diff --git a/Makefile b/Makefile index bce6edb33e10..ae36f9ea1e09 100644 --- a/Makefile +++ b/Makefile @@ -34,12 +34,16 @@ # for world and kernel targets. # toolchains - Build a toolchain for all world and kernel targets. # xdev - xdev-build + xdev-install for the architecture -# specified with XDEV and XDEV_ARCH. +# specified with TARGET and TARGET_ARCH. # xdev-build - Build cross-development tools. # xdev-install - Install cross-development tools. # xdev-links - Create traditional links in /usr/bin for cc, etc # native-xtools - Create host binaries that produce target objects -# for use in qemu user-mode jails. +# for use in qemu user-mode jails. TARGET and +# TARGET_ARCH should be defined. +# native-xtools-install +# - Install the files to the given DESTDIR/NXTP where +# NXTP defaults to /nxb-bin. # # "quick" way to test all kernel builds: # _jflag=`sysctl -n hw.ncpu` @@ -118,6 +122,7 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \ check check-old check-old-dirs check-old-files check-old-libs \ checkdpadd checkworld clean cleandepend cleandir cleanworld \ + cleanuniverse \ delete-old delete-old-dirs delete-old-files delete-old-libs \ depend distribute distributekernel distributekernel.debug \ distributeworld distrib-dirs distribution doxygen \ @@ -130,11 +135,16 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \ _build-tools _build-metadata _cross-tools _includes _libraries \ build32 distribute32 install32 buildsoft distributesoft installsoft \ builddtb xdev xdev-build xdev-install \ - xdev-links native-xtools stageworld stagekernel stage-packages \ + xdev-links native-xtools native-xtools-install stageworld stagekernel \ + stage-packages \ create-packages-world create-packages-kernel create-packages \ packages installconfig real-packages sign-packages package-pkg \ print-dir test-system-compiler +# These targets require a TARGET and TARGET_ARCH be defined. +XTGTS= native-xtools native-xtools-install xdev xdev-build xdev-install \ + xdev-links + # XXX: r156740: This can't work since bsd.subdir.mk is not included ever. # It will only work for SUBDIR_TARGETS in make.conf. TGTS+= ${SUBDIR_TARGETS} @@ -179,7 +189,7 @@ META_TGT_WHITELIST+= \ PATH= /sbin:/bin:/usr/sbin:/usr/bin MAKEOBJDIRPREFIX?= /usr/obj -_MAKEOBJDIRPREFIX!= /usr/bin/env -i PATH=${PATH} MK_AUTO_OBJ=no ${MAKE} \ +_MAKEOBJDIRPREFIX!= /usr/bin/env -i PATH=${PATH} ${MAKE} MK_AUTO_OBJ=no \ ${.MAKEFLAGS:MMAKEOBJDIRPREFIX=*} __MAKE_CONF=${__MAKE_CONF} \ -f /dev/null -V MAKEOBJDIRPREFIX dummy .if !empty(_MAKEOBJDIRPREFIX) @@ -199,7 +209,7 @@ WANT_MAKE_VERSION= 20160604 # 20160220 - support .dinclude for FAST_DEPEND. WANT_MAKE_VERSION= 20160220 .endif -MYMAKE= ${MAKEOBJDIRPREFIX}${.CURDIR}/make.${MACHINE}/${WANT_MAKE} +MYMAKE= ${OBJROOT}make.${MACHINE}/${WANT_MAKE} .if defined(.PARSEDIR) HAVE_MAKE= bmake .else @@ -270,6 +280,11 @@ _TARGET= ${XDEV} .if defined(XDEV_ARCH) _TARGET_ARCH= ${XDEV_ARCH} .endif +# Some targets require a set TARGET/TARGET_ARCH, check before the default +# MACHINE and after the compatibility handling. +.if !defined(_TARGET) || !defined(_TARGET_ARCH) +${XTGTS}: _assert_target +.endif # Otherwise, default to current machine type and architecture. _TARGET?= ${MACHINE} _TARGET_ARCH?= ${MACHINE_ARCH} @@ -278,6 +293,14 @@ _TARGET_ARCH?= ${MACHINE_ARCH} .SILENT: .endif +_assert_target: .PHONY .MAKE +.for _tgt in ${XTGTS} +.if make(${_tgt}) + @echo "*** Error: Both TARGET and TARGET_ARCH must be defined for \"${_tgt}\" target" + @false +.endif +.endfor + # # Make sure we have an up-to-date make(1). Only world and buildworld # should do this as those are the initial targets used for upgrades. @@ -384,10 +407,13 @@ upgrade_checks: .PHONY # headers, libraries and tools. Also, allow the location of # the system bsdmake-like utility to be overridden. # -MMAKEENV= MAKEOBJDIRPREFIX=${MYMAKE:H} \ +MMAKEENV= \ DESTDIR= \ INSTALL="sh ${.CURDIR}/tools/install.sh" MMAKE= ${MMAKEENV} ${MAKE} \ + OBJTOP=${MYMAKE:H}/obj \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ MAN= -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WERROR \ -DNO_SUBDIR \ @@ -435,7 +461,7 @@ worlds: .PHONY .if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets) TARGETS?=amd64 arm arm64 i386 mips powerpc riscv sparc64 _UNIVERSE_TARGETS= ${TARGETS} -TARGET_ARCHES_arm?= arm armeb armv6 +TARGET_ARCHES_arm?= arm armeb armv6 armv7 TARGET_ARCHES_arm64?= aarch64 TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe diff --git a/Makefile.inc1 b/Makefile.inc1 index 7a4c156d28ce..e306f7dd0615 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -78,18 +78,11 @@ MK_CLANG_BOOTSTRAP= no MK_GCC_BOOTSTRAP= no .endif -MAKEOBJDIRPREFIX?= /usr/obj -.if ${MACHINE} == ${TARGET} && ${MACHINE_ARCH} == ${TARGET_ARCH} && !defined(CROSS_BUILD_TESTING) -OBJTREE= ${MAKEOBJDIRPREFIX} -.else -OBJTREE= ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH} -.endif - # Pull in compiler metadata from buildworld/toolchain if possible to avoid # running CC from bsd.compiler.mk. .if make(installworld) || make(install) || make(distributeworld) || \ make(stageworld) -.-include "${OBJTREE}${.CURDIR}/compiler-metadata.mk" +.-include "${OBJTOP}/compiler-metadata.mk" .endif # Pull in COMPILER_TYPE and COMPILER_FREEBSD_VERSION early. @@ -133,7 +126,7 @@ WANT_COMPILER_VERSION!= \ # TARGET_ARCH!=MACHINE_ARCH. .if ${MK_SYSTEM_COMPILER} == "yes" && \ (${MK_CLANG_BOOTSTRAP} == "yes" || ${MK_GCC_BOOTSTRAP} == "yes") && \ - !make(showconfig) && !make(native-xtools) && !make(xdev*) && \ + !make(showconfig) && !make(xdev*) && \ ${WANT_COMPILER_TYPE} == ${COMPILER_TYPE} && \ (${COMPILER_TYPE} == "clang" || ${TARGET_ARCH} == ${MACHINE_ARCH}) && \ ${COMPILER_VERSION} == ${WANT_COMPILER_VERSION} && \ @@ -308,7 +301,7 @@ CLEANDIR= cleandir .if defined(WORLDFAST) NO_CLEAN= t -NO_OBJ= t +NO_OBJWALK= t .endif .if ${MK_META_MODE} == "yes" @@ -319,11 +312,11 @@ NO_OBJ= t NO_CLEAN= t .endif .endif -.if defined(NO_OBJ) || ${MK_AUTO_OBJ} == "yes" -NO_OBJ= t +.if defined(NO_OBJWALK) || ${MK_AUTO_OBJ} == "yes" +NO_OBJWALK= t NO_KERNELOBJ= t .endif -.if !defined(NO_OBJ) +.if !defined(NO_OBJWALK) _obj= obj .endif @@ -365,11 +358,11 @@ OSRELDATE= 0 # Set VERSION for CTFMERGE to use via the default CTFFLAGS=-L VERSION. .if !defined(_REVISION) -_REVISION!= MK_AUTO_OBJ=no ${MAKE} -C ${SRCDIR}/release -V REVISION +_REVISION!= ${MAKE} -C ${SRCDIR}/release MK_AUTO_OBJ=no -V REVISION .export _REVISION .endif .if !defined(_BRANCH) -_BRANCH!= MK_AUTO_OBJ=no ${MAKE} -C ${SRCDIR}/release -V BRANCH +_BRANCH!= ${MAKE} -C ${SRCDIR}/release MK_AUTO_OBJ=no -V BRANCH .export _BRANCH .endif .if !defined(SRCRELDATE) @@ -398,6 +391,7 @@ KNOWN_ARCHES?= aarch64/arm64 \ arm \ armeb/arm \ armv6/arm \ + armv7/arm \ i386 \ mips \ mipsel/mips \ @@ -438,8 +432,8 @@ _TARGET_CPUTYPE=${TARGET_CPUTYPE} .else _TARGET_CPUTYPE=dummy .endif -_CPUTYPE!= MK_AUTO_OBJ=no MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} \ - -f /dev/null -m ${.CURDIR}/share/mk -V CPUTYPE +_CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} -f /dev/null \ + -m ${.CURDIR}/share/mk MK_AUTO_OBJ=no -V CPUTYPE .if ${_CPUTYPE} != ${_TARGET_CPUTYPE} .error CPUTYPE global should be set with ?=. .endif @@ -449,7 +443,7 @@ BUILD_ARCH!= uname -p .error To cross-build, set TARGET_ARCH. .endif .endif -WORLDTMP= ${OBJTREE}${.CURDIR}/tmp +WORLDTMP?= ${OBJTOP}/tmp BPATH= ${CCACHE_WRAPPER_PATH_PFX}${WORLDTMP}/legacy/usr/sbin:${WORLDTMP}/legacy/usr/bin:${WORLDTMP}/legacy/bin XPATH= ${WORLDTMP}/usr/sbin:${WORLDTMP}/usr/bin STRICTTMPPATH= ${BPATH}:${XPATH} @@ -507,7 +501,7 @@ MINIMUM_SUPPORTED_OSREL?= 900044 MINIMUM_SUPPORTED_REL?= 9.1 # Common environment for world related stages -CROSSENV+= MAKEOBJDIRPREFIX=${OBJTREE} \ +CROSSENV+= \ MACHINE_ARCH=${TARGET_ARCH} \ MACHINE=${TARGET} \ CPUTYPE=${TARGET_CPUTYPE} @@ -527,6 +521,9 @@ BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" # need to keep this in sync with targets/pseudo/bootstrap-tools/Makefile BSARGS= DESTDIR= \ + OBJTOP='${WORLDTMP}/obj-tools' \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ BOOTSTRAPPING=${OSRELDATE} \ BWPHASE=${.TARGET:C,^_,,} \ SSP_CFLAGS= \ @@ -537,12 +534,12 @@ BSARGS= DESTDIR= \ MK_LLDB=no MK_TESTS=no \ MK_INCLUDES=yes -BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ +BMAKE= \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ ${BSARGS} # build-tools stage -TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ +TMAKE= \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ DESTDIR= \ @@ -555,7 +552,8 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ MK_LLDB=no MK_TESTS=no # cross-tools stage -XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ +# TOOLS_PREFIX set in BMAKE +XMAKE= ${BMAKE} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ MK_GDB=no MK_LLD_IS_LD=${MK_LLD_BOOTSTRAP} MK_TESTS=no @@ -563,9 +561,12 @@ XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} -KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ +KTMAKE= TOOLS_PREFIX=${WORLDTMP} \ ${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ DESTDIR= \ + OBJTOP='${WORLDTMP}/obj-kernel-tools' \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ MK_HTML=no -DNO_LINT MK_MAN=no \ @@ -614,7 +615,7 @@ BFLAGS+= -B${CROSS_BINUTILS_PREFIX} BFLAGS+= -B${WORLDTMP}/usr/bin .endif .if ${TARGET} == "arm" -.if ${TARGET_ARCH:Marmv6*} != "" && ${TARGET_CPUTYPE:M*soft*} == "" +.if ${TARGET_ARCH:Marmv[67]*} != "" && ${TARGET_CPUTYPE:M*soft*} == "" TARGET_ABI= gnueabihf .else TARGET_ABI= gnueabi @@ -636,6 +637,8 @@ XCXXFLAGS+= -isystem ${WORLDTMP}/usr/include/c++/v1 -std=c++11 \ .endif .elif ${WANT_COMPILER_TYPE} == clang || \ (defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == clang) +MACHINE_ABI?= unknown +MACHINE_TRIPLE?=${MACHINE_ARCH:C/amd64/x86_64/}-${MACHINE_ABI}-freebsd12.0 TARGET_ABI?= unknown TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd12.0 XCFLAGS+= -target ${TARGET_TRIPLE} @@ -650,7 +653,7 @@ XCFLAGS+= ${BFLAGS} ${TARGET_ARCH} == "powerpc64" || ${TARGET_ARCH:Mmips64*} != "") LIBCOMPAT= 32 .include "Makefile.libcompat" -.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH} == "armv6" +.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH:Marmv[67]*} != "" LIBCOMPAT= SOFT .include "Makefile.libcompat" .endif @@ -666,11 +669,11 @@ LIBCOMPAT= SOFT META_MODE_BAD_ABI_VERS+= 1200031 .if !defined(OBJDIR_HOST_OSRELDATE) -.if exists(${OBJTREE}${.CURDIR}/host-osreldate.h) +.if exists(${OBJTOP}/host-osreldate.h) OBJDIR_HOST_OSRELDATE!= \ awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ - ${OBJTREE}${.CURDIR}/host-osreldate.h -.else + ${OBJTOP}/host-osreldate.h +.elif exists(${WORLDTMP}/usr/include/osreldate.h) OBJDIR_HOST_OSRELDATE= 0 .endif .export OBJDIR_HOST_OSRELDATE @@ -679,6 +682,7 @@ OBJDIR_HOST_OSRELDATE= 0 # Note that this logic is the opposite of normal BOOTSTRAP handling. We want # to compare the WORLDTMP's OSRELDATE to the host's OSRELDATE. If the WORLDTMP # is older than the ABI-breakage OSRELDATE of the HOST then we rebuild. +.if defined(OBJDIR_HOST_OSRELDATE) .for _ver in ${META_MODE_BAD_ABI_VERS} .if ${OSRELDATE} >= ${_ver} && ${OBJDIR_HOST_OSRELDATE} < ${_ver} _meta_mode_need_rebuild= ${_ver} @@ -688,8 +692,9 @@ _meta_mode_need_rebuild= ${_ver} .info META_MODE: Rebuilding host tools due to ABI breakage in __FreeBSD_version ${_meta_mode_need_rebuild}. NO_META_IGNORE_HOST_HEADERS= 1 .export NO_META_IGNORE_HOST_HEADERS -.endif -.endif +.endif # defined(_meta_mode_need_rebuild) +.endif # defined(OBJDIR_HOST_OSRELDATE) +.endif # ${MK_META_MODE} == "yes" && defined(NO_CLEAN) ... # This is only used for META_MODE+filemon to track what the oldest # __FreeBSD_version is in WORLDTMP. This purposely does NOT have # a make dependency on /usr/include/osreldate.h as the file should @@ -747,34 +752,76 @@ KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME} # Attempt to rebuild the entire system, with reasonable chance of # success, regardless of how old your existing system is. # -_worldtmp: .PHONY +_sanity_check: .PHONY .MAKE .if ${.CURDIR:C/[^,]//g} != "" # The m4 build of sendmail files doesn't like it if ',' is used # anywhere in the path of it's files. @echo @echo "*** Error: path to source tree contains a comma ','" @echo - false + @false +.elif ${.CURDIR:M*\:*} != "" +# Using ':' leaks into PATH and breaks finding cross-tools. + @echo + @echo "*** Error: path to source tree contains a colon ':'" + @echo + @false .endif + +# Our current approach to dependency tracking cannot cope with certain source +# tree changes, particularly with respect to removing source files and +# replacing generated files. Handle these cases here in an ad-hoc fashion. +_cleanobj_fast_depend_hack: .PHONY +# Syscall stubs rewritten in C +# Date SVN Rev Syscalls +# 20160829 r305012 ptrace +# 20170624 r320278 fstat fstatat fstatfs getdirentries getfsstat statfs +.for f in fstat fstatat fstatfs getdirentries getfsstat ptrace statfs +.if exists(${OBJTOP}/lib/libc/.depend.${f}.o) + @if egrep -qw '${f}\.[sS]' \ + ${OBJTOP}/lib/libc/.depend.${f}.o; then \ + echo Removing stale dependencies for ${f} syscall wrappers; \ + rm -f ${OBJTOP}/lib/libc/.depend.${f}.* \ + ${LIBCOMPAT:D${LIBCOMPAT_OBJTOP}/lib/libc/.depend.${f}.*}; \ + fi +.endif +.endfor +# 20170607 remove stale dependencies for utimens* wrappers removed in r319663 +.for f in futimens utimensat +.if exists(${OBJTOP}/lib/libc/.depend.${f}.o) + @if egrep -q '/${f}.c' \ + ${OBJTOP}/lib/libc/.depend.${f}.o; then \ + echo Removing stale dependencies for ${f} syscall wrappers; \ + rm -f ${OBJTOP}/lib/libc/.depend.${f}.* \ + ${LIBCOMPAT:D${LIBCOMPAT_OBJTOP}/lib/libc/.depend.${f}.*}; \ + fi +.endif +.endfor +# 20170523 remove stale generated asm files for functions which are no longer +# syscalls after r302092 (pipe) and r318736 (others) +.for f in getdents lstat mknod pipe stat +.if exists(${OBJTOP}/lib/libc/${f}.s) || \ + exists(${OBJTOP}/lib/libc/${f}.S) + @echo Removing stale generated ${f} syscall files + @rm -f ${OBJTOP}/lib/libc/${f}.* \ + ${OBJTOP}/lib/libc/.depend.${f}.* \ + ${LIBCOMPAT:D${LIBCOMPAT_OBJTOP}/lib/libc/${f}.*} \ + ${LIBCOMPAT:D${LIBCOMPAT_OBJTOP}/lib/libc/.depend.${f}.*} +.endif +.endfor + +_worldtmp: .PHONY @echo @echo "--------------------------------------------------------------" @echo ">>> Rebuilding the temporary build tree" @echo "--------------------------------------------------------------" .if !defined(NO_CLEAN) rm -rf ${WORLDTMP} -.if defined(LIBCOMPAT) - rm -rf ${LIBCOMPATTMP} -.endif .else .if exists(${WORLDTMP}) @echo ">>> Deleting stale files in build tree..." ${_+_}cd ${.CURDIR}; ${WMAKE} -DBATCH_DELETE_OLD_FILES \ delete-old delete-old-libs >/dev/null -.endif -.if defined(LIBCOMPAT) && exists(${LIBCOMPATTMP}) - ${_+_}cd ${.CURDIR}; ${WMAKE} -DBATCH_DELETE_OLD_FILES \ - DESTDIR=${LIBCOMPATTMP} \ - delete-old delete-old-libs >/dev/null .endif rm -rf ${WORLDTMP}/legacy/usr/include .if ${USING_SYSTEM_COMPILER} == "yes" @@ -785,50 +832,9 @@ _worldtmp: .PHONY fi .endfor .endif # ${USING_SYSTEM_COMPILER} == "yes" - -# Our current approach to dependency tracking cannot cope with certain source -# tree changes, particularly with respect to removing source files and -# replacing generated files. Handle these cases here in an ad-hoc fashion. -# -# Syscall stubs rewritten in C -# Date SVN Rev Syscalls -# 20160829 r305012 ptrace -# 20170624 r320278 fstat fstatat fstatfs getdirentries getfsstat statfs -.for f in fstat fstatat fstatfs getdirentries getfsstat ptrace statfs -.if exists(${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o) - @if egrep -qw '${f}\.[sS]' \ - ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o; then \ - echo Removing stale dependencies for ${f} syscall wrappers; \ - rm -f ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ - ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.*; \ - fi -.endif -.endfor -# 20170607 remove stale dependencies for utimens* wrappers removed in r319663 -.for f in futimens utimensat -.if exists(${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o) - @if egrep -q '/${f}.c' \ - ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o; then \ - echo Removing stale dependencies for ${f} syscall wrappers; \ - rm -f ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ - ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.*; \ - fi -.endif -.endfor -# 20170523 remove stale generated asm files for functions which are no longer -# syscalls after r302092 (pipe) and r318736 (others) -.for f in getdents lstat mknod pipe stat -.if exists(${OBJTREE}${.CURDIR}/lib/libc/${f}.s) || \ - exists(${OBJTREE}${.CURDIR}/lib/libc/${f}.S) - @echo Removing stale generated ${f} syscall files - @rm -f ${OBJTREE}${.CURDIR}/lib/libc/${f}.* \ - ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ - ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/${f}.* \ - ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.* -.endif -.endfor - .endif # !defined(NO_CLEAN) + @mkdir -p ${WORLDTMP} + @touch ${WORLDTMP}/${.TARGET} .for _dir in \ lib lib/casper usr legacy/bin legacy/usr @@ -844,32 +850,11 @@ _worldtmp: .PHONY -p ${WORLDTMP}/usr/include >/dev/null ln -sf ${.CURDIR}/sys ${WORLDTMP} .if ${MK_DEBUG_FILES} != "no" - # We could instead disable debug files for these build stages mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/legacy/usr/lib >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/usr/lib >/dev/null .endif -.if defined(LIBCOMPAT) - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ - -p ${WORLDTMP}/usr >/dev/null -.if ${MK_DEBUG_FILES} != "no" - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ - -p ${WORLDTMP}/legacy/usr/lib/debug/usr >/dev/null - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ - -p ${WORLDTMP}/usr/lib/debug/usr >/dev/null -.endif -.endif -.if ${MK_TESTS} != "no" - mkdir -p ${WORLDTMP}${TESTSBASE} - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ - -p ${WORLDTMP}${TESTSBASE} >/dev/null -.if ${MK_DEBUG_FILES} != "no" - mkdir -p ${WORLDTMP}/usr/lib/debug/${TESTSBASE} - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ - -p ${WORLDTMP}/usr/lib/debug/${TESTSBASE} >/dev/null -.endif -.endif .for _mtree in ${LOCAL_MTREE} mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null .endfor @@ -895,7 +880,9 @@ _cleanobj: .if defined(LIBCOMPAT) ${_+_}cd ${.CURDIR}; ${LIBCOMPATWMAKE} -f Makefile.inc1 ${CLEANDIR} .endif -.endif +.else + ${_+_}cd ${.CURDIR}; ${WMAKE} _cleanobj_fast_depend_hack +.endif # !defined(NO_CLEAN) _obj: @echo @echo "--------------------------------------------------------------" @@ -913,7 +900,7 @@ _cross-tools: @echo "--------------------------------------------------------------" @echo ">>> stage 3: cross tools" @echo "--------------------------------------------------------------" - @rm -f ${OBJTREE}${.CURDIR}/compiler-metadata.mk + @rm -f ${OBJTOP}/compiler-metadata.mk ${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools ${_+_}cd ${.CURDIR}; ${XMAKE} kernel-tools _build-metadata: @@ -952,12 +939,12 @@ everything: .PHONY WMAKE_TGTS= .if !defined(WORLDFAST) -WMAKE_TGTS+= _worldtmp _legacy +WMAKE_TGTS+= _sanity_check _worldtmp _legacy .if empty(SUBDIR_OVERRIDE) WMAKE_TGTS+= _bootstrap-tools .endif WMAKE_TGTS+= _cleanobj -.if !defined(NO_OBJ) +.if !defined(NO_OBJWALK) WMAKE_TGTS+= _obj .endif WMAKE_TGTS+= _build-tools _cross-tools @@ -1006,12 +993,15 @@ buildenv: .PHONY .if ${BUILDENV_SHELL:M*zsh*} @echo For ZSH you must run: export CPUTYPE=${TARGET_CPUTYPE} .endif - @cd ${BUILDENV_DIR} && env ${WMAKEENV} BUILDENV=1 ${BUILDENV_SHELL} \ - || true + @cd ${BUILDENV_DIR} && env ${WMAKEENV} BUILDENV=1 ${BUILDENV_SHELL} TOOLCHAIN_TGTS= ${WMAKE_TGTS:Neverything:Nbuild${libcompat}} toolchain: ${TOOLCHAIN_TGTS} .PHONY -kernel-toolchain: ${TOOLCHAIN_TGTS:N_includes:N_libraries} .PHONY +KERNEL_TOOLCHAIN_TGTS= ${TOOLCHAIN_TGTS:N_obj:N_cleanobj:N_includes:N_libraries} +.if make(kernel-toolchain) +.ORDER: ${KERNEL_TOOLCHAIN_TGTS} +.endif +kernel-toolchain: ${KERNEL_TOOLCHAIN_TGTS} .PHONY # # installcheck @@ -1082,7 +1072,7 @@ __installcheck_UGID: .PHONY (empty(DESTDIR) || ${DESTDIR} == "/") && empty(BYPASS_INSTALLCHECK_SH) _installcheck_world: __installcheck_sh_check __installcheck_sh_check: .PHONY - @if [ "`${OBJTREE}${.CURDIR}/rescue/rescue/rescue sh -c 'echo OK'`" != \ + @if [ "`${OBJTOP}/rescue/rescue/rescue sh -c 'echo OK'`" != \ OK ]; then \ echo "rescue/sh check failed, installation aborted" >&2; \ false; \ @@ -1344,7 +1334,7 @@ INSTKERNNAME?= kernel KERNSRCDIR?= ${.CURDIR}/sys KRNLCONFDIR= ${KERNSRCDIR}/${TARGET}/conf -KRNLOBJDIR= ${OBJTREE}${KERNSRCDIR} +KRNLOBJDIR= ${OBJTOP}${KERNSRCDIR:C,^${.CURDIR},,} KERNCONFDIR?= ${KRNLCONFDIR} BUILDKERNELS= @@ -1359,6 +1349,10 @@ BUILDKERNELS+= ${_kernel} .if empty(INSTALLKERNEL) && !defined(NO_INSTALLKERNEL) INSTALLKERNEL= ${_kernel} .endif +.else +.if make(buildkernel) +.error Missing KERNCONF ${KERNCONFDIR}/${_kernel} +.endif .endif .endfor @@ -1548,9 +1542,9 @@ stagekernel: .PHONY ${_+_}${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} distributekernel PORTSDIR?= /usr/ports -WSTAGEDIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH}/worldstage -KSTAGEDIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH}/kernelstage -REPODIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/repo +WSTAGEDIR?= ${OBJTOP}/worldstage +KSTAGEDIR?= ${OBJTOP}/kernelstage +REPODIR?= ${OBJROOT}repo PKGSIGNKEY?= # empty .ORDER: stage-packages create-packages @@ -1812,11 +1806,11 @@ legacy: .PHONY .for _tool in tools/build ${_elftoolchain_libs} ${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,all,install)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ - ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy includes; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ + ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${WORLDTMP}/legacy includes; \ ${MAKE} DIRPRFX=${_tool}/ MK_INCLUDES=no all; \ ${MAKE} DIRPRFX=${_tool}/ MK_INCLUDES=no \ - DESTDIR=${MAKEOBJDIRPREFIX}/legacy install + DESTDIR=${WORLDTMP}/legacy install .endfor # @@ -1840,7 +1834,6 @@ _vtfontcvt= usr.bin/vtfontcvt .endif .if ${BOOTSTRAPPING} < 1000033 -_libopenbsd= lib/libopenbsd _m4= usr.bin/m4 _lex= usr.bin/lex @@ -1926,9 +1919,6 @@ _kerberos5_bootstrap_tools= \ .ORDER: ${_kerberos5_bootstrap_tools:C/^/${_bt}-/g} .endif -# r283777 makewhatis(1) replaced with mandoc version which builds a database. -_libopenbsd?= lib/libopenbsd -_makewhatis= usr.bin/mandoc ${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd bootstrap-tools: .PHONY @@ -1945,8 +1935,8 @@ bootstrap-tools: .PHONY ${_cat} \ ${_kbdcontrol} \ usr.bin/lorder \ - ${_libopenbsd} \ - ${_makewhatis} \ + lib/libopenbsd \ + usr.bin/mandoc \ usr.bin/rpcgen \ ${_yacc} \ ${_m4} \ @@ -1962,9 +1952,9 @@ bootstrap-tools: .PHONY ${_bt}-${_tool}: .PHONY .MAKE ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ all; \ - ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install + ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${WORLDTMP}/legacy install bootstrap-tools: ${_bt}-${_tool} .endfor @@ -1989,6 +1979,12 @@ _rescue=rescue/rescue _tcsh=bin/csh .endif +# kernel-toolchain skips _cleanobj, so handle cleaning up previous +# build-tools directories if needed. +.if !defined(NO_CLEAN) && make(kernel-toolchain) +_bt_clean= ${CLEANDIR} +.endif + .for _tool in \ ${_tcsh} \ bin/sh \ @@ -2001,21 +1997,14 @@ _tcsh=bin/csh lib/libmagic \ usr.bin/mkesdb_static \ usr.bin/mkcsmapper_static \ - usr.bin/vi/catalog -build-tools_${_tool}: .PHONY - ${_+_}@${ECHODIR} "===> ${_tool} (obj,build-tools)"; \ - cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ - ${MAKE} DIRPRFX=${_tool}/ build-tools -build-tools: build-tools_${_tool} -.endfor -.for _tool in \ + usr.bin/vi/catalog \ ${_gcc_tools} build-tools_${_tool}: .PHONY - ${_+_}@${ECHODIR} "===> ${_tool} (obj,all)"; \ + ${_+_}@${ECHODIR} "===> ${_tool} (${_bt_clean:D${_bt_clean},}obj,build-tools)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ - ${MAKE} DIRPRFX=${_tool}/ all + if [ -n "${_bt_clean}" ]; then ${MAKE} DIRPRFX=${_tool}/ ${_bt_clean}; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ + ${MAKE} DIRPRFX=${_tool}/ build-tools build-tools: build-tools_${_tool} .endfor @@ -2023,9 +2012,9 @@ build-tools: build-tools_${_tool} # kernel-tools: Build kernel-building tools # kernel-tools: .PHONY - mkdir -p ${MAKEOBJDIRPREFIX}/usr + mkdir -p ${WORLDTMP}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ - -p ${MAKEOBJDIRPREFIX}/usr >/dev/null + -p ${WORLDTMP}/usr >/dev/null # # cross-tools: All the tools needed to build the rest of the system after @@ -2099,52 +2088,30 @@ cross-tools: .MAKE .PHONY ${_usb_tools} ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ all; \ - ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX} install + ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${WORLDTMP} install .endfor -NXBDESTDIR= ${OBJTREE}/nxb-bin -NXBENV= MAKEOBJDIRPREFIX=${OBJTREE}/nxb \ - TOOLS_PREFIX= \ - INSTALL="sh ${.CURDIR}/tools/install.sh" \ - PATH=${PATH}:${OBJTREE}/gperf_for_gcc/usr/bin -NXBMAKE= ${NXBENV} ${MAKE} \ - LLVM_TBLGEN=${NXBDESTDIR}/usr/bin/llvm-tblgen \ - CLANG_TBLGEN=${NXBDESTDIR}/usr/bin/clang-tblgen \ - MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} \ - MK_GDB=no MK_TESTS=no \ - SSP_CFLAGS= \ - MK_HTML=no NO_LINT=yes MK_MAN=no MK_MAN_UTILS=yes \ - -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ - MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ - MK_LLDB=no MK_DEBUG_FILES=no - +# # native-xtools is the current target for qemu-user cross builds of ports # via poudriere and the imgact_binmisc kernel module. -# For non-clang enabled targets that are still using the in tree gcc -# we must build a gperf binary for one instance of its Makefiles. On -# clang-enabled systems, the gperf binary is obsolete. -native-xtools: .PHONY -.if ${MK_GCC_BOOTSTRAP} != "no" - mkdir -p ${OBJTREE}/gperf_for_gcc/usr/bin - ${_+_}@${ECHODIR} "===> ${_gperf} (obj,all,install)"; \ - cd ${.CURDIR}/${_gperf}; \ - if [ -z "${NO_OBJ}" ]; then ${NXBMAKE} DIRPRFX=${_gperf}/ obj; fi; \ - ${NXBMAKE} DIRPRFX=${_gperf}/ all; \ - ${NXBMAKE} DIRPRFX=${_gperf}/ DESTDIR=${OBJTREE}/gperf_for_gcc install +# This target merely builds a toolchan/sysroot, then builds the tools it wants +# with the options it wants in a special MAKEOBJDIRPREFIX, using the toolchain +# already built. It then installs the static tools to NXBDESTDIR for Poudriere +# to pickup. +# +NXBOBJROOT= ${OBJROOT}${MACHINE}.${MACHINE_ARCH}/nxb/ +NXBOBJTOP= ${NXBOBJROOT}${TARGET}.${TARGET_ARCH} +NXTP?= /nxb-bin +.if ${NXTP:N/*} +.error NXTP variable should be an absolute path .endif - mkdir -p ${NXBDESTDIR}/bin ${NXBDESTDIR}/sbin ${NXBDESTDIR}/usr - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ - -p ${NXBDESTDIR}/usr >/dev/null - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ - -p ${NXBDESTDIR}/usr/include >/dev/null -.if ${MK_DEBUG_FILES} != "no" - mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ - -p ${NXBDESTDIR}/usr/lib >/dev/null -.endif -.for _tool in \ +NXBDESTDIR?= ${DESTDIR}${NXTP} + +# This is the list of tools to be built/installed as static and where +# appropriate to build for the given TARGET.TARGET_ARCH. +NXBDIRS+= \ bin/cat \ bin/chmod \ bin/cp \ @@ -2162,24 +2129,18 @@ native-xtools: .PHONY bin/rmdir \ bin/sh \ bin/sleep \ - ${_clang_tblgen} \ - usr.bin/ar \ - ${_binutils} \ - ${_elftctools} \ - ${_gcc} \ - ${_gcc_tools} \ - ${_clang_libs} \ - ${_clang} \ - ${_lld} \ sbin/md5 \ sbin/sysctl \ - usr.bin/diff \ + usr.bin/addr2line \ + usr.bin/ar \ usr.bin/awk \ usr.bin/basename \ usr.bin/bmake \ usr.bin/bzip2 \ usr.bin/cmp \ + usr.bin/diff \ usr.bin/dirname \ + usr.bin/elfcopy \ usr.bin/env \ usr.bin/fetch \ usr.bin/find \ @@ -2189,14 +2150,16 @@ native-xtools: .PHONY usr.bin/lex \ usr.bin/limits \ usr.bin/lorder \ - ${_libopenbsd} \ - ${_makewhatis} \ + usr.bin/mandoc \ usr.bin/mktemp \ usr.bin/mt \ + usr.bin/nm \ usr.bin/patch \ usr.bin/readelf \ usr.bin/sed \ + usr.bin/size \ usr.bin/sort \ + usr.bin/strings \ usr.bin/tar \ usr.bin/touch \ usr.bin/tr \ @@ -2208,12 +2171,82 @@ native-xtools: .PHONY usr.bin/xz \ usr.bin/yacc \ usr.sbin/chown - ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ - cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${NXBMAKE} DIRPRFX=${_tool}/ obj; fi; \ - ${NXBMAKE} DIRPRFX=${_tool}/ all; \ - ${NXBMAKE} DIRPRFX=${_tool}/ DESTDIR=${NXBDESTDIR} install -.endfor + +.if ${MK_CLANG} != "no" +NXBDIRS+= lib/clang +SUBDIR_DEPEND_usr.bin/clang= lib/clang +NXBDIRS+= usr.bin/clang +.elif ${MK_GCC} != "no" +NXBDIRS+= gnu/usr.bin/cc +.endif +.if ${MK_BINUTILS} != "no" +NXBDIRS+= gnu/usr.bin/binutils +.endif + +NXBMAKEARGS+= \ + OBJTOP=${NXBOBJTOP:Q} \ + OBJROOT=${NXBOBJROOT:Q} \ + -DNO_SHARED \ + -DNO_CPU_CFLAGS \ + -DNO_PIC \ + SSP_CFLAGS= \ + MK_CLANG_EXTRAS=no \ + MK_CLANG_FULL=no \ + MK_CTF=no \ + MK_DEBUG_FILES=no \ + MK_GDB=no \ + MK_HTML=no \ + MK_LLDB=no \ + MK_MAN=no \ + MK_MAN_UTILS=yes \ + MK_OFED=no \ + MK_OPENSSH=no \ + MK_PROFILE=no \ + MK_SENDMAIL=no \ + MK_SVNLITE=no \ + MK_TESTS=no \ + MK_WARNS=no \ + MK_ZFS=no + + +# For 'toolchain' we want to produce native binaries that themselves generate +# native binaries. +NXBTMAKE= ${NXBMAKEENV} ${MAKE} ${NXBMAKEARGS:N-DNO_PIC:N-DNO_SHARED} \ + TARGET=${MACHINE} TARGET_ARCH=${MACHINE_ARCH} +# For 'everything' we want to produce native binaries (hence -target to +# be MACHINE) that themselves generate TARGET.TARGET_ARCH binaries. +# TARGET/TARGET_ARCH are still passed along from user. +NXBMAKE= ${NXBMAKEENV} ${MAKE} ${NXBMAKEARGS} \ + TARGET_TRIPLE=${MACHINE_TRIPLE:Q} +native-xtools: .PHONY + # Build the bootstrap/host/cross tools that produce native binaries + ${_+_}cd ${.CURDIR}; ${NXBTMAKE} kernel-toolchain + # Populate includes/libraries sysroot that produce native binaries. + # This is split out from 'toolchain' above mostly so that target LLVM + # libraries have a proper LLVM_DEFAULT_TARGET_TRIPLE without + # polluting the cross-compiler build. The LLVM/GCC libs are skipped + # here to avoid the problem but are kept in 'toolchain' so that + # needed build tools are built. + ${_+_}cd ${.CURDIR}; ${NXBTMAKE} _includes MK_CLANG=no MK_GCC=no + ${_+_}cd ${.CURDIR}; ${NXBTMAKE} _libraries MK_CLANG=no MK_GCC=no +.if !defined(NO_OBJWALK) + ${_+_}cd ${.CURDIR}; ${NXBMAKE} SUBDIR_OVERRIDE="${NXBDIRS:M*}" _obj +.endif + ${_+_}cd ${.CURDIR}; ${NXBMAKE} SUBDIR_OVERRIDE="${NXBDIRS:M*}" \ + everything + @echo ">> native-xtools done. Use 'make native-xtools-install' to install to a given DESTDIR" + +native-xtools-install: .PHONY + mkdir -p ${NXBDESTDIR}/bin ${NXBDESTDIR}/sbin ${NXBDESTDIR}/usr + mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ + -p ${NXBDESTDIR}/usr >/dev/null + mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ + -p ${NXBDESTDIR}/usr/include >/dev/null + ${_+_}cd ${.CURDIR}; ${NXBMAKE} -f Makefile.inc1 \ + DESTDIR=${NXBDESTDIR} \ + SUBDIR_OVERRIDE="${NXBDIRS:M*}" \ + -DNO_ROOT \ + install # # hierarchy - ensure that all the needed directories are present @@ -2473,7 +2506,7 @@ ${_lib}__PL: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \ cd ${.CURDIR}/${_lib}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ DIRPRFX=${_lib}/ all; \ ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ @@ -2486,7 +2519,7 @@ ${_lib}__L: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \ cd ${.CURDIR}/${_lib}; \ - if [ -z "${NO_OBJ}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ all; \ ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ install .endif @@ -2559,7 +2592,7 @@ delete-old-files: .PHONY done # Remove catpages without corresponding manpages. @exec 3<&0; \ - find ${DESTDIR}/usr/share/man/cat* ! -type d | \ + find ${DESTDIR}/usr/share/man/cat* ! -type d 2>/dev/null | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ @@ -2585,7 +2618,7 @@ check-old-files: .PHONY done; \ done # Check for catpages without corresponding manpages. - @find ${DESTDIR}/usr/share/man/cat* ! -type d | \ + @find ${DESTDIR}/usr/share/man/cat* ! -type d 2>/dev/null | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ @@ -2723,21 +2756,29 @@ builddtb: .PHONY # # It is expected that BW_CANONICALOBJDIR == the CANONICALOBJDIR as would be # created by bsd.obj.mk, except that we don't want to .include that file -# in this makefile. +# in this makefile. We don't do a cleandir walk if MK_AUTO_OBJ is yes +# since it is not possible for files to land in the wrong place. # -BW_CANONICALOBJDIR:=${OBJTREE}${.CURDIR} -cleanworld: .PHONY -.if exists(${BW_CANONICALOBJDIR}/) - -rm -rf ${BW_CANONICALOBJDIR}/* - -chflags -R 0 ${BW_CANONICALOBJDIR} - rm -rf ${BW_CANONICALOBJDIR}/* +.if make(cleanworld) +BW_CANONICALOBJDIR:=${OBJTOP}/ +.elif make(cleanuniverse) +BW_CANONICALOBJDIR:=${OBJROOT} +.if ${MK_UNIFIED_OBJDIR} == "no" +.error ${.TARGETS} only supported with WITH_UNIFIED_OBJDIR enabled. .endif +.endif +cleanworld cleanuniverse: .PHONY +.if !empty(BW_CANONICALOBJDIR) && exists(${BW_CANONICALOBJDIR}) + -rm -rf ${BW_CANONICALOBJDIR}* + -chflags -R 0 ${BW_CANONICALOBJDIR} + rm -rf ${BW_CANONICALOBJDIR}* +.endif +.if make(cleanworld) && ${MK_AUTO_OBJ} == "no" .if ${.CURDIR} == ${.OBJDIR} || ${.CURDIR}/obj == ${.OBJDIR} # To be safe in this case, fall back to a 'make cleandir' ${_+_}@cd ${.CURDIR}; ${MAKE} cleandir .endif - -.if defined(TARGET) && defined(TARGET_ARCH) +.endif .if ${TARGET} == ${MACHINE} && ${TARGET_ARCH} == ${MACHINE_ARCH} XDEV_CPUTYPE?=${CPUTYPE} @@ -2757,10 +2798,16 @@ XDTP?=/usr/${XDDIR} .error XDTP variable should be an absolute path .endif -CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \ +CDBOBJROOT= ${OBJROOT}${MACHINE}.${MACHINE_ARCH}/xdev/ +CDBOBJTOP= ${CDBOBJROOT}${XDDIR} +CDBENV= \ INSTALL="sh ${.CURDIR}/tools/install.sh" CDENV= ${CDBENV} \ TOOLS_PREFIX=${XDTP} +CDMAKEARGS= \ + OBJTOP=${CDBOBJTOP:Q} \ + OBJROOT=${CDBOBJROOT:Q} +CD2MAKEARGS= ${CDMAKEARGS} .if ${WANT_COMPILER_TYPE} == gcc || \ (defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == gcc) @@ -2782,14 +2829,15 @@ CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" CXX="${CXX} ${CD2CXXFLAGS} ${CD2CFLAGS}" CPP="${CPP} ${CD2CFLAGS}" \ MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} -CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp -CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN} -CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} ${MAKE} ${NOFUN} +CDTMP= ${OBJTOP}/${XDDIR}/tmp +CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${CDMAKEARGS} ${NOFUN} +CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} \ + ${MAKE} ${CD2MAKEARGS} ${NOFUN} .if ${MK_META_MODE} != "no" # Don't rebuild build-tools targets during normal build. CD2MAKE+= BUILD_TOOLS_META=.NOMETA .endif -XDDESTDIR=${DESTDIR}/${XDTP} +XDDESTDIR=${DESTDIR}${XDTP} .ORDER: xdev-build xdev-install xdev-links xdev: xdev-build xdev-install .PHONY @@ -2809,26 +2857,29 @@ _xb-bootstrap-tools: .PHONY ${_yacc} ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ ${CDMAKE} DIRPRFX=${_tool}/ all; \ ${CDMAKE} DIRPRFX=${_tool}/ DESTDIR=${CDTMP} install .endfor _xb-build-tools: .PHONY ${_+_}@cd ${.CURDIR}; \ - ${CDBENV} ${MAKE} -f Makefile.inc1 ${NOFUN} build-tools + ${CDBENV} ${MAKE} ${CDMAKEARGS} -f Makefile.inc1 ${NOFUN} build-tools -_xb-cross-tools: .PHONY -.for _tool in \ +XDEVDIRS= \ + ${_clang_libs} \ + ${_lld} \ ${_binutils} \ ${_elftctools} \ usr.bin/ar \ - ${_clang_libs} \ ${_clang} \ ${_gcc} + +_xb-cross-tools: .PHONY +.for _tool in ${XDEVDIRS} ${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,all)"; \ cd ${.CURDIR}/${_tool}; \ - if [ -z "${NO_OBJ}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ + if [ -z "${NO_OBJWALK}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ ${CDMAKE} DIRPRFX=${_tool}/ all .endfor @@ -2856,19 +2907,17 @@ xdev-install: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries .P _xi-cross-tools: .PHONY @echo "_xi-cross-tools" -.for _tool in \ - ${_binutils} \ - ${_elftctools} \ - usr.bin/ar \ - ${_clang_libs} \ - ${_clang} \ - ${_gcc} +.for _tool in ${XDEVDIRS} ${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \ cd ${.CURDIR}/${_tool}; \ ${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR} .endfor _xi-includes: .PHONY +.if !defined(NO_OBJWALK) + ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 _obj \ + DESTDIR=${XDDESTDIR} +.endif ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 includes \ DESTDIR=${XDDESTDIR} @@ -2885,7 +2934,3 @@ xdev-links: .PHONY ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}${_REVISION}-$$i; \ done -.else -xdev xdev-build xdev-install xdev-links: .PHONY - @echo "*** Error: Both TARGET and TARGET_ARCH must be defined for \"${.TARGET}\" target" -.endif diff --git a/Makefile.libcompat b/Makefile.libcompat index 6918e5f73021..b8fc76c4e152 100644 --- a/Makefile.libcompat +++ b/Makefile.libcompat @@ -59,10 +59,10 @@ LIB32WMAKEFLAGS+= -DCOMPAT_32BIT # ------------------------------------------------------------------- # soft-fp world -.if ${TARGET_ARCH} == "armv6" +.if ${TARGET_ARCH:Marmv[67]*} != "" LIBSOFTCFLAGS= -DCOMPAT_SOFTFP LIBSOFTCPUFLAGS= -mfloat-abi=softfp -LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=armv6 +LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=${TARGET_ARCH} LIBSOFTWMAKEFLAGS= -DCOMPAT_SOFTFP .endif @@ -70,7 +70,7 @@ LIBSOFTWMAKEFLAGS= -DCOMPAT_SOFTFP # Generic code for each type. # Set defaults based on type. libcompat= ${LIBCOMPAT:tl} -_LIBCOMPAT_MAKEVARS= _OBJTREE TMP CPUFLAGS CFLAGS CXXFLAGS WMAKEENV \ +_LIBCOMPAT_MAKEVARS= _OBJTOP TMP CPUFLAGS CFLAGS CXXFLAGS WMAKEENV \ WMAKEFLAGS WMAKE .for _var in ${_LIBCOMPAT_MAKEVARS} .if !empty(LIB${LIBCOMPAT}${_var}) @@ -79,8 +79,8 @@ LIBCOMPAT${_var}?= ${LIB${LIBCOMPAT}${_var}} .endfor # Shared flags -LIBCOMPAT_OBJTREE?= ${OBJTREE}${.CURDIR}/world${libcompat} -LIBCOMPATTMP?= ${OBJTREE}${.CURDIR}/lib${libcompat} +LIBCOMPAT_OBJTOP?= ${OBJTOP}/obj-lib${libcompat} +LIBCOMPATTMP?= ${LIBCOMPAT_OBJTOP}/tmp LIBCOMPATCFLAGS+= ${LIBCOMPATCPUFLAGS} \ -L${LIBCOMPATTMP}/usr/lib${libcompat} \ @@ -107,7 +107,7 @@ LIBCOMPATCXXFLAGS+= -isystem ${LIBCOMPATTMP}/usr/include/c++/v1 -std=c++11 \ .endif # Yes, the flags are redundant. -LIBCOMPATWMAKEENV+= MAKEOBJDIRPREFIX=${LIBCOMPAT_OBJTREE} \ +LIBCOMPATWMAKEENV+= \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${TMPPATH} \ SYSROOT=${LIBCOMPATTMP} \ @@ -127,6 +127,9 @@ LIBCOMPATWMAKEFLAGS+= CC="${XCC} ${LIBCOMPATCFLAGS}" \ -DNO_LINT \ MK_TESTS=no LIBCOMPATWMAKE+= ${LIBCOMPATWMAKEENV} ${MAKE} ${LIBCOMPATWMAKEFLAGS} \ + OBJTOP=${LIBCOMPAT_OBJTOP} \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ MK_MAN=no MK_HTML=no LIBCOMPATIMAKE+= ${LIBCOMPATWMAKE:NINSTALL=*:NDESTDIR=*} \ MK_TOOLCHAIN=no ${IMAKE_INSTALL} \ @@ -148,6 +151,16 @@ build${libcompat}: .PHONY @echo "--------------------------------------------------------------" @echo ">>> stage 5.1: building lib${libcompat} shim libraries" @echo "--------------------------------------------------------------" +.if !defined(NO_CLEAN) + rm -rf ${LIBCOMPATTMP} +.else +.if exists(${LIBCOMPATTMP}) + ${_+_}cd ${.CURDIR}; ${WMAKE} -DBATCH_DELETE_OLD_FILES \ + DESTDIR=${LIBCOMPATTMP} \ + delete-old delete-old-libs >/dev/null +.endif +.endif # !defined(NO_CLEAN) + mkdir -p ${LIBCOMPATTMP}/usr/include mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${LIBCOMPATTMP}/usr >/dev/null @@ -173,16 +186,21 @@ build${libcompat}: .PHONY ${_+_}cd ${.CURDIR}/${_dir}; \ WORLDTMP=${WORLDTMP} \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ - MAKEOBJDIRPREFIX=${LIBCOMPAT_OBJTREE} ${MAKE} SSP_CFLAGS= DESTDIR= \ + ${MAKE} SSP_CFLAGS= DESTDIR= \ + OBJTOP=${LIBCOMPAT_OBJTOP} \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ build-tools .endfor ${_+_}cd ${.CURDIR}; \ ${LIBCOMPATWMAKE} -f Makefile.inc1 -DNO_FSCHG libraries -.if ${libcompat} == "32" && !defined(NO_RTLD) +.if ${libcompat} == "32" .for _t in ${_obj} all +.if !defined(NO_RTLD) ${_+_}cd ${.CURDIR}/libexec/rtld-elf; PROG=ld-elf32.so.1 ${LIBCOMPATWMAKE} \ -DNO_FSCHG DIRPRFX=libexec/rtld-elf/ ${_t} +.endif ${_+_}cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIBCOMPATWMAKE} \ DIRPRFX=usr.bin/ldd ${_t} .endfor @@ -192,9 +210,11 @@ distribute${libcompat} install${libcompat}: .PHONY .for _dir in ${_LC_LIBDIRS.yes} ${_+_}cd ${.CURDIR}/${_dir}; ${LIBCOMPATIMAKE} ${.TARGET:S/${libcompat}$//} .endfor -.if ${libcompat} == "32" && !defined(NO_RTLD) +.if ${libcompat} == "32" +.if !defined(NO_RTLD) ${_+_}cd ${.CURDIR}/libexec/rtld-elf; \ PROG=ld-elf32.so.1 ${LIBCOMPATIMAKE} ${.TARGET:S/32$//} +.endif ${_+_}cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIBCOMPATIMAKE} \ ${.TARGET:S/32$//} .endif diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 2e6ec04cfb35..9377f936873d 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,16 +38,205 @@ # xargs -n1 | sort | uniq -d; # done +# 20171108: badsect(8) removal +OLD_FILES+=sbin/badsect +OLD_FILES+=rescue/badsect +OLD_FILES+=usr/share/man/man8/badsect.8.gz +# 20171105: fixing lib/libclang_rt CRTARCH for arm:armv[67]. +.if ${MACHINE} == "arm" +.if ${MACHINE_ARCH:Marmv[67]*} != "" && ${CPUTYPE:M*soft*} == "" +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-arm.a +OLD_LIBS+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-arm.so +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a +OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a +.endif +.endif +# 20171104: libcap_random should be in /lib not in /usr/lib +OLD_LIBS+=usr/lib/libcap_random.so.0 +# 20171104: Casper can work only as shared library +OLD_FILES+=usr/lib/libcasper.a +OLD_FILES+=usr/lib/libcasper_p.a +OLD_FILES+=usr/lib/libcap_dns.a +OLD_FILES+=usr/lib/libcap_dns_p.a +OLD_FILES+=usr/lib/libcap_grp.a +OLD_FILES+=usr/lib/libcap_grp_p.a +OLD_FILES+=usr/lib/libcap_pwd.a +OLD_FILES+=usr/lib/libcap_pwd_p.a +OLD_FILES+=usr/lib/libcap_random.a +OLD_FILES+=usr/lib/libcap_random_p.a +OLD_FILES+=usr/lib/libcap_sysctl.a +OLD_FILES+=usr/lib/libcap_sysctl_p.a +# 20171031: Removal of obsolete man files +OLD_FILES+=usr/share/man/man7/adding_user.7.gz +# 20171031: Disconnected libpathconv tests +OLD_DIRS+=usr/tests/lib/libpathconv +# 20171017: Removal of mbpool(9) +OLD_FILES+=usr/include/sys/mbpool.h +OLD_FILES+=usr/share/man/man9/mbpool.9.gz +OLD_FILES+=usr/share/man/man9/mbp_destroy.9.gz +OLD_FILES+=usr/share/man/man9/mbp_alloc.9.gz +OLD_FILES+=usr/share/man/man9/mbp_ext_free.9.gz +OLD_FILES+=usr/share/man/man9/mbp_count.9.gz +OLD_FILES+=usr/share/man/man9/mbp_card_free.9.gz +OLD_FILES+=usr/share/man/man9/mbp_get_keep.9.gz +OLD_FILES+=usr/share/man/man9/mbp_free.9.gz +OLD_FILES+=usr/share/man/man9/mbp_get.9.gz +OLD_FILES+=usr/share/man/man9/mbp_create.9.gz +OLD_FILES+=usr/share/man/man9/mbp_sync.9.gz +# 20171010: Remove libstand +OLD_FILES+=usr/lib/libstand.a +OLD_FILES+=usr/lib/libstand_p.a +OLD_FILES+=usr/include/stand.h +OLD_FILES+=usr/share/man/man3/libstand.3 +# 20171003: remove RCMDS +OLD_FILES+=bin/rcp +OLD_FILES+=rescue/rcp +OLD_FILES+=usr/bin/rlogin +OLD_FILES+=usr/bin/rsh +OLD_FILES+=usr/libexec/rlogind +OLD_FILES+=usr/libexec/rshd +OLD_FILES+=usr/share/man/man1/rcp.1.gz +OLD_FILES+=usr/share/man/man1/rlogin.1.gz +OLD_FILES+=usr/share/man/man1/rsh.1.gz +OLD_FILES+=usr/share/man/man8/rlogind.8.gz +OLD_FILES+=usr/share/man/man8/rshd.8.gz +# 20170927: crshared +OLD_FILES+=usr/share/man/man9/crshared.9.gz +# 20170927: procctl +OLD_FILES+=usr/share/man/man8/procctl.8.gz +OLD_FILES+=usr/sbin/procctl +# 20170926: remove unneeded man aliases and locales directory +OLD_FILES+=usr/share/man/en.ISO8859-1/man1 +OLD_FILES+=usr/share/man/en.ISO8859-1/man2 +OLD_FILES+=usr/share/man/en.ISO8859-1/man3 +OLD_FILES+=usr/share/man/en.ISO8859-1/man4 +OLD_FILES+=usr/share/man/en.ISO8859-1/man5 +OLD_FILES+=usr/share/man/en.ISO8859-1/man6 +OLD_FILES+=usr/share/man/en.ISO8859-1/man7 +OLD_FILES+=usr/share/man/en.ISO8859-1/man8 +OLD_FILES+=usr/share/man/en.ISO8859-1/man9 +OLD_DIRS+=usr/share/man/en.ISO8859-1 +OLD_FILES+=usr/share/man/en.ISO8859-1/mandoc.db +OLD_FILES+=usr/share/man/en.UTF-8/man1 +OLD_FILES+=usr/share/man/en.UTF-8/man2 +OLD_FILES+=usr/share/man/en.UTF-8/man3 +OLD_FILES+=usr/share/man/en.UTF-8/man4 +OLD_FILES+=usr/share/man/en.UTF-8/man5 +OLD_FILES+=usr/share/man/en.UTF-8/man6 +OLD_FILES+=usr/share/man/en.UTF-8/man7 +OLD_FILES+=usr/share/man/en.UTF-8/man8 +OLD_FILES+=usr/share/man/en.UTF-8/man9 +OLD_FILES+=usr/share/man/en.UTF-8/mandoc.db +OLD_DIRS+=usr/share/man/en.UTF-8 +OLD_FILES+=usr/share/man/en.ISO8859-15 +OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/man1 +OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/man3 +OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/mandoc.db +OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1 +OLD_FILES+=usr/share/openssl/man/en.ISO8859-15 +OLD_DIRS+=usr/share/man/ja/man1 +OLD_DIRS+=usr/share/man/ja/man2 +OLD_DIRS+=usr/share/man/ja/man3 +OLD_DIRS+=usr/share/man/ja/man4 +OLD_DIRS+=usr/share/man/ja/man5 +OLD_DIRS+=usr/share/man/ja/man6 +OLD_DIRS+=usr/share/man/ja/man7 +OLD_DIRS+=usr/share/man/ja/man8 +OLD_DIRS+=usr/share/man/ja/man9 +OLD_DIRS+=usr/share/man/ja # 20170913: remove unneeded catman utility OLD_FILES+=etc/periodic/weekly/330.catman OLD_FILES+=usr/bin/catman OLD_FILES+=usr/libexec/catman.local OLD_FILES+=usr/share/man/man1/catman.1.gz OLD_FILES+=usr/share/man/man8/catman.local.8.gz - +OLD_DIRS+=usr/share/man/cat1 +OLD_DIRS+=usr/share/man/cat2 +OLD_DIRS+=usr/share/man/cat3 +OLD_DIRS+=usr/share/man/cat4/amd64 +OLD_DIRS+=usr/share/man/cat4/arm +OLD_DIRS+=usr/share/man/cat4/i386 +OLD_DIRS+=usr/share/man/cat4/powerpc +OLD_DIRS+=usr/share/man/cat4/sparc64 +OLD_DIRS+=usr/share/man/cat4 +OLD_DIRS+=usr/share/man/cat5 +OLD_DIRS+=usr/share/man/cat6 +OLD_DIRS+=usr/share/man/cat7 +OLD_DIRS+=usr/share/man/cat8/amd64 +OLD_DIRS+=usr/share/man/cat8/arm +OLD_DIRS+=usr/share/man/cat8/i386 +OLD_DIRS+=usr/share/man/cat8/powerpc +OLD_DIRS+=usr/share/man/cat8/sparc64 +OLD_DIRS+=usr/share/man/cat8 +OLD_DIRS+=usr/share/man/cat9 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat1 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat2 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat3 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/amd64 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/arm +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/i386 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/powerpc +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/sparc64 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat5 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat6 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat7 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/amd64 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/arm +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/i386 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/powerpc +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/sparc64 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8 +OLD_DIRS+=usr/share/man/en.ISO8859-1/cat9 +OLD_DIRS+=usr/share/man/en.UTF-8/cat1 +OLD_DIRS+=usr/share/man/en.UTF-8/cat2 +OLD_DIRS+=usr/share/man/en.UTF-8/cat3 +OLD_DIRS+=usr/share/man/en.UTF-8/cat4/amd64 +OLD_DIRS+=usr/share/man/en.UTF-8/cat4/arm +OLD_DIRS+=usr/share/man/en.UTF-8/cat4/i386 +OLD_DIRS+=usr/share/man/en.UTF-8/cat4/powerpc +OLD_DIRS+=usr/share/man/en.UTF-8/cat4/sparc64 +OLD_DIRS+=usr/share/man/en.UTF-8/cat4 +OLD_DIRS+=usr/share/man/en.UTF-8/cat5 +OLD_DIRS+=usr/share/man/en.UTF-8/cat6 +OLD_DIRS+=usr/share/man/en.UTF-8/cat7 +OLD_DIRS+=usr/share/man/en.UTF-8/cat8/amd64 +OLD_DIRS+=usr/share/man/en.UTF-8/cat8/arm +OLD_DIRS+=usr/share/man/en.UTF-8/cat8/i386 +OLD_DIRS+=usr/share/man/en.UTF-8/cat8/powerpc +OLD_DIRS+=usr/share/man/en.UTF-8/cat8/sparc64 +OLD_DIRS+=usr/share/man/en.UTF-8/cat8 +OLD_DIRS+=usr/share/man/en.UTF-8/cat9 +OLD_DIRS+=usr/share/man/ja/cat1 +OLD_DIRS+=usr/share/man/ja/cat2 +OLD_DIRS+=usr/share/man/ja/cat3 +OLD_DIRS+=usr/share/man/ja/cat4/amd64 +OLD_DIRS+=usr/share/man/ja/cat4/arm +OLD_DIRS+=usr/share/man/ja/cat4/i386 +OLD_DIRS+=usr/share/man/ja/cat4/powerpc +OLD_DIRS+=usr/share/man/ja/cat4/sparc64 +OLD_DIRS+=usr/share/man/ja/cat4 +OLD_DIRS+=usr/share/man/ja/cat5 +OLD_DIRS+=usr/share/man/ja/cat6 +OLD_DIRS+=usr/share/man/ja/cat7 +OLD_DIRS+=usr/share/man/ja/cat8/amd64 +OLD_DIRS+=usr/share/man/ja/cat8/arm +OLD_DIRS+=usr/share/man/ja/cat8/powerpc +OLD_DIRS+=usr/share/man/ja/cat8/sparc64 +OLD_DIRS+=usr/share/man/ja/cat8 +OLD_DIRS+=usr/share/man/ja/cat9 +OLD_DIRS+=usr/share/openssl/man/cat1 +OLD_DIRS+=usr/share/openssl/man/cat3 +OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1/cat1 +OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1/cat3 # 20170802: ksyms(4) ioctl interface was removed OLD_FILES+=usr/include/sys/ksyms.h - # 20170722: new clang import which bumps version from 4.0.0 to 5.0.0. OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/asan_interface.h diff --git a/README b/README index a097ddfdb108..c9068c34ee10 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ more information). The Makefile in this directory supports a number of targets for building components (or all) of the FreeBSD source tree. See build(7) -and http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html +and https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html for more information, including setting make(1) variables. The `buildkernel` and `installkernel` targets build and install @@ -18,7 +18,7 @@ the Makefile in this directory for more information on the standard build targets and compile-time flags. Building a kernel is a somewhat more involved process. See build(7), config(8), -and http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html +and https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html for more information. Note: If you want to build and install the kernel with the @@ -81,4 +81,4 @@ usr.sbin System administration commands. For information on synchronizing your source tree with one or more of the FreeBSD Project's development branches, please see: - https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/updating-src.html + https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/current-stable.html diff --git a/README.md b/README.md index 9e1181e685b5..6b5e078f738c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ more information). The Makefile in this directory supports a number of targets for building components (or all) of the FreeBSD source tree. See build(7) -and http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html +and https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html for more information, including setting make(1) variables. The `buildkernel` and `installkernel` targets build and install @@ -20,7 +20,7 @@ the Makefile in this directory for more information on the standard build targets and compile-time flags. Building a kernel is a somewhat more involved process. See build(7), config(8), -and http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html +and https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html for more information. Note: If you want to build and install the kernel with the @@ -83,4 +83,4 @@ usr.sbin System administration commands. For information on synchronizing your source tree with one or more of the FreeBSD Project's development branches, please see: - http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/synching.html + https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/current-stable.html diff --git a/UPDATING b/UPDATING index 7d109a5de103..2a8946c7786a 100644 --- a/UPDATING +++ b/UPDATING @@ -6,7 +6,7 @@ COMMON ITEMS: section later in the file. These instructions assume that you basically know what you are doing. If not, then please consult the FreeBSD handbook: - https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/updating-src.html + https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/current-stable.html Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. @@ -51,6 +51,60 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: ****************************** SPECIAL WARNING: ****************************** +20171106: + The naive and non-compliant support of posix_fallocate(2) in ZFS + has been removed as of r325320. The system call now returns EINVAL + when used on a ZFS file. Although the new behavior complies with the + standard, some consumers are not prepared to cope with it. + One known victim is lld prior to r325420. + +20171102: + Building in a FreeBSD src checkout will automatically create object + directories now rather than store files in the current directory if + 'make obj' was not ran. Calling 'make obj' is no longer necesarry. + This feature can be disabled by setting WITHOUT_AUTO_OBJ=yes in + /etc/src-env.conf (not /etc/src.conf), or passing the option in the + environment. + +20171101: + The default MAKEOBJDIR has changed from /usr/obj/ for native + builds, and /usr/obj// for cross-builds, to a unified + /usr/obj//. This behavior can be changed to the old + format by setting WITHOUT_UNIFIED_OBJDIR=yes in /etc/src-env.conf, + the environment, or with -DWITHOUT_UNIFIED_OBJDIR when building. + The UNIFIED_OBJDIR option is a transitional feature that will be + removed for 12.0 release; please migrate to the new format for any + tools by looking up the OBJDIR used by 'make -V .OBJDIR' means rather + than hardcoding paths. + +20171028: + The native-xtools target no longer installs the files by default to the + OBJDIR. Use the native-xtools-install target with a DESTDIR to install + to ${DESTDIR}/${NXTP} where NXTP defaults to /nxb-bin. + +20171021: + As part of the boot loader infrastructure cleanup, LOADER_*_SUPPORT + options are changing from controlling the build if defined / undefined + to controlling the build with explicit 'yes' or 'no' values. They will + shift to WITH/WITHOUT options to match other options in the system. + +20171010: + libstand has turned into a private library for sys/boot use only. + It is no longer supported as a public interface outside of sys/boot. + +20171005: + The arm port has split armv6 into armv6 and armv7. armv7 is now + a valid TARGET_ARCH/MACHINE_ARCH setting. If you have an armv7 system + and are running a kernel from before r324363, you will need to add + MACHINE_ARCH=armv7 to 'make buildworld' to do a native build. + +20171003: + When building multiple kernels using KERNCONF, non-existent KERNCONF + files will produce an error and buildkernel will fail. Previously + missing KERNCONF files silently failed giving no indication as to + why, only to subsequently discover during installkernel that the + desired kernel was never built in the first place. + 20170912: The default serial number format for CTL LUNs has changed. This will affect users who use /dev/diskid/* device nodes, or whose FibreChannel @@ -66,8 +120,8 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: soft-float everything else should be affected. 20170826: - During boot the geli passphrase will be hidden. To restore previous - behavior see geli(8) configuration options. + The geli password typed at boot is now hidden. To restore the previous + behavior, see geli(8) for configuration options. 20170825: Move PMTUD blackhole counters to TCPSTATS and remove them from bare @@ -1815,21 +1869,6 @@ COMMON ITEMS: make installkernel KERNCONF=YOUR_KERNEL_HERE KODIR=/boot/testkernel nextboot -k testkernel - To just build a kernel when you know that it won't mess you up - -------------------------------------------------------------- - This assumes you are already running a CURRENT system. Replace - ${arch} with the architecture of your machine (e.g. "i386", - "arm", "amd64", "ia64", "pc98", "sparc64", "powerpc", "mips", etc). - - cd src/sys/${arch}/conf - config KERNEL_NAME_HERE - cd ../compile/KERNEL_NAME_HERE - make depend - make - make install - - If this fails, go to the "To build a kernel" section. - To rebuild everything and install it on the current system. ----------------------------------------------------------- # Note: sometimes if you are running current you gotta do more than @@ -1837,7 +1876,8 @@ COMMON ITEMS: make buildworld - make kernel KERNCONF=YOUR_KERNEL_HERE + make buildkernel KERNCONF=YOUR_KERNEL_HERE + make installkernel KERNCONF=YOUR_KERNEL_HERE [1] [3] mergemaster -Fp [5] @@ -1937,10 +1977,7 @@ COMMON ITEMS: Make sure that you merge any new devices from GENERIC since the last time you updated your kernel config file. - [9] When checking out sources, you must include the -P flag to have - cvs prune empty directories. - - If CPUTYPE is defined in your /etc/make.conf, make sure to use the + [9] If CPUTYPE is defined in your /etc/make.conf, make sure to use the "?=" instead of the "=" assignment operator, so that buildworld can override the CPUTYPE if it needs to. diff --git a/bin/Makefile b/bin/Makefile index 3e7571c27e61..3ad97ac8d624 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -40,7 +40,6 @@ SUBDIR= cat \ test \ uuidgen -SUBDIR.${MK_RCMDS}+= rcp SUBDIR.${MK_SENDMAIL}+= rmail SUBDIR.${MK_TCSH}+= csh SUBDIR.${MK_TESTS}+= tests diff --git a/bin/cat/Makefile.depend b/bin/cat/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/cat/Makefile.depend +++ b/bin/cat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/cat/cat.c b/bin/cat/cat.c index 770ab61a08a4..57d48028906e 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -226,10 +226,16 @@ cook_cat(FILE *fp) } else gobble = 0; } - if (nflag && (!bflag || ch != '\n')) { - (void)fprintf(stdout, "%6d\t", ++line); - if (ferror(stdout)) - break; + if (nflag) { + if (!bflag || ch != '\n') { + (void)fprintf(stdout, "%6d\t", ++line); + if (ferror(stdout)) + break; + } else if (eflag) { + (void)fprintf(stdout, "%6s\t", ""); + if (ferror(stdout)) + break; + } } } if (ch == '\n') { diff --git a/bin/cat/tests/Makefile b/bin/cat/tests/Makefile index 92e16aea1732..ebc313c5a091 100644 --- a/bin/cat/tests/Makefile +++ b/bin/cat/tests/Makefile @@ -17,10 +17,4 @@ ${PACKAGE}FILES+= d_vt_output.out .include -d_align.out: ${TESTSRC}/d_align.out - sed -E -e 's,^[[:space:]]{7}\$$$$,\$$,' < ${.ALLSRC} > ${.TARGET}.tmp - mv ${.TARGET}.tmp ${.TARGET} - -CLEANFILES+= d_align.out d_align.out.tmp - .include diff --git a/bin/chflags/Makefile b/bin/chflags/Makefile index e37650780a1d..1cee973c5655 100644 --- a/bin/chflags/Makefile +++ b/bin/chflags/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.include + PACKAGE=runtime PROG= chflags diff --git a/bin/chflags/Makefile.depend b/bin/chflags/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/chflags/Makefile.depend +++ b/bin/chflags/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/chflags/tests/Makefile.depend b/bin/chflags/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/chflags/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/chio/Makefile.depend b/bin/chio/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/chio/Makefile.depend +++ b/bin/chio/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/chmod/Makefile.depend b/bin/chmod/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/chmod/Makefile.depend +++ b/bin/chmod/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/chmod/tests/Makefile.depend b/bin/chmod/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/chmod/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/cp/Makefile.depend b/bin/cp/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/cp/Makefile.depend +++ b/bin/cp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/csh/Makefile.depend b/bin/csh/Makefile.depend index c7bb5b0b113c..05f33d1d7799 100644 --- a/bin/csh/Makefile.depend +++ b/bin/csh/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/bin/date/Makefile.depend b/bin/date/Makefile.depend index 26cae4ede976..4bd09984c29d 100644 --- a/bin/date/Makefile.depend +++ b/bin/date/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/protocols \ include/xlocale \ diff --git a/bin/dd/Makefile.depend b/bin/dd/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/bin/dd/Makefile.depend +++ b/bin/dd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/df/Makefile.depend b/bin/df/Makefile.depend index 137678c21e46..5770a091f2a6 100644 --- a/bin/df/Makefile.depend +++ b/bin/df/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/domainname/Makefile.depend b/bin/domainname/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/domainname/Makefile.depend +++ b/bin/domainname/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/echo/Makefile.depend b/bin/echo/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/bin/echo/Makefile.depend +++ b/bin/echo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/echo/tests/Makefile.depend b/bin/echo/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/echo/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/ed/Makefile.depend b/bin/ed/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/bin/ed/Makefile.depend +++ b/bin/ed/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/expr/Makefile.depend b/bin/expr/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/bin/expr/Makefile.depend +++ b/bin/expr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/getfacl/Makefile.depend b/bin/getfacl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/getfacl/Makefile.depend +++ b/bin/getfacl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/hostname/Makefile.depend b/bin/hostname/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/hostname/Makefile.depend +++ b/bin/hostname/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/kenv/Makefile.depend b/bin/kenv/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/kenv/Makefile.depend +++ b/bin/kenv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/kill/Makefile.depend b/bin/kill/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/kill/Makefile.depend +++ b/bin/kill/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/ln/Makefile.depend b/bin/ln/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/ln/Makefile.depend +++ b/bin/ln/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/ln/tests/Makefile.depend b/bin/ln/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/ln/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/ls/Makefile.depend b/bin/ls/Makefile.depend index 6151c71a3632..6f1067211443 100644 --- a/bin/ls/Makefile.depend +++ b/bin/ls/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/mkdir/Makefile b/bin/mkdir/Makefile index ab05a100f39b..79ed25fdc204 100644 --- a/bin/mkdir/Makefile +++ b/bin/mkdir/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 # $FreeBSD$ +.include + PACKAGE=runtime PROG= mkdir diff --git a/bin/mkdir/Makefile.depend b/bin/mkdir/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/mkdir/Makefile.depend +++ b/bin/mkdir/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/mkdir/tests/Makefile.depend b/bin/mkdir/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/mkdir/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/mv/Makefile.depend b/bin/mv/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/mv/Makefile.depend +++ b/bin/mv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/pax/Makefile.depend b/bin/pax/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/pax/Makefile.depend +++ b/bin/pax/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/pkill/Makefile.depend b/bin/pkill/Makefile.depend index 35df7dcbf24e..6f5a5f79bf30 100644 --- a/bin/pkill/Makefile.depend +++ b/bin/pkill/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/ps/Makefile.depend b/bin/ps/Makefile.depend index 1576eff2f0c6..eefffb37d491 100644 --- a/bin/ps/Makefile.depend +++ b/bin/ps/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c index 55c89a134250..5c873910f33c 100644 --- a/bin/ps/keyword.c +++ b/bin/ps/keyword.c @@ -199,7 +199,8 @@ static VAR var[] = { {"tdaddr", "TDADDR", NULL, "thread-address", 0, kvar, KOFF(ki_tdaddr), KPTR, "lx", 0}, {"tdev", "TDEV", NULL, "terminal-device", 0, tdev, 0, CHAR, NULL, 0}, - {"tdnam", "TDNAM", NULL, "terminal-device-name", LJUST, tdnam, 0, CHAR, + {"tdnam", "", "tdname", NULL, 0, NULL, 0, CHAR, NULL, 0}, + {"tdname", "TDNAME", NULL, "thread-name", LJUST, tdnam, 0, CHAR, NULL, 0}, {"time", "TIME", NULL, "cpu-time", USER, cputime, 0, CHAR, NULL, 0}, {"tpgid", "TPGID", NULL, "terminal-process-gid", 0, kvar, diff --git a/bin/ps/ps.1 b/bin/ps/ps.1 index 649f5e9e7082..67bea88f1a4d 100644 --- a/bin/ps/ps.1 +++ b/bin/ps/ps.1 @@ -29,7 +29,7 @@ .\" @(#)ps.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd September 7, 2017 +.Dd October 9, 2017 .Dt PS 1 .Os .Sh NAME @@ -675,6 +675,8 @@ saved UID from a setuid executable accumulated system CPU time .It Cm tdaddr thread address +.It Cm tdname +thread name .It Cm tdev control terminal device number .It Cm time diff --git a/bin/ps/ps.c b/bin/ps/ps.c index cb3e5e64aae5..40dc4f77f6b2 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -523,7 +523,11 @@ main(int argc, char *argv[]) */ nentries = -1; kp = kvm_getprocs(kd, what, flag, &nentries); - if ((kp == NULL && nentries > 0) || (kp != NULL && nentries < 0)) + /* + * Ignore ESRCH to preserve behaviour of "ps -p nonexistent-pid" + * not reporting an error. + */ + if ((kp == NULL && errno != ESRCH) || (kp != NULL && nentries < 0)) xo_errx(1, "%s", kvm_geterr(kd)); nkept = 0; if (nentries > 0) { diff --git a/bin/pwait/Makefile.depend b/bin/pwait/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/pwait/Makefile.depend +++ b/bin/pwait/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/pwd/Makefile.depend b/bin/pwd/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/pwd/Makefile.depend +++ b/bin/pwd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/rcp/Makefile b/bin/rcp/Makefile deleted file mode 100644 index b1165c642248..000000000000 --- a/bin/rcp/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 7/19/93 -# $FreeBSD$ - -PACKAGE=rcmds -PROG= rcp -SRCS= rcp.c util.c -CFLAGS+=-DBINDIR=${BINDIR} - -PACKAGE=rcmds - -BINOWN= root -BINMODE=4555 - -HAS_TESTS= -SUBDIR.${MK_TESTS}+= tests - -.include diff --git a/bin/rcp/rcp.1 b/bin/rcp/rcp.1 deleted file mode 100644 index 9d2b8ae35bca..000000000000 --- a/bin/rcp/rcp.1 +++ /dev/null @@ -1,160 +0,0 @@ -.\"- -.\" Copyright (c) 1983, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)rcp.1 8.1 (Berkeley) 5/31/93 -.\" $FreeBSD$ -.\" -.Dd July 3, 2017 -.Dt RCP 1 -.Os -.Sh NAME -.Nm rcp -.Nd remote file copy -.Sh SYNOPSIS -.Nm -.Op Fl 46p -.Ar file1 file2 -.Nm -.Op Fl 46pr -.Ar -.Ar directory -.Sh DEPRECATION NOTICE -.Nm -is deprecated and will be removed from future versions of the -.Fx -base system. -If -.Nm -is still required, it can be installed from ports or packages -(net/bsdrcmds). -.Sh DESCRIPTION -The -.Nm -utility copies files between machines. -Each -.Ar file -or -.Ar directory -argument is either a remote file name of the -form -.Dq ruser@rhost:path , -or a local file name (containing no -.Ql :\& -characters, -or a -.Ql / -before any -.Ql :\& Ns -s). -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl 4 -Use IPv4 addresses only. -.It Fl 6 -Use IPv6 addresses only. -.It Fl p -Cause -.Nm -to attempt to preserve (duplicate) in its copies the modification -times and modes of the source files, ignoring the -.Xr umask 2 . -By default, the mode and owner of -.Ar file2 -are preserved if it already existed; otherwise the mode of the source file -modified by the -.Xr umask 2 -on the destination host is used. -.It Fl r -If any of the source files are directories, -.Nm -copies each subtree rooted at that name; in this case -the destination must be a directory. -.El -.Pp -If -.Ar path -is not a full path name, it is interpreted relative to -the login directory of the specified user -.Ar ruser -on -.Ar rhost , -or your current user name if no other remote user name is specified. -A -.Ar path -on a remote host may be quoted (using -.Ql \e , -.Ql \&" , -or -.Ql \(aa ) -so that the metacharacters are interpreted remotely. -.Pp -The -.Nm -utility does not prompt for passwords; it performs remote execution -via -.Xr rsh 1 , -and requires the same authorization. -.Pp -The -.Nm -utility handles third party copies, where neither source nor target files -are on the current machine. -.Sh SEE ALSO -.Xr cp 1 , -.Xr ftp 1 , -.Xr rlogin 1 , -.Xr rsh 1 , -.Xr hosts.equiv 5 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . -The version of -.Nm -described here -has been reimplemented with Kerberos in -.Bx 4.3 Reno . -.Sh BUGS -Does not detect all cases where the target of a copy might -be a file in cases where only a directory should be legal. -.Pp -Is confused by any output generated by commands in a -.Pa .login , -.Pa .profile , -or -.Pa .cshrc -file on the remote host. -.Pp -The destination user and hostname may have to be specified as -.Dq rhost.ruser -when the destination machine is running the -.Bx 4.2 -version of -.Nm . diff --git a/bin/rcp/rcp.c b/bin/rcp/rcp.c deleted file mode 100644 index 3c6fdcf5ba41..000000000000 --- a/bin/rcp/rcp.c +++ /dev/null @@ -1,791 +0,0 @@ -/*- - * Copyright (c) 1983, 1990, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2002 Networks Associates Technology, Inc. - * All rights reserved. - * - * Portions of this software were developed for the FreeBSD Project by - * ThinkSec AS and NAI Labs, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#if 0 -#ifndef lint -static char const copyright[] = -"@(#) Copyright (c) 1983, 1990, 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94"; -#endif /* not lint */ -#endif -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" - -#define OPTIONS "46dfprt" - -static struct passwd *pwd; -static u_short port; -static uid_t userid; -static int errs, rem; -int iamremote; -static int pflag, iamrecursive, targetshouldbedirectory; -static int family = PF_UNSPEC; - -static int argc_copy; -static const char **argv_copy; - -static char period[] = "."; - -#define CMDNEEDS 64 -static char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ - -int response(void); -void rsource(char *, struct stat *); -void sink(int, char *[]); -void source(int, char *[]); -void tolocal(int, char *[]); -void toremote(char *, int, char *[]); -void usage(void); - -int -main(int argc, char *argv[]) -{ - struct servent *sp; - int ch, fflag, i, tflag; - char *targ; - - /* - * Prepare for execing ourselves. - */ - argc_copy = argc + 1; - argv_copy = malloc((argc_copy + 1) * sizeof(*argv_copy)); - if (argv_copy == NULL) - err(1, "malloc"); - argv_copy[0] = argv[0]; - argv_copy[1] = "-K"; - for (i = 1; i < argc; ++i) { - argv_copy[i + 1] = strdup(argv[i]); - if (argv_copy[i + 1] == NULL) - errx(1, "strdup: out of memory"); - } - argv_copy[argc + 1] = NULL; - - fflag = tflag = 0; - while ((ch = getopt(argc, argv, OPTIONS)) != -1) - switch(ch) { /* User-visible flags. */ - case '4': - family = PF_INET; - break; - - case '6': - family = PF_INET6; - break; - - case 'p': - pflag = 1; - break; - case 'r': - iamrecursive = 1; - break; - /* Server options. */ - case 'd': - targetshouldbedirectory = 1; - break; - case 'f': /* "from" */ - iamremote = 1; - fflag = 1; - break; - case 't': /* "to" */ - iamremote = 1; - tflag = 1; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - sp = getservbyname("shell", "tcp"); - if (sp == NULL) - errx(1, "shell/tcp: unknown service"); - port = sp->s_port; - - if ((pwd = getpwuid(userid = getuid())) == NULL) - errx(1, "unknown user %d", (int)userid); - - rem = STDIN_FILENO; /* XXX */ - - if (fflag) { /* Follow "protocol", send data. */ - (void)response(); - (void)setuid(userid); - source(argc, argv); - exit(errs); - } - - if (tflag) { /* Receive data. */ - (void)setuid(userid); - sink(argc, argv); - exit(errs); - } - - if (argc < 2) - usage(); - if (argc > 2) - targetshouldbedirectory = 1; - - rem = -1; - /* Command to be executed on remote system using "rsh". */ - (void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s", - iamrecursive ? " -r" : "", pflag ? " -p" : "", - targetshouldbedirectory ? " -d" : ""); - - (void)signal(SIGPIPE, lostconn); - - if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ - toremote(targ, argc, argv); - else { - tolocal(argc, argv); /* Dest is local host. */ - if (targetshouldbedirectory) - verifydir(argv[argc - 1]); - } - exit(errs); -} - -void -toremote(char *targ, int argc, char *argv[]) -{ - int i, tos; - char *bp, *host, *src, *suser, *thost, *tuser; - - *targ++ = 0; - if (*targ == 0) - targ = period; - - if ((thost = strchr(argv[argc - 1], '@'))) { - /* user@host */ - *thost++ = 0; - tuser = argv[argc - 1]; - if (*tuser == '\0') - tuser = NULL; - else if (!okname(tuser)) - exit(1); - } else { - thost = argv[argc - 1]; - tuser = NULL; - } - - for (i = 0; i < argc - 1; i++) { - src = colon(argv[i]); - if (src) { /* remote to remote */ - *src++ = 0; - if (*src == 0) - src = period; - host = strchr(argv[i], '@'); - if (host) { - *host++ = 0; - suser = argv[i]; - if (*suser == '\0') - suser = pwd->pw_name; - else if (!okname(suser)) { - ++errs; - continue; - } - if (asprintf(&bp, - "%s %s -l %s -n %s %s '%s%s%s:%s'", - _PATH_RSH, host, suser, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ) == -1) - err(1, "asprintf"); - } else - if (asprintf(&bp, - "exec %s %s -n %s %s '%s%s%s:%s'", - _PATH_RSH, argv[i], cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ) == -1) - err(1, "asprintf"); - (void)susystem(bp, userid); - (void)free(bp); - } else { /* local to remote */ - if (rem == -1) { - if (asprintf(&bp, "%s -t %s", cmd, targ) - == -1) - err(1, "asprintf"); - host = thost; - rem = rcmd_af(&host, port, - pwd->pw_name, - tuser ? tuser : pwd->pw_name, - bp, 0, family); - if (rem < 0) - exit(1); - if (family == PF_INET) { - tos = IPTOS_THROUGHPUT; - if (setsockopt(rem, IPPROTO_IP, IP_TOS, - &tos, sizeof(int)) < 0) - warn("TOS (ignored)"); - } - if (response() < 0) - exit(1); - (void)free(bp); - (void)setuid(userid); - } - source(1, argv+i); - } - } -} - -void -tolocal(int argc, char *argv[]) -{ - int i, len, tos; - char *bp, *host, *src, *suser; - - for (i = 0; i < argc - 1; i++) { - if (!(src = colon(argv[i]))) { /* Local to local. */ - len = strlen(_PATH_CP) + strlen(argv[i]) + - strlen(argv[argc - 1]) + 20; - if (!(bp = malloc(len))) - err(1, "malloc"); - (void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -PR" : "", pflag ? " -p" : "", - argv[i], argv[argc - 1]); - if (susystem(bp, userid)) - ++errs; - (void)free(bp); - continue; - } - *src++ = 0; - if (*src == 0) - src = period; - if ((host = strchr(argv[i], '@')) == NULL) { - host = argv[i]; - suser = pwd->pw_name; - } else { - *host++ = 0; - suser = argv[i]; - if (*suser == '\0') - suser = pwd->pw_name; - else if (!okname(suser)) { - ++errs; - continue; - } - } - len = strlen(src) + CMDNEEDS + 20; - if ((bp = malloc(len)) == NULL) - err(1, "malloc"); - (void)snprintf(bp, len, "%s -f %s", cmd, src); - rem = rcmd_af(&host, port, pwd->pw_name, suser, bp, 0, - family); - (void)free(bp); - if (rem < 0) { - ++errs; - continue; - } - (void)seteuid(userid); - if (family == PF_INET) { - tos = IPTOS_THROUGHPUT; - if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos, - sizeof(int)) < 0) - warn("TOS (ignored)"); - } - sink(1, argv + argc - 1); - (void)seteuid(0); - (void)close(rem); - rem = -1; - } -} - -void -source(int argc, char *argv[]) -{ - struct stat stb; - static BUF buffer; - BUF *bp; - off_t i; - int amt, fd, haderr, indx, result; - char *last, *name, buf[BUFSIZ]; - - for (indx = 0; indx < argc; ++indx) { - name = argv[indx]; - if ((fd = open(name, O_RDONLY, 0)) < 0) - goto syserr; - if (fstat(fd, &stb)) { -syserr: run_err("%s: %s", name, strerror(errno)); - goto next; - } - switch (stb.st_mode & S_IFMT) { - case S_IFREG: - break; - case S_IFDIR: - if (iamrecursive) { - rsource(name, &stb); - goto next; - } - /* FALLTHROUGH */ - default: - run_err("%s: not a regular file", name); - goto next; - } - if ((last = strrchr(name, '/')) == NULL) - last = name; - else - ++last; - if (pflag) { - /* - * Make it compatible with possible future - * versions expecting microseconds. - */ - (void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n", - (long)stb.st_mtim.tv_sec, - (long)stb.st_atim.tv_sec); - (void)write(rem, buf, strlen(buf)); - if (response() < 0) - goto next; - } -#define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) - (void)snprintf(buf, sizeof(buf), "C%04o %jd %s\n", - stb.st_mode & MODEMASK, (intmax_t)stb.st_size, last); - (void)write(rem, buf, strlen(buf)); - if (response() < 0) - goto next; - if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) { -next: if (fd >= 0) - (void)close(fd); - continue; - } - - /* Keep writing after an error so that we stay sync'd up. */ - for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { - amt = bp->cnt; - if (i + amt > stb.st_size) - amt = stb.st_size - i; - if (!haderr) { - result = read(fd, bp->buf, amt); - if (result != amt) - haderr = result >= 0 ? EIO : errno; - } - if (haderr) - (void)write(rem, bp->buf, amt); - else { - result = write(rem, bp->buf, amt); - if (result != amt) - haderr = result >= 0 ? EIO : errno; - } - } - if (close(fd) && !haderr) - haderr = errno; - if (!haderr) - (void)write(rem, "", 1); - else - run_err("%s: %s", name, strerror(haderr)); - (void)response(); - } -} - -void -rsource(char *name, struct stat *statp) -{ - DIR *dirp; - struct dirent *dp; - char *last, *vect[1], path[PATH_MAX]; - - if (!(dirp = opendir(name))) { - run_err("%s: %s", name, strerror(errno)); - return; - } - last = strrchr(name, '/'); - if (last == NULL) - last = name; - else - last++; - if (pflag) { - (void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n", - (long)statp->st_mtim.tv_sec, - (long)statp->st_atim.tv_sec); - (void)write(rem, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - } - (void)snprintf(path, sizeof(path), - "D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last); - (void)write(rem, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - while ((dp = readdir(dirp))) { - if (dp->d_ino == 0) - continue; - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path)) { - run_err("%s/%s: name too long", name, dp->d_name); - continue; - } - (void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name); - vect[0] = path; - source(1, vect); - } - (void)closedir(dirp); - (void)write(rem, "E\n", 2); - (void)response(); -} - -void -sink(int argc, char *argv[]) -{ - static BUF buffer; - struct stat stb; - struct timeval tv[2]; - enum { YES, NO, DISPLAYED } wrerr; - BUF *bp; - off_t i, j, size; - int amt, exists, first, mask, mode, ofd, omode; - size_t count; - int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ], path[PATH_MAX]; - const char *why; - -#define atime tv[0] -#define mtime tv[1] -#define SCREWUP(str) { why = str; goto screwup; } - - setimes = targisdir = 0; - mask = umask(0); - if (!pflag) - (void)umask(mask); - if (argc != 1) { - run_err("ambiguous target"); - exit(1); - } - targ = *argv; - if (targetshouldbedirectory) - verifydir(targ); - (void)write(rem, "", 1); - if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) - targisdir = 1; - for (first = 1;; first = 0) { - cp = buf; - if (read(rem, cp, 1) <= 0) - return; - if (*cp++ == '\n') - SCREWUP("unexpected "); - do { - if (read(rem, &ch, sizeof(ch)) != sizeof(ch)) - SCREWUP("lost connection"); - *cp++ = ch; - } while (cp < &buf[BUFSIZ - 1] && ch != '\n'); - *cp = 0; - - if (buf[0] == '\01' || buf[0] == '\02') { - if (iamremote == 0) - (void)write(STDERR_FILENO, - buf + 1, strlen(buf + 1)); - if (buf[0] == '\02') - exit(1); - ++errs; - continue; - } - if (buf[0] == 'E') { - (void)write(rem, "", 1); - return; - } - - if (ch == '\n') - *--cp = 0; - - cp = buf; - if (*cp == 'T') { - setimes++; - cp++; - mtime.tv_sec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("mtime.sec not delimited"); - mtime.tv_usec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("mtime.usec not delimited"); - atime.tv_sec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("atime.sec not delimited"); - atime.tv_usec = strtol(cp, &cp, 10); - if (!cp || *cp++ != '\0') - SCREWUP("atime.usec not delimited"); - (void)write(rem, "", 1); - continue; - } - if (*cp != 'C' && *cp != 'D') { - /* - * Check for the case "rcp remote:foo\* local:bar". - * In this case, the line "No match." can be returned - * by the shell before the rcp command on the remote is - * executed so the ^Aerror_message convention isn't - * followed. - */ - if (first) { - run_err("%s", cp); - exit(1); - } - SCREWUP("expected control record"); - } - mode = 0; - for (++cp; cp < buf + 5; cp++) { - if (*cp < '0' || *cp > '7') - SCREWUP("bad mode"); - mode = (mode << 3) | (*cp - '0'); - } - if (*cp++ != ' ') - SCREWUP("mode not delimited"); - - for (size = 0; isdigit(*cp);) - size = size * 10 + (*cp++ - '0'); - if (*cp++ != ' ') - SCREWUP("size not delimited"); - if (targisdir) { - if (strlen(targ) + (*targ ? 1 : 0) + strlen(cp) - >= sizeof(path)) { - run_err("%s%s%s: name too long", targ, - *targ ? "/" : "", cp); - exit(1); - } - (void)snprintf(path, sizeof(path), "%s%s%s", targ, - *targ ? "/" : "", cp); - np = path; - } else - np = targ; - exists = stat(np, &stb) == 0; - if (buf[0] == 'D') { - int mod_flag = pflag; - if (exists) { - if (!S_ISDIR(stb.st_mode)) { - errno = ENOTDIR; - goto bad; - } - if (pflag) - (void)chmod(np, mode); - } else { - /* Handle copying from a read-only directory */ - mod_flag = 1; - if (mkdir(np, mode | S_IRWXU) < 0) - goto bad; - } - vect[0] = np; - sink(1, vect); - if (setimes) { - setimes = 0; - if (utimes(np, tv) < 0) - run_err("%s: set times: %s", - np, strerror(errno)); - } - if (mod_flag) - (void)chmod(np, mode); - continue; - } - omode = mode; - mode |= S_IWRITE; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { -bad: run_err("%s: %s", np, strerror(errno)); - continue; - } - (void)write(rem, "", 1); - if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) { - (void)close(ofd); - continue; - } - cp = bp->buf; - wrerr = NO; - for (count = i = 0; i < size; i += BUFSIZ) { - amt = BUFSIZ; - if (i + amt > size) - amt = size - i; - count += amt; - do { - j = read(rem, cp, amt); - if (j <= 0) { - run_err("%s", j ? strerror(errno) : - "dropped connection"); - exit(1); - } - amt -= j; - cp += j; - } while (amt > 0); - if (count == bp->cnt) { - /* Keep reading so we stay sync'd up. */ - if (wrerr == NO) { - j = write(ofd, bp->buf, count); - if (j != (off_t)count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; - } - } - count = 0; - cp = bp->buf; - } - } - if (count != 0 && wrerr == NO && - (j = write(ofd, bp->buf, count)) != (off_t)count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; - } - if (ftruncate(ofd, size)) { - run_err("%s: truncate: %s", np, strerror(errno)); - wrerr = DISPLAYED; - } - if (pflag) { - if (exists || omode != mode) - if (fchmod(ofd, omode)) - run_err("%s: set mode: %s", - np, strerror(errno)); - } else { - if (!exists && omode != mode) - if (fchmod(ofd, omode & ~mask)) - run_err("%s: set mode: %s", - np, strerror(errno)); - } - (void)close(ofd); - (void)response(); - if (setimes && wrerr == NO) { - setimes = 0; - if (utimes(np, tv) < 0) { - run_err("%s: set times: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } - } - switch(wrerr) { - case YES: - run_err("%s: %s", np, strerror(wrerrno)); - break; - case NO: - (void)write(rem, "", 1); - break; - case DISPLAYED: - break; - } - } -screwup: - run_err("protocol error: %s", why); - exit(1); -} - -int -response(void) -{ - char ch, *cp, resp, rbuf[BUFSIZ]; - - if (read(rem, &resp, sizeof(resp)) != sizeof(resp)) - lostconn(0); - - cp = rbuf; - switch(resp) { - case 0: /* ok */ - return (0); - default: - *cp++ = resp; - /* FALLTHROUGH */ - case 1: /* error, followed by error msg */ - case 2: /* fatal error, "" */ - do { - if (read(rem, &ch, sizeof(ch)) != sizeof(ch)) - lostconn(0); - *cp++ = ch; - } while (cp < &rbuf[BUFSIZ] && ch != '\n'); - - if (!iamremote) - (void)write(STDERR_FILENO, rbuf, cp - rbuf); - ++errs; - if (resp == 1) - return (-1); - exit(1); - } - /* NOTREACHED */ -} - -void -usage(void) -{ - (void)fprintf(stderr, "%s\n%s\n", - "usage: rcp [-46p] file1 file2", - " rcp [-46pr] file ... directory"); - exit(1); -} - -#include - -void -run_err(const char *fmt, ...) -{ - static FILE *fp; - va_list ap; - - ++errs; - if (fp == NULL && !(fp = fdopen(rem, "w"))) - return; - (void)fprintf(fp, "%c", 0x01); - (void)fprintf(fp, "rcp: "); - va_start(ap, fmt); - (void)vfprintf(fp, fmt, ap); - va_end(ap); - (void)fprintf(fp, "\n"); - (void)fflush(fp); - - if (!iamremote) { - va_start(ap, fmt); - vwarnx(fmt, ap); - va_end(ap); - } -} diff --git a/bin/rcp/tests/Makefile b/bin/rcp/tests/Makefile deleted file mode 100644 index 99d653aa89a8..000000000000 --- a/bin/rcp/tests/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -ATF_TESTS_SH+= rcp_test - -.include diff --git a/bin/rcp/tests/rcp_test.sh b/bin/rcp/tests/rcp_test.sh deleted file mode 100644 index 62a072b3b6dd..000000000000 --- a/bin/rcp/tests/rcp_test.sh +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2017 Shivansh Rai -# All rights reserved. -# -# 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 AUTHOR 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 AUTHOR 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. -# -# $FreeBSD$ -# - -usage_output='usage: rcp' - -atf_test_case invalid_usage -invalid_usage_head() -{ - atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message" -} - -invalid_usage_body() -{ - atf_check -s not-exit:0 -e match:"$usage_output" rcp -4 - atf_check -s not-exit:0 -e match:"$usage_output" rcp -6 - atf_check -s not-exit:0 -e match:"$usage_output" rcp -p - atf_check -s not-exit:0 -e match:"$usage_output" rcp -r -} - -atf_test_case no_arguments -no_arguments_head() -{ - atf_set "descr" "Verify that rcp(1) fails and generates a valid usage message when no arguments are supplied" -} - -no_arguments_body() -{ - atf_check -s not-exit:0 -e match:"$usage_output" rcp -} - -atf_init_test_cases() -{ - atf_add_test_case invalid_usage - atf_add_test_case no_arguments -} diff --git a/bin/rcp/util.c b/bin/rcp/util.c deleted file mode 100644 index 501123eb356c..000000000000 --- a/bin/rcp/util.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)util.c 8.2 (Berkeley) 4/2/94"; -#endif -#endif /* not lint */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" - -char * -colon(char *cp) -{ - if (*cp == ':') /* Leading colon is part of file name. */ - return (0); - - for (; *cp; ++cp) { - if (*cp == ':') - return (cp); - if (*cp == '/') - return (0); - } - return (0); -} - -void -verifydir(char *cp) -{ - struct stat stb; - - if (!stat(cp, &stb)) { - if (S_ISDIR(stb.st_mode)) - return; - errno = ENOTDIR; - } - run_err("%s: %s", cp, strerror(errno)); - exit(1); -} - -int -okname(char *cp0) -{ - int c; - char *cp; - - cp = cp0; - do { - c = *cp; - if (c & 0200) - goto bad; - if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.') - goto bad; - } while (*++cp); - return (1); - -bad: warnx("%s: invalid user name", cp0); - return (0); -} - -int -susystem(char *s, int userid) -{ - sig_t istat, qstat; - int status; - pid_t pid; - - pid = vfork(); - switch (pid) { - case -1: - return (127); - - case 0: - (void)setuid(userid); - execl(_PATH_BSHELL, "sh", "-c", s, (char *)NULL); - _exit(127); - } - istat = signal(SIGINT, SIG_IGN); - qstat = signal(SIGQUIT, SIG_IGN); - if (waitpid(pid, &status, 0) < 0) - status = -1; - (void)signal(SIGINT, istat); - (void)signal(SIGQUIT, qstat); - return (status); -} - -BUF * -allocbuf(BUF *bp, int fd, int blksize) -{ - struct stat stb; - size_t size; - - if (fstat(fd, &stb) < 0) { - run_err("fstat: %s", strerror(errno)); - return (0); - } - size = roundup(stb.st_blksize, blksize); - if (size == 0) - size = blksize; - if (bp->cnt >= size) - return (bp); - if ((bp->buf = realloc(bp->buf, size)) == NULL) { - bp->cnt = 0; - run_err("%s", strerror(errno)); - return (0); - } - bp->cnt = size; - return (bp); -} - -void -lostconn(int signo __unused) -{ - if (!iamremote) - warnx("lost connection"); - exit(1); -} diff --git a/bin/realpath/Makefile.depend b/bin/realpath/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/bin/realpath/Makefile.depend +++ b/bin/realpath/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/bin/rm/Makefile.depend b/bin/rm/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/rm/Makefile.depend +++ b/bin/rm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/rm/rm.c b/bin/rm/rm.c index bb05aac6cac9..af3322199408 100644 --- a/bin/rm/rm.c +++ b/bin/rm/rm.c @@ -515,7 +515,7 @@ check(const char *path, const char *name, struct stat *sp) "%s: -P was specified, but file is not writable", path); (void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ", - modep + 1, modep[9] == ' ' ? "" : " ", + modep + 1, modep[10] == ' ' ? "" : " ", user_from_uid(sp->st_uid, 0), group_from_gid(sp->st_gid, 0), *flagsp ? flagsp : "", *flagsp ? " " : "", diff --git a/bin/rmail/Makefile.depend b/bin/rmail/Makefile.depend index 0cb1420f7290..e07330e48118 100644 --- a/bin/rmail/Makefile.depend +++ b/bin/rmail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/rmdir/Makefile b/bin/rmdir/Makefile index 534c66282a70..9a081323f813 100644 --- a/bin/rmdir/Makefile +++ b/bin/rmdir/Makefile @@ -1,9 +1,10 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 # $FreeBSD$ +.include + PACKAGE=runtime PROG= rmdir - HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/bin/rmdir/Makefile.depend b/bin/rmdir/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/rmdir/Makefile.depend +++ b/bin/rmdir/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/rmdir/tests/Makefile.depend b/bin/rmdir/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/rmdir/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/setfacl/Makefile.depend b/bin/setfacl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/setfacl/Makefile.depend +++ b/bin/setfacl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/sh/Makefile.depend b/bin/sh/Makefile.depend index 3d9203935abf..0e0490b10835 100644 --- a/bin/sh/Makefile.depend +++ b/bin/sh/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/sh/tests/invocation/Makefile.depend b/bin/sh/tests/invocation/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/bin/sh/tests/invocation/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/sleep/Makefile.depend b/bin/sleep/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/bin/sleep/Makefile.depend +++ b/bin/sleep/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/stty/Makefile.depend b/bin/stty/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/stty/Makefile.depend +++ b/bin/stty/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/sync/Makefile.depend b/bin/sync/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/bin/sync/Makefile.depend +++ b/bin/sync/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/bin/test/Makefile.depend b/bin/test/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/test/Makefile.depend +++ b/bin/test/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/bin/uuidgen/Makefile.depend b/bin/uuidgen/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/bin/uuidgen/Makefile.depend +++ b/bin/uuidgen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c index e39108366e39..8dd7bb972ef3 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c @@ -35,13 +35,13 @@ main(int argc, char **argv) sigset_t ss; (void) sigemptyset(&ss); - (void) sigaddset(&ss, SIGINT); + (void) sigaddset(&ss, SIGUSR1); (void) sigprocmask(SIG_BLOCK, &ss, NULL); do { (void) getpid(); (void) sigpending(&ss); - } while (!sigismember(&ss, SIGINT)); + } while (!sigismember(&ss, SIGUSR1)); return (0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d index cdc7154750b6..30bf5ae4bf0a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d @@ -47,7 +47,7 @@ syscall::getpid:entry /pid == $1/ { trace("raised"); - raise(SIGINT); + raise(SIGUSR1); /* * Wait no more than half a second for the process to die. */ @@ -55,6 +55,7 @@ syscall::getpid:entry } syscall::exit:entry +/pid == $1/ { exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c index 9089283f7893..3901d9862097 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c @@ -45,7 +45,7 @@ main(int argc, char **argv) sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - (void) sigaction(SIGINT, &sa, NULL); + (void) sigaction(SIGUSR1, &sa, NULL); for (;;) { (void) getpid(); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d index 4f68a0b93b3b..7d18442d7408 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d @@ -47,7 +47,7 @@ syscall::getpid:return /pid == $1/ { trace("raised"); - raise(SIGINT); + raise(SIGUSR1); /* * Wait no more than half a second for the process to die. */ @@ -55,6 +55,7 @@ syscall::getpid:return } syscall::exit:entry +/pid == $1/ { exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c index 9089283f7893..3901d9862097 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c @@ -45,7 +45,7 @@ main(int argc, char **argv) sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - (void) sigaction(SIGINT, &sa, NULL); + (void) sigaction(SIGUSR1, &sa, NULL); for (;;) { (void) getpid(); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d index cdc7154750b6..30bf5ae4bf0a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d @@ -47,7 +47,7 @@ syscall::getpid:entry /pid == $1/ { trace("raised"); - raise(SIGINT); + raise(SIGUSR1); /* * Wait no more than half a second for the process to die. */ @@ -55,6 +55,7 @@ syscall::getpid:entry } syscall::exit:entry +/pid == $1/ { exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 b/cddl/contrib/opensolaris/cmd/zdb/zdb.8 index 6ae25c398f2d..2d294ea3641a 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.8 @@ -1,6 +1,3 @@ -'\" te -.\" Copyright (c) 2012, Martin Matuska . -.\" All Rights Reserved. .\" .\" This file and its contents are supplied under the terms of the .\" Common Development and Distribution License ("CDDL"), version 1.0. @@ -13,71 +10,75 @@ .\" .\" .\" Copyright 2012, Richard Lowe. -.\" Copyright (c) 2012, Marcelo Araujo . -.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved. -.\" All Rights Reserved. +.\" Copyright (c) 2012, 2017 by Delphix. All rights reserved. +.\" Copyright 2017 Nexenta Systems, Inc. .\" -.\" $FreeBSD$ -.\" -.Dd July 26, 2014 +.Dd October 06, 2017 .Dt ZDB 8 .Os .Sh NAME .Nm zdb -.Nd Display zpool debugging and consistency information +.Nd display zpool debugging and consistency information .Sh SYNOPSIS .Nm -.Op Fl CumdibcsDvhLMXFPA -.Op Fl e Op Fl p Ar path... -.Op Fl t Ar txg -.Op Fl U Ar cache +.Op Fl AbcdDFGhiLMPsvX +.Op Fl e Oo Fl V Oc Op Fl p Ar path ... .Op Fl I Ar inflight I/Os -.Op Fl x Ar dumpdir -.Ar poolname -.Op Ar object ... -.Nm -.Op Fl divPA -.Op Fl e Op Fl p Ar path... -.Op Fl U Ar cache -.Ar dataset -.Op Ar object ... -.Nm -.Fl m Op Fl MLXFPA +.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ... .Op Fl t Ar txg -.Op Fl e Op Fl p Ar path... .Op Fl U Ar cache -.Ar poolname +.Op Fl x Ar dumpdir +.Op Ar poolname Op Ar object ... .Nm -.Fl R Op Fl A -.Op Fl e Op Fl p Ar path... +.Op Fl AdiPv +.Op Fl e Oo Fl V Oc Op Fl p Ar path ... .Op Fl U Ar cache -.Ar poolname -.Ar poolname -.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags -.Nm -.Fl S -.Op Fl AP -.Op Fl e Op Fl p Ar path... -.Op Fl U Ar cache -.Ar poolname -.Ar poolname -.Nm -.Fl l -.Op Fl uA -.Ar device +.Ar dataset Op Ar object ... .Nm .Fl C .Op Fl A .Op Fl U Ar cache +.Nm +.Fl E +.Op Fl A +.Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15 +.Nm +.Fl l +.Op Fl Aqu +.Ar device +.Nm +.Fl m +.Op Fl AFLPX +.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl t Ar txg +.Op Fl U Ar cache +.Ar poolname Op Ar vdev Op Ar metaslab ... +.Nm +.Fl O +.Ar dataset path +.Nm +.Fl R +.Op Fl A +.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl U Ar cache +.Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags +.Nm +.Fl S +.Op Fl AP +.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl U Ar cache +.Ar poolname .Sh DESCRIPTION The .Nm -utility displays information about a ZFS pool useful for debugging and -performs some amount of consistency checking. -It is a not a general purpose tool and options (and facilities) may change. +utility displays information about a ZFS pool useful for debugging and performs +some amount of consistency checking. +It is a not a general purpose tool and options +.Pq and facilities +may change. This is neither a .Xr fsck 8 -nor a +nor an .Xr fsdb 8 utility. .Pp @@ -89,73 +90,96 @@ internals is assumed. If the .Ar dataset argument does not contain any -.Sy / +.Qq Sy / or -.Sy @ +.Qq Sy @ characters, it is interpreted as a pool name. The root dataset can be specified as -.Pa pool Ns Sy / -(pool name followed by a slash). +.Ar pool Ns / +.Pq pool name followed by a slash . .Pp When operating on an imported and active pool it is possible, though unlikely, that zdb may interpret inconsistent pool data and behave erratically. .Sh OPTIONS Display options: -.Bl -tag -width indent +.Bl -tag -width Ds .It Fl b -Display statistics regarding the number, size (logical, physical and -allocated) and deduplication of blocks. +Display statistics regarding the number, size +.Pq logical, physical and allocated +and deduplication of blocks. .It Fl c Verify the checksum of all metadata blocks while printing block statistics -(see -.Fl b Ns ). +.Po see +.Fl b +.Pc . .Pp If specified multiple times, verify the checksums of all blocks. .It Fl C -Display information about the configuration. If specified with no other -options, instead display information about the cache file -.Po Pa /etc/zfs/zpool.cache Pc . +Display information about the configuration. +If specified with no other options, instead display information about the cache +file +.Pq Pa /boot/zfs/zpool.cache . To specify the cache file to display, see -.Fl U +.Fl U . .Pp -If specified multiple times, and a pool name is also specified display both -the cached configuration and the on-disk configuration. +If specified multiple times, and a pool name is also specified display both the +cached configuration and the on-disk configuration. If specified multiple times with .Fl e -also display the configuration that would be used were the pool to be -imported. +also display the configuration that would be used were the pool to be imported. .It Fl d -Display information about datasets. Specified once, displays basic dataset -information: ID, create transaction, size, and object count. +Display information about datasets. +Specified once, displays basic dataset information: ID, create transaction, +size, and object count. .Pp If specified multiple times provides greater and greater verbosity. .Pp -If object IDs are specified, display information about those specific objects only. +If object IDs are specified, display information about those specific objects +only. .It Fl D -Display deduplication statistics, including the deduplication ratio (dedup), -compression ratio (compress), inflation due to the zfs copies property -(copies), and an overall effective ratio (dedup * compress / copies). -.Pp -If specified twice, display a histogram of deduplication statistics, showing -the allocated (physically present on disk) and referenced (logically -referenced in the pool) block counts and sizes by reference count. -.Pp -If specified a third time, display the statistics independently for each deduplication table. -.Pp -If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks. -.Pp -If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks. +Display deduplication statistics, including the deduplication ratio +.Pq Sy dedup , +compression ratio +.Pq Sy compress , +inflation due to the zfs copies property +.Pq Sy copies , +and an overall effective ratio +.Pq Sy dedup No * Sy compress No / Sy copies . +.It Fl DD +Display a histogram of deduplication statistics, showing the allocated +.Pq physically present on disk +and referenced +.Pq logically referenced in the pool +block counts and sizes by reference count. +.It Fl DDD +Display the statistics independently for each deduplication table. +.It Fl DDDD +Dump the contents of the deduplication tables describing duplicate blocks. +.It Fl DDDDD +Also dump the contents of the deduplication tables describing unique blocks. +.It Fl E Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15 +Decode and display block from an embedded block pointer specified by the +.Ar word +arguments. .It Fl h Display pool history similar to -.Cm zpool history , +.Nm zpool Cm history , but include internal changes, transaction, and dataset information. .It Fl i -Display information about intent log (ZIL) entries relating to each -dataset. -If specified multiple times, display counts of each intent log transaction -type. +Display information about intent log +.Pq ZIL +entries relating to each dataset. +If specified multiple times, display counts of each intent log transaction type. .It Fl l Ar device -Display the vdev labels from the specified device. +Read the vdev labels from the specified device. +.Nm Fl l +will return 0 if valid label was found, 1 if error occurred, and 2 if no valid +labels were found. +.Pp +If the +.Fl q +option is also specified, don't print the labels. +.Pp If the .Fl u option is also specified, also display the uberblocks on this device. @@ -166,36 +190,55 @@ By default, verifies that all non-free blocks are referenced, which can be very expensive. .It Fl m Display the offset, spacemap, and free space of each metaslab. -When specified twice, also display information about the on-disk free -space histogram associated with each metaslab. When specified three time, -display the maximum contiguous free space, the in-core free space histogram, -and the percentage of free space in each space map. When specified -four times display every spacemap record. +.It Fl mm +Also display information about the on-disk free space histogram associated with +each metaslab. +.It Fl mmm +Display the maximum contiguous free space, the in-core free space histogram, and +the percentage of free space in each space map. +.It Fl mmmm +Display every spacemap record. .It Fl M Display the offset, spacemap, and free space of each metaslab. -When specified twice, also display information about the maximum contiguous -free space and the percentage of free space in each space map. -When specified three times display every spacemap record. +.It Fl MM +Also display information about the maximum contiguous free space and the +percentage of free space in each space map. +.It Fl MMM +Display every spacemap record. +.It Fl O Ar dataset path +Look up the specified +.Ar path +inside of the +.Ar dataset +and display its metadata and indirect blocks. +Specified +.Ar path +must be relative to the root of +.Ar dataset . +This option can be combined with +.Fl v +for increasing verbosity. .It Xo -.Fl R Ar poolname -.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags +.Fl R Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags .Xc -Read and display a block from the specified device. By default the block is -displayed as a hex dump, but see the description of the -.Fl r +Read and display a block from the specified device. +By default the block is displayed as a hex dump, but see the description of the +.Sy r flag, below. .Pp The block is specified in terms of a colon-separated tuple .Ar vdev -(an integer vdev identifier) +.Pq an integer vdev identifier .Ar offset -(the offset within the vdev) +.Pq the offset within the vdev .Ar size -(the size of the block to read) and, optionally, +.Pq the size of the block to read +and, optionally, .Ar flags -(a set of flags, described below). -.Bl -tag -width indent -.It Sy b offset +.Pq a set of flags, described below . +.Pp +.Bl -tag -compact -width "b offset" +.It Sy b Ar offset Print block pointer .It Sy d Decompress the block @@ -210,19 +253,20 @@ Dump raw uninterpreted block data .El .It Fl s Report statistics on -.Nm Ns 's +.Nm zdb I/O. Display operation counts, bandwidth, and error counts of I/O to the pool from .Nm . .It Fl S Simulate the effects of deduplication, constructing a DDT and then display -that DDT as with \fB-DD\fR. +that DDT as with +.Fl DD . .It Fl u Display the current uberblock. .El .Pp Other options: -.Bl -tag -width indent +.Bl -tag -width Ds .It Fl A Do not abort should any assertion fail. .It Fl AA @@ -230,28 +274,41 @@ Enable panic recovery, certain errors which would otherwise be fatal are demoted to warnings. .It Fl AAA Do not abort if asserts fail and also enable panic recovery. -.It Fl e Op Fl p Ar path... +.It Fl e Op Fl p Ar path ... Operate on an exported pool, not present in -.Pa /etc/zfs/zpool.cache . +.Pa /boot/zfs/zpool.cache . The .Fl p flag specifies the path under which devices are to be searched. .It Fl x Ar dumpdir All blocks accessed will be copied to files in the specified directory. The blocks will be placed in sparse files whose name is the same as -that of the file or device read. zdb can be then run on the generated files. +that of the file or device read. +.Nm +can be then run on the generated files. Note that the .Fl bbc -flags are sufficient to access (and thus copy) +flags are sufficient to access +.Pq and thus copy all metadata on the pool. .It Fl F Attempt to make an unreadable pool readable by trying progressively older transactions. +.It Fl G +Dump the contents of the zfs_dbgmsg buffer before exiting +.Nm . +zfs_dbgmsg is a buffer used by ZFS to dump advanced debug information. .It Fl I Ar inflight I/Os Limit the number of outstanding checksum I/Os to the specified value. -The default value is 200. This option affects the performance of the +The default value is 200. +This option affects the performance of the .Fl c option. +.It Fl o Ar var Ns = Ns Ar value ... +Set the given global libzpool variable to the provided value. +The value must be an unsigned 32-bit integer. +Currently only little-endian systems are supported to avoid accidentally setting +the high 32 bits of 64-bit variables. .It Fl P Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather than 1M. @@ -269,9 +326,14 @@ Use a cache file other than .It Fl v Enable verbosity. Specify multiple times for increased verbosity. +.It Fl V +Attempt verbatim import. +This mimics the behavior of the kernel when loading a pool from a cachefile. +Only usable with +.Fl e . .It Fl X Attempt -.Ql extreme +.Qq extreme transaction rewind, that is attempt the same recovery as .Fl F but read transactions otherwise deemed too old. @@ -283,46 +345,58 @@ option, with more occurrences enabling more verbosity. If no options are specified, all information about the named pool will be displayed at default verbosity. .Sh EXAMPLES -.Bl -tag -width 0n -.It Sy Example 1 Display the configuration of imported pool 'rpool' -.Bd -literal -offset 2n -.Li # Ic zdb -C rpool +.Bl -tag -width Ds +.It Xo +.Sy Example 1 +Display the configuration of imported pool +.Pa rpool +.Xc +.Bd -literal +# zdb -C rpool MOS Configuration: version: 28 name: 'rpool' ... .Ed -.It Sy Example 2 Display basic dataset information about 'rpool' -.Bd -literal -offset 2n -.Li # Ic zdb -d rpool +.It Xo +.Sy Example 2 +Display basic dataset information about +.Pa rpool +.Xc +.Bd -literal +# zdb -d rpool Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects ... .Ed -.It Xo Sy Example 3 Display basic information about object 0 in -.Sy 'rpool/export/home' +.It Xo +.Sy Example 3 +Display basic information about object 0 in +.Pa rpool/export/home .Xc -.Bd -literal -offset 2n -.Li # Ic zdb -d rpool/export/home 0 +.Bd -literal +# zdb -d rpool/export/home 0 Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects Object lvl iblk dblk dsize lsize %full type 0 7 16K 16K 15.0K 16K 25.00 DMU dnode .Ed -.It Xo Sy Example 4 Display the predicted effect of enabling deduplication on -.Sy 'rpool' +.It Xo +.Sy Example 4 +Display the predicted effect of enabling deduplication on +.Pa rpool .Xc -.Bd -literal -offset 2n -.Li # Ic zdb -S rpool +.Bd -literal +# zdb -S rpool Simulated DDT histogram: -bucket allocated referenced -______ ______________________________ ______________________________ -refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------- ------ ----- ----- ----- ------ ----- ----- ----- - 1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G - 2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G +bucket allocated referenced +______ ______________________________ ______________________________ +refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE +------ ------ ----- ----- ----- ------ ----- ----- ----- + 1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G + 2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G ... dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00 .Ed @@ -330,22 +404,3 @@ dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00 .Sh SEE ALSO .Xr zfs 8 , .Xr zpool 8 -.Sh AUTHORS -This manual page is a -.Xr mdoc 7 -reimplementation of the -.Tn illumos -manual page -.Em zdb(1M) , -modified and customized for -.Fx -and licensed under the -Common Development and Distribution License -.Pq Tn CDDL . -.Pp -The -.Xr mdoc 7 -implementation of this manual page was initially written by -.An Martin Matuska Aq mm@FreeBSD.org -and -.An Marcelo Araujo Aq araujo@FreeBSD.org . diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c index 711377a9fa25..6ca504783a19 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2017 Nexenta Systems, Inc. */ #include @@ -60,7 +61,9 @@ #include #include #include +#include #include +#include #undef verify #include @@ -120,18 +123,24 @@ static void usage(void) { (void) fprintf(stderr, - "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] " - "[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n" - " %s [-divPA] [-e -p path...] [-U config] dataset " - "[object...]\n" - " %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] " - "poolname [vdev [metaslab...]]\n" - " %s -R [-A] [-e [-p path...]] poolname " - "vdev:offset:size[:flags]\n" - " %s -S [-PA] [-e [-p path...]] [-U config] poolname\n" - " %s -l [-uA] device\n" - " %s -C [-A] [-U config]\n\n", - cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname); + "Usage:\t%s [-AbcdDFGhiLMPsvX] [-e [-V] [-p ...]] " + "[-I ]\n" + "\t\t[-o =]... [-t ] [-U ] [-x ]\n" + "\t\t[ [ ...]]\n" + "\t%s [-AdiPv] [-e [-V] [-p ...]] [-U ] " + "[ ...]\n" + "\t%s -C [-A] [-U ]\n" + "\t%s -l [-Aqu] \n" + "\t%s -m [-AFLPX] [-e [-V] [-p ...]] [-t ] " + "[-U ]\n\t\t [ [ ...]]\n" + "\t%s -O \n" + "\t%s -R [-A] [-e [-V] [-p ...]] [-U ]\n" + "\t\t ::[:]\n" + "\t%s -E [-A] word0:word1:...:word15\n" + "\t%s -S [-AP] [-e [-V] [-p ...]] [-U ] " + "\n\n", + cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, + cmdname, cmdname); (void) fprintf(stderr, " Dataset name must include at least one " "separator character '/' or '@'\n"); @@ -140,49 +149,57 @@ usage(void) (void) fprintf(stderr, " If object numbers are specified, only " "those objects are dumped\n\n"); (void) fprintf(stderr, " Options to control amount of output:\n"); - (void) fprintf(stderr, " -u uberblock\n"); - (void) fprintf(stderr, " -d dataset(s)\n"); - (void) fprintf(stderr, " -i intent logs\n"); - (void) fprintf(stderr, " -C config (or cachefile if alone)\n"); - (void) fprintf(stderr, " -h pool history\n"); (void) fprintf(stderr, " -b block statistics\n"); - (void) fprintf(stderr, " -m metaslabs\n"); - (void) fprintf(stderr, " -M metaslab groups\n"); (void) fprintf(stderr, " -c checksum all metadata (twice for " "all data) blocks\n"); - (void) fprintf(stderr, " -s report stats on zdb's I/O\n"); + (void) fprintf(stderr, " -C config (or cachefile if alone)\n"); + (void) fprintf(stderr, " -d dataset(s)\n"); (void) fprintf(stderr, " -D dedup statistics\n"); - (void) fprintf(stderr, " -S simulate dedup to measure effect\n"); - (void) fprintf(stderr, " -v verbose (applies to all others)\n"); - (void) fprintf(stderr, " -l dump label contents\n"); + (void) fprintf(stderr, " -E decode and display block from an " + "embedded block pointer\n"); + (void) fprintf(stderr, " -h pool history\n"); + (void) fprintf(stderr, " -i intent logs\n"); + (void) fprintf(stderr, " -l read label contents\n"); (void) fprintf(stderr, " -L disable leak tracking (do not " "load spacemaps)\n"); + (void) fprintf(stderr, " -m metaslabs\n"); + (void) fprintf(stderr, " -M metaslab groups\n"); + (void) fprintf(stderr, " -O perform object lookups by path\n"); (void) fprintf(stderr, " -R read and display block from a " - "device\n\n"); + "device\n"); + (void) fprintf(stderr, " -s report stats on zdb's I/O\n"); + (void) fprintf(stderr, " -S simulate dedup to measure effect\n"); + (void) fprintf(stderr, " -v verbose (applies to all " + "others)\n\n"); (void) fprintf(stderr, " Below options are intended for use " "with other options:\n"); (void) fprintf(stderr, " -A ignore assertions (-A), enable " "panic recovery (-AA) or both (-AAA)\n"); - (void) fprintf(stderr, " -F attempt automatic rewind within " - "safe range of transaction groups\n"); - (void) fprintf(stderr, " -U -- use alternate " - "cachefile\n"); - (void) fprintf(stderr, " -X attempt extreme rewind (does not " - "work with dataset)\n"); (void) fprintf(stderr, " -e pool is exported/destroyed/" "has altroot/not in a cachefile\n"); - (void) fprintf(stderr, " -p -- use one or more with " - "-e to specify path to vdev dir\n"); - (void) fprintf(stderr, " -x -- " - "dump all read blocks into specified directory\n"); - (void) fprintf(stderr, " -P print numbers in parseable form\n"); - (void) fprintf(stderr, " -t -- highest txg to use when " - "searching for uberblocks\n"); + (void) fprintf(stderr, " -F attempt automatic rewind within " + "safe range of transaction groups\n"); + (void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before " + "exiting\n"); (void) fprintf(stderr, " -I -- " "specify the maximum number of " "checksumming I/Os [default is 200]\n"); - (void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before " - "exiting\n"); + (void) fprintf(stderr, " -o = set global " + "variable to an unsigned 32-bit integer value\n"); + (void) fprintf(stderr, " -p -- use one or more with " + "-e to specify path to vdev dir\n"); + (void) fprintf(stderr, " -P print numbers in parseable form\n"); + (void) fprintf(stderr, " -q don't print label contents\n"); + (void) fprintf(stderr, " -t -- highest txg to use when " + "searching for uberblocks\n"); + (void) fprintf(stderr, " -u uberblock\n"); + (void) fprintf(stderr, " -U -- use alternate " + "cachefile\n"); + (void) fprintf(stderr, " -V do verbatim import\n"); + (void) fprintf(stderr, " -x -- " + "dump all read blocks into specified directory\n"); + (void) fprintf(stderr, " -X attempt extreme rewind (does not " + "work with dataset)\n\n"); (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " "to make only that option verbose\n"); (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); @@ -260,12 +277,12 @@ dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size) } static void -zdb_nicenum(uint64_t num, char *buf) +zdb_nicenum(uint64_t num, char *buf, size_t buflen) { if (dump_opt['P']) - (void) sprintf(buf, "%llu", (longlong_t)num); + (void) snprintf(buf, buflen, "%llu", (longlong_t)num); else - nicenum(num, buf); + nicenum(num, buf, sizeof (buf)); } const char histo_stars[] = "****************************************"; @@ -442,12 +459,17 @@ dump_bpobj(objset_t *os, uint64_t object, void *data, size_t size) bpobj_phys_t *bpop = data; char bytes[32], comp[32], uncomp[32]; + /* make sure the output won't get truncated */ + CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); + if (bpop == NULL) return; - zdb_nicenum(bpop->bpo_bytes, bytes); - zdb_nicenum(bpop->bpo_comp, comp); - zdb_nicenum(bpop->bpo_uncomp, uncomp); + zdb_nicenum(bpop->bpo_bytes, bytes, sizeof (bytes)); + zdb_nicenum(bpop->bpo_comp, comp, sizeof (comp)); + zdb_nicenum(bpop->bpo_uncomp, uncomp, sizeof (uncomp)); (void) printf("\t\tnum_blkptrs = %llu\n", (u_longlong_t)bpop->bpo_num_blkptrs); @@ -740,7 +762,10 @@ dump_metaslab_stats(metaslab_t *msp) avl_tree_t *t = &msp->ms_size_tree; int free_pct = range_tree_space(rt) * 100 / msp->ms_size; - zdb_nicenum(metaslab_block_maxsize(msp), maxbuf); + /* max sure nicenum has enough space */ + CTASSERT(sizeof (maxbuf) >= NN_NUMBUF_SZ); + + zdb_nicenum(metaslab_block_maxsize(msp), maxbuf, sizeof (maxbuf)); (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n", "segments", avl_numnodes(t), "maxsize", maxbuf, @@ -757,7 +782,8 @@ dump_metaslab(metaslab_t *msp) space_map_t *sm = msp->ms_sm; char freebuf[32]; - zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf); + zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf, + sizeof (freebuf)); (void) printf( "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n", @@ -1340,6 +1366,9 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) time_t crtime; char nice[32]; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (nice) >= NN_NUMBUF_SZ); + if (dd == NULL) return; @@ -1355,15 +1384,15 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) (u_longlong_t)dd->dd_origin_obj); (void) printf("\t\tchild_dir_zapobj = %llu\n", (u_longlong_t)dd->dd_child_dir_zapobj); - zdb_nicenum(dd->dd_used_bytes, nice); + zdb_nicenum(dd->dd_used_bytes, nice, sizeof (nice)); (void) printf("\t\tused_bytes = %s\n", nice); - zdb_nicenum(dd->dd_compressed_bytes, nice); + zdb_nicenum(dd->dd_compressed_bytes, nice, sizeof (nice)); (void) printf("\t\tcompressed_bytes = %s\n", nice); - zdb_nicenum(dd->dd_uncompressed_bytes, nice); + zdb_nicenum(dd->dd_uncompressed_bytes, nice, sizeof (nice)); (void) printf("\t\tuncompressed_bytes = %s\n", nice); - zdb_nicenum(dd->dd_quota, nice); + zdb_nicenum(dd->dd_quota, nice, sizeof (nice)); (void) printf("\t\tquota = %s\n", nice); - zdb_nicenum(dd->dd_reserved, nice); + zdb_nicenum(dd->dd_reserved, nice, sizeof (nice)); (void) printf("\t\treserved = %s\n", nice); (void) printf("\t\tprops_zapobj = %llu\n", (u_longlong_t)dd->dd_props_zapobj); @@ -1373,7 +1402,8 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) (u_longlong_t)dd->dd_flags); #define DO(which) \ - zdb_nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice); \ + zdb_nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice, \ + sizeof (nice)); \ (void) printf("\t\tused_breakdown[" #which "] = %s\n", nice) DO(HEAD); DO(SNAP); @@ -1392,15 +1422,22 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size) char used[32], compressed[32], uncompressed[32], unique[32]; char blkbuf[BP_SPRINTF_LEN]; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (used) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (compressed) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (uncompressed) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (unique) >= NN_NUMBUF_SZ); + if (ds == NULL) return; ASSERT(size == sizeof (*ds)); crtime = ds->ds_creation_time; - zdb_nicenum(ds->ds_referenced_bytes, used); - zdb_nicenum(ds->ds_compressed_bytes, compressed); - zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed); - zdb_nicenum(ds->ds_unique_bytes, unique); + zdb_nicenum(ds->ds_referenced_bytes, used, sizeof (used)); + zdb_nicenum(ds->ds_compressed_bytes, compressed, sizeof (compressed)); + zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed, + sizeof (uncompressed)); + zdb_nicenum(ds->ds_unique_bytes, unique, sizeof (unique)); snprintf_blkptr(blkbuf, sizeof (blkbuf), &ds->ds_bp); (void) printf("\t\tdir_obj = %llu\n", @@ -1459,12 +1496,15 @@ dump_bptree(objset_t *os, uint64_t obj, char *name) bptree_phys_t *bt; dmu_buf_t *db; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); + if (dump_opt['d'] < 3) return; VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db)); bt = db->db_data; - zdb_nicenum(bt->bt_bytes, bytes); + zdb_nicenum(bt->bt_bytes, bytes, sizeof (bytes)); (void) printf("\n %s: %llu datasets, %s\n", name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes); dmu_buf_rele(db, FTAG); @@ -1496,13 +1536,18 @@ dump_full_bpobj(bpobj_t *bpo, char *name, int indent) char comp[32]; char uncomp[32]; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); + if (dump_opt['d'] < 3) return; - zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes); + zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes, sizeof (bytes)); if (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_subobjs != 0) { - zdb_nicenum(bpo->bpo_phys->bpo_comp, comp); - zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp); + zdb_nicenum(bpo->bpo_phys->bpo_comp, comp, sizeof (comp)); + zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp, sizeof (uncomp)); (void) printf(" %*s: object %llu, %llu local blkptrs, " "%llu subobjs in object %llu, %s (%s/%s comp)\n", indent * 8, name, @@ -1556,6 +1601,11 @@ dump_deadlist(dsl_deadlist_t *dl) char comp[32]; char uncomp[32]; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); + if (dump_opt['d'] < 3) return; @@ -1564,9 +1614,9 @@ dump_deadlist(dsl_deadlist_t *dl) return; } - zdb_nicenum(dl->dl_phys->dl_used, bytes); - zdb_nicenum(dl->dl_phys->dl_comp, comp); - zdb_nicenum(dl->dl_phys->dl_uncomp, uncomp); + zdb_nicenum(dl->dl_phys->dl_used, bytes, sizeof (bytes)); + zdb_nicenum(dl->dl_phys->dl_comp, comp, sizeof (comp)); + zdb_nicenum(dl->dl_phys->dl_uncomp, uncomp, sizeof (uncomp)); (void) printf("\n Deadlist: %s (%s/%s comp)\n", bytes, comp, uncomp); @@ -1582,8 +1632,9 @@ dump_deadlist(dsl_deadlist_t *dl) dle = AVL_NEXT(&dl->dl_tree, dle)) { if (dump_opt['d'] >= 5) { char buf[128]; - (void) snprintf(buf, sizeof (buf), "mintxg %llu -> " - "obj %llu", (longlong_t)dle->dle_mintxg, + (void) snprintf(buf, sizeof (buf), + "mintxg %llu -> obj %llu", + (longlong_t)dle->dle_mintxg, (longlong_t)dle->dle_bpobj.bpo_object); dump_full_bpobj(&dle->dle_bpobj, buf, 0); } else { @@ -1597,8 +1648,55 @@ dump_deadlist(dsl_deadlist_t *dl) static avl_tree_t idx_tree; static avl_tree_t domain_tree; static boolean_t fuid_table_loaded; -static boolean_t sa_loaded; -sa_attr_type_t *sa_attr_table; +static objset_t *sa_os = NULL; +static sa_attr_type_t *sa_attr_table = NULL; + +static int +open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp) +{ + int err; + uint64_t sa_attrs = 0; + uint64_t version = 0; + + VERIFY3P(sa_os, ==, NULL); + err = dmu_objset_own(path, type, B_TRUE, tag, osp); + if (err != 0) { + (void) fprintf(stderr, "failed to own dataset '%s': %s\n", path, + strerror(err)); + return (err); + } + + if (dmu_objset_type(*osp) == DMU_OST_ZFS) { + (void) zap_lookup(*osp, MASTER_NODE_OBJ, ZPL_VERSION_STR, + 8, 1, &version); + if (version >= ZPL_VERSION_SA) { + (void) zap_lookup(*osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS, + 8, 1, &sa_attrs); + } + err = sa_setup(*osp, sa_attrs, zfs_attr_table, ZPL_END, + &sa_attr_table); + if (err != 0) { + (void) fprintf(stderr, "sa_setup failed: %s\n", + strerror(err)); + dmu_objset_disown(*osp, tag); + *osp = NULL; + } + } + sa_os = *osp; + + return (0); +} + +static void +close_objset(objset_t *os, void *tag) +{ + VERIFY3P(os, ==, sa_os); + if (os->os_sa != NULL) + sa_tear_down(os); + dmu_objset_disown(os, tag); + sa_attr_table = NULL; + sa_os = NULL; +} static void fuid_table_destroy() @@ -1670,25 +1768,7 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size) int idx = 0; int error; - if (!sa_loaded) { - uint64_t sa_attrs = 0; - uint64_t version; - - VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, - 8, 1, &version) == 0); - if (version >= ZPL_VERSION_SA) { - VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, - 8, 1, &sa_attrs) == 0); - } - if ((error = sa_setup(os, sa_attrs, zfs_attr_table, - ZPL_END, &sa_attr_table)) != 0) { - (void) printf("sa_setup failed errno %d, can't " - "display znode contents\n", error); - return; - } - sa_loaded = B_TRUE; - } - + VERIFY3P(os, ==, sa_os); if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) { (void) printf("Failed to get handle for SA znode\n"); return; @@ -1837,6 +1917,13 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) char aux[50]; int error; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (iblk) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (dblk) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (lsize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (asize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (bonus_size) >= NN_NUMBUF_SZ); + if (*print_header) { (void) printf("\n%10s %3s %5s %5s %5s %5s %6s %s\n", "Object", "lvl", "iblk", "dblk", "dsize", "lsize", @@ -1857,11 +1944,11 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) } dmu_object_info_from_dnode(dn, &doi); - zdb_nicenum(doi.doi_metadata_block_size, iblk); - zdb_nicenum(doi.doi_data_block_size, dblk); - zdb_nicenum(doi.doi_max_offset, lsize); - zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize); - zdb_nicenum(doi.doi_bonus_size, bonus_size); + zdb_nicenum(doi.doi_metadata_block_size, iblk, sizeof (iblk)); + zdb_nicenum(doi.doi_data_block_size, dblk, sizeof (dblk)); + zdb_nicenum(doi.doi_max_offset, lsize, sizeof (lsize)); + zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize, sizeof (asize)); + zdb_nicenum(doi.doi_bonus_size, bonus_size, sizeof (bonus_size)); (void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count * doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) / doi.doi_max_offset); @@ -1924,6 +2011,8 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) for (;;) { char segsize[32]; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (segsize) >= NN_NUMBUF_SZ); error = dnode_next_offset(dn, 0, &start, minlvl, blkfill, 0); if (error) @@ -1931,7 +2020,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) end = start; error = dnode_next_offset(dn, DNODE_FIND_HOLE, &end, minlvl, blkfill, 0); - zdb_nicenum(end - start, segsize); + zdb_nicenum(end - start, segsize, sizeof (segsize)); (void) printf("\t\tsegment [%016llx, %016llx)" " size %5s\n", (u_longlong_t)start, (u_longlong_t)end, segsize); @@ -1962,6 +2051,9 @@ dump_dir(objset_t *os) int print_header = 1; int i, error; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (numbuf) >= NN_NUMBUF_SZ); + dsl_pool_config_enter(dmu_objset_pool(os), FTAG); dmu_objset_fast_stat(os, &dds); dsl_pool_config_exit(dmu_objset_pool(os), FTAG); @@ -1980,7 +2072,7 @@ dump_dir(objset_t *os) ASSERT3U(usedobjs, ==, BP_GET_FILL(os->os_rootbp)); - zdb_nicenum(refdbytes, numbuf); + zdb_nicenum(refdbytes, numbuf, sizeof (numbuf)); if (verbosity >= 4) { (void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp "); @@ -2156,44 +2248,154 @@ dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift) } } -static void +static char curpath[PATH_MAX]; + +/* + * Iterate through the path components, recursively passing + * current one's obj and remaining path until we find the obj + * for the last one. + */ +static int +dump_path_impl(objset_t *os, uint64_t obj, char *name) +{ + int err; + int header = 1; + uint64_t child_obj; + char *s; + dmu_buf_t *db; + dmu_object_info_t doi; + + if ((s = strchr(name, '/')) != NULL) + *s = '\0'; + err = zap_lookup(os, obj, name, 8, 1, &child_obj); + + (void) strlcat(curpath, name, sizeof (curpath)); + + if (err != 0) { + (void) fprintf(stderr, "failed to lookup %s: %s\n", + curpath, strerror(err)); + return (err); + } + + child_obj = ZFS_DIRENT_OBJ(child_obj); + err = sa_buf_hold(os, child_obj, FTAG, &db); + if (err != 0) { + (void) fprintf(stderr, + "failed to get SA dbuf for obj %llu: %s\n", + (u_longlong_t)child_obj, strerror(err)); + return (EINVAL); + } + dmu_object_info_from_db(db, &doi); + sa_buf_rele(db, FTAG); + + if (doi.doi_bonus_type != DMU_OT_SA && + doi.doi_bonus_type != DMU_OT_ZNODE) { + (void) fprintf(stderr, "invalid bonus type %d for obj %llu\n", + doi.doi_bonus_type, (u_longlong_t)child_obj); + return (EINVAL); + } + + if (dump_opt['v'] > 6) { + (void) printf("obj=%llu %s type=%d bonustype=%d\n", + (u_longlong_t)child_obj, curpath, doi.doi_type, + doi.doi_bonus_type); + } + + (void) strlcat(curpath, "/", sizeof (curpath)); + + switch (doi.doi_type) { + case DMU_OT_DIRECTORY_CONTENTS: + if (s != NULL && *(s + 1) != '\0') + return (dump_path_impl(os, child_obj, s + 1)); + /*FALLTHROUGH*/ + case DMU_OT_PLAIN_FILE_CONTENTS: + dump_object(os, child_obj, dump_opt['v'], &header); + return (0); + default: + (void) fprintf(stderr, "object %llu has non-file/directory " + "type %d\n", (u_longlong_t)obj, doi.doi_type); + break; + } + + return (EINVAL); +} + +/* + * Dump the blocks for the object specified by path inside the dataset. + */ +static int +dump_path(char *ds, char *path) +{ + int err; + objset_t *os; + uint64_t root_obj; + + err = open_objset(ds, DMU_OST_ZFS, FTAG, &os); + if (err != 0) + return (err); + + err = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, &root_obj); + if (err != 0) { + (void) fprintf(stderr, "can't lookup root znode: %s\n", + strerror(err)); + dmu_objset_disown(os, FTAG); + return (EINVAL); + } + + (void) snprintf(curpath, sizeof (curpath), "dataset=%s path=/", ds); + + err = dump_path_impl(os, root_obj, path); + + close_objset(os, FTAG); + return (err); +} + +static int dump_label(const char *dev) { int fd; vdev_label_t label; - char *path, *buf = label.vl_vdev_phys.vp_nvlist; + char path[MAXPATHLEN]; + char *buf = label.vl_vdev_phys.vp_nvlist; size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist); struct stat64 statbuf; uint64_t psize, ashift; - int len = strlen(dev) + 1; + boolean_t label_found = B_FALSE; - if (strncmp(dev, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) { - len++; - path = malloc(len); - (void) snprintf(path, len, "%s%s", ZFS_RDISK_ROOTD, - dev + strlen(ZFS_DISK_ROOTD)); - } else { - path = strdup(dev); + (void) strlcpy(path, dev, sizeof (path)); + if (dev[0] == '/') { + if (strncmp(dev, ZFS_DISK_ROOTD, + strlen(ZFS_DISK_ROOTD)) == 0) { + (void) snprintf(path, sizeof (path), "%s%s", + ZFS_RDISK_ROOTD, dev + strlen(ZFS_DISK_ROOTD)); + } + } else if (stat64(path, &statbuf) != 0) { + char *s; + + (void) snprintf(path, sizeof (path), "%s%s", ZFS_RDISK_ROOTD, + dev); + if (((s = strrchr(dev, 's')) == NULL && + (s = strchr(dev, 'p')) == NULL) || + !isdigit(*(s + 1))) + (void) strlcat(path, "s0", sizeof (path)); } if ((fd = open64(path, O_RDONLY)) < 0) { - (void) printf("cannot open '%s': %s\n", path, strerror(errno)); - free(path); + (void) fprintf(stderr, "cannot open '%s': %s\n", path, + strerror(errno)); exit(1); } if (fstat64(fd, &statbuf) != 0) { - (void) printf("failed to stat '%s': %s\n", path, + (void) fprintf(stderr, "failed to stat '%s': %s\n", path, strerror(errno)); - free(path); (void) close(fd); exit(1); } if (S_ISBLK(statbuf.st_mode)) { - (void) printf("cannot use '%s': character device required\n", - path); - free(path); + (void) fprintf(stderr, + "cannot use '%s': character device required\n", path); (void) close(fd); exit(1); } @@ -2204,36 +2406,43 @@ dump_label(const char *dev) for (int l = 0; l < VDEV_LABELS; l++) { nvlist_t *config = NULL; - (void) printf("--------------------------------------------\n"); - (void) printf("LABEL %d\n", l); - (void) printf("--------------------------------------------\n"); + if (!dump_opt['q']) { + (void) printf("------------------------------------\n"); + (void) printf("LABEL %d\n", l); + (void) printf("------------------------------------\n"); + } if (pread64(fd, &label, sizeof (label), vdev_label_offset(psize, l, 0)) != sizeof (label)) { - (void) printf("failed to read label %d\n", l); + if (!dump_opt['q']) + (void) printf("failed to read label %d\n", l); continue; } if (nvlist_unpack(buf, buflen, &config, 0) != 0) { - (void) printf("failed to unpack label %d\n", l); + if (!dump_opt['q']) + (void) printf("failed to unpack label %d\n", l); ashift = SPA_MINBLOCKSHIFT; } else { nvlist_t *vdev_tree = NULL; - dump_nvlist(config, 4); + if (!dump_opt['q']) + dump_nvlist(config, 4); if ((nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) || (nvlist_lookup_uint64(vdev_tree, ZPOOL_CONFIG_ASHIFT, &ashift) != 0)) ashift = SPA_MINBLOCKSHIFT; nvlist_free(config); + label_found = B_TRUE; } if (dump_opt['u']) dump_label_uberblocks(&label, ashift); } - free(path); (void) close(fd); + + return (label_found ? 0 : 2); } static uint64_t dataset_feature_count[SPA_FEATURES]; @@ -2245,11 +2454,9 @@ dump_one_dir(const char *dsname, void *arg) int error; objset_t *os; - error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os); - if (error) { - (void) printf("Could not open %s, error %d\n", dsname, error); + error = open_objset(dsname, DMU_OST_ANY, FTAG, &os); + if (error != 0) return (0); - } for (spa_feature_t f = 0; f < SPA_FEATURES; f++) { if (!dmu_objset_ds(os)->ds_feature_inuse[f]) @@ -2260,9 +2467,8 @@ dump_one_dir(const char *dsname, void *arg) } dump_dir(os); - dmu_objset_disown(os, FTAG); + close_objset(os, FTAG); fuid_table_destroy(); - sa_loaded = B_FALSE; return (0); } @@ -2513,6 +2719,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, int sec_remaining = (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (buf) >= NN_NUMBUF_SZ); + zfs_nicenum(bytes, buf, sizeof (buf)); (void) fprintf(stderr, "\r%5s completed (%4dMB/s) " @@ -2862,6 +3071,14 @@ dump_block_stats(spa_t *spa) char avg[32], gang[32]; char *typename; + /* make sure nicenum has enough space */ + CTASSERT(sizeof (csize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (lsize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (psize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (asize) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (avg) >= NN_NUMBUF_SZ); + CTASSERT(sizeof (gang) >= NN_NUMBUF_SZ); + if (t < DMU_OT_NUMTYPES) typename = dmu_ot[t].ot_name; else @@ -2895,12 +3112,17 @@ dump_block_stats(spa_t *spa) zcb.zcb_type[ZB_TOTAL][t].zb_asize) continue; - zdb_nicenum(zb->zb_count, csize); - zdb_nicenum(zb->zb_lsize, lsize); - zdb_nicenum(zb->zb_psize, psize); - zdb_nicenum(zb->zb_asize, asize); - zdb_nicenum(zb->zb_asize / zb->zb_count, avg); - zdb_nicenum(zb->zb_gangs, gang); + zdb_nicenum(zb->zb_count, csize, + sizeof (csize)); + zdb_nicenum(zb->zb_lsize, lsize, + sizeof (lsize)); + zdb_nicenum(zb->zb_psize, psize, + sizeof (psize)); + zdb_nicenum(zb->zb_asize, asize, + sizeof (asize)); + zdb_nicenum(zb->zb_asize / zb->zb_count, avg, + sizeof (avg)); + zdb_nicenum(zb->zb_gangs, gang, sizeof (gang)); (void) printf("%6s\t%5s\t%5s\t%5s\t%5s" "\t%5.2f\t%6.2f\t", @@ -3497,6 +3719,33 @@ zdb_read_block(char *thing, spa_t *spa) free(dup); } +static void +zdb_embedded_block(char *thing) +{ + blkptr_t bp = { 0 }; + unsigned long long *words = (void *)&bp; + char buf[SPA_MAXBLOCKSIZE]; + int err; + + err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:" + "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx", + words + 0, words + 1, words + 2, words + 3, + words + 4, words + 5, words + 6, words + 7, + words + 8, words + 9, words + 10, words + 11, + words + 12, words + 13, words + 14, words + 15); + if (err != 16) { + (void) printf("invalid input format\n"); + exit(1); + } + ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE); + err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp)); + if (err != 0) { + (void) printf("decode failed: %u\n", err); + exit(1); + } + zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0); +} + static boolean_t pool_match(nvlist_t *cfg, char *tgt) { @@ -3595,6 +3844,7 @@ main(int argc, char **argv) char *target; nvlist_t *policy = NULL; uint64_t max_txg = UINT64_MAX; + int flags = ZFS_IMPORT_MISSING_LOG; int rewind = ZPOOL_NEVER_REWIND; char *spa_config_path_env; boolean_t target_is_spa = B_TRUE; @@ -3614,34 +3864,38 @@ main(int argc, char **argv) spa_config_path = spa_config_path_env; while ((c = getopt(argc, argv, - "bcdhilmMI:suCDRSAFLXx:evp:t:U:PG")) != -1) { + "AbcCdDeEFGhiI:lLmMo:Op:PqRsSt:uU:vVx:X")) != -1) { switch (c) { case 'b': case 'c': + case 'C': case 'd': + case 'D': + case 'E': + case 'G': case 'h': case 'i': case 'l': case 'm': - case 's': - case 'u': - case 'C': - case 'D': case 'M': + case 'O': case 'R': + case 's': case 'S': - case 'G': + case 'u': dump_opt[c]++; dump_all = 0; break; case 'A': + case 'e': case 'F': case 'L': - case 'X': - case 'e': case 'P': + case 'q': + case 'X': dump_opt[c]++; break; + /* NB: Sort single match options below. */ case 'I': max_inflight = strtoull(optarg, NULL, 0); if (max_inflight == 0) { @@ -3651,6 +3905,11 @@ main(int argc, char **argv) usage(); } break; + case 'o': + error = set_global_var(optarg); + if (error != 0) + usage(); + break; case 'p': if (searchdirs == NULL) { searchdirs = umem_alloc(sizeof (char *), @@ -3676,10 +3935,19 @@ main(int argc, char **argv) break; case 'U': spa_config_path = optarg; + if (spa_config_path[0] != '/') { + (void) fprintf(stderr, + "cachefile must be an absolute path " + "(i.e. start with a slash)\n"); + usage(); + } break; case 'v': verbose++; break; + case 'V': + flags = ZFS_IMPORT_VERBATIM; + break; case 'x': vn_dumpdir = optarg; break; @@ -3721,7 +3989,7 @@ main(int argc, char **argv) verbose = MAX(verbose, 1); for (c = 0; c < 256; c++) { - if (dump_all && !strchr("elAFLRSXP", c)) + if (dump_all && strchr("AeEFlLOPRSX", c) == NULL) dump_opt[c] = 1; if (dump_opt[c]) dump_opt[c] += verbose; @@ -3735,6 +4003,14 @@ main(int argc, char **argv) if (argc < 2 && dump_opt['R']) usage(); + + if (dump_opt['E']) { + if (argc != 1) + usage(); + zdb_embedded_block(argv[0]); + return (0); + } + if (argc < 1) { if (!dump_opt['e'] && dump_opt['C']) { dump_cachefile(spa_config_path); @@ -3743,9 +4019,14 @@ main(int argc, char **argv) usage(); } - if (dump_opt['l']) { - dump_label(argv[0]); - return (0); + if (dump_opt['l']) + return (dump_label(argv[0])); + + if (dump_opt['O']) { + if (argc != 2) + usage(); + dump_opt['v'] = verbose + 3; + return (dump_path(argv[0], argv[1])); } if (dump_opt['X'] || dump_opt['F']) @@ -3775,11 +4056,7 @@ main(int argc, char **argv) fatal("can't open '%s': %s", target, strerror(ENOMEM)); } - if ((error = spa_import(name, cfg, NULL, - ZFS_IMPORT_MISSING_LOG)) != 0) { - error = spa_import(name, cfg, NULL, - ZFS_IMPORT_VERBATIM); - } + error = spa_import(name, cfg, NULL, flags); } } @@ -3822,8 +4099,7 @@ main(int argc, char **argv) } } } else { - error = dmu_objset_own(target, DMU_OST_ANY, - B_TRUE, FTAG, &os); + error = open_objset(target, DMU_OST_ANY, FTAG, &os); } } nvlist_free(policy); @@ -3866,10 +4142,12 @@ main(int argc, char **argv) zdb_read_block(argv[i], spa); } - (os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG); + if (os != NULL) + close_objset(os, FTAG); + else + spa_close(spa, FTAG); fuid_table_destroy(); - sa_loaded = B_FALSE; dump_debug_buffer(); diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8 new file mode 100644 index 000000000000..0ede564e1fa2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8 @@ -0,0 +1,536 @@ +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2016, 2017 by Delphix. All rights reserved. +.\" +.Dd October 02, 2017 +.Dt ZFS-PROGRAM 1M +.Os +.Sh NAME +.Nm zfs program +.Nd executes ZFS channel programs +.Sh SYNOPSIS +.Cm zfs program +.Op Fl t Ar instruction-limit +.Op Fl m Ar memory-limit +.Ar pool +.Ar script +.\".Op Ar optional arguments to channel program +.Sh DESCRIPTION +The ZFS channel program interface allows ZFS administrative operations to be +run programmatically as a Lua script. +The entire script is executed atomically, with no other administrative +operations taking effect concurrently. +A library of ZFS calls is made available to channel program scripts. +Channel programs may only be run with root privileges. +.Pp +A modified version of the Lua 5.2 interpreter is used to run channel program +scripts. +The Lua 5.2 manual can be found at: +.Bd -centered -offset indent +.Lk http://www.lua.org/manual/5.2/ +.Ed +.Pp +The channel program given by +.Ar script +will be run on +.Ar pool , +and any attempts to access or modify other pools will cause an error. +.Sh OPTIONS +.Bl -tag -width "-t" +.It Fl t Ar instruction-limit +Execution time limit, in number of Lua instructions to execute. +If a channel program executes more than the specified number of instructions, +it will be stopped and an error will be returned. +The default limit is 10 million instructions, and it can be set to a maximum of +100 million instructions. +.It Fl m Ar memory-limit +Memory limit, in bytes. +If a channel program attempts to allocate more memory than the given limit, it +will be stopped and an error returned. +The default memory limit is 10 MB, and can be set to a maximum of 100 MB. +.El +.Pp +All remaining argument strings will be passed directly to the Lua script as +described in the +.Sx LUA INTERFACE +section below. +.Sh LUA INTERFACE +A channel program can be invoked either from the command line, or via a library +call to +.Fn lzc_channel_program . +.Ss Arguments +Arguments passed to the channel program are converted to a Lua table. +If invoked from the command line, extra arguments to the Lua script will be +accessible as an array stored in the argument table with the key 'argv': +.Bd -literal -offset indent +args = ... +argv = args["argv"] +-- argv == {1="arg1", 2="arg2", ...} +.Ed +.Pp +If invoked from the libZFS interface, an arbitrary argument list can be +passed to the channel program, which is accessible via the same +"..." syntax in Lua: +.Bd -literal -offset indent +args = ... +-- args == {"foo"="bar", "baz"={...}, ...} +.Ed +.Pp +Note that because Lua arrays are 1-indexed, arrays passed to Lua from the +libZFS interface will have their indices incremented by 1. +That is, the element +in +.Va arr[0] +in a C array passed to a channel program will be stored in +.Va arr[1] +when accessed from Lua. +.Ss Return Values +Lua return statements take the form: +.Bd -literal -offset indent +return ret0, ret1, ret2, ... +.Ed +.Pp +Return statements returning multiple values are permitted internally in a +channel program script, but attempting to return more than one value from the +top level of the channel program is not permitted and will throw an error. +However, tables containing multiple values can still be returned. +If invoked from the command line, a return statement: +.Bd -literal -offset indent +a = {foo="bar", baz=2} +return a +.Ed +.Pp +Will be output formatted as: +.Bd -literal -offset indent +Channel program fully executed with return value: + return: + baz: 2 + foo: 'bar' +.Ed +.Ss Fatal Errors +If the channel program encounters a fatal error while running, a non-zero exit +status will be returned. +If more information about the error is available, a singleton list will be +returned detailing the error: +.Bd -literal -offset indent +error: "error string, including Lua stack trace" +.Ed +.Pp +If a fatal error is returned, the channel program may have not executed at all, +may have partially executed, or may have fully executed but failed to pass a +return value back to userland. +.Pp +If the channel program exhausts an instruction or memory limit, a fatal error +will be generated and the program will be stopped, leaving the program partially +executed. +No attempt is made to reverse or undo any operations already performed. +Note that because both the instruction count and amount of memory used by a +channel program are deterministic when run against the same inputs and +filesystem state, as long as a channel program has run successfully once, you +can guarantee that it will finish successfully against a similar size system. +.Pp +If a channel program attempts to return too large a value, the program will +fully execute but exit with a nonzero status code and no return value. +.Pp +.Em Note: +ZFS API functions do not generate Fatal Errors when correctly invoked, they +return an error code and the channel program continues executing. +See the +.Sx ZFS API +section below for function-specific details on error return codes. +.Ss Lua to C Value Conversion +When invoking a channel program via the libZFS interface, it is necessary to +translate arguments and return values from Lua values to their C equivalents, +and vice-versa. +.Pp +There is a correspondence between nvlist values in C and Lua tables. +A Lua table which is returned from the channel program will be recursively +converted to an nvlist, with table values converted to their natural +equivalents: +.Bd -literal -offset indent +string -> string +number -> int64 +boolean -> boolean_value +nil -> boolean (no value) +table -> nvlist +.Ed +.Pp +Likewise, table keys are replaced by string equivalents as follows: +.Bd -literal -offset indent +string -> no change +number -> signed decimal string ("%lld") +boolean -> "true" | "false" +.Ed +.Pp +Any collision of table key strings (for example, the string "true" and a +true boolean value) will cause a fatal error. +.Pp +Lua numbers are represented internally as signed 64-bit integers. +.Sh LUA STANDARD LIBRARY +The following Lua built-in base library functions are available: +.Bd -literal -offset indent +assert rawlen +collectgarbage rawget +error rawset +getmetatable select +ipairs setmetatable +next tonumber +pairs tostring +rawequal type +.Ed +.Pp +All functions in the +.Em coroutine , +.Em string , +and +.Em table +built-in submodules are also available. +A complete list and documentation of these modules is available in the Lua +manual. +.Pp +The following functions base library functions have been disabled and are +not available for use in channel programs: +.Bd -literal -offset indent +dofile +loadfile +load +pcall +print +xpcall +.Ed +.Sh ZFS API +.Ss Function Arguments +Each API function takes a fixed set of required positional arguments and +optional keyword arguments. +For example, the destroy function takes a single positional string argument +(the name of the dataset to destroy) and an optional "defer" keyword boolean +argument. +When using parentheses to specify the arguments to a Lua function, only +positional arguments can be used: +.Bd -literal -offset indent +zfs.sync.destroy("rpool@snap") +.Ed +.Pp +To use keyword arguments, functions must be called with a single argument that +is a Lua table containing entries mapping integers to positional arguments and +strings to keyword arguments: +.Bd -literal -offset indent +zfs.sync.destroy({1="rpool@snap", defer=true}) +.Ed +.Pp +The Lua language allows curly braces to be used in place of parenthesis as +syntactic sugar for this calling convention: +.Bd -literal -offset indent +zfs.sync.snapshot{"rpool@snap", defer=true} +.Ed +.Ss Function Return Values +If an API function succeeds, it returns 0. +If it fails, it returns an error code and the channel program continues +executing. +API functions do not generate Fatal Errors except in the case of an +unrecoverable internal file system error. +.Pp +In addition to returning an error code, some functions also return extra +details describing what caused the error. +This extra description is given as a second return value, and will always be a +Lua table, or Nil if no error details were returned. +Different keys will exist in the error details table depending on the function +and error case. +Any such function may be called expecting a single return value: +.Bd -literal -offset indent +errno = zfs.sync.promote(dataset) +.Ed +.Pp +Or, the error details can be retrieved: +.Bd -literal -offset indent +errno, details = zfs.sync.promote(dataset) +if (errno == EEXIST) then + assert(details ~= Nil) + list_of_conflicting_snapshots = details +end +.Ed +.Pp +The following global aliases for API function error return codes are defined +for use in channel programs: +.Bd -literal -offset indent +EPERM ECHILD ENODEV ENOSPC +ENOENT EAGAIN ENOTDIR ESPIPE +ESRCH ENOMEM EISDIR EROFS +EINTR EACCES EINVAL EMLINK +EIO EFAULT ENFILE EPIPE +ENXIO ENOTBLK EMFILE EDOM +E2BIG EBUSY ENOTTY ERANGE +ENOEXEC EEXIST ETXTBSY EDQUOT +EBADF EXDEV EFBIG +.Ed +.Ss API Functions +For detailed descriptions of the exact behavior of any zfs administrative +operations, see the main +.Xr zfs 1 +manual page. +.Bl -tag -width "xx" +.It Em zfs.debug(msg) +Record a debug message in the zfs_dbgmsg log. +A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or +can be monitored live by running: +.Bd -literal -offset indent + dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}' +.Ed +.Pp +msg (string) +.Bd -ragged -compact -offset "xxxx" +Debug message to be printed. +.Ed +.It Em zfs.exists(dataset) +Returns true if the given dataset exists, or false if it doesn't. +A fatal error will be thrown if the dataset is not in the target pool. +That is, in a channel program running on rpool, +zfs.exists("rpool/nonexistent_fs") returns false, but +zfs.exists("somepool/fs_that_may_exist") will error. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Dataset to check for existence. +Must be in the target pool. +.Ed +.It Em zfs.get_prop(dataset, property) +Returns two values. +First, a string, number or table containing the property value for the given +dataset. +Second, a string containing the source of the property (i.e. the name of the +dataset in which it was set or nil if it is readonly). +Throws a Lua error if the dataset is invalid or the property doesn't exist. +Note that Lua only supports int64 number types whereas ZFS number properties +are uint64. +This means very large values (like guid) may wrap around and appear negative. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Filesystem or snapshot path to retrieve properties from. +.Ed +.Pp +property (string) +.Bd -ragged -compact -offset "xxxx" +Name of property to retrieve. +All filesystem, snapshot and volume properties are supported except +for 'mounted' and 'iscsioptions.' +Also supports the 'written@snap' and 'written#bookmark' properties and +the '@id' properties, though the id must be in numeric +form. +.Ed +.El +.Bl -tag -width "xx" +.It Sy zfs.sync submodule +The sync submodule contains functions that modify the on-disk state. +They are executed in "syncing context". +.Pp +The available sync submodule functions are as follows: +.Bl -tag -width "xx" +.It Em zfs.sync.destroy(dataset, [defer=true|false]) +Destroy the given dataset. +Returns 0 on successful destroy, or a nonzero error code if the dataset could +not be destroyed (for example, if the dataset has any active children or +clones). +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Filesystem or snapshot to be destroyed. +.Ed +.Pp +[optional] defer (boolean) +.Bd -ragged -compact -offset "xxxx" +Valid only for destroying snapshots. +If set to true, and the snapshot has holds or clones, allows the snapshot to be +marked for deferred deletion rather than failing. +.Ed +.It Em zfs.sync.promote(dataset) +Promote the given clone to a filesystem. +Returns 0 on successful promotion, or a nonzero error code otherwise. +If EEXIST is returned, the second return value will be an array of the clone's +snapshots whose names collide with snapshots of the parent filesystem. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Clone to be promoted. +.Ed +.It Em zfs.sync.rollback(filesystem) +Rollback to the previous snapshot for a dataset. +Returns 0 on successful rollback, or a nonzero error code otherwise. +Rollbacks can be performed on filesystems or zvols, but not on snapshots +or mounted datasets. +EBUSY is returned in the case where the filesystem is mounted. +.Pp +filesystem (string) +.Bd -ragged -compact -offset "xxxx" +Filesystem to rollback. +.Ed +.It Em zfs.sync.snapshot(dataset) +Create a snapshot of a filesystem. +Returns 0 if the snapshot was successfully created, +and a nonzero error code otherwise. +.Pp +Note: Taking a snapshot will fail on any pool older than legacy version 27. +To enable taking snapshots from ZCP scripts, the pool must be upgraded. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Name of snapshot to create. +.Ed +.El +.It Sy zfs.check submodule +For each function in the zfs.sync submodule, there is a corresponding zfs.check +function which performs a "dry run" of the same operation. +Each takes the same arguments as its zfs.sync counterpart and returns 0 if the +operation would succeed, or a non-zero error code if it would fail, along with +any other error details. +That is, each has the same behavior as the corresponding sync function except +for actually executing the requested change. +For example, +.Em zfs.check.destroy("fs") +returns 0 if +.Em zfs.sync.destroy("fs") +would successfully destroy the dataset. +.Pp +The available zfs.check functions are: +.Bl -tag -width "xx" +.It Em zfs.check.destroy(dataset, [defer=true|false]) +.It Em zfs.check.promote(dataset) +.It Em zfs.check.rollback(filesystem) +.It Em zfs.check.snapshot(dataset) +.El +.It Sy zfs.list submodule +The zfs.list submodule provides functions for iterating over datasets and +properties. +Rather than returning tables, these functions act as Lua iterators, and are +generally used as follows: +.Bd -literal -offset indent +for child in zfs.list.children("rpool") do + ... +end +.Ed +.Pp +The available zfs.list functions are: +.Bl -tag -width "xx" +.It Em zfs.list.clones(snapshot) +Iterate through all clones of the given snapshot. +.Pp +snapshot (string) +.Bd -ragged -compact -offset "xxxx" +Must be a valid snapshot path in the current pool. +.Ed +.It Em zfs.list.snapshots(dataset) +Iterate through all snapshots of the given dataset. +Each snapshot is returned as a string containing the full dataset name, e.g. +"pool/fs@snap". +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Must be a valid filesystem or volume. +.Ed +.It Em zfs.list.children(dataset) +Iterate through all direct children of the given dataset. +Each child is returned as a string containing the full dataset name, e.g. +"pool/fs/child". +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Must be a valid filesystem or volume. +.Ed +.It Em zfs.list.properties(dataset) +Iterate through all user properties for the given dataset. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Must be a valid filesystem, snapshot, or volume. +.Ed +.It Em zfs.list.system_properties(dataset) +Returns an array of strings, the names of the valid system (non-user defined) +properties for the given dataset. +Throws a Lua error if the dataset is invalid. +.Pp +dataset (string) +.Bd -ragged -compact -offset "xxxx" +Must be a valid filesystem, snapshot or volume. +.Ed +.El +.El +.Sh EXAMPLES +.Ss Example 1 +The following channel program recursively destroys a filesystem and all its +snapshots and children in a naive manner. +Note that this does not involve any error handling or reporting. +.Bd -literal -offset indent +function destroy_recursive(root) + for child in zfs.list.children(root) do + destroy_recursive(child) + end + for snap in zfs.list.snapshots(root) do + zfs.sync.destroy(snap) + end + zfs.sync.destroy(root) +end +destroy_recursive("pool/somefs") +.Ed +.Ss Example 2 +A more verbose and robust version of the same channel program, which +properly detects and reports errors, and also takes the dataset to destroy +as a command line argument, would be as follows: +.Bd -literal -offset indent +succeeded = {} +failed = {} + +function destroy_recursive(root) + for child in zfs.list.children(root) do + destroy_recursive(child) + end + for snap in zfs.list.snapshots(root) do + err = zfs.sync.destroy(snap) + if (err ~= 0) then + failed[snap] = err + else + succeeded[snap] = err + end + end + err = zfs.sync.destroy(root) + if (err ~= 0) then + failed[root] = err + else + succeeded[root] = err + end +end + +args = ... +argv = args["argv"] + +destroy_recursive(argv[1]) + +results = {} +results["succeeded"] = succeeded +results["failed"] = failed +return results +.Ed +.Ss Example 3 +The following function performs a forced promote operation by attempting to +promote the given clone and destroying any conflicting snapshots. +.Bd -literal -offset indent +function force_promote(ds) + errno, details = zfs.check.promote(ds) + if (errno == EEXIST) then + assert(details ~= Nil) + for i, snap in ipairs(details) do + zfs.sync.destroy(ds .. "@" .. snap) + end + elseif (errno ~= 0) then + return errno + end + return zfs.sync.promote(ds) +end +.Ed diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 index 677b559644ba..d52b30f0c180 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 @@ -286,6 +286,12 @@ .Ar snapshot .Op Ar snapshot Ns | Ns Ar filesystem .Nm +.Cm program +.Op Fl t Ar timeout +.Op Fl m Ar memory_limit +.Ar pool script +.Op Ar arg1 No ... +.Nm .Cm jail .Ar jailid Ns | Ns Ar jailname filesystem .Nm @@ -3287,6 +3293,48 @@ Display the path's inode change time as the first column of output. .El .It Xo .Nm +.Cm program +.Op Fl t Ar timeout +.Op Fl m Ar memory_limit +.Ar pool script +.Op Ar arg1 No ... +.Xc +.Pp +Executes +.Ar script +as a ZFS channel program on +.Ar pool . +The ZFS channel +program interface allows ZFS administrative operations to be run +programmatically via a Lua script. +The entire script is executed atomically, with no other administrative +operations taking effect concurrently. +A library of ZFS calls is made available to channel program scripts. +Channel programs may only be run with root privileges. +.Pp +For full documentation of the ZFS channel program interface, see the manual +page for +.Xr zfs-program 8 . +.Bl -tag -width indent +.It Fl t Ar timeout +Execution time limit, in milliseconds. +If a channel program executes for longer than the provided timeout, it will +be stopped and an error will be returned. +The default timeout is 1000 ms, and can be set to a maximum of 10000 ms. +.It Fl m Ar memory-limit +Memory limit, in bytes. +If a channel program attempts to allocate more memory than the given limit, +it will be stopped and an error returned. +The default memory limit is 10 MB, and can be set to a maximum of 100 MB. +.Pp +All remaining argument strings are passed directly to the channel program as +arguments. +See +.Xr zfs-program 8 +for more information. +.El +.It Xo +.Nm .Cm jail .Ar jailid filesystem .Xc diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c index 39d3802c910b..4727b9f49223 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,7 @@ static int zfs_do_diff(int argc, char **argv); static int zfs_do_jail(int argc, char **argv); static int zfs_do_unjail(int argc, char **argv); static int zfs_do_bookmark(int argc, char **argv); +static int zfs_do_channel_program(int argc, char **argv); /* * Enable a reasonable set of defaults for libumem debugging on DEBUG builds. @@ -160,6 +162,7 @@ typedef enum { HELP_RELEASE, HELP_DIFF, HELP_BOOKMARK, + HELP_CHANNEL_PROGRAM, } zfs_help_t; typedef struct zfs_command { @@ -187,6 +190,7 @@ static zfs_command_t command_table[] = { { "promote", zfs_do_promote, HELP_PROMOTE }, { "rename", zfs_do_rename, HELP_RENAME }, { "bookmark", zfs_do_bookmark, HELP_BOOKMARK }, + { "program", zfs_do_channel_program, HELP_CHANNEL_PROGRAM }, { NULL }, { "list", zfs_do_list, HELP_LIST }, { NULL }, @@ -340,6 +344,10 @@ get_usage(zfs_help_t idx) "[snapshot|filesystem]\n")); case HELP_BOOKMARK: return (gettext("\tbookmark \n")); + case HELP_CHANNEL_PROGRAM: + return (gettext("\tprogram [-t ] " + "[-m ] " + "[lua args...]\n")); } abort(); @@ -368,6 +376,18 @@ safe_malloc(size_t size) return (data); } +void * +safe_realloc(void *data, size_t size) +{ + void *newp; + if ((newp = realloc(data, size)) == NULL) { + free(data); + nomem(); + } + + return (newp); +} + static char * safe_strdup(char *str) { @@ -7101,6 +7121,194 @@ zfs_do_bookmark(int argc, char **argv) return (-1); } +static int +zfs_do_channel_program(int argc, char **argv) +{ + int ret, fd; + char c; + char *progbuf, *filename, *poolname; + size_t progsize, progread; + nvlist_t *outnvl; + uint64_t instrlimit = ZCP_DEFAULT_INSTRLIMIT; + uint64_t memlimit = ZCP_DEFAULT_MEMLIMIT; + zpool_handle_t *zhp; + + /* check options */ + while (-1 != + (c = getopt(argc, argv, "t:(instr-limit)m:(memory-limit)"))) { + switch (c) { + case 't': + case 'm': { + uint64_t arg; + char *endp; + + errno = 0; + arg = strtoull(optarg, &endp, 0); + if (errno != 0 || *endp != '\0') { + (void) fprintf(stderr, gettext( + "invalid argument " + "'%s': expected integer\n"), optarg); + goto usage; + } + + if (c == 't') { + if (arg > ZCP_MAX_INSTRLIMIT || arg == 0) { + (void) fprintf(stderr, gettext( + "Invalid instruction limit: " + "%s\n"), optarg); + return (1); + } else { + instrlimit = arg; + } + } else { + ASSERT3U(c, ==, 'm'); + if (arg > ZCP_MAX_MEMLIMIT || arg == 0) { + (void) fprintf(stderr, gettext( + "Invalid memory limit: " + "%s\n"), optarg); + return (1); + } else { + memlimit = arg; + } + } + break; + } + case '?': + (void) fprintf(stderr, gettext("invalid option '%c'\n"), + optopt); + goto usage; + } + } + + argc -= optind; + argv += optind; + + if (argc < 2) { + (void) fprintf(stderr, + gettext("invalid number of arguments\n")); + goto usage; + } + + poolname = argv[0]; + filename = argv[1]; + if (strcmp(filename, "-") == 0) { + fd = 0; + filename = "standard input"; + } else if ((fd = open(filename, O_RDONLY)) < 0) { + (void) fprintf(stderr, gettext("cannot open '%s': %s\n"), + filename, strerror(errno)); + return (1); + } + + if ((zhp = zpool_open(g_zfs, poolname)) == NULL) { + (void) fprintf(stderr, gettext("cannot open pool '%s'"), + poolname); + return (1); + } + zpool_close(zhp); + + /* + * Read in the channel program, expanding the program buffer as + * necessary. + */ + progread = 0; + progsize = 1024; + progbuf = safe_malloc(progsize); + do { + ret = read(fd, progbuf + progread, progsize - progread); + progread += ret; + if (progread == progsize && ret > 0) { + progsize *= 2; + progbuf = safe_realloc(progbuf, progsize); + } + } while (ret > 0); + + if (fd != 0) + (void) close(fd); + if (ret < 0) { + free(progbuf); + (void) fprintf(stderr, + gettext("cannot read '%s': %s\n"), + filename, strerror(errno)); + return (1); + } + progbuf[progread] = '\0'; + + /* + * Any remaining arguments are passed as arguments to the lua script as + * a string array: + * { + * "argv" -> [ "arg 1", ... "arg n" ], + * } + */ + nvlist_t *argnvl = fnvlist_alloc(); + fnvlist_add_string_array(argnvl, ZCP_ARG_CLIARGV, argv + 2, argc - 2); + + ret = lzc_channel_program(poolname, progbuf, instrlimit, memlimit, + argnvl, &outnvl); + + if (ret != 0) { + /* + * On error, report the error message handed back by lua if one + * exists. Otherwise, generate an appropriate error message, + * falling back on strerror() for an unexpected return code. + */ + char *errstring = NULL; + if (nvlist_exists(outnvl, ZCP_RET_ERROR)) { + (void) nvlist_lookup_string(outnvl, + ZCP_RET_ERROR, &errstring); + if (errstring == NULL) + errstring = strerror(ret); + } else { + switch (ret) { + case EINVAL: + errstring = + "Invalid instruction or memory limit."; + break; + case ENOMEM: + errstring = "Return value too large."; + break; + case ENOSPC: + errstring = "Memory limit exhausted."; + break; +#ifdef illumos + case ETIME: +#else + case ETIMEDOUT: +#endif + errstring = "Timed out."; + break; + case EPERM: + errstring = "Permission denied. Channel " + "programs must be run as root."; + break; + default: + errstring = strerror(ret); + } + } + (void) fprintf(stderr, + gettext("Channel program execution failed:\n%s\n"), + errstring); + } else { + (void) printf("Channel program fully executed "); + if (nvlist_empty(outnvl)) { + (void) printf("with no return value.\n"); + } else { + (void) printf("with return value:\n"); + dump_nvlist(outnvl, 4); + } + } + + free(progbuf); + fnvlist_free(outnvl); + fnvlist_free(argnvl); + return (ret != 0); + +usage: + usage(B_FALSE); + return (-1); +} + int main(int argc, char **argv) { diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c index 572265fbaf9e..99be59879419 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2012 by Frederik Wessels. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. @@ -705,7 +705,7 @@ zpool_do_labelclear(int argc, char **argv) return (1); } - if (zpool_read_label(fd, &config) != 0 || config == NULL) { + if (zpool_read_label(fd, &config) != 0) { (void) fprintf(stderr, gettext("failed to read label from %s\n"), vdev); return (1); @@ -5254,6 +5254,11 @@ get_history_one(zpool_handle_t *zhp, void *data) dump_nvlist(fnvlist_lookup_nvlist(rec, ZPOOL_HIST_OUTPUT_NVL), 8); } + if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { + (void) printf(" errno: %lld\n", + fnvlist_lookup_int64(rec, + ZPOOL_HIST_ERRNO)); + } } else { if (!cb->internal) continue; diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c index 2205c9563eeb..64c550e5cc1a 100644 --- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c +++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c @@ -25,6 +25,7 @@ * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2017 Joyent, Inc. */ /* @@ -125,6 +126,7 @@ #include #include #include +#include static int ztest_fd_data = -1; static int ztest_fd_rand = -1; @@ -556,12 +558,13 @@ usage(boolean_t requested) { const ztest_shared_opts_t *zo = &ztest_opts_defaults; - char nice_vdev_size[10]; - char nice_gang_bang[10]; + char nice_vdev_size[NN_NUMBUF_SZ]; + char nice_gang_bang[NN_NUMBUF_SZ]; FILE *fp = requested ? stdout : stderr; - nicenum(zo->zo_vdev_size, nice_vdev_size); - nicenum(zo->zo_metaslab_gang_bang, nice_gang_bang); + nicenum(zo->zo_vdev_size, nice_vdev_size, sizeof (nice_vdev_size)); + nicenum(zo->zo_metaslab_gang_bang, nice_gang_bang, + sizeof (nice_gang_bang)); (void) fprintf(fp, "Usage: %s\n" "\t[-v vdevs (default: %llu)]\n" @@ -583,6 +586,8 @@ usage(boolean_t requested) "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n" "\t[-P passtime (default: %llu sec)] time per pass\n" "\t[-B alt_ztest (default: )] alternate ztest path\n" + "\t[-o variable=value] ... set global variable to an unsigned\n" + "\t 32-bit integer value\n" "\t[-h] (print help)\n" "", zo->zo_pool, @@ -618,7 +623,7 @@ process_options(int argc, char **argv) bcopy(&ztest_opts_defaults, zo, sizeof (*zo)); while ((opt = getopt(argc, argv, - "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) { + "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:o:")) != EOF) { value = 0; switch (opt) { case 'v': @@ -705,6 +710,10 @@ process_options(int argc, char **argv) case 'B': (void) strlcpy(altdir, optarg, sizeof (altdir)); break; + case 'o': + if (set_global_var(optarg) != 0) + usage(B_FALSE); + break; case 'h': usage(B_TRUE); break; @@ -1825,13 +1834,14 @@ ztest_get_done(zgd_t *zgd, int error) ztest_object_unlock(zd, object); if (error == 0 && zgd->zgd_bp) - zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); + zil_lwb_add_block(zgd->zgd_lwb, zgd->zgd_bp); umem_free(zgd, sizeof (*zgd)); } static int -ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) +ztest_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, + zio_t *zio) { ztest_ds_t *zd = arg; objset_t *os = zd->zd_os; @@ -1845,6 +1855,10 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) zgd_t *zgd; int error; + ASSERT3P(lwb, !=, NULL); + ASSERT3P(zio, !=, NULL); + ASSERT3U(size, !=, 0); + ztest_object_lock(zd, object, RL_READER); error = dmu_bonus_hold(os, object, FTAG, &db); if (error) { @@ -1865,7 +1879,7 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) db = NULL; zgd = umem_zalloc(sizeof (*zgd), UMEM_NOFAIL); - zgd->zgd_zilog = zd->zd_zilog; + zgd->zgd_lwb = lwb; zgd->zgd_private = zd; if (buf != NULL) { /* immediate write */ @@ -3147,10 +3161,10 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id) old_class_space, new_class_space); if (ztest_opts.zo_verbose >= 5) { - char oldnumbuf[6], newnumbuf[6]; + char oldnumbuf[NN_NUMBUF_SZ], newnumbuf[NN_NUMBUF_SZ]; - nicenum(old_class_space, oldnumbuf); - nicenum(new_class_space, newnumbuf); + nicenum(old_class_space, oldnumbuf, sizeof (oldnumbuf)); + nicenum(new_class_space, newnumbuf, sizeof (newnumbuf)); (void) printf("%s grew from %s to %s\n", spa->spa_name, oldnumbuf, newnumbuf); } @@ -6193,7 +6207,7 @@ main(int argc, char **argv) ztest_info_t *zi; ztest_shared_callstate_t *zc; char timebuf[100]; - char numbuf[6]; + char numbuf[NN_NUMBUF_SZ]; spa_t *spa; char *cmd; boolean_t hasalt; @@ -6330,7 +6344,7 @@ main(int argc, char **argv) now = MIN(now, zs->zs_proc_stop); print_time(zs->zs_proc_stop - now, timebuf); - nicenum(zs->zs_space, numbuf); + nicenum(zs->zs_space, numbuf, sizeof (numbuf)); (void) printf("Pass %3d, %8s, %3llu ENOSPC, " "%4.1f%% of %5s used, %3.0f%% done, %8s to go\n", diff --git a/cddl/contrib/opensolaris/lib/libcmdutils/common/nicenum.c b/cddl/contrib/opensolaris/lib/libcmdutils/common/nicenum.c new file mode 100644 index 000000000000..8e3202f79270 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libcmdutils/common/nicenum.c @@ -0,0 +1,130 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Jason king + */ + +#include +#include +#include +#include +#include "libcmdutils.h" + +/* The largest suffix that can fit, aka an exabyte (2^60 / 10^18) */ +#define INDEX_MAX (6) + +/* Verify INDEX_MAX fits */ +CTASSERT(INDEX_MAX * 10 < sizeof (uint64_t) * 8); + +void +nicenum_scale(uint64_t n, size_t units, char *buf, size_t buflen, + uint32_t flags) +{ + uint64_t divamt = 1024; + uint64_t divisor = 1; + int index = 0; + int rc = 0; + char u; + + if (units == 0) + units = 1; + + if (n > 0) { + n *= units; + if (n < units) + goto overflow; + } + + if (flags & NN_DIVISOR_1000) + divamt = 1000; + + /* + * This tries to find the suffix S(n) such that + * S(n) <= n < S(n+1), where S(n) = 2^(n*10) | 10^(3*n) + * (i.e. 1024/1000, 1,048,576/1,000,000, etc). Stop once S(n) + * is the largest prefix supported (i.e. don't bother computing + * and checking S(n+1). Since INDEX_MAX should be the largest + * suffix that fits (currently an exabyte), S(INDEX_MAX + 1) is + * never checked as it would overflow. + */ + while (index < INDEX_MAX) { + uint64_t newdiv = divisor * divamt; + + /* CTASSERT() guarantee these never trip */ + VERIFY3U(newdiv, >=, divamt); + VERIFY3U(newdiv, >=, divisor); + + if (n < newdiv) + break; + + divisor = newdiv; + index++; + } + + u = " KMGTPE"[index]; + + if (index == 0) { + rc = snprintf(buf, buflen, "%llu", n); + } else if (n % divisor == 0) { + /* + * If this is an even multiple of the base, always display + * without any decimal precision. + */ + rc = snprintf(buf, buflen, "%llu%c", n / divisor, u); + } else { + /* + * We want to choose a precision that reflects the best choice + * for fitting in 5 characters. This can get rather tricky + * when we have numbers that are very close to an order of + * magnitude. For example, when displaying 10239 (which is + * really 9.999K), we want only a single place of precision + * for 10.0K. We could develop some complex heuristics for + * this, but it's much easier just to try each combination + * in turn. + */ + int i; + for (i = 2; i >= 0; i--) { + if ((rc = snprintf(buf, buflen, "%.*f%c", i, + (double)n / divisor, u)) <= 5) + break; + } + } + + if (rc + 1 > buflen || rc < 0) + goto overflow; + + return; + +overflow: + /* prefer a more verbose message if possible */ + if (buflen > 10) + (void) strlcpy(buf, "", buflen); + else + (void) strlcpy(buf, "??", buflen); +} + +void +nicenum(uint64_t num, char *buf, size_t buflen) +{ + nicenum_scale(num, 1, buf, buflen, 0); +} diff --git a/cddl/contrib/opensolaris/lib/libcmdutils/libcmdutils.h b/cddl/contrib/opensolaris/lib/libcmdutils/libcmdutils.h new file mode 100644 index 000000000000..fffdd9de22f1 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libcmdutils/libcmdutils.h @@ -0,0 +1,235 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* + * Copyright (c) 2013 RackTop Systems. + */ +/* + * Copyright 2017 Joyent, Inc. + */ + +/* + * Declarations for the functions in libcmdutils. + */ + +#ifndef _LIBCMDUTILS_H +#define _LIBCMDUTILS_H + +#ifdef illumos +#if !defined(_LP64) && \ + !((_FILE_OFFSET_BITS == 64) || defined(_LARGEFILE64_SOURCE)) +#error "libcmdutils.h can only be used in a largefile compilation environment" +#endif +#endif + +/* + * This is a private header file. Applications should not directly include + * this file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef illumos +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* extended system attribute support */ +#define _NOT_SATTR 0 +#define _RO_SATTR 1 +#define _RW_SATTR 2 + +#define MAXMAPSIZE (1024*1024*8) /* map at most 8MB */ +#define SMALLFILESIZE (32*1024) /* don't use mmap on little file */ + +/* Type used for a node containing a device id and inode number */ + +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) +typedef struct tree_node { + dev_t node_dev; + ino_t node_ino; + avl_node_t avl_link; +} tree_node_t; +#else +typedef struct tree_node { + dev_t node_dev; + ino64_t node_ino; + avl_node_t avl_link; +} tree_node_t; +#endif + + /* extended system attribute support */ + +/* Determine if a file is the name of an extended system attribute file */ +extern int sysattr_type(char *); + +/* Determine if the underlying file system supports system attributes */ +extern int sysattr_support(char *, int); + +/* Copies the content of the source file to the target file */ +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) +extern int writefile(int, int, char *, char *, char *, char *, + struct stat *, struct stat *); +#else +extern int writefile(int, int, char *, char *, char *, char *, + struct stat64 *, struct stat64 *); +#endif + +/* Gets file descriptors of the source and target attribute files */ +extern int get_attrdirs(int, int, char *, int *, int *); + +/* Move extended attribute and extended system attribute */ +extern int mv_xattrs(char *, char *, char *, int, int); + +/* Returns non default extended system attribute list */ +extern nvlist_t *sysattr_list(char *, int, char *); + + + + /* avltree */ + +/* + * Used to compare two nodes. We are attempting to match the 1st + * argument (node) against the 2nd argument (a node which + * is already in the search tree). + */ + +extern int tnode_compare(const void *, const void *); + +/* + * Used to add a single node (containing the input device id and + * inode number) to the specified search tree. The calling + * application must set the tree pointer to NULL before calling + * add_tnode() for the first time. + */ +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) +extern int add_tnode(avl_tree_t **, dev_t, ino_t); +#else +extern int add_tnode(avl_tree_t **, dev_t, ino64_t); +#endif + +/* + * Used to destroy a whole tree (all nodes) without rebalancing. + * The calling application is responsible for setting the tree + * pointer to NULL upon return. + */ +extern void destroy_tree(avl_tree_t *); + + + + /* user/group id helpers */ + +/* + * Used to get the next available user id in given range. + */ +extern int findnextuid(uid_t, uid_t, uid_t *); + +/* + * Used to get the next available group id in given range. + */ +extern int findnextgid(gid_t, gid_t, gid_t *); + + + + /* dynamic string utilities */ + +typedef struct custr custr_t; + +/* + * Allocate and free a "custr_t" dynamic string object. Returns 0 on success + * and -1 otherwise. + */ +extern int custr_alloc(custr_t **); +extern void custr_free(custr_t *); + +/* + * Allocate a "custr_t" dynamic string object that operates on a fixed external + * buffer. + */ +extern int custr_alloc_buf(custr_t **, void *, size_t); + +/* + * Append a single character, or a NUL-terminated string of characters, to a + * dynamic string. Returns 0 on success and -1 otherwise. The dynamic string + * will be unmodified if the function returns -1. + */ +extern int custr_appendc(custr_t *, char); +extern int custr_append(custr_t *, const char *); + +/* + * Append a format string and arguments as though the contents were being parsed + * through snprintf. Returns 0 on success and -1 otherwise. The dynamic string + * will be unmodified if the function returns -1. + */ +extern int custr_append_printf(custr_t *, const char *, ...); +extern int custr_append_vprintf(custr_t *, const char *, va_list); + +/* + * Determine the length in bytes, not including the NUL terminator, of the + * dynamic string. + */ +extern size_t custr_len(custr_t *); + +/* + * Clear the contents of a dynamic string. Does not free the underlying + * memory. + */ +extern void custr_reset(custr_t *); + +/* + * Retrieve a const pointer to a NUL-terminated string version of the contents + * of the dynamic string. Storage for this string should not be freed, and + * the pointer will be invalidated by any mutations to the dynamic string. + */ +extern const char *custr_cstr(custr_t *str); + +#define NN_DIVISOR_1000 (1U << 0) + +/* Minimum size for the output of nicenum, including NULL */ +#define NN_NUMBUF_SZ (6) + +void nicenum(uint64_t, char *, size_t); +void nicenum_scale(uint64_t, size_t, char *, size_t, uint32_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBCMDUTILS_H */ diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf.5 b/cddl/contrib/opensolaris/lib/libctf/common/ctf.5 index 316e97872c07..5a90b0ef3121 100644 --- a/cddl/contrib/opensolaris/lib/libctf/common/ctf.5 +++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf.5 @@ -39,7 +39,8 @@ data contained in each file has information about the layout and sizes of C types, including intrinsic types, enumerations, structures, typedefs, and unions, that are used by the corresponding .Sy ELF -object. The +object. +The .Nm data may also include information about the types of global objects and the return type and arguments of functions in the symbol table. @@ -51,41 +52,43 @@ file itself, it may also be referred to as a .Nm .Sy container . .Lp -On illumos systems, +On +.Fx +systems, .Nm -data is consumed by multiple programs. It can be used by the modular -debugger, -.Xr mdb 1 , -as well as by -.Xr dtrace 1M . +data is consumed by +.Xr dtrace 1 . Programmatic access to .Nm -data can be obtained through -.Xr libctf 3LIB . +data can be obtained through libctf. .Lp The .Nm -file format is broken down into seven different sections. The first -section is the +file format is broken down into seven different sections. +The first section is the .Sy preamble and .Sy header , which describes the version of the .Nm -file, links it has to other +file, the links it has to other .Nm -files, and the sizes of the other sections. The next section is the +files, and the sizes of the other sections. +The next section is the .Sy label section, which provides a way of identifying similar groups of .Nm -data across multiple files. This is followed by the +data across multiple files. +This is followed by the .Sy object -information section, which describes the type of global -symbols. The subsequent section is the +information section, which describes the types of global +symbols. +The subsequent section is the .Sy function information section, which describes the return -types and arguments of functions. The next section is the +types and arguments of functions. +The next section is the .Sy type information section, which describes the format and layout of the C types themselves, and finally the last @@ -106,29 +109,35 @@ A file may contain all of the type information that it requires, or it may optionally refer to another .Nm -file which holds the remaining types. When a +file which holds the remaining types. +When a .Nm file refers to another file, it is called the .Sy child and the file it refers to is called the .Sy parent . -A given file may only refer to one parent. This process is called +A given file may only refer to one parent. +This process is called .Em uniquification because it ensures each child only has type information that is -unique to it. A common example of this is that most kernel modules in -illumos are uniquified against the kernel module +unique to it. +A common example of this is that most kernel modules in illumos are uniquified +against the kernel module .Sy genunix and the type information that comes from the .Sy IP -module. This means that a module only has types that are unique to -itself and the most common types in the kernel are not duplicated. +module. +This means that a module only has types that are unique to itself and the most +common types in the kernel are not duplicated. .Sh FILE FORMAT This documents version .Em two of the .Nm -file format. All applications and tools currently produce and operate on -this version. +file format. +All applications and tools on +.Fx +currently produce and operate on this version. .Lp The file format can be summarized with the following image, the following sections will cover this in more detail. @@ -235,26 +244,31 @@ This .Sy preamble defines the version of the .Nm -file which defines the format of the rest of the header. While the -header may change in subsequent versions, the preamble will not change +file which defines the format of the rest of the header. +While the header may change in subsequent versions, the preamble will not change across versions, though the interpretation of its flags may change from -version to version. The +version to version. +The .Em ctp_magic member defines the magic number for the .Nm -file format. This must always be +file format. +This must always be .Li 0xcff1 . If another value is encountered, then the file should not be treated as a .Nm -file. The +file. +The .Em ctp_version member defines the version of the .Nm -file. The current version is +file. +The current version is .Li 2 . -It is possible to encounter an unsupported version. In that case, -software should not try to parse the format, as it may have changed. +It is possible to encounter an unsupported version. +In that case, software should not try to parse the format, as it may have +changed. Finally, the .Em ctp_flags member describes aspects of the file which modify its interpretation. @@ -273,9 +287,10 @@ has been compressed through the .Sy zlib library and its .Sy deflate -algorithm. If this flag is not present, then the body has not been -compressed and no special action is needed to interpret it. All offsets -into the data as described by +algorithm. +If this flag is not present, then the body has not been compressed and no +special action is needed to interpret it. +All offsets into the data as described by .Sy header , always refer to the .Sy uncompressed @@ -285,13 +300,13 @@ In version two of the .Nm file format, the .Sy header -denotes whether whether or not this +denotes whether or not this .Nm file is the child of another .Nm -file and also indicates the size of the remaining sections. The -structure for the -.Sy header , +file and also indicates the size of the remaining sections. +The structure for the +.Sy header logically contains a copy of the .Sy preamble and the two have a combined size of 36 bytes. @@ -315,37 +330,40 @@ the next two members .Em cth_parlablel and .Em cth_parname , -are used to identify the parent. The value of both members are offsets -into the +are used to identify the parent. +The value of both members are offsets into the .Sy string -section which point to the start of a null-terminated string. For more -information on the encoding of strings, see the subsection on +section which point to the start of a null-terminated string. +For more information on the encoding of strings, see the subsection on .Sx String Identifiers . If the value of either is zero, then there is no entry for that -member. If the member +member. +If the member .Em cth_parlabel is set, then the .Em ctf_parname member must be set, otherwise it will not be possible to find the -parent. If +parent. +If .Em ctf_parname is set, it is not necessary to define .Em cth_parlabel , -as the parent may not have a label. For more information on labels -and their interpretation, see +as the parent may not have a label. +For more information on labels and their interpretation, see .Sx The Label Section . .Lp The remaining members (excepting .Em cth_strlen ) -describe the beginning of the corresponding sections. These offsets are -relative to the end of the +describe the beginning of the corresponding sections. +These offsets are relative to the end of the .Sy header . Therefore, something with an offset of 0 is at an offset of thirty-six bytes relative to the start of the .Nm -file. The difference between members -indicates the size of the section itself. Different offsets have -different alignment requirements. The start of the +file. +The difference between members indicates the size of the section itself. +Different offsets have different alignment requirements. +The start of the .Em cth_objotoff and .Em cth_funcoff @@ -353,13 +371,14 @@ must be two byte aligned, while the sections .Em cth_lbloff and .Em cth_typeoff -must be four-byte aligned. The section +must be four-byte aligned. +The section .Em cth_stroff -has no alignment requirements. To calculate the size of a given section, -excepting the +has no alignment requirements. +To calculate the size of a given section, excepting the .Sy string -section, one should subtract the offset of the section from the following one. For -example, the size of the +section, one should subtract the offset of the section from the following one. +For example, the size of the .Sy types section can be calculated by subtracting .Em cth_stroff @@ -368,8 +387,8 @@ from .Lp Finally, the member .Em cth_strlen -describes the length of the string section itself. From it, you can also -calculate the size of the entire +describes the length of the string section itself. +From it, you can also calculate the size of the entire .Nm file by adding together the size of the .Sy ctf_header_t , @@ -380,9 +399,11 @@ and the size of the string section in .Ss Type Identifiers Through the .Nm ctf -data, types are referred to by identifiers. A given +data, types are referred to by identifiers. +A given .Nm -file supports up to 32767 (0x7fff) types. The first valid type identifier is 0x1. +file supports up to 32767 (0x7fff) types. +The first valid type identifier is 0x1. When a given .Nm file is a child, indicated by a non-zero entry for the @@ -403,18 +424,20 @@ Other consumers of information may use larger or opaque identifiers. .Ss String Identifiers String identifiers are always encoded as four byte unsigned integers -which are an offset into a string table. The +which are an offset into a string table. +The .Nm format supports two different string tables which have an identifier of -zero or one. This identifier is stored in the high-order bit of the -unsigned four byte offset. Therefore, the maximum supported offset into -one of these tables is 0x7ffffffff. +zero or one. +This identifier is stored in the high-order bit of the unsigned four byte +offset. +Therefore, the maximum supported offset into one of these tables is 0x7ffffffff. .Lp Table identifier zero, always refers to the .Sy string -section in the CTF file itself. String table identifier one refers to an -external string table which is the ELF string table for the ELF symbol -table associated with the +section in the CTF file itself. +String table identifier one refers to an external string table which is the ELF +string table for the ELF symbol table associated with the .Nm container. .Ss Type Encoding @@ -434,8 +457,8 @@ The length of the variable data .Lp The 16 bits that make up the encoding are broken down such that you have five bits for the kind, one bit for indicating whether or not it is a -root type, and 10 bits for the variable length. This is laid out as -follows: +root type, and 10 bits for the variable length. +This is laid out as follows: .Bd -literal -offset indent +--------------------+ | kind | root | vlen | @@ -443,12 +466,13 @@ follows: 15 11 10 9 0 .Ed .Lp -The current version of the file format defines 14 different kinds. The -interpretation of these different kinds will be discussed in the section +The current version of the file format defines 14 different kinds. +The interpretation of these different kinds will be discussed in the section .Sx The Type Section . If a kind is encountered that is not listed below, then it is not a valid .Nm -file. The kinds are defined as follows: +file. +The kinds are defined as follows: .Bd -literal -offset indent #define CTF_K_UNKNOWN 0 #define CTF_K_INTEGER 1 @@ -467,14 +491,16 @@ file. The kinds are defined as follows: .Ed .Lp Programs directly reference many types; however, other types are referenced -indirectly because they are part of some other structure. These types that are -referenced directly and used are called +indirectly because they are part of some other structure. +These types that are referenced directly and used are called .Sy root -types. Other types may be used indirectly, for example, a program may reference -a structure directly, but not one of its members which has a type. That type is -not considered a +types. +Other types may be used indirectly, for example, a program may reference +a structure directly, but not one of its members which has a type. +That type is not considered a .Sy root -type. If a type is a +type. +If a type is a .Sy root type, then it will have bit 10 set. .Lp @@ -499,16 +525,17 @@ When consuming .Nm data, it is often useful to know whether two different .Nm -containers come from the same source base and version. For example, when -building illumos, there are many kernel modules that are built against a -single collection of source code. A label is encoded into the +containers come from the same source base and version. +For example, when building illumos, there are many kernel modules that are built +against a single collection of source code. +A label is encoded into the .Nm -files that corresponds with the particular build. This ensures that if -files on the system were to become mixed up from multiple releases, that -they are not used together by tools, particularly when a child needs to -refer to a type in the parent. Because they are linked used the type -identifiers, if the wrong parent is used then the wrong type will be -encountered. +files that corresponds with the particular build. +This ensures that if files on the system were to become mixed up from multiple +releases, that they are not used together by tools, particularly when a child +needs to refer to a type in the parent. +Because they are linked using the type identifiers, if the wrong parent is used +then the wrong type will be encountered. .Lp Each label is encoded in the file format using the following eight byte structure: @@ -530,21 +557,22 @@ section. The type identifier encoded in the member .Em ctl_typeidx refers to the last type identifier that a label refers to in the current -file. Labels only refer to types in the current file, if the +file. +Labels only refer to types in the current file, if the .Nm file is a child, then it will have the same label as its parent; -however, its label will only refer to its types, not its parents. +however, its label will only refer to its types, not its parent's. .Lp It is also possible, though rather uncommon, for a .Nm -file to have multiple labels. Labels are placed one after another, every -eight bytes. When multiple labels are present, types may only belong to -a single label. +file to have multiple labels. +Labels are placed one after another, every eight bytes. +When multiple labels are present, types may only belong to a single label. .Ss The Object Section The object section provides a mapping from ELF symbols of type .Sy STT_OBJECT -in the symbol table to a type identifier. Every entry in this section is -a +in the symbol table to a type identifier. +Every entry in this section is a .Sy uint16_t which contains a type identifier as described in the section .Sx Type Identifiers . @@ -555,9 +583,10 @@ To walk the object section, you need to have a corresponding .Sy symbol table in the ELF object that contains the .Nm -data. Not every object is included in this section. Specifically, when -walking the symbol table. An entry is skipped if it matches any of the -following conditions: +data. +Not every object is included in this section. +Specifically, when walking the symbol table, an entry is skipped if it matches +any of the following conditions: .Lp .Bl -bullet -offset indent -compact .It @@ -628,40 +657,45 @@ walk_symbols(uint16_t *objtoff, Elf_Data *symdata, Elf_Data *strdata, The function section of the .Nm file encodes the types of both the function's arguments and the function's -return type. Similar to +return value. +Similar to .Sx The Object Section , the function section encodes information for all symbols of type .Sy STT_FUNCTION , -excepting those that fit specific criteria. Unlike with objects, because -functions have a variable number of arguments, they start with a type encoding -as defined in +excepting those that fit specific criteria. +Unlike with objects, because functions have a variable number of arguments, they +start with a type encoding as defined in .Sx Type Encoding , which is the size of a .Sy uint16_t . For functions which have no type information available, they are encoded as .Li CTF_TYPE_INFO(CTF_K_UNKNOWN, 0, 0) . -Functions with arguments are encoded differently. Here, the variable length is -turned into the number of arguments in the function. If a function is a +Functions with arguments are encoded differently. +Here, the variable length is turned into the number of arguments in the +function. +If a function is a .Sy varargs -type function, then the number of arguments is increased by one. Functions with -type information are encoded as: +type function, then the number of arguments is increased by one. +Functions with type information are encoded as: .Li CTF_TYPE_INFO(CTF_K_FUNCTION, 0, nargs) . .Lp For functions that have no type information, nothing else is encoded, and the -next function is encoded. For functions with type information, the next +next function is encoded. +For functions with type information, the next .Sy uint16_t -is encoded with the type identifier of the return type of the function. It is -followed by each of the type identifiers of the arguments, if any exist, in the -order that they appear in the function. Therefore, argument 0 is the first type -identifier and so on. When a function has a final varargs argument, that is -encoded with the type identifier of zero. +is encoded with the type identifier of the return type of the function. +It is followed by each of the type identifiers of the arguments, if any exist, +in the order that they appear in the function. +Therefore, argument 0 is the first type identifier and so on. +When a function has a final varargs argument, that is encoded with the type +identifier of zero. .Lp Like .Sx The Object Section , -the function section is encoded in the order of the symbol table. It has -similar, but slightly different considerations from objects. While iterating the -symbol table, if any of the following conditions are true, then the entry is -skipped and no corresponding entry is written: +the function section is encoded in the order of the symbol table. +It has similar, but slightly different considerations from objects. +While iterating the symbol table, if any of the following conditions are true, +then the entry is skipped and no corresponding entry is written: .Lp .Bl -bullet -offset indent -compact .It @@ -683,10 +717,11 @@ ELF. .Ss The Type Section The type section is the heart of the .Nm -data. It encodes all of the information about the types themselves. The base of -the type information comes in two forms, a short form and a long form, each of -which may be followed by a variable number of arguments. The following -definitions describe the short and long forms: +data. +It encodes all of the information about the types themselves. +The base of the type information comes in two forms, a short form and a long +form, each of which may be followed by a variable number of arguments. +The following definitions describe the short and long forms: .Bd -literal #define CTF_MAX_SIZE 0xfffe /* max size of a type in bytes */ #define CTF_LSIZE_SENT 0xffff /* sentinel for ctt_size */ @@ -720,14 +755,17 @@ Type sizes are stored in .Sy bytes . The basic small form uses a .Sy ushort_t -to store the number of bytes. If the number of bytes in a structure would exceed -0xfffe, then the alternate form, the +to store the number of bytes. +If the number of bytes in a structure would exceed 0xfffe, then the alternate +form, the .Sy ctf_type_t , -is used instead. To indicate that the larger form is being used, the member +is used instead. +To indicate that the larger form is being used, the member .Em ctt_size is set to value of .Sy CTF_LSIZE_SENT -(0xffff). In general, when going through the type section, consumers use the +(0xffff). +In general, when going through the type section, consumers use the .Sy ctf_type_t structure, but pay attention to the value of the member .Em ctt_size @@ -739,36 +777,43 @@ Not all kinds of types use .Sy ctt_size . Those which do not, will always use the .Sy ctf_stype_t -structure. The individual sections for each kind have more information. +structure. +The individual sections for each kind have more information. .Lp -Types are written out in order. Therefore the first entry encountered has a type -id of 0x1, or 0x8000 if a child. The member +Types are written out in order. +Therefore the first entry encountered has a type id of 0x1, or 0x8000 if a +child. +The member .Em ctt_name is encoded as described in the section .Sx String Identifiers . -The string that it points to is the name of the type. If the identifier points -to an empty string (one that consists solely of a null terminator) then the type -does not have a name, this is common with anonymous structures and unions that -only have a typedef to name them, as well as, pointers and qualifiers. +The string that it points to is the name of the type. +If the identifier points to an empty string (one that consists solely of a null +terminator) then the type does not have a name, this is common with anonymous +structures and unions that only have a typedef to name them, as well as +pointers and qualifiers. .Lp The next member, the .Em ctt_info , is encoded as described in the section .Sx Type Encoding . -The types kind tells us how to interpret the remaining data in the +The type's kind tells us how to interpret the remaining data in the .Sy ctf_type_t -and any variable length data that may exist. The rest of this section will be -broken down into the interpretation of the various kinds. +and any variable length data that may exist. +The rest of this section will be broken down into the interpretation of the +various kinds. .Ss Encoding of Integers Integers, which are of type .Sy CTF_K_INTEGER , -have no variable length arguments. Instead, they are followed by a four byte +have no variable length arguments. +Instead, they are followed by a four byte .Sy uint_t -which describes their encoding. All integers must be encoded with a variable -length of zero. The +which describes their encoding. +All integers must be encoded with a variable length of zero. +The .Em ctt_size -member describes the length of the integer in bytes. In general, integer sizes -will be rounded up to the closest power of two. +member describes the length of the integer in bytes. +In general, integer sizes will be rounded up to the closest power of two. .Lp The integer encoding contains three different pieces of information: .Bl -bullet -offset indent -compact @@ -804,33 +849,37 @@ The following flags are defined for the encoding at this time: .Lp By default, an integer is considered to be unsigned, unless it has the .Sy CTF_INT_SIGNED -flag set. If the flag +flag set. +If the flag .Sy CTF_INT_CHAR is set, that indicates that the integer is of a type that stores character data, for example the intrinsic C type .Sy char would have the .Sy CTF_INT_CHAR -flag set. If the flag +flag set. +If the flag .Sy CTF_INT_BOOL -is set, that indicates that the integer represents a boolean type. For example, -the intrinsic C type +is set, that indicates that the integer represents a boolean type. +For example, the intrinsic C type .Sy _Bool would have the .Sy CTF_INT_BOOL -flag set. Finally, the flag +flag set. +Finally, the flag .Sy CTF_INT_VARARGS indicates that the integer is used as part of a variable number of arguments. This encoding is rather uncommon. .Ss Encoding of Floats Floats, which are of type .Sy CTF_K_FLOAT , -are similar to their integer counterparts. They have no variable length -arguments and are followed by a four byte encoding which describes the kind of -float that exists. The +are similar to their integer counterparts. +They have no variable length arguments and are followed by a four byte encoding +which describes the kind of float that exists. +The .Em ctt_size -member is the size, in bytes, of the float. The float encoding has three -different pieces of information inside of it: +member is the size, in bytes, of the float. +The float encoding has three different pieces of information inside of it: .Lp .Bl -bullet -offset indent -compact .It @@ -855,11 +904,12 @@ This encoding can be expressed through the following macros: (((encoding) << 24) | ((offset) << 16) | (bits)) .Ed .Lp -Where as the encoding for integers was a series of flags, the encoding for -floats maps to a specific kind of float. It is not a flag-based value. The kinds of floats -correspond to both their size, and the encoding. This covers all of the basic C -intrinsic floating point types. The following are the different kinds of floats -represented in the encoding: +Where as the encoding for integers is a series of flags, the encoding for +floats maps to a specific kind of float. +It is not a flag-based value. +The kinds of floats correspond to both their size, and the encoding. +This covers all of the basic C intrinsic floating point types. +The following are the different kinds of floats represented in the encoding: .Bd -literal -offset indent #define CTF_FP_SINGLE 1 /* IEEE 32-bit float encoding */ #define CTF_FP_DOUBLE 2 /* IEEE 64-bit float encoding */ @@ -877,12 +927,14 @@ represented in the encoding: .Ss Encoding of Arrays Arrays, which are of type .Sy CTF_K_ARRAY , -have no variable length arguments. They are followed by a structure which -describes the number of elements in the array, the type identifier of the -elements in the array, and the type identifier of the index of the array. With -arrays, the +have no variable length arguments. +They are followed by a structure which describes the number of elements in the +array, the type identifier of the elements in the array, and the type identifier +of the index of the array. +With arrays, the .Em ctt_size -member is set to zero. The structure that follows an array is defined as: +member is set to zero. +The structure that follows an array is defined as: .Bd -literal typedef struct ctf_array { ushort_t cta_contents; /* reference to type of array contents */ @@ -901,14 +953,15 @@ are type identifiers which are encoded as per the section .Sx Type Identifiers . The member .Em cta_nelems -is a simple four byte unsigned count of the number of elements. This count may -be zero when encountering C99's flexible array members. +is a simple four byte unsigned count of the number of elements. +This count may be zero when encountering C99's flexible array members. .Ss Encoding of Functions Function types, which are of type .Sy CTF_K_FUNCTION , -use the variable length list to be the number of arguments in the function. When -the function has a final member which is a varargs, then the argument count is -incremented by one to account for the variable argument. Here, the +use the variable length list to be the number of arguments in the function. +When the function has a final member which is a varargs, then the argument count +is incremented by one to account for the variable argument. +Here, the .Em ctt_type member is encoded with the type identifier of the return type of the function. Note that the @@ -916,31 +969,40 @@ Note that the member is not used here. .Lp The variable argument list contains the type identifiers for the arguments of -the function, if any. Each one is represented by a +the function, if any. +Each one is represented by a .Sy uint16_t and encoded according to the .Sx Type Identifiers -section. If the function's last argument is of type varargs, then it is also -written out, but the type identifier is zero. This is included in the count of -the function's arguments. +section. +If the function's last argument is of type varargs, then it is also written out, +but the type identifier is zero. +This is included in the count of the function's arguments. +An extra type identifier may follow the argument and return type identifiers +in order to maintain four-byte alignment for the following type definition. +Such a type identifier is not included in the argument count and has a value +of zero. .Ss Encoding of Structures and Unions Structures and Unions, which are encoded with .Sy CTF_K_STRUCT and .Sy CTF_K_UNION -respectively, are very similar constructs in C. The main difference -between them is the fact that every member of a structure follows one another, -where as in a union, all members share the same memory. They are also very -similar in terms of their encoding in +respectively, are very similar constructs in C. +The main difference between them is the fact that members of a structure +follow one another, where as in a union, all members share the same memory. +They are also very similar in terms of their encoding in .Nm . The variable length argument for structures and unions represents the number of -members that they have. The value of the member +members that they have. +The value of the member .Em ctt_size -is the size of the structure and union. There are two different structures which -are used to encode members in the variable list. When the size of a structure or -union is greater than or equal to the large member threshold, 8192, then a -different structure is used to encode the member, all members are encoded using -the same structure. The structure for members is as follows: +is the size of the structure and union. +There are two different structures which are used to encode members in the +variable list. +When the size of a structure or union is greater than or equal to the large +member threshold, 8192, then a different structure is used to encode the member, +all members are encoded using the same structure. +The structure for members is as follows: .Bd -literal typedef struct ctf_member { uint_t ctm_name; /* reference to name in string table */ @@ -961,54 +1023,66 @@ Both the .Em ctm_name and .Em ctlm_name -refer to the name of the member. The name is encoded as an offset into the -string table as described by the section +refer to the name of the member. +The name is encoded as an offset into the string table as described by the +section .Sx String Identifiers . The members .Sy ctm_type and .Sy ctlm_type -both refer to the type of the member. They are encoded as per the section +both refer to the type of the member. +They are encoded as per the section .Sx Type Identifiers . .Lp The last piece of information that is present is the offset which describes the -offset in memory that the member begins at. For unions, this value will always -be zero because the start of unions in memory is always zero. For structures, -this is the offset in +offset in memory at which the member begins. +For unions, this value will always be zero because each member of a union has +an offset of zero. +For structures, this is the offset in .Sy bits -that the member begins at. Note that a compiler may lay out a type with padding. +at which the member begins. +Note that a compiler may lay out a type with padding. This means that the difference in offset between two consecutive members may be -larger than the size of the member. When the size of the overall structure is -strictly less than 8192 bytes, the normal structure, +larger than the size of the member. +When the size of the overall structure is strictly less than 8192 bytes, the +normal structure, .Sy ctf_member_t , is used and the offset in bits is stored in the member .Em ctm_offset . However, when the size of the structure is greater than or equal to 8192 bytes, -then the number of bits is split into two 32-bit quantities. One member, +then the number of bits is split into two 32-bit quantities. +One member, .Em ctlm_offsethi , represents the upper 32 bits of the offset, while the other member, .Em ctlm_offsetlo , -represents the lower 32 bits of the offset. These can be joined together to get -a 64-bit sized offset in bits by shifting the member +represents the lower 32 bits of the offset. +These can be joined together to get a 64-bit sized offset in bits by shifting +the member .Em ctlm_offsethi to the left by thirty two and then doing a binary or of .Em ctlm_offsetlo . .Ss Encoding of Enumerations Enumerations, noted by the type .Sy CTF_K_ENUM , -are similar to structures. Enumerations use the variable list to note the number -of values that the enumeration contains, which we'll term enumerators. In C, an -enumeration is always equivalent to the intrinsic type +are similar to structures. +Enumerations use the variable list to note the number of values that the +enumeration contains, which we'll term enumerators. +In C, an enumeration is always equivalent to the intrinsic type .Sy int , thus the value of the member .Em ctt_size is always the size of an integer which is determined based on the current model. -For illumos systems, this will always be 4, as an integer is always defined to +For +.Fx +systems, this will always be 4, as an integer is always defined to be 4 bytes large in both .Sy ILP32 and .Sy LP64 , regardless of the architecture. +For further details, see +.Xr arch 7 . .Lp The enumerators encoded in an enumeration have the following structure in the variable list: @@ -1032,25 +1106,27 @@ Forward references, types of kind .Sy CTF_K_FORWARD , in a .Nm -file refer to types which may not have a definition at all, only a name. If -the +file refer to types which may not have a definition at all, only a name. +If the .Nm file is a child, then it may be that the forward is resolved to an actual type in the parent, otherwise the definition may be in another .Nm -container or may not be known at all. The only member of the +container or may not be known at all. +The only member of the .Sy ctf_type_t that matters for a forward declaration is the .Em ctt_name which points to the name of the forward reference in the string table as -described earlier. There is no other information recorded for forward -references. +described earlier. +There is no other information recorded for forward references. .Ss Encoding of Pointers, Typedefs, Volatile, Const, and Restrict Pointers, typedefs, volatile, const, and restrict are all similar in .Nm . -They all refer to another type. In the case of typedefs, they provide an -alternate name, while volatile, const, and restrict change how the type is -interpreted in the C programming language. This covers the +They all refer to another type. +In the case of typedefs, they provide an alternate name, while volatile, const, +and restrict change how the type is interpreted in the C programming language. +This covers the .Nm kinds .Sy CTF_K_POINTER , @@ -1066,43 +1142,49 @@ to refer to the base type that they modify. .Ss Encoding of Unknown Types Types with the kind .Sy CTF_K_UNKNOWN -are used to indicate gaps in the type identifier space. These entries consume an -identifier, but do not define anything. Nothing should refer to these gap -identifiers. +are used to indicate gaps in the type identifier space. +These entries consume an identifier, but do not define anything. +Nothing should refer to these gap identifiers. .Ss Dependencies Between Types -C types can be imagined as a directed, cyclic, graph. Structures and unions may -refer to each other in a way that creates a cyclic dependency. In cases such as -these, the entire type section must be read in and processed. Consumers must -not assume that every type can be laid out in dependency order; they -cannot. +C types can be imagined as a directed, cyclic, graph. +Structures and unions may refer to each other in a way that creates a cyclic +dependency. +In cases such as these, the entire type section must be read in and processed. +Consumers must not assume that every type can be laid out in dependency order; +they cannot. .Ss The String Section The last section of the .Nm file is the .Sy string -section. This section encodes all of the strings that appear throughout -the other sections. It is laid out as a series of characters followed by -a null terminator. Generally, all names are written out in ASCII, as -most C compilers do not allow and characters to appear in identifiers -outside of a subset of ASCII. However, any extended characters sets -should be written out as a series of UTF-8 bytes. +section. +This section encodes all of the strings that appear throughout the other +sections. +It is laid out as a series of characters followed by a null terminator. +Generally, all names are written out in ASCII, as most C compilers do not allow +any characters to appear in identifiers outside of a subset of ASCII. +However, any extended characters sets should be written out as a series of UTF-8 +bytes. .Lp The first entry in the section, at offset zero, is a single null -terminator to reference the empty string. Following that, each C string -should be written out, including the null terminator. Offsets that refer -to something in this section should refer to the first byte which begins -a string. Beyond the first byte in the section being the null -terminator, the order of strings is unimportant. +terminator to reference the empty string. +Following that, each C string should be written out, including the null +terminator. +Offsets that refer to something in this section should refer to the first byte +which begins a string. +Beyond the first byte in the section being the null terminator, the order of +strings is unimportant. .Ss Data Encoding and ELF Considerations .Nm data is generally included in ELF objects which specify information to -identify the architecture and endianness of the file. A +identify the architecture and endianness of the file. +A .Nm -container inside such an object must match the endianness of the ELF -object. Aside from the question of the endian encoding of data, there -should be no other differences between architectures. While many of the -types in this document refer to non-fixed size C integral types, they -are equivalent in the models +container inside such an object must match the endianness of the ELF object. +Aside from the question of the endian encoding of data, there should be no other +differences between architectures. +While many of the types in this document refer to non-fixed size C integral +types, they are equivalent in the models .Sy ILP32 and .Sy LP64 . @@ -1118,15 +1200,16 @@ When placing a container inside of an ELF object, there are certain conventions that are expected for the purposes of tooling being able to find the .Nm -data. In particular, a given ELF object should only contain a single +data. +In particular, a given ELF object should only contain a single .Nm -section. Multiple containers should be merged together into a single -one. +section. +Multiple containers should be merged together into a single one. .Lp The .Nm -file should be included in its own ELF section. The section's name -must be +file should be included in its own ELF section. +The section's name must be .Ql .SUNW_ctf . The type of the section must be .Sy SHT_PROGBITS . @@ -1137,4 +1220,5 @@ alignment must be 4. .Xr elf 3 , .Xr gelf 3 , .Xr a.out 5 , -.Xr elf 5 +.Xr elf 5 , +.Xr arch 7 diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c index 0c41bda0aac9..d1335180ec97 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c @@ -434,7 +434,7 @@ dt_dis(const dtrace_difo_t *dp, FILE *fp) ulong_t i = 0; char type[DT_TYPE_NAMELEN]; - (void) fprintf(fp, "\nDIFO 0x%p returns %s\n", (void *)dp, + (void) fprintf(fp, "\nDIFO %p returns %s\n", (void *)dp, dt_dis_typestr(&dp->dtdo_rtype, type, sizeof (type))); (void) fprintf(fp, "%-3s %-8s %s\n", diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index bfd5ec15cc9e..e5d30f0e037d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -229,10 +229,12 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep) for (j = 0; j < nrel; j++) { #if defined(__aarch64__) /* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): aarch64 not implemented\n", + __FUNCTION__, __FILE__, __LINE__); #elif defined(__arm__) /* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): arm not implemented\n", + __FUNCTION__, __FILE__, __LINE__); #elif defined(__i386) || defined(__amd64) rel->r_offset = s->dofs_offset + dofr[j].dofr_offset; @@ -240,7 +242,8 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); R_386_PC32); #elif defined(__mips__) /* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): MIPS not implemented\n", + __FUNCTION__, __FILE__, __LINE__); #elif defined(__powerpc__) /* * Add 4 bytes to hit the low half of this 64-bit @@ -252,7 +255,8 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); R_PPC_REL32); #elif defined(__riscv) /* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): RISC-V not implemented\n", + __FUNCTION__, __FILE__, __LINE__); #else #error unknown ISA #endif @@ -802,7 +806,8 @@ static int dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): aarch64 not implemented\n", __FUNCTION__, __FILE__, + __LINE__); return (0); } #elif defined(__arm__) @@ -811,7 +816,8 @@ static int dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): arm not implemented\n", __FUNCTION__, __FILE__, + __LINE__); return (0); } #elif defined(__mips__) @@ -820,7 +826,8 @@ static int dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): MIPS not implemented\n", __FUNCTION__, __FILE__, + __LINE__); return (0); } #elif defined(__powerpc__) @@ -910,7 +917,8 @@ static int dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): RISC-V implementation required\n", __FUNCTION__, + __FILE__, __LINE__); return (0); } #elif defined(__sparc) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c index 4be0f03d4a43..0a3a10a76954 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c @@ -377,7 +377,7 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap) ctf_id_t rtype; if (ctf_array_info(ctfp, base, &car) == CTF_ERR) { - (void) fprintf(fp, "0x%p", (void *)addr); + (void) fprintf(fp, "%p", (void *)addr); return; } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c index 79c187140de9..9215b438a40f 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c @@ -426,7 +426,8 @@ dt_proc_attach(dt_proc_t *dpr, int exec) static void dt_proc_waitrun(dt_proc_t *dpr) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); + printf("%s:%s(%d): not implemented\n", __FUNCTION__, __FILE__, + __LINE__); #ifdef DOODAD struct ps_prochandle *P = dpr->dpr_proc; const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index de78b5479240..d77667d19877 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2013 Martin Matuska. All rights reserved. @@ -2166,6 +2166,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, if (zfs_prop_readonly(prop) && *source != NULL && (*source)[0] == '\0') { *source = NULL; + return (-1); } break; @@ -2354,6 +2355,74 @@ zfs_get_clones_nvl(zfs_handle_t *zhp) return (value); } +/* + * Accepts a property and value and checks that the value + * matches the one found by the channel program. If they are + * not equal, print both of them. + */ +void +zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval, + const char *strval) +{ + if (!zhp->zfs_hdl->libzfs_prop_debug) + return; + int error; + char *poolname = zhp->zpool_hdl->zpool_name; + const char *program = + "args = ...\n" + "ds = args['dataset']\n" + "prop = args['property']\n" + "value, setpoint = zfs.get_prop(ds, prop)\n" + "return {value=value, setpoint=setpoint}\n"; + nvlist_t *outnvl; + nvlist_t *retnvl; + nvlist_t *argnvl = fnvlist_alloc(); + + fnvlist_add_string(argnvl, "dataset", zhp->zfs_name); + fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop)); + + error = lzc_channel_program(poolname, program, + 10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl); + + if (error == 0) { + retnvl = fnvlist_lookup_nvlist(outnvl, "return"); + if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) { + int64_t ans; + error = nvlist_lookup_int64(retnvl, "value", &ans); + if (error != 0) { + (void) fprintf(stderr, "zcp check error: %u\n", + error); + return; + } + if (ans != intval) { + (void) fprintf(stderr, + "%s: zfs found %lld, but zcp found %lld\n", + zfs_prop_to_name(prop), + (longlong_t)intval, (longlong_t)ans); + } + } else { + char *str_ans; + error = nvlist_lookup_string(retnvl, "value", &str_ans); + if (error != 0) { + (void) fprintf(stderr, "zcp check error: %u\n", + error); + return; + } + if (strcmp(strval, str_ans) != 0) { + (void) fprintf(stderr, + "%s: zfs found %s, but zcp found %s\n", + zfs_prop_to_name(prop), + strval, str_ans); + } + } + } else { + (void) fprintf(stderr, + "zcp check failed, channel program error: %u\n", error); + } + nvlist_free(argnvl); + nvlist_free(outnvl); +} + /* * Retrieve a property from the given object. If 'literal' is specified, then * numbers are left as exact values. Otherwise, numbers are converted to a @@ -2400,6 +2469,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, &t) == 0) (void) snprintf(propbuf, proplen, "%llu", val); } + zcp_check(zhp, prop, val, NULL); break; case ZFS_PROP_MOUNTPOINT: @@ -2468,7 +2538,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, /* 'legacy' or 'none' */ (void) strlcpy(propbuf, str, proplen); } - + zcp_check(zhp, prop, NULL, propbuf); break; case ZFS_PROP_ORIGIN: @@ -2476,6 +2546,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (str == NULL) return (-1); (void) strlcpy(propbuf, str, proplen); + zcp_check(zhp, prop, NULL, str); break; case ZFS_PROP_CLONES: @@ -2490,7 +2561,6 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (get_numeric_property(zhp, prop, src, &source, &val) != 0) return (-1); - /* * If quota or reservation is 0, we translate this into 'none' * (unless literal is set), and indicate that it's the default @@ -2509,6 +2579,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, else zfs_nicenum(val, propbuf, proplen); } + zcp_check(zhp, prop, val, NULL); break; case ZFS_PROP_FILESYSTEM_LIMIT: @@ -2533,6 +2604,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, } else { zfs_nicenum(val, propbuf, proplen); } + + zcp_check(zhp, prop, val, NULL); break; case ZFS_PROP_REFRATIO: @@ -2542,6 +2615,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, (void) snprintf(propbuf, proplen, "%llu.%02llux", (u_longlong_t)(val / 100), (u_longlong_t)(val % 100)); + zcp_check(zhp, prop, val, NULL); break; case ZFS_PROP_TYPE: @@ -2562,6 +2636,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, abort(); } (void) snprintf(propbuf, proplen, "%s", str); + zcp_check(zhp, prop, NULL, propbuf); break; case ZFS_PROP_MOUNTED: @@ -2587,6 +2662,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, * consumers. */ (void) strlcpy(propbuf, zhp->zfs_name, proplen); + zcp_check(zhp, prop, NULL, propbuf); break; case ZFS_PROP_MLSLABEL: @@ -2640,26 +2716,33 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (get_numeric_property(zhp, prop, src, &source, &val) != 0) return (-1); (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val); + zcp_check(zhp, prop, val, NULL); break; default: switch (zfs_prop_get_type(prop)) { case PROP_TYPE_NUMBER: if (get_numeric_property(zhp, prop, src, - &source, &val) != 0) + &source, &val) != 0) { return (-1); - if (literal) + } + + if (literal) { (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val); - else + } else { zfs_nicenum(val, propbuf, proplen); + } + zcp_check(zhp, prop, val, NULL); break; case PROP_TYPE_STRING: str = getprop_string(zhp, prop, &source); if (str == NULL) return (-1); + (void) strlcpy(propbuf, str, proplen); + zcp_check(zhp, prop, NULL, str); break; case PROP_TYPE_INDEX: @@ -2668,7 +2751,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, return (-1); if (zfs_prop_index_to_string(prop, val, &strval) != 0) return (-1); + (void) strlcpy(propbuf, strval, proplen); + zcp_check(zhp, prop, NULL, strval); break; default: diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c index 1447b4cb7a11..840c814ff4c0 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c @@ -55,15 +55,6 @@ #define ZDIFF_REMOVED '-' #define ZDIFF_RENAMED 'R' -static boolean_t -do_name_cmp(const char *fpath, const char *tpath) -{ - char *fname, *tname; - fname = strrchr(fpath, '/') + 1; - tname = strrchr(tpath, '/') + 1; - return (strcmp(fname, tname) == 0); -} - typedef struct differ_info { zfs_handle_t *zhp; char *fromsnap; @@ -262,7 +253,6 @@ static int write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) { struct zfs_stat fsb, tsb; - boolean_t same_name; mode_t fmode, tmode; char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN]; int fobjerr, tobjerr; @@ -323,7 +313,6 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) if (fmode != tmode && fsb.zs_gen == tsb.zs_gen) tsb.zs_gen++; /* Force a generational difference */ - same_name = do_name_cmp(fobjname, tobjname); /* Simple modification or no change */ if (fsb.zs_gen == tsb.zs_gen) { @@ -334,7 +323,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) if (change) { print_link_change(fp, di, change, change > 0 ? fobjname : tobjname, &tsb); - } else if (same_name) { + } else if (strcmp(fobjname, tobjname) == 0) { print_file(fp, di, ZDIFF_MODIFIED, fobjname, &tsb); } else { print_rename(fp, di, fobjname, tobjname, &tsb); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h index ded3d88237b0..c934cff70506 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h @@ -79,6 +79,7 @@ struct libzfs_handle { libzfs_fru_t **libzfs_fru_hash; libzfs_fru_t *libzfs_fru_list; char libzfs_chassis_id[256]; + boolean_t libzfs_prop_debug; }; #define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */ diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index ed20afbac1ca..a8da5b4dc77a 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -42,6 +42,7 @@ * using our derived config, and record the results. */ +#include #include #include #include @@ -865,6 +866,7 @@ label_offset(uint64_t size, int l) /* * Given a file descriptor, read the label information and return an nvlist * describing the configuration, if there is one. + * Return 0 on success, or -1 on failure */ int zpool_read_label(int fd, nvlist_t **config) @@ -877,7 +879,7 @@ zpool_read_label(int fd, nvlist_t **config) *config = NULL; if (fstat64(fd, &statbuf) == -1) - return (0); + return (-1); size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); if ((label = malloc(sizeof (vdev_label_t))) == NULL) @@ -911,20 +913,24 @@ zpool_read_label(int fd, nvlist_t **config) free(label); *config = NULL; - return (0); + return (-1); } /* * Given a file descriptor, read the label information and return an nvlist * describing the configuration, if there is one. * returns the number of valid labels found + * If a label is found, returns it via config. The caller is responsible for + * freeing it. */ int zpool_read_all_labels(int fd, nvlist_t **config) { struct stat64 statbuf; + struct aiocb aiocbs[VDEV_LABELS]; + struct aiocb *aiocbps[VDEV_LABELS]; int l; - vdev_label_t *label; + vdev_phys_t *labels; uint64_t state, txg, size; int nlabels = 0; @@ -934,19 +940,40 @@ zpool_read_all_labels(int fd, nvlist_t **config) return (0); size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); - if ((label = malloc(sizeof (vdev_label_t))) == NULL) + if ((labels = calloc(VDEV_LABELS, sizeof (vdev_phys_t))) == NULL) return (0); + memset(aiocbs, 0, sizeof(aiocbs)); + for (l = 0; l < VDEV_LABELS; l++) { + aiocbs[l].aio_fildes = fd; + aiocbs[l].aio_offset = label_offset(size, l) + VDEV_SKIP_SIZE; + aiocbs[l].aio_buf = &labels[l]; + aiocbs[l].aio_nbytes = sizeof(vdev_phys_t); + aiocbs[l].aio_lio_opcode = LIO_READ; + aiocbps[l] = &aiocbs[l]; + } + + if (lio_listio(LIO_WAIT, aiocbps, VDEV_LABELS, NULL) != 0) { + if (errno == EAGAIN || errno == EINTR || errno == EIO) { + for (l = 0; l < VDEV_LABELS; l++) { + errno = 0; + int r = aio_error(&aiocbs[l]); + if (r != EINVAL) + (void)aio_return(&aiocbs[l]); + } + } + free(labels); + return (0); + } + for (l = 0; l < VDEV_LABELS; l++) { nvlist_t *temp = NULL; - /* TODO: use aio_read so we can read al 4 labels in parallel */ - if (pread64(fd, label, sizeof (vdev_label_t), - label_offset(size, l)) != sizeof (vdev_label_t)) + if (aio_return(&aiocbs[l]) != sizeof(vdev_phys_t)) continue; - if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist, - sizeof (label->vl_vdev_phys.vp_nvlist), &temp, 0) != 0) + if (nvlist_unpack(labels[l].vp_nvlist, + sizeof (labels[l].vp_nvlist), &temp, 0) != 0) continue; if (nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_STATE, @@ -969,7 +996,7 @@ zpool_read_all_labels(int fd, nvlist_t **config) nlabels++; } - free(label); + free(labels); return (nlabels); } @@ -1148,7 +1175,7 @@ zpool_open_func(void *arg) } #endif /* illumos */ - if ((zpool_read_label(fd, &config)) != 0) { + if ((zpool_read_label(fd, &config)) != 0 && errno == ENOMEM) { (void) close(fd); (void) no_memory(rn->rn_hdl); return; @@ -1649,7 +1676,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr, *inuse = B_FALSE; - if (zpool_read_label(fd, &config) != 0) { + if (zpool_read_label(fd, &config) != 0 && errno == ENOMEM) { (void) no_memory(hdl); return (-1); } diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c index f2efcbac4ea0..76f06e54a98b 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c @@ -2295,6 +2295,7 @@ vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size, return (ret); } } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 || + strcmp(type, VDEV_TYPE_RAIDZ) == 0 || strcmp(type, VDEV_TYPE_REPLACING) == 0 || (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) { nvlist_t **child; diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c index 3e24741b9832..85f6098d82ff 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c @@ -3212,7 +3212,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, /* * Determine the name of the origin snapshot, store in zc_string. */ - if (drrb->drr_flags & DRR_FLAG_CLONE) { + if (originsnap) { + (void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string)); + if (flags->verbose) + (void) printf("using provided clone origin %s\n", + zc.zc_string); + } else if (drrb->drr_flags & DRR_FLAG_CLONE) { if (guid_to_name(hdl, zc.zc_value, drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) { zcmd_free_nvlists(&zc); @@ -3223,11 +3228,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, } if (flags->verbose) (void) printf("found clone origin %s\n", zc.zc_string); - } else if (originsnap) { - (void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string)); - if (flags->verbose) - (void) printf("using provided clone origin %s\n", - zc.zc_string); } boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) & diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c index a2ae8b043be2..5f5335d0f8c4 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -579,42 +580,7 @@ zfs_strdup(libzfs_handle_t *hdl, const char *str) void zfs_nicenum(uint64_t num, char *buf, size_t buflen) { - uint64_t n = num; - int index = 0; - char u; - - while (n >= 1024) { - n /= 1024; - index++; - } - - u = " KMGTPE"[index]; - - if (index == 0) { - (void) snprintf(buf, buflen, "%llu", n); - } else if ((num & ((1ULL << 10 * index) - 1)) == 0) { - /* - * If this is an even multiple of the base, always display - * without any decimal precision. - */ - (void) snprintf(buf, buflen, "%llu%c", n, u); - } else { - /* - * We want to choose a precision that reflects the best choice - * for fitting in 5 characters. This can get rather tricky when - * we have numbers that are very close to an order of magnitude. - * For example, when displaying 10239 (which is really 9.999K), - * we want only a single place of precision for 10.0K. We could - * develop some complex heuristics for this, but it's much - * easier just to try each combination in turn. - */ - int i; - for (i = 2; i >= 0; i--) { - if (snprintf(buf, buflen, "%.*f%c", i, - (double)num / (1ULL << 10 * index), u) <= 5) - break; - } - } + nicenum(num, buf, buflen); } void @@ -678,6 +644,10 @@ libzfs_init(void) zpool_feature_init(); libzfs_mnttab_init(hdl); + if (getenv("ZFS_PROP_DEBUG") != NULL) { + hdl->libzfs_prop_debug = B_TRUE; + } + return (hdl); } diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c index c38c8c64ee1d..ec32486e8c8f 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2017 RackTop Systems. @@ -160,7 +160,12 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name, if (resultp != NULL) { *resultp = NULL; - zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024); + if (ioc == ZFS_IOC_CHANNEL_PROGRAM) { + zc.zc_nvlist_dst_size = fnvlist_lookup_uint64(source, + ZCP_ARG_MEMLIMIT); + } else { + zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024); + } zc.zc_nvlist_dst = (uint64_t)(uintptr_t) malloc(zc.zc_nvlist_dst_size); #ifdef illumos @@ -174,7 +179,15 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name, } while (ioctl(g_fd, ioc, &zc) != 0) { - if (errno == ENOMEM && resultp != NULL) { + /* + * If ioctl exited with ENOMEM, we retry the ioctl after + * increasing the size of the destination nvlist. + * + * Channel programs that exit with ENOMEM ran over the + * lua memory sandbox; they should not be retried. + */ + if (errno == ENOMEM && resultp != NULL && + ioc != ZFS_IOC_CHANNEL_PROGRAM) { free((void *)(uintptr_t)zc.zc_nvlist_dst); zc.zc_nvlist_dst_size *= 2; zc.zc_nvlist_dst = (uint64_t)(uintptr_t) @@ -904,3 +917,54 @@ lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist) return (error); } + +/* + * Executes a channel program. + * + * If this function returns 0 the channel program was successfully loaded and + * ran without failing. Note that individual commands the channel program ran + * may have failed and the channel program is responsible for reporting such + * errors through outnvl if they are important. + * + * This method may also return: + * + * EINVAL The program contains syntax errors, or an invalid memory or time + * limit was given. No part of the channel program was executed. + * If caused by syntax errors, 'outnvl' contains information about the + * errors. + * + * EDOM The program was executed, but encountered a runtime error, such as + * calling a function with incorrect arguments, invoking the error() + * function directly, failing an assert() command, etc. Some portion + * of the channel program may have executed and committed changes. + * Information about the failure can be found in 'outnvl'. + * + * ENOMEM The program fully executed, but the output buffer was not large + * enough to store the returned value. No output is returned through + * 'outnvl'. + * + * ENOSPC The program was terminated because it exceeded its memory usage + * limit. Some portion of the channel program may have executed and + * committed changes to disk. No output is returned through 'outnvl'. + * + * ETIMEDOUT The program was terminated because it exceeded its Lua instruction + * limit. Some portion of the channel program may have executed and + * committed changes to disk. No output is returned through 'outnvl'. + */ +int +lzc_channel_program(const char *pool, const char *program, uint64_t instrlimit, + uint64_t memlimit, nvlist_t *argnvl, nvlist_t **outnvl) +{ + int error; + nvlist_t *args; + + args = fnvlist_alloc(); + fnvlist_add_string(args, ZCP_ARG_PROGRAM, program); + fnvlist_add_nvlist(args, ZCP_ARG_ARGLIST, argnvl); + fnvlist_add_uint64(args, ZCP_ARG_INSTRLIMIT, instrlimit); + fnvlist_add_uint64(args, ZCP_ARG_MEMLIMIT, memlimit); + error = lzc_ioctl(ZFS_IOC_CHANNEL_PROGRAM, pool, args, outnvl); + fnvlist_free(args); + + return (error); +} diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h index ea0e752e3524..234dda4a194c 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 by Martin Matuska . All rights reserved. * Copyright 2017 RackTop Systems. */ @@ -86,6 +86,9 @@ boolean_t lzc_exists(const char *); int lzc_rollback(const char *, char *, int); int lzc_rollback_to(const char *, const char *); +int lzc_channel_program(const char *, const char *, uint64_t, uint64_t, + nvlist_t *, nvlist_t **); + #ifdef __cplusplus } #endif diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c index ab1b839975ab..1d43c8d7253c 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c @@ -738,6 +738,7 @@ vpanic(const char *fmt, va_list adx) char buf[512]; (void) vsnprintf(buf, 512, fmt, adx); assfail(buf, NULL, 0); + abort(); /* necessary to make vpanic meet noreturn requirements */ } void diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h index f11174ffa521..019defb04d60 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h +++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ /* @@ -66,6 +66,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -126,8 +127,8 @@ extern void dprintf_setup(int *argc, char **argv); extern void cmn_err(int, const char *, ...); extern void vcmn_err(int, const char *, __va_list); -extern void panic(const char *, ...); -extern void vpanic(const char *, __va_list); +extern void panic(const char *, ...) __NORETURN; +extern void vpanic(const char *, __va_list) __NORETURN; #define fm_panic panic @@ -349,6 +350,7 @@ extern void cv_broadcast(kcondvar_t *cv); #define KM_SLEEP UMEM_NOFAIL #define KM_PUSHPAGE KM_SLEEP #define KM_NOSLEEP UMEM_DEFAULT +#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */ #define KMC_NODEBUG UMC_NODEBUG #define KMC_NOTOUCH 0 /* not needed for userland caches */ #define KM_NODEBUG 0 @@ -579,8 +581,9 @@ extern void kernel_init(int); extern void kernel_fini(void); struct spa; -extern void nicenum(uint64_t num, char *buf); +extern void nicenum(uint64_t num, char *buf, size_t); extern void show_pool_stats(struct spa *); +extern int set_global_var(char *arg); typedef struct callb_cpr { kmutex_t *cc_lockp; diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/util.c b/cddl/contrib/opensolaris/lib/libzpool/common/util.c index 6257e2b3e776..71894c2af290 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/util.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/util.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016 by Delphix. All rights reserved. */ #include @@ -31,38 +32,12 @@ #include #include #include +#include /* * Routines needed by more than one client of libzpool. */ -void -nicenum(uint64_t num, char *buf) -{ - uint64_t n = num; - int index = 0; - char u; - - while (n >= 1024) { - n = (n + (1024 / 2)) / 1024; /* Round up or down */ - index++; - } - - u = " KMGTPE"[index]; - - if (index == 0) { - (void) sprintf(buf, "%llu", (u_longlong_t)n); - } else if (n < 10 && (num & (num - 1)) != 0) { - (void) sprintf(buf, "%.2f%c", - (double)num / (1ULL << 10 * index), u); - } else if (n < 100 && (num & (num - 1)) != 0) { - (void) sprintf(buf, "%.1f%c", - (double)num / (1ULL << 10 * index), u); - } else { - (void) sprintf(buf, "%llu%c", (u_longlong_t)n, u); - } -} - static void show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) { @@ -95,15 +70,17 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) sec = MAX(1, vs->vs_timestamp / NANOSEC); - nicenum(vs->vs_alloc, used); - nicenum(vs->vs_space - vs->vs_alloc, avail); - nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops); - nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops); - nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes); - nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes); - nicenum(vs->vs_read_errors, rerr); - nicenum(vs->vs_write_errors, werr); - nicenum(vs->vs_checksum_errors, cerr); + nicenum(vs->vs_alloc, used, sizeof (used)); + nicenum(vs->vs_space - vs->vs_alloc, avail, sizeof (avail)); + nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops, sizeof (rops)); + nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops, sizeof (wops)); + nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes, + sizeof (rbytes)); + nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes, + sizeof (wbytes)); + nicenum(vs->vs_read_errors, rerr, sizeof (rerr)); + nicenum(vs->vs_write_errors, werr, sizeof (werr)); + nicenum(vs->vs_checksum_errors, cerr, sizeof (cerr)); (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n", indent, "", @@ -153,3 +130,58 @@ show_pool_stats(spa_t *spa) nvlist_free(config); } + +/* + * Sets given global variable in libzpool to given unsigned 32-bit value. + * arg: "=" + */ +int +set_global_var(char *arg) +{ + void *zpoolhdl; + char *varname = arg, *varval; + u_longlong_t val; + +#ifndef _LITTLE_ENDIAN + /* + * On big endian systems changing a 64-bit variable would set the high + * 32 bits instead of the low 32 bits, which could cause unexpected + * results. + */ + fprintf(stderr, "Setting global variables is only supported on " + "little-endian systems\n", varname); + return (ENOTSUP); +#endif + if ((varval = strchr(arg, '=')) != NULL) { + *varval = '\0'; + varval++; + val = strtoull(varval, NULL, 0); + if (val > UINT32_MAX) { + fprintf(stderr, "Value for global variable '%s' must " + "be a 32-bit unsigned integer\n", varname); + return (EOVERFLOW); + } + } else { + return (EINVAL); + } + + zpoolhdl = dlopen("libzpool.so", RTLD_LAZY); + if (zpoolhdl != NULL) { + uint32_t *var; + var = dlsym(zpoolhdl, varname); + if (var == NULL) { + fprintf(stderr, "Global variable '%s' does not exist " + "in libzpool.so\n", varname); + return (EINVAL); + } + *var = (uint32_t)val; + + dlclose(zpoolhdl); + } else { + fprintf(stderr, "Failed to open libzpool.so to set global " + "variable\n"); + return (EIO); + } + + return (0); +} diff --git a/cddl/lib/libavl/Makefile.depend b/cddl/lib/libavl/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/lib/libavl/Makefile.depend +++ b/cddl/lib/libavl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/lib/libctf/Makefile.depend b/cddl/lib/libctf/Makefile.depend index ff9d79528313..ceebc6a83a34 100644 --- a/cddl/lib/libctf/Makefile.depend +++ b/cddl/lib/libctf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/lib/libdtrace/Makefile.depend b/cddl/lib/libdtrace/Makefile.depend index ff38bcc81a9e..68a8d3e9c520 100644 --- a/cddl/lib/libdtrace/Makefile.depend +++ b/cddl/lib/libdtrace/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ cddl/lib/libctf \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/cddl/lib/libnvpair/Makefile.depend b/cddl/lib/libnvpair/Makefile.depend index c9f9d52f6e26..905e67cc66c9 100644 --- a/cddl/lib/libnvpair/Makefile.depend +++ b/cddl/lib/libnvpair/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/lib/libumem/Makefile.depend b/cddl/lib/libumem/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/lib/libumem/Makefile.depend +++ b/cddl/lib/libumem/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/lib/libuutil/Makefile.depend b/cddl/lib/libuutil/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/cddl/lib/libuutil/Makefile.depend +++ b/cddl/lib/libuutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/lib/libzfs/Makefile b/cddl/lib/libzfs/Makefile index e8de72f18275..c873f3e80d77 100644 --- a/cddl/lib/libzfs/Makefile +++ b/cddl/lib/libzfs/Makefile @@ -4,6 +4,7 @@ .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common +.PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils/common LIB= zfs LIBADD= md pthread umem util uutil m avl bsdxml geom nvpair z zfs_core @@ -15,6 +16,8 @@ SRCS= deviceid.c \ zmount.c \ zone.c +SRCS+= nicenum.c + SRCS+= libzfs_changelist.c \ libzfs_compat.c \ libzfs_config.c \ @@ -54,5 +57,6 @@ CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libuutil/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils .include diff --git a/cddl/lib/libzfs/Makefile.depend b/cddl/lib/libzfs/Makefile.depend index d1ae9c336827..c595a33ac32a 100644 --- a/cddl/lib/libzfs/Makefile.depend +++ b/cddl/lib/libzfs/Makefile.depend @@ -8,7 +8,6 @@ DIRDEPS = \ cddl/lib/libuutil \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/lib/libzfs_core/Makefile.depend b/cddl/lib/libzfs_core/Makefile.depend index 86e045ff4aa0..29182b722f62 100644 --- a/cddl/lib/libzfs_core/Makefile.depend +++ b/cddl/lib/libzfs_core/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ cddl/lib/libnvpair \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile index 4b5fdaf0d406..920cf865aa45 100644 --- a/cddl/lib/libzpool/Makefile +++ b/cddl/lib/libzpool/Makefile @@ -4,6 +4,8 @@ # ZFS_COMMON_SRCS .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs +# LUA_SRCS +.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua # ZFS_SHARED_SRCS .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs # KERNEL_SRCS @@ -23,18 +25,22 @@ ATOMIC_SRCS= opensolaris_atomic.c .endif # UNICODE_SRCS .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/unicode +# LIBCMDUTILS_SRCS +.PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils/common LIB= zpool ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} trim_map.c ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/} +LUA_SRCS= ${LUA_OBJS:C/.o$/.c/} KERNEL_SRCS= kernel.c taskq.c util.c LIST_SRCS= list.c UNICODE_SRCS= u8_textprep.c +LIBCMDUTILS_SRCS=nicenum.c -SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \ +SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} ${LUA_SRCS} \ ${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \ - ${UNICODE_SRCS} + ${UNICODE_SRCS} ${LIBCMDUTILS_SRCS} WARNS?= 0 CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris @@ -43,10 +49,12 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs +CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils # XXX: pthread doesn't have mutex_owned() equivalent, so we need to look # into libthr private structures. That's sooo evil, but it's only for # ZFS debugging tools needs. diff --git a/cddl/lib/libzpool/Makefile.depend b/cddl/lib/libzpool/Makefile.depend index c91de43e0c03..97914fc35322 100644 --- a/cddl/lib/libzpool/Makefile.depend +++ b/cddl/lib/libzpool/Makefile.depend @@ -6,7 +6,6 @@ DIRDEPS = \ cddl/lib/libnvpair \ cddl/lib/libumem \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/sbin/zfs/Makefile b/cddl/sbin/zfs/Makefile index e0d6faa8d873..9d6075e6ad8f 100644 --- a/cddl/sbin/zfs/Makefile +++ b/cddl/sbin/zfs/Makefile @@ -3,7 +3,7 @@ .PATH: ${SRCTOP}/cddl/contrib/opensolaris/cmd/zfs PROG= zfs -MAN= zfs.8 +MAN= zfs.8 zfs-program.8 SRCS= zfs_main.c zfs_iter.c WARNS?= 0 diff --git a/cddl/sbin/zfs/Makefile.depend b/cddl/sbin/zfs/Makefile.depend index dc8a013df91e..b22dd60b0ef8 100644 --- a/cddl/sbin/zfs/Makefile.depend +++ b/cddl/sbin/zfs/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ cddl/lib/libzfs \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/sbin/zpool/Makefile.depend b/cddl/sbin/zpool/Makefile.depend index b1a2eff6cb4f..53090da6e2fc 100644 --- a/cddl/sbin/zpool/Makefile.depend +++ b/cddl/sbin/zpool/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ cddl/lib/libzfs \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/ctfconvert/Makefile.depend b/cddl/usr.bin/ctfconvert/Makefile.depend index 9dafcb6af276..44e570745e22 100644 --- a/cddl/usr.bin/ctfconvert/Makefile.depend +++ b/cddl/usr.bin/ctfconvert/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/ctfdump/Makefile.depend b/cddl/usr.bin/ctfdump/Makefile.depend index ff9d79528313..ceebc6a83a34 100644 --- a/cddl/usr.bin/ctfdump/Makefile.depend +++ b/cddl/usr.bin/ctfdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/ctfmerge/Makefile.depend b/cddl/usr.bin/ctfmerge/Makefile.depend index e94f8d4ba875..32a1985bd180 100644 --- a/cddl/usr.bin/ctfmerge/Makefile.depend +++ b/cddl/usr.bin/ctfmerge/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/zinject/Makefile.depend b/cddl/usr.bin/zinject/Makefile.depend index deb1256e93a4..dfb2563fa7d1 100644 --- a/cddl/usr.bin/zinject/Makefile.depend +++ b/cddl/usr.bin/zinject/Makefile.depend @@ -10,7 +10,6 @@ DIRDEPS = \ cddl/lib/libzfs_core \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/zstreamdump/Makefile.depend b/cddl/usr.bin/zstreamdump/Makefile.depend index 138e88bc6aa4..3089536f9717 100644 --- a/cddl/usr.bin/zstreamdump/Makefile.depend +++ b/cddl/usr.bin/zstreamdump/Makefile.depend @@ -7,7 +7,6 @@ DIRDEPS = \ cddl/lib/libumem \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile index 81f120a13116..367512999c41 100644 --- a/cddl/usr.bin/ztest/Makefile +++ b/cddl/usr.bin/ztest/Makefile @@ -11,6 +11,7 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys diff --git a/cddl/usr.bin/ztest/Makefile.depend b/cddl/usr.bin/ztest/Makefile.depend index deb1256e93a4..dfb2563fa7d1 100644 --- a/cddl/usr.bin/ztest/Makefile.depend +++ b/cddl/usr.bin/ztest/Makefile.depend @@ -10,7 +10,6 @@ DIRDEPS = \ cddl/lib/libzfs_core \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/dtrace/Makefile.depend b/cddl/usr.sbin/dtrace/Makefile.depend index db4aafd0a282..c37ef4acf01e 100644 --- a/cddl/usr.sbin/dtrace/Makefile.depend +++ b/cddl/usr.sbin/dtrace/Makefile.depend @@ -5,7 +5,6 @@ DIRDEPS = \ cddl/lib/libctf \ cddl/lib/libdtrace \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/dtrace/tests/common/io/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/io/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/io/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/io/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/java_api/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/java_api/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/java_api/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/java_api/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/json/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/json/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/json/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/json/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/pid/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/pid/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/pid/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/pid/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/probes/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/probes/Makefile.depend index f80275d86ab1..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/probes/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/probes/Makefile.depend @@ -2,6 +2,11 @@ # Autogenerated - do NOT edit! DIRDEPS = \ + gnu/lib/csu \ + include \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ .include diff --git a/cddl/usr.sbin/dtrace/tests/common/proc/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/proc/Makefile.depend index 7543607a575c..564eb51e0156 100644 --- a/cddl/usr.sbin/dtrace/tests/common/proc/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/proc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile.depend index 43d71f8b2760..03d33794d0e3 100644 --- a/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ diff --git a/cddl/usr.sbin/dtrace/tests/common/raise/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/raise/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/raise/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/raise/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/sdt/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/sdt/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/sdt/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/sdt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/stop/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/stop/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/stop/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/stop/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/sugar/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/sugar/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/cddl/usr.sbin/dtrace/tests/common/sugar/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/cddl/usr.sbin/dtrace/tests/common/syscall/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/syscall/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/syscall/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/syscall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/uctf/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/uctf/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/uctf/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/uctf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/usdt/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/usdt/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/usdt/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/usdt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/dtrace/tests/common/ustack/Makefile.depend b/cddl/usr.sbin/dtrace/tests/common/ustack/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/cddl/usr.sbin/dtrace/tests/common/ustack/Makefile.depend +++ b/cddl/usr.sbin/dtrace/tests/common/ustack/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/cddl/usr.sbin/lockstat/Makefile.depend b/cddl/usr.sbin/lockstat/Makefile.depend index 18ce380c1380..04b96e83f1c7 100644 --- a/cddl/usr.sbin/lockstat/Makefile.depend +++ b/cddl/usr.sbin/lockstat/Makefile.depend @@ -5,7 +5,6 @@ DIRDEPS = \ cddl/lib/libctf \ cddl/lib/libdtrace \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/plockstat/Makefile.depend b/cddl/usr.sbin/plockstat/Makefile.depend index db4aafd0a282..c37ef4acf01e 100644 --- a/cddl/usr.sbin/plockstat/Makefile.depend +++ b/cddl/usr.sbin/plockstat/Makefile.depend @@ -5,7 +5,6 @@ DIRDEPS = \ cddl/lib/libctf \ cddl/lib/libdtrace \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/zdb/Makefile b/cddl/usr.sbin/zdb/Makefile index 84b64e45c6b2..8f50aaa5f525 100644 --- a/cddl/usr.sbin/zdb/Makefile +++ b/cddl/usr.sbin/zdb/Makefile @@ -12,6 +12,7 @@ CSTD= c99 CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libcmdutils CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libuutil/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common diff --git a/cddl/usr.sbin/zdb/Makefile.depend b/cddl/usr.sbin/zdb/Makefile.depend index deb1256e93a4..dfb2563fa7d1 100644 --- a/cddl/usr.sbin/zdb/Makefile.depend +++ b/cddl/usr.sbin/zdb/Makefile.depend @@ -10,7 +10,6 @@ DIRDEPS = \ cddl/lib/libzfs_core \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/zfsd/Makefile.depend b/cddl/usr.sbin/zfsd/Makefile.depend index 35e134179446..023a4456ec68 100644 --- a/cddl/usr.sbin/zfsd/Makefile.depend +++ b/cddl/usr.sbin/zfsd/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ cddl/lib/libzfs \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc index 0cd659622e94..c3105853b29c 100644 --- a/cddl/usr.sbin/zfsd/case_file.cc +++ b/cddl/usr.sbin/zfsd/case_file.cc @@ -102,7 +102,8 @@ CaseFile::Find(Guid poolGUID, Guid vdevGUID) for (CaseFileList::iterator curCase = s_activeCases.begin(); curCase != s_activeCases.end(); curCase++) { - if ((*curCase)->PoolGUID() != poolGUID + if (((*curCase)->PoolGUID() != poolGUID + && Guid::InvalidGuid() != poolGUID) || (*curCase)->VdevGUID() != vdevGUID) continue; @@ -268,7 +269,8 @@ CaseFile::ReEvaluate(const string &devPath, const string &physPath, Vdev *vdev) } if (vdev != NULL - && vdev->PoolGUID() == m_poolGUID + && ( vdev->PoolGUID() == m_poolGUID + || vdev->PoolGUID() == Guid::InvalidGuid()) && vdev->GUID() == m_vdevGUID) { zpool_vdev_online(pool, vdev->GUIDString().c_str(), diff --git a/cddl/usr.sbin/zfsd/case_file.h b/cddl/usr.sbin/zfsd/case_file.h index aa2a447e8a47..fcb1261f2a67 100644 --- a/cddl/usr.sbin/zfsd/case_file.h +++ b/cddl/usr.sbin/zfsd/case_file.h @@ -89,6 +89,8 @@ class CaseFile * \brief Find a CaseFile object by a vdev's pool/vdev GUID tuple. * * \param poolGUID Pool GUID for the vdev of the CaseFile to find. + * If InvalidGuid, then only match the vdev GUID + * instead of both pool and vdev GUIDs. * \param vdevGUID Vdev GUID for the vdev of the CaseFile to find. * * \return If found, a pointer to a valid CaseFile object. diff --git a/cddl/usr.sbin/zfsd/vdev_iterator.cc b/cddl/usr.sbin/zfsd/vdev_iterator.cc index 07f19d2b074c..31a4ce962970 100644 --- a/cddl/usr.sbin/zfsd/vdev_iterator.cc +++ b/cddl/usr.sbin/zfsd/vdev_iterator.cc @@ -76,7 +76,9 @@ void VdevIterator::Reset() { nvlist_t *rootVdev; + nvlist **cache_child; int result; + uint_t cache_children; result = nvlist_lookup_nvlist(m_poolConfig, ZPOOL_CONFIG_VDEV_TREE, @@ -85,6 +87,13 @@ VdevIterator::Reset() throw ZfsdException(m_poolConfig, "Unable to extract " "ZPOOL_CONFIG_VDEV_TREE from pool."); m_vdevQueue.assign(1, rootVdev); + result = nvlist_lookup_nvlist_array(rootVdev, + ZPOOL_CONFIG_L2CACHE, + &cache_child, + &cache_children); + if (result == 0) + for (uint_t c = 0; c < cache_children; c++) + m_vdevQueue.push_back(cache_child[c]); } nvlist_t * diff --git a/cddl/usr.sbin/zfsd/zfsd_event.cc b/cddl/usr.sbin/zfsd/zfsd_event.cc index 706b1b1ed2ba..5594b35a88a8 100644 --- a/cddl/usr.sbin/zfsd/zfsd_event.cc +++ b/cddl/usr.sbin/zfsd/zfsd_event.cc @@ -101,7 +101,7 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool °raded) poolName = NULL; if (zpool_in_use(g_zfsHandle, devFd, &poolState, &poolName, &b_inuse) == 0) { - nvlist_t *devLabel; + nvlist_t *devLabel = NULL; inUse = b_inuse == B_TRUE; if (poolName != NULL) @@ -116,8 +116,10 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool °raded) * might be damaged. In that case, zfsd should do nothing and * wait for the sysadmin to decide. */ - if (nlabels != VDEV_LABELS || devLabel == NULL) + if (nlabels != VDEV_LABELS || devLabel == NULL) { + nvlist_free(devLabel); return (NULL); + } try { Vdev vdev(devLabel); @@ -131,6 +133,7 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool °raded) exp.GetString().insert(0, context); exp.Log(); + nvlist_free(devLabel); } } return (NULL); diff --git a/cddl/usr.sbin/zhack/Makefile.depend b/cddl/usr.sbin/zhack/Makefile.depend index deb1256e93a4..dfb2563fa7d1 100644 --- a/cddl/usr.sbin/zhack/Makefile.depend +++ b/cddl/usr.sbin/zhack/Makefile.depend @@ -10,7 +10,6 @@ DIRDEPS = \ cddl/lib/libzfs_core \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/contrib/binutils/bfd/elf-eh-frame.c b/contrib/binutils/bfd/elf-eh-frame.c index 092c2c57ec34..baa998676cdd 100644 --- a/contrib/binutils/bfd/elf-eh-frame.c +++ b/contrib/binutils/bfd/elf-eh-frame.c @@ -1344,7 +1344,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, val = read_value (abfd, buf, per_width, get_DW_EH_PE_signed (per_encoding)); - val += ent->offset - ent->new_offset; + val += (bfd_vma)ent->offset - ent->new_offset; val -= extra_string + extra_data; write_value (abfd, buf, val, per_width); action &= ~4; @@ -1400,7 +1400,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, } break; case DW_EH_PE_pcrel: - value += ent->offset - ent->new_offset; + value += (bfd_vma)ent->offset - ent->new_offset; address += sec->output_section->vma + ent->offset + 8; break; } @@ -1428,7 +1428,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, if (value) { if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel) - value += ent->offset - ent->new_offset; + value += (bfd_vma)ent->offset - ent->new_offset; else if (ent->cie_inf->need_lsda_relative) value -= (sec->output_section->vma + ent->new_offset + 8 + ent->lsda_offset); diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog index c15589c284ad..36476d8ccdd4 100644 --- a/contrib/bmake/ChangeLog +++ b/contrib/bmake/ChangeLog @@ -1,3 +1,36 @@ +2017-10-28 Simon J. Gerraty + + * VERSION: 20171028 + Merge with NetBSD make, pick up + o main.c: ignore empty MAKEOBJDIR + + * Makefile.config.in: + make @prefix@ @machine*@ and @default_sys_path@ defaults. + +2017-10-05 Simon J. Gerraty + + * VERSION: 20171005 + + * unit-tests/dotwait.mk: redirect stderr through pipe for more + consistent result on some platforms. + +2017-08-13 Simon J. Gerraty + + * machine.sh: entry for AIX + +2017-08-12 Simon J. Gerraty + + * VERSION (_MAKE_VERSION): Move the setting of _MAKE_VERSION + to a file that can be included by configure as well as make. + This allows configure to set set _MAKE_VERSION in make-bootstrap.sh + +2017-08-10 Simon J. Gerraty + + * Makefile (_MAKE_VERSION): 20170810 + Merge with NetBSD make, pick up + o meta.c: if target is in subdir we only need subdir name in + meta_name. + 2017-07-20 Simon J. Gerraty * Makefile (_MAKE_VERSION): 20170720 diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES index 720eb1b9bfb7..24cd0451f077 100644 --- a/contrib/bmake/FILES +++ b/contrib/bmake/FILES @@ -5,6 +5,7 @@ Makefile.config.in PSD.doc/Makefile PSD.doc/tutorial.ms README +VERSION aclocal.m4 arch.c bmake.1 diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile index f0b94966ab07..28d8bf713a00 100644 --- a/contrib/bmake/Makefile +++ b/contrib/bmake/Makefile @@ -1,7 +1,4 @@ -# $Id: Makefile,v 1.95 2017/07/20 19:36:13 sjg Exp $ - -# Base version on src date -_MAKE_VERSION= 20170720 +# $Id: Makefile,v 1.99 2017/08/13 20:12:53 sjg Exp $ PROG= bmake @@ -58,6 +55,8 @@ SRCS+= \ lstReplace.c \ lstSucc.c +.-include "VERSION" + # this file gets generated by configure .-include "Makefile.config" @@ -192,11 +191,13 @@ MANDIR= ${MANDIR.bmake:U${SHAREDIR}/man} ${OBJS}: config.h .endif -# make sure that MAKE_VERSION gets updated. -main.o: ${SRCS} ${MAKEFILE} - # start-delete2 for bsd.after-import.mk + +# make sure that MAKE_VERSION gets updated. +main.o: ${SRCS} ${.CURDIR}/VERSION + .if ${MK_AUTOCONF_MK} == "yes" +CONFIGURE_DEPS += ${.CURDIR}/VERSION .include .endif SHARE_MK?=${SHAREDIR}/mk diff --git a/contrib/bmake/Makefile.config.in b/contrib/bmake/Makefile.config.in index 1f9aefe1dfad..7b417cef2604 100644 --- a/contrib/bmake/Makefile.config.in +++ b/contrib/bmake/Makefile.config.in @@ -1,11 +1,13 @@ # things set by configure -prefix= @prefix@ +_MAKE_VERSION=@_MAKE_VERSION@ + +prefix?= @prefix@ srcdir= @srcdir@ CC?= @CC@ -MACHINE= @machine@ -MACHINE_ARCH= @machine_arch@ -DEFAULT_SYS_PATH= @default_sys_path@ +MACHINE?= @machine@ +MACHINE_ARCH?= @machine_arch@ +DEFAULT_SYS_PATH?= @default_sys_path@ CPPFLAGS+= @CPPFLAGS@ CFLAGS+= ${CPPFLAGS} @DEFS@ @@ -17,4 +19,3 @@ FILEMON_H= @filemon_h@ BMAKE_PATH_MAX?= @bmake_path_max@ # used if MAXPATHLEN not defined CPPFLAGS+= -DBMAKE_PATH_MAX=${BMAKE_PATH_MAX} - diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION new file mode 100644 index 000000000000..5117e28f593c --- /dev/null +++ b/contrib/bmake/VERSION @@ -0,0 +1,2 @@ +# keep this compatible with sh and make +_MAKE_VERSION=20171028 diff --git a/contrib/bmake/bsd.after-import.mk b/contrib/bmake/bsd.after-import.mk index 9a65096a9597..275b443b657d 100644 --- a/contrib/bmake/bsd.after-import.mk +++ b/contrib/bmake/bsd.after-import.mk @@ -1,4 +1,4 @@ -# $Id: bsd.after-import.mk,v 1.12 2014/02/14 23:45:49 sjg Exp $ +# $Id: bsd.after-import.mk,v 1.13 2017/08/13 00:56:10 sjg Exp $ # This makefile is for use when integrating bmake into a BSD build # system. Use this makefile after importing bmake. @@ -56,6 +56,7 @@ bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE} # Makefiles need a little more tweaking than say config.h MAKEFILE_SED = sed -e '/^MACHINE/d' \ + -e '/include.*VERSION/d' \ -e '/^PROG/ { s,=,?=,;s,bmake,$${.CURDIR:T},; }' \ -e 's,^.-include,.sinclude,' \ -e '/^\..*include *. # @@ -549,8 +549,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bmake' PACKAGE_TARNAME='bmake' -PACKAGE_VERSION='20160606' -PACKAGE_STRING='bmake 20160606' +PACKAGE_VERSION='20170812' +PACKAGE_STRING='bmake 20170812' PACKAGE_BUGREPORT='sjg@NetBSD.org' PACKAGE_URL='' @@ -591,6 +591,7 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +_MAKE_VERSION filemon_h use_meta diff_u @@ -1221,7 +1222,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bmake 20160606 to adapt to many kinds of systems. +\`configure' configures bmake 20170812 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1282,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bmake 20160606:";; + short | recursive ) echo "Configuration of bmake 20170812:";; esac cat <<\_ACEOF @@ -1387,7 +1388,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bmake configure 20160606 +bmake configure 20170812 generated by GNU Autoconf 2.64 Copyright (C) 2009 Free Software Foundation, Inc. @@ -1960,7 +1961,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bmake $as_me 20160606, which was +It was created by bmake $as_me 20170812, which was generated by GNU Autoconf 2.64. Invocation command line was $ $0 $@ @@ -2315,6 +2316,8 @@ case "$srcdir" in *) srcdir=`cd $srcdir && pwd`;; esac +. $srcdir/VERSION + # Check whether --with-defshell was given. if test "${with_defshell+set}" = set; then : @@ -6005,6 +6008,7 @@ fi + ac_config_files="$ac_config_files makefile Makefile.config make-bootstrap.sh unit-tests/Makefile" cat >confcache <<\_ACEOF @@ -6513,7 +6517,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bmake $as_me 20160606, which was +This file was extended by bmake $as_me 20170812, which was generated by GNU Autoconf 2.64. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6573,7 +6577,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -bmake config.status 20160606 +bmake config.status 20170812 configured by $0, generated by GNU Autoconf 2.64, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/contrib/bmake/configure.in b/contrib/bmake/configure.in index 29d368b2ed29..aed426ef8ede 100644 --- a/contrib/bmake/configure.in +++ b/contrib/bmake/configure.in @@ -1,11 +1,11 @@ dnl dnl RCSid: -dnl $Id: configure.in,v 1.57 2016/06/07 00:49:44 sjg Exp $ +dnl $Id: configure.in,v 1.58 2017/08/13 00:56:10 sjg Exp $ dnl dnl Process this file with autoconf to produce a configure script dnl AC_PREREQ(2.50) -AC_INIT([bmake], [20160606], [sjg@NetBSD.org]) +AC_INIT([bmake], [20170812], [sjg@NetBSD.org]) AC_CONFIG_HEADERS(config.h) dnl make srcdir absolute @@ -14,6 +14,9 @@ case "$srcdir" in *) srcdir=`cd $srcdir && pwd`;; esac +dnl get _MAKE_VERSION +. $srcdir/VERSION + dnl AC_ARG_WITH(defshell, [ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions], @@ -386,6 +389,7 @@ AC_SUBST(GCC) AC_SUBST(diff_u) AC_SUBST(use_meta) AC_SUBST(filemon_h) +AC_SUBST(_MAKE_VERSION) AC_OUTPUT(makefile Makefile.config make-bootstrap.sh unit-tests/Makefile) cat < #ifndef lint @@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ #if 0 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: main.c,v 1.272 2017/06/19 19:58:24 christos Exp $"); +__RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -792,7 +792,8 @@ Main_SetVarObjdir(const char *var, const char *suffix) { char *p, *path, *xpath; - if ((path = Var_Value(var, VAR_CMD, &p)) == NULL) + if ((path = Var_Value(var, VAR_CMD, &p)) == NULL || + *path == '\0') return FALSE; /* expand variable substitutions */ diff --git a/contrib/bmake/make-bootstrap.sh.in b/contrib/bmake/make-bootstrap.sh.in index 83336b47d5af..a39427284586 100755 --- a/contrib/bmake/make-bootstrap.sh.in +++ b/contrib/bmake/make-bootstrap.sh.in @@ -13,7 +13,7 @@ esac CC="@CC@" CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS} -DBMAKE_PATH_MAX=@bmake_path_max@" -MAKE_VERSION=`sed -n '/^_MAKE_VERSION=/s,.*=[^0-9]*,,p' $srcdir/Makefile` +MAKE_VERSION=@_MAKE_VERSION@ MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \ -D@force_machine@MACHINE=\"@machine@\" -DMACHINE_ARCH=\"@machine_arch@\" \ diff --git a/contrib/bmake/meta.c b/contrib/bmake/meta.c index b8ddfb0b5e1b..4be13b5d0a97 100644 --- a/contrib/bmake/meta.c +++ b/contrib/bmake/meta.c @@ -1,4 +1,4 @@ -/* $NetBSD: meta.c,v 1.68 2017/07/09 04:54:00 sjg Exp $ */ +/* $NetBSD: meta.c,v 1.69 2017/08/10 21:07:48 sjg Exp $ */ /* * Implement 'meta' mode. @@ -250,6 +250,8 @@ meta_name(char *mname, size_t mnamelen, char *rp; char *cp; char *tp; + char *dtp; + size_t ldname; /* * Weed out relative paths from the target file name. @@ -286,10 +288,15 @@ meta_name(char *mname, size_t mnamelen, } /* on some systems dirname may modify its arg */ tp = bmake_strdup(tname); - if (strcmp(dname, dirname(tp)) == 0) + dtp = dirname(tp); + if (strcmp(dname, dtp) == 0) snprintf(mname, mnamelen, "%s.meta", tname); else { - snprintf(mname, mnamelen, "%s/%s.meta", dname, tname); + ldname = strlen(dname); + if (strncmp(dname, dtp, ldname) == 0 && dtp[ldname] == '/') + snprintf(mname, mnamelen, "%s/%s.meta", dname, &tname[ldname+1]); + else + snprintf(mname, mnamelen, "%s/%s.meta", dname, tname); /* * Replace path separators in the file name after the diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog index 179d191e9008..cd473d8d07cc 100644 --- a/contrib/bmake/mk/ChangeLog +++ b/contrib/bmake/mk/ChangeLog @@ -1,3 +1,21 @@ +2017-10-25 Simon J. Gerraty + + * Allow for host32 on rare occasions. + +2017-10-18 Simon J. Gerraty + + * install-mk (MK_VERSION): 20171018 + + * whats.mk: include what_thing in what_uuid to avoid problem + when building multiple apps in the same directory. + +2017-08-12 Simon J. Gerraty + + * install-mk (MK_VERSION): 20170812 + + * autoconf.mk: Use CONFIGURE_DEPS so Makefile can + add dependencies for config.recheck and config.gen + 2017-06-30 Simon J. Gerraty * install-mk (MK_VERSION): 20170630 diff --git a/contrib/bmake/mk/autoconf.mk b/contrib/bmake/mk/autoconf.mk index 573a7159957b..38f4ece48ad6 100644 --- a/contrib/bmake/mk/autoconf.mk +++ b/contrib/bmake/mk/autoconf.mk @@ -1,4 +1,4 @@ -# $Id: autoconf.mk,v 1.8 2012/11/19 05:37:48 sjg Exp $ +# $Id: autoconf.mk,v 1.9 2017/08/13 20:03:13 sjg Exp $ # # @(#) Copyright (c) 1996-2009, Simon J. Gerraty # @@ -15,8 +15,10 @@ .NOPATH: config.h config.status +CONFIGURE_DEPS += ${.CURDIR}/config.h.in ${.CURDIR}/configure + .if !target(config.h) -config.h: ${.CURDIR}/config.h.in config.status +config.h: ${CONFIGURE_DEPS} config.status ./config.status .endif @@ -28,11 +30,11 @@ config.status: config.recheck config.status: config.gen .endif -config.recheck: config.h.in ${.CURDIR}/configure +config.recheck: ${CONFIGURE_DEPS} ./config.status --recheck @touch $@ -config.gen: config.h.in ${.CURDIR}/configure +config.gen: ${CONFIGURE_DEPS} CC="${CC} ${CCMODE}" ${.CURDIR}/configure --no-create ${CONFIGURE_ARGS} @touch $@ config.recheck diff --git a/contrib/bmake/mk/dirdeps.mk b/contrib/bmake/mk/dirdeps.mk index 1ae0fbb635ab..2ff875770660 100644 --- a/contrib/bmake/mk/dirdeps.mk +++ b/contrib/bmake/mk/dirdeps.mk @@ -1,4 +1,4 @@ -# $Id: dirdeps.mk,v 1.89 2017/05/17 17:41:47 sjg Exp $ +# $Id: dirdeps.mk,v 1.90 2017/10/25 23:44:20 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -536,10 +536,14 @@ _machines := ${DEP_MACHINE} # this is the machine list we actually use below _machines := ${_only_machines} -.if defined(HOSTPROG) || ${DEP_MACHINE} == "host" +.if defined(HOSTPROG) || ${DEP_MACHINE:Nhost*} == "" # we need to build this guy's dependencies for host as well. +.if ${DEP_MACHINE:Nhost*} == "" +_machines += ${DEP_MACHINE} +.else _machines += host .endif +.endif _machines := ${_machines:O:u} .endif diff --git a/contrib/bmake/mk/dpadd.mk b/contrib/bmake/mk/dpadd.mk index 650d61bf9a80..731b915e604f 100644 --- a/contrib/bmake/mk/dpadd.mk +++ b/contrib/bmake/mk/dpadd.mk @@ -1,4 +1,4 @@ -# $Id: dpadd.mk,v 1.23 2017/02/13 16:46:01 sjg Exp $ +# $Id: dpadd.mk,v 1.24 2017/10/25 23:44:20 sjg Exp $ # # @(#) Copyright (c) 2004, Simon J. Gerraty # @@ -195,7 +195,7 @@ __dpadd_incs += ${__dpadd_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x: __dpadd_last_incs += ${__dpadd_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@} __dpadd_last_incs += ${__dpadd_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@} -.if defined(HOSTPROG) || ${MACHINE} == "host" +.if defined(HOSTPROG) || ${MACHINE:Nhost*} == "" # we want any -I/usr/* last __dpadd_last_incs := \ ${__dpadd_last_incs:N-I/usr/*} \ diff --git a/contrib/bmake/mk/gendirdeps.mk b/contrib/bmake/mk/gendirdeps.mk index 9ac7dcdba644..66158c411ad9 100644 --- a/contrib/bmake/mk/gendirdeps.mk +++ b/contrib/bmake/mk/gendirdeps.mk @@ -1,4 +1,4 @@ -# $Id: gendirdeps.mk,v 1.33 2016/10/11 22:37:28 sjg Exp $ +# $Id: gendirdeps.mk,v 1.34 2017/10/26 00:46:26 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -194,7 +194,7 @@ dpadd_dir_list += ${f:H:tA} .endfor .if !empty(ddep_list) ddeps != cat ${ddep_list:O:u} | ${META2DEPS_FILTER} ${_skip_gendirdeps} \ - sed 's,//*$$,,;s,\.${HOST_TARGET}$$,.host,;s,\.${MACHINE}$$,,' + sed 's,//*$$,,;s,\.${HOST_TARGET:Uhost}$$,.host,;s,\.${HOST_TARGET32:Uhost32}$$,.host32,;s,\.${MACHINE}$$,,' .if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" .info ${RELDIR}: raw_dir_list='${dir_list}' diff --git a/contrib/bmake/mk/install-mk b/contrib/bmake/mk/install-mk index 0950b109a276..15486a10ce4d 100644 --- a/contrib/bmake/mk/install-mk +++ b/contrib/bmake/mk/install-mk @@ -55,7 +55,7 @@ # Simon J. Gerraty # RCSid: -# $Id: install-mk,v 1.148 2017/06/30 23:46:15 sjg Exp $ +# $Id: install-mk,v 1.150 2017/10/19 03:50:51 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -70,7 +70,7 @@ # sjg@crufty.net # -MK_VERSION=20170630 +MK_VERSION=20171018 OWNER= GROUP= MODE=444 diff --git a/contrib/bmake/mk/meta.autodep.mk b/contrib/bmake/mk/meta.autodep.mk index 06fa98c6a5a7..10f9ca307762 100644 --- a/contrib/bmake/mk/meta.autodep.mk +++ b/contrib/bmake/mk/meta.autodep.mk @@ -1,4 +1,4 @@ -# $Id: meta.autodep.mk,v 1.45 2016/06/03 17:22:32 sjg Exp $ +# $Id: meta.autodep.mk,v 1.46 2017/10/25 23:44:20 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -261,7 +261,7 @@ META_FILES = ${.MAKE.META.FILES:T:N.depend*:N*o.meta:O:u} \ _makesyspath:= ${_PARSEDIR} ${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} $${.MAKE.META.CREATED} @echo Checking $@: ${.OODATE:T:[1..8]} - @(cd . && \ + @(cd . && ${GENDIRDEPS_ENV} \ SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS:O:u}' \ DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \ MAKESYSPATH=${_makesyspath} \ diff --git a/contrib/bmake/mk/meta.stage.mk b/contrib/bmake/mk/meta.stage.mk index 03906a8d7507..5c54f81fb378 100644 --- a/contrib/bmake/mk/meta.stage.mk +++ b/contrib/bmake/mk/meta.stage.mk @@ -1,4 +1,4 @@ -# $Id: meta.stage.mk,v 1.54 2017/07/06 23:20:33 sjg Exp $ +# $Id: meta.stage.mk,v 1.55 2017/10/27 01:17:09 sjg Exp $ # # @(#) Copyright (c) 2011-2017, Simon J. Gerraty # @@ -20,9 +20,9 @@ .if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != "" # this is generally safer anyway -_dirdep = ${RELDIR}.${MACHINE} +_dirdep ?= ${RELDIR}.${MACHINE} .else -_dirdep = ${RELDIR} +_dirdep ?= ${RELDIR} .endif CLEANFILES+= .dirdep diff --git a/contrib/bmake/mk/sys.clean-env.mk b/contrib/bmake/mk/sys.clean-env.mk index 396599bd7832..5ac74bba9342 100644 --- a/contrib/bmake/mk/sys.clean-env.mk +++ b/contrib/bmake/mk/sys.clean-env.mk @@ -1,4 +1,4 @@ -# $Id: sys.clean-env.mk,v 1.21 2016/02/18 21:16:40 sjg Exp $ +# $Id: sys.clean-env.mk,v 1.22 2017/10/25 23:44:20 sjg Exp $ # # @(#) Copyright (c) 2009, Simon J. Gerraty # @@ -97,7 +97,7 @@ _objroot := ${OBJROOT:U${SB_OBJROOT:U${SB}/${SB_OBJPREFIX}}} .if ${MAKE_VERSION} < 20160218 _objtop := ${OBJTOP:U${_objroot}${MACHINE}} # Take care of ${MACHINE} -.if ${MACHINE} == "host" || ${OBJTOP} == ${HOST_OBJTOP:Uno} +.if ${MACHINE:Nhost*} == "" || ${OBJTOP} == ${HOST_OBJTOP:Uno} OBJTOP = ${_objtop:S,${HOST_TARGET}$,\${MACHINE},} .else OBJTOP = ${_objtop:S,${MACHINE}$,\${MACHINE},} diff --git a/contrib/bmake/mk/whats.mk b/contrib/bmake/mk/whats.mk index d17c3ef290ea..4080c12e00f8 100644 --- a/contrib/bmake/mk/whats.mk +++ b/contrib/bmake/mk/whats.mk @@ -1,4 +1,4 @@ -# $Id: whats.mk,v 1.1 2014/08/30 22:40:47 sjg Exp $ +# $Id: whats.mk,v 1.3 2017/10/19 06:09:14 sjg Exp $ # # @(#) Copyright (c) 2014, Simon J. Gerraty # @@ -36,7 +36,8 @@ what_build_thing?= ${KMOD}.ko .if !empty(what_thing) # a unique name that won't conflict with anything -what_uuid = what_${.CURDIR:T:hash} +what_uuid = what_${what_thing}_${.CURDIR:T:hash} +what_var = what_${.CURDIR:T:hash} .if !empty(what_build_thing) ${what_build_thing}: ${what_build_exts:@e@${what_uuid}.$e@} @@ -57,7 +58,7 @@ _what1:= @(\#)${what_thing:tu} built ${%Y%m%d:L:localtime} by ${USER} _what2:= @(\#)${what_location} ${what_uuid}.c: - echo '${_what_t} ${what_uuid}1[] = "${_what1}";' > $@ ${.OODATE:MNO_META_CMP} - echo '${_what_t} ${what_uuid}2[] = "${_what2}";' >> $@ + echo '${_what_t} ${what_var}1[] = "${_what1}";' > $@ ${.OODATE:MNO_META_CMP} + echo '${_what_t} ${what_var}2[] = "${_what2}";' >> $@ .endif .endif diff --git a/contrib/bmake/os.sh b/contrib/bmake/os.sh index 8468ba1b3e7d..5815ea2874fb 100755 --- a/contrib/bmake/os.sh +++ b/contrib/bmake/os.sh @@ -17,7 +17,7 @@ # Simon J. Gerraty # RCSid: -# $Id: os.sh,v 1.53 2017/01/11 20:01:09 sjg Exp $ +# $Id: os.sh,v 1.54 2017/09/08 06:17:22 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -246,5 +246,7 @@ case /$0 in echo "$v='$vv'" done ;; +*/host_target32) echo $HOST_TARGET32;; +*/host_target) echo $HOST_TARGET;; esac diff --git a/contrib/bmake/unit-tests/dotwait.exp b/contrib/bmake/unit-tests/dotwait.exp index 6bf96e301c19..bdc0a0eb1504 100644 --- a/contrib/bmake/unit-tests/dotwait.exp +++ b/contrib/bmake/unit-tests/dotwait.exp @@ -22,9 +22,9 @@ shared.2.1 shared.2.1 shared.2.99 shared.2.99 +cycle.1.99 +cycle.1.99 make: Graph cycles through `cycle.2.99' make: Graph cycles through `cycle.2.98' make: Graph cycles through `cycle.2.97' -cycle.1.99 -cycle.1.99 exit status 0 diff --git a/contrib/bmake/unit-tests/dotwait.mk b/contrib/bmake/unit-tests/dotwait.mk index 9bdaaba399d1..bab5993e7481 100644 --- a/contrib/bmake/unit-tests/dotwait.mk +++ b/contrib/bmake/unit-tests/dotwait.mk @@ -1,4 +1,4 @@ -# $NetBSD: dotwait.mk,v 1.1 2014/08/21 13:44:51 apb Exp $ +# $NetBSD: dotwait.mk,v 1.2 2017/10/08 20:44:19 sjg Exp $ THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE} @@ -11,7 +11,7 @@ PAUSE= sleep 1 # Ignore "--- target ---" lines printed by parallel make. all: .for t in ${TESTS} - @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- " + @${.MAKE} -f ${THISMAKEFILE} -j4 $t 2>&1 | grep -v "^--- " .endfor # diff --git a/contrib/dma/dma.c b/contrib/dma/dma.c index 62b1bad4d754..b553c0fa0eef 100644 --- a/contrib/dma/dma.c +++ b/contrib/dma/dma.c @@ -331,8 +331,8 @@ deliver(struct qitem *it) switch (error) { case 0: - delqueue(it); syslog(LOG_INFO, "<%s> delivery successful", it->addr); + delqueue(it); exit(EX_OK); case 1: diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 2657ed9518e9..46fe8025bc7b 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -1141,7 +1141,9 @@ note_type_freebsd_core(unsigned int nt) case 14: return "NT_PROCSTAT_OSREL"; case 15: return "NT_PROCSTAT_PSSTRINGS"; case 16: return "NT_PROCSTAT_AUXV"; + case 17: return "NT_PTLWPINFO"; case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; + case 0x400: return "NT_ARM_VFP (arm VFP registers)"; default: return (note_type_unknown(nt)); } } @@ -2693,6 +2695,9 @@ dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn) case DT_MIPS_TIME_STAMP: printf(" %s\n", timestamp(dyn->d_un.d_val)); break; + default: + printf("\n"); + break; } break; default: diff --git a/contrib/file/ChangeLog b/contrib/file/ChangeLog index 2b6606d2979b..2063a23befed 100644 --- a/contrib/file/ChangeLog +++ b/contrib/file/ChangeLog @@ -1,6 +1,60 @@ +2017-09-02 11:53 Christos Zoulas + + * release 5.32 + +2017-08-28 16:37 Christos Zoulas + + * Always reset state in {file,buffer}_apprentice (Krzysztof Wilczynski) + +2017-08-27 03:55 Christos Zoulas + + * Fix always true condition (Thomas Jarosch) + +2017-05-24 17:30 Christos Zoulas + + * pickier parsing of numeric values in magic files. + +2017-05-23 17:55 Christos Zoulas + + * PR/615 add magic_getflags() + +2017-05-23 13:55 Christos Zoulas + + * release 5.31 + +2017-03-17 20:32 Christos Zoulas + + * remove trailing spaces from magic files + * refactor is_tar + * better bounds checks for cdf + +2017-02-10 12:24 Christos Zoulas + + * release 5.30 + +2017-02-07 23:27 Christos Zoulas + + * If we exceeded the offset in a search return no match + (Christoph Biedl) + * Be more lenient on corrupt CDF files (Christoph Biedl) + +2017-02-04 16:46 Christos Zoulas + + * pacify ubsan sign extension (oss-fuzz/524) + +2017-02-01 12:42 Christos Zoulas + + * off by one in cdf parsing (PR/593) + * report debugging sections in elf (PR/591) + +2016-11-06 10:52 Christos Zoulas + + * Allow @@@ in extensions + * Add missing overflow check in der magic (Jonas Wagner) + 2016-10-25 10:40 Christos Zoulas - * release 5.28 + * release 5.29 2016-10-24 11:20 Christos Zoulas @@ -387,7 +441,7 @@ ` 2013-11-06 14:40 Christos Zoulas - * fix erroneous non-zero exit code from non-existant file and message + * fix erroneous non-zero exit code from non-existent file and message 2013-10-29 14:25 Christos Zoulas diff --git a/contrib/file/aclocal.m4 b/contrib/file/aclocal.m4 index 4398374d8259..158e1494b339 100644 --- a/contrib/file/aclocal.m4 +++ b/contrib/file/aclocal.m4 @@ -21,7 +21,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # visibility.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2005, 2008, 2010-2014 Free Software Foundation, Inc. +dnl Copyright (C) 2005, 2008, 2010-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/contrib/file/config.guess b/contrib/file/config.guess index f7eb141e75a9..bbd48b60e88b 100755 --- a/contrib/file/config.guess +++ b/contrib/file/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2015-03-04' +timestamp='2017-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ timestamp='2015-03-04' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -221,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: @@ -237,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -249,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -265,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -373,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -407,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -632,13 +642,13 @@ EOF sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -677,11 +687,11 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -694,12 +704,12 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -804,14 +814,14 @@ EOF echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -893,7 +903,7 @@ EOF exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -916,7 +926,7 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -962,6 +972,9 @@ EOF ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -987,6 +1000,9 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; @@ -1019,6 +1035,9 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; @@ -1038,7 +1057,7 @@ EOF echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -1117,7 +1136,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1266,6 +1285,9 @@ EOF SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1279,9 +1301,9 @@ EOF UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in @@ -1303,7 +1325,7 @@ EOF exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1334,7 +1356,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1376,7 +1398,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1387,23 +1409,25 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/contrib/file/config.sub b/contrib/file/config.sub index 8f1229c6f7dd..7e792b4ae17b 100755 --- a/contrib/file/config.sub +++ b/contrib/file/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2015-03-08' +timestamp='2017-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2015-03-08' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,8 +53,7 @@ timestamp='2015-03-08' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. @@ -68,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -118,7 +117,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -255,6 +254,7 @@ case $basic_machine in | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ @@ -301,11 +301,12 @@ case $basic_machine in | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -376,6 +377,7 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ @@ -427,13 +429,15 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -518,7 +522,7 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) + asmjs) basic_machine=asmjs-unknown ;; aux) @@ -641,6 +645,14 @@ case $basic_machine in basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -1020,7 +1032,7 @@ case $basic_machine in ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) @@ -1030,7 +1042,7 @@ case $basic_machine in ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) @@ -1376,18 +1388,18 @@ case $os in | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* | -cloudabi* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ @@ -1396,7 +1408,8 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1528,6 +1541,8 @@ case $os in ;; -nacl*) ;; + -ios) + ;; -none) ;; *) @@ -1623,6 +1638,9 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + pru-*) + os=-elf + ;; *-be) os=-beos ;; diff --git a/contrib/file/configure b/contrib/file/configure index 47f7cbfb8587..eaf97ab0622e 100755 --- a/contrib/file/configure +++ b/contrib/file/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for file 5.29. +# Generated by GNU Autoconf 2.69 for file 5.32. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='file' PACKAGE_TARNAME='file' -PACKAGE_VERSION='5.29' -PACKAGE_STRING='file 5.29' +PACKAGE_VERSION='5.32' +PACKAGE_STRING='file 5.32' PACKAGE_BUGREPORT='christos@astron.com' PACKAGE_URL='' @@ -1328,7 +1328,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures file 5.29 to adapt to many kinds of systems. +\`configure' configures file 5.32 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1398,7 +1398,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of file 5.29:";; + short | recursive ) echo "Configuration of file 5.32:";; esac cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -file configure 5.29 +file configure 5.32 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2165,7 +2165,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by file $as_me 5.29, which was +It was created by file $as_me 5.32, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3031,7 +3031,7 @@ fi # Define the identity of the package. PACKAGE='file' - VERSION='5.29' + VERSION='5.32' cat >>confdefs.h <<_ACEOF @@ -15075,7 +15075,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by file $as_me 5.29, which was +This file was extended by file $as_me 5.32, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15141,7 +15141,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -file config.status 5.29 +file config.status 5.32 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/contrib/file/configure.ac b/contrib/file/configure.ac index da2fbbf5fbfa..946198be643d 100644 --- a/contrib/file/configure.ac +++ b/contrib/file/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([file],[5.29],[christos@astron.com]) +AC_INIT([file],[5.32],[christos@astron.com]) AM_INIT_AUTOMAKE([subdir-objects foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/contrib/file/doc/file.man b/contrib/file/doc/file.man index 6b9abdac87cd..321c995c7c76 100644 --- a/contrib/file/doc/file.man +++ b/contrib/file/doc/file.man @@ -1,4 +1,4 @@ -.\" $File: file.man,v 1.124 2016/10/19 20:52:45 christos Exp $ +.\" $File: file.man,v 1.125 2017/01/03 11:24:46 christos Exp $ .Dd October 19, 2016 .Dt FILE __CSECTION__ .Os @@ -238,8 +238,8 @@ or at least one filename argument must be present; to test the standard input, use .Sq - as a filename argument. -Please note that -.Ar namefile +Please note that +.Ar namefile is unwrapped and the enclosed filenames are processed when this option is encountered and before any further options processing is done. This allows one to process multiple lists of files with different command line @@ -411,10 +411,10 @@ and .Fl h options. .Sh SEE ALSO -.Xr magic __FSECTION__ , .Xr hexdump 1 , .Xr od 1 , .Xr strings 1 , +.Xr magic __FSECTION__ , .Xr fstyp 8 .Sh STANDARDS CONFORMANCE This program is believed to exceed the System V Interface Definition @@ -531,16 +531,15 @@ John Gilmore revised the code extensively, making it better than the first version. Geoff Collyer found several inadequacies and provided some magic file entries. -Contributions by the +Contributions of the .Sq \*[Am] operator by Rob McMahon, .Aq cudcv@warwick.ac.uk , 1989. .Pp -Guy Harris, +Guy Harris, .Aq guy@netapp.com , made many changes from 1993 to the present. -1989. .Pp Primary development and maintenance from 1990 to the present by Christos Zoulas @@ -588,7 +587,6 @@ program, and are not covered by the above license. .Nm returns 0 on success, and non-zero on error. .Sh BUGS -.Pp Please report bugs and send patches to the bug tracker at .Pa http://bugs.gw.com/ or the mailing list at @@ -597,7 +595,6 @@ or the mailing list at .Pa http://mx.gw.com/mailman/listinfo/file first to subscribe). .Sh TODO -.Pp Fix output so that tests for MIME and APPLE flags are not needed all over the place, and actual output is only done in one place. This needs a design. @@ -646,16 +643,16 @@ Fix .Dq name and .Dq use -to check for consistency at compile time (duplicate +to check for consistency at compile time (duplicate .Dq name , .Dq use pointing to undefined .Dq name ). -Make +Make .Dq name / -.Dq use +.Dq use more efficient by keeping a sorted list of names. Special-case ^ to flip endianness in the parser so that it does not have to be escaped, and document it. diff --git a/contrib/file/doc/libmagic.man b/contrib/file/doc/libmagic.man index a3de98139c21..4c7e42ff4f9c 100644 --- a/contrib/file/doc/libmagic.man +++ b/contrib/file/doc/libmagic.man @@ -1,4 +1,4 @@ -.\" $File: libmagic.man,v 1.40 2016/03/31 17:51:12 christos Exp $ +.\" $File: libmagic.man,v 1.41 2017/05/23 21:54:07 christos Exp $ .\" .\" Copyright (c) Christos Zoulas 2003. .\" All Rights Reserved. @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 11, 2015 +.Dd May 23, 2017 .Dt LIBMAGIC 3 .Os .Sh NAME @@ -35,6 +35,7 @@ .Nm magic_errno , .Nm magic_descriptor , .Nm magic_buffer , +.Nm magic_getflags , .Nm magic_setflags , .Nm magic_check , .Nm magic_compile , @@ -64,6 +65,8 @@ .Ft const char * .Fn magic_buffer "magic_t cookie" "const void *buffer" "size_t length" .Ft int +.Fn magic_getflags "magic_t cookie" +.Ft int .Fn magic_setflags "magic_t cookie" "int flags" .Ft int .Fn magic_check "magic_t cookie" "const char *filename" @@ -206,6 +209,12 @@ argument with bytes size. .Pp The +.Fn magic_getflags +functions returns a value representing current +.Ar flags +set. +.Pp +The .Fn magic_setflags function sets the .Ar flags diff --git a/contrib/file/doc/magic.man b/contrib/file/doc/magic.man index bc374040dc2f..4c69bca2ab24 100644 --- a/contrib/file/doc/magic.man +++ b/contrib/file/doc/magic.man @@ -1,5 +1,5 @@ -.\" $File: magic.man,v 1.88 2016/07/27 09:42:49 rrt Exp $ -.Dd July 20, 2016 +.\" $File: magic.man,v 1.91 2017/02/12 15:30:08 christos Exp $ +.Dd February 12, 2017 .Dt MAGIC __FSECTION__ .Os .\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems. @@ -7,7 +7,7 @@ .Nm magic .Nd file command's magic pattern file .Sh DESCRIPTION -This manual page documents the format of the magic file as +This manual page documents the format of magic files as used by the .Xr file __CSECTION__ command, version __VERSION__. @@ -17,13 +17,19 @@ command identifies the type of a file using, among other tests, a test for whether the file contains certain .Dq "magic patterns" . -The file -.Pa __MAGIC__ -specifies what patterns are to be tested for, what message or +The database of these +.Dq "magic patterns" +is usually located in a binary file in +.Pa __MAGIC__.mgc +or a directory of source text magic pattern fragment files in +.Pa __MAGIC__ . +The database specifies what patterns are to be tested for, what message or MIME type to print if a particular pattern is found, and additional information to extract from the file. .Pp -Each line of the file specifies a test to be performed. +The format of the source fragment files that are used to build this database +is as follows: +Each line of a fragment file specifies a test to be performed. A test compares the data starting at a particular offset in the file with a byte value, a string or a numeric value. If the test succeeds, a message is printed. @@ -98,13 +104,13 @@ The following modifiers are supported: .It B A byte length (default). .It H -A 2 byte big endian length. -.It h -A 2 byte big little length. -.It L A 4 byte big endian length. +.It h +A 2 byte big endian length. +.It L +A 4 byte little endian length. .It l -A 4 byte big little length. +A 2 byte little endian length. .It J The length includes itself in its count. .El @@ -651,7 +657,7 @@ start of the main indirect offset. \*[Gt]\*[Gt]\*[Gt]\*[Gt](\*[Am]0xe.l+(-4)) string PK\e3\e4 \eb, ZIP self-extracting archive .Ed .Pp -If you have a list of known avalues at a particular continuation level, +If you have a list of known values at a particular continuation level, and you want to provide a switch-like default case: .Bd -literal -offset indent # clear that continuation level match diff --git a/contrib/file/magic/Localstuff b/contrib/file/magic/Localstuff index 419855fb6220..aef809524b80 100644 --- a/contrib/file/magic/Localstuff +++ b/contrib/file/magic/Localstuff @@ -2,6 +2,6 @@ #------------------------------------------------------------------------------ # Localstuff: file(1) magic for locally observed files # -# $File: Localstuff,v 1.4 2003/03/23 04:17:27 christos Exp $ +# $File: Localstuff,v 1.5 2007/01/12 17:38:27 christos Exp $ # Add any locally observed files here. Remember: # text if readable, executable if runnable binary, data if unreadable. diff --git a/contrib/file/magic/Magdir/adventure b/contrib/file/magic/Magdir/adventure index 94835e11ed39..6fae85adfd40 100644 --- a/contrib/file/magic/Magdir/adventure +++ b/contrib/file/magic/Magdir/adventure @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: adventure,v 1.15 2015/09/07 10:03:21 christos Exp $ +# $File: adventure,v 1.17 2017/07/03 16:03:40 christos Exp $ # adventure: file(1) magic for Adventure game files # # from Allen Garvin @@ -36,11 +36,12 @@ >0 ubyte <9 >>16 belong&0xfe00f0f0 0x3030 >>>0 ubyte < 10 ->>>>2 ubeshort < 10 +>>>>2 ubeshort x >>>>>18 regex [0-9][0-9][0-9][0-9][0-9][0-9] ->>>>>>0 ubyte < 10 Infocom (Z-machine %d, ->>>>>>>2 ubeshort < 10 Release %d / ->>>>>>>>18 string >\0 Serial %.6s) +>>>>>>0 ubyte < 10 Infocom (Z-machine %d +>>>>>>>2 ubeshort x \b, Release %d +>>>>>>>>18 string >\0 \b, Serial %.6s +>>>>>>>>18 string x \b) !:strength + 40 !:mime application/x-zmachine @@ -78,7 +79,7 @@ !:mime application/x-tads # Some saved game files start with "TADS2 save/g\n\r\032\0", a little-endian # 2-byte length N, the N-char name of the game file *without* a NUL (darn!), -# "TADS2 save\n\r\032\0" and the interpreter version. +# "TADS2 save\n\r\032\0" and the interpreter version. 0 string TADS2\ save/g TADS >12 belong !0x0A0D1A00 saved game data, CORRUPTED >12 belong 0x0A0D1A00 @@ -109,7 +110,7 @@ # edited by David Griffith # Danny Milosavljevic # These are ADRIFT (adventure game standard) game files, extension .taf -# Checked from source at (http://www.adrift.co/) and various taf files +# Checked from source at (http://www.adrift.co/) and various taf files # found at the Interactive Fiction Archive (http://ifarchive.org/) 0 belong 0x3C423FC9 >4 belong 0x6A87C2CF Adrift game file version diff --git a/contrib/file/magic/Magdir/amanda b/contrib/file/magic/Magdir/amanda index 395ef545c2ba..e7fa53901388 100644 --- a/contrib/file/magic/Magdir/amanda +++ b/contrib/file/magic/Magdir/amanda @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# $File: amanda,v 1.5 2009/09/19 16:28:07 christos Exp $ +# $File: amanda,v 1.6 2017/03/17 21:35:28 christos Exp $ # amanda: file(1) magic for amanda file format # -0 string AMANDA:\ AMANDA +0 string AMANDA:\ AMANDA >8 string TAPESTART\ DATE tape header file, >>23 string X >>>25 string >\ Unused %s diff --git a/contrib/file/magic/Magdir/amigaos b/contrib/file/magic/Magdir/amigaos index 8fdf37662c57..d9330bd1493c 100644 --- a/contrib/file/magic/Magdir/amigaos +++ b/contrib/file/magic/Magdir/amigaos @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: amigaos,v 1.15 2012/06/21 01:13:59 christos Exp $ +# $File: amigaos,v 1.16 2017/03/17 21:35:28 christos Exp $ # amigaos: file(1) magic for AmigaOS binary formats: # @@ -11,7 +11,7 @@ 0 belong 0x000003e7 AmigaOS object/library data # 0 beshort 0xe310 Amiga Workbench ->2 beshort 1 +>2 beshort 1 >>48 byte 1 disk icon >>48 byte 2 drawer icon >>48 byte 3 tool icon @@ -49,7 +49,7 @@ 0 string/c @database AmigaGuide file # Amiga disk types -# +# 0 string RDSK Rigid Disk Block >160 string x on %.24s 0 string DOS\0 Amiga DOS disk diff --git a/contrib/file/magic/Magdir/android b/contrib/file/magic/Magdir/android index f1340d53a38b..dca5c33482bf 100644 --- a/contrib/file/magic/Magdir/android +++ b/contrib/file/magic/Magdir/android @@ -1,6 +1,6 @@ #------------------------------------------------------------ -# $File: android,v 1.9 2016/01/11 21:19:18 christos Exp $ +# $File: android,v 1.10 2017/03/17 21:35:28 christos Exp $ # Various android related magic entries #------------------------------------------------------------ @@ -61,9 +61,9 @@ # http://forum.xda-developers.com/showthread.php?t=816449 # Partition Information Table for Samsung's smartphone with Android # used by flash software Odin -0 ulelong 0x12349876 +0 ulelong 0x12349876 # 1st pit entry marker ->0x01C ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 +>0x01C ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 # minimal 13 and maximal 18 PIT entries found >>4 ulelong <128 Partition Information Table for Samsung smartphone >>>4 ulelong x \b, %d entries @@ -109,9 +109,9 @@ 0 name PIT-entry # garbage value implies end of pit entries ->0x00 ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 +>0x00 ulequad&0xFFFFFFFCFFFFFFFC =0x0000000000000000 # skip empty partition name ->>0x24 ubyte !0 +>>0x24 ubyte !0 # partition name >>>0x24 string >\0 %-.32s # flags @@ -122,7 +122,7 @@ >>>0x08 ulelong x (0x%x) # filename >>>0x44 string >\0 "%-.64s" -#>>>0x18 ulelong >0 +#>>>0x18 ulelong >0 # blocksize in 512 byte units ? #>>>>0x18 ulelong x \b, %db # partition size in blocks ? diff --git a/contrib/file/magic/Magdir/animation b/contrib/file/magic/Magdir/animation index faa839e8783b..a6e50ff86b09 100644 --- a/contrib/file/magic/Magdir/animation +++ b/contrib/file/magic/Magdir/animation @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: animation,v 1.58 2016/07/03 14:13:11 christos Exp $ +# $File: animation,v 1.63 2017/05/26 14:33:07 christos Exp $ # animation: file(1) magic for animation/movie formats # # animation formats @@ -34,14 +34,23 @@ !:mime image/jp2 # http://www.ftyps.com/ with local additions 4 string ftyp ISO Media +# http://aeroquartet.com/wordpress/2016/03/05/3-xavc-s/ +>8 string XAVC \b, MPEG v4 system, Sony XAVC Codec +>>96 string x \b, Audio "%.4s" +>>118 beshort x at %dHz +>>140 string x \b, Video "%.4s" +>>168 beshort x %d +>>170 beshort x \bx%d >8 string 3g2 \b, MPEG v4 system, 3GPP2 !:mime video/3gpp2 >>11 byte 4 \b v4 (H.263/AMR GSM 6.10) >>11 byte 5 \b v5 (H.263/AMR GSM 6.10) >>11 byte 6 \b v6 (ITU H.264/AMR GSM 6.10) ->>11 byte a \b C.S0050-0 V1.0 ->>11 byte b \b C.S0050-0-A V1.0.0 ->>11 byte c \b C.S0050-0-B V1.0 +# http://www.3gpp2.org/Public_html/Specs/C.S0050-B_v1.0_070521.pdf +# Section 8.1.1, corresponds to a, b, c +>>11 byte 0x61 \b C.S0050-0 V1.0 +>>11 byte 0x62 \b C.S0050-0-A V1.0.0 +>>11 byte 0x63 \b C.S0050-0-B V1.0 >8 string 3ge \b, MPEG v4 system, 3GPP !:mime video/3gpp >>11 byte 6 \b, Release 6 MBMS Extended Presentations @@ -186,13 +195,13 @@ # MPEG sequences # Scans for all common MPEG header start codes -0 belong 0x00000001 +0 belong 0x00000001 >4 byte&0x1F 0x07 JVT NAL sequence, H.264 video >>5 byte 66 \b, baseline >>5 byte 77 \b, main >>5 byte 88 \b, extended >>7 byte x \b @ L %u -0 belong&0xFFFFFF00 0x00000100 +0 belong&0xFFFFFF00 0x00000100 >3 byte 0xBA MPEG sequence !:mime video/mpeg >>4 byte &0x40 \b, v2, program multiplex @@ -493,8 +502,8 @@ # GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448 # GRR this test is still too general as it catches a BOM of UTF-16 files (0xFFFE) # FIXME: Almost all little endian UTF-16 text with BOM are clobbered by these entries -#0 beshort&0xFFFE 0xFFFE -#>2 ubyte&0xF0 >0x0F +#0 beshort&0xFFFE 0xFFFE +#>2 ubyte&0xF0 >0x0F #>>2 ubyte&0xF0 <0xE1 MPEG ADTS, layer I, v1 ## rate #>>>2 byte&0xF0 0x10 \b, 32 kbps @@ -566,9 +575,9 @@ # MP2, M2A 0 beshort&0xFFFE 0xFFF4 MPEG ADTS, layer II, v2 !:mime audio/mpeg -# rate +# rate >2 byte&0xF0 0x10 \b, 8 kbps ->2 byte&0xF0 0x20 \b, 16 kbps +>2 byte&0xF0 0x20 \b, 16 kbps >2 byte&0xF0 0x30 \b, 24 kbps >2 byte&0xF0 0x40 \b, 32 kbps >2 byte&0xF0 0x50 \b, 40 kbps @@ -636,7 +645,7 @@ # MP3, M25A 0 beshort&0xFFFE 0xFFE2 MPEG ADTS, layer III, v2.5 !:mime audio/mpeg -# rate +# rate >2 byte&0xF0 0x10 \b, 8 kbps >2 byte&0xF0 0x20 \b, 16 kbps >2 byte&0xF0 0x30 \b, 24 kbps @@ -855,10 +864,12 @@ # X3D (Extensible 3D) [http://www.web3d.org/specifications/x3d-3.0.dtd] # From Michel Briand -0 string/t \20 search/1000/cw \20 search/1000/w \3 byte x version %d + +# ORC files +# Important information is in file footer, which we can't index to :( +0 string ORC Apache ORC + +# Parquet files +0 string PAR1 Apache Parquet + +# Hive RC files +0 string RCF Apache Hive RC file +>3 byte x version %d + +# Sequence files (and the careless first version of RC file) + +0 string SEQ +>3 byte <6 Apache Hadoop Sequence file version %d +>3 byte >6 Apache Hadoop Sequence file version %d +>3 byte =6 +>>5 string org.apache.hadoop.hive.ql.io.RCFile$KeyBuffer Apache Hive RC file version 0 +>>3 default x Apache Hadoop Sequence file version 6 diff --git a/contrib/file/magic/Magdir/apple b/contrib/file/magic/Magdir/apple index ce03298f95f2..391205f265fc 100644 --- a/contrib/file/magic/Magdir/apple +++ b/contrib/file/magic/Magdir/apple @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: apple,v 1.35 2016/08/17 09:45:13 christos Exp $ +# $File: apple,v 1.36 2017/03/17 21:35:28 christos Exp $ # apple: file(1) magic for Apple file formats # 0 search/1/t FiLeStArTfIlEsTaRt binscii (apple ][) text @@ -67,15 +67,15 @@ # AppleWorks word processor: # URL: https://en.wikipedia.org/wiki/AppleWorks # Reference: http://www.gno.org/pub/apple2/doc/apple/filetypes/ftn.1a.xxxx -# Update: Joerg Jenderek +# Update: Joerg Jenderek # NOTE: # The "O" is really the magic number, but that's so common that it's # necessary to check the tab stops that follow it to avoid false positives. # and/or look for unused bits of booleans bytes like zoom, paginated, mail merge # the newer AppleWorks is from claris with extension CWK -4 string O +4 string O # test for unused bits of zoom- , paginated-boolean bytes ->84 ubequad ^0x00Fe00000000Fe00 +>84 ubequad ^0x00Fe00000000Fe00 # look for tabstop definitions "=" no tab, "|" no tab # "<" left tab,"^" center tab,">" right tab, "." decimal tab, # unofficial "!" other , "\x8a" other @@ -92,9 +92,9 @@ !:ext awp # minimum version needed to read this files. SFMinVers (0 , 30~3.0 ) >>>183 ubyte 30 3.0 ->>>183 ubyte !30 +>>>183 ubyte !30 >>>>183 ubyte !0 0x%x -# usual tabstop start sequence "=====<" +# usual tabstop start sequence "=====<" >>>5 string x \b, tabstop ruler "%6.6s" # tabstop ruler #>>>5 string >\0 \b, tabstops "%-79s" @@ -105,7 +105,7 @@ # contains any mail-merge commands >>>92 byte&0x01 >0 \b, with mail merge # left margin in 1/10 inches ( normally 0 or 10 ) ->>>91 ubyte >0 +>>>91 ubyte >0 >>>>91 ubyte x \b, %d/10 inch left margin # AppleWorks database: @@ -140,13 +140,13 @@ # GRR: this test is still too general as it catches also Gujin BOOT144.SYS (0xfa080000) #0 belong&0xff00ff 0x80000 Applesoft BASIC program data -0 belong&0x00ff00ff 0x00080000 +0 belong&0x00ff00ff 0x00080000 # assuming that line number must be positive >2 leshort >0 Applesoft BASIC program data, first line number %d #>2 leshort x \b, first line number %d # ORCA/EZ assembler: -# +# # This will not identify ORCA/M source files, since those have # some sort of date code instead of the two zero bytes at 6 and 7 # XXX Conflicts with ELF @@ -186,18 +186,18 @@ # From Johan Gade. # These entries are disabled for now until we fix the following issues. # -# Note there might be some problems with the "VAX COFF executable" -# entry. Note this entry should be placed before the mac filesystem section, +# Note there might be some problems with the "VAX COFF executable" +# entry. Note this entry should be placed before the mac filesystem section, # particularly the "Apple Partition data" entry. # -# The intended meaning of these tests is, that the file is only of the +# The intended meaning of these tests is, that the file is only of the # specified type if both of the lines are correct - i.e. if the first # line matches and the second doesn't then it is not of that type. # #0 long 0x7801730d #>4 long 0x62626060 UDIF read-only zlib-compressed image (UDZO) # -# Note that this entry is recognized correctly by the "Apple Partition +# Note that this entry is recognized correctly by the "Apple Partition # data" entry - however since this entry is more specific - this # information seems to be more useful. #0 long 0x45520200 @@ -288,7 +288,7 @@ # Apple disk partition stuff # URL: https://en.wikipedia.org/wiki/Apple_Partition_Map # Reference: https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/sys/bootblock.h -# Update: Joerg Jenderek +# Update: Joerg Jenderek # "ER" is APPLE_DRVR_MAP_MAGIC signature 0 beshort 0x4552 # display Apple Driver Map (strength=50) after Syslinux bootloader (71) @@ -315,7 +315,7 @@ # device id 0 1 (37008 garbage for super_grub2_disk_hybrid_2.02s3.iso) >>10 ubeshort x \b, devid %u # driver data 0 (2425393296 garbage for super_grub2_disk_hybrid_2.02s3.iso) ->>12 ubelong >0 +>>12 ubelong >0 >>>12 ubelong x \b, driver data %u # number of driver descriptors sbDrvrCount <= 61 # (37008 garbage for super_grub2_disk_hybrid_2.02s3.iso) @@ -327,26 +327,26 @@ # >>500 use apple-driver-map # number of partitions is always same in every partition (map block count) #>>0x0204 ubelong x \b, %u partitions ->>0x0204 ubelong >0 \b, contains[@0x200]: +>>0x0204 ubelong >0 \b, contains[@0x200]: >>>0x0200 use apple-apm ->>0x0204 ubelong >1 \b, contains[@0x400]: +>>0x0204 ubelong >1 \b, contains[@0x400]: >>>0x0400 use apple-apm ->>0x0204 ubelong >2 \b, contains[@0x600]: +>>0x0204 ubelong >2 \b, contains[@0x600]: >>>0x0600 use apple-apm ->>0x0204 ubelong >3 \b, contains[@0x800]: +>>0x0204 ubelong >3 \b, contains[@0x800]: >>>0x0800 use apple-apm ->>0x0204 ubelong >4 \b, contains[@0xA00]: +>>0x0204 ubelong >4 \b, contains[@0xA00]: >>>0x0A00 use apple-apm ->>0x0204 ubelong >5 \b, contains[@0xC00]: +>>0x0204 ubelong >5 \b, contains[@0xC00]: >>>0x0C00 use apple-apm ->>0x0204 ubelong >6 \b, contains[@0xE00]: +>>0x0204 ubelong >6 \b, contains[@0xE00]: >>>0x0E00 use apple-apm ->>0x0204 ubelong >7 \b, contains[@0x1000]: +>>0x0204 ubelong >7 \b, contains[@0x1000]: >>>0x1000 use apple-apm # display apple driver descriptor map (start-block, # blocks in sbBlkSize sizes, type) 0 name apple-driver-map ->0 ubequad !0 -# descBlock first block of driver +>0 ubequad !0 +# descBlock first block of driver >>0 ubelong x \b, driver start block %u # descSize driver size in blocks >>4 ubeshort x \b, size %u @@ -355,11 +355,11 @@ # URL: https://en.wikipedia.org/wiki/Apple_Partition_Map # Reference: http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h -# Update: Joerg Jenderek +# Update: Joerg Jenderek # Yes, the 3rd and 4th bytes pmSigPad are reserved, but we use them to make the # magic stronger. # for apple partition map stored as a single file -0 belong 0x504d0000 +0 belong 0x504d0000 # to display Apple Partition Map (strength=70) after Syslinux bootloader (71) #!:strength +0 >0 use apple-apm @@ -417,7 +417,7 @@ 0 name appleworks >0 belong&0x00ffffff 0x07e100 AppleWorks CWK Document >0 belong&0x00ffffff 0x008803 ClarisWorks CWK Document ->0 default x +>0 default x >>0 belong x AppleWorks/ClarisWorks CWK Document >0 byte x \b, version %d >30 beshort x \b, %d diff --git a/contrib/file/magic/Magdir/archive b/contrib/file/magic/Magdir/archive index e737550c76a7..abecf7101f15 100644 --- a/contrib/file/magic/Magdir/archive +++ b/contrib/file/magic/Magdir/archive @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: archive,v 1.103 2016/05/05 17:07:40 christos Exp $ +# $File: archive,v 1.108 2017/08/30 13:45:10 christos Exp $ # archive: file(1) magic for archive formats (see also "msdos" for self- # extracting compressed archives) # @@ -249,9 +249,9 @@ # URL: http://fileformats.archiveteam.org/wiki/TTComp_archive # Update: Joerg Jenderek # GRR: line below is too general as it matches also Panorama database "TCDB 2003-10 demo.pan", others -0 string \0\6 +0 string \0\6 # look for first keyword of Panorama database *.pan ->12 search/261 DESIGN +>12 search/261 DESIGN # skip keyword with low entropy >12 default x TTComp archive, binary, 4K dictionary # (version 5.25) labeled the above entry as "TTComp archive data" @@ -447,9 +447,9 @@ 0 string SZ\x0a\4 SZip archive data # XPack DiskImage # *.XDI updated by Joerg Jenderek Sep 2015 -# ftp://ftp.sac.sk/pub/sac/pack/0index.txt +# ftp://ftp.sac.sk/pub/sac/pack/0index.txt # GRR: this test is still too general as it catches also text files starting with jm -0 string jm +0 string jm # only found examples with this additional characteristic 2 bytes >2 string \x2\x4 Xpack DiskImage archive data #!:ext xdi @@ -462,7 +462,7 @@ # ftp://ftp.elf.stuba.sk/pub/pc/pack/xpa32.zip # created by XPA32.EXE version 1.0.2 for Windows >0 string xpa\0\1 \b32 archive data -# created by XPACK.COM version 1.67m or 1.67r with short 0x1800 +# created by XPACK.COM version 1.67m or 1.67r with short 0x1800 >3 ubeshort !0x0001 \bck archive data # XPack Single Data # changed by Joerg Jenderek Sep 2015 back to like in version 5.12 @@ -552,7 +552,7 @@ >>0x36 string >\0 fstype %.8s # LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu) -# Update: Joerg Jenderek +# Update: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/LHA_(file_format) # Reference: http://web.archive.org/web/20021005080911/http://www.osirusoft.com/joejared/lzhformat.html # @@ -561,14 +561,14 @@ # check 1st character of method id like -lz4- -lh5- or -pm2- >2 string - # check 5th character of method id ->>6 string - +>>6 string - # check header level 0 1 2 3 ->>>20 ubyte <4 +>>>20 ubyte <4 # check 2nd, 3th and 4th character of method id >>>>3 regex \^(lh[0-9a-ex]|lz[s2-8]|pm[012]|pc1) \b !:mime application/x-lzh-compressed # creator type "LHA " -!:apple ????LHA +!:apple ????LHA # display archive type name like "LHa/LZS archive data" or "LArc archive" >>>>>2 string -lz \b !:ext lzs @@ -578,7 +578,7 @@ # missing -lz?- with wikipedia names >>>>>>3 regex \^lz[2378] LArc archive # display archive type name like "LHa (2.x) archive data" ->>>>>2 string -lh \b +>>>>>2 string -lh \b # already known -lh0- -lh1- -lh2- -lh3- -lh4- -lh5- -lh6- -lh7- -lhd- variants with old names >>>>>>3 regex \^lh[01] LHarc 1.x/ARX archive data # LHice archiver use ".ICE" as name extension instead usual one ".lzh" @@ -614,28 +614,28 @@ # check and display information of lharc header 0 name lharc-header # header size 0x4 , 0x1b-0x61 ->0 ubyte x +>0 ubyte x # compressed data size != compressed file size #>7 ulelong x \b, data size %d -# attribute: 0x2~?? 0x10~symlink|target 0x20~normal +# attribute: 0x2~?? 0x10~symlink|target 0x20~normal #>19 ubyte x \b, 19_0x%x # level identifier 0 1 2 3 #>20 ubyte x \b, level %d # time stamp #>15 ubelong x DATE 0x%8.8x # OS ID for level 1 ->20 ubyte 1 +>20 ubyte 1 # 0x20 types find for *.rom files >>(21.b+24) ubyte <0x21 \b, 0x%x OS # ascii type like M for MSDOS >>(21.b+24) ubyte >0x20 \b, '%c' OS # OS ID for level 2 ->20 ubyte 2 +>20 ubyte 2 #>>23 ubyte x \b, OS ID 0x%x >>23 ubyte <0x21 \b, 0x%x OS >>23 ubyte >0x20 \b, '%c' OS # filename only for level 0 and 1 ->20 ubyte <2 +>20 ubyte <2 # length of filename >>21 ubyte >0 \b, with # filename @@ -643,73 +643,73 @@ # #2 string -lh0- LHarc 1.x/ARX archive data [lh0] #!:mime application/x-lharc -2 string -lh0- +2 string -lh0- >0 use lharc-file #2 string -lh1- LHarc 1.x/ARX archive data [lh1] #!:mime application/x-lharc -2 string -lh1- +2 string -lh1- >0 use lharc-file # NEW -lz2- ... -lz8- -2 string -lz2- +2 string -lz2- >0 use lharc-file -2 string -lz3- +2 string -lz3- >0 use lharc-file -2 string -lz4- +2 string -lz4- >0 use lharc-file -2 string -lz5- +2 string -lz5- >0 use lharc-file -2 string -lz7- +2 string -lz7- >0 use lharc-file -2 string -lz8- +2 string -lz8- >0 use lharc-file # [never seen any but the last; -lh4- reported in comp.compression:] #2 string -lzs- LHa/LZS archive data [lzs] -2 string -lzs- +2 string -lzs- >0 use lharc-file # According to wikipedia and others such a version does not exist #2 string -lh\40- LHa 2.x? archive data [lh ] #2 string -lhd- LHa 2.x? archive data [lhd] -2 string -lhd- +2 string -lhd- >0 use lharc-file #2 string -lh2- LHa 2.x? archive data [lh2] -2 string -lh2- +2 string -lh2- >0 use lharc-file #2 string -lh3- LHa 2.x? archive data [lh3] -2 string -lh3- +2 string -lh3- >0 use lharc-file #2 string -lh4- LHa (2.x) archive data [lh4] -2 string -lh4- +2 string -lh4- >0 use lharc-file #2 string -lh5- LHa (2.x) archive data [lh5] -2 string -lh5- +2 string -lh5- >0 use lharc-file #2 string -lh6- LHa (2.x) archive data [lh6] -2 string -lh6- +2 string -lh6- >0 use lharc-file #2 string -lh7- LHa (2.x)/LHark archive data [lh7] -2 string -lh7- +2 string -lh7- # !:mime application/x-lha # >20 byte x - header level %d >0 use lharc-file # NEW -lh8- ... -lhe- , -lhx- -2 string -lh8- +2 string -lh8- >0 use lharc-file -2 string -lh9- +2 string -lh9- >0 use lharc-file -2 string -lha- +2 string -lha- >0 use lharc-file -2 string -lhb- +2 string -lhb- >0 use lharc-file -2 string -lhc- +2 string -lhc- >0 use lharc-file -2 string -lhe- +2 string -lhe- >0 use lharc-file -2 string -lhx- +2 string -lhx- >0 use lharc-file # taken from idarc [JW] 2 string -lZ PUT archive data # already done by LHarc magics -# this should never happen if all sub types of LZS archive are identified +# this should never happen if all sub types of LZS archive are identified #2 string -lz LZS archive data 2 string -sw1- Swag archive data @@ -908,7 +908,17 @@ >>>4 byte 0x0a \b, at least v1.0 to extract >>>4 byte 0x0b \b, at least v1.1 to extract >>>4 byte 0x14 \b, at least v2.0 to extract +>>>4 byte 0x15 \b, at least v2.1 to extract +>>>4 byte 0x19 \b, at least v2.5 to extract +>>>4 byte 0x1b \b, at least v2.7 to extract >>>4 byte 0x2d \b, at least v4.5 to extract +>>>4 byte 0x2e \b, at least v4.6 to extract +>>>4 byte 0x32 \b, at least v5.0 to extract +>>>4 byte 0x33 \b, at least v5.1 to extract +>>>4 byte 0x34 \b, at least v5.2 to extract +>>>4 byte 0x3d \b, at least v6.1 to extract +>>>4 byte 0x3e \b, at least v6.2 to extract +>>>4 byte 0x3f \b, at least v6.3 to extract >>>0x161 string WINZIP \b, WinZIP self-extracting # StarView Metafile @@ -940,17 +950,17 @@ 0 string \0\ \ \ \ \ \ \ \ \ \ \ \0\0 LBR archive data # # PMA (CP/M derivative of LHA) -# Update: Joerg Jenderek +# Update: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/LHA_(file_format) # #2 string -pm0- PMarc archive data [pm0] -2 string -pm0- +2 string -pm0- >0 use lharc-file #2 string -pm1- PMarc archive data [pm1] -2 string -pm1- +2 string -pm1- >0 use lharc-file #2 string -pm2- PMarc archive data [pm2] -2 string -pm2- +2 string -pm2- >0 use lharc-file 2 string -pms- PMarc SFX archive (CP/M, DOS) #!:mime application/x-foobar-exec @@ -1145,12 +1155,12 @@ >3 ubyte 0 \b, no compression >3 ubyte 2 \b, fast compression (Z1) >3 ubyte 3 \b, medium compression (Z2) ->3 ubyte >3 +>3 ubyte >3 >>3 ubyte <11 \b, compression (Z%d-1) ->2 ubyte&0x08 0x00 +>2 ubyte&0x08 0x00 # ~ 30 byte password field only for *.gho >>12 ubequad !0 \b, password protected ->>44 ubyte !1 +>>44 ubyte !1 # 1~Image All, sector-by-sector only for *.gho >>>10 ubyte 1 \b, sector copy # 1~Image Boot track only for *.gho @@ -1160,8 +1170,8 @@ # optional image description only *.gho >>0xff string >\0 "%-.254s" # look for DOS sector end sequence ->0xE08 search/7776 \x55\xAA ->>&-512 indirect x \b; contains +>0xE08 search/7776 \x55\xAA +>>&-512 indirect x \b; contains # Google Chrome extensions # https://developer.chrome.com/extensions/crx @@ -1169,3 +1179,10 @@ 0 string Cr24 Google Chrome extension !:mime application/x-chrome-extension >4 ulong x \b, version %u + +# SeqBox - Sequenced container +# ext: sbx, seqbox +# Marco Pontello marcopon@gmail.com +# reference: https://github.com/MarcoPon/SeqBox +0 string SBx SeqBox, +>3 byte x version %d diff --git a/contrib/file/magic/Magdir/att3b b/contrib/file/magic/Magdir/att3b index a3ed9c0037a9..b83ae2ec08d8 100644 --- a/contrib/file/magic/Magdir/att3b +++ b/contrib/file/magic/Magdir/att3b @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: att3b,v 1.9 2014/04/30 21:41:02 christos Exp $ +# $File: att3b,v 1.10 2017/03/17 21:35:28 christos Exp $ # att3b: file(1) magic for AT&T 3B machines # # The `versions' should be un-commented if they work for you. @@ -36,6 +36,6 @@ #>18 beshort &00040000 and MAU hardware required #>22 beshort >0 - version %d # -# core file for 3b2 +# core file for 3b2 0 string \000\004\036\212\200 3b2 core file >364 string >\0 of '%s' diff --git a/contrib/file/magic/Magdir/audio b/contrib/file/magic/Magdir/audio index 29442a51b3cf..0330bbfa8078 100644 --- a/contrib/file/magic/Magdir/audio +++ b/contrib/file/magic/Magdir/audio @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: audio,v 1.75 2016/02/08 17:30:11 christos Exp $ +# $File: audio,v 1.80 2017/08/13 00:21:47 christos Exp $ # audio: file(1) magic for sound formats (see also "iff") # # Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com), @@ -300,7 +300,7 @@ >>5 byte &0x40 \b, extended header >>5 byte &0x20 \b, experimental >>5 byte &0x10 \b, footer present ->(6.I+10) indirect x \b, contains: +>(6.I+10) indirect x \b, contains: # NSF (NES sound file) magic 0 string NESM\x1a NES Sound File @@ -314,7 +314,7 @@ >122 byte&0x1 =0 NTSC # NSFE (Extended NES sound file) magic -# http://slickproductions.org/docs/NSF/nsfespec.txt +# http://slickproductions.org/docs/NSF/nsfespec.txt # From: David Pflug 0 string NSFE Extended NES Sound File >48 search/0x1000 auth @@ -469,6 +469,8 @@ >>20 byte&0xe 0xc \b, 7 channels >>20 byte&0xe 0xe \b, 8 channels # some common sample rates +>>17 belong&0xfffff0 0x2ee000 \b, 192 kHz +>>17 belong&0xfffff0 0x158880 \b, 88.2 kHz >>17 belong&0xfffff0 0x0ac440 \b, 44.1 kHz >>17 belong&0xfffff0 0x0bb800 \b, 48 kHz >>17 belong&0xfffff0 0x07d000 \b, 32 kHz @@ -658,7 +660,7 @@ # From Fabio R. Schmidlin # VGM music file -0 string Vgm\ +0 string Vgm\040 >9 ubyte >0 VGM Video Game Music dump v >>9 ubyte/16 >0 \b%d >>9 ubyte&0x0F x \b%d @@ -723,7 +725,7 @@ # URL: http://www.garmin.com/ # Reference: http://turboccc.wikispaces.com/share/view/28622555 # NOTE: there exist 2 other Garmin VPM formats -0 string AUDIMG +0 string AUDIMG # skip text files starting with string "AUDIMG" >13 ubyte <13 Garmin Voice Processing Module !:mime audio/x-vpm-wav-garmin @@ -743,16 +745,68 @@ # second of release (0-59) >>9 ubyte x \b:%.2d # if you select a language like german on your garmin device -# you can only select voice modules with correponding language byte ID like 1 +# you can only select voice modules with corresponding language byte ID like 1 >>18 ubyte x \b, language ID %d # pointer to 1st audio WAV sample ->>16 uleshort >0 +>>16 uleshort >0 >>>(16.s) ulelong >0 \b, at offset 0x%x # WAV length >>>>(16.s+4) ulelong >0 %d Bytes # look for magic ->>>>>(&-8.l) string RIFF +>>>>>(&-8.l) string RIFF # determine type by ./riff ->>>>>>&-4 indirect x \b +>>>>>>&-4 indirect x \b # 2 - ~ 131 WAV samples following same way +# From Martin Mueller Skarbiniks Pedersen +0 string GDM +>0x3 byte 0xFE General Digital Music. +>0x4 string >\0 title: "%s" +>0x24 string >\0 musician: "%s" +>>0x44 beshort 0x0D0A +>>>0x46 byte 0x1A +>>>>0x47 string GMFS Version +>>>>0x4B byte x %d. +>>>>0x4C byte x \b%02d +>>>>0x4D beshort 0x000 (2GDM v +>>>>0x4F byte x \b%d. +>>>>>0x50 byte x \b%d) + +0 string MTM Multitracker +>0x3 byte/16 x Version %d. +>0x3 byte&0x0F x \b%02d +>>0x4 string >\0 title: "%s" + +0 string HVL +>3 byte <2 Hively Tracker Song +>3 byte 0 1 module data +>3 byte 1 2 module data + +0 string MO3 +>3 ubyte <6 MOdule with MP3 +>>3 byte 0 Version 0 (With MP3 and lossless) +>>3 byte 1 Version 1 (With ogg and lossless) +>>3 byte 3 Version 2.2 +>>3 byte 4 (With no LAME header) +>>3 byte 5 Version 2.4 + +0 string ADRVPACK AProSys module + +# ftp://ftp.modland.com/pub/documents/format_documentation/\ +# Art%20Of%20Noise%20(.aon).txt +0 string AON +>4 string "ArtOfNoise by Bastian Spiegel(twice/lego)" +>0x2e string NAME Art of Noise Tracker Song +>3 string <9 +>3 string 4 (4 voices) +>3 string 8 (8 voices) +>>0x36 string >\0 Title: "%s" + +0 string FAR +>0x2c byte 0x0d +>0x2d byte 0x0a +>0x2e byte 0x1a +>>0x3 byte 0xFE Farandole Tracker Song +>>>0x31 byte/16 x Version %d. +>>>0x31 byte&0x0F x \b%02d +>>>>0x4 string >\0 \b, title: "%s" diff --git a/contrib/file/magic/Magdir/bhl b/contrib/file/magic/Magdir/bhl new file mode 100644 index 000000000000..6f57f0343395 --- /dev/null +++ b/contrib/file/magic/Magdir/bhl @@ -0,0 +1,10 @@ + +#------------------------------------------------------------------------------ +# $File: bhl,v 1.1 2017/06/11 22:20:02 christos Exp $ +# BlockHashLoc +# ext: bhl +# Marco Pontello marcopon@gmail.com +# reference: https://github.com/MarcoPon/BlockHashLoc +0 string BlockHashLoc\x1a BlockHashLoc recovery info, +>13 byte x version %d +!:ext bhl diff --git a/contrib/file/magic/Magdir/blackberry b/contrib/file/magic/Magdir/blackberry index 4a61d4e98cfa..2e38a54f42d6 100644 --- a/contrib/file/magic/Magdir/blackberry +++ b/contrib/file/magic/Magdir/blackberry @@ -1,8 +1,8 @@ #------------------------------------------------------------------------------ -# $File: blackberry,v 1.1 2014/01/31 01:51:32 christos Exp $ +# $File: blackberry,v 1.2 2017/03/17 21:35:28 christos Exp $ # blackberry: file(1) magic for BlackBerry file formats # -5 belong 0 +5 belong 0 >8 belong 010010010 BlackBerry RIM ETP file >>22 string x \b for %s diff --git a/contrib/file/magic/Magdir/blender b/contrib/file/magic/Magdir/blender index 5b9c8556e521..09485702b15b 100644 --- a/contrib/file/magic/Magdir/blender +++ b/contrib/file/magic/Magdir/blender @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# $File: blender,v 1.6 2014/08/30 08:34:17 christos Exp $ +# $File: blender,v 1.7 2017/03/17 21:35:28 christos Exp $ # blender: file(1) magic for Blender 3D related files # -# Native format rule v1.2. For questions use the developers list +# Native format rule v1.2. For questions use the developers list # http://lists.blender.org/mailman/listinfo/bf-committers -# GLOB chunk was moved near start and provides subversion info since 2.42 +# GLOB chunk was moved near start and provides subversion info since 2.42 0 string =BLENDER Blender3D, >7 string =_ saved as 32-bits diff --git a/contrib/file/magic/Magdir/c-lang b/contrib/file/magic/Magdir/c-lang index bb594b069fc7..7b3f703ef3ec 100644 --- a/contrib/file/magic/Magdir/c-lang +++ b/contrib/file/magic/Magdir/c-lang @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: c-lang,v 1.24 2016/07/01 23:31:13 christos Exp $ +# $File: c-lang,v 1.26 2017/08/14 07:40:38 christos Exp $ # c-lang: file(1) magic for C and related languages programs # # The strength is to beat standard HTML @@ -11,49 +11,72 @@ !:mime text/x-bcpl # C -0 regex \^#include C source text -!:strength +25 +# Check for class if include is found, otherwise class is beaten by include becouse of lowered strength +0 regex \^#include C +>0 regex \^class[[:space:]]+ +>>&0 regex \\{[\.\*]\\}(;)?$ \b++ +>&0 clear x source text +!:strength + 13 !:mime text/x-c -0 regex \^char[\ \t\n]+ C source text +0 regex \^#[[:space:]]*pragma C source text !:mime text/x-c -0 regex \^double[\ \t\n]+ C source text +0 regex \^#[[:space:]]*(if\|ifn)def +>&0 regex \^#[[:space:]]*endif$ C source text !:mime text/x-c -0 regex \^extern[\ \t\n]+ C source text +0 regex \^#[[:space:]]*(if\|ifn)def +>&0 regex \^#[[:space:]]*define C source text !:mime text/x-c -0 regex \^float[\ \t\n]+ C source text +0 regex \^[[:space:]]*char(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text !:mime text/x-c -0 regex \^struct[\ \t\n]+ C source text +0 regex \^[[:space:]]*double(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text !:mime text/x-c -0 regex \^union[\ \t\n]+ C source text +0 regex \^[[:space:]]*extern[[:space:]]+ C source text !:mime text/x-c -0 search/8192 main( C source text +0 regex \^[[:space:]]*float(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text +!:mime text/x-c +0 regex \^struct[[:space:]]+ C source text +!:mime text/x-c +0 regex \^union[[:space:]]+ C source text +!:mime text/x-c +0 search/8192 main( +>&0 regex \\)[[:space:]]*\\{ C source text !:mime text/x-c # C++ # The strength of these rules is increased so they beat the C rules above -0 regex \^template[\ \t]+<.*>[\ \t\n]+ C++ source text +0 regex \^namespace[[:space:]]+[_[:alpha:]]{1,30}[[:space:]]*\\{ C++ source text !:strength + 30 !:mime text/x-c++ -0 regex \^virtual[\ \t\n]+ C++ source text +# using namespace [namespace] or using std::[lib] +0 regex \^using[[:space:]]+(namespace\ )?std(::)?[[:alpha:]]*[[:space:]]*; C++ source text !:strength + 30 !:mime text/x-c++ -0 regex \^class[\ \t\n]+ C++ source text -# But class is reduced to avoid beating php (Jens Schleusener) +0 regex \^[[:space:]]*template[[:space:]]*<.*>[[:space:]]*$ C++ source text +!:strength + 30 +!:mime text/x-c++ +0 regex \^[[:space:]]*virtual[[:space:]]+.*[};][[:space:]]*$ C++ source text +!:strength + 30 +!:mime text/x-c++ +# But class alone is reduced to avoid beating php (Jens Schleusener) +0 regex \^[[:space:]]*class[[:space:]]+[[:digit:][:alpha:]:_]+[[:space:]]*\\{(.*[\n]*)*\\}(;)?$ C++ source text !:strength + 13 !:mime text/x-c++ -0 regex \^public: C++ source text +0 regex \^[[:space:]]*public: C++ source text !:strength + 30 !:mime text/x-c++ -0 regex \^private: C++ source text +0 regex \^[[:space:]]*private: C++ source text +!:strength + 30 +!:mime text/x-c++ +0 regex \^[[:space:]]*protected: C++ source text !:strength + 30 !:mime text/x-c++ # Objective-C -0 regex \^#import Objective-C source text -!:strength +25 +0 regex \^#import Objective-C source text +!:strength + 25 !:mime text/x-objective-c -# From: Mikhail Teterin +# From: Mikhail Teterin 0 string cscope cscope reference data >7 string x version %.2s # We skip the path here, because it is often long (so file will diff --git a/contrib/file/magic/Magdir/cad b/contrib/file/magic/Magdir/cad index 9b09fd7a1917..daafba9d444c 100644 --- a/contrib/file/magic/Magdir/cad +++ b/contrib/file/magic/Magdir/cad @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: cad,v 1.13 2014/03/23 18:05:38 christos Exp $ +# $File: cad,v 1.15 2017/06/24 15:24:56 christos Exp $ # autocad: file(1) magic for cad files # @@ -9,7 +9,7 @@ # DGN is the default file extension of Microstation/Intergraph CAD files. # CIT is the proprietary raster format (similar to TIFF) used to attach # raster underlays to Microstation DGN (vector) drawings. -# +# # http://www.wotsit.org/search.asp # http://filext.com/detaillist.php?extdetail=DGN # http://filext.com/detaillist.php?extdetail=CIT @@ -42,7 +42,7 @@ >4 string \030\000\000 CITFile >4 string \030\000\003 CITFile -# AutoCAD +# AutoCAD # Merge of the different contributions and updates from http://en.wikipedia.org/wiki/Dwg # and http://www.iana.org/assignments/media-types/image/vnd.dwg 0 string MC0.0 DWG AutoDesk AutoCAD Release 1.0 @@ -99,42 +99,42 @@ 0 string AC1027 DWG AutoDesk AutoCAD 2013/2014 !:mime image/vnd.dwg -# KOMPAS 2D drawing from ASCON +# KOMPAS 2D drawing from ASCON # This is KOMPAS 2D drawing or fragment of drawing but is not detailed nor # gathered nor specification # ASCON http://ascon.net/main/ in English, # http://ascon.ru/ main site in Russian -# Extension is CDW for drawing and FRW for fragment of drawing +# Extension is CDW for drawing and FRW for fragment of drawing # Sergey Zaykov (mail_of_sergey@mail.ru, sergey_zaikov@rambler.ru, # ICQ 358572321, http://vkontakte.ru/id16076543) # From: # http://sd.ascon.ru/otrs/customer.pl?Action=CustomerFAQ&CategoryID=4&ItemID=292 # (in russian) and my experiments 0 string KF ->2 belong 0x4E00000C Kompas drawing 12.0 SP1 ->2 belong 0x4D00000C Kompas drawing 12.0 ->2 belong 0x3200000B Kompas drawing 11.0 SP1 ->2 belong 0x3100000B Kompas drawing 11.0 ->2 belong 0x2310000A Kompas drawing 10.0 SP1 ->2 belong 0x2110000A Kompas drawing 10.0 ->2 belong 0x08000009 Kompas drawing 9.0 SP1 ->2 belong 0x05000009 Kompas drawing 9.0 ->2 belong 0x33010008 Kompas drawing 8+ ->2 belong 0x1A000008 Kompas drawing 8.0 ->2 belong 0x2C010107 Kompas drawing 7+ ->2 belong 0x05000007 Kompas drawing 7.0 ->2 belong 0x32000006 Kompas drawing 6+ ->2 belong 0x09000006 Kompas drawing 6.0 ->2 belong 0x5C009005 Kompas drawing 5.11R03 ->2 belong 0x54009005 Kompas drawing 5.11R02 ->2 belong 0x51009005 Kompas drawing 5.11R01 ->2 belong 0x22009005 Kompas drawing 5.10R03 ->2 belong 0x22009005 Kompas drawing 5.10R02 mar ->2 belong 0x21009005 Kompas drawing 5.10R02 febr ->2 belong 0x19009005 Kompas drawing 5.10R01 ->2 belong 0xF4008005 Kompas drawing 5.9R01.003 ->2 belong 0x1C008005 Kompas drawing 5.9R01.002 ->2 belong 0x11008005 Kompas drawing 5.8R01.003 +>2 belong 0x4E00000C Kompas drawing 12.0 SP1 +>2 belong 0x4D00000C Kompas drawing 12.0 +>2 belong 0x3200000B Kompas drawing 11.0 SP1 +>2 belong 0x3100000B Kompas drawing 11.0 +>2 belong 0x2310000A Kompas drawing 10.0 SP1 +>2 belong 0x2110000A Kompas drawing 10.0 +>2 belong 0x08000009 Kompas drawing 9.0 SP1 +>2 belong 0x05000009 Kompas drawing 9.0 +>2 belong 0x33010008 Kompas drawing 8+ +>2 belong 0x1A000008 Kompas drawing 8.0 +>2 belong 0x2C010107 Kompas drawing 7+ +>2 belong 0x05000007 Kompas drawing 7.0 +>2 belong 0x32000006 Kompas drawing 6+ +>2 belong 0x09000006 Kompas drawing 6.0 +>2 belong 0x5C009005 Kompas drawing 5.11R03 +>2 belong 0x54009005 Kompas drawing 5.11R02 +>2 belong 0x51009005 Kompas drawing 5.11R01 +>2 belong 0x22009005 Kompas drawing 5.10R03 +>2 belong 0x22009005 Kompas drawing 5.10R02 mar +>2 belong 0x21009005 Kompas drawing 5.10R02 febr +>2 belong 0x19009005 Kompas drawing 5.10R01 +>2 belong 0xF4008005 Kompas drawing 5.9R01.003 +>2 belong 0x1C008005 Kompas drawing 5.9R01.002 +>2 belong 0x11008005 Kompas drawing 5.8R01.003 # CAD: file(1) magic for computer aided design files # Phillip Griffith @@ -147,8 +147,13 @@ >0x02 byte 0xfe >>0x04 beshort 0x1800 CIT raster CAD -# 3DS (3d Studio files) Conflicts with diff output 0x3d '=' -#16 beshort 0x3d3d image/x-3ds +# 3DS (3d Studio files) +0 leshort 0x4d4d +>6 leshort 0x2 +>>8 lelong 0xa +>>>16 leshort 0x3d3d 3D Studio model +!:mime image/x-3ds +!:extension 3ds # MegaCAD 2D/3D drawing (.prt) # http://megacad.de/ diff --git a/contrib/file/magic/Magdir/cafebabe b/contrib/file/magic/Magdir/cafebabe index 6d97cebc4fa1..6482858fc62c 100644 --- a/contrib/file/magic/Magdir/cafebabe +++ b/contrib/file/magic/Magdir/cafebabe @@ -1,14 +1,14 @@ #------------------------------------------------------------------------------ -# $File: cafebabe,v 1.21 2015/10/15 20:56:51 christos Exp $ +# $File: cafebabe,v 1.23 2017/05/25 20:07:23 christos Exp $ # Cafe Babes unite! # # Since Java bytecode and Mach-O universal binaries have the same magic number, # the test must be performed in the same "magic" sequence to get both right. # The long at offset 4 in a Mach-O universal binary tells the number of # architectures; the short at offset 4 in a Java bytecode file is the JVM minor -# version and the short at offset 6 is the JVM major version. Since there are only -# only 18 labeled Mach-O architectures at current, and the first released +# version and the short at offset 6 is the JVM major version. Since there are only +# only 18 labeled Mach-O architectures at current, and the first released # Java class format was version 43.0, we can safely choose any number # between 18 and 39 to test the number of architectures against # (and use as a hack). Let's not use 18, because the Mach-O people @@ -47,7 +47,7 @@ 0 name mach-o \b [ >0 use mach-o-cpu \b ->(8.L) indirect \b: +>(8.L) indirect x \b: >0 belong x \b] 0 belong 0xcafebabe diff --git a/contrib/file/magic/Magdir/clipper b/contrib/file/magic/Magdir/clipper index 98278ebf0615..2768b3af501d 100644 --- a/contrib/file/magic/Magdir/clipper +++ b/contrib/file/magic/Magdir/clipper @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------ -# $File: clipper,v 1.7 2014/04/30 21:41:02 christos Exp $ +# $File: clipper,v 1.8 2017/03/17 21:35:28 christos Exp $ # clipper: file(1) magic for Intergraph (formerly Fairchild) Clipper. # # XXX - what byte order does the Clipper use? # # XXX - what's the "!" stuff: # -# >18 short !074000,000000 C1 R1 +# >18 short !074000,000000 C1 R1 # >18 short !074000,004000 C2 R1 # >18 short !074000,010000 C3 R1 # >18 short !074000,074000 TEST @@ -15,7 +15,7 @@ # I shall assume it's ANDing the field with the first value and # comparing it with the second, and rewrite it as: # -# >18 short&074000 000000 C1 R1 +# >18 short&074000 000000 C1 R1 # >18 short&074000 004000 C2 R1 # >18 short&074000 010000 C3 R1 # >18 short&074000 074000 TEST @@ -37,7 +37,7 @@ >12 long >0 not stripped >22 short >0 - version %d 0 short 0577 CLIPPER COFF executable ->18 short&074000 000000 C1 R1 +>18 short&074000 000000 C1 R1 >18 short&074000 004000 C2 R1 >18 short&074000 010000 C3 R1 >18 short&074000 074000 TEST diff --git a/contrib/file/magic/Magdir/coff b/contrib/file/magic/Magdir/coff index 02cbf9ce7413..b4addec58ffd 100644 --- a/contrib/file/magic/Magdir/coff +++ b/contrib/file/magic/Magdir/coff @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: coff,v 1.1 2015/09/30 20:32:35 christos Exp $ +# $File: coff,v 1.2 2017/03/17 21:35:28 christos Exp $ # coff: file(1) magic for Common Object Files not specific to known cpu types or manufactures # # COFF @@ -15,7 +15,7 @@ # mips,motorola,msdos,osf1,sharc,varied.out,vax 0 name display-coff # test for unused flag bits (0x8000,0x0800,0x0400,0x0200,x0080) in f_flags ->18 uleshort&0x8E80 0 +>18 uleshort&0x8E80 0 >>0 clear x # f_magic - magic number # DJGPP, 80386 COFF executable, MS Windows COFF Intel 80386 object file (./intel) @@ -25,7 +25,7 @@ # Hitachi SH little-endian COFF (./hitachi-sh) >>0 uleshort 0x0550 Hitachi SH little-endian # executable (RISC System/6000 V3.1) or obj module (./ibm6000) -#>>0 uleshort 0x01DF +#>>0 uleshort 0x01DF # TODO for other COFFs #>>0 uleshort 0xABCD COFF_TEMPLATE >>0 default x @@ -45,12 +45,12 @@ >>18 leshort &0x0008 \b, stripped >>18 leshort ^0x0008 \b, not stripped # flags in other COFF versions -#0x0010 F_FDPR_PROF +#0x0010 F_FDPR_PROF #0x0020 F_FDPR_OPTI #0x0040 F_DSA # F_AR32WR flag bit #>>>18 leshort &0x0100 \b, 32 bit little endian -#0x1000 F_DYNLOAD +#0x1000 F_DYNLOAD #0x2000 F_SHROBJ #0x4000 F_LOADONLY # f_nscns - number of sections @@ -62,7 +62,7 @@ >>8 ulelong >0 \b, symbol offset=0x%x # f_nsyms - number of symbols, only for not stripped >>12 ulelong >0 \b, %d symbols -# f_opthdr - optional header size +# f_opthdr - optional header size >>16 uleshort >0 \b, optional header size %d # at offset 20 can be optional header, extra bytes FILHSZ-20 because # do not rely on sizeof(FILHDR) to give the correct size for header. diff --git a/contrib/file/magic/Magdir/commands b/contrib/file/magic/Magdir/commands index 48d706358c0e..f6ad1c878a31 100644 --- a/contrib/file/magic/Magdir/commands +++ b/contrib/file/magic/Magdir/commands @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: commands,v 1.56 2016/07/14 19:01:12 christos Exp $ +# $File: commands,v 1.59 2017/08/14 07:40:38 christos Exp $ # commands: file(1) magic for various shells and interpreters # #0 string/w : shell archive or script for antique kernel text @@ -56,7 +56,7 @@ !:mime text/x-awk 0 string/wt #!\ /usr/bin/awk awk script text executable !:mime text/x-awk -0 regex/4096 =^\\s{0,100}BEGIN\\s{0,100}[{] awk or perl script text +0 regex/4096 =^[\040\t\f\r\n]{0,100}BEGIN[\040\t\f\r\n]{0,100}[{] awk or perl script text # AT&T Bell Labs' Plan 9 shell 0 string/wt #!\ /bin/rc Plan 9 rc shell script text executable @@ -84,7 +84,7 @@ # PHP scripts # Ulf Harnhammar 0 search/1/c =(4.l+8) indirect +>(4.l+8) indirect x # Zstandard Dictionary ID subroutine 0 name zstd-dictionary-id @@ -310,7 +310,7 @@ # Zlib https://www.ietf.org/rfc/rfc6713.txt 0 string/b x ->0 beshort%31 =0 +>0 beshort%31 =0 >>0 byte&0xf =8 >>>0 byte&0x80 =0 zlib compressed data !:mime application/zlib diff --git a/contrib/file/magic/Magdir/console b/contrib/file/magic/Magdir/console index 2a1c9af7f035..66f5dbda294e 100644 --- a/contrib/file/magic/Magdir/console +++ b/contrib/file/magic/Magdir/console @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: console,v 1.26 2016/06/12 15:20:37 christos Exp $ +# $File: console,v 1.32 2017/08/13 00:21:47 christos Exp $ # Console game magic # Toby Deshane @@ -9,17 +9,19 @@ # References: # - http://wiki.nesdev.com/w/index.php/INES # - http://wiki.nesdev.com/w/index.php/NES_2.0 -0 string NES\x1A iNES ROM image + +# Common header for iNES, NES 2.0, and Wii U iNES. +0 name nes-rom-image-ines >7 byte&0x0C =0x8 (NES 2.0) >4 byte x \b: %ux16k PRG ->5 byte x \b, %ux16k CHR +>5 byte x \b, %ux8k CHR >6 byte&0x08 =0x8 [4-Scr] >6 byte&0x09 =0x0 [H-mirror] >6 byte&0x09 =0x1 [V-mirror] >6 byte&0x02 =0x2 [SRAM] >6 byte&0x04 =0x4 [Trainer] >7 byte&0x03 =0x2 [PC10] ->7 byte&0x03 =0x1 [VS +>7 byte&0x03 =0x1 [VS] >>7 byte&0x0C =0x8 # NES 2.0: VS PPU >>>13 byte&0x0F =0x0 \b, RP2C03B @@ -43,17 +45,24 @@ >>12 byte&0x03 =0x1 [PAL] >>12 byte&0x02 =0x2 [NTSC+PAL] +# Standard iNES ROM header. +0 string NES\x1A NES ROM image (iNES) +>0 use nes-rom-image-ines + +# Wii U Virtual Console iNES ROM header. +0 belong 0x4E455300 NES ROM image (Wii U Virtual Console) +>0 use nes-rom-image-ines + #------------------------------------------------------------------------------ # unif: file(1) magic for UNIF-format Nintendo Entertainment System ROM images # Reference: http://wiki.nesdev.com/w/index.php/UNIF # From: David Korth -# TODO commit on 2016/03/21 # # NOTE: The UNIF format uses chunks instead of a fixed header, # so most of the data isn't easily parseable. # 0 string UNIF ->4 lelong <16 UNIF v%d format NES ROM image +>4 lelong <16 NES ROM image (UNIF v%d format) #------------------------------------------------------------------------------ # fds: file(1) magic for Famciom Disk System disk images @@ -63,24 +72,39 @@ # Disk info block. (block 1) 0 name nintendo-fds-disk-info-block ->1 string *NINTENDO-HVC* Famicom Disk System disk image: >23 byte !1 FMC- >23 byte 1 FSC- >16 string x \b%.3s ->15 byte x \b, mfr 0x%02X +>15 byte x \b, mfr %02X >20 byte x (Rev.%02u) # Headered version. 0 string FDS\x1A ->0x11 string *NINTENDO-HVC* +>0x11 string *NINTENDO-HVC* Famicom Disk System disk image: >>0x10 use nintendo-fds-disk-info-block >4 byte 1 (%u side) >4 byte !1 (%u sides) # Unheadered version. -1 string *NINTENDO-HVC* +1 string *NINTENDO-HVC* Famicom Disk System disk image: >0 use nintendo-fds-disk-info-block +#------------------------------------------------------------------------------ +# tnes: file(1) magic for TNES-format Nintendo Entertainment System ROM images +# Used by Nintendo 3DS NES Virtual Console games. +# From: David Korth +# +0 string TNES NES ROM image (Nintendo 3DS Virtual Console) +>4 byte 100 \b: FDS, +>>0x2010 use nintendo-fds-disk-info-block +>4 byte !100 \b: TNES mapper %u +>>5 byte x \b, %ux8k PRG +>>6 byte x \b, %ux8k CHR +>>7 byte&0x08 =1 [WRAM] +>>8 byte&0x09 =1 [H-mirror] +>>8 byte&0x09 =2 [V-mirror] +>>8 byte&0x02 =3 [VRAM] + #------------------------------------------------------------------------------ # gameboy: file(1) magic for the Nintendo (Color) Gameboy raw ROM format # Reference: http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header @@ -389,6 +413,15 @@ >0x1E byte x \b, Rev.%02u) >0x12 byte 2 (DSi enhanced) >0x12 byte 3 (DSi only) +# Secure Area check. +>0x20 lelong <0x4000 (homebrew) +>0x20 lelong >0x3FFF +>>0x4000 lequad 0x0000000000000000 (multiboot) +>>0x4000 lequad !0x0000000000000000 +>>>0x4000 lequad 0xE7FFDEFFE7FFDEFF (decrypted) +>>>0x4000 lequad !0xE7FFDEFFE7FFDEFF +>>>>0x1000 lequad 0x0000000000000000 (encrypted) +>>>>0x1000 lequad !0x0000000000000000 (mask ROM) #------------------------------------------------------------------------------ # nds_passme: file(1) magic for Nintendo DS ROM images for GBA cartridge boot. @@ -412,7 +445,7 @@ #------------------------------------------------------------------------------ # msx: file(1) magic for MSX game cartridge dumps # Too simple - MPi -#0 beshort 0x4142 MSX game cartridge dump +#0 beshort 0x4142 MSX game cartridge dump #------------------------------------------------------------------------------ # Sony Playstation executables (Adam Sjoegren ) : @@ -467,7 +500,7 @@ # Double-check that the image type matches too, 0x8008 conflicts with # 8 character OMF-86 object file headers. -0 beshort 0x8008 +0 beshort 0x8008 >6 string BS93 Lynx homebrew cartridge >>2 beshort x \b, RAM start $%04x >6 string LYNX Lynx cartridge @@ -482,7 +515,7 @@ # is the offset 12 or the offset 16 correct? # GBS (Game Boy Sound) magic # ftp://ftp.modland.com/pub/documents/format_documentation/\ -# Gameboy%20Sound%20System%20(.gbs).txt +# Gameboy%20Sound%20System%20(.gbs).txt 0 string GBS Nintendo Gameboy Music/Audio Data #12 string GameBoy\ Music\ Module Nintendo Gameboy Music Module >16 string >\0 ("%s" by @@ -491,6 +524,10 @@ >3 byte x version %d, >4 byte x %d tracks +# IPS Patch Files from: From: Thomas Klausner +# see http://zerosoft.zophar.net/ips.php +0 string PATCH IPS patch file + # Playstations Patch Files from: From: Thomas Klausner 0 string PPF30 Playstation Patch File version 3.0 >5 byte 0 \b, PPF 1.0 patch @@ -518,7 +555,7 @@ # SNES9x .smv "movie" file format. 0 string SMV\x1A SNES9x input recording >0x4 lelong x \b, version %d -# version 4 is latest so far +# version 4 is latest so far >0x4 lelong <5 >>0x8 ledate x \b, recorded at %s >>0xc lelong >0 \b, rerecorded %d times @@ -617,6 +654,52 @@ >0x218 belong 0x5D1C9EA3 Nintendo Wii disc image (WBFS format): >>0x200 use nintendo-gcn-disc-common +# Type: Nintendo GameCube/Wii disc image (CISO format) +# NOTE: This is NOT the same as Compact ISO or PSP CISO, +# though it has the same magic number. +0 string CISO +# Other fields are used to determine what type of CISO this is: +# - 0x04 == 0x00200000: GameCube/Wii CISO (block_size) +# - 0x10 == 0x00000800: PSP CISO (ISO-9660 sector size) +# - None of the above: Compact ISO. +>4 lelong 0x200000 +>>8 byte 1 +>>>0x801C belong 0xC2339F3D Nintendo GameCube disc image (CISO format): +>>>>0x8000 use nintendo-gcn-disc-common +>>>0x8018 belong 0x5D1C9EA3 Nintendo Wii disc image (CISO format): +>>>>0x8000 use nintendo-gcn-disc-common + +# Type: Nintendo GameCube/Wii disc image (GCZ format) +# Due to zlib compression, we can't get the actual disc information. +0 lelong 0xB10BC001 +>4 lelong 0 Nintendo GameCube disc image (GCZ format) +>4 lelong 1 Nintendo Wii disc image (GCZ format) +>4 lelong >1 Nintendo GameCube/Wii disc image (GCZ format) + +# Type: Nintendo GameCube/Wii disc image (WDF format) +0 string WII\001DISC +>8 belong 1 +# WDFv1 +>>0x54 belong 0xC2339F3D Nintendo GameCube disc image (WDFv1 format): +>>>0x38 use nintendo-gcn-disc-common +>>0x58 belong 0x5D1C9EA3 Nintendo Wii disc image (WDFv1 format): +>>>0x38 use nintendo-gcn-disc-common +>8 belong 2 +# WDFv2 +>>(12.L+0x1C) belong 0xC2339F3D Nintendo GameCube disc image (WDFv2 format): +>>>(12.L) use nintendo-gcn-disc-common +>>(12.L+0x18) belong 0x5D1C9EA3 Nintendo Wii disc image (WDFv2 format): +>>>(12.L) use nintendo-gcn-disc-common + +# Type: Nintendo GameCube/Wii disc image (WIA format) +0 string WIA\001 Nintendo +>0x48 belong 0 GameCube/Wii +>0x48 belong 1 GameCube +>0x48 belong 2 Wii +>0x48 belong >2 GameCube/Wii +>0x48 belong x disc image (WIA format): +>>0x58 use nintendo-gcn-disc-common + #------------------------------------------------------------------------------ # Nintendo 3DS file formats. # @@ -722,7 +805,7 @@ # Type: Nintendo 3DS Homebrew Application. # From: David Korth -# Refernece: https://3dbrew.org/wiki/3DSX_Format +# Reference: https://3dbrew.org/wiki/3DSX_Format 0 string 3DSX Nintendo 3DS Homebrew Application (3DSX) #------------------------------------------------------------------------------ @@ -750,3 +833,17 @@ # 0 string g\ GCE Vectrex ROM image >0x11 string >\0 \b: "%.16s" + +#------------------------------------------------------------------------------ +# amiibo: file(1) magic for Nintendo amiibo NFC dumps. +# From: David Korth +# Reference: https://www.3dbrew.org/wiki/Amiibo +0x00 byte 0x04 +>0x0A beshort 0x0FE0 +>>0x0C belong 0xF110FFEE +>>>0x208 beshort 0x0100 +>>>>0x020A byte 0x0F +>>>>>0x020C bequad 0x000000045F000000 +>>>>>>0x5B byte 0x02 +>>>>>>>0x54 belong x Nintendo amiibo NFC dump - amiibo ID: %08X- +>>>>>>>0x58 belong x \b%08X diff --git a/contrib/file/magic/Magdir/cups b/contrib/file/magic/Magdir/cups index 4d0056bb4b57..a065de39637d 100644 --- a/contrib/file/magic/Magdir/cups +++ b/contrib/file/magic/Magdir/cups @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: cups,v 1.4 2016/10/17 18:51:02 christos Exp $ +# $File: cups,v 1.5 2017/03/17 21:35:28 christos Exp $ # Cups: file(1) magic for the cups raster file format # From: Laurent Martelli # http://www.cups.org/documentation.php/spec-raster.html @@ -39,7 +39,7 @@ >404 lelong 20 ColorSpace=AdobeRGB # Cups Raster image format, Big Endian -0 string RaS +0 string RaS >3 string t Cups Raster version 1, Big Endian >3 string 2 Cups Raster version 2, Big Endian >3 string 3 Cups Raster version 3, Big Endian @@ -48,7 +48,7 @@ # Cups Raster image format, Little Endian -1 string SaR +1 string SaR >0 string t Cups Raster version 1, Little Endian >0 string 2 Cups Raster version 2, Little Endian >0 string 3 Cups Raster version 3, Little Endian diff --git a/contrib/file/magic/Magdir/database b/contrib/file/magic/Magdir/database index 15f94b1faab4..a0300ae772ce 100644 --- a/contrib/file/magic/Magdir/database +++ b/contrib/file/magic/Magdir/database @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: database,v 1.49 2016/06/11 17:01:51 christos Exp $ +# $File: database,v 1.52 2017/08/13 00:21:47 christos Exp $ # database: file(1) magic for various databases # # extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk) @@ -84,7 +84,7 @@ # From Max Bowsher. 12 long 0x00040988 Berkeley DB >16 long >0 (Log, version %d, native byte-order) -12 belong 0x00040988 Berkeley DB +12 belong 0x00040988 Berkeley DB >16 belong >0 (Log, version %d, big-endian) 12 lelong 0x00040988 Berkeley DB >16 lelong >0 (Log, version %d, little-endian) @@ -103,7 +103,7 @@ >>>12 long !0 32bit aligned >>>>12 bedouble 8.642135e+130 big-endian >>>>>20 long 0 64bit long ->>>>>20 long !0 32bit long +>>>>>20 long !0 32bit long >>>>12 ledouble 8.642135e+130 little-endian >>>>>24 long 0 64bit long >>>>>24 long !0 32bit long (i386) @@ -128,22 +128,22 @@ # XXX: Weak magic. # Alex Ott ## Paradox file formats -#2 leshort 0x0800 Paradox -#>0x39 byte 3 v. 3.0 -#>0x39 byte 4 v. 3.5 -#>0x39 byte 9 v. 4.x -#>0x39 byte 10 v. 5.x -#>0x39 byte 11 v. 5.x -#>0x39 byte 12 v. 7.x -#>>0x04 byte 0 indexed .DB data file -#>>0x04 byte 1 primary index .PX file -#>>0x04 byte 2 non-indexed .DB data file -#>>0x04 byte 3 non-incrementing secondary index .Xnn file -#>>0x04 byte 4 secondary index .Ynn file -#>>0x04 byte 5 incrementing secondary index .Xnn file -#>>0x04 byte 6 non-incrementing secondary index .XGn file -#>>0x04 byte 7 secondary index .YGn file -#>>>0x04 byte 8 incrementing secondary index .XGn file +#2 leshort 0x0800 Paradox +#>0x39 byte 3 v. 3.0 +#>0x39 byte 4 v. 3.5 +#>0x39 byte 9 v. 4.x +#>0x39 byte 10 v. 5.x +#>0x39 byte 11 v. 5.x +#>0x39 byte 12 v. 7.x +#>>0x04 byte 0 indexed .DB data file +#>>0x04 byte 1 primary index .PX file +#>>0x04 byte 2 non-indexed .DB data file +#>>0x04 byte 3 non-incrementing secondary index .Xnn file +#>>0x04 byte 4 secondary index .Ynn file +#>>0x04 byte 5 incrementing secondary index .Xnn file +#>>0x04 byte 6 non-incrementing secondary index .XGn file +#>>0x04 byte 7 secondary index .YGn file +#>>>0x04 byte 8 incrementing secondary index .XGn file ## XBase database files # updated by Joerg Jenderek at Feb 2013 @@ -151,33 +151,33 @@ # http://www.clicketyclick.dk/databases/xbase/format/dbf.html # http://home.f1.htw-berlin.de/scheibl/db/intern/dBase.htm # inspect VVYYMMDD , where 1<= MM <= 12 and 1<= DD <= 31 -0 ubelong&0x0000FFFF <0x00000C20 +0 ubelong&0x0000FFFF <0x00000C20 # skip Infocom game Z-machine ->2 ubyte >0 +>2 ubyte >0 # skip Androids *.xml ->>3 ubyte >0 ->>>3 ubyte <32 +>>3 ubyte >0 +>>>3 ubyte <32 # 1 < version VV ->>>>0 ubyte >1 +>>>>0 ubyte >1 # skip HELP.CA3 by test for reserved byte ( NULL ) ->>>>>27 ubyte 0 +>>>>>27 ubyte 0 # reserved bytes not always 0 ; also found 0x3901 (T4.DBF) ,0x7101 (T5.DBF,T6.DBF) #>>>>>30 ubeshort x 30NULL?%x -# possible production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL) ->>>>>>24 ubelong&0xffFFFFff >0x01302000 +# possible production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL) +>>>>>>24 ubelong&0xffFFFFff >0x01302000 # .DBF or .MDX ->>>>>>24 ubelong&0xffFFFFff <0x01302001 +>>>>>>24 ubelong&0xffFFFFff <0x01302001 # for Xbase Database file (*.DBF) reserved (NULL) for multi-user ->>>>>>>24 ubelong&0xffFFFFff =0 +>>>>>>>24 ubelong&0xffFFFFff =0 # test for 2 reserved NULL bytes,transaction and encryption byte flag ->>>>>>>>12 ubelong&0xFFFFfEfE 0 +>>>>>>>>12 ubelong&0xFFFFfEfE 0 # test for MDX flag ->>>>>>>>>28 ubyte x ->>>>>>>>>28 ubyte&0xf8 0 +>>>>>>>>>28 ubyte x +>>>>>>>>>28 ubyte&0xf8 0 # header size >= 32 ->>>>>>>>>>8 uleshort >31 +>>>>>>>>>>8 uleshort >31 # skip PIC15736.PCX by test for language driver name or field name ->>>>>>>>>>>32 ubyte >0 +>>>>>>>>>>>32 ubyte >0 #!:mime application/x-dbf; charset=unknown-8bit ?? #!:mime application/x-dbase >>>>>>>>>>>>0 use xbase-type @@ -202,22 +202,22 @@ >>>>>>>>>>>>28 ubyte&0x02 2 \b, with memo .FPT >>>>>>>>>>>>28 ubyte&0x04 4 \b, DataBaseContainer # 1st record offset + 1 = header size ->>>>>>>>>>>>8 uleshort >0 ->>>>>>>>>>>>(8.s+1) ubyte >0 +>>>>>>>>>>>>8 uleshort >0 +>>>>>>>>>>>>(8.s+1) ubyte >0 >>>>>>>>>>>>>8 uleshort >0 \b, at offset %d ->>>>>>>>>>>>>(8.s+1) ubyte >0 +>>>>>>>>>>>>>(8.s+1) ubyte >0 >>>>>>>>>>>>>>&-1 string >\0 1st record "%s" -# for multiple index files (*.MDX) Production flag,tag numbers(<=0x30),tag length(<=0x20), reserverd (NULL) ->>>>>>>24 ubelong&0x0133f7ff >0 +# for multiple index files (*.MDX) Production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL) +>>>>>>>24 ubelong&0x0133f7ff >0 # test for reserved NULL byte ->>>>>>>>47 ubyte 0 +>>>>>>>>47 ubyte 0 # test for valid TAG key format (0x10 or 0) ->>>>>>>>>559 ubyte&0xeF 0 +>>>>>>>>>559 ubyte&0xeF 0 # test MM <= 12 ->>>>>>>>>>45 ubeshort <0x0C20 ->>>>>>>>>>>45 ubyte >0 ->>>>>>>>>>>>46 ubyte <32 ->>>>>>>>>>>>>46 ubyte >0 +>>>>>>>>>>45 ubeshort <0x0C20 +>>>>>>>>>>>45 ubyte >0 +>>>>>>>>>>>>46 ubyte <32 +>>>>>>>>>>>>>46 ubyte >0 #!:mime application/x-mdx >>>>>>>>>>>>>>0 use xbase-type >>>>>>>>>>>>>>0 ubyte x \b MDX @@ -236,11 +236,11 @@ # 2nd tag name #>>>>>>>>>>>>(26.b+548) string x \b, 2nd tag "%.11s" # -# Print the xBase names of different version variants +# Print the xBase names of different version variants 0 name xbase-type ->0 ubyte <2 +>0 ubyte <2 # 1 < version ->0 ubyte >1 +>0 ubyte >1 >>0 ubyte 0x02 FoxBase # FoxBase+/dBaseIII+, no memo >>0 ubyte 0x03 FoxBase+/dBase III @@ -293,7 +293,7 @@ # dBASE IV with SQL table, with memo .DBT >>0 ubyte 0xCB dBase IV with SQL table, with memo .DBT !:mime application/x-dbf -# HiPer-Six format;Clipper SIX, with SMT memo file +# HiPer-Six format;Clipper SIX, with SMT memo file >>0 ubyte 0xE5 Clipper SIX with memo !:mime application/x-dbf # http://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx @@ -318,12 +318,12 @@ # test and print the date of xBase .DBF .MDX 0 name xbase-date # inspect YYMMDD , where 1<= MM <= 12 and 1<= DD <= 31 ->0 ubelong x ->1 ubyte <13 ->>1 ubyte >0 ->>>2 ubyte >0 ->>>>2 ubyte <32 ->>>>>0 ubyte x +>0 ubelong x +>1 ubyte <13 +>>1 ubyte >0 +>>>2 ubyte >0 +>>>>2 ubyte <32 +>>>>>0 ubyte x # YY is interpreted as 20YY or 19YY >>>>>>0 ubyte <100 \b %.2d # YY is interpreted 1900+YY; TODO: display yy or 20yy instead 1YY @@ -333,56 +333,56 @@ # dBase memo files .DBT or .FPT # http://msdn.microsoft.com/en-us/library/8599s21w(v=vs.80).aspx -16 ubyte <4 ->16 ubyte !2 ->>16 ubyte !1 +16 ubyte <4 +>16 ubyte !2 +>>16 ubyte !1 # next free block index is positive ->>>0 ulelong >0 +>>>0 ulelong >0 # skip many JPG. ZIP, BZ2 by test for reserved bytes NULL , 0|2 , 0|1 , low byte of block size ->>>>17 ubelong&0xFFfdFE00 0x00000000 +>>>>17 ubelong&0xFFfdFE00 0x00000000 # skip many RAR by test for low byte 0 ,high byte 0|2|even of block size, 0|a|e|d7 , 0|64h ->>>>>20 ubelong&0xFF01209B 0x00000000 +>>>>>20 ubelong&0xFF01209B 0x00000000 # dBASE III ->>>>>>16 ubyte 3 +>>>>>>16 ubyte 3 # dBASE III DBT >>>>>>>0 use dbase3-memo-print # dBASE III DBT without version, dBASE IV DBT , FoxPro FPT , or many ZIP , DBF garbage ->>>>>>16 ubyte 0 +>>>>>>16 ubyte 0 # unusual dBASE III DBT like angest.dbt, dBASE IV DBT with block size 0 , FoxPro FPT , or garbage PCX DBF ->>>>>>>20 uleshort 0 +>>>>>>>20 uleshort 0 # FoxPro FPT , unusual dBASE III DBT like biblio.dbt or garbage ->>>>>>>>8 ulong =0 ->>>>>>>>>6 ubeshort >0 +>>>>>>>>8 ulong =0 +>>>>>>>>>6 ubeshort >0 # skip emacs.PIF ->>>>>>>>>>4 ushort 0 +>>>>>>>>>>4 ushort 0 >>>>>>>>>>>0 use foxpro-memo-print # dBASE III DBT , garbage ->>>>>>>>>6 ubeshort 0 +>>>>>>>>>6 ubeshort 0 # skip MM*DD*.bin by test for for reserved NULL byte ->>>>>>>>>>510 ubeshort 0 +>>>>>>>>>>510 ubeshort 0 # skip TK-DOS11.img image by looking for memo text ->>>>>>>>>>>512 ubelong <0xfeffff03 +>>>>>>>>>>>512 ubelong <0xfeffff03 # skip EFI executables by looking for memo text ->>>>>>>>>>>>512 ubelong >0x1F202020 ->>>>>>>>>>>>>513 ubyte >0 +>>>>>>>>>>>>512 ubelong >0x1F202020 +>>>>>>>>>>>>>513 ubyte >0 # unusual dBASE III DBT like adressen.dbt >>>>>>>>>>>>>>0 use dbase3-memo-print # dBASE III DBT like angest.dbt, or garbage PCX DBF ->>>>>>>>8 ubelong !0 +>>>>>>>>8 ubelong !0 # skip PCX and some DBF by test for for reserved NULL bytes ->>>>>>>>>510 ubeshort 0 +>>>>>>>>>510 ubeshort 0 # skip some DBF by test of invalid version ->>>>>>>>>>0 ubyte >5 ->>>>>>>>>>>0 ubyte <48 +>>>>>>>>>>0 ubyte >5 +>>>>>>>>>>>0 ubyte <48 >>>>>>>>>>>>0 use dbase3-memo-print # dBASE IV DBT with positive block size ->>>>>>>20 uleshort >0 -# dBASE IV DBT with valid block length like 512, 1024 +>>>>>>>20 uleshort >0 +# dBASE IV DBT with valid block length like 512, 1024 # multiple of 2 in between 16 and 16 K ,implies upper and lower bits are zero ->>>>>>>>20 uleshort&0x800f 0 +>>>>>>>>20 uleshort&0x800f 0 >>>>>>>>>0 use dbase4-memo-print -# Print the information of dBase III DBT memo file +# Print the information of dBase III DBT memo file 0 name dbase3-memo-print >0 ubyte x dBase III DBT # instead 3 as version number 0 for unusual examples like biblio.dbt @@ -395,45 +395,45 @@ >20 uleshort !0 \b, block length %u # dBase III memo field terminated by \032\032 >512 string >\0 \b, 1st item "%s" -# Print the information of dBase IV DBT memo file +# Print the information of dBase IV DBT memo file 0 name dbase4-memo-print >0 lelong x dBase IV DBT !:mime application/x-dbt !:ext dbt # 8 character shorted main name of coresponding dBASE IV DBF file ->8 ubelong >0x20000000 +>8 ubelong >0x20000000 # skip unusual like for angest.dbt ->>20 uleshort >0 +>>20 uleshort >0 >>>8 string >\0 \b of %-.8s.DBF # value 0 implies 512 as size #>4 ulelong =0 \b, blocks size %u # size of blocks not reliable like 0x2020204C in angest.dbt ->4 ulelong !0 +>4 ulelong !0 >>4 ulelong&0x0000003f 0 \b, blocks size %u # dBase IV DBT with positive block length (found 512 , 1024) >20 uleshort >0 \b, block length %u # next available block #>0 lelong =0 \b, next free block index %u >0 lelong !0 \b, next free block index %u ->20 uleshort >0 ->>(20.s) ubelong x +>20 uleshort >0 +>>(20.s) ubelong x >>>&-4 use dbase4-memofield-print # unusual dBase IV DBT without block length (implies 512 as length) ->20 uleshort =0 ->>512 ubelong x +>20 uleshort =0 +>>512 ubelong x >>>&-4 use dbase4-memofield-print -# Print the information of dBase IV memo field +# Print the information of dBase IV memo field 0 name dbase4-memofield-print # free dBase IV memo field ->0 ubelong !0xFFFF0800 +>0 ubelong !0xFFFF0800 >>0 lelong x \b, next free block %u >>4 lelong x \b, next used block %u # used dBase IV memo field ->0 ubelong =0xFFFF0800 +>0 ubelong =0xFFFF0800 # length of memo field >>4 lelong x \b, field length %d >>>8 string >\0 \b, 1st used item "%s" -# Print the information of FoxPro FPT memo file +# Print the information of FoxPro FPT memo file 0 name foxpro-memo-print >0 belong x FoxPro FPT # Size of blocks for FoxPro ( 64,256 ) @@ -441,14 +441,14 @@ # next available block #>0 belong =0 \b, next free block index %u >0 belong !0 \b, next free block index %u -# field type ( 0~picture, 1~memo, 2~object ) +# field type ( 0~picture, 1~memo, 2~object ) >512 ubelong <3 \b, field type %u # length of memo field ->512 ubelong 1 +>512 ubelong 1 >>516 belong >0 \b, field length %d >>>520 string >\0 \b, 1st item "%s" -# TODO: +# TODO: # DBASE index file *.NDX # DBASE Compound Index file *.CDX # dBASE IV Printer Driver *.PRF @@ -465,9 +465,9 @@ # Reference: https://github.com/libyal/libesedb/archive/master.zip # libesedb-master/documentation/ # Extensible Storage Engine (ESE) Database File (EDB) format.asciidoc -# Note: also known as "JET Blue". Used by numerous Windows components such as +# Note: also known as "JET Blue". Used by numerous Windows components such as # Windows Search, Mail, Exchange and Active Directory. -4 ubelong 0xefcdab89 +4 ubelong 0xefcdab89 # unknown1 >132 ubelong 0 Extensible storage engine !:mime application/x-ms-ese @@ -497,8 +497,8 @@ # From: Joerg Jenderek # URL: http://forensicswiki.org/wiki/Windows_Application_Compatibility # Note: files contain application compatibility fixes, application compatibility modes and application help messages. -8 string sdbf ->7 ubyte 0 +8 string sdbf +>7 ubyte 0 # TAG_TYPE_LIST+TAG_INDEXES >>12 uleshort 0x7802 Windows application compatibility Shim DataBase # version? 2 3 @@ -600,10 +600,10 @@ # Reference: http://www.provue.com/Panorama/ # From: Joerg Jenderek # NOTE: test only versions 4 and 6.0 with Windows -# length of Panorama database name -5 ubyte >0 +# length of Panorama database name +5 ubyte >0 # look after database name for "some" null bits ->(5.B+7) ubelong&0xF3ffF000 0 +>(5.B+7) ubelong&0xF3ffF000 0 # look for first keyword >>&1 search/2 DESIGN Panorama database #!:mime application/x-panorama-database @@ -622,3 +622,13 @@ # MUIbase Database Tool by Stefan A. Haubenthal 0 string MBSTV\040 MUIbase DB >6 string x version %s + +# +# CDB database +0 string NBCDB\012 NetBSD Constant Database +>7 byte x \b, version %d +>8 string x \b, for '%s' +>24 lelong x \b, datasize %d +>28 lelong x \b, entries %d +>32 lelong x \b, index %d +>36 lelong x \b, seed %#x diff --git a/contrib/file/magic/Magdir/der b/contrib/file/magic/Magdir/der index abfbf9b8c0a2..9c25f00cc611 100644 --- a/contrib/file/magic/Magdir/der +++ b/contrib/file/magic/Magdir/der @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: der,v 1.1 2016/01/19 15:07:45 christos Exp $ +# $File: der,v 1.2 2017/03/17 21:35:28 christos Exp $ # der: file(1) magic for DER encoded files # @@ -32,37 +32,37 @@ # Key Pairs 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int65=x >&0 der int3=010001 DER Encoded Key Pair, 512 bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int129=x >&0 der int3=010001 DER Encoded Key Pair, 1024 bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int257=x >&0 der int3=010001 DER Encoded Key Pair, 2048 bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int513=x >&0 der int3=010001 DER Encoded Key Pair, 4096 bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int1025=x >&0 der int3=010001 DER Encoded Key Pair, 8192 bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int2049=x >&0 der int3=010001 DER Encoded Key Pair, 16k bits 0 der seq ->&0 der int1=00 +>&0 der int1=00 >&0 der int4097=x >&0 der int3=010001 DER Encoded Key Pair, 32k bits diff --git a/contrib/file/magic/Magdir/diff b/contrib/file/magic/Magdir/diff index 59243801eb5a..cd530d345e32 100644 --- a/contrib/file/magic/Magdir/diff +++ b/contrib/file/magic/Magdir/diff @@ -1,15 +1,15 @@ #------------------------------------------------------------------------------ -# $File: diff,v 1.14 2012/09/16 23:08:54 christos Exp $ +# $File: diff,v 1.16 2017/03/17 22:20:22 christos Exp $ # diff: file(1) magic for diff(1) output # -0 search/1 diff\ diff output text +0 search/1 diff\040 diff output text !:mime text/x-diff -0 search/1 ***\ diff output text +0 search/1 ***\040 diff output text !:mime text/x-diff -0 search/1 Only\ in\ diff output text +0 search/1 Only\040in\040 diff output text !:mime text/x-diff -0 search/1 Common\ subdirectories:\ diff output text +0 search/1 Common\040subdirectories:\040 diff output text !:mime text/x-diff 0 search/1 Index: RCS/CVS diff output text @@ -20,9 +20,9 @@ # unified diff -0 search/4096 ---\ +0 search/4096 ---\040 >&0 search/1024 \n ->>&0 search/1 +++\ +>>&0 search/1 +++\040 >>>&0 search/1024 \n >>>>&0 search/1 @@ unified diff output text !:mime text/x-diff diff --git a/contrib/file/magic/Magdir/dolby b/contrib/file/magic/Magdir/dolby index 573398f347c8..8034eddc2a8f 100644 --- a/contrib/file/magic/Magdir/dolby +++ b/contrib/file/magic/Magdir/dolby @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: dolby,v 1.7 2014/01/08 22:37:23 christos Exp $ +# $File: dolby,v 1.8 2017/03/17 21:35:28 christos Exp $ # ATSC A/53 aka AC-3 aka Dolby Digital # from http://www.atsc.org/standards/a_52a.pdf # corrections, additions, etc. are always welcome! @@ -23,7 +23,7 @@ >5 byte&0x07 = 0x04 \b, dialogue (D) >5 byte&0x07 = 0x05 \b, commentary (C) >5 byte&0x07 = 0x06 \b, emergency (E) ->5 beshort&0x07e0 0x0720 \b, voiceover (VO) +>5 beshort&0x07e0 0x0720 \b, voiceover (VO) >5 beshort&0x07e0 >0x0720 \b, karaoke # acmod >6 byte&0xe0 = 0x00 1+1 front, diff --git a/contrib/file/magic/Magdir/dump b/contrib/file/magic/Magdir/dump index 1a20ace29c4b..73de3dc87a0b 100644 --- a/contrib/file/magic/Magdir/dump +++ b/contrib/file/magic/Magdir/dump @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: dump,v 1.13 2014/04/30 21:41:02 christos Exp $ +# $File: dump,v 1.16 2017/07/22 19:21:02 christos Exp $ # dump: file(1) magic for dump file format--for new and old dump filesystems # # We specify both byte orders in order to recognize byte-swapped dumps. @@ -62,23 +62,25 @@ >824 string >\0 Host %s, >888 belong >0 Flags %x -24 belong 60012 new-fs dump file (big endian), +24 belong 60012 new-fs dump file (big endian), >0 use new-dump-be -24 belong 60011 old-fs dump file (big endian), +24 belong 60011 old-fs dump file (big endian), >0 use old-dump-be -24 lelong 60012 new-fs dump file (little endian), +24 lelong 60012 new-fs dump file (little endian), +# to correctly recognize '*.mo' GNU message catalog (little endian) +!:strength - 15 >0 use \^new-dump-be -24 lelong 60011 old-fs dump file (little endian), +24 lelong 60011 old-fs dump file (little endian), >0 use \^old-dump-be -24 belong 0x19540119 new-fs dump file (ufs2, big endian), +24 belong 0x19540119 new-fs dump file (ufs2, big endian), >0 use ufs2-dump-be -24 lelong 0x19540119 new-fs dump file (ufs2, little endian), +24 lelong 0x19540119 new-fs dump file (ufs2, little endian), >0 use \^ufs2-dump-be 18 leshort 60011 old-fs dump file (16-bit, assuming PDP-11 endianness), diff --git a/contrib/file/magic/Magdir/dyadic b/contrib/file/magic/Magdir/dyadic index ab7346586eab..185970e4ee00 100644 --- a/contrib/file/magic/Magdir/dyadic +++ b/contrib/file/magic/Magdir/dyadic @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: dyadic,v 1.7 2015/05/27 18:02:48 christos Exp $ +# $File: dyadic,v 1.8 2017/03/17 21:35:28 christos Exp $ # Dyadic: file(1) magic for Dyalog APL. # # updated by Joerg Jenderek at Oct 2013 @@ -10,9 +10,9 @@ # .DIN Dyalog APL Input Table # .DOT Dyalog APL Output Table # .DFT Dyalog APL Format File -0 ubeshort&0xFF60 0xaa00 +0 ubeshort&0xFF60 0xaa00 # skip biblio.dbt ->1 byte !4 +>1 byte !4 # real Dyalog APL have non zero version numbers like 7.3 or 13.4 >>2 ubeshort >0x0000 Dyalog APL >>>1 byte 0x00 aplcore diff --git a/contrib/file/magic/Magdir/editors b/contrib/file/magic/Magdir/editors index fa6cbc64c095..78f3a84056e6 100644 --- a/contrib/file/magic/Magdir/editors +++ b/contrib/file/magic/Magdir/editors @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ -# $File: editors,v 1.10 2016/07/18 17:44:49 christos Exp $ -# T602 editor documents +# $File: editors,v 1.11 2017/03/17 21:35:28 christos Exp $ +# T602 editor documents # by David Necas 0 string @CT\ T602 document data, >4 string 0 Kamenicky @@ -9,7 +9,7 @@ >4 string 2 KOI8-CS >4 string >2 unknown encoding -# Vi IMproved Encrypted file +# Vi IMproved Encrypted file # by David Necas 0 string VimCrypt~ Vim encrypted file data diff --git a/contrib/file/magic/Magdir/filesystems b/contrib/file/magic/Magdir/filesystems index b7c6e5b32fa7..48b74e04c8ff 100644 --- a/contrib/file/magic/Magdir/filesystems +++ b/contrib/file/magic/Magdir/filesystems @@ -1,8 +1,8 @@ #------------------------------------------------------------------------------ -# $File: filesystems,v 1.114 2016/09/05 08:34:25 christos Exp $ +# $File: filesystems,v 1.122 2017/07/21 10:34:41 christos Exp $ # filesystems: file(1) magic for different filesystems # -0 name partid +0 name partid >0 ubyte 0x00 Unused >0 ubyte 0x01 12-bit FAT >0 ubyte 0x02 XENIX / @@ -187,7 +187,7 @@ 0 string \366\366\366\366 PC formatted floppy with no filesystem # Sun disk labels # From /usr/include/sun/dklabel.h: -0774 beshort 0xdabe +0774 beshort 0xdabe # modified by Joerg Jenderek, because original test # succeeds for Cabinet archive dao360.dl_ with negative blocks >0770 long >0 Sun disk label @@ -213,50 +213,50 @@ # (http://btmgr.sourceforge.net/docs/user-guide-3.html) 0 string SBMBAKUP_ Smart Boot Manager backup file >9 string x \b, version %-5.5s ->>14 string =_ +>>14 string =_ >>>15 string x %-.1s >>>>16 string =_ \b. >>>>>17 string x \b%-.1s >>>>>>18 string =_ \b. >>>>>>>19 string x \b%-.1s ->>>22 ubyte 0 +>>>22 ubyte 0 >>>>21 ubyte x \b, from drive 0x%x ->>>22 ubyte >0 +>>>22 ubyte >0 >>>>21 string x \b, from drive %s ->>>535 search/17 \x55\xAA ->>>>&-512 indirect x \b; contains +>>>535 search/17 \x55\xAA +>>>>&-512 indirect x \b; contains # updated by Joerg Jenderek at Nov 2012 # DOS Emulator image is 128 byte, null right padded header + harddisc image -0 string DOSEMU\0 ->0x27E leshort 0xAA55 +0 string DOSEMU\0 +>0x27E leshort 0xAA55 #offset is 128 ->>19 ubyte 128 +>>19 ubyte 128 >>>(19.b-1) ubyte 0x0 DOS Emulator image >>>>7 ulelong >0 \b, %u heads >>>>11 ulelong >0 \b, %d sectors/track >>>>15 ulelong >0 \b, %d cylinders ->>>>128 indirect x \b; contains +>>>>128 indirect x \b; contains # added by Joerg Jenderek at Nov 2012 # http://www.thenakedpc.com/articles/v04/08/0408-05.html # Symantec (Peter Norton) Image.dat file consists of variable header, bootrecord, part of FAT and root directory data 0 string PNCIHISK\0 Norton Utilities disc image data # real x86 boot sector with jump instruction ->509 search/1026 \x55\xAA\xeb ->>&-1 indirect x \b; contains +>509 search/1026 \x55\xAA\xeb +>>&-1 indirect x \b; contains # http://file-extension.net/seeker/file_extension_dat 0 string PNCIUNDO Norton Disk Doctor UnDo file # # DOS/MBR boot sector updated by Joerg Jenderek at Sep 2007,May 2011,2013 # for any allowed sector sizes -30 search/481 \x55\xAA +30 search/481 \x55\xAA # to display DOS/MBR boot sector (40) before old one (strength=50+21),Syslinux bootloader (71),SYSLINUX MBR (37+36),NetBSD mbr (110),AdvanceMAME mbr (111) # DOS BPB information (70) and after DOS floppy (120) like in previous file version !:strength +65 # for sector sizes < 512 Bytes ->11 uleshort <512 +>11 uleshort <512 >>(11.s-2) uleshort 0xAA55 DOS/MBR boot sector # for sector sizes with 512 or more Bytes >0x1FE leshort 0xAA55 DOS/MBR boot sector @@ -270,18 +270,18 @@ >2 string OSBS OS/BS MBR # added by Joerg Jenderek at Feb 2013 according to http://thestarman.pcministry.com/asm/mbr/ # and http://en.wikipedia.org/wiki/Master_Boot_Record -# test for nearly all MS-DOS Master Boot Record initial program loader (IPL) is now done by +# test for nearly all MS-DOS Master Boot Record initial program loader (IPL) is now done by # characteristic assembler instructions: xor ax,ax;mov ss,ax;mov sp,7c00 >0 search/2 \x33\xc0\x8e\xd0\xbc\x00\x7c MS-MBR # Microsoft Windows 95A and early ( http://thestarman.pcministry.com/asm/mbr/STDMBR.htm ) # assembler instructions: mov si,sp;push ax;pop es;push ax;pop ds;sti;cld ->>8 ubequad 0x8bf45007501ffbfc +>>8 ubequad 0x8bf45007501ffbfc # http://thestarman.pcministry.com/asm/mbr/200MBR.htm >>>0x16 ubyte 0xF3 \b,DOS 2 >>>>219 regex Author\ -\ Author: # found "David Litton" , "A Pehrsson " >>>>>&0 string x "%s" ->>>0x16 ubyte 0xF2 +>>>0x16 ubyte 0xF2 # NEC MS-DOS 3.30 Rev. 3 . See http://thestarman.pcministry.com/asm/mbr/DOS33MBR.htm # assembler instructions: mov di,077c;cmp word ptrl[di],a55a;jnz >>>>0x22 ubequad 0xbf7c07813d5aa575 \b,NEC 3.3 @@ -316,7 +316,7 @@ >>>>>>(0x79.b) string >\0 "%s" # Microsoft Windows 95B to XP (http://thestarman.pcministry.com/asm/mbr/95BMEMBR.htm) # assembler instructions: push ax;pop es;push ax;pop ds;cld;mov si,7c1b ->>8 ubequad 0x5007501ffcbe1b7c +>>8 ubequad 0x5007501ffcbe1b7c # assembler instructions: rep;movsb;retf;mov si,07be;mov cl,04 >>>24 ubequad 0xf3a4cbbebe07b104 9M # "Invalid partition table" nn=0x10F for english version @@ -361,7 +361,7 @@ >>>>(0x1b7.b+0x100) string >\0 "%s" # Microsoft Windows Vista or 7 # assembler instructions: ..;mov ds,ax;mov si,7c00;mov di,..00 ->>8 ubequad 0xc08ed8be007cbf00 +>>8 ubequad 0xc08ed8be007cbf00 # Microsoft Windows Vista (http://thestarman.pcministry.com/asm/mbr/VistaMBR.htm) # assembler instructions: jnz 0729;cmp ebx,"TCPA" >>>0xEC ubequad 0x753b6681fb544350 Vista @@ -402,38 +402,38 @@ # http://en.wikipedia.org/wiki/MBR_disk_signature#ID >>0x1b8 ulelong >0 \b, disk signature 0x%-.4x # driveID/timestamp for Win 95B,98,98SE and ME. See http://thestarman.pcministry.com/asm/mbr/mystery.htm ->>0xDA uleshort 0 +>>0xDA uleshort 0 >>>0xDC ulelong >0 \b, created # physical drive number (0x80-0xFF) when the Windows wrote that byte to the drive >>>>0xDC ubyte x with driveID 0x%x -# hours, minutes and seconds +# hours, minutes and seconds >>>>0xDf ubyte x at %x >>>>0xDe ubyte x \b:%x >>>>0xDd ubyte x \b:%x # special case for Microsoft MS-DOS 3.21 spanish -# assembler instructions: cli;mov $0x30,%ax;mov %ax,%ss;mov ->0 ubequad 0xfab830008ed0bc00 -# assembler instructions: $0x1f00,%sp;mov $0x80cb,%di;add %cl,(%bx,%si);in (%dx),%ax;mov +# assembler instructions: cli;mov $0x30,%ax;mov %ax,%ss;mov +>0 ubequad 0xfab830008ed0bc00 +# assembler instructions: $0x1f00,%sp;mov $0x80cb,%di;add %cl,(%bx,%si);in (%dx),%ax;mov >>8 ubequad 0x1fbfcb800008ed8 MS-MBR,D0S version 3.21 spanish # Microsoft MBR IPL end # dr-dos with some upper-, lowercase variants ->0x9D string Invalid\ partition\ table$ ->>181 string No\ Operating\ System$ +>0x9D string Invalid\ partition\ table$ +>>181 string No\ Operating\ System$ >>>201 string Operating\ System\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03 ->0x9D string Invalid\ partition\ table$ ->>181 string No\ operating\ system$ +>0x9D string Invalid\ partition\ table$ +>>181 string No\ operating\ system$ >>>201 string Operating\ system\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03 ->342 string Invalid\ partition\ table$ ->>366 string No\ operating\ system$ +>342 string Invalid\ partition\ table$ +>>366 string No\ operating\ system$ >>>386 string Operating\ system\ load\ error$ \b, DR-DOS MBR, version 7.01 to 7.03 ->295 string NEWLDR\0 ->>302 string Bad\ PT\ $ ->>>310 string No\ OS\ $ ->>>>317 string OS\ load\ err$ ->>>>>329 string Moved\ or\ missing\ IBMBIO.LDR\n\r ->>>>>>358 string Press\ any\ key\ to\ continue.\n\r$ ->>>>>>>387 string Copyright\ (c)\ 1984,1998 +>295 string NEWLDR\0 +>>302 string Bad\ PT\ $ +>>>310 string No\ OS\ $ +>>>>317 string OS\ load\ err$ +>>>>>329 string Moved\ or\ missing\ IBMBIO.LDR\n\r +>>>>>>358 string Press\ any\ key\ to\ continue.\n\r$ +>>>>>>>387 string Copyright\ (c)\ 1984,1998 >>>>>>>>411 string Caldera\ Inc.\0 \b, DR-DOS MBR (IBMBIO.LDR) # # tests for different MS-DOS Master Boot Records (MBR) moved and merged @@ -441,15 +441,15 @@ #>0x145 string Default:\ F \b, FREE-DOS MBR #>0x14B string Default:\ F \b, FREE-DOS 1.0 MBR >0x145 search/7 Default:\ F \b, FREE-DOS MBR -#>>313 string F0\ .\ .\ . -#>>>322 string disk\ 1 -#>>>>382 string FAT3 ->64 string no\ active\ partition\ found +#>>313 string F0\ .\ .\ . +#>>>322 string disk\ 1 +#>>>>382 string FAT3 +>64 string no\ active\ partition\ found >>96 string read\ error\ while\ reading\ drive \b, FREE-DOS Beta 0.9 MBR # Ranish Partition Manager http://www.ranish.com/part/ ->387 search/4 \0\ Error!\r ->>378 search/7 Virus! ->>>397 search/4 Booting\ +>387 search/4 \0\ Error!\r +>>378 search/7 Virus! +>>>397 search/4 Booting\040 >>>>408 search/4 HD1/\0 \b, Ranish MBR ( >>>>>416 string Writing\ changes... \b2.37 >>>>>>438 ubyte x \b,0x%x dots @@ -466,23 +466,23 @@ # # SYSLINUX MBR moved # http://www.acronis.de/ ->362 string MBR\ Error\ \0\r ->>376 string ress\ any\ key\ to\ +>362 string MBR\ Error\ \0\r +>>376 string ress\ any\ key\ to\040 >>>392 string boot\ from\ floppy...\0 \b, Acronis MBR # added by Joerg Jenderek # http://www.visopsys.org/ # http://partitionlogic.org.uk/ ->309 string No\ bootable\ partition\ found\r +>309 string No\ bootable\ partition\ found\r >>339 string I/O\ Error\ reading\ boot\ sector\r \b, Visopsys MBR ->349 string No\ bootable\ partition\ found\r +>349 string No\ bootable\ partition\ found\r >>379 string I/O\ Error\ reading\ boot\ sector\r \b, simple Visopsys MBR # bootloader, bootmanager ->0x40 string SBML +>0x40 string SBML # label with 11 characters of FAT 12 bit filesystem ->>43 string SMART\ BTMGR +>>43 string SMART\ BTMGR >>>430 string SBMK\ Bad!\r \b, Smart Boot Manager # OEM-ID not always "SBM" -#>>>>3 strings SBM +#>>>>3 strings SBM >>>>6 string >\0 \b, version %s >382 string XOSLLOADXCF \b, eXtended Operating System Loader >6 string LILO \b, LInux i386 boot LOader @@ -492,11 +492,11 @@ # variables according to grub-0.97/stage1/stage1.S or # http://www.gnu.org/software/grub/manual/grub.html#Embedded-data # usual values are marked with comments to get only informations of strange GRUB loaders ->342 search/60 \0Geom\0 +>342 search/60 \0Geom\0 #>0 ulelong x %x=0x009048EB , 0x2a9048EB 0 ->>0x41 ubyte <2 +>>0x41 ubyte <2 >>>0x3E ubyte >2 \b; GRand Unified Bootloader -# 0x3 for 0.5.95,0.93,0.94,0.96 0x4 for 1.90 +# 0x3 for 0.5.95,0.93,0.94,0.96 0x4 for 1.90 >>>>0x3E ubyte x \b, stage1 version 0x%x #If it is 0xFF, use a drive passed by BIOS >>>>0x40 ubyte <0xFF \b, boot drive 0x%x @@ -521,497 +521,497 @@ >>>>391 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>>385 string GRUB\ \0 \b, GRUB version 0.97 # unknown version ->>>343 string Geom\0Read\0\ Error\0 +>>>343 string Geom\0Read\0\ Error\0 >>>>321 string Loading\ stage1.5 \b, GRUB version x.y >>>380 string Geom\0Hard\ Disk\0Read\0\ Error\0 >>>>374 string GRUB\ \0 \b, GRUB version n.m # SYSLINUX bootloader moved >395 string chksum\0\ ERROR!\0 \b, Gujin bootloader # http://www.bcdwb.de/bcdw/index_e.htm ->3 string BCDL +>3 string BCDL >>498 string BCDL\ \ \ \ BIN \b, Bootable CD Loader (1.50Z) # mbr partition table entries updated by Joerg Jenderek at Sep 2013 # skip Norton Utilities disc image data ->3 string !IHISK +>3 string !IHISK # skip Linux style boot sector starting with assember instructions mov 0x7c0,ax; ->>0 belong !0xb8c0078e -# not Linux kernel ->>>514 string !HdrS +>>0 belong !0xb8c0078e +# not Linux kernel +>>>514 string !HdrS # not BeOS ->>>>422 string !Be\ Boot\ Loader -# jump over BPB instruction implies DOS bootsector or AdvanceMAME mbr ->>>>>0 ubelong&0xFD000000 =0xE9000000 +>>>>422 string !Be\ Boot\ Loader +# jump over BPB instruction implies DOS bootsector or AdvanceMAME mbr +>>>>>0 ubelong&0xFD000000 =0xE9000000 # AdvanceMAME mbr ->>>>>>(1.b+2) ubequad 0xfa31c08ed88ec08e +>>>>>>(1.b+2) ubequad 0xfa31c08ed88ec08e >>>>>>>446 use partition-table # mbr, Norton Utilities disc image data, or 2nd,etc. sector of x86 bootloader ->>>>>0 ubelong&0xFD000000 !0xE9000000 +>>>>>0 ubelong&0xFD000000 !0xE9000000 # skip FSInfosector ->>>>>>0 string !RRaA +>>>>>>0 string !RRaA # skip 3rd sector of MS x86 bootloader with assember instructions cli;MOVZX EAX,BYTE PTR [BP+10];MOV ECX, # http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm ->>>>>>>0 ubequad !0xfa660fb64610668b +>>>>>>>0 ubequad !0xfa660fb64610668b # skip 13rd sector of MS x86 bootloader ->>>>>>>>0 ubequad !0x660fb64610668b4e +>>>>>>>>0 ubequad !0x660fb64610668b4e # skip sector starting with DOS new line ->>>>>>>>>0 string !\r\n +>>>>>>>>>0 string !\r\n # allowed active flag 0,80h-FFh ->>>>>>>>>>446 ubyte 0 +>>>>>>>>>>446 ubyte 0 >>>>>>>>>>>446 use partition-table ->>>>>>>>>>446 ubyte >0x7F +>>>>>>>>>>446 ubyte >0x7F >>>>>>>>>>>446 use partition-table # TODO: test for extended bootrecord (ebr) moved and merged with mbr partition table entries # mbr partition table entries end # http://www.acronis.de/ #FAT label=ACRONIS\ SZ #OEM-ID=BOOTWIZ0 ->442 string Non-system\ disk,\ +>442 string Non-system\ disk,\040 >>459 string press\ any\ key...\x7\0 \b, Acronis Startup Recovery Loader # updated by Joerg Jenderek at Nov 2012, Sep 2013 # DOS names like F11.SYS or BOOTWIZ.SYS are 8 right space padded bytes+3 bytes # display 1 space ->>>447 ubyte x \b +>>>447 ubyte x \b >>>477 use DOS-filename # ->185 string FDBOOT\ Version\ ->>204 string \rNo\ Systemdisk.\ ->>>220 string Booting\ from\ harddisk.\n\r ->>>245 string Cannot\ load\ from\ harddisk.\n\r ->>>>273 string Insert\ Systemdisk\ +>185 string FDBOOT\ Version\040 +>>204 string \rNo\ Systemdisk.\040 +>>>220 string Booting\ from\ harddisk.\n\r +>>>245 string Cannot\ load\ from\ harddisk.\n\r +>>>>273 string Insert\ Systemdisk\040 >>>>>291 string and\ press\ any\ key.\n\r \b, FDBOOT harddisk Bootloader >>>>>>200 string >\0 \b, version %-3s ->242 string Bootsector\ from\ C.H.\ Hochst\204 +>242 string Bootsector\ from\ C.H.\ Hochst\204 # http://freecode.com/projects/dosfstools dosfstools-n.m/src/mkdosfs.c # updated by Joerg Jenderek at Nov 2012. Use search directive with offset instead of string # skip name "C.H. Hochstaetter" partly because it is sometimes written without umlaut ->242 search/127 Bootsector\ from\ C.H.\ Hochst ->>278 search/127 No\ Systemdisk.\ Booting\ from\ harddisk +>242 search/127 Bootsector\ from\ C.H.\ Hochst +>>278 search/127 No\ Systemdisk.\ Booting\ from\ harddisk # followed by variants with point,CR-NL or NL-CR ->>>208 search/261 Cannot\ load\ from\ harddisk. +>>>208 search/261 Cannot\ load\ from\ harddisk. # followed by variants CR-NL or NL-CR ->>>>236 search/235 Insert\ Systemdisk\ and\ press\ any\ key. +>>>>236 search/235 Insert\ Systemdisk\ and\ press\ any\ key. # followed by variants with point,CR-NL or NL-CR >>>>>180 search/96 Disk\ formatted\ with\ WinImage\ \b, WinImage harddisk Bootloader # followed by string like "6.50 (c) 1993-2004 Gilles Vollant" >>>>>>&0 string x \b, version %-4.4s ->(1.b+2) ubyte 0xe ->>(1.b+3) ubyte 0x1f ->>>(1.b+4) ubyte 0xbe +>(1.b+2) ubyte 0xe +>>(1.b+3) ubyte 0x1f +>>>(1.b+4) ubyte 0xbe # message offset found at (1.b+5) is 0x77 for FAT32 or 0x5b for others ->>>>(1.b+5) ubyte&0xd3 0x53 ->>>>>(1.b+6) ubyte 0x7c +>>>>(1.b+5) ubyte&0xd3 0x53 +>>>>>(1.b+6) ubyte 0x7c # assembler instructions: lodsb;and al,al;jz 0xb;push si;mov ah, ->>>>>>(1.b+7) ubyte 0xac ->>>>>>>(1.b+8) ubyte 0x22 ->>>>>>>>(1.b+9) ubyte 0xc0 ->>>>>>>>>(1.b+10) ubyte 0x74 ->>>>>>>>>>(1.b+11) ubyte 0x0b ->>>>>>>>>>>(1.b+12) ubyte 0x56 +>>>>>>(1.b+7) ubyte 0xac +>>>>>>>(1.b+8) ubyte 0x22 +>>>>>>>>(1.b+9) ubyte 0xc0 +>>>>>>>>>(1.b+10) ubyte 0x74 +>>>>>>>>>>(1.b+11) ubyte 0x0b +>>>>>>>>>>>(1.b+12) ubyte 0x56 >>>>>>>>>>>>(1.b+13) ubyte 0xb4 \b, mkdosfs boot message display # FAT1X version ->>>>>>>>>>>>>(1.b+5) ubyte 0x5b +>>>>>>>>>>>>>(1.b+5) ubyte 0x5b >>>>>>>>>>>>>>0x5b string >\0 "%-s" # FAT32 version ->>>>>>>>>>>>>(1.b+5) ubyte 0x77 +>>>>>>>>>>>>>(1.b+5) ubyte 0x77 >>>>>>>>>>>>>>0x77 string >\0 "%-s" >214 string Please\ try\ to\ install\ FreeDOS\ \b, DOS Emulator boot message display -#>>244 string from\ dosemu-freedos-*-bin.tgz\r -#>>>170 string Sorry,\ could\ not\ load\ an\ -#>>>>195 string operating\ system.\r\n +#>>244 string from\ dosemu-freedos-*-bin.tgz\r +#>>>170 string Sorry,\ could\ not\ load\ an\040 +#>>>>195 string operating\ system.\r\n # ->103 string This\ is\ not\ a\ bootable\ disk.\ ->>132 string Please\ insert\ a\ bootable\ ->>>157 string floppy\ and\r\n +>103 string This\ is\ not\ a\ bootable\ disk.\040 +>>132 string Please\ insert\ a\ bootable\040 +>>>157 string floppy\ and\r\n >>>>169 string press\ any\ key\ to\ try\ again...\r \b, FREE-DOS message display # ->66 string Solaris\ Boot\ Sector ->>99 string Incomplete\ MDBoot\ load. +>66 string Solaris\ Boot\ Sector +>>99 string Incomplete\ MDBoot\ load. >>>89 string Version \b, Sun Solaris Bootloader >>>>97 byte x version %c # ->408 string OS/2\ !!\ SYS01475\r\0 ->>429 string OS/2\ !!\ SYS02025\r\0 ->>>450 string OS/2\ !!\ SYS02027\r\0 +>408 string OS/2\ !!\ SYS01475\r\0 +>>429 string OS/2\ !!\ SYS02025\r\0 +>>>450 string OS/2\ !!\ SYS02027\r\0 >>>469 string OS2BOOT\ \ \ \ \b, IBM OS/2 Warp bootloader # ->409 string OS/2\ !!\ SYS01475\r\0 ->>430 string OS/2\ !!\ SYS02025\r\0 ->>>451 string OS/2\ !!\ SYS02027\r\0 +>409 string OS/2\ !!\ SYS01475\r\0 +>>430 string OS/2\ !!\ SYS02025\r\0 +>>>451 string OS/2\ !!\ SYS02027\r\0 >>>470 string OS2BOOT\ \ \ \ \b, IBM OS/2 Warp Bootloader ->112 string This\ disk\ is\ not\ bootable\r ->>142 string If\ you\ wish\ to\ make\ it\ bootable ->>>176 string run\ the\ DOS\ program\ SYS\ ->>>200 string after\ the\r ->>>>216 string system\ has\ been\ loaded\r\n ->>>>>242 string Please\ insert\ a\ DOS\ diskette\ ->>>>>271 string into\r\n\ the\ drive\ and\ +>112 string This\ disk\ is\ not\ bootable\r +>>142 string If\ you\ wish\ to\ make\ it\ bootable +>>>176 string run\ the\ DOS\ program\ SYS\040 +>>>200 string after\ the\r +>>>>216 string system\ has\ been\ loaded\r\n +>>>>>242 string Please\ insert\ a\ DOS\ diskette\040 +>>>>>271 string into\r\n\ the\ drive\ and\040 >>>>>>292 string strike\ any\ key...\0 \b, IBM OS/2 Warp message display # XP ->430 string NTLDR\ is\ missing\xFF\r\n ->>449 string Disk\ error\xFF\r\n +>430 string NTLDR\ is\ missing\xFF\r\n +>>449 string Disk\ error\xFF\r\n >>>462 string Press\ any\ key\ to\ restart\r \b, Microsoft Windows XP Bootloader # DOS names like NTLDR,CMLDR,$LDR$ are 8 right space padded bytes+3 bytes ->>>>417 ubyte&0xDF >0 +>>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s ->>>>>>422 ubyte&0xDF >0 +>>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s ->>>>>425 ubyte&0xDF >0 +>>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # ->>>>371 ubyte >0x20 ->>>>>368 ubyte&0xDF >0 +>>>>371 ubyte >0x20 +>>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s ->>>>>>>373 ubyte&0xDF >0 +>>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s ->>>>>>376 ubyte&0xDF >0 +>>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # ->430 string NTLDR\ nicht\ gefunden\xFF\r\n ->>453 string Datentr\204gerfehler\xFF\r\n +>430 string NTLDR\ nicht\ gefunden\xFF\r\n +>>453 string Datentr\204gerfehler\xFF\r\n >>>473 string Neustart\ mit\ beliebiger\ Taste\r \b, Microsoft Windows XP Bootloader (german) ->>>>417 ubyte&0xDF >0 +>>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s ->>>>>>422 ubyte&0xDF >0 +>>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s ->>>>>425 ubyte&0xDF >0 +>>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # offset variant ->>>>379 string \0 ->>>>>368 ubyte&0xDF >0 +>>>>379 string \0 +>>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s ->>>>>>>373 ubyte&0xDF >0 +>>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s # ->430 string NTLDR\ fehlt\xFF\r\n ->>444 string Datentr\204gerfehler\xFF\r\n +>430 string NTLDR\ fehlt\xFF\r\n +>>444 string Datentr\204gerfehler\xFF\r\n >>>464 string Neustart\ mit\ beliebiger\ Taste\r \b, Microsoft Windows XP Bootloader (2.german) ->>>>417 ubyte&0xDF >0 +>>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s ->>>>>>422 ubyte&0xDF >0 +>>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s ->>>>>425 ubyte&0xDF >0 +>>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # variant ->>>>371 ubyte >0x20 ->>>>>368 ubyte&0xDF >0 +>>>>371 ubyte >0x20 +>>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s ->>>>>>>373 ubyte&0xDF >0 +>>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s ->>>>>>376 ubyte&0xDF >0 +>>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # ->430 string NTLDR\ fehlt\xFF\r\n ->>444 string Medienfehler\xFF\r\n +>430 string NTLDR\ fehlt\xFF\r\n +>>444 string Medienfehler\xFF\r\n >>>459 string Neustart:\ Taste\ dr\201cken\r \b, Microsoft Windows XP Bootloader (3.german) ->>>>371 ubyte >0x20 ->>>>>368 ubyte&0xDF >0 +>>>>371 ubyte >0x20 +>>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s ->>>>>>>373 ubyte&0xDF >0 +>>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s ->>>>>>376 ubyte&0xDF >0 +>>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # variant ->>>>417 ubyte&0xDF >0 +>>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s ->>>>>>422 ubyte&0xDF >0 +>>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s ->>>>>425 ubyte&0xDF >0 +>>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # ->430 string Datentr\204ger\ entfernen\xFF\r\n ->>454 string Medienfehler\xFF\r\n +>430 string Datentr\204ger\ entfernen\xFF\r\n +>>454 string Medienfehler\xFF\r\n >>>469 string Neustart:\ Taste\ dr\201cken\r \b, Microsoft Windows XP Bootloader (4.german) ->>>>379 string \0 ->>>>>368 ubyte&0xDF >0 +>>>>379 string \0 +>>>>>368 ubyte&0xDF >0 >>>>>>368 string x %-.5s ->>>>>>>373 ubyte&0xDF >0 +>>>>>>>373 ubyte&0xDF >0 >>>>>>>>373 string x \b%-.3s ->>>>>>376 ubyte&0xDF >0 +>>>>>>376 ubyte&0xDF >0 >>>>>>>376 string x \b.%-.3s # variant ->>>>417 ubyte&0xDF >0 +>>>>417 ubyte&0xDF >0 >>>>>417 string x %-.5s ->>>>>>422 ubyte&0xDF >0 +>>>>>>422 ubyte&0xDF >0 >>>>>>>422 string x \b%-.3s ->>>>>425 ubyte&0xDF >0 +>>>>>425 ubyte&0xDF >0 >>>>>>425 string >\ \b.%-.3s # -#>3 string NTFS\ \ \ \ ->389 string Fehler\ beim\ Lesen\ +#>3 string NTFS\ \ \ \040 +>389 string Fehler\ beim\ Lesen\040 >>407 string des\ Datentr\204gers ->>>426 string NTLDR\ fehlt +>>>426 string NTLDR\ fehlt >>>>440 string NTLDR\ ist\ komprimiert >>>>>464 string Neustart\ mit\ Strg+Alt+Entf\r \b, Microsoft Windows XP Bootloader NTFS (german) -#>3 string NTFS\ \ \ \ +#>3 string NTFS\ \ \ \040 >313 string A\ disk\ read\ error\ occurred.\r ->>345 string A\ kernel\ file\ is\ missing\ ->>>370 string from\ the\ disk.\r ->>>>484 string NTLDR\ is\ compressed ->>>>>429 string Insert\ a\ system\ diskette\ +>>345 string A\ kernel\ file\ is\ missing\040 +>>>370 string from\ the\ disk.\r +>>>>484 string NTLDR\ is\ compressed +>>>>>429 string Insert\ a\ system\ diskette\040 >>>>>>454 string and\ restart\r\nthe\ system.\r \b, Microsoft Windows XP Bootloader NTFS # DOS loader variants different languages,offsets >472 ubyte&0xDF >0 ->>389 string Invalid\ system\ disk\xFF\r\n ->>>411 string Disk\ I/O\ error ->>>>428 string Replace\ the\ disk,\ and\ +>>389 string Invalid\ system\ disk\xFF\r\n +>>>411 string Disk\ I/O\ error +>>>>428 string Replace\ the\ disk,\ and\040 >>>>>455 string press\ any\ key \b, Microsoft Windows 98 Bootloader #IO.SYS ->>>>>>472 ubyte&0xDF >0 +>>>>>>472 ubyte&0xDF >0 >>>>>>>472 string x \b %-.2s ->>>>>>>>474 ubyte&0xDF >0 +>>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.5s ->>>>>>>>>>479 ubyte&0xDF >0 +>>>>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>>>479 string x \b%-.1s ->>>>>>>480 ubyte&0xDF >0 +>>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s ->>>>>>>>>488 ubyte&0xDF >0 +>>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s ->>>>>>>>491 ubyte&0xDF >0 +>>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # ->>390 string Invalid\ system\ disk\xFF\r\n ->>>412 string Disk\ I/O\ error\xFF\r\n ->>>>429 string Replace\ the\ disk,\ and\ +>>390 string Invalid\ system\ disk\xFF\r\n +>>>412 string Disk\ I/O\ error\xFF\r\n +>>>>429 string Replace\ the\ disk,\ and\040 >>>>>451 string then\ press\ any\ key\r \b, Microsoft Windows 98 Bootloader ->>388 string Ungueltiges\ System\ \xFF\r\n ->>>410 string E/A-Fehler\ \ \ \ \xFF\r\n ->>>>427 string Datentraeger\ wechseln\ und\ +>>388 string Ungueltiges\ System\ \xFF\r\n +>>>410 string E/A-Fehler\ \ \ \ \xFF\r\n +>>>>427 string Datentraeger\ wechseln\ und\040 >>>>>453 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (german) #WINBOOT.SYS only not spaces (0xDF) ->>>>>>497 ubyte&0xDF >0 +>>>>>>497 ubyte&0xDF >0 >>>>>>>497 string x %-.5s ->>>>>>>>502 ubyte&0xDF >0 +>>>>>>>>502 ubyte&0xDF >0 >>>>>>>>>502 string x \b%-.1s ->>>>>>>>>>503 ubyte&0xDF >0 +>>>>>>>>>>503 ubyte&0xDF >0 >>>>>>>>>>>503 string x \b%-.1s ->>>>>>>>>>>>504 ubyte&0xDF >0 +>>>>>>>>>>>>504 ubyte&0xDF >0 >>>>>>>>>>>>>504 string x \b%-.1s ->>>>>>505 ubyte&0xDF >0 +>>>>>>505 ubyte&0xDF >0 >>>>>>>505 string x \b.%-.3s #IO.SYS >>>>>>472 ubyte&0xDF >0 or >>>>>>>472 string x \b %-.2s ->>>>>>>>474 ubyte&0xDF >0 +>>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.5s ->>>>>>>>>>479 ubyte&0xDF >0 +>>>>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>>>479 string x \b%-.1s ->>>>>>>480 ubyte&0xDF >0 +>>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s ->>>>>>>>>488 ubyte&0xDF >0 +>>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s ->>>>>>>>491 ubyte&0xDF >0 +>>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # ->>390 string Ungueltiges\ System\ \xFF\r\n ->>>412 string E/A-Fehler\ \ \ \ \xFF\r\n ->>>>429 string Datentraeger\ wechseln\ und\ +>>390 string Ungueltiges\ System\ \xFF\r\n +>>>412 string E/A-Fehler\ \ \ \ \xFF\r\n +>>>>429 string Datentraeger\ wechseln\ und\040 >>>>>455 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (German) #WINBOOT.SYS only not spaces (0xDF) ->>>>>>497 ubyte&0xDF >0 +>>>>>>497 ubyte&0xDF >0 >>>>>>>497 string x %-.7s ->>>>>>>>504 ubyte&0xDF >0 +>>>>>>>>504 ubyte&0xDF >0 >>>>>>>>>504 string x \b%-.1s ->>>>>>505 ubyte&0xDF >0 +>>>>>>505 ubyte&0xDF >0 >>>>>>>505 string x \b.%-.3s #IO.SYS >>>>>>472 ubyte&0xDF >0 or >>>>>>>472 string x \b %-.2s ->>>>>>>>474 ubyte&0xDF >0 +>>>>>>>>474 ubyte&0xDF >0 >>>>>>>>>474 string x \b%-.6s ->>>>>>>480 ubyte&0xDF >0 +>>>>>>>480 ubyte&0xDF >0 >>>>>>>>480 string x \b.%-.3s #MSDOS.SYS >>>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>>483 string x \b%-.5s ->>>>>>>>>488 ubyte&0xDF >0 +>>>>>>>>>488 ubyte&0xDF >0 >>>>>>>>>>488 string x \b%-.3s ->>>>>>>>491 ubyte&0xDF >0 +>>>>>>>>491 ubyte&0xDF >0 >>>>>>>>>491 string x \b.%-.3s # ->>389 string Ungueltiges\ System\ \xFF\r\n ->>>411 string E/A-Fehler\ \ \ \ \xFF\r\n ->>>>428 string Datentraeger\ wechseln\ und\ +>>389 string Ungueltiges\ System\ \xFF\r\n +>>>411 string E/A-Fehler\ \ \ \ \xFF\r\n +>>>>428 string Datentraeger\ wechseln\ und\040 >>>>>454 string Taste\ druecken\r \b, Microsoft Windows 95/98/ME Bootloader (GERMAN) # DOS names like IO.SYS,WINBOOT.SYS,MSDOS.SYS,WINBOOT.INI are 8 right space padded bytes+3 bytes >>>>>>472 string x %-.2s ->>>>>>>474 ubyte&0xDF >0 +>>>>>>>474 ubyte&0xDF >0 >>>>>>>>474 string x \b%-.5s ->>>>>>>>479 ubyte&0xDF >0 +>>>>>>>>479 ubyte&0xDF >0 >>>>>>>>>479 string x \b%-.1s ->>>>>>480 ubyte&0xDF >0 +>>>>>>480 ubyte&0xDF >0 >>>>>>>480 string x \b.%-.3s >>>>>>483 ubyte&0xDF >0 \b+ >>>>>>>483 string x \b%-.5s ->>>>>>>488 ubyte&0xDF >0 +>>>>>>>488 ubyte&0xDF >0 >>>>>>>>488 string x \b%-.2s ->>>>>>>>490 ubyte&0xDF >0 +>>>>>>>>490 ubyte&0xDF >0 >>>>>>>>>490 string x \b%-.1s ->>>>>>>491 ubyte&0xDF >0 +>>>>>>>491 ubyte&0xDF >0 >>>>>>>>491 string x \b.%-.3s >479 ubyte&0xDF >0 ->>416 string Kein\ System\ oder\ ->>>433 string Laufwerksfehler +>>416 string Kein\ System\ oder\040 +>>>433 string Laufwerksfehler >>>>450 string Wechseln\ und\ Taste\ dr\201cken \b, Microsoft DOS Bootloader (german) #IO.SYS >>>>>479 string x \b %-.2s ->>>>>>481 ubyte&0xDF >0 +>>>>>>481 ubyte&0xDF >0 >>>>>>>481 string x \b%-.6s ->>>>>487 ubyte&0xDF >0 +>>>>>487 ubyte&0xDF >0 >>>>>>487 string x \b.%-.3s #MSDOS.SYS >>>>>>490 ubyte&0xDF >0 \b+ >>>>>>>490 string x \b%-.5s ->>>>>>>>495 ubyte&0xDF >0 +>>>>>>>>495 ubyte&0xDF >0 >>>>>>>>>495 string x \b%-.3s ->>>>>>>498 ubyte&0xDF >0 +>>>>>>>498 ubyte&0xDF >0 >>>>>>>>498 string x \b.%-.3s # ->376 search/41 Non-System\ disk\ or\ ->>395 search/41 disk\ error\r ->>>407 search/41 Replace\ and\ +>376 search/41 Non-System\ disk\ or\040 +>>395 search/41 disk\ error\r +>>>407 search/41 Replace\ and\040 >>>>419 search/41 press\ \b, >>>>419 search/41 strike\ \b, old >>>>426 search/41 any\ key\ when\ ready\r MS or PC-DOS bootloader #449 Disk\ Boot\ failure\r MS 3.21 #466 Boot\ Failure\r MS 3.30 ->>>>>468 search/18 \0 +>>>>>468 search/18 \0 #IO.SYS,IBMBIO.COM >>>>>>&0 string x \b %-.2s ->>>>>>>&-20 ubyte&0xDF >0 +>>>>>>>&-20 ubyte&0xDF >0 >>>>>>>>&-1 string x \b%-.4s ->>>>>>>>>&-16 ubyte&0xDF >0 +>>>>>>>>>&-16 ubyte&0xDF >0 >>>>>>>>>>&-1 string x \b%-.2s >>>>>>&8 ubyte&0xDF >0 \b. >>>>>>>&-1 string x \b%-.3s #MSDOS.SYS,IBMDOS.COM >>>>>>&11 ubyte&0xDF >0 \b+ >>>>>>>&-1 string x \b%-.5s ->>>>>>>>&-6 ubyte&0xDF >0 +>>>>>>>>&-6 ubyte&0xDF >0 >>>>>>>>>&-1 string x \b%-.1s ->>>>>>>>>>&-5 ubyte&0xDF >0 +>>>>>>>>>>&-5 ubyte&0xDF >0 >>>>>>>>>>>&-1 string x \b%-.2s >>>>>>>&7 ubyte&0xDF >0 \b. >>>>>>>>&-1 string x \b%-.3s >441 string Cannot\ load\ from\ harddisk.\n\r ->>469 string Insert\ Systemdisk\ +>>469 string Insert\ Systemdisk\040 >>>487 string and\ press\ any\ key.\n\r \b, MS (2.11) DOS bootloader -#>43 string \224R-LOADER\ \ SYS =label +#>43 string \224R-LOADER\ \ SYS =label >54 string SYS >>324 string VASKK >>>495 string NEWLDR\0 \b, DR-DOS Bootloader (LOADER.SYS) # ->98 string Press\ a\ key\ to\ retry\0\r ->>120 string Cannot\ find\ file\ \0\r ->>>139 string Disk\ read\ error\0\r +>98 string Press\ a\ key\ to\ retry\0\r +>>120 string Cannot\ find\ file\ \0\r +>>>139 string Disk\ read\ error\0\r >>>>156 string Loading\ ...\0 \b, DR-DOS (3.41) Bootloader #DRBIOS.SYS ->>>>>44 ubyte&0xDF >0 +>>>>>44 ubyte&0xDF >0 >>>>>>44 string x \b %-.6s ->>>>>>>50 ubyte&0xDF >0 +>>>>>>>50 ubyte&0xDF >0 >>>>>>>>50 string x \b%-.2s ->>>>>>52 ubyte&0xDF >0 +>>>>>>52 ubyte&0xDF >0 >>>>>>>52 string x \b.%-.3s # ->70 string IBMBIO\ \ COM ->>472 string Cannot\ load\ DOS!\ +>70 string IBMBIO\ \ COM +>>472 string Cannot\ load\ DOS!\040 >>>489 string Any\ key\ to\ retry \b, DR-DOS Bootloader ->>471 string Cannot\ load\ DOS\ +>>471 string Cannot\ load\ DOS\040 >>487 string press\ key\ to\ retry \b, Open-DOS Bootloader #?? ->444 string KERNEL\ \ SYS +>444 string KERNEL\ \ SYS >>314 string BOOT\ error! \b, FREE-DOS Bootloader ->499 string KERNEL\ \ SYS +>499 string KERNEL\ \ SYS >>305 string BOOT\ err!\0 \b, Free-DOS Bootloader ->449 string KERNEL\ \ SYS +>449 string KERNEL\ \ SYS >>319 string BOOT\ error! \b, FREE-DOS 0.5 Bootloader # ->449 string Loading\ FreeDOS +>449 string Loading\ FreeDOS >>0x1AF ulelong >0 \b, FREE-DOS 0.95,1.0 Bootloader ->>>497 ubyte&0xDF >0 +>>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s ->>>>>503 ubyte&0xDF >0 +>>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s ->>>>>>>504 ubyte&0xDF >0 +>>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s ->>>>505 ubyte&0xDF >0 +>>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s # >331 string Error!.0 \b, FREE-DOS 1.0 bootloader # ->125 string Loading\ FreeDOS...\r +>125 string Loading\ FreeDOS...\r >>311 string BOOT\ error!\r \b, FREE-DOS bootloader ->>>441 ubyte&0xDF >0 +>>>441 ubyte&0xDF >0 >>>>441 string x \b %-.6s ->>>>>447 ubyte&0xDF >0 +>>>>>447 ubyte&0xDF >0 >>>>>>447 string x \b%-.1s ->>>>>>>448 ubyte&0xDF >0 +>>>>>>>448 ubyte&0xDF >0 >>>>>>>>448 string x \b%-.1s ->>>>449 ubyte&0xDF >0 +>>>>449 ubyte&0xDF >0 >>>>>449 string x \b.%-.3s ->124 string FreeDOS\0 +>124 string FreeDOS\0 >>331 string \ err\0 \b, FREE-DOS BETa 0.9 Bootloader # DOS names like KERNEL.SYS,KERNEL16.SYS,KERNEL32.SYS,METAKERN.SYS are 8 right space padded bytes+3 bytes ->>>497 ubyte&0xDF >0 +>>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s ->>>>>503 ubyte&0xDF >0 +>>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s ->>>>>>>504 ubyte&0xDF >0 +>>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s ->>>>505 ubyte&0xDF >0 +>>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s >>333 string \ err\0 \b, FREE-DOS BEta 0.9 Bootloader ->>>497 ubyte&0xDF >0 +>>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s ->>>>>503 ubyte&0xDF >0 +>>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s ->>>>>>>504 ubyte&0xDF >0 +>>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s ->>>>505 ubyte&0xDF >0 +>>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s >>334 string \ err\0 \b, FREE-DOS Beta 0.9 Bootloader ->>>497 ubyte&0xDF >0 +>>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s ->>>>>503 ubyte&0xDF >0 +>>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s ->>>>>>>504 ubyte&0xDF >0 +>>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s ->>>>505 ubyte&0xDF >0 +>>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s ->336 string Error!\ +>336 string Error!\040 >>343 string Hit\ a\ key\ to\ reboot. \b, FREE-DOS Beta 0.9sr1 Bootloader ->>>497 ubyte&0xDF >0 +>>>497 ubyte&0xDF >0 >>>>497 string x \b %-.6s ->>>>>503 ubyte&0xDF >0 +>>>>>503 ubyte&0xDF >0 >>>>>>503 string x \b%-.1s ->>>>>>>504 ubyte&0xDF >0 +>>>>>>>504 ubyte&0xDF >0 >>>>>>>>504 string x \b%-.1s ->>>>505 ubyte&0xDF >0 +>>>>505 ubyte&0xDF >0 >>>>>505 string x \b.%-.3s # added by Joerg Jenderek # http://www.visopsys.org/ # http://partitionlogic.org.uk/ # OEM-ID=Visopsys ->478 ulelong 0 ->>(1.b+326) string I/O\ Error\ reading\ ->>>(1.b+344) string Visopsys\ loader\r +>478 ulelong 0 +>>(1.b+326) string I/O\ Error\ reading\040 +>>>(1.b+344) string Visopsys\ loader\r >>>>(1.b+361) string Press\ any\ key\ to\ continue.\r \b, Visopsys loader # http://alexfru.chat.ru/epm.html#bootprog ->494 ubyte >0x4D ->>495 string >E ->>>495 string 494 ubyte >0x4D +>>495 string >E +>>>495 string >>>3 string BootProg +>>>>3 string BootProg # It just looks for a program file name at the root directory # and loads corresponding file with following execution. # DOS names like STARTUP.BIN,STARTUPC.COM,STARTUPE.EXE are 8 right space padded bytes+3 bytes ->>>>499 ubyte&0xDF >0 \b, COM/EXE Bootloader +>>>>499 ubyte&0xDF >0 \b, COM/EXE Bootloader >>>>>499 use DOS-filename #If the boot sector fails to read any other sector, #it prints a very short message ("RE") to the screen and hangs the computer. @@ -1025,23 +1025,23 @@ # added by Joerg Jenderek at Feb 2013 according to http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO # and http://en.wikipedia.org/wiki/File_Allocation_Table#FS_Information_Sector ->0 string RRaA +>0 string RRaA >>0x1E4 string rrAa \b, FSInfosector #>>0x1FC uleshort =0 SHOULD BE ZERO >>>0x1E8 ulelong <0xffffffff \b, %u free clusters >>>0x1EC ulelong <0xffffffff \b, last allocated cluster %u # updated by Joerg Jenderek at Sep 2007 ->3 ubyte 0 +>3 ubyte 0 #no active flag ->>446 ubyte 0 +>>446 ubyte 0 # partition 1 not empty ->>>450 ubyte >0 +>>>450 ubyte >0 # partitions 3,4 empty ->>>>482 ubyte 0 ->>>>>498 ubyte 0 +>>>>482 ubyte 0 +>>>>>498 ubyte 0 # partition 2 ID=0,5,15 ->>>>>>466 ubyte <0x10 +>>>>>>466 ubyte <0x10 >>>>>>>466 ubyte 0x05 \b, extended partition table >>>>>>>466 ubyte 0x0F \b, extended partition table (LBA) >>>>>>>466 ubyte 0x0 \b, extended partition table (last) @@ -1054,35 +1054,35 @@ # Print the DOS filenames from directory entry form with 8 right space padded bytes + 3 bytes for extension # like IO.SYS. MSDOS.SYS , KERNEL.SYS , DRBIO.SYS 0 name DOS-filename -# space=0x20 (00100000b) means empty ->0 ubyte&0xDF >0 +# space=0x20 (00100000b) means empty +>0 ubyte&0xDF >0 >>0 ubyte x \b%c ->>>1 ubyte&0xDF >0 +>>>1 ubyte&0xDF >0 >>>>1 ubyte x \b%c ->>>>>2 ubyte&0xDF >0 +>>>>>2 ubyte&0xDF >0 >>>>>>2 ubyte x \b%c ->>>>>>>3 ubyte&0xDF >0 +>>>>>>>3 ubyte&0xDF >0 >>>>>>>>3 ubyte x \b%c ->>>>>>>>>4 ubyte&0xDF >0 +>>>>>>>>>4 ubyte&0xDF >0 >>>>>>>>>>4 ubyte x \b%c ->>>>>>>>>>>5 ubyte&0xDF >0 +>>>>>>>>>>>5 ubyte&0xDF >0 >>>>>>>>>>>>5 ubyte x \b%c ->>>>>>>>>>>>>6 ubyte&0xDF >0 +>>>>>>>>>>>>>6 ubyte&0xDF >0 >>>>>>>>>>>>>>6 ubyte x \b%c ->>>>>>>>>>>>>>>7 ubyte&0xDF >0 +>>>>>>>>>>>>>>>7 ubyte&0xDF >0 >>>>>>>>>>>>>>>>7 ubyte x \b%c # DOS filename extension >>8 ubyte&0xDF >0 \b. >>>8 ubyte x \b%c ->>>>9 ubyte&0xDF >0 +>>>>9 ubyte&0xDF >0 >>>>>9 ubyte x \b%c ->>>>>>10 ubyte&0xDF >0 +>>>>>>10 ubyte&0xDF >0 >>>>>>>10 ubyte x \b%c # Print 2 following DOS filenames from directory entry form # like IO.SYS+MSDOS.SYS or ibmbio.com+ibmdos.com 0 name 2xDOS-filename # display 1 space ->0 ubyte x \b +>0 ubyte x \b >0 use DOS-filename >11 ubyte x \b+ >11 use DOS-filename @@ -1101,10 +1101,10 @@ # partition type ID > 0 >4 ubyte >0 # active flag 0 ->>0 ubyte 0 +>>0 ubyte 0 >>>0 use partition-entry -# active flag 0x80, 0x81, ... ->>0 ubyte >0x7F +# active flag 0x80, 0x81, ... +>>0 ubyte >0x7F >>>0 use partition-entry # Print entry of partition table 0 name partition-entry @@ -1136,7 +1136,7 @@ # sector >1 ubyte&0x3F x \b,%u -# FATX +# FATX 0 string FATX FATX filesystem data # romfs filesystems - Juan Cespedes @@ -1157,7 +1157,7 @@ # http://syslinux.zytor.com/iso.php # tested with versions 1.47,1.48,1.49,1.50,1.62,1.76,2.00,2.10;3.00,3.11,3.31,;3.70,3.71,3.73,3.75,3.80,3.82,3.84,3.86,4.01,4.03 and 4.05 # assembler instructions: cli;jmp 0:7Cyy (yy=0x40,0x5e,0x6c,0x6e,0x77);nop;nop -0 ulequad&0x909000007cc0eafa 0x909000007c40eafa +0 ulequad&0x909000007cc0eafa 0x909000007c40eafa >631 search/689 ISOLINUX\ isolinux Loader >>&0 string x (version %-4.4s) # http://syslinux.zytor.com/pxe.php @@ -1174,88 +1174,88 @@ >11 string x (version %-4.4s) # syslinux updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012 # assembler instructions: jmp yy (yy=0x3c,0x58);nop;"SYSLINUX" -0 ulelong&0x80909bEB 0x009018EB +0 ulelong&0x80909bEB 0x009018EB # OEM-ID not always "SYSLINUX" ->434 search/47 Boot\ failed -# followed by \r\n\0 or :\ +>434 search/47 Boot\ failed +# followed by \r\n\0 or :\ >>482 search/132 \0LDLINUX\ SYS Syslinux bootloader (version 2.13 or older) >>1 ubyte 0x58 Syslinux bootloader (version 3.0-3.9) ->459 search/30 Boot\ error\r\n\0 +>459 search/30 Boot\ error\r\n\0 >>1 ubyte 0x58 Syslinux bootloader (version 3.10 or newer) # SYSLINUX MBR updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012 # assembler instructions: mov di,0600h;mov cx,0100h -16 search/4 \xbf\x00\x06\xb9\x00\x01 +16 search/4 \xbf\x00\x06\xb9\x00\x01 # to display SYSLINUX MBR (36) before old DOS/MBR boot sector one with partition table (strength=50+21) !:strength +36 ->94 search/249 Missing\ operating\ system +>94 search/249 Missing\ operating\ system # followed by \r for versions older 3.35 , .\r for versions newer 3.52 and point for other # skip Ranish MBR ->>408 search/4 HD1/\0 ->>408 default x +>>408 search/4 HD1/\0 +>>408 default x >>>250 search/118 \0Operating\ system\ load SYSLINUX MBR # followed by "ing " or space ->>>>292 search/98 error +>>>>292 search/98 error >>>>>&0 string \r (version 3.35 or older) >>>>>&0 string .\r (version 3.52 or newer) >>>>>&0 default x (version 3.36-3.51 ) >368 search/106 \0Disk\ error\ on\ boot\r\n SYSLINUX GPT-MBR ->>156 search/10 \0Boot\ partition\ not\ found\r\n +>>156 search/10 \0Boot\ partition\ not\ found\r\n >>>270 search/10 \0OS\ not\ bootable\r\n (version 3.86 or older) ->>174 search/10 \0Missing\ OS\r\n +>>174 search/10 \0Missing\ OS\r\n >>>189 search/10 \0Multiple\ active\ partitions\r\n (version 4.00 or newer) # SYSLINUX END # NetBSD mbr variants (master-boot-code version 1.22) added by Joerg Jenderek at Nov 2012 # assembler instructions: xor ax,ax;mov ax,ss;mov sp,0x7c00;mov ax, -0 ubequad 0x31c08ed0bc007c8e +0 ubequad 0x31c08ed0bc007c8e # mbr_bootsel magic before partition table not reliable with small ipl fragments -#>444 uleshort 0xb5e1 ->0004 uleshort x +#>444 uleshort 0xb5e1 +>0004 uleshort x # ERRorTeXT >>181 search/166 Error\ \0\r\n NetBSD mbr # NT Drive Serial Number http://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm#DS >>>0x1B8 ubelong >0 \b,Serial 0x%-.8x # BOOTSEL definitions contains assembler instructions: int 0x13;pop dx;push dx;push dx >>>0xbb search/71 \xcd\x13\x5a\x52\x52 \b,bootselector -# BOOT_EXTENDED definitions contains assembler instructions: +# BOOT_EXTENDED definitions contains assembler instructions: # xchg ecx,edx;addl ecx,edx;movw lba_info,si;movb 0x42,ah;pop dx;push dx;int 0x13 >>>0x96 search/1 \x66\x87\xca\x66\x01\xca\x66\x89\x16\x3a\x07\xbe\x32\x07\xb4\x42\x5a\x52\xcd\x13 \b,boot extended # COM_PORT_VAL definitions contains assembler instructions: outb al,dx;add 5,dl;inb %dx;test 0x40,al >>>0x130 search/55 \xee\x80\xc2\x05\xec\xa8\x40 \b,serial IO # not TERSE_ERROR ->>>196 search/106 No\ active\ partition\0 ->>>>&0 string Disk\ read\ error\0 +>>>196 search/106 No\ active\ partition\0 +>>>>&0 string Disk\ read\ error\0 >>>>>&0 string No\ operating\ system\0 \b,verbose # not NO_CHS definitions contains assembler instructions: pop dx;push dx;movb $8,ah;int0x13 >>>0x7d search/7 \x5a\x52\xb4\x08\xcd\x13 \b,CHS # not NO_LBA_CHECK definitions contains assembler instructions: movw 0x55aa,bx;movb 0x41,ah;pop dx;push dx;int 0x13 >>>0xa4 search/84 \xbb\xaa\x55\xb4\x41\x5a\x52\xcd\x13 \b,LBA-check # assembler instructions: movw nametab,bx ->>>0x26 search/21 \xBB\x94\x07 +>>>0x26 search/21 \xBB\x94\x07 # not NO_BANNER definitions contains assembler instructions: mov banner,si;call message_crlf ->>>>&-9 ubequad&0xBE00f0E800febb94 0xBE0000E80000bb94 ->>>>>181 search/166 Error\ \0 +>>>>&-9 ubequad&0xBE00f0E800febb94 0xBE0000E80000bb94 +>>>>>181 search/166 Error\ \0 # "a: disk" , "Fn: diskn" or "NetBSD MBR boot" >>>>>>&3 string x \b,"%s" >>>446 use partition-table # Andrea Mazzoleni AdvanceCD mbr loader of http://advancemame.sourceforge.net/boot-readme.html # added by Joerg Jenderek at Nov 2012 for versions 1.3 - 1.4 # assembler instructions: jmp short 0x58;nop;ASCII -0 ubequad&0xeb58908000000000 0xeb58900000000000 +0 ubequad&0xeb58908000000000 0xeb58900000000000 # assembler instructions: cli;xor ax,ax;mov ds,ax;mov es,ax;mov ss, ->(1.b+2) ubequad 0xfa31c08ed88ec08e +>(1.b+2) ubequad 0xfa31c08ed88ec08e # Error messages at end of code ->>376 string No\ operating\ system\r\n\0 ->>>398 string Disk\ error\r\n\0FDD\0HDD\0 +>>376 string No\ operating\ system\r\n\0 +>>>398 string Disk\ error\r\n\0FDD\0HDD\0 >>>>419 string \ EBIOS\r\n\0 AdvanceMAME mbr -# Neil Turton mbr loader variant of http://www.chiark.greenend.org.uk/~neilt/mbr/ +# Neil Turton mbr loader variant of http://www.chiark.greenend.org.uk/~neilt/mbr/ # added by Joerg Jenderek at Mar 2011 for versions 1.0.0 - 1.1.11 # for 1st version assembler instructions: cld;xor ax,ax;mov DS,ax;MOV ES,AX;mov SI, # or cld;xor ax,ax;mov SS,ax;XOR SP,SP;mov DS, -0 ulequad&0xcE1b40D48EC031FC 0x8E0000D08EC031FC +0 ulequad&0xcE1b40D48EC031FC 0x8E0000D08EC031FC # pointer to the data starting with Neil Turton signature string ->(0x1BC.s) string NDTmbr +>(0x1BC.s) string NDTmbr >>&-14 string 1234F\0 Turton mbr ( # parameters also viewed by install-mbr --list >>>(0x1BC.s+7) ubyte x \b%u<= @@ -1269,23 +1269,23 @@ #0x0~1,0x1~2,...,0x3~4,0x4~F,0x7~D default boot #>>>(0x1BC.s+11) ubyte x \b,cfg_def 0x%x # for older versions ->>>(0x1BC.s+9) ubyte <2 +>>>(0x1BC.s+9) ubyte <2 #>>>>(0x1BC.s+12) ubyte 18 \b,%hhu/18 seconds >>>>(0x1BC.s+12) ubyte !18 \b,%u/18 seconds # floppy A: or B: >>>>(0x1BC.s+13) ubyte <2 \b,floppy 0x%x ->>>>(0x1BC.s+13) ubyte >1 +>>>>(0x1BC.s+13) ubyte >1 # 1st hard disc #>>>>>(0x1BC.s+13) ubyte 0x80 \b,drive 0x%x # not 1st hard disc >>>>>(0x1BC.s+13) ubyte !0x80 \b,drive 0x%x # for version >= 2 maximal timeout can be 65534 ->>>(0x1BC.s+9) ubyte >1 +>>>(0x1BC.s+9) ubyte >1 #>>>>(0x1BC.s+12) uleshort 18 \b,%u/18 seconds >>>>(0x1BC.s+12) uleshort !18 \b,%u/18 seconds # floppy A: or B: >>>>(0x1BC.s+14) ubyte <2 \b,floppy 0x%x ->>>>(0x1BC.s+14) ubyte >1 +>>>>(0x1BC.s+14) ubyte >1 # 1st hard disc #>>>>>(0x1BC.s+14) ubyte 0x80 \b,drive 0x%x # not 1st hard disc @@ -1297,14 +1297,14 @@ # grub-1.94/kern/i386/pc/startup.S # http://www.gnu.org/software/grub/manual/grub.html#Embedded-data # usual values are marked with comments to get only informations of strange GRUB loaders -0x200 uleshort 0x70EA +0x200 uleshort 0x70EA # found only version 3.{1,2} ->0x206 ubeshort >0x0300 +>0x206 ubeshort >0x0300 # GRUB version (0.5.)95,0.93,0.94,0.96,0.97 > "00" ->>0x212 ubyte >0x29 ->>>0x213 ubyte >0x29 +>>0x212 ubyte >0x29 +>>>0x213 ubyte >0x29 # not iso9660_stage1_5 -#>>>0 ulelong&0x00BE5652 0x00BE5652 +#>>>0 ulelong&0x00BE5652 0x00BE5652 >>>>0x213 ubyte >0x29 GRand Unified Bootloader # config_file for stage1_5 is 0xffffffff + default "/boot/grub/stage2" >>>>0x217 ubyte 0xFF stage1_5 @@ -1316,7 +1316,7 @@ #>>>>0x208 ulelong =0xffffff \b, %lu (default) >>>>0x208 ulelong >0xffffff \b, installed partition %u # GRUB 0.5.95 unofficial ->>>>0x20C ulelong&0x2E300000 0x2E300000 +>>>>0x20C ulelong&0x2E300000 0x2E300000 # 0=stage2 1=ffs 2=e2fs 3=fat 4=minix 5=reiserfs >>>>>0x20C ubyte x \b, identifier 0x%x #>>>>>0x20D ubyte =0 \b, LBA flag 0x%x (default) @@ -1324,17 +1324,17 @@ # GRUB version as string >>>>>0x20E string >\0 \b, GRUB version %-s # for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default ->>>>>>0x215 ulong 0xffffffff +>>>>>>0x215 ulong 0xffffffff >>>>>>>0x219 string >\0 \b, configuration file %-s ->>>>>>0x215 ulong !0xffffffff +>>>>>>0x215 ulong !0xffffffff >>>>>>>0x215 string >\0 \b, configuration file %-s # newer GRUB versions ->>>>0x20C ulelong&0x2E300000 !0x2E300000 +>>>>0x20C ulelong&0x2E300000 !0x2E300000 ##>>>>>0x20C ulelong =0 \b, saved entry %d (usual) >>>>>0x20C ulelong >0 \b, saved entry %d # for 1.94 contains kernel image size # for 0.93,0.94,0.96,0.97 -# 0=stage2 1=ffs 2=e2fs 3=fat 4=minix 5=reiserfs 6=vstafs 7=jfs 8=xfs 9=iso9660 a=ufs2 +# 0=stage2 1=ffs 2=e2fs 3=fat 4=minix 5=reiserfs 6=vstafs 7=jfs 8=xfs 9=iso9660 a=ufs2 >>>>>0x210 ubyte x \b, identifier 0x%x # The flag for LBA forcing is in most cases 0 #>>>>>0x211 ubyte =0 \b, LBA flag 0x%x (default) @@ -1342,9 +1342,9 @@ # GRUB version as string >>>>>0x212 string >\0 \b, GRUB version %-s # for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default ->>>>>0x217 ulong 0xffffffff +>>>>>0x217 ulong 0xffffffff >>>>>>0x21b string >\0 \b, configuration file %-s ->>>>>0x217 ulong !0xffffffff +>>>>>0x217 ulong !0xffffffff >>>>>>0x217 string >\0 \b, configuration file %-s # DOS x86 sector updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at May 2011 @@ -1360,13 +1360,13 @@ # mtools-3.9.8/msdos.h # usual values are marked with comments to get only informations of strange FAT systems # valid sectorsize must be a power of 2 from 32 to 32768 ->11 uleshort&0x001f 0 ->>11 uleshort <32769 ->>>11 uleshort >31 ->>>>21 ubyte&0xf0 0xF0 +>11 uleshort&0x001f 0 +>>11 uleshort <32769 +>>>11 uleshort >31 +>>>>21 ubyte&0xf0 0xF0 >>>>>0 ubyte 0xEB DOS/MBR boot sector >>>>>>1 ubyte x \b, code offset 0x%x+2 ->>>>>0 ubyte 0xE9 +>>>>>0 ubyte 0xE9 >>>>>>1 uleshort x \b, code offset 0x%x+3 >>>>>3 string >\0 \b, OEM-ID "%-.8s" #http://mirror.href.com/thestarman/asm/debug/debug2.htm#IHC @@ -1377,10 +1377,10 @@ >>>>>13 ubyte >1 \b, sectors/cluster %u #>>>>>13 ubyte =1 \b, sectors/cluster %u (usual on Floppies) # for lazy FAT32 implementation like Transcend digital photo frame PF830 ->>>>>82 string/c fat32 +>>>>>82 string/c fat32 >>>>>>14 uleshort !32 \b, reserved sectors %u #>>>>>>14 uleshort =32 \b, reserved sectors %u (usual Fat32) ->>>>>82 string/c !fat32 +>>>>>82 string/c !fat32 >>>>>>14 uleshort >1 \b, reserved sectors %u #>>>>>>14 uleshort =1 \b, reserved sectors %u (usual FAT12,FAT16) #>>>>>>14 uleshort 0 \b, reserved sectors %u (usual NTFS) @@ -1390,7 +1390,7 @@ >>>>>16 ubyte >0 >>>>>17 uleshort >0 \b, root entries %u #>>>>>17 uleshort =0 \b, root entries %hu=0 (usual Fat32) ->>>>>19 uleshort >0 \b, sectors %u (volumes <=32 MB) +>>>>>19 uleshort >0 \b, sectors %u (volumes <=32 MB) #>>>>>19 uleshort =0 \b, sectors %hu=0 (usual Fat32) >>>>>21 ubyte >0xF0 \b, Media descriptor 0x%x #>>>>>21 ubyte =0xF0 \b, Media descriptor 0x%x (usual floppy) @@ -1402,20 +1402,20 @@ #>>>>>26 ubyte =2 \b, heads %u (usual floppy) >>>>>26 ubyte =1 \b, heads %u # valid only for sector sizes with more then 32 Bytes ->>>>>11 uleshort >32 +>>>>>11 uleshort >32 # http://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Extended_BIOS_Parameter_Block # skip for values 2,2Ah,70h,73h,DFh # and continue for extended boot signature values 0,28h,29h,80h ->>>>>>38 ubyte&0x56 =0 +>>>>>>38 ubyte&0x56 =0 >>>>>>>28 ulelong >0 \b, hidden sectors %u #>>>>>>>28 ulelong =0 \b, hidden sectors %u (usual floppy) ->>>>>>>32 ulelong >0 \b, sectors %u (volumes > 32 MB) +>>>>>>>32 ulelong >0 \b, sectors %u (volumes > 32 MB) #>>>>>>>32 ulelong =0 \b, sectors %u (volumes > 32 MB) -# FAT<32 bit specific ->>>>>>>82 string/c !fat32 +# FAT<32 bit specific +>>>>>>>82 string/c !fat32 #>>>>>>>>36 ubyte 0x80 \b, physical drive 0x%x=0x80 (usual harddisk) #>>>>>>>>36 ubyte 0 \b, physical drive 0x%x=0 (usual floppy) ->>>>>>>>36 ubyte !0x80 +>>>>>>>>36 ubyte !0x80 >>>>>>>>>36 ubyte !0 \b, physical drive 0x%x # VGA-copy CRC or # in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too @@ -1435,27 +1435,27 @@ # if it is small enough FAT is 12 bit, if it is too big enough FAT is 32 bit, # otherwise FAT is 16 bit. # http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-fat-widths.html ->>>>>82 string/c !fat32 +>>>>>82 string/c !fat32 >>>>>>54 string FAT12 \b, FAT (12 bit) >>>>>>54 string FAT16 \b, FAT (16 bit) ->>>>>>54 default x +>>>>>>54 default x # determinate FAT bit size by media descriptor # small floppies implies FAT12 >>>>>>>21 ubyte <0xF0 \b, FAT (12 bit by descriptor) # with media descriptor F0h floppy or maybe superfloppy with FAT16 ->>>>>>>21 ubyte =0xF0 +>>>>>>>21 ubyte =0xF0 # superfloppy (many sectors) implies FAT16 >>>>>>>>32 ulelong >0xFFFF \b, FAT (16 bit by descriptor+sectors) # no superfloppy with media descriptor F0h implies FAT12 >>>>>>>>32 default x \b, FAT (12 bit by descriptor+sectors) # with media descriptor F8h floppy or hard disc with FAT12 or FAT16 ->>>>>>>21 ubyte =0xF8 +>>>>>>>21 ubyte =0xF8 # 360 KiB with media descriptor F8h, 9 sectors per track ,single sided floppy implies FAT12 >>>>>>>>19 ubequad 0xd002f80300090001 \b, FAT (12 bit by descriptor+geometry) # hard disc with FAT12 or FAT16 >>>>>>>>19 default x \b, FAT (1Y bit by descriptor) # with media descriptor FAh floppy, RAM disc with FAT12 or FAT16 or Tandy hard disc ->>>>>>>21 ubyte =0xFA +>>>>>>>21 ubyte =0xFA # 320 KiB with media descriptor FAh, 8 sectors per track ,single sided floppy implies FAT12 >>>>>>>>19 ubequad 0x8002fa0200080001 \b, FAT (12 bit by descriptor+geometry) # RAM disc with FAT12 or FAT16 or Tandy hard disc @@ -1479,17 +1479,17 @@ # 0 or 0xFFFF instead of usual 6 means no backup sector >>>>>>50 uleshort =0xFFFF \b, no Backup boot sector >>>>>>50 uleshort =0 \b, no Backup boot sector -#>>>>>>50 uleshort =6 \b, Backup boot sector %u (usual) ->>>>>>50 default x +#>>>>>>50 uleshort =6 \b, Backup boot sector %u (usual) +>>>>>>50 default x >>>>>>>50 uleshort x \b, Backup boot sector %u # corrected by Joerg Jenderek at Feb 2011 according to http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO >>>>>>52 ulelong >0 \b, reserved1 0x%x >>>>>>56 ulelong >0 \b, reserved2 0x%x >>>>>>60 ulelong >0 \b, reserved3 0x%x -# same structure as FAT1X +# same structure as FAT1X #>>>>>>64 ubyte =0x80 \b, physical drive 0x%x=80 (usual harddisk) #>>>>>>64 ubyte =0 \b, physical drive 0x%x=0 (usual floppy) ->>>>>>64 ubyte !0x80 +>>>>>>64 ubyte !0x80 >>>>>>>64 ubyte >0 \b, physical drive 0x%x # in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too >>>>>>65 ubyte >0 \b, reserved 0x%x @@ -1500,10 +1500,10 @@ >>>>>>>71 string >NO\ NAME \b, label: "%11.11s" >>>>>>>71 string =NO\ NAME \b, unlabeled # additional tests for floppy image added by Joerg Jenderek -# no fixed disk ->>>>>21 ubyte !0xF8 +# no fixed disk +>>>>>21 ubyte !0xF8 # floppy media with 12 bit FAT ->>>>>>54 string !FAT16 +>>>>>>54 string !FAT16 # test for FAT after bootsector >>>>>>>(11.s) ulelong&0x00ffffF0 0x00ffffF0 \b, followed by FAT # floppy image @@ -1511,11 +1511,11 @@ # NTFS specific added by Joerg Jenderek at Mar 2011 according to http://thestarman.pcministry.com/asm/mbr/NTFSBR.htm # and http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/bios-parameter-block.html # 0 FATs ->>>>>16 ubyte =0 +>>>>>16 ubyte =0 # 0 root entries ->>>>>>17 uleshort =0 +>>>>>>17 uleshort =0 # 0 DOS sectors ->>>>>>>19 uleshort =0 +>>>>>>>19 uleshort =0 # 0 sectors/FAT # dos < 4.0 BootSector value found is 0x80 #38 ubyte =0x80 \b, dos < 4.0 BootSector (0x%x) @@ -1526,33 +1526,43 @@ >>>>>>>>>48 ulequad >0 \b, $MFT start cluster %lld >>>>>>>>>56 ulequad >0 \b, $MFTMirror start cluster %lld # Values 0 to 127 represent MFT record sizes of 0 to 127 clusters. -# Values 128 to 255 represent MFT record sizes of 2^(256-N) bytes. ->>>>>>>>>64 lelong <256 +# Values 128 to 255 represent MFT record sizes of 2^(256-N) bytes. +>>>>>>>>>64 lelong <256 >>>>>>>>>>64 lelong <128 \b, clusters/RecordSegment %d >>>>>>>>>>64 ubyte >127 \b, bytes/RecordSegment 2^(-1*%i) # Values 0 to 127 represent index block sizes of 0 to 127 clusters. # Values 128 to 255 represent index block sizes of 2^(256-N) byte ->>>>>>>>>68 ulelong <256 +>>>>>>>>>68 ulelong <256 >>>>>>>>>>68 ulelong <128 \b, clusters/index block %d #>>>>>>>>>>68 ulelong >127 \b, bytes/index block 2^(256-%d) >>>>>>>>>>68 ubyte >127 \b, bytes/index block 2^(-1*%i) >>>>>>>>>72 ulequad x \b, serial number 0%llx >>>>>>>>>80 ulelong >0 \b, checksum 0x%x #>>>>>>>>>80 ulelong =0 \b, checksum 0x%x=0 (usual) ->>>>>>>>>0x258 ulelong&0x00009090 =0x00009090 ->>>>>>>>>>&-92 indirect x \b; contains +>>>>>>>>>0x258 ulelong&0x00009090 =0x00009090 +>>>>>>>>>>&-92 indirect x \b; contains # For 2nd NTFS sector added by Joerg Jenderek at Jan 2013 # http://thestarman.pcministry.com/asm/mbr/NTFSbrHexEd.htm # unused assembler instructions JMP y2;NOP;NOP -0x056 ulelong&0xFFFF0FFF 0x909002EB +0x056 ulelong&0xFFFF0FFF 0x909002EB # unicode loadername terminated by CTRL-D ->(0.s*2) ulelong&0xFFFFFF00 0x00040000 +>(0.s*2) ulelong&0xFFFFFF00 0x00040000 # loadernames are NTLDR,CMLDR,PELDR,$LDR$ or BOOTMGR >>0x002 lestring16 x Microsoft Windows XP/VISTA bootloader %-5.5s ->>0x12 string $ +>>0x12 string $ >>>0x0c lestring16 x \b%-2.2s ### DOS,NTFS boot sectors end +# ntfsclone-image is a special save format for NTFS volumes, +# created and restored by the ntfsclone program +0 string \0ntfsclone-image ntfsclone image, +>0x10 byte x version %d. +>0x11 byte x \b%d, +>0x12 lelong x cluster size %d, +>0x16 lequad x device size %lld, +>0x1e lequad x %lld total clusters, +>0x26 lequad x %lld clusters in use + 9564 lelong 0x00011954 Unix Fast File system [v1] (little-endian), >8404 string x last mounted on %s, #>9504 ledate x last checked at %s, @@ -1669,6 +1679,13 @@ >&-1248 belong 0 TIME optimization >&-1248 belong 1 SPACE optimization +0 ulequad 0xc8414d4dc5523031 HAMMER filesystem (little-endian), +>0x90 lelong+1 x volume %d +>0x94 lelong x (of %d), +>0x50 string x name %s, +>0x98 ulelong x version %u, +>0xa0 ulelong x flags 0x%x + # ext2/ext3 filesystems - Andreas Dilger # ext4 filesystem - Eric Sandeen # volume label and UUID Russell Coker @@ -1818,7 +1835,7 @@ # FE 250K 8-inch, 1-sided, single-density # FD 500K 8-inch, 2-sided, single-density # FE 1.2 MB 8-inch, 2-sided, double-density -# F8 ----- Fixed disk +# F8 ----- Fixed disk # # FC xxxK Apricot 70x1x9 boot disk. # @@ -1846,7 +1863,7 @@ # all FAT12 (strength=70) floppies with sectorsize 512 added by Joerg Jenderek at Jun 2013 # http://en.wikipedia.org/wiki/File_Allocation_Table#Exceptions # Too Weak. -#512 ubelong&0xE0ffff00 0xE0ffff00 +#512 ubelong&0xE0ffff00 0xE0ffff00 # without valid Media descriptor in place of BPB, cases with are done at other places #>21 ubyte <0xE5 floppy with old FAT filesystem # but valid Media descriptor at begin of FAT @@ -1858,61 +1875,61 @@ #>>512 ubyte =0xfb 640k #>>512 ubyte =0xfc 180k # look like an an old DOS directory entry -#>>>0xA0E ubequad 0 -#>>>>0xA00 ubequad !0 +#>>>0xA0E ubequad 0 +#>>>>0xA00 ubequad !0 #!:mime application/x-ima -#>>512 ubyte =0xfd +#>>512 ubyte =0xfd # look for 2nd FAT at different location to distinguish between 360k and 500k #>>>0x600 ubelong&0xE0ffff00 0xE0ffff00 360k #>>>0x500 ubelong&0xE0ffff00 0xE0ffff00 500k -#>>>0xA0E ubequad 0 +#>>>0xA0E ubequad 0 #!:mime application/x-ima -#>>512 ubyte =0xfe +#>>512 ubyte =0xfe #>>>0x400 ubelong&0xE0ffff00 0xE0ffff00 160k -#>>>>0x60E ubequad 0 -#>>>>>0x600 ubequad !0 +#>>>>0x60E ubequad 0 +#>>>>>0x600 ubequad !0 #!:mime application/x-ima #>>>0xC00 ubelong&0xE0ffff00 0xE0ffff00 1200k #>>512 ubyte =0xff 320k -#>>>0x60E ubequad 0 -#>>>>0x600 ubequad !0 +#>>>0x60E ubequad 0 +#>>>>0x600 ubequad !0 #!:mime application/x-ima #>>512 ubyte x \b, Media descriptor 0x%x # without x86 jump instruction -#>>0 ulelong&0x804000E9 !0x000000E9 -# assembler instructions: CLI;MOV SP,1E7;MOV AX;07c0;MOV +#>>0 ulelong&0x804000E9 !0x000000E9 +# assembler instructions: CLI;MOV SP,1E7;MOV AX;07c0;MOV #>>>0 ubequad 0xfabce701b8c0078e \b, MS-DOS 1.12 bootloader # IOSYS.COM+MSDOS.COM #>>>>0xc4 use 2xDOS-filename -#>>0 ulelong&0x804000E9 =0x000000E9 +#>>0 ulelong&0x804000E9 =0x000000E9 # only x86 short jump instruction found #>>>0 ubyte =0xEB #>>>>1 ubyte x \b, code offset 0x%x+2 # http://thestarman.pcministry.com/DOS/ibm100/Boot.htm -# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;MOV DX,0 -#>>>>(1.b+2) ubequad 0xfa8cc88ed8ba0000 \b, PC-DOS 1.0 bootloader +# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;MOV DX,0 +#>>>>(1.b+2) ubequad 0xfa8cc88ed8ba0000 \b, PC-DOS 1.0 bootloader # ibmbio.com+ibmdos.com #>>>>>0x176 use DOS-filename #>>>>>0x181 ubyte x \b+ #>>>>>0x182 use DOS-filename # http://thestarman.pcministry.com/DOS/ibm110/Boot.htm -# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;XOR DX,DX;MOV -#>>>>(1.b+2) ubequad 0xfa8cc88ed833d28e \b, PC-DOS 1.1 bootloader +# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;XOR DX,DX;MOV +#>>>>(1.b+2) ubequad 0xfa8cc88ed833d28e \b, PC-DOS 1.1 bootloader # ibmbio.com+ibmdos.com #>>>>>0x18b use DOS-filename #>>>>>0x196 ubyte x \b+ #>>>>>0x197 use DOS-filename # http://en.wikipedia.org/wiki/Zenith_Data_Systems -# assembler instructions: MOV BX,07c0;MOV SS,BX;MOV SP,01c6 +# assembler instructions: MOV BX,07c0;MOV SS,BX;MOV SP,01c6 #>>>>(1.b+2) ubequad 0xbbc0078ed3bcc601 \b, Zenith Data Systems MS-DOS 1.25 bootloader # IO.SYS+MSDOS.SYS #>>>>>0x20 use 2xDOS-filename # http://en.wikipedia.org/wiki/Corona_Data_Systems -# assembler instructions: MOV AX,CS;MOV DS,AX;CLI;MOV SS,AX; +# assembler instructions: MOV AX,CS;MOV DS,AX;CLI;MOV SS,AX; #>>>>(1.b+2) ubequad 0x8cc88ed8fa8ed0bc \b, MS-DOS 1.25 bootloader # IO.SYS+MSDOS.SYS #>>>>>0x69 use 2xDOS-filename -# assembler instructions: CLI;PUSH CS;POP SS;MOV SP,7c00; +# assembler instructions: CLI;PUSH CS;POP SS;MOV SP,7c00; #>>>>(1.b+2) ubequad 0xfa0e17bc007cb860 \b, MS-DOS 2.11 bootloader # defect IO.SYS+MSDOS.SYS ? #>>>>>0x162 use 2xDOS-filename @@ -1942,14 +1959,25 @@ 32769 string CD001 # mime line at that position does not work # to display CD-ROM (70=81-11) after MBR (113=40+72+1), partition-table (71=50+21) and before Apple Driver Map (51) -!:strength -11 +#!:strength -11 # to display CD-ROM (114=81+33) before MBR (113=40+72+1), partition-table (71=50+21) and Apple Driver Map (51) -# does not work -#!:strength +33 ->0 use cdrom +!:strength +34 +>0 use cdrom # .cso files -0 string CISO Compressed ISO CD image +# Reference: http://pismotec.com/ciso/ciso.h +# NOTE: There are two other formats with the same magic but +# completely incompatible specifications: +# - GameCube/Wii CISO: https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/DiscIO/CISOBlob.h +# - PSP CISO: https://github.com/jamie/ciso/blob/master/ciso.h +0 string CISO +# Other fields are used to determine what type of CISO this is: +# - 0x04 == 0x00200000: GameCube/Wii CISO (block_size) +# - 0x10 == 0x00000800: PSP CISO (ISO-9660 sector size) +# - None of the above: Compact ISO. +>4 lelong !0 +>>4 lelong !0x200000 +>>>0x10 lelong !0x800 Compressed ISO CD image # cramfs filesystem - russell@coker.com.au 0 lelong 0x28cd3d45 Linux Compressed ROM File System data, little endian @@ -2041,6 +2069,13 @@ >29 byte 16 \bBlackfin, >29 byte 17 \bAVR32, >29 byte 18 \bSTMicroelectronics ST200, +>29 byte 19 \bSandbox architecture, +>29 byte 20 \bANDES Technology NDS32, +>29 byte 21 \bOpenRISC 1000, +>29 byte 22 \bARM 64-bit, +>29 byte 23 \bDesignWare ARC, +>29 byte 24 \bx86_64, +>29 byte 25 \bXtensa, >30 byte 0 Invalid Image >30 byte 1 Standalone Program >30 byte 2 OS Kernel Image @@ -2114,7 +2149,7 @@ >>8 ledate x created: %s # AFS Dump Magic -# From: Ty Sarna +# From: Ty Sarna 0 string \x01\xb3\xa1\x13\x22 AFS Dump >&0 belong x (v%d) >>&0 byte 0x76 @@ -2229,7 +2264,7 @@ # From: "Nelson A. de Oliveira" 0 string *dvdisaster* dvdisaster error correction file -# xfs metadump image +# xfs metadump image # mb_magic XFSM at 0; superblock magic XFSB at 1 << mb_blocklog # but can we do the << ? For now it's always 512 (0x200) anyway. 0 string XFSM @@ -2301,8 +2336,8 @@ 0 string td\000 floppy image data (TeleDisk, compressed) 0 string TD\000 floppy image data (TeleDisk) -0 string CQ\024 floppy image data (CopyQM, ->16 leshort x %d sectors, +0 string CQ\024 floppy image data (CopyQM, +>16 leshort x %d sectors, >18 leshort x %d heads.) 0 string ACT\020Apricot\020disk\020image\032\004 floppy image data (ApriDisk) @@ -2352,3 +2387,13 @@ >>>>>>>>0x1B ubyte 0x30 \b, media=1D >>>>>>>>0x1B ubyte 0x40 \b, media=1DD >>>>>>>>0x1A ubyte 0x10 \b, write-protected + +# HDD Raw Copy Tool disk image, file extension: .imgc +# From Benjamin Vanheuverzwijn +0 pstring HDD\ Raw\ Copy\ Tool %s +>0x100 pstring x %s +>0x200 pstring x - HD model: %s +#>0x300 pstring x unknown %s +>0x400 pstring x serial: %s +#>0x500 pstring x unknown: %s +!:ext imgc diff --git a/contrib/file/magic/Magdir/flash b/contrib/file/magic/Magdir/flash index b06f879efcd5..b48abe968eb4 100644 --- a/contrib/file/magic/Magdir/flash +++ b/contrib/file/magic/Magdir/flash @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: flash,v 1.11 2014/05/02 00:26:49 christos Exp $ +# $File: flash,v 1.14 2017/05/25 20:09:55 christos Exp $ # flash: file(1) magic for Macromedia Flash file format # # See @@ -10,23 +10,45 @@ # en/devnet/swf/pdf/swf-file-format-spec.pdf page 27 # -0 name swf-details ->0 string F Macromedia Flash data -!:mime application/x-shockwave-flash ->0 string C Macromedia Flash data (compressed) -!:mime application/x-shockwave-flash ->0 string Z Macromedia Flash data (lzma compressed) -!:mime application/x-shockwave-flash ->3 byte x \b, version %d +0 name swf-details -1 string WS ->4 lelong !0 ->>3 byte 255 Suspicious ->>>0 use swf-details +>0 string F +>>8 byte&0xfd 0x08 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d +>>8 byte&0xfe 0x10 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d +>>8 byte 0x18 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d +>>8 beshort&0xff87 0x2000 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d +>>8 beshort&0xffe0 0x3000 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d +>>8 byte&0x7 0 +>>>8 ubyte >0x2f +>>>>9 ubyte <0x20 Macromedia Flash data +!:mime application/x-shockwave-flash +>>>>>3 byte x \b, version %d ->>3 ubyte <32 ->>>3 ubyte !0 ->>>>0 use swf-details +>0 string C +>>8 byte 0x78 Macromedia Flash data (compressed) +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d + +>0 string Z +>>8 byte 0x5d Macromedia Flash data (lzma compressed) +!:mime application/x-shockwave-flash +>>>3 byte x \b, version %d + + +1 string WS +>4 ulelong >14 +>>3 ubyte !0 +>>>0 use swf-details # From: Cal Peake 0 string FLV\x01 Macromedia Flash Video @@ -34,7 +56,7 @@ # # Yosu Gomez -0 string AGD2\xbe\xb8\xbb\xcd\x00 Macromedia Freehand 7 Document -0 string AGD3\xbe\xb8\xbb\xcc\x00 Macromedia Freehand 8 Document +0 string AGD2\xbe\xb8\xbb\xcd\x00 Macromedia Freehand 7 Document +0 string AGD3\xbe\xb8\xbb\xcc\x00 Macromedia Freehand 8 Document # From Dave Wilson -0 string AGD4\xbe\xb8\xbb\xcb\x00 Macromedia Freehand 9 Document +0 string AGD4\xbe\xb8\xbb\xcb\x00 Macromedia Freehand 9 Document diff --git a/contrib/file/magic/Magdir/fonts b/contrib/file/magic/Magdir/fonts index be489cba01e0..7e9b0da914df 100644 --- a/contrib/file/magic/Magdir/fonts +++ b/contrib/file/magic/Magdir/fonts @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: fonts,v 1.33 2016/09/14 01:26:26 christos Exp $ +# $File: fonts,v 1.37 2017/06/24 00:39:00 christos Exp $ # fonts: file(1) magic for font data # 0 search/1 FONT ASCII vfont text @@ -19,17 +19,17 @@ # URL: https://en.wikipedia.org/wiki/PostScript_fonts # Reference: http://partners.adobe.com/public/developer/en/font/5178.PFM.pdf # Modified by: Joerg Jenderek -# Note: moved from ./msdos magic -# dfVersion 256=0100h -0 uleshort 0x0100 +# Note: moved from ./msdos magic +# dfVersion 256=0100h +0 uleshort 0x0100 # GRR: line above is too general as it catches also TrueType font, # raw G3 data FAX, WhatsApp encrypted and Panorama database # dfType 129=0081h ->66 uleshort 0x0081 +>66 uleshort 0x0081 # dfVertRes 300=012Ch not needed as additional test -#>>70 uleshort 0x012c +#>>70 uleshort 0x012c # dfHorizRes 300=012Ch -#>>>72 uleshort 0x012c +#>>>72 uleshort 0x012c # dfDriverInfo points to postscript information section >>(101.l) string/c Postscript Printer Font Metrics # above labeled "PFM data" by ./msdos (version 5.28) or "Adobe Printer Font Metrics" by TrID @@ -40,13 +40,13 @@ # dfCopyright 60 byte null padded Copyright string. uncomment it to get old looking #>>>6 string >\060 - %-.60s # dfDriverInfo ->>>139 ulelong >0 +>>>139 ulelong >0 # often abbreviated and same as filename >>>>(139.l) string x %s # dfSize >>>2 ulelong x \b, %d bytes # dfFace 210=D2h 9Eh ->>>105 ulelong >0 +>>>105 ulelong >0 # Windows font name >>>>(105.l) string x \b, %s # dfItalic @@ -72,7 +72,7 @@ #>104 belong 00000004 X11 SNF font data, MSB first !:mime application/x-font-sfn # GRR: line below too general as it catches also Xbase index file t3-CHAR.NDX -0 lelong 00000004 +0 lelong 00000004 >104 lelong 00000004 X11 SNF font data, LSB first !:mime application/x-font-sfn @@ -82,27 +82,29 @@ # From: Joerg Jenderek # URL: http://grub.gibibit.com/New_font_format # Reference: util/grub-mkfont.c -# include/grub/fontformat.h +# include/grub/fontformat.h # FONT_FORMAT_SECTION_NAMES_FILE -0 string FILE +0 string FILE # FONT_FORMAT_PFF2_MAGIC ->8 string PFF2 +>8 string PFF2 # leng 4 only at the moment ->>4 ubelong 4 +>>4 ubelong 4 # FONT_FORMAT_SECTION_NAMES_FONT_NAME >>>12 string NAME GRUB2 font !:mime application/x-font-pf2 !:ext pf2 # length of font_name ->>>>16 ubelong >0 +>>>>16 ubelong >0 # font_name >>>>>20 string >\0 "%-s" # X11 fonts, from Daniel Quinlan (quinlan@yggdrasil.com) # PCF must come before SGI additions ("MIPSEL MIPS-II COFF" collides) -0 string \001fcp X11 Portable Compiled Font data ->12 byte 0x02 \b, LSB first ->12 byte 0x0a \b, MSB first +0 string \001fcp X11 Portable Compiled Font data, +>12 lelong ^0x08 bit: LSB, +>12 lelong &0x08 bit: MSB, +>12 lelong ^0x04 byte: LSB first +>12 lelong &0x04 byte: MSB first 0 string D1.0\015 X11 Speedo font data #------------------------------------------------------------------------------ @@ -134,28 +136,166 @@ >4 beshort >0 version %d # True Type fonts -0 string \000\001\000\000\000 TrueType font data -!:mime application/x-font-ttf +# Modified by: Joerg Jenderek +# URL: https://en.wikipedia.org/wiki/TrueType +# Reference: https://developer.apple.com/fonts/TrueType-Reference-Manual/ +# +# sfnt version "typ1" used by some Apple, but no example found +0 string typ1 +>0 use sfnt-font +>0 use sfnt-names +# sfnt version "true" used by some Apple +0 string true +>0 use sfnt-font +>0 use sfnt-names +# GRR: below test is too general +# sfnt version often 0x00010000 +0 string \000\001\000\000 +>0 use sfnt-font +>0 use sfnt-names +# validate and display sfnt font data like number of tables +0 name sfnt-font +# file 5.30 version assumes 00FFh as maximal number of tables +#>4 ubeshort <0x0100 +# maximal 27 tables found like in Skia.ttf +# 46 different table names mentioned on Apple specification +# skip 1st sequence of DOS 2 backup with path separator (\~92 or /~47) misinterpreted as table number +>4 ubeshort <47 +# skip bad examples with garbage table names like in a5.show HYPERC MAC +# tag names consist of up to four characters padded with spaces at end like +# BASE DSIG OS/2 Zapf acnt glyf cvt vmtx xref ... +>>12 regex/4l \^[A-Za-z][A-Za-z][A-Za-z/][A-Za-z2\ ] +#>>>0 ubelong x \b, sfnt version 0x%x +>>>0 ubelong !0x4f54544f TrueType +!:mime application/font-sfnt +#!:mime font/ttf +!:apple ????tfil +# .ttf for TrueType font +# EUDC.tte created by privat character editor %WINDIR%\system32\eudcedit.exe +!:ext ttf/tte +# sfnt version 4F54544Fh~OTTO +>>>0 ubelong =0x4f54544f OpenType +!:mime application/font-sfnt +#!:mime font/otf +!:apple ????OTTO +!:ext otf +>>>0 ubelong x Font data +# DSIG=44454947h table name implies a digitally signed font +# search range = number of tables * 16 =< maximal number of tables * 16 = 27 * 16 = 432 +>>>12 search/432 DSIG \b, digitally signed +>>>4 ubeshort x \b, %d tables +# minimal 9 tables found like in NISC18030.ttf +#>>>4 ubeshort <10 TMIN +#>>>4 ubeshort >24 TBIG +# table directory entries +>>>12 string x \b, 1st "%4.4s" + +# search and display 1st name in sfnt font which is often copyright text +# does not work inside font collections +0 name sfnt-names +# search for naming table +>12 search/432/s name +# biggest offset 0x0100bd28 like Windows10 Fonts\simsunb.ttf +#>>>>&8 ubelong >0x0100bd27 BIGGEST OFFSET +>>&8 ubelong >0x00100000 +# offset of name table +>>>&-4 ubelong x \b, name offset 0x%x +# GRR: pointer to name table only works if offset ~< FILE_BYTES_MAX = 100000h defined in src\file.h +>>&8 ubelong <0x00100000 +>>>&-16 ubelong x +# name table +>>>>(&8.L) ubequad x +# invalid format selector +#>>>>>&-8 ubeshort !0 \b, invalid selector %x +# minimal 3 name records found like in c:\Program Files (x86)\Tesseract-OCR\tessdata\pdf.ttf +# maximal 1227 name records found like in Apple Chancery.ttf +#>>>>>&-6 ubeshort <0x4 mincount +#>>>>>&-6 ubeshort >130 maxcount +>>>>>&-6 ubeshort x \b, %d names +# offset to start of string storage from start of table +#>>>>>&-4 ubeshort x \b, record offset %d +# 1st name record +# string offset from start of storage area +#>>>>>&8 ubeshort x \b, string offset %d +# string length +#>>>>>&6 ubeshort x \b, string length %d +# minimal name string 7 like in c:\Program Files (x86)\Kodi\addons\webinterface.default\lib\video-js\font\VideoJS.ttf +# also found 0 like in SWZCONLN.TTF +#>>>>>&6 ubeshort <8 MIN STRING +# maximal name string 806 like in c:\Windows\Fonts\palabi.ttf +#>>>>>&6 ubeshort >805 MAX STRING +# platform identifier: 0~Apple Unicode, 1~Macintosh, 3~Microsoft +#>>>>>&-2 ubeshort >3 BAD PLATFORM +>>>>>&-2 ubeshort 0 \b, Unicode +>>>>>&-2 ubeshort 1 \b, Macintosh +>>>>>&-2 ubeshort 3 \b, Microsoft +# languageID (0~english Macintosh, 0409h~english Microsoft, ...) +>>>>>&2 ubeshort >0 \b, language 0x%x +# name identifiers +# often 0~copyright, 1~font, 2~font subfamily, 5~version, 13~license, 19~sample, ... +>>>>>&4 ubeshort >0 \b, type %d string +# platform specific encoding: +# 0~undefined character set, 1~UGL set with Unicode, 3~Unicode 2.0 BMP only, 4~Unicode 2.0 +#>>>>>&0 ubeshort x \b, %d encoding +>>>>>&0 ubeshort 0 +# handle only name string offset 0 because do not know how to add 2 relative offsets +>>>>>>&6 ubeshort 0 +>>>>>>>&(&-14.S-18) ubyte !0 +# GRR: instead 806 only first MAXstring = 96 characters are displayed as defined in src\file.h +# often copyright string that starts like \251 2006 The Monotype Corporation +>>>>>>>>&-1 string x \b, %-11.96s +# test for unicode string +>>>>>>>&(&-14.S-18) ubyte 0 +>>>>>>>>&0 lestring16 x \b, %-11.96s +# unicode encoding +>>>>>&0 ubeshort >0 +>>>>>>&6 ubeshort 0 +>>>>>>>&(&-14.S-17) lestring16 x \b, %-11.96s 0 string \007\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font 0 string \012\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font # TrueType/OpenType font collections (.ttc) +# URL: https://en.wikipedia.org/wiki/OpenType # http://www.microsoft.com/typography/otspec/otff.htm -0 string ttcf TrueType font collection data ->4 belong 0x00010000 \b, 1.0 ->>8 belong >0 \b, %d fonts ->4 belong 0x00020000 \b, 2.0 ->>8 belong >0 \b, %d fonts +# Modified by: Joerg Jenderek +# Note: container for TrueType, OpenType font +0 string ttcf +# skip ASCII text +>4 ubyte 0 +# sfnt version often 0x00010000 of 1st table is TrueType +>>(12.L) ubelong !0x4f54544f TrueType +#!:mime font/ttf +!:apple ????tfil +!:ext ttc +# sfnt version 4F54544Fh~OTTO of 1st table is OpenType font +>>(12.L) ubelong =0x4f54544f OpenType +#!:mime font/otf +!:apple ????OTTO +# no example found for otc +!:ext ttc/otc +>>4 ubyte x font collection data +!:mime application/font-sfnt +#!:mime font/collection +# TCC version +>>4 belong 0x00010000 \b, 1.0 +>>4 belong 0x00020000 \b, 2.0 +>>8 ubelong >0 \b, %d fonts +# array offset size = fonts * offsetsize = fonts * 4 +>>(8.L*4) ubequad x # 0x44454947 = 'DSIG' ->>>16 belong 0x44534947 \b, digitally signed +>>>&4 belong 0x44534947 \b, digitally signed +# offset to 1st font +>>12 ubelong x \b, at 0x%x +# point to 1st font that starts with sfnt version +>>(12.L) use sfnt-font # Opentype font data from Avi Bercovich 0 string OTTO OpenType font data !:mime application/vnd.ms-opentype -# Gurkan Sengun , www.linuks.mine.nu -0 string SplineFontDB: Spline Font Database +# Gurkan Sengun , www.linuks.mine.nu +0 string SplineFontDB: Spline Font Database !:mime application/vnd.font-fontforge-sfd >14 string x version %s diff --git a/contrib/file/magic/Magdir/fsav b/contrib/file/magic/Magdir/fsav index ecdc4f654b7c..5714798e9131 100644 --- a/contrib/file/magic/Magdir/fsav +++ b/contrib/file/magic/Magdir/fsav @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: fsav,v 1.13 2013/03/25 17:18:47 christos Exp $ +# $File: fsav,v 1.14 2017/03/17 21:35:28 christos Exp $ # fsav: file(1) magic for datafellows fsav virus definition files # Anthon van der Neut (anthon@mnt.org) @@ -29,11 +29,11 @@ #>>>>10 byte 11 \b12- #>>>>9 ubyte >0 \b%02d) # ftp://ftp.f-prot.com/pub/sign2.zip -#0 ubyte 0x62 -#>1 ubyte 0xF5 -#>>2 ubyte 0x1 -#>>>3 ubyte 0x1 -#>>>>4 ubyte 0x0e +#0 ubyte 0x62 +#>1 ubyte 0xF5 +#>>2 ubyte 0x1 +#>>>3 ubyte 0x1 +#>>>>4 ubyte 0x0e #>>>>>13 ubyte >0 fsav virus signatures #>>>>>>11 ubyte x size 0x%02x #>>>>>>12 ubyte x \b%02x @@ -44,16 +44,16 @@ # .cvd files start with a 512 bytes colon separated header # ClamAV-VDB:buildDate:version:signaturesNumbers:functionalityLevelRequired:MD5:Signature:builder:buildTime # + gzipped tarball files -0 string ClamAV-VDB: +0 string ClamAV-VDB: >11 string >\0 Clam AntiVirus database %-.23s ->>34 string : ->>>35 string !: \b, version +>>34 string : +>>>35 string !: \b, version >>>>35 string x \b%-.1s ->>>>>36 string !: +>>>>>36 string !: >>>>>>36 string x \b%-.1s ->>>>>>>37 string !: +>>>>>>>37 string !: >>>>>>>>37 string x \b%-.1s ->>>>>>>>>38 string !: +>>>>>>>>>38 string !: >>>>>>>>>>38 string x \b%-.1s >512 string \037\213 \b, gzipped >769 string ustar\0 \b, tarred diff --git a/contrib/file/magic/Magdir/games b/contrib/file/magic/Magdir/games index 779bc6cfd643..9f72661d82fb 100644 --- a/contrib/file/magic/Magdir/games +++ b/contrib/file/magic/Magdir/games @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: games,v 1.14 2014/04/30 21:41:02 christos Exp $ +# $File: games,v 1.15 2017/03/17 21:35:28 christos Exp $ # games: file(1) for games # Fabio Bonelli @@ -39,7 +39,7 @@ #0 string -1\x0a Quake I demo #>30 string x version %.4s -#>61 string x level %s +#>61 string x level %s #0 string 5\x0a Quake I save @@ -240,7 +240,7 @@ # Summary: NetImmerse game engine file # Extension .nif # Created by: Abel Cheung -0 string NetImmerse\ File\ Format,\ Versio +0 string NetImmerse\ File\ Format,\ Versio >&0 string n\ NetImmerse game engine file >>&0 regex [0-9a-z.]+ \b, version %s diff --git a/contrib/file/magic/Magdir/gconv b/contrib/file/magic/Magdir/gconv new file mode 100644 index 000000000000..eec5ddcd7a57 --- /dev/null +++ b/contrib/file/magic/Magdir/gconv @@ -0,0 +1,10 @@ + +#------------------------------------------------------------------------------ +# $File: gconv +# gconv: file(1) magic for iconv/gconv module configuration cache +# +# Magic number defined in glibc/iconv/iconvconfig.h as GCONVCACHE_MAGIC +# +# From: Marek Cermak +# +0 lelong 0x20010324 gconv module configuration cache data diff --git a/contrib/file/magic/Magdir/geo b/contrib/file/magic/Magdir/geo index 9a765fed0c11..f93abd806c27 100644 --- a/contrib/file/magic/Magdir/geo +++ b/contrib/file/magic/Magdir/geo @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: geo,v 1.3 2013/01/04 00:47:02 christos Exp $ +# $File: geo,v 1.4 2017/03/17 21:35:28 christos Exp $ # Geo- files from Kurt Schwehr ###################################################################### @@ -57,7 +57,7 @@ 4 beshort 0x2002 GeoSwath RDF 0 string Start:- GeoSwatch auf text file -# Seabeam 2100 +# Seabeam 2100 # mbsystem code mb41 0 string SB2100 SeaBeam 2100 multibeam sonar 0 string SB2100DR SeaBeam 2100 DR multibeam sonar diff --git a/contrib/file/magic/Magdir/gnu b/contrib/file/magic/Magdir/gnu index 24609c16459c..8d5c9721588b 100644 --- a/contrib/file/magic/Magdir/gnu +++ b/contrib/file/magic/Magdir/gnu @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: gnu,v 1.17 2016/07/16 22:17:04 christos Exp $ +# $File: gnu,v 1.18 2017/03/17 21:35:28 christos Exp $ # gnu: file(1) magic for various GNU tools # # GNU nlsutils message catalog file format @@ -71,7 +71,7 @@ # they will ordinarily reported as "compressed", but at least -z helps 39 string = +# From: James Youngman # gnu find magic 0 string \0LOCATE GNU findutils locate database data >7 string >\0 \b, format %s diff --git a/contrib/file/magic/Magdir/gpt b/contrib/file/magic/Magdir/gpt index c48a58f7fe63..76a223c3a030 100644 --- a/contrib/file/magic/Magdir/gpt +++ b/contrib/file/magic/Magdir/gpt @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: gpt,v 1.3 2014/04/30 21:41:02 christos Exp $ +# $File: gpt,v 1.4 2017/03/17 21:35:28 christos Exp $ # # GPT Partition table patterns. # Author: Rogier Goossens (goossens.rogier@gmail.com) @@ -36,7 +36,7 @@ >>>>>>>>>>>>>(454.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table ->>>>>>>>>>>>>>0 ubyte x of 8192 bytes +>>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(454.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(454.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type @@ -66,7 +66,7 @@ >>>>>>>>>>>>>(470.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table ->>>>>>>>>>>>>>0 ubyte x of 8192 bytes +>>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(470.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(470.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type @@ -96,7 +96,7 @@ >>>>>>>>>>>>>(486.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table ->>>>>>>>>>>>>>0 ubyte x of 8192 bytes +>>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(486.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(486.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type @@ -126,7 +126,7 @@ >>>>>>>>>>>>>(502.l*8192) string EFI\ PART GPT partition table >>>>>>>>>>>>>>0 use gpt-mbr-type >>>>>>>>>>>>>>&-8 use gpt-table ->>>>>>>>>>>>>>0 ubyte x of 8192 bytes +>>>>>>>>>>>>>>0 ubyte x of 8192 bytes >>>>>>>>>>>>>(502.l*8192) string !EFI\ PART >>>>>>>>>>>>>>(502.l*4096) string EFI\ PART GPT partition table >>>>>>>>>>>>>>>0 use gpt-mbr-type @@ -166,7 +166,7 @@ ##>(8.l*8192) string EFI\ PART ##>>(8.l*8192) use gpt-mbr-type ##>>&-8 use gpt-table -##>>0 ubyte x of 8192 bytes +##>>0 ubyte x of 8192 bytes ##>(8.l*8192) string !EFI\ PART ##>>(8.l*4096) string EFI\ PART GPT partition table ##>>>0 use gpt-mbr-type @@ -212,7 +212,7 @@ >>486 ulelong !1 \b (nonstandard: not at LBA 1) # GPT with protective MBR entry in partition 4 >498 ubyte 0xee ->>502 ulelong 1 +>>502 ulelong 1 >>>446 string !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \b (with hybrid MBR) >>502 ulelong !1 \b (nonstandard: not at LBA 1) diff --git a/contrib/file/magic/Magdir/gpu b/contrib/file/magic/Magdir/gpu new file mode 100644 index 000000000000..62e30d0f7a25 --- /dev/null +++ b/contrib/file/magic/Magdir/gpu @@ -0,0 +1,28 @@ + +#------------------------------------------------------------------------------ +# $File: gpu,v 1.2 2017/03/23 22:11:53 christos Exp $ +# gpu: file(1) magic for GPU input files + +# Standard Portable Intermediate Representation (SPIR) +# Documentation: https://www.khronos.org/spir +# Typical file extension: .spv + +0 belong 0x07230203 Khronos SPIR-V binary, big-endian +>4 belong x \b, version 0x%08x +>8 belong x \b, generator 0x%08x + +0 lelong 0x07230203 Khronos SPIR-V binary, little-endian +>4 lelong x \b, version 0x%08x +>8 lelong x \b, generator 0x%08x + +# Vulkan Trace file +# Documentation: +# https://github.com/LunarG/VulkanTools/blob/master/vktrace/vktrace_common/\ +# vktrace_trace_packet_identifiers.h +# Typical file extension: .vktrace + +8 lequad 0xABADD068ADEAFD0C Vulkan trace file, little-endian +>0 leshort x \b, version %d + +8 bequad 0xABADD068ADEAFD0C Vulkan trace file, big-endian +>0 beshort x \b, version %d diff --git a/contrib/file/magic/Magdir/gringotts b/contrib/file/magic/Magdir/gringotts index 2bfef1b7f7de..b67475406a7b 100644 --- a/contrib/file/magic/Magdir/gringotts +++ b/contrib/file/magic/Magdir/gringotts @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: gringotts,v 1.5 2009/09/19 16:28:09 christos Exp $ +# $File: gringotts,v 1.6 2017/03/17 21:35:28 christos Exp $ # gringotts: file(1) magic for Gringotts # http://devel.pluto.linux.it/projects/Gringotts/ # author: Germano Rizzo @@ -9,10 +9,10 @@ #file format 1 >3 string 1 v.1, MCRYPT S2K, SERPENT crypt, SHA-256 hash, ZLib lvl.9 #file format 2 ->3 string 2 v.2, MCRYPT S2K, +>3 string 2 v.2, MCRYPT S2K, >>8 byte&0x70 0x00 RIJNDAEL-128 crypt, >>8 byte&0x70 0x10 SERPENT crypt, ->>8 byte&0x70 0x20 TWOFISH crypt, +>>8 byte&0x70 0x20 TWOFISH crypt, >>8 byte&0x70 0x30 CAST-256 crypt, >>8 byte&0x70 0x40 SAFER+ crypt, >>8 byte&0x70 0x50 LOKI97 crypt, @@ -27,10 +27,10 @@ >>8 byte&0x03 0x02 lvl.6 >>8 byte&0x03 0x03 lvl.9 #file format 3 ->3 string 3 v.3, OpenPGP S2K, +>3 string 3 v.3, OpenPGP S2K, >>8 byte&0x70 0x00 RIJNDAEL-128 crypt, >>8 byte&0x70 0x10 SERPENT crypt, ->>8 byte&0x70 0x20 TWOFISH crypt, +>>8 byte&0x70 0x20 TWOFISH crypt, >>8 byte&0x70 0x30 CAST-256 crypt, >>8 byte&0x70 0x40 SAFER+ crypt, >>8 byte&0x70 0x50 LOKI97 crypt, diff --git a/contrib/file/magic/Magdir/hitachi-sh b/contrib/file/magic/Magdir/hitachi-sh index 1b615ae9256e..0238ed7ebc4e 100644 --- a/contrib/file/magic/Magdir/hitachi-sh +++ b/contrib/file/magic/Magdir/hitachi-sh @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: hitachi-sh,v 1.7 2015/09/30 20:32:35 christos Exp $ +# $File: hitachi-sh,v 1.8 2017/03/17 21:35:28 christos Exp $ # hitach-sh: file(1) magic for Hitachi Super-H # # Super-H COFF @@ -9,20 +9,20 @@ # https://en.wikipedia.org/wiki/COFF # https://de.wikipedia.org/wiki/Common_Object_File_Format # http://www.delorie.com/djgpp/doc/coff/filhdr.html -# below test line conflicts with 2nd NTFS filesystem sector +# below test line conflicts with 2nd NTFS filesystem sector # 2nd NTFS filesystem sector often starts with 0x05004e00 for unicode string 5 NTLDR # and Portable Gaming Notation Compressed format (*.WID http://pgn.freeservers.com/) -0 beshort 0x0500 +0 beshort 0x0500 # test for unused flag bits (0x8000,0x0800,0x0400,0x0200,x0080) in f_flags ->18 ubeshort&0x8E80 0 +>18 ubeshort&0x8E80 0 # use big endian variant of subroutine to display name+variables+flags -# for common object formated files +# for common object formated files >>0 use \^display-coff -0 leshort 0x0550 +0 leshort 0x0550 # test for unused flag bits in f_flags ->18 uleshort&0x8E80 0 -# use little endian variant of subroutine to -# display name+variables+flags for common object formated files +>18 uleshort&0x8E80 0 +# use little endian variant of subroutine to +# display name+variables+flags for common object formated files >>0 use display-coff diff --git a/contrib/file/magic/Magdir/ibm370 b/contrib/file/magic/Magdir/ibm370 index 7887dc3c5c7a..a49b28f5db80 100644 --- a/contrib/file/magic/Magdir/ibm370 +++ b/contrib/file/magic/Magdir/ibm370 @@ -1,28 +1,28 @@ #------------------------------------------------------------------------------ -# $File: ibm370,v 1.9 2014/04/30 21:41:02 christos Exp $ +# $File: ibm370,v 1.10 2017/03/17 21:35:28 christos Exp $ # ibm370: file(1) magic for IBM 370 and compatibles. # # "ibm370" said that 0x15d == 0535 was "ibm 370 pure executable". # What the heck *is* "USS/370"? # AIX 4.1's "/etc/magic" has # -# 0 short 0535 370 sysV executable +# 0 short 0535 370 sysV executable # >12 long >0 not stripped # >22 short >0 - version %d # >30 long >0 - 5.2 format -# 0 short 0530 370 sysV pure executable +# 0 short 0530 370 sysV pure executable # >12 long >0 not stripped # >22 short >0 - version %d # >30 long >0 - 5.2 format # # instead of the "USS/370" versions of the same magic numbers. # -0 beshort 0537 370 XA sysV executable +0 beshort 0537 370 XA sysV executable >12 belong >0 not stripped >22 beshort >0 - version %d >30 belong >0 - 5.2 format -0 beshort 0532 370 XA sysV pure executable +0 beshort 0532 370 XA sysV pure executable >12 belong >0 not stripped >22 beshort >0 - version %d >30 belong >0 - 5.2 format diff --git a/contrib/file/magic/Magdir/ibm6000 b/contrib/file/magic/Magdir/ibm6000 index 7f45072a187a..8b48f370eb79 100644 --- a/contrib/file/magic/Magdir/ibm6000 +++ b/contrib/file/magic/Magdir/ibm6000 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: ibm6000,v 1.12 2013/09/16 15:12:42 christos Exp $ +# $File: ibm6000,v 1.13 2017/03/17 21:35:28 christos Exp $ # ibm6000: file(1) magic for RS/6000 and the RT PC. # 0 beshort 0x01df executable (RISC System/6000 V3.1) or obj module @@ -21,7 +21,7 @@ 0 beshort 0x01f7 64-bit XCOFF executable or object module >20 belong 0 not stripped # GRR: this test is still too general as it catches also many FATs of DOS filesystems -4 belong &0x0feeddb0 +4 belong &0x0feeddb0 # real core dump could not be 32-bit and 64-bit together >7 byte&0x03 !3 AIX core file >>1 byte &0x01 fulldump diff --git a/contrib/file/magic/Magdir/icc b/contrib/file/magic/Magdir/icc index 37fa30e8cb8c..55583b7b4f26 100644 --- a/contrib/file/magic/Magdir/icc +++ b/contrib/file/magic/Magdir/icc @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: icc,v 1.1 2013/01/08 01:43:18 christos Exp $ +# $File: icc,v 1.5 2017/08/13 00:21:47 christos Exp $ # icc: file(1) magic for International Color Consortium file formats # @@ -11,41 +11,204 @@ # http://www.color.org/specification/ICC1v43_2010-12.pdf # # for Specification ICC.1:2010 (Profile version 4.3.0.0). +# URL: http://fileformats.archiveteam.org/wiki/ICC_profile +# Reference: http://www.color.org/iccmax/ICC.2-2016-7.pdf +# Update: Joerg Jenderek # # Bytes 36 to 39 contain a generic profile file signature of "acsp"; # bytes 40 to 43 "may be used to identify the primary platform/operating # system framework for which the profile was created". # -# There are other fields that might be worth dumping as well. -# +# check and display ICC/ICM color profile +0 name color-profile +>36 string acsp +# skip ASCII like Cognacspirit.txt by month <= 12 +>>26 ubeshort <13 +# platform/operating system. Only 5 mentioned +# # This appears to be what's used for Apple ColorSync profiles. # Instead of adding that, Apple just changed the generic "acsp" entry # to be for "ColorSync ICC Color Profile" rather than "Kodak Color # Management System, ICC Profile". # Yes, it's "APPL", not "AAPL"; see the spec. -36 string acspAPPL ColorSync ICC Profile -!:mime application/vnd.iccprofile +>>>40 string APPL ColorSync # Microsoft ICM color profile -36 string acspMSFT Microsoft ICM Color Profile -!:mime application/vnd.iccprofile +>>>40 string MSFT Microsoft # Yes, that's a blank after "SGI". -36 string acspSGI\ SGI ICC Profile -!:mime application/vnd.iccprofile +>>>40 string SGI\ SGI # XXX - is this what's used for the Sun KCMS or not? The standard file # uses just "acsp" for that, but Apple's file uses it for "ColorSync", # and there *is* an identified "primary platform" value of SUNW. -36 string acspSUNW Sun KCMS ICC Profile +>>>40 string SUNW Sun KCMS + +# 5th platform +>>>40 string TGNT Taligent + +# remaining "l" "e" of "color profile" printed later to avoid error +>>>40 string x color profi +#>>>40 string x (%.4s) !:mime application/vnd.iccprofile +# for "ICM" extension only versions 2.x and for Kodak "CC" 2.0 is found +>>>8 ubyte =2 +# do not use empty message text to a avoid error like +# icc, 82: Warning: Current entry does not yet have a description for adding a EXTENSION type +# file.exe: could not find any valid magic files! +>>>>9 ubyte !0 \ble +!:ext icc/icm +# minor version +>>>>9 ubyte =0 \bl +# Kodak colour management system +>>>>>4 string =KCMS \be +!:ext icc/icm/cc +>>>>>4 string !KCMS \be +!:ext icc/icm +>>>8 ubyte !2 \ble +!:ext icc +# Profile version major.4bit-minor.sub1.sub2 like 4.3.0.0 (04300000h) +>>>8 ubyte x %u +>>>9 ubyte/16 x \b.%u +# reserved and shall be null but 205.205 in umx1220u.icm +>>>10 ubyte >0 \b.%u +>>>>11 ubyte >0 \b.%u +# preferred colour management module like appl CCMS KCMS Lino UCCM "Win " "FF " +# skip space like in brmsl08f.icm and null like in brmsl09f.icm, brmsl07f.icm +>>>4 string >\ \b, type %.2s +>>>>6 string >\ \b%.1s +>>>>>7 string >\ \b%.1s +# colour space "XYZ " "Lab " "RGB " CMYK GRAY ... +>>>16 string x \b, %.3s +>>>19 string >\ \b%.1s +# Profile Connection Space (PCS) field usually "XYZ " or "Lab " but sometimes +# null or CMYK like in ISOcoated_v2_to_PSOcoated_v3_DeviceLink.icc +>>>20 string >\0 \b/%.3s +>>>>23 string >\ \b%.1s +# eleven device classes +>>>12 string x \b-%.4s device +# skip 00001964h in hpf69000.icc or 0h in XRDC50Q.ICM or " ROT" in brmsl05f.icm +>>>52 string >\040 +# skip "none" model like in "Trinitron Compatible 9300K G2.2.icm" +>>>>52 ubelong !0x6e6f6e65 +# device manufacturer field like "HP " "IBM " EPSO +>>>>>48 string x \b, %.2s +>>>>>50 string >\ \b%.1s +>>>>>51 string >\ \b%.1s +# model like "ADI " "A265" and skip 20000404h in IS330.icm for RICOH RUSSIAN-SC +>>>>>52 string >\ \ \b/%.3s +>>>>>>55 string >\ \b%.1s +>>>>>52 string x model +# creator (often same as manufacture) like HP SONY XROX or null like in A925A.icm +>>>80 string >\0 by %.2s +>>>>82 string >\ \b%.1s +>>>>>83 string >\ \b%.1s +# profile size +>>>0 ubelong x \b, %u bytes +# skip invalid date 0 like in linearSRGB.icc +>>>24 ubequad !0 +# datetime dd-mm-yyyy hh:mm:ss +>>>>28 ubeshort x \b, %u +# month <= 12 +>>>>26 ubeshort x \b-%u +# year +>>>>24 ubeshort x \b-%u +# do not display midnight time like in CNHP8308.ICC +>>>>30 ubequad&0xFFffFFffFFff0000 !0 +# hour <= 24 +>>>>>30 ubeshort x %u +# minutes <= 59 +>>>>>32 ubeshort x \b:%.2u +# seconds <= 59 +>>>>>34 ubeshort x \b:%.2u +# vendor specific flags like 2 in HPCLJ5.ICM +>>>44 ubeshort >0 \b, 0x%x vendor flags +# profile flags bits 0-2 of least 16 used by ICC +#>>>44 ubelong >0 \b, 0x%x flags +# icEmbeddedProfileTrue +>>>44 ubelong &1 \b, embedded +# icEmbeddedProfileFalse +#>>>44 ubelong ^1 \b, not embedded +# icUseWithEmbeddedDataOnly +>>>44 ubelong &2 \b, dependently +# icUseAnywhere +#>>>44 ubelong ^2 \b, independently +>>>44 ubelong &4 \b, MCS +#>>>44 ubelong ^4 \b, no MCS +# vendor specific device attributes 1~srgb.icc +# E000D00h~CNB7QEDA.ICM C000A00h~CNB5FCAA.ICM 01040401h~CNB25PE3.ICM +>>>56 ubelong >0 \b, 0x%x vendor attribute +# ICC device attributes bits 0-7 used +#>>>60 ubelong x \b, 0x%x attribute +# http://www.color.org/icc34.h +>>>60 ubelong &0x01 \b, transparent +#>>>60 ubelong ^0x01 \b, reflective +>>>60 ubelong &0x02 \b, matte +#>>>60 ubelong ^0x02 \b, glossy +>>>60 ubelong &0x04 \b, negative +#>>>60 ubelong ^0x04 \b, positive +>>>60 ubelong &0x08 \b, black&white +#>>>60 ubelong ^0x08 \b, colour +>>>60 ubelong &0x10 \b, non-paper +#>>>60 ubelong ^0x10 \b, paper +>>>60 ubelong &0x20 \b, non-textured +#>>>60 ubelong ^0x20 \b, textured +>>>60 ubelong &0x40 \b, non-isotropic +#>>>60 ubelong ^0x40 \b, isotropic +>>>60 ubelong &0x80 \b, self-luminous +#>>>60 ubelong ^0x80 \b, non-self-luminous +# rendering intent 0-3 but 7AEA5027h in EE051__1.ICM 6CB1BCh in EE061__1.ICM +>>>64 ubelong >3 \b, 0x%x rendering intent +#>>>64 ubelong =0 \b, perceptual +>>>64 ubelong =1 \b, relative colorimetric +>>>64 ubelong =2 \b, saturation +>>>64 ubelong =3 \b, absolute colorimetric +# PCS illuminant (3*s15Fixed16Numbers) often 0000f6d6 00010000 0000d32d +>>>71 ubequad !0xd6000100000000d3 \b, PCS +# usually X~0.9642*65536=63189.8112~63190=F6D5h ; but also found +# often F6D6 in gt5000r.icm, F6B8 in kodakce.icm, F6CA in RSWOP.icm +>>>>68 ubelong !0x0000f6d5 X=0x%x +# usually Y=1.0~00010000h but Y=0 in brmsl07f.icm +>>>>72 ubelong !0x00010000 Y=0x%x +# usually Z~0.8249*65536=54060.6464~54061=D32Dh ; but also found +# D2F7 in hp1200c.icm, often D32C in A925A.icm, D309 in RSWOP.icm , D2F8 in kodak_dc.icm +>>>>76 ubelong !0x0000d32d Z=0x%x +# Profile ID. MD5 fingerprinting method as defined in Internet RFC 1321. +>>>84 ubequad >0 \b, 0x%llx MD5 +# reserved in older versions should be zero but also found CDCDCDCDCDCDCDCD +#>>100 ubequad x \b 0x%llx reserved +# tag table +# 6 <= tags count <= 43 +#>>>128 ubelong >43 \b, %u tags +>>>128 ubelong x +# shall contain the profileDescriptionTag "desc" , copyrightTag "cprt" +# search range = tags count * 12 -8=< maximal tag count * 12 -8= 43 * 12 -8= 508 +>>>>132 search/508 cprt +# but no copyright tag in linearSRGB.icc +# beneath /System/Library/Frameworks/WebKit.framework/ +# Versions/A/Frameworks/WebCore.framework/Versions/A/Resources +>>>>132 default x \b, no copyright tag +# 1st tag +#>>>132 string x \b, 1st tag %.4s +#>>>136 ubelong x 0x%x offset +#>>>140 ubelong x 0x%x len +# 2nd tag,... +# look also for profileDescriptionTag "desc" +>>>132 search/508 desc +# look further for TextDescriptionType "desc" signature +>>>>(&0.L) string =desc +>>>>>&4 pstring/l x "%s" +# look alternative for multiLocalizedUnicodeType "mluc" signature like in VideoPAL.icc +>>>>(&0.L) string =mluc +>>>>>&(&8.L) ubequad x +>>>>>>&4 bestring16 x '%s' # Any other profile. # XXX - should we use "acsp\0\0\0\0" for "no primary platform" profiles, # and use "acsp" for everything else and dump the "primary platform" # string in those cases? -36 string acsp ICC Profile -!:mime application/vnd.iccprofile +36 string acsp +>0 use color-profile diff --git a/contrib/file/magic/Magdir/images b/contrib/file/magic/Magdir/images index 3e9cd81f3198..f0d087b3b4b6 100644 --- a/contrib/file/magic/Magdir/images +++ b/contrib/file/magic/Magdir/images @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: images,v 1.117 2016/07/05 19:12:21 christos Exp $ +# $File: images,v 1.126 2017/06/11 22:25:44 christos Exp $ # images: file(1) magic for image formats (see also "iff", and "c-lang" for # XPM bitmaps) # @@ -26,23 +26,28 @@ # test of Color Map Type 0~no 1~color map # and Image Type 1 2 3 9 10 11 32 33 # and Color Map Entry Size 0 15 16 24 32 -0 ubequad&0x00FeC400000000C0 0 +0 ubequad&0x00FeC400000000C0 0 # skip more garbage by looking for positive image type ->2 ubyte >0 +>2 ubyte >0 # skip some compiled terminfo by looking for image type less equal 33 ->>2 ubyte <34 +>>2 ubyte <34 # skip arches.3200 , Finder.Root , Slp.1 by looking for low pixel sizes 15 16 24 32 ->>>16 ubyte <33 +>>>16 ubyte <33 # skip more by looking for pixel size 0Fh 10h 18h 20h ->>>>16 ubyte&0xC0 0x00 -# skip 260-16.ico by looking for no color map ->>>>>1 ubyte 0 -# implies no first map entry ->>>>>>3 uleshort 0 ->>>>>>>0 use tga-image +>>>>16 ubyte&0xC0 0x00 # Color Map ->>>>>1 ubyte >0 +>>>>>1 belong&0xfff7ffff 0x01010000 >>>>>>0 use tga-image +>>>>>1 belong&0xfff7ffff 0x00020000 +>>>>>>0 use tga-image +>>>>>1 belong&0xfff7ffff 0x00030000 +>>>>>>0 use tga-image +>>>>>1 default x +# skip 260-16.ico by looking for no color map +>>>>>>1 ubyte 0 +# implies no first map entry +>>>>>>>3 uleshort 0 +>>>>>>>>0 use tga-image # display tga bitmap image information 0 name tga-image >2 ubyte <34 Targa image data @@ -78,7 +83,7 @@ >14 uleshort =0 65536 # Image Pixel Size 15 16 24 32 >16 ubyte x x %d -# X origin of image. 0 normal +# X origin of image. 0 normal >8 uleshort >0 +%d # Y origin of image. 0 normal; positive for top >10 uleshort >0 +%d @@ -90,27 +95,27 @@ >17 ubyte &0x10 - right #>17 ubyte ^0x10 - left # some info say other bits 6-7 should be zero -# but data storage interleave by http://www.fileformat.info/format/tga/corion.htm +# but data storage interleave by http://www.fileformat.info/format/tga/corion.htm # 00 - no interleave;01 - even/odd interleave; 10 - four way interleave; 11 - reserved #>17 ubyte&0xC0 0x00 - no interleave >17 ubyte&0xC0 0x40 - interleave >17 ubyte&0xC0 0x80 - four way interleave >17 ubyte&0xC0 0xC0 - reserved -# positive length implies identification field ->0 ubyte >0 +# positive length implies identification field +>0 ubyte >0 >>18 string x "%s" # last 18 bytes of newer tga file footer signature ->18 search/4261301/s TRUEVISION-XFILE.\0 +>18 search/4261301/s TRUEVISION-XFILE.\0 # extension area offset if not 0 ->>&-8 ulelong >0 +>>&-8 ulelong >0 # length of the extension area. normal 495 for version 2.0 ->>>(&-4.l) uleshort 0x01EF +>>>(&-4.l) uleshort 0x01EF # AuthorName[41] >>>>&0 string >\0 - author "%-.40s" # Comment[324]=4 * 80 null terminated >>>>&41 string >\0 - comment "%-.80s" # date ->>>>&365 ubequad&0xffffFFFFffff0000 !0 +>>>>&365 ubequad&0xffffFFFFffff0000 !0 # Day >>>>>&-6 uleshort x %d # Month @@ -118,7 +123,7 @@ # Year >>>>>&-4 uleshort x \b-%d # time ->>>>&371 ubequad&0xffffFFFFffff0000 !0 +>>>>&371 ubequad&0xffffFFFFffff0000 !0 # hour >>>>>&-8 uleshort x %d # minutes @@ -128,14 +133,14 @@ # JobName[41] >>>>&377 string >\0 - job "%-.40s" # JobHour Jobminute Jobsecond ->>>>&418 ubequad&0xffffFFFFffff0000 !0 +>>>>&418 ubequad&0xffffFFFFffff0000 !0 >>>>>&-8 uleshort x %d >>>>>&-6 uleshort x \b:%.2d >>>>>&-4 uleshort x \b:%.2d # SoftwareId[41] >>>>&424 string >\0 - %-.40s # SoftwareVersionNumber ->>>>&424 ubyte >0 +>>>>&424 ubyte >0 >>>>>&40 uleshort/100 x %d >>>>>&40 uleshort%100 x \b.%d # VersionLetter @@ -143,16 +148,16 @@ # KeyColor >>>>&468 ulelong >0 - keycolor 0x%8.8x # Denominator of Pixel ratio. 0~no pixel aspect ->>>>&474 uleshort >0 +>>>>&474 uleshort >0 # Numerator >>>>>&-4 uleshort >0 - aspect %d >>>>>&-2 uleshort x \b/%d # Denominator of Gamma ratio. 0~no Gamma value ->>>>&478 uleshort >0 +>>>>&478 uleshort >0 # Numerator >>>>>&-4 uleshort >0 - gamma %d >>>>>&-2 uleshort x \b/%d -# ColorOffset +# ColorOffset #>>>>&480 ulelong x - col offset 0x%8.8x # StampOffset #>>>>&484 ulelong x - stamp offset 0x%8.8x @@ -170,43 +175,43 @@ >>&0 regex =[0-9]{1,50} \b, size = %s x >>>&0 regex =[0-9]{1,50} \b %s -0 search/1 P1 ->0 regex/4 P1\\s +0 search/1 P1 +>0 regex/4 P1[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, bitmap !:strength + 45 !:mime image/x-portable-bitmap -0 search/1 P2 ->0 regex/4 P2\\s +0 search/1 P2 +>0 regex/4 P2[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, greymap !:strength + 45 !:mime image/x-portable-greymap 0 search/1 P3 ->0 regex/4 P3\\s +>0 regex/4 P3[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, pixmap !:strength + 45 !:mime image/x-portable-pixmap -0 string P4 ->0 regex/4 P4\\s +0 string P4 +>0 regex/4 P4[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, rawbits, bitmap !:strength + 45 !:mime image/x-portable-bitmap -0 string P5 ->0 regex/4 P5\\s +0 string P5 +>0 regex/4 P5[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, rawbits, greymap !:strength + 45 !:mime image/x-portable-greymap -0 string P6 ->0 regex/4 P6\\s +0 string P6 +>0 regex/4 P6[\040\t\f\r\n] >>0 use netpbm >>>0 string x \b, rawbits, pixmap !:strength + 45 @@ -303,7 +308,7 @@ >>>8 leshort 0x8765 \bJBIG >>>8 leshort 0x8798 \bJPEG2000 >>>8 leshort 0x8799 \bNikon NEF Compressed ->>>8 default x +>>>8 default x >>>>8 leshort x \b(unknown 0x%x) >>>12 use tiff_entry >0 leshort 0x106 \b, PhotometricIntepretation= @@ -414,21 +419,35 @@ # (Greg Roelofs, newt@uchicago.edu) # (Albert Cahalan, acahalan@cs.uml.edu) # -# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ... +# 137 P N G \r \n ^Z \n [4-byte length] I H D R [HEAD data] [HEAD crc] ... # -0 string \x89PNG\x0d\x0a\x1a\x0a PNG image data + +# IHDR parser +0 name png-ihdr +>0 belong x \b, %d x +>4 belong x %d, +>8 byte x %d-bit +>9 byte 0 grayscale, +>9 byte 2 \b/color RGB, +>9 byte 3 colormap, +>9 byte 4 gray+alpha, +>9 byte 6 \b/color RGBA, +#>10 byte 0 deflate/32K, +>12 byte 0 non-interlaced +>12 byte 1 interlaced + +# Standard PNG image. +0 string \x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0DIHDR PNG image data !:mime image/png ->16 belong x \b, %d x ->20 belong x %d, ->24 byte x %d-bit ->25 byte 0 grayscale, ->25 byte 2 \b/color RGB, ->25 byte 3 colormap, ->25 byte 4 gray+alpha, ->25 byte 6 \b/color RGBA, -#>26 byte 0 deflate/32K, ->28 byte 0 non-interlaced ->28 byte 1 interlaced +!:strength +10 +>16 use png-ihdr + +# Apple CgBI PNG image. +0 string \x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x04CgBI +>24 string \x00\x00\x00\x0DIHDR PNG image data (CgBI) +!:mime image/png +!:strength +10 +>>32 use png-ihdr # possible GIF replacements; none yet released! # (Greg Roelofs, newt@uchicago.edu) @@ -438,13 +457,13 @@ !:mime image/x-unknown # # GRR 950115: this is Jeremy Wohl's Free Graphics Format (better): -# +# 0 string FGF95a FGF image (GIF+deflate beta) !:mime image/x-unknown # # GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal # (best; not yet implemented): -# +# 0 string PBF PBF image (deflate compression) !:mime image/x-unknown @@ -528,19 +547,19 @@ # http://www.blackfiveservices.co.uk/awbmtools.shtml # http://biosgfx.narod.ru/v3/ # http://biosgfx.narod.ru/abr-2/ -0 string AWBM +0 string AWBM >4 leshort <1981 Award BIOS bitmap !:mime image/x-award-bmp # image width is a multiple of 4 ->>4 leshort&0x0003 0 +>>4 leshort&0x0003 0 >>>4 leshort x \b, %d >>>6 leshort x x %d >>4 leshort&0x0003 >0 \b, ->>>4 leshort&0x0003 =1 +>>>4 leshort&0x0003 =1 >>>>4 leshort x %d+3 ->>>4 leshort&0x0003 =2 +>>>4 leshort&0x0003 =2 >>>>4 leshort x %d+2 ->>>4 leshort&0x0003 =3 +>>>4 leshort&0x0003 =3 >>>>4 leshort x %d+1 >>>6 leshort x x %d # at offset 8 starts imagedata followed by "RGB " marker @@ -764,11 +783,11 @@ # http://web.archive.org/web/20100206055706/http://www.qzx.com/pc-gpe/pcx.txt # GRR: original test was still too general as it catches xbase examples T5.DBT,T6.DBT with 0xa000000 # test for bytes 0x0a,version byte (0,2,3,4,5),compression byte flag(0,1), bit depth (>0) of PCX or T5.DBT,T6.DBT -0 ubelong&0xffF8fe00 0x0a000000 -# for PCX bit depth > 0 ->3 ubyte >0 +0 ubelong&0xffF8fe00 0x0a000000 +# for PCX bit depth > 0 +>3 ubyte >0 # test for valid versions ->>1 ubyte <6 +>>1 ubyte <6 >>>1 ubyte !1 PCX !:mime image/x-pcx #!:mime image/pcx @@ -828,29 +847,29 @@ # Update: Joerg Jenderek # See http://fileformats.archiveteam.org/wiki/GEM_Raster # For variations, also see: -# http://www.seasip.info/Gem/ff_img.html (Ventura) +# http://www.seasip.info/Gem/ff_img.html (Ventura) # http://www.atari-wiki.com/?title=IMG_file (XIMG, STTT) # http://www.fileformat.info/format/gemraster/spec/index.htm (XIMG, STTT) # http://sylvana.net/1stguide/1STGUIDE.ENG (TIMG) 0 beshort 0x0001 # header_size ->2 beshort 0x0008 +>2 beshort 0x0008 >>0 use gem_info ->2 beshort 0x0009 +>2 beshort 0x0009 >>0 use gem_info # no example for NOSIG ->2 beshort 24 +>2 beshort 24 >>0 use gem_info # no example for HYPERPAINT ->2 beshort 25 +>2 beshort 25 >>0 use gem_info -16 string XIMG\0 +16 string XIMG\0 >0 use gem_info # no example -16 string STTT\0\x10 +16 string STTT\0\x10 >0 use gem_info # no example or description -16 string TIMG\0 +16 string TIMG\0 >0 use gem_info 0 name gem_info @@ -859,15 +878,15 @@ # http://www.snowstone.org.uk/riscos/mimeman/mimemap.txt !:mime image/x-gem # header_size 24 25 27 59 779 words for colored bitmaps ->>2 beshort >9 +>>2 beshort >9 >>>16 string STTT\0\x10 STTT >>>16 string TIMG\0 TIMG # HYPERPAINT or NOSIG variant ->>>16 string \0\x80 +>>>16 string \0\x80 >>>>2 beshort =24 NOSIG >>>>2 beshort !24 HYPERPAINT # NOSIG or XIMG variant ->>>16 default x +>>>16 default x >>>>16 string !XIMG\0 NOSIG >>16 string =XIMG\0 XIMG Image data !:ext img/ximg @@ -1177,7 +1196,7 @@ # updated by: Joerg Jenderek # URL: http://techmods.net/nuvi/ 0 string GARMIN\ BITMAP\ 01 Garmin Bitmap file -# extension is also used for +# extension is also used for # Sony SRF raw image (image/x-sony-srf) # SRF map # Terragen Surface Map (http://www.planetside.co.uk/terragen) @@ -1318,7 +1337,7 @@ !:mime image/x-icns !:apple ????icns !:ext icns ->4 ubelong >0 +>4 ubelong >0 # file size >>4 ubelong x \b, %d bytes # icon type @@ -1451,3 +1470,12 @@ >0x10 string GVRT Sega GVR image: >>0x10 use sega-gvr-image-header >>0x08 belong x \b, global index = %u + +# Light Field Picture +# Documentation: http://optics.miloush.net/lytro/TheFileFormat.aspx +# Typical file extensions: .lfp .lfr .lfx + +0 belong 0x894C4650 +>4 belong 0x0D0A1A0A +>12 belong 0x00000000 Lytro Light Field Picture +>8 belong x \b, version %d diff --git a/contrib/file/magic/Magdir/intel b/contrib/file/magic/Magdir/intel index 3f96b758fdd4..c4f02544d638 100644 --- a/contrib/file/magic/Magdir/intel +++ b/contrib/file/magic/Magdir/intel @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: intel,v 1.14 2015/11/10 00:13:27 christos Exp $ +# $File: intel,v 1.15 2017/03/17 21:35:28 christos Exp $ # intel: file(1) magic for x86 Unix # # Various flavors of x86 UNIX executable/object (other than Xenix, which @@ -36,8 +36,8 @@ # ./msdos (version 5.25) labeled the next entry as "MS Windows COFF Intel 80386 object file" # ./intel (version 5.25) label labeled the next entry as "80386 COFF executable" # SGI labeled the next entry as "iAPX 386 executable" --Dan Quinlan -0 leshort =0514 -# use subroutine to display name+flags+variables for common object formated files +0 leshort =0514 +# use subroutine to display name+flags+variables for common object formated files >0 use display-coff #>12 lelong >0 not stripped # no hint found, that at offset 22 is version diff --git a/contrib/file/magic/Magdir/isz b/contrib/file/magic/Magdir/isz index 3388a82a5b9d..af68db2b3e2e 100644 --- a/contrib/file/magic/Magdir/isz +++ b/contrib/file/magic/Magdir/isz @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ -# $File: isz,v 1.3 2014/04/30 21:41:02 christos Exp $ -# ISO Zipped file format +# $File: isz,v 1.4 2017/03/17 21:35:28 christos Exp $ +# ISO Zipped file format # http://www.ezbsystems.com/isz/iszspec.txt 0 string IsZ! ISO Zipped file >4 byte x \b, header size %u diff --git a/contrib/file/magic/Magdir/jpeg b/contrib/file/magic/Magdir/jpeg index 2b49c21c6053..57adb1e546b0 100644 --- a/contrib/file/magic/Magdir/jpeg +++ b/contrib/file/magic/Magdir/jpeg @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: jpeg,v 1.30 2016/07/04 15:18:23 christos Exp $ +# $File: jpeg,v 1.31 2017/03/17 21:35:28 christos Exp $ # JPEG images # SunOS 5.5.1 had # @@ -53,14 +53,14 @@ >>5 beshort x \b%d >>9 byte x \b, frames %d ->0 beshort 0xFFC1 +>0 beshort 0xFFC1 >>(2.S+2) use jpeg_segment >>4 byte x \b, extended sequential, precision %d >>7 beshort x \b, %dx >>5 beshort x \b%d >>9 byte x \b, frames %d ->0 beshort 0xFFC2 +>0 beshort 0xFFC2 >>(2.S+2) use jpeg_segment >>4 byte x \b, progressive, precision %d >>7 beshort x \b, %dx @@ -71,11 +71,11 @@ >0 beshort 0xFFC4 >>(2.S+2) use jpeg_segment ->0 beshort 0xFFE1 +>0 beshort 0xFFE1 # Recursion handled by FFE0 #>>(2.S+2) use jpeg_segment >>4 string Exif \b, Exif Standard: [ ->>>10 indirect/r x +>>>10 indirect/r x >>>10 string x \b] # Application specific markers diff --git a/contrib/file/magic/Magdir/kerberos b/contrib/file/magic/Magdir/kerberos index cb07fedbe27f..93b8f79de99b 100644 --- a/contrib/file/magic/Magdir/kerberos +++ b/contrib/file/magic/Magdir/kerberos @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: kerberos,v 1.1 2014/12/10 18:45:43 christos Exp $ +# $File: kerberos,v 1.2 2017/03/17 21:35:28 christos Exp $ # kerberos: MIT kerberos file binary formats # @@ -38,7 +38,7 @@ >>>>>&0 bedate x \b, date=%s >>>>>>&0 byte x \b, kvno=%u #>>>>>>>&0 pstring/H x -#>>>>>>>>&0 belong x +#>>>>>>>>&0 belong x #>>>>>>>>>>&0 use keytab_entry 0 belong 0x05020000 Kerberos Keytab file diff --git a/contrib/file/magic/Magdir/kml b/contrib/file/magic/Magdir/kml index ed0f42ed8533..d603ea806288 100644 --- a/contrib/file/magic/Magdir/kml +++ b/contrib/file/magic/Magdir/kml @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------ -# $File: kml,v 1.3 2010/11/25 15:00:12 christos Exp $ +# $File: kml,v 1.4 2017/03/17 21:35:28 christos Exp $ # Type: Google KML, formerly Keyhole Markup Language # Future development of this format has been handed # over to the Open Geospatial Consortium. # http://www.opengeospatial.org/standards/kml/ # From: Asbjoern Sloth Toennesen 0 string/t \20 search/400 \ xmlns= +>20 search/400 \ xmlns= >>&0 regex ['"]http://earth.google.com/kml Google KML document !:mime application/vnd.google-earth.kml+xml >>>&1 string 2.0' \b, version 2.0 @@ -25,7 +25,7 @@ >>>&1 string/t 2.2 \b, version 2.2 #------------------------------------------------------------------------------ -# Type: Google KML Archive (ZIP based) +# Type: Google KML Archive (ZIP based) # http://code.google.com/apis/kml/documentation/kml_tut.html # From: Asbjoern Sloth Toennesen 0 string PK\003\004 diff --git a/contrib/file/magic/Magdir/linux b/contrib/file/magic/Magdir/linux index c8cc0df5e50e..0630a8a7ce10 100644 --- a/contrib/file/magic/Magdir/linux +++ b/contrib/file/magic/Magdir/linux @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: linux,v 1.63 2015/08/24 05:16:11 christos Exp $ +# $File: linux,v 1.64 2017/03/17 21:35:28 christos Exp $ # linux: file(1) magic for Linux files # # Values for Linux/i386 binaries, from Daniel Quinlan @@ -199,7 +199,7 @@ ############################################################################ # Linux 8086 executable 0 lelong&0xFF0000FF 0xC30000E9 Linux-Dev86 executable, headerless ->5 string . +>5 string . >>4 string >\0 \b, libc version %s 0 lelong&0xFF00FFFF 0x4000301 Linux-8086 executable @@ -213,7 +213,7 @@ >2 byte&0x40 !0 \b, A_PURE >2 byte&0x80 !0 \b, A_TOVLY >28 long !0 \b, not stripped ->37 string . +>37 string . >>36 string >\0 \b, libc version %s # 0 lelong&0xFF00FFFF 0x10000301 ld86 I80386 executable @@ -241,7 +241,7 @@ >24 lelong x %d symbols >28 lelong x %d ocons -# Linux Logical Volume Manager (LVM) +# Linux Logical Volume Manager (LVM) # Emmanuel VARAGNAT # # System ID, UUID and volume group name are 128 bytes long @@ -301,7 +301,7 @@ >>&0x20 lequad x \b, size: %lld 0x618 string LVM2\ 001 LVM2 PV (Linux Logical Volume Manager) ->&(&-12.l-0x21) byte x +>&(&-12.l-0x21) byte x # display UUID in LVM format + display all 32 bytes (instead of max string length: 31) >>&0x0 string >\x2f \b, UUID: %.6s >>&0x6 string >\x2f \b-%.4s @@ -340,7 +340,7 @@ # Summary: Xen saved domain file # Created by: Radek Vokal 0 string LinuxGuestRecord Xen saved domain ->20 search/256 (name +>20 search/256 (name >>&1 string x (name %s) # Type: Xen, the virtual machine monitor @@ -397,7 +397,7 @@ >>0x1046 ubeshort x \b%04x # Linux device tree: -# File format description can be found in the Linux kernel sources at +# File format description can be found in the Linux kernel sources at # Documentation/devicetree/booting-without-of.txt # From Christoph Biedl 0 belong 0xd00dfeed diff --git a/contrib/file/magic/Magdir/lisp b/contrib/file/magic/Magdir/lisp index db0592e730c7..43d102e1dd76 100644 --- a/contrib/file/magic/Magdir/lisp +++ b/contrib/file/magic/Magdir/lisp @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------ -# $File: lisp,v 1.24 2015/11/30 20:54:26 christos Exp $ +# $File: lisp,v 1.25 2017/03/17 21:35:28 christos Exp $ # lisp: file(1) magic for lisp programs # # various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com) # updated by Joerg Jenderek # GRR: This lot is too weak -#0 string ;; +#0 string ;; # windows INF files often begin with semicolon and use CRLF as line end # lisp files are mainly created on unix system with LF as line end #>2 search/4096 !\r Lisp/Scheme program text @@ -28,9 +28,9 @@ # URL: https://en.wikipedia.org/wiki/Emacs_Lisp # Reference: http://ftp.gnu.org/old-gnu/emacs/elisp-manual-18-1.03.tar.gz -# Update: Joerg Jenderek +# Update: Joerg Jenderek # Emacs 18 - this is always correct, but not very magical. -0 string \012( +0 string \012( # look for emacs lisp keywords # GRR: split regex because it is too long or get error like # lisp, 36: Warning: cannot get string from `^(defun|defvar|defconst|defmacro|setq|fset|put|provide|require|' @@ -50,13 +50,13 @@ # Emacs 19+ - ver. recognition added by Ian Springer # Also applies to XEmacs 19+ .elc files; could tell them apart with regexs # - Chris Chittleborough -# Update: Joerg Jenderek -0 string ;ELC +# Update: Joerg Jenderek +0 string ;ELC # version\0\0\0 >4 byte >18 Emacs/XEmacs v%d byte-compiled Lisp data # why less than 32 ? does not make sense to me. GNU Emacs version is 24.5 at April 2015 #>4 byte <32 Emacs/XEmacs v%d byte-compiled Lisp data -!:mime application/x-elc +!:mime application/x-elc !:apple EMAxTEXT !:ext elc @@ -67,7 +67,7 @@ 0 long 0x70768BD2 CLISP memory image data 0 long 0xD28B7670 CLISP memory image data, other endian -#.com and .bin for MIT scheme +#.com and .bin for MIT scheme 0 string \372\372\372\372 MIT scheme (library?) # From: David Allouche diff --git a/contrib/file/magic/Magdir/m4 b/contrib/file/magic/Magdir/m4 index f6b5e52640f9..3a1c6d19f7db 100644 --- a/contrib/file/magic/Magdir/m4 +++ b/contrib/file/magic/Magdir/m4 @@ -1,6 +1,9 @@ #------------------------------------------------------------------------------ -# $File: m4,v 1.1 2011/12/08 12:12:46 rrt Exp $ +# $File: m4,v 1.2 2017/08/14 07:40:38 christos Exp $ # make: file(1) magic for M4 scripts # 0 regex \^dnl\ M4 macro processor script text !:mime text/x-m4 +0 regex \^AC_DEFUN\\(\\[ M4 macro processor script text +!:strength + 15 +!:mime text/x-m4 diff --git a/contrib/file/magic/Magdir/macintosh b/contrib/file/magic/Magdir/macintosh index d7f20f2027f1..e7c0e5e81da6 100644 --- a/contrib/file/magic/Magdir/macintosh +++ b/contrib/file/magic/Magdir/macintosh @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: macintosh,v 1.26 2015/11/25 00:36:02 christos Exp $ +# $File: macintosh,v 1.27 2017/03/17 21:35:28 christos Exp $ # macintosh description # # BinHex is the Macintosh ASCII-encoded file format (see also "apple") @@ -109,9 +109,9 @@ # the assumption that 65-72 will all be ASCII (0x20-0x7F), that 73 will # have bits 1 (changed), 2 (busy), 3 (bozo), and 6 (invisible) unset, # and that 74 will be 0. So something like -# +# # 71 belong&0x80804EFF 0x00000000 Macintosh MacBinary data -# +# # >73 byte&0x01 0x01 \b, inited # >73 byte&0x02 0x02 \b, changed # >73 byte&0x04 0x04 \b, busy @@ -254,7 +254,7 @@ >0x9C string INDEX data file index >0x9C string VIEW data view -# spss magic for SPSS system and portable files, +# spss magic for SPSS system and portable files, # from Bruce Foster (bef@nwu.edu). 0 long 0xc1e2c3c9 SPSS Portable File @@ -273,7 +273,7 @@ # entries depend on the data arithmetic added after v.35 # There's also some Pascal strings in here, ditto... -# The boot block signature, according to IM:Files, is +# The boot block signature, according to IM:Files, is # "for HFS volumes, this field always contains the value 0x4C4B." # But if this is true for MFS or HFS+ volumes, I don't know. # Alternatively, the boot block is supposed to be zeroed if it's @@ -291,10 +291,10 @@ # *.hfs updated by Joerg Jenderek # http://en.wikipedia.org/wiki/Hierarchical_File_System # "BD" gives many false positives -0x400 beshort 0x4244 +0x400 beshort 0x4244 # ftp://ftp.mars.org/pub/hfs/hfsutils-3.2.6.tar.gz/hfsutils-3.2.6/libhfs/apple.h # first block of volume bit map (always 3) ->0x40e ubeshort 0x0003 +>0x40e ubeshort 0x0003 # maximal length of volume name is 27 >>0x424 ubyte <28 Macintosh HFS data !:mime application/x-apple-diskimage @@ -351,15 +351,15 @@ #>0x230 string x first type: %s, #>0x210 string x name: %s, #>0x254 belong x number of blocks: %d, -#>0x400 beshort 0x504D +#>0x400 beshort 0x504D #>>0x430 string x second type: %s, #>>0x410 string x name: %s, #>>0x454 belong x number of blocks: %d, -#>>0x800 beshort 0x504D +#>>0x800 beshort 0x504D #>>>0x830 string x third type: %s, #>>>0x810 string x name: %s, #>>>0x854 belong x number of blocks: %d, -#>>>0xa00 beshort 0x504D +#>>>0xa00 beshort 0x504D #>>>>0xa30 string x fourth type: %s, #>>>>0xa10 string x name: %s, #>>>>0xa54 belong x number of blocks: %d diff --git a/contrib/file/magic/Magdir/make b/contrib/file/magic/Magdir/make index f8509d6bdbcf..2895325a6e62 100644 --- a/contrib/file/magic/Magdir/make +++ b/contrib/file/magic/Magdir/make @@ -1,7 +1,8 @@ #------------------------------------------------------------------------------ -# $File: make,v 1.2 2015/08/25 07:34:06 christos Exp $ +# $File: make,v 1.3 2016/12/10 14:21:29 christos Exp $ # make: file(1) magic for makefiles # +# URL: https://en.wikipedia.org/wiki/Make_(software) 0 regex/100l \^CFLAGS makefile script text !:mime text/x-makefile 0 regex/100l \^VPATH makefile script text @@ -10,12 +11,19 @@ !:mime text/x-makefile 0 regex/100l \^all: makefile script text !:mime text/x-makefile -0 regex/100l \^\.PRECIOUS makefile script text +0 regex/100l \^\\.PRECIOUS makefile script text !:mime text/x-makefile -0 regex/100l \^\.BEGIN BSD makefile script text +# Update: Joerg Jenderek +# Reference: https://www.freebsd.org/cgi/man.cgi?make(1) +# exclude grub-core\lib\libgcrypt\mpi\Makefile.am with "#BEGIN_ASM_LIST" +# by additional escaping point character +0 regex/100l \^\\.BEGIN BSD makefile script text with "%s" !:mime text/x-makefile -0 regex/100l \^\.include BSD makefile script text +!:ext /mk +# exclude MS Windows help file CoNtenT with ":include FOOBAR.CNT" +# and NSIS script with "!include" by additional escaping point character +0 regex/100l \^\\.include BSD makefile script text with "%s" !:mime text/x-makefile - +!:ext /mk 0 regex/100l \^SUBDIRS automake makefile script text !:mime text/x-makefile diff --git a/contrib/file/magic/Magdir/maple b/contrib/file/magic/Magdir/maple index 05a8eaf298be..44ab2842b604 100644 --- a/contrib/file/magic/Magdir/maple +++ b/contrib/file/magic/Magdir/maple @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: maple,v 1.7 2013/01/11 16:45:23 christos Exp $ +# $File: maple,v 1.8 2017/03/17 21:35:28 christos Exp $ # maple: file(1) magic for maple files # "H. Nanosecond" # Maple V release 4, a multi-purpose math program @@ -13,7 +13,7 @@ # no magic for these :-( # they are compiled indexes for maple files -# .hdb +# .hdb 0 string \000\004\000\000 Maple help database # .mhp @@ -40,7 +40,7 @@ # from byte 4 it is either 'nul E' or 'soh R' # I think 'nul E' means a file that was saved as a different name # a sort of revision marking -# 'soh R' means new +# 'soh R' means new >4 string \000\105 An old revision >4 string \001\122 The latest save diff --git a/contrib/file/magic/Magdir/marc21 b/contrib/file/magic/Magdir/marc21 index 7e859a3893b9..fd509ec15245 100644 --- a/contrib/file/magic/Magdir/marc21 +++ b/contrib/file/magic/Magdir/marc21 @@ -2,27 +2,29 @@ # marc21: file(1) magic for MARC 21 Format # # Kevin Ford (kefo@loc.gov) -# +# # MARC21 formats are for the representation and communication # of bibliographic and related information in machine-readable # form. For more info, see http://www.loc.gov/marc/ # leader position 20-21 must be 45 -20 string 45 +# and 22-23 also 00 so far, but we check that later. +20 string 45 +>0 search/2048 \x1e # leader starts with 5 digits, followed by codes specific to MARC format ->0 regex/1l (^[0-9]{5})[acdnp][^bhlnqsu-z] MARC21 Bibliographic +>>0 regex/1l (^[0-9]{5})[acdnp][^bhlnqsu-z] MARC21 Bibliographic !:mime application/marc ->0 regex/1l (^[0-9]{5})[acdnosx][z] MARC21 Authority +>>0 regex/1l (^[0-9]{5})[acdnosx][z] MARC21 Authority !:mime application/marc ->0 regex/1l (^[0-9]{5})[cdn][uvxy] MARC21 Holdings +>>0 regex/1l (^[0-9]{5})[cdn][uvxy] MARC21 Holdings !:mime application/marc -0 regex/1l (^[0-9]{5})[acdn][w] MARC21 Classification +>>0 regex/1l (^[0-9]{5})[acdn][w] MARC21 Classification !:mime application/marc ->0 regex/1l (^[0-9]{5})[cdn][q] MARC21 Community +>>0 regex/1l (^[0-9]{5})[cdn][q] MARC21 Community !:mime application/marc # leader position 22-23, should be "00" but is it? ->0 regex/1l (^.{21})([^0]{2}) (non-conforming) +>>0 regex/1l (^.{21})([^0]{2}) (non-conforming) !:mime application/marc diff --git a/contrib/file/magic/Magdir/mathematica b/contrib/file/magic/Magdir/mathematica index a93899e83c2e..e76957eea43a 100644 --- a/contrib/file/magic/Magdir/mathematica +++ b/contrib/file/magic/Magdir/mathematica @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: mathematica,v 1.8 2015/04/09 20:01:40 christos Exp $ +# $File: mathematica,v 1.9 2017/03/17 21:35:28 christos Exp $ # mathematica: file(1) magic for mathematica files # "H. Nanosecond" # Mathematica a multi-purpose math program @@ -49,7 +49,7 @@ #0 string (*This\ is\ a\ Mathematica\ binary\ dump\ file.\ It\ can\ be\ loaded\ with\ Get.*) Mathematica binary file 0 string (*This\ is\ a\ Mathematica\ binary\ Mathematica binary file -#>71 string \000\010\010\010\010\000\000\000\000\000\000\010\100\010\000\000\000 +#>71 string \000\010\010\010\010\000\000\000\000\000\000\010\100\010\000\000\000 # >71... is optional >88 string >\0 from %s @@ -59,7 +59,7 @@ 0 string MMAPBF\000\001\000\000\000\203\000\001\000 Mathematica PBF (fonts I think) # .ml files These are menu resources I think -# these start with "[0-9][0-9][0-9]\ A~[0-9][0-9][0-9]\ +# these start with "[0-9][0-9][0-9]\ A~[0-9][0-9][0-9]\ # how to put that into a magic rule? 4 string \ A~ MAthematica .ml file diff --git a/contrib/file/magic/Magdir/metastore b/contrib/file/magic/Magdir/metastore index 285c3cfa0cca..53f5b37c936a 100644 --- a/contrib/file/magic/Magdir/metastore +++ b/contrib/file/magic/Magdir/metastore @@ -1,8 +1,8 @@ #------------------------------------------------------------------------------ -# $File: metastore,v 1.1 2011/04/06 12:37:44 christos Exp $ +# $File: metastore,v 1.2 2017/03/17 21:35:28 christos Exp $ # metastore: file(1) magic for metastore files # From: Thomas Wissen # see http://david.hardeman.nu/software.php#metastore -0 string MeTaSt00r3 Metastore data file, +0 string MeTaSt00r3 Metastore data file, >10 bequad x version %0llx diff --git a/contrib/file/magic/Magdir/meteorological b/contrib/file/magic/Magdir/meteorological index 541bbbffb894..9e7a3f1bcca6 100644 --- a/contrib/file/magic/Magdir/meteorological +++ b/contrib/file/magic/Magdir/meteorological @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: meteorological,v 1.1 2014/08/04 06:26:16 christos Exp $ +# $File: meteorological,v 1.2 2017/03/17 21:35:28 christos Exp $ # rinex: file(1) magic for RINEX files # http://igscb.jpl.nasa.gov/igscb/data/format/rinex210.txt # ftp://cddis.gsfc.nasa.gov/pub/reports/formats/rinex300.pdf @@ -34,7 +34,7 @@ >>&32 string x \b, date %15.15s >>5 string x \b, version %6.6s !:mime rinex/meteorological ->80 search/256 XXRINEXN RINEX Data, Navigation +>80 search/256 XXRINEXN RINEX Data, Navigation >>&32 string x \b, date %15.15s >>5 string x \b, version %6.6s !:mime rinex/navigation diff --git a/contrib/file/magic/Magdir/microfocus b/contrib/file/magic/Magdir/microfocus index b2d204b1b0c3..e5b247cd3d90 100644 --- a/contrib/file/magic/Magdir/microfocus +++ b/contrib/file/magic/Magdir/microfocus @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ -# $File: microfocus,v 1.1 2016/02/09 01:22:49 christos Exp $ -# Micro Focus COBOL data files. +# $File: microfocus,v 1.2 2017/03/17 21:35:28 christos Exp $ +# Micro Focus COBOL data files. # http://documentation.microfocus.com/help/index.jsp?topic=\ # %2FGUID-0E0191D8-C39A-44D1-BA4C-D67107BAF784%2FHRFLRHFILE05.html diff --git a/contrib/file/magic/Magdir/mime b/contrib/file/magic/Magdir/mime index 42ca52dc6b58..57b2dd557ba2 100644 --- a/contrib/file/magic/Magdir/mime +++ b/contrib/file/magic/Magdir/mime @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# $File: mime,v 1.6 2010/11/25 15:00:12 christos Exp $ +# $File: mime,v 1.8 2017/03/17 22:20:22 christos Exp $ # mime: file(1) magic for MIME encoded files # -0 string/t Content-Type:\ +0 string/t Content-Type:\040 >14 string >\0 %s 0 string/t Content-Type: >13 string >\0 %s diff --git a/contrib/file/magic/Magdir/misctools b/contrib/file/magic/Magdir/misctools index eeb518d4f92a..3ce91b560bf7 100644 --- a/contrib/file/magic/Magdir/misctools +++ b/contrib/file/magic/Magdir/misctools @@ -1,6 +1,6 @@ #----------------------------------------------------------------------------- -# $File: misctools,v 1.16 2016/02/14 15:46:52 christos Exp $ +# $File: misctools,v 1.17 2017/03/17 21:35:28 christos Exp $ # misctools: file(1) magic for miscellaneous UNIX tools. # 0 search/1 %%!! X-Post-It-Note text @@ -14,7 +14,7 @@ #!:mime text/x-vcard !:mime text/vcard # VERSION must come right after BEGIN for 3.0 or 4.0 except in 2.1 , where it can be anywhere ->12 search/14000/c VERSION: +>12 search/14000/c VERSION: # VERSION 2.1 , 3.0 or 4.0 >>&0 string x \b, version %-.3s @@ -48,7 +48,7 @@ >12 ulelong !0x20 \b, 0x%8.8x RVA # CheckSum 0 >16 ulelong !0 \b, CheckSum 0x%8.8x -# Reserved or TimeDateStamp +# Reserved or TimeDateStamp >20 ledate x \b, %s # https://msdn.microsoft.com/en-us/library/windows/desktop/ms680519%28v=vs.85%29.aspx # Flags MINIDUMP_TYPE enumeration type 0 0x121 0x800 diff --git a/contrib/file/magic/Magdir/modem b/contrib/file/magic/Magdir/modem index e4decfda5195..d988e903bfcf 100644 --- a/contrib/file/magic/Magdir/modem +++ b/contrib/file/magic/Magdir/modem @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: modem,v 1.7 2016/01/08 00:56:42 christos Exp $ +# $File: modem,v 1.8 2017/03/17 21:35:28 christos Exp $ # modem: file(1) magic for modem programs # # From: Florian La Roche @@ -13,24 +13,24 @@ # URL: https://de.wikipedia.org/wiki/Fax # Reference: http://web.archive.org/web/20020628195336/http://www.netnam.vn/unescocourse/computervision/104.htm # GRR: EOL of G3 is too general as it catches also TrueType fonts, Postscript PrinterFontMetric, others -0 short 0x0100 +0 short 0x0100 # 16 0-bits near beginning like True Type fonts *.ttf, Postscript PrinterFontMetric *.pfm, FTYPE.HYPERCARD, XFER ->2 search/9 \0\0 +>2 search/9 \0\0 # maximal 7 0-bits for pixel sequences or 11 0-bits for EOL in G3 ->2 default x +>2 default x # skip IRCAM file (VAX big-endian) ./audio ->>0 belong !0x0001a364 +>>0 belong !0x0001a364 # skip GEM Image data ./images ->>>2 beshort !0x0008 +>>>2 beshort !0x0008 # look for first keyword of Panorama database *.pan ->>>>11 search/262 \x06DESIGN +>>>>11 search/262 \x06DESIGN # skip Panorama database ->>>>11 default x +>>>>11 default x # old Apple DreamWorld DreamGrafix *.3200 with keyword at end of g3 looking files ->>>>>27118 search/1864 DreamWorld ->>>>>27118 default x +>>>>>27118 search/1864 DreamWorld +>>>>>27118 default x # skip MouseTrap/Mt.Defaults with file size 16 found on Golden Orchard Apple II CD Rom ->>>>>>8 ubequad !0x2e01010454010203 +>>>>>>8 ubequad !0x2e01010454010203 # skip PICTUREH.SML found on Golden Orchard Apple II CD Rom >>>>>>>8 ubequad !0x5dee74ad1aa56394 raw G3 (Group 3) FAX, byte-padded # version 5.25 labeled the entry above "raw G3 data, byte-padded" @@ -39,9 +39,9 @@ !:ext g3 # unusual image starting with black pixel #0 short 0x1300 raw G3 (Group 3) FAX -0 short 0x1400 +0 short 0x1400 # 16 0-bits near beginning like PicturePuzzler found on Golden Orchard Apple CD Rom ->2 search/9 \0\0 +>2 search/9 \0\0 # maximal 7 0-bits for pixel sequences or 11 0-bits for EOL in G3 >2 default x raw G3 (Group 3) FAX # version 5.25 labeled the above entry as "raw G3 data" diff --git a/contrib/file/magic/Magdir/mozilla b/contrib/file/magic/Magdir/mozilla index 173018c3fbb8..23288019f1aa 100644 --- a/contrib/file/magic/Magdir/mozilla +++ b/contrib/file/magic/Magdir/mozilla @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ -# $File: mozilla,v 1.6 2015/01/25 16:20:46 christos Exp $ -# mozilla: file(1) magic for Mozilla XUL fastload files +# $File: mozilla,v 1.7 2017/03/17 21:35:28 christos Exp $ +# mozilla: file(1) magic for Mozilla XUL fastload files # (XUL.mfasl and XPC.mfasl) # URL: http://www.mozilla.org/ # From: Josh Triplett diff --git a/contrib/file/magic/Magdir/msdos b/contrib/file/magic/Magdir/msdos index 55ea3e83c3a7..6eb12c215774 100644 --- a/contrib/file/magic/Magdir/msdos +++ b/contrib/file/magic/Magdir/msdos @@ -1,12 +1,12 @@ #------------------------------------------------------------------------------ -# $File: msdos,v 1.111 2016/09/14 01:26:26 christos Exp $ +# $File: msdos,v 1.120 2017/08/13 00:21:47 christos Exp $ # msdos: file(1) magic for MS-DOS files # # .BAT files (Daniel Quinlan, quinlan@yggdrasil.com) # updated by Joerg Jenderek at Oct 2008,Apr 2011 -0 string/t @ +0 string/t @ >1 string/cW \ echo\ off DOS batch file text !:mime text/x-msdos-batch >1 string/cW echo\ off DOS batch file text @@ -230,7 +230,7 @@ >>(8.s*16) string go32stub for MS-DOS, DJGPP go32 DOS extender >>(8.s*16) string emx >>>&1 string x for DOS, Win or OS/2, emx %s ->>&(&0x42.l-3) byte x +>>&(&0x42.l-3) byte x >>>&0x26 string UPX \b, UPX compressed # and yet another guess: small .text, and after large .data is unusal, could be 32lite >>&0x2c search/0xa0 .text @@ -240,8 +240,8 @@ >(8.s*16) string $WdX \b, WDos/X DOS extender # By now an executable type should have been printed out. The executable -# may be a self-uncompressing archive, so look for evidence of that and -# print it out. +# may be a self-uncompressing archive, so look for evidence of that and +# print it out. # # Some signatures below from Greg Roelofs, newt@uchicago.edu. # @@ -283,8 +283,8 @@ # Skip to the end of the EXE. This will usually work fine in the PE case # because the MZ image is hardcoded into the toolchain and almost certainly # won't match any of these signatures. ->(4.s*512) long x ->>&(2.s-517) byte x +>(4.s*512) long x +>>&(2.s-517) byte x >>>&0 string PK\3\4 \b, ZIP self-extracting archive >>>&0 string Rar! \b, RAR self-extracting archive >>>&0 string =!\x11 \b, AIN 2.x self-extracting archive @@ -312,71 +312,77 @@ # only version=0x100 found >3 uleshort x \b, version 0x%x # length of string containing author,info and special characters ->6 ubyte >0 +>6 ubyte >0 #>>6 pstring x \b, name=%s >>7 string >\0 \b, author=%-.14s >>7 search/254 \xff \b, info= #>>>&0 string x \b%-s >>>&0 string x \b%-.15s -# for FreeDOS *.KL files +# for FreeDOS *.KL files 0 string/b KLF FreeDOS KEYBoard Layout file # only version=0x100 or 0x101 found >3 uleshort x \b, version 0x%x # stringlength ->5 ubyte >0 +>5 ubyte >0 >>8 string x \b, name=%-.2s -0 string \xffKEYB\ \ \ \0\0\0\0 +0 string \xffKEYB\ \ \ \0\0\0\0 >12 string \0\0\0\0`\004\360 MS-DOS KEYBoard Layout file -# DOS device driver updated by Joerg Jenderek at May 2011 -# http://maben.homeip.net/static/S100/IBM/software/DOS/DOS%20techref/CHAPTER.009 -0 ulequad&0x07a0ffffffff 0xffffffff DOS executable ( ->40 search/7 UPX! \bUPX compressed +# DOS device driver updated by Joerg Jenderek at May 2011,Mar 2017 +# https://amaus.net/static/S100/IBM/software/DOS/DOS%20techref/CHAPTER.009 +0 ulequad&0x07a0ffffffff 0xffffffff +>0 use msdos-driver +0 name msdos-driver DOS executable ( +#!:mime application/octet-stream +!:mime application/x-dosdriver +# also found FreeDOS print driver SPOOL.DEV and disc compression driver STACLOAD.BIN +!:ext sys/dev/bin +>40 search/7 UPX! \bUPX compressed # DOS device driver attributes >4 uleshort&0x8000 0x0000 \bblock device driver # character device >4 uleshort&0x8000 0x8000 \b ->>4 uleshort&0x0008 0x0008 \bclock +>>4 uleshort&0x0008 0x0008 \bclock # fast video output by int 29h ->>4 uleshort&0x0010 0x0010 \bfast +>>4 uleshort&0x0010 0x0010 \bfast # standard input/output device ->>4 uleshort&0x0003 >0 \bstandard +>>4 uleshort&0x0003 >0 \bstandard >>>4 uleshort&0x0001 0x0001 \binput >>>4 uleshort&0x0003 0x0003 \b/ ->>>4 uleshort&0x0002 0x0002 \boutput +>>>4 uleshort&0x0002 0x0002 \boutput >>4 uleshort&0x8000 0x8000 \bcharacter device driver ->0 ubyte x +>0 ubyte x # upx compressed device driver has garbage instead of real in name field of header ->>40 search/7 UPX! ->>40 default x +>>40 search/7 UPX! +>>40 default x # leading/trailing nulls, zeros or non ASCII characters in 8-byte name field at offset 10 are skipped ->>>12 ubyte >0x27 \b ->>>>10 ubyte >0x20 ->>>>>10 ubyte !0x2E +>>>12 ubyte >0x2E \b +>>>>10 ubyte >0x20 +>>>>>10 ubyte !0x2E >>>>>>10 ubyte !0x2A \b%c ->>>>11 ubyte >0x20 +>>>>11 ubyte >0x20 >>>>>11 ubyte !0x2E \b%c ->>>>12 ubyte >0x20 ->>>>>12 ubyte !0x39 +>>>>12 ubyte >0x20 +>>>>>12 ubyte !0x39 >>>>>>12 ubyte !0x2E \b%c ->>>13 ubyte >0x20 +>>>13 ubyte >0x20 >>>>13 ubyte !0x2E \b%c ->>>>14 ubyte >0x20 +>>>>14 ubyte >0x20 >>>>>14 ubyte !0x2E \b%c ->>>>15 ubyte >0x20 +>>>>15 ubyte >0x20 >>>>>15 ubyte !0x2E \b%c ->>>>16 ubyte >0x20 ->>>>>16 ubyte !0x2E +>>>>16 ubyte >0x20 +>>>>>16 ubyte !0x2E >>>>>>16 ubyte <0xCB \b%c ->>>>17 ubyte >0x20 ->>>>>17 ubyte !0x2E +>>>>17 ubyte >0x20 +>>>>>17 ubyte !0x2E >>>>>>17 ubyte <0x90 \b%c # some character device drivers like ASPICD.SYS, btcdrom.sys and Cr_atapi.sys contain only spaces or points in name field ->>>4 uleshort&0x8000 0x8000 ->>>>12 ubyte <0x2F +>>>12 ubyte <0x2F # they have their real name at offset 22 ->>>>>22 string >\0 \b%-.5s ->4 uleshort&0x8000 0x0000 +# also block device drivers like DUMBDRV.SYS +>>>>22 string >\056 %-.6s +>4 uleshort&0x8000 0x0000 # 32 bit sector addressing ( > 32 MB) for block devices >>4 uleshort&0x0002 0x0002 \b,32-bit sector- # support by driver functions 13h, 17h, 18h @@ -384,33 +390,42 @@ # open, close, removable media support by driver functions 0Dh, 0Eh, 0Fh >4 uleshort&0x0800 0x0800 \b,close media- # output until busy support by int 10h for character device driver ->4 uleshort&0x8000 0x8000 +>4 uleshort&0x8000 0x8000 >>4 uleshort&0x2000 0x2000 \b,until busy- # direct read/write support by driver functions 03h,0Ch >4 uleshort&0x4000 0x4000 \b,control strings- ->4 uleshort&0x8000 0x8000 +>4 uleshort&0x8000 0x8000 >>4 uleshort&0x6840 >0 \bsupport ->4 uleshort&0x8000 0x0000 +>4 uleshort&0x8000 0x0000 >>4 uleshort&0x4842 >0 \bsupport >0 ubyte x \b) -# DOS driver cmd640x.sys has 0x12 instead of 0xffffffff for pointer field to next device header -# Too weak, matches files that only contain 0's -#0 ulequad&0x000007a0ffffffed 0x0000000000000000 DOS-executable ( -#>4 uleshort&0x8000 0x8000 \bcharacter device driver -#>>10 string x %-.8s -#>4 uleshort&0x4000 0x4000 \b,control strings-support) +# DOS driver cmd640x.sys has 0x12 instead of 0xffffffff for pointer field to next device header +0 ulequad 0x0513c00000000012 +>0 use msdos-driver +# DOS drivers DC2975.SYS, DUMBDRV.SYS, ECHO.SYS has also none 0xffffffff for pointer field +0 ulequad 0x32f28000ffff0016 +>0 use msdos-driver +0 ulequad 0x007f00000000ffff +>0 use msdos-driver +0 ulequad 0x001600000000ffff +>0 use msdos-driver +# DOS drivers LS120.SYS, MKELS120.SYS use reserved bits of attribute field +0 ulequad 0x0bf708c2ffffffff +>0 use msdos-driver +0 ulequad 0x07bd08c2ffffffff +>0 use msdos-driver # updated by Joerg Jenderek -# GRR: line below too general as it catches also +# GRR: line below too general as it catches also # rt.lib DYADISKS.PIC and many more # start with assembler instruction MOV -0 ubyte 0x8c +0 ubyte 0x8c # skip "AppleWorks word processor data" like ARTICLE.1 ./apple ->4 string !O==== +>4 string !O==== # skip some unknown basic binaries like RocketRnger.SHR ->>5 string !MAIN +>>5 string !MAIN # skip "GPG symmetrically encrypted data" ./gnu -# skip "PGP symmetric key encrypted data" ./pgp +# skip "PGP symmetric key encrypted data" ./pgp # openpgpdefs.h: fourth byte < 14 indicate cipher algorithm type >>>4 ubyte >13 DOS executable (COM, 0x8C-variant) # the remaining files should be DOS *.COM executables @@ -428,7 +443,7 @@ # updated by Joerg Jenderek at Oct 2008 0 ulelong 0xffff10eb DR-DOS executable (COM) # byte 0xeb conflicts with "sequent" magic leshort 0xn2eb -0 ubeshort&0xeb8d >0xeb00 +0 ubeshort&0xeb8d >0xeb00 # DR-DOS STACKER.COM SCREATE.SYS missed 0 name msdos-com @@ -463,9 +478,9 @@ # updated by Joerg Jenderek at Oct 2008,2015 # following line is too general -0 ubyte 0xb8 +0 ubyte 0xb8 # skip 2 linux kernels like memtest.bin with "\xb8\xc0\x07\x8e" in ./linux ->0 string !\xb8\xc0\x07\x8e +>0 string !\xb8\xc0\x07\x8e # modified by Joerg Jenderek # syslinux COM32 or COM32R executable >>1 lelong&0xFFFFFFFe 0x21CD4CFe COM executable (32-bit COMBOOT @@ -496,8 +511,8 @@ #!:mime application/x-msdos-program !:ext com -0 string/b \x81\xfc ->4 string \x77\x02\xcd\x20\xb9 +0 string/b \x81\xfc +>4 string \x77\x02\xcd\x20\xb9 >>36 string UPX! FREE-DOS executable (COM), UPX compressed 252 string Must\ have\ DOS\ version DR-DOS executable (COM) # added by Joerg Jenderek at Oct 2008 @@ -514,10 +529,10 @@ #IFMEMDSK.cOM ASSIGN.cOM COMP.cOM 5 string \xcd\x21 COM executable for DOS #DELTMP.COm HASFAT32.cOM -7 string \xcd\x21 +7 string \xcd\x21 >0 byte !0xb8 COM executable for DOS #COMP.cOM MORE.COm -10 string \xcd\x21 +10 string \xcd\x21 >5 string !\xcd\x21 COM executable for DOS #comecho.com 13 string \xcd\x21 COM executable for DOS @@ -565,10 +580,23 @@ 0 string/b PO^Q` Microsoft Word 6.0 Document !:mime application/msword # -0 string/b \376\067\0\043 Microsoft Office Document +4 long 0 +>0 belong 0xfe320000 Microsoft Word for Macintosh 1.0 !:mime application/msword -0 string/b \333\245-\0\0\0 Microsoft Office Document +!:ext mcw +>0 belong 0xfe340000 Microsoft Word for Macintosh 3.0 !:mime application/msword +!:ext mcw +>0 belong 0xfe37001c Microsoft Word for Macintosh 4.0 +!:mime application/msword +!:ext mcw +>0 belong 0xfe370023 Microsoft Word for Macintosh 5.0 +!:mime application/msword +!:ext mcw + +0 string/b \333\245-\0\0\0 Microsoft Word 2.0 Document +!:mime application/msword +!:ext doc 512 string/b \354\245\301 Microsoft Word Document !:mime application/msword @@ -599,11 +627,11 @@ # Reference: http://www.aboutvb.de/bas/formate/pdf/wk3.pdf # Note: newer Lotus versions >2 use longer BOF record # record type (BeginningOfFile=0000h) + length (001Ah) -0 belong 0x00001a00 +0 belong 0x00001a00 # reserved should be 0h but 8c0dh for TUTMAC.WK3, 5h for SAMPADNS.WK3, 1h for a_readme.wk3, 1eh for K&G86.WK3 -#>18 uleshort&0x73E0 0 +#>18 uleshort&0x73E0 0 # Lotus Multi Byte Character Set (LMBCS=1-31) ->20 ubyte >0 +>20 ubyte >0 >>20 ubyte <32 Lotus 1-2-3 #!:mime application/x-123 !:mime application/vnd.lotus-1-2-3 @@ -640,10 +668,10 @@ !:ext fXX # main revision number >>>>4 uleshort x \b, revision 0x%x ->>>6 uleshort =0x0004 \b, cell range +>>>6 uleshort =0x0004 \b, cell range # active cellcoord range (start row, page,column ; end row, page, column) # start values normally 0~1st sheet A1 ->>>>8 ulelong !0 +>>>>8 ulelong !0 >>>>>10 ubyte >0 \b%d* >>>>>8 uleshort x \b%d, >>>>>11 ubyte x \b%d- @@ -656,9 +684,9 @@ >>>>20 ubyte >1 \b, character set 0x%x # flags >>>>21 ubyte x \b, flags 0x%x ->>>6 uleshort !0x0004 +>>>6 uleshort !0x0004 # record type (FONTNAME=00AEh) ->>>>30 search/29 \0\xAE +>>>>30 search/29 \0\xAE # variable length m (2) + entries (1) + ?? (1) + LCMBS string (n) >>>>>&4 string >\0 \b, 1st font "%s" # @@ -667,12 +695,12 @@ # Reference: http://www.schnarff.com/file-formats/lotus-1-2-3/WSFF2.TXT # Note: Used by both old Lotus 1-2-3 and Lotus Symphony (DOS) til version 2.x # record type (BeginningOfFile=0000h) + length (0002h) -0 belong 0x00000200 +0 belong 0x00000200 # GRR: line above is too general as it catches also MS Windows CURsor # to display MS Windows cursor (strength=70) before Lotus 1-2-3 (strength=70-1) !:strength -1 # skip Windows cursors with image height <256 and keep Lotus with low opcode 0001-0083h ->7 ubyte 0 +>7 ubyte 0 # skip Windows cursors with image width 256 and keep Lotus with positiv opcode >>6 ubyte >0 Lotus # !:mime application/x-123 @@ -737,9 +765,9 @@ # check and then display Lotus worksheet cells range 0 name lotus-cells # look for type (RANGE=0006h) + length (0008h) at record begin ->0 ubelong 0x06000800 \b, cell range +>0 ubelong 0x06000800 \b, cell range # cell range (start column, row, end column, row) start values normally 0,0~A1 cell ->>4 ulong !0 +>>4 ulong !0 >>>4 uleshort x \b%d, >>>6 uleshort x \b%d- # end of cell range @@ -792,19 +820,19 @@ # Windows icons # Update: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/CUR_(file_format) -# Note: similiar to Windows CURsor. container for BMP (only DIB part) or PNG +# Note: similar to Windows CURsor. container for BMP (only DIB part) or PNG 0 belong 0x00000100 >9 byte 0 ->>0 byte x +>>0 byte x >>0 use cur-ico-dir >9 ubyte 0xff ->>0 byte x +>>0 byte x >>0 use cur-ico-dir # displays number of icons and information for icon or cursor 0 name cur-ico-dir # skip some Lotus 1-2-3 worksheets, CYCLE.PIC and keep Windows cursors with # 1st data offset = dir header size + n * dir entry size = 6 + n * 10h = ?6h ->18 ulelong &0x00000006 +>18 ulelong &0x00000006 # skip remaining worksheets, because valid only for DIB image (40) or PNG image (\x89PNG) >>(18.l) ulelong x MS Windows >>>0 ubelong 0x00000100 icon resource @@ -817,7 +845,7 @@ # 1st icon >>>>0x06 use ico-entry # 2nd icon ->>>>4 uleshort >1 +>>>>4 uleshort >1 >>>>>0x16 use ico-entry >>>0 ubelong 0x00000200 cursor resource #!:mime image/x-cur @@ -854,16 +882,16 @@ # offset of PNG or DIB image #>12 ulelong x \b, offset 0x%x # PNG header (\x89PNG) ->(12.l) ubelong =0x89504e47 ->>&-4 indirect x \b with +>(12.l) ubelong =0x89504e47 +>>&-4 indirect x \b with # DIB image ->(12.l) ubelong !0x89504e47 +>(12.l) ubelong !0x89504e47 #>>&-4 use dib-image # Windows non-animated cursors # Update: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/CUR_(file_format) -# Note: similiar to Windows ICOn. container for BMP ( only DIB part) +# Note: similar to Windows ICOn. container for BMP ( only DIB part) # GRR: line below is too general as it catches also Lotus 1-2-3 files 0 belong 0x00000200 >9 byte 0 @@ -872,13 +900,13 @@ >>0 use cur-ico-dir # .chr files -0 string/b PK\010\010BGI Borland font +0 string/b PK\010\010BGI Borland font >4 string >\0 %s # then there is a copyright notice # .bgi files -0 string/b pk\010\010BGI Borland device +0 string/b pk\010\010BGI Borland device >4 string >\0 %s # then there is a copyright notice @@ -909,7 +937,7 @@ 0 lelong 0x08086b70 TurboC BGI file 0 lelong 0x08084b50 TurboC Font file -# Debian#712046: The magic below identifies "Delphi compiled form data". +# Debian#712046: The magic below identifies "Delphi compiled form data". # An additional source of information is available at: # http://www.woodmann.com/fravia/dafix_t1.htm 0 string TPF0 @@ -918,7 +946,7 @@ # tests for DBase files moved, updated and merged to database 0 string PMCC Windows 3.x .GRP file -1 string RDC-meg MegaDots +1 string RDC-meg MegaDots >8 byte >0x2F version %c >9 byte >0x2F \b.%c file 0 lelong 0x4C @@ -935,16 +963,16 @@ #>0x181 leshort x \b, offset %x #>0x183 leshort x \b, offsetdata %x #>0x185 leshort x \b, section length %x ->0x187 search/0xB55 WINDOWS\ VMM\ 4.0\0 ->>&0x5e ubyte >0 +>0x187 search/0xB55 WINDOWS\ VMM\ 4.0\0 +>>&0x5e ubyte >0 >>>&-1 string >>&-1 string PIFMGR.DLL \b, icon=%s >>>&-1 string >PIFMGR.DLL \b, icon=%s ->>&0xF0 ubyte >0 +>>&0xF0 ubyte >0 >>>&-1 string >>&-1 string =Terminal \b, font=%.32s >>>&-1 string >Terminal \b, font=%.32s ->>&0x110 ubyte >0 +>>&0x110 ubyte >0 >>>&-1 string >>&-1 string =Lucida\ Console \b, TrueTypeFont=%.32s >>>&-1 string >Lucida\ Console \b, TrueTypeFont=%.32s @@ -960,6 +988,7 @@ # DOS EPS Binary File Header # From: Ed Sznyter 0 belong 0xC5D0D3C6 DOS EPS Binary File +!:mime image/x-eps >4 long >0 Postscript starts at byte %d >>8 long >0 length %d >>>12 long >0 Metafile starts at byte %d @@ -967,15 +996,15 @@ >>>20 long >0 TIFF starts at byte %d >>>>24 long >0 length %d -# TNEF magic From "Joomy" +# TNEF magic From "Joomy" # Microsoft Outlook's Transport Neutral Encapsulation Format (TNEF) -0 leshort 0x223e9f78 TNEF +0 lelong 0x223e9f78 TNEF !:mime application/vnd.ms-tnef # Norton Guide (.NG , .HLP) files added by Joerg Jenderek from source NG2HTML.C # of http://www.davep.org/norton-guides/ng2h-105.tgz # http://en.wikipedia.org/wiki/Norton_Guides -0 string NG\0\001 +0 string NG\0\001 # only value 0x100 found at offset 2 >2 ulelong 0x00000100 Norton Guide # Title[40] @@ -985,7 +1014,7 @@ >>48 string >\0 \b, %-.66s >>114 string >\0 %-.66s -# 4DOS help (.HLP) files added by Joerg Jenderek from source TPHELP.PAS +# 4DOS help (.HLP) files added by Joerg Jenderek from source TPHELP.PAS # of http://www.4dos.info/ # pointer,HelpID[8]=4DHnnnmm 0 ulelong 0x48443408 4DOS help file @@ -1033,7 +1062,7 @@ # Windows Enhanced Metafile (EMF) -# See msdn.microsoft.com/archive/en-us/dnargdi/html/msdn_enhmeta.asp +# See msdn.microsoft.com/archive/en-us/dnargdi/html/msdn_enhmeta.asp # for further information. 0 ulelong 1 >40 string \ EMF Windows Enhanced Metafile (EMF) image data @@ -1095,7 +1124,7 @@ 0 string/b MSWIM\000\000\000 Windows imaging (WIM) image 0 string/b WLPWM\000\000\000 Windows imaging (WIM) image, wimlib pipable format -# The second byte of these signatures is a file version; I don't know what, +# The second byte of these signatures is a file version; I don't know what, # if anything, produced files with version numbers 0-2. # From: John Elliott 0 string \xfc\x03\x00 Mallard BASIC program data (v1.11) @@ -1106,3 +1135,66 @@ 0 string MIOPEN Mallard BASIC Jetsam data 0 string Jetsam0 Mallard BASIC Jetsam index data +# DOS backup 2.0 to 3.2 + +# backupid.@@@ + +# plausibility check for date +0x3 ushort >1979 +>0x5 ubyte-1 <31 +>>0x6 ubyte-1 <12 +# actually 121 nul bytes +>>>0x7 string \0\0\0\0\0\0\0\0 +>>>>0x1 ubyte x DOS 2.0 backup id file, sequence %d +!:ext @@@ +>>>>0x0 ubyte 0xff \b, last disk + +# backed up file + +# skip some AppleWorks word like Tomahawk.Awp, WIN98SE-DE.vhd +# by looking for trailing nul of maximal file name string +0x52 ubyte 0 +# test for flag byte: FFh~complete file, 00h~split file +# FFh -127 = -1 -127 = -128 +# 00h -127 = 0 -127 = -127 +>0 byte-127 <-126 +# plausibility check for file name length +>>0x53 ubyte-1 <78 +# looking for terminating nul of file name string +>>>(0x53.b+4) ubyte 0 +# looking if last char of string is valid DOS file name +>>>>(0x53.b+3) ubyte >0x1F +# actually 44 nul bytes +# but sometimes garbage according to Ralf Quint. So can not be used as test +#>0x54 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 +# first char of full file name is DOS (5Ch) or UNIX (2Fh) path separator +# only DOS variant found. UNIX variant according to V32SLASH.TXT in archive PD0315.EXE +>>>>>5 ubyte&0x8C 0x0C +# ./msdos (version 5.30) labeled the entry as +# "DOS 2.0 backed up file %s, split file, sequence %d" or +# "DOS 2.0 backed up file %s, complete file" +>>>>>>0 ubyte x DOS 2.0-3.2 backed up +#>>>>>>0 ubyte 0xff complete +>>>>>>0 ubyte 0 +>>>>>>>1 uleshort x sequence %d of +# full file name with path but without drive letter and colon stored from 0x05 til 0x52 +>>>>>>0x5 string x file %s +# backup name is original filename +#!:ext * +# magic/Magdir/msdos, 1169: Warning: EXTENSION type ` *' has bad char '*' +# file: line 1169: Bad magic entry ' *' +# after header original file content +>>>>>>128 indirect x \b; + + +# DOS backup 3.3 to 5.x + +# CONTROL.nnn files +0 string \x8bBACKUP\x20 +# actually 128 nul bytes +>0xa string \0\0\0\0\0\0\0\0 +>>0x9 ubyte x DOS 3.3 backup control file, sequence %d +>>0x8a ubyte 0xff \b, last disk + +# NB: The BACKUP.nnn files consist of the files backed up, +# concatenated. diff --git a/contrib/file/magic/Magdir/msvc b/contrib/file/magic/Magdir/msvc index bf4ab0ca6147..13f847fbb20e 100644 --- a/contrib/file/magic/Magdir/msvc +++ b/contrib/file/magic/Magdir/msvc @@ -1,10 +1,10 @@ #------------------------------------------------------------------------------ -# $File: msvc,v 1.6 2016/01/26 00:03:19 christos Exp $ +# $File: msvc,v 1.9 2017/08/02 08:15:20 christos Exp $ # msvc: file(1) magic for msvc # "H. Nanosecond" # Microsoft visual C -# +# # I have version 1.0 # .aps @@ -30,10 +30,10 @@ # Summary: Symbol Table / Debug info used by Microsoft compilers # URL: https://en.wikipedia.org/wiki/Program_database # Reference: https://code.google.com/p/pdbparser/wiki/MSF_Format -# Update: Joerg Jenderek +# Update: Joerg Jenderek # Note: test only for Windows XP+SP3 x86 , 8.1 x64 arm and 10.1 x86 # info does only applies partly for older files like msvbvm50.pdb about year 2001 -0 string Microsoft\ C/C++\ +0 string Microsoft\ C/C++\040 # "Microsoft Program DataBase" by TrID >24 search/14 \r\n\x1A MSVC program database !:mime application/x-ms-pdb @@ -42,18 +42,21 @@ >>16 regex \([0-9.]+\) ver %s #>>>0x38 search/128123456 /LinkInfo \b with linkinfo # "MSF 7.00" variant ->>0x1e leshort 0 +>>0x1e leshort 0 # PageSize 400h 1000h >>>0x20 lelong x \b, %d # Page Count >>>0x28 lelong x \b*%d bytes # "program database 2.00" variant ->>0x1e leshort !0 +>>0x1e leshort !0 # PageSize 400h >>>0x2c lelong x \b, %d # Page Count for msoo-dll.pdb 4379h >>>0x32 leshort x \b*%d bytes +# Reference: https://github.com/Microsoft/vstest/pull/856/commits/fdc7a9f074ca5a8dfeec83b1be9162bf0cf4000d +0 string/c bsjb\001\000\001\000\000\000\000\000\f\000\000\000pdb\ v1.0 Microsoft Rosyln C# debugging symbols version 1.0 + #.sbr 0 string \000\002\000\007\000 MSVC .sbr >5 string >\0 %s diff --git a/contrib/file/magic/Magdir/msx b/contrib/file/magic/Magdir/msx index ef2a7bb29891..69df6416fe7c 100644 --- a/contrib/file/magic/Magdir/msx +++ b/contrib/file/magic/Magdir/msx @@ -7,7 +7,7 @@ ############## MSX Music file formats ############## # Gigamix MGSDRV music file -0 string/b MGS MSX Gigamix MGSDRV3 music file, +0 string/b MGS MSX Gigamix MGSDRV3 music file, >6 ubeshort 0x0D0A >>3 byte x \bv%c >>4 byte x \b.%c @@ -35,7 +35,7 @@ >>0xF byte&0x02 0 \b, soundchips: AY-3-8910, SCC(+) >>0xF byte&0x02 0x02 \b, soundchips: SN76489 >>>0xF byte&0x04 0x04 stereo ->>0xF byte&0x01 0x01 \b, +>>0xF byte&0x01 0x01 \b, >>>0xF byte&0x18 0x00 \bYM2413 >>>0xF byte&0x18 0x08 \bYM2413, Y8950 >>>0xF byte&0x18 0x18 \bYM2413+Y8950 pseudostereo @@ -245,18 +245,18 @@ 0x4000 string/b AB >0x4002 uleshort >0x400F >>0x400A string \0\0\0\0\0\0 MSX ROM with nonstandard page order ->>0x4002 uleshort x \b, init=0x%04x ->>0x4004 uleshort >0 \b, stahdl=0x%04x ->>0x4006 uleshort >0 \b, devhdl=0x%04x ->>0x4008 uleshort >0 \b, bas=0x%04x +>>>0x4002 uleshort x \b, init=0x%04x +>>>0x4004 uleshort >0 \b, stahdl=0x%04x +>>>0x4006 uleshort >0 \b, devhdl=0x%04x +>>>0x4008 uleshort >0 \b, bas=0x%04x 0x8000 string/b AB >0x8002 uleshort >0x400F >>0x800A string \0\0\0\0\0\0 MSX ROM with nonstandard page order ->>0x8002 uleshort x \b, init=0x%04x ->>0x8004 uleshort >0 \b, stahdl=0x%04x ->>0x8006 uleshort >0 \b, devhdl=0x%04x ->>0x8008 uleshort >0 \b, bas=0x%04x +>>>0x8002 uleshort x \b, init=0x%04x +>>>0x8004 uleshort >0 \b, stahdl=0x%04x +>>>0x8006 uleshort >0 \b, devhdl=0x%04x +>>>0x8008 uleshort >0 \b, bas=0x%04x 0x3C000 string/b AB @@ -296,7 +296,7 @@ 4 uleshort 0x0900 >0xF byte 1 >>0x14 byte 0 ->>>0x1E string \ \ \ +>>>0x1E string \040\040\040 >>>>0x23 byte 1 >>>>>0x25 byte 0 >>>>>>0x15 string >\x30 diff --git a/contrib/file/magic/Magdir/mup b/contrib/file/magic/Magdir/mup index 5060c01dd8bf..05b9471b0755 100644 --- a/contrib/file/magic/Magdir/mup +++ b/contrib/file/magic/Magdir/mup @@ -1,6 +1,6 @@ # ------------------------------------------------------------------------ -# $File: mup,v 1.4 2009/09/19 16:28:11 christos Exp $ +# $File: mup,v 1.5 2017/03/17 21:35:28 christos Exp $ # mup: file(1) magic for Mup (Music Publisher) input file. # # From: Abel Cheung @@ -12,13 +12,13 @@ # 0 search/1 //!Mup Mup music publication program input text >6 string -Arkkra (Arkkra) ->>13 string - ->>>16 string . +>>13 string - +>>>16 string . >>>>14 string x \b, need V%.4s ->>>15 string . +>>>15 string . >>>>14 string x \b, need V%.3s ->6 string - ->>9 string . +>6 string - +>>9 string . >>>7 string x \b, need V%.4s ->>8 string . +>>8 string . >>>7 string x \b, need V%.3s diff --git a/contrib/file/magic/Magdir/nasa b/contrib/file/magic/Magdir/nasa index 49673b32fb99..de3545f80800 100644 --- a/contrib/file/magic/Magdir/nasa +++ b/contrib/file/magic/Magdir/nasa @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# nasa: file(1) magic +# nasa: file(1) magic # From: Barry Carter 0 string DAF/SPK NASA SPICE file (binary format) diff --git a/contrib/file/magic/Magdir/netbsd b/contrib/file/magic/Magdir/netbsd index eb0847b67de4..5ee2d712d05f 100644 --- a/contrib/file/magic/Magdir/netbsd +++ b/contrib/file/magic/Magdir/netbsd @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: netbsd,v 1.23 2015/11/29 01:55:14 christos Exp $ +# $File: netbsd,v 1.24 2017/03/17 21:35:28 christos Exp $ # netbsd: file(1) magic for NetBSD objects # # All new-style magic numbers are in network byte order. @@ -10,7 +10,7 @@ # 0 belong&0377777777 041400413 a.out NetBSD/i386 demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 lelong <4096 shared library >>20 lelong =4096 dynamically linked executable >>20 lelong >4096 dynamically linked executable @@ -32,7 +32,7 @@ >32 lelong !0 (signal %d) 0 belong&0377777777 041600413 a.out NetBSD/m68k demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 belong <8192 shared library >>20 belong =8192 dynamically linked executable >>20 belong >8192 dynamically linked executable @@ -54,7 +54,7 @@ >32 belong !0 (signal %d) 0 belong&0377777777 042000413 a.out NetBSD/m68k4k demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 belong <4096 shared library >>20 belong =4096 dynamically linked executable >>20 belong >4096 dynamically linked executable @@ -76,7 +76,7 @@ >32 belong !0 (signal %d) 0 belong&0377777777 042200413 a.out NetBSD/ns32532 demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 lelong <4096 shared library >>20 lelong =4096 dynamically linked executable >>20 lelong >4096 dynamically linked executable @@ -101,7 +101,7 @@ >12 string >\0 from '%s' 0 belong&0377777777 042400413 a.out NetBSD/SPARC demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 belong <8192 shared library >>20 belong =8192 dynamically linked executable >>20 belong >8192 dynamically linked executable @@ -123,7 +123,7 @@ >32 belong !0 (signal %d) 0 belong&0377777777 042600413 a.out NetBSD/pmax demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 lelong <4096 shared library >>20 lelong =4096 dynamically linked executable >>20 lelong >4096 dynamically linked executable @@ -145,7 +145,7 @@ >32 lelong !0 (signal %d) 0 belong&0377777777 043000413 a.out NetBSD/vax 1k demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 lelong <4096 shared library >>20 lelong =4096 dynamically linked executable >>20 lelong >4096 dynamically linked executable @@ -167,7 +167,7 @@ >32 lelong !0 (signal %d) 0 belong&0377777777 045400413 a.out NetBSD/vax 4k demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 lelong <4096 shared library >>20 lelong =4096 dynamically linked executable >>20 lelong >4096 dynamically linked executable @@ -189,7 +189,7 @@ >32 lelong !0 (signal %d) # NetBSD/alpha does not support (and has never supported) a.out objects, -# so no rules are provided for them. NetBSD/alpha ELF objects are +# so no rules are provided for them. NetBSD/alpha ELF objects are # dealt with in "elf". 0 lelong 0x00070185 ECOFF NetBSD/alpha binary >10 leshort 0x0001 not stripped @@ -199,7 +199,7 @@ >32 lelong !0 (signal %d) 0 belong&0377777777 043400413 a.out NetBSD/mips demand paged ->0 byte &0x80 +>0 byte &0x80 >>20 belong <8192 shared library >>20 belong =8192 dynamically linked executable >>20 belong >8192 dynamically linked executable diff --git a/contrib/file/magic/Magdir/netscape b/contrib/file/magic/Magdir/netscape index a9b43cdd5f1d..0e1ca61334cf 100644 --- a/contrib/file/magic/Magdir/netscape +++ b/contrib/file/magic/Magdir/netscape @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: netscape,v 1.7 2015/08/24 05:20:52 christos Exp $ +# $File: netscape,v 1.8 2017/03/17 21:35:28 christos Exp $ # netscape: file(1) magic for Netscape files # "H. Nanosecond" # version 3 and 4 I think @@ -15,8 +15,8 @@ # .snm Caches 0 string #\ Netscape\ folder\ cache Netscape folder cache 0 string \000\036\204\220\000 Netscape folder cache -# .n2p -# Net 2 Phone +# .n2p +# Net 2 Phone #0 string 123\130\071\066\061\071\071\071\060\070\061\060\061\063\060 0 string SX961999 Net2phone diff --git a/contrib/file/magic/Magdir/nitpicker b/contrib/file/magic/Magdir/nitpicker index 2486dee037f4..48c3d63a288a 100644 --- a/contrib/file/magic/Magdir/nitpicker +++ b/contrib/file/magic/Magdir/nitpicker @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# $File: nitpicker,v 1.6 2014/04/30 21:41:02 christos Exp $ +# $File: nitpicker,v 1.7 2017/03/17 21:35:28 christos Exp $ # nitpicker: file(1) magic for Flowfiles. # From: Christian Jachmann http://www.nitpicker.de -0 string NPFF NItpicker Flow File +0 string NPFF NItpicker Flow File >4 byte x V%d. >5 byte x %d >6 bedate x started: %s diff --git a/contrib/file/magic/Magdir/os2 b/contrib/file/magic/Magdir/os2 index 21c1c0019dfd..ace69cb34b23 100644 --- a/contrib/file/magic/Magdir/os2 +++ b/contrib/file/magic/Magdir/os2 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: os2,v 1.9 2016/05/11 15:51:57 christos Exp $ +# $File: os2,v 1.10 2017/03/17 21:35:28 christos Exp $ # os2: file(1) magic for OS/2 files # @@ -25,7 +25,7 @@ #>5 string >\ (Local file) <%s> # >>>>> OS/2 INF/HLP <<<<< (source: Daniel Dissett ddissett@netcom.com) -# Carl Hauser (chauser.parc@xerox.com) and +# Carl Hauser (chauser.parc@xerox.com) and # Marcus Groeber (marcusg@ph-cip.uni-koeln.de) # list the following header format in inf02a.doc: # @@ -35,11 +35,11 @@ # // bit 0: set if INF style file # // bit 4: set if HLP style file # // patching this byte allows reading HLP files -# // using the VIEW command, while help files +# // using the VIEW command, while help files # // seem to work with INF settings here as well. # int16 hdrsize; // total size of header # int16 unknown2; // unknown purpose -# +# 0 string HSP\x01\x9b\x00 OS/2 INF >107 string >0 (%s) 0 string HSP\x10\x9b\x00 OS/2 HLP diff --git a/contrib/file/magic/Magdir/os9 b/contrib/file/magic/Magdir/os9 index 52b04be3059c..74b47f358514 100644 --- a/contrib/file/magic/Magdir/os9 +++ b/contrib/file/magic/Magdir/os9 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: os9,v 1.7 2011/05/13 22:15:54 christos Exp $ +# $File: os9,v 1.8 2017/03/17 21:35:28 christos Exp $ # # Copyright (c) 1996 Ignatios Souvatzis. All rights reserved. # @@ -15,7 +15,7 @@ # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR 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; diff --git a/contrib/file/magic/Magdir/pbf b/contrib/file/magic/Magdir/pbf index d133d12bf621..8de6db025047 100644 --- a/contrib/file/magic/Magdir/pbf +++ b/contrib/file/magic/Magdir/pbf @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# $File: pbf,v 1.1 2013/12/21 14:27:24 christos Exp $ +# $File: pbf,v 1.2 2017/01/18 16:16:21 christos Exp $ # file(1) magic(5) data for OpenStreetMap # OpenStreetMap Protocolbuffer Binary Format (.osm.pbf) # http://wiki.openstreetmap.org/wiki/PBF_Format # From: Markus Heidelberg -0 belong 0x0000000D ->4 beshort 0x0A09 ->>6 string OSMHeader OpenStreetMap Protocolbuffer Binary Format +0 belong&0xfffffff0 0 +>4 beshort 0x0A09 +>>6 string OSMHeader OpenStreetMap Protocolbuffer Binary Format diff --git a/contrib/file/magic/Magdir/pc88 b/contrib/file/magic/Magdir/pc88 index e604a3b478ec..03822f50279f 100644 --- a/contrib/file/magic/Magdir/pc88 +++ b/contrib/file/magic/Magdir/pc88 @@ -9,7 +9,7 @@ >>0x280 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 >>>0x1A ubyte&0xEF 0 >>>>0x1B ubyte&0x8F 0 ->>>>>0x1B ubyte&70 <0x40 +>>>>>0x1B ubyte&70 <0x40 >>>>>>0x1C ulelong >0x21 >>>>>>>0 regex [[:print:]]* NEC PC-88 disk image, name=%s >>>>>>>>0x1B ubyte 0 \b, media=2D diff --git a/contrib/file/magic/Magdir/pc98 b/contrib/file/magic/Magdir/pc98 index 30f1ea386c46..3b995ed013d4 100644 --- a/contrib/file/magic/Magdir/pc98 +++ b/contrib/file/magic/Magdir/pc98 @@ -8,7 +8,7 @@ # http://www.jisyo.com/viewer/faq/maki_tech.htm 0 string/b MAKI01 Maki-chan v1. >6 ubyte|0x20 x \b%c image ->8 ubelong >0x40404040 \b, system ID: +>8 ubelong >0x40404040 \b, system ID: >>8 byte x %c >>9 byte x \b%c >>10 byte x \b%c diff --git a/contrib/file/magic/Magdir/pdf b/contrib/file/magic/Magdir/pdf index b43a675cec0c..04b564dd56b6 100644 --- a/contrib/file/magic/Magdir/pdf +++ b/contrib/file/magic/Magdir/pdf @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: pdf,v 1.8 2015/01/11 18:19:18 christos Exp $ +# $File: pdf,v 1.9 2017/05/24 17:35:20 christos Exp $ # pdf: file(1) magic for Portable Document Format # @@ -20,3 +20,8 @@ !:mime application/vnd.fdf >5 byte x \b, version %c >7 byte x \b.%c + +0 search/256 %PDF- PDF document +!:mime application/pdf +>&0 byte x \b, version %c +>&2 byte x \b.%c diff --git a/contrib/file/magic/Magdir/pdp b/contrib/file/magic/Magdir/pdp index 0afee0c9ba5c..2d18b62df595 100644 --- a/contrib/file/magic/Magdir/pdp +++ b/contrib/file/magic/Magdir/pdp @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: pdp,v 1.10 2014/04/30 21:41:02 christos Exp $ +# $File: pdp,v 1.11 2017/03/17 21:35:28 christos Exp $ # pdp: file(1) magic for PDP-11 executable/object and APL workspace # 0 lelong 0101555 PDP-11 single precision APL workspace @@ -14,8 +14,8 @@ # updated by Joerg Jenderek at Mar 2013 # GRR: line below too general as it catches also Windows precompiled setup information *.PNF -0 leshort 0401 -# skip *.PNF with WinDirPathOffset 58h +0 leshort 0401 +# skip *.PNF with WinDirPathOffset 58h >68 ulelong !0x00000058 PDP-11 UNIX/RT ldp # skip *.PNF with high byte of InfVersionDatumCount zero #>>15 byte !0 PDP-11 UNIX/RT ldp diff --git a/contrib/file/magic/Magdir/perl b/contrib/file/magic/Magdir/perl index 099a22d11298..c391d4a72036 100644 --- a/contrib/file/magic/Magdir/perl +++ b/contrib/file/magic/Magdir/perl @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: perl,v 1.25 2016/06/07 23:28:37 rrt Exp $ +# $File: perl,v 1.26 2017/02/21 18:34:55 christos Exp $ # perl: file(1) magic for Larry Wall's perl language. # # The `eval' lines recognizes an outrageously clever hack. @@ -33,14 +33,14 @@ # by Dmitry V. Levin and Alexey Tourbin # check the first line -0 search/1024 package +0 search/8192 package >0 regex \^package[\ \t]+[0-9A-Za-z_:]+\ *; Perl5 module source text -!:strength + 10 +!:strength + 40 # not 'p', check other lines -0 search/1024 !p +0 search/8192 !p >0 regex \^package[\ \t]+[0-9A-Za-z_:]+\ *; >>0 regex \^1\ *;|\^(use|sub|my)\ .*[(;{=] Perl5 module source text -!:strength + 10 +!:strength + 75 # Perl POD documents # From: Tom Hukins diff --git a/contrib/file/magic/Magdir/pgf b/contrib/file/magic/Magdir/pgf index 825f5f685690..b5a251efdf38 100644 --- a/contrib/file/magic/Magdir/pgf +++ b/contrib/file/magic/Magdir/pgf @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: pgf,v 1.1 2013/04/22 15:19:49 christos Exp $ +# $File: pgf,v 1.2 2017/03/17 21:35:28 christos Exp $ # pgf: file(1) magic for Progressive Graphics File (PGF) # # @@ -42,7 +42,7 @@ >>20 byte 19 RGB color 12, >>20 byte 20 RGB color 16, >>20 byte 255 unknown format, ->>20 default x format +>>20 default x format >>>20 byte x \b %d, >>21 byte x %d bpc # PGFPostHeader diff --git a/contrib/file/magic/Magdir/pgp b/contrib/file/magic/Magdir/pgp index 6e685fcfc979..585475dbb38c 100644 --- a/contrib/file/magic/Magdir/pgp +++ b/contrib/file/magic/Magdir/pgp @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: pgp,v 1.12 2016/10/07 20:22:12 christos Exp $ +# $File: pgp,v 1.14 2017/03/17 21:35:28 christos Exp $ # pgp: file(1) magic for Pretty Good Privacy # see http://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html # @@ -19,15 +19,15 @@ #>15 string SIGNED\040MESSAGE- signed message #>15 string PGP\040SIGNATURE- signature -2 string ---BEGIN\ PGP\ PUBLIC\ KEY\ BLOCK- PGP public key block +2 string ---BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK- PGP public key block !:mime application/pgp-keys >10 search/100 \n\n >>&0 use pgp -0 string -----BEGIN\040PGP\40MESSAGE- PGP message +0 string -----BEGIN\040PGP\040MESSAGE- PGP message !:mime application/pgp >10 search/100 \n\n >>&0 use pgp -0 string -----BEGIN\040PGP\40SIGNATURE- PGP signature +0 string -----BEGIN\040PGP\040SIGNATURE- PGP signature !:mime application/pgp-signature >10 search/100 \n\n >>&0 use pgp @@ -77,7 +77,7 @@ >0 byte 0x30 >>1 byte&0xc0 0x00 Unused [0%x] >>1 byte&0xc0 0x40 User Attribute ->>1 byte&0xc0 0x80 Sym. Encrypted and Integrity Protected Data +>>1 byte&0xc0 0x80 Sym. Encrypted and Integrity Protected Data >>1 byte&0xc0 0xc0 Modification Detection Code # magic signatures to detect PGP crypto material (from stef) @@ -206,7 +206,7 @@ >0 byte 19 ECDSA >0 byte 20 ElGamal (Encrypt or Sign) >0 byte 21 Diffie-Hellman ->0 default x +>0 default x >>0 ubyte <22 unknown (pub %d) # this should never happen >>0 ubyte >21 invalid (%d) @@ -482,16 +482,16 @@ >1 use pgpkey 0 byte 0x97 PGP Secret Sub-key - >1 use pgpkey -0 byte 0x9d +0 byte 0x9d # Update: Joerg Jenderek # secret subkey packet (tag 7) with same structure as secret key packet (tag 5) # skip Fetus.Sys16 CALIBUS.MAIN OrbFix.Sys16.Ex by looking for positive len ->1 ubeshort >0 +>1 ubeshort >0 #>1 ubeshort x \b, body length 0x%x # next packet type often 88h,89h~(tag 2)~Signature Packet #>>(1.S+3) ubyte x \b, next packet type 0x%x # skip Dragon.SHR DEMO.INIT by looking for positive version ->>3 ubyte >0 +>>3 ubyte >0 # skip BUISSON.13 GUITAR1 by looking for low version number >>>3 ubyte <5 PGP Secret Sub-key # sub-key are normally part of secret key. So it does not occur as standalone file @@ -500,7 +500,7 @@ >>>>3 ubyte x (v%d) >>>>3 ubyte x - # old versions 2 or 3 but no real example found ->>>>3 ubyte <4 +>>>>3 ubyte <4 # 2 byte for key bits in version 5.28 look >>>>>11 ubeshort x %db >>>>>4 beldate x created on %s - @@ -508,15 +508,15 @@ #>>>>>8 ubeshort x 0x%x # display key algorithm 1~RSA Encrypt|Sign - 21~Diffie-Hellman >>>>>10 use key_algo ->>>>>(11.S/8) ubequad x +>>>>>(11.S/8) ubequad x # look after first key >>>>>>&5 use keyend # new version ->>>>3 ubyte >3 +>>>>3 ubyte >3 >>>>>9 ubeshort x %db >>>>>4 beldate x created on %s - # display key algorithm >>>>>8 use key_algo ->>>>>(9.S/8) ubequad x +>>>>>(9.S/8) ubequad x # look after first key for something like s2k >>>>>>&3 use keyend diff --git a/contrib/file/magic/Magdir/printer b/contrib/file/magic/Magdir/printer index 10168266c924..98fc1dfaad42 100644 --- a/contrib/file/magic/Magdir/printer +++ b/contrib/file/magic/Magdir/printer @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: printer,v 1.26 2014/04/12 14:51:52 christos Exp $ +# $File: printer,v 1.28 2017/03/17 22:20:22 christos Exp $ # printer: file(1) magic for printer-formatted files # @@ -13,7 +13,7 @@ >>>15 string EPS \b, type %s >>>15 string Query \b, type %s >>>15 string ExitServer \b, type %s ->>>15 search/1000 %%LanguageLevel:\ +>>>15 search/1000 %%LanguageLevel:\040 >>>>&0 string >\0 \b, Level %s # Some PCs have the annoying habit of adding a ^D as a document separator 0 string \004%! PostScript document text @@ -24,7 +24,7 @@ >>>16 string EPS \b, type %s >>>16 string Query \b, type %s >>>16 string ExitServer \b, type %s ->>>16 search/1000 %%LanguageLevel:\ +>>>16 search/1000 %%LanguageLevel:\040 >>>>&0 string >\0 \b, Level %s 0 string \033%-12345X%!PS PostScript document @@ -49,18 +49,18 @@ # HP Printer Job Language 0 string \033%-12345X@PJL HP Printer Job Language data # HP Printer Job Language -# The header found on Win95 HP plot files is the "Silliest Thing possible" +# The header found on Win95 HP plot files is the "Silliest Thing possible" # (TM) # Every driver puts the language at some random position, with random case # (LANGUAGE and Language) # For example the LaserJet 5L driver puts the "PJL ENTER LANGUAGE" in line 10 # From: Uwe Bonnes -# +# 0 string \033%-12345X@PJL HP Printer Job Language data ->&0 string >\0 %s ->>&0 string >\0 %s ->>>&0 string >\0 %s ->>>>&0 string >\0 %s +>&0 string >\0 %s +>>&0 string >\0 %s +>>>&0 string >\0 %s +>>>>&0 string >\0 %s #>15 string \ ENTER\ LANGUAGE\ = #>31 string PostScript PostScript @@ -143,8 +143,8 @@ #------------------------------------------------------------------------------ # HP LaserJet 1000 series downloadable firmware file -0 string \xbe\xefABCDEFGH HP LaserJet 1000 series downloadable firmware +0 string \xbe\xefABCDEFGH HP LaserJet 1000 series downloadable firmware # From: Paolo -# Epson ESC/Page, ESC/PageColor +# Epson ESC/Page, ESC/PageColor 0 string \x1b\x01@EJL Epson ESC/Page language printer data diff --git a/contrib/file/magic/Magdir/project b/contrib/file/magic/Magdir/project index efa5d40f7afe..9180b57d63e5 100644 --- a/contrib/file/magic/Magdir/project +++ b/contrib/file/magic/Magdir/project @@ -1,8 +1,8 @@ #------------------------------------------------------------------------------ -# $File: project,v 1.4 2009/09/19 16:28:11 christos Exp $ +# $File: project,v 1.5 2017/03/17 21:35:28 christos Exp $ # project: file(1) magic for Project management -# +# # Magic strings for ftnchek project files. Alexander Mai 0 string FTNCHEK_\ P project file for ftnchek >10 string 1 version 2.7 diff --git a/contrib/file/magic/Magdir/psdbms b/contrib/file/magic/Magdir/psdbms index 1d218c0b8548..3eec965731a6 100644 --- a/contrib/file/magic/Magdir/psdbms +++ b/contrib/file/magic/Magdir/psdbms @@ -1,12 +1,12 @@ #------------------------------------------------------------------------------ -# $File: psdbms,v 1.7 2016/01/08 00:41:02 christos Exp $ +# $File: psdbms,v 1.8 2017/03/17 21:35:28 christos Exp $ # psdbms: file(1) magic for psdatabase # # Update: Joerg Jenderek # GRR: line below too general as it catches also some Panorama database *.pan , # AppleWorks word processor -0 belong&0xff00ffff 0x56000000 +0 belong&0xff00ffff 0x56000000 # assume version starts with digit >1 regex/s =^[0-9] ps database >>1 string >\0 version %s diff --git a/contrib/file/magic/Magdir/python b/contrib/file/magic/Magdir/python index 29dcc15a8519..f21ff659b453 100644 --- a/contrib/file/magic/Magdir/python +++ b/contrib/file/magic/Magdir/python @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: python,v 1.29 2016/07/27 09:42:16 rrt Exp $ +# $File: python,v 1.34 2017/08/14 07:40:38 christos Exp $ # python: file(1) magic for python # # Outlook puts """ too for urgent messages @@ -24,7 +24,11 @@ 0 belong 0x6c0c0d0a python 3.2 byte-compiled 0 belong 0x9e0c0d0a python 3.3 byte-compiled 0 belong 0xee0c0d0a python 3.4 byte-compiled -0 belong 0x160d0d0a python 3.5 byte-compiled +0 belong 0x160d0d0a python 3.5.1- byte-compiled +0 belong 0x170d0d0a python 3.5.2+ byte-compiled +0 belong 0x330d0d0a python 3.6 byte-compiled +0 belong 0x3e0d0d0a python 3.7 byte-compiled + 0 search/1/w #!\ /usr/bin/python Python script text executable !:strength + 15 @@ -41,12 +45,25 @@ # from module.submodule import func1, func2 -0 regex \^from\\s+(\\w|\\.)+\\s+import.*$ Python script text executable +0 regex \^from[\040\t\f\r\n]+([A-Za-z0-9_]|\\.)+[\040\t\f\r\n]+import.*$ Python script text executable +!:strength + 15 !:mime text/x-python # def __init__ (self, ...): 0 search/4096 def\ __init__ >&0 search/64 self Python script text executable +!:strength + 15 +!:mime text/x-python + +# if __name__ == "__main__": +0 search/4096 if\ __name__ +>&0 search/64 '__main__' Python script text executable +>&0 search/64 "__main__" Python script text executable +!:strength + 15 +!:mime text/x-python + +# import module [as abrev] +0 regex \^import\ [_[:alpha:]]+\ as\ [[:alpha:]][[:space:]]*$ Python script text executable !:mime text/x-python # comments @@ -62,12 +79,19 @@ # except: or finally: # block 0 search/4096 try: ->&0 regex \^\\s*except.*: Python script text executable +>&0 regex \^[[:space:]]*except.*:$ Python script text executable +!:strength + 15 !:mime text/x-python >&0 search/4096 finally: Python script text executable !:mime text/x-python -# def name(args, args): -0 regex \^(\ |\\t){0,50}def\ {1,50}[a-zA-Z]{1,100} ->&0 regex \ {0,50}\\(([a-zA-Z]|,|\ ){1,255}\\):$ Python script text executable +# class name[(base classes,)]: [pass] +0 regex \^class\ [_[:alpha:]]+(\\(.*\\))?(\ )*:([\ \t]+pass)?$ Python script text executable +!:strength + 15 +!:mime text/x-python + +# def name(*args, **kwargs): +0 regex \^[[:space:]]{0,50}def\ {1,50}[_a-zA-Z]{1,100} +>&0 regex \\(([[:alpha:]*_,\ ]){0,255}\\):$ Python script text executable +!:strength + 15 !:mime text/x-python diff --git a/contrib/file/magic/Magdir/riff b/contrib/file/magic/Magdir/riff index 55cfb20b63f2..adf0fc9fb9ed 100644 --- a/contrib/file/magic/Magdir/riff +++ b/contrib/file/magic/Magdir/riff @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: riff,v 1.31 2015/02/14 17:30:03 christos Exp $ +# $File: riff,v 1.32 2017/03/17 21:35:28 christos Exp $ # riff: file(1) magic for RIFF format # See # @@ -75,7 +75,7 @@ >>18 leshort x \b, %d entries # RIFF Device Independent Bitmap format >8 string RDIB \b, device-independent bitmap ->>16 string BM +>>16 string BM >>>30 leshort 12 \b, OS/2 1.x format >>>>34 leshort x \b, %d x >>>>36 leshort x %d @@ -226,9 +226,9 @@ >8 string sfbk SoundFont/Bank # MPEG-1 wrapped in a RIFF, apparently >8 string CDXA \b, wrapped MPEG-1 (CDXA) ->8 string 4XMV \b, 4X Movie file +>8 string 4XMV \b, 4X Movie file # AMV-type AVI file: http://wiki.multimedia.cx/index.php?title=AMV ->8 string AMV\040 \b, AMV +>8 string AMV\040 \b, AMV >8 string WEBP \b, Web/P image !:mime image/webp >>12 use riff-walk @@ -246,7 +246,7 @@ >>18 beshort x \b, %d entries # RIFF Device Independent Bitmap format >8 string RDIB \b, device-independent bitmap ->>16 string BM +>>16 string BM >>>30 beshort 12 \b, OS/2 1.x format >>>>34 beshort x \b, %d x >>>>36 beshort x %d @@ -284,7 +284,7 @@ #------------------------------------------------------------------------------ # Sony Wave64 # see http://www.vcs.de/fileadmin/user_upload/MBS/PDF/Whitepaper/Informations_about_Sony_Wave64.pdf -# 128 bit RIFF-GUID { 66666972-912E-11CF-A5D6-28DB04C10000 } in little-endian +# 128 bit RIFF-GUID { 66666972-912E-11CF-A5D6-28DB04C10000 } in little-endian 0 string riff\x2E\x91\xCF\x11\xA5\xD6\x28\xDB\x04\xC1\x00\x00 Sony Wave64 RIFF data # 128 bit + total file size (64 bits) so 24 bytes # then WAVE-GUID { 65766177-ACF3-11D3-8CD1-00C04F8EDB8A } diff --git a/contrib/file/magic/Magdir/ruby b/contrib/file/magic/Magdir/ruby index cc3abd0408ae..45a253cb5f69 100644 --- a/contrib/file/magic/Magdir/ruby +++ b/contrib/file/magic/Magdir/ruby @@ -1,32 +1,51 @@ #------------------------------------------------------------------------------ -# $File: ruby,v 1.6 2016/07/27 09:46:29 rrt Exp $ +# $File: ruby,v 1.7 2017/08/14 13:39:18 christos Exp $ # ruby: file(1) magic for Ruby scripting language # URL: http://www.ruby-lang.org/ # From: Reuben Thomas # Ruby scripts -0 search/1/w #!\ /usr/bin/ruby Ruby script text executable +0 search/1/w #!\ /usr/bin/ruby Ruby script text executable !:strength + 15 !:mime text/x-ruby 0 search/1/w #!\ /usr/local/bin/ruby Ruby script text executable !:strength + 15 !:mime text/x-ruby -0 search/1 #!/usr/bin/env\ ruby Ruby script text executable +0 search/1 #!/usr/bin/env\ ruby Ruby script text executable !:strength + 15 !:mime text/x-ruby -0 search/1 #!\ /usr/bin/env\ ruby Ruby script text executable +0 search/1 #!\ /usr/bin/env\ ruby Ruby script text executable !:strength + 15 !:mime text/x-ruby # What looks like ruby, but does not have a shebang # (modules and such) # From: Lubomir Rintel -0 regex \^[\ \t]*require[\ \t]'[A-Za-z_/]+' ->0 regex include\ [A-Z]|def\ [a-z]|\ do$ ->>0 regex \^[\ \t]*end([\ \t]*[;#].*)?$ Ruby script text +0 regex \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+' +>0 regex def\ [a-z]|\ do$ +>>&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text +!:strength + 30 !:mime text/x-ruby -0 regex \^[\ \t]*(class|module)[\ \t][A-Z] +0 regex \^[[:space:]]*(class|module)[[:space:]][A-Z] >0 regex (modul|includ)e\ [A-Z]|def\ [a-z] ->>0 regex \^[\ \t]*end([\ \t]*[;#].*)?$ Ruby module source text +>>&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text +!:strength + 30 +!:mime text/x-ruby +# Classes with no modules or defs, beats simple ASCII +0 regex \^[[:space:]]*(class|module)[[:space:]][A-Z] +>&0 regex \^[[:space:]]*end([[:space:]]+[;#if].*)?$ Ruby script text +!:strength + 10 +!:mime text/x-ruby +# Looks for function definition to balance python magic +# def name (args) +# end +0 regex \^[[:space:]]*def\ [a-z]|def\ [[:alpha:]]+::[a-z] +>&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text +!:strength + 10 +!:mime text/x-ruby + +0 regex \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+' Ruby script text +!:mime text/x-ruby +0 regex \^[[:space:]]*include\ ([A-Z]+[a-z]*(::))+ Ruby script text !:mime text/x-ruby diff --git a/contrib/file/magic/Magdir/sccs b/contrib/file/magic/Magdir/sccs index 95b3a5db128d..4717948fdbfc 100644 --- a/contrib/file/magic/Magdir/sccs +++ b/contrib/file/magic/Magdir/sccs @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sccs,v 1.6 2009/09/19 16:28:12 christos Exp $ +# $File: sccs,v 1.7 2017/03/17 21:35:28 christos Exp $ # sccs: file(1) magic for SCCS archives # # SCCS archive structure: @@ -17,6 +17,6 @@ # Maybe we should just switch everybody from SCCS to RCS! # Further, you can't just say '\001h0', because the five-digit number # is a checksum that could (presumably) have any leading digit, -# and we don't have regular expression matching yet. +# and we don't have regular expression matching yet. # Hence the following official kludge: 8 string \001s\ SCCS archive data diff --git a/contrib/file/magic/Magdir/scientific b/contrib/file/magic/Magdir/scientific index e39720cf8784..2e0cf49bee74 100644 --- a/contrib/file/magic/Magdir/scientific +++ b/contrib/file/magic/Magdir/scientific @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ -# $File: scientific,v 1.10 2015/08/24 05:18:55 christos Exp $ -# scientific: file(1) magic for scientific formats +# $File: scientific,v 1.12 2017/03/17 22:20:22 christos Exp $ +# scientific: file(1) magic for scientific formats # # From: Joe Krahn @@ -90,7 +90,7 @@ # format DD-MMM-YY, e.g., 01-JAN-70, and the IDcode consists of numbers and # uppercase letters. However, examples have been seen without the date string, # e.g., the example on the chemime site. -0 string HEADER\ \ \ \ +0 string HEADER\ \ \ \040 >&0 regex/1l \^.{40} >>&0 regex/1l [0-9]{2}-[A-Z]{3}-[0-9]{2}\ {3} >>>&0 regex/1ls [A-Z0-9]{4}.{14}$ diff --git a/contrib/file/magic/Magdir/sendmail b/contrib/file/magic/Magdir/sendmail index 29004104d012..840859c56232 100644 --- a/contrib/file/magic/Magdir/sendmail +++ b/contrib/file/magic/Magdir/sendmail @@ -1,27 +1,27 @@ #------------------------------------------------------------------------------ -# $File: sendmail,v 1.8 2015/11/11 15:27:03 christos Exp $ +# $File: sendmail,v 1.10 2017/08/13 00:21:47 christos Exp $ # sendmail: file(1) magic for sendmail config files # # XXX - byte order? # -# Update: Joerg Jenderek +# Update: Joerg Jenderek # GRR: this test is too general as it catches also # READ.ME.FIRST.AWP Sendmail frozen configuration # - version ====|====|====|====|====|====|====|====|====|====|====|====|=== # Email_23_f217153422.ts Sendmail frozen configuration # - version \330jK\354 -0 byte 046 +0 byte 046 # http://www.sendmail.com/sm/open_source/docs/older_release_notes/ # freezed configuration file (dbm format?) created from sendmal.cf with -bz # by older sendmail. til version 8.6 support for frozen configuration files is removed -# valid version numbers look like "7.14.4" and should be simliar to output of commands -# "sendmail -d0 -bt < /dev/null |grep -i Version" or "egrep '^DZ' /etc/sendmail.cf" +# valid version numbers look like "7.14.4" and should be similar to output of commands +# "sendmail -d0 -bt < /dev/null |grep -i Version" or "egrep '^DZ' /etc/sendmail.cf" >16 regex/s =^[0-78][0-9.]{4} Sendmail frozen configuration # normally only /etc/sendmail.fc or /var/adm/sendmail/sendmail.fc !:ext fc >>16 string >\0 - version %s -0 short 0x271c +0 short 0x271c # look for valid version number >16 regex/s =^[0-78][0-9.]{4} Sendmail frozen configuration !:ext fc diff --git a/contrib/file/magic/Magdir/sequent b/contrib/file/magic/Magdir/sequent index 5137c0ed9af4..780d77e5d6ab 100644 --- a/contrib/file/magic/Magdir/sequent +++ b/contrib/file/magic/Magdir/sequent @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sequent,v 1.12 2014/08/16 16:07:12 christos Exp $ +# $File: sequent,v 1.13 2017/03/17 21:35:28 christos Exp $ # sequent: file(1) magic for Sequent machines # # Sequent information updated by Don Dwiggins . @@ -33,9 +33,9 @@ # http://en.wikipedia.org/wiki/Sequent_Computer_Systems # below test line conflicts with MS-DOS 2.11 floppies and Acronis loader #0 leshort 0x42eb SYMMETRY i386 standalone executable -0 leshort 0x42eb +0 leshort 0x42eb # skip unlike negative version ->124 lelong >-1 +>124 lelong >-1 # assuming version 28867614 is very low probable >>124 lelong !28867614 SYMMETRY i386 standalone executable >>>16 lelong >0 not stripped diff --git a/contrib/file/magic/Magdir/sgml b/contrib/file/magic/Magdir/sgml index e3dcc26c89b7..34edd3c30cdc 100644 --- a/contrib/file/magic/Magdir/sgml +++ b/contrib/file/magic/Magdir/sgml @@ -1,8 +1,10 @@ -#------------------------------------------------------------------------------ # $File: sgml,v 1.34 2016/09/11 13:56:42 christos Exp $ + +#------------------------------------------------------------------------------ +# $File: sgml,v 1.37 2017/07/23 08:23:33 christos Exp $ # Type: SVG Vectorial Graphics # From: Noel Torres -0 string \15 string >\0 +0 string \14 regex ['"\ \t]*[0-9.]+['"\ \t]* >>19 search/4096 \>19 search/4096 \>19 search/4096 \ -0 string \15 string >\0 +0 string \14 regex ['"\ \t]*[0-9.]+['"\ \t]* >>19 search/4096 \ HTML document text !:mime text/html !:strength + 5 diff --git a/contrib/file/magic/Magdir/sharc b/contrib/file/magic/Magdir/sharc index b40e65234282..e54088bc8f75 100644 --- a/contrib/file/magic/Magdir/sharc +++ b/contrib/file/magic/Magdir/sharc @@ -1,9 +1,9 @@ #------------------------------------------------------------------------ -# $File: sharc,v 1.7 2014/04/30 21:41:02 christos Exp $ +# $File: sharc,v 1.8 2017/03/17 21:35:28 christos Exp $ # file(1) magic for sharc files # -# SHARC DSP, MIDI SysEx and RiscOS filetype definitions added by +# SHARC DSP, MIDI SysEx and RiscOS filetype definitions added by # FutureGroove Music (dsp@futuregroove.de) #------------------------------------------------------------------------ diff --git a/contrib/file/magic/Magdir/sketch b/contrib/file/magic/Magdir/sketch index 82dacb8f06dc..ee731ddd52f8 100644 --- a/contrib/file/magic/Magdir/sketch +++ b/contrib/file/magic/Magdir/sketch @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sketch,v 1.4 2009/09/19 16:28:12 christos Exp $ -# Sketch Drawings: http://sketch.sourceforge.net/ +# $File: sketch,v 1.5 2017/03/17 21:35:28 christos Exp $ +# Sketch Drawings: http://sketch.sourceforge.net/ # From: Edwin Mons 0 search/1 ##Sketch Sketch document text diff --git a/contrib/file/magic/Magdir/sql b/contrib/file/magic/Magdir/sql index b07350a6b474..acc452931084 100644 --- a/contrib/file/magic/Magdir/sql +++ b/contrib/file/magic/Magdir/sql @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sql,v 1.20 2016/07/05 19:49:59 christos Exp $ +# $File: sql,v 1.21 2017/03/17 21:35:28 christos Exp $ # sql: file(1) magic for SQL files # # From: "Marty Leisner" @@ -73,7 +73,7 @@ >>3 byte x Version %d #------------------------------------------------------------------------------ -# iRiver H Series database file +# iRiver H Series database file # From Ken Guest # As observed from iRivNavi.iDB and unencoded firmware # @@ -133,9 +133,9 @@ 0 string PSDB\0 Panasonic channel list DataBase !:ext db/bin #!:mime application/x-db-svl-panasonic ->126 string SQLite\ format\ 3 +>126 string SQLite\ format\ 3 #!:mime application/x-panasonic-sqlite3 ->>&-15 indirect x \b; contains +>>&-15 indirect x \b; contains # H2 Database from http://www.h2database.com/ 0 string --\ H2\ 0.5/B\ --\ \n H2 Database file diff --git a/contrib/file/magic/Magdir/ssl b/contrib/file/magic/Magdir/ssl index 5d5daeeaf30f..2094ef5e7c6f 100644 --- a/contrib/file/magic/Magdir/ssl +++ b/contrib/file/magic/Magdir/ssl @@ -1,8 +1,20 @@ + +#------------------------------------------------------------------------------ +# $File: ssl,v 1.4 2017/01/22 21:14:25 christos Exp $ +# ssl: file(1) magic for SSL file formats + # Type: OpenSSL certificates/key files # From: Nicolas Collignon -0 string -----BEGIN\ CERTIFICATE----- PEM certificate -0 string -----BEGIN\ CERTIFICATE\ REQ PEM certificate request -0 string -----BEGIN\ RSA\ PRIVATE PEM RSA private key -0 string -----BEGIN\ DSA\ PRIVATE PEM DSA private key -0 string -----BEGIN\ EC\ PRIVATE PEM EC private key +0 string -----BEGIN\040CERTIFICATE----- PEM certificate +0 string -----BEGIN\040CERTIFICATE\040REQ PEM certificate request +0 string -----BEGIN\040RSA\040PRIVATE PEM RSA private key +0 string -----BEGIN\040DSA\040PRIVATE PEM DSA private key +0 string -----BEGIN\040EC\040PRIVATE PEM EC private key +0 string -----BEGIN\040ECDSA\040PRIVATE PEM ECDSA private key + +# From Luc Gommans +# OpenSSL enc file (recognized by a magic string preceding the password's salt) +0 string Salted__ openssl enc'd data with salted password +# Using the -a or -base64 option, OpenSSL will base64-encode the data. +0 string U2FsdGVkX19 openssl enc'd data with salted password, base64 encoded diff --git a/contrib/file/magic/Magdir/sysex b/contrib/file/magic/Magdir/sysex index 97472e275548..fc9cbf4ed4a2 100644 --- a/contrib/file/magic/Magdir/sysex +++ b/contrib/file/magic/Magdir/sysex @@ -1,6 +1,6 @@ #------------------------------------------------------------------------ -# $File: sysex,v 1.8 2014/06/03 19:17:27 christos Exp $ +# $File: sysex,v 1.9 2017/03/17 21:35:28 christos Exp $ # sysex: file(1) magic for MIDI sysex files # # GRR: original 1 byte test at offset was too general as it catches also many FATs of DOS filesystems @@ -256,7 +256,7 @@ >1 belong&0xffffff00 0x00011d00 Nemesys >1 belong&0xffffff00 0x00011e00 DBX >1 belong&0xffffff00 0x00011f00 Syndyne ->1 belong&0xffffff00 0x00012000 Bitheadz +>1 belong&0xffffff00 0x00012000 Bitheadz >1 belong&0xffffff00 0x00012100 Cakewalk >1 belong&0xffffff00 0x00012200 Staccato >1 belong&0xffffff00 0x00012300 National Semicon. diff --git a/contrib/file/magic/Magdir/terminfo b/contrib/file/magic/Magdir/terminfo index b201bcae5b7a..43e9d43179eb 100644 --- a/contrib/file/magic/Magdir/terminfo +++ b/contrib/file/magic/Magdir/terminfo @@ -1,24 +1,51 @@ #------------------------------------------------------------------------------ -# $File: terminfo,v 1.7 2016/03/17 21:02:29 christos Exp $ +# $File: terminfo,v 1.9 2017/04/28 16:28:58 christos Exp $ # terminfo: file(1) magic for terminfo # -# XXX - byte order for screen images? +# URL: http://invisible-island.net/ncurses/man/term.5.html +# URL: http://invisible-island.net/ncurses/man/scr_dump.5.html # -# URL: https://en.wikipedia.org/wiki/Terminfo -# Reference: ncurses-5.9/ncurses/tinfo/write_entry.c -# Update: Joerg Jenderek -# -# GRR: line below too general as it catches also +# Workaround for Targa image type by Joerg Jenderek +# GRR: line below too general as it catches also # Targa image type 1 with 26 long identification field # and HELP.DSK -0 string \032\001 +0 string \032\001 # 5th character of terminal name list, but not Targa image pixel size (15 16 24 32) ->16 ubyte >32 +>16 ubyte >32 # namelist, if more than 1 separated by "|" like "st|stterm| simpleterm 0.4.1" >>12 regex \^[a-zA-Z0-9][a-zA-Z0-9.][^|]* Compiled terminfo entry "%-s" !:mime application/x-terminfo # no extension -#!:ext -0 short 0433 Curses screen image -0 short 0434 Curses screen image +#!:ext +# +# While the compiled terminfo uses little-endian format irregardless of +# platform, SystemV screen dumps do not. They came later, and that detail was +# overlooked. +# +# AIX and HPUX use the SVr4 big-endian format +# Solaris uses the SVr3 formats (sparc and x86 differ endian-ness) +0 beshort 0433 SVr2 curses screen image, big-endian +0 beshort 0434 SVr3 curses screen image, big-endian +0 beshort 0435 SVr4 curses screen image, big-endian +# +0 leshort 0433 SVr2 curses screen image, little-endian +0 leshort 0434 SVr3 curses screen image, little-endian +0 leshort 0435 SVr4 curses screen image, little-endian +# +# Rather than SVr4, Solaris "xcurses" writes this header: +0 regex \^MAX=[0-9]+,[0-9]+$ +>1 regex \^BEG=[0-9]+,[0-9]+$ +>2 regex \^SCROLL=[0-9]+,[0-9]+$ +>3 regex \^VMIN=[0-9]+$ +>4 regex \^VTIME=[0-9]+$ +>5 regex \^FLAGS=0x[[:xdigit:]]+$ +>6 regex \^FG=[0-9],[0-9]+$ +>7 regex \^BG=[0-9]+,[0-9]+, Solaris xcurses screen image +# +# ncurses5 (and before) did not use a magic number, making screen dumps "data". +# ncurses6 (2015) uses this format, ignoring byte-order +0 string \210\210\210\210ncurses ncurses6 screen image +# +# PDCurses added this in 2005 +0 string PDC\001 PDCurses screen image diff --git a/contrib/file/magic/Magdir/vms b/contrib/file/magic/Magdir/vms index 493930394865..56d57ae93280 100644 --- a/contrib/file/magic/Magdir/vms +++ b/contrib/file/magic/Magdir/vms @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: vms,v 1.9 2014/08/17 13:47:59 christos Exp $ +# $File: vms,v 1.10 2017/03/17 21:35:28 christos Exp $ # vms: file(1) magic for VMS executables (experimental) # # VMS .exe formats, both VAX and AXP (Greg Roelofs, newt@uchicago.edu) @@ -25,6 +25,6 @@ # 00040 00 00 00 00 ff ff ff ff ff ff ff ff 02 00 00 00 ................ # # GRR this test is still too general as it catches example adressen.dbt -0 belong 0x03000000 +0 belong 0x03000000 >8 ubelong 0xec020000 VMS Alpha executable >>75264 string PK\003\004 \b, Info-ZIP SFX archive v5.12 w/decryption diff --git a/contrib/file/magic/Magdir/vmware b/contrib/file/magic/Magdir/vmware index b6b6a619b3ee..cd1a9d95765c 100644 --- a/contrib/file/magic/Magdir/vmware +++ b/contrib/file/magic/Magdir/vmware @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: vmware,v 1.7 2009/09/19 16:28:13 christos Exp $ +# $File: vmware,v 1.8 2017/03/17 21:35:28 christos Exp $ # VMware specific files (deducted from version 1.1 and log file entries) # Anthon van der Neut (anthon@mnt.org) -0 belong 0x4d52564e VMware nvram +0 belong 0x4d52564e VMware nvram diff --git a/contrib/file/magic/Magdir/vorbis b/contrib/file/magic/Magdir/vorbis index 3b5e51f5c8e8..5335ca8777c1 100644 --- a/contrib/file/magic/Magdir/vorbis +++ b/contrib/file/magic/Magdir/vorbis @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: vorbis,v 1.22 2015/03/28 15:14:55 christos Exp $ +# $File: vorbis,v 1.23 2017/03/17 21:35:28 christos Exp $ # vorbis: file(1) magic for Ogg/Vorbis files # # From Felix von Leitner @@ -95,7 +95,7 @@ # in a different place, so we must use an indirect offset. >>>(84.b+85) string \x03vorbis >>>>(84.b+96) string/c Xiphophorus\ libVorbis\ I \b, created by: Xiphophorus libVorbis I ->>>>>(84.b+120) string >00000000 +>>>>>(84.b+120) string >00000000 # Map to beta version numbers: >>>>>>(84.b+120) string <20000508 (>>>>>(84.b+120) string 20000508 (1.0 beta 1 or beta 2) @@ -117,7 +117,7 @@ >>>>>>(84.b+120) string >20011231 (pre-1.0 CVS) # For the 1.0 release, Xiphophorus is replaced by Xiph.Org >>>>(84.b+96) string/c Xiph.Org\ libVorbis\ I \b, created by: Xiph.Org libVorbis I ->>>>>(84.b+117) string >00000000 +>>>>>(84.b+117) string >00000000 >>>>>>(84.b+117) string <20020717 (pre-1.0 CVS) >>>>>>(84.b+117) string 20020717 (1.0) >>>>>>(84.b+117) string 20030909 (1.0.1) @@ -128,13 +128,13 @@ !:mime audio/ogg >>>36 ubyte >0x0F UNKNOWN VERSION %u, >>>36 ubyte &0x0F version 0.%d ->>>>46 ubyte >1 +>>>>46 ubyte >1 >>>>>46 ubyte !255 unknown channel mapping family %u, >>>>>37 ubyte x %u channels >>>>46 ubyte 0 >>>>>37 ubyte 1 mono >>>>>37 ubyte 2 stereo ->>>>46 ubyte 1 +>>>>46 ubyte 1 >>>>>37 ubyte 1 mono >>>>>37 ubyte 2 stereo >>>>>37 ubyte 3 linear surround diff --git a/contrib/file/magic/Magdir/webassembly b/contrib/file/magic/Magdir/webassembly new file mode 100644 index 000000000000..8a4ce1b1a599 --- /dev/null +++ b/contrib/file/magic/Magdir/webassembly @@ -0,0 +1,15 @@ +#------------------------------------------------------------------------------ +# $File: webassembly,v 1.2 2017/05/02 14:05:29 christos Exp $ +# webassembly: file(1) magic for WebAssembly modules +# +# WebAssembly is a virtual architecture developed by a W3C Community +# Group at http://webassembly.org/. The file extension is .wasm, and +# the MIME type is application/wasm. +# +# http://webassembly.org/docs/binary-encoding/ is the main +# document describing the binary format. +# From: Pip Cet and Joel Martin + +0 string \0asm WebAssembly (wasm) binary module +>4 lelong =1 version %#x (MVP) +>4 lelong >1 version %#x diff --git a/contrib/file/magic/Magdir/windows b/contrib/file/magic/Magdir/windows index faaa7e290028..169d4f8d0976 100644 --- a/contrib/file/magic/Magdir/windows +++ b/contrib/file/magic/Magdir/windows @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: windows,v 1.14 2015/12/15 01:06:17 christos Exp $ +# $File: windows,v 1.16 2017/03/17 22:20:22 christos Exp $ # windows: file(1) magic for Microsoft Windows # # This file is mainly reserved for files where programs @@ -29,7 +29,7 @@ # Created by: Andreas Schuster (http://computer.forensikblog.de/) # Reference (1): http://computer.forensikblog.de/en/2008/02/64bit_magic.html # Modified by (1): Abel Cheung (Avoid match with first 4 bytes only) -0 string PAGE +0 string PAGE >4 string DUMP MS Windows 32bit crash dump >>0x05c byte 0 \b, no PAE >>0x05c byte 1 \b, PAE @@ -66,13 +66,13 @@ # Summary: Old format help files # URL: https://en.wikipedia.org/wiki/WinHelp # Reference: http://www.oocities.org/mwinterhoff/helpfile.htm -# Update: Joerg Jenderek +# Update: Joerg Jenderek # Created by: Dirk Jagdmann # # check and then display version and date inside MS Windows HeLP file fragment 0 name help-ver-date # look for Magic of SYSTEMHEADER ->0 leshort 0x036C +>0 leshort 0x036C # version Major 1 for right file fragment >>4 leshort 1 Windows # print non empty string above to avoid error message @@ -93,7 +93,7 @@ >>>6 ldate x \b, %s # # Magic for HeLP files -0 lelong 0x00035f3f +0 lelong 0x00035f3f # ./windows (version 5.25) labeled the entry as "MS Windows 3.x help file" # file header magic 0x293B at DirectoryStart+9 >(4.l+9) uleshort 0x293B MS @@ -101,37 +101,37 @@ >>0xD4 string =\x62\x6D\x66\x01\x00 Windows help annotation !:mime application/x-winhelp !:ext ann ->>0xD4 string !\x62\x6D\x66\x01\x00 +>>0xD4 string !\x62\x6D\x66\x01\x00 # "GID Help index" by TrID >>>(4.l+0x65) string =|Pete Windows help Global Index !:mime application/x-winhelp !:ext gid # HeLP Bookmark or # "Windows HELP File" by TrID ->>>(4.l+0x65) string !|Pete +>>>(4.l+0x65) string !|Pete # maybe there exist a cleaner way to detect HeLP fragments # brute search for Magic 0x036C with matching Major maximal 7 iterations # discapp.hlp ->>>>16 search/0x49AF/s \x6c\x03 +>>>>16 search/0x49AF/s \x6c\x03 >>>>>&0 use help-ver-date ->>>>>&4 leshort !1 +>>>>>&4 leshort !1 # putty.hlp ->>>>>>&0 search/0x69AF/s \x6c\x03 +>>>>>>&0 search/0x69AF/s \x6c\x03 >>>>>>>&0 use help-ver-date ->>>>>>>&4 leshort !1 ->>>>>>>>&0 search/0x49AF/s \x6c\x03 +>>>>>>>&4 leshort !1 +>>>>>>>>&0 search/0x49AF/s \x6c\x03 >>>>>>>>>&0 use help-ver-date ->>>>>>>>>&4 leshort !1 ->>>>>>>>>>&0 search/0x49AF/s \x6c\x03 +>>>>>>>>>&4 leshort !1 +>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 >>>>>>>>>>>&0 use help-ver-date ->>>>>>>>>>>&4 leshort !1 ->>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 +>>>>>>>>>>>&4 leshort !1 +>>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 >>>>>>>>>>>>>&0 use help-ver-date ->>>>>>>>>>>>>&4 leshort !1 ->>>>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 +>>>>>>>>>>>>>&4 leshort !1 +>>>>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 >>>>>>>>>>>>>>>&0 use help-ver-date ->>>>>>>>>>>>>>>&4 leshort !1 ->>>>>>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 +>>>>>>>>>>>>>>>&4 leshort !1 +>>>>>>>>>>>>>>>>&0 search/0x49AF/s \x6c\x03 # GCC.HLP is detected after 7 iterations >>>>>>>>>>>>>>>>>&0 use help-ver-date # this only happens if bigger hlp file is detected after used search iterations @@ -139,7 +139,7 @@ !:mime application/winhelp !:ext hlp # repeat search again or following default line does not work ->>>>16 search/0x49AF/s \x6c\x03 +>>>>16 search/0x49AF/s \x6c\x03 # remaining files should be HeLP Bookmark WinHlp32.BMK (XP 32-bit) or WinHlp32 (Windows 8.1 64-bit) >>>>16 default x Windows help Bookmark !:mime application/x-winhelp @@ -180,21 +180,21 @@ #>>(4.l+47) ubequad x \b, PageStart 0x%16.16llx # start with colon or semicolon for comment line like Back2Life.cnt -0 regex \^(:|;) +0 regex \^(:|;) # look for first keyword Base ->0 search/45 :Base +>0 search/45 :Base >>&0 use cnt-name # only solution to search again from beginning , because relative offsets changes when use is called ->0 search/45 :Base ->0 default x +>0 search/45 :Base +>0 default x # look for other keyword Title like in putty.cnt ->>0 search/45 :Title +>>0 search/45 :Title >>>&0 use cnt-name # # display mime type and name of Windows help Content source 0 name cnt-name # skip space at beginning ->0 string \ +>0 string \040 # name without extension and greater character or name with hlp extension >>1 regex/c \^([^\xd>]*|.*\.hlp) MS Windows help file Content, based "%s" !:mime text/plain @@ -210,10 +210,10 @@ # Summary: Hyper terminal # Extension: .ht # Created by: unknown -0 string HyperTerminal\ +0 string HyperTerminal\040 >15 string 1.0\ --\ HyperTerminal\ data\ file MS Windows HyperTerminal profile -# http://ithreats.files.wordpress.com/2009/05/\ +# http://ithreats.files.wordpress.com/2009/05/\040 # lnk_the_windows_shortcut_file_format.pdf # Summary: Windows shortcut # Extension: .lnk @@ -293,7 +293,7 @@ # Extension: .reg # Submitted by: Abel Cheung 0 string REGEDIT4\r\n\r\n Windows Registry text (Win95 or above) -0 string Windows\ Registry\ Editor\ +0 string Windows\ Registry\ Editor\040 >&0 string Version\ 5.00\r\n\r\n Windows Registry text (Win2K or above) # Windows *.INF *.INI files updated by Joerg Jenderek at Apr 2013 @@ -301,10 +301,10 @@ # PR/383: remove unicode BOM because it is not portable across regex impls 0 regex/s \\`(\\r\\n|;|[[]) # left bracket in section line ->&0 search/8192 [ +>&0 search/8192 [ # http://en.wikipedia.org/wiki/Autorun.inf # http://msdn.microsoft.com/en-us/library/windows/desktop/cc144200.aspx ->>&0 regex/c \^(autorun)]\r\n +>>&0 regex/c \^(autorun)]\r\n >>>&0 ubyte =0x5b INItialization configuration !:mime application/x-wine-extension-ini # From: Pal Tamas @@ -343,31 +343,31 @@ # http://en.wikipedia.org/wiki/NTLDR Windows Boot Loader information >>&0 regex/c \^(boot\x20loader)] Windows boot.ini !:mime application/x-wine-extension-ini ->>>&0 ubyte x +>>>&0 ubyte x # http://en.wikipedia.org/wiki/CONFIG.SYS >>&0 regex/c \^(menu)]\r\n MS-DOS CONFIG.SYS # http://support.microsoft.com/kb/118579/ >>&0 regex/c \^(Paths)]\r\n MS-DOS MSDOS.SYS # VERS string unicoded case-independent ->>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0056004500520053 +>>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0056004500520053 # ION] string unicoded case-independent ->>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x0049004f004e005d Windows setup INFormation +>>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x0049004f004e005d Windows setup INFormation !:mime application/x-setupscript # STRI string unicoded case-independent ->>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0053005400520049 +>>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0053005400520049 # NGS] string unicoded case-independent ->>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x004e00470053005D Windows setup INFormation +>>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x004e00470053005D Windows setup INFormation !:mime application/x-setupscript # unknown keyword after opening bracket ->>&0 default x ->>>&0 search/8192 [ +>>&0 default x +>>>&0 search/8192 [ # version Strings FileIdentification ->>>>&0 string/c version Windows setup INFormation +>>>>&0 string/c version Windows setup INFormation !:mime application/x-setupscript # VERS string unicoded case-independent ->>>>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0056004500520053 +>>>>&0 ubequad&0xFFdfFFdfFFdfFFdf 0x0056004500520053 # ION] string unicoded case-independent ->>>>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x0049004f004e005d Windows setup INFormation +>>>>>&0 ubequad&0xFFdfFFdfFFdfFFff 0x0049004f004e005d Windows setup INFormation !:mime application/x-setupscript # http://en.wikipedia.org/wiki/Initialization_file Windows Initialization File or other #>>>>&0 default x Generic INItialization configuration @@ -376,21 +376,21 @@ # Windows Precompiled INF files *.PNF added by Joerg Jenderek at Mar 2013 of _PNF_HEADER inf.h # http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/windows/setup/setupapi/inf.h__.htm # GRR: line below too general as it catches also PDP-11 UNIX/RT ldp -0 leshort&0xFeFe 0x0000 +0 leshort&0xFeFe 0x0000 !:strength -5 # test for unused null bits in PNF_FLAGs ->4 ulelong&0xFCffFe00 0x00000000 +>4 ulelong&0xFCffFe00 0x00000000 # only found 58h for Offset of WinDirPath immediately after _PNF_HEADER structure ->>68 ulelong >0x57 +>>68 ulelong >0x57 # test for zero high byte of InfValueBlockSize, followed by WinDirPath like # C:\WINDOWS (ASCII 0x433a5c.. , unicode 0x43003a005c..) or X:\MININT >>>(68.l-1) ubelong&0xffE0C519 =0x00400018 Windows Precompiled iNF !:mime application/x-pnf # currently only found Major Version=1 and Minor Version=1 -#>>>>0 uleshort =0x0101 +#>>>>0 uleshort =0x0101 #>>>>>1 ubyte x \b, version %u #>>>>>0 ubyte x \b.%u ->>>>0 uleshort !0x0101 +>>>>0 uleshort !0x0101 >>>>>1 ubyte x \b, version %u >>>>>0 ubyte x \b.%u # 1 ,2 (windows 98 SE) @@ -416,10 +416,10 @@ #>>>>16 ulelong x \b, InfVersionDataSize 0x%x # only found positive values lower 0x00ffFFff for InfVersionDataOffset >>>>20 ulelong x \b, at 0x%x ->>>>4 ulelong&0x00000001 =0x00000001 -# case independent: CatalogFile Class DriverVer layoutfile LayoutFile SetupClass signature Signature +>>>>4 ulelong&0x00000001 =0x00000001 +# case independent: CatalogFile Class DriverVer layoutfile LayoutFile SetupClass signature Signature >>>>>(20.l) lestring16 x "%s" ->>>>4 ulelong&0x00000001 !0x00000001 +>>>>4 ulelong&0x00000001 !0x00000001 >>>>>(20.l) string x "%s" # FILETIME is number of 100-nanosecond intervals since 1 January 1601 #>>>>24 ulequad x \b, InfVersionLastWriteTime %16.16llx @@ -435,23 +435,23 @@ #>>>>64 ulelong x \b, InfValueBlockSize 0x%x # WinDirPathOffset #>>>>68 ulelong x \b, at 0x%x ->>>>68 ulelong >0x57 ->>>>>4 ulelong&0x00000001 =0x00000001 ->>>>>>(68.l) ubequad =0x43003a005c005700 +>>>>68 ulelong >0x57 +>>>>>4 ulelong&0x00000001 =0x00000001 +>>>>>>(68.l) ubequad =0x43003a005c005700 # normally unicoded C:\Windows #>>>>>>>(68.l) lestring16 x \b, WinDirPath "%s" ->>>>>>(68.l) ubequad !0x43003a005c005700 +>>>>>>(68.l) ubequad !0x43003a005c005700 >>>>>>>(68.l) lestring16 x \b, WinDirPath "%s" ->>>>>4 ulelong&0x00000001 !0x00000001 +>>>>>4 ulelong&0x00000001 !0x00000001 # normally ASCII C:\WINDOWS #>>>>>>(68.l) string =C:\\WINDOWS \b, WinDirPath "%s" >>>>>>(68.l) string !C:\\WINDOWS \b, WinDirPath "%s" -# found OsLoaderPathOffset values often 0 , once 70h corelist.PNF, once 68h ASCII machine.PNF +# found OsLoaderPathOffset values often 0 , once 70h corelist.PNF, once 68h ASCII machine.PNF #>>>>72 ulelong >0 \b, at 0x%x >>>>72 ulelong >0 \b, ->>>>>4 ulelong&0x00000001 =0x00000001 +>>>>>4 ulelong&0x00000001 =0x00000001 >>>>>>(72.l) lestring16 x OsLoaderPath "%s" ->>>>>4 ulelong&0x00000001 !0x00000001 +>>>>>4 ulelong&0x00000001 !0x00000001 # seldom C:\ instead empty >>>>>>(72.l) string x OsLoaderPath "%s" # 1fdh @@ -462,16 +462,16 @@ # InfSourcePathOffset often 0 #>>>>80 ulelong >0 \b, at 0x%x >>>>80 ulelong >0 \b, ->>>>>4 ulelong&0x00000001 =0x00000001 +>>>>>4 ulelong&0x00000001 =0x00000001 >>>>>>(80.l) lestring16 x SourcePath "%s" ->>>>>4 ulelong&0x00000001 !0x00000001 +>>>>>4 ulelong&0x00000001 !0x00000001 >>>>>>(80.l) string >\0 SourcePath "%s" # OriginalInfNameOffset often 0 #>>>>84 ulelong >0 \b, at 0x%x >>>>84 ulelong >0 \b, ->>>>>4 ulelong&0x00000001 =0x00000001 +>>>>>4 ulelong&0x00000001 =0x00000001 >>>>>>(84.l) lestring16 x InfName "%s" ->>>>>4 ulelong&0x00000001 !0x00000001 +>>>>>4 ulelong&0x00000001 !0x00000001 >>>>>>(84.l) string >\0 InfName "%s" # Summary: backup file created with utility like NTBACKUP.EXE shipped with Windows NT/2K/XP/2003 @@ -480,13 +480,13 @@ # URL: http://en.wikipedia.org/wiki/NTBackup # Reference: http://laytongraphics.com/mtf/MTF_100a.PDF # Descriptor BloCK name of Microsoft Tape Format -0 string TAPE +0 string TAPE # Format Logical Address is zero ->20 ulequad 0 +>20 ulequad 0 # Reserved for MBC is zero ->>28 uleshort 0 +>>28 uleshort 0 # Control Block ID is zero ->>>36 ulelong 0 +>>>36 ulelong 0 # BIT4-BIT15, BIT18-BIT31 of block attributes are unused >>>>4 ulelong&0xFFfcFFe0 0 Windows NTbackup archive #!:mime application/x-ntbackup @@ -508,7 +508,7 @@ >>>>>4 ulelong&0x00000004 !0 \b, compressed # MTF_EOS_AT_EOM End Of Medium was hit during end of set processing >>>>>4 ulelong&0x00000008 !0 \b, End Of Medium hit ->>>>>4 ulelong&0x00020000 0 +>>>>>4 ulelong&0x00020000 0 # MTF_SET_MAP_EXISTS A Media Based Catalog Set Map may exist on tape >>>>>>4 ulelong&0x00010000 !0 \b, with catalog # MTF_FDD_ALLOWED However File/Directory Detail can only exist if a Set Map is also present @@ -531,37 +531,37 @@ # Media Based Catalog Type (1,2) #>>>>>66 uleshort x \b, catalog type %4.4x # size of Media Name (66,68,6Eh) ->>>>>68 uleshort >0 +>>>>>68 uleshort >0 # offset of Media Name (5Eh) ->>>>>>70 uleshort >0 +>>>>>>70 uleshort >0 # 0~, 1~ANSI, 2~UNICODE ->>>>>>>48 ubyte 1 +>>>>>>>48 ubyte 1 # size terminated ansi coded string normally followed by "MTF Media Label" >>>>>>>>(70.s) string >\0 \b, name: %s ->>>>>>>48 ubyte 2 +>>>>>>>48 ubyte 2 # Not null, but size terminated unicoded string >>>>>>>>(70.s) lestring16 x \b, name: %s # size of Media Label (104h) ->>>>>72 uleshort >0 +>>>>>72 uleshort >0 # offset of Media Label (C4h,C6h,CCh) ->>>>>74 uleshort >0 ->>>>>>48 ubyte 1 +>>>>>74 uleshort >0 +>>>>>>48 ubyte 1 #Tag|Version|Vendor|Vendor ID|Creation Time Stamp|Cartridge Label|Side|Media ID|Media Domain ID|Vendor Specific fields >>>>>>>(74.s) string >\0 \b, label: %s ->>>>>>48 ubyte 2 +>>>>>>48 ubyte 2 >>>>>>>(74.s) lestring16 x \b, label: %s # size of password name (0,1Ch) #>>>>>76 uleshort >0 \b, password size %4.4x # Software Vendor ID (CBEh) >>>>>86 uleshort x \b, software (0x%x) # size of Software Name (6Eh) ->>>>>80 uleshort >0 +>>>>>80 uleshort >0 # offset of Software Name (1C8h,1CAh,1D0h) ->>>>>>82 uleshort >0 +>>>>>>82 uleshort >0 # 1~ANSI, 2~UNICODE ->>>>>>>48 ubyte 1 +>>>>>>>48 ubyte 1 >>>>>>>>(82.s) string >\0 \b: %s ->>>>>>>48 ubyte 2 +>>>>>>>48 ubyte 2 # size terminated unicoded coded string normally followed by "SPAD" >>>>>>>>(82.s) lestring16 x \b: %s # Format Logical Block Size (512,1024) diff --git a/contrib/file/magic/Magdir/xenix b/contrib/file/magic/Magdir/xenix index 89de6033268c..fb83faa876ed 100644 --- a/contrib/file/magic/Magdir/xenix +++ b/contrib/file/magic/Magdir/xenix @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: xenix,v 1.10 2016/04/19 18:14:19 christos Exp $ +# $File: xenix,v 1.11 2017/03/17 21:35:28 christos Exp $ # xenix: file(1) magic for Microsoft Xenix # # "Middle model" stuff, and "Xenix 8086 relocatable or 80286 small @@ -16,14 +16,14 @@ # Reference: http://www.azillionmonkeys.com/qed/Omfg.pdf # Update: Joerg Jenderek # recordtype~TranslatorHEADerRecord -0 byte 0x80 +0 byte 0x80 # GRR: line above is too general as it catches also Extensible storage engine DataBase # skip examples like GENA.SND Switch.Snd by looking for record length maximal 1024-3 ->1 uleshort <1022 +>1 uleshort <1022 # skip examples like GAME.PICTURE Strange.Pic by looking for positiv record length ->>1 uleshort >0 +>>1 uleshort >0 # skip examples like Xtable.Data FRACTAL.GEN SHR.VIEW by looking for positiv string length ->>>3 ubyte >0 +>>>3 ubyte >0 # skip examples like OMBRE.6 with "UUUUUU" by looking for filename like "hello.c" >>>>4 regex [a-zA-Z_/]{1,8}[.] 8086 relocatable (Microsoft) #!:mime application/octet-stream @@ -54,8 +54,8 @@ >0x1c byte &0x9 286 >0x1c byte &0xa 386 >0x1f byte <0x040 small model ->0x1f byte =0x048 large model ->0x1f byte =0x049 huge model +>0x1f byte =0x048 large model +>0x1f byte =0x049 huge model >0x1e leshort &0x1 executable >0x1e leshort ^0x1 object file >0x1e leshort &0x40 Large Text diff --git a/contrib/file/magic/Magdir/xilinx b/contrib/file/magic/Magdir/xilinx index 91e84d91d0ee..a5219778d390 100644 --- a/contrib/file/magic/Magdir/xilinx +++ b/contrib/file/magic/Magdir/xilinx @@ -1,12 +1,12 @@ #------------------------------------------------------------------------------ -# $File: xilinx,v 1.7 2014/04/30 21:41:02 christos Exp $ +# $File: xilinx,v 1.8 2017/03/17 21:35:28 christos Exp $ # This is Aaron's attempt at a MAGIC file for Xilinx .bit files. # Xilinx-Magic@RevRagnarok.com # Got the info from FPGA-FAQ 0026 # -# Rewritten to use pstring/H instead of hardcoded lengths by O. Freyermuth, -# fixes at least reading of bitfiles from Spartan 2, 3, 6. +# Rewritten to use pstring/H instead of hardcoded lengths by O. Freyermuth, +# fixes at least reading of bitfiles from Spartan 2, 3, 6. # http://www.fpga-faq.com/FAQ_Pages/0026_Tell_me_about_bit_files.htm # # First there is the sync header and its length @@ -20,7 +20,7 @@ >>>>&0 pstring/H x - from %s # And then 'b' >>>>>&1 string b -# Then the model / part number: +# Then the model / part number: >>>>>>&0 pstring/H x - for %s # Then 'c' >>>>>>>&1 string c @@ -36,5 +36,5 @@ >>>>>>>>>>>>&0 belong x - data length 0x%x # Raw bitstream files -0 long 0xffffffff +0 long 0xffffffff >&0 belong 0xaa995566 Xilinx RAW bitstream (.BIN) diff --git a/contrib/file/magic/Magdir/xwindows b/contrib/file/magic/Magdir/xwindows index eb208927f01e..85f64c8c36a4 100644 --- a/contrib/file/magic/Magdir/xwindows +++ b/contrib/file/magic/Magdir/xwindows @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# $File: xwindows,v 1.9 2014/04/30 21:41:02 christos Exp $ +# $File: xwindows,v 1.10 2017/03/17 21:35:28 christos Exp $ # xwindows: file(1) magic for various X/Window system file formats. -# Compiled X Keymap +# Compiled X Keymap # XKM (compiled X keymap) files (including version and byte ordering) 1 string mkx Compiled XKB Keymap: lsb, >0 byte >0 version %d diff --git a/contrib/file/magic/Magdir/yara b/contrib/file/magic/Magdir/yara new file mode 100644 index 000000000000..523a2d05f410 --- /dev/null +++ b/contrib/file/magic/Magdir/yara @@ -0,0 +1,17 @@ + + +#------------------------------------------------------------------------------ +# $File: yara,v 1.2 2017/05/25 20:07:23 christos Exp $ +# yara: file(1) magic for http://virustotal.github.io/yara/ +# + +0 string YARA +>4 lelong >2047 +>8 byte <20 YARA 3.x compiled rule set +# version +>>8 clear x +>>8 byte 6 created with version 3.3.0 +>>8 byte 8 created with version 3.4.0 +>>8 byte 11 created with version 3.5.0 +>>8 default x +>>>8 byte x development version 0x%02x diff --git a/contrib/file/magic/Makefile.am b/contrib/file/magic/Makefile.am index 19701ecd179b..5259a478368d 100644 --- a/contrib/file/magic/Makefile.am +++ b/contrib/file/magic/Makefile.am @@ -1,5 +1,5 @@ # -# $File: Makefile.am,v 1.120 2016/10/17 19:52:29 christos Exp $ +# $File: Makefile.am,v 1.126 2017/08/10 11:01:38 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -21,6 +21,7 @@ $(MAGIC_FRAGMENT_DIR)/amigaos \ $(MAGIC_FRAGMENT_DIR)/android \ $(MAGIC_FRAGMENT_DIR)/animation \ $(MAGIC_FRAGMENT_DIR)/aout \ +$(MAGIC_FRAGMENT_DIR)/apache \ $(MAGIC_FRAGMENT_DIR)/apl \ $(MAGIC_FRAGMENT_DIR)/apple \ $(MAGIC_FRAGMENT_DIR)/application \ @@ -34,6 +35,7 @@ $(MAGIC_FRAGMENT_DIR)/audio \ $(MAGIC_FRAGMENT_DIR)/basis \ $(MAGIC_FRAGMENT_DIR)/ber \ $(MAGIC_FRAGMENT_DIR)/bflt \ +$(MAGIC_FRAGMENT_DIR)/bhl \ $(MAGIC_FRAGMENT_DIR)/bioinformatics \ $(MAGIC_FRAGMENT_DIR)/blackberry \ $(MAGIC_FRAGMENT_DIR)/blcr \ @@ -97,6 +99,7 @@ $(MAGIC_FRAGMENT_DIR)/fsav \ $(MAGIC_FRAGMENT_DIR)/fusecompress \ $(MAGIC_FRAGMENT_DIR)/games \ $(MAGIC_FRAGMENT_DIR)/gcc \ +$(MAGIC_FRAGMENT_DIR)/gconv \ $(MAGIC_FRAGMENT_DIR)/geo \ $(MAGIC_FRAGMENT_DIR)/geos \ $(MAGIC_FRAGMENT_DIR)/gimp \ @@ -104,6 +107,7 @@ $(MAGIC_FRAGMENT_DIR)/gnome \ $(MAGIC_FRAGMENT_DIR)/gnu \ $(MAGIC_FRAGMENT_DIR)/gnumeric \ $(MAGIC_FRAGMENT_DIR)/gpt \ +$(MAGIC_FRAGMENT_DIR)/gpu \ $(MAGIC_FRAGMENT_DIR)/grace \ $(MAGIC_FRAGMENT_DIR)/graphviz \ $(MAGIC_FRAGMENT_DIR)/gringotts \ @@ -275,6 +279,7 @@ $(MAGIC_FRAGMENT_DIR)/vorbis \ $(MAGIC_FRAGMENT_DIR)/vxl \ $(MAGIC_FRAGMENT_DIR)/warc \ $(MAGIC_FRAGMENT_DIR)/weak \ +$(MAGIC_FRAGMENT_DIR)/webassembly \ $(MAGIC_FRAGMENT_DIR)/windows \ $(MAGIC_FRAGMENT_DIR)/wireless \ $(MAGIC_FRAGMENT_DIR)/wordprocessors \ @@ -285,6 +290,7 @@ $(MAGIC_FRAGMENT_DIR)/xenix \ $(MAGIC_FRAGMENT_DIR)/xilinx \ $(MAGIC_FRAGMENT_DIR)/xo65 \ $(MAGIC_FRAGMENT_DIR)/xwindows \ +$(MAGIC_FRAGMENT_DIR)/yara \ $(MAGIC_FRAGMENT_DIR)/zfs \ $(MAGIC_FRAGMENT_DIR)/zilog \ $(MAGIC_FRAGMENT_DIR)/zyxel diff --git a/contrib/file/magic/Makefile.in b/contrib/file/magic/Makefile.in index 0de849d603bd..3555f9e6b332 100644 --- a/contrib/file/magic/Makefile.in +++ b/contrib/file/magic/Makefile.in @@ -273,7 +273,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # -# $File: Makefile.am,v 1.120 2016/10/17 19:52:29 christos Exp $ +# $File: Makefile.am,v 1.126 2017/08/10 11:01:38 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -293,6 +293,7 @@ $(MAGIC_FRAGMENT_DIR)/amigaos \ $(MAGIC_FRAGMENT_DIR)/android \ $(MAGIC_FRAGMENT_DIR)/animation \ $(MAGIC_FRAGMENT_DIR)/aout \ +$(MAGIC_FRAGMENT_DIR)/apache \ $(MAGIC_FRAGMENT_DIR)/apl \ $(MAGIC_FRAGMENT_DIR)/apple \ $(MAGIC_FRAGMENT_DIR)/application \ @@ -306,6 +307,7 @@ $(MAGIC_FRAGMENT_DIR)/audio \ $(MAGIC_FRAGMENT_DIR)/basis \ $(MAGIC_FRAGMENT_DIR)/ber \ $(MAGIC_FRAGMENT_DIR)/bflt \ +$(MAGIC_FRAGMENT_DIR)/bhl \ $(MAGIC_FRAGMENT_DIR)/bioinformatics \ $(MAGIC_FRAGMENT_DIR)/blackberry \ $(MAGIC_FRAGMENT_DIR)/blcr \ @@ -369,6 +371,7 @@ $(MAGIC_FRAGMENT_DIR)/fsav \ $(MAGIC_FRAGMENT_DIR)/fusecompress \ $(MAGIC_FRAGMENT_DIR)/games \ $(MAGIC_FRAGMENT_DIR)/gcc \ +$(MAGIC_FRAGMENT_DIR)/gconv \ $(MAGIC_FRAGMENT_DIR)/geo \ $(MAGIC_FRAGMENT_DIR)/geos \ $(MAGIC_FRAGMENT_DIR)/gimp \ @@ -376,6 +379,7 @@ $(MAGIC_FRAGMENT_DIR)/gnome \ $(MAGIC_FRAGMENT_DIR)/gnu \ $(MAGIC_FRAGMENT_DIR)/gnumeric \ $(MAGIC_FRAGMENT_DIR)/gpt \ +$(MAGIC_FRAGMENT_DIR)/gpu \ $(MAGIC_FRAGMENT_DIR)/grace \ $(MAGIC_FRAGMENT_DIR)/graphviz \ $(MAGIC_FRAGMENT_DIR)/gringotts \ @@ -547,6 +551,7 @@ $(MAGIC_FRAGMENT_DIR)/vorbis \ $(MAGIC_FRAGMENT_DIR)/vxl \ $(MAGIC_FRAGMENT_DIR)/warc \ $(MAGIC_FRAGMENT_DIR)/weak \ +$(MAGIC_FRAGMENT_DIR)/webassembly \ $(MAGIC_FRAGMENT_DIR)/windows \ $(MAGIC_FRAGMENT_DIR)/wireless \ $(MAGIC_FRAGMENT_DIR)/wordprocessors \ @@ -557,6 +562,7 @@ $(MAGIC_FRAGMENT_DIR)/xenix \ $(MAGIC_FRAGMENT_DIR)/xilinx \ $(MAGIC_FRAGMENT_DIR)/xo65 \ $(MAGIC_FRAGMENT_DIR)/xwindows \ +$(MAGIC_FRAGMENT_DIR)/yara \ $(MAGIC_FRAGMENT_DIR)/zfs \ $(MAGIC_FRAGMENT_DIR)/zilog \ $(MAGIC_FRAGMENT_DIR)/zyxel diff --git a/contrib/file/python/magic.py b/contrib/file/python/magic.py index b0f7a1765e8f..662569e889d0 100644 --- a/contrib/file/python/magic.py +++ b/contrib/file/python/magic.py @@ -117,30 +117,43 @@ def close(self): """ _close(self._magic_t) + @staticmethod + def __tostr(s): + if s is None: + return None + if isinstance(s, str): + return s + try: # keep Python 2 compatibility + return str(s, 'utf-8') + except TypeError: + return str(s) + + @staticmethod + def __tobytes(b): + if b is None: + return None + if isinstance(b, bytes): + return b + try: # keep Python 2 compatibility + return bytes(b, 'utf-8') + except TypeError: + return bytes(b) + def file(self, filename): """ Returns a textual description of the contents of the argument passed as a filename or None if an error occurred and the MAGIC_ERROR flag - is set. A call to errno() will return the numeric error code. + is set. A call to errno() will return the numeric error code. """ - if isinstance(filename, bytes): - bi = filename - else: - try: # keep Python 2 compatibility - bi = bytes(filename, 'utf-8') - except TypeError: - bi = bytes(filename) - r = _file(self._magic_t, bi) - if isinstance(r, str): - return r - else: - return str(r, 'utf-8') + return Magic.__tostr(_file(self._magic_t, Magic.__tobytes(filename))) def descriptor(self, fd): """ - Like the file method, but the argument is a file descriptor. + Returns a textual description of the contents of the argument passed + as a file descriptor or None if an error occurred and the MAGIC_ERROR + flag is set. A call to errno() will return the numeric error code. """ - return _descriptor(self._magic_t, fd) + return Magic.__tostr(_descriptor(self._magic_t, fd)) def buffer(self, buf): """ @@ -148,22 +161,14 @@ def buffer(self, buf): as a buffer or None if an error occurred and the MAGIC_ERROR flag is set. A call to errno() will return the numeric error code. """ - r = _buffer(self._magic_t, buf, len(buf)) - if isinstance(r, str): - return r - else: - return str(r, 'utf-8') + return Magic.__tostr(_buffer(self._magic_t, buf, len(buf))) def error(self): """ Returns a textual explanation of the last error or None if there was no error. """ - e = _error(self._magic_t) - if isinstance(e, str): - return e - else: - return str(e, 'utf-8') + return Magic.__tostr(_error(self._magic_t)) def setflags(self, flags): """ @@ -184,35 +189,38 @@ def load(self, filename=None): Returns 0 on success and -1 on failure. """ - return _load(self._magic_t, filename) + return _load(self._magic_t, Magic.__tobytes(filename)) def compile(self, dbs): """ Compile entries in the colon separated list of database files passed as argument or the default database file if no argument. - Returns 0 on success and -1 on failure. The compiled files created are named from the basename(1) of each file argument with ".mgc" appended to it. + + Returns 0 on success and -1 on failure. """ - return _compile(self._magic_t, dbs) + return _compile(self._magic_t, Magic.__tobytes(dbs)) def check(self, dbs): """ Check the validity of entries in the colon separated list of database files passed as argument or the default database file if no argument. + Returns 0 on success and -1 on failure. """ - return _check(self._magic_t, dbs) + return _check(self._magic_t, Magic.__tobytes(dbs)) def list(self, dbs): """ Check the validity of entries in the colon separated list of database files passed as argument or the default database file if no argument. + Returns 0 on success and -1 on failure. """ - return _list(self._magic_t, dbs) + return _list(self._magic_t, Magic.__tobytes(dbs)) def errno(self): """ diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c index f2622c081284..a7b4dd8f9115 100644 --- a/contrib/file/src/apprentice.c +++ b/contrib/file/src/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.255 2016/10/24 18:02:17 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $") #endif /* lint */ #include "magic.h" @@ -549,8 +549,10 @@ apprentice_unmap(struct magic_map *map) break; case MAP_TYPE_MALLOC: for (i = 0; i < MAGIC_SETS; i++) { - if ((char *)map->magic[i] >= (char *)map->p && - (char *)map->magic[i] <= (char *)map->p + map->len) + void *b = map->magic[i]; + void *p = map->p; + if (CAST(char *, b) >= CAST(char *, p) && + CAST(char *, b) <= CAST(char *, p) + map->len) continue; free(map->magic[i]); } @@ -610,8 +612,7 @@ buffer_apprentice(struct magic_set *ms, struct magic **bufs, if (nbufs == 0) return -1; - if (ms->mlist[0] != NULL) - file_reset(ms); + (void)file_reset(ms, 0); init_file_tables(); @@ -654,8 +655,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action) int file_err, errs = -1; size_t i; - if (ms->mlist[0] != NULL) - file_reset(ms); + (void)file_reset(ms, 0); if ((fn = magic_getpath(fn, action)) == NULL) return -1; @@ -777,6 +777,59 @@ nonmagic(const char *str) return rv == 0 ? 1 : rv; /* Return at least 1 */ } + +private size_t +typesize(int type) +{ + switch (type) { + case FILE_BYTE: + return 1; + + case FILE_SHORT: + case FILE_LESHORT: + case FILE_BESHORT: + return 2; + + case FILE_LONG: + case FILE_LELONG: + case FILE_BELONG: + case FILE_MELONG: + return 4; + + case FILE_DATE: + case FILE_LEDATE: + case FILE_BEDATE: + case FILE_MEDATE: + case FILE_LDATE: + case FILE_LELDATE: + case FILE_BELDATE: + case FILE_MELDATE: + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: + return 4; + + case FILE_QUAD: + case FILE_BEQUAD: + case FILE_LEQUAD: + case FILE_QDATE: + case FILE_LEQDATE: + case FILE_BEQDATE: + case FILE_QLDATE: + case FILE_LEQLDATE: + case FILE_BEQLDATE: + case FILE_QWDATE: + case FILE_LEQWDATE: + case FILE_BEQWDATE: + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: + return 8; + default: + return (size_t)~0; + } +} + /* * Get weight of this magic entry, for sorting purposes. */ @@ -784,7 +837,7 @@ private size_t apprentice_magic_strength(const struct magic *m) { #define MULT 10 - size_t v, val = 2 * MULT; /* baseline strength */ + size_t ts, v, val = 2 * MULT; /* baseline strength */ switch (m->type) { case FILE_DEFAULT: /* make sure this sorts last */ @@ -793,20 +846,43 @@ apprentice_magic_strength(const struct magic *m) return 0; case FILE_BYTE: - val += 1 * MULT; - break; - case FILE_SHORT: case FILE_LESHORT: case FILE_BESHORT: - val += 2 * MULT; - break; - case FILE_LONG: case FILE_LELONG: case FILE_BELONG: case FILE_MELONG: - val += 4 * MULT; + case FILE_DATE: + case FILE_LEDATE: + case FILE_BEDATE: + case FILE_MEDATE: + case FILE_LDATE: + case FILE_LELDATE: + case FILE_BELDATE: + case FILE_MELDATE: + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: + case FILE_QUAD: + case FILE_BEQUAD: + case FILE_LEQUAD: + case FILE_QDATE: + case FILE_LEQDATE: + case FILE_BEQDATE: + case FILE_QLDATE: + case FILE_LEQLDATE: + case FILE_BEQLDATE: + case FILE_QWDATE: + case FILE_LEQWDATE: + case FILE_BEQWDATE: + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: + ts = typesize(m->type); + if (ts == (size_t)~0) + abort(); + val += ts * MULT; break; case FILE_PSTRING: @@ -828,38 +904,6 @@ apprentice_magic_strength(const struct magic *m) val += v * MAX(MULT / v, 1); break; - case FILE_DATE: - case FILE_LEDATE: - case FILE_BEDATE: - case FILE_MEDATE: - case FILE_LDATE: - case FILE_LELDATE: - case FILE_BELDATE: - case FILE_MELDATE: - case FILE_FLOAT: - case FILE_BEFLOAT: - case FILE_LEFLOAT: - val += 4 * MULT; - break; - - case FILE_QUAD: - case FILE_BEQUAD: - case FILE_LEQUAD: - case FILE_QDATE: - case FILE_LEQDATE: - case FILE_BEQDATE: - case FILE_QLDATE: - case FILE_LEQLDATE: - case FILE_BEQLDATE: - case FILE_QWDATE: - case FILE_LEQWDATE: - case FILE_BEQWDATE: - case FILE_DOUBLE: - case FILE_BEDOUBLE: - case FILE_LEDOUBLE: - val += 8 * MULT; - break; - case FILE_INDIRECT: case FILE_NAME: case FILE_USE: @@ -1314,6 +1358,8 @@ apprentice_load(struct magic_set *ms, const char *fn, int action) goto out; } while ((d = readdir(dir)) != NULL) { + if (d->d_name[0] == '.') + continue; if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) { file_oomem(ms, strlen(fn) + strlen(d->d_name) + 2); @@ -2291,7 +2337,7 @@ parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line) return parse_extra(ms, me, line, CAST(off_t, offsetof(struct magic, ext)), - sizeof(m->ext), "EXTENSION", ",!+-/", 0); + sizeof(m->ext), "EXTENSION", ",!+-/@", 0); } /* @@ -2352,6 +2398,8 @@ check_format_type(const char *ptr, int type, const char **estr) ptr++; if (*ptr == '.') ptr++; + if (*ptr == '#') + ptr++; #define CHECKLEN() do { \ for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \ len = len * 10 + (*ptr - '0'); \ @@ -2617,9 +2665,46 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) default: if (m->reln != 'x') { char *ep; + uint64_t ull; errno = 0; - m->value.q = file_signextend(ms, m, - (uint64_t)strtoull(*p, &ep, 0)); + ull = (uint64_t)strtoull(*p, &ep, 0); + m->value.q = file_signextend(ms, m, ull); + if (*p == ep) { + file_magwarn(ms, "Unparseable number `%s'", *p); + } else { + size_t ts = typesize(m->type); + uint64_t x; + const char *q; + + if (ts == (size_t)~0) { + file_magwarn(ms, "Expected numeric type got `%s'", + type_tbl[m->type].name); + } + for (q = *p; isspace((unsigned char)*q); q++) + continue; + if (*q == '-') + ull = -(int64_t)ull; + switch (ts) { + case 1: + x = ull & ~0xffULL; + break; + case 2: + x = ull & ~0xffffULL; + break; + case 4: + x = ull & ~0xffffffffULL; + break; + case 8: + x = 0; + break; + default: + abort(); + } + if (x) { + file_magwarn(ms, "Overflow for numeric type `%s' value %#" PRIx64, + type_tbl[m->type].name, ull); + } + } if (errno == 0) { *p = ep; eatsize(p); @@ -3271,22 +3356,35 @@ file_pstring_get_length(const struct magic *m, const char *ss) { size_t len = 0; const unsigned char *s = (const unsigned char *)ss; + unsigned int s3, s2, s1, s0; switch (m->str_flags & PSTRING_LEN) { case PSTRING_1_LE: len = *s; break; case PSTRING_2_LE: - len = (s[1] << 8) | s[0]; + s0 = s[0]; + s1 = s[1]; + len = (s1 << 8) | s0; break; case PSTRING_2_BE: - len = (s[0] << 8) | s[1]; + s0 = s[0]; + s1 = s[1]; + len = (s0 << 8) | s1; break; case PSTRING_4_LE: - len = (s[3] << 24) | (s[2] << 16) | (s[1] << 8) | s[0]; + s0 = s[0]; + s1 = s[1]; + s2 = s[2]; + s3 = s[3]; + len = (s3 << 24) | (s2 << 16) | (s1 << 8) | s0; break; case PSTRING_4_BE: - len = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; + s0 = s[0]; + s1 = s[1]; + s2 = s[2]; + s3 = s[3]; + len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3; break; default: abort(); /* Impossible */ diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c index d38e793612fc..accfb325b999 100644 --- a/contrib/file/src/cdf.c +++ b/contrib/file/src/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.85 2016/10/24 18:02:17 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.106 2017/04/30 17:05:02 christos Exp $") #endif #include @@ -80,6 +80,34 @@ static union { CDF_TOLE8(CAST(uint64_t, x)))) #define CDF_GETUINT32(x, y) cdf_getuint32(x, y) +#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n)) +#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n)) +#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u)) + + +static void * +cdf_malloc(const char *file __attribute__((__unused__)), + size_t line __attribute__((__unused__)), size_t n) +{ + DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n)); + return malloc(n); +} + +static void * +cdf_realloc(const char *file __attribute__((__unused__)), + size_t line __attribute__((__unused__)), void *p, size_t n) +{ + DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n)); + return realloc(p, n); +} + +static void * +cdf_calloc(const char *file __attribute__((__unused__)), + size_t line __attribute__((__unused__)), size_t n, size_t u) +{ + DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u)); + return calloc(n, u); +} /* * swap a short @@ -340,18 +368,18 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h) cdf_unpack_header(h, buf); cdf_swap_header(h); if (h->h_magic != CDF_MAGIC) { - DPRINTF(("Bad magic 0x%" INT64_T_FORMAT "x != 0x%" + DPRINTF(("Bad magic %#" INT64_T_FORMAT "x != %#" INT64_T_FORMAT "x\n", (unsigned long long)h->h_magic, (unsigned long long)CDF_MAGIC)); goto out; } if (h->h_sec_size_p2 > 20) { - DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2)); + DPRINTF(("Bad sector size %hu\n", h->h_sec_size_p2)); goto out; } if (h->h_short_sec_size_p2 > 20) { - DPRINTF(("Bad short sector size 0x%u\n", + DPRINTF(("Bad short sector size %hu\n", h->h_short_sec_size_p2)); goto out; } @@ -408,7 +436,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) if (h->h_master_sat[i] == CDF_SECID_FREE) break; -#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss)) +#define CDF_SEC_LIMIT (UINT32_MAX / (8 * ss)) if ((nsatpersec > 0 && h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) || i > CDF_SEC_LIMIT) { @@ -421,7 +449,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i; DPRINTF(("sat_len = %" SIZE_T_FORMAT "u ss = %" SIZE_T_FORMAT "u\n", sat->sat_len, ss)); - if ((sat->sat_tab = CAST(cdf_secid_t *, calloc(sat->sat_len, ss))) + if ((sat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(sat->sat_len, ss))) == NULL) return -1; @@ -435,7 +463,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) } } - if ((msa = CAST(cdf_secid_t *, calloc(1, ss))) == NULL) + if ((msa = CAST(cdf_secid_t *, CDF_CALLOC(1, ss))) == NULL) goto out1; mid = h->h_secid_first_sector_in_master_sat; @@ -527,13 +555,16 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, ssize_t nr; scn->sst_tab = NULL; scn->sst_len = cdf_count_chain(sat, sid, ss); - scn->sst_dirlen = len; + scn->sst_dirlen = MAX(h->h_min_size_standard_stream, len); scn->sst_ss = ss; + if (sid == CDF_SECID_END_OF_CHAIN || len == 0) + return cdf_zero_stream(scn); + if (scn->sst_len == (size_t)-1) goto out; - scn->sst_tab = calloc(scn->sst_len, ss); + scn->sst_tab = CDF_CALLOC(scn->sst_len, ss); if (scn->sst_tab == NULL) return cdf_zero_stream(scn); @@ -579,7 +610,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h, if (scn->sst_len == (size_t)-1) goto out; - scn->sst_tab = calloc(scn->sst_len, ss); + scn->sst_tab = CDF_CALLOC(scn->sst_len, ss); if (scn->sst_tab == NULL) return cdf_zero_stream(scn); @@ -637,11 +668,11 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, dir->dir_len = ns * nd; dir->dir_tab = CAST(cdf_directory_t *, - calloc(dir->dir_len, sizeof(dir->dir_tab[0]))); + CDF_CALLOC(dir->dir_len, sizeof(dir->dir_tab[0]))); if (dir->dir_tab == NULL) return -1; - if ((buf = CAST(char *, malloc(ss))) == NULL) { + if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) { free(dir->dir_tab); return -1; } @@ -687,7 +718,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h, if (ssat->sat_len == (size_t)-1) goto out; - ssat->sat_tab = CAST(cdf_secid_t *, calloc(ssat->sat_len, ss)); + ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss)); if (ssat->sat_tab == NULL) goto out1; @@ -808,13 +839,107 @@ cdf_find_stream(const cdf_dir_t *dir, const char *name, int type) == 0) break; if (i > 0) - return i; + return CAST(int, i); DPRINTF(("Cannot find type %d `%s'\n", type, name)); errno = ESRCH; return 0; } +#define CDF_SHLEN_LIMIT (UINT32_MAX / 8) +#define CDF_PROP_LIMIT (UINT32_MAX / (8 * sizeof(cdf_property_info_t))) + +static const void * +cdf_offset(const void *p, size_t l) +{ + return CAST(const void *, CAST(const uint8_t *, p) + l); +} + +static const uint8_t * +cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h, + const uint8_t *p, const uint8_t *e, size_t i) +{ + size_t tail = (i << 1) + 1; + size_t ofs; + const uint8_t *q; + + if (p >= e) { + DPRINTF(("Past end %p < %p\n", e, p)); + return NULL; + } + if (cdf_check_stream_offset(sst, h, p, (tail + 1) * sizeof(uint32_t), + __LINE__) == -1) + return NULL; + ofs = CDF_GETUINT32(p, tail); + q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p), + ofs - 2 * sizeof(uint32_t))); + + if (q < p) { + DPRINTF(("Wrapped around %p < %p\n", q, p)); + return NULL; + } + + if (q >= e) { + DPRINTF(("Ran off the end %p >= %p\n", q, e)); + return NULL; + } + return q; +} + +static cdf_property_info_t * +cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr) +{ + cdf_property_info_t *inp; + size_t newcount = *maxcount + incr; + + if (newcount > CDF_PROP_LIMIT) { + DPRINTF(("exceeded property limit %zu > %zu\n", + newcount, CDF_PROP_LIMIT)); + goto out; + } + inp = CAST(cdf_property_info_t *, + CDF_REALLOC(*info, newcount * sizeof(*inp))); + if (inp == NULL) + goto out; + + *info = inp; + *maxcount = newcount; + return inp; +out: + free(*info); + *maxcount = 0; + *info = NULL; + return NULL; +} + +static int +cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e, + size_t len) +{ + if (inp->pi_type & CDF_VECTOR) + return 0; + + if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len) + return 0; + + (void)memcpy(&inp->pi_val, p, len); + + switch (len) { + case 2: + inp->pi_u16 = CDF_TOLE2(inp->pi_u16); + break; + case 4: + inp->pi_u32 = CDF_TOLE4(inp->pi_u32); + break; + case 8: + inp->pi_u64 = CDF_TOLE8(inp->pi_u64); + break; + default: + abort(); + } + return 1; +} + int cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount) @@ -822,92 +947,69 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, const cdf_section_header_t *shp; cdf_section_header_t sh; const uint8_t *p, *q, *e; - int16_t s16; - int32_t s32; - uint32_t u32; - int64_t s64; - uint64_t u64; - cdf_timestamp_t tp; - size_t i, o, o4, nelements, j; + size_t i, o4, nelements, j, slen, left; cdf_property_info_t *inp; if (offs > UINT32_MAX / 4) { errno = EFTYPE; goto out; } - shp = CAST(const cdf_section_header_t *, (const void *) - ((const char *)sst->sst_tab + offs)); + shp = CAST(const cdf_section_header_t *, + cdf_offset(sst->sst_tab, offs)); if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp), __LINE__) == -1) goto out; sh.sh_len = CDF_TOLE4(shp->sh_len); -#define CDF_SHLEN_LIMIT (UINT32_MAX / 8) if (sh.sh_len > CDF_SHLEN_LIMIT) { errno = EFTYPE; goto out; } - sh.sh_properties = CDF_TOLE4(shp->sh_properties); -#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp))) - if (sh.sh_properties > CDF_PROP_LIMIT) + + if (cdf_check_stream_offset(sst, h, shp, sh.sh_len, __LINE__) == -1) goto out; + + sh.sh_properties = CDF_TOLE4(shp->sh_properties); DPRINTF(("section len: %u properties %u\n", sh.sh_len, sh.sh_properties)); - if (*maxcount) { - if (*maxcount > CDF_PROP_LIMIT) - goto out; - *maxcount += sh.sh_properties; - inp = CAST(cdf_property_info_t *, - realloc(*info, *maxcount * sizeof(*inp))); - } else { - *maxcount = sh.sh_properties; - inp = CAST(cdf_property_info_t *, - malloc(*maxcount * sizeof(*inp))); - } + if (sh.sh_properties > CDF_PROP_LIMIT) + goto out; + inp = cdf_grow_info(info, maxcount, sh.sh_properties); if (inp == NULL) - goto out1; - *info = inp; + goto out; inp += *count; *count += sh.sh_properties; - p = CAST(const uint8_t *, (const void *) - ((const char *)(const void *)sst->sst_tab + - offs + sizeof(sh))); - e = CAST(const uint8_t *, (const void *) - (((const char *)(const void *)shp) + sh.sh_len)); - if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) + p = CAST(const uint8_t *, cdf_offset(sst->sst_tab, offs + sizeof(sh))); + e = CAST(const uint8_t *, cdf_offset(shp, sh.sh_len)); + if (p >= e || cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) goto out; + for (i = 0; i < sh.sh_properties; i++) { - size_t tail = (i << 1) + 1; - size_t ofs; - if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), - __LINE__) == -1) + if ((q = cdf_get_property_info_pos(sst, h, p, e, i)) == NULL) goto out; - ofs = CDF_GETUINT32(p, tail); - q = (const uint8_t *)(const void *) - ((const char *)(const void *)p + ofs - - 2 * sizeof(uint32_t)); - if (q < p) { - DPRINTF(("Wrapped around %p < %p\n", q, p)); - goto out; - } - if (q > e) { - DPRINTF(("Ran of the end %p > %p\n", q, e)); - goto out; - } inp[i].pi_id = CDF_GETUINT32(p, i << 1); + left = CAST(size_t, e - q); + if (left < sizeof(uint32_t)) { + DPRINTF(("short info (no type)_\n")); + goto out; + } inp[i].pi_type = CDF_GETUINT32(q, 0); - DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n", + DPRINTF(("%" SIZE_T_FORMAT "u) id=%#x type=%#x offs=%#tx,%#x\n", i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); if (inp[i].pi_type & CDF_VECTOR) { + if (left < sizeof(uint32_t) * 2) { + DPRINTF(("missing CDF_VECTOR length\n")); + goto out; + } nelements = CDF_GETUINT32(q, 1); if (nelements == 0) { DPRINTF(("CDF_VECTOR with nelements == 0\n")); goto out; } - o = 2; + slen = 2; } else { nelements = 1; - o = 1; + slen = 1; } - o4 = o * sizeof(uint32_t); + o4 = slen * sizeof(uint32_t); if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED)) goto unknown; switch (inp[i].pi_type & CDF_TYPEMASK) { @@ -915,109 +1017,83 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, case CDF_EMPTY: break; case CDF_SIGNED16: - if (inp[i].pi_type & CDF_VECTOR) + if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int16_t))) goto unknown; - (void)memcpy(&s16, &q[o4], sizeof(s16)); - inp[i].pi_s16 = CDF_TOLE2(s16); break; case CDF_SIGNED32: - if (inp[i].pi_type & CDF_VECTOR) - goto unknown; - (void)memcpy(&s32, &q[o4], sizeof(s32)); - inp[i].pi_s32 = CDF_TOLE4((uint32_t)s32); - break; case CDF_BOOL: case CDF_UNSIGNED32: - if (inp[i].pi_type & CDF_VECTOR) + case CDF_FLOAT: + if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int32_t))) goto unknown; - (void)memcpy(&u32, &q[o4], sizeof(u32)); - inp[i].pi_u32 = CDF_TOLE4(u32); break; case CDF_SIGNED64: - if (inp[i].pi_type & CDF_VECTOR) - goto unknown; - (void)memcpy(&s64, &q[o4], sizeof(s64)); - inp[i].pi_s64 = CDF_TOLE8((uint64_t)s64); - break; case CDF_UNSIGNED64: - if (inp[i].pi_type & CDF_VECTOR) - goto unknown; - (void)memcpy(&u64, &q[o4], sizeof(u64)); - inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64); - break; - case CDF_FLOAT: - if (inp[i].pi_type & CDF_VECTOR) - goto unknown; - (void)memcpy(&u32, &q[o4], sizeof(u32)); - u32 = CDF_TOLE4(u32); - memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f)); - break; case CDF_DOUBLE: - if (inp[i].pi_type & CDF_VECTOR) + case CDF_FILETIME: + if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int64_t))) goto unknown; - (void)memcpy(&u64, &q[o4], sizeof(u64)); - u64 = CDF_TOLE8((uint64_t)u64); - memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d)); break; case CDF_LENGTH32_STRING: case CDF_LENGTH32_WSTRING: if (nelements > 1) { size_t nelem = inp - *info; - if (*maxcount > CDF_PROP_LIMIT - || nelements > CDF_PROP_LIMIT) - goto out; - *maxcount += nelements; - inp = CAST(cdf_property_info_t *, - realloc(*info, *maxcount * sizeof(*inp))); + inp = cdf_grow_info(info, maxcount, nelements); if (inp == NULL) - goto out1; - *info = inp; - inp = *info + nelem; + goto out; + inp += nelem; } DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", nelements)); for (j = 0; j < nelements && i < sh.sh_properties; j++, i++) { - uint32_t l = CDF_GETUINT32(q, o); + uint32_t l; + + if (o4 + sizeof(uint32_t) > left) + goto out; + + l = CDF_GETUINT32(q, slen); + o4 += sizeof(uint32_t); + if (o4 + l > left) + goto out; + inp[i].pi_str.s_len = l; - inp[i].pi_str.s_buf = (const char *) - (const void *)(&q[o4 + sizeof(l)]); - DPRINTF(("l = %d, r = %" SIZE_T_FORMAT - "u, s = %s\n", l, - CDF_ROUND(l, sizeof(l)), + inp[i].pi_str.s_buf = CAST(const char *, + CAST(const void *, &q[o4])); + + DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT + "u), t=%zu s=%s\n", o4, l, + CDF_ROUND(l, sizeof(l)), left, inp[i].pi_str.s_buf)); + if (l & 1) l++; - o += l >> 1; - if (q + o >= e) - goto out; - o4 = o * sizeof(uint32_t); + + slen += l >> 1; + o4 = slen * sizeof(uint32_t); } i--; break; - case CDF_FILETIME: - if (inp[i].pi_type & CDF_VECTOR) - goto unknown; - (void)memcpy(&tp, &q[o4], sizeof(tp)); - inp[i].pi_tp = CDF_TOLE8((uint64_t)tp); - break; case CDF_CLIPBOARD: if (inp[i].pi_type & CDF_VECTOR) goto unknown; break; default: unknown: - DPRINTF(("Don't know how to deal with %x\n", + memset(&inp[i].pi_val, 0, sizeof(inp[i].pi_val)); + DPRINTF(("Don't know how to deal with %#x\n", inp[i].pi_type)); break; } } return 0; out: - errno = EFTYPE; -out1: free(*info); + *info = NULL; + *count = 0; + *maxcount = 0; + errno = EFTYPE; return -1; } @@ -1065,7 +1141,7 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, { size_t ss = cdf_check_stream(sst, h); const char *b = CAST(const char *, sst->sst_tab); - const char *eb = b + ss * sst->sst_len; + const char *nb, *eb = b + ss * sst->sst_len; size_t nr, i, j, k; cdf_catalog_entry_t *ce; uint16_t reclen; @@ -1084,7 +1160,7 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, return -1; nr--; *cat = CAST(cdf_catalog_t *, - malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce))); + CDF_MALLOC(sizeof(cdf_catalog_t) + nr * sizeof(*ce))); if (*cat == NULL) return -1; ce = (*cat)->cat_e; @@ -1110,7 +1186,9 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, cep->ce_namlen = rlen; np = CAST(const uint16_t *, CAST(const void *, (b + 16))); - if (RCAST(const char *, np + cep->ce_namlen) > eb) { + nb = CAST(const char *, CAST(const void *, + (np + cep->ce_namlen))); + if (nb > eb) { cep->ce_namlen = 0; break; } @@ -1169,7 +1247,7 @@ cdf_print_property_name(char *buf, size_t bufsiz, uint32_t p) for (i = 0; i < __arraycount(vn); i++) if (vn[i].v == p) return snprintf(buf, bufsiz, "%s", vn[i].n); - return snprintf(buf, bufsiz, "0x%x", p); + return snprintf(buf, bufsiz, "%#x", p); } int @@ -1228,7 +1306,7 @@ cdf_dump_header(const cdf_header_t *h) h->h_ ## b, 1 << h->h_ ## b) DUMP("%d", revision); DUMP("%d", version); - DUMP("0x%x", byte_order); + DUMP("%#x", byte_order); DUMP2("%d", sec_size_p2); DUMP2("%d", short_sec_size_p2); DUMP("%d", num_sectors_in_sat); @@ -1322,7 +1400,7 @@ cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h, d->d_color ? "black" : "red"); (void)fprintf(stderr, "Left child: %d\n", d->d_left_child); (void)fprintf(stderr, "Right child: %d\n", d->d_right_child); - (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags); + (void)fprintf(stderr, "Flags: %#x\n", d->d_flags); cdf_timestamp_to_timespec(&ts, d->d_created); (void)fprintf(stderr, "Created %s", cdf_ctime(&ts.tv_sec, buf)); cdf_timestamp_to_timespec(&ts, d->d_modified); @@ -1415,7 +1493,7 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32); break; default: - DPRINTF(("Don't know how to deal with %x\n", + DPRINTF(("Don't know how to deal with %#x\n", info[i].pi_type)); break; } @@ -1434,7 +1512,7 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst) (void)&h; if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1) return; - (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); + (void)fprintf(stderr, "Endian: %#x\n", ssi.si_byte_order); (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, ssi.si_os_version >> 8); (void)fprintf(stderr, "Os %d\n", ssi.si_os); diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h index 0b345ab49615..f2df8306b17d 100644 --- a/contrib/file/src/cdf.h +++ b/contrib/file/src/cdf.h @@ -127,9 +127,9 @@ typedef struct { typedef struct { void *sst_tab; - size_t sst_len; - size_t sst_dirlen; - size_t sst_ss; + size_t sst_len; /* Number of sectors */ + size_t sst_dirlen; /* Directory sector size */ + size_t sst_ss; /* Sector size */ } cdf_stream_t; typedef struct { diff --git a/contrib/file/src/cdf_time.c b/contrib/file/src/cdf_time.c index 1e572de539f8..2bdcd2a7f7a8 100644 --- a/contrib/file/src/cdf_time.c +++ b/contrib/file/src/cdf_time.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf_time.c,v 1.15 2014/05/14 23:15:42 christos Exp $") +FILE_RCSID("@(#)$File: cdf_time.c,v 1.16 2017/03/29 15:57:48 christos Exp $") #endif #include @@ -171,7 +171,7 @@ cdf_ctime(const time_t *sec, char *buf) char *ptr = ctime_r(sec, buf); if (ptr != NULL) return buf; - (void)snprintf(buf, 26, "*Bad* 0x%16.16" INT64_T_FORMAT "x\n", + (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n", (long long)*sec); return buf; } diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c index 95f095529da5..2f789cd2bc44 100644 --- a/contrib/file/src/compress.c +++ b/contrib/file/src/compress.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: compress.c,v 1.100 2016/10/24 18:02:17 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.105 2017/05/25 00:13:03 christos Exp $") #endif #include "magic.h" @@ -62,7 +62,7 @@ typedef void (*sig_t)(int); #if defined(HAVE_SYS_TIME_H) #include #endif -#if defined(HAVE_ZLIB_H) +#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT) #define BUILTIN_DECOMPRESS #include #endif @@ -83,6 +83,7 @@ int tty = -1; /* * The following python code is not really used because ZLIBSUPPORT is only * defined if we have a built-in zlib, and the built-in zlib handles that. + * That is not true for android where we have zlib.h and not -lz. */ static const char zlibcode[] = "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))"; @@ -93,7 +94,7 @@ static int zlibcmp(const unsigned char *buf) { unsigned short x = 1; - unsigned char *s = (unsigned char *)&x; + unsigned char *s = CAST(unsigned char *, CAST(void *, &x)); if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0) return 0; @@ -497,7 +498,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch, z.next_in = CCAST(Bytef *, old); z.avail_in = CAST(uint32_t, *n); z.next_out = *newch; - z.avail_out = bytes_max; + z.avail_out = CAST(unsigned int, bytes_max); z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; @@ -632,7 +633,7 @@ filter_error(unsigned char *ubuf, ssize_t n) while (isspace((unsigned char)*p)) p++; n = strlen(p); - memmove(ubuf, p, n + 1); + memmove(ubuf, p, CAST(size_t, n + 1)); } DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf); if (islower(*ubuf)) @@ -688,7 +689,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, } for (i = 0; i < __arraycount(fdp); i++) - copydesc(i, fdp[i]); + copydesc(CAST(int, i), fdp[i]); (void)execvp(compr[method].argv[0], (char *const *)(intptr_t)compr[method].argv); @@ -748,9 +749,9 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, rv = makeerror(newch, n, "Wait failed, %s", strerror(errno)); DPRINTF("Child wait return %#x\n", status); } else if (!WIFEXITED(status)) { - DPRINTF("Child not exited (0x%x)\n", status); + DPRINTF("Child not exited (%#x)\n", status); } else if (WEXITSTATUS(status) != 0) { - DPRINTF("Child exited (0x%d)\n", WEXITSTATUS(status)); + DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status)); } closefd(fdp[STDIN_FILENO], 0); diff --git a/contrib/file/src/der.c b/contrib/file/src/der.c index 8ae638fb9897..4e22caf41d4a 100644 --- a/contrib/file/src/der.c +++ b/contrib/file/src/der.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: der.c,v 1.10 2016/10/24 18:02:17 christos Exp $") +FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $") #endif #endif @@ -159,31 +159,49 @@ gettag(const uint8_t *c, size_t *p, size_t l) return tag; } +/* + * Read the length of a DER tag from the input. + * + * `c` is the input, `p` is an output parameter that specifies how much of the + * input we consumed, and `l` is the maximum input length. + * + * Returns the length, or DER_BAD if the end of the input is reached or the + * length exceeds the remaining input. + */ static uint32_t getlength(const uint8_t *c, size_t *p, size_t l) { uint8_t digits, i; size_t len; + int is_onebyte_result; if (*p >= l) return DER_BAD; - digits = c[(*p)++]; - - if ((digits & 0x80) == 0) - return digits; - - digits &= 0x7f; - len = 0; - + /* + * Digits can either be 0b0 followed by the result, or 0b1 + * followed by the number of digits of the result. In either case, + * we verify that we can read so many bytes from the input. + */ + is_onebyte_result = (c[*p] & 0x80) == 0; + digits = c[(*p)++] & 0x7f; if (*p + digits >= l) return DER_BAD; + if (is_onebyte_result) + return digits; + + /* + * Decode len. We've already verified that we're allowed to read + * `digits` bytes. + */ + len = 0; for (i = 0; i < digits; i++) len = (len << 8) | c[(*p)++]; + if (*p + len >= l) return DER_BAD; - return len; + return CAST(uint32_t, len); } static const char * @@ -242,12 +260,12 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes) #endif if (m->cont_level != 0) { if (offs + tlen > nbytes) - return DER_BAD; - ms->c.li[m->cont_level - 1].off = offs + tlen; + return -1; + ms->c.li[m->cont_level - 1].off = CAST(int, offs + tlen); DPRINTF(("cont_level[%u] = %u\n", m->cont_level - 1, ms->c.li[m->cont_level - 1].off)); } - return offs; + return CAST(int32_t, offs); } int diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h index 180efd3525ce..eb9c05421db6 100644 --- a/contrib/file/src/file.h +++ b/contrib/file/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.180 2016/07/20 11:27:08 christos Exp $ + * @(#)$File: file.h,v 1.183 2017/08/28 13:39:18 christos Exp $ */ #ifndef __file_h__ @@ -36,6 +36,10 @@ #ifdef HAVE_CONFIG_H #include #endif +#ifdef HAVE_STDINT_H +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif #ifdef WIN32 #ifdef _WIN64 @@ -50,16 +54,12 @@ #define INT64_T_FORMAT "ll" #define INTMAX_T_FORMAT "j" #endif +#include +#endif #include /* Include that here, to make sure __P gets defined */ #include #include /* For open and flags */ -#ifdef HAVE_STDINT_H -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS -#endif -#include -#endif #ifdef HAVE_INTTYPES_H #include #endif @@ -447,7 +447,7 @@ protected size_t file_printedlen(const struct magic_set *); protected int file_replace(struct magic_set *, const char *, const char *); protected int file_printf(struct magic_set *, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); -protected int file_reset(struct magic_set *); +protected int file_reset(struct magic_set *, int); protected int file_tryelf(struct magic_set *, int, const unsigned char *, size_t); protected int file_trycdf(struct magic_set *, int, const unsigned char *, diff --git a/contrib/file/src/fsmagic.c b/contrib/file/src/fsmagic.c index 27f982a58348..c0a437a8f6d0 100644 --- a/contrib/file/src/fsmagic.c +++ b/contrib/file/src/fsmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: fsmagic.c,v 1.76 2015/04/09 20:01:41 christos Exp $") +FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $") #endif /* lint */ #include "magic.h" @@ -104,14 +104,13 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) { int ret, did = 0; int mime = ms->flags & MAGIC_MIME; + int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION); #ifdef S_IFLNK char buf[BUFSIZ+4]; ssize_t nch; struct stat tstatbuf; #endif - if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) - return 0; if (fn == NULL) return 0; @@ -168,7 +167,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) } ret = 1; - if (!mime) { + if (!mime && !silent) { #ifdef S_ISUID if (sb->st_mode & S_ISUID) if (file_printf(ms, "%ssetuid", COMMA) == -1) @@ -191,6 +190,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "directory") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%sdirectory", COMMA) == -1) return -1; break; @@ -208,6 +208,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "chardevice") == -1) return -1; + } else if (silent) { } else { #ifdef HAVE_STRUCT_STAT_ST_RDEV # ifdef dv_unit @@ -242,6 +243,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "blockdevice") == -1) return -1; + } else if (silent) { } else { #ifdef HAVE_STRUCT_STAT_ST_RDEV # ifdef dv_unit @@ -270,6 +272,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "fifo") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1) return -1; break; @@ -279,6 +282,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "door") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%sdoor", COMMA) == -1) return -1; break; @@ -294,6 +298,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "symlink") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%sunreadable symlink `%s' (%s)", COMMA, fn, strerror(errno)) == -1) @@ -323,6 +328,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (handle_mime(ms, mime, "x-path-too-long") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%spath too long: `%s'", COMMA, fn) == -1) @@ -352,6 +358,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "symlink") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%ssymbolic link to %s", COMMA, buf) == -1) return -1; @@ -364,6 +371,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "socket") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%ssocket", COMMA) == -1) return -1; break; @@ -386,6 +394,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (mime) { if (handle_mime(ms, mime, "x-empty") == -1) return -1; + } else if (silent) { } else if (file_printf(ms, "%sempty", COMMA) == -1) return -1; break; @@ -399,7 +408,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) /*NOTREACHED*/ } - if (!mime && did && ret == 0) { + if (!silent && !mime && did && ret == 0) { if (file_printf(ms, " ") == -1) return -1; } diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c index c8918a45963a..d7a18f451a7e 100644 --- a/contrib/file/src/funcs.c +++ b/contrib/file/src/funcs.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.90 2016/10/19 20:51:17 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.93 2017/08/28 13:39:18 christos Exp $") #endif /* lint */ #include "magic.h" @@ -76,7 +76,7 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap) ms->o.buf = buf; return 0; out: - file_error(ms, errno, "vasprintf failed"); + fprintf(stderr, "vasprintf failed (%s)", strerror(errno)); return -1; } @@ -328,9 +328,9 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u #endif protected int -file_reset(struct magic_set *ms) +file_reset(struct magic_set *ms, int checkloaded) { - if (ms->mlist[0] == NULL) { + if (checkloaded && ms->mlist[0] == NULL) { file_error(ms, 0, "no magic files loaded"); return -1; } @@ -509,6 +509,8 @@ file_regexec(file_regex_t *rx, const char *str, size_t nmatch, regmatch_t* pmatch, int eflags) { assert(rx->rc == 0); + /* XXX: force initialization because glibc does not always do this */ + memset(pmatch, 0, nmatch * sizeof(*pmatch)); return regexec(&rx->rx, str, nmatch, pmatch, eflags); } diff --git a/contrib/file/src/is_tar.c b/contrib/file/src/is_tar.c index a3e5dbf24c36..1953a7fc102e 100644 --- a/contrib/file/src/is_tar.c +++ b/contrib/file/src/is_tar.c @@ -40,7 +40,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: is_tar.c,v 1.38 2015/04/09 20:01:41 christos Exp $") +FILE_RCSID("@(#)$File: is_tar.c,v 1.39 2017/03/17 20:45:01 christos Exp $") #endif #include "magic.h" @@ -51,7 +51,7 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.38 2015/04/09 20:01:41 christos Exp $") #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) private int is_tar(const unsigned char *, size_t); -private int from_oct(int, const char *); /* Decode octal number */ +private int from_oct(const char *, size_t); /* Decode octal number */ static const char tartype[][32] = { "tar archive", @@ -93,31 +93,35 @@ private int is_tar(const unsigned char *buf, size_t nbytes) { const union record *header = (const union record *)(const void *)buf; - int i; - int sum, recsum; - const unsigned char *p; + size_t i; + int sum, recsum; + const unsigned char *p, *ep; - if (nbytes < sizeof(union record)) + if (nbytes < sizeof(*header)) return 0; - recsum = from_oct(8, header->header.chksum); + recsum = from_oct(header->header.chksum, sizeof(header->header.chksum)); sum = 0; p = header->charptr; - for (i = sizeof(union record); --i >= 0;) + ep = header->charptr + sizeof(*header); + while (p < ep) sum += *p++; /* Adjust checksum to count the "chksum" field as blanks. */ - for (i = sizeof(header->header.chksum); --i >= 0;) + for (i = 0; i < sizeof(header->header.chksum); i++) sum -= header->header.chksum[i]; - sum += ' ' * sizeof header->header.chksum; + sum += ' ' * sizeof(header->header.chksum); if (sum != recsum) return 0; /* Not a tar archive */ - if (strcmp(header->header.magic, GNUTMAGIC) == 0) + if (strncmp(header->header.magic, GNUTMAGIC, + sizeof(header->header.magic)) == 0) return 3; /* GNU Unix Standard tar archive */ - if (strcmp(header->header.magic, TMAGIC) == 0) + + if (strncmp(header->header.magic, TMAGIC, + sizeof(header->header.magic)) == 0) return 2; /* Unix Standard tar archive */ return 1; /* Old fashioned tar archive */ @@ -130,19 +134,22 @@ is_tar(const unsigned char *buf, size_t nbytes) * Result is -1 if the field is invalid (all blank, or non-octal). */ private int -from_oct(int digs, const char *where) +from_oct(const char *where, size_t digs) { int value; + if (digs == 0) + return -1; + while (isspace((unsigned char)*where)) { /* Skip spaces */ where++; - if (--digs <= 0) + if (digs-- == 0) return -1; /* All blank field */ } value = 0; while (digs > 0 && isodigit(*where)) { /* Scan til non-octal */ value = (value << 3) | (*where++ - '0'); - --digs; + digs--; } if (digs > 0 && *where && !isspace((unsigned char)*where)) diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c index b61ad29d7a5d..1448a69bcad5 100644 --- a/contrib/file/src/magic.c +++ b/contrib/file/src/magic.c @@ -33,7 +33,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.100 2016/07/18 11:43:05 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $") #endif /* lint */ #include "magic.h" @@ -167,7 +167,7 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, { if (fdwReason == DLL_PROCESS_ATTACH) _w32_dll_instance = hinstDLL; - return TRUE; + return 1; } #endif @@ -409,7 +409,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) int ispipe = 0; off_t pos = (off_t)-1; - if (file_reset(ms) == -1) + if (file_reset(ms, 1) == -1) goto out; /* @@ -538,7 +538,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb) { if (ms == NULL) return NULL; - if (file_reset(ms) == -1) + if (file_reset(ms, 1) == -1) return NULL; /* * The main work is done here! @@ -567,6 +567,15 @@ magic_errno(struct magic_set *ms) return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0; } +public int +magic_getflags(struct magic_set *ms) +{ + if (ms == NULL) + return -1; + + return ms->flags; +} + public int magic_setflags(struct magic_set *ms, int flags) { diff --git a/contrib/file/src/magic.h.in b/contrib/file/src/magic.h.in index 3d6954a2a6d4..1134bdc886d4 100644 --- a/contrib/file/src/magic.h.in +++ b/contrib/file/src/magic.h.in @@ -73,6 +73,35 @@ 0 \ ) +#define MAGIC_SNPRINTB "\177\020\ +b\0debug\0\ +b\1symlink\0\ +b\2compress\0\ +b\3devices\0\ +b\4mime_type\0\ +b\5continue\0\ +b\6check\0\ +b\7preserve_atime\0\ +b\10raw\0\ +b\11error\0\ +b\12mime_encoding\0\ +b\13apple\0\ +b\14no_check_compress\0\ +b\15no_check_tar\0\ +b\16no_check_soft\0\ +b\17no_check_sapptype\0\ +b\20no_check_elf\0\ +b\21no_check_text\0\ +b\22no_check_cdf\0\ +b\23no_check_reserved0\0\ +b\24no_check_tokens\0\ +b\25no_check_encoding\0\ +b\26no_check_reserved1\0\ +b\27no_check_reserved2\0\ +b\30extension\0\ +b\31transp_compression\0\ +" + /* Defined for backwards compatibility (renamed) */ #define MAGIC_NO_CHECK_ASCII MAGIC_NO_CHECK_TEXT @@ -97,6 +126,7 @@ const char *magic_descriptor(magic_t, int); const char *magic_buffer(magic_t, const void *, size_t); const char *magic_error(magic_t); +int magic_getflags(magic_t); int magic_setflags(magic_t, int); int magic_version(void); diff --git a/contrib/file/src/print.c b/contrib/file/src/print.c index a0221b126ecb..0b918636bc5e 100644 --- a/contrib/file/src/print.c +++ b/contrib/file/src/print.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: print.c,v 1.81 2016/01/19 15:09:03 christos Exp $") +FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $") #endif /* lint */ #include @@ -238,7 +238,7 @@ file_fmttime(uint64_t v, int flags, char *buf) if (flags & FILE_T_WINDOWS) { struct timespec ts; - cdf_timestamp_to_timespec(&ts, v); + cdf_timestamp_to_timespec(&ts, CAST(cdf_timestamp_t, v)); t = ts.tv_sec; } else { // XXX: perhaps detect and print something if overflow diff --git a/contrib/file/src/readcdf.c b/contrib/file/src/readcdf.c index 20e631d6db6f..80c8d26e3fec 100644 --- a/contrib/file/src/readcdf.c +++ b/contrib/file/src/readcdf.c @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.63 2016/10/18 22:25:42 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.65 2017/04/08 20:58:03 christos Exp $") #endif #include @@ -152,7 +152,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, struct timespec ts; char buf[64]; const char *str = NULL; - const char *s; + const char *s, *e; int len; if (!NOTMIME(ms) && root_storage) @@ -199,7 +199,9 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, if (info[i].pi_type == CDF_LENGTH32_WSTRING) k++; s = info[i].pi_str.s_buf; - for (j = 0; j < sizeof(vbuf) && len--; s += k) { + e = info[i].pi_str.s_buf + len; + for (j = 0; s < e && j < sizeof(vbuf) + && len--; s += k) { if (*s == '\0') break; if (isprint((unsigned char)*s)) @@ -603,7 +605,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, if ((i = cdf_read_user_stream(&info, &h, &sat, &ssat, &sst, &dir, "FileHeader", &scn)) != -1) { #define HWP5_SIGNATURE "HWP Document File" - if (scn.sst_dirlen >= sizeof(HWP5_SIGNATURE) - 1 + if (scn.sst_len * scn.sst_ss >= sizeof(HWP5_SIGNATURE) - 1 && memcmp(scn.sst_tab, HWP5_SIGNATURE, sizeof(HWP5_SIGNATURE) - 1) == 0) { if (NOTMIME(ms)) { diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c index f3212871d625..5f425c974e76 100644 --- a/contrib/file/src/readelf.c +++ b/contrib/file/src/readelf.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.128 2016/10/04 21:43:10 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.138 2017/08/27 07:55:02 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -310,16 +310,18 @@ private const char os_style_names[][8] = { "NetBSD", }; -#define FLAGS_DID_CORE 0x001 -#define FLAGS_DID_OS_NOTE 0x002 -#define FLAGS_DID_BUILD_ID 0x004 -#define FLAGS_DID_CORE_STYLE 0x008 -#define FLAGS_DID_NETBSD_PAX 0x010 -#define FLAGS_DID_NETBSD_MARCH 0x020 -#define FLAGS_DID_NETBSD_CMODEL 0x040 -#define FLAGS_DID_NETBSD_UNKNOWN 0x080 -#define FLAGS_IS_CORE 0x100 -#define FLAGS_DID_AUXV 0x200 +#define FLAGS_CORE_STYLE 0x003 + +#define FLAGS_DID_CORE 0x004 +#define FLAGS_DID_OS_NOTE 0x008 +#define FLAGS_DID_BUILD_ID 0x010 +#define FLAGS_DID_CORE_STYLE 0x020 +#define FLAGS_DID_NETBSD_PAX 0x040 +#define FLAGS_DID_NETBSD_MARCH 0x080 +#define FLAGS_DID_NETBSD_CMODEL 0x100 +#define FLAGS_DID_NETBSD_UNKNOWN 0x200 +#define FLAGS_IS_CORE 0x400 +#define FLAGS_DID_AUXV 0x800 private int dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, @@ -709,32 +711,30 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, == -1) return 1; *flags |= FLAGS_DID_CORE_STYLE; + *flags |= os_style; } switch (os_style) { case OS_STYLE_NETBSD: if (type == NT_NETBSD_CORE_PROCINFO) { char sbuf[512]; - uint32_t signo; - /* - * Extract the program name. It is at - * offset 0x7c, and is up to 32-bytes, - * including the terminating NUL. - */ - if (file_printf(ms, ", from '%.31s'", + struct NetBSD_elfcore_procinfo pi; + memset(&pi, 0, sizeof(pi)); + memcpy(&pi, nbuf + doff, descsz); + + if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, " + "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)", file_printable(sbuf, sizeof(sbuf), - (const char *)&nbuf[doff + 0x7c])) == -1) - return 1; - - /* - * Extract the signal number. It is at - * offset 0x08. - */ - (void)memcpy(&signo, &nbuf[doff + 0x08], - sizeof(signo)); - if (file_printf(ms, " (signal %u)", - elf_getu32(swap, signo)) == -1) + CAST(char *, pi.cpi_name)), + elf_getu32(swap, pi.cpi_pid), + elf_getu32(swap, pi.cpi_euid), + elf_getu32(swap, pi.cpi_egid), + elf_getu32(swap, pi.cpi_nlwps), + elf_getu32(swap, pi.cpi_siglwp), + elf_getu32(swap, pi.cpi_signo), + elf_getu32(swap, pi.cpi_sigcode)) == -1) return 1; + *flags |= FLAGS_DID_CORE; return 1; } @@ -890,7 +890,7 @@ get_string_on_virtaddr(struct magic_set *ms, offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num, fsize, virtaddr); - if ((buflen = pread(fd, buf, buflen, offset)) <= 0) { + if ((buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) { file_badread(ms); return 0; } @@ -924,9 +924,29 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int is_string; size_t nval; - if (type != NT_AUXV || (*flags & FLAGS_IS_CORE) == 0) + if ((*flags & (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE)) != + (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE)) return 0; + switch (*flags & FLAGS_CORE_STYLE) { + case OS_STYLE_SVR4: + if (type != NT_AUXV) + return 0; + break; +#ifdef notyet + case OS_STYLE_NETBSD: + if (type != NT_NETBSD_CORE_AUXV) + return 0; + break; + case OS_STYLE_FREEBSD: + if (type != NT_FREEBSD_PROCSTAT_AUXV) + return 0; + break; +#endif + default: + return 0; + } + *flags |= FLAGS_DID_AUXV; nval = 0; @@ -1031,13 +1051,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, } if (namesz & 0x80000000) { - (void)file_printf(ms, ", bad note name size 0x%lx", + (void)file_printf(ms, ", bad note name size %#lx", (unsigned long)namesz); return 0; } if (descsz & 0x80000000) { - (void)file_printf(ms, ", bad note description size 0x%lx", + (void)file_printf(ms, ", bad note description size %#lx", (unsigned long)descsz); return 0; } @@ -1185,12 +1205,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, { Elf32_Shdr sh32; Elf64_Shdr sh64; - int stripped = 1; + int stripped = 1, has_debug_info = 0; size_t nbadcap = 0; void *nbuf; off_t noff, coff, name_off; - uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ - uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ + uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilities */ + uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilities */ char name[50]; ssize_t namesize; @@ -1203,8 +1223,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, /* Read offset of name section to be able to read section names later */ if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab))) < (ssize_t)xsh_sizeof) { - file_badread(ms); - return -1; + if (file_printf(ms, ", missing section headers") == -1) + return -1; + return 0; } name_off = xsh_offset; @@ -1215,8 +1236,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, return -1; } name[namesize] = '\0'; - if (strcmp(name, ".debug_info") == 0) + if (strcmp(name, ".debug_info") == 0) { + has_debug_info = 1; stripped = 0; + } if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) { file_badread(ms); @@ -1247,9 +1270,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if ((uintmax_t)(xsh_size + xsh_offset) > (uintmax_t)fsize) { if (file_printf(ms, - ", note offset/size 0x%" INTMAX_T_FORMAT - "x+0x%" INTMAX_T_FORMAT "x exceeds" - " file size 0x%" INTMAX_T_FORMAT "x", + ", note offset/size %#" INTMAX_T_FORMAT + "x+%#" INTMAX_T_FORMAT "x exceeds" + " file size %#" INTMAX_T_FORMAT "x", (uintmax_t)xsh_offset, (uintmax_t)xsh_size, (uintmax_t)fsize) == -1) return -1; @@ -1353,7 +1376,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, default: if (file_printf(ms, ", with unknown capability " - "0x%" INT64_T_FORMAT "x = 0x%" + "%#" INT64_T_FORMAT "x = %#" INT64_T_FORMAT "x", (unsigned long long)xcap_tag, (unsigned long long)xcap_val) == -1) @@ -1370,6 +1393,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } } + if (has_debug_info) { + if (file_printf(ms, ", with debug_info") == -1) + return -1; + } if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1) return -1; if (cap_hw1) { @@ -1403,13 +1430,13 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } if (cap_hw1) if (file_printf(ms, - " unknown hardware capability 0x%" + " unknown hardware capability %#" INT64_T_FORMAT "x", (unsigned long long)cap_hw1) == -1) return -1; } else { if (file_printf(ms, - " hardware capability 0x%" INT64_T_FORMAT "x", + " hardware capability %#" INT64_T_FORMAT "x", (unsigned long long)cap_hw1) == -1) return -1; } @@ -1425,7 +1452,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, cap_sf1 &= ~SF1_SUNW_MASK; if (cap_sf1) if (file_printf(ms, - ", with unknown software capability 0x%" + ", with unknown software capability %#" INT64_T_FORMAT "x", (unsigned long long)cap_sf1) == -1) return -1; @@ -1479,7 +1506,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, if (((align = xph_align) & 0x80000000UL) != 0 || align < 4) { if (file_printf(ms, - ", invalid note alignment 0x%lx", + ", invalid note alignment %#lx", (unsigned long)align) == -1) return -1; align = 4; diff --git a/contrib/file/src/readelf.h b/contrib/file/src/readelf.h index f443b298585c..ef880b9cbe22 100644 --- a/contrib/file/src/readelf.h +++ b/contrib/file/src/readelf.h @@ -141,7 +141,7 @@ typedef struct { #define SHT_SYMTAB 2 #define SHT_NOTE 7 #define SHT_DYNSYM 11 -#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilites */ +#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilities */ /* elf type */ #define ELFDATANONE 0 /* e_ident[EI_DATA] */ @@ -230,6 +230,33 @@ typedef struct { } Elf64_Shdr; #define NT_NETBSD_CORE_PROCINFO 1 +#define NT_NETBSD_CORE_AUXV 2 + +struct NetBSD_elfcore_procinfo { + /* Version 1 fields start here. */ + uint32_t cpi_version; /* our version */ + uint32_t cpi_cpisize; /* sizeof(this struct) */ + uint32_t cpi_signo; /* killing signal */ + uint32_t cpi_sigcode; /* signal code */ + uint32_t cpi_sigpend[4]; /* pending signals */ + uint32_t cpi_sigmask[4]; /* blocked signals */ + uint32_t cpi_sigignore[4]; /* ignored signals */ + uint32_t cpi_sigcatch[4]; /* caught signals */ + int32_t cpi_pid; /* process ID */ + int32_t cpi_ppid; /* parent process ID */ + int32_t cpi_pgrp; /* process group ID */ + int32_t cpi_sid; /* session ID */ + uint32_t cpi_ruid; /* real user ID */ + uint32_t cpi_euid; /* effective user ID */ + uint32_t cpi_svuid; /* saved user ID */ + uint32_t cpi_rgid; /* real group ID */ + uint32_t cpi_egid; /* effective group ID */ + uint32_t cpi_svgid; /* saved group ID */ + uint32_t cpi_nlwps; /* number of LWPs */ + int8_t cpi_name[32]; /* copy of p->p_comm */ + /* Add version 2 fields below here. */ + int32_t cpi_siglwp; /* LWP target of killing signal */ +}; /* Note header in a PT_NOTE section */ typedef struct elf_note { @@ -328,6 +355,11 @@ typedef struct { */ #define NT_NETBSD_CMODEL 6 +/* + * FreeBSD specific notes + */ +#define NT_FREEBSD_PROCSTAT_AUXV 16 + #if !defined(ELFSIZE) && defined(ARCH_ELFSIZE) #define ELFSIZE ARCH_ELFSIZE #endif diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c index 0e9d433ddd99..b9e975374b40 100644 --- a/contrib/file/src/softmagic.c +++ b/contrib/file/src/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.238 2016/10/24 18:02:17 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $") #endif /* lint */ #include "magic.h" @@ -192,6 +192,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) magindex++; + cont_level = 0; continue; /* Skip to next top-level test*/ } @@ -370,6 +371,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, case -1: case 0: flush = 1; + cont_level--; break; default: break; @@ -1017,9 +1019,8 @@ private int mconvert(struct magic_set *ms, struct magic *m, int flip) { union VALUETYPE *p = &ms->ms_value; - uint8_t type; - switch (type = cvt_flip(m->type, flip)) { + switch (cvt_flip(m->type, flip)) { case FILE_BYTE: if (cvt_8(p, m) == -1) goto out; @@ -1184,7 +1185,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, case FILE_DER: case FILE_SEARCH: if (offset > nbytes) - offset = nbytes; + offset = CAST(uint32_t, nbytes); ms->search.s = RCAST(const char *, s) + offset; ms->search.s_len = nbytes - offset; ms->search.offset = offset; @@ -1198,7 +1199,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, const char *end; size_t lines, linecnt, bytecnt; - if (s == NULL) { + if (s == NULL || nbytes < offset) { ms->search.s_len = 0; ms->search.s = NULL; return 0; @@ -1260,7 +1261,8 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, if (*dst == '\0') { if (type == FILE_BESTRING16 ? *(src - 1) != '\0' : - *(src + 1) != '\0') + ((src + 1 < esrc) && + *(src + 1) != '\0')) *dst = ' '; } } @@ -1365,7 +1367,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return -1; if ((ms->flags & MAGIC_DEBUG) != 0) { - fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%" + fprintf(stderr, "mget(type=%d, flag=%#x, offset=%u, o=%" SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT "u, il=%hu, nc=%hu)\n", m->type, m->flag, offset, o, nbytes, @@ -1632,6 +1634,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) */ const unsigned char *a = (const unsigned char *)s1; const unsigned char *b = (const unsigned char *)s2; + const unsigned char *eb = b + len; uint64_t v; /* @@ -1646,6 +1649,10 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) } else { /* combine the others */ while (len-- > 0) { + if (b >= eb) { + v = 1; + break; + } if ((flags & STRING_IGNORE_LOWERCASE) && islower(*a)) { if ((v = tolower(*b++) - *a++) != '\0') @@ -1661,7 +1668,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) a++; if (isspace(*b++)) { if (!isspace(*a)) - while (isspace(*b)) + while (b < eb && isspace(*b)) b++; } else { @@ -1672,7 +1679,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) && isspace(*a)) { a++; - while (isspace(*b)) + while (b < eb && isspace(*b)) b++; } else { @@ -1843,13 +1850,13 @@ magiccheck(struct magic_set *ms, struct magic *m) for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) { if (slen + idx > ms->search.s_len) - break; + return 0; v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags); if (v == 0) { /* found match */ ms->search.offset += idx; - ms->search.rm_len = m->str_range - idx; + ms->search.rm_len = ms->search.s_len - idx; break; } } @@ -1887,7 +1894,7 @@ magiccheck(struct magic_set *ms, struct magic *m) copy[--slen] = '\0'; search = copy; } else { - search = ms->search.s; + search = CCAST(char *, ""); copy = NULL; } rc = file_regexec(&rx, (const char *)search, diff --git a/contrib/file/src/vasprintf.c b/contrib/file/src/vasprintf.c index 7a18bed763b6..ad1d3165534d 100644 --- a/contrib/file/src/vasprintf.c +++ b/contrib/file/src/vasprintf.c @@ -88,7 +88,7 @@ type: d i o u x X f e g E G c s p n The function needs to allocate memory to store the full text before to -actually writting it. i.e if you want to fnprintf() 1000 characters, the +actually writing it. i.e if you want to fnprintf() 1000 characters, the functions will allocate 1000 bytes. This behaviour can be modified: you have to customise the code to flush the internal buffer (writing to screen or file) when it reach a given size. Then @@ -108,7 +108,7 @@ you use strange formats. #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: vasprintf.c,v 1.13 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $") #endif /* lint */ #include diff --git a/contrib/file/tests/Makefile.am b/contrib/file/tests/Makefile.am index 46c02e820b9f..8bf4f27cef5d 100644 --- a/contrib/file/tests/Makefile.am +++ b/contrib/file/tests/Makefile.am @@ -1,12 +1,14 @@ check_PROGRAMS = test test_LDADD = $(top_builddir)/src/libmagic.la -test_CPPFLAGS = -I$(top_srcdir)/src +test_CPPFLAGS = -I$(top_builddir)/src EXTRA_DIST = \ escapevel.result \ escapevel.testfile \ gedcom.result \ gedcom.testfile \ +hddrawcopytool.result \ +hddrawcopytool.testfile \ issue311docx.result \ issue311docx.testfile diff --git a/contrib/file/tests/Makefile.in b/contrib/file/tests/Makefile.in index 92f623e8454b..094034c69993 100644 --- a/contrib/file/tests/Makefile.in +++ b/contrib/file/tests/Makefile.in @@ -290,12 +290,14 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ test_LDADD = $(top_builddir)/src/libmagic.la -test_CPPFLAGS = -I$(top_srcdir)/src +test_CPPFLAGS = -I$(top_builddir)/src EXTRA_DIST = \ escapevel.result \ escapevel.testfile \ gedcom.result \ gedcom.testfile \ +hddrawcopytool.result \ +hddrawcopytool.testfile \ issue311docx.result \ issue311docx.testfile diff --git a/contrib/file/tests/hddrawcopytool.result b/contrib/file/tests/hddrawcopytool.result new file mode 100644 index 000000000000..0fe077dca388 --- /dev/null +++ b/contrib/file/tests/hddrawcopytool.result @@ -0,0 +1 @@ +HDD Raw Copy Tool 1.10 - HD model: ST500DM0 02-1BD142 serial: 51D20233A7C0 \ No newline at end of file diff --git a/contrib/file/tests/hddrawcopytool.testfile b/contrib/file/tests/hddrawcopytool.testfile new file mode 100644 index 000000000000..36ad7c64d148 Binary files /dev/null and b/contrib/file/tests/hddrawcopytool.testfile differ diff --git a/contrib/file/tests/test.c b/contrib/file/tests/test.c index db91c62f2ece..330a357b3d4c 100644 --- a/contrib/file/tests/test.c +++ b/contrib/file/tests/test.c @@ -80,7 +80,8 @@ main(int argc, char **argv) return 10; } if (magic_load(ms, NULL) == -1) { - (void)fprintf(stderr, "ERROR loading with NULL file: %s\n", magic_error(ms)); + (void)fprintf(stderr, "ERROR loading with NULL file: %s\n", + magic_error(ms)); return 11; } diff --git a/contrib/gcc/config/arm/unwind-arm.c b/contrib/gcc/config/arm/unwind-arm.c index fff5fdf288a8..7c668a3b0de0 100644 --- a/contrib/gcc/config/arm/unwind-arm.c +++ b/contrib/gcc/config/arm/unwind-arm.c @@ -625,8 +625,8 @@ __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp, do { /* Find the entry for this routine. */ - if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK) - return _URC_FAILURE; + if ((pr_result = get_eit_entry (ucbp, saved_vrs.core.r[R_PC])) != _URC_OK) + return pr_result; /* Call the pr to decide what to do. */ pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) @@ -773,11 +773,8 @@ __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument, do { /* Find the entry for this routine. */ - if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK) - { - code = _URC_FAILURE; + if ((code = get_eit_entry (ucbp, saved_vrs.core.r[R_PC])) != _URC_OK) break; - } /* The dwarf unwinder assumes the context structure holds things like the function and LSDA pointers. The ARM implementation diff --git a/contrib/jemalloc/include/jemalloc/internal/tsd.h b/contrib/jemalloc/include/jemalloc/internal/tsd.h index 155a2ec6c44b..fc14f8cea031 100644 --- a/contrib/jemalloc/include/jemalloc/internal/tsd.h +++ b/contrib/jemalloc/include/jemalloc/internal/tsd.h @@ -120,7 +120,8 @@ struct tsd_s { t use_a_getter_or_setter_instead_##n; MALLOC_TSD #undef O -}; +/* AddressSanitizer requires TLS data to be aligned to at least 8 bytes. */ +} JEMALLOC_ALIGNED(16); /* * Wrapper around tsd_t that makes it possible to avoid implicit conversion diff --git a/contrib/libarchive/cat/test/test_empty.zst.uu b/contrib/libarchive/cat/test/test_empty.zst.uu new file mode 100644 index 000000000000..44ae9a966c13 --- /dev/null +++ b/contrib/libarchive/cat/test/test_empty.zst.uu @@ -0,0 +1,4 @@ +begin 644 test_empty.zst +-*+4O_010`0``F>G840`` +` +end diff --git a/sys/boot/arm/at91/boot0/main.c b/contrib/libarchive/cat/test/test_empty_zstd.c similarity index 65% rename from sys/boot/arm/at91/boot0/main.c rename to contrib/libarchive/cat/test/test_empty_zstd.c index 36dfe821444d..c2d5ea106fa1 100644 --- a/sys/boot/arm/at91/boot0/main.c +++ b/contrib/libarchive/cat/test/test_empty_zstd.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. + * Copyright (c) 2017 Sean Purcell + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,36 +11,31 @@ * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR(S) 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. - * - * $FreeBSD$ */ +#include "test.h" -#include "at91rm9200.h" -#include "lib.h" -#include "at91rm9200_lowlevel.h" - -typedef void fn_t(void); - -int main(void); - -int -main(void) +DEFINE_TEST(test_empty_zstd) { - char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */ - fn_t *fn = (fn_t *)(SDRAM_BASE + (1 << 20)); /* Load to base + 1MB */ + const char *reffile = "test_empty.zst"; + int f; - while (xmodem_rx(addr) == -1) - continue; - fn(); - return (0); + extract_reference_file(reffile); + f = systemf("%s %s >test.out 2>test.err", testprog, reffile); + if (f == 0 || canZstd()) { + assertEqualInt(0, f); + assertEmptyFile("test.out"); + assertEmptyFile("test.err"); + } else { + skipping("It seems zstd is not supported on this platform"); + } } diff --git a/contrib/libarchive/cat/test/test_expand.zst.uu b/contrib/libarchive/cat/test/test_expand.zst.uu new file mode 100644 index 000000000000..89c28b1bc2f8 --- /dev/null +++ b/contrib/libarchive/cat/test/test_expand.zst.uu @@ -0,0 +1,4 @@ +begin 644 test_expand.zst +J*+4O_010Z0``8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N>G-T+@J;23#F +` +end diff --git a/sys/boot/arm/at91/libat91/memcpy.c b/contrib/libarchive/cat/test/test_expand_zstd.c similarity index 64% rename from sys/boot/arm/at91/libat91/memcpy.c rename to contrib/libarchive/cat/test/test_expand_zstd.c index f7544fee64ad..23d918252ad1 100644 --- a/sys/boot/arm/at91/libat91/memcpy.c +++ b/contrib/libarchive/cat/test/test_expand_zstd.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. + * Copyright (c) 2017 Sean Purcell + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,30 +11,31 @@ * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR(S) 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 "test.h" -#include -__FBSDID("$FreeBSD$"); - -#include "lib.h" - -void -memcpy(void *dst, const void *src, unsigned len) +DEFINE_TEST(test_expand_zstd) { - const char *s = src; - char *d = dst; + const char *reffile = "test_expand.zst"; + int f; - while (len--) - *d++ = *s++; + extract_reference_file(reffile); + f = systemf("%s %s >test.out 2>test.err", testprog, reffile); + if (f == 0 || canZstd()) { + assertEqualInt(0, f); + assertTextFileContents("contents of test_expand.zst.\n", "test.out"); + assertEmptyFile("test.err"); + } else { + skipping("It seems zstd is not supported on this platform"); + } } diff --git a/contrib/libarchive/cpio/bsdcpio.1 b/contrib/libarchive/cpio/bsdcpio.1 index e52546e6f761..786a717097ed 100644 --- a/contrib/libarchive/cpio/bsdcpio.1 +++ b/contrib/libarchive/cpio/bsdcpio.1 @@ -187,6 +187,11 @@ In input mode, this option is ignored. Compress the archive with lz4-compatible compression before writing it. In input mode, this option is ignored; lz4 compression is recognized automatically on input. +.It Fl Fl zstd +(o mode only) +Compress the archive with zstd-compatible compression before writing it. +In input mode, this option is ignored; zstd compression is recognized +automatically on input. .It Fl Fl lzma (o mode only) Compress the file with lzma-compatible compression before writing it. diff --git a/contrib/libarchive/cpio/cmdline.c b/contrib/libarchive/cpio/cmdline.c index f37fe5e8431e..830caf659a07 100644 --- a/contrib/libarchive/cpio/cmdline.c +++ b/contrib/libarchive/cpio/cmdline.c @@ -92,6 +92,7 @@ static const struct option { { "verbose", 0, 'v' }, { "version", 0, OPTION_VERSION }, { "xz", 0, 'J' }, + { "zstd", 0, OPTION_ZSTD }, { NULL, 0, 0 } }; diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c index cade829571bb..8396f1f98ce1 100644 --- a/contrib/libarchive/cpio/cpio.c +++ b/contrib/libarchive/cpio/cpio.c @@ -269,6 +269,7 @@ main(int argc, char *argv[]) case OPTION_LZ4: case OPTION_LZMA: /* GNU tar, others */ case OPTION_LZOP: /* GNU tar, others */ + case OPTION_ZSTD: cpio->compress = opt; break; case 'm': /* POSIX 1997 */ @@ -546,6 +547,9 @@ mode_out(struct cpio *cpio) case OPTION_LZOP: r = archive_write_add_filter_lzop(cpio->archive); break; + case OPTION_ZSTD: + r = archive_write_add_filter_zstd(cpio->archive); + break; case 'j': case 'y': r = archive_write_add_filter_bzip2(cpio->archive); break; diff --git a/contrib/libarchive/cpio/cpio.h b/contrib/libarchive/cpio/cpio.h index a383560bcf7b..b10f387be0e3 100644 --- a/contrib/libarchive/cpio/cpio.h +++ b/contrib/libarchive/cpio/cpio.h @@ -111,7 +111,8 @@ enum { OPTION_PRESERVE_OWNER, OPTION_QUIET, OPTION_UUENCODE, - OPTION_VERSION + OPTION_VERSION, + OPTION_ZSTD, }; int cpio_getopt(struct cpio *cpio); diff --git a/contrib/libarchive/cpio/test/test_extract.cpio.zst.uu b/contrib/libarchive/cpio/test/test_extract.cpio.zst.uu new file mode 100644 index 000000000000..5ec854b85d28 --- /dev/null +++ b/contrib/libarchive/cpio/test/test_extract.cpio.zst.uu @@ -0,0 +1,6 @@ +begin 644 test_extract.cpio.zst +M*+4O_01090,`,@41%X")&@#'G6T\K16_MR)#=DK)5:.1,2J0HY2"!(1!`!7R +M$(UB`2"*D41;J2UF&)<0!Y7X'TU<%W.\W^R]GO-WW^OO^QX0`%P<]30-!#U` +?!KD!`#XP,_`U4`HT3+RF:#!7Y\V@R)5"7P"^;WEUK@`` +` +end diff --git a/sys/boot/arm/at91/libat91/memset.c b/contrib/libarchive/cpio/test/test_extract_cpio_zstd.c similarity index 56% rename from sys/boot/arm/at91/libat91/memset.c rename to contrib/libarchive/cpio/test/test_extract_cpio_zstd.c index 3432e640cd43..289f33d0583c 100644 --- a/sys/boot/arm/at91/libat91/memset.c +++ b/contrib/libarchive/cpio/test/test_extract_cpio_zstd.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. + * Copyright (c) 2017 Sean Purcell + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,27 +11,38 @@ * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR(S) 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 +#include "test.h" __FBSDID("$FreeBSD$"); -#include "lib.h" - -void -p_memset(char *buffer, char value, int size) +DEFINE_TEST(test_extract_cpio_zstd) { - while (size--) - *buffer++ = value; + const char *reffile = "test_extract.cpio.zst"; + int f; + + extract_reference_file(reffile); + f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); + if (f == 0 || canZstd()) { + assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", + testprog, reffile)); + + assertFileExists("file1"); + assertTextFileContents("contents of file1.\n", "file1"); + assertFileExists("file2"); + assertTextFileContents("contents of file2.\n", "file2"); + assertEmptyFile("test.out"); + assertTextFileContents("1 block\n", "test.err"); + } else { + skipping("It seems zstd is not supported on this platform"); + } } diff --git a/contrib/libarchive/cpio/test/test_option_zstd.c b/contrib/libarchive/cpio/test/test_option_zstd.c new file mode 100644 index 000000000000..29b8c78b94aa --- /dev/null +++ b/contrib/libarchive/cpio/test/test_option_zstd.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * All rights reserved. + * + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_option_zstd) +{ + char *p; + int r; + size_t s; + + /* Create a file. */ + assertMakeFile("f", 0644, "a"); + + /* Archive it with zstd compression. */ + r = systemf("echo f | %s -o --zstd >archive.out 2>archive.err", + testprog); + p = slurpfile(&s, "archive.err"); + p[s] = '\0'; + if (r != 0) { + if (strstr(p, "Unsupported compression") != NULL) { + skipping("This version of bsdcpio was compiled " + "without zstd support"); + goto done; + } + /* POSIX permits different handling of the spawnp + * system call used to launch the subsidiary + * program: */ + /* Some systems fail immediately to spawn the new process. */ + if (strstr(p, "Can't launch") != NULL && !canZstd()) { + skipping("This version of bsdcpio uses an external zstd program " + "but no such program is available on this system."); + goto done; + } + /* Some systems successfully spawn the new process, + * but fail to exec a program within that process. + * This results in failure at the first attempt to + * write. */ + if (strstr(p, "Can't write") != NULL && !canZstd()) { + skipping("This version of bsdcpio uses an external zstd program " + "but no such program is available on this system."); + goto done; + } + /* On some systems the error won't be detected until closing + time, by a 127 exit error returned by waitpid. */ + if (strstr(p, "Error closing") != NULL && !canZstd()) { + skipping("This version of bsdcpio uses an external zstd program " + "but no such program is available on this system."); + return; + } + failure("--zstd option is broken: %s", p); + assertEqualInt(r, 0); + goto done; + } + free(p); + /* Check that the archive file has an zstd signature. */ + p = slurpfile(&s, "archive.out"); + assert(s > 2); + assertEqualMem(p, "\x28\xb5\x2f\xfd", 4); + +done: + free(p); +} diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index c3681e60c50a..46938ad20cdf 100644 --- a/contrib/libarchive/libarchive/archive.h +++ b/contrib/libarchive/libarchive/archive.h @@ -177,6 +177,7 @@ __LA_DECL const char * archive_zlib_version(void); __LA_DECL const char * archive_liblzma_version(void); __LA_DECL const char * archive_bzlib_version(void); __LA_DECL const char * archive_liblz4_version(void); +__LA_DECL const char * archive_libzstd_version(void); /* Declare our basic types. */ struct archive; @@ -276,6 +277,7 @@ typedef const char *archive_passphrase_callback(struct archive *, #define ARCHIVE_FILTER_LZOP 11 #define ARCHIVE_FILTER_GRZIP 12 #define ARCHIVE_FILTER_LZ4 13 +#define ARCHIVE_FILTER_ZSTD 14 #if ARCHIVE_VERSION_NUMBER < 4000000 #define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE @@ -433,6 +435,7 @@ __LA_DECL int archive_read_support_filter_program_signature __LA_DECL int archive_read_support_filter_rpm(struct archive *); __LA_DECL int archive_read_support_filter_uu(struct archive *); __LA_DECL int archive_read_support_filter_xz(struct archive *); +__LA_DECL int archive_read_support_filter_zstd(struct archive *); __LA_DECL int archive_read_support_format_7zip(struct archive *); __LA_DECL int archive_read_support_format_all(struct archive *); @@ -778,6 +781,7 @@ __LA_DECL int archive_write_add_filter_program(struct archive *, const char *cmd); __LA_DECL int archive_write_add_filter_uuencode(struct archive *); __LA_DECL int archive_write_add_filter_xz(struct archive *); +__LA_DECL int archive_write_add_filter_zstd(struct archive *); /* A convenience function to set the format based on the code or name. */ diff --git a/contrib/libarchive/libarchive/archive_cmdline.c b/contrib/libarchive/libarchive/archive_cmdline.c index 7d3bac53bb5c..5c519cd17f1b 100644 --- a/contrib/libarchive/libarchive/archive_cmdline.c +++ b/contrib/libarchive/libarchive/archive_cmdline.c @@ -100,10 +100,10 @@ get_argument(struct archive_string *as, const char *p) /* * Set up command line arguments. - * Returns ARChIVE_OK if everything okey. - * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an + * Returns ARCHIVE_OK if everything okey. + * Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an * empty command line. - * Returns ARChIVE_FATAL if no memory. + * Returns ARCHIVE_FATAL if no memory. */ int __archive_cmdline_parse(struct archive_cmdline *data, const char *cmd) diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h index 692238277a84..3ade7887222a 100644 --- a/contrib/libarchive/libarchive/archive_platform.h +++ b/contrib/libarchive/libarchive/archive_platform.h @@ -52,6 +52,17 @@ #error Oops: No config.h and no pre-built configuration in archive_platform.h. #endif +/* On macOS check for some symbols based on the deployment target version. */ +#if defined(__APPLE__) +# undef HAVE_FUTIMENS +# undef HAVE_UTIMENSAT +# include +# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 +# define HAVE_FUTIMENS 1 +# define HAVE_UTIMENSAT 1 +# endif +#endif + /* It should be possible to get rid of this by extending the feature-test * macros to cover Windows API functions, probably along with non-trivial * refactoring of code to find structures that sit more cleanly on top of diff --git a/contrib/libarchive/libarchive/archive_read_append_filter.c b/contrib/libarchive/libarchive/archive_read_append_filter.c index 5e4d16307987..da7c55b9b088 100644 --- a/contrib/libarchive/libarchive/archive_read_append_filter.c +++ b/contrib/libarchive/libarchive/archive_read_append_filter.c @@ -89,6 +89,10 @@ archive_read_append_filter(struct archive *_a, int code) strcpy(str, "lz4"); r1 = archive_read_support_filter_lz4(_a); break; + case ARCHIVE_FILTER_ZSTD: + strcpy(str, "zstd"); + r1 = archive_read_support_filter_zstd(_a); + break; case ARCHIVE_FILTER_LZIP: strcpy(str, "lzip"); r1 = archive_read_support_filter_lzip(_a); diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c index 548ba89ef3db..1786cff38453 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -127,7 +127,7 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, /* * Enter working directory and return working pathname of archive_entry. * If a pointer to an integer is provided and its value is below zero - * open a file descriptor on this pahtname. + * open a file descriptor on this pathname. */ const char * archive_read_disk_entry_setup_path(struct archive_read_disk *a, diff --git a/contrib/libarchive/libarchive/archive_read_filter.3 b/contrib/libarchive/libarchive/archive_read_filter.3 index 7f020e3734b8..ef0a70175332 100644 --- a/contrib/libarchive/libarchive/archive_read_filter.3 +++ b/contrib/libarchive/libarchive/archive_read_filter.3 @@ -38,6 +38,7 @@ .Nm archive_read_support_filter_rpm , .Nm archive_read_support_filter_uu , .Nm archive_read_support_filter_xz , +.Nm archive_read_support_filter_zstd , .Nm archive_read_support_filter_program , .Nm archive_read_support_filter_program_signature .Nd functions for reading streaming archives @@ -73,6 +74,8 @@ Streaming Archive Library (libarchive, -larchive) .Ft int .Fn archive_read_support_filter_xz "struct archive *" .Ft int +.Fn archive_read_support_filter_zstd "struct archive *" +.Ft int .Fo archive_read_support_filter_program .Fa "struct archive *" .Fa "const char *cmd" @@ -99,7 +102,8 @@ Streaming Archive Library (libarchive, -larchive) .Fn archive_read_support_filter_none , .Fn archive_read_support_filter_rpm , .Fn archive_read_support_filter_uu , -.Fn archive_read_support_filter_xz +.Fn archive_read_support_filter_xz , +.Fn archive_read_support_filter_zstd , .Xc Enables auto-detection code and decompression support for the specified compression. diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_all.c b/contrib/libarchive/libarchive/archive_read_support_filter_all.c index 68c53de41f2d..edb508c1dfd8 100644 --- a/contrib/libarchive/libarchive/archive_read_support_filter_all.c +++ b/contrib/libarchive/libarchive/archive_read_support_filter_all.c @@ -71,6 +71,8 @@ archive_read_support_filter_all(struct archive *a) archive_read_support_filter_grzip(a); /* Lz4 falls back to "lz4 -d" command-line program. */ archive_read_support_filter_lz4(a); + /* Zstd falls back to "zstd -d" command-line program. */ + archive_read_support_filter_zstd(a); /* Note: We always return ARCHIVE_OK here, even if some of the * above return ARCHIVE_WARN. The intent here is to enable diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_zstd.c b/contrib/libarchive/libarchive/archive_read_support_filter_zstd.c new file mode 100644 index 000000000000..c8bb36be703c --- /dev/null +++ b/contrib/libarchive/libarchive/archive_read_support_filter_zstd.c @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 2009-2011 Sean Purcell + * All rights reserved. + * + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "archive_platform.h" + +__FBSDID("$FreeBSD$"); + +#ifdef HAVE_ERRNO_H +#include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#if HAVE_ZSTD_H +#include +#endif + +#include "archive.h" +#include "archive_endian.h" +#include "archive_private.h" +#include "archive_read_private.h" + +#if HAVE_ZSTD_H && HAVE_LIBZSTD + +struct private_data { + ZSTD_DStream *dstream; + unsigned char *out_block; + size_t out_block_size; + int64_t total_out; + char in_frame; /* True = in the middle of a zstd frame. */ + char eof; /* True = found end of compressed data. */ +}; + +/* Zstd Filter. */ +static ssize_t zstd_filter_read(struct archive_read_filter *, const void**); +static int zstd_filter_close(struct archive_read_filter *); +#endif + +/* + * Note that we can detect zstd compressed files even if we can't decompress + * them. (In fact, we like detecting them because we can give better error + * messages.) So the bid framework here gets compiled even if no zstd library + * is available. + */ +static int zstd_bidder_bid(struct archive_read_filter_bidder *, + struct archive_read_filter *); +static int zstd_bidder_init(struct archive_read_filter *); + +int +archive_read_support_filter_zstd(struct archive *_a) +{ + struct archive_read *a = (struct archive_read *)_a; + struct archive_read_filter_bidder *bidder; + + archive_check_magic(_a, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "archive_read_support_filter_zstd"); + + if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + return (ARCHIVE_FATAL); + + bidder->data = NULL; + bidder->name = "zstd"; + bidder->bid = zstd_bidder_bid; + bidder->init = zstd_bidder_init; + bidder->options = NULL; + bidder->free = NULL; +#if HAVE_ZSTD_H && HAVE_LIBZSTD + return (ARCHIVE_OK); +#else + archive_set_error(_a, ARCHIVE_ERRNO_MISC, + "Using external zstd program for zstd decompression"); + return (ARCHIVE_WARN); +#endif +} + +/* + * Test whether we can handle this data. + */ +static int +zstd_bidder_bid(struct archive_read_filter_bidder *self, + struct archive_read_filter *filter) +{ + const unsigned char *buffer; + ssize_t avail; + unsigned prefix; + + /* Zstd frame magic values */ + const unsigned zstd_magic = 0xFD2FB528U; + + (void) self; /* UNUSED */ + + buffer = __archive_read_filter_ahead(filter, 4, &avail); + if (buffer == NULL) + return (0); + + prefix = archive_le32dec(buffer); + if (prefix == zstd_magic) + return (32); + + return (0); +} + +#if !(HAVE_ZSTD_H && HAVE_LIBZSTD) + +/* + * If we don't have the library on this system, we can't do the + * decompression directly. We can, however, try to run "zstd -d" + * in case that's available. + */ +static int +zstd_bidder_init(struct archive_read_filter *self) +{ + int r; + + r = __archive_read_program(self, "zstd -d -qq"); + /* Note: We set the format here even if __archive_read_program() + * above fails. We do, after all, know what the format is + * even if we weren't able to read it. */ + self->code = ARCHIVE_FILTER_ZSTD; + self->name = "zstd"; + return (r); +} + +#else + +/* + * Initialize the filter object + */ +static int +zstd_bidder_init(struct archive_read_filter *self) +{ + struct private_data *state; + const size_t out_block_size = ZSTD_DStreamOutSize(); + void *out_block; + ZSTD_DStream *dstream; + + self->code = ARCHIVE_FILTER_ZSTD; + self->name = "zstd"; + + state = (struct private_data *)calloc(sizeof(*state), 1); + out_block = (unsigned char *)malloc(out_block_size); + dstream = ZSTD_createDStream(); + + if (state == NULL || out_block == NULL || dstream == NULL) { + free(out_block); + free(state); + ZSTD_freeDStream(dstream); /* supports free on NULL */ + archive_set_error(&self->archive->archive, ENOMEM, + "Can't allocate data for zstd decompression"); + return (ARCHIVE_FATAL); + } + + self->data = state; + + state->out_block_size = out_block_size; + state->out_block = out_block; + state->dstream = dstream; + self->read = zstd_filter_read; + self->skip = NULL; /* not supported */ + self->close = zstd_filter_close; + + state->eof = 0; + state->in_frame = 0; + + return (ARCHIVE_OK); +} + +static ssize_t +zstd_filter_read(struct archive_read_filter *self, const void **p) +{ + struct private_data *state; + size_t decompressed; + ssize_t avail_in; + ZSTD_outBuffer out; + ZSTD_inBuffer in; + + state = (struct private_data *)self->data; + + out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 }; + + /* Try to fill the output buffer. */ + while (out.pos < out.size && !state->eof) { + if (!state->in_frame) { + const size_t ret = ZSTD_initDStream(state->dstream); + if (ZSTD_isError(ret)) { + archive_set_error(&self->archive->archive, + ARCHIVE_ERRNO_MISC, + "Error initializing zstd decompressor: %s", + ZSTD_getErrorName(ret)); + return (ARCHIVE_FATAL); + } + } + in.src = __archive_read_filter_ahead(self->upstream, 1, + &avail_in); + if (avail_in < 0) { + return avail_in; + } + if (in.src == NULL && avail_in == 0) { + if (!state->in_frame) { + /* end of stream */ + state->eof = 1; + break; + } else { + archive_set_error(&self->archive->archive, + ARCHIVE_ERRNO_MISC, + "Truncated zstd input"); + return (ARCHIVE_FATAL); + } + } + in.size = avail_in; + in.pos = 0; + + { + const size_t ret = + ZSTD_decompressStream(state->dstream, &out, &in); + + if (ZSTD_isError(ret)) { + archive_set_error(&self->archive->archive, + ARCHIVE_ERRNO_MISC, + "Zstd decompression failed: %s", + ZSTD_getErrorName(ret)); + return (ARCHIVE_FATAL); + } + + /* Decompressor made some progress */ + __archive_read_filter_consume(self->upstream, in.pos); + + /* ret guaranteed to be > 0 if frame isn't done yet */ + state->in_frame = (ret != 0); + } + } + + decompressed = out.pos; + state->total_out += decompressed; + if (decompressed == 0) + *p = NULL; + else + *p = state->out_block; + return (decompressed); +} + +/* + * Clean up the decompressor. + */ +static int +zstd_filter_close(struct archive_read_filter *self) +{ + struct private_data *state; + + state = (struct private_data *)self->data; + + ZSTD_freeDStream(state->dstream); + free(state->out_block); + free(state); + + return (ARCHIVE_OK); +} + +#endif /* HAVE_ZLIB_H && HAVE_LIBZSTD */ diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c index 6b4d241fd34a..665acaeff459 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c @@ -633,6 +633,13 @@ header_newc(struct archive_read *a, struct cpio *cpio, /* Pad name to 2 more than a multiple of 4. */ *name_pad = (2 - *namelength) & 3; + /* Make sure that the padded name length fits into size_t. */ + if (*name_pad > SIZE_MAX - *namelength) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "cpio archive has invalid namelength"); + return (ARCHIVE_FATAL); + } + /* * Note: entry_bytes_remaining is at least 64 bits and * therefore guaranteed to be big enough for a 33-bit file diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c index d2770f1cf701..69a62e189bc5 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c @@ -77,6 +77,8 @@ __FBSDID("$FreeBSD$"); #define MTREE_HASHTABLE_SIZE 1024 +#define MAX_LINE_LEN (1024 * 1024) + struct mtree_option { struct mtree_option *next; char *value; @@ -334,6 +336,14 @@ next_line(struct archive_read *a, size_t nbytes_req = (*ravail+1023) & ~1023U; ssize_t tested; + /* + * Place an arbitrary limit on the line length. + * mtree is almost free-form input and without line length limits, + * it can consume a lot of memory. + */ + if (len >= MAX_LINE_LEN) + return (-1); + /* Increase reading bytes if it is not enough to at least * new two lines. */ if (nbytes_req < (size_t)*ravail + 160) diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c index cbb14c32dc3b..751de6979ba5 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c @@ -1496,7 +1496,11 @@ read_header(struct archive_read *a, struct archive_entry *entry, return (ARCHIVE_FATAL); } filename[filename_size++] = '\0'; - filename[filename_size++] = '\0'; + /* + * Do not increment filename_size here as the computations below + * add the space for the terminating NUL explicitly. + */ + filename[filename_size] = '\0'; /* Decoded unicode form is UTF-16BE, so we have to update a string * conversion object for it. */ diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c index e956f40cd6ad..7348e2d5c07e 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c @@ -2243,7 +2243,7 @@ gnu_add_sparse_entry(struct archive_read *a, struct tar *tar, else tar->sparse_list = p; tar->sparse_last = p; - if (remaining < 0 || offset < 0) { + if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data"); return (ARCHIVE_FATAL); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c index 7a22beb9d8e4..602fc7722144 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c @@ -1040,6 +1040,9 @@ atol10(const char *p, size_t char_cnt) uint64_t l; int digit; + if (char_cnt == 0) + return (0); + l = 0; digit = *p - '0'; while (digit >= 0 && digit < 10 && char_cnt-- > 0) { @@ -1054,7 +1057,10 @@ atol8(const char *p, size_t char_cnt) { int64_t l; int digit; - + + if (char_cnt == 0) + return (0); + l = 0; while (char_cnt-- > 0) { if (*p >= '0' && *p <= '7') @@ -2623,6 +2629,14 @@ strappend_base64(struct xar *xar, archive_strncat(as, (const char *)buff, len); } +static int +is_string(const char *known, const char *data, size_t len) +{ + if (strlen(known) != len) + return -1; + return memcmp(data, known, len); +} + static void xml_data(void *userData, const char *s, int len) { @@ -2674,26 +2688,26 @@ xml_data(void *userData, const char *s, int len) archive_strncpy(&(xar->file->symlink), s, len); break; case FILE_TYPE: - if (strncmp("file", s, len) == 0 || - strncmp("hardlink", s, len) == 0) + if (is_string("file", s, len) == 0 || + is_string("hardlink", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFREG; - if (strncmp("directory", s, len) == 0) + if (is_string("directory", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFDIR; - if (strncmp("symlink", s, len) == 0) + if (is_string("symlink", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFLNK; - if (strncmp("character special", s, len) == 0) + if (is_string("character special", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFCHR; - if (strncmp("block special", s, len) == 0) + if (is_string("block special", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFBLK; - if (strncmp("socket", s, len) == 0) + if (is_string("socket", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFSOCK; - if (strncmp("fifo", s, len) == 0) + if (is_string("fifo", s, len) == 0) xar->file->mode = (xar->file->mode & ~AE_IFMT) | AE_IFIFO; xar->file->has |= HAS_TYPE; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index c88e7bbbe0d5..d6c957045625 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -723,6 +723,11 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct } case 0x9901: /* WinZip AES extra data field. */ + if (datasize < 6) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Incomplete AES field"); + return ARCHIVE_FAILED; + } if (p[offset + 2] == 'A' && p[offset + 3] == 'E') { /* Vendor version. */ zip_entry->aes_extra.vendor = diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c index 3501a9e09143..c12355f08916 100644 --- a/contrib/libarchive/libarchive/archive_string.c +++ b/contrib/libarchive/libarchive/archive_string.c @@ -214,7 +214,8 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s) { if (archive_wstring_ensure(as, as->length + s + 1) == NULL) return (NULL); - wmemmove(as->s + as->length, p, s); + if (s) + wmemmove(as->s + as->length, p, s); as->length += s; as->s[as->length] = 0; return (as); diff --git a/contrib/libarchive/libarchive/archive_version_details.c b/contrib/libarchive/libarchive/archive_version_details.c index e10b83e5b7e4..2651503e6fda 100644 --- a/contrib/libarchive/libarchive/archive_version_details.c +++ b/contrib/libarchive/libarchive/archive_version_details.c @@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_LZ4_H #include #endif +#ifdef HAVE_ZSTD_H +#include +#endif #include "archive.h" #include "archive_private.h" @@ -59,6 +62,7 @@ archive_version_details(void) const char *liblzma = archive_liblzma_version(); const char *bzlib = archive_bzlib_version(); const char *liblz4 = archive_liblz4_version(); + const char *libzstd = archive_libzstd_version(); if (!init) { archive_string_init(&str); @@ -84,6 +88,10 @@ archive_version_details(void) archive_strcat(&str, " liblz4/"); archive_strcat(&str, liblz4); } + if (libzstd) { + archive_strcat(&str, " libzstd/"); + archive_strcat(&str, libzstd); + } } return str.s; } @@ -131,3 +139,13 @@ archive_liblz4_version(void) return NULL; #endif } + +const char * +archive_libzstd_version(void) +{ +#if HAVE_ZSTD_H && HAVE_LIBZSTD + return ZSTD_VERSION_STRING; +#else + return NULL; +#endif +} diff --git a/contrib/libarchive/libarchive/archive_write.3 b/contrib/libarchive/libarchive/archive_write.3 index 376d71dee20e..c1164f5b5fdb 100644 --- a/contrib/libarchive/libarchive/archive_write.3 +++ b/contrib/libarchive/libarchive/archive_write.3 @@ -71,7 +71,7 @@ support. .\" .Ss Set options See -.Xr archive_read_set_options 3 . +.Xr archive_write_set_options 3 . .\" .Ss Open archive See diff --git a/contrib/libarchive/libarchive/archive_write_add_filter.c b/contrib/libarchive/libarchive/archive_write_add_filter.c index 08f518adec4b..203f4142b5c9 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter.c @@ -53,6 +53,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] = { ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip }, { ARCHIVE_FILTER_UU, archive_write_add_filter_uuencode }, { ARCHIVE_FILTER_XZ, archive_write_add_filter_xz }, + { ARCHIVE_FILTER_ZSTD, archive_write_add_filter_zstd }, { -1, NULL } }; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_by_name.c b/contrib/libarchive/libarchive/archive_write_add_filter_by_name.c index 85a8d4753415..ffa633c96371 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_by_name.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_by_name.c @@ -57,6 +57,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] = { "lzop", archive_write_add_filter_lzop }, { "uuencode", archive_write_add_filter_uuencode }, { "xz", archive_write_add_filter_xz }, + { "zstd", archive_write_add_filter_zstd }, { NULL, NULL } }; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c new file mode 100644 index 000000000000..671fc6affbaa --- /dev/null +++ b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c @@ -0,0 +1,335 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * All rights reserved. + * + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "archive_platform.h" + +__FBSDID("$FreeBSD$"); + + +#ifdef HAVE_ERRNO_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_ZSTD_H +#include +#endif + +#include "archive.h" +#include "archive_private.h" +#include "archive_string.h" +#include "archive_write_private.h" + +/* Don't compile this if we don't have zstd.h */ + +struct private_data { + int compression_level; +#if HAVE_ZSTD_H && HAVE_LIBZSTD + ZSTD_CStream *cstream; + int64_t total_in; + ZSTD_outBuffer out; +#else + struct archive_write_program_data *pdata; +#endif +}; + +static int archive_compressor_zstd_options(struct archive_write_filter *, + const char *, const char *); +static int archive_compressor_zstd_open(struct archive_write_filter *); +static int archive_compressor_zstd_write(struct archive_write_filter *, + const void *, size_t); +static int archive_compressor_zstd_close(struct archive_write_filter *); +static int archive_compressor_zstd_free(struct archive_write_filter *); +#if HAVE_ZSTD_H && HAVE_LIBZSTD +static int drive_compressor(struct archive_write_filter *, + struct private_data *, int, const void *, size_t); +#endif + + +/* + * Add a zstd compression filter to this write handle. + */ +int +archive_write_add_filter_zstd(struct archive *_a) +{ + struct archive_write *a = (struct archive_write *)_a; + struct archive_write_filter *f = __archive_write_allocate_filter(_a); + struct private_data *data; + archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_NEW, "archive_write_add_filter_zstd"); + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + archive_set_error(&a->archive, ENOMEM, "Out of memory"); + return (ARCHIVE_FATAL); + } + f->data = data; + f->open = &archive_compressor_zstd_open; + f->options = &archive_compressor_zstd_options; + f->close = &archive_compressor_zstd_close; + f->free = &archive_compressor_zstd_free; + f->code = ARCHIVE_FILTER_ZSTD; + f->name = "zstd"; + data->compression_level = 3; /* Default level used by the zstd CLI */ +#if HAVE_ZSTD_H && HAVE_LIBZSTD + data->cstream = ZSTD_createCStream(); + if (data->cstream == NULL) { + free(data); + archive_set_error(&a->archive, ENOMEM, + "Failed to allocate zstd compressor object"); + return (ARCHIVE_FATAL); + } + + return (ARCHIVE_OK); +#else + data->pdata = __archive_write_program_allocate("zstd"); + if (data->pdata == NULL) { + free(data); + archive_set_error(&a->archive, ENOMEM, "Out of memory"); + return (ARCHIVE_FATAL); + } + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Using external zstd program"); + return (ARCHIVE_WARN); +#endif +} + +static int +archive_compressor_zstd_free(struct archive_write_filter *f) +{ + struct private_data *data = (struct private_data *)f->data; +#if HAVE_ZSTD_H && HAVE_LIBZSTD + ZSTD_freeCStream(data->cstream); + free(data->out.dst); +#else + __archive_write_program_free(data->pdata); +#endif + free(data); + f->data = NULL; + return (ARCHIVE_OK); +} + +/* + * Set write options. + */ +static int +archive_compressor_zstd_options(struct archive_write_filter *f, const char *key, + const char *value) +{ + struct private_data *data = (struct private_data *)f->data; + + if (strcmp(key, "compression-level") == 0) { + int level = atoi(value); +#if HAVE_ZSTD_H && HAVE_LIBZSTD + if (level < 1 || level > ZSTD_maxCLevel()) { +#else + /* If we don't have the library, hard-code the max level */ + if (level < 1 || level > 22) { +#endif + return (ARCHIVE_WARN); + } + data->compression_level = level; + return (ARCHIVE_OK); + } + + /* Note: The "warn" return is just to inform the options + * supervisor that we didn't handle it. It will generate + * a suitable error if no one used this option. */ + return (ARCHIVE_WARN); +} + +#if HAVE_ZSTD_H && HAVE_LIBZSTD +/* + * Setup callback. + */ +static int +archive_compressor_zstd_open(struct archive_write_filter *f) +{ + struct private_data *data = (struct private_data *)f->data; + int ret; + + ret = __archive_write_open_filter(f->next_filter); + if (ret != ARCHIVE_OK) + return (ret); + + if (data->out.dst == NULL) { + size_t bs = ZSTD_CStreamOutSize(), bpb; + if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { + /* Buffer size should be a multiple number of + * the of bytes per block for performance. */ + bpb = archive_write_get_bytes_per_block(f->archive); + if (bpb > bs) + bs = bpb; + else if (bpb != 0) + bs -= bs % bpb; + } + data->out.size = bs; + data->out.pos = 0; + data->out.dst + = (unsigned char *)malloc(data->out.size); + if (data->out.dst == NULL) { + archive_set_error(f->archive, ENOMEM, + "Can't allocate data for compression buffer"); + return (ARCHIVE_FATAL); + } + } + + f->write = archive_compressor_zstd_write; + + if (ZSTD_isError(ZSTD_initCStream(data->cstream, + data->compression_level))) { + archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, + "Internal error initializing zstd compressor object"); + return (ARCHIVE_FATAL); + } + + return (ARCHIVE_OK); +} + +/* + * Write data to the compressed stream. + */ +static int +archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff, + size_t length) +{ + struct private_data *data = (struct private_data *)f->data; + int ret; + + /* Update statistics */ + data->total_in += length; + + if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK) + return (ret); + + return (ARCHIVE_OK); +} + +/* + * Finish the compression... + */ +static int +archive_compressor_zstd_close(struct archive_write_filter *f) +{ + struct private_data *data = (struct private_data *)f->data; + int r1, r2; + + /* Finish zstd frame */ + r1 = drive_compressor(f, data, 1, NULL, 0); + + r2 = __archive_write_close_filter(f->next_filter); + + return r1 < r2 ? r1 : r2; +} + +/* + * Utility function to push input data through compressor, + * writing full output blocks as necessary. + * + * Note that this handles both the regular write case (finishing == + * false) and the end-of-archive case (finishing == true). + */ +static int +drive_compressor(struct archive_write_filter *f, + struct private_data *data, int finishing, const void *src, size_t length) +{ + ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 }; + + for (;;) { + if (data->out.pos == data->out.size) { + const int ret = __archive_write_filter(f->next_filter, + data->out.dst, data->out.size); + if (ret != ARCHIVE_OK) + return (ARCHIVE_FATAL); + data->out.pos = 0; + } + + /* If there's nothing to do, we're done. */ + if (!finishing && in.pos == in.size) + return (ARCHIVE_OK); + + { + const size_t zstdret = !finishing ? + ZSTD_compressStream(data->cstream, &data->out, &in) + : ZSTD_endStream(data->cstream, &data->out); + + if (ZSTD_isError(zstdret)) { + archive_set_error(f->archive, + ARCHIVE_ERRNO_MISC, + "Zstd compression failed: %s", + ZSTD_getErrorName(zstdret)); + return (ARCHIVE_FATAL); + } + + /* If we're finishing, 0 means nothing left to flush */ + if (finishing && zstdret == 0) { + const int ret = __archive_write_filter(f->next_filter, + data->out.dst, data->out.pos); + return (ret); + } + } + } +} + +#else /* HAVE_ZSTD_H && HAVE_LIBZSTD */ + +static int +archive_compressor_zstd_open(struct archive_write_filter *f) +{ + struct private_data *data = (struct private_data *)f->data; + struct archive_string as; + int r; + + archive_string_init(&as); + archive_string_sprintf(&as, "zstd -%d", data->compression_level); + + f->write = archive_compressor_zstd_write; + r = __archive_write_program_open(f, data->pdata, as.s); + archive_string_free(&as); + return (r); +} + +static int +archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff, + size_t length) +{ + struct private_data *data = (struct private_data *)f->data; + + return __archive_write_program_write(f, data->pdata, buff, length); +} + +static int +archive_compressor_zstd_close(struct archive_write_filter *f) +{ + struct private_data *data = (struct private_data *)f->data; + + return __archive_write_program_close(f, data->pdata); +} + +#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD */ diff --git a/contrib/libarchive/libarchive/archive_write_filter.3 b/contrib/libarchive/libarchive/archive_write_filter.3 index e1d189150644..d6fa07131a80 100644 --- a/contrib/libarchive/libarchive/archive_write_filter.3 +++ b/contrib/libarchive/libarchive/archive_write_filter.3 @@ -42,7 +42,8 @@ .Nm archive_write_add_filter_none , .Nm archive_write_add_filter_program , .Nm archive_write_add_filter_uuencode , -.Nm archive_write_add_filter_xz +.Nm archive_write_add_filter_xz , +.Nm archive_write_add_filter_zstd , .Nd functions enabling output filters .Sh LIBRARY Streaming Archive Library (libarchive, -larchive) @@ -76,6 +77,8 @@ Streaming Archive Library (libarchive, -larchive) .Fn archive_write_add_filter_uuencode "struct archive *" .Ft int .Fn archive_write_add_filter_xz "struct archive *" +.Ft int +.Fn archive_write_add_filter_zstd "struct archive *" .Sh DESCRIPTION .Bl -tag -width indent .It Xo @@ -89,6 +92,7 @@ Streaming Archive Library (libarchive, -larchive) .Fn archive_write_add_filter_lzma , .Fn archive_write_add_filter_lzop , .Fn archive_write_add_filter_xz , +.Fn archive_write_add_filter_zstd , .Xc The resulting archive will be compressed as specified. Note that the compressed output is always properly blocked. diff --git a/contrib/libarchive/libarchive/archive_write_set_format_pax.c b/contrib/libarchive/libarchive/archive_write_set_format_pax.c index 318ca78c554d..650b4529060a 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_pax.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_pax.c @@ -1654,7 +1654,7 @@ build_pax_attribute_name(char *dest, const char *src) * GNU PAX Format 1.0 requires the special name, which pattern is: * /GNUSparseFile./ * - * Since reproducable archives are more important, use 0 as pid. + * Since reproducible archives are more important, use 0 as pid. * * This function is used for only Sparse file, a file type of which * is regular file. diff --git a/contrib/libarchive/libarchive/test/test_archive_write_add_filter_by_name.c b/contrib/libarchive/libarchive/test/test_archive_write_add_filter_by_name.c index 38b606b9d165..d962af92311b 100644 --- a/contrib/libarchive/libarchive/test/test_archive_write_add_filter_by_name.c +++ b/contrib/libarchive/libarchive/test/test_archive_write_add_filter_by_name.c @@ -207,3 +207,8 @@ DEFINE_TEST(test_archive_write_add_filter_by_name_xz) { test_filter_by_name("xz", ARCHIVE_FILTER_XZ, cannot); } + +DEFINE_TEST(test_archive_write_add_filter_by_name_zstd) +{ + test_filter_by_name("zstd", ARCHIVE_FILTER_ZSTD, canZstd); +} diff --git a/contrib/libarchive/libarchive/test/test_compat_zstd.c b/contrib/libarchive/libarchive/test/test_compat_zstd.c new file mode 100644 index 000000000000..1d63a2845ff5 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_compat_zstd.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * All rights reserved. + * + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "test.h" +__FBSDID("$FreeBSD$"); + +/* + * Verify our ability to read sample files compatibly with 'zstd -d'. + * + * In particular: + * * zstd -d will read multiple zstd streams, concatenating the output + * * zstd -d will skip over zstd skippable frames + */ + +static void +compat_zstd(const char *name) +{ + const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; + struct archive_entry *ae; + struct archive *a; + int i, r; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + r = archive_read_support_filter_zstd(a); + if (r == ARCHIVE_WARN) { + skipping("zstd reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); + + /* Read entries, match up names with list above. */ + for (i = 0; i < 6; ++i) { + failure("Could not read file %d (%s) from %s", i, n[i], name); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header(a, &ae)); + assertEqualString(n[i], archive_entry_pathname(ae)); + } + + /* Verify the end-of-archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_ZSTD); + assertEqualString(archive_filter_name(a, 0), "zstd"); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + + +DEFINE_TEST(test_compat_zstd) +{ + /* This sample was compressed as 3 separate streams with a zstd skippable + * frame placed in the middle */ + compat_zstd("test_compat_zstd_1.tar.zst"); +} diff --git a/contrib/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu b/contrib/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu new file mode 100644 index 000000000000..4b0b98447ffa --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu @@ -0,0 +1,12 @@ +begin 644 test_compat_zstd_1.tar.zst +M*+4O_010)0,`HL0.%;`Q&>>\/$2[#IQF[<1+Z3T<0CX]!77&0@R.6+/F,0+I +M.$1A$QE2`J!+*_6[_YT9_W_M1KC-EG*V>10.`,M`%3*@#F#\`-FT#J:1#U1" +M`H1!&R#A5\*'"JYIJ;C&4=B2CL(L)*E-IJT/RV?.:A_]_N +MB&[7SDG;/=4&#P";0!5D0`=8T0&R&19,)1^HA`0(@S9`N`G.!0!IP&NM<,K! +M-#8!%A]U]K10*DT8!`````$"`P0HM2_]!%!]`P`B11`6H+$)"%]@,Z6OH`"L +MM$R2MAN&*MSG`W?OJ7+4P*B::VXR`NM(1&$7&58"J*U'_&V^S$/_O]U1N%T[ +M)VW7J'+4!A``_4$%^T`],J`8P.0!L@D63"4?J(0$"(,V0+@)S@4`:Y+>!0*5E/PM"$7^K^1VI3SS-AX&_W0KQWY!-Z1(`_4$%[$"] +#include "test.h" __FBSDID("$FreeBSD$"); -#include "lib.h" - -int -p_memcmp(const char *to, const char *from, unsigned size) +DEFINE_TEST(test_extract_tar_zstd) { - while ((--size) && (*to++ == *from++)) - continue; + const char *reffile = "test_extract.tar.zst"; + int f; - return (size || (*to != *from)); + extract_reference_file(reffile); + f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); + if (f == 0 || canZstd()) { + assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", + testprog, reffile)); + + assertFileExists("file1"); + assertTextFileContents("contents of file1.\n", "file1"); + assertFileExists("file2"); + assertTextFileContents("contents of file2.\n", "file2"); + assertEmptyFile("test.out"); + assertEmptyFile("test.err"); + } else { + skipping("It seems zstd is not supported on this platform"); + } } diff --git a/contrib/libarchive/tar/test/test_option_acls.c b/contrib/libarchive/tar/test/test_option_acls.c index f2d51d661abf..325f319537af 100644 --- a/contrib/libarchive/tar/test/test_option_acls.c +++ b/contrib/libarchive/tar/test/test_option_acls.c @@ -483,7 +483,7 @@ DEFINE_TEST(test_option_acls) r = compare_acls("f", "acls_acls/f"); assertEqualInt(r, 1); - /* Extractl acls without acls */ + /* Extract acls without acls */ assertMakeDir("acls_noacls", 0755); clear_inheritance_flags("acls_noacls", acltype); r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog); diff --git a/contrib/libarchive/tar/test/test_option_zstd.c b/contrib/libarchive/tar/test/test_option_zstd.c new file mode 100644 index 000000000000..73965e33f3af --- /dev/null +++ b/contrib/libarchive/tar/test/test_option_zstd.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * All rights reserved. + * + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_option_zstd) +{ + char *p; + int r; + size_t s; + + /* Create a file. */ + assertMakeFile("f", 0644, "a"); + + /* Archive it with lz4 compression. */ + r = systemf("%s -cf - --zstd f >archive.out 2>archive.err", + testprog); + p = slurpfile(&s, "archive.err"); + p[s] = '\0'; + if (r != 0) { + if (strstr(p, "Unsupported compression") != NULL) { + skipping("This version of bsdtar was compiled " + "without zstd support"); + goto done; + } + /* POSIX permits different handling of the spawnp + * system call used to launch the subsidiary + * program: */ + /* Some systems fail immediately to spawn the new process. */ + if (strstr(p, "Can't launch") != NULL && !canZstd()) { + skipping("This version of bsdtar uses an external zstd program " + "but no such program is available on this system."); + goto done; + } + /* Some systems successfully spawn the new process, + * but fail to exec a program within that process. + * This results in failure at the first attempt to + * write. */ + if (strstr(p, "Can't write") != NULL && !canZstd()) { + skipping("This version of bsdtar uses an external zstd program " + "but no such program is available on this system."); + goto done; + } + /* On some systems the error won't be detected until closing + time, by a 127 exit error returned by waitpid. */ + if (strstr(p, "Error closing") != NULL && !canZstd()) { + skipping("This version of bsdcpio uses an external zstd program " + "but no such program is available on this system."); + return; + } + failure("--zstd option is broken: %s", p); + assertEqualInt(r, 0); + goto done; + } + free(p); + /* Check that the archive file has an lz4 signature. */ + p = slurpfile(&s, "archive.out"); + assert(s > 2); + assertEqualMem(p, "\x28\xb5\x2f\xfd", 4); + +done: + free(p); +} diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h index 1425dd84b7df..dd7e41016d52 100644 --- a/contrib/libarchive/test_utils/test_common.h +++ b/contrib/libarchive/test_utils/test_common.h @@ -329,6 +329,9 @@ int canLrzip(void); /* Return true if this platform can run the "lz4" program. */ int canLz4(void); +/* Return true if this platform can run the "zstd" program. */ +int canZstd(void); + /* Return true if this platform can run the "lzip" program. */ int canLzip(void); diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c index 0e1413693f4a..0e8cc9fc56a2 100644 --- a/contrib/libarchive/test_utils/test_main.c +++ b/contrib/libarchive/test_utils/test_main.c @@ -2318,6 +2318,21 @@ canLz4(void) return (value); } +/* + * Can this platform run the zstd program? + */ +int +canZstd(void) +{ + static int tested = 0, value = 0; + if (!tested) { + tested = 1; + if (systemf("zstd -V %s", redirectArgs) == 0) + value = 1; + } + return (value); +} + /* * Can this platform run the lzip program? */ diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc index 45097eb918b7..67edb46f0025 100644 --- a/contrib/llvm/lib/Support/Unix/Path.inc +++ b/contrib/llvm/lib/Support/Unix/Path.inc @@ -427,7 +427,7 @@ std::error_code resize_file(int FD, uint64_t Size) { // If we have posix_fallocate use it. Unlike ftruncate it always allocates // space, so we get an error if the disk is full. if (int Err = ::posix_fallocate(FD, 0, Size)) { - if (Err != EOPNOTSUPP) + if (Err != EINVAL && Err != EOPNOTSUPP) return std::error_code(Err, std::generic_category()); } #endif diff --git a/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index c0c6055c358f..13c80a46e5b0 100644 --- a/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -940,6 +940,12 @@ bool AArch64InstrInfo::areMemAccessesTriviallyDisjoint( bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &CmpMask, int &CmpValue) const { + // The first operand can be a frame index where we'd normally expect a + // register. + assert(MI.getNumOperands() >= 2 && "All AArch64 cmps should have 2 operands"); + if (!MI.getOperand(1).isReg()) + return false; + switch (MI.getOpcode()) { default: break; diff --git a/contrib/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp b/contrib/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp index 4e65c0ab6011..22c11c7276d2 100644 --- a/contrib/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp +++ b/contrib/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp @@ -167,6 +167,9 @@ AArch64RedundantCopyElimination::knownRegValInBlock( // CMP is an alias for SUBS with a dead destination register. case AArch64::SUBSWri: case AArch64::SUBSXri: { + // Sometimes the first operand is a FrameIndex. Bail if tht happens. + if (!PredI.getOperand(1).isReg()) + return None; MCPhysReg SrcReg = PredI.getOperand(1).getReg(); // Must not be a symbolic immediate. diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S index 923ddacbaea6..2330fc2adb5f 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S +++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S @@ -528,4 +528,5 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) #endif - .section .note.GNU-stack,"",@progbits +NO_EXEC_STACK_DIRECTIVE + diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S index 0839c446f196..9b66a7657fe4 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S +++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S @@ -470,4 +470,5 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #endif - .section .note.GNU-stack,"",@progbits +NO_EXEC_STACK_DIRECTIVE + diff --git a/contrib/llvm/projects/libunwind/src/assembly.h b/contrib/llvm/projects/libunwind/src/assembly.h index f46a24d0eed9..06b29b364fb5 100644 --- a/contrib/llvm/projects/libunwind/src/assembly.h +++ b/contrib/llvm/projects/libunwind/src/assembly.h @@ -35,19 +35,34 @@ #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) #if defined(__APPLE__) + #define SYMBOL_IS_FUNC(name) +#define NO_EXEC_STACK_DIRECTIVE + #elif defined(__ELF__) + #if defined(__arm__) #define SYMBOL_IS_FUNC(name) .type name,%function #else #define SYMBOL_IS_FUNC(name) .type name,@function #endif + +#if defined(__GNU__) || defined(__ANDROID__) || defined(__FreeBSD__) +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits #else +#define NO_EXEC_STACK_DIRECTIVE +#endif + +#else + #define SYMBOL_IS_FUNC(name) \ .def name SEPARATOR \ .scl 2 SEPARATOR \ .type 32 SEPARATOR \ .endef + +#define NO_EXEC_STACK_DIRECTIVE + #endif #define DEFINE_LIBUNWIND_FUNCTION(name) \ diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile index 9507d9918a43..9855c9f8f1e8 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mdocml/Makefile @@ -15,7 +15,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -VERSION = 1.14.2 +VERSION = 1.14.3 # === LIST OF FILES ==================================================== diff --git a/contrib/mdocml/NEWS b/contrib/mdocml/NEWS index d62ac4b73dc4..3d35e2b7bdc5 100644 --- a/contrib/mdocml/NEWS +++ b/contrib/mdocml/NEWS @@ -2,6 +2,21 @@ $Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $ This file lists the most important changes in the mandoc.bsd.lv distribution. +Changes in version 1.14.3, released on August 5, 2017 + + --- BUG FIXES --- + * man(7): Do not crash with out-of-bounds read access to a constant + array if .sp or a blank line immediately precedes .SS or .SH. + * mdoc(7): Do not crash with out-of-bounds read access to a constant + array if .sp or a blank line precede the first .Sh macro. + * tbl(7): Ignore explicitly specified negative column widths rather than + wrapping around to huge numbers and risking memory exhaustion. + * man(1): No longer use names that only occur in the SYNOPSIS section. + Gets rid of some surprising behaviour and bogus warnings. + --- THANKS TO --- + Leah Neukirchen (Void Linux), Markus Waldeck (Debian), + Peter Bui (nd.edu), and Yuri Pankov (illumos) for bug reports. + Changes in version 1.14.2, released on July 28, 2017 --- MAJOR NEW FEATURES --- diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c index fcdb45df8ddb..8946a05067a7 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mdocml/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.208 2017/06/25 11:42:02 schwarze Exp $ */ +/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017 Ingo Schwarze @@ -673,7 +673,7 @@ pre_SS(DECL_ARGS) do { n = n->prev; - } while (n != NULL && n->tok != TOKEN_NONE && + } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) break; @@ -735,7 +735,7 @@ pre_SH(DECL_ARGS) do { n = n->prev; - } while (n != NULL && n->tok != TOKEN_NONE && + } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL)) break; diff --git a/contrib/mdocml/mansearch.c b/contrib/mdocml/mansearch.c index c889aecf52f2..0d60c3bed731 100644 --- a/contrib/mdocml/mansearch.c +++ b/contrib/mdocml/mansearch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013-2017 Ingo Schwarze @@ -171,7 +171,9 @@ mansearch(const struct mansearch *search, page = dbm_page_get(rp->page); if (lstmatch(search->sec, page->sect) == 0 || - lstmatch(search->arch, page->arch) == 0) + lstmatch(search->arch, page->arch) == 0 || + (search->argmode == ARG_NAME && + rp->bits <= (int32_t)(NAME_SYN & NAME_MASK))) continue; if (res == NULL) { @@ -452,14 +454,28 @@ lstlen(const char *cp, size_t sep) { size_t sz; - for (sz = 0;; sz++) { - if (cp[0] == '\0') { - if (cp[1] == '\0') - break; - sz += sep - 1; - } else if (cp[0] < ' ') - sz--; - cp++; + for (sz = 0; *cp != '\0'; cp++) { + + /* Skip names appearing only in the SYNOPSIS. */ + if (*cp <= (char)(NAME_SYN & NAME_MASK)) { + while (*cp != '\0') + cp++; + continue; + } + + /* Skip name class markers. */ + if (*cp < ' ') + cp++; + + /* Print a separator before each but the first string. */ + if (sz) + sz += sep; + + /* Copy one string. */ + while (*cp != '\0') { + sz++; + cp++; + } } return sz; } @@ -471,19 +487,34 @@ lstlen(const char *cp, size_t sep) static void lstcat(char *buf, size_t *i, const char *cp, const char *sep) { - const char *s; + const char *s; + size_t i_start; - for (;;) { - if (cp[0] == '\0') { - if (cp[1] == '\0') - break; + for (i_start = *i; *cp != '\0'; cp++) { + + /* Skip names appearing only in the SYNOPSIS. */ + if (*cp <= (char)(NAME_SYN & NAME_MASK)) { + while (*cp != '\0') + cp++; + continue; + } + + /* Skip name class markers. */ + if (*cp < ' ') + cp++; + + /* Print a separator before each but the first string. */ + if (*i > i_start) { s = sep; while (*s != '\0') buf[(*i)++] = *s++; - } else if (cp[0] >= ' ') - buf[(*i)++] = cp[0]; - cp++; + } + + /* Copy one string. */ + while (*cp != '\0') + buf[(*i)++] = *cp++; } + } /* diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c index de36bb843eb2..3a9b86f3fd2b 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mdocml/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.350 2017/07/20 12:54:02 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -1137,8 +1137,6 @@ post_fname(POST_ARGS) if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*'))) mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse, n->line, n->pos + pos, n->string); - if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL) - mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1); } static void @@ -1205,9 +1203,8 @@ post_nm(POST_ARGS) n = mdoc->last; - if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) && - n->child != NULL && n->child->type == ROFFT_TEXT && - mdoc->meta.msec != NULL) + if (n->sec == SEC_NAME && n->child != NULL && + n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL) mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1); if (n->last != NULL && @@ -1931,7 +1928,7 @@ post_root(POST_ARGS) /* Check that we begin with a proper `Sh'. */ n = mdoc->first->child; - while (n != NULL && n->tok != TOKEN_NONE && + while (n != NULL && n->tok >= MDOC_Dd && mdoc_macros[n->tok].flags & MDOC_PROLOGUE) n = n->next; diff --git a/contrib/mdocml/tbl_html.c b/contrib/mdocml/tbl_html.c index 06fae5eba1a7..d59f1635d013 100644 --- a/contrib/mdocml/tbl_html.c +++ b/contrib/mdocml/tbl_html.c @@ -1,4 +1,4 @@ -/* $Id: tbl_html.c,v 1.22 2017/06/12 20:14:18 schwarze Exp $ */ +/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -49,6 +49,9 @@ html_tbl_strlen(const char *p, void *arg) static size_t html_tbl_sulen(const struct roffsu *su, void *arg) { + if (su->scale < 0.0) + return 0; + switch (su->unit) { case SCALE_FS: /* 2^16 basic units */ return su->scale * 65536.0 / 24.0; diff --git a/contrib/mdocml/tbl_term.c b/contrib/mdocml/tbl_term.c index fd03b81303f9..c154a0e9b967 100644 --- a/contrib/mdocml/tbl_term.c +++ b/contrib/mdocml/tbl_term.c @@ -1,4 +1,4 @@ -/* $Id: tbl_term.c,v 1.56 2017/07/08 13:43:15 schwarze Exp $ */ +/* $Id: tbl_term.c,v 1.57 2017/07/31 16:14:10 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons * Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze @@ -51,7 +51,10 @@ static void tbl_word(struct termp *, const struct tbl_dat *); static size_t term_tbl_sulen(const struct roffsu *su, void *arg) { - return term_hen((const struct termp *)arg, su); + int i; + + i = term_hen((const struct termp *)arg, su); + return i > 0 ? i : 0; } static size_t diff --git a/contrib/one-true-awk/awk.h b/contrib/one-true-awk/awk.h index a36cdb151e75..5564af7619a4 100644 --- a/contrib/one-true-awk/awk.h +++ b/contrib/one-true-awk/awk.h @@ -126,6 +126,12 @@ extern Cell *rlengthloc; /* RLENGTH */ #define FTOUPPER 12 #define FTOLOWER 13 #define FFLUSH 14 +#define FAND 15 +#define FFOR 16 +#define FXOR 17 +#define FCOMPL 18 +#define FLSHIFT 19 +#define FRSHIFT 20 /* Node: parse tree is made of nodes, with Cell's at bottom */ diff --git a/contrib/one-true-awk/lex.c b/contrib/one-true-awk/lex.c index 0c65a9fe3292..3aeffb7f0539 100644 --- a/contrib/one-true-awk/lex.c +++ b/contrib/one-true-awk/lex.c @@ -47,9 +47,11 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "BEGIN", XBEGIN, XBEGIN }, { "END", XEND, XEND }, { "NF", VARNF, VARNF }, + { "and", FAND, BLTIN }, { "atan2", FATAN, BLTIN }, { "break", BREAK, BREAK }, { "close", CLOSE, CLOSE }, + { "compl", FCOMPL, BLTIN }, { "continue", CONTINUE, CONTINUE }, { "cos", FCOS, BLTIN }, { "delete", DELETE, DELETE }, @@ -69,13 +71,16 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "int", FINT, BLTIN }, { "length", FLENGTH, BLTIN }, { "log", FLOG, BLTIN }, + { "lshift", FLSHIFT, BLTIN }, { "match", MATCHFCN, MATCHFCN }, { "next", NEXT, NEXT }, { "nextfile", NEXTFILE, NEXTFILE }, + { "or", FFOR, BLTIN }, { "print", PRINT, PRINT }, { "printf", PRINTF, PRINTF }, { "rand", FRAND, BLTIN }, { "return", RETURN, RETURN }, + { "rshift", FRSHIFT, BLTIN }, { "sin", FSIN, BLTIN }, { "split", SPLIT, SPLIT }, { "sprintf", SPRINTF, SPRINTF }, @@ -87,6 +92,7 @@ Keyword keywords[] ={ /* keep sorted: binary searched */ { "tolower", FTOLOWER, BLTIN }, { "toupper", FTOUPPER, BLTIN }, { "while", WHILE, WHILE }, + { "xor", FXOR, BLTIN }, }; #define RET(x) { if(dbg)printf("lex %s\n", tokname(x)); return(x); } diff --git a/contrib/one-true-awk/lib.c b/contrib/one-true-awk/lib.c index 5eeb53d4679d..e2688a2debe4 100644 --- a/contrib/one-true-awk/lib.c +++ b/contrib/one-true-awk/lib.c @@ -62,6 +62,7 @@ void recinit(unsigned int n) || (fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *))) == NULL || (fldtab[0] = (Cell *) malloc(sizeof(Cell))) == NULL ) FATAL("out of space for $0 and fields"); + *record = '\0'; *fldtab[0] = dollar0; fldtab[0]->sval = record; fldtab[0]->nval = tostring("0"); @@ -616,7 +617,7 @@ void eprint(void) /* try to print context around error */ static int been_here = 0; extern char ebuf[], *ep; - if (compile_time == 2 || compile_time == 0 || been_here++ > 0) + if (compile_time == 2 || compile_time == 0 || been_here++ > 0 || ebuf == ep) return; p = ep - 1; if (p > ebuf && *p == '\n') diff --git a/contrib/one-true-awk/run.c b/contrib/one-true-awk/run.c index 1e5f1c25a69c..1b02a79fb46b 100644 --- a/contrib/one-true-awk/run.c +++ b/contrib/one-true-awk/run.c @@ -918,7 +918,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co break; case 'c': if (isnum(x)) { - if (getfval(x)) + if ((int)getfval(x)) sprintf(p, fmt, (int) getfval(x)); else { *p++ = '\0'; /* explicit null byte */ @@ -1476,7 +1476,7 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis { Cell *x, *y; Awkfloat u; - int t; + int t, i; Awkfloat tmp; char *p, *buf; Node *nextarg; @@ -1516,6 +1516,76 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis nextarg = nextarg->nnext; } break; + case FCOMPL: + u = ~((int)getfval(x)); + break; + case FAND: + if (nextarg == NULL) { + WARNING("and requires two arguments; returning 0"); + u = 0; + break; + } + i = ((int)getfval(x)); + while (nextarg != NULL) { + y = execute(nextarg); + i &= (int)getfval(y); + tempfree(y); + nextarg = nextarg->nnext; + } + u = i; + break; + case FFOR: + if (nextarg == NULL) { + WARNING("or requires two arguments; returning 0"); + u = 0; + break; + } + i = ((int)getfval(x)); + while (nextarg != NULL) { + y = execute(nextarg); + i |= (int)getfval(y); + tempfree(y); + nextarg = nextarg->nnext; + } + u = i; + break; + case FXOR: + if (nextarg == NULL) { + WARNING("xor requires two arguments; returning 0"); + u = 0; + break; + } + i = ((int)getfval(x)); + while (nextarg != NULL) { + y = execute(nextarg); + i ^= (int)getfval(y); + tempfree(y); + nextarg = nextarg->nnext; + } + u = i; + break; + case FLSHIFT: + if (nextarg == NULL) { + WARNING("lshift requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) << ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; + case FRSHIFT: + if (nextarg == NULL) { + WARNING("rshift requires two arguments; returning 0"); + u = 0; + break; + } + y = execute(a[1]->nnext); + u = ((int)getfval(x)) >> ((int)getfval(y)); + tempfree(y); + nextarg = nextarg->nnext; + break; case FSYSTEM: fflush(stdout); /* in case something is buffered already */ u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c index a007d48d9dde..c74065a08836 100644 --- a/contrib/traceroute/traceroute.c +++ b/contrib/traceroute/traceroute.c @@ -227,7 +227,7 @@ static const char rcsid[] = #include -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER #include #include #endif @@ -369,7 +369,7 @@ extern int optind; extern int opterr; extern char *optarg; -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER static cap_channel_t *capdns; #endif @@ -521,7 +521,7 @@ main(int argc, char **argv) int requestPort = -1; int sump = 0; int sockerrno; -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER const char *types[] = { "NAME", "ADDR" }; int families[1]; cap_channel_t *casper; @@ -556,7 +556,7 @@ main(int argc, char **argv) exit(1); } -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER casper = cap_init(); if (casper == NULL) errx(1, "unable to create casper process"); @@ -568,7 +568,7 @@ main(int argc, char **argv) families[0] = AF_INET; if (cap_dns_family_limit(capdns, families, 1) < 0) errx(1, "unable to limit access to system.dns service"); -#endif /* HAVE_LIBCASPER */ +#endif /* WITH_CASPER */ #ifdef IPCTL_DEFTTL { @@ -584,7 +584,7 @@ main(int argc, char **argv) max_ttl = 30; #endif -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER cap_close(casper); #endif @@ -1006,7 +1006,7 @@ main(int argc, char **argv) exit(1); } -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER cansandbox = true; #else if (nflag) @@ -1851,7 +1851,7 @@ inetname(struct in_addr in) else { cp = strchr(domain, '.'); if (cp == NULL) { -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (capdns != NULL) hp = cap_gethostbyname(capdns, domain); else @@ -1870,7 +1870,7 @@ inetname(struct in_addr in) } } if (!nflag && in.s_addr != INADDR_ANY) { -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (capdns != NULL) hp = cap_gethostbyaddr(capdns, (char *)&in, sizeof(in), AF_INET); @@ -1922,7 +1922,7 @@ gethostinfo(register char *hostname) return (hi); } -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (capdns != NULL) hp = cap_gethostbyname(capdns, hostname); else diff --git a/contrib/tzdata/CONTRIBUTING b/contrib/tzdata/CONTRIBUTING index 22addd2b546f..716f32b3a39a 100644 --- a/contrib/tzdata/CONTRIBUTING +++ b/contrib/tzdata/CONTRIBUTING @@ -5,20 +5,26 @@ change timekeeping rules erratically and sometimes with little warning, the data entries do not cover all of civil time before 1970, and undoubtedly errors remain in the code and data. Feel free to fill gaps or fix mistakes, and please email improvements -to tz@iana.org for use in the future. +to tz@iana.org for use in the future. In your email, please give +reliable sources that reviewers can check. + +----- + +Developers can contribute technical changes to the source code and +data as follows. To email small changes, please run a POSIX shell command like 'diff -u old/europe new/europe >myfix.patch', and attach myfix.patch to the email. -For more-elaborate changes, please read the Theory file and browse -the mailing list archives for -examples of patches that tend to work well. Ideally, additions to +For more-elaborate changes, please read the theory.html file and browse +the mailing list archives for +examples of patches that tend to work well. Additions to data should contain commentary citing reliable sources as -justification. +justification. Citations should use https: URLs if available. Please submit changes against either the latest release in - or the master branch of the development + or the master branch of the development repository. If you use Git the following workflow may be helpful: * Copy the development repository. diff --git a/contrib/tzdata/LICENSE b/contrib/tzdata/LICENSE index 148eb232b673..8ba4399c622d 100644 --- a/contrib/tzdata/LICENSE +++ b/contrib/tzdata/LICENSE @@ -1,4 +1,5 @@ -With a few exceptions, all files in the tz code and data (including -this one) are in the public domain. The exceptions are date.c, -newstrftime.3, and strftime.c, which contain material derived from BSD -and which use the BSD 3-clause license. +Unless specified below, all files in the tz code and data (including +this LICENSE file) are in the public domain. + +If the files date.c, newstrftime.3, and strftime.c are present, they +contain material derived from BSD and use the BSD 3-clause license. diff --git a/contrib/tzdata/Makefile b/contrib/tzdata/Makefile index 8067ba087b43..c92edc064084 100644 --- a/contrib/tzdata/Makefile +++ b/contrib/tzdata/Makefile @@ -49,6 +49,7 @@ TOPDIR= /usr/local # "Compiled" time zone information is placed in the "TZDIR" directory # (and subdirectories). # Use an absolute path name for TZDIR unless you're just testing the software. +# TZDIR_BASENAME should not contain "/" and should not be ".", ".." or empty. TZDIR_BASENAME= zoneinfo TZDIR= $(TOPDIR)/etc/$(TZDIR_BASENAME) @@ -75,7 +76,7 @@ LIBDIR= $(TOPDIR)/lib # If you want only POSIX time, with time values interpreted as # seconds since the epoch (not counting leap seconds), use # REDO= posix_only -# below. If you want want only "right" time, with values interpreted +# below. If you want only "right" time, with values interpreted # as seconds since the epoch (counting leap seconds), use # REDO= right_only # below. If you want both sets of data available, with leap seconds not @@ -92,6 +93,24 @@ LIBDIR= $(TOPDIR)/lib REDO= posix_right +# To install data in text form that has all the information of the binary data, +# (optionally incorporating leap second information), use +# TZDATA_TEXT= tzdata.zi leapseconds +# To install text data without leap second information (e.g., because +# REDO='posix_only'), use +# TZDATA_TEXT= tzdata.zi +# To avoid installing text data, use +# TZDATA_TEXT= + +TZDATA_TEXT= leapseconds tzdata.zi + +# For backward-compatibility links for old zone names, use +# BACKWARD= backward pacificnew +# To omit these links, use +# BACKWARD= + +BACKWARD= backward pacificnew + # If you want out-of-scope and often-wrong data from the file 'backzone', use # PACKRATDATA= backzone # To omit this data, use @@ -99,6 +118,11 @@ REDO= posix_right PACKRATDATA= +# The name of a locale using the UTF-8 encoding, used during self-tests. +# The tests are skipped if the name does not appear to work on this system. + +UTF8_LOCALE= en_US.utf8 + # Since "." may not be in PATH... YEARISTYPE= ./yearistype @@ -106,50 +130,53 @@ YEARISTYPE= ./yearistype # Non-default libraries needed to link. LDLIBS= -# Add the following to the end of the "CFLAGS=" line as needed. +# Add the following to the end of the "CFLAGS=" line as needed to override +# defaults specified in the source code. "-DFOO" is equivalent to "-DFOO=1". # -DBIG_BANG=-9999999LL if the Big Bang occurred at time -9999999 (see zic.c) -# -DHAVE_DECL_ASCTIME_R=0 if does not declare asctime_r -# -DHAVE_DIRECT_H if mkdir needs (MS-Windows) -# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS) -# -DHAVE_GETTEXT=1 if 'gettext' works (e.g., GNU/Linux, FreeBSD, Solaris) -# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares -# ctime_r and asctime_r incompatibly with the POSIX standard -# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined). -# -DHAVE_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h" -# -DHAVE_LINK=0 if your system lacks a link function -# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function -# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz -# This defaults to 1 if a working localtime_rz seems to be available. -# localtime_rz can make zdump significantly faster, but is nonstandard. -# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare -# functions like 'link' or variables like 'tzname' required by POSIX -# -DHAVE_STDINT_H=1 if you have a pre-C99 compiler with "stdint.h" -# -DHAVE_STRFTIME_L=1 if declares locale_t and strftime_l -# This defaults to 0 if _POSIX_VERSION < 200809, 1 otherwise. -# -DHAVE_STRDUP=0 if your system lacks the strdup function -# -DHAVE_SYMLINK=0 if your system lacks the symlink function -# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h" -# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h" -# -DHAVE_TZSET=0 if your system lacks a tzset function -# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?) -# -DEPOCH_LOCAL=1 if the 'time' function returns local time not UT +# -DDEPRECATE_TWO_DIGIT_YEARS for optional runtime warnings about strftime +# formats that generate only the last two digits of year numbers +# -DEPOCH_LOCAL if the 'time' function returns local time not UT # -DEPOCH_OFFSET=N if the 'time' function returns a value N greater # than what POSIX specifies, assuming local time is UT. # For example, N is 252460800 on AmigaOS. -# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1 -# if you do not want run time warnings about formats that may cause -# year 2000 grief -# -Dssize_t=long on ancient hosts that lack ssize_t -# -DTHREAD_SAFE=1 to make localtime.c thread-safe, as POSIX requires; +# -DHAVE_DECL_ASCTIME_R=0 if does not declare asctime_r +# -DHAVE_DECL_ENVIRON if declares 'environ' +# -DHAVE_DIRECT_H if mkdir needs (MS-Windows) +# -DHAVE_GENERIC=0 if _Generic does not work +# -DHAVE_GETTEXT if 'gettext' works (e.g., GNU/Linux, FreeBSD, Solaris) +# -DHAVE_INCOMPATIBLE_CTIME_R if your system's time.h declares +# ctime_r and asctime_r incompatibly with the POSIX standard +# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined). +# -DHAVE_INTTYPES_H if you have a non-C99 compiler with +# -DHAVE_LINK=0 if your system lacks a link function +# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function +# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz +# localtime_rz can make zdump significantly faster, but is nonstandard. +# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare +# functions like 'link' or variables like 'tzname' required by POSIX +# -DHAVE_SNPRINTF=0 if your system lacks the snprintf function +# -DHAVE_STDBOOL_H if you have a non-C99 compiler with +# -DHAVE_STDINT_H if you have a non-C99 compiler with +# -DHAVE_STRFTIME_L if declares locale_t and strftime_l +# -DHAVE_STRDUP=0 if your system lacks the strdup function +# -DHAVE_SYMLINK=0 if your system lacks the symlink function +# -DHAVE_SYS_STAT_H=0 if your compiler lacks a +# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a +# -DHAVE_TZSET=0 if your system lacks a tzset function +# -DHAVE_UNISTD_H=0 if your compiler lacks a +# -Dlocale_t=XXX if your system uses XXX instead of locale_t +# -Dssize_t=long on hosts like MS-Windows that lack ssize_t +# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires; # not needed by the main-program tz code, which is single-threaded. # Append other compiler flags as needed, e.g., -pthread on GNU/Linux. # -Dtime_tz=\"T\" to use T as the time_t type, rather than the system time_t +# This is intended for internal use only; it mangles external names. # -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz" # -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory; # the default is system-supplied, typically "/usr/lib/locale" # -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified # DST transitions if the time zone files cannot be accessed -# -DUNINIT_TRAP=1 if reading uninitialized storage can cause problems +# -DUNINIT_TRAP if reading uninitialized storage can cause problems # other than simply getting garbage data # -DUSE_LTZ=0 to build zdump with the system time zone library # Also set TZDOBJS=zdump.o and CHECK_TIME_T_ALTERNATIVES= below. @@ -157,26 +184,27 @@ LDLIBS= # (or some other number) to set the maximum time zone abbreviation length # that zic will accept without a warning (the default is 6) # $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking -GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \ - -Wall -Wextra \ - -Wbad-function-cast -Wcast-align -Wdate-time \ - -Wdeclaration-after-statement \ - -Wdouble-promotion \ - -Wformat=2 -Winit-self -Wjump-misses-init \ - -Wlogical-op -Wmissing-prototypes -Wnested-externs \ - -Wold-style-definition -Woverlength-strings -Wpointer-arith \ - -Wshadow -Wstrict-prototypes -Wsuggest-attribute=const \ - -Wsuggest-attribute=format -Wsuggest-attribute=noreturn \ - -Wsuggest-attribute=pure -Wtrampolines \ - -Wundef -Wunused -Wwrite-strings \ - -Wno-address -Wno-format-nonliteral -Wno-sign-compare \ - -Wno-type-limits -Wno-unused-parameter -# -# If you want to use System V compatibility code, add -# -DUSG_COMPAT -# to the end of the "CFLAGS=" line. This arrange for "timezone" and "daylight" -# variables to be kept up-to-date by the time conversion functions. Neither -# "timezone" nor "daylight" is described in X3J11's work. +# Select instrumentation via "make GCC_INSTRUMENT='whatever'". +GCC_INSTRUMENT = \ + -fsanitize=undefined -fsanitize-address-use-after-scope \ + -fsanitize-undefined-trap-on-error -fstack-protector +GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ + $(GCC_INSTRUMENT) \ + -Wall -Wextra \ + -Walloc-size-larger-than=100000 -Warray-bounds=2 \ + -Wbad-function-cast -Wcast-align -Wdate-time \ + -Wdeclaration-after-statement -Wdouble-promotion \ + -Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \ + -Winit-self -Wjump-misses-init -Wlogical-op \ + -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ + -Wold-style-definition -Woverlength-strings -Wpointer-arith \ + -Wshadow -Wshift-overflow=2 -Wstrict-prototypes -Wstringop-overflow=5 \ + -Wsuggest-attribute=const -Wsuggest-attribute=format \ + -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \ + -Wtrampolines -Wundef -Wuninitialized -Wunused \ + -Wvariadic-macros -Wvla -Wwrite-strings \ + -Wno-address -Wno-format-nonliteral -Wno-sign-compare \ + -Wno-type-limits -Wno-unused-parameter # # If your system has a "GMT offset" field in its "struct tm"s # (or if you decide to add such a field in your system's "time.h" file), @@ -189,6 +217,31 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \ # and define NO_TM_ZONE to suppress any guessing. These two fields are not # required by POSIX, but are widely available on GNU/Linux and BSD systems. # +# The next batch of options control support for external variables +# exported by tzcode. In practice these variables are less useful +# than TM_GMTOFF and TM_ZONE. However, most of them are standardized. +# # +# # To omit or support the external variable "tzname", add one of: +# # -DHAVE_TZNAME=0 +# # -DHAVE_TZNAME=1 +# # to the "CFLAGS=" line. "tzname" is required by POSIX 1988 and later. +# # If not defined, the code attempts to guess HAVE_TZNAME from other macros. +# # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause +# # crashes when combined with some platforms' standard libraries, +# # presumably due to memory allocation issues. +# # +# # To omit or support the external variables "timezone" and "daylight", add +# # -DUSG_COMPAT=0 +# # -DUSG_COMPAT=1 +# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by +# # Unix Systems Group code and are required by POSIX 2008 (with XSI) and later. +# # If not defined, the code attempts to guess USG_COMPAT from other macros. +# # +# # To support the external variable "altzone", add +# # -DALTZONE +# # to the end of the "CFLAGS=" line; although "altzone" appeared in +# # System V Release 3.1 it has not been standardized. +# # If you want functions that were inspired by early versions of X3J11's work, # add # -DSTD_INSPIRED @@ -226,11 +279,6 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \ # -DALL_STATE # to the end of the "CFLAGS=" line. Storage is obtained by calling malloc. # -# If you want an "altzone" variable (a la System V Release 3.1), add -# -DALTZONE -# to the end of the "CFLAGS=" line. -# This variable is not described in X3J11's work. -# # NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put # out by the National Institute of Standards and Technology # which claims to test C and Posix conformance. If you want to pass PCTS, add @@ -240,8 +288,8 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \ # If you want strict compliance with XPG4 as of 1994-04-09, add # -DXPG4_1994_04_09 # to the end of the "CFLAGS=" line. This causes "strftime" to always return -# 53 as a week number (rather than 52 or 53) for those days in January that -# before the first Monday in January when a "%V" format is used and January 1 +# 53 as a week number (rather than 52 or 53) for January days before +# January's first Monday when a "%V" format is used and January 1 # falls on a Friday, Saturday, or Sunday. CFLAGS= @@ -265,7 +313,7 @@ ZFLAGS= # How to use zic to install tz binary files. -ZIC_INSTALL= $(ZIC) -y $(YEARISTYPE) -d $(DESTDIR)$(TZDIR) $(LEAPSECONDS) +ZIC_INSTALL= $(ZIC) -d $(DESTDIR)$(TZDIR) $(LEAPSECONDS) # The name of a Posix-compliant 'awk' on your system. AWK= awk @@ -289,6 +337,7 @@ SGML_CATALOG_FILES= \ # The name, arguments and environment of a program to validate your web pages. # See for a validator, and # for a validation library. +# Set VALIDATE=':' if you do not have such a program. VALIDATE = nsgmls VALIDATE_FLAGS = -s -B -wall -wno-unused-param VALIDATE_ENV = \ @@ -355,7 +404,7 @@ AR= ar RANLIB= : TZCOBJS= zic.o -TZDOBJS= zdump.o localtime.o asctime.o +TZDOBJS= zdump.o localtime.o asctime.o strftime.o DATEOBJS= date.o localtime.o strftime.o asctime.o LIBSRCS= localtime.c asctime.c difftime.c LIBOBJS= localtime.o asctime.o difftime.o @@ -370,33 +419,35 @@ MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \ time2posix.3.txt \ tzfile.5.txt tzselect.8.txt zic.8.txt zdump.8.txt \ date.1.txt -COMMON= CONTRIBUTING LICENSE Makefile NEWS README Theory version +COMMON= calendars CONTRIBUTING LICENSE Makefile \ + NEWS README theory.html version WEB_PAGES= tz-art.htm tz-how-to.html tz-link.htm DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES) PRIMARY_YDATA= africa antarctica asia australasia \ europe northamerica southamerica -YDATA= $(PRIMARY_YDATA) pacificnew etcetera backward +YDATA= $(PRIMARY_YDATA) etcetera $(BACKWARD) NDATA= systemv factory TDATA= $(YDATA) $(NDATA) ZONETABLES= zone1970.tab zone.tab -TABDATA= iso3166.tab leapseconds $(ZONETABLES) +TABDATA= iso3166.tab $(TZDATA_TEXT) $(ZONETABLES) LEAP_DEPS= leapseconds.awk leap-seconds.list -DATA= $(YDATA) $(NDATA) backzone $(TABDATA) \ - leap-seconds.list yearistype.sh -AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk +TZDATA_ZI_DEPS= zishrink.awk $(TDATA) $(PACKRATDATA) +DATA= $(YDATA) $(NDATA) backzone iso3166.tab leap-seconds.list \ + leapseconds yearistype.sh $(ZONETABLES) +AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk zishrink.awk MISC= $(AWK_SCRIPTS) zoneinfo2tdf.pl TZS_YEAR= 2050 TZS= to$(TZS_YEAR).tzs TZS_NEW= to$(TZS_YEAR)new.tzs TZS_DEPS= $(PRIMARY_YDATA) asctime.c localtime.c \ private.h tzfile.h zdump.c zic.c -ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) $(TZS) +ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) $(TZS) tzdata.zi # Consult these files when deciding whether to rebuild the 'version' file. # This list is not the same as the output of 'git ls-files', since # .gitignore is not distributed. VERSION_DEPS= \ - CONTRIBUTING LICENSE Makefile NEWS README Theory \ + calendars CONTRIBUTING LICENSE Makefile NEWS README \ africa antarctica asctime.c asia australasia \ backward backzone \ checklinks.awk checktab.awk \ @@ -405,7 +456,7 @@ VERSION_DEPS= \ leap-seconds.list leapseconds.awk localtime.c \ newctime.3 newstrftime.3 newtzset.3 northamerica \ pacificnew private.h \ - southamerica strftime.c systemv \ + southamerica strftime.c systemv theory.html \ time2posix.3 tz-art.htm tz-how-to.html tz-link.htm \ tzfile.5 tzfile.h tzselect.8 tzselect.ksh \ workman.sh yearistype.sh \ @@ -427,7 +478,7 @@ install: all $(DATA) $(REDO) $(MANS) $(DESTDIR)$(MANDIR)/man3 $(DESTDIR)$(MANDIR)/man5 \ $(DESTDIR)$(MANDIR)/man8 $(ZIC_INSTALL) -l $(LOCALTIME) -p $(POSIXRULES) - cp -f iso3166.tab $(ZONETABLES) $(DESTDIR)$(TZDIR)/. + cp -f $(TABDATA) $(DESTDIR)$(TZDIR)/. cp tzselect zic zdump $(DESTDIR)$(ETCDIR)/. cp libtz.a $(DESTDIR)$(LIBDIR)/. $(RANLIB) $(DESTDIR)$(LIBDIR)/libtz.a @@ -448,6 +499,11 @@ version: $(VERSION_DEPS) printf '%s\n' "$$V" >$@.out mv $@.out $@ +# This file can be tailored by setting BACKWARD, PACKRATDATA, etc. +tzdata.zi: $(TZDATA_ZI_DEPS) + LC_ALL=C $(AWK) -f zishrink.awk $(TDATA) $(PACKRATDATA) >$@.out + mv $@.out $@ + version.h: version VERSION=`cat version` && printf '%s\n' \ 'static char const PKGVERSION[]="($(PACKAGE)) ";' \ @@ -473,6 +529,7 @@ leapseconds: $(LEAP_DEPS) # Arguments to pass to submakes of install_data. # They can be overridden by later submake arguments. INSTALLARGS = \ + BACKWARD=$(BACKWARD) \ DESTDIR=$(DESTDIR) \ LEAPSECONDS='$(LEAPSECONDS)' \ PACKRATDATA='$(PACKRATDATA)' \ @@ -481,10 +538,8 @@ INSTALLARGS = \ ZIC='$(ZIC)' # 'make install_data' installs one set of tz binary files. -# It can be tailored by setting LEAPSECONDS, PACKRATDATA, etc. -install_data: zic leapseconds yearistype $(PACKRATDATA) $(TDATA) - $(ZIC_INSTALL) $(TDATA) - $(AWK) '/^Rule/' $(TDATA) | $(ZIC_INSTALL) - $(PACKRATDATA) +install_data: zic leapseconds yearistype tzdata.zi + $(ZIC_INSTALL) tzdata.zi posix_only: $(MAKE) $(INSTALLARGS) LEAPSECONDS= install_data @@ -521,14 +576,14 @@ posix_packrat: zones: $(REDO) -$(TZS_NEW): $(TDATA) zdump zic +$(TZS_NEW): tzdata.zi zdump zic mkdir -p tzs.dir - $(zic) -d tzs.dir $(TDATA) - $(AWK) '/^Link/{print $$1 "\t" $$2 "\t" $$3}' \ - $(TDATA) | LC_ALL=C sort >$@.out + $(zic) -d tzs.dir tzdata.zi + $(AWK) '/^L/{print "Link\t" $$2 "\t" $$3}' \ + tzdata.zi | LC_ALL=C sort >$@.out wd=`pwd` && \ zones=`$(AWK) -v wd="$$wd" \ - '/^Zone/{print wd "/tzs.dir/" $$2}' $(TDATA) \ + '/^Z/{print wd "/tzs.dir/" $$2}' tzdata.zi \ | LC_ALL=C sort` && \ ./zdump -i -c $(TZS_YEAR) $$zones >>$@.out sed 's,^TZ=".*tzs\.dir/,TZ=",' $@.out >$@.sed.out @@ -564,24 +619,37 @@ tzselect: tzselect.ksh version chmod +x $@.out mv $@.out $@ -check: check_character_set check_white_space check_links check_sorted \ - check_tables check_tzs check_web +check: check_character_set check_white_space check_links \ + check_name_lengths check_sorted \ + check_tables check_web check_zishrink check_tzs check_character_set: $(ENCHILADA) - LC_ALL=en_US.utf8 && export LC_ALL && \ + test ! '$(UTF8_LOCALE)' || \ + ! printf 'A\304\200B\n' | \ + LC_ALL='$(UTF8_LOCALE)' grep -q '^A.B$$' >/dev/null 2>&1 || { \ + LC_ALL='$(UTF8_LOCALE)' && export LC_ALL && \ sharp='#' && \ ! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \ $(MISC) $(SOURCES) $(WEB_PAGES) \ - CONTRIBUTING LICENSE Makefile README version && \ + CONTRIBUTING LICENSE Makefile README \ + version tzdata.zi && \ ! grep -Env $(SAFE_SHARP_LINE) $(TDATA) backzone \ leapseconds yearistype.sh zone.tab && \ - ! grep -Env $(OK_LINE) $(ENCHILADA) + ! grep -Env $(OK_LINE) $(ENCHILADA); \ + } check_white_space: $(ENCHILADA) patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \ ! grep -En "$$pat" $(ENCHILADA) ! grep -n '[[:space:]]$$' $(ENCHILADA) +PRECEDES_FILE_NAME = ^(Zone|Link[[:space:]]+[^[:space:]]+)[[:space:]]+ +FILE_NAME_COMPONENT_TOO_LONG = \ + $(PRECEDES_FILE_NAME)[^[:space:]]*[^/[:space:]]{15} + +check_name_lengths: $(TDATA) backzone + ! grep -En '$(FILE_NAME_COMPONENT_TOO_LONG)' $(TDATA) backzone + CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; } check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab @@ -596,6 +664,7 @@ check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab check_links: checklinks.awk $(TDATA) $(AWK) -f checklinks.awk $(TDATA) + $(AWK) -f checklinks.awk tzdata.zi check_tables: checktab.awk $(PRIMARY_YDATA) $(ZONETABLES) for tab in $(ZONETABLES); do \ @@ -606,14 +675,32 @@ check_tables: checktab.awk $(PRIMARY_YDATA) $(ZONETABLES) check_tzs: $(TZS) $(TZS_NEW) diff -u $(TZS) $(TZS_NEW) -check_web: $(WEB_PAGES) - $(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES) +# This checks only the HTML 4.01 strict page. +# To check the the other pages, use . +check_web: tz-how-to.html + $(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) tz-how-to.html + +# Check that tzdata.zi generates the same binary data that its sources do. +check_zishrink: tzdata.zi zic leapseconds $(PACKRATDATA) $(TDATA) + for type in posix right; do \ + mkdir -p time_t.dir/$$type time_t.dir/$$type-shrunk && \ + case $$type in \ + right) leap='-L leapseconds';; \ + *) leap=;; \ + esac && \ + $(ZIC) $$leap -d time_t.dir/$$type $(TDATA) && \ + $(AWK) '/^Rule/' $(TDATA) | \ + $(ZIC) $$leap -d time_t.dir/$$type - $(PACKRATDATA) && \ + $(ZIC) $$leap -d time_t.dir/$$type-shrunk tzdata.zi && \ + diff -r time_t.dir/$$type time_t.dir/$$type-shrunk || exit; \ + done + rm -fr time_t.dir clean_misc: rm -f core *.o *.out \ date tzselect version.h zdump zic yearistype libtz.a clean: clean_misc - rm -fr *.dir tzdb-*/ $(TZS_NEW) + rm -fr *.dir tzdata.zi tzdb-*/ $(TZS_NEW) maintainer-clean: clean @echo 'This command is intended for maintainers to use; it' @@ -667,6 +754,7 @@ set-timestamps.out: $(ENCHILADA) touch -cmr `ls -t $$file workman.sh | sed 1q` $$file.txt || \ exit; \ done + touch -cmr `ls -t $(TZDATA_ZI_DEPS) | sed 1q` tzdata.zi touch -cmr `ls -t $(TZS_DEPS) | sed 1q` $(TZS) touch -cmr `ls -t $(VERSION_DEPS) | sed 1q` version touch $@ @@ -678,7 +766,7 @@ check_public: $(MAKE) maintainer-clean $(MAKE) "CFLAGS=$(GCC_DEBUG_FLAGS)" ALL mkdir -p public.dir - for i in $(TDATA) ; do \ + for i in $(TDATA) tzdata.zi; do \ $(zic) -v -d public.dir $$i 2>&1 || exit; \ done $(zic) -v -d public.dir $(TDATA) @@ -772,8 +860,8 @@ typecheck: $(MAKE) clean ; \ done -zonenames: $(TDATA) - @$(AWK) '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA) +zonenames: tzdata.zi + @$(AWK) '/^Z/ { print $$2 } /^L/ { print $$3 }' tzdata.zi asctime.o: private.h tzfile.h date.o: private.h @@ -789,6 +877,7 @@ zic.o: private.h tzfile.h version.h .PHONY: check check_character_set check_links .PHONY: check_public check_sorted check_tables .PHONY: check_time_t_alternatives check_tzs check_web check_white_space +.PHONY: check_zishrink .PHONY: clean clean_misc force_tzs .PHONY: install install_data maintainer-clean names .PHONY: posix_only posix_packrat posix_right diff --git a/contrib/tzdata/NEWS b/contrib/tzdata/NEWS index f986cf6f0f67..bd2bec223a0b 100644 --- a/contrib/tzdata/NEWS +++ b/contrib/tzdata/NEWS @@ -1,5 +1,169 @@ News for the tz database +Release 2017c - 2017-10-20 14:49:34 -0700 + + Briefly: + Northern Cyprus switches from +03 to +02/+03 on 2017-10-29. + Fiji ends DST 2018-01-14, not 2018-01-21. + Namibia switches from +01/+02 to +02 on 2018-04-01. + Sudan switches from +03 to +02 on 2017-11-01. + Tonga likely switches from +13/+14 to +13 on 2017-11-05. + Turks & Caicos switches from -04 to -05/-04 on 2018-11-04. + A new file tzdata.zi now holds a small text copy of all data. + The zic input format has been regularized slightly. + + Changes to future time stamps + + Northern Cyprus has decided to resume EU rules starting + 2017-10-29, thus reinstituting winter time. + + Fiji ends DST 2018-01-14 instead of the 2018-01-21 previously + predicted. (Thanks to Dominic Fok.) Adjust future predictions + accordingly. + + Namibia will switch from +01 with DST to +02 all year on + 2017-09-03 at 02:00. This affects UT offsets starting 2018-04-01 + at 02:00. (Thanks to Steffen Thorsen.) + + Sudan will switch from +03 to +02 on 2017-11-01. (Thanks to Ahmed + Atyya and Yahia Abdalla.) South Sudan is not switching, so + Africa/Juba is no longer a link to Africa/Khartoum. + + Tonga has likely ended its experiment with DST, and will not + adjust its clocks on 2017-11-05. Although Tonga has not announced + whether it will continue to observe DST, the IATA is assuming that + it will not. (Thanks to David Wade.) + + Turks & Caicos will switch from -04 all year to -05 with US DST on + 2018-03-11 at 03:00. This affects UT offsets starting 2018-11-04 + at 02:00. (Thanks to Steffen Thorsen.) + + Changes to past time stamps + + Namibia switched from +02 to +01 on 1994-03-21, not 1994-04-03. + (Thanks to Arthur David Olson.) + + Detroit did not observe DST in 1967. + + Use railway time for Asia/Kolkata before 1941, by switching to + Madras local time (UT +052110) in 1870, then to IST (UT +0530) in + 1906. Also, treat 1941-2's +0630 as DST, like 1942-5. + + Europe/Dublin's 1946 and 1947 fallback transitions occurred at + 02:00 standard time, not 02:00 DST. (Thanks to Michael Deckers.) + + Pacific/Apia and Pacific/Pago_Pago switched from Antipodean to + American time in 1892, not 1879. (Thanks to Michael Deckers.) + + Adjust the 1867 transition in Alaska to better reflect the + historical record, by changing it to occur on 1867-10-18 at 15:30 + Sitka time rather than at the start of 1867-10-17 local time. + Although strictly speaking this is accurate only for Sitka, + the rest of Alaska's blanks need to be filled in somehow. + + Fix off-by-one errors in UT offsets for Adak and Nome before 1867. + (Thanks to Michael Deckers.) + + Add 7 s to the UT offset in Asia/Yangon before 1920. + + Changes to zone names + + Remove Canada/East-Saskatchewan from the 'backward' file, as it + exceeded the 14-character limit and was an unused misnomer anyway. + + Changes to build procedure + + To support applications that prefer to read time zone data in text + form, two zic input files tzdata.zi and leapseconds are now + installed by default. The commands 'zic tzdata.zi' and 'zic -L + leapseconds tzdata.zi' can reproduce the tzdata binary files + without and with leap seconds, respectively. To prevent these two + new files from being installed, use 'make TZDATA_TEXT=', and to + suppress leap seconds from the tzdata text installation, use 'make + TZDATA_TEXT=tzdata.zi'. + + 'make BACKWARD=' now suppresses backward-compatibility names + like 'US/Pacific' that are defined in the 'backward' and + 'pacificnew' files. + + 'make check' now works on systems that lack a UTF-8 locale, + or that lack the nsgmls program. Set UTF8_LOCALE to configure + the name of a UTF-8 locale, if you have one. + + Y2K runtime checks are no longer enabled by default. Add + -DDEPRECATE_TWO_DIGIT_YEARS to CFLAGS to enable them, instead of + adding -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU + to disable them. (New name suggested by Brian Inglis.) + + The build procedure for zdump now works on AIX 7.1. + (Problem reported by Kees Dekker.) + + Changes to code + + zic and the reference runtime now reject multiple leap seconds + within 28 days of each other, or leap seconds before the Epoch. + As a result, support for double leap seconds, which was + obsolescent and undocumented, has been removed. Double leap + seconds were an error in the C89 standard; they have never existed + in civil timekeeping. (Thanks to Robert Elz and Bradley White for + noticing glitches in the code that uncovered this problem.) + + zic now warns about use of the obsolescent and undocumented -y + option, and about use of the obsolescent TYPE field of Rule lines. + + zic now allows unambiguous abbreviations like "Sa" and "Su" for + weekdays; formerly it rejected them due to a bug. Conversely, zic + no longer considers non-prefixes to be abbreviations; for example, + it no longer accepts "lF" as an abbreviation for "lastFriday". + Also, zic warns about the undocumented usage with a "last-" + prefix, e.g., "last-Fri". + + Similarly, zic now accepts the unambiguous abbreviation "L" for + "Link" in ordinary context and for "Leap" in leap-second context. + Conversely, zic no longer accepts non-prefixes such as "La" as + abbreviations for words like "Leap". + + zic no longer accepts leap second lines in ordinary input, or + ordinary lines in leap second input. Formerly, zic sometimes + warned about this undocumented usage and handled it incorrectly. + + The new macro HAVE_TZNAME governs whether the tzname external + variable is exported, instead of USG_COMPAT. USG_COMPAT now + governs only the external variables "timezone" and "daylight". + This change is needed because the three variables are not in the + same category: although POSIX requires tzname, it specifies the + other two variables as optional. Also, USG_COMPAT is now 1 or 0: + if not defined, the code attempts to guess it from other macros. + + localtime.c and difftime.c no longer require stdio.h, and .c files + other than zic.c no longer require sys/wait.h. + + zdump.c no longer assumes snprintf. (Reported by Jonathan Leffler.) + + Calculation of time_t extrema works around a bug in GCC 4.8.4 + (Reported by Stan Shebs and Joseph Myers.) + + zic.c no longer mistranslates formats of line numbers in non-English + locales. (Problem reported by Benno Schulenberg.) + + Several minor changes have been made to the code to make it a + bit easier to port to MS-Windows and Solaris. (Thanks to Kees + Dekker for reporting the problems.) + + Changes to documentation and commentary + + The two new files 'theory.html' and 'calendars' contain the + contents of the removed file 'Theory'. The goal is to document + tzdb theory more accessibly. + + The zic man page now documents abbreviation rules. + + tz-link.htm now covers how to apply tzdata changes to clients. + (Thanks to Jorge Fábregas for the AIX link.) It also mentions MySQL. + + The leap-seconds.list URL has been updated to something that is + more reliable for tzdb. (Thanks to Tim Parenti and Brian Inglis.) + Release 2017b - 2017-03-17 07:30:38 -0700 Briefly: Haiti has resumed DST. @@ -15,6 +179,16 @@ Release 2017b - 2017-03-17 07:30:38 -0700 Use "MMT" to abbreviate Liberia's time zone before 1972, as "-004430" is one byte over the POSIX limit. (Problem reported by Derick Rethans.) + Changes to code + + The reference localtime implementation now falls back on the + current US daylight-saving transition rules rather than the + 1987-2006 rules. This fallback occurs only when (1) the TZ + environment variable's value has a name like "AST4ADT" that asks + for daylight saving time but does not specify the rules, (2) there + is no file by that name, and (3) the TZDEFRULES file cannot be + loaded. (Thanks to Tom Lane.) + Release 2017a - 2017-02-28 00:05:36 -0800 @@ -1981,7 +2155,7 @@ Release 2013e - 2013-09-19 23:50:04 -0700 The 'leapseconds' file is now generated automatically from a new file 'leap-seconds.list', which is a copy of - . + A new source file 'leapseconds.awk' implements this. The goal is simplification of the future maintenance of 'leapseconds'. @@ -2187,7 +2361,7 @@ Release 2013a - 2013-02-27 09:20:35 -0800 Many changes affect historical timestamps before 1940. These were deduced from: Milne J. Civil time. Geogr J. 1899 - Feb;13(2):173-94 . + Feb;13(2):173-94 . Changes affecting the code: diff --git a/contrib/tzdata/Theory b/contrib/tzdata/Theory deleted file mode 100644 index 33e46069ba23..000000000000 --- a/contrib/tzdata/Theory +++ /dev/null @@ -1,870 +0,0 @@ -Theory and pragmatics of the tz code and data - - ------ Outline ----- - - Scope of the tz database - Names of time zone rules - Time zone abbreviations - Accuracy of the tz database - Time and date functions - Interface stability - Calendrical issues - Time and time zones on Mars - - ------ Scope of the tz database ----- - -The tz database attempts to record the history and predicted future of -all computer-based clocks that track civil time. To represent this -data, the world is partitioned into regions whose clocks all agree -about time stamps that occur after the somewhat-arbitrary cutoff point -of the POSIX Epoch (1970-01-01 00:00:00 UTC). For each such region, -the database records all known clock transitions, and labels the region -with a notable location. Although 1970 is a somewhat-arbitrary -cutoff, there are significant challenges to moving the cutoff earlier -even by a decade or two, due to the wide variety of local practices -before computer timekeeping became prevalent. - -Clock transitions before 1970 are recorded for each such location, -because most systems support time stamps before 1970 and could -misbehave if data entries were omitted for pre-1970 transitions. -However, the database is not designed for and does not suffice for -applications requiring accurate handling of all past times everywhere, -as it would take far too much effort and guesswork to record all -details of pre-1970 civil timekeeping. - -As described below, reference source code for using the tz database is -also available. The tz code is upwards compatible with POSIX, an -international standard for UNIX-like systems. As of this writing, the -current edition of POSIX is: - - The Open Group Base Specifications Issue 7 - IEEE Std 1003.1-2008, 2016 Edition - - - - ------ Names of time zone rules ----- - -Each of the database's time zone rules has a unique name. -Inexperienced users are not expected to select these names unaided. -Distributors should provide documentation and/or a simple selection -interface that explains the names; for one example, see the 'tzselect' -program in the tz code. The Unicode Common Locale Data Repository - contains data that may be useful for other -selection interfaces. - -The time zone rule naming conventions attempt to strike a balance -among the following goals: - - * Uniquely identify every region where clocks have agreed since 1970. - This is essential for the intended use: static clocks keeping local - civil time. - - * Indicate to experts where that region is. - - * Be robust in the presence of political changes. For example, names - of countries are ordinarily not used, to avoid incompatibilities - when countries change their name (e.g. Zaire->Congo) or when - locations change countries (e.g. Hong Kong from UK colony to - China). - - * Be portable to a wide variety of implementations. - - * Use a consistent naming conventions over the entire world. - -Names normally have the form AREA/LOCATION, where AREA is the name -of a continent or ocean, and LOCATION is the name of a specific -location within that region. North and South America share the same -area, 'America'. Typical names are 'Africa/Cairo', 'America/New_York', -and 'Pacific/Honolulu'. - -Here are the general rules used for choosing location names, -in decreasing order of importance: - - Use only valid POSIX file name components (i.e., the parts of - names other than '/'). Do not use the file name - components '.' and '..'. Within a file name component, - use only ASCII letters, '.', '-' and '_'. Do not use - digits, as that might create an ambiguity with POSIX - TZ strings. A file name component must not exceed 14 - characters or start with '-'. E.g., prefer 'Brunei' - to 'Bandar_Seri_Begawan'. Exceptions: see the discussion - of legacy names below. - A name must not be empty, or contain '//', or start or end with '/'. - Do not use names that differ only in case. Although the reference - implementation is case-sensitive, some other implementations - are not, and they would mishandle names differing only in case. - If one name A is an initial prefix of another name AB (ignoring case), - then B must not start with '/', as a regular file cannot have - the same name as a directory in POSIX. For example, - 'America/New_York' precludes 'America/New_York/Bronx'. - Uninhabited regions like the North Pole and Bouvet Island - do not need locations, since local time is not defined there. - There should typically be at least one name for each ISO 3166-1 - officially assigned two-letter code for an inhabited country - or territory. - If all the clocks in a region have agreed since 1970, - don't bother to include more than one location - even if subregions' clocks disagreed before 1970. - Otherwise these tables would become annoyingly large. - If a name is ambiguous, use a less ambiguous alternative; - e.g. many cities are named San José and Georgetown, so - prefer 'Costa_Rica' to 'San_Jose' and 'Guyana' to 'Georgetown'. - Keep locations compact. Use cities or small islands, not countries - or regions, so that any future time zone changes do not split - locations into different time zones. E.g. prefer 'Paris' - to 'France', since France has had multiple time zones. - Use mainstream English spelling, e.g. prefer 'Rome' to 'Roma', and - prefer 'Athens' to the Greek 'Αθήνα' or the Romanized 'Athína'. - The POSIX file name restrictions encourage this rule. - Use the most populous among locations in a zone, - e.g. prefer 'Shanghai' to 'Beijing'. Among locations with - similar populations, pick the best-known location, - e.g. prefer 'Rome' to 'Milan'. - Use the singular form, e.g. prefer 'Canary' to 'Canaries'. - Omit common suffixes like '_Islands' and '_City', unless that - would lead to ambiguity. E.g. prefer 'Cayman' to - 'Cayman_Islands' and 'Guatemala' to 'Guatemala_City', - but prefer 'Mexico_City' to 'Mexico' because the country - of Mexico has several time zones. - Use '_' to represent a space. - Omit '.' from abbreviations in names, e.g. prefer 'St_Helena' - to 'St._Helena'. - Do not change established names if they only marginally - violate the above rules. For example, don't change - the existing name 'Rome' to 'Milan' merely because - Milan's population has grown to be somewhat greater - than Rome's. - If a name is changed, put its old spelling in the 'backward' file. - This means old spellings will continue to work. - -The file 'zone1970.tab' lists geographical locations used to name time -zone rules. It is intended to be an exhaustive list of names for -geographic regions as described above; this is a subset of the names -in the data. Although a 'zone1970.tab' location's longitude -corresponds to its LMT offset with one hour for every 15 degrees east -longitude, this relationship is not exact. - -Older versions of this package used a different naming scheme, -and these older names are still supported. -See the file 'backward' for most of these older names -(e.g., 'US/Eastern' instead of 'America/New_York'). -The other old-fashioned names still supported are -'WET', 'CET', 'MET', and 'EET' (see the file 'europe'). - -Older versions of this package defined legacy names that are -incompatible with the first rule of location names, but which are -still supported. These legacy names are mostly defined in the file -'etcetera'. Also, the file 'backward' defines the legacy names -'GMT0', 'GMT-0', 'GMT+0' and 'Canada/East-Saskatchewan', and the file -'northamerica' defines the legacy names 'EST5EDT', 'CST6CDT', -'MST7MDT', and 'PST8PDT'. - -Excluding 'backward' should not affect the other data. If -'backward' is excluded, excluding 'etcetera' should not affect the -remaining data. - - ------ Time zone abbreviations ----- - -When this package is installed, it generates time zone abbreviations -like 'EST' to be compatible with human tradition and POSIX. -Here are the general rules used for choosing time zone abbreviations, -in decreasing order of importance: - - Use three or more characters that are ASCII alphanumerics or '+' or '-'. - Previous editions of this database also used characters like - ' ' and '?', but these characters have a special meaning to - the shell and cause commands like - set `date` - to have unexpected effects. - Previous editions of this rule required upper-case letters, - but the Congressman who introduced Chamorro Standard Time - preferred "ChST", so lower-case letters are now allowed. - Also, POSIX from 2001 on relaxed the rule to allow '-', '+', - and alphanumeric characters from the portable character set - in the current locale. In practice ASCII alphanumerics and - '+' and '-' are safe in all locales. - - In other words, in the C locale the POSIX extended regular - expression [-+[:alnum:]]{3,} should match the abbreviation. - This guarantees that all abbreviations could have been - specified by a POSIX TZ string. - - Use abbreviations that are in common use among English-speakers, - e.g. 'EST' for Eastern Standard Time in North America. - We assume that applications translate them to other languages - as part of the normal localization process; for example, - a French application might translate 'EST' to 'HNE'. - - For zones whose times are taken from a city's longitude, use the - traditional xMT notation, e.g. 'PMT' for Paris Mean Time. - The only name like this in current use is 'GMT'. - - Use 'LMT' for local mean time of locations before the introduction - of standard time; see "Scope of the tz database". - - If there is no common English abbreviation, use numeric offsets like - -05 and +0830 that are generated by zic's %z notation. - - Use current abbreviations for older timestamps to avoid confusion. - For example, in 1910 a common English abbreviation for UT +01 - in central Europe was 'MEZ' (short for both "Middle European - Zone" and for "Mitteleuropäische Zeit" in German). Nowadays - 'CET' ("Central European Time") is more common in English, and - the database uses 'CET' even for circa-1910 timestamps as this - is less confusing for modern users and avoids the need for - determining when 'CET' supplanted 'MEZ' in common usage. - - Use a consistent style in a zone's history. For example, if a zone's - history tends to use numeric abbreviations and a particular - entry could go either way, use a numeric abbreviation. - - [The remaining guidelines predate the introduction of %z. - They are problematic as they mean tz data entries invent - notation rather than record it. These guidelines are now - deprecated and the plan is to gradually move to %z for - inhabited locations and to "-00" for uninhabited locations.] - - If there is no common English abbreviation, abbreviate the English - translation of the usual phrase used by native speakers. - If this is not available or is a phrase mentioning the country - (e.g. "Cape Verde Time"), then: - - When a country is identified with a single or principal zone, - append 'T' to the country's ISO code, e.g. 'CVT' for - Cape Verde Time. For summer time append 'ST'; - for double summer time append 'DST'; etc. - Otherwise, take the first three letters of an English place - name identifying each zone and append 'T', 'ST', etc. - as before; e.g. 'CHAST' for CHAtham Summer Time. - - Use UT (with time zone abbreviation '-00') for locations while - uninhabited. The leading '-' is a flag that the time - zone is in some sense undefined; this notation is - derived from Internet RFC 3339. - -Application writers should note that these abbreviations are ambiguous -in practice: e.g. 'CST' has a different meaning in China than -it does in the United States. In new applications, it's often better -to use numeric UT offsets like '-0600' instead of time zone -abbreviations like 'CST'; this avoids the ambiguity. - - ------ Accuracy of the tz database ----- - -The tz database is not authoritative, and it surely has errors. -Corrections are welcome and encouraged; see the file CONTRIBUTING. -Users requiring authoritative data should consult national standards -bodies and the references cited in the database's comments. - -Errors in the tz database arise from many sources: - - * The tz database predicts future time stamps, and current predictions - will be incorrect after future governments change the rules. - For example, if today someone schedules a meeting for 13:00 next - October 1, Casablanca time, and tomorrow Morocco changes its - daylight saving rules, software can mess up after the rule change - if it blithely relies on conversions made before the change. - - * The pre-1970 entries in this database cover only a tiny sliver of how - clocks actually behaved; the vast majority of the necessary - information was lost or never recorded. Thousands more zones would - be needed if the tz database's scope were extended to cover even - just the known or guessed history of standard time; for example, - the current single entry for France would need to split into dozens - of entries, perhaps hundreds. And in most of the world even this - approach would be misleading due to widespread disagreement or - indifference about what times should be observed. In her 2015 book - "The Global Transformation of Time, 1870-1950", Vanessa Ogle writes - "Outside of Europe and North America there was no system of time - zones at all, often not even a stable landscape of mean times, - prior to the middle decades of the twentieth century". See: - Timothy Shenk, Booked: A Global History of Time. Dissent 2015-12-17 - https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanessa-ogle - - * Most of the pre-1970 data entries come from unreliable sources, often - astrology books that lack citations and whose compilers evidently - invented entries when the true facts were unknown, without - reporting which entries were known and which were invented. - These books often contradict each other or give implausible entries, - and on the rare occasions when they are checked they are - typically found to be incorrect. - - * For the UK the tz database relies on years of first-class work done by - Joseph Myers and others; see . - Other countries are not done nearly as well. - - * Sometimes, different people in the same city would maintain clocks - that differed significantly. Railway time was used by railroad - companies (which did not always agree with each other), - church-clock time was used for birth certificates, etc. - Often this was merely common practice, but sometimes it was set by law. - For example, from 1891 to 1911 the UT offset in France was legally - 0:09:21 outside train stations and 0:04:21 inside. - - * Although a named location in the tz database stands for the - containing region, its pre-1970 data entries are often accurate for - only a small subset of that region. For example, Europe/London - stands for the United Kingdom, but its pre-1847 times are valid - only for locations that have London's exact meridian, and its 1847 - transition to GMT is known to be valid only for the L&NW and the - Caledonian railways. - - * The tz database does not record the earliest time for which a zone's - data entries are thereafter valid for every location in the region. - For example, Europe/London is valid for all locations in its - region after GMT was made the standard time, but the date of - standardization (1880-08-02) is not in the tz database, other than - in commentary. For many zones the earliest time of validity is - unknown. - - * The tz database does not record a region's boundaries, and in many - cases the boundaries are not known. For example, the zone - America/Kentucky/Louisville represents a region around the city of - Louisville, the boundaries of which are unclear. - - * Changes that are modeled as instantaneous transitions in the tz - database were often spread out over hours, days, or even decades. - - * Even if the time is specified by law, locations sometimes - deliberately flout the law. - - * Early timekeeping practices, even assuming perfect clocks, were - often not specified to the accuracy that the tz database requires. - - * Sometimes historical timekeeping was specified more precisely - than what the tz database can handle. For example, from 1909 to - 1937 Netherlands clocks were legally UT +00:19:32.13, but the tz - database cannot represent the fractional second. - - * Even when all the timestamp transitions recorded by the tz database - are correct, the tz rules that generate them may not faithfully - reflect the historical rules. For example, from 1922 until World - War II the UK moved clocks forward the day following the third - Saturday in April unless that was Easter, in which case it moved - clocks forward the previous Sunday. Because the tz database has no - way to specify Easter, these exceptional years are entered as - separate tz Rule lines, even though the legal rules did not change. - - * The tz database models pre-standard time using the proleptic Gregorian - calendar and local mean time (LMT), but many people used other - calendars and other timescales. For example, the Roman Empire used - the Julian calendar, and had 12 varying-length daytime hours with a - non-hour-based system at night. - - * Early clocks were less reliable, and data entries do not represent - clock error. - - * The tz database assumes Universal Time (UT) as an origin, even - though UT is not standardized for older time stamps. In the tz - database commentary, UT denotes a family of time standards that - includes Coordinated Universal Time (UTC) along with other variants - such as UT1 and GMT, with days starting at midnight. Although UT - equals UTC for modern time stamps, UTC was not defined until 1960, - so commentary uses the more-general abbreviation UT for time stamps - that might predate 1960. Since UT, UT1, etc. disagree slightly, - and since pre-1972 UTC seconds varied in length, interpretation of - older time stamps can be problematic when subsecond accuracy is - needed. - - * Civil time was not based on atomic time before 1972, and we don't - know the history of earth's rotation accurately enough to map SI - seconds to historical solar time to more than about one-hour - accuracy. See: Stephenson FR, Morrison LV, Hohenkerk CY. - Measurement of the Earth's rotation: 720 BC to AD 2015. - Proc Royal Soc A. 2016 Dec 7;472:20160404. - http://dx.doi.org/10.1098/rspa.2016.0404 - Also see: Espenak F. Uncertainty in Delta T (ΔT). - http://eclipse.gsfc.nasa.gov/SEhelp/uncertainty2004.html - - * The relationship between POSIX time (that is, UTC but ignoring leap - seconds) and UTC is not agreed upon after 1972. Although the POSIX - clock officially stops during an inserted leap second, at least one - proposed standard has it jumping back a second instead; and in - practice POSIX clocks more typically either progress glacially during - a leap second, or are slightly slowed while near a leap second. - - * The tz database does not represent how uncertain its information is. - Ideally it would contain information about when data entries are - incomplete or dicey. Partial temporal knowledge is a field of - active research, though, and it's not clear how to apply it here. - -In short, many, perhaps most, of the tz database's pre-1970 and future -time stamps are either wrong or misleading. Any attempt to pass the -tz database off as the definition of time should be unacceptable to -anybody who cares about the facts. In particular, the tz database's -LMT offsets should not be considered meaningful, and should not prompt -creation of zones merely because two locations differ in LMT or -transitioned to standard time at different dates. - - ------ Time and date functions ----- - -The tz code contains time and date functions that are upwards -compatible with those of POSIX. - -POSIX has the following properties and limitations. - -* In POSIX, time display in a process is controlled by the - environment variable TZ. Unfortunately, the POSIX TZ string takes - a form that is hard to describe and is error-prone in practice. - Also, POSIX TZ strings can't deal with other (for example, Israeli) - daylight saving time rules, or situations where more than two - time zone abbreviations are used in an area. - - The POSIX TZ string takes the following form: - - stdoffset[dst[offset][,date[/time],date[/time]]] - - where: - - std and dst - are 3 or more characters specifying the standard - and daylight saving time (DST) zone names. - Starting with POSIX.1-2001, std and dst may also be - in a quoted form like ""; this allows - "+" and "-" in the names. - offset - is of the form '[+-]hh:[mm[:ss]]' and specifies the - offset west of UT. 'hh' may be a single digit; 0<=hh<=24. - The default DST offset is one hour ahead of standard time. - date[/time],date[/time] - specifies the beginning and end of DST. If this is absent, - the system supplies its own rules for DST, and these can - differ from year to year; typically US DST rules are used. - time - takes the form 'hh:[mm[:ss]]' and defaults to 02:00. - This is the same format as the offset, except that a - leading '+' or '-' is not allowed. - date - takes one of the following forms: - Jn (1<=n<=365) - origin-1 day number not counting February 29 - n (0<=n<=365) - origin-0 day number counting February 29 if present - Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12) - for the dth day of week n of month m of the year, - where week 1 is the first week in which day d appears, - and '5' stands for the last week in which day d appears - (which may be either the 4th or 5th week). - Typically, this is the only useful form; - the n and Jn forms are rarely used. - - Here is an example POSIX TZ string, for US Pacific time using rules - appropriate from 1987 through 2006: - - TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00' - - This POSIX TZ string is hard to remember, and mishandles time stamps - before 1987 and after 2006. With this package you can use this - instead: - - TZ='America/Los_Angeles' - -* POSIX does not define the exact meaning of TZ values like "EST5EDT". - Typically the current US DST rules are used to interpret such values, - but this means that the US DST rules are compiled into each program - that does time conversion. This means that when US time conversion - rules change (as in the United States in 1987), all programs that - do time conversion must be recompiled to ensure proper results. - -* The TZ environment variable is process-global, which makes it hard - to write efficient, thread-safe applications that need access - to multiple time zones. - -* In POSIX, there's no tamper-proof way for a process to learn the - system's best idea of local wall clock. (This is important for - applications that an administrator wants used only at certain times - - without regard to whether the user has fiddled the "TZ" environment - variable. While an administrator can "do everything in UTC" to get - around the problem, doing so is inconvenient and precludes handling - daylight saving time shifts - as might be required to limit phone - calls to off-peak hours.) - -* POSIX provides no convenient and efficient way to determine the UT - offset and time zone abbreviation of arbitrary time stamps, - particularly for time zone settings that do not fit into the - POSIX model. - -* POSIX requires that systems ignore leap seconds. - -* The tz code attempts to support all the time_t implementations - allowed by POSIX. The time_t type represents a nonnegative count of - seconds since 1970-01-01 00:00:00 UTC, ignoring leap seconds. - In practice, time_t is usually a signed 64- or 32-bit integer; 32-bit - signed time_t values stop working after 2038-01-19 03:14:07 UTC, so - new implementations these days typically use a signed 64-bit integer. - Unsigned 32-bit integers are used on one or two platforms, - and 36-bit and 40-bit integers are also used occasionally. - Although earlier POSIX versions allowed time_t to be a - floating-point type, this was not supported by any practical - systems, and POSIX.1-2013 and the tz code both require time_t - to be an integer type. - -These are the extensions that have been made to the POSIX functions: - -* The "TZ" environment variable is used in generating the name of a file - from which time zone information is read (or is interpreted a la - POSIX); "TZ" is no longer constrained to be a three-letter time zone - name followed by a number of hours and an optional three-letter - daylight time zone name. The daylight saving time rules to be used - for a particular time zone are encoded in the time zone file; - the format of the file allows U.S., Australian, and other rules to be - encoded, and allows for situations where more than two time zone - abbreviations are used. - - It was recognized that allowing the "TZ" environment variable to - take on values such as "America/New_York" might cause "old" programs - (that expect "TZ" to have a certain form) to operate incorrectly; - consideration was given to using some other environment variable - (for example, "TIMEZONE") to hold the string used to generate the - time zone information file name. In the end, however, it was decided - to continue using "TZ": it is widely used for time zone purposes; - separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance; - and systems where "new" forms of "TZ" might cause problems can simply - use TZ values such as "EST5EDT" which can be used both by - "new" programs (a la POSIX) and "old" programs (as zone names and - offsets). - -* The code supports platforms with a UT offset member in struct tm, - e.g., tm_gmtoff. - -* The code supports platforms with a time zone abbreviation member in - struct tm, e.g., tm_zone. - -* Since the "TZ" environment variable can now be used to control time - conversion, the "daylight" and "timezone" variables are no longer - needed. (These variables are defined and set by "tzset"; however, their - values will not be used by "localtime.") - -* Functions tzalloc, tzfree, localtime_rz, and mktime_z for - more-efficient thread-safe applications that need to use - multiple time zones. The tzalloc and tzfree functions - allocate and free objects of type timezone_t, and localtime_rz - and mktime_z are like localtime_r and mktime with an extra - timezone_t argument. The functions were inspired by NetBSD. - -* A function "tzsetwall" has been added to arrange for the system's - best approximation to local wall clock time to be delivered by - subsequent calls to "localtime." Source code for portable - applications that "must" run on local wall clock time should call - "tzsetwall();" if such code is moved to "old" systems that don't - provide tzsetwall, you won't be able to generate an executable program. - (These time zone functions also arrange for local wall clock time to be - used if tzset is called - directly or indirectly - and there's no "TZ" - environment variable; portable applications should not, however, rely - on this behavior since it's not the way SVR2 systems behave.) - -* Negative time_t values are supported, on systems where time_t is signed. - -* These functions can account for leap seconds, thanks to Bradley White. - -Points of interest to folks with other systems: - -* Code compatible with this package is already part of many platforms, - including GNU/Linux, Android, the BSDs, Chromium OS, Cygwin, AIX, iOS, - BlackBery 10, macOS, Microsoft Windows, OpenVMS, and Solaris. - On such hosts, the primary use of this package - is to update obsolete time zone rule tables. - To do this, you may need to compile the time zone compiler - 'zic' supplied with this package instead of using the system 'zic', - since the format of zic's input is occasionally extended, - and a platform may still be shipping an older zic. - -* The UNIX Version 7 "timezone" function is not present in this package; - it's impossible to reliably map timezone's arguments (a "minutes west - of GMT" value and a "daylight saving time in effect" flag) to a - time zone abbreviation, and we refuse to guess. - Programs that in the past used the timezone function may now examine - tzname[localtime(&clock)->tm_isdst] to learn the correct time - zone abbreviation to use. Alternatively, use - localtime(&clock)->tm_zone if this has been enabled. - -* The 4.2BSD gettimeofday function is not used in this package. - This formerly let users obtain the current UTC offset and DST flag, - but this functionality was removed in later versions of BSD. - -* In SVR2, time conversion fails for near-minimum or near-maximum - time_t values when doing conversions for places that don't use UT. - This package takes care to do these conversions correctly. - A comment in the source code tells how to get compatibly wrong - results. - -The functions that are conditionally compiled if STD_INSPIRED is defined -should, at this point, be looked on primarily as food for thought. They are -not in any sense "standard compatible" - some are not, in fact, specified in -*any* standard. They do, however, represent responses of various authors to -standardization proposals. - -Other time conversion proposals, in particular the one developed by folks at -Hewlett Packard, offer a wider selection of functions that provide capabilities -beyond those provided here. The absence of such functions from this package -is not meant to discourage the development, standardization, or use of such -functions. Rather, their absence reflects the decision to make this package -contain valid extensions to POSIX, to ensure its broad acceptability. If -more powerful time conversion functions can be standardized, so much the -better. - - ------ Interface stability ----- - -The tz code and data supply the following interfaces: - - * A set of zone names as per "Names of time zone rules" above. - - * Library functions described in "Time and date functions" above. - - * The programs tzselect, zdump, and zic, documented in their man pages. - - * The format of zic input files, documented in the zic man page. - - * The format of zic output files, documented in the tzfile man page. - - * The format of zone table files, documented in zone1970.tab. - - * The format of the country code file, documented in iso3166.tab. - - * The version number of the code and data, as the first line of - the text file 'version' in each release. - -Interface changes in a release attempt to preserve compatibility with -recent releases. For example, tz data files typically do not rely on -recently-added zic features, so that users can run older zic versions -to process newer data files. The tz-link.htm file describes how -releases are tagged and distributed. - -Interfaces not listed above are less stable. For example, users -should not rely on particular UT offsets or abbreviations for time -stamps, as data entries are often based on guesswork and these guesses -may be corrected or improved. - - ------ Calendrical issues ----- - -Calendrical issues are a bit out of scope for a time zone database, -but they indicate the sort of problems that we would run into if we -extended the time zone database further into the past. An excellent -resource in this area is Nachum Dershowitz and Edward M. Reingold, -Calendrical Calculations: Third Edition, Cambridge University Press (2008) -. -Other information and sources are given below. They sometimes disagree. - - -France - -Gregorian calendar adopted 1582-12-20. -French Revolutionary calendar used 1793-11-24 through 1805-12-31, -and (in Paris only) 1871-05-06 through 1871-05-23. - - -Russia - -From Chris Carrier (1996-12-02): -On 1929-10-01 the Soviet Union instituted an "Eternal Calendar" -with 30-day months plus 5 holidays, with a 5-day week. -On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the -Gregorian calendar while retaining the 6-day week; on 1940-06-27 it -reverted to the 7-day week. With the 6-day week the usual days -off were the 6th, 12th, 18th, 24th and 30th of the month. -(Source: Evitiar Zerubavel, _The Seven Day Circle_) - - -Mark Brader reported a similar story in "The Book of Calendars", edited -by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: - -From: Petteri Sulonen (via Usenet) -Date: 14 Jan 1999 00:00:00 GMT -... - -If your source is correct, how come documents between 1929 and 1940 were -still dated using the conventional, Gregorian calendar? - -I can post a scan of a document dated December 1, 1934, signed by -Yenukidze, the secretary, on behalf of Kalinin, the President of the -Executive Committee of the Supreme Soviet, if you like. - - - -Sweden (and Finland) - -From: Mark Brader -Subject: Re: Gregorian reform - a part of locale? - -Date: 1996-07-06 - -In 1700, Denmark made the transition from Julian to Gregorian. Sweden -decided to *start* a transition in 1700 as well, but rather than have one of -those unsightly calendar gaps :-), they simply decreed that the next leap -year after 1696 would be in 1744 - putting the whole country on a calendar -different from both Julian and Gregorian for a period of 40 years. - -However, in 1704 something went wrong and the plan was not carried through; -they did, after all, have a leap year that year. And one in 1708. In 1712 -they gave it up and went back to Julian, putting 30 days in February that -year!... - -Then in 1753, Sweden made the transition to Gregorian in the usual manner, -getting there only 13 years behind the original schedule. - -(A previous posting of this story was challenged, and Swedish readers -produced the following references to support it: "Tideräkning och historia" -by Natanael Beckman (1924) and "Tid, en bok om tideräkning och -kalenderväsen" by Lars-Olof Lodén (1968). - - -Grotefend's data - -From: "Michael Palmer" [with one obvious typo fixed] -Subject: Re: Gregorian Calendar (was Re: Another FHC related question -Newsgroups: soc.genealogy.german -Date: Tue, 9 Feb 1999 02:32:48 -800 -... - -The following is a(n incomplete) listing, arranged chronologically, of -European states, with the date they converted from the Julian to the -Gregorian calendar: - -04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman - Catholics and Danzig only) -09/20 Dec 1582 - France, Lorraine - -21 Dec 1582/ - 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau -10/21 Feb 1583 - bishopric of Liege (Lüttich) -13/24 Feb 1583 - bishopric of Augsburg -04/15 Oct 1583 - electorate of Trier -05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg, - Salzburg, Brixen -13/24 Oct 1583 - Austrian Oberelsaß and Breisgau -20/31 Oct 1583 - bishopric of Basel -02/13 Nov 1583 - duchy of Jülich-Berg -02/13 Nov 1583 - electorate and city of Köln -04/15 Nov 1583 - bishopric of Würzburg -11/22 Nov 1583 - electorate of Mainz -16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden -17/28 Nov 1583 - bishopric of Münster and duchy of Cleve -14/25 Dec 1583 - Steiermark - -06/17 Jan 1584 - Austria and Bohemia -11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn -12/23 Jan 1584 - Silesia and the Lausitz -22 Jan/ - 02 Feb 1584 - Hungary (legally on 21 Oct 1587) - Jun 1584 - Unterwalden -01/12 Jul 1584 - duchy of Westfalen - -16/27 Jun 1585 - bishopric of Paderborn - -14/25 Dec 1590 - Transylvania - -22 Aug/ - 02 Sep 1612 - duchy of Prussia - -13/24 Dec 1614 - Pfalz-Neuburg - - 1617 - duchy of Kurland (reverted to the Julian calendar in - 1796) - - 1624 - bishopric of Osnabrück - - 1630 - bishopric of Minden - -15/26 Mar 1631 - bishopric of Hildesheim - - 1655 - Kanton Wallis - -05/16 Feb 1682 - city of Strassburg - -18 Feb/ - 01 Mar 1700 - Protestant Germany (including Swedish possessions in - Germany), Denmark, Norway -30 Jun/ - 12 Jul 1700 - Gelderland, Zutphen -10 Nov/ - 12 Dec 1700 - Utrecht, Overijssel - -31 Dec 1700/ - 12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva, - Turgau, and Schaffhausen - - 1724 - Glarus, Appenzell, and the city of St. Gallen - -01 Jan 1750 - Pisa and Florence - -02/14 Sep 1752 - Great Britain - -17 Feb/ - 01 Mar 1753 - Sweden - -1760-1812 - Graubünden - -The Russian empire (including Finland and the Baltic states) did not -convert to the Gregorian calendar until the Soviet revolution of 1917. - -Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen -Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend -(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28. - - ------ Time and time zones on Mars ----- - -Some people's work schedules use Mars time. Jet Propulsion Laboratory -(JPL) coordinators have kept Mars time on and off at least since 1997 -for the Mars Pathfinder mission. Some of their family members have -also adapted to Mars time. Dozens of special Mars watches were built -for JPL workers who kept Mars time during the Mars Exploration -Rovers mission (2004). These timepieces look like normal Seikos and -Citizens but use Mars seconds rather than terrestrial seconds. - -A Mars solar day is called a "sol" and has a mean period equal to -about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is -divided into a conventional 24-hour clock, so each Mars second equals -about 1.02749125 terrestrial seconds. - -The prime meridian of Mars goes through the center of the crater -Airy-0, named in honor of the British astronomer who built the -Greenwich telescope that defines Earth's prime meridian. Mean solar -time on the Mars prime meridian is called Mars Coordinated Time (MTC). - -Each landed mission on Mars has adopted a different reference for -solar time keeping, so there is no real standard for Mars time zones. -For example, the Mars Exploration Rover project (2004) defined two -time zones "Local Solar Time A" and "Local Solar Time B" for its two -missions, each zone designed so that its time equals local true solar -time at approximately the middle of the nominal mission. Such a "time -zone" is not particularly suited for any application other than the -mission itself. - -Many calendars have been proposed for Mars, but none have achieved -wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a -sequential count of Mars solar days elapsed since about 1873-12-29 -12:00 GMT. - -The tz database does not currently support Mars time, but it is -documented here in the hopes that support will be added eventually. - -Sources: - -Michael Allison and Robert Schmunk, -"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock" - (2012-08-08). - -Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times - -(2004-01-14), pp A1, A20-A21. - -Tom Chmielewski, "Jet Lag Is Worse on Mars", The Atlantic (2015-02-26) - - ------ - -This file is in the public domain, so clarified as of 2009-05-17 by -Arthur David Olson. - ------ -Local Variables: -coding: utf-8 -End: diff --git a/contrib/tzdata/africa b/contrib/tzdata/africa index dcc20b9b1c33..3a60bc27d02c 100644 --- a/contrib/tzdata/africa +++ b/contrib/tzdata/africa @@ -26,7 +26,7 @@ # # For data circa 1899, a common source is: # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. -# http://www.jstor.org/stable/1774359 +# https://www.jstor.org/stable/1774359 # # A reliable and entertaining source about time zones is # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). @@ -218,7 +218,7 @@ Rule Egypt 2006 only - Sep 21 24:00 0 - # saving time in Egypt will end in the night of 2007-09-06 to 2007-09-07. # From Jesper Nørgaard Welen (2007-08-15): [The following agree:] # http://www.nentjes.info/Bill/bill5.htm -# http://www.timeanddate.com/worldclock/city.html?n=53 +# https://www.timeanddate.com/worldclock/city.html?n=53 # From Steffen Thorsen (2007-09-04): The official information...: # http://www.sis.gov.eg/En/EgyptOnline/Miscellaneous/000002/0207000000000000001580.htm Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - @@ -256,8 +256,8 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - # timeanddate[2] and another site I've found[3] also support that. # # [1] https://bugzilla.redhat.com/show_bug.cgi?id=492263 -# [2] http://www.timeanddate.com/worldclock/clockchange.html?n=53 -# [3] http://wwp.greenwichmeantime.com/time-zone/africa/egypt/ +# [2] https://www.timeanddate.com/worldclock/clockchange.html?n=53 +# [3] https://wwp.greenwichmeantime.com/time-zone/africa/egypt/ # From Arthur David Olson (2009-04-20): # In 2009 (and for the next several years), Ramadan ends before the fourth @@ -267,10 +267,10 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - # From Steffen Thorsen (2009-08-11): # We have been able to confirm the August change with the Egyptian Cabinet # Information and Decision Support Center: -# http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html +# https://www.timeanddate.com/news/time/egypt-dst-ends-2009.html # # The Middle East News Agency -# http://www.mena.org.eg/index.aspx +# https://www.mena.org.eg/index.aspx # also reports "Egypt starts winter time on August 21" # today in article numbered "71, 11/08/2009 12:25 GMT." # Only the title above is available without a subscription to their service, @@ -320,7 +320,7 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - # Thursday of April.... Clocks will still be turned back for Ramadan, but # dates not yet announced.... # http://almogaz.com/news/weird-news/2015/04/05/1947105 ... -# http://www.timeanddate.com/news/time/egypt-starts-dst-2015.html +# https://www.timeanddate.com/news/time/egypt-starts-dst-2015.html # From Ahmed Nazmy (2015-04-20): # Egypt's ministers cabinet just announced ... that it will cancel DST at @@ -447,11 +447,11 @@ Zone Africa/Monrovia -0:43:08 - LMT 1882 # From Even Scharning (2012-11-10): # Libya set their time one hour back at 02:00 on Saturday November 10. -# http://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/ +# https://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/ # Here is an official source [in Arabic]: http://ls.ly/fb6Yc # # Steffen Thorsen forwarded a translation (2012-11-10) in -# http://mm.icann.org/pipermail/tz/2012-November/018451.html +# https://mm.icann.org/pipermail/tz/2012-November/018451.html # # From Tim Parenti (2012-11-11): # Treat the 2012-11-10 change as a zone change from UTC+2 to UTC+1. @@ -462,7 +462,7 @@ Zone Africa/Monrovia -0:43:08 - LMT 1882 # From Even Scharning (2013-10-25): # The scheduled end of DST in Libya on Friday, October 25, 2013 was # cancelled yesterday.... -# http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/ +# https://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/ # # From Paul Eggert (2013-10-25): # For now, assume they're reverting to the pre-2012 rules of permanent UT +02. @@ -515,7 +515,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 # basis.... # It seems that Mauritius observed daylight saving time from 1982-10-10 to # 1983-03-20 as well, but that was not successful.... -# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html +# https://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html # From Alex Krivenyshev (2008-06-25): # http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD @@ -583,7 +583,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 # http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints- # # Our wrap-up: -# http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html +# https://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html # From Arthur David Olson (2009-07-11): # The "mauritius-dst-will-not-repeat" wrapup includes this: @@ -615,7 +615,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # be one hour ahead of GMT between 1 June and 27 September, according to # Communication Minister and Government Spokesman, Khalid Naciri...." # -# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html +# http://www.worldtimezone.com/dst_news/dst_news_morocco01.html # http://en.afrik.com/news11892.html # From Alex Krivenyshev (2008-05-09): @@ -628,7 +628,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # From Patrice Scattolin (2008-05-09): # According to this article: -# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html +# https://www.avmaroc.com/actualite/heure-dete-comment-a127896.html # (and republished here: ) # the changes occur at midnight: # @@ -650,7 +650,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # posted in English). # # The following Google query will generate many relevant hits: -# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search +# https://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search # From Steffen Thorsen (2008-08-27): # Morocco will change the clocks back on the midnight between August 31 @@ -661,7 +661,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default # # We have some further details posted here: -# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html +# https://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html # From Steffen Thorsen (2009-03-17): # Morocco will observe DST from 2009-06-01 00:00 to 2009-08-21 00:00 according @@ -671,7 +671,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # (French) # # Our summary: -# http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html +# https://www.timeanddate.com/news/time/morocco-starts-dst-2009.html # From Alexander Krivenyshev (2009-03-17): # Here is a link to official document from Royaume du Maroc Premier Ministre, @@ -694,7 +694,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html # (French) # Our page: -# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html +# https://www.timeanddate.com/news/time/morocco-starts-dst-2010.html # From Dan Abitol (2011-03-30): # ...Rules for Africa/Casablanca are the following (24h format) @@ -711,7 +711,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # They said that the decision was already taken. # # More articles in the press -# http://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-leve.html +# https://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-leve.html # http://www.lematin.ma/Actualite/Express/Article.asp?id=148923 # http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim @@ -803,7 +803,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # 1433 (18 April 2012) and the decision of the Head of Government of # 16 N. 3-29-15 Chaaban 1435 (4 June 2015). # Source (french): -# http://lnt.ma/le-maroc-reculera-dune-heure-le-dimanche-14-juin/ +# https://lnt.ma/le-maroc-reculera-dune-heure-le-dimanche-14-juin/ # # From Milamber (2015-06-09): # http://www.mmsp.gov.ma/fr/actualites.aspx?id=863 @@ -812,7 +812,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # [The gov.ma announcement] would (probably) make the switch on 2015-07-19 go # from 03:00 to 04:00 rather than from 02:00 to 03:00, as in the patch.... # I think the patch is correct and the quoted text is wrong; the text in -# agrees +# agrees # with the patch. # From Paul Eggert (2015-06-08): @@ -937,9 +937,17 @@ Link Africa/Maputo Africa/Kigali # Rwanda Link Africa/Maputo Africa/Lubumbashi # E Dem. Rep. of Congo Link Africa/Maputo Africa/Lusaka # Zambia + # Namibia -# The 1994-04-03 transition is from Shanks & Pottenger. -# Shanks & Pottenger report no DST after 1998-04; go with IATA. + +# From Arthur David Olson (2017-08-09): +# The text of the "Namibia Time Act, 1994" is available online at +# www.lac.org.na/laws/1994/811.pdf +# and includes this nugget: +# Notwithstanding the provisions of subsection (2) of section 1, the +# first winter period after the commencement of this Act shall +# commence at OOhOO on Monday 21 March 1994 and shall end at 02h00 on +# Sunday 4 September 1994. # From Petronella Sibeene (2007-03-30): # http://allafrica.com/stories/200703300178.html @@ -955,19 +963,30 @@ Link Africa/Maputo Africa/Lusaka # Zambia # observes Botswana time, we have no details about historical practice. # In the meantime people there can use Africa/Gaborone. # See: Immanuel S. The Namibian. 2017-02-23. -# http://www.namibian.com.na/51480/read/Time-change-divides-lawmakers +# https://www.namibian.com.na/51480/read/Time-change-divides-lawmakers + +# From Steffen Thorsen (2017-08-09): +# Namibia is going to change their time zone to what is now their DST: +# https://www.newera.com.na/2017/02/23/namibias-winter-time-might-be-repealed/ +# This video is from the government decision: +# https://www.nbc.na/news/na-passes-namibia-time-bill-repealing-1994-namibia-time-act.8665 +# We have made the assumption so far that they will change their time zone at +# the same time they would normally start DST, the first Sunday in September: +# https://www.timeanddate.com/news/time/namibia-new-time-zone.html # RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Namibia 1994 max - Sep Sun>=1 2:00 1:00 S -Rule Namibia 1995 max - Apr Sun>=1 2:00 0 - +Rule Namibia 1994 only - Mar 21 0:00 0 - +Rule Namibia 1994 2016 - Sep Sun>=1 2:00 1:00 S +Rule Namibia 1995 2017 - Apr Sun>=1 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 1:30 - +0130 1903 Mar 2:00 - SAST 1942 Sep 20 2:00 2:00 1:00 SAST 1943 Mar 21 2:00 2:00 - SAST 1990 Mar 21 # independence - 2:00 - CAT 1994 Apr 3 - 1:00 Namibia WA%sT + 2:00 - CAT 1994 Mar 21 0:00 + 1:00 Namibia WA%sT 2017 Sep 3 2:00 + 2:00 - CAT # Niger # See Africa/Lagos. @@ -1054,14 +1073,24 @@ Link Africa/Johannesburg Africa/Mbabane # Swaziland # no information # Sudan -# + # From # Sudan News Agency (2000-01-13), # also reported by Michaël De Beukelaer-Dossche via Steffen Thorsen: # Clocks will be moved ahead for 60 minutes all over the Sudan as of noon # Saturday.... This was announced Thursday by Caretaker State Minister for # Manpower Abdul-Rahman Nur-Eddin. + +# From Ahmed Atyya, National Telecommunications Corp. (NTC), Sudan (2017-10-17): +# ... the Republic of Sudan is going to change the time zone from (GMT+3:00) +# to (GMT+ 2:00) starting from Wednesday 1 November 2017. # +# From Paul Eggert (2017-10-18): +# A scanned copy (in Arabic) of Cabinet Resolution No. 352 for the +# year 2017 can be found as an attachment in email today from Yahia +# Abdalla of NTC, archived at: +# https://mm.icann.org/pipermail/tz/2017-October/025333.html + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Sudan 1970 only - May 1 0:00 1:00 S Rule Sudan 1970 1985 - Oct 15 0:00 0 - @@ -1070,10 +1099,14 @@ Rule Sudan 1972 1985 - Apr lastSun 0:00 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Khartoum 2:10:08 - LMT 1931 2:00 Sudan CA%sT 2000 Jan 15 12:00 - 3:00 - EAT + 3:00 - EAT 2017 Nov 1 + 2:00 - CAT # South Sudan -Link Africa/Khartoum Africa/Juba +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Juba 2:06:28 - LMT 1931 + 2:00 Sudan CA%sT 2000 Jan 15 12:00 + 3:00 - EAT # Swaziland # See Africa/Johannesburg. @@ -1111,11 +1144,11 @@ Link Africa/Khartoum Africa/Juba # According to several news sources, Tunisia will not observe DST this year. # (Arabic) # http://www.elbashayer.com/?page=viewn&nid=42546 -# http://www.babnet.net/kiwidetail-15295.asp +# https://www.babnet.net/kiwidetail-15295.asp # # We have also confirmed this with the US embassy in Tunisia. # We have a wrap-up about this on the following page: -# http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html +# https://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html # From Alexander Krivenyshev (2009-03-17): # Here is a link to Tunis Afrique Presse News Agency diff --git a/contrib/tzdata/antarctica b/contrib/tzdata/antarctica index 3332d6684252..d9c132a30f45 100644 --- a/contrib/tzdata/antarctica +++ b/contrib/tzdata/antarctica @@ -26,7 +26,7 @@ # Heard Island, McDonald Islands (uninhabited) # previously sealers and scientific personnel wintered # Margaret Turner reports -# http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html +# https://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html # (1999-09-30) that they're UT +05, with no DST; # presumably this is when they have visitors. # @@ -47,7 +47,7 @@ # http://www.aad.gov.au/default.asp?casid=37079 # # We have more background information here: -# http://www.timeanddate.com/news/time/antarctica-new-times.html +# https://www.timeanddate.com/news/time/antarctica-new-times.html # From Steffen Thorsen (2010-03-10): # We got these changes from the Australian Antarctic Division: ... @@ -62,7 +62,7 @@ # - Mawson station stays on UTC+5. # # Background: -# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html +# https://www.timeanddate.com/news/time/antartica-time-changes-2010.html # From Steffen Thorsen (2016-10-28): # Australian Antarctica Division informed us that Casey changed time @@ -145,7 +145,7 @@ Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français # # year-round base in the main continent # Dumont d'Urville, ÃŽle des Pétrels, -6640+14001, since 1956-11 -# (2005-12-05) +# (2005-12-05) # # Another base at Port-Martin, 50km east, began operation in 1947. # It was destroyed by fire on 1952-01-14. diff --git a/contrib/tzdata/asia b/contrib/tzdata/asia index 35774c6d7edd..ac39af351ecd 100644 --- a/contrib/tzdata/asia +++ b/contrib/tzdata/asia @@ -26,7 +26,7 @@ # # For data circa 1899, a common source is: # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. -# http://www.jstor.org/stable/1774359 +# https://www.jstor.org/stable/1774359 # # For Russian data circa 1919, a source is: # Byalokoz EL. New Counting of Time in Russia since July 1, 1919. @@ -75,8 +75,8 @@ Rule E-EurAsia 1996 max - Oct lastSun 0:00 0 - Rule RussiaAsia 1981 1984 - Apr 1 0:00 1:00 S Rule RussiaAsia 1981 1983 - Oct 1 0:00 0 - Rule RussiaAsia 1984 1995 - Sep lastSun 2:00s 0 - -Rule RussiaAsia 1985 2011 - Mar lastSun 2:00s 1:00 S -Rule RussiaAsia 1996 2011 - Oct lastSun 2:00s 0 - +Rule RussiaAsia 1985 2010 - Mar lastSun 2:00s 1:00 S +Rule RussiaAsia 1996 2010 - Oct lastSun 2:00s 0 - # Afghanistan # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -109,13 +109,17 @@ Zone Asia/Kabul 4:36:48 - LMT 1890 # or # (brief) # http://www.worldtimezone.com/dst_news/dst_news_armenia03.html +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Armenia 2011 only - Mar lastSun 2:00s 1:00 S +Rule Armenia 2011 only - Oct lastSun 2:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 3:00 - +03 1957 Mar 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s 3:00 RussiaAsia +03/+04 1995 Sep 24 2:00s 4:00 - +04 1997 - 4:00 RussiaAsia +04/+05 + 4:00 RussiaAsia +04/+05 2011 + 4:00 Armenia +04/+05 # Azerbaijan @@ -127,7 +131,7 @@ Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 # From Steffen Thorsen (2016-03-17): # ... the Azerbaijani Cabinet of Ministers has cancelled switching to # daylight saving time.... -# http://www.azernews.az/azerbaijan/94137.html +# https://www.azernews.az/azerbaijan/94137.html # http://vestnikkavkaza.net/news/Azerbaijani-Cabinet-of-Ministers-cancels-daylight-saving-time.html # http://en.apa.az/xeber_azerbaijan_abolishes_daylight_savings_ti_240862.html @@ -168,11 +172,11 @@ Zone Asia/Baku 3:19:24 - LMT 1924 May 2 # the 19th and 20th, and they have not set the end date yet. # # Some sources: -# http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601 +# https://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601 # http://bdnews24.com/details.php?id=85889&cid=2 # # Our wrap-up: -# http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html +# https://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html # From A. N. M. Kamrus Saadat (2009-06-15): # Finally we've got the official mail regarding DST start time where DST start @@ -258,9 +262,15 @@ Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan # Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon. +# From Paul Eggert (2017-04-20): +# Page 27 of Reed & Low (cited for Asia/Kolkata) says "Rangoon local time is +# used upon the railways and telegraphs of Burma, and is 6h. 24m. 47s. ahead +# of Greenwich." This refers to the period before Burma's transition to +0630, +# a transition for which Shanks is the only source. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Yangon 6:24:40 - LMT 1880 # or Rangoon - 6:24:40 - RMT 1920 # Rangoon Mean Time? +Zone Asia/Yangon 6:24:47 - LMT 1880 # or Rangoon + 6:24:47 - RMT 1920 # Rangoon local time 6:30 - +0630 1942 May 9:00 - +09 1945 May 3 6:30 - +0630 @@ -317,7 +327,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D # # From Jesper Nørgaard Welen (2006-07-14): # I have investigated the timezones around 1970 on the -# http://www.astro.com/atlas site [with provinces and county +# https://www.astro.com/atlas site [with provinces and county # boundaries summarized below].... A few other exceptions were two # counties on the Sichuan side of the Xizang-Sichuan border, # counties Dege and Baiyu which lies on the Sichuan side and are @@ -469,7 +479,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D # From David Cochrane (2014-03-26): # Just a confirmation that Ãœrümqi time was implemented in Ãœrümqi on 1 Feb 1986: -# http://content.time.com/time/magazine/article/0,9171,960684,00.html +# https://content.time.com/time/magazine/article/0,9171,960684,00.html # From Luther Ma (2014-04-22): # I have interviewed numerous people of various nationalities and from @@ -626,7 +636,7 @@ Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 # (both in Okinawa) adopt the Western Standard Time which is based on # 120E. The adoption began from Jan 1, 1896. The original text can be # found on Wikisource: -# http://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時) +# https://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時) # ... This could be the first adoption of time zone in Taiwan, because # during the Qing Dynasty, it seems that there was no time zone # declared officially. @@ -639,7 +649,7 @@ Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 # territory, including later occupations, adopt Japan Central Time # (UTC+9). The adoption began on Oct 1, 1937. The original text can # be found on Wikisource: -# http://ja.wikisource.org/wiki/明治二å八年勅令第百六å七號標準時ニ關スル件中改正ノ件 +# https://ja.wikisource.org/wiki/明治二å八年勅令第百六å七號標準時ニ關スル件中改正ノ件 # # That is, the time zone of Taipei switched to UTC+9 on Oct 1, 1937. @@ -775,6 +785,12 @@ Zone Asia/Macau 7:34:20 - LMT 1912 Jan 1 # Looks like the time zone split in Cyprus went through last night. # http://cyprus-mail.com/2016/10/30/cyprus-new-division-two-time-zones-now-reality/ +# From Paul Eggert (2017-10-18): +# Northern Cyprus will reinstate winter time on October 29, thus +# staying in sync with the rest of Cyprus. See: Anastasiou A. +# Cyprus to remain united in time. Cyprus Mail 2017-10-17. +# https://cyprus-mail.com/2017/10/17/cyprus-remain-united-time/ + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Cyprus 1975 only - Apr 13 0:00 1:00 S Rule Cyprus 1975 only - Oct 12 0:00 0 - @@ -792,7 +808,8 @@ Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14 Zone Asia/Famagusta 2:15:48 - LMT 1921 Nov 14 2:00 Cyprus EE%sT 1998 Sep 2:00 EUAsia EE%sT 2016 Sep 8 - 3:00 - +03 + 3:00 - +03 2017 Oct 29 1:00u + 2:00 EUAsia EE%sT # Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72. # However, for various reasons many users expect to find it under Europe. @@ -852,7 +869,7 @@ Zone Asia/Tbilisi 2:59:11 - LMT 1880 # From João Carrascalão, brother of the former governor of East Timor, in # East Timor may be late for its millennium -# (1999-12-26/31): +# (1999-12-26/31): # Portugal tried to change the time forward in 1974 because the sun # rises too early but the suggestion raised a lot of problems with the # Timorese and I still don't think it would work today because it @@ -880,21 +897,62 @@ Zone Asia/Dili 8:22:20 - LMT 1912 Jan 1 # India # From Ian P. Beacock, in "A brief history of (modern) time", The Atlantic -# http://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/ +# https://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/ # (2015-12-22): # In January 1906, several thousand cotton-mill workers rioted on the # outskirts of Bombay.... They were protesting the proposed abolition of # local time in favor of Indian Standard Time.... Journalists called this # dispute the "Battle of the Clocks." It lasted nearly half a century. +# From Paul Eggert (2017-04-20): +# Good luck trying to nail down old timekeeping records in India. +# "... in the nineteenth century ... Madras Observatory took its magnetic +# measurements on Göttingen time, its meteorological measurements on Madras +# (local) time, dropped its time ball on Greenwich (ocean navigator's) time, +# and distributed civil (local time)." -- Bartky IR. Selling the true time: +# 19th-century timekeeping in america. Stanford U Press (2000), 247 note 19. +# "A more potent cause of resistance to the general adoption of the present +# standard time lies in the fact that it is Madras time. The citizen of +# Bombay, proud of being 'primus in Indis' and of Calcutta, equally proud of +# his city being the Capital of India, and - for a part of the year - the Seat +# of the Supreme Government, alike look down on Madras, and refuse to change +# the time they are using, for that of what they regard as a benighted +# Presidency; while Madras, having for long given the standard time to the +# rest of India, would resist the adoption of any other Indian standard in its +# place." -- Oldham RD. On Time in India: a suggestion for its improvement. +# Proceedings of the Asiatic Society of Bengal (April 1899), 49-55. +# +# "In 1870 ... Madras time - 'now used by the telegraph and regulated from the +# only government observatory' - was suggested as a standard railway time, +# first to be adopted on the Great Indian Peninsular Railway (GIPR).... +# Calcutta, Bombay, and Karachi, were to be allowed to continue with their +# local time for civil purposes." - Prasad R. Tracks of Change: Railways and +# Everyday Life in Colonial India. Cambridge University Press (2016), 145. +# +# Reed S, Low F. The Indian Year Book 1936-37. Bennett, Coleman, pp 27-8. +# https://archive.org/details/in.ernet.dli.2015.282212 +# This lists +052110 as Madras local time used in railways, and says that on +# 1906-01-01 railways and telegraphs in India switched to +0530. Some +# municipalities retained their former time, and the time in Calcutta +# continued to depend on whether you were at the railway station or at +# government offices. Government time was at +055320 (according to Shanks) or +# at +0554 (according to the Indian Year Book). Railway time is more +# appropriate for our purposes, as it was better documented, it is what we do +# elsewhere (e.g., Europe/London before 1880), and after 1906 it was +# consistent in the region now identified by Asia/Kolkata. So, use railway +# time for 1870-1941. Shanks is our only (and dubious) source for the +# 1941-1945 data. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata - 5:53:20 - HMT 1941 Oct # Howrah Mean Time? - 6:30 - +0630 1942 May 15 +Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata + 5:53:20 - HMT 1870 # Howrah Mean Time? + 5:21:10 - MMT 1906 Jan 1 # Madras local time + 5:30 - IST 1941 Oct + 5:30 1:00 +0630 1942 May 15 5:30 - IST 1942 Sep 5:30 1:00 +0630 1945 Oct 15 5:30 - IST -# The following are like Asia/Kolkata: +# Since 1970 the following are like Asia/Kolkata: # Andaman Is # Lakshadweep (Laccadive, Minicoy and Amindivi Is) # Nicobar Is @@ -1036,7 +1094,7 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov # From Reuters (2007-09-16), with a heads-up from Jesper Nørgaard Welen: # ... the Guardian Council ... approved a law on Sunday to re-introduce # daylight saving time ... -# http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916 +# https://uk.reuters.com/article/oilRpt/idUKBLA65048420070916 # # From Roozbeh Pournader (2007-11-05): # This is quoted from Official Gazette of the Islamic Republic of @@ -1135,7 +1193,7 @@ Zone Asia/Tehran 3:25:44 - LMT 1916 # http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10 # # We have published a short article in English about the change: -# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html +# https://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Iraq 1982 only - May 1 0:00 1:00 D @@ -1443,12 +1501,12 @@ Rule Japan 1950 1951 - May Sun>=1 2:00 1:00 D # From Yu-Cheng Chuang (2013-07-12): # ...the Meiji Emperor announced Ordinance No. 167 of Meiji Year 28 "The clause # about standard time" ... The adoption began from Jan 1, 1896. -# http://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時) +# https://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時) # # ...the Showa Emperor announced Ordinance No. 529 of Showa Year 12 ... which # means the whole Japan territory, including later occupations, adopt Japan # Central Time (UTC+9). The adoption began on Oct 1, 1937. -# http://ja.wikisource.org/wiki/明治二å八年勅令第百六å七號標準時ニ關スル件中改正ノ件 +# https://ja.wikisource.org/wiki/明治二å八年勅令第百六å七號標準時ニ關スル件中改正ノ件 # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u @@ -1510,7 +1568,7 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u # Official, in Arabic: # http://www.petra.gov.jo/public_news/Nws_NewsDetails.aspx?Menu_ID=&Site_Id=2&lang=1&NewsID=133230&CatID=14 # ... Our background/permalink about it -# http://www.timeanddate.com/news/time/jordan-reverses-dst-decision.html +# https://www.timeanddate.com/news/time/jordan-reverses-dst-decision.html # ... # http://www.petra.gov.jo/Public_News/Nws_NewsDetails.aspx?lang=2&site_id=1&NewsID=133313&Type=P # ... says midnight for the coming one and 1:00 for the ones in the future @@ -1868,9 +1926,9 @@ Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 # between 1987 and 1988 ... # From Sanghyuk Jung (2014-10-29): -# http://mm.icann.org/pipermail/tz/2014-October/021830.html +# https://mm.icann.org/pipermail/tz/2014-October/021830.html # According to the Korean Wikipedia -# http://ko.wikipedia.org/wiki/한국_표준시 +# https://ko.wikipedia.org/wiki/한국_표준시 # [oldid=12896437 2014-09-04 08:03 UTC] # DST in Republic of Korea was as follows.... And I checked old # newspapers in Korean, all articles correspond with data in Wikipedia. @@ -2092,7 +2150,7 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Male # +08:00 instead. Different sources appear to disagree with the tz # database on this, e.g.: # -# http://www.timeanddate.com/worldclock/city.html?n=1026 +# https://www.timeanddate.com/worldclock/city.html?n=1026 # http://www.worldtimeserver.com/current_time_in_MN.aspx # # both say GMT+08:00. @@ -2222,7 +2280,7 @@ Zone Asia/Kathmandu 5:41:16 - LMT 1920 # help reduce load shedding by approving the closure of commercial centres at # 9pm and moving clocks forward by one hour for the next three months. ...." # -# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html +# http://www.worldtimezone.com/dst_news/dst_news_pakistan01.html # http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4 # From Arthur David Olson (2008-05-19): @@ -2288,7 +2346,7 @@ Zone Asia/Kathmandu 5:41:16 - LMT 1920 # # We have confirmed this year's end date with both with the Ministry of # Water and Power and the Pakistan Electric Power Company: -# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html +# https://www.timeanddate.com/news/time/pakistan-ends-dst09.html # From Christoph Göhre (2009-10-01): # [T]he German Consulate General in Karachi reported me today that Pakistan @@ -2470,7 +2528,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # # We are not sure if Gaza will do the same, last year they had a different # end date, we will keep this page updated: -# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html +# https://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html # From Alexander Krivenyshev (2009-09-02): # Seems that Gaza Strip will go back to Winter Time same date as West Bank. @@ -2508,7 +2566,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # the clocks were set back one hour at 2010-08-11 00:00:00 local time in # Gaza and the West Bank. # Some more background info: -# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html +# https://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html # From Steffen Thorsen (2011-08-26): # Gaza and the West Bank did go back to standard time in the beginning of @@ -2518,7 +2576,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # # http://www.maannews.net/eng/ViewDetails.aspx?ID=416217 # Additional info: -# http://www.timeanddate.com/news/time/palestine-dst-2011.html +# https://www.timeanddate.com/news/time/palestine-dst-2011.html # From Alexander Krivenyshev (2011-08-27): # According to the article in The Jerusalem Post: @@ -2528,7 +2586,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # The Hamas government said on Saturday that it won't observe summertime after # the Muslim feast of Id al-Fitr, which begins on Tuesday..." # ... -# http://www.jpost.com/MiddleEast/Article.aspx?id=235650 +# https://www.jpost.com/MiddleEast/Article.aspx?id=235650 # http://www.worldtimezone.com/dst_news/dst_news_gazastrip05.html # The rules for Egypt are stolen from the 'africa' file. @@ -2549,7 +2607,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html # # Our brief summary: -# http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html +# https://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html # From Steffen Thorsen (2013-03-26): # The following news sources tells that Palestine will "start daylight saving @@ -2569,11 +2627,11 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # From Steffen Thorsen (2015-03-03): # Sources such as http://www.alquds.com/news/article/view/id/548257 -# and http://www.raya.ps/ar/news/890705.html say Palestine areas will +# and https://www.raya.ps/ar/news/890705.html say Palestine areas will # start DST on 2015-03-28 00:00 which is one day later than expected. # # From Paul Eggert (2015-03-03): -# http://www.timeanddate.com/time/change/west-bank/ramallah?year=2014 +# https://www.timeanddate.com/time/change/west-bank/ramallah?year=2014 # says that the fall 2014 transition was Oct 23 at 24:00. # From Hannah Kreitem (2016-03-09): @@ -2597,8 +2655,8 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # # From Paul Eggert (2016-10-19): # It's also consistent with predictions in the following URLs today: -# http://www.timeanddate.com/time/change/gaza-strip/gaza -# http://www.timeanddate.com/time/change/west-bank/hebron +# https://www.timeanddate.com/time/change/gaza-strip/gaza +# https://www.timeanddate.com/time/change/west-bank/hebron # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -2661,7 +2719,7 @@ Zone Asia/Hebron 2:20:23 - LMT 1900 Oct # Philippines, issued a proclamation announcing that 1844-12-30 was to # be immediately followed by 1845-01-01; see R.H. van Gent's # History of the International Date Line -# http://www.staff.science.uu.nl/~gent0113/idl/idl_philippines.htm +# https://www.staff.science.uu.nl/~gent0113/idl/idl_philippines.htm # The rest of the data entries are from Shanks & Pottenger. # From Jesper Nørgaard Welen (2006-04-26): @@ -2925,7 +2983,7 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 - # We have not found any sources saying anything about when DST ends this year. # # Our summary -# http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html +# https://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html # From Steffen Thorsen (2009-10-27): # The Syrian Arab News Network on 2009-09-29 reported that Syria will @@ -2952,7 +3010,7 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 - # http://www.sana.sy/ara/2/2012/03/26/408215.htm # # Our brief summary: -# http://www.timeanddate.com/news/time/syria-dst-2012.html +# https://www.timeanddate.com/news/time/syria-dst-2012.html # From Arthur David Olson (2012-03-27): # Assume last Friday in March going forward XXX. @@ -3035,7 +3093,7 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 # is quoted verbatim in: # http://www.thoigian.com.vn/?mPage=P80D01 # is translated by Brian Inglis in: -# http://mm.icann.org/pipermail/tz/2014-October/021654.html +# https://mm.icann.org/pipermail/tz/2014-October/021654.html # and is the basis for the information below. # # The 1906 transition was effective July 1 and standardized Indochina to diff --git a/contrib/tzdata/australasia b/contrib/tzdata/australasia index d389ae134ab7..5f7c86dda660 100644 --- a/contrib/tzdata/australasia +++ b/contrib/tzdata/australasia @@ -293,7 +293,7 @@ Zone Indian/Cocos 6:27:40 - LMT 1900 # http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166 # # A bit more background info here: -# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html +# https://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html # From Alexander Krivenyshev (2010-10-24): # According to Radio Fiji and Fiji Times online, Fiji will end DST 3 @@ -357,9 +357,12 @@ Zone Indian/Cocos 6:27:40 - LMT 1900 # clocks go forward an hour at 2am to 3am.... Daylight Saving will # end at 3.00am on Sunday 15th January 2017." -# From Paul Eggert (2016-10-03): -# For now, guess DST from 02:00 the first Sunday in November to -# 03:00 the third Sunday in January. Although ad hoc, it matches +# From Paul Eggert (2017-08-21): +# Dominic Fok writes (2017-08-20) that DST ends 2018-01-14, citing +# Extraordinary Government of Fiji Gazette Supplement No. 21 (2017-08-27), +# [Legal Notice No. 41] of an order of the previous day by J Usamate. +# For now, guess DST from 02:00 the first Sunday in November to 03:00 +# the first Sunday on or after January 14. Although ad hoc, it matches # transitions since late 2014 and seems more likely to match future # practice than guessing no DST. @@ -373,7 +376,7 @@ Rule Fiji 2011 only - Mar Sun>=1 3:00 0 - Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 - Rule Fiji 2014 only - Jan Sun>=18 2:00 0 - Rule Fiji 2014 max - Nov Sun>=1 2:00 1:00 S -Rule Fiji 2015 max - Jan Sun>=15 3:00 0 - +Rule Fiji 2015 max - Jan Sun>=14 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva 12:00 Fiji +12/+13 @@ -557,7 +560,7 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 # The World War II entries below are instead based on Arawa-Kieta. # The Japanese occupied Kieta in July 1942, # according to the Pacific War Online Encyclopedia -# http://pwencycl.kgbudge.com/B/o/Bougainville.htm +# https://pwencycl.kgbudge.com/B/o/Bougainville.htm # and seem to have controlled it until their 1945-08-21 surrender. # # The Autonomous Region of Bougainville switched from UT +10 to +11 @@ -579,7 +582,7 @@ Zone Pacific/Pitcairn -8:40:20 - LMT 1901 # Adamstown -8:00 - -08 # American Samoa -Zone Pacific/Pago_Pago 12:37:12 - LMT 1879 Jul 5 +Zone Pacific/Pago_Pago 12:37:12 - LMT 1892 Jul 5 -11:22:48 - LMT 1911 -11:00 - SST # S=Samoa Link Pacific/Pago_Pago Pacific/Midway # in US minor outlying islands @@ -595,7 +598,7 @@ Link Pacific/Pago_Pago Pacific/Midway # in US minor outlying islands # Sunday of April 2011." # # Background info: -# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html +# https://www.timeanddate.com/news/time/samoa-dst-plan-2009.html # # Samoa's Daylight Saving Time Act 2009 is available here, but does not # contain any dates: @@ -659,7 +662,7 @@ Rule WS 2011 only - Sep lastSat 3:00 1 D Rule WS 2012 max - Apr Sun>=1 4:00 0 S Rule WS 2012 max - Sep lastSun 3:00 1 D # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5 +Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5 -11:26:56 - LMT 1911 -11:30 - -1130 1950 -11:00 WS -11/-10 2011 Dec 29 24:00 @@ -686,7 +689,7 @@ Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara # From Paul Eggert (2012-07-25) # A Google Books snippet of Appendix to the Journals of the House of # Representatives of New Zealand, Session 1948, -# , page 65, says Tokelau +# , page 65, says Tokelau # was "11 hours slow on G.M.T." Go with Thorsen and assume Shanks & Pottenger # are off by an hour starting in 1901. @@ -701,8 +704,8 @@ Rule Tonga 1999 only - Oct 7 2:00s 1:00 S Rule Tonga 2000 only - Mar 19 2:00s 0 - Rule Tonga 2000 2001 - Nov Sun>=1 2:00 1:00 S Rule Tonga 2001 2002 - Jan lastSun 2:00 0 - -Rule Tonga 2016 max - Nov Sun>=1 2:00 1:00 S -Rule Tonga 2017 max - Jan Sun>=15 3:00 0 - +Rule Tonga 2016 only - Nov Sun>=1 2:00 1:00 S +Rule Tonga 2017 only - Jan Sun>=15 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Pacific/Tongatapu 12:19:20 - LMT 1901 12:20 - +1220 1941 @@ -756,7 +759,7 @@ Zone Pacific/Funafuti 11:56:52 - LMT 1901 # Operation Fishbowl shot (Tightrope, 1962-11-04).... [See] Herman Hoerlin, # "The United States High-Altitude Test Experience: A Review Emphasizing the # Impact on the Environment", Los Alamos LA-6405, Oct 1976. -# http://www.fas.org/sgp/othergov/doe/lanl/docs1/00322994.pdf +# https://www.fas.org/sgp/othergov/doe/lanl/docs1/00322994.pdf # See the table on page 4 where he lists GMT and local times for the tests; a # footnote for the JI tests reads that local time is "JI time = Hawaii Time # Minus One Hour". @@ -822,7 +825,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # # For data circa 1899, a common source is: # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. -# http://www.jstor.org/stable/1774359 +# https://www.jstor.org/stable/1774359 # # A reliable and entertaining source about time zones is # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). @@ -969,7 +972,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # AEST ACST AWST AEDT ACDT # # Parliamentary Library (2008-11-10) -# http://www.aph.gov.au/binaries/library/pubs/rp/2008-09/09rp14.pdf +# https://www.aph.gov.au/binaries/library/pubs/rp/2008-09/09rp14.pdf # EST CST WST preferred for standard time; AEST AEDT ACST ACDT also used # # The Transport Safety Bureau has an extensive series of accident reports, @@ -1005,13 +1008,13 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # # NSW (including LHI and Broken Hill): # Standard Time Act 1987 (updated 1995-04-04) -# http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html +# https://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html # ACT # Standard Time and Summer Time Act 1972 -# http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html +# https://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html # SA # Standard Time Act, 1898 -# http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html +# https://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html # From David Grosz (2005-06-13): # It was announced last week that Daylight Saving would be extended by @@ -1306,7 +1309,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm # (1999-07-22). For now, we'll wait to see if this really happens. # -# Victoria will following NSW. See: +# Victoria will follow NSW. See: # Vic to extend daylight saving (1999-07-28) # http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm # @@ -1409,7 +1412,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # the ACT for all 52 weeks of the year... # # We have a wrap-up here: -# http://www.timeanddate.com/news/time/south-australia-extends-dst.html +# https://www.timeanddate.com/news/time/south-australia-extends-dst.html ############################################################################### # New Zealand @@ -1463,7 +1466,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # From Paul Eggert (2014-07-14): # Chatham Island time was formally standardized on 1957-01-01 by # New Zealand's Standard Time Amendment Act 1956 (1956-10-26). -# http://www.austlii.edu.au/nz/legis/hist_act/staa19561956n100244.pdf +# https://www.austlii.edu.au/nz/legis/hist_act/staa19561956n100244.pdf # According to Google Books snippet view, a speaker in the New Zealand # parliamentary debates in 1956 said "Clause 78 makes provision for standard # time in the Chatham Islands. The time there is 45 minutes in advance of New @@ -1578,7 +1581,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # the Norfolk Island Museum and the Australian Bureau of Meteorology's # Norfolk Island station, and found no record of Norfolk observing DST # other than in 1974/5. See: -# http://www.timeanddate.com/time/australia/norfolk-island.html +# https://www.timeanddate.com/time/australia/norfolk-island.html # Pitcairn @@ -1606,11 +1609,13 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # (Western) Samoa and American Samoa -# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald) -# that in 1879 the King of Samoa decided to change +# Howse writes (p 153) that after the 1879 standardization on Antipodean +# time by the British governor of Fiji, the King of Samoa decided to change # "the date in his kingdom from the Antipodean to the American system, # ordaining - by a masterpiece of diplomatic flattery - that # the Fourth of July should be celebrated twice in that year." +# This happened in 1892, according to the Evening News (Sydney) of 1892-07-20. +# https://www.staff.science.uu.nl/~gent0113/idl/idl.htm # Although Shanks & Pottenger says they both switched to UT -11:30 # in 1911, and to -11 in 1950. many earlier sources give -11 @@ -1621,6 +1626,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # day in 2011. Assume also that the Samoas follow the US and New # Zealand's "ST"/"DT" style of daylight-saving abbreviations. + # Tonga # From Paul Eggert (1996-01-22): @@ -1715,6 +1721,15 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # Assume Tonga will observe DST from the first Sunday in November at 02:00 # through the third Sunday in January at 03:00, like Fiji, for now. +# From David Wade (2017-10-18): +# In August government was disolved by the King. The current prime minister +# continued in office in care taker mode. It is easy to see that few +# decisions will be made until elections 16th November. +# +# From Paul Eggert (2017-10-18): +# For now, guess that DST is discontinued. That's what the IATA is guessing. + + # Wake # From Vernice Anderson, Personal Secretary to Philip Jessup, @@ -1727,7 +1742,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # making calculation of time in Washington difficult if not almost # impossible. # -# http://www.trumanlibrary.org/wake/meeting.htm +# https://www.trumanlibrary.org/oralhist/andrsonv.htm # From Paul Eggert (2003-03-23): # We have no other report of DST in Wake Island, so omit this info for now. @@ -1755,7 +1770,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # an international standard, there are some places on the high seas where the # correct date is ambiguous. -# From Wikipedia (2005-08-31): +# From Wikipedia (2005-08-31): # Before 1920, all ships kept local apparent time on the high seas by setting # their clocks at night or at the morning sight so that, given the ship's # speed and direction, it would be 12 o'clock when the Sun crossed the ship's diff --git a/contrib/tzdata/backward b/contrib/tzdata/backward index 09f2a31b685d..2141f0d5798f 100644 --- a/contrib/tzdata/backward +++ b/contrib/tzdata/backward @@ -61,7 +61,9 @@ Link America/Sao_Paulo Brazil/East Link America/Manaus Brazil/West Link America/Halifax Canada/Atlantic Link America/Winnipeg Canada/Central -Link America/Regina Canada/East-Saskatchewan +# This line is commented out, as the name exceeded the 14-character limit +# and was an unused misnomer. +#Link America/Regina Canada/East-Saskatchewan Link America/Toronto Canada/Eastern Link America/Edmonton Canada/Mountain Link America/St_Johns Canada/Newfoundland diff --git a/contrib/tzdata/backzone b/contrib/tzdata/backzone index 9ce78316c2b3..32bd0f106155 100644 --- a/contrib/tzdata/backzone +++ b/contrib/tzdata/backzone @@ -181,7 +181,7 @@ Zone Africa/Lome 0:04:52 - LMT 1893 # with the date that it took effect, namely 1912-01-01. # Zone Africa/Luanda 0:52:56 - LMT 1892 - 0:52:04 - +005204 1912 Jan 1 + 0:52:04 - LMT 1912 Jan 1 # Luanda Mean Time? 1:00 - WAT # Democratic Republic of the Congo (east) @@ -540,10 +540,10 @@ Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2 # Guernsey # Data from Joseph S. Myers -# http://mm.icann.org/pipermail/tz/2013-September/019883.html +# https://mm.icann.org/pipermail/tz/2013-September/019883.html # References to be added -# LMT Location - 49.27N -2.33E - St.Peter Port -Zone Europe/Guernsey -0:09:19 - LMT 1913 Jun 18 +# LMT is for Town Church, St. Peter Port, 49 degrees 27'17"N 2 degrees 32'10"W +Zone Europe/Guernsey -0:10:09 - LMT 1913 Jun 18 0:00 GB-Eire %s 1940 Jul 2 1:00 C-Eur CE%sT 1945 May 8 0:00 GB-Eire %s 1968 Oct 27 @@ -555,11 +555,11 @@ Zone Europe/Guernsey -0:09:19 - LMT 1913 Jun 18 # # From Lester Caine (2013-09-04): # The Isle of Man legislation is now on-line at -# , starting with the original Statutory +# , starting with the original Statutory # Time Act in 1883 and including additional confirmation of some of # the dates of the 'Summer Time' orders originating at # Westminster. There is a little uncertainty as to the starting date -# of the first summer time in 1916 which may have be announced a +# of the first summer time in 1916 which may have been announced a # couple of days late. There is still a substantial number of # documents to work through, but it is thought that every GB change # was also implemented on the island. @@ -574,10 +574,10 @@ Zone Europe/Isle_of_Man -0:17:55 - LMT 1883 Mar 30 0:00s # Jersey # Data from Joseph S. Myers -# http://mm.icann.org/pipermail/tz/2013-September/019883.html +# https://mm.icann.org/pipermail/tz/2013-September/019883.html # References to be added -# LMT Location - 49.187N -2.107E - St. Helier -Zone Europe/Jersey -0:08:25 - LMT 1898 Jun 11 16:00u +# LMT is for Parish Church, St. Helier, 49 degrees 11'0.57"N 2 degrees 6'24.33"W +Zone Europe/Jersey -0:08:26 - LMT 1898 Jun 11 16:00u 0:00 GB-Eire %s 1940 Jul 2 1:00 C-Eur CE%sT 1945 May 8 0:00 GB-Eire %s 1968 Oct 27 diff --git a/contrib/tzdata/calendars b/contrib/tzdata/calendars new file mode 100644 index 000000000000..8bc70626eb5a --- /dev/null +++ b/contrib/tzdata/calendars @@ -0,0 +1,173 @@ +----- Calendrical issues ----- + +As mentioned in Theory.html, although calendrical issues are out of +scope for tzdb, they indicate the sort of problems that we would run +into if we extended tzdb further into the past. The following +information and sources go beyond Theory.html's brief discussion. +They sometimes disagree. + + +France + +Gregorian calendar adopted 1582-12-20. +French Revolutionary calendar used 1793-11-24 through 1805-12-31, +and (in Paris only) 1871-05-06 through 1871-05-23. + + +Russia + +From Chris Carrier (1996-12-02): +On 1929-10-01 the Soviet Union instituted an "Eternal Calendar" +with 30-day months plus 5 holidays, with a 5-day week. +On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the +Gregorian calendar while retaining the 6-day week; on 1940-06-27 it +reverted to the 7-day week. With the 6-day week the usual days +off were the 6th, 12th, 18th, 24th and 30th of the month. +(Source: Evitiar Zerubavel, _The Seven Day Circle_) + + +Mark Brader reported a similar story in "The Book of Calendars", edited +by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: + +From: Petteri Sulonen (via Usenet) +Date: 14 Jan 1999 00:00:00 GMT +... + +If your source is correct, how come documents between 1929 and 1940 were +still dated using the conventional, Gregorian calendar? + +I can post a scan of a document dated December 1, 1934, signed by +Yenukidze, the secretary, on behalf of Kalinin, the President of the +Executive Committee of the Supreme Soviet, if you like. + + + +Sweden (and Finland) + +From: Mark Brader +Subject: Re: Gregorian reform - a part of locale? + +Date: 1996-07-06 + +In 1700, Denmark made the transition from Julian to Gregorian. Sweden +decided to *start* a transition in 1700 as well, but rather than have one of +those unsightly calendar gaps :-), they simply decreed that the next leap +year after 1696 would be in 1744 - putting the whole country on a calendar +different from both Julian and Gregorian for a period of 40 years. + +However, in 1704 something went wrong and the plan was not carried through; +they did, after all, have a leap year that year. And one in 1708. In 1712 +they gave it up and went back to Julian, putting 30 days in February that +year!... + +Then in 1753, Sweden made the transition to Gregorian in the usual manner, +getting there only 13 years behind the original schedule. + +(A previous posting of this story was challenged, and Swedish readers +produced the following references to support it: "Tideräkning och historia" +by Natanael Beckman (1924) and "Tid, en bok om tideräkning och +kalenderväsen" by Lars-Olof Lodén (1968). + + +Grotefend's data + +From: "Michael Palmer" [with one obvious typo fixed] +Subject: Re: Gregorian Calendar (was Re: Another FHC related question +Newsgroups: soc.genealogy.german +Date: Tue, 9 Feb 1999 02:32:48 -800 +... + +The following is a(n incomplete) listing, arranged chronologically, of +European states, with the date they converted from the Julian to the +Gregorian calendar: + +04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman + Catholics and Danzig only) +09/20 Dec 1582 - France, Lorraine + +21 Dec 1582/ + 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau +10/21 Feb 1583 - bishopric of Liege (Lüttich) +13/24 Feb 1583 - bishopric of Augsburg +04/15 Oct 1583 - electorate of Trier +05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg, + Salzburg, Brixen +13/24 Oct 1583 - Austrian Oberelsaß and Breisgau +20/31 Oct 1583 - bishopric of Basel +02/13 Nov 1583 - duchy of Jülich-Berg +02/13 Nov 1583 - electorate and city of Köln +04/15 Nov 1583 - bishopric of Würzburg +11/22 Nov 1583 - electorate of Mainz +16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden +17/28 Nov 1583 - bishopric of Münster and duchy of Cleve +14/25 Dec 1583 - Steiermark + +06/17 Jan 1584 - Austria and Bohemia +11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn +12/23 Jan 1584 - Silesia and the Lausitz +22 Jan/ + 02 Feb 1584 - Hungary (legally on 21 Oct 1587) + Jun 1584 - Unterwalden +01/12 Jul 1584 - duchy of Westfalen + +16/27 Jun 1585 - bishopric of Paderborn + +14/25 Dec 1590 - Transylvania + +22 Aug/ + 02 Sep 1612 - duchy of Prussia + +13/24 Dec 1614 - Pfalz-Neuburg + + 1617 - duchy of Kurland (reverted to the Julian calendar in + 1796) + + 1624 - bishopric of Osnabrück + + 1630 - bishopric of Minden + +15/26 Mar 1631 - bishopric of Hildesheim + + 1655 - Kanton Wallis + +05/16 Feb 1682 - city of Strassburg + +18 Feb/ + 01 Mar 1700 - Protestant Germany (including Swedish possessions in + Germany), Denmark, Norway +30 Jun/ + 12 Jul 1700 - Gelderland, Zutphen +10 Nov/ + 12 Dec 1700 - Utrecht, Overijssel + +31 Dec 1700/ + 12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva, + Turgau, and Schaffhausen + + 1724 - Glarus, Appenzell, and the city of St. Gallen + +01 Jan 1750 - Pisa and Florence + +02/14 Sep 1752 - Great Britain + +17 Feb/ + 01 Mar 1753 - Sweden + +1760-1812 - Graubünden + +The Russian empire (including Finland and the Baltic states) did not +convert to the Gregorian calendar until the Soviet revolution of 1917. + +Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen +Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend +(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28. + +----- + +This file is in the public domain, so clarified as of 2009-05-17 by +Arthur David Olson. + +----- +Local Variables: +coding: utf-8 +End: diff --git a/contrib/tzdata/checklinks.awk b/contrib/tzdata/checklinks.awk index 5b3e1571d9f4..f30901086536 100644 --- a/contrib/tzdata/checklinks.awk +++ b/contrib/tzdata/checklinks.awk @@ -9,7 +9,7 @@ BEGIN { Zone = "\n" } -/^Zone/ { +/^Z/ { if (defined[$2]) { if (defined[$2] == Zone) { printf "%s: Zone has duplicate definition\n", $2 @@ -21,7 +21,7 @@ BEGIN { defined[$2] = Zone } -/^Link/ { +/^L/ { if (defined[$3]) { if (defined[$3] == Zone) { printf "%s: Link with same name as Zone\n", $3 diff --git a/contrib/tzdata/europe b/contrib/tzdata/europe index 558b9f168f36..5b3b4e52fa44 100644 --- a/contrib/tzdata/europe +++ b/contrib/tzdata/europe @@ -37,14 +37,14 @@ # [PDF] (1914-03) # # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94 -# . He writes: +# . He writes: # "It is requested that corrections and additions to these tables # may be sent to Mr. John Milne, Royal Geographical Society, # Savile Row, London." Nowadays please email them to tz@iana.org. # # Byalokoz EL. New Counting of Time in Russia since July 1, 1919. # This Russian-language source was consulted by Vladimir Karpinsky; see -# http://mm.icann.org/pipermail/tz/2014-August/021320.html +# https://mm.icann.org/pipermail/tz/2014-August/021320.html # The full Russian citation is: # БÑлокоз, Евгений Людвигович. Ðовый Ñчет времени в течении Ñуток # введенный декретом Совета народных комиÑÑаров Ð´Ð»Ñ Ð²Ñей РоÑÑии Ñ 1-го @@ -187,7 +187,7 @@ # foundations of civilization throughout the world. # -- "A Silent Toast to William Willett", Pictorial Weekly; # republished in Finest Hour (Spring 2002) 1(114):26 -# http://www.winstonchurchill.org/images/finesthour/Vol.01%20No.114.pdf +# https://www.winstonchurchill.org/publications/finest-hour/finest-hour-114/a-silent-toast-to-william-willett-by-winston-s-churchill # From Paul Eggert (2015-08-08): # The OED Supplement says that the English originally said "Daylight Saving" @@ -225,8 +225,8 @@ # official designation; the reply of the 21st was that there wasn't # but he couldn't think of anything better than the "Double British # Summer Time" that the BBC had been using informally. -# http://www.polyomino.org.uk/british-time/bbc-19410418.png -# http://www.polyomino.org.uk/british-time/ho-19410421.png +# https://www.polyomino.org.uk/british-time/bbc-19410418.png +# https://www.polyomino.org.uk/british-time/ho-19410421.png # From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21): # [N]o official designation has as far as I know been adopted for the time @@ -243,13 +243,13 @@ # the history of summer time legislation in the United Kingdom. # Since 1998 Joseph S. Myers has been updating # and extending this list, which can be found in -# http://www.polyomino.org.uk/british-time/ +# https://www.polyomino.org.uk/british-time/ # From Joseph S. Myers (1998-01-06): # # The legal time in the UK outside of summer time is definitely GMT, not UTC; # see Lord Tanlaw's speech -# http://www.publications.parliament.uk/pa/ld199798/ldhansrd/vo970611/text/70611-10.htm#70611-10_head0 +# https://www.publications.parliament.uk/pa/ld199798/ldhansrd/vo970611/text/70611-10.htm#70611-10_head0 # (Lords Hansard 11 June 1997 columns 964 to 976). # From Paul Eggert (2006-03-22): @@ -295,7 +295,7 @@ # Irish 'public feeling (was) outraged by forcing of English time on us'." # -- Parsons M. Dublin lost its time zone - and 25 minutes - after 1916 Rising. # Irish Times 2014-10-27. -# http://www.irishtimes.com/news/politics/dublin-lost-its-time-zone-and-25-minutes-after-1916-rising-1.1977411 +# https://www.irishtimes.com/news/politics/dublin-lost-its-time-zone-and-25-minutes-after-1916-rising-1.1977411 # From Joseph S. Myers (2005-01-26): # Irish laws are available online at . @@ -348,6 +348,12 @@ # Justice (tel +353 1 678 9711) who confirmed to me that the correct name is # "Irish Summer Time", abbreviated to "IST". +# Michael Deckers (2017-06-01) gave the following URLs for Ireland's +# Summer Time Act, 1925 and Summer Time Orders, 1926 and 1947: +# http://www.irishstatutebook.ie/eli/1925/act/8/enacted/en/print.html +# http://www.irishstatutebook.ie/eli/1926/sro/919/made/en/print.html +# http://www.irishstatutebook.ie/eli/1947/sro/71/made/en/print.html + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S # Summer Time Act, 1916 Rule GB-Eire 1916 only - May 21 2:00s 1:00 BST @@ -472,14 +478,14 @@ Link Europe/London Europe/Isle_of_Man # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Dublin -0:25:00 - LMT 1880 Aug 2 - -0:25:21 - DMT 1916 May 21 2:00 # Dublin MT + -0:25:21 - DMT 1916 May 21 2:00s # Dublin MT -0:25:21 1:00 IST 1916 Oct 1 2:00s 0:00 GB-Eire %s 1921 Dec 6 # independence - 0:00 GB-Eire GMT/IST 1940 Feb 25 2:00 - 0:00 1:00 IST 1946 Oct 6 2:00 - 0:00 - GMT 1947 Mar 16 2:00 - 0:00 1:00 IST 1947 Nov 2 2:00 - 0:00 - GMT 1948 Apr 18 2:00 + 0:00 GB-Eire GMT/IST 1940 Feb 25 2:00s + 0:00 1:00 IST 1946 Oct 6 2:00s + 0:00 - GMT 1947 Mar 16 2:00s + 0:00 1:00 IST 1947 Nov 2 2:00s + 0:00 - GMT 1948 Apr 18 2:00s 0:00 GB-Eire GMT/IST 1968 Oct 27 1:00 - IST 1971 Oct 31 2:00u 0:00 GB-Eire GMT/IST 1996 @@ -625,7 +631,7 @@ Rule Russia 1996 2010 - Oct lastSun 2:00s 0 - # Council of Ministers of the USSR from 1989-03-14 No. 227. # # I did not find full texts of these acts. For the 1989 one we have -# title at http://base.garant.ru/70754136/ : +# title at https://base.garant.ru/70754136/ : # "About change in calculation of time on the territories of # Lithuanian SSR, Latvian SSR and Estonian SSR, Astrakhan, # Kaliningrad, Kirov, Kuybyshev, Ulyanovsk and Uralsk oblasts". @@ -656,7 +662,7 @@ Rule Russia 1996 2010 - Oct lastSun 2:00s 0 - # http://bmockbe.ru/events/?ID=7583 # # Medvedev signed a law on the calculation of the time (in russian): -# http://www.regnum.ru/news/polit/1413906.html +# https://www.regnum.ru/news/polit/1413906.html # From Arthur David Olson (2011-06-15): # Take "abolishing daylight saving time" to mean that time is now considered @@ -783,7 +789,7 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr # Sources (Russian language): # http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html # http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/ -# http://news.tut.by/society/250578.html +# https://news.tut.by/society/250578.html # # From Alexander Bokovoy (2014-10-09): # Belarussian government decided against changing to winter time.... @@ -1104,7 +1110,7 @@ Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base # for their standard and summer times. He says no, they use "suveaeg" # (summer time) and "talveaeg" (winter time). -# From The Baltic Times (1999-09-09) +# From The Baltic Times (1999-09-09) # via Steffen Thorsen: # This year will mark the last time Estonia shifts to summer time, # a council of the ruling coalition announced Sept. 6.... @@ -1156,7 +1162,7 @@ Zone Europe/Tallinn 1:39:00 - LMT 1880 # This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac # Office of University of Helsinki, ISBN 952-10-3221-9, available online (in # Finnish) at -# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf +# https://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf # # Page 105 (56 in PDF version) has a handy table of all past daylight savings # transitions. It is easy enough to interpret without Finnish skills. @@ -1169,7 +1175,7 @@ Zone Europe/Tallinn 1:39:00 - LMT 1880 # From Konstantin Hyppönen (2014-06-13): # [Heikki Oja's book Aikakirja 2013] -# http://almanakka.helsinki.fi/images/aikakirja/Aikakirja2013kokonaan.pdf +# https://almanakka.helsinki.fi/images/aikakirja/Aikakirja2013kokonaan.pdf # pages 104-105, including a scan from a newspaper published on Apr 2 1942 # say that ... [o]n Apr 2 1942, 24 o'clock (which means Apr 3 1942, # 00:00), clocks were moved one hour forward. The newspaper @@ -1299,7 +1305,7 @@ Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01 # From Jörg Schilling (2002-10-23): # In 1945, Berlin was switched to Moscow Summer time (GMT+4) by -# http://www.dhm.de/lemo/html/biografien/BersarinNikolai/ +# https://www.dhm.de/lemo/html/biografien/BersarinNikolai/ # General [Nikolai] Bersarin. # From Paul Eggert (2003-03-08): @@ -1524,7 +1530,7 @@ Zone Atlantic/Reykjavik -1:28 - LMT 1908 # From Paul Eggert (2016-10-27): # Go with INRiM for DST rules, except as corrected by Inglis for 1944 # for the Kingdom of Italy. This is consistent with Renzo Baldini. -# Model Rome's occupation by using using C-Eur rules from 1943-09-10 +# Model Rome's occupation by using C-Eur rules from 1943-09-10 # to 1944-06-04; although Rome was an open city during this period, it # was effectively controlled by Germany. # @@ -1839,14 +1845,14 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta # Following Moldova and neighboring Ukraine- Transnistria (Pridnestrovie)- # Tiraspol will go back to winter time on October 30, 2011. # News from Moldova (in russian): -# http://ru.publika.md/link_317061.html +# https://ru.publika.md/link_317061.html # From Roman Tudos (2015-07-02): # http://lex.justice.md/index.php?action=view&view=doc&lang=1&id=355077 # From Paul Eggert (2015-07-01): # The abovementioned official link to IGO1445-868/2014 states that # 2014-10-26's fallback transition occurred at 03:00 local time. Also, -# http://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara +# https://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara # says the 2014-03-30 spring-forward transition was at 02:00 local time. # Guess that since 1997 Moldova has switched one hour before the EU. @@ -1918,7 +1924,7 @@ Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 # Amsterdam mean time. # The data entries before 1945 are taken from -# http://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm +# https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time @@ -1999,7 +2005,7 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1 # so it must have diverged from Oslo time during the war, as Oslo was # keeping Berlin time. # -# says that the meteorologists +# says that the meteorologists # burned down their station in 1940 and left the island, but returned in # 1941 with a small Norwegian garrison and continued operations despite # frequent air attacks from Germans. In 1943 the Americans established a @@ -2037,7 +2043,7 @@ Rule Poland 1945 only - Apr 29 0:00 1:00 S Rule Poland 1945 only - Nov 1 0:00 0 - # For 1946 on the source is Kazimierz Borkowski, # ToruÅ„ Center for Astronomy, Dept. of Radio Astronomy, Nicolaus Copernicus U., -# http://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1 +# https://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1 # Thanks to PrzemysÅ‚aw Augustyniak (2005-05-28) for this reference. # He also gives these further references: # Mon Pol nr 13, poz 162 (1995) @@ -2071,7 +2077,7 @@ Zone Europe/Warsaw 1:24:00 - LMT 1880 # # From Paul Eggert (2014-08-11), after a heads-up from Stephen Colebourne: # According to a Portuguese decree (1911-05-26) -# http://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf +# https://dre.pt/application/dir/pdf1sdip/1911/05/12500/23132313.pdf # Lisbon was at -0:36:44.68, but switched to GMT on 1912-01-01 at 00:00. # Round the old offset to -0:36:45. This agrees with Willett but disagrees # with Shanks, who says the transition occurred on 1911-05-24 at 00:00 for @@ -2253,7 +2259,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # 2011 No. 725" and contains no other dates or "effective date" information. # # Another source is -# http://www.rg.ru/2011/09/06/chas-zona-dok.html +# https://rg.ru/2011/09/06/chas-zona-dok.html # which, according to translate.google.com, begins "Resolution of the # Government of the Russian Federation on August 31, 2011 N 725" and also # contains "Date first official publication: September 6, 2011 Posted on: @@ -2261,7 +2267,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # does not contain any "effective date" information. # # Another source is -# http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7 +# https://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7 # which, in note 8, contains "Resolution No. 725 of August 31, 2011... # Effective as of after 7 days following the day of the official publication" # but which does not contain any reference to September 6, 2011. @@ -2297,7 +2303,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # http://itar-tass.com/obschestvo/1333711 # http://www.pravo.gov.ru:8080/page.aspx?111660 # http://www.kremlin.ru/acts/46279 -# From October 26, 2014 the new Russian time zone map will looks like this: +# From October 26, 2014 the new Russian time zone map will look like this: # http://www.worldtimezone.com/dst_news/dst_news_russia-map-2014-07.html # From Paul Eggert (2006-03-22): @@ -2344,7 +2350,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # with maintenance only and represent our best guesses as to which regions # are covered by each zone. They are not meant to be taken as an authoritative # listing. The region codes listed come from -# http://en.wikipedia.org/w/?title=Federal_subjects_of_Russia&oldid=611810498 +# https://en.wikipedia.org/w/?title=Federal_subjects_of_Russia&oldid=611810498 # and are used for convenience only; no guarantees are made regarding their # future stability. ISO 3166-2:RU codes are also listed for first-level # divisions where available. @@ -2509,7 +2515,7 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr # http://www.kaliningradka.ru/site_pc/cherez/index.php?ELEMENT_ID=40091 # says that Kaliningrad decided not to be an exception 2 days before the # 1991-03-31 switch and one person at -# http://izhevsk.ru/forum_light_message/50/682597-m8369040.html +# https://izhevsk.ru/forum_light_message/50/682597-m8369040.html # says he remembers that Samara opted out of the 1992-01-19 exception # 2 days before the switch. # @@ -2581,7 +2587,7 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880 3:00 - MSK 1997 Mar lastSun 1:00u # From Alexander Krivenyshev (2014-03-17): # time change at 2:00 (2am) on March 30, 2014 -# http://vz.ru/news/2014/3/17/677464.html +# https://vz.ru/news/2014/3/17/677464.html # From Paul Eggert (2014-03-30): # Simferopol and Sevastopol reportedly changed their central town clocks # late the previous day, but this appears to have been ceremonial @@ -2764,7 +2770,7 @@ Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14 # suggests that Altai Republic transitioned to Moscow+3 on # 1995-05-28. # -# http://regnum.ru/news/society/1957270.html +# https://regnum.ru/news/society/1957270.html # has some historical data for Altai Krai: # before 1957: west part on UTC+6, east on UTC+7 # after 1957: UTC+7 @@ -3138,8 +3144,8 @@ Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 # districts, but have very similar populations. In fact, Wikipedia currently # lists them both as having 3528 people, exactly 1668 males and 1860 females # each! (Yikes!) -# http://en.wikipedia.org/w/?title=Srednekolymsky_District&oldid=603435276 -# http://en.wikipedia.org/w/?title=Verkhnekolymsky_District&oldid=594378493 +# https://en.wikipedia.org/w/?title=Srednekolymsky_District&oldid=603435276 +# https://en.wikipedia.org/w/?title=Verkhnekolymsky_District&oldid=594378493 # Assume this is a mistake, albeit an amusing one. # # Looking at censuses, the populations of the two municipalities seem to have @@ -3460,7 +3466,7 @@ Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1 # # From Alois Treindl (2013-09-11): # The Federal regulations say -# http://www.admin.ch/opc/de/classified-compilation/20071096/index.html +# https://www.admin.ch/opc/de/classified-compilation/20071096/index.html # ... the meridian for Bern mean time ... is 7 degrees 26' 22.50". # Expressed in time, it is 0h29m45.5s. @@ -3537,9 +3543,9 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment. # According to the articles linked below, Turkey will change into summer # time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27. # This change is due to a nationwide exam on 27th. -# http://www.worldbulletin.net/?aType=haber&ArticleID=70872 +# https://www.worldbulletin.net/?aType=haber&ArticleID=70872 # Turkish: -# http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373 +# https://www.hurriyet.com.tr/yaz-saati-uygulamasi-bir-gun-ileri-alindi-17230464 # From Faruk Pasin (2014-02-14): # The DST for Turkey has been changed for this year because of the @@ -3675,7 +3681,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # http://www.segodnya.ua/news/14290482.html # # Deputies cancelled the winter time (in Russian) -# http://www.pravda.com.ua/rus/news/2011/09/20/6600616/ +# https://www.pravda.com.ua/rus/news/2011/09/20/6600616/ # # From Philip Pizzey (2011-10-18): # Today my Ukrainian colleagues have informed me that the diff --git a/contrib/tzdata/leap-seconds.list b/contrib/tzdata/leap-seconds.list index d0903e7e0ebd..5d5001029667 100644 --- a/contrib/tzdata/leap-seconds.list +++ b/contrib/tzdata/leap-seconds.list @@ -199,10 +199,10 @@ # current -- the update time stamp, the data and the name of the file # will not change. # -# Updated through IERS Bulletin C53 -# File expires on: 28 December 2017 +# Updated through IERS Bulletin C54 +# File expires on: 28 June 2018 # -#@ 3723408000 +#@ 3739132800 # 2272060800 10 # 1 Jan 1972 2287785600 11 # 1 Jul 1972 @@ -247,4 +247,4 @@ # the hash line is also ignored in the # computation. # -#h 62cf8c5d 8bbb6dcc c61e3b56 c308343 869bb80d +#h 5101445a 69948b51 9153e2b 2086e3d8 d54561a3 diff --git a/contrib/tzdata/leapseconds b/contrib/tzdata/leapseconds index 1ebf70fcf61e..a191d5f535a5 100644 --- a/contrib/tzdata/leapseconds +++ b/contrib/tzdata/leapseconds @@ -3,19 +3,18 @@ # This file is in the public domain. # This file is generated automatically from the data in the public-domain -# leap-seconds.list file available from most NIST time servers. -# If the URL does not work, -# you should be able to pick up leap-seconds.list from a secondary NIST server. -# See for a list of secondary servers. +# leap-seconds.list file, which is copied from: +# ftp://ftp.nist.gov/pub/time/leap-seconds.list # For more about leap-seconds.list, please see # The NTP Timescale and Leap Seconds -# http://www.eecis.udel.edu/~mills/leap.html +# https://www.eecis.udel.edu/~mills/leap.html # The International Earth Rotation and Reference Systems Service # periodically uses leap seconds to keep UTC to within 0.9 s of UT1 # (which measures the true angular orientation of the earth in space); see -# Terry J Quinn, The BIPM and the accurate measure of time, -# Proc IEEE 79, 7 (July 1991), 894-905 . +# Levine J. Coordinated Universal Time and the leap second. +# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995 +# http://ieeexplore.ieee.org/document/7909995/ # There were no leap seconds before 1972, because the official mechanism # accounting for the discrepancy between atomic time and the earth's rotation # did not exist until the early 1970s. @@ -58,5 +57,5 @@ Leap 2012 Jun 30 23:59:60 + S Leap 2015 Jun 30 23:59:60 + S Leap 2016 Dec 31 23:59:60 + S -# Updated through IERS Bulletin C53 -# File expires on: 28 December 2017 +# Updated through IERS Bulletin C54 +# File expires on: 28 June 2018 diff --git a/contrib/tzdata/leapseconds.awk b/contrib/tzdata/leapseconds.awk index 21fe540791b5..66eb64d3dcab 100644 --- a/contrib/tzdata/leapseconds.awk +++ b/contrib/tzdata/leapseconds.awk @@ -8,19 +8,18 @@ BEGIN { print "# This file is in the public domain." print "" print "# This file is generated automatically from the data in the public-domain" - print "# leap-seconds.list file available from most NIST time servers." - print "# If the URL does not work," - print "# you should be able to pick up leap-seconds.list from a secondary NIST server." - print "# See for a list of secondary servers." + print "# leap-seconds.list file, which is copied from:" + print "# ftp://ftp.nist.gov/pub/time/leap-seconds.list" print "# For more about leap-seconds.list, please see" print "# The NTP Timescale and Leap Seconds" - print "# http://www.eecis.udel.edu/~mills/leap.html" + print "# https://www.eecis.udel.edu/~mills/leap.html" print "" print "# The International Earth Rotation and Reference Systems Service" print "# periodically uses leap seconds to keep UTC to within 0.9 s of UT1" print "# (which measures the true angular orientation of the earth in space); see" - print "# Terry J Quinn, The BIPM and the accurate measure of time," - print "# Proc IEEE 79, 7 (July 1991), 894-905 ." + print "# Levine J. Coordinated Universal Time and the leap second." + print "# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995" + print "# http://ieeexplore.ieee.org/document/7909995/" print "# There were no leap seconds before 1972, because the official mechanism" print "# accounting for the discrepancy between atomic time and the earth's rotation" print "# did not exist until the early 1970s." diff --git a/contrib/tzdata/northamerica b/contrib/tzdata/northamerica index 6ede9dcd96be..e5d3eca41c25 100644 --- a/contrib/tzdata/northamerica +++ b/contrib/tzdata/northamerica @@ -105,10 +105,13 @@ # Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama. # In the introduction, Oboler spoke of "Eastern Peace Time." # An AltaVista search turned up: -# http://rowayton.org/rhs/hstaug45.html +# https://web.archive.org/web/20000926032210/http://rowayton.org/rhs/hstaug45.html # "When the time is announced over the radio now, it is 'Eastern Peace # Time' instead of the old familiar 'Eastern War Time.' Peace is wonderful." # (August 1945) by way of confirmation. +# +# From Paul Eggert (2017-09-23): +# This was the V-J Day issue of the Clamdigger, a Rowayton, CT newsletter. # From Joseph Gallant citing # George H. Douglas, _The Early Days of Radio Broadcasting_ (1987): @@ -257,7 +260,7 @@ Zone PST8PDT -8:00 US P%sT # HST and HDT are standardized abbreviations for Hawaii-Aleutian # standard and daylight times. See section 9.47 (p 234) of the # U.S. Government Printing Office Style Manual (2008) -# http://www.gpo.gov/fdsys/pkg/GPO-STYLEMANUAL-2008/pdf/GPO-STYLEMANUAL-2008.pdf +# https://www.gpo.gov/fdsys/pkg/GPO-STYLEMANUAL-2008/pdf/GPO-STYLEMANUAL-2008.pdf # From Arthur David Olson, 2005-08-09 # The following was signed into law on 2005-08-08. @@ -346,7 +349,7 @@ Zone America/New_York -4:56:02 - LMT 1883 Nov 18 12:03:58 # western Tennessee, most of Texas, Wisconsin # From Larry M. Smith (2006-04-26) re Wisconsin: -# http://www.legis.state.wi.us/statutes/Stat0175.pdf ... +# https://docs.legis.wisconsin.gov/statutes/statutes/175.pdf # is currently enforced at the 01:00 time of change. Because the local # "bar time" in the state corresponds to 02:00, a number of citations # are issued for the "sale of class 'B' alcohol after prohibited @@ -355,7 +358,7 @@ Zone America/New_York -4:56:02 - LMT 1883 Nov 18 12:03:58 # From Douglas R. Bomberg (2007-03-12): # Wisconsin has enacted (nearly eleventh-hour) legislation to get WI # Statue 175 closer in synch with the US Congress' intent.... -# http://www.legis.state.wi.us/2007/data/acts/07Act3.pdf +# https://docs.legis.wisconsin.gov/2007/related/acts/3 # From an email administrator of the City of Fort Pierre, SD (2015-12-21): # Fort Pierre is technically located in the Mountain time zone as is @@ -402,7 +405,7 @@ Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21 # ...it appears that Mercer County, North Dakota, changed from the # mountain time zone to the central time zone at the last transition from # daylight-saving to standard time (on Nov. 7, 2010): -# http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm +# https://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm # http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html # From Andy Lipscomb (2011-01-24): @@ -453,7 +456,7 @@ Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04 # legal time, and is not part of the data here.) See: # Ross SA. An energy crisis from the past: Northern California in 1948. # Working Paper No. 8, Institute of Governmental Studies, UC Berkeley, -# 1973-11. http://escholarship.org/uc/item/8x22k30c +# 1973-11. https://escholarship.org/uc/item/8x22k30c # # In another measure to save electricity, DST was instituted from 1948-03-14 # at 02:01 to 1949-01-16 at 02:00, with the governor having the option to move @@ -474,8 +477,8 @@ Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04 # which established DST from April's last Sunday at 01:00 until September's # last Sunday at 02:00. This was amended by 1962's Proposition 6, which changed # the fall-back date to October's last Sunday. See: -# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props -# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props +# https://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props +# https://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props # # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER Rule CA 1948 only - Mar 14 2:01 1:00 D @@ -492,20 +495,31 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02 # Alaska # AK%sT is the modern abbreviation for -09 per USNO. # -# From Paul Eggert (2001-05-30): +# From Paul Eggert (2017-06-15): # Howse writes that Alaska switched from the Julian to the Gregorian calendar, # and from east-of-GMT to west-of-GMT days, when the US bought it from Russia. -# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian, -# also a Friday. Include only the time zone part of this transition, -# ignoring the switch from Julian to Gregorian, since we can't represent -# the Julian calendar. +# On Friday, 1867-10-18 (Gregorian), at precisely 15:30 local time, the +# Russian forts and fleet at Sitka fired salutes to mark the ceremony of +# formal transfer. See the Sacramento Daily Union (1867-11-14), p 3, col 2. +# https://cdnc.ucr.edu/cgi-bin/cdnc?a=d&d=SDU18671114.2.12.1 +# Sitka workers did not change their calendars until Sunday, 1867-10-20, +# and so celebrated two Sundays that week. See: Ahllund T (tr Hallamaa P). +# From the memoirs of a Finnish workman. Alaska History. 2006 Fall;21(2):1-25. +# http://alaskahistoricalsociety.org/wp-content/uploads/2016/12/Ahllund-2006-Memoirs-of-a-Finnish-Workman.pdf +# Include only the time zone part of this transition, ignoring the switch +# from Julian to Gregorian, since we can't represent the Julian calendar. # -# As far as we know, none of the exact locations mentioned below were +# As far as we know, of the locations mentioned below only Sitka was # permanently inhabited in 1867 by anyone using either calendar. -# (Yakutat was colonized by the Russians in 1799, but the settlement -# was destroyed in 1805 by a Yakutat-kon war party.) However, there -# were nearby inhabitants in some cases and for our purposes perhaps -# it's best to simply use the official transition. +# (Yakutat was colonized by the Russians in 1799, but the settlement was +# destroyed in 1805 by a Yakutat-kon war party.) Many of Alaska's inhabitants +# were unaware of the US acquisition of Alaska, much less of any calendar or +# time change. However, the Russian-influenced part of Alaska did observe +# Russian time, and it is more accurate to model this than to ignore it. +# The database format requires an exact transition time; use the Russian +# salute as a somewhat-arbitrary time for the formal transfer of control for +# all of Alaska. Sitka's UTC offset is -9:01:13; adjust its 15:30 to the +# local times of other Alaskan locations so that they change simultaneously. # From Paul Eggert (2014-07-18): # One opinion of the early-1980s turmoil in Alaska over time zones and @@ -558,10 +572,10 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02 # It seems Metlakatla did go off PST on Sunday, November 1, changing # their time to AKST and are going to follow Alaska's DST, switching # between AKST and AKDT from now on.... -# http://www.krbd.org/2015/10/30/annette-island-times-they-are-a-changing/ +# https://www.krbd.org/2015/10/30/annette-island-times-they-are-a-changing/ # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone America/Juneau 15:02:19 - LMT 1867 Oct 18 +Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32 -8:57:41 - LMT 1900 Aug 20 12:00 -8:00 - PST 1942 -8:00 US P%sT 1946 @@ -571,7 +585,7 @@ Zone America/Juneau 15:02:19 - LMT 1867 Oct 18 -8:00 US P%sT 1983 Oct 30 2:00 -9:00 US Y%sT 1983 Nov 30 -9:00 US AK%sT -Zone America/Sitka 14:58:47 - LMT 1867 Oct 18 +Zone America/Sitka 14:58:47 - LMT 1867 Oct 19 15:30 -9:01:13 - LMT 1900 Aug 20 12:00 -8:00 - PST 1942 -8:00 US P%sT 1946 @@ -579,7 +593,7 @@ Zone America/Sitka 14:58:47 - LMT 1867 Oct 18 -8:00 US P%sT 1983 Oct 30 2:00 -9:00 US Y%sT 1983 Nov 30 -9:00 US AK%sT -Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 18 +Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 19 15:44:55 -8:46:18 - LMT 1900 Aug 20 12:00 -8:00 - PST 1942 -8:00 US P%sT 1946 @@ -587,14 +601,14 @@ Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 18 -8:00 US P%sT 1983 Oct 30 2:00 -8:00 - PST 2015 Nov 1 2:00 -9:00 US AK%sT -Zone America/Yakutat 14:41:05 - LMT 1867 Oct 18 +Zone America/Yakutat 14:41:05 - LMT 1867 Oct 19 15:12:18 -9:18:55 - LMT 1900 Aug 20 12:00 -9:00 - YST 1942 -9:00 US Y%sT 1946 -9:00 - YST 1969 -9:00 US Y%sT 1983 Nov 30 -9:00 US AK%sT -Zone America/Anchorage 14:00:24 - LMT 1867 Oct 18 +Zone America/Anchorage 14:00:24 - LMT 1867 Oct 19 14:31:37 -9:59:36 - LMT 1900 Aug 20 12:00 -10:00 - AST 1942 -10:00 US A%sT 1967 Apr @@ -602,7 +616,7 @@ Zone America/Anchorage 14:00:24 - LMT 1867 Oct 18 -10:00 US AH%sT 1983 Oct 30 2:00 -9:00 US Y%sT 1983 Nov 30 -9:00 US AK%sT -Zone America/Nome 12:58:21 - LMT 1867 Oct 18 +Zone America/Nome 12:58:22 - LMT 1867 Oct 19 13:29:35 -11:01:38 - LMT 1900 Aug 20 12:00 -11:00 - NST 1942 -11:00 US N%sT 1946 @@ -611,7 +625,7 @@ Zone America/Nome 12:58:21 - LMT 1867 Oct 18 -11:00 US B%sT 1983 Oct 30 2:00 -9:00 US Y%sT 1983 Nov 30 -9:00 US AK%sT -Zone America/Adak 12:13:21 - LMT 1867 Oct 18 +Zone America/Adak 12:13:22 - LMT 1867 Oct 19 12:44:35 -11:46:38 - LMT 1900 Aug 20 12:00 -11:00 - NST 1942 -11:00 US N%sT 1946 @@ -647,7 +661,7 @@ Zone America/Adak 12:13:21 - LMT 1867 Oct 18 # "Hawaiian Time" by Robert C. Schmitt and Doak C. Cox appears on pages 207-225 # of volume 26 of The Hawaiian Journal of History (1992). As of 2010-12-09, # the article is available at -# http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf +# https://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf # and indicates that standard time was adopted effective noon, January # 13, 1896 (page 218), that in "1933, the Legislature decreed daylight # saving for the period between the last Sunday of each April and the @@ -746,7 +760,7 @@ Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11 # Indiana # # For a map of Indiana's time zone regions, see: -# http://en.wikipedia.org/wiki/Time_in_Indiana +# https://en.wikipedia.org/wiki/Time_in_Indiana # # From Paul Eggert (2007-08-17): # Since 1970, most of Indiana has been like America/Indiana/Indianapolis, @@ -973,7 +987,7 @@ Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58 # From Paul Eggert (2001-07-16): # The final rule was published in the # Federal Register 65, 160 (2000-08-17), pp 50154-50158. -# http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=2000_register&docid=fr17au00-22 +# https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm # Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36 -6:00 US C%sT 1946 @@ -999,7 +1013,7 @@ Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36 # West Wendover, NV officially switched from Pacific to mountain time on # 1999-10-31. See the # Federal Register 64, 203 (1999-10-21), pp 56705-56707. -# http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=1999_register&docid=fr21oc99-15 +# https://www.gpo.gov/fdsys/pkg/FR-1999-10-21/html/99-27240.htm # However, the Federal Register says that West Wendover already operated # on mountain time, and the rule merely made this official; # hence a separate tz entry is not needed. @@ -1029,12 +1043,23 @@ Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36 # one hour in 1914." This change is not in Shanks. We have no more # info, so omit this for now. # +# From Paul Eggert (2017-07-26): +# Although Shanks says Detroit observed DST in 1967 from 06-14 00:01 +# until 10-29 00:01, I now see multiple reports that this is incorrect. +# For example, according to a 50-year anniversary report about the 1967 +# Detroit riots and a major-league doubleheader on 1967-07-23, "By the time +# the last fly ball of the doubleheader settled into the glove of leftfielder +# Lenny Green, it was after 7 p.m. Detroit did not observe daylight saving +# time, so light was already starting to fail. Twilight was made even deeper +# by billowing columns of smoke that ascended in an unbroken wall north of the +# ballpark." See: Dow B. Detroit '67: As violence unfolded, Tigers played two +# at home vs. Yankees. Detroit Free Press 2017-07-23. +# https://www.freep.com/story/sports/mlb/tigers/2017/07/23/detroit-tigers-1967-riot-new-york-yankees/499951001/ +# # Most of Michigan observed DST from 1973 on, but was a bit late in 1975. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER Rule Detroit 1948 only - Apr lastSun 2:00 1:00 D Rule Detroit 1948 only - Sep lastSun 2:00 0 S -Rule Detroit 1967 only - Jun 14 2:00 1:00 D -Rule Detroit 1967 only - Oct lastSun 2:00 0 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Detroit -5:32:11 - LMT 1905 -6:00 - CST 1915 May 15 2:00 @@ -1098,7 +1123,7 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # [PDF] (1914-03) # # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94 -# . +# . # # See the 'europe' file for Greenland. @@ -1144,19 +1169,19 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # The British Columbia government announced yesterday that it will # adjust daylight savings next year to align with changes in the # U.S. and the rest of Canada.... -# http://www2.news.gov.bc.ca/news_releases_2005-2009/2006AG0014-000330.htm +# https://archive.news.gov.bc.ca/releases/news_releases_2005-2009/2006AG0014-000330.htm # ... # Nova Scotia # Daylight saving time will be extended by four weeks starting in 2007.... -# http://www.gov.ns.ca/just/regulations/rg2/2006/ma1206.pdf +# https://www.novascotia.ca/just/regulations/rg2/2006/ma1206.pdf # # [For New Brunswick] the new legislation dictates that the time change is to # be done at 02:00 instead of 00:01. -# http://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf +# https://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf # ... # Manitoba has traditionally changed the clock every fall at 03:00. # As of 2006, the transition is to take place one hour earlier at 02:00. -# http://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php +# https://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php # ... # [Alberta, Ontario, Quebec] will follow US rules. # http://www.qp.gov.ab.ca/documents/spring/CH03_06.CFM @@ -1170,7 +1195,7 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # http://www.hoa.gov.nl.ca/hoa/bills/Bill0634.htm # ... # Yukon -# http://www.gov.yk.ca/legislation/regs/oic2006_127.pdf +# https://www.gov.yk.ca/legislation/regs/oic2006_127.pdf # ... # N.W.T. will follow US rules. Whoever maintains the government web site # does not seem to believe in bookmarks. To see the news release, click the @@ -1191,8 +1216,8 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # time and daylight saving time arrangements in Canada circa 1998. # # National Research Council Canada maintains info about time zones and DST. -# http://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html -# http://www.nrc-cnrc.gc.ca/eng/services/time/faq/index.html#Q5 +# https://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html +# https://www.nrc-cnrc.gc.ca/eng/services/time/faq/index.html#Q5 # Its unofficial information is often taken from Matthews and Vincent. # From Paul Eggert (2006-06-27): @@ -1229,11 +1254,13 @@ Rule Canada 2007 max - Nov Sun>=1 2:00 0 S # Newfoundland and Labrador -# From Paul Eggert (2000-10-02): -# Matthews and Vincent (1998) write that Labrador should use NST/NDT, -# but the only part of Labrador that follows the rules is the -# southeast corner, including Port Hope Simpson and Mary's Harbour, -# but excluding, say, Black Tickle. +# From Paul Eggert (2017-10-14): +# Legally Labrador should observe Newfoundland time; see: +# McLeod J. Labrador time - legal or not? St. John's Telegram, 2017-10-07 +# http://www.thetelegram.com/news/local/labrador-time--legal-or-not-154860/ +# Matthews and Vincent (1998) write that the only part of Labrador +# that follows the rules is the southeast corner, including Port Hope +# Simpson and Mary's Harbour, but excluding, say, Black Tickle. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule StJohns 1917 only - Apr 8 2:00 1:00 D @@ -1433,7 +1460,7 @@ Zone America/Moncton -4:19:08 - LMT 1883 Dec 9 # http://www.justice.gouv.qc.ca/english/publications/generale/temps-minganie-a.htm # that the coastal strip from just east of Natashquan to Blanc-Sablon # observes Atlantic standard time all year round. -# http://www.assnat.qc.ca/Media/Process.aspx?MediaId=ANQ.Vigie.Bll.DocumentGenerique_8845en +# https://www.assnat.qc.ca/Media/Process.aspx?MediaId=ANQ.Vigie.Bll.DocumentGenerique_8845en # says this common practice was codified into law as of 2007. # For lack of better info, guess this practice began around 1970, contra to # Shanks & Pottenger who have this region observing AST/ADT. @@ -1465,6 +1492,11 @@ Zone America/Blanc-Sablon -3:48:28 - LMT 1884 # earlier in June). # # Kenora, Ontario, was to abandon DST on 1914-06-01 (-05-21). +# +# From Paul Eggert (2017-07-08): +# For more on Orillia, see: Daubs K. Bold attempt at daylight saving +# time became a comic failure in Orillia. Toronto Star 2017-07-08. +# https://www.thestar.com/news/insight/2017/07/08/bold-attempt-at-daylight-saving-time-became-a-comic-failure-in-orillia.html # From Paul Eggert (1997-10-17): # Mark Brader writes that an article in the 1997-10-14 Toronto Star @@ -1956,7 +1988,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # * 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68, # c. 7 defines Yukon standard time as UTC-9.... # see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1). -# [http://canlii.ca/t/7vhg] +# [https://www.canlii.org/en/ca/laws/stat/rsc-1985-c-i-21/latest/rsc-1985-c-i-21.html] # * C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00. # * O.I.C. 1980/02 established DST. # * O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00. @@ -2021,7 +2053,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # hours behind Greenwich Time. # # * Yukon Standard Time defined as Pacific Standard Time, YCO 1973/214 -# http://www.canlii.org/en/yk/laws/regu/yco-1973-214/latest/yco-1973-214.html +# https://www.canlii.org/en/yk/laws/regu/yco-1973-214/latest/yco-1973-214.html # C.O. 1973/214 INTERPRETATION ACT ... # # 1. Effective October 28, 1973 Commissioner's Order 1967/59 is hereby @@ -2036,7 +2068,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # http://? - no online source found # # * Yukon Daylight Saving Time, YOIC 1987/56 -# http://www.canlii.org/en/yk/laws/regu/yoic-1987-56/latest/yoic-1987-56.html +# https://www.canlii.org/en/yk/laws/regu/yoic-1987-56/latest/yoic-1987-56.html # O.I.C. 1987/056 INTERPRETATION ACT ... # # In every year between @@ -2048,7 +2080,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # Dated ... 9th day of March, A.D., 1987. # # * Yukon Daylight Saving Time 2006, YOIC 2006/127 -# http://www.canlii.org/en/yk/laws/regu/yoic-2006-127/latest/yoic-2006-127.html +# https://www.canlii.org/en/yk/laws/regu/yoic-2006-127/latest/yoic-2006-127.html # O.I.C. 2006/127 INTERPRETATION ACT ... # # 1. In Yukon each year the time for general purposes shall be 7 hours @@ -2062,7 +2094,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # 3. This order comes into force January 1, 2007. # # * Interpretation Act, RSY 2002, c 125 -# http://www.canlii.org/en/yk/laws/stat/rsy-2002-c-125/latest/rsy-2002-c-125.html +# https://www.canlii.org/en/yk/laws/stat/rsy-2002-c-125/latest/rsy-2002-c-125.html # From Rives McDow (1999-09-04): # Nunavut ... moved ... to incorporate the whole territory into one time zone. @@ -2105,7 +2137,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # From Michaela Rodrigue, writing in the # Nunatsiaq News (1999-11-19): -# http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html +# http://www.nunatsiaqonline.ca/archives/nunavut991130/nvt91119_17.html # Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones, # central - or Nunavut time - for government offices, and eastern time # for municipal offices and schools.... Igloolik [was similar but then] @@ -2123,7 +2155,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # Central Time and Southampton Island [in the Central zone] is not # required to use daylight savings. -# From +# From # Nunavut now has two time zones (2000-11-10): # The Nunavut government would allow its employees in Kugluktuk and # Cambridge Bay to operate on central time year-round, putting them @@ -2454,7 +2486,7 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20 # http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html # # Our page: -# http://www.timeanddate.com/news/time/north-mexico-dst-change.html +# https://www.timeanddate.com/news/time/north-mexico-dst-change.html # From Arthur David Olson (2010-01-20): # The page @@ -2873,7 +2905,7 @@ Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José # http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm # # Some more background information is posted here: -# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html +# https://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html # # The article also says that Cuba has been observing DST since 1963, # while Shanks (and tzdata) has 1965 as the first date (except in the @@ -2920,7 +2952,7 @@ Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José # http://granma.co.cu/2011/03/08/nacional/artic01.html # # Our info: -# http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html +# https://www.timeanddate.com/news/time/cuba-starts-dst-2011.html # # From Steffen Thorsen (2011-10-30) # Cuba will end DST two weeks later this year. Instead of going back @@ -2930,7 +2962,7 @@ Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José # http://www.radioangulo.cu/noticias/cuba/17105-cuba-restablecera-el-horario-del-meridiano-de-greenwich.html # # Our page: -# http://www.timeanddate.com/news/time/cuba-time-changes-2011.html +# https://www.timeanddate.com/news/time/cuba-time-changes-2011.html # # From Steffen Thorsen (2012-03-01) # According to Radio Reloj, Cuba will start DST on Midnight between March @@ -2940,7 +2972,7 @@ Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José # http://www.radioreloj.cu/index.php/noticias-radio-reloj/71-miscelaneas/7529-cuba-aplicara-el-horario-de-verano-desde-el-1-de-abril # # Our info on it: -# http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html +# https://www.timeanddate.com/news/time/cuba-starts-dst-2012.html # From Steffen Thorsen (2012-11-03): # Radio Reloj and many other sources report that Cuba is changing back @@ -3135,8 +3167,8 @@ Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5 # From Steffen Thorsen (2016-03-12): # Jean Antoine, editor of www.haiti-reference.com informed us that Haiti # are not going on DST this year. Several other resources confirm this: ... -# http://www.radiotelevisioncaraibes.com/presse/heure_d_t_pas_de_changement_d_heure_pr_vu_pour_cet_ann_e.html -# http://www.vantbefinfo.com/changement-dheure-pas-pour-haiti/ +# https://www.radiotelevisioncaraibes.com/presse/heure_d_t_pas_de_changement_d_heure_pr_vu_pour_cet_ann_e.html +# https://www.vantbefinfo.com/changement-dheure-pas-pour-haiti/ # http://news.anmwe.com/haiti-lheure-nationale-ne-sera-ni-avancee-ni-reculee-cette-annee/ # From Steffen Thorsen (2017-03-12): @@ -3335,7 +3367,7 @@ Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre # Turks and Caicos # # From Chris Dunn in -# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415007 +# https://bugs.debian.org/415007 # (2007-03-15): In the Turks & Caicos Islands (America/Grand_Turk) the # daylight saving dates for time changes have been adjusted to match # the recent U.S. change of dates. @@ -3357,12 +3389,25 @@ Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre # "permanent daylight saving time" by one year.... # http://tcweeklynews.com/time-change-to-go-ahead-this-november-p5437-127.htm # +# From the Turks & Caicos Cabinet (2017-07-20), heads-up from Steffen Thorsen: +# ... agreed to the reintroduction in TCI of Daylight Saving Time (DST) +# during the summer months and Standard Time, also known as Local +# Time, during the winter months with effect from April 2018 ... +# https://www.gov.uk/government/news/turks-and-caicos-post-cabinet-meeting-statement--3 +# +# From Paul Eggert (2017-08-26): +# The date of effect of the spring 2018 change appears to be March 11, +# which makes more sense. See: Hamilton D. Time change back +# by March 2018 for TCI. Magnetic Media. 2017-08-25. +# http://magneticmediatv.com/2017/08/time-change-back-by-march-2018-for-tci/ +# # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Grand_Turk -4:44:32 - LMT 1890 -5:07:11 - KMT 1912 Feb # Kingston Mean Time -5:00 - EST 1979 -5:00 US E%sT 2015 Nov Sun>=1 2:00 - -4:00 - AST + -4:00 - AST 2018 Mar 11 3:00 + -5:00 US E%sT # British Virgin Is # Virgin Is diff --git a/contrib/tzdata/southamerica b/contrib/tzdata/southamerica index 6038c3b65c26..bbae2261560b 100644 --- a/contrib/tzdata/southamerica +++ b/contrib/tzdata/southamerica @@ -22,7 +22,7 @@ # # For data circa 1899, a common source is: # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. -# http://www.jstor.org/stable/1774359 +# https://www.jstor.org/stable/1774359 # # These tables use numeric abbreviations like -03 and -0330 for # integer hour and minute UTC offsets. Although earlier editions used @@ -265,8 +265,8 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S # # Es inminente que en San Luis atrasen una hora los relojes # (It is imminent in San Luis clocks one hour delay) -# http://www.lagaceta.com.ar/nota/253414/Economia/Es-inminente-que-en-San-Luis-atrasen-una-hora-los-relojes.html -# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html +# https://www.lagaceta.com.ar/nota/253414/Economia/Es-inminente-que-en-San-Luis-atrasen-una-hora-los-relojes.html +# http://www.worldtimezone.com/dst_news/dst_news_argentina02.html # From Jesper Nørgaard Welen (2008-01-18): # The page of the San Luis provincial government @@ -385,7 +385,7 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S # Perhaps San Luis operates on the legal fiction that it is at -04 # with perpetual summer time, but ordinary usage typically seems to # just say it's at -03; see, for example, -# http://es.wikipedia.org/wiki/Hora_oficial_argentina +# https://es.wikipedia.org/wiki/Hora_oficial_argentina # We've documented similar situations as being plain changes to # standard time, so let's do that here too. This does not change UTC # offsets, only tm_isdst and the time zone abbreviations. One minor @@ -716,7 +716,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # (Portuguese) # # We have a written a short article about it as well: -# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html +# https://www.timeanddate.com/news/time/brazil-dst-2008-2009.html # # From Alexander Krivenyshev (2011-10-04): # State Bahia will return to Daylight savings time this year after 8 years off. @@ -725,7 +725,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # In Portuguese: # http://g1.globo.com/bahia/noticia/2011/10/governador-jaques-wagner-confirma-horario-de-verao-na-bahia.html -# http://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html +# https://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html # From Guilherme Bernardes Rodrigues (2011-10-07): # There is news in the media, however there is still no decree about it. @@ -751,16 +751,16 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # From Rodrigo Severo (2012-10-16): # Tocantins state will have DST. -# http://noticias.terra.com.br/brasil/noticias/0,,OI6232536-EI306.html +# https://noticias.terra.com.br/brasil/noticias/0,,OI6232536-EI306.html # From Steffen Thorsen (2013-09-20): # Tocantins in Brazil is very likely not to observe DST from October.... # http://conexaoto.com.br/2013/09/18/ministerio-confirma-que-tocantins-esta-fora-do-horario-de-verao-em-2013-mas-falta-publicacao-de-decreto # We will keep this article updated when this is confirmed: -# http://www.timeanddate.com/news/time/brazil-starts-dst-2013.html +# https://www.timeanddate.com/news/time/brazil-starts-dst-2013.html # From Steffen Thorsen (2013-10-17): -# http://www.timeanddate.com/news/time/acre-amazonas-change-time-zone.html +# https://www.timeanddate.com/news/time/acre-amazonas-change-time-zone.html # Senator Jorge Viana announced that Acre will change time zone on November 10. # He did not specify the time of the change, nor if western parts of Amazonas # will change as well. @@ -1076,18 +1076,18 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # the following source, cited by Oscar van Vlijmen (2006-10-08): # [1] Chile Law # http://www.webexhibits.org/daylightsaving/chile.html -# This contains a copy of a this official table: +# This contains a copy of this official table: # Cambios en la hora oficial de Chile desde 1900 (retrieved 2008-03-30) -# http://web.archive.org/web/20080330200901/http://www.horaoficial.cl/cambio.htm +# https://web.archive.org/web/20080330200901/http://www.horaoficial.cl/cambio.htm # [1] needs several corrections, though. # # The first set of corrections is from: # [2] History of the Official Time of Chile # http://www.horaoficial.cl/ing/horaof_ing.html (retrieved 2012-03-06). See: -# http://web.archive.org/web/20120306042032/http://www.horaoficial.cl/ing/horaof_ing.html +# https://web.archive.org/web/20120306042032/http://www.horaoficial.cl/ing/horaof_ing.html # This is an English translation of: # Historia de la hora oficial de Chile (retrieved 2012-10-24). See: -# http://web.archive.org/web/20121024234627/http://www.horaoficial.cl/horaof.htm +# https://web.archive.org/web/20121024234627/http://www.horaoficial.cl/horaof.htm # A fancier Spanish version (requiring mouse-clicking) is at: # http://www.horaoficial.cl/historia_hora.html # Conflicts between [1] and [2] were resolved as follows: @@ -1363,10 +1363,10 @@ Link America/Curacao America/Kralendijk # Caribbean Netherlands # Milne says the Central and South American Telegraph Company used -5:24:15. # # From Alois Treindl (2016-12-15): -# http://www.elcomercio.com/actualidad/hora-sixto-1993.html +# https://www.elcomercio.com/actualidad/hora-sixto-1993.html # ... Whether the law applied also to Galápagos, I do not know. # From Paul Eggert (2016-12-15): -# http://www.elcomercio.com/afull/modificacion-husohorario-ecuador-presidentes-decreto.html +# https://www.elcomercio.com/afull/modificacion-husohorario-ecuador-presidentes-decreto.html # This says President Sixto Durán Ballén signed decree No. 285, which # established DST from 1992-11-28 to 1993-02-05; it does not give transition # times. The people called it "hora de Sixto" ("Sixto hour"). The change did @@ -1778,7 +1778,7 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # hours of presidential broadcasts, hours of lines,' quipped comedian # Jean Mary Curró ...". See: Cawthorne A, Kai D. Venezuela scraps # half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400 -# http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE +# https://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE # # From Matt Johnson (2016-04-20): # ... published in the official Gazette [2016-04-18], here: diff --git a/contrib/tzdata/theory.html b/contrib/tzdata/theory.html new file mode 100644 index 000000000000..965135d7e541 --- /dev/null +++ b/contrib/tzdata/theory.html @@ -0,0 +1,1034 @@ + + + + Theory and pragmatics of the tz code and data + + + + + + +

Theory and pragmatics of the tz code and data

+

Outline

+ + + +
+

Scope of the tz database

+

+The tz database attempts to record the history and predicted future of +all computer-based clocks that track civil time. To represent this +data, the world is partitioned into regions whose clocks all agree +about timestamps that occur after the somewhat-arbitrary cutoff point +of the POSIX Epoch (1970-01-01 00:00:00 UTC). For each such region, +the database records all known clock transitions, and labels the region +with a notable location. Although 1970 is a somewhat-arbitrary +cutoff, there are significant challenges to moving the cutoff earlier +even by a decade or two, due to the wide variety of local practices +before computer timekeeping became prevalent. +

+ +

+Clock transitions before 1970 are recorded for each such location, +because most systems support timestamps before 1970 and could +misbehave if data entries were omitted for pre-1970 transitions. +However, the database is not designed for and does not suffice for +applications requiring accurate handling of all past times everywhere, +as it would take far too much effort and guesswork to record all +details of pre-1970 civil timekeeping. +

+ +

+As described below, reference source code for using the tz database is +also available. The tz code is upwards compatible with POSIX, an +international standard for UNIX-like systems. As of this writing, the +current edition of POSIX is: + + The Open Group Base Specifications Issue 7, + IEEE Std 1003.1-2008, 2016 Edition. +

+
+ + + +
+

Names of time zone rules

+

+Each of the database's time zone rules has a unique name. +Inexperienced users are not expected to select these names unaided. +Distributors should provide documentation and/or a simple selection +interface that explains the names; for one example, see the 'tzselect' +program in the tz code. The +Unicode Common Locale Data +Repository contains data that may be useful for other +selection interfaces. +

+ +

+The time zone rule naming conventions attempt to strike a balance +among the following goals: +

+
    +
  • + Uniquely identify every region where clocks have agreed since 1970. + This is essential for the intended use: static clocks keeping local + civil time. +
  • +
  • + Indicate to experts where that region is. +
  • +
  • + Be robust in the presence of political changes. For example, names + of countries are ordinarily not used, to avoid incompatibilities + when countries change their name (e.g. Zaire→Congo) or when + locations change countries (e.g. Hong Kong from UK colony to + China). +
  • +
  • + Be portable to a wide variety of implementations. +
  • +
  • + Use a consistent naming conventions over the entire world. +
  • +
+

+Names normally have the +form AREA/LOCATION, +where AREA is the name of a continent or ocean, +and LOCATION is the name of a specific +location within that region. North and South America share the same +area, 'America'. Typical names are +'Africa/Cairo', 'America/New_York', and +'Pacific/Honolulu'. +

+ +

+Here are the general rules used for choosing location names, +in decreasing order of importance: +

+
    +
  • + Use only valid POSIX file name components (i.e., the parts of + names other than '/'). Do not use the file name + components '.' and '..'. + Within a file name component, + use only ASCII letters, '.', + '-' and '_'. Do not use + digits, as that might create an ambiguity with POSIX + TZ strings. A file name component must not exceed 14 + characters or start with '-'. E.g., + prefer 'Brunei' to + 'Bandar_Seri_Begawan'. Exceptions: see + the discussion + of legacy names below. +
  • +
  • + A name must not be empty, or contain '//', or + start or end with '/'. +
  • +
  • + Do not use names that differ only in case. Although the reference + implementation is case-sensitive, some other implementations + are not, and they would mishandle names differing only in case. +
  • +
  • + If one name A is an initial prefix of another + name AB (ignoring case), then B + must not start with '/', as a + regular file cannot have + the same name as a directory in POSIX. For example, + 'America/New_York' precludes + 'America/New_York/Bronx'. +
  • +
  • + Uninhabited regions like the North Pole and Bouvet Island + do not need locations, since local time is not defined there. +
  • +
  • + There should typically be at least one name for each ISO 3166-1 + officially assigned two-letter code for an inhabited country + or territory. +
  • +
  • + If all the clocks in a region have agreed since 1970, + don't bother to include more than one location + even if subregions' clocks disagreed before 1970. + Otherwise these tables would become annoyingly large. +
  • +
  • + If a name is ambiguous, use a less ambiguous alternative; + e.g. many cities are named San José and Georgetown, so + prefer 'Costa_Rica' to 'San_Jose' and 'Guyana' to 'Georgetown'. +
  • +
  • + Keep locations compact. Use cities or small islands, not countries + or regions, so that any future time zone changes do not split + locations into different time zones. E.g. prefer + 'Paris' to 'France', since + France has had multiple time zones. +
  • +
  • + Use mainstream English spelling, e.g. prefer + 'Rome' to 'Roma', and prefer + 'Athens' to the Greek + 'Αθήνα' or the Romanized + 'Athína'. + The POSIX file name restrictions encourage this rule. +
  • +
  • + Use the most populous among locations in a zone, + e.g. prefer 'Shanghai' to + 'Beijing'. Among locations with + similar populations, pick the best-known location, + e.g. prefer 'Rome' to 'Milan'. +
  • +
  • + Use the singular form, e.g. prefer 'Canary' to 'Canaries'. +
  • +
  • + Omit common suffixes like '_Islands' and + '_City', unless that would lead to + ambiguity. E.g. prefer 'Cayman' to + 'Cayman_Islands' and + 'Guatemala' to + 'Guatemala_City', but prefer + 'Mexico_City' to 'Mexico' + because the country + of Mexico has several time zones. +
  • +
  • + Use '_' to represent a space. +
  • +
  • + Omit '.' from abbreviations in names, e.g. prefer + 'St_Helena' to 'St._Helena'. +
  • +
  • + Do not change established names if they only marginally + violate the above rules. For example, don't change + the existing name 'Rome' to + 'Milan' merely because + Milan's population has grown to be somewhat greater + than Rome's. +
  • +
  • + If a name is changed, put its old spelling in the + 'backward' file. + This means old spellings will continue to work. +
  • +
+ +

+The file 'zone1970.tab' lists geographical locations used +to name time +zone rules. It is intended to be an exhaustive list of names for +geographic regions as described above; this is a subset of the names +in the data. Although a 'zone1970.tab' location's longitude +corresponds to its LMT offset with one hour for every 15 degrees east +longitude, this relationship is not exact. +

+ +

+Older versions of this package used a different naming scheme, +and these older names are still supported. +See the file 'backward' for most of these older names +(e.g., 'US/Eastern' instead of 'America/New_York'). +The other old-fashioned names still supported are +'WET', 'CET', 'MET', and 'EET' (see the file 'europe'). +

+ +

+Older versions of this package defined legacy names that are +incompatible with the first rule of location names, but which are +still supported. These legacy names are mostly defined in the file +'etcetera'. Also, the file 'backward' defines the legacy names +'GMT0', 'GMT-0' and 'GMT+0', and the file 'northamerica' defines the +legacy names 'EST5EDT', 'CST6CDT', 'MST7MDT', and 'PST8PDT'. +

+ +

+Excluding 'backward' should not affect the other data. If +'backward' is excluded, excluding 'etcetera' should not affect the +remaining data. +

+ + +
+
+

Time zone abbreviations

+

+When this package is installed, it generates time zone abbreviations +like 'EST' to be compatible with human tradition and POSIX. +Here are the general rules used for choosing time zone abbreviations, +in decreasing order of importance: +

    +
  • + Use three or more characters that are ASCII alphanumerics or + '+' or '-'. + Previous editions of this database also used characters like + ' ' and '?', but these + characters have a special meaning to + the shell and cause commands like + 'set `date`' + to have unexpected effects. + Previous editions of this rule required upper-case letters, + but the Congressman who introduced Chamorro Standard Time + preferred "ChST", so lower-case letters are now allowed. + Also, POSIX from 2001 on relaxed the rule to allow + '-', '+', + and alphanumeric characters from the portable character set + in the current locale. In practice ASCII alphanumerics and + '+' and '-' are safe in all locales. + + In other words, in the C locale the POSIX extended regular + expression [-+[:alnum:]]{3,} should match + the abbreviation. + This guarantees that all abbreviations could have been + specified by a POSIX TZ string. +
  • +
  • + Use abbreviations that are in common use among English-speakers, + e.g. 'EST' for Eastern Standard Time in North America. + We assume that applications translate them to other languages + as part of the normal localization process; for example, + a French application might translate 'EST' to 'HNE'. +
  • +
  • + For zones whose times are taken from a city's longitude, use the + traditional xMT notation, e.g. 'PMT' for + Paris Mean Time. + The only name like this in current use is 'GMT'. +
  • +
  • + Use 'LMT' for local mean time of locations before the introduction + of standard time; see "Scope of the + tz database". +
  • +
  • + If there is no common English abbreviation, use numeric offsets like + -05 and +0830 that are + generated by zic's %z notation. +
  • +
  • + Use current abbreviations for older timestamps to avoid confusion. + For example, in 1910 a common English abbreviation for UT +01 + in central Europe was 'MEZ' (short for both "Middle European + Zone" and for "Mitteleuropäische Zeit" in German). Nowadays + 'CET' ("Central European Time") is more common in English, and + the database uses 'CET' even for circa-1910 timestamps as this + is less confusing for modern users and avoids the need for + determining when 'CET' supplanted 'MEZ' in common usage. +
  • +
  • + Use a consistent style in a zone's history. For example, if a zone's + history tends to use numeric abbreviations and a particular + entry could go either way, use a numeric abbreviation. +
  • +
+ [The remaining guidelines predate the introduction of %z. + They are problematic as they mean tz data entries invent + notation rather than record it. These guidelines are now + deprecated and the plan is to gradually move to %z for + inhabited locations and to "-00" for uninhabited locations.] +
    +
  • + If there is no common English abbreviation, abbreviate the English + translation of the usual phrase used by native speakers. + If this is not available or is a phrase mentioning the country + (e.g. "Cape Verde Time"), then: +
      +
    • + When a country is identified with a single or principal zone, + append 'T' to the country's ISO code, e.g. 'CVT' for + Cape Verde Time. For summer time append 'ST'; + for double summer time append 'DST'; etc. +
    • +
    • + Otherwise, take the first three letters of an English place + name identifying each zone and append 'T', 'ST', etc. + as before; e.g. 'CHAST' for CHAtham Summer Time. +
    • +
    +
  • +
  • + Use UT (with time zone abbreviation '-00') for + locations while uninhabited. The leading + '-' is a flag that the time + zone is in some sense undefined; this notation is + derived from Internet RFC 3339. +
  • +
+

+Application writers should note that these abbreviations are ambiguous +in practice: e.g. 'CST' has a different meaning in China than +it does in the United States. In new applications, it's often better +to use numeric UT offsets like '-0600' instead of time zone +abbreviations like 'CST'; this avoids the ambiguity. +

+
+ + +
+

Accuracy of the tz database

+

+The tz database is not authoritative, and it surely has errors. +Corrections are welcome and encouraged; see the file CONTRIBUTING. +Users requiring authoritative data should consult national standards +bodies and the references cited in the database's comments. +

+ +

+Errors in the tz database arise from many sources: +

+
    +
  • + The tz database predicts future timestamps, and current predictions + will be incorrect after future governments change the rules. + For example, if today someone schedules a meeting for 13:00 next + October 1, Casablanca time, and tomorrow Morocco changes its + daylight saving rules, software can mess up after the rule change + if it blithely relies on conversions made before the change. +
  • +
  • + The pre-1970 entries in this database cover only a tiny sliver of how + clocks actually behaved; the vast majority of the necessary + information was lost or never recorded. Thousands more zones would + be needed if the tz database's scope were extended to cover even + just the known or guessed history of standard time; for example, + the current single entry for France would need to split into dozens + of entries, perhaps hundreds. And in most of the world even this + approach would be misleading due to widespread disagreement or + indifference about what times should be observed. In her 2015 book + The Global Transformation of Time, 1870-1950, Vanessa Ogle writes + "Outside of Europe and North America there was no system of time + zones at all, often not even a stable landscape of mean times, + prior to the middle decades of the twentieth century". See: + Timothy Shenk, Booked: + A Global History of Time. Dissent 2015-12-17. +
  • +
  • + Most of the pre-1970 data entries come from unreliable sources, often + astrology books that lack citations and whose compilers evidently + invented entries when the true facts were unknown, without + reporting which entries were known and which were invented. + These books often contradict each other or give implausible entries, + and on the rare occasions when they are checked they are + typically found to be incorrect. +
  • +
  • + For the UK the tz database relies on years of first-class work done by + Joseph Myers and others; see + "History of + legal time in Britain". + Other countries are not done nearly as well. +
  • +
  • + Sometimes, different people in the same city would maintain clocks + that differed significantly. Railway time was used by railroad + companies (which did not always agree with each other), + church-clock time was used for birth certificates, etc. + Often this was merely common practice, but sometimes it was set by law. + For example, from 1891 to 1911 the UT offset in France was legally + 0:09:21 outside train stations and 0:04:21 inside. +
  • +
  • + Although a named location in the tz database stands for the + containing region, its pre-1970 data entries are often accurate for + only a small subset of that region. For example, Europe/London + stands for the United Kingdom, but its pre-1847 times are valid + only for locations that have London's exact meridian, and its 1847 + transition to GMT is known to be valid only for the L&NW and the + Caledonian railways. +
  • +
  • + The tz database does not record the earliest time for which a zone's + data entries are thereafter valid for every location in the region. + For example, Europe/London is valid for all locations in its + region after GMT was made the standard time, but the date of + standardization (1880-08-02) is not in the tz database, other than + in commentary. For many zones the earliest time of validity is + unknown. +
  • +
  • + The tz database does not record a region's boundaries, and in many + cases the boundaries are not known. For example, the zone + America/Kentucky/Louisville represents a region around + the city of + Louisville, the boundaries of which are unclear. +
  • +
  • + Changes that are modeled as instantaneous transitions in the tz + database were often spread out over hours, days, or even decades. +
  • +
  • + Even if the time is specified by law, locations sometimes + deliberately flout the law. +
  • +
  • + Early timekeeping practices, even assuming perfect clocks, were + often not specified to the accuracy that the tz database requires. +
  • +
  • + Sometimes historical timekeeping was specified more precisely + than what the tz database can handle. For example, from 1909 to + 1937 Netherlands clocks were legally UT +00:19:32.13, but the tz + database cannot represent the fractional second. +
  • +
  • + Even when all the timestamp transitions recorded by the tz database + are correct, the tz rules that generate them may not faithfully + reflect the historical rules. For example, from 1922 until World + War II the UK moved clocks forward the day following the third + Saturday in April unless that was Easter, in which case it moved + clocks forward the previous Sunday. Because the tz database has no + way to specify Easter, these exceptional years are entered as + separate tz Rule lines, even though the legal rules did not change. +
  • +
  • + The tz database models pre-standard time using the proleptic Gregorian + calendar and local mean time (LMT), but many people used other + calendars and other timescales. For example, the Roman Empire used + the Julian calendar, and had 12 varying-length daytime hours with a + non-hour-based system at night. +
  • +
  • + Early clocks were less reliable, and data entries do not represent + clock error. +
  • +
  • + The tz database assumes Universal Time (UT) as an origin, even + though UT is not standardized for older timestamps. In the tz + database commentary, UT denotes a family of time standards that + includes Coordinated Universal Time (UTC) along with other variants + such as UT1 and GMT, with days starting at midnight. Although UT + equals UTC for modern timestamps, UTC was not defined until 1960, + so commentary uses the more-general abbreviation UT for timestamps + that might predate 1960. Since UT, UT1, etc. disagree slightly, + and since pre-1972 UTC seconds varied in length, interpretation of + older timestamps can be problematic when subsecond accuracy is + needed. +
  • +
  • + Civil time was not based on atomic time before 1972, and we don't + know the history of earth's rotation accurately enough to map SI + seconds to historical solar time to more than about one-hour + accuracy. See: Stephenson FR, Morrison LV, Hohenkerk CY. + Measurement + of the Earth's rotation: 720 BC to AD 2015. + Proc Royal Soc A. 2016 Dec 7;472:20160404. + Also see: Espenak F. Uncertainty + in Delta T (ΔT). +
  • +
  • + The relationship between POSIX time (that is, UTC but ignoring leap + seconds) and UTC is not agreed upon after 1972. Although the POSIX + clock officially stops during an inserted leap second, at least one + proposed standard has it jumping back a second instead; and in + practice POSIX clocks more typically either progress glacially during + a leap second, or are slightly slowed while near a leap second. +
  • +
  • + The tz database does not represent how uncertain its information is. + Ideally it would contain information about when data entries are + incomplete or dicey. Partial temporal knowledge is a field of + active research, though, and it's not clear how to apply it here. +
  • +
+

+In short, many, perhaps most, of the tz database's pre-1970 and future +timestamps are either wrong or misleading. Any attempt to pass the +tz database off as the definition of time should be unacceptable to +anybody who cares about the facts. In particular, the tz database's +LMT offsets should not be considered meaningful, and should not prompt +creation of zones merely because two locations differ in LMT or +transitioned to standard time at different dates. +

+
+ + +
+

Time and date functions

+

+The tz code contains time and date functions that are upwards +compatible with those of POSIX. +

+ +

+POSIX has the following properties and limitations. +

+
    +
  • +

    + In POSIX, time display in a process is controlled by the + environment variable TZ. Unfortunately, the POSIX TZ string takes + a form that is hard to describe and is error-prone in practice. + Also, POSIX TZ strings can't deal with other (for example, Israeli) + daylight saving time rules, or situations where more than two + time zone abbreviations are used in an area. +

    +

    + The POSIX TZ string takes the following form: +

    +

    + stdoffset[dst[offset][,date[/time],date[/time]]] +

    +

    + where: +

    +
    std and dst
    + are 3 or more characters specifying the standard + and daylight saving time (DST) zone names. + Starting with POSIX.1-2001, std + and dst may also be + in a quoted form like '<UTC+10>'; this allows + "+" and "-" in the names. +
    +
    offset
    + is of the form + '[±]hh:[mm[:ss]]' + and specifies the offset west of UT. 'hh' + may be a single digit; 0≤hh≤24. + The default DST offset is one hour ahead of standard time. +
    +
    date[/time],date[/time]
    + specifies the beginning and end of DST. If this is absent, + the system supplies its own rules for DST, and these can + differ from year to year; typically US DST rules are used. +
    +
    time
    + takes the form + 'hh:[mm[:ss]]' + and defaults to 02:00. + This is the same format as the offset, except that a + leading '+' or '-' is not allowed. +
    +
    date
    + takes one of the following forms: +
    +
    Jn (1≤n≤365)
    + origin-1 day number not counting February 29 +
    +
    n (0≤n≤365)
    + origin-0 day number counting February 29 if present +
    +
    Mm.n.d (0[Sunday]≤d≤6[Saturday], 1≤n≤5, 1≤m≤12)
    + for the dth day of + week n of month m of the + year, where week 1 is the first week in which + day d appears, and '5' + stands for the last week in which + day d appears + (which may be either the 4th or 5th week). + Typically, this is the only useful form; + the n + and Jn forms are + rarely used. +
    +
    +
    +
    + Here is an example POSIX TZ string for New Zealand after 2007. + It says that standard time (NZST) is 12 hours ahead of UTC, + and that daylight saving time (NZDT) is observed from September's + last Sunday at 02:00 until April's first Sunday at 03:00: + +
    TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'
    + + This POSIX TZ string is hard to remember, and mishandles some + timestamps before 2008. With this package you can use this + instead: + +
    TZ='Pacific/Auckland'
    +
  • +
  • + POSIX does not define the exact meaning of TZ values like + "EST5EDT". + Typically the current US DST rules are used to interpret such values, + but this means that the US DST rules are compiled into each program + that does time conversion. This means that when US time conversion + rules change (as in the United States in 1987), all programs that + do time conversion must be recompiled to ensure proper results. +
  • +
  • + The TZ environment variable is process-global, which makes it hard + to write efficient, thread-safe applications that need access + to multiple time zones. +
  • +
  • + In POSIX, there's no tamper-proof way for a process to learn the + system's best idea of local wall clock. (This is important for + applications that an administrator wants used only at certain + times – + without regard to whether the user has fiddled the TZ environment + variable. While an administrator can "do everything in UTC" to get + around the problem, doing so is inconvenient and precludes handling + daylight saving time shifts - as might be required to limit phone + calls to off-peak hours.) +
  • +
  • + POSIX provides no convenient and efficient way to determine the UT + offset and time zone abbreviation of arbitrary timestamps, + particularly for time zone settings that do not fit into the + POSIX model. +
  • +
  • + POSIX requires that systems ignore leap seconds. +
  • +
  • + The tz code attempts to support all the time_t + implementations allowed by POSIX. The time_t + type represents a nonnegative count of + seconds since 1970-01-01 00:00:00 UTC, ignoring leap seconds. + In practice, time_t is usually a signed 64- or + 32-bit integer; 32-bit signed time_t values stop + working after 2038-01-19 03:14:07 UTC, so + new implementations these days typically use a signed 64-bit integer. + Unsigned 32-bit integers are used on one or two platforms, + and 36-bit and 40-bit integers are also used occasionally. + Although earlier POSIX versions allowed time_t to be a + floating-point type, this was not supported by any practical + systems, and POSIX.1-2013 and the tz code both + require time_t + to be an integer type. +
  • +
+

+These are the extensions that have been made to the POSIX functions: +

+
    +
  • +

    + The TZ environment variable is used in generating the name of a file + from which time zone information is read (or is interpreted a la + POSIX); TZ is no longer constrained to be a three-letter time zone + name followed by a number of hours and an optional three-letter + daylight time zone name. The daylight saving time rules to be used + for a particular time zone are encoded in the time zone file; + the format of the file allows U.S., Australian, and other rules to be + encoded, and allows for situations where more than two time zone + abbreviations are used. +

    +

    + It was recognized that allowing the TZ environment variable to + take on values such as 'America/New_York' might + cause "old" programs + (that expect TZ to have a certain form) to operate incorrectly; + consideration was given to using some other environment variable + (for example, TIMEZONE) to hold the string used to generate the + time zone information file name. In the end, however, it was decided + to continue using TZ: it is widely used for time zone purposes; + separately maintaining both TZ and TIMEZONE seemed a nuisance; + and systems where "new" forms of TZ might cause problems can simply + use TZ values such as "EST5EDT" which can be used both by + "new" programs (a la POSIX) and "old" programs (as zone names and + offsets). +

    +
  • +
  • + The code supports platforms with a UT offset member + in struct tm, + e.g., tm_gmtoff. +
  • +
  • + The code supports platforms with a time zone abbreviation member in + struct tm, e.g., tm_zone. +
  • +
  • + Since the TZ environment variable can now be used to control time + conversion, the daylight + and timezone variables are no longer needed. + (These variables are defined and set by tzset; + however, their values will not be used + by localtime.) +
  • +
  • + Functions tzalloc, tzfree, + localtime_rz, and mktime_z for + more-efficient thread-safe applications that need to use + multiple time zones. The tzalloc + and tzfree functions allocate and free objects of + type timezone_t, and localtime_rz + and mktime_z are like localtime_r + and mktime with an extra + timezone_t argument. The functions were inspired + by NetBSD. +
  • +
  • + A function tzsetwall has been added to arrange + for the system's + best approximation to local wall clock time to be delivered by + subsequent calls to localtime. Source code for portable + applications that "must" run on local wall clock time should call + tzsetwall; if such code is moved to "old" systems that don't + provide tzsetwall, you won't be able to generate an executable program. + (These time zone functions also arrange for local wall clock time to be + used if tzset is called – directly or indirectly – + and there's no TZ + environment variable; portable applications should not, however, rely + on this behavior since it's not the way SVR2 systems behave.) +
  • +
  • + Negative time_t values are supported, on systems + where time_t is signed. +
  • +
  • + These functions can account for leap seconds, thanks to Bradley White. +
  • +
+

+Points of interest to folks with other systems: +

+
    +
  • + Code compatible with this package is already part of many platforms, + including GNU/Linux, Android, the BSDs, Chromium OS, Cygwin, AIX, iOS, + BlackBery 10, macOS, Microsoft Windows, OpenVMS, and Solaris. + On such hosts, the primary use of this package + is to update obsolete time zone rule tables. + To do this, you may need to compile the time zone compiler + 'zic' supplied with this package instead of using + the system 'zic', since the format + of zic's input is occasionally extended, and a + platform may still be shipping an older zic. +
  • +
  • + The UNIX Version 7 timezone function is not + present in this package; + it's impossible to reliably map timezone's arguments (a "minutes west + of GMT" value and a "daylight saving time in effect" flag) to a + time zone abbreviation, and we refuse to guess. + Programs that in the past used the timezone function may now examine + localtime(&clock)->tm_zone + (if TM_ZONE is defined) or + tzname[localtime(&clock)->tm_isdst] + (if HAVE_TZNAME is defined) + to learn the correct time zone abbreviation to use. +
  • +
  • + The 4.2BSD gettimeofday function is not used in + this package. + This formerly let users obtain the current UTC offset and DST flag, + but this functionality was removed in later versions of BSD. +
  • +
  • + In SVR2, time conversion fails for near-minimum or near-maximum + time_t values when doing conversions for places + that don't use UT. + This package takes care to do these conversions correctly. + A comment in the source code tells how to get compatibly wrong + results. +
  • +
+

+The functions that are conditionally compiled +if STD_INSPIRED is defined +should, at this point, be looked on primarily as food for thought. They are +not in any sense "standard compatible" – some are not, in fact, +specified in any standard. They do, however, represent responses of +various authors to +standardization proposals. +

+ +

+Other time conversion proposals, in particular the one developed by folks at +Hewlett Packard, offer a wider selection of functions that provide capabilities +beyond those provided here. The absence of such functions from this package +is not meant to discourage the development, standardization, or use of such +functions. Rather, their absence reflects the decision to make this package +contain valid extensions to POSIX, to ensure its broad acceptability. If +more powerful time conversion functions can be standardized, so much the +better. +

+
+ + +
+

Interface stability

+

+The tz code and data supply the following interfaces: +

+
    +
  • + A set of zone names as per "Names of time zone + rules" above. +
  • +
  • + Library functions described in "Time and date + functions" above. +
  • +
  • + The programs tzselect, zdump, + and zic, documented in their man pages. +
  • +
  • + The format of zic input files, documented in + the zic man page. +
  • +
  • + The format of zic output files, documented in + the tzfile man page. +
  • +
  • + The format of zone table files, documented in zone1970.tab. +
  • +
  • + The format of the country code file, documented in iso3166.tab. +
  • +
  • + The version number of the code and data, as the first line of + the text file 'version' in each release. +
  • +
+

+Interface changes in a release attempt to preserve compatibility with +recent releases. For example, tz data files typically do not rely on +recently-added zic features, so that users can run +older zic versions to process newer data +files. Sources for time zone and daylight +saving time data describes how +releases are tagged and distributed. +

+ +

+Interfaces not listed above are less stable. For example, users +should not rely on particular UT offsets or abbreviations for +timestamps, as data entries are often based on guesswork and these +guesses may be corrected or improved. +

+
+ + +
+

Calendrical issues

+

+Calendrical issues are a bit out of scope for a time zone database, +but they indicate the sort of problems that we would run into if we +extended the time zone database further into the past. An excellent +resource in this area is Nachum Dershowitz and Edward M. Reingold, +Calendrical +Calculations: Third Edition, Cambridge University Press (2008). +Other information and sources are given in the file 'calendars' +in the tz distribution. They sometimes disagree. +

+
+ + +
+

Time and time zones on other planets

+

+Some people's work schedules use Mars time. Jet Propulsion Laboratory +(JPL) coordinators have kept Mars time on and off at least since 1997 +for the Mars Pathfinder mission. Some of their family members have +also adapted to Mars time. Dozens of special Mars watches were built +for JPL workers who kept Mars time during the Mars Exploration +Rovers mission (2004). These timepieces look like normal Seikos and +Citizens but use Mars seconds rather than terrestrial seconds. +

+ +

+A Mars solar day is called a "sol" and has a mean period equal to +about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is +divided into a conventional 24-hour clock, so each Mars second equals +about 1.02749125 terrestrial seconds. +

+ +

+The prime meridian of Mars goes through the center of the crater +Airy-0, named in honor of the British astronomer who built the +Greenwich telescope that defines Earth's prime meridian. Mean solar +time on the Mars prime meridian is called Mars Coordinated Time (MTC). +

+ +

+Each landed mission on Mars has adopted a different reference for +solar time keeping, so there is no real standard for Mars time zones. +For example, the Mars Exploration Rover project (2004) defined two +time zones "Local Solar Time A" and "Local Solar Time B" for its two +missions, each zone designed so that its time equals local true solar +time at approximately the middle of the nominal mission. Such a "time +zone" is not particularly suited for any application other than the +mission itself. +

+ +

+Many calendars have been proposed for Mars, but none have achieved +wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a +sequential count of Mars solar days elapsed since about 1873-12-29 +12:00 GMT. +

+ +

+In our solar system, Mars is the planet with time and calendar most +like Earth's. On other planets, Sun-based time and calendars would +work quite differently. For example, although Mercury's sidereal +rotation period is 58.646 Earth days, Mercury revolves around the Sun +so rapidly that an observer on Mercury's equator would see a sunrise +only every 175.97 Earth days, i.e., a Mercury year is 0.5 of a Mercury +day. Venus is more complicated, partly because its rotation is +slightly retrograde: its year is 1.92 of its days. Gas giants like +Jupiter are trickier still, as their polar and equatorial regions +rotate at different rates, so that the length of a day depends on +latitude. This effect is most pronounced on Neptune, where the day is +about 12 hours at the poles and 18 hours at the equator. +

+ +

+Although the tz database does not support time on other planets, it is +documented here in the hopes that support will be added eventually. +

+ +

+Sources: +

+ +
+ +
+
+This file is in the public domain, so clarified as of 2009-05-17 by +Arthur David Olson. +
+ + diff --git a/contrib/tzdata/version b/contrib/tzdata/version index c5bbdc4ead5d..198e36de73e0 100644 --- a/contrib/tzdata/version +++ b/contrib/tzdata/version @@ -1 +1 @@ -2017b +2017c diff --git a/contrib/tzdata/zishrink.awk b/contrib/tzdata/zishrink.awk new file mode 100644 index 000000000000..02c883a62620 --- /dev/null +++ b/contrib/tzdata/zishrink.awk @@ -0,0 +1,156 @@ +# Convert tzdata source into a smaller version of itself. + +# Contributed by Paul Eggert. This file is in the public domain. + +# This is not a general-purpose converter; it is designed for current tzdata. +# 'zic' should treat this script's output as if it were identical to +# this script's input. + + +# Return a new rule name. +# N_RULE_NAMES keeps track of how many rule names have been generated. + +function gen_rule_name(alphabet, base, rule_name, n, digit) +{ + alphabet = "" + alphabet = alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + alphabet = alphabet "abcdefghijklmnopqrstuvwxyz" + alphabet = alphabet "!$%&'()*+,./:;<=>?@[\\]^_`{|}~" + base = length(alphabet) + rule_name = "" + n = n_rule_names++ + + do { + n -= rule_name && n <= base + digit = n % base + rule_name = substr(alphabet, digit + 1, 1) rule_name + n = (n - digit) / base + } while (n); + + return rule_name +} + +# Process an input line and save it for later output. + +function process_input_line(line, field, end, i, n, startdef) +{ + # Remove comments, normalize spaces, and append a space to each line. + sub(/#.*/, "", line) + line = line " " + gsub(/[[:space:]]+/, " ", line) + + # Abbreviate keywords. Do not abbreviate "Link" to just "L", + # as pre-2017c zic erroneously diagnoses "Li" as ambiguous. + sub(/^Link /, "Li ", line) + sub(/^Rule /, "R ", line) + sub(/^Zone /, "Z ", line) + + # SystemV rules are not needed. + if (line ~ /^R SystemV /) return + + # Replace FooAsia rules with the same rules without "Asia", as they + # are duplicates. + if (match(line, /[^ ]Asia /)) { + if (line ~ /^R /) return + line = substr(line, 1, RSTART) substr(line, RSTART + 5) + } + + # Abbreviate times. + while (match(line, /[: ]0+[0-9]/)) + line = substr(line, 1, RSTART) substr(line, RSTART + RLENGTH - 1) + while (match(line, /:0[^:]/)) + line = substr(line, 1, RSTART - 1) substr(line, RSTART + 2) + + # Abbreviate weekday names. Do not abbreviate "Sun" and "Sat", as + # pre-2017c zic erroneously diagnoses "Su" and "Sa" as ambiguous. + while (match(line, / (last)?(Mon|Wed|Fri)[ <>]/)) { + end = RSTART + RLENGTH + line = substr(line, 1, end - 4) substr(line, end - 1) + } + while (match(line, / (last)?(Tue|Thu)[ <>]/)) { + end = RSTART + RLENGTH + line = substr(line, 1, end - 3) substr(line, end - 1) + } + + # Abbreviate "max", "only" and month names. + # Do not abbreviate "min", as pre-2017c zic erroneously diagnoses "mi" + # as ambiguous. + gsub(/ max /, " ma ", line) + gsub(/ only /, " o ", line) + gsub(/ Jan /, " Ja ", line) + gsub(/ Feb /, " F ", line) + gsub(/ Apr /, " Ap ", line) + gsub(/ Aug /, " Au ", line) + gsub(/ Sep /, " S ", line) + gsub(/ Oct /, " O ", line) + gsub(/ Nov /, " N ", line) + gsub(/ Dec /, " D ", line) + + # Strip leading and trailing space. + sub(/^ /, "", line) + sub(/ $/, "", line) + + # Remove unnecessary trailing zero fields. + sub(/ 0+$/, "", line) + + # Remove unnecessary trailing days-of-month "1". + if (match(line, /[[:alpha:]] 1$/)) + line = substr(line, 1, RSTART) + + # Remove unnecessary trailing " Ja" (for January). + sub(/ Ja$/, "", line) + + n = split(line, field) + + # Abbreviate rule names. + i = field[1] == "Z" ? 4 : field[1] == "Li" ? 0 : 2 + if (i && field[i] ~ /^[^-+0-9]/) { + if (!rule[field[i]]) + rule[field[i]] = gen_rule_name() + field[i] = rule[field[i]] + } + + # If this zone supersedes an earlier one, delete the earlier one + # from the saved output lines. + startdef = "" + if (field[1] == "Z") + zonename = startdef = field[2] + else if (field[1] == "Li") + zonename = startdef = field[3] + else if (field[1] == "R") + zonename = "" + if (startdef) { + i = zonedef[startdef] + if (i) { + do + output_line[i - 1] = "" + while (output_line[i++] ~ /^[-+0-9]/); + } + } + zonedef[zonename] = nout + 1 + + # Save the line for later output. + line = field[1] + for (i = 2; i <= n; i++) + line = line " " field[i] + output_line[nout++] = line +} + +function output_saved_lines(i) +{ + for (i = 0; i < nout; i++) + if (output_line[i]) + print output_line[i] +} + +BEGIN { + print "# This zic input file is in the public domain." +} + +/^[[:space:]]*[^#[:space:]]/ { + process_input_line($0) +} + +END { + output_saved_lines() +} diff --git a/contrib/tzdata/zone.tab b/contrib/tzdata/zone.tab index 204048cc5a63..2d0b26b7d658 100644 --- a/contrib/tzdata/zone.tab +++ b/contrib/tzdata/zone.tab @@ -186,7 +186,7 @@ GB +513030-0000731 Europe/London GD +1203-06145 America/Grenada GE +4143+04449 Asia/Tbilisi GF +0456-05220 America/Cayenne -GG +4927-00232 Europe/Guernsey +GG +492717-0023210 Europe/Guernsey GH +0533-00013 Africa/Accra GI +3608-00521 Europe/Gibraltar GL +6411-05144 America/Godthab Greenland (most areas) @@ -221,7 +221,7 @@ IQ +3321+04425 Asia/Baghdad IR +3540+05126 Asia/Tehran IS +6409-02151 Atlantic/Reykjavik IT +4154+01229 Europe/Rome -JE +4912-00207 Europe/Jersey +JE +491101-0020624 Europe/Jersey JM +175805-0764736 America/Jamaica JO +3157+03556 Asia/Amman JP +353916+1394441 Asia/Tokyo diff --git a/contrib/tzdata/zone1970.tab b/contrib/tzdata/zone1970.tab index b5fd7fc7d31f..bb0357631562 100644 --- a/contrib/tzdata/zone1970.tab +++ b/contrib/tzdata/zone1970.tab @@ -2,7 +2,7 @@ # # This file is in the public domain. # -# From Paul Eggert (2014-07-31): +# From Paul Eggert (2017-10-01): # This file contains a table where each row stands for a zone where # civil time stamps have agreed since 1970. Columns are separated by # a single tab. Lines beginning with '#' are comments. All text uses @@ -16,7 +16,7 @@ # either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS, # first latitude (+ is north), then longitude (+ is east). # 3. Zone name used in value of TZ environment variable. -# Please see the 'Theory' file for how zone names are chosen. +# Please see the theory.html file for how zone names are chosen. # If multiple zones overlap a country, each has a row in the # table, with each column 1 containing the country code. # 4. Comments; present if and only if a country has multiple zones. @@ -317,10 +317,11 @@ RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea SA,KW,YE +2438+04643 Asia/Riyadh SB -0932+16012 Pacific/Guadalcanal SC -0440+05528 Indian/Mahe -SD,SS +1536+03232 Africa/Khartoum +SD +1536+03232 Africa/Khartoum SE +5920+01803 Europe/Stockholm SG +0117+10351 Asia/Singapore SR +0550-05510 America/Paramaribo +SS +0451+03137 Africa/Juba SV +1342-08912 America/El_Salvador SY +3330+03618 Asia/Damascus TC +2128-07108 America/Grand_Turk diff --git a/contrib/wpa/src/ap/wpa_auth.c b/contrib/wpa/src/ap/wpa_auth.c index 2760a3f3a00e..63f252fb55b0 100644 --- a/contrib/wpa/src/ap/wpa_auth.c +++ b/contrib/wpa/src/ap/wpa_auth.c @@ -1893,6 +1893,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) } +static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) +{ + if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { + wpa_printf(MSG_ERROR, + "WPA: Failed to get random data for ANonce"); + sm->Disconnect = TRUE; + return -1; + } + wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, + WPA_NONCE_LEN); + sm->TimeoutCtr = 0; + return 0; +} + + SM_STATE(WPA_PTK, INITPMK) { u8 msk[2 * PMK_LEN]; @@ -2414,9 +2429,12 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, AUTHENTICATION); else if (sm->ReAuthenticationRequest) SM_ENTER(WPA_PTK, AUTHENTICATION2); - else if (sm->PTKRequest) - SM_ENTER(WPA_PTK, PTKSTART); - else switch (sm->wpa_ptk_state) { + else if (sm->PTKRequest) { + if (wpa_auth_sm_ptk_update(sm) < 0) + SM_ENTER(WPA_PTK, DISCONNECTED); + else + SM_ENTER(WPA_PTK, PTKSTART); + } else switch (sm->wpa_ptk_state) { case WPA_PTK_INITIALIZE: break; case WPA_PTK_DISCONNECT: @@ -3209,6 +3227,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) } +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm) +{ + if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt)) + return 0; + return sm->tk_already_set; +} + + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, struct rsn_pmksa_cache_entry *entry) { diff --git a/contrib/wpa/src/ap/wpa_auth.h b/contrib/wpa/src/ap/wpa_auth.h index fd04f169433a..1b1442f414fa 100644 --- a/contrib/wpa/src/ap/wpa_auth.h +++ b/contrib/wpa/src/ap/wpa_auth.h @@ -271,6 +271,7 @@ int wpa_auth_pairwise_set(struct wpa_state_machine *sm); int wpa_auth_get_pairwise(struct wpa_state_machine *sm); int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm); int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm); +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm); int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, struct rsn_pmksa_cache_entry *entry); struct rsn_pmksa_cache_entry * diff --git a/contrib/wpa/src/ap/wpa_auth_ft.c b/contrib/wpa/src/ap/wpa_auth_ft.c index eeaffbf63516..f8f5dbe3e7da 100644 --- a/contrib/wpa/src/ap/wpa_auth_ft.c +++ b/contrib/wpa/src/ap/wpa_auth_ft.c @@ -780,6 +780,14 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) return; } + if (sm->tk_already_set) { + /* Must avoid TK reconfiguration to prevent clearing of TX/RX + * PN in the driver */ + wpa_printf(MSG_DEBUG, + "FT: Do not re-install same PTK to the driver"); + return; + } + /* FIX: add STA entry to kernel/driver here? The set_key will fail * most likely without this.. At the moment, STA entry is added only * after association has been completed. This function will be called @@ -792,6 +800,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ sm->pairwise_set = TRUE; + sm->tk_already_set = TRUE; } @@ -898,6 +907,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, sm->pairwise = pairwise; sm->PTK_valid = TRUE; + sm->tk_already_set = FALSE; wpa_ft_install_ptk(sm); buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + diff --git a/contrib/wpa/src/ap/wpa_auth_i.h b/contrib/wpa/src/ap/wpa_auth_i.h index 57b098f2ed72..234d84c84689 100644 --- a/contrib/wpa/src/ap/wpa_auth_i.h +++ b/contrib/wpa/src/ap/wpa_auth_i.h @@ -64,6 +64,7 @@ struct wpa_state_machine { struct wpa_ptk PTK; Boolean PTK_valid; Boolean pairwise_set; + Boolean tk_already_set; int keycount; Boolean Pair; struct wpa_key_replay_counter { diff --git a/contrib/wpa/src/common/wpa_common.h b/contrib/wpa/src/common/wpa_common.h index c08f6514ab57..a04e759373b9 100644 --- a/contrib/wpa/src/common/wpa_common.h +++ b/contrib/wpa/src/common/wpa_common.h @@ -213,8 +213,20 @@ struct wpa_ptk { size_t kck_len; size_t kek_len; size_t tk_len; + int installed; /* 1 if key has already been installed to driver */ }; +struct wpa_gtk { + u8 gtk[WPA_GTK_MAX_LEN]; + size_t gtk_len; +}; + +#ifdef CONFIG_IEEE80211W +struct wpa_igtk { + u8 igtk[WPA_IGTK_MAX_LEN]; + size_t igtk_len; +}; +#endif /* CONFIG_IEEE80211W */ /* WPA IE version 1 * 00-50-f2:1 (OUI:OUI type) diff --git a/contrib/wpa/src/rsn_supp/tdls.c b/contrib/wpa/src/rsn_supp/tdls.c index 722c20a706f9..cce59d7df5b9 100644 --- a/contrib/wpa/src/rsn_supp/tdls.c +++ b/contrib/wpa/src/rsn_supp/tdls.c @@ -112,6 +112,7 @@ struct wpa_tdls_peer { u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ } tpk; int tpk_set; + int tk_set; /* TPK-TK configured to the driver */ int tpk_success; int tpk_in_progress; @@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) u8 rsc[6]; enum wpa_alg alg; + if (peer->tk_set) { + /* + * This same TPK-TK has already been configured to the driver + * and this new configuration attempt (likely due to an + * unexpected retransmitted frame) would result in clearing + * the TX/RX sequence number which can break security, so must + * not allow that to happen. + */ + wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR + " has already been configured to the driver - do not reconfigure", + MAC2STR(peer->addr)); + return -1; + } + os_memset(rsc, 0, 6); switch (peer->cipher) { @@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) return -1; } + wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, + MAC2STR(peer->addr)); if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " "driver"); return -1; } + peer->tk_set = 1; return 0; } @@ -690,7 +708,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->cipher = 0; peer->qos_info = 0; peer->wmm_capable = 0; - peer->tpk_set = peer->tpk_success = 0; + peer->tk_set = peer->tpk_set = peer->tpk_success = 0; peer->chan_switch_enabled = 0; os_memset(&peer->tpk, 0, sizeof(peer->tpk)); os_memset(peer->inonce, 0, WPA_NONCE_LEN); @@ -1153,6 +1171,7 @@ static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm, wpa_tdls_peer_free(sm, peer); return -1; } + peer->tk_set = 0; /* A new nonce results in a new TK */ wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", peer->inonce, WPA_NONCE_LEN); os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); @@ -1745,6 +1764,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, } +static int tdls_nonce_set(const u8 *nonce) +{ + int i; + + for (i = 0; i < WPA_NONCE_LEN; i++) { + if (nonce[i]) + return 1; + } + + return 0; +} + + static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, const u8 *buf, size_t len) { @@ -1998,7 +2030,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, peer->rsnie_i_len = kde.rsn_ie_len; peer->cipher = cipher; - if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { + if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || + !tdls_nonce_set(peer->inonce)) { /* * There is no point in updating the RNonce for every obtained * TPK M1 frame (e.g., retransmission due to timeout) with the @@ -2014,6 +2047,7 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, "TDLS: Failed to get random data for responder nonce"); goto error; } + peer->tk_set = 0; /* A new nonce results in a new TK */ } #if 0 @@ -2170,6 +2204,14 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr, "ignore TPK M2 from " MACSTR, MAC2STR(src_addr)); return -1; } + + if (peer->tpk_success) { + wpa_printf(MSG_INFO, "TDLS: Ignore incoming TPK M2 retry, from " + MACSTR " as TPK M3 was already sent", + MAC2STR(src_addr)); + return 0; + } + wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST); if (len < 3 + 2 + 1) { diff --git a/contrib/wpa/src/rsn_supp/wpa.c b/contrib/wpa/src/rsn_supp/wpa.c index d397ff1605c2..bc50c97141b6 100644 --- a/contrib/wpa/src/rsn_supp/wpa.c +++ b/contrib/wpa/src/rsn_supp/wpa.c @@ -605,6 +605,12 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, const u8 *key_rsc; u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + if (sm->ptk.installed) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Do not re-install same PTK to the driver"); + return 0; + } + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Installing PTK to the driver"); @@ -643,6 +649,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, /* TK is not needed anymore in supplicant */ os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); + sm->ptk.installed = 1; if (sm->wpa_ptk_rekey) { eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); @@ -692,11 +699,23 @@ struct wpa_gtk_data { static int wpa_supplicant_install_gtk(struct wpa_sm *sm, const struct wpa_gtk_data *gd, - const u8 *key_rsc) + const u8 *key_rsc, int wnm_sleep) { const u8 *_gtk = gd->gtk; u8 gtk_buf[32]; + /* Detect possible key reinstallation */ + if ((sm->gtk.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) || + (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk, + sm->gtk_wnm_sleep.gtk_len) == 0)) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", + gd->keyidx, gd->tx, gd->gtk_len); + return 0; + } + wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)", @@ -731,6 +750,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, } os_memset(gtk_buf, 0, sizeof(gtk_buf)); + if (wnm_sleep) { + sm->gtk_wnm_sleep.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk, + sm->gtk_wnm_sleep.gtk_len); + } else { + sm->gtk.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); + } + return 0; } @@ -788,7 +816,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, gtk_len, gtk_len, &gd.key_rsc_len, &gd.alg) || - wpa_supplicant_install_gtk(sm, &gd, key->key_rsc))) { + wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0))) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Failed to install GTK"); os_memset(&gd, 0, sizeof(gd)); @@ -802,6 +830,58 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, } +#ifdef CONFIG_IEEE80211W +static int wpa_supplicant_install_igtk(struct wpa_sm *sm, + const struct wpa_igtk_kde *igtk, + int wnm_sleep) +{ + size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); + u16 keyidx = WPA_GET_LE16(igtk->keyid); + + /* Detect possible key reinstallation */ + if ((sm->igtk.igtk_len == len && + os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) || + (sm->igtk_wnm_sleep.igtk_len == len && + os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk, + sm->igtk_wnm_sleep.igtk_len) == 0)) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", + keyidx); + return 0; + } + + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", + keyidx, MAC2STR(igtk->pn)); + wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); + if (keyidx > 4095) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Invalid IGTK KeyID %d", keyidx); + return -1; + } + if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), + broadcast_ether_addr, + keyidx, 0, igtk->pn, sizeof(igtk->pn), + igtk->igtk, len) < 0) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Failed to configure IGTK to the driver"); + return -1; + } + + if (wnm_sleep) { + sm->igtk_wnm_sleep.igtk_len = len; + os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk, + sm->igtk_wnm_sleep.igtk_len); + } else { + sm->igtk.igtk_len = len; + os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + } + + return 0; +} +#endif /* CONFIG_IEEE80211W */ + + static int ieee80211w_set_keys(struct wpa_sm *sm, struct wpa_eapol_ie_parse *ie) { @@ -812,30 +892,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm, if (ie->igtk) { size_t len; const struct wpa_igtk_kde *igtk; - u16 keyidx; + len = wpa_cipher_key_len(sm->mgmt_group_cipher); if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len) return -1; + igtk = (const struct wpa_igtk_kde *) ie->igtk; - keyidx = WPA_GET_LE16(igtk->keyid); - wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d " - "pn %02x%02x%02x%02x%02x%02x", - keyidx, MAC2STR(igtk->pn)); - wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", - igtk->igtk, len); - if (keyidx > 4095) { - wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "WPA: Invalid IGTK KeyID %d", keyidx); + if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0) return -1; - } - if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), - broadcast_ether_addr, - keyidx, 0, igtk->pn, sizeof(igtk->pn), - igtk->igtk, len) < 0) { - wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "WPA: Failed to configure IGTK to the driver"); - return -1; - } } return 0; @@ -1483,7 +1547,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, if (ret) goto failed; - if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) || + if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0) || wpa_supplicant_send_2_of_2(sm, key, ver, key_info)) goto failed; os_memset(&gd, 0, sizeof(gd)); @@ -2251,7 +2315,7 @@ void wpa_sm_deinit(struct wpa_sm *sm) */ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) { - int clear_ptk = 1; + int clear_keys = 1; if (sm == NULL) return; @@ -2277,11 +2341,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) /* Prepare for the next transition */ wpa_ft_prepare_auth_request(sm, NULL); - clear_ptk = 0; + clear_keys = 0; } #endif /* CONFIG_IEEE80211R */ - if (clear_ptk) { + if (clear_keys) { /* * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if * this is not part of a Fast BSS Transition. @@ -2291,6 +2355,12 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) os_memset(&sm->ptk, 0, sizeof(sm->ptk)); sm->tptk_set = 0; os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); +#ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); + os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); +#endif /* CONFIG_IEEE80211W */ } #ifdef CONFIG_TDLS @@ -2322,6 +2392,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm) #ifdef CONFIG_TDLS wpa_tdls_disassoc(sm); #endif /* CONFIG_TDLS */ +#ifdef CONFIG_IEEE80211R + sm->ft_reassoc_completed = 0; +#endif /* CONFIG_IEEE80211R */ /* Keys are not needed in the WPA state machine anymore */ wpa_sm_drop_sa(sm); @@ -2807,6 +2880,12 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) os_memset(sm->pmk, 0, sizeof(sm->pmk)); os_memset(&sm->ptk, 0, sizeof(sm->ptk)); os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); +#ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); + os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); +#endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0)); @@ -2870,7 +2949,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", gd.gtk, gd.gtk_len); - if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) { + if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) { os_memset(&gd, 0, sizeof(gd)); wpa_printf(MSG_DEBUG, "Failed to install the GTK in " "WNM mode"); @@ -2879,29 +2958,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) os_memset(&gd, 0, sizeof(gd)); #ifdef CONFIG_IEEE80211W } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { - struct wpa_igtk_kde igd; - u16 keyidx; + const struct wpa_igtk_kde *igtk; - os_memset(&igd, 0, sizeof(igd)); - keylen = wpa_cipher_key_len(sm->mgmt_group_cipher); - os_memcpy(igd.keyid, buf + 2, 2); - os_memcpy(igd.pn, buf + 4, 6); - - keyidx = WPA_GET_LE16(igd.keyid); - os_memcpy(igd.igtk, buf + 10, keylen); - - wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)", - igd.igtk, keylen); - if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), - broadcast_ether_addr, - keyidx, 0, igd.pn, sizeof(igd.pn), - igd.igtk, keylen) < 0) { - wpa_printf(MSG_DEBUG, "Failed to install the IGTK in " - "WNM mode"); - os_memset(&igd, 0, sizeof(igd)); + igtk = (const struct wpa_igtk_kde *) (buf + 2); + if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0) return -1; - } - os_memset(&igd, 0, sizeof(igd)); #endif /* CONFIG_IEEE80211W */ } else { wpa_printf(MSG_DEBUG, "Unknown element id"); diff --git a/contrib/wpa/src/rsn_supp/wpa_ft.c b/contrib/wpa/src/rsn_supp/wpa_ft.c index 205793e7f43a..d45bb4585e50 100644 --- a/contrib/wpa/src/rsn_supp/wpa_ft.c +++ b/contrib/wpa/src/rsn_supp/wpa_ft.c @@ -153,6 +153,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, u16 capab; sm->ft_completed = 0; + sm->ft_reassoc_completed = 0; buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + 2 + sm->r0kh_id_len + ric_ies_len + 100; @@ -681,6 +682,11 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, return -1; } + if (sm->ft_reassoc_completed) { + wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission"); + return 0; + } + if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); return -1; @@ -781,6 +787,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, return -1; } + sm->ft_reassoc_completed = 1; + if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0) return -1; diff --git a/contrib/wpa/src/rsn_supp/wpa_i.h b/contrib/wpa/src/rsn_supp/wpa_i.h index 965a9c1d577c..85cc86282640 100644 --- a/contrib/wpa/src/rsn_supp/wpa_i.h +++ b/contrib/wpa/src/rsn_supp/wpa_i.h @@ -30,6 +30,12 @@ struct wpa_sm { u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + struct wpa_gtk gtk; + struct wpa_gtk gtk_wnm_sleep; +#ifdef CONFIG_IEEE80211W + struct wpa_igtk igtk; + struct wpa_igtk igtk_wnm_sleep; +#endif /* CONFIG_IEEE80211W */ struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ @@ -121,6 +127,7 @@ struct wpa_sm { size_t r0kh_id_len; u8 r1kh_id[FT_R1KH_ID_LEN]; int ft_completed; + int ft_reassoc_completed; int over_the_ds_in_progress; u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ int set_ptk_after_assoc; diff --git a/contrib/wpa/wpa_supplicant/ctrl_iface.c b/contrib/wpa/wpa_supplicant/ctrl_iface.c index 3b97806d871d..25dcdf7ee321 100644 --- a/contrib/wpa/wpa_supplicant/ctrl_iface.c +++ b/contrib/wpa/wpa_supplicant/ctrl_iface.c @@ -6891,6 +6891,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) } eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); + wpa_s->wnmsleep_used = 0; } diff --git a/contrib/wpa/wpa_supplicant/events.c b/contrib/wpa/wpa_supplicant/events.c index 3af1c7d89c64..e2105ec505f5 100644 --- a/contrib/wpa/wpa_supplicant/events.c +++ b/contrib/wpa/wpa_supplicant/events.c @@ -303,6 +303,7 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) wpa_s->key_mgmt = 0; wpas_rrm_reset(wpa_s); + wpa_s->wnmsleep_used = 0; } diff --git a/contrib/wpa/wpa_supplicant/wnm_sta.c b/contrib/wpa/wpa_supplicant/wnm_sta.c index 954de67c2aa3..d88c863ac25e 100644 --- a/contrib/wpa/wpa_supplicant/wnm_sta.c +++ b/contrib/wpa/wpa_supplicant/wnm_sta.c @@ -137,6 +137,8 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, if (res < 0) wpa_printf(MSG_DEBUG, "Failed to send WNM-Sleep Request " "(action=%d, intval=%d)", action, intval); + else + wpa_s->wnmsleep_used = 1; os_free(wnmsleep_ie); os_free(wnmtfs_ie); @@ -187,6 +189,12 @@ static void wnm_sleep_mode_exit_success(struct wpa_supplicant *wpa_s, end = ptr + key_len_total; wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total); + if (key_len_total && !wpa_sm_pmf_enabled(wpa_s->wpa)) { + wpa_msg(wpa_s, MSG_INFO, + "WNM: Ignore Key Data in WNM-Sleep Mode Response - PMF not enabled"); + return; + } + while (ptr + 1 < end) { if (ptr + 2 + ptr[1] > end) { wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element " @@ -247,6 +255,12 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, u8 *tfsresp_ie_end = NULL; size_t left; + if (!wpa_s->wnmsleep_used) { + wpa_printf(MSG_DEBUG, + "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested"); + return; + } + if (len < 3) return; key_len_total = WPA_GET_LE16(frm + 1); @@ -282,6 +296,8 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, return; } + wpa_s->wnmsleep_used = 0; + if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT || wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) { wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response " diff --git a/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h b/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h index 58df48c548ea..318768bc2776 100644 --- a/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h +++ b/contrib/wpa/wpa_supplicant/wpa_supplicant_i.h @@ -658,6 +658,7 @@ struct wpa_supplicant { unsigned int reattach:1; /* reassociation to the same BSS requested */ unsigned int mac_addr_changed:1; unsigned int added_vif:1; + unsigned int wnmsleep_used:1; struct os_reltime last_mac_addr_change; int last_mac_addr_style; diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES index 307b2ed5e312..e3d57b328c58 100644 --- a/crypto/openssl/CHANGES +++ b/crypto/openssl/CHANGES @@ -2,6 +2,44 @@ OpenSSL CHANGES _______________ + This is a high-level summary of the most important changes. + For a full list of changes, see the git commit log; for example, + https://github.com/openssl/openssl/commits/ and pick the appropriate + release branch. + + Changes between 1.0.2l and 1.0.2m [2 Nov 2017] + + *) bn_sqrx8x_internal carry bug on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. + + This only affects processors that support the BMI1, BMI2 and ADX extensions + like Intel Broadwell (5th generation) and later or AMD Ryzen. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + (CVE-2017-3736) + [Andy Polyakov] + + *) Malformed X.509 IPAddressFamily could cause OOB read + + If an X.509 certificate has a malformed IPAddressFamily extension, + OpenSSL could do a one-byte buffer overread. The most likely result + would be an erroneous display of the certificate in text format. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + (CVE-2017-3735) + [Rich Salz] + Changes between 1.0.2k and 1.0.2l [25 May 2017] *) Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target diff --git a/crypto/openssl/INSTALL b/crypto/openssl/INSTALL index aa7e35fa79fe..fcdbfc0a6ee0 100644 --- a/crypto/openssl/INSTALL +++ b/crypto/openssl/INSTALL @@ -190,10 +190,8 @@ the failure that isn't a problem in OpenSSL itself (like a missing or malfunctioning bc). If it is a problem with OpenSSL itself, try removing any compiler optimization flags from the CFLAG line - in Makefile.ssl and run "make clean; make". Please send a bug - report to , including the output of - "make report" in order to be added to the request tracker at - http://www.openssl.org/support/rt.html. + in Makefile.ssl and run "make clean; make". To report a bug please open an + issue on GitHub, at https://github.com/openssl/openssl/issues. 4. If everything tests ok, install OpenSSL with diff --git a/crypto/openssl/Makefile b/crypto/openssl/Makefile index a3d30318f917..484f2f45f776 100644 --- a/crypto/openssl/Makefile +++ b/crypto/openssl/Makefile @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2l +VERSION=1.0.2m MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS index fd49cedeba4c..1b72013ad186 100644 --- a/crypto/openssl/NEWS +++ b/crypto/openssl/NEWS @@ -5,6 +5,11 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.0.2l and OpenSSL 1.0.2m [2 Nov 2017] + + o bn_sqrx8x_internal carry bug on x86_64 (CVE-2017-3736) + o Malformed X.509 IPAddressFamily could cause OOB read (CVE-2017-3735) + Major changes between OpenSSL 1.0.2k and OpenSSL 1.0.2l [25 May 2017] o config now recognises 64-bit mingw and chooses mingw64 instead of mingw diff --git a/crypto/openssl/README b/crypto/openssl/README index 4c357d9a836d..b5aae6260ce8 100644 --- a/crypto/openssl/README +++ b/crypto/openssl/README @@ -1,5 +1,5 @@ - OpenSSL 1.0.2l 25 May 2017 + OpenSSL 1.0.2m 2 Nov 2017 Copyright (c) 1998-2015 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/crypto/openssl/apps/ca.c b/crypto/openssl/apps/ca.c index f90f033baed3..9a839969a204 100644 --- a/crypto/openssl/apps/ca.c +++ b/crypto/openssl/apps/ca.c @@ -1985,10 +1985,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* Lets add the extensions, if there are any */ if (ext_sect) { X509V3_CTX ctx; - if (ci->version == NULL) - if ((ci->version = ASN1_INTEGER_new()) == NULL) - goto err; - ASN1_INTEGER_set(ci->version, 2); /* version 3 certificate */ /* * Free the current entries if any, there should not be any I believe @@ -2051,6 +2047,15 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, goto err; } + { + STACK_OF(X509_EXTENSION) *exts = ci->extensions; + + if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0) + /* Make it an X509 v3 certificate. */ + if (!X509_set_version(ret, 2)) + goto err; + } + /* Set the right value for the noemailDN option */ if (email_dn == 0) { if (!X509_set_subject_name(ret, dn_subject)) diff --git a/crypto/openssl/apps/s_client.c b/crypto/openssl/apps/s_client.c index 85c1b6b57944..dc467994f8e2 100644 --- a/crypto/openssl/apps/s_client.c +++ b/crypto/openssl/apps/s_client.c @@ -1667,6 +1667,8 @@ int MAIN(int argc, char **argv) if (strstr(mbuf, "/stream:features>")) goto shut; seen = BIO_read(sbio, mbuf, BUFSIZZ); + if (seen <= 0) + goto shut; mbuf[seen] = 0; } BIO_printf(sbio, diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c index d75871386928..98ffc09314a3 100644 --- a/crypto/openssl/apps/s_server.c +++ b/crypto/openssl/apps/s_server.c @@ -3017,7 +3017,7 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) PEM_write_bio_X509(io, peer); } else BIO_puts(io, "no client certificate available\n"); - BIO_puts(io, "\r\n\r\n"); + BIO_puts(io, "\r\n\r\n"); break; } else if ((www == 2 || www == 3) && (strncmp("GET /", buf, 5) == 0)) { diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c index 6cd102152504..5259c16f1218 100644 --- a/crypto/openssl/apps/speed.c +++ b/crypto/openssl/apps/speed.c @@ -307,7 +307,8 @@ static SIGRETTYPE sig_done(int sig) # if !defined(SIGALRM) # define SIGALRM # endif -static unsigned int lapse, schlock; +static volatile unsigned int lapse; +static volatile unsigned int schlock; static void alarm_win32(unsigned int secs) { lapse = secs * 1000; @@ -725,6 +726,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "no EVP given\n"); goto end; } + evp_md = NULL; evp_cipher = EVP_get_cipherbyname(*argv); if (!evp_cipher) { evp_md = EVP_get_digestbyname(*argv); diff --git a/crypto/openssl/apps/spkac.c b/crypto/openssl/apps/spkac.c index 7f5333fe832e..4b4106d03b99 100644 --- a/crypto/openssl/apps/spkac.c +++ b/crypto/openssl/apps/spkac.c @@ -5,7 +5,7 @@ * 1999. Based on an original idea by Massimiliano Pala (madwolf@openca.org). */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2017 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -185,20 +185,23 @@ int MAIN(int argc, char **argv) } e = setup_engine(bio_err, engine, 0); - if (keyfile) { + if (keyfile != NULL) { pkey = load_key(bio_err, strcmp(keyfile, "-") ? keyfile : NULL, FORMAT_PEM, 1, passin, e, "private key"); - if (!pkey) { + if (pkey == NULL) goto end; - } spki = NETSCAPE_SPKI_new(); - if (challenge) + if (spki == NULL) + goto end; + if (challenge != NULL) ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge)); NETSCAPE_SPKI_set_pubkey(spki, pkey); NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); + if (spkstr == NULL) + goto end; if (outfile) out = BIO_new_file(outfile, "w"); @@ -253,7 +256,7 @@ int MAIN(int argc, char **argv) spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); - if (!spki) { + if (spki == NULL) { BIO_printf(bio_err, "Error loading SPKAC\n"); ERR_print_errors(bio_err); goto end; @@ -282,9 +285,9 @@ int MAIN(int argc, char **argv) pkey = NETSCAPE_SPKI_get_pubkey(spki); if (verify) { i = NETSCAPE_SPKI_verify(spki, pkey); - if (i > 0) + if (i > 0) { BIO_printf(bio_err, "Signature OK\n"); - else { + } else { BIO_printf(bio_err, "Signature Failure\n"); ERR_print_errors(bio_err); goto end; diff --git a/crypto/openssl/apps/srp.c b/crypto/openssl/apps/srp.c index ce01a24f2a78..491445df60b0 100644 --- a/crypto/openssl/apps/srp.c +++ b/crypto/openssl/apps/srp.c @@ -123,13 +123,14 @@ static int get_index(CA_DB *db, char *id, char type) int i; if (id == NULL) return -1; - if (type == DB_SRP_INDEX) + if (type == DB_SRP_INDEX) { for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id, pp[DB_srpid])) return i; - } else + } + } else { for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); @@ -137,6 +138,7 @@ static int get_index(CA_DB *db, char *id, char type) && !strcmp(id, pp[DB_srpid])) return i; } + } return -1; } @@ -177,8 +179,8 @@ static int update_index(CA_DB *db, BIO *bio, char **row) char **irow; int i; - if ((irow = - (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) { + irow = (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1)); + if (irow == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); return 0; } @@ -205,30 +207,32 @@ static char *srp_verify_user(const char *user, const char *srp_verifier, char *srp_usersalt, const char *g, const char *N, const char *passin, BIO *bio, int verbose) { - char password[1024]; + char password[1025]; PW_CB_DATA cb_tmp; char *verifier = NULL; char *gNid = NULL; + int len; cb_tmp.prompt_info = user; cb_tmp.password = passin; - if (password_callback(password, 1024, 0, &cb_tmp) > 0) { + len = password_callback(password, sizeof(password)-1, 0, &cb_tmp); + if (len > 0) { + password[len] = 0; VERBOSE BIO_printf(bio, "Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", user, srp_verifier, srp_usersalt, g, N); - BIO_printf(bio, "Pass %s\n", password); + VVERBOSE BIO_printf(bio, "Pass %s\n", password); - if (! - (gNid = - SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, - g))) { + if (!(gNid = SRP_create_verifier(user, password, &srp_usersalt, + &verifier, N, g))) { BIO_printf(bio, "Internal error validating SRP verifier\n"); } else { if (strcmp(verifier, srp_verifier)) gNid = NULL; OPENSSL_free(verifier); } + OPENSSL_cleanse(password, len); } return gNid; } @@ -237,24 +241,27 @@ static char *srp_create_user(char *user, char **srp_verifier, char **srp_usersalt, char *g, char *N, char *passout, BIO *bio, int verbose) { - char password[1024]; + char password[1025]; PW_CB_DATA cb_tmp; char *gNid = NULL; char *salt = NULL; + int len; cb_tmp.prompt_info = user; cb_tmp.password = passout; - if (password_callback(password, 1024, 1, &cb_tmp) > 0) { + len = password_callback(password, sizeof(password)-1, 1, &cb_tmp); + if (len > 0) { + password[len] = 0; VERBOSE BIO_printf(bio, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", user, g, N); - if (! - (gNid = - SRP_create_verifier(user, password, &salt, srp_verifier, N, - g))) { + if (!(gNid = SRP_create_verifier(user, password, &salt, + srp_verifier, N, g))) { BIO_printf(bio, "Internal error creating SRP verifier\n"); - } else + } else { *srp_usersalt = salt; + } + OPENSSL_cleanse(password, len); VVERBOSE BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid, salt, *srp_verifier); @@ -314,9 +321,9 @@ int MAIN(int argc, char **argv) argc--; argv++; while (argc >= 1 && badops == 0) { - if (strcmp(*argv, "-verbose") == 0) + if (strcmp(*argv, "-verbose") == 0) { verbose++; - else if (strcmp(*argv, "-config") == 0) { + } else if (strcmp(*argv, "-config") == 0) { if (--argc < 1) goto bad; configfile = *(++argv); @@ -328,15 +335,15 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; dbfile = *(++argv); - } else if (strcmp(*argv, "-add") == 0) + } else if (strcmp(*argv, "-add") == 0) { add_user = 1; - else if (strcmp(*argv, "-delete") == 0) + } else if (strcmp(*argv, "-delete") == 0) { delete_user = 1; - else if (strcmp(*argv, "-modify") == 0) + } else if (strcmp(*argv, "-modify") == 0) { modify_user = 1; - else if (strcmp(*argv, "-list") == 0) + } else if (strcmp(*argv, "-list") == 0) { list_user = 1; - else if (strcmp(*argv, "-gn") == 0) { + } else if (strcmp(*argv, "-gn") == 0) { if (--argc < 1) goto bad; gN = *(++argv); @@ -366,8 +373,9 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; - } else + } else { break; + } argc--; argv++; @@ -388,7 +396,7 @@ int MAIN(int argc, char **argv) "Need at least one user for options -add, -delete, -modify. \n"); badops = 1; } - if ((passin || passout) && argc != 1) { + if ((passargin || passargout) && argc != 1) { BIO_printf(bio_err, "-passin, -passout arguments only valid with one user.\n"); badops = 1; @@ -706,9 +714,9 @@ int MAIN(int argc, char **argv) doupdatedb = 1; } } - if (--argc > 0) + if (--argc > 0) { user = *(argv++); - else { + } else { user = NULL; list_user = 0; } diff --git a/crypto/openssl/apps/tsget b/crypto/openssl/apps/tsget index 0d54e9fc9a76..0fca99f4385a 100644 --- a/crypto/openssl/apps/tsget +++ b/crypto/openssl/apps/tsget @@ -193,4 +193,3 @@ REQUEST: foreach (@ARGV) { STDERR->printflush(", $output written.\n") if $options{v}; } $curl->cleanup(); -WWW::Curl::Easy::global_cleanup(); diff --git a/crypto/openssl/crypto/asn1/Makefile b/crypto/openssl/crypto/asn1/Makefile index 330fe81b740c..fb3140c1d302 100644 --- a/crypto/openssl/crypto/asn1/Makefile +++ b/crypto/openssl/crypto/asn1/Makefile @@ -680,7 +680,7 @@ tasn_fre.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h tasn_fre.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -tasn_fre.o: ../../include/openssl/symhacks.h tasn_fre.c +tasn_fre.o: ../../include/openssl/symhacks.h asn1_int.h tasn_fre.c tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h tasn_new.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h @@ -688,7 +688,7 @@ tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h tasn_new.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -tasn_new.o: ../../include/openssl/symhacks.h tasn_new.c +tasn_new.o: ../../include/openssl/symhacks.h asn1_int.h tasn_new.c tasn_prn.o: ../../e_os.h ../../include/openssl/asn1.h tasn_prn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h tasn_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h diff --git a/crypto/openssl/crypto/asn1/a_bitstr.c b/crypto/openssl/crypto/asn1/a_bitstr.c index c429342e03d4..0c8bb144a099 100644 --- a/crypto/openssl/crypto/asn1/a_bitstr.c +++ b/crypto/openssl/crypto/asn1/a_bitstr.c @@ -56,6 +56,7 @@ * [including the GNU Public Licence.] */ +#include #include #include "cryptlib.h" #include @@ -136,6 +137,11 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, goto err; } + if (len > INT_MAX) { + i = ASN1_R_STRING_TOO_LONG; + goto err; + } + if ((a == NULL) || ((*a) == NULL)) { if ((ret = M_ASN1_BIT_STRING_new()) == NULL) return (NULL); diff --git a/crypto/openssl/crypto/asn1/asn1_int.h b/crypto/openssl/crypto/asn1/asn1_int.h new file mode 100644 index 000000000000..c9fd8b12ae17 --- /dev/null +++ b/crypto/openssl/crypto/asn1/asn1_int.h @@ -0,0 +1,63 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Internal ASN1 template structures and functions: not for application use */ + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); diff --git a/crypto/openssl/crypto/asn1/tasn_fre.c b/crypto/openssl/crypto/asn1/tasn_fre.c index aeea4eff7ab8..0cf7510ff038 100644 --- a/crypto/openssl/crypto/asn1/tasn_fre.c +++ b/crypto/openssl/crypto/asn1/tasn_fre.c @@ -61,9 +61,7 @@ #include #include #include - -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); +#include "asn1_int.h" /* Free up an ASN1 structure */ @@ -77,8 +75,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) asn1_item_combine_free(pval, it, 0); } -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; diff --git a/crypto/openssl/crypto/asn1/tasn_new.c b/crypto/openssl/crypto/asn1/tasn_new.c index 54f459d1ed9c..6ba90260dab3 100644 --- a/crypto/openssl/crypto/asn1/tasn_new.c +++ b/crypto/openssl/crypto/asn1/tasn_new.c @@ -63,6 +63,7 @@ #include #include #include +#include "asn1_int.h" static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); @@ -199,7 +200,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; memerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); memerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); #ifdef CRYPTO_MDEBUG @@ -209,7 +210,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; auxerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); auxerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); #ifdef CRYPTO_MDEBUG diff --git a/crypto/openssl/crypto/asn1/x_name.c b/crypto/openssl/crypto/asn1/x_name.c index 1fb7ad1cbf88..aea0c2763c28 100644 --- a/crypto/openssl/crypto/asn1/x_name.c +++ b/crypto/openssl/crypto/asn1/x_name.c @@ -523,19 +523,11 @@ static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { - X509_NAME *in; - - if (!xn || !name) - return (0); - - if (*xn != name) { - in = X509_NAME_dup(name); - if (in != NULL) { - X509_NAME_free(*xn); - *xn = in; - } - } - return (*xn != NULL); + if ((name = X509_NAME_dup(name)) == NULL) + return 0; + X509_NAME_free(*xn); + *xn = name; + return 1; } IMPLEMENT_STACK_OF(X509_NAME_ENTRY) diff --git a/crypto/openssl/crypto/asn1/x_pkey.c b/crypto/openssl/crypto/asn1/x_pkey.c index 2da23e4756b4..59f855392840 100644 --- a/crypto/openssl/crypto/asn1/x_pkey.c +++ b/crypto/openssl/crypto/asn1/x_pkey.c @@ -106,10 +106,14 @@ X509_PKEY *X509_PKEY_new(void) X509_PKEY *ret = NULL; ASN1_CTX c; - M_ASN1_New_Malloc(ret, X509_PKEY); + ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + c.line = __LINE__; + goto err; + } ret->version = 0; - M_ASN1_New(ret->enc_algor, X509_ALGOR_new); - M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new); + ret->enc_algor = X509_ALGOR_new(); + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); ret->dec_pkey = NULL; ret->key_length = 0; ret->key_data = NULL; @@ -117,8 +121,15 @@ X509_PKEY *X509_PKEY_new(void) ret->cipher.cipher = NULL; memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); ret->references = 1; - return (ret); - M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW); + if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { + c.line = __LINE__; + goto err; + } + return ret; +err: + X509_PKEY_free(ret); + ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE, c.line); + return NULL; } void X509_PKEY_free(X509_PKEY *x) diff --git a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl index 3bb0cdf5bd39..42178e455a98 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl @@ -3090,11 +3090,19 @@ $code.=<<___; .align 32 .Lsqrx8x_break: - sub 16+8(%rsp),%r8 # consume last carry + xor $zero,$zero + sub 16+8(%rsp),%rbx # mov 16(%rsp),%cf + adcx $zero,%r8 mov 24+8(%rsp),$carry # initial $tptr, borrow $carry + adcx $zero,%r9 mov 0*8($aptr),%rdx # a[8], modulo-scheduled - xor %ebp,%ebp # xor $zero,$zero + adc \$0,%r10 mov %r8,0*8($tptr) + adc \$0,%r11 + adc \$0,%r12 + adc \$0,%r13 + adc \$0,%r14 + adc \$0,%r15 cmp $carry,$tptr # cf=0, of=0 je .Lsqrx8x_outer_loop diff --git a/crypto/openssl/crypto/bn/bn_exp.c b/crypto/openssl/crypto/bn/bn_exp.c index 195a7867a46b..35facd213a25 100644 --- a/crypto/openssl/crypto/bn/bn_exp.c +++ b/crypto/openssl/crypto/bn/bn_exp.c @@ -145,7 +145,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int i, bits, ret = 0; BIGNUM *v, *rr; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -245,7 +246,9 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { # ifdef MONT_EXP_WORD if (a->top == 1 && !a->neg - && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { BN_ULONG A = a->d[0]; ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); } else @@ -277,7 +280,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -411,7 +416,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_MONT_CTX *mont = NULL; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); } @@ -1217,7 +1224,8 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -1348,7 +1356,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* Table of variables obtained from 'ctx' */ BIGNUM *val[TABLE_SIZE]; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; diff --git a/crypto/openssl/crypto/bn/bn_lib.c b/crypto/openssl/crypto/bn/bn_lib.c index 10b78f512607..f9c65f9f948a 100644 --- a/crypto/openssl/crypto/bn/bn_lib.c +++ b/crypto/openssl/crypto/bn/bn_lib.c @@ -524,6 +524,9 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); #endif + if (BN_get_flags(b, BN_FLG_CONSTTIME) != 0) + BN_set_flags(a, BN_FLG_CONSTTIME); + a->top = b->top; a->neg = b->neg; bn_check_top(a); diff --git a/crypto/openssl/crypto/bn/bn_mont.c b/crypto/openssl/crypto/bn/bn_mont.c index be95bd55d020..3af9db870bcb 100644 --- a/crypto/openssl/crypto/bn/bn_mont.c +++ b/crypto/openssl/crypto/bn/bn_mont.c @@ -394,6 +394,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) tmod.dmax = 2; tmod.neg = 0; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(&tmod, BN_FLG_CONSTTIME); + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) diff --git a/crypto/openssl/crypto/bn/bn_mul.c b/crypto/openssl/crypto/bn/bn_mul.c index 3c618dc30708..6b455a755f71 100644 --- a/crypto/openssl/crypto/bn/bn_mul.c +++ b/crypto/openssl/crypto/bn/bn_mul.c @@ -1032,46 +1032,6 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) rr->top = top; goto end; } -# if 0 - if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)b; - if (bn_wexpand(tmp_bn, al) == NULL) - goto err; - tmp_bn->d[bl] = 0; - bl++; - i--; - } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)a; - if (bn_wexpand(tmp_bn, bl) == NULL) - goto err; - tmp_bn->d[al] = 0; - al++; - i++; - } - if (i == 0) { - /* symmetric and > 4 */ - /* 16 or larger */ - j = BN_num_bits_word((BN_ULONG)al); - j = 1 << (j - 1); - k = j + j; - t = BN_CTX_get(ctx); - if (al == j) { /* exact multiple */ - if (bn_wexpand(t, k * 2) == NULL) - goto err; - if (bn_wexpand(rr, k * 2) == NULL) - goto err; - bn_mul_recursive(rr->d, a->d, b->d, al, t->d); - } else { - if (bn_wexpand(t, k * 4) == NULL) - goto err; - if (bn_wexpand(rr, k * 4) == NULL) - goto err; - bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); - } - rr->top = top; - goto end; - } -# endif } #endif /* BN_RECURSION */ if (bn_wexpand(rr, top) == NULL) diff --git a/crypto/openssl/crypto/bn/bn_x931p.c b/crypto/openssl/crypto/bn/bn_x931p.c index efa48bdf8772..f444af3feabd 100644 --- a/crypto/openssl/crypto/bn/bn_x931p.c +++ b/crypto/openssl/crypto/bn/bn_x931p.c @@ -217,6 +217,8 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) BN_CTX_start(ctx); t = BN_CTX_get(ctx); + if (t == NULL) + goto err; for (i = 0; i < 1000; i++) { if (!BN_rand(Xq, nbits, 1, 0)) @@ -255,10 +257,12 @@ int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, int ret = 0; BN_CTX_start(ctx); - if (!Xp1) + if (Xp1 == NULL) Xp1 = BN_CTX_get(ctx); - if (!Xp2) + if (Xp2 == NULL) Xp2 = BN_CTX_get(ctx); + if (Xp1 == NULL || Xp2 == NULL) + goto error; if (!BN_rand(Xp1, 101, 0, 0)) goto error; diff --git a/crypto/openssl/crypto/cryptlib.c b/crypto/openssl/crypto/cryptlib.c index 1925428f5ec5..5fab45b2ec85 100644 --- a/crypto/openssl/crypto/cryptlib.c +++ b/crypto/openssl/crypto/cryptlib.c @@ -469,11 +469,18 @@ void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) } } +#ifdef OPENSSL_FIPS +extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *)); +#endif + int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) { if (threadid_callback) return 0; threadid_callback = func; +#ifdef OPENSSL_FIPS + FIPS_crypto_threadid_set_callback(func); +#endif return 1; } diff --git a/crypto/openssl/crypto/dh/Makefile b/crypto/openssl/crypto/dh/Makefile index 46fa5ac57b47..cc366ec6fa38 100644 --- a/crypto/openssl/crypto/dh/Makefile +++ b/crypto/openssl/crypto/dh/Makefile @@ -134,7 +134,7 @@ dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h dh_gen.o: ../cryptlib.h dh_gen.c -dh_kdf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +dh_kdf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h dh_kdf.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h dh_kdf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h dh_kdf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h diff --git a/crypto/openssl/crypto/dh/dh.h b/crypto/openssl/crypto/dh/dh.h index a228c7a7a4c3..80b28fb39dc8 100644 --- a/crypto/openssl/crypto/dh/dh.h +++ b/crypto/openssl/crypto/dh/dh.h @@ -257,11 +257,13 @@ DH *DH_get_1024_160(void); DH *DH_get_2048_224(void); DH *DH_get_2048_256(void); +# ifndef OPENSSL_NO_CMS /* RFC2631 KDF */ int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif # define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ diff --git a/crypto/openssl/crypto/dh/dh_kdf.c b/crypto/openssl/crypto/dh/dh_kdf.c index a882cb286e0e..8947a0873152 100644 --- a/crypto/openssl/crypto/dh/dh_kdf.c +++ b/crypto/openssl/crypto/dh/dh_kdf.c @@ -51,6 +51,9 @@ * ==================================================================== */ +#include + +#ifndef OPENSSL_NO_CMS #include #include #include @@ -185,3 +188,4 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, EVP_MD_CTX_cleanup(&mctx); return rv; } +#endif diff --git a/crypto/openssl/crypto/dh/dh_pmeth.c b/crypto/openssl/crypto/dh/dh_pmeth.c index b58e3fa86fad..6452482c87d2 100644 --- a/crypto/openssl/crypto/dh/dh_pmeth.c +++ b/crypto/openssl/crypto/dh/dh_pmeth.c @@ -207,7 +207,11 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; +#ifdef OPENSSL_NO_CMS + if (p1 != EVP_PKEY_DH_KDF_NONE) +#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) +#endif return -2; dctx->kdf_type = p1; return 1; @@ -448,7 +452,9 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, return ret; *keylen = ret; return 1; - } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { + } +#ifndef OPENSSL_NO_CMS + else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; size_t Zlen = 0; if (!dctx->kdf_outlen || !dctx->kdf_oid) @@ -479,6 +485,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, } return ret; } +#endif return 1; } diff --git a/crypto/openssl/crypto/dsa/dsa_ameth.c b/crypto/openssl/crypto/dsa/dsa_ameth.c index c4fa105747fe..aac253095141 100644 --- a/crypto/openssl/crypto/dsa/dsa_ameth.c +++ b/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -258,6 +258,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) goto dsaerr; } + BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); goto dsaerr; diff --git a/crypto/openssl/crypto/dsa/dsa_gen.c b/crypto/openssl/crypto/dsa/dsa_gen.c index 1fce0f81c242..21af2e159fb2 100644 --- a/crypto/openssl/crypto/dsa/dsa_gen.c +++ b/crypto/openssl/crypto/dsa/dsa_gen.c @@ -482,6 +482,8 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, } else { p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); + if (q == NULL) + goto err; } if (!BN_lshift(test, BN_value_one(), L - 1)) diff --git a/crypto/openssl/crypto/dsa/dsa_ossl.c b/crypto/openssl/crypto/dsa/dsa_ossl.c index 58013a4a13b5..aa10dd12f6f8 100644 --- a/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -224,7 +224,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, { BN_CTX *ctx; BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; + BIGNUM l, m; int ret = 0; + int q_bits; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); @@ -233,6 +235,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_init(&k); BN_init(&kq); + BN_init(&l); + BN_init(&m); if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) @@ -243,6 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if ((r = BN_new()) == NULL) goto err; + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q); + if (!BN_set_bit(&k, q_bits) + || !BN_set_bit(&l, q_bits) + || !BN_set_bit(&m, q_bits)) + goto err; + /* Get random k */ do if (!BN_rand_range(&k, dsa->q)) @@ -263,25 +274,24 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, /* Compute r = (g^k mod p) mod q */ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - if (!BN_copy(&kq, &k)) + /* + * We do not want timing information to leak the length of k, so we + * compute G^k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. + */ + if (!BN_add(&l, &k, dsa->q) + || !BN_add(&m, &l, dsa->q) + || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) goto err; BN_set_flags(&kq, BN_FLG_CONSTTIME); - /* - * We do not want timing information to leak the length of k, so we - * compute g^k using an equivalent exponent of fixed length. (This - * is a kludge that we need because the BN_mod_exp_mont() does not - * let us specify the desired timing behaviour.) - */ - - if (!BN_add(&kq, &kq, dsa->q)) - goto err; - if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { - if (!BN_add(&kq, &kq, dsa->q)) - goto err; - } - K = &kq; } else { K = &k; @@ -314,7 +324,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_CTX_free(ctx); BN_clear_free(&k); BN_clear_free(&kq); - return (ret); + BN_clear_free(&l); + BN_clear_free(&m); + return ret; } static int dsa_do_verify(const unsigned char *dgst, int dgst_len, diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl index 7948bf71b51e..35d2b6d146c1 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -1178,19 +1178,18 @@ __ecp_nistz256_sqr_montx: adox $t1, $acc5 .byte 0x67,0x67 mulx %rdx, $t0, $t4 - mov $acc0, %rdx + mov .Lpoly+8*3(%rip), %rdx adox $t0, $acc6 shlx $a_ptr, $acc0, $t0 adox $t4, $acc7 shrx $a_ptr, $acc0, $t4 - mov .Lpoly+8*3(%rip), $t1 + mov %rdx,$t1 # reduction step 1 add $t0, $acc1 adc $t4, $acc2 - mulx $t1, $t0, $acc0 - mov $acc1, %rdx + mulx $acc0, $t0, $acc0 adc $t0, $acc3 shlx $a_ptr, $acc1, $t0 adc \$0, $acc0 @@ -1200,8 +1199,7 @@ __ecp_nistz256_sqr_montx: add $t0, $acc2 adc $t4, $acc3 - mulx $t1, $t0, $acc1 - mov $acc2, %rdx + mulx $acc1, $t0, $acc1 adc $t0, $acc0 shlx $a_ptr, $acc2, $t0 adc \$0, $acc1 @@ -1211,8 +1209,7 @@ __ecp_nistz256_sqr_montx: add $t0, $acc3 adc $t4, $acc0 - mulx $t1, $t0, $acc2 - mov $acc3, %rdx + mulx $acc2, $t0, $acc2 adc $t0, $acc1 shlx $a_ptr, $acc3, $t0 adc \$0, $acc2 @@ -1222,12 +1219,12 @@ __ecp_nistz256_sqr_montx: add $t0, $acc0 adc $t4, $acc1 - mulx $t1, $t0, $acc3 + mulx $acc3, $t0, $acc3 adc $t0, $acc2 adc \$0, $acc3 - xor $t3, $t3 # cf=0 - adc $acc0, $acc4 # accumulate upper half + xor $t3, $t3 + add $acc0, $acc4 # accumulate upper half mov .Lpoly+8*1(%rip), $a_ptr adc $acc1, $acc5 mov $acc4, $acc0 @@ -1236,8 +1233,7 @@ __ecp_nistz256_sqr_montx: mov $acc5, $acc1 adc \$0, $t3 - xor %eax, %eax # cf=0 - sbb \$-1, $acc4 # .Lpoly[0] + sub \$-1, $acc4 # .Lpoly[0] mov $acc6, $acc2 sbb $a_ptr, $acc5 # .Lpoly[1] sbb \$0, $acc6 # .Lpoly[2] diff --git a/crypto/openssl/crypto/ec/ecp_mont.c b/crypto/openssl/crypto/ec/ecp_mont.c index b2de7faea75e..43c4330cb0b7 100644 --- a/crypto/openssl/crypto/ec/ecp_mont.c +++ b/crypto/openssl/crypto/ec/ecp_mont.c @@ -247,6 +247,8 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX_free(new_ctx); if (mont != NULL) BN_MONT_CTX_free(mont); + if (one != NULL) + BN_free(one); return ret; } diff --git a/crypto/openssl/crypto/ec/ecp_nistp224.c b/crypto/openssl/crypto/ec/ecp_nistp224.c index d81cc9ce6b1a..fcd754e44881 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp224.c +++ b/crypto/openssl/crypto/ec/ecp_nistp224.c @@ -716,7 +716,7 @@ static limb felem_is_zero(const felem in) return (zero | two224m96p1 | two225m97p2); } -static limb felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1391,7 +1391,6 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/crypto/openssl/crypto/ec/ecp_nistp256.c b/crypto/openssl/crypto/ec/ecp_nistp256.c index 78d191aac7af..1272966fff84 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp256.c +++ b/crypto/openssl/crypto/ec/ecp_nistp256.c @@ -977,7 +977,7 @@ static limb smallfelem_is_zero(const smallfelem small) return result; } -static int smallfelem_is_zero_int(const smallfelem small) +static int smallfelem_is_zero_int(const void *small) { return (int)(smallfelem_is_zero(small) & ((limb) 1)); } @@ -1979,7 +1979,6 @@ static void make_points_affine(size_t num, smallfelem points[][3], sizeof(smallfelem), tmp_smallfelems, (void (*)(void *))smallfelem_one, - (int (*)(const void *)) smallfelem_is_zero_int, (void (*)(void *, const void *)) smallfelem_assign, diff --git a/crypto/openssl/crypto/ec/ecp_nistp521.c b/crypto/openssl/crypto/ec/ecp_nistp521.c index c53a61bbfb69..a1dc9946fd17 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp521.c +++ b/crypto/openssl/crypto/ec/ecp_nistp521.c @@ -871,7 +871,7 @@ static limb felem_is_zero(const felem in) return is_zero; } -static int felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1787,7 +1787,6 @@ static void make_points_affine(size_t num, felem points[][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/crypto/openssl/crypto/ecdh/ech_lib.c b/crypto/openssl/crypto/ecdh/ech_lib.c index cbc21d1a276e..9cc22582e4ad 100644 --- a/crypto/openssl/crypto/ecdh/ech_lib.c +++ b/crypto/openssl/crypto/ecdh/ech_lib.c @@ -225,9 +225,16 @@ ECDH_DATA *ecdh_check(EC_KEY *key) */ ecdh_data_free(ecdh_data); ecdh_data = (ECDH_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, + ecdh_data_free) != ecdh_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdh_data_free(ecdh_data); + return NULL; } - } else + } else { ecdh_data = (ECDH_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/crypto/openssl/crypto/ecdsa/ecs_lib.c b/crypto/openssl/crypto/ecdsa/ecs_lib.c index 8dc1dda46259..f1dd47231793 100644 --- a/crypto/openssl/crypto/ecdsa/ecs_lib.c +++ b/crypto/openssl/crypto/ecdsa/ecs_lib.c @@ -203,9 +203,16 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key) */ ecdsa_data_free(ecdsa_data); ecdsa_data = (ECDSA_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, + ecdsa_data_free) != ecdsa_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdsa_data_free(ecdsa_data); + return NULL; } - } else + } else { ecdsa_data = (ECDSA_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/crypto/openssl/crypto/ecdsa/ecs_ossl.c b/crypto/openssl/crypto/ecdsa/ecs_ossl.c index dd769609be4c..16d4f59b9ba9 100644 --- a/crypto/openssl/crypto/ecdsa/ecs_ossl.c +++ b/crypto/openssl/crypto/ecdsa/ecs_ossl.c @@ -95,6 +95,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; + int order_bits; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); @@ -126,6 +127,13 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, goto err; } + /* Preallocate space */ + order_bits = BN_num_bits(order); + if (!BN_set_bit(k, order_bits) + || !BN_set_bit(r, order_bits) + || !BN_set_bit(X, order_bits)) + goto err; + do { /* get random k */ do @@ -139,13 +147,19 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, /* * We do not want timing information to leak the length of k, so we * compute G*k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the order. This guarantees the code + * path used in the constant time implementations elsewhere. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(k, k, order)) + if (!BN_add(r, k, order) + || !BN_add(X, r, order) + || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) goto err; - if (BN_num_bits(k) <= BN_num_bits(order)) - if (!BN_add(k, k, order)) - goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { diff --git a/crypto/openssl/crypto/err/err.c b/crypto/openssl/crypto/err/err.c index 0b1fcfc1f1a5..cfe0e8083f39 100644 --- a/crypto/openssl/crypto/err/err.c +++ b/crypto/openssl/crypto/err/err.c @@ -725,6 +725,8 @@ void ERR_put_error(int lib, int func, int reason, const char *file, int line) } #endif es = ERR_get_state(); + if (es == NULL) + return; es->top = (es->top + 1) % ERR_NUM_ERRORS; if (es->top == es->bottom) @@ -742,6 +744,8 @@ void ERR_clear_error(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return; for (i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(es, i); @@ -806,6 +810,8 @@ static unsigned long get_error_values(int inc, int top, const char **file, unsigned long ret; es = ERR_get_state(); + if (es == NULL) + return 0; if (inc && top) { if (file) @@ -1016,7 +1022,6 @@ void ERR_remove_state(unsigned long pid) ERR_STATE *ERR_get_state(void) { - static ERR_STATE fallback; ERR_STATE *ret, tmp, *tmpp = NULL; int i; CRYPTO_THREADID tid; @@ -1030,7 +1035,7 @@ ERR_STATE *ERR_get_state(void) if (ret == NULL) { ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); if (ret == NULL) - return (&fallback); + return NULL; CRYPTO_THREADID_cpy(&ret->tid, &tid); ret->top = 0; ret->bottom = 0; @@ -1042,7 +1047,7 @@ ERR_STATE *ERR_get_state(void) /* To check if insertion failed, do a get. */ if (ERRFN(thread_get_item) (ret) != ret) { ERR_STATE_free(ret); /* could not insert it */ - return (&fallback); + return NULL; } /* * If a race occured in this function and we came second, tmpp is the @@ -1066,10 +1071,10 @@ void ERR_set_error_data(char *data, int flags) int i; es = ERR_get_state(); + if (es == NULL) + return; i = es->top; - if (i == 0) - i = ERR_NUM_ERRORS - 1; err_clear_data(es, i); es->err_data[i] = data; @@ -1121,6 +1126,8 @@ int ERR_set_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; if (es->bottom == es->top) return 0; @@ -1133,6 +1140,8 @@ int ERR_pop_to_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; while (es->bottom != es->top && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { diff --git a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c index d114710e98ec..b25fc6d541d4 100644 --- a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -579,12 +579,17 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c index 917ae0751dee..9a8a2ad7787c 100644 --- a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -507,10 +507,12 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, * to identify it and avoid stitch invocation. So that after we * establish that current CPU supports AVX, we even see if it's * either even XOP-capable Bulldozer-based or GenuineIntel one. + * But SHAEXT-capable go ahead... */ - if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */ - ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ - | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */ + if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */ + ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */ + ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ + | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */ plen > (sha_off + iv) && (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) { SHA256_Update(&key->md, in + iv, sha_off); @@ -590,12 +592,17 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/crypto/openssl/crypto/evp/evp.h b/crypto/openssl/crypto/evp/evp.h index d258ef870a36..cf1de15e6d03 100644 --- a/crypto/openssl/crypto/evp/evp.h +++ b/crypto/openssl/crypto/evp/evp.h @@ -1363,6 +1363,98 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, const char *type, const char *value)); +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + void EVP_add_alg_module(void); /* BEGIN ERROR CODES */ diff --git a/crypto/openssl/crypto/evp/evp_key.c b/crypto/openssl/crypto/evp/evp_key.c index 5be9e336f9e7..cdffe1c8c428 100644 --- a/crypto/openssl/crypto/evp/evp_key.c +++ b/crypto/openssl/crypto/evp/evp_key.c @@ -97,7 +97,7 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify) { - int ret; + int ret = -1; char buff[BUFSIZ]; UI *ui; @@ -105,16 +105,18 @@ int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, prompt = prompt_string; ui = UI_new(); if (ui == NULL) - return -1; - UI_add_input_string(ui, prompt, 0, buf, min, - (len >= BUFSIZ) ? BUFSIZ - 1 : len); - if (verify) - UI_add_verify_string(ui, prompt, 0, - buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len, - buf); + return ret; + if (UI_add_input_string(ui, prompt, 0, buf, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 + || (verify + && UI_add_verify_string(ui, prompt, 0, buff, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len, + buf) < 0)) + goto end; ret = UI_process(ui); - UI_free(ui); OPENSSL_cleanse(buff, BUFSIZ); + end: + UI_free(ui); return ret; } diff --git a/crypto/openssl/crypto/evp/pmeth_lib.c b/crypto/openssl/crypto/evp/pmeth_lib.c index b7b7bdcd0290..e50826b568d8 100644 --- a/crypto/openssl/crypto/evp/pmeth_lib.c +++ b/crypto/openssl/crypto/evp/pmeth_lib.c @@ -589,3 +589,170 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl = ctrl; pmeth->ctrl_str = ctrl_str; } + +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)) +{ + *pinit = pmeth->init; +} + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + *pcopy = pmeth->copy; +} + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)) +{ + *pcleanup = pmeth->cleanup; +} + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pparamgen_init) + *pparamgen_init = pmeth->paramgen_init; + if (pparamgen) + *pparamgen = pmeth->paramgen; +} + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pkeygen_init) + *pkeygen_init = pmeth->keygen_init; + if (pkeygen) + *pkeygen = pmeth->keygen; +} + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (psign_init) + *psign_init = pmeth->sign_init; + if (psign) + *psign = pmeth->sign; +} + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (pverify_init) + *pverify_init = pmeth->verify_init; + if (pverify) + *pverify = pmeth->verify; +} + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + if (pverify_recover_init) + *pverify_recover_init = pmeth->verify_recover_init; + if (pverify_recover) + *pverify_recover = pmeth->verify_recover; +} + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + if (psignctx_init) + *psignctx_init = pmeth->signctx_init; + if (psignctx) + *psignctx = pmeth->signctx; +} + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + if (pverifyctx_init) + *pverifyctx_init = pmeth->verifyctx_init; + if (pverifyctx) + *pverifyctx = pmeth->verifyctx; +} + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pencrypt_init) + *pencrypt_init = pmeth->encrypt_init; + if (pencryptfn) + *pencryptfn = pmeth->encrypt; +} + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pdecrypt_init) + *pdecrypt_init = pmeth->decrypt_init; + if (pdecrypt) + *pdecrypt = pmeth->decrypt; +} + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + if (pderive_init) + *pderive_init = pmeth->derive_init; + if (pderive) + *pderive = pmeth->derive; +} + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + if (pctrl) + *pctrl = pmeth->ctrl; + if (pctrl_str) + *pctrl_str = pmeth->ctrl_str; +} diff --git a/crypto/openssl/crypto/ex_data.c b/crypto/openssl/crypto/ex_data.c index 108a1959eacf..723b21b3d281 100644 --- a/crypto/openssl/crypto/ex_data.c +++ b/crypto/openssl/crypto/ex_data.c @@ -473,7 +473,14 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (j < mx) mx = j; if (mx > 0) { - if (!CRYPTO_set_ex_data(to, mx - 1, NULL)) + /* + * Make sure the ex_data stack is at least |mx| elements long to avoid + * issues in the for loop that follows; so go get the |mx|'th element + * (if it does not exist CRYPTO_get_ex_data() returns NULL), and assign + * to itself. This is normally a no-op; but ensures the stack is the + * proper size + */ + if (!CRYPTO_set_ex_data(to, mx - 1, CRYPTO_get_ex_data(to, mx - 1))) goto skip; storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); if (!storage) diff --git a/crypto/openssl/crypto/lhash/lhash.c b/crypto/openssl/crypto/lhash/lhash.c index f20353aea33f..f3798872598a 100644 --- a/crypto/openssl/crypto/lhash/lhash.c +++ b/crypto/openssl/crypto/lhash/lhash.c @@ -101,6 +101,24 @@ #include #include +/* + * A hashing implementation that appears to be based on the linear hashing + * alogrithm: + * https://en.wikipedia.org/wiki/Linear_hashing + * + * Litwin, Witold (1980), "Linear hashing: A new tool for file and table + * addressing", Proc. 6th Conference on Very Large Databases: 212–223 + * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf + * + * From the wikipedia article "Linear hashing is used in the BDB Berkeley + * database system, which in turn is used by many software systems such as + * OpenLDAP, using a C implementation derived from the CACM article and first + * published on the Usenet in 1988 by Esmond Pitt." + * + * The CACM paper is available here: + * https://pdfs.semanticscholar.org/ff4d/1c5deca6269cc316bfd952172284dbf610ee.pdf + */ + const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #undef MIN_NODES @@ -108,7 +126,7 @@ const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ -static void expand(_LHASH *lh); +static int expand(_LHASH *lh); static void contract(_LHASH *lh); static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); @@ -182,8 +200,9 @@ void *lh_insert(_LHASH *lh, void *data) void *ret; lh->error = 0; - if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) - expand(lh); + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes) + && !expand(lh)) + return NULL; rn = getrn(lh, data, &hash); @@ -300,19 +319,37 @@ void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); } -static void expand(_LHASH *lh) +static int expand(_LHASH *lh) { LHASH_NODE **n, **n1, **n2, *np; - unsigned int p, i, j; - unsigned long hash, nni; + unsigned int p, pmax, nni, j; + unsigned long hash; + + nni = lh->num_alloc_nodes; + p = lh->p; + pmax = lh->pmax; + if (p + 1 >= pmax) { + j = nni * 2; + n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); + if (n == NULL) { + lh->error++; + return 0; + } + lh->b = n; + memset(n + nni, 0, sizeof(*n) * (j - nni)); + lh->pmax = nni; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + } else { + lh->p++; + } lh->num_nodes++; lh->num_expands++; - p = (int)lh->p++; n1 = &(lh->b[p]); - n2 = &(lh->b[p + (int)lh->pmax]); - *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ - nni = lh->num_alloc_nodes; + n2 = &(lh->b[p + pmax]); + *n2 = NULL; for (np = *n1; np != NULL;) { #ifndef OPENSSL_NO_HASH_COMP @@ -330,25 +367,7 @@ static void expand(_LHASH *lh) np = *n1; } - if ((lh->p) >= lh->pmax) { - j = (int)lh->num_alloc_nodes * 2; - n = (LHASH_NODE **)OPENSSL_realloc(lh->b, - (int)(sizeof(LHASH_NODE *) * j)); - if (n == NULL) { - lh->error++; - lh->num_nodes--; - lh->p = 0; - return; - } - /* else */ - for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */ - n[i] = NULL; /* 02/03/92 eay */ - lh->pmax = lh->num_alloc_nodes; - lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; - lh->p = 0; - lh->b = n; - } + return 1; } static void contract(_LHASH *lh) diff --git a/crypto/openssl/crypto/ocsp/ocsp_vfy.c b/crypto/openssl/crypto/ocsp/ocsp_vfy.c index d4a257c33bb5..7a7d06094edf 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_vfy.c +++ b/crypto/openssl/crypto/ocsp/ocsp_vfy.c @@ -118,6 +118,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, goto end; } } + } else if (certs != NULL) { + untrusted = certs; } else { untrusted = bs->certs; } diff --git a/crypto/openssl/crypto/opensslv.h b/crypto/openssl/crypto/opensslv.h index 9eae57ca8ae5..83867763cab3 100644 --- a/crypto/openssl/crypto/opensslv.h +++ b/crypto/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x100020cfL +# define OPENSSL_VERSION_NUMBER 0x100020dfL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-fips 2 Nov 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-freebsd 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-freebsd 2 Nov 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/crypto/openssl/crypto/pem/pem_lib.c b/crypto/openssl/crypto/pem/pem_lib.c index c82b3c0ae263..865976bf8cce 100644 --- a/crypto/openssl/crypto/pem/pem_lib.c +++ b/crypto/openssl/crypto/pem/pem_lib.c @@ -536,7 +536,8 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) ((c >= '0') && (c <= '9')))) break; #else - if (!(isupper(c) || (c == '-') || isdigit(c))) + if (!(isupper((unsigned char)c) || (c == '-') + || isdigit((unsigned char)c))) break; #endif header++; diff --git a/crypto/openssl/crypto/pem/pem_pk8.c b/crypto/openssl/crypto/pem/pem_pk8.c index 5747c7366e3d..daf210fde0f9 100644 --- a/crypto/openssl/crypto/pem/pem_pk8.c +++ b/crypto/openssl/crypto/pem/pem_pk8.c @@ -178,6 +178,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) return NULL; ret = EVP_PKCS82PKEY(p8inf); diff --git a/crypto/openssl/crypto/pem/pem_pkey.c b/crypto/openssl/crypto/pem/pem_pkey.c index 04d6319a225b..e8b3a1b92c8d 100644 --- a/crypto/openssl/crypto/pem/pem_pkey.c +++ b/crypto/openssl/crypto/pem/pem_pkey.c @@ -120,6 +120,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); diff --git a/crypto/openssl/crypto/pkcs12/p12_kiss.c b/crypto/openssl/crypto/pkcs12/p12_kiss.c index 9aa3c90c4e57..1841f78f6915 100644 --- a/crypto/openssl/crypto/pkcs12/p12_kiss.c +++ b/crypto/openssl/crypto/pkcs12/p12_kiss.c @@ -84,6 +84,12 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, { STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; + + if (pkey) + *pkey = NULL; + if (cert) + *cert = NULL; + /* Check for NULL PKCS12 structure */ if (!p12) { @@ -92,11 +98,6 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, return 0; } - if (pkey) - *pkey = NULL; - if (cert) - *cert = NULL; - /* Check the mac */ /* @@ -125,7 +126,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, if (!ocerts) { PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { @@ -163,10 +164,14 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, err: - if (pkey && *pkey) + if (pkey) { EVP_PKEY_free(*pkey); - if (cert && *cert) + *pkey = NULL; + } + if (cert) { X509_free(*cert); + *cert = NULL; + } if (x) X509_free(x); if (ocerts) diff --git a/crypto/openssl/crypto/rsa/rsa_ameth.c b/crypto/openssl/crypto/rsa/rsa_ameth.c index 951e1d5ca32b..ddead3d74455 100644 --- a/crypto/openssl/crypto/rsa/rsa_ameth.c +++ b/crypto/openssl/crypto/rsa/rsa_ameth.c @@ -768,6 +768,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } +#ifndef OPENSSL_NO_CMS static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash) { @@ -791,7 +792,6 @@ static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, return pss; } -#ifndef OPENSSL_NO_CMS static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; diff --git a/crypto/openssl/crypto/rsa/rsa_oaep.c b/crypto/openssl/crypto/rsa/rsa_oaep.c index 19d28c6f0e60..9a01b4afc11f 100644 --- a/crypto/openssl/crypto/rsa/rsa_oaep.c +++ b/crypto/openssl/crypto/rsa/rsa_oaep.c @@ -237,10 +237,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR); cleanup: - if (db != NULL) + if (db != NULL) { + OPENSSL_cleanse(db, dblen); OPENSSL_free(db); - if (em != NULL) + } + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } return mlen; } diff --git a/crypto/openssl/crypto/rsa/rsa_pk1.c b/crypto/openssl/crypto/rsa/rsa_pk1.c index efa1fd3e993f..50397c335a5a 100644 --- a/crypto/openssl/crypto/rsa/rsa_pk1.c +++ b/crypto/openssl/crypto/rsa/rsa_pk1.c @@ -255,8 +255,6 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, * We can't continue in constant-time because we need to copy the result * and we cannot fake its length. This unavoidably leaks timing * information at the API boundary. - * TODO(emilia): this could be addressed at the call site, - * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. */ if (!good) { mlen = -1; @@ -266,8 +264,10 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, memcpy(to, em + msg_index, mlen); err: - if (em != NULL) + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } if (mlen == -1) RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); diff --git a/crypto/openssl/crypto/rsa/rsa_pmeth.c b/crypto/openssl/crypto/rsa/rsa_pmeth.c index 8896e2e97714..00e730ffa958 100644 --- a/crypto/openssl/crypto/rsa/rsa_pmeth.c +++ b/crypto/openssl/crypto/rsa/rsa_pmeth.c @@ -180,27 +180,25 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) * FIPS mode. */ -static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) +static int pkey_fips_check_rsa(const RSA *rsa, const EVP_MD **pmd, + const EVP_MD **pmgf1md) { - RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; int rv = -1; + if (!FIPS_mode()) return 0; if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) rv = 0; if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) return -1; - if (rctx->md) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmd != NULL) { + *pmd = FIPS_get_digestbynid(EVP_MD_type(*pmd)); + if (*pmd == NULL || !((*pmd)->flags & EVP_MD_FLAG_FIPS)) return rv; } - if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmgf1md != NULL) { + *pmgf1md = FIPS_get_digestbynid(EVP_MD_type(*pmgf1md)); + if (*pmgf1md == NULL || !((*pmgf1md)->flags & EVP_MD_FLAG_FIPS)) return rv; } return 1; @@ -214,27 +212,27 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; #ifdef OPENSSL_FIPS - ret = pkey_fips_check_ctx(ctx); + ret = pkey_fips_check_rsa(rsa, &md, &mgf1md); if (ret < 0) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (md != NULL) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } #ifdef OPENSSL_FIPS if (ret > 0) { unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, &slen); + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, &slen); if (ret > 0) *siglen = slen; else @@ -243,12 +241,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, } #endif - if (EVP_MD_type(rctx->md) == NID_mdc2) { + if (EVP_MD_type(md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; - ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, + rsa); if (ret <= 0) return ret; @@ -263,23 +261,20 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, return -1; } memcpy(rctx->tbuf, tbs, tbslen); - rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; - ret = RSA_sign(EVP_MD_type(rctx->md), - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign(EVP_MD_type(md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; - if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, - rctx->tbuf, tbs, - rctx->md, rctx->mgf1md, - rctx->saltlen)) + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, + md, mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); @@ -348,32 +343,31 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; size_t rslen; + #ifdef OPENSSL_FIPS - int rv; - rv = pkey_fips_check_ctx(ctx); + int rv = pkey_fips_check_rsa(rsa, &md, &mgf1md); + if (rv < 0) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { + if (md != NULL) { #ifdef OPENSSL_FIPS if (rv > 0) { - return FIPS_rsa_verify_digest(rsa, - tbs, tbslen, - rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, siglen); + return FIPS_rsa_verify_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, siglen); } #endif if (rctx->pad_mode == RSA_PKCS1_PADDING) - return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + return RSA_verify(EVP_MD_type(md), tbs, tbslen, sig, siglen, rsa); - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); return -1; } @@ -388,8 +382,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, rsa, RSA_NO_PADDING); if (ret <= 0) return 0; - ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, - rctx->md, rctx->mgf1md, + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, md, mgf1md, rctx->tbuf, rctx->saltlen); if (ret <= 0) return 0; diff --git a/crypto/openssl/crypto/ui/ui_lib.c b/crypto/openssl/crypto/ui/ui_lib.c index 643ae593439a..03ef981cf912 100644 --- a/crypto/openssl/crypto/ui/ui_lib.c +++ b/crypto/openssl/crypto/ui/ui_lib.c @@ -520,6 +520,7 @@ int UI_process(UI *ui) } } } + err: if (ui->meth->ui_close_session != NULL && ui->meth->ui_close_session(ui) <= 0) diff --git a/crypto/openssl/crypto/whrlpool/wp_dgst.c b/crypto/openssl/crypto/whrlpool/wp_dgst.c index 807d1c49b2d3..96d042f5859e 100644 --- a/crypto/openssl/crypto/whrlpool/wp_dgst.c +++ b/crypto/openssl/crypto/whrlpool/wp_dgst.c @@ -166,7 +166,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) goto reconsider; } else #endif - if (bits >= 8) { + if (bits > 8) { b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); b &= 0xff; if (bitrem) @@ -183,7 +183,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) } if (bitrem) c->data[byteoff] = b << (8 - bitrem); - } else { /* remaining less than 8 bits */ + } else { /* remaining less than or equal to 8 bits */ b = (inp[0] << inpgap) & 0xff; if (bitrem) diff --git a/crypto/openssl/crypto/x509/by_dir.c b/crypto/openssl/crypto/x509/by_dir.c index bbc3189381e5..6f0209a275ef 100644 --- a/crypto/openssl/crypto/x509/by_dir.c +++ b/crypto/openssl/crypto/x509/by_dir.c @@ -402,6 +402,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, if (!hent) { hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); if (hent == NULL) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); goto finish; } diff --git a/crypto/openssl/crypto/x509/by_file.c b/crypto/openssl/crypto/x509/by_file.c index 43a073003d8b..82ce4e8d87c3 100644 --- a/crypto/openssl/crypto/x509/by_file.c +++ b/crypto/openssl/crypto/x509/by_file.c @@ -92,12 +92,12 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) { int ok = 0; - char *file; + const char *file; switch (cmd) { case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = (char *)getenv(X509_get_default_cert_file_env()); + file = getenv(X509_get_default_cert_file_env()); if (file) ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); @@ -140,7 +140,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -199,7 +199,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -253,7 +253,7 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); BIO_free(in); if (!inf) { X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); diff --git a/crypto/openssl/crypto/x509v3/pcy_tree.c b/crypto/openssl/crypto/x509v3/pcy_tree.c index 09b8691c8694..03c9533bcca9 100644 --- a/crypto/openssl/crypto/x509v3/pcy_tree.c +++ b/crypto/openssl/crypto/x509v3/pcy_tree.c @@ -732,6 +732,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) { int ret; + int calc_ret; X509_POLICY_TREE *tree = NULL; STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; *ptree = NULL; @@ -800,16 +801,19 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, /* Tree is not empty: continue */ - ret = tree_calculate_authority_set(tree, &auth_nodes); + calc_ret = tree_calculate_authority_set(tree, &auth_nodes); + + if (!calc_ret) + goto error; + + ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); + + if (calc_ret == 2) + sk_X509_POLICY_NODE_free(auth_nodes); if (!ret) goto error; - if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) - goto error; - - if (ret == 2) - sk_X509_POLICY_NODE_free(auth_nodes); if (tree) *ptree = tree; diff --git a/crypto/openssl/crypto/x509v3/v3_addr.c b/crypto/openssl/crypto/x509v3/v3_addr.c index 1290dec9bb8c..af080a04f2ba 100644 --- a/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/crypto/openssl/crypto/x509v3/v3_addr.c @@ -130,10 +130,12 @@ static int length_from_afi(const unsigned afi) */ unsigned int v3_addr_get_afi(const IPAddressFamily *f) { - return ((f != NULL && - f->addressFamily != NULL && f->addressFamily->data != NULL) - ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) - : 0); + if (f == NULL + || f->addressFamily == NULL + || f->addressFamily->data == NULL + || f->addressFamily->length < 2) + return 0; + return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; } /* diff --git a/crypto/openssl/crypto/x509v3/v3_genn.c b/crypto/openssl/crypto/x509v3/v3_genn.c index 7f40bfabe050..9bb01ee38e63 100644 --- a/crypto/openssl/crypto/x509v3/v3_genn.c +++ b/crypto/openssl/crypto/x509v3/v3_genn.c @@ -231,6 +231,7 @@ int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, oth = OTHERNAME_new(); if (!oth) return 0; + ASN1_TYPE_free(oth->value); oth->type_id = oid; oth->value = value; GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); diff --git a/crypto/openssl/crypto/x509v3/v3_ncons.c b/crypto/openssl/crypto/x509v3/v3_ncons.c index 2855269668be..1184091ccf30 100644 --- a/crypto/openssl/crypto/x509v3/v3_ncons.c +++ b/crypto/openssl/crypto/x509v3/v3_ncons.c @@ -107,6 +107,47 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) +/* + * We cannot use strncasecmp here because that applies locale specific rules. + * For example in Turkish 'I' is not the uppercase character for 'i'. We need to + * do a simple ASCII case comparison ignoring the locale (that is why we use + * numeric constants below). + */ +static int ia5ncasecmp(const char *s1, const char *s2, size_t n) +{ + for (; n > 0; n--, s1++, s2++) { + if (*s1 != *s2) { + unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2; + + /* Convert to lower case */ + if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */) + c1 += 0x20; + if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */) + c2 += 0x20; + + if (c1 == c2) + continue; + + if (c1 < c2) + return -1; + + /* c1 > c2 */ + return 1; + } else if (*s1 == 0) { + /* If we get here we know that *s2 == 0 too */ + return 0; + } + } + + return 0; +} + +static int ia5casecmp(const char *s1, const char *s2) +{ + /* No portable definition of SIZE_MAX, so we use (size_t)(-1) instead */ + return ia5ncasecmp(s1, s2, (size_t)(-1)); +} + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { @@ -384,7 +425,7 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) return X509_V_ERR_PERMITTED_VIOLATION; } - if (strcasecmp(baseptr, dnsptr)) + if (ia5casecmp(baseptr, dnsptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -404,7 +445,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) if (!baseat && (*baseptr == '.')) { if (eml->length > base->length) { emlptr += eml->length - base->length; - if (!strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; @@ -425,7 +466,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) } emlptr = emlat + 1; /* Just have hostname left to match: case insensitive */ - if (strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -464,14 +505,14 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) if (*baseptr == '.') { if (hostlen > base->length) { p = hostptr + hostlen - base->length; - if (!strncasecmp(p, baseptr, base->length)) + if (ia5ncasecmp(p, baseptr, base->length) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; } if ((base->length != (int)hostlen) - || strncasecmp(hostptr, baseptr, hostlen)) + || ia5ncasecmp(hostptr, baseptr, hostlen)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; diff --git a/crypto/openssl/crypto/x86_64cpuid.pl b/crypto/openssl/crypto/x86_64cpuid.pl index a3d6f438f91e..ef3608b13495 100644 --- a/crypto/openssl/crypto/x86_64cpuid.pl +++ b/crypto/openssl/crypto/x86_64cpuid.pl @@ -136,8 +136,19 @@ OPENSSL_ia32_cpuid: or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs and \$15,%ah cmp \$15,%ah # examine Family ID - jne .Lnotintel + jne .LnotP4 or \$0x00100000,%edx # set reserved bit#20 to engage RC4_CHAR +.LnotP4: + cmp \$6,%ah + jne .Lnotintel + and \$0x0fff0ff0,%eax + cmp \$0x00050670,%eax # Knights Landing + je .Lknights + cmp \$0x00080650,%eax # Knights Mill (according to sde) + jne .Lnotintel +.Lknights: + and \$0xfbffffff,%ecx # clear XSAVE flag to mimic Silvermont + .Lnotintel: bt \$28,%edx # test hyper-threading bit jnc .Lgeneric @@ -162,6 +173,10 @@ OPENSSL_ia32_cpuid: mov \$7,%eax xor %ecx,%ecx cpuid + bt \$26,%r9d # check XSAVE bit, cleared on Knights + jc .Lnotknights + and \$0xfff7ffff,%ebx # clear ADCX/ADOX flag +.Lnotknights: mov %ebx,8(%rdi) # save extended feature flags .Lno_extended_info: @@ -175,7 +190,7 @@ OPENSSL_ia32_cpuid: .Lclear_avx: mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11) and %eax,%r9d # clear AVX, FMA and AMD XOP bits - andl \$0xffffffdf,8(%rdi) # cleax AVX2, ~(1<<5) + andl \$0xffffffdf,8(%rdi) # clear AVX2, ~(1<<5) .Ldone: shl \$32,%r9 mov %r10d,%eax diff --git a/crypto/openssl/doc/apps/asn1parse.pod b/crypto/openssl/doc/apps/asn1parse.pod index 76a765daf95b..a84dbc37dc89 100644 --- a/crypto/openssl/doc/apps/asn1parse.pod +++ b/crypto/openssl/doc/apps/asn1parse.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-asn1parse, asn1parse - ASN.1 parsing tool =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ca.pod b/crypto/openssl/doc/apps/ca.pod index f600f553b1a7..bd1acc88f35c 100644 --- a/crypto/openssl/doc/apps/ca.pod +++ b/crypto/openssl/doc/apps/ca.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-ca, ca - sample minimal CA application =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ciphers.pod b/crypto/openssl/doc/apps/ciphers.pod index 35d40bbf27ae..fa16124d08b8 100644 --- a/crypto/openssl/doc/apps/ciphers.pod +++ b/crypto/openssl/doc/apps/ciphers.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ciphers, ciphers - SSL cipher display and cipher list tool. =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/cms.pod b/crypto/openssl/doc/apps/cms.pod index ac69804228cc..4a7783d47a4e 100644 --- a/crypto/openssl/doc/apps/cms.pod +++ b/crypto/openssl/doc/apps/cms.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-cms, cms - CMS utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/crl.pod b/crypto/openssl/doc/apps/crl.pod index 044a9da91545..cdced1c742c0 100644 --- a/crypto/openssl/doc/apps/crl.pod +++ b/crypto/openssl/doc/apps/crl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-crl, crl - CRL utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/crl2pkcs7.pod b/crypto/openssl/doc/apps/crl2pkcs7.pod index 3797bc0df4ef..18654c5afa0e 100644 --- a/crypto/openssl/doc/apps/crl2pkcs7.pod +++ b/crypto/openssl/doc/apps/crl2pkcs7.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-crl2pkcs7, crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates. =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/dgst.pod b/crypto/openssl/doc/apps/dgst.pod index 9d2bf2173715..1c0c51333a18 100644 --- a/crypto/openssl/doc/apps/dgst.pod +++ b/crypto/openssl/doc/apps/dgst.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dgst, dgst, sha, sha1, mdc2, ripemd160, sha224, sha256, sha384, sha512, md2, md4, md5, dss1 - message digests =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/dhparam.pod b/crypto/openssl/doc/apps/dhparam.pod index 1cd4c76663c5..018d9935085a 100644 --- a/crypto/openssl/doc/apps/dhparam.pod +++ b/crypto/openssl/doc/apps/dhparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dhparam, dhparam - DH parameter manipulation and generation =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/dsa.pod b/crypto/openssl/doc/apps/dsa.pod index 8bf6cc9dcad6..77d66089beac 100644 --- a/crypto/openssl/doc/apps/dsa.pod +++ b/crypto/openssl/doc/apps/dsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dsa, dsa - DSA key processing =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/dsaparam.pod b/crypto/openssl/doc/apps/dsaparam.pod index ba5ec4d72cdf..446903491357 100644 --- a/crypto/openssl/doc/apps/dsaparam.pod +++ b/crypto/openssl/doc/apps/dsaparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dsaparam, dsaparam - DSA parameter manipulation and generation =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ec.pod b/crypto/openssl/doc/apps/ec.pod index 5c7b45d4e75e..658eac5d509f 100644 --- a/crypto/openssl/doc/apps/ec.pod +++ b/crypto/openssl/doc/apps/ec.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ec, ec - EC key processing =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ecparam.pod b/crypto/openssl/doc/apps/ecparam.pod index 88e9d1e83d02..ba2f3b9ae274 100644 --- a/crypto/openssl/doc/apps/ecparam.pod +++ b/crypto/openssl/doc/apps/ecparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ecparam, ecparam - EC parameter manipulation and generation =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/enc.pod b/crypto/openssl/doc/apps/enc.pod index 41791ad6713c..aceafcd4d557 100644 --- a/crypto/openssl/doc/apps/enc.pod +++ b/crypto/openssl/doc/apps/enc.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-enc, enc - symmetric cipher routines =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/errstr.pod b/crypto/openssl/doc/apps/errstr.pod index b3c6ccfc9cbd..0dee51c844ef 100644 --- a/crypto/openssl/doc/apps/errstr.pod +++ b/crypto/openssl/doc/apps/errstr.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-errstr, errstr - lookup error codes =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/gendsa.pod b/crypto/openssl/doc/apps/gendsa.pod index d9f56be890f8..2c8e5c86f208 100644 --- a/crypto/openssl/doc/apps/gendsa.pod +++ b/crypto/openssl/doc/apps/gendsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-gendsa, gendsa - generate a DSA private key from a set of parameters =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/genpkey.pod b/crypto/openssl/doc/apps/genpkey.pod index 929edcd26ff0..4d09fc0937c5 100644 --- a/crypto/openssl/doc/apps/genpkey.pod +++ b/crypto/openssl/doc/apps/genpkey.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-genpkey, genpkey - generate a private key =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/genrsa.pod b/crypto/openssl/doc/apps/genrsa.pod index f4ed9593ae26..8be06834f507 100644 --- a/crypto/openssl/doc/apps/genrsa.pod +++ b/crypto/openssl/doc/apps/genrsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-genrsa, genrsa - generate an RSA private key =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/nseq.pod b/crypto/openssl/doc/apps/nseq.pod index 989c3108fb83..de441fa87a4d 100644 --- a/crypto/openssl/doc/apps/nseq.pod +++ b/crypto/openssl/doc/apps/nseq.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-nseq, nseq - create or examine a netscape certificate sequence =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ocsp.pod b/crypto/openssl/doc/apps/ocsp.pod index 1bb7958d20e5..9e2716f00820 100644 --- a/crypto/openssl/doc/apps/ocsp.pod +++ b/crypto/openssl/doc/apps/ocsp.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ocsp, ocsp - Online Certificate Status Protocol utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/passwd.pod b/crypto/openssl/doc/apps/passwd.pod index f44982549bf1..7f74ce016d92 100644 --- a/crypto/openssl/doc/apps/passwd.pod +++ b/crypto/openssl/doc/apps/passwd.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-passwd, passwd - compute password hashes =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkcs12.pod b/crypto/openssl/doc/apps/pkcs12.pod index 744984838dc7..debc9ea27a27 100644 --- a/crypto/openssl/doc/apps/pkcs12.pod +++ b/crypto/openssl/doc/apps/pkcs12.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkcs12, pkcs12 - PKCS#12 file utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkcs7.pod b/crypto/openssl/doc/apps/pkcs7.pod index acfb8100f078..651e9371c105 100644 --- a/crypto/openssl/doc/apps/pkcs7.pod +++ b/crypto/openssl/doc/apps/pkcs7.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkcs7, pkcs7 - PKCS#7 utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkcs8.pod b/crypto/openssl/doc/apps/pkcs8.pod index 6901f1f3f211..f741741e5ad2 100644 --- a/crypto/openssl/doc/apps/pkcs8.pod +++ b/crypto/openssl/doc/apps/pkcs8.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkcs8, pkcs8 - PKCS#8 format private key conversion tool =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkey.pod b/crypto/openssl/doc/apps/pkey.pod index 4851223f3fcd..6db8a6238393 100644 --- a/crypto/openssl/doc/apps/pkey.pod +++ b/crypto/openssl/doc/apps/pkey.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkey, pkey - public or private key processing tool =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkeyparam.pod b/crypto/openssl/doc/apps/pkeyparam.pod index 154f6721af4a..27c10a6a745c 100644 --- a/crypto/openssl/doc/apps/pkeyparam.pod +++ b/crypto/openssl/doc/apps/pkeyparam.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkeyparam, pkeyparam - public key algorithm parameter processing tool =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/pkeyutl.pod b/crypto/openssl/doc/apps/pkeyutl.pod index 5da347c97d32..78b3b02a7d96 100644 --- a/crypto/openssl/doc/apps/pkeyutl.pod +++ b/crypto/openssl/doc/apps/pkeyutl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkeyutl, pkeyutl - public key algorithm utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/rand.pod b/crypto/openssl/doc/apps/rand.pod index d1d213ef43cb..94df10d939e0 100644 --- a/crypto/openssl/doc/apps/rand.pod +++ b/crypto/openssl/doc/apps/rand.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-rand, rand - generate pseudo-random bytes =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/req.pod b/crypto/openssl/doc/apps/req.pod index 1682ba5143dd..20b2f39e90f2 100644 --- a/crypto/openssl/doc/apps/req.pod +++ b/crypto/openssl/doc/apps/req.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-req, req - PKCS#10 certificate request and certificate generating utility. =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/rsa.pod b/crypto/openssl/doc/apps/rsa.pod index 21cbf8ee009b..7e43e0f3d062 100644 --- a/crypto/openssl/doc/apps/rsa.pod +++ b/crypto/openssl/doc/apps/rsa.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-rsa, rsa - RSA key processing tool =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/rsautl.pod b/crypto/openssl/doc/apps/rsautl.pod index 1a498c2f62e0..e16ce29cf609 100644 --- a/crypto/openssl/doc/apps/rsautl.pod +++ b/crypto/openssl/doc/apps/rsautl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-rsautl, rsautl - RSA utility =head1 SYNOPSIS @@ -105,7 +106,7 @@ Recover the signed data Examine the raw signed data: - openssl rsautl -verify -in file -inkey key.pem -raw -hexdump + openssl rsautl -verify -in sig -inkey key.pem -raw -hexdump 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ diff --git a/crypto/openssl/doc/apps/s_client.pod b/crypto/openssl/doc/apps/s_client.pod index b45acbc5e3e4..d9413a0cf211 100644 --- a/crypto/openssl/doc/apps/s_client.pod +++ b/crypto/openssl/doc/apps/s_client.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_client, s_client - SSL/TLS client program =head1 SYNOPSIS @@ -197,12 +198,14 @@ Can be used to override the implicit B<-ign_eof> after B<-quiet>. =item B<-psk_identity identity> Use the PSK identity B when using a PSK cipher suite. +The default value is "Client_identity" (without the quotes). =item B<-psk key> Use the PSK key B when using a PSK cipher suite. The key is given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. +This option must be provided in order to use a PSK cipher. =item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> diff --git a/crypto/openssl/doc/apps/s_server.pod b/crypto/openssl/doc/apps/s_server.pod index 1fe93ddfbebb..9916fc3ef6a3 100644 --- a/crypto/openssl/doc/apps/s_server.pod +++ b/crypto/openssl/doc/apps/s_server.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_server, s_server - SSL/TLS server program =head1 SYNOPSIS @@ -219,6 +220,7 @@ Use the PSK identity hint B when using a PSK cipher suite. Use the PSK key B when using a PSK cipher suite. The key is given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. +This option must be provided in order to use a PSK cipher. =item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> @@ -403,10 +405,6 @@ a web browser the command: can be used for example. -Most web browsers (in particular Netscape and MSIE) only support RSA cipher -suites, so they cannot connect to servers which don't use a certificate -carrying an RSA key or a version of OpenSSL with RSA disabled. - Although specifying an empty list of CAs when requesting a client certificate is strictly speaking a protocol violation, some SSL clients interpret this to mean any CA is acceptable. This is useful for debugging purposes. diff --git a/crypto/openssl/doc/apps/s_time.pod b/crypto/openssl/doc/apps/s_time.pod index 9082d876feeb..1fa02800a419 100644 --- a/crypto/openssl/doc/apps/s_time.pod +++ b/crypto/openssl/doc/apps/s_time.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_time, s_time - SSL/TLS performance timing program =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/sess_id.pod b/crypto/openssl/doc/apps/sess_id.pod index 9988d2cd3d5d..0771baef1173 100644 --- a/crypto/openssl/doc/apps/sess_id.pod +++ b/crypto/openssl/doc/apps/sess_id.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-sess_id, sess_id - SSL/TLS session handling utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/smime.pod b/crypto/openssl/doc/apps/smime.pod index 04a83ca8e427..fbf60da27faf 100644 --- a/crypto/openssl/doc/apps/smime.pod +++ b/crypto/openssl/doc/apps/smime.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-smime, smime - S/MIME utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/speed.pod b/crypto/openssl/doc/apps/speed.pod index 1cd1998d1675..2bfe91e371cb 100644 --- a/crypto/openssl/doc/apps/speed.pod +++ b/crypto/openssl/doc/apps/speed.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-speed, speed - test library performance =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/spkac.pod b/crypto/openssl/doc/apps/spkac.pod index 97fb80e4016b..b8a5477a063e 100644 --- a/crypto/openssl/doc/apps/spkac.pod +++ b/crypto/openssl/doc/apps/spkac.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-spkac, spkac - SPKAC printing and generating utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/ts.pod b/crypto/openssl/doc/apps/ts.pod index d6aa47d3144d..5da019b2eb2f 100644 --- a/crypto/openssl/doc/apps/ts.pod +++ b/crypto/openssl/doc/apps/ts.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ts, ts - Time Stamping Authority tool (client/server) =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/tsget.pod b/crypto/openssl/doc/apps/tsget.pod index 56db985c4bb1..4856c850d8e1 100644 --- a/crypto/openssl/doc/apps/tsget.pod +++ b/crypto/openssl/doc/apps/tsget.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-tsget, tsget - Time Stamping HTTP/HTTPS client =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/verify.pod b/crypto/openssl/doc/apps/verify.pod index b3767325ae07..321d5ac7e126 100644 --- a/crypto/openssl/doc/apps/verify.pod +++ b/crypto/openssl/doc/apps/verify.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-verify, verify - Utility to verify certificates. =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/version.pod b/crypto/openssl/doc/apps/version.pod index 58f543bc3e64..675b0f84d6a7 100644 --- a/crypto/openssl/doc/apps/version.pod +++ b/crypto/openssl/doc/apps/version.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-version, version - print OpenSSL version information =head1 SYNOPSIS diff --git a/crypto/openssl/doc/apps/x509.pod b/crypto/openssl/doc/apps/x509.pod index 10e49e5b88b2..aed22259f045 100644 --- a/crypto/openssl/doc/apps/x509.pod +++ b/crypto/openssl/doc/apps/x509.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-x509, x509 - Certificate display and signing utility =head1 SYNOPSIS diff --git a/crypto/openssl/doc/crypto/BN_bn2bin.pod b/crypto/openssl/doc/crypto/BN_bn2bin.pod index 3bed47f8f1d5..f6bb484f902f 100644 --- a/crypto/openssl/doc/crypto/BN_bn2bin.pod +++ b/crypto/openssl/doc/crypto/BN_bn2bin.pod @@ -70,8 +70,9 @@ BN_bn2bin() returns the length of the big-endian number placed at B. BN_bin2bn() returns the B, NULL on error. BN_bn2hex() and BN_bn2dec() return a null-terminated string, or NULL -on error. BN_hex2bn() and BN_dec2bn() return the number's length in -hexadecimal or decimal digits, and 0 on error. +on error. BN_hex2bn() and BN_dec2bn() return the number of characters +used in parsing, or 0 on error, in which +case no new B will be created. BN_print_fp() and BN_print() return 1 on success, 0 on write errors. diff --git a/crypto/openssl/doc/crypto/BN_new.pod b/crypto/openssl/doc/crypto/BN_new.pod index ab7a105e3ad7..d446603191af 100644 --- a/crypto/openssl/doc/crypto/BN_new.pod +++ b/crypto/openssl/doc/crypto/BN_new.pod @@ -30,10 +30,12 @@ to the value 0. BN_free() frees the components of the B, and if it was created by BN_new(), also the structure itself. BN_clear_free() additionally overwrites the data before the memory is returned to the system. +If B is NULL, nothing is done. =head1 RETURN VALUES -BN_new() returns a pointer to the B. If the allocation fails, +BN_new() returns a pointer to the B initialised to the value 0. +If the allocation fails, it returns B and sets an error code that can be obtained by L. diff --git a/crypto/openssl/doc/crypto/EVP_EncryptInit.pod b/crypto/openssl/doc/crypto/EVP_EncryptInit.pod index 28ab53507d2d..b19d7887345f 100644 --- a/crypto/openssl/doc/crypto/EVP_EncryptInit.pod +++ b/crypto/openssl/doc/crypto/EVP_EncryptInit.pod @@ -395,8 +395,7 @@ processed (e.g. after an EVP_EncryptFinal() call). EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag); Sets the expected tag to B bytes from B. This call is only legal -when decrypting data and must be made B any data is processed (e.g. -before any EVP_DecryptUpdate() call). +when decrypting data. =head1 CCM Mode diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_meth_new.pod b/crypto/openssl/doc/crypto/EVP_PKEY_meth_new.pod new file mode 100644 index 000000000000..041492a8f0fb --- /dev/null +++ b/crypto/openssl/doc/crypto/EVP_PKEY_meth_new.pod @@ -0,0 +1,376 @@ +=pod + +=head1 NAME + +EVP_PKEY_meth_new, EVP_PKEY_meth_free, EVP_PKEY_meth_copy, EVP_PKEY_meth_find, +EVP_PKEY_meth_add0, EVP_PKEY_METHOD, +EVP_PKEY_meth_set_init, EVP_PKEY_meth_set_copy, EVP_PKEY_meth_set_cleanup, +EVP_PKEY_meth_set_paramgen, EVP_PKEY_meth_set_keygen, EVP_PKEY_meth_set_sign, +EVP_PKEY_meth_set_verify, EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_signctx, +EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt, EVP_PKEY_meth_set_decrypt, +EVP_PKEY_meth_set_derive, EVP_PKEY_meth_set_ctrl, +EVP_PKEY_meth_get_init, EVP_PKEY_meth_get_copy, EVP_PKEY_meth_get_cleanup, +EVP_PKEY_meth_get_paramgen, EVP_PKEY_meth_get_keygen, EVP_PKEY_meth_get_sign, +EVP_PKEY_meth_get_verify, EVP_PKEY_meth_get_verify_recover, EVP_PKEY_meth_get_signctx, +EVP_PKEY_meth_get_verifyctx, EVP_PKEY_meth_get_encrypt, EVP_PKEY_meth_get_decrypt, +EVP_PKEY_meth_get_derive, EVP_PKEY_meth_get_ctrl +- manipulating EVP_PKEY_METHOD structure + +=head1 SYNOPSIS + + #include + + typedef struct evp_pkey_method_st EVP_PKEY_METHOD; + + EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); + void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); + void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); + const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); + int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + + void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + + void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +=head1 DESCRIPTION + +B is a structure which holds a set of methods for a +specific public key cryptographic algorithm. Those methods are usually +used to perform different jobs, such as generating a key, signing or +verifying, encrypting or decrypting, etc. + +There are two places where the B objects are stored: one +is a built-in static array representing the standard methods for different +algorithms, and the other one is a stack of user-defined application-specific +methods, which can be manipulated by using L. + +The B objects are usually referenced by B +objects. + +=head2 Methods + +The methods are the underlying implementations of a particular public key +algorithm present by the B object. + + int (*init) (EVP_PKEY_CTX *ctx); + int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup) (EVP_PKEY_CTX *ctx); + +The init() method is called to initialize algorithm-specific data when a new +B is created. As opposed to init(), the cleanup() method is called +when an B is freed. The copy() method is called when an B +is being duplicated. Refer to L, L, +L and L. + + int (*paramgen_init) (EVP_PKEY_CTX *ctx); + int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + +The paramgen_init() and paramgen() methods deal with key parameter generation. +They are called by L and L to +handle the parameter generation process. + + int (*keygen_init) (EVP_PKEY_CTX *ctx); + int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + +The keygen_init() and keygen() methods are used to generate the actual key for +the specified algorithm. They are called by L and +L. + + int (*sign_init) (EVP_PKEY_CTX *ctx); + int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + +The sign_init() and sign() methods are used to generate the signature of a +piece of data using a private key. They are called by L +and L. + + int (*verify_init) (EVP_PKEY_CTX *ctx); + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + +The verify_init() and verify() methods are used to verify whether a signature is +valid. They are called by L and L. + + int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + int (*verify_recover) (EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + +The verify_recover_init() and verify_recover() methods are used to verify a +signature and then recover the digest from the signature (for instance, a +signature that was generated by RSA signing algorithm). They are called by +L and L. + + int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + +The signctx_init() and signctx() methods are used to sign a digest present by +a B object. They are called by the EVP_DigestSign functions. See +L for detail. + + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); + +The verifyctx_init() and verifyctx() methods are used to verify a signature +against the data in a B object. They are called by the various +EVP_DigestVerify functions. See L for detail. + + int (*encrypt_init) (EVP_PKEY_CTX *ctx); + int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +The encrypt_init() and encrypt() methods are used to encrypt a piece of data. +They are called by L and L. + + int (*decrypt_init) (EVP_PKEY_CTX *ctx); + int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +The decrypt_init() and decrypt() methods are used to decrypt a piece of data. +They are called by L and L. + + int (*derive_init) (EVP_PKEY_CTX *ctx); + int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +The derive_init() and derive() methods are used to derive the shared secret +from a public key algorithm (for instance, the DH algorithm). They are called by +L and L. + + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); + +The ctrl() and ctrl_str() methods are used to adjust algorithm-specific +settings. See L and related functions for detail. + + int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + +The digestsign() and digestverify() methods are used to generate or verify +a signature in a one-shot mode. They could be called by L +and L. + +=head2 Functions + +EVP_PKEY_meth_new() creates and returns a new B object, +and associates the given B and B. The following flags are +supported: + + EVP_PKEY_FLAG_AUTOARGLEN + EVP_PKEY_FLAG_SIGCTX_CUSTOM + +If an B is set with the B flag, the +maximum size of the output buffer will be automatically calculated or checked +in corresponding EVP methods by the EVP framework. Thus the implementations of +these methods don't need to care about handling the case of returning output +buffer size by themselves. For details on the output buffer size, refer to +L. + +The B is used to indicate the signctx() method +of an B is always called by the EVP framework while doing a +digest signing operation by calling L. + +EVP_PKEY_meth_free() frees an existing B pointed by +B. + +EVP_PKEY_meth_copy() copies an B object from B +to B. + +EVP_PKEY_meth_find() finds an B object with the B. +This function first searches through the user-defined method objects and +then the built-in objects. + +EVP_PKEY_meth_add0() adds B to the user defined stack of methods. + +The EVP_PKEY_meth_set functions set the corresponding fields of +B structure with the arguments passed. + +The EVP_PKEY_meth_get functions get the corresponding fields of +B structure to the arguments provided. + +=head1 RETURN VALUES + +EVP_PKEY_meth_new() returns a pointer to a new B +object or returns NULL on error. + +EVP_PKEY_meth_free() and EVP_PKEY_meth_copy() do not return values. + +EVP_PKEY_meth_find() returns a pointer to the found B +object or returns NULL if not found. + +EVP_PKEY_meth_add0() returns 1 if method is added successfully or 0 +if an error occurred. + +All EVP_PKEY_meth_set and EVP_PKEY_meth_get functions have no return +values. For the 'get' functions, function pointers are returned by +arguments. + +=head1 COPYRIGHT + +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod b/crypto/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod index b8f678fe729d..f20f815d4786 100644 --- a/crypto/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod +++ b/crypto/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod @@ -104,6 +104,13 @@ The RSA_padding_check_xxx() functions return the length of the recovered data, -1 on error. Error codes can be obtained by calling L. +=head1 WARNING + +The RSA_padding_check_PKCS1_type_2() padding check leaks timing +information which can potentially be used to mount a Bleichenbacher +padding oracle attack. This is an inherent weakness in the PKCS #1 +v1.5 padding design. Prefer PKCS1_OAEP padding. + =head1 SEE ALSO L, diff --git a/crypto/openssl/doc/crypto/RSA_public_encrypt.pod b/crypto/openssl/doc/crypto/RSA_public_encrypt.pod index 0541f348b3e2..4d7c1f2cac7a 100644 --- a/crypto/openssl/doc/crypto/RSA_public_encrypt.pod +++ b/crypto/openssl/doc/crypto/RSA_public_encrypt.pod @@ -67,6 +67,13 @@ recovered plaintext. On error, -1 is returned; the error codes can be obtained by L. +=head1 WARNING + +Decryption failures in the RSA_PKCS1_PADDING mode leak information +which can potentially be used to mount a Bleichenbacher padding oracle +attack. This is an inherent weakness in the PKCS #1 v1.5 padding +design. Prefer RSA_PKCS1_OAEP_PADDING. + =head1 CONFORMING TO SSL, PKCS #1 v2.0 diff --git a/crypto/openssl/doc/crypto/X509_check_private_key.pod b/crypto/openssl/doc/crypto/X509_check_private_key.pod new file mode 100644 index 000000000000..a1fb07b1097e --- /dev/null +++ b/crypto/openssl/doc/crypto/X509_check_private_key.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +X509_check_private_key, X509_REQ_check_private_key - check the consistency +of a private key with the public key in an X509 certificate or certificate +request + +=head1 SYNOPSIS + + #include + + int X509_check_private_key(X509 *x, EVP_PKEY *k); + + int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k); + +=head1 DESCRIPTION + +X509_check_private_key() function checks the consistency of private +key B with the public key in B. + +X509_REQ_check_private_key() is equivalent to X509_check_private_key() +except that B represents a certificate request of structure B. + +=head1 RETURN VALUE + +X509_check_private_key() and X509_REQ_check_private_key() return 1 if +the keys match each other, and 0 if not. + +If the key is invalid or an error occurred, the reason code can be +obtained using L. + +=head1 BUGS + +The B functions don't check if B itself is indeed +a private key or not. It merely compares the public materials (e.g. exponent +and modulus of an RSA key) and/or key parameters (e.g. EC params of an EC key) +of a key pair. So if you pass a public key to these functions in B, it will +return success. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/crypto/hmac.pod b/crypto/openssl/doc/crypto/hmac.pod index 2c8f20a20188..ca9798af62c3 100644 --- a/crypto/openssl/doc/crypto/hmac.pod +++ b/crypto/openssl/doc/crypto/hmac.pod @@ -38,7 +38,8 @@ B bytes long. It places the result in B (which must have space for the output of the hash function, which is no more than B bytes). If B is NULL, the digest is placed in a static array. The size of -the output is placed in B, unless it is B. +the output is placed in B, unless it is B. Note: passing a NULL +value for B to use the static array is not thread safe. B can be EVP_sha1(), EVP_ripemd160() etc. diff --git a/crypto/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_tlsext_servername_callback.pod similarity index 100% rename from crypto/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod rename to crypto/openssl/doc/ssl/SSL_CTX_set_tlsext_servername_callback.pod diff --git a/crypto/openssl/doc/ssl/SSL_export_keying_material.pod b/crypto/openssl/doc/ssl/SSL_export_keying_material.pod new file mode 100644 index 000000000000..ccb99ec9a8e0 --- /dev/null +++ b/crypto/openssl/doc/ssl/SSL_export_keying_material.pod @@ -0,0 +1,61 @@ +=pod + +=head1 NAME + +SSL_export_keying_material - obtain keying material for application use + +=head1 SYNOPSIS + + #include + + int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context); + +=head1 DESCRIPTION + +During the creation of a TLS or DTLS connection shared keying material is +established between the two endpoints. The function SSL_export_keying_material() +enables an application to use some of this keying material for its own purposes +in accordance with RFC5705. + +An application may need to securely establish the context within which this +keying material will be used. For example this may include identifiers for the +application session, application algorithms or parameters, or the lifetime of +the context. The context value is left to the application but must be the same +on both sides of the communication. + +For a given SSL connection B, B bytes of data will be written to +B. The application specific context should be supplied in the location +pointed to by B and should be B bytes long. Provision of +a context is optional. If the context should be omitted entirely then +B should be set to 0. Otherwise it should be any other value. If +B is 0 then the values of B and B are ignored. +Note that a zero length context is treated differently to no context at all, and +will result in different keying material being returned. + +An application specific label should be provided in the location pointed to by +B - -

For questions about FreeBSD, read the - documentation before - contacting <questions@FreeBSD.org>.

- -

All users of FreeBSD should - subscribe to the <@FreeBSD.org> - mailing list.

- -

For questions about this documentation, - e-mail <doc@FreeBSD.org>.

- - diff --git a/release/doc/share/examples/Makefile.relnotesng b/release/doc/share/examples/Makefile.relnotesng deleted file mode 100644 index 5bbc1a110900..000000000000 --- a/release/doc/share/examples/Makefile.relnotesng +++ /dev/null @@ -1,61 +0,0 @@ -# -*- makefile -*- -# -# $FreeBSD$ -# -# Sample makefile for rendering and uploading RELNOTESng files outside -# the build tree. -# - -ARCHS= amd64 i386 powerpc sparc64 -MULTITEXTS= -UNITEXTS= hardware readme relnotes errata - -IMAGEDIR= .imagedir -RHOST= freefall.freebsd.org -RDIR= public_html/relnotes/CURRENT -DOCDIR= ./release/doc -LANG= en_US.ISO8859-1 - -DOC_PREFIX?= /usr/doc -CSS_SHEET?= ${DOC_PREFIX}/share/misc/docbook.css -FORMATS?= html txt pdf - -BUILD_OPTIONS+= URLS_ABSOLUTE=YES - -all: - (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} FORMATS="${FORMATS}" ${BUILD_OPTIONS} all) - -lint: - (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} lint) - -image: all - @echo "#" - @echo "# Creating local image" - @echo "#" - rm -rf ${IMAGEDIR} - mkdir ${IMAGEDIR} - cp -p ${CSS_SHEET} ${IMAGEDIR}/docbook.css - for i in ${ARCHS}; do \ - for j in ${MULTITEXTS}; do \ - for k in ${FORMATS}; do \ - cp -p ${DOCDIR}/${LANG}/$${j}/$${i}/article.$${k} ${IMAGEDIR}/$${j}-$${i}.$${k} ; \ - done; \ - done; \ - done - for j in ${UNITEXTS}; do \ - for k in ${FORMATS}; do \ - cp -p ${DOCDIR}/${LANG}/$${j}/article.$${k} ${IMAGEDIR}/$${j}.$${k} ; \ - done; \ - done - -push: image - @echo "#" - @echo "# Pushing to ${RHOST}" - @echo "#" -# (cd ${IMAGEDIR}; tar -cf - .) | gzip -c -9 | (ssh ${RHOST} "( cd ${RDIR}; gunzip -c | tar -xf -)" ) - (cd ${IMAGEDIR}; rsync -azuv * ${RHOST}:${RDIR}) - rm -rf ${IMAGEDIR} - -clean: - (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} FORMATS="${FORMATS}" clean) - rm -rf ${IMAGEDIR} diff --git a/release/doc/share/misc/dev.archlist.txt b/release/doc/share/misc/dev.archlist.txt deleted file mode 100644 index 7ad81543e989..000000000000 --- a/release/doc/share/misc/dev.archlist.txt +++ /dev/null @@ -1,176 +0,0 @@ -# -# Copyright (c) 2004-2006 The FreeBSD Project -# All rights reserved. -# -# 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 AUTHOR 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 AUTHOR 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. -# -# $FreeBSD$ -# - -# -# This file is used by man2hwnotes.pl to set which drivers are usable -# on which architectures. -# -# Format: -# -# Empty lines, and lines beginning with "#" are ignored. -# [,...] -# -aac i386,amd64 -adv i386,amd64 -adw i386,amd64 -aha i386 -ahb i386 -ahd i386,sparc64,amd64 -aic i386,amd64 -amd i386,amd64 -arcmsr i386,amd64 -asr i386 -ath i386,amd64,sparc64 -aue i386,amd64,powerpc -axe i386,amd64,powerpc -bce i386,amd64 -bge i386,sparc64,amd64 -bktr i386 -bt i386,amd64 -bxe i386,amd64 -cdce i386,amd64,powerpc -ciss i386,amd64 -ce i386 -cm i386 -cnw i386,amd64 -cp i386 -ctau i386 -cue i386,amd64,powerpc -cx i386 -cxgb i386,amd64 -de i386,amd64 -dpt i386,amd64 -ed i386 -ep i386,amd64 -esp sparc64 -ex i386,amd64 -fe i386,amd64 -fwohci i386,sparc64,amd64,powerpc -hifn i386,amd64 -hpt27xx i386,amd64 -hptiop i386,amd64 -hptmv i386,amd64 -hptrr i386,amd64 -ida i386 -ie i386 -iir i386,amd64 -ips i386,amd64 -isci i386,amd64 -ixgb i386,amd64 -kue i386,amd64,powerpc -lge i386,amd64 -mfi i386,amd64 -mlx i386,amd64 -mly i386,amd64 -msk i386,amd64 -mxge i386,amd64 -my i386 -ncr i386,amd64 -ncv i386 -nfe i386,amd64 -ng_bt3c i386,amd64 -ng_ubt i386,amd64 -nsp i386 -nxge i386,amd64 -oce i386,amd64 -ohci i386,amd64,powerpc -oltr i386 -otus i386,amd64 -pcn i386,amd64 -pst i386 -qlxgb amd64 -qlxgbe amd64 -qlxge amd64 -rc i386 -ral i386,amd64 -rsu i386,amd64 -rue i386,amd64 -rum i386,amd64 -run i386,amd64 -safe i386,amd64 -sbp i386,sparc64,amd64 -sfgxe amd64 -sn i386,amd64 -snd_ad1816 i386,amd64 -snd_als4000 i386 -snd_atiixp i386,amd64 -snd_audiocs sparc64 -snd_cmi i386,amd64 -snd_cs4281 i386,amd64 -snd_csa i386,amd64 -snd_ds1 i386,amd64 -snd_emu10k1 i386,amd64 -snd_emu10kx i386,amd64 -snd_envy24 i386,amd64 -snd_envy24ht i386,amd64 -snd_es137x i386,sparc64,amd64 -snd_ess i386,amd64 -snd_fm801 i386,amd64 -snd_gusc i386,amd64 -snd_hda i386,amd64 -snd_hdspe i386,amd64 -snd_ich i386,amd64 -snd_maestro i386,amd64 -snd_maestro3 i386,amd64 -snd_mss i386 -snd_neomagic i386,amd64 -snd_sbc i386,amd64 -snd_solo i386,amd64 -snd_spicds i386,amd64 -snd_t4dwave i386,amd64,sparc64 -snd_via8233 i386,amd64 -snd_via82c686 i386,amd64 -snd_vibes i386,amd64 -stg i386 -ti i386,amd64,sparc64 -tl i386,amd64 -trm i386,amd64 -twa i386,amd64 -twe i386,amd64 -tws i386,amd64 -ubsa i386,amd64 -ubsec i386,amd64 -ubser i386,amd64 -ucycom i386,amd64 -udav i386,amd64 -uftdi i386,amd64 -uhci i386,amd64,powerpc -ulpt i386,amd64,powerpc -umass i386,amd64,powerpc -umodem i386,amd64 -uplcom i386,amd64 -ural i386,amd64 -urio i386,amd64,powerpc -uvisor i386,amd64 -uvscom i386,amd64 -vpo i386 -vx i386,amd64 -vxge i386,amd64 -wb i386,amd64 -xe i386,amd64 -zyd i386,amd64 diff --git a/release/doc/share/misc/man2hwnotes.pl b/release/doc/share/misc/man2hwnotes.pl deleted file mode 100644 index a64aae872913..000000000000 --- a/release/doc/share/misc/man2hwnotes.pl +++ /dev/null @@ -1,533 +0,0 @@ -#!/usr/bin/perl -w -# Emacs should use -*- cperl -*- mode -# -# Copyright (c) 2003-2006 Simon L. Nielsen -# All rights reserved. -# -# 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 AUTHOR 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 AUTHOR 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. -# -# $FreeBSD$ -# - -# Parse the list of supported hardware out of section 4 manual pages -# and output it on stdout as SGML/DocBook entities. - -# The script will look for the following line in the manual page: -# .Sh HARDWARE -# and make an entity of the content until the line containing: -# .Sh -# -# For Lists only the first line will be printed. If there are -# arguments to the .It command, only the argument will be printed. - -# Usage: -# man2hwnotes.pl [-cl] [-d 0-6] [-a ] [-o ] -# [ ...] - -use strict; -use Getopt::Std; -use Digest::MD5 qw(md5_hex); - -# Section from manual page to extract -my $hwlist_sect = "HARDWARE"; - -# Override default archtecture list for some devices: -my $archlist_file = "dev.archlist.txt"; -my %archlist; - -# Globals -my $compat_mode = 0; # Enable compat for old Hardware Notes style -my $debuglevel = 0; -my $only_list_out = 0; # Should only lists be generated in the output? -my @out_lines; # Single lines -my @out_dev; # Device entities - -# Getopt -my %options = (); -if (!getopts("a:cd:lo:",\%options)) { - die("$!: Invalid command line arguments in ", __LINE__, "\n"); -} - -if (defined($options{c})) { - $compat_mode = 1; -} -if (defined($options{d})) { - $debuglevel = $options{d}; -} -if (defined($options{a})) { - $archlist_file = $options{a}; -} -if (defined($options{l})) { - $only_list_out = 1; -} - -my $outputfile = $options{o}; - -if ($debuglevel > 0) { - # Don't do output buffering in debug mode. - $| = 1; -} - -load_archlist($archlist_file); - -if (defined($outputfile)) { - open(OLDOUT, ">&STDOUT") || die("$!: Could not open STDOUT in ", __LINE__, ".\n"); - open(STDOUT, ">$outputfile") || die("$!: Could not open $outputfile in ", __LINE__, ".\n"); -} - -print < -EOT - -if ($only_list_out) { - # Print the default device preamble entities - print "\n"; - print "\n"; -} - -foreach my $page (@ARGV) { - if ($page !~ m/\.4$/) { - dlog(2, "Skipped $page (not *.4)"); - next; - } - dlog(2, "Parsing $page"); - parse($page); - - if (@out_lines) { - print join("\n", @out_lines), "\n"; - } - if (@out_dev) { - print join("\n", @out_dev), "\n"; - } - - @out_lines = (); - @out_dev = (); -} - -if (defined($outputfile)) { - open(STDOUT, ">&OLDOUT") || die("$!: Could not open STDOUT in ", __LINE__, ".\n"); - close(OLDOUT) || die("$!: Could not close OLDOUT in ", __LINE__, ".\n"); -} - -sub normalize (@) { - my @lines = @_; - - foreach my $l (@lines) { - $l =~ s/\\&//g; - $l =~ s:([\x21-\x2f\x5b-\x60\x7b-\x7f]):sprintf("&\#\%d;", ord($1)):eg; - # Make sure ampersand is encoded as & since jade seems to - # be confused when it is encoded as & inside an entity. - $l =~ s/&/&/g; - } - return (wantarray) ? @lines : join "", @lines; -} - -sub parse { - my ($manpage) = @_; - - my $cur_mansection; - my $found_hwlist = 0; - my %mdocvars; - $mdocvars{isin_hwlist} = 0; - $mdocvars{isin_list} = 0; - $mdocvars{first_para} = 1; - $mdocvars{parabuf} = ""; - $mdocvars{listtype} = ""; - $mdocvars{it_nr} = 0; - - open(MANPAGE, "$manpage") || die("$!: Could not open $manpage in ", __LINE__, ".\n"); - while() { - chomp; - my $line = $_; - - dlog(5, "Read '$line'"); - - # Find commands - if (s/^\.(.*)$/$1/) { - my $cmd = $1; - - # Detect, and ignore, comment lines - if (s/^\\"(.*)$/$1/) { - next; - } - - $cmd =~ s/^([^ ]+).*$/$1/; - - if (/^Nm "?(\w+)"?/ && !defined($mdocvars{Nm})) { - dlog(3, "Setting Nm to $1"); - $mdocvars{Nm} = $1; - # "_" cannot be used for an entity name. - $mdocvars{EntNm} = $1; - $mdocvars{EntNm} =~ s,_,.,g; - - } elsif (/^Nm$/) { - if (defined($mdocvars{Nm}) && $mdocvars{Nm} ne "") { - parabuf_addline(\%mdocvars, "&man.".$mdocvars{EntNm}.".$cur_mansection;"); - } else { - dlog(2, "Warning: Bad Nm call in $manpage"); - } - - } elsif (/^Sh (.+)$/) { - dlog(4, "Setting section to $1"); - my $cur_section = $1; - - flush_out(\%mdocvars); - - if ($cur_section =~ /^${hwlist_sect}$/) { - dlog(2, "Found the device section ${hwlist_sect}"); - $mdocvars{isin_hwlist} = 1; - $found_hwlist = 1; - add_sgmltag(\%mdocvars, "&hwlist.preamble.pre; " . - "&man.".$mdocvars{EntNm}.".$cur_mansection; " . - "&hwlist.preamble.post;"); - } - } elsif ($mdocvars{isin_hwlist}) { - dlog(2, "Found a HWLIST STOP key!"); - add_sgmltag(\%mdocvars, "'>"); - $mdocvars{isin_hwlist} = 0; - } - if ($mdocvars{isin_list}) { - dlog(1, "Warning: Still in list, but just entered new " . - "section. This is probably due to missing .El; " . - "check manual page for errors."); - # If we try to recover from this we will probably - # just end with bad SGML output and it really - # should be fixed in the manual page so we don't - # even try to "fix" this. - } - - - } elsif (/^Dt ([^ ]+) ([^ ]+)/) { - dlog(4, "Setting mansection to $2"); - $mdocvars{cur_manname} = lc($1); - $cur_mansection = $2; - - # "_" cannot be used for an entity name. - $mdocvars{cur_manname} =~ s,_,.,g; - - } elsif (/^It ?(.*)$/) { - my $txt = $1; - - $mdocvars{it_nr}++; - - # Flush last item - if ($mdocvars{parabuf} ne "") { - add_listitem(\%mdocvars); - } - - # Remove quotes, if any. - $txt =~ s/"(.*)"/$1/; - - if ($mdocvars{listtype} eq "column") { - # Ignore first item when it is likely to be a - # header. - if ($mdocvars{it_nr} == 1 && $txt =~ m/^(Em|Sy) /) { - dlog(2, "Skipping header line in column list"); - next; - } - # Only extract the first column. - $txt =~ s/ Ta /\t/g; - $txt =~ s/([^\t]+)\t.*/$1/; - } - - # Remove Li commands - $txt =~ s/^Li //g; - - parabuf_addline(\%mdocvars, normalize($txt)); - } elsif (/^Bl/) { - $mdocvars{isin_list} = 1; - flush_out(\%mdocvars); - add_sgmltag(\%mdocvars, ""); - - if (/-tag/) { - $mdocvars{listtype} = "tag"; - # YACK! Hack for ata(4) - if ($mdocvars{Nm} eq "ata") { - $mdocvars{listtype} = "tagHACK"; - } - } elsif (/-bullet/) { - $mdocvars{listtype} = "bullet"; - } elsif (/-column/) { - $mdocvars{listtype} = "column"; - } else { - $mdocvars{listtype} = "unknown"; - } - dlog(2, "Listtype set to $mdocvars{listtype}"); - } elsif (/^El/) { - if ($mdocvars{parabuf} ne "") { - add_listitem(\%mdocvars); - } - - add_sgmltag(\%mdocvars, ""); - $mdocvars{isin_list} = 0; - } elsif (/^Tn (.+)$/) { - # For now we print TradeName text as regular text. - my ($txt, $punct_str) = split_punct_chars($1); - - parabuf_addline(\%mdocvars, normalize($txt . $punct_str)); - } elsif (/^Xr ([^ ]+) (.+)$/) { - my ($xr_sect, $punct_str) = split_punct_chars($2); - my $txt; - - # We need to check if the manual page exist to avoid - # breaking the doc build just because of a broken - # reference. - #$txt = "&man.$1.$xr_sect;$punct_str"; - $txt = "$1($xr_sect)$punct_str"; - parabuf_addline(\%mdocvars, normalize($txt)); - } elsif (/^Dq (.+)$/) { - my ($txt, $punct_str) = split_punct_chars($1); - - parabuf_addline(\%mdocvars, - normalize("$txt$punct_str")); - } elsif (/^Sx (.+)$/) { - if ($mdocvars{isin_hwlist}) { - dlog(1, "Warning: Reference to another section in the " . - "$hwlist_sect section in " . $mdocvars{Nm} . - "(${cur_mansection})"); - } - parabuf_addline(\%mdocvars, normalize($1)); - } elsif (/^Pa (.+)$/) { - my ($txt, $punct_str) = split_punct_chars($1); - - $txt = make_ulink($txt) . $punct_str; - parabuf_addline(\%mdocvars, normalize($txt)); - } elsif (/^Pp/) { - dlog(3, "Got Pp command - forcing new para"); - flush_out(\%mdocvars); - } elsif (/^Fx (.+)/) { - dlog(3, "Got Fx command"); - parabuf_addline(\%mdocvars, "FreeBSD $1"); - } elsif (/^Fx/) { - dlog(3, "Got Fx command"); - parabuf_addline(\%mdocvars, "FreeBSD"); - } elsif (/^Em (.+)$/) { - my ($txt, $punct_str) = split_punct_chars($1); - - parabuf_addline(\%mdocvars, - normalize("$txt$punct_str")); - } else { - # Ignore all other commands. - dlog(3, "Ignoring unknown command $cmd"); - } - } else { - # This is then regular text - parabuf_addline(\%mdocvars, normalize($_)); - } - } - close(MANPAGE) || die("$!: Could not close $manpage in ", __LINE__, ".\n"); - if (! $found_hwlist) { - dlog(2, "Hardware list not found in $manpage"); - } -} - -sub dlog { - my ($level, $txt) = @_; - - if ($level <= $debuglevel) { - print STDERR "$level: $txt\n"; - } -} - -# Output a SGML tag. -sub add_sgmltag { - my ($mdocvars, $txt) = (@_); - - # We only care about the HW list for now. - if (${$mdocvars}{isin_hwlist}) { - push(@out_dev, $txt); - } -} - -# Add a text entity, and return the used entity name. -sub add_txt_ent { - my ($itemtxt) = (@_); - my ($entity_name); - - # Convert mdoc(7) minus - $itemtxt =~ s/\\-/-/g; - - $itemtxt =~ s/'/‘/g; - - $entity_name = "hwlist." . md5_hex($itemtxt); - dlog(4, "Adding '$itemtxt' as entity $entity_name"); - push(@out_lines, ""); - - return ($entity_name); -} -sub flush_out { - my ($mdocvars) = (@_); - my ($entity_name, $out); - my $para_arch = ""; - - if (!${$mdocvars}{isin_hwlist} || ${$mdocvars}{parabuf} eq "") { - return; - } - - $entity_name = add_txt_ent(${$mdocvars}{parabuf}); - ${$mdocvars}{parabuf} = ""; - if(defined($archlist{${$mdocvars}{Nm}})) { - if ($compat_mode) { - $para_arch = ' arch="' . $archlist{${$mdocvars}{Nm}} . '"'; - } else { - $para_arch = '[' . $archlist{${$mdocvars}{Nm}} . '] '; - } - } - if ($compat_mode) { - $out = "&".$entity_name.";"; - } else { - if (${$mdocvars}{first_para}) { - $out = "".$para_arch."&".$entity_name.";"; - } else { - $out = "&".$entity_name.";"; - } - ${$mdocvars}{first_para} = 0; - } - - dlog(4, "Flushing parabuf"); - add_sgmltag($mdocvars, $out); -} - -# Add a new list item from the "parabuf". -sub add_listitem { - my ($mdocvars) = (@_); - my ($listitem, $entity_name); - my $para_arch = ""; - - $entity_name = add_txt_ent(${$mdocvars}{parabuf}); - ${$mdocvars}{parabuf} = ""; - - if ($compat_mode) { - if(defined($archlist{${$mdocvars}{Nm}})) { - $para_arch = ' arch="' . $archlist{${$mdocvars}{Nm}} . '"'; - } - } - $listitem = "&".$entity_name.";"; - dlog(4, "Adding '$listitem' to out_dev"); - push(@out_dev, $listitem); - -} - -# Add a line to the "paragraph buffer" -sub parabuf_addline { - my $mdocvars = shift; - my ($txt) = (@_); - - dlog(5, "Now in parabuf_addline for '$txt'"); - - # We only care about the HW list for now. - if (!${$mdocvars}{isin_hwlist}) { - dlog(6, "Exiting parabuf_addline due to: !\${\$mdocvars}{isin_hwlist}"); - return; - } - if ($txt eq "") { - dlog(6, "Exiting parabuf_addline due to: \$txt eq \"\""); - return; - } - - if ($only_list_out && !${$mdocvars}{isin_list}) { - dlog(6, "Exiting parabuf_addline due to: ". - "\$only_list_out && !\${\$mdocvars}{isin_list}"); - return; - } - - # We only add the first line for "tag" lists - if (${$mdocvars}{parabuf} ne "" && ${$mdocvars}{isin_list} && - ${$mdocvars}{listtype} eq "tag") { - dlog(6, "Exiting parabuf_addline due to: ". - "\${\$mdocvars}{parabuf} ne \"\" && \${\$mdocvars}{isin_list} && ". - "\${\$mdocvars}{listtype} eq \"tag\""); - return; - } - - if (${$mdocvars}{parabuf} ne "") { - ${$mdocvars}{parabuf} .= " "; - } - - dlog(4, "Adding '$txt' to parabuf"); - - ${$mdocvars}{parabuf} .= $txt; -} - -sub load_archlist { - my ($file) = (@_); - - my $lineno = 0; - - dlog(2, "Parsing archlist $file"); - - open(FILE, "$file") || die("$!: Could not open archlist $file in ", __LINE__, ".\n"); - while() { - chomp; - $lineno++; - - if (/^#/ || $_ eq "") { - next; - } - - if (/(\w+)\t([\w,]+)/) { - dlog(4, "For driver $1 setting arch to $2"); - $archlist{$1} = $2; - } else { - dlog(1, "Warning: Could not parse archlist line $lineno"); - } - } - - close(FILE); -} - -# Check if a character is a mdoc(7) punctuation character. -sub is_punct_char { - my ($str) = (@_); - - return (length($str) == 1 && $str =~ /[\.,:;()\[\]\?!]/); -} - -# Split out the punctuation characters of a mdoc(7) line. -sub split_punct_chars { - my ($str) = (@_); - my (@stritems, $stritem, $punct_str); - - $punct_str = ""; - @stritems = split(/ /, $str); - - while (defined($stritem = $stritems[$#stritems]) && - is_punct_char($stritem)) { - $punct_str = $stritem . $punct_str; - pop(@stritems); - } - - return (join(' ', @stritems), $punct_str); -} - -# Create a ulink, if the string contains an URL. -sub make_ulink { - my ($str) = (@_); - - $str =~ s,(http://[^ ]+),,; - - return $str; -} diff --git a/release/doc/share/mk/doc.relnotes.mk b/release/doc/share/mk/doc.relnotes.mk deleted file mode 100644 index ae8a31fbbaaa..000000000000 --- a/release/doc/share/mk/doc.relnotes.mk +++ /dev/null @@ -1,54 +0,0 @@ -# $FreeBSD$ - -DOC_PREFIX?= ${RELN_ROOT}/../../../doc - -# XXX -RELEASETYPE!= grep -o 'release.type "[a-z]*"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[a-z.]* "\([a-z]*\)"|\1|' -RELEASEURL!= grep -o 'release.url \"[^\"]*\"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|' -RELEASEBRANCH!= grep -o 'release.branch "\([^"]*\)"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|' -RELEASEMAILLIST!= grep -o 'release.maillist "\([^"]*\)"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|' -.if ${RELEASETYPE} == "current" -PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'current'" -.elif ${RELEASETYPE} == "snapshot" -PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'snapshot'" -.elif ${RELEASETYPE} == "release" -PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'release'" -.endif -XSLTPROCFLAGS+= --param release.url "'${RELEASEURL}'" -XSLTPROCFLAGS+= --param release.branch "'${RELEASEBRANCH}'" -XSLTPROCFLAGS+= --param release.maillist "'${RELEASEMAILLIST}'" -XSLTPROCFLAGS+= --param toc.section.depth "'3'" - -# Find the RELNOTESng document catalogs -EXTRA_CATALOGS+= file://${RELN_ROOT}/${LANGCODE}/share/xml/catalog.xml \ - file://${RELN_ROOT}/share/xml/catalog.xml - -XSLXHTML= http://www.FreeBSD.org/release/XML/share/xml/release.xsl - -# -# Automatic device list generation: -# -.if exists(${RELN_ROOT}/../man4) -MAN4DIR?= ${RELN_ROOT}/../man4 -.elif exists(${RELN_ROOT}/../../man4) -MAN4DIR?= ${RELN_ROOT}/../../man4 -.else -MAN4DIR?= ${RELN_ROOT}/../../share/man/man4 -.endif -MAN4PAGES?= ${MAN4DIR}/*.4 ${MAN4DIR}/man4.*/*.4 -ARCHLIST?= ${RELN_ROOT}/share/misc/dev.archlist.txt -DEV-AUTODIR= ${RELN_ROOT:S/${.CURDIR}/${.OBJDIR}/}/share/xml -CLEANFILES+= ${DEV-AUTODIR}/dev-auto.ent - -MAN2HWNOTES_CMD=${RELN_ROOT}/share/misc/man2hwnotes.pl -.if defined(HWNOTES_MI) -MAN2HWNOTES_FLAGS= -.else -MAN2HWNOTES_FLAGS= -c -.endif - -# Dependency that the article makefiles can use to pull in -# dev-auto.ent. -${DEV-AUTODIR}/catalog-auto ${DEV-AUTODIR}/dev-auto.ent: ${MAN4PAGES} \ - ${ARCHLIST} ${MAN2HWNOTES_CMD} - cd ${RELN_ROOT}/share/xml && make MAN2HWNOTES_FLAGS=${MAN2HWNOTES_FLAGS} dev-auto.ent diff --git a/release/doc/share/xml/Makefile b/release/doc/share/xml/Makefile deleted file mode 100644 index b2c1b6db2133..000000000000 --- a/release/doc/share/xml/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -RELN_ROOT?= ${.CURDIR}/../.. - -.include "${RELN_ROOT}/share/mk/doc.relnotes.mk" -.include "${DOC_PREFIX}/share/mk/doc.project.mk" - -dev-auto.ent: ${MAN4PAGES} ${ARCHLIST} ${MAN2HWNOTES_CMD} - ${PERL} ${MAN2HWNOTES_CMD} ${MAN2HWNOTES_FLAGS} -a ${ARCHLIST} -o ${.TARGET} ${MAN4PAGES} - -all: dev-auto.ent diff --git a/release/doc/share/xml/catalog.xml b/release/doc/share/xml/catalog.xml deleted file mode 100644 index 74f8ccd068ff..000000000000 --- a/release/doc/share/xml/catalog.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/release/doc/share/xml/errata.xml b/release/doc/share/xml/errata.xml deleted file mode 100644 index efc21a1cb7c0..000000000000 --- a/release/doc/share/xml/errata.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - Errata - Date - Topic - - - - - - No errata notices. -   -   - - - - diff --git a/release/doc/share/xml/release.ent b/release/doc/share/xml/release.ent deleted file mode 100644 index cacc43401fba..000000000000 --- a/release/doc/share/xml/release.ent +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - -]]> - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/release/doc/share/xml/release.xsl b/release/doc/share/xml/release.xsl deleted file mode 100644 index f76ae683d8a5..000000000000 --- a/release/doc/share/xml/release.xsl +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Sponsored by - - - - - - - - - - - - - - - - - - (Contributed / provided by - - - - - - - - - - - - - - - - - - -

-
- - - - - - - - - - - -
-
diff --git a/release/doc/share/xml/security.xml b/release/doc/share/xml/security.xml deleted file mode 100644 index 74a8cd7211df..000000000000 --- a/release/doc/share/xml/security.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - Advisory - Date - Topic - - - - - - No advisories. -   -   - - - - diff --git a/release/doc/share/xml/sponsor.ent b/release/doc/share/xml/sponsor.ent deleted file mode 100644 index c762d1900856..000000000000 --- a/release/doc/share/xml/sponsor.ent +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/release/doc/share/xml/vendor.ent b/release/doc/share/xml/vendor.ent deleted file mode 100644 index 75c879b71c82..000000000000 --- a/release/doc/share/xml/vendor.ent +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/release/i386/mkisoimages.sh b/release/i386/mkisoimages.sh index 1eeb9ddc3a75..a7d33c4c40ad 100644 --- a/release/i386/mkisoimages.sh +++ b/release/i386/mkisoimages.sh @@ -39,7 +39,7 @@ fi LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift NAME="$1"; shift -publisher="The FreeBSD Project. http://www.FreeBSD.org/" +publisher="The FreeBSD Project. https://www.FreeBSD.org/" echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab" makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@" rm -f "$1/etc/fstab" diff --git a/release/powerpc/mkisoimages.sh b/release/powerpc/mkisoimages.sh index 34b91ffbd1ad..ef61f9cbb2e7 100644 --- a/release/powerpc/mkisoimages.sh +++ b/release/powerpc/mkisoimages.sh @@ -61,7 +61,7 @@ fi LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift NAME="$1"; shift -publisher="The FreeBSD Project. http://www.FreeBSD.org/" +publisher="The FreeBSD Project. https://www.FreeBSD.org/" echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab" makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@" rm -f "$1/etc/fstab" diff --git a/release/release.sh b/release/release.sh index e8e671b91c22..18ec210b78f6 100755 --- a/release/release.sh +++ b/release/release.sh @@ -148,7 +148,7 @@ env_check() { WITH_COMPRESSED_IMAGES= NODOC=yes case ${EMBEDDED_TARGET}:${EMBEDDED_TARGET_ARCH} in - arm:armv6|arm64:aarch64) + arm:armv6|arm:armv7|arm64:aarch64) chroot_build_release_cmd="chroot_arm_build_release" ;; *) @@ -350,7 +350,6 @@ chroot_build_release() { # chroot_arm_build_release(): Create arm SD card image. chroot_arm_build_release() { load_target_env - eval chroot ${CHROOTDIR} make -C /usr/src/release obj case ${EMBEDDED_TARGET} in arm|arm64) if [ -e "${RELENGDIR}/tools/arm.subr" ]; then @@ -361,11 +360,14 @@ chroot_arm_build_release() { ;; esac [ ! -z "${RELEASECONF}" ] && . "${RELEASECONF}" - WORLDDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V WORLDDIR)" - OBJDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V .OBJDIR)" - DESTDIR="${OBJDIR}/${KERNEL}" - IMGBASE="${CHROOTDIR}/${OBJDIR}/${KERNEL}.img" - OSRELEASE="$(eval chroot ${CHROOTDIR} make -C /usr/src/release \ + export MAKE_FLAGS="${MAKE_FLAGS} TARGET=${EMBEDDED_TARGET}" + export MAKE_FLAGS="${MAKE_FLAGS} TARGET_ARCH=${EMBEDDED_TARGET_ARCH}" + eval chroot ${CHROOTDIR} env WITH_UNIFIED_OBJDIR=1 make ${MAKE_FLAGS} -C /usr/src/release obj + export WORLDDIR="$(eval chroot ${CHROOTDIR} make ${MAKE_FLAGS} -C /usr/src/release -V WORLDDIR)" + export OBJDIR="$(eval chroot ${CHROOTDIR} env WITH_UNIFIED_OBJDIR=1 make ${MAKE_FLAGS} -C /usr/src/release -V .OBJDIR)" + export DESTDIR="${OBJDIR}/${KERNEL}" + export IMGBASE="${CHROOTDIR}/${OBJDIR}/${KERNEL}.img" + export OSRELEASE="$(eval chroot ${CHROOTDIR} make ${MAKE_FLAGS} -C /usr/src/release \ TARGET=${EMBEDDED_TARGET} TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \ -V OSRELEASE)" chroot ${CHROOTDIR} mkdir -p ${DESTDIR} diff --git a/release/scripts/mm-mtree.sh b/release/scripts/mm-mtree.sh index 620ab6dd962c..45c47be4f16e 100755 --- a/release/scripts/mm-mtree.sh +++ b/release/scripts/mm-mtree.sh @@ -81,11 +81,6 @@ if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \ fi # Setup make to use system files from SOURCEDIR -objp=${MAKEOBJDIRPREFIX} -[ -z "${objp}" ] && objp=/usr/obj -legacydir=${objp}${SOURCEDIR}/tmp/legacy -legacypath=${legacydir}/usr/sbin:${legacydir}/usr/bin:${legacydir}/bin -MM_MAKE_ARGS="${MM_MAKE_ARGS} PATH=${legacypath}:${PATH}" MM_MAKE="make ${ARCHSTRING} ${MM_MAKE_ARGS} -m ${SOURCEDIR}/share/mk" delete_temproot () { @@ -119,11 +114,10 @@ echo '' ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs ;; esac - od=${TEMPROOT}/usr/obj ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs && - MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc && - MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc && - MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} || + ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc && + ${MM_MAKE} everything SUBDIR_OVERRIDE=etc && + ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} || { echo ''; echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; echo " the temproot environment"; diff --git a/release/sparc64/mkisoimages.sh b/release/sparc64/mkisoimages.sh index 3cc0d9ad0591..78446c980ade 100644 --- a/release/sparc64/mkisoimages.sh +++ b/release/sparc64/mkisoimages.sh @@ -35,7 +35,7 @@ NAME="$1"; shift BASEBITSDIR="$1" # Create an ISO image -publisher="The FreeBSD Project. http://www.FreeBSD.org/" +publisher="The FreeBSD Project. https://www.FreeBSD.org/" echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$BASEBITSDIR/etc/fstab" makefs -t cd9660 -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME.tmp" "$@" rm -f "$BASEBITSDIR/etc/fstab" diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf index 924e7876001d..4331edc7e00c 100644 --- a/release/tools/ec2.conf +++ b/release/tools/ec2.conf @@ -6,7 +6,7 @@ # Packages to install into the image we're creating. This is a deliberately # minimalist set, providing only the packages necessary to bootstrap further # package installation as specified via EC2 user-data. -export VM_EXTRA_PACKAGES="ec2-scripts firstboot-freebsd-update firstboot-pkgs dual-dhclient" +export VM_EXTRA_PACKAGES="ec2-scripts firstboot-freebsd-update firstboot-pkgs dual-dhclient amazon-ssm-agent" # Set to a list of third-party software to enable in rc.conf(5). export VM_RC_LIST="ec2_configinit ec2_fetchkey ec2_ephemeralswap ec2_loghostkey firstboot_freebsd_update firstboot_pkgs" diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index fe937defc27a..78e7839d64e4 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -14,13 +14,10 @@ write_partition_layout() { SWAPOPT="-p freebsd-swap/swapfs::${SWAPSIZE}" fi - _OBJDIR="$(make -C ${WORLDDIR} -V .OBJDIR)" - _OBJDIR="$(realpath ${_OBJDIR})" - if [ -d "${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}" ]; then - BOOTFILES="/${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}/usr/src/sys/boot" - else - BOOTFILES="/${_OBJDIR}/sys/boot" - fi + BOOTFILES="$(env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ + WITH_UNIFIED_OBJDIR=yes \ + make -C ${WORLDDIR}/sys/boot -V .OBJDIR)" + BOOTFILES="$(realpath ${BOOTFILES})" case "${TARGET}:${TARGET_ARCH}" in amd64:amd64 | i386:i386) @@ -122,6 +119,15 @@ vm_install_base() { installworld installkernel distribution || \ err "\n\nCannot install the base system to ${DESTDIR}." + # Bootstrap etcupdate(8) and mergemaster(8) databases. + mkdir -p ${DESTDIR}/var/db/etcupdate + etcupdate extract -B \ + -M "TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH}" \ + -s ${WORLDDIR} -d ${DESTDIR}/var/db/etcupdate + sh ${WORLDDIR}/release/scripts/mm-mtree.sh -m ${WORLDDIR} \ + -F "TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH}" \ + -D ${DESTDIR} + echo '# Custom /etc/fstab for FreeBSD VM images' \ > ${DESTDIR}/etc/fstab echo "/dev/${ROOTLABEL}/rootfs / ufs rw 1 1" \ @@ -131,6 +137,10 @@ vm_install_base() { >> ${DESTDIR}/etc/fstab fi + local hostname + hostname="$(echo $(uname -o) | tr '[:upper:]' '[:lower:]')" + echo "hostname=\"${hostname}\"" >> ${DESTDIR}/etc/rc.conf + mkdir -p ${DESTDIR}/dev mount -t devfs devfs ${DESTDIR}/dev chroot ${DESTDIR} /usr/bin/newaliases diff --git a/rescue/README b/rescue/README index 3a8cb463fe5e..496575e1a323 100644 --- a/rescue/README +++ b/rescue/README @@ -16,8 +16,7 @@ normally found in /bin and /sbin. These Makefiles recompile each of the crunchgen components and include support for overriding specific library entries. Such techniques -should be useful elsewhere. For example, boot floppies could use this -to conditionally compile out features to reduce executable size. +should be useful elsewhere. 3) Produce a toolkit suitable for small distributions. @@ -27,8 +26,8 @@ system. These tools have one big disadvantage: being statically linked, they cannot use some advanced library functions that rely on dynamic -linking. In particular, nsswitch, locales, and pam are likely to all -rely on dynamic linking in the near future. +linking. In particular, nsswitch, locales, and pam all +rely on dynamic linking. To compile: diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile index a31d303bc848..06b5f3ff65fd 100644 --- a/rescue/rescue/Makefile +++ b/rescue/rescue/Makefile @@ -67,10 +67,6 @@ CRUNCH_ALIAS_rm= unlink CRUNCH_ALIAS_ed= red CRUNCH_ALIAS_pkill= pgrep -.if ${MK_RCMDS} != "no" -CRUNCH_PROGS_bin+= rcp -.endif - .if ${MK_TCSH} != "no" CRUNCH_PROGS_bin+= csh CRUNCH_ALIAS_csh= -csh tcsh -tcsh @@ -89,7 +85,7 @@ CRUNCH_SUPPRESS_LINK_-tcsh= 1 # headers in addition to the standard 'paths.h' header. # CRUNCH_SRCDIRS+= sbin -CRUNCH_PROGS_sbin= badsect \ +CRUNCH_PROGS_sbin= \ camcontrol clri devfs dmesg dump \ dumpfs dumpon fsck fsck_ffs fsck_msdosfs fsdb \ fsirand gbde geom ifconfig init \ diff --git a/rescue/rescue/Makefile.depend b/rescue/rescue/Makefile.depend index 3af6cf1fc661..1a01391d2b90 100644 --- a/rescue/rescue/Makefile.depend +++ b/rescue/rescue/Makefile.depend @@ -10,7 +10,6 @@ DIRDEPS = \ cddl/lib/libzfs_core \ cddl/lib/libzpool \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ @@ -25,6 +24,8 @@ DIRDEPS = \ lib/libc \ lib/libcam \ lib/libcapsicum \ + lib/libcasper/libcasper \ + lib/libcasper/services/cap_dns \ lib/libcompiler_rt \ lib/libcrypt \ lib/libdevstat \ diff --git a/sbin/Makefile b/sbin/Makefile index 43f3cec7e03c..ca9f42ec0d6b 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -6,7 +6,6 @@ # XXX MISSING: icheck ncheck SUBDIR=adjkerntz \ - badsect \ camcontrol \ clri \ comcontrol \ diff --git a/sbin/adjkerntz/Makefile.depend b/sbin/adjkerntz/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/adjkerntz/Makefile.depend +++ b/sbin/adjkerntz/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/badsect/Makefile b/sbin/badsect/Makefile deleted file mode 100644 index c344e6c63552..000000000000 --- a/sbin/badsect/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 -# $FreeBSD$ - -PACKAGE=runtime -PROG= badsect -LIBADD= ufs -MAN= badsect.8 - -.include diff --git a/sbin/badsect/badsect.8 b/sbin/badsect/badsect.8 deleted file mode 100644 index 498febab1d96..000000000000 --- a/sbin/badsect/badsect.8 +++ /dev/null @@ -1,133 +0,0 @@ -.\" Copyright (c) 1985, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)badsect.8 8.1 (Berkeley) 6/5/93 -.\" $FreeBSD$ -.\" -.Dd June 5, 1993 -.Dt BADSECT 8 -.Os -.Sh NAME -.Nm badsect -.Nd create files to contain bad sectors -.Sh SYNOPSIS -.Nm -.Ar bbdir sector ... -.Sh DESCRIPTION -The -.Nm -utility makes a file to contain a bad sector. -Normally, bad sectors -are made inaccessible by the standard formatter, which provides -a forwarding table for bad sectors to the driver. -If a driver supports the bad blocking standard it is much preferable to -use that method to isolate bad blocks, since the bad block forwarding -makes the pack appear perfect, and such packs can then be copied with -.Xr dd 1 . -The technique used by this program is also less general than -bad block forwarding, as -.Nm -cannot make amends for -bad blocks in the i-list of file systems or in swap areas. -.Pp -On some disks, -adding a sector which is suddenly bad to the bad sector table -currently requires the running of the standard -.Tn DEC -formatter. -Thus to deal with a newly bad block -or on disks where the drivers -do not support the bad-blocking standard -.Nm -may be used to good effect. -.Pp -The -.Nm -utility is used on a quiet file system in the following way: -First mount the file system, and change to its root directory. -Make a directory -.Li BAD -there. -Run -.Nm -giving as argument the -.Ar BAD -directory followed by -all the bad sectors you wish to add. -(The sector numbers must be relative to the beginning of -the file system, but this is not hard as the system reports -relative sector numbers in its console error messages.) -Then change back to the root directory, unmount the file system -and run -.Xr fsck 8 -on the file system. -The bad sectors should show up in two files -or in the bad sector files and the free list. -Have -.Xr fsck 8 -remove files containing the offending bad sectors, but -.Em do not -have it remove the -.Pa BAD/ Ns Em nnnnn -files. -This will leave the bad sectors in only the -.Li BAD -files. -.Pp -The -.Nm -utility works by giving the specified sector numbers in a -.Xr mknod 2 -system call, -creating an illegal file whose first block address is the block containing -bad sector and whose name is the bad sector number. -When it is discovered by -.Xr fsck 8 -it will ask -.Dq Li "HOLD BAD BLOCK \&?" . -A positive response will cause -.Xr fsck 8 -to convert the inode to a regular file containing the bad block. -.Sh DIAGNOSTICS -The -.Nm -utility refuses to attach a block that -resides in a critical area or is out of range of the file system. -A warning is issued if the block is already in use. -.Sh SEE ALSO -.Xr fsck 8 -.Sh HISTORY -The -.Nm -utility appeared in -.Bx 4.1 . -.Sh BUGS -If more than one sector which comprise a file system fragment are bad, -you should specify only one of them to -.Nm , -as the blocks in the bad sector files actually cover all the sectors in a -file system fragment. diff --git a/sbin/badsect/badsect.c b/sbin/badsect/badsect.c deleted file mode 100644 index 097e3b112f67..000000000000 --- a/sbin/badsect/badsect.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 1981, 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#if 0 -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1981, 1983, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static const char sccsid[] = "@(#)badsect.c 8.1 (Berkeley) 6/5/93"; -#endif -#endif -#include -__FBSDID("$FreeBSD$"); - -/* - * badsect - * - * Badsect takes a list of file-system relative sector numbers - * and makes files containing the blocks of which these sectors are a part. - * It can be used to contain sectors which have problems if these sectors - * are not part of the bad file for the pack (see bad144). For instance, - * this program can be used if the driver for the file system in question - * does not support bad block forwarding. - */ -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define sblock disk.d_fs -#define acg disk.d_cg -static struct uufsd disk; -static struct fs *fs = &sblock; -static int errs; - -int chkuse(daddr_t, int); - -static void -usage(void) -{ - fprintf(stderr, "usage: badsect bbdir blkno ...\n"); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - daddr_t diskbn; - daddr_t number; - struct stat stbuf, devstat; - struct dirent *dp; - DIR *dirp; - char name[2 * MAXPATHLEN]; - char *name_dir_end; - - if (argc < 3) - usage(); - if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) - err(2, "%s", argv[1]); - strcpy(name, _PATH_DEV); - if ((dirp = opendir(name)) == NULL) - err(3, "%s", name); - name_dir_end = name + strlen(name); - while ((dp = readdir(dirp)) != NULL) { - strcpy(name_dir_end, dp->d_name); - if (lstat(name, &devstat) < 0) - err(4, "%s", name); - if (stbuf.st_dev == devstat.st_rdev && - (devstat.st_mode & IFMT) == IFCHR) - break; - } - closedir(dirp); - if (dp == NULL) { - printf("Cannot find dev 0%lo corresponding to %s\n", - (u_long)stbuf.st_rdev, argv[1]); - exit(5); - } - if (ufs_disk_fillout(&disk, name) == -1) { - if (disk.d_error != NULL) - errx(6, "%s: %s", name, disk.d_error); - else - err(7, "%s", name); - } - for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { - number = strtol(*argv, NULL, 0); - if (errno == EINVAL || errno == ERANGE) - err(8, "%s", *argv); - if (chkuse(number, 1)) - continue; - diskbn = dbtofsb(fs, number); - if (mknod(*argv, IFMT|0600, (dev_t)diskbn) < 0) { - warn("%s", *argv); - errs++; - } - } - ufs_disk_close(&disk); - printf("Don't forget to run ``fsck %s''\n", name); - exit(errs); -} - -int -chkuse(daddr_t blkno, int cnt) -{ - int cg; - daddr_t fsbn, bn; - - fsbn = dbtofsb(fs, blkno); - if ((unsigned)(fsbn+cnt) > fs->fs_size) { - printf("block %ld out of range of file system\n", (long)blkno); - return (1); - } - cg = dtog(fs, fsbn); - if (fsbn < cgdmin(fs, cg)) { - if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { - printf("block %ld in non-data area: cannot attach\n", - (long)blkno); - return (1); - } - } else { - if ((fsbn+cnt) > cgbase(fs, cg+1)) { - printf("block %ld in non-data area: cannot attach\n", - (long)blkno); - return (1); - } - } - if (cgread1(&disk, cg) != 1) { - fprintf(stderr, "cg %d: could not be read\n", cg); - errs++; - return (1); - } - if (!cg_chkmagic(&acg)) { - fprintf(stderr, "cg %d: bad magic number\n", cg); - errs++; - return (1); - } - bn = dtogd(fs, fsbn); - if (isclr(cg_blksfree(&acg), bn)) - printf("Warning: sector %ld is in use\n", (long)blkno); - return (0); -} diff --git a/sbin/bsdlabel/Makefile.depend b/sbin/bsdlabel/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/sbin/bsdlabel/Makefile.depend +++ b/sbin/bsdlabel/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/camcontrol/Makefile.depend b/sbin/camcontrol/Makefile.depend index 48a48dd2446c..ee06e1c20939 100644 --- a/sbin/camcontrol/Makefile.depend +++ b/sbin/camcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ccdconfig/Makefile.depend b/sbin/ccdconfig/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/sbin/ccdconfig/Makefile.depend +++ b/sbin/ccdconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/clri/Makefile.depend b/sbin/clri/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/clri/Makefile.depend +++ b/sbin/clri/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/comcontrol/Makefile.depend b/sbin/comcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/comcontrol/Makefile.depend +++ b/sbin/comcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/conscontrol/Makefile.depend b/sbin/conscontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/conscontrol/Makefile.depend +++ b/sbin/conscontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ddb/Makefile.depend b/sbin/ddb/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/sbin/ddb/Makefile.depend +++ b/sbin/ddb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/decryptcore/Makefile.depend b/sbin/decryptcore/Makefile.depend index ff3df3c14de0..d718b860472f 100644 --- a/sbin/decryptcore/Makefile.depend +++ b/sbin/decryptcore/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/devd/Makefile.depend b/sbin/devd/Makefile.depend index 2e1231695ae5..8c3f699ac991 100644 --- a/sbin/devd/Makefile.depend +++ b/sbin/devd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/devd/tests/Makefile.depend b/sbin/devd/tests/Makefile.depend index 74074b9588ec..c062f6026d94 100644 --- a/sbin/devd/tests/Makefile.depend +++ b/sbin/devd/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/devfs/Makefile.depend b/sbin/devfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/devfs/Makefile.depend +++ b/sbin/devfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/dhclient/Makefile.depend b/sbin/dhclient/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/sbin/dhclient/Makefile.depend +++ b/sbin/dhclient/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/dhclient/tests/Makefile.depend b/sbin/dhclient/tests/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/sbin/dhclient/tests/Makefile.depend +++ b/sbin/dhclient/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/dmesg/Makefile.depend b/sbin/dmesg/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/sbin/dmesg/Makefile.depend +++ b/sbin/dmesg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/dump/Makefile.depend b/sbin/dump/Makefile.depend index 26cae4ede976..4bd09984c29d 100644 --- a/sbin/dump/Makefile.depend +++ b/sbin/dump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/protocols \ include/xlocale \ diff --git a/sbin/dumpfs/Makefile.depend b/sbin/dumpfs/Makefile.depend index 99cf113eba55..735bf03b75b6 100644 --- a/sbin/dumpfs/Makefile.depend +++ b/sbin/dumpfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c index cea9a95ba4ae..e163b4b69747 100644 --- a/sbin/dumpfs/dumpfs.c +++ b/sbin/dumpfs/dumpfs.c @@ -276,6 +276,24 @@ dumpfs(const char *name) if (fsflags != 0) printf("unknown flags (%#x)", fsflags); putchar('\n'); + printf("check hashes\t"); + fsflags = afs.fs_metackhash; + if (fsflags == 0) + printf("none"); + if (fsflags & CK_SUPERBLOCK) + printf("superblock "); + if (fsflags & CK_CYLGRP) + printf("cylinder-groups "); + if (fsflags & CK_INODE) + printf("inodes "); + if (fsflags & CK_INDIR) + printf("indirect-blocks "); + if (fsflags & CK_DIR) + printf("directories "); + fsflags &= ~(CK_SUPERBLOCK | CK_CYLGRP | CK_INODE | CK_INDIR | CK_DIR); + if (fsflags != 0) + printf("unknown flags (%#x)", fsflags); + putchar('\n'); printf("fsmnt\t%s\n", afs.fs_fsmnt); printf("volname\t%s\tswuid\t%ju\tprovidersize\t%ju\n", afs.fs_volname, (uintmax_t)afs.fs_swuid, diff --git a/sbin/dumpon/Makefile.depend b/sbin/dumpon/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/sbin/dumpon/Makefile.depend +++ b/sbin/dumpon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/dumpon/dumpon.8 b/sbin/dumpon/dumpon.8 index b0c8e2c12de4..572bd030aef1 100644 --- a/sbin/dumpon/dumpon.8 +++ b/sbin/dumpon/dumpon.8 @@ -28,7 +28,7 @@ .\" From: @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd December 10, 2016 +.Dd October 24, 2017 .Dt DUMPON 8 .Os .Sh NAME @@ -38,6 +38,7 @@ .Nm .Op Fl v .Op Fl k Ar public_key_file +.Op Fl z .Ar special_file .Nm .Op Fl v @@ -114,6 +115,22 @@ This flag requires a kernel compiled with the kernel option. .Pp The +.Fl z +option configures the kernel to compress the dump in gzip format before writing +it to the dump device. +This reduces the amount of space required for the dump and accelerates +recovery with +.Xr savecore 8 +since less data needs to be copied from the dump device. +When compression is enabled, the +.Nm +utility will not verify that the dump device is sufficiently large for a full +dump. +This flag requires a kernel compiled with the +.Dv GZIO +kernel option. +.Pp +The .Fl l flag causes .Nm @@ -272,3 +289,7 @@ utility appeared in .Sh BUGS Because the file system layer is already dead by the time a crash dump is taken, it is not possible to send crash dumps directly to a file. +.Pp +It is currently not possible to configure both compression and encryption. +The encrypted dump format assumes that the kernel dump size is a multiple +of the cipher block size, which may not be true when the dump is compressed. diff --git a/sbin/dumpon/dumpon.c b/sbin/dumpon/dumpon.c index e3701eace3db..8530c63b889d 100644 --- a/sbin/dumpon/dumpon.c +++ b/sbin/dumpon/dumpon.c @@ -71,7 +71,7 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n%s\n", - "usage: dumpon [-v] [-k public_key_file] special_file", + "usage: dumpon [-v] [-k public_key_file] [-z] special_file", " dumpon [-v] off", " dumpon [-v] -l"); exit(EX_USAGE); @@ -190,11 +190,12 @@ main(int argc, char *argv[]) int ch; int i, fd; int do_listdumpdev = 0; - bool enable; + bool enable, gzip; + gzip = false; pubkeyfile = NULL; - while ((ch = getopt(argc, argv, "k:lv")) != -1) + while ((ch = getopt(argc, argv, "k:lvz")) != -1) switch((char)ch) { case 'k': pubkeyfile = optarg; @@ -205,6 +206,9 @@ main(int argc, char *argv[]) case 'v': verbose = 1; break; + case 'z': + gzip = true; + break; default: usage(); } @@ -247,9 +251,11 @@ main(int argc, char *argv[]) fd = open(dumpdev, O_RDONLY); if (fd < 0) err(EX_OSFILE, "%s", dumpdev); - check_size(fd, dumpdev); - bzero(&kda, sizeof(kda)); + if (!gzip) + check_size(fd, dumpdev); + + bzero(&kda, sizeof(kda)); kda.kda_enable = 0; i = ioctl(fd, DIOCSKERNELDUMP, &kda); explicit_bzero(&kda, sizeof(kda)); @@ -260,6 +266,8 @@ main(int argc, char *argv[]) #endif kda.kda_enable = 1; + kda.kda_compression = gzip ? KERNELDUMP_COMP_GZIP : + KERNELDUMP_COMP_NONE; i = ioctl(fd, DIOCSKERNELDUMP, &kda); explicit_bzero(kda.kda_encryptedkey, kda.kda_encryptedkeysize); free(kda.kda_encryptedkey); diff --git a/sbin/etherswitchcfg/Makefile.depend b/sbin/etherswitchcfg/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/etherswitchcfg/Makefile.depend +++ b/sbin/etherswitchcfg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fdisk/Makefile.depend b/sbin/fdisk/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/sbin/fdisk/Makefile.depend +++ b/sbin/fdisk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ffsinfo/Makefile.depend b/sbin/ffsinfo/Makefile.depend index 99cf113eba55..735bf03b75b6 100644 --- a/sbin/ffsinfo/Makefile.depend +++ b/sbin/ffsinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fsck/Makefile.depend b/sbin/fsck/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/fsck/Makefile.depend +++ b/sbin/fsck/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fsck_ffs/Makefile.depend b/sbin/fsck_ffs/Makefile.depend index 99cf113eba55..735bf03b75b6 100644 --- a/sbin/fsck_ffs/Makefile.depend +++ b/sbin/fsck_ffs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index f4da123b18f9..16d960d155af 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "fsck.h" @@ -349,6 +350,20 @@ flush(int fd, struct bufarea *bp) if (!bp->b_dirty) return; + /* + * Calculate any needed check hashes. + */ + switch (bp->b_type) { + case BT_CYLGRP: + if ((sblock.fs_metackhash & CK_CYLGRP) == 0) + break; + bp->b_un.b_cg->cg_ckhash = 0; + bp->b_un.b_cg->cg_ckhash = + calculate_crc32c(~0L, bp->b_un.b_buf, bp->b_size); + break; + default: + break; + } bp->b_dirty = 0; if (fswritefd < 0) { pfatal("WRITING IN READ_ONLY MODE.\n"); diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 5c800b8e0642..32082c1c126f 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -231,6 +231,7 @@ checkfilesys(char *filesys) struct group *grp; struct iovec *iov; char errmsg[255]; + int ofsmodified; int iovlen; int cylno; intmax_t blks, files; @@ -425,10 +426,15 @@ checkfilesys(char *filesys) } /* * Write the superblock so we don't try to recover the - * journal on another pass. + * journal on another pass. If this is the only change + * to the filesystem, we do not want it to be called + * out as modified. */ sblock.fs_mtime = time(NULL); sbdirty(); + ofsmodified = fsmodified; + flush(fswritefd, &sblk); + fsmodified = ofsmodified; } /* diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index ef289c4342ac..16c46bece00b 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -71,6 +71,13 @@ pass5(void) inoinfo(UFS_WINO)->ino_state = USTATE; memset(newcg, 0, (size_t)fs->fs_cgsize); newcg->cg_niblk = fs->fs_ipg; + if (preen == 0 && yflag == 0 && fs->fs_magic == FS_UFS2_MAGIC && + fswritefd != -1 && (fs->fs_metackhash & CK_CYLGRP) == 0 && + reply("ADD CYLINDER GROUP CHECKSUM PROTECTION") != 0) { + fs->fs_metackhash |= CK_CYLGRP; + rewritecg = 1; + sbdirty(); + } if (cvtlevel >= 3) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (preen) @@ -305,6 +312,12 @@ pass5(void) sump[run]++; } } + if ((fs->fs_metackhash & CK_CYLGRP) != 0) { + newcg->cg_ckhash = 0; + newcg->cg_ckhash = + calculate_crc32c(~0L, (void *)newcg, fs->fs_cgsize); + } + if (bkgrdflag != 0) { cstotal.cs_nffree += cg->cg_cs.cs_nffree; cstotal.cs_nbfree += cg->cg_cs.cs_nbfree; diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c index 72bf83cdb2f5..f537537d2e3b 100644 --- a/sbin/fsck_ffs/suj.c +++ b/sbin/fsck_ffs/suj.c @@ -1395,7 +1395,7 @@ ino_adjust(struct suj_ino *sino) } ip = ino_read(ino); mode = DIP(ip, di_mode) & IFMT; - if (nlink > LINK_MAX) + if (nlink > UFS_LINK_MAX) err_suj("ino %ju nlink manipulation error, new %ju, old %d\n", (uintmax_t)ino, (uintmax_t)nlink, DIP(ip, di_nlink)); if (debug) diff --git a/sbin/fsck_msdosfs/Makefile.depend b/sbin/fsck_msdosfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/fsck_msdosfs/Makefile.depend +++ b/sbin/fsck_msdosfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fsdb/Makefile b/sbin/fsdb/Makefile index a3e7545c7c5a..96b93cd1690b 100644 --- a/sbin/fsdb/Makefile +++ b/sbin/fsdb/Makefile @@ -10,7 +10,7 @@ SRCS= fsdb.c fsdbutil.c \ pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c globs.c CFLAGS+= -I${.CURDIR:H}/fsck_ffs WARNS?= 2 -LIBADD= edit +LIBADD= edit ufs .PATH: ${.CURDIR:H}/fsck_ffs ${SRCTOP}/sys/ufs/ffs .include diff --git a/sbin/fsdb/Makefile.depend b/sbin/fsdb/Makefile.depend index a1c5d0315275..7fdfb8aa8455 100644 --- a/sbin/fsdb/Makefile.depend +++ b/sbin/fsdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/fsirand/Makefile.depend b/sbin/fsirand/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/fsirand/Makefile.depend +++ b/sbin/fsirand/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/gbde/Makefile.depend b/sbin/gbde/Makefile.depend index f2694f43d6d0..262aec4302c7 100644 --- a/sbin/gbde/Makefile.depend +++ b/sbin/gbde/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/cache/Makefile.depend b/sbin/geom/class/cache/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/cache/Makefile.depend +++ b/sbin/geom/class/cache/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/concat/Makefile.depend b/sbin/geom/class/concat/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/concat/Makefile.depend +++ b/sbin/geom/class/concat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/eli/Makefile.depend b/sbin/geom/class/eli/Makefile.depend index cbf4e19581db..3378fcd11dbc 100644 --- a/sbin/geom/class/eli/Makefile.depend +++ b/sbin/geom/class/eli/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/eli/geli.8 b/sbin/geom/class/eli/geli.8 index e773cce7b4c9..c3e36fd7263e 100644 --- a/sbin/geom/class/eli/geli.8 +++ b/sbin/geom/class/eli/geli.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 26, 2017 +.Dd September 17, 2017 .Dt GELI 8 .Os .Sh NAME @@ -280,8 +280,10 @@ To inhibit backups, you can use as the .Ar backupfile . .It Fl d -While booting from this encrypted root filesystem enable visibility of -passphrase length. +When entering the passphrase to boot from this encrypted root filesystem, echo +.Ql * +characters. +This makes the length of the passphrase visible. .It Fl e Ar ealgo Encryption algorithm to use. Currently supported algorithms are: @@ -494,11 +496,14 @@ subcommand. .It Fl B Remove the BOOT flag from the given providers. .It Fl d -While booting from this encrypted root filesystem enable visibility of -passphrase length. +When entering the passphrase to boot from this encrypted root filesystem, echo +.Ql * +characters. +This makes the length of the passphrase visible. .It Fl D -While booting from this encrypted root filesystem disable visibility of -passphrase length. +Disable echoing of any characters when a passphrase is entered to boot from this +encrypted root filesystem. +This hides the passphrase length. .It Fl g Enable booting from this encrypted root filesystem. The boot loader prompts for the passphrase and loads diff --git a/sbin/geom/class/journal/Makefile.depend b/sbin/geom/class/journal/Makefile.depend index f04aa870d29a..7c411851c451 100644 --- a/sbin/geom/class/journal/Makefile.depend +++ b/sbin/geom/class/journal/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/label/Makefile.depend b/sbin/geom/class/label/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/label/Makefile.depend +++ b/sbin/geom/class/label/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/mirror/Makefile.depend b/sbin/geom/class/mirror/Makefile.depend index 87303d7152ce..7902e1927044 100644 --- a/sbin/geom/class/mirror/Makefile.depend +++ b/sbin/geom/class/mirror/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/mountver/Makefile.depend b/sbin/geom/class/mountver/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/mountver/Makefile.depend +++ b/sbin/geom/class/mountver/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/multipath/Makefile.depend b/sbin/geom/class/multipath/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/multipath/Makefile.depend +++ b/sbin/geom/class/multipath/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/nop/Makefile.depend b/sbin/geom/class/nop/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/nop/Makefile.depend +++ b/sbin/geom/class/nop/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/part/Makefile.depend b/sbin/geom/class/part/Makefile.depend index 462276464cf8..29b9a504acf9 100644 --- a/sbin/geom/class/part/Makefile.depend +++ b/sbin/geom/class/part/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index d21e5eb6b657..7f668d32e9a6 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -547,7 +547,7 @@ gpart_autofill(struct gctl_req *req) last = (off_t)strtoimax(s, NULL, 0); grade = ~0ULL; a_first = ALIGNUP(first + offset, alignment); - last = ALIGNDOWN(last + offset, alignment); + last = ALIGNDOWN(last + offset + 1, alignment) - 1; if (a_first < start) a_first = start; while ((pp = find_provider(gp, first)) != NULL) { diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index dc05c8220db4..e0199cb4f317 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2016 +.Dd September 19, 2017 .Dt GPART 8 .Os .Sh NAME @@ -1325,6 +1325,29 @@ After creating all required partitions, embed bootstrap code into them: .Bd -literal -offset indent /sbin/gpart bootcode -p /boot/boot1 da0 .Ed +.Ss Deleting partitions and partitioning scheme +If you get a +.Em "Device busy" +error when trying to destroy a partition table, remember that you must +delete all its partitions first with the +.Cm delete +action. +In this example, assume we have +.Pa da0 +with three partitions: +.Bd -literal -offset indent +/sbin/gpart delete -i 3 da0 +/sbin/gpart delete -i 2 da0 +/sbin/gpart delete -i 1 da0 +/sbin/gpart destroy da0 +.Ed +.Pp +Alternatively, you can invoke the +.Cm destroy +action with the +.Fl F +flag. +.Ed .Ss Backup and Restore .Pp Create a backup of the partition table from diff --git a/sbin/geom/class/raid/Makefile.depend b/sbin/geom/class/raid/Makefile.depend index 87303d7152ce..7902e1927044 100644 --- a/sbin/geom/class/raid/Makefile.depend +++ b/sbin/geom/class/raid/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/raid3/Makefile.depend b/sbin/geom/class/raid3/Makefile.depend index 87303d7152ce..7902e1927044 100644 --- a/sbin/geom/class/raid3/Makefile.depend +++ b/sbin/geom/class/raid3/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/sched/Makefile.depend b/sbin/geom/class/sched/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/sched/Makefile.depend +++ b/sbin/geom/class/sched/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/shsec/Makefile.depend b/sbin/geom/class/shsec/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/shsec/Makefile.depend +++ b/sbin/geom/class/shsec/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/stripe/Makefile.depend b/sbin/geom/class/stripe/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/stripe/Makefile.depend +++ b/sbin/geom/class/stripe/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/class/virstor/Makefile.depend b/sbin/geom/class/virstor/Makefile.depend index 1c2c57cc225a..fb5f86e931fb 100644 --- a/sbin/geom/class/virstor/Makefile.depend +++ b/sbin/geom/class/virstor/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/geom/core/Makefile.depend b/sbin/geom/core/Makefile.depend index 77629333af5f..3f477bc3f8b0 100644 --- a/sbin/geom/core/Makefile.depend +++ b/sbin/geom/core/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ggate/ggatec/Makefile.depend b/sbin/ggate/ggatec/Makefile.depend index 73bafe444f3c..4fb720d36316 100644 --- a/sbin/ggate/ggatec/Makefile.depend +++ b/sbin/ggate/ggatec/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ggate/ggated/Makefile.depend b/sbin/ggate/ggated/Makefile.depend index 918509195413..408a62870b41 100644 --- a/sbin/ggate/ggated/Makefile.depend +++ b/sbin/ggate/ggated/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ggate/ggatel/Makefile.depend b/sbin/ggate/ggatel/Makefile.depend index 8ea3042fce46..1096cf51d094 100644 --- a/sbin/ggate/ggatel/Makefile.depend +++ b/sbin/ggate/ggatel/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/growfs/Makefile b/sbin/growfs/Makefile index 01a209849789..8aeb9d77509e 100644 --- a/sbin/growfs/Makefile +++ b/sbin/growfs/Makefile @@ -20,7 +20,7 @@ CFLAGS+= -DFS_DEBUG NO_WCAST_ALIGN= yes .endif -LIBADD= util +LIBADD= ufs util HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/sbin/growfs/Makefile.depend b/sbin/growfs/Makefile.depend index 58f9a3347b00..51f2384d1c84 100644 --- a/sbin/growfs/Makefile.depend +++ b/sbin/growfs/Makefile.depend @@ -3,12 +3,12 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libufs \ lib/libutil \ diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index 0aa4d4586e6f..2e8271b39d5d 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "debug.h" @@ -121,6 +122,7 @@ static void updcsloc(time_t, int, int, unsigned int); static void frag_adjust(ufs2_daddr_t, int); static void updclst(int); static void mount_reload(const struct statfs *stfs); +static void cgckhash(struct cg *); /* * Here we actually start growing the file system. We basically read the @@ -480,6 +482,7 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag) sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree; *cs = acg.cg_cs; + cgckhash(&acg); memcpy(iobuf, &acg, sblock.fs_cgsize); memset(iobuf + sblock.fs_cgsize, '\0', sblock.fs_bsize * 3 - sblock.fs_cgsize); @@ -771,6 +774,7 @@ updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag) /* * Write the updated "joining" cylinder group back to disk. */ + cgckhash(&acg); wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); DBG_PRINT0("jcg written\n"); @@ -1739,3 +1743,16 @@ mount_reload(const struct statfs *stfs) *errmsg != '\0' ? ": " : "", errmsg); } } + +/* + * Calculate the check-hash of the cylinder group. + */ +static void +cgckhash(struct cg *cgp) +{ + + if ((sblock.fs_metackhash & CK_CYLGRP) == 0) + return; + cgp->cg_ckhash = 0; + cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize); +} diff --git a/sbin/growfs/tests/legacy_test.pl b/sbin/growfs/tests/legacy_test.pl index 727960290d1a..931a57b6dde4 100755 --- a/sbin/growfs/tests/legacy_test.pl +++ b/sbin/growfs/tests/legacy_test.pl @@ -2,6 +2,7 @@ use strict; use warnings; +use POSIX; use Test::More tests => 19; use Fcntl qw(:DEFAULT :seek); @@ -11,6 +12,22 @@ use constant BLKS_PER_MB => 2048; my $unit; END { system "mdconfig -du$unit" if defined $unit }; +sub fsck_md { + my ($is_clean, $md); + + $md = shift; + + chomp(my @fsck_output = `fsck_ffs -Ffy ${md}a`); + $is_clean = WIFEXITED($?) && + (WEXITSTATUS($?) == 0 || WEXITSTATUS($?) == 7); + ok($is_clean, "checking ${md}a's filesystem"); + if ($is_clean) { + diag "filesystem reported clean"; + } else { + diag "filesystem not reported clean: " . join("\n", @fsck_output); + } +} + sub setsize { my ($partszMB, $unitszMB) = @_; @@ -46,9 +63,8 @@ SKIP: { ok(setsize(10, 40), "Sized ${md}a to 10m"); system "newfs -O $type -U ${md}a >/dev/null"; is($?, 0, "Initialised the filesystem on ${md}a as UFS$type"); - chomp(my @out = `fsck -tufs -y ${md}a`); - ok(!grep(/MODIFIED/, @out), "fsck says ${md}a is clean, " . - scalar(@out) . " lines of output"); + + fsck_md($md); } extend20_zeroed: { @@ -62,9 +78,7 @@ SKIP: { fill(30 * BLKS_PER_MB - $unallocated, $unallocated, chr(0)) if $unallocated; - chomp(my @out = `fsck -tufs -y ${md}a`); - ok(!grep(/MODIFIED/, @out), "fsck says ${md}a is clean, " . - scalar(@out) . " lines of output"); + fsck_md($md); } extend30_garbaged: { @@ -78,9 +92,7 @@ SKIP: { fill(30 * BLKS_PER_MB - $unallocated, $unallocated, chr(0)) if $unallocated; - chomp(my @out = `fsck -tufs -y ${md}a`); - ok(!grep(/MODIFIED/, @out), "fsck says ${md}a is clean, " . - scalar(@out) . " lines of output"); + fsck_md($md); } } diff --git a/sbin/gvinum/Makefile.depend b/sbin/gvinum/Makefile.depend index 30266ac3ea0c..bc5225ea2a80 100644 --- a/sbin/gvinum/Makefile.depend +++ b/sbin/gvinum/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/hastctl/Makefile.depend b/sbin/hastctl/Makefile.depend index cedd9669cacf..371ab3746dcc 100644 --- a/sbin/hastctl/Makefile.depend +++ b/sbin/hastctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/hastd/Makefile.depend b/sbin/hastd/Makefile.depend index 9394623beea3..9a828fd8932d 100644 --- a/sbin/hastd/Makefile.depend +++ b/sbin/hastd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ifconfig/Makefile.depend b/sbin/ifconfig/Makefile.depend index 9096e8c570ab..b750e5b894fc 100644 --- a/sbin/ifconfig/Makefile.depend +++ b/sbin/ifconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/init/Makefile.depend b/sbin/init/Makefile.depend index d8297c28fac7..10a95e7fdc38 100644 --- a/sbin/init/Makefile.depend +++ b/sbin/init/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/init/init.8 b/sbin/init/init.8 index 2e64e598bccb..cefbf499d98a 100644 --- a/sbin/init/init.8 +++ b/sbin/init/init.8 @@ -286,6 +286,7 @@ as follows: .It Sy "Run-level Signal Action" .It Cm 0 Ta Dv SIGUSR1 Ta "Halt" .It Cm 0 Ta Dv SIGUSR2 Ta "Halt and turn the power off" +.It Cm 0 Ta Dv SIGWINCH Ta "Halt and turn the power off and then back on" .It Cm 1 Ta Dv SIGTERM Ta "Go to single-user mode" .It Cm 6 Ta Dv SIGINT Ta "Reboot the machine" .It Cm c Ta Dv SIGTSTP Ta "Block further logins" diff --git a/sbin/init/init.c b/sbin/init/init.c index 34e40457622f..e6fcdb93ef3e 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -305,12 +305,12 @@ main(int argc, char *argv[]) handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, - SIGUSR1, SIGUSR2, 0); + SIGUSR1, SIGUSR2, SIGWINCH, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, - SIGALRM, SIGUSR1, SIGUSR2, 0); + SIGALRM, SIGUSR1, SIGUSR2, SIGWINCH, 0); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -919,7 +919,7 @@ single_user(void) _exit(0); password = crypt(clear, pp->pw_passwd); bzero(clear, _PASSWORD_LEN); - if (password == NULL || + if (password != NULL && strcmp(password, pp->pw_passwd) == 0) break; warning("single-user login failed\n"); @@ -1557,8 +1557,9 @@ transition_handler(int sig) current_state == clean_ttys || current_state == catatonia) requested_transition = clean_ttys; break; + case SIGWINCH: case SIGUSR2: - howto = RB_POWEROFF; + howto = sig == SIGUSR2 ? RB_POWEROFF : RB_POWERCYCLE; case SIGUSR1: howto |= RB_HALT; case SIGINT: diff --git a/sbin/ipf/ipf/Makefile.depend b/sbin/ipf/ipf/Makefile.depend index fc64f41e34eb..84ddd8bb35de 100644 --- a/sbin/ipf/ipf/Makefile.depend +++ b/sbin/ipf/ipf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipfs/Makefile.depend b/sbin/ipf/ipfs/Makefile.depend index 6773fa2ca5d4..2b60f342cc06 100644 --- a/sbin/ipf/ipfs/Makefile.depend +++ b/sbin/ipf/ipfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipfstat/Makefile.depend b/sbin/ipf/ipfstat/Makefile.depend index 8f5d6f7f990a..8e480ba0d4ec 100644 --- a/sbin/ipf/ipfstat/Makefile.depend +++ b/sbin/ipf/ipfstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipftest/Makefile.depend b/sbin/ipf/ipftest/Makefile.depend index 6fbd5941772d..cfe5ad5352e5 100644 --- a/sbin/ipf/ipftest/Makefile.depend +++ b/sbin/ipf/ipftest/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipmon/Makefile.depend b/sbin/ipf/ipmon/Makefile.depend index 6fbd5941772d..cfe5ad5352e5 100644 --- a/sbin/ipf/ipmon/Makefile.depend +++ b/sbin/ipf/ipmon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipnat/Makefile.depend b/sbin/ipf/ipnat/Makefile.depend index 6fbd5941772d..cfe5ad5352e5 100644 --- a/sbin/ipf/ipnat/Makefile.depend +++ b/sbin/ipf/ipnat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ippool/Makefile.depend b/sbin/ipf/ippool/Makefile.depend index 6fbd5941772d..cfe5ad5352e5 100644 --- a/sbin/ipf/ippool/Makefile.depend +++ b/sbin/ipf/ippool/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipf/ipresend/Makefile.depend b/sbin/ipf/ipresend/Makefile.depend index 6795d2cff035..a1632c6f3baa 100644 --- a/sbin/ipf/ipresend/Makefile.depend +++ b/sbin/ipf/ipresend/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipfw/Makefile.depend b/sbin/ipfw/Makefile.depend index 94816f2b0d84..5700139d85dd 100644 --- a/sbin/ipfw/Makefile.depend +++ b/sbin/ipfw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 96349a0563ce..cb19b5b65d2a 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 3, 2017 +.Dd October 2, 2017 .Dt IPFW 8 .Os .Sh NAME @@ -537,7 +537,7 @@ for filtering packets, among the following: .It Layer-2 header fields When available .It IPv4 and IPv6 Protocol -TCP, UDP, ICMP, etc. +SCTP, TCP, UDP, ICMP, etc. .It Source and dest. addresses and ports .It Direction See Section @@ -1396,7 +1396,7 @@ error-prone. No support for sets of IPv6 addresses is provided because IPv6 addresses are typically random past the initial prefix. .It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Ns Op , Ns Ar ports -For protocols which support port numbers (such as TCP and UDP), optional +For protocols which support port numbers (such as SCTP, TCP and UDP), optional .Cm ports may be specified as one or more ports or port ranges, separated by commas but no spaces, and an optional diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h index 13018f899db3..1ff9c38d1ea4 100644 --- a/sbin/ipfw/ipfw2.h +++ b/sbin/ipfw/ipfw2.h @@ -205,14 +205,14 @@ enum tokens { TOK_IP, TOK_IF, - TOK_ALOG, - TOK_DENY_INC, - TOK_SAME_PORTS, - TOK_UNREG_ONLY, + TOK_ALOG, + TOK_DENY_INC, + TOK_SAME_PORTS, + TOK_UNREG_ONLY, TOK_SKIP_GLOBAL, - TOK_RESET_ADDR, - TOK_ALIAS_REV, - TOK_PROXY_ONLY, + TOK_RESET_ADDR, + TOK_ALIAS_REV, + TOK_PROXY_ONLY, TOK_REDIR_ADDR, TOK_REDIR_PORT, TOK_REDIR_PROTO, diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c index 9aad4d959c7a..89bc36375d87 100644 --- a/sbin/ipfw/tables.c +++ b/sbin/ipfw/tables.c @@ -885,6 +885,8 @@ table_do_modify_record(int cmd, ipfw_obj_header *oh, sz += sizeof(*oh); error = do_get3(cmd, &oh->opheader, &sz); + if (error != 0) + error = errno; tent = (ipfw_obj_tentry *)(ctlv + 1); /* Copy result back to provided buffer */ memcpy(tent_base, ctlv + 1, sizeof(*tent) * count); diff --git a/sbin/iscontrol/Makefile.depend b/sbin/iscontrol/Makefile.depend index 6e045828d269..c800a3df77c3 100644 --- a/sbin/iscontrol/Makefile.depend +++ b/sbin/iscontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/kldconfig/Makefile.depend b/sbin/kldconfig/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/kldconfig/Makefile.depend +++ b/sbin/kldconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/kldload/Makefile.depend b/sbin/kldload/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/kldload/Makefile.depend +++ b/sbin/kldload/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/kldstat/Makefile.depend b/sbin/kldstat/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/sbin/kldstat/Makefile.depend +++ b/sbin/kldstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/kldunload/Makefile.depend b/sbin/kldunload/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/sbin/kldunload/Makefile.depend +++ b/sbin/kldunload/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/sbin/ldconfig/Makefile.depend b/sbin/ldconfig/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/ldconfig/Makefile.depend +++ b/sbin/ldconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ldconfig/ldconfig.c b/sbin/ldconfig/ldconfig.c index 85d97e68cdb0..764ca3e12ab2 100644 --- a/sbin/ldconfig/ldconfig.c +++ b/sbin/ldconfig/ldconfig.c @@ -550,7 +550,7 @@ readhints(void) } msize = PAGE_SIZE; - addr = mmap(0, msize, PROT_READ, MAP_COPY, fd, 0); + addr = mmap(0, msize, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { warn("%s", hints_file); @@ -573,7 +573,7 @@ readhints(void) if (hdr->hh_ehints > msize) { fsize = hdr->hh_ehints; munmap(addr, msize); - addr = mmap(0, fsize, PROT_READ, MAP_COPY, fd, 0); + addr = mmap(0, fsize, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { warn("%s", hints_file); return -1; diff --git a/sbin/md5/Makefile.depend b/sbin/md5/Makefile.depend index 8aac374844ec..18541d6a1857 100644 --- a/sbin/md5/Makefile.depend +++ b/sbin/md5/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mdconfig/Makefile.depend b/sbin/mdconfig/Makefile.depend index bfd9ff6f1fc4..7cae0ca03e1e 100644 --- a/sbin/mdconfig/Makefile.depend +++ b/sbin/mdconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mdmfs/Makefile.depend b/sbin/mdmfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mdmfs/Makefile.depend +++ b/sbin/mdmfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mdmfs/mdmfs.8 b/sbin/mdmfs/mdmfs.8 index 30a81fa49cf6..7505ff214ca8 100644 --- a/sbin/mdmfs/mdmfs.8 +++ b/sbin/mdmfs/mdmfs.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 9, 2016 +.Dd September 9, 2017 .Dt MDMFS 8 .Os .Sh NAME @@ -33,7 +33,9 @@ .Nm mount_mfs .Nd configure and mount an in-memory file system using the .Xr md 4 -driver +driver or the +.Xr tmpfs 5 +filesystem .Sh SYNOPSIS .Nm .Op Fl DLlMNnPStTUX @@ -63,9 +65,13 @@ utility is designed to be a work-alike and look-alike of the deprecated .Xr mount_mfs 8 . The end result is essentially the same, but is accomplished in a completely different way. -The +Based on +.Ar md-device , +the .Nm -utility configures an +utility either creates a +.Xr tmpfs 5 +filesystem, or it configures an .Xr md 4 disk using .Xr mdconfig 8 , @@ -81,6 +87,44 @@ compressed disk images, as long as the kernel supports this GEOM class. All the command line options are passed to the appropriate program at the appropriate stage in order to achieve the desired effect. .Pp +When +.Ar md-device +is `auto', +.Nm +uses +.Xr tmpfs 5 +if it is present in the kernel or can be loaded as a module, +otherwise it falls back to using +.Xr md 4 +auto-unit as if `md' had been specified. +.Pp +When +.Ar md-device +is `tmpfs', +.Nm +mounts a +.Xr tmpfs 5 +filesystem, translating the +.Fl s +size option, if present, into a `-o size=' mount option. +Any +.Fl o +options on the command line are passed through to the +.Xr tmpfs 5 +mount. +Options specific to +.Xr mdconfig 8 +or +.Xr newfs 8 +are ignored. +.Pp +When +.Ar md-device +does not result in +.Xr tmpfs 5 +being used, then an +.Xr md 4 +device is configured instead. By default, .Nm creates a swap-based @@ -219,14 +263,10 @@ is .Em not specified. That is, -this will work for the default swap-backed -.Pq Dv MD_SWAP -disks, -and the optional -.Pq Fl M -.Xr malloc 9 -backed disks -.Pq Dv MD_MALLOC . +this will work when the backing storage is some form of +memory, as opposed to a fixed-size file. +The size may include the usual SI suffixes (k, m, g, t, p). +A number without a suffix is interpreted as a count of 512-byte sectors. .It Fl t Turn on the TRIM enable flag for .Xr newfs 8 . @@ -392,6 +432,7 @@ was given on the command line. .Sh SEE ALSO .Xr md 4 , .Xr fstab 5 , +.Xr tmpfs 5 , .Xr mdconfig 8 , .Xr mount 8 , .Xr newfs 8 diff --git a/sbin/mdmfs/mdmfs.c b/sbin/mdmfs/mdmfs.c index 4b3a012ff50f..ee2faf0dcbaf 100644 --- a/sbin/mdmfs/mdmfs.c +++ b/sbin/mdmfs/mdmfs.c @@ -34,15 +34,19 @@ __FBSDID("$FreeBSD$"); #include +#include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -78,7 +82,8 @@ static void debugprintf(const char *, ...) __printflike(1, 2); static void do_mdconfig_attach(const char *, const enum md_types); static void do_mdconfig_attach_au(const char *, const enum md_types); static void do_mdconfig_detach(void); -static void do_mount(const char *, const char *); +static void do_mount_md(const char *, const char *); +static void do_mount_tmpfs(const char *, const char *); static void do_mtptsetup(const char *, struct mtpt_info *); static void do_newfs(const char *); static void extract_ugid(const char *, struct mtpt_info *); @@ -89,14 +94,15 @@ int main(int argc, char **argv) { struct mtpt_info mi; /* Mountpoint info. */ + intmax_t mdsize; char *mdconfig_arg, *newfs_arg, /* Args to helper programs. */ *mount_arg; enum md_types mdtype; /* The type of our memory disk. */ - bool have_mdtype; + bool have_mdtype, mlmac; bool detach, softdep, autounit, newfs; - char *mtpoint, *unitstr; + const char *mtpoint, *size_arg, *unitstr; char *p; - int ch; + int ch, idx; void *set; unsigned long ul; @@ -105,11 +111,13 @@ main(int argc, char **argv) detach = true; softdep = true; autounit = false; + mlmac = false; newfs = true; have_mdtype = false; mdtype = MD_SWAP; mdname = MD_NAME; mdnamelen = strlen(mdname); + mdsize = 0; /* * Can't set these to NULL. They may be passed to the * respective programs without modification. I.e., we may not @@ -119,6 +127,7 @@ main(int argc, char **argv) mdconfig_arg = strdup(""); newfs_arg = strdup(""); mount_arg = strdup(""); + size_arg = NULL; /* If we were started as mount_mfs or mfs, imply -C. */ if (strcmp(getprogname(), "mount_mfs") == 0 || @@ -175,6 +184,7 @@ main(int argc, char **argv) loudsubs = true; break; case 'l': + mlmac = true; argappend(&newfs_arg, "-l"); break; case 'M': @@ -213,7 +223,7 @@ main(int argc, char **argv) softdep = false; break; case 's': - argappend(&mdconfig_arg, "-s %s", optarg); + size_arg = optarg; break; case 't': argappend(&newfs_arg, "-t"); @@ -242,42 +252,107 @@ main(int argc, char **argv) if (argc < 2) usage(); - /* Derive 'unit' (global). */ - unitstr = argv[0]; - if (strncmp(unitstr, "/dev/", 5) == 0) - unitstr += 5; - if (strncmp(unitstr, mdname, mdnamelen) == 0) - unitstr += mdnamelen; - if (!isdigit(*unitstr)) { - autounit = true; - unit = -1; - mdsuffix = unitstr; - } else { - ul = strtoul(unitstr, &p, 10); - if (ul == ULONG_MAX) - errx(1, "bad device unit: %s", unitstr); - unit = ul; - mdsuffix = p; /* can be empty */ + /* + * Historically our size arg was passed directly to mdconfig, which + * treats a number without a suffix as a count of 512-byte sectors; + * tmpfs would treat it as a count of bytes. To get predictable + * behavior for 'auto' we document that the size always uses mdconfig + * rules. To make that work, decode the size here so it can be passed + * to either tmpfs or mdconfig as a count of bytes. + */ + if (size_arg != NULL) { + mdsize = (intmax_t)strtoumax(size_arg, &p, 0); + if (p == size_arg || (p[0] != 0 && p[1] != 0) || mdsize < 0) + errx(1, "invalid size '%s'", size_arg); + switch (*p) { + case 'p': + case 'P': + mdsize *= 1024; + case 't': + case 'T': + mdsize *= 1024; + case 'g': + case 'G': + mdsize *= 1024; + case 'm': + case 'M': + mdsize *= 1024; + case 'k': + case 'K': + mdsize *= 1024; + case 'b': + case 'B': + break; + case '\0': + mdsize *= 512; + break; + default: + errx(1, "invalid size suffix on '%s'", size_arg); + } } + /* + * Based on the command line 'md-device' either mount a tmpfs filesystem + * or configure the md device then format and mount a filesystem on it. + * If the device is 'auto' use tmpfs if it is available and there is no + * request for multilabel MAC (which tmpfs does not support). + */ + unitstr = argv[0]; mtpoint = argv[1]; - if (!have_mdtype) - mdtype = MD_SWAP; - if (softdep) - argappend(&newfs_arg, "-U"); - if (mdtype != MD_VNODE && !newfs) - errx(1, "-P requires a vnode-backed disk"); - /* Do the work. */ - if (detach && !autounit) - do_mdconfig_detach(); - if (autounit) - do_mdconfig_attach_au(mdconfig_arg, mdtype); - else - do_mdconfig_attach(mdconfig_arg, mdtype); - if (newfs) - do_newfs(newfs_arg); - do_mount(mount_arg, mtpoint); + if (strcmp(unitstr, "auto") == 0) { + if (mlmac) + idx = -1; /* Must use md for mlmac. */ + else if ((idx = modfind("tmpfs")) == -1) + idx = kldload("tmpfs"); + if (idx == -1) + unitstr = "md"; + else + unitstr = "tmpfs"; + } + + if (strcmp(unitstr, "tmpfs") == 0) { + if (size_arg != NULL && mdsize != 0) + argappend(&mount_arg, "-o size=%jd", mdsize); + do_mount_tmpfs(mount_arg, mtpoint); + } else { + if (size_arg != NULL) + argappend(&mdconfig_arg, "-s %jdB", mdsize); + if (strncmp(unitstr, "/dev/", 5) == 0) + unitstr += 5; + if (strncmp(unitstr, mdname, mdnamelen) == 0) + unitstr += mdnamelen; + if (!isdigit(*unitstr)) { + autounit = true; + unit = -1; + mdsuffix = unitstr; + } else { + ul = strtoul(unitstr, &p, 10); + if (ul == ULONG_MAX) + errx(1, "bad device unit: %s", unitstr); + unit = ul; + mdsuffix = p; /* can be empty */ + } + + if (!have_mdtype) + mdtype = MD_SWAP; + if (softdep) + argappend(&newfs_arg, "-U"); + if (mdtype != MD_VNODE && !newfs) + errx(1, "-P requires a vnode-backed disk"); + + /* Do the work. */ + if (detach && !autounit) + do_mdconfig_detach(); + if (autounit) + do_mdconfig_attach_au(mdconfig_arg, mdtype); + else + do_mdconfig_attach(mdconfig_arg, mdtype); + if (newfs) + do_newfs(newfs_arg); + do_mount_md(mount_arg, mtpoint); + } + do_mtptsetup(mtpoint, &mi); return (0); @@ -434,7 +509,7 @@ do_mdconfig_detach(void) * Mount the configured memory disk. */ static void -do_mount(const char *args, const char *mtpoint) +do_mount_md(const char *args, const char *mtpoint) { int rv; @@ -444,6 +519,19 @@ do_mount(const char *args, const char *mtpoint) errx(1, "mount exited with error code %d", rv); } +/* + * Mount the configured tmpfs. + */ +static void +do_mount_tmpfs(const char *args, const char *mtpoint) +{ + int rv; + + rv = run(NULL, "%s -t tmpfs %s tmp %s", _PATH_MOUNT, args, mtpoint); + if (rv) + errx(1, "tmpfs mount exited with error code %d", rv); +} + /* * Various configuration of the mountpoint. Mostly, enact 'mip'. */ diff --git a/sbin/mknod/Makefile.depend b/sbin/mknod/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mknod/Makefile.depend +++ b/sbin/mknod/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mksnap_ffs/Makefile.depend b/sbin/mksnap_ffs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mksnap_ffs/Makefile.depend +++ b/sbin/mksnap_ffs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount/Makefile.depend b/sbin/mount/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/sbin/mount/Makefile.depend +++ b/sbin/mount/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount_cd9660/Makefile.depend b/sbin/mount_cd9660/Makefile.depend index 5a8df4c360b0..f2cf917f0e4c 100644 --- a/sbin/mount_cd9660/Makefile.depend +++ b/sbin/mount_cd9660/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/mount_fusefs/Makefile.depend b/sbin/mount_fusefs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mount_fusefs/Makefile.depend +++ b/sbin/mount_fusefs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount_msdosfs/Makefile.depend b/sbin/mount_msdosfs/Makefile.depend index af108671b361..cdb18932a6c2 100644 --- a/sbin/mount_msdosfs/Makefile.depend +++ b/sbin/mount_msdosfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount_nfs/Makefile.depend b/sbin/mount_nfs/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/sbin/mount_nfs/Makefile.depend +++ b/sbin/mount_nfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/sbin/mount_nullfs/Makefile.depend b/sbin/mount_nullfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mount_nullfs/Makefile.depend +++ b/sbin/mount_nullfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount_udf/Makefile.depend b/sbin/mount_udf/Makefile.depend index 51cf5395acf7..9258f1c2123f 100644 --- a/sbin/mount_udf/Makefile.depend +++ b/sbin/mount_udf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/mount_unionfs/Makefile.depend b/sbin/mount_unionfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/mount_unionfs/Makefile.depend +++ b/sbin/mount_unionfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/nandfs/Makefile.depend b/sbin/nandfs/Makefile.depend index b17f6d6fc6ed..1269878d50ef 100644 --- a/sbin/nandfs/Makefile.depend +++ b/sbin/nandfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/natd/Makefile.depend b/sbin/natd/Makefile.depend index 3418575389f8..ed80e66dfc4b 100644 --- a/sbin/natd/Makefile.depend +++ b/sbin/natd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/newfs/Makefile.depend b/sbin/newfs/Makefile.depend index 24f47f38796e..51f2384d1c84 100644 --- a/sbin/newfs/Makefile.depend +++ b/sbin/newfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index dbfab4536bd6..f68c42ec6b36 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -98,6 +98,7 @@ static void iput(union dinode *, ino_t); static int makedir(struct direct *, int); static void setblock(struct fs *, unsigned char *, int); static void wtfs(ufs2_daddr_t, int, char *); +static void cgckhash(struct cg *); static u_int32_t newfs_random(void); static int @@ -491,6 +492,11 @@ mkfs(struct partition *pp, char *fsys) sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree; sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree; } + /* + * Set flags for metadata that is being check-hashed. + */ + if (Oflag > 1) + sblock.fs_metackhash = CK_CYLGRP; /* * Dump out summary information about file system. @@ -791,6 +797,7 @@ initcg(int cylno, time_t utime) } } *cs = acg.cg_cs; + cgckhash(&acg); /* * Write out the duplicate super block, the cylinder group map * and two blocks worth of inodes in a single write. @@ -1006,6 +1013,7 @@ alloc(int size, int mode) setbit(cg_blksfree(&acg), d + i); } /* XXX cgwrite(&disk, 0)??? */ + cgckhash(&acg); wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, (char *)&acg); return ((ufs2_daddr_t)d); @@ -1027,6 +1035,7 @@ iput(union dinode *ip, ino_t ino) } acg.cg_cs.cs_nifree--; setbit(cg_inosused(&acg), ino); + cgckhash(&acg); wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, (char *)&acg); sblock.fs_cstotal.cs_nifree--; @@ -1059,6 +1068,20 @@ wtfs(ufs2_daddr_t bno, int size, char *bf) err(36, "wtfs: %d bytes at sector %jd", size, (intmax_t)bno); } +/* + * Calculate the check-hash of the cylinder group. + */ +static void +cgckhash(cgp) + struct cg *cgp; +{ + + if ((sblock.fs_metackhash & CK_CYLGRP) == 0) + return; + cgp->cg_ckhash = 0; + cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize); +} + /* * check if a block is available */ diff --git a/sbin/newfs_msdos/Makefile.depend b/sbin/newfs_msdos/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/newfs_msdos/Makefile.depend +++ b/sbin/newfs_msdos/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/newfs_nandfs/Makefile.depend b/sbin/newfs_nandfs/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/sbin/newfs_nandfs/Makefile.depend +++ b/sbin/newfs_nandfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/nfsiod/Makefile.depend b/sbin/nfsiod/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/sbin/nfsiod/Makefile.depend +++ b/sbin/nfsiod/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/sbin/nos-tun/Makefile.depend b/sbin/nos-tun/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/sbin/nos-tun/Makefile.depend +++ b/sbin/nos-tun/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/nvmecontrol/Makefile.depend b/sbin/nvmecontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/nvmecontrol/Makefile.depend +++ b/sbin/nvmecontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/nvmecontrol/logpage.c b/sbin/nvmecontrol/logpage.c index 993165f5e1e6..ccda7f06ce10 100644 --- a/sbin/nvmecontrol/logpage.c +++ b/sbin/nvmecontrol/logpage.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #define DEFAULT_SIZE (4096) #define MAX_FW_SLOTS (7) -typedef void (*print_fn_t)(void *buf, uint32_t size); +typedef void (*print_fn_t)(const struct nvme_controller_data *cdata, void *buf, uint32_t size); struct kv_name { @@ -75,8 +75,16 @@ kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key) } static void -print_bin(void *data, uint32_t length) +print_log_hex(const struct nvme_controller_data *cdata __unused, void *data, uint32_t length) { + + print_hex(data, length); +} + +static void +print_bin(const struct nvme_controller_data *cdata __unused, void *data, uint32_t length) +{ + write(STDOUT_FILENO, data, length); } @@ -115,7 +123,7 @@ read_logpage(int fd, uint8_t log_page, int nsid, void *payload, } static void -print_log_error(void *buf, uint32_t size) +print_log_error(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size) { int i, nentries; struct nvme_error_information_entry *entry = buf; @@ -162,7 +170,7 @@ print_temp(uint16_t t) static void -print_log_health(void *buf, uint32_t size __unused) +print_log_health(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { struct nvme_health_information_page *health = buf; char cbuf[UINT128_DIG + 1]; @@ -224,16 +232,21 @@ print_log_health(void *buf, uint32_t size __unused) } static void -print_log_firmware(void *buf, uint32_t size __unused) +print_log_firmware(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { - int i; + int i, slots; const char *status; struct nvme_firmware_page *fw = buf; printf("Firmware Slot Log\n"); printf("=================\n"); - for (i = 0; i < MAX_FW_SLOTS; i++) { + if (cdata->oacs.firmware == 0) + slots = 1; + else + slots = MIN(cdata->frmw.num_slots, MAX_FW_SLOTS); + + for (i = 0; i < slots; i++) { printf("Slot %d: ", i + 1); if (fw->afi.slot == i + 1) status = " Active"; @@ -260,7 +273,7 @@ print_log_firmware(void *buf, uint32_t size __unused) * offset 147: it is only 1 byte, not 6. */ static void -print_intel_temp_stats(void *buf, uint32_t size __unused) +print_intel_temp_stats(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { struct intel_log_temp_stats *temp = buf; @@ -287,7 +300,7 @@ print_intel_temp_stats(void *buf, uint32_t size __unused) * Read and write stats pages have identical encoding. */ static void -print_intel_read_write_lat_log(void *buf, uint32_t size __unused) +print_intel_read_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { const char *walker = buf; int i; @@ -303,28 +316,28 @@ print_intel_read_write_lat_log(void *buf, uint32_t size __unused) } static void -print_intel_read_lat_log(void *buf, uint32_t size) +print_intel_read_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size) { printf("Intel Read Latency Log\n"); printf("======================\n"); - print_intel_read_write_lat_log(buf, size); + print_intel_read_write_lat_log(cdata, buf, size); } static void -print_intel_write_lat_log(void *buf, uint32_t size) +print_intel_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size) { printf("Intel Write Latency Log\n"); printf("=======================\n"); - print_intel_read_write_lat_log(buf, size); + print_intel_read_write_lat_log(cdata, buf, size); } /* * Table 19. 5.4 SMART Attributes. Samsung also implements this and some extra data not documented. */ static void -print_intel_add_smart(void *buf, uint32_t size __unused) +print_intel_add_smart(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { uint8_t *walker = buf; uint8_t *end = walker + 150; @@ -753,7 +766,7 @@ kv_indirect(void *buf, uint32_t subtype, uint8_t res, uint32_t size, struct subp } static void -print_hgst_info_log(void *buf, uint32_t size __unused) +print_hgst_info_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) { uint8_t *walker, *end, *subpage; int pages; @@ -928,7 +941,7 @@ logpage(int argc, char *argv[]) "smart/health information"); } - print_fn = print_hex; + print_fn = print_log_hex; size = DEFAULT_SIZE; if (binflag) print_fn = print_bin; @@ -960,7 +973,7 @@ logpage(int argc, char *argv[]) /* Read the log page */ buf = get_log_buffer(size); read_logpage(fd, log_page, nsid, buf, size); - print_fn(buf, size); + print_fn(&cdata, buf, size); close(fd); exit(0); diff --git a/sbin/pfctl/Makefile.depend b/sbin/pfctl/Makefile.depend index 6a75a18b83df..dc2c63d06b09 100644 --- a/sbin/pfctl/Makefile.depend +++ b/sbin/pfctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/pfctl/tests/Makefile.depend b/sbin/pfctl/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/sbin/pfctl/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/sbin/pfctl/tests/files/Makefile.depend b/sbin/pfctl/tests/files/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/sbin/pfctl/tests/files/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/sbin/pflogd/Makefile.depend b/sbin/pflogd/Makefile.depend index 268320b6f6e3..893e74eb908c 100644 --- a/sbin/pflogd/Makefile.depend +++ b/sbin/pflogd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile index 21a4dccc01d9..12f00ffe5d1f 100644 --- a/sbin/ping/Makefile +++ b/sbin/ping/Makefile @@ -14,7 +14,7 @@ LIBADD= m .if ${MK_CASPER} != "no" && !defined(RESCUE) LIBADD+= casper LIBADD+= cap_dns -CFLAGS+=-DHAVE_LIBCASPER +CFLAGS+=-DWITH_CASPER .endif .if !defined(RELEASE_CRUNCH) diff --git a/sbin/ping/Makefile.depend b/sbin/ping/Makefile.depend index 575acedacc0e..7632b092168b 100644 --- a/sbin/ping/Makefile.depend +++ b/sbin/ping/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c index 87817a67862b..0453ee0af3c6 100644 --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -76,10 +76,8 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef HAVE_LIBCASPER #include #include -#endif #ifdef IPSEC #include @@ -204,15 +202,11 @@ static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ static volatile sig_atomic_t finish_up; static volatile sig_atomic_t siginfo_p; -#ifdef HAVE_LIBCASPER static cap_channel_t *capdns; -#endif static void fill(char *, char *); static u_short in_cksum(u_short *, int); -#ifdef HAVE_LIBCASPER static cap_channel_t *capdns_setup(void); -#endif static void check_status(void); static void finish(void) __dead2; static void pinger(void); @@ -563,21 +557,17 @@ main(int argc, char *const *argv) if (options & F_PINGFILLED) { fill((char *)datap, payload); } -#ifdef HAVE_LIBCASPER capdns = capdns_setup(); -#endif if (source) { bzero((char *)&sock_in, sizeof(sock_in)); sock_in.sin_family = AF_INET; if (inet_aton(source, &sock_in.sin_addr) != 0) { shostname = source; } else { -#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyname2(capdns, source, AF_INET); else -#endif hp = gethostbyname2(source, AF_INET); if (!hp) errx(EX_NOHOST, "cannot resolve %s: %s", @@ -606,11 +596,9 @@ main(int argc, char *const *argv) if (inet_aton(target, &to->sin_addr) != 0) { hostname = target; } else { -#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyname2(capdns, target, AF_INET); else -#endif hp = gethostbyname2(target, AF_INET); if (!hp) errx(EX_NOHOST, "cannot resolve %s: %s", @@ -624,7 +612,6 @@ main(int argc, char *const *argv) hostname = hnamebuf; } -#ifdef HAVE_LIBCASPER /* From now on we will use only reverse DNS lookups. */ if (capdns != NULL) { const char *types[1]; @@ -633,7 +620,6 @@ main(int argc, char *const *argv) if (cap_dns_type_limit(capdns, types, 1) < 0) err(1, "unable to limit access to system.dns service"); } -#endif if (connect(ssend, (struct sockaddr *)&whereto, sizeof(whereto)) != 0) err(1, "connect"); @@ -722,10 +708,8 @@ main(int argc, char *const *argv) if (options & F_NUMERIC) cansandbox = true; -#ifdef HAVE_LIBCASPER else if (capdns != NULL) cansandbox = true; -#endif else cansandbox = false; @@ -1707,11 +1691,9 @@ pr_addr(struct in_addr ina) if (options & F_NUMERIC) return inet_ntoa(ina); -#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyaddr(capdns, (char *)&ina, 4, AF_INET); else -#endif hp = gethostbyaddr((char *)&ina, 4, AF_INET); if (hp == NULL) @@ -1791,7 +1773,6 @@ fill(char *bp, char *patp) } } -#ifdef HAVE_LIBCASPER static cap_channel_t * capdns_setup(void) { @@ -1817,7 +1798,6 @@ capdns_setup(void) return (capdnsloc); } -#endif /* HAVE_LIBCASPER */ #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) #define SECOPT " [-P policy]" diff --git a/sbin/ping6/Makefile.depend b/sbin/ping6/Makefile.depend index c87ecaf67d8b..653f949402e0 100644 --- a/sbin/ping6/Makefile.depend +++ b/sbin/ping6/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/quotacheck/Makefile.depend b/sbin/quotacheck/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/sbin/quotacheck/Makefile.depend +++ b/sbin/quotacheck/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/rcorder/Makefile.depend b/sbin/rcorder/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/sbin/rcorder/Makefile.depend +++ b/sbin/rcorder/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/reboot/Makefile.depend b/sbin/reboot/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/reboot/Makefile.depend +++ b/sbin/reboot/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8 index c31f9663a88f..6f2d023e8bb9 100644 --- a/sbin/reboot/reboot.8 +++ b/sbin/reboot/reboot.8 @@ -28,7 +28,7 @@ .\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd March 19, 2017 +.Dd October 23, 2017 .Dt REBOOT 8 .Os .Sh NAME @@ -42,7 +42,7 @@ .Op Fl lNnpq .Op Fl k Ar kernel .Nm -.Op Fl dlNnpqr +.Op Fl cdlNnpqr .Op Fl k Ar kernel .Nm fasthalt .Op Fl lNnpq @@ -66,6 +66,20 @@ accounting database. .Pp The options are as follows: .Bl -tag -width indent +.It Fl c +The system will turn off the power and then turn it back on if it can. +If the power down action fails, the system +will halt or reboot normally, depending on whether +.Nm halt +or +.Nm +was called. +At the present time, only the +.Xr ipmi 4 +driver implements the power cycle functionality and only on hardware +with a BMC that supports power cycling. +Unlike power off, the amount of hardware that supports power cycling +is small. .It Fl d The system is requested to create a crash dump. This option is @@ -162,6 +176,7 @@ reboot -r .Sh SEE ALSO .Xr kenv 1 , .Xr getutxent 3 , +.Xr ipmi 4 , .Xr boot 8 , .Xr dumpon 8 , .Xr nextboot 8 , diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c index 8722e27511f5..01c7d38da5a9 100644 --- a/sbin/reboot/reboot.c +++ b/sbin/reboot/reboot.c @@ -77,8 +77,11 @@ main(int argc, char *argv[]) } else howto = 0; lflag = nflag = qflag = Nflag = 0; - while ((ch = getopt(argc, argv, "dk:lNnpqr")) != -1) + while ((ch = getopt(argc, argv, "cdk:lNnpqr")) != -1) switch(ch) { + case 'c': + howto |= RB_POWERCYCLE; + break; case 'd': howto |= RB_DUMP; break; @@ -116,8 +119,10 @@ main(int argc, char *argv[]) errx(1, "cannot dump (-d) when halting; must reboot instead"); if (Nflag && (howto & RB_NOSYNC) != 0) errx(1, "-N cannot be used with -n"); + if ((howto & RB_POWEROFF) && (howto & RB_POWERCYCLE)) + errx(1, "-c and -p cannot be used together"); if ((howto & RB_REROOT) != 0 && howto != RB_REROOT) - errx(1, "-r cannot be used with -d, -n, or -p"); + errx(1, "-r cannot be used with -c, -d, -n, or -p"); if (geteuid()) { errno = EPERM; err(1, NULL); @@ -151,6 +156,12 @@ main(int argc, char *argv[]) } else if (howto & RB_REROOT) { openlog("reroot", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "rerooted by %s", user); + } else if (howto & RB_POWEROFF) { + openlog("reboot", 0, LOG_AUTH | LOG_CONS); + syslog(LOG_CRIT, "powered off by %s", user); + } else if (howto & RB_POWERCYCLE) { + openlog("reboot", 0, LOG_AUTH | LOG_CONS); + syslog(LOG_CRIT, "power cycled by %s", user); } else { openlog("reboot", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "rebooted by %s", user); @@ -248,8 +259,8 @@ usage(void) { (void)fprintf(stderr, dohalt ? - "usage: halt [-lNnpq] [-k kernel]\n" : - "usage: reboot [-dlNnpqr] [-k kernel]\n"); + "usage: halt [-clNnpq] [-k kernel]\n" : + "usage: reboot [-cdlNnpqr] [-k kernel]\n"); exit(1); } diff --git a/sbin/recoverdisk/Makefile.depend b/sbin/recoverdisk/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/recoverdisk/Makefile.depend +++ b/sbin/recoverdisk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/restore/Makefile.depend b/sbin/restore/Makefile.depend index 26cae4ede976..4bd09984c29d 100644 --- a/sbin/restore/Makefile.depend +++ b/sbin/restore/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/protocols \ include/xlocale \ diff --git a/sbin/route/Makefile.depend b/sbin/route/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/sbin/route/Makefile.depend +++ b/sbin/route/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/routed/Makefile.depend b/sbin/routed/Makefile.depend index 1dd269719589..c369ae60fd72 100644 --- a/sbin/routed/Makefile.depend +++ b/sbin/routed/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/sbin/routed/rtquery/Makefile.depend b/sbin/routed/rtquery/Makefile.depend index 1dd269719589..c369ae60fd72 100644 --- a/sbin/routed/rtquery/Makefile.depend +++ b/sbin/routed/rtquery/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/sbin/rtsol/Makefile.depend b/sbin/rtsol/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/sbin/rtsol/Makefile.depend +++ b/sbin/rtsol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/savecore/Makefile.depend b/sbin/savecore/Makefile.depend index 2d56689cfaed..276faebbb279 100644 --- a/sbin/savecore/Makefile.depend +++ b/sbin/savecore/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/savecore/savecore.8 b/sbin/savecore/savecore.8 index 45e2af9588b3..ae2265070b85 100644 --- a/sbin/savecore/savecore.8 +++ b/sbin/savecore/savecore.8 @@ -28,7 +28,7 @@ .\" From: @(#)savecore.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd December 10, 2016 +.Dd October 24, 2017 .Dt SAVECORE 8 .Os .Sh NAME @@ -96,8 +96,12 @@ the counter will restart from Print out some additional debugging information. Specify twice for more information. .It Fl z -Compress the core dump and kernel (see +Compress the dump (see .Xr gzip 1 ) . +The dump may already be compressed if the kernel was configured to +do so by +.Xr dumpon 8 . +In this case, the option has no effect. .El .Pp The diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index 80817655aa34..d037ae2912f1 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -121,6 +121,9 @@ printheader(xo_handle_t *xo, const struct kerneldumpheader *h, (long long)dumplen); xo_emit_h(xo, "{P: }{Lwc:Blocksize}{:blocksize/%d}\n", dtoh32(h->blocksize)); + xo_emit_h(xo, "{P: }{Lwc:Compression}{:compression/%s}\n", + h->compression == KERNELDUMP_COMP_GZIP ? + "gzip" : "none"); t = dtoh64(h->dumptime); xo_emit_h(xo, "{P: }{Lwc:Dumptime}{:dumptime/%s}", ctime(&t)); @@ -357,7 +360,7 @@ compare_magic(const struct kerneldumpheader *kdh, const char *magic) #define BLOCKMASK (~(BLOCKSIZE-1)) static int -DoRegularFile(int fd, bool isencrypted, off_t dumpsize, char *buf, +DoRegularFile(int fd, off_t dumpsize, u_int sectorsize, bool sparse, char *buf, const char *device, const char *filename, FILE *fp) { int he, hs, nr, nw, wl; @@ -370,8 +373,8 @@ DoRegularFile(int fd, bool isencrypted, off_t dumpsize, char *buf, wl = BUFFERSIZE; if (wl > dumpsize) wl = dumpsize; - nr = read(fd, buf, wl); - if (nr != wl) { + nr = read(fd, buf, roundup(wl, sectorsize)); + if (nr != (int)roundup(wl, sectorsize)) { if (nr == 0) syslog(LOG_WARNING, "WARNING: EOF on dump device"); @@ -380,7 +383,7 @@ DoRegularFile(int fd, bool isencrypted, off_t dumpsize, char *buf, nerr++; return (-1); } - if (compress || isencrypted) { + if (!sparse) { nw = fwrite(buf, 1, wl, fp); } else { for (nw = 0; nw < nr; nw = he) { @@ -506,15 +509,14 @@ DoFile(const char *savedir, const char *device) char *temp = NULL; struct kerneldumpheader kdhf, kdhl; uint8_t *dumpkey; - off_t mediasize, dumpsize, firsthd, lasthd; + off_t mediasize, dumpextent, dumplength, firsthd, lasthd; FILE *info, *fp; mode_t oumask; int fd, fdinfo, error; int bounds, status; u_int sectorsize, xostyle; - int istextdump; uint32_t dumpkeysize; - bool isencrypted, ret; + bool iscompressed, isencrypted, istextdump, ret; bounds = getbounds(); dumpkey = NULL; @@ -582,12 +584,12 @@ DoFile(const char *savedir, const char *device) goto closefd; } memcpy(&kdhl, temp, sizeof(kdhl)); - istextdump = 0; + iscompressed = istextdump = false; if (compare_magic(&kdhl, TEXTDUMPMAGIC)) { if (verbose) printf("textdump magic on last dump header on %s\n", device); - istextdump = 1; + istextdump = true; if (dtoh32(kdhl.version) != KERNELDUMP_TEXT_VERSION) { syslog(LOG_ERR, "unknown version (%d) in last dump header on %s", @@ -607,6 +609,20 @@ DoFile(const char *savedir, const char *device) if (force == 0) goto closefd; } + switch (kdhl.compression) { + case KERNELDUMP_COMP_NONE: + break; + case KERNELDUMP_COMP_GZIP: + if (compress && verbose) + printf("dump is already compressed\n"); + compress = false; + iscompressed = true; + break; + default: + syslog(LOG_ERR, "unknown compression type %d on %s", + kdhl.compression, device); + break; + } } else { if (verbose) printf("magic mismatch on last dump header on %s\n", @@ -619,8 +635,7 @@ DoFile(const char *savedir, const char *device) if (compare_magic(&kdhl, KERNELDUMPMAGIC_CLEARED)) { if (verbose) printf("forcing magic on %s\n", device); - memcpy(kdhl.magic, KERNELDUMPMAGIC, - sizeof kdhl.magic); + memcpy(kdhl.magic, KERNELDUMPMAGIC, sizeof(kdhl.magic)); } else { syslog(LOG_ERR, "unable to force dump - bad magic"); goto closefd; @@ -648,9 +663,10 @@ DoFile(const char *savedir, const char *device) if (force == 0) goto closefd; } - dumpsize = dtoh64(kdhl.dumplength); + dumpextent = dtoh64(kdhl.dumpextent); + dumplength = dtoh64(kdhl.dumplength); dumpkeysize = dtoh32(kdhl.dumpkeysize); - firsthd = lasthd - dumpsize - sectorsize - dumpkeysize; + firsthd = lasthd - dumpextent - sectorsize - dumpkeysize; if (lseek(fd, firsthd, SEEK_SET) != firsthd || read(fd, temp, sectorsize) != (ssize_t)sectorsize) { syslog(LOG_ERR, @@ -696,7 +712,7 @@ DoFile(const char *savedir, const char *device) if (verbose) printf("Checking for available free space\n"); - if (!check_space(savedir, dumpsize, bounds)) { + if (!check_space(savedir, dumplength, bounds)) { nerr++; goto closefd; } @@ -724,6 +740,9 @@ DoFile(const char *savedir, const char *device) istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore"), bounds); fp = zopen(corename, "w"); + } else if (iscompressed && !isencrypted) { + snprintf(corename, sizeof(corename), "vmcore.%d.gz", bounds); + fp = fopen(corename, "w"); } else { snprintf(corename, sizeof(corename), "%s.%d", istextdump ? "textdump.tar" : @@ -792,11 +811,12 @@ DoFile(const char *savedir, const char *device) savedir, corename); if (istextdump) { - if (DoTextdumpFile(fd, dumpsize, lasthd, buf, device, + if (DoTextdumpFile(fd, dumplength, lasthd, buf, device, corename, fp) < 0) goto closeall; } else { - if (DoRegularFile(fd, isencrypted, dumpsize, buf, device, + if (DoRegularFile(fd, dumplength, sectorsize, + !(compress || iscompressed || isencrypted), buf, device, corename, fp) < 0) { goto closeall; } @@ -822,7 +842,7 @@ DoFile(const char *savedir, const char *device) "key.last"); } } - if (compress) { + if (compress || iscompressed) { snprintf(linkname, sizeof(linkname), "%s.last.gz", istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore")); diff --git a/sbin/sconfig/Makefile.depend b/sbin/sconfig/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/sbin/sconfig/Makefile.depend +++ b/sbin/sconfig/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/setkey/Makefile.depend b/sbin/setkey/Makefile.depend index 88d8cebda9cf..ca3301c271b9 100644 --- a/sbin/setkey/Makefile.depend +++ b/sbin/setkey/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/sbin/shutdown/Makefile.depend b/sbin/shutdown/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/shutdown/Makefile.depend +++ b/sbin/shutdown/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/shutdown/shutdown.8 b/sbin/shutdown/shutdown.8 index 1b7c6e19bdf6..b388aaf92fe9 100644 --- a/sbin/shutdown/shutdown.8 +++ b/sbin/shutdown/shutdown.8 @@ -28,7 +28,7 @@ .\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95 .\" $FreeBSD$ .\" -.Dd September 21, 2016 +.Dd October 23, 2017 .Dt SHUTDOWN 8 .Os .Sh NAME @@ -39,7 +39,7 @@ .Nm .Op Fl .Oo -.Fl h | Fl p | +.Fl c | Fl h | Fl p | .Fl r | Fl k .Oc .Oo @@ -59,12 +59,22 @@ would otherwise not bother with such niceties. .Pp The following options are available: .Bl -tag -width indent +.It Fl c +The system is power cycled (power turned off and then back on) +at the specified time. +If the hardware doesn't support power cycle, the system will be +halted. +At the present time, only systems with BMC supported by the +.Xr ipmi 4 +driver that implement this functionality support this flag. +The amount of time the system is off is dependent on the device +that implements this feature. .It Fl h The system is halted at the specified .Ar time . .It Fl p The system is halted and the power is turned off -(hardware support required) +(hardware support required, otherwise the system is halted) at the specified .Ar time . .It Fl r @@ -79,6 +89,7 @@ does not actually halt the system, but leaves the system multi-user with logins disabled (for all but super-user). .It Fl o If one of the +.Fl c , .Fl h , .Fl p or diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c index 6c24e4b2a580..f1f780e5d1e8 100644 --- a/sbin/shutdown/shutdown.c +++ b/sbin/shutdown/shutdown.c @@ -89,7 +89,7 @@ static struct interval { #undef S static time_t offset, shuttime; -static int dohalt, dopower, doreboot, killflg, mbuflen, oflag; +static int docycle, dohalt, dopower, doreboot, killflg, mbuflen, oflag; static char mbuf[BUFSIZ]; static const char *nosync, *whom; @@ -141,11 +141,14 @@ main(int argc, char **argv) goto poweroff; } - while ((ch = getopt(argc, argv, "-hknopr")) != -1) + while ((ch = getopt(argc, argv, "-chknopr")) != -1) switch (ch) { case '-': readstdin = 1; break; + case 'c': + docycle = 1; + break; case 'h': dohalt = 1; break; @@ -174,11 +177,11 @@ main(int argc, char **argv) if (argc < 1) usage((char *)NULL); - if (killflg + doreboot + dohalt + dopower > 1) - usage("incompatible switches -h, -k, -p and -r"); + if (killflg + doreboot + dohalt + dopower + docycle > 1) + usage("incompatible switches -c, -h, -k, -p and -r"); - if (oflag && !(dohalt || dopower || doreboot)) - usage("-o requires -h, -p or -r"); + if (oflag && !(dohalt || dopower || doreboot || docycle)) + usage("-o requires -c, -h, -p or -r"); if (nosync != NULL && !oflag) usage("-n requires -o"); @@ -356,8 +359,8 @@ die_you_gravy_sucking_pig_dog(void) char *empty_environ[] = { NULL }; syslog(LOG_NOTICE, "%s by %s: %s", - doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" : - "shutdown", whom, mbuf); + doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" : + docycle ? "power-cycle" : "shutdown", whom, mbuf); (void)printf("\r\nSystem shutdown time has arrived\007\007\r\n"); if (killflg) { @@ -367,6 +370,8 @@ die_you_gravy_sucking_pig_dog(void) #ifdef DEBUG if (doreboot) (void)printf("reboot"); + else if (docycle) + (void)printf("power-cycle"); else if (dohalt) (void)printf("halt"); else if (dopower) @@ -379,6 +384,7 @@ die_you_gravy_sucking_pig_dog(void) (void)kill(1, doreboot ? SIGINT : /* reboot */ dohalt ? SIGUSR1 : /* halt */ dopower ? SIGUSR2 : /* power-down */ + docycle ? SIGWINCH : /* power-cycle */ SIGTERM); /* single-user */ } else { if (doreboot) { @@ -402,6 +408,13 @@ die_you_gravy_sucking_pig_dog(void) _PATH_HALT); warn(_PATH_HALT); } + else if (docycle) { + execle(_PATH_HALT, "halt", "-l", "-c", nosync, + (char *)NULL, empty_environ); + syslog(LOG_ERR, "shutdown: can't exec %s: %m.", + _PATH_HALT); + warn(_PATH_HALT); + } (void)kill(1, SIGTERM); /* to single-user */ } #endif @@ -553,7 +566,7 @@ usage(const char *cp) if (cp != NULL) warnx("%s", cp); (void)fprintf(stderr, - "usage: shutdown [-] [-h | -p | -r | -k] [-o [-n]] time [warning-message ...]\n" + "usage: shutdown [-] [-c | -h | -p | -r | -k] [-o [-n]] time [warning-message ...]\n" " poweroff\n"); exit(1); } diff --git a/sbin/spppcontrol/Makefile.depend b/sbin/spppcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/spppcontrol/Makefile.depend +++ b/sbin/spppcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/sunlabel/Makefile.depend b/sbin/sunlabel/Makefile.depend index 2df49d098af1..a05551ae5136 100644 --- a/sbin/sunlabel/Makefile.depend +++ b/sbin/sunlabel/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/swapon/Makefile.depend b/sbin/swapon/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/sbin/swapon/Makefile.depend +++ b/sbin/swapon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/sysctl/Makefile.depend b/sbin/sysctl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sbin/sysctl/Makefile.depend +++ b/sbin/sysctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index c029e71b9a8d..efebfebf054b 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -214,7 +214,7 @@ String and integer values can be set using .It "kern.filedelay integer yes" .It "kern.dirdelay integer yes" .It "kern.metadelay integer yes" -.It "kern.osreldate string no" +.It "kern.osreldate integer no" .It "kern.bootfile string yes" .It "kern.corefile string yes" .It "kern.logsigexit integer yes" diff --git a/sbin/tunefs/Makefile.depend b/sbin/tunefs/Makefile.depend index 99cf113eba55..735bf03b75b6 100644 --- a/sbin/tunefs/Makefile.depend +++ b/sbin/tunefs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sbin/umount/Makefile.depend b/sbin/umount/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/sbin/umount/Makefile.depend +++ b/sbin/umount/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/sbin/zfsbootcfg/Makefile.depend b/sbin/zfsbootcfg/Makefile.depend index b1a2eff6cb4f..53090da6e2fc 100644 --- a/sbin/zfsbootcfg/Makefile.depend +++ b/sbin/zfsbootcfg/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ cddl/lib/libzfs \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/Makefile.depend b/secure/lib/libcrypto/Makefile.depend index 9f2467a2d441..a516cff0b547 100644 --- a/secure/lib/libcrypto/Makefile.depend +++ b/secure/lib/libcrypto/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc index 8330b942439b..323e6f5cf742 100644 --- a/secure/lib/libcrypto/Makefile.inc +++ b/secure/lib/libcrypto/Makefile.inc @@ -3,8 +3,8 @@ .include # OpenSSL version used for manual page generation -OPENSSL_VER= 1.0.2l -OPENSSL_DATE= 2017-05-25 +OPENSSL_VER= 1.0.2m +OPENSSL_DATE= 2017-11-02 LCRYPTO_SRC= ${SRCTOP}/crypto/openssl LCRYPTO_DOC= ${LCRYPTO_SRC}/doc diff --git a/secure/lib/libcrypto/Makefile.man b/secure/lib/libcrypto/Makefile.man index be7eaacc0bd3..4ad0b080b410 100644 --- a/secure/lib/libcrypto/Makefile.man +++ b/secure/lib/libcrypto/Makefile.man @@ -112,6 +112,7 @@ MAN+= EVP_PKEY_derive.3 MAN+= EVP_PKEY_encrypt.3 MAN+= EVP_PKEY_get_default_digest.3 MAN+= EVP_PKEY_keygen.3 +MAN+= EVP_PKEY_meth_new.3 MAN+= EVP_PKEY_new.3 MAN+= EVP_PKEY_print_private.3 MAN+= EVP_PKEY_set1_RSA.3 @@ -172,6 +173,7 @@ MAN+= X509_STORE_CTX_set_verify_cb.3 MAN+= X509_STORE_set_verify_cb_func.3 MAN+= X509_VERIFY_PARAM_set_flags.3 MAN+= X509_check_host.3 +MAN+= X509_check_private_key.3 MAN+= X509_new.3 MAN+= X509_verify_cert.3 MAN+= bio.3 @@ -763,6 +765,39 @@ MLINKS+= EVP_PKEY_keygen.3 EVP_PKEY_CTX_set_cb.3 MLINKS+= EVP_PKEY_keygen.3 EVP_PKEY_keygen_init.3 MLINKS+= EVP_PKEY_keygen.3 EVP_PKEY_paramgen.3 MLINKS+= EVP_PKEY_keygen.3 EVP_PKEY_paramgen_init.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_METHOD.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_add0.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_copy.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_find.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_free.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_cleanup.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_copy.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_ctrl.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_decrypt.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_derive.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_encrypt.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_init.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_keygen.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_paramgen.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_sign.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_signctx.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_verify.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_verify_recover.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_get_verifyctx.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_cleanup.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_copy.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_ctrl.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_decrypt.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_derive.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_encrypt.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_init.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_keygen.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_paramgen.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_sign.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_signctx.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_verify.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_verify_recover.3 +MLINKS+= EVP_PKEY_meth_new.3 EVP_PKEY_meth_set_verifyctx.3 MLINKS+= EVP_PKEY_new.3 EVP_PKEY_free.3 MLINKS+= EVP_PKEY_print_private.3 EVP_PKEY_print_params.3 MLINKS+= EVP_PKEY_print_private.3 EVP_PKEY_print_public.3 @@ -909,6 +944,7 @@ MLINKS+= X509_VERIFY_PARAM_set_flags.3 X509_VERIFY_PARAM_set_trust.3 MLINKS+= X509_check_host.3 X509_check_email.3 MLINKS+= X509_check_host.3 X509_check_ip.3 MLINKS+= X509_check_host.3 X509_check_ip_asc.3 +MLINKS+= X509_check_private_key.3 X509_REQ_check_private_key.3 MLINKS+= X509_new.3 X509_free.3 MLINKS+= blowfish.3 BF_cbc_encrypt.3 MLINKS+= blowfish.3 BF_cfb64_encrypt.3 diff --git a/secure/lib/libcrypto/amd64/ecp_nistz256-x86_64.S b/secure/lib/libcrypto/amd64/ecp_nistz256-x86_64.S index 7cd1db07d002..4ac9e2186380 100644 --- a/secure/lib/libcrypto/amd64/ecp_nistz256-x86_64.S +++ b/secure/lib/libcrypto/amd64/ecp_nistz256-x86_64.S @@ -1038,19 +1038,18 @@ __ecp_nistz256_sqr_montx: adoxq %rbp,%r13 .byte 0x67,0x67 mulxq %rdx,%rcx,%rax - movq %r8,%rdx + movq .Lpoly+24(%rip),%rdx adoxq %rcx,%r14 shlxq %rsi,%r8,%rcx adoxq %rax,%r15 shrxq %rsi,%r8,%rax - movq .Lpoly+24(%rip),%rbp + movq %rdx,%rbp addq %rcx,%r9 adcq %rax,%r10 - mulxq %rbp,%rcx,%r8 - movq %r9,%rdx + mulxq %r8,%rcx,%r8 adcq %rcx,%r11 shlxq %rsi,%r9,%rcx adcq $0,%r8 @@ -1060,8 +1059,7 @@ __ecp_nistz256_sqr_montx: addq %rcx,%r10 adcq %rax,%r11 - mulxq %rbp,%rcx,%r9 - movq %r10,%rdx + mulxq %r9,%rcx,%r9 adcq %rcx,%r8 shlxq %rsi,%r10,%rcx adcq $0,%r9 @@ -1071,8 +1069,7 @@ __ecp_nistz256_sqr_montx: addq %rcx,%r11 adcq %rax,%r8 - mulxq %rbp,%rcx,%r10 - movq %r11,%rdx + mulxq %r10,%rcx,%r10 adcq %rcx,%r9 shlxq %rsi,%r11,%rcx adcq $0,%r10 @@ -1082,12 +1079,12 @@ __ecp_nistz256_sqr_montx: addq %rcx,%r8 adcq %rax,%r9 - mulxq %rbp,%rcx,%r11 + mulxq %r11,%rcx,%r11 adcq %rcx,%r10 adcq $0,%r11 xorq %rdx,%rdx - adcq %r8,%r12 + addq %r8,%r12 movq .Lpoly+8(%rip),%rsi adcq %r9,%r13 movq %r12,%r8 @@ -1096,8 +1093,7 @@ __ecp_nistz256_sqr_montx: movq %r13,%r9 adcq $0,%rdx - xorl %eax,%eax - sbbq $-1,%r12 + subq $-1,%r12 movq %r14,%r10 sbbq %rsi,%r13 sbbq $0,%r14 diff --git a/secure/lib/libcrypto/amd64/x86_64-mont5.S b/secure/lib/libcrypto/amd64/x86_64-mont5.S index 3d1b0ce4706e..f4a12d7d8a98 100644 --- a/secure/lib/libcrypto/amd64/x86_64-mont5.S +++ b/secure/lib/libcrypto/amd64/x86_64-mont5.S @@ -3077,11 +3077,19 @@ __bn_sqrx8x_internal: .align 32 .Lsqrx8x_break: - subq 16+8(%rsp),%r8 + xorq %rbp,%rbp + subq 16+8(%rsp),%rbx + adcxq %rbp,%r8 movq 24+8(%rsp),%rcx + adcxq %rbp,%r9 movq 0(%rsi),%rdx - xorl %ebp,%ebp + adcq $0,%r10 movq %r8,0(%rdi) + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 cmpq %rcx,%rdi je .Lsqrx8x_outer_loop diff --git a/secure/lib/libcrypto/amd64/x86_64cpuid.S b/secure/lib/libcrypto/amd64/x86_64cpuid.S index d66eeaa50fdf..820960ab6644 100644 --- a/secure/lib/libcrypto/amd64/x86_64cpuid.S +++ b/secure/lib/libcrypto/amd64/x86_64cpuid.S @@ -118,8 +118,19 @@ OPENSSL_ia32_cpuid: orl $0x40000000,%edx andb $15,%ah cmpb $15,%ah - jne .Lnotintel + jne .LnotP4 orl $0x00100000,%edx +.LnotP4: + cmpb $6,%ah + jne .Lnotintel + andl $0x0fff0ff0,%eax + cmpl $0x00050670,%eax + je .Lknights + cmpl $0x00080650,%eax + jne .Lnotintel +.Lknights: + andl $0xfbffffff,%ecx + .Lnotintel: btl $28,%edx jnc .Lgeneric @@ -144,6 +155,10 @@ OPENSSL_ia32_cpuid: movl $7,%eax xorl %ecx,%ecx cpuid + btl $26,%r9d + jc .Lnotknights + andl $0xfff7ffff,%ebx +.Lnotknights: movl %ebx,8(%rdi) .Lno_extended_info: diff --git a/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend b/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend +++ b/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libaep/Makefile.depend b/secure/lib/libcrypto/engines/libaep/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libaep/Makefile.depend +++ b/secure/lib/libcrypto/engines/libaep/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libatalla/Makefile.depend b/secure/lib/libcrypto/engines/libatalla/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libatalla/Makefile.depend +++ b/secure/lib/libcrypto/engines/libatalla/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libcapi/Makefile.depend b/secure/lib/libcrypto/engines/libcapi/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libcapi/Makefile.depend +++ b/secure/lib/libcrypto/engines/libcapi/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libchil/Makefile.depend b/secure/lib/libcrypto/engines/libchil/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libchil/Makefile.depend +++ b/secure/lib/libcrypto/engines/libchil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libcswift/Makefile.depend b/secure/lib/libcrypto/engines/libcswift/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libcswift/Makefile.depend +++ b/secure/lib/libcrypto/engines/libcswift/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libgost/Makefile.depend b/secure/lib/libcrypto/engines/libgost/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libgost/Makefile.depend +++ b/secure/lib/libcrypto/engines/libgost/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libnuron/Makefile.depend b/secure/lib/libcrypto/engines/libnuron/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libnuron/Makefile.depend +++ b/secure/lib/libcrypto/engines/libnuron/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libsureware/Makefile.depend b/secure/lib/libcrypto/engines/libsureware/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libsureware/Makefile.depend +++ b/secure/lib/libcrypto/engines/libsureware/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/engines/libubsec/Makefile.depend b/secure/lib/libcrypto/engines/libubsec/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/secure/lib/libcrypto/engines/libubsec/Makefile.depend +++ b/secure/lib/libcrypto/engines/libubsec/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 index 6ac9e966eb39..9df328b9790d 100644 --- a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 +++ b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_OBJECT_new 3" -.TH ASN1_OBJECT_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_OBJECT_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ASN1_STRING_length.3 b/secure/lib/libcrypto/man/ASN1_STRING_length.3 index 660ba7abb1dd..8dfcd8d25a43 100644 --- a/secure/lib/libcrypto/man/ASN1_STRING_length.3 +++ b/secure/lib/libcrypto/man/ASN1_STRING_length.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_STRING_length 3" -.TH ASN1_STRING_length 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_STRING_length 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ASN1_STRING_new.3 b/secure/lib/libcrypto/man/ASN1_STRING_new.3 index 7373e0312ffa..3f657f59db03 100644 --- a/secure/lib/libcrypto/man/ASN1_STRING_new.3 +++ b/secure/lib/libcrypto/man/ASN1_STRING_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_STRING_new 3" -.TH ASN1_STRING_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_STRING_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 index e6e65a9461ec..6662a4d45973 100644 --- a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 +++ b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_STRING_print_ex 3" -.TH ASN1_STRING_print_ex 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_STRING_print_ex 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ASN1_TIME_set.3 b/secure/lib/libcrypto/man/ASN1_TIME_set.3 index 26422c1f9611..9dd6a7410149 100644 --- a/secure/lib/libcrypto/man/ASN1_TIME_set.3 +++ b/secure/lib/libcrypto/man/ASN1_TIME_set.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_TIME_set 3" -.TH ASN1_TIME_set 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_TIME_set 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ASN1_generate_nconf.3 b/secure/lib/libcrypto/man/ASN1_generate_nconf.3 index 40aed65b8a16..21ca91c782ca 100644 --- a/secure/lib/libcrypto/man/ASN1_generate_nconf.3 +++ b/secure/lib/libcrypto/man/ASN1_generate_nconf.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ASN1_generate_nconf 3" -.TH ASN1_generate_nconf 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1_generate_nconf 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_ctrl.3 b/secure/lib/libcrypto/man/BIO_ctrl.3 index 5c7e1d0da10b..c7b1a8711c5b 100644 --- a/secure/lib/libcrypto/man/BIO_ctrl.3 +++ b/secure/lib/libcrypto/man/BIO_ctrl.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_ctrl 3" -.TH BIO_ctrl 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_ctrl 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_base64.3 b/secure/lib/libcrypto/man/BIO_f_base64.3 index 9ecbf8adbe34..2f54714acfc4 100644 --- a/secure/lib/libcrypto/man/BIO_f_base64.3 +++ b/secure/lib/libcrypto/man/BIO_f_base64.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_base64 3" -.TH BIO_f_base64 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_base64 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_buffer.3 b/secure/lib/libcrypto/man/BIO_f_buffer.3 index ceea86218617..f53cc1772a5e 100644 --- a/secure/lib/libcrypto/man/BIO_f_buffer.3 +++ b/secure/lib/libcrypto/man/BIO_f_buffer.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_buffer 3" -.TH BIO_f_buffer 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_buffer 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_cipher.3 b/secure/lib/libcrypto/man/BIO_f_cipher.3 index 10f2f664b3ea..717be4d42e5c 100644 --- a/secure/lib/libcrypto/man/BIO_f_cipher.3 +++ b/secure/lib/libcrypto/man/BIO_f_cipher.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_cipher 3" -.TH BIO_f_cipher 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_cipher 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_md.3 b/secure/lib/libcrypto/man/BIO_f_md.3 index 5190de44eccf..61d9564ca4c1 100644 --- a/secure/lib/libcrypto/man/BIO_f_md.3 +++ b/secure/lib/libcrypto/man/BIO_f_md.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_md 3" -.TH BIO_f_md 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_md 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_null.3 b/secure/lib/libcrypto/man/BIO_f_null.3 index bce2a4129bdc..406e0a996a9a 100644 --- a/secure/lib/libcrypto/man/BIO_f_null.3 +++ b/secure/lib/libcrypto/man/BIO_f_null.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_null 3" -.TH BIO_f_null 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_null 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_f_ssl.3 b/secure/lib/libcrypto/man/BIO_f_ssl.3 index 5b84694b7688..833c552c520c 100644 --- a/secure/lib/libcrypto/man/BIO_f_ssl.3 +++ b/secure/lib/libcrypto/man/BIO_f_ssl.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_f_ssl 3" -.TH BIO_f_ssl 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_f_ssl 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_find_type.3 b/secure/lib/libcrypto/man/BIO_find_type.3 index cf617a0e9be4..436c7b8f41fd 100644 --- a/secure/lib/libcrypto/man/BIO_find_type.3 +++ b/secure/lib/libcrypto/man/BIO_find_type.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_find_type 3" -.TH BIO_find_type 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_find_type 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_new.3 b/secure/lib/libcrypto/man/BIO_new.3 index b3ace30a6449..88e6b5027e5f 100644 --- a/secure/lib/libcrypto/man/BIO_new.3 +++ b/secure/lib/libcrypto/man/BIO_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_new 3" -.TH BIO_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_new_CMS.3 b/secure/lib/libcrypto/man/BIO_new_CMS.3 index 1cb3d8e8f0c1..cf7c315cd538 100644 --- a/secure/lib/libcrypto/man/BIO_new_CMS.3 +++ b/secure/lib/libcrypto/man/BIO_new_CMS.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_new_CMS 3" -.TH BIO_new_CMS 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_new_CMS 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_push.3 b/secure/lib/libcrypto/man/BIO_push.3 index 3b88daab0675..ad30f7bd5c45 100644 --- a/secure/lib/libcrypto/man/BIO_push.3 +++ b/secure/lib/libcrypto/man/BIO_push.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_push 3" -.TH BIO_push 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_push 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_read.3 b/secure/lib/libcrypto/man/BIO_read.3 index 1501ecd12973..82b536f52423 100644 --- a/secure/lib/libcrypto/man/BIO_read.3 +++ b/secure/lib/libcrypto/man/BIO_read.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_read 3" -.TH BIO_read 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_read 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_accept.3 b/secure/lib/libcrypto/man/BIO_s_accept.3 index c00f233f1c28..42fbecff5ca1 100644 --- a/secure/lib/libcrypto/man/BIO_s_accept.3 +++ b/secure/lib/libcrypto/man/BIO_s_accept.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_accept 3" -.TH BIO_s_accept 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_accept 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_bio.3 b/secure/lib/libcrypto/man/BIO_s_bio.3 index 1a09226985d3..f92f0f21f8b0 100644 --- a/secure/lib/libcrypto/man/BIO_s_bio.3 +++ b/secure/lib/libcrypto/man/BIO_s_bio.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_bio 3" -.TH BIO_s_bio 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_bio 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_connect.3 b/secure/lib/libcrypto/man/BIO_s_connect.3 index 44400ceeaa57..b4e142775646 100644 --- a/secure/lib/libcrypto/man/BIO_s_connect.3 +++ b/secure/lib/libcrypto/man/BIO_s_connect.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_connect 3" -.TH BIO_s_connect 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_connect 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_fd.3 b/secure/lib/libcrypto/man/BIO_s_fd.3 index 369105ccf2c7..ca1113c87bf0 100644 --- a/secure/lib/libcrypto/man/BIO_s_fd.3 +++ b/secure/lib/libcrypto/man/BIO_s_fd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_fd 3" -.TH BIO_s_fd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_fd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_file.3 b/secure/lib/libcrypto/man/BIO_s_file.3 index 997b888e50c2..9034f9b54989 100644 --- a/secure/lib/libcrypto/man/BIO_s_file.3 +++ b/secure/lib/libcrypto/man/BIO_s_file.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_file 3" -.TH BIO_s_file 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_file 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_mem.3 b/secure/lib/libcrypto/man/BIO_s_mem.3 index 857b105531ce..2828bd94cf82 100644 --- a/secure/lib/libcrypto/man/BIO_s_mem.3 +++ b/secure/lib/libcrypto/man/BIO_s_mem.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_mem 3" -.TH BIO_s_mem 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_mem 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_null.3 b/secure/lib/libcrypto/man/BIO_s_null.3 index 78c6a0d12df9..9ee2f24bda18 100644 --- a/secure/lib/libcrypto/man/BIO_s_null.3 +++ b/secure/lib/libcrypto/man/BIO_s_null.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_null 3" -.TH BIO_s_null 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_null 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_s_socket.3 b/secure/lib/libcrypto/man/BIO_s_socket.3 index 00af35432825..def0a055dacd 100644 --- a/secure/lib/libcrypto/man/BIO_s_socket.3 +++ b/secure/lib/libcrypto/man/BIO_s_socket.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_s_socket 3" -.TH BIO_s_socket 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_s_socket 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_set_callback.3 b/secure/lib/libcrypto/man/BIO_set_callback.3 index 1d2789dacada..9c6b86aa206f 100644 --- a/secure/lib/libcrypto/man/BIO_set_callback.3 +++ b/secure/lib/libcrypto/man/BIO_set_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_set_callback 3" -.TH BIO_set_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_set_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BIO_should_retry.3 b/secure/lib/libcrypto/man/BIO_should_retry.3 index c1d2b9785fd9..93184b6709ca 100644 --- a/secure/lib/libcrypto/man/BIO_should_retry.3 +++ b/secure/lib/libcrypto/man/BIO_should_retry.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BIO_should_retry 3" -.TH BIO_should_retry 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BIO_should_retry 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_BLINDING_new.3 b/secure/lib/libcrypto/man/BN_BLINDING_new.3 index d770f3b0e9b9..4a1d9aaba3d7 100644 --- a/secure/lib/libcrypto/man/BN_BLINDING_new.3 +++ b/secure/lib/libcrypto/man/BN_BLINDING_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_BLINDING_new 3" -.TH BN_BLINDING_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_BLINDING_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_CTX_new.3 b/secure/lib/libcrypto/man/BN_CTX_new.3 index 79a255d03324..3df698a78995 100644 --- a/secure/lib/libcrypto/man/BN_CTX_new.3 +++ b/secure/lib/libcrypto/man/BN_CTX_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_CTX_new 3" -.TH BN_CTX_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_CTX_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_CTX_start.3 b/secure/lib/libcrypto/man/BN_CTX_start.3 index 51efc69e714e..1d154aca7364 100644 --- a/secure/lib/libcrypto/man/BN_CTX_start.3 +++ b/secure/lib/libcrypto/man/BN_CTX_start.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_CTX_start 3" -.TH BN_CTX_start 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_CTX_start 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_add.3 b/secure/lib/libcrypto/man/BN_add.3 index 111c2af2911f..82bad3fd62ad 100644 --- a/secure/lib/libcrypto/man/BN_add.3 +++ b/secure/lib/libcrypto/man/BN_add.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_add 3" -.TH BN_add 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_add 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_add_word.3 b/secure/lib/libcrypto/man/BN_add_word.3 index 3977f4a890c2..6f65bc58041d 100644 --- a/secure/lib/libcrypto/man/BN_add_word.3 +++ b/secure/lib/libcrypto/man/BN_add_word.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_add_word 3" -.TH BN_add_word 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_add_word 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_bn2bin.3 b/secure/lib/libcrypto/man/BN_bn2bin.3 index f8e9ae88bd20..ebe24769aa87 100644 --- a/secure/lib/libcrypto/man/BN_bn2bin.3 +++ b/secure/lib/libcrypto/man/BN_bn2bin.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_bn2bin 3" -.TH BN_bn2bin 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_bn2bin 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -202,8 +202,9 @@ if \fBret\fR is \s-1NULL.\s0 \&\fIBN_bin2bn()\fR returns the \fB\s-1BIGNUM\s0\fR, \s-1NULL\s0 on error. .PP \&\fIBN_bn2hex()\fR and \fIBN_bn2dec()\fR return a null-terminated string, or \s-1NULL\s0 -on error. \fIBN_hex2bn()\fR and \fIBN_dec2bn()\fR return the number's length in -hexadecimal or decimal digits, and 0 on error. +on error. \fIBN_hex2bn()\fR and \fIBN_dec2bn()\fR return the number of characters +used in parsing, or 0 on error, in which +case no new \fB\s-1BIGNUM\s0\fR will be created. .PP \&\fIBN_print_fp()\fR and \fIBN_print()\fR return 1 on success, 0 on write errors. .PP diff --git a/secure/lib/libcrypto/man/BN_cmp.3 b/secure/lib/libcrypto/man/BN_cmp.3 index 0be97451bbdb..cc87414f4573 100644 --- a/secure/lib/libcrypto/man/BN_cmp.3 +++ b/secure/lib/libcrypto/man/BN_cmp.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_cmp 3" -.TH BN_cmp 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_cmp 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_copy.3 b/secure/lib/libcrypto/man/BN_copy.3 index 36413fefa412..6a303316f536 100644 --- a/secure/lib/libcrypto/man/BN_copy.3 +++ b/secure/lib/libcrypto/man/BN_copy.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_copy 3" -.TH BN_copy 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_copy 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_generate_prime.3 b/secure/lib/libcrypto/man/BN_generate_prime.3 index 4e80799963e4..89525193f66a 100644 --- a/secure/lib/libcrypto/man/BN_generate_prime.3 +++ b/secure/lib/libcrypto/man/BN_generate_prime.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_generate_prime 3" -.TH BN_generate_prime 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_generate_prime 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_mod_inverse.3 b/secure/lib/libcrypto/man/BN_mod_inverse.3 index 368aadd8d783..e9ae8065debd 100644 --- a/secure/lib/libcrypto/man/BN_mod_inverse.3 +++ b/secure/lib/libcrypto/man/BN_mod_inverse.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_mod_inverse 3" -.TH BN_mod_inverse 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_mod_inverse 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 index 865aabb1d6cc..418dc3f6f4aa 100644 --- a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 +++ b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_mod_mul_montgomery 3" -.TH BN_mod_mul_montgomery 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_mod_mul_montgomery 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 index c62871fef9f3..e69f92cb69e6 100644 --- a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 +++ b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_mod_mul_reciprocal 3" -.TH BN_mod_mul_reciprocal 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_mod_mul_reciprocal 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_new.3 b/secure/lib/libcrypto/man/BN_new.3 index 17636a491833..1eda87c3922b 100644 --- a/secure/lib/libcrypto/man/BN_new.3 +++ b/secure/lib/libcrypto/man/BN_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_new 3" -.TH BN_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -163,9 +163,11 @@ to the value 0. \&\fIBN_free()\fR frees the components of the \fB\s-1BIGNUM\s0\fR, and if it was created by \fIBN_new()\fR, also the structure itself. \fIBN_clear_free()\fR additionally overwrites the data before the memory is returned to the system. +If \fBa\fR is \s-1NULL,\s0 nothing is done. .SH "RETURN VALUES" .IX Header "RETURN VALUES" -\&\fIBN_new()\fR returns a pointer to the \fB\s-1BIGNUM\s0\fR. If the allocation fails, +\&\fIBN_new()\fR returns a pointer to the \fB\s-1BIGNUM\s0\fR initialised to the value 0. +If the allocation fails, it returns \fB\s-1NULL\s0\fR and sets an error code that can be obtained by \fIERR_get_error\fR\|(3). .PP diff --git a/secure/lib/libcrypto/man/BN_num_bytes.3 b/secure/lib/libcrypto/man/BN_num_bytes.3 index 47fbdff10f2f..b54ae85a3cae 100644 --- a/secure/lib/libcrypto/man/BN_num_bytes.3 +++ b/secure/lib/libcrypto/man/BN_num_bytes.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_num_bytes 3" -.TH BN_num_bytes 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_num_bytes 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_rand.3 b/secure/lib/libcrypto/man/BN_rand.3 index 4e5d2487bff2..7507c59a4555 100644 --- a/secure/lib/libcrypto/man/BN_rand.3 +++ b/secure/lib/libcrypto/man/BN_rand.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_rand 3" -.TH BN_rand 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_rand 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_set_bit.3 b/secure/lib/libcrypto/man/BN_set_bit.3 index 75df857b58e3..43d3c5f0903a 100644 --- a/secure/lib/libcrypto/man/BN_set_bit.3 +++ b/secure/lib/libcrypto/man/BN_set_bit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_set_bit 3" -.TH BN_set_bit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_set_bit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_swap.3 b/secure/lib/libcrypto/man/BN_swap.3 index 7244c44ae565..98bf01e3a8c3 100644 --- a/secure/lib/libcrypto/man/BN_swap.3 +++ b/secure/lib/libcrypto/man/BN_swap.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_swap 3" -.TH BN_swap 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_swap 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/BN_zero.3 b/secure/lib/libcrypto/man/BN_zero.3 index 866f9adacad1..060afe121091 100644 --- a/secure/lib/libcrypto/man/BN_zero.3 +++ b/secure/lib/libcrypto/man/BN_zero.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BN_zero 3" -.TH BN_zero 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH BN_zero 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_add0_cert.3 b/secure/lib/libcrypto/man/CMS_add0_cert.3 index 037680afd9ea..fc57f45bf401 100644 --- a/secure/lib/libcrypto/man/CMS_add0_cert.3 +++ b/secure/lib/libcrypto/man/CMS_add0_cert.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_add0_cert 3" -.TH CMS_add0_cert 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_add0_cert 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_add1_recipient_cert.3 b/secure/lib/libcrypto/man/CMS_add1_recipient_cert.3 index dbccbb1f64d7..9d0049d4b403 100644 --- a/secure/lib/libcrypto/man/CMS_add1_recipient_cert.3 +++ b/secure/lib/libcrypto/man/CMS_add1_recipient_cert.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_add1_recipient_cert 3" -.TH CMS_add1_recipient_cert 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_add1_recipient_cert 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_add1_signer.3 b/secure/lib/libcrypto/man/CMS_add1_signer.3 index 016242ca13e5..aca496ffe5c7 100644 --- a/secure/lib/libcrypto/man/CMS_add1_signer.3 +++ b/secure/lib/libcrypto/man/CMS_add1_signer.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_add1_signer 3" -.TH CMS_add1_signer 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_add1_signer 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_compress.3 b/secure/lib/libcrypto/man/CMS_compress.3 index 26649a70c789..a8c62a26d09f 100644 --- a/secure/lib/libcrypto/man/CMS_compress.3 +++ b/secure/lib/libcrypto/man/CMS_compress.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_compress 3" -.TH CMS_compress 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_compress 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_decrypt.3 b/secure/lib/libcrypto/man/CMS_decrypt.3 index a6016b9794ec..793e835d9ad1 100644 --- a/secure/lib/libcrypto/man/CMS_decrypt.3 +++ b/secure/lib/libcrypto/man/CMS_decrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_decrypt 3" -.TH CMS_decrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_decrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_encrypt.3 b/secure/lib/libcrypto/man/CMS_encrypt.3 index 67776b55a2e5..e04ebf4a295c 100644 --- a/secure/lib/libcrypto/man/CMS_encrypt.3 +++ b/secure/lib/libcrypto/man/CMS_encrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_encrypt 3" -.TH CMS_encrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_encrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_final.3 b/secure/lib/libcrypto/man/CMS_final.3 index ee90cdd03bef..b6f98b5e1cc0 100644 --- a/secure/lib/libcrypto/man/CMS_final.3 +++ b/secure/lib/libcrypto/man/CMS_final.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_final 3" -.TH CMS_final 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_final 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_get0_RecipientInfos.3 b/secure/lib/libcrypto/man/CMS_get0_RecipientInfos.3 index 53144a7abc81..5ac4ceaad024 100644 --- a/secure/lib/libcrypto/man/CMS_get0_RecipientInfos.3 +++ b/secure/lib/libcrypto/man/CMS_get0_RecipientInfos.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_get0_RecipientInfos 3" -.TH CMS_get0_RecipientInfos 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_get0_RecipientInfos 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_get0_SignerInfos.3 b/secure/lib/libcrypto/man/CMS_get0_SignerInfos.3 index 3c6d12d690a9..8f8ac50efc76 100644 --- a/secure/lib/libcrypto/man/CMS_get0_SignerInfos.3 +++ b/secure/lib/libcrypto/man/CMS_get0_SignerInfos.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_get0_SignerInfos 3" -.TH CMS_get0_SignerInfos 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_get0_SignerInfos 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_get0_type.3 b/secure/lib/libcrypto/man/CMS_get0_type.3 index 908623b4144d..704bc4584700 100644 --- a/secure/lib/libcrypto/man/CMS_get0_type.3 +++ b/secure/lib/libcrypto/man/CMS_get0_type.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_get0_type 3" -.TH CMS_get0_type 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_get0_type 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_get1_ReceiptRequest.3 b/secure/lib/libcrypto/man/CMS_get1_ReceiptRequest.3 index 151fb7ee16cd..76d9c09f3e0e 100644 --- a/secure/lib/libcrypto/man/CMS_get1_ReceiptRequest.3 +++ b/secure/lib/libcrypto/man/CMS_get1_ReceiptRequest.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_get1_ReceiptRequest 3" -.TH CMS_get1_ReceiptRequest 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_get1_ReceiptRequest 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_sign.3 b/secure/lib/libcrypto/man/CMS_sign.3 index c903dd919bb6..e93b9a7b90f3 100644 --- a/secure/lib/libcrypto/man/CMS_sign.3 +++ b/secure/lib/libcrypto/man/CMS_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_sign 3" -.TH CMS_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_sign_receipt.3 b/secure/lib/libcrypto/man/CMS_sign_receipt.3 index c37ec6ccc832..62e270c63d54 100644 --- a/secure/lib/libcrypto/man/CMS_sign_receipt.3 +++ b/secure/lib/libcrypto/man/CMS_sign_receipt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_sign_receipt 3" -.TH CMS_sign_receipt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_sign_receipt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_uncompress.3 b/secure/lib/libcrypto/man/CMS_uncompress.3 index 2f967e618ef3..e7106b595c8c 100644 --- a/secure/lib/libcrypto/man/CMS_uncompress.3 +++ b/secure/lib/libcrypto/man/CMS_uncompress.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_uncompress 3" -.TH CMS_uncompress 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_uncompress 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_verify.3 b/secure/lib/libcrypto/man/CMS_verify.3 index a6d7791acd72..e9c999702621 100644 --- a/secure/lib/libcrypto/man/CMS_verify.3 +++ b/secure/lib/libcrypto/man/CMS_verify.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_verify 3" -.TH CMS_verify 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_verify 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CMS_verify_receipt.3 b/secure/lib/libcrypto/man/CMS_verify_receipt.3 index 07a1bd237950..377c000ed652 100644 --- a/secure/lib/libcrypto/man/CMS_verify_receipt.3 +++ b/secure/lib/libcrypto/man/CMS_verify_receipt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CMS_verify_receipt 3" -.TH CMS_verify_receipt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS_verify_receipt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CONF_modules_free.3 b/secure/lib/libcrypto/man/CONF_modules_free.3 index eb3ddd599963..769e6dfc4582 100644 --- a/secure/lib/libcrypto/man/CONF_modules_free.3 +++ b/secure/lib/libcrypto/man/CONF_modules_free.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CONF_modules_free 3" -.TH CONF_modules_free 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CONF_modules_free 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CONF_modules_load_file.3 b/secure/lib/libcrypto/man/CONF_modules_load_file.3 index 98733f267666..6f7387141ff7 100644 --- a/secure/lib/libcrypto/man/CONF_modules_load_file.3 +++ b/secure/lib/libcrypto/man/CONF_modules_load_file.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CONF_modules_load_file 3" -.TH CONF_modules_load_file 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CONF_modules_load_file 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 index 0414f50db53f..b0422bc302cd 100644 --- a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 +++ b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CRYPTO_set_ex_data 3" -.TH CRYPTO_set_ex_data 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CRYPTO_set_ex_data 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_generate_key.3 b/secure/lib/libcrypto/man/DH_generate_key.3 index 07c68c5a2e83..f0ed83430592 100644 --- a/secure/lib/libcrypto/man/DH_generate_key.3 +++ b/secure/lib/libcrypto/man/DH_generate_key.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_generate_key 3" -.TH DH_generate_key 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_generate_key 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_generate_parameters.3 b/secure/lib/libcrypto/man/DH_generate_parameters.3 index 41e1b8f564c0..7e7d381adbd6 100644 --- a/secure/lib/libcrypto/man/DH_generate_parameters.3 +++ b/secure/lib/libcrypto/man/DH_generate_parameters.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_generate_parameters 3" -.TH DH_generate_parameters 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_generate_parameters 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_get_ex_new_index.3 b/secure/lib/libcrypto/man/DH_get_ex_new_index.3 index eeeaedb1051c..dbfac6ac56b4 100644 --- a/secure/lib/libcrypto/man/DH_get_ex_new_index.3 +++ b/secure/lib/libcrypto/man/DH_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_get_ex_new_index 3" -.TH DH_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_new.3 b/secure/lib/libcrypto/man/DH_new.3 index 49d92b33163c..96021212b852 100644 --- a/secure/lib/libcrypto/man/DH_new.3 +++ b/secure/lib/libcrypto/man/DH_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_new 3" -.TH DH_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_set_method.3 b/secure/lib/libcrypto/man/DH_set_method.3 index 9b5938663c59..a235a16876e0 100644 --- a/secure/lib/libcrypto/man/DH_set_method.3 +++ b/secure/lib/libcrypto/man/DH_set_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_set_method 3" -.TH DH_set_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_set_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DH_size.3 b/secure/lib/libcrypto/man/DH_size.3 index 891a9daf139e..8259dc5df256 100644 --- a/secure/lib/libcrypto/man/DH_size.3 +++ b/secure/lib/libcrypto/man/DH_size.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DH_size 3" -.TH DH_size 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DH_size 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_SIG_new.3 b/secure/lib/libcrypto/man/DSA_SIG_new.3 index 068a8e94e4e7..028b2856aa5e 100644 --- a/secure/lib/libcrypto/man/DSA_SIG_new.3 +++ b/secure/lib/libcrypto/man/DSA_SIG_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_SIG_new 3" -.TH DSA_SIG_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_SIG_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_do_sign.3 b/secure/lib/libcrypto/man/DSA_do_sign.3 index 1cd3cad97110..565342a4a5e8 100644 --- a/secure/lib/libcrypto/man/DSA_do_sign.3 +++ b/secure/lib/libcrypto/man/DSA_do_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_do_sign 3" -.TH DSA_do_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_do_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_dup_DH.3 b/secure/lib/libcrypto/man/DSA_dup_DH.3 index 5cdca46b47ba..a5082afc5e6c 100644 --- a/secure/lib/libcrypto/man/DSA_dup_DH.3 +++ b/secure/lib/libcrypto/man/DSA_dup_DH.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_dup_DH 3" -.TH DSA_dup_DH 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_dup_DH 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_generate_key.3 b/secure/lib/libcrypto/man/DSA_generate_key.3 index 7db87ec4b556..3f54cf2207c1 100644 --- a/secure/lib/libcrypto/man/DSA_generate_key.3 +++ b/secure/lib/libcrypto/man/DSA_generate_key.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_generate_key 3" -.TH DSA_generate_key 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_generate_key 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_generate_parameters.3 b/secure/lib/libcrypto/man/DSA_generate_parameters.3 index 80406d6e7990..e03fee4bed89 100644 --- a/secure/lib/libcrypto/man/DSA_generate_parameters.3 +++ b/secure/lib/libcrypto/man/DSA_generate_parameters.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_generate_parameters 3" -.TH DSA_generate_parameters 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_generate_parameters 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 index 6dbc33ea09c1..40ed9eb5f581 100644 --- a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 +++ b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_get_ex_new_index 3" -.TH DSA_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_new.3 b/secure/lib/libcrypto/man/DSA_new.3 index 489ea4824cf2..0f32583b5dc8 100644 --- a/secure/lib/libcrypto/man/DSA_new.3 +++ b/secure/lib/libcrypto/man/DSA_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_new 3" -.TH DSA_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_set_method.3 b/secure/lib/libcrypto/man/DSA_set_method.3 index ae04e0bc89e1..5ead4ff4e567 100644 --- a/secure/lib/libcrypto/man/DSA_set_method.3 +++ b/secure/lib/libcrypto/man/DSA_set_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_set_method 3" -.TH DSA_set_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_set_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_sign.3 b/secure/lib/libcrypto/man/DSA_sign.3 index a7b6f17e199c..509b5455db3e 100644 --- a/secure/lib/libcrypto/man/DSA_sign.3 +++ b/secure/lib/libcrypto/man/DSA_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_sign 3" -.TH DSA_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/DSA_size.3 b/secure/lib/libcrypto/man/DSA_size.3 index 29f1fb122553..cc8810842c4e 100644 --- a/secure/lib/libcrypto/man/DSA_size.3 +++ b/secure/lib/libcrypto/man/DSA_size.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DSA_size 3" -.TH DSA_size 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA_size 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_GFp_simple_method.3 b/secure/lib/libcrypto/man/EC_GFp_simple_method.3 index 991941bad649..fa038c85be2c 100644 --- a/secure/lib/libcrypto/man/EC_GFp_simple_method.3 +++ b/secure/lib/libcrypto/man/EC_GFp_simple_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_GFp_simple_method 3" -.TH EC_GFp_simple_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_GFp_simple_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_GROUP_copy.3 b/secure/lib/libcrypto/man/EC_GROUP_copy.3 index abf4732a010b..624fe0ff7fec 100644 --- a/secure/lib/libcrypto/man/EC_GROUP_copy.3 +++ b/secure/lib/libcrypto/man/EC_GROUP_copy.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_GROUP_copy 3" -.TH EC_GROUP_copy 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_GROUP_copy 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_GROUP_new.3 b/secure/lib/libcrypto/man/EC_GROUP_new.3 index 9df10468bec3..c39dfe619ddf 100644 --- a/secure/lib/libcrypto/man/EC_GROUP_new.3 +++ b/secure/lib/libcrypto/man/EC_GROUP_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_GROUP_new 3" -.TH EC_GROUP_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_GROUP_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_KEY_new.3 b/secure/lib/libcrypto/man/EC_KEY_new.3 index 508f827a3ad7..439d22acb5b9 100644 --- a/secure/lib/libcrypto/man/EC_KEY_new.3 +++ b/secure/lib/libcrypto/man/EC_KEY_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_KEY_new 3" -.TH EC_KEY_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_KEY_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_POINT_add.3 b/secure/lib/libcrypto/man/EC_POINT_add.3 index 89e13ed4b6eb..7f50ffac426a 100644 --- a/secure/lib/libcrypto/man/EC_POINT_add.3 +++ b/secure/lib/libcrypto/man/EC_POINT_add.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_POINT_add 3" -.TH EC_POINT_add 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_POINT_add 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EC_POINT_new.3 b/secure/lib/libcrypto/man/EC_POINT_new.3 index f6c275725629..18e505a0d9ce 100644 --- a/secure/lib/libcrypto/man/EC_POINT_new.3 +++ b/secure/lib/libcrypto/man/EC_POINT_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EC_POINT_new 3" -.TH EC_POINT_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC_POINT_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_GET_LIB.3 b/secure/lib/libcrypto/man/ERR_GET_LIB.3 index a1ed22e1188f..0baf558ff43a 100644 --- a/secure/lib/libcrypto/man/ERR_GET_LIB.3 +++ b/secure/lib/libcrypto/man/ERR_GET_LIB.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_GET_LIB 3" -.TH ERR_GET_LIB 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_GET_LIB 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_clear_error.3 b/secure/lib/libcrypto/man/ERR_clear_error.3 index 9c05b90cdff0..9d346d161f59 100644 --- a/secure/lib/libcrypto/man/ERR_clear_error.3 +++ b/secure/lib/libcrypto/man/ERR_clear_error.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_clear_error 3" -.TH ERR_clear_error 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_clear_error 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_error_string.3 b/secure/lib/libcrypto/man/ERR_error_string.3 index b9e65c6036fa..8a003e40d8c2 100644 --- a/secure/lib/libcrypto/man/ERR_error_string.3 +++ b/secure/lib/libcrypto/man/ERR_error_string.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_error_string 3" -.TH ERR_error_string 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_error_string 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_get_error.3 b/secure/lib/libcrypto/man/ERR_get_error.3 index 4ee451fc1127..a7f4fcdac6b1 100644 --- a/secure/lib/libcrypto/man/ERR_get_error.3 +++ b/secure/lib/libcrypto/man/ERR_get_error.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_get_error 3" -.TH ERR_get_error 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_get_error 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 index 2f15d30ab359..e39b291f4fd6 100644 --- a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 +++ b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_load_crypto_strings 3" -.TH ERR_load_crypto_strings 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_load_crypto_strings 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_load_strings.3 b/secure/lib/libcrypto/man/ERR_load_strings.3 index 78e74ab4238c..be6f1755d8fd 100644 --- a/secure/lib/libcrypto/man/ERR_load_strings.3 +++ b/secure/lib/libcrypto/man/ERR_load_strings.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_load_strings 3" -.TH ERR_load_strings 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_load_strings 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_print_errors.3 b/secure/lib/libcrypto/man/ERR_print_errors.3 index 7653b43d3a57..1ca1dbb24258 100644 --- a/secure/lib/libcrypto/man/ERR_print_errors.3 +++ b/secure/lib/libcrypto/man/ERR_print_errors.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_print_errors 3" -.TH ERR_print_errors 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_print_errors 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_put_error.3 b/secure/lib/libcrypto/man/ERR_put_error.3 index e0d3ed311e15..e7b6c74e4197 100644 --- a/secure/lib/libcrypto/man/ERR_put_error.3 +++ b/secure/lib/libcrypto/man/ERR_put_error.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_put_error 3" -.TH ERR_put_error 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_put_error 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_remove_state.3 b/secure/lib/libcrypto/man/ERR_remove_state.3 index ac75e725e92a..d94056ff49c6 100644 --- a/secure/lib/libcrypto/man/ERR_remove_state.3 +++ b/secure/lib/libcrypto/man/ERR_remove_state.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_remove_state 3" -.TH ERR_remove_state 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_remove_state 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ERR_set_mark.3 b/secure/lib/libcrypto/man/ERR_set_mark.3 index ae1bf6ded0fa..c71a0e272e58 100644 --- a/secure/lib/libcrypto/man/ERR_set_mark.3 +++ b/secure/lib/libcrypto/man/ERR_set_mark.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ERR_set_mark 3" -.TH ERR_set_mark 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERR_set_mark 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_BytesToKey.3 b/secure/lib/libcrypto/man/EVP_BytesToKey.3 index 765cf615e0f8..d56a08648f16 100644 --- a/secure/lib/libcrypto/man/EVP_BytesToKey.3 +++ b/secure/lib/libcrypto/man/EVP_BytesToKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_BytesToKey 3" -.TH EVP_BytesToKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_BytesToKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_DigestInit.3 b/secure/lib/libcrypto/man/EVP_DigestInit.3 index 11993befcddf..8a86fb3deb31 100644 --- a/secure/lib/libcrypto/man/EVP_DigestInit.3 +++ b/secure/lib/libcrypto/man/EVP_DigestInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_DigestInit 3" -.TH EVP_DigestInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_DigestInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_DigestSignInit.3 b/secure/lib/libcrypto/man/EVP_DigestSignInit.3 index c90ea3b00770..c42a09249a68 100644 --- a/secure/lib/libcrypto/man/EVP_DigestSignInit.3 +++ b/secure/lib/libcrypto/man/EVP_DigestSignInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_DigestSignInit 3" -.TH EVP_DigestSignInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_DigestSignInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_DigestVerifyInit.3 b/secure/lib/libcrypto/man/EVP_DigestVerifyInit.3 index 2ddf66052450..ae19e5c8ce6a 100644 --- a/secure/lib/libcrypto/man/EVP_DigestVerifyInit.3 +++ b/secure/lib/libcrypto/man/EVP_DigestVerifyInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_DigestVerifyInit 3" -.TH EVP_DigestVerifyInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_DigestVerifyInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_EncodeInit.3 b/secure/lib/libcrypto/man/EVP_EncodeInit.3 index abb34ab114a9..594054639a19 100644 --- a/secure/lib/libcrypto/man/EVP_EncodeInit.3 +++ b/secure/lib/libcrypto/man/EVP_EncodeInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_EncodeInit 3" -.TH EVP_EncodeInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_EncodeInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_EncryptInit.3 b/secure/lib/libcrypto/man/EVP_EncryptInit.3 index 3b16207fe2aa..6e72f5396626 100644 --- a/secure/lib/libcrypto/man/EVP_EncryptInit.3 +++ b/secure/lib/libcrypto/man/EVP_EncryptInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_EncryptInit 3" -.TH EVP_EncryptInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_EncryptInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -512,8 +512,7 @@ processed (e.g. after an \fIEVP_EncryptFinal()\fR call). .Ve .PP Sets the expected tag to \fBtaglen\fR bytes from \fBtag\fR. This call is only legal -when decrypting data and must be made \fBbefore\fR any data is processed (e.g. -before any \fIEVP_DecryptUpdate()\fR call). +when decrypting data. .SH "CCM Mode" .IX Header "CCM Mode" The behaviour of \s-1CCM\s0 mode ciphers is similar to \s-1CCM\s0 mode but with a few diff --git a/secure/lib/libcrypto/man/EVP_OpenInit.3 b/secure/lib/libcrypto/man/EVP_OpenInit.3 index 00eedbe83cae..0b68e5dc4b01 100644 --- a/secure/lib/libcrypto/man/EVP_OpenInit.3 +++ b/secure/lib/libcrypto/man/EVP_OpenInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_OpenInit 3" -.TH EVP_OpenInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_OpenInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_CTX_ctrl.3 b/secure/lib/libcrypto/man/EVP_PKEY_CTX_ctrl.3 index 5cf329b396e7..c201b15d9d79 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_CTX_ctrl.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_CTX_ctrl.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_CTX_ctrl 3" -.TH EVP_PKEY_CTX_ctrl 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_CTX_ctrl 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_CTX_new.3 b/secure/lib/libcrypto/man/EVP_PKEY_CTX_new.3 index 9324a8079228..9e8b6753c478 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_CTX_new.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_CTX_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_CTX_new 3" -.TH EVP_PKEY_CTX_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_CTX_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_cmp.3 b/secure/lib/libcrypto/man/EVP_PKEY_cmp.3 index 6c2e66023cd8..760afa7c5850 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_cmp.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_cmp.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_cmp 3" -.TH EVP_PKEY_cmp 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_cmp 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_decrypt.3 b/secure/lib/libcrypto/man/EVP_PKEY_decrypt.3 index e788a45239ea..7025a0d6eeac 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_decrypt.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_decrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_decrypt 3" -.TH EVP_PKEY_decrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_decrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_derive.3 b/secure/lib/libcrypto/man/EVP_PKEY_derive.3 index 67148231c81b..52fc3eca0ca8 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_derive.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_derive.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_derive 3" -.TH EVP_PKEY_derive 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_derive 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_encrypt.3 b/secure/lib/libcrypto/man/EVP_PKEY_encrypt.3 index fba84059cee3..da11fe77e564 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_encrypt.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_encrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_encrypt 3" -.TH EVP_PKEY_encrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_encrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_get_default_digest.3 b/secure/lib/libcrypto/man/EVP_PKEY_get_default_digest.3 index 7bd8afb703a3..2dcb3e94b359 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_get_default_digest.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_get_default_digest.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_get_default_digest 3" -.TH EVP_PKEY_get_default_digest 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_get_default_digest 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_keygen.3 b/secure/lib/libcrypto/man/EVP_PKEY_keygen.3 index 300836e0495a..9474ba5cd633 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_keygen.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_keygen.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_keygen 3" -.TH EVP_PKEY_keygen 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_keygen 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_meth_new.3 b/secure/lib/libcrypto/man/EVP_PKEY_meth_new.3 new file mode 100644 index 000000000000..d978226cea6a --- /dev/null +++ b/secure/lib/libcrypto/man/EVP_PKEY_meth_new.3 @@ -0,0 +1,531 @@ +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "EVP_PKEY_meth_new 3" +.TH EVP_PKEY_meth_new 3 "2017-11-02" "1.0.2m" "OpenSSL" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +EVP_PKEY_meth_new, EVP_PKEY_meth_free, EVP_PKEY_meth_copy, EVP_PKEY_meth_find, +EVP_PKEY_meth_add0, EVP_PKEY_METHOD, +EVP_PKEY_meth_set_init, EVP_PKEY_meth_set_copy, EVP_PKEY_meth_set_cleanup, +EVP_PKEY_meth_set_paramgen, EVP_PKEY_meth_set_keygen, EVP_PKEY_meth_set_sign, +EVP_PKEY_meth_set_verify, EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_signctx, +EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt, EVP_PKEY_meth_set_decrypt, +EVP_PKEY_meth_set_derive, EVP_PKEY_meth_set_ctrl, +EVP_PKEY_meth_get_init, EVP_PKEY_meth_get_copy, EVP_PKEY_meth_get_cleanup, +EVP_PKEY_meth_get_paramgen, EVP_PKEY_meth_get_keygen, EVP_PKEY_meth_get_sign, +EVP_PKEY_meth_get_verify, EVP_PKEY_meth_get_verify_recover, EVP_PKEY_meth_get_signctx, +EVP_PKEY_meth_get_verifyctx, EVP_PKEY_meth_get_encrypt, EVP_PKEY_meth_get_decrypt, +EVP_PKEY_meth_get_derive, EVP_PKEY_meth_get_ctrl +\&\- manipulating EVP_PKEY_METHOD structure +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& #include +\& +\& typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +\& +\& EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +\& void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +\& void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +\& const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +\& int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +\& +\& void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, +\& int (*init) (EVP_PKEY_CTX *ctx)); +\& void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, +\& int (*copy) (EVP_PKEY_CTX *dst, +\& EVP_PKEY_CTX *src)); +\& void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, +\& void (*cleanup) (EVP_PKEY_CTX *ctx)); +\& void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, +\& int (*paramgen_init) (EVP_PKEY_CTX *ctx), +\& int (*paramgen) (EVP_PKEY_CTX *ctx, +\& EVP_PKEY *pkey)); +\& void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, +\& int (*keygen_init) (EVP_PKEY_CTX *ctx), +\& int (*keygen) (EVP_PKEY_CTX *ctx, +\& EVP_PKEY *pkey)); +\& void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, +\& int (*sign_init) (EVP_PKEY_CTX *ctx), +\& int (*sign) (EVP_PKEY_CTX *ctx, +\& unsigned char *sig, size_t *siglen, +\& const unsigned char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, +\& int (*verify_init) (EVP_PKEY_CTX *ctx), +\& int (*verify) (EVP_PKEY_CTX *ctx, +\& const unsigned char *sig, +\& size_t siglen, +\& const unsigned char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, +\& int (*verify_recover_init) (EVP_PKEY_CTX +\& *ctx), +\& int (*verify_recover) (EVP_PKEY_CTX +\& *ctx, +\& unsigned char +\& *sig, +\& size_t *siglen, +\& const unsigned +\& char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, +\& int (*signctx_init) (EVP_PKEY_CTX *ctx, +\& EVP_MD_CTX *mctx), +\& int (*signctx) (EVP_PKEY_CTX *ctx, +\& unsigned char *sig, +\& size_t *siglen, +\& EVP_MD_CTX *mctx)); +\& void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, +\& int (*verifyctx_init) (EVP_PKEY_CTX *ctx, +\& EVP_MD_CTX *mctx), +\& int (*verifyctx) (EVP_PKEY_CTX *ctx, +\& const unsigned char *sig, +\& int siglen, +\& EVP_MD_CTX *mctx)); +\& void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, +\& int (*encrypt_init) (EVP_PKEY_CTX *ctx), +\& int (*encryptfn) (EVP_PKEY_CTX *ctx, +\& unsigned char *out, +\& size_t *outlen, +\& const unsigned char *in, +\& size_t inlen)); +\& void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, +\& int (*decrypt_init) (EVP_PKEY_CTX *ctx), +\& int (*decrypt) (EVP_PKEY_CTX *ctx, +\& unsigned char *out, +\& size_t *outlen, +\& const unsigned char *in, +\& size_t inlen)); +\& void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, +\& int (*derive_init) (EVP_PKEY_CTX *ctx), +\& int (*derive) (EVP_PKEY_CTX *ctx, +\& unsigned char *key, +\& size_t *keylen)); +\& void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, +\& int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, +\& void *p2), +\& int (*ctrl_str) (EVP_PKEY_CTX *ctx, +\& const char *type, +\& const char *value)); +\& +\& void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, +\& int (**pinit) (EVP_PKEY_CTX *ctx)); +\& void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, +\& int (**pcopy) (EVP_PKEY_CTX *dst, +\& EVP_PKEY_CTX *src)); +\& void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, +\& void (**pcleanup) (EVP_PKEY_CTX *ctx)); +\& void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, +\& int (**pparamgen_init) (EVP_PKEY_CTX *ctx), +\& int (**pparamgen) (EVP_PKEY_CTX *ctx, +\& EVP_PKEY *pkey)); +\& void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, +\& int (**pkeygen_init) (EVP_PKEY_CTX *ctx), +\& int (**pkeygen) (EVP_PKEY_CTX *ctx, +\& EVP_PKEY *pkey)); +\& void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, +\& int (**psign_init) (EVP_PKEY_CTX *ctx), +\& int (**psign) (EVP_PKEY_CTX *ctx, +\& unsigned char *sig, size_t *siglen, +\& const unsigned char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, +\& int (**pverify_init) (EVP_PKEY_CTX *ctx), +\& int (**pverify) (EVP_PKEY_CTX *ctx, +\& const unsigned char *sig, +\& size_t siglen, +\& const unsigned char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, +\& int (**pverify_recover_init) (EVP_PKEY_CTX +\& *ctx), +\& int (**pverify_recover) (EVP_PKEY_CTX +\& *ctx, +\& unsigned char +\& *sig, +\& size_t *siglen, +\& const unsigned +\& char *tbs, +\& size_t tbslen)); +\& void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, +\& int (**psignctx_init) (EVP_PKEY_CTX *ctx, +\& EVP_MD_CTX *mctx), +\& int (**psignctx) (EVP_PKEY_CTX *ctx, +\& unsigned char *sig, +\& size_t *siglen, +\& EVP_MD_CTX *mctx)); +\& void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, +\& int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, +\& EVP_MD_CTX *mctx), +\& int (**pverifyctx) (EVP_PKEY_CTX *ctx, +\& const unsigned char *sig, +\& int siglen, +\& EVP_MD_CTX *mctx)); +\& void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, +\& int (**pencrypt_init) (EVP_PKEY_CTX *ctx), +\& int (**pencryptfn) (EVP_PKEY_CTX *ctx, +\& unsigned char *out, +\& size_t *outlen, +\& const unsigned char *in, +\& size_t inlen)); +\& void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, +\& int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), +\& int (**pdecrypt) (EVP_PKEY_CTX *ctx, +\& unsigned char *out, +\& size_t *outlen, +\& const unsigned char *in, +\& size_t inlen)); +\& void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, +\& int (**pderive_init) (EVP_PKEY_CTX *ctx), +\& int (**pderive) (EVP_PKEY_CTX *ctx, +\& unsigned char *key, +\& size_t *keylen)); +\& void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, +\& int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, +\& void *p2), +\& int (**pctrl_str) (EVP_PKEY_CTX *ctx, +\& const char *type, +\& const char *value)); +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fB\s-1EVP_PKEY_METHOD\s0\fR is a structure which holds a set of methods for a +specific public key cryptographic algorithm. Those methods are usually +used to perform different jobs, such as generating a key, signing or +verifying, encrypting or decrypting, etc. +.PP +There are two places where the \fB\s-1EVP_PKEY_METHOD\s0\fR objects are stored: one +is a built-in static array representing the standard methods for different +algorithms, and the other one is a stack of user-defined application-specific +methods, which can be manipulated by using \fIEVP_PKEY_meth_add0\fR\|(3). +.PP +The \fB\s-1EVP_PKEY_METHOD\s0\fR objects are usually referenced by \fB\s-1EVP_PKEY_CTX\s0\fR +objects. +.SS "Methods" +.IX Subsection "Methods" +The methods are the underlying implementations of a particular public key +algorithm present by the \fB\s-1EVP_PKEY_CTX\s0\fR object. +.PP +.Vb 3 +\& int (*init) (EVP_PKEY_CTX *ctx); +\& int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); +\& void (*cleanup) (EVP_PKEY_CTX *ctx); +.Ve +.PP +The \fIinit()\fR method is called to initialize algorithm-specific data when a new +\&\fB\s-1EVP_PKEY_CTX\s0\fR is created. As opposed to \fIinit()\fR, the \fIcleanup()\fR method is called +when an \fB\s-1EVP_PKEY_CTX\s0\fR is freed. The \fIcopy()\fR method is called when an \fB\s-1EVP_PKEY_CTX\s0\fR +is being duplicated. Refer to \fIEVP_PKEY_CTX_new\fR\|(3), \fIEVP_PKEY_CTX_new_id\fR\|(3), +\&\fIEVP_PKEY_CTX_free\fR\|(3) and \fIEVP_PKEY_CTX_dup\fR\|(3). +.PP +.Vb 2 +\& int (*paramgen_init) (EVP_PKEY_CTX *ctx); +\& int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); +.Ve +.PP +The \fIparamgen_init()\fR and \fIparamgen()\fR methods deal with key parameter generation. +They are called by \fIEVP_PKEY_paramgen_init\fR\|(3) and \fIEVP_PKEY_paramgen\fR\|(3) to +handle the parameter generation process. +.PP +.Vb 2 +\& int (*keygen_init) (EVP_PKEY_CTX *ctx); +\& int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); +.Ve +.PP +The \fIkeygen_init()\fR and \fIkeygen()\fR methods are used to generate the actual key for +the specified algorithm. They are called by \fIEVP_PKEY_keygen_init\fR\|(3) and +\&\fIEVP_PKEY_keygen\fR\|(3). +.PP +.Vb 3 +\& int (*sign_init) (EVP_PKEY_CTX *ctx); +\& int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, +\& const unsigned char *tbs, size_t tbslen); +.Ve +.PP +The \fIsign_init()\fR and \fIsign()\fR methods are used to generate the signature of a +piece of data using a private key. They are called by \fIEVP_PKEY_sign_init\fR\|(3) +and \fIEVP_PKEY_sign\fR\|(3). +.PP +.Vb 4 +\& int (*verify_init) (EVP_PKEY_CTX *ctx); +\& int (*verify) (EVP_PKEY_CTX *ctx, +\& const unsigned char *sig, size_t siglen, +\& const unsigned char *tbs, size_t tbslen); +.Ve +.PP +The \fIverify_init()\fR and \fIverify()\fR methods are used to verify whether a signature is +valid. They are called by \fIEVP_PKEY_verify_init\fR\|(3) and \fIEVP_PKEY_verify\fR\|(3). +.PP +.Vb 4 +\& int (*verify_recover_init) (EVP_PKEY_CTX *ctx); +\& int (*verify_recover) (EVP_PKEY_CTX *ctx, +\& unsigned char *rout, size_t *routlen, +\& const unsigned char *sig, size_t siglen); +.Ve +.PP +The \fIverify_recover_init()\fR and \fIverify_recover()\fR methods are used to verify a +signature and then recover the digest from the signature (for instance, a +signature that was generated by \s-1RSA\s0 signing algorithm). They are called by +\&\fIEVP_PKEY_verify_recover_init\fR\|(3) and \fIEVP_PKEY_verify_recover\fR\|(3). +.PP +.Vb 3 +\& int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); +\& int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, +\& EVP_MD_CTX *mctx); +.Ve +.PP +The \fIsignctx_init()\fR and \fIsignctx()\fR methods are used to sign a digest present by +a \fB\s-1EVP_MD_CTX\s0\fR object. They are called by the EVP_DigestSign functions. See +\&\fIEVP_DigestSignInit\fR\|(3) for detail. +.PP +.Vb 3 +\& int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); +\& int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, +\& EVP_MD_CTX *mctx); +.Ve +.PP +The \fIverifyctx_init()\fR and \fIverifyctx()\fR methods are used to verify a signature +against the data in a \fB\s-1EVP_MD_CTX\s0\fR object. They are called by the various +EVP_DigestVerify functions. See \fIEVP_DigestVerifyInit\fR\|(3) for detail. +.PP +.Vb 3 +\& int (*encrypt_init) (EVP_PKEY_CTX *ctx); +\& int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, +\& const unsigned char *in, size_t inlen); +.Ve +.PP +The \fIencrypt_init()\fR and \fIencrypt()\fR methods are used to encrypt a piece of data. +They are called by \fIEVP_PKEY_encrypt_init\fR\|(3) and \fIEVP_PKEY_encrypt\fR\|(3). +.PP +.Vb 3 +\& int (*decrypt_init) (EVP_PKEY_CTX *ctx); +\& int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, +\& const unsigned char *in, size_t inlen); +.Ve +.PP +The \fIdecrypt_init()\fR and \fIdecrypt()\fR methods are used to decrypt a piece of data. +They are called by \fIEVP_PKEY_decrypt_init\fR\|(3) and \fIEVP_PKEY_decrypt\fR\|(3). +.PP +.Vb 2 +\& int (*derive_init) (EVP_PKEY_CTX *ctx); +\& int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +.Ve +.PP +The \fIderive_init()\fR and \fIderive()\fR methods are used to derive the shared secret +from a public key algorithm (for instance, the \s-1DH\s0 algorithm). They are called by +\&\fIEVP_PKEY_derive_init\fR\|(3) and \fIEVP_PKEY_derive\fR\|(3). +.PP +.Vb 2 +\& int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); +\& int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); +.Ve +.PP +The \fIctrl()\fR and \fIctrl_str()\fR methods are used to adjust algorithm-specific +settings. See \fIEVP_PKEY_CTX_ctrl\fR\|(3) and related functions for detail. +.PP +.Vb 5 +\& int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, +\& const unsigned char *tbs, size_t tbslen); +\& int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, +\& size_t siglen, const unsigned char *tbs, +\& size_t tbslen); +.Ve +.PP +The \fIdigestsign()\fR and \fIdigestverify()\fR methods are used to generate or verify +a signature in a one-shot mode. They could be called by \fIEVP_DigetSign\fR\|(3) +and \fIEVP_DigestVerify\fR\|(3). +.SS "Functions" +.IX Subsection "Functions" +\&\fIEVP_PKEY_meth_new()\fR creates and returns a new \fB\s-1EVP_PKEY_METHOD\s0\fR object, +and associates the given \fBid\fR and \fBflags\fR. The following flags are +supported: +.PP +.Vb 2 +\& EVP_PKEY_FLAG_AUTOARGLEN +\& EVP_PKEY_FLAG_SIGCTX_CUSTOM +.Ve +.PP +If an \fB\s-1EVP_PKEY_METHOD\s0\fR is set with the \fB\s-1EVP_PKEY_FLAG_AUTOARGLEN\s0\fR flag, the +maximum size of the output buffer will be automatically calculated or checked +in corresponding \s-1EVP\s0 methods by the \s-1EVP\s0 framework. Thus the implementations of +these methods don't need to care about handling the case of returning output +buffer size by themselves. For details on the output buffer size, refer to +\&\fIEVP_PKEY_sign\fR\|(3). +.PP +The \fB\s-1EVP_PKEY_FLAG_SIGCTX_CUSTOM\s0\fR is used to indicate the \fIsignctx()\fR method +of an \fB\s-1EVP_PKEY_METHOD\s0\fR is always called by the \s-1EVP\s0 framework while doing a +digest signing operation by calling \fIEVP_DigestSignFinal\fR\|(3). +.PP +\&\fIEVP_PKEY_meth_free()\fR frees an existing \fB\s-1EVP_PKEY_METHOD\s0\fR pointed by +\&\fBpmeth\fR. +.PP +\&\fIEVP_PKEY_meth_copy()\fR copies an \fB\s-1EVP_PKEY_METHOD\s0\fR object from \fBsrc\fR +to \fBdst\fR. +.PP +\&\fIEVP_PKEY_meth_find()\fR finds an \fB\s-1EVP_PKEY_METHOD\s0\fR object with the \fBid\fR. +This function first searches through the user-defined method objects and +then the built-in objects. +.PP +\&\fIEVP_PKEY_meth_add0()\fR adds \fBpmeth\fR to the user defined stack of methods. +.PP +The EVP_PKEY_meth_set functions set the corresponding fields of +\&\fB\s-1EVP_PKEY_METHOD\s0\fR structure with the arguments passed. +.PP +The EVP_PKEY_meth_get functions get the corresponding fields of +\&\fB\s-1EVP_PKEY_METHOD\s0\fR structure to the arguments provided. +.SH "RETURN VALUES" +.IX Header "RETURN VALUES" +\&\fIEVP_PKEY_meth_new()\fR returns a pointer to a new \fB\s-1EVP_PKEY_METHOD\s0\fR +object or returns \s-1NULL\s0 on error. +.PP +\&\fIEVP_PKEY_meth_free()\fR and \fIEVP_PKEY_meth_copy()\fR do not return values. +.PP +\&\fIEVP_PKEY_meth_find()\fR returns a pointer to the found \fB\s-1EVP_PKEY_METHOD\s0\fR +object or returns \s-1NULL\s0 if not found. +.PP +\&\fIEVP_PKEY_meth_add0()\fR returns 1 if method is added successfully or 0 +if an error occurred. +.PP +All EVP_PKEY_meth_set and EVP_PKEY_meth_get functions have no return +values. For the 'get' functions, function pointers are returned by +arguments. +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +.PP +Licensed under the OpenSSL license (the \*(L"License\*(R"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file \s-1LICENSE\s0 in the source distribution or at +. diff --git a/secure/lib/libcrypto/man/EVP_PKEY_new.3 b/secure/lib/libcrypto/man/EVP_PKEY_new.3 index 624ff333da95..15bc41a63aa6 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_new.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_new 3" -.TH EVP_PKEY_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_print_private.3 b/secure/lib/libcrypto/man/EVP_PKEY_print_private.3 index 63f4cb9fd657..549d0105f167 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_print_private.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_print_private.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_print_private 3" -.TH EVP_PKEY_print_private 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_print_private 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 index 699e4d57412c..7a06a96866d5 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_set1_RSA 3" -.TH EVP_PKEY_set1_RSA 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_set1_RSA 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_sign.3 b/secure/lib/libcrypto/man/EVP_PKEY_sign.3 index 72335e8e1573..26c906655300 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_sign.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_sign 3" -.TH EVP_PKEY_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_verify.3 b/secure/lib/libcrypto/man/EVP_PKEY_verify.3 index 39beb4f44358..371659e56a30 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_verify.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_verify.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_verify 3" -.TH EVP_PKEY_verify 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_verify 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_PKEY_verify_recover.3 b/secure/lib/libcrypto/man/EVP_PKEY_verify_recover.3 index 42fbd8067818..915d31698771 100644 --- a/secure/lib/libcrypto/man/EVP_PKEY_verify_recover.3 +++ b/secure/lib/libcrypto/man/EVP_PKEY_verify_recover.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_PKEY_verify_recover 3" -.TH EVP_PKEY_verify_recover 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_PKEY_verify_recover 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_SealInit.3 b/secure/lib/libcrypto/man/EVP_SealInit.3 index 592ed76e3818..bbdd02e24358 100644 --- a/secure/lib/libcrypto/man/EVP_SealInit.3 +++ b/secure/lib/libcrypto/man/EVP_SealInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_SealInit 3" -.TH EVP_SealInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_SealInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_SignInit.3 b/secure/lib/libcrypto/man/EVP_SignInit.3 index c93324b56be1..0bcea9d468ae 100644 --- a/secure/lib/libcrypto/man/EVP_SignInit.3 +++ b/secure/lib/libcrypto/man/EVP_SignInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_SignInit 3" -.TH EVP_SignInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_SignInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/EVP_VerifyInit.3 b/secure/lib/libcrypto/man/EVP_VerifyInit.3 index 21b61c056ac1..defa1ae917a3 100644 --- a/secure/lib/libcrypto/man/EVP_VerifyInit.3 +++ b/secure/lib/libcrypto/man/EVP_VerifyInit.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EVP_VerifyInit 3" -.TH EVP_VerifyInit 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EVP_VerifyInit 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OBJ_nid2obj.3 b/secure/lib/libcrypto/man/OBJ_nid2obj.3 index 8b4d549de978..1d770852f41b 100644 --- a/secure/lib/libcrypto/man/OBJ_nid2obj.3 +++ b/secure/lib/libcrypto/man/OBJ_nid2obj.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OBJ_nid2obj 3" -.TH OBJ_nid2obj 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OBJ_nid2obj 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_Applink.3 b/secure/lib/libcrypto/man/OPENSSL_Applink.3 index 0ef13a7da95e..717f26732af2 100644 --- a/secure/lib/libcrypto/man/OPENSSL_Applink.3 +++ b/secure/lib/libcrypto/man/OPENSSL_Applink.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_Applink 3" -.TH OPENSSL_Applink 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_Applink 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 index 72186e614a63..823c8d3c1255 100644 --- a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 +++ b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_VERSION_NUMBER 3" -.TH OPENSSL_VERSION_NUMBER 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_VERSION_NUMBER 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_config.3 b/secure/lib/libcrypto/man/OPENSSL_config.3 index 531d85a9ae0e..39c89915585d 100644 --- a/secure/lib/libcrypto/man/OPENSSL_config.3 +++ b/secure/lib/libcrypto/man/OPENSSL_config.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_config 3" -.TH OPENSSL_config 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_config 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 index 249fdcac2d3c..6212a3ab15f9 100644 --- a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 +++ b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_ia32cap 3" -.TH OPENSSL_ia32cap 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_ia32cap 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_instrument_bus.3 b/secure/lib/libcrypto/man/OPENSSL_instrument_bus.3 index 58263827fc01..60e0c04db79c 100644 --- a/secure/lib/libcrypto/man/OPENSSL_instrument_bus.3 +++ b/secure/lib/libcrypto/man/OPENSSL_instrument_bus.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_instrument_bus 3" -.TH OPENSSL_instrument_bus 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_instrument_bus 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 index cffe62b7a5a3..84a9bed63592 100644 --- a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 +++ b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL_load_builtin_modules 3" -.TH OPENSSL_load_builtin_modules 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL_load_builtin_modules 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 index 1adb654ba9f2..a33df960676b 100644 --- a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 +++ b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OpenSSL_add_all_algorithms 3" -.TH OpenSSL_add_all_algorithms 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OpenSSL_add_all_algorithms 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PEM_write_bio_CMS_stream.3 b/secure/lib/libcrypto/man/PEM_write_bio_CMS_stream.3 index b5a2633aff0e..248256efddf8 100644 --- a/secure/lib/libcrypto/man/PEM_write_bio_CMS_stream.3 +++ b/secure/lib/libcrypto/man/PEM_write_bio_CMS_stream.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PEM_write_bio_CMS_stream 3" -.TH PEM_write_bio_CMS_stream 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PEM_write_bio_CMS_stream 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3 b/secure/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3 index 932f92c5b3ff..24a019da7203 100644 --- a/secure/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3 +++ b/secure/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PEM_write_bio_PKCS7_stream 3" -.TH PEM_write_bio_PKCS7_stream 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PEM_write_bio_PKCS7_stream 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS12_create.3 b/secure/lib/libcrypto/man/PKCS12_create.3 index 3d7fa02921bf..46244616fb4d 100644 --- a/secure/lib/libcrypto/man/PKCS12_create.3 +++ b/secure/lib/libcrypto/man/PKCS12_create.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS12_create 3" -.TH PKCS12_create 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS12_create 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS12_parse.3 b/secure/lib/libcrypto/man/PKCS12_parse.3 index bf57ac55ffdd..b5d5ffd174ee 100644 --- a/secure/lib/libcrypto/man/PKCS12_parse.3 +++ b/secure/lib/libcrypto/man/PKCS12_parse.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS12_parse 3" -.TH PKCS12_parse 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS12_parse 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS7_decrypt.3 b/secure/lib/libcrypto/man/PKCS7_decrypt.3 index 53a365eba521..01cf45537183 100644 --- a/secure/lib/libcrypto/man/PKCS7_decrypt.3 +++ b/secure/lib/libcrypto/man/PKCS7_decrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS7_decrypt 3" -.TH PKCS7_decrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7_decrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS7_encrypt.3 b/secure/lib/libcrypto/man/PKCS7_encrypt.3 index 151395d3f2f3..5294f968e12b 100644 --- a/secure/lib/libcrypto/man/PKCS7_encrypt.3 +++ b/secure/lib/libcrypto/man/PKCS7_encrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS7_encrypt 3" -.TH PKCS7_encrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7_encrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS7_sign.3 b/secure/lib/libcrypto/man/PKCS7_sign.3 index ab463e401c9a..902065b160e7 100644 --- a/secure/lib/libcrypto/man/PKCS7_sign.3 +++ b/secure/lib/libcrypto/man/PKCS7_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS7_sign 3" -.TH PKCS7_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS7_sign_add_signer.3 b/secure/lib/libcrypto/man/PKCS7_sign_add_signer.3 index 6882ea2eadb4..043c2eb17863 100644 --- a/secure/lib/libcrypto/man/PKCS7_sign_add_signer.3 +++ b/secure/lib/libcrypto/man/PKCS7_sign_add_signer.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS7_sign_add_signer 3" -.TH PKCS7_sign_add_signer 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7_sign_add_signer 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/PKCS7_verify.3 b/secure/lib/libcrypto/man/PKCS7_verify.3 index ba8f4e5fcc46..d2e26653550f 100644 --- a/secure/lib/libcrypto/man/PKCS7_verify.3 +++ b/secure/lib/libcrypto/man/PKCS7_verify.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "PKCS7_verify 3" -.TH PKCS7_verify 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7_verify 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_add.3 b/secure/lib/libcrypto/man/RAND_add.3 index 33cc6502dcea..a6b217454916 100644 --- a/secure/lib/libcrypto/man/RAND_add.3 +++ b/secure/lib/libcrypto/man/RAND_add.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_add 3" -.TH RAND_add 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_add 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_bytes.3 b/secure/lib/libcrypto/man/RAND_bytes.3 index 52b4de3ecb1c..7042c724b2ea 100644 --- a/secure/lib/libcrypto/man/RAND_bytes.3 +++ b/secure/lib/libcrypto/man/RAND_bytes.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_bytes 3" -.TH RAND_bytes 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_bytes 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_cleanup.3 b/secure/lib/libcrypto/man/RAND_cleanup.3 index 8658f96b6844..fd0a1822ebc5 100644 --- a/secure/lib/libcrypto/man/RAND_cleanup.3 +++ b/secure/lib/libcrypto/man/RAND_cleanup.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_cleanup 3" -.TH RAND_cleanup 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_cleanup 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_egd.3 b/secure/lib/libcrypto/man/RAND_egd.3 index 7f0b89dccc96..9e454947b0de 100644 --- a/secure/lib/libcrypto/man/RAND_egd.3 +++ b/secure/lib/libcrypto/man/RAND_egd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_egd 3" -.TH RAND_egd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_egd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_load_file.3 b/secure/lib/libcrypto/man/RAND_load_file.3 index 90270d270b88..27e4cfb29bfc 100644 --- a/secure/lib/libcrypto/man/RAND_load_file.3 +++ b/secure/lib/libcrypto/man/RAND_load_file.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_load_file 3" -.TH RAND_load_file 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_load_file 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RAND_set_rand_method.3 b/secure/lib/libcrypto/man/RAND_set_rand_method.3 index fa148f1082c9..f4e2004db746 100644 --- a/secure/lib/libcrypto/man/RAND_set_rand_method.3 +++ b/secure/lib/libcrypto/man/RAND_set_rand_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RAND_set_rand_method 3" -.TH RAND_set_rand_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND_set_rand_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_blinding_on.3 b/secure/lib/libcrypto/man/RSA_blinding_on.3 index dbd9a1932546..070648eb8658 100644 --- a/secure/lib/libcrypto/man/RSA_blinding_on.3 +++ b/secure/lib/libcrypto/man/RSA_blinding_on.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_blinding_on 3" -.TH RSA_blinding_on 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_blinding_on 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_check_key.3 b/secure/lib/libcrypto/man/RSA_check_key.3 index d889874c9184..8d1d487a0b72 100644 --- a/secure/lib/libcrypto/man/RSA_check_key.3 +++ b/secure/lib/libcrypto/man/RSA_check_key.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_check_key 3" -.TH RSA_check_key 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_check_key 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_generate_key.3 b/secure/lib/libcrypto/man/RSA_generate_key.3 index 27b41fdeb6bf..4f5933230d44 100644 --- a/secure/lib/libcrypto/man/RSA_generate_key.3 +++ b/secure/lib/libcrypto/man/RSA_generate_key.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_generate_key 3" -.TH RSA_generate_key 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_generate_key 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 index 5167b4051798..708f6c1780bb 100644 --- a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 +++ b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_get_ex_new_index 3" -.TH RSA_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_new.3 b/secure/lib/libcrypto/man/RSA_new.3 index 2f2a156153e9..3f533fca1bcf 100644 --- a/secure/lib/libcrypto/man/RSA_new.3 +++ b/secure/lib/libcrypto/man/RSA_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_new 3" -.TH RSA_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 index da8d9997b661..deabd55e991b 100644 --- a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 +++ b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_padding_add_PKCS1_type_1 3" -.TH RSA_padding_add_PKCS1_type_1 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_padding_add_PKCS1_type_1 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -226,6 +226,12 @@ The \fIRSA_padding_add_xxx()\fR functions return 1 on success, 0 on error. The \fIRSA_padding_check_xxx()\fR functions return the length of the recovered data, \-1 on error. Error codes can be obtained by calling \&\fIERR_get_error\fR\|(3). +.SH "WARNING" +.IX Header "WARNING" +The \fIRSA_padding_check_PKCS1_type_2()\fR padding check leaks timing +information which can potentially be used to mount a Bleichenbacher +padding oracle attack. This is an inherent weakness in the \s-1PKCS\s0 #1 +v1.5 padding design. Prefer \s-1PKCS1_OAEP\s0 padding. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIRSA_public_encrypt\fR\|(3), diff --git a/secure/lib/libcrypto/man/RSA_print.3 b/secure/lib/libcrypto/man/RSA_print.3 index 238392f582c8..9c0e2423d082 100644 --- a/secure/lib/libcrypto/man/RSA_print.3 +++ b/secure/lib/libcrypto/man/RSA_print.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_print 3" -.TH RSA_print 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_print 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_private_encrypt.3 b/secure/lib/libcrypto/man/RSA_private_encrypt.3 index 6d35b042d9c4..cbe20c0779f2 100644 --- a/secure/lib/libcrypto/man/RSA_private_encrypt.3 +++ b/secure/lib/libcrypto/man/RSA_private_encrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_private_encrypt 3" -.TH RSA_private_encrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_private_encrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_public_encrypt.3 b/secure/lib/libcrypto/man/RSA_public_encrypt.3 index df118db5fb1d..31649b5b5b93 100644 --- a/secure/lib/libcrypto/man/RSA_public_encrypt.3 +++ b/secure/lib/libcrypto/man/RSA_public_encrypt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_public_encrypt 3" -.TH RSA_public_encrypt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_public_encrypt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -190,6 +190,12 @@ recovered plaintext. .PP On error, \-1 is returned; the error codes can be obtained by \fIERR_get_error\fR\|(3). +.SH "WARNING" +.IX Header "WARNING" +Decryption failures in the \s-1RSA_PKCS1_PADDING\s0 mode leak information +which can potentially be used to mount a Bleichenbacher padding oracle +attack. This is an inherent weakness in the \s-1PKCS\s0 #1 v1.5 padding +design. Prefer \s-1RSA_PKCS1_OAEP_PADDING.\s0 .SH "CONFORMING TO" .IX Header "CONFORMING TO" \&\s-1SSL, PKCS\s0 #1 v2.0 diff --git a/secure/lib/libcrypto/man/RSA_set_method.3 b/secure/lib/libcrypto/man/RSA_set_method.3 index a0a063d8e779..9d40a5a0af0c 100644 --- a/secure/lib/libcrypto/man/RSA_set_method.3 +++ b/secure/lib/libcrypto/man/RSA_set_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_set_method 3" -.TH RSA_set_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_set_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_sign.3 b/secure/lib/libcrypto/man/RSA_sign.3 index 8459cff99219..3c7b836aff3f 100644 --- a/secure/lib/libcrypto/man/RSA_sign.3 +++ b/secure/lib/libcrypto/man/RSA_sign.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_sign 3" -.TH RSA_sign 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_sign 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 index f918a47c1469..8c5e0612742d 100644 --- a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 +++ b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_sign_ASN1_OCTET_STRING 3" -.TH RSA_sign_ASN1_OCTET_STRING 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_sign_ASN1_OCTET_STRING 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/RSA_size.3 b/secure/lib/libcrypto/man/RSA_size.3 index 50b111cf7ec0..c9b984fe8af7 100644 --- a/secure/lib/libcrypto/man/RSA_size.3 +++ b/secure/lib/libcrypto/man/RSA_size.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RSA_size 3" -.TH RSA_size 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA_size 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/SMIME_read_CMS.3 b/secure/lib/libcrypto/man/SMIME_read_CMS.3 index 9e75aeddd0d3..3d7eb19d04cc 100644 --- a/secure/lib/libcrypto/man/SMIME_read_CMS.3 +++ b/secure/lib/libcrypto/man/SMIME_read_CMS.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SMIME_read_CMS 3" -.TH SMIME_read_CMS 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SMIME_read_CMS 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 index 3c94d4fed607..a3592c1211b5 100644 --- a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 +++ b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SMIME_read_PKCS7 3" -.TH SMIME_read_PKCS7 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SMIME_read_PKCS7 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/SMIME_write_CMS.3 b/secure/lib/libcrypto/man/SMIME_write_CMS.3 index cc4075bf9d92..fc71b2808cbd 100644 --- a/secure/lib/libcrypto/man/SMIME_write_CMS.3 +++ b/secure/lib/libcrypto/man/SMIME_write_CMS.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SMIME_write_CMS 3" -.TH SMIME_write_CMS 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SMIME_write_CMS 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 index 390481dc9cbb..a7ce4e2a1158 100644 --- a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 +++ b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SMIME_write_PKCS7 3" -.TH SMIME_write_PKCS7 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SMIME_write_PKCS7 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 index 3d6b1dfefbdb..76b5c4c30030 100644 --- a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 +++ b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_NAME_ENTRY_get_object 3" -.TH X509_NAME_ENTRY_get_object 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_NAME_ENTRY_get_object 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 index 74d8f0c61af4..073ac5f62ff0 100644 --- a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 +++ b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_NAME_add_entry_by_txt 3" -.TH X509_NAME_add_entry_by_txt 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_NAME_add_entry_by_txt 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 index 98f00641893e..787af84f6f69 100644 --- a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 +++ b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_NAME_get_index_by_NID 3" -.TH X509_NAME_get_index_by_NID 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_NAME_get_index_by_NID 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_NAME_print_ex.3 b/secure/lib/libcrypto/man/X509_NAME_print_ex.3 index 8dfdbe68dfbf..4a97d9edb9cf 100644 --- a/secure/lib/libcrypto/man/X509_NAME_print_ex.3 +++ b/secure/lib/libcrypto/man/X509_NAME_print_ex.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_NAME_print_ex 3" -.TH X509_NAME_print_ex 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_NAME_print_ex 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_STORE_CTX_get_error.3 b/secure/lib/libcrypto/man/X509_STORE_CTX_get_error.3 index 8ac8dcd15aad..3e0674719d84 100644 --- a/secure/lib/libcrypto/man/X509_STORE_CTX_get_error.3 +++ b/secure/lib/libcrypto/man/X509_STORE_CTX_get_error.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_STORE_CTX_get_error 3" -.TH X509_STORE_CTX_get_error 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_STORE_CTX_get_error 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_STORE_CTX_get_ex_new_index.3 b/secure/lib/libcrypto/man/X509_STORE_CTX_get_ex_new_index.3 index 02cd80a03e49..e26f2f7345ba 100644 --- a/secure/lib/libcrypto/man/X509_STORE_CTX_get_ex_new_index.3 +++ b/secure/lib/libcrypto/man/X509_STORE_CTX_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_STORE_CTX_get_ex_new_index 3" -.TH X509_STORE_CTX_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_STORE_CTX_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_STORE_CTX_new.3 b/secure/lib/libcrypto/man/X509_STORE_CTX_new.3 index 0d7dcf59319a..815e30a83e1d 100644 --- a/secure/lib/libcrypto/man/X509_STORE_CTX_new.3 +++ b/secure/lib/libcrypto/man/X509_STORE_CTX_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_STORE_CTX_new 3" -.TH X509_STORE_CTX_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_STORE_CTX_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_STORE_CTX_set_verify_cb.3 b/secure/lib/libcrypto/man/X509_STORE_CTX_set_verify_cb.3 index edfe8867211d..d96a9319f76d 100644 --- a/secure/lib/libcrypto/man/X509_STORE_CTX_set_verify_cb.3 +++ b/secure/lib/libcrypto/man/X509_STORE_CTX_set_verify_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_STORE_CTX_set_verify_cb 3" -.TH X509_STORE_CTX_set_verify_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_STORE_CTX_set_verify_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_STORE_set_verify_cb_func.3 b/secure/lib/libcrypto/man/X509_STORE_set_verify_cb_func.3 index 428b558233d1..0fb91d502a24 100644 --- a/secure/lib/libcrypto/man/X509_STORE_set_verify_cb_func.3 +++ b/secure/lib/libcrypto/man/X509_STORE_set_verify_cb_func.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_STORE_set_verify_cb_func 3" -.TH X509_STORE_set_verify_cb_func 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_STORE_set_verify_cb_func 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_VERIFY_PARAM_set_flags.3 b/secure/lib/libcrypto/man/X509_VERIFY_PARAM_set_flags.3 index fba0b78471c6..85c7a2141279 100644 --- a/secure/lib/libcrypto/man/X509_VERIFY_PARAM_set_flags.3 +++ b/secure/lib/libcrypto/man/X509_VERIFY_PARAM_set_flags.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_VERIFY_PARAM_set_flags 3" -.TH X509_VERIFY_PARAM_set_flags 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_VERIFY_PARAM_set_flags 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_check_host.3 b/secure/lib/libcrypto/man/X509_check_host.3 index a9169f519585..32f902ca1c88 100644 --- a/secure/lib/libcrypto/man/X509_check_host.3 +++ b/secure/lib/libcrypto/man/X509_check_host.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_check_host 3" -.TH X509_check_host 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_check_host 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_check_private_key.3 b/secure/lib/libcrypto/man/X509_check_private_key.3 new file mode 100644 index 000000000000..4c9929558593 --- /dev/null +++ b/secure/lib/libcrypto/man/X509_check_private_key.3 @@ -0,0 +1,181 @@ +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "X509_check_private_key 3" +.TH X509_check_private_key 3 "2017-11-02" "1.0.2m" "OpenSSL" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +X509_check_private_key, X509_REQ_check_private_key \- check the consistency +of a private key with the public key in an X509 certificate or certificate +request +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& #include +\& +\& int X509_check_private_key(X509 *x, EVP_PKEY *k); +\& +\& int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k); +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fIX509_check_private_key()\fR function checks the consistency of private +key \fBk\fR with the public key in \fBx\fR. +.PP +\&\fIX509_REQ_check_private_key()\fR is equivalent to \fIX509_check_private_key()\fR +except that \fBx\fR represents a certificate request of structure \fBX509_REQ\fR. +.SH "RETURN VALUE" +.IX Header "RETURN VALUE" +\&\fIX509_check_private_key()\fR and \fIX509_REQ_check_private_key()\fR return 1 if +the keys match each other, and 0 if not. +.PP +If the key is invalid or an error occurred, the reason code can be +obtained using \fIERR_get_error\fR\|(3). +.SH "BUGS" +.IX Header "BUGS" +The \fBcheck_private_key\fR functions don't check if \fBk\fR itself is indeed +a private key or not. It merely compares the public materials (e.g. exponent +and modulus of an \s-1RSA\s0 key) and/or key parameters (e.g. \s-1EC\s0 params of an \s-1EC\s0 key) +of a key pair. So if you pass a public key to these functions in \fBk\fR, it will +return success. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fIERR_get_error\fR\|(3) +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +.PP +Licensed under the OpenSSL license (the \*(L"License\*(R"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file \s-1LICENSE\s0 in the source distribution or at +. diff --git a/secure/lib/libcrypto/man/X509_new.3 b/secure/lib/libcrypto/man/X509_new.3 index 920f76d62bf5..6555891679b8 100644 --- a/secure/lib/libcrypto/man/X509_new.3 +++ b/secure/lib/libcrypto/man/X509_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_new 3" -.TH X509_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/X509_verify_cert.3 b/secure/lib/libcrypto/man/X509_verify_cert.3 index c87a93bfd0e1..259d32eaefb9 100644 --- a/secure/lib/libcrypto/man/X509_verify_cert.3 +++ b/secure/lib/libcrypto/man/X509_verify_cert.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509_verify_cert 3" -.TH X509_verify_cert 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509_verify_cert 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/bio.3 b/secure/lib/libcrypto/man/bio.3 index a4ef456b8358..c88c60ec7f70 100644 --- a/secure/lib/libcrypto/man/bio.3 +++ b/secure/lib/libcrypto/man/bio.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "bio 3" -.TH bio 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH bio 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/blowfish.3 b/secure/lib/libcrypto/man/blowfish.3 index e642203d8649..dc2e88f5b035 100644 --- a/secure/lib/libcrypto/man/blowfish.3 +++ b/secure/lib/libcrypto/man/blowfish.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "blowfish 3" -.TH blowfish 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH blowfish 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/bn.3 b/secure/lib/libcrypto/man/bn.3 index 8fa42f2b17c7..63869687a758 100644 --- a/secure/lib/libcrypto/man/bn.3 +++ b/secure/lib/libcrypto/man/bn.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "bn 3" -.TH bn 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH bn 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/bn_internal.3 b/secure/lib/libcrypto/man/bn_internal.3 index d503afb8a22d..57deeccb14da 100644 --- a/secure/lib/libcrypto/man/bn_internal.3 +++ b/secure/lib/libcrypto/man/bn_internal.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "bn_internal 3" -.TH bn_internal 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH bn_internal 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/buffer.3 b/secure/lib/libcrypto/man/buffer.3 index 180157d010cf..51d2b256951f 100644 --- a/secure/lib/libcrypto/man/buffer.3 +++ b/secure/lib/libcrypto/man/buffer.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "buffer 3" -.TH buffer 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH buffer 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/crypto.3 b/secure/lib/libcrypto/man/crypto.3 index db288d024ee6..828b4d2a71be 100644 --- a/secure/lib/libcrypto/man/crypto.3 +++ b/secure/lib/libcrypto/man/crypto.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "crypto 3" -.TH crypto 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH crypto 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 index 06f0bcd0bbec..95e8e9f8993c 100644 --- a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 +++ b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_ASN1_OBJECT 3" -.TH d2i_ASN1_OBJECT 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_ASN1_OBJECT 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_CMS_ContentInfo.3 b/secure/lib/libcrypto/man/d2i_CMS_ContentInfo.3 index 4cd4a0df8616..44fe52a301fd 100644 --- a/secure/lib/libcrypto/man/d2i_CMS_ContentInfo.3 +++ b/secure/lib/libcrypto/man/d2i_CMS_ContentInfo.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_CMS_ContentInfo 3" -.TH d2i_CMS_ContentInfo 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_CMS_ContentInfo 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_DHparams.3 b/secure/lib/libcrypto/man/d2i_DHparams.3 index 5d76a0133c9c..5f166e626ca3 100644 --- a/secure/lib/libcrypto/man/d2i_DHparams.3 +++ b/secure/lib/libcrypto/man/d2i_DHparams.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_DHparams 3" -.TH d2i_DHparams 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_DHparams 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 index 191496ef4a0f..3f58eae165d4 100644 --- a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 +++ b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_DSAPublicKey 3" -.TH d2i_DSAPublicKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_DSAPublicKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_ECPKParameters.3 b/secure/lib/libcrypto/man/d2i_ECPKParameters.3 index 7befafa86280..7574743a99e9 100644 --- a/secure/lib/libcrypto/man/d2i_ECPKParameters.3 +++ b/secure/lib/libcrypto/man/d2i_ECPKParameters.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_ECPKParameters 3" -.TH d2i_ECPKParameters 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_ECPKParameters 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_ECPrivateKey.3 b/secure/lib/libcrypto/man/d2i_ECPrivateKey.3 index 77c3f5a9be5c..43e6e1fd7dd4 100644 --- a/secure/lib/libcrypto/man/d2i_ECPrivateKey.3 +++ b/secure/lib/libcrypto/man/d2i_ECPrivateKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_ECPrivateKey 3" -.TH d2i_ECPrivateKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_ECPrivateKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 index f9eb0c6b1240..f7467c2daebb 100644 --- a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 +++ b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_PKCS8PrivateKey 3" -.TH d2i_PKCS8PrivateKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_PKCS8PrivateKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_PrivateKey.3 b/secure/lib/libcrypto/man/d2i_PrivateKey.3 index 51bc904dbeac..7b824872b568 100644 --- a/secure/lib/libcrypto/man/d2i_PrivateKey.3 +++ b/secure/lib/libcrypto/man/d2i_PrivateKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_PrivateKey 3" -.TH d2i_PrivateKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_PrivateKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 index d9ef62ad0379..ea929f8f339c 100644 --- a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 +++ b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_RSAPublicKey 3" -.TH d2i_RSAPublicKey 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_RSAPublicKey 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509.3 b/secure/lib/libcrypto/man/d2i_X509.3 index d24b1859a861..c4339fe0ec3a 100644 --- a/secure/lib/libcrypto/man/d2i_X509.3 +++ b/secure/lib/libcrypto/man/d2i_X509.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509 3" -.TH d2i_X509 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 index 8796133b333f..0737a63d6975 100644 --- a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 +++ b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509_ALGOR 3" -.TH d2i_X509_ALGOR 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509_ALGOR 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509_CRL.3 b/secure/lib/libcrypto/man/d2i_X509_CRL.3 index 18ae2b73ee9a..4ce70419afe2 100644 --- a/secure/lib/libcrypto/man/d2i_X509_CRL.3 +++ b/secure/lib/libcrypto/man/d2i_X509_CRL.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509_CRL 3" -.TH d2i_X509_CRL 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509_CRL 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509_NAME.3 b/secure/lib/libcrypto/man/d2i_X509_NAME.3 index 5aa4d25f45f1..cf1edddf3e9b 100644 --- a/secure/lib/libcrypto/man/d2i_X509_NAME.3 +++ b/secure/lib/libcrypto/man/d2i_X509_NAME.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509_NAME 3" -.TH d2i_X509_NAME 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509_NAME 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509_REQ.3 b/secure/lib/libcrypto/man/d2i_X509_REQ.3 index 5e1f907a5a40..12b14c4f9826 100644 --- a/secure/lib/libcrypto/man/d2i_X509_REQ.3 +++ b/secure/lib/libcrypto/man/d2i_X509_REQ.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509_REQ 3" -.TH d2i_X509_REQ 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509_REQ 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/d2i_X509_SIG.3 b/secure/lib/libcrypto/man/d2i_X509_SIG.3 index f7e6e77e8174..ed03082eda32 100644 --- a/secure/lib/libcrypto/man/d2i_X509_SIG.3 +++ b/secure/lib/libcrypto/man/d2i_X509_SIG.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_X509_SIG 3" -.TH d2i_X509_SIG 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_X509_SIG 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/des.3 b/secure/lib/libcrypto/man/des.3 index f5a6157906db..53d3eeec5ba0 100644 --- a/secure/lib/libcrypto/man/des.3 +++ b/secure/lib/libcrypto/man/des.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "des 3" -.TH des 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH des 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/dh.3 b/secure/lib/libcrypto/man/dh.3 index e8df5f3b88e6..c67fe2ee68b5 100644 --- a/secure/lib/libcrypto/man/dh.3 +++ b/secure/lib/libcrypto/man/dh.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "dh 3" -.TH dh 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH dh 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/dsa.3 b/secure/lib/libcrypto/man/dsa.3 index 8ff605fc61c3..dad3b657f17c 100644 --- a/secure/lib/libcrypto/man/dsa.3 +++ b/secure/lib/libcrypto/man/dsa.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "dsa 3" -.TH dsa 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH dsa 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ec.3 b/secure/lib/libcrypto/man/ec.3 index 9bc520549e59..fd9914682b1c 100644 --- a/secure/lib/libcrypto/man/ec.3 +++ b/secure/lib/libcrypto/man/ec.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ec 3" -.TH ec 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ec 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ecdsa.3 b/secure/lib/libcrypto/man/ecdsa.3 index a72b21513a19..c39def5b3466 100644 --- a/secure/lib/libcrypto/man/ecdsa.3 +++ b/secure/lib/libcrypto/man/ecdsa.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ecdsa 3" -.TH ecdsa 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ecdsa 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/engine.3 b/secure/lib/libcrypto/man/engine.3 index 846de1955a32..1f6af9dce2a6 100644 --- a/secure/lib/libcrypto/man/engine.3 +++ b/secure/lib/libcrypto/man/engine.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "engine 3" -.TH engine 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH engine 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/err.3 b/secure/lib/libcrypto/man/err.3 index 010be67a5850..359538fbdaef 100644 --- a/secure/lib/libcrypto/man/err.3 +++ b/secure/lib/libcrypto/man/err.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "err 3" -.TH err 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH err 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/evp.3 b/secure/lib/libcrypto/man/evp.3 index 081e1c1a90c2..74f73a1fe630 100644 --- a/secure/lib/libcrypto/man/evp.3 +++ b/secure/lib/libcrypto/man/evp.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "evp 3" -.TH evp 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH evp 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/hmac.3 b/secure/lib/libcrypto/man/hmac.3 index 03f6a9889f85..05621cc50fa7 100644 --- a/secure/lib/libcrypto/man/hmac.3 +++ b/secure/lib/libcrypto/man/hmac.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "hmac 3" -.TH hmac 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH hmac 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -171,7 +171,8 @@ function. It places the result in \fBmd\fR (which must have space for the output of the hash function, which is no more than \fB\s-1EVP_MAX_MD_SIZE\s0\fR bytes). If \fBmd\fR is \s-1NULL,\s0 the digest is placed in a static array. The size of -the output is placed in \fBmd_len\fR, unless it is \fB\s-1NULL\s0\fR. +the output is placed in \fBmd_len\fR, unless it is \fB\s-1NULL\s0\fR. Note: passing a \s-1NULL\s0 +value for \fBmd\fR to use the static array is not thread safe. .PP \&\fBevp_md\fR can be \fIEVP_sha1()\fR, \fIEVP_ripemd160()\fR etc. .PP diff --git a/secure/lib/libcrypto/man/i2d_CMS_bio_stream.3 b/secure/lib/libcrypto/man/i2d_CMS_bio_stream.3 index dcd9299e04c1..3026c3d3d2c0 100644 --- a/secure/lib/libcrypto/man/i2d_CMS_bio_stream.3 +++ b/secure/lib/libcrypto/man/i2d_CMS_bio_stream.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "i2d_CMS_bio_stream 3" -.TH i2d_CMS_bio_stream 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH i2d_CMS_bio_stream 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 b/secure/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 index 7eef3d506d9d..2372be1e383e 100644 --- a/secure/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 +++ b/secure/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "i2d_PKCS7_bio_stream 3" -.TH i2d_PKCS7_bio_stream 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH i2d_PKCS7_bio_stream 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/lh_stats.3 b/secure/lib/libcrypto/man/lh_stats.3 index 3a25a52a1c91..ac3e8e6e502c 100644 --- a/secure/lib/libcrypto/man/lh_stats.3 +++ b/secure/lib/libcrypto/man/lh_stats.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "lh_stats 3" -.TH lh_stats 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH lh_stats 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/lhash.3 b/secure/lib/libcrypto/man/lhash.3 index 02e333186dbb..c870229ddd92 100644 --- a/secure/lib/libcrypto/man/lhash.3 +++ b/secure/lib/libcrypto/man/lhash.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "lhash 3" -.TH lhash 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH lhash 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/md5.3 b/secure/lib/libcrypto/man/md5.3 index d9c8ab448f5a..aec67b2176ec 100644 --- a/secure/lib/libcrypto/man/md5.3 +++ b/secure/lib/libcrypto/man/md5.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "md5 3" -.TH md5 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH md5 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/mdc2.3 b/secure/lib/libcrypto/man/mdc2.3 index 56ea7e312000..8d4505eebf2b 100644 --- a/secure/lib/libcrypto/man/mdc2.3 +++ b/secure/lib/libcrypto/man/mdc2.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "mdc2 3" -.TH mdc2 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH mdc2 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/pem.3 b/secure/lib/libcrypto/man/pem.3 index ee832670fbd5..52e4a1ddf0ca 100644 --- a/secure/lib/libcrypto/man/pem.3 +++ b/secure/lib/libcrypto/man/pem.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "pem 3" -.TH pem 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH pem 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/rand.3 b/secure/lib/libcrypto/man/rand.3 index 24cb6e5c4a07..bcd1618bd637 100644 --- a/secure/lib/libcrypto/man/rand.3 +++ b/secure/lib/libcrypto/man/rand.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "rand 3" -.TH rand 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH rand 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/rc4.3 b/secure/lib/libcrypto/man/rc4.3 index f273a0bf15e9..8a4813b7e329 100644 --- a/secure/lib/libcrypto/man/rc4.3 +++ b/secure/lib/libcrypto/man/rc4.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "rc4 3" -.TH rc4 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH rc4 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ripemd.3 b/secure/lib/libcrypto/man/ripemd.3 index 5b7f9ac5f3f3..f3f69fc9b960 100644 --- a/secure/lib/libcrypto/man/ripemd.3 +++ b/secure/lib/libcrypto/man/ripemd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ripemd 3" -.TH ripemd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ripemd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/rsa.3 b/secure/lib/libcrypto/man/rsa.3 index 35fcb2d8e4e9..d5f337a59b08 100644 --- a/secure/lib/libcrypto/man/rsa.3 +++ b/secure/lib/libcrypto/man/rsa.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "rsa 3" -.TH rsa 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH rsa 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/sha.3 b/secure/lib/libcrypto/man/sha.3 index 45a291b3a12c..cc7c0758a96d 100644 --- a/secure/lib/libcrypto/man/sha.3 +++ b/secure/lib/libcrypto/man/sha.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "sha 3" -.TH sha 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH sha 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/threads.3 b/secure/lib/libcrypto/man/threads.3 index 99551e54c58d..9b3d4562e4e4 100644 --- a/secure/lib/libcrypto/man/threads.3 +++ b/secure/lib/libcrypto/man/threads.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "threads 3" -.TH threads 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH threads 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ui.3 b/secure/lib/libcrypto/man/ui.3 index e82b76112a28..96f020be69a0 100644 --- a/secure/lib/libcrypto/man/ui.3 +++ b/secure/lib/libcrypto/man/ui.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ui 3" -.TH ui 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ui 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/ui_compat.3 b/secure/lib/libcrypto/man/ui_compat.3 index e48142ddd027..c80022842e15 100644 --- a/secure/lib/libcrypto/man/ui_compat.3 +++ b/secure/lib/libcrypto/man/ui_compat.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ui_compat 3" -.TH ui_compat 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ui_compat 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libcrypto/man/x509.3 b/secure/lib/libcrypto/man/x509.3 index f35248709fcc..4204d28e6d4a 100644 --- a/secure/lib/libcrypto/man/x509.3 +++ b/secure/lib/libcrypto/man/x509.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "x509 3" -.TH x509 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH x509 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssh/Makefile.depend b/secure/lib/libssh/Makefile.depend index 4b24848fc507..28b737e447b6 100644 --- a/secure/lib/libssh/Makefile.depend +++ b/secure/lib/libssh/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/gssapi \ diff --git a/secure/lib/libssl/Makefile.depend b/secure/lib/libssl/Makefile.depend index f318cc1a6b40..2518ffc9b5ad 100644 --- a/secure/lib/libssl/Makefile.depend +++ b/secure/lib/libssl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/lib/libssl/Makefile.man b/secure/lib/libssl/Makefile.man index 92e9d25b7d31..4d357e0dbaad 100644 --- a/secure/lib/libssl/Makefile.man +++ b/secure/lib/libssl/Makefile.man @@ -65,6 +65,7 @@ MAN+= SSL_check_chain.3 MAN+= SSL_clear.3 MAN+= SSL_connect.3 MAN+= SSL_do_handshake.3 +MAN+= SSL_export_keying_material.3 MAN+= SSL_free.3 MAN+= SSL_get_SSL_CTX.3 MAN+= SSL_get_ciphers.3 diff --git a/secure/lib/libssl/man/SSL_CIPHER_get_name.3 b/secure/lib/libssl/man/SSL_CIPHER_get_name.3 index d08ea35602ed..25f168d6ddcf 100644 --- a/secure/lib/libssl/man/SSL_CIPHER_get_name.3 +++ b/secure/lib/libssl/man/SSL_CIPHER_get_name.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CIPHER_get_name 3" -.TH SSL_CIPHER_get_name 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CIPHER_get_name 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 index 09db133ab4df..4f2b0427a4d3 100644 --- a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 +++ b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_COMP_add_compression_method 3" -.TH SSL_COMP_add_compression_method 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_COMP_add_compression_method 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_CTX_new.3 b/secure/lib/libssl/man/SSL_CONF_CTX_new.3 index f716f68e710f..3f8cdb0c76b7 100644 --- a/secure/lib/libssl/man/SSL_CONF_CTX_new.3 +++ b/secure/lib/libssl/man/SSL_CONF_CTX_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_CTX_new 3" -.TH SSL_CONF_CTX_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_CTX_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_CTX_set1_prefix.3 b/secure/lib/libssl/man/SSL_CONF_CTX_set1_prefix.3 index 71b8df74a2a2..14aab9b6f424 100644 --- a/secure/lib/libssl/man/SSL_CONF_CTX_set1_prefix.3 +++ b/secure/lib/libssl/man/SSL_CONF_CTX_set1_prefix.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_CTX_set1_prefix 3" -.TH SSL_CONF_CTX_set1_prefix 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_CTX_set1_prefix 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_CTX_set_flags.3 b/secure/lib/libssl/man/SSL_CONF_CTX_set_flags.3 index 9a122728c86a..f44013b3fd9a 100644 --- a/secure/lib/libssl/man/SSL_CONF_CTX_set_flags.3 +++ b/secure/lib/libssl/man/SSL_CONF_CTX_set_flags.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_CTX_set_flags 3" -.TH SSL_CONF_CTX_set_flags 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_CTX_set_flags 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_CTX_set_ssl_ctx.3 b/secure/lib/libssl/man/SSL_CONF_CTX_set_ssl_ctx.3 index ef23ef74e80c..1d250145530c 100644 --- a/secure/lib/libssl/man/SSL_CONF_CTX_set_ssl_ctx.3 +++ b/secure/lib/libssl/man/SSL_CONF_CTX_set_ssl_ctx.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_CTX_set_ssl_ctx 3" -.TH SSL_CONF_CTX_set_ssl_ctx 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_CTX_set_ssl_ctx 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_cmd.3 b/secure/lib/libssl/man/SSL_CONF_cmd.3 index 75fc933ff6fa..36029fd1047c 100644 --- a/secure/lib/libssl/man/SSL_CONF_cmd.3 +++ b/secure/lib/libssl/man/SSL_CONF_cmd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_cmd 3" -.TH SSL_CONF_cmd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_cmd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CONF_cmd_argv.3 b/secure/lib/libssl/man/SSL_CONF_cmd_argv.3 index 8f57e2064c50..8ac1b4aaa8a1 100644 --- a/secure/lib/libssl/man/SSL_CONF_cmd_argv.3 +++ b/secure/lib/libssl/man/SSL_CONF_cmd_argv.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CONF_cmd_argv 3" -.TH SSL_CONF_cmd_argv 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CONF_cmd_argv 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_add1_chain_cert.3 b/secure/lib/libssl/man/SSL_CTX_add1_chain_cert.3 index 678825503f7f..f546d9fe45a7 100644 --- a/secure/lib/libssl/man/SSL_CTX_add1_chain_cert.3 +++ b/secure/lib/libssl/man/SSL_CTX_add1_chain_cert.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_add1_chain_cert 3" -.TH SSL_CTX_add1_chain_cert 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_add1_chain_cert 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 index 83221be0addd..93f4c148e879 100644 --- a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 +++ b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_add_extra_chain_cert 3" -.TH SSL_CTX_add_extra_chain_cert 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_add_extra_chain_cert 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_add_session.3 b/secure/lib/libssl/man/SSL_CTX_add_session.3 index f270857f68c4..d42aabde2a21 100644 --- a/secure/lib/libssl/man/SSL_CTX_add_session.3 +++ b/secure/lib/libssl/man/SSL_CTX_add_session.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_add_session 3" -.TH SSL_CTX_add_session 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_add_session 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_ctrl.3 b/secure/lib/libssl/man/SSL_CTX_ctrl.3 index a59ddf41e76d..93623fcb6988 100644 --- a/secure/lib/libssl/man/SSL_CTX_ctrl.3 +++ b/secure/lib/libssl/man/SSL_CTX_ctrl.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_ctrl 3" -.TH SSL_CTX_ctrl 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_ctrl 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 index 192cf9c3b3f7..000d98f6ec6c 100644 --- a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 +++ b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_flush_sessions 3" -.TH SSL_CTX_flush_sessions 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_flush_sessions 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_free.3 b/secure/lib/libssl/man/SSL_CTX_free.3 index 1679325783b1..0f57b5cecbe3 100644 --- a/secure/lib/libssl/man/SSL_CTX_free.3 +++ b/secure/lib/libssl/man/SSL_CTX_free.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_free 3" -.TH SSL_CTX_free 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_free 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_get0_param.3 b/secure/lib/libssl/man/SSL_CTX_get0_param.3 index 481e605055d5..0a9cf65a1a3b 100644 --- a/secure/lib/libssl/man/SSL_CTX_get0_param.3 +++ b/secure/lib/libssl/man/SSL_CTX_get0_param.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_get0_param 3" -.TH SSL_CTX_get0_param 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_get0_param 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 index 80571f2b1d37..cb81ea3adf01 100644 --- a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 +++ b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_get_ex_new_index 3" -.TH SSL_CTX_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 index e0972931c9e7..dfeab4874d5b 100644 --- a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 +++ b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_get_verify_mode 3" -.TH SSL_CTX_get_verify_mode 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_get_verify_mode 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 index 44433d52eb25..0c351842cb92 100644 --- a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 +++ b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_load_verify_locations 3" -.TH SSL_CTX_load_verify_locations 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_load_verify_locations 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_new.3 b/secure/lib/libssl/man/SSL_CTX_new.3 index 2f0e043b0dc0..f15e68c3df1a 100644 --- a/secure/lib/libssl/man/SSL_CTX_new.3 +++ b/secure/lib/libssl/man/SSL_CTX_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_new 3" -.TH SSL_CTX_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_sess_number.3 b/secure/lib/libssl/man/SSL_CTX_sess_number.3 index 14169603c5d8..12d4500e3970 100644 --- a/secure/lib/libssl/man/SSL_CTX_sess_number.3 +++ b/secure/lib/libssl/man/SSL_CTX_sess_number.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_sess_number 3" -.TH SSL_CTX_sess_number 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_sess_number 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 index aef68daf1bb5..39518a4e563a 100644 --- a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 +++ b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_sess_set_cache_size 3" -.TH SSL_CTX_sess_set_cache_size 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_sess_set_cache_size 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 index fd61c774e520..e2ffd99befc7 100644 --- a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_sess_set_get_cb 3" -.TH SSL_CTX_sess_set_get_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_sess_set_get_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_sessions.3 b/secure/lib/libssl/man/SSL_CTX_sessions.3 index ac996927fd35..bfacc25f16c5 100644 --- a/secure/lib/libssl/man/SSL_CTX_sessions.3 +++ b/secure/lib/libssl/man/SSL_CTX_sessions.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_sessions 3" -.TH SSL_CTX_sessions 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_sessions 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set1_curves.3 b/secure/lib/libssl/man/SSL_CTX_set1_curves.3 index 0276aad082ea..142fbde21101 100644 --- a/secure/lib/libssl/man/SSL_CTX_set1_curves.3 +++ b/secure/lib/libssl/man/SSL_CTX_set1_curves.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set1_curves 3" -.TH SSL_CTX_set1_curves 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set1_curves 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set1_verify_cert_store.3 b/secure/lib/libssl/man/SSL_CTX_set1_verify_cert_store.3 index 71eee436c388..345752f9bae9 100644 --- a/secure/lib/libssl/man/SSL_CTX_set1_verify_cert_store.3 +++ b/secure/lib/libssl/man/SSL_CTX_set1_verify_cert_store.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set1_verify_cert_store 3" -.TH SSL_CTX_set1_verify_cert_store 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set1_verify_cert_store 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_alpn_select_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_alpn_select_cb.3 index d32905a5b965..f2e1b41cceb2 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_alpn_select_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_alpn_select_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_alpn_select_cb 3" -.TH SSL_CTX_set_alpn_select_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_alpn_select_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_cb.3 index e39f08758d59..01a73d77a468 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_cert_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_cert_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_cert_cb 3" -.TH SSL_CTX_set_cert_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_cert_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 index 097e8d3bec42..e080a82df131 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_cert_store 3" -.TH SSL_CTX_set_cert_store 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_cert_store 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 index 2164b141b4f1..424a61a2f99b 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_cert_verify_callback 3" -.TH SSL_CTX_set_cert_verify_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_cert_verify_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 index 01c532261586..c6d400142c96 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_cipher_list 3" -.TH SSL_CTX_set_cipher_list 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_cipher_list 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 index 9f4521d149b8..b89b90e5ebd4 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_client_CA_list 3" -.TH SSL_CTX_set_client_CA_list 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_client_CA_list 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 index ba6e8bf5a16b..062435e0c117 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_client_cert_cb 3" -.TH SSL_CTX_set_client_cert_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_client_cert_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_custom_cli_ext.3 b/secure/lib/libssl/man/SSL_CTX_set_custom_cli_ext.3 index 44070dd60fc5..5441dc36537f 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_custom_cli_ext.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_custom_cli_ext.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_custom_cli_ext 3" -.TH SSL_CTX_set_custom_cli_ext 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_custom_cli_ext 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 index 030fe91bd195..a0ac7dcb80bb 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_default_passwd_cb 3" -.TH SSL_CTX_set_default_passwd_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_default_passwd_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 index 60aaa024833f..fe2b42e78313 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_generate_session_id 3" -.TH SSL_CTX_set_generate_session_id 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_generate_session_id 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 index c8b467c615aa..ec1cfd2baf88 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_info_callback 3" -.TH SSL_CTX_set_info_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_info_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 index d9537553635f..5c9165f22d9b 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_max_cert_list 3" -.TH SSL_CTX_set_max_cert_list 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_max_cert_list 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_mode.3 index 8ef6f71c8dc2..c83cab7265aa 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_mode.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_mode.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_mode 3" -.TH SSL_CTX_set_mode 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_mode 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 index 571a32c1aefc..78237ad2be22 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_msg_callback 3" -.TH SSL_CTX_set_msg_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_msg_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_options.3 b/secure/lib/libssl/man/SSL_CTX_set_options.3 index e82e1de69e06..3e8bef12ac06 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_options.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_options.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_options 3" -.TH SSL_CTX_set_options 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_options 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_psk_client_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_psk_client_callback.3 index 6b85c8b3699c..ffe94999aaa0 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_psk_client_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_psk_client_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_psk_client_callback 3" -.TH SSL_CTX_set_psk_client_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_psk_client_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 index 6050ce320944..ac7bffe6904a 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_quiet_shutdown 3" -.TH SSL_CTX_set_quiet_shutdown 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_quiet_shutdown 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_read_ahead.3 b/secure/lib/libssl/man/SSL_CTX_set_read_ahead.3 index 0742592edc9c..2ec96e25ed59 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_read_ahead.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_read_ahead.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_read_ahead 3" -.TH SSL_CTX_set_read_ahead 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_read_ahead 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 index b3f820ec2127..0a83dd8b9d7d 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_session_cache_mode 3" -.TH SSL_CTX_set_session_cache_mode 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_session_cache_mode 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 index e0954770fa6a..d523bc5ebdec 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_session_id_context 3" -.TH SSL_CTX_set_session_id_context 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_session_id_context 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 index 72dd1122a923..9c8a1507fbde 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_ssl_version 3" -.TH SSL_CTX_set_ssl_version 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_ssl_version 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_timeout.3 b/secure/lib/libssl/man/SSL_CTX_set_timeout.3 index 900da2fe762f..e415aab4373e 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_timeout.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_timeout.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_timeout 3" -.TH SSL_CTX_set_timeout 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_timeout 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_tlsext_servername_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tlsext_servername_callback.3 index 174392c3c346..c9590d824c10 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_tlsext_servername_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_tlsext_servername_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_tlsext_servername_callback 3" -.TH SSL_CTX_set_tlsext_servername_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_tlsext_servername_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_tlsext_status_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_tlsext_status_cb.3 index a9c6c29467f0..927842b30a45 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_tlsext_status_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_tlsext_status_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_tlsext_status_cb 3" -.TH SSL_CTX_set_tlsext_status_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_tlsext_status_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 index 1bd3a0fa9092..bbdbaef6e0e0 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_tlsext_ticket_key_cb.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_tlsext_ticket_key_cb 3" -.TH SSL_CTX_set_tlsext_ticket_key_cb 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_tlsext_ticket_key_cb 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 index f99d9f73d8b8..6a9f966d2880 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_tmp_dh_callback 3" -.TH SSL_CTX_set_tmp_dh_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_tmp_dh_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 index c8f867e4b683..0d4c5cf58e57 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_tmp_rsa_callback 3" -.TH SSL_CTX_set_tmp_rsa_callback 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_tmp_rsa_callback 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_set_verify.3 b/secure/lib/libssl/man/SSL_CTX_set_verify.3 index 6709ef53bf67..a9881effbc17 100644 --- a/secure/lib/libssl/man/SSL_CTX_set_verify.3 +++ b/secure/lib/libssl/man/SSL_CTX_set_verify.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_set_verify 3" -.TH SSL_CTX_set_verify 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_set_verify 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_use_certificate.3 b/secure/lib/libssl/man/SSL_CTX_use_certificate.3 index fa72e6168842..b05dab1d063f 100644 --- a/secure/lib/libssl/man/SSL_CTX_use_certificate.3 +++ b/secure/lib/libssl/man/SSL_CTX_use_certificate.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_use_certificate 3" -.TH SSL_CTX_use_certificate 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_use_certificate 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_use_psk_identity_hint.3 b/secure/lib/libssl/man/SSL_CTX_use_psk_identity_hint.3 index e595826d3587..ac4f1003c06f 100644 --- a/secure/lib/libssl/man/SSL_CTX_use_psk_identity_hint.3 +++ b/secure/lib/libssl/man/SSL_CTX_use_psk_identity_hint.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_use_psk_identity_hint 3" -.TH SSL_CTX_use_psk_identity_hint 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_use_psk_identity_hint 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_CTX_use_serverinfo.3 b/secure/lib/libssl/man/SSL_CTX_use_serverinfo.3 index a35e15a757f3..f0e06b089bc6 100644 --- a/secure/lib/libssl/man/SSL_CTX_use_serverinfo.3 +++ b/secure/lib/libssl/man/SSL_CTX_use_serverinfo.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_CTX_use_serverinfo 3" -.TH SSL_CTX_use_serverinfo 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_CTX_use_serverinfo 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_SESSION_free.3 b/secure/lib/libssl/man/SSL_SESSION_free.3 index 139cf4090e9b..10af17a4ca25 100644 --- a/secure/lib/libssl/man/SSL_SESSION_free.3 +++ b/secure/lib/libssl/man/SSL_SESSION_free.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_SESSION_free 3" -.TH SSL_SESSION_free 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_SESSION_free 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 index 68b224ff8762..18096595c416 100644 --- a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 +++ b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_SESSION_get_ex_new_index 3" -.TH SSL_SESSION_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_SESSION_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_SESSION_get_time.3 b/secure/lib/libssl/man/SSL_SESSION_get_time.3 index c950cafa1bcc..c120c363a180 100644 --- a/secure/lib/libssl/man/SSL_SESSION_get_time.3 +++ b/secure/lib/libssl/man/SSL_SESSION_get_time.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_SESSION_get_time 3" -.TH SSL_SESSION_get_time 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_SESSION_get_time 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_accept.3 b/secure/lib/libssl/man/SSL_accept.3 index 598af0f5138d..e66573551f8b 100644 --- a/secure/lib/libssl/man/SSL_accept.3 +++ b/secure/lib/libssl/man/SSL_accept.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_accept 3" -.TH SSL_accept 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_accept 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_alert_type_string.3 b/secure/lib/libssl/man/SSL_alert_type_string.3 index b6aed1241ba0..110ba5d3b6df 100644 --- a/secure/lib/libssl/man/SSL_alert_type_string.3 +++ b/secure/lib/libssl/man/SSL_alert_type_string.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_alert_type_string 3" -.TH SSL_alert_type_string 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_alert_type_string 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_check_chain.3 b/secure/lib/libssl/man/SSL_check_chain.3 index cd50cbc19660..9ab9ab0e4fcf 100644 --- a/secure/lib/libssl/man/SSL_check_chain.3 +++ b/secure/lib/libssl/man/SSL_check_chain.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_check_chain 3" -.TH SSL_check_chain 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_check_chain 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_clear.3 b/secure/lib/libssl/man/SSL_clear.3 index 0cfa333b4149..d07cf131515a 100644 --- a/secure/lib/libssl/man/SSL_clear.3 +++ b/secure/lib/libssl/man/SSL_clear.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_clear 3" -.TH SSL_clear 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_clear 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_connect.3 b/secure/lib/libssl/man/SSL_connect.3 index 8f3cfe5d516c..b5776a25b1cf 100644 --- a/secure/lib/libssl/man/SSL_connect.3 +++ b/secure/lib/libssl/man/SSL_connect.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_connect 3" -.TH SSL_connect 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_connect 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_do_handshake.3 b/secure/lib/libssl/man/SSL_do_handshake.3 index 52e9cb8a62ac..e62fd96a97bd 100644 --- a/secure/lib/libssl/man/SSL_do_handshake.3 +++ b/secure/lib/libssl/man/SSL_do_handshake.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_do_handshake 3" -.TH SSL_do_handshake 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_do_handshake 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_export_keying_material.3 b/secure/lib/libssl/man/SSL_export_keying_material.3 new file mode 100644 index 000000000000..cf2c5b4135c6 --- /dev/null +++ b/secure/lib/libssl/man/SSL_export_keying_material.3 @@ -0,0 +1,190 @@ +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "SSL_export_keying_material 3" +.TH SSL_export_keying_material 3 "2017-11-02" "1.0.2m" "OpenSSL" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +SSL_export_keying_material \- obtain keying material for application use +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& #include +\& +\& int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, +\& const char *label, size_t llen, +\& const unsigned char *context, +\& size_t contextlen, int use_context); +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +During the creation of a \s-1TLS\s0 or \s-1DTLS\s0 connection shared keying material is +established between the two endpoints. The function \fISSL_export_keying_material()\fR +enables an application to use some of this keying material for its own purposes +in accordance with \s-1RFC5705.\s0 +.PP +An application may need to securely establish the context within which this +keying material will be used. For example this may include identifiers for the +application session, application algorithms or parameters, or the lifetime of +the context. The context value is left to the application but must be the same +on both sides of the communication. +.PP +For a given \s-1SSL\s0 connection \fBs\fR, \fBolen\fR bytes of data will be written to +\&\fBout\fR. The application specific context should be supplied in the location +pointed to by \fBcontext\fR and should be \fBcontextlen\fR bytes long. Provision of +a context is optional. If the context should be omitted entirely then +\&\fBuse_context\fR should be set to 0. Otherwise it should be any other value. If +\&\fBuse_context\fR is 0 then the values of \fBcontext\fR and \fBcontextlen\fR are ignored. +Note that a zero length context is treated differently to no context at all, and +will result in different keying material being returned. +.PP +An application specific label should be provided in the location pointed to by +\&\fBlabel\fR and should be \fBllen\fR bytes long. Typically this will be a value from +the \s-1IANA\s0 Exporter Label Registry +(). +Alternatively labels beginning with \*(L"\s-1EXPERIMENTAL\*(R"\s0 are permitted by the standard +to be used without registration. +.PP +Note that this function is only defined for TLSv1.0 and above, and DTLSv1.0 and +above. Attempting to use it in SSLv3 will result in an error. +.SH "RETURN VALUES" +.IX Header "RETURN VALUES" +\&\fISSL_export_keying_material()\fR returns 0 or \-1 on failure or 1 on success. +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +.PP +Licensed under the OpenSSL license (the \*(L"License\*(R"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file \s-1LICENSE\s0 in the source distribution or at +. diff --git a/secure/lib/libssl/man/SSL_free.3 b/secure/lib/libssl/man/SSL_free.3 index 81a8273effaa..59538f4406f6 100644 --- a/secure/lib/libssl/man/SSL_free.3 +++ b/secure/lib/libssl/man/SSL_free.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_free 3" -.TH SSL_free 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_free 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_SSL_CTX.3 b/secure/lib/libssl/man/SSL_get_SSL_CTX.3 index 1edaa25a46d1..4c6fb5a344bb 100644 --- a/secure/lib/libssl/man/SSL_get_SSL_CTX.3 +++ b/secure/lib/libssl/man/SSL_get_SSL_CTX.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_SSL_CTX 3" -.TH SSL_get_SSL_CTX 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_SSL_CTX 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_ciphers.3 b/secure/lib/libssl/man/SSL_get_ciphers.3 index e0ed574804df..bf565abfd79b 100644 --- a/secure/lib/libssl/man/SSL_get_ciphers.3 +++ b/secure/lib/libssl/man/SSL_get_ciphers.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_ciphers 3" -.TH SSL_get_ciphers 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_ciphers 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_client_CA_list.3 b/secure/lib/libssl/man/SSL_get_client_CA_list.3 index acd34926ad32..f0fa10504b0f 100644 --- a/secure/lib/libssl/man/SSL_get_client_CA_list.3 +++ b/secure/lib/libssl/man/SSL_get_client_CA_list.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_client_CA_list 3" -.TH SSL_get_client_CA_list 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_client_CA_list 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_current_cipher.3 b/secure/lib/libssl/man/SSL_get_current_cipher.3 index 0598b380fa61..80c5a4b73a4b 100644 --- a/secure/lib/libssl/man/SSL_get_current_cipher.3 +++ b/secure/lib/libssl/man/SSL_get_current_cipher.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_current_cipher 3" -.TH SSL_get_current_cipher 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_current_cipher 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_default_timeout.3 b/secure/lib/libssl/man/SSL_get_default_timeout.3 index a30c24674a4d..313543417503 100644 --- a/secure/lib/libssl/man/SSL_get_default_timeout.3 +++ b/secure/lib/libssl/man/SSL_get_default_timeout.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_default_timeout 3" -.TH SSL_get_default_timeout 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_default_timeout 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_error.3 b/secure/lib/libssl/man/SSL_get_error.3 index 2815aecdb04f..e0f4b22a67b8 100644 --- a/secure/lib/libssl/man/SSL_get_error.3 +++ b/secure/lib/libssl/man/SSL_get_error.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_error 3" -.TH SSL_get_error 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_error 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 index 1f44941bf883..b863f98dccfd 100644 --- a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 +++ b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_ex_data_X509_STORE_CTX_idx 3" -.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_get_ex_new_index.3 index 18ec33138d1d..6e244ce9e873 100644 --- a/secure/lib/libssl/man/SSL_get_ex_new_index.3 +++ b/secure/lib/libssl/man/SSL_get_ex_new_index.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_ex_new_index 3" -.TH SSL_get_ex_new_index 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_ex_new_index 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_fd.3 b/secure/lib/libssl/man/SSL_get_fd.3 index a54f962815e1..e47e5f629f93 100644 --- a/secure/lib/libssl/man/SSL_get_fd.3 +++ b/secure/lib/libssl/man/SSL_get_fd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_fd 3" -.TH SSL_get_fd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_fd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 index 3b027ed588bc..2d0b2d48cee7 100644 --- a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 +++ b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_peer_cert_chain 3" -.TH SSL_get_peer_cert_chain 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_peer_cert_chain 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_peer_certificate.3 b/secure/lib/libssl/man/SSL_get_peer_certificate.3 index 2d700a3b6e77..3e9bc48635a0 100644 --- a/secure/lib/libssl/man/SSL_get_peer_certificate.3 +++ b/secure/lib/libssl/man/SSL_get_peer_certificate.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_peer_certificate 3" -.TH SSL_get_peer_certificate 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_peer_certificate 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_psk_identity.3 b/secure/lib/libssl/man/SSL_get_psk_identity.3 index dcdbb3b82c0a..3347cf723a13 100644 --- a/secure/lib/libssl/man/SSL_get_psk_identity.3 +++ b/secure/lib/libssl/man/SSL_get_psk_identity.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_psk_identity 3" -.TH SSL_get_psk_identity 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_psk_identity 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_rbio.3 b/secure/lib/libssl/man/SSL_get_rbio.3 index 0d74634ee0d5..1f9b43f0d218 100644 --- a/secure/lib/libssl/man/SSL_get_rbio.3 +++ b/secure/lib/libssl/man/SSL_get_rbio.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_rbio 3" -.TH SSL_get_rbio 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_rbio 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_session.3 b/secure/lib/libssl/man/SSL_get_session.3 index d624b8a4357a..4a002eb8aa76 100644 --- a/secure/lib/libssl/man/SSL_get_session.3 +++ b/secure/lib/libssl/man/SSL_get_session.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_session 3" -.TH SSL_get_session 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_session 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_verify_result.3 b/secure/lib/libssl/man/SSL_get_verify_result.3 index 0a794950f8ef..1f21f2159ff3 100644 --- a/secure/lib/libssl/man/SSL_get_verify_result.3 +++ b/secure/lib/libssl/man/SSL_get_verify_result.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_verify_result 3" -.TH SSL_get_verify_result 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_verify_result 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_get_version.3 b/secure/lib/libssl/man/SSL_get_version.3 index 4b46d5b12c6f..106e73e248f0 100644 --- a/secure/lib/libssl/man/SSL_get_version.3 +++ b/secure/lib/libssl/man/SSL_get_version.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_get_version 3" -.TH SSL_get_version 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_get_version 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_library_init.3 b/secure/lib/libssl/man/SSL_library_init.3 index 06594e9a1e16..1bdfd4cef418 100644 --- a/secure/lib/libssl/man/SSL_library_init.3 +++ b/secure/lib/libssl/man/SSL_library_init.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_library_init 3" -.TH SSL_library_init 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_library_init 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_load_client_CA_file.3 b/secure/lib/libssl/man/SSL_load_client_CA_file.3 index 0e6bbaca86ee..4ba550f733e0 100644 --- a/secure/lib/libssl/man/SSL_load_client_CA_file.3 +++ b/secure/lib/libssl/man/SSL_load_client_CA_file.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_load_client_CA_file 3" -.TH SSL_load_client_CA_file 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_load_client_CA_file 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_new.3 b/secure/lib/libssl/man/SSL_new.3 index d4ac8a88d274..2d207bac6b1d 100644 --- a/secure/lib/libssl/man/SSL_new.3 +++ b/secure/lib/libssl/man/SSL_new.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_new 3" -.TH SSL_new 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_new 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_pending.3 b/secure/lib/libssl/man/SSL_pending.3 index e55dd4930a4e..07bccbad6b6d 100644 --- a/secure/lib/libssl/man/SSL_pending.3 +++ b/secure/lib/libssl/man/SSL_pending.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_pending 3" -.TH SSL_pending 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_pending 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_read.3 b/secure/lib/libssl/man/SSL_read.3 index 1ce745c895de..3825de3f3b24 100644 --- a/secure/lib/libssl/man/SSL_read.3 +++ b/secure/lib/libssl/man/SSL_read.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_read 3" -.TH SSL_read 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_read 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_rstate_string.3 b/secure/lib/libssl/man/SSL_rstate_string.3 index ccb7a42a9bff..a151b79cb39a 100644 --- a/secure/lib/libssl/man/SSL_rstate_string.3 +++ b/secure/lib/libssl/man/SSL_rstate_string.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_rstate_string 3" -.TH SSL_rstate_string 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_rstate_string 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_session_reused.3 b/secure/lib/libssl/man/SSL_session_reused.3 index 862a45bf40b5..fc351758b077 100644 --- a/secure/lib/libssl/man/SSL_session_reused.3 +++ b/secure/lib/libssl/man/SSL_session_reused.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_session_reused 3" -.TH SSL_session_reused 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_session_reused 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_set_bio.3 b/secure/lib/libssl/man/SSL_set_bio.3 index 9a6256c1cf96..3113ae477df4 100644 --- a/secure/lib/libssl/man/SSL_set_bio.3 +++ b/secure/lib/libssl/man/SSL_set_bio.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_bio 3" -.TH SSL_set_bio 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_bio 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_set_connect_state.3 b/secure/lib/libssl/man/SSL_set_connect_state.3 index 9061f955bf4e..0f0e27230ad8 100644 --- a/secure/lib/libssl/man/SSL_set_connect_state.3 +++ b/secure/lib/libssl/man/SSL_set_connect_state.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_connect_state 3" -.TH SSL_set_connect_state 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_connect_state 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -157,7 +157,7 @@ it was either assigned a dedicated client method, a dedicated server method, or a generic method, that can be used for both client and server connections. (The method might have been changed with \&\fISSL_CTX_set_ssl_version\fR\|(3) or -\&\fISSL_set_ssl_method()\fR.) +\&\fISSL_set_ssl_method\fR\|(3).) .PP When beginning a new handshake, the \s-1SSL\s0 engine must know whether it must call the connect (client) or accept (server) routines. Even though it may diff --git a/secure/lib/libssl/man/SSL_set_fd.3 b/secure/lib/libssl/man/SSL_set_fd.3 index c55aa83214fe..b9b327112093 100644 --- a/secure/lib/libssl/man/SSL_set_fd.3 +++ b/secure/lib/libssl/man/SSL_set_fd.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_fd 3" -.TH SSL_set_fd 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_fd 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_set_session.3 b/secure/lib/libssl/man/SSL_set_session.3 index a26c7abf2653..89beea372eed 100644 --- a/secure/lib/libssl/man/SSL_set_session.3 +++ b/secure/lib/libssl/man/SSL_set_session.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_session 3" -.TH SSL_set_session 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_session 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_set_shutdown.3 b/secure/lib/libssl/man/SSL_set_shutdown.3 index 4c5b4087f908..c87282fc1645 100644 --- a/secure/lib/libssl/man/SSL_set_shutdown.3 +++ b/secure/lib/libssl/man/SSL_set_shutdown.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_shutdown 3" -.TH SSL_set_shutdown 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_shutdown 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_set_verify_result.3 b/secure/lib/libssl/man/SSL_set_verify_result.3 index 932c04ef197f..6dde8d569ac8 100644 --- a/secure/lib/libssl/man/SSL_set_verify_result.3 +++ b/secure/lib/libssl/man/SSL_set_verify_result.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_set_verify_result 3" -.TH SSL_set_verify_result 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_set_verify_result 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_shutdown.3 b/secure/lib/libssl/man/SSL_shutdown.3 index dacedbae145e..e2e6d31645e6 100644 --- a/secure/lib/libssl/man/SSL_shutdown.3 +++ b/secure/lib/libssl/man/SSL_shutdown.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_shutdown 3" -.TH SSL_shutdown 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_shutdown 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_state_string.3 b/secure/lib/libssl/man/SSL_state_string.3 index 4bcdba7ad0aa..b2c9434646ad 100644 --- a/secure/lib/libssl/man/SSL_state_string.3 +++ b/secure/lib/libssl/man/SSL_state_string.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_state_string 3" -.TH SSL_state_string 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_state_string 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_want.3 b/secure/lib/libssl/man/SSL_want.3 index cc5ada7bf65e..fc7103cb91be 100644 --- a/secure/lib/libssl/man/SSL_want.3 +++ b/secure/lib/libssl/man/SSL_want.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_want 3" -.TH SSL_want 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_want 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/SSL_write.3 b/secure/lib/libssl/man/SSL_write.3 index 5aa6245e195f..161d3c07dd8d 100644 --- a/secure/lib/libssl/man/SSL_write.3 +++ b/secure/lib/libssl/man/SSL_write.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SSL_write 3" -.TH SSL_write 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SSL_write 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/d2i_SSL_SESSION.3 b/secure/lib/libssl/man/d2i_SSL_SESSION.3 index fbcdd441f83d..ae1c7eeb13e0 100644 --- a/secure/lib/libssl/man/d2i_SSL_SESSION.3 +++ b/secure/lib/libssl/man/d2i_SSL_SESSION.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "d2i_SSL_SESSION 3" -.TH d2i_SSL_SESSION 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH d2i_SSL_SESSION 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/lib/libssl/man/ssl.3 b/secure/lib/libssl/man/ssl.3 index 0fb91336b68c..b86ec48246f3 100644 --- a/secure/lib/libssl/man/ssl.3 +++ b/secure/lib/libssl/man/ssl.3 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ssl 3" -.TH ssl 3 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ssl 3 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/libexec/sftp-server/Makefile.depend b/secure/libexec/sftp-server/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/libexec/sftp-server/Makefile.depend +++ b/secure/libexec/sftp-server/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/libexec/ssh-keysign/Makefile.depend b/secure/libexec/ssh-keysign/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/libexec/ssh-keysign/Makefile.depend +++ b/secure/libexec/ssh-keysign/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/libexec/ssh-pkcs11-helper/Makefile.depend b/secure/libexec/ssh-pkcs11-helper/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/libexec/ssh-pkcs11-helper/Makefile.depend +++ b/secure/libexec/ssh-pkcs11-helper/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/openssl/Makefile.depend b/secure/usr.bin/openssl/Makefile.depend index 67e2d7605872..e383274b1a46 100644 --- a/secure/usr.bin/openssl/Makefile.depend +++ b/secure/usr.bin/openssl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/openssl/Makefile.man b/secure/usr.bin/openssl/Makefile.man index 86593eda90a0..773bebbcbcf5 100644 --- a/secure/usr.bin/openssl/Makefile.man +++ b/secure/usr.bin/openssl/Makefile.man @@ -46,11 +46,18 @@ MAN+= verify.1 MAN+= version.1 MAN+= x509.1 MAN+= x509v3_config.1 +MLINKS+= asn1parse.1 openssl-asn1parse.1 +MLINKS+= ca.1 openssl-ca.1 +MLINKS+= ciphers.1 openssl-ciphers.1 +MLINKS+= cms.1 openssl-cms.1 +MLINKS+= crl.1 openssl-crl.1 +MLINKS+= crl2pkcs7.1 openssl-crl2pkcs7.1 MLINKS+= dgst.1 dss1.1 MLINKS+= dgst.1 md2.1 MLINKS+= dgst.1 md4.1 MLINKS+= dgst.1 md5.1 MLINKS+= dgst.1 mdc2.1 +MLINKS+= dgst.1 openssl-dgst.1 MLINKS+= dgst.1 ripemd160.1 MLINKS+= dgst.1 sha.1 MLINKS+= dgst.1 sha1.1 @@ -58,3 +65,38 @@ MLINKS+= dgst.1 sha224.1 MLINKS+= dgst.1 sha256.1 MLINKS+= dgst.1 sha384.1 MLINKS+= dgst.1 sha512.1 +MLINKS+= dhparam.1 openssl-dhparam.1 +MLINKS+= dsa.1 openssl-dsa.1 +MLINKS+= dsaparam.1 openssl-dsaparam.1 +MLINKS+= ec.1 openssl-ec.1 +MLINKS+= ecparam.1 openssl-ecparam.1 +MLINKS+= enc.1 openssl-enc.1 +MLINKS+= errstr.1 openssl-errstr.1 +MLINKS+= gendsa.1 openssl-gendsa.1 +MLINKS+= genpkey.1 openssl-genpkey.1 +MLINKS+= genrsa.1 openssl-genrsa.1 +MLINKS+= nseq.1 openssl-nseq.1 +MLINKS+= ocsp.1 openssl-ocsp.1 +MLINKS+= passwd.1 openssl-passwd.1 +MLINKS+= pkcs12.1 openssl-pkcs12.1 +MLINKS+= pkcs7.1 openssl-pkcs7.1 +MLINKS+= pkcs8.1 openssl-pkcs8.1 +MLINKS+= pkey.1 openssl-pkey.1 +MLINKS+= pkeyparam.1 openssl-pkeyparam.1 +MLINKS+= pkeyutl.1 openssl-pkeyutl.1 +MLINKS+= rand.1 openssl-rand.1 +MLINKS+= req.1 openssl-req.1 +MLINKS+= rsa.1 openssl-rsa.1 +MLINKS+= rsautl.1 openssl-rsautl.1 +MLINKS+= s_client.1 openssl-s_client.1 +MLINKS+= s_server.1 openssl-s_server.1 +MLINKS+= s_time.1 openssl-s_time.1 +MLINKS+= sess_id.1 openssl-sess_id.1 +MLINKS+= smime.1 openssl-smime.1 +MLINKS+= speed.1 openssl-speed.1 +MLINKS+= spkac.1 openssl-spkac.1 +MLINKS+= ts.1 openssl-ts.1 +MLINKS+= tsget.1 openssl-tsget.1 +MLINKS+= verify.1 openssl-verify.1 +MLINKS+= version.1 openssl-version.1 +MLINKS+= x509.1 openssl-x509.1 diff --git a/secure/usr.bin/openssl/man/CA.pl.1 b/secure/usr.bin/openssl/man/CA.pl.1 index b49ba143a860..5e97570d4a39 100644 --- a/secure/usr.bin/openssl/man/CA.pl.1 +++ b/secure/usr.bin/openssl/man/CA.pl.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "CA.PL 1" -.TH CA.PL 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CA.PL 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/usr.bin/openssl/man/asn1parse.1 b/secure/usr.bin/openssl/man/asn1parse.1 index b291793ee225..e2eca2a7ce1a 100644 --- a/secure/usr.bin/openssl/man/asn1parse.1 +++ b/secure/usr.bin/openssl/man/asn1parse.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "ASN1PARSE 1" -.TH ASN1PARSE 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ASN1PARSE 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-asn1parse, asn1parse \- ASN.1 parsing tool .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/c_rehash.1 b/secure/usr.bin/openssl/man/c_rehash.1 index 27b0f4d9e046..37f4cbf804bd 100644 --- a/secure/usr.bin/openssl/man/c_rehash.1 +++ b/secure/usr.bin/openssl/man/c_rehash.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "C_REHASH 1" -.TH C_REHASH 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH C_REHASH 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/usr.bin/openssl/man/ca.1 b/secure/usr.bin/openssl/man/ca.1 index a5334ce2337d..9eb0f4f55b85 100644 --- a/secure/usr.bin/openssl/man/ca.1 +++ b/secure/usr.bin/openssl/man/ca.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "CA 1" -.TH CA 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CA 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ca, ca \- sample minimal CA application .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/ciphers.1 b/secure/usr.bin/openssl/man/ciphers.1 index 28ccf99dd364..50e07c95f8de 100644 --- a/secure/usr.bin/openssl/man/ciphers.1 +++ b/secure/usr.bin/openssl/man/ciphers.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "CIPHERS 1" -.TH CIPHERS 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CIPHERS 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ciphers, ciphers \- SSL cipher display and cipher list tool. .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/cms.1 b/secure/usr.bin/openssl/man/cms.1 index fe806c0de702..3e0518afdc0f 100644 --- a/secure/usr.bin/openssl/man/cms.1 +++ b/secure/usr.bin/openssl/man/cms.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "CMS 1" -.TH CMS 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CMS 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-cms, cms \- CMS utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/crl.1 b/secure/usr.bin/openssl/man/crl.1 index 2f7a0dc64afb..91abbce75bed 100644 --- a/secure/usr.bin/openssl/man/crl.1 +++ b/secure/usr.bin/openssl/man/crl.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "CRL 1" -.TH CRL 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CRL 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-crl, crl \- CRL utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/crl2pkcs7.1 b/secure/usr.bin/openssl/man/crl2pkcs7.1 index dcd1d089d5c5..40162ecaee7f 100644 --- a/secure/usr.bin/openssl/man/crl2pkcs7.1 +++ b/secure/usr.bin/openssl/man/crl2pkcs7.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "CRL2PKCS7 1" -.TH CRL2PKCS7 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH CRL2PKCS7 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-crl2pkcs7, crl2pkcs7 \- Create a PKCS#7 structure from a CRL and certificates. .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/dgst.1 b/secure/usr.bin/openssl/man/dgst.1 index 245734326316..928f73010f59 100644 --- a/secure/usr.bin/openssl/man/dgst.1 +++ b/secure/usr.bin/openssl/man/dgst.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "DGST 1" -.TH DGST 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DGST 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-dgst, dgst, sha, sha1, mdc2, ripemd160, sha224, sha256, sha384, sha512, md2, md4, md5, dss1 \- message digests .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/dhparam.1 b/secure/usr.bin/openssl/man/dhparam.1 index fe78cc4c1964..ec23e33b47ba 100644 --- a/secure/usr.bin/openssl/man/dhparam.1 +++ b/secure/usr.bin/openssl/man/dhparam.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "DHPARAM 1" -.TH DHPARAM 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DHPARAM 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-dhparam, dhparam \- DH parameter manipulation and generation .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/dsa.1 b/secure/usr.bin/openssl/man/dsa.1 index 1b67f881093c..8b5a9da34f5e 100644 --- a/secure/usr.bin/openssl/man/dsa.1 +++ b/secure/usr.bin/openssl/man/dsa.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "DSA 1" -.TH DSA 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSA 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-dsa, dsa \- DSA key processing .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/dsaparam.1 b/secure/usr.bin/openssl/man/dsaparam.1 index b9915878e125..64012bc654e8 100644 --- a/secure/usr.bin/openssl/man/dsaparam.1 +++ b/secure/usr.bin/openssl/man/dsaparam.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "DSAPARAM 1" -.TH DSAPARAM 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH DSAPARAM 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-dsaparam, dsaparam \- DSA parameter manipulation and generation .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/ec.1 b/secure/usr.bin/openssl/man/ec.1 index 7b2dc5330b3d..e14303e0d0cf 100644 --- a/secure/usr.bin/openssl/man/ec.1 +++ b/secure/usr.bin/openssl/man/ec.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "EC 1" -.TH EC 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH EC 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ec, ec \- EC key processing .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/ecparam.1 b/secure/usr.bin/openssl/man/ecparam.1 index f9ad457d7f81..8e08078de55d 100644 --- a/secure/usr.bin/openssl/man/ecparam.1 +++ b/secure/usr.bin/openssl/man/ecparam.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "ECPARAM 1" -.TH ECPARAM 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ECPARAM 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ecparam, ecparam \- EC parameter manipulation and generation .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/enc.1 b/secure/usr.bin/openssl/man/enc.1 index 9eb5bcdb1f57..466a27e33d9f 100644 --- a/secure/usr.bin/openssl/man/enc.1 +++ b/secure/usr.bin/openssl/man/enc.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "ENC 1" -.TH ENC 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ENC 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-enc, enc \- symmetric cipher routines .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/errstr.1 b/secure/usr.bin/openssl/man/errstr.1 index f51ecfc681dc..4e481a61628e 100644 --- a/secure/usr.bin/openssl/man/errstr.1 +++ b/secure/usr.bin/openssl/man/errstr.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "ERRSTR 1" -.TH ERRSTR 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH ERRSTR 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-errstr, errstr \- lookup error codes .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/gendsa.1 b/secure/usr.bin/openssl/man/gendsa.1 index f90accb42124..9cb9620c1c44 100644 --- a/secure/usr.bin/openssl/man/gendsa.1 +++ b/secure/usr.bin/openssl/man/gendsa.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "GENDSA 1" -.TH GENDSA 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH GENDSA 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-gendsa, gendsa \- generate a DSA private key from a set of parameters .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/genpkey.1 b/secure/usr.bin/openssl/man/genpkey.1 index 005d4f96db00..87b2f9f841da 100644 --- a/secure/usr.bin/openssl/man/genpkey.1 +++ b/secure/usr.bin/openssl/man/genpkey.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "GENPKEY 1" -.TH GENPKEY 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH GENPKEY 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-genpkey, genpkey \- generate a private key .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/genrsa.1 b/secure/usr.bin/openssl/man/genrsa.1 index 43e28c68fa57..ec6a4f12a346 100644 --- a/secure/usr.bin/openssl/man/genrsa.1 +++ b/secure/usr.bin/openssl/man/genrsa.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "GENRSA 1" -.TH GENRSA 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH GENRSA 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-genrsa, genrsa \- generate an RSA private key .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/nseq.1 b/secure/usr.bin/openssl/man/nseq.1 index 6810118c7421..b6c885f2c86c 100644 --- a/secure/usr.bin/openssl/man/nseq.1 +++ b/secure/usr.bin/openssl/man/nseq.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "NSEQ 1" -.TH NSEQ 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH NSEQ 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-nseq, nseq \- create or examine a netscape certificate sequence .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/ocsp.1 b/secure/usr.bin/openssl/man/ocsp.1 index 6a21506e2c88..f2190e33886f 100644 --- a/secure/usr.bin/openssl/man/ocsp.1 +++ b/secure/usr.bin/openssl/man/ocsp.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "OCSP 1" -.TH OCSP 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OCSP 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ocsp, ocsp \- Online Certificate Status Protocol utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/openssl.1 b/secure/usr.bin/openssl/man/openssl.1 index 89a7ac726d22..b312d29d1955 100644 --- a/secure/usr.bin/openssl/man/openssl.1 +++ b/secure/usr.bin/openssl/man/openssl.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OPENSSL 1" -.TH OPENSSL 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH OPENSSL 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/usr.bin/openssl/man/passwd.1 b/secure/usr.bin/openssl/man/passwd.1 index 38e1bc3ab9dc..b92a0470b502 100644 --- a/secure/usr.bin/openssl/man/passwd.1 +++ b/secure/usr.bin/openssl/man/passwd.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PASSWD 1" -.TH PASSWD 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PASSWD 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-passwd, passwd \- compute password hashes .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkcs12.1 b/secure/usr.bin/openssl/man/pkcs12.1 index 34d966cc228e..2ef9cd903468 100644 --- a/secure/usr.bin/openssl/man/pkcs12.1 +++ b/secure/usr.bin/openssl/man/pkcs12.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKCS12 1" -.TH PKCS12 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS12 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkcs12, pkcs12 \- PKCS#12 file utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkcs7.1 b/secure/usr.bin/openssl/man/pkcs7.1 index f40c82805bd8..ae2c9872755f 100644 --- a/secure/usr.bin/openssl/man/pkcs7.1 +++ b/secure/usr.bin/openssl/man/pkcs7.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKCS7 1" -.TH PKCS7 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS7 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkcs7, pkcs7 \- PKCS#7 utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkcs8.1 b/secure/usr.bin/openssl/man/pkcs8.1 index bef1493598ef..87feb6f4b3c5 100644 --- a/secure/usr.bin/openssl/man/pkcs8.1 +++ b/secure/usr.bin/openssl/man/pkcs8.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKCS8 1" -.TH PKCS8 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKCS8 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkcs8, pkcs8 \- PKCS#8 format private key conversion tool .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkey.1 b/secure/usr.bin/openssl/man/pkey.1 index 3bbb34fdb0ba..64ae69863b65 100644 --- a/secure/usr.bin/openssl/man/pkey.1 +++ b/secure/usr.bin/openssl/man/pkey.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKEY 1" -.TH PKEY 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKEY 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkey, pkey \- public or private key processing tool .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkeyparam.1 b/secure/usr.bin/openssl/man/pkeyparam.1 index 3ce435f55245..f39a927a8b8b 100644 --- a/secure/usr.bin/openssl/man/pkeyparam.1 +++ b/secure/usr.bin/openssl/man/pkeyparam.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKEYPARAM 1" -.TH PKEYPARAM 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKEYPARAM 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkeyparam, pkeyparam \- public key algorithm parameter processing tool .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/pkeyutl.1 b/secure/usr.bin/openssl/man/pkeyutl.1 index bb5936f98754..0b86f13d33a6 100644 --- a/secure/usr.bin/openssl/man/pkeyutl.1 +++ b/secure/usr.bin/openssl/man/pkeyutl.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "PKEYUTL 1" -.TH PKEYUTL 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH PKEYUTL 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-pkeyutl, pkeyutl \- public key algorithm utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/rand.1 b/secure/usr.bin/openssl/man/rand.1 index dc5c9a6acdf0..0d4dbee39692 100644 --- a/secure/usr.bin/openssl/man/rand.1 +++ b/secure/usr.bin/openssl/man/rand.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "RAND 1" -.TH RAND 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RAND 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-rand, rand \- generate pseudo\-random bytes .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/req.1 b/secure/usr.bin/openssl/man/req.1 index 95a2aed483ea..e4d5cce3ce8d 100644 --- a/secure/usr.bin/openssl/man/req.1 +++ b/secure/usr.bin/openssl/man/req.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "REQ 1" -.TH REQ 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH REQ 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-req, req \- PKCS#10 certificate request and certificate generating utility. .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/rsa.1 b/secure/usr.bin/openssl/man/rsa.1 index db7f5557bfeb..3d2ec4cbdef1 100644 --- a/secure/usr.bin/openssl/man/rsa.1 +++ b/secure/usr.bin/openssl/man/rsa.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "RSA 1" -.TH RSA 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSA 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-rsa, rsa \- RSA key processing tool .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/rsautl.1 b/secure/usr.bin/openssl/man/rsautl.1 index 4a2a4c85dec4..0835f3677837 100644 --- a/secure/usr.bin/openssl/man/rsautl.1 +++ b/secure/usr.bin/openssl/man/rsautl.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "RSAUTL 1" -.TH RSAUTL 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH RSAUTL 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-rsautl, rsautl \- RSA utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" @@ -223,7 +224,7 @@ Recover the signed data Examine the raw signed data: .PP .Vb 1 -\& openssl rsautl \-verify \-in file \-inkey key.pem \-raw \-hexdump +\& openssl rsautl \-verify \-in sig \-inkey key.pem \-raw \-hexdump \& \& 0000 \- 00 01 ff ff ff ff ff ff\-ff ff ff ff ff ff ff ff ................ \& 0010 \- ff ff ff ff ff ff ff ff\-ff ff ff ff ff ff ff ff ................ diff --git a/secure/usr.bin/openssl/man/s_client.1 b/secure/usr.bin/openssl/man/s_client.1 index a0f9f8ea2909..4a5c77476d6a 100644 --- a/secure/usr.bin/openssl/man/s_client.1 +++ b/secure/usr.bin/openssl/man/s_client.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "S_CLIENT 1" -.TH S_CLIENT 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH S_CLIENT 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-s_client, s_client \- SSL/TLS client program .SH "SYNOPSIS" .IX Header "SYNOPSIS" @@ -299,11 +300,13 @@ Can be used to override the implicit \fB\-ign_eof\fR after \fB\-quiet\fR. .IP "\fB\-psk_identity identity\fR" 4 .IX Item "-psk_identity identity" Use the \s-1PSK\s0 identity \fBidentity\fR when using a \s-1PSK\s0 cipher suite. +The default value is \*(L"Client_identity\*(R" (without the quotes). .IP "\fB\-psk key\fR" 4 .IX Item "-psk key" Use the \s-1PSK\s0 key \fBkey\fR when using a \s-1PSK\s0 cipher suite. The key is given as a hexadecimal number without leading 0x, for example \-psk 1a2b3c4d. +This option must be provided in order to use a \s-1PSK\s0 cipher. .IP "\fB\-ssl2\fR, \fB\-ssl3\fR, \fB\-tls1\fR, \fB\-tls1_1\fR, \fB\-tls1_2\fR, \fB\-no_ssl2\fR, \fB\-no_ssl3\fR, \fB\-no_tls1\fR, \fB\-no_tls1_1\fR, \fB\-no_tls1_2\fR" 4 .IX Item "-ssl2, -ssl3, -tls1, -tls1_1, -tls1_2, -no_ssl2, -no_ssl3, -no_tls1, -no_tls1_1, -no_tls1_2" These options require or disable the use of the specified \s-1SSL\s0 or \s-1TLS\s0 protocols. diff --git a/secure/usr.bin/openssl/man/s_server.1 b/secure/usr.bin/openssl/man/s_server.1 index f7617cc8950d..d9820c472f1f 100644 --- a/secure/usr.bin/openssl/man/s_server.1 +++ b/secure/usr.bin/openssl/man/s_server.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "S_SERVER 1" -.TH S_SERVER 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH S_SERVER 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-s_server, s_server \- SSL/TLS server program .SH "SYNOPSIS" .IX Header "SYNOPSIS" @@ -320,6 +321,7 @@ Use the \s-1PSK\s0 identity hint \fBhint\fR when using a \s-1PSK\s0 cipher suite Use the \s-1PSK\s0 key \fBkey\fR when using a \s-1PSK\s0 cipher suite. The key is given as a hexadecimal number without leading 0x, for example \-psk 1a2b3c4d. +This option must be provided in order to use a \s-1PSK\s0 cipher. .IP "\fB\-ssl2\fR, \fB\-ssl3\fR, \fB\-tls1\fR, \fB\-tls1_1\fR, \fB\-tls1_2\fR, \fB\-no_ssl2\fR, \fB\-no_ssl3\fR, \fB\-no_tls1\fR, \fB\-no_tls1_1\fR, \fB\-no_tls1_2\fR" 4 .IX Item "-ssl2, -ssl3, -tls1, -tls1_1, -tls1_2, -no_ssl2, -no_ssl3, -no_tls1, -no_tls1_1, -no_tls1_2" These options require or disable the use of the specified \s-1SSL\s0 or \s-1TLS\s0 protocols. @@ -472,10 +474,6 @@ a web browser the command: .PP can be used for example. .PP -Most web browsers (in particular Netscape and \s-1MSIE\s0) only support \s-1RSA\s0 cipher -suites, so they cannot connect to servers which don't use a certificate -carrying an \s-1RSA\s0 key or a version of OpenSSL with \s-1RSA\s0 disabled. -.PP Although specifying an empty list of CAs when requesting a client certificate is strictly speaking a protocol violation, some \s-1SSL\s0 clients interpret this to mean any \s-1CA\s0 is acceptable. This is useful for debugging purposes. diff --git a/secure/usr.bin/openssl/man/s_time.1 b/secure/usr.bin/openssl/man/s_time.1 index 81a42a1a2d25..e6db1f8c2411 100644 --- a/secure/usr.bin/openssl/man/s_time.1 +++ b/secure/usr.bin/openssl/man/s_time.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "S_TIME 1" -.TH S_TIME 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH S_TIME 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-s_time, s_time \- SSL/TLS performance timing program .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/sess_id.1 b/secure/usr.bin/openssl/man/sess_id.1 index af9b21e99b70..8644632280f8 100644 --- a/secure/usr.bin/openssl/man/sess_id.1 +++ b/secure/usr.bin/openssl/man/sess_id.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "SESS_ID 1" -.TH SESS_ID 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SESS_ID 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-sess_id, sess_id \- SSL/TLS session handling utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/smime.1 b/secure/usr.bin/openssl/man/smime.1 index f9672f805ef5..3a59bec0b7df 100644 --- a/secure/usr.bin/openssl/man/smime.1 +++ b/secure/usr.bin/openssl/man/smime.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "SMIME 1" -.TH SMIME 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SMIME 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-smime, smime \- S/MIME utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/speed.1 b/secure/usr.bin/openssl/man/speed.1 index 73bccfa9e0ca..d410e8f6f251 100644 --- a/secure/usr.bin/openssl/man/speed.1 +++ b/secure/usr.bin/openssl/man/speed.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "SPEED 1" -.TH SPEED 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SPEED 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-speed, speed \- test library performance .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/spkac.1 b/secure/usr.bin/openssl/man/spkac.1 index edba455b0b8a..12afc8820a42 100644 --- a/secure/usr.bin/openssl/man/spkac.1 +++ b/secure/usr.bin/openssl/man/spkac.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "SPKAC 1" -.TH SPKAC 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH SPKAC 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-spkac, spkac \- SPKAC printing and generating utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/ts.1 b/secure/usr.bin/openssl/man/ts.1 index 89ce9088d22f..636d405ab420 100644 --- a/secure/usr.bin/openssl/man/ts.1 +++ b/secure/usr.bin/openssl/man/ts.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "TS 1" -.TH TS 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH TS 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-ts, ts \- Time Stamping Authority tool (client/server) .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/tsget.1 b/secure/usr.bin/openssl/man/tsget.1 index 77a38d00f431..7127e5d2bc43 100644 --- a/secure/usr.bin/openssl/man/tsget.1 +++ b/secure/usr.bin/openssl/man/tsget.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "TSGET 1" -.TH TSGET 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH TSGET 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-tsget, tsget \- Time Stamping HTTP/HTTPS client .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/verify.1 b/secure/usr.bin/openssl/man/verify.1 index aa939300b17a..4f65f99b7e84 100644 --- a/secure/usr.bin/openssl/man/verify.1 +++ b/secure/usr.bin/openssl/man/verify.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "VERIFY 1" -.TH VERIFY 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH VERIFY 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-verify, verify \- Utility to verify certificates. .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/version.1 b/secure/usr.bin/openssl/man/version.1 index a545563c0b1a..27de32704043 100644 --- a/secure/usr.bin/openssl/man/version.1 +++ b/secure/usr.bin/openssl/man/version.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "VERSION 1" -.TH VERSION 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH VERSION 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-version, version \- print OpenSSL version information .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/x509.1 b/secure/usr.bin/openssl/man/x509.1 index 8869ce28a559..09e67adfbfcf 100644 --- a/secure/usr.bin/openssl/man/x509.1 +++ b/secure/usr.bin/openssl/man/x509.1 @@ -129,12 +129,13 @@ .\" ======================================================================== .\" .IX Title "X509 1" -.TH X509 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" +openssl\-x509, x509 \- Certificate display and signing utility .SH "SYNOPSIS" .IX Header "SYNOPSIS" diff --git a/secure/usr.bin/openssl/man/x509v3_config.1 b/secure/usr.bin/openssl/man/x509v3_config.1 index 0458496062b9..2aab3ef029a6 100644 --- a/secure/usr.bin/openssl/man/x509v3_config.1 +++ b/secure/usr.bin/openssl/man/x509v3_config.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "X509V3_CONFIG 1" -.TH X509V3_CONFIG 1 "2017-05-25" "1.0.2l" "OpenSSL" +.TH X509V3_CONFIG 1 "2017-11-02" "1.0.2m" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/secure/usr.bin/scp/Makefile.depend b/secure/usr.bin/scp/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/usr.bin/scp/Makefile.depend +++ b/secure/usr.bin/scp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/sftp/Makefile.depend b/secure/usr.bin/sftp/Makefile.depend index 8c545dd07878..255a2ea15c03 100644 --- a/secure/usr.bin/sftp/Makefile.depend +++ b/secure/usr.bin/sftp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/ssh-add/Makefile.depend b/secure/usr.bin/ssh-add/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/usr.bin/ssh-add/Makefile.depend +++ b/secure/usr.bin/ssh-add/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/ssh-agent/Makefile.depend b/secure/usr.bin/ssh-agent/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/usr.bin/ssh-agent/Makefile.depend +++ b/secure/usr.bin/ssh-agent/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/ssh-keygen/Makefile.depend b/secure/usr.bin/ssh-keygen/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/usr.bin/ssh-keygen/Makefile.depend +++ b/secure/usr.bin/ssh-keygen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/ssh-keyscan/Makefile.depend b/secure/usr.bin/ssh-keyscan/Makefile.depend index 853147744a76..270b7612d3a6 100644 --- a/secure/usr.bin/ssh-keyscan/Makefile.depend +++ b/secure/usr.bin/ssh-keyscan/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/secure/usr.bin/ssh/Makefile.depend b/secure/usr.bin/ssh/Makefile.depend index aa586707742a..c56fe0f8f0fd 100644 --- a/secure/usr.bin/ssh/Makefile.depend +++ b/secure/usr.bin/ssh/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/gssapi \ diff --git a/secure/usr.sbin/sshd/Makefile.depend b/secure/usr.sbin/sshd/Makefile.depend index 220aae36c11c..f72ff7419475 100644 --- a/secure/usr.sbin/sshd/Makefile.depend +++ b/secure/usr.sbin/sshd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/gssapi \ diff --git a/share/colldef/Makefile b/share/colldef/Makefile index 5de824be3a5f..478a91b2e5f8 100644 --- a/share/colldef/Makefile +++ b/share/colldef/Makefile @@ -5,7 +5,7 @@ LOCALEDIR= ${SHAREDIR}/locale FILESNAME= LC_COLLATE .SUFFIXES: .src .LC_COLLATE -MAPLOC= ${SRCTOP}/tools/tools/locale/etc/final-maps +MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps .src.LC_COLLATE: localedef -D -U -i ${.IMPSRC} \ diff --git a/share/colldef/af_ZA.UTF-8.src b/share/colldef/af_ZA.UTF-8.src index 4eafd339e08d..a2f91bfb944b 100644 --- a/share/colldef/af_ZA.UTF-8.src +++ b/share/colldef/af_ZA.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -561,9 +561,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -588,7 +588,7 @@ order_start forward;forward;forward;forward - + @@ -1026,9 +1026,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1053,7 +1053,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1637,8 +1637,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/am_ET.UTF-8.src b/share/colldef/am_ET.UTF-8.src index 187228add0b3..3433b30668a9 100644 --- a/share/colldef/am_ET.UTF-8.src +++ b/share/colldef/am_ET.UTF-8.src @@ -34,15 +34,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -76,7 +76,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -372,15 +372,15 @@ order_start forward;forward;forward;forward - - + - - - + + + + @@ -414,7 +414,7 @@ order_start forward;forward;forward;forward - + @@ -725,15 +725,15 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -771,7 +771,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/ar_SA.UTF-8.src b/share/colldef/ar_SA.UTF-8.src index 64d0c20eb9ff..41bf4067cc82 100644 --- a/share/colldef/ar_SA.UTF-8.src +++ b/share/colldef/ar_SA.UTF-8.src @@ -162,10 +162,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -198,8 +198,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -487,10 +487,10 @@ order_start forward;forward;forward;forward - - - - + + + + @@ -523,8 +523,8 @@ order_start forward;forward;forward;forward - - + + @@ -745,6 +745,7 @@ order_start forward;forward;forward;forward IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; + IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; @@ -906,10 +907,10 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -962,8 +963,8 @@ order_start forward;forward;forward;forward ;;; "";;""; "";;""; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/be_BY.UTF-8.src b/share/colldef/be_BY.UTF-8.src index 9783667f9f40..a6e2eabe6381 100644 --- a/share/colldef/be_BY.UTF-8.src +++ b/share/colldef/be_BY.UTF-8.src @@ -46,9 +46,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -67,7 +67,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -77,7 +77,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -289,9 +289,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -310,7 +310,7 @@ order_start forward;forward;forward;forward - + @@ -320,7 +320,7 @@ order_start forward;forward;forward;forward - + @@ -545,9 +545,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -565,7 +565,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; "";;""; @@ -575,7 +575,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/ca_AD.UTF-8.src b/share/colldef/ca_AD.UTF-8.src index f77d8939a2c4..966b274c1895 100644 --- a/share/colldef/ca_AD.UTF-8.src +++ b/share/colldef/ca_AD.UTF-8.src @@ -70,9 +70,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -561,9 +561,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -589,7 +589,7 @@ order_start forward;forward;forward;forward - + @@ -1028,9 +1028,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1056,7 +1056,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1640,8 +1640,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/cs_CZ.ISO8859-2.src b/share/colldef/cs_CZ.ISO8859-2.src index ee35738599c5..7588d615abfb 100644 --- a/share/colldef/cs_CZ.ISO8859-2.src +++ b/share/colldef/cs_CZ.ISO8859-2.src @@ -46,9 +46,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -85,8 +85,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -166,9 +166,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -205,8 +205,8 @@ order_start forward;forward;forward;forward - - + + @@ -323,9 +323,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -362,8 +362,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/cs_CZ.UTF-8.src b/share/colldef/cs_CZ.UTF-8.src index c7ed361df51f..bcd92fefa7ae 100644 --- a/share/colldef/cs_CZ.UTF-8.src +++ b/share/colldef/cs_CZ.UTF-8.src @@ -107,9 +107,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -134,7 +134,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -605,9 +605,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -632,7 +632,7 @@ order_start forward;forward;forward;forward - + @@ -1076,9 +1076,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1103,7 +1103,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1721,8 +1721,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/da_DK.ISO8859-1.src b/share/colldef/da_DK.ISO8859-1.src index dda9ea2e7281..2df08071c966 100644 --- a/share/colldef/da_DK.ISO8859-1.src +++ b/share/colldef/da_DK.ISO8859-1.src @@ -37,6 +37,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -55,7 +56,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -71,11 +71,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -118,11 +118,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -173,6 +173,7 @@ order_start forward;forward;forward;forward + @@ -191,7 +192,6 @@ order_start forward;forward;forward;forward - @@ -207,11 +207,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -254,11 +254,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -372,11 +372,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -418,11 +418,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -520,8 +520,8 @@ order_start forward;forward;forward;forward "";"";""; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;"";""; diff --git a/share/colldef/da_DK.ISO8859-15.src b/share/colldef/da_DK.ISO8859-15.src index 372a04aec502..bb6a6689cd1f 100644 --- a/share/colldef/da_DK.ISO8859-15.src +++ b/share/colldef/da_DK.ISO8859-15.src @@ -37,6 +37,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -44,6 +45,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -54,7 +56,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -70,11 +71,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -112,11 +113,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -167,6 +168,7 @@ order_start forward;forward;forward;forward + @@ -174,6 +176,7 @@ order_start forward;forward;forward;forward + @@ -184,7 +187,6 @@ order_start forward;forward;forward;forward - @@ -200,11 +202,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -242,11 +244,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -360,11 +362,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -402,11 +404,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -490,6 +492,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; + "";"";""; + "";"";"";

;;;

;;;

;;; @@ -503,8 +507,8 @@ order_start forward;forward;forward;forward "";"";""; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;"";""; @@ -539,8 +543,6 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; "";;""; "";;""; "";;""; diff --git a/share/colldef/da_DK.UTF-8.src b/share/colldef/da_DK.UTF-8.src index ca445175110b..6e0583068c7d 100644 --- a/share/colldef/da_DK.UTF-8.src +++ b/share/colldef/da_DK.UTF-8.src @@ -108,6 +108,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -120,6 +121,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -132,7 +134,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -169,9 +170,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -196,7 +197,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -607,6 +608,7 @@ order_start forward;forward;forward;forward + @@ -619,6 +621,7 @@ order_start forward;forward;forward;forward + @@ -631,7 +634,6 @@ order_start forward;forward;forward;forward - @@ -668,9 +670,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -695,7 +697,7 @@ order_start forward;forward;forward;forward - + @@ -1134,9 +1136,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1161,7 +1163,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1730,8 +1732,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; @@ -1920,6 +1922,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; @@ -2147,8 +2151,8 @@ order_start forward;forward;forward;forward ;;; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; @@ -2507,8 +2511,6 @@ order_start forward;forward;forward;forward "";"";""; "";;""; "";;""; - "";;""; - "";;""; "";;"";"" "";;"";"" "";;""; diff --git a/share/colldef/el_GR.UTF-8.src b/share/colldef/el_GR.UTF-8.src index 46f77523342b..685d3d7bcd1a 100644 --- a/share/colldef/el_GR.UTF-8.src +++ b/share/colldef/el_GR.UTF-8.src @@ -47,9 +47,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -80,7 +80,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -206,9 +206,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -239,7 +239,7 @@ order_start forward;forward;forward;forward - + @@ -365,9 +365,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -410,7 +410,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/en_US.UTF-8.src b/share/colldef/en_US.UTF-8.src index 6f5bef8e8023..b47b6b62f494 100644 --- a/share/colldef/en_US.UTF-8.src +++ b/share/colldef/en_US.UTF-8.src @@ -70,9 +70,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -97,7 +97,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -560,9 +560,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -587,7 +587,7 @@ order_start forward;forward;forward;forward - + @@ -1026,9 +1026,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1053,7 +1053,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1637,8 +1637,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/es_MX.UTF-8.src b/share/colldef/es_MX.UTF-8.src index df2ad4320159..eb894c270b84 100644 --- a/share/colldef/es_MX.UTF-8.src +++ b/share/colldef/es_MX.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -563,9 +563,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -590,7 +590,7 @@ order_start forward;forward;forward;forward - + @@ -1030,9 +1030,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1057,7 +1057,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1641,8 +1641,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/et_EE.UTF-8.src b/share/colldef/et_EE.UTF-8.src index 911f15722232..092de044d371 100644 --- a/share/colldef/et_EE.UTF-8.src +++ b/share/colldef/et_EE.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -569,9 +569,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -596,7 +596,7 @@ order_start forward;forward;forward;forward - + @@ -1042,9 +1042,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1069,7 +1069,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1649,8 +1649,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/fi_FI.UTF-8.src b/share/colldef/fi_FI.UTF-8.src index 13a100bfcf22..4c769a86ec45 100644 --- a/share/colldef/fi_FI.UTF-8.src +++ b/share/colldef/fi_FI.UTF-8.src @@ -80,9 +80,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -107,7 +107,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -579,9 +579,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -606,7 +606,7 @@ order_start forward;forward;forward;forward - + @@ -1044,9 +1044,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1071,7 +1071,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1640,8 +1640,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/fr_CA.UTF-8.src b/share/colldef/fr_CA.UTF-8.src index 8cf1ae085784..e407da19683f 100644 --- a/share/colldef/fr_CA.UTF-8.src +++ b/share/colldef/fr_CA.UTF-8.src @@ -70,9 +70,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -97,7 +97,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -560,9 +560,9 @@ order_start forward;backward;forward;forward - - - + + + @@ -587,7 +587,7 @@ order_start forward;backward;forward;forward - + @@ -1026,9 +1026,9 @@ order_start forward;backward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1053,7 +1053,7 @@ order_start forward;backward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1637,8 +1637,8 @@ order_start forward;backward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/he_IL.UTF-8.src b/share/colldef/he_IL.UTF-8.src index 3ba42a14647a..8bcbe86f84e6 100644 --- a/share/colldef/he_IL.UTF-8.src +++ b/share/colldef/he_IL.UTF-8.src @@ -48,9 +48,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -67,10 +67,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -79,7 +79,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -181,9 +181,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -200,10 +200,10 @@ order_start forward;forward;forward;forward - - - - + + + + @@ -212,7 +212,7 @@ order_start forward;forward;forward;forward - + @@ -364,9 +364,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -385,10 +385,10 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -398,7 +398,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/hi_IN.UTF-8.src b/share/colldef/hi_IN.UTF-8.src index fde3f98b1037..d3ab1b6ad0ac 100644 --- a/share/colldef/hi_IN.UTF-8.src +++ b/share/colldef/hi_IN.UTF-8.src @@ -35,9 +35,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -54,11 +54,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -67,8 +67,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -233,9 +233,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -252,11 +252,11 @@ order_start forward;forward;forward;forward - - - - + + + + @@ -265,8 +265,8 @@ order_start forward;forward;forward;forward - - + + @@ -464,9 +464,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -483,11 +483,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -496,8 +496,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/hr_HR.ISO8859-2.src b/share/colldef/hr_HR.ISO8859-2.src index b4353ce94b36..920265a4af90 100644 --- a/share/colldef/hr_HR.ISO8859-2.src +++ b/share/colldef/hr_HR.ISO8859-2.src @@ -51,9 +51,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -90,8 +90,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -174,9 +174,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -213,8 +213,8 @@ order_start forward;forward;forward;forward - - + + @@ -334,9 +334,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -373,8 +373,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/hu_HU.ISO8859-2.src b/share/colldef/hu_HU.ISO8859-2.src index 099c0e43274c..23834709fd3c 100644 --- a/share/colldef/hu_HU.ISO8859-2.src +++ b/share/colldef/hu_HU.ISO8859-2.src @@ -213,9 +213,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -252,8 +252,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -342,9 +342,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -381,8 +381,8 @@ order_start forward;forward;forward;forward - - + + @@ -505,9 +505,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -544,8 +544,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/hu_HU.UTF-8.src b/share/colldef/hu_HU.UTF-8.src index 654ec9c8ca39..cdc0279fde97 100644 --- a/share/colldef/hu_HU.UTF-8.src +++ b/share/colldef/hu_HU.UTF-8.src @@ -613,9 +613,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -640,7 +640,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1119,9 +1119,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -1146,7 +1146,7 @@ order_start forward;forward;forward;forward - + @@ -1596,9 +1596,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1623,7 +1623,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -2445,8 +2445,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/hy_AM.UTF-8.src b/share/colldef/hy_AM.UTF-8.src index 09af8f915a6e..3fca88a5312f 100644 --- a/share/colldef/hy_AM.UTF-8.src +++ b/share/colldef/hy_AM.UTF-8.src @@ -32,11 +32,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -54,9 +54,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -66,8 +66,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -171,11 +171,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -193,9 +193,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -205,8 +205,8 @@ order_start forward;forward;forward;forward - - + + @@ -327,11 +327,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -348,9 +348,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; "";;""; @@ -361,8 +361,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/is_IS.UTF-8.src b/share/colldef/is_IS.UTF-8.src index a498c6348ab3..6f600338899a 100644 --- a/share/colldef/is_IS.UTF-8.src +++ b/share/colldef/is_IS.UTF-8.src @@ -74,9 +74,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -101,7 +101,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -576,9 +576,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -603,7 +603,7 @@ order_start forward;forward;forward;forward - + @@ -1050,9 +1050,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1077,7 +1077,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1646,8 +1646,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/ja_JP.UTF-8.src b/share/colldef/ja_JP.UTF-8.src index d86ff264e8cd..c0f865b1aceb 100644 --- a/share/colldef/ja_JP.UTF-8.src +++ b/share/colldef/ja_JP.UTF-8.src @@ -783,9 +783,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -822,14 +822,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -955,6 +955,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -965,7 +966,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7362,9 +7362,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -7401,14 +7401,14 @@ order_start forward;forward;forward;forward - - + - - - - - + + + + + + @@ -7534,6 +7534,7 @@ order_start forward;forward;forward;forward + @@ -7544,7 +7545,6 @@ order_start forward;forward;forward;forward - @@ -13949,12 +13949,12 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -14015,18 +14015,18 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;"";"";"" - ;"";"";"" - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;"";"";"" + ;"";"";"" + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -14158,7 +14158,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14177,9 +14177,9 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14205,8 +14205,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14240,7 +14240,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14248,7 +14248,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14267,7 +14267,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14275,7 +14275,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14294,7 +14294,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14310,7 +14310,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14325,10 +14325,10 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14351,13 +14351,13 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14383,10 +14383,10 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14395,7 +14395,7 @@ order_start forward;forward;forward;forward ;;; ;"";"";"" ;"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14423,7 +14423,7 @@ order_start forward;forward;forward;forward ;;; ;"";"";"" ;"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14440,7 +14440,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14452,7 +14452,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14463,7 +14463,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14489,7 +14489,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14536,8 +14536,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14565,7 +14565,7 @@ order_start forward;forward;forward;forward ;;; ;"";"";"" ;"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14682,8 +14682,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14764,9 +14764,9 @@ order_start forward;forward;forward;forward ;"";"";"" ;"";"";"" ;"";"";"" - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14801,7 +14801,7 @@ order_start forward;forward;forward;forward ;"";"";"" ;"";"";"" ;"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14810,7 +14810,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";""; "";"";"";"" "";"";"";"" @@ -14828,7 +14828,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14838,8 +14838,8 @@ order_start forward;forward;forward;forward ;"";"";"" ;"";"";"" ;"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14848,7 +14848,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14865,7 +14865,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14875,8 +14875,8 @@ order_start forward;forward;forward;forward ;"";"";"" ;"";"";"" ;"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14885,7 +14885,7 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";"";"" @@ -14904,8 +14904,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14915,9 +14915,9 @@ order_start forward;forward;forward;forward ;"";"";"" ;"";"";"" ;"";"";"" - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -14942,9 +14942,9 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14952,8 +14952,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";"";"" "";"";"";"" @@ -14961,8 +14961,8 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -14970,15 +14970,15 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" "";"";"";"" "";"";"";"" "";"";"";"" - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -15000,12 +15000,12 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" "";"";""; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -15032,8 +15032,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -15059,7 +15059,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";"";"" "";"";"";"" "";"";"";"" @@ -15078,201 +15078,201 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;"";""; - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;"";""; - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;"";""; + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;"";""; + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" ;;; ;;; ;;; diff --git a/share/colldef/ja_JP.eucJP.src b/share/colldef/ja_JP.eucJP.src index 313adea05cd3..b8b45c4c279e 100644 --- a/share/colldef/ja_JP.eucJP.src +++ b/share/colldef/ja_JP.eucJP.src @@ -710,6 +710,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -729,11 +730,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -834,16 +835,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1040,6 +1041,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1050,7 +1052,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7478,22 +7479,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7546,7 +7539,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7587,17 +7579,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7607,16 +7596,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7630,7 +7615,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7650,9 +7637,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7669,6 +7654,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7686,17 +7672,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7715,7 +7699,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7795,6 +7778,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7830,13 +7815,17 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7869,21 +7858,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7930,8 +7913,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7947,6 +7928,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7961,7 +7944,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7978,6 +7960,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7986,24 +7969,23 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8011,6 +7993,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -8021,9 +8004,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -8034,6 +8020,60 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol order_start forward;forward;forward;forward @@ -8072,6 +8112,7 @@ order_start forward;forward;forward;forward + @@ -8091,11 +8132,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -8196,16 +8237,16 @@ order_start forward;forward;forward;forward - - - + + - - - - - + + + + + + @@ -8402,6 +8443,7 @@ order_start forward;forward;forward;forward + @@ -8412,7 +8454,6 @@ order_start forward;forward;forward;forward - @@ -14840,22 +14881,14 @@ order_start forward;forward;forward;forward - - - - - - - - @@ -14908,7 +14941,6 @@ order_start forward;forward;forward;forward - @@ -14949,17 +14981,14 @@ order_start forward;forward;forward;forward - - - - + @@ -14969,16 +14998,12 @@ order_start forward;forward;forward;forward - - - - @@ -14992,7 +15017,9 @@ order_start forward;forward;forward;forward + + @@ -15012,9 +15039,7 @@ order_start forward;forward;forward;forward - - @@ -15031,6 +15056,7 @@ order_start forward;forward;forward;forward + @@ -15048,17 +15074,15 @@ order_start forward;forward;forward;forward + - - - @@ -15077,7 +15101,6 @@ order_start forward;forward;forward;forward - @@ -15157,6 +15180,8 @@ order_start forward;forward;forward;forward + + @@ -15192,13 +15217,17 @@ order_start forward;forward;forward;forward + - - + + + + + @@ -15231,21 +15260,15 @@ order_start forward;forward;forward;forward - - - - - - - + @@ -15292,8 +15315,6 @@ order_start forward;forward;forward;forward - - @@ -15309,6 +15330,8 @@ order_start forward;forward;forward;forward + + @@ -15323,7 +15346,6 @@ order_start forward;forward;forward;forward - @@ -15340,6 +15362,7 @@ order_start forward;forward;forward;forward + @@ -15348,24 +15371,23 @@ order_start forward;forward;forward;forward + + - - - @@ -15373,6 +15395,7 @@ order_start forward;forward;forward;forward + @@ -15383,9 +15406,12 @@ order_start forward;forward;forward;forward + + + @@ -15396,6 +15422,60 @@ order_start forward;forward;forward;forward + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * assignment of characters to weights @@ -15452,14 +15532,14 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; "";"";""; @@ -15600,8 +15680,8 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; + "";;""; + "";;""; ;;; "";;""; "";;""; @@ -15649,23 +15729,23 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - ;;; - "";;""; - ;;; - ;;; - ;;; - ;"";"";"" - ;"";"";"" - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + "";;""; + "";;""; + ;;; + "";;""; + ;;; + ;;; + ;;; + ;"";"";"" + ;"";"";"" + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -15834,8 +15914,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; ;;; ;;; ;;; @@ -16747,147 +16827,147 @@ order_start forward;forward;forward;forward "";"";"";"" "";"";"";"" "";"";"";"" - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - ;;; - ;;; - ;;; - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" - "";"";"";"" + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + ;;; + ;;; + ;;; + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" + "";"";"";"" ;;; ;;; ;;; @@ -23246,5805 +23326,5805 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;"";""; diff --git a/share/colldef/kk_KZ.UTF-8.src b/share/colldef/kk_KZ.UTF-8.src index e278dfe986d5..d0d0180099d3 100644 --- a/share/colldef/kk_KZ.UTF-8.src +++ b/share/colldef/kk_KZ.UTF-8.src @@ -46,9 +46,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -67,7 +67,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -77,7 +77,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -289,9 +289,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -310,7 +310,7 @@ order_start forward;forward;forward;forward - + @@ -320,7 +320,7 @@ order_start forward;forward;forward;forward - + @@ -545,9 +545,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -565,7 +565,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; "";;""; @@ -575,7 +575,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/ko_KR.UTF-8.src b/share/colldef/ko_KR.UTF-8.src index 99b98c0e2b81..863f3f4731fe 100644 --- a/share/colldef/ko_KR.UTF-8.src +++ b/share/colldef/ko_KR.UTF-8.src @@ -279,9 +279,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -308,7 +308,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -822,9 +822,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -851,7 +851,7 @@ order_start forward;forward;forward;forward - + @@ -1122,8 +1122,8 @@ order_start forward;forward;forward;forward IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; - IGNORE;"";""; - IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; ;;; ;;; ;;; @@ -1134,9 +1134,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1192,7 +1192,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/lt_LT.UTF-8.src b/share/colldef/lt_LT.UTF-8.src index 2a46efaa9cc4..828f94715c4d 100644 --- a/share/colldef/lt_LT.UTF-8.src +++ b/share/colldef/lt_LT.UTF-8.src @@ -73,9 +73,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -100,7 +100,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -569,9 +569,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -596,7 +596,7 @@ order_start forward;forward;forward;forward - + @@ -1038,9 +1038,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1065,7 +1065,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1670,8 +1670,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/lv_LV.UTF-8.src b/share/colldef/lv_LV.UTF-8.src index 9c9946bfdbbe..cca7fb3ae268 100644 --- a/share/colldef/lv_LV.UTF-8.src +++ b/share/colldef/lv_LV.UTF-8.src @@ -72,9 +72,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -99,7 +99,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -572,9 +572,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -599,7 +599,7 @@ order_start forward;forward;forward;forward - + @@ -1046,9 +1046,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1073,7 +1073,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1676,8 +1676,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/nb_NO.ISO8859-1.src b/share/colldef/nb_NO.ISO8859-1.src index 5be0795c7fb1..ab10fbfd5830 100644 --- a/share/colldef/nb_NO.ISO8859-1.src +++ b/share/colldef/nb_NO.ISO8859-1.src @@ -69,11 +69,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -116,11 +116,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -203,11 +203,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -250,11 +250,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -368,11 +368,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -414,11 +414,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/nb_NO.ISO8859-15.src b/share/colldef/nb_NO.ISO8859-15.src index ea0efc9283a9..ce837745ea20 100644 --- a/share/colldef/nb_NO.ISO8859-15.src +++ b/share/colldef/nb_NO.ISO8859-15.src @@ -69,11 +69,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -111,11 +111,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -198,11 +198,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -240,11 +240,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -358,11 +358,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -400,11 +400,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/nn_NO.ISO8859-1.src b/share/colldef/nn_NO.ISO8859-1.src index 5be0795c7fb1..ab10fbfd5830 100644 --- a/share/colldef/nn_NO.ISO8859-1.src +++ b/share/colldef/nn_NO.ISO8859-1.src @@ -69,11 +69,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -116,11 +116,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -203,11 +203,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -250,11 +250,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -368,11 +368,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -414,11 +414,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/nn_NO.ISO8859-15.src b/share/colldef/nn_NO.ISO8859-15.src index ea0efc9283a9..ce837745ea20 100644 --- a/share/colldef/nn_NO.ISO8859-15.src +++ b/share/colldef/nn_NO.ISO8859-15.src @@ -69,11 +69,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -111,11 +111,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -198,11 +198,11 @@ order_start forward;forward;forward;forward - - + - + + @@ -240,11 +240,11 @@ order_start forward;forward;forward;forward - - - - - + + + + + @@ -358,11 +358,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -400,11 +400,11 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/nn_NO.UTF-8.src b/share/colldef/nn_NO.UTF-8.src index cbc7e644fb92..8fcbc4f42a60 100644 --- a/share/colldef/nn_NO.UTF-8.src +++ b/share/colldef/nn_NO.UTF-8.src @@ -168,9 +168,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -195,7 +195,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -666,9 +666,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -693,7 +693,7 @@ order_start forward;forward;forward;forward - + @@ -1132,9 +1132,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1159,7 +1159,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1726,8 +1726,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/pl_PL.UTF-8.src b/share/colldef/pl_PL.UTF-8.src index 207c10bf4dc2..d589668f3b27 100644 --- a/share/colldef/pl_PL.UTF-8.src +++ b/share/colldef/pl_PL.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -571,9 +571,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -598,7 +598,7 @@ order_start forward;forward;forward;forward - + @@ -1046,9 +1046,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1073,7 +1073,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1655,8 +1655,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/ro_RO.UTF-8.src b/share/colldef/ro_RO.UTF-8.src index ae657fe02db3..4fc72cb20352 100644 --- a/share/colldef/ro_RO.UTF-8.src +++ b/share/colldef/ro_RO.UTF-8.src @@ -70,9 +70,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -97,7 +97,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -565,9 +565,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -592,7 +592,7 @@ order_start forward;forward;forward;forward - + @@ -1036,9 +1036,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1063,7 +1063,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1647,8 +1647,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/ru_RU.UTF-8.src b/share/colldef/ru_RU.UTF-8.src index 04ffd14ae1e0..259053812df7 100644 --- a/share/colldef/ru_RU.UTF-8.src +++ b/share/colldef/ru_RU.UTF-8.src @@ -45,9 +45,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -66,7 +66,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -76,7 +76,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -285,9 +285,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -306,7 +306,7 @@ order_start forward;forward;forward;forward - + @@ -316,7 +316,7 @@ order_start forward;forward;forward;forward - + @@ -539,9 +539,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -559,7 +559,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; "";;""; @@ -569,7 +569,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/se_NO.UTF-8.src b/share/colldef/se_NO.UTF-8.src index babc0be149a5..3a16cdc324d7 100644 --- a/share/colldef/se_NO.UTF-8.src +++ b/share/colldef/se_NO.UTF-8.src @@ -78,9 +78,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -105,7 +105,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -585,9 +585,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -612,7 +612,7 @@ order_start forward;forward;forward;forward - + @@ -1060,9 +1060,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1087,7 +1087,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1654,8 +1654,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/sk_SK.ISO8859-2.src b/share/colldef/sk_SK.ISO8859-2.src index 09a2367e78f6..13039c0d35b6 100644 --- a/share/colldef/sk_SK.ISO8859-2.src +++ b/share/colldef/sk_SK.ISO8859-2.src @@ -46,9 +46,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -85,8 +85,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -168,9 +168,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -207,8 +207,8 @@ order_start forward;forward;forward;forward - - + + @@ -327,9 +327,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -366,8 +366,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/sk_SK.UTF-8.src b/share/colldef/sk_SK.UTF-8.src index 6aab7fbf7ead..bb1174fa179a 100644 --- a/share/colldef/sk_SK.UTF-8.src +++ b/share/colldef/sk_SK.UTF-8.src @@ -107,9 +107,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -134,7 +134,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -607,9 +607,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -634,7 +634,7 @@ order_start forward;forward;forward;forward - + @@ -1080,9 +1080,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1107,7 +1107,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1725,8 +1725,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/sl_SI.UTF-8.src b/share/colldef/sl_SI.UTF-8.src index 9d6ba188b6e1..aa4a85efa34d 100644 --- a/share/colldef/sl_SI.UTF-8.src +++ b/share/colldef/sl_SI.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -567,9 +567,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -594,7 +594,7 @@ order_start forward;forward;forward;forward - + @@ -1038,9 +1038,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1065,7 +1065,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1649,8 +1649,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/sr_RS.ISO8859-2.src b/share/colldef/sr_RS.ISO8859-2.src index b4353ce94b36..920265a4af90 100644 --- a/share/colldef/sr_RS.ISO8859-2.src +++ b/share/colldef/sr_RS.ISO8859-2.src @@ -51,9 +51,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -90,8 +90,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -174,9 +174,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -213,8 +213,8 @@ order_start forward;forward;forward;forward - - + + @@ -334,9 +334,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -373,8 +373,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/sr_RS.ISO8859-5.src b/share/colldef/sr_RS.ISO8859-5.src index cfdda39a5215..1fa0db4f4b0d 100644 --- a/share/colldef/sr_RS.ISO8859-5.src +++ b/share/colldef/sr_RS.ISO8859-5.src @@ -33,9 +33,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -61,7 +61,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -167,9 +167,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -195,7 +195,7 @@ order_start forward;forward;forward;forward - + @@ -347,9 +347,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -375,7 +375,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/sr_RS.UTF-8.src b/share/colldef/sr_RS.UTF-8.src index 945e318189c4..521a1b1974fb 100644 --- a/share/colldef/sr_RS.UTF-8.src +++ b/share/colldef/sr_RS.UTF-8.src @@ -45,9 +45,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -66,7 +66,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -76,7 +76,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -284,9 +284,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -305,7 +305,7 @@ order_start forward;forward;forward;forward - + @@ -315,7 +315,7 @@ order_start forward;forward;forward;forward - + @@ -537,9 +537,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -557,7 +557,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; "";;""; @@ -567,7 +567,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/sr_RS.UTF-8@latin.src b/share/colldef/sr_RS.UTF-8@latin.src index b819c0542c90..e6cc59eab5b4 100644 --- a/share/colldef/sr_RS.UTF-8@latin.src +++ b/share/colldef/sr_RS.UTF-8@latin.src @@ -94,9 +94,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -121,7 +121,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -597,9 +597,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -624,7 +624,7 @@ order_start forward;forward;forward;forward - + @@ -1071,9 +1071,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1098,7 +1098,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1685,8 +1685,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/sv_SE.UTF-8.src b/share/colldef/sv_SE.UTF-8.src index 50d7d893b30a..07637cbabe7c 100644 --- a/share/colldef/sv_SE.UTF-8.src +++ b/share/colldef/sv_SE.UTF-8.src @@ -78,9 +78,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -105,7 +105,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -576,9 +576,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -603,7 +603,7 @@ order_start forward;forward;forward;forward - + @@ -1042,9 +1042,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1069,7 +1069,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1636,8 +1636,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/tr_TR.UTF-8.src b/share/colldef/tr_TR.UTF-8.src index a737cea91e83..3206413c60da 100644 --- a/share/colldef/tr_TR.UTF-8.src +++ b/share/colldef/tr_TR.UTF-8.src @@ -71,9 +71,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -98,7 +98,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -567,9 +567,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -594,7 +594,7 @@ order_start forward;forward;forward;forward - + @@ -1038,9 +1038,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1065,7 +1065,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1649,8 +1649,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; diff --git a/share/colldef/uk_UA.UTF-8.src b/share/colldef/uk_UA.UTF-8.src index 70a4fb0843cd..0271c62f5298 100644 --- a/share/colldef/uk_UA.UTF-8.src +++ b/share/colldef/uk_UA.UTF-8.src @@ -48,9 +48,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -69,7 +69,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -79,7 +79,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -293,9 +293,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -314,7 +314,7 @@ order_start forward;forward;forward;forward - + @@ -324,7 +324,7 @@ order_start forward;forward;forward;forward - + @@ -550,9 +550,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -570,7 +570,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; "";;""; @@ -580,7 +580,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/zh_CN.GB18030.src b/share/colldef/zh_CN.GB18030.src index ac7341a9b5e5..56ca1a2ed879 100644 --- a/share/colldef/zh_CN.GB18030.src +++ b/share/colldef/zh_CN.GB18030.src @@ -818,6 +818,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1186,7 +1187,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1356,8 +1362,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1374,19 +1379,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1428,7 +1426,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4206,6 +4210,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4836,13 +4841,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5079,29 +5083,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5110,8 +5100,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5122,10 +5115,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5133,21 +5124,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5215,12 +5206,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5228,29 +5219,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5262,14 +5242,19 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5336,29 +5321,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5632,6 +5635,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5642,7 +5646,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9780,54 +9783,55 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9839,85 +9843,83 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9928,50 +9930,48 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9982,25 +9982,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10012,9 +10013,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10029,7 +10030,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10041,110 +10042,108 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10152,16 +10151,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10169,38 +10168,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10215,165 +10215,161 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10384,13 +10380,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10400,36 +10397,35 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10441,27 +10437,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10470,21 +10465,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10493,29 +10487,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10525,52 +10519,53 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10586,26 +10581,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10622,22 +10617,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10646,12 +10640,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10667,12 +10661,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10680,9 +10673,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10692,11 +10684,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10706,31 +10697,31 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10738,76 +10729,75 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10819,11 +10809,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10831,7 +10822,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10849,14 +10840,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10867,32 +10857,32 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10901,17 +10891,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10922,125 +10913,124 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11048,6 +11038,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11058,14 +11049,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11074,30 +11066,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11106,24 +11098,23 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11134,76 +11125,76 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11212,51 +11203,51 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11264,64 +11255,66 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11330,45 +11323,46 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11387,9 +11381,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11400,67 +11394,69 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11477,23 +11473,22 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11502,18 +11497,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11522,75 +11517,76 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11609,207 +11605,205 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11820,6 +11814,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11830,32 +11825,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11864,45 +11857,45 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11911,60 +11904,60 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11973,8 +11966,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11983,20 +11976,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12005,44 +11999,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12050,48 +12044,49 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12110,96 +12105,95 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12208,8 +12202,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12217,8 +12211,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12226,17 +12221,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12248,13 +12244,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12267,25 +12263,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12295,28 +12292,27 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12325,16 +12321,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12345,9 +12340,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12359,101 +12353,101 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12461,43 +12455,45 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12509,21 +12505,22 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12533,65 +12530,63 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12599,33 +12594,32 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12635,86 +12629,84 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12722,67 +12714,70 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12795,157 +12790,155 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12954,11 +12947,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12971,27 +12965,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13003,428 +12996,426 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13433,61 +13424,60 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13495,92 +13485,93 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13588,138 +13579,137 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13727,41 +13717,41 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13771,175 +13761,175 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13947,42 +13937,42 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13990,319 +13980,319 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14311,205 +14301,207 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14521,91 +14513,91 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14626,60 +14618,58 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14687,11 +14677,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14700,10 +14689,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14712,277 +14701,272 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -14992,33 +14976,34 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15029,142 +15014,142 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15173,39 +15158,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15214,30 +15199,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15256,214 +15241,216 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15478,97 +15465,103 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -15577,66 +15570,66 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15644,32 +15637,33 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15677,212 +15671,213 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15894,34 +15889,34 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -15930,80 +15925,84 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16018,19 +16017,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16038,40 +16036,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16084,14 +16081,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16107,94 +16105,94 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16203,217 +16201,213 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16421,55 +16415,57 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16478,50 +16474,49 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16532,28 +16527,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16562,79 +16559,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16642,29 +16640,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16676,25 +16675,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16703,10 +16703,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16721,16 +16721,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16739,45 +16739,45 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16785,52 +16785,55 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16850,36 +16853,36 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16889,117 +16892,115 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17009,196 +17010,195 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17206,10 +17206,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17217,66 +17216,65 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17285,345 +17283,350 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -17631,15 +17634,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17650,58 +17653,58 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17714,189 +17717,191 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17905,148 +17910,145 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18056,6 +18058,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18063,21 +18066,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18091,6 +18094,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18098,28 +18102,28 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18130,72 +18134,72 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18203,55 +18207,56 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18259,97 +18264,95 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18357,216 +18360,216 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18575,174 +18578,175 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18750,31 +18754,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18782,123 +18785,124 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18906,26 +18910,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18935,65 +18938,66 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19010,82 +19014,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19094,40 +19096,38 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19136,80 +19136,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19226,6 +19226,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -19234,7 +19235,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19242,39 +19242,40 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19289,52 +19290,48 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19342,181 +19339,184 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -19524,50 +19524,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19577,59 +19574,61 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19637,78 +19636,78 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19716,20 +19715,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19737,47 +19736,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19786,156 +19785,158 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -19943,57 +19944,58 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20005,62 +20007,67 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -20068,35 +20075,37 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -20105,98 +20114,97 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -20204,351 +20212,352 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20556,84 +20565,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20642,261 +20647,258 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20905,83 +20907,83 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20989,324 +20991,329 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21314,24 +21321,24 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -21346,116 +21353,112 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21464,13 +21467,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21479,43 +21483,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21526,65 +21531,64 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21596,11 +21600,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21610,222 +21615,227 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21839,89 +21849,91 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -21930,51 +21942,50 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -21983,80 +21994,79 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22064,73 +22074,77 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22139,72 +22153,71 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22215,55 +22228,53 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22279,62 +22290,62 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22342,55 +22353,56 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -22399,100 +22411,100 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -22500,74 +22512,74 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -22577,117 +22589,117 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -22698,7 +22710,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22711,220 +22722,217 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -22932,25 +22940,27 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -22959,41 +22969,40 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23003,43 +23012,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23053,18 +23063,19 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -23072,56 +23083,57 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23129,213 +23141,216 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23343,235 +23358,235 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23581,301 +23596,299 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -23887,156 +23900,158 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -24046,23 +24061,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -24070,200 +24080,201 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -24271,163 +24282,163 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -24435,123 +24446,122 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -24560,46 +24570,46 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -24608,529 +24618,531 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25139,6 +25151,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -25146,8 +25159,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -25155,140 +25169,140 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -25296,20 +25310,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25319,178 +25333,181 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25498,61 +25515,59 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25563,178 +25578,178 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25749,29 +25764,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25781,96 +25797,93 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -25878,155 +25891,160 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -26034,314 +26052,313 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -26352,101 +26369,94 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -26456,15 +26466,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -26472,76 +26485,73 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -26551,6 +26561,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -26569,139 +26580,136 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -26711,30 +26719,31 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -26742,80 +26751,79 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -26823,441 +26831,436 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -27265,143 +27268,145 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -27447,15 +27452,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -27472,161 +27474,157 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -27636,21 +27634,19 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -27659,7 +27655,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -27667,125 +27662,121 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -27799,83 +27790,110 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -28284,6 +28302,7 @@ order_start forward;forward;forward;forward + @@ -28652,7 +28671,12 @@ order_start forward;forward;forward;forward + + + + + @@ -28822,8 +28846,7 @@ order_start forward;forward;forward;forward - - + @@ -28840,19 +28863,12 @@ order_start forward;forward;forward;forward - - - - - - - @@ -28894,7 +28910,13 @@ order_start forward;forward;forward;forward + + + + + + @@ -31672,6 +31694,7 @@ order_start forward;forward;forward;forward + @@ -32302,13 +32325,12 @@ order_start forward;forward;forward;forward - - - - - - + + + + + @@ -32545,29 +32567,15 @@ order_start forward;forward;forward;forward - - - - - - - - - - - - - - - - + + @@ -32576,8 +32584,11 @@ order_start forward;forward;forward;forward + + + @@ -32588,10 +32599,8 @@ order_start forward;forward;forward;forward - - + - @@ -32599,21 +32608,21 @@ order_start forward;forward;forward;forward - + + - + + - - - + + + - - - - - + + + @@ -32681,12 +32690,12 @@ order_start forward;forward;forward;forward - - - - - - + + + + + + @@ -32694,29 +32703,18 @@ order_start forward;forward;forward;forward - - - - - - - - - - - - - - - - + + + + + @@ -32728,14 +32726,19 @@ order_start forward;forward;forward;forward + + + - + + + + - @@ -32802,29 +32805,47 @@ order_start forward;forward;forward;forward - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33098,6 +33119,7 @@ order_start forward;forward;forward;forward + @@ -33108,7 +33130,6 @@ order_start forward;forward;forward;forward - @@ -37246,54 +37267,55 @@ order_start forward;forward;forward;forward - - + + + - + - + - + - - - + + + - + - + - - + + - - + + - + - - + + @@ -37305,85 +37327,83 @@ order_start forward;forward;forward;forward - + + - - + - + - - + - + - - - + + + - - + - + - - + + - - + - + - + - - + + - + + - - + + - + + - - - - + + + @@ -37394,50 +37414,48 @@ order_start forward;forward;forward;forward - + + - - - + + - + - + - - - + + - + - + - + - - + - + - + @@ -37448,25 +37466,26 @@ order_start forward;forward;forward;forward - + - + - + - + - + + @@ -37478,9 +37497,9 @@ order_start forward;forward;forward;forward + - - + @@ -37495,7 +37514,7 @@ order_start forward;forward;forward;forward - + @@ -37507,110 +37526,108 @@ order_start forward;forward;forward;forward - - + + + - - + - + - - + + - + - + - + - - + - + - + - - + + - - - + + - + + - - + - + - + + - - + - + - + - + - - + - + - + - + - + + - - - - + + + + - + - + - + - + - + @@ -37618,16 +37635,16 @@ order_start forward;forward;forward;forward - + - + - - + + @@ -37635,38 +37652,39 @@ order_start forward;forward;forward;forward - + - + + - - - - - + + + + + - - - + + - - - + + + - - - + + + + - - + + @@ -37681,165 +37699,161 @@ order_start forward;forward;forward;forward - + - + - - - - - + + + + + - - + - - + + - + - + - + - - - + + + - - + - + - + - - - + + - - + - + - - + - + - + - - + - + - - + - - + + - + + - + - + + - + - + - + + - + - + + - + - - + + - + - + - + - + - + - - - + + - + - + @@ -37850,13 +37864,14 @@ order_start forward;forward;forward;forward - - + + + - - + + @@ -37866,36 +37881,35 @@ order_start forward;forward;forward;forward - - - + + + + - - + - + - + - + - + - - + @@ -37907,27 +37921,26 @@ order_start forward;forward;forward;forward - - + - - + + + - - - - - + + + + + - - + @@ -37936,21 +37949,20 @@ order_start forward;forward;forward;forward - - + + - + - - + @@ -37959,29 +37971,29 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - + @@ -37991,52 +38003,53 @@ order_start forward;forward;forward;forward - - - - + + + + + - - + + - - + - + + - - - - - + + + + + - - + + - + - + - + - + - - + + @@ -38052,26 +38065,26 @@ order_start forward;forward;forward;forward - + - + - + - + - + - + - - + + @@ -38088,22 +38101,21 @@ order_start forward;forward;forward;forward - + - - + - - - + + + - + @@ -38112,12 +38124,12 @@ order_start forward;forward;forward;forward - - + + - + @@ -38133,12 +38145,11 @@ order_start forward;forward;forward;forward - + - - + @@ -38146,9 +38157,8 @@ order_start forward;forward;forward;forward - - + @@ -38158,11 +38168,10 @@ order_start forward;forward;forward;forward - - + @@ -38172,31 +38181,31 @@ order_start forward;forward;forward;forward - + - + - + - + - + - + @@ -38204,76 +38213,75 @@ order_start forward;forward;forward;forward - + - + - + - - - + + + - + - + - - + + - + - - - + + - + - + - + - + + - @@ -38285,11 +38293,12 @@ order_start forward;forward;forward;forward + - + - + @@ -38297,7 +38306,7 @@ order_start forward;forward;forward;forward - + @@ -38315,14 +38324,13 @@ order_start forward;forward;forward;forward - + - @@ -38333,32 +38341,32 @@ order_start forward;forward;forward;forward - + - - - + + + - + - - + + + - - - + + @@ -38367,17 +38375,18 @@ order_start forward;forward;forward;forward - + - + + - - + + - + @@ -38388,125 +38397,124 @@ order_start forward;forward;forward;forward - + - + - + - - + + + - - + + - + - - + + - - + + - + - - + - + - + - + - - + - + - + - + - + + - - + - + - + - + - - - + + + - + - - - + + + - + - + + - + - - - + + + - - + @@ -38514,6 +38522,7 @@ order_start forward;forward;forward;forward + @@ -38524,14 +38533,15 @@ order_start forward;forward;forward;forward - + + - - + + @@ -38540,30 +38550,30 @@ order_start forward;forward;forward;forward - + - + + - + - + - - - + + @@ -38572,24 +38582,23 @@ order_start forward;forward;forward;forward - + - + - - + + - + - @@ -38600,76 +38609,76 @@ order_start forward;forward;forward;forward + - + - - + + - + - - - + + + - - + + - + - + - + - + - + - + - - + - - - + + + + - + - @@ -38678,51 +38687,51 @@ order_start forward;forward;forward;forward - + - + - + - + - + - - + + - + + - - + + - - + + - @@ -38730,64 +38739,66 @@ order_start forward;forward;forward;forward - - + + + - - - + + + + - + - - - + + + - - + + - - + + - - - - - + + + + - - + + + - + - + - - + + - + - + - + + - - - + + @@ -38796,45 +38807,46 @@ order_start forward;forward;forward;forward - + - + - + - - + + - - + + + - + - + - + @@ -38853,9 +38865,9 @@ order_start forward;forward;forward;forward + - @@ -38866,67 +38878,69 @@ order_start forward;forward;forward;forward - - + + + + - - - + + + - + + - - - + + - - + + + - + - - - + + + - - - + + + + - - + - + - - - + + @@ -38943,23 +38957,22 @@ order_start forward;forward;forward;forward - + + - - - - + + + - @@ -38968,18 +38981,18 @@ order_start forward;forward;forward;forward + - - + + - @@ -38988,75 +39001,76 @@ order_start forward;forward;forward;forward + - + - + - + - + + - - - - + + + + - - - + + + - - + - - + + - - - + + + - + - - - - + + + + @@ -39075,207 +39089,205 @@ order_start forward;forward;forward;forward - + + - + - + - - + + - + - + - - + + - + - - - - + + + - - + - + - + - + + - - - + + + - + - - + + - + - - - + + + - + - + - + - + - - - - + + + - - + + - - + + - - + + + - - + - + - + - - + - + - + - + - + - - + + - + + - + - + - - - + + + - + - + - - - + + + - @@ -39286,6 +39298,7 @@ order_start forward;forward;forward;forward + @@ -39296,32 +39309,30 @@ order_start forward;forward;forward;forward - - + + + - - + - + - - + - + - - - - + + + + - @@ -39330,45 +39341,45 @@ order_start forward;forward;forward;forward - - + + - + + - - + - - + + - - + + + + - - + + - + + - - - + - + + - - @@ -39377,60 +39388,60 @@ order_start forward;forward;forward;forward + - - - - - + + + + + - - + + - + - - + + + - + - + - + - - + - + - + - + - - + @@ -39439,8 +39450,8 @@ order_start forward;forward;forward;forward + - @@ -39449,20 +39460,21 @@ order_start forward;forward;forward;forward + - - + + + - - - + + + - + - @@ -39471,44 +39483,44 @@ order_start forward;forward;forward;forward + - - - + + + - + - - + - - + + - - + + + - + - - - + + + - @@ -39516,48 +39528,49 @@ order_start forward;forward;forward;forward + - + + - + - + - + - + - + - - - + + - + - - - - + + + + + - @@ -39576,96 +39589,95 @@ order_start forward;forward;forward;forward + - + - - + - + - - - + + + - - - - + + + + - - - + + + - + - + - - + + + - - + - - + - - + + + - - + + + - - + - + - @@ -39674,8 +39686,8 @@ order_start forward;forward;forward;forward + - @@ -39683,8 +39695,9 @@ order_start forward;forward;forward;forward + + - @@ -39692,17 +39705,18 @@ order_start forward;forward;forward;forward + - + + - - - + + + - @@ -39714,13 +39728,13 @@ order_start forward;forward;forward;forward + - + - @@ -39733,25 +39747,26 @@ order_start forward;forward;forward;forward + - + + - + - - - + + + - - - + + @@ -39761,28 +39776,27 @@ order_start forward;forward;forward;forward + - + - + + - - - + + - - + - @@ -39791,16 +39805,15 @@ order_start forward;forward;forward;forward - + - + - - + @@ -39811,9 +39824,8 @@ order_start forward;forward;forward;forward - + - @@ -39825,101 +39837,101 @@ order_start forward;forward;forward;forward - - - + + - + - - + + - - + + + - + - - - - - - + + + + + + - + - + - + - - + + - + - - - + + + + + - - - + + - + - - + - - + + - - + + + - + - + - - - + + @@ -39927,43 +39939,45 @@ order_start forward;forward;forward;forward + - + + - - + + - + - + - - + + + - + + - - + + - - - - + + @@ -39975,21 +39989,22 @@ order_start forward;forward;forward;forward + - + - + - - - - - + + + + + + - - + @@ -39999,65 +40014,63 @@ order_start forward;forward;forward;forward - + + - + + - + - + - + - - - - + + + - - - + + + + - - + - - + + + - - + - + - + - - - - + + + - - @@ -40065,33 +40078,32 @@ order_start forward;forward;forward;forward + - + - + - + - - + - - + - + - + @@ -40101,86 +40113,84 @@ order_start forward;forward;forward;forward + - - - + + - + + + - + - + - - + - + - + - - + + - - - - - - + + + + - - - + + + + - + - + - - - + + - + + - - @@ -40188,67 +40198,70 @@ order_start forward;forward;forward;forward + + - - + + - - - + + - + + - - - + + + + - + - - + + + - + - + - - + + - + - - + - + @@ -40261,157 +40274,155 @@ order_start forward;forward;forward;forward + - + - + + - + - + - + - + - + - + - - - + + + - - + - + + - + - + - - + - + - + - - + - - + - + - - - + + + + - - + + - - + - + - + - + - + - - + - - - + + + + - - - - + + + @@ -40420,11 +40431,12 @@ order_start forward;forward;forward;forward + - + + - @@ -40437,27 +40449,26 @@ order_start forward;forward;forward;forward + - + - - - + + - - + + - @@ -40469,428 +40480,426 @@ order_start forward;forward;forward;forward + - - + + + - + - - + + - + + - - - + - + + - - + - + - + + - - + + - - + - + - + + - - + - + + + - - - - - + + + + - - - - + + + + + - + - - + + + + - - - - - - + + + + + + - - + - + + - - + + + - - - + - + + + - - - - + - + - + + - - + + + - - - - - - + + + - + - - + + - + + - + - + + - - - - + - + + - - + - - - + + + + - - + - + - - - + + + + - + - - - + + - + + - - + + - - + + - + - - - - + + + - - + - + - + + + - - + - - + + + - - - + - - - - - + + + - - + + + - + - + + + - - - - - + + - + - + - - + - + + + - - - + - - + - + + - - + + + - - - + - + - + - + + + - - + + - + - + + + - - + + - - @@ -40899,61 +40908,60 @@ order_start forward;forward;forward;forward + - + + - + + - - - + - - + + - + + + - - - - + + - - + - + + - - + - + + - - + - + + - - @@ -40961,92 +40969,93 @@ order_start forward;forward;forward;forward - + - + + - - + - + + - - - + + - + - - + - + + + - - - + - - - - + + + + + + - + + - - + + - - + + + - - + - @@ -41054,138 +41063,137 @@ order_start forward;forward;forward;forward + - + - + - + + + + - - - + - - + + + - - - + - + - + + + - - - + - + - + - + + - + - - + - + + - - + - - + - + + - - + - - + @@ -41193,41 +41201,41 @@ order_start forward;forward;forward;forward - + + + - - - + + + - - - - - + + + + - + - - - + + + - + - @@ -41237,175 +41245,175 @@ order_start forward;forward;forward;forward + - - + + - - + - + - - + + - + + - - + - - + + + + - - + + - - + - + + - + + - - - - - + + + + + - + - + + - - + - + - + - - + + + - - - + - + - - + + - - - + + + + - - + - + - - + + - + - - + - + - @@ -41413,42 +41421,42 @@ order_start forward;forward;forward;forward + - + + + - - - + - + + - - + + - - - + - + - + + + - - - + - + @@ -41456,319 +41464,319 @@ order_start forward;forward;forward;forward + + - - + + - - - + + + + - - - + - + + - - + + - + + - - + + - - - + + - + - + + - + - - - + - + - + + - - + + + - - - + + - - + + - - + + - + + - + - - + - + + - + - + - + + - + + - + - - + - + + - - + + - + - + + - - - + + - - + + + - - - + - + + - - + + - + - - + - + + - - + - - - + + + - + - - + + - + - - - + + - + - - + + + + - - - + - + + - - + - - + - + + - - - + + - - + - + + + - + + - - - - @@ -41777,205 +41785,207 @@ order_start forward;forward;forward;forward + + + - - - + - - + - + + - + - + + + - - - + - + + - + + - + - - + + - + - - + + + + - - - + - - - + + + + + - - - - + + + + - - - + + - + - + - + - + + - + - + + - - - + + - - - + + - - + + - - + + - + - + - + + - - - + + + - - + + - - - + + - - + + - + - + + + - - - - + + - - @@ -41987,91 +41997,91 @@ order_start forward;forward;forward;forward + + - - + + + - - - - + + - - + + + - - + - - - + + - + + - - + - + + + - - + + - + - - + + - - + + + - - - + - + + - - + - - - + + + - @@ -42092,60 +42102,58 @@ order_start forward;forward;forward;forward + + + - - - + - + + + - - + - - - + - + + + - - + - - + - + - - + + + - + - - - @@ -42153,11 +42161,10 @@ order_start forward;forward;forward;forward - + - @@ -42166,10 +42173,10 @@ order_start forward;forward;forward;forward + - @@ -42178,277 +42185,272 @@ order_start forward;forward;forward;forward + + - - + - + + - - + + - - + + + - - + - + - - - + + + - + - + - + + - + - - - - + + + - + + - - - + + - + - - + - + - + - + + - - + + - - + - + + - - + - + + - - + + - - - + + - - - + + - + - - + - - + + + - - + - - - + + - - + + - - + + - - + - + - + + + - + - - + + - - - + - - - - + + + - + - + - + + - - + + - + - - - + @@ -42458,33 +42460,34 @@ order_start forward;forward;forward;forward + + - + - - + + + - + - - + - @@ -42495,142 +42498,142 @@ order_start forward;forward;forward;forward + - + + - - + + + - - - + + - + + - + - + - - - + + - + - + + - + + - - + + - - + + + - - + + - - - + - - + + + - - + - - + + - - + - - - + + + + - - - - + + + - - - + + + + + - - - - + - + + - - + + - - @@ -42639,39 +42642,39 @@ order_start forward;forward;forward;forward + + + - - - + - + - + + - + - + - - + - @@ -42680,30 +42683,30 @@ order_start forward;forward;forward;forward + + - - + + - + + + - - - - @@ -42722,214 +42725,216 @@ order_start forward;forward;forward;forward - + + - - + - + + - - + + - + - - - - + + + - - + - - - + + + + - + - + - + + - - + + - - + - + + - - + - + + - - - - + + + + - - + - + + - - + + - + + + + - - - + + - + - + - + + - - + - + + - - + + + - - + - + + - - - @@ -42944,97 +42949,103 @@ order_start forward;forward;forward;forward + + - - + - + + + - - - - - + + + + + - + - + + - + - + + - - + - + + - + + - - - + - + + - + - + - + + - + - + + + - - - + + - - + @@ -43043,66 +43054,66 @@ order_start forward;forward;forward;forward - + - + + - + + - + - - + - - - + + - + + - + - + - + + - + + + - - - - + + + - - - @@ -43110,32 +43121,33 @@ order_start forward;forward;forward;forward + - - - + + + - - + + - + + + - - + + - - @@ -43143,212 +43155,213 @@ order_start forward;forward;forward;forward + + - - + - + - - + - + + + - + - + - + + - - + + - - + - + - + + - + - - + - + + - - - - - - + + + + - + - - - + + + - + - - + + - - + + + - - + - + + - - + + - + - + - + + - - + - - - + + + + - - + + - - + + - + - + + - + - - + - - + + + + - - - + - + - + - - + - + + - - @@ -43360,34 +43373,34 @@ order_start forward;forward;forward;forward + + - + + - - + - + + - - - - - + + + - - + @@ -43396,80 +43409,84 @@ order_start forward;forward;forward;forward - + + + - - - + + - + + - + - + - + - + + + - + + - - + - - + - + + + - - + - - + + - + + - - - - + + + + - + + - - @@ -43484,19 +43501,18 @@ order_start forward;forward;forward;forward + - + + - - - + - @@ -43504,40 +43520,39 @@ order_start forward;forward;forward;forward + + - - - + + - - + + - - + - + - - - - + + + + - @@ -43550,14 +43565,15 @@ order_start forward;forward;forward;forward + + + - + + - - - @@ -43573,94 +43589,94 @@ order_start forward;forward;forward;forward + + - - + - + + - + + - - - - + + + - - + + - - + + - + - - + + - - + + - + + + - - - + + - + + - - + + - - - - + + + - - - - + + + - + + - - - @@ -43669,217 +43685,213 @@ order_start forward;forward;forward;forward - + - + - - - - - + + + + - + + - - + + - - + - + + - + - - + - + - - + - - - + + + + + - - - + - + - + + - + + - + - + - - + + + - - - + + - - + + - + - - + - - + + - - + - + - + + - + - + - - + - + - + - - + - + + - + - - - + + + - - + + - + - - - + + - + - + + - - + + + - - + + - - + - - + - @@ -43887,55 +43899,57 @@ order_start forward;forward;forward;forward + + - - - + + + - - - + + + + - - + + - + - - + + + - - + - - - + + - + + - + - @@ -43944,50 +43958,49 @@ order_start forward;forward;forward;forward - + - - + - + - + - + - + + - + - + - + - - - - + + + @@ -43998,28 +44011,30 @@ order_start forward;forward;forward;forward + - - - + + + - + + - - + + - + - + + - @@ -44028,79 +44043,80 @@ order_start forward;forward;forward;forward + + - - + + - - - + - + + - - + - + - + + + - - + - - + + - - + - + + - - + + @@ -44108,29 +44124,30 @@ order_start forward;forward;forward;forward + + + - - - - + + - + @@ -44142,25 +44159,26 @@ order_start forward;forward;forward;forward + + - + + - - + + - - @@ -44169,10 +44187,10 @@ order_start forward;forward;forward;forward + - @@ -44187,16 +44205,16 @@ order_start forward;forward;forward;forward + + - + - - - + + - @@ -44205,45 +44223,45 @@ order_start forward;forward;forward;forward + + + - - - + + - - - + + - - - + + - - - + + - + + + - @@ -44251,52 +44269,55 @@ order_start forward;forward;forward;forward + - - + + + - + - + + + - - + + - - + - - - + + + - + + - + + - - - + + + - - @@ -44316,36 +44337,36 @@ order_start forward;forward;forward;forward + + - + - - - - + + + - - - + + + + - - @@ -44355,117 +44376,115 @@ order_start forward;forward;forward;forward + + - - + + - - + + - - - + - + - + - + - - + + - + - - + + - + - - + - + - + + - - + - + + - - - - + + + + - - @@ -44475,196 +44494,195 @@ order_start forward;forward;forward;forward + - + - + - + + - - - + + - - + - + + - - + - + + + - - + - + + - - + - + + - + + - - - + - + - - + - + - + + - - + - + - + + + - - - + - + - + + - - + + - - + - + + - + - - - - - + + + + - + + - - + + - - - - - + + + + - @@ -44672,10 +44690,9 @@ order_start forward;forward;forward;forward + - - @@ -44683,66 +44700,65 @@ order_start forward;forward;forward;forward + + + - - - + + + - - + + - + - - - + - + + - - + - + + - + - - + + - - - @@ -44751,345 +44767,350 @@ order_start forward;forward;forward;forward - + - + + - - + + - - + + - - + + + - + + - - - + + - - - - + + - + - - + + + - + + - + + - - + + + - - + - + + + - - - + + - - - - - + + + + + - + + - + - - + + + - - - + - + - + + - + + + - - - + + + - - - + - + - + - + + + - - + + - - + + - - + - - + + + - + - - + - + - - - + + + - + + - - - + + - - + + - - + + - - - + + + + + - - - - + - + + + - - + - - + - - - - + + + + + - + - + + - - - + + + - + - + + - - + - - + + + - - - + + + - + - - - - + + + - - - - - + + + @@ -45097,15 +45118,15 @@ order_start forward;forward;forward;forward + - + - @@ -45116,58 +45137,58 @@ order_start forward;forward;forward;forward + - + - + - + + - - + + - + - - + + - - - + - + - + - + + + - - @@ -45180,189 +45201,191 @@ order_start forward;forward;forward;forward + + + - - - + - + - + + + - - - - - - + + + + - - + + - - + - + + - - + - + - + - + - + - + - - + + + + - - + - + - + - - + + + + - - - + + + + - - - + + - - + + + - - - + + - + - - - + + + - - + + + - - @@ -45371,148 +45394,145 @@ order_start forward;forward;forward;forward + + + - - + + - + + - + + + - - - + + - - + - + + - - + + - - - + - - + - + + - - + - + - + - + - - + + - - - + + - - + - + + - - + - - - - + + + + + - - - + + - - + - - @@ -45522,6 +45542,7 @@ order_start forward;forward;forward;forward + @@ -45529,21 +45550,21 @@ order_start forward;forward;forward;forward - + + - + - + - @@ -45557,6 +45578,7 @@ order_start forward;forward;forward;forward + @@ -45564,28 +45586,28 @@ order_start forward;forward;forward;forward - + + + - - - + + + - + - - - - + + + + - - + + - - @@ -45596,72 +45618,72 @@ order_start forward;forward;forward;forward + + - + - - + + + + - - - + + + - - + - - - - - + + + - + - - + - + - - - - + + + + - + - + + - + - + - @@ -45669,55 +45691,56 @@ order_start forward;forward;forward;forward + - + + - - + + + - - + + - - + + - - - + + - + - + + + + - - - - + - - + - + @@ -45725,97 +45748,95 @@ order_start forward;forward;forward;forward - - + + + - - - + + + - - - + + - - + - + + + - - + + + - - + + + - - + + + - - + - - + - + - + + + - - + - - - - - @@ -45823,216 +45844,216 @@ order_start forward;forward;forward;forward + + + - - + - - - + + - + - + - - - + + + - - - + + - - + - + - + + - + + + - - + - + + - - - - + - + - + - + + + - - - + - + + - - - + + - - + + - + + + - - + - - + - + + + - - - + + - + - - + + + - - + - + + - - + + - @@ -46041,174 +46062,175 @@ order_start forward;forward;forward;forward + + - - - + + - + + - - - + - - + + - + - + + + + - - - + - + - - - + + + - - + + + + - - - - + + + - - - + + - - - + - - - - + + + + + - + + - + - + - - + + + - - - + - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + @@ -46216,31 +46238,30 @@ order_start forward;forward;forward;forward - - + - + + + + - - - + - + - @@ -46248,123 +46269,124 @@ order_start forward;forward;forward;forward + + - - + + - + - + - - + - - + + - + + - - - + + + + - - - + + - + + - - - - + + + + + - - + - - + + - + + - - - + - + - - + + - - + + + + - - - - - - + + + + + + - - - - + + - - + @@ -46372,26 +46394,25 @@ order_start forward;forward;forward;forward + + - - - - + + + - - + - @@ -46401,65 +46422,66 @@ order_start forward;forward;forward;forward + + - - + + + - - + - + - + + - - - + - + - + - + + + - - - + + + - - @@ -46476,82 +46498,80 @@ order_start forward;forward;forward;forward + + - + - - + + + - + - + - - + + - - + - - + - + + - - + - + + + - - - - + + - - - @@ -46560,40 +46580,38 @@ order_start forward;forward;forward;forward + + - + - + - - + - - + - + + + - - - - - + + - @@ -46602,80 +46620,80 @@ order_start forward;forward;forward;forward - + - + + - - + + - + + - - - + + - + - + + - + + + - - + - + + - - - + - - - - + + + + - + - - @@ -46692,6 +46710,7 @@ order_start forward;forward;forward;forward + @@ -46700,7 +46719,6 @@ order_start forward;forward;forward;forward - @@ -46708,39 +46726,40 @@ order_start forward;forward;forward;forward + - + + - - + + + + - - - + - + - @@ -46755,52 +46774,48 @@ order_start forward;forward;forward;forward - + - - + + - + - - + - - + + + - - - - + + + - - - + - @@ -46808,181 +46823,184 @@ order_start forward;forward;forward;forward + - + + - - + + - - + - - + + - - - + + + + + - - - - + + - + + - - - + + + + + - - - - - + + - + - - + + - + - - + + + - - - + + - - - - - - - + + + + + + - + + + - - - + + - + + + + - - - - - + + + - - + - + + - - + + - + + + - - + - + @@ -46990,50 +47008,47 @@ order_start forward;forward;forward;forward - + - + + - + - - + - + + + - - - + - + - - - - + + - @@ -47043,59 +47058,61 @@ order_start forward;forward;forward;forward + + + - - - + + - + + - - + + - - + + - - + + - - + + + - - + - - + + + + - - - @@ -47103,78 +47120,78 @@ order_start forward;forward;forward;forward + - + - - + + - + - + - + + + - + + - - + + - - - + + - - - - + + + + - + + - - - + + - - + - - @@ -47182,20 +47199,20 @@ order_start forward;forward;forward;forward + + + - - - + + - - @@ -47203,47 +47220,47 @@ order_start forward;forward;forward;forward + + + - - + - - + + + + - - - - + + - - @@ -47252,156 +47269,158 @@ order_start forward;forward;forward;forward + + + - + - + - + + - + + - - - + - + + - - - + - + - - + + - - + + - + + - - - - + + - + + - + - - + - - + - + + + - - - - + + + - + + + + - - - - - + + - - - + + + - + - + + - + + + + - - - - + - + - - + + @@ -47409,57 +47428,58 @@ order_start forward;forward;forward;forward + + + - - - - + - + - + + + - - + + - - - + + - + - + + + - - @@ -47471,62 +47491,67 @@ order_start forward;forward;forward;forward + + + - - - + + - + + - - - - - + + + + - + + + + - - - - + + + + + - - + - + - + - - + + + + - - + - + + + - - - - - + + @@ -47534,35 +47559,37 @@ order_start forward;forward;forward;forward + - + + + + - - + + - - + + - + - - - + @@ -47571,98 +47598,97 @@ order_start forward;forward;forward;forward + + + + - - - - + + - - - + + - - - + + + - - - + - + + + - - - + - + + + + + - - - + + - - + + - - + + - + - - - + - + + - + - - - + + - + + + + - - - + - - - + @@ -47670,351 +47696,352 @@ order_start forward;forward;forward;forward - + + + + + - - - - + + - - + + + - - - + - + + - - - + - - + - + + + + - - + - + + - + + - - - + + + - - + + - - + + - + + + - - - + + - - + + - - - + + + - - + + - - + + + + - - - - - + + - - + + + + + - - - - + - + - + + - - - - + + + + - - - - - + + + - + + + - - - + - - + + + - + - - - + + + - + - - + + - - - + + + - - + - - - + + + + + + - - - - - + - - + - - + + + - - + + + + - - - - + + + - - - + + - - + - - + - + + + - - + - - + + + - - + + - - - + + + - - - + + + + + - - @@ -48022,84 +48049,80 @@ order_start forward;forward;forward;forward - + + + + - - - - - + - + + + + + - - - - + - - + + + - - - - - + + - + + - + - + + + - - + + - - - - + - - @@ -48108,261 +48131,258 @@ order_start forward;forward;forward;forward - + - + + + - - - - - - - + + + + + - - - + + - + - - + + - + - - - - + - + + + + - - + - + + - + + - - + + - - + + - + - - + + - - - + + - - + + + + - - - + + - - - - + + + - - + + - + - + - + - - + + + - - + + - + + + - - - - + + + + - - - + + - - + + - - + + - + + - + + - - - - + + - + - - + - - + + + - - - + + - - - + + + - - + + + + - - - - + + + - - - - @@ -48371,83 +48391,83 @@ order_start forward;forward;forward;forward + + + - - + - - + + - - + - - + + - - + + + - - + + - + + - - + - - + + - - @@ -48455,324 +48475,329 @@ order_start forward;forward;forward;forward + + - - + + + - - - + + + - - - + + + - - - + + - + - + - + + + - - - + + + + - - - + - - + + + + + - - - + - - + - - + + - + - + + - - + + + - - - - + + + + - - + + - - - + + + - - + + - - - + + - + + + + - - - - + + - - + - + + + - - + + - + - - + - + - - + - - - - + + + + - + + - + - - - + + + - - + + - - - + - + + + + - - - - + + + + - - - + - - - + + + - - - + + + + + - - + - - + + - - - + + - - + + + + + - - - + - - + + + - - + + + + - - - @@ -48780,24 +48805,24 @@ order_start forward;forward;forward;forward - + - + - + @@ -48812,116 +48837,112 @@ order_start forward;forward;forward;forward - + + + - - - + + + + + - - - + - + - - - - + + + - - + + + - - - + - + - + + - + + - - + + - - - + + - - + + + - - - + + + - - - - + + + - - - - + + + - - - + + - - + + + - + + - - - + + - - - - @@ -48930,13 +48951,14 @@ order_start forward;forward;forward;forward + + - @@ -48945,43 +48967,44 @@ order_start forward;forward;forward;forward + - + + + - - - + - + + + + - - - - + + - + - @@ -48992,65 +49015,64 @@ order_start forward;forward;forward;forward + - + + + - + - - + + + - + - - - - + + - + + - - + + + - - - - - + - + + - - @@ -49062,11 +49084,12 @@ order_start forward;forward;forward;forward + + - @@ -49076,222 +49099,227 @@ order_start forward;forward;forward;forward + - + + + - - + + + - - - + + + - - - + - + + - - + + + + - - + + - - - + + - + + - + - - + - + - - + + + - - + + - - - + + + - - + + + - - + - + - + + + + - - + - + - - + + + - - - + - - + + + - - + + - - + - - - - - + + + + + - + + - - - - + - + + + + + - - + + - - + - + + + - - - - @@ -49305,89 +49333,91 @@ order_start forward;forward;forward;forward + + - - + + + - - + - + + - - - + + + - - - + + + + - - + + - - + - - + + + - + - - + + - - - - + - + - + + - + + - @@ -49396,51 +49426,50 @@ order_start forward;forward;forward;forward - - + - - + + - + - + - - + + - - + + - - - + + + - + + - - - + - + + - + @@ -49449,80 +49478,79 @@ order_start forward;forward;forward;forward + - - + - + - + + - + - - - + + + - - + - + + + - - + + - - + - - @@ -49530,73 +49558,77 @@ order_start forward;forward;forward;forward + + - - + + - - + - + + - + - + + - - + + - + + - + - - - + + + - - + + - + - + + - @@ -49605,72 +49637,71 @@ order_start forward;forward;forward;forward - + + + - - - - + + + - + - - + + - + - + + + - + - - - + - - + + + - - - @@ -49681,55 +49712,53 @@ order_start forward;forward;forward;forward + + + - - - + + - + + + + - - - + - - - + - - - + - + + - - @@ -49745,62 +49774,62 @@ order_start forward;forward;forward;forward + + + - + - - - + + - - + + + + - - - + - + + - + + + - - + - - - + + + - - - - + + + - - - @@ -49808,55 +49837,56 @@ order_start forward;forward;forward;forward + + - + + + - - - - + - + + + - + - + - - + + - - - + @@ -49865,100 +49895,100 @@ order_start forward;forward;forward;forward - - + + - + - - + + + + + - - - - + + - - + + + - - - + - - + + + + + - - + + - - - + + + - - - + - - + - + + + - - - + + - - + @@ -49966,74 +49996,74 @@ order_start forward;forward;forward;forward + - + + - - - + + - - + - + + - + + + - - - - + + + + - - + - + - + + - - + + - + - - - - - + + + - - + @@ -50043,117 +50073,117 @@ order_start forward;forward;forward;forward - + - + + + - - - + + + - - - + - + - - + + - - + + - + + - + + - - + + - - - + - + + - + + - - + + - - - + - + - - + + - - + + + - + + + + - - - + + - - - + - - + @@ -50164,7 +50194,6 @@ order_start forward;forward;forward;forward - @@ -50177,220 +50206,217 @@ order_start forward;forward;forward;forward - + - + + + + - - - + + + - - + - + - + + - - + + - - - + - + - + + - + - - + + - - + + - - - + + - - - - + + + - + + - + + + - - - - + - + - - + + + - + - + - - - - - - + + + + + + + - - - - + + + + - + - - - + - + - + - - - + + + - - + - - + - + + + + - - - - + - - - + + + + + - - - + + - + - - + + + - - - @@ -50398,25 +50424,27 @@ order_start forward;forward;forward;forward + + + + - - + + - - - - + + @@ -50425,41 +50453,40 @@ order_start forward;forward;forward;forward - + + + - - - + - + - + - @@ -50469,43 +50496,44 @@ order_start forward;forward;forward;forward + - + + + - - - + + + + + - - - - - + + + + + - - - - @@ -50519,18 +50547,19 @@ order_start forward;forward;forward;forward + + - - + @@ -50538,56 +50567,57 @@ order_start forward;forward;forward;forward + - + + - + + - + - - + + + - - - + + + + - - + + - - + + - - - - @@ -50595,213 +50625,216 @@ order_start forward;forward;forward;forward + - - + + - - - + + + + + - - - - + + + - + - + - - + - + + - - + + + - - + + - - - - + + + - + - + + - - - + + - - + + + - + + - - - + + + + - - - - + + - - + + - - - + - + + - + + + - - - + + - + + + - + - + - + - + + - + + - + - + - - - + + + + + - - - + + - - + + - - - - - @@ -50809,235 +50842,235 @@ order_start forward;forward;forward;forward + + - + + - - - - + + + - + - - + + + - - - + + - - - + + + + - - - + + + + + - - - - + + + - - + + + - - - + + + - - - + + - + + - - + + - + - - - + + + + + + - - - - - + + - - + - + + + - - - + + - - - + + - - + + - - + - + - + - + + - + - - + + + - + - - - - + - + + + - - + - + - - - + + + + - - - - + + - - @@ -51047,301 +51080,299 @@ order_start forward;forward;forward;forward + + + + - - + + - - + + - - - - - + + + - - + - + + + + - - - + + - - - + - - - + + - + - + - + - + - + + - - - - - + + + - + - - - - + + - + + + - - + + - - + + - - + - + + + - - - + + - - + + + - + - - - + - + - - + - + + - - - + + + + - + + + - + - - + - - + - - + + - + + + - + + - + - - - + - + + - - - + + - - + + + - - + + + + - - - + + + - - - - + - - @@ -51353,156 +51384,158 @@ order_start forward;forward;forward;forward + - + - + + - + + - + + - - + - - + + - + + - + - - + + - - + + - - + - + - + + + + - - - - - + + - + - + + - + - - + - + - + - - - + + + + + - - + + - - + - - + + + - - - - - + + + + + - - - + - + - - + @@ -51512,23 +51545,18 @@ order_start forward;forward;forward;forward - - - + + + - - + - - - - @@ -51536,200 +51564,201 @@ order_start forward;forward;forward;forward + + - + - + - + - - + + - - + - + - + - + - + + + - - - - - - + + + - - - + + + - - + - + + - - + + - - - + + + - + - - - + + - + + + + - - + - + - - + + - + + - + + - - - - + + - - + + + + - - + + - - + - - - + + + - + + - - - + + + + + - - - - @@ -51737,163 +51766,163 @@ order_start forward;forward;forward;forward - + - + + - - - + - + + - + - - + + - + - - + + - - - + + + + - + + + - - - - - - + + + - + + - - - + - - + + - - - + + + - + - - - + + - + - + - + + - + + - + - - - - - + + + + + - - + + + - - - - + - + + + @@ -51901,123 +51930,122 @@ order_start forward;forward;forward;forward - - - + - + + - - + + - + - + - + + + + - + - - - - + + + - + - - - - + - + + + - - + + + + + + - - - - - + - - + - + - + + + + - - + + - - - @@ -52026,46 +52054,46 @@ order_start forward;forward;forward;forward + + - - + + + + - - + + + + - - - - + + + - - + + + - - - - - - @@ -52074,529 +52102,531 @@ order_start forward;forward;forward;forward + + - + - - + + + - - + + - + + + - - - + + - + - - + - + + + - - + - - + + - + - - + - - - + + - + + - - + + - + - + - - - + + + + - - + + + - - - - + + + - - - + + + - + - + + - - - + + + - + - + - - + + + + - - - - + + + - - - + + + - + - - + + + + - + + - - - - - + + - - + + + - - + + + + - - - - - - + + + + - + + - + + - - - - + + + - + + + - - + + + - - - - + + + + - - + + - - - - + + + + + - - - - + + + + + - - - - + + - - - + - + + + + + - - - + - - + + - - - + + + - + + - - - - - - + + - + - + + + - - - + + + - - + - - + - + - + - + + + - + + - - - - - + + + + + - - - - + + + + - - - - - - + + - + - - - + + - + - + + + - + - - + - - - + - + + + + - - - + - + + + - - - - - + + + - + + - + + - - + + + - - - - + + - - - - - - + + + + - - - @@ -52605,6 +52635,7 @@ order_start forward;forward;forward;forward + @@ -52612,8 +52643,9 @@ order_start forward;forward;forward;forward - + + @@ -52621,140 +52653,140 @@ order_start forward;forward;forward;forward + - - + + - + + + - + - - - + + + - + - - + - - + + - - + - - + + + + - - - + - + - - + + - - - + + + + + + - - - - - - + + + + - - + + + + - - - - + - - + + + + - - - + - - + @@ -52762,20 +52794,20 @@ order_start forward;forward;forward;forward + + - - + - + - @@ -52785,178 +52817,181 @@ order_start forward;forward;forward;forward + + - + - + - + + - - + + + + - - - - + + + - - + + - - - + + + + + - - - + - + - - - + + + - - + - - + + - + + - - - + - - + + + - + - + + + - - + - + + - + + - - - - + + + - - - + + + + - - - + - + - + + + - - - @@ -52964,61 +52999,59 @@ order_start forward;forward;forward;forward + + + - - + + - - - + - + - - + + - - - + - + + - - - + + - - + + - @@ -53029,178 +53062,178 @@ order_start forward;forward;forward;forward + + - + + - + + + - - + - + - - + - + + - - + - - - - + + - + - + + + + - + + - - - - + + + - - - - + + + - + + - + - - + + + - - - + + - - - - + + + + - - + + + + - - - - + - - + + - + - - - + - - + + + - - + + - - @@ -53215,29 +53248,30 @@ order_start forward;forward;forward;forward + + + - - - - + + + + + + - - - - + - @@ -53247,96 +53281,93 @@ order_start forward;forward;forward;forward + - + - + + + - + + + + - - - - - - + + + - - + + + - - - - + + + + - - - - - - + + - + + - - - + - - + + + + + - - - - + + - - - + - @@ -53344,155 +53375,160 @@ order_start forward;forward;forward;forward + + + + + - + - - - - + + + + - - - + - + - + + - - - + + + + - - - - - + + + - - + + + - + - + + + + - - - - + + - - + + - - - - + + + - + - - + - + + - - + + - + - - + + + + - - - - + + - - + - + + + - - + + - - + + @@ -53500,314 +53536,313 @@ order_start forward;forward;forward;forward + + - + - - + + - - + + + + - - + + - - + - + - - - + + - + + + - + - - - + - + + + - - - + - - - + + + + + - - - + + + - - - - + + - - + - + - + + + + - + - - - - - + + - + + - - - + - + + + - - + + + - - - + - - - - + + + + - + - + - - + + - + + - + + - - - - - + + + - + - + - + + - - - + + + - - - - - + + + + + - - - + - - - + + + + + + - + - - + + - - + - + - - + + - - - - + + - + + + - - + + - + - - - - + - - + + + - + + - - @@ -53818,101 +53853,94 @@ order_start forward;forward;forward;forward + + + + - - - - - + - - + + - + + + - + - - - - + - + - - - - + + + + + - - - + + - - + - - - - + - + + + + - - - - - + + - + + + + - - - + - - - @@ -53922,15 +53950,18 @@ order_start forward;forward;forward;forward + + - + + @@ -53938,76 +53969,73 @@ order_start forward;forward;forward;forward + - - - + + - - - + + - - + + + - + + + - - - - + + + + - - + + - + - - - - - @@ -54017,6 +54045,7 @@ order_start forward;forward;forward;forward + @@ -54035,139 +54064,136 @@ order_start forward;forward;forward;forward + + + - - - - + + - + + - - - + + + - + + - - + + - - - + + + + - - - - - - + + - - - + + + + - - + + + - - - + - + + - - - + + + - - + + - - + + - + - + + - - - - - + + + - - + - + - - @@ -54177,30 +54203,31 @@ order_start forward;forward;forward;forward + + - + - + - @@ -54208,80 +54235,79 @@ order_start forward;forward;forward;forward + + - - - + + + + - - + + - - + - + + - + - + - - - - + + - + - + + - - - - + @@ -54289,441 +54315,436 @@ order_start forward;forward;forward;forward + + + - - - - + + + + + - - - - - - - + + + - - - + + + - - + + + + - - - - - + + + + + + + - - - - - - + - - + + + + - - + + - - + - + + + - - - - + + + - - - + + + + - - - + + + + - - - - - + - + + - - + - + - + - + + - - - - + + + + - - + + - - + - - - + - + - + + - + + + + - - - - - - + - - + + - - + + - + + - + - - + + + + - - - - - + + + - - - + + + + + - - - + + + - - - + - - - + - + + - + + + + - - - - - + + - - - + + - - + - + + + + - + - - - - + + - - + + + + - - + + - - + + - - - - - + + + - - - + + - - + - + + + + + - - - + + - - + + + + + - - - - + + - - + - - + + - + - + + - - - - + + - + - + - + @@ -54731,143 +54752,145 @@ order_start forward;forward;forward;forward - + + + - + - - - - + + + + + - - - - - + + + + - - - + - - + + + - + - - + - + + - - - - + + + + + + - - - - + + + + - - - - + + + + - - - + + - + + - + - + - - - + + - + - - + + + - + + - - - + @@ -54913,15 +54936,12 @@ order_start forward;forward;forward;forward - - - @@ -54938,161 +54958,157 @@ order_start forward;forward;forward;forward - - - + + - + + - - + + - + - + - - + + - - + + - - + + + - + + - - - - + - - - - + - + - - - + + + + + + - + + - + + + - - - - - + - - - - - + - - + + + + - + + + - - + + - - - - + + - + + - @@ -55102,21 +55118,19 @@ order_start forward;forward;forward;forward - + - - - + - + - + @@ -55125,7 +55139,6 @@ order_start forward;forward;forward;forward - @@ -55133,125 +55146,121 @@ order_start forward;forward;forward;forward + - - + - + + + + + + + - - - + + - - - - - - + + + - - + + + + - + - - - + - - + + - + + + + - + + + - - - - - - - + + + + - + - - - - - + + + - - - - + + - + - - - - - + + - - - + + @@ -55265,83 +55274,110 @@ order_start forward;forward;forward;forward - - - - + - - + + + + - - - + - + - - - + + - - + + + - + - - - - + - - + - + - + + + + - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -55615,6 +55651,7 @@ order_start forward;forward;forward;forward IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; + IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; IGNORE;IGNORE;IGNORE; @@ -55777,6 +55814,9 @@ order_start forward;forward;forward;forward IGNORE;;; IGNORE;;; IGNORE;;; + IGNORE;;; + IGNORE;;; + IGNORE;;; IGNORE;;; IGNORE;;; IGNORE;;; @@ -55830,6 +55870,7 @@ order_start forward;forward;forward;forward IGNORE;;; IGNORE;;; IGNORE;;; + IGNORE;;; IGNORE;;; IGNORE;;; IGNORE;;; @@ -55963,13 +56004,16 @@ order_start forward;forward;forward;forward IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; + IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; + IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; + IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; @@ -56027,6 +56071,9 @@ order_start forward;forward;forward;forward IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; @@ -56055,6 +56102,7 @@ order_start forward;forward;forward;forward IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; + IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; @@ -56091,62 +56139,62 @@ order_start forward;forward;forward;forward IGNORE;"";""; IGNORE;"";""; IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; - IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; + IGNORE;"";""; ;;; ;;; ;;; @@ -56247,79 +56295,80 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";""; - ;;; - ;;; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";""; + ;;; + ;;; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; ;;; ;;; ;;; @@ -56468,39 +56517,39 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; @@ -56791,96 +56840,101 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";;""; + "";;""; + "";;""; ;;; ;;; ;;; @@ -57841,58 +57895,59 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; "";;""; @@ -59271,547 +59326,549 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;"";""; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;"";""; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -59983,58 +60040,58 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60093,32 +60150,32 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60175,9 +60232,9 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; "";"";""; "";"";""; @@ -60187,8 +60244,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60251,8 +60308,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60307,8 +60364,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60361,8 +60418,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60415,8 +60472,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60468,8 +60525,8 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -60520,8 +60577,8 @@ order_start forward;forward;forward;forward ;;; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;"";""; ;"";""; @@ -63049,7 +63106,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -63883,7 +63940,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -64463,24694 +64520,24715 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;"";""; @@ -89937,8 +90015,8 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - ;"";""; - ;"";""; + ;"";""; + ;"";""; "";"";""; "";"";""; "";"";""; @@ -93274,6 +93352,17 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; "";;""; "";;""; "";;""; @@ -94086,6 +94175,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; + ;;; ;;; ;;; ;;; @@ -94568,6 +94658,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -94814,57 +94906,57 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;;; @@ -95159,2103 +95251,2103 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";"";""; - "";;""; - "";;""; - ;;; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";"";""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";"";""; + "";;""; + "";;""; + ;;; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";"";""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;;; @@ -109422,10 +109514,10 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109433,8 +109525,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109444,7 +109536,7 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109452,8 +109544,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109461,8 +109553,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109471,11 +109563,11 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109483,13 +109575,13 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109497,10 +109589,10 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109509,24 +109601,24 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; ;;; ;"";""; ;"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; ;;; ;"";""; ;"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109535,7 +109627,7 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; "";"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109549,8 +109641,8 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109563,7 +109655,7 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109593,8 +109685,8 @@ order_start forward;forward;forward;forward ;;; ;"";""; ;"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109627,9 +109719,9 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";""; ;;; ;;; @@ -109640,10 +109732,10 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109653,10 +109745,10 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109666,13 +109758,13 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109682,29 +109774,29 @@ order_start forward;forward;forward;forward ;"";""; ;"";""; ;"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; ;;; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109714,9 +109806,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109728,8 +109820,8 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -109737,70 +109829,70 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - "";"";""; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + "";"";""; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -109843,6 +109935,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/zh_CN.GB2312.src b/share/colldef/zh_CN.GB2312.src index c09ad60c8c83..43f39bb4fe57 100644 --- a/share/colldef/zh_CN.GB2312.src +++ b/share/colldef/zh_CN.GB2312.src @@ -101,9 +101,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -191,13 +191,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -399,6 +399,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -409,7 +410,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1458,4481 +1458,4478 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5971,21 +5968,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol @@ -6059,9 +6056,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -6149,13 +6146,13 @@ order_start forward;forward;forward;forward - - - - - - - + + + + + + + @@ -6357,6 +6354,7 @@ order_start forward;forward;forward;forward + @@ -6367,7 +6365,6 @@ order_start forward;forward;forward;forward - @@ -7416,4481 +7413,4478 @@ order_start forward;forward;forward;forward - - - - - + + + + - - - + + + - + - + - + - - - - + + + + - - - - - - - - - + + + + + + + + + - + - - - + + + + - - - - - - + + + + + - - - + + + - - - - - - - + + + + + + + - - - - + + + + - - - + + + - - - - - - + + + + + + - - - - + + + + + - - + - - + + - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + + - - - - - - + + + + + - - + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + - - + + - + + - - + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - + - + - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + - - + - - + + - + - - + + - - - - - + + + + + - - + + - - - + + + - + - + - - - + + + - - + + - + - - - - - - + + + + + + - - - - + + + + + - - - - - - + + + + + - + - - - + + + - - + + - - - - + + + + - - - - - - + + + + + + - - - + + + - - - - + + + + - + - - - + + + - - - + + + - + - - + + - - - - - + + + + + - + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + - - - + + - - - - - + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + + - + - - + + - + - - - - - - + + + + + + - - - - + + + + + - - - - - - - + + + + + + - - - - - - + + + + + + - + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - - + - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - + - - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + + - - - + + - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - + + - - - - - - + + + + + + + - + - - - - - + + + + + - - - - + + + + + - - + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - + + + - + - - - + + - - - + + + + - - - + + + - + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - + - + + - - - - - - - - + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - + + + + + + - + - - + - - - - - - - - + + + + + + + + - + + - - - - - - - + + + + + + + - - - + + + - - - - - - - + + + + + + + + - - - - - - - + + + + + + - - - - + + + + - - - - - + + + + + - - + + - - + + - - - + + + - + - + - - - - + + + + - - - - + + + + - + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + + - - - + + - - - + + + - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - + + - - - + - - - - + + + + - + + - - + + - + - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + - - - - + + + - - - - - + + + + + + + - - - - - + + + + - - - - - - + + + + + + - + + - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - - - - + + + + - + - - + + - - + + - - - - - - - - + + + + + + + + + - - - - + + + - - - - + + + - - + + - + - - - - - - - - - + + + + + + + + + + - - - + + + - - - + + + - - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - + + - + - - + - - - - - + + + + + + + - - - - + + + - - - - - + + + + + + + - - + - - - - - + + + + - - + - - + + + + - - - + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + - - + + - + + - - - - - - + + + + - - - - - - - + + + + + + + + - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + - + - + + - - - - - - + + + + + + - - - + + - - - + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - - + + + + + - - - - - - - - + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - + - - + + + - - - - + + + + - - - - + + + + + - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - + + + + + + + + + - - + - - - + + + + - - - + + + + + - - - - - - - + + + + + - - - - - - - + + + + + + + + - - + + - - - + + + - - - - - + + + + + - - + + - - - - - - + + + + + - - - - - - + + + + + + - - - + + + - - - - - + + + + - - - + + + + + - - - - + + + - + - - - - - + + + + + - - - + + - + + + - - - + + + + - - - - - - - - - + + + + + + + - - + + + - + - - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - + - - - - + + + + + + - - - - - + + + + - - - - - - + + + + + + - - - - - + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + - - - - + + - - - + + + - - - - + + + + + - - - + + + - - + + - - + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - + + - - - - - - + + + + + + - + - - - - + + + - - - - - + + + + + + - - - + + + - - - + + - - - - - - + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + - + + + - + - - - + + - + - - - + + + - + + + - - - - - - - - - + + + + + + + + - - - - - - + + + + + - - + + + - - - + + + - - + - - + + - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + - - - - - - - + + + + + + + - - - + + + + - - + - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + + - - - - + - + + - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - - + + + - - - - - - + + + + + + - - + + + - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - + - - + + + - - + - + + - - - - - - - - - + + + + + + + + + - - + + + - - - + + - - - + + + - - - - - - + + + + + - + + - - - + + - - - + + + - - - - + + + + - - - - - - - - + + + + + + + + - + + - - - - + + + + - + - - - - + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + + - - - + + - - + + - - - - - - + + + + + + - - - + + - - + + - - - - - - - + + + + + + + + - - + - - - + + + - - - - - - - + + + + + + + + + - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + - + + - - - + - - + + + - - - + + + - - - - + + + + - + - - + - + + - - - - - + + + + - - - - + + + + + - - - - + + + + - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - - + + + - - - - - - + + + - + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + - + + - - - - - - - - - - - + + + + + + + + + + - - - + + + + + - - - - - + + + + - - - - - - + + + - + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + + + - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + - - - - - - - + + + + + + - - - - + + + + + + + + - - - - - - - - - - - - + + + + + + + + - + - - - - - - - + + + + + + + + - + - - - - - - + + + + + + + + - - - - - + + + - - + + + - - - - - - - - - - + + + + + + + + + - + + + - - - - - + + + + + - - - - + + - - + + + + - - + + - + - - - + + + + - - - + - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + + + - - + - + + - - - - - - - + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - + + + - - - - + + + - + + + - - - + - - - - - - + + + + + + - + + - - - - - - - - - - - + + + + + + + + + + + - - - + + - + + - - - - - + + + + - - - - - + + + - - + + + + - - + + + - - - - - + + + + + - - - - + + + - + + - - - - - - - + + + + + + + - - - - - - - + + + + + + - - + + - - - - + + + + + - - - - - - + + + + - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + - - - - - + + + + + + + - - - - + + + + - - - + + + + - - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - - + + + - + - - - + + + + - - - - + + - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - + + + + + + - - - + + + + - - - - - - + + + + + + + + - - - - - + + + - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + - - + + - - + + + - + - - - - - + + + + + - - - - + + + + - - - + + - + + + - - - - - - + + + + - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - - - + + + + - - - - - - - - + + + + + + + + + + - - - - + + + + + + - - - + + + - - + + - - - - - - + + + + + - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + - - + + - - - - + + + - - - - - - - + + + + + + + + - - + + + - - - + + - - + + + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + + + + - - - - - + + + + - - - - - - - - + + + + + + + - + - + + - - - - - - - - - + + + + + + + + + - - - + + - + + - - - + + + - - - - - - - - + + + + + + - - - + + + + + + - + + - - - - - + + - - + - + + + + - - - - + + + - - - + + + + - - - - - - - - - + + + + + + + + + + - - - - + - - - + + - - - + + + + + + - - - + + - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - + + + + - - - + + + - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + - - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + + - + - - - - - - - - - + + + + + + + + + - - - - + + + - - - + + + + + - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + - - - - + + + + + + - - - - + + + + + - - - - - - + + + + + - + - - - + + + + + - - - - - + - - - - - + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - + + - - + + + - - - - - - + + + + - + + + + - - - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + + - + + - + - - - - - - + + + + - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + - - - - - - - + + + + + + + + + - - + - - + + + - - - - - + + + - - + - - - + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + - - - - - - + + + + - + - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + - - - - - + + + + + + - - - - - + + + + + + - - + + - - - - + + - - - - + + + + - + + - - - - + + + + + + - - - - - + + + + - - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + - - - - + + + + + + - + - + - - - - + + + - - + + + + - - - - - + + + + + + + - - - + - + - - - + + - - - - - + + + + - + + - + + + - - + - - - + + - - - - - + + + + - - - - - - + + + + + + + - - - - + + + - - - + + + + + - - - - + + + + + - - - - + + + - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - + - - - - - + + + + + + - - - + + - - - + + + + - - - - - - - - + + + + + + + + - - - - + + + + - - + + + - - - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + + + - - - - - - + + + + + - - - - - - - - + + + + + + + - - - - - + + + + + + + - - - - - - - + + + + + + + - - + + - - - + + + + - - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + + - - - - - + + + + - - + + + + - - - - + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + + + + - - - + + + + - - - - - + + - - - - - - - - + + + + + + + + + + - - - - - - + + + + + - - - - + + + + + - - - - - - + + + + + - - - - - - - - + + + + + + + + + + - - - - - + + + - - - + + + + - - + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - - - - + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - - - + + - + + - - - + - + - - - - + + + - - - + + + + + + - - + + - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + - - + + - + + + - - - - - - - + + + + + - - + + - - - - + + + - + + - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + - - - + + + - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - - - - + + + + + + - + + - - - - + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + - - - - - + + + + + - - - + + - - - - - - - + + + + + + + + - - - + + + - + + - - - - - + + + - - - + + + + - - - - - - - - - - - + + + + + + + + + + - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + - - - + - - - - - + + + + + + + + - - + + + - - - - + - - - + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - + + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + - + + + - - - - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + - - - + + + + - - - - - + + + + @@ -11929,21 +11923,21 @@ order_start forward;forward;forward;forward - - - - - - - + + + + + + + - - - + + - - - + + + + @@ -11995,12 +11989,12 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; "";"";""; @@ -12036,15 +12030,15 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -12149,8 +12143,8 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; + "";;""; + "";;""; ;;; "";;""; "";;""; @@ -12238,14 +12232,14 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -12927,7 +12921,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -13280,5811 +13274,5811 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;"";""; @@ -19485,32 +19479,32 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/zh_CN.GBK.src b/share/colldef/zh_CN.GBK.src index 4b8c7cb3a11f..898af62f5fc8 100644 --- a/share/colldef/zh_CN.GBK.src +++ b/share/colldef/zh_CN.GBK.src @@ -172,9 +172,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -278,18 +278,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -493,6 +493,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -503,7 +504,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -3595,212 +3595,212 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -3810,348 +3810,352 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4160,89 +4164,90 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4250,100 +4255,99 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4353,82 +4357,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -4436,40 +4438,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -4480,44 +4481,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4528,110 +4529,110 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4641,62 +4642,61 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -4704,68 +4704,67 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -4774,45 +4773,45 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -4820,159 +4819,164 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4981,300 +4985,299 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5282,108 +5285,106 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5392,207 +5393,207 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5600,28 +5601,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5634,23 +5636,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5660,26 +5664,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5688,145 +5691,144 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5838,381 +5840,375 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6223,459 +6219,456 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6683,113 +6676,112 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6797,723 +6789,729 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7524,53 +7522,51 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7578,300 +7574,292 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7879,147 +7867,150 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8028,15 +8019,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8045,7 +8037,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8053,328 +8044,334 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8382,296 +8379,300 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8686,69 +8687,66 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8760,80 +8758,80 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -8842,290 +8840,290 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9134,93 +9132,95 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9230,33 +9230,33 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9268,15 +9268,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9285,82 +9285,82 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9376,201 +9376,201 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9580,868 +9580,868 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10449,46 +10449,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10496,757 +10497,757 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11255,13 +11256,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11269,948 +11271,960 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12218,706 +12232,702 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12925,19 +12935,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12946,142 +12955,140 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13093,362 +13100,364 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13457,37 +13466,37 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13495,194 +13504,199 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13694,56 +13708,53 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13751,186 +13762,187 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13938,283 +13950,281 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14222,516 +14232,527 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14743,257 +14764,250 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -15003,138 +15017,141 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -15142,2133 +15159,2126 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17276,572 +17286,567 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17881,51 +17886,52 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -17933,33 +17939,32 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18149,9 +18154,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -18255,18 +18260,18 @@ order_start forward;forward;forward;forward - - - + + - - - - - - + + + + + + + @@ -18470,6 +18475,7 @@ order_start forward;forward;forward;forward + @@ -18480,7 +18486,6 @@ order_start forward;forward;forward;forward - @@ -21572,212 +21577,212 @@ order_start forward;forward;forward;forward - + + - - - + + + - + - - + + - - + + - + + - + - - + + - + - - + + - + - + + - - + - - + + + - - + + - - - - + + + + - - + - + - + - - + + - - + - - + + - - - + + + - - + + + - - - + + - - + + - - - - - + + + + - + - - + - - + + - + - + - + - - + - + - + - + - + - + + - + - + + - + + - - + - + - + - + @@ -21787,348 +21792,352 @@ order_start forward;forward;forward;forward - - + + + - - + + - - + + - - + + - + - - + + - - - + + - + - - + + + - - + + - - + - + - + + - - - + + - + + - - - + + - + + - + - - + + + - - - - + + + + - + - - + + - + - - + + - + - + - - - - + + + + - + - + + - - - - + + + + - - + - - - + + + - - - + + + + - - + + - + - + - + + - - - - - + + + + + - - - + + - - - + + + + - + - - + + + - - + - + - + - - + - - + - + + - - - + + - + - - + - + + - - + - - + + - + + - + - + + - + - + + - + - + + - - - + + + - + - + - - + - + - - + + - + - - + + + - - + + - + - - + + + - - + - + + - + - + - - + - + - - + + - - - - + + + + - - + @@ -22137,89 +22146,90 @@ order_start forward;forward;forward;forward - - + + - + - - + - + - + - + - + - - + + + - - + + - + + - - - - + + + + - - + + - - + - + + - - - - - + + + + + - - + + - - + - - - + + + - + - - + + + @@ -22227,100 +22237,99 @@ order_start forward;forward;forward;forward - - + + + - + - + + - + - + - - + + - + - + - - + - - - + + + - - + + + - - + + - + - - + + - + - + - - + - - + - + - - + @@ -22330,82 +22339,80 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - + - - + + - + - + - - + + - - + - + + - - + + - - - + + - + + - - + + - - + - - + + - - - + + + - @@ -22413,40 +22420,39 @@ order_start forward;forward;forward;forward - + + - + - + - + - + - - + + - - - + + - @@ -22457,44 +22463,44 @@ order_start forward;forward;forward;forward - + - - - - + + + + - + - - + + + - - - + + - - + - + + - + - + @@ -22505,110 +22511,110 @@ order_start forward;forward;forward;forward - - + + - - - - + + + + - - - + + + - - - + + + - - + - + - + - + - + - - - + + - + - + - + + - - - - + + + - + - + - - - + + + - - - - - + + + + + - + - + + - + - - - + + + + - - + - + + @@ -22618,62 +22624,61 @@ order_start forward;forward;forward;forward - + + - - - + + - + - + - + + - - - + + + - - - + + - + - + + - - - + + - @@ -22681,68 +22686,67 @@ order_start forward;forward;forward;forward - + + - + - - + + - + - - - + + + - - + + - + - + - - + - + - + - + - + - - - - - + + + + + - - - + + + - @@ -22751,45 +22755,45 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - - + + - - + + + - + - - + + - @@ -22797,159 +22801,164 @@ order_start forward;forward;forward;forward - + + - - + + + - - - + + + - - + + - - + + - - - - - + + + + - - + + - + - + - - + + - - - + + + + - - - + + - + - + - + - + - - + + - - - + + + - - - + + + + - - - + + - + + + - - + + + - + - + - - + + + - - - + + + - - - + + + - - - + + + + + - - - + + + - - - + + + - - + - + - - - + + @@ -22958,300 +22967,299 @@ order_start forward;forward;forward;forward + - + - - - + + + - - - + - + + - + - + - - + - + - - - + + + + - + - - - + + + + - - - - + + + + - - - + + + - - + - + - - - + + + - + + - - - - + + + + - + - + - + + - + - + - - + + - + + - - + + - + - - + + - + + - - - - + + + - - - + + - + - - - + + + - + + - - - + + + - + - - + + - + - - - + + + - + - + - - - + + + - - - - + + + - - - - + + + + - + + - + - - + - - + + - - + - + - + - - - + + + - - + - - + + + - - + - - + - + - + - + - - - - + + + + - + - + - + + - @@ -23259,108 +23267,106 @@ order_start forward;forward;forward;forward - - + + + - - + - - + - - - + + - - - + + + + - - + - - + - - - + + + - - - - + + + + + + - - + + + - - - - + + + - - - - + + + + - - + + - + - - + + + - - + + - - - - - - + + + + + - + - + - + - - - - + + + @@ -23369,207 +23375,207 @@ order_start forward;forward;forward;forward + - + - - + - - + + - - - + + + + - + - + - - - + + + - + - - + - - + + - - + + + - + - - + + + - + - - + + - + - + - - - + + + - - + + - + - - + + + - + - + - + - - - + + + - - + - - + - - + + - - + + + - - - + + + - - + + - + - + - - - + + + - + - - - + - - + + + - - + + + - - + + - - - + + - + - + - - - + + - + + - @@ -23577,28 +23583,29 @@ order_start forward;forward;forward;forward + + - - + + - + - + - + - @@ -23611,23 +23618,25 @@ order_start forward;forward;forward;forward + - + + - + - - + + + - + - - - + + @@ -23637,26 +23646,25 @@ order_start forward;forward;forward;forward - - + + + - + + - - - + + - - + - @@ -23665,145 +23673,144 @@ order_start forward;forward;forward;forward - + - + - - + - - + - + - + - - - - + + + - - - + + + - + - - - + + + + - - - - - - + + + + + + - + - + + - - + - + + + - - - + + - + - - + - - - + + + - - - + + + + + - - - - - + + + + + - + + - + - - + - - + + - + + - + - - - + @@ -23815,381 +23822,375 @@ order_start forward;forward;forward;forward + - + + - - - - + + + - - - + + + - - - + + + - + + - - + - + - - - + - + + - - - + + + + - - + - - + + + - - - - + + + - - - - + + + - - - + + - + - + - + + - - - + + - - - + + - - + + + - + + - - + + + - + - + - + - - + + - - - + + + - - - - + + - - + + - + + - - + - - - + + + - - + - + + - - + - + + - - + + - - - + + + + - + - - + + - - + + - - + + + - - + + - - + + - + - + + - - - + - + + + - + - + - + - - + + - + - - + - - + - + + - + - + - - - - + + + - + + - - + - - + - - + + - - - - - + + + + + - + - - + + - - - + + - - + - + - + - + - + - - + - - - + + + + - - - - + + + + - + + - + - + - - + + - - - + - - + + + - - - + @@ -24200,459 +24201,456 @@ order_start forward;forward;forward;forward + - - + + + - - - + + - + + - - - + + - - + + - + - + - - - + + + + - - + + - - + + + - - - + + + - + - - - + + + - - - - + + + - - - - + + + + - + - - + + + - - - + + + - - + + + - - - - + + - + + + - - + - - + + - - - - + - + - + + - - + + - + + - - - - + + - - - + + + - - - + + + - - - + + + - - - - - + + + + - - + - - - + + + + - - - - + + - + + + + - - - + - - + + + + - - - + + - + - - - - + + + - - + + - + - - - - + + + + + + - - - + + + - - - + - - + + - - - - + + + - - + + - + + - - - - + + - + + - - - + + - + + - - - + + - - - + - + + + - - - - + + + - - + - - + + + - - - + + + + - - - - + + + + - + + + - - + + - - + + - - - + + - + + - - - + - + + - - + + + - - + - - + - - + - + + - + - + - + - - + + + - - - + + - + + + - - - + + - - + + - - + - - + + - + - - - + + + + - - - + + + - - - + + + + + - - - + + + - + + - - - + - @@ -24660,113 +24658,112 @@ order_start forward;forward;forward;forward + - + + + - - - - + - + - - - + + + + + - - - + + + + - - + - - + - - - - + + + + + - + - + - - + - - + + - + - - + + - + - - - + + + - - + - + + - - + - + - - + @@ -24774,723 +24771,729 @@ order_start forward;forward;forward;forward - + + + - - - - + + + + - - + + - - - + + + - + + - - - + + + - - - - + + - + - - - + + + + - - + + + - - - - + - + + + - - + + - + + - - + + - + - - - - - + + + + + - - - + + + - + - + - - + + - - - - + + + + + - - - + + + - - + + + - - - - + - + - - - + + + + - - + + + - - + + + + - - - - + + - + + - - - - - + + + + + - - - - - + + + + + - - + + + - - - + + - - - - + + + + - - + - + + - - + + - - + + + - - + + - - + + - + - + + - + - - - + - + - + + + - - + + + - - - + + - - - + + - - - + + + + - - + + - - + + - - + + - + - + - - - + + + + - - - + + + + - + - - + - + - + + - + - - + + + - - - + - + + + - - + + - - - + - - + + + - - - + + + - + - + - - + + - - + - - + + + - - - + - - + + + + - - - - - + + + + - - - - + + + + + - - + + + - - - + + - - - + - - - + + + - - + + + - - + - - + + + + + - - - + - - - + + + - - - + + - - + + + - + + - - + + - + - - + + - - - - - - - + + + + + + + - + - - + + + - - - - + + + - - - + + + + + - - - + + + + - + - - - + + - - + - + - + - + + - - - + + - - + - + + - - - - - + + + + - + - - + + + + - - - + + + - - - - - + + + - - + + - - + + + - - + + + - - - - + + - - + - + + - - + + + + - - - - + + - - + + + - - + - - + - + + - - - - + + + + - - + + - + - + + - - - + + + - - + - + + - - - - + + + - - - @@ -25501,53 +25504,51 @@ order_start forward;forward;forward;forward + + + - - - + + - + - + + - - - - - + + - + - - + + + - - - + + - + - - - + + + + - - - - + @@ -25555,300 +25556,292 @@ order_start forward;forward;forward;forward - + - + - - + - + + - - + - + + - - + - + - - + + + - - - + + + + - - - - - + + + + - - - + + + + - - - - + + + + - - - + + - + - - + - + + - - + + - - + - + - - + + + + - - - + - + + - - - + - + + - - - - - - + + + + + - - - + + - - - - + + - - + + + - - - + - - - + + + + - - - - - - + + + + - + - + + + - + - - - + + + - - - + - - - - + + + - + - + - + + - - + + + - - + + - + - - - + + - + + - - + + - - + + - + + - - - + - @@ -25856,147 +25849,150 @@ order_start forward;forward;forward;forward + - + - - - - + + + + + - - - - + + + + + + - - + - - + - - + + + - + - - + + - - + + - - + + + - - - - + + + - - - + + + + - - + - + + - - - + + - + - - - + + + + - + + - - + + - - - - + + + - - + - - + - - - - - + + + + + + - + + + - - - + + + - - + - @@ -26005,15 +26001,16 @@ order_start forward;forward;forward;forward + + + - - + + + - - - @@ -26022,7 +26019,6 @@ order_start forward;forward;forward;forward - @@ -26030,328 +26026,334 @@ order_start forward;forward;forward;forward + + - - - - + + + + - + + - + - - - - + + + + + - - - - + + + - + - - - + + + - - + - + - + - - + + + - - - + - + + - - + - + + + - - - - + + + - + - - + - + + - - + + - + + - - - - + + + + - + - + - - + + + - - + + - - - - + + + + - - - + + + + - + + - - + - - + - + + - + + - + - - - + + + - - - - + + + + - - + + - - + + + - - + + - - + + - + + - - + - - - + + - + - + - - + + + + - + - + - - + - - + - + + - - + - - + + - + + - + - - + - - - - - - + + + + + + - + - + - - - + + + + + - - - + + - @@ -26359,296 +26361,300 @@ order_start forward;forward;forward;forward - + - - - - + + + + + + - + - - - + - + + + - - + - + - - + - - + + + + - - + - + + - - + + - - + + - - + - + + - - + + - + - + + + - - - - - - - + + + + - + + - - + + - - - - + + + + - - - + + - - + + + - - + + - - + - + + - - + - - - - + + + + - + + - - + + - - - - - + + + + + + - - + + - + + - - - + - + - + - + - - - + + - - + - + + - + + - - + - + + - - + - - - + + + - - - + + + + - - - + + + - + - + + + + - - - - + + + + - - - + + - + - - + - + + - + + - - + + - - + - + + - - + + - - + + + - - @@ -26663,69 +26669,66 @@ order_start forward;forward;forward;forward + - + + - - + - - + + + - - + - - - + + + - - - + + + - - - - - - + + + - - + + + - - - - + + + - @@ -26737,80 +26740,80 @@ order_start forward;forward;forward;forward + + + - - - + - + + - - + + - - - + + + - + - - + + - + - - - + + + - + + + - - - + + + - - + + - - - + + - - - + + + + - - - - + + - - - - - + + + @@ -26819,290 +26822,290 @@ order_start forward;forward;forward;forward + - + - - - - + + + - - - + + - + + - - + - + + - + - - + + - - + - - - - + + + + + - - - + + + - - + + - + - + - + + - - - - - + + + + - + + - - + - - - - - + + + + - - + + - - + - - + + + - - + - - + - + + - - - + + - - - + + - + + - - - - - + + + + - + - - + + + - - + + - + - + - - + - + - + + - + - + + - - - + + + - - + + - + - - - - + + + + + - - - + + - - - + + + + + - - - + + - - + - + + - + + - - + - + + + - - - + - + - - + + + + - - + - - - + + + - - + + - + + - + - @@ -27111,93 +27114,95 @@ order_start forward;forward;forward;forward + + - - + + - - - + - + + + - - - + + - + - - + + + + - - + - + - - - + + + - - - + + + - + + + - - - - - + + + + - - + @@ -27207,33 +27212,33 @@ order_start forward;forward;forward;forward + + + - - - + + + - + - - - + - + - - - - + + + @@ -27245,15 +27250,15 @@ order_start forward;forward;forward;forward + + - + - - - - + + @@ -27262,82 +27267,82 @@ order_start forward;forward;forward;forward - - + + + + - - + + - - - + + - - - + + - - - - - + + + + - + - + - + - - + + + - + + + + - - + + - - + + - - - + + + - + - - - + + - - @@ -27353,201 +27358,201 @@ order_start forward;forward;forward;forward + + - - + + + - - - - + + + + - - - - + + - - + + + + - - + + - + + - - - + + - - + + - - + + - - + + - - - + + - + - - + + + - - + + - + - - + + - - + - - + + + - - - + - + + - + - - - + + + + - - - + + + - - - + - + - + - + - + + + - - - - - + + + - - - + + + - - + + - - - + + - + - + + + - + - + + - + - - + - - - + @@ -27557,868 +27562,868 @@ order_start forward;forward;forward;forward - + - + + - - + - - - - + + + + - + - + + + - - - + + - - + + + - - + - + + - - - - + + + - - - - - - + + + + - + + - - + + - - - - - + + + + + - - + - - - - + + + + - - + + - + - - + + - - + + - + + - - - + + - - + + - - + - - + + - + - - - + - - - + + + - + - - + + + - - - + + - - - - + + + + + - - - + + + - - - - + + + - + + + - - + - + + - - - - - - + + + + + - - - + + + + - - - - + + + - - - + + + - + + + - - - + + - + - + - + - + + - - - + + + - - - + - + - + - + - - - - + + + + + + - - + + + - - - + + - - - - + + + - - + + + - + - - + + + - - + - + - - + + + - - - + + + - - + - + + + - - - + + + + - - - - + + - + + - - - - - + + + + - - - - + + + + - - + - + + - - - + + + - - + + + - - - + + - - + + + + - - - + + - - - - + + + - + + + - - + - - + + - - + + + - - - + - + + - - + + - - - + + + + - - + + - + - - + + + - + + - - - + - - + + + - - - + - + + + - - - + + - + + - - - - + + + - - + + - - + - - + + + + - - - + - + - + - - + + - + - - + - + + + - - + + - - + - + - - + + + + - - - + + - - - + + + - - + + + - + + - - + - - + + + - - - - + + + - - + - + + - - + - + + + - - + - - - + + + + + + - - - + + - + + - - - + + - - - + + - - - + + + - - - + + - - + - + - - + + - - + - - - - + + + + - - + - + + - - - + - - - - + + + + + + - - - - - + + - + - - + - + + - + + - - + - + + - + - + - + - + + - - - + + + + - - - + + + + - - - + + - - + + + - - - - - + + + + + - - + + + - - + + - - + + - - - - + - - - - + + + + + - - + + + - - + - + - @@ -28426,46 +28431,47 @@ order_start forward;forward;forward;forward + - + + - - - - - + + + + + - + - + + - - - + + - + - - - - - + + + + + - - + - + @@ -28473,757 +28479,757 @@ order_start forward;forward;forward;forward - + + - - + + - - - + + + - - - + + + - - - + + - + + - - + + + + + - - - + + + - - + + - - + - + - + + - - + - + + - + - - - + - - - + + + + - - - - + - - + - - + - + + - - + - + + - + - - + - - + + - - - + - + + + + - + - - + - + + - - - - + - + + + - - - + + - - + + + + - - - - + + + - - + + - - - - + + - + - + + - + - - - + + - - + + - + + - - + + + - + - - - + + + + - - + + + - - + - + - - + + - + - - + + + - + - - + - - - + + + - - - + + + + + - - - + - - + + - + - + + + - - - - - + + + + - - - + - + - - + - - - - - + + + + + - + + - + - + - + + - + - - - + + + - - + + + - - + - + + + - - - + + - + - + - - + + + - - - + + + + + - - - - + + - - + + + + - - - + + - + - + - - + + - - - + + - + + + - - - + + + + - - - + + - - - + + + + - - - - + + + + - - - + + + + - - + + - - - + + + - - - + - - - - + + + + + - - - - + + + + + - - - - - + + - + + - - - + + - + - - + - + + + - + + - - + - - + + + + - - - - + - + + - - + + + - - - - - + + + + + - + - - + + + - - + + - + - - - + + + - - + + - + - - + - + + + - + - + - - - - + + - - + - - + + + - - - - + - + + + - + + - - - - - + + - + - + - - + + - - + - + + - - + - - - + + + - + + - + + - - + + + + - - + + + - - - - - - + + + + - - + - - @@ -29232,13 +29238,14 @@ order_start forward;forward;forward;forward + - + - + @@ -29246,948 +29253,960 @@ order_start forward;forward;forward;forward - + + - + + + - - + + + - - - + - + + - + - + - - + + - + - - + + - + - - - - - - + + + + + + - - + + + - - - + + - - + + - + + - + - - - - + + + - - - - + + + + + - - - - + + + - + + + - - - - + + + - + - + - - - + + + - - - - + + + + - - - - - + + + + - + + + - - - - - + + - + - - - - + + + + - - - + + + + + - - - - + + - + - + + - - - + + + + + - - - + + - + - + + - - - - + + + - + - - + + + + - - + + - - - - - + + - + + - + + + - - - - + + + + + - - - + + + - - - + - + - - + + + - - + + + - - - + + + - - - + + - - + - - + + - - + - + - + + + - + + - - + + - - - + + - - - + + + - + + - - - - + + - + - - - + + + + + - - - + - - - - + + - + + + - - + - + - - + + + + - - - - + + + - - - + + + + + - - - - + + + + - - - + - + - + + - - - + - + - - + + - + + + - - - - + - + + - + - + + - - - - + - + + + - - - - + + + - + + + + - - - + - - + - - + + + - - + + + + - + + - - - - + - + + - - - - - + + + + + + + + - - - + - - + + - - + + + - + + - - - - + + - + + + - - + + + - - - + + + - - + + + - - - - + + + - - - + + + + + - - - - + + + + + - - - + + + - + - + - + + + - + + - - - - + - + + + + - - + + - + - - - + - - - + + + - + + + - - - - - - + + + + - - + + - - - - + + + - - - + + + + + - - - - - + + + + - - + + + - - - - - + + + + - - + - + - + - + + + - - - - - + + + + - - - + + - + - + + + - - - + - + + + - - - - + + - - - + - + + - - + + + - - + - - + + - + + - - - + + + - - + + - - + + + + + - - - + - - + + - - - + + + - - + + - - + + + - + + + - - - - - + + + - + - - + + + + + - - - - - + - + + - - - + + + + - - - - + + + + + - - - - - + + - + + - + + - - - + + - + + + + - - - - + - - - - + + + + + - + - - - + + + - - - + + - + + + - - - - - + @@ -30195,706 +30214,702 @@ order_start forward;forward;forward;forward - - + - - + + + - - - - - + + + + + + + - - - - + + + - - + + + - - - - + + - - + + + + - - + - - + + + + - - - - - + + + - - + + + - - - - - + + + + + - - - + + + - - - - - + + - - + + + + + - - - - - + + + + - - - - - + + + + - - + - + + + - - + + - - - - + - + + + - - - - + - + - + - - + + + + - - - - - - + + - + - - - + - + - - + + + + - - + + + - - + + - - - - + + + + + - - - - - + + + - - - - + + + + - - + + + - - - + + - - - - + + + - + + - - + - - - - - + + + + + - - - - - + + + + + + - + + + - - - - + + + + + - - - - + + - - + + - - + + - + + - + + - - - - + + + + - - - - - + + + - + - - + + + - - - - - + + + - - + + - + + + - - - - + + + - - - + - - + + + - + - + + - - - + + - - - + + - - + + - - + - + - + + - - + + + - + - - + + + - + - - + - - + - + + - - + + + + - - - + + - - - + + + - - - - + + + - + - + + - + + - - - + + + + + - - - - - + + + + + + - - - - - + - - + + + - + - + - + - - + + + - - - - + + + + - - + + + - - - + - + + - - + - + + - - + - + + + + - - + - - - + - - + + + + - - + - + - + - + - - - + + + + - - - - + + - + - + - + - - - + + - + + - - + - - + + - - - + + + + - - - - + + + + - - + + - - - - + - + - + + - - - + + + + + - - + - + + - - + - - - + - + + + + + - - - + - - + + + - + + + - - + - - @@ -30902,19 +30917,18 @@ order_start forward;forward;forward;forward - + + - + - - @@ -30923,142 +30937,140 @@ order_start forward;forward;forward;forward + - + + - + - - + + + + - - - + - + - - - - + + + + - + - - + - - + + + - + - - + + - - - + + + - + + - - - - + + + - - + - - + - + + - - - + - + - - + + + - + + - - + - - - - - + + - - - + + + + + - - - - - + + + - + + - + + + - - - + - - + + - + @@ -31070,362 +31082,364 @@ order_start forward;forward;forward;forward - + + - + + - + - + + - + - + - - - + + + - - - - - + - + + - - + - + + + - - + - + + - - - + + + + - - + - + - - + + - + - + - - + + + - - - - - + + + + + - + - + - - + + + - - - + + + - - - + + + + - - - - + + + - - - + + + + + - - - - - + - + + + - - + + + - + - - + + - - - - + + + + - - - + + - - + + - + + + - - - - - + + + - - - - - + + + + + + - + + - - - - - - + + - + + + - - - + + + - - + - + + - - + + - + - - - + + + + + - - - - + + + - - - + + + + - + - + - - - + - + - - + + - + + + - - + - - - + - + + - + - - + + + - + - - - - + + + + + - - - + - - + @@ -31434,37 +31448,37 @@ order_start forward;forward;forward;forward + + - + - + - - + + - + + - - - - + + + - - - + @@ -31472,194 +31486,199 @@ order_start forward;forward;forward;forward - - + + + - - - + + + - + + - - + + - - + - - + + + - - + - + - - + - - + + + + + - - + + - - + + - - + + - + - - - + + + - + + - - + - + + + - + + - - + + + - + + - - - - - + + + + + - - + - + - - + + - + + + + - - - - + - + - + + + - - + - - - + + + + - - + - + + + - - - + + - - - + - - + + - + - + + + - - - - @@ -31671,56 +31690,53 @@ order_start forward;forward;forward;forward + + - - + + + - - - + + - + - + + - - - + - + - + + + - - - - + + - - - + + + - - - - @@ -31728,186 +31744,187 @@ order_start forward;forward;forward;forward + + + + - - - - - + + - - - + + + + + - - + + + - - - - + + - - + + - - - + + + + + + - - - - + - + + - - + - - + - - + + + + - - + - - + + + - - + - - - + - + - - - + + + + + - - - + + + - + - - + + + - + + - - - + - - - - - - + + + + + + - - + - + + + - - - + + + - - - + - + + + + - - + + - + - - - - - + + - + @@ -31915,283 +31932,281 @@ order_start forward;forward;forward;forward + + - + + - - - + + + - + + - - - + - - - + + - + + - + + + - - + - - - + - - + + + - - + + + + - - + - - - - - + + - + + + + + + - - - + + - - - + - + - + - + + + - - - - + + - - - + - - + + + + - + - + - - + - + - + + - + - - - - + - + + - + - - + + + - - - - - - + + + + - - - + + + - + + - - + + + - - - + + - - - + - + + - + + + - - - + + + + - - - + + - - - - + + + + - - - - + + + + + - - - + - + - + - - - + + + + + - - - - + + + - - + - - + + - - - + - + + + - + + + - - - - @@ -32199,516 +32214,527 @@ order_start forward;forward;forward;forward + + + + - - + + - - + + - - - - + + + - + + + + - - - - + + - + + - + + - - - + + - - + + - + + - - + + + - - - + + + + - - - - + + + + - - - + - - + + - + + + - + - + - - + - + + + - - + + - + + + + - - - + + - - - - + + + + - + + - - + - - - + + - - - + - + + - - + - - + + - - - - + + + + + + - + - + - - + - + + + - - + - + + - - + + - - - + - - + + + + - + + - - - - + + + - + - + + + - + - + + - - - - - + + + - - + - - + + + - - - + - - + + - + - + - - + - + + + + - + - - + - + + - + + - + - + + - - - - + + + + + + - + - - - - + - - - + + + + + - - - + - - - - + + + + - - + + + - - - - + + + - - + + + - - + + - - + + + + - - - + - + + - - + + - + + - - - + + + - + + - + - - - + + - + - - - + + + + + - - - - + + - - - - + + + + - - - - + + + - - - + + + - + - - - + - - + + + + - - + + - + - + + - + - - - + - + + + - - - - + + + - - - - + - + + + - - + + - - - @@ -32720,257 +32746,250 @@ order_start forward;forward;forward;forward - + + + + + - - + - - + + + - - - - + + - - + + + - - - - + + - - - - + - + - + - - + + - + - + + + - - - - + - - - + + - - - + + + - + - - - - + + - + + + - - + + + - - - - + - + + + - - - + + + - + - - + + + + + - - - - - - + - - - + + + - - - - + + + + + + + - - + + - - - - - + - + + + + - - - + + + + - - - - + + - - + + - - - - + + - - + + + - - + + + + - - - + + + + - - - - + - - - + + @@ -32980,138 +32999,141 @@ order_start forward;forward;forward;forward - - + - + - - + + + + - - + + - - + + - - - + + + - + - + + - + - - + - - + + - - - + + + - + + - - - + + + - - - + + - + - + + + + + - - - - - + - - - + + + + + + - - + - - + - - + + + - + - - - - - + + + + + - - + + - - + + @@ -33119,2133 +33141,2126 @@ order_start forward;forward;forward;forward - - - + + - - - + + - - - - + + + + - - - + - + + + - - + + - - - + - - + + + + - - - - - - - + + - - + + + - + + - - - + + + - - + + - + + - - + + + - - - + + - + + - + - - - + + - + + + - + + + - - - - - + + + - - - - - + + + + + - - + + + + - - + - + - - + + - - - - - + + + + + + + - - - - + + - - - - + + - + + - + - - + + - + - - + + + - - - + - - + + + + + - - - - - - + + + + - + - - - + - + + - - - - + + + - + + - - - - - - + + + + + - - - + + + + - - - + - - + + + + + - - + + - + - - - - - - + + + + + + + - + - - - - + - + + + + - - - - + - - + + + + + - - - + + + + + + - - - - - + - + + + + - - - - - + - - - + - + + + - + - + + + + + - - - - - + + - - + + + - - + + - - + - - - + + - - + + + + - + + + + - - - - + + + - - + - - - - - - + + + - - + + - - + + + - - - + - + + + + - + - - - - - + + + + - + - + - + - - - - + - + + + + - - - + + + + - - - - - + + + + - - + + + - - - + + + - - + - - + + + + - - + + - - - + - + - + + - - - - + + + + + - - - - + + + + - - - + + + - + - - + - + + - - + + - + + - - + + - - + - - + + + - - - - - + + + + - + + - - - + + + - + + - - - - + + - - + + + - - + + + - - - + + + - - + + + - - - + + + + - - + + + + - - - + + - - - + - + + - - + + + - + - - - - - - + + + + - + + - + + - + - - - - - - + + + - + + - - + - - + + - - + + - + + - - + - + - + + - + - + + - - - + + + + - - - - - + - - - + + + + - - - - + + - + - + - + + - - - + + + - - + + - + - + + - - - - + + + - - - - + + - + + - - + + + - + + - - + + - - - - - - + - - - + + + + - - + + + - - + + - - - + + + + + - - + + - + + - - - + + + + - - - - + - + + + - - + + - - - + - + + - + + + - - - + + + + - - - + - + + + - + - - + + + - - - + - - + - + + + + + - - - - - - + + + - + - - + + + - - - + + + + - - + + - - + - - - + + + + + - + - - - - + + + + - - - + - + - + + + - + - - - + - - - - + + + + - + - - - - + + - + + - + - + - - + - + - + + + - + - - + + - - + - + + - - - - + + + - + - - - + + + + - + + - - - + + + + - - + + - - + - + + - - + + + - - + - - - - + - + + - - - - + + - + + + - - - + - - + + + - + - - + + - + + - + + + - - + + - - - + + + - + - - - + + + + - - - + - - - - - + + + + - - + + - - - + + + + + + - - - + + - + - - - - + + + - + - - - + + - + + + + + - - - - + + - - + + + - - - - + + - - + + + - - - - + + - + - - - + + - + - - + - + + - - + - + + + + - + - - - + + + + - - + - - + + - - + - + + + - + + + - + + - - - - - - + + + + - - + + - - - - - + + + + - - - - - + + + - + - - - - - + + - + + + + + - - - - + + - - + - - + + + + + + + - - - - - - + + - - - + - + - + + + + - + + - - - - + + - - - - + + + + - - + + + + - - - + - + + + - - - - - + - - - + + + + + - - - - + + + - - + - + - - + + + + + + - - - + - - - + + + - + + + - - - - + + + + + - - - + + + - - - + + + + - - - - + + + - + - - - + - + + - - + + + + - - + - - - + + - + + + - - - + + - - - - - + + + + + - + + - - - - - + + - - + - + - + + + + + + - - - - - - - + + - - - - + + + + + - + - + + + - - - + + + + - - - + - - - - + + + + - + + - + - - - + + - + + - + + - - - - - + + + - + - + + + + - - - - + - + + + - - - - + - - - + + + + + - + + - + - - - - + + + - - + + - - - - + + - - + + + - - + + + - - - - + - - + + + - - - + + + + - - + + + + + - - - - - - + - + + - - - + + + - - - + - + - - + + - - - - - - + + + + + - - - + + - - - - + + - + - - - + - + - - + + + + + - - - - + - - + - + - + - + - + + + + - - - + - - - + + - - + + + + - - + + + + - - - + + + + + - - - - + - - - - - - + + + - - + + + - + + - - + - + - - + - + + + - + + + - - - - + + + + + - - - + - - + + - + + + - - - - - - + - - - + + + + - + + + - - - - + + - - - + + + - - + + - + - + + + + - - - - - + + + + - + - - - - - @@ -35253,572 +35268,567 @@ order_start forward;forward;forward;forward - + + - + - + + - + - - + + - + - - - + + + + + + + - - - - + - + - + + + - - - + - - + - + + - + - - - + - + + + + - - + + + - - - - - - - + + - - + - + + - - + + + + - - - - + + + + + + - - - - - - + - - + + + + - - - + + + + - + + - - - - - + + + + - - - - + + + + + + - - - + + - - - + - + - + - + - + - + + - - - - + + + + - - - + + + + - - - - - + - + - + + - + + + + - - - - - - + + - - - + + + - - + + + - + - + - + + + + - - - - - + - - + + + + - - - - + + + + - - - + + + - + - - - - - + + + - + + + - - + - - - - - + + - - + + + - - - - + + + + - + + - - - - + + + + - + - - - - + + + - - - + + - + - + - - - - + - + - + + - + - - - + + + + + - - + + - - + + + - - + + - - - - - + + + + - - - - + + - - + + + + - - + - + - + + - - + - - - - + + + + + - - - - - + + + + - - - + - - + - - - + + + + + - - + + - - + + - - - + + - + - - + - + + + + + + - - - - + + + + - - + + - - - + - - + + + - - - + - + + - - - + + + + - - @@ -35858,51 +35868,52 @@ order_start forward;forward;forward;forward - + - - - + + - + - + + + - + - - + - + - - - + + + + - - - - - + + + + + @@ -35910,33 +35921,32 @@ order_start forward;forward;forward;forward - - + - + - - - - + - - - + + - + + + + + @@ -36049,15 +36059,15 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -36101,16 +36111,16 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -36265,8 +36275,8 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; + "";;""; + "";;""; ;;; "";;""; "";;""; @@ -36416,22 +36426,22 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - ;;; - "";;""; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + "";;""; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -38336,7 +38346,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -39445,18003 +39455,18003 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;"";""; @@ -57870,32 +57880,32 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/zh_CN.UTF-8.src b/share/colldef/zh_CN.UTF-8.src index 0142ae6982cb..db468dfd175d 100644 --- a/share/colldef/zh_CN.UTF-8.src +++ b/share/colldef/zh_CN.UTF-8.src @@ -151,9 +151,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -183,7 +183,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4145,56 +4145,55 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4206,79 +4205,79 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4289,47 +4288,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4340,26 +4339,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4370,8 +4369,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4386,7 +4385,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4398,103 +4397,103 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4502,16 +4501,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4519,35 +4518,35 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4562,157 +4561,157 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4723,13 +4722,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4739,34 +4738,34 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4777,25 +4776,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4804,20 +4803,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4826,29 +4825,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4858,49 +4857,49 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4916,26 +4915,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4952,21 +4951,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4975,12 +4974,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -4996,20 +4995,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5018,11 +5017,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5032,31 +5031,31 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5064,72 +5063,72 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5141,11 +5140,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5153,7 +5152,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5171,13 +5170,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5188,31 +5187,31 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5221,17 +5220,17 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5242,121 +5241,121 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5364,7 +5363,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5374,14 +5373,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5390,29 +5389,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5421,23 +5420,23 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5448,74 +5447,74 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5524,50 +5523,50 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5575,62 +5574,62 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5639,48 +5638,48 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5696,9 +5695,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5709,65 +5708,65 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5782,23 +5781,23 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5807,18 +5806,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5827,76 +5826,76 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -5912,199 +5911,199 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6115,8 +6114,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6125,29 +6124,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6156,43 +6155,43 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6201,58 +6200,58 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6261,8 +6260,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6271,20 +6270,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6293,43 +6292,43 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6337,47 +6336,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6396,93 +6395,93 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6491,8 +6490,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6500,8 +6499,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6509,17 +6508,17 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6531,13 +6530,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6550,25 +6549,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6578,43 +6577,43 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6623,10 +6622,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6635,99 +6634,99 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6735,40 +6734,40 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6780,21 +6779,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6804,59 +6803,59 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6864,32 +6863,32 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -6898,81 +6897,81 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -6980,67 +6979,67 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7050,149 +7049,149 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7201,11 +7200,11 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7218,26 +7217,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7249,411 +7248,409 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7662,148 +7659,148 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7811,134 +7808,135 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -7946,40 +7944,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -7987,171 +7984,171 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8159,344 +8156,344 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8505,199 +8502,199 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8709,89 +8706,89 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8812,68 +8809,68 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8882,10 +8879,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -8894,301 +8891,301 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9199,135 +9196,135 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9336,39 +9333,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9377,28 +9374,28 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9414,213 +9411,213 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9635,96 +9632,97 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -9733,64 +9731,63 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9798,30 +9795,30 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -9829,204 +9826,204 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10038,32 +10035,33 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10072,79 +10070,78 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10159,18 +10156,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10178,39 +10175,39 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10223,14 +10220,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10246,300 +10243,300 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10547,103 +10544,103 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -10654,29 +10651,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10684,110 +10681,110 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10795,25 +10792,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10822,10 +10819,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10840,15 +10837,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10857,96 +10854,96 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -10966,148 +10963,148 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11117,202 +11114,202 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11320,397 +11317,397 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -11718,15 +11715,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11737,57 +11734,57 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -11800,325 +11797,325 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12128,6 +12125,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12135,21 +12133,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12163,6 +12160,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12170,27 +12168,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12201,67 +12198,67 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12269,147 +12266,145 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12417,411 +12412,411 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12829,116 +12824,117 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -12946,26 +12942,25 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -12975,65 +12970,65 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13047,79 +13042,79 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13128,37 +13123,38 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13167,78 +13163,77 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13254,6 +13249,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13262,7 +13258,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13270,44 +13265,45 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13316,49 +13312,48 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13366,173 +13361,174 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -13540,48 +13536,47 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13591,59 +13586,59 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13651,75 +13646,75 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13727,20 +13722,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13748,46 +13743,46 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -13796,206 +13791,206 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14005,97 +14000,98 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -14104,430 +14100,431 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14535,333 +14532,332 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14869,80 +14865,79 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -14950,336 +14945,337 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -15294,110 +15290,109 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15406,13 +15401,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15421,45 +15417,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15468,60 +15463,61 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15529,235 +15525,234 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15769,86 +15764,88 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15856,130 +15853,128 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -15987,71 +15982,72 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16060,125 +16056,124 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16193,59 +16188,59 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16253,152 +16248,153 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16406,73 +16402,73 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16482,113 +16478,113 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16598,9 +16594,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -16610,279 +16606,277 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16892,43 +16886,43 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -16942,278 +16936,278 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17221,224 +17215,224 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17448,291 +17442,291 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17743,177 +17737,176 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -17921,193 +17914,195 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18115,275 +18110,273 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18392,44 +18385,44 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18438,506 +18431,506 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -18946,6 +18939,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18953,8 +18947,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -18962,137 +18957,136 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -19100,20 +19094,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19123,175 +19117,175 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19299,58 +19293,58 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19361,175 +19355,175 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19544,29 +19538,29 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -19576,244 +19570,245 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -19821,298 +19816,298 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20122,95 +20117,93 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20220,15 +20213,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -20236,75 +20232,72 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20314,6 +20307,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -20321,7 +20315,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20332,134 +20325,134 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20469,30 +20462,31 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -20500,642 +20494,643 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -21174,17 +21169,17 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol @@ -21282,9 +21277,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -21314,7 +21309,7 @@ order_start forward;forward;forward;forward - + @@ -25276,56 +25271,55 @@ order_start forward;forward;forward;forward - - - + + - + - + - + - + - - - + + + - + - + - - + + - - + + - + - - + + @@ -25337,79 +25331,79 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - - + + - - + + - + - + - + - - - + + + - + - + - + - - + + - + - - - + + + - + - - - - + + + + @@ -25420,47 +25414,47 @@ order_start forward;forward;forward;forward - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + @@ -25471,26 +25465,26 @@ order_start forward;forward;forward;forward - + - + - + - + - + - + @@ -25501,8 +25495,8 @@ order_start forward;forward;forward;forward - - + + @@ -25517,7 +25511,7 @@ order_start forward;forward;forward;forward - + @@ -25529,103 +25523,103 @@ order_start forward;forward;forward;forward - - - - + + + + - - - + + + - - + + - + - + - + - + - + - + - - + + - - - + + + - - + + - + - + - - - + + + - + - + - + - + - + - + - + - + - + - + - - - - + + + + - + - + - + - + - + @@ -25633,16 +25627,16 @@ order_start forward;forward;forward;forward - + - + - - + + @@ -25650,35 +25644,35 @@ order_start forward;forward;forward;forward - + - - - - - - - + + + + + + + - - + + - - - + + + - + - - - - - - + + + + + + @@ -25693,157 +25687,157 @@ order_start forward;forward;forward;forward - + - + - - - - - - - + + + + + + + - - + + - + - + - + - - - - + + + + - + - + - + - - - + + + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - - + + - + - + @@ -25854,13 +25848,13 @@ order_start forward;forward;forward;forward - - - + + + - - + + @@ -25870,34 +25864,34 @@ order_start forward;forward;forward;forward - - - - - + + + + + - + - + - + - - + + - + @@ -25908,25 +25902,25 @@ order_start forward;forward;forward;forward - - + + - - - - - - - + + + + + + + - + - + @@ -25935,20 +25929,20 @@ order_start forward;forward;forward;forward - - + + - + - + - + @@ -25957,29 +25951,29 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - + @@ -25989,49 +25983,49 @@ order_start forward;forward;forward;forward - - - - + + + + - + - - + + - + - + - + - - - - - - - + + + + + + + - + - + - + - + - + - - + + @@ -26047,26 +26041,26 @@ order_start forward;forward;forward;forward - + - + - + - + - + - + - - + + @@ -26083,21 +26077,21 @@ order_start forward;forward;forward;forward - - - + + + - - - + + + - + @@ -26106,12 +26100,12 @@ order_start forward;forward;forward;forward - - + + - + @@ -26127,20 +26121,20 @@ order_start forward;forward;forward;forward - - + + - + - + - + @@ -26149,11 +26143,11 @@ order_start forward;forward;forward;forward - + - + @@ -26163,31 +26157,31 @@ order_start forward;forward;forward;forward - + - + - + - + - + - + @@ -26195,72 +26189,72 @@ order_start forward;forward;forward;forward - + - + - + - + - - + + - + - + - + - + - + - + - + - + - - + + - + - + - + - + + - @@ -26272,11 +26266,11 @@ order_start forward;forward;forward;forward - + - + - + @@ -26284,7 +26278,7 @@ order_start forward;forward;forward;forward - + @@ -26302,13 +26296,13 @@ order_start forward;forward;forward;forward - + - + @@ -26319,31 +26313,31 @@ order_start forward;forward;forward;forward - + - - - + + + - + - - + + - + - - + + @@ -26352,17 +26346,17 @@ order_start forward;forward;forward;forward - + - + - - - + + + - + @@ -26373,121 +26367,121 @@ order_start forward;forward;forward;forward - + - + - + - - - + + + - - + + - + - - + + - - + + - - + + - + - + - + - + - - + + - + - + - + - + + - - + - + - + - + - - - + + + - + - - - + + + - + - + - - + + - - - + + + - - + + @@ -26495,7 +26489,7 @@ order_start forward;forward;forward;forward - + @@ -26505,14 +26499,14 @@ order_start forward;forward;forward;forward - + - + - - + + @@ -26521,29 +26515,29 @@ order_start forward;forward;forward;forward - + - - + + - + - + - + - - + + @@ -26552,23 +26546,23 @@ order_start forward;forward;forward;forward - + - + - - + + - + - + @@ -26579,74 +26573,74 @@ order_start forward;forward;forward;forward - + - + - - + + - + - - - + + + - - + + - + - + - + - + - + - + - - + + - - - + + + - + - - + + @@ -26655,50 +26649,50 @@ order_start forward;forward;forward;forward - + - + - + - + - + - - + + - - + + - - + + - - - + + + @@ -26706,62 +26700,62 @@ order_start forward;forward;forward;forward - - - + + + - - - - + + + + - + - - - + + + - - + + - - - - - - - + + + + + + + - - + + - - + + - + - - + + - + - + - - + + - - + + @@ -26770,48 +26764,48 @@ order_start forward;forward;forward;forward - + - + - + - - + + - - + + + - + - + - + - @@ -26827,9 +26821,9 @@ order_start forward;forward;forward;forward + - @@ -26840,65 +26834,65 @@ order_start forward;forward;forward;forward - - + + - + + - - - - + + + - + + - - - + + - - + + + - - - - + + + + - + - - - + + - - + + + - + - - - + + @@ -26913,23 +26907,23 @@ order_start forward;forward;forward;forward + - + - - - - + + + + - @@ -26938,18 +26932,18 @@ order_start forward;forward;forward;forward + - - + + - @@ -26958,76 +26952,76 @@ order_start forward;forward;forward;forward + - + - + - + - - - - - + + + + + - - - - + + + + - + - + - - + + - - - + + + - + - - - - + + + + - @@ -27043,199 +27037,199 @@ order_start forward;forward;forward;forward - + + - + - + - - + + - + - + - - + + - - + + - - - + + + - - + + - + - + - - + + - - - + + + - + - - + + - + - - - + + + - + - + - + - + - - - - + + + + - - + + - - - + + - - + + + - + - + - + - + - - + + - + - + - + - + - - + + - - + + - + - + - - - + + + - + - + - - - + + + - @@ -27246,8 +27240,8 @@ order_start forward;forward;forward;forward + - @@ -27256,29 +27250,29 @@ order_start forward;forward;forward;forward - - - - + + + + + - + - + - + - + - + - - - - - + + + + @@ -27287,43 +27281,43 @@ order_start forward;forward;forward;forward - - + + - + + - - + - - + + - - + + + - + - - + + - - - - + + + - + + - + - @@ -27332,58 +27326,58 @@ order_start forward;forward;forward;forward + - - - - - - - + + + + + + - + + - - - - + + + + - + - + - + - - + + - + - + - + - - + @@ -27392,8 +27386,8 @@ order_start forward;forward;forward;forward + - @@ -27402,20 +27396,20 @@ order_start forward;forward;forward;forward + - - - + + + - - - + + + - + - @@ -27424,43 +27418,43 @@ order_start forward;forward;forward;forward + - - - + + + - - - + + + - - - - - + + + + + - + - - - + + + - @@ -27468,47 +27462,47 @@ order_start forward;forward;forward;forward + - + - + - + - + - + - + - + - + - - + + - + - - - - - - + + + + + @@ -27527,93 +27521,93 @@ order_start forward;forward;forward;forward + - + - + - + - + - - - + + + - - - - + + + + - - - + + + - + - - + - - + + + - + - + - - + - - + + + - - - + + + - - + + - + - @@ -27622,8 +27616,8 @@ order_start forward;forward;forward;forward + - @@ -27631,8 +27625,8 @@ order_start forward;forward;forward;forward - - + + @@ -27640,17 +27634,17 @@ order_start forward;forward;forward;forward + - - - + + - - + + + - @@ -27662,13 +27656,13 @@ order_start forward;forward;forward;forward + - + - @@ -27681,25 +27675,25 @@ order_start forward;forward;forward;forward + - + - - + + - - - + + + - - - + + @@ -27709,43 +27703,43 @@ order_start forward;forward;forward;forward + - + - - - + + - - - + + + + - + - + - + - - + @@ -27754,10 +27748,10 @@ order_start forward;forward;forward;forward + - + - @@ -27766,99 +27760,99 @@ order_start forward;forward;forward;forward + - - - + + + - + - - - - - + + + + + - + - - + - - - - + + + + + + - - + - + - + - - + + - + - - - - + + + + - + - - + + - - - + + + - - - + + - - + + + - + - + - - - + + @@ -27866,40 +27860,40 @@ order_start forward;forward;forward;forward + - - - + + + - - + + - + - - - + + + - + - - + + - - - - + + + @@ -27911,21 +27905,21 @@ order_start forward;forward;forward;forward + - + - - - - - - - + + + + + + + - - + @@ -27935,59 +27929,59 @@ order_start forward;forward;forward;forward - + + - - - + + + - + - + - + - - - - - - + + + + + - - + + + - - - - + + + + - + - + - - - - + + + + - + - @@ -27995,32 +27989,32 @@ order_start forward;forward;forward;forward + - + - + - - - + + + - - + + - + - - + @@ -28029,81 +28023,81 @@ order_start forward;forward;forward;forward + - - - + + - + + - + - + - - - + + + - + - + - - + - - + + - - - - + + + + + - - - + + - + + - + - + - - - + + + - + + - - @@ -28111,67 +28105,67 @@ order_start forward;forward;forward;forward + - + - - + + - - - + + + - - + + - - - - + + + + - + - - - + + + - + - + - - + + - - - + + + - + - @@ -28181,149 +28175,149 @@ order_start forward;forward;forward;forward + - + - + - - + + - + - + - + - + - + - - - + + + - + - + - + - + - + - - - + + + - + - - - + + + - + - + - + - - - + + + - + - - - - + + + + - + - + - + - + - + - + - - - - - - - - + + + + + + + @@ -28332,11 +28326,11 @@ order_start forward;forward;forward;forward + - - + + - @@ -28349,26 +28343,26 @@ order_start forward;forward;forward;forward + - - - - + + + + - - + + - @@ -28380,411 +28374,409 @@ order_start forward;forward;forward;forward + - - + - - + + + - - + - - + + + - - - + - + + - - + - + - + + - - + + - - + - + - + + - - + - + + + - - - - - - - - - - + + + + + + + + + - + - - + + - + + - - - - - - + + + + - + + - - + + - + + - - - + + + - - - + - + + + - - - + - + - + - + + - - - - - - - - + + + + + + + + - + - - + + - + + - - + - + + - - - + - + - + + - - + - - - + + + + - - + + - + - - - + + + + - + - - - + + - + + - - - + + - - + + - - - - - + + + + + - - + - + - + + + - - + - - + + + - - - + + - - - - - + + + + - - - + + + - + - + + + - - - - - + + + - + - + + - - + - + + + - - - + + - - + - + + - - + + + - - - + - + - + - + - + + - - + + - + - - + + + - - + + - - - @@ -28793,148 +28785,148 @@ order_start forward;forward;forward;forward + - + + - - - - + + + + - - + + - - + + + - - + - - + + - - + - + + - - + - + + - - + - + + - - + - + - + + - - + - + + + - - - + + - + - - + - + + + - - - + - - - - + + + + - + + - + + - - + - - + - + + + - - - + - @@ -28942,134 +28934,135 @@ order_start forward;forward;forward;forward + - + - + - + - + + + - - - + + - - + + + - - - + - + - + + + - - - + - + - + - + + - + - - + - + + - - + + - - + - + + + - - + - - + @@ -29077,40 +29070,39 @@ order_start forward;forward;forward;forward - + + + - - - + + + - - - - - + + + + - - + - - - + + + - + - @@ -29118,171 +29110,171 @@ order_start forward;forward;forward;forward + + - - + + - - + - + + - - + + - - + + - - - + + - + - + + + - - + - + - - + - + + - - + + - - - - - - + + + + + - + - + + - - + - + - + + - - + + + - - - + - + - - + + + - - - - - + + + + - + - + + - - + + - + - - + - + - @@ -29290,344 +29282,344 @@ order_start forward;forward;forward;forward + - - - - + + + + - - - + + + + + - - - + - + - + - - - + + + - + - + + - - + + - - - + + + + - - - + - + + - - + + - - - + + - + + - - - + + - + - + + - + - + - - + - + - + + - - + + + - - - + + - - + + - - + + - + + - - + - - + - + + - - + - + - + - + - + + - + - - + - + + - - + + - + - + + - - - + + - - + - - - + + + - + + - - + + - + - - + - + + + - - + - - - - + + + + - - + + - + + - - - + + - + - - - + + + + - - - + - + + - - + + - - + - + + - - + - + + - - + - + + + - - - - + + - @@ -29636,199 +29628,199 @@ order_start forward;forward;forward;forward + + + - - - + + - - + - + + - - - + + + + - - - + - + + - - + + - + - - + + + - - + - - + + - + + - - - + - - - - + + + + + - - - - + + + + - - - + + - + - + - + - + + - + - + + - - - + + + - - - + + - - + + - - + - + - + - + - + + - - - - + + + - + + - - + - + + - - + + - + - - - - - + + + + + - - @@ -29840,89 +29832,89 @@ order_start forward;forward;forward;forward + + - - + - - - - + + + + + - - + + + - - + + - - - + + - - + + - - + - + + + - - - + + - + - - + + - - + + + - - - + - + + - - + - - - + + + - @@ -29943,68 +29935,68 @@ order_start forward;forward;forward;forward + + + - - - + - + + - - + + + - - - + - + + + - - + + - - + - + - - + + + - + - - - + - + - @@ -30013,10 +30005,10 @@ order_start forward;forward;forward;forward + - @@ -30025,301 +30017,301 @@ order_start forward;forward;forward;forward + + - - + - + + - - + + - - + - + + - - + - + + - - - + + + - + - - + - + + - + - - - - + + + - + + + - - - + + - + - - + - + - + - + + - - + + - - + - + + - - + - + + + - - + + - - - + + + - - - + + - + - - + + - - + + + - - + - - + - + + - - + + - - + + - - + - + - + + - - + + - - + + - + - - + - + - - - + + + - + - + - + + - - + + - + - + - - + - + + - + - - + + + - - + - - + - @@ -30330,135 +30322,135 @@ order_start forward;forward;forward;forward + - + + - - + + + - - - + + - - + + - + - + - + - - + + - + - - + + - + + - - - + + - - + + + - - + + - - - + + - - + + - + - - + + - - + + - - + - - - + + + + + - - - - - - - + + + + + - - + + + - - + - + + - - + + - - @@ -30467,39 +30459,39 @@ order_start forward;forward;forward;forward + + + - - - + - + - + + - + - + - - + - @@ -30508,28 +30500,28 @@ order_start forward;forward;forward;forward + + - - + + - - - - + + + - @@ -30545,213 +30537,213 @@ order_start forward;forward;forward;forward + - + + - - + - + + - - + + - + - - + - - + + + - - + - - - - - + + + + + - + - + + - - + + - - + - + + - - + - + + - - - - - + + + + + - - + - + + - - - + + - + - + + + - - - + + - - + - + - + + - - + - + + - - + + + - - + - + + - - - @@ -30766,96 +30758,97 @@ order_start forward;forward;forward;forward + + - - + - - - + + + - - - - + + + + + - + - + + - - + - + + - - - + - + + - + + - - - + - + + - - - + + - + + - - + - + + + - - - + + - - + @@ -30864,64 +30857,63 @@ order_start forward;forward;forward;forward - + - + + - - + + - + - - - - - + + + + - + + - + - + - - + + - - - - + + + - + + + - - - @@ -30929,30 +30921,30 @@ order_start forward;forward;forward;forward - - - + + + + + - - + - + - + + + - - + + - - - @@ -30960,204 +30952,204 @@ order_start forward;forward;forward;forward + + - - + - + + - - + - + - + + - + - - + - + + - - + + - - + - + - + + - + - - + - + + - - - - - - + + + + + - + - - - - + + + + + - - + + - - + + + - - - + - + + - - + + - + - - + - + + - - - - - + + + + + + - - - + + - - + + - - + - + + - + - - + + - - + + - - - + + + - + - + - - + - + + - - @@ -31169,32 +31161,33 @@ order_start forward;forward;forward;forward + + - + - - - + + - + + - - + - - - + + + - + - + @@ -31203,79 +31196,78 @@ order_start forward;forward;forward;forward - + + + - - - + + - - + + - - - + + - + - - - + + + + + - - + - - + - + + + - - + - - + + - - + + - - - - - + + + + - + + - - @@ -31290,18 +31282,18 @@ order_start forward;forward;forward;forward + - + + + - - - + - @@ -31309,39 +31301,39 @@ order_start forward;forward;forward;forward + + - - + - + + - - + + - - + - + - - - - + + + + - @@ -31354,14 +31346,14 @@ order_start forward;forward;forward;forward + + - - + + + - - - @@ -31377,300 +31369,300 @@ order_start forward;forward;forward;forward + + - - + - + + - + + - - - + - + + + - - - + + - - + + - + - - + + - - + + - - + + + - - - + + - - + + - - - - - - + + + + + - - - - + + + + + - + + - - - + - + - + + - - - - - + + + + - + + - - + + - - + - + + - + - - + + - + - - + + - - - + + - - - - + + + + - + - + + - - + + - + - + - - + + + - - - + + + - - + + - + - - + - - + + - - + - + - + + - + - + - - + + - + - + - - + - + + - + - - - + + + - - + + - + - - + - + + - + - - + + - - + + + - - + + - - + - - + - @@ -31678,103 +31670,103 @@ order_start forward;forward;forward;forward + + - - - - + + + + - - - + + + + - - - + + - + - - + + + - - + + - - - + + - - + + - + - + - + - - + - + - + - + - + - + - + - + - + - - - - + + + @@ -31785,29 +31777,29 @@ order_start forward;forward;forward;forward + - - - + + + - + + - - + + - - + - + + - - @@ -31815,110 +31807,110 @@ order_start forward;forward;forward;forward + + - - + + - - + - + - + + - - + - + - + + + - - + - - + + - - + - + + - - + + - + - - - + + - + + - - + - @@ -31926,25 +31918,25 @@ order_start forward;forward;forward;forward + + - - + + - - + + - - @@ -31953,10 +31945,10 @@ order_start forward;forward;forward;forward + - @@ -31971,15 +31963,15 @@ order_start forward;forward;forward;forward + + - + - - - + + - @@ -31988,96 +31980,96 @@ order_start forward;forward;forward;forward + + + - - + - + + - - - + + + - - - + + - - - + + - + - + + - - + - - + + + - - + - - + + + - - + + - - + - - - + + + - + + - + - - - - + + + + - - @@ -32097,148 +32089,148 @@ order_start forward;forward;forward;forward + + - + - - - - + + + + + - - - + - + + + - - - + + - - + + - - + + - - + - + - + + - + - + - - + + - + - - + + - - + - + - + - + - + + - - + - + + - - - - + + + + - - @@ -32248,202 +32240,202 @@ order_start forward;forward;forward;forward + - + - + - + + - - - + + + - - + - + + - - + - + + + - - - + - + + - - + - + + - + + - - - + - + + - - + - + - + + - - + - + - + + + - - - + - + - + + - - + + - - + - + + - + - - - - - + + + + - + + - - + + - - - - - + + + + + - + - - @@ -32451,397 +32443,397 @@ order_start forward;forward;forward;forward + + + - - - + - + + - - + + - + + - - - + - + + - - + - + + - + - - + + - - + - + - + - + + - - + + - - + + - - + + + - - + + - - - + - - - - + + + + - + - - - - + + + + + - + + - - - + + + - - + - - + + + - - - + + - - - - - + + + + + - + + - + - - - + + + - - - + - + - + + - - + + + - - - + + + - - - + - + - + - + - + + - - + + - - + + - - + + - - + + + - - + - - + - + - - - + + + + - + + - - - + + - - + + - - + + - - - + + + + + - - - - + - - + + + - + - - + - + - - - - - + + + + + + - + + - - - + + + - - + - - - + + + - - + + - - - - + + + + - + - + - - - + + + - - - - - + + + @@ -32849,15 +32841,15 @@ order_start forward;forward;forward;forward + - + - @@ -32868,57 +32860,57 @@ order_start forward;forward;forward;forward + - + - + - + + - - + + - + - - + + + - - - + - + - + - - - + + + - @@ -32931,325 +32923,325 @@ order_start forward;forward;forward;forward + + + - - - + - + - + + + - - + - - - - + + + + - - + + - - + + - + + - - - + - + - + - + - + - + - - + + + - - - + + - + - + + - - + + - + + - - - + - + + + - - - + + - - + + + - - - + + - - - - + + + + + - - - + + + - - - + + + - - - + + - - + + - + - - - + + + + - - + - + + - - + + - - - + - + - + - + + - - + - + - + - + + - - + + - - - + + + - - + - + + - - + - - - - + + + + + + - - - + + - - + + - - @@ -33259,6 +33251,7 @@ order_start forward;forward;forward;forward + @@ -33266,21 +33259,20 @@ order_start forward;forward;forward;forward - + + - - + - + - @@ -33294,6 +33286,7 @@ order_start forward;forward;forward;forward + @@ -33301,27 +33294,26 @@ order_start forward;forward;forward;forward - - - - + + + + + + - - - - - - + + + + + - - + + - - @@ -33332,67 +33324,67 @@ order_start forward;forward;forward;forward + + - + - - - - - + + + + - - + + + + - - - - - - + + + + + - - + - + - - - - + + + + - + - + + - + - + - - @@ -33400,147 +33392,145 @@ order_start forward;forward;forward;forward + - + + - - + + + - - - + + - - + + - - - + + - + - - + + + + - - - - + + - - + - + + - - + + + - - - + + + - - - + + - - + - + + + - - - + + + - - - + + + - - - + + + - - + - - + - + - + + + + - - - - + + - - - @@ -33548,411 +33538,411 @@ order_start forward;forward;forward;forward + + + + - - + - - - + + - + + - + - - - + + + - - - + + - - + + - + - + + - - + + + - - + - + + - - - - + - + - + - + + + - - - + - + + + - - - + + - - + + - - + + + - - + - - + - + + + - - - + + - + - - + + + - - - + - + + - - + + - + + + - - - + + - + + - - - + - - + + - + - + - - + + + + - + - - + - - - + + + - - - + + + + - - - - + + + - - - + + - + - - + - - - - + + + + + - + + - + - + - - + + + - - - + - - + + + + - - - - + + + - - - + + + - - - + + + - - + + + - - - + - - + - + + + + - - - + - - + - @@ -33960,116 +33950,117 @@ order_start forward;forward;forward;forward + + - - + + - + - + + - - + - - + + - + + - - - + + + + - - - + + - + - - - - - - - + + + + + + + - - + + - - + + - - - + + - + - - + + + - - + + + + - - - - - - - - - + + + + + + - + + - - - + @@ -34077,26 +34068,25 @@ order_start forward;forward;forward;forward + + - - - - + + + - - + - @@ -34106,65 +34096,65 @@ order_start forward;forward;forward;forward + + - - + + + - - + - - + - + + - - + - + - + - + - + + + - - - + + + - - - @@ -34178,79 +34168,79 @@ order_start forward;forward;forward;forward + + + - - + - - + + + - - + + - - + + - - + - - + - + + - - + - + + - + + - - - + + + - - - @@ -34259,37 +34249,38 @@ order_start forward;forward;forward;forward + + - - + + + - - + - - + + - + + + - - - - - + + + - @@ -34298,78 +34289,77 @@ order_start forward;forward;forward;forward - + - + + - - + + - + + + - - - - + + - + - - + + - - + + + - - + - + + - - - + + - - - - + + + + + - + - - - @@ -34385,6 +34375,7 @@ order_start forward;forward;forward;forward + @@ -34393,7 +34384,6 @@ order_start forward;forward;forward;forward - @@ -34401,44 +34391,45 @@ order_start forward;forward;forward;forward + - + + - - - + + + + - - - + - + - + @@ -34447,49 +34438,48 @@ order_start forward;forward;forward;forward - + + - - + + - + - + - + - - + + + - - - - + + + + - - - + - @@ -34497,173 +34487,174 @@ order_start forward;forward;forward;forward + - + + + - - + + - - + - - + + + - - - - - - - - + + + + + + + - + + - - - - - - - - + + + + + + + - + - - + + - + - - + + + + - - - + + - - - - - - - + + + + + + - + + + - - - - + + - - + + + + - - - + - - + - + + - - + - + + - - + - + - + + - - + - + - + @@ -34671,48 +34662,47 @@ order_start forward;forward;forward;forward - + - + + - + - - + - + + + - + - - + - + + - - - - + + - @@ -34722,59 +34712,59 @@ order_start forward;forward;forward;forward + + + - - - + + - + + - - - + + - - + + - - + + - - + + + - - + - - + + - - + + - - @@ -34782,75 +34772,75 @@ order_start forward;forward;forward;forward + + - + - - + + - + - + - - + + + - - - - + + + + - - - + + - - - - + + + + - + + - - - + + - - + + - - @@ -34858,20 +34848,20 @@ order_start forward;forward;forward;forward + + + - - - + + - - @@ -34879,46 +34869,46 @@ order_start forward;forward;forward;forward + + + - - + - - + + + + - - - - + + - - @@ -34927,206 +34917,206 @@ order_start forward;forward;forward;forward + + + - - - + + - + + - - + + - - - + + - + + - - - + - + + - - + + - - + + - + - - - - + + + + - + - + - + - - + + - - + - + + + - - - - + + + - - - - - + + + + - + + + - - - - + + + - + - + + - - - - - - + + + + - + - + + - - + + - + - - - - + + + + - - + - + + + + - - - - - + + - + + - - + - + + + - - - @@ -35136,97 +35126,98 @@ order_start forward;forward;forward;forward + + + - - - + + - + + - - - - - - + + + + - + + + + - - - - - - - - + + + + + + - + - + - - + + + + - - - + - - - - - - + + + + + - + - + + + - - + - + + - - + + - + - - - + @@ -35235,430 +35226,431 @@ order_start forward;forward;forward;forward + + + + - - - - + + + - - - - + + + - - + + + - - - - + - + + + - - - + - + + + + + - - - - + + - - + + - - + + - - + + - - + - + + - + - - - + + - - - - + + + + + + - - - + - - + + + + + - - - - - + + - - + + - + + - - + - + + + - - - + - - + - + + + + - - - + - + + - - - + + - - + + + - - + + - - + + - + + - + - - + + - - - + + - - - + + + - - + + - - + + + + - - - - - + + - - + + + + + - - - - + - + - + + + - - - - + + + + - - - - - + + + - + + + - - - + - - + + + - + + - - - - + + + - + - - + + - - - + + + + - - + - - - + - - - - - + + + + + + - + - + - - + + + - - - + + + + - - - - + + + - - - + + + - - + - - + - + + + - - + - - + + + - - + + - - - + + + - - - + - + + + + - - @@ -35666,333 +35658,332 @@ order_start forward;forward;forward;forward - + + + - + - - - - + - + + + + + - - - - + + - - + + + - - - - - + + - + + - + - + + + - - + + - - + - - + - - + - + - + + + - - - - - - - + + + + + + + - - - + + - + - - + + + - + - - - + - + - + + + + - - - + - - + + - + + - - + + - - + + - + - + - + + - - - + + - - - + + + + - - - + + + - - - - + + + - - + + - + - + - + - - - + + + - - + - + - + + + - - - - + + + + - - - - + + - - + + - - + + - + + - + + - - - - + + - - + + - + - - + + + - - - + + + - - - + + + - - + + + + - - - - + + + + - - - - @@ -36000,80 +35991,79 @@ order_start forward;forward;forward;forward + + + - - - + + - - + + - - + - - + + - - + + - + - - + + - + + + - - + - - - + + - - @@ -36081,336 +36071,337 @@ order_start forward;forward;forward;forward + + - - + + + - - - + + + + - - - - + + + - - - + + - + - + - + + + - - - + - + + + - - - + - - + + + - - - - + + + - - + + - - + + - + - + + - - + + + + - - - - + - + + + - - + + - - - + + + - - + + - - - - + + - + + + + - - - - + + - - + - + + + - - - + + - + - - + - + - - - - - - + + + + + + - - + + - + - + - - + + + - - + + - - - + - + + + + - - - - + + + + - - - - + + - - + + + - - - + + + - + + - - + - - + + - - - + + - - + + + + + - - - - + - - + - + + - - + + + + - - - - + - + - + @@ -36425,110 +36416,109 @@ order_start forward;forward;forward;forward - + + + - - - + + + + + - - - + - + - - - - + + + - - + + + + - - - + - + - + + - + + - - + + - - - - + + - - + + + + - - - - - - - + + + + + + + - - - - + + + - - - + + - - + + + - + + - - - + + + - - - - @@ -36537,13 +36527,14 @@ order_start forward;forward;forward;forward + + - @@ -36552,45 +36543,44 @@ order_start forward;forward;forward;forward + - + + + - - - - + - + + + + - - - - + + - + - - @@ -36599,60 +36589,61 @@ order_start forward;forward;forward;forward + - + + + - + - - + + + - + - - - - - + + + + + - - - + + + - - - - + + - + + - - @@ -36660,235 +36651,234 @@ order_start forward;forward;forward;forward - + + - - + - + + + - - + + + - - - - + + + - - - + + - + + - - + - + + + - - + - + - - - + + - + + - + - - + - + - - + + + - - + + - - - + + + - - - + + + - - + - + - + + - + + - - + - + - - + + + - - - + - - + + + + - - + + - - + - - - - - + + + + + - + + - - - - + - + + + + + - - - + + - - - + + + + - - - - - @@ -36900,86 +36890,88 @@ order_start forward;forward;forward;forward + + - - + + + - - + - + + - - - + + + - - - + + + + - - + + - - - + - - + + + - - - + + + + - - - - + - + - + + + - + + - - @@ -36987,130 +36979,128 @@ order_start forward;forward;forward;forward - - + + - - + + - + + - + - - + + + - - + + - - - - + + + - + + - - - - + - + + - + - + - - + - + - + + - + - - + - + + + - - + - + + + - - + + - - - - + - @@ -37118,71 +37108,72 @@ order_start forward;forward;forward;forward + + + - - + + - - - + - + + - + - + + - - + - + - + + - + - - - + + + - - - + + - + - - + + - @@ -37191,125 +37182,124 @@ order_start forward;forward;forward;forward - + + + - - + - - + + + - + - - - + + - + - - + + + - - - - + + + - - + + + - - - + + + + - - - - + + - + + + + - - - + + - - - + - + - - + - + + + - - - @@ -37324,59 +37314,59 @@ order_start forward;forward;forward;forward + + + - + - - - + + - - + + + + + - - - + - - + + - - - - + + + + - - - + + + + - - - - + + + - - - @@ -37384,152 +37374,153 @@ order_start forward;forward;forward;forward + + + - + - + + - - - - + - + + + - - - + + - - + + + - - - + + - - + + - + - - + + + + + - - - - + + - - + + + - - - + - - + + - + + + - - - - - - + + + + + - - + - + - - + - + + + - - - + + - - + @@ -37537,73 +37528,73 @@ order_start forward;forward;forward;forward + - + + - - - + + - - + - + + - + + + - - - - + + + + - - - + - + - + + - - + + - + - - - - - + + + + - - + @@ -37613,113 +37604,113 @@ order_start forward;forward;forward;forward - + - + + + - - - + + + - - - + + - + - - + + - - + + - + + - - + + - - + + - - - + + - + + + - + + - - + + - - + - + - - - + - + + - - - + + + - - - - - + + + + + + - - - + + - - - + @@ -37729,9 +37720,9 @@ order_start forward;forward;forward;forward - + @@ -37741,279 +37732,277 @@ order_start forward;forward;forward;forward - + - + + + + - - - - + + + - - + - + - + + - - + + - - - + - + - + + - + + - - + + - - + + - - - + + + - - - - + + + - - + + - + + + + - - - - + - + - - + + + - + - + - - - - - - + + + + + + + + - - - - - + + + + - - + - - + - + - + + - - - + + + - - + - - + - + + + + + - - - - + - - - + + + + + - - - - + + - + - - + + + - - - - + + + + - - + + - - - - + + - - + + + - - - + - + - + - @@ -38023,43 +38012,43 @@ order_start forward;forward;forward;forward + - + + + - - - + + - + + + - - - - - + + + + + - - - - @@ -38073,278 +38062,278 @@ order_start forward;forward;forward;forward + + - - + + - - + + - + + - + - - + + + + - - - - - + + + + + + - - - - - - + + - - + + - - + + + - - - + + + + + - - - - + + + - + - - - + - + - - + + - - + + + + - - + + - - - - + + + - + - + + - - - + + - - - + + + - + + - - - + + + + - - - - + + - - + + - - - + - + + - + + + - - - - + + - - + + + - + - - + - + - + + - - + + + - - + - - - + + + + + + - - - - - + + + + + - - - - - - @@ -38352,224 +38341,224 @@ order_start forward;forward;forward;forward + + - + + + - - - - + + + - + - - + + + - - - + + - - - + + + + - - - + + + + + - - - - - + + + - - + + + - - - - + + + - - - + + - + + - - + - - + + - - - + + + + + + - - - - - + + - + - + - + + + - - - + + - - - + + - - - + + + - - + - + - + + - + + - + - - + + + - + - - - - + - + + + - - + + - + - - - - + + + + - - - - + + - - @@ -38579,291 +38568,291 @@ order_start forward;forward;forward;forward + + + + + - - + - - + - + + - + - - - - + + + - - + - + + + + - - - + + - - - + - - - + + - + - + - + - - + + + + - - - + - - + + + + - + - - - - + + - + + + - - + + - - - + + - - + - + + + - - - + + - - + + + - + + - - - + - + - - + - + + - - - + + + + - - + + + - + - - - + - - + - - + + - + + + - + + - - - + - - + - + + - - - + + - - + + + + - - + + + + - - - + + - + - - - + - + - - @@ -38874,177 +38863,176 @@ order_start forward;forward;forward;forward + - + - + + - + + - - + + - - + - - - + + - + + - + - - + + - - + + - - + - + - + + + + - - - - - + + - + - + + + - + - - + - + - + - - - + + + + - - - + + + - - + - - + + + - - + - - - + + + + + + - - - + - + - - + + - - - + + + + - - + - - - - @@ -39052,193 +39040,195 @@ order_start forward;forward;forward;forward + + - + - + - + + - - + + - + - + - + - + - + - + + + + - - - - - - + + + - - - + + + + - - + - + + - - + + - - - - + + + - + - - - + + - - + + + + - - + - + - - + + - + + + - + + - - - - + + - - - + + + + - - + + - - + - - - - + + + - - + + - - - - - + + + + + + - - @@ -39246,275 +39236,273 @@ order_start forward;forward;forward;forward - + - + + + - - - - + + + + - + - - + + - + - - + + - - - - + + + + - + + + - - - - - - + + + - + + - - - + - - + + + - - - + + + - + - - - + + - + - + - + + + - + + - + - - - - - + + + + + - - + + + - - - - + - + + + - - - - + - + + + - - + + - + - - - + + + + + - - - - + - - + + + - + - - - - + - + + + - - + + + - + + + - - - - + - - + - + - + + - + + - - + + - - - - @@ -39523,44 +39511,44 @@ order_start forward;forward;forward;forward + + - - + + + + - - - + + + + - - - - + + + - - - - + + + + - - - - @@ -39569,506 +39557,506 @@ order_start forward;forward;forward;forward + + - + - - + + + - - + + - + + + - - - - + + - + - - + - + + + - - + + - - + + - - - + + + - - - + + - + - - - + + + - + - + - - - + + + + - - + + + - - - - + + + - - - + + + - + - + + - - - - + + + - - + - + - - - + + + + - - - - + + + - - - + + + - - + - - + + - + + - + + - - - + - - + + - - + + + + - - + + - - - - - - + + + + + + - + + - - - - - - - + + + + + - + + + - - - + + + - - - - + + + + - - + + - - - - - + + + + + - - - - - + + + + + - - - - + + - - - + - + + + + + - - + - + - - + + - - - + + - + + + + - - - - - - + + - + - + + + - - - + + + - - + - - + - - + + + - + + - + + + - - - - - + + + - + + - - - + + + + + - - - - - - + + + - + - - - + + - + - + + - + + - - + - + - - + - - + + + + - - - + - + + + - - - - + - + + + - - - + + + + - - + + + - - - - + - - - - - - + + + + + + - - - @@ -40077,6 +40065,7 @@ order_start forward;forward;forward;forward + @@ -40084,8 +40073,9 @@ order_start forward;forward;forward;forward - + + @@ -40093,137 +40083,136 @@ order_start forward;forward;forward;forward + - - - + + - + + + - + - - - + + + - + - - + - - + + - - + - - + + + + + - - - - + - + - - + + + - - - + + + + + + - - - - - - + + + + - - - + + + + - - - - + - - + + + + - - - + - - + @@ -40231,20 +40220,20 @@ order_start forward;forward;forward;forward + + - - + - + - @@ -40254,175 +40243,175 @@ order_start forward;forward;forward;forward + - + - + - + - + + - - + + + + - - - - - + + + - - + + - - - + + + + + - - - + - + - - - + + + - - + - - + + - + + - - - + + - - + + + - + - - + + + - - + - + + - + + - - - - + + + - - - + + + - + - - - + - + - + + + + - - - - @@ -40430,58 +40419,58 @@ order_start forward;forward;forward;forward + + + - - + + + - - - + - + - - + + + - - - + + - + + - - - + + - - + + - - @@ -40492,175 +40481,175 @@ order_start forward;forward;forward;forward + + - + + - - + + + - - + - + - - + - + + - - + - + - - - + + - + - + + + + - - - - + + - - + + + - - - - + + + - + + - + - - + + + - - - + + - - - - + + + - + - - + + + + - - - + - + - - + + - + - - - + + - - + + + - - + + - - @@ -40675,29 +40664,29 @@ order_start forward;forward;forward;forward + + + - - - - + + - + + + + - - - - + - @@ -40707,244 +40696,245 @@ order_start forward;forward;forward;forward + - + - + + + - + + - - - + + - - - + + + - - + + + - - + - - + + + + + - - - - - - + + - + + - - - + - - + + + + + + - - - - + + - - - + - - + + + + + - - - - + - - + + + + - - - + - + - + + - - - + + + + - + - - - - + + + - - + + + - - + - + + + - + - - - + + - - + + - - - - + + + - + - - + - + + - - + + - + - - - + + + + - - - - + + + - - + - - + + + - - - + + - - + + @@ -40952,298 +40942,298 @@ order_start forward;forward;forward;forward + + - + - - + + - - - + + - + + - - + + - + - + - + - - - + + - + + + - - - - - + + - + + + + - - - + - - - + + + + + + - - - - + + + - - - - + + - - + - + - + + + + - + - - - - - + + + - + + - - - + + - + + + - - - + + + - - - + + - - - - + + + + - + - + - - - + + - + + - - + + + - - - - + - + + - + - + - + + + - - - + + + - - - - + - + + + + + - - - - + - - - + + + + - + + - + - - - + + - - + - + + - - + + - - - - + + - + + + - - - + + + + - - - - + - - + + + - + + - - @@ -41253,95 +41243,93 @@ order_start forward;forward;forward;forward + + - - + + + - - - + - - + + - + + + - - - - + + - + + - + - - - - + + + + + - - - + + + - - + - - - - + - + + + + + - - - - - + + - + + + + - - - + - - - @@ -41351,15 +41339,18 @@ order_start forward;forward;forward;forward + + - + + @@ -41367,75 +41358,72 @@ order_start forward;forward;forward;forward + - - - + + + - - - + + - - - + + + - + + + - - - - + + + + - - + + - + - - - - - @@ -41445,6 +41433,7 @@ order_start forward;forward;forward;forward + @@ -41452,7 +41441,6 @@ order_start forward;forward;forward;forward - @@ -41463,134 +41451,134 @@ order_start forward;forward;forward;forward + + + + - - - - + + - + + - - - + + + + - + + - - - + + - - - + + + + + - - - - - - + + + - - - + + + + - - + + + - - - + - + + - - - + + + - - + + - - + + - + - + + - - - - - + + + - - + - + - - @@ -41600,30 +41588,31 @@ order_start forward;forward;forward;forward + + - + - + - @@ -41631,642 +41620,643 @@ order_start forward;forward;forward;forward + + - - - + + + + - - + + - - + - + + - + - + - - - - + + + - + - + + - - - - + + + + + - - - - - - - - - + + + + + + - - + + + + - - - + + + - - + + + + - - - - - - + + + + + + + - - - - - - + - - + + + + - - + + - - - - + + + + - - - - + + + - - - + + + + - - - + + + + - - - - - + + - + + - - + - + + - + - + + - - - - + + - - + + + + + - - + - - - + - + + - + + - - + + + + - - - - - - + + - - + + - - + + - + + - + - - + + + + - - - - - + + + - - - + + + + + - - - - + + + - - - + + - - - + + - + + - + + + + - - - - - - + + + - - - + + - - + + - + + + + - - + - - - - + + - - + + + + - - + + + - - + + - - - - - + + + + - - - + + - - - + - + + + + + - - - - + + - - + + + + + - - - - + + + - - - - - + + + - + - + + + - - - - + + - - + - + - - + - + + + + - + + - - - - + + + - + + - - - - - + + + + - - + - + - - + + + - + - - + - + + - - - - + + + + + + - - - - - + + + + - - - - + + + + - - - + + - + + - + - - - + - - + + - + - - + + + - - + + - - - + @@ -42305,17 +42295,17 @@ order_start forward;forward;forward;forward - - - - - - + + + + + + - + - - + + @@ -42359,9 +42349,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -42369,39 +42359,39 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -42422,85 +42412,85 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; - "";"";""; - "";"";""; + "";"";""; + "";"";""; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; ;;; ;"";""; ;"";""; @@ -44994,7 +44984,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -45822,7 +45812,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -46402,23642 +46392,23643 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;;; diff --git a/share/colldef/zh_CN.eucCN.src b/share/colldef/zh_CN.eucCN.src index c09ad60c8c83..43f39bb4fe57 100644 --- a/share/colldef/zh_CN.eucCN.src +++ b/share/colldef/zh_CN.eucCN.src @@ -101,9 +101,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -191,13 +191,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -399,6 +399,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -409,7 +410,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1458,4481 +1458,4478 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -5971,21 +5968,21 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol @@ -6059,9 +6056,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -6149,13 +6146,13 @@ order_start forward;forward;forward;forward - - - - - - - + + + + + + + @@ -6357,6 +6354,7 @@ order_start forward;forward;forward;forward + @@ -6367,7 +6365,6 @@ order_start forward;forward;forward;forward - @@ -7416,4481 +7413,4478 @@ order_start forward;forward;forward;forward - - - - - + + + + - - - + + + - + - + - + - - - - + + + + - - - - - - - - - + + + + + + + + + - + - - - + + + + - - - - - - + + + + + - - - + + + - - - - - - - + + + + + + + - - - - + + + + - - - + + + - - - - - - + + + + + + - - - - + + + + + - - + - - + + - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + + - - - - - - + + + + + - - + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + - - + + - + + - - + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - + - + - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + - - + - - + + - + - - + + - - - - - + + + + + - - + + - - - + + + - + - + - - - + + + - - + + - + - - - - - - + + + + + + - - - - + + + + + - - - - - - + + + + + - + - - - + + + - - + + - - - - + + + + - - - - - - + + + + + + - - - + + + - - - - + + + + - + - - - + + + - - - + + + - + - - + + - - - - - + + + + + - + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + - - - + + - - - - - + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + + - + - - + + - + - - - - - - + + + + + + - - - - + + + + + - - - - - - - + + + + + + - - - - - - + + + + + + - + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - - + - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - + - - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + + - - - + + - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - + + - - - - - - + + + + + + + - + - - - - - + + + + + - - - - + + + + + - - + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - + + + - + - - - + + - - - + + + + - - - + + + - + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - + - + + - - - - - - - - + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - + + + + + + - + - - + - - - - - - - - + + + + + + + + - + + - - - - - - - + + + + + + + - - - + + + - - - - - - - + + + + + + + + - - - - - - - + + + + + + - - - - + + + + - - - - - + + + + + - - + + - - + + - - - + + + - + - + - - - - + + + + - - - - + + + + - + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + + - - - + + - - - + + + - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - + + - - - + - - - - + + + + - + + - - + + - + - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + - - - - + + + - - - - - + + + + + + + - - - - - + + + + - - - - - - + + + + + + - + + - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - - - - + + + + - + - - + + - - + + - - - - - - - - + + + + + + + + + - - - - + + + - - - - + + + - - + + - + - - - - - - - - - + + + + + + + + + + - - - + + + - - - + + + - - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - + + - + - - + - - - - - + + + + + + + - - - - + + + - - - - - + + + + + + + - - + - - - - - + + + + - - + - - + + + + - - - + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + - - + + - + + - - - - - - + + + + - - - - - - - + + + + + + + + - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + - + - + + - - - - - - + + + + + + - - - + + - - - + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - - + + + + + - - - - - - - - + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - + - - + + + - - - - + + + + - - - - + + + + + - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - + + + + + + + + + - - + - - - + + + + - - - + + + + + - - - - - - - + + + + + - - - - - - - + + + + + + + + - - + + - - - + + + - - - - - + + + + + - - + + - - - - - - + + + + + - - - - - - + + + + + + - - - + + + - - - - - + + + + - - - + + + + + - - - - + + + - + - - - - - + + + + + - - - + + - + + + - - - + + + + - - - - - - - - - + + + + + + + - - + + + - + - - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - + - - - - + + + + + + - - - - - + + + + - - - - - - + + + + + + - - - - - + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + - - - - + + - - - + + + - - - - + + + + + - - - + + + - - + + - - + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - + + - - - - - - + + + + + + - + - - - - + + + - - - - - + + + + + + - - - + + + - - - + + - - - - - - + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + - + + + - + - - - + + - + - - - + + + - + + + - - - - - - - - - + + + + + + + + - - - - - - + + + + + - - + + + - - - + + + - - + - - + + - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + - - - - - - - + + + + + + + - - - + + + + - - + - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + + - - - - + - + + - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - - + + + - - - - - - + + + + + + - - + + + - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - + - - + + + - - + - + + - - - - - - - - - + + + + + + + + + - - + + + - - - + + - - - + + + - - - - - - + + + + + - + + - - - + + - - - + + + - - - - + + + + - - - - - - - - + + + + + + + + - + + - - - - + + + + - + - - - - + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + + - - - + + - - + + - - - - - - + + + + + + - - - + + - - + + - - - - - - - + + + + + + + + - - + - - - + + + - - - - - - - + + + + + + + + + - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + - + + - - - + - - + + + - - - + + + - - - - + + + + - + - - + - + + - - - - - + + + + - - - - + + + + + - - - - + + + + - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - - + + + - - - - - - + + + - + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + - + + - - - - - - - - - - - + + + + + + + + + + - - - + + + + + - - - - - + + + + - - - - - - + + + - + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + + + - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + - - - - - - - + + + + + + - - - - + + + + + + + + - - - - - - - - - - - - + + + + + + + + - + - - - - - - - + + + + + + + + - + - - - - - - + + + + + + + + - - - - - + + + - - + + + - - - - - - - - - - + + + + + + + + + - + + + - - - - - + + + + + - - - - + + - - + + + + - - + + - + - - - + + + + - - - + - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + + + - - + - + + - - - - - - - + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - + + + - - - - + + + - + + + - - - + - - - - - - + + + + + + - + + - - - - - - - - - - - + + + + + + + + + + + - - - + + - + + - - - - - + + + + - - - - - + + + - - + + + + - - + + + - - - - - + + + + + - - - - + + + - + + - - - - - - - + + + + + + + - - - - - - - + + + + + + - - + + - - - - + + + + + - - - - - - + + + + - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + - - - - - + + + + + + + - - - - + + + + - - - + + + + - - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - - + + + - + - - - + + + + - - - - + + - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - + + + + + + - - - + + + + - - - - - - + + + + + + + + - - - - - + + + - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + - - + + - - + + + - + - - - - - + + + + + - - - - + + + + - - - + + - + + + - - - - - - + + + + - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - - - + + + + - - - - - - - - + + + + + + + + + + - - - - + + + + + + - - - + + + - - + + - - - - - - + + + + + - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + - - + + - - - - + + + - - - - - - - + + + + + + + + - - + + + - - - + + - - + + + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + + + + - - - - - + + + + - - - - - - - - + + + + + + + - + - + + - - - - - - - - - + + + + + + + + + - - - + + - + + - - - + + + - - - - - - - - + + + + + + - - - + + + + + + - + + - - - - - + + - - + - + + + + - - - - + + + - - - + + + + - - - - - - - - - + + + + + + + + + + - - - - + - - - + + - - - + + + + + + - - - + + - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - + + + + - - - + + + - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + - - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + + - + - - - - - - - - - + + + + + + + + + - - - - + + + - - - + + + + + - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + - - - - + + + + + + - - - - + + + + + - - - - - - + + + + + - + - - - + + + + + - - - - - + - - - - - + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - + + - - + + + - - - - - - + + + + - + + + + - - - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + + - + + - + - - - - - - + + + + - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + - - - - - - - + + + + + + + + + - - + - - + + + - - - - - + + + - - + - - - + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + - - - - - - + + + + - + - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + - - - - - + + + + + + - - - - - + + + + + + - - + + - - - - + + - - - - + + + + - + + - - - - + + + + + + - - - - - + + + + - - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + - - - - + + + + + + - + - + - - - - + + + - - + + + + - - - - - + + + + + + + - - - + - + - - - + + - - - - - + + + + - + + - + + + - - + - - - + + - - - - - + + + + - - - - - - + + + + + + + - - - - + + + - - - + + + + + - - - - + + + + + - - - - + + + - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - + - - - - - + + + + + + - - - + + - - - + + + + - - - - - - - - + + + + + + + + - - - - + + + + - - + + + - - - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + + + - - - - - - + + + + + - - - - - - - - + + + + + + + - - - - - + + + + + + + - - - - - - - + + + + + + + - - + + - - - + + + + - - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + + - - - - - + + + + - - + + + + - - - - + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + + + + - - - + + + + - - - - - + + - - - - - - - - + + + + + + + + + + - - - - - - + + + + + - - - - + + + + + - - - - - - + + + + + - - - - - - - - + + + + + + + + + + - - - - - + + + - - - + + + + - - + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - - - - + + + + + + + - + - - - - - - - - - - + + + + + + + + + + - - - + + - + + - - - + - + - - - - + + + - - - + + + + + + - - + + - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + - - + + - + + + - - - - - - - + + + + + - - + + - - - - + + + - + + - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + - - - + + + - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - - - - + + + + + + - + + - - - - + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + - - - - - + + + + + - - - + + - - - - - - - + + + + + + + + - - - + + + - + + - - - - - + + + - - - + + + + - - - - - - - - - - - + + + + + + + + + + - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + - - - + - - - - - + + + + + + + + - - + + + - - - - + - - - + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - + + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + - + + + - - - - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + - - - + + + + - - - - - + + + + @@ -11929,21 +11923,21 @@ order_start forward;forward;forward;forward - - - - - - - + + + + + + + - - - + + - - - + + + + @@ -11995,12 +11989,12 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; "";"";""; @@ -12036,15 +12030,15 @@ order_start forward;forward;forward;forward "";"";""; "";"";""; "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; - "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; + "";"";""; ;;; ;;; ;;; @@ -12149,8 +12143,8 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; + "";;""; + "";;""; ;;; "";;""; "";;""; @@ -12238,14 +12232,14 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -12927,7 +12921,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - "";"";""; + "";"";""; ;;; ;;; ;;; @@ -13280,5811 +13274,5811 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";"";""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";"";""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; ;;; ;;; ;"";""; @@ -19485,32 +19479,32 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; diff --git a/share/colldef/zh_TW.Big5.src b/share/colldef/zh_TW.Big5.src index 6ef0dd9a81fe..6e527ef0a65d 100644 --- a/share/colldef/zh_TW.Big5.src +++ b/share/colldef/zh_TW.Big5.src @@ -64,9 +64,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -156,14 +156,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -172,6 +172,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -345,6 +346,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -355,7 +357,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -535,20 +536,15 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -642,7 +638,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -652,6 +647,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -662,16 +658,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -685,7 +677,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -707,7 +701,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -724,6 +717,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -743,7 +737,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -752,7 +745,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -851,6 +843,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -886,14 +880,18 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -926,21 +924,16 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -987,8 +980,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1004,6 +995,8 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1018,7 +1011,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1055,15 +1047,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -1071,6 +1060,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1081,6 +1071,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -1096,6 +1087,62 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol @@ -1158,9 +1205,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -1250,14 +1297,14 @@ order_start forward;forward;forward;forward - - - - - - - - + + + + + + + + @@ -1266,6 +1313,7 @@ order_start forward;forward;forward;forward + @@ -1439,6 +1487,7 @@ order_start forward;forward;forward;forward + @@ -1449,7 +1498,6 @@ order_start forward;forward;forward;forward - @@ -1629,20 +1677,15 @@ order_start forward;forward;forward;forward - - - - - @@ -1736,7 +1779,6 @@ order_start forward;forward;forward;forward - @@ -1746,6 +1788,7 @@ order_start forward;forward;forward;forward + @@ -1756,16 +1799,12 @@ order_start forward;forward;forward;forward - - - - @@ -1779,7 +1818,9 @@ order_start forward;forward;forward;forward + + @@ -1801,7 +1842,6 @@ order_start forward;forward;forward;forward - @@ -1818,6 +1858,7 @@ order_start forward;forward;forward;forward + @@ -1837,7 +1878,6 @@ order_start forward;forward;forward;forward - @@ -1846,7 +1886,6 @@ order_start forward;forward;forward;forward - @@ -1945,6 +1984,8 @@ order_start forward;forward;forward;forward + + @@ -1980,14 +2021,18 @@ order_start forward;forward;forward;forward + - + + + + @@ -2020,21 +2065,16 @@ order_start forward;forward;forward;forward - - - - - - + @@ -2081,8 +2121,6 @@ order_start forward;forward;forward;forward - - @@ -2098,6 +2136,8 @@ order_start forward;forward;forward;forward + + @@ -2112,7 +2152,6 @@ order_start forward;forward;forward;forward - @@ -2149,15 +2188,12 @@ order_start forward;forward;forward;forward - - - @@ -2165,6 +2201,7 @@ order_start forward;forward;forward;forward + @@ -2175,6 +2212,7 @@ order_start forward;forward;forward;forward + @@ -2190,6 +2228,62 @@ order_start forward;forward;forward;forward + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2256,15 +2350,15 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -2416,7 +2510,7 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; + "";;""; ;;; "";;""; "";;""; @@ -2476,17 +2570,17 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - ;;; - ;;; - ;;; - ;"";""; - ;"";""; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;"";""; + ;"";""; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -2899,32 +2993,32 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -2965,13067 +3059,13067 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; UNDEFINED IGNORE;IGNORE;IGNORE;... order_end diff --git a/share/colldef/zh_TW.UTF-8.src b/share/colldef/zh_TW.UTF-8.src index bf062b714b65..7d6e56287b8e 100644 --- a/share/colldef/zh_TW.UTF-8.src +++ b/share/colldef/zh_TW.UTF-8.src @@ -27,9 +27,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -56,7 +56,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -223,9 +223,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -238,6 +236,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -258,19 +257,13 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -281,16 +274,19 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -300,10 +296,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -311,6 +303,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -318,15 +313,10 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -340,6 +330,7 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -353,27 +344,26 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -385,16 +375,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -406,31 +400,28 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -439,7 +430,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -447,26 +437,20 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -474,10 +458,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -485,13 +468,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -502,30 +484,28 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -536,11 +516,12 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -550,77 +531,73 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -628,22 +605,19 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -651,12 +625,9 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -668,12 +639,14 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol collating-symbol -collating-symbol -collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol @@ -681,7 +654,6 @@ collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol collating-symbol @@ -689,47 +661,102 @@ collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol -collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol +collating-symbol collating-symbol collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol collating-symbol collating-symbol -collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol +collating-symbol collating-symbol order_start forward;forward;forward;forward @@ -753,9 +780,9 @@ order_start forward;forward;forward;forward - - - + + + @@ -782,7 +809,7 @@ order_start forward;forward;forward;forward - + @@ -949,9 +976,7 @@ order_start forward;forward;forward;forward - - @@ -964,6 +989,7 @@ order_start forward;forward;forward;forward + @@ -984,19 +1010,13 @@ order_start forward;forward;forward;forward - - - + - - - - @@ -1007,16 +1027,19 @@ order_start forward;forward;forward;forward - + + + + @@ -1026,10 +1049,6 @@ order_start forward;forward;forward;forward - - - - @@ -1037,6 +1056,9 @@ order_start forward;forward;forward;forward + + + @@ -1044,15 +1066,10 @@ order_start forward;forward;forward;forward - - - - - @@ -1066,6 +1083,7 @@ order_start forward;forward;forward;forward + @@ -1079,27 +1097,26 @@ order_start forward;forward;forward;forward - + + + - - - @@ -1111,16 +1128,20 @@ order_start forward;forward;forward;forward + - + + + + @@ -1132,31 +1153,28 @@ order_start forward;forward;forward;forward - - + - - - - + + - + + - - + @@ -1165,7 +1183,6 @@ order_start forward;forward;forward;forward - @@ -1173,26 +1190,20 @@ order_start forward;forward;forward;forward - - - - - + - - @@ -1200,10 +1211,9 @@ order_start forward;forward;forward;forward - - + @@ -1211,13 +1221,12 @@ order_start forward;forward;forward;forward + - - + - + - @@ -1228,30 +1237,28 @@ order_start forward;forward;forward;forward - - - + - - + + @@ -1262,11 +1269,12 @@ order_start forward;forward;forward;forward + + - @@ -1276,77 +1284,73 @@ order_start forward;forward;forward;forward - - + - + + - - + + + + + - + - + + + - - - - - - - - + + - - - @@ -1354,22 +1358,19 @@ order_start forward;forward;forward;forward - + - + + - - - - @@ -1377,12 +1378,9 @@ order_start forward;forward;forward;forward - - - @@ -1394,12 +1392,14 @@ order_start forward;forward;forward;forward - + + + + + - - - + @@ -1407,7 +1407,6 @@ order_start forward;forward;forward;forward - @@ -1415,47 +1414,102 @@ order_start forward;forward;forward;forward + + - + + + + + - - - + + - + + + + + + + + + + + + + - + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * assignment of characters to weights @@ -1498,9 +1552,9 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; - ;;; - ;;; + ;;; + ;;; + ;;; ;;; ;;; ;;; @@ -1525,7 +1579,7 @@ order_start forward;forward;forward;forward ;;; ;;; ;;; - ;;; + ;;; ;;; ;;; ;;; @@ -1591,2183 +1645,2183 @@ order_start forward;forward;forward;forward "";;""; "";;""; "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; - "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; + "";;""; UNDEFINED IGNORE;IGNORE;IGNORE;... order_end diff --git a/share/ctypedef/Makefile b/share/ctypedef/Makefile index 870ebfd76362..028baf460e5b 100644 --- a/share/ctypedef/Makefile +++ b/share/ctypedef/Makefile @@ -5,7 +5,7 @@ LOCALEDIR= ${SHAREDIR}/locale FILESNAME= LC_CTYPE .SUFFIXES: .src .LC_CTYPE -MAPLOC= ${SRCTOP}/tools/tools/locale/etc/final-maps +MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps .src.LC_CTYPE: localedef -D -U -c -w ${MAPLOC}/widths.txt \ @@ -219,6 +219,7 @@ SYMLINKS+= ../$f/${FILESNAME} \ FILESDIR_${f}.LC_CTYPE= ${LOCALEDIR}/${f} .endfor +SYMPAIRS+= ja_JP.eucJP.src ja_JP.SJIS.src SYMPAIRS+= en_US.ISO8859-1.src en_US.ISO8859-15.src SYMPAIRS+= en_US.ISO8859-1.src en_US.US-ASCII.src SYMPAIRS+= en_US.ISO8859-1.src lv_LV.ISO8859-13.src @@ -234,7 +235,6 @@ SYMPAIRS+= be_BY.CP1131.src ru_RU.CP1251.src SYMPAIRS+= be_BY.CP1131.src ru_RU.CP866.src SYMPAIRS+= be_BY.CP1131.src ru_RU.ISO8859-5.src SYMPAIRS+= be_BY.CP1131.src ru_RU.KOI8-R.src -SYMPAIRS+= ja_JP.eucJP.src ja_JP.SJIS.src .for s t in ${SYMPAIRS} ${t:S/src$/LC_CTYPE/}: $s diff --git a/share/ctypedef/en_US.UTF-8.src b/share/ctypedef/en_US.UTF-8.src index f54f9add3700..bebdb9180b56 100644 --- a/share/ctypedef/en_US.UTF-8.src +++ b/share/ctypedef/en_US.UTF-8.src @@ -3162,7 +3162,8 @@ alpha ;...;;/ ;/ ;...;;/ ;/ - + ;/ + graph ;...;;/ ;...;;/ ;/ @@ -3180,7 +3181,8 @@ graph ;...;;/ ;/ ;/ ;...;;/ - ;...; + ;...; +punct ********************************************************************** * 0x0A00 - 0x0A7F Gurmukhi @@ -3250,7 +3252,7 @@ alpha ;...;;/ ;/ ;/ ;...;;/ - + ;...; graph ;...;;/ ;...;;/ ;...;;/ @@ -3266,7 +3268,7 @@ graph ;...;;/ ;/ ;...;;/ ;...;;/ - + ;...; punct ********************************************************************** @@ -3433,7 +3435,7 @@ graph ;...;;/ ********************************************************************** * 0x0D00 - 0x0D7F Malayalam ********************************************************************** -alpha ;...;;/ +alpha ;...;;/ ;...;;/ ;...;;/ ;...;;/ @@ -3445,11 +3447,10 @@ alpha ;...;;/ ;...;;/ ;...;;/ ;...; -graph ;...;;/ +graph ;...;;/ ;...;;/ ;...;;/ - ;...;;/ - ;...;;/ + ;...;;/ ;...;;/ ;...;;/ ;...;;/ diff --git a/share/ctypedef/ja_JP.eucJP.src b/share/ctypedef/ja_JP.eucJP.src index 3843f38893db..29ae959f5d59 100644 --- a/share/ctypedef/ja_JP.eucJP.src +++ b/share/ctypedef/ja_JP.eucJP.src @@ -1912,7 +1912,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -1943,8 +1942,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -1966,7 +1963,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2053,7 +2049,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2110,6 +2105,7 @@ alpha ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -2137,8 +2133,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -2160,7 +2154,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2191,6 +2184,7 @@ alpha ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -2240,7 +2234,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2292,6 +2285,7 @@ alpha ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -2305,7 +2299,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2399,7 +2392,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2465,7 +2457,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2498,7 +2489,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2520,7 +2510,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -2623,8 +2612,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -2762,7 +2749,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3066,7 +3052,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3124,7 +3109,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3184,17 +3168,14 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3380,7 +3361,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3634,7 +3614,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3697,7 +3676,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3727,13 +3705,11 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3748,7 +3724,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3791,7 +3766,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -3827,6 +3801,7 @@ alpha ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -3883,7 +3858,6 @@ alpha ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17200,7 +17174,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17231,8 +17204,6 @@ graph ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -17254,7 +17225,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17341,7 +17311,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17398,6 +17367,7 @@ graph ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -17425,8 +17395,6 @@ graph ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -17448,7 +17416,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17479,6 +17446,7 @@ graph ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -17528,7 +17496,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17580,6 +17547,7 @@ graph ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -17593,7 +17561,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17687,7 +17654,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17753,7 +17719,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17786,7 +17751,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17808,7 +17772,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -17911,8 +17874,6 @@ graph ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -18050,7 +18011,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18354,7 +18314,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18412,7 +18371,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18472,17 +18430,14 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18668,7 +18623,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18922,7 +18876,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -18985,7 +18938,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -19015,13 +18967,11 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -19036,7 +18986,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -19079,7 +19028,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -19115,6 +19063,7 @@ graph ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -19171,7 +19120,6 @@ graph ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -32707,7 +32655,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -32738,8 +32685,6 @@ print ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -32761,7 +32706,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -32848,7 +32792,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -32905,6 +32848,7 @@ print ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -32932,8 +32876,6 @@ print ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -32955,7 +32897,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -32986,6 +32927,7 @@ print ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -33035,7 +32977,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33087,6 +33028,7 @@ print ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -33100,7 +33042,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33194,7 +33135,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33260,7 +33200,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33293,7 +33232,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33315,7 +33253,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33418,8 +33355,6 @@ print ;/ ;/ ;/ ;/ - ;/ - ;/ ;/ ;/ ;/ @@ -33557,7 +33492,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33861,7 +33795,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33919,7 +33852,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -33979,17 +33911,14 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34175,7 +34104,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34429,7 +34357,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34492,7 +34419,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34522,13 +34448,11 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34543,7 +34467,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34586,7 +34509,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ @@ -34622,6 +34544,7 @@ print ;/ ;/ ;/ ;/ + ;/ ;/ ;/ ;/ @@ -34678,7 +34601,6 @@ print ;/ ;/ ;/ ;/ - ;/ ;/ ;/ ;/ diff --git a/share/doc/papers/contents/contents.ms b/share/doc/papers/contents/contents.ms index 12b287a919c3..a303b6c0314d 100644 --- a/share/doc/papers/contents/contents.ms +++ b/share/doc/papers/contents/contents.ms @@ -31,8 +31,8 @@ UNIX Papers coming with FreeBSD These papers are of both historic and current interest, but most of them are many years old. More recent documentation is available from -.>> -http://www.FreeBSD.org/docs/ +.>> +https://www.FreeBSD.org/docs/ .>> .IP diff --git a/share/examples/BSD_daemon/poster.sh b/share/examples/BSD_daemon/poster.sh index 1407701029f0..0f9dd6d33e6a 100644 --- a/share/examples/BSD_daemon/poster.sh +++ b/share/examples/BSD_daemon/poster.sh @@ -50,7 +50,7 @@ center 90 moveto /FreeBSD findfont 50 scalefont setfont center 50 moveto -(http://www.FreeBSD.org) cshow +(https://www.FreeBSD.org) cshow % Do not forget Kirks copyright string. 10 105 moveto diff --git a/share/examples/Makefile b/share/examples/Makefile index 7e3bfe6c5684..8fe52b788689 100644 --- a/share/examples/Makefile +++ b/share/examples/Makefile @@ -136,7 +136,6 @@ XFILES= BSD_daemon/FreeBSD.pfa \ ppp/ppp.secret.sample \ ppp/ppp.secret.span-isp \ ppp/ppp.secret.span-isp.working \ - printing/README \ printing/diablo-if-net \ printing/hpdf \ printing/hpif \ diff --git a/share/examples/libvgl/Makefile.depend b/share/examples/libvgl/Makefile.depend index 2a82ebbb86d2..a7894947a890 100644 --- a/share/examples/libvgl/Makefile.depend +++ b/share/examples/libvgl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/share/examples/printing/README b/share/examples/printing/README deleted file mode 100644 index f83eaa9c236a..000000000000 --- a/share/examples/printing/README +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ -# -# The files in this directory are generated automatically -# from doc/handbook/printing.sgml, do not edit it here! -# -# Please change doc/handbook/printing.sgml or maybe -# src/tools/tools/epfe/epfe.pl instead. diff --git a/share/examples/tests/tests/atf/Makefile.depend b/share/examples/tests/tests/atf/Makefile.depend index 74074b9588ec..c062f6026d94 100644 --- a/share/examples/tests/tests/atf/Makefile.depend +++ b/share/examples/tests/tests/atf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/share/examples/tests/tests/plain/Makefile.depend b/share/examples/tests/tests/plain/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/share/examples/tests/tests/plain/Makefile.depend +++ b/share/examples/tests/tests/plain/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/share/examples/tests/tests/tap/Makefile.depend b/share/examples/tests/tests/tap/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/share/examples/tests/tests/tap/Makefile.depend +++ b/share/examples/tests/tests/tap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/share/man/man4/aesni.4 b/share/man/man4/aesni.4 index 07706e7f55e2..aacbe79cc337 100644 --- a/share/man/man4/aesni.4 +++ b/share/man/man4/aesni.4 @@ -24,12 +24,12 @@ .\" .\" $FreeBSD$ .\" -.Dd December 14, 2015 +.Dd September 26, 2017 .Dt AESNI 4 .Os .Sh NAME .Nm aesni -.Nd "driver for the AES accelerator on Intel CPUs" +.Nd "driver for the AES and SHA accelerator on x86 CPUs" .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your @@ -47,8 +47,8 @@ module at boot time, place the following line in aesni_load="YES" .Ed .Sh DESCRIPTION -Starting with some models of Core i5/i7, Intel processors implement -a new set of instructions called AESNI. +Starting with Intel Westmere and AMD Bulldozer, some x86 processors implement a +new set of instructions called AESNI. The set of six instructions accelerates the calculation of the key schedule for key lengths of 128, 192, and 256 of the Advanced Encryption Standard (AES) symmetric cipher, and provides a hardware @@ -56,13 +56,24 @@ implementation of the regular and the last encryption and decryption rounds. .Pp The processor capability is reported as AESNI in the Features2 line at boot. -The -.Nm -driver does not attach on systems that lack the required CPU capability. +.Pp +Starting with the Intel Goldmont and AMD Ryzen microarchitectures, some x86 +processors implement a new set of SHA instructions. +The set of seven instructions accelerates the calculation of SHA1 and SHA256 +hashes. +.Pp +The processor capability is reported as SHA in the Structured Extended Features +line at boot. .Pp The .Nm -driver registers itself to accelerate AES operations for +driver does not attach on systems that lack both CPU capabilities. +On systems that support only one of AESNI or SHA extensions, the driver will +attach and support that one function. +.Pp +The +.Nm +driver registers itself to accelerate AES and SHA operations for .Xr crypto 4 . Besides speed, the advantage of using the .Nm @@ -83,13 +94,18 @@ The .Nm driver first appeared in .Fx 9.0 . +SHA support was added in +.Fx 12.0 . .Sh AUTHORS .An -nosplit The .Nm driver was written by -.An Konstantin Belousov Aq Mt kib@FreeBSD.org . +.An Konstantin Belousov Aq Mt kib@FreeBSD.org +and +.An Conrad Meyer Aq Mt cem@FreeBSD.org . The key schedule calculation code was adopted from the sample provided by Intel and used in the analogous .Ox driver. +The hash step intrinsics implementations were supplied by Intel. diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4 index d3410d5f9440..d787db1aa141 100644 --- a/share/man/man4/bridge.4 +++ b/share/man/man4/bridge.4 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 27, 2013 +.Dd October 16, 2017 .Dt IF_BRIDGE 4 .Os .Sh NAME @@ -129,8 +129,11 @@ in The MTU of the first member interface to be added is used as the bridge MTU. All additional members are required to have exactly the same value. .Pp -The TXCSUM capability is disabled for any interface added to the bridge, and it -is restored when the interface is removed again. +The TOE, TSO, TXCSUM and TXCSUM6 capabilities on all interfaces added to the +bridge are disabled if any of the interfaces doesn't support/enable them. +The LRO capability is always disabled. +All the capabilities are restored when the interface is removed from bridge. +Changing capabilities in run time may cause NIC reinit and the link flap. .Pp The bridge supports .Dq monitor mode , diff --git a/share/man/man4/crypto.4 b/share/man/man4/crypto.4 index 31edb7f0dbb0..e29b02789263 100644 --- a/share/man/man4/crypto.4 +++ b/share/man/man4/crypto.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 15, 2015 +.Dd September 21, 2017 .Dt CRYPTO 4 .Os .Sh NAME @@ -127,7 +127,9 @@ Asymmetric operations do not use sessions. .It Submit requests, synchronously with .Dv CIOCCRYPT -(symmetric) +(symmetric), +.Dv CIOCCRYPTAEAD +(symmetric), or .Dv CIOCKEY (asymmetric). @@ -279,6 +281,16 @@ supplies the length of the input buffer; the fields .Fa cr_op-\*[Gt]iv supply the addresses of the input buffer, output buffer, one-way hash, and initialization vector, respectively. +If a session is using both a privacy algorithm and a hash algorithm, +the request will generate a hash of the input buffer before +generating the output buffer by default. +If the +.Dv COP_F_CIPHER_FIRST +flag is included in the +.Fa cr_op-\*[Gt]flags +field, +then the request will generate a hash of the output buffer after +executing the privacy algorithm. .It Dv CIOCCRYPTAEAD Fa struct crypt_aead *cr_aead .Bd -literal struct crypt_aead { diff --git a/share/man/man4/cxgbe.4 b/share/man/man4/cxgbe.4 index 8833ba8efdbc..b0d7d8843b8d 100644 --- a/share/man/man4/cxgbe.4 +++ b/share/man/man4/cxgbe.4 @@ -215,23 +215,27 @@ for rx and tx as well an additional pair of queues for TOE rx and tx. The default is 1. .It Va hw.cxgbe.holdoff_timer_idx_10G .It Va hw.cxgbe.holdoff_timer_idx_1G +.It Va hw.cxgbe.holdoff_timer_idx_ofld Timer index value used to delay interrupts. The holdoff timer list has the values 1, 5, 10, 50, 100, and 200 by default (all values are in microseconds) and the index selects a value from this list. +holdoff_timer_idx_ofld applies to queues used for TOE rx. The default value is 1 which means the timer value is 5us. Different interfaces can be assigned different values at any time via the -dev..X.holdoff_tmr_idx sysctl. +dev..X.holdoff_tmr_idx and dev..X.holdoff_tmr_idx_ofld sysctls. .It Va hw.cxgbe.holdoff_pktc_idx_10G .It Va hw.cxgbe.holdoff_pktc_idx_1G +.It Va hw.cxgbe.holdoff_pktc_idx_ofld Packet-count index value used to delay interrupts. The packet-count list has the values 1, 8, 16, and 32 by default, and the index selects a value from this list. +holdoff_pktc_idx_ofld applies to queues used for TOE rx. The default value is -1 which means packet counting is disabled and interrupts are generated based solely on the holdoff timer value. Different interfaces can be assigned different values via the -dev..X.holdoff_pktc_idx sysctl. -This sysctl works only when the interface has never been marked up (as done by +dev..X.holdoff_pktc_idx and dev..X.holdoff_pktc_idx_ofld sysctls. +These sysctls work only when the interface has never been marked up (as done by ifconfig up). .It Va hw.cxgbe.qsize_txq Number of entries in a transmit queue's descriptor ring. diff --git a/share/man/man4/ipmi.4 b/share/man/man4/ipmi.4 index ba99464f17f8..f908911378da 100644 --- a/share/man/man4/ipmi.4 +++ b/share/man/man4/ipmi.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 10, 2007 +.Dd October 25, 2017 .Dt IPMI 4 .Os .Sh NAME @@ -90,6 +90,17 @@ is heavily adopted from the standard and .Tn Linux driver; however, not all features described in the standard are supported. +.Pp +The +.Nm +driver implements the power cycling option to +.Xr shutdown 8 +to implement power cycling of the system. +The motherboard's BMC must support the chassis device and the optional +power cycle subcomand of the chassis control command as described in section 28.3 +of the IPMI standard. +The length of time the system is off will be at least one second, but +may be longer if the power cycle interval has been set (see section 28.9). .Sh IOCTLS Sending and receiving messages through the .Nm @@ -179,6 +190,8 @@ An address supplied was invalid. .Sh SEE ALSO .Xr ioctl 2 , .Xr watchdog 4 , +.Xr reboot 8 , +.Xr shutdown 8 , .Xr watchdog 8 , .Xr watchdogd 8 , .Xr watchdog 9 diff --git a/share/man/man4/iwm.4 b/share/man/man4/iwm.4 index 9b906d7c2d29..90d493c540bb 100644 --- a/share/man/man4/iwm.4 +++ b/share/man/man4/iwm.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 26, 2016 +.Dd October 29, 2017 .Dt IWM 4 .Os .Sh NAME @@ -49,6 +49,7 @@ Choose one from: .Cd "device iwm7260fw" .Cd "device iwm7265fw" .Cd "device iwm8000Cfw" +.Cd "device iwm8265fw" .Ed .Pp Or you can use @@ -67,6 +68,7 @@ iwm3160fw_load="YES" iwm7260fw_load="YES" iwm7265fw_load="YES" iwm8000Cfw_load="YES" +iwm8265fw_load="YES" .Ed .Sh DESCRIPTION The diff --git a/share/man/man4/iwmfw.4 b/share/man/man4/iwmfw.4 index 71017f392645..0a36abfa8ed2 100644 --- a/share/man/man4/iwmfw.4 +++ b/share/man/man4/iwmfw.4 @@ -22,7 +22,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 26, 2016 +.Dd October 29, 2017 .Dt IWMFW 4 .Os .Sh NAME @@ -46,6 +46,7 @@ of the following: .Cd "device iwm7260fw" .Cd "device iwm7265fw" .Cd "device iwm8000Cfw" +.Cd "device iwm8265fw" .Ed .Pp Alternatively, to load the driver as a @@ -57,10 +58,11 @@ iwm7260fw_load="YES" iwm7265fw_load="YES" iwm7265Dfw_load="YES" iwm8000Cfw_load="YES" +iwm8265fw_load="YES" .Ed .Sh DESCRIPTION This module provides access to firmware sets for the -Intel Dual Band Wireless WiFi 3160, 3165, 7260, 7265 and 8260 series of +Intel Dual Band Wireless WiFi 3160, 3165, 7260, 7265, 8000, and 8260 series of IEEE 802.11n/11ac adapters. It may be statically linked into the kernel, or loaded as a module. diff --git a/share/man/man4/lge.4 b/share/man/man4/lge.4 index 734eb4a8ae4f..0e9ecbd421df 100644 --- a/share/man/man4/lge.4 +++ b/share/man/man4/lge.4 @@ -143,7 +143,7 @@ the network connection (cable). .Xr ifconfig 8 .Rs .%T Level 1 LXT1001 Programming Manual -.%U http://www.FreeBSD.org/~wpaul/Level1/LXT1001SRM.pdf +.%U https://www.FreeBSD.org/~wpaul/Level1/LXT1001SRM.pdf .Re .Sh HISTORY The diff --git a/share/man/man4/mac.4 b/share/man/man4/mac.4 index 0c143139d7e0..135301962f3b 100644 --- a/share/man/man4/mac.4 +++ b/share/man/man4/mac.4 @@ -219,7 +219,7 @@ man page. .Rs .%B "The FreeBSD Handbook" .%T "Mandatory Access Control" -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html +.%U https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html .Re .Sh HISTORY The diff --git a/share/man/man4/man4.powerpc/Makefile b/share/man/man4/man4.powerpc/Makefile index 01d5a46dbb83..3b38dd3f6416 100644 --- a/share/man/man4/man4.powerpc/Makefile +++ b/share/man/man4/man4.powerpc/Makefile @@ -8,6 +8,7 @@ MAN= adb.4 \ ams.4 \ bm.4 \ cuda.4 \ + dtsec.4 \ llan.4 \ pmu.4 \ powermac_nvram.4 \ diff --git a/share/man/man4/man4.powerpc/dtsec.4 b/share/man/man4/man4.powerpc/dtsec.4 index 8b6999413d85..93d5b5759fc3 100644 --- a/share/man/man4/man4.powerpc/dtsec.4 +++ b/share/man/man4/man4.powerpc/dtsec.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 16, 2017 +.Dd October 31, 2017 .Dt DTSEC 4 .Os .Sh NAME @@ -89,6 +89,14 @@ P2041, P3041 .It P5010, P5020 .El +.Pp +Additionally, the following devices are expected to work, but are untested: +.Bl -bullet -compact +.It +P4080, P4040 +.It +P5040 +.El .Sh SEE ALSO .Xr altq 4 , .Xr arp 4 , @@ -96,13 +104,6 @@ P5010, P5020 .Xr netintro 4 , .Xr ng_ether 4 , .Xr ifconfig 8 -.Sh BUGS -The -.Nm -driver assumes that there is only one Frame Manager, and that dtsec0 controls -the MDIO interface. Though this is the case for the supported devices, other -SoCs with the DPAA controller may not work correctly. Particularly, the P5040 -and P4080 SoCs have two frame managers, which breaks this assumption. .Sh HISTORY The .Nm diff --git a/share/man/man4/md.4 b/share/man/man4/md.4 index 477465fe9d38..f13aa4d2f676 100644 --- a/share/man/man4/md.4 +++ b/share/man/man4/md.4 @@ -7,14 +7,26 @@ .\" .\" $FreeBSD$ .\" -.Dd October 30, 2007 +.Dd November 5, 2017 .Dt MD 4 .Os .Sh NAME .Nm md .Nd memory disk .Sh SYNOPSIS -.Cd device md +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device md" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +geom_md_load="YES" +.Ed .Sh DESCRIPTION The .Nm diff --git a/share/man/man4/mpr.4 b/share/man/man4/mpr.4 index ecec66efed69..12039f8e0bfb 100644 --- a/share/man/man4/mpr.4 +++ b/share/man/man4/mpr.4 @@ -337,31 +337,46 @@ dev.mpr.X.use_phy_num The same set of values are valid as when setting this tunable for all adapters. .Pp .Sh DEBUGGING -To enable debugging prints from the -.Nm -driver, set the -.Bd -literal -offset indent -hw.mpr.X.debug_level -.Ed -.Pp -tunable, either in +Driver diagnostic printing is controlled in .Xr loader.conf 5 -or by using -.Xr sysctl 8 . -These bits have the described effects: -.Bd -literal -offset indent -0x0001 Enable informational prints (set by default). -0x0002 Enable prints for driver faults (set by default). -0x0004 Enable prints for controller events. -0x0008 Enable prints for controller logging. -0x0010 Enable prints for tracing recovery operations. -0x0020 Enable prints for parameter errors and programming bugs. -0x0040 Enable prints for system initialization operations. -0x0080 Enable prints for more detailed information. -0x0100 Enable prints for user-generated commands (IOCTL). -0x0200 Enable prints for device mapping. -0x0400 Enable prints for tracing through driver functions. -.Ed +by using the global +.Va hw.mpr.debug_level +and per-device +.Va dev.mpr.X.debug_level +tunables. +One can alter the debug level for any adapter at run-time using the +.Xr sysctl 8 +variable +.Va dev.mpr.X.debug_level . +.Pp +All +.Va debug_level +variables can be named by either an integer value or a text string. +Multiple values can be specified together by either ORing the +integer values or by providing a comma-separated list of names. +A text string prefixed by +.Qq + +adds the specified debug levels to the existing set, while the prefix +.Qq - +removes them from the existing set. +The current +.Va debug_level +status is reported in both formats for convenience. +The following levels are available: +.Bl -column "FlagXX" "NameXXXX" "Description" -offset indent +.It Em Flag Ta Em Name Ta Em Description +.It 0x0001 Ta info Ta Basic information (enabled by default) +.It 0x0002 Ta fault Ta Driver faults (enabled by default) +.It 0x0004 Ta event Ta Controller events +.It 0x0008 Ta log Ta Logging data from controller +.It 0x0010 Ta recovery Ta Tracing of recovery operations +.It 0x0020 Ta error Ta Parameter errors and programming bugs +.It 0x0040 Ta init Ta System initialization operations +.It 0x0080 Ta xinfo Ta More detailed information +.It 0x0100 Ta user Ta Tracing of user-generated commands (IOCTL) +.It 0x0200 Ta mapping Ta Tracing of device mapping +.It 0x0400 Ta trace Ta Tracing through driver functions +.El .Sh SEE ALSO .Xr cam 4 , .Xr cd 4 , @@ -378,7 +393,8 @@ These bits have the described effects: .Sh HISTORY The .Nm -driver first appeared in FreeBSD 9.3. +driver first appeared in +.Fx 9.3 . .Sh AUTHORS The .Nm diff --git a/share/man/man4/mps.4 b/share/man/man4/mps.4 index e07ccf91ca24..f40596a7d30a 100644 --- a/share/man/man4/mps.4 +++ b/share/man/man4/mps.4 @@ -313,31 +313,46 @@ dev.mps.X.use_phy_num The same set of values are valid as when setting this tunable for all adapters. .Pp .Sh DEBUGGING -To enable debugging prints from the -.Nm -driver, set the -.Bd -literal -offset indent -hw.mps.X.debug_level -.Ed -.Pp -tunable, either in +Driver diagnostic printing is controlled in .Xr loader.conf 5 -or by using -.Xr sysctl 8 . -These bits have the described effects: -.Bd -literal -offset indent -0x0001 Enable informational prints (set by default). -0x0002 Enable prints for driver faults (set by default). -0x0004 Enable prints for controller events. -0x0008 Enable prints for controller logging. -0x0010 Enable prints for tracing recovery operations. -0x0020 Enable prints for parameter errors and programming bugs. -0x0040 Enable prints for system initialization operations. -0x0080 Enable prints for more detailed information. -0x0100 Enable prints for user-generated commands (IOCTL). -0x0200 Enable prints for device mapping. -0x0400 Enable prints for tracing through driver functions. -.Ed +by using the global +.Va hw.mps.debug_level +and per-device +.Va dev.mps.X.debug_level +tunables. +One can alter the debug level for any adapter at run-time using the +.Xr sysctl 8 +variable +.Va dev.mps.X.debug_level . +.Pp +All +.Va debug_level +variables can be named by either an integer value or a text string. +Multiple values can be specified together by either ORing the +integer values or by providing a comma-separated list of names. +A text string prefixed by +.Qq + +adds the specified debug levels to the existing set, while the prefix +.Qq - +removes them from the existing set. +The current +.Va debug_level +status is reported in both formats for convenience. +The following levels are available: +.Bl -column "FlagXX" "NameXXXX" "Description" -offset indent +.It Em Flag Ta Em Name Ta Em Description +.It 0x0001 Ta info Ta Basic information (enabled by default) +.It 0x0002 Ta fault Ta Driver faults (enabled by default) +.It 0x0004 Ta event Ta Controller events +.It 0x0008 Ta log Ta Logging data from controller +.It 0x0010 Ta recovery Ta Tracing of recovery operations +.It 0x0020 Ta error Ta Parameter errors and programming bugs +.It 0x0040 Ta init Ta System initialization operations +.It 0x0080 Ta xinfo Ta More detailed information +.It 0x0100 Ta user Ta Tracing of user-generated commands (IOCTL) +.It 0x0200 Ta mapping Ta Tracing of device mapping +.It 0x0400 Ta trace Ta Tracing through driver functions +.El .Sh SEE ALSO .Xr cam 4 , .Xr cd 4 , @@ -354,7 +369,8 @@ These bits have the described effects: .Sh HISTORY The .Nm -driver first appeared in FreeBSD 9.3. +driver first appeared in +.Fx 9.0 . .Sh AUTHORS The .Nm diff --git a/share/man/man4/rtwn_usb.4 b/share/man/man4/rtwn_usb.4 index db75257ce5bc..876e56a302cb 100644 --- a/share/man/man4/rtwn_usb.4 +++ b/share/man/man4/rtwn_usb.4 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\"/ -.Dd January 24, 2017 +.Dd October 9, 2017 .Dt RTWN_USB 4 .Os .Sh NAME @@ -64,6 +64,7 @@ based USB wireless network adapters, including: .It "Alfa AWUS036NHR v2" Ta USB 2.0 .It "ASUS USB-AC56" Ta USB 3.0 .It "ASUS USB-N10 NANO" Ta USB 2.0 +.It "Asus USB-N13, rev. B1" Ta USB 2.0 .It "Belkin F7D1102 Surf Wireless Micro" Ta USB 2.0 .It "Buffalo WI-U2-433DM" Ta USB 2.0 .It "Buffalo WI-U3-866D" Ta USB 3.0 diff --git a/share/man/man4/udbp.4 b/share/man/man4/udbp.4 index b455901043ac..3ac8b3fa470c 100644 --- a/share/man/man4/udbp.4 +++ b/share/man/man4/udbp.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 22, 2006 +.Dd October 20, 2017 .Dt UDBP 4 .Os .Sh NAME @@ -48,9 +48,14 @@ udbp_load="YES" The .Nm driver provides support for host-to-host cables -that contain at least two bulk pipes (one for each direction), -for example -the EzLink cable and the NetChip 1080 chip. +that contain at least two bulk pipes (one for each direction). +This typically includes cables branded for use with +.Sy Windows USB Easy Transfer , +and many cables based on the Prolific PL2xx1 series of USB bridge chips. +A useful (but non-comprehensive) list of compatible USB host cables +is listed in the +.Sx SEE ALSO +section below. .Pp .\" XXX The description of how to add netgraph to the kernel .\" is out of place here. It should be limited to the @@ -86,30 +91,64 @@ module and then the .Nm driver. .Pp -.Dl ngctl mkpeer udbp0: iface data inet -.Dl ifconfig ng0 10.0.0.1 10.0.0.2 +.Dl ngctl mkpeer udbp0: eiface data ether +.Dl ifconfig ngeth0 ether aa:dd:xx:xx:xx +.Dl ifconfig ngeth0 inet 169.254.x.x/16 .Pp -Create a new network interface node -and connect its inet hook to the data hook of the +Create a new Ethernet network interface node +and connect its ether hook to the data hook of the .Nm -node. -.Xr ifconfig 8 -configures the resulting network interface ng0 with a local -IP address of 10.0.0.1 and a remote IP address of 10.0.0.2. -On the remote host, the two -IP addresses should of course be reversed. +driver. +.Pp +This enables FreeBSD to communicate with a Linux peer (e.g. using the +.Sy plusb +driver). +The Linux node should be configured to prefer link-local IPv4 addresses +(e.g. using Network Manager in Debian and Red Hat derived distributions). +.Pp +Whilst both FreeBSD and Linux are able to interoperate by +loosely following CDC EEM 1.0 in their behaviour, neither implementation +has been expressly designed to follow its specification. .Sh SEE ALSO .Xr netgraph 4 , -.Xr ng_iface 4 , +.Xr ng_eiface 4 , .Xr ohci 4 , .Xr uhci 4 , .Xr usb 4 , .Xr ngctl 8 +.\" +.Rs +.%B Universal Serial Bus: Communications Class Subclass Specification for Ethernet Emulation Model Devices +.%N Revision 1.0 +.%D February 2, 2005 +.%I USB Implementers Forum, Inc. +.%U http://www.usb.org/developers/docs/devclass_docs/CDC_EEM10.pdf +.Re +.\" +.Rs +.%B Total Commander: Supported cables for USB cable connection +.%I Ghisler Software GmbH. +.%U https://www.ghisler.com/cables/index.htm +.Re +.Sh CAVEATS +The point-to-point nature and additional latency of USB host-host links +makes them unsuitable as a "drop-in" replacement for an Ethernet LAN; +for a USB 3.0 SuperSpeed cable, latency is comparable to 100BaseTX Ethernet +(but often worse), with throughput comparable to 2.5GBASE-T. +.Pp +However, their energy efficiency makes them attractive for embedded +applications. A Plugable PL27A1 cable claims 24mA of USB3 bus power, +as compared to 150mA for a typical USB 3.0 to Gigabit Ethernet interface. .Sh HISTORY The .Nm driver first appeared in .Fx 5.0 . +.Sh BUGS +The +.Nm +driver does not support the special packets described in section 5.1 +of the CDC EEM specification. .Sh AUTHORS .An -nosplit The @@ -121,4 +160,6 @@ and .An Nick Hibma Aq Mt n_hibma@FreeBSD.org . .Pp This manual page was written by -.An Nick Hibma Aq Mt n_hibma@FreeBSD.org . +.An Nick Hibma Aq Mt n_hibma@FreeBSD.org +and updated by +.An Bruce Simpson Aq Mt bms@FreeBSD.org . diff --git a/share/man/man4/usfs.4 b/share/man/man4/usfs.4 index e8610beb9b7b..a81f6717b79c 100644 --- a/share/man/man4/usfs.4 +++ b/share/man/man4/usfs.4 @@ -65,4 +65,5 @@ Upon attach the driver creates a RAM disk which can be read and written. .Sh HISTORY The .Nm -driver appeared in FreeBSD 8. +driver appeared in +.Fx 8.0 . diff --git a/share/man/man5/procfs.5 b/share/man/man5/procfs.5 index cea1505f2b75..8532762a154e 100644 --- a/share/man/man5/procfs.5 +++ b/share/man/man5/procfs.5 @@ -196,7 +196,6 @@ file system on .Xr mount 2 , .Xr sigaction 2 , .Xr unmount 2 , -.Xr procctl 8 , .Xr pseudofs 9 .Sh AUTHORS .An -nosplit diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index eb4a0fca9f16..76415f06b6e2 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 26, 2017 +.Dd October 24, 2017 .Dt RC.CONF 5 .Os .Sh NAME @@ -64,6 +64,9 @@ is used to override settings in .Pa /etc/rc.conf for historical reasons. .Pp +The sysrc(8) command provides a scripting interface to modify system +config files. +.Pp In addition to .Pa /etc/rc.conf.local you can also place smaller configuration files for each @@ -3377,6 +3380,13 @@ Otherwise, the value of this variable is passed as the argument to .Xr dumpon 8 . To disable crash dumps, set this variable to .Dq Li NO . +.It Va dumpon_flags +.Pq Vt str +Flags to pass to +.Xr dumpon 8 +when configuring +.Va dumpdev +as the system dump device. .It Va dumpdir .Pq Vt str When the system reboots after a crash and a crash dump is found on the @@ -3397,18 +3407,6 @@ to not run at boot time when .Va dumpdir is set. -.It Va dumppubkey -.Pq Vt str -Path to a public key. -It is used by -.Xr dumpon 8 -to encrypt a one-time key for a crash dump. -The public key has to match a private key used by -.Xr decryptcore 8 -to decrypt a crash dump after reboot. -See -.Xr dumpon 8 -for more details. .It Va savecore_enable .Pq Vt bool If set to @@ -4537,6 +4535,7 @@ configuration file. .Xr swapon 8 , .Xr sysctl 8 , .Xr syslogd 8 , +.Xr sysrc 8 , .Xr timed 8 , .Xr unbound 8 , .Xr usbconfig 8 , diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 0d67b68cb1c1..c28688a3c77c 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd August 14, 2017 +.Dd November 2, 2017 .Dt SRC.CONF 5 .Os .Sh NAME @@ -73,12 +73,10 @@ variable, which defaults to Some examples that may only be set in this file are .Va WITH_DIRDEPS_BUILD , and -.Va WITH_META_MODE -as they are environment-only variables. -Note that +.Va WITH_META_MODE , +and .Va MAKEOBJDIRPREFIX -may be set here only when using -.Va WITH_DIRDEPS_BUILD . +as they are environment-only variables. .Pp The values of variables are ignored regardless of their setting; even if they would be set to @@ -131,8 +129,9 @@ Set to not build Set to not build .Xr autofs 5 related programs, libraries, and kernel modules. -.It Va WITH_AUTO_OBJ -Enable automatic creation of objdirs. +.It Va WITHOUT_AUTO_OBJ +Disable automatic creation of objdirs. +This is enabled by default if the wanted OBJDIR is writable by the current user. .Pp This must be set in the environment, make command line, or .Pa /etc/src-env.conf , @@ -162,7 +161,7 @@ Set to build and install binutils (as, ld, objcopy, and objdump) as part of the normal system build. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITHOUT_BINUTILS_BOOTSTRAP Set to not build binutils (as, ld, objcopy and objdump) as part of the bootstrap process. @@ -178,7 +177,7 @@ Set build binutils (as, ld, objcopy and objdump) as part of the bootstrap process. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITHOUT_BLACKLIST Set this if you do not want to build .Xr blacklistd 8 @@ -220,11 +219,6 @@ Set to not build the BSD licensed version of cpio based on .Xr libarchive 3 . .It Va WITH_BSD_GREP Install BSD-licensed grep as '[ef]grep' instead of GNU grep. -.It Va WITHOUT_BSD_GREP_FASTMATCH -Set this option to exclude the fastmatch implementation from -.Xr bsdgrep 1 , -instead using only -.Xr regex 3 . .It Va WITHOUT_BSNMP Set to not build or install .Xr bsnmpd 1 @@ -325,7 +319,7 @@ When set, it enforces these options: Set to build the Clang C/C++ compiler during the normal phase of the build. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. .It Va WITHOUT_CLANG_BOOTSTRAP Set to not build the Clang C/C++ compiler during the bootstrap phase of the build. @@ -338,7 +332,7 @@ mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, Set to build the Clang C/C++ compiler during the bootstrap phase of the build. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64 and i386/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386. .It Va WITH_CLANG_EXTRAS Set to build additional clang and llvm tools, such as bugpoint. .It Va WITHOUT_CLANG_FULL @@ -352,7 +346,7 @@ Set to build the ARCMigrate, Rewriter and StaticAnalyzer components of the Clang C/C++ compiler. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. .It Va WITHOUT_CLANG_IS_CC Set to install the GCC compiler as .Pa /usr/bin/cc , @@ -370,7 +364,7 @@ and .Pa /usr/bin/cpp . .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64 and i386/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386. .It Va WITHOUT_CPP Set to not build .Xr cpp 1 . @@ -437,7 +431,7 @@ Set to not build .Xr cxgbetool 8 .Pp This is a default setting on -arm/arm, arm/armeb, arm/armv6, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpcspe, riscv/riscv64 and riscv/riscv64sf. +arm/arm, arm/armeb, arm/armv6, arm/armv7, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpcspe, riscv/riscv64 and riscv/riscv64sf. .It Va WITH_CXGBETOOL Set to build .Xr cxgbetool 8 @@ -479,7 +473,7 @@ Set to build and related libraries. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITHOUT_DEBUG_FILES Set to avoid building or installing standalone debug files for each executable binary and shared library. @@ -544,10 +538,6 @@ When set, it enforces these options: When set, these options are also in effect: .Pp .Bl -inset -compact -.It Va WITH_AUTO_OBJ -(unless -.Va WITHOUT_AUTO_OBJ -is set explicitly) .It Va WITH_META_MODE (unless .Va WITHOUT_META_MODE @@ -624,7 +614,7 @@ and .Xr efivar 8 . .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64 and i386/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386. .It Va WITHOUT_ELFTOOLCHAIN_BOOTSTRAP Set to not build ELF Tool Chain tools (addr2line, nm, size, strings and strip) @@ -680,7 +670,7 @@ Set to not build games. Set to not build and install gcc and g++ as part of the normal build process. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. .It Va WITH_GCC Set to build and install gcc and g++. .Pp @@ -693,7 +683,7 @@ unless an alternative compiler is provided via XCC. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. .It Va WITH_GCC_BOOTSTRAP Set to build gcc and g++ as part of the bootstrap process. .Pp @@ -714,7 +704,7 @@ Set to build .Xr gdb 1 . .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITHOUT_GDB_LIBEXEC Set to install .Xr gdb 1 @@ -722,7 +712,7 @@ into .Pa /usr/bin . .Pp This is a default setting on -arm/arm, arm/armeb, arm/armv6 and sparc64/sparc64. +arm/arm, arm/armeb, arm/armv6, arm/armv7 and sparc64/sparc64. .It Va WITH_GDB_LIBEXEC Set to install .Xr gdb 1 @@ -741,7 +731,7 @@ Do not build the GNU C++ stack (g++, libstdc++). This is the default on platforms where clang is the system compiler. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, riscv/riscv64 and riscv/riscv64sf. .It Va WITH_GNUCXX Build the GNU C++ stack (g++, libstdc++). This is the default on platforms where gcc is the system compiler. @@ -769,13 +759,13 @@ Set to build the BSD licensed version of the device tree compiler rather than the GPLed one from elinux.org. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpcspe. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386. .It Va WITH_GPL_DTC Set to build the GPL'd version of the device tree compiler from elinux.org, instead of the BSD licensed one. .Pp This is a default setting on -riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITHOUT_GSSAPI Set to not build libgssapi. .It Va WITHOUT_HAST @@ -962,12 +952,12 @@ mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, Set to build LLVM's lld linker. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64 and i386/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386. .It Va WITHOUT_LLDB Set to not build the LLDB debugger. .Pp This is a default setting on -arm/arm, arm/armeb, arm/armv6, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +arm/arm, arm/armeb, arm/armv6, arm/armv7, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITH_LLDB Set to build the LLDB debugger. .Pp @@ -980,7 +970,7 @@ To be able to build the system, either Binutils or LLD bootstrap must be enabled unless an alternate linker is provided via XLD. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITH_LLD_BOOTSTRAP Set to build the LLD linker during the bootstrap phase of the build. .Pp @@ -990,7 +980,7 @@ arm64/aarch64. Set to use GNU binutils ld as the system linker, instead of LLVM's LLD. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITH_LLD_IS_LD Set to use LLVM's LLD as the system linker, instead of GNU binutils ld. .Pp @@ -1000,7 +990,7 @@ arm64/aarch64. Set to use GCC's stack unwinder (instead of LLVM's libunwind). .Pp This is a default setting on -arm/arm, arm/armeb, arm/armv6, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +arm/arm, arm/armeb, arm/armv6, arm/armv7, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITH_LLVM_LIBUNWIND Set to use LLVM's libunwind stack unwinder (instead of GCC's unwinder). .Pp @@ -1269,7 +1259,7 @@ Set to build profiled libraries for use with .Xr gprof 8 . .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mipsn32, mips/mipselhf, mips/mipshf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, mips/mipsel, mips/mips, mips/mipsn32, mips/mipselhf, mips/mipshf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and sparc64/sparc64. .It Va WITHOUT_QUOTAS Set to not build .Xr quota 1 @@ -1294,14 +1284,6 @@ by proxy. .It Va WITHOUT_RBOOTD Set to not build or install .Xr rbootd 8 . -.It Va WITH_RCMDS -Enable building of the -.Bx -r-commands. -This includes -.Xr rlogin 1 , -.Xr rsh 1 , -etc. .It Va WITH_REPRODUCIBLE_BUILD Set to exclude build metadata (such as the build time, user, or host) from the kernel, boot loaders, and uname output, so that builds produce @@ -1361,7 +1343,7 @@ mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, Set to build world with propolice stack smashing protection. .Pp This is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. .It Va WITH_STAGING Enable staging of files to a stage tree. This can be best thought of as auto-install to @@ -1512,6 +1494,26 @@ When set, it enforces these options: Set to not build .Xr unbound 8 and related programs. +.It Va WITHOUT_UNIFIED_OBJDIR +Set to use the historical object directory format for +.Xr build 7 +targets. +For native-builds and builds done directly in sub-directories the format of +.Pa ${MAKEOBJDIRPREFIX}/${.CURDIR} +is used, +while for cross-builds +.Pa ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH}/${.CURDIR} +is used. +.Pp +This option is transitional and will be removed before the 12.0 release, +at which time +.va WITH_UNIFIED_OBJDIR +will be enabled permanently. +.Pp +This must be set in the environment, make command line, or +.Pa /etc/src-env.conf , +not +.Pa /etc/src.conf . .It Va WITHOUT_USB Set to not build USB-related programs and libraries. .It Va WITHOUT_USB_GADGET_EXAMPLES diff --git a/share/man/man7/Makefile b/share/man/man7/Makefile index 83e97bc52ab6..cc4826242341 100644 --- a/share/man/man7/Makefile +++ b/share/man/man7/Makefile @@ -6,8 +6,7 @@ PACKAGE=runtime-manuals #MISSING: eqnchar.7 ms.7 term.7 -MAN= adding_user.7 \ - arch.7 \ +MAN= arch.7 \ ascii.7 \ bsd.snmpmod.mk.7 \ build.7 \ diff --git a/share/man/man7/adding_user.7 b/share/man/man7/adding_user.7 deleted file mode 100644 index b0f7e8c1ed89..000000000000 --- a/share/man/man7/adding_user.7 +++ /dev/null @@ -1,106 +0,0 @@ -.\" Copyright (c) 1980, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)adduser.8 8.1 (Berkeley) 6/5/93 -.\" $FreeBSD$ -.\" -.Dd January 30, 2009 -.Dt ADDING_USER 8 -.Os -.Sh NAME -.Nm adding_user -.Nd procedure for adding new users -.Sh DESCRIPTION -A new user must choose a login name, which must not already appear in -.Pa /etc/passwd -or -.Pa /etc/mail/aliases . -It must also not begin with the hyphen -.Sq Fl -character. -It is strongly recommended that it be all lower-case, and not contain -the dot -.Ql .\& -character, as that tends to confuse mailers. -An account can be added by editing a line into the passwd file; this -must be done with the password file locked e.g.\& by using -.Xr chpass 1 -or -.Xr vipw 8 . -.Pp -A new user is given a group and user id. -Login and user id's should be unique across the system, and often across -a group of systems, since they are used to control file access. -Typically, users working on similar projects will be put in the same groups. -At the University of California, Berkeley, we have groups for system staff, -faculty, graduate students, and special groups for large projects. -.Pp -A skeletal account for a new user -.Dq ernie -might look like: -.Bd -literal -ernie::25:30::0:0:Ernie Kovacs,508 Evans Hall,x7925, - 642-8202:/a/users/ernie:/bin/csh -.Ed -.Pp -For a description of each of these fields, see -.Xr passwd 5 . -.Pp -It is useful to give new users some help in getting started, supplying -them with a few skeletal files such as -.Pa \&.profile -if they use -.Pa /bin/sh , -or -.Pa \&.cshrc -and -.Pa \&.login -if they use -.Pa /bin/csh . -The directory -.Pa /usr/share/skel -contains skeletal definitions of such files. -New users should be given copies of these files which, for instance, -use -.Xr tset 1 -automatically at each login. -.Sh FILES -.Bl -tag -width /etc/master.passwdxx -compact -.It Pa /etc/master.passwd -user database -.It Pa /usr/share/skel -skeletal login directory -.El -.Sh SEE ALSO -.Xr chpass 1 , -.Xr finger 1 , -.Xr passwd 1 , -.Xr aliases 5 , -.Xr passwd 5 , -.Xr adduser 8 , -.Xr pwd_mkdb 8 , -.Xr vipw 8 diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7 index b95c627646bb..82228ccff4a5 100644 --- a/share/man/man7/arch.7 +++ b/share/man/man7/arch.7 @@ -212,8 +212,7 @@ Machine-dependent type sizes: .El .Pp .Sy time_t -is 8 bytes on all supported architectures except i386 and 32-bit -variants of powerpc. +is 8 bytes on all supported architectures except i386. .Ss Endianness and Char Signedness .Bl -column -offset indent "Sy Architecture" "Sy Endianness" "Sy char Signedness" .It Sy Architecture Ta Sy Endianness Ta Sy char Signedness diff --git a/share/man/man7/ascii.7 b/share/man/man7/ascii.7 index 586a5374b6b3..3b5c120cb004 100644 --- a/share/man/man7/ascii.7 +++ b/share/man/man7/ascii.7 @@ -28,7 +28,7 @@ .\" @(#)ascii.7 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd March 10, 2017 +.Dd October 30, 2017 .Dt ASCII 7 .Os .Sh NAME @@ -137,7 +137,7 @@ CAN 8 X x 11000 EM 9 Y y 11001 SUB : Z z 11010 ESC ; [ { 11011 - FS < \ | 11100 + FS < \e\ | 11100 GS = ] } 11101 RS > ^ - 11110 US ? _ DEL 11111 diff --git a/share/man/man7/build.7 b/share/man/man7/build.7 index d5036daf87b5..aabae96fa7ab 100644 --- a/share/man/man7/build.7 +++ b/share/man/man7/build.7 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 11, 2017 +.Dd November 3, 2017 .Dt BUILD 7 .Os .Sh NAME @@ -82,18 +82,7 @@ or under if variable .Va MAKEOBJDIRPREFIX is not set. -For a given source directory, its canonical object directory -would be -.Pa ${MAKEOBJDIRPREFIX}${.CURDIR} -if -.Xr make 1 -variable -.Va MAKEOBJDIRPREFIX -is set, or -.Pa /usr/obj${.CURDIR} -if this variable is not set. -Cross-builds set the object directory as described in the -documentation for the +The canonical object directory is described in the documentation for the .Cm buildworld target below. .Pp @@ -201,17 +190,32 @@ by setting the .Pa MAKEOBJDIRPREFIX .Xr make 1 variable. -The actual build location prefix used is +The actual build location prefix used +depends on the +.Va WITH_UNIFIED_OBJDIR +option from +.Xr src.conf 5 . +If enabled it is +.Pa ${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH} +for all builds. +If disabled it is .Pa ${MAKEOBJDIRPREFIX}${.CURDIR} for native builds, and -.Pa ${MAKEOBJDIRPREFIX}/${TARGET}${.CURDIR} +.Pa ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH}${.CURDIR} for cross builds and native builds with variable .Va CROSS_BUILD_TESTING set. .It Cm cleanworld Attempt to clean up targets built by a preceding -.Cm buildworld -step. +.Cm buildworld , +or similar step built from this source directory. +.It Cm cleanuniverse +When +.Va WITH_UNIFIED_OBJDIR +is enabled, attempt to clean up targets built by a preceding +.Cm buildworld , +.Cm universe , +or similar step, for any architecture built from this source directory. .It Cm distributeworld Distribute everything compiled by a preceding .Cm buildworld @@ -222,6 +226,29 @@ variable .Va DISTDIR . This target is used while building a release; see .Xr release 7 . +.It Cm native-xtools +This target builds a cross-toolchain for the given +.Sy TARGET +and +.Sy TARGET_ARCH , +as well as a select list of static userland tools for the host system. +This is intended to be used in a jail where QEMU is used to improve +performance by avoiding emulating binaries that do not need to be emulated. +.Sy TARGET +and +.Sy TARGET_ARCH +should be defined. +.It Cm native-xtools-install +Installs the results to +.Pa ${DESTDIR}/${NXTP} +where +.Va NXTP +defaults to +.Pa nxb-bin . +.Sy TARGET +and +.Sy TARGET_ARCH +must be defined. .It Cm packageworld Archive the results of .Cm distributeworld , @@ -276,6 +303,43 @@ In addition print a summary of all failed targets at the end and exit with an error if there were any. .It Cm toolchains Create a build toolchain for each architecture supported by the build system. +.It Cm xdev +Builds and installs a cross-toolchain and sysroot for the given +.Sy TARGET +and +.Sy TARGET_ARCH . +The sysroot contains target library and headers. +The target is an alias for +.Cm xdev-build +and +.Cm xdev-install . +The location of the files installed can be controlled with +.Va DESTDIR . +The target location in +.Va DESTDIR +is +.Pa ${DESTDIR}/${XDTP} +where +.Va XDTP +defaults to +.Pa /usr/${XDDIR} +and +.Va XDDIR +defaults to +.Pa ${TARGET_ARCH}-freebsd . +.It Cm xdev-build +Builds for the +.Cm xdev +target. +.It Cm xdev-install +Installs the files for the +.Cm xdev +target. +.It Cm xdev-links +Installs autoconf-style symlinks to +.Pa ${DESTDIR}/usr/bin +pointing into the xdev toolchain in +.Pa ${DESTDIR}/${XDTP} . .El .Pp Kernel specific build targets in @@ -400,8 +464,12 @@ Defines the prefix for directory names in the tree of built objects. Defaults to .Pa /usr/obj if not defined. -This variable should only be set in the environment and not via +This variable should only be set in the environment or +.Pa /etc/src-env.conf +and not via .Pa /etc/make.conf +or +.Pa /etc/src.conf or the command line. .It Va NO_WERROR If defined, compiler warnings will not cause the build to halt, @@ -615,7 +683,7 @@ documentation as part of the target. .It Va NO_LIBS If set, the libraries phase will be skipped. -.It Va NO_OBJ +.It Va NO_OBJWALK If set, no object directories will be created. This should only be used if object directories were created in a previous build and no new directories are connected. @@ -632,7 +700,7 @@ If set, the build target .Cm buildworld defaults to setting .Va NO_CLEAN , -.Va NO_OBJ , +.Va NO_OBJWALK , and will skip most bootstrap phases. It will only bootstrap libraries and build all of userland. This option should be used only when it is known that none of the bootstrap diff --git a/share/man/man7/ports.7 b/share/man/man7/ports.7 index 99d566580385..73cc63c7d7c9 100644 --- a/share/man/man7/ports.7 +++ b/share/man/man7/ports.7 @@ -62,12 +62,12 @@ in .%B "The FreeBSD Handbook" , .Pa ( file:/usr/share/doc/en_US.ISO8859-1/books/handbook/ports.html or -.Pa http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/ports.html ) . +.Pa https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/ports.html ) . For information about creating new ports, see .%B "The Porter's Handbook" .Pa ( file:/usr/share/doc/en_US.ISO8859-1/books/porters-handbook/index.html or -.Pa http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/porters-handbook/ ) . +.Pa https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/porters-handbook/ ) . .Sh TARGETS Some of the targets work recursively through subdirectories. This lets you, for example, install all of the @@ -430,7 +430,7 @@ cluster (for .Cm fetchindex target). Defaults to -.Pa http://www.FreeBSD.org/ports/ . +.Pa https://www.FreeBSD.org/ports/ . .It Va FETCHINDEX Command to get .Pa INDEX @@ -545,7 +545,7 @@ The following are part of the ports collection: .%B "The FreeBSD Handbook" .Re .Pp -.Pa http://www.FreeBSD.org/ports +.Pa https://www.FreeBSD.org/ports (searchable index of all ports) .Sh HISTORY The Ports Collection diff --git a/share/man/man7/release.7 b/share/man/man7/release.7 index 2bc5c237562b..065ef1037332 100644 --- a/share/man/man7/release.7 +++ b/share/man/man7/release.7 @@ -717,11 +717,11 @@ variable in .Xr sysctl 8 .Rs .%T "FreeBSD Release Engineering" -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/releng/ +.%U https://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/releng/ .Re .Rs .%T "FreeBSD Developers' Handbook" -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/ +.%U https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/ .Re .Sh HISTORY .Fx diff --git a/share/man/man7/tests.7 b/share/man/man7/tests.7 index a40cf6af001c..6a5b07baa18c 100644 --- a/share/man/man7/tests.7 +++ b/share/man/man7/tests.7 @@ -200,7 +200,7 @@ For more details please refer to: .It .Lk http://lists.freebsd.org/ "FreeBSD Mailing Lists" .It -.Lk http://www.freebsd.org/support.html "Problem Reporting" +.Lk https://www.freebsd.org/support.html "Problem Reporting" .El .Sh FILES .Bl -tag -compact -width usrXlocalXetcXkyuaXkyuaXconfXX diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7 index be692b8e8373..ff79b48fc414 100644 --- a/share/man/man7/tuning.7 +++ b/share/man/man7/tuning.7 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 22, 2017 +.Dd October 30, 2017 .Dt TUNING 7 .Os .Sh NAME @@ -41,8 +41,7 @@ Configuring too little swap can lead to inefficiencies in the VM page scanning code as well as create issues later on if you add more memory to your machine. On larger systems -with multiple SCSI disks (or multiple IDE disks operating on different -controllers), configure swap on each drive. +with multiple disks, configure swap on each drive. The swap partitions on the drives should be approximately the same size. The kernel can handle arbitrary sizes but internal data structures scale to 4 times the largest swap partition. @@ -176,11 +175,6 @@ This means you want to use a large off-center stripe size such as 1152 sectors so sequential I/O does not seek both disks and so meta-data is distributed across both disks rather than concentrated on a single disk. -If -you really need to get sophisticated, we recommend using a real hardware -RAID controller from the list of -.Fx -supported controllers. .Sh SYSCTL TUNING .Xr sysctl 8 variables permit system behavior to be monitored and controlled at @@ -347,9 +341,6 @@ is adhered to. .Pp There are various other buffer-cache and VM page cache related sysctls. We do not recommend modifying these values. -As of -.Fx 4.3 , -the VM system does an extremely good job tuning itself. .Pp The .Va net.inet.tcp.sendspace @@ -547,30 +538,12 @@ and reboot the system. .Va kern.maxusers controls the scaling of a number of static system tables, including defaults for the maximum number of open files, sizing of network memory resources, etc. -As of -.Fx 4.5 , .Va kern.maxusers is automatically sized at boot based on the amount of memory available in the system, and may be determined at run-time by inspecting the value of the read-only .Va kern.maxusers sysctl. -Some sites will require larger or smaller values of -.Va kern.maxusers -and may set it as a loader tunable; values of 64, 128, and 256 are not -uncommon. -We do not recommend going above 256 unless you need a huge number -of file descriptors; many of the tunable values set to their defaults by -.Va kern.maxusers -may be individually overridden at boot-time or run-time as described -elsewhere in this document. -Systems older than -.Fx 4.4 -must set this value via the kernel -.Xr config 8 -option -.Cd maxusers -instead. .Pp The .Va kern.dfldsiz @@ -619,14 +592,6 @@ The option to .Xr netstat 1 may be used to observe network cluster use. -Older versions of -.Fx -do not have this tunable and require that the -kernel -.Xr config 8 -option -.Dv NMBCLUSTERS -be set instead. .Pp More and more programs are using the .Xr sendfile 2 @@ -705,11 +670,6 @@ can be used to monitor this. There are many solutions to saturated disks: increasing memory for caching, mirroring disks, distributing operations across several machines, and so forth. -If disk performance is an issue and you -are using IDE drives, switching to SCSI can help a great deal. -While modern -IDE drives compare with SCSI in raw sequential bandwidth, the moment you -start seeking around the disk SCSI drives usually win. .Pp Finally, you might run out of network suds. Optimize the network path @@ -718,10 +678,7 @@ For example, in .Xr firewall 7 we describe a firewall protecting internal hosts with a topology where the externally visible hosts are not routed through it. -Use 1000BaseT rather -than 100BaseT, depending on your needs. -Most bottlenecks occur at the WAN link (e.g.,\& -modem, T1, DSL, whatever). +Most bottlenecks occur at the WAN link. If expanding the link is not an option it may be possible to use the .Xr dummynet 4 feature to implement peak shaving or other forms of traffic shaping to diff --git a/share/man/man8/crash.8 b/share/man/man8/crash.8 index 3383a75900fe..63b814881bd1 100644 --- a/share/man/man8/crash.8 +++ b/share/man/man8/crash.8 @@ -203,7 +203,7 @@ the panic message is printed. For more details consult the chapter on kernel debugging in the .%B "FreeBSD Developers' Handbook" -.Pq Pa http://www.freebsd.org/doc/en/books/developers-handbook/ . +.Pq Pa https://www.freebsd.org/doc/en/books/developers-handbook/ . .Sh SEE ALSO .Xr kgdb 1 , .Xr dumpon 8 , diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8 index 2aa7d3aa6ad2..cb0aab7f1bab 100644 --- a/share/man/man8/rc.8 +++ b/share/man/man8/rc.8 @@ -87,6 +87,9 @@ The .Nm rc.d/ directories contain scripts which will be automatically executed at boot time and shutdown time. +.Pp +The sysrc(8) command provides a scripting interface to modify system +config files. .Ss Operation of Nm .Bl -enum .It @@ -548,7 +551,8 @@ is unnecessary, but is often included. .Xr rc.subr 8 , .Xr rcorder 8 , .Xr reboot 8 , -.Xr savecore 8 +.Xr savecore 8 , +.Xr sysrc 8 .Sh HISTORY The .Nm diff --git a/share/man/man8/uefi.8 b/share/man/man8/uefi.8 index 4f7935ed5a7d..a37fe21b48b7 100644 --- a/share/man/man8/uefi.8 +++ b/share/man/man8/uefi.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 11, 2016 +.Dd October 23, 2017 .Dt UEFI 8 .Os .Sh NAME @@ -37,7 +37,7 @@ Unified Extensible Firmware Interface provides boot- and run-time services to operating systems. .Nm is a replacement for the legacy BIOS on the i386 and amd64 CPU architectures, -and is also used on arm64 and ia64. +and is also used on arm, arm64 and ia64. .Pp The .Nm diff --git a/share/man/man9/EVENTHANDLER.9 b/share/man/man9/EVENTHANDLER.9 index b6be88319b4f..93dcfc02b0a2 100644 --- a/share/man/man9/EVENTHANDLER.9 +++ b/share/man/man9/EVENTHANDLER.9 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" $FreeBSD$ .\" -.Dd March 27, 2017 +.Dd October 1, 2017 .Dt EVENTHANDLER 9 .Os .Sh NAME @@ -37,6 +37,7 @@ .Ft eventhandler_tag .Fn EVENTHANDLER_REGISTER name func arg priority .Fn EVENTHANDLER_DEREGISTER name tag +.Fn EVENTHANDLER_DEREGISTER_NOWAIT name tag .Ft eventhandler_tag .Fo eventhandler_register .Fa "struct eventhandler_list *list" @@ -50,6 +51,11 @@ .Fa "struct eventhandler_list *list" .Fa "eventhandler_tag tag" .Fc +.Ft void +.Fo eventhandler_deregister_nowait +.Fa "struct eventhandler_list *list" +.Fa "eventhandler_tag tag" +.Fc .Ft "struct eventhandler_list *" .Fn eventhandler_find_list "const char *name" .Ft void @@ -121,6 +127,18 @@ This macro removes a previously registered callback associated with tag .Fa tag from the event handler named by argument .Fa name . +It waits until no threads are running handlers for this event before +returning, making it safe to unload a module immediately upon return +from this function. +.It Fn EVENTHANDLER_DEREGISTER_NOWAIT +This macro removes a previously registered callback associated with tag +.Fa tag +from the event handler named by argument +.Fa name . +Upon return, one or more threads could still be running the removed +function(s), but no new calls will be made. +To remove a handler function from within that function, use this +version of deregister, to avoid a deadlock. .It Fn EVENTHANDLER_INVOKE This macro is used to invoke all the callbacks associated with event handler @@ -182,6 +200,21 @@ function removes the callback associated with tag .Fa tag from the event handler list pointed to by .Fa list . +If +.Fa tag +is +.Va NULL , +all callback functions for the event are removed. +This function will not return until all threads have exited from the +removed handler callback function(s). +This function is not safe to call from inside an event handler callback. +.It Fn eventhandler_deregister_nowait +The +.Fn eventhandler_deregister +function removes the callback associated with tag +.Fa tag +from the event handler list pointed to by +.Fa list . This function is safe to call from inside an event handler callback. .It Fn eventhandler_find_list diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 7d0ba0000ad7..400995fb0d6f 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -184,7 +184,6 @@ MAN= accept_filter.9 \ make_dev.9 \ malloc.9 \ mbchain.9 \ - mbpool.9 \ mbuf.9 \ mbuf_tags.9 \ MD5.9 \ @@ -414,6 +413,7 @@ MAN= accept_filter.9 \ MLINKS= unr.9 alloc_unr.9 \ unr.9 alloc_unrl.9 \ unr.9 alloc_unr_specific.9 \ + unr.9 clear_unrhdr.9 \ unr.9 delete_unrhdr.9 \ unr.9 free_unr.9 \ unr.9 new_unrhdr.9 @@ -760,7 +760,8 @@ MLINKS+=devstat.9 devicestat.9 \ devstat.9 devstat_end_transaction.9 \ devstat.9 devstat_remove_entry.9 \ devstat.9 devstat_start_transaction.9 -MLINKS+=disk.9 disk_alloc.9 \ +MLINKS+=disk.9 disk_add_alias.9 \ + disk.9 disk_alloc.9 \ disk.9 disk_create.9 \ disk.9 disk_destroy.9 \ disk.9 disk_gone.9 \ @@ -1161,16 +1162,6 @@ MLINKS+=mbchain.9 mb_detach.9 \ mbchain.9 mb_put_uint8.9 \ mbchain.9 mb_put_uio.9 \ mbchain.9 mb_reserve.9 -MLINKS+=mbpool.9 mbp_alloc.9 \ - mbpool.9 mbp_card_free.9 \ - mbpool.9 mbp_count.9 \ - mbpool.9 mbp_create.9 \ - mbpool.9 mbp_destroy.9 \ - mbpool.9 mbp_ext_free.9 \ - mbpool.9 mbp_free.9 \ - mbpool.9 mbp_get.9 \ - mbpool.9 mbp_get_keep.9 \ - mbpool.9 mbp_sync.9 MLINKS+=\ mbuf.9 m_adj.9 \ mbuf.9 m_align.9 \ @@ -1316,13 +1307,18 @@ MLINKS+=nv.9 libnv.9 \ nv.9 nvlist.9 \ nv.9 nvlist_add_binary.9 \ nv.9 nvlist_add_bool.9 \ + nv.9 nvlist_add_bool_array.9 \ nv.9 nvlist_add_descriptor.9 \ + nv.9 nvlist_add_descriptor_array.9 \ nv.9 nvlist_add_null.9 \ nv.9 nvlist_add_number.9 \ + nv.9 nvlist_add_number_array.9 \ nv.9 nvlist_add_nvlist.9 \ + nv.9 nvlist_add_nvlist_array.9 \ nv.9 nvlist_add_string.9 \ nv.9 nvlist_add_stringf.9 \ nv.9 nvlist_add_stringv.9 \ + nv.9 nvlist_add_string_array.9 \ nv.9 nvlist_clone.9 \ nv.9 nvlist_create.9 \ nv.9 nvlist_destroy.9 \ @@ -1332,10 +1328,14 @@ MLINKS+=nv.9 libnv.9 \ nv.9 nvlist_exists.9 \ nv.9 nvlist_exists_binary.9 \ nv.9 nvlist_exists_bool.9 \ + nv.9 nvlist_exists_bool_array.9 \ nv.9 nvlist_exists_descriptor.9 \ + nv.9 nvlist_exists_descriptor_array.9 \ nv.9 nvlist_exists_null.9 \ nv.9 nvlist_exists_number.9 \ + nv.9 nvlist_exists_number_array.9 \ nv.9 nvlist_exists_nvlist.9 \ + nv.9 nvlist_exists_nvlist_array.9 \ nv.9 nvlist_exists_string.9 \ nv.9 nvlist_exists_type.9 \ nv.9 nvlist_fdump.9 \ @@ -1343,23 +1343,36 @@ MLINKS+=nv.9 libnv.9 \ nv.9 nvlist_free.9 \ nv.9 nvlist_free_binary.9 \ nv.9 nvlist_free_bool.9 \ + nv.9 nvlist_free_bool_array.9 \ nv.9 nvlist_free_descriptor.9 \ + nv.9 nvlist_free_descriptor_array.9 \ nv.9 nvlist_free_null.9 \ nv.9 nvlist_free_number.9 \ + nv.9 nvlist_free_number_array.9 \ nv.9 nvlist_free_nvlist.9 \ + nv.9 nvlist_free_nvlist_array.9 \ nv.9 nvlist_free_string.9 \ + nv.9 nvlist_free_string_array.9 \ nv.9 nvlist_free_type.9 \ nv.9 nvlist_get_binary.9 \ nv.9 nvlist_get_bool.9 \ + nv.9 nvlist_get_bool_array.9 \ nv.9 nvlist_get_descriptor.9 \ + nv.9 nvlist_get_descriptor_array.9 \ nv.9 nvlist_get_number.9 \ + nv.9 nvlist_get_number_array.9 \ nv.9 nvlist_get_nvlist.9 \ + nv.9 nvlist_get_nvlist_array.9 \ nv.9 nvlist_get_parent.9 \ nv.9 nvlist_get_string.9 \ + nv.9 nvlist_get_string_array.9 \ nv.9 nvlist_move_binary.9 \ nv.9 nvlist_move_descriptor.9 \ + nv.9 nvlist_move_descriptor_array.9 \ nv.9 nvlist_move_nvlist.9 \ + nv.9 nvlist_move_nvlist_array.9 \ nv.9 nvlist_move_string.9 \ + nv.9 nvlist_move_string_array.9 \ nv.9 nvlist_next.9 \ nv.9 nvlist_pack.9 \ nv.9 nvlist_recv.9 \ @@ -1368,10 +1381,15 @@ MLINKS+=nv.9 libnv.9 \ nv.9 nvlist_size.9 \ nv.9 nvlist_take_binary.9 \ nv.9 nvlist_take_bool.9 \ + nv.9 nvlist_take_bool_array.9 \ nv.9 nvlist_take_descriptor.9 \ + nv.9 nvlist_take_descriptor_array.9 \ nv.9 nvlist_take_number.9 \ + nv.9 nvlist_take_number_array.9 \ nv.9 nvlist_take_nvlist.9 \ + nv.9 nvlist_take_nvlist_array.9 \ nv.9 nvlist_take_string.9 \ + nv.9 nvlist_take_string_array.9 \ nv.9 nvlist_unpack.9 \ nv.9 nvlist_xfer.9 MLINKS+=osd.9 osd_call.9 \ @@ -1902,7 +1920,6 @@ MLINKS+=ucred.9 cred_update_thread.9 \ ucred.9 crget.9 \ ucred.9 crhold.9 \ ucred.9 crsetgroups.9 \ - ucred.9 crshared.9 \ ucred.9 cru2x.9 MLINKS+=uidinfo.9 uifind.9 \ uidinfo.9 uifree.9 \ diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9 index 6dc4350153e6..e57ce5e7bb16 100644 --- a/share/man/man9/atomic.9 +++ b/share/man/man9/atomic.9 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 22, 2017 +.Dd March 23, 2017 .Dt ATOMIC 9 .Os .Sh NAME @@ -76,10 +76,41 @@ .Ft int .Fn atomic_testandset_ "volatile *p" "u_int v" .Sh DESCRIPTION -Each of the atomic operations is guaranteed to be atomic across multiple -threads and in the presence of interrupts. -They can be used to implement reference counts or as building blocks for more -advanced synchronization primitives such as mutexes. +All of these operations are performed atomically across multiple +threads and in the presence of interrupts, meaning that they are +performed in an indivisible manner from the perspective of concurrently +running threads and interrupt handlers. +.Pp +When atomic operations are performed on cache-coherent memory, all +operations on the same location are totally ordered. +.Pp +When an atomic load is performed on a location in cache-coherent memory, +it reads the entire value that was defined by the last atomic store to +each byte of the location. +An atomic load will never return a value out of thin air. +When an atomic store is performed on a location, no other thread or +interrupt handler will observe a +.Em torn write , +or partial modification of the location. +.Pp +On all architectures supported by +.Fx , +ordinary loads and stores of naturally aligned integer types +are atomic, as executed by the processor. +.Pp +Atomic operations can be used to implement reference counts or as +building blocks for synchronization primitives such as mutexes. +.Pp +The semantics of +.Fx Ns 's +atomic operations are almost identical to those of the similarly named +C11 operations. +The one important difference is that the C11 standard does not +require ordinary loads and stores to ever be atomic. +This is is why the +.Fn atomic_load_explicit memory_order_relaxed +operation exists in the C11 standard, but is not provided by +.In machine/atomic.h . .Ss Types Each atomic operation operates on a specific .Fa type . diff --git a/share/man/man9/cnv.9 b/share/man/man9/cnv.9 index 453cbee0456a..fef921488bd7 100644 --- a/share/man/man9/cnv.9 +++ b/share/man/man9/cnv.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 27, 2016 +.Dd October 26, 2017 .Dt CNV 9 .Os .Sh NAME @@ -37,6 +37,11 @@ .Lb libnv .Sh SYNOPSIS .In sys/cnv.h +.Ft const char * +.Fn cnvlist_name "void *cookiep" +.Ft int +.Fn cnvlist_type "void *cookiep" +.\" .Ft bool .Fn cnvlist_get_bool "void *cookiep" .Ft uint64_t @@ -124,6 +129,16 @@ from .Xr nv 9 . .Pp The +.Fn cnvlist_name +function returns the name of an element associated with the given cookie. +.Pp +The +.Fn cnvlist_type +function returns the type of an element associated with the given cookie. +Types which can be returned are described in +.Xr nv 9 . +.Pp +The .Nm cnvlist_get family of functions obtains the value associated with the given cookie. Returned strings, nvlists, descriptors, binaries, or arrays must not be modified diff --git a/share/man/man9/crypto.9 b/share/man/man9/crypto.9 index 428c9b35b605..cf1195de07a0 100644 --- a/share/man/man9/crypto.9 +++ b/share/man/man9/crypto.9 @@ -331,6 +331,17 @@ Do callback immediately if operation is synchronous (that the driver specified the .Dv CRYPTOCAP_F_SYNC flag). +.It Dv CRYPTO_F_ASYNC +Try to do the crypto operation in a pool of workers +if the operation is synchronous (that the driver specified the +.Dv CRYPTOCAP_F_SYNC +flag). It aims to speed up processing by dispatching crypto operations +on different processors. +.It Dv CRYPTO_F_ASYNC_KEEPORDER +Dispatch callbacks in the same order they are posted. +Only relevant if the +.Dv CRYPTO_F_ASYNC +flag is set and if the operation is synchronous. .El .It Va crp_buf Points to the input buffer. diff --git a/share/man/man9/mac.9 b/share/man/man9/mac.9 index d1e86ad79234..58c2f7a2484e 100644 --- a/share/man/man9/mac.9 +++ b/share/man/man9/mac.9 @@ -165,7 +165,7 @@ for information on the MAC Framework APIs. .Xr VFS 9 .Rs .%T "The FreeBSD Architecture Handbook" -.%U "http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/arch-handbook/" +.%U "https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/arch-handbook/" .Re .Sh HISTORY The diff --git a/share/man/man9/mbpool.9 b/share/man/man9/mbpool.9 deleted file mode 100644 index e9cd7a244e49..000000000000 --- a/share/man/man9/mbpool.9 +++ /dev/null @@ -1,264 +0,0 @@ -.\" Copyright (c) 2003 -.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus). -.\" All rights reserved. -.\" -.\" 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 AUTHOR 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 AUTHOR 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. -.\" -.\" Author: Hartmut Brandt -.\" -.\" $FreeBSD$ -.\" -.Dd July 15, 2003 -.Dt MBPOOL 9 -.Os -.Sh NAME -.Nm mbpool -.Nd "buffer pools for network interfaces" -.Sh SYNOPSIS -.In sys/types.h -.In machine/bus.h -.In sys/mbpool.h -.Vt struct mbpool ; -.Ft int -.Fo mbp_create -.Fa "struct mbpool **mbp" "const char *name" "bus_dma_tag_t dmat" -.Fa "u_int max_pages" "size_t page_size" "size_t chunk_size" -.Fc -.Ft void -.Fn mbp_destroy "struct mbpool *mbp" -.Ft "void *" -.Fn mbp_alloc "struct mbpool *mbp" "bus_addr_t *pa" "uint32_t *hp" -.Ft void -.Fn mbp_free "struct mbpool *mbp" "void *p" -.Ft void -.Fn mbp_ext_free "void *" "void *" -.Ft void -.Fn mbp_card_free "struct mbpool *mbp" -.Ft void -.Fn mbp_count "struct mbpool *mbp" "u_int *used" "u_int *card" "u_int *free" -.Ft "void *" -.Fn mbp_get "struct mbpool *mbp" "uint32_t h" -.Ft "void *" -.Fn mbp_get_keep "struct mbpool *mbp" "uint32_t h" -.Ft void -.Fo mbp_sync -.Fa "struct mbpool *mbp" "uint32_t h" "bus_addr_t off" "bus_size_t len" -.Fa "u_int op" -.Fc -.Pp -.Fn MODULE_DEPEND "your_module" "libmbpool" 1 1 1 -.Pp -.Cd "options LIBMBPOOL" -.Sh DESCRIPTION -Mbuf pools are intended to help drivers for interface cards that need huge -amounts of receive buffers, and additionally provides a mapping between these -buffers and 32-bit handles. -.Pp -An example of these cards are the Fore/Marconi ForeRunnerHE cards. -These -employ up to 8 receive groups, each with two buffer pools, each of which -can contain up to 8192. -This gives a total maximum number of more than -100000 buffers. -Even with a more moderate configuration the card eats several -thousand buffers. -Each of these buffers must be mapped for DMA. -While for -machines without an IOMMU and with lesser than 4GByte memory this is not -a problem, for other machines this may quickly eat up all available IOMMU -address space and/or bounce buffers. -On sparc64, the default I/O page size -is 16k, so mapping a simple mbuf wastes 31/32 of the address space. -.Pp -Another problem with most of these cards is that they support putting a 32-bit -handle into the buffer descriptor together with the physical address. -This handle is reflected back to the driver when the buffer is filled, and -assists the driver in finding the buffer in host memory. -For 32-bit machines, -the virtual address of the buffer is usually used as the handle. -This does not -work for 64-bit machines for obvious reasons, so a mapping is needed between -these handles and the buffers. -This mapping should be possible without -searching lists and the like. -.Pp -An mbuf pool overcomes both problems by allocating DMA-able memory page wise -with a per-pool configurable page size. -Each page is divided into a number of -equally-sized chunks, the last -.Dv MBPOOL_TRAILER_SIZE -of which are used by the pool code (4 bytes). -The rest of each chunk is -usable as a buffer. -There is a per-pool limit on pages that will be allocated. -.Pp -Additionally, the code manages two flags for each buffer: -.Dq on-card -and -.Dq used . -A buffer may be in one of three states: -.Bl -tag -width "on-card" -.It free -None of the flags is set. -.It on-card -Both flags are set. -The buffer is assumed to be handed over to the card and -waiting to be filled. -.It used -The buffer was returned by the card and is now travelling through the system. -.El -.Pp -A pool is created with -.Fn mbp_create . -This call specifies a DMA tag -.Fa dmat -to be used to create and map the memory pages via -.Xr bus_dmamem_alloc 9 . -The -.Fa chunk_size -includes the pool overhead. -It means that to get buffers for 5 ATM cells -(240 bytes), a chunk size of 256 should be specified. -This results in 12 unused -bytes between the buffer, and the pool overhead of four byte. -The total -maximum number of buffers in a pool is -.Fa max_pages -* -.Fa ( page_size -/ -.Fa chunk_size ) . -The maximum value for -.Fa max_pages -is 2^14-1 (16383) and the maximum of -.Fa page_size -/ -.Fa chunk_size -is 2^9 (512). -If the call is successful, a pointer to a newly allocated -.Vt "struct mbpool" -is set into the variable pointed to by -.Fa mpb . -.Pp -A pool is destroyed with -.Fn mbp_destroy . -This frees all pages and the pool structure itself. -If compiled with -.Dv DIAGNOSTICS , -the code checks that all buffers are free. -If not, a warning message is issued -to the console. -.Pp -A buffer is allocated with -.Fn mbp_alloc . -This returns the virtual address of the buffer and stores the physical -address into the variable pointed to by -.Fa pa . -The handle is stored into the variable pointed to by -.Fa hp . -The two most significant bits and the 7 least significant bits of the handle -are unused by the pool code and may be used by the caller. -These are -automatically stripped when passing a handle to one of the other functions. -If a buffer cannot be allocated (either because the maximum number of pages -is reached, no memory is available or the memory cannot be mapped), -.Dv NULL -is returned. -If a buffer could be allocated, it is in the -.Dq on-card -state. -.Pp -When the buffer is returned by the card, the driver calls -.Fn mbp_get -with the handle. -This function returns the virtual address of the buffer -and clears the -.Dq on-card -bit. -The buffer is now in the -.Dq used -state. -The function -.Fn mbp_get_keep -differs from -.Fn mbp_get -in that it does not clear the -.Dq on-card -bit. -This can be used for buffers -that are returned -.Dq partially -by the card. -.Pp -A buffer is freed by calling -.Fn mbp_free -with the virtual address of the buffer. -This clears the -.Dq used -bit, and -puts the buffer on the free list of the pool. -Note that free buffers -are NOT returned to the system. -The function -.Fn mbp_ext_free -can be given to -.Fn m_extadd -as the free function. -The user argument must be the pointer to -the pool. -.Pp -Before using the contents of a buffer returned by the card, the driver -must call -.Fn mbp_sync -with the appropriate parameters. -This results in a call to -.Xr bus_dmamap_sync 9 -for the buffer. -.Pp -All buffers in the pool that are currently in the -.Dq on-card -state can be freed -with a call to -.Fn mbp_card_free . -This may be called by the driver when it stops the interface. -Buffers in the -.Dq used -state are not freed by this call. -.Pp -For debugging it is possible to call -.Fn mbp_count . -This returns the number of buffers in the -.Dq used -and -.Dq on-card -states and -the number of buffers on the free list. -.Sh SEE ALSO -.Xr mbuf 9 -.Sh AUTHORS -.An Harti Brandt Aq Mt harti@FreeBSD.org -.Sh CAVEATS -The function -.Fn mbp_sync -is currently a no-op because -.Xr bus_dmamap_sync 9 -is missing the offset and length parameters. diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9 index a4fa70606a97..0286d244d553 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 10, 2016 +.Dd September 27, 2017 .Dt MBUF 9 .Os .\" @@ -44,12 +44,12 @@ .Fn MCLGET "struct mbuf *mbuf" "int how" .Fo MEXTADD .Fa "struct mbuf *mbuf" -.Fa "caddr_t buf" +.Fa "char *buf" .Fa "u_int size" -.Fa "void (*free)(void *opt_arg1, void *opt_arg2)" +.Fa "void (*free)(struct mbuf *)" .Fa "void *opt_arg1" .Fa "void *opt_arg2" -.Fa "short flags" +.Fa "int flags" .Fa "int type" .Fc .\" @@ -416,8 +416,13 @@ The .Fa opt_arg1 and .Fa opt_arg2 -arguments will be passed unmodified to -.Fa free . +arguments will be saved in +.Va ext_arg1 +and +.Va ext_arg2 +fields of the +.Va struct m_ext +of the mbuf. The .Fa flags argument specifies additional diff --git a/share/man/man9/nv.9 b/share/man/man9/nv.9 index fbf2dd991afb..12175a996560 100644 --- a/share/man/man9/nv.9 +++ b/share/man/man9/nv.9 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 15, 2015 +.Dd September 16, 2017 .Dt NV 9 .Os .Sh NAME @@ -201,11 +201,11 @@ .Ft "const bool *" .Fn nvlist_get_bool_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "const uint64_t *" -.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_get_number_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "const char * const *" -.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_get_string_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "const nvlist_t * const *" -.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_get_nvlist_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "const int *" .Fn nvlist_get_descriptor_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "const nvlist_t *" @@ -230,13 +230,13 @@ .Ft "bool *" .Fn nvlist_take_bool_array "nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "uint64_t **" -.Fn nvlist_take_number "nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_take_number_array "nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "char **" -.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_take_string_array "nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "nvlist_t **" -.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_take_nvlist_array "nvlist_t *nvl" "const char *name" "size_t *nitems" .Ft "int *" -.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name" "size_t *nitems" +.Fn nvlist_take_descriptor_array "nvlist_t *nvl" "const char *name" "size_t *nitems" .\" .Ft void .Fn nvlist_free "nvlist_t *nvl" "const char *name" diff --git a/share/man/man9/own.9 b/share/man/man9/own.9 index 8609eb7d2098..c4588c16400a 100644 --- a/share/man/man9/own.9 +++ b/share/man/man9/own.9 @@ -214,7 +214,7 @@ driver. .Xr ow 4 , .Xr owc 4 , .Xr owll 9 -.Pa http://pdfserv.maximintegrated.com/en/an/AN937.pdf +.Pa https://pdfserv.maximintegrated.com/en/an/AN937.pdf .Sh LEGAL .Tn 1-Wire is a registered trademark of Maxim Integrated Products, Inc. diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9 index a65f9e1755c4..9071debe26e2 100644 --- a/share/man/man9/pci.9 +++ b/share/man/man9/pci.9 @@ -1047,7 +1047,7 @@ is unattached but with valid instance variables. .Rs .%B FreeBSD Developers' Handbook .%T NewBus -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/ +.%U https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/ .Re .Rs .%A Shanley diff --git a/share/man/man9/stack.9 b/share/man/man9/stack.9 index 06065bde31ae..6da1d0408704 100644 --- a/share/man/man9/stack.9 +++ b/share/man/man9/stack.9 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 10, 2015 +.Dd October 6, 2017 .Dt STACK 9 .Os .Sh NAME @@ -42,7 +42,7 @@ In the kernel configuration file: .Cd "options STACK" .Pp .Ft struct stack * -.Fn stack_create "void" +.Fn stack_create "int flags" .Ft void .Fn stack_destroy "struct stack *st" .Ft int @@ -85,8 +85,11 @@ Each stack trace is described by a .Vt "struct stack" . Before a trace may be created or otherwise manipulated, storage for the trace must be allocated with -.Fn stack_create , -which may sleep. +.Fn stack_create . +The +.Ar flags +argument is passed to +.Xr malloc 9 . Memory associated with a trace is freed by calling .Fn stack_destroy . .Pp diff --git a/share/man/man9/sysctl.9 b/share/man/man9/sysctl.9 index dbb61f59f2c0..558c65a248fe 100644 --- a/share/man/man9/sysctl.9 +++ b/share/man/man9/sysctl.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 13, 2016 +.Dd October 10, 2017 .Dt SYSCTL 9 .Os .Sh NAME @@ -668,6 +668,10 @@ Additionally, any of the following optional flags may also be specified: .Bl -tag -width ".Dv CTLFLAG_ANYBODY" .It Dv CTLFLAG_ANYBODY Any user or process can write to this sysctl. +.It Dv CTLFLAG_CAPRD +A process in capability mode can read from this sysctl. +.It Dv CTLFLAG_CAPWR +A process in capability mode can write to this sysctl. .It Dv CTLFLAG_SECURE This sysctl can be written to only if the effective securelevel of the process is \[<=] 0. diff --git a/share/man/man9/ucred.9 b/share/man/man9/ucred.9 index e8b26d653fbd..afe4812d196c 100644 --- a/share/man/man9/ucred.9 +++ b/share/man/man9/ucred.9 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 19, 2009 +.Dd September 27, 2017 .Dt UCRED 9 .Os .Sh NAME @@ -34,7 +34,6 @@ .Nm crget , .Nm crhold , .Nm crfree , -.Nm crshared , .Nm crcopy , .Nm crdup , .Nm cru2x , @@ -49,8 +48,6 @@ .Fn crhold "struct ucred *cr" .Ft void .Fn crfree "struct ucred *cr" -.Ft int -.Fn crshared "struct ucred *cr" .Ft void .Fn crcopy "struct ucred *dest" "struct ucred *src" .Ft "struct ucred *" @@ -86,12 +83,6 @@ function decreases the reference count on the credential. If the count drops to 0, the storage for the structure is freed. .Pp The -.Fn crshared -function returns true if the credential is shared. -A credential is considered to be shared if its reference -count is greater than one. -.Pp -The .Fn crcopy function copies the contents of the source (template) credential into the destination template. @@ -170,10 +161,6 @@ and all return a pointer to a .Vt ucred structure. -.Pp -.Fn crshared -returns 0 if the credential has a reference count greater than 1; -otherwise, 1 is returned. .Sh USAGE NOTES As of .Fx 5.0 , diff --git a/share/man/man9/unr.9 b/share/man/man9/unr.9 index d8b9d9585352..fe1299d40e5d 100644 --- a/share/man/man9/unr.9 +++ b/share/man/man9/unr.9 @@ -24,11 +24,12 @@ .\" .\" $FreeBSD$ .\" -.Dd July 5, 2010 +.Dd October 4, 2017 .Dt UNR 9 .Os .Sh NAME .Nm new_unrhdr , +.Nm clear_unrhdr , .Nm delete_unrhdr , .Nm alloc_unr , .Nm alloc_unr_specific , @@ -39,6 +40,8 @@ .Ft "struct unrhdr *" .Fn new_unrhdr "int low" "int high" "struct mtx *mutex" .Ft void +.Fn clear_unrhdr "struct unrhdr *uh" +.Ft void .Fn delete_unrhdr "struct unrhdr *uh" .Ft int .Fn alloc_unr "struct unrhdr *uh" @@ -70,8 +73,16 @@ is not .Dv NULL , it is used for locking when allocating and freeing units. Otherwise, internal mutex is used. +.It Fn clear_unrhdr uh +Clear all units from the specified unit number allocator entity. +This function resets the entity as if it were just initialized with +.Fn new_unrhdr . .It Fn delete_unrhdr uh -Destroy specified unit number allocator entity. +Delete specified unit number allocator entity. +This function frees the memory associated with the entity, it does not free +any units. +To free all units use +.Fn clear_unrhdr . .It Fn alloc_unr uh Return a new unit number. The lowest free number is always allocated. diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index 42bd3d5d5ec9..14df1d7072b9 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -339,22 +339,24 @@ FreeBSD 5.2 | | | | | | | | | DragonFly 4.2.0 | FreeBSD | | | | | 10.2 | | | | - | | OS X NetBSD 7.0 | | + | | macOS NetBSD 7.0 | | | | 10.11 | OpenBSD 5.8 | | | | | | DragonFly 4.4.1 | FreeBSD | | OpenBSD 5.9 | | 10.3 | | | | - | | NetBSD 7.0.1 | | - | | | | DragonFly 4.6.0 - | | | | | - | | | | | - *--FreeBSD macOS | OpenBSD 6.0 | - | 11.0 10.12 | | | - | | | NetBSD 7.1 | | - | | | | | DragonFly 4.8.0 - | | | | OpenBSD 6.1 | - | FreeBSD | | | | - | 11.1 | | | | + | | | NetBSD 7.0.1 | | + | `------. | | | DragonFly 4.6.0 + | | | | | | + | | | | | | + *--FreeBSD | macOS | OpenBSD 6.0 | + | 11.0 | 10.12 | | | + | | | | NetBSD 7.1 | | + | | | macOS | | DragonFly 4.8.0 + | | | 10.13 | OpenBSD 6.1 | + | FreeBSD | | | | | + | 11.1 FreeBSD | | | | + | | 10.4 | | OpenBSD 6.2 | + | v | | | DragonFly 5.0.0 | | | | | FreeBSD 12 -current | NetBSD -current OpenBSD -current DragonFly -current | | | | | @@ -369,7 +371,7 @@ was the announcement in Usenet or if it was available as tape. [44B] McKusick, Marshall Kirk, Keith Bostic, Michael J Karels, and John Quarterman. The Design and Implementation of the 4.4BSD Operating System. -[APL] Apple website [http://www.apple.com/macosx/] +[APL] Apple website [https://www.apple.com/macosx/] [BSDI] Berkeley Software Design, Inc. [DFB] DragonFlyBSD Project, The. [DOC] README, COPYRIGHT on tape. @@ -715,6 +717,10 @@ NetBSD 7.1 2017-03-11 [NBD] DragonFly 4.8.0 2017-03-27 [DFB] OpenBSD 6.1 2017-04-11 [OBD] FreeBSD 11.1 2017-07-26 [FBD] +macOS 10.13 2017-09-25 [APL] +FreeBSD 10.4 2017-10-03 [FBD] +OpenBSD 6.2 2017-10-09 [OBD] +DragonFly 5.0.0 2017-10-16 [DFB] Bibliography ------------------------ @@ -751,10 +757,10 @@ Andreas Klemm, Lars Köller. If you're going to San Francisco ... Die freien BSD-Varianten von Unix. c't April 1997, page 368ff. BSD Release Announcements collection. -URL: http://www.FreeBSD.org/releases/ +URL: https://www.FreeBSD.org/releases/ BSD Hypertext Man Pages -URL: http://www.FreeBSD.org/cgi/man.cgi +URL: https://www.FreeBSD.org/cgi/man.cgi UNIX history graphing project URL: http://minnie.tuhs.org/Unix_History/index.html diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index 072289a68397..b1892c2539dd 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -99,6 +99,7 @@ edwin [label="Edwin Groothuis\nedwin@FreeBSD.org\n2002/10/22"] ehaupt [label="Emanuel Haupt\nehaupt@FreeBSD.org\n2005/10/03"] eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"] erwin [label="Erwin Lansing\nerwin@FreeBSD.org\n2003/06/04"] +eugen [label="Eugene Grosbein\neugen@FreeBSD.org\n2017/03/04"] farrokhi [label="Babak Farrokhi\nfarrokhi@FreeBSD.org\n2006/11/07"] feld [label="Mark Felder\nfeld@FreeBSD.org\n2013/06/25"] fjoe [label="Max Khon\nfjoe@FreeBSD.org\n2001/08/06"] @@ -149,6 +150,7 @@ lawrance [label="Sam Lawrance\nlawrance@FreeBSD.org\n2005/04/11\n2007/02/21"] lbr [label="Lars Balker Rasmussen\nlbr@FreeBSD.org\n2006/04/30"] leeym [label="Yen-Ming Lee\nleeym@FreeBSD.org\n2002/08/14"] ler [label="Larry Rosenman\nler@FreeBSD.org\n2017/01/09"] +leres [label="Craig Leres\nleres@FreeBSD.org\n2017/10/10"] lev [label="Lev Serebryakov\nlev@FreeBSD.org\n2003/06/17"] lifanov [label="Nikolai Lifanov\nlifanov@FreeBSD.org\n2016/12/11"] linimon [label="Mark Linimon\nlinimon@FreeBSD.org\n2003/10/23"] @@ -252,6 +254,7 @@ woodsb02 [label="Ben Woods\nwoodsb02@FreeBSD.org\n2016/05/09"] wxs [label="Wesley Shields\nwxs@FreeBSD.org\n2008/01/03"] xmj [label="Johannes Jost Meixner\nxmj@FreeBSD.org\n2014/04/07"] xride [label="Soeren Straarup\nxride@FreeBSD.org\n2006/09/27"] +yuri [label="Yuri Victorovich\nyuri@FreeBSD.org\n2017/10/30"] yzlin [label="Yi-Jheng Lin\nyzlin@FreeBSD.org\n2009/07/19"] zeising [label="Niclas Zeising\nzeising@FreeBSD.org\n2012/07/03"] zi [label="Ryan Steinmetz\nzi@FreeBSD.org\n2011/07/14"] @@ -289,6 +292,8 @@ asami -> obrien avilla -> jhale avilla -> rakuco +az -> eugen + bdrewery -> dbn bdrewery -> sbruno bdrewery -> trociny @@ -468,6 +473,8 @@ lawrance -> itetcu leeym -> clsung +ler -> leres + lifanov -> ultima lioux -> pat @@ -502,6 +509,7 @@ mat -> thierry mat -> tobik mat -> woodsb02 +matthew -> leres matthew -> lifanov matthew -> ultima @@ -645,6 +653,7 @@ tabthorpe -> zi tabthorpe -> gblach tcberner -> adridg +tcberner -> yuri thierry -> jadawin thierry -> riggs @@ -652,6 +661,8 @@ thierry -> riggs tmclaugh -> itetcu tmclaugh -> xride +vsevolod -> eugen + wen -> cs wen -> culot wen -> pawel diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index c99731b6cf80..d84d1aa89796 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -113,6 +113,7 @@ andreast [label="Andreas Tobler\nandreast@FreeBSD.org\n2010/09/05"] andrew [label="Andrew Turner\nandrew@FreeBSD.org\n2010/07/19"] antoine [label="Antoine Brodin\nantoine@FreeBSD.org\n2008/02/03"] araujo [label="Marcelo Araujo\naraujo@FreeBSD.org\n2015/08/04"] +arichardson [label="Alex Richardson\narichardson@FreeBSD.org\n2017/10/30"] ariff [label="Ariff Abdullah\nariff@FreeBSD.org\n2005/11/14"] art [label="Artem Belevich\nart@FreeBSD.org\n2011/03/29"] arybchik [label="Andrew Rybchenko\narybchik@FreeBSD.org\n2014/10/12"] @@ -162,10 +163,12 @@ emaste [label="Ed Maste\nemaste@FreeBSD.org\n2005/10/04"] emax [label="Maksim Yevmenkin\nemax@FreeBSD.org\n2003/10/12"] eri [label="Ermal Luci\neri@FreeBSD.org\n2008/06/11"] erj [label="Eric Joyner\nerj@FreeBSD.org\n2014/12/14"] +eugen [label="Eugene Grosbein\neugen@FreeBSD.org\n2017/09/19"] fabient [label="Fabien Thomas\nfabient@FreeBSD.org\n2009/03/16"] fanf [label="Tony Finch\nfanf@FreeBSD.org\n2002/05/05"] fjoe [label="Max Khon\nfjoe@FreeBSD.org\n2001/08/06"] flz [label="Florent Thoumie\nflz@FreeBSD.org\n2006/03/30"] +fsu [label="Fedor Uporov\nfsu@FreeBSD.org\n2017/08/28"] gabor [label="Gabor Kovesdan\ngabor@FreeBSD.org\n2010/02/02"] gad [label="Garance A. Drosehn\ngad@FreeBSD.org\n2000/10/27"] gallatin [label="Andrew Gallatin\ngallatin@FreeBSD.org\n1999/01/15"] @@ -386,6 +389,7 @@ andrew -> manu anholt -> jkim avg -> art +avg -> eugen avg -> pluknet avg -> smh @@ -413,6 +417,7 @@ brian -> joe brooks -> bushman brooks -> jamie brooks -> theraven +brooks -> arichardson bz -> anchie bz -> jamie @@ -566,6 +571,7 @@ jhb -> peterj jhb -> pfg jhb -> rnoland jhb -> rpokala +jhb -> arichardson jimharris -> carl @@ -650,6 +656,7 @@ markm -> jasone markm -> sheldonh mav -> ae +mav -> eugen mdf -> gleb @@ -687,6 +694,8 @@ obrien -> gshapiro obrien -> kan obrien -> sam +pfg -> fsu + peter -> asmodai peter -> jayanth peter -> ps diff --git a/share/misc/iso3166 b/share/misc/iso3166 index 8b7533b79ab8..ba9b69a9896e 100644 --- a/share/misc/iso3166 +++ b/share/misc/iso3166 @@ -1,6 +1,6 @@ # $FreeBSD$ # -# Please consult with http://www.FreeBSD.org/internal/i18n.html before +# Please consult with https://www.FreeBSD.org/internal/i18n.html before # making changes to this file. # # ISO 3166 country codes @@ -21,7 +21,7 @@ # two three number name AF AFG 004 Afghanistan AL ALB 008 Albania -AX ALA 248 Aland Islands +AX ALA 248 Ã…land Islands DZ DZA 012 Algeria AS ASM 016 American Samoa AD AND 020 Andorra @@ -59,7 +59,7 @@ BI BDI 108 Burundi KH KHM 116 Cambodia CM CMR 120 Cameroon CA CAN 124 Canada -CV CPV 132 Cape Verde +CV CPV 132 Cabo Verde KY CYM 136 Cayman Islands CF CAF 140 Central African Republic TD TCD 148 Chad @@ -70,20 +70,19 @@ CC CCK 166 Cocos (Keeling) Islands CO COL 170 Colombia KM COM 174 Comoros CG COG 178 Congo -CD COD 180 Congo, the Democratic Republic of the +CD COD 180 Congo, Democratic Republic of the CK COK 184 Cook Islands CR CRI 188 Costa Rica -CI CIV 384 Cote d'Ivoire +CI CIV 384 Côte d'Ivoire HR HRV 191 Croatia CU CUB 192 Cuba -CW CUW 531 Curacao +CW CUW 531 Curaçao CY CYP 196 Cyprus CZ CZE 203 Czech Republic DK DNK 208 Denmark DJ DJI 262 Djibouti DM DMA 212 Dominica DO DOM 214 Dominican Republic -TL TLS 626 Timor-Leste EC ECU 218 Ecuador EG EGY 818 Egypt SV SLV 222 El Salvador @@ -117,13 +116,14 @@ GW GNB 624 Guinea-Bissau GY GUY 328 Guyana HT HTI 332 Haiti HM HMD 334 Heard Island and McDonald Islands +VA VAT 336 Holy See HN HND 340 Honduras HK HKG 344 Hong Kong HU HUN 348 Hungary IS ISL 352 Iceland IN IND 356 India ID IDN 360 Indonesia -IR IRN 364 Iran, Islamic Republic of +IR IRN 364 Iran (Islamic Republic of) IQ IRQ 368 Iraq IE IRL 372 Ireland IM IMN 833 Isle of Man @@ -136,8 +136,8 @@ JO JOR 400 Jordan KZ KAZ 398 Kazakhstan KE KEN 404 Kenya KI KIR 296 Kiribati -KP PRK 408 Korea, Democratic People's Republic of -KR KOR 410 Korea, Republic of +KP PRK 408 Korea (Democratic People's Republic of) +KR KOR 410 Korea (Republic of) KW KWT 414 Kuwait KG KGZ 417 Kyrgyzstan LA LAO 418 Lao People's Democratic Republic @@ -145,12 +145,12 @@ LV LVA 428 Latvia LB LBN 422 Lebanon LS LSO 426 Lesotho LR LBR 430 Liberia -LY LBY 434 Libyan Arab Jamahiriya +LY LBY 434 Libya LI LIE 438 Liechtenstein LT LTU 440 Lithuania LU LUX 442 Luxembourg MO MAC 446 Macao -MK MKD 807 Macedonia, the Former Yugoslav Republic of +MK MKD 807 Macedonia (the former Yugoslav Republic of) MG MDG 450 Madagascar MW MWI 454 Malawi MY MYS 458 Malaysia @@ -163,8 +163,8 @@ MR MRT 478 Mauritania MU MUS 480 Mauritius YT MYT 175 Mayotte MX MEX 484 Mexico -FM FSM 583 Micronesia, Federated States of -MD MDA 498 Moldova, Republic of +FM FSM 583 Micronesia (Federated States of) +MD MDA 498 Moldova (Republic of) MC MCO 492 Monaco MN MNG 496 Mongolia ME MNE 499 Montenegro @@ -188,7 +188,7 @@ NO NOR 578 Norway OM OMN 512 Oman PK PAK 586 Pakistan PW PLW 585 Palau -PS PSE 275 Palestinian Territory, Occupied +PS PSE 275 Palestine, State of PA PAN 591 Panama PG PNG 598 Papua New Guinea PY PRY 600 Paraguay @@ -199,14 +199,16 @@ PL POL 616 Poland PT PRT 620 Portugal PR PRI 630 Puerto Rico QA QAT 634 Qatar -RE REU 638 Reunion +RE REU 638 Réunion RO ROU 642 Romania RU RUS 643 Russian Federation RW RWA 646 Rwanda -BL BLM 652 Saint Barthelemy +BL BLM 652 Saint Barthélemy +SH SHN 654 Saint Helena Ascension and Tristan da Cunha KN KNA 659 Saint Kitts and Nevis LC LCA 662 Saint Lucia -MF MAF 663 Saint Martin (French Part) +MF MAF 663 Saint Martin (French part) +PM SPM 666 Saint Pierre and Miquelon VC VCT 670 Saint Vincent and the Grenadines WS WSM 882 Samoa SM SMR 674 San Marino @@ -227,8 +229,6 @@ GS SGS 239 South Georgia and the South Sandwich Islands SS SSD 728 South Sudan ES ESP 724 Spain LK LKA 144 Sri Lanka -SH SHN 654 Saint Helena, Ascension and Tristan da Cunha -PM SPM 666 Saint Pierre and Miquelon SD SDN 729 Sudan SR SUR 740 Suriname SJ SJM 744 Svalbard and Jan Mayen @@ -238,8 +238,9 @@ CH CHE 756 Switzerland SY SYR 760 Syrian Arab Republic TW TWN 158 Taiwan TJ TJK 762 Tajikistan -TZ TZA 834 Tanzania, United Republic of +TZ TZA 834 Tanzania United Republic of TH THA 764 Thailand +TL TLS 626 Timor-Leste TG TGO 768 Togo TK TKL 772 Tokelau TO TON 776 Tonga @@ -252,17 +253,16 @@ TV TUV 798 Tuvalu UG UGA 800 Uganda UA UKR 804 Ukraine AE ARE 784 United Arab Emirates -GB GBR 826 United Kingdom -US USA 840 United States +GB GBR 826 United Kingdom of Great Britain and Northern Ireland +US USA 840 United States of America UM UMI 581 United States Minor Outlying Islands UY URY 858 Uruguay UZ UZB 860 Uzbekistan VU VUT 548 Vanuatu -VA VAT 336 Holy See (Vatican City State) VE VEN 862 Venezuela, Bolivarian Republic of VN VNM 704 Viet Nam -VG VGB 092 Virgin Islands, British -VI VIR 850 Virgin Islands, U.S. +VG VGB 092 Virgin Islands (British) +VI VIR 850 Virgin Islands (U.S.) WF WLF 876 Wallis and Futuna EH ESH 732 Western Sahara YE YEM 887 Yemen diff --git a/share/misc/organization.dot b/share/misc/organization.dot index 29ac23665289..5c295f9c3243 100644 --- a/share/misc/organization.dot +++ b/share/misc/organization.dot @@ -5,7 +5,7 @@ # each other. # For a detailed description of the responsibilities and duties of the listed # teams, please see our Administration page at -# http://www.freebsd.org/administration.html . +# https://www.freebsd.org/administration.html . # # The graphical output can be generated from this file with the following # command: @@ -45,10 +45,8 @@ accounts [label="Accounts Team\naccounts@FreeBSD.org\nmarkm, simon, kensmith,\nd backups [label="Backup Administrators\nbackups@FreeBSD.org\nsimon, kensmith,\ndhw"] bugmeister [label="Bugmeister Team\nbugmeister@FreeBSD.org\neadler, gavin, gonzo"] clusteradm [label="Cluster Administrators\nclusteradm@FreeBSD.org\nallanjude, brd,\ndhw, gavin,\ngjb, peter,\nsbruno, simon,\nzi"] -cvsupmaster [label="CVSup Mirror Site Coordinators\ncvsup-master@FreeBSD.org\nkuriyama, jdp,\nkensmith"] dnsadm [label="DNS Administrators\ndnsadm@FreeBSD.org\nbillf, dg, ps,\nkensmith, peter"] mirroradmin [label="FTP/WWW Mirror Site Coordinators\nmirror-admin@FreeBSD.org\nkuriyama, kensmith"] -ncvs [label="CVS src Repository Managers\nncvs@FreeBSD.org\njoe, kuriyama, markm,\nsimon, peter"] perforceadmin [label="Perforce Repository Administrators\nperforce-admin@FreeBSD.org\nscottl, kensmith, gordon,\nrwatson, peter, dhw"] postmaster [label="Postmaster Team\npostmaster@FreeBSD.org\ndhw, ler, pi, rea, remko, zi"] refadm [label="Reference Systems Administrators\nrefadm@FreeBSD.org\njake, billf, markm, simon,\nobrien, ps, kensmith,\npeter, dhw"] @@ -68,8 +66,6 @@ _admin -> accounts _admin -> backups _admin -> bugmeister _admin -> clusteradm -_admin -> ncvs -_admin -> cvsupmaster _admin -> dnsadm _admin -> mirroradmin _admin -> perforceadmin diff --git a/share/mk/auto.obj.mk b/share/mk/auto.obj.mk index b633937674be..7f903ee7efb8 100644 --- a/share/mk/auto.obj.mk +++ b/share/mk/auto.obj.mk @@ -61,11 +61,17 @@ __objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \ .endif # This causes make to use the specified directory as .OBJDIR .OBJDIR: ${__objdir} -.if ${.OBJDIR:tA} != ${__objdir:tA} && ${__objdir_made:Uno:M${__objdir}/*} != "" +.if ${.OBJDIR:tA} != ${__objdir:tA} +# we did not get what we want - do we care? +.if ${__objdir_made:Uno:M${__objdir}/*} != "" # watch out for __objdir being relative path .if !(${__objdir:M/*} == "" && ${.OBJDIR:tA} == ${${.CURDIR}/${__objdir}:L:tA}) .error could not use ${__objdir}: .OBJDIR=${.OBJDIR} .endif .endif +# apparently we can live with it +# make sure we know what we have +.OBJDIR: ${.CURDIR} +.endif .endif .endif diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk index 9b296c8dfaa3..f05dbc3ae011 100644 --- a/share/mk/bsd.cpu.mk +++ b/share/mk/bsd.cpu.mk @@ -110,8 +110,6 @@ _CPUCFLAGS = -march=${CPUTYPE} _CPUCFLAGS = -march=armv5te -D__XSCALE__ . elif ${CPUTYPE:M*soft*} != "" _CPUCFLAGS = -mfloat-abi=softfp -. elif ${CPUTYPE} == "armv6" -_CPUCFLAGS = -march=${CPUTYPE} . elif ${CPUTYPE} == "cortexa" _CPUCFLAGS = -march=armv7 -mfpu=vfp . elif ${CPUTYPE:Marmv[4567]*} != "" @@ -339,18 +337,20 @@ MACHINE_CPU += arm . if ${MACHINE_ARCH:Marmv6*} != "" MACHINE_CPU += armv6 . endif -# armv6 is a hybrid. It can use the softfp ABI, but doesn't emulate -# floating point in the general case, so don't define softfp for -# it at this time. arm and armeb are pure softfp, so define it -# for them. -. if ${MACHINE_ARCH:Marmv6*} == "" +. if ${MACHINE_ARCH:Marmv7*} != "" +MACHINE_CPU += armv7 +. endif +# armv6 and armv7 are a hybrid. It can use the softfp ABI, but doesn't emulate +# floating point in the general case, so don't define softfp for it at this +# time. arm and armeb are pure softfp, so define it for them. +. if ${MACHINE_ARCH:Marmv[67]*} == "" MACHINE_CPU += softfp . endif -# Normally armv6 is hard float ABI from FreeBSD 11 onwards. However -# when CPUTYPE has 'soft' in it, we use the soft-float ABI to allow -# building of soft-float ABI libraries. In this case, we have to -# add the -mfloat-abi=softfp to force that. -.if ${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "" +# Normally armv6 and armv7 are hard float ABI from FreeBSD 11 onwards. However +# when CPUTYPE has 'soft' in it, we use the soft-float ABI to allow building of +# soft-float ABI libraries. In this case, we have to add the -mfloat-abi=softfp +# to force that. +.if ${MACHINE_ARCH:Marmv[67]*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "" # Needs to be CFLAGS not _CPUCFLAGS because it's needed for the ABI # not a nice optimization. CFLAGS += -mfloat-abi=softfp diff --git a/share/mk/bsd.crunchgen.mk b/share/mk/bsd.crunchgen.mk index 55fa8b583ec5..d85d75838568 100644 --- a/share/mk/bsd.crunchgen.mk +++ b/share/mk/bsd.crunchgen.mk @@ -41,7 +41,7 @@ CRUNCHOBJS= ${.OBJDIR} CRUNCH_GENERATE_LINKS?= yes # Don't let the prog.mk use MK_AUTO_OBJ, but do let the component builds use # it. -CRUNCHENV+= MK_AUTO_OBJ=no +CRUNCHARGS+= MK_AUTO_OBJ=no CRUNCH_BUILDOPTS+= MK_AUTO_OBJ=${MK_AUTO_OBJ} CLEANFILES+= ${CONF} *.o *.lo *.c *.mk *.cache *.a *.h @@ -114,7 +114,7 @@ CRUNCHENV+= MK_TESTS=no \ ${OUTPUTS:[1]}: .META ${OUTPUTS:[2..-1]}: .NOMETA ${OUTPUTS}: ${CONF} - MAKE="${MAKE}" ${CRUNCHENV:NMK_AUTO_OBJ=*} MAKEOBJDIRPREFIX=${CRUNCHOBJS} \ + MAKE="${MAKE}" ${CRUNCHENV} MAKEOBJDIRPREFIX=${CRUNCHOBJS} \ MK_AUTO_OBJ=${MK_AUTO_OBJ} \ ${CRUNCHGEN} -fq -m ${OUTMK} -c ${OUTC} ${CONF} # Avoid redundantly calling 'make objs' which we've done by our @@ -127,20 +127,22 @@ ${PROG}: ${OUTPUTS} objs .NOMETA .PHONY ${CRUNCHENV} \ CC="${CC} ${CFLAGS} ${LDFLAGS}" \ CXX="${CXX} ${CXXFLAGS} ${LDFLAGS}" \ - ${MAKE} .MAKE.MODE="${.MAKE.MODE} curdirOk=yes" \ + ${MAKE} ${CRUNCHARGS} .MAKE.MODE="${.MAKE.MODE} curdirOk=yes" \ .MAKE.META.IGNORE_PATHS="${.MAKE.META.IGNORE_PATHS}" \ -f ${OUTMK} exe objs: ${OUTMK} .META ${CRUNCHENV} MAKEOBJDIRPREFIX=${CRUNCHOBJS} \ - ${MAKE} -f ${OUTMK} BUILD_TOOLS_META=.NOMETA objs + ${MAKE} -f ${OUTMK} ${CRUNCHARGS} BUILD_TOOLS_META=.NOMETA objs # Someone should replace the bin/csh and bin/sh build-tools with # shell scripts so we can remove this nonsense. .for _tool in ${CRUNCH_BUILDTOOLS} build-tools-${_tool}: ${_+_}cd ${.CURDIR}/../../${_tool}; \ - ${CRUNCHENV} MAKEOBJDIRPREFIX=${CRUNCHOBJS} ${MAKE} obj; \ + if [ "${MK_AUTO_OBJ}" = "no" ]; then \ + ${CRUNCHENV} MAKEOBJDIRPREFIX=${CRUNCHOBJS} ${MAKE} obj; \ + fi; \ ${CRUNCHENV} MAKEOBJDIRPREFIX=${CRUNCHOBJS} ${MAKE} build-tools build-tools: build-tools-${_tool} .endfor @@ -155,6 +157,7 @@ build-tools: build-tools-${_tool} ${__target}_crunchdir_${P}: .PHONY .MAKE ${_+_}cd ${CRUNCH_SRCDIR_${P}} && \ ${CRUNCHENV} MAKEOBJDIRPREFIX=${CANONICALOBJDIR} ${MAKE} \ + ${CRUNCHARGS} \ DIRPRFX=${DIRPRFX}${P}/ ${CRUNCH_BUILDOPTS} ${__target} ${__target}: ${__target}_crunchdir_${P} .endfor diff --git a/share/mk/bsd.dep.mk b/share/mk/bsd.dep.mk index 403c07c7c313..c6bf68b067f4 100644 --- a/share/mk/bsd.dep.mk +++ b/share/mk/bsd.dep.mk @@ -101,7 +101,7 @@ _SKIP_DEPEND= 1 CLEANFILES?= .for _S in ${SRCS:N*.[dhly]} -OBJS_DEPEND_GUESS.${_S:R}.o+= ${_S} +OBJS_DEPEND_GUESS.${_S:${OBJS_SRCS_FILTER:ts:}}.o+= ${_S} .endfor # Lexical analyzers @@ -180,7 +180,7 @@ DEPEND_MP?= -MP DEPEND_FILTER= C,/,_,g DEPENDSRCS= ${SRCS:M*.[cSC]} ${SRCS:M*.cxx} ${SRCS:M*.cpp} ${SRCS:M*.cc} .if !empty(DEPENDSRCS) -DEPENDOBJS+= ${DEPENDSRCS:R:S,$,.o,} +DEPENDOBJS+= ${DEPENDSRCS:${OBJS_SRCS_FILTER:ts:}:S,$,.o,} .endif DEPENDFILES_OBJS= ${DEPENDOBJS:O:u:${DEPEND_FILTER}:C/^/${DEPENDFILE}./} .if defined(_SKIP_DEPEND) @@ -327,6 +327,10 @@ cleandepend: .endif .ORDER: cleandepend all .ORDER: cleandepend depend +.if ${MK_AUTO_OBJ} == "yes" +.ORDER: cleanobj depend +.ORDER: cleandir depend +.endif .if !target(checkdpadd) && (defined(DPADD) || defined(LDADD)) _LDADD_FROM_DPADD= ${DPADD:R:T:C;^lib(.*)$;-l\1;g} diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk index 735fd37e7dfa..10bfe7721fe0 100644 --- a/share/mk/bsd.incs.mk +++ b/share/mk/bsd.incs.mk @@ -89,7 +89,6 @@ _${group}INS: ${_${group}INCS} .if defined(INCSLINKS) && !empty(INCSLINKS) installincludes: .for s t in ${INCSLINKS} - @${ECHO} "${DESTDIR}${t} -> ${s}" ; \ ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},development} ${s} ${DESTDIR}${t} .endfor .endif diff --git a/share/mk/bsd.init.mk b/share/mk/bsd.init.mk index ce3b3a4e3d17..f3851745a44d 100644 --- a/share/mk/bsd.init.mk +++ b/share/mk/bsd.init.mk @@ -10,12 +10,24 @@ ____: .include .-include "local.init.mk" + +.if ${MK_AUTO_OBJ} == "yes" +# This is also done in bsd.obj.mk +.if defined(NO_OBJ) +.OBJDIR: ${.CURDIR} +.endif +.endif + .if exists(${.CURDIR}/../Makefile.inc) .include "${.CURDIR}/../Makefile.inc" .endif .include .MAIN: all +# This is used in bsd.{dep,lib,prog}.mk as ${OBJS_SRCS_FILTER:ts:} +# Some makefiles may want T as well to avoid nested objdirs. +OBJS_SRCS_FILTER+= R + # Handle INSTALL_AS_USER here to maximize the chance that # it has final authority over fooOWN and fooGRP. .if ${MK_INSTALL_AS_USER} != "no" @@ -52,7 +64,8 @@ _SKIP_BUILD= not building at level 0 ${.TARGETS:M*install*} == ${.TARGETS} || \ ${.TARGETS:Mclean*} == ${.TARGETS} || \ ${.TARGETS:Mdestroy*} == ${.TARGETS} || \ - make(obj) || make(analyze) || make(print-dir) + ${.TARGETS:Mobj} == ${.TARGETS} || \ + make(analyze) || make(print-dir) # Skip building, but don't show a warning. _SKIP_BUILD= .endif diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index db66b7f189b1..d3e4d7839cff 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -168,8 +168,10 @@ LDFLAGS+= -Wl,--version-script=${VERSION_MAP} .endif .if defined(LIB) && !empty(LIB) || defined(SHLIB_NAME) -OBJS+= ${SRCS:N*.h:R:S/$/.o/} -CLEANFILES+= ${OBJS} ${STATICOBJS} +OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.o/} +BCOBJS+= ${SRCS:N*.[hsS]:N*.asm:${OBJS_SRCS_FILTER:ts:}:S/$/.bco/g} +LLOBJS+= ${SRCS:N*.[hsS]:N*.asm:${OBJS_SRCS_FILTER:ts:}:S/$/.llo/g} +CLEANFILES+= ${OBJS} ${BCOBJS} ${LLOBJS} ${STATICOBJS} .endif .if defined(LIB) && !empty(LIB) @@ -200,15 +202,13 @@ lib${LIB_PRIVATE}${LIB}_p.a: ${POBJS} .endif .if defined(LLVM_LINK) -BCOBJS= ${OBJS:.o=.bco} ${STATICOBJS:.o=.bco} -LLOBJS= ${OBJS:.o=.llo} ${STATICOBJS:.o=.llo} -CLEANFILES+= ${BCOBJS} ${LLOBJS} - lib${LIB_PRIVATE}${LIB}.bc: ${BCOBJS} ${LLVM_LINK} -o ${.TARGET} ${BCOBJS} lib${LIB_PRIVATE}${LIB}.ll: ${LLOBJS} ${LLVM_LINK} -S -o ${.TARGET} ${LLOBJS} + +CLEANFILES+= lib${LIB_PRIVATE}${LIB}.bc lib${LIB_PRIVATE}${LIB}.ll .endif .if defined(SHLIB_NAME) || \ @@ -437,13 +437,13 @@ lint: ${SRCS:M*.c} .if defined(LIB) && !empty(LIB) OBJS_DEPEND_GUESS+= ${SRCS:M*.h} .for _S in ${SRCS:N*.[hly]} -OBJS_DEPEND_GUESS.${_S:R}.po+= ${_S} +OBJS_DEPEND_GUESS.${_S:${OBJS_SRCS_FILTER:ts:}}.po+= ${_S} .endfor .endif .if defined(SHLIB_NAME) || \ defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB) .for _S in ${SRCS:N*.[hly]} -OBJS_DEPEND_GUESS.${_S:R}.pico+= ${_S} +OBJS_DEPEND_GUESS.${_S:${OBJS_SRCS_FILTER:ts:}}.pico+= ${_S} .endfor .endif diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index 6a592c84b422..b95ea0937697 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -142,7 +142,6 @@ LIBSDP?= ${LIBDESTDIR}${LIBDIR_BASE}/libsdp.a LIBSMB?= ${LIBDESTDIR}${LIBDIR_BASE}/libsmb.a LIBSSL?= ${LIBDESTDIR}${LIBDIR_BASE}/libssl.a LIBSSP_NONSHARED?= ${LIBDESTDIR}${LIBDIR_BASE}/libssp_nonshared.a -LIBSTAND?= ${LIBDESTDIR}${LIBDIR_BASE}/libstand.a LIBSTDCPLUSPLUS?= ${LIBDESTDIR}${LIBDIR_BASE}/libstdc++.a LIBSTDTHREADS?= ${LIBDESTDIR}${LIBDIR_BASE}/libstdthreads.a LIBSYSDECODE?= ${LIBDESTDIR}${LIBDIR_BASE}/libsysdecode.a diff --git a/share/mk/bsd.links.mk b/share/mk/bsd.links.mk index f932f39c446e..fbae4c0f6420 100644 --- a/share/mk/bsd.links.mk +++ b/share/mk/bsd.links.mk @@ -15,10 +15,8 @@ afterinstall: _installlinks .ORDER: realinstall _installlinks _installlinks: .for s t in ${LINKS} - @${ECHO} "${t} -> ${s}" ;\ ${INSTALL_LINK} ${TAG_ARGS} ${DESTDIR}${s} ${DESTDIR}${t} .endfor .for s t in ${SYMLINKS} - @${ECHO} "${t} -> ${s}" ;\ ${INSTALL_SYMLINK} ${TAG_ARGS} ${s} ${DESTDIR}${t} .endfor diff --git a/share/mk/bsd.obj.mk b/share/mk/bsd.obj.mk index c9b099b86889..e4a7bf69682c 100644 --- a/share/mk/bsd.obj.mk +++ b/share/mk/bsd.obj.mk @@ -47,6 +47,7 @@ ____: objwarn: obj: CANONICALOBJDIR= ${.OBJDIR} +# This is also done in bsd.init.mk .if defined(NO_OBJ) # but this makefile does not want it! .OBJDIR: ${.CURDIR} @@ -75,7 +76,7 @@ __objdir_made != umask ${OBJDIR_UMASK:U002}; ${Mkdirs}; \ done .endif .endif # !empty(SRCS:M*/*) || !empty(DPSRCS:M*/*) -.elif defined(MAKEOBJDIRPREFIX) +.elif !empty(MAKEOBJDIRPREFIX) CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR} .elif defined(MAKEOBJDIR) && ${MAKEOBJDIR:M/*} != "" CANONICALOBJDIR:=${MAKEOBJDIR} @@ -84,6 +85,11 @@ OBJTOP?= ${MAKEOBJDIR} CANONICALOBJDIR:=/usr/obj${.CURDIR} .endif +.if defined(SRCTOP) && defined(RELDIR) && \ + (${CANONICALOBJDIR} == /${RELDIR} || ${.OBJDIR} == /${RELDIR}) +.error .OBJDIR incorrectly set to /${RELDIR} +.endif + OBJTOP?= ${.OBJDIR:S,${.CURDIR},,}${SRCTOP} # @@ -158,7 +164,8 @@ whereobj: .endif # Same check in bsd.progs.mk -.if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) +.if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) && \ + (${MK_AUTO_OBJ} == "no" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} == "") cleanobj: -rm -rf ${CANONICALOBJDIR} .else @@ -182,6 +189,10 @@ clean: .endif .endif .ORDER: clean all +.if ${MK_AUTO_OBJ} == "yes" +.ORDER: cleanobj all +.ORDER: cleandir all +.endif .include diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index b66424b1d193..a3129a8cdca9 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -85,7 +85,11 @@ PROGNAME?= ${PROG} .if defined(SRCS) -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} +OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.o/g} + +# LLVM bitcode / textual IR representations of the program +BCOBJS+=${SRCS:N*.[hsS]:N*.asm:${OBJS_SRCS_FILTER:ts:}:S/$/.bco/g} +LLOBJS+=${SRCS:N*.[hsS]:N*.asm:${OBJS_SRCS_FILTER:ts:}:S/$/.llo/g} .if target(beforelinking) beforelinking: ${OBJS} @@ -117,7 +121,10 @@ SRCS= ${PROG}.c # - the name of the object gets put into the executable symbol table instead of # the name of a variable temporary object. # - it's useful to keep objects around for crunching. -OBJS+= ${PROG}.o +OBJS+= ${PROG}.o +BCOBJS+= ${PROG}.bc +LLOBJS+= ${PROG}.ll +CLEANFILES+= ${PROG}.o ${PROG}.bc ${PROG}.ll .if target(beforelinking) beforelinking: ${OBJS} @@ -148,16 +155,13 @@ ${PROGNAME}.debug: ${PROG_FULL} .endif .if defined(LLVM_LINK) -# LLVM bitcode / textual IR representations of the program -BCOBJS= ${OBJS:.o=.bco} -LLOBJS= ${OBJS:.o=.llo} - ${PROG_FULL}.bc: ${BCOBJS} ${LLVM_LINK} -o ${.TARGET} ${BCOBJS} ${PROG_FULL}.ll: ${LLOBJS} ${LLVM_LINK} -S -o ${.TARGET} ${LLOBJS} +CLEANFILES+= ${PROG_FULL}.bc ${PROG_FULL}.ll .endif # defined(LLVM_LINK) .if ${MK_MAN} != "no" && !defined(MAN) && \ @@ -181,7 +185,7 @@ all: all-man .if defined(PROG) CLEANFILES+= ${PROG} ${PROG}.bc ${PROG}.ll .if ${MK_DEBUG_FILES} != "no" -CLEANFILES+= ${PROG_FULL} ${PROG_FULL}.bc ${PROGNAME}.debug ${PROG_FULL}.ll +CLEANFILES+= ${PROG_FULL} ${PROGNAME}.debug .endif .endif diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk index 252acea115a4..1730895705f8 100644 --- a/share/mk/bsd.subdir.mk +++ b/share/mk/bsd.subdir.mk @@ -38,12 +38,16 @@ .if !target(____) ____: +.if ${MK_AUTO_OBJ} == "no" +_obj= obj +.endif + SUBDIR_TARGETS+= \ all all-man analyze buildconfig buildfiles buildincludes \ checkdpadd clean cleandepend cleandir cleanilinks \ cleanobj depend distribute files includes installconfig \ installfiles installincludes print-dir realinstall lint \ - maninstall manlint obj objlink tags \ + maninstall manlint ${_obj} objlink tags \ # Described above. STANDALONE_SUBDIR_TARGETS+= \ @@ -69,6 +73,10 @@ print-dir: .PHONY .endif .endif +.if ${MK_AUTO_OBJ} == "yes" && !target(obj) +obj: .PHONY +.endif + .if !defined(NEED_SUBDIR) # .MAKE.DEPENDFILE==/dev/null is set by bsd.dep.mk to avoid reading # Makefile.depend diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index dbda6fee087f..0d4571c428e4 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -131,11 +131,6 @@ CWARNFLAGS+= -Wno-error=address \ -Wno-error=unused-value .endif -# GCC 5.3.0 -.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 50300 -CWARNFLAGS+= -Wno-error=strict-overflow -.endif - # GCC 6.1.0 .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 60100 CWARNFLAGS+= -Wno-error=misleading-indentation \ diff --git a/share/mk/local.dirdeps.mk b/share/mk/local.dirdeps.mk index fd675a9fcb08..85f7bbf052c0 100644 --- a/share/mk/local.dirdeps.mk +++ b/share/mk/local.dirdeps.mk @@ -49,6 +49,20 @@ DIRDEPS_FILTER.host = \ DIRDEPS_FILTER+= \ Nbin/cat.host \ ${DIRDEPS_FILTER.xtras:U} + +# Cleanup a buildworld's WORLDTMP so that any files generated from it +# or using it will rebuild with the DIRDEPS SYSROOT. Otherwise existing +# object .meta files may still reference those directories and not be +# rebuilt and lead to incorrect Makefile.depend files due to lack of +# .dirdep files. +.if !defined(NO_CLEANUP_WORLDTMP) && exists(${OBJTOP}/tmp/_worldtmp) +cleanup_worldtmp: .PHONY .NOMETA + @echo "Cleaning leftover WORLDTMP from buildworld." + -rm -rf ${OBJTOP}/tmp/* + -chflags -R 0 ${OBJTOP}/tmp/* + rm -rf ${OBJTOP}/tmp +beforedirdeps: cleanup_worldtmp +.endif .endif # reset this each time @@ -76,6 +90,19 @@ DIRDEPS += \ cddl/usr.bin/ctfmerge.host .endif +# Add in proper libgcc (gnu or LLVM) if not building libcc and libc is needed. +# Add both gcc_s and gcc_eh as dependencies as the decision to build +# -static or not is not known here. +.if ${DEP_RELDIR:M*libgcc*} == "" && ${DIRDEPS:Mlib/libc} +.if ${MK_LLVM_LIBUNWIND} == "yes" +DIRDEPS+= \ + lib/libgcc_eh \ + lib/libgcc_s +.else +DIRDEPS+= gnu/lib/libgcc +.endif +.endif + # Bootstrap support. Give hints to DIRDEPS if there is no Makefile.depend* # generated yet. This can be based on things such as SRC files and LIBADD. # These hints will not factor into the final Makefile.depend as only what is @@ -124,7 +151,6 @@ _SRCS= ${SRCS} ${_PROGS_SRCS} # Has C files. The C_DIRDEPS are shared with C++ files as well. C_DIRDEPS= \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ @@ -135,6 +161,7 @@ C_DIRDEPS= \ lib/libc \ lib/libcompiler_rt \ +# libgcc is needed as well but is added later. .if ${MK_GSSAPI} != "no" C_DIRDEPS+= include/gssapi diff --git a/share/mk/local.gendirdeps.mk b/share/mk/local.gendirdeps.mk index 5df941602f77..009e10d8d494 100644 --- a/share/mk/local.gendirdeps.mk +++ b/share/mk/local.gendirdeps.mk @@ -10,6 +10,9 @@ GENDIRDEPS_FILTER+= \ Ngnu/lib/libssp/libssp_nonshared \ Ncddl/usr.bin/ctf* \ Nlib/libc_nonshared \ + Ngnu/lib/libgcc \ + Nlib/libgcc_eh \ + Nlib/libgcc_s \ Ntargets/pseudo/stage* \ Ntools/* diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk index 2706683f210b..ce7e35bd72a1 100644 --- a/share/mk/local.meta.sys.mk +++ b/share/mk/local.meta.sys.mk @@ -7,43 +7,14 @@ # we need this until there is an alternative MK_INSTALL_AS_USER= yes -_default_makeobjdir=$${.CURDIR:S,^$${SRCTOP},$${OBJTOP},} - -.if empty(OBJROOT) || ${.MAKE.LEVEL} == 0 -.if defined(MAKEOBJDIRPREFIX) && !empty(MAKEOBJDIRPREFIX) -# put things approximately where they want -OBJROOT:=${MAKEOBJDIRPREFIX}${SRCTOP}/ -MAKEOBJDIRPREFIX= -.export MAKEOBJDIRPREFIX -.endif -.if empty(MAKEOBJDIR) -# OBJTOP set below -MAKEOBJDIR=${_default_makeobjdir} -# export but do not track -.export-env MAKEOBJDIR -# Expand for our own use -MAKEOBJDIR:= ${MAKEOBJDIR} -.endif -.if !empty(SB) -SB_OBJROOT ?= ${SB}/obj/ -# this is what we use below -OBJROOT ?= ${SB_OBJROOT} -.endif -OBJROOT ?= /usr/obj${SRCTOP}/ -.if ${OBJROOT:M*/} != "" -OBJROOT:= ${OBJROOT:H:tA}/ -.else -OBJROOT:= ${OBJROOT:H:tA}/${OBJROOT:T} -.endif -.export OBJROOT SRCTOP - +.if !defined(HOST_TARGET) # we need HOST_TARGET etc below. .include .export HOST_TARGET .endif # from src/Makefile (for universe) -TARGET_ARCHES_arm?= arm armeb armv6 +TARGET_ARCHES_arm?= arm armeb armv6 armv7 TARGET_ARCHES_arm64?= aarch64 TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipsn32el TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe @@ -107,7 +78,7 @@ TARGET_OBJ_SPEC:= ${TARGET_SPEC:S;,;.;g} OBJTOP:= ${OBJROOT}${TARGET_OBJ_SPEC} .if defined(MAKEOBJDIR) -.if ${MAKEOBJDIR:M*/*} == "" +.if ${MAKEOBJDIR:M/*} == "" .error Cannot use MAKEOBJDIR=${MAKEOBJDIR}${.newline}Unset MAKEOBJDIR to get default: MAKEOBJDIR='${_default_makeobjdir}' .endif .endif diff --git a/share/mk/local.sys.env.mk b/share/mk/local.sys.env.mk index ca3f7a0e0e75..c901b81c77ce 100644 --- a/share/mk/local.sys.env.mk +++ b/share/mk/local.sys.env.mk @@ -40,4 +40,8 @@ TIME_STAMP = ${TIME_STAMP_FMT:localtime} TIME_STAMP_DATE = `date '+${TIME_STAMP_FMT}'` TIME_STAMP_END?= ${TIME_STAMP_DATE} +# Simplify auto.obj.mk mkdir -p handling and avoid unneeded/redundant +# error spam and show a proper error. +Mkdirs= Mkdirs() { mkdir -p $$* || :; } + .include "src.sys.env.mk" diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index fb5f77c989d9..703adb03cc56 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -20,6 +20,7 @@ _PRIVATELIBS= \ event \ heimipcc \ heimipcs \ + ifconfig \ ldns \ sqlite3 \ ssh \ @@ -42,6 +43,7 @@ _INTERNALLIBS= \ opts \ parse \ pe \ + pmcstat \ readline \ sl \ sm \ @@ -108,7 +110,6 @@ _LIBRARIES= \ heimntlm \ heimsqlite \ hx509 \ - ifconfig \ ipsec \ jail \ kadm5clnt \ @@ -465,6 +466,9 @@ LIBBSNMPTOOLS?= ${LIBBSNMPTOOLSDIR}/libbsnmptools.a LIBAMUDIR= ${OBJTOP}/usr.sbin/amd/libamu LIBAMU?= ${LIBAMUDIR}/libamu.a +LIBPMCSTATDIR= ${OBJTOP}/lib/libpmcstat +LIBPMCSTAT?= ${LIBPMCSTATDIR}/libpmcstat.a + # Define a directory for each library. This is useful for adding -L in when # not using a --sysroot or for meta mode bootstrapping when there is no # Makefile.depend. These are sorted by directory. diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 8eeaa7b8e551..83eb875bcbe2 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -62,7 +62,6 @@ __DEFAULT_YES_OPTIONS = \ BOOTPARAMD \ BOOTPD \ BSD_CPIO \ - BSD_GREP_FASTMATCH \ BSDINSTALL \ BSNMP \ BZIP2 \ @@ -175,15 +174,16 @@ __DEFAULT_YES_OPTIONS = \ __DEFAULT_NO_OPTIONS = \ BSD_GREP \ + BSD_GREP_FASTMATCH \ CLANG_EXTRAS \ DTRACE_TESTS \ GNU_GREP_COMPAT \ HESIOD \ LIBSOFT \ + LOADER_FORCE_LE \ NAND \ OFED \ OPENLDAP \ - RCMDS \ REPRODUCIBLE_BUILD \ RPCBIND_WARMSTART_SUPPORT \ SHARED_TOOLCHAIN \ @@ -227,8 +227,8 @@ __DEFAULT_NO_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX GPL_DTC # If an external compiler that supports C++11 is used as ${CC} and Clang # supports the target, then Clang is enabled but GCC is installed as the # default /usr/bin/cc. -__DEFAULT_YES_OPTIONS+=CLANG CLANG_FULL GCC GCC_BOOTSTRAP GNUCXX -__DEFAULT_NO_OPTIONS+=CLANG_BOOTSTRAP CLANG_IS_CC GPL_DTC LLD +__DEFAULT_YES_OPTIONS+=CLANG CLANG_FULL GCC GCC_BOOTSTRAP GNUCXX GPL_DTC +__DEFAULT_NO_OPTIONS+=CLANG_BOOTSTRAP CLANG_IS_CC LLD .else # Everything else disables Clang, and uses GCC instead. __DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX GPL_DTC @@ -271,8 +271,8 @@ __DEFAULT_NO_OPTIONS+=GDB_LIBEXEC .else __DEFAULT_YES_OPTIONS+=GDB_LIBEXEC .endif -# Only doing soft float API stuff on armv6 -.if ${__T} != "armv6" +# Only doing soft float API stuff on armv6 and armv7 +.if ${__T} != "armv6" && ${__T} != "armv7" BROKEN_OPTIONS+=LIBSOFT .endif .if ${__T:Mmips*} diff --git a/share/mk/src.sys.env.mk b/share/mk/src.sys.env.mk index 1b436ce46cb6..b100c2ad1429 100644 --- a/share/mk/src.sys.env.mk +++ b/share/mk/src.sys.env.mk @@ -6,10 +6,14 @@ SRCTOP:= ${.PARSEDIR:tA:H:H} .if ${.CURDIR} == ${SRCTOP} -RELDIR = . +RELDIR= . +RELTOP= . .elif ${.CURDIR:M${SRCTOP}/*} -RELDIR := ${.CURDIR:S,${SRCTOP}/,,} +RELDIR:= ${.CURDIR:S,${SRCTOP}/,,} .endif +RELTOP?= ${RELDIR:C,[^/]+,..,g} +RELOBJTOP?= ${RELTOP} +RELSRCTOP?= ${RELTOP} # site customizations that do not depend on anything! SRC_ENV_CONF?= /etc/src-env.conf @@ -39,3 +43,5 @@ MAKESYSPATH:= ${MAKESYSPATH:S,.../share/mk,${.PARSEDIR:tA},} MAKESYSPATH:= ${.PARSEDIR:tA} .export MAKESYSPATH .endif + +.include diff --git a/share/mk/src.sys.mk b/share/mk/src.sys.mk index 9a627f647a9f..fff26b477c61 100644 --- a/share/mk/src.sys.mk +++ b/share/mk/src.sys.mk @@ -14,7 +14,7 @@ SRCCONF?= /etc/src.conf # Validate that the user didn't try setting an env-only variable in # their src.conf. This benefits from already including bsd.mkopt.mk. -.for var in ${__ENV_ONLY_OPTIONS} +.for var in ${__ENV_ONLY_OPTIONS:O:u} __presrcconf_${var}:= ${MK_${var}:U-}${WITHOUT_${var}:Uno:Dyes}${WITH_${var}:Uno:Dyes} .endfor @@ -22,7 +22,7 @@ __presrcconf_${var}:= ${MK_${var}:U-}${WITHOUT_${var}:Uno:Dyes}${WITH_${var}:Uno _srcconf_included_: .NOTMAIN # Validate the env-only variables. -.for var in ${__ENV_ONLY_OPTIONS} +.for var in ${__ENV_ONLY_OPTIONS:O:u} __postrcconf_${var}:= ${MK_${var}:U-}${WITHOUT_${var}:Uno:Dyes}${WITH_${var}:Uno:Dyes} .if ${__presrcconf_${var}} != ${__postrcconf_${var}} .error Option ${var} may only be defined in ${SRC_ENV_CONF}, environment, or make argument, not ${SRCCONF}. diff --git a/share/mk/src.sys.obj.mk b/share/mk/src.sys.obj.mk new file mode 100644 index 000000000000..811a0ae20d40 --- /dev/null +++ b/share/mk/src.sys.obj.mk @@ -0,0 +1,181 @@ +# $FreeBSD$ +# +# Early setup of MAKEOBJDIR +# +# Default format is: /usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/]bin/sh +# MAKEOBJDIRPREFIX is /usr/obj +# OBJROOT is /usr/obj/usr/src/ +# OBJTOP is /usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/] +# MAKEOBJDIR is /usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/]bin/sh +# +# MAKEOBJDIRPREFIX will override the default pattern above and internally +# set MAKEOBJDIR. If OBJROOT is set then MAKEOBJDIRPREFIX is rooted inside +# of there. +# +# If MK_UNIFIED_OBJDIR is no then OBJROOT will always match OBJTOP. +# +# If .MAKE.LEVEL == 0 then the TARGET.TARGET_ARCH is potentially added on. +# If .MAKE.LEVEL > 0 and MAKEOBJDIRPREFIX is set then it will not get +# TARGET.TARGET_ARCH added in as it assumes that MAKEOBJDIRPREFIX is +# nested in the existing OBJTOP with TARGET.TARGET_ARCH in it. +# + +_default_makeobjdirprefix?= /usr/obj +_default_makeobjdir= $${.CURDIR:S,^$${SRCTOP},$${OBJTOP},} + +.include + +.if ${.MAKE.LEVEL} == 0 || empty(OBJROOT) +.if ${MK_UNIFIED_OBJDIR} == "no" +# Fall back to historical behavior. +# We always want to set a default MAKEOBJDIRPREFIX... +MAKEOBJDIRPREFIX?= ${_default_makeobjdirprefix} +# but don't enforce TARGET.TARGET_ARCH unless we're at the top-level directory. +.if ${.CURDIR} == ${SRCTOP} && \ + !(defined(TARGET) && defined(TARGET_ARCH) && \ + ${MACHINE} == ${TARGET} && ${MACHINE_ARCH} == ${TARGET_ARCH} && \ + !defined(CROSS_BUILD_TESTING)) +MAKEOBJDIRPREFIX:= ${MAKEOBJDIRPREFIX}${TARGET:D/${TARGET}.${TARGET_ARCH}} +.endif +.endif # ${MK_UNIFIED_OBJDIR} == "no" + +.if !empty(MAKEOBJDIRPREFIX) +# put things approximately where they want +OBJROOT:= ${MAKEOBJDIRPREFIX}${SRCTOP}/ +MAKEOBJDIRPREFIX= +# export but do not track +.export-env MAKEOBJDIRPREFIX +.endif +.if empty(MAKEOBJDIR) +# OBJTOP set below +MAKEOBJDIR= ${_default_makeobjdir} +# export but do not track +.export-env MAKEOBJDIR +# Expand for our own use +MAKEOBJDIR:= ${MAKEOBJDIR} +.endif +# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm +.if !empty(SB) +SB_OBJROOT?= ${SB}/obj/ +# this is what we use below +OBJROOT?= ${SB_OBJROOT} +.endif +OBJROOT?= ${_default_makeobjdirprefix}${SRCTOP}/ +.if ${OBJROOT:M*/} != "" +OBJROOT:= ${OBJROOT:H:tA}/ +.else +OBJROOT:= ${OBJROOT:H:tA}/${OBJROOT:T} +.endif +# Must export since OBJDIR will dynamically be based on it +.export OBJROOT SRCTOP +.endif + +.if ${MK_UNIFIED_OBJDIR} == "yes" +OBJTOP:= ${OBJROOT}${TARGET:D${TARGET}.${TARGET_ARCH}:U${MACHINE}.${MACHINE_ARCH}} +.else +# TARGET.TARGET_ARCH handled in OBJROOT already. +OBJTOP:= ${OBJROOT:H} +.endif # ${MK_UNIFIED_OBJDIR} == "yes" + +# Fixup OBJROOT/OBJTOP if using MAKEOBJDIRPREFIX but leave it alone +# for DIRDEPS_BUILD which really wants to know the absolute top at +# all times. This intenionally comes after adding TARGET.TARGET_ARCH +# so that is truncated away for nested objdirs. This logic also +# will not trigger if the OBJROOT block above unsets MAKEOBJDIRPREFIX. +.if !empty(MAKEOBJDIRPREFIX) && ${MK_DIRDEPS_BUILD} == "no" +OBJTOP:= ${MAKEOBJDIRPREFIX}${SRCTOP} +OBJROOT:= ${OBJTOP}/ +.endif + +# Wait to validate MAKEOBJDIR until OBJTOP is set. +.if defined(MAKEOBJDIR) +.if ${MAKEOBJDIR:M/*} == "" +.error Cannot use MAKEOBJDIR=${MAKEOBJDIR}${.newline}Unset MAKEOBJDIR to get default: MAKEOBJDIR='${_default_makeobjdir}' +.endif +.endif + +# __objdir is the expected .OBJDIR we want to use and that auto.obj.mk will +# try to create. +.if !empty(MAKEOBJDIRPREFIX) +__objdir:= ${MAKEOBJDIRPREFIX}${.CURDIR} +.elif !empty(MAKEOBJDIR) +__objdir:= ${MAKEOBJDIR} +.endif + +# Try to enable MK_AUTO_OBJ by default if we can write to the __objdir. Only +# do this if AUTO_OBJ is not disabled by the user, not cleaning, and this is +# the first make ran. +.if 0 && ${.MAKE.LEVEL} == 0 && \ + ${MK_AUTO_OBJ} == "no" && empty(.MAKEOVERRIDES:MMK_AUTO_OBJ) && \ + !defined(WITHOUT_AUTO_OBJ) && !make(showconfig) && !make(print-dir) && \ + !defined(NO_OBJ) && \ + (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "") +# Find the last existing directory component and check if we can write to it. +# If the last component is a symlink then recurse on the new path. +CheckAutoObj= \ +DirIsCreatable() { \ + [ -w "$${1}" ] && return 0; \ + d="$${1}"; \ + IFS=/; \ + set -- $${d}; \ + unset dir; \ + while [ $$\# -gt 0 ]; do \ + d="$${1}"; \ + shift; \ + if [ ! -d "$${dir}$${d}/" ]; then \ + if [ -L "$${dir}$${d}" ]; then \ + dir="$$(readlink "$${dir}$${d}")/"; \ + for d in "$${@}"; do \ + dir="$${dir}$${d}/"; \ + done; \ + ret=0; \ + DirIsCreatable "$${dir%/}" || ret=$$?; \ + return $${ret}; \ + else \ + break; \ + fi; \ + fi; \ + dir="$${dir}$${d}/"; \ + done; \ + [ -w "$${dir}" ]; \ +}; \ +CheckAutoObj() { \ + if DirIsCreatable "$${1}"; then \ + echo yes; \ + else \ + echo no; \ + fi; \ +} +.if !empty(__objdir) +__objdir_writable!= \ + ${CheckAutoObj}; CheckAutoObj "${__objdir}" || echo no +.endif +__objdir_writable?= no +# Export the decision to sub-makes. +MK_AUTO_OBJ:= ${__objdir_writable} +.export MK_AUTO_OBJ +.elif make(showconfig) +# Need to export for showconfig internally running make -dg1. It is enabled +# in sys.mk by default. +.export MK_AUTO_OBJ +.endif # ${MK_AUTO_OBJ} == "no" && ... + +# Assign this directory as .OBJDIR if possible. +# +# The expected OBJDIR already exists, set it as .OBJDIR. +.if !empty(__objdir) && exists(${__objdir}) +.OBJDIR: ${__objdir} +# Special case to work around bmake bug. If the top-level .OBJDIR does not yet +# exist and MAKEOBJDIR is passed into environment and yield a blank value, +# bmake will incorrectly set .OBJDIR=${SRCTOP}/ rather than the expected +# ${SRCTOP} to match ${.CURDIR}. +.elif ${MAKE_VERSION} <= 20170720 && \ + ${.CURDIR} == ${SRCTOP} && ${.OBJDIR} == ${SRCTOP}/ +.OBJDIR: ${.CURDIR} +.else +# The OBJDIR we wanted does not yet exist, ensure we default to safe .CURDIR +# in case make started with a bogus MAKEOBJDIR, that expanded before OBJTOP +# was set, that happened to match some unexpected directory. Either +# auto.obj.mk or bsd.obj.mk will create the directory and fix .OBJDIR later. +.OBJDIR: ${.CURDIR} +.endif diff --git a/share/mk/suite.test.mk b/share/mk/suite.test.mk index b314eceb389e..5639691df721 100644 --- a/share/mk/suite.test.mk +++ b/share/mk/suite.test.mk @@ -101,11 +101,11 @@ realcheck: .PHONY fi @env ${TESTS_ENV:Q} ${KYUA} test -k ${DESTDIR}${TESTSDIR}/Kyuafile -MAKE_CHECK_SANDBOX_DIR= ${.OBJDIR}/checkdir +MAKE_CHECK_SANDBOX_DIR= checkdir CLEANDIRS+= ${MAKE_CHECK_SANDBOX_DIR} .if ${MK_MAKE_CHECK_USE_SANDBOX} != "no" && make(check) -DESTDIR:= ${MAKE_CHECK_SANDBOX_DIR} +DESTDIR:= ${.OBJDIR}/${MAKE_CHECK_SANDBOX_DIR} beforecheck: .for t in clean depend all diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 71726e619ba4..e59671f430f0 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -13,10 +13,18 @@ unix ?= We run FreeBSD, not UNIX. # and/or endian. This is called MACHINE_CPU in NetBSD, but that's used # for something different in FreeBSD. # -__TO_CPUARCH=C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64(sf)?/riscv/ +__TO_CPUARCH=C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v[67])?(eb)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64(sf)?/riscv/ MACHINE_CPUARCH=${MACHINE_ARCH:${__TO_CPUARCH}} .endif +__DEFAULT_YES_OPTIONS+= \ + UNIFIED_OBJDIR + +# src.sys.obj.mk enables AUTO_OBJ by default if possible but it is otherwise +# disabled. Ensure src.conf.5 shows it as default on. +.if make(showconfig) +__DEFAULT_YES_OPTIONS+= AUTO_OBJ +.endif # Some options we need now __DEFAULT_NO_OPTIONS= \ @@ -51,8 +59,11 @@ MK_META_MODE= no .if ${MK_DIRDEPS_BUILD} == "yes" .sinclude .elif ${MK_META_MODE} == "yes" +META_MODE+= meta +.if empty(.MAKEFLAGS:M-s) # verbose will show .MAKE.META.PREFIX for each target. -META_MODE+= meta verbose +META_MODE+= verbose +.endif .if !defined(NO_META_MISSING) META_MODE+= missing-meta=yes .endif @@ -110,7 +121,7 @@ NO_META_IGNORE_HOST_HEADERS= 1 .if !make(showconfig) && !make(print-dir) .sinclude .endif -.endif +.endif # ${MK_AUTO_OBJ} == "yes" .else # bmake .include .endif diff --git a/share/monetdef/Makefile b/share/monetdef/Makefile index bb079411bea8..56f954b40a15 100644 --- a/share/monetdef/Makefile +++ b/share/monetdef/Makefile @@ -58,6 +58,7 @@ LOCALES+= hu_HU.UTF-8 LOCALES+= hy_AM.ARMSCII-8 LOCALES+= hy_AM.UTF-8 LOCALES+= is_IS.UTF-8 +LOCALES+= it_CH.ISO8859-15 LOCALES+= it_CH.UTF-8 LOCALES+= ja_JP.SJIS LOCALES+= ja_JP.UTF-8 @@ -132,7 +133,6 @@ SAME+= nl_BE.ISO8859-15 ca_FR.ISO8859-15 SAME+= nl_BE.ISO8859-15 ca_ES.ISO8859-15 SAME+= nl_BE.ISO8859-15 ca_AD.ISO8859-15 SAME+= nl_BE.UTF-8 it_IT.UTF-8 -SAME+= nl_BE.UTF-8 eu_ES.UTF-8 SAME+= nl_BE.UTF-8 es_ES.UTF-8 SAME+= nl_BE.UTF-8 el_GR.UTF-8 SAME+= nl_BE.UTF-8 de_DE.UTF-8 @@ -142,11 +142,10 @@ SAME+= nl_BE.UTF-8 ca_ES.UTF-8 SAME+= nl_BE.UTF-8 ca_AD.UTF-8 SAME+= da_DK.UTF-8 da_DK.ISO8859-15 SAME+= da_DK.UTF-8 da_DK.ISO8859-1 -SAME+= it_CH.UTF-8 it_CH.ISO8859-15 -SAME+= it_CH.UTF-8 it_CH.ISO8859-1 +SAME+= it_CH.ISO8859-15 it_CH.ISO8859-1 +SAME+= it_CH.ISO8859-15 de_CH.ISO8859-15 +SAME+= it_CH.ISO8859-15 de_CH.ISO8859-1 SAME+= it_CH.UTF-8 de_CH.UTF-8 -SAME+= it_CH.UTF-8 de_CH.ISO8859-15 -SAME+= it_CH.UTF-8 de_CH.ISO8859-1 SAME+= en_AU.UTF-8 en_AU.US-ASCII SAME+= en_AU.UTF-8 en_AU.ISO8859-15 SAME+= en_AU.UTF-8 en_AU.ISO8859-1 @@ -182,6 +181,7 @@ SAME+= sv_FI.UTF-8 se_FI.UTF-8 SAME+= sv_FI.UTF-8 lt_LT.UTF-8 SAME+= sv_FI.UTF-8 fi_FI.UTF-8 SAME+= sv_FI.UTF-8 et_EE.UTF-8 +SAME+= sl_SI.UTF-8 eu_ES.UTF-8 SAME+= sk_SK.UTF-8 pt_PT.UTF-8 SAME+= sk_SK.UTF-8 lv_LV.UTF-8 SAME+= sk_SK.UTF-8 fr_FR.UTF-8 diff --git a/share/monetdef/fr_CH.ISO8859-15.src b/share/monetdef/fr_CH.ISO8859-15.src index 13919009384f..49261a06dc8f 100644 --- a/share/monetdef/fr_CH.ISO8859-15.src +++ b/share/monetdef/fr_CH.ISO8859-15.src @@ -31,20 +31,20 @@ CHF 2 # # p_cs_precedes -1 +0 # # p_sep_by_space 1 # # n_cs_precedes -1 +0 # # n_sep_by_space -0 +1 # # p_sign_posn 1 # # n_sign_posn -4 +1 # EOF diff --git a/share/monetdef/fr_CH.UTF-8.src b/share/monetdef/fr_CH.UTF-8.src index 3056638b6b99..46906d2fe72d 100644 --- a/share/monetdef/fr_CH.UTF-8.src +++ b/share/monetdef/fr_CH.UTF-8.src @@ -31,20 +31,20 @@ CHF 2 # # p_cs_precedes -1 +0 # # p_sep_by_space 1 # # n_cs_precedes -1 +0 # # n_sep_by_space -0 +1 # # p_sign_posn 1 # # n_sign_posn -4 +1 # EOF diff --git a/share/monetdef/hy_AM.ARMSCII-8.src b/share/monetdef/hy_AM.ARMSCII-8.src index 475ebb650646..2e337a7a373e 100644 --- a/share/monetdef/hy_AM.ARMSCII-8.src +++ b/share/monetdef/hy_AM.ARMSCII-8.src @@ -31,13 +31,13 @@ AMD 0 # # p_cs_precedes -1 +0 # # p_sep_by_space 1 # # n_cs_precedes -1 +0 # # n_sep_by_space 1 diff --git a/share/monetdef/hy_AM.UTF-8.src b/share/monetdef/hy_AM.UTF-8.src index 46b3f95304e0..1f9536229a6b 100644 --- a/share/monetdef/hy_AM.UTF-8.src +++ b/share/monetdef/hy_AM.UTF-8.src @@ -31,13 +31,13 @@ AMD 0 # # p_cs_precedes -1 +0 # # p_sep_by_space 1 # # n_cs_precedes -1 +0 # # n_sep_by_space 1 diff --git a/share/monetdef/it_CH.ISO8859-15.src b/share/monetdef/it_CH.ISO8859-15.src new file mode 100644 index 000000000000..527926f0dc2a --- /dev/null +++ b/share/monetdef/it_CH.ISO8859-15.src @@ -0,0 +1,50 @@ +# Warning: Do not edit. This file is automatically generated from the +# tools in /usr/src/tools/tools/locale. The data is obtained from the +# CLDR project, obtained from http://cldr.unicode.org/ +# ----------------------------------------------------------------------------- +# +# int_curr_symbol (last character always SPACE) +CHF +# +# currency_symbol +CHF +# +# mon_decimal_point +. +# +# mon_thousands_sep +' +# +# mon_grouping +3 +# +# positive_sign + +# +# negative_sign +- +# +# int_frac_digits +2 +# +# frac_digits +2 +# +# p_cs_precedes +1 +# +# p_sep_by_space +1 +# +# n_cs_precedes +1 +# +# n_sep_by_space +0 +# +# p_sign_posn +1 +# +# n_sign_posn +4 +# EOF diff --git a/share/monetdef/it_CH.UTF-8.src b/share/monetdef/it_CH.UTF-8.src index 527926f0dc2a..01f514d30f29 100644 --- a/share/monetdef/it_CH.UTF-8.src +++ b/share/monetdef/it_CH.UTF-8.src @@ -13,7 +13,7 @@ CHF . # # mon_thousands_sep -' +’ # # mon_grouping 3 diff --git a/share/monetdef/pt_BR.UTF-8.src b/share/monetdef/pt_BR.UTF-8.src index e487eaba1c84..9460ce961a79 100644 --- a/share/monetdef/pt_BR.UTF-8.src +++ b/share/monetdef/pt_BR.UTF-8.src @@ -34,13 +34,13 @@ R$ 1 # # p_sep_by_space -0 +1 # # n_cs_precedes 1 # # n_sep_by_space -0 +1 # # p_sign_posn 1 diff --git a/share/monetdef/sl_SI.UTF-8.src b/share/monetdef/sl_SI.UTF-8.src index 1fe3e9cee91b..7bcdc1d45081 100644 --- a/share/monetdef/sl_SI.UTF-8.src +++ b/share/monetdef/sl_SI.UTF-8.src @@ -22,7 +22,7 @@ EUR # # negative_sign -– +− # # int_frac_digits 2 diff --git a/share/msgdef/Makefile b/share/msgdef/Makefile index 383a92b5834e..4c0e6d981e75 100644 --- a/share/msgdef/Makefile +++ b/share/msgdef/Makefile @@ -28,6 +28,7 @@ LOCALES+= eu_ES.UTF-8 LOCALES+= fi_FI.ISO8859-15 LOCALES+= fi_FI.UTF-8 LOCALES+= fr_FR.UTF-8 +LOCALES+= he_IL.UTF-8 LOCALES+= hi_IN.ISCII-DEV LOCALES+= hi_IN.UTF-8 LOCALES+= hu_HU.UTF-8 @@ -130,7 +131,6 @@ SAME+= de_DE.UTF-8 de_CH.ISO8859-1 SAME+= de_DE.UTF-8 de_AT.UTF-8 SAME+= de_DE.UTF-8 de_AT.ISO8859-15 SAME+= de_DE.UTF-8 de_AT.ISO8859-1 -SAME+= en_US.UTF-8 he_IL.UTF-8 SAME+= en_US.UTF-8 en_ZA.UTF-8 SAME+= en_US.UTF-8 en_ZA.US-ASCII SAME+= en_US.UTF-8 en_ZA.ISO8859-15 diff --git a/share/numericdef/fr_CH.UTF-8.src b/share/msgdef/he_IL.UTF-8.src similarity index 65% rename from share/numericdef/fr_CH.UTF-8.src rename to share/msgdef/he_IL.UTF-8.src index 0a40c9ab5d1f..a712045f9e48 100644 --- a/share/numericdef/fr_CH.UTF-8.src +++ b/share/msgdef/he_IL.UTF-8.src @@ -3,12 +3,15 @@ # CLDR project, obtained from http://cldr.unicode.org/ # ----------------------------------------------------------------------------- # -# decimal_point -. +# yesexpr +^((כן)|(×›)|([yY]([eE][sS])?)|([yY])) # -# thousands_sep -  +# noexpr +^((ל×)|(ל)|([nN]([oO])?)|([nN])) # -# grouping -3 +# yesstr +כן:×›:yes:y:YES:Y +# +# nostr +ל×:ל:no:n:NO:N # EOF diff --git a/share/numericdef/Makefile b/share/numericdef/Makefile index 93c3f92b5652..7a0e69bfa12d 100644 --- a/share/numericdef/Makefile +++ b/share/numericdef/Makefile @@ -12,9 +12,8 @@ FILESNAME= LC_NUMERIC LOCALES+= ar_SA.UTF-8 LOCALES+= en_US.UTF-8 LOCALES+= en_ZA.US-ASCII -LOCALES+= fr_CH.ISO8859-15 -LOCALES+= fr_CH.UTF-8 LOCALES+= hi_IN.UTF-8 +LOCALES+= it_CH.ISO8859-15 LOCALES+= it_CH.UTF-8 LOCALES+= ru_RU.CP866 LOCALES+= tr_TR.UTF-8 @@ -48,6 +47,8 @@ SAME+= uk_UA.ISO8859-5 hy_AM.ARMSCII-8 SAME+= uk_UA.ISO8859-5 hu_HU.ISO8859-2 SAME+= uk_UA.ISO8859-5 fr_FR.ISO8859-15 SAME+= uk_UA.ISO8859-5 fr_FR.ISO8859-1 +SAME+= uk_UA.ISO8859-5 fr_CH.ISO8859-15 +SAME+= uk_UA.ISO8859-5 fr_CH.ISO8859-1 SAME+= uk_UA.ISO8859-5 fr_CA.ISO8859-15 SAME+= uk_UA.ISO8859-5 fr_CA.ISO8859-1 SAME+= uk_UA.ISO8859-5 fr_BE.ISO8859-15 @@ -82,6 +83,7 @@ SAME+= uk_UA.UTF-8 kk_KZ.UTF-8 SAME+= uk_UA.UTF-8 hy_AM.UTF-8 SAME+= uk_UA.UTF-8 hu_HU.UTF-8 SAME+= uk_UA.UTF-8 fr_FR.UTF-8 +SAME+= uk_UA.UTF-8 fr_CH.UTF-8 SAME+= uk_UA.UTF-8 fr_CA.UTF-8 SAME+= uk_UA.UTF-8 fr_BE.UTF-8 SAME+= uk_UA.UTF-8 fi_FI.UTF-8 @@ -194,12 +196,10 @@ SAME+= tr_TR.UTF-8 ca_AD.ISO8859-15 SAME+= tr_TR.UTF-8 ca_AD.ISO8859-1 SAME+= tr_TR.UTF-8 ar_MA.UTF-8 SAME+= ru_RU.CP866 be_BY.CP1131 -SAME+= it_CH.UTF-8 it_CH.ISO8859-15 -SAME+= it_CH.UTF-8 it_CH.ISO8859-1 +SAME+= it_CH.ISO8859-15 it_CH.ISO8859-1 +SAME+= it_CH.ISO8859-15 de_CH.ISO8859-15 +SAME+= it_CH.ISO8859-15 de_CH.ISO8859-1 SAME+= it_CH.UTF-8 de_CH.UTF-8 -SAME+= it_CH.UTF-8 de_CH.ISO8859-15 -SAME+= it_CH.UTF-8 de_CH.ISO8859-1 -SAME+= fr_CH.ISO8859-15 fr_CH.ISO8859-1 SAME+= hi_IN.UTF-8 hi_IN.ISCII-DEV SAME+= uk_UA.KOI8-U ru_RU.KOI8-R SAME+= ko_KR.eucKR ko_KR.CP949 # legacy (same charset) diff --git a/share/numericdef/fr_CH.ISO8859-15.src b/share/numericdef/it_CH.ISO8859-15.src similarity index 99% rename from share/numericdef/fr_CH.ISO8859-15.src rename to share/numericdef/it_CH.ISO8859-15.src index 28741bc343b2..bbef3c1cfc7c 100644 --- a/share/numericdef/fr_CH.ISO8859-15.src +++ b/share/numericdef/it_CH.ISO8859-15.src @@ -7,7 +7,7 @@ . # # thousands_sep -  +' # # grouping 3 diff --git a/share/numericdef/it_CH.UTF-8.src b/share/numericdef/it_CH.UTF-8.src index bbef3c1cfc7c..8077d7637397 100644 --- a/share/numericdef/it_CH.UTF-8.src +++ b/share/numericdef/it_CH.UTF-8.src @@ -7,7 +7,7 @@ . # # thousands_sep -' +’ # # grouping 3 diff --git a/share/syscons/scrnmaps/Makefile.depend b/share/syscons/scrnmaps/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/share/syscons/scrnmaps/Makefile.depend +++ b/share/syscons/scrnmaps/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/share/zoneinfo/tests/Makefile.depend b/share/zoneinfo/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/share/zoneinfo/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index a8217f31aabd..b010e3513c77 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -172,7 +172,7 @@ sw1: * to load up the rest of the next context. */ - /* Skip loading user fsbase/gsbase for kthreads */ + /* Skip loading LDT and user fsbase/gsbase for kthreads */ testl $TDP_KTHREAD,TD_PFLAGS(%r12) jnz do_kthread diff --git a/sys/amd64/amd64/efirt.c b/sys/amd64/amd64/efirt_machdep.c similarity index 58% rename from sys/amd64/amd64/efirt.c rename to sys/amd64/amd64/efirt_machdep.c index ea940d771c51..45b29a0d802b 100644 --- a/sys/amd64/amd64/efirt.c +++ b/sys/amd64/amd64/efirt_machdep.c @@ -60,53 +60,11 @@ __FBSDID("$FreeBSD$"); #include #include -static struct efi_systbl *efi_systbl; -static struct efi_cfgtbl *efi_cfgtbl; -static struct efi_rt *efi_runtime; - -static int efi_status2err[25] = { - 0, /* EFI_SUCCESS */ - ENOEXEC, /* EFI_LOAD_ERROR */ - EINVAL, /* EFI_INVALID_PARAMETER */ - ENOSYS, /* EFI_UNSUPPORTED */ - EMSGSIZE, /* EFI_BAD_BUFFER_SIZE */ - EOVERFLOW, /* EFI_BUFFER_TOO_SMALL */ - EBUSY, /* EFI_NOT_READY */ - EIO, /* EFI_DEVICE_ERROR */ - EROFS, /* EFI_WRITE_PROTECTED */ - EAGAIN, /* EFI_OUT_OF_RESOURCES */ - EIO, /* EFI_VOLUME_CORRUPTED */ - ENOSPC, /* EFI_VOLUME_FULL */ - ENXIO, /* EFI_NO_MEDIA */ - ESTALE, /* EFI_MEDIA_CHANGED */ - ENOENT, /* EFI_NOT_FOUND */ - EACCES, /* EFI_ACCESS_DENIED */ - ETIMEDOUT, /* EFI_NO_RESPONSE */ - EADDRNOTAVAIL, /* EFI_NO_MAPPING */ - ETIMEDOUT, /* EFI_TIMEOUT */ - EDOOFUS, /* EFI_NOT_STARTED */ - EALREADY, /* EFI_ALREADY_STARTED */ - ECANCELED, /* EFI_ABORTED */ - EPROTO, /* EFI_ICMP_ERROR */ - EPROTO, /* EFI_TFTP_ERROR */ - EPROTO /* EFI_PROTOCOL_ERROR */ -}; - -static int -efi_status_to_errno(efi_status status) -{ - u_long code; - - code = status & 0x3ffffffffffffffful; - return (code < nitems(efi_status2err) ? efi_status2err[code] : EDOOFUS); -} - -static struct mtx efi_lock; static pml4_entry_t *efi_pml4; static vm_object_t obj_1t1_pt; static vm_page_t efi_pml4_page; -static void +void efi_destroy_1t1_map(void) { vm_page_t m; @@ -185,7 +143,7 @@ efi_1t1_pte(vm_offset_t va) return (pte); } -static bool +bool efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) { struct efi_md *p; @@ -288,22 +246,13 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) * firmware/SMM long operation, which would negatively affect IPIs, * esp. TLB shootdown requests. */ -static int -efi_enter(void) +int +efi_arch_enter(void) { pmap_t curpmap; - int error; - if (efi_runtime == NULL) - return (ENXIO); curpmap = PCPU_GET(curpmap); - PMAP_LOCK(curpmap); - mtx_lock(&efi_lock); - error = fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); - if (error != 0) { - PMAP_UNLOCK(curpmap); - return (error); - } + PMAP_LOCK_ASSERT(curpmap, MA_OWNED); /* * IPI TLB shootdown handler invltlb_pcid_handler() reloads @@ -326,8 +275,8 @@ efi_enter(void) return (0); } -static void -efi_leave(void) +void +efi_arch_leave(void) { pmap_t curpmap; @@ -338,263 +287,8 @@ efi_leave(void) curpmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid : 0)); if (!pmap_pcid_enabled) invltlb(); - - fpu_kern_leave(curthread, NULL); - mtx_unlock(&efi_lock); - PMAP_UNLOCK(curpmap); } -static int -efi_init(void) -{ - struct efi_map_header *efihdr; - struct efi_md *map; - caddr_t kmdp; - size_t efisz; - - mtx_init(&efi_lock, "efi", NULL, MTX_DEF); - - if (efi_systbl_phys == 0) { - if (bootverbose) - printf("EFI systbl not available\n"); - return (0); - } - efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys); - if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { - efi_systbl = NULL; - if (bootverbose) - printf("EFI systbl signature invalid\n"); - return (0); - } - efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL : - (struct efi_cfgtbl *)efi_systbl->st_cfgtbl; - if (efi_cfgtbl == NULL) { - if (bootverbose) - printf("EFI config table is not present\n"); - } - - kmdp = preload_search_by_type("elf kernel"); - if (kmdp == NULL) - kmdp = preload_search_by_type("elf64 kernel"); - efihdr = (struct efi_map_header *)preload_search_info(kmdp, - MODINFO_METADATA | MODINFOMD_EFI_MAP); - if (efihdr == NULL) { - if (bootverbose) - printf("EFI map is not present\n"); - return (0); - } - efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; - map = (struct efi_md *)((uint8_t *)efihdr + efisz); - if (efihdr->descriptor_size == 0) - return (ENOMEM); - - if (!efi_create_1t1_map(map, efihdr->memory_size / - efihdr->descriptor_size, efihdr->descriptor_size)) { - if (bootverbose) - printf("EFI cannot create runtime map\n"); - return (ENOMEM); - } - - efi_runtime = (efi_systbl->st_rt == 0) ? NULL : - (struct efi_rt *)efi_systbl->st_rt; - if (efi_runtime == NULL) { - if (bootverbose) - printf("EFI runtime services table is not present\n"); - efi_destroy_1t1_map(); - return (ENXIO); - } - - return (0); -} - -static void -efi_uninit(void) -{ - - efi_destroy_1t1_map(); - - efi_systbl = NULL; - efi_cfgtbl = NULL; - efi_runtime = NULL; - - mtx_destroy(&efi_lock); -} - -int -efi_rt_ok(void) -{ - - if (efi_runtime == NULL) - return (ENXIO); - return (0); -} - -int -efi_get_table(struct uuid *uuid, void **ptr) -{ - struct efi_cfgtbl *ct; - u_long count; - - if (efi_cfgtbl == NULL || efi_systbl == NULL) - return (ENXIO); - count = efi_systbl->st_entries; - ct = efi_cfgtbl; - while (count--) { - if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { - *ptr = (void *)PHYS_TO_DMAP(ct->ct_data); - return (0); - } - ct++; - } - return (ENOENT); -} - -int -efi_get_time_locked(struct efi_tm *tm) -{ - efi_status status; - int error; - - mtx_assert(&atrtc_time_lock, MA_OWNED); - error = efi_enter(); - if (error != 0) - return (error); - status = efi_runtime->rt_gettime(tm, NULL); - efi_leave(); - error = efi_status_to_errno(status); - return (error); -} - -int -efi_get_time(struct efi_tm *tm) -{ - int error; - - if (efi_runtime == NULL) - return (ENXIO); - mtx_lock(&atrtc_time_lock); - error = efi_get_time_locked(tm); - mtx_unlock(&atrtc_time_lock); - return (error); -} - -int -efi_reset_system(void) -{ - int error; - - error = efi_enter(); - if (error != 0) - return (error); - efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL); - efi_leave(); - return (EIO); -} - -int -efi_set_time_locked(struct efi_tm *tm) -{ - efi_status status; - int error; - - mtx_assert(&atrtc_time_lock, MA_OWNED); - error = efi_enter(); - if (error != 0) - return (error); - status = efi_runtime->rt_settime(tm); - efi_leave(); - error = efi_status_to_errno(status); - return (error); -} - -int -efi_set_time(struct efi_tm *tm) -{ - int error; - - if (efi_runtime == NULL) - return (ENXIO); - mtx_lock(&atrtc_time_lock); - error = efi_set_time_locked(tm); - mtx_unlock(&atrtc_time_lock); - return (error); -} - -int -efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, - size_t *datasize, void *data) -{ - efi_status status; - int error; - - error = efi_enter(); - if (error != 0) - return (error); - status = efi_runtime->rt_getvar(name, vendor, attrib, datasize, data); - efi_leave(); - error = efi_status_to_errno(status); - return (error); -} - -int -efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) -{ - efi_status status; - int error; - - error = efi_enter(); - if (error != 0) - return (error); - status = efi_runtime->rt_scanvar(namesize, name, vendor); - efi_leave(); - error = efi_status_to_errno(status); - return (error); -} - -int -efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, - size_t datasize, void *data) -{ - efi_status status; - int error; - - error = efi_enter(); - if (error != 0) - return (error); - status = efi_runtime->rt_setvar(name, vendor, attrib, datasize, data); - efi_leave(); - error = efi_status_to_errno(status); - return (error); -} - -static int -efirt_modevents(module_t m, int event, void *arg __unused) -{ - - switch (event) { - case MOD_LOAD: - return (efi_init()); - - case MOD_UNLOAD: - efi_uninit(); - return (0); - - case MOD_SHUTDOWN: - return (0); - - default: - return (EOPNOTSUPP); - } -} - -static moduledata_t efirt_moddata = { - .name = "efirt", - .evhand = efirt_modevents, - .priv = NULL, -}; -DECLARE_MODULE(efirt, efirt_moddata, SI_SUB_VM_CONF, SI_ORDER_ANY); -MODULE_VERSION(efirt, 1); - /* XXX debug stuff */ static int efi_time_sysctl_handler(SYSCTL_HANDLER_ARGS) diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 483d3b8677ca..bcae3d2e670b 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -806,6 +806,7 @@ fpusetregs(struct thread *td, struct savefpu *addr, char *xfpustate, struct pcb *pcb; int error; + addr->sv_env.en_mxcsr &= cpu_mxcsr_mask; pcb = td->td_pcb; critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 2ac09802fb5e..78777d814d7e 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -81,7 +81,6 @@ ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_PFLAGS, offsetof(struct thread, td_pflags)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); -ASSYM(TD_TID, offsetof(struct thread, td_tid)); ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 9cfcc6fe2057..ea38a5f6b9fb 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -581,12 +581,9 @@ exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - mtx_lock(&dt_lock); if (td->td_proc->p_md.md_ldt != NULL) user_ldt_free(td); - else - mtx_unlock(&dt_lock); - + update_pcb_bases(pcb); pcb->pcb_fsbase = 0; pcb->pcb_gsbase = 0; @@ -2241,7 +2238,6 @@ static int set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate, size_t xfpustate_len) { - struct savefpu *fpstate; int error; if (mcp->mc_fpformat == _MC_FPFMT_NODEV) @@ -2254,9 +2250,8 @@ set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate, error = 0; } else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || mcp->mc_ownedfp == _MC_FPOWNED_PCB) { - fpstate = (struct savefpu *)&mcp->mc_fpstate; - fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask; - error = fpusetregs(td, fpstate, xfpustate, xfpustate_len); + error = fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate, + xfpustate, xfpustate_len); } else return (EINVAL); return (error); diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c index c5414a18ab67..d1990ba9cf69 100644 --- a/sys/amd64/amd64/minidump_machdep.c +++ b/sys/amd64/amd64/minidump_machdep.c @@ -56,7 +56,6 @@ uint64_t *vm_page_dump; int vm_page_dump_size; static struct kerneldumpheader kdh; -static off_t dumplo; /* Handle chunked writes. */ static size_t fragsz; @@ -93,8 +92,7 @@ blk_flush(struct dumperinfo *di) if (fragsz == 0) return (0); - error = dump_write(di, dump_va, 0, dumplo, fragsz); - dumplo += fragsz; + error = dump_append(di, dump_va, 0, fragsz); fragsz = 0; return (error); } @@ -177,10 +175,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) wdog_kern_pat(WD_LASTVAL); if (ptr) { - error = dump_write(di, ptr, 0, dumplo, len); + error = dump_append(di, ptr, 0, len); if (error) return (error); - dumplo += len; ptr += len; sz -= len; } else { @@ -333,7 +330,7 @@ minidumpsys(struct dumperinfo *di) printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20, ptoa((uintmax_t)physmem) / 1048576); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -419,7 +416,7 @@ minidumpsys(struct dumperinfo *di) if (error) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index f9d1d31394d1..9050c9fcfeec 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -380,8 +380,8 @@ static int pmap_initialized; * elements, but reads are not. */ static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); -static struct mtx pv_chunks_mutex; -static struct rwlock pv_list_locks[NPV_LIST_LOCKS]; +static struct mtx __exclusive_cache_line pv_chunks_mutex; +static struct rwlock __exclusive_cache_line pv_list_locks[NPV_LIST_LOCKS]; static u_long pv_invl_gen[NPV_LIST_LOCKS]; static struct md_page *pv_table; static struct md_page pv_dummy; @@ -535,14 +535,12 @@ pmap_delayed_invl_genp(vm_page_t m) static void pmap_delayed_invl_wait(vm_page_t m) { - struct thread *td; struct turnstile *ts; u_long *m_gen; #ifdef PV_STATS bool accounted = false; #endif - td = curthread; m_gen = pmap_delayed_invl_genp(m); while (*m_gen > pmap_invl_gen) { #ifdef PV_STATS @@ -606,8 +604,10 @@ static void pmap_pv_demote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, struct rwlock **lockp); static bool pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, pd_entry_t pde, u_int flags, struct rwlock **lockp); +#if VM_NRESERVLEVEL > 0 static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, struct rwlock **lockp); +#endif static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); @@ -630,8 +630,10 @@ static void pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static void pmap_pde_attr(pd_entry_t *pde, int cache_bits, int mask); +#if VM_NRESERVLEVEL > 0 static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, struct rwlock **lockp); +#endif static boolean_t pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot); static void pmap_pte_attr(pt_entry_t *pte, int cache_bits, int mask); @@ -2890,11 +2892,11 @@ reclaim_pv_chunk_leave_pmap(pmap_t pmap, pmap_t locked_pmap, bool start_di) static vm_page_t reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) { - struct pch new_tail; - struct pv_chunk *pc; + struct pv_chunk *pc, *pc_marker, *pc_marker_end; + struct pv_chunk_header pc_marker_b, pc_marker_end_b; struct md_page *pvh; pd_entry_t *pde; - pmap_t pmap; + pmap_t next_pmap, pmap; pt_entry_t *pte, tpte; pt_entry_t PG_G, PG_A, PG_M, PG_RW; pv_entry_t pv; @@ -2904,6 +2906,7 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) uint64_t inuse; int bit, field, freed; bool start_di; + static int active_reclaims = 0; PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED); KASSERT(lockp != NULL, ("reclaim_pv_chunk: lockp is NULL")); @@ -2911,7 +2914,10 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) m_pc = NULL; PG_G = PG_A = PG_M = PG_RW = 0; SLIST_INIT(&free); - TAILQ_INIT(&new_tail); + bzero(&pc_marker_b, sizeof(pc_marker_b)); + bzero(&pc_marker_end_b, sizeof(pc_marker_end_b)); + pc_marker = (struct pv_chunk *)&pc_marker_b; + pc_marker_end = (struct pv_chunk *)&pc_marker_end_b; /* * A delayed invalidation block should already be active if @@ -2921,30 +2927,61 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) start_di = pmap_not_in_di(); mtx_lock(&pv_chunks_mutex); - while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && SLIST_EMPTY(&free)) { - TAILQ_REMOVE(&pv_chunks, pc, pc_lru); + active_reclaims++; + TAILQ_INSERT_HEAD(&pv_chunks, pc_marker, pc_lru); + TAILQ_INSERT_TAIL(&pv_chunks, pc_marker_end, pc_lru); + while ((pc = TAILQ_NEXT(pc_marker, pc_lru)) != pc_marker_end && + SLIST_EMPTY(&free)) { + next_pmap = pc->pc_pmap; + if (next_pmap == NULL) { + /* + * The next chunk is a marker. However, it is + * not our marker, so active_reclaims must be + * > 1. Consequently, the next_chunk code + * will not rotate the pv_chunks list. + */ + goto next_chunk; + } mtx_unlock(&pv_chunks_mutex); - if (pmap != pc->pc_pmap) { + + /* + * A pv_chunk can only be removed from the pc_lru list + * when both pc_chunks_mutex is owned and the + * corresponding pmap is locked. + */ + if (pmap != next_pmap) { reclaim_pv_chunk_leave_pmap(pmap, locked_pmap, start_di); - pmap = pc->pc_pmap; + pmap = next_pmap; /* Avoid deadlock and lock recursion. */ if (pmap > locked_pmap) { RELEASE_PV_LIST_LOCK(lockp); PMAP_LOCK(pmap); - } else if (pmap != locked_pmap && - !PMAP_TRYLOCK(pmap)) { - pmap = NULL; - TAILQ_INSERT_TAIL(&new_tail, pc, pc_lru); + if (start_di) + pmap_delayed_invl_started(); mtx_lock(&pv_chunks_mutex); continue; - } + } else if (pmap != locked_pmap) { + if (PMAP_TRYLOCK(pmap)) { + if (start_di) + pmap_delayed_invl_started(); + mtx_lock(&pv_chunks_mutex); + continue; + } else { + pmap = NULL; /* pmap is not locked */ + mtx_lock(&pv_chunks_mutex); + pc = TAILQ_NEXT(pc_marker, pc_lru); + if (pc == NULL || + pc->pc_pmap != next_pmap) + continue; + goto next_chunk; + } + } else if (start_di) + pmap_delayed_invl_started(); PG_G = pmap_global_bit(pmap); PG_A = pmap_accessed_bit(pmap); PG_M = pmap_modified_bit(pmap); PG_RW = pmap_rw_bit(pmap); - if (start_di) - pmap_delayed_invl_started(); } /* @@ -2989,9 +3026,8 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) } } if (freed == 0) { - TAILQ_INSERT_TAIL(&new_tail, pc, pc_lru); mtx_lock(&pv_chunks_mutex); - continue; + goto next_chunk; } /* Every freed mapping is for a 4 KB page. */ pmap_resident_count_dec(pmap, freed); @@ -3008,16 +3044,35 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) m_pc = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc)); dump_drop_page(m_pc->phys_addr); mtx_lock(&pv_chunks_mutex); + TAILQ_REMOVE(&pv_chunks, pc, pc_lru); break; } TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list); - TAILQ_INSERT_TAIL(&new_tail, pc, pc_lru); mtx_lock(&pv_chunks_mutex); /* One freed pv entry in locked_pmap is sufficient. */ if (pmap == locked_pmap) break; +next_chunk: + TAILQ_REMOVE(&pv_chunks, pc_marker, pc_lru); + TAILQ_INSERT_AFTER(&pv_chunks, pc, pc_marker, pc_lru); + if (active_reclaims == 1 && pmap != NULL) { + /* + * Rotate the pv chunks list so that we do not + * scan the same pv chunks that could not be + * freed (because they contained a wired + * and/or superpage mapping) on every + * invocation of reclaim_pv_chunk(). + */ + while ((pc = TAILQ_FIRST(&pv_chunks)) != pc_marker) { + MPASS(pc->pc_pmap != NULL); + TAILQ_REMOVE(&pv_chunks, pc, pc_lru); + TAILQ_INSERT_TAIL(&pv_chunks, pc, pc_lru); + } + } } - TAILQ_CONCAT(&pv_chunks, &new_tail, pc_lru); + TAILQ_REMOVE(&pv_chunks, pc_marker, pc_lru); + TAILQ_REMOVE(&pv_chunks, pc_marker_end, pc_lru); + active_reclaims--; mtx_unlock(&pv_chunks_mutex); reclaim_pv_chunk_leave_pmap(pmap, locked_pmap, start_di); if (m_pc == NULL && !SLIST_EMPTY(&free)) { @@ -3336,6 +3391,7 @@ pmap_pv_demote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, PV_STAT(atomic_subtract_int(&pv_entry_spare, NPTEPG - 1)); } +#if VM_NRESERVLEVEL > 0 /* * After promotion from 512 4KB page mappings to a single 2MB page mapping, * replace the many pv entries for the 4KB page mappings by a single pv entry @@ -3376,6 +3432,7 @@ pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, pmap_pvh_free(&m->md, pmap, va); } while (va < va_last); } +#endif /* VM_NRESERVLEVEL > 0 */ /* * First find and then destroy the pv entry for the specified pmap and virtual @@ -4220,6 +4277,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) PMAP_UNLOCK(pmap); } +#if VM_NRESERVLEVEL > 0 /* * Tries to promote the 512, contiguous 4KB page mappings that are within a * single page table page (PTP) to a single 2MB page mapping. For promotion @@ -4348,6 +4406,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, CTR2(KTR_PMAP, "pmap_promote_pde: success for va %#lx" " in pmap %p", va, pmap); } +#endif /* VM_NRESERVLEVEL > 0 */ /* * Insert the given physical page (p) at @@ -4576,6 +4635,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, unchanged: +#if VM_NRESERVLEVEL > 0 /* * If both the page table page and the reservation are fully * populated, then attempt promotion. @@ -4585,6 +4645,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, (m->flags & PG_FICTITIOUS) == 0 && vm_reserv_level_iffullpop(m) == 0) pmap_promote_pde(pmap, pde, va, &lock); +#endif rv = KERN_SUCCESS; out: @@ -7148,7 +7209,9 @@ pmap_emulate_accessed_dirty(pmap_t pmap, vm_offset_t va, int ftype) { int rv; struct rwlock *lock; +#if VM_NRESERVLEVEL > 0 vm_page_t m, mpte; +#endif pd_entry_t *pde; pt_entry_t *pte, PG_A, PG_M, PG_RW, PG_V; @@ -7203,6 +7266,7 @@ pmap_emulate_accessed_dirty(pmap_t pmap, vm_offset_t va, int ftype) *pte |= PG_A; } +#if VM_NRESERVLEVEL > 0 /* try to promote the mapping */ if (va < VM_MAXUSER_ADDRESS) mpte = PHYS_TO_VM_PAGE(*pde & PG_FRAME); @@ -7220,6 +7284,8 @@ pmap_emulate_accessed_dirty(pmap_t pmap, vm_offset_t va, int ftype) atomic_add_long(&ad_emulation_superpage_promotions, 1); #endif } +#endif + #ifdef INVARIANTS if (ftype == VM_PROT_WRITE) atomic_add_long(&num_dirty_emulations, 1); diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c index ead718cb0190..ae68b39af19a 100644 --- a/sys/amd64/amd64/sys_machdep.c +++ b/sys/amd64/amd64/sys_machdep.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -64,7 +65,7 @@ __FBSDID("$FreeBSD$"); #define MAX_LD 8192 -int max_ldt_segment = 1024; +int max_ldt_segment = 512; SYSCTL_INT(_machdep, OID_AUTO, max_ldt_segment, CTLFLAG_RDTUN, &max_ldt_segment, 0, "Maximum number of allowed LDT segments in the single address space"); @@ -80,11 +81,6 @@ max_ldt_segment_init(void *arg __unused) } SYSINIT(maxldt, SI_SUB_VM_CONF, SI_ORDER_ANY, max_ldt_segment_init, NULL); -#ifdef notyet -#ifdef SMP -static void set_user_ldt_rv(struct vmspace *vmsp); -#endif -#endif static void user_ldt_derefl(struct proc_ldt *pldt); #ifndef _SYS_SYSPROTO_H_ @@ -426,18 +422,14 @@ amd64_get_ioperm(td, uap) * Update the GDT entry pointing to the LDT to point to the LDT of the * current process. */ -void +static void set_user_ldt(struct mdproc *mdp) { - critical_enter(); *PCPU_GET(ldt) = mdp->md_ldt_sd; lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); - critical_exit(); } -#ifdef notyet -#ifdef SMP static void set_user_ldt_rv(struct vmspace *vmsp) { @@ -449,8 +441,6 @@ set_user_ldt_rv(struct vmspace *vmsp) set_user_ldt(&td->td_proc->p_md); } -#endif -#endif struct proc_ldt * user_ldt_alloc(struct proc *p, int force) @@ -492,11 +482,13 @@ user_ldt_alloc(struct proc *p, int force) sizeof(struct user_segment_descriptor)); user_ldt_derefl(pldt); } + critical_enter(); ssdtosyssd(&sldt, &p->p_md.md_ldt_sd); - atomic_store_rel_ptr((volatile uintptr_t *)&mdp->md_ldt, - (uintptr_t)new_ldt); - if (p == curproc) - set_user_ldt(mdp); + atomic_thread_fence_rel(); + mdp->md_ldt = new_ldt; + critical_exit(); + smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, + p->p_vmspace); return (mdp->md_ldt); } @@ -508,16 +500,19 @@ user_ldt_free(struct thread *td) struct mdproc *mdp = &p->p_md; struct proc_ldt *pldt; - mtx_assert(&dt_lock, MA_OWNED); + mtx_lock(&dt_lock); if ((pldt = mdp->md_ldt) == NULL) { mtx_unlock(&dt_lock); return; } + critical_enter(); mdp->md_ldt = NULL; + atomic_thread_fence_rel(); bzero(&mdp->md_ldt_sd, sizeof(mdp->md_ldt_sd)); if (td == curthread) lldt(GSEL(GNULL_SEL, SEL_KPL)); + critical_exit(); user_ldt_deref(pldt); } @@ -548,57 +543,57 @@ user_ldt_deref(struct proc_ldt *pldt) * the OS-specific one. */ int -amd64_get_ldt(td, uap) - struct thread *td; - struct i386_ldt_args *uap; +amd64_get_ldt(struct thread *td, struct i386_ldt_args *uap) { - int error = 0; struct proc_ldt *pldt; - int num; struct user_segment_descriptor *lp; + uint64_t *data; + u_int i, num; + int error; #ifdef DEBUG - printf("amd64_get_ldt: start=%d num=%d descs=%p\n", + printf("amd64_get_ldt: start=%u num=%u descs=%p\n", uap->start, uap->num, (void *)uap->descs); #endif - if ((pldt = td->td_proc->p_md.md_ldt) != NULL) { - lp = &((struct user_segment_descriptor *)(pldt->ldt_base)) - [uap->start]; - num = min(uap->num, max_ldt_segment); - } else - return (EINVAL); - - if ((uap->start > (unsigned int)max_ldt_segment) || - ((unsigned int)num > (unsigned int)max_ldt_segment) || - ((unsigned int)(uap->start + num) > (unsigned int)max_ldt_segment)) - return(EINVAL); - - error = copyout(lp, uap->descs, num * + pldt = td->td_proc->p_md.md_ldt; + if (pldt == NULL || uap->start >= max_ldt_segment || uap->num == 0) { + td->td_retval[0] = 0; + return (0); + } + num = min(uap->num, max_ldt_segment - uap->start); + lp = &((struct user_segment_descriptor *)(pldt->ldt_base))[uap->start]; + data = malloc(num * sizeof(struct user_segment_descriptor), M_TEMP, + M_WAITOK); + mtx_lock(&dt_lock); + for (i = 0; i < num; i++) + data[i] = ((volatile uint64_t *)lp)[i]; + mtx_unlock(&dt_lock); + error = copyout(data, uap->descs, num * sizeof(struct user_segment_descriptor)); - if (!error) + free(data, M_TEMP); + if (error == 0) td->td_retval[0] = num; - - return(error); + return (error); } int -amd64_set_ldt(td, uap, descs) - struct thread *td; - struct i386_ldt_args *uap; - struct user_segment_descriptor *descs; +amd64_set_ldt(struct thread *td, struct i386_ldt_args *uap, + struct user_segment_descriptor *descs) { - int error = 0; - unsigned int largest_ld, i; - struct mdproc *mdp = &td->td_proc->p_md; + struct mdproc *mdp; struct proc_ldt *pldt; struct user_segment_descriptor *dp; struct proc *p; + u_int largest_ld, i; + int error; #ifdef DEBUG - printf("amd64_set_ldt: start=%d num=%d descs=%p\n", + printf("amd64_set_ldt: start=%u num=%u descs=%p\n", uap->start, uap->num, (void *)uap->descs); #endif + mdp = &td->td_proc->p_md; + error = 0; set_pcb_flags(td->td_pcb, PCB_FULL_IRET); p = td->td_proc; @@ -616,10 +611,9 @@ amd64_set_ldt(td, uap, descs) largest_ld = max_ldt_segment; if (largest_ld < uap->start) return (EINVAL); - i = largest_ld - uap->start; mtx_lock(&dt_lock); - bzero(&((struct user_segment_descriptor *)(pldt->ldt_base)) - [uap->start], sizeof(struct user_segment_descriptor) * i); + for (i = uap->start; i < largest_ld; i++) + ((volatile uint64_t *)(pldt->ldt_base))[i] = 0; mtx_unlock(&dt_lock); return (0); } @@ -656,12 +650,7 @@ amd64_set_ldt(td, uap, descs) case SDT_SYSNULL4: case SDT_SYSIGT: case SDT_SYSTGT: - /* I can't think of any reason to allow a user proc - * to create a segment of these types. They are - * for OS use only. - */ return (EACCES); - /*NOTREACHED*/ /* memory segment types */ case SDT_MEMEC: /* memory execute only conforming */ @@ -687,7 +676,6 @@ amd64_set_ldt(td, uap, descs) break; default: return(EINVAL); - /*NOTREACHED*/ } /* Only user (ring-3) descriptors may be present. */ @@ -741,14 +729,18 @@ int amd64_set_ldt_data(struct thread *td, int start, int num, struct user_segment_descriptor *descs) { - struct mdproc *mdp = &td->td_proc->p_md; - struct proc_ldt *pldt = mdp->md_ldt; + struct mdproc *mdp; + struct proc_ldt *pldt; + volatile uint64_t *dst, *src; + int i; mtx_assert(&dt_lock, MA_OWNED); - /* Fill in range */ - bcopy(descs, - &((struct user_segment_descriptor *)(pldt->ldt_base))[start], - num * sizeof(struct user_segment_descriptor)); + mdp = &td->td_proc->p_md; + pldt = mdp->md_ldt; + dst = (volatile uint64_t *)(pldt->ldt_base); + src = (volatile uint64_t *)descs; + for (i = 0; i < num; i++) + dst[start + i] = src[i]; return (0); } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index f71378b36f81..fae37d731b06 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -244,6 +244,10 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) /* Copy the LDT, if necessary. */ mdp1 = &td1->td_proc->p_md; mdp2 = &p2->p_md; + if (mdp1->md_ldt == NULL) { + mdp2->md_ldt = NULL; + return; + } mtx_lock(&dt_lock); if (mdp1->md_ldt != NULL) { if (flags & RFMEM) { @@ -299,11 +303,8 @@ cpu_exit(struct thread *td) /* * If this process has a custom LDT, release it. */ - mtx_lock(&dt_lock); - if (td->td_proc->p_md.md_ldt != 0) + if (td->td_proc->p_md.md_ldt != NULL) user_ldt_free(td); - else - mtx_unlock(&dt_lock); } void @@ -507,6 +508,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, (((uintptr_t)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4; td->td_frame->tf_rip = (uintptr_t)entry; + /* Return address sentinel value to stop stack unwinding. */ + suword32((void *)td->td_frame->tf_rsp, 0); + /* Pass the argument to the entry point. */ suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)), (uint32_t)(uintptr_t)arg); @@ -530,6 +534,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, td->td_frame->tf_gs = _ugssel; td->td_frame->tf_flags = TF_HASSEGS; + /* Return address sentinel value to stop stack unwinding. */ + suword((void *)td->td_frame->tf_rsp, 0); + /* Pass the argument to the entry point. */ td->td_frame->tf_rdi = (register_t)arg; } diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index bf5e209ad3bd..14f2c9d02ac3 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -26,6 +26,7 @@ makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security diff --git a/sys/amd64/conf/GENERIC-NODEBUG b/sys/amd64/conf/GENERIC-NODEBUG index 6d4e4b05206f..1bba3c0b59d2 100644 --- a/sys/amd64/conf/GENERIC-NODEBUG +++ b/sys/amd64/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/amd64/conf/MINIMAL b/sys/amd64/conf/MINIMAL index faa35807f5fc..3a3e9c500bf3 100644 --- a/sys/amd64/conf/MINIMAL +++ b/sys/amd64/conf/MINIMAL @@ -18,11 +18,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index 8161eaf25f0f..13e3877a83bc 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -937,12 +937,9 @@ ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack) { struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - - mtx_lock(&dt_lock); + if (td->td_proc->p_md.md_ldt != NULL) user_ldt_free(td); - else - mtx_unlock(&dt_lock); #ifdef COMPAT_43 setup_lcall_gate(); #endif diff --git a/sys/amd64/include/efi.h b/sys/amd64/include/efi.h index c29a1a4d09a8..eaea8d03276c 100644 --- a/sys/amd64/include/efi.h +++ b/sys/amd64/include/efi.h @@ -46,21 +46,11 @@ #endif #ifdef _KERNEL -struct uuid; -struct efi_tm; +#include -int efi_rt_ok(void); -int efi_get_table(struct uuid *uuid, void **ptr); -int efi_get_time(struct efi_tm *tm); -int efi_get_time_locked(struct efi_tm *tm); -int efi_reset_system(void); -int efi_set_time(struct efi_tm *tm); -int efi_set_time_locked(struct efi_tm *tm); -int efi_var_get(uint16_t *name, struct uuid *vendor, uint32_t *attrib, - size_t *datasize, void *data); -int efi_var_nextname(size_t *namesize, uint16_t *name, struct uuid *vendor); -int efi_var_set(uint16_t *name, struct uuid *vendor, uint32_t attrib, - size_t datasize, void *data); +#define EFI_TIME_LOCK() mtx_lock(&atrtc_time_lock); +#define EFI_TIME_UNLOCK() mtx_unlock(&atrtc_time_lock); +#define EFI_TIME_OWNED() mtx_assert(&atrtc_time_lock, MA_OWNED); #endif #endif /* __AMD64_INCLUDE_EFI_H_ */ diff --git a/sys/amd64/include/param.h b/sys/amd64/include/param.h index 9fc6ca40649e..23fce271e901 100644 --- a/sys/amd64/include/param.h +++ b/sys/amd64/include/param.h @@ -152,4 +152,8 @@ #define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ || ((va) >= VM_MIN_KERNEL_ADDRESS && (va) < VM_MAX_KERNEL_ADDRESS)) +#ifdef SMP +#define SC_TABLESIZE 1024 /* Must be power of 2. */ +#endif + #endif /* !_AMD64_INCLUDE_PARAM_H_ */ diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 36d5c446dbe8..1e4f6bfdc127 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -366,11 +366,18 @@ typedef struct pv_entry { */ #define _NPCM 3 #define _NPCPV 168 -struct pv_chunk { - pmap_t pc_pmap; - TAILQ_ENTRY(pv_chunk) pc_list; - uint64_t pc_map[_NPCM]; /* bitmap; 1 = free */ +#define PV_CHUNK_HEADER \ + pmap_t pc_pmap; \ + TAILQ_ENTRY(pv_chunk) pc_list; \ + uint64_t pc_map[_NPCM]; /* bitmap; 1 = free */ \ TAILQ_ENTRY(pv_chunk) pc_lru; + +struct pv_chunk_header { + PV_CHUNK_HEADER +}; + +struct pv_chunk { + PV_CHUNK_HEADER struct pv_entry pc_pventry[_NPCPV]; }; diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h index 52e24460c5e2..caa6c1cdcc24 100644 --- a/sys/amd64/include/proc.h +++ b/sys/amd64/include/proc.h @@ -88,7 +88,6 @@ struct syscall_args { (char *)&td; \ } while (0) -void set_user_ldt(struct mdproc *); struct proc_ldt *user_ldt_alloc(struct proc *, int); void user_ldt_free(struct thread *); void user_ldt_deref(struct proc_ldt *); diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index b87185f1fe33..7bf09429f0f2 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -453,11 +453,8 @@ linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - mtx_lock(&dt_lock); if (td->td_proc->p_md.md_ldt != NULL) user_ldt_free(td); - else - mtx_unlock(&dt_lock); pcb->pcb_fsbase = 0; pcb->pcb_gsbase = 0; diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 140d7b9e9612..8b0a35ea0bfa 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -804,11 +804,8 @@ exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack) struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - mtx_lock(&dt_lock); if (td->td_proc->p_md.md_ldt != NULL) user_ldt_free(td); - else - mtx_unlock(&dt_lock); critical_enter(); wrmsr(MSR_FSBASE, 0); diff --git a/sys/amd64/vmm/io/iommu.c b/sys/amd64/vmm/io/iommu.c index 75cf1ecceecc..d1772094333a 100644 --- a/sys/amd64/vmm/io/iommu.c +++ b/sys/amd64/vmm/io/iommu.c @@ -174,6 +174,7 @@ iommu_init(void) { int error, bus, slot, func; vm_paddr_t maxaddr; + devclass_t dc; device_t dev; if (!iommu_enable) @@ -214,6 +215,7 @@ iommu_init(void) add_tag = EVENTHANDLER_REGISTER(pci_add_device, iommu_pci_add, NULL, 0); delete_tag = EVENTHANDLER_REGISTER(pci_delete_device, iommu_pci_delete, NULL, 0); + dc = devclass_find("ppt"); for (bus = 0; bus <= PCI_BUSMAX; bus++) { for (slot = 0; slot <= PCI_SLOTMAX; slot++) { for (func = 0; func <= PCI_FUNCMAX; func++) { @@ -221,7 +223,15 @@ iommu_init(void) if (dev == NULL) continue; - /* Everything belongs to the host domain. */ + /* Skip passthrough devices. */ + if (dc != NULL && + device_get_devclass(dev) == dc) + continue; + + /* + * Everything else belongs to the host + * domain. + */ iommu_add_device(host_domain, pci_get_rid(dev)); } diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c index 4c9ff474580f..b306508e18ad 100644 --- a/sys/amd64/vmm/io/ppt.c +++ b/sys/amd64/vmm/io/ppt.c @@ -154,6 +154,7 @@ ppt_attach(device_t dev) ppt = device_get_softc(dev); + iommu_remove_device(iommu_host_domain(), pci_get_rid(dev)); num_pptdevs++; TAILQ_INSERT_TAIL(&pptdev_list, ppt, next); ppt->dev = dev; @@ -175,6 +176,8 @@ ppt_detach(device_t dev) return (EBUSY); num_pptdevs--; TAILQ_REMOVE(&pptdev_list, ppt, next); + pci_disable_busmaster(dev); + iommu_add_device(iommu_host_domain(), pci_get_rid(dev)); return (0); } @@ -368,7 +371,6 @@ ppt_assign_device(struct vm *vm, int bus, int slot, int func) true); pci_restore_state(ppt->dev); ppt->vm = vm; - iommu_remove_device(iommu_host_domain(), pci_get_rid(ppt->dev)); iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev)); return (0); } @@ -397,7 +399,6 @@ ppt_unassign_device(struct vm *vm, int bus, int slot, int func) ppt_teardown_msi(ppt); ppt_teardown_msix(ppt); iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev)); - iommu_add_device(iommu_host_domain(), pci_get_rid(ppt->dev)); ppt->vm = NULL; return (0); } diff --git a/sys/amd64/vmm/io/vhpet.c b/sys/amd64/vmm/io/vhpet.c index 6d9b0fe0a087..b11095f72c4a 100644 --- a/sys/amd64/vmm/io/vhpet.c +++ b/sys/amd64/vmm/io/vhpet.c @@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_VHPET, "vhpet", "bhyve virtual hpet"); -#define HPET_FREQ 10000000 /* 10.0 Mhz */ +#define HPET_FREQ 16777216 /* 16.7 (2^24) Mhz */ #define FS_PER_S 1000000000000000ul /* Timer N Configuration and Capabilities Register */ diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c index 852f1d7393bf..64a0b35d3b44 100644 --- a/sys/amd64/vmm/vmm_instruction_emul.c +++ b/sys/amd64/vmm/vmm_instruction_emul.c @@ -109,6 +109,10 @@ static const struct vie_op one_byte_opcodes[256] = { .op_byte = 0x0F, .op_type = VIE_OP_TYPE_TWO_BYTE }, + [0x0B] = { + .op_byte = 0x0B, + .op_type = VIE_OP_TYPE_OR, + }, [0x2B] = { .op_byte = 0x2B, .op_type = VIE_OP_TYPE_SUB, @@ -992,12 +996,38 @@ emulate_or(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, mem_region_read_t memread, mem_region_write_t memwrite, void *arg) { int error, size; - uint64_t val1, result, rflags, rflags2; + enum vm_reg_name reg; + uint64_t result, rflags, rflags2, val1, val2; size = vie->opsize; error = EINVAL; switch (vie->op.op_byte) { + case 0x0B: + /* + * OR reg (ModRM:reg) and mem (ModRM:r/m) and store the + * result in reg. + * + * 0b/r or r16, r/m16 + * 0b/r or r32, r/m32 + * REX.W + 0b/r or r64, r/m64 + */ + + /* get the first operand */ + reg = gpr_map[vie->reg]; + error = vie_read_register(vm, vcpuid, reg, &val1); + if (error) + break; + + /* get the second operand */ + error = memread(vm, vcpuid, gpa, &val2, size, arg); + if (error) + break; + + /* perform the operation and write the result */ + result = val1 | val2; + error = vie_update_register(vm, vcpuid, reg, result, size); + break; case 0x81: case 0x83: /* diff --git a/sys/arm/allwinner/a10_ahci.c b/sys/arm/allwinner/a10_ahci.c index 887c1658c0ed..7762e7acfda3 100644 --- a/sys/arm/allwinner/a10_ahci.c +++ b/sys/arm/allwinner/a10_ahci.c @@ -373,8 +373,6 @@ ahci_a10_detach(device_t dev) return (ahci_detach(dev)); } -static devclass_t ahci_devclass; - static device_method_t ahci_ata_methods[] = { DEVMETHOD(device_probe, ahci_a10_probe), DEVMETHOD(device_attach, ahci_a10_attach), diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c index 01c2af65b756..64da9b5fe516 100644 --- a/sys/arm/allwinner/a10_ehci.c +++ b/sys/arm/allwinner/a10_ehci.c @@ -65,17 +65,10 @@ __FBSDID("$FreeBSD$"); #define EHCI_HC_DEVSTR "Allwinner Integrated USB 2.0 controller" -#define SW_USB_PMU_IRQ_ENABLE 0x800 - #define SW_SDRAM_REG_HPCR_USB1 (0x250 + ((1 << 2) * 4)) #define SW_SDRAM_REG_HPCR_USB2 (0x250 + ((1 << 2) * 5)) #define SW_SDRAM_BP_HPCR_ACCESS (1 << 0) -#define SW_ULPI_BYPASS (1 << 0) -#define SW_AHB_INCRX_ALIGN (1 << 8) -#define SW_AHB_INCR4 (1 << 9) -#define SW_AHB_INCR8 (1 << 10) - #define USB_CONF(d) \ (void *)ofw_bus_search_compatible((d), compat_data)->ocd_data @@ -88,11 +81,21 @@ __FBSDID("$FreeBSD$"); static device_attach_t a10_ehci_attach; static device_detach_t a10_ehci_detach; +struct clk_list { + TAILQ_ENTRY(clk_list) next; + clk_t clk; +}; + +struct hwrst_list { + TAILQ_ENTRY(hwrst_list) next; + hwreset_t rst; +}; + struct aw_ehci_softc { ehci_softc_t sc; - clk_t clk; - hwreset_t rst; - phy_t phy; + TAILQ_HEAD(, clk_list) clk_list; + TAILQ_HEAD(, hwrst_list) rst_list; + phy_t phy; }; struct aw_ehci_conf { @@ -114,6 +117,7 @@ static struct ofw_compat_data compat_data[] = { { "allwinner,sun7i-a20-ehci", (uintptr_t)&a10_ehci_conf }, { "allwinner,sun8i-a83t-ehci", (uintptr_t)&a31_ehci_conf }, { "allwinner,sun8i-h3-ehci", (uintptr_t)&a31_ehci_conf }, + { "allwinner,sun50i-a64-ehci", (uintptr_t)&a31_ehci_conf }, { NULL, (uintptr_t)NULL } }; @@ -139,8 +143,11 @@ a10_ehci_attach(device_t self) ehci_softc_t *sc = &aw_sc->sc; const struct aw_ehci_conf *conf; bus_space_handle_t bsh; - int err; - int rid; + int err, rid, off; + struct clk_list *clkp; + clk_t clk; + struct hwrst_list *rstp; + hwreset_t rst; uint32_t reg_value = 0; conf = USB_CONF(self); @@ -204,25 +211,31 @@ a10_ehci_attach(device_t self) sc->sc_flags |= EHCI_SCFLG_DONTRESET; + /* Enable clock for USB */ + TAILQ_INIT(&aw_sc->clk_list); + for (off = 0; clk_get_by_ofw_index(self, 0, off, &clk) == 0; off++) { + err = clk_enable(clk); + if (err != 0) { + device_printf(self, "Could not enable clock %s\n", + clk_get_name(clk)); + goto error; + } + clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); + clkp->clk = clk; + TAILQ_INSERT_TAIL(&aw_sc->clk_list, clkp, next); + } + /* De-assert reset */ - if (hwreset_get_by_ofw_idx(self, 0, 0, &aw_sc->rst) == 0) { - err = hwreset_deassert(aw_sc->rst); + TAILQ_INIT(&aw_sc->rst_list); + for (off = 0; hwreset_get_by_ofw_idx(self, 0, off, &rst) == 0; off++) { + err = hwreset_deassert(rst); if (err != 0) { device_printf(self, "Could not de-assert reset\n"); goto error; } - } - - /* Enable clock for USB */ - err = clk_get_by_ofw_index(self, 0, 0, &aw_sc->clk); - if (err != 0) { - device_printf(self, "Could not get clock\n"); - goto error; - } - err = clk_enable(aw_sc->clk); - if (err != 0) { - device_printf(self, "Could not enable clock\n"); - goto error; + rstp = malloc(sizeof(*rstp), M_DEVBUF, M_WAITOK | M_ZERO); + rstp->rst = rst; + TAILQ_INSERT_TAIL(&aw_sc->rst_list, rstp, next); } /* Enable USB PHY */ @@ -234,14 +247,6 @@ a10_ehci_attach(device_t self) } } - /* Enable passby */ - reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE); - reg_value |= SW_AHB_INCR8; /* AHB INCR8 enable */ - reg_value |= SW_AHB_INCR4; /* AHB burst type INCR4 enable */ - reg_value |= SW_AHB_INCRX_ALIGN; /* AHB INCRX align enable */ - reg_value |= SW_ULPI_BYPASS; /* ULPI bypass enable */ - A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value); - /* Configure port */ if (conf->sdram_init) { reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2); @@ -272,6 +277,8 @@ a10_ehci_detach(device_t self) const struct aw_ehci_conf *conf; int err; uint32_t reg_value = 0; + struct clk_list *clk, *clk_tmp; + struct hwrst_list *rst, *rst_tmp; conf = USB_CONF(self); @@ -311,24 +318,26 @@ a10_ehci_detach(device_t self) A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value); } - /* Disable passby */ - reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE); - reg_value &= ~SW_AHB_INCR8; /* AHB INCR8 disable */ - reg_value &= ~SW_AHB_INCR4; /* AHB burst type INCR4 disable */ - reg_value &= ~SW_AHB_INCRX_ALIGN; /* AHB INCRX align disable */ - reg_value &= ~SW_ULPI_BYPASS; /* ULPI bypass disable */ - A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value); - - /* Disable clock for USB */ - if (aw_sc->clk != NULL) { - clk_disable(aw_sc->clk); - clk_release(aw_sc->clk); + /* Disable clock */ + TAILQ_FOREACH_SAFE(clk, &aw_sc->clk_list, next, clk_tmp) { + err = clk_disable(clk->clk); + if (err != 0) + device_printf(self, "Could not disable clock %s\n", + clk_get_name(clk->clk)); + err = clk_release(clk->clk); + if (err != 0) + device_printf(self, "Could not release clock %s\n", + clk_get_name(clk->clk)); + TAILQ_REMOVE(&aw_sc->clk_list, clk, next); + free(clk, M_DEVBUF); } /* Assert reset */ - if (aw_sc->rst != NULL) { - hwreset_assert(aw_sc->rst); - hwreset_release(aw_sc->rst); + TAILQ_FOREACH_SAFE(rst, &aw_sc->rst_list, next, rst_tmp) { + hwreset_assert(rst->rst); + hwreset_release(rst->rst); + TAILQ_REMOVE(&aw_sc->rst_list, rst, next); + free(rst, M_DEVBUF); } return (0); diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c index 8b75e6ddb575..da1460e93212 100644 --- a/sys/arm/allwinner/a10_gpio.c +++ b/sys/arm/allwinner/a10_gpio.c @@ -165,6 +165,11 @@ static struct ofw_compat_data compat_data[] = { {NULL, 0} }; +struct clk_list { + TAILQ_ENTRY(clk_list) next; + clk_t clk; +}; + struct a10_gpio_softc { device_t sc_dev; device_t sc_busdev; @@ -175,6 +180,7 @@ struct a10_gpio_softc { bus_space_handle_t sc_bsh; void * sc_intrhand; const struct allwinner_padconf * padconf; + TAILQ_HEAD(, clk_list) clk_list; }; #define A10_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) @@ -197,6 +203,8 @@ struct a10_gpio_softc { static int a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value); static int a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); +static int a10_gpio_pin_get_locked(struct a10_gpio_softc *sc, uint32_t pin, unsigned int *value); +static int a10_gpio_pin_set_locked(struct a10_gpio_softc *sc, uint32_t pin, unsigned int value); #define A10_GPIO_WRITE(_sc, _off, _val) \ bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) @@ -333,15 +341,15 @@ a10_gpio_pin_configure(struct a10_gpio_softc *sc, uint32_t pin, uint32_t flags) err = a10_gpio_set_function(sc, pin, A10_GPIO_INPUT); } else if (flags & GPIO_PIN_OUTPUT) { if (flags & GPIO_PIN_PRESET_LOW) { - a10_gpio_pin_set(sc->sc_dev, pin, 0); + a10_gpio_pin_set_locked(sc, pin, 0); } else if (flags & GPIO_PIN_PRESET_HIGH) { - a10_gpio_pin_set(sc->sc_dev, pin, 1); + a10_gpio_pin_set_locked(sc, pin, 1); } else { /* Read the pin and preset output to current state. */ err = a10_gpio_set_function(sc, pin, A10_GPIO_INPUT); if (err == 0) { - a10_gpio_pin_get(sc->sc_dev, pin, &val); - a10_gpio_pin_set(sc->sc_dev, pin, val); + a10_gpio_pin_get_locked(sc, pin, &val); + a10_gpio_pin_set_locked(sc, pin, val); } } if (err == 0) @@ -473,27 +481,61 @@ a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) } static int -a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) +a10_gpio_pin_set_locked(struct a10_gpio_softc *sc, uint32_t pin, + unsigned int value) { - struct a10_gpio_softc *sc; uint32_t bank, data; - sc = device_get_softc(dev); + A10_GPIO_LOCK_ASSERT(sc); + if (pin > sc->padconf->npins) return (EINVAL); bank = sc->padconf->pins[pin].port; pin = sc->padconf->pins[pin].pin; - A10_GPIO_LOCK(sc); data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); if (value) data |= (1 << pin); else data &= ~(1 << pin); A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data); + + return (0); +} + +static int +a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) +{ + struct a10_gpio_softc *sc; + int ret; + + sc = device_get_softc(dev); + + A10_GPIO_LOCK(sc); + ret = a10_gpio_pin_set_locked(sc, pin, value); A10_GPIO_UNLOCK(sc); + return (ret); +} + +static int +a10_gpio_pin_get_locked(struct a10_gpio_softc *sc,uint32_t pin, + unsigned int *val) +{ + uint32_t bank, reg_data; + + A10_GPIO_LOCK_ASSERT(sc); + + if (pin > sc->padconf->npins) + return (EINVAL); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + + reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); + *val = (reg_data & (1 << pin)) ? 1 : 0; + return (0); } @@ -501,21 +543,15 @@ static int a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct a10_gpio_softc *sc; - uint32_t bank, reg_data; + int ret; sc = device_get_softc(dev); - if (pin > sc->padconf->npins) - return (EINVAL); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; A10_GPIO_LOCK(sc); - reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); + ret = a10_gpio_pin_get_locked(sc, pin, val); A10_GPIO_UNLOCK(sc); - *val = (reg_data & (1 << pin)) ? 1 : 0; - return (0); + return (ret); } static int @@ -736,8 +772,10 @@ a10_gpio_attach(device_t dev) int rid, error; phandle_t gpio; struct a10_gpio_softc *sc; + struct clk_list *clkp, *clkp_tmp; clk_t clk; - hwreset_t rst; + hwreset_t rst = NULL; + int off, err, clkret; sc = device_get_softc(dev); sc->sc_dev = dev; @@ -777,16 +815,29 @@ a10_gpio_attach(device_t dev) error = hwreset_deassert(rst); if (error != 0) { device_printf(dev, "cannot de-assert reset\n"); - return (error); + goto fail; } } - if (clk_get_by_ofw_index(dev, 0, 0, &clk) == 0) { - error = clk_enable(clk); - if (error != 0) { - device_printf(dev, "could not enable clock\n"); - return (error); + TAILQ_INIT(&sc->clk_list); + for (off = 0, clkret = 0; clkret == 0; off++) { + clkret = clk_get_by_ofw_index(dev, 0, off, &clk); + if (clkret != 0) + break; + err = clk_enable(clk); + if (err != 0) { + device_printf(dev, "Could not enable clock %s\n", + clk_get_name(clk)); + goto fail; } + clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); + clkp->clk = clk; + TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); + } + if (clkret != 0 && clkret != ENOENT) { + device_printf(dev, "Could not find clock at offset %d (%d)\n", + off, clkret); + goto fail; } sc->sc_busdev = gpiobus_attach_bus(dev); @@ -810,6 +861,26 @@ a10_gpio_attach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); mtx_destroy(&sc->sc_mtx); + /* Disable clock */ + TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) { + err = clk_disable(clkp->clk); + if (err != 0) + device_printf(dev, "Could not disable clock %s\n", + clk_get_name(clkp->clk)); + err = clk_release(clkp->clk); + if (err != 0) + device_printf(dev, "Could not release clock %s\n", + clk_get_name(clkp->clk)); + TAILQ_REMOVE(&sc->clk_list, clkp, next); + free(clkp, M_DEVBUF); + } + + /* Assert resets */ + if (rst) { + hwreset_assert(rst); + hwreset_release(rst); + } + return (ENXIO); } diff --git a/sys/arm/allwinner/aw_machdep.c b/sys/arm/allwinner/aw_machdep.c index 45a62d9af7e0..1acac3809a65 100644 --- a/sys/arm/allwinner/aw_machdep.c +++ b/sys/arm/allwinner/aw_machdep.c @@ -164,6 +164,30 @@ allwinner_cpu_reset(platform_t plat) while (1); } +/* + * To use early printf on Allwinner SoC, add to kernel config + * options SOCDEV_PA=0x01C00000 + * options SOCDEV_VA=0x10000000 + * options EARLY_PRINTF + * And remove the if 0 +*/ +#if 0 +#ifdef EARLY_PRINTF +static void +allwinner_early_putc(int c) +{ + volatile uint32_t * UART_STAT_REG = (uint32_t *)0x1002807C; + volatile uint32_t * UART_TX_REG = (uint32_t *)0x10028000; + const uint32_t UART_TXRDY = (1 << 2); + + while ((*UART_STAT_REG & UART_TXRDY) == 0) + continue; + *UART_TX_REG = c; +} +early_putc_t *early_putc = allwinner_early_putc; +#endif /* EARLY_PRINTF */ +#endif + #if defined(SOC_ALLWINNER_A10) static platform_method_t a10_methods[] = { PLATFORMMETHOD(platform_attach, a10_attach), diff --git a/sys/arm/allwinner/aw_usbphy.c b/sys/arm/allwinner/aw_usbphy.c index 0c99728d4c81..db13f88197e8 100644 --- a/sys/arm/allwinner/aw_usbphy.c +++ b/sys/arm/allwinner/aw_usbphy.c @@ -53,52 +53,89 @@ __FBSDID("$FreeBSD$"); #include "phy_if.h" -#define USBPHY_NPHYS 4 -#define USBPHY_NRES USBPHY_NPHYS - enum awusbphy_type { AWUSBPHY_TYPE_A10 = 1, AWUSBPHY_TYPE_A13, AWUSBPHY_TYPE_A20, AWUSBPHY_TYPE_A31, - AWUSBPHY_TYPE_A83T, AWUSBPHY_TYPE_H3, AWUSBPHY_TYPE_A64 }; +struct aw_usbphy_conf { + int num_phys; + enum awusbphy_type phy_type; + bool pmu_unk1; + bool phy0_route; +}; + +static const struct aw_usbphy_conf a10_usbphy_conf = { + .num_phys = 3, + .phy_type = AWUSBPHY_TYPE_A10, + .pmu_unk1 = false, + .phy0_route = false, +}; + +static const struct aw_usbphy_conf a13_usbphy_conf = { + .num_phys = 2, + .phy_type = AWUSBPHY_TYPE_A13, + .pmu_unk1 = false, + .phy0_route = false, +}; + +static const struct aw_usbphy_conf a20_usbphy_conf = { + .num_phys = 3, + .phy_type = AWUSBPHY_TYPE_A20, + .pmu_unk1 = false, + .phy0_route = false, +}; + +static const struct aw_usbphy_conf a31_usbphy_conf = { + .num_phys = 3, + .phy_type = AWUSBPHY_TYPE_A31, + .pmu_unk1 = false, + .phy0_route = false, +}; + +static const struct aw_usbphy_conf h3_usbphy_conf = { + .num_phys = 4, + .phy_type = AWUSBPHY_TYPE_H3, + .pmu_unk1 = true, + .phy0_route = false, +}; + +static const struct aw_usbphy_conf a64_usbphy_conf = { + .num_phys = 2, + .phy_type = AWUSBPHY_TYPE_A64, + .pmu_unk1 = true, + .phy0_route = true, +}; + static struct ofw_compat_data compat_data[] = { - { "allwinner,sun4i-a10-usb-phy", AWUSBPHY_TYPE_A10 }, - { "allwinner,sun5i-a13-usb-phy", AWUSBPHY_TYPE_A13 }, - { "allwinner,sun6i-a31-usb-phy", AWUSBPHY_TYPE_A31 }, - { "allwinner,sun7i-a20-usb-phy", AWUSBPHY_TYPE_A20 }, - { "allwinner,sun8i-a83t-usb-phy", AWUSBPHY_TYPE_A83T }, - { "allwinner,sun8i-h3-usb-phy", AWUSBPHY_TYPE_H3 }, - { "allwinner,sun50i-a64-usb-phy", AWUSBPHY_TYPE_A64 }, + { "allwinner,sun4i-a10-usb-phy", (uintptr_t)&a10_usbphy_conf }, + { "allwinner,sun5i-a13-usb-phy", (uintptr_t)&a13_usbphy_conf }, + { "allwinner,sun6i-a31-usb-phy", (uintptr_t)&a31_usbphy_conf }, + { "allwinner,sun7i-a20-usb-phy", (uintptr_t)&a20_usbphy_conf }, + { "allwinner,sun8i-h3-usb-phy", (uintptr_t)&h3_usbphy_conf }, + { "allwinner,sun50i-a64-usb-phy", (uintptr_t)&a64_usbphy_conf }, { NULL, 0 } }; struct awusbphy_softc { - struct resource * res[USBPHY_NRES]; - regulator_t reg[USBPHY_NPHYS]; + struct resource * phy_ctrl; + struct resource ** pmu; + regulator_t * reg; gpio_pin_t id_det_pin; int id_det_valid; gpio_pin_t vbus_det_pin; int vbus_det_valid; - enum awusbphy_type phy_type; + struct aw_usbphy_conf *phy_conf; }; -static struct resource_spec awusbphy_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_MEMORY, 1, RF_ACTIVE }, - { SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL }, - { SYS_RES_MEMORY, 3, RF_ACTIVE | RF_OPTIONAL }, - { -1, 0 } -}; - -#define RD4(sc, i, o) bus_read_4((sc)->res[(i)], (o)) -#define WR4(sc, i, o, v) bus_write_4((sc)->res[(i)], (o), (v)) -#define CLR4(sc, i, o, m) WR4(sc, i, o, RD4(sc, i, o) & ~(m)) -#define SET4(sc, i, o, m) WR4(sc, i, o, RD4(sc, i, o) | (m)) +#define RD4(res, o) bus_read_4(res, (o)) +#define WR4(res, o, v) bus_write_4(res, (o), (v)) +#define CLR4(res, o, m) WR4(res, o, RD4(res, o) & ~(m)) +#define SET4(res, o, m) WR4(res, o, RD4(res, o) | (m)) #define OTG_PHY_CFG 0x20 #define OTG_PHY_ROUTE_OTG (1 << 0) @@ -117,24 +154,14 @@ awusbphy_configure(device_t dev, int phyno) sc = device_get_softc(dev); - if (sc->res[phyno] == NULL) + if (sc->pmu[phyno] == NULL) return; - if (sc->phy_type == AWUSBPHY_TYPE_A64) { - CLR4(sc, phyno, PMU_UNK_H3, PMU_UNK_H3_CLR); + if (sc->phy_conf->pmu_unk1 == true) + CLR4(sc->pmu[phyno], PMU_UNK_H3, PMU_UNK_H3_CLR); - /* EHCI0 and OTG share a PHY */ - if (phyno == 0) - SET4(sc, 0, OTG_PHY_CFG, OTG_PHY_ROUTE_OTG); - else if (phyno == 1) - CLR4(sc, 0, OTG_PHY_CFG, OTG_PHY_ROUTE_OTG); - } - - if (phyno > 0) { - /* Enable passby */ - SET4(sc, phyno, PMU_IRQ_ENABLE, PMU_ULPI_BYPASS | - PMU_AHB_INCR8 | PMU_AHB_INCR4 | PMU_AHB_INCRX_ALIGN); - } + SET4(sc->pmu[phyno], PMU_IRQ_ENABLE, PMU_ULPI_BYPASS | + PMU_AHB_INCR8 | PMU_AHB_INCR4 | PMU_AHB_INCRX_ALIGN); } static int @@ -143,7 +170,7 @@ awusbphy_init(device_t dev) struct awusbphy_softc *sc; phandle_t node; char pname[20]; - int error, off; + int error, off, rid; regulator_t reg; hwreset_t rst; clk_t clk; @@ -151,7 +178,19 @@ awusbphy_init(device_t dev) sc = device_get_softc(dev); node = ofw_bus_get_node(dev); - sc->phy_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + sc->phy_conf = (struct aw_usbphy_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; + + /* Get phy_ctrl region */ + if (ofw_bus_find_string_index(node, "reg-names", "phy_ctrl", &rid) != 0) { + device_printf(dev, "Cannot locate phy control resource\n"); + return (ENXIO); + } + sc->phy_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->phy_ctrl == NULL) { + device_printf(dev, "Cannot allocate resource\n"); + return (ENXIO); + } /* Enable clocks */ for (off = 0; clk_get_by_ofw_index(dev, 0, off, &clk) == 0; off++) { @@ -173,13 +212,6 @@ awusbphy_init(device_t dev) } } - /* Get regulators */ - for (off = 0; off < USBPHY_NPHYS; off++) { - snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off); - if (regulator_get_by_ofw_property(dev, 0, pname, ®) == 0) - sc->reg[off] = reg; - } - /* Get GPIOs */ error = gpio_pin_get_by_ofw_property(dev, node, "usb0_id_det-gpios", &sc->id_det_pin); @@ -190,9 +222,28 @@ awusbphy_init(device_t dev) if (error == 0) sc->vbus_det_valid = 1; - /* Allocate resources */ - if (bus_alloc_resources(dev, awusbphy_spec, sc->res) != 0) - device_printf(dev, "couldn't allocate resources\n"); + sc->reg = malloc(sizeof(*(sc->reg)) * sc->phy_conf->num_phys, M_DEVBUF, + M_WAITOK | M_ZERO); + sc->pmu = malloc(sizeof(*(sc->pmu)) * sc->phy_conf->num_phys, M_DEVBUF, + M_WAITOK | M_ZERO); + /* Get regulators */ + for (off = 0; off < sc->phy_conf->num_phys; off++) { + snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off); + if (regulator_get_by_ofw_property(dev, 0, pname, ®) == 0) + sc->reg[off] = reg; + + snprintf(pname, sizeof(pname), "pmu%d", off); + if (ofw_bus_find_string_index(node, "reg-names", + pname, &rid) != 0) + continue; + + sc->pmu[off] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->pmu[off] == NULL) { + device_printf(dev, "Cannot allocate resource\n"); + return (ENXIO); + } + } return (0); } @@ -208,8 +259,11 @@ awusbphy_vbus_detect(device_t dev, int *val) if (sc->vbus_det_valid) { error = gpio_pin_is_active(sc->vbus_det_pin, &active); - if (error != 0) + if (error != 0) { + device_printf(dev, "Cannot get status of id pin %d\n", + error); return (error); + } *val = active; return (0); } @@ -225,11 +279,11 @@ awusbphy_phy_enable(device_t dev, intptr_t phy, bool enable) regulator_t reg; int error, vbus_det; - if (phy < 0 || phy >= USBPHY_NPHYS) - return (ERANGE); - sc = device_get_softc(dev); + if (phy < 0 || phy >= sc->phy_conf->num_phys) + return (ERANGE); + /* Configure PHY */ awusbphy_configure(dev, phy); @@ -242,7 +296,21 @@ awusbphy_phy_enable(device_t dev, intptr_t phy, bool enable) /* If an external vbus is detected, do not enable phy 0 */ if (phy == 0) { error = awusbphy_vbus_detect(dev, &vbus_det); - if (error == 0 && vbus_det == 1) + if (error) + goto out; + + /* Depending on the PHY we need to route OTG to OHCI/EHCI */ + if (sc->phy_conf->phy0_route == true) { + if (vbus_det == 0) + /* Host mode */ + CLR4(sc->phy_ctrl, OTG_PHY_CFG, + OTG_PHY_ROUTE_OTG); + else + /* Peripheral mode */ + SET4(sc->phy_ctrl, OTG_PHY_CFG, + OTG_PHY_ROUTE_OTG); + } + if (vbus_det == 1) return (0); } else error = 0; @@ -250,6 +318,8 @@ awusbphy_phy_enable(device_t dev, intptr_t phy, bool enable) error = regulator_enable(reg); } else error = regulator_disable(reg); + +out: if (error != 0) { device_printf(dev, "couldn't %s regulator for phy %jd\n", diff --git a/sys/arm/allwinner/clkng/aw_ccung.c b/sys/arm/allwinner/clkng/aw_ccung.c index 5c7ec0a279a0..732e4d4b3121 100644 --- a/sys/arm/allwinner/clkng/aw_ccung.c +++ b/sys/arm/allwinner/clkng/aw_ccung.c @@ -64,10 +64,12 @@ __FBSDID("$FreeBSD$"); #if defined(SOC_ALLWINNER_A64) #include +#include #endif #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) #include +#include #endif #include "clkdev_if.h" @@ -79,26 +81,30 @@ static struct resource_spec aw_ccung_spec[] = { }; #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) -#define H3_CCU 1 +#define H3_CCU 1 +#define H3_R_CCU 2 #endif #if defined(SOC_ALLWINNER_A31) -#define A31_CCU 2 +#define A31_CCU 3 #endif #if defined(SOC_ALLWINNER_A64) -#define A64_CCU 2 +#define A64_CCU 4 +#define A64_R_CCU 5 #endif static struct ofw_compat_data compat_data[] = { #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) { "allwinner,sun8i-h3-ccu", H3_CCU }, + { "allwinner,sun8i-h3-r-ccu", H3_R_CCU }, #endif #if defined(SOC_ALLWINNER_A31) { "allwinner,sun6i-a31-ccu", A31_CCU }, #endif #if defined(SOC_ALLWINNER_A64) { "allwinner,sun50i-a64-ccu", A64_CCU }, + { "allwinner,sun50i-a64-r-ccu", A64_R_CCU }, #endif {NULL, 0 } }; @@ -320,6 +326,9 @@ aw_ccung_attach(device_t dev) case H3_CCU: ccu_h3_register_clocks(sc); break; + case H3_R_CCU: + ccu_sun8i_r_register_clocks(sc); + break; #endif #if defined(SOC_ALLWINNER_A31) case A31_CCU: @@ -330,6 +339,9 @@ aw_ccung_attach(device_t dev) case A64_CCU: ccu_a64_register_clocks(sc); break; + case A64_R_CCU: + ccu_sun8i_r_register_clocks(sc); + break; #endif } diff --git a/sys/arm/allwinner/clkng/ccu_a31.c b/sys/arm/allwinner/clkng/ccu_a31.c index 0f0476950449..5fdc28c82b96 100644 --- a/sys/arm/allwinner/clkng/ccu_a31.c +++ b/sys/arm/allwinner/clkng/ccu_a31.c @@ -43,169 +43,204 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + #include "ccu_a31.h" +/* Non-exported clocks */ +#define CLK_PLL_CPU 0 +#define CLK_PLL_AUDIO_BASE 1 +#define CLK_PLL_AUDIO 2 +#define CLK_PLL_AUDIO_2X 3 +#define CLK_PLL_AUDIO_4X 4 +#define CLK_PLL_AUDIO_8X 5 +#define CLK_PLL_VIDEO0 6 +#define CLK_PLL_VIDEO0_2X 7 +#define CLK_PLL_VE 8 +#define CLK_PLL_DDR 9 + +#define CLK_PLL_PERIPH_2X 11 +#define CLK_PLL_VIDEO1 12 +#define CLK_PLL_VIDEO1_2X 13 +#define CLK_PLL_GPU 14 +#define CLK_PLL_MIPI 15 +#define CLK_PLL9 16 +#define CLK_PLL10 17 + +#define CLK_AXI 19 +#define CLK_AHB1 20 +#define CLK_APB1 21 +#define CLK_APB2 22 + +#define CLK_MDFS 107 +#define CLK_SDRAM0 108 +#define CLK_SDRAM1 109 + +#define CLK_MBUS0 141 +#define CLK_MBUS1 142 + static struct aw_ccung_reset a31_ccu_resets[] = { - CCU_RESET(A31_RST_USB_PHY0, 0xcc, 0) - CCU_RESET(A31_RST_USB_PHY1, 0xcc, 1) - CCU_RESET(A31_RST_USB_PHY2, 0xcc, 2) + CCU_RESET(RST_USB_PHY0, 0xcc, 0) + CCU_RESET(RST_USB_PHY1, 0xcc, 1) + CCU_RESET(RST_USB_PHY2, 0xcc, 2) - CCU_RESET(A31_RST_AHB1_MIPI_DSI, 0x2c0, 1) - CCU_RESET(A31_RST_AHB1_SS, 0x2c0, 5) - CCU_RESET(A31_RST_AHB1_DMA, 0x2c0, 6) - CCU_RESET(A31_RST_AHB1_MMC0, 0x2c0, 8) - CCU_RESET(A31_RST_AHB1_MMC1, 0x2c0, 9) - CCU_RESET(A31_RST_AHB1_MMC2, 0x2c0, 10) - CCU_RESET(A31_RST_AHB1_MMC3, 0x2c0, 11) - CCU_RESET(A31_RST_AHB1_NAND1, 0x2c0, 12) - CCU_RESET(A31_RST_AHB1_NAND0, 0x2c0, 13) - CCU_RESET(A31_RST_AHB1_SDRAM, 0x2c0, 14) - CCU_RESET(A31_RST_AHB1_EMAC, 0x2c0, 17) - CCU_RESET(A31_RST_AHB1_TS, 0x2c0, 18) - CCU_RESET(A31_RST_AHB1_HSTIMER, 0x2c0, 19) - CCU_RESET(A31_RST_AHB1_SPI0, 0x2c0, 20) - CCU_RESET(A31_RST_AHB1_SPI1, 0x2c0, 21) - CCU_RESET(A31_RST_AHB1_SPI2, 0x2c0, 22) - CCU_RESET(A31_RST_AHB1_SPI3, 0x2c0, 23) - CCU_RESET(A31_RST_AHB1_OTG, 0x2c0, 24) - CCU_RESET(A31_RST_AHB1_EHCI0, 0x2c0, 26) - CCU_RESET(A31_RST_AHB1_EHCI1, 0x2c0, 27) - CCU_RESET(A31_RST_AHB1_OHCI0, 0x2c0, 29) - CCU_RESET(A31_RST_AHB1_OHCI1, 0x2c0, 30) - CCU_RESET(A31_RST_AHB1_OHCI2, 0x2c0, 31) + CCU_RESET(RST_AHB1_MIPI_DSI, 0x2c0, 1) + CCU_RESET(RST_AHB1_SS, 0x2c0, 5) + CCU_RESET(RST_AHB1_DMA, 0x2c0, 6) + CCU_RESET(RST_AHB1_MMC0, 0x2c0, 8) + CCU_RESET(RST_AHB1_MMC1, 0x2c0, 9) + CCU_RESET(RST_AHB1_MMC2, 0x2c0, 10) + CCU_RESET(RST_AHB1_MMC3, 0x2c0, 11) + CCU_RESET(RST_AHB1_NAND1, 0x2c0, 12) + CCU_RESET(RST_AHB1_NAND0, 0x2c0, 13) + CCU_RESET(RST_AHB1_SDRAM, 0x2c0, 14) + CCU_RESET(RST_AHB1_EMAC, 0x2c0, 17) + CCU_RESET(RST_AHB1_TS, 0x2c0, 18) + CCU_RESET(RST_AHB1_HSTIMER, 0x2c0, 19) + CCU_RESET(RST_AHB1_SPI0, 0x2c0, 20) + CCU_RESET(RST_AHB1_SPI1, 0x2c0, 21) + CCU_RESET(RST_AHB1_SPI2, 0x2c0, 22) + CCU_RESET(RST_AHB1_SPI3, 0x2c0, 23) + CCU_RESET(RST_AHB1_OTG, 0x2c0, 24) + CCU_RESET(RST_AHB1_EHCI0, 0x2c0, 26) + CCU_RESET(RST_AHB1_EHCI1, 0x2c0, 27) + CCU_RESET(RST_AHB1_OHCI0, 0x2c0, 29) + CCU_RESET(RST_AHB1_OHCI1, 0x2c0, 30) + CCU_RESET(RST_AHB1_OHCI2, 0x2c0, 31) - CCU_RESET(A31_RST_AHB1_VE, 0x2c4, 0) - CCU_RESET(A31_RST_AHB1_LCD0, 0x2c4, 4) - CCU_RESET(A31_RST_AHB1_LCD1, 0x2c4, 5) - CCU_RESET(A31_RST_AHB1_CSI, 0x2c4, 8) - CCU_RESET(A31_RST_AHB1_HDMI, 0x2c4, 11) - CCU_RESET(A31_RST_AHB1_BE0, 0x2c4, 12) - CCU_RESET(A31_RST_AHB1_BE1, 0x2c4, 13) - CCU_RESET(A31_RST_AHB1_FE0, 0x2c4, 14) - CCU_RESET(A31_RST_AHB1_FE1, 0x2c4, 15) - CCU_RESET(A31_RST_AHB1_MP, 0x2c4, 18) - CCU_RESET(A31_RST_AHB1_GPU, 0x2c4, 20) - CCU_RESET(A31_RST_AHB1_DEU0, 0x2c4, 23) - CCU_RESET(A31_RST_AHB1_DEU1, 0x2c4, 24) - CCU_RESET(A31_RST_AHB1_DRC0, 0x2c4, 25) - CCU_RESET(A31_RST_AHB1_DRC1, 0x2c4, 26) + CCU_RESET(RST_AHB1_VE, 0x2c4, 0) + CCU_RESET(RST_AHB1_LCD0, 0x2c4, 4) + CCU_RESET(RST_AHB1_LCD1, 0x2c4, 5) + CCU_RESET(RST_AHB1_CSI, 0x2c4, 8) + CCU_RESET(RST_AHB1_HDMI, 0x2c4, 11) + CCU_RESET(RST_AHB1_BE0, 0x2c4, 12) + CCU_RESET(RST_AHB1_BE1, 0x2c4, 13) + CCU_RESET(RST_AHB1_FE0, 0x2c4, 14) + CCU_RESET(RST_AHB1_FE1, 0x2c4, 15) + CCU_RESET(RST_AHB1_MP, 0x2c4, 18) + CCU_RESET(RST_AHB1_GPU, 0x2c4, 20) + CCU_RESET(RST_AHB1_DEU0, 0x2c4, 23) + CCU_RESET(RST_AHB1_DEU1, 0x2c4, 24) + CCU_RESET(RST_AHB1_DRC0, 0x2c4, 25) + CCU_RESET(RST_AHB1_DRC1, 0x2c4, 26) - CCU_RESET(A31_RST_AHB1_LVDS, 0x2c8, 0) + CCU_RESET(RST_AHB1_LVDS, 0x2c8, 0) - CCU_RESET(A31_RST_APB1_CODEC, 0x2d0, 0) - CCU_RESET(A31_RST_APB1_SPDIF, 0x2d0, 1) - CCU_RESET(A31_RST_APB1_DIGITAL_MIC, 0x2d0, 4) - CCU_RESET(A31_RST_APB1_DAUDIO0, 0x2d0, 12) - CCU_RESET(A31_RST_APB1_DAUDIO1, 0x2d0, 13) + CCU_RESET(RST_APB1_CODEC, 0x2d0, 0) + CCU_RESET(RST_APB1_SPDIF, 0x2d0, 1) + CCU_RESET(RST_APB1_DIGITAL_MIC, 0x2d0, 4) + CCU_RESET(RST_APB1_DAUDIO0, 0x2d0, 12) + CCU_RESET(RST_APB1_DAUDIO1, 0x2d0, 13) - CCU_RESET(A31_RST_APB2_I2C0, 0x2d8, 0) - CCU_RESET(A31_RST_APB2_I2C1, 0x2d8, 1) - CCU_RESET(A31_RST_APB2_I2C2, 0x2d8, 2) - CCU_RESET(A31_RST_APB2_I2C3, 0x2d8, 3) - CCU_RESET(A31_RST_APB2_UART0, 0x2d8, 16) - CCU_RESET(A31_RST_APB2_UART1, 0x2d8, 17) - CCU_RESET(A31_RST_APB2_UART2, 0x2d8, 18) - CCU_RESET(A31_RST_APB2_UART3, 0x2d8, 19) - CCU_RESET(A31_RST_APB2_UART4, 0x2d8, 20) - CCU_RESET(A31_RST_APB2_UART5, 0x2d8, 21) + CCU_RESET(RST_APB2_I2C0, 0x2d8, 0) + CCU_RESET(RST_APB2_I2C1, 0x2d8, 1) + CCU_RESET(RST_APB2_I2C2, 0x2d8, 2) + CCU_RESET(RST_APB2_I2C3, 0x2d8, 3) + CCU_RESET(RST_APB2_UART0, 0x2d8, 16) + CCU_RESET(RST_APB2_UART1, 0x2d8, 17) + CCU_RESET(RST_APB2_UART2, 0x2d8, 18) + CCU_RESET(RST_APB2_UART3, 0x2d8, 19) + CCU_RESET(RST_APB2_UART4, 0x2d8, 20) + CCU_RESET(RST_APB2_UART5, 0x2d8, 21) }; static struct aw_ccung_gate a31_ccu_gates[] = { - CCU_GATE(A31_CLK_AHB1_MIPIDSI, "ahb1-mipidsi", "ahb1", 0x60, 1) - CCU_GATE(A31_CLK_AHB1_SS, "ahb1-ss", "ahb1", 0x60, 5) - CCU_GATE(A31_CLK_AHB1_DMA, "ahb1-dma", "ahb1", 0x60, 6) - CCU_GATE(A31_CLK_AHB1_MMC0, "ahb1-mmc0", "ahb1", 0x60, 8) - CCU_GATE(A31_CLK_AHB1_MMC1, "ahb1-mmc1", "ahb1", 0x60, 9) - CCU_GATE(A31_CLK_AHB1_MMC2, "ahb1-mmc2", "ahb1", 0x60, 10) - CCU_GATE(A31_CLK_AHB1_MMC3, "ahb1-mmc3", "ahb1", 0x60, 11) - CCU_GATE(A31_CLK_AHB1_NAND1, "ahb1-nand1", "ahb1", 0x60, 12) - CCU_GATE(A31_CLK_AHB1_NAND0, "ahb1-nand0", "ahb1", 0x60, 13) - CCU_GATE(A31_CLK_AHB1_SDRAM, "ahb1-sdram", "ahb1", 0x60, 14) - CCU_GATE(A31_CLK_AHB1_EMAC, "ahb1-emac", "ahb1", 0x60, 17) - CCU_GATE(A31_CLK_AHB1_TS, "ahb1-ts", "ahb1", 0x60, 18) - CCU_GATE(A31_CLK_AHB1_HSTIMER, "ahb1-hstimer", "ahb1", 0x60, 19) - CCU_GATE(A31_CLK_AHB1_SPI0, "ahb1-spi0", "ahb1", 0x60, 20) - CCU_GATE(A31_CLK_AHB1_SPI1, "ahb1-spi1", "ahb1", 0x60, 21) - CCU_GATE(A31_CLK_AHB1_SPI2, "ahb1-spi2", "ahb1", 0x60, 22) - CCU_GATE(A31_CLK_AHB1_SPI3, "ahb1-spi3", "ahb1", 0x60, 23) - CCU_GATE(A31_CLK_AHB1_OTG, "ahb1-otg", "ahb1", 0x60, 24) - CCU_GATE(A31_CLK_AHB1_EHCI0, "ahb1-ehci0", "ahb1", 0x60, 26) - CCU_GATE(A31_CLK_AHB1_EHCI1, "ahb1-ehci1", "ahb1", 0x60, 27) - CCU_GATE(A31_CLK_AHB1_OHCI0, "ahb1-ohci0", "ahb1", 0x60, 29) - CCU_GATE(A31_CLK_AHB1_OHCI1, "ahb1-ohci1", "ahb1", 0x60, 30) - CCU_GATE(A31_CLK_AHB1_OHCI2, "ahb1-ohci2", "ahb1", 0x60, 31) - CCU_GATE(A31_CLK_AHB1_VE, "ahb1-ve", "ahb1", 0x64, 0) - CCU_GATE(A31_CLK_AHB1_LCD0, "ahb1-lcd0", "ahb1", 0x64, 4) - CCU_GATE(A31_CLK_AHB1_LCD1, "ahb1-lcd1", "ahb1", 0x64, 5) - CCU_GATE(A31_CLK_AHB1_CSI, "ahb1-csi", "ahb1", 0x64, 8) - CCU_GATE(A31_CLK_AHB1_HDMI, "ahb1-hdmi", "ahb1", 0x64, 11) - CCU_GATE(A31_CLK_AHB1_BE0, "ahb1-be0", "ahb1", 0x64, 12) - CCU_GATE(A31_CLK_AHB1_BE1, "ahb1-be1", "ahb1", 0x64, 13) - CCU_GATE(A31_CLK_AHB1_FE0, "ahb1-fe0", "ahb1", 0x64, 14) - CCU_GATE(A31_CLK_AHB1_FE1, "ahb1-fe1", "ahb1", 0x64, 15) - CCU_GATE(A31_CLK_AHB1_MP, "ahb1-mp", "ahb1", 0x64, 18) - CCU_GATE(A31_CLK_AHB1_GPU, "ahb1-gpu", "ahb1", 0x64, 20) - CCU_GATE(A31_CLK_AHB1_DEU0, "ahb1-deu0", "ahb1", 0x64, 23) - CCU_GATE(A31_CLK_AHB1_DEU1, "ahb1-deu1", "ahb1", 0x64, 24) - CCU_GATE(A31_CLK_AHB1_DRC0, "ahb1-drc0", "ahb1", 0x64, 25) - CCU_GATE(A31_CLK_AHB1_DRC1, "ahb1-drc1", "ahb1", 0x64, 26) + CCU_GATE(CLK_AHB1_MIPIDSI, "ahb1-mipidsi", "ahb1", 0x60, 1) + CCU_GATE(CLK_AHB1_SS, "ahb1-ss", "ahb1", 0x60, 5) + CCU_GATE(CLK_AHB1_DMA, "ahb1-dma", "ahb1", 0x60, 6) + CCU_GATE(CLK_AHB1_MMC0, "ahb1-mmc0", "ahb1", 0x60, 8) + CCU_GATE(CLK_AHB1_MMC1, "ahb1-mmc1", "ahb1", 0x60, 9) + CCU_GATE(CLK_AHB1_MMC2, "ahb1-mmc2", "ahb1", 0x60, 10) + CCU_GATE(CLK_AHB1_MMC3, "ahb1-mmc3", "ahb1", 0x60, 11) + CCU_GATE(CLK_AHB1_NAND1, "ahb1-nand1", "ahb1", 0x60, 12) + CCU_GATE(CLK_AHB1_NAND0, "ahb1-nand0", "ahb1", 0x60, 13) + CCU_GATE(CLK_AHB1_SDRAM, "ahb1-sdram", "ahb1", 0x60, 14) + CCU_GATE(CLK_AHB1_EMAC, "ahb1-emac", "ahb1", 0x60, 17) + CCU_GATE(CLK_AHB1_TS, "ahb1-ts", "ahb1", 0x60, 18) + CCU_GATE(CLK_AHB1_HSTIMER, "ahb1-hstimer", "ahb1", 0x60, 19) + CCU_GATE(CLK_AHB1_SPI0, "ahb1-spi0", "ahb1", 0x60, 20) + CCU_GATE(CLK_AHB1_SPI1, "ahb1-spi1", "ahb1", 0x60, 21) + CCU_GATE(CLK_AHB1_SPI2, "ahb1-spi2", "ahb1", 0x60, 22) + CCU_GATE(CLK_AHB1_SPI3, "ahb1-spi3", "ahb1", 0x60, 23) + CCU_GATE(CLK_AHB1_OTG, "ahb1-otg", "ahb1", 0x60, 24) + CCU_GATE(CLK_AHB1_EHCI0, "ahb1-ehci0", "ahb1", 0x60, 26) + CCU_GATE(CLK_AHB1_EHCI1, "ahb1-ehci1", "ahb1", 0x60, 27) + CCU_GATE(CLK_AHB1_OHCI0, "ahb1-ohci0", "ahb1", 0x60, 29) + CCU_GATE(CLK_AHB1_OHCI1, "ahb1-ohci1", "ahb1", 0x60, 30) + CCU_GATE(CLK_AHB1_OHCI2, "ahb1-ohci2", "ahb1", 0x60, 31) + CCU_GATE(CLK_AHB1_VE, "ahb1-ve", "ahb1", 0x64, 0) + CCU_GATE(CLK_AHB1_LCD0, "ahb1-lcd0", "ahb1", 0x64, 4) + CCU_GATE(CLK_AHB1_LCD1, "ahb1-lcd1", "ahb1", 0x64, 5) + CCU_GATE(CLK_AHB1_CSI, "ahb1-csi", "ahb1", 0x64, 8) + CCU_GATE(CLK_AHB1_HDMI, "ahb1-hdmi", "ahb1", 0x64, 11) + CCU_GATE(CLK_AHB1_BE0, "ahb1-be0", "ahb1", 0x64, 12) + CCU_GATE(CLK_AHB1_BE1, "ahb1-be1", "ahb1", 0x64, 13) + CCU_GATE(CLK_AHB1_FE0, "ahb1-fe0", "ahb1", 0x64, 14) + CCU_GATE(CLK_AHB1_FE1, "ahb1-fe1", "ahb1", 0x64, 15) + CCU_GATE(CLK_AHB1_MP, "ahb1-mp", "ahb1", 0x64, 18) + CCU_GATE(CLK_AHB1_GPU, "ahb1-gpu", "ahb1", 0x64, 20) + CCU_GATE(CLK_AHB1_DEU0, "ahb1-deu0", "ahb1", 0x64, 23) + CCU_GATE(CLK_AHB1_DEU1, "ahb1-deu1", "ahb1", 0x64, 24) + CCU_GATE(CLK_AHB1_DRC0, "ahb1-drc0", "ahb1", 0x64, 25) + CCU_GATE(CLK_AHB1_DRC1, "ahb1-drc1", "ahb1", 0x64, 26) - CCU_GATE(A31_CLK_APB1_CODEC, "apb1-codec", "apb1", 0x68, 0) - CCU_GATE(A31_CLK_APB1_SPDIF, "apb1-spdif", "apb1", 0x68, 1) - CCU_GATE(A31_CLK_APB1_DIGITAL_MIC, "apb1-digital-mic", "apb1", 0x68, 4) - CCU_GATE(A31_CLK_APB1_PIO, "apb1-pio", "apb1", 0x68, 5) - CCU_GATE(A31_CLK_APB1_DAUDIO0, "apb1-daudio0", "apb1", 0x68, 12) - CCU_GATE(A31_CLK_APB1_DAUDIO1, "apb1-daudio1", "apb1", 0x68, 13) + CCU_GATE(CLK_APB1_CODEC, "apb1-codec", "apb1", 0x68, 0) + CCU_GATE(CLK_APB1_SPDIF, "apb1-spdif", "apb1", 0x68, 1) + CCU_GATE(CLK_APB1_DIGITAL_MIC, "apb1-digital-mic", "apb1", 0x68, 4) + CCU_GATE(CLK_APB1_PIO, "apb1-pio", "apb1", 0x68, 5) + CCU_GATE(CLK_APB1_DAUDIO0, "apb1-daudio0", "apb1", 0x68, 12) + CCU_GATE(CLK_APB1_DAUDIO1, "apb1-daudio1", "apb1", 0x68, 13) - CCU_GATE(A31_CLK_APB2_I2C0, "apb2-i2c0", "apb2", 0x6c, 0) - CCU_GATE(A31_CLK_APB2_I2C1, "apb2-i2c1", "apb2", 0x6c, 1) - CCU_GATE(A31_CLK_APB2_I2C2, "apb2-i2c2", "apb2", 0x6c, 2) - CCU_GATE(A31_CLK_APB2_I2C3, "apb2-i2c3", "apb2", 0x6c, 3) - CCU_GATE(A31_CLK_APB2_UART0, "apb2-uart0", "apb2", 0x6c, 16) - CCU_GATE(A31_CLK_APB2_UART1, "apb2-uart1", "apb2", 0x6c, 17) - CCU_GATE(A31_CLK_APB2_UART2, "apb2-uart2", "apb2", 0x6c, 18) - CCU_GATE(A31_CLK_APB2_UART3, "apb2-uart3", "apb2", 0x6c, 19) - CCU_GATE(A31_CLK_APB2_UART4, "apb2-uart4", "apb2", 0x6c, 20) - CCU_GATE(A31_CLK_APB2_UART5, "apb2-uart5", "apb2", 0x6c, 21) + CCU_GATE(CLK_APB2_I2C0, "apb2-i2c0", "apb2", 0x6c, 0) + CCU_GATE(CLK_APB2_I2C1, "apb2-i2c1", "apb2", 0x6c, 1) + CCU_GATE(CLK_APB2_I2C2, "apb2-i2c2", "apb2", 0x6c, 2) + CCU_GATE(CLK_APB2_I2C3, "apb2-i2c3", "apb2", 0x6c, 3) + CCU_GATE(CLK_APB2_UART0, "apb2-uart0", "apb2", 0x6c, 16) + CCU_GATE(CLK_APB2_UART1, "apb2-uart1", "apb2", 0x6c, 17) + CCU_GATE(CLK_APB2_UART2, "apb2-uart2", "apb2", 0x6c, 18) + CCU_GATE(CLK_APB2_UART3, "apb2-uart3", "apb2", 0x6c, 19) + CCU_GATE(CLK_APB2_UART4, "apb2-uart4", "apb2", 0x6c, 20) + CCU_GATE(CLK_APB2_UART5, "apb2-uart5", "apb2", 0x6c, 21) - CCU_GATE(A31_CLK_DAUDIO0, "daudio0", "daudio0mux", 0xb0, 31) - CCU_GATE(A31_CLK_DAUDIO1, "daudio1", "daudio1mux", 0xb4, 31) + CCU_GATE(CLK_DAUDIO0, "daudio0", "daudio0mux", 0xb0, 31) + CCU_GATE(CLK_DAUDIO1, "daudio1", "daudio1mux", 0xb4, 31) - CCU_GATE(A31_CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8) - CCU_GATE(A31_CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9) - CCU_GATE(A31_CLK_USB_PHY2, "usb-phy2", "osc24M", 0xcc, 10) - CCU_GATE(A31_CLK_USB_OHCI0, "usb-ohci0", "osc24M", 0xcc, 16) - CCU_GATE(A31_CLK_USB_OHCI1, "usb-ohci1", "osc24M", 0xcc, 17) - CCU_GATE(A31_CLK_USB_OHCI2, "usb-ohci2", "osc24M", 0xcc, 18) + CCU_GATE(CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8) + CCU_GATE(CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9) + CCU_GATE(CLK_USB_PHY2, "usb-phy2", "osc24M", 0xcc, 10) + CCU_GATE(CLK_USB_OHCI0, "usb-ohci0", "osc24M", 0xcc, 16) + CCU_GATE(CLK_USB_OHCI1, "usb-ohci1", "osc24M", 0xcc, 17) + CCU_GATE(CLK_USB_OHCI2, "usb-ohci2", "osc24M", 0xcc, 18) - CCU_GATE(A31_CLK_DRAM_VE, "dram-ve", "mdfs", 0x100, 0) - CCU_GATE(A31_CLK_DRAM_CSI_ISP, "dram-csi_isp", "mdfs", 0x100, 1) - CCU_GATE(A31_CLK_DRAM_TS, "dram-ts", "mdfs", 0x100, 3) - CCU_GATE(A31_CLK_DRAM_DRC0, "dram-drc0", "mdfs", 0x100, 16) - CCU_GATE(A31_CLK_DRAM_DRC1, "dram-drc1", "mdfs", 0x100, 17) - CCU_GATE(A31_CLK_DRAM_DEU0, "dram-deu0", "mdfs", 0x100, 18) - CCU_GATE(A31_CLK_DRAM_DEU1, "dram-deu1", "mdfs", 0x100, 19) - CCU_GATE(A31_CLK_DRAM_FE0, "dram-fe0", "mdfs", 0x100, 24) - CCU_GATE(A31_CLK_DRAM_FE1, "dram-fe1", "mdfs", 0x100, 25) - CCU_GATE(A31_CLK_DRAM_BE0, "dram-be0", "mdfs", 0x100, 26) - CCU_GATE(A31_CLK_DRAM_BE1, "dram-be1", "mdfs", 0x100, 27) - CCU_GATE(A31_CLK_DRAM_MP, "dram-mp", "mdfs", 0x100, 28) + CCU_GATE(CLK_DRAM_VE, "dram-ve", "mdfs", 0x100, 0) + CCU_GATE(CLK_DRAM_CSI_ISP, "dram-csi_isp", "mdfs", 0x100, 1) + CCU_GATE(CLK_DRAM_TS, "dram-ts", "mdfs", 0x100, 3) + CCU_GATE(CLK_DRAM_DRC0, "dram-drc0", "mdfs", 0x100, 16) + CCU_GATE(CLK_DRAM_DRC1, "dram-drc1", "mdfs", 0x100, 17) + CCU_GATE(CLK_DRAM_DEU0, "dram-deu0", "mdfs", 0x100, 18) + CCU_GATE(CLK_DRAM_DEU1, "dram-deu1", "mdfs", 0x100, 19) + CCU_GATE(CLK_DRAM_FE0, "dram-fe0", "mdfs", 0x100, 24) + CCU_GATE(CLK_DRAM_FE1, "dram-fe1", "mdfs", 0x100, 25) + CCU_GATE(CLK_DRAM_BE0, "dram-be0", "mdfs", 0x100, 26) + CCU_GATE(CLK_DRAM_BE1, "dram-be1", "mdfs", 0x100, 27) + CCU_GATE(CLK_DRAM_MP, "dram-mp", "mdfs", 0x100, 28) - CCU_GATE(A31_CLK_CODEC, "codec", "pll_audio", 0x140, 31) + CCU_GATE(CLK_CODEC, "codec", "pll_audio", 0x140, 31) - CCU_GATE(A31_CLK_AVS, "avs", "pll_audio", 0x144, 31) + CCU_GATE(CLK_AVS, "avs", "pll_audio", 0x144, 31) - CCU_GATE(A31_CLK_DIGITAL_MIC, "digital-mic", "pll_audio", 0x148, 31) + CCU_GATE(CLK_DIGITAL_MIC, "digital-mic", "pll_audio", 0x148, 31) - CCU_GATE(A31_CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x150, 30) + CCU_GATE(CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x150, 30) - CCU_GATE(A31_CLK_PS, "ps", "lcd1_ch1", 0x154, 31) + CCU_GATE(CLK_PS, "ps", "lcd1_ch1", 0x154, 31) }; static const char *pll_parents[] = {"osc24M"}; NKMP_CLK(pll_cpu_clk, - A31_CLK_PLL_CPU, /* id */ + CLK_PLL_CPU, /* id */ "pll_cpu", pll_parents, /* name, parents */ 0x00, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -217,7 +252,7 @@ NKMP_CLK(pll_cpu_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK | AW_CLK_SCALE_CHANGE); /* flags */ NKMP_CLK(pll_audio_clk, - A31_CLK_PLL_AUDIO, /* id */ + CLK_PLL_AUDIO, /* id */ "pll_audio", pll_parents, /* name, parents */ 0x08, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -230,7 +265,7 @@ NKMP_CLK(pll_audio_clk, static const char *pll_audio_mult_parents[] = {"pll_audio"}; FIXED_CLK(pll_audio_2x_clk, - A31_CLK_PLL_AUDIO_2X, /* id */ + CLK_PLL_AUDIO_2X, /* id */ "pll_audio-2x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -238,7 +273,7 @@ FIXED_CLK(pll_audio_2x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_4x_clk, - A31_CLK_PLL_AUDIO_4X, /* id */ + CLK_PLL_AUDIO_4X, /* id */ "pll_audio-4x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -246,7 +281,7 @@ FIXED_CLK(pll_audio_4x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_8x_clk, - A31_CLK_PLL_AUDIO_8X, /* id */ + CLK_PLL_AUDIO_8X, /* id */ "pll_audio-8x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -255,7 +290,7 @@ FIXED_CLK(pll_audio_8x_clk, 0); /* flags */ NM_CLK_WITH_FRAC(pll_video0_clk, - A31_CLK_PLL_VIDEO0, /* id */ + CLK_PLL_VIDEO0, /* id */ "pll_video0", pll_parents, /* name, parents */ 0x10, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -267,7 +302,7 @@ NM_CLK_WITH_FRAC(pll_video0_clk, static const char *pll_video0_2x_parents[] = {"pll_video0"}; FIXED_CLK(pll_video0_2x_clk, - A31_CLK_PLL_VIDEO0_2X, /* id */ + CLK_PLL_VIDEO0_2X, /* id */ "pll_video0-2x", /* name */ pll_video0_2x_parents, /* parent */ 0, /* freq */ @@ -276,7 +311,7 @@ FIXED_CLK(pll_video0_2x_clk, 0); /* flags */ NM_CLK_WITH_FRAC(pll_ve_clk, - A31_CLK_PLL_VE, /* id */ + CLK_PLL_VE, /* id */ "pll_ve", pll_parents, /* name, parents */ 0x18, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -287,7 +322,7 @@ NM_CLK_WITH_FRAC(pll_ve_clk, 24, 25); /* mode sel, freq sel */ NKMP_CLK_WITH_UPDATE(pll_ddr_clk, - A31_CLK_PLL_DDR, /* id */ + CLK_PLL_DDR, /* id */ "pll_ddr", pll_parents, /* name, parents */ 0x20, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -300,7 +335,7 @@ NKMP_CLK_WITH_UPDATE(pll_ddr_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ NKMP_CLK(pll_periph_clk, - A31_CLK_PLL_PERIPH, /* id */ + CLK_PLL_PERIPH, /* id */ "pll_periph", pll_parents, /* name, parents */ 0x28, /* offset */ 8, 4, 0, 0, /* n factor */ @@ -313,7 +348,7 @@ NKMP_CLK(pll_periph_clk, static const char *pll_periph_2x_parents[] = {"pll_periph"}; FIXED_CLK(pll_periph_2x_clk, - A31_CLK_PLL_PERIPH_2X, /* id */ + CLK_PLL_PERIPH_2X, /* id */ "pll_periph-2x", /* name */ pll_periph_2x_parents, /* parent */ 0, /* freq */ @@ -322,7 +357,7 @@ FIXED_CLK(pll_periph_2x_clk, 0); /* flags */ NM_CLK_WITH_FRAC(pll_video1_clk, - A31_CLK_PLL_VIDEO1, /* id */ + CLK_PLL_VIDEO1, /* id */ "pll_video1", pll_parents, /* name, parents */ 0x30, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -334,7 +369,7 @@ NM_CLK_WITH_FRAC(pll_video1_clk, static const char *pll_video1_2x_parents[] = {"pll_video1"}; FIXED_CLK(pll_video1_2x_clk, - A31_CLK_PLL_VIDEO1_2X, /* id */ + CLK_PLL_VIDEO1_2X, /* id */ "pll_video1-2x", /* name */ pll_video1_2x_parents, /* parent */ 0, /* freq */ @@ -343,7 +378,7 @@ FIXED_CLK(pll_video1_2x_clk, 0); /* flags */ NM_CLK_WITH_FRAC(pll_gpu_clk, - A31_CLK_PLL_GPU, /* id */ + CLK_PLL_GPU, /* id */ "pll_gpu", pll_parents, /* name, parents */ 0x38, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -355,7 +390,7 @@ NM_CLK_WITH_FRAC(pll_gpu_clk, static const char *pll_mipi_parents[] = {"pll_video0", "pll_video1"}; NKMP_CLK(pll_mipi_clk, - A31_CLK_PLL_MIPI, /* id */ + CLK_PLL_MIPI, /* id */ "pll_mipi", pll_mipi_parents, /* name, parents */ 0x40, /* offset */ 8, 4, 0, 0, /* n factor */ @@ -367,7 +402,7 @@ NKMP_CLK(pll_mipi_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ NM_CLK_WITH_FRAC(pll9_clk, - A31_CLK_PLL9, /* id */ + CLK_PLL9, /* id */ "pll9", pll_parents, /* name, parents */ 0x44, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -378,7 +413,7 @@ NM_CLK_WITH_FRAC(pll9_clk, 24, 25); /* mode sel, freq sel */ NM_CLK_WITH_FRAC(pll10_clk, - A31_CLK_PLL10, /* id */ + CLK_PLL10, /* id */ "pll10", pll_parents, /* name, parents */ 0x48, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -401,7 +436,7 @@ static struct clk_div_table axi_div_table[] = { }; static const char *axi_parents[] = {"cpu"}; DIV_CLK(axi_clk, - A31_CLK_AXI, /* id */ + CLK_AXI, /* id */ "axi", axi_parents, /* name, parents */ 0x50, /* offset */ 0, 2, /* shift, mask */ @@ -409,13 +444,13 @@ DIV_CLK(axi_clk, static const char *cpu_parents[] = {"osc32k", "osc24M", "pll_cpu", "pll_cpu"}; MUX_CLK(cpu_clk, - A31_CLK_CPU, /* id */ + CLK_CPU, /* id */ "cpu", cpu_parents, /* name, parents */ 0x50, 16, 2); /* offset, shift, width */ static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph"}; PREDIV_CLK(ahb1_clk, - A31_CLK_AHB1, /* id */ + CLK_AHB1, /* id */ "ahb1", ahb1_parents, /* name, parents */ 0x54, /* offset */ 12, 2, /* mux */ @@ -432,7 +467,7 @@ static struct clk_div_table apb1_div_table[] = { { }, }; DIV_CLK(apb1_clk, - A31_CLK_APB1, /* id */ + CLK_APB1, /* id */ "apb1", apb1_parents, /* name, parents */ 0x54, /* offset */ 8, 2, /* shift, mask */ @@ -441,7 +476,7 @@ DIV_CLK(apb1_clk, static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph", "pll_periph"}; NM_CLK(apb2_clk, - A31_CLK_APB2, /* id */ + CLK_APB2, /* id */ "apb2", apb2_parents, /* name, parents */ 0x58, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ @@ -452,7 +487,7 @@ NM_CLK(apb2_clk, static const char *mod_parents[] = {"osc24M", "pll_periph"}; NM_CLK(nand0_clk, - A31_CLK_NAND0, "nand0", mod_parents, /* id, name, parents */ + CLK_NAND0, "nand0", mod_parents, /* id, name, parents */ 0x80, /* offset */ 16, 3, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -461,7 +496,7 @@ NM_CLK(nand0_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(nand1_clk, - A31_CLK_NAND1, "nand1", mod_parents, /* id, name, parents */ + CLK_NAND1, "nand1", mod_parents, /* id, name, parents */ 0x80, /* offset */ 16, 3, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -470,7 +505,7 @@ NM_CLK(nand1_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(mmc0_clk, - A31_CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ + CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ 0x88, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -480,7 +515,7 @@ NM_CLK(mmc0_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc1_clk, - A31_CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ + CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ 0x8c, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -490,7 +525,7 @@ NM_CLK(mmc1_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc2_clk, - A31_CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ + CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ 0x90, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -500,7 +535,7 @@ NM_CLK(mmc2_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc3_clk, - A31_CLK_MMC2, "mmc3", mod_parents, /* id, name, parents */ + CLK_MMC2, "mmc3", mod_parents, /* id, name, parents */ 0x94, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -511,7 +546,7 @@ NM_CLK(mmc3_clk, static const char *ts_parents[] = {"osc24M", "pll_periph"}; NM_CLK(ts_clk, - A31_CLK_TS, "ts", ts_parents, /* id, name, parents */ + CLK_TS, "ts", ts_parents, /* id, name, parents */ 0x98, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -520,7 +555,7 @@ NM_CLK(ts_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(ss_clk, - A31_CLK_SS, "ss", mod_parents, /* id, name, parents */ + CLK_SS, "ss", mod_parents, /* id, name, parents */ 0x9C, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -529,7 +564,7 @@ NM_CLK(ss_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi0_clk, - A31_CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ + CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ 0xA0, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -538,7 +573,7 @@ NM_CLK(spi0_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi1_clk, - A31_CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ + CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ 0xA4, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -547,7 +582,7 @@ NM_CLK(spi1_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi2_clk, - A31_CLK_SPI2, "spi2", mod_parents, /* id, name, parents */ + CLK_SPI2, "spi2", mod_parents, /* id, name, parents */ 0xA8, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -556,7 +591,7 @@ NM_CLK(spi2_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi3_clk, - A31_CLK_SPI3, "spi3", mod_parents, /* id, name, parents */ + CLK_SPI3, "spi3", mod_parents, /* id, name, parents */ 0xAC, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -577,7 +612,7 @@ MUX_CLK(daudio1mux_clk, static const char *mdfs_parents[] = {"pll_ddr", "pll_periph"}; NM_CLK(mdfs_clk, - A31_CLK_MDFS, "mdfs", mdfs_parents, /* id, name, parents */ + CLK_MDFS, "mdfs", mdfs_parents, /* id, name, parents */ 0xF0, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -587,7 +622,7 @@ NM_CLK(mdfs_clk, static const char *dram_parents[] = {"pll_ddr", "pll_periph"}; NM_CLK(sdram0_clk, - A31_CLK_SDRAM0, "sdram0", dram_parents, /* id, name, parents */ + CLK_SDRAM0, "sdram0", dram_parents, /* id, name, parents */ 0xF4, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -595,7 +630,7 @@ NM_CLK(sdram0_clk, 0, /* gate */ AW_CLK_HAS_MUX); /* flags */ NM_CLK(sdram1_clk, - A31_CLK_SDRAM1, "sdram1", dram_parents, /* id, name, parents */ + CLK_SDRAM1, "sdram1", dram_parents, /* id, name, parents */ 0xF4, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 8, 4, 0, 0, /* m factor */ @@ -605,7 +640,7 @@ NM_CLK(sdram1_clk, static const char *befe_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"}; NM_CLK(be0_clk, - A31_CLK_BE0, "be0", befe_parents, /* id, name, parents */ + CLK_BE0, "be0", befe_parents, /* id, name, parents */ 0x104, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -614,7 +649,7 @@ NM_CLK(be0_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(be1_clk, - A31_CLK_BE1, "be1", befe_parents, /* id, name, parents */ + CLK_BE1, "be1", befe_parents, /* id, name, parents */ 0x108, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -623,7 +658,7 @@ NM_CLK(be1_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(fe0_clk, - A31_CLK_FE0, "fe0", befe_parents, /* id, name, parents */ + CLK_FE0, "fe0", befe_parents, /* id, name, parents */ 0x104, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -631,7 +666,7 @@ NM_CLK(fe0_clk, 31, /* gate */ AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(fe1_clk, - A31_CLK_FE1, "fe1", befe_parents, /* id, name, parents */ + CLK_FE1, "fe1", befe_parents, /* id, name, parents */ 0x108, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -641,7 +676,7 @@ NM_CLK(fe1_clk, static const char *mp_parents[] = {"pll_video0", "pll_video1", "pll9", "pll10"}; NM_CLK(mp_clk, - A31_CLK_MP, "mp", mp_parents, /* id, name, parents */ + CLK_MP, "mp", mp_parents, /* id, name, parents */ 0x108, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -651,7 +686,7 @@ NM_CLK(mp_clk, static const char *lcd_ch0_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x", "pll_mipi"}; NM_CLK(lcd0_ch0_clk, - A31_CLK_LCD0_CH0, "lcd0_ch0", lcd_ch0_parents, /* id, name, parents */ + CLK_LCD0_CH0, "lcd0_ch0", lcd_ch0_parents, /* id, name, parents */ 0x118, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake )*/ @@ -660,7 +695,7 @@ NM_CLK(lcd0_ch0_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(lcd1_ch0_clk, - A31_CLK_LCD1_CH0, "lcd1_ch0", lcd_ch0_parents, /* id, name, parents */ + CLK_LCD1_CH0, "lcd1_ch0", lcd_ch0_parents, /* id, name, parents */ 0x11C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake )*/ @@ -670,7 +705,7 @@ NM_CLK(lcd1_ch0_clk, static const char *lcd_ch1_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"}; NM_CLK(lcd0_ch1_clk, - A31_CLK_LCD0_CH1, "lcd0_ch1", lcd_ch1_parents, /* id, name, parents */ + CLK_LCD0_CH1, "lcd0_ch1", lcd_ch1_parents, /* id, name, parents */ 0x12C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -679,7 +714,7 @@ NM_CLK(lcd0_ch1_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(lcd1_ch1_clk, - A31_CLK_LCD1_CH1, "lcd1_ch1", lcd_ch1_parents, /* id, name, parents */ + CLK_LCD1_CH1, "lcd1_ch1", lcd_ch1_parents, /* id, name, parents */ 0x130, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -692,7 +727,7 @@ NM_CLK(lcd1_ch1_clk, static const char *ve_parents[] = {"pll_ve"}; NM_CLK(ve_clk, - A31_CLK_VE, "ve", ve_parents, /* id, name, parents */ + CLK_VE, "ve", ve_parents, /* id, name, parents */ 0x13C, /* offset */ 16, 3, 0, 0, /* n factor */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ @@ -701,7 +736,7 @@ NM_CLK(ve_clk, AW_CLK_HAS_GATE); /* flags */ NM_CLK(hdmi_clk, - A31_CLK_HDMI, "hdmi", lcd_ch1_parents, /* id, name, parents */ + CLK_HDMI, "hdmi", lcd_ch1_parents, /* id, name, parents */ 0x150, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -711,7 +746,7 @@ NM_CLK(hdmi_clk, static const char *mbus_parents[] = {"osc24M", "pll_periph", "pll_ddr"}; NM_CLK(mbus0_clk, - A31_CLK_MBUS0, "mbus0", mbus_parents, /* id, name, parents */ + CLK_MBUS0, "mbus0", mbus_parents, /* id, name, parents */ 0x15C, /* offset */ 16, 2, 0, 0, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -720,7 +755,7 @@ NM_CLK(mbus0_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(mbus1_clk, - A31_CLK_MBUS1, "mbus1", mbus_parents, /* id, name, parents */ + CLK_MBUS1, "mbus1", mbus_parents, /* id, name, parents */ 0x160, /* offset */ 16, 2, 0, 0, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -730,7 +765,7 @@ NM_CLK(mbus1_clk, static const char *mipi_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"}; NM_CLK(mipi_dsi_clk, - A31_CLK_MIPI_DSI, "mipi_dsi", mipi_parents, /* id, name, parents */ + CLK_MIPI_DSI, "mipi_dsi", mipi_parents, /* id, name, parents */ 0x168, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 16, 4, 0, 0, /* m factor */ @@ -739,7 +774,7 @@ NM_CLK(mipi_dsi_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(mipi_dsi_dphy_clk, - A31_CLK_MIPI_DSI_DPHY, "mipi_dsi_dphy", mipi_parents, /* id, name, parents */ + CLK_MIPI_DSI_DPHY, "mipi_dsi_dphy", mipi_parents, /* id, name, parents */ 0x168, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -748,7 +783,7 @@ NM_CLK(mipi_dsi_dphy_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(mipi_csi_dphy_clk, - A31_CLK_MIPI_CSI_DPHY, "mipi_csi_dphy", mipi_parents, /* id, name, parents */ + CLK_MIPI_CSI_DPHY, "mipi_csi_dphy", mipi_parents, /* id, name, parents */ 0x16C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -759,7 +794,7 @@ NM_CLK(mipi_csi_dphy_clk, static const char *iep_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"}; NM_CLK(iep_drc0_clk, - A31_CLK_IEP_DRC0, "iep_drc0", iep_parents, /* id, name, parents */ + CLK_IEP_DRC0, "iep_drc0", iep_parents, /* id, name, parents */ 0x180, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -768,7 +803,7 @@ NM_CLK(iep_drc0_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(iep_drc1_clk, - A31_CLK_IEP_DRC1, "iep_drc1", iep_parents, /* id, name, parents */ + CLK_IEP_DRC1, "iep_drc1", iep_parents, /* id, name, parents */ 0x184, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -777,7 +812,7 @@ NM_CLK(iep_drc1_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(iep_deu0_clk, - A31_CLK_IEP_DEU0, "iep_deu0", iep_parents, /* id, name, parents */ + CLK_IEP_DEU0, "iep_deu0", iep_parents, /* id, name, parents */ 0x188, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -786,7 +821,7 @@ NM_CLK(iep_deu0_clk, AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ NM_CLK(iep_deu1_clk, - A31_CLK_IEP_DEU1, "iep_deu1", iep_parents, /* id, name, parents */ + CLK_IEP_DEU1, "iep_deu1", iep_parents, /* id, name, parents */ 0x18C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -796,7 +831,7 @@ NM_CLK(iep_deu1_clk, static const char *gpu_parents[] = {"pll_gpu", "pll_periph-2x", "pll_video0", "pll_video1", "pll9", "pll10"}; PREDIV_CLK(gpu_core_clk, - A31_CLK_GPU_CORE, /* id */ + CLK_GPU_CORE, /* id */ "gpu_core", gpu_parents, /* name, parents */ 0x1A0, /* offset */ 24, 3, /* mux */ @@ -805,7 +840,7 @@ PREDIV_CLK(gpu_core_clk, 24, 2, 1); /* prediv condition */ PREDIV_CLK(gpu_memory_clk, - A31_CLK_GPU_MEMORY, /* id */ + CLK_GPU_MEMORY, /* id */ "gpu_memory", gpu_parents, /* name, parents */ 0x1A4, /* offset */ 24, 3, /* mux */ @@ -814,7 +849,7 @@ PREDIV_CLK(gpu_memory_clk, 24, 2, 1); /* prediv condition */ PREDIV_CLK(gpu_hyd_clk, - A31_CLK_GPU_HYD, /* id */ + CLK_GPU_HYD, /* id */ "gpu_hyd", gpu_parents, /* name, parents */ 0x1A8, /* offset */ 24, 3, /* mux */ diff --git a/sys/arm/allwinner/clkng/ccu_a31.h b/sys/arm/allwinner/clkng/ccu_a31.h index 504d0abdc592..2295485e6376 100644 --- a/sys/arm/allwinner/clkng/ccu_a31.h +++ b/sys/arm/allwinner/clkng/ccu_a31.h @@ -29,222 +29,6 @@ #ifndef __CCU_A31_H__ #define __CCU_A31_H__ -#define A31_RST_USB_PHY0 0 -#define A31_RST_USB_PHY1 1 -#define A31_RST_USB_PHY2 2 -#define A31_RST_AHB1_MIPI_DSI 3 -#define A31_RST_AHB1_SS 4 -#define A31_RST_AHB1_DMA 5 -#define A31_RST_AHB1_MMC0 6 -#define A31_RST_AHB1_MMC1 7 -#define A31_RST_AHB1_MMC2 8 -#define A31_RST_AHB1_MMC3 9 -#define A31_RST_AHB1_NAND1 10 -#define A31_RST_AHB1_NAND0 11 -#define A31_RST_AHB1_SDRAM 12 -#define A31_RST_AHB1_EMAC 13 -#define A31_RST_AHB1_TS 14 -#define A31_RST_AHB1_HSTIMER 15 -#define A31_RST_AHB1_SPI0 16 -#define A31_RST_AHB1_SPI1 17 -#define A31_RST_AHB1_SPI2 18 -#define A31_RST_AHB1_SPI3 19 -#define A31_RST_AHB1_OTG 20 -#define A31_RST_AHB1_EHCI0 21 -#define A31_RST_AHB1_EHCI1 22 -#define A31_RST_AHB1_OHCI0 23 -#define A31_RST_AHB1_OHCI1 24 -#define A31_RST_AHB1_OHCI2 25 -#define A31_RST_AHB1_VE 26 -#define A31_RST_AHB1_LCD0 27 -#define A31_RST_AHB1_LCD1 28 -#define A31_RST_AHB1_CSI 29 -#define A31_RST_AHB1_HDMI 30 -#define A31_RST_AHB1_BE0 31 -#define A31_RST_AHB1_BE1 32 -#define A31_RST_AHB1_FE0 33 -#define A31_RST_AHB1_FE1 34 -#define A31_RST_AHB1_MP 35 -#define A31_RST_AHB1_GPU 36 -#define A31_RST_AHB1_DEU0 37 -#define A31_RST_AHB1_DEU1 38 -#define A31_RST_AHB1_DRC0 39 -#define A31_RST_AHB1_DRC1 40 -#define A31_RST_AHB1_LVDS 41 -#define A31_RST_APB1_CODEC 42 -#define A31_RST_APB1_SPDIF 43 -#define A31_RST_APB1_DIGITAL_MIC 44 -#define A31_RST_APB1_DAUDIO0 45 -#define A31_RST_APB1_DAUDIO1 46 -#define A31_RST_APB2_I2C0 47 -#define A31_RST_APB2_I2C1 48 -#define A31_RST_APB2_I2C2 49 -#define A31_RST_APB2_I2C3 50 -#define A31_RST_APB2_UART0 51 -#define A31_RST_APB2_UART1 52 -#define A31_RST_APB2_UART2 53 -#define A31_RST_APB2_UART3 54 -#define A31_RST_APB2_UART4 55 -#define A31_RST_APB2_UART5 56 - -#define A31_CLK_PLL_CPU 0 -#define A31_CLK_PLL_AUDIO_BASE 1 -#define A31_CLK_PLL_AUDIO 2 -#define A31_CLK_PLL_AUDIO_2X 3 -#define A31_CLK_PLL_AUDIO_4X 4 -#define A31_CLK_PLL_AUDIO_8X 5 -#define A31_CLK_PLL_VIDEO0 6 -#define A31_CLK_PLL_VIDEO0_2X 7 -#define A31_CLK_PLL_VE 8 -#define A31_CLK_PLL_DDR 9 -#define A31_CLK_PLL_PERIPH 10 -#define A31_CLK_PLL_PERIPH_2X 11 -#define A31_CLK_PLL_VIDEO1 12 -#define A31_CLK_PLL_VIDEO1_2X 13 -#define A31_CLK_PLL_GPU 14 -#define A31_CLK_PLL_MIPI 15 -#define A31_CLK_PLL9 16 -#define A31_CLK_PLL10 17 -#define A31_CLK_CPU 18 -#define A31_CLK_AXI 19 -#define A31_CLK_AHB1 20 -#define A31_CLK_APB1 21 -#define A31_CLK_APB2 22 -#define A31_CLK_AHB1_MIPIDSI 23 -#define A31_CLK_AHB1_SS 24 -#define A31_CLK_AHB1_DMA 25 -#define A31_CLK_AHB1_MMC0 26 -#define A31_CLK_AHB1_MMC1 27 -#define A31_CLK_AHB1_MMC2 28 -#define A31_CLK_AHB1_MMC3 29 -#define A31_CLK_AHB1_NAND1 30 -#define A31_CLK_AHB1_NAND0 31 -#define A31_CLK_AHB1_SDRAM 32 -#define A31_CLK_AHB1_EMAC 33 -#define A31_CLK_AHB1_TS 34 -#define A31_CLK_AHB1_HSTIMER 35 -#define A31_CLK_AHB1_SPI0 36 -#define A31_CLK_AHB1_SPI1 37 -#define A31_CLK_AHB1_SPI2 38 -#define A31_CLK_AHB1_SPI3 39 -#define A31_CLK_AHB1_OTG 40 -#define A31_CLK_AHB1_EHCI0 41 -#define A31_CLK_AHB1_EHCI1 42 -#define A31_CLK_AHB1_OHCI0 43 -#define A31_CLK_AHB1_OHCI1 44 -#define A31_CLK_AHB1_OHCI2 45 -#define A31_CLK_AHB1_VE 46 -#define A31_CLK_AHB1_LCD0 47 -#define A31_CLK_AHB1_LCD1 48 -#define A31_CLK_AHB1_CSI 49 -#define A31_CLK_AHB1_HDMI 50 -#define A31_CLK_AHB1_BE0 51 -#define A31_CLK_AHB1_BE1 52 -#define A31_CLK_AHB1_FE0 53 -#define A31_CLK_AHB1_FE1 54 -#define A31_CLK_AHB1_MP 55 -#define A31_CLK_AHB1_GPU 56 -#define A31_CLK_AHB1_DEU0 57 -#define A31_CLK_AHB1_DEU1 58 -#define A31_CLK_AHB1_DRC0 59 -#define A31_CLK_AHB1_DRC1 60 -#define A31_CLK_APB1_CODEC 61 -#define A31_CLK_APB1_SPDIF 62 -#define A31_CLK_APB1_DIGITAL_MIC 63 -#define A31_CLK_APB1_PIO 64 -#define A31_CLK_APB1_DAUDIO0 65 -#define A31_CLK_APB1_DAUDIO1 66 -#define A31_CLK_APB2_I2C0 67 -#define A31_CLK_APB2_I2C1 68 -#define A31_CLK_APB2_I2C2 69 -#define A31_CLK_APB2_I2C3 70 -#define A31_CLK_APB2_UART0 71 -#define A31_CLK_APB2_UART1 72 -#define A31_CLK_APB2_UART2 73 -#define A31_CLK_APB2_UART3 74 -#define A31_CLK_APB2_UART4 75 -#define A31_CLK_APB2_UART5 76 -#define A31_CLK_NAND0 77 -#define A31_CLK_NAND1 78 -#define A31_CLK_MMC0 79 -#define A31_CLK_MMC0_SAMPLE 80 -#define A31_CLK_MMC0_OUTPUT 81 -#define A31_CLK_MMC1 82 -#define A31_CLK_MMC1_SAMPLE 83 -#define A31_CLK_MMC1_OUTPUT 84 -#define A31_CLK_MMC2 85 -#define A31_CLK_MMC2_SAMPLE 86 -#define A31_CLK_MMC2_OUTPUT 87 -#define A31_CLK_MMC3 88 -#define A31_CLK_MMC3_SAMPLE 89 -#define A31_CLK_MMC3_OUTPUT 90 -#define A31_CLK_TS 91 -#define A31_CLK_SS 92 -#define A31_CLK_SPI0 93 -#define A31_CLK_SPI1 94 -#define A31_CLK_SPI2 95 -#define A31_CLK_SPI3 96 -#define A31_CLK_DAUDIO0 97 -#define A31_CLK_DAUDIO1 98 -#define A31_CLK_SPDIF 99 -#define A31_CLK_USB_PHY0 100 -#define A31_CLK_USB_PHY1 101 -#define A31_CLK_USB_PHY2 102 -#define A31_CLK_USB_OHCI0 103 -#define A31_CLK_USB_OHCI1 104 -#define A31_CLK_USB_OHCI2 105 -#define A31_CLK_MDFS 107 -#define A31_CLK_SDRAM0 108 -#define A31_CLK_SDRAM1 109 -#define A31_CLK_DRAM_VE 110 -#define A31_CLK_DRAM_CSI_ISP 111 -#define A31_CLK_DRAM_TS 112 -#define A31_CLK_DRAM_DRC0 113 -#define A31_CLK_DRAM_DRC1 114 -#define A31_CLK_DRAM_DEU0 115 -#define A31_CLK_DRAM_DEU1 116 -#define A31_CLK_DRAM_FE0 117 -#define A31_CLK_DRAM_FE1 118 -#define A31_CLK_DRAM_BE0 119 -#define A31_CLK_DRAM_BE1 120 -#define A31_CLK_DRAM_MP 121 -#define A31_CLK_BE0 122 -#define A31_CLK_BE1 123 -#define A31_CLK_FE0 124 -#define A31_CLK_FE1 125 -#define A31_CLK_MP 126 -#define A31_CLK_LCD0_CH0 127 -#define A31_CLK_LCD1_CH0 128 -#define A31_CLK_LCD0_CH1 129 -#define A31_CLK_LCD1_CH1 130 -#define A31_CLK_CSI0_SCLK 131 -#define A31_CLK_CSI0_MCLK 132 -#define A31_CLK_CSI1_MCLK 133 -#define A31_CLK_VE 134 -#define A31_CLK_CODEC 135 -#define A31_CLK_AVS 136 -#define A31_CLK_DIGITAL_MIC 137 -#define A31_CLK_HDMI 138 -#define A31_CLK_HDMI_DDC 139 -#define A31_CLK_PS 140 -#define A31_CLK_MBUS0 141 -#define A31_CLK_MBUS1 142 -#define A31_CLK_MIPI_DSI 143 -#define A31_CLK_MIPI_DSI_DPHY 144 -#define A31_CLK_MIPI_CSI_DPHY 145 -#define A31_CLK_IEP_DRC0 146 -#define A31_CLK_IEP_DRC1 147 -#define A31_CLK_IEP_DEU0 148 -#define A31_CLK_IEP_DEU1 149 -#define A31_CLK_GPU_CORE 150 -#define A31_CLK_GPU_MEMORY 151 -#define A31_CLK_GPU_HYD 152 -#define A31_CLK_ATS 153 -#define A31_CLK_TRACE 154 -#define A31_CLK_OUT_A 155 -#define A31_CLK_OUT_B 156 -#define A31_CLK_OUT_C 157 - void ccu_a31_register_clocks(struct aw_ccung_softc *sc); #endif /* __CCU_A31 H__ */ diff --git a/sys/arm/allwinner/clkng/ccu_a64.c b/sys/arm/allwinner/clkng/ccu_a64.c index 4e53884f86f7..bb061e7ee24e 100644 --- a/sys/arm/allwinner/clkng/ccu_a64.c +++ b/sys/arm/allwinner/clkng/ccu_a64.c @@ -43,143 +43,178 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + #include "ccu_a64.h" +/* Non-exported clocks */ + +#define CLK_OSC_12M 0 +#define CLK_PLL_CPUX 1 +#define CLK_PLL_AUDIO_BASE 2 +#define CLK_PLL_AUDIO 3 +#define CLK_PLL_AUDIO_2X 4 +#define CLK_PLL_AUDIO_4X 5 +#define CLK_PLL_AUDIO_8X 6 +#define CLK_PLL_VIDEO0 7 +#define CLK_PLL_VIDEO0_2X 8 +#define CLK_PLL_VE 9 +#define CLK_PLL_DDR0 10 +#define CLK_PLL_PERIPH0_2X 12 +#define CLK_PLL_PERIPH1 13 +#define CLK_PLL_PERIPH1_2X 14 +#define CLK_PLL_VIDEO1 15 +#define CLK_PLL_GPU 16 +#define CLK_PLL_HSIC 18 +#define CLK_PLL_DE 19 +#define CLK_PLL_DDR1 20 +#define CLK_CPUX 21 +#define CLK_AXI 22 +#define CLK_APB 23 +#define CLK_AHB1 24 +#define CLK_APB1 25 +#define CLK_APB2 26 +#define CLK_AHB2 27 +#define CLK_DRAM 94 + +#define CLK_MBUS 112 + static struct aw_ccung_reset a64_ccu_resets[] = { - CCU_RESET(A64_RST_USB_PHY0, 0x0cc, 0) - CCU_RESET(A64_RST_USB_PHY1, 0x0cc, 1) - CCU_RESET(A64_RST_USB_HSIC, 0x0cc, 2) + CCU_RESET(RST_USB_PHY0, 0x0cc, 0) + CCU_RESET(RST_USB_PHY1, 0x0cc, 1) + CCU_RESET(RST_USB_HSIC, 0x0cc, 2) - CCU_RESET(A64_RST_BUS_MIPI_DSI, 0x2c0, 1) - CCU_RESET(A64_RST_BUS_CE, 0x2c0, 5) - CCU_RESET(A64_RST_BUS_DMA, 0x2c0, 6) - CCU_RESET(A64_RST_BUS_MMC0, 0x2c0, 8) - CCU_RESET(A64_RST_BUS_MMC1, 0x2c0, 9) - CCU_RESET(A64_RST_BUS_MMC2, 0x2c0, 10) - CCU_RESET(A64_RST_BUS_NAND, 0x2c0, 13) - CCU_RESET(A64_RST_BUS_DRAM, 0x2c0, 14) - CCU_RESET(A64_RST_BUS_EMAC, 0x2c0, 17) - CCU_RESET(A64_RST_BUS_TS, 0x2c0, 18) - CCU_RESET(A64_RST_BUS_HSTIMER, 0x2c0, 19) - CCU_RESET(A64_RST_BUS_SPI0, 0x2c0, 20) - CCU_RESET(A64_RST_BUS_SPI1, 0x2c0, 21) - CCU_RESET(A64_RST_BUS_OTG, 0x2c0, 23) - CCU_RESET(A64_RST_BUS_EHCI0, 0x2c0, 24) - CCU_RESET(A64_RST_BUS_EHCI1, 0x2c0, 25) - CCU_RESET(A64_RST_BUS_OHCI0, 0x2c0, 26) - CCU_RESET(A64_RST_BUS_OHCI1, 0x2c0, 27) + CCU_RESET(RST_BUS_MIPI_DSI, 0x2c0, 1) + CCU_RESET(RST_BUS_CE, 0x2c0, 5) + CCU_RESET(RST_BUS_DMA, 0x2c0, 6) + CCU_RESET(RST_BUS_MMC0, 0x2c0, 8) + CCU_RESET(RST_BUS_MMC1, 0x2c0, 9) + CCU_RESET(RST_BUS_MMC2, 0x2c0, 10) + CCU_RESET(RST_BUS_NAND, 0x2c0, 13) + CCU_RESET(RST_BUS_DRAM, 0x2c0, 14) + CCU_RESET(RST_BUS_EMAC, 0x2c0, 17) + CCU_RESET(RST_BUS_TS, 0x2c0, 18) + CCU_RESET(RST_BUS_HSTIMER, 0x2c0, 19) + CCU_RESET(RST_BUS_SPI0, 0x2c0, 20) + CCU_RESET(RST_BUS_SPI1, 0x2c0, 21) + CCU_RESET(RST_BUS_OTG, 0x2c0, 23) + CCU_RESET(RST_BUS_EHCI0, 0x2c0, 24) + CCU_RESET(RST_BUS_EHCI1, 0x2c0, 25) + CCU_RESET(RST_BUS_OHCI0, 0x2c0, 28) + CCU_RESET(RST_BUS_OHCI1, 0x2c0, 29) - CCU_RESET(A64_RST_BUS_VE, 0x2c4, 0) - CCU_RESET(A64_RST_BUS_TCON0, 0x2c4, 3) - CCU_RESET(A64_RST_BUS_TCON1, 0x2c4, 4) - CCU_RESET(A64_RST_BUS_DEINTERLACE, 0x2c4, 5) - CCU_RESET(A64_RST_BUS_CSI, 0x2c4, 8) - CCU_RESET(A64_RST_BUS_HDMI0, 0x2c4, 10) - CCU_RESET(A64_RST_BUS_HDMI1, 0x2c4, 11) - CCU_RESET(A64_RST_BUS_DE, 0x2c4, 12) - CCU_RESET(A64_RST_BUS_GPU, 0x2c4, 20) - CCU_RESET(A64_RST_BUS_MSGBOX, 0x2c4, 21) - CCU_RESET(A64_RST_BUS_SPINLOCK, 0x2c4, 22) - CCU_RESET(A64_RST_BUS_DBG, 0x2c4, 31) + CCU_RESET(RST_BUS_VE, 0x2c4, 0) + CCU_RESET(RST_BUS_TCON0, 0x2c4, 3) + CCU_RESET(RST_BUS_TCON1, 0x2c4, 4) + CCU_RESET(RST_BUS_DEINTERLACE, 0x2c4, 5) + CCU_RESET(RST_BUS_CSI, 0x2c4, 8) + CCU_RESET(RST_BUS_HDMI0, 0x2c4, 10) + CCU_RESET(RST_BUS_HDMI1, 0x2c4, 11) + CCU_RESET(RST_BUS_DE, 0x2c4, 12) + CCU_RESET(RST_BUS_GPU, 0x2c4, 20) + CCU_RESET(RST_BUS_MSGBOX, 0x2c4, 21) + CCU_RESET(RST_BUS_SPINLOCK, 0x2c4, 22) + CCU_RESET(RST_BUS_DBG, 0x2c4, 31) - CCU_RESET(A64_RST_BUS_LVDS, 0x2C8, 31) + CCU_RESET(RST_BUS_LVDS, 0x2C8, 31) - CCU_RESET(A64_RST_BUS_CODEC, 0x2D0, 0) - CCU_RESET(A64_RST_BUS_SPDIF, 0x2D0, 1) - CCU_RESET(A64_RST_BUS_THS, 0x2D0, 8) - CCU_RESET(A64_RST_BUS_I2S0, 0x2D0, 12) - CCU_RESET(A64_RST_BUS_I2S1, 0x2D0, 13) - CCU_RESET(A64_RST_BUS_I2S2, 0x2D0, 14) + CCU_RESET(RST_BUS_CODEC, 0x2D0, 0) + CCU_RESET(RST_BUS_SPDIF, 0x2D0, 1) + CCU_RESET(RST_BUS_THS, 0x2D0, 8) + CCU_RESET(RST_BUS_I2S0, 0x2D0, 12) + CCU_RESET(RST_BUS_I2S1, 0x2D0, 13) + CCU_RESET(RST_BUS_I2S2, 0x2D0, 14) - CCU_RESET(A64_RST_BUS_I2C0, 0x2D8, 0) - CCU_RESET(A64_RST_BUS_I2C1, 0x2D8, 1) - CCU_RESET(A64_RST_BUS_I2C2, 0x2D8, 2) - CCU_RESET(A64_RST_BUS_SCR, 0x2D8, 5) - CCU_RESET(A64_RST_BUS_UART0, 0x2D8, 16) - CCU_RESET(A64_RST_BUS_UART1, 0x2D8, 17) - CCU_RESET(A64_RST_BUS_UART2, 0x2D8, 18) - CCU_RESET(A64_RST_BUS_UART3, 0x2D8, 19) - CCU_RESET(A64_RST_BUS_UART4, 0x2D8, 20) + CCU_RESET(RST_BUS_I2C0, 0x2D8, 0) + CCU_RESET(RST_BUS_I2C1, 0x2D8, 1) + CCU_RESET(RST_BUS_I2C2, 0x2D8, 2) + CCU_RESET(RST_BUS_SCR, 0x2D8, 5) + CCU_RESET(RST_BUS_UART0, 0x2D8, 16) + CCU_RESET(RST_BUS_UART1, 0x2D8, 17) + CCU_RESET(RST_BUS_UART2, 0x2D8, 18) + CCU_RESET(RST_BUS_UART3, 0x2D8, 19) + CCU_RESET(RST_BUS_UART4, 0x2D8, 20) }; static struct aw_ccung_gate a64_ccu_gates[] = { - CCU_GATE(A64_CLK_BUS_MIPI_DSI, "bus-mipi-dsi", "ahb1", 0x60, 1) - CCU_GATE(A64_CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5) - CCU_GATE(A64_CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6) - CCU_GATE(A64_CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8) - CCU_GATE(A64_CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9) - CCU_GATE(A64_CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10) - CCU_GATE(A64_CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13) - CCU_GATE(A64_CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14) - CCU_GATE(A64_CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 16) - CCU_GATE(A64_CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18) - CCU_GATE(A64_CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19) - CCU_GATE(A64_CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20) - CCU_GATE(A64_CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21) - CCU_GATE(A64_CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23) - CCU_GATE(A64_CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24) - CCU_GATE(A64_CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25) - CCU_GATE(A64_CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 26) - CCU_GATE(A64_CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 27) + CCU_GATE(CLK_BUS_MIPI_DSI, "bus-mipi-dsi", "ahb1", 0x60, 1) + CCU_GATE(CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5) + CCU_GATE(CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6) + CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8) + CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9) + CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10) + CCU_GATE(CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13) + CCU_GATE(CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14) + CCU_GATE(CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 16) + CCU_GATE(CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18) + CCU_GATE(CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19) + CCU_GATE(CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20) + CCU_GATE(CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21) + CCU_GATE(CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23) + CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24) + CCU_GATE(CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25) + CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 28) + CCU_GATE(CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 29) - CCU_GATE(A64_CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0) - CCU_GATE(A64_CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3) - CCU_GATE(A64_CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4) - CCU_GATE(A64_CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5) - CCU_GATE(A64_CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8) - CCU_GATE(A64_CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11) - CCU_GATE(A64_CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12) - CCU_GATE(A64_CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20) - CCU_GATE(A64_CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21) - CCU_GATE(A64_CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22) + CCU_GATE(CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0) + CCU_GATE(CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3) + CCU_GATE(CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4) + CCU_GATE(CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5) + CCU_GATE(CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8) + CCU_GATE(CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11) + CCU_GATE(CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12) + CCU_GATE(CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20) + CCU_GATE(CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21) + CCU_GATE(CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22) - CCU_GATE(A64_CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0) - CCU_GATE(A64_CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1) - CCU_GATE(A64_CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5) - CCU_GATE(A64_CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8) - CCU_GATE(A64_CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12) - CCU_GATE(A64_CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13) - CCU_GATE(A64_CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14) + CCU_GATE(CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0) + CCU_GATE(CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1) + CCU_GATE(CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5) + CCU_GATE(CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8) + CCU_GATE(CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12) + CCU_GATE(CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13) + CCU_GATE(CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14) - CCU_GATE(A64_CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6C, 0) - CCU_GATE(A64_CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6C, 1) - CCU_GATE(A64_CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6C, 2) - CCU_GATE(A64_CLK_BUS_SCR, "bus-src", "apb2", 0x6C, 5) - CCU_GATE(A64_CLK_BUS_UART0, "bus-uart0", "apb2", 0x6C, 16) - CCU_GATE(A64_CLK_BUS_UART1, "bus-uart1", "apb2", 0x6C, 17) - CCU_GATE(A64_CLK_BUS_UART2, "bus-uart2", "apb2", 0x6C, 18) - CCU_GATE(A64_CLK_BUS_UART3, "bus-uart3", "apb2", 0x6C, 19) - CCU_GATE(A64_CLK_BUS_UART4, "bus-uart4", "apb2", 0x6C, 20) + CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6C, 0) + CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6C, 1) + CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6C, 2) + CCU_GATE(CLK_BUS_SCR, "bus-src", "apb2", 0x6C, 5) + CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb2", 0x6C, 16) + CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb2", 0x6C, 17) + CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb2", 0x6C, 18) + CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb2", 0x6C, 19) + CCU_GATE(CLK_BUS_UART4, "bus-uart4", "apb2", 0x6C, 20) - CCU_GATE(A64_CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7) + CCU_GATE(CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7) - CCU_GATE(A64_CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8) - CCU_GATE(A64_CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9) - CCU_GATE(A64_CLK_USB_HSIC, "usb-hsic", "pll_hsic", 0xcc, 10) - CCU_GATE(A64_CLK_USB_HSIC_12M, "usb-hsic-12M", "osc12M", 0xcc, 11) - CCU_GATE(A64_CLK_USB_OHCI0, "usb-ohci0", "osc12M", 0xcc, 16) - CCU_GATE(A64_CLK_USB_OHCI1, "usb-ohci1", "usb-ohci0", 0xcc, 17) + CCU_GATE(CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8) + CCU_GATE(CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9) + CCU_GATE(CLK_USB_HSIC, "usb-hsic", "pll_hsic", 0xcc, 10) + CCU_GATE(CLK_USB_HSIC_12M, "usb-hsic-12M", "osc12M", 0xcc, 11) + CCU_GATE(CLK_USB_OHCI0, "usb-ohci0", "osc12M", 0xcc, 16) + CCU_GATE(CLK_USB_OHCI1, "usb-ohci1", "usb-ohci0", 0xcc, 17) - CCU_GATE(A64_CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) - CCU_GATE(A64_CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) - CCU_GATE(A64_CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) - CCU_GATE(A64_CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) + CCU_GATE(CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) + CCU_GATE(CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) + CCU_GATE(CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) + CCU_GATE(CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) - CCU_GATE(A64_CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) + CCU_GATE(CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) - CCU_GATE(A64_CLK_AC_DIG_4X, "ac-dig-4x", "pll_audio-4x", 0x140, 30) - CCU_GATE(A64_CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) + CCU_GATE(CLK_AC_DIG_4X, "ac-dig-4x", "pll_audio-4x", 0x140, 30) + CCU_GATE(CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) - CCU_GATE(A64_CLK_AVS, "avs", "osc24M", 0x144, 31) + CCU_GATE(CLK_AVS, "avs", "osc24M", 0x144, 31) - CCU_GATE(A64_CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) + CCU_GATE(CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) }; static const char *osc12m_parents[] = {"osc24M"}; FIXED_CLK(osc12m_clk, - A64_CLK_OSC_12M, /* id */ - "osc12M", /* name */ - osc12m_parents, /* parent */ + CLK_OSC_12M, /* id */ + "osc12M", /* name */ + osc12m_parents, /* parent */ 0, /* freq */ 1, /* mult */ 2, /* div */ @@ -187,7 +222,7 @@ FIXED_CLK(osc12m_clk, static const char *pll_cpux_parents[] = {"osc24M"}; NKMP_CLK(pll_cpux_clk, - A64_CLK_PLL_CPUX, /* id */ + CLK_PLL_CPUX, /* id */ "pll_cpux", pll_cpux_parents, /* name, parents */ 0x00, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -200,7 +235,7 @@ NKMP_CLK(pll_cpux_clk, static const char *pll_audio_parents[] = {"osc24M"}; NKMP_CLK(pll_audio_clk, - A64_CLK_PLL_AUDIO, /* id */ + CLK_PLL_AUDIO, /* id */ "pll_audio", pll_audio_parents, /* name, parents */ 0x08, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -213,7 +248,7 @@ NKMP_CLK(pll_audio_clk, static const char *pll_audio_mult_parents[] = {"pll_audio"}; FIXED_CLK(pll_audio_2x_clk, - A64_CLK_PLL_AUDIO_2X, /* id */ + CLK_PLL_AUDIO_2X, /* id */ "pll_audio-2x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -221,7 +256,7 @@ FIXED_CLK(pll_audio_2x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_4x_clk, - A64_CLK_PLL_AUDIO_4X, /* id */ + CLK_PLL_AUDIO_4X, /* id */ "pll_audio-4x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -229,7 +264,7 @@ FIXED_CLK(pll_audio_4x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_8x_clk, - A64_CLK_PLL_AUDIO_8X, /* id */ + CLK_PLL_AUDIO_8X, /* id */ "pll_audio-8x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -239,7 +274,7 @@ FIXED_CLK(pll_audio_8x_clk, static const char *pll_video0_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_video0_clk, - A64_CLK_PLL_VIDEO0, /* id */ + CLK_PLL_VIDEO0, /* id */ "pll_video0", pll_video0_parents, /* name, parents */ 0x10, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -251,7 +286,7 @@ NM_CLK_WITH_FRAC(pll_video0_clk, static const char *pll_ve_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_ve_clk, - A64_CLK_PLL_VE, /* id */ + CLK_PLL_VE, /* id */ "pll_ve", pll_ve_parents, /* name, parents */ 0x18, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -263,7 +298,7 @@ NM_CLK_WITH_FRAC(pll_ve_clk, static const char *pll_ddr0_parents[] = {"osc24M"}; NKMP_CLK_WITH_UPDATE(pll_ddr0_clk, - A64_CLK_PLL_DDR0, /* id */ + CLK_PLL_DDR0, /* id */ "pll_ddr0", pll_ddr0_parents, /* name, parents */ 0x20, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -278,7 +313,7 @@ NKMP_CLK_WITH_UPDATE(pll_ddr0_clk, static const char *pll_periph0_2x_parents[] = {"osc24M"}; static const char *pll_periph0_parents[] = {"pll_periph0_2x"}; NKMP_CLK(pll_periph0_2x_clk, - A64_CLK_PLL_PERIPH0_2X, /* id */ + CLK_PLL_PERIPH0_2X, /* id */ "pll_periph0_2x", pll_periph0_2x_parents, /* name, parents */ 0x28, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -289,7 +324,7 @@ NKMP_CLK(pll_periph0_2x_clk, 28, 1000, /* lock */ AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ FIXED_CLK(pll_periph0_clk, - A64_CLK_PLL_PERIPH0, /* id */ + CLK_PLL_PERIPH0, /* id */ "pll_periph0", /* name */ pll_periph0_parents, /* parent */ 0, /* freq */ @@ -300,7 +335,7 @@ FIXED_CLK(pll_periph0_clk, static const char *pll_periph1_2x_parents[] = {"osc24M"}; static const char *pll_periph1_parents[] = {"pll_periph1_2x"}; NKMP_CLK(pll_periph1_2x_clk, - A64_CLK_PLL_PERIPH1_2X, /* id */ + CLK_PLL_PERIPH1_2X, /* id */ "pll_periph1_2x", pll_periph1_2x_parents, /* name, parents */ 0x2C, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -311,7 +346,7 @@ NKMP_CLK(pll_periph1_2x_clk, 28, 1000, /* lock */ AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ FIXED_CLK(pll_periph1_clk, - A64_CLK_PLL_PERIPH1, /* id */ + CLK_PLL_PERIPH1, /* id */ "pll_periph1", /* name */ pll_periph1_parents, /* parent */ 0, /* freq */ @@ -321,7 +356,7 @@ FIXED_CLK(pll_periph1_clk, static const char *pll_video1_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_video1_clk, - A64_CLK_PLL_VIDEO1, /* id */ + CLK_PLL_VIDEO1, /* id */ "pll_video1", pll_video1_parents, /* name, parents */ 0x30, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -333,7 +368,7 @@ NM_CLK_WITH_FRAC(pll_video1_clk, static const char *pll_gpu_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_gpu_clk, - A64_CLK_PLL_GPU, /* id */ + CLK_PLL_GPU, /* id */ "pll_gpu", pll_gpu_parents, /* name, parents */ 0x38, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -347,7 +382,7 @@ NM_CLK_WITH_FRAC(pll_gpu_clk, static const char *pll_hsic_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_hsic_clk, - A64_CLK_PLL_HSIC, /* id */ + CLK_PLL_HSIC, /* id */ "pll_hsic", pll_hsic_parents, /* name, parents */ 0x44, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -359,7 +394,7 @@ NM_CLK_WITH_FRAC(pll_hsic_clk, static const char *pll_de_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_de_clk, - A64_CLK_PLL_DE, /* id */ + CLK_PLL_DE, /* id */ "pll_de", pll_de_parents, /* name, parents */ 0x48, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -371,7 +406,7 @@ NM_CLK_WITH_FRAC(pll_de_clk, static const char *pll_ddr1_parents[] = {"osc24M"}; NKMP_CLK_WITH_UPDATE(pll_ddr1_clk, - A64_CLK_PLL_DDR1, /* id */ + CLK_PLL_DDR1, /* id */ "pll_ddr1", pll_ddr1_parents, /* name, parents */ 0x4C, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -385,13 +420,13 @@ NKMP_CLK_WITH_UPDATE(pll_ddr1_clk, static const char *cpux_parents[] = {"osc32k", "osc24M", "pll_cpux"}; MUX_CLK(cpux_clk, - A64_CLK_CPUX, /* id */ + CLK_CPUX, /* id */ "cpux", cpux_parents, /* name, parents */ 0x50, 16, 2); /* offset, shift, width */ static const char *axi_parents[] = {"cpux"}; DIV_CLK(axi_clk, - A64_CLK_AXI, /* id */ + CLK_AXI, /* id */ "axi", axi_parents, /* name, parents */ 0x50, /* offset */ 0, 2, /* shift, width */ @@ -399,14 +434,14 @@ DIV_CLK(axi_clk, static const char *apb_parents[] = {"cpux"}; DIV_CLK(apb_clk, - A64_CLK_APB, /* id */ + CLK_APB, /* id */ "apb", apb_parents, /* name, parents */ 0x50, /* offset */ 8, 2, /* shift, width */ 0, NULL); /* flags, div table */ static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph0"}; -PREDIV_CLK(ahb1_clk, A64_CLK_AHB1, /* id */ +PREDIV_CLK(ahb1_clk, CLK_AHB1, /* id */ "ahb1", ahb1_parents, /* name, parents */ 0x54, /* offset */ 12, 2, /* mux */ @@ -423,7 +458,7 @@ static struct clk_div_table apb1_div_table[] = { { }, }; DIV_CLK(apb1_clk, - A64_CLK_APB1, /* id */ + CLK_APB1, /* id */ "apb1", apb1_parents, /* name, parents */ 0x54, /* offset */ 8, 2, /* shift, width */ @@ -432,7 +467,7 @@ DIV_CLK(apb1_clk, static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph0_2x", "pll_periph0_2x"}; NM_CLK(apb2_clk, - A64_CLK_APB2, /* id */ + CLK_APB2, /* id */ "apb2", apb2_parents, /* name, parents */ 0x58, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ @@ -442,7 +477,7 @@ NM_CLK(apb2_clk, AW_CLK_HAS_MUX); static const char *ahb2_parents[] = {"ahb1", "pll_periph0"}; -PREDIV_CLK(ahb2_clk, A64_CLK_AHB2, /* id */ +PREDIV_CLK(ahb2_clk, CLK_AHB2, /* id */ "ahb2", ahb2_parents, /* name, parents */ 0x5c, /* offset */ 0, 2, /* mux */ @@ -452,7 +487,7 @@ PREDIV_CLK(ahb2_clk, A64_CLK_AHB2, /* id */ static const char *mod_parents[] = {"osc24M", "pll_periph0_2x", "pll_periph1_2x"}; NM_CLK(nand_clk, - A64_CLK_NAND, "nand", mod_parents, /* id, name, parents */ + CLK_NAND, "nand", mod_parents, /* id, name, parents */ 0x80, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -461,7 +496,7 @@ NM_CLK(nand_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(mmc0_clk, - A64_CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ + CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ 0x88, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -471,7 +506,7 @@ NM_CLK(mmc0_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc1_clk, - A64_CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ + CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ 0x8c, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -481,7 +516,7 @@ NM_CLK(mmc1_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc2_clk, - A64_CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ + CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ 0x90, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -492,7 +527,7 @@ NM_CLK(mmc2_clk, static const char *ts_parents[] = {"osc24M", "pll_periph0"}; NM_CLK(ts_clk, - A64_CLK_TS, "ts", ts_parents, /* id, name, parents */ + CLK_TS, "ts", ts_parents, /* id, name, parents */ 0x98, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -501,7 +536,7 @@ NM_CLK(ts_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(ce_clk, - A64_CLK_CE, "ce", mod_parents, /* id, name, parents */ + CLK_CE, "ce", mod_parents, /* id, name, parents */ 0x9C, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -510,7 +545,7 @@ NM_CLK(ce_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi0_clk, - A64_CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ + CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ 0xA0, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -520,7 +555,7 @@ NM_CLK(spi0_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(spi1_clk, - A64_CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ + CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ 0xA4, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -542,7 +577,7 @@ MUX_CLK(i2s2mux_clk, static const char *spdif_parents[] = {"pll_audio"}; NM_CLK(spdif_clk, - A64_CLK_SPDIF, "spdif", spdif_parents, /* id, name, parents */ + CLK_SPDIF, "spdif", spdif_parents, /* id, name, parents */ 0xC0, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake); */ 0, 4, 0, 0, /* m factor */ @@ -555,7 +590,7 @@ NM_CLK(spdif_clk, /* DRAM needs update bit */ static const char *dram_parents[] = {"pll_ddr0", "pll_ddr1"}; NM_CLK(dram_clk, - A64_CLK_DRAM, "dram", dram_parents, /* id, name, parents */ + CLK_DRAM, "dram", dram_parents, /* id, name, parents */ 0xF4, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 2, 0, 0, /* m factor */ @@ -565,7 +600,7 @@ NM_CLK(dram_clk, static const char *de_parents[] = {"pll_periph0_2x", "pll_de"}; NM_CLK(de_clk, - A64_CLK_DE, "de", de_parents, /* id, name, parents */ + CLK_DE, "de", de_parents, /* id, name, parents */ 0x104, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -577,7 +612,7 @@ NM_CLK(de_clk, static const char *deinterlace_parents[] = {"pll_periph0", "pll_periph1"}; NM_CLK(deinterlace_clk, - A64_CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ + CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ 0x124, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -587,7 +622,7 @@ NM_CLK(deinterlace_clk, static const char *csi_sclk_parents[] = {"pll_periph0", "pll_periph1"}; NM_CLK(csi_sclk_clk, - A64_CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ + CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ 0x134, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 16, 4, 0, 0, /* m factor */ @@ -597,7 +632,7 @@ NM_CLK(csi_sclk_clk, static const char *csi_mclk_parents[] = {"osc24M", "pll_video0", "pll_periph1"}; NM_CLK(csi_mclk_clk, - A64_CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ + CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ 0x134, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -607,7 +642,7 @@ NM_CLK(csi_mclk_clk, static const char *ve_parents[] = {"pll_ve"}; NM_CLK(ve_clk, - A64_CLK_VE, "ve", ve_parents, /* id, name, parents */ + CLK_VE, "ve", ve_parents, /* id, name, parents */ 0x13C, /* offset */ 16, 3, 0, 0, /* n factor */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ @@ -617,7 +652,7 @@ NM_CLK(ve_clk, static const char *hdmi_parents[] = {"pll_video0"}; NM_CLK(hdmi_clk, - A64_CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ + CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ 0x150, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -627,7 +662,7 @@ NM_CLK(hdmi_clk, static const char *mbus_parents[] = {"osc24M", "pll_periph0_2x", "pll_ddr0"}; NM_CLK(mbus_clk, - A64_CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ + CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ 0x15C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 3, 0, 0, /* m factor */ @@ -637,7 +672,7 @@ NM_CLK(mbus_clk, static const char *gpu_parents[] = {"pll_gpu"}; NM_CLK(gpu_clk, - A64_CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ + CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ 0x1A0, /* offset */ 0, 2, 0, 0, /* n factor */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ diff --git a/sys/arm/allwinner/clkng/ccu_a64.h b/sys/arm/allwinner/clkng/ccu_a64.h index bda1ce6d76aa..bfa3dd4e61a8 100644 --- a/sys/arm/allwinner/clkng/ccu_a64.h +++ b/sys/arm/allwinner/clkng/ccu_a64.h @@ -29,176 +29,6 @@ #ifndef __CCU_A64_H__ #define __CCU_A64_H__ -#define A64_RST_USB_PHY0 0 -#define A64_RST_USB_PHY1 1 -#define A64_RST_USB_HSIC 2 -#define A64_RST_DRAM 3 -#define A64_RST_MBUS 4 -#define A64_RST_BUS_MIPI_DSI 5 -#define A64_RST_BUS_CE 6 -#define A64_RST_BUS_DMA 7 -#define A64_RST_BUS_MMC0 8 -#define A64_RST_BUS_MMC1 9 -#define A64_RST_BUS_MMC2 10 -#define A64_RST_BUS_NAND 11 -#define A64_RST_BUS_DRAM 12 -#define A64_RST_BUS_EMAC 13 -#define A64_RST_BUS_TS 14 -#define A64_RST_BUS_HSTIMER 15 -#define A64_RST_BUS_SPI0 16 -#define A64_RST_BUS_SPI1 17 -#define A64_RST_BUS_OTG 18 -#define A64_RST_BUS_EHCI0 19 -#define A64_RST_BUS_EHCI1 20 -#define A64_RST_BUS_OHCI0 21 -#define A64_RST_BUS_OHCI1 22 -#define A64_RST_BUS_VE 23 -#define A64_RST_BUS_TCON0 24 -#define A64_RST_BUS_TCON1 25 -#define A64_RST_BUS_DEINTERLACE 26 -#define A64_RST_BUS_CSI 27 -#define A64_RST_BUS_HDMI0 28 -#define A64_RST_BUS_HDMI1 29 -#define A64_RST_BUS_DE 30 -#define A64_RST_BUS_GPU 31 -#define A64_RST_BUS_MSGBOX 32 -#define A64_RST_BUS_SPINLOCK 33 -#define A64_RST_BUS_DBG 34 -#define A64_RST_BUS_LVDS 35 -#define A64_RST_BUS_CODEC 36 -#define A64_RST_BUS_SPDIF 37 -#define A64_RST_BUS_THS 38 -#define A64_RST_BUS_I2S0 39 -#define A64_RST_BUS_I2S1 40 -#define A64_RST_BUS_I2S2 41 -#define A64_RST_BUS_I2C0 42 -#define A64_RST_BUS_I2C1 43 -#define A64_RST_BUS_I2C2 44 -#define A64_RST_BUS_SCR 45 -#define A64_RST_BUS_UART0 46 -#define A64_RST_BUS_UART1 47 -#define A64_RST_BUS_UART2 48 -#define A64_RST_BUS_UART3 49 -#define A64_RST_BUS_UART4 50 - -#define A64_CLK_OSC_12M 0 -#define A64_CLK_PLL_CPUX 1 -#define A64_CLK_PLL_AUDIO_BASE 2 -#define A64_CLK_PLL_AUDIO 3 -#define A64_CLK_PLL_AUDIO_2X 4 -#define A64_CLK_PLL_AUDIO_4X 5 -#define A64_CLK_PLL_AUDIO_8X 6 -#define A64_CLK_PLL_VIDEO0 7 -#define A64_CLK_PLL_VIDEO0_2X 8 -#define A64_CLK_PLL_VE 9 -#define A64_CLK_PLL_DDR0 10 -#define A64_CLK_PLL_PERIPH0 11 -#define A64_CLK_PLL_PERIPH0_2X 12 -#define A64_CLK_PLL_PERIPH1 13 -#define A64_CLK_PLL_PERIPH1_2X 14 -#define A64_CLK_PLL_VIDEO1 15 -#define A64_CLK_PLL_GPU 16 -#define A64_CLK_PLL_MIPI 17 -#define A64_CLK_PLL_HSIC 18 -#define A64_CLK_PLL_DE 19 -#define A64_CLK_PLL_DDR1 20 -#define A64_CLK_CPUX 21 -#define A64_CLK_AXI 22 -#define A64_CLK_APB 23 -#define A64_CLK_AHB1 24 -#define A64_CLK_APB1 25 -#define A64_CLK_APB2 26 -#define A64_CLK_AHB2 27 -#define A64_CLK_BUS_MIPI_DSI 28 -#define A64_CLK_BUS_CE 29 -#define A64_CLK_BUS_DMA 30 -#define A64_CLK_BUS_MMC0 31 -#define A64_CLK_BUS_MMC1 32 -#define A64_CLK_BUS_MMC2 33 -#define A64_CLK_BUS_NAND 34 -#define A64_CLK_BUS_DRAM 35 -#define A64_CLK_BUS_EMAC 36 -#define A64_CLK_BUS_TS 37 -#define A64_CLK_BUS_HSTIMER 38 -#define A64_CLK_BUS_SPI0 39 -#define A64_CLK_BUS_SPI1 40 -#define A64_CLK_BUS_OTG 41 -#define A64_CLK_BUS_EHCI0 42 -#define A64_CLK_BUS_EHCI1 43 -#define A64_CLK_BUS_OHCI0 44 -#define A64_CLK_BUS_OHCI1 45 -#define A64_CLK_BUS_VE 46 -#define A64_CLK_BUS_TCON0 47 -#define A64_CLK_BUS_TCON1 48 -#define A64_CLK_BUS_DEINTERLACE 49 -#define A64_CLK_BUS_CSI 50 -#define A64_CLK_BUS_HDMI 51 -#define A64_CLK_BUS_DE 52 -#define A64_CLK_BUS_GPU 53 -#define A64_CLK_BUS_MSGBOX 54 -#define A64_CLK_BUS_SPINLOCK 55 -#define A64_CLK_BUS_CODEC 56 -#define A64_CLK_BUS_SPDIF 57 -#define A64_CLK_BUS_PIO 58 -#define A64_CLK_BUS_THS 59 -#define A64_CLK_BUS_I2S0 60 -#define A64_CLK_BUS_I2S1 61 -#define A64_CLK_BUS_I2S2 62 -#define A64_CLK_BUS_I2C0 63 -#define A64_CLK_BUS_I2C1 64 -#define A64_CLK_BUS_I2C2 65 -#define A64_CLK_BUS_SCR 66 -#define A64_CLK_BUS_UART0 67 -#define A64_CLK_BUS_UART1 68 -#define A64_CLK_BUS_UART2 69 -#define A64_CLK_BUS_UART3 70 -#define A64_CLK_BUS_UART4 71 -#define A64_CLK_BUS_DBG 72 -#define A64_CLK_THS 73 -#define A64_CLK_NAND 74 -#define A64_CLK_MMC0 75 -#define A64_CLK_MMC1 76 -#define A64_CLK_MMC2 77 -#define A64_CLK_TS 78 -#define A64_CLK_CE 79 -#define A64_CLK_SPI0 80 -#define A64_CLK_SPI1 81 -#define A64_CLK_I2S0 82 -#define A64_CLK_I2S1 83 -#define A64_CLK_I2S2 84 -#define A64_CLK_SPDIF 85 -#define A64_CLK_USB_PHY0 86 -#define A64_CLK_USB_PHY1 87 -#define A64_CLK_USB_HSIC 88 -#define A64_CLK_USB_HSIC_12M 89 -#define A64_CLK_USB_OHCI0_12M 90 -#define A64_CLK_USB_OHCI0 91 -#define A64_CLK_USB_OHCI1_12M 92 -#define A64_CLK_USB_OHCI1 93 -#define A64_CLK_DRAM 94 -#define A64_CLK_DRAM_VE 95 -#define A64_CLK_DRAM_CSI 96 -#define A64_CLK_DRAM_DEINTERLACE 97 -#define A64_CLK_DRAM_TS 98 -#define A64_CLK_DE 99 -#define A64_CLK_TCON0 100 -#define A64_CLK_TCON1 101 -#define A64_CLK_DEINTERLACE 102 -#define A64_CLK_CSI_MISC 103 -#define A64_CLK_CSI_SCLK 104 -#define A64_CLK_CSI_MCLK 105 -#define A64_CLK_VE 106 -#define A64_CLK_AC_DIG 107 -#define A64_CLK_AC_DIG_4X 108 -#define A64_CLK_AVS 109 -#define A64_CLK_HDMI 110 -#define A64_CLK_HDMI_DDC 111 - -#define A64_CLK_MBUS 112 - -#define A64_CLK_DSI_DPHY 113 -#define A64_CLK_GPU 114 - void ccu_a64_register_clocks(struct aw_ccung_softc *sc); #endif /* __CCU_A64_H__ */ diff --git a/sys/arm/allwinner/clkng/ccu_h3.c b/sys/arm/allwinner/clkng/ccu_h3.c index 8158964e670c..69ae7d06b427 100644 --- a/sys/arm/allwinner/clkng/ccu_h3.c +++ b/sys/arm/allwinner/clkng/ccu_h3.c @@ -43,157 +43,198 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + #include "ccu_h3.h" +/* Non-exported resets */ +#define RST_BUS_SCR 53 + +/* Non-exported clocks */ +#define CLK_PLL_CPUX 0 +#define CLK_PLL_AUDIO_BASE 1 +#define CLK_PLL_AUDIO 2 +#define CLK_PLL_AUDIO_2X 3 +#define CLK_PLL_AUDIO_4X 4 +#define CLK_PLL_AUDIO_8X 5 +#define CLK_PLL_VIDEO 6 +#define CLK_PLL_VE 7 +#define CLK_PLL_DDR 8 +#define CLK_PLL_PERIPH0_2X 10 +#define CLK_PLL_GPU 11 +#define CLK_PLL_PERIPH1 12 +#define CLK_PLL_DE 13 + +#define CLK_AXI 15 +#define CLK_AHB1 16 +#define CLK_APB1 17 +#define CLK_APB2 18 +#define CLK_AHB2 19 + +#define CLK_BUS_SCR 66 + +#define CLK_USBPHY0 88 +#define CLK_USBPHY1 89 +#define CLK_USBPHY2 90 +#define CLK_USBPHY3 91 +#define CLK_USBOHCI0 92 +#define CLK_USBOHCI1 93 +#define CLK_USBOHCI2 94 +#define CLK_USBOHCI3 95 +#define CLK_DRAM 96 + +#define CLK_MBUS 113 + static struct aw_ccung_reset h3_ccu_resets[] = { - CCU_RESET(H3_RST_USB_PHY0, 0xcc, 0) - CCU_RESET(H3_RST_USB_PHY1, 0xcc, 1) - CCU_RESET(H3_RST_USB_PHY2, 0xcc, 2) - CCU_RESET(H3_RST_USB_PHY3, 0xcc, 3) + CCU_RESET(RST_USB_PHY0, 0xcc, 0) + CCU_RESET(RST_USB_PHY1, 0xcc, 1) + CCU_RESET(RST_USB_PHY2, 0xcc, 2) + CCU_RESET(RST_USB_PHY3, 0xcc, 3) - CCU_RESET(H3_RST_MBUS, 0xfc, 31) + CCU_RESET(RST_MBUS, 0xfc, 31) - CCU_RESET(H3_RST_BUS_CE, 0x2c0, 5) - CCU_RESET(H3_RST_BUS_DMA, 0x2c0, 6) - CCU_RESET(H3_RST_BUS_MMC0, 0x2c0, 8) - CCU_RESET(H3_RST_BUS_MMC1, 0x2c0, 9) - CCU_RESET(H3_RST_BUS_MMC2, 0x2c0, 10) - CCU_RESET(H3_RST_BUS_NAND, 0x2c0, 13) - CCU_RESET(H3_RST_BUS_DRAM, 0x2c0, 14) - CCU_RESET(H3_RST_BUS_EMAC, 0x2c0, 17) - CCU_RESET(H3_RST_BUS_TS, 0x2c0, 18) - CCU_RESET(H3_RST_BUS_HSTIMER, 0x2c0, 19) - CCU_RESET(H3_RST_BUS_SPI0, 0x2c0, 20) - CCU_RESET(H3_RST_BUS_SPI1, 0x2c0, 21) - CCU_RESET(H3_RST_BUS_OTG, 0x2c0, 23) - CCU_RESET(H3_RST_BUS_EHCI0, 0x2c0, 24) - CCU_RESET(H3_RST_BUS_EHCI1, 0x2c0, 25) - CCU_RESET(H3_RST_BUS_EHCI2, 0x2c0, 26) - CCU_RESET(H3_RST_BUS_EHCI3, 0x2c0, 27) - CCU_RESET(H3_RST_BUS_OHCI0, 0x2c0, 28) - CCU_RESET(H3_RST_BUS_OHCI1, 0x2c0, 29) - CCU_RESET(H3_RST_BUS_OHCI2, 0x2c0, 30) - CCU_RESET(H3_RST_BUS_OHCI3, 0x2c0, 31) + CCU_RESET(RST_BUS_CE, 0x2c0, 5) + CCU_RESET(RST_BUS_DMA, 0x2c0, 6) + CCU_RESET(RST_BUS_MMC0, 0x2c0, 8) + CCU_RESET(RST_BUS_MMC1, 0x2c0, 9) + CCU_RESET(RST_BUS_MMC2, 0x2c0, 10) + CCU_RESET(RST_BUS_NAND, 0x2c0, 13) + CCU_RESET(RST_BUS_DRAM, 0x2c0, 14) + CCU_RESET(RST_BUS_EMAC, 0x2c0, 17) + CCU_RESET(RST_BUS_TS, 0x2c0, 18) + CCU_RESET(RST_BUS_HSTIMER, 0x2c0, 19) + CCU_RESET(RST_BUS_SPI0, 0x2c0, 20) + CCU_RESET(RST_BUS_SPI1, 0x2c0, 21) + CCU_RESET(RST_BUS_OTG, 0x2c0, 23) + CCU_RESET(RST_BUS_EHCI0, 0x2c0, 24) + CCU_RESET(RST_BUS_EHCI1, 0x2c0, 25) + CCU_RESET(RST_BUS_EHCI2, 0x2c0, 26) + CCU_RESET(RST_BUS_EHCI3, 0x2c0, 27) + CCU_RESET(RST_BUS_OHCI0, 0x2c0, 28) + CCU_RESET(RST_BUS_OHCI1, 0x2c0, 29) + CCU_RESET(RST_BUS_OHCI2, 0x2c0, 30) + CCU_RESET(RST_BUS_OHCI3, 0x2c0, 31) - CCU_RESET(H3_RST_BUS_VE, 0x2c4, 0) - CCU_RESET(H3_RST_BUS_TCON0, 0x2c4, 3) - CCU_RESET(H3_RST_BUS_TCON1, 0x2c4, 4) - CCU_RESET(H3_RST_BUS_DEINTERLACE, 0x2c4, 5) - CCU_RESET(H3_RST_BUS_CSI, 0x2c4, 8) - CCU_RESET(H3_RST_BUS_TVE, 0x2c4, 9) - CCU_RESET(H3_RST_BUS_HDMI0, 0x2c4, 10) - CCU_RESET(H3_RST_BUS_HDMI1, 0x2c4, 11) - CCU_RESET(H3_RST_BUS_DE, 0x2c4, 12) - CCU_RESET(H3_RST_BUS_GPU, 0x2c4, 20) - CCU_RESET(H3_RST_BUS_MSGBOX, 0x2c4, 21) - CCU_RESET(H3_RST_BUS_SPINLOCK, 0x2c4, 22) - CCU_RESET(H3_RST_BUS_DBG, 0x2c4, 31) + CCU_RESET(RST_BUS_VE, 0x2c4, 0) + CCU_RESET(RST_BUS_TCON0, 0x2c4, 3) + CCU_RESET(RST_BUS_TCON1, 0x2c4, 4) + CCU_RESET(RST_BUS_DEINTERLACE, 0x2c4, 5) + CCU_RESET(RST_BUS_CSI, 0x2c4, 8) + CCU_RESET(RST_BUS_TVE, 0x2c4, 9) + CCU_RESET(RST_BUS_HDMI0, 0x2c4, 10) + CCU_RESET(RST_BUS_HDMI1, 0x2c4, 11) + CCU_RESET(RST_BUS_DE, 0x2c4, 12) + CCU_RESET(RST_BUS_GPU, 0x2c4, 20) + CCU_RESET(RST_BUS_MSGBOX, 0x2c4, 21) + CCU_RESET(RST_BUS_SPINLOCK, 0x2c4, 22) + CCU_RESET(RST_BUS_DBG, 0x2c4, 31) - CCU_RESET(H3_RST_BUS_EPHY, 0x2c8, 2) + CCU_RESET(RST_BUS_EPHY, 0x2c8, 2) - CCU_RESET(H3_RST_BUS_CODEC, 0x2d0, 0) - CCU_RESET(H3_RST_BUS_SPDIF, 0x2d0, 1) - CCU_RESET(H3_RST_BUS_THS, 0x2d0, 8) - CCU_RESET(H3_RST_BUS_I2S0, 0x2d0, 12) - CCU_RESET(H3_RST_BUS_I2S1, 0x2d0, 13) - CCU_RESET(H3_RST_BUS_I2S2, 0x2d0, 14) + CCU_RESET(RST_BUS_CODEC, 0x2d0, 0) + CCU_RESET(RST_BUS_SPDIF, 0x2d0, 1) + CCU_RESET(RST_BUS_THS, 0x2d0, 8) + CCU_RESET(RST_BUS_I2S0, 0x2d0, 12) + CCU_RESET(RST_BUS_I2S1, 0x2d0, 13) + CCU_RESET(RST_BUS_I2S2, 0x2d0, 14) - CCU_RESET(H3_RST_BUS_I2C0, 0x2d8, 0) - CCU_RESET(H3_RST_BUS_I2C1, 0x2d8, 1) - CCU_RESET(H3_RST_BUS_I2C2, 0x2d8, 2) - CCU_RESET(H3_RST_BUS_UART0, 0x2d8, 16) - CCU_RESET(H3_RST_BUS_UART1, 0x2d8, 17) - CCU_RESET(H3_RST_BUS_UART2, 0x2d8, 18) - CCU_RESET(H3_RST_BUS_UART3, 0x2d8, 19) - CCU_RESET(H3_RST_BUS_SCR, 0x2d8, 20) + CCU_RESET(RST_BUS_I2C0, 0x2d8, 0) + CCU_RESET(RST_BUS_I2C1, 0x2d8, 1) + CCU_RESET(RST_BUS_I2C2, 0x2d8, 2) + CCU_RESET(RST_BUS_UART0, 0x2d8, 16) + CCU_RESET(RST_BUS_UART1, 0x2d8, 17) + CCU_RESET(RST_BUS_UART2, 0x2d8, 18) + CCU_RESET(RST_BUS_UART3, 0x2d8, 19) + CCU_RESET(RST_BUS_SCR, 0x2d8, 20) }; static struct aw_ccung_gate h3_ccu_gates[] = { - CCU_GATE(H3_CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5) - CCU_GATE(H3_CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6) - CCU_GATE(H3_CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8) - CCU_GATE(H3_CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9) - CCU_GATE(H3_CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10) - CCU_GATE(H3_CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13) - CCU_GATE(H3_CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14) - CCU_GATE(H3_CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 17) - CCU_GATE(H3_CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18) - CCU_GATE(H3_CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19) - CCU_GATE(H3_CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20) - CCU_GATE(H3_CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21) - CCU_GATE(H3_CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23) - CCU_GATE(H3_CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24) - CCU_GATE(H3_CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25) - CCU_GATE(H3_CLK_BUS_EHCI2, "bus-ehci2", "ahb2", 0x60, 26) - CCU_GATE(H3_CLK_BUS_EHCI3, "bus-ehci3", "ahb2", 0x60, 27) - CCU_GATE(H3_CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 28) - CCU_GATE(H3_CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 29) - CCU_GATE(H3_CLK_BUS_OHCI2, "bus-ohci2", "ahb2", 0x60, 30) - CCU_GATE(H3_CLK_BUS_OHCI3, "bus-ohci3", "ahb2", 0x60, 31) + CCU_GATE(CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5) + CCU_GATE(CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6) + CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8) + CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9) + CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10) + CCU_GATE(CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13) + CCU_GATE(CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14) + CCU_GATE(CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 17) + CCU_GATE(CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18) + CCU_GATE(CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19) + CCU_GATE(CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20) + CCU_GATE(CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21) + CCU_GATE(CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23) + CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24) + CCU_GATE(CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25) + CCU_GATE(CLK_BUS_EHCI2, "bus-ehci2", "ahb2", 0x60, 26) + CCU_GATE(CLK_BUS_EHCI3, "bus-ehci3", "ahb2", 0x60, 27) + CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 28) + CCU_GATE(CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 29) + CCU_GATE(CLK_BUS_OHCI2, "bus-ohci2", "ahb2", 0x60, 30) + CCU_GATE(CLK_BUS_OHCI3, "bus-ohci3", "ahb2", 0x60, 31) - CCU_GATE(H3_CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0) - CCU_GATE(H3_CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3) - CCU_GATE(H3_CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4) - CCU_GATE(H3_CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5) - CCU_GATE(H3_CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8) - CCU_GATE(H3_CLK_BUS_TVE, "bus-tve", "ahb1", 0x64, 9) - CCU_GATE(H3_CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11) - CCU_GATE(H3_CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12) - CCU_GATE(H3_CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20) - CCU_GATE(H3_CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21) - CCU_GATE(H3_CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22) + CCU_GATE(CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0) + CCU_GATE(CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3) + CCU_GATE(CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4) + CCU_GATE(CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5) + CCU_GATE(CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8) + CCU_GATE(CLK_BUS_TVE, "bus-tve", "ahb1", 0x64, 9) + CCU_GATE(CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11) + CCU_GATE(CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12) + CCU_GATE(CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20) + CCU_GATE(CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21) + CCU_GATE(CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22) - CCU_GATE(H3_CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0) - CCU_GATE(H3_CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1) - CCU_GATE(H3_CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5) - CCU_GATE(H3_CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8) - CCU_GATE(H3_CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12) - CCU_GATE(H3_CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13) - CCU_GATE(H3_CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14) + CCU_GATE(CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0) + CCU_GATE(CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1) + CCU_GATE(CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5) + CCU_GATE(CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8) + CCU_GATE(CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12) + CCU_GATE(CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13) + CCU_GATE(CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14) - CCU_GATE(H3_CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6c, 0) - CCU_GATE(H3_CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6c, 1) - CCU_GATE(H3_CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6c, 2) - CCU_GATE(H3_CLK_BUS_UART0, "bus-uart0", "apb2", 0x6c, 16) - CCU_GATE(H3_CLK_BUS_UART1, "bus-uart1", "apb2", 0x6c, 17) - CCU_GATE(H3_CLK_BUS_UART2, "bus-uart2", "apb2", 0x6c, 18) - CCU_GATE(H3_CLK_BUS_UART3, "bus-uart3", "apb2", 0x6c, 19) - CCU_GATE(H3_CLK_BUS_SCR, "bus-scr", "apb2", 0x6c, 20) + CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6c, 0) + CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6c, 1) + CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6c, 2) + CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb2", 0x6c, 16) + CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb2", 0x6c, 17) + CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb2", 0x6c, 18) + CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb2", 0x6c, 19) + CCU_GATE(CLK_BUS_SCR, "bus-scr", "apb2", 0x6c, 20) - CCU_GATE(H3_CLK_BUS_EPHY, "bus-ephy", "ahb1", 0x70, 0) - CCU_GATE(H3_CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7) + CCU_GATE(CLK_BUS_EPHY, "bus-ephy", "ahb1", 0x70, 0) + CCU_GATE(CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7) - CCU_GATE(H3_CLK_USBPHY0, "usb-phy0", "osc24M", 0xcc, 8) - CCU_GATE(H3_CLK_USBPHY1, "usb-phy1", "osc24M", 0xcc, 9) - CCU_GATE(H3_CLK_USBPHY2, "usb-phy2", "osc24M", 0xcc, 10) - CCU_GATE(H3_CLK_USBPHY3, "usb-phy3", "osc24M", 0xcc, 11) - CCU_GATE(H3_CLK_USBOHCI0, "usb-ohci0", "osc24M", 0xcc, 16) - CCU_GATE(H3_CLK_USBOHCI1, "usb-ohci1", "osc24M", 0xcc, 17) - CCU_GATE(H3_CLK_USBOHCI2, "usb-ohci2", "osc24M", 0xcc, 18) - CCU_GATE(H3_CLK_USBOHCI3, "usb-ohci3", "osc24M", 0xcc, 19) + CCU_GATE(CLK_USBPHY0, "usb-phy0", "osc24M", 0xcc, 8) + CCU_GATE(CLK_USBPHY1, "usb-phy1", "osc24M", 0xcc, 9) + CCU_GATE(CLK_USBPHY2, "usb-phy2", "osc24M", 0xcc, 10) + CCU_GATE(CLK_USBPHY3, "usb-phy3", "osc24M", 0xcc, 11) + CCU_GATE(CLK_USBOHCI0, "usb-ohci0", "osc24M", 0xcc, 16) + CCU_GATE(CLK_USBOHCI1, "usb-ohci1", "osc24M", 0xcc, 17) + CCU_GATE(CLK_USBOHCI2, "usb-ohci2", "osc24M", 0xcc, 18) + CCU_GATE(CLK_USBOHCI3, "usb-ohci3", "osc24M", 0xcc, 19) - CCU_GATE(H3_CLK_THS, "ths", "thsdiv", 0x74, 31) - CCU_GATE(H3_CLK_I2S0, "i2s0", "i2s0mux", 0xB0, 31) - CCU_GATE(H3_CLK_I2S1, "i2s1", "i2s1mux", 0xB4, 31) - CCU_GATE(H3_CLK_I2S2, "i2s2", "i2s2mux", 0xB8, 31) + CCU_GATE(CLK_THS, "ths", "thsdiv", 0x74, 31) + CCU_GATE(CLK_I2S0, "i2s0", "i2s0mux", 0xB0, 31) + CCU_GATE(CLK_I2S1, "i2s1", "i2s1mux", 0xB4, 31) + CCU_GATE(CLK_I2S2, "i2s2", "i2s2mux", 0xB8, 31) - CCU_GATE(H3_CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) - CCU_GATE(H3_CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) - CCU_GATE(H3_CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) - CCU_GATE(H3_CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) + CCU_GATE(CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) + CCU_GATE(CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) + CCU_GATE(CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) + CCU_GATE(CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) - CCU_GATE(H3_CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) + CCU_GATE(CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) - CCU_GATE(H3_CLK_AVS, "avs", "osc24M", 0x144, 31) + CCU_GATE(CLK_AVS, "avs", "osc24M", 0x144, 31) - CCU_GATE(H3_CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) + CCU_GATE(CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) - CCU_GATE(H3_CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) + CCU_GATE(CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) }; static const char *pll_cpux_parents[] = {"osc24M"}; NKMP_CLK(pll_cpux_clk, - H3_CLK_PLL_CPUX, /* id */ + CLK_PLL_CPUX, /* id */ "pll_cpux", pll_cpux_parents, /* name, parents */ 0x00, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -206,7 +247,7 @@ NKMP_CLK(pll_cpux_clk, static const char *pll_audio_parents[] = {"osc24M"}; NKMP_CLK(pll_audio_clk, - H3_CLK_PLL_AUDIO, /* id */ + CLK_PLL_AUDIO, /* id */ "pll_audio", pll_audio_parents, /* name, parents */ 0x08, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -219,7 +260,7 @@ NKMP_CLK(pll_audio_clk, static const char *pll_audio_mult_parents[] = {"pll_audio"}; FIXED_CLK(pll_audio_2x_clk, - H3_CLK_PLL_AUDIO_2X, /* id */ + CLK_PLL_AUDIO_2X, /* id */ "pll_audio-2x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -227,7 +268,7 @@ FIXED_CLK(pll_audio_2x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_4x_clk, - H3_CLK_PLL_AUDIO_4X, /* id */ + CLK_PLL_AUDIO_4X, /* id */ "pll_audio-4x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -235,7 +276,7 @@ FIXED_CLK(pll_audio_4x_clk, 1, /* div */ 0); /* flags */ FIXED_CLK(pll_audio_8x_clk, - H3_CLK_PLL_AUDIO_8X, /* id */ + CLK_PLL_AUDIO_8X, /* id */ "pll_audio-8x", /* name */ pll_audio_mult_parents, /* parent */ 0, /* freq */ @@ -245,7 +286,7 @@ FIXED_CLK(pll_audio_8x_clk, static const char *pll_video_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_video_clk, - H3_CLK_PLL_VIDEO, /* id */ + CLK_PLL_VIDEO, /* id */ "pll_video", pll_video_parents, /* name, parents */ 0x10, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -257,7 +298,7 @@ NM_CLK_WITH_FRAC(pll_video_clk, static const char *pll_ve_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_ve_clk, - H3_CLK_PLL_VE, /* id */ + CLK_PLL_VE, /* id */ "pll_ve", pll_ve_parents, /* name, parents */ 0x18, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -269,7 +310,7 @@ NM_CLK_WITH_FRAC(pll_ve_clk, static const char *pll_ddr_parents[] = {"osc24M"}; NKMP_CLK_WITH_UPDATE(pll_ddr_clk, - H3_CLK_PLL_DDR, /* id */ + CLK_PLL_DDR, /* id */ "pll_ddr", pll_ddr_parents, /* name, parents */ 0x20, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -284,7 +325,7 @@ NKMP_CLK_WITH_UPDATE(pll_ddr_clk, static const char *pll_periph0_parents[] = {"osc24M"}; static const char *pll_periph0_2x_parents[] = {"pll_periph0"}; NKMP_CLK(pll_periph0_clk, - H3_CLK_PLL_PERIPH0, /* id */ + CLK_PLL_PERIPH0, /* id */ "pll_periph0", pll_periph0_parents, /* name, parents */ 0x28, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -295,7 +336,7 @@ NKMP_CLK(pll_periph0_clk, 28, 1000, /* lock */ AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ FIXED_CLK(pll_periph0_2x_clk, - H3_CLK_PLL_PERIPH0_2X, /* id */ + CLK_PLL_PERIPH0_2X, /* id */ "pll_periph0-2x", /* name */ pll_periph0_2x_parents, /* parent */ 0, /* freq */ @@ -305,7 +346,7 @@ FIXED_CLK(pll_periph0_2x_clk, static const char *pll_gpu_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_gpu_clk, - H3_CLK_PLL_GPU, /* id */ + CLK_PLL_GPU, /* id */ "pll_gpu", pll_gpu_parents, /* name, parents */ 0x38, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -317,7 +358,7 @@ NM_CLK_WITH_FRAC(pll_gpu_clk, static const char *pll_periph1_parents[] = {"osc24M"}; NKMP_CLK(pll_periph1_clk, - H3_CLK_PLL_PERIPH1, /* id */ + CLK_PLL_PERIPH1, /* id */ "pll_periph1", pll_periph1_parents, /* name, parents */ 0x44, /* offset */ 8, 5, 0, 0, /* n factor */ @@ -330,7 +371,7 @@ NKMP_CLK(pll_periph1_clk, static const char *pll_de_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_de_clk, - H3_CLK_PLL_DE, /* id */ + CLK_PLL_DE, /* id */ "pll_de", pll_de_parents, /* name, parents */ 0x48, /* offset */ 8, 7, 0, 0, /* n factor */ @@ -342,20 +383,20 @@ NM_CLK_WITH_FRAC(pll_de_clk, static const char *cpux_parents[] = {"osc32k", "osc24M", "pll_cpux", "pll_cpux"}; MUX_CLK(cpux_clk, - H3_CLK_CPUX, /* id */ + CLK_CPUX, /* id */ "cpux", cpux_parents, /* name, parents */ 0x50, 16, 2); /* offset, shift, width */ static const char *axi_parents[] = {"cpux"}; DIV_CLK(axi_clk, - H3_CLK_AXI, /* id */ + CLK_AXI, /* id */ "axi", axi_parents, /* name, parents */ 0x50, /* offset */ 0, 2, /* shift, width */ 0, NULL); /* flags, div table */ static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph0"}; -PREDIV_CLK(ahb1_clk, H3_CLK_AHB1, /* id */ +PREDIV_CLK(ahb1_clk, CLK_AHB1, /* id */ "ahb1", ahb1_parents, /* name, parents */ 0x54, /* offset */ 12, 2, /* mux */ @@ -372,7 +413,7 @@ static struct clk_div_table apb1_div_table[] = { { }, }; DIV_CLK(apb1_clk, - H3_CLK_APB1, /* id */ + CLK_APB1, /* id */ "apb1", apb1_parents, /* name, parents */ 0x54, /* offset */ 8, 2, /* shift, width */ @@ -381,7 +422,7 @@ DIV_CLK(apb1_clk, static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph0", "pll_periph0"}; NM_CLK(apb2_clk, - H3_CLK_APB2, /* id */ + CLK_APB2, /* id */ "apb2", apb2_parents, /* name, parents */ 0x58, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ @@ -391,7 +432,7 @@ NM_CLK(apb2_clk, AW_CLK_HAS_MUX); static const char *ahb2_parents[] = {"ahb1", "pll_periph0"}; -PREDIV_CLK(ahb2_clk, H3_CLK_AHB2, /* id */ +PREDIV_CLK(ahb2_clk, CLK_AHB2, /* id */ "ahb2", ahb2_parents, /* name, parents */ 0x5c, /* offset */ 0, 2, /* mux */ @@ -408,7 +449,7 @@ static struct clk_div_table ths_div_table[] = { { }, }; DIV_CLK(thsdiv_clk, - 0, /* id */ + 0, /* id */ "thsdiv", ths_parents, /* name, parents */ 0x74, /* offset */ 0, 2, /* shift, width */ @@ -417,7 +458,7 @@ DIV_CLK(thsdiv_clk, static const char *mod_parents[] = {"osc24M", "pll_periph0", "pll_periph1"}; NM_CLK(nand_clk, - H3_CLK_NAND, "nand", mod_parents, /* id, name, parents */ + CLK_NAND, "nand", mod_parents, /* id, name, parents */ 0x80, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -426,7 +467,7 @@ NM_CLK(nand_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(mmc0_clk, - H3_CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ + CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ 0x88, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -436,7 +477,7 @@ NM_CLK(mmc0_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc1_clk, - H3_CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ + CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ 0x8c, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -446,7 +487,7 @@ NM_CLK(mmc1_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(mmc2_clk, - H3_CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ + CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ 0x90, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -457,7 +498,7 @@ NM_CLK(mmc2_clk, static const char *ts_parents[] = {"osc24M", "pll_periph0"}; NM_CLK(ts_clk, - H3_CLK_TS, "ts", ts_parents, /* id, name, parents */ + CLK_TS, "ts", ts_parents, /* id, name, parents */ 0x98, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -466,7 +507,7 @@ NM_CLK(ts_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(ce_clk, - H3_CLK_CE, "ce", mod_parents, /* id, name, parents */ + CLK_CE, "ce", mod_parents, /* id, name, parents */ 0x9C, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -475,7 +516,7 @@ NM_CLK(ce_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_MUX); /* flags */ NM_CLK(spi0_clk, - H3_CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ + CLK_SPI0, "spi0", mod_parents, /* id, name, parents */ 0xA0, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -485,7 +526,7 @@ NM_CLK(spi0_clk, AW_CLK_REPARENT); /* flags */ NM_CLK(spi1_clk, - H3_CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ + CLK_SPI1, "spi1", mod_parents, /* id, name, parents */ 0xA4, /* offset */ 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 0, 4, 0, 0, /* m factor */ @@ -507,7 +548,7 @@ MUX_CLK(i2s2mux_clk, static const char *spdif_parents[] = {"pll_audio"}; NM_CLK(spdif_clk, - H3_CLK_SPDIF, "spdif", spdif_parents, /* id, name, parents */ + CLK_SPDIF, "spdif", spdif_parents, /* id, name, parents */ 0xC0, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake); */ 0, 4, 0, 0, /* m factor */ @@ -517,7 +558,7 @@ NM_CLK(spdif_clk, static const char *dram_parents[] = {"pll_ddr", "pll_periph0-2x"}; NM_CLK(dram_clk, - H3_CLK_DRAM, "dram", dram_parents, /* id, name, parents */ + CLK_DRAM, "dram", dram_parents, /* id, name, parents */ 0xF4, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -527,7 +568,7 @@ NM_CLK(dram_clk, static const char *de_parents[] = {"pll_periph0-2x", "pll_de"}; NM_CLK(de_clk, - H3_CLK_DE, "de", de_parents, /* id, name, parents */ + CLK_DE, "de", de_parents, /* id, name, parents */ 0x104, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -537,7 +578,7 @@ NM_CLK(de_clk, static const char *tcon0_parents[] = {"pll_video"}; NM_CLK(tcon0_clk, - H3_CLK_TCON0, "tcon0", tcon0_parents, /* id, name, parents */ + CLK_TCON0, "tcon0", tcon0_parents, /* id, name, parents */ 0x118, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -547,7 +588,7 @@ NM_CLK(tcon0_clk, static const char *tve_parents[] = {"pll_de", "pll_periph1"}; NM_CLK(tve_clk, - H3_CLK_TVE, "tve", tve_parents, /* id, name, parents */ + CLK_TVE, "tve", tve_parents, /* id, name, parents */ 0x120, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -557,7 +598,7 @@ NM_CLK(tve_clk, static const char *deinterlace_parents[] = {"pll_periph0", "pll_periph1"}; NM_CLK(deinterlace_clk, - H3_CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ + CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ 0x124, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -567,7 +608,7 @@ NM_CLK(deinterlace_clk, static const char *csi_sclk_parents[] = {"pll_periph0", "pll_periph1"}; NM_CLK(csi_sclk_clk, - H3_CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ + CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ 0x134, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 16, 4, 0, 0, /* m factor */ @@ -577,7 +618,7 @@ NM_CLK(csi_sclk_clk, static const char *csi_mclk_parents[] = {"osc24M", "pll_video", "pll_periph1"}; NM_CLK(csi_mclk_clk, - H3_CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ + CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ 0x134, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -587,7 +628,7 @@ NM_CLK(csi_mclk_clk, static const char *ve_parents[] = {"pll_ve"}; NM_CLK(ve_clk, - H3_CLK_VE, "ve", ve_parents, /* id, name, parents */ + CLK_VE, "ve", ve_parents, /* id, name, parents */ 0x13C, /* offset */ 16, 3, 0, 0, /* n factor */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ @@ -597,7 +638,7 @@ NM_CLK(ve_clk, static const char *hdmi_parents[] = {"pll_video"}; NM_CLK(hdmi_clk, - H3_CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ + CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ 0x150, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 4, 0, 0, /* m factor */ @@ -607,7 +648,7 @@ NM_CLK(hdmi_clk, static const char *mbus_parents[] = {"osc24M", "pll_periph0-2x", "pll_ddr"}; NM_CLK(mbus_clk, - H3_CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ + CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ 0x15C, /* offset */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ 0, 3, 0, 0, /* m factor */ @@ -617,7 +658,7 @@ NM_CLK(mbus_clk, static const char *gpu_parents[] = {"pll_gpu"}; NM_CLK(gpu_clk, - H3_CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ + CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ 0x1A0, /* offset */ 0, 2, 0, 0, /* n factor */ 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ diff --git a/sys/arm/allwinner/clkng/ccu_h3.h b/sys/arm/allwinner/clkng/ccu_h3.h index 0144255f74cb..26569cd69692 100644 --- a/sys/arm/allwinner/clkng/ccu_h3.h +++ b/sys/arm/allwinner/clkng/ccu_h3.h @@ -29,177 +29,6 @@ #ifndef __CCU_H3_H__ #define __CCU_H3_H__ -#define H3_RST_USB_PHY0 0 -#define H3_RST_USB_PHY1 1 -#define H3_RST_USB_PHY2 2 -#define H3_RST_USB_PHY3 3 -#define H3_RST_MBUS 4 -#define H3_RST_BUS_CE 5 -#define H3_RST_BUS_DMA 6 -#define H3_RST_BUS_MMC0 7 -#define H3_RST_BUS_MMC1 8 -#define H3_RST_BUS_MMC2 9 -#define H3_RST_BUS_NAND 10 -#define H3_RST_BUS_DRAM 11 -#define H3_RST_BUS_EMAC 12 -#define H3_RST_BUS_TS 13 -#define H3_RST_BUS_HSTIMER 14 -#define H3_RST_BUS_SPI0 15 -#define H3_RST_BUS_SPI1 16 -#define H3_RST_BUS_OTG 17 -#define H3_RST_BUS_EHCI0 18 -#define H3_RST_BUS_EHCI1 19 -#define H3_RST_BUS_EHCI2 20 -#define H3_RST_BUS_EHCI3 21 -#define H3_RST_BUS_OHCI0 22 -#define H3_RST_BUS_OHCI1 23 -#define H3_RST_BUS_OHCI2 24 -#define H3_RST_BUS_OHCI3 25 -#define H3_RST_BUS_VE 26 -#define H3_RST_BUS_TCON0 27 -#define H3_RST_BUS_TCON1 28 -#define H3_RST_BUS_DEINTERLACE 29 -#define H3_RST_BUS_CSI 30 -#define H3_RST_BUS_TVE 31 -#define H3_RST_BUS_HDMI0 32 -#define H3_RST_BUS_HDMI1 33 -#define H3_RST_BUS_DE 34 -#define H3_RST_BUS_GPU 35 -#define H3_RST_BUS_MSGBOX 36 -#define H3_RST_BUS_SPINLOCK 37 -#define H3_RST_BUS_DBG 38 -#define H3_RST_BUS_EPHY 39 -#define H3_RST_BUS_CODEC 40 -#define H3_RST_BUS_SPDIF 41 -#define H3_RST_BUS_THS 42 -#define H3_RST_BUS_I2S0 43 -#define H3_RST_BUS_I2S1 44 -#define H3_RST_BUS_I2S2 45 -#define H3_RST_BUS_I2C0 46 -#define H3_RST_BUS_I2C1 47 -#define H3_RST_BUS_I2C2 48 -#define H3_RST_BUS_UART0 49 -#define H3_RST_BUS_UART1 50 -#define H3_RST_BUS_UART2 51 -#define H3_RST_BUS_UART3 52 -#define H3_RST_BUS_SCR 53 - -#define H3_CLK_PLL_CPUX 0 -#define H3_CLK_PLL_AUDIO_BASE 1 -#define H3_CLK_PLL_AUDIO 2 -#define H3_CLK_PLL_AUDIO_2X 3 -#define H3_CLK_PLL_AUDIO_4X 4 -#define H3_CLK_PLL_AUDIO_8X 5 -#define H3_CLK_PLL_VIDEO 6 -#define H3_CLK_PLL_VE 7 -#define H3_CLK_PLL_DDR 8 -#define H3_CLK_PLL_PERIPH0 9 -#define H3_CLK_PLL_PERIPH0_2X 10 -#define H3_CLK_PLL_GPU 11 -#define H3_CLK_PLL_PERIPH1 12 -#define H3_CLK_PLL_DE 13 -#define H3_CLK_CPUX 14 -#define H3_CLK_AXI 15 -#define H3_CLK_AHB1 16 -#define H3_CLK_APB1 17 -#define H3_CLK_APB2 18 -#define H3_CLK_AHB2 19 -#define H3_CLK_BUS_CE 20 -#define H3_CLK_BUS_DMA 21 -#define H3_CLK_BUS_MMC0 22 -#define H3_CLK_BUS_MMC1 23 -#define H3_CLK_BUS_MMC2 24 -#define H3_CLK_BUS_NAND 25 -#define H3_CLK_BUS_DRAM 26 -#define H3_CLK_BUS_EMAC 27 -#define H3_CLK_BUS_TS 28 -#define H3_CLK_BUS_HSTIMER 29 -#define H3_CLK_BUS_SPI0 30 -#define H3_CLK_BUS_SPI1 31 -#define H3_CLK_BUS_OTG 32 -#define H3_CLK_BUS_EHCI0 33 -#define H3_CLK_BUS_EHCI1 34 -#define H3_CLK_BUS_EHCI2 35 -#define H3_CLK_BUS_EHCI3 36 -#define H3_CLK_BUS_OHCI0 37 -#define H3_CLK_BUS_OHCI1 38 -#define H3_CLK_BUS_OHCI2 39 -#define H3_CLK_BUS_OHCI3 40 -#define H3_CLK_BUS_VE 41 -#define H3_CLK_BUS_TCON0 42 -#define H3_CLK_BUS_TCON1 43 -#define H3_CLK_BUS_DEINTERLACE 44 -#define H3_CLK_BUS_CSI 45 -#define H3_CLK_BUS_TVE 46 -#define H3_CLK_BUS_HDMI 47 -#define H3_CLK_BUS_DE 48 -#define H3_CLK_BUS_GPU 49 -#define H3_CLK_BUS_MSGBOX 50 -#define H3_CLK_BUS_SPINLOCK 51 -#define H3_CLK_BUS_CODEC 52 -#define H3_CLK_BUS_SPDIF 53 -#define H3_CLK_BUS_PIO 54 -#define H3_CLK_BUS_THS 55 -#define H3_CLK_BUS_I2S0 56 -#define H3_CLK_BUS_I2S1 57 -#define H3_CLK_BUS_I2S2 58 -#define H3_CLK_BUS_I2C0 59 -#define H3_CLK_BUS_I2C1 60 -#define H3_CLK_BUS_I2C2 61 -#define H3_CLK_BUS_UART0 62 -#define H3_CLK_BUS_UART1 63 -#define H3_CLK_BUS_UART2 64 -#define H3_CLK_BUS_UART3 65 -#define H3_CLK_BUS_SCR 66 -#define H3_CLK_BUS_EPHY 67 -#define H3_CLK_BUS_DBG 68 -#define H3_CLK_THS 69 -#define H3_CLK_NAND 70 -#define H3_CLK_MMC0 71 -#define H3_CLK_MMC0_SAMPLE 72 -#define H3_CLK_MMC0_OUTPUT 73 -#define H3_CLK_MMC1 74 -#define H3_CLK_MMC1_SAMPLE 75 -#define H3_CLK_MMC1_OUTPUT 76 -#define H3_CLK_MMC2 77 -#define H3_CLK_MMC2_SAMPLE 78 -#define H3_CLK_MMC2_OUTPUT 79 -#define H3_CLK_TS 80 -#define H3_CLK_CE 81 -#define H3_CLK_SPI0 82 -#define H3_CLK_SPI1 83 -#define H3_CLK_I2S0 84 -#define H3_CLK_I2S1 85 -#define H3_CLK_I2S2 86 -#define H3_CLK_SPDIF 87 -#define H3_CLK_USBPHY0 88 -#define H3_CLK_USBPHY1 89 -#define H3_CLK_USBPHY2 90 -#define H3_CLK_USBPHY3 91 -#define H3_CLK_USBOHCI0 92 -#define H3_CLK_USBOHCI1 93 -#define H3_CLK_USBOHCI2 94 -#define H3_CLK_USBOHCI3 95 -#define H3_CLK_DRAM 96 -#define H3_CLK_DRAM_VE 97 -#define H3_CLK_DRAM_CSI 98 -#define H3_CLK_DRAM_DEINTERLACE 99 -#define H3_CLK_DRAM_TS 100 -#define H3_CLK_DE 101 -#define H3_CLK_TCON0 102 -#define H3_CLK_TVE 103 -#define H3_CLK_DEINTERLACE 104 -#define H3_CLK_CSI_MISC 105 -#define H3_CLK_CSI_SCLK 106 -#define H3_CLK_CSI_MCLK 107 -#define H3_CLK_VE 108 -#define H3_CLK_AC_DIG 109 -#define H3_CLK_AVS 110 -#define H3_CLK_HDMI 111 -#define H3_CLK_HDMI_DDC 112 -#define H3_CLK_MBUS 113 -#define H3_CLK_GPU 114 - void ccu_h3_register_clocks(struct aw_ccung_softc *sc); #endif /* __CCU_H3_H__ */ diff --git a/sys/arm/allwinner/clkng/ccu_sun8i_r.c b/sys/arm/allwinner/clkng/ccu_sun8i_r.c new file mode 100644 index 000000000000..3c3fba828adf --- /dev/null +++ b/sys/arm/allwinner/clkng/ccu_sun8i_r.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2017 Emmanuel Vadot + * All rights reserved. + * + * 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 AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* Non-exported clocks */ +#define CLK_AHB0 1 +#define CLK_APB0 2 + +static struct aw_ccung_reset ccu_sun8i_r_resets[] = { + CCU_RESET(RST_APB0_IR, 0xb0, 1) + CCU_RESET(RST_APB0_TIMER, 0xb0, 2) + CCU_RESET(RST_APB0_RSB, 0xb0, 4) + CCU_RESET(RST_APB0_UART, 0xb0, 6) +}; + +static struct aw_ccung_gate ccu_sun8i_r_gates[] = { + CCU_GATE(CLK_APB0_PIO, "apb0-pio", "apb0", 0x28, 0) + CCU_GATE(CLK_APB0_IR, "apb0-ir", "apb0", 0x28, 1) + CCU_GATE(CLK_APB0_TIMER, "apb0-timer", "apb0", 0x28, 2) + CCU_GATE(CLK_APB0_RSB, "apb0-rsb", "apb0", 0x28, 3) + CCU_GATE(CLK_APB0_UART, "apb0-uart", "apb0", 0x28, 4) + CCU_GATE(CLK_APB0_I2C, "apb0-i2c", "apb0", 0x28, 6) + CCU_GATE(CLK_APB0_TWD, "apb0-twd", "apb0", 0x28, 7) +}; + +static const char *ar100_parents[] = {"osc32k", "osc24M", "pll_periph0", "iosc"}; +PREDIV_CLK(ar100_clk, CLK_AR100, /* id */ + "ar100", ar100_parents, /* name, parents */ + 0x00, /* offset */ + 16, 2, /* mux */ + 4, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* div */ + 8, 5, 0, AW_CLK_FACTOR_HAS_COND, /* prediv */ + 16, 2, 2); /* prediv condition */ + +static const char *ahb0_parents[] = {"ar100"}; +FIXED_CLK(ahb0_clk, + CLK_AHB0, /* id */ + "ahb0", /* name */ + ahb0_parents, /* parent */ + 0, /* freq */ + 1, /* mult */ + 1, /* div */ + 0); /* flags */ + +static const char *apb0_parents[] = {"ahb0"}; +DIV_CLK(apb0_clk, + CLK_APB0, /* id */ + "apb0", apb0_parents, /* name, parents */ + 0x0c, /* offset */ + 0, 2, /* shift, width */ + 0, NULL); /* flags, div table */ + +static struct aw_clk_prediv_mux_def *prediv_mux_clks[] = { + &ar100_clk, +}; + +static struct clk_div_def *div_clks[] = { + &apb0_clk, +}; + +static struct clk_fixed_def *fixed_factor_clks[] = { + &ahb0_clk, +}; + +void +ccu_sun8i_r_register_clocks(struct aw_ccung_softc *sc) +{ + int i; + + sc->resets = ccu_sun8i_r_resets; + sc->nresets = nitems(ccu_sun8i_r_resets); + sc->gates = ccu_sun8i_r_gates; + sc->ngates = nitems(ccu_sun8i_r_gates); + + for (i = 0; i < nitems(prediv_mux_clks); i++) + aw_clk_prediv_mux_register(sc->clkdom, prediv_mux_clks[i]); + for (i = 0; i < nitems(div_clks); i++) + clknode_div_register(sc->clkdom, div_clks[i]); + for (i = 0; i < nitems(fixed_factor_clks); i++) + clknode_fixed_register(sc->clkdom, fixed_factor_clks[i]); +} diff --git a/sys/boot/arm/at91/boot2/board.h b/sys/arm/allwinner/clkng/ccu_sun8i_r.h similarity index 59% rename from sys/boot/arm/at91/boot2/board.h rename to sys/arm/allwinner/clkng/ccu_sun8i_r.h index 823d871f9e71..10e741640f99 100644 --- a/sys/boot/arm/at91/boot2/board.h +++ b/sys/arm/allwinner/clkng/ccu_sun8i_r.h @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. + * Copyright (c) 2017 Emmanuel Vadot + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -14,16 +15,20 @@ * 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 AUTHOR 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. + * 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. * * $FreeBSD$ */ -void Update(void); -void board_init(void); -int drvread(void *, unsigned, unsigned); +#ifndef __CCU_SUN8I_R_H__ +#define __CCU_SUN8I_R_H__ + +void ccu_sun8i_r_register_clocks(struct aw_ccung_softc *sc); + +#endif /* __CCU_SUN8I_R_H__ */ diff --git a/sys/arm/allwinner/h3/files.h3 b/sys/arm/allwinner/h3/files.h3 index 2b42c78822d9..bce6ca07c553 100644 --- a/sys/arm/allwinner/h3/files.h3 +++ b/sys/arm/allwinner/h3/files.h3 @@ -1,5 +1,6 @@ # $FreeBSD$ arm/allwinner/clkng/ccu_h3.c standard +arm/allwinner/clkng/ccu_sun8i_r.c standard arm/allwinner/h3/h3_padconf.c standard arm/allwinner/h3/h3_r_padconf.c standard diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c index 58c233b59052..d254b37e3cdd 100644 --- a/sys/arm/allwinner/if_awg.c +++ b/sys/arm/allwinner/if_awg.c @@ -92,7 +92,7 @@ __FBSDID("$FreeBSD$"); #define TX_SKIP(n, o) (((n) + (o)) & (TX_DESC_COUNT - 1)) #define RX_NEXT(n) (((n) + 1) & (RX_DESC_COUNT - 1)) -#define TX_MAX_SEGS 10 +#define TX_MAX_SEGS 20 #define SOFT_RST_RETRY 1000 #define MII_BUSY_RETRY 1000 @@ -192,6 +192,7 @@ struct awg_softc { struct resource *res[_RES_NITEMS]; struct mtx mtx; if_t ifp; + device_t dev; device_t miibus; struct callout stat_ch; struct task link_task; @@ -421,14 +422,18 @@ awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp) sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS); - if (m == NULL) + if (m == NULL) { + device_printf(sc->dev, "awg_setup_txbuf: m_collapse failed\n"); return (0); + } *mp = m; error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT); } - if (error != 0) + if (error != 0) { + device_printf(sc->dev, "awg_setup_txbuf: bus_dmamap_load_mbuf_sg failed\n"); return (0); + } bus_dmamap_sync(sc->tx.buf_tag, sc->tx.buf_map[index].map, BUS_DMASYNC_PREWRITE); @@ -1041,10 +1046,10 @@ awg_ioctl(if_t ifp, u_long cmd, caddr_t data) if_togglecapenable(ifp, IFCAP_RXCSUM); if (mask & IFCAP_TXCSUM) if_togglecapenable(ifp, IFCAP_TXCSUM); - if ((if_getcapenable(ifp) & (IFCAP_RXCSUM|IFCAP_TXCSUM)) != 0) - if_sethwassistbits(ifp, CSUM_IP, 0); + if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0) + if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0); else - if_sethwassistbits(ifp, 0, CSUM_IP); + if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP); break; default: error = ether_ioctl(ifp, cmd, data); @@ -1613,6 +1618,7 @@ awg_attach(device_t dev) int error; sc = device_get_softc(dev); + sc->dev = dev; sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; node = ofw_bus_get_node(dev); diff --git a/sys/arm/allwinner/if_awgreg.h b/sys/arm/allwinner/if_awgreg.h index 163ffa491913..0b77c6220a30 100644 --- a/sys/arm/allwinner/if_awgreg.h +++ b/sys/arm/allwinner/if_awgreg.h @@ -115,9 +115,9 @@ #define EMAC_MII_DATA 0x4c #define EMAC_ADDR_HIGH(n) (0x50 + (n) * 8) #define EMAC_ADDR_LOW(n) (0x54 + (n) * 8) -#define EMAC_TX_DMA_STA 0x80 -#define EMAC_TX_DMA_CUR_DESC 0x84 -#define EMAC_TX_DMA_CUR_BUF 0x88 +#define EMAC_TX_DMA_STA 0xb0 +#define EMAC_TX_DMA_CUR_DESC 0xb4 +#define EMAC_TX_DMA_CUR_BUF 0xb8 #define EMAC_RX_DMA_STA 0xc0 #define EMAC_RX_DMA_CUR_DESC 0xc4 #define EMAC_RX_DMA_CUR_BUF 0xc8 diff --git a/sys/arm/allwinner/std.allwinner b/sys/arm/allwinner/std.allwinner index 5a1bf94e474b..360d16932e0d 100644 --- a/sys/arm/allwinner/std.allwinner +++ b/sys/arm/allwinner/std.allwinner @@ -2,7 +2,7 @@ #$FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0200000 diff --git a/sys/arm/allwinner/std.allwinner_up b/sys/arm/allwinner/std.allwinner_up index 6294cd0b461c..0d5661eed558 100644 --- a/sys/arm/allwinner/std.allwinner_up +++ b/sys/arm/allwinner/std.allwinner_up @@ -2,7 +2,7 @@ #$FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0200000 diff --git a/sys/arm/altera/socfpga/std.socfpga b/sys/arm/altera/socfpga/std.socfpga index 687c5a7f7a22..bbfb218da28a 100644 --- a/sys/arm/altera/socfpga/std.socfpga +++ b/sys/arm/altera/socfpga/std.socfpga @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0f00000 diff --git a/sys/arm/amlogic/aml8726/std.aml8726 b/sys/arm/amlogic/aml8726/std.aml8726 index bd1c12e1c417..2a044046d126 100644 --- a/sys/arm/amlogic/aml8726/std.aml8726 +++ b/sys/arm/amlogic/aml8726/std.aml8726 @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" # Physical memory starts at 0x80000000. We assume the kernel is loaded diff --git a/sys/arm/annapurna/alpine/std.alpine b/sys/arm/annapurna/alpine/std.alpine index 002b4ce5fa78..b04821c9c62d 100644 --- a/sys/arm/annapurna/alpine/std.alpine +++ b/sys/arm/annapurna/alpine/std.alpine @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a -DAL_HAVE_TYPES" makeoptions KERNVIRTADDR=0xa0200000 diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c index 5dceab37be00..15efa9fd378b 100644 --- a/sys/arm/arm/cpuinfo.c +++ b/sys/arm/arm/cpuinfo.c @@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #if __ARM_ARCH >= 6 void reinit_mmu(uint32_t ttb, uint32_t aux_clr, uint32_t aux_set); @@ -77,6 +79,9 @@ SYSCTL_INT(_hw_cpu_quirks, OID_AUTO, actlr_set, void cpuinfo_init(void) { +#if __ARM_ARCH >= 6 + uint32_t tmp; +#endif /* * Prematurely fetch CPU quirks. Standard fetch for tunable @@ -190,6 +195,47 @@ cpuinfo_init(void) } cpuinfo.dcache_line_mask = cpuinfo.dcache_line_size - 1; cpuinfo.icache_line_mask = cpuinfo.icache_line_size - 1; + + /* Fill AT_HWCAP bits. */ + elf_hwcap |= HWCAP_HALF | HWCAP_FAST_MULT; /* Required for all CPUs */ + elf_hwcap |= HWCAP_TLS | HWCAP_EDSP; /* Required for v6+ CPUs */ + + tmp = (cpuinfo.id_isar0 >> 24) & 0xF; /* Divide_instrs */ + if (tmp >= 1) + elf_hwcap |= HWCAP_IDIVT; + if (tmp >= 2) + elf_hwcap |= HWCAP_IDIVA; + + tmp = (cpuinfo.id_pfr0 >> 4) & 0xF; /* State1 */ + if (tmp >= 1) + elf_hwcap |= HWCAP_THUMB; + + tmp = (cpuinfo.id_pfr0 >> 12) & 0xF; /* State3 */ + if (tmp >= 1) + elf_hwcap |= HWCAP_THUMBEE; + + tmp = (cpuinfo.id_mmfr0 >> 0) & 0xF; /* VMSA */ + if (tmp >= 5) + elf_hwcap |= HWCAP_LPAE; + + /* Fill AT_HWCAP2 bits. */ + tmp = (cpuinfo.id_isar5 >> 4) & 0xF; /* AES */ + if (tmp >= 1) + elf_hwcap2 |= HWCAP2_AES; + if (tmp >= 2) + elf_hwcap2 |= HWCAP2_PMULL; + + tmp = (cpuinfo.id_isar5 >> 8) & 0xF; /* SHA1 */ + if (tmp >= 1) + elf_hwcap2 |= HWCAP2_SHA1; + + tmp = (cpuinfo.id_isar5 >> 12) & 0xF; /* SHA2 */ + if (tmp >= 1) + elf_hwcap2 |= HWCAP2_SHA2; + + tmp = (cpuinfo.id_isar5 >> 16) & 0xF; /* CRC32 */ + if (tmp >= 1) + elf_hwcap2 |= HWCAP2_CRC32; #endif } diff --git a/sys/arm/arm/disassem.c b/sys/arm/arm/disassem.c index 81dbe1096f2d..3aa94e893fae 100644 --- a/sys/arm/arm/disassem.c +++ b/sys/arm/arm/disassem.c @@ -131,6 +131,7 @@ static const struct arm32_insn arm32_i[] = { { 0x0c500000, 0x04400000, "strb", "daW" }, { 0x0c500000, 0x04500000, "ldrb", "daW" }, #if __ARM_ARCH >= 6 + { 0x0fff0ff0, 0x06bf0fb0, "rev16", "dm" }, { 0xffffffff, 0xf57ff01f, "clrex", "c" }, { 0x0ff00ff0, 0x01800f90, "strex", "dmo" }, { 0x0ff00fff, 0x01900f9f, "ldrex", "do" }, diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index a962ee882e1c..cc8ef9994f0f 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -45,9 +45,15 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef VFP +#include +#endif static boolean_t elf32_arm_abi_supported(struct image_params *); +u_long elf_hwcap; +u_long elf_hwcap2; + struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, @@ -86,6 +92,8 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, + .sv_hwcap = &elf_hwcap, + .sv_hwcap2 = &elf_hwcap2, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); @@ -124,9 +132,19 @@ elf32_arm_abi_supported(struct image_params *imgp) } void -elf32_dump_thread(struct thread *td __unused, void *dst __unused, - size_t *off __unused) +elf32_dump_thread(struct thread *td, void *dst, size_t *off) { +#ifdef VFP + mcontext_vfp_t vfp; + + if (dst != NULL) { + get_vfpcontext(td, &vfp); + *off = elf32_populate_note(NT_ARM_VFP, &vfp, dst, sizeof(vfp), + NULL); + } else + *off = elf32_populate_note(NT_ARM_VFP, NULL, NULL, sizeof(vfp), + NULL); +#endif } /* diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index 4b3e2fc88700..b32692a1e342 100644 --- a/sys/arm/arm/elf_trampoline.c +++ b/sys/arm/arm/elf_trampoline.c @@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$"); #include #include +#if __ARM_ARCH >= 6 +#error "elf_trampline is not supported on ARMv6/v7 platforms" +#endif extern char kernel_start[]; extern char kernel_end[]; @@ -51,8 +54,6 @@ void __start(void); void __startC(unsigned r0, unsigned r1, unsigned r2, unsigned r3); extern unsigned int cpu_ident(void); -extern void armv6_idcache_wbinv_all(void); -extern void armv7_idcache_wbinv_all(void); extern void do_call(void *, void *, void *, int); #define GZ_HEAD 0xa @@ -66,36 +67,23 @@ extern void fa526_idcache_wbinv_all(void); #elif defined(CPU_ARM9E) #define cpu_idcache_wbinv_all armv5_ec_idcache_wbinv_all extern void armv5_ec_idcache_wbinv_all(void); -#elif defined(CPU_ARM1176) -#define cpu_idcache_wbinv_all armv6_idcache_wbinv_all #elif defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) #define cpu_idcache_wbinv_all xscale_cache_purgeID extern void xscale_cache_purgeID(void); #elif defined(CPU_XSCALE_81342) #define cpu_idcache_wbinv_all xscalec3_cache_purgeID extern void xscalec3_cache_purgeID(void); -#elif defined(CPU_MV_PJ4B) -#if !defined(SOC_MV_ARMADAXP) -#define cpu_idcache_wbinv_all armv6_idcache_wbinv_all -extern void armv6_idcache_wbinv_all(void); -#else -#define cpu_idcache_wbinv_all() armadaxp_idcache_wbinv_all #endif -#endif /* CPU_MV_PJ4B */ #ifdef CPU_XSCALE_81342 #define cpu_l2cache_wbinv_all xscalec3_l2cache_purge extern void xscalec3_l2cache_purge(void); #elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) #define cpu_l2cache_wbinv_all sheeva_l2cache_wbinv_all extern void sheeva_l2cache_wbinv_all(void); -#elif defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT) -#define cpu_idcache_wbinv_all armv7_idcache_wbinv_all -#define cpu_l2cache_wbinv_all() #else #define cpu_l2cache_wbinv_all() #endif -static void armadaxp_idcache_wbinv_all(void); int arm_picache_size; int arm_picache_line_size; @@ -389,18 +377,6 @@ arm9_setup(void) arm9_dcache_index_max = 0U - arm9_dcache_index_inc; } -static void -armadaxp_idcache_wbinv_all(void) -{ - uint32_t feat; - - __asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (feat)); - if (feat & ARM_PFR0_THUMBEE_MASK) - armv7_idcache_wbinv_all(); - else - armv6_idcache_wbinv_all(); - -} #ifdef KZIP static unsigned char *orig_input, *i_input, *i_output; diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index e995ee0fcf3c..689f7686d4c9 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -405,42 +405,68 @@ exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) /* * Get machine VFP context. */ -static void +void get_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) { - struct pcb *curpcb; + struct pcb *pcb; - curpcb = curthread->td_pcb; - critical_enter(); - - vfp_store(&curpcb->pcb_vfpstate, false); - memcpy(vfp->mcv_reg, curpcb->pcb_vfpstate.reg, + pcb = td->td_pcb; + if (td == curthread) { + critical_enter(); + vfp_store(&pcb->pcb_vfpstate, false); + critical_exit(); + } else + MPASS(TD_IS_SUSPENDED(td)); + memcpy(vfp->mcv_reg, pcb->pcb_vfpstate.reg, sizeof(vfp->mcv_reg)); - vfp->mcv_fpscr = curpcb->pcb_vfpstate.fpscr; - - critical_exit(); + vfp->mcv_fpscr = pcb->pcb_vfpstate.fpscr; } /* * Set machine VFP context. */ -static void +void set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp) { - struct pcb *curpcb; + struct pcb *pcb; - curpcb = curthread->td_pcb; - critical_enter(); - - vfp_discard(td); - memcpy(curpcb->pcb_vfpstate.reg, vfp->mcv_reg, - sizeof(curpcb->pcb_vfpstate.reg)); - curpcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr; - - critical_exit(); + pcb = td->td_pcb; + if (td == curthread) { + critical_enter(); + vfp_discard(td); + critical_exit(); + } else + MPASS(TD_IS_SUSPENDED(td)); + memcpy(pcb->pcb_vfpstate.reg, vfp->mcv_reg, + sizeof(pcb->pcb_vfpstate.reg)); + pcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr; } #endif +int +arm_get_vfpstate(struct thread *td, void *args) +{ + int rv; + struct arm_get_vfpstate_args ua; + mcontext_vfp_t mcontext_vfp; + + rv = copyin(args, &ua, sizeof(ua)); + if (rv != 0) + return (rv); + if (ua.mc_vfp_size != sizeof(mcontext_vfp_t)) + return (EINVAL); +#ifdef VFP + get_vfpcontext(td, &mcontext_vfp); +#else + bzero(&mcontext_vfp, sizeof(mcontext_vfp)); +#endif + + rv = copyout(&mcontext_vfp, ua.mc_vfp, sizeof(mcontext_vfp)); + if (rv != 0) + return (rv); + return (0); +} + /* * Get machine context. */ diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c index 9fff9fda1d34..c6a0de4483d4 100644 --- a/sys/arm/arm/minidump_machdep.c +++ b/sys/arm/arm/minidump_machdep.c @@ -58,8 +58,6 @@ int vm_page_dump_size; static struct kerneldumpheader kdh; -static off_t dumplo; - /* Handle chunked writes. */ static size_t fragsz; static void *dump_va; @@ -89,8 +87,7 @@ blk_flush(struct dumperinfo *di) if (fragsz == 0) return (0); - error = dump_write(di, dump_va, 0, dumplo, fragsz); - dumplo += fragsz; + error = dump_append(di, dump_va, 0, fragsz); fragsz = 0; return (error); } @@ -141,10 +138,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) wdog_kern_pat(WD_LASTVAL); #endif if (ptr) { - error = dump_write(di, ptr, 0, dumplo, len); + error = dump_append(di, ptr, 0, len); if (error) return (error); - dumplo += len; ptr += len; sz -= len; } else { @@ -251,7 +247,7 @@ minidumpsys(struct dumperinfo *di) printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576); printf("Dumping %llu MB:", (long long)dumpsize >> 20); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -329,7 +325,7 @@ minidumpsys(struct dumperinfo *di) if (error) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 44ced95df92e..cae6948ac36b 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -3165,6 +3165,7 @@ pmap_pv_demote_pte1(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) } while (va < va_last); } +#if VM_NRESERVLEVEL > 0 static void pmap_pv_promote_pte1(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) { @@ -3198,6 +3199,7 @@ pmap_pv_promote_pte1(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) pmap_pvh_free(&m->md, pmap, va); } while (va < va_last); } +#endif /* * Conditionally create a pv entry. @@ -3405,6 +3407,7 @@ pmap_change_pte1(pmap_t pmap, pt1_entry_t *pte1p, vm_offset_t va, } #endif +#if VM_NRESERVLEVEL > 0 /* * Tries to promote the NPTE2_IN_PT2, contiguous 4KB page mappings that are * within a single page table page (PT2) to a single 1MB page mapping. @@ -3532,6 +3535,7 @@ pmap_promote_pte1(pmap_t pmap, pt1_entry_t *pte1p, vm_offset_t va) PDEBUG(6, printf("%s(%p): success for va %#x pte1 %#x(%#x) at %p\n", __func__, pmap, va, npte1, pte1_load(pte1p), pte1p)); } +#endif /* VM_NRESERVLEVEL > 0 */ /* * Zero L2 page table page. @@ -4053,6 +4057,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, va, opte2, npte2); } #endif + +#if VM_NRESERVLEVEL > 0 /* * If both the L2 page table page and the reservation are fully * populated, then attempt promotion. @@ -4061,6 +4067,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, sp_enabled && (m->flags & PG_FICTITIOUS) == 0 && vm_reserv_level_iffullpop(m) == 0) pmap_promote_pte1(pmap, pte1p, va); +#endif sched_unpin(); rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pmap); @@ -6397,6 +6404,22 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) */ PMAP_LOCK(pmap); +#ifdef INVARIANTS + pte1 = pte1_load(pmap_pte1(pmap, far)); + if (pte1_is_link(pte1)) { + /* + * Check in advance that associated L2 page table is mapped into + * PT2MAP space. Note that faulty access to not mapped L2 page + * table is caught in more general check above where "far" is + * checked that it does not lay in PT2MAP space. Note also that + * L1 page table and PT2TAB always exist and are mapped. + */ + pte2 = pt2tab_load(pmap_pt2tab_entry(pmap, far)); + if (!pte2_is_valid(pte2)) + panic("%s: missing L2 page table (%p, %#x)", + __func__, pmap, far); + } +#endif #ifdef SMP /* * Special treatment is due to break-before-make approach done when @@ -6417,10 +6440,23 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) * for aborts from user mode. */ if (idx == FAULT_ACCESS_L2) { - pte2p = pt2map_entry(far); - pte2 = pte2_load(pte2p); - if (pte2_is_valid(pte2)) { - pte2_store(pte2p, pte2 | PTE2_A); + pte1 = pte1_load(pmap_pte1(pmap, far)); + if (pte1_is_link(pte1)) { + /* L2 page table should exist and be mapped. */ + pte2p = pt2map_entry(far); + pte2 = pte2_load(pte2p); + if (pte2_is_valid(pte2)) { + pte2_store(pte2p, pte2 | PTE2_A); + PMAP_UNLOCK(pmap); + return (KERN_SUCCESS); + } + } else { + /* + * We got L2 access fault but PTE1 is not a link. + * Probably some race happened, do nothing. + */ + CTR3(KTR_PMAP, "%s: FAULT_ACCESS_L2 - pmap %#x far %#x", + __func__, pmap, far); PMAP_UNLOCK(pmap); return (KERN_SUCCESS); } @@ -6432,6 +6468,15 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) pte1_store(pte1p, pte1 | PTE1_A); PMAP_UNLOCK(pmap); return (KERN_SUCCESS); + } else { + /* + * We got L1 access fault but PTE1 is not section + * mapping. Probably some race happened, do nothing. + */ + CTR3(KTR_PMAP, "%s: FAULT_ACCESS_L1 - pmap %#x far %#x", + __func__, pmap, far); + PMAP_UNLOCK(pmap); + return (KERN_SUCCESS); } } @@ -6444,12 +6489,25 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) * for aborts from user mode. */ if ((fsr & FSR_WNR) && (idx == FAULT_PERM_L2)) { - pte2p = pt2map_entry(far); - pte2 = pte2_load(pte2p); - if (pte2_is_valid(pte2) && !(pte2 & PTE2_RO) && - (pte2 & PTE2_NM)) { - pte2_store(pte2p, pte2 & ~PTE2_NM); - tlb_flush(trunc_page(far)); + pte1 = pte1_load(pmap_pte1(pmap, far)); + if (pte1_is_link(pte1)) { + /* L2 page table should exist and be mapped. */ + pte2p = pt2map_entry(far); + pte2 = pte2_load(pte2p); + if (pte2_is_valid(pte2) && !(pte2 & PTE2_RO) && + (pte2 & PTE2_NM)) { + pte2_store(pte2p, pte2 & ~PTE2_NM); + tlb_flush(trunc_page(far)); + PMAP_UNLOCK(pmap); + return (KERN_SUCCESS); + } + } else { + /* + * We got L2 permission fault but PTE1 is not a link. + * Probably some race happened, do nothing. + */ + CTR3(KTR_PMAP, "%s: FAULT_PERM_L2 - pmap %#x far %#x", + __func__, pmap, far); PMAP_UNLOCK(pmap); return (KERN_SUCCESS); } @@ -6457,10 +6515,20 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) if ((fsr & FSR_WNR) && (idx == FAULT_PERM_L1)) { pte1p = pmap_pte1(pmap, far); pte1 = pte1_load(pte1p); - if (pte1_is_section(pte1) && !(pte1 & PTE1_RO) && - (pte1 & PTE1_NM)) { - pte1_store(pte1p, pte1 & ~PTE1_NM); - tlb_flush(pte1_trunc(far)); + if (pte1_is_section(pte1)) { + if (!(pte1 & PTE1_RO) && (pte1 & PTE1_NM)) { + pte1_store(pte1p, pte1 & ~PTE1_NM); + tlb_flush(pte1_trunc(far)); + PMAP_UNLOCK(pmap); + return (KERN_SUCCESS); + } + } else { + /* + * We got L1 permission fault but PTE1 is not section + * mapping. Probably some race happened, do nothing. + */ + CTR3(KTR_PMAP, "%s: FAULT_PERM_L1 - pmap %#x far %#x", + __func__, pmap, far); PMAP_UNLOCK(pmap); return (KERN_SUCCESS); } @@ -6471,33 +6539,6 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode) * modify bits aborts, could be moved to ASM. Now we are * starting to deal with not fast aborts. */ - -#ifdef INVARIANTS - /* - * Read an entry in PT2TAB associated with both pmap and far. - * It's safe because PT2TAB is always mapped. - */ - pte2 = pt2tab_load(pmap_pt2tab_entry(pmap, far)); - if (pte2_is_valid(pte2)) { - /* - * Now, when we know that L2 page table is allocated, - * we can use PT2MAP to get L2 page table entry. - */ - pte2 = pte2_load(pt2map_entry(far)); - if (pte2_is_valid(pte2)) { - /* - * If L2 page table entry is valid, make sure that - * L1 page table entry is valid too. Note that we - * leave L2 page entries untouched when promoted. - */ - pte1 = pte1_load(pmap_pte1(pmap, far)); - if (!pte1_is_valid(pte1)) { - panic("%s: missing L1 page entry (%p, %#x)", - __func__, pmap, far); - } - } - } -#endif PMAP_UNLOCK(pmap); return (KERN_FAILURE); } diff --git a/sys/arm/arm/ptrace_machdep.c b/sys/arm/arm/ptrace_machdep.c new file mode 100644 index 000000000000..3a6f2938ab88 --- /dev/null +++ b/sys/arm/arm/ptrace_machdep.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2017 John Baldwin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#ifdef VFP +#include +#endif + +int +cpu_ptrace(struct thread *td, int req, void *addr, int data) +{ +#ifdef VFP + mcontext_vfp_t vfp; +#endif + int error; + + switch (req) { +#ifdef VFP + case PT_GETVFPREGS: + get_vfpcontext(td, &vfp); + error = copyout(&vfp, addr, sizeof(vfp)); + break; + case PT_SETVFPREGS: + error = copyin(addr, &vfp, sizeof(vfp)); + if (error == 0) + set_vfpcontext(td, &vfp); + break; +#endif + default: + error = EINVAL; + } + + return (error); +} diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c index af34e30930b6..c938c0b1f570 100644 --- a/sys/arm/arm/sys_machdep.c +++ b/sys/arm/arm/sys_machdep.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #ifndef _SYS_SYSPROTO_H_ @@ -204,6 +205,7 @@ sysarch(struct thread *td, struct sysarch_args *uap) case ARM_DRAIN_WRITEBUF: case ARM_SET_TP: case ARM_GET_TP: + case ARM_GET_VFPSTATE: break; default: @@ -229,6 +231,9 @@ sysarch(struct thread *td, struct sysarch_args *uap) case ARM_GET_TP: error = arm32_get_tp(td, uap->parms); break; + case ARM_GET_VFPSTATE: + error = arm_get_vfpstate(td, uap->parms); + break; default: error = EINVAL; break; diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c index 5a403a692c0c..7e3e728ce1d2 100644 --- a/sys/arm/arm/vfp.c +++ b/sys/arm/arm/vfp.c @@ -33,9 +33,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include @@ -115,6 +117,7 @@ vfp_init(void) vfp_exists = 1; is_d32 = 0; PCPU_SET(vfpsid, fpsid); /* save the fpsid */ + elf_hwcap |= HWCAP_VFP; vfp_arch = (fpsid & VFPSID_SUBVERSION2_MASK) >> VFPSID_SUBVERSION_OFF; @@ -122,9 +125,13 @@ vfp_init(void) if (vfp_arch >= VFP_ARCH3) { tmp = fmrx(mvfr0); PCPU_SET(vfpmvfr0, tmp); + elf_hwcap |= HWCAP_VFPv3; - if ((tmp & VMVFR0_RB_MASK) == 2) + if ((tmp & VMVFR0_RB_MASK) == 2) { + elf_hwcap |= HWCAP_VFPD32; is_d32 = 1; + } else + elf_hwcap |= HWCAP_VFPv3D16; tmp = fmrx(mvfr1); PCPU_SET(vfpmvfr1, tmp); @@ -137,6 +144,13 @@ vfp_init(void) initial_fpscr; } } + + if ((tmp & VMVFR1_LS_MASK) >> VMVFR1_LS_OFF == 1 && + (tmp & VMVFR1_I_MASK) >> VMVFR1_I_OFF == 1 && + (tmp & VMVFR1_SP_MASK) >> VMVFR1_SP_OFF == 1) + elf_hwcap |= HWCAP_NEON; + if ((tmp & VMVFR1_FMAC_MASK) >> VMVFR1_FMAC_OFF == 1) + elf_hwcap |= HWCAP_VFPv4; } /* initialize the coprocess 10 and 11 calls diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c index 8c21aad0ec04..155fb84d1a77 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c @@ -2,6 +2,7 @@ * Copyright (c) 2001 Tsubai Masanari. * Copyright (c) 2012 Oleksandr Tymoshenko * Copyright (c) 2013 Luiz Otavio O Souza + * Copyright (c) 2017 Ian Lepore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +30,57 @@ #include __FBSDID("$FreeBSD$"); +/* + * Driver for bcm2835 i2c-compatible two-wire bus, named 'BSC' on this SoC. + * + * This controller can only perform complete transfers, it does not provide + * low-level control over sending start/repeat-start/stop sequences on the bus. + * In addition, bugs in the silicon make it somewhat difficult to perform a + * repeat-start, and limit the repeat-start to a read following a write on + * the same slave device. (The i2c protocol allows a repeat start to change + * direction or not, and change slave address or not at any time.) + * + * The repeat-start bug and workaround are described in a problem report at + * https://github.com/raspberrypi/linux/issues/254 with the crucial part being + * in a comment block from a fragment of a GPU i2c driver, containing this: + * + * ----------------------------------------------------------------------------- + * - See i2c.v: The I2C peripheral samples the values for rw_bit and xfer_count + * - in the IDLE state if start is set. + * - + * - We want to generate a ReSTART not a STOP at the end of the TX phase. In + * - order to do that we must ensure the state machine goes RACK1 -> RACK2 -> + * - SRSTRT1 (not RACK1 -> RACK2 -> SSTOP1). + * - + * - So, in the RACK2 state when (TX) xfer_count==0 we must therefore have + * - already set, ready to be sampled: + * - READ ; rw_bit <= I2CC bit 0 -- must be "read" + * - ST; start <= I2CC bit 7 -- must be "Go" in order to not issue STOP + * - DLEN; xfer_count <= I2CDLEN -- must be equal to our read amount + * - + * - The plan to do this is: + * - 1. Start the sub-address write, but don't let it finish + * - (keep xfer_count > 0) + * - 2. Populate READ, DLEN and ST in preparation for ReSTART read sequence + * - 3. Let TX finish (write the rest of the data) + * - 4. Read back data as it arrives + * ----------------------------------------------------------------------------- + * + * The transfer function below scans the list of messages passed to it, looking + * for a read following a write to the same slave. When it finds that, it + * starts the write without prefilling the tx fifo, which holds xfer_count>0, + * then presets the direction, length, and start command for the following read, + * as described above. Then the tx fifo is filled and the rest of the transfer + * proceeds as normal, with the controller automatically supplying a + * repeat-start on the bus when the write operation finishes. + * + * XXX I suspect the controller may be able to do a repeat-start on any + * write->read or write->write transition, even when the slave addresses differ. + * It's unclear whether the slave address can be prestaged along with the + * direction and length while the write xfer_count is being held at zero. In + * fact, if it can't do this, then it couldn't be used to read EDID data. + */ + #include #include #include @@ -59,6 +111,14 @@ static struct ofw_compat_data compat_data[] = { {NULL, 0} }; +#define DEVICE_DEBUGF(sc, lvl, fmt, args...) \ + if ((lvl) <= (sc)->sc_debug) \ + device_printf((sc)->sc_dev, fmt, ##args) + +#define DEBUGF(sc, lvl, fmt, args...) \ + if ((lvl) <= (sc)->sc_debug) \ + printf(fmt, ##args) + static void bcm_bsc_intr(void *); static int bcm_bsc_detach(device_t); @@ -198,6 +258,9 @@ bcm_bsc_sysctl_init(struct bcm_bsc_softc *sc) SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "rise_edge_delay", CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), bcm_bsc_rise_proc, "IU", "I2C BUS rising edge delay"); + SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "debug", + CTLFLAG_RWTUN, &sc->sc_debug, 0, + "Enable debug; 1=reads/writes, 2=add starts/stops"); } static void @@ -323,6 +386,8 @@ bcm_bsc_detach(device_t dev) bus_generic_detach(dev); sc = device_get_softc(dev); + if (sc->sc_iicbus != NULL) + device_delete_child(dev, sc->sc_iicbus); mtx_destroy(&sc->sc_mtx); if (sc->sc_intrhand) bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); @@ -334,6 +399,76 @@ bcm_bsc_detach(device_t dev) return (0); } +static void +bcm_bsc_empty_rx_fifo(struct bcm_bsc_softc *sc) +{ + uint32_t status; + + /* Assumes sc_totlen > 0 and BCM_BSC_STATUS_RXD is asserted on entry. */ + do { + if (sc->sc_resid == 0) { + sc->sc_data = sc->sc_curmsg->buf; + sc->sc_dlen = sc->sc_curmsg->len; + sc->sc_resid = sc->sc_dlen; + ++sc->sc_curmsg; + } + do { + *sc->sc_data = BCM_BSC_READ(sc, BCM_BSC_DATA); + DEBUGF(sc, 1, "0x%02x ", *sc->sc_data); + ++sc->sc_data; + --sc->sc_resid; + --sc->sc_totlen; + status = BCM_BSC_READ(sc, BCM_BSC_STATUS); + } while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_RXD)); + } while (sc->sc_totlen > 0 && (status & BCM_BSC_STATUS_RXD)); +} + +static void +bcm_bsc_fill_tx_fifo(struct bcm_bsc_softc *sc) +{ + uint32_t status; + + /* Assumes sc_totlen > 0 and BCM_BSC_STATUS_TXD is asserted on entry. */ + do { + if (sc->sc_resid == 0) { + sc->sc_data = sc->sc_curmsg->buf; + sc->sc_dlen = sc->sc_curmsg->len; + sc->sc_resid = sc->sc_dlen; + ++sc->sc_curmsg; + } + do { + BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data); + DEBUGF(sc, 1, "0x%02x ", *sc->sc_data); + ++sc->sc_data; + --sc->sc_resid; + --sc->sc_totlen; + status = BCM_BSC_READ(sc, BCM_BSC_STATUS); + } while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_TXD)); + /* + * If a repeat-start was pending and we just hit the end of a tx + * buffer, see if it's also the end of the writes that preceeded + * the repeat-start. If so, log the repeat-start and the start + * of the following read, and return because we're not writing + * anymore (and TXD will be true because there's room to write + * in the fifo). + */ + if (sc->sc_replen > 0 && sc->sc_resid == 0) { + sc->sc_replen -= sc->sc_dlen; + if (sc->sc_replen == 0) { + DEBUGF(sc, 1, " err=0\n"); + DEVICE_DEBUGF(sc, 2, "rstart 0x%02x\n", + sc->sc_curmsg->slave | 0x01); + DEVICE_DEBUGF(sc, 1, + "read 0x%02x len %d: ", + sc->sc_curmsg->slave | 0x01, + sc->sc_totlen); + sc->sc_flags |= BCM_I2C_READ; + return; + } + } + } while (sc->sc_totlen > 0 && (status & BCM_BSC_STATUS_TXD)); +} + static void bcm_bsc_intr(void *arg) { @@ -351,35 +486,28 @@ bcm_bsc_intr(void *arg) } status = BCM_BSC_READ(sc, BCM_BSC_STATUS); + DEBUGF(sc, 4, " ", status); - /* Check for errors. */ - if (status & (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR)) { + /* RXD and DONE can assert together, empty fifo before checking done. */ + if ((sc->sc_flags & BCM_I2C_READ) && (status & BCM_BSC_STATUS_RXD)) + bcm_bsc_empty_rx_fifo(sc); + + /* Check for completion. */ + if (status & (BCM_BSC_STATUS_ERRBITS | BCM_BSC_STATUS_DONE)) { + sc->sc_flags |= BCM_I2C_DONE; + if (status & BCM_BSC_STATUS_ERRBITS) + sc->sc_flags |= BCM_I2C_ERROR; /* Disable interrupts. */ bcm_bsc_reset(sc); - sc->sc_flags |= BCM_I2C_ERROR; - wakeup(sc->sc_dev); - BCM_BSC_UNLOCK(sc); - return; - } - - if (sc->sc_flags & BCM_I2C_READ) { - while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_RXD)) { - *sc->sc_data++ = BCM_BSC_READ(sc, BCM_BSC_DATA); - sc->sc_resid--; - status = BCM_BSC_READ(sc, BCM_BSC_STATUS); - } - } else { - while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_TXD)) { - BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data++); - sc->sc_resid--; - status = BCM_BSC_READ(sc, BCM_BSC_STATUS); - } - } - - if (status & BCM_BSC_STATUS_DONE) { - /* Disable interrupts. */ - bcm_bsc_reset(sc); - wakeup(sc->sc_dev); + wakeup(sc); + } else if (!(sc->sc_flags & BCM_I2C_READ)) { + /* + * Don't check for TXD until after determining whether the + * transfer is complete; TXD will be asserted along with ERR or + * DONE if there is room in the fifo. + */ + if (status & BCM_BSC_STATUS_TXD) + bcm_bsc_fill_tx_fifo(sc); } BCM_BSC_UNLOCK(sc); @@ -389,8 +517,11 @@ static int bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) { struct bcm_bsc_softc *sc; - uint32_t intr, read, status; - int i, err; + struct iic_msg *endmsgs, *nxtmsg; + uint32_t readctl, status; + int err; + uint16_t curlen; + uint8_t curisread, curslave, nxtisread, nxtslave; sc = device_get_softc(dev); BCM_BSC_LOCK(sc); @@ -402,54 +533,157 @@ bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) /* Now we have control over the BSC controller. */ sc->sc_flags = BCM_I2C_BUSY; + DEVICE_DEBUGF(sc, 3, "Transfer %d msgs\n", nmsgs); + /* Clear the FIFO and the pending interrupts. */ bcm_bsc_reset(sc); + /* + * Perform all the transfers requested in the array of msgs. Note that + * it is bcm_bsc_empty_rx_fifo() and bcm_bsc_fill_tx_fifo() that advance + * sc->sc_curmsg through the array of messages, as the data from each + * message is fully consumed, but it is this loop that notices when we + * have no more messages to process. + */ err = 0; - for (i = 0; i < nmsgs; i++) { + sc->sc_resid = 0; + sc->sc_curmsg = msgs; + endmsgs = &msgs[nmsgs]; + while (sc->sc_curmsg < endmsgs) { + readctl = 0; + curslave = sc->sc_curmsg->slave >> 1; + curisread = sc->sc_curmsg->flags & IIC_M_RD; + sc->sc_replen = 0; + sc->sc_totlen = sc->sc_curmsg->len; + /* + * Scan for scatter/gather IO (same slave and direction) or + * repeat-start (read following write for the same slave). + */ + for (nxtmsg = sc->sc_curmsg + 1; nxtmsg < endmsgs; ++nxtmsg) { + nxtslave = nxtmsg->slave >> 1; + if (curslave == nxtslave) { + nxtisread = nxtmsg->flags & IIC_M_RD; + if (curisread == nxtisread) { + /* + * Same slave and direction, this + * message will be part of the same + * transfer as the previous one. + */ + sc->sc_totlen += nxtmsg->len; + continue; + } else if (curisread == IIC_M_WR) { + /* + * Read after write to same slave means + * repeat-start, remember how many bytes + * come before the repeat-start, switch + * the direction to IIC_M_RD, and gather + * up following reads to the same slave. + */ + curisread = IIC_M_RD; + sc->sc_replen = sc->sc_totlen; + sc->sc_totlen += nxtmsg->len; + continue; + } + } + break; + } + + /* + * curslave and curisread temporaries from above may refer to + * the after-repstart msg, reset them to reflect sc_curmsg. + */ + curisread = (sc->sc_curmsg->flags & IIC_M_RD) ? 1 : 0; + curslave = sc->sc_curmsg->slave | curisread; /* Write the slave address. */ - BCM_BSC_WRITE(sc, BCM_BSC_SLAVE, msgs[i].slave >> 1); + BCM_BSC_WRITE(sc, BCM_BSC_SLAVE, curslave >> 1); - /* Write the data length. */ - BCM_BSC_WRITE(sc, BCM_BSC_DLEN, msgs[i].len); + DEVICE_DEBUGF(sc, 2, "start 0x%02x\n", curslave); - sc->sc_data = msgs[i].buf; - sc->sc_resid = msgs[i].len; - if ((msgs[i].flags & IIC_M_RD) == 0) { - /* Fill up the TX FIFO. */ - status = BCM_BSC_READ(sc, BCM_BSC_STATUS); - while (sc->sc_resid > 0 && - (status & BCM_BSC_STATUS_TXD)) { - BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data); - sc->sc_data++; - sc->sc_resid--; - status = BCM_BSC_READ(sc, BCM_BSC_STATUS); + /* + * Either set up read length and direction variables for a + * simple transfer or get the hardware started on the first + * piece of a transfer that involves a repeat-start and set up + * the read length and direction vars for the second piece. + */ + if (sc->sc_replen == 0) { + DEVICE_DEBUGF(sc, 1, "%-6s 0x%02x len %d: ", + (curisread) ? "readctl" : "write", curslave, + sc->sc_totlen); + curlen = sc->sc_totlen; + if (curisread) { + readctl = BCM_BSC_CTRL_READ; + sc->sc_flags |= BCM_I2C_READ; + } else { + readctl = 0; + sc->sc_flags &= ~BCM_I2C_READ; } - read = 0; - intr = BCM_BSC_CTRL_INTT; - sc->sc_flags &= ~BCM_I2C_READ; } else { - sc->sc_flags |= BCM_I2C_READ; - read = BCM_BSC_CTRL_READ; - intr = BCM_BSC_CTRL_INTR; - } - intr |= BCM_BSC_CTRL_INTD; + DEVICE_DEBUGF(sc, 1, "%-6s 0x%02x len %d: ", + (curisread) ? "readctl" : "write", curslave, + sc->sc_replen); - /* Start the transfer. */ - BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN | - BCM_BSC_CTRL_ST | read | intr); + /* + * Start the write transfer with an empty fifo and wait + * for the 'transfer active' status bit to light up; + * that indicates that the hardware has latched the + * direction and length for the write, and we can safely + * reload those registers and issue the start for the + * following read; interrupts are not enabled here. + */ + BCM_BSC_WRITE(sc, BCM_BSC_DLEN, sc->sc_replen); + BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN | + BCM_BSC_CTRL_ST); + do { + status = BCM_BSC_READ(sc, BCM_BSC_STATUS); + if (status & BCM_BSC_STATUS_ERR) { + /* no ACK on slave addr */ + err = EIO; + goto xfer_done; + } + } while ((status & BCM_BSC_STATUS_TA) == 0); + /* + * Set curlen and readctl for the repeat-start read that + * we need to set up below, but set sc_flags to write, + * because that is the operation in progress right now. + */ + curlen = sc->sc_totlen - sc->sc_replen; + readctl = BCM_BSC_CTRL_READ; + sc->sc_flags &= ~BCM_I2C_READ; + } + + /* + * Start the transfer with interrupts enabled, then if doing a + * write, fill the tx fifo. Not prefilling the fifo until after + * this start command is the key workaround for making + * repeat-start work, and it's harmless to do it in this order + * for a regular write too. + */ + BCM_BSC_WRITE(sc, BCM_BSC_DLEN, curlen); + BCM_BSC_WRITE(sc, BCM_BSC_CTRL, readctl | BCM_BSC_CTRL_I2CEN | + BCM_BSC_CTRL_ST | BCM_BSC_CTRL_INT_ALL); + + if (!(sc->sc_curmsg->flags & IIC_M_RD)) { + bcm_bsc_fill_tx_fifo(sc); + } /* Wait for the transaction to complete. */ - err = mtx_sleep(dev, &sc->sc_mtx, 0, "bsciow", hz); - + while (err == 0 && !(sc->sc_flags & BCM_I2C_DONE)) { + err = mtx_sleep(sc, &sc->sc_mtx, 0, "bsciow", hz); + } /* Check for errors. */ if (err == 0 && (sc->sc_flags & BCM_I2C_ERROR)) err = EIO; +xfer_done: + DEBUGF(sc, 1, " err=%d\n", err); + DEVICE_DEBUGF(sc, 2, "stop\n"); if (err != 0) break; } + /* Disable interrupts, clean fifo, etc. */ + bcm_bsc_reset(sc); + /* Clean the controller flags. */ sc->sc_flags = 0; diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h b/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h index d48ce378a8e4..48b31b645d91 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h +++ b/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h @@ -40,6 +40,9 @@ #define BCM_BSC_CTRL_CLEAR1 (1 << 5) #define BCM_BSC_CTRL_CLEAR0 (1 << 4) #define BCM_BSC_CTRL_READ (1 << 0) +#define BCM_BSC_CTRL_INT_ALL \ + (BCM_BSC_CTRL_INTR | BCM_BSC_CTRL_INTT | BCM_BSC_CTRL_INTD) + #define BCM_BSC_STATUS 0x04 #define BCM_BSC_STATUS_CLKT (1 << 9) #define BCM_BSC_STATUS_ERR (1 << 8) @@ -51,6 +54,9 @@ #define BCM_BSC_STATUS_TXW (1 << 2) #define BCM_BSC_STATUS_DONE (1 << 1) #define BCM_BSC_STATUS_TA (1 << 0) +#define BCM_BSC_STATUS_ERRBITS \ + (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR) + #define BCM_BSC_DLEN 0x08 #define BCM_BSC_SLAVE 0x0c #define BCM_BSC_DATA 0x10 diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h b/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h index 6b31dc3cc7a0..77974854f4c3 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h +++ b/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h @@ -40,23 +40,31 @@ struct { }; #define BCM_BSC_BASE_MASK 0x00ffffff +struct iic_msg; + struct bcm_bsc_softc { device_t sc_dev; device_t sc_iicbus; struct mtx sc_mtx; struct resource * sc_mem_res; struct resource * sc_irq_res; + void * sc_intrhand; + struct iic_msg * sc_curmsg; bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; + int sc_debug; + uint16_t sc_replen; + uint16_t sc_totlen; uint16_t sc_resid; - uint8_t *sc_data; + uint16_t sc_dlen; + uint8_t * sc_data; uint8_t sc_flags; - void * sc_intrhand; }; #define BCM_I2C_BUSY 0x01 #define BCM_I2C_READ 0x02 #define BCM_I2C_ERROR 0x04 +#define BCM_I2C_DONE 0x08 #define BCM_BSC_WRITE(_sc, _off, _val) \ bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c index a29a1c148054..61a1cc8e19ca 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c @@ -133,7 +133,8 @@ static platform_method_t bcm2835_methods[] = { PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(bcm2835, "bcm2835", 0, "raspberrypi,model-b", 100); +FDT_PLATFORM_DEF2(bcm2835, bcm2835_legacy, "bcm2835 (legacy)", 0, "raspberrypi,model-b", 100); +FDT_PLATFORM_DEF2(bcm2835, bcm2835, "bcm2835", 0, "brcm,bcm2835", 100); #endif #ifdef SOC_BCM2836 @@ -149,5 +150,6 @@ static platform_method_t bcm2836_methods[] = { PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(bcm2836, "bcm2836", 0, "brcm,bcm2709", 100); +FDT_PLATFORM_DEF2(bcm2836, bcm2836_legacy, "bcm2836 (legacy)", 0, "brcm,bcm2709", 100); +FDT_PLATFORM_DEF2(bcm2836, bcm2836, "bcm2836", 0, "brcm,bcm2836", 100); #endif diff --git a/sys/arm/broadcom/bcm2835/bcm2835_rng.c b/sys/arm/broadcom/bcm2835/bcm2835_rng.c index 49d6992952c7..dea1aa0f735a 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_rng.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_rng.c @@ -109,6 +109,12 @@ struct bcm2835_rng_softc { long sc_underrun; }; +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-rng", 1}, + {"brcm,bcm2835-rng", 1}, + {NULL, 0} +}; + static __inline void bcm2835_rng_stat_inc_underrun(struct bcm2835_rng_softc *sc) { @@ -364,7 +370,7 @@ bcm2835_rng_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-rng")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Broadcom BCM2835 RNG"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 0471d42ad452..e39d4e6445b3 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -255,11 +255,7 @@ bcm_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); -#ifdef MMCCAM - sdhci_cam_start_slot(&sc->sc_slot); -#else sdhci_start_slot(&sc->sc_slot); -#endif return (0); @@ -685,4 +681,6 @@ static driver_t bcm_sdhci_driver = { DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, NULL, NULL); MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1); +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_bcm); +#endif diff --git a/sys/arm/broadcom/bcm2835/std.bcm2836 b/sys/arm/broadcom/bcm2835/std.bcm2836 index 789450f4fab9..74accfe46bf2 100644 --- a/sys/arm/broadcom/bcm2835/std.bcm2836 +++ b/sys/arm/broadcom/bcm2835/std.bcm2836 @@ -1,6 +1,6 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 cpu CPU_CORTEXA makeoptions CONF_CFLAGS="-march=armv7a" options SOC_BCM2836 diff --git a/sys/arm/conf/ALLWINNER_UP b/sys/arm/conf/ALLWINNER_UP index 3c2384a823b9..e136a873258c 100644 --- a/sys/arm/conf/ALLWINNER_UP +++ b/sys/arm/conf/ALLWINNER_UP @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ ident ALLWINNER_UP -include "std.armv6" +include "std.armv7" include "../allwinner/std.allwinner_up" options INTRNG diff --git a/sys/arm/conf/ALPINE b/sys/arm/conf/ALPINE index bb64740b56f9..52fc49c7b16a 100644 --- a/sys/arm/conf/ALPINE +++ b/sys/arm/conf/ALPINE @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -19,7 +19,7 @@ ident ALPINE -include "std.armv6" +include "std.armv7" include "../annapurna/alpine/std.alpine" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/AML8726 b/sys/arm/conf/AML8726 index 267e3075af67..12204dbdc841 100644 --- a/sys/arm/conf/AML8726 +++ b/sys/arm/conf/AML8726 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -23,7 +23,7 @@ ident AML8726 -include "std.armv6" +include "std.armv7" include "../amlogic/aml8726/std.aml8726" options SCHED_ULE # ULE scheduler diff --git a/sys/arm/conf/APALIS-IMX6 b/sys/arm/conf/APALIS-IMX6 index ce8a0d5221a1..9b5886216ada 100644 --- a/sys/arm/conf/APALIS-IMX6 +++ b/sys/arm/conf/APALIS-IMX6 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/ARMADA38X b/sys/arm/conf/ARMADA38X index 7134f8832809..abc8a96fec02 100644 --- a/sys/arm/conf/ARMADA38X +++ b/sys/arm/conf/ARMADA38X @@ -5,7 +5,7 @@ # include "../mv/armada38x/std.armada38x" -include "std.armv6" +include "std.armv7" ident ARMADA38X diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP index 7e36f13126a0..0aad3a5c437d 100644 --- a/sys/arm/conf/ARMADAXP +++ b/sys/arm/conf/ARMADAXP @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -23,7 +23,7 @@ ident MV-88F78XX0 -include "std.armv6" +include "std.armv7" include "../mv/armadaxp/std.mv78x60" options SOC_MV_ARMADAXP diff --git a/sys/arm/conf/ARNDALE b/sys/arm/conf/ARNDALE index 1c16d131cfca..84ccf12342a5 100644 --- a/sys/arm/conf/ARNDALE +++ b/sys/arm/conf/ARNDALE @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/ARNDALE-OCTA b/sys/arm/conf/ARNDALE-OCTA index a4faaa0387c8..0b42adada3a9 100644 --- a/sys/arm/conf/ARNDALE-OCTA +++ b/sys/arm/conf/ARNDALE-OCTA @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA index e9f71ccfe623..958e1286ba27 100644 --- a/sys/arm/conf/AVILA +++ b/sys/arm/conf/AVILA @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index fec1f2859a61..eba7e1957e33 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -7,11 +7,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -23,7 +23,7 @@ ident BEAGLEBONE -include "std.armv6" +include "std.armv7" include "../ti/am335x/std.am335x" makeoptions MODULES_EXTRA="dtb/am335x am335x_dmtpps" diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT index b06daebd3a85..88e1698742c8 100644 --- a/sys/arm/conf/BWCT +++ b/sys/arm/conf/BWCT @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA index 8f1881d40a86..5f15c13ff3d0 100644 --- a/sys/arm/conf/CAMBRIA +++ b/sys/arm/conf/CAMBRIA @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CHROMEBOOK b/sys/arm/conf/CHROMEBOOK index 059f24344f4b..302a67a1a1a8 100644 --- a/sys/arm/conf/CHROMEBOOK +++ b/sys/arm/conf/CHROMEBOOK @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CHROMEBOOK-PEACH-PIT b/sys/arm/conf/CHROMEBOOK-PEACH-PIT index 87284c2eff90..005055a973cb 100644 --- a/sys/arm/conf/CHROMEBOOK-PEACH-PIT +++ b/sys/arm/conf/CHROMEBOOK-PEACH-PIT @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CHROMEBOOK-SNOW b/sys/arm/conf/CHROMEBOOK-SNOW index aee3dc07b5d9..fad11490f8d8 100644 --- a/sys/arm/conf/CHROMEBOOK-SNOW +++ b/sys/arm/conf/CHROMEBOOK-SNOW @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CHROMEBOOK-SPRING b/sys/arm/conf/CHROMEBOOK-SPRING index 9714d3402ca4..921eb8acf314 100644 --- a/sys/arm/conf/CHROMEBOOK-SPRING +++ b/sys/arm/conf/CHROMEBOOK-SPRING @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS index d7cd496c071f..e1b70922b474 100644 --- a/sys/arm/conf/CNS11XXNAS +++ b/sys/arm/conf/CNS11XXNAS @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/COLIBRI-VF50 b/sys/arm/conf/COLIBRI-VF50 index 81581f6bf842..86dcb0b9ef73 100644 --- a/sys/arm/conf/COLIBRI-VF50 +++ b/sys/arm/conf/COLIBRI-VF50 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/COSMIC b/sys/arm/conf/COSMIC index 61b99a743d33..cd49dbc5b050 100644 --- a/sys/arm/conf/COSMIC +++ b/sys/arm/conf/COSMIC @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB index 3970c551e78a..2256ff7a6d06 100644 --- a/sys/arm/conf/CRB +++ b/sys/arm/conf/CRB @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index 9af5ec34efdf..4dd595507285 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -3,11 +3,11 @@ # # $FreeBSD$ # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index e7c32f923d0f..c43d295bcd93 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -6,11 +6,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/EB9200 b/sys/arm/conf/EB9200 index 23e364fdbb09..c1ec0f598e3d 100644 --- a/sys/arm/conf/EB9200 +++ b/sys/arm/conf/EB9200 @@ -3,7 +3,7 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index a77a5a8eb1c6..a26d107bfb1c 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ ident EFIKA_MX -include "std.armv6" +include "std.armv7" include "../freescale/imx/std.imx51" makeoptions WITHOUT_MODULES="ahc" diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5 index 9e84a623bddf..e3041c294116 100644 --- a/sys/arm/conf/ETHERNUT5 +++ b/sys/arm/conf/ETHERNUT5 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index 5bfc9c792265..9edf62b1ff5d 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ makeoptions WERROR="-Werror" -include "std.armv6" +include "std.armv7" options SCHED_ULE # ULE scheduler options PLATFORM # Platform based SoC options PREEMPTION # Enable kernel thread preemption diff --git a/sys/arm/conf/EXYNOS5250 b/sys/arm/conf/EXYNOS5250 index e22239f41fcf..31f7ac916d6d 100644 --- a/sys/arm/conf/EXYNOS5250 +++ b/sys/arm/conf/EXYNOS5250 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/EXYNOS5420 b/sys/arm/conf/EXYNOS5420 index b55151a7c949..cfad83c9e8d1 100644 --- a/sys/arm/conf/EXYNOS5420 +++ b/sys/arm/conf/EXYNOS5420 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 05187c922e89..e48cc57ce309 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -22,13 +22,13 @@ ident GENERIC cpu CPU_CORTEXA options SMP_ON_UP -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0000000 options KERNVIRTADDR=0xc0000000 -include "std.armv6" +include "std.armv7" files "../allwinner/files.allwinner" files "../allwinner/files.allwinner_up" files "../allwinner/a10/files.a10" @@ -40,11 +40,13 @@ files "../allwinner/a83t/files.a83t" files "../allwinner/h3/files.h3" files "../broadcom/bcm2835/files.bcm2836" files "../broadcom/bcm2835/files.bcm283x" +files "../freescale/imx/files.imx6" files "../nvidia/tegra124/files.tegra124" files "../qemu/files.qemu" files "../ti/files.ti" files "../ti/am335x/files.am335x" files "../ti/omap4/files.omap4" +files "../xilinx/files.zynq7" options SOC_ALLWINNER_A10 options SOC_ALLWINNER_A13 @@ -97,6 +99,7 @@ device ahci # AHCI-compatible SATA controllers # PCI options NEW_PCIB device pci +device pci_host_generic # PCI NICs device re # RealTek 8139C+/8169/8169S/8110S @@ -104,6 +107,7 @@ device re # RealTek 8139C+/8169/8169S/8110S # VirtIO device virtio device virtio_mmio +device virtio_pci device virtio_blk device vtnet @@ -116,6 +120,7 @@ device pty device snp device md # Memory "disks" device random # Entropy device +device firmware # firmware assist module device pl310 # PL310 L2 cache controller device psci @@ -128,6 +133,7 @@ device p2wi # Allwinner Push-Pull Two Wire device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc +device fsliic # Freescale i2c/iic device icee # AT24Cxxx and compatible EEPROMs device sy8106a # SY8106A Buck Regulator device ti_i2c @@ -171,6 +177,7 @@ device ti_adc # reboot automatically because the boot loader might have enabled the # watchdog. device ti_wdt +device imxwdt # Watchdog. WARNING: can't be disabled!!! device scbus # SCSI bus (required for ATA/SCSI) device da # Direct Access (disks) @@ -186,6 +193,7 @@ device ehci device dwcotg # DWC OTG controller device musb +device axe # USB-Ethernet device umass # Disks/Mass storage - Requires scbus and da device uhid # "Human Interface Devices" device ukbd # Allow keyboard like HIDs to control console @@ -205,8 +213,10 @@ device miibus device awg # 10/100/1000 integrated EMAC controller device cpsw # TI Common Platform Ethernet Switch (CPSW) +device cgem # Zynq-7000 gig ethernet device device dwc # 10/100/1000 integrated GMAC controller device emac # 10/100 integrated EMAC controller +device ffec # Freescale Fast Ethernet Controller device smsc # SMSC LAN91C111 # Sound support @@ -230,6 +240,7 @@ device ti_pruss device ti_mbox # DMA controller +device fslsdma device ti_sdma # Extensible Firmware Interface @@ -237,4 +248,4 @@ options EFI # Flattened Device Tree options FDT # Configure using FDT/DTB data -makeoptions MODULES_EXTRA="dtb/allwinner dtb/am335x dtb/nvidia dtb/rpi dtb/omap4" +makeoptions MODULES_EXTRA="dtb/allwinner dtb/am335x dtb/imx6 dtb/nvidia dtb/rpi dtb/zynq dtb/omap4" diff --git a/sys/arm/conf/GENERIC-NODEBUG b/sys/arm/conf/GENERIC-NODEBUG index d545889b6b11..f4bc4ac86d8b 100644 --- a/sys/arm/conf/GENERIC-NODEBUG +++ b/sys/arm/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX index 34e51e608e79..a6db12e51fef 100644 --- a/sys/arm/conf/GUMSTIX +++ b/sys/arm/conf/GUMSTIX @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/GUMSTIX-QEMU b/sys/arm/conf/GUMSTIX-QEMU index 17d2f6ed4803..2152da747e55 100644 --- a/sys/arm/conf/GUMSTIX-QEMU +++ b/sys/arm/conf/GUMSTIX-QEMU @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200 index 1b38af94f6cf..c6ebabf689c9 100644 --- a/sys/arm/conf/HL200 +++ b/sys/arm/conf/HL200 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201 index cbf7cb00c981..d527adafe1cd 100644 --- a/sys/arm/conf/HL201 +++ b/sys/arm/conf/HL201 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index 0cf6205fe7f3..4013ab704a85 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ ident IMX53 -include "std.armv6" +include "std.armv7" include "../freescale/imx/std.imx53" options SOC_IMX53 diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 25f8b0777e27..b5f0c530c15a 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -19,7 +19,7 @@ # $FreeBSD$ ident IMX6 -include "std.armv6" +include "std.armv7" include "../freescale/imx/std.imx6" options INTRNG diff --git a/sys/arm/conf/JETSON-TK1 b/sys/arm/conf/JETSON-TK1 index 242e83509e63..b12186d91c2c 100644 --- a/sys/arm/conf/JETSON-TK1 +++ b/sys/arm/conf/JETSON-TK1 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X index 7d347b973708..aefc530b591c 100644 --- a/sys/arm/conf/KB920X +++ b/sys/arm/conf/KB920X @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU index b6837d9a4c37..b1e9d669ddd7 100644 --- a/sys/arm/conf/NSLU +++ b/sys/arm/conf/NSLU @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/ODROIDC1 b/sys/arm/conf/ODROIDC1 index 16802d31f5c8..857cbb9c8edd 100644 --- a/sys/arm/conf/ODROIDC1 +++ b/sys/arm/conf/ODROIDC1 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD index 05ea2af69962..feca8a394540 100644 --- a/sys/arm/conf/PANDABOARD +++ b/sys/arm/conf/PANDABOARD @@ -5,11 +5,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -27,7 +27,7 @@ ident PANDABOARD hints "PANDABOARD.hints" -include "std.armv6" +include "std.armv7" include "../ti/omap4/std.omap4" makeoptions MODULES_EXTRA=dtb/omap4 diff --git a/sys/arm/conf/QILA9G20 b/sys/arm/conf/QILA9G20 index 97bde286effe..afed9bedd882 100644 --- a/sys/arm/conf/QILA9G20 +++ b/sys/arm/conf/QILA9G20 @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/QUARTZ b/sys/arm/conf/QUARTZ index 9c981850b4c0..3e7d239785e2 100644 --- a/sys/arm/conf/QUARTZ +++ b/sys/arm/conf/QUARTZ @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/RADXA b/sys/arm/conf/RADXA index 8801f6728e91..7b3d88aa2d39 100644 --- a/sys/arm/conf/RADXA +++ b/sys/arm/conf/RADXA @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/RADXA-LITE b/sys/arm/conf/RADXA-LITE index 72529411a6ba..62aaf60563d7 100644 --- a/sys/arm/conf/RADXA-LITE +++ b/sys/arm/conf/RADXA-LITE @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index 00dfcd45b729..23d1a18b0534 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ ident RK3188 -include "std.armv6" +include "std.armv7" include "../rockchip/std.rk30xx" options SOC_ROCKCHIP_RK3188 diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B index ce408aba9ef1..e843715d279c 100644 --- a/sys/arm/conf/RPI-B +++ b/sys/arm/conf/RPI-B @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2 index 058100176a3b..9a632ae7f3d1 100644 --- a/sys/arm/conf/RPI2 +++ b/sys/arm/conf/RPI2 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -22,7 +22,7 @@ ident RPI2 -include "std.armv6" +include "std.armv7" include "../broadcom/bcm2835/std.rpi" include "../broadcom/bcm2835/std.bcm2836" diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK index fc65625855b5..34638883b65d 100644 --- a/sys/arm/conf/SAM9260EK +++ b/sys/arm/conf/SAM9260EK @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SAM9G20EK b/sys/arm/conf/SAM9G20EK index e518e7c6f62f..6417deed26bc 100644 --- a/sys/arm/conf/SAM9G20EK +++ b/sys/arm/conf/SAM9G20EK @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SAM9X25EK b/sys/arm/conf/SAM9X25EK index ab69a2d6d871..c5d5d8947cab 100644 --- a/sys/arm/conf/SAM9X25EK +++ b/sys/arm/conf/SAM9X25EK @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SN9G45 b/sys/arm/conf/SN9G45 index 21cb7a6c1e1b..10d6412d4b79 100644 --- a/sys/arm/conf/SN9G45 +++ b/sys/arm/conf/SN9G45 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SOCDK b/sys/arm/conf/SOCDK index acdf4f341412..4c92aaea108a 100644 --- a/sys/arm/conf/SOCDK +++ b/sys/arm/conf/SOCDK @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SOCFPGA b/sys/arm/conf/SOCFPGA index 0291db7a4bdb..364be2e7f99d 100644 --- a/sys/arm/conf/SOCFPGA +++ b/sys/arm/conf/SOCFPGA @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -19,7 +19,7 @@ # $FreeBSD$ ident SOCFPGA -include "std.armv6" +include "std.armv7" include "../altera/socfpga/std.socfpga" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/SOCKIT b/sys/arm/conf/SOCKIT index a40cf5bacd99..c83a3f260691 100644 --- a/sys/arm/conf/SOCKIT +++ b/sys/arm/conf/SOCKIT @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/SOCKIT-BERI b/sys/arm/conf/SOCKIT-BERI index 70cdd91d4cc8..7dd37a340502 100644 --- a/sys/arm/conf/SOCKIT-BERI +++ b/sys/arm/conf/SOCKIT-BERI @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/TEGRA124 b/sys/arm/conf/TEGRA124 index cf466bb89307..aa84ed86e91e 100644 --- a/sys/arm/conf/TEGRA124 +++ b/sys/arm/conf/TEGRA124 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -18,7 +18,7 @@ # # $FreeBSD$ -include "std.armv6" +include "std.armv7" include "../nvidia/tegra124/std.tegra124" ident TEGRA124 diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB index 10686ea8b6c3..2c6f11644e7c 100644 --- a/sys/arm/conf/VERSATILEPB +++ b/sys/arm/conf/VERSATILEPB @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT index 64f3a3df59e3..5320074de0e4 100644 --- a/sys/arm/conf/VIRT +++ b/sys/arm/conf/VIRT @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -20,7 +20,7 @@ ident VIRT -include "std.armv6" +include "std.armv7" include "../qemu/std.virt" options SCHED_ULE # ULE scheduler diff --git a/sys/arm/conf/VSATV102 b/sys/arm/conf/VSATV102 index c08060a3bcac..bf77c7933892 100644 --- a/sys/arm/conf/VSATV102 +++ b/sys/arm/conf/VSATV102 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID index 336c4ddc1357..9c967aeaf146 100644 --- a/sys/arm/conf/VYBRID +++ b/sys/arm/conf/VYBRID @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -19,7 +19,7 @@ # $FreeBSD$ ident VYBRID -include "std.armv6" +include "std.armv7" include "../freescale/vybrid/std.vybrid" makeoptions WERROR="-Werror" diff --git a/sys/arm/conf/YYHD18 b/sys/arm/conf/YYHD18 index 1a251ce9e988..5459e5acc6ba 100644 --- a/sys/arm/conf/YYHD18 +++ b/sys/arm/conf/YYHD18 @@ -3,11 +3,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index 4085aa8d1370..8e79757a98f2 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -5,11 +5,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -21,7 +21,7 @@ ident ZEDBOARD -include "std.armv6" +include "std.armv7" include "../xilinx/std.zynq7" makeoptions MODULES_EXTRA="dtb/zynq" diff --git a/sys/arm/conf/std.armv6 b/sys/arm/conf/std.armv6 index 4ee9caff32e7..123fbca7efe6 100644 --- a/sys/arm/conf/std.armv6 +++ b/sys/arm/conf/std.armv6 @@ -1,10 +1,11 @@ -# Standard kernel config items for all ARMv6/v7 systems. +# Standard kernel config items for all ARMv6 systems. # # $FreeBSD$ options HZ=1000 options ARM_L2_PIPT # Only L2 PIPT is supported options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP diff --git a/sys/arm/conf/std.armv7 b/sys/arm/conf/std.armv7 new file mode 100644 index 000000000000..d1e42e15ebeb --- /dev/null +++ b/sys/arm/conf/std.armv7 @@ -0,0 +1,80 @@ +# Standard kernel config items for all ARMv7 systems. +# +# $FreeBSD$ + +options HZ=1000 +options ARM_L2_PIPT # Only L2 PIPT is supported +options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP +options IPSEC # IP (v4/v6) security +options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme +options GEOM_LABEL # Provides labelization +options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support + +options COMPAT_FREEBSD10 # Compatible with FreeBSD10 +options COMPAT_FREEBSD11 # Compatible with FreeBSD11 + +# DTrace support +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # all architectures - kernel ELF linker loads CTF data +makeoptions WITH_CTF=1 + +# Debugging support. Always need this: +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options KDB # Enable kernel debugger support. +options KDB_TRACE # Print a stack trace for a panic. + +# For full debugger support use (turn off in stable branch): +options DDB # Support DDB +#options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones +options ALT_BREAK_TO_DEBUGGER # Enter debugger on keyboard escape sequence +options USB_DEBUG # Enable usb debug support code + +# Optional extras, never enabled by default: +#options BOOTVERBOSE +#options DEBUG # May result in extreme spewage +#options KTR +#options KTR_COMPILE=KTR_ALL +#options KTR_ENTRIES=16384 +#options KTR_MASK=(KTR_SPARE2) +#options KTR_VERBOSE=0 +#options USB_REQ_DEBUG +#options USB_VERBOSE +#options VERBOSE_SYSINIT # Enable verbose sysinit messages + diff --git a/sys/arm/freescale/imx/files.imx6 b/sys/arm/freescale/imx/files.imx6 index c9bd6b305d3f..36bbe80e8083 100644 --- a/sys/arm/freescale/imx/files.imx6 +++ b/sys/arm/freescale/imx/files.imx6 @@ -22,7 +22,7 @@ arm/freescale/imx/imx_machdep.c standard arm/freescale/imx/imx_gpt.c optional imx_gpt arm/freescale/imx/imx_gpio.c optional gpio arm/freescale/imx/imx_i2c.c optional fsliic -arm/freescale/imx/imx6_sdma.c optional sdma +arm/freescale/imx/imx6_sdma.c optional fslsdma arm/freescale/imx/imx6_audmux.c optional sound arm/freescale/imx/imx6_ssi.c optional sound arm/freescale/imx/imx6_ahci.c optional ahci diff --git a/sys/arm/freescale/imx/imx6_ahci.c b/sys/arm/freescale/imx/imx6_ahci.c index d4f9af99bbf3..da508aba8b91 100644 --- a/sys/arm/freescale/imx/imx6_ahci.c +++ b/sys/arm/freescale/imx/imx6_ahci.c @@ -330,8 +330,6 @@ imx6_ahci_detach(device_t dev) return (ahci_detach(dev)); } -devclass_t ahci_devclass; - static device_method_t imx6_ahci_ata_methods[] = { /* device probe, attach and detach methods */ DEVMETHOD(device_probe, imx6_ahci_probe), diff --git a/sys/arm/freescale/imx/imx6_hdmi.c b/sys/arm/freescale/imx/imx6_hdmi.c index 7059f09a86f3..cd89710be897 100644 --- a/sys/arm/freescale/imx/imx6_hdmi.c +++ b/sys/arm/freescale/imx/imx6_hdmi.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -57,6 +58,7 @@ __FBSDID("$FreeBSD$"); struct imx_hdmi_softc { struct dwc_hdmi_softc base; phandle_t i2c_xref; + eventhandler_tag eh_tag; }; static struct ofw_compat_data compat_data[] = { @@ -78,6 +80,48 @@ imx_hdmi_get_i2c_dev(device_t dev) return (OF_device_from_xref(sc->i2c_xref)); } +/* + * Deferred HDMI init. dwc_hdmi_init() does i2c transfers for DDC/EDID. The imx + * i2c devices also use a config_intrhook function to finish their init, because + * they require interrupts to perform transfers. There is no way to control + * whether the i2c or our hdmi intrhook function runs first. If we go first we + * have to continue waiting until after the i2c driver is ready to do transfers + * and has registered its phandle. + * + * This function is used as both a config_intrhook function and after that as an + * eventhandler callback function (if necessary), to see if our i2c device is + * ready yet. When it is, continue with hdmi init. When first called as an + * intrhook function the i2c devices might be ready, in which case we never + * register as an eventhandler at all. Otherwise we register to see newbus + * attach events, and as each device attaches we check to see whether it was the + * i2c device we care about. Once we have our i2c device we unregister from + * seeing further attach events. + */ +static void +imx_hdmi_init(void *dev) +{ + struct imx_hdmi_softc *sc; + + sc = device_get_softc((device_t)dev); + + if (OF_device_from_xref(sc->i2c_xref) != NULL) { + if (sc->eh_tag != NULL) { + EVENTHANDLER_DEREGISTER_NOWAIT(device_attach, + sc->eh_tag); + } + dwc_hdmi_init(dev); + return; + } + + if (bootverbose) + device_printf((device_t)dev, "Waiting for DDC i2c device\n"); + + if (sc->eh_tag == NULL) { + sc->eh_tag = EVENTHANDLER_REGISTER(device_attach, + imx_hdmi_init, dev, EVENTHANDLER_PRI_ANY); + } +} + static int imx_hdmi_detach(device_t dev) { @@ -128,7 +172,9 @@ imx_hdmi_attach(device_t dev) gpr3 |= IOMUXC_GPR3_HDMI_IPU1_DI0; imx_iomux_gpr_set(IOMUXC_GPR3, gpr3); - return (dwc_hdmi_init(dev)); + /* Further HDMI init requires interrupts for i2c transfers. */ + config_intrhook_oneshot(imx_hdmi_init, dev); + return (0); out: imx_hdmi_detach(dev); diff --git a/sys/arm/freescale/imx/std.imx51 b/sys/arm/freescale/imx/std.imx51 index 4f9ac1454b9a..730c976899a7 100644 --- a/sys/arm/freescale/imx/std.imx51 +++ b/sys/arm/freescale/imx/std.imx51 @@ -1,5 +1,5 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 cpu CPU_CORTEXA makeoptions CONF_CFLAGS="-march=armv7a" diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53 index 4f9ac1454b9a..730c976899a7 100644 --- a/sys/arm/freescale/imx/std.imx53 +++ b/sys/arm/freescale/imx/std.imx53 @@ -1,5 +1,5 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 cpu CPU_CORTEXA makeoptions CONF_CFLAGS="-march=armv7a" diff --git a/sys/arm/freescale/imx/std.imx6 b/sys/arm/freescale/imx/std.imx6 index 7d9dc3ce82d2..8778a29a705d 100644 --- a/sys/arm/freescale/imx/std.imx6 +++ b/sys/arm/freescale/imx/std.imx6 @@ -1,5 +1,5 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 cpu CPU_CORTEXA makeoptions CONF_CFLAGS="-march=armv7a" diff --git a/sys/arm/freescale/vybrid/std.vybrid b/sys/arm/freescale/vybrid/std.vybrid index 6baf9489ae0b..25d2a6b39150 100644 --- a/sys/arm/freescale/vybrid/std.vybrid +++ b/sys/arm/freescale/vybrid/std.vybrid @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0100000 diff --git a/sys/arm/include/cpu-v4.h b/sys/arm/include/cpu-v4.h index bd383d3f2d90..2574f47469ae 100644 --- a/sys/arm/include/cpu-v4.h +++ b/sys/arm/include/cpu-v4.h @@ -51,10 +51,10 @@ #define _FX(s...) #s #define _RF0(fname, aname...) \ -static __inline register_t \ +static __inline uint32_t \ fname(void) \ { \ - register_t reg; \ + uint32_t reg; \ __asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \ return(reg); \ } @@ -77,7 +77,7 @@ fname(void) \ #define _WF1(fname, aname...) \ static __inline void \ -fname(register_t reg) \ +fname(uint32_t reg) \ { \ __asm __volatile("mcr\t" _FX(aname):: "r" (reg)); \ } diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h index b1d41a46d2e9..3077eb95def9 100644 --- a/sys/arm/include/cpu-v6.h +++ b/sys/arm/include/cpu-v6.h @@ -103,10 +103,10 @@ extern int pmu_attched; #define _FX(s...) #s #define _RF0(fname, aname...) \ -static __inline register_t \ +static __inline uint32_t \ fname(void) \ { \ - register_t reg; \ + uint32_t reg; \ __asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \ return(reg); \ } @@ -129,7 +129,7 @@ fname(void) \ #define _WF1(fname, aname...) \ static __inline void \ -fname(register_t reg) \ +fname(uint32_t reg) \ { \ __asm __volatile("mcr\t" _FX(aname):: "r" (reg)); \ } diff --git a/sys/arm/include/elf.h b/sys/arm/include/elf.h index 8b498b69caba..ee854f76adde 100644 --- a/sys/arm/include/elf.h +++ b/sys/arm/include/elf.h @@ -85,8 +85,10 @@ __ElfType(Auxinfo); #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ #define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 25 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ #define R_ARM_COUNT 33 /* Count of defined relocation types. */ @@ -114,4 +116,37 @@ __ElfType(Auxinfo); #define ET_DYN_LOAD_ADDR 0x12000 +/* Flags passed in AT_HWCAP. */ +#define HWCAP_SWP 0x00000001 /* Unsupported, never set. */ +#define HWCAP_HALF 0x00000002 /* Always set. */ +#define HWCAP_THUMB 0x00000004 +#define HWCAP_26BIT 0x00000008 /* Unsupported, never set. */ +#define HWCAP_FAST_MULT 0x00000010 /* Always set. */ +#define HWCAP_FPA 0x00000020 /* Unsupported, never set. */ +#define HWCAP_VFP 0x00000040 +#define HWCAP_EDSP 0x00000080 /* Always set for ARMv6+. */ +#define HWCAP_JAVA 0x00000100 /* Unsupported, never set. */ +#define HWCAP_IWMMXT 0x00000200 /* Unsupported, never set. */ +#define HWCAP_CRUNCH 0x00000400 /* Unsupported, never set. */ +#define HWCAP_THUMBEE 0x00000800 +#define HWCAP_NEON 0x00001000 +#define HWCAP_VFPv3 0x00002000 +#define HWCAP_VFPv3D16 0x00004000 +#define HWCAP_TLS 0x00008000 /* Always set for ARMv6+. */ +#define HWCAP_VFPv4 0x00010000 +#define HWCAP_IDIVA 0x00020000 +#define HWCAP_IDIVT 0x00040000 +#define HWCAP_VFPD32 0x00080000 +#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) +#define HWCAP_LPAE 0x00100000 +#define HWCAP_EVTSTRM 0x00200000 /* Not implemented yet. */ + + +/* Flags passed in AT_HWCAP2. */ +#define HWCAP2_AES 0x00000001 +#define HWCAP2_PMULL 0x00000002 +#define HWCAP2_SHA1 0x00000004 +#define HWCAP2_SHA2 0x00000008 +#define HWCAP2_CRC32 0x00000010 + #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/arm/include/machdep.h b/sys/arm/include/machdep.h index b738b971bd3f..ba20e40c0d35 100644 --- a/sys/arm/include/machdep.h +++ b/sys/arm/include/machdep.h @@ -40,6 +40,7 @@ void arm_parse_fdt_bootargs(void); void arm_print_kenv(void); void arm_generic_initclocks(void); +int arm_get_vfpstate(struct thread *td, void *args); /* Board-specific attributes */ void board_set_serial(uint64_t); diff --git a/sys/arm/include/md_var.h b/sys/arm/include/md_var.h index 642124d9d214..39a174ee7a42 100644 --- a/sys/arm/include/md_var.h +++ b/sys/arm/include/md_var.h @@ -38,6 +38,8 @@ extern char sigcode[]; extern int szsigcode; extern uint32_t *vm_page_dump; extern int vm_page_dump_size; +extern u_long elf_hwcap; +extern u_long elf_hwcap2; extern int (*_arm_memcpy)(void *, void *, int, int); extern int (*_arm_bzero)(void *, int, int); diff --git a/sys/arm/include/metadata.h b/sys/arm/include/metadata.h index cf4c9bb5cbbc..9589b7309dd4 100644 --- a/sys/arm/include/metadata.h +++ b/sys/arm/include/metadata.h @@ -39,4 +39,19 @@ struct efi_map_header { uint32_t descriptor_version; }; +/* + * Placeholder for now + */ +struct efi_fb { + uint64_t fb_addr; + uint64_t fb_size; + uint32_t fb_height; + uint32_t fb_width; + uint32_t fb_stride; + uint32_t fb_mask_red; + uint32_t fb_mask_green; + uint32_t fb_mask_blue; + uint32_t fb_mask_reserved; +}; + #endif /* !_MACHINE_METADATA_H_ */ diff --git a/sys/arm/include/param.h b/sys/arm/include/param.h index a5fd5208a9e7..6c20dd28716b 100644 --- a/sys/arm/include/param.h +++ b/sys/arm/include/param.h @@ -52,10 +52,12 @@ #define __PCI_REROUTE_INTERRUPT -#if __ARM_ARCH >= 6 -#define _V6_SUFFIX "v6" +#if __ARM_ARCH >= 7 +#define _V_SUFFIX "v7" +#elif __ARM_ARCH >= 6 +#define _V_SUFFIX "v6" #else -#define _V6_SUFFIX "" +#define _V_SUFFIX "" #endif #ifdef __ARM_BIG_ENDIAN @@ -68,7 +70,7 @@ #define MACHINE "arm" #endif #ifndef MACHINE_ARCH -#define MACHINE_ARCH "arm" _V6_SUFFIX _EB_SUFFIX +#define MACHINE_ARCH "arm" _V_SUFFIX _EB_SUFFIX #endif #if defined(SMP) || defined(KLD_MODULE) diff --git a/sys/arm/include/pmap-v4.h b/sys/arm/include/pmap-v4.h index 9ecfc3761221..bdca55dcf0d5 100644 --- a/sys/arm/include/pmap-v4.h +++ b/sys/arm/include/pmap-v4.h @@ -356,6 +356,7 @@ extern int pmap_needs_pte_sync; #endif /* ARM_NMMUS > 1 */ #if defined(CPU_XSCALE_81342) +#define CPU_XSCALE_CORE3 #define PMAP_NEEDS_PTE_SYNC 1 #define PMAP_INCLUDE_PTE_SYNC #else diff --git a/sys/arm/include/ptrace.h b/sys/arm/include/ptrace.h index d98aa14f3ef7..7aec39cb84f3 100644 --- a/sys/arm/include/ptrace.h +++ b/sys/arm/include/ptrace.h @@ -4,5 +4,20 @@ #ifndef _MACHINE_PTRACE_H_ #define _MACHINE_PTRACE_H_ +#define __HAVE_PTRACE_MACHDEP + +/* + * Must match mcontext_vfp_t. Note that mcontext_vfp_t does not + * include explicit padding. + */ +struct vfpreg { + __uint64_t vfp_reg[32]; + __uint32_t vfp_scr; + __uint32_t vfp_pad0; +}; + +#define PT_GETVFPREGS (PT_FIRSTMACH + 0) +#define PT_SETVFPREGS (PT_FIRSTMACH + 1) + #endif /* !_MACHINE_PTRACE_H */ diff --git a/sys/arm/include/sysarch.h b/sys/arm/include/sysarch.h index 43abb0057505..de48587cfd19 100644 --- a/sys/arm/include/sysarch.h +++ b/sys/arm/include/sysarch.h @@ -78,12 +78,18 @@ #define ARM_DRAIN_WRITEBUF 1 #define ARM_SET_TP 2 #define ARM_GET_TP 3 +#define ARM_GET_VFPSTATE 4 struct arm_sync_icache_args { uintptr_t addr; /* Virtual start address */ size_t len; /* Region size */ }; +struct arm_get_vfpstate_args { + size_t mc_vfp_size; + void *mc_vfp; +}; + #ifndef _KERNEL __BEGIN_DECLS int arm_sync_icache (u_int addr, int len); diff --git a/sys/arm/include/vfp.h b/sys/arm/include/vfp.h index 1c4540e1a4fe..15ae54030005 100644 --- a/sys/arm/include/vfp.h +++ b/sys/arm/include/vfp.h @@ -119,6 +119,12 @@ #define VMVFR0_RB_MASK (0x0000000f) /* VFP 64 bit media support */ /* VMVFR1 */ +#define VMVFR1_FMAC_OFF 28 +#define VMVFR1_FMAC_MASK (0xf0000000) /* Neon FMAC support */ +#define VMVFR1_VFP_HP_OFF 24 +#define VMVFR1_VFP_HP_MASK (0x0f000000) /* VFP half prec support */ +#define VMVFR1_HP_OFF 20 +#define VMVFR1_HP_MASK (0x00f00000) /* Neon half prec support */ #define VMVFR1_SP_OFF 16 #define VMVFR1_SP_MASK (0x000f0000) /* Neon single prec support */ #define VMVFR1_I_OFF 12 @@ -142,6 +148,8 @@ struct vfp_state { }; #ifdef _KERNEL +void get_vfpcontext(struct thread *, mcontext_vfp_t *); +void set_vfpcontext(struct thread *, mcontext_vfp_t *); void vfp_init(void); void vfp_store(struct vfp_state *, boolean_t); void vfp_discard(struct thread *); diff --git a/sys/arm/mv/armada38x/std.armada38x b/sys/arm/mv/armada38x/std.armada38x index 732fd90124c1..abda7a769406 100644 --- a/sys/arm/mv/armada38x/std.armada38x +++ b/sys/arm/mv/armada38x/std.armada38x @@ -2,7 +2,7 @@ files "../mv/armada38x/files.armada38x" files "../mv/files.mv" cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0000000 diff --git a/sys/arm/mv/std-pj4b.mv b/sys/arm/mv/std-pj4b.mv index 8a64fab7bc1e..bf12e62b657f 100644 --- a/sys/arm/mv/std-pj4b.mv +++ b/sys/arm/mv/std-pj4b.mv @@ -2,7 +2,7 @@ files "../mv/files.mv" cpu CPU_MV_PJ4B -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" # This was originally defined as "(KERNBASE-(1024*1024*1024))" but that diff --git a/sys/arm/nvidia/tegra124/std.tegra124 b/sys/arm/nvidia/tegra124/std.tegra124 index 35de22534f46..e9688732d696 100644 --- a/sys/arm/nvidia/tegra124/std.tegra124 +++ b/sys/arm/nvidia/tegra124/std.tegra124 @@ -1,6 +1,6 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" options KERNVIRTADDR = 0xc0200000 diff --git a/sys/arm/nvidia/tegra124/tegra124_machdep.c b/sys/arm/nvidia/tegra124/tegra124_machdep.c index 55b411dd7914..ee65805738e3 100644 --- a/sys/arm/nvidia/tegra124/tegra124_machdep.c +++ b/sys/arm/nvidia/tegra124/tegra124_machdep.c @@ -122,6 +122,7 @@ tegra124_cpu_reset(platform_t plat) * option SOCDEV_VA=0x70000000 * option EARLY_PRINTF */ +#if 0 #ifdef EARLY_PRINTF static void tegra124_early_putc(int c) @@ -136,6 +137,7 @@ tegra124_early_putc(int c) } early_putc_t *early_putc = tegra124_early_putc; #endif +#endif static platform_method_t tegra124_methods[] = { PLATFORMMETHOD(platform_attach, tegra124_attach), diff --git a/sys/arm/nvidia/tegra_ahci.c b/sys/arm/nvidia/tegra_ahci.c index 2ea714a77641..6e23f1eb0ac4 100644 --- a/sys/arm/nvidia/tegra_ahci.c +++ b/sys/arm/nvidia/tegra_ahci.c @@ -618,8 +618,7 @@ static device_method_t tegra_ahci_methods[] = { DEVMETHOD_END }; -static devclass_t tegra_ahci_devclass; static DEFINE_CLASS_0(ahci, tegra_ahci_driver, tegra_ahci_methods, sizeof(struct tegra_ahci_sc)); -DRIVER_MODULE(tegra_ahci, simplebus, tegra_ahci_driver, tegra_ahci_devclass, +DRIVER_MODULE(tegra_ahci, simplebus, tegra_ahci_driver, ahci_devclass, NULL, NULL); diff --git a/sys/arm/qemu/std.virt b/sys/arm/qemu/std.virt index 858e195914ce..ac21f828ece4 100644 --- a/sys/arm/qemu/std.virt +++ b/sys/arm/qemu/std.virt @@ -1,5 +1,5 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 cpu CPU_CORTEXA makeoptions CONF_CFLAGS="-march=armv7a" diff --git a/sys/arm/rockchip/std.rk30xx b/sys/arm/rockchip/std.rk30xx index 431526b1c36e..4747145d4b8a 100644 --- a/sys/arm/rockchip/std.rk30xx +++ b/sys/arm/rockchip/std.rk30xx @@ -2,7 +2,7 @@ #$FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0400000 diff --git a/sys/arm/samsung/exynos/std.exynos5250 b/sys/arm/samsung/exynos/std.exynos5250 index 52e450823d74..7f0a2fb190e3 100644 --- a/sys/arm/samsung/exynos/std.exynos5250 +++ b/sys/arm/samsung/exynos/std.exynos5250 @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0f00000 diff --git a/sys/arm/samsung/exynos/std.exynos5420 b/sys/arm/samsung/exynos/std.exynos5420 index 52e450823d74..7f0a2fb190e3 100644 --- a/sys/arm/samsung/exynos/std.exynos5420 +++ b/sys/arm/samsung/exynos/std.exynos5420 @@ -1,7 +1,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0f00000 diff --git a/sys/arm/ti/std.ti b/sys/arm/ti/std.ti index 5eb69fdbdae1..83c144393910 100644 --- a/sys/arm/ti/std.ti +++ b/sys/arm/ti/std.ti @@ -1,6 +1,6 @@ # $FreeBSD$ -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" files "../ti/files.ti" diff --git a/sys/arm/ti/ti_pruss.c b/sys/arm/ti/ti_pruss.c index 8ffb9e078997..42cc48e45acb 100644 --- a/sys/arm/ti/ti_pruss.c +++ b/sys/arm/ti/ti_pruss.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 Rui Paulo + * Copyright (c) 2017 Manuel Stuehn * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,27 +27,32 @@ #include __FBSDID("$FreeBSD$"); +#include +#include +#include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include #include #include #include +#include #include #include #include -#include - #include #include @@ -59,27 +65,72 @@ __FBSDID("$FreeBSD$"); #define DPRINTF(fmt, ...) #endif +static d_open_t ti_pruss_irq_open; +static d_read_t ti_pruss_irq_read; +static d_poll_t ti_pruss_irq_poll; + static device_probe_t ti_pruss_probe; static device_attach_t ti_pruss_attach; static device_detach_t ti_pruss_detach; static void ti_pruss_intr(void *); static d_open_t ti_pruss_open; static d_mmap_t ti_pruss_mmap; -static void ti_pruss_kq_read_detach(struct knote *); -static int ti_pruss_kq_read_event(struct knote *, long); -static d_kqfilter_t ti_pruss_kqfilter; +static void ti_pruss_irq_kqread_detach(struct knote *); +static int ti_pruss_irq_kqevent(struct knote *, long); +static d_kqfilter_t ti_pruss_irq_kqfilter; +static void ti_pruss_privdtor(void *data); -#define TI_PRUSS_IRQS 8 +#define TI_PRUSS_PRU_IRQS 2 +#define TI_PRUSS_HOST_IRQS 8 +#define TI_PRUSS_IRQS (TI_PRUSS_HOST_IRQS+TI_PRUSS_PRU_IRQS) +#define TI_PRUSS_EVENTS 64 +#define NOT_SET_STR "NONE" +#define TI_TS_ARRAY 16 + +struct ctl +{ + size_t cnt; + size_t idx; +}; + +struct ts_ring_buf +{ + struct ctl ctl; + uint64_t ts[TI_TS_ARRAY]; +}; + +struct ti_pruss_irqsc +{ + struct mtx sc_mtx; + struct cdev *sc_pdev; + struct selinfo sc_selinfo; + int8_t channel; + int8_t last; + int8_t event; + bool enable; + struct ts_ring_buf tstamps; +}; + +static struct cdevsw ti_pruss_cdevirq = { + .d_version = D_VERSION, + .d_name = "ti_pruss_irq", + .d_open = ti_pruss_irq_open, + .d_read = ti_pruss_irq_read, + .d_poll = ti_pruss_irq_poll, + .d_kqfilter = ti_pruss_irq_kqfilter, +}; struct ti_pruss_softc { struct mtx sc_mtx; struct resource *sc_mem_res; - struct resource *sc_irq_res[TI_PRUSS_IRQS]; - void *sc_intr[TI_PRUSS_IRQS]; + struct resource *sc_irq_res[TI_PRUSS_HOST_IRQS]; + void *sc_intr[TI_PRUSS_HOST_IRQS]; + struct ti_pruss_irqsc sc_irq_devs[TI_PRUSS_IRQS]; bus_space_tag_t sc_bt; bus_space_handle_t sc_bh; struct cdev *sc_pdev; struct selinfo sc_selinfo; + bool sc_glob_irqen; }; static struct cdevsw ti_pruss_cdevsw = { @@ -87,7 +138,6 @@ static struct cdevsw ti_pruss_cdevsw = { .d_name = "ti_pruss", .d_open = ti_pruss_open, .d_mmap = ti_pruss_mmap, - .d_kqfilter = ti_pruss_kqfilter, }; static device_method_t ti_pruss_methods[] = { @@ -107,6 +157,7 @@ static driver_t ti_pruss_driver = { static devclass_t ti_pruss_devclass; DRIVER_MODULE(ti_pruss, simplebus, ti_pruss_driver, ti_pruss_devclass, 0, 0); +MODULE_DEPEND(ti_pruss, ti_prcm, 1, 1, 1); static struct resource_spec ti_pruss_irq_spec[] = { { SYS_RES_IRQ, 0, RF_ACTIVE }, @@ -119,7 +170,111 @@ static struct resource_spec ti_pruss_irq_spec[] = { { SYS_RES_IRQ, 7, RF_ACTIVE }, { -1, 0, 0 } }; -CTASSERT(TI_PRUSS_IRQS == nitems(ti_pruss_irq_spec) - 1); +CTASSERT(TI_PRUSS_HOST_IRQS == nitems(ti_pruss_irq_spec) - 1); + +static int +ti_pruss_irq_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct ctl* irqs; + struct ti_pruss_irqsc *sc; + sc = dev->si_drv1; + + irqs = malloc(sizeof(struct ctl), M_DEVBUF, M_WAITOK); + if (!irqs) + return (ENOMEM); + + irqs->cnt = sc->tstamps.ctl.cnt; + irqs->idx = sc->tstamps.ctl.idx; + + return devfs_set_cdevpriv(irqs, ti_pruss_privdtor); +} + +static void +ti_pruss_privdtor(void *data) +{ + free(data, M_DEVBUF); +} + +static int +ti_pruss_irq_poll(struct cdev *dev, int events, struct thread *td) +{ + struct ctl* irqs; + struct ti_pruss_irqsc *sc; + sc = dev->si_drv1; + + devfs_get_cdevpriv((void**)&irqs); + + if (events & (POLLIN | POLLRDNORM)) { + if (sc->tstamps.ctl.cnt != irqs->cnt) + return events & (POLLIN | POLLRDNORM); + else + selrecord(td, &sc->sc_selinfo); + } + return 0; +} + +static int +ti_pruss_irq_read(struct cdev *cdev, struct uio *uio, int ioflag) +{ + const size_t ts_len = sizeof(uint64_t); + struct ti_pruss_irqsc* irq; + struct ctl* priv; + int error = 0; + size_t idx; + ssize_t level; + + irq = cdev->si_drv1; + + if (uio->uio_resid < ts_len) + return (EINVAL); + + error = devfs_get_cdevpriv((void**)&priv); + if (error) + return (error); + + mtx_lock(&irq->sc_mtx); + + if (irq->tstamps.ctl.cnt - priv->cnt > TI_TS_ARRAY) + { + priv->cnt = irq->tstamps.ctl.cnt; + priv->idx = irq->tstamps.ctl.idx; + mtx_unlock(&irq->sc_mtx); + return (ENXIO); + } + + do { + idx = priv->idx; + level = irq->tstamps.ctl.idx - idx; + if (level < 0) + level += TI_TS_ARRAY; + + if (level == 0) { + if (ioflag & O_NONBLOCK) { + mtx_unlock(&irq->sc_mtx); + return (EWOULDBLOCK); + } + + error = msleep(irq, &irq->sc_mtx, PCATCH | PDROP, + "pruirq", 0); + if (error) + return error; + + mtx_lock(&irq->sc_mtx); + } + }while(level == 0); + + mtx_unlock(&irq->sc_mtx); + + error = uiomove(&irq->tstamps.ts[idx], ts_len, uio); + + if (++idx == TI_TS_ARRAY) + idx = 0; + priv->idx = idx; + + atomic_add_32(&priv->cnt, 1); + + return (error); +} static struct ti_pruss_irq_arg { int irq; @@ -138,6 +293,204 @@ ti_pruss_reg_write(struct ti_pruss_softc *sc, uint32_t reg, uint32_t val) bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val); } +static __inline void +ti_pruss_interrupts_clear(struct ti_pruss_softc *sc) +{ + /* disable global interrupt */ + ti_pruss_reg_write(sc, PRUSS_INTC_GER, 0 ); + + /* clear all events */ + ti_pruss_reg_write(sc, PRUSS_INTC_SECR0, 0xFFFFFFFF); + ti_pruss_reg_write(sc, PRUSS_INTC_SECR1, 0xFFFFFFFF); + + /* disable all host interrupts */ + ti_pruss_reg_write(sc, PRUSS_INTC_HIER, 0); +} + +static __inline int +ti_pruss_interrupts_enable(struct ti_pruss_softc *sc, int8_t irq, bool enable) +{ + if (enable && ((sc->sc_irq_devs[irq].channel == -1) || + (sc->sc_irq_devs[irq].event== -1))) + { + device_printf( sc->sc_pdev->si_drv1, + "Interrupt chain not fully configured, not possible to enable\n" ); + return (EINVAL); + } + + sc->sc_irq_devs[irq].enable = enable; + + if (sc->sc_irq_devs[irq].sc_pdev) { + destroy_dev(sc->sc_irq_devs[irq].sc_pdev); + sc->sc_irq_devs[irq].sc_pdev = NULL; + } + + if (enable) { + sc->sc_irq_devs[irq].sc_pdev = make_dev(&ti_pruss_cdevirq, 0, UID_ROOT, GID_WHEEL, + 0600, "pruss%d.irq%d", device_get_unit(sc->sc_pdev->si_drv1), irq); + sc->sc_irq_devs[irq].sc_pdev->si_drv1 = &sc->sc_irq_devs[irq]; + + sc->sc_irq_devs[irq].tstamps.ctl.idx = 0; + } + + uint32_t reg = enable ? PRUSS_INTC_HIEISR : PRUSS_INTC_HIDISR; + ti_pruss_reg_write(sc, reg, sc->sc_irq_devs[irq].channel); + + reg = enable ? PRUSS_INTC_EISR : PRUSS_INTC_EICR; + ti_pruss_reg_write(sc, reg, sc->sc_irq_devs[irq].event ); + + return (0); +} + +static __inline void +ti_pruss_map_write(struct ti_pruss_softc *sc, uint32_t basereg, uint8_t index, uint8_t content) +{ + const size_t regadr = basereg + index & ~0x03; + const size_t bitpos = (index & 0x03) * 8; + uint32_t rmw = ti_pruss_reg_read(sc, regadr); + rmw = (rmw & ~( 0xF << bitpos)) | ( (content & 0xF) << bitpos); + ti_pruss_reg_write(sc, regadr, rmw); +} + +static int +ti_pruss_event_map( SYSCTL_HANDLER_ARGS ) +{ + struct ti_pruss_softc *sc; + const int8_t irq = arg2; + int err; + char event[sizeof(NOT_SET_STR)]; + + sc = arg1; + + if(sc->sc_irq_devs[irq].event == -1) + bcopy(NOT_SET_STR, event, sizeof(event)); + else + snprintf(event, sizeof(event), "%d", sc->sc_irq_devs[irq].event); + + err = sysctl_handle_string(oidp, event, sizeof(event), req); + if(err != 0) + return (err); + + if (req->newptr) { // write event + if (strcmp(NOT_SET_STR, event) == 0) { + ti_pruss_interrupts_enable(sc, irq, false); + sc->sc_irq_devs[irq].event = -1; + } else { + if (sc->sc_irq_devs[irq].channel == -1) { + device_printf( sc->sc_pdev->si_drv1, + "corresponding channel not configured\n"); + return (ENXIO); + } + + const int8_t channelnr = sc->sc_irq_devs[irq].channel; + const int8_t eventnr = strtol( event, NULL, 10 ); // TODO: check if strol is valid + if (eventnr > TI_PRUSS_EVENTS || eventnr < 0) { + device_printf( sc->sc_pdev->si_drv1, + "Event number %d not valid (0 - %d)", + channelnr, TI_PRUSS_EVENTS -1); + return (EINVAL); + } + + sc->sc_irq_devs[irq].channel = channelnr; + sc->sc_irq_devs[irq].event = eventnr; + + // event[nr] <= channel + ti_pruss_map_write(sc, PRUSS_INTC_CMR_BASE, + eventnr, channelnr); + } + } + return (err); +} + +static int +ti_pruss_channel_map(SYSCTL_HANDLER_ARGS) +{ + struct ti_pruss_softc *sc; + int err; + char channel[sizeof(NOT_SET_STR)]; + const int8_t irq = arg2; + + sc = arg1; + + if (sc->sc_irq_devs[irq].channel == -1) + bcopy(NOT_SET_STR, channel, sizeof(channel)); + else + snprintf(channel, sizeof(channel), "%d", sc->sc_irq_devs[irq].channel); + + err = sysctl_handle_string(oidp, channel, sizeof(channel), req); + if (err != 0) + return (err); + + if (req->newptr) { // write event + if (strcmp(NOT_SET_STR, channel) == 0) { + ti_pruss_interrupts_enable(sc, irq, false); + ti_pruss_reg_write(sc, PRUSS_INTC_HIDISR, + sc->sc_irq_devs[irq].channel); + sc->sc_irq_devs[irq].channel = -1; + } else { + const int8_t channelnr = strtol(channel, NULL, 10); // TODO: check if strol is valid + if (channelnr > TI_PRUSS_IRQS || channelnr < 0) + { + device_printf(sc->sc_pdev->si_drv1, + "Channel number %d not valid (0 - %d)", + channelnr, TI_PRUSS_IRQS-1); + return (EINVAL); + } + + sc->sc_irq_devs[irq].channel = channelnr; + sc->sc_irq_devs[irq].last = -1; + + // channel[nr] <= irqnr + ti_pruss_map_write(sc, PRUSS_INTC_HMR_BASE, + irq, channelnr); + } + } + + return (err); +} + +static int +ti_pruss_interrupt_enable(SYSCTL_HANDLER_ARGS) +{ + struct ti_pruss_softc *sc; + int err; + bool irqenable; + const int8_t irq = arg2; + + sc = arg1; + irqenable = sc->sc_irq_devs[arg2].enable; + + err = sysctl_handle_bool(oidp, &irqenable, arg2, req); + if (err != 0) + return (err); + + if (req->newptr) // write enable + return ti_pruss_interrupts_enable(sc, irq, irqenable); + + return (err); +} + +static int +ti_pruss_global_interrupt_enable(SYSCTL_HANDLER_ARGS) +{ + struct ti_pruss_softc *sc; + int err; + bool glob_irqen; + + sc = arg1; + glob_irqen = sc->sc_glob_irqen; + + err = sysctl_handle_bool(oidp, &glob_irqen, arg2, req); + if (err != 0) + return (err); + + if (req->newptr) { + sc->sc_glob_irqen = glob_irqen; + ti_pruss_reg_write(sc, PRUSS_INTC_GER, glob_irqen); + } + + return (err); +} static int ti_pruss_probe(device_t dev) { @@ -167,13 +520,31 @@ ti_pruss_attach(device_t dev) sc = device_get_softc(dev); rid = 0; mtx_init(&sc->sc_mtx, "TI PRUSS", NULL, MTX_DEF); - knlist_init_mtx(&sc->sc_selinfo.si_note, &sc->sc_mtx); sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->sc_mem_res == NULL) { device_printf(dev, "could not allocate memory resource\n"); return (ENXIO); } + + struct sysctl_ctx_list *clist = device_get_sysctl_ctx(dev); + if (!clist) + return (EINVAL); + + struct sysctl_oid *poid; + poid = device_get_sysctl_tree( dev ); + if (!poid) + return (EINVAL); + + sc->sc_glob_irqen = false; + struct sysctl_oid *irq_root = SYSCTL_ADD_NODE(clist, SYSCTL_CHILDREN(poid), + OID_AUTO, "irq", CTLFLAG_RD, 0, + "PRUSS Host Interrupts"); + SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(poid), OID_AUTO, + "global_interrupt_enable", CTLFLAG_RW | CTLTYPE_U8, + sc, 0, ti_pruss_global_interrupt_enable, + "CU", "Global interrupt enable"); + sc->sc_bt = rman_get_bustag(sc->sc_mem_res); sc->sc_bh = rman_get_bushandle(sc->sc_mem_res); if (bus_alloc_resources(dev, ti_pruss_irq_spec, sc->sc_irq_res) != 0) { @@ -181,48 +552,91 @@ ti_pruss_attach(device_t dev) ti_pruss_detach(dev); return (ENXIO); } + + ti_pruss_interrupts_clear(sc); + for (i = 0; i < TI_PRUSS_IRQS; i++) { - ti_pruss_irq_args[i].irq = i; - ti_pruss_irq_args[i].sc = sc; - if (bus_setup_intr(dev, sc->sc_irq_res[i], - INTR_MPSAFE | INTR_TYPE_MISC, - NULL, ti_pruss_intr, &ti_pruss_irq_args[i], - &sc->sc_intr[i]) != 0) { - device_printf(dev, - "unable to setup the interrupt handler\n"); - ti_pruss_detach(dev); - return (ENXIO); + char name[8]; + snprintf(name, sizeof(name), "%d", i); + + struct sysctl_oid *irq_nodes = SYSCTL_ADD_NODE(clist, SYSCTL_CHILDREN(irq_root), + OID_AUTO, name, CTLFLAG_RD, 0, + "PRUSS Interrupts"); + SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO, + "channel", CTLFLAG_RW | CTLTYPE_STRING, sc, i, ti_pruss_channel_map, + "A", "Channel attached to this irq"); + SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO, + "event", CTLFLAG_RW | CTLTYPE_STRING, sc, i, ti_pruss_event_map, + "A", "Event attached to this irq"); + SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO, + "enable", CTLFLAG_RW | CTLTYPE_U8, sc, i, ti_pruss_interrupt_enable, + "CU", "Enable/Disable interrupt"); + + sc->sc_irq_devs[i].event = -1; + sc->sc_irq_devs[i].channel = -1; + sc->sc_irq_devs[i].tstamps.ctl.idx = 0; + + if (i < TI_PRUSS_HOST_IRQS) { + ti_pruss_irq_args[i].irq = i; + ti_pruss_irq_args[i].sc = sc; + if (bus_setup_intr(dev, sc->sc_irq_res[i], + INTR_MPSAFE | INTR_TYPE_MISC, + NULL, ti_pruss_intr, &ti_pruss_irq_args[i], + &sc->sc_intr[i]) != 0) { + device_printf(dev, + "unable to setup the interrupt handler\n"); + ti_pruss_detach(dev); + + return (ENXIO); + } + mtx_init(&sc->sc_irq_devs[i].sc_mtx, "TI PRUSS IRQ", NULL, MTX_DEF); + knlist_init_mtx(&sc->sc_irq_devs[i].sc_selinfo.si_note, &sc->sc_irq_devs[i].sc_mtx); } } - if (ti_pruss_reg_read(sc, PRUSS_AM18XX_INTC) == PRUSS_AM18XX_REV) - device_printf(dev, "AM18xx PRU-ICSS\n"); - else if (ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC) == PRUSS_AM33XX_REV) + + if (ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC) == PRUSS_AM33XX_REV) device_printf(dev, "AM33xx PRU-ICSS\n"); sc->sc_pdev = make_dev(&ti_pruss_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "pruss%d", device_get_unit(dev)); sc->sc_pdev->si_drv1 = dev; + /* Acc. to datasheet always write 1 to polarity registers */ + ti_pruss_reg_write(sc, PRUSS_INTC_SIPR0, 0xFFFFFFFF); + ti_pruss_reg_write(sc, PRUSS_INTC_SIPR1, 0xFFFFFFFF); + + /* Acc. to datasheet always write 0 to event type registers */ + ti_pruss_reg_write(sc, PRUSS_INTC_SITR0, 0); + ti_pruss_reg_write(sc, PRUSS_INTC_SITR1, 0); + return (0); } static int ti_pruss_detach(device_t dev) { - struct ti_pruss_softc *sc; - int i; + struct ti_pruss_softc *sc = device_get_softc(dev); + + ti_pruss_interrupts_clear(sc); + + for (int i = 0; i < TI_PRUSS_HOST_IRQS; i++) { + ti_pruss_interrupts_enable( sc, i, false ); - sc = device_get_softc(dev); - for (i = 0; i < TI_PRUSS_IRQS; i++) { if (sc->sc_intr[i]) bus_teardown_intr(dev, sc->sc_irq_res[i], sc->sc_intr[i]); if (sc->sc_irq_res[i]) bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res[i]), sc->sc_irq_res[i]); + knlist_clear(&sc->sc_irq_devs[i].sc_selinfo.si_note, 0); + mtx_lock(&sc->sc_irq_devs[i].sc_mtx); + if (!knlist_empty(&sc->sc_irq_devs[i].sc_selinfo.si_note)) + printf("IRQ %d KQueue not empty!\n", i ); + mtx_unlock(&sc->sc_irq_devs[i].sc_mtx); + knlist_destroy(&sc->sc_irq_devs[i].sc_selinfo.si_note); + mtx_destroy(&sc->sc_irq_devs[i].sc_mtx); } - knlist_clear(&sc->sc_selinfo.si_note, 0); - knlist_destroy(&sc->sc_selinfo.si_note); + mtx_destroy(&sc->sc_mtx); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res), @@ -240,19 +654,38 @@ ti_pruss_intr(void *arg) struct ti_pruss_irq_arg *iap = arg; struct ti_pruss_softc *sc = iap->sc; /* - * Interrupts pr1_host_intr[0:7] are mapped to + * Interrupts pr1_host_intr[0:7] are mapped to * Host-2 to Host-9 of PRU-ICSS IRQ-controller. */ - const int pru_int = iap->irq + 2; + const int pru_int = iap->irq + TI_PRUSS_PRU_IRQS; const int pru_int_mask = (1 << pru_int); + const int pru_channel = sc->sc_irq_devs[pru_int].channel; + const int pru_event = sc->sc_irq_devs[pru_channel].event; - val = ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC + PRUSS_INTC_HIER); - DPRINTF("interrupt %p, %d", sc, pru_int); + val = ti_pruss_reg_read(sc, PRUSS_INTC_HIER); if (!(val & pru_int_mask)) return; - ti_pruss_reg_write(sc, PRUSS_AM33XX_INTC + PRUSS_INTC_HIDISR, - pru_int); - KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, pru_int); + + ti_pruss_reg_write(sc, PRUSS_INTC_HIDISR, pru_int); + ti_pruss_reg_write(sc, PRUSS_INTC_SICR, pru_event); + ti_pruss_reg_write(sc, PRUSS_INTC_HIEISR, pru_int); + + struct ti_pruss_irqsc* irq = &sc->sc_irq_devs[pru_channel]; + size_t wr = irq->tstamps.ctl.idx; + + struct timespec ts; + nanouptime(&ts); + irq->tstamps.ts[wr] = ts.tv_sec * 1000000000 + ts.tv_nsec; + + if (++wr == TI_TS_ARRAY) + wr = 0; + atomic_add_32(&irq->tstamps.ctl.cnt, 1); + + irq->tstamps.ctl.idx = wr; + + KNOTE_UNLOCKED(&irq->sc_selinfo.si_note, pru_int); + wakeup(irq); + selwakeup(&irq->sc_selinfo); } static int @@ -270,7 +703,7 @@ ti_pruss_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, struct ti_pruss_softc *sc = device_get_softc(dev); if (offset > rman_get_size(sc->sc_mem_res)) - return (-1); + return (ENOSPC); *paddr = rman_get_start(sc->sc_mem_res) + offset; *memattr = VM_MEMATTR_UNCACHEABLE; @@ -279,31 +712,43 @@ ti_pruss_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, static struct filterops ti_pruss_kq_read = { .f_isfd = 1, - .f_detach = ti_pruss_kq_read_detach, - .f_event = ti_pruss_kq_read_event, + .f_detach = ti_pruss_irq_kqread_detach, + .f_event = ti_pruss_irq_kqevent, }; static void -ti_pruss_kq_read_detach(struct knote *kn) +ti_pruss_irq_kqread_detach(struct knote *kn) { - struct ti_pruss_softc *sc = kn->kn_hook; + struct ti_pruss_irqsc *sc = kn->kn_hook; knlist_remove(&sc->sc_selinfo.si_note, kn, 0); } static int -ti_pruss_kq_read_event(struct knote *kn, long hint) +ti_pruss_irq_kqevent(struct knote *kn, long hint) { - kn->kn_data = hint; + struct ti_pruss_irqsc* irq_sc; + int notify; - return (hint); + irq_sc = kn->kn_hook; + + if (hint > 0) + kn->kn_data = hint - 2; + + if (hint > 0 || irq_sc->last > 0) + notify = 1; + else + notify = 0; + + irq_sc->last = hint; + + return (notify); } static int -ti_pruss_kqfilter(struct cdev *cdev, struct knote *kn) +ti_pruss_irq_kqfilter(struct cdev *cdev, struct knote *kn) { - device_t dev = cdev->si_drv1; - struct ti_pruss_softc *sc = device_get_softc(dev); + struct ti_pruss_irqsc *sc = cdev->si_drv1; switch (kn->kn_filter) { case EVFILT_READ: diff --git a/sys/arm/ti/ti_pruss.h b/sys/arm/ti/ti_pruss.h index 4eea12e4f7d2..44552a5fa535 100644 --- a/sys/arm/ti/ti_pruss.h +++ b/sys/arm/ti/ti_pruss.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 Rui Paulo + * Copyright (c) 2017 Manuel Stuehn * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,8 +34,22 @@ #define PRUSS_AM33XX_REV 0x4e82A900 #define PRUSS_AM33XX_INTC 0x20000 -#define PRUSS_INTC_HIER 0x1500 -#define PRUSS_INTC_HIDISR 0x0038 -#define PRUSS_INTC_HIPIR_BASE 0x0900 +#define PRUSS_INTC_GER (PRUSS_AM33XX_INTC + 0x0010) +#define PRUSS_INTC_SISR (PRUSS_AM33XX_INTC + 0x0020) +#define PRUSS_INTC_SICR (PRUSS_AM33XX_INTC + 0x0024) +#define PRUSS_INTC_EISR (PRUSS_AM33XX_INTC + 0x0028) +#define PRUSS_INTC_EICR (PRUSS_AM33XX_INTC + 0x002C) +#define PRUSS_INTC_HIEISR (PRUSS_AM33XX_INTC + 0x0034) +#define PRUSS_INTC_HIDISR (PRUSS_AM33XX_INTC + 0x0038) +#define PRUSS_INTC_SECR0 (PRUSS_AM33XX_INTC + 0x0280) +#define PRUSS_INTC_SECR1 (PRUSS_AM33XX_INTC + 0x0284) +#define PRUSS_INTC_CMR_BASE (PRUSS_AM33XX_INTC + 0x0400) +#define PRUSS_INTC_HMR_BASE (PRUSS_AM33XX_INTC + 0x0800) +#define PRUSS_INTC_HIPIR_BASE (PRUSS_AM33XX_INTC + 0x0900) +#define PRUSS_INTC_SIPR0 (PRUSS_AM33XX_INTC + 0x0D00) +#define PRUSS_INTC_SIPR1 (PRUSS_AM33XX_INTC + 0x0D04) +#define PRUSS_INTC_SITR0 (PRUSS_AM33XX_INTC + 0x0D80) +#define PRUSS_INTC_SITR1 (PRUSS_AM33XX_INTC + 0x0D84) +#define PRUSS_INTC_HIER (PRUSS_AM33XX_INTC + 0x1500) #endif /* _TI_PRUSS_H_ */ diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c index 00c2fcfa49f2..cb7e9da65c86 100644 --- a/sys/arm/ti/ti_sdhci.c +++ b/sys/arm/ti/ti_sdhci.c @@ -683,11 +683,7 @@ ti_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); -#ifdef MMCCAM - sdhci_cam_start_slot(&sc->slot); -#else sdhci_start_slot(&sc->slot); -#endif return (0); fail: diff --git a/sys/arm/xilinx/std.zynq7 b/sys/arm/xilinx/std.zynq7 index addf7bcb663c..6690fd5e9a04 100644 --- a/sys/arm/xilinx/std.zynq7 +++ b/sys/arm/xilinx/std.zynq7 @@ -4,7 +4,7 @@ # $FreeBSD$ cpu CPU_CORTEXA -machine arm armv6 +machine arm armv7 makeoptions CONF_CFLAGS="-march=armv7a" files "../xilinx/files.zynq7" diff --git a/sys/arm/xscale/i8134x/std.i81342 b/sys/arm/xscale/i8134x/std.i81342 index 16c72ce079e5..a9ad3f92a3c8 100644 --- a/sys/arm/xscale/i8134x/std.i81342 +++ b/sys/arm/xscale/i8134x/std.i81342 @@ -1,5 +1,6 @@ #XScale i81342 generic configuration #$FreeBSD$ files "../xscale/i8134x/files.i81342" -include "../xscale/std.xscale-be" +include "../xscale/std.xscale" cpu CPU_XSCALE_81342 +machine arm diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c new file mode 100644 index 000000000000..70a66c114799 --- /dev/null +++ b/sys/arm64/arm64/efirt_machdep.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2004 Marcel Moolenaar + * Copyright (c) 2001 Doug Rabson + * Copyright (c) 2016 The FreeBSD Foundation + * Copyright (c) 2017 Andrew Turner + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static vm_object_t obj_1t1_pt; +static vm_page_t efi_l0_page; +static pd_entry_t *efi_l0; + +void +efi_destroy_1t1_map(void) +{ + vm_page_t m; + + if (obj_1t1_pt != NULL) { + VM_OBJECT_RLOCK(obj_1t1_pt); + TAILQ_FOREACH(m, &obj_1t1_pt->memq, listq) + m->wire_count = 0; + atomic_subtract_int(&vm_cnt.v_wire_count, + obj_1t1_pt->resident_page_count); + VM_OBJECT_RUNLOCK(obj_1t1_pt); + vm_object_deallocate(obj_1t1_pt); + } + + obj_1t1_pt = NULL; + efi_l0 = NULL; + efi_l0_page = NULL; +} + +static vm_page_t +efi_1t1_page(vm_pindex_t idx) +{ + + return (vm_page_grab(obj_1t1_pt, idx, VM_ALLOC_NOBUSY | + VM_ALLOC_WIRED | VM_ALLOC_ZERO)); +} + +static pt_entry_t * +efi_1t1_l3(vm_offset_t va) +{ + pd_entry_t *l0, *l1, *l2; + pt_entry_t *l3; + vm_pindex_t l0_idx, l1_idx, l2_idx; + vm_page_t m; + vm_paddr_t mphys; + + l0_idx = pmap_l0_index(va); + l0 = &efi_l0[l0_idx]; + if (*l0 == 0) { + m = efi_1t1_page(1 + l0_idx); + mphys = VM_PAGE_TO_PHYS(m); + *l0 = mphys | L0_TABLE; + } else { + mphys = *l0 & ~ATTR_MASK; + } + + l1 = (pd_entry_t *)PHYS_TO_DMAP(mphys); + l1_idx = pmap_l1_index(va); + l1 += l1_idx; + if (*l1 == 0) { + m = efi_1t1_page(1 + L0_ENTRIES + (l0_idx + 1) * (l1_idx + 1)); + mphys = VM_PAGE_TO_PHYS(m); + *l1 = mphys | L1_TABLE; + } else { + mphys = *l1 & ~ATTR_MASK; + } + + l2 = (pd_entry_t *)PHYS_TO_DMAP(mphys); + l2_idx = pmap_l2_index(va); + l2 += l2_idx; + if (*l2 == 0) { + m = efi_1t1_page(1 + L0_ENTRIES + L0_ENTRIES * Ln_ENTRIES + + (l0_idx + 1) * (l1_idx + 1) * (l2_idx + 1)); + mphys = VM_PAGE_TO_PHYS(m); + *l2 = mphys | L2_TABLE; + } else { + mphys = *l2 & ~ATTR_MASK; + } + + l3 = (pt_entry_t *)PHYS_TO_DMAP(mphys); + l3 += pmap_l3_index(va); + KASSERT(*l3 == 0, ("%s: Already mapped: va %#jx *pt %#jx", __func__, + va, *l3)); + + return (l3); +} + +/* + * Create the 1:1 virtual to physical map for EFI + */ +bool +efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) +{ + struct efi_md *p; + pt_entry_t *l3; + vm_offset_t va; + uint64_t idx; + int i, mode; + + obj_1t1_pt = vm_pager_allocate(OBJT_PHYS, NULL, L0_ENTRIES + + L0_ENTRIES * Ln_ENTRIES + L0_ENTRIES * Ln_ENTRIES * Ln_ENTRIES + + L0_ENTRIES * Ln_ENTRIES * Ln_ENTRIES * Ln_ENTRIES, + VM_PROT_ALL, 0, NULL); + VM_OBJECT_WLOCK(obj_1t1_pt); + efi_l0_page = efi_1t1_page(0); + VM_OBJECT_WUNLOCK(obj_1t1_pt); + efi_l0 = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(efi_l0_page)); + bzero(efi_l0, L0_ENTRIES * sizeof(*efi_l0)); + + for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, + descsz)) { + if ((p->md_attr & EFI_MD_ATTR_RT) == 0) + continue; + if (p->md_virt != NULL) { + if (bootverbose) + printf("EFI Runtime entry %d is mapped\n", i); + goto fail; + } + if ((p->md_phys & EFI_PAGE_MASK) != 0) { + if (bootverbose) + printf("EFI Runtime entry %d is not aligned\n", + i); + goto fail; + } + if (p->md_phys + p->md_pages * EFI_PAGE_SIZE < p->md_phys || + p->md_phys + p->md_pages * EFI_PAGE_SIZE >= + VM_MAXUSER_ADDRESS) { + printf("EFI Runtime entry %d is not in mappable for RT:" + "base %#016jx %#jx pages\n", + i, (uintmax_t)p->md_phys, + (uintmax_t)p->md_pages); + goto fail; + } + if ((p->md_attr & EFI_MD_ATTR_WB) != 0) + mode = VM_MEMATTR_WRITE_BACK; + else if ((p->md_attr & EFI_MD_ATTR_WT) != 0) + mode = VM_MEMATTR_WRITE_THROUGH; + else if ((p->md_attr & EFI_MD_ATTR_WC) != 0) + mode = VM_MEMATTR_WRITE_COMBINING; + else if ((p->md_attr & EFI_MD_ATTR_UC) != 0) + mode = VM_MEMATTR_UNCACHEABLE; + else { + if (bootverbose) + printf("EFI Runtime entry %d mapping " + "attributes unsupported\n", i); + mode = VM_MEMATTR_UNCACHEABLE; + } + + printf("MAP %lx mode %x pages %lu\n", p->md_phys, mode, p->md_pages); + VM_OBJECT_WLOCK(obj_1t1_pt); + for (va = p->md_phys, idx = 0; idx < p->md_pages; idx++, + va += PAGE_SIZE) { + l3 = efi_1t1_l3(va); + *l3 = va | ATTR_DEFAULT | ATTR_IDX(mode) | + ATTR_AP(ATTR_AP_RW) | L3_PAGE; + } + VM_OBJECT_WUNLOCK(obj_1t1_pt); + } + + return (true); +fail: + efi_destroy_1t1_map(); + return (false); +} + +int +efi_arch_enter(void) +{ + + __asm __volatile( + "msr ttbr0_el1, %0 \n" + "dsb ishst \n" + "tlbi vmalle1is \n" + "dsb ish \n" + "isb \n" + : : "r"(VM_PAGE_TO_PHYS(efi_l0_page))); + + return (0); +} + +void +efi_arch_leave(void) +{ + struct thread *td; + + td = curthread; + __asm __volatile( + "msr ttbr0_el1, %0 \n" + "dsb ishst \n" + "tlbi vmalle1is \n" + "dsb ish \n" + "isb \n" + : : "r"(td->td_proc->p_md.md_l0addr)); +} diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index c1c7738d5968..e07dad15b99f 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -343,7 +343,7 @@ gic_v3_detach(device_t dev) for (rid = 0; rid < (sc->gic_redists.nregions + 1); rid++) bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->gic_res[rid]); - for (i = 0; i < mp_ncpus; i++) + for (i = 0; i <= mp_maxid; i++) free(sc->gic_redists.pcpu[i], M_GIC_V3); free(sc->gic_res, M_GIC_V3); @@ -895,7 +895,7 @@ gic_v3_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus, val = 0; /* Iterate through all CPUs in set */ - for (i = 0; i < mp_ncpus; i++) { + for (i = 0; i <= mp_maxid; i++) { /* Move to the next affinity group */ if (aff != GIC_AFFINITY(i)) { /* Send the IPI */ @@ -1103,7 +1103,7 @@ gic_v3_redist_alloc(struct gic_v3_softc *sc) u_int cpuid; /* Allocate struct resource for all CPU's Re-Distributor registers */ - for (cpuid = 0; cpuid < mp_ncpus; cpuid++) + for (cpuid = 0; cpuid <= mp_maxid; cpuid++) if (CPU_ISSET(cpuid, &all_cpus) != 0) sc->gic_redists.pcpu[cpuid] = malloc(sizeof(*sc->gic_redists.pcpu[0]), diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c index 712dcf0228e6..0191003e4d19 100644 --- a/sys/arm64/arm64/gicv3_its.c +++ b/sys/arm64/arm64/gicv3_its.c @@ -457,7 +457,7 @@ gicv3_its_table_init(device_t dev, struct gicv3_its_softc *sc) /* Allocate the table */ table = (vm_offset_t)contigmalloc(npages * PAGE_SIZE, M_GICV3_ITS, M_WAITOK | M_ZERO, 0, (1ul << 48) - 1, - PAGE_SIZE, 0); + PAGE_SIZE_64K, 0); sc->sc_its_ptab[i].ptab_vaddr = table; sc->sc_its_ptab[i].ptab_size = npages * PAGE_SIZE; @@ -557,7 +557,7 @@ gicv3_its_pendtables_init(struct gicv3_its_softc *sc) { int i; - for (i = 0; i < mp_ncpus; i++) { + for (i = 0; i <= mp_maxid; i++) { if (CPU_ISSET(i, &sc->sc_cpus) == 0) continue; @@ -736,7 +736,7 @@ gicv3_its_attach(device_t dev) gicv3_its_cmdq_init(sc); /* Allocate the per-CPU collections */ - for (int cpu = 0; cpu < mp_ncpus; cpu++) + for (int cpu = 0; cpu <= mp_maxid; cpu++) if (CPU_ISSET(cpu, &sc->sc_cpus) != 0) sc->sc_its_cols[cpu] = malloc( sizeof(*sc->sc_its_cols[0]), M_GICV3_ITS, diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index 74bedf90ccc3..9407b446e39e 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -282,6 +282,9 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SHA2_BASE: printf("%sSHA2", SEP_STR); break; + case ID_AA64ISAR0_SHA2_512: + printf("%sSHA2+SHA512", SEP_STR); + break; default: printf("%sUnknown SHA2", SEP_STR); break; @@ -298,6 +301,50 @@ print_cpu_features(u_int cpu) break; } + switch (ID_AA64ISAR0_SHA3(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_SHA3_NONE: + break; + case ID_AA64ISAR0_SHA3_IMPL: + printf("%sSHA3", SEP_STR); + break; + default: + printf("%sUnknown SHA3", SEP_STR); + break; + } + + switch (ID_AA64ISAR0_SM3(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_SM3_NONE: + break; + case ID_AA64ISAR0_SM3_IMPL: + printf("%sSM3", SEP_STR); + break; + default: + printf("%sUnknown SM3", SEP_STR); + break; + } + + switch (ID_AA64ISAR0_SM4(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_SM4_NONE: + break; + case ID_AA64ISAR0_SM4_IMPL: + printf("%sSM4", SEP_STR); + break; + default: + printf("%sUnknown SM4", SEP_STR); + break; + } + + switch (ID_AA64ISAR0_DP(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_DP_NONE: + break; + case ID_AA64ISAR0_DP_IMPL: + printf("%sDotProd", SEP_STR); + break; + default: + printf("%sUnknown DP", SEP_STR); + break; + } + if ((cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK) != 0) printf("%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK); @@ -310,6 +357,83 @@ print_cpu_features(u_int cpu) printed = 0; printf(" Instruction Set Attributes 1 = <"); + switch (ID_AA64ISAR1_GPI(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_GPI_NONE: + break; + case ID_AA64ISAR1_GPI_IMPL: + printf("%sImpl GenericAuth", SEP_STR); + break; + default: + printf("%sUnknown GenericAuth", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_GPA(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_GPA_NONE: + break; + case ID_AA64ISAR1_GPA_IMPL: + printf("%sPrince GenericAuth", SEP_STR); + break; + default: + printf("%sUnknown GenericAuth", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_LRCPC(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_LRCPC_NONE: + break; + case ID_AA64ISAR1_LRCPC_IMPL: + printf("%sRCpc", SEP_STR); + break; + default: + printf("%sUnknown RCpc", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_FCMA(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_FCMA_NONE: + break; + case ID_AA64ISAR1_FCMA_IMPL: + printf("%sFCMA", SEP_STR); + break; + default: + printf("%sUnknown FCMA", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_JSCVT(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_JSCVT_NONE: + break; + case ID_AA64ISAR1_JSCVT_IMPL: + printf("%sJS Conv", SEP_STR); + break; + default: + printf("%sUnknown JS Conv", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_API(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_API_NONE: + break; + case ID_AA64ISAR1_API_IMPL: + printf("%sImpl AddrAuth", SEP_STR); + break; + default: + printf("%sUnknown Impl AddrAuth", SEP_STR); + break; + } + + switch (ID_AA64ISAR1_APA(cpu_desc[cpu].id_aa64isar1)) { + case ID_AA64ISAR1_APA_NONE: + break; + case ID_AA64ISAR1_APA_IMPL: + printf("%sPrince AddrAuth", SEP_STR); + break; + default: + printf("%sUnknown Prince AddrAuth", SEP_STR); + break; + } + switch (ID_AA64ISAR1_DPB(cpu_desc[cpu].id_aa64isar1)) { case ID_AA64ISAR1_DPB_NONE: break; @@ -688,6 +812,29 @@ print_cpu_features(u_int cpu) printed = 0; printf(" Memory Model Features 2 = <"); + switch (ID_AA64MMFR2_NV(cpu_desc[cpu].id_aa64mmfr2)) { + case ID_AA64MMFR2_NV_NONE: + break; + case ID_AA64MMFR2_NV_IMPL: + printf("%sNestedVirt", SEP_STR); + break; + default: + printf("%sUnknown NestedVirt", SEP_STR); + break; + } + + switch (ID_AA64MMFR2_CCIDX(cpu_desc[cpu].id_aa64mmfr2)) { + case ID_AA64MMFR2_CCIDX_32: + printf("%s32b CCIDX", SEP_STR); + break; + case ID_AA64MMFR2_CCIDX_64: + printf("%s64b CCIDX", SEP_STR); + break; + default: + printf("%sUnknown CCIDX", SEP_STR); + break; + } + switch (ID_AA64MMFR2_VA_RANGE(cpu_desc[cpu].id_aa64mmfr2)) { case ID_AA64MMFR2_VA_RANGE_48: printf("%s48b VA", SEP_STR); @@ -897,11 +1044,7 @@ identify_cpu(void) cpu_desc[cpu].id_aa64isar1 = READ_SPECIALREG(ID_AA64ISAR1_EL1); cpu_desc[cpu].id_aa64mmfr0 = READ_SPECIALREG(ID_AA64MMFR0_EL1); cpu_desc[cpu].id_aa64mmfr1 = READ_SPECIALREG(ID_AA64MMFR1_EL1); -#ifdef NOTYET cpu_desc[cpu].id_aa64mmfr2 = READ_SPECIALREG(ID_AA64MMFR2_EL1); -#else - cpu_desc[cpu].id_aa64mmfr2 = 0; -#endif cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(ID_AA64PFR0_EL1); cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(ID_AA64PFR1_EL1); diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 17933f206873..886792a9681d 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #ifdef VFP @@ -120,6 +121,12 @@ int64_t idcache_line_size; /* The minimum cache line size */ int64_t dczva_line_size; /* The size of cache line the dc zva zeroes */ int has_pan; +/* + * Physical address of the EFI System Table. Stashed from the metadata hints + * passed into the kernel and used by the EFI code to call runtime services. + */ +vm_paddr_t efi_systbl_phys; + /* pagezero_* implementations are provided in support.S */ void pagezero_simple(void *); void pagezero_cache(void *); @@ -162,6 +169,7 @@ static void cpu_startup(void *dummy) { + undef_init(); identify_cpu(); vm_ksubmap_init(&kmi); @@ -984,6 +992,8 @@ initarm(struct arm64_bootparams *abp) try_load_dtb(kmdp); #endif + efi_systbl_phys = MD_FETCH(kmdp, MODINFOMD_FW_HANDLE, vm_paddr_t); + /* Find the address to start allocating from */ lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c index 50139b1b54b9..34295be87a08 100644 --- a/sys/arm64/arm64/minidump_machdep.c +++ b/sys/arm64/arm64/minidump_machdep.c @@ -62,7 +62,6 @@ uint64_t *vm_page_dump; int vm_page_dump_size; static struct kerneldumpheader kdh; -static off_t dumplo; /* Handle chunked writes. */ static size_t fragsz; @@ -96,8 +95,7 @@ blk_flush(struct dumperinfo *di) if (fragsz == 0) return (0); - error = dump_write(di, dump_va, 0, dumplo, fragsz); - dumplo += fragsz; + error = dump_append(di, dump_va, 0, fragsz); fragsz = 0; return (error); } @@ -183,10 +181,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) wdog_kern_pat(WD_LASTVAL); if (ptr) { - error = dump_write(di, ptr, 0, dumplo, len); + error = dump_append(di, ptr, 0, len); if (error) return (error); - dumplo += len; ptr += len; sz -= len; } else { @@ -295,7 +292,7 @@ minidumpsys(struct dumperinfo *di) printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20, ptoa((uintmax_t)physmem) / 1048576); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -395,7 +392,7 @@ minidumpsys(struct dumperinfo *di) if (error) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 99c0a745eaaf..2b2d7f8fbe2c 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -236,7 +236,10 @@ release_aps(void *dummy __unused) atomic_store_rel_int(&aps_ready, 1); /* Wake up the other CPUs */ - __asm __volatile("sev"); + __asm __volatile( + "dsb ishst \n" + "sev \n" + ::: "memory"); printf("Release APs\n"); diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index e26e0a0a65d4..266559b987ea 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -105,6 +105,8 @@ __FBSDID("$FreeBSD$"); * and to when physical maps must be made correct. */ +#include "opt_vm.h" + #include #include #include @@ -306,11 +308,6 @@ pagecopy(void *s, void *d) memcpy(d, s, PAGE_SIZE); } -#define pmap_l0_index(va) (((va) >> L0_SHIFT) & L0_ADDR_MASK) -#define pmap_l1_index(va) (((va) >> L1_SHIFT) & Ln_ADDR_MASK) -#define pmap_l2_index(va) (((va) >> L2_SHIFT) & Ln_ADDR_MASK) -#define pmap_l3_index(va) (((va) >> L3_SHIFT) & Ln_ADDR_MASK) - static __inline pd_entry_t * pmap_l0(pmap_t pmap, vm_offset_t va) { @@ -2682,6 +2679,7 @@ pmap_update_entry(pmap_t pmap, pd_entry_t *pte, pd_entry_t newpte, intr_restore(intr); } +#if VM_NRESERVLEVEL > 0 /* * After promotion from 512 4KB page mappings to a single 2MB page mapping, * replace the many pv entries for the 4KB page mappings by a single pv entry @@ -2795,6 +2793,7 @@ pmap_promote_l2(pmap_t pmap, pd_entry_t *l2, vm_offset_t va, CTR2(KTR_PMAP, "pmap_promote_l2: success for va %#lx in pmap %p", va, pmap); } +#endif /* VM_NRESERVLEVEL > 0 */ /* * Insert the given physical page (p) at @@ -3050,12 +3049,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, (prot & VM_PROT_EXECUTE) != 0) cpu_icache_sync_range(va, PAGE_SIZE); +#if VM_NRESERVLEVEL > 0 if ((mpte == NULL || mpte->wire_count == NL3PG) && pmap_superpages_enabled() && (m->flags & PG_FICTITIOUS) == 0 && vm_reserv_level_iffullpop(m) == 0) { pmap_promote_l2(pmap, pde, va, &lock); } +#endif } if (lock != NULL) diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 158b0efa6d7e..3d81cebf5edd 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef KDTRACE_HOOKS #include @@ -332,6 +333,10 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) panic("No debugger in kernel.\n"); #endif break; + case EXCP_UNKNOWN: + if (undef_insn(1, frame)) + break; + /* FALLTHROUGH */ default: print_registers(frame); panic("Unknown kernel exception %x esr_el1 %lx\n", exception, @@ -341,20 +346,6 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) td->td_frame = oframe; } -/* - * The attempted execution of an instruction bit pattern that has no allocated - * instruction results in an exception with an unknown reason. - */ -static void -el0_excp_unknown(struct trapframe *frame, uint64_t far) -{ - struct thread *td; - - td = curthread; - call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); - userret(td, frame); -} - void do_el0_sync(struct thread *td, struct trapframe *frame) { @@ -399,7 +390,9 @@ do_el0_sync(struct thread *td, struct trapframe *frame) data_abort(td, frame, esr, far, 1); break; case EXCP_UNKNOWN: - el0_excp_unknown(frame, far); + if (!undef_insn(0, frame)) + call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); + userret(td, frame); break; case EXCP_SP_ALIGN: call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp); diff --git a/sys/arm64/arm64/undefined.c b/sys/arm64/arm64/undefined.c new file mode 100644 index 000000000000..1e78a358b7e0 --- /dev/null +++ b/sys/arm64/arm64/undefined.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2017 Andrew Turner + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +MALLOC_DEFINE(M_UNDEF, "undefhandler", "Undefined instruction handler data"); + +struct undef_handler { + LIST_ENTRY(undef_handler) uh_link; + undef_handler_t uh_handler; +}; + +/* + * Create two undefined instruction handler lists, one for userspace, one for + * the kernel. This allows us to handle instructions that will trap + */ +LIST_HEAD(, undef_handler) undef_handlers[2]; + +/* + * Work around a bug in QEMU prior to 2.5.1 where reading unknown ID + * registers would raise an exception when they should return 0. + */ +static int +id_aa64mmfr2_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, + uint32_t esr) +{ + int reg; + +#define MRS_MASK 0xfff00000 +#define MRS_VALUE 0xd5300000 +#define MRS_REGISTER(insn) ((insn) & 0x1f) +#define MRS_ID_AA64MMFR2_EL0_MASK (MRS_MASK | 0x000fffe0) +#define MRS_ID_AA64MMFR2_EL0_VALUE (MRS_VALUE | 0x00080740) + + /* mrs xn, id_aa64mfr2_el1 */ + if ((insn & MRS_ID_AA64MMFR2_EL0_MASK) == MRS_ID_AA64MMFR2_EL0_VALUE) { + reg = MRS_REGISTER(insn); + + frame->tf_elr += INSN_SIZE; + if (reg < nitems(frame->tf_x)) { + frame->tf_x[reg] = 0; + } else if (reg == 30) { + frame->tf_lr = 0; + } + /* If reg is 32 then write to xzr, i.e. do nothing */ + + return (1); + } + return (0); +} + +void +undef_init(void) +{ + + LIST_INIT(&undef_handlers[0]); + LIST_INIT(&undef_handlers[1]); + + install_undef_handler(false, id_aa64mmfr2_handler); +} + +void * +install_undef_handler(bool user, undef_handler_t func) +{ + struct undef_handler *uh; + + uh = malloc(sizeof(*uh), M_UNDEF, M_WAITOK); + uh->uh_handler = func; + LIST_INSERT_HEAD(&undef_handlers[user ? 0 : 1], uh, uh_link); + + return (uh); +} + +void +remove_undef_handler(void *handle) +{ + struct undef_handler *uh; + + uh = handle; + LIST_REMOVE(uh, uh_link); + free(handle, M_UNDEF); +} + +int +undef_insn(u_int el, struct trapframe *frame) +{ + struct undef_handler *uh; + uint32_t insn; + int ret; + + KASSERT(el < 2, ("Invalid exception level %u", el)); + + if (el == 0) { + ret = fueword32((uint32_t *)frame->tf_elr, &insn); + if (ret != 0) + panic("Unable to read userspace faulting instruction"); + } else { + insn = *(uint32_t *)frame->tf_elr; + } + + LIST_FOREACH(uh, &undef_handlers[el], uh_link) { + ret = uh->uh_handler(frame->tf_elr, insn, frame, frame->tf_esr); + if (ret) + return (1); + } + + return (0); +} diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 4b580cd51089..83bd487c9419 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -26,10 +26,11 @@ makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security -options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_HHOOK # hhook(9) framework for TCP options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol diff --git a/sys/arm64/conf/GENERIC-NODEBUG b/sys/arm64/conf/GENERIC-NODEBUG index c052d7f7bd02..6758caef62b8 100644 --- a/sys/arm64/conf/GENERIC-NODEBUG +++ b/sys/arm64/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm64/conf/GENERIC-UP b/sys/arm64/conf/GENERIC-UP index 031d4c377777..f6c4e6edeca9 100644 --- a/sys/arm64/conf/GENERIC-UP +++ b/sys/arm64/conf/GENERIC-UP @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index c8d381e019bd..a7a15fc87850 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -205,7 +205,7 @@ #define ID_AA64DFR0_PMS_VER_V1 (0x1ul << ID_AA64DFR0_PMS_VER_SHIFT) /* ID_AA64ISAR0_EL1 */ -#define ID_AA64ISAR0_MASK 0xf0fffff0 +#define ID_AA64ISAR0_MASK 0x0000fffff0fffff0ul #define ID_AA64ISAR0_AES_SHIFT 4 #define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT) #define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK) @@ -222,6 +222,7 @@ #define ID_AA64ISAR0_SHA2(x) ((x) & ID_AA64ISAR0_SHA2_MASK) #define ID_AA64ISAR0_SHA2_NONE (0x0 << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_SHA2_BASE (0x1 << ID_AA64ISAR0_SHA2_SHIFT) +#define ID_AA64ISAR0_SHA2_512 (0x2 << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_CRC32_SHIFT 16 #define ID_AA64ISAR0_CRC32_MASK (0xf << ID_AA64ISAR0_CRC32_SHIFT) #define ID_AA64ISAR0_CRC32(x) ((x) & ID_AA64ISAR0_CRC32_MASK) @@ -237,14 +238,69 @@ #define ID_AA64ISAR0_RDM(x) ((x) & ID_AA64ISAR0_RDM_MASK) #define ID_AA64ISAR0_RDM_NONE (0x0 << ID_AA64ISAR0_RDM_SHIFT) #define ID_AA64ISAR0_RDM_IMPL (0x1 << ID_AA64ISAR0_RDM_SHIFT) +#define ID_AA64ISAR0_SHA3_SHIFT 32 +#define ID_AA64ISAR0_SHA3_MASK (0xful << ID_AA64ISAR0_SHA3_SHIFT) +#define ID_AA64ISAR0_SHA3(x) ((x) & ID_AA64ISAR0_SHA3_MASK) +#define ID_AA64ISAR0_SHA3_NONE (0x0ul << ID_AA64ISAR0_SHA3_SHIFT) +#define ID_AA64ISAR0_SHA3_IMPL (0x1ul << ID_AA64ISAR0_SHA3_SHIFT) +#define ID_AA64ISAR0_SM3_SHIFT 36 +#define ID_AA64ISAR0_SM3_MASK (0xful << ID_AA64ISAR0_SM3_SHIFT) +#define ID_AA64ISAR0_SM3(x) ((x) & ID_AA64ISAR0_SM3_MASK) +#define ID_AA64ISAR0_SM3_NONE (0x0ul << ID_AA64ISAR0_SM3_SHIFT) +#define ID_AA64ISAR0_SM3_IMPL (0x1ul << ID_AA64ISAR0_SM3_SHIFT) +#define ID_AA64ISAR0_SM4_SHIFT 40 +#define ID_AA64ISAR0_SM4_MASK (0xful << ID_AA64ISAR0_SM4_SHIFT) +#define ID_AA64ISAR0_SM4(x) ((x) & ID_AA64ISAR0_SM4_MASK) +#define ID_AA64ISAR0_SM4_NONE (0x0ul << ID_AA64ISAR0_SM4_SHIFT) +#define ID_AA64ISAR0_SM4_IMPL (0x1ul << ID_AA64ISAR0_SM4_SHIFT) +#define ID_AA64ISAR0_DP_SHIFT 48 +#define ID_AA64ISAR0_DP_MASK (0xful << ID_AA64ISAR0_DP_SHIFT) +#define ID_AA64ISAR0_DP(x) ((x) & ID_AA64ISAR0_DP_MASK) +#define ID_AA64ISAR0_DP_NONE (0x0ul << ID_AA64ISAR0_DP_SHIFT) +#define ID_AA64ISAR0_DP_IMPL (0x1ul << ID_AA64ISAR0_DP_SHIFT) /* ID_AA64ISAR1_EL1 */ -#define ID_AA64ISAR1_MASK 0x0000000f +#define ID_AA64ISAR1_MASK 0xffffffff #define ID_AA64ISAR1_DPB_SHIFT 0 #define ID_AA64ISAR1_DPB_MASK (0xf << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_DPB(x) ((x) & ID_AA64ISAR1_DPB_MASK) #define ID_AA64ISAR1_DPB_NONE (0x0 << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_DPB_IMPL (0x1 << ID_AA64ISAR1_DPB_SHIFT) +#define ID_AA64ISAR1_APA_SHIFT 4 +#define ID_AA64ISAR1_APA_MASK (0xf << ID_AA64ISAR1_APA_SHIFT) +#define ID_AA64ISAR1_APA(x) ((x) & ID_AA64ISAR1_APA_MASK) +#define ID_AA64ISAR1_APA_NONE (0x0 << ID_AA64ISAR1_APA_SHIFT) +#define ID_AA64ISAR1_APA_IMPL (0x1 << ID_AA64ISAR1_APA_SHIFT) +#define ID_AA64ISAR1_API_SHIFT 8 +#define ID_AA64ISAR1_API_MASK (0xf << ID_AA64ISAR1_API_SHIFT) +#define ID_AA64ISAR1_API(x) ((x) & ID_AA64ISAR1_API_MASK) +#define ID_AA64ISAR1_API_NONE (0x0 << ID_AA64ISAR1_API_SHIFT) +#define ID_AA64ISAR1_API_IMPL (0x1 << ID_AA64ISAR1_API_SHIFT) +#define ID_AA64ISAR1_JSCVT_SHIFT 12 +#define ID_AA64ISAR1_JSCVT_MASK (0xf << ID_AA64ISAR1_JSCVT_SHIFT) +#define ID_AA64ISAR1_JSCVT(x) ((x) & ID_AA64ISAR1_JSCVT_MASK) +#define ID_AA64ISAR1_JSCVT_NONE (0x0 << ID_AA64ISAR1_JSCVT_SHIFT) +#define ID_AA64ISAR1_JSCVT_IMPL (0x1 << ID_AA64ISAR1_JSCVT_SHIFT) +#define ID_AA64ISAR1_FCMA_SHIFT 16 +#define ID_AA64ISAR1_FCMA_MASK (0xf << ID_AA64ISAR1_FCMA_SHIFT) +#define ID_AA64ISAR1_FCMA(x) ((x) & ID_AA64ISAR1_FCMA_MASK) +#define ID_AA64ISAR1_FCMA_NONE (0x0 << ID_AA64ISAR1_FCMA_SHIFT) +#define ID_AA64ISAR1_FCMA_IMPL (0x1 << ID_AA64ISAR1_FCMA_SHIFT) +#define ID_AA64ISAR1_LRCPC_SHIFT 20 +#define ID_AA64ISAR1_LRCPC_MASK (0xf << ID_AA64ISAR1_LRCPC_SHIFT) +#define ID_AA64ISAR1_LRCPC(x) ((x) & ID_AA64ISAR1_LRCPC_MASK) +#define ID_AA64ISAR1_LRCPC_NONE (0x0 << ID_AA64ISAR1_LRCPC_SHIFT) +#define ID_AA64ISAR1_LRCPC_IMPL (0x1 << ID_AA64ISAR1_LRCPC_SHIFT) +#define ID_AA64ISAR1_GPA_SHIFT 24 +#define ID_AA64ISAR1_GPA_MASK (0xf << ID_AA64ISAR1_GPA_SHIFT) +#define ID_AA64ISAR1_GPA(x) ((x) & ID_AA64ISAR1_GPA_MASK) +#define ID_AA64ISAR1_GPA_NONE (0x0 << ID_AA64ISAR1_GPA_SHIFT) +#define ID_AA64ISAR1_GPA_IMPL (0x1 << ID_AA64ISAR1_GPA_SHIFT) +#define ID_AA64ISAR1_GPI_SHIFT 28 +#define ID_AA64ISAR1_GPI_MASK (0xf << ID_AA64ISAR1_GPI_SHIFT) +#define ID_AA64ISAR1_GPI(x) ((x) & ID_AA64ISAR1_GPI_MASK) +#define ID_AA64ISAR1_GPI_NONE (0x0 << ID_AA64ISAR1_GPI_SHIFT) +#define ID_AA64ISAR1_GPI_IMPL (0x1 << ID_AA64ISAR1_GPI_SHIFT) /* ID_AA64MMFR0_EL1 */ #define ID_AA64MMFR0_MASK 0xffffffff @@ -342,7 +398,7 @@ /* ID_AA64MMFR2_EL1 */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 -#define ID_AA64MMFR2_MASK 0x000fffff +#define ID_AA64MMFR2_MASK 0x0fffffff #define ID_AA64MMFR2_CNP_SHIFT 0 #define ID_AA64MMFR2_CNP_MASK (0xf << ID_AA64MMFR2_CNP_SHIFT) #define ID_AA64MMFR2_CNP(x) ((x) & ID_AA64MMFR2_CNP_MASK) @@ -368,6 +424,16 @@ #define ID_AA64MMFR2_VA_RANGE(x) ((x) & ID_AA64MMFR2_VA_RANGE_MASK) #define ID_AA64MMFR2_VA_RANGE_48 (0x0 << ID_AA64MMFR2_VA_RANGE_SHIFT) #define ID_AA64MMFR2_VA_RANGE_52 (0x1 << ID_AA64MMFR2_VA_RANGE_SHIFT) +#define ID_AA64MMFR2_CCIDX_SHIFT 20 +#define ID_AA64MMFR2_CCIDX_MASK (0xf << ID_AA64MMFR2_CCIDX_SHIFT) +#define ID_AA64MMFR2_CCIDX(x) ((x) & ID_AA64MMFR2_CCIDX_MASK) +#define ID_AA64MMFR2_CCIDX_32 (0x0 << ID_AA64MMFR2_CCIDX_SHIFT) +#define ID_AA64MMFR2_CCIDX_64 (0x1 << ID_AA64MMFR2_CCIDX_SHIFT) +#define ID_AA64MMFR2_NV_SHIFT 24 +#define ID_AA64MMFR2_NV_MASK (0xf << ID_AA64MMFR2_NV_SHIFT) +#define ID_AA64MMFR2_NV(x) ((x) & ID_AA64MMFR2_NV_MASK) +#define ID_AA64MMFR2_NV_NONE (0x0 << ID_AA64MMFR2_NV_SHIFT) +#define ID_AA64MMFR2_NV_IMPL (0x1 << ID_AA64MMFR2_NV_SHIFT) /* ID_AA64PFR0_EL1 */ #define ID_AA64PFR0_MASK 0x0000000ffffffffful diff --git a/sys/arm64/include/efi.h b/sys/arm64/include/efi.h index 026a1822d9ed..6673adccb34f 100644 --- a/sys/arm64/include/efi.h +++ b/sys/arm64/include/efi.h @@ -1,5 +1,31 @@ /*- - * This file is in the public domain since it's just boilerplate. + * Copyright (c) 2017 Andrew Turner + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AUTHOR 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 AUTHOR 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. * * $FreeBSD$ */ @@ -9,4 +35,10 @@ #define EFIABI_ATTR +#ifdef _KERNEL +#define EFI_TIME_LOCK() +#define EFI_TIME_UNLOCK() +#define EFI_TIME_OWNED() +#endif + #endif /* __ARM64_INCLUDE_EFI_H_ */ diff --git a/sys/arm64/include/elf.h b/sys/arm64/include/elf.h index 32f2e64d9ae1..ed85d3a92485 100644 --- a/sys/arm64/include/elf.h +++ b/sys/arm64/include/elf.h @@ -90,8 +90,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #define ELF_TARG_CLASS ELFCLASS64 diff --git a/sys/arm64/include/fpu.h b/sys/arm64/include/fpu.h new file mode 100644 index 000000000000..bd543d0d8e61 --- /dev/null +++ b/sys/arm64/include/fpu.h @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + * + * $FreeBSD$ + */ +#include diff --git a/sys/arm64/include/metadata.h b/sys/arm64/include/metadata.h index 090e9088d68b..dc98620304e4 100644 --- a/sys/arm64/include/metadata.h +++ b/sys/arm64/include/metadata.h @@ -31,6 +31,7 @@ #define MODINFOMD_EFI_MAP 0x1001 #define MODINFOMD_DTBP 0x1002 +#define MODINFOMD_EFI_FB 0x1003 struct efi_map_header { size_t memory_size; @@ -38,4 +39,16 @@ struct efi_map_header { uint32_t descriptor_version; }; +struct efi_fb { + uint64_t fb_addr; + uint64_t fb_size; + uint32_t fb_height; + uint32_t fb_width; + uint32_t fb_stride; + uint32_t fb_mask_red; + uint32_t fb_mask_green; + uint32_t fb_mask_blue; + uint32_t fb_mask_reserved; +}; + #endif /* !_MACHINE_METADATA_H_ */ diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h index 50cf3d762553..26421a61bafb 100644 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -118,6 +118,11 @@ typedef uint64_t pt_entry_t; /* page table entry */ #define Ln_ADDR_MASK (Ln_ENTRIES - 1) #define Ln_TABLE_MASK ((1 << 12) - 1) +#define pmap_l0_index(va) (((va) >> L0_SHIFT) & L0_ADDR_MASK) +#define pmap_l1_index(va) (((va) >> L1_SHIFT) & Ln_ADDR_MASK) +#define pmap_l2_index(va) (((va) >> L2_SHIFT) & Ln_ADDR_MASK) +#define pmap_l3_index(va) (((va) >> L3_SHIFT) & Ln_ADDR_MASK) + #endif /* !_MACHINE_PTE_H_ */ /* End of pte.h */ diff --git a/sys/arm64/include/undefined.h b/sys/arm64/include/undefined.h new file mode 100644 index 000000000000..7fded28c31f2 --- /dev/null +++ b/sys/arm64/include/undefined.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2017 Andrew Turner + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE__UNDEFINED_H_ +#define _MACHINE__UNDEFINED_H_ + +typedef int (*undef_handler_t)(vm_offset_t, uint32_t, struct trapframe *, + uint32_t); + +void undef_init(void); +void *install_undef_handler(bool, undef_handler_t); +void remove_undef_handler(void *); +int undef_insn(u_int, struct trapframe *); + +#endif diff --git a/sys/boot/Makefile b/sys/boot/Makefile index 260765126440..523418965871 100644 --- a/sys/boot/Makefile +++ b/sys/boot/Makefile @@ -2,20 +2,19 @@ .include +SUBDIR+= libsa .if ${MK_FORTH} != "no" # Build the add-in FORTH interpreter. SUBDIR+= ficl SUBDIR+= forth .endif -SUBDIR+= common +SUBDIR+= man .include -# Pick the machine-dependent subdir based on the target architecture. -ADIR= ${MACHINE:S/powerpc64/powerpc/} -.if exists(${.CURDIR}/${ADIR}/.) -SUBDIR+= ${ADIR} +.if exists(${.CURDIR}/${MACHINE}/.) +SUBDIR+= ${MACHINE} .endif .include diff --git a/sys/boot/Makefile.amd64 b/sys/boot/Makefile.amd64 index 5e730bd6c62f..08f9f50d88d4 100644 --- a/sys/boot/Makefile.amd64 +++ b/sys/boot/Makefile.amd64 @@ -1,16 +1,16 @@ # $FreeBSD$ -SUBDIR+= efi -SUBDIR+= libstand32 -SUBDIR+= zfs -SUBDIR+= userboot - -.if !defined(LOADER_NO_GELI_SUPPORT) -SUBDIR+= geli -.endif - +SUBDIR+= libsa32 +SUBDIR+= zfs zfs32 .if ${MK_FORTH} != "no" SUBDIR+= ficl32 .endif +SUBDIR+= efi +SUBDIR+= userboot + +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" +SUBDIR+= geli +.endif + SUBDIR+= i386 diff --git a/sys/boot/Makefile.arm b/sys/boot/Makefile.arm index bb0e01cb5fcf..387b77bd344d 100644 --- a/sys/boot/Makefile.arm +++ b/sys/boot/Makefile.arm @@ -3,5 +3,8 @@ .if ${MK_FDT} != "no" SUBDIR+= fdt .endif +.if ${MK_ZFS} != "no" +SUBDIR+= zfs +.endif SUBDIR+= efi uboot diff --git a/sys/boot/Makefile.arm64 b/sys/boot/Makefile.arm64 index 116e903020fc..bf0fd3988c15 100644 --- a/sys/boot/Makefile.arm64 +++ b/sys/boot/Makefile.arm64 @@ -3,5 +3,8 @@ .if ${MK_FDT} != "no" SUBDIR+= fdt .endif +.if ${MK_ZFS} != "no" +SUBDIR+= zfs +.endif SUBDIR+= efi diff --git a/sys/boot/Makefile.ficl b/sys/boot/Makefile.ficl deleted file mode 100644 index ef9a11de347a..000000000000 --- a/sys/boot/Makefile.ficl +++ /dev/null @@ -1,43 +0,0 @@ -# $FreeBSD$ - -# Common flags to build FICL related files - -FICLDIR?= ${SRCTOP}/sys/boot/ficl - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -FICL_CPUARCH= i386 -.elif ${MACHINE_ARCH:Mmips64*} != "" -FICL_CPUARCH= mips64 -.else -FICL_CPUARCH= ${MACHINE_CPUARCH} -.endif - -.PATH: ${FICLDIR} ${FICLDIR}/${FICL_CPUARCH} - -.if ${MACHINE_CPUARCH} == "amd64" -.if defined(FICL32) -CFLAGS+= -m32 -I. -.else -CFLAGS+= -fPIC -.endif -.endif - -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -I. -.endif - -CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ - -I${FICLDIR}/../common - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -.if !exists(machine) -${SRCS:M*.c:R:S/$/.o/g}: machine - -beforedepend ${OBJS}: machine -.endif - -machine: .NOMETA - ln -sf ${.CURDIR}/../../i386/include machine - -CLEANFILES+= machine -.endif diff --git a/sys/boot/Makefile.i386 b/sys/boot/Makefile.i386 index 7c1990558ea7..a5c6f673477c 100644 --- a/sys/boot/Makefile.i386 +++ b/sys/boot/Makefile.i386 @@ -1,9 +1,9 @@ # $FreeBSD$ -SUBDIR+= efi -SUBDIR+= libstand32 -SUBDIR+= zfs - -.if !defined(LOADER_NO_GELI_SUPPORT) +SUBDIR+= libsa32 +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" SUBDIR+= geli .endif +SUBDIR+= zfs + +SUBDIR+= efi diff --git a/sys/boot/Makefile.inc b/sys/boot/Makefile.inc index 1f1ccc292326..cf833d92423d 100644 --- a/sys/boot/Makefile.inc +++ b/sys/boot/Makefile.inc @@ -1,6 +1,11 @@ # $FreeBSD$ -.include +.include "defs.mk" + +.if !defined(__BOOT_MAKEFILE_INC__) +__BOOT_MAKEFILE_INC__=${MFILE} + +CFLAGS+=-I${SASRC} SSP_CFLAGS= @@ -22,3 +27,11 @@ CFLAGS.clang+= -mfpu=none # when this test succeeds rather than require dd to be a bootstrap tool. DD_NOSTATUS!=(dd status=none count=0 2> /dev/null && echo status=none) || true DD=dd ${DD_NOSTATUS} + +.if ${MK_LOADER_FORCE_LE} != "no" +.if ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -mlittle-endian +.endif +.endif + +.endif diff --git a/sys/boot/Makefile.powerpc b/sys/boot/Makefile.powerpc index 6d76e7094511..b7660f4600d4 100644 --- a/sys/boot/Makefile.powerpc +++ b/sys/boot/Makefile.powerpc @@ -4,6 +4,5 @@ SUBDIR+= fdt .endif -SUBDIR+= libstand32 SUBDIR+= ofw SUBDIR+= uboot diff --git a/sys/boot/README b/sys/boot/README deleted file mode 100644 index 22faea26b80c..000000000000 --- a/sys/boot/README +++ /dev/null @@ -1,238 +0,0 @@ -$FreeBSD$ - - README file, for the boot config file setup. This is meant - to explain how to manage the loader configuration process. - The boot and loading process is either defined, or being - defined in boot(8) and loader(8). - - The ongoing development of the FreeBSD bootloader, and its - rapid deployment while still in the development phase, has - resulted in a large number of installations with outdated - configurations. Those installations actively tracking the - FreeBSD development should also ensure that their bootloader - configurations are updated. If you see files discussed here - that your system doesn't yet have, add them yourself. - - This is an effort to give the currently correct method for - setting up your boot process. It includes information on - setting up screen savers and plug and play information, and - also on recording any changes you make in your kernel - configuration. This file is temporary, because as I noted, - the process is still undergoing development, and will still - change. Man pages are coming out, but they're still going - to be somewhat fragile for a while. If you note anything in - here that's broken, it would be a good idea to report it to - the FreeBSD-current list, or to Daniel C. Sobral - or Mike Smith . - - After the first two stages in the booting process (described - in boot(8)), the last stage of the booting process, called - the loader (see loader(8)) reads in the /boot/loader.rc - file. The two lines you should have there are: - - include /boot/loader.4th - start - - This reads the ficl (forth) initialization files, then - /boot/default/loader.conf. This file, which strongly - resembles in form /etc/rc.conf but functions quite - differently, has spots for endless user customization but - isn't yet completely finished. For one thing, it used to - assume a /kernel.config instead of a /boot/kernel.conf. - Watch the first few lines of /boot/defaults/loader.conf to - see if the file name changes. - - [See the section at the end on loader.conf syntax] - - You don't actually want to make any changes to - /boot/defaults/loader.conf, the file that is a hacking- - target is: - - /boot/loader.conf - - and might very likely not exist yet on your system). You - should copy /boot/defaults/loader.conf to /boot/loader.conf, - and then cut out anything you didn't want changed. - - The start command also loads your kernel for you, so don't - put any lines in there like "load kernel", they'll fail (but - really have already worked for you). Start also reads in - the file /boot/defaults/loader.conf and /boot/loader.conf. - If you don't have /boot/loader.conf, you'll see a message on - boot about it, but it's a warning only, no other effects. - See the section on loader.conf syntax at the end of this - document, for some more pointers on loader.conf syntax. - - The best way to manage splash screens is with entries in - /boot/loader.conf, and this is very clearly illustrated in - /boot/defaults/loader.conf (which you could just copy over - to /boot/loader.conf). I'm going to illustrate here how you - *could* do it in /boot/loader.rc (for information only) - but I don't recommend you do this; use the - /boot/defaults/loader.conf syntax, it's easier to get it - correct. - - You can load your splash screen by putting the following - lines into /boot/loader.rc: - - load splash_bmp - load -t splash_image_data /path/to/file.bmp - - The top line causes the splash_bmp module to get loaded. - The second line has the parameter "-t" which tells the - loader that the class of DATA being loaded is not a module, - but instead a splash_image_data located in file - /path/to/file.bmp. - - To get your plug and play data correctly set, run kget, - redirecting the output to /boot/kernel.conf. Note that kget - right now adds an extra "q" to it's output (from the q for - quit you press when you exit config), and if you want, you - can remove that from the file. Kget reports data only, so - feel free to run it, just to see the output. Make certain - you have the kernel option USERCONFIG set in your kernel, so - that you can do a boot -c, to initially set your cards up. - Then, edit /boot/loader.conf so that the following line - shows up (overwriting, in effect, a similar line in - /boot/default/loader.conf): - - userconfig_script_load="YES" - - My own pnp line looks like: - pnp 1 0 os irq0 15 irq1 0 drq0 1 drq1 0 port0 1332 - (kget changes numbers from hexadecimal to decimal). Note - that, at this moment, the change from using /kernel.config - to using /boot/kernel.conf as the storage place for kernel - config changes is going on. Take a look at your - /boot/defaults/loader.conf, see what's defined as - userconfig_script_name, and if you override, make sure the - file exists. Note that the loader only has access to the - root filesystem, so be careful where you tell it to read - from. - - - o If you interrupt autoboot, you'll engage interactive - mode with loader. Everything you type will have the - same effects as if it were lines in /boot/loader.rc. - - o While in interactive mode, you can get help by typing - "?", "help [ []]" and "help index". - These are mostly commands one would expect a normal - user to use. I recommend you play with them a little, - to gain further familiarity with what's going on. - - Note that it is not possible to damage or corrupt your - system while experimenting with the loader, as it - cannot write to any of your filesystems. - - o The command "unload" will unload everything. This is - very useful. Once loader.rc has finished and the - system is in the autoboot count-down, you will usually - have the kernel and other modules loaded. Now, suppose - your new /kernel is broken, how do you load - /kernel.old? By typing: - - unload - load kernel.old - [any other modules you wish to load] - boot - - o If you use loader.conf, you can do: - - unload - set kernel=kernel.old - boot-conf - - this will then load all the modules you have - configured, using kernel.old as kernel, and boot. - - o From loader, you can use the command "more" to read the - contents of /boot/loader.rc, if you wish. This is not - FreeBSD's more. It is one of loader's builtin commands. - Useful if you can't quite recall what you have there. - :-) Of course, you can use this command to read - anything else you want. - - o "boot -flag" works, "boot kernelname" works, "boot - -flag kernelname" doesn't. "boot kernelname -flag" - might work, but I'm not sure. The problem is that these - flags are kernel's flags, not boot's flags. - - o There are a number of variables that can be set. You - can see them in loader.conf, but you can get much more - detailed information using the "help" command, eg. help - set . - - o The variable root_disk_unit is particularly important, - as it solves a relatively common problem. This problem - shows when the BIOS assign disk units in a different - way than the kernel. For example, if you have two IDE - disks, one on the primary, the other on the secondary - controller, and both as master, the default in most - kernels is having the first as wd0, and the second as - wd2. If your root partition is in wd2, you'll get an - error, because the BIOS sees these disks as 0 and 1 - (well, 1 and 2), and that's what loader tells the - kernel. In this case, "set root_disk_unit=2" solves the - problem. You use this whenever the kernel fails to - mount to root partition because it has a wrong unit - number. - - FILE OVERVIEW - - - o /boot/defaults/loader.conf -- Master configuration - file, not to be edited. Overridden by - /boot/loader.conf. - - o /boot/loader.conf -- local system customization file, - in form very much like /boot/defaults/loader.conf. - This file is meant to be used by local users and the - sysinstall process. - - o /boot/loader.conf.local -- local installation override - file. This is intended for use by installations with - large numbers of systems, to allow global policy - overrides. No FreeBSD tools should ever write this - file. - - o /kernel.config -- old location of kernel configuration - changes (like pnp changes). - - o /boot/kernel.conf -- new location for kernel - configuration changes. - - o /boot/loader.rc -- loader initial configuration file, - chiefly used to source in a forth file, and start the - configuration process. - - NOTES ON LOADER.CONF SYNTAX - - I'm copy here from the last 11 lines from - /boot/defaults/loader.conf: - - ############################################################## - ### Module loading syntax example ########################## - ############################################################## - - #module_load="YES" # loads module "module" - #module_name="realname" # uses "realname" instead of "module" - #module_type="type" # passes "-t type" to load - #module_flags="flags" # passes "flags" to the module - #module_before="cmd" # executes "cmd" before loading module - #module_after="cmd" # executes "cmd" after loading module - #module_error="cmd" # executes "cmd" if load fails - - The way this works, the command processor used by the loader - (which is a subset of forth) inspects these variables for - their suffix, and the 7 lines above illustrate all the - currently defined suffixes, and their use. Take the part - before the underscore, and customize it i(make it unique) - for your particular use, keeping the suffix to allow the - particular function you want to activate. Extra underscores - are fine, because it's only the sufixes that are scanned - for. - - - - (authors Chuck Robey and Daniel Sobral). diff --git a/sys/boot/arm/at91/Makefile b/sys/boot/arm/at91/Makefile deleted file mode 100644 index 266c0ad567ea..000000000000 --- a/sys/boot/arm/at91/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -SUBDIR= libat91 boot0 boot0iic boot0spi boot2 bootiic bootspi - -.include diff --git a/sys/boot/arm/at91/Makefile.inc b/sys/boot/arm/at91/Makefile.inc deleted file mode 100644 index 3c6f5ca8b05f..000000000000 --- a/sys/boot/arm/at91/Makefile.inc +++ /dev/null @@ -1,57 +0,0 @@ -# $FreeBSD$ - -.if !target(__at91_boot_Makefile.inc__) -.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm - -__at91_boot_Makefile.inc__: - -# tsc, bwct, kb920x, centipad are the supported flavors -BOOT_FLAVOR?=kb920x - -CFLAGS=-Os -mcpu=arm9 -ffreestanding \ - -I${.CURDIR}/../libat91 \ - -I${.CURDIR}/../../../.. \ - -I${.CURDIR}/../../../../arm \ - -D_KERNEL \ - -Wall -Waggregate-return \ - -Wnested-externs \ - -Wpointer-arith -Wshadow -Wwrite-strings \ - -Werror \ - -Wmissing-prototypes \ - -Wmissing-declarations -# -Wstrict-prototypes - -CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu} - -LIBAT91=${.OBJDIR}/../libat91/libat91.a - -LD ?= ld -OBJCOPY ?= objcopy - -.if defined(P) -${P}: ${P}.out - ${OBJCOPY} -S -O binary ${P}.out ${.TARGET} - @set -- `ls -l ${.TARGET}`; x=$$((12288-$$5)); \ - echo "$$x bytes available"; test $$x -ge 0 - -${P}.out: ${OBJS} - ${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LIBAT91} - -CLEANFILES+= ${P} ${P}.out -.endif - -.if defined(WITH_TAG_LIST) -MK_TAG_LIST:=yes -.else -MK_TAG_LIST:=no -.endif - -.if defined(WITH_FPGA) -MK_FPGA:=yes -.else -MK_FPGA:=no -.endif - -.endif - -.include "../Makefile.inc" diff --git a/sys/boot/arm/at91/boot0/Makefile b/sys/boot/arm/at91/boot0/Makefile deleted file mode 100644 index 8c22cc9967a5..000000000000 --- a/sys/boot/arm/at91/boot0/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../libat91 - -P=boot0 -FILES=${P} -SRCS=arm_init.S main.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -CFLAGS+=-DBOOT_BOOT0 diff --git a/sys/boot/arm/at91/boot0/README b/sys/boot/arm/at91/boot0/README deleted file mode 100644 index 1d617d6fd812..000000000000 --- a/sys/boot/arm/at91/boot0/README +++ /dev/null @@ -1,7 +0,0 @@ -This is a bootstrap bootloader. It is intended to be used when the -AT91RM9200 is running xmodem over DBGU. It will download the next stage -of the booting process (or the recovery program) and jump to it. It loads -the program at a 1MB offset into SDRAM. Programs are expected to be -smaller than this and copy themselves to the right location. - -$FreeBSD$ diff --git a/sys/boot/arm/at91/boot0/linker.cfg b/sys/boot/arm/at91/boot0/linker.cfg deleted file mode 100644 index b2318939690f..000000000000 --- a/sys/boot/arm/at91/boot0/linker.cfg +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * - * Filename: linker.cfg - * - * linker config file used for internal RAM or eeprom images at address 0. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin move data to SDRAM - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(start) -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .text : - { - *(.text) - *(.text.*) - *(.stub) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .data : - { - __data_start = . ; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - __bss_start__ = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - .bss : - { - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; - PROVIDE (end = .); -} diff --git a/sys/boot/arm/at91/boot0iic/Makefile b/sys/boot/arm/at91/boot0iic/Makefile deleted file mode 100644 index af93ce2e488d..000000000000 --- a/sys/boot/arm/at91/boot0iic/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../libat91 - -P=boot0iic -FILES=${P} -SRCS=arm_init.S main.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -CFLAGS+=-DBOOT_BOOT0 diff --git a/sys/boot/arm/at91/boot0iic/main.c b/sys/boot/arm/at91/boot0iic/main.c deleted file mode 100644 index 2a81b937ae69..000000000000 --- a/sys/boot/arm/at91/boot0iic/main.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "lib.h" -#include "at91rm9200_lowlevel.h" - -int main(void); - -int -main(void) -{ - char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */ - int len, sec; - - printf("\nSend data to be written into EEPROM\n"); - while ((len = xmodem_rx(addr)) == -1) - continue; - sec = GetSeconds() + 1; - while (sec >= GetSeconds()) - continue; - printf("\nWriting EEPROM from 0x%x to addr 0, 0x%x bytes\n", addr, - len); - InitEEPROM(); - printf("init done\n"); - WriteEEPROM(0, addr, len); - printf("\nWrote %d bytes. Press reset\n", len); - return (1); -} diff --git a/sys/boot/arm/at91/boot0spi/Makefile b/sys/boot/arm/at91/boot0spi/Makefile deleted file mode 100644 index 207d6204cd3b..000000000000 --- a/sys/boot/arm/at91/boot0spi/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../libat91 - -P=boot0spi -FILES=${P} -SRCS=arm_init.S main.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -CFLAGS+=-DBOOT_BOOT0 diff --git a/sys/boot/arm/at91/boot0spi/main.c b/sys/boot/arm/at91/boot0spi/main.c deleted file mode 100644 index cac037b5b0af..000000000000 --- a/sys/boot/arm/at91/boot0spi/main.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "lib.h" -#include "at91rm9200_lowlevel.h" -#include "spi_flash.h" - -#define OFFSET 0 - -int main(void); - -int -main(void) -{ - int len, i, j, off, sec; - char *addr = (char *)SDRAM_BASE + (1 << 20); /* download at + 1MB */ - char *addr2 = (char *)SDRAM_BASE + (2 << 20); /* readback to + 2MB */ - - SPI_InitFlash(); - printf("Waiting for data\n"); - while ((len = xmodem_rx(addr)) == -1) - continue; - printf("Writing %u bytes at %u\n", len, OFFSET); - for (i = 0; i < len; i+= FLASH_PAGE_SIZE) { - off = i + OFFSET; - for (j = 0; j < 10; j++) { - SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE); - SPI_ReadFlash(off, addr2 + i, FLASH_PAGE_SIZE); - if (p_memcmp(addr + i, addr2 + i, FLASH_PAGE_SIZE) == 0) - break; - } - if (j >= 10) - printf("Bad Readback at %u\n", i); - } - sec = GetSeconds() + 2; - while (sec <= GetSeconds()) - continue; - printf("Done\n"); - reset(); - return (1); -} diff --git a/sys/boot/arm/at91/boot2/Makefile b/sys/boot/arm/at91/boot2/Makefile deleted file mode 100644 index 1150969bc4de..000000000000 --- a/sys/boot/arm/at91/boot2/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../libat91 ${.CURDIR}/../bootspi - -P=boot2 -FILES=${P} -SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -.if ${BOOT_FLAVOR} == "kb920x" -CFLAGS+=-DBOOT_IIC -.endif -CFLAGS+= \ - -I${.CURDIR}/../bootspi \ - -I${.CURDIR}/../../../common \ - -I${.CURDIR}/../../../.. \ - -D_KERNEL \ - -DUFS1_ONLY diff --git a/sys/boot/arm/at91/boot2/boot2.c b/sys/boot/arm/at91/boot2/boot2.c deleted file mode 100644 index f7510a5a0fcc..000000000000 --- a/sys/boot/arm/at91/boot2/boot2.c +++ /dev/null @@ -1,361 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay - * Copyright (c) 2006 M Warner Losh - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include - -#include - -#include "lib.h" -#include "board.h" -#include "paths.h" -#include "rbx.h" - -#undef PATH_KERNEL -#define PATH_KERNEL "/boot/kernel/kernel.gz.tramp" - -extern uint32_t _end; - -#define NOPT 6 - -static const char optstr[NOPT] = "agnrsv"; -static const unsigned char bootflags[NOPT] = { - RBX_ASKNAME, - RBX_GDB, - RBX_NOINTR, - RBX_DFLTROOT, - RBX_SINGLE, - RBX_VERBOSE -}; - -unsigned board_id; /* board type to pass to kernel, if set by board_* code */ -unsigned dsk_start; -static char cmd[512]; -static char kname[1024]; -static uint32_t opts; -static uint8_t dsk_meta; - -int main(void); -static void load(void); -static int parse(void); -static int dskread(void *, unsigned, unsigned); -#ifdef FIXUP_BOOT_DRV -static void fixup_boot_drv(caddr_t, int, int, int); -#endif - -#define UFS_SMALL_CGBASE -#include "ufsread.c" - -#ifdef DEBUG -#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif - -static inline int -xfsread(ufs_ino_t inode, void *buf, size_t nbyte) -{ - if ((size_t)fsread(inode, buf, nbyte) != nbyte) - return -1; - return 0; -} - -static inline void -getstr(int c) -{ - char *s; - - s = cmd; - if (c == 0) - c = getc(10000); - for (;;) { - switch (c) { - case 0: - break; - case '\177': - case '\b': - if (s > cmd) { - s--; - printf("\b \b"); - } - break; - case '\n': - case '\r': - *s = 0; - return; - default: - if (s - cmd < sizeof(cmd) - 1) - *s++ = c; - xputchar(c); - } - c = getc(10000); - } -} - -int -main(void) -{ - int autoboot, c = 0; - ufs_ino_t ino; - - dmadat = (void *)(0x20000000 + (16 << 20)); - board_init(); - - autoboot = 1; - - /* Process configuration file */ - if ((ino = lookup(PATH_CONFIG)) || - (ino = lookup(PATH_DOTCONFIG))) - fsread(ino, cmd, sizeof(cmd)); - - if (*cmd) { - if (parse()) - autoboot = 0; - printf("%s: %s\n", PATH_CONFIG, cmd); - /* Do not process this command twice */ - *cmd = 0; - } - - if (*kname == '\0') - strcpy(kname, PATH_KERNEL); - - /* Present the user with the boot2 prompt. */ - for (;;) { - printf("\nDefault: %s\nboot: ", kname); - if (!autoboot || - (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0)) - getstr(c); - xputchar('\n'); - autoboot = 0; - c = 0; - if (parse()) - xputchar('\a'); - else - load(); - } - return (1); -} - -static void -load(void) -{ - Elf32_Ehdr eh; - static Elf32_Phdr ep[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr; - int i, j; -#ifdef FIXUP_BOOT_DRV - caddr_t staddr; - int klen; - - staddr = (caddr_t)0xffffffff; - klen = 0; -#endif - if (!(ino = lookup(kname))) { - if (!ls) - printf("No %s\n", kname); - return; - } - if (xfsread(ino, &eh, sizeof(eh))) - return; - if (!IS_ELF(eh)) { - printf("Invalid %s\n", "format"); - return; - } - fs_off = eh.e_phoff; - for (j = i = 0; i < eh.e_phnum && j < 2; i++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) - return; - if (ep[j].p_type == PT_LOAD) - j++; - } - for (i = 0; i < 2; i++) { - p = (caddr_t)ep[i].p_paddr; - fs_off = ep[i].p_offset; -#ifdef FIXUP_BOOT_DRV - if (staddr == (caddr_t)0xffffffff) - staddr = p; - klen += ep[i].p_filesz; -#endif - if (xfsread(ino, p, ep[i].p_filesz)) - return; - } - addr = eh.e_entry; -#ifdef FIXUP_BOOT_DRV - fixup_boot_drv(staddr, klen, bootslice, bootpart); -#endif - ((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0); -} - -static int -parse() -{ - char *arg = cmd; - char *ep, *p; - int c, i; - - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(bootflags[i]); - } - } else { - arg--; - if ((i = ep - arg)) { - if ((size_t)i >= sizeof(kname)) - return -1; - memcpy(kname, arg, i + 1); - } - } - arg = p; - } - return 0; -} - -static int -dskread(void *buf, unsigned lba, unsigned nblk) -{ - struct dos_partition *dp; - struct disklabel *d; - char *sec; - int i; - - if (!dsk_meta) { - sec = dmadat->secbuf; - dsk_start = 0; - if (drvread(sec, DOSBBSECTOR, 1)) - return -1; - dp = (void *)(sec + DOSPARTOFF); - for (i = 0; i < NDOSPART; i++) { - if (dp[i].dp_typ == DOSPTYP_386BSD) - break; - } - if (i == NDOSPART) - return -1; - /* - * Although dp_start is aligned within the disk - * partition structure, DOSPARTOFF is 446, which is - * only word (2) aligned, not longword (4) aligned. - * Cope by using memcpy to fetch the start of this - * partition. - */ - memcpy(&dsk_start, &dp[1].dp_start, 4); - if (drvread(sec, dsk_start + LABELSECTOR, 1)) - return -1; - d = (void *)(sec + LABELOFFSET); - if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { - printf("Invalid %s\n", "label"); - return -1; - } - if (!d->d_partitions[0].p_size) { - printf("Invalid %s\n", "partition"); - return -1; - } - dsk_start += d->d_partitions[0].p_offset; - dsk_start -= d->d_partitions[RAW_PART].p_offset; - dsk_meta++; - } - return drvread(buf, dsk_start + lba, nblk); -} - -#ifdef FIXUP_BOOT_DRV -/* - * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel - * and change it to what was specified on the comandline or /boot.conf - * file or to what was encountered on the disk. It will try to handle 3 - * different disk layouts, raw (dangerously dedicated), slice only and - * slice + partition. It will look for the following strings in the - * kernel, but if it is one of the first three, the string in the kernel - * must use the correct form to match the actual disk layout: - * - ufs:ad0a - * - ufs:ad0s1 - * - ufs:ad0s1a - * - ufs:ROOTDEVNAME - * In the case of the first three strings, only the "a" at the end and - * the "1" after the "s" will be modified, if they exist. The string - * length will not be changed. In the case of the last string, the - * whole string will be built up and nul, '\0' terminated. - */ -static void -fixup_boot_drv(caddr_t addr, int klen, int bs, int bp) -{ - const u_int8_t op[] = "ufs:ROOTDEVNAME"; - const u_int8_t op2[] = "ufs:ad0"; - u_int8_t *p, *ps; - - DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n", - (int)addr, klen, bs, bp); - if (bs > 4) - return; - if (bp > 7) - return; - ps = memmem(addr, klen, op, sizeof(op)); - if (ps != NULL) { - p = ps + 4; /* past ufs: */ - DPRINTF("Found it at 0x%x\n", (int)ps); - p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */ - p += 3; - if (bs > 0) { - /* append slice */ - *p++ = 's'; - *p++ = bs + '0'; - } - if (disk_layout != DL_SLICE) { - /* append partition */ - *p++ = bp + 'a'; - } - *p = '\0'; - } else { - ps = memmem(addr, klen, op2, sizeof(op2) - 1); - if (ps != NULL) { - p = ps + sizeof(op2) - 1; - DPRINTF("Found it at 0x%x\n", (int)ps); - if (*p == 's') { - /* fix slice */ - p++; - *p++ = bs + '0'; - } - if (*p == 'a') - *p = bp + 'a'; - } - } - if (ps == NULL) { - printf("Could not locate \"%s\" to fix kernel boot device, " - "check ROOTDEVNAME is set\n", op); - return; - } - DPRINTF("Changed boot device to %s\n", ps); -} -#endif diff --git a/sys/boot/arm/at91/boot2/bwct_board.c b/sys/boot/arm/at91/boot2/bwct_board.c deleted file mode 100644 index fffdd2a8172f..000000000000 --- a/sys/boot/arm/at91/boot2/bwct_board.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -#include - -#include "at91rm9200_lowlevel.h" -#include "at91rm9200.h" -#include "emac.h" -#include "lib.h" -#include "ee.h" -#include "board.h" -#include "sd-card.h" - -unsigned char mac[6] = { 0x00, 0x0e, 0x42, 0x02, 0x00, 0x28 }; - -static void USART0_Init(); -static void USART1_Init(); -static void USART2_Init(); -static void USART3_Init(); -static void DS1672_Init(); - -static void -DS1672_Init() { - char buf[] = {0x00, 0xa9}; - - EEWrite(0xd0, buf, sizeof(buf)); -} - -static void -USART0_Init() { - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - // setup GPIO - pPio->PIO_ASR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0; - pPio->PIO_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0; - - // enable power - pPMC->PMC_PCER = 1u << AT91C_ID_US0; -} - -static void -USART1_Init() { - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - // setup GPIO - pPio->PIO_ASR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1; - pPio->PIO_PDR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1; - - // enable power - pPMC->PMC_PCER = 1u << AT91C_ID_US1; -} - -static void -USART2_Init() { - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - // setup GPIO - pPio->PIO_ASR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2; - pPio->PIO_PDR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2; - - // enable power - pPMC->PMC_PCER = 1u << AT91C_ID_US2; -} - -static void -USART3_Init() { - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - // setup GPIO - pPio->PIO_BSR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3; - pPio->PIO_PDR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3; - - // enable power - pPMC->PMC_PCER = 1u << AT91C_ID_US3; -} - -void -board_init(void) -{ - - printf("\n\n"); - printf("BWCT FSB-A920-1\n"); - printf("http://www.bwct.de\n"); - printf("\n"); -#if defined(SDRAM_128M) - printf("AT92RM9200 180MHz 128MB\n"); -#else - printf("AT92RM9200 180MHz 64MB\n"); -#endif - printf("Initialising USART0\n"); - USART0_Init(); - printf("Initialising USART1\n"); - USART1_Init(); - printf("Initialising USART2\n"); - USART2_Init(); - printf("Initialising USART3\n"); - USART3_Init(); - printf("Initialising TWI\n"); - EEInit(); - printf("Initialising DS1672\n"); - DS1672_Init(); - printf("Initialising Ethernet\n"); - printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0], - mac[1], mac[2], mac[3], mac[4], mac[5]); - EMAC_Init(); - EMAC_SetMACAddress(mac); - printf("Initialising SD-card\n"); - sdcard_init(); -} - -#include "../bootspi/ee.c" - -int -drvread(void *buf, unsigned lba, unsigned nblk) -{ - return (MCI_read((char *)buf, lba << 9, nblk << 9)); -} diff --git a/sys/boot/arm/at91/boot2/kb920x_board.c b/sys/boot/arm/at91/boot2/kb920x_board.c deleted file mode 100644 index 52f9676be411..000000000000 --- a/sys/boot/arm/at91/boot2/kb920x_board.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -#include - -#include "emac.h" -#include "lib.h" -#include "board.h" -#include "sd-card.h" - -unsigned char mac[6] = { 0x42, 0x53, 0x44, 0, 0, 1 }; - -static void -MacFromEE() -{ - uint32_t sig; - sig = 0; - ReadEEPROM(12 * 1024, (uint8_t *)&sig, sizeof(sig)); - if (sig != 0x92021054) - return; - ReadEEPROM(12 * 1024 + 4, mac, 6); - printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0], - mac[1], mac[2], mac[3], mac[4], mac[5]); -} - -void -board_init(void) -{ - InitEEPROM(); - MacFromEE(); - EMAC_Init(); - EMAC_SetMACAddress(mac); - while (sdcard_init() == 0) - printf("Looking for SD card\n"); -} - -int -drvread(void *buf, unsigned lba, unsigned nblk) -{ - return (MCI_read((char *)buf, lba << 9, nblk << 9)); -} diff --git a/sys/boot/arm/at91/bootiic/Makefile b/sys/boot/arm/at91/bootiic/Makefile deleted file mode 100644 index 13f2482e6260..000000000000 --- a/sys/boot/arm/at91/bootiic/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../libat91 - -P=bootiic -FILES=${P} -SRCS=arm_init.S main.c loader_prompt.c env_vars.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -CFLAGS += -DBOOT_IIC -DBOOT_COMMANDS diff --git a/sys/boot/arm/at91/bootiic/README b/sys/boot/arm/at91/bootiic/README deleted file mode 100644 index 1489d7c09c94..000000000000 --- a/sys/boot/arm/at91/bootiic/README +++ /dev/null @@ -1,35 +0,0 @@ -$FreeBSD$ - -This image is intended to be programmed into boot EEPROM. The image is nearly -0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or -later. Alternatively, the KB9200 can be upgraded with larger EEPROM. -It performs basic functions prior to executing an image at a -specified address. The pre-boot functions can be modified and saved back into -EEPROM. -The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address -and must be changed to a valid value in order to use the ethernet interface. - -Memory usage: - -EEPROM = 0x4000 -SDRAM = - run stack = 0x21800000 - variables = 0x21200000 - ethernet = 0x21000000 (buffers and descriptors) - - -Functions supported: - - c - copy - d - display auto command table (in RAM) - e - execute image - ? - help - ip - set local ip - m - set mac - server_ip - set server ip - s - set auto command entry - t - create linux boot tag list - tftp - download image via tftp - w - update auto command table - x - download image via xmodem - diff --git a/sys/boot/arm/at91/bootiic/env_vars.c b/sys/boot/arm/at91/bootiic/env_vars.c deleted file mode 100644 index ac0b4f978fa8..000000000000 --- a/sys/boot/arm/at91/bootiic/env_vars.c +++ /dev/null @@ -1,207 +0,0 @@ -/****************************************************************************** - * - * Filename: env_vars.c - * - * Instantiation of environment variables, structures, and other globals. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "env_vars.h" -#include "loader_prompt.h" -#include "lib.h" - -/******************************* GLOBALS *************************************/ -char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE]; - -char env_table[MAX_ENV_SIZE_BYTES]; - -extern char BootCommandSection; - -/************************** PRIVATE FUNCTIONS ********************************/ - - -static int currentIndex; -static int currentOffset; - - -/* - * .KB_C_FN_DEFINITION_START - * int ReadCharFromEnvironment(char *) - * This private function reads characters from the environment variables - * to service the command prompt during auto-boot or just to setup the - * default environment. Returns positive value if valid character was - * set in the pointer. Returns negative value to signal input stream - * terminated. Returns 0 to indicate _wait_ condition. - * .KB_C_FN_DEFINITION_END - */ -static int -ReadCharFromEnvironment(int timeout) -{ - int ch; - - if (currentIndex < MAX_BOOT_COMMANDS) { - ch = boot_commands[currentIndex][currentOffset++]; - if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) { - currentOffset = 0; - ++currentIndex; - ch = '\r'; - } - return (ch); - } - - return (-1); -} - - -/*************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void WriteCommandTable(void) - * This global function write the current command table to the non-volatile - * memory. - * .KB_C_FN_DEFINITION_END - */ -void -WriteCommandTable(void) -{ - int i, size = MAX_ENV_SIZE_BYTES, copySize; - char *cPtr = env_table; - - p_memset(env_table, 0, sizeof(env_table)); - - for (i = 0; i < MAX_BOOT_COMMANDS; ++i) { - - copySize = p_strlen(boot_commands[i]); - size -= copySize + 1; - - if (size < 0) { - continue; - } - memcpy(cPtr, boot_commands[i], copySize); - cPtr += copySize; - *cPtr++ = 0; - } - - /* We're executing in low RAM so addr in ram == offset in eeprom */ - WriteEEPROM((unsigned)&BootCommandSection, env_table, - sizeof(env_table)); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void SetBootCommand(int index, char *command) - * This global function replaces the specified index with the string residing - * at command. Execute this function with a NULL string to clear the - * associated command index. - * .KB_C_FN_DEFINITION_END - */ -void -SetBootCommand(int index, char *command) -{ - int i; - - if ((unsigned)index < MAX_BOOT_COMMANDS) { - - p_memset(boot_commands[index], 0, MAX_INPUT_SIZE); - - if (!command) - return ; - - for (i = 0; i < MAX_INPUT_SIZE; ++i) { - boot_commands[index][i] = command[i]; - if (!(boot_commands[index][i])) - return; - } - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * void DumpBootCommands(void) - * This global function displays the current boot commands. - * .KB_C_FN_DEFINITION_END - */ -void -DumpBootCommands(void) -{ - int i, j; - - for (i = 0; i < MAX_BOOT_COMMANDS; ++i) { - printf("0x%x : ", i); - for (j = 0; j < MAX_INPUT_SIZE; ++j) { - putchar(boot_commands[i][j]); - if (!(boot_commands[i][j])) - break; - } - printf("[E]\n\r"); - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * void LoadBootCommands(void) - * This global function loads the existing boot commands from raw format and - * coverts it to the standard, command-index format. Notice, the processed - * boot command table has much more space allocated than the actual table - * stored in non-volatile memory. This is because the processed table - * exists in RAM which is larger than the non-volatile space. - * .KB_C_FN_DEFINITION_END - */ -void -LoadBootCommands(void) -{ - int index, j, size; - char *cPtr; - - p_memset((char*)boot_commands, 0, sizeof(boot_commands)); - - cPtr = &BootCommandSection; - - size = MAX_ENV_SIZE_BYTES; - - for (index = 0; (index < MAX_BOOT_COMMANDS) && size; ++index) { - for (j = 0; (j < MAX_INPUT_SIZE) && size; ++j) { - size--; - boot_commands[index][j] = *cPtr++; - if (!(boot_commands[index][j])) { - break; - } - } - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ExecuteEnvironmentFunctions(void) - * This global function executes applicable entries in the environment. - * .KB_C_FN_DEFINITION_END - */ -void -ExecuteEnvironmentFunctions(void) -{ - currentIndex = 0; - currentOffset = 0; - - DumpBootCommands(); - Bootloader(ReadCharFromEnvironment); -} diff --git a/sys/boot/arm/at91/bootiic/env_vars.h b/sys/boot/arm/at91/bootiic/env_vars.h deleted file mode 100644 index c6e46b4e4332..000000000000 --- a/sys/boot/arm/at91/bootiic/env_vars.h +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** - * - * Filename: env_vars.h - * - * Definition of environment variables, structures, and other globals. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#ifndef _ENV_VARS_H_ -#define _ENV_VARS_H_ - -/* each environment variable is a string following the standard command */ -/* definition used by the interactive loader in the following format: */ -/* ... */ -/* all environment variables (or commands) are stored in a string */ -/* format: NULL-terminated. */ -/* this implies that commands can never utilize 0-values: actual 0, not */ -/* the string '0'. this is not an issue as the string '0' is handled */ -/* by the command parse routine. */ - -/* the following defines the maximum size of the environment for */ -/* including variables. */ -/* this value must match that declared in the low-level file that */ -/* actually reserves the space for the non-volatile environment. */ -#define MAX_ENV_SIZE_BYTES 0x100 - -#define MAX_BOOT_COMMANDS 10 - -/* C-style reference section */ -#ifndef __ASSEMBLY__ - -extern void WriteCommandTable(void); -extern void SetBootCommand(int index, char *command); -extern void DumpBootCommands(void); -extern void LoadBootCommands(void); -extern void ExecuteEnvironmentFunctions(void); - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ENV_VARS_H_ */ diff --git a/sys/boot/arm/at91/bootiic/loader_prompt.c b/sys/boot/arm/at91/bootiic/loader_prompt.c deleted file mode 100644 index 29413b8e6ce0..000000000000 --- a/sys/boot/arm/at91/bootiic/loader_prompt.c +++ /dev/null @@ -1,387 +0,0 @@ -/****************************************************************************** - * - * Filename: loader_prompt.c - * - * Instantiation of the interactive loader functions. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin massive changes for tftp, strings, and more - * 05JUL2005 kb_admin save tag address, and set registers on boot - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "at91rm9200_lowlevel.h" -#ifdef SUPPORT_TAG_LIST -#include "tag_list.h" -#endif -#include "emac.h" -#include "loader_prompt.h" -#include "env_vars.h" -#include "lib.h" - - -/******************************* GLOBALS *************************************/ - - -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ - -static char inputBuffer[MAX_INPUT_SIZE]; -static int buffCount; - -// argv pointer are either NULL or point to locations in inputBuffer -static char *argv[MAX_COMMAND_PARAMS]; - -static const char *backspaceString = "\010 \010"; - -static const command_entry_t CommandTable[] = { - {COMMAND_COPY, "c"}, - {COMMAND_DUMP, "d"}, - {COMMAND_EXEC, "e"}, - {COMMAND_HELP, "?"}, - {COMMAND_LOCAL_IP, "ip"}, - {COMMAND_MAC, "m"}, - {COMMAND_SERVER_IP, "server_ip"}, - {COMMAND_SET, "s"}, -#ifdef SUPPORT_TAG_LIST - {COMMAND_TAG, "t"}, -#endif - {COMMAND_TFTP, "tftp"}, - {COMMAND_WRITE, "w"}, - {COMMAND_XMODEM, "x"}, - {COMMAND_FINAL_FLAG, 0} -}; - -static unsigned tagAddress; - -/* - * .KB_C_FN_DEFINITION_START - * unsigned BuildIP(void) - * This private function packs the test IP info to an unsigned value. - * .KB_C_FN_DEFINITION_END - */ -static unsigned -BuildIP(void) -{ - return ((p_ASCIIToDec(argv[1]) << 24) | - (p_ASCIIToDec(argv[2]) << 16) | - (p_ASCIIToDec(argv[3]) << 8) | - p_ASCIIToDec(argv[4])); -} - - -/* - * .KB_C_FN_DEFINITION_START - * int StringToCommand(char *cPtr) - * This private function converts a command string to a command code. - * .KB_C_FN_DEFINITION_END - */ -static int -StringToCommand(char *cPtr) -{ - int i; - - for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i) - if (!strcmp(CommandTable[i].c_string, cPtr)) - return (CommandTable[i].command); - - return (COMMAND_INVALID); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void RestoreSpace(int) - * This private function restores NULL characters to spaces in order to - * process the remaining args as a string. The number passed is the argc - * of the first entry to begin restoring space in the inputBuffer. - * .KB_C_FN_DEFINITION_END - */ -static void -RestoreSpace(int startArgc) -{ - char *cPtr; - - for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) { - if ((cPtr = argv[startArgc])) - *(cPtr - 1) = ' '; - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * int BreakCommand(char *) - * This private function splits the buffer into separate strings as pointed - * by argv and returns the number of parameters (< 0 on failure). - * .KB_C_FN_DEFINITION_END - */ -static int -BreakCommand(char *buffer) -{ - int pCount, cCount, state; - - state = pCount = 0; - p_memset((char*)argv, 0, sizeof(argv)); - - for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) { - - if (!state) { - /* look for next command */ - if (!p_IsWhiteSpace(buffer[cCount])) { - argv[pCount++] = &buffer[cCount]; - state = 1; - } else { - buffer[cCount] = 0; - } - } else { - /* in command, find next white space */ - if (p_IsWhiteSpace(buffer[cCount])) { - buffer[cCount] = 0; - state = 0; - } - } - - if (pCount >= MAX_COMMAND_PARAMS) { - return (-1); - } - } - - return (pCount); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ParseCommand(char *) - * This private function executes matching functions. - * .KB_C_FN_DEFINITION_END - */ -static void -ParseCommand(char *buffer) -{ - int argc, i; - - if ((argc = BreakCommand(buffer)) < 1) - return; - - switch (StringToCommand(argv[0])) { - case COMMAND_COPY: - { - // "c " - // copy memory - char *to, *from; - unsigned size; - - if (argc > 3) { - to = (char *)p_ASCIIToHex(argv[1]); - from = (char *)p_ASCIIToHex(argv[2]); - size = p_ASCIIToHex(argv[3]); - memcpy(to, from, size); - } - break; - } - - case COMMAND_DUMP: - // display boot commands - DumpBootCommands(); - break; - - case COMMAND_EXEC: - { - // "e

" - // execute at address - void (*execAddr)(unsigned, unsigned, unsigned); - - if (argc > 1) { - /* in future, include machtypes (MACH_KB9200 = 612) */ - execAddr = (void (*)(unsigned, unsigned, unsigned)) - p_ASCIIToHex(argv[1]); - (*execAddr)(0, 612, tagAddress); - } - break; - } - - case COMMAND_TFTP: - { - // "tftp " - // tftp download - unsigned address = 0; - - if (argc > 2) - address = p_ASCIIToHex(argv[1]); - TFTP_Download(address, argv[2]); - break; - } - - case COMMAND_SERVER_IP: - // "server_ip " - // set download server address - if (argc > 4) - SetServerIPAddress(BuildIP()); - break; - - case COMMAND_HELP: - // dump command info - printf("Commands:\n" - "\tc\n" - "\td\n" - "\te\n" - "\tip\n" - "\tserver_ip\n" - "\tm\n" - "\ttftp\n" - "\ts\n" -#ifdef SUPPORT_TAG_LIST - "\tt\n" -#endif - "\tw\n" - "\tx\n"); - break; - - case COMMAND_LOCAL_IP: - // "local_ip - // set ip of this module - if (argc > 4) - SetLocalIPAddress(BuildIP()); - break; - - case COMMAND_MAC: - { - // "m - // set mac address using 6 byte values - unsigned char mac[6]; - - if (argc > 6) { - for (i = 0; i < 6; i++) - mac[i] = p_ASCIIToHex(argv[i + 1]); - EMAC_SetMACAddress(mac); - } - break; - } - - case COMMAND_SET: - { - // s - // set the boot command at index (0-based) - unsigned index; - - if (argc > 1) { - RestoreSpace(2); - index = p_ASCIIToHex(argv[1]); - SetBootCommand(index, argv[2]); - } - break; - } - -#ifdef SUPPORT_TAG_LIST - case COMMAND_TAG: - // t
- // create tag-list for linux boot - if (argc > 2) { - RestoreSpace(2); - tagAddress = p_ASCIIToHex(argv[1]); - InitTagList(argv[2], (void*)tagAddress); - } - break; -#endif - - case COMMAND_WRITE: - // write the command table to non-volatile - WriteCommandTable(); - break; - - case COMMAND_XMODEM: - { - // "x
" - // download X-modem record at address - if (argc > 1) - xmodem_rx((char *)p_ASCIIToHex(argv[1])); - break; - } - - default: - break; - } - - printf("\n"); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ServicePrompt(char) - * This private function process each character checking for valid commands. - * This function is only executed if the character is considered valid. - * Each command is terminated with NULL (0) or ''. - * .KB_C_FN_DEFINITION_END - */ -static void -ServicePrompt(char p_char) -{ - if (p_char == '\r') - p_char = 0; - - if (p_char == '\010') { - if (buffCount) { - /* handle backspace BS */ - inputBuffer[--buffCount] = 0; - printf(backspaceString); - } - return; - } - if (buffCount < MAX_INPUT_SIZE - 1) { - inputBuffer[buffCount++] = p_char; - putchar(p_char); - } - if (!p_char) { - printf("\n"); - ParseCommand(inputBuffer); - p_memset(inputBuffer, 0, MAX_INPUT_SIZE); - buffCount = 0; - printf("\n>"); - } -} - - -/* ************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void Bootloader(void *inputFunction) - * This global function is the entry point for the bootloader. If the - * inputFunction pointer is NULL, the loader input will be serviced from - * the uart. Otherwise, inputFunction is called to get characters which - * the loader will parse. - * .KB_C_FN_DEFINITION_END - */ -void -Bootloader(int(*inputFunction)(int)) -{ - int ch = 0; - - p_memset((void*)inputBuffer, 0, sizeof(inputBuffer)); - - buffCount = 0; - if (!inputFunction) { - inputFunction = getc; - } - - printf("\n>"); - - while (1) - if ((ch = ((*inputFunction)(0))) > 0) - ServicePrompt(ch); -} diff --git a/sys/boot/arm/at91/bootiic/loader_prompt.h b/sys/boot/arm/at91/bootiic/loader_prompt.h deleted file mode 100644 index 02233405f96a..000000000000 --- a/sys/boot/arm/at91/bootiic/loader_prompt.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** - * - * Filename: loader_prompt.h - * - * Definition of the interactive loader functions. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#ifndef _LOADER_PROMPT_H_ -#define _LOADER_PROMPT_H_ - -#define MAX_INPUT_SIZE 256 -#define MAX_COMMAND_PARAMS 10 - -enum { - COMMAND_INVALID = 0, - COMMAND_COPY, - COMMAND_DUMP, - COMMAND_EXEC, - COMMAND_HELP, - COMMAND_LOCAL_IP, - COMMAND_MAC, - COMMAND_SERVER_IP, - COMMAND_SET, - COMMAND_TAG, - COMMAND_TFTP, - COMMAND_WRITE, - COMMAND_XMODEM, - COMMAND_FINAL_FLAG -} e_cmd_t; - - -typedef struct { - int command; - const char *c_string; -} command_entry_t; - -void EnterInteractiveBootloader(int(*inputFunction)(int)); -void Bootloader(int(*inputFunction)(int)); - -#endif /* _LOADER_PROMPT_H_ */ diff --git a/sys/boot/arm/at91/bootiic/main.c b/sys/boot/arm/at91/bootiic/main.c deleted file mode 100644 index 86368358ce8a..000000000000 --- a/sys/boot/arm/at91/bootiic/main.c +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * - * Filename: main.c - * - * Basic entry points for top-level functions - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin cosmetic changes - * 29APR2005 kb_admin modified boot delay - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ - -#include "env_vars.h" -#include "at91rm9200_lowlevel.h" -#include "loader_prompt.h" -#include "emac.h" -#include "lib.h" - -int main(void); - -/* - * .KB_C_FN_DEFINITION_START - * int main(void) - * This global function waits at least one second, but not more than two - * seconds, for input from the serial port. If no response is recognized, - * it acts according to the parameters specified by the environment. For - * example, the function might boot an operating system. Do not return - * from this function. - * .KB_C_FN_DEFINITION_END - */ -int -main(void) -{ - InitEEPROM(); - EMAC_Init(); - LoadBootCommands(); - printf("\n\rKB9202(www.kwikbyte.com)\n\rAuto boot..\n\r"); - if (getc(1) == -1) - ExecuteEnvironmentFunctions(); - Bootloader(0); - - return (1); -} diff --git a/sys/boot/arm/at91/bootspi/Makefile b/sys/boot/arm/at91/bootspi/Makefile deleted file mode 100644 index a02d447b48a3..000000000000 --- a/sys/boot/arm/at91/bootspi/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ - -.include - -.PATH: ${.CURDIR}/../libat91 - -P=bootspi -FILES=${P} -SRCS=arm_init.S main.c loader_prompt.c env_vars.c ee.c -MAN= -LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} - -.include - -.if ${MK_FPGA} == "yes" -CFLAGS += -DTSC_FPGA -.endif -CFLAGS += -DBOOT_COMMANDS diff --git a/sys/boot/arm/at91/bootspi/README b/sys/boot/arm/at91/bootspi/README deleted file mode 100644 index 9a4ffa882440..000000000000 --- a/sys/boot/arm/at91/bootspi/README +++ /dev/null @@ -1,34 +0,0 @@ -$FreeBSD$ - -This image is intended to be programmed into boot EEPROM. The image is nearly -0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or -later. Alternatively, the KB9200 can be upgraded with larger EEPROM. -It performs basic functions prior to executing an image at a -specified address. The pre-boot functions can be modified and saved back into -EEPROM. -The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address -and must be changed to a valid value in order to use the ethernet interface. - -Memory usage: - -EEPROM = 0x4000 -SDRAM = - run stack = 0x21800000 - variables = 0x21200000 - ethernet = 0x21000000 (buffers and descriptors) - - -Functions supported: - - c - copy - d - display auto command table (in RAM) - e - execute image - ? - help - ip - set local ip - m - set mac - server_ip - set server ip - s - set auto command entry - t - create linux boot tag list - tftp - download image via tftp - w - update auto command table - x - download image via xmodem diff --git a/sys/boot/arm/at91/bootspi/ee.c b/sys/boot/arm/at91/bootspi/ee.c deleted file mode 100644 index ef0571924b6c..000000000000 --- a/sys/boot/arm/at91/bootspi/ee.c +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * - * Filename: eeprom.c - * - * Instantiation of eeprom routines - * - * Revision information: - * - * 28AUG2004 kb_admin initial creation - adapted from Atmel sources - * 12JAN2005 kb_admin fixed clock generation, write polling, init - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "at91rm9200_lowlevel.h" -#include "at91rm9200.h" -#include "lib.h" -#include "ee.h" - -/******************************* GLOBALS *************************************/ - - -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ - - -/* Use a macro to calculate the TWI clock generator value to save code space. */ -#define AT91C_TWSI_CLOCK 100000 -#define TWSI_EEPROM_ADDRESS 0x40 - -#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2) -#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8)) - - -/*************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void InitEEPROM(void) - * This global function initializes the EEPROM interface (TWI). Intended - * to be called a single time. - * .KB_C_FN_DEFINITION_END - */ -void -EEInit(void) -{ - - AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI; - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26; - pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26; - - pPio->PIO_MDDR = ~AT91C_PIO_PA25; - pPio->PIO_MDER = AT91C_PIO_PA25; - - pPMC->PMC_PCER = 1u << AT91C_ID_TWI; - - twiPtr->TWI_IDR = 0xffffffffu; - twiPtr->TWI_CR = AT91C_TWI_SWRST; - twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; - - twiPtr->TWI_CWGR = SET_TWI_CLOCK; -} - -static inline unsigned -iicaddr(unsigned ee_off) -{ - return (TWSI_EEPROM_ADDRESS | ((ee_off >> 8) & 0x7)); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size) - * This global function reads data from the eeprom at ee_addr storing data - * to data_addr for size bytes. Assume the TWI has been initialized. - * This function does not utilize the page read mode to simplify the code. - * .KB_C_FN_DEFINITION_END - */ -void -EERead(unsigned ee_off, char *data_addr, unsigned size) -{ - const AT91PS_TWI twiPtr = AT91C_BASE_TWI; - unsigned int status; - - if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) { - printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size); - return; - } - - status = twiPtr->TWI_SR; - status = twiPtr->TWI_RHR; - twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | AT91C_TWI_IADRSZ_1_BYTE | - AT91C_TWI_MREAD; - twiPtr->TWI_IADR = ee_off & 0xff; - twiPtr->TWI_CR = AT91C_TWI_START; - while (size-- > 1) { - while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY)) - continue; - *(data_addr++) = twiPtr->TWI_RHR; - } - twiPtr->TWI_CR = AT91C_TWI_STOP; - status = twiPtr->TWI_SR; - while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP)) - continue; - *data_addr = twiPtr->TWI_RHR; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size) - * This global function writes data to the eeprom at ee_off using data - * from data_addr for size bytes. Assume the TWI has been initialized. - * This function does not utilize the page write mode as the write time is - * much greater than the time required to access the device for byte-write - * functionality. This allows the function to be much simpler. - * .KB_C_FN_DEFINITION_END - */ -void -EEWrite(unsigned ee_off, const char *data_addr, unsigned size) -{ - const AT91PS_TWI twiPtr = AT91C_BASE_TWI; - unsigned status; - char test_data; - - while (size--) { - // Set the TWI Master Mode Register - twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | - AT91C_TWI_IADRSZ_1_BYTE; - twiPtr->TWI_IADR = ee_off++; - status = twiPtr->TWI_SR; - - // Load one data byte - twiPtr->TWI_THR = *(data_addr++); - twiPtr->TWI_CR = AT91C_TWI_START; - while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY)) - continue; - twiPtr->TWI_CR = AT91C_TWI_STOP; - status = twiPtr->TWI_SR; - while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP)) - continue; - - // wait for write operation to complete, it is done once - // we can read it back... - EERead(ee_off, &test_data, 1); - } -} diff --git a/sys/boot/arm/at91/bootspi/ee.h b/sys/boot/arm/at91/bootspi/ee.h deleted file mode 100644 index d4d8b8dc6f89..000000000000 --- a/sys/boot/arm/at91/bootspi/ee.h +++ /dev/null @@ -1,6 +0,0 @@ -/* $FreeBSD$ */ - -void EEInit(void); -void EERead(unsigned ee_off, char *data_addr, unsigned size); -void EEWrite(unsigned ee_off, const char *data_addr, unsigned size); - diff --git a/sys/boot/arm/at91/bootspi/env_vars.c b/sys/boot/arm/at91/bootspi/env_vars.c deleted file mode 100644 index 29b819b22941..000000000000 --- a/sys/boot/arm/at91/bootspi/env_vars.c +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** - * - * Filename: env_vars.c - * - * Instantiation of environment variables, structures, and other globals. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "env_vars.h" -#include "loader_prompt.h" -#include "lib.h" - -/******************************* GLOBALS *************************************/ -char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE]; - -char env_table[MAX_ENV_SIZE_BYTES]; - -extern char BootCommandSection; - -/************************** PRIVATE FUNCTIONS ********************************/ - - -static int currentIndex; -static int currentOffset; - - -/* - * .KB_C_FN_DEFINITION_START - * int ReadCharFromEnvironment(char *) - * This private function reads characters from the environment variables - * to service the command prompt during auto-boot or just to setup the - * default environment. Returns positive value if valid character was - * set in the pointer. Returns negative value to signal input stream - * terminated. Returns 0 to indicate _wait_ condition. - * .KB_C_FN_DEFINITION_END - */ -static int -ReadCharFromEnvironment(int timeout) -{ - int ch; - - if (currentIndex < MAX_BOOT_COMMANDS) { - ch = boot_commands[currentIndex][currentOffset++]; - if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) { - currentOffset = 0; - ++currentIndex; - ch = '\r'; - } - return (ch); - } - - return (-1); -} - - -/*************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void DumpBootCommands(void) - * This global function displays the current boot commands. - * .KB_C_FN_DEFINITION_END - */ -void -DumpBootCommands(void) -{ - int i; - - for (i = 0; boot_commands[i][0]; i++) - printf("0x%x : %s[E]\n", i, boot_commands[i]); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void LoadBootCommands(void) - * This global function loads the existing boot commands from raw format and - * coverts it to the standard, command-index format. Notice, the processed - * boot command table has much more space allocated than the actual table - * stored in non-volatile memory. This is because the processed table - * exists in RAM which is larger than the non-volatile space. - * .KB_C_FN_DEFINITION_END - */ -void -LoadBootCommands(void) -{ - int index, j; - char *cptr; - - p_memset((char*)boot_commands, 0, sizeof(boot_commands)); - cptr = &BootCommandSection; - for (index = 0; *cptr; index++) { - for (j = 0; *cptr; j++) - boot_commands[index][j] = *cptr++; - cptr++; - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ExecuteEnvironmentFunctions(void) - * This global function executes applicable entries in the environment. - * .KB_C_FN_DEFINITION_END - */ -void -ExecuteEnvironmentFunctions(void) -{ - currentIndex = 0; - currentOffset = 0; - - DumpBootCommands(); - printf("Autoboot...\n"); - Bootloader(ReadCharFromEnvironment); -} diff --git a/sys/boot/arm/at91/bootspi/env_vars.h b/sys/boot/arm/at91/bootspi/env_vars.h deleted file mode 100644 index c6e46b4e4332..000000000000 --- a/sys/boot/arm/at91/bootspi/env_vars.h +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** - * - * Filename: env_vars.h - * - * Definition of environment variables, structures, and other globals. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#ifndef _ENV_VARS_H_ -#define _ENV_VARS_H_ - -/* each environment variable is a string following the standard command */ -/* definition used by the interactive loader in the following format: */ -/* ... */ -/* all environment variables (or commands) are stored in a string */ -/* format: NULL-terminated. */ -/* this implies that commands can never utilize 0-values: actual 0, not */ -/* the string '0'. this is not an issue as the string '0' is handled */ -/* by the command parse routine. */ - -/* the following defines the maximum size of the environment for */ -/* including variables. */ -/* this value must match that declared in the low-level file that */ -/* actually reserves the space for the non-volatile environment. */ -#define MAX_ENV_SIZE_BYTES 0x100 - -#define MAX_BOOT_COMMANDS 10 - -/* C-style reference section */ -#ifndef __ASSEMBLY__ - -extern void WriteCommandTable(void); -extern void SetBootCommand(int index, char *command); -extern void DumpBootCommands(void); -extern void LoadBootCommands(void); -extern void ExecuteEnvironmentFunctions(void); - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ENV_VARS_H_ */ diff --git a/sys/boot/arm/at91/bootspi/loader_prompt.c b/sys/boot/arm/at91/bootspi/loader_prompt.c deleted file mode 100644 index 63bc50e536ec..000000000000 --- a/sys/boot/arm/at91/bootspi/loader_prompt.c +++ /dev/null @@ -1,363 +0,0 @@ -/****************************************************************************** - * - * Filename: loader_prompt.c - * - * Instantiation of the interactive loader functions. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin massive changes for tftp, strings, and more - * 05JUL2005 kb_admin save tag address, and set registers on boot - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "at91rm9200_lowlevel.h" -#include "at91rm9200.h" -#include "emac.h" -#include "loader_prompt.h" -#include "env_vars.h" -#include "lib.h" -#include "spi_flash.h" -#include "ee.h" - -/******************************* GLOBALS *************************************/ - - -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ - -static char inputBuffer[MAX_INPUT_SIZE]; -static int buffCount; - -// argv pointer are either NULL or point to locations in inputBuffer -static char *argv[MAX_COMMAND_PARAMS]; - -#define FLASH_OFFSET (0 * FLASH_PAGE_SIZE) -#define KERNEL_OFFSET (220 * FLASH_PAGE_SIZE) -#define KERNEL_LEN (6 * 1024 * FLASH_PAGE_SIZE) -static const char *backspaceString = "\010 \010"; - -static const command_entry_t CommandTable[] = { - {COMMAND_DUMP, "d"}, - {COMMAND_EXEC, "e"}, - {COMMAND_LOCAL_IP, "ip"}, - {COMMAND_MAC, "m"}, - {COMMAND_SERVER_IP, "server_ip"}, - {COMMAND_TFTP, "tftp"}, - {COMMAND_XMODEM, "x"}, - {COMMAND_RESET, "R"}, - {COMMAND_LOAD_SPI_KERNEL, "k"}, - {COMMAND_REPLACE_KERNEL_VIA_XMODEM, "K"}, - {COMMAND_REPLACE_FLASH_VIA_XMODEM, "I"}, - {COMMAND_REPLACE_ID_EEPROM, "E"}, - {COMMAND_FINAL_FLAG, 0} -}; - -/* - * .KB_C_FN_DEFINITION_START - * unsigned BuildIP(void) - * This private function packs the test IP info to an unsigned value. - * .KB_C_FN_DEFINITION_END - */ -static unsigned -BuildIP(void) -{ - return ((p_ASCIIToDec(argv[1]) << 24) | - (p_ASCIIToDec(argv[2]) << 16) | - (p_ASCIIToDec(argv[3]) << 8) | - p_ASCIIToDec(argv[4])); -} - - -/* - * .KB_C_FN_DEFINITION_START - * int StringToCommand(char *cPtr) - * This private function converts a command string to a command code. - * .KB_C_FN_DEFINITION_END - */ -static int -StringToCommand(char *cPtr) -{ - int i; - - for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i) - if (!strcmp(CommandTable[i].c_string, cPtr)) - return (CommandTable[i].command); - - return (COMMAND_INVALID); -} - - -/* - * .KB_C_FN_DEFINITION_START - * int BreakCommand(char *) - * This private function splits the buffer into separate strings as pointed - * by argv and returns the number of parameters (< 0 on failure). - * .KB_C_FN_DEFINITION_END - */ -static int -BreakCommand(char *buffer) -{ - int pCount, cCount, state; - - state = pCount = 0; - p_memset((char*)argv, 0, sizeof(argv)); - - for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) { - - if (!state) { - /* look for next command */ - if (!p_IsWhiteSpace(buffer[cCount])) { - argv[pCount++] = &buffer[cCount]; - state = 1; - } else { - buffer[cCount] = 0; - } - } else { - /* in command, find next white space */ - if (p_IsWhiteSpace(buffer[cCount])) { - buffer[cCount] = 0; - state = 0; - } - } - - if (pCount >= MAX_COMMAND_PARAMS) { - return (-1); - } - } - - return (pCount); -} - -#if 0 -static void -UpdateEEProm(int eeaddr) -{ - char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */ - int len; - - while ((len = xmodem_rx(addr)) == -1) - continue; - printf("\nDownloaded %u bytes.\n", len); - WriteEEPROM(eeaddr, 0, addr, len); -} -#endif - -static void -UpdateFlash(int offset) -{ - char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */ - int len, i, off; - - while ((len = xmodem_rx(addr)) == -1) - continue; - printf("\nDownloaded %u bytes.\n", len); - for (i = 0; i < len; i+= FLASH_PAGE_SIZE) { - off = i + offset; - SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE); - } -} - -static void -LoadKernelFromSpi(char *addr) -{ - int i, off; - - for (i = 0; i < KERNEL_LEN; i+= FLASH_PAGE_SIZE) { - off = i + KERNEL_OFFSET; - SPI_ReadFlash(off, addr + i, FLASH_PAGE_SIZE); - } -} - -/* - * .KB_C_FN_DEFINITION_START - * void ParseCommand(char *) - * This private function executes matching functions. - * .KB_C_FN_DEFINITION_END - */ -static void -ParseCommand(char *buffer) -{ - int argc, i; - - if ((argc = BreakCommand(buffer)) < 1) - return; - - switch (StringToCommand(argv[0])) { - case COMMAND_DUMP: - // display boot commands - DumpBootCommands(); - break; - - case COMMAND_EXEC: - { - // "e
" - // execute at address - void (*execAddr)(unsigned, unsigned); - - if (argc > 1) { - /* in future, include machtypes (MACH_KB9200 = 612) */ - execAddr = (void (*)(unsigned, unsigned)) - p_ASCIIToHex(argv[1]); - (*execAddr)(0, 612); - } - break; - } - - case COMMAND_TFTP: - { - // "tftp " - // tftp download - unsigned address = 0; - - if (argc > 2) - address = p_ASCIIToHex(argv[1]); - TFTP_Download(address, argv[2]); - break; - } - - case COMMAND_SERVER_IP: - // "server_ip " - // set download server address - if (argc > 4) - SetServerIPAddress(BuildIP()); - break; - - case COMMAND_LOCAL_IP: - // "local_ip - // set ip of this module - if (argc > 4) - SetLocalIPAddress(BuildIP()); - break; - - case COMMAND_MAC: - { - // "m - // set mac address using 6 byte values - unsigned char mac[6]; - - if (argc > 6) { - for (i = 0; i < 6; i++) - mac[i] = p_ASCIIToHex(argv[i + 1]); - EMAC_SetMACAddress(mac); - } - break; - } - - case COMMAND_LOAD_SPI_KERNEL: - // "k
" - if (argc > 1) - LoadKernelFromSpi((char *)p_ASCIIToHex(argv[1])); - break; - - case COMMAND_XMODEM: - // "x
" - // download X-modem record at address - if (argc > 1) - xmodem_rx((char *)p_ASCIIToHex(argv[1])); - break; - - case COMMAND_RESET: - printf("Reset\n"); - reset(); - while (1) continue; - break; - - case COMMAND_REPLACE_KERNEL_VIA_XMODEM: - printf("Updating KERNEL image\n"); - UpdateFlash(KERNEL_OFFSET); - break; - case COMMAND_REPLACE_FLASH_VIA_XMODEM: - printf("Updating FLASH image\n"); - UpdateFlash(FLASH_OFFSET); - break; - - case COMMAND_REPLACE_ID_EEPROM: - { - char buf[25]; - printf("Testing Config EEPROM\n"); - EEWrite(0, "This is a test", 15); - EERead(0, buf, 15); - printf("Found '%s'\n", buf); - break; - } - default: - break; - } - - printf("\n"); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ServicePrompt(char) - * This private function process each character checking for valid commands. - * This function is only executed if the character is considered valid. - * Each command is terminated with NULL (0) or ''. - * .KB_C_FN_DEFINITION_END - */ -static void -ServicePrompt(char p_char) -{ - if (p_char == '\r') - p_char = 0; - - if (p_char == '\010') { - if (buffCount) { - /* handle backspace BS */ - inputBuffer[--buffCount] = 0; - printf(backspaceString); - } - return; - } - if (buffCount < MAX_INPUT_SIZE - 1) { - inputBuffer[buffCount++] = p_char; - putchar(p_char); - } - if (!p_char) { - printf("\n"); - ParseCommand(inputBuffer); - p_memset(inputBuffer, 0, MAX_INPUT_SIZE); - buffCount = 0; - printf("\n>"); - } -} - - -/* ************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void Bootloader(void *inputFunction) - * This global function is the entry point for the bootloader. If the - * inputFunction pointer is NULL, the loader input will be serviced from - * the uart. Otherwise, inputFunction is called to get characters which - * the loader will parse. - * .KB_C_FN_DEFINITION_END - */ -void -Bootloader(int(*inputFunction)(int)) -{ - int ch = 0; - - p_memset((void*)inputBuffer, 0, sizeof(inputBuffer)); - buffCount = 0; - - printf("\n>"); - - while (1) - if ((ch = ((*inputFunction)(0))) > 0) - ServicePrompt(ch); -} diff --git a/sys/boot/arm/at91/bootspi/loader_prompt.h b/sys/boot/arm/at91/bootspi/loader_prompt.h deleted file mode 100644 index 70d7514391e5..000000000000 --- a/sys/boot/arm/at91/bootspi/loader_prompt.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * - * Filename: loader_prompt.h - * - * Definition of the interactive loader functions. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#ifndef _LOADER_PROMPT_H_ -#define _LOADER_PROMPT_H_ - -#define MAX_INPUT_SIZE 256 -#define MAX_COMMAND_PARAMS 10 - -enum { - COMMAND_INVALID = 0, - COMMAND_COPY, - COMMAND_DUMP, - COMMAND_EXEC, - COMMAND_HELP, - COMMAND_LOCAL_IP, - COMMAND_MAC, - COMMAND_SERVER_IP, - COMMAND_SET, - COMMAND_TAG, - COMMAND_TFTP, - COMMAND_WRITE, - COMMAND_XMODEM, - COMMAND_RESET, - COMMAND_LOAD_SPI_KERNEL, - COMMAND_REPLACE_KERNEL_VIA_XMODEM, - COMMAND_REPLACE_FLASH_VIA_XMODEM, - COMMAND_REPLACE_FPGA_VIA_XMODEM, - COMMAND_REPLACE_ID_EEPROM, - COMMAND_FINAL_FLAG -} e_cmd_t; - - -typedef struct { - int command; - const char *c_string; -} command_entry_t; - -void EnterInteractiveBootloader(int(*inputFunction)(int)); -void Bootloader(int(*inputFunction)(int)); -void fpga_load(void); - -#endif /* _LOADER_PROMPT_H_ */ diff --git a/sys/boot/arm/at91/bootspi/main.c b/sys/boot/arm/at91/bootspi/main.c deleted file mode 100644 index cb9d1dbc4225..000000000000 --- a/sys/boot/arm/at91/bootspi/main.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provided by kwikbyte without - * copyright as follows: - * - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * - * $FreeBSD$ - */ - -#include "env_vars.h" -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" -#include "loader_prompt.h" -#include "emac.h" -#include "lib.h" -#include "spi_flash.h" -#include "ee.h" - -int main(void); - -int -main(void) -{ - printf("\nBoot\n"); - EEInit(); - SPI_InitFlash(); -#ifdef TSC_FPGA - fpga_load(); -#endif - EMAC_Init(); - LoadBootCommands(); - if (getc(1) == -1) { - start_wdog(30); - ExecuteEnvironmentFunctions(); - } - Bootloader(getc); - return (1); -} diff --git a/sys/boot/arm/at91/libat91/Makefile b/sys/boot/arm/at91/libat91/Makefile deleted file mode 100644 index b02281dc640d..000000000000 --- a/sys/boot/arm/at91/libat91/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# $FreeBSD$ - -.include -.include "${.CURDIR}/../Makefile.inc" - -SOC?=at91rm9200 - -LIB= at91 -INTERNALLIB= -SRCS=${SOC}_lowlevel.c delay.c eeprom.c emac.c emac_init.c getc.c \ - putchar.c printf.c reset.c spi_flash.c xmodem.c \ - sd-card.c strcvt.c strlen.c strcmp.c memcpy.c strcpy.c \ - memset.c memcmp.c -SRCS+=ashldi3.c divsi3.S -MAN= - -.if ${MK_TAG_LIST} != "no" -CFLAGS += -I${.CURDIR}/.. -DSUPPORT_TAG_LIST -SRCS+=tag_list.c -.endif - -.include diff --git a/sys/boot/arm/at91/libat91/arm_init.S b/sys/boot/arm/at91/libat91/arm_init.S deleted file mode 100644 index a15fb540e9cc..000000000000 --- a/sys/boot/arm/at91/libat91/arm_init.S +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * - * Filename: arm_init.s - * - * Initialization for C-environment and basic operation. Adapted from - * ATMEL cstartup.s. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin updated for 16KB eeprom - * Atmel stack prevents loading full size at once - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ - - .equ TWI_EEPROM_SIZE, 0x3000 - .equ ARM_MODE_USER, 0x10 - .equ ARM_MODE_FIQ, 0x11 - .equ ARM_MODE_IRQ, 0x12 - .equ ARM_MODE_SVC, 0x13 - .equ ARM_MODE_ABORT, 0x17 - .equ ARM_MODE_UNDEF, 0x1B - .equ ARM_MODE_SYS, 0x1F - .equ I_BIT, 0x80 - .equ F_BIT, 0x40 - .equ T_BIT, 0x20 - -/* - * Stack definitions - * - * Start near top of internal RAM. - */ - .equ END_INT_SRAM, 0x4000 - .equ SVC_STACK_START, (END_INT_SRAM - 0x4) - .equ SVC_STACK_USE, 0x21800000 - -start: - -/* vectors - must reside at address 0 */ -/* the format of this table is defined in the datasheet */ - B InitReset @; reset -undefvec: - B undefvec @; Undefined Instruction -swivec: - B swivec @; Software Interrupt -pabtvec: - B pabtvec @; Prefetch Abort -dabtvec: - B dabtvec @; Data Abort -rsvdvec: -#ifdef BOOT_IIC - .long (TWI_EEPROM_SIZE >> 9) -#else -#ifdef BOOT_BWCT - .long ((528 << 17) | (13 << 13) | (12 * 2)) -#else - .long ((1056 << 17) | (13 << 13) | (12 * 2)) -#endif -#endif -irqvec: - ldr pc, [pc,#-0xF20] @; IRQ : read the AIC -fiqvec: - B fiqvec @; FIQ - -InitReset: - -/* Set stack and init for SVC */ - ldr r1, = SVC_STACK_START - mov sp, r1 @; Init stack SYS - - msr cpsr_c, #(ARM_MODE_SVC | I_BIT | F_BIT) - mov sp, r1 @ ; Init stack SYS - -/* Perform system initialization */ - - .extern _init - bl _init -#ifndef BOOT_BOOT0 - ldr r1, = SVC_STACK_USE - mov sp, r1 @ ; Move the stack to SDRAM -#endif - -/* Start execution at main */ - .extern main -_main: -__main: - bl main -/* main should not return. If it does, spin forever */ -infiniteLoop: - b infiniteLoop - -#ifdef BOOT_COMMANDS -/* the following section is used to store boot commands in */ -/* non-volatile memory. */ - - .global BootCommandSection -BootCommandSection: -#ifdef SUPPORT_LINUX - .string "Bootloader for KB9202 Evaluation Board." - .string "c 0x20210000 0x10100000 0x80000 " - .string "m 0 0 0 0 0 0 " - .string "t 0x20000100 console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933" - .string "e 0x10000000 " - .string " " -#else -#if 1 - .string "m 42 53 44 0 0 1" - .string "ip 206 168 13 194" - .string "server_ip 206 168 13 207" - .string "tftp 0x20000000 kernel.bin" - .string "e 0x20000000" -#else - .string "m 42 53 44 0 0 1" - .string "k 0x20000000" - .string "e 0x20000000" -#endif - .word 0 -#endif -#endif diff --git a/sys/boot/arm/at91/libat91/at91rm9200.h b/sys/boot/arm/at91/libat91/at91rm9200.h deleted file mode 100644 index 42dc969397fb..000000000000 --- a/sys/boot/arm/at91/libat91/at91rm9200.h +++ /dev/null @@ -1,2411 +0,0 @@ -// ---------------------------------------------------------------------------- -// ATMEL Microcontroller Software Support - ROUSSET - -// ---------------------------------------------------------------------------- -// The software is delivered "AS IS" without warranty or condition of any -// kind, either express, implied or statutory. This includes without -// limitation any warranty or condition with respect to merchantability or -// fitness for any particular purpose, or against the infringements of -// intellectual property rights of others. -// ---------------------------------------------------------------------------- -// $FreeBSD$ -// -// File Name : AT91RM9200.h -// Object : AT91RM9200 definitions -// Generated : AT91 SW Application Group 07/04/2003 (11:05:04) -// -// CVS Reference : /AT91RM9200.pl/1.16/Fri Feb 07 09:29:50 2003// -// CVS Reference : /SYS_AT91RM9200.pl/1.2/Fri Jan 17 11:44:36 2003// -// CVS Reference : /MC_1760A.pl/1.1/Fri Aug 23 13:38:22 2002// -// CVS Reference : /AIC_1796B.pl/1.1.1.1/Fri Jun 28 08:36:46 2002// -// CVS Reference : /PMC_2636A.pl/1.1.1.1/Fri Jun 28 08:36:48 2002// -// CVS Reference : /ST_1763B.pl/1.1/Fri Aug 23 13:41:42 2002// -// CVS Reference : /RTC_1245D.pl/1.2/Fri Jan 31 11:19:06 2003// -// CVS Reference : /PIO_1725D.pl/1.1.1.1/Fri Jun 28 08:36:46 2002// -// CVS Reference : /DBGU_1754A.pl/1.4/Fri Jan 31 11:18:24 2003// -// CVS Reference : /UDP_1765B.pl/1.3/Fri Aug 02 13:45:38 2002// -// CVS Reference : /MCI_1764A.pl/1.2/Thu Nov 14 16:48:24 2002// -// CVS Reference : /US_1739C.pl/1.2/Fri Jul 12 06:49:24 2002// -// CVS Reference : /SPI_AT91RMxxxx.pl/1.3/Tue Nov 26 09:20:28 2002// -// CVS Reference : /SSC_1762A.pl/1.2/Fri Nov 08 12:26:38 2002// -// CVS Reference : /TC_1753B.pl/1.2/Fri Jan 31 11:19:54 2003// -// CVS Reference : /TWI_1761B.pl/1.4/Fri Feb 07 09:30:06 2003// -// CVS Reference : /PDC_1734B.pl/1.2/Thu Nov 21 15:38:22 2002// -// CVS Reference : /UHP_xxxxA.pl/1.1/Mon Jul 22 11:21:58 2002// -// CVS Reference : /EMAC_1794A.pl/1.4/Fri Jan 17 11:11:54 2003// -// CVS Reference : /EBI_1759B.pl/1.10/Fri Jan 17 11:44:28 2003// -// CVS Reference : /SMC_1783A.pl/1.3/Thu Oct 31 13:38:16 2002// -// CVS Reference : /SDRC_1758B.pl/1.2/Thu Oct 03 12:04:40 2002// -// CVS Reference : /BFC_1757B.pl/1.3/Thu Oct 31 13:38:00 2002// -// ---------------------------------------------------------------------------- - -#ifndef AT91RM9200_H -#define AT91RM9200_H - -#define ATMEL_ENV - -typedef volatile unsigned int AT91_REG;// Hardware register definition - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR System Peripherals -// ***************************************************************************** -typedef struct _AT91S_SYS { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register - AT91_REG Reserved2[45]; // - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved3[7]; // - AT91_REG DBGU_C1R; // Chip ID1 Register - AT91_REG DBGU_C2R; // Chip ID2 Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved4[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register - AT91_REG Reserved5[54]; // - AT91_REG PIOA_PER; // PIO Enable Register - AT91_REG PIOA_PDR; // PIO Disable Register - AT91_REG PIOA_PSR; // PIO Status Register - AT91_REG Reserved6[1]; // - AT91_REG PIOA_OER; // Output Enable Register - AT91_REG PIOA_ODR; // Output Disable Registerr - AT91_REG PIOA_OSR; // Output Status Register - AT91_REG Reserved7[1]; // - AT91_REG PIOA_IFER; // Input Filter Enable Register - AT91_REG PIOA_IFDR; // Input Filter Disable Register - AT91_REG PIOA_IFSR; // Input Filter Status Register - AT91_REG Reserved8[1]; // - AT91_REG PIOA_SODR; // Set Output Data Register - AT91_REG PIOA_CODR; // Clear Output Data Register - AT91_REG PIOA_ODSR; // Output Data Status Register - AT91_REG PIOA_PDSR; // Pin Data Status Register - AT91_REG PIOA_IER; // Interrupt Enable Register - AT91_REG PIOA_IDR; // Interrupt Disable Register - AT91_REG PIOA_IMR; // Interrupt Mask Register - AT91_REG PIOA_ISR; // Interrupt Status Register - AT91_REG PIOA_MDER; // Multi-driver Enable Register - AT91_REG PIOA_MDDR; // Multi-driver Disable Register - AT91_REG PIOA_MDSR; // Multi-driver Status Register - AT91_REG Reserved9[1]; // - AT91_REG PIOA_PPUDR; // Pull-up Disable Register - AT91_REG PIOA_PPUER; // Pull-up Enable Register - AT91_REG PIOA_PPUSR; // Pad Pull-up Status Register - AT91_REG Reserved10[1]; // - AT91_REG PIOA_ASR; // Select A Register - AT91_REG PIOA_BSR; // Select B Register - AT91_REG PIOA_ABSR; // AB Select Status Register - AT91_REG Reserved11[9]; // - AT91_REG PIOA_OWER; // Output Write Enable Register - AT91_REG PIOA_OWDR; // Output Write Disable Register - AT91_REG PIOA_OWSR; // Output Write Status Register - AT91_REG Reserved12[85]; // - AT91_REG PIOB_PER; // PIO Enable Register - AT91_REG PIOB_PDR; // PIO Disable Register - AT91_REG PIOB_PSR; // PIO Status Register - AT91_REG Reserved13[1]; // - AT91_REG PIOB_OER; // Output Enable Register - AT91_REG PIOB_ODR; // Output Disable Registerr - AT91_REG PIOB_OSR; // Output Status Register - AT91_REG Reserved14[1]; // - AT91_REG PIOB_IFER; // Input Filter Enable Register - AT91_REG PIOB_IFDR; // Input Filter Disable Register - AT91_REG PIOB_IFSR; // Input Filter Status Register - AT91_REG Reserved15[1]; // - AT91_REG PIOB_SODR; // Set Output Data Register - AT91_REG PIOB_CODR; // Clear Output Data Register - AT91_REG PIOB_ODSR; // Output Data Status Register - AT91_REG PIOB_PDSR; // Pin Data Status Register - AT91_REG PIOB_IER; // Interrupt Enable Register - AT91_REG PIOB_IDR; // Interrupt Disable Register - AT91_REG PIOB_IMR; // Interrupt Mask Register - AT91_REG PIOB_ISR; // Interrupt Status Register - AT91_REG PIOB_MDER; // Multi-driver Enable Register - AT91_REG PIOB_MDDR; // Multi-driver Disable Register - AT91_REG PIOB_MDSR; // Multi-driver Status Register - AT91_REG Reserved16[1]; // - AT91_REG PIOB_PPUDR; // Pull-up Disable Register - AT91_REG PIOB_PPUER; // Pull-up Enable Register - AT91_REG PIOB_PPUSR; // Pad Pull-up Status Register - AT91_REG Reserved17[1]; // - AT91_REG PIOB_ASR; // Select A Register - AT91_REG PIOB_BSR; // Select B Register - AT91_REG PIOB_ABSR; // AB Select Status Register - AT91_REG Reserved18[9]; // - AT91_REG PIOB_OWER; // Output Write Enable Register - AT91_REG PIOB_OWDR; // Output Write Disable Register - AT91_REG PIOB_OWSR; // Output Write Status Register - AT91_REG Reserved19[85]; // - AT91_REG PIOC_PER; // PIO Enable Register - AT91_REG PIOC_PDR; // PIO Disable Register - AT91_REG PIOC_PSR; // PIO Status Register - AT91_REG Reserved20[1]; // - AT91_REG PIOC_OER; // Output Enable Register - AT91_REG PIOC_ODR; // Output Disable Registerr - AT91_REG PIOC_OSR; // Output Status Register - AT91_REG Reserved21[1]; // - AT91_REG PIOC_IFER; // Input Filter Enable Register - AT91_REG PIOC_IFDR; // Input Filter Disable Register - AT91_REG PIOC_IFSR; // Input Filter Status Register - AT91_REG Reserved22[1]; // - AT91_REG PIOC_SODR; // Set Output Data Register - AT91_REG PIOC_CODR; // Clear Output Data Register - AT91_REG PIOC_ODSR; // Output Data Status Register - AT91_REG PIOC_PDSR; // Pin Data Status Register - AT91_REG PIOC_IER; // Interrupt Enable Register - AT91_REG PIOC_IDR; // Interrupt Disable Register - AT91_REG PIOC_IMR; // Interrupt Mask Register - AT91_REG PIOC_ISR; // Interrupt Status Register - AT91_REG PIOC_MDER; // Multi-driver Enable Register - AT91_REG PIOC_MDDR; // Multi-driver Disable Register - AT91_REG PIOC_MDSR; // Multi-driver Status Register - AT91_REG Reserved23[1]; // - AT91_REG PIOC_PPUDR; // Pull-up Disable Register - AT91_REG PIOC_PPUER; // Pull-up Enable Register - AT91_REG PIOC_PPUSR; // Pad Pull-up Status Register - AT91_REG Reserved24[1]; // - AT91_REG PIOC_ASR; // Select A Register - AT91_REG PIOC_BSR; // Select B Register - AT91_REG PIOC_ABSR; // AB Select Status Register - AT91_REG Reserved25[9]; // - AT91_REG PIOC_OWER; // Output Write Enable Register - AT91_REG PIOC_OWDR; // Output Write Disable Register - AT91_REG PIOC_OWSR; // Output Write Status Register - AT91_REG Reserved26[85]; // - AT91_REG PIOD_PER; // PIO Enable Register - AT91_REG PIOD_PDR; // PIO Disable Register - AT91_REG PIOD_PSR; // PIO Status Register - AT91_REG Reserved27[1]; // - AT91_REG PIOD_OER; // Output Enable Register - AT91_REG PIOD_ODR; // Output Disable Registerr - AT91_REG PIOD_OSR; // Output Status Register - AT91_REG Reserved28[1]; // - AT91_REG PIOD_IFER; // Input Filter Enable Register - AT91_REG PIOD_IFDR; // Input Filter Disable Register - AT91_REG PIOD_IFSR; // Input Filter Status Register - AT91_REG Reserved29[1]; // - AT91_REG PIOD_SODR; // Set Output Data Register - AT91_REG PIOD_CODR; // Clear Output Data Register - AT91_REG PIOD_ODSR; // Output Data Status Register - AT91_REG PIOD_PDSR; // Pin Data Status Register - AT91_REG PIOD_IER; // Interrupt Enable Register - AT91_REG PIOD_IDR; // Interrupt Disable Register - AT91_REG PIOD_IMR; // Interrupt Mask Register - AT91_REG PIOD_ISR; // Interrupt Status Register - AT91_REG PIOD_MDER; // Multi-driver Enable Register - AT91_REG PIOD_MDDR; // Multi-driver Disable Register - AT91_REG PIOD_MDSR; // Multi-driver Status Register - AT91_REG Reserved30[1]; // - AT91_REG PIOD_PPUDR; // Pull-up Disable Register - AT91_REG PIOD_PPUER; // Pull-up Enable Register - AT91_REG PIOD_PPUSR; // Pad Pull-up Status Register - AT91_REG Reserved31[1]; // - AT91_REG PIOD_ASR; // Select A Register - AT91_REG PIOD_BSR; // Select B Register - AT91_REG PIOD_ABSR; // AB Select Status Register - AT91_REG Reserved32[9]; // - AT91_REG PIOD_OWER; // Output Write Enable Register - AT91_REG PIOD_OWDR; // Output Write Disable Register - AT91_REG PIOD_OWSR; // Output Write Status Register - AT91_REG Reserved33[85]; // - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved34[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved35[1]; // - AT91_REG CKGR_MOR; // Main Oscillator Register - AT91_REG CKGR_MCFR; // Main Clock Frequency Register - AT91_REG CKGR_PLLAR; // PLL A Register - AT91_REG CKGR_PLLBR; // PLL B Register - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved36[3]; // - AT91_REG PMC_PCKR[8]; // Programmable Clock Register - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register - AT91_REG Reserved37[36]; // - AT91_REG ST_CR; // Control Register - AT91_REG ST_PIMR; // Period Interval Mode Register - AT91_REG ST_WDMR; // Watchdog Mode Register - AT91_REG ST_RTMR; // Real-time Mode Register - AT91_REG ST_SR; // Status Register - AT91_REG ST_IER; // Interrupt Enable Register - AT91_REG ST_IDR; // Interrupt Disable Register - AT91_REG ST_IMR; // Interrupt Mask Register - AT91_REG ST_RTAR; // Real-time Alarm Register - AT91_REG ST_CRTR; // Current Real-time Register - AT91_REG Reserved38[54]; // - AT91_REG RTC_CR; // Control Register - AT91_REG RTC_MR; // Mode Register - AT91_REG RTC_TIMR; // Time Register - AT91_REG RTC_CALR; // Calendar Register - AT91_REG RTC_TIMALR; // Time Alarm Register - AT91_REG RTC_CALALR; // Calendar Alarm Register - AT91_REG RTC_SR; // Status Register - AT91_REG RTC_SCCR; // Status Clear Command Register - AT91_REG RTC_IER; // Interrupt Enable Register - AT91_REG RTC_IDR; // Interrupt Disable Register - AT91_REG RTC_IMR; // Interrupt Mask Register - AT91_REG RTC_VER; // Valid Entry Register - AT91_REG Reserved39[52]; // - AT91_REG MC_RCR; // MC Remap Control Register - AT91_REG MC_ASR; // MC Abort Status Register - AT91_REG MC_AASR; // MC Abort Address Status Register - AT91_REG Reserved40[1]; // - AT91_REG MC_PUIA[16]; // MC Protection Unit Area - AT91_REG MC_PUP; // MC Protection Unit Peripherals - AT91_REG MC_PUER; // MC Protection Unit Enable Register - AT91_REG Reserved41[2]; // - AT91_REG EBI_CSA; // Chip Select Assignment Register - AT91_REG EBI_CFGR; // Configuration Register - AT91_REG Reserved42[2]; // - AT91_REG EBI_SMC2_CSR[8]; // SMC2 Chip Select Register - AT91_REG EBI_SDRC_MR; // SDRAM Controller Mode Register - AT91_REG EBI_SDRC_TR; // SDRAM Controller Refresh Timer Register - AT91_REG EBI_SDRC_CR; // SDRAM Controller Configuration Register - AT91_REG EBI_SDRC_SRR; // SDRAM Controller Self Refresh Register - AT91_REG EBI_SDRC_LPR; // SDRAM Controller Low Power Register - AT91_REG EBI_SDRC_IER; // SDRAM Controller Interrupt Enable Register - AT91_REG EBI_SDRC_IDR; // SDRAM Controller Interrupt Disable Register - AT91_REG EBI_SDRC_IMR; // SDRAM Controller Interrupt Mask Register - AT91_REG EBI_SDRC_ISR; // SDRAM Controller Interrupt Mask Register - AT91_REG Reserved43[3]; // - AT91_REG EBI_BFC_MR; // BFC Mode Register -} AT91S_SYS, *AT91PS_SYS; - - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Memory Controller Interface -// ***************************************************************************** -typedef struct _AT91S_MC { - AT91_REG MC_RCR; // MC Remap Control Register - AT91_REG MC_ASR; // MC Abort Status Register - AT91_REG MC_AASR; // MC Abort Address Status Register - AT91_REG Reserved0[1]; // - AT91_REG MC_PUIA[16]; // MC Protection Unit Area - AT91_REG MC_PUP; // MC Protection Unit Peripherals - AT91_REG MC_PUER; // MC Protection Unit Enable Register -} AT91S_MC, *AT91PS_MC; - -// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- -#define AT91C_MC_RCB (0x1u << 0) // (MC) Remap Command Bit -// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- -#define AT91C_MC_UNDADD (0x1u << 0) // (MC) Undefined Addess Abort Status -#define AT91C_MC_MISADD (0x1u << 1) // (MC) Misaligned Addess Abort Status -#define AT91C_MC_MPU (0x1u << 2) // (MC) Memory protection Unit Abort Status -#define AT91C_MC_ABTSZ (0x3u << 8) // (MC) Abort Size Status -#define AT91C_MC_ABTSZ_BYTE (0x0u << 8) // (MC) Byte -#define AT91C_MC_ABTSZ_HWORD (0x1u << 8) // (MC) Half-word -#define AT91C_MC_ABTSZ_WORD (0x2u << 8) // (MC) Word -#define AT91C_MC_ABTTYP (0x3u << 10) // (MC) Abort Type Status -#define AT91C_MC_ABTTYP_DATAR (0x0u << 10) // (MC) Data Read -#define AT91C_MC_ABTTYP_DATAW (0x1u << 10) // (MC) Data Write -#define AT91C_MC_ABTTYP_FETCH (0x2u << 10) // (MC) Code Fetch -#define AT91C_MC_MST0 (0x1u << 16) // (MC) Master 0 Abort Source -#define AT91C_MC_MST1 (0x1u << 17) // (MC) Master 1 Abort Source -#define AT91C_MC_SVMST0 (0x1u << 24) // (MC) Saved Master 0 Abort Source -#define AT91C_MC_SVMST1 (0x1u << 25) // (MC) Saved Master 1 Abort Source -// -------- MC_PUIA : (MC Offset: 0x10) MC Protection Unit Area -------- -#define AT91C_MC_PROT (0x3u << 0) // (MC) Protection -#define AT91C_MC_PROT_PNAUNA 0x0u // (MC) Privilege: No Access, User: No Access -#define AT91C_MC_PROT_PRWUNA 0x1u // (MC) Privilege: Read/Write, User: No Access -#define AT91C_MC_PROT_PRWURO 0x2u // (MC) Privilege: Read/Write, User: Read Only -#define AT91C_MC_PROT_PRWURW 0x3u // (MC) Privilege: Read/Write, User: Read/Write -#define AT91C_MC_SIZE (0xFu << 4) // (MC) Internal Area Size -#define AT91C_MC_SIZE_1KB (0x0u << 4) // (MC) Area size 1KByte -#define AT91C_MC_SIZE_2KB (0x1u << 4) // (MC) Area size 2KByte -#define AT91C_MC_SIZE_4KB (0x2u << 4) // (MC) Area size 4KByte -#define AT91C_MC_SIZE_8KB (0x3u << 4) // (MC) Area size 8KByte -#define AT91C_MC_SIZE_16KB (0x4u << 4) // (MC) Area size 16KByte -#define AT91C_MC_SIZE_32KB (0x5u << 4) // (MC) Area size 32KByte -#define AT91C_MC_SIZE_64KB (0x6u << 4) // (MC) Area size 64KByte -#define AT91C_MC_SIZE_128KB (0x7u << 4) // (MC) Area size 128KByte -#define AT91C_MC_SIZE_256KB (0x8u << 4) // (MC) Area size 256KByte -#define AT91C_MC_SIZE_512KB (0x9u << 4) // (MC) Area size 512KByte -#define AT91C_MC_SIZE_1MB (0xAu << 4) // (MC) Area size 1MByte -#define AT91C_MC_SIZE_2MB (0xBu << 4) // (MC) Area size 2MByte -#define AT91C_MC_SIZE_4MB (0xCu << 4) // (MC) Area size 4MByte -#define AT91C_MC_SIZE_8MB (0xDu << 4) // (MC) Area size 8MByte -#define AT91C_MC_SIZE_16MB (0xEu << 4) // (MC) Area size 16MByte -#define AT91C_MC_SIZE_64MB (0xFu << 4) // (MC) Area size 64MByte -#define AT91C_MC_BA (0x3FFFFu << 10) // (MC) Internal Area Base Address -// -------- MC_PUP : (MC Offset: 0x50) MC Protection Unit Peripheral -------- -// -------- MC_PUER : (MC Offset: 0x54) MC Protection Unit Area -------- -#define AT91C_MC_PUEB (0x1u << 0) // (MC) Protection Unit enable Bit - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Real-time Clock Alarm and Parallel Load Interface -// ***************************************************************************** -typedef struct _AT91S_RTC { - AT91_REG RTC_CR; // Control Register - AT91_REG RTC_MR; // Mode Register - AT91_REG RTC_TIMR; // Time Register - AT91_REG RTC_CALR; // Calendar Register - AT91_REG RTC_TIMALR; // Time Alarm Register - AT91_REG RTC_CALALR; // Calendar Alarm Register - AT91_REG RTC_SR; // Status Register - AT91_REG RTC_SCCR; // Status Clear Command Register - AT91_REG RTC_IER; // Interrupt Enable Register - AT91_REG RTC_IDR; // Interrupt Disable Register - AT91_REG RTC_IMR; // Interrupt Mask Register - AT91_REG RTC_VER; // Valid Entry Register -} AT91S_RTC, *AT91PS_RTC; - -// -------- RTC_CR : (RTC Offset: 0x0) RTC Control Register -------- -#define AT91C_RTC_UPDTIM (0x1u << 0) // (RTC) Update Request Time Register -#define AT91C_RTC_UPDCAL (0x1u << 1) // (RTC) Update Request Calendar Register -#define AT91C_RTC_TIMEVSEL (0x3u << 8) // (RTC) Time Event Selection -#define AT91C_RTC_TIMEVSEL_MINUTE (0x0u << 8) // (RTC) Minute change. -#define AT91C_RTC_TIMEVSEL_HOUR (0x1u << 8) // (RTC) Hour change. -#define AT91C_RTC_TIMEVSEL_DAY24 (0x2u << 8) // (RTC) Every day at midnight. -#define AT91C_RTC_TIMEVSEL_DAY12 (0x3u << 8) // (RTC) Every day at noon. -#define AT91C_RTC_CALEVSEL (0x3u << 16) // (RTC) Calendar Event Selection -#define AT91C_RTC_CALEVSEL_WEEK (0x0u << 16) // (RTC) Week change (every Monday at time 00:00:00). -#define AT91C_RTC_CALEVSEL_MONTH (0x1u << 16) // (RTC) Month change (every 01 of each month at time 00:00:00). -#define AT91C_RTC_CALEVSEL_YEAR (0x2u << 16) // (RTC) Year change (every January 1 at time 00:00:00). -// -------- RTC_MR : (RTC Offset: 0x4) RTC Mode Register -------- -#define AT91C_RTC_HRMOD (0x1u << 0) // (RTC) 12-24 hour Mode -// -------- RTC_TIMR : (RTC Offset: 0x8) RTC Time Register -------- -#define AT91C_RTC_SEC (0x7Fu << 0) // (RTC) Current Second -#define AT91C_RTC_MIN (0x7Fu << 8) // (RTC) Current Minute -#define AT91C_RTC_HOUR (0x1Fu << 16) // (RTC) Current Hour -#define AT91C_RTC_AMPM (0x1u << 22) // (RTC) Ante Meridiem, Post Meridiem Indicator -// -------- RTC_CALR : (RTC Offset: 0xc) RTC Calendar Register -------- -#define AT91C_RTC_CENT (0x3Fu << 0) // (RTC) Current Century -#define AT91C_RTC_YEAR (0xFFu << 8) // (RTC) Current Year -#define AT91C_RTC_MONTH (0x1Fu << 16) // (RTC) Current Month -#define AT91C_RTC_DAY (0x7u << 21) // (RTC) Current Day -#define AT91C_RTC_DATE (0x3Fu << 24) // (RTC) Current Date -// -------- RTC_TIMALR : (RTC Offset: 0x10) RTC Time Alarm Register -------- -#define AT91C_RTC_SECEN (0x1u << 7) // (RTC) Second Alarm Enable -#define AT91C_RTC_MINEN (0x1u << 15) // (RTC) Minute Alarm -#define AT91C_RTC_HOUREN (0x1u << 23) // (RTC) Current Hour -// -------- RTC_CALALR : (RTC Offset: 0x14) RTC Calendar Alarm Register -------- -#define AT91C_RTC_MONTHEN (0x1u << 23) // (RTC) Month Alarm Enable -#define AT91C_RTC_DATEEN (0x1u << 31) // (RTC) Date Alarm Enable -// -------- RTC_SR : (RTC Offset: 0x18) RTC Status Register -------- -#define AT91C_RTC_ACKUPD (0x1u << 0) // (RTC) Acknowledge for Update -#define AT91C_RTC_ALARM (0x1u << 1) // (RTC) Alarm Flag -#define AT91C_RTC_SECEV (0x1u << 2) // (RTC) Second Event -#define AT91C_RTC_TIMEV (0x1u << 3) // (RTC) Time Event -#define AT91C_RTC_CALEV (0x1u << 4) // (RTC) Calendar event -// -------- RTC_SCCR : (RTC Offset: 0x1c) RTC Status Clear Command Register -------- -// -------- RTC_IER : (RTC Offset: 0x20) RTC Interrupt Enable Register -------- -// -------- RTC_IDR : (RTC Offset: 0x24) RTC Interrupt Disable Register -------- -// -------- RTC_IMR : (RTC Offset: 0x28) RTC Interrupt Mask Register -------- -// -------- RTC_VER : (RTC Offset: 0x2c) RTC Valid Entry Register -------- -#define AT91C_RTC_NVTIM (0x1u << 0) // (RTC) Non valid Time -#define AT91C_RTC_NVCAL (0x1u << 1) // (RTC) Non valid Calendar -#define AT91C_RTC_NVTIMALR (0x1u << 2) // (RTC) Non valid time Alarm -#define AT91C_RTC_NVCALALR (0x1u << 3) // (RTC) Nonvalid Calendar Alarm - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR System Timer Interface -// ***************************************************************************** -typedef struct _AT91S_ST { - AT91_REG ST_CR; // Control Register - AT91_REG ST_PIMR; // Period Interval Mode Register - AT91_REG ST_WDMR; // Watchdog Mode Register - AT91_REG ST_RTMR; // Real-time Mode Register - AT91_REG ST_SR; // Status Register - AT91_REG ST_IER; // Interrupt Enable Register - AT91_REG ST_IDR; // Interrupt Disable Register - AT91_REG ST_IMR; // Interrupt Mask Register - AT91_REG ST_RTAR; // Real-time Alarm Register - AT91_REG ST_CRTR; // Current Real-time Register -} AT91S_ST, *AT91PS_ST; - -// -------- ST_CR : (ST Offset: 0x0) System Timer Control Register -------- -#define AT91C_ST_WDRST (0x1u << 0) // (ST) Watchdog Timer Restart -// -------- ST_PIMR : (ST Offset: 0x4) System Timer Period Interval Mode Register -------- -#define AT91C_ST_PIV (0xFFFFu << 0) // (ST) Watchdog Timer Restart -// -------- ST_WDMR : (ST Offset: 0x8) System Timer Watchdog Mode Register -------- -#define AT91C_ST_WDV (0xFFFFu << 0) // (ST) Watchdog Timer Restart -#define AT91C_ST_RSTEN (0x1u << 16) // (ST) Reset Enable -#define AT91C_ST_EXTEN (0x1u << 17) // (ST) External Signal Assertion Enable -// -------- ST_RTMR : (ST Offset: 0xc) System Timer Real-time Mode Register -------- -#define AT91C_ST_RTPRES (0xFFFFu << 0) // (ST) Real-time Timer Prescaler Value -// -------- ST_SR : (ST Offset: 0x10) System Timer Status Register -------- -#define AT91C_ST_PITS (0x1u << 0) // (ST) Period Interval Timer Interrupt -#define AT91C_ST_WDOVF (0x1u << 1) // (ST) Watchdog Overflow -#define AT91C_ST_RTTINC (0x1u << 2) // (ST) Real-time Timer Increment -#define AT91C_ST_ALMS (0x1u << 3) // (ST) Alarm Status -// -------- ST_IER : (ST Offset: 0x14) System Timer Interrupt Enable Register -------- -// -------- ST_IDR : (ST Offset: 0x18) System Timer Interrupt Disable Register -------- -// -------- ST_IMR : (ST Offset: 0x1c) System Timer Interrupt Mask Register -------- -// -------- ST_RTAR : (ST Offset: 0x20) System Timer Real-time Alarm Register -------- -#define AT91C_ST_ALMV (0xFFFFFu << 0) // (ST) Alarm Value Value -// -------- ST_CRTR : (ST Offset: 0x24) System Timer Current Real-time Register -------- -#define AT91C_ST_CRTV (0xFFFFFu << 0) // (ST) Current Real-time Value - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Power Management Controller -// ***************************************************************************** -typedef struct _AT91S_PMC { - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved0[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved1[5]; // - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved2[3]; // - AT91_REG PMC_PCKR[8]; // Programmable Clock Register - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register -} AT91S_PMC, *AT91PS_PMC; - -// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register -------- -#define AT91C_PMC_PCK (0x1u << 0) // (PMC) Processor Clock -#define AT91C_PMC_UDP (0x1u << 1) // (PMC) USB Device Port Clock -#define AT91C_PMC_MCKUDP (0x1u << 2) // (PMC) USB Device Port Master Clock Automatic Disable on Suspend -#define AT91C_PMC_UHP (0x1u << 4) // (PMC) USB Host Port Clock -#define AT91C_PMC_PCK0 (0x1u << 8) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK1 (0x1u << 9) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK2 (0x1u << 10) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK3 (0x1u << 11) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK4 (0x1u << 12) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK5 (0x1u << 13) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK6 (0x1u << 14) // (PMC) Programmable Clock Output -#define AT91C_PMC_PCK7 (0x1u << 15) // (PMC) Programmable Clock Output -// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register -------- -// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register -------- -// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register -------- -#define AT91C_PMC_CSS (0x3u << 0) // (PMC) Programmable Clock Selection -#define AT91C_PMC_CSS_SLOW_CLK 0x0u // (PMC) Slow Clock is selected -#define AT91C_PMC_CSS_MAIN_CLK 0x1u // (PMC) Main Clock is selected -#define AT91C_PMC_CSS_PLLA_CLK 0x2u // (PMC) Clock from PLL A is selected -#define AT91C_PMC_CSS_PLLB_CLK 0x3u // (PMC) Clock from PLL B is selected -#define AT91C_PMC_PRES (0x7u << 2) // (PMC) Programmable Clock Prescaler -#define AT91C_PMC_PRES_CLK (0x0u << 2) // (PMC) Selected clock -#define AT91C_PMC_PRES_CLK_2 (0x1u << 2) // (PMC) Selected clock divided by 2 -#define AT91C_PMC_PRES_CLK_4 (0x2u << 2) // (PMC) Selected clock divided by 4 -#define AT91C_PMC_PRES_CLK_8 (0x3u << 2) // (PMC) Selected clock divided by 8 -#define AT91C_PMC_PRES_CLK_16 (0x4u << 2) // (PMC) Selected clock divided by 16 -#define AT91C_PMC_PRES_CLK_32 (0x5u << 2) // (PMC) Selected clock divided by 32 -#define AT91C_PMC_PRES_CLK_64 (0x6u << 2) // (PMC) Selected clock divided by 64 -#define AT91C_PMC_MDIV (0x3u << 8) // (PMC) Master Clock Division -#define AT91C_PMC_MDIV_1 (0x0u << 8) // (PMC) The master clock and the processor clock are the same -#define AT91C_PMC_MDIV_2 (0x1u << 8) // (PMC) The processor clock is twice as fast as the master clock -#define AT91C_PMC_MDIV_3 (0x2u << 8) // (PMC) The processor clock is three times faster than the master clock -#define AT91C_PMC_MDIV_4 (0x3u << 8) // (PMC) The processor clock is four times faster than the master clock -// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register -------- -// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register -------- -#define AT91C_PMC_MOSCS (0x1u << 0) // (PMC) MOSC Status/Enable/Disable/Mask -#define AT91C_PMC_LOCKA (0x1u << 1) // (PMC) PLL A Status/Enable/Disable/Mask -#define AT91C_PMC_LOCKB (0x1u << 2) // (PMC) PLL B Status/Enable/Disable/Mask -#define AT91C_PMC_MCKRDY (0x1u << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK0RDY (0x1u << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK1RDY (0x1u << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK2RDY (0x1u << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK3RDY (0x1u << 11) // (PMC) PCK3_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK4RDY (0x1u << 12) // (PMC) PCK4_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK5RDY (0x1u << 13) // (PMC) PCK5_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK6RDY (0x1u << 14) // (PMC) PCK6_RDY Status/Enable/Disable/Mask -#define AT91C_PMC_PCK7RDY (0x1u << 15) // (PMC) PCK7_RDY Status/Enable/Disable/Mask -// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register -------- -// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register -------- -// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Clock Generator Controller -// ***************************************************************************** -typedef struct _AT91S_CKGR { - AT91_REG CKGR_MOR; // Main Oscillator Register - AT91_REG CKGR_MCFR; // Main Clock Frequency Register - AT91_REG CKGR_PLLAR; // PLL A Register - AT91_REG CKGR_PLLBR; // PLL B Register -} AT91S_CKGR, *AT91PS_CKGR; - -// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register -------- -#define AT91C_CKGR_MOSCEN (0x1u << 0) // (CKGR) Main Oscillator Enable -#define AT91C_CKGR_OSCTEST (0x1u << 1) // (CKGR) Oscillator Test -#define AT91C_CKGR_OSCOUNT (0xFFu << 8) // (CKGR) Main Oscillator Start-up Time -// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register -------- -#define AT91C_CKGR_MAINF (0xFFFFu << 0) // (CKGR) Main Clock Frequency -#define AT91C_CKGR_MAINRDY (0x1u << 16) // (CKGR) Main Clock Ready -// -------- CKGR_PLLAR : (CKGR Offset: 0x8) PLL A Register -------- -#define AT91C_CKGR_DIVA (0xFFu << 0) // (CKGR) Divider Selected -#define AT91C_CKGR_DIVA_0 0x0u // (CKGR) Divider output is 0 -#define AT91C_CKGR_DIVA_BYPASS 0x1u // (CKGR) Divider is bypassed -#define AT91C_CKGR_PLLACOUNT (0x3Fu << 8) // (CKGR) PLL A Counter -#define AT91C_CKGR_OUTA (0x3u << 14) // (CKGR) PLL A Output Frequency Range -#define AT91C_CKGR_OUTA_0 (0x0u << 14) // (CKGR) Please refer to the PLLA datasheet -#define AT91C_CKGR_OUTA_1 (0x1u << 14) // (CKGR) Please refer to the PLLA datasheet -#define AT91C_CKGR_OUTA_2 (0x2u << 14) // (CKGR) Please refer to the PLLA datasheet -#define AT91C_CKGR_OUTA_3 (0x3u << 14) // (CKGR) Please refer to the PLLA datasheet -#define AT91C_CKGR_MULA (0x7FFu << 16) // (CKGR) PLL A Multiplier -#define AT91C_CKGR_SRCA (0x1u << 29) // (CKGR) PLL A Source -// -------- CKGR_PLLBR : (CKGR Offset: 0xc) PLL B Register -------- -#define AT91C_CKGR_DIVB (0xFFu << 0) // (CKGR) Divider Selected -#define AT91C_CKGR_DIVB_0 0x0u // (CKGR) Divider output is 0 -#define AT91C_CKGR_DIVB_BYPASS 0x1u // (CKGR) Divider is bypassed -#define AT91C_CKGR_PLLBCOUNT (0x3Fu << 8) // (CKGR) PLL B Counter -#define AT91C_CKGR_OUTB (0x3u << 14) // (CKGR) PLL B Output Frequency Range -#define AT91C_CKGR_OUTB_0 (0x0u << 14) // (CKGR) Please refer to the PLLB datasheet -#define AT91C_CKGR_OUTB_1 (0x1u << 14) // (CKGR) Please refer to the PLLB datasheet -#define AT91C_CKGR_OUTB_2 (0x2u << 14) // (CKGR) Please refer to the PLLB datasheet -#define AT91C_CKGR_OUTB_3 (0x3u << 14) // (CKGR) Please refer to the PLLB datasheet -#define AT91C_CKGR_MULB (0x7FFu << 16) // (CKGR) PLL B Multiplier -#define AT91C_CKGR_USB_96M (0x1u << 28) // (CKGR) Divider for USB Ports -#define AT91C_CKGR_USB_PLL (0x1u << 29) // (CKGR) PLL Use - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Parallel Input Output Controller -// ***************************************************************************** -typedef struct _AT91S_PIO { - AT91_REG PIO_PER; // PIO Enable Register - AT91_REG PIO_PDR; // PIO Disable Register - AT91_REG PIO_PSR; // PIO Status Register - AT91_REG Reserved0[1]; // - AT91_REG PIO_OER; // Output Enable Register - AT91_REG PIO_ODR; // Output Disable Registerr - AT91_REG PIO_OSR; // Output Status Register - AT91_REG Reserved1[1]; // - AT91_REG PIO_IFER; // Input Filter Enable Register - AT91_REG PIO_IFDR; // Input Filter Disable Register - AT91_REG PIO_IFSR; // Input Filter Status Register - AT91_REG Reserved2[1]; // - AT91_REG PIO_SODR; // Set Output Data Register - AT91_REG PIO_CODR; // Clear Output Data Register - AT91_REG PIO_ODSR; // Output Data Status Register - AT91_REG PIO_PDSR; // Pin Data Status Register - AT91_REG PIO_IER; // Interrupt Enable Register - AT91_REG PIO_IDR; // Interrupt Disable Register - AT91_REG PIO_IMR; // Interrupt Mask Register - AT91_REG PIO_ISR; // Interrupt Status Register - AT91_REG PIO_MDER; // Multi-driver Enable Register - AT91_REG PIO_MDDR; // Multi-driver Disable Register - AT91_REG PIO_MDSR; // Multi-driver Status Register - AT91_REG Reserved3[1]; // - AT91_REG PIO_PPUDR; // Pull-up Disable Register - AT91_REG PIO_PPUER; // Pull-up Enable Register - AT91_REG PIO_PPUSR; // Pad Pull-up Status Register - AT91_REG Reserved4[1]; // - AT91_REG PIO_ASR; // Select A Register - AT91_REG PIO_BSR; // Select B Register - AT91_REG PIO_ABSR; // AB Select Status Register - AT91_REG Reserved5[9]; // - AT91_REG PIO_OWER; // Output Write Enable Register - AT91_REG PIO_OWDR; // Output Write Disable Register - AT91_REG PIO_OWSR; // Output Write Status Register -} AT91S_PIO, *AT91PS_PIO; - - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Debug Unit -// ***************************************************************************** -typedef struct _AT91S_DBGU { - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved0[7]; // - AT91_REG DBGU_C1R; // Chip ID1 Register - AT91_REG DBGU_C2R; // Chip ID2 Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved1[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register -} AT91S_DBGU, *AT91PS_DBGU; - -// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register -------- -#define AT91C_US_RSTRX (0x1u << 2) // (DBGU) Reset Receiver -#define AT91C_US_RSTTX (0x1u << 3) // (DBGU) Reset Transmitter -#define AT91C_US_RXEN (0x1u << 4) // (DBGU) Receiver Enable -#define AT91C_US_RXDIS (0x1u << 5) // (DBGU) Receiver Disable -#define AT91C_US_TXEN (0x1u << 6) // (DBGU) Transmitter Enable -#define AT91C_US_TXDIS (0x1u << 7) // (DBGU) Transmitter Disable -// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register -------- -#define AT91C_US_PAR (0x7u << 9) // (DBGU) Parity type -#define AT91C_US_PAR_EVEN (0x0u << 9) // (DBGU) Even Parity -#define AT91C_US_PAR_ODD (0x1u << 9) // (DBGU) Odd Parity -#define AT91C_US_PAR_SPACE (0x2u << 9) // (DBGU) Parity forced to 0 (Space) -#define AT91C_US_PAR_MARK (0x3u << 9) // (DBGU) Parity forced to 1 (Mark) -#define AT91C_US_PAR_NONE (0x4u << 9) // (DBGU) No Parity -#define AT91C_US_PAR_MULTI_DROP (0x6u << 9) // (DBGU) Multi-drop mode -#define AT91C_US_CHMODE (0x3u << 14) // (DBGU) Channel Mode -#define AT91C_US_CHMODE_NORMAL (0x0u << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART. -#define AT91C_US_CHMODE_AUTO (0x1u << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin. -#define AT91C_US_CHMODE_LOCAL (0x2u << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal. -#define AT91C_US_CHMODE_REMOTE (0x3u << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin. -// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register -------- -#define AT91C_US_RXRDY (0x1u << 0) // (DBGU) RXRDY Interrupt -#define AT91C_US_TXRDY (0x1u << 1) // (DBGU) TXRDY Interrupt -#define AT91C_US_ENDRX (0x1u << 3) // (DBGU) End of Receive Transfer Interrupt -#define AT91C_US_ENDTX (0x1u << 4) // (DBGU) End of Transmit Interrupt -#define AT91C_US_OVRE (0x1u << 5) // (DBGU) Overrun Interrupt -#define AT91C_US_FRAME (0x1u << 6) // (DBGU) Framing Error Interrupt -#define AT91C_US_PARE (0x1u << 7) // (DBGU) Parity Error Interrupt -#define AT91C_US_TXEMPTY (0x1u << 9) // (DBGU) TXEMPTY Interrupt -#define AT91C_US_TXBUFE (0x1u << 11) // (DBGU) TXBUFE Interrupt -#define AT91C_US_RXBUFF (0x1u << 12) // (DBGU) RXBUFF Interrupt -#define AT91C_US_COMM_TX (0x1u << 30) // (DBGU) COMM_TX Interrupt -#define AT91C_US_COMM_RX (0x1u << 31) // (DBGU) COMM_RX Interrupt -// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register -------- -// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register -------- -// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register -------- -// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register -------- -#define AT91C_US_FORCE_NTRST (0x1u << 0) // (DBGU) Force NTRST in JTAG - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Peripheral Data Controller -// ***************************************************************************** -typedef struct _AT91S_PDC { - AT91_REG PDC_RPR; // Receive Pointer Register - AT91_REG PDC_RCR; // Receive Counter Register - AT91_REG PDC_TPR; // Transmit Pointer Register - AT91_REG PDC_TCR; // Transmit Counter Register - AT91_REG PDC_RNPR; // Receive Next Pointer Register - AT91_REG PDC_RNCR; // Receive Next Counter Register - AT91_REG PDC_TNPR; // Transmit Next Pointer Register - AT91_REG PDC_TNCR; // Transmit Next Counter Register - AT91_REG PDC_PTCR; // PDC Transfer Control Register - AT91_REG PDC_PTSR; // PDC Transfer Status Register -} AT91S_PDC, *AT91PS_PDC; - -// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register -------- -#define AT91C_PDC_RXTEN (0x1u << 0) // (PDC) Receiver Transfer Enable -#define AT91C_PDC_RXTDIS (0x1u << 1) // (PDC) Receiver Transfer Disable -#define AT91C_PDC_TXTEN (0x1u << 8) // (PDC) Transmitter Transfer Enable -#define AT91C_PDC_TXTDIS (0x1u << 9) // (PDC) Transmitter Transfer Disable -// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller -// ***************************************************************************** -typedef struct _AT91S_AIC { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register -} AT91S_AIC, *AT91PS_AIC; - -// -------- AIC_SMR : (AIC Offset: 0x0) Control Register -------- -#define AT91C_AIC_PRIOR (0x7u << 0) // (AIC) Priority Level -#define AT91C_AIC_PRIOR_LOWEST 0x0u // (AIC) Lowest priority level -#define AT91C_AIC_PRIOR_HIGHEST 0x7u // (AIC) Highest priority level -#define AT91C_AIC_SRCTYPE (0x3u << 5) // (AIC) Interrupt Source Type -#define AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE (0x0u << 5) // (AIC) Internal Sources Code Label Level Sensitive -#define AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED (0x1u << 5) // (AIC) Internal Sources Code Label Edge triggered -#define AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL (0x2u << 5) // (AIC) External Sources Code Label High-level Sensitive -#define AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE (0x3u << 5) // (AIC) External Sources Code Label Positive Edge triggered -// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register -------- -#define AT91C_AIC_NFIQ (0x1u << 0) // (AIC) NFIQ Status -#define AT91C_AIC_NIRQ (0x1u << 1) // (AIC) NIRQ Status -// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) -------- -#define AT91C_AIC_DCR_PROT (0x1u << 0) // (AIC) Protection Mode -#define AT91C_AIC_DCR_GMSK (0x1u << 1) // (AIC) General Mask - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Serial Parallel Interface -// ***************************************************************************** -typedef struct _AT91S_SPI { - AT91_REG SPI_CR; // Control Register - AT91_REG SPI_MR; // Mode Register - AT91_REG SPI_RDR; // Receive Data Register - AT91_REG SPI_TDR; // Transmit Data Register - AT91_REG SPI_SR; // Status Register - AT91_REG SPI_IER; // Interrupt Enable Register - AT91_REG SPI_IDR; // Interrupt Disable Register - AT91_REG SPI_IMR; // Interrupt Mask Register - AT91_REG Reserved0[4]; // - AT91_REG SPI_CSR[4]; // Chip Select Register - AT91_REG Reserved1[48]; // - AT91_REG SPI_RPR; // Receive Pointer Register - AT91_REG SPI_RCR; // Receive Counter Register - AT91_REG SPI_TPR; // Transmit Pointer Register - AT91_REG SPI_TCR; // Transmit Counter Register - AT91_REG SPI_RNPR; // Receive Next Pointer Register - AT91_REG SPI_RNCR; // Receive Next Counter Register - AT91_REG SPI_TNPR; // Transmit Next Pointer Register - AT91_REG SPI_TNCR; // Transmit Next Counter Register - AT91_REG SPI_PTCR; // PDC Transfer Control Register - AT91_REG SPI_PTSR; // PDC Transfer Status Register -} AT91S_SPI, *AT91PS_SPI; - -// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register -------- -#define AT91C_SPI_SPIEN (0x1u << 0) // (SPI) SPI Enable -#define AT91C_SPI_SPIDIS (0x1u << 1) // (SPI) SPI Disable -#define AT91C_SPI_SWRST (0x1u << 7) // (SPI) SPI Software reset -// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register -------- -#define AT91C_SPI_MSTR (0x1u << 0) // (SPI) Master/Slave Mode -#define AT91C_SPI_PS (0x1u << 1) // (SPI) Peripheral Select -#define AT91C_SPI_PS_FIXED (0x0u << 1) // (SPI) Fixed Peripheral Select -#define AT91C_SPI_PS_VARIABLE (0x1u << 1) // (SPI) Variable Peripheral Select -#define AT91C_SPI_PCSDEC (0x1u << 2) // (SPI) Chip Select Decode -#define AT91C_SPI_DIV32 (0x1u << 3) // (SPI) Clock Selection -#define AT91C_SPI_MODFDIS (0x1u << 4) // (SPI) Mode Fault Detection -#define AT91C_SPI_LLB (0x1u << 7) // (SPI) Clock Selection -#define AT91C_SPI_PCS (0xFu << 16) // (SPI) Peripheral Chip Select -#define AT91C_SPI_DLYBCS (0xFFu << 24) // (SPI) Delay Between Chip Selects -// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register -------- -#define AT91C_SPI_RD (0xFFFFu << 0) // (SPI) Receive Data -#define AT91C_SPI_RPCS (0xFu << 16) // (SPI) Peripheral Chip Select Status -// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register -------- -#define AT91C_SPI_TD (0xFFFFu << 0) // (SPI) Transmit Data -#define AT91C_SPI_TPCS (0xFu << 16) // (SPI) Peripheral Chip Select Status -// -------- SPI_SR : (SPI Offset: 0x10) Status Register -------- -#define AT91C_SPI_RDRF (0x1u << 0) // (SPI) Receive Data Register Full -#define AT91C_SPI_TDRE (0x1u << 1) // (SPI) Transmit Data Register Empty -#define AT91C_SPI_MODF (0x1u << 2) // (SPI) Mode Fault Error -#define AT91C_SPI_OVRES (0x1u << 3) // (SPI) Overrun Error Status -#define AT91C_SPI_SPENDRX (0x1u << 4) // (SPI) End of Receiver Transfer -#define AT91C_SPI_SPENDTX (0x1u << 5) // (SPI) End of Receiver Transfer -#define AT91C_SPI_RXBUFF (0x1u << 6) // (SPI) RXBUFF Interrupt -#define AT91C_SPI_TXBUFE (0x1u << 7) // (SPI) TXBUFE Interrupt -#define AT91C_SPI_SPIENS (0x1u << 16) // (SPI) Enable Status -// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register -------- -// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register -------- -// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register -------- -// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register -------- -#define AT91C_SPI_CPOL (0x1u << 0) // (SPI) Clock Polarity -#define AT91C_SPI_NCPHA (0x1u << 1) // (SPI) Clock Phase -#define AT91C_SPI_BITS (0xFu << 4) // (SPI) Bits Per Transfer -#define AT91C_SPI_BITS_8 (0x0u << 4) // (SPI) 8 Bits Per transfer -#define AT91C_SPI_BITS_9 (0x1u << 4) // (SPI) 9 Bits Per transfer -#define AT91C_SPI_BITS_10 (0x2u << 4) // (SPI) 10 Bits Per transfer -#define AT91C_SPI_BITS_11 (0x3u << 4) // (SPI) 11 Bits Per transfer -#define AT91C_SPI_BITS_12 (0x4u << 4) // (SPI) 12 Bits Per transfer -#define AT91C_SPI_BITS_13 (0x5u << 4) // (SPI) 13 Bits Per transfer -#define AT91C_SPI_BITS_14 (0x6u << 4) // (SPI) 14 Bits Per transfer -#define AT91C_SPI_BITS_15 (0x7u << 4) // (SPI) 15 Bits Per transfer -#define AT91C_SPI_BITS_16 (0x8u << 4) // (SPI) 16 Bits Per transfer -#define AT91C_SPI_SCBR (0xFFu << 8) // (SPI) Serial Clock Baud Rate -#define AT91C_SPI_DLYBS (0xFFu << 16) // (SPI) Serial Clock Baud Rate -#define AT91C_SPI_DLYBCT (0xFFu << 24) // (SPI) Delay Between Consecutive Transfers - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface -// ***************************************************************************** -typedef struct _AT91S_SSC { - AT91_REG SSC_CR; // Control Register - AT91_REG SSC_CMR; // Clock Mode Register - AT91_REG Reserved0[2]; // - AT91_REG SSC_RCMR; // Receive Clock ModeRegister - AT91_REG SSC_RFMR; // Receive Frame Mode Register - AT91_REG SSC_TCMR; // Transmit Clock Mode Register - AT91_REG SSC_TFMR; // Transmit Frame Mode Register - AT91_REG SSC_RHR; // Receive Holding Register - AT91_REG SSC_THR; // Transmit Holding Register - AT91_REG Reserved1[2]; // - AT91_REG SSC_RSHR; // Receive Sync Holding Register - AT91_REG SSC_TSHR; // Transmit Sync Holding Register - AT91_REG SSC_RC0R; // Receive Compare 0 Register - AT91_REG SSC_RC1R; // Receive Compare 1 Register - AT91_REG SSC_SR; // Status Register - AT91_REG SSC_IER; // Interrupt Enable Register - AT91_REG SSC_IDR; // Interrupt Disable Register - AT91_REG SSC_IMR; // Interrupt Mask Register - AT91_REG Reserved2[44]; // - AT91_REG SSC_RPR; // Receive Pointer Register - AT91_REG SSC_RCR; // Receive Counter Register - AT91_REG SSC_TPR; // Transmit Pointer Register - AT91_REG SSC_TCR; // Transmit Counter Register - AT91_REG SSC_RNPR; // Receive Next Pointer Register - AT91_REG SSC_RNCR; // Receive Next Counter Register - AT91_REG SSC_TNPR; // Transmit Next Pointer Register - AT91_REG SSC_TNCR; // Transmit Next Counter Register - AT91_REG SSC_PTCR; // PDC Transfer Control Register - AT91_REG SSC_PTSR; // PDC Transfer Status Register -} AT91S_SSC, *AT91PS_SSC; - -// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register -------- -#define AT91C_SSC_RXEN (0x1u << 0) // (SSC) Receive Enable -#define AT91C_SSC_RXDIS (0x1u << 1) // (SSC) Receive Disable -#define AT91C_SSC_TXEN (0x1u << 8) // (SSC) Transmit Enable -#define AT91C_SSC_TXDIS (0x1u << 9) // (SSC) Transmit Disable -#define AT91C_SSC_SWRST (0x1u << 15) // (SSC) Software Reset -// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register -------- -#define AT91C_SSC_CKS (0x3u << 0) // (SSC) Receive/Transmit Clock Selection -#define AT91C_SSC_CKS_DIV 0x0u // (SSC) Divided Clock -#define AT91C_SSC_CKS_TK 0x1u // (SSC) TK Clock signal -#define AT91C_SSC_CKS_RK 0x2u // (SSC) RK pin -#define AT91C_SSC_CKO (0x7u << 2) // (SSC) Receive/Transmit Clock Output Mode Selection -#define AT91C_SSC_CKO_NONE (0x0u << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only -#define AT91C_SSC_CKO_CONTINOUS (0x1u << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output -#define AT91C_SSC_CKO_DATA_TX (0x2u << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output -#define AT91C_SSC_CKI (0x1u << 5) // (SSC) Receive/Transmit Clock Inversion -#define AT91C_SSC_CKG (0x3u << 6) // (SSC) Receive/Transmit Clock Gating Selection -#define AT91C_SSC_CKG_NONE (0x0u << 6) // (SSC) Receive/Transmit Clock Gating: None, continuous clock -#define AT91C_SSC_CKG_LOW (0x1u << 6) // (SSC) Receive/Transmit Clock enabled only if RF Low -#define AT91C_SSC_CKG_HIGH (0x2u << 6) // (SSC) Receive/Transmit Clock enabled only if RF High -#define AT91C_SSC_START (0xFu << 8) // (SSC) Receive/Transmit Start Selection -#define AT91C_SSC_START_CONTINOUS (0x0u << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data. -#define AT91C_SSC_START_TX (0x1u << 8) // (SSC) Transmit/Receive start -#define AT91C_SSC_START_LOW_RF (0x2u << 8) // (SSC) Detection of a low level on RF input -#define AT91C_SSC_START_HIGH_RF (0x3u << 8) // (SSC) Detection of a high level on RF input -#define AT91C_SSC_START_FALL_RF (0x4u << 8) // (SSC) Detection of a falling edge on RF input -#define AT91C_SSC_START_RISE_RF (0x5u << 8) // (SSC) Detection of a rising edge on RF input -#define AT91C_SSC_START_LEVEL_RF (0x6u << 8) // (SSC) Detection of any level change on RF input -#define AT91C_SSC_START_EDGE_RF (0x7u << 8) // (SSC) Detection of any edge on RF input -#define AT91C_SSC_START_0 (0x8u << 8) // (SSC) Compare 0 -#define AT91C_SSC_STOP (0x1u << 12) // (SSC) Receive Stop Selection -#define AT91C_SSC_STTOUT (0x1u << 15) // (SSC) Receive/Transmit Start Output Selection -#define AT91C_SSC_STTDLY (0xFFu << 16) // (SSC) Receive/Transmit Start Delay -#define AT91C_SSC_PERIOD (0xFFu << 24) // (SSC) Receive/Transmit Period Divider Selection -// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register -------- -#define AT91C_SSC_DATLEN (0x1Fu << 0) // (SSC) Data Length -#define AT91C_SSC_LOOP (0x1u << 5) // (SSC) Loop Mode -#define AT91C_SSC_MSBF (0x1u << 7) // (SSC) Most Significant Bit First -#define AT91C_SSC_DATNB (0xFu << 8) // (SSC) Data Number per Frame -#define AT91C_SSC_FSLEN (0xFu << 16) // (SSC) Receive/Transmit Frame Sync length -#define AT91C_SSC_FSOS (0x7u << 20) // (SSC) Receive/Transmit Frame Sync Output Selection -#define AT91C_SSC_FSOS_NONE (0x0u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only -#define AT91C_SSC_FSOS_NEGATIVE (0x1u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse -#define AT91C_SSC_FSOS_POSITIVE (0x2u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse -#define AT91C_SSC_FSOS_LOW (0x3u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer -#define AT91C_SSC_FSOS_HIGH (0x4u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer -#define AT91C_SSC_FSOS_TOGGLE (0x5u << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer -#define AT91C_SSC_FSEDGE (0x1u << 24) // (SSC) Frame Sync Edge Detection -// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register -------- -// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register -------- -#define AT91C_SSC_DATDEF (0x1u << 5) // (SSC) Data Default Value -#define AT91C_SSC_FSDEN (0x1u << 23) // (SSC) Frame Sync Data Enable -// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register -------- -#define AT91C_SSC_TXRDY (0x1u << 0) // (SSC) Transmit Ready -#define AT91C_SSC_TXEMPTY (0x1u << 1) // (SSC) Transmit Empty -#define AT91C_SSC_ENDTX (0x1u << 2) // (SSC) End Of Transmission -#define AT91C_SSC_TXBUFE (0x1u << 3) // (SSC) Transmit Buffer Empty -#define AT91C_SSC_RXRDY (0x1u << 4) // (SSC) Receive Ready -#define AT91C_SSC_OVRUN (0x1u << 5) // (SSC) Receive Overrun -#define AT91C_SSC_ENDRX (0x1u << 6) // (SSC) End of Reception -#define AT91C_SSC_RXBUFF (0x1u << 7) // (SSC) Receive Buffer Full -#define AT91C_SSC_CP0 (0x1u << 8) // (SSC) Compare 0 -#define AT91C_SSC_CP1 (0x1u << 9) // (SSC) Compare 1 -#define AT91C_SSC_TXSYN (0x1u << 10) // (SSC) Transmit Sync -#define AT91C_SSC_RXSYN (0x1u << 11) // (SSC) Receive Sync -#define AT91C_SSC_TXENA (0x1u << 16) // (SSC) Transmit Enable -#define AT91C_SSC_RXENA (0x1u << 17) // (SSC) Receive Enable -// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register -------- -// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register -------- -// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Usart -// ***************************************************************************** -typedef struct _AT91S_USART { - AT91_REG US_CR; // Control Register - AT91_REG US_MR; // Mode Register - AT91_REG US_IER; // Interrupt Enable Register - AT91_REG US_IDR; // Interrupt Disable Register - AT91_REG US_IMR; // Interrupt Mask Register - AT91_REG US_CSR; // Channel Status Register - AT91_REG US_RHR; // Receiver Holding Register - AT91_REG US_THR; // Transmitter Holding Register - AT91_REG US_BRGR; // Baud Rate Generator Register - AT91_REG US_RTOR; // Receiver Time-out Register - AT91_REG US_TTGR; // Transmitter Time-guard Register - AT91_REG Reserved0[5]; // - AT91_REG US_FIDI; // FI_DI_Ratio Register - AT91_REG US_NER; // Nb Errors Register - AT91_REG US_XXR; // XON_XOFF Register - AT91_REG US_IF; // IRDA_FILTER Register - AT91_REG Reserved1[44]; // - AT91_REG US_RPR; // Receive Pointer Register - AT91_REG US_RCR; // Receive Counter Register - AT91_REG US_TPR; // Transmit Pointer Register - AT91_REG US_TCR; // Transmit Counter Register - AT91_REG US_RNPR; // Receive Next Pointer Register - AT91_REG US_RNCR; // Receive Next Counter Register - AT91_REG US_TNPR; // Transmit Next Pointer Register - AT91_REG US_TNCR; // Transmit Next Counter Register - AT91_REG US_PTCR; // PDC Transfer Control Register - AT91_REG US_PTSR; // PDC Transfer Status Register -} AT91S_USART, *AT91PS_USART; - -// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register -------- -#define AT91C_US_RSTSTA (0x1u << 8) // (USART) Reset Status Bits -#define AT91C_US_STTBRK (0x1u << 9) // (USART) Start Break -#define AT91C_US_STPBRK (0x1u << 10) // (USART) Stop Break -#define AT91C_US_STTTO (0x1u << 11) // (USART) Start Time-out -#define AT91C_US_SENDA (0x1u << 12) // (USART) Send Address -#define AT91C_US_RSTIT (0x1u << 13) // (USART) Reset Iterations -#define AT91C_US_RSTNACK (0x1u << 14) // (USART) Reset Non Acknowledge -#define AT91C_US_RETTO (0x1u << 15) // (USART) Rearm Time-out -#define AT91C_US_DTREN (0x1u << 16) // (USART) Data Terminal ready Enable -#define AT91C_US_DTRDIS (0x1u << 17) // (USART) Data Terminal ready Disable -#define AT91C_US_RTSEN (0x1u << 18) // (USART) Request to Send enable -#define AT91C_US_RTSDIS (0x1u << 19) // (USART) Request to Send Disable -// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register -------- -#define AT91C_US_USMODE (0xFu << 0) // (USART) Usart mode -#define AT91C_US_USMODE_NORMAL 0x0u // (USART) Normal -#define AT91C_US_USMODE_RS485 0x1u // (USART) RS485 -#define AT91C_US_USMODE_HWHSH 0x2u // (USART) Hardware Handshaking -#define AT91C_US_USMODE_MODEM 0x3u // (USART) Modem -#define AT91C_US_USMODE_ISO7816_0 0x4u // (USART) ISO7816 protocol: T = 0 -#define AT91C_US_USMODE_ISO7816_1 0x6u // (USART) ISO7816 protocol: T = 1 -#define AT91C_US_USMODE_IRDA 0x8u // (USART) IrDA -#define AT91C_US_USMODE_SWHSH 0xCu // (USART) Software Handshaking -#define AT91C_US_CLKS (0x3u << 4) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CLKS_CLOCK (0x0u << 4) // (USART) Clock -#define AT91C_US_CLKS_FDIV1 (0x1u << 4) // (USART) fdiv1 -#define AT91C_US_CLKS_SLOW (0x2u << 4) // (USART) slow_clock (ARM) -#define AT91C_US_CLKS_EXT (0x3u << 4) // (USART) External (SCK) -#define AT91C_US_CHRL (0x3u << 6) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CHRL_5_BITS (0x0u << 6) // (USART) Character Length: 5 bits -#define AT91C_US_CHRL_6_BITS (0x1u << 6) // (USART) Character Length: 6 bits -#define AT91C_US_CHRL_7_BITS (0x2u << 6) // (USART) Character Length: 7 bits -#define AT91C_US_CHRL_8_BITS (0x3u << 6) // (USART) Character Length: 8 bits -#define AT91C_US_SYNC (0x1u << 8) // (USART) Synchronous Mode Select -#define AT91C_US_NBSTOP (0x3u << 12) // (USART) Number of Stop bits -#define AT91C_US_NBSTOP_1_BIT (0x0u << 12) // (USART) 1 stop bit -#define AT91C_US_NBSTOP_15_BIT (0x1u << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits -#define AT91C_US_NBSTOP_2_BIT (0x2u << 12) // (USART) 2 stop bits -#define AT91C_US_MSBF (0x1u << 16) // (USART) Bit Order -#define AT91C_US_MODE9 (0x1u << 17) // (USART) 9-bit Character length -#define AT91C_US_CKLO (0x1u << 18) // (USART) Clock Output Select -#define AT91C_US_OVER (0x1u << 19) // (USART) Over Sampling Mode -#define AT91C_US_INACK (0x1u << 20) // (USART) Inhibit Non Acknowledge -#define AT91C_US_DSNACK (0x1u << 21) // (USART) Disable Successive NACK -#define AT91C_US_MAX_ITER (0x1u << 24) // (USART) Number of Repetitions -#define AT91C_US_FILTER (0x1u << 28) // (USART) Receive Line Filter -// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register -------- -#define AT91C_US_RXBRK (0x1u << 2) // (USART) Break Received/End of Break -#define AT91C_US_TIMEOUT (0x1u << 8) // (USART) Receiver Time-out -#define AT91C_US_ITERATION (0x1u << 10) // (USART) Max number of Repetitions Reached -#define AT91C_US_NACK (0x1u << 13) // (USART) Non Acknowledge -#define AT91C_US_RIIC (0x1u << 16) // (USART) Ring INdicator Input Change Flag -#define AT91C_US_DSRIC (0x1u << 17) // (USART) Data Set Ready Input Change Flag -#define AT91C_US_DCDIC (0x1u << 18) // (USART) Data Carrier Flag -#define AT91C_US_CTSIC (0x1u << 19) // (USART) Clear To Send Input Change Flag -// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register -------- -// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register -------- -// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register -------- -#define AT91C_US_RI (0x1u << 20) // (USART) Image of RI Input -#define AT91C_US_DSR (0x1u << 21) // (USART) Image of DSR Input -#define AT91C_US_DCD (0x1u << 22) // (USART) Image of DCD Input -#define AT91C_US_CTS (0x1u << 23) // (USART) Image of CTS Input - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Two-wire Interface -// ***************************************************************************** -typedef struct _AT91S_TWI { - AT91_REG TWI_CR; // Control Register - AT91_REG TWI_MMR; // Master Mode Register - AT91_REG TWI_SMR; // Slave Mode Register - AT91_REG TWI_IADR; // Internal Address Register - AT91_REG TWI_CWGR; // Clock Waveform Generator Register - AT91_REG Reserved0[3]; // - AT91_REG TWI_SR; // Status Register - AT91_REG TWI_IER; // Interrupt Enable Register - AT91_REG TWI_IDR; // Interrupt Disable Register - AT91_REG TWI_IMR; // Interrupt Mask Register - AT91_REG TWI_RHR; // Receive Holding Register - AT91_REG TWI_THR; // Transmit Holding Register -} AT91S_TWI, *AT91PS_TWI; - -// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register -------- -#define AT91C_TWI_START (0x1u << 0) // (TWI) Send a START Condition -#define AT91C_TWI_STOP (0x1u << 1) // (TWI) Send a STOP Condition -#define AT91C_TWI_MSEN (0x1u << 2) // (TWI) TWI Master Transfer Enabled -#define AT91C_TWI_MSDIS (0x1u << 3) // (TWI) TWI Master Transfer Disabled -#define AT91C_TWI_SVEN (0x1u << 4) // (TWI) TWI Slave Transfer Enabled -#define AT91C_TWI_SVDIS (0x1u << 5) // (TWI) TWI Slave Transfer Disabled -#define AT91C_TWI_SWRST (0x1u << 7) // (TWI) Software Reset -// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register -------- -#define AT91C_TWI_IADRSZ (0x3u << 8) // (TWI) Internal Device Address Size -#define AT91C_TWI_IADRSZ_NO (0x0u << 8) // (TWI) No internal device address -#define AT91C_TWI_IADRSZ_1_BYTE (0x1u << 8) // (TWI) One-byte internal device address -#define AT91C_TWI_IADRSZ_2_BYTE (0x2u << 8) // (TWI) Two-byte internal device address -#define AT91C_TWI_IADRSZ_3_BYTE (0x3u << 8) // (TWI) Three-byte internal device address -#define AT91C_TWI_MREAD (0x1u << 12) // (TWI) Master Read Direction -#define AT91C_TWI_DADR (0x7Fu << 16) // (TWI) Device Address -// -------- TWI_SMR : (TWI Offset: 0x8) TWI Slave Mode Register -------- -#define AT91C_TWI_SADR (0x7Fu << 16) // (TWI) Slave Device Address -// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register -------- -#define AT91C_TWI_CLDIV (0xFFu << 0) // (TWI) Clock Low Divider -#define AT91C_TWI_CHDIV (0xFFu << 8) // (TWI) Clock High Divider -#define AT91C_TWI_CKDIV (0x7u << 16) // (TWI) Clock Divider -// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register -------- -#define AT91C_TWI_TXCOMP (0x1u << 0) // (TWI) Transmission Completed -#define AT91C_TWI_RXRDY (0x1u << 1) // (TWI) Receive holding register ReaDY -#define AT91C_TWI_TXRDY (0x1u << 2) // (TWI) Transmit holding register ReaDY -#define AT91C_TWI_SVREAD (0x1u << 3) // (TWI) Slave Read -#define AT91C_TWI_SVACC (0x1u << 4) // (TWI) Slave Access -#define AT91C_TWI_GCACC (0x1u << 5) // (TWI) General Call Access -#define AT91C_TWI_OVRE (0x1u << 6) // (TWI) Overrun Error -#define AT91C_TWI_UNRE (0x1u << 7) // (TWI) Underrun Error -#define AT91C_TWI_NACK (0x1u << 8) // (TWI) Not Acknowledged -#define AT91C_TWI_ARBLST (0x1u << 9) // (TWI) Arbitration Lost -// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register -------- -// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register -------- -// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Multimedia Card Interface -// ***************************************************************************** -typedef struct _AT91S_MCI { - AT91_REG MCI_CR; // MCI Control Register - AT91_REG MCI_MR; // MCI Mode Register - AT91_REG MCI_DTOR; // MCI Data Timeout Register - AT91_REG MCI_SDCR; // MCI SD Card Register - AT91_REG MCI_ARGR; // MCI Argument Register - AT91_REG MCI_CMDR; // MCI Command Register - AT91_REG Reserved0[2]; // - AT91_REG MCI_RSPR[4]; // MCI Response Register - AT91_REG MCI_RDR; // MCI Receive Data Register - AT91_REG MCI_TDR; // MCI Transmit Data Register - AT91_REG Reserved1[2]; // - AT91_REG MCI_SR; // MCI Status Register - AT91_REG MCI_IER; // MCI Interrupt Enable Register - AT91_REG MCI_IDR; // MCI Interrupt Disable Register - AT91_REG MCI_IMR; // MCI Interrupt Mask Register - AT91_REG Reserved2[44]; // - AT91_REG MCI_RPR; // Receive Pointer Register - AT91_REG MCI_RCR; // Receive Counter Register - AT91_REG MCI_TPR; // Transmit Pointer Register - AT91_REG MCI_TCR; // Transmit Counter Register - AT91_REG MCI_RNPR; // Receive Next Pointer Register - AT91_REG MCI_RNCR; // Receive Next Counter Register - AT91_REG MCI_TNPR; // Transmit Next Pointer Register - AT91_REG MCI_TNCR; // Transmit Next Counter Register - AT91_REG MCI_PTCR; // PDC Transfer Control Register - AT91_REG MCI_PTSR; // PDC Transfer Status Register -} AT91S_MCI, *AT91PS_MCI; - -// -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register -------- -#define AT91C_MCI_MCIEN (0x1u << 0) // (MCI) Multimedia Interface Enable -#define AT91C_MCI_MCIDIS (0x1u << 1) // (MCI) Multimedia Interface Disable -#define AT91C_MCI_PWSEN (0x1u << 2) // (MCI) Power Save Mode Enable -#define AT91C_MCI_PWSDIS (0x1u << 3) // (MCI) Power Save Mode Disable -// -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register -------- -#define AT91C_MCI_CLKDIV (0x1u << 0) // (MCI) Clock Divider -#define AT91C_MCI_PWSDIV (0x1u << 8) // (MCI) Power Saving Divider -#define AT91C_MCI_PDCPADV (0x1u << 14) // (MCI) PDC Padding Value -#define AT91C_MCI_PDCMODE (0x1u << 15) // (MCI) PDC Oriented Mode -#define AT91C_MCI_BLKLEN (0x1u << 18) // (MCI) Data Block Length -// -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- -#define AT91C_MCI_DTOCYC (0x1u << 0) // (MCI) Data Timeout Cycle Number -#define AT91C_MCI_DTOMUL (0x7u << 4) // (MCI) Data Timeout Multiplier -#define AT91C_MCI_DTOMUL_1 (0x0u << 4) // (MCI) DTOCYC x 1 -#define AT91C_MCI_DTOMUL_16 (0x1u << 4) // (MCI) DTOCYC x 16 -#define AT91C_MCI_DTOMUL_128 (0x2u << 4) // (MCI) DTOCYC x 128 -#define AT91C_MCI_DTOMUL_256 (0x3u << 4) // (MCI) DTOCYC x 256 -#define AT91C_MCI_DTOMUL_1024 (0x4u << 4) // (MCI) DTOCYC x 1024 -#define AT91C_MCI_DTOMUL_4096 (0x5u << 4) // (MCI) DTOCYC x 4096 -#define AT91C_MCI_DTOMUL_65536 (0x6u << 4) // (MCI) DTOCYC x 65536 -#define AT91C_MCI_DTOMUL_1048576 (0x7u << 4) // (MCI) DTOCYC x 1048576 -// -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register -------- -#define AT91C_MCI_SCDSEL (0x1u << 0) // (MCI) SD Card Selector -#define AT91C_MCI_SCDBUS (0x1u << 7) // (MCI) SD Card Bus Width -// -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register -------- -// -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- -#define AT91C_MCI_CMDRDY (0x1u << 0) // (MCI) Command Ready flag -#define AT91C_MCI_RXRDY (0x1u << 1) // (MCI) RX Ready flag -#define AT91C_MCI_TXRDY (0x1u << 2) // (MCI) TX Ready flag -#define AT91C_MCI_BLKE (0x1u << 3) // (MCI) Data Block Transfer Ended flag -#define AT91C_MCI_DTIP (0x1u << 4) // (MCI) Data Transfer in Progress flag -#define AT91C_MCI_NOTBUSY (0x1u << 5) // (MCI) Data Line Not Busy flag -#define AT91C_MCI_ENDRX (0x1u << 6) // (MCI) End of RX Buffer flag -#define AT91C_MCI_ENDTX (0x1u << 7) // (MCI) End of TX Buffer flag -#define AT91C_MCI_RXBUFF (0x1u << 14) // (MCI) RX Buffer Full flag -#define AT91C_MCI_TXBUFE (0x1u << 15) // (MCI) TX Buffer Empty flag -#define AT91C_MCI_RINDE (0x1u << 16) // (MCI) Response Index Error flag -#define AT91C_MCI_RDIRE (0x1u << 17) // (MCI) Response Direction Error flag -#define AT91C_MCI_RCRCE (0x1u << 18) // (MCI) Response CRC Error flag -#define AT91C_MCI_RENDE (0x1u << 19) // (MCI) Response End Bit Error flag -#define AT91C_MCI_RTOE (0x1u << 20) // (MCI) Response Time-out Error flag -#define AT91C_MCI_DCRCE (0x1u << 21) // (MCI) data CRC Error flag -#define AT91C_MCI_DTOE (0x1u << 22) // (MCI) Data timeout Error flag -#define AT91C_MCI_OVRE (0x1u << 30) // (MCI) Overrun flag -#define AT91C_MCI_UNRE (0x1u << 31) // (MCI) Underrun flag -// -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register -------- -// -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register -------- -// -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR USB Device Interface -// ***************************************************************************** -typedef struct _AT91S_UDP { - AT91_REG UDP_NUM; // Frame Number Register - AT91_REG UDP_GLBSTATE; // Global State Register - AT91_REG UDP_FADDR; // Function Address Register - AT91_REG Reserved0[1]; // - AT91_REG UDP_IER; // Interrupt Enable Register - AT91_REG UDP_IDR; // Interrupt Disable Register - AT91_REG UDP_IMR; // Interrupt Mask Register - AT91_REG UDP_ISR; // Interrupt Status Register - AT91_REG UDP_ICR; // Interrupt Clear Register - AT91_REG Reserved1[1]; // - AT91_REG UDP_RSTEP; // Reset Endpoint Register - AT91_REG Reserved2[1]; // - AT91_REG UDP_CSR[8]; // Endpoint Control and Status Register - AT91_REG UDP_FDR[8]; // Endpoint FIFO Data Register -} AT91S_UDP, *AT91PS_UDP; - -// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register -------- -#define AT91C_UDP_FRM_NUM (0x7FFu << 0) // (UDP) Frame Number as Defined in the Packet Field Formats -#define AT91C_UDP_FRM_ERR (0x1u << 16) // (UDP) Frame Error -#define AT91C_UDP_FRM_OK (0x1u << 17) // (UDP) Frame OK -// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register -------- -#define AT91C_UDP_FADDEN (0x1u << 0) // (UDP) Function Address Enable -#define AT91C_UDP_CONFG (0x1u << 1) // (UDP) Configured -#define AT91C_UDP_RMWUPE (0x1u << 2) // (UDP) Remote Wake Up Enable -#define AT91C_UDP_RSMINPR (0x1u << 3) // (UDP) A Resume Has Been Sent to the Host -// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register -------- -#define AT91C_UDP_FADD (0xFFu << 0) // (UDP) Function Address Value -#define AT91C_UDP_FEN (0x1u << 8) // (UDP) Function Enable -// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register -------- -#define AT91C_UDP_EPINT0 (0x1u << 0) // (UDP) Endpoint 0 Interrupt -#define AT91C_UDP_EPINT1 (0x1u << 1) // (UDP) Endpoint 0 Interrupt -#define AT91C_UDP_EPINT2 (0x1u << 2) // (UDP) Endpoint 2 Interrupt -#define AT91C_UDP_EPINT3 (0x1u << 3) // (UDP) Endpoint 3 Interrupt -#define AT91C_UDP_EPINT4 (0x1u << 4) // (UDP) Endpoint 4 Interrupt -#define AT91C_UDP_EPINT5 (0x1u << 5) // (UDP) Endpoint 5 Interrupt -#define AT91C_UDP_EPINT6 (0x1u << 6) // (UDP) Endpoint 6 Interrupt -#define AT91C_UDP_EPINT7 (0x1u << 7) // (UDP) Endpoint 7 Interrupt -#define AT91C_UDP_RXSUSP (0x1u << 8) // (UDP) USB Suspend Interrupt -#define AT91C_UDP_RXRSM (0x1u << 9) // (UDP) USB Resume Interrupt -#define AT91C_UDP_EXTRSM (0x1u << 10) // (UDP) USB External Resume Interrupt -#define AT91C_UDP_SOFINT (0x1u << 11) // (UDP) USB Start Of frame Interrupt -#define AT91C_UDP_WAKEUP (0x1u << 13) // (UDP) USB Resume Interrupt -// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register -------- -// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register -------- -// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register -------- -#define AT91C_UDP_ENDBUSRES (0x1u << 12) // (UDP) USB End Of Bus Reset Interrupt -// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register -------- -// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register -------- -#define AT91C_UDP_EP0 (0x1u << 0) // (UDP) Reset Endpoint 0 -#define AT91C_UDP_EP1 (0x1u << 1) // (UDP) Reset Endpoint 1 -#define AT91C_UDP_EP2 (0x1u << 2) // (UDP) Reset Endpoint 2 -#define AT91C_UDP_EP3 (0x1u << 3) // (UDP) Reset Endpoint 3 -#define AT91C_UDP_EP4 (0x1u << 4) // (UDP) Reset Endpoint 4 -#define AT91C_UDP_EP5 (0x1u << 5) // (UDP) Reset Endpoint 5 -#define AT91C_UDP_EP6 (0x1u << 6) // (UDP) Reset Endpoint 6 -#define AT91C_UDP_EP7 (0x1u << 7) // (UDP) Reset Endpoint 7 -// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register -------- -#define AT91C_UDP_TXCOMP (0x1u << 0) // (UDP) Generates an IN packet with data previously written in the DPR -#define AT91C_UDP_RX_DATA_BK0 (0x1u << 1) // (UDP) Receive Data Bank 0 -#define AT91C_UDP_RXSETUP (0x1u << 2) // (UDP) Sends STALL to the Host (Control endpoints) -#define AT91C_UDP_ISOERROR (0x1u << 3) // (UDP) Isochronous error (Isochronous endpoints) -#define AT91C_UDP_TXPKTRDY (0x1u << 4) // (UDP) Transmit Packet Ready -#define AT91C_UDP_FORCESTALL (0x1u << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints). -#define AT91C_UDP_RX_DATA_BK1 (0x1u << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes). -#define AT91C_UDP_DIR (0x1u << 7) // (UDP) Transfer Direction -#define AT91C_UDP_EPTYPE (0x7u << 8) // (UDP) Endpoint type -#define AT91C_UDP_EPTYPE_CTRL (0x0u << 8) // (UDP) Control -#define AT91C_UDP_EPTYPE_ISO_OUT (0x1u << 8) // (UDP) Isochronous OUT -#define AT91C_UDP_EPTYPE_BULK_OUT (0x2u << 8) // (UDP) Bulk OUT -#define AT91C_UDP_EPTYPE_INT_OUT (0x3u << 8) // (UDP) Interrupt OUT -#define AT91C_UDP_EPTYPE_ISO_IN (0x5u << 8) // (UDP) Isochronous IN -#define AT91C_UDP_EPTYPE_BULK_IN (0x6u << 8) // (UDP) Bulk IN -#define AT91C_UDP_EPTYPE_INT_IN (0x7u << 8) // (UDP) Interrupt IN -#define AT91C_UDP_DTGLE (0x1u << 11) // (UDP) Data Toggle -#define AT91C_UDP_EPEDS (0x1u << 15) // (UDP) Endpoint Enable Disable -#define AT91C_UDP_RXBYTECNT (0x7FFu << 16) // (UDP) Number Of Bytes Available in the FIFO - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface -// ***************************************************************************** -typedef struct _AT91S_TC { - AT91_REG TC_CCR; // Channel Control Register - AT91_REG TC_CMR; // Channel Mode Register - AT91_REG Reserved0[2]; // - AT91_REG TC_CV; // Counter Value - AT91_REG TC_RA; // Register A - AT91_REG TC_RB; // Register B - AT91_REG TC_RC; // Register C - AT91_REG TC_SR; // Status Register - AT91_REG TC_IER; // Interrupt Enable Register - AT91_REG TC_IDR; // Interrupt Disable Register - AT91_REG TC_IMR; // Interrupt Mask Register -} AT91S_TC, *AT91PS_TC; - -// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register -------- -#define AT91C_TC_CLKEN (0x1u << 0) // (TC) Counter Clock Enable Command -#define AT91C_TC_CLKDIS (0x1u << 1) // (TC) Counter Clock Disable Command -#define AT91C_TC_SWTRG (0x1u << 2) // (TC) Software Trigger Command -// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode -------- -#define AT91C_TC_CPCSTOP (0x1u << 6) // (TC) Counter Clock Stopped with RC Compare -#define AT91C_TC_CPCDIS (0x1u << 7) // (TC) Counter Clock Disable with RC Compare -#define AT91C_TC_EEVTEDG (0x3u << 8) // (TC) External Event Edge Selection -#define AT91C_TC_EEVTEDG_NONE (0x0u << 8) // (TC) Edge: None -#define AT91C_TC_EEVTEDG_RISING (0x1u << 8) // (TC) Edge: rising edge -#define AT91C_TC_EEVTEDG_FALLING (0x2u << 8) // (TC) Edge: falling edge -#define AT91C_TC_EEVTEDG_BOTH (0x3u << 8) // (TC) Edge: each edge -#define AT91C_TC_EEVT (0x3u << 10) // (TC) External Event Selection -#define AT91C_TC_EEVT_NONE (0x0u << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input -#define AT91C_TC_EEVT_RISING (0x1u << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output -#define AT91C_TC_EEVT_FALLING (0x2u << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output -#define AT91C_TC_EEVT_BOTH (0x3u << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output -#define AT91C_TC_ENETRG (0x1u << 12) // (TC) External Event Trigger enable -#define AT91C_TC_WAVESEL (0x3u << 13) // (TC) Waveform Selection -#define AT91C_TC_WAVESEL_UP (0x0u << 13) // (TC) UP mode without atomatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UP_AUTO (0x1u << 13) // (TC) UP mode with automatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UPDOWN (0x2u << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare -#define AT91C_TC_WAVESEL_UPDOWN_AUTO (0x3u << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare -#define AT91C_TC_CPCTRG (0x1u << 14) // (TC) RC Compare Trigger Enable -#define AT91C_TC_WAVE (0x1u << 15) // (TC) -#define AT91C_TC_ACPA (0x3u << 16) // (TC) RA Compare Effect on TIOA -#define AT91C_TC_ACPA_NONE (0x0u << 16) // (TC) Effect: none -#define AT91C_TC_ACPA_SET (0x1u << 16) // (TC) Effect: set -#define AT91C_TC_ACPA_CLEAR (0x2u << 16) // (TC) Effect: clear -#define AT91C_TC_ACPA_TOGGLE (0x3u << 16) // (TC) Effect: toggle -#define AT91C_TC_ACPC (0x3u << 18) // (TC) RC Compare Effect on TIOA -#define AT91C_TC_ACPC_NONE (0x0u << 18) // (TC) Effect: none -#define AT91C_TC_ACPC_SET (0x1u << 18) // (TC) Effect: set -#define AT91C_TC_ACPC_CLEAR (0x2u << 18) // (TC) Effect: clear -#define AT91C_TC_ACPC_TOGGLE (0x3u << 18) // (TC) Effect: toggle -#define AT91C_TC_AEEVT (0x3u << 20) // (TC) External Event Effect on TIOA -#define AT91C_TC_AEEVT_NONE (0x0u << 20) // (TC) Effect: none -#define AT91C_TC_AEEVT_SET (0x1u << 20) // (TC) Effect: set -#define AT91C_TC_AEEVT_CLEAR (0x2u << 20) // (TC) Effect: clear -#define AT91C_TC_AEEVT_TOGGLE (0x3u << 20) // (TC) Effect: toggle -#define AT91C_TC_ASWTRG (0x3u << 22) // (TC) Software Trigger Effect on TIOA -#define AT91C_TC_ASWTRG_NONE (0x0u << 22) // (TC) Effect: none -#define AT91C_TC_ASWTRG_SET (0x1u << 22) // (TC) Effect: set -#define AT91C_TC_ASWTRG_CLEAR (0x2u << 22) // (TC) Effect: clear -#define AT91C_TC_ASWTRG_TOGGLE (0x3u << 22) // (TC) Effect: toggle -#define AT91C_TC_BCPB (0x3u << 24) // (TC) RB Compare Effect on TIOB -#define AT91C_TC_BCPB_NONE (0x0u << 24) // (TC) Effect: none -#define AT91C_TC_BCPB_SET (0x1u << 24) // (TC) Effect: set -#define AT91C_TC_BCPB_CLEAR (0x2u << 24) // (TC) Effect: clear -#define AT91C_TC_BCPB_TOGGLE (0x3u << 24) // (TC) Effect: toggle -#define AT91C_TC_BCPC (0x3u << 26) // (TC) RC Compare Effect on TIOB -#define AT91C_TC_BCPC_NONE (0x0u << 26) // (TC) Effect: none -#define AT91C_TC_BCPC_SET (0x1u << 26) // (TC) Effect: set -#define AT91C_TC_BCPC_CLEAR (0x2u << 26) // (TC) Effect: clear -#define AT91C_TC_BCPC_TOGGLE (0x3u << 26) // (TC) Effect: toggle -#define AT91C_TC_BEEVT (0x3u << 28) // (TC) External Event Effect on TIOB -#define AT91C_TC_BEEVT_NONE (0x0u << 28) // (TC) Effect: none -#define AT91C_TC_BEEVT_SET (0x1u << 28) // (TC) Effect: set -#define AT91C_TC_BEEVT_CLEAR (0x2u << 28) // (TC) Effect: clear -#define AT91C_TC_BEEVT_TOGGLE (0x3u << 28) // (TC) Effect: toggle -#define AT91C_TC_BSWTRG (0x3u << 30) // (TC) Software Trigger Effect on TIOB -#define AT91C_TC_BSWTRG_NONE (0x0u << 30) // (TC) Effect: none -#define AT91C_TC_BSWTRG_SET (0x1u << 30) // (TC) Effect: set -#define AT91C_TC_BSWTRG_CLEAR (0x2u << 30) // (TC) Effect: clear -#define AT91C_TC_BSWTRG_TOGGLE (0x3u << 30) // (TC) Effect: toggle -// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register -------- -#define AT91C_TC_COVFS (0x1u << 0) // (TC) Counter Overflow -#define AT91C_TC_LOVRS (0x1u << 1) // (TC) Load Overrun -#define AT91C_TC_CPAS (0x1u << 2) // (TC) RA Compare -#define AT91C_TC_CPBS (0x1u << 3) // (TC) RB Compare -#define AT91C_TC_CPCS (0x1u << 4) // (TC) RC Compare -#define AT91C_TC_LDRAS (0x1u << 5) // (TC) RA Loading -#define AT91C_TC_LDRBS (0x1u << 6) // (TC) RB Loading -#define AT91C_TC_ETRCS (0x1u << 7) // (TC) External Trigger -#define AT91C_TC_ETRGS (0x1u << 16) // (TC) Clock Enabling -#define AT91C_TC_MTIOA (0x1u << 17) // (TC) TIOA Mirror -#define AT91C_TC_MTIOB (0x1u << 18) // (TC) TIOA Mirror -// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register -------- -// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register -------- -// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Timer Counter Interface -// ***************************************************************************** -typedef struct _AT91S_TCB { - AT91S_TC TCB_TC0; // TC Channel 0 - AT91_REG Reserved0[4]; // - AT91S_TC TCB_TC1; // TC Channel 1 - AT91_REG Reserved1[4]; // - AT91S_TC TCB_TC2; // TC Channel 2 - AT91_REG Reserved2[4]; // - AT91_REG TCB_BCR; // TC Block Control Register - AT91_REG TCB_BMR; // TC Block Mode Register -} AT91S_TCB, *AT91PS_TCB; - -// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register -------- -#define AT91C_TCB_SYNC (0x1u << 0) // (TCB) Synchro Command -// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register -------- -#define AT91C_TCB_TC0XC0S (0x1u << 0) // (TCB) External Clock Signal 0 Selection -#define AT91C_TCB_TC0XC0S_TCLK0 0x0u // (TCB) TCLK0 connected to XC0 -#define AT91C_TCB_TC0XC0S_NONE 0x1u // (TCB) None signal connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA1 0x2u // (TCB) TIOA1 connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA2 0x3u // (TCB) TIOA2 connected to XC0 -#define AT91C_TCB_TC1XC1S (0x1u << 2) // (TCB) External Clock Signal 1 Selection -#define AT91C_TCB_TC1XC1S_TCLK1 (0x0u << 2) // (TCB) TCLK1 connected to XC1 -#define AT91C_TCB_TC1XC1S_NONE (0x1u << 2) // (TCB) None signal connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA0 (0x2u << 2) // (TCB) TIOA0 connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA2 (0x3u << 2) // (TCB) TIOA2 connected to XC1 -#define AT91C_TCB_TC2XC2S (0x1u << 4) // (TCB) External Clock Signal 2 Selection -#define AT91C_TCB_TC2XC2S_TCLK2 (0x0u << 4) // (TCB) TCLK2 connected to XC2 -#define AT91C_TCB_TC2XC2S_NONE (0x1u << 4) // (TCB) None signal connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA0 (0x2u << 4) // (TCB) TIOA0 connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA2 (0x3u << 4) // (TCB) TIOA2 connected to XC2 - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR USB Host Interface -// ***************************************************************************** -typedef struct _AT91S_UHP { - AT91_REG UHP_HcRevision; // Revision - AT91_REG UHP_HcControl; // Operating modes for the Host Controller - AT91_REG UHP_HcCommandStatus; // Command & status Register - AT91_REG UHP_HcInterruptStatus; // Interrupt Status Register - AT91_REG UHP_HcInterruptEnable; // Interrupt Enable Register - AT91_REG UHP_HcInterruptDisable; // Interrupt Disable Register - AT91_REG UHP_HcHCCA; // Pointer to the Host Controller Communication Area - AT91_REG UHP_HcPeriodCurrentED; // Current Isochronous or Interrupt Endpoint Descriptor - AT91_REG UHP_HcControlHeadED; // First Endpoint Descriptor of the Control list - AT91_REG UHP_HcControlCurrentED; // Endpoint Control and Status Register - AT91_REG UHP_HcBulkHeadED; // First endpoint register of the Bulk list - AT91_REG UHP_HcBulkCurrentED; // Current endpoint of the Bulk list - AT91_REG UHP_HcBulkDoneHead; // Last completed transfer descriptor - AT91_REG UHP_HcFmInterval; // Bit time between 2 consecutive SOFs - AT91_REG UHP_HcFmRemaining; // Bit time remaining in the current Frame - AT91_REG UHP_HcFmNumber; // Frame number - AT91_REG UHP_HcPeriodicStart; // Periodic Start - AT91_REG UHP_HcLSThreshold; // LS Threshold - AT91_REG UHP_HcRhDescriptorA; // Root Hub characteristics A - AT91_REG UHP_HcRhDescriptorB; // Root Hub characteristics B - AT91_REG UHP_HcRhStatus; // Root Hub Status register - AT91_REG UHP_HcRhPortStatus[2]; // Root Hub Port Status Register -} AT91S_UHP, *AT91PS_UHP; - - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Ethernet MAC -// ***************************************************************************** -typedef struct _AT91S_EMAC { - AT91_REG EMAC_CTL; // Network Control Register - AT91_REG EMAC_CFG; // Network Configuration Register - AT91_REG EMAC_SR; // Network Status Register - AT91_REG EMAC_TAR; // Transmit Address Register - AT91_REG EMAC_TCR; // Transmit Control Register - AT91_REG EMAC_TSR; // Transmit Status Register - AT91_REG EMAC_RBQP; // Receive Buffer Queue Pointer - AT91_REG Reserved0[1]; // - AT91_REG EMAC_RSR; // Receive Status Register - AT91_REG EMAC_ISR; // Interrupt Status Register - AT91_REG EMAC_IER; // Interrupt Enable Register - AT91_REG EMAC_IDR; // Interrupt Disable Register - AT91_REG EMAC_IMR; // Interrupt Mask Register - AT91_REG EMAC_MAN; // PHY Maintenance Register - AT91_REG Reserved1[2]; // - AT91_REG EMAC_FRA; // Frames Transmitted OK Register - AT91_REG EMAC_SCOL; // Single Collision Frame Register - AT91_REG EMAC_MCOL; // Multiple Collision Frame Register - AT91_REG EMAC_OK; // Frames Received OK Register - AT91_REG EMAC_SEQE; // Frame Check Sequence Error Register - AT91_REG EMAC_ALE; // Alignment Error Register - AT91_REG EMAC_DTE; // Deferred Transmission Frame Register - AT91_REG EMAC_LCOL; // Late Collision Register - AT91_REG EMAC_ECOL; // Excessive Collision Register - AT91_REG EMAC_CSE; // Carrier Sense Error Register - AT91_REG EMAC_TUE; // Transmit Underrun Error Register - AT91_REG EMAC_CDE; // Code Error Register - AT91_REG EMAC_ELR; // Excessive Length Error Register - AT91_REG EMAC_RJB; // Receive Jabber Register - AT91_REG EMAC_USF; // Undersize Frame Register - AT91_REG EMAC_SQEE; // SQE Test Error Register - AT91_REG EMAC_DRFC; // Discarded RX Frame Register - AT91_REG Reserved2[3]; // - AT91_REG EMAC_HSH; // Hash Address High[63:32] - AT91_REG EMAC_HSL; // Hash Address Low[31:0] - AT91_REG EMAC_SA1L; // Specific Address 1 Low, First 4 bytes - AT91_REG EMAC_SA1H; // Specific Address 1 High, Last 2 bytes - AT91_REG EMAC_SA2L; // Specific Address 2 Low, First 4 bytes - AT91_REG EMAC_SA2H; // Specific Address 2 High, Last 2 bytes - AT91_REG EMAC_SA3L; // Specific Address 3 Low, First 4 bytes - AT91_REG EMAC_SA3H; // Specific Address 3 High, Last 2 bytes - AT91_REG EMAC_SA4L; // Specific Address 4 Low, First 4 bytes - AT91_REG EMAC_SA4H; // Specific Address 4 High, Last 2 bytesr -} AT91S_EMAC, *AT91PS_EMAC; - -// -------- EMAC_CTL : (EMAC Offset: 0x0) -------- -#define AT91C_EMAC_LB (0x1u << 0) // (EMAC) Loopback. Optional. When set, loopback signal is at high level. -#define AT91C_EMAC_LBL (0x1u << 1) // (EMAC) Loopback local. -#define AT91C_EMAC_RE (0x1u << 2) // (EMAC) Receive enable. -#define AT91C_EMAC_TE (0x1u << 3) // (EMAC) Transmit enable. -#define AT91C_EMAC_MPE (0x1u << 4) // (EMAC) Management port enable. -#define AT91C_EMAC_CSR (0x1u << 5) // (EMAC) Clear statistics registers. -#define AT91C_EMAC_ISR (0x1u << 6) // (EMAC) Increment statistics registers. -#define AT91C_EMAC_WES (0x1u << 7) // (EMAC) Write enable for statistics registers. -#define AT91C_EMAC_BP (0x1u << 8) // (EMAC) Back pressure. -// -------- EMAC_CFG : (EMAC Offset: 0x4) Network Configuration Register -------- -#define AT91C_EMAC_SPD (0x1u << 0) // (EMAC) Speed. -#define AT91C_EMAC_FD (0x1u << 1) // (EMAC) Full duplex. -#define AT91C_EMAC_BR (0x1u << 2) // (EMAC) Bit rate. -#define AT91C_EMAC_CAF (0x1u << 4) // (EMAC) Copy all frames. -#define AT91C_EMAC_NBC (0x1u << 5) // (EMAC) No broadcast. -#define AT91C_EMAC_MTI (0x1u << 6) // (EMAC) Multicast hash enable -#define AT91C_EMAC_UNI (0x1u << 7) // (EMAC) Unicast hash enable. -#define AT91C_EMAC_BIG (0x1u << 8) // (EMAC) Receive 1522 bytes. -#define AT91C_EMAC_EAE (0x1u << 9) // (EMAC) External address match enable. -#define AT91C_EMAC_CLK (0x3u << 10) // (EMAC) -#define AT91C_EMAC_CLK_HCLK_8 (0x0u << 10) // (EMAC) HCLK divided by 8 -#define AT91C_EMAC_CLK_HCLK_16 (0x1u << 10) // (EMAC) HCLK divided by 16 -#define AT91C_EMAC_CLK_HCLK_32 (0x2u << 10) // (EMAC) HCLK divided by 32 -#define AT91C_EMAC_CLK_HCLK_64 (0x3u << 10) // (EMAC) HCLK divided by 64 -#define AT91C_EMAC_RTY (0x1u << 12) // (EMAC) -#define AT91C_EMAC_RMII (0x1u << 13) // (EMAC) -// -------- EMAC_SR : (EMAC Offset: 0x8) Network Status Register -------- -#define AT91C_EMAC_MDIO (0x1u << 1) // (EMAC) -#define AT91C_EMAC_IDLE (0x1u << 2) // (EMAC) -// -------- EMAC_TCR : (EMAC Offset: 0x10) Transmit Control Register -------- -#define AT91C_EMAC_LEN (0x7FFu << 0) // (EMAC) -#define AT91C_EMAC_NCRC (0x1u << 15) // (EMAC) -// -------- EMAC_TSR : (EMAC Offset: 0x14) Transmit Control Register -------- -#define AT91C_EMAC_OVR (0x1u << 0) // (EMAC) -#define AT91C_EMAC_COL (0x1u << 1) // (EMAC) -#define AT91C_EMAC_RLE (0x1u << 2) // (EMAC) -#define AT91C_EMAC_TXIDLE (0x1u << 3) // (EMAC) -#define AT91C_EMAC_BNQ (0x1u << 4) // (EMAC) -#define AT91C_EMAC_COMP (0x1u << 5) // (EMAC) -#define AT91C_EMAC_UND (0x1u << 6) // (EMAC) -// -------- EMAC_RSR : (EMAC Offset: 0x20) Receive Status Register -------- -#define AT91C_EMAC_BNA (0x1u << 0) // (EMAC) -#define AT91C_EMAC_REC (0x1u << 1) // (EMAC) -// -------- EMAC_ISR : (EMAC Offset: 0x24) Interrupt Status Register -------- -#define AT91C_EMAC_DONE (0x1u << 0) // (EMAC) -#define AT91C_EMAC_RCOM (0x1u << 1) // (EMAC) -#define AT91C_EMAC_RBNA (0x1u << 2) // (EMAC) -#define AT91C_EMAC_TOVR (0x1u << 3) // (EMAC) -#define AT91C_EMAC_TUND (0x1u << 4) // (EMAC) -#define AT91C_EMAC_RTRY (0x1u << 5) // (EMAC) -#define AT91C_EMAC_TBRE (0x1u << 6) // (EMAC) -#define AT91C_EMAC_TCOM (0x1u << 7) // (EMAC) -#define AT91C_EMAC_TIDLE (0x1u << 8) // (EMAC) -#define AT91C_EMAC_LINK (0x1u << 9) // (EMAC) -#define AT91C_EMAC_ROVR (0x1u << 10) // (EMAC) -#define AT91C_EMAC_HRESP (0x1u << 11) // (EMAC) -// -------- EMAC_IER : (EMAC Offset: 0x28) Interrupt Enable Register -------- -// -------- EMAC_IDR : (EMAC Offset: 0x2c) Interrupt Disable Register -------- -// -------- EMAC_IMR : (EMAC Offset: 0x30) Interrupt Mask Register -------- -// -------- EMAC_MAN : (EMAC Offset: 0x34) PHY Maintenance Register -------- -#define AT91C_EMAC_DATA (0xFFFFu << 0) // (EMAC) -#define AT91C_EMAC_CODE (0x3u << 16) // (EMAC) -#define AT91C_EMAC_REGA (0x1Fu << 18) // (EMAC) -#define AT91C_EMAC_PHYA (0x1Fu << 23) // (EMAC) -#define AT91C_EMAC_RW (0x3u << 28) // (EMAC) -#define AT91C_EMAC_HIGH (0x1u << 30) // (EMAC) -#define AT91C_EMAC_LOW (0x1u << 31) // (EMAC) - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR External Bus Interface -// ***************************************************************************** -typedef struct _AT91S_EBI { - AT91_REG EBI_CSA; // Chip Select Assignment Register - AT91_REG EBI_CFGR; // Configuration Register -} AT91S_EBI, *AT91PS_EBI; - -// -------- EBI_CSA : (EBI Offset: 0x0) Chip Select Assignment Register -------- -#define AT91C_EBI_CS0A (0x1u << 0) // (EBI) Chip Select 0 Assignment -#define AT91C_EBI_CS0A_SMC 0x0u // (EBI) Chip Select 0 is assigned to the Static Memory Controller. -#define AT91C_EBI_CS0A_BFC 0x1u // (EBI) Chip Select 0 is assigned to the Burst Flash Controller. -#define AT91C_EBI_CS1A (0x1u << 1) // (EBI) Chip Select 1 Assignment -#define AT91C_EBI_CS1A_SMC (0x0u << 1) // (EBI) Chip Select 1 is assigned to the Static Memory Controller. -#define AT91C_EBI_CS1A_SDRAMC (0x1u << 1) // (EBI) Chip Select 1 is assigned to the SDRAM Controller. -#define AT91C_EBI_CS3A (0x1u << 3) // (EBI) Chip Select 3 Assignment -#define AT91C_EBI_CS3A_SMC (0x0u << 3) // (EBI) Chip Select 3 is only assigned to the Static Memory Controller and NCS3 behaves as defined by the SMC2. -#define AT91C_EBI_CS3A_SMC_SmartMedia (0x1u << 3) // (EBI) Chip Select 3 is assigned to the Static Memory Controller and the SmartMedia Logic is activated. -#define AT91C_EBI_CS4A (0x1u << 4) // (EBI) Chip Select 4 Assignment -#define AT91C_EBI_CS4A_SMC (0x0u << 4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and NCS4,NCS5 and NCS6 behave as defined by the SMC2. -#define AT91C_EBI_CS4A_SMC_CompactFlash (0x1u << 4) // (EBI) Chip Select 4 is assigned to the Static Memory Controller and the CompactFlash Logic is activated. -// -------- EBI_CFGR : (EBI Offset: 0x4) Configuration Register -------- -#define AT91C_EBI_DBPUC (0x1u << 0) // (EBI) Data Bus Pull-Up Configuration -#define AT91C_EBI_EBSEN (0x1u << 1) // (EBI) Bus Sharing Enable - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Static Memory Controller 2 Interface -// ***************************************************************************** -typedef struct _AT91S_SMC2 { - AT91_REG SMC2_CSR[8]; // SMC2 Chip Select Register -} AT91S_SMC2, *AT91PS_SMC2; - -// -------- SMC2_CSR : (SMC2 Offset: 0x0) SMC2 Chip Select Register -------- -#define AT91C_SMC2_NWS (0x7Fu << 0) // (SMC2) Number of Wait States -#define AT91C_SMC2_WSEN (0x1u << 7) // (SMC2) Wait State Enable -#define AT91C_SMC2_TDF (0xFu << 8) // (SMC2) Data Float Time -#define AT91C_SMC2_BAT (0x1u << 12) // (SMC2) Byte Access Type -#define AT91C_SMC2_DBW (0x1u << 13) // (SMC2) Data Bus Width -#define AT91C_SMC2_DBW_16 (0x1u << 13) // (SMC2) 16-bit. -#define AT91C_SMC2_DBW_8 (0x2u << 13) // (SMC2) 8-bit. -#define AT91C_SMC2_DRP (0x1u << 15) // (SMC2) Data Read Protocol -#define AT91C_SMC2_ACSS (0x3u << 16) // (SMC2) Address to Chip Select Setup -#define AT91C_SMC2_ACSS_STANDARD (0x0u << 16) // (SMC2) Standard, asserted at the beginning of the access and deasserted at the end. -#define AT91C_SMC2_ACSS_1_CYCLE (0x1u << 16) // (SMC2) One cycle less at the beginning and the end of the access. -#define AT91C_SMC2_ACSS_2_CYCLES (0x2u << 16) // (SMC2) Two cycles less at the beginning and the end of the access. -#define AT91C_SMC2_ACSS_3_CYCLES (0x3u << 16) // (SMC2) Three cycles less at the beginning and the end of the access. -#define AT91C_SMC2_RWSETUP (0x7u << 24) // (SMC2) Read and Write Signal Setup Time -#define AT91C_SMC2_RWHOLD (0x7u << 29) // (SMC2) Read and Write Signal Hold Time - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR SDRAM Controller Interface -// ***************************************************************************** -typedef struct _AT91S_SDRC { - AT91_REG SDRC_MR; // SDRAM Controller Mode Register - AT91_REG SDRC_TR; // SDRAM Controller Refresh Timer Register - AT91_REG SDRC_CR; // SDRAM Controller Configuration Register - AT91_REG SDRC_SRR; // SDRAM Controller Self Refresh Register - AT91_REG SDRC_LPR; // SDRAM Controller Low Power Register - AT91_REG SDRC_IER; // SDRAM Controller Interrupt Enable Register - AT91_REG SDRC_IDR; // SDRAM Controller Interrupt Disable Register - AT91_REG SDRC_IMR; // SDRAM Controller Interrupt Mask Register - AT91_REG SDRC_ISR; // SDRAM Controller Interrupt Mask Register -} AT91S_SDRC, *AT91PS_SDRC; - -// -------- SDRC_MR : (SDRC Offset: 0x0) SDRAM Controller Mode Register -------- -#define AT91C_SDRC_MODE (0xFu << 0) // (SDRC) Mode -#define AT91C_SDRC_MODE_NORMAL_CMD 0x0u // (SDRC) Normal Mode -#define AT91C_SDRC_MODE_NOP_CMD 0x1u // (SDRC) NOP Command -#define AT91C_SDRC_MODE_PRCGALL_CMD 0x2u // (SDRC) All Banks Precharge Command -#define AT91C_SDRC_MODE_LMR_CMD 0x3u // (SDRC) Load Mode Register Command -#define AT91C_SDRC_MODE_RFSH_CMD 0x4u // (SDRC) Refresh Command -#define AT91C_SDRC_DBW (0x1u << 4) // (SDRC) Data Bus Width -#define AT91C_SDRC_DBW_32_BITS (0x0u << 4) // (SDRC) 32 Bits datas bus -#define AT91C_SDRC_DBW_16_BITS (0x1u << 4) // (SDRC) 16 Bits datas bus -// -------- SDRC_TR : (SDRC Offset: 0x4) SDRC Refresh Timer Register -------- -#define AT91C_SDRC_COUNT (0xFFFu << 0) // (SDRC) Refresh Counter -// -------- SDRC_CR : (SDRC Offset: 0x8) SDRAM Configuration Register -------- -#define AT91C_SDRC_NC (0x3u << 0) // (SDRC) Number of Column Bits -#define AT91C_SDRC_NC_8 0x0u // (SDRC) 8 Bits -#define AT91C_SDRC_NC_9 0x1u // (SDRC) 9 Bits -#define AT91C_SDRC_NC_10 0x2u // (SDRC) 10 Bits -#define AT91C_SDRC_NC_11 0x3u // (SDRC) 11 Bits -#define AT91C_SDRC_NR (0x3u << 2) // (SDRC) Number of Row Bits -#define AT91C_SDRC_NR_11 (0x0u << 2) // (SDRC) 11 Bits -#define AT91C_SDRC_NR_12 (0x1u << 2) // (SDRC) 12 Bits -#define AT91C_SDRC_NR_13 (0x2u << 2) // (SDRC) 13 Bits -#define AT91C_SDRC_NB (0x1u << 4) // (SDRC) Number of Banks -#define AT91C_SDRC_NB_2_BANKS (0x0u << 4) // (SDRC) 2 banks -#define AT91C_SDRC_NB_4_BANKS (0x1u << 4) // (SDRC) 4 banks -#define AT91C_SDRC_CAS (0x3u << 5) // (SDRC) CAS Latency -#define AT91C_SDRC_CAS_2 (0x2u << 5) // (SDRC) 2 cycles -#define AT91C_SDRC_TWR (0xFu << 7) // (SDRC) Number of Write Recovery Time Cycles -#define AT91C_SDRC_TRC (0xFu << 11) // (SDRC) Number of RAS Cycle Time Cycles -#define AT91C_SDRC_TRP (0xFu << 15) // (SDRC) Number of RAS Precharge Time Cycles -#define AT91C_SDRC_TRCD (0xFu << 19) // (SDRC) Number of RAS to CAS Delay Cycles -#define AT91C_SDRC_TRAS (0xFu << 23) // (SDRC) Number of RAS Active Time Cycles -#define AT91C_SDRC_TXSR (0xFu << 27) // (SDRC) Number of Command Recovery Time Cycles -// -------- SDRC_SRR : (SDRC Offset: 0xc) SDRAM Controller Self-refresh Register -------- -#define AT91C_SDRC_SRCB (0x1u << 0) // (SDRC) Self-refresh Command Bit -// -------- SDRC_LPR : (SDRC Offset: 0x10) SDRAM Controller Low-power Register -------- -#define AT91C_SDRC_LPCB (0x1u << 0) // (SDRC) Low-power Command Bit -// -------- SDRC_IER : (SDRC Offset: 0x14) SDRAM Controller Interrupt Enable Register -------- -#define AT91C_SDRC_RES (0x1u << 0) // (SDRC) Refresh Error Status -// -------- SDRC_IDR : (SDRC Offset: 0x18) SDRAM Controller Interrupt Disable Register -------- -// -------- SDRC_IMR : (SDRC Offset: 0x1c) SDRAM Controller Interrupt Mask Register -------- -// -------- SDRC_ISR : (SDRC Offset: 0x20) SDRAM Controller Interrupt Status Register -------- - -// ***************************************************************************** -// SOFTWARE API DEFINITION FOR Burst Flash Controller Interface -// ***************************************************************************** -typedef struct _AT91S_BFC { - AT91_REG BFC_MR; // BFC Mode Register -} AT91S_BFC, *AT91PS_BFC; - -// -------- BFC_MR : (BFC Offset: 0x0) BFC Mode Register -------- -#define AT91C_BFC_BFCOM (0x3u << 0) // (BFC) Burst Flash Controller Operating Mode -#define AT91C_BFC_BFCOM_DISABLED 0x0u // (BFC) NPCS0 is driven by the SMC or remains high. -#define AT91C_BFC_BFCOM_ASYNC 0x1u // (BFC) Asynchronous -#define AT91C_BFC_BFCOM_BURST_READ 0x2u // (BFC) Burst Read -#define AT91C_BFC_BFCC (0x3u << 2) // (BFC) Burst Flash Controller Operating Mode -#define AT91C_BFC_BFCC_MCK (0x1u << 2) // (BFC) Master Clock. -#define AT91C_BFC_BFCC_MCK_DIV_2 (0x2u << 2) // (BFC) Master Clock divided by 2. -#define AT91C_BFC_BFCC_MCK_DIV_4 (0x3u << 2) // (BFC) Master Clock divided by 4. -#define AT91C_BFC_AVL (0xFu << 4) // (BFC) Address Valid Latency -#define AT91C_BFC_PAGES (0x7u << 8) // (BFC) Page Size -#define AT91C_BFC_PAGES_NO_PAGE (0x0u << 8) // (BFC) No page handling. -#define AT91C_BFC_PAGES_16 (0x1u << 8) // (BFC) 16 bytes page size. -#define AT91C_BFC_PAGES_32 (0x2u << 8) // (BFC) 32 bytes page size. -#define AT91C_BFC_PAGES_64 (0x3u << 8) // (BFC) 64 bytes page size. -#define AT91C_BFC_PAGES_128 (0x4u << 8) // (BFC) 128 bytes page size. -#define AT91C_BFC_PAGES_256 (0x5u << 8) // (BFC) 256 bytes page size. -#define AT91C_BFC_PAGES_512 (0x6u << 8) // (BFC) 512 bytes page size. -#define AT91C_BFC_PAGES_1024 (0x7u << 8) // (BFC) 1024 bytes page size. -#define AT91C_BFC_OEL (0x3u << 12) // (BFC) Output Enable Latency -#define AT91C_BFC_BAAEN (0x1u << 16) // (BFC) Burst Address Advance Enable -#define AT91C_BFC_BFOEH (0x1u << 17) // (BFC) Burst Flash Output Enable Handling -#define AT91C_BFC_MUXEN (0x1u << 18) // (BFC) Multiplexed Bus Enable -#define AT91C_BFC_RDYEN (0x1u << 19) // (BFC) Ready Enable Mode - -// ***************************************************************************** -// REGISTER ADDRESS DEFINITION FOR AT91RM9200 -// ***************************************************************************** -// ========== Register definition for SYS peripheral ========== -// ========== Register definition for MC peripheral ========== -#define AT91C_MC_PUER ((AT91_REG *) 0xFFFFFF54) // (MC) MC Protection Unit Enable Register -#define AT91C_MC_ASR ((AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register -#define AT91C_MC_PUP ((AT91_REG *) 0xFFFFFF50) // (MC) MC Protection Unit Peripherals -#define AT91C_MC_PUIA ((AT91_REG *) 0xFFFFFF10) // (MC) MC Protection Unit Area -#define AT91C_MC_AASR ((AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register -#define AT91C_MC_RCR ((AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register -// ========== Register definition for RTC peripheral ========== -#define AT91C_RTC_IMR ((AT91_REG *) 0xFFFFFE28) // (RTC) Interrupt Mask Register -#define AT91C_RTC_IER ((AT91_REG *) 0xFFFFFE20) // (RTC) Interrupt Enable Register -#define AT91C_RTC_SR ((AT91_REG *) 0xFFFFFE18) // (RTC) Status Register -#define AT91C_RTC_TIMALR ((AT91_REG *) 0xFFFFFE10) // (RTC) Time Alarm Register -#define AT91C_RTC_TIMR ((AT91_REG *) 0xFFFFFE08) // (RTC) Time Register -#define AT91C_RTC_CR ((AT91_REG *) 0xFFFFFE00) // (RTC) Control Register -#define AT91C_RTC_VER ((AT91_REG *) 0xFFFFFE2C) // (RTC) Valid Entry Register -#define AT91C_RTC_IDR ((AT91_REG *) 0xFFFFFE24) // (RTC) Interrupt Disable Register -#define AT91C_RTC_SCCR ((AT91_REG *) 0xFFFFFE1C) // (RTC) Status Clear Command Register -#define AT91C_RTC_CALALR ((AT91_REG *) 0xFFFFFE14) // (RTC) Calendar Alarm Register -#define AT91C_RTC_CALR ((AT91_REG *) 0xFFFFFE0C) // (RTC) Calendar Register -#define AT91C_RTC_MR ((AT91_REG *) 0xFFFFFE04) // (RTC) Mode Register -// ========== Register definition for ST peripheral ========== -#define AT91C_ST_CRTR ((AT91_REG *) 0xFFFFFD24) // (ST) Current Real-time Register -#define AT91C_ST_IMR ((AT91_REG *) 0xFFFFFD1C) // (ST) Interrupt Mask Register -#define AT91C_ST_IER ((AT91_REG *) 0xFFFFFD14) // (ST) Interrupt Enable Register -#define AT91C_ST_RTMR ((AT91_REG *) 0xFFFFFD0C) // (ST) Real-time Mode Register -#define AT91C_ST_PIMR ((AT91_REG *) 0xFFFFFD04) // (ST) Period Interval Mode Register -#define AT91C_ST_RTAR ((AT91_REG *) 0xFFFFFD20) // (ST) Real-time Alarm Register -#define AT91C_ST_IDR ((AT91_REG *) 0xFFFFFD18) // (ST) Interrupt Disable Register -#define AT91C_ST_SR ((AT91_REG *) 0xFFFFFD10) // (ST) Status Register -#define AT91C_ST_WDMR ((AT91_REG *) 0xFFFFFD08) // (ST) Watchdog Mode Register -#define AT91C_ST_CR ((AT91_REG *) 0xFFFFFD00) // (ST) Control Register -// ========== Register definition for PMC peripheral ========== -#define AT91C_PMC_SCSR ((AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register -#define AT91C_PMC_SCER ((AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register -#define AT91C_PMC_IMR ((AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register -#define AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register -#define AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register -#define AT91C_PMC_SCDR ((AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register -#define AT91C_PMC_SR ((AT91_REG *) 0xFFFFFC68) // (PMC) Status Register -#define AT91C_PMC_IER ((AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register -#define AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register -#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register -#define AT91C_PMC_PCSR ((AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register -#define AT91C_PMC_PCKR ((AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register -// ========== Register definition for CKGR peripheral ========== -#define AT91C_CKGR_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL B Register -#define AT91C_CKGR_MCFR ((AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register -#define AT91C_CKGR_PLLAR ((AT91_REG *) 0xFFFFFC28) // (CKGR) PLL A Register -#define AT91C_CKGR_MOR ((AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register -// ========== Register definition for PIOD peripheral ========== -#define AT91C_PIOD_PDSR ((AT91_REG *) 0xFFFFFA3C) // (PIOD) Pin Data Status Register -#define AT91C_PIOD_CODR ((AT91_REG *) 0xFFFFFA34) // (PIOD) Clear Output Data Register -#define AT91C_PIOD_OWER ((AT91_REG *) 0xFFFFFAA0) // (PIOD) Output Write Enable Register -#define AT91C_PIOD_MDER ((AT91_REG *) 0xFFFFFA50) // (PIOD) Multi-driver Enable Register -#define AT91C_PIOD_IMR ((AT91_REG *) 0xFFFFFA48) // (PIOD) Interrupt Mask Register -#define AT91C_PIOD_IER ((AT91_REG *) 0xFFFFFA40) // (PIOD) Interrupt Enable Register -#define AT91C_PIOD_ODSR ((AT91_REG *) 0xFFFFFA38) // (PIOD) Output Data Status Register -#define AT91C_PIOD_SODR ((AT91_REG *) 0xFFFFFA30) // (PIOD) Set Output Data Register -#define AT91C_PIOD_PER ((AT91_REG *) 0xFFFFFA00) // (PIOD) PIO Enable Register -#define AT91C_PIOD_OWDR ((AT91_REG *) 0xFFFFFAA4) // (PIOD) Output Write Disable Register -#define AT91C_PIOD_PPUER ((AT91_REG *) 0xFFFFFA64) // (PIOD) Pull-up Enable Register -#define AT91C_PIOD_MDDR ((AT91_REG *) 0xFFFFFA54) // (PIOD) Multi-driver Disable Register -#define AT91C_PIOD_ISR ((AT91_REG *) 0xFFFFFA4C) // (PIOD) Interrupt Status Register -#define AT91C_PIOD_IDR ((AT91_REG *) 0xFFFFFA44) // (PIOD) Interrupt Disable Register -#define AT91C_PIOD_PDR ((AT91_REG *) 0xFFFFFA04) // (PIOD) PIO Disable Register -#define AT91C_PIOD_ODR ((AT91_REG *) 0xFFFFFA14) // (PIOD) Output Disable Registerr -#define AT91C_PIOD_OWSR ((AT91_REG *) 0xFFFFFAA8) // (PIOD) Output Write Status Register -#define AT91C_PIOD_ABSR ((AT91_REG *) 0xFFFFFA78) // (PIOD) AB Select Status Register -#define AT91C_PIOD_ASR ((AT91_REG *) 0xFFFFFA70) // (PIOD) Select A Register -#define AT91C_PIOD_PPUSR ((AT91_REG *) 0xFFFFFA68) // (PIOD) Pad Pull-up Status Register -#define AT91C_PIOD_PPUDR ((AT91_REG *) 0xFFFFFA60) // (PIOD) Pull-up Disable Register -#define AT91C_PIOD_MDSR ((AT91_REG *) 0xFFFFFA58) // (PIOD) Multi-driver Status Register -#define AT91C_PIOD_PSR ((AT91_REG *) 0xFFFFFA08) // (PIOD) PIO Status Register -#define AT91C_PIOD_OER ((AT91_REG *) 0xFFFFFA10) // (PIOD) Output Enable Register -#define AT91C_PIOD_OSR ((AT91_REG *) 0xFFFFFA18) // (PIOD) Output Status Register -#define AT91C_PIOD_IFER ((AT91_REG *) 0xFFFFFA20) // (PIOD) Input Filter Enable Register -#define AT91C_PIOD_BSR ((AT91_REG *) 0xFFFFFA74) // (PIOD) Select B Register -#define AT91C_PIOD_IFDR ((AT91_REG *) 0xFFFFFA24) // (PIOD) Input Filter Disable Register -#define AT91C_PIOD_IFSR ((AT91_REG *) 0xFFFFFA28) // (PIOD) Input Filter Status Register -// ========== Register definition for PIOC peripheral ========== -#define AT91C_PIOC_IFDR ((AT91_REG *) 0xFFFFF824) // (PIOC) Input Filter Disable Register -#define AT91C_PIOC_ODR ((AT91_REG *) 0xFFFFF814) // (PIOC) Output Disable Registerr -#define AT91C_PIOC_ABSR ((AT91_REG *) 0xFFFFF878) // (PIOC) AB Select Status Register -#define AT91C_PIOC_SODR ((AT91_REG *) 0xFFFFF830) // (PIOC) Set Output Data Register -#define AT91C_PIOC_IFSR ((AT91_REG *) 0xFFFFF828) // (PIOC) Input Filter Status Register -#define AT91C_PIOC_CODR ((AT91_REG *) 0xFFFFF834) // (PIOC) Clear Output Data Register -#define AT91C_PIOC_ODSR ((AT91_REG *) 0xFFFFF838) // (PIOC) Output Data Status Register -#define AT91C_PIOC_IER ((AT91_REG *) 0xFFFFF840) // (PIOC) Interrupt Enable Register -#define AT91C_PIOC_IMR ((AT91_REG *) 0xFFFFF848) // (PIOC) Interrupt Mask Register -#define AT91C_PIOC_OWDR ((AT91_REG *) 0xFFFFF8A4) // (PIOC) Output Write Disable Register -#define AT91C_PIOC_MDDR ((AT91_REG *) 0xFFFFF854) // (PIOC) Multi-driver Disable Register -#define AT91C_PIOC_PDSR ((AT91_REG *) 0xFFFFF83C) // (PIOC) Pin Data Status Register -#define AT91C_PIOC_IDR ((AT91_REG *) 0xFFFFF844) // (PIOC) Interrupt Disable Register -#define AT91C_PIOC_ISR ((AT91_REG *) 0xFFFFF84C) // (PIOC) Interrupt Status Register -#define AT91C_PIOC_PDR ((AT91_REG *) 0xFFFFF804) // (PIOC) PIO Disable Register -#define AT91C_PIOC_OWSR ((AT91_REG *) 0xFFFFF8A8) // (PIOC) Output Write Status Register -#define AT91C_PIOC_OWER ((AT91_REG *) 0xFFFFF8A0) // (PIOC) Output Write Enable Register -#define AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register -#define AT91C_PIOC_PPUSR ((AT91_REG *) 0xFFFFF868) // (PIOC) Pad Pull-up Status Register -#define AT91C_PIOC_PPUDR ((AT91_REG *) 0xFFFFF860) // (PIOC) Pull-up Disable Register -#define AT91C_PIOC_MDSR ((AT91_REG *) 0xFFFFF858) // (PIOC) Multi-driver Status Register -#define AT91C_PIOC_MDER ((AT91_REG *) 0xFFFFF850) // (PIOC) Multi-driver Enable Register -#define AT91C_PIOC_IFER ((AT91_REG *) 0xFFFFF820) // (PIOC) Input Filter Enable Register -#define AT91C_PIOC_OSR ((AT91_REG *) 0xFFFFF818) // (PIOC) Output Status Register -#define AT91C_PIOC_OER ((AT91_REG *) 0xFFFFF810) // (PIOC) Output Enable Register -#define AT91C_PIOC_PSR ((AT91_REG *) 0xFFFFF808) // (PIOC) PIO Status Register -#define AT91C_PIOC_PER ((AT91_REG *) 0xFFFFF800) // (PIOC) PIO Enable Register -#define AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register -#define AT91C_PIOC_PPUER ((AT91_REG *) 0xFFFFF864) // (PIOC) Pull-up Enable Register -// ========== Register definition for PIOB peripheral ========== -#define AT91C_PIOB_OWSR ((AT91_REG *) 0xFFFFF6A8) // (PIOB) Output Write Status Register -#define AT91C_PIOB_PPUSR ((AT91_REG *) 0xFFFFF668) // (PIOB) Pad Pull-up Status Register -#define AT91C_PIOB_PPUDR ((AT91_REG *) 0xFFFFF660) // (PIOB) Pull-up Disable Register -#define AT91C_PIOB_MDSR ((AT91_REG *) 0xFFFFF658) // (PIOB) Multi-driver Status Register -#define AT91C_PIOB_MDER ((AT91_REG *) 0xFFFFF650) // (PIOB) Multi-driver Enable Register -#define AT91C_PIOB_IMR ((AT91_REG *) 0xFFFFF648) // (PIOB) Interrupt Mask Register -#define AT91C_PIOB_OSR ((AT91_REG *) 0xFFFFF618) // (PIOB) Output Status Register -#define AT91C_PIOB_OER ((AT91_REG *) 0xFFFFF610) // (PIOB) Output Enable Register -#define AT91C_PIOB_PSR ((AT91_REG *) 0xFFFFF608) // (PIOB) PIO Status Register -#define AT91C_PIOB_PER ((AT91_REG *) 0xFFFFF600) // (PIOB) PIO Enable Register -#define AT91C_PIOB_BSR ((AT91_REG *) 0xFFFFF674) // (PIOB) Select B Register -#define AT91C_PIOB_PPUER ((AT91_REG *) 0xFFFFF664) // (PIOB) Pull-up Enable Register -#define AT91C_PIOB_IFDR ((AT91_REG *) 0xFFFFF624) // (PIOB) Input Filter Disable Register -#define AT91C_PIOB_ODR ((AT91_REG *) 0xFFFFF614) // (PIOB) Output Disable Registerr -#define AT91C_PIOB_ABSR ((AT91_REG *) 0xFFFFF678) // (PIOB) AB Select Status Register -#define AT91C_PIOB_ASR ((AT91_REG *) 0xFFFFF670) // (PIOB) Select A Register -#define AT91C_PIOB_IFER ((AT91_REG *) 0xFFFFF620) // (PIOB) Input Filter Enable Register -#define AT91C_PIOB_IFSR ((AT91_REG *) 0xFFFFF628) // (PIOB) Input Filter Status Register -#define AT91C_PIOB_SODR ((AT91_REG *) 0xFFFFF630) // (PIOB) Set Output Data Register -#define AT91C_PIOB_ODSR ((AT91_REG *) 0xFFFFF638) // (PIOB) Output Data Status Register -#define AT91C_PIOB_CODR ((AT91_REG *) 0xFFFFF634) // (PIOB) Clear Output Data Register -#define AT91C_PIOB_PDSR ((AT91_REG *) 0xFFFFF63C) // (PIOB) Pin Data Status Register -#define AT91C_PIOB_OWER ((AT91_REG *) 0xFFFFF6A0) // (PIOB) Output Write Enable Register -#define AT91C_PIOB_IER ((AT91_REG *) 0xFFFFF640) // (PIOB) Interrupt Enable Register -#define AT91C_PIOB_OWDR ((AT91_REG *) 0xFFFFF6A4) // (PIOB) Output Write Disable Register -#define AT91C_PIOB_MDDR ((AT91_REG *) 0xFFFFF654) // (PIOB) Multi-driver Disable Register -#define AT91C_PIOB_ISR ((AT91_REG *) 0xFFFFF64C) // (PIOB) Interrupt Status Register -#define AT91C_PIOB_IDR ((AT91_REG *) 0xFFFFF644) // (PIOB) Interrupt Disable Register -#define AT91C_PIOB_PDR ((AT91_REG *) 0xFFFFF604) // (PIOB) PIO Disable Register -// ========== Register definition for PIOA peripheral ========== -#define AT91C_PIOA_IMR ((AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register -#define AT91C_PIOA_IER ((AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register -#define AT91C_PIOA_OWDR ((AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register -#define AT91C_PIOA_ISR ((AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register -#define AT91C_PIOA_PPUDR ((AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register -#define AT91C_PIOA_MDSR ((AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register -#define AT91C_PIOA_MDER ((AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register -#define AT91C_PIOA_PER ((AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register -#define AT91C_PIOA_PSR ((AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register -#define AT91C_PIOA_OER ((AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register -#define AT91C_PIOA_BSR ((AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register -#define AT91C_PIOA_PPUER ((AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register -#define AT91C_PIOA_MDDR ((AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register -#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register -#define AT91C_PIOA_ODR ((AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr -#define AT91C_PIOA_IFDR ((AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register -#define AT91C_PIOA_ABSR ((AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register -#define AT91C_PIOA_ASR ((AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register -#define AT91C_PIOA_PPUSR ((AT91_REG *) 0xFFFFF468) // (PIOA) Pad Pull-up Status Register -#define AT91C_PIOA_ODSR ((AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register -#define AT91C_PIOA_SODR ((AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register -#define AT91C_PIOA_IFSR ((AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register -#define AT91C_PIOA_IFER ((AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register -#define AT91C_PIOA_OSR ((AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register -#define AT91C_PIOA_IDR ((AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register -#define AT91C_PIOA_PDSR ((AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register -#define AT91C_PIOA_CODR ((AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register -#define AT91C_PIOA_OWSR ((AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register -#define AT91C_PIOA_OWER ((AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register -// ========== Register definition for DBGU peripheral ========== -#define AT91C_DBGU_C2R ((AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID2 Register -#define AT91C_DBGU_THR ((AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register -#define AT91C_DBGU_CSR ((AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register -#define AT91C_DBGU_IDR ((AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register -#define AT91C_DBGU_MR ((AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register -#define AT91C_DBGU_FNTR ((AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register -#define AT91C_DBGU_C1R ((AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID1 Register -#define AT91C_DBGU_BRGR ((AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register -#define AT91C_DBGU_RHR ((AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register -#define AT91C_DBGU_IMR ((AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register -#define AT91C_DBGU_IER ((AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register -#define AT91C_DBGU_CR ((AT91_REG *) 0xFFFFF200) // (DBGU) Control Register -// ========== Register definition for PDC_DBGU peripheral ========== -#define AT91C_DBGU_TNCR ((AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register -#define AT91C_DBGU_RNCR ((AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register -#define AT91C_DBGU_PTCR ((AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register -#define AT91C_DBGU_PTSR ((AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register -#define AT91C_DBGU_RCR ((AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register -#define AT91C_DBGU_TCR ((AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register -#define AT91C_DBGU_RPR ((AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register -#define AT91C_DBGU_TPR ((AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register -#define AT91C_DBGU_RNPR ((AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register -#define AT91C_DBGU_TNPR ((AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register -// ========== Register definition for AIC peripheral ========== -#define AT91C_AIC_ICCR ((AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register -#define AT91C_AIC_IECR ((AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register -#define AT91C_AIC_SMR ((AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register -#define AT91C_AIC_ISCR ((AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register -#define AT91C_AIC_EOICR ((AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register -#define AT91C_AIC_DCR ((AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) -#define AT91C_AIC_FFER ((AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register -#define AT91C_AIC_SVR ((AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register -#define AT91C_AIC_SPU ((AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register -#define AT91C_AIC_FFDR ((AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register -#define AT91C_AIC_FVR ((AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register -#define AT91C_AIC_FFSR ((AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register -#define AT91C_AIC_IMR ((AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register -#define AT91C_AIC_ISR ((AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register -#define AT91C_AIC_IVR ((AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register -#define AT91C_AIC_IDCR ((AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register -#define AT91C_AIC_CISR ((AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register -#define AT91C_AIC_IPR ((AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register -// ========== Register definition for PDC_SPI peripheral ========== -#define AT91C_SPI_PTCR ((AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register -#define AT91C_SPI_TNPR ((AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register -#define AT91C_SPI_RNPR ((AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register -#define AT91C_SPI_TPR ((AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register -#define AT91C_SPI_RPR ((AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register -#define AT91C_SPI_PTSR ((AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register -#define AT91C_SPI_TNCR ((AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register -#define AT91C_SPI_RNCR ((AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register -#define AT91C_SPI_TCR ((AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register -#define AT91C_SPI_RCR ((AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register -// ========== Register definition for SPI peripheral ========== -#define AT91C_SPI_CSR ((AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register -#define AT91C_SPI_IDR ((AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register -#define AT91C_SPI_SR ((AT91_REG *) 0xFFFE0010) // (SPI) Status Register -#define AT91C_SPI_RDR ((AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register -#define AT91C_SPI_CR ((AT91_REG *) 0xFFFE0000) // (SPI) Control Register -#define AT91C_SPI_IMR ((AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register -#define AT91C_SPI_IER ((AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register -#define AT91C_SPI_TDR ((AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register -#define AT91C_SPI_MR ((AT91_REG *) 0xFFFE0004) // (SPI) Mode Register -// ========== Register definition for PDC_SSC2 peripheral ========== -#define AT91C_SSC2_PTCR ((AT91_REG *) 0xFFFD8120) // (PDC_SSC2) PDC Transfer Control Register -#define AT91C_SSC2_TNPR ((AT91_REG *) 0xFFFD8118) // (PDC_SSC2) Transmit Next Pointer Register -#define AT91C_SSC2_RNPR ((AT91_REG *) 0xFFFD8110) // (PDC_SSC2) Receive Next Pointer Register -#define AT91C_SSC2_TPR ((AT91_REG *) 0xFFFD8108) // (PDC_SSC2) Transmit Pointer Register -#define AT91C_SSC2_RPR ((AT91_REG *) 0xFFFD8100) // (PDC_SSC2) Receive Pointer Register -#define AT91C_SSC2_PTSR ((AT91_REG *) 0xFFFD8124) // (PDC_SSC2) PDC Transfer Status Register -#define AT91C_SSC2_TNCR ((AT91_REG *) 0xFFFD811C) // (PDC_SSC2) Transmit Next Counter Register -#define AT91C_SSC2_RNCR ((AT91_REG *) 0xFFFD8114) // (PDC_SSC2) Receive Next Counter Register -#define AT91C_SSC2_TCR ((AT91_REG *) 0xFFFD810C) // (PDC_SSC2) Transmit Counter Register -#define AT91C_SSC2_RCR ((AT91_REG *) 0xFFFD8104) // (PDC_SSC2) Receive Counter Register -// ========== Register definition for SSC2 peripheral ========== -#define AT91C_SSC2_IMR ((AT91_REG *) 0xFFFD804C) // (SSC2) Interrupt Mask Register -#define AT91C_SSC2_IER ((AT91_REG *) 0xFFFD8044) // (SSC2) Interrupt Enable Register -#define AT91C_SSC2_RC1R ((AT91_REG *) 0xFFFD803C) // (SSC2) Receive Compare 1 Register -#define AT91C_SSC2_TSHR ((AT91_REG *) 0xFFFD8034) // (SSC2) Transmit Sync Holding Register -#define AT91C_SSC2_CMR ((AT91_REG *) 0xFFFD8004) // (SSC2) Clock Mode Register -#define AT91C_SSC2_IDR ((AT91_REG *) 0xFFFD8048) // (SSC2) Interrupt Disable Register -#define AT91C_SSC2_TCMR ((AT91_REG *) 0xFFFD8018) // (SSC2) Transmit Clock Mode Register -#define AT91C_SSC2_RCMR ((AT91_REG *) 0xFFFD8010) // (SSC2) Receive Clock ModeRegister -#define AT91C_SSC2_CR ((AT91_REG *) 0xFFFD8000) // (SSC2) Control Register -#define AT91C_SSC2_RFMR ((AT91_REG *) 0xFFFD8014) // (SSC2) Receive Frame Mode Register -#define AT91C_SSC2_TFMR ((AT91_REG *) 0xFFFD801C) // (SSC2) Transmit Frame Mode Register -#define AT91C_SSC2_THR ((AT91_REG *) 0xFFFD8024) // (SSC2) Transmit Holding Register -#define AT91C_SSC2_SR ((AT91_REG *) 0xFFFD8040) // (SSC2) Status Register -#define AT91C_SSC2_RC0R ((AT91_REG *) 0xFFFD8038) // (SSC2) Receive Compare 0 Register -#define AT91C_SSC2_RSHR ((AT91_REG *) 0xFFFD8030) // (SSC2) Receive Sync Holding Register -#define AT91C_SSC2_RHR ((AT91_REG *) 0xFFFD8020) // (SSC2) Receive Holding Register -// ========== Register definition for PDC_SSC1 peripheral ========== -#define AT91C_SSC1_PTCR ((AT91_REG *) 0xFFFD4120) // (PDC_SSC1) PDC Transfer Control Register -#define AT91C_SSC1_TNPR ((AT91_REG *) 0xFFFD4118) // (PDC_SSC1) Transmit Next Pointer Register -#define AT91C_SSC1_RNPR ((AT91_REG *) 0xFFFD4110) // (PDC_SSC1) Receive Next Pointer Register -#define AT91C_SSC1_TPR ((AT91_REG *) 0xFFFD4108) // (PDC_SSC1) Transmit Pointer Register -#define AT91C_SSC1_RPR ((AT91_REG *) 0xFFFD4100) // (PDC_SSC1) Receive Pointer Register -#define AT91C_SSC1_PTSR ((AT91_REG *) 0xFFFD4124) // (PDC_SSC1) PDC Transfer Status Register -#define AT91C_SSC1_TNCR ((AT91_REG *) 0xFFFD411C) // (PDC_SSC1) Transmit Next Counter Register -#define AT91C_SSC1_RNCR ((AT91_REG *) 0xFFFD4114) // (PDC_SSC1) Receive Next Counter Register -#define AT91C_SSC1_TCR ((AT91_REG *) 0xFFFD410C) // (PDC_SSC1) Transmit Counter Register -#define AT91C_SSC1_RCR ((AT91_REG *) 0xFFFD4104) // (PDC_SSC1) Receive Counter Register -// ========== Register definition for SSC1 peripheral ========== -#define AT91C_SSC1_RFMR ((AT91_REG *) 0xFFFD4014) // (SSC1) Receive Frame Mode Register -#define AT91C_SSC1_CMR ((AT91_REG *) 0xFFFD4004) // (SSC1) Clock Mode Register -#define AT91C_SSC1_IDR ((AT91_REG *) 0xFFFD4048) // (SSC1) Interrupt Disable Register -#define AT91C_SSC1_SR ((AT91_REG *) 0xFFFD4040) // (SSC1) Status Register -#define AT91C_SSC1_RC0R ((AT91_REG *) 0xFFFD4038) // (SSC1) Receive Compare 0 Register -#define AT91C_SSC1_RSHR ((AT91_REG *) 0xFFFD4030) // (SSC1) Receive Sync Holding Register -#define AT91C_SSC1_RHR ((AT91_REG *) 0xFFFD4020) // (SSC1) Receive Holding Register -#define AT91C_SSC1_TCMR ((AT91_REG *) 0xFFFD4018) // (SSC1) Transmit Clock Mode Register -#define AT91C_SSC1_RCMR ((AT91_REG *) 0xFFFD4010) // (SSC1) Receive Clock ModeRegister -#define AT91C_SSC1_CR ((AT91_REG *) 0xFFFD4000) // (SSC1) Control Register -#define AT91C_SSC1_IMR ((AT91_REG *) 0xFFFD404C) // (SSC1) Interrupt Mask Register -#define AT91C_SSC1_IER ((AT91_REG *) 0xFFFD4044) // (SSC1) Interrupt Enable Register -#define AT91C_SSC1_RC1R ((AT91_REG *) 0xFFFD403C) // (SSC1) Receive Compare 1 Register -#define AT91C_SSC1_TSHR ((AT91_REG *) 0xFFFD4034) // (SSC1) Transmit Sync Holding Register -#define AT91C_SSC1_THR ((AT91_REG *) 0xFFFD4024) // (SSC1) Transmit Holding Register -#define AT91C_SSC1_TFMR ((AT91_REG *) 0xFFFD401C) // (SSC1) Transmit Frame Mode Register -// ========== Register definition for PDC_SSC0 peripheral ========== -#define AT91C_SSC0_PTCR ((AT91_REG *) 0xFFFD0120) // (PDC_SSC0) PDC Transfer Control Register -#define AT91C_SSC0_TNPR ((AT91_REG *) 0xFFFD0118) // (PDC_SSC0) Transmit Next Pointer Register -#define AT91C_SSC0_RNPR ((AT91_REG *) 0xFFFD0110) // (PDC_SSC0) Receive Next Pointer Register -#define AT91C_SSC0_TPR ((AT91_REG *) 0xFFFD0108) // (PDC_SSC0) Transmit Pointer Register -#define AT91C_SSC0_RPR ((AT91_REG *) 0xFFFD0100) // (PDC_SSC0) Receive Pointer Register -#define AT91C_SSC0_PTSR ((AT91_REG *) 0xFFFD0124) // (PDC_SSC0) PDC Transfer Status Register -#define AT91C_SSC0_TNCR ((AT91_REG *) 0xFFFD011C) // (PDC_SSC0) Transmit Next Counter Register -#define AT91C_SSC0_RNCR ((AT91_REG *) 0xFFFD0114) // (PDC_SSC0) Receive Next Counter Register -#define AT91C_SSC0_TCR ((AT91_REG *) 0xFFFD010C) // (PDC_SSC0) Transmit Counter Register -#define AT91C_SSC0_RCR ((AT91_REG *) 0xFFFD0104) // (PDC_SSC0) Receive Counter Register -// ========== Register definition for SSC0 peripheral ========== -#define AT91C_SSC0_IMR ((AT91_REG *) 0xFFFD004C) // (SSC0) Interrupt Mask Register -#define AT91C_SSC0_IER ((AT91_REG *) 0xFFFD0044) // (SSC0) Interrupt Enable Register -#define AT91C_SSC0_RC1R ((AT91_REG *) 0xFFFD003C) // (SSC0) Receive Compare 1 Register -#define AT91C_SSC0_TSHR ((AT91_REG *) 0xFFFD0034) // (SSC0) Transmit Sync Holding Register -#define AT91C_SSC0_THR ((AT91_REG *) 0xFFFD0024) // (SSC0) Transmit Holding Register -#define AT91C_SSC0_TFMR ((AT91_REG *) 0xFFFD001C) // (SSC0) Transmit Frame Mode Register -#define AT91C_SSC0_RFMR ((AT91_REG *) 0xFFFD0014) // (SSC0) Receive Frame Mode Register -#define AT91C_SSC0_CMR ((AT91_REG *) 0xFFFD0004) // (SSC0) Clock Mode Register -#define AT91C_SSC0_IDR ((AT91_REG *) 0xFFFD0048) // (SSC0) Interrupt Disable Register -#define AT91C_SSC0_SR ((AT91_REG *) 0xFFFD0040) // (SSC0) Status Register -#define AT91C_SSC0_RC0R ((AT91_REG *) 0xFFFD0038) // (SSC0) Receive Compare 0 Register -#define AT91C_SSC0_RSHR ((AT91_REG *) 0xFFFD0030) // (SSC0) Receive Sync Holding Register -#define AT91C_SSC0_RHR ((AT91_REG *) 0xFFFD0020) // (SSC0) Receive Holding Register -#define AT91C_SSC0_TCMR ((AT91_REG *) 0xFFFD0018) // (SSC0) Transmit Clock Mode Register -#define AT91C_SSC0_RCMR ((AT91_REG *) 0xFFFD0010) // (SSC0) Receive Clock ModeRegister -#define AT91C_SSC0_CR ((AT91_REG *) 0xFFFD0000) // (SSC0) Control Register -// ========== Register definition for PDC_US3 peripheral ========== -#define AT91C_US3_PTSR ((AT91_REG *) 0xFFFCC124) // (PDC_US3) PDC Transfer Status Register -#define AT91C_US3_TNCR ((AT91_REG *) 0xFFFCC11C) // (PDC_US3) Transmit Next Counter Register -#define AT91C_US3_RNCR ((AT91_REG *) 0xFFFCC114) // (PDC_US3) Receive Next Counter Register -#define AT91C_US3_TCR ((AT91_REG *) 0xFFFCC10C) // (PDC_US3) Transmit Counter Register -#define AT91C_US3_RCR ((AT91_REG *) 0xFFFCC104) // (PDC_US3) Receive Counter Register -#define AT91C_US3_PTCR ((AT91_REG *) 0xFFFCC120) // (PDC_US3) PDC Transfer Control Register -#define AT91C_US3_TNPR ((AT91_REG *) 0xFFFCC118) // (PDC_US3) Transmit Next Pointer Register -#define AT91C_US3_RNPR ((AT91_REG *) 0xFFFCC110) // (PDC_US3) Receive Next Pointer Register -#define AT91C_US3_TPR ((AT91_REG *) 0xFFFCC108) // (PDC_US3) Transmit Pointer Register -#define AT91C_US3_RPR ((AT91_REG *) 0xFFFCC100) // (PDC_US3) Receive Pointer Register -// ========== Register definition for US3 peripheral ========== -#define AT91C_US3_IF ((AT91_REG *) 0xFFFCC04C) // (US3) IRDA_FILTER Register -#define AT91C_US3_NER ((AT91_REG *) 0xFFFCC044) // (US3) Nb Errors Register -#define AT91C_US3_RTOR ((AT91_REG *) 0xFFFCC024) // (US3) Receiver Time-out Register -#define AT91C_US3_THR ((AT91_REG *) 0xFFFCC01C) // (US3) Transmitter Holding Register -#define AT91C_US3_CSR ((AT91_REG *) 0xFFFCC014) // (US3) Channel Status Register -#define AT91C_US3_IDR ((AT91_REG *) 0xFFFCC00C) // (US3) Interrupt Disable Register -#define AT91C_US3_MR ((AT91_REG *) 0xFFFCC004) // (US3) Mode Register -#define AT91C_US3_XXR ((AT91_REG *) 0xFFFCC048) // (US3) XON_XOFF Register -#define AT91C_US3_FIDI ((AT91_REG *) 0xFFFCC040) // (US3) FI_DI_Ratio Register -#define AT91C_US3_TTGR ((AT91_REG *) 0xFFFCC028) // (US3) Transmitter Time-guard Register -#define AT91C_US3_BRGR ((AT91_REG *) 0xFFFCC020) // (US3) Baud Rate Generator Register -#define AT91C_US3_RHR ((AT91_REG *) 0xFFFCC018) // (US3) Receiver Holding Register -#define AT91C_US3_IMR ((AT91_REG *) 0xFFFCC010) // (US3) Interrupt Mask Register -#define AT91C_US3_IER ((AT91_REG *) 0xFFFCC008) // (US3) Interrupt Enable Register -#define AT91C_US3_CR ((AT91_REG *) 0xFFFCC000) // (US3) Control Register -// ========== Register definition for PDC_US2 peripheral ========== -#define AT91C_US2_PTSR ((AT91_REG *) 0xFFFC8124) // (PDC_US2) PDC Transfer Status Register -#define AT91C_US2_TNCR ((AT91_REG *) 0xFFFC811C) // (PDC_US2) Transmit Next Counter Register -#define AT91C_US2_RNCR ((AT91_REG *) 0xFFFC8114) // (PDC_US2) Receive Next Counter Register -#define AT91C_US2_TCR ((AT91_REG *) 0xFFFC810C) // (PDC_US2) Transmit Counter Register -#define AT91C_US2_PTCR ((AT91_REG *) 0xFFFC8120) // (PDC_US2) PDC Transfer Control Register -#define AT91C_US2_RCR ((AT91_REG *) 0xFFFC8104) // (PDC_US2) Receive Counter Register -#define AT91C_US2_TNPR ((AT91_REG *) 0xFFFC8118) // (PDC_US2) Transmit Next Pointer Register -#define AT91C_US2_RPR ((AT91_REG *) 0xFFFC8100) // (PDC_US2) Receive Pointer Register -#define AT91C_US2_TPR ((AT91_REG *) 0xFFFC8108) // (PDC_US2) Transmit Pointer Register -#define AT91C_US2_RNPR ((AT91_REG *) 0xFFFC8110) // (PDC_US2) Receive Next Pointer Register -// ========== Register definition for US2 peripheral ========== -#define AT91C_US2_XXR ((AT91_REG *) 0xFFFC8048) // (US2) XON_XOFF Register -#define AT91C_US2_FIDI ((AT91_REG *) 0xFFFC8040) // (US2) FI_DI_Ratio Register -#define AT91C_US2_TTGR ((AT91_REG *) 0xFFFC8028) // (US2) Transmitter Time-guard Register -#define AT91C_US2_BRGR ((AT91_REG *) 0xFFFC8020) // (US2) Baud Rate Generator Register -#define AT91C_US2_RHR ((AT91_REG *) 0xFFFC8018) // (US2) Receiver Holding Register -#define AT91C_US2_IMR ((AT91_REG *) 0xFFFC8010) // (US2) Interrupt Mask Register -#define AT91C_US2_IER ((AT91_REG *) 0xFFFC8008) // (US2) Interrupt Enable Register -#define AT91C_US2_CR ((AT91_REG *) 0xFFFC8000) // (US2) Control Register -#define AT91C_US2_IF ((AT91_REG *) 0xFFFC804C) // (US2) IRDA_FILTER Register -#define AT91C_US2_NER ((AT91_REG *) 0xFFFC8044) // (US2) Nb Errors Register -#define AT91C_US2_RTOR ((AT91_REG *) 0xFFFC8024) // (US2) Receiver Time-out Register -#define AT91C_US2_THR ((AT91_REG *) 0xFFFC801C) // (US2) Transmitter Holding Register -#define AT91C_US2_CSR ((AT91_REG *) 0xFFFC8014) // (US2) Channel Status Register -#define AT91C_US2_IDR ((AT91_REG *) 0xFFFC800C) // (US2) Interrupt Disable Register -#define AT91C_US2_MR ((AT91_REG *) 0xFFFC8004) // (US2) Mode Register -// ========== Register definition for PDC_US1 peripheral ========== -#define AT91C_US1_PTSR ((AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register -#define AT91C_US1_TNCR ((AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register -#define AT91C_US1_RNCR ((AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register -#define AT91C_US1_TCR ((AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register -#define AT91C_US1_RCR ((AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register -#define AT91C_US1_PTCR ((AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register -#define AT91C_US1_TNPR ((AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register -#define AT91C_US1_RNPR ((AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register -#define AT91C_US1_TPR ((AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register -#define AT91C_US1_RPR ((AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register -// ========== Register definition for US1 peripheral ========== -#define AT91C_US1_XXR ((AT91_REG *) 0xFFFC4048) // (US1) XON_XOFF Register -#define AT91C_US1_RHR ((AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register -#define AT91C_US1_IMR ((AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register -#define AT91C_US1_IER ((AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register -#define AT91C_US1_CR ((AT91_REG *) 0xFFFC4000) // (US1) Control Register -#define AT91C_US1_RTOR ((AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register -#define AT91C_US1_THR ((AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register -#define AT91C_US1_CSR ((AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register -#define AT91C_US1_IDR ((AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register -#define AT91C_US1_FIDI ((AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register -#define AT91C_US1_BRGR ((AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register -#define AT91C_US1_TTGR ((AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register -#define AT91C_US1_IF ((AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register -#define AT91C_US1_NER ((AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register -#define AT91C_US1_MR ((AT91_REG *) 0xFFFC4004) // (US1) Mode Register -// ========== Register definition for PDC_US0 peripheral ========== -#define AT91C_US0_PTCR ((AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register -#define AT91C_US0_TNPR ((AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register -#define AT91C_US0_RNPR ((AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register -#define AT91C_US0_TPR ((AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register -#define AT91C_US0_RPR ((AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register -#define AT91C_US0_PTSR ((AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register -#define AT91C_US0_TNCR ((AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register -#define AT91C_US0_RNCR ((AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register -#define AT91C_US0_TCR ((AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register -#define AT91C_US0_RCR ((AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register -// ========== Register definition for US0 peripheral ========== -#define AT91C_US0_TTGR ((AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register -#define AT91C_US0_BRGR ((AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register -#define AT91C_US0_RHR ((AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register -#define AT91C_US0_IMR ((AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register -#define AT91C_US0_NER ((AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register -#define AT91C_US0_RTOR ((AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register -#define AT91C_US0_XXR ((AT91_REG *) 0xFFFC0048) // (US0) XON_XOFF Register -#define AT91C_US0_FIDI ((AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register -#define AT91C_US0_CR ((AT91_REG *) 0xFFFC0000) // (US0) Control Register -#define AT91C_US0_IER ((AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register -#define AT91C_US0_IF ((AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register -#define AT91C_US0_MR ((AT91_REG *) 0xFFFC0004) // (US0) Mode Register -#define AT91C_US0_IDR ((AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register -#define AT91C_US0_CSR ((AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register -#define AT91C_US0_THR ((AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register -// ========== Register definition for TWI peripheral ========== -#define AT91C_TWI_RHR ((AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register -#define AT91C_TWI_IDR ((AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register -#define AT91C_TWI_SR ((AT91_REG *) 0xFFFB8020) // (TWI) Status Register -#define AT91C_TWI_CWGR ((AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register -#define AT91C_TWI_SMR ((AT91_REG *) 0xFFFB8008) // (TWI) Slave Mode Register -#define AT91C_TWI_CR ((AT91_REG *) 0xFFFB8000) // (TWI) Control Register -#define AT91C_TWI_THR ((AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register -#define AT91C_TWI_IMR ((AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register -#define AT91C_TWI_IER ((AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register -#define AT91C_TWI_IADR ((AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register -#define AT91C_TWI_MMR ((AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register -// ========== Register definition for PDC_MCI peripheral ========== -#define AT91C_MCI_PTCR ((AT91_REG *) 0xFFFB4120) // (PDC_MCI) PDC Transfer Control Register -#define AT91C_MCI_TNPR ((AT91_REG *) 0xFFFB4118) // (PDC_MCI) Transmit Next Pointer Register -#define AT91C_MCI_RNPR ((AT91_REG *) 0xFFFB4110) // (PDC_MCI) Receive Next Pointer Register -#define AT91C_MCI_TPR ((AT91_REG *) 0xFFFB4108) // (PDC_MCI) Transmit Pointer Register -#define AT91C_MCI_RPR ((AT91_REG *) 0xFFFB4100) // (PDC_MCI) Receive Pointer Register -#define AT91C_MCI_PTSR ((AT91_REG *) 0xFFFB4124) // (PDC_MCI) PDC Transfer Status Register -#define AT91C_MCI_TNCR ((AT91_REG *) 0xFFFB411C) // (PDC_MCI) Transmit Next Counter Register -#define AT91C_MCI_RNCR ((AT91_REG *) 0xFFFB4114) // (PDC_MCI) Receive Next Counter Register -#define AT91C_MCI_TCR ((AT91_REG *) 0xFFFB410C) // (PDC_MCI) Transmit Counter Register -#define AT91C_MCI_RCR ((AT91_REG *) 0xFFFB4104) // (PDC_MCI) Receive Counter Register -// ========== Register definition for MCI peripheral ========== -#define AT91C_MCI_IDR ((AT91_REG *) 0xFFFB4048) // (MCI) MCI Interrupt Disable Register -#define AT91C_MCI_SR ((AT91_REG *) 0xFFFB4040) // (MCI) MCI Status Register -#define AT91C_MCI_RDR ((AT91_REG *) 0xFFFB4030) // (MCI) MCI Receive Data Register -#define AT91C_MCI_RSPR ((AT91_REG *) 0xFFFB4020) // (MCI) MCI Response Register -#define AT91C_MCI_ARGR ((AT91_REG *) 0xFFFB4010) // (MCI) MCI Argument Register -#define AT91C_MCI_DTOR ((AT91_REG *) 0xFFFB4008) // (MCI) MCI Data Timeout Register -#define AT91C_MCI_CR ((AT91_REG *) 0xFFFB4000) // (MCI) MCI Control Register -#define AT91C_MCI_IMR ((AT91_REG *) 0xFFFB404C) // (MCI) MCI Interrupt Mask Register -#define AT91C_MCI_IER ((AT91_REG *) 0xFFFB4044) // (MCI) MCI Interrupt Enable Register -#define AT91C_MCI_TDR ((AT91_REG *) 0xFFFB4034) // (MCI) MCI Transmit Data Register -#define AT91C_MCI_CMDR ((AT91_REG *) 0xFFFB4014) // (MCI) MCI Command Register -#define AT91C_MCI_SDCR ((AT91_REG *) 0xFFFB400C) // (MCI) MCI SD Card Register -#define AT91C_MCI_MR ((AT91_REG *) 0xFFFB4004) // (MCI) MCI Mode Register -// ========== Register definition for UDP peripheral ========== -#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register -#define AT91C_UDP_IDR ((AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register -#define AT91C_UDP_GLBSTATE ((AT91_REG *) 0xFFFB0004) // (UDP) Global State Register -#define AT91C_UDP_FDR ((AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register -#define AT91C_UDP_CSR ((AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register -#define AT91C_UDP_RSTEP ((AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register -#define AT91C_UDP_ICR ((AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register -#define AT91C_UDP_IMR ((AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register -#define AT91C_UDP_IER ((AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register -#define AT91C_UDP_FADDR ((AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register -#define AT91C_UDP_NUM ((AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register -// ========== Register definition for TC5 peripheral ========== -#define AT91C_TC5_CMR ((AT91_REG *) 0xFFFA4084) // (TC5) Channel Mode Register -#define AT91C_TC5_IDR ((AT91_REG *) 0xFFFA40A8) // (TC5) Interrupt Disable Register -#define AT91C_TC5_SR ((AT91_REG *) 0xFFFA40A0) // (TC5) Status Register -#define AT91C_TC5_RB ((AT91_REG *) 0xFFFA4098) // (TC5) Register B -#define AT91C_TC5_CV ((AT91_REG *) 0xFFFA4090) // (TC5) Counter Value -#define AT91C_TC5_CCR ((AT91_REG *) 0xFFFA4080) // (TC5) Channel Control Register -#define AT91C_TC5_IMR ((AT91_REG *) 0xFFFA40AC) // (TC5) Interrupt Mask Register -#define AT91C_TC5_IER ((AT91_REG *) 0xFFFA40A4) // (TC5) Interrupt Enable Register -#define AT91C_TC5_RC ((AT91_REG *) 0xFFFA409C) // (TC5) Register C -#define AT91C_TC5_RA ((AT91_REG *) 0xFFFA4094) // (TC5) Register A -// ========== Register definition for TC4 peripheral ========== -#define AT91C_TC4_IMR ((AT91_REG *) 0xFFFA406C) // (TC4) Interrupt Mask Register -#define AT91C_TC4_IER ((AT91_REG *) 0xFFFA4064) // (TC4) Interrupt Enable Register -#define AT91C_TC4_RC ((AT91_REG *) 0xFFFA405C) // (TC4) Register C -#define AT91C_TC4_RA ((AT91_REG *) 0xFFFA4054) // (TC4) Register A -#define AT91C_TC4_CMR ((AT91_REG *) 0xFFFA4044) // (TC4) Channel Mode Register -#define AT91C_TC4_IDR ((AT91_REG *) 0xFFFA4068) // (TC4) Interrupt Disable Register -#define AT91C_TC4_SR ((AT91_REG *) 0xFFFA4060) // (TC4) Status Register -#define AT91C_TC4_RB ((AT91_REG *) 0xFFFA4058) // (TC4) Register B -#define AT91C_TC4_CV ((AT91_REG *) 0xFFFA4050) // (TC4) Counter Value -#define AT91C_TC4_CCR ((AT91_REG *) 0xFFFA4040) // (TC4) Channel Control Register -// ========== Register definition for TC3 peripheral ========== -#define AT91C_TC3_IMR ((AT91_REG *) 0xFFFA402C) // (TC3) Interrupt Mask Register -#define AT91C_TC3_CV ((AT91_REG *) 0xFFFA4010) // (TC3) Counter Value -#define AT91C_TC3_CCR ((AT91_REG *) 0xFFFA4000) // (TC3) Channel Control Register -#define AT91C_TC3_IER ((AT91_REG *) 0xFFFA4024) // (TC3) Interrupt Enable Register -#define AT91C_TC3_CMR ((AT91_REG *) 0xFFFA4004) // (TC3) Channel Mode Register -#define AT91C_TC3_RA ((AT91_REG *) 0xFFFA4014) // (TC3) Register A -#define AT91C_TC3_RC ((AT91_REG *) 0xFFFA401C) // (TC3) Register C -#define AT91C_TC3_IDR ((AT91_REG *) 0xFFFA4028) // (TC3) Interrupt Disable Register -#define AT91C_TC3_RB ((AT91_REG *) 0xFFFA4018) // (TC3) Register B -#define AT91C_TC3_SR ((AT91_REG *) 0xFFFA4020) // (TC3) Status Register -// ========== Register definition for TCB1 peripheral ========== -#define AT91C_TCB1_BCR ((AT91_REG *) 0xFFFA4140) // (TCB1) TC Block Control Register -#define AT91C_TCB1_BMR ((AT91_REG *) 0xFFFA4144) // (TCB1) TC Block Mode Register -// ========== Register definition for TC2 peripheral ========== -#define AT91C_TC2_IMR ((AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register -#define AT91C_TC2_IER ((AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register -#define AT91C_TC2_RC ((AT91_REG *) 0xFFFA009C) // (TC2) Register C -#define AT91C_TC2_RA ((AT91_REG *) 0xFFFA0094) // (TC2) Register A -#define AT91C_TC2_CMR ((AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register -#define AT91C_TC2_IDR ((AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register -#define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register -#define AT91C_TC2_RB ((AT91_REG *) 0xFFFA0098) // (TC2) Register B -#define AT91C_TC2_CV ((AT91_REG *) 0xFFFA0090) // (TC2) Counter Value -#define AT91C_TC2_CCR ((AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register -// ========== Register definition for TC1 peripheral ========== -#define AT91C_TC1_IMR ((AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register -#define AT91C_TC1_IER ((AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register -#define AT91C_TC1_RC ((AT91_REG *) 0xFFFA005C) // (TC1) Register C -#define AT91C_TC1_RA ((AT91_REG *) 0xFFFA0054) // (TC1) Register A -#define AT91C_TC1_CMR ((AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register -#define AT91C_TC1_IDR ((AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register -#define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register -#define AT91C_TC1_RB ((AT91_REG *) 0xFFFA0058) // (TC1) Register B -#define AT91C_TC1_CV ((AT91_REG *) 0xFFFA0050) // (TC1) Counter Value -#define AT91C_TC1_CCR ((AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register -// ========== Register definition for TC0 peripheral ========== -#define AT91C_TC0_IMR ((AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register -#define AT91C_TC0_IER ((AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register -#define AT91C_TC0_RC ((AT91_REG *) 0xFFFA001C) // (TC0) Register C -#define AT91C_TC0_RA ((AT91_REG *) 0xFFFA0014) // (TC0) Register A -#define AT91C_TC0_CMR ((AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register -#define AT91C_TC0_IDR ((AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register -#define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register -#define AT91C_TC0_RB ((AT91_REG *) 0xFFFA0018) // (TC0) Register B -#define AT91C_TC0_CV ((AT91_REG *) 0xFFFA0010) // (TC0) Counter Value -#define AT91C_TC0_CCR ((AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register -// ========== Register definition for TCB0 peripheral ========== -#define AT91C_TCB0_BMR ((AT91_REG *) 0xFFFA00C4) // (TCB0) TC Block Mode Register -#define AT91C_TCB0_BCR ((AT91_REG *) 0xFFFA00C0) // (TCB0) TC Block Control Register -// ========== Register definition for UHP peripheral ========== -#define AT91C_UHP_HcRhDescriptorA ((AT91_REG *) 0x00300048) // (UHP) Root Hub characteristics A -#define AT91C_UHP_HcRhPortStatus ((AT91_REG *) 0x00300054) // (UHP) Root Hub Port Status Register -#define AT91C_UHP_HcRhDescriptorB ((AT91_REG *) 0x0030004C) // (UHP) Root Hub characteristics B -#define AT91C_UHP_HcControl ((AT91_REG *) 0x00300004) // (UHP) Operating modes for the Host Controller -#define AT91C_UHP_HcInterruptStatus ((AT91_REG *) 0x0030000C) // (UHP) Interrupt Status Register -#define AT91C_UHP_HcRhStatus ((AT91_REG *) 0x00300050) // (UHP) Root Hub Status register -#define AT91C_UHP_HcRevision ((AT91_REG *) 0x00300000) // (UHP) Revision -#define AT91C_UHP_HcCommandStatus ((AT91_REG *) 0x00300008) // (UHP) Command & status Register -#define AT91C_UHP_HcInterruptEnable ((AT91_REG *) 0x00300010) // (UHP) Interrupt Enable Register -#define AT91C_UHP_HcHCCA ((AT91_REG *) 0x00300018) // (UHP) Pointer to the Host Controller Communication Area -#define AT91C_UHP_HcControlHeadED ((AT91_REG *) 0x00300020) // (UHP) First Endpoint Descriptor of the Control list -#define AT91C_UHP_HcInterruptDisable ((AT91_REG *) 0x00300014) // (UHP) Interrupt Disable Register -#define AT91C_UHP_HcPeriodCurrentED ((AT91_REG *) 0x0030001C) // (UHP) Current Isochronous or Interrupt Endpoint Descriptor -#define AT91C_UHP_HcControlCurrentED ((AT91_REG *) 0x00300024) // (UHP) Endpoint Control and Status Register -#define AT91C_UHP_HcBulkCurrentED ((AT91_REG *) 0x0030002C) // (UHP) Current endpoint of the Bulk list -#define AT91C_UHP_HcFmInterval ((AT91_REG *) 0x00300034) // (UHP) Bit time between 2 consecutive SOFs -#define AT91C_UHP_HcBulkHeadED ((AT91_REG *) 0x00300028) // (UHP) First endpoint register of the Bulk list -#define AT91C_UHP_HcBulkDoneHead ((AT91_REG *) 0x00300030) // (UHP) Last completed transfer descriptor -#define AT91C_UHP_HcFmRemaining ((AT91_REG *) 0x00300038) // (UHP) Bit time remaining in the current Frame -#define AT91C_UHP_HcPeriodicStart ((AT91_REG *) 0x00300040) // (UHP) Periodic Start -#define AT91C_UHP_HcLSThreshold ((AT91_REG *) 0x00300044) // (UHP) LS Threshold -#define AT91C_UHP_HcFmNumber ((AT91_REG *) 0x0030003C) // (UHP) Frame number -// ========== Register definition for EMAC peripheral ========== -#define AT91C_EMAC_RSR ((AT91_REG *) 0xFFFBC020) // (EMAC) Receive Status Register -#define AT91C_EMAC_MAN ((AT91_REG *) 0xFFFBC034) // (EMAC) PHY Maintenance Register -#define AT91C_EMAC_HSH ((AT91_REG *) 0xFFFBC090) // (EMAC) Hash Address High[63:32] -#define AT91C_EMAC_MCOL ((AT91_REG *) 0xFFFBC048) // (EMAC) Multiple Collision Frame Register -#define AT91C_EMAC_IER ((AT91_REG *) 0xFFFBC028) // (EMAC) Interrupt Enable Register -#define AT91C_EMAC_SA2H ((AT91_REG *) 0xFFFBC0A4) // (EMAC) Specific Address 2 High, Last 2 bytes -#define AT91C_EMAC_HSL ((AT91_REG *) 0xFFFBC094) // (EMAC) Hash Address Low[31:0] -#define AT91C_EMAC_LCOL ((AT91_REG *) 0xFFFBC05C) // (EMAC) Late Collision Register -#define AT91C_EMAC_OK ((AT91_REG *) 0xFFFBC04C) // (EMAC) Frames Received OK Register -#define AT91C_EMAC_CFG ((AT91_REG *) 0xFFFBC004) // (EMAC) Network Configuration Register -#define AT91C_EMAC_SA3L ((AT91_REG *) 0xFFFBC0A8) // (EMAC) Specific Address 3 Low, First 4 bytes -#define AT91C_EMAC_SEQE ((AT91_REG *) 0xFFFBC050) // (EMAC) Frame Check Sequence Error Register -#define AT91C_EMAC_ECOL ((AT91_REG *) 0xFFFBC060) // (EMAC) Excessive Collision Register -#define AT91C_EMAC_ELR ((AT91_REG *) 0xFFFBC070) // (EMAC) Excessive Length Error Register -#define AT91C_EMAC_SR ((AT91_REG *) 0xFFFBC008) // (EMAC) Network Status Register -#define AT91C_EMAC_RBQP ((AT91_REG *) 0xFFFBC018) // (EMAC) Receive Buffer Queue Pointer -#define AT91C_EMAC_CSE ((AT91_REG *) 0xFFFBC064) // (EMAC) Carrier Sense Error Register -#define AT91C_EMAC_RJB ((AT91_REG *) 0xFFFBC074) // (EMAC) Receive Jabber Register -#define AT91C_EMAC_USF ((AT91_REG *) 0xFFFBC078) // (EMAC) Undersize Frame Register -#define AT91C_EMAC_IDR ((AT91_REG *) 0xFFFBC02C) // (EMAC) Interrupt Disable Register -#define AT91C_EMAC_SA1L ((AT91_REG *) 0xFFFBC098) // (EMAC) Specific Address 1 Low, First 4 bytes -#define AT91C_EMAC_IMR ((AT91_REG *) 0xFFFBC030) // (EMAC) Interrupt Mask Register -#define AT91C_EMAC_FRA ((AT91_REG *) 0xFFFBC040) // (EMAC) Frames Transmitted OK Register -#define AT91C_EMAC_SA3H ((AT91_REG *) 0xFFFBC0AC) // (EMAC) Specific Address 3 High, Last 2 bytes -#define AT91C_EMAC_SA1H ((AT91_REG *) 0xFFFBC09C) // (EMAC) Specific Address 1 High, Last 2 bytes -#define AT91C_EMAC_SCOL ((AT91_REG *) 0xFFFBC044) // (EMAC) Single Collision Frame Register -#define AT91C_EMAC_ALE ((AT91_REG *) 0xFFFBC054) // (EMAC) Alignment Error Register -#define AT91C_EMAC_TAR ((AT91_REG *) 0xFFFBC00C) // (EMAC) Transmit Address Register -#define AT91C_EMAC_SA4L ((AT91_REG *) 0xFFFBC0B0) // (EMAC) Specific Address 4 Low, First 4 bytes -#define AT91C_EMAC_SA2L ((AT91_REG *) 0xFFFBC0A0) // (EMAC) Specific Address 2 Low, First 4 bytes -#define AT91C_EMAC_TUE ((AT91_REG *) 0xFFFBC068) // (EMAC) Transmit Underrun Error Register -#define AT91C_EMAC_DTE ((AT91_REG *) 0xFFFBC058) // (EMAC) Deferred Transmission Frame Register -#define AT91C_EMAC_TCR ((AT91_REG *) 0xFFFBC010) // (EMAC) Transmit Control Register -#define AT91C_EMAC_CTL ((AT91_REG *) 0xFFFBC000) // (EMAC) Network Control Register -#define AT91C_EMAC_SA4H ((AT91_REG *) 0xFFFBC0B4) // (EMAC) Specific Address 4 High, Last 2 bytesr -#define AT91C_EMAC_CDE ((AT91_REG *) 0xFFFBC06C) // (EMAC) Code Error Register -#define AT91C_EMAC_SQEE ((AT91_REG *) 0xFFFBC07C) // (EMAC) SQE Test Error Register -#define AT91C_EMAC_TSR ((AT91_REG *) 0xFFFBC014) // (EMAC) Transmit Status Register -#define AT91C_EMAC_DRFC ((AT91_REG *) 0xFFFBC080) // (EMAC) Discarded RX Frame Register -// ========== Register definition for EBI peripheral ========== -#define AT91C_EBI_CFGR ((AT91_REG *) 0xFFFFFF64) // (EBI) Configuration Register -#define AT91C_EBI_CSA ((AT91_REG *) 0xFFFFFF60) // (EBI) Chip Select Assignment Register -// ========== Register definition for SMC2 peripheral ========== -#define AT91C_SMC2_CSR ((AT91_REG *) 0xFFFFFF70) // (SMC2) SMC2 Chip Select Register -// ========== Register definition for SDRC peripheral ========== -#define AT91C_SDRC_IMR ((AT91_REG *) 0xFFFFFFAC) // (SDRC) SDRAM Controller Interrupt Mask Register -#define AT91C_SDRC_IER ((AT91_REG *) 0xFFFFFFA4) // (SDRC) SDRAM Controller Interrupt Enable Register -#define AT91C_SDRC_SRR ((AT91_REG *) 0xFFFFFF9C) // (SDRC) SDRAM Controller Self Refresh Register -#define AT91C_SDRC_TR ((AT91_REG *) 0xFFFFFF94) // (SDRC) SDRAM Controller Refresh Timer Register -#define AT91C_SDRC_ISR ((AT91_REG *) 0xFFFFFFB0) // (SDRC) SDRAM Controller Interrupt Mask Register -#define AT91C_SDRC_IDR ((AT91_REG *) 0xFFFFFFA8) // (SDRC) SDRAM Controller Interrupt Disable Register -#define AT91C_SDRC_LPR ((AT91_REG *) 0xFFFFFFA0) // (SDRC) SDRAM Controller Low Power Register -#define AT91C_SDRC_CR ((AT91_REG *) 0xFFFFFF98) // (SDRC) SDRAM Controller Configuration Register -#define AT91C_SDRC_MR ((AT91_REG *) 0xFFFFFF90) // (SDRC) SDRAM Controller Mode Register -// ========== Register definition for BFC peripheral ========== -#define AT91C_BFC_MR ((AT91_REG *) 0xFFFFFFC0) // (BFC) BFC Mode Register - -#include - -// ***************************************************************************** -// PERIPHERAL ID DEFINITIONS FOR AT91RM9200 -// ***************************************************************************** -#define AT91C_ID_FIQ 0u // Advanced Interrupt Controller (FIQ) -#define AT91C_ID_SYS 1u // System Peripheral -#define AT91C_ID_PIOA 2u // Parallel IO Controller A -#define AT91C_ID_PIOB 3u // Parallel IO Controller B -#define AT91C_ID_PIOC 4u // Parallel IO Controller C -#define AT91C_ID_PIOD 5u // Parallel IO Controller D -#define AT91C_ID_US0 6u // USART 0 -#define AT91C_ID_US1 7u // USART 1 -#define AT91C_ID_US2 8u // USART 2 -#define AT91C_ID_US3 9u // USART 3 -#define AT91C_ID_MCI 10u // Multimedia Card Interface -#define AT91C_ID_UDP 11u // USB Device Port -#define AT91C_ID_TWI 12u // Two-Wire Interface -#define AT91C_ID_SPI 13u // Serial Peripheral Interface -#define AT91C_ID_SSC0 14u // Serial Synchronous Controller 0 -#define AT91C_ID_SSC1 15u // Serial Synchronous Controller 1 -#define AT91C_ID_SSC2 16u // Serial Synchronous Controller 2 -#define AT91C_ID_TC0 17u // Timer Counter 0 -#define AT91C_ID_TC1 18u // Timer Counter 1 -#define AT91C_ID_TC2 19u // Timer Counter 2 -#define AT91C_ID_TC3 20u // Timer Counter 3 -#define AT91C_ID_TC4 21u // Timer Counter 4 -#define AT91C_ID_TC5 22u // Timer Counter 5 -#define AT91C_ID_UHP 23u // USB Host port -#define AT91C_ID_EMAC 24u // Ethernet MAC -#define AT91C_ID_IRQ0 25u // Advanced Interrupt Controller (IRQ0) -#define AT91C_ID_IRQ1 26u // Advanced Interrupt Controller (IRQ1) -#define AT91C_ID_IRQ2 27u // Advanced Interrupt Controller (IRQ2) -#define AT91C_ID_IRQ3 28u // Advanced Interrupt Controller (IRQ3) -#define AT91C_ID_IRQ4 29u // Advanced Interrupt Controller (IRQ4) -#define AT91C_ID_IRQ5 30u // Advanced Interrupt Controller (IRQ5) -#define AT91C_ID_IRQ6 31u // Advanced Interrupt Controller (IRQ6) - -// ***************************************************************************** -// BASE ADDRESS DEFINITIONS FOR AT91RM9200 -// ***************************************************************************** -#define AT91C_BASE_SYS ((AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address -#define AT91C_BASE_MC ((AT91PS_MC) 0xFFFFFF00) // (MC) Base Address -#define AT91C_BASE_RTC ((AT91PS_RTC) 0xFFFFFE00) // (RTC) Base Address -#define AT91C_BASE_ST ((AT91PS_ST) 0xFFFFFD00) // (ST) Base Address -#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address -#define AT91C_BASE_CKGR ((AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address -#define AT91C_BASE_PIOD ((AT91PS_PIO) 0xFFFFFA00) // (PIOD) Base Address -#define AT91C_BASE_PIOC ((AT91PS_PIO) 0xFFFFF800) // (PIOC) Base Address -#define AT91C_BASE_PIOB ((AT91PS_PIO) 0xFFFFF600) // (PIOB) Base Address -#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address -#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address -#define AT91C_BASE_PDC_DBGU ((AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address -#define AT91C_BASE_AIC ((AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address -#define AT91C_BASE_PDC_SPI ((AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address -#define AT91C_BASE_SPI ((AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address -#define AT91C_BASE_PDC_SSC2 ((AT91PS_PDC) 0xFFFD8100) // (PDC_SSC2) Base Address -#define AT91C_BASE_SSC2 ((AT91PS_SSC) 0xFFFD8000) // (SSC2) Base Address -#define AT91C_BASE_PDC_SSC1 ((AT91PS_PDC) 0xFFFD4100) // (PDC_SSC1) Base Address -#define AT91C_BASE_SSC1 ((AT91PS_SSC) 0xFFFD4000) // (SSC1) Base Address -#define AT91C_BASE_PDC_SSC0 ((AT91PS_PDC) 0xFFFD0100) // (PDC_SSC0) Base Address -#define AT91C_BASE_SSC0 ((AT91PS_SSC) 0xFFFD0000) // (SSC0) Base Address -#define AT91C_BASE_PDC_US3 ((AT91PS_PDC) 0xFFFCC100) // (PDC_US3) Base Address -#define AT91C_BASE_US3 ((AT91PS_USART) 0xFFFCC000) // (US3) Base Address -#define AT91C_BASE_PDC_US2 ((AT91PS_PDC) 0xFFFC8100) // (PDC_US2) Base Address -#define AT91C_BASE_US2 ((AT91PS_USART) 0xFFFC8000) // (US2) Base Address -#define AT91C_BASE_PDC_US1 ((AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address -#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) // (US1) Base Address -#define AT91C_BASE_PDC_US0 ((AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address -#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) // (US0) Base Address -#define AT91C_BASE_TWI ((AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address -#define AT91C_BASE_PDC_MCI ((AT91PS_PDC) 0xFFFB4100) // (PDC_MCI) Base Address -#define AT91C_BASE_MCI ((AT91PS_MCI) 0xFFFB4000) // (MCI) Base Address -#define AT91C_BASE_UDP ((AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address -#define AT91C_BASE_TC5 ((AT91PS_TC) 0xFFFA4080) // (TC5) Base Address -#define AT91C_BASE_TC4 ((AT91PS_TC) 0xFFFA4040) // (TC4) Base Address -#define AT91C_BASE_TC3 ((AT91PS_TC) 0xFFFA4000) // (TC3) Base Address -#define AT91C_BASE_TCB1 ((AT91PS_TCB) 0xFFFA4080) // (TCB1) Base Address -#define AT91C_BASE_TC2 ((AT91PS_TC) 0xFFFA0080) // (TC2) Base Address -#define AT91C_BASE_TC1 ((AT91PS_TC) 0xFFFA0040) // (TC1) Base Address -#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) // (TC0) Base Address -#define AT91C_BASE_TCB0 ((AT91PS_TCB) 0xFFFA0000) // (TCB0) Base Address -#define AT91C_BASE_UHP ((AT91PS_UHP) 0x00300000) // (UHP) Base Address -#define AT91C_BASE_EMAC ((AT91PS_EMAC) 0xFFFBC000) // (EMAC) Base Address -#define AT91C_BASE_EBI ((AT91PS_EBI) 0xFFFFFF60) // (EBI) Base Address -#define AT91C_BASE_SMC2 ((AT91PS_SMC2) 0xFFFFFF70) // (SMC2) Base Address -#define AT91C_BASE_SDRC ((AT91PS_SDRC) 0xFFFFFF90) // (SDRC) Base Address -#define AT91C_BASE_BFC ((AT91PS_BFC) 0xFFFFFFC0) // (BFC) Base Address - -// ***************************************************************************** -// MEMORY MAPPING DEFINITIONS FOR AT91RM9200 -// ***************************************************************************** -#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address -#define AT91C_ISRAM_SIZE 0x00004000u // Internal SRAM size in byte (16 Kbyte) -#define AT91C_IROM ((char *) 0x00100000) // Internal ROM base address -#define AT91C_IROM_SIZE 0x00020000u // Internal ROM size in byte (128 Kbyte) - -#endif diff --git a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c b/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c deleted file mode 100644 index 1d54cfdad483..000000000000 --- a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c +++ /dev/null @@ -1,223 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" - -extern int __bss_start__[]; -extern int __bss_end__[]; - -#define BAUD 115200 -#define AT91C_US_ASYNC_MODE (AT91C_US_USMODE_NORMAL | AT91C_US_NBSTOP_1_BIT | \ - AT91C_US_PAR_NONE | AT91C_US_CHRL_8_BITS | AT91C_US_CLKS_CLOCK) - -/* - * void DefaultSystemInit(void) - * Load the system with sane values based on how the system is configured. - * at91rm9200_lowlevel.h is expected to define the necessary parameters. - */ -void -_init(void) -{ - int *i; - - AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU; - AT91PS_PDC pPDC = (AT91PS_PDC)&(pUSART->US_RPR); - - register unsigned value; - volatile sdram_size_t *p = (sdram_size_t *)SDRAM_BASE; - - AT91C_BASE_ST->ST_RTMR = 1; -#ifdef BOOT_TSC - // For the TSC board, we turn ON the one LED we have while - // early in boot. - AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC10; - AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC10; - AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC10; -#endif - -#if defined(BOOT_KB920X) - AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC18 | AT91C_PIO_PC19 | - AT91C_PIO_PC20; - AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC18 | AT91C_PIO_PC19 | - AT91C_PIO_PC20; - AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC18 | AT91C_PIO_PC19 | - AT91C_PIO_PC20; - AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC18; -#endif - - // configure clocks - // assume: - // main osc = 10Mhz - // PLLB configured for 96MHz (48MHz after div) - // CSS = PLLB - // set PLLA = 180MHz - // assume main osc = 10Mhz - // div = 5 , out = 2 (150MHz = 240MHz) - value = AT91C_BASE_CKGR->CKGR_PLLAR; - value &= ~(AT91C_CKGR_DIVA | AT91C_CKGR_OUTA | AT91C_CKGR_MULA); - value |= OSC_MAIN_FREQ_DIV | AT91C_CKGR_OUTA_2 | AT91C_CKGR_SRCA | - ((OSC_MAIN_MULT - 1) << 16); - AT91C_BASE_CKGR->CKGR_PLLAR = value; - - // wait for lock - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)) - continue; - - // change divider = 3, pres = 1 - value = AT91C_BASE_PMC->PMC_MCKR; - value &= ~(AT91C_PMC_MDIV | AT91C_PMC_PRES); - value |= AT91C_PMC_MDIV_3 | AT91C_PMC_PRES_CLK; - AT91C_BASE_PMC->PMC_MCKR = value; - - // wait for update - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) - continue; - - // change CSS = PLLA - value &= ~AT91C_PMC_CSS; - value |= AT91C_PMC_CSS_PLLA_CLK; - AT91C_BASE_PMC->PMC_MCKR = value; - - // wait for update - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) - continue; - -#ifdef BOOT_KB920X - // setup flash access (allow ample margin) - // 9 wait states, 1 setup, 1 hold, 1 float for 8-bit device - ((AT91PS_SMC2)AT91C_BASE_SMC2)->SMC2_CSR[0] = - AT91C_SMC2_WSEN | - (9 & AT91C_SMC2_NWS) | - ((1 << 8) & AT91C_SMC2_TDF) | - AT91C_SMC2_DBW_8 | - ((1 << 24) & AT91C_SMC2_RWSETUP) | - ((1 << 29) & AT91C_SMC2_RWHOLD); -#endif - - // setup SDRAM access - // EBI chip-select register (CS1 = SDRAM controller) - // 9 col, 13row, 4 bank, CAS2 - // write recovery = 2 (Twr) - // row cycle = 5 (Trc) - // precharge delay = 2 (Trp) - // row to col delay 2 (Trcd) - // active to precharge = 4 (Tras) - // exit self refresh to active = 6 (Txsr) - value = ((AT91PS_EBI)AT91C_BASE_EBI)->EBI_CSA; - value &= ~AT91C_EBI_CS1A; - value |= AT91C_EBI_CS1A_SDRAMC; - AT91C_BASE_EBI->EBI_CSA = value; - - AT91C_BASE_SDRC->SDRC_CR = -#if defined(KB9202_B) || defined(SDRAM_128M) - AT91C_SDRC_NC_10 | -#else - AT91C_SDRC_NC_9 | -#endif - AT91C_SDRC_NR_13 | - AT91C_SDRC_NB_4_BANKS | - AT91C_SDRC_CAS_2 | - ((2 << 7) & AT91C_SDRC_TWR) | - ((5 << 11) & AT91C_SDRC_TRC) | - ((2 << 15) & AT91C_SDRC_TRP) | - ((2 << 19) & AT91C_SDRC_TRCD) | - ((4 << 23) & AT91C_SDRC_TRAS) | - ((6 << 27) & AT91C_SDRC_TXSR); - - // Step 1: We assume 200us of idle time. - // Step 2: Issue an all banks precharge command - AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_PRCGALL_CMD; - *p = 0; - - // Step 3: Issue 8 Auto-refresh (CBR) cycles - AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_RFSH_CMD; - *p = 0; - *p = 0; - *p = 0; - *p = 0; - *p = 0; - *p = 0; - *p = 0; - *p = 0; - - // Step 4: Issue an Mode Set Register (MRS) cycle to program in - // the parameters that we setup in the SDRC_CR register above. - AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_LMR_CMD; - *p = 0; - - // Step 5: set the refresh timer and access memory to start it - // running. We have to wait 3 clocks after the LMR_CMD above, - // and this fits the bill nicely. - AT91C_BASE_SDRC->SDRC_TR = 7 * AT91C_MASTER_CLOCK / 1000000; - *p = 0; - - // Step 6: Set normal mode. - AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_NORMAL_CMD; - *p = 0; - -#if SDRAM_WIDTH == AT91C_SDRC_DBW_32_BITS - // Turn on the upper 16 bits on the SDRAM bus. - AT91C_BASE_PIOC->PIO_ASR = 0xffff0000; - AT91C_BASE_PIOC->PIO_PDR = 0xffff0000; -#endif - // Configure DBGU -use local routine optimized for space - AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA31 | AT91C_PIO_PA30; - AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA31 | AT91C_PIO_PA30; - pUSART->US_IDR = (unsigned int) -1; - pUSART->US_CR = - AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; - pUSART->US_BRGR = ((((AT91C_MASTER_CLOCK*10)/(BAUD*16))+5)/10); - pUSART->US_TTGR = 0; - pPDC->PDC_PTCR = AT91C_PDC_RXTDIS; - pPDC->PDC_PTCR = AT91C_PDC_TXTDIS; - pPDC->PDC_TNPR = 0; - pPDC->PDC_TNCR = 0; - - pPDC->PDC_RNPR = 0; - pPDC->PDC_RNCR = 0; - - pPDC->PDC_TPR = 0; - pPDC->PDC_TCR = 0; - - pPDC->PDC_RPR = 0; - pPDC->PDC_RCR = 0; - - pPDC->PDC_PTCR = AT91C_PDC_RXTEN; - pPDC->PDC_PTCR = AT91C_PDC_TXTEN; - - pUSART->US_MR = AT91C_US_ASYNC_MODE; - pUSART->US_CR = AT91C_US_TXEN; - pUSART->US_CR = AT91C_US_RXEN; - - /* Zero BSS now that we have memory setup */ - i = (int *)__bss_start__; - while (i < (int *)__bss_end__) - *i++ = 0; -} diff --git a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h b/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h deleted file mode 100644 index 9d9b12736f9c..000000000000 --- a/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.h +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef _AT91RM9200_LOWLEVEL_H_ -#define _AT91RM9200_LOWLEVEL_H_ - -/* default system config parameters */ - -#define SDRAM_BASE 0x20000000 - -#ifdef BOOT_KB920X -/* The following divisor sets PLLA frequency: e.g. 10/5 * 90 = 180MHz */ -#define OSC_MAIN_FREQ_DIV 5 /* for 10MHz osc */ -#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS -typedef unsigned short sdram_size_t; -#define OSC_MAIN_MULT 90 -#endif - -#ifdef BOOT_CENTIPAD -/* The following divisor sets PLLA frequency: e.g. 10/5 * 90 = 180MHz */ -#define OSC_MAIN_FREQ_DIV 5 /* for 10MHz osc */ -#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS -typedef unsigned short sdram_size_t; -#define OSC_MAIN_MULT 90 -#endif - -#ifdef BOOT_BWCT -/* The following divisor sets PLLA frequency: e.g. 16/4 * 45 = 180MHz */ -#define OSC_MAIN_FREQ_DIV 4 /* for 16MHz osc */ -#define SDRAM_WIDTH AT91C_SDRC_DBW_32_BITS -typedef unsigned int sdram_size_t; -#define OSC_MAIN_MULT 45 -#endif - -#ifdef BOOT_TSC -/* The following divisor sets PLLA frequency: e.g. 16/4 * 45 = 180MHz */ -#define OSC_MAIN_FREQ_DIV 4 /* for 16MHz osc */ -#define SDRAM_WIDTH AT91C_SDRC_DBW_32_BITS -typedef unsigned int sdram_size_t; -#define OSC_MAIN_MULT 45 -#endif - -/* Master clock frequency at power-up */ -#define AT91C_MASTER_CLOCK 60000000 - -/* #define GetSeconds() (AT91C_BASE_RTC->RTC_TIMR & AT91C_RTC_SEC) */ -#define GetSeconds() (AT91C_BASE_ST->ST_CRTR >> 15) - -extern void _init(void); - -#endif /* _AT91RM9200_LOWLEVEL_H_ */ diff --git a/sys/boot/arm/at91/libat91/delay.c b/sys/boot/arm/at91/libat91/delay.c deleted file mode 100644 index 390e06790c3c..000000000000 --- a/sys/boot/arm/at91/libat91/delay.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "spi_flash.h" -#include "lib.h" - -void -Delay(int us) -{ - unsigned later, now; - - now = AT91C_BASE_ST->ST_CRTR; - later = (now + us / 25 + 1) & AT91C_ST_CRTV; - while (later != AT91C_BASE_ST->ST_CRTR) - continue; -} diff --git a/sys/boot/arm/at91/libat91/eeprom.c b/sys/boot/arm/at91/libat91/eeprom.c deleted file mode 100644 index e08996bed8e6..000000000000 --- a/sys/boot/arm/at91/libat91/eeprom.c +++ /dev/null @@ -1,185 +0,0 @@ -/****************************************************************************** - * - * Filename: eeprom.c - * - * Instantiation of eeprom routines - * - * Revision information: - * - * 28AUG2004 kb_admin initial creation - adapted from Atmel sources - * 12JAN2005 kb_admin fixed clock generation, write polling, init - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "at91rm9200_lowlevel.h" -#include "at91rm9200.h" -#include "lib.h" - -/******************************* GLOBALS *************************************/ - - -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ - - -/* Use a macro to calculate the TWI clock generator value to save code space. */ -#define AT91C_TWSI_CLOCK 100000 -#define TWSI_EEPROM_ADDRESS 0x50 - -#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2) -#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8)) - - -/*************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void InitEEPROM(void) - * This global function initializes the EEPROM interface (TWI). Intended - * to be called a single time. - * .KB_C_FN_DEFINITION_END - */ -void -InitEEPROM(void) -{ - - AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI; - - AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC; - - pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26; - pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26; - - pPio->PIO_MDDR = ~AT91C_PIO_PA25; - pPio->PIO_MDER = AT91C_PIO_PA25; - - pPMC->PMC_PCER = 1u << AT91C_ID_TWI; - - twiPtr->TWI_IDR = 0xffffffffu; - twiPtr->TWI_CR = AT91C_TWI_SWRST; - twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; - - twiPtr->TWI_CWGR = SET_TWI_CLOCK; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size) - * This global function reads data from the eeprom at ee_addr storing data - * to data_addr for size bytes. Assume the TWI has been initialized. - * This function does not utilize the page read mode to simplify the code. - * .KB_C_FN_DEFINITION_END - */ -int -ReadEEPROM(unsigned ee_off, unsigned char *data_addr, unsigned size) -{ - const AT91PS_TWI twiPtr = AT91C_BASE_TWI; - unsigned int status; - unsigned int count; - - status = twiPtr->TWI_SR; - status = twiPtr->TWI_RHR; - - // Set the TWI Master Mode Register - twiPtr->TWI_MMR = (TWSI_EEPROM_ADDRESS << 16) | - AT91C_TWI_IADRSZ_2_BYTE | AT91C_TWI_MREAD; - - // Set TWI Internal Address Register - twiPtr->TWI_IADR = ee_off; - - // Start transfer - twiPtr->TWI_CR = AT91C_TWI_START; - - status = twiPtr->TWI_SR; - - while (size-- > 1){ - // Wait RHR Holding register is full - count = 1000000; - while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0) - continue; - if (count <= 0) - return -1; - - // Read byte - *(data_addr++) = twiPtr->TWI_RHR; - } - - twiPtr->TWI_CR = AT91C_TWI_STOP; - - status = twiPtr->TWI_SR; - - // Wait transfer is finished - while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP)) - continue; - - // Read last byte - *data_addr = twiPtr->TWI_RHR; - return 0; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size) - * This global function writes data to the eeprom at ee_off using data - * from data_addr for size bytes. Assume the TWI has been initialized. - * This function does not utilize the page write mode as the write time is - * much greater than the time required to access the device for byte-write - * functionality. This allows the function to be much simpler. - * .KB_C_FN_DEFINITION_END - */ -void -WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size) -{ - const AT91PS_TWI twiPtr = AT91C_BASE_TWI; - unsigned status; - unsigned char test_data; - - while (size--) { - if (!(ee_off & 0x3f)) - putchar('.'); - - // Set the TWI Master Mode Register - twiPtr->TWI_MMR = ((TWSI_EEPROM_ADDRESS << 16) | - AT91C_TWI_IADRSZ_2_BYTE) & ~AT91C_TWI_MREAD; - - // Set TWI Internal Address Register - twiPtr->TWI_IADR = ee_off++; - - status = twiPtr->TWI_SR; - - twiPtr->TWI_THR = *(data_addr++); - - twiPtr->TWI_CR = AT91C_TWI_START; - - // Wait transfer is finished - while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY)) - continue; - - twiPtr->TWI_CR = AT91C_TWI_STOP; - - status = twiPtr->TWI_SR; - - // Wait transfer is finished - while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP)) - continue; - - // wait for write operation to complete - ReadEEPROM(ee_off, &test_data, 1); - } - - putchar('\r'); - putchar('\n'); -} diff --git a/sys/boot/arm/at91/libat91/emac.c b/sys/boot/arm/at91/libat91/emac.c deleted file mode 100644 index 509d535ed977..000000000000 --- a/sys/boot/arm/at91/libat91/emac.c +++ /dev/null @@ -1,575 +0,0 @@ -/******************************************************************************* - * - * Filename: emac.c - * - * Instantiation of routines for MAC/ethernet functions supporting tftp. - * - * Revision information: - * - * 28AUG2004 kb_admin initial creation - * 08JAN2005 kb_admin added tftp download - * also adapted from external sources - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ - -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" -#include "emac.h" -#include "lib.h" - -/* ****************************** GLOBALS *************************************/ - -/* ********************** PRIVATE FUNCTIONS/DATA ******************************/ - -static receive_descriptor_t *p_rxBD; -static unsigned short localPort; -static unsigned short serverPort; -static unsigned serverMACSet; -static unsigned localIPSet, serverIPSet; -static unsigned lastSize; -static unsigned char serverMACAddr[6]; -static unsigned char localIPAddr[4], serverIPAddr[4]; -static int ackBlock; -static char *dlAddress; - -static unsigned transmitBuffer[1024 / sizeof(unsigned)]; -static unsigned tftpSendPacket[256 / sizeof(unsigned)]; - -/* - * .KB_C_FN_DEFINITION_START - * unsigned short IP_checksum(unsigned short *p, int len) - * This private function calculates the IP checksum for various headers. - * .KB_C_FN_DEFINITION_END - */ -static unsigned short -IP_checksum(unsigned short *p, int len) -{ - unsigned i, t; - - len &= ~1; - - for (i=0,t=0; i> 16); - return (~t); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void GetServerAddress(void) - * This private function sends an ARP request to determine the server MAC. - * .KB_C_FN_DEFINITION_END - */ -static void -GetServerAddress(void) -{ - arp_header_t *p_ARP; - - p_ARP = (arp_header_t*)transmitBuffer; - - p_memset((char*)p_ARP->dest_mac, 0xFF, 6); - - memcpy(p_ARP->src_mac, localMACAddr, 6); - - p_ARP->frame_type = SWAP16(PROTOCOL_ARP); - p_ARP->hard_type = SWAP16(1); - p_ARP->prot_type = SWAP16(PROTOCOL_IP); - p_ARP->hard_size = 6; - p_ARP->prot_size = 4; - p_ARP->operation = SWAP16(ARP_REQUEST); - - memcpy(p_ARP->sender_mac, localMACAddr, 6); - memcpy(p_ARP->sender_ip, localIPAddr, 4); - p_memset((char*)p_ARP->target_mac, 0, 6); - memcpy(p_ARP->target_ip, serverIPAddr, 4); - - // wait until transmit is available - while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) - continue; - - *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; - *AT91C_EMAC_TAR = (unsigned)transmitBuffer; - *AT91C_EMAC_TCR = 0x40; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void Send_TFTP_Packet(char *tftpData, unsigned tftpLength) - * This private function initializes and send a TFTP packet. - * .KB_C_FN_DEFINITION_END - */ -static void -Send_TFTP_Packet(char *tftpData, unsigned tftpLength) -{ - transmit_header_t *macHdr = (transmit_header_t*)tftpSendPacket; - ip_header_t *ipHdr; - udp_header_t *udpHdr; - unsigned t_checksum; - - memcpy(macHdr->dest_mac, serverMACAddr, 6); - memcpy(macHdr->src_mac, localMACAddr, 6); - macHdr->proto_mac = SWAP16(PROTOCOL_IP); - - ipHdr = (ip_header_t*)&macHdr->packet_length; - - ipHdr->ip_v_hl = 0x45; - ipHdr->ip_tos = 0; - ipHdr->ip_len = SWAP16(28 + tftpLength); - ipHdr->ip_id = 0; - ipHdr->ip_off = SWAP16(0x4000); - ipHdr->ip_ttl = 64; - ipHdr->ip_p = PROTOCOL_UDP; - ipHdr->ip_sum = 0; - - memcpy(ipHdr->ip_src, localIPAddr, 4); - memcpy(ipHdr->ip_dst, serverIPAddr, 4); - - ipHdr->ip_sum = SWAP16(IP_checksum((unsigned short*)ipHdr, 20)); - - udpHdr = (udp_header_t*)(ipHdr + 1); - - udpHdr->src_port = localPort; - udpHdr->dst_port = serverPort; - udpHdr->udp_len = SWAP16(8 + tftpLength); - udpHdr->udp_cksum = 0; - - memcpy((char *)udpHdr+8, tftpData, tftpLength); - - t_checksum = IP_checksum((unsigned short*)ipHdr + 6, (16 + tftpLength)); - - t_checksum = (~t_checksum) & 0xFFFF; - t_checksum += 25 + tftpLength; - - t_checksum = (t_checksum & 0xffff) + (t_checksum >> 16); - t_checksum = (~t_checksum) & 0xFFFF; - - udpHdr->udp_cksum = SWAP16(t_checksum); - - while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) - continue; - - *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; - *AT91C_EMAC_TAR = (unsigned)tftpSendPacket; - *AT91C_EMAC_TCR = 42 + tftpLength; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void TFTP_RequestFile(char *filename) - * This private function sends a RRQ packet to the server. - * .KB_C_FN_DEFINITION_END - */ -static void -TFTP_RequestFile(char *filename) -{ - tftp_header_t tftpHeader; - char *cPtr, *ePtr, *mPtr; - unsigned length; - - tftpHeader.opcode = TFTP_RRQ_OPCODE; - - cPtr = (char*)&(tftpHeader.block_num); - - ePtr = strcpy(cPtr, filename); - mPtr = strcpy(ePtr, "octet"); - - length = mPtr - cPtr; - length += 2; - - Send_TFTP_Packet((char*)&tftpHeader, length); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len) - * This private function sends an ACK packet to the server. - * .KB_C_FN_DEFINITION_END - */ -static void -TFTP_ACK_Data(unsigned char *data, unsigned short block_num, unsigned short len) -{ - tftp_header_t tftpHeader; - - if (block_num == (ackBlock + 1)) { - ++ackBlock; - memcpy(dlAddress, data, len); - dlAddress += len; - lastSize += len; - if (ackBlock % 128 == 0) - printf("tftp: %u kB\r", lastSize / 1024); - } - tftpHeader.opcode = TFTP_ACK_OPCODE; - tftpHeader.block_num = SWAP16(ackBlock); - Send_TFTP_Packet((char*)&tftpHeader, 4); - if (len < 512) { - ackBlock = -2; - printf("tftp: %u byte\n", lastSize); - } -} - - -/* - * .KB_C_FN_DEFINITION_START - * void CheckForNewPacket(ip_header_t *pHeader) - * This private function polls for received ethernet packets and handles - * any here. - * .KB_C_FN_DEFINITION_END - */ -static int -CheckForNewPacket(ip_header_t *pHeader) -{ - unsigned short *pFrameType; - unsigned i; - char *pData; - ip_header_t *pIpHeader; - arp_header_t *p_ARP; - int process = 0; - - process = 0; - for (i = 0; i < MAX_RX_PACKETS; ++i) { - if(p_rxBD[i].address & 0x1) { - process = 1; - (*AT91C_EMAC_RSR) |= (*AT91C_EMAC_RSR); - break; - } - } - - if (!process) - return (0); - process = i; - - pFrameType = (unsigned short *)((p_rxBD[i].address & 0xFFFFFFFC) + 12); - pData = (char *)(p_rxBD[i].address & 0xFFFFFFFC); - - switch (*pFrameType) { - - case SWAP16(PROTOCOL_ARP): - p_ARP = (arp_header_t*)pData; - if (p_ARP->operation == SWAP16(ARP_REPLY)) { - // check if new server info is available - if ((!serverMACSet) && - (!(p_memcmp((char*)p_ARP->sender_ip, - (char*)serverIPAddr, 4)))) { - - serverMACSet = 1; - memcpy(serverMACAddr, p_ARP->sender_mac, 6); - } - } else if (p_ARP->operation == SWAP16(ARP_REQUEST)) { - // ARP REPLY operation - p_ARP->operation = SWAP16(ARP_REPLY); - - // Fill the dest address and src address - for (i = 0; i <6; i++) { - // swap ethernet dest address and ethernet src address - pData[i] = pData[i+6]; - pData[i+6] = localMACAddr[i]; - // swap sender ethernet address and target ethernet address - pData[i+22] = localMACAddr[i]; - pData[i+32] = pData[i+6]; - } - - // swap sender IP address and target IP address - for (i = 0; i<4; i++) { - pData[i+38] = pData[i+28]; - pData[i+28] = localIPAddr[i]; - } - - if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) break; - - *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; - *AT91C_EMAC_TAR = (unsigned)pData; - *AT91C_EMAC_TCR = 0x40; - } - break; - case SWAP16(PROTOCOL_IP): - pIpHeader = (ip_header_t*)(pData + 14); - memcpy(pHeader, pIpHeader, sizeof(ip_header_t)); - - if (pIpHeader->ip_p == PROTOCOL_UDP) { - udp_header_t *udpHdr; - tftp_header_t *tftpHdr; - - udpHdr = (udp_header_t*)((char*)pIpHeader+20); - tftpHdr = (tftp_header_t*)((char*)udpHdr + 8); - - if (udpHdr->dst_port != localPort) - break; - - if (tftpHdr->opcode != TFTP_DATA_OPCODE) - break; - - if (ackBlock == -1) { - if (tftpHdr->block_num != SWAP16(1)) - break; - serverPort = udpHdr->src_port; - ackBlock = 0; - } - - if (serverPort != udpHdr->src_port) - break; - - TFTP_ACK_Data(tftpHdr->data, - SWAP16(tftpHdr->block_num), - SWAP16(udpHdr->udp_len) - 12); - } - } - p_rxBD[process].address &= ~0x01; - return (1); -} - - -/* - * .KB_C_FN_DEFINITION_START - * unsigned short AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) - * This private function reads the PHY device. - * .KB_C_FN_DEFINITION_END - */ -#ifndef BOOT_BWCT -static unsigned short -AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) -{ - unsigned value = 0x60020000 | (addr << 18); - - pEmac->EMAC_CTL |= AT91C_EMAC_MPE; - pEmac->EMAC_MAN = value; - while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE)); - pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE; - return (pEmac->EMAC_MAN & 0x0000ffff); -} -#endif - -/* - * .KB_C_FN_DEFINITION_START - * unsigned short AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s) - * This private function writes the PHY device. - * .KB_C_FN_DEFINITION_END - */ -#ifdef BOOT_TSC -static unsigned short -AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s) -{ - unsigned value = 0x50020000 | (addr << 18) | s; - - pEmac->EMAC_CTL |= AT91C_EMAC_MPE; - pEmac->EMAC_MAN = value; - while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE)); - pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE; - return (pEmac->EMAC_MAN & 0x0000ffff); -} -#endif - -/* - * .KB_C_FN_DEFINITION_START - * void MII_GetLinkSpeed(AT91PS_EMAC pEmac) - * This private function determines the link speed set by the PHY. - * .KB_C_FN_DEFINITION_END - */ -static void -MII_GetLinkSpeed(AT91PS_EMAC pEmac) -{ -#if defined(BOOT_TSC) || defined(BOOT_KB920X) || defined(BOOT_CENTIPAD) - unsigned short stat2; -#endif - unsigned update; -#ifdef BOOT_TSC - unsigned sec; - int i; -#endif -#ifdef BOOT_BWCT - /* hardcoded link speed since we connect a switch via MII */ - update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - update |= AT91C_EMAC_SPD; - update |= AT91C_EMAC_FD; -#endif -#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD) - stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG); - if (!(stat2 & MII_STS2_LINK)) - return ; - update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - if (stat2 & MII_STS2_100TX) - update |= AT91C_EMAC_SPD; - if (stat2 & MII_STS2_FDX) - update |= AT91C_EMAC_FD; -#endif -#ifdef BOOT_TSC - while (1) { - for (i = 0; i < 10; i++) { - stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG); - if (stat2 & MII_STS_LINK_STAT) - break; - printf("."); - sec = GetSeconds(); - while (GetSeconds() == sec) - continue; - } - if (stat2 & MII_STS_LINK_STAT) - break; - printf("Resetting MII..."); - AT91F_MII_WritePhy(pEmac, 0x0, 0x8000); - while (AT91F_MII_ReadPhy(pEmac, 0x0) & 0x8000) continue; - } - printf("emac: link"); - stat2 = AT91F_MII_ReadPhy(pEmac, MII_SPEC_STS_REG); - update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); - if (stat2 & (MII_SSTS_100FDX | MII_SSTS_100HDX)) { - printf(" 100TX"); - update |= AT91C_EMAC_SPD; - } - if (stat2 & (MII_SSTS_100FDX | MII_SSTS_10FDX)) { - printf(" FDX"); - update |= AT91C_EMAC_FD; - } - printf("\n"); -#endif - pEmac->EMAC_CFG = update; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void AT91F_EmacEntry(void) - * This private function initializes the EMAC on the chip. - * .KB_C_FN_DEFINITION_END - */ -static void -AT91F_EmacEntry(void) -{ - unsigned i; - char *pRxPacket = (char*)RX_DATA_START; - AT91PS_EMAC pEmac = AT91C_BASE_EMAC; - - p_rxBD = (receive_descriptor_t*)RX_BUFFER_START; - localPort = SWAP16(0x8002); - - for (i = 0; i < MAX_RX_PACKETS; ++i) { - - p_rxBD[i].address = (unsigned)pRxPacket; - p_rxBD[i].size = 0; - pRxPacket += RX_PACKET_SIZE; - } - - // Set the WRAP bit at the end of the list descriptor - p_rxBD[MAX_RX_PACKETS-1].address |= 0x02; - - if (!(pEmac->EMAC_SR & AT91C_EMAC_LINK)) - MII_GetLinkSpeed(pEmac); - - pEmac->EMAC_RBQP = (unsigned) p_rxBD; - pEmac->EMAC_RSR |= (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); - pEmac->EMAC_CTL = AT91C_EMAC_TE | AT91C_EMAC_RE; - - pEmac->EMAC_TAR = (unsigned)transmitBuffer; -} - - -/* ************************** GLOBAL FUNCTIONS ********************************/ - -/* - * .KB_C_FN_DEFINITION_START - * void SetServerIPAddress(unsigned address) - * This global function sets the IP of the TFTP download server. - * .KB_C_FN_DEFINITION_END - */ -void -SetServerIPAddress(unsigned address) -{ - // force update in case the IP has changed - serverMACSet = 0; - - serverIPAddr[0] = (address >> 24) & 0xFF; - serverIPAddr[1] = (address >> 16) & 0xFF; - serverIPAddr[2] = (address >> 8) & 0xFF; - serverIPAddr[3] = (address >> 0) & 0xFF; - - serverIPSet = 1; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void SetLocalIPAddress(unsigned address) - * This global function sets the IP of this module. - * .KB_C_FN_DEFINITION_END - */ -void -SetLocalIPAddress(unsigned address) -{ - // force update in case the IP has changed - serverMACSet = 0; - - localIPAddr[0] = (address >> 24) & 0xFF; - localIPAddr[1] = (address >> 16) & 0xFF; - localIPAddr[2] = (address >> 8) & 0xFF; - localIPAddr[3] = (address >> 0) & 0xFF; - - localIPSet = 1; -} - - -/* - * .KB_C_FN_DEFINITION_START - * void TFTP_Download(unsigned address, char *filename) - * This global function initiates and processes a tftp download request. - * The server IP, local IP, local MAC must be set before this function is - * executed. - * .KB_C_FN_DEFINITION_END - */ -void -TFTP_Download(unsigned address, char *filename) -{ - ip_header_t IpHeader; - unsigned thisSeconds; - int timeout; - - if ((!localMACSet) || (!localIPSet) || (!serverIPSet)) - return ; - - AT91F_EmacEntry(); - GetServerAddress(); - dlAddress = (char*)address; - lastSize = 0; - timeout = 10; - thisSeconds = (GetSeconds() + 2) % 32; - serverPort = SWAP16(69); - ++localPort; - ackBlock = -1; - - while (timeout) { - if (CheckForNewPacket(&IpHeader)) { - if (ackBlock == -2) - break; - timeout = 10; - thisSeconds = (GetSeconds() + 2) % 32; - } else if (GetSeconds() == thisSeconds) { - --timeout; - thisSeconds = (GetSeconds() + 2) % 32; - if (!serverMACSet) - GetServerAddress(); - else if (ackBlock == -1) - TFTP_RequestFile(filename); - else { - // Be sure to send a NAK, which is done by - // ACKing the last block we got. - TFTP_ACK_Data(0, ackBlock, 512); - printf("\nNAK %u\n", ackBlock); - } - } - } - if (timeout == 0) - printf("TFTP TIMEOUT!\n"); -} diff --git a/sys/boot/arm/at91/libat91/emac.h b/sys/boot/arm/at91/libat91/emac.h deleted file mode 100644 index fea08f8efc56..000000000000 --- a/sys/boot/arm/at91/libat91/emac.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * - * Filename: emac.h - * - * Definition of routine to set the MAC address. - * - * Revision information: - * - * 28AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - - -#ifndef _EMAC_H_ -#define _EMAC_H_ - -extern void EMAC_SetMACAddress(unsigned char addr[6]); -extern void SetServerIPAddress(unsigned address); -extern void SetLocalIPAddress(unsigned address); -extern void EMAC_Init(void); -extern void TFTP_Download(unsigned address, char *filename); - -#define MAX_RX_PACKETS 8 -#define RX_PACKET_SIZE 1536 -#define RX_BUFFER_START 0x21000000 -#define RX_DATA_START (RX_BUFFER_START + (8 * MAX_RX_PACKETS)) - -#define ARP_REQUEST 0x0001 -#define ARP_REPLY 0x0002 -#define PROTOCOL_ARP 0x0806 -#define PROTOCOL_IP 0x0800 -#define PROTOCOL_UDP 0x11 - -#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8)) - -typedef struct { - unsigned address; - unsigned size; -} receive_descriptor_t; - -typedef struct { - - unsigned char dest_mac[6]; - - unsigned char src_mac[6]; - - unsigned short frame_type; - unsigned short hard_type; - unsigned short prot_type; - unsigned char hard_size; - unsigned char prot_size; - - unsigned short operation; - - unsigned char sender_mac[6]; - unsigned char sender_ip[4]; - - unsigned char target_mac[6]; - unsigned char target_ip[4]; - -} __attribute__((__packed__)) arp_header_t; - -typedef struct { - unsigned char ip_v_hl; - unsigned char ip_tos; - unsigned short ip_len; - unsigned short ip_id; - unsigned short ip_off; - unsigned char ip_ttl; - unsigned char ip_p; - unsigned short ip_sum; - unsigned char ip_src[4]; - unsigned char ip_dst[4]; -} __attribute__((__packed__)) ip_header_t; - -typedef struct { - unsigned char dest_mac[6]; - unsigned char src_mac[6]; - unsigned short proto_mac; - unsigned short packet_length; - ip_header_t iphdr; -} __attribute__((__packed__)) transmit_header_t; - -typedef struct { - unsigned short src_port; - unsigned short dst_port; - unsigned short udp_len; - unsigned short udp_cksum; -} __attribute__((__packed__)) udp_header_t; - -typedef struct { - unsigned short opcode; - unsigned short block_num; - unsigned char data[512]; -} __attribute__((__packed__)) tftp_header_t; - -// Preswap bytes -#define TFTP_RRQ_OPCODE 0x0100 -#define TFTP_WRQ_OPCODE 0x0200 -#define TFTP_DATA_OPCODE 0x0300 -#define TFTP_ACK_OPCODE 0x0400 -#define TFTP_ERROR_OPCODE 0x0500 - -/* MII registers definition */ -#define MII_STS_REG 0x01 -#define MII_STS_LINK_STAT 0x04 -#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD) -#define MII_STS2_REG 0x11 -#define MII_STS2_LINK 0x400 -#define MII_STS2_100TX 0x4000 -#define MII_STS2_FDX 0x200 -#else -#define MII_SPEC_STS_REG 0x11 -#define MII_SSTS_100FDX 0x8000 -#define MII_SSTS_100HDX 0x4000 -#define MII_SSTS_10FDX 0x2000 -#define MII_SSTS_10HDX 0x1000 -#endif - -extern unsigned char localMACAddr[6]; -extern unsigned localMAClow, localMAChigh; -extern unsigned localMACSet; -#define EMAC_Init() - -#endif /* _EMAC_H_ */ diff --git a/sys/boot/arm/at91/libat91/emac_init.c b/sys/boot/arm/at91/libat91/emac_init.c deleted file mode 100644 index a3869b67de91..000000000000 --- a/sys/boot/arm/at91/libat91/emac_init.c +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -/****************************************************************************** - * - * Filename: emac.c - * - * Instantiation of routines for MAC/ethernet functions supporting tftp. - * - * Revision information: - * - * 28AUG2004 kb_admin initial creation - * 08JAN2005 kb_admin added tftp download - * also adapted from external sources - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - ******************************************************************************/ - -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" -#include "emac.h" -#include "lib.h" - -/* ****************************** GLOBALS *************************************/ - -unsigned localMACSet; -unsigned char localMACAddr[6]; -unsigned localMAClow, localMAChigh; - -/* ********************** PRIVATE FUNCTIONS/DATA ******************************/ - -/* - * .KB_C_FN_DEFINITION_START - * void EMAC_SetMACAddress(unsigned low_address, unsigned high_address) - * This global function sets the MAC address. low_address is the first - * four bytes while high_address is the last 2 bytes of the 48-bit value. - * .KB_C_FN_DEFINITION_END - */ -void -EMAC_SetMACAddress(unsigned char mac[6]) -{ - AT91PS_PMC pPMC = AT91C_BASE_PMC; - AT91PS_EMAC pEmac = AT91C_BASE_EMAC; - - /* enable the peripheral clock before using EMAC */ - pPMC->PMC_PCER = ((unsigned) 1 << AT91C_ID_EMAC); - - memcpy(localMACAddr, mac, 6); - localMAClow = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]; - localMAChigh = (mac[5] << 8) | mac[4]; - localMACSet = 1; - - AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_EMAC; - AT91C_BASE_PIOA->PIO_ASR = - AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 | - AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 | - AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 | - AT91C_PIO_PA7; - AT91C_BASE_PIOA->PIO_PDR = - AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 | - AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 | - AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 | - AT91C_PIO_PA7; -#if defined(BOOT_KB920X) | defined(BOOT_BWCT) /* Really !RMII */ - AT91C_BASE_PIOB->PIO_BSR = - AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 | - AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 | - AT91C_PIO_PB18 | AT91C_PIO_PB19; - AT91C_BASE_PIOB->PIO_PDR = - AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 | - AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 | - AT91C_PIO_PB18 | AT91C_PIO_PB19; -#endif - pEmac->EMAC_CTL = 0; - - pEmac->EMAC_CFG = (pEmac->EMAC_CFG & ~(AT91C_EMAC_CLK)) | -#ifdef BOOT_TSC - AT91C_EMAC_RMII | -#endif - AT91C_EMAC_CLK_HCLK_32 | AT91C_EMAC_CAF; - // the sequence write EMAC_SA1L and write EMAC_SA1H must be respected - pEmac->EMAC_SA1L = localMAClow; - pEmac->EMAC_SA1H = localMAChigh; -} diff --git a/sys/boot/arm/at91/libat91/getc.c b/sys/boot/arm/at91/libat91/getc.c deleted file mode 100644 index 59e27a40e890..000000000000 --- a/sys/boot/arm/at91/libat91/getc.c +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provided by kwikbyte without - * copyright as follows: - * - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" -#include "lib.h" - -/* - * int getc(int seconds) - * - * Reads a character from the DBGU port, if one is available within about - * seconds seconds. It assumes that DBGU has already been initialized. - */ -int -getc(int seconds) -{ - AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU; - unsigned thisSecond; - - // Clamp to 20s - if (seconds > 20) - seconds = 20; - thisSecond = GetSeconds(); - seconds = thisSecond + seconds; - do { - if ((pUSART->US_CSR & AT91C_US_RXRDY)) - return (pUSART->US_RHR & 0xFF); - thisSecond = GetSeconds(); - } while (thisSecond != seconds); - return (-1); -} diff --git a/sys/boot/arm/at91/libat91/lib.h b/sys/boot/arm/at91/libat91/lib.h deleted file mode 100644 index 24ac49fd3249..000000000000 --- a/sys/boot/arm/at91/libat91/lib.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef ARM_BOOT_LIB_H -#define ARM_BOOT_LIB_H - -int getc(int); -void putchar(int); -void xputchar(int); -void printf(const char *fmt,...); - -/* The following function write eeprom at ee_addr using data */ -/* from data_add for size bytes. */ -int ReadEEPROM(unsigned eeoff, unsigned char *data_addr, unsigned size); -void WriteEEPROM(unsigned eeoff, char *data_addr, unsigned size); -void InitEEPROM(void); - -/* XMODEM protocol */ -int xmodem_rx(char *dst); - -/* */ -void start_wdog(int n); -void reset(void); - -/* Delay us */ -void Delay(int us); - -#define ToASCII(x) ((x > 9) ? (x + 'A' - 0xa) : (x + '0')) - -int p_IsWhiteSpace(char cValue); -unsigned p_HexCharValue(char cValue); -unsigned p_ASCIIToHex(const char *buf); -unsigned p_ASCIIToDec(const char *buf); - -void p_memset(char *buffer, char value, int size); -int p_strlen(const char *buffer); -char *strcpy(char *to, const char *from); -void memcpy(void *to, const void *from, unsigned size); -int p_memcmp(const char *to, const char *from, unsigned size); -int strcmp(const char *to, const char *from); - -#endif diff --git a/sys/boot/arm/at91/libat91/lib_AT91RM9200.h b/sys/boot/arm/at91/libat91/lib_AT91RM9200.h deleted file mode 100644 index c87512f9b017..000000000000 --- a/sys/boot/arm/at91/libat91/lib_AT91RM9200.h +++ /dev/null @@ -1,277 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -#ifndef __LIBAT91RM9200_H -#define __LIBAT91RM9200_H - -#include "at91rm9200.h" - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PMC_EnablePeriphClock -//* \brief Enable peripheral clock -//*---------------------------------------------------------------------------- -static inline void -AT91F_PMC_EnablePeriphClock ( - AT91PS_PMC pPMC, // \arg pointer to PMC controller - unsigned int periphIds) // \arg IDs of peripherals to enable -{ - pPMC->PMC_PCER = periphIds; -} - -/* ***************************************************************************** - SOFTWARE API FOR PIO - ***************************************************************************** */ -//*---------------------------------------------------------------------------- -//* \fn AT91F_PIO_CfgPeriph -//* \brief Enable pins to be drived by peripheral -//*---------------------------------------------------------------------------- -static inline -void AT91F_PIO_CfgPeriph( - AT91PS_PIO pPio, // \arg pointer to a PIO controller - unsigned int periphAEnable, // \arg PERIPH A to enable - unsigned int periphBEnable) // \arg PERIPH B to enable - -{ - if (periphAEnable) - pPio->PIO_ASR = periphAEnable; - if (periphBEnable) - pPio->PIO_BSR = periphBEnable; - pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode -} - -/* ***************************************************************************** - SOFTWARE API FOR MCI - ***************************************************************************** */ -//* Classic MCI Data Timeout Register Configuration with 1048576 MCK cycles between 2 data transfer -#define AT91C_MCI_DTOR_1MEGA_CYCLES (AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL) - -//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot A -#define AT91C_MCI_MMC_SLOTA (AT91C_MCI_SCDSEL & 0x0) - -//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot B -#define AT91C_MCI_MMC_SLOTB (AT91C_MCI_SCDSEL) - -//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot A -#define AT91C_MCI_SDCARD_4BITS_SLOTA ( (AT91C_MCI_SCDSEL & 0x0) | AT91C_MCI_SCDBUS ) - -//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot B -#define AT91C_MCI_SDCARD_4BITS_SLOTB (AT91C_MCI_SCDSEL | AT91C_MCI_SCDBUS) - - - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_Configure -//* \brief Configure the MCI -//*---------------------------------------------------------------------------- -static inline -void AT91F_MCI_Configure( - AT91PS_MCI pMCI, // \arg pointer to a MCI controller - unsigned int DTOR_register, // \arg Data Timeout Register to be programmed - unsigned int MR_register, // \arg Mode Register to be programmed - unsigned int SDCR_register) // \arg SDCard Register to be programmed -{ - //* Reset the MCI - pMCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN; - - //* Disable all the interrupts - pMCI->MCI_IDR = 0xFFFFFFFF; - - //* Set the Data Timeout Register - pMCI->MCI_DTOR = DTOR_register; - - //* Set the Mode Register - pMCI->MCI_MR = MR_register; - - //* Set the SDCard Register - pMCI->MCI_SDCR = SDCR_register; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_CfgPMC -//* \brief Enable Peripheral clock in PMC for MCI -//*---------------------------------------------------------------------------- -static inline void -AT91F_MCI_CfgPMC(void) -{ - AT91F_PMC_EnablePeriphClock( - AT91C_BASE_PMC, // PIO controller base address - ((unsigned int) 1 << AT91C_ID_MCI)); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_CfgPIO -//* \brief Configure PIO controllers to drive MCI signals -//*---------------------------------------------------------------------------- -static inline void -AT91F_MCI_CfgPIO(void) -{ - // Configure PIO controllers to periph mode - AT91F_PIO_CfgPeriph( - AT91C_BASE_PIOA, // PIO controller base address - ((unsigned int) AT91C_PIO_PA28 ) | - ((unsigned int) AT91C_PIO_PA29 ) | - ((unsigned int) AT91C_PIO_PA27 ), // Peripheral A - 0); // Peripheral B - // Configure PIO controllers to periph mode - AT91F_PIO_CfgPeriph( - AT91C_BASE_PIOB, // PIO controller base address - 0, // Peripheral A - ((unsigned int) AT91C_PIO_PB5 ) | - ((unsigned int) AT91C_PIO_PB3 ) | - ((unsigned int) AT91C_PIO_PB4 )); // Peripheral B -} - - -/* ***************************************************************************** - SOFTWARE API FOR PDC - ***************************************************************************** */ -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_SetNextRx -//* \brief Set the next receive transfer descriptor -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_SetNextRx ( - AT91PS_PDC pPDC, // \arg pointer to a PDC controller - char *address, // \arg address to the next bloc to be received - unsigned int bytes) // \arg number of bytes to be received -{ - pPDC->PDC_RNPR = (unsigned int) address; - pPDC->PDC_RNCR = bytes; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_SetNextTx -//* \brief Set the next transmit transfer descriptor -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_SetNextTx( - AT91PS_PDC pPDC, // \arg pointer to a PDC controller - char *address, // \arg address to the next bloc to be transmitted - unsigned int bytes) // \arg number of bytes to be transmitted -{ - pPDC->PDC_TNPR = (unsigned int) address; - pPDC->PDC_TNCR = bytes; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_SetRx -//* \brief Set the receive transfer descriptor -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_SetRx( - AT91PS_PDC pPDC, // \arg pointer to a PDC controller - char *address, // \arg address to the next bloc to be received - unsigned int bytes) // \arg number of bytes to be received -{ - pPDC->PDC_RPR = (unsigned int) address; - pPDC->PDC_RCR = bytes; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_SetTx -//* \brief Set the transmit transfer descriptor -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_SetTx( - AT91PS_PDC pPDC, // \arg pointer to a PDC controller - char *address, // \arg address to the next bloc to be transmitted - unsigned int bytes) // \arg number of bytes to be transmitted -{ - pPDC->PDC_TPR = (unsigned int) address; - pPDC->PDC_TCR = bytes; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_EnableTx -//* \brief Enable transmit -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_EnableTx( - AT91PS_PDC pPDC ) // \arg pointer to a PDC controller -{ - pPDC->PDC_PTCR = AT91C_PDC_TXTEN; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_EnableRx -//* \brief Enable receive -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_EnableRx( - AT91PS_PDC pPDC ) // \arg pointer to a PDC controller -{ - pPDC->PDC_PTCR = AT91C_PDC_RXTEN; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_DisableTx -//* \brief Disable transmit -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_DisableTx( - AT91PS_PDC pPDC ) // \arg pointer to a PDC controller -{ - pPDC->PDC_PTCR = AT91C_PDC_TXTDIS; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_DisableRx -//* \brief Disable receive -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_DisableRx( - AT91PS_PDC pPDC ) // \arg pointer to a PDC controller -{ - pPDC->PDC_PTCR = AT91C_PDC_RXTDIS; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_PDC_Open -//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX -//*---------------------------------------------------------------------------- -static inline void -AT91F_PDC_Open( - AT91PS_PDC pPDC) // \arg pointer to a PDC controller -{ - //* Disable the RX and TX PDC transfer requests - AT91F_PDC_DisableRx(pPDC); - AT91F_PDC_DisableTx(pPDC); - - //* Reset all Counter register Next buffer first - AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0); - AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0); - AT91F_PDC_SetTx(pPDC, (char *) 0, 0); - AT91F_PDC_SetRx(pPDC, (char *) 0, 0); - - //* Enable the RX and TX PDC transfer requests - AT91F_PDC_EnableRx(pPDC); - AT91F_PDC_EnableTx(pPDC); -} - -#endif diff --git a/sys/boot/arm/at91/libat91/mci_device.h b/sys/boot/arm/at91/libat91/mci_device.h deleted file mode 100644 index 9f2f665df2c1..000000000000 --- a/sys/boot/arm/at91/libat91/mci_device.h +++ /dev/null @@ -1,434 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -//*--------------------------------------------------------------------------- -//* ATMEL Microcontroller Software Support - ROUSSET - -//*--------------------------------------------------------------------------- -//* The software is delivered "AS IS" without warranty or condition of any -//* kind, either express, implied or statutory. This includes without -//* limitation any warranty or condition with respect to merchantability or -//* fitness for any particular purpose, or against the infringements of -//* intellectual property rights of others. -//*--------------------------------------------------------------------------- -//* File Name : AT91C_MCI_Device.h -//* Object : Data Flash Atmel Description File -//* Translator : -//* -//* 1.0 26/11/02 FB : Creation -//*--------------------------------------------------------------------------- - -#ifndef __MCI_Device_h -#define __MCI_Device_h - -#include - -typedef unsigned int AT91S_MCIDeviceStatus; - -/////////////////////////////////////////////////////////////////////////////// - -#define AT91C_CARD_REMOVED 0 -#define AT91C_MMC_CARD_INSERTED 1 -#define AT91C_SD_CARD_INSERTED 2 - -#define AT91C_NO_ARGUMENT 0x0 - -#define AT91C_FIRST_RCA 0xCAFE -#define AT91C_MAX_MCI_CARDS 10 - -#define AT91C_BUS_WIDTH_1BIT 0x00 -#define AT91C_BUS_WIDTH_4BITS 0x02 - -/* Driver State */ -#define AT91C_MCI_IDLE 0x0 -#define AT91C_MCI_TIMEOUT_ERROR 0x1 -#define AT91C_MCI_RX_SINGLE_BLOCK 0x2 -#define AT91C_MCI_RX_MULTIPLE_BLOCK 0x3 -#define AT91C_MCI_RX_STREAM 0x4 -#define AT91C_MCI_TX_SINGLE_BLOCK 0x5 -#define AT91C_MCI_TX_MULTIPLE_BLOCK 0x6 -#define AT91C_MCI_TX_STREAM 0x7 - -/* TimeOut */ -#define AT91C_TIMEOUT_CMDRDY 30 - - - -/////////////////////////////////////////////////////////////////////////////// -// MMC & SDCard Structures -/////////////////////////////////////////////////////////////////////////////// - -/*---------------------------------------------*/ -/* MCI Device Structure Definition */ -/*---------------------------------------------*/ -typedef struct _AT91S_MciDevice -{ - volatile unsigned char state; - unsigned char SDCard_bus_width; - unsigned char IsSDv2; - unsigned char IsSDHC; - unsigned int RCA; // RCA - unsigned int READ_BL_LEN; -#ifdef REPORT_SIZE - unsigned int Memory_Capacity; -#endif -} AT91S_MciDevice; - -#include - -/////////////////////////////////////////////////////////////////////////////// -// Functions returnals -/////////////////////////////////////////////////////////////////////////////// -#define AT91C_CMD_SEND_OK 0 // Command ok -#define AT91C_CMD_SEND_ERROR -1 // Command failed -#define AT91C_INIT_OK 2 // Init Successful -#define AT91C_INIT_ERROR 3 // Init Failed -#define AT91C_READ_OK 4 // Read Successful -#define AT91C_READ_ERROR 5 // Read Failed -#define AT91C_WRITE_OK 6 // Write Successful -#define AT91C_WRITE_ERROR 7 // Write Failed -#define AT91C_ERASE_OK 8 // Erase Successful -#define AT91C_ERASE_ERROR 9 // Erase Failed -#define AT91C_CARD_SELECTED_OK 10 // Card Selection Successful -#define AT91C_CARD_SELECTED_ERROR 11 // Card Selection Failed - -#define AT91C_MCI_SR_ERROR (AT91C_MCI_UNRE | AT91C_MCI_OVRE | AT91C_MCI_DTOE | \ - AT91C_MCI_DCRCE | AT91C_MCI_RTOE | AT91C_MCI_RENDE | AT91C_MCI_RCRCE | \ - AT91C_MCI_RDIRE | AT91C_MCI_RINDE) - -#define MMC_CMDNB (0x1Fu << 0) // Command Number -#define MMC_RSPTYP (0x3u << 6) // Response Type -#define MMC_RSPTYP_NO (0x0u << 6) // No response -#define MMC_RSPTYP_48 (0x1u << 6) // 48-bit response -#define MMC_RSPTYP_136 (0x2u << 6) // 136-bit response -#define MMC_SPCMD (0x7u << 8) // Special CMD -#define MMC_SPCMD_NONE (0x0u << 8) // Not a special CMD -#define MMC_SPCMD_INIT (0x1u << 8) // Initialization CMD -#define MMC_SPCMD_SYNC (0x2u << 8) // Synchronized CMD -#define MMC_SPCMD_IT_CMD (0x4u << 8) // Interrupt command -#define MMC_SPCMD_IT_REP (0x5u << 8) // Interrupt response -#define MMC_OPDCMD (0x1u << 11) // Open Drain Command -#define MMC_MAXLAT (0x1u << 12) // Maximum Latency for Command to respond -#define MMC_TRCMD (0x3u << 16) // Transfer CMD -#define MMC_TRCMD_NO (0x0u << 16) // No transfer -#define MMC_TRCMD_START (0x1u << 16) // Start transfer -#define MMC_TRCMD_STOP (0x2u << 16) // Stop transfer -#define MMC_TRDIR (0x1u << 18) // Transfer Direction -#define MMC_TRTYP (0x3u << 19) // Transfer Type -#define MMC_TRTYP_BLOCK (0x0u << 19) // Block Transfer type -#define MMC_TRTYP_MULTIPLE (0x1u << 19) // Multiple Block transfer type -#define MMC_TRTYP_STREAM (0x2u << 19) // Stream transfer type - -/////////////////////////////////////////////////////////////////////////////// -// MCI_CMD Register Value -/////////////////////////////////////////////////////////////////////////////// -#define POWER_ON_INIT \ - (0 | MMC_TRCMD_NO | MMC_SPCMD_INIT | MMC_OPDCMD) - -///////////////////////////////////////////////////////////////// -// Class 0 & 1 commands: Basic commands and Read Stream commands -///////////////////////////////////////////////////////////////// - -#define GO_IDLE_STATE_CMD \ - (0 | MMC_TRCMD_NO | MMC_SPCMD_NONE ) -#define MMC_GO_IDLE_STATE_CMD \ - (0 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_OPDCMD) -#define MMC_SEND_OP_COND_CMD \ - (1 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_OPDCMD) - -#define ALL_SEND_CID_CMD \ - (2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136) -#define MMC_ALL_SEND_CID_CMD \ - (2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \ - MMC_OPDCMD) - -#define SET_RELATIVE_ADDR_CMD \ - (3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -#define MMC_SET_RELATIVE_ADDR_CMD \ - (3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT | MMC_OPDCMD) - -#define SET_DSR_CMD \ - (4 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_NO | \ - MMC_MAXLAT) // no tested - -#define SEL_DESEL_CARD_CMD \ - (7 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -#define SEND_CSD_CMD \ - (9 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \ - MMC_MAXLAT) -#define SEND_CID_CMD \ - (10 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \ - MMC_MAXLAT) -#define MMC_READ_DAT_UNTIL_STOP_CMD \ - (11 | MMC_TRTYP_STREAM | MMC_SPCMD_NONE | \ - MMC_RSPTYP_48 | MMC_TRDIR | MMC_TRCMD_START | \ - MMC_MAXLAT) - -#define STOP_TRANSMISSION_CMD \ - (12 | MMC_TRCMD_STOP | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -#define STOP_TRANSMISSION_SYNC_CMD \ - (12 | MMC_TRCMD_STOP | MMC_SPCMD_SYNC | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -#define SEND_STATUS_CMD \ - (13 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -#define GO_INACTIVE_STATE_CMD \ - (15 | MMC_RSPTYP_NO) -#define SD_SEND_IF_COND_CMD \ - (8 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \ - MMC_MAXLAT) -//*------------------------------------------------ -//* Class 2 commands: Block oriented Read commands -//*------------------------------------------------ - -#define SET_BLOCKLEN_CMD (16 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT ) -#define READ_SINGLE_BLOCK_CMD (17 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_BLOCK | MMC_TRDIR | MMC_MAXLAT) -#define READ_MULTIPLE_BLOCK_CMD (18 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_MULTIPLE | MMC_TRDIR | MMC_MAXLAT) - -//*-------------------------------------------- -//* Class 3 commands: Sequential write commands -//*-------------------------------------------- - -#define MMC_WRITE_DAT_UNTIL_STOP_CMD (20 | MMC_TRTYP_STREAM| MMC_SPCMD_NONE | MMC_RSPTYP_48 & ~(MMC_TRDIR) | MMC_TRCMD_START | MMC_MAXLAT ) // MMC - -//*------------------------------------------------ -//* Class 4 commands: Block oriented write commands -//*------------------------------------------------ - -#define WRITE_BLOCK_CMD (24 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_BLOCK & ~(MMC_TRDIR)) | MMC_MAXLAT) -#define WRITE_MULTIPLE_BLOCK_CMD (25 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_MULTIPLE & ~(MMC_TRDIR)) | MMC_MAXLAT) -#define PROGRAM_CSD_CMD (27 | MMC_RSPTYP_48 ) - - -//*---------------------------------------- -//* Class 6 commands: Group Write protect -//*---------------------------------------- - -#define SET_WRITE_PROT_CMD (28 | MMC_RSPTYP_48 ) -#define CLR_WRITE_PROT_CMD (29 | MMC_RSPTYP_48 ) -#define SEND_WRITE_PROT_CMD (30 | MMC_RSPTYP_48 ) - - -//*---------------------------------------- -//* Class 5 commands: Erase commands -//*---------------------------------------- - -#define TAG_SECTOR_START_CMD (32 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define TAG_SECTOR_END_CMD (33 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define MMC_UNTAG_SECTOR_CMD (34 | MMC_RSPTYP_48 ) -#define MMC_TAG_ERASE_GROUP_START_CMD (35 | MMC_RSPTYP_48 ) -#define MMC_TAG_ERASE_GROUP_END_CMD (36 | MMC_RSPTYP_48 ) -#define MMC_UNTAG_ERASE_GROUP_CMD (37 | MMC_RSPTYP_48 ) -#define ERASE_CMD (38 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT ) - -//*---------------------------------------- -//* Class 7 commands: Lock commands -//*---------------------------------------- - -#define LOCK_UNLOCK (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested - -//*----------------------------------------------- -// Class 8 commands: Application specific commands -//*----------------------------------------------- - -#define APP_CMD (55 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define GEN_CMD (56 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested - -#define SDCARD_SET_BUS_WIDTH_CMD (6 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_STATUS_CMD (13 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_SEND_NUM_WR_BLOCKS_CMD (22 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_SET_WR_BLK_ERASE_COUNT_CMD (23 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_APP_OP_COND_CMD (41 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_SET_CLR_CARD_DETECT_CMD (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) -#define SDCARD_SEND_SCR_CMD (51 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) - -#define SDCARD_APP_ALL_CMD (SDCARD_SET_BUS_WIDTH_CMD +\ - SDCARD_STATUS_CMD +\ - SDCARD_SEND_NUM_WR_BLOCKS_CMD +\ - SDCARD_SET_WR_BLK_ERASE_COUNT_CMD +\ - SDCARD_APP_OP_COND_CMD +\ - SDCARD_SET_CLR_CARD_DETECT_CMD +\ - SDCARD_SEND_SCR_CMD) - -//*---------------------------------------- -//* Class 9 commands: IO Mode commands -//*---------------------------------------- - -#define MMC_FAST_IO_CMD (39 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT) -#define MMC_GO_IRQ_STATE_CMD (40 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) - -/////////////////////////////////////////////////////////////////////////////// -// OCR Register -/////////////////////////////////////////////////////////////////////////////// -#define AT91C_VDD_16_17 (1 << 4) -#define AT91C_VDD_17_18 (1 << 5) -#define AT91C_VDD_18_19 (1 << 6) -#define AT91C_VDD_19_20 (1 << 7) -#define AT91C_VDD_20_21 (1 << 8) -#define AT91C_VDD_21_22 (1 << 9) -#define AT91C_VDD_22_23 (1 << 10) -#define AT91C_VDD_23_24 (1 << 11) -#define AT91C_VDD_24_25 (1 << 12) -#define AT91C_VDD_25_26 (1 << 13) -#define AT91C_VDD_26_27 (1 << 14) -#define AT91C_VDD_27_28 (1 << 15) -#define AT91C_VDD_28_29 (1 << 16) -#define AT91C_VDD_29_30 (1 << 17) -#define AT91C_VDD_30_31 (1 << 18) -#define AT91C_VDD_31_32 (1 << 19) -#define AT91C_VDD_32_33 (1 << 20) -#define AT91C_VDD_33_34 (1 << 21) -#define AT91C_VDD_34_35 (1 << 22) -#define AT91C_VDD_35_36 (1 << 23) -#define AT91C_CCS (1 << 30) -#define AT91C_CARD_POWER_UP_DONE (1U << 31) - -#define AT91C_MMC_HOST_VOLTAGE_RANGE (AT91C_VDD_27_28 | AT91C_VDD_28_29 | \ - AT91C_VDD_29_30 | AT91C_VDD_30_31 | AT91C_VDD_31_32 | AT91C_VDD_32_33) - -/////////////////////////////////////////////////////////////////////////////// -// CURRENT_STATE & READY_FOR_DATA in SDCard Status Register definition (response type R1) -/////////////////////////////////////////////////////////////////////////////// -#define AT91C_SR_READY_FOR_DATA (1 << 8) // corresponds to buffer empty signalling on the bus -#define AT91C_SR_IDLE (0 << 9) -#define AT91C_SR_READY (1 << 9) -#define AT91C_SR_IDENT (2 << 9) -#define AT91C_SR_STBY (3 << 9) -#define AT91C_SR_TRAN (4 << 9) -#define AT91C_SR_DATA (5 << 9) -#define AT91C_SR_RCV (6 << 9) -#define AT91C_SR_PRG (7 << 9) -#define AT91C_SR_DIS (8 << 9) - -#define AT91C_SR_CARD_SELECTED (AT91C_SR_READY_FOR_DATA + AT91C_SR_TRAN) - -#define MMC_FIRST_RCA 0xCAFE - -/////////////////////////////////////////////////////////////////////////////// -// MMC CSD register header File -// CSD_x_xxx_S for shift value for word x -// CSD_x_xxx_M for mask value for word x -/////////////////////////////////////////////////////////////////////////////// - -// First Response INT <=> CSD[3] : bits 0 to 31 -#define CSD_3_BIT0_S 0 // [0:0] -#define CSD_3_BIT0_M 0x01 -#define CSD_3_CRC_S 1 // [7:1] -#define CSD_3_CRC_M 0x7F -#define CSD_3_MMC_ECC_S 8 // [9:8] reserved for MMC compatibility -#define CSD_3_MMC_ECC_M 0x03 -#define CSD_3_FILE_FMT_S 10 // [11:10] -#define CSD_3_FILE_FMT_M 0x03 -#define CSD_3_TMP_WP_S 12 // [12:12] -#define CSD_3_TMP_WP_M 0x01 -#define CSD_3_PERM_WP_S 13 // [13:13] -#define CSD_3_PERM_WP_M 0x01 -#define CSD_3_COPY_S 14 // [14:14] -#define CSD_3_COPY_M 0x01 -#define CSD_3_FILE_FMT_GRP_S 15 // [15:15] -#define CSD_3_FILE_FMT_GRP_M 0x01 -// reserved 16 // [20:16] -// reserved 0x1F -#define CSD_3_WBLOCK_P_S 21 // [21:21] -#define CSD_3_WBLOCK_P_M 0x01 -#define CSD_3_WBLEN_S 22 // [25:22] -#define CSD_3_WBLEN_M 0x0F -#define CSD_3_R2W_F_S 26 // [28:26] -#define CSD_3_R2W_F_M 0x07 -#define CSD_3_MMC_DEF_ECC_S 29 // [30:29] reserved for MMC compatibility -#define CSD_3_MMC_DEF_ECC_M 0x03 -#define CSD_3_WP_GRP_EN_S 31 // [31:31] -#define CSD_3_WP_GRP_EN_M 0x01 - -// Seconde Response INT <=> CSD[2] : bits 32 to 63 -#define CSD_2_v21_WP_GRP_SIZE_S 0 // [38:32] -#define CSD_2_v21_WP_GRP_SIZE_M 0x7F -#define CSD_2_v21_SECT_SIZE_S 7 // [45:39] -#define CSD_2_v21_SECT_SIZE_M 0x7F -#define CSD_2_v21_ER_BLEN_EN_S 14 // [46:46] -#define CSD_2_v21_ER_BLEN_EN_M 0x01 - -#define CSD_2_v22_WP_GRP_SIZE_S 0 // [36:32] -#define CSD_2_v22_WP_GRP_SIZE_M 0x1F -#define CSD_2_v22_ER_GRP_SIZE_S 5 // [41:37] -#define CSD_2_v22_ER_GRP_SIZE_M 0x1F -#define CSD_2_v22_SECT_SIZE_S 10 // [46:42] -#define CSD_2_v22_SECT_SIZE_M 0x1F - -#define CSD_2_C_SIZE_M_S 15 // [49:47] -#define CSD_2_C_SIZE_M_M 0x07 -#define CSD_2_VDD_WMAX_S 18 // [52:50] -#define CSD_2_VDD_WMAX_M 0x07 -#define CSD_2_VDD_WMIN_S 21 // [55:53] -#define CSD_2_VDD_WMIN_M 0x07 -#define CSD_2_RCUR_MAX_S 24 // [58:56] -#define CSD_2_RCUR_MAX_M 0x07 -#define CSD_2_RCUR_MIN_S 27 // [61:59] -#define CSD_2_RCUR_MIN_M 0x07 -#define CSD_2_CSIZE_L_S 30 // [63:62] <=> 2 LSB of CSIZE -#define CSD_2_CSIZE_L_M 0x03 - -// Third Response INT <=> CSD[1] : bits 64 to 95 -#define CSD_1_CSIZE_H_S 0 // [73:64] <=> 10 MSB of CSIZE -#define CSD_1_CSIZE_H_M 0x03FF -// reserved 10 // [75:74] -// reserved 0x03 -#define CSD_1_DSR_I_S 12 // [76:76] -#define CSD_1_DSR_I_M 0x01 -#define CSD_1_RD_B_MIS_S 13 // [77:77] -#define CSD_1_RD_B_MIS_M 0x01 -#define CSD_1_WR_B_MIS_S 14 // [78:78] -#define CSD_1_WR_B_MIS_M 0x01 -#define CSD_1_RD_B_PAR_S 15 // [79:79] -#define CSD_1_RD_B_PAR_M 0x01 -#define CSD_1_RD_B_LEN_S 16 // [83:80] -#define CSD_1_RD_B_LEN_M 0x0F -#define CSD_1_CCC_S 20 // [95:84] -#define CSD_1_CCC_M 0x0FFF - -// Fourth Response INT <=> CSD[0] : bits 96 to 127 -#define CSD_0_TRANS_SPEED_S 0 // [103:96] -#define CSD_0_TRANS_SPEED_M 0xFF -#define CSD_0_NSAC_S 8 // [111:104] -#define CSD_0_NSAC_M 0xFF -#define CSD_0_TAAC_S 16 // [119:112] -#define CSD_0_TAAC_M 0xFF -// reserved 24 // [121:120] -// reserved 0x03 -#define CSD_0_MMC_SPEC_VERS_S 26 // [125:122] reserved for MMC compatibility -#define CSD_0_MMC_SPEC_VERS_M 0x0F -#define CSD_0_STRUCT_S 30 // [127:126] -#define CSD_0_STRUCT_M 0x03 - -/////////////////////////////////////////////////////////////////////////////// -#endif diff --git a/sys/boot/arm/at91/libat91/p_string.c b/sys/boot/arm/at91/libat91/p_string.c deleted file mode 100644 index 8e7bbabb8c2c..000000000000 --- a/sys/boot/arm/at91/libat91/p_string.c +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** - * - * Filename: p_string.c - * - * Instantiation of basic string operations to prevent inclusion of full - * string library. These are simple implementations not necessarily optimized - * for speed, but rather to show intent. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin minor updates - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "lib.h" - -/* - * .KB_C_FN_DEFINITION_START - * void p_memset(char *buffer, char value, int size) - * This global function sets memory at the pointer for the specified - * number of bytes to value. - * .KB_C_FN_DEFINITION_END - */ -void -p_memset(char *buffer, char value, int size) -{ - while (size--) - *buffer++ = value; -} - -/* - * .KB_C_FN_DEFINITION_START - * int p_memcmp(char *to, char *from, unsigned size) - * This global function compares data at to against data at from for - * size bytes. Returns 0 if the locations are equal. size must be - * greater than 0. - * .KB_C_FN_DEFINITION_END - */ -int -p_memcmp(const char *to, const char *from, unsigned size) -{ - while ((--size) && (*to++ == *from++)) - continue; - - return (*to != *from); -} diff --git a/sys/boot/arm/at91/libat91/printf.c b/sys/boot/arm/at91/libat91/printf.c deleted file mode 100644 index f2622b859057..000000000000 --- a/sys/boot/arm/at91/libat91/printf.c +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * Copyright (c) 2006 M. Warner Losh - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - * - * $FreeBSD$ - */ - -#include -#include "lib.h" - -void -printf(const char *fmt,...) -{ - va_list ap; - const char *hex = "0123456789abcdef"; - char buf[10]; - char *s; - unsigned u; - int c; - - va_start(ap, fmt); - while ((c = *fmt++)) { - if (c == '%') { - c = *fmt++; - switch (c) { - case 'c': - xputchar(va_arg(ap, int)); - continue; - case 's': - for (s = va_arg(ap, char *); *s; s++) - xputchar(*s); - continue; - case 'd': /* A lie, always prints unsigned */ - case 'u': - u = va_arg(ap, unsigned); - s = buf; - do - *s++ = '0' + u % 10U; - while (u /= 10U); - dumpbuf:; - while (--s >= buf) - xputchar(*s); - continue; - case 'x': - u = va_arg(ap, unsigned); - s = buf; - do - *s++ = hex[u & 0xfu]; - while (u >>= 4); - goto dumpbuf; - } - } - xputchar(c); - } - va_end(ap); - - return; -} diff --git a/sys/boot/arm/at91/libat91/putchar.c b/sys/boot/arm/at91/libat91/putchar.c deleted file mode 100644 index 2b805c98c29b..000000000000 --- a/sys/boot/arm/at91/libat91/putchar.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provided by kwikbyte without - * copyright as follows: - * - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "at91rm9200_lowlevel.h" -#include "lib.h" - -/* - * void putchar(int ch) - * Writes a character to the DBGU port. It assumes that DBGU has - * already been initialized. - */ -void -putchar(int ch) -{ - AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU; - - while (!(pUSART->US_CSR & AT91C_US_TXRDY)) - continue; - pUSART->US_THR = (ch & 0xFF); -} - -void -xputchar(int ch) -{ - if (ch == '\n') - putchar('\r'); - putchar(ch); -} diff --git a/sys/boot/arm/at91/libat91/reset.c b/sys/boot/arm/at91/libat91/reset.c deleted file mode 100644 index b1f083a6e72c..000000000000 --- a/sys/boot/arm/at91/libat91/reset.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#include "at91rm9200.h" -#include "lib.h" - -/* - * void reset() - * - * Forces a reset of the system. Uses watchdog timer of '1', which - * corresponds to 128 / SLCK seconds (SLCK is 32,768 Hz, so 128/32768 is - * 1 / 256 ~= 5.4ms - */ -void -reset(void) -{ - // The following should effect a reset. - AT91C_BASE_ST->ST_WDMR = 1 | AT91C_ST_RSTEN; - AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST; -} - -/* - * void start_wdog() - * - * Starts a watchdog timer. We force the boot process to get to the point - * it can kick the watch dog part of the ST part for the OS's driver. - */ -void -start_wdog(int n) -{ - // The following should effect a reset after N seconds. - AT91C_BASE_ST->ST_WDMR = (n * (32768 / 128)) | AT91C_ST_RSTEN; - AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST; -} diff --git a/sys/boot/arm/at91/libat91/sd-card.c b/sys/boot/arm/at91/libat91/sd-card.c deleted file mode 100644 index d173399c3e1e..000000000000 --- a/sys/boot/arm/at91/libat91/sd-card.c +++ /dev/null @@ -1,517 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -//*---------------------------------------------------------------------------- -//* ATMEL Microcontroller Software Support - ROUSSET - -//*---------------------------------------------------------------------------- -//* The software is delivered "AS IS" without warranty or condition of any -//* kind, either express, implied or statutory. This includes without -//* limitation any warranty or condition with respect to merchantability or -//* fitness for any particular purpose, or against the infringements of -//* intellectual property rights of others. -//*---------------------------------------------------------------------------- -//* File Name : main.c -//* Object : main application written in C -//* Creation : FB 21/11/2002 -//* -//*---------------------------------------------------------------------------- -#include "at91rm9200.h" -#include "lib_AT91RM9200.h" -#include "mci_device.h" -#include "lib.h" -#include "sd-card.h" - -#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ -#define SD_BLOCK_SIZE 512 - -//* Global Variables -static AT91S_MciDevice MCI_Device; - -/****************************************************************************** -**Error return codes -******************************************************************************/ -#define MCI_UNSUPP_SIZE_ERROR 5 -#define MCI_UNSUPP_OFFSET_ERROR 6 - -//*---------------------------------------------------------------------------- -//* \fn MCIDeviceWaitReady -//* \brief Wait for MCI Device ready -//*---------------------------------------------------------------------------- -static unsigned int -MCIDeviceWaitReady(unsigned int timeout) -{ - volatile unsigned int status; - int waitfor; - - if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK) - waitfor = AT91C_MCI_RXBUFF; - else - waitfor = AT91C_MCI_NOTBUSY; - do - { - status = AT91C_BASE_MCI->MCI_SR; - timeout--; - } - while( !(status & waitfor) && (timeout>0) ); - - status = AT91C_BASE_MCI->MCI_SR; - - // If End of Tx Buffer Empty interrupt occurred - if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) { - AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; - MCI_Device.state = AT91C_MCI_IDLE; - } // End of if AT91C_MCI_TXBUFF - - // If End of Rx Buffer Full interrupt occurred - if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) { - AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; - MCI_Device.state = AT91C_MCI_IDLE; - } // End of if AT91C_MCI_RXBUFF - - //printf("WaitReady returning status %x\n", status); - - return status; -} - -static inline unsigned int -swap(unsigned int v) -{ - unsigned int t1; - - __asm __volatile("eor %1, %0, %0, ror #16\n" - "bic %1, %1, #0x00ff0000\n" - "mov %0, %0, ror #8\n" - "eor %0, %0, %1, lsr #8\n" - : "+r" (v), "=r" (t1)); - - return (v); -} - -inline static unsigned int -wait_ready() -{ - int status; - int timeout = AT91C_MCI_TIMEOUT; - - // wait for CMDRDY Status flag to read the response - do - { - status = AT91C_BASE_MCI->MCI_SR; - } while( !(status & AT91C_MCI_CMDRDY) && (--timeout > 0) ); - - return status; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_SendCommand -//* \brief Generic function to send a command to the MMC or SDCard -//*---------------------------------------------------------------------------- -static int -MCI_SendCommand( - unsigned int Cmd, - unsigned int Arg) -{ - unsigned int error; - unsigned int errorMask = AT91C_MCI_SR_ERROR; - unsigned int opcode = Cmd & 0x3F; - - //printf("SendCmd %d (%x) arg %x\n", opcode, Cmd, Arg); - - // Don't check response CRC on ACMD41 (R3 response type). - - if (opcode == 41) - errorMask &= ~AT91C_MCI_RCRCE; - - AT91C_BASE_MCI->MCI_ARGR = Arg; - AT91C_BASE_MCI->MCI_CMDR = Cmd; - - error = wait_ready(); - - if ((error & errorMask) != 0) { - return (1); - } - return 0; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_GetStatus -//* \brief Addressed card sends its status register -//*---------------------------------------------------------------------------- -static unsigned int -MCI_GetStatus() -{ - if (MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16)) - return 0; - return (AT91C_BASE_MCI->MCI_RSPR[0]); - -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_ReadBlock -//* \brief Start the read for a single 512-byte block -//*---------------------------------------------------------------------------- -static int -MCI_StartReadBlock(unsigned blknum, void *dataBuffer) -{ - // Init Mode Register - AT91C_BASE_MCI->MCI_MR |= ((SD_BLOCK_SIZE << 16) | AT91C_MCI_PDCMODE); - - // (PDC) Receiver Transfer Enable - AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); - AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; - AT91C_BASE_PDC_MCI->PDC_RCR = SD_BLOCK_SIZE / 4; - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; - - // SDHC wants block offset, non-HC wants byte offset. - if (!MCI_Device.IsSDHC) - blknum *= SD_BLOCK_SIZE; - - // Send the Read single block command - if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, blknum)) { - return AT91C_READ_ERROR; - } - MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK; - - return 0; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_readblocks -//* \brief Read one or more blocks -//*---------------------------------------------------------------------------- -int -MCI_readblocks(char* dest, unsigned blknum, unsigned blkcount) -{ - unsigned int status; - unsigned int *walker; - - if (MCI_Device.state != AT91C_MCI_IDLE) { - return 1; - } - - if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0) { - return 1; - } - - // As long as there is data to read - while (blkcount) - { - //Do the reading - if (MCI_StartReadBlock(blknum, dest)) - return -1; - - // Wait MCI Device Ready - status = MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); - if (status & AT91C_MCI_SR_ERROR) - return 1; - - // Fix erratum in MCI part - endian-swap all data. - for (walker = (unsigned int *)dest; - walker < (unsigned int *)(dest + SD_BLOCK_SIZE); walker++) - *walker = swap(*walker); - - // Update counters & pointers - ++blknum; - --blkcount; - dest += SD_BLOCK_SIZE; - } - - - return 0; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_read -//* \brief Legacy read function, takes byte offset and length but was always -//* used to read full blocks; interface preserved for existing boot code. -//*---------------------------------------------------------------------------- -int -MCI_read(char* dest, unsigned byteoffset, unsigned length) -{ - return MCI_readblocks(dest, - byteoffset/SD_BLOCK_SIZE, length/SD_BLOCK_SIZE); -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_SDCard_SendAppCommand -//* \brief Specific function to send a specific command to the SDCard -//*---------------------------------------------------------------------------- -static int -MCI_SDCard_SendAppCommand( - unsigned int Cmd_App, - unsigned int Arg) -{ - int status; - - if ((status = MCI_SendCommand(APP_CMD, (MCI_Device.RCA << 16))) == 0) - status = MCI_SendCommand(Cmd_App,Arg); - return status; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_GetCSD -//* \brief Asks to the specified card to send its CSD -//*---------------------------------------------------------------------------- -static int -MCI_GetCSD(unsigned int rca, unsigned int *response) -{ - if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16))) - return 1; - - response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; - response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; - response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; - response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; - - return 0; -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_SDCard_GetOCR -//* \brief Wait for card to power up and determine whether it's SDHC or not. -//*---------------------------------------------------------------------------- -static int -MCI_SDCard_GetOCR() -{ - unsigned int response; - unsigned int arg = AT91C_MMC_HOST_VOLTAGE_RANGE; - int timeout = AT91C_MCI_TIMEOUT; - - // Force card to idle state. - - MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); - - // Begin probe for SDHC by sending CMD8; only v2.0 cards respond to it. - // - // Arg is vvpp where vv is voltage range and pp is an arbitrary bit - // pattern that gets echoed back in the response. The only voltage - // ranges defined are: - // 0x01 = 2.7 - 3.6 - // 0x02 = "reserved for low voltage" whatever that means. - // - // If the card fails to respond then it's not v2.0. If it responds by - // echoing back exactly the arg we sent, then it's a v2.0 card and can - // run at our voltage. That means that when we send the ACMD41 (in - // MCI_SDCard_GetOCR) we can include the HCS bit to inquire about SDHC. - - if (MCI_SendCommand(SD_SEND_IF_COND_CMD, 0x01AA) == 0) { - MCI_Device.IsSDv2 = (AT91C_BASE_MCI->MCI_RSPR[0] == 0x01AA); - } - - // If we've determined the card supports v2.0 functionality, set the - // HCS/CCS bit to indicate that we support SDHC. This will cause a - // v2.0 card to report whether it is SDHC in the ACMD41 response. - - if (MCI_Device.IsSDv2) { - arg |= AT91C_CCS; - } - - // The RCA to be used for CMD55 in Idle state shall be the card's - // default RCA=0x0000. - - MCI_Device.RCA = 0x0; - - // Repeat ACMD41 until the card comes out of power-up-busy state. - - do { - if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD, arg)) { - return 1; - } - response = AT91C_BASE_MCI->MCI_RSPR[0]; - } while (!(response & AT91C_CARD_POWER_UP_DONE) && (--timeout > 0)); - - // A v2.0 card sets CCS (card capacity status) in the response if it's SDHC. - - if (MCI_Device.IsSDv2) { - MCI_Device.IsSDHC = ((response & AT91C_CCS) == AT91C_CCS); - } - - return (0); -} - -//*---------------------------------------------------------------------------- -//* \fn MCI_SDCard_GetCID -//* \brief Asks to the SDCard on the chosen slot to send its CID -//*---------------------------------------------------------------------------- -static int -MCI_SDCard_GetCID(unsigned int *response) -{ - if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT)) - return 1; - - response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; - response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; - response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; - response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; - - return 0; -} - -//*---------------------------------------------------------------------------- -//* \fn sdcard_4wire -//* \brief Set bus width to 1-bit or 4-bit according to the parm. -//* -//* Unlike most functions in this file, the return value from this one is -//* bool-ish; returns 0 on failure, 1 on success. -//*---------------------------------------------------------------------------- -int -sdcard_use4wire(int use4wire) -{ - volatile int ret_value; - - do { - ret_value=MCI_GetStatus(); - } - while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); - - // If going to 4-wire mode, ask the card to turn off the DAT3 card detect - // pullup resistor, if going to 1-wire ask it to turn it back on. - - ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_CLR_CARD_DETECT_CMD, - use4wire ? 0 : 1); - if (ret_value != AT91C_CMD_SEND_OK) - return 0; - - // Ask the card to go into the requested mode. - - ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_BUS_WIDTH_CMD, - use4wire ? AT91C_BUS_WIDTH_4BITS : - AT91C_BUS_WIDTH_1BIT); - if (ret_value != AT91C_CMD_SEND_OK) - return 0; - - // Set the MCI device to match the mode we set in the card. - - if (use4wire) { - MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_4BITS; - AT91C_BASE_MCI->MCI_SDCR |= AT91C_MCI_SCDBUS; - } else { - MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_1BIT; - AT91C_BASE_MCI->MCI_SDCR &= ~AT91C_MCI_SCDBUS; - } - - return 1; -} - -//*---------------------------------------------------------------------------- -//* \fn sdcard_init -//* \brief get the mci device ready to read from an SD or SDHC card. -//* -//* Unlike most functions in this file, the return value from this one is -//* bool-ish; returns 0 on failure, 1 on success. -//*---------------------------------------------------------------------------- -int -sdcard_init(void) -{ - unsigned int tab_response[4]; - int i; - - // Init MCI for MMC and SDCard interface - AT91F_MCI_CfgPIO(); - AT91F_MCI_CfgPMC(); - AT91F_PDC_Open(AT91C_BASE_PDC_MCI); - - // Init Device Structure - MCI_Device.state = AT91C_MCI_IDLE; - MCI_Device.SDCard_bus_width = 0; - MCI_Device.IsSDv2 = 0; - MCI_Device.IsSDHC = 0; - - // Reset the MCI and set the bus speed. - // Using MCK/230 gives a legal (under 400khz) bus speed for the card id - // sequence for all reasonable master clock speeds. - - AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIDIS | 0x80; - AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; - AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES; - AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 114; /* clkdiv 114 = MCK/230 */ - AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_MMC_SLOTA; - AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN|AT91C_MCI_PWSEN; - - // Wait for the card to come out of power-up-busy state by repeatedly - // sending ACMD41. This also probes for SDHC versus standard cards. - - for (i = 0; i < 100; i++) { - if (MCI_SDCard_GetOCR() == 0) - break; - if ((i & 0x01) == 0) { - printf("."); - } - } - if (i >= 100) - return 0; - - if (MCI_SDCard_GetCID(tab_response)) - return 0; - - // Tell the card to set its address, and remember the result. - - if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0)) - return 0; - MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); - - // After sending CMD3 (set addr) we can increase the clock to full speed. - // Using MCK/4 gives a legal (under 25mhz) bus speed for all reasonable - // master clock speeds. - - AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 1; /* clkdiv 1 = MCK/4 */ - - if (MCI_GetCSD(MCI_Device.RCA,tab_response)) - return 0; - MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) & - CSD_1_RD_B_LEN_M; - -#ifdef REPORT_SIZE - { - unsigned int mult,blocknr; - // compute MULT - mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) & - CSD_2_C_SIZE_M_M) + 2 ); - // compute MSB of C_SIZE - blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) & - CSD_1_CSIZE_H_M) << 2; - // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR - blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) & - CSD_2_CSIZE_L_M)) + 1); - MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr; - printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity); - } -#endif - - // Select card and set block length for following transfers. - - if (MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16)) - return 0; - if (MCI_SendCommand(SET_BLOCKLEN_CMD, SD_BLOCK_SIZE)) - return 0; - - return 1; -} diff --git a/sys/boot/arm/at91/libat91/sd-card.h b/sys/boot/arm/at91/libat91/sd-card.h deleted file mode 100644 index 378ad0178901..000000000000 --- a/sys/boot/arm/at91/libat91/sd-card.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. - * - * $FreeBSD$ - */ - -#ifndef __SD_CARD_H -#define __SD_CARD_H - -/* MCI_read() is the original read function, taking a byte offset and byte - * count. It is preserved to support existing customized boot code that still - * refers to it; it will work fine even on SDHC cards as long as the kernel and - * the metadata for locating it all exist within the first 4GB of the card. - * - * MCI_readblocks() is the new read function, taking offset and length in terms - * of block counts (where the SD spec defines a block as 512 bytes), allowing - * the kernel and filesystem metadata to be located anywhere on an SDHC card. - * - * Returns 0 on success, non-zero on failure. - */ - -int MCI_read (char* dest, unsigned bytenum, unsigned length); -int MCI_readblocks (char* dest, unsigned blknum, unsigned blkcount); - -/* sdcard_init() - get things set up to read from an SD or SDHC card. - * - * Returns 0 on failure, non-zero on success. - */ - -int sdcard_init(void); - -/* By default sdcard_init() sets things up for a 1-wire interface to the - * SD card. Calling sdcard_4wire(true) after sdcard_init() allows customized - * boot code to change to 4-bit transfers when the hardware supports it. - * - * Returns 0 on failure, non-zero on success. - */ -int sdcard_use4wire(int use4wire); - -#endif - diff --git a/sys/boot/arm/at91/libat91/spi_flash.c b/sys/boot/arm/at91/libat91/spi_flash.c deleted file mode 100644 index 388e64e2021f..000000000000 --- a/sys/boot/arm/at91/libat91/spi_flash.c +++ /dev/null @@ -1,267 +0,0 @@ -/****************************************************************************** - * - * Filename: spi_flash.c - * - * Instantiation of SPI flash control routines supporting AT45DB161B - * - * Revision information: - * - * 17JAN2005 kb_admin initial creation - * adapted from external sources - * tested for basic operation only!!! - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -#include "at91rm9200.h" -#include "spi_flash.h" -#include "lib.h" - -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ - - -static spiCommand_t spi_command; -static char tx_commandBuffer[8], rx_commandBuffer[8]; - -/* - * .KB_C_FN_DEFINITION_START - * void SendCommand(spiCommand_t *pCommand) - * Private function sends 8-bit value to the device and returns the 8-bit - * value in response. - * .KB_C_FN_DEFINITION_END - */ -static void -SendCommand(spiCommand_t *pCommand) -{ - AT91PS_SPI pSPI = AT91C_BASE_SPI; - - pSPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS; - - pSPI->SPI_RPR = (unsigned)pCommand->rx_cmd; - pSPI->SPI_RCR = pCommand->rx_cmd_size; - pSPI->SPI_TPR = (unsigned)pCommand->tx_cmd; - pSPI->SPI_TCR = pCommand->tx_cmd_size; - - pSPI->SPI_TNPR = (unsigned)pCommand->tx_data; - pSPI->SPI_TNCR = pCommand->tx_data_size; - pSPI->SPI_RNPR = (unsigned)pCommand->rx_data; - pSPI->SPI_RNCR = pCommand->rx_data_size; - - pSPI->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN; - - // wait for completion - while (!(pSPI->SPI_SR & AT91C_SPI_SPENDRX)) - Delay(700); -} - - -/* - * .KB_C_FN_DEFINITION_START - * char GetFlashStatus(void) - * Private function to return device status. - * .KB_C_FN_DEFINITION_END - */ -static char -GetFlashStatus(void) -{ - p_memset((char *)&spi_command, 0, sizeof(spi_command)); - p_memset(tx_commandBuffer, 0, 8); - tx_commandBuffer[0] = STATUS_REGISTER_READ; - p_memset(rx_commandBuffer, 0, 8); - spi_command.tx_cmd = tx_commandBuffer; - spi_command.rx_cmd = rx_commandBuffer; - spi_command.rx_cmd_size = 2; - spi_command.tx_cmd_size = 2; - SendCommand(&spi_command); - return (rx_commandBuffer[1]); -} - -/* - * .KB_C_FN_DEFINITION_START - * void WaitForDeviceReady(void) - * Private function to poll until the device is ready for next operation. - * .KB_C_FN_DEFINITION_END - */ -static void -WaitForDeviceReady(void) -{ - while (!(GetFlashStatus() & 0x80)) ; -} - -/*************************** GLOBAL FUNCTIONS ********************************/ - - -/* - * .KB_C_FN_DEFINITION_START - * void SPI_ReadFlash(unsigned flash_addr, unsigned dest_addr, unsigned size) - * Global function to read the SPI flash device using the continuous read - * array command. - * .KB_C_FN_DEFINITION_END - */ -void -SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size) -{ - unsigned pageAddress, byteAddress; - - // determine page address - pageAddress = flash_addr / FLASH_PAGE_SIZE; - - // determine byte address - byteAddress = flash_addr % FLASH_PAGE_SIZE; - - p_memset(tx_commandBuffer, 0, 8); -#ifdef BOOT_BWCT - tx_commandBuffer[0] = 0xd2; - tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF); - tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) | - ((byteAddress >> 8) & 0x3); - tx_commandBuffer[3] = byteAddress & 0xFF; - spi_command.tx_cmd = tx_commandBuffer; - spi_command.tx_cmd_size = 8; - spi_command.tx_data_size = size; - spi_command.tx_data = dest_addr; - - p_memset(rx_commandBuffer, 0, 8); - spi_command.rx_cmd = rx_commandBuffer; - spi_command.rx_cmd_size = 8; - spi_command.rx_data_size = size; - spi_command.rx_data = dest_addr; -#else - tx_commandBuffer[0] = CONTINUOUS_ARRAY_READ_HF; - tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF); - tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) | - ((byteAddress >> 8) & 0x7); - tx_commandBuffer[3] = byteAddress & 0xFF; - spi_command.tx_cmd = tx_commandBuffer; - spi_command.tx_cmd_size = 5; - spi_command.tx_data_size = size; - spi_command.tx_data = dest_addr; - - p_memset(rx_commandBuffer, 0, 8); - spi_command.rx_cmd = rx_commandBuffer; - spi_command.rx_cmd_size = 5; - spi_command.rx_data_size = size; - spi_command.rx_data = dest_addr; -#endif - - SendCommand(&spi_command); -} - - -/* - * .KB_C_FN_DEFINITION_START - * void SPI_WriteFlash(unsigned flash_addr, unsigned src_addr, unsigned size) - * Global function to program the SPI flash device. Notice the warning - * provided in lower-level functions regarding corruption of data in non- - * page aligned write operations. - * .KB_C_FN_DEFINITION_END - */ -void -SPI_WriteFlash(unsigned flash_addr, char *src_addr, unsigned size) -{ - unsigned pageAddress, byteAddress; - - // determine page address - pageAddress = flash_addr / FLASH_PAGE_SIZE; - - // determine byte address - byteAddress = flash_addr % FLASH_PAGE_SIZE; - - p_memset(tx_commandBuffer, 0, 8); -#ifdef BOOT_BWCT - tx_commandBuffer[0] = 0x82; - tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF); - tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) | - ((byteAddress >> 8) & 0x3); - tx_commandBuffer[3] = (byteAddress & 0xFF); -#else - tx_commandBuffer[0] = PROGRAM_THROUGH_BUFFER; - tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF); - tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) | - ((byteAddress >> 8) & 0x7); - tx_commandBuffer[3] = (byteAddress & 0xFF); -#endif - - p_memset(rx_commandBuffer, 0, 8); - - spi_command.tx_cmd = tx_commandBuffer; - spi_command.rx_cmd = rx_commandBuffer; - spi_command.rx_cmd_size = 4; - spi_command.tx_cmd_size = 4; - - spi_command.tx_data_size = size; - spi_command.tx_data = src_addr; - spi_command.rx_data_size = size; - spi_command.rx_data = src_addr; - - SendCommand(&spi_command); - - WaitForDeviceReady(); -} - -/* - * .KB_C_FN_DEFINITION_START - * void SPI_InitFlash(void) - * Global function to initialize the SPI flash device/accessor functions. - * .KB_C_FN_DEFINITION_END - */ -void -SPI_InitFlash(void) -{ - AT91PS_PIO pPio; - AT91PS_SPI pSPI = AT91C_BASE_SPI; - unsigned value; - - // enable CS0, CLK, MOSI, MISO - pPio = (AT91PS_PIO)AT91C_BASE_PIOA; - pPio->PIO_ASR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 | - AT91C_PIO_PA2; - pPio->PIO_PDR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 | - AT91C_PIO_PA2; - - // enable clocks to SPI - AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_SPI; - - // reset the SPI - pSPI->SPI_CR = AT91C_SPI_SWRST; - - pSPI->SPI_MR = (0xf << 24) | AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | - (0xE << 16); - - pSPI->SPI_CSR[0] = AT91C_SPI_CPOL | (4 << 16) | (2 << 8); - pSPI->SPI_CR = AT91C_SPI_SPIEN; - - pSPI->SPI_PTCR = AT91C_PDC_TXTDIS; - pSPI->SPI_PTCR = AT91C_PDC_RXTDIS; - pSPI->SPI_RNPR = 0; - pSPI->SPI_RNCR = 0; - pSPI->SPI_TNPR = 0; - pSPI->SPI_TNCR = 0; - pSPI->SPI_RPR = 0; - pSPI->SPI_RCR = 0; - pSPI->SPI_TPR = 0; - pSPI->SPI_TCR = 0; - pSPI->SPI_PTCR = AT91C_PDC_RXTEN; - pSPI->SPI_PTCR = AT91C_PDC_TXTEN; - - value = pSPI->SPI_RDR; - value = pSPI->SPI_SR; - - value = GetFlashStatus() & 0xFC; -#ifdef BOOT_BWCT - if (value != 0xB4 && value != 0xAC) - printf(" Bad SPI status: 0x%x\n", value); -#else - if (value != 0xBC) - printf(" Bad SPI status: 0x%x\n", value); -#endif -} diff --git a/sys/boot/arm/at91/libat91/spi_flash.h b/sys/boot/arm/at91/libat91/spi_flash.h deleted file mode 100644 index 90247e1577b0..000000000000 --- a/sys/boot/arm/at91/libat91/spi_flash.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * - * Filename: spi_flash.h - * - * Definition of flash control routines supporting AT45DB161B - * - * Revision information: - * - * 17JAN2005 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ - -#ifndef _SPI_FLASH_H_ -#define _SPI_FLASH_H_ - -typedef struct { - char *tx_cmd; - unsigned tx_cmd_size; - char *rx_cmd; - unsigned rx_cmd_size; - char *tx_data; - unsigned tx_data_size; - char *rx_data; - unsigned rx_data_size; -} spiCommand_t; - -void SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size); -void SPI_WriteFlash(unsigned flash_addr, char *dest_addr, unsigned size); -void SPI_InitFlash(void); - -void SPI_GetId(unsigned *id); - -#ifdef BOOT_BWCT -#define FLASH_PAGE_SIZE 528 -#else -#define FLASH_PAGE_SIZE 1056 -#endif - -// Flash commands - -#define CONTINUOUS_ARRAY_READ 0xE8 -#define CONTINUOUS_ARRAY_READ_HF 0x0B -#define CONTINUOUS_ARRAY_READ_LF 0x03 -#define STATUS_REGISTER_READ 0xD7 -#define PROGRAM_THROUGH_BUFFER 0x82 -#define MANUFACTURER_ID 0x9F - -#endif diff --git a/sys/boot/arm/at91/libat91/strcmp.c b/sys/boot/arm/at91/libat91/strcmp.c deleted file mode 100644 index de1d9e0c1e0b..000000000000 --- a/sys/boot/arm/at91/libat91/strcmp.c +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -#include "lib.h" - -int -strcmp(const char *s1, const char *s2) -{ - for (; *s1 == *s2 && *s1; s1++, s2++); - return (unsigned char)*s1 - (unsigned char)*s2; -} diff --git a/sys/boot/arm/at91/libat91/strcpy.c b/sys/boot/arm/at91/libat91/strcpy.c deleted file mode 100644 index 0bdd3a596dd4..000000000000 --- a/sys/boot/arm/at91/libat91/strcpy.c +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -#include "lib.h" - -char * -strcpy(char *to, const char *from) -{ - while (*from) - *to++ = *from++; - *to++ = '\0'; - return (to); -} diff --git a/sys/boot/arm/at91/libat91/strcvt.c b/sys/boot/arm/at91/libat91/strcvt.c deleted file mode 100644 index 64442cc91bd3..000000000000 --- a/sys/boot/arm/at91/libat91/strcvt.c +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -/****************************************************************************** - * - * Filename: p_string.c - * - * Instantiation of basic string operations to prevent inclusion of full - * string library. These are simple implementations not necessarily optimized - * for speed, but rather to show intent. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin minor updates - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - *****************************************************************************/ - -#include "lib.h" - -/* - * .KB_C_FN_DEFINITION_START - * int p_IsWhiteSpace(char) - * This global function returns true if the character is not considered - * a non-space character. - * .KB_C_FN_DEFINITION_END - */ -int -p_IsWhiteSpace(char cValue) -{ - return ((cValue == ' ') || - (cValue == '\t') || - (cValue == 0) || - (cValue == '\r') || - (cValue == '\n')); -} - - -/* - * .KB_C_FN_DEFINITION_START - * unsigned p_HexCharValue(char) - * This global function returns the decimal value of the validated hex char. - * .KB_C_FN_DEFINITION_END - */ -unsigned -p_HexCharValue(char cValue) -{ - if (cValue < ('9' + 1)) - return (cValue - '0'); - if (cValue < ('F' + 1)) - return (cValue - 'A' + 10); - return (cValue - 'a' + 10); -} - -/* - * .KB_C_FN_DEFINITION_START - * unsigned p_ASCIIToHex(char *) - * This global function set the unsigned value equal to the converted - * hex number passed as a string. No error checking is performed; the - * string must be valid hex value, point at the start of string, and be - * NULL-terminated. - * .KB_C_FN_DEFINITION_END - */ -unsigned -p_ASCIIToHex(const char *buf) -{ - unsigned lValue = 0; - - if ((*buf == '0') && ((buf[1] == 'x') || (buf[1] == 'X'))) - buf += 2; - - while (*buf) { - lValue <<= 4; - lValue += p_HexCharValue(*buf++); - } - return (lValue); -} - - -/* - * .KB_C_FN_DEFINITION_START - * unsigned p_ASCIIToDec(char *) - * This global function set the unsigned value equal to the converted - * decimal number passed as a string. No error checking is performed; the - * string must be valid decimal value, point at the start of string, and be - * NULL-terminated. - * .KB_C_FN_DEFINITION_END - */ -unsigned -p_ASCIIToDec(const char *buf) -{ - unsigned v = 0; - - while (*buf) { - v *= 10; - v += (*buf++) - '0'; - } - return (v); -} diff --git a/sys/boot/arm/at91/libat91/strlen.c b/sys/boot/arm/at91/libat91/strlen.c deleted file mode 100644 index 35de89262a51..000000000000 --- a/sys/boot/arm/at91/libat91/strlen.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -/****************************************************************************** - * - * Filename: p_string.c - * - * Instantiation of basic string operations to prevent inclusion of full - * string library. These are simple implementations not necessarily optimized - * for speed, but rather to show intent. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin minor updates - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - *****************************************************************************/ - -#include "lib.h" - -/* - * .KB_C_FN_DEFINITION_START - * int p_strlen(char *) - * This global function returns the number of bytes starting at the pointer - * before (not including) the string termination character ('/0'). - * .KB_C_FN_DEFINITION_END - */ -int -p_strlen(const char *buffer) -{ - const char *ptr = buffer; - while (*ptr++) - continue; - return (ptr - buffer - 1); -} diff --git a/sys/boot/arm/at91/libat91/tag_list.c b/sys/boot/arm/at91/libat91/tag_list.c deleted file mode 100644 index c6a9bba82377..000000000000 --- a/sys/boot/arm/at91/libat91/tag_list.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - * - * Filename: tag_list.c - * - * Instantiation of basic routines that create linux-boot tag list. - * - * Revision information: - * - * 22AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - *****************************************************************************/ - -/******************************* GLOBALS *************************************/ - -/********************** PRIVATE FUNCTIONS/DATA/DEFINES ***********************/ - -#define u32 unsigned -#define u16 unsigned short -#define u8 unsigned char - -// #include "/usr/src/arm/linux/include/asm/setup.h" -#include -#include "tag_list.h" - -#define PAGE_SIZE 0x1000 -#define MEM_SIZE 0x2000000 -#define PHYS_OFFSET 0x20000000 - -/*************************** GLOBAL FUNCTIONS ********************************/ - -/* - * .KB_C_FN_DEFINITION_START - * void InitTagList(char*, void *) - * This global function populates a linux-boot style tag list from the - * string passed in the pointer at the location specified. - * .KB_C_FN_DEFINITION_END - */ -void InitTagList(char *parms, void *output) { - - char *src, *dst; - struct tag *tagList = (struct tag*)output; - - tagList->hdr.size = tag_size(tag_core); - tagList->hdr.tag = ATAG_CORE; - tagList->u.core.flags = 1; - tagList->u.core.pagesize = PAGE_SIZE; - tagList->u.core.rootdev = 0xff; - tagList = tag_next(tagList); - - tagList->hdr.size = tag_size(tag_mem32); - tagList->hdr.tag = ATAG_MEM; - tagList->u.mem.size = MEM_SIZE; - tagList->u.mem.start = PHYS_OFFSET; - tagList = tag_next(tagList); - - tagList->hdr.size = tag_size(tag_cmdline); - tagList->hdr.tag = ATAG_CMDLINE; - - src = parms; - dst = tagList->u.cmdline.cmdline; - while (*src) { - *dst++ = *src++; - } - *dst = 0; - - tagList->hdr.size += ((unsigned)(src - parms) + 1) / sizeof(unsigned); - tagList = tag_next(tagList); - - tagList->hdr.size = 0; - tagList->hdr.tag = ATAG_NONE; -} diff --git a/sys/boot/arm/at91/libat91/tag_list.h b/sys/boot/arm/at91/libat91/tag_list.h deleted file mode 100644 index f98016510d5e..000000000000 --- a/sys/boot/arm/at91/libat91/tag_list.h +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** - * - * Filename: tag_list.h - * - * Definition of basic routines that create linux-boot tag list. - * - * Revision information: - * - * 22AUG2004 kb_admin initial creation - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ****************************************************************************/ - -#ifndef _TAG_LIST_H_ -#define _TAG_LIST_H_ - -extern void InitTagList(char *parms, void*); - -#endif /* _TAG_LIST_H_ */ diff --git a/sys/boot/arm/at91/libat91/xmodem.c b/sys/boot/arm/at91/libat91/xmodem.c deleted file mode 100644 index 0c4b1387dcb2..000000000000 --- a/sys/boot/arm/at91/libat91/xmodem.c +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 2006 M. Warner Losh. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * This software is derived from software provide by Kwikbyte who specifically - * disclaimed copyright on the code. This version of xmodem has been nearly - * completely rewritten, but the CRC is from the original. - * - * $FreeBSD$ - */ - -#include "lib.h" - -#define PACKET_SIZE 128 - -/* Line control codes */ -#define SOH 0x01 /* start of header */ -#define ACK 0x06 /* Acknowledge */ -#define NAK 0x15 /* Negative acknowledge */ -#define CAN 0x18 /* Cancel */ -#define EOT 0x04 /* end of text */ - -#define TO 10 -/* - * int GetRecord(char , char *) - * This private function receives a x-modem record to the pointer and - * returns non-zero on success. - */ -static int -GetRecord(char blocknum, char *dest) -{ - int size; - int ch; - unsigned chk, j; - - chk = 0; - - if ((ch = getc(TO)) == -1) - goto err; - if (ch != blocknum) - goto err; - if ((ch = getc(TO)) == -1) - goto err; - if (ch != (~blocknum & 0xff)) - goto err; - - for (size = 0; size < PACKET_SIZE; ++size) { - if ((ch = getc(TO)) == -1) - goto err; - chk = chk ^ ch << 8; - for (j = 0; j < 8; ++j) { - if (chk & 0x8000) - chk = chk << 1 ^ 0x1021; - else - chk = chk << 1; - } - *dest++ = ch; - } - - chk &= 0xFFFF; - - if (((ch = getc(TO)) == -1) || ((ch & 0xff) != ((chk >> 8) & 0xFF))) - goto err; - if (((ch = getc(TO)) == -1) || ((ch & 0xff) != (chk & 0xFF))) - goto err; - putchar(ACK); - - return (1); -err:; - putchar(CAN); - // We should allow for resend, but we don't. - return (0); -} - -/* - * int xmodem_rx(char *) - * This global function receives a x-modem transmission consisting of - * (potentially) several blocks. Returns the number of bytes received or - * -1 on error. - */ -int -xmodem_rx(char *dest) -{ - int starting, ch; - char packetNumber, *startAddress = dest; - - packetNumber = 1; - starting = 1; - - while (1) { - if (starting) - putchar('C'); - if (((ch = getc(1)) == -1) || (ch != SOH && ch != EOT)) - continue; - if (ch == EOT) { - putchar(ACK); - return (dest - startAddress); - } - starting = 0; - // Xmodem packets: SOH PKT# ~PKT# 128-bytes CRC16 - if (!GetRecord(packetNumber, dest)) - return (-1); - dest += PACKET_SIZE; - packetNumber++; - } - - // the loop above should return in all cases - return (-1); -} diff --git a/sys/boot/arm/at91/linker.cfg b/sys/boot/arm/at91/linker.cfg deleted file mode 100644 index 2065ed71936d..000000000000 --- a/sys/boot/arm/at91/linker.cfg +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * - * Filename: linker.cfg - * - * linker config file used for internal RAM or eeprom images at address 0. - * - * Revision information: - * - * 20AUG2004 kb_admin initial creation - * 12JAN2005 kb_admin move data to SDRAM - * - * BEGIN_KBDD_BLOCK - * No warranty, expressed or implied, is included with this software. It is - * provided "AS IS" and no warranty of any kind including statutory or aspects - * relating to merchantability or fitness for any purpose is provided. All - * intellectual property rights of others is maintained with the respective - * owners. This software is not copyrighted and is intended for reference - * only. - * END_BLOCK - * - * $FreeBSD$ - ******************************************************************************/ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(start) -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .text : - { - *(.text) - } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .data : - { - __data_start = . ; - *(.data) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - __bss_start__ = .; - .bss : - { - *(.bss) - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; - PROVIDE (end = .); -} diff --git a/sys/boot/arm/ixp425/Makefile.inc b/sys/boot/arm/ixp425/Makefile.inc deleted file mode 100644 index 031b7afa616e..000000000000 --- a/sys/boot/arm/ixp425/Makefile.inc +++ /dev/null @@ -1,42 +0,0 @@ -# $FreeBSD$ - -.if !target(__ixp425_boot_Makefile.inc__) -.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm - -__ixp425_boot_Makefile.inc__: - -# Both Avila and Pronghorn Metro are supported by ixp425 -BOOT_FLAVOR=ixp425 - -CFLAGS+=-Os -ffreestanding \ - -I${.CURDIR}/../../../.. \ - -I${.CURDIR}/../../../../arm \ - -DCPU_XSCALE_IXP425 \ - -Wall -Waggregate-return \ - -Werror \ - -Wnested-externs \ - -Wpointer-arith -Wshadow -Wwrite-strings \ - -Wmissing-prototypes \ - -Wmissing-declarations - -# -Wstrict-prototypes - -CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu} - -LD ?= ld -OBJCOPY ?= objcopy - -.if defined(P) -${P}: ${OBJS} - ${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS} - -CLEANFILES+= ${P} -.endif - -.if defined(WITH_TAG_LIST) -MK_TAG_LIST:=yes -.else -MK_TAG_LIST:=no -.endif - -.endif diff --git a/sys/boot/arm/ixp425/boot2/Makefile b/sys/boot/arm/ixp425/boot2/Makefile deleted file mode 100644 index fe1068faefaa..000000000000 --- a/sys/boot/arm/ixp425/boot2/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -# $FreeBSD$ - -.include - -# We get a lot of the std lib functions from here. -.PATH: ${.CURDIR}/../../at91/libat91 - -# Enable to get debug msgs -#DEBUG=yes - -# Hack to search through the kernel for ufs:ad0s1a and replace it with -# the correct one for the active slice/partition. -FIXUP_BOOT_DRV=yes - -P=boot2 -FILES=${P} -SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c -SRCS+=memchr.c memcmp.c memcpy.c memmem.c memset.c printf.c strcmp.c strcpy.c -SRCS+=strlen.c ashldi3.c divsi3.S muldi3.c -SRCS+=aeabi_unwind.c -MAN= - -KERNPHYSADDR=0x180000 -KERNVIRTADDR=${KERNPHYSADDR} -BOOT_STACK=0x200000-4 -M=${MACHINE} -LDFLAGS=-e ${KERNPHYSADDR} -EB -T ldscript.${M} -OBJS+= ${SRCS:N*.h:R:S/$/.o/g} -S=${.CURDIR}/../../../.. - -CFLAGS+= \ - -DBOOT_STACK=${BOOT_STACK} \ - -I${.CURDIR}/../../../common \ - -I${.CURDIR} - -.if defined(FIXUP_BOOT_DRV) -CFLAGS+=-DFIXUP_BOOT_DRV -.endif -.if defined(DEBUG) -CFLAGS+=-DDEBUG -.endif - -ldscript.$M: $S/conf/ldscript.$M - cat $S/conf/ldscript.$M|sed s/KERNPHYSADDR/${KERNPHYSADDR}/g| \ - sed s/KERNVIRTADDR/${KERNVIRTADDR}/g | \ - sed s/" + SIZEOF_HEADERS"// > ldscript.$M - -${P}: ldscript.$M - -CLEANFILES+=ldscript.$M - -memchr.c: $S/../lib/libc/string/memchr.c - sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memchr.c > \ - ${.TARGET} - -memmem.c: $S/../lib/libc/string/memmem.c - sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memmem.c > \ - ${.TARGET} - -CLEANFILES+=memchr.c memmem.c - -ashldi3.o: $S/libkern/ashldi3.c - ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC} - -divsi3.o: $S/libkern/${M}/divsi3.S - ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC} - -muldi3.o: $S/libkern/${M}/muldi3.c - ${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC} - -inflate.c: $S/kern/inflate.c - sed -e 's/extern void putstr (char/extern void putstr (const char/' < \ - $S/kern/inflate.c > ${.TARGET} - -CLEANFILES+=inflate.c - -.include - diff --git a/sys/boot/arm/ixp425/boot2/arm_init.S b/sys/boot/arm/ixp425/boot2/arm_init.S deleted file mode 100644 index 15e1e6c87ed8..000000000000 --- a/sys/boot/arm/ixp425/boot2/arm_init.S +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#include - -ASENTRY_NP(start) -/* Initialise bss and sp */ - nop - adr r1, .Lstart - ldmia r1, {r1, r2, sp} /* Set initial stack and */ - sub r2, r2, r1 /* get zero init data */ - mov r3, #0 -.L1: - str r3, [r1], #0x0004 /* get zero init data */ - subs r2, r2, #4 - bgt .L1 - - .extern main - bl main -/* main should not return. If it does, spin forever */ -infiniteLoop: - b infiniteLoop -END(start) - -.Lstart: - .word _edata - .word _end - .word BOOT_STACK - -ENTRY(cpu_id) - mrc p15, 0, r0, c0, c0, 0 - RET -END(cpu_id) - -/* End */ diff --git a/sys/boot/arm/ixp425/boot2/boot2.c b/sys/boot/arm/ixp425/boot2/boot2.c deleted file mode 100644 index 93c4fe1aff53..000000000000 --- a/sys/boot/arm/ixp425/boot2/boot2.c +++ /dev/null @@ -1,446 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include - -#include - -#include "lib.h" -#include "paths.h" -#include "rbx.h" - -extern uint32_t _end; - -#define NOPT 6 - -static const char optstr[NOPT] = "agnrsv"; -static const unsigned char flags[NOPT] = { - RBX_ASKNAME, - RBX_GDB, - RBX_NOINTR, - RBX_DFLTROOT, - RBX_SINGLE, - RBX_VERBOSE -}; - -static unsigned dsk_start; -static char cmd[512]; -static char kname[1024]; -static uint32_t opts; -static uint8_t dsk_meta; -static int bootslice; -static int bootpart; -static int disk_layout; -#define DL_UNKNOWN 0 -#define DL_RAW 1 /* Dangerously dedicated */ -#define DL_SLICE 2 /* Use only slices (DOS partitions) */ -#define DL_SLICEPART 3 /* Use slices and partitions */ - -static void load(void); -static int parse(void); -static int dskread(void *, unsigned, unsigned); -static int drvread(void *, unsigned, unsigned); -#ifdef FIXUP_BOOT_DRV -static void fixup_boot_drv(caddr_t, int, int, int); -#endif - -#include "ufsread.c" - -#ifdef DEBUG -#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif - -static inline int -xfsread(ufs_ino_t inode, void *buf, size_t nbyte) -{ - if ((size_t)fsread(inode, buf, nbyte) != nbyte) - return -1; - return 0; -} - -static inline void -getstr(int c) -{ - char *s; - - s = cmd; - if (c == 0) - c = getc(10000); - for (;;) { - switch (c) { - case 0: - break; - case '\177': - case '\b': - if (s > cmd) { - s--; - printf("\b \b"); - } - break; - case '\n': - case '\r': - *s = 0; - return; - default: - if (s - cmd < sizeof(cmd) - 1) - *s++ = c; - xputchar(c); - } - c = getc(10000); - } -} - -int -main(void) -{ - const char *bt; - int autoboot, c = 0; - ufs_ino_t ino; - - dmadat = (void *)(0x1c0000); - p_memset((char *)dmadat, 0, 32 * 1024); - bt = board_init(); - - printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 4); - - autoboot = 1; - - /* Process configuration file */ - if ((ino = lookup(PATH_CONFIG)) || - (ino = lookup(PATH_DOTCONFIG))) - fsread(ino, cmd, sizeof(cmd)); - - if (*cmd) { - if (parse()) - autoboot = 0; - printf("%s: %s\n", PATH_CONFIG, cmd); - /* Do not process this command twice */ - *cmd = 0; - } - - if (*kname == '\0') - strcpy(kname, PATH_KERNEL); - - /* Present the user with the boot2 prompt. */ - for (;;) { - printf("\nDefault: %s\nboot: ", kname); - if (!autoboot || - (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0)) - getstr(c); - xputchar('\n'); - autoboot = 0; - c = 0; - DPRINTF("cmd is '%s'\n", cmd); - if (parse()) - xputchar('\a'); - else - load(); - } -} - -static void -load(void) -{ - Elf32_Ehdr eh; - static Elf32_Phdr ep[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr; - int i, j; -#ifdef FIXUP_BOOT_DRV - caddr_t staddr; - int klen; - - staddr = (caddr_t)0xffffffff; - klen = 0; -#endif - if (!(ino = lookup(kname))) { - if (!ls) - printf("No %s\n", kname); - return; - } - DPRINTF("Found %s\n", kname); - if (xfsread(ino, &eh, sizeof(eh))) - return; - if (!IS_ELF(eh)) { - printf("Invalid %s\n", "format"); - return; - } - fs_off = eh.e_phoff; - for (j = i = 0; i < eh.e_phnum && j < 2; i++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) - return; - if (ep[j].p_type == PT_LOAD) - j++; - } - for (i = 0; i < 2; i++) { - p = (caddr_t)(ep[i].p_paddr & 0x0fffffff); - fs_off = ep[i].p_offset; -#ifdef FIXUP_BOOT_DRV - if (staddr == (caddr_t)0xffffffff) - staddr = p; - klen += ep[i].p_filesz; -#endif - if (xfsread(ino, p, ep[i].p_filesz)) - return; - } - addr = eh.e_entry & 0x0fffffff; - DPRINTF("Entry point %x for %s\n", addr, kname); - clr_board(); -#ifdef FIXUP_BOOT_DRV - fixup_boot_drv(staddr, klen, bootslice, bootpart); -#endif - ((void(*)(int))addr)(RB_BOOTINFO /* XXX | (opts & RBX_MASK) */); -} - -static int -parse() -{ - char *arg = cmd; - char *ep, *p; - int c, i; - - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(flags[i]); - } - } else { - arg--; - /* look for ad0s1a:... | ad0s1:... */ - if (strlen(arg) > 6 && arg[0] == 'a' && - arg[1] == 'd' && arg[3] == 's' && - (arg[5] == ':' || arg[6] == ':')) { - /* XXX Should also handle disk. */ - bootslice = arg[4] - '0'; - if (bootslice < 1 || bootslice > 4) - return (-1); - bootpart = 0; - if (arg[5] != ':') - bootpart = arg[5] - 'a'; - if (bootpart < 0 || bootpart > 7) - return (-1); - dsk_meta = 0; - if (arg[5] == ':') - arg += 6; - else - arg += 7; - /* look for ad0a:... */ - } else if (strlen(arg) > 4 && arg[0] == 'a' && - arg[1] == 'd' && arg[2] == '0' && arg[4] == ':') { - bootslice = 0; - bootpart = arg[3] - 'a'; - if (bootpart < 0 || bootpart > 7) - return (-1); - dsk_meta = 0; - arg += 5; - } - if ((i = ep - arg)) { - if ((size_t)i >= sizeof(kname)) - return -1; - memcpy(kname, arg, i + 1); - } - } - arg = p; - } - return 0; -} - -/* - * dskread() will try to handle the disk layouts that are typically - * encountered. - * - raw or "Dangerously Dedicated" mode. No real slice table, just the - * default one that is included with bsdlabel -B. Typically this is - * used with ROOTDEVNAME=\"ufs:ad0a\". - * - slice only. Only a slice table is installed with no bsd label or - * bsd partition table. This is typically used with - * ROOTDEVNAME=\"ufs:ad0s1\". - * - slice + bsd label + partition table. This is typically done with - * with fdisk + bsdlabel and is used with ROOTDEVNAME=\"ufs:ad0s1a\". - */ -static int -dskread(void *buf, unsigned lba, unsigned nblk) -{ - struct dos_partition *dp; - struct disklabel *d; - char *sec; - int i; - - if (!dsk_meta) { - sec = dmadat->secbuf; - dsk_start = 0; - if (drvread(sec, DOSBBSECTOR, 1)) - return -1; - dp = (void *)(sec + DOSPARTOFF); - if (bootslice != 0) { - i = bootslice - 1; - if (dp[i].dp_typ != DOSPTYP_386BSD) - return -1; - } else { - for (i = 0; i < NDOSPART; i++) { - if ((dp[i].dp_typ == DOSPTYP_386BSD) && - (dp[i].dp_flag == 0x80)) - break; - } - } - if (i != NDOSPART) { - bootslice = i + 1; - DPRINTF("Found an active fbsd slice. (%d)\n", i + 1); - /* - * Although dp_start is aligned within the disk - * partition structure, DOSPARTOFF is 446, which - * is only word (2) aligned, not longword (4) - * aligned. Cope by using memcpy to fetch the - * start of this partition. - */ - memcpy(&dsk_start, &dp[i].dp_start, 4); - dsk_start = swap32(dsk_start); - DPRINTF("dsk_start %x\n", dsk_start); - if ((bootslice == 4) && (dsk_start == 0)) { - disk_layout = DL_RAW; - bootslice = 0; - } - } - if (drvread(sec, dsk_start + LABELSECTOR, 1)) - return -1; - d = (void *)(sec + LABELOFFSET); - if ((d->d_magic == DISKMAGIC && d->d_magic2 == DISKMAGIC) || - (swap32(d->d_magic) == DISKMAGIC && - swap32(d->d_magic2) == DISKMAGIC)) { - DPRINTF("p_size = %x\n", - !d->d_partitions[bootpart].p_size); - if (!d->d_partitions[bootpart].p_size) { - printf("Invalid partition\n"); - return -1; - } - DPRINTF("p_offset %x, RAW %x\n", - swap32(d->d_partitions[bootpart].p_offset), - swap32(d->d_partitions[RAW_PART].p_offset)); - dsk_start += swap32(d->d_partitions[bootpart].p_offset); - dsk_start -= swap32(d->d_partitions[RAW_PART].p_offset); - if ((disk_layout == DL_UNKNOWN) && (bootslice == 0)) - disk_layout = DL_RAW; - else if (disk_layout == DL_UNKNOWN) - disk_layout = DL_SLICEPART; - } else { - disk_layout = DL_SLICE; - DPRINTF("Invalid %s\n", "label"); - } - DPRINTF("bootslice %d, bootpart %d, dsk_start %u\n", bootslice, - bootpart, dsk_start); - dsk_meta++; - } - return drvread(buf, dsk_start + lba, nblk); -} - -static int -drvread(void *buf, unsigned lba, unsigned nblk) -{ - static unsigned c = 0x2d5c7c2f; - - printf("%c\b", c = c << 8 | c >> 24); - return (avila_read((char *)buf, lba, nblk)); -} - -#ifdef FIXUP_BOOT_DRV -/* - * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel - * and change it to what was specified on the comandline or /boot.conf - * file or to what was encountered on the disk. It will try to handle 3 - * different disk layouts, raw (dangerously dedicated), slice only and - * slice + partition. It will look for the following strings in the - * kernel, but if it is one of the first three, the string in the kernel - * must use the correct form to match the actual disk layout: - * - ufs:ad0a - * - ufs:ad0s1 - * - ufs:ad0s1a - * - ufs:ROOTDEVNAME - * In the case of the first three strings, only the "a" at the end and - * the "1" after the "s" will be modified, if they exist. The string - * length will not be changed. In the case of the last string, the - * whole string will be built up and nul, '\0' terminated. - */ -static void -fixup_boot_drv(caddr_t addr, int klen, int bs, int bp) -{ - const u_int8_t op[] = "ufs:ROOTDEVNAME"; - const u_int8_t op2[] = "ufs:ad0"; - u_int8_t *p, *ps; - - DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n", - (int)addr, klen, bs, bp); - if (bs > 4) - return; - if (bp > 7) - return; - ps = memmem(addr, klen, op, sizeof(op)); - if (ps != NULL) { - p = ps + 4; /* past ufs: */ - DPRINTF("Found it at 0x%x\n", (int)ps); - p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */ - p += 3; - if (bs > 0) { - /* append slice */ - *p++ = 's'; - *p++ = bs + '0'; - } - if (disk_layout != DL_SLICE) { - /* append partition */ - *p++ = bp + 'a'; - } - *p = '\0'; - } else { - ps = memmem(addr, klen, op2, sizeof(op2) - 1); - if (ps != NULL) { - p = ps + sizeof(op2) - 1; - DPRINTF("Found it at 0x%x\n", (int)ps); - if (*p == 's') { - /* fix slice */ - p++; - *p++ = bs + '0'; - } - if (*p == 'a') - *p = bp + 'a'; - } - } - if (ps == NULL) { - printf("Could not locate \"%s\" to fix kernel boot device, " - "check ROOTDEVNAME is set\n", op); - return; - } - DPRINTF("Changed boot device to %s\n", ps); -} -#endif diff --git a/sys/boot/arm/ixp425/boot2/cf_ata.h b/sys/boot/arm/ixp425/boot2/cf_ata.h deleted file mode 100644 index 3c9e9e5facae..000000000000 --- a/sys/boot/arm/ixp425/boot2/cf_ata.h +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef ARM_BOOT_CF_ATA_H -#define ARM_BOOT_CF_ATA_H - -#define CF_DATA 0x00 -#define CF_ERROR 0x01 -#define CF_FEATURE 0x01 -#define CF_SECT_CNT 0x02 -#define CF_SECT_NUM 0x03 -#define CF_CYL_L 0x04 -#define CF_CYL_H 0x05 -#define CF_DRV_HEAD 0x06 -#define CF_D_MASTER 0x00 -#define CF_D_LBA 0x40 -#define CF_D_IBM 0xa0 -#define CF_STATUS 0x07 -#define CF_S_ERROR 0x01 -#define CF_S_INDEX 0x02 -#define CF_S_CORR 0x04 -#define CF_S_DRQ 0x08 -#define CF_S_DSC 0x10 -#define CF_S_DWF 0x20 -#define CF_S_READY 0x40 -#define CF_S_BUSY 0x80 -#define CF_COMMAND 0x07 - -/* This is according to the appnote, but Sam use 0x1e in avila_ata.c */ -#define CF_ALT_STATUS 0x16 -#define CF_ALT_DEV_CTR 0x16 -#define CF_ALT_DEV_CTR2 0x1e -#define CF_A_IDS 0x02 -#define CF_A_RESET 0x04 -#define CF_A_4BIT 0x08 - -#define AVILA_IDE_GPIN 12 - -#endif /* !ARM_BOOT_CF_ATA_H */ diff --git a/sys/boot/arm/ixp425/boot2/ixp425_board.c b/sys/boot/arm/ixp425/boot2/ixp425_board.c deleted file mode 100644 index c13f8ed52694..000000000000 --- a/sys/boot/arm/ixp425/boot2/ixp425_board.c +++ /dev/null @@ -1,771 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); -#include -#include -#include - -#include - -#include "lib.h" -#include "cf_ata.h" - -#include -#include -#include - -struct board_config { - const char *desc; - int (*probe)(int boardtype_hint); - void (*init)(void); -}; -/* set of registered boards */ -SET_DECLARE(boards, struct board_config); -#define BOARD_CONFIG(name, _desc) \ -static struct board_config name##config = { \ - .desc = _desc, \ - .probe = name##_probe, \ - .init = name##_init, \ -}; \ -DATA_SET(boards, name##config) - -static u_int cputype; -#define cpu_is_ixp43x() (cputype == CPU_ID_IXP435) -static u_int8_t *ubase; - -static u_int8_t uart_getreg(u_int8_t *, int); -static void uart_setreg(u_int8_t *, int, u_int8_t); - -static void cf_init(void); -static void cf_clr(void); - -#ifdef DEBUG -#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif - -const char * -board_init(void) -{ - struct board_config **pbp; - - cputype = cpu_id() & CPU_ID_CPU_MASK; - - SET_FOREACH(pbp, boards) - /* XXX pass down redboot board type */ - if ((*pbp)->probe(0)) { - (*pbp)->init(); - return (*pbp)->desc; - } - /* XXX panic, unknown board type */ - return "???"; -} - -/* - * This should be called just before starting the kernel. This is so - * that one can undo incompatible hardware settings. - */ -void -clr_board(void) -{ - cf_clr(); -} - -/* - * General support functions. - */ - -/* - * DELAY should delay for the number of microseconds. - * The idea is that the inner loop should take 1us, so val is the - * number of usecs to delay. - */ -void -DELAY(int val) -{ - volatile int sub; - volatile int subsub; - - sub = val; - while(sub) { - subsub = 3; - while(subsub) - subsub--; - sub--; - } -} - -u_int32_t -swap32(u_int32_t a) -{ - return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | - ((a & 0xff0000) >> 8) | ((a & 0xff000000) >> 24)); -} - -u_int16_t -swap16(u_int16_t val) -{ - return (val << 8) | (val >> 8); -} - -/* - * uart related funcs - */ -static u_int8_t -uart_getreg(u_int8_t *bas, int off) -{ - return *((volatile u_int32_t *)(bas + (off << 2))) & 0xff; -} - -static void -uart_setreg(u_int8_t *bas, int off, u_int8_t val) -{ - *((volatile u_int32_t *)(bas + (off << 2))) = (u_int32_t)val; -} - -int -getc(int seconds) -{ - int c, delay, limit; - - c = 0; - delay = 10000; - limit = seconds * 1000000/10000; - while ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == 0 && --limit) - DELAY(delay); - - if ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == LSR_RXRDY) - c = uart_getreg(ubase, REG_DATA); - - return c; -} - -void -putchar(int ch) -{ - int delay, limit; - - delay = 500; - limit = 20; - while ((uart_getreg(ubase, REG_LSR) & LSR_THRE) == 0 && --limit) - DELAY(delay); - uart_setreg(ubase, REG_DATA, ch); - - limit = 40; - while ((uart_getreg(ubase, REG_LSR) & LSR_TEMT) == 0 && --limit) - DELAY(delay); -} - -void -xputchar(int ch) -{ - if (ch == '\n') - putchar('\r'); - putchar(ch); -} - -void -putstr(const char *str) -{ - while(*str) - xputchar(*str++); -} - -void -puthex8(u_int8_t ch) -{ - const char *hex = "0123456789abcdef"; - - putchar(hex[ch >> 4]); - putchar(hex[ch & 0xf]); -} - -void -puthexlist(const u_int8_t *str, int length) -{ - while(length) { - puthex8(*str); - putchar(' '); - str++; - length--; - } -} - -/* - * - * CF/IDE functions. - * - */ - -struct { - u_int64_t dsize; - u_int64_t total_secs; - u_int8_t heads; - u_int8_t sectors; - u_int32_t cylinders; - - u_int32_t *cs1to; - u_int32_t *cs2to; - - u_int8_t *cs1; - u_int8_t *cs2; - - u_int32_t use_lba; - u_int32_t use_stream8; - u_int32_t debug; - - u_int8_t status; - u_int8_t error; -} dskinf; - -static void cfenable16(void); -static void cfdisable16(void); -static u_int8_t cfread8(u_int32_t off); -static u_int16_t cfread16(u_int32_t off); -static void cfreadstream8(void *buf, int length); -static void cfreadstream16(void *buf, int length); -static void cfwrite8(u_int32_t off, u_int8_t val); -static u_int8_t cfaltread8(u_int32_t off); -static void cfaltwrite8(u_int32_t off, u_int8_t val); -static int cfwait(u_int8_t mask); -static int cfaltwait(u_int8_t mask); -static int cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head, - u_int32_t sector, u_int32_t count, u_int32_t feature); -static void cfreset(void); -#ifdef DEBUG -static int cfgetparams(void); -#endif -static void cfprintregs(void); - -static void -cf_init(void) -{ - u_int8_t status; -#ifdef DEBUG - int rval; -#endif - - /* NB: board init routines setup other parts of dskinf */ - dskinf.use_stream8 = 0; - dskinf.use_lba = 0; - dskinf.debug = 1; - - DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2); - - /* Setup the CF window */ - *dskinf.cs1to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); - DPRINTF("t1 %x, ", *dskinf.cs1to); - - *dskinf.cs2to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); - DPRINTF("t2 %x\n", *dskinf.cs2to); - - /* Detect if there is a disk. */ - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1000); - status = cfread8(CF_STATUS); - if (status != 0x50) - printf("cf-ata0 %x\n", (u_int32_t)status); - if (status == 0xff) { - printf("cf_ata0: No disk!\n"); - return; - } - - cfreset(); - - if (dskinf.use_stream8) { - DPRINTF("setting %d bit mode.\n", 8); - cfwrite8(CF_FEATURE, 0x01); /* Enable 8 bit transfers */ - cfwrite8(CF_COMMAND, ATA_SETFEATURES); - cfaltwait(CF_S_READY); - } - -#ifdef DEBUG - rval = cfgetparams(); - if (rval) - return; -#endif - dskinf.use_lba = 1; - dskinf.debug = 0; -} - -static void -cf_clr(void) -{ - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - cfaltwait(CF_S_READY); - cfwrite8(CF_FEATURE, 0x81); /* Enable 8 bit transfers */ - cfwrite8(CF_COMMAND, ATA_SETFEATURES); - cfaltwait(CF_S_READY); -} - -static void -cfenable16(void) -{ - u_int32_t val; - - val = *dskinf.cs1to; - *dskinf.cs1to = val &~ EXP_BYTE_EN; - DELAY(100); -#if 0 - DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__); -#endif -} - -static void -cfdisable16(void) -{ - u_int32_t val; - - DELAY(100); - val = *dskinf.cs1to; - *dskinf.cs1to = val | EXP_BYTE_EN; -#if 0 - DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__); -#endif -} - -static u_int8_t -cfread8(u_int32_t off) -{ - volatile u_int8_t *vp; - - vp = (volatile u_int8_t *)(dskinf.cs1 + off); - return *vp; -} - -static void -cfreadstream8(void *buf, int length) -{ - u_int8_t *lbuf; - u_int8_t tmp; - - lbuf = buf; - while (length) { - tmp = cfread8(CF_DATA); - *lbuf = tmp; -#ifdef DEBUG - if (dskinf.debug && (length > (512 - 32))) { - if ((length % 16) == 0) - xputchar('\n'); - puthex8(tmp); - putchar(' '); - } -#endif - lbuf++; - length--; - } -#ifdef DEBUG - if (dskinf.debug) - xputchar('\n'); -#endif -} - -static u_int16_t -cfread16(u_int32_t off) -{ - volatile u_int16_t *vp; - - vp = (volatile u_int16_t *)(dskinf.cs1 + off); - return swap16(*vp); -} - -static void -cfreadstream16(void *buf, int length) -{ - u_int16_t *lbuf; - - length = length / 2; - cfenable16(); - lbuf = buf; - while (length--) { - *lbuf = cfread16(CF_DATA); - lbuf++; - } - cfdisable16(); -} - -static void -cfwrite8(u_int32_t off, u_int8_t val) -{ - volatile u_int8_t *vp; - - vp = (volatile u_int8_t *)(dskinf.cs1 + off); - *vp = val; -} - -#if 0 -static void -cfwrite16(u_int32_t off, u_int16_t val) -{ - volatile u_int16_t *vp; - - vp = (volatile u_int16_t *)(dskinf.cs1 + off); - *vp = val; -} -#endif - -static u_int8_t -cfaltread8(u_int32_t off) -{ - volatile u_int8_t *vp; - - off &= 0x0f; - vp = (volatile u_int8_t *)(dskinf.cs2 + off); - return *vp; -} - -static void -cfaltwrite8(u_int32_t off, u_int8_t val) -{ - volatile u_int8_t *vp; - - /* - * This is documented in the Intel appnote 302456. - */ - off &= 0x0f; - vp = (volatile u_int8_t *)(dskinf.cs2 + off); - *vp = val; -} - -static int -cfwait(u_int8_t mask) -{ - u_int8_t status; - u_int32_t tout; - - tout = 0; - while (tout <= 5000000) { - status = cfread8(CF_STATUS); - if (status == 0xff) { - printf("%s: master: no status, reselecting\n", - __func__); - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1); - status = cfread8(CF_STATUS); - } - if (status == 0xff) - return -1; - dskinf.status = status; - if (!(status & CF_S_BUSY)) { - if (status & CF_S_ERROR) { - dskinf.error = cfread8(CF_ERROR); - printf("%s: error, status 0x%x error 0x%x\n", - __func__, status, dskinf.error); - } - if ((status & mask) == mask) { - DPRINTF("%s: status 0x%x mask 0x%x tout %u\n", - __func__, status, mask, tout); - return (status & CF_S_ERROR); - } - } - if (tout > 1000) { - tout += 1000; - DELAY(1000); - } else { - tout += 10; - DELAY(10); - } - } - return -1; -} - -static int -cfaltwait(u_int8_t mask) -{ - u_int8_t status; - u_int32_t tout; - - tout = 0; - while (tout <= 5000000) { - status = cfaltread8(CF_ALT_STATUS); - if (status == 0xff) { - printf("cfaltwait: master: no status, reselecting\n"); - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1); - status = cfread8(CF_STATUS); - } - if (status == 0xff) - return -1; - dskinf.status = status; - if (!(status & CF_S_BUSY)) { - if (status & CF_S_ERROR) - dskinf.error = cfread8(CF_ERROR); - if ((status & mask) == mask) { - DPRINTF("cfaltwait: tout %u\n", tout); - return (status & CF_S_ERROR); - } - } - if (tout > 1000) { - tout += 1000; - DELAY(1000); - } else { - tout += 10; - DELAY(10); - } - } - return -1; -} - -static int -cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head, u_int32_t sector, - u_int32_t count, u_int32_t feature) -{ - if (cfwait(0) < 0) { - printf("cfcmd: timeout\n"); - return -1; - } - cfwrite8(CF_FEATURE, feature); - cfwrite8(CF_CYL_L, cylinder); - cfwrite8(CF_CYL_H, cylinder >> 8); - if (dskinf.use_lba) - cfwrite8(CF_DRV_HEAD, CF_D_IBM | CF_D_LBA | head); - else - cfwrite8(CF_DRV_HEAD, CF_D_IBM | head); - cfwrite8(CF_SECT_NUM, sector); - cfwrite8(CF_SECT_CNT, count); - cfwrite8(CF_COMMAND, cmd); - return 0; -} - -static void -cfreset(void) -{ - u_int8_t status; - u_int32_t tout; - - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1); -#ifdef DEBUG - cfprintregs(); -#endif - cfread8(CF_STATUS); - cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS | CF_A_RESET); - DELAY(10000); - cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS); - DELAY(10000); - cfread8(CF_ERROR); - DELAY(3000); - - for (tout = 0; tout < 310000; tout++) { - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1); - status = cfread8(CF_STATUS); - if (!(status & CF_S_BUSY)) - break; - DELAY(100); - } - DELAY(1); - if (status & CF_S_BUSY) { - cfprintregs(); - printf("cfreset: Status stayed busy after reset.\n"); - } - DPRINTF("cfreset: finished, tout %u\n", tout); -} - -#ifdef DEBUG -static int -cfgetparams(void) -{ - u_int8_t *buf; - - buf = (u_int8_t *)(0x170000); - p_memset((char *)buf, 0, 1024); - /* Select the drive. */ - cfwrite8(CF_DRV_HEAD, CF_D_IBM); - DELAY(1); - cfcmd(ATA_ATA_IDENTIFY, 0, 0, 0, 0, 0); - if (cfaltwait(CF_S_READY | CF_S_DSC | CF_S_DRQ)) { - printf("cfgetparams: ATA_IDENTIFY failed.\n"); - return -1; - } - if (dskinf.use_stream8) - cfreadstream8(buf, 512); - else - cfreadstream16(buf, 512); - if (dskinf.debug) - cfprintregs(); -#if 0 - memcpy(&dskinf.ata_params, buf, sizeof(struct ata_params)); - dskinf.cylinders = dskinf.ata_params.cylinders; - dskinf.heads = dskinf.ata_params.heads; - dskinf.sectors = dskinf.ata_params.sectors; - printf("dsk0: sec %x, hd %x, cyl %x, stat %x, err %x\n", - (u_int32_t)dskinf.ata_params.sectors, - (u_int32_t)dskinf.ata_params.heads, - (u_int32_t)dskinf.ata_params.cylinders, - (u_int32_t)dskinf.status, - (u_int32_t)dskinf.error); -#endif - dskinf.status = cfread8(CF_STATUS); - if (dskinf.debug) - printf("cfgetparams: ata_params * %x, stat %x\n", - (u_int32_t)buf, (u_int32_t)dskinf.status); - return 0; -} -#endif /* DEBUG */ - -static void -cfprintregs(void) -{ - u_int8_t rv; - - putstr("cfprintregs: regs error "); - rv = cfread8(CF_ERROR); - puthex8(rv); - putstr(", count "); - rv = cfread8(CF_SECT_CNT); - puthex8(rv); - putstr(", sect "); - rv = cfread8(CF_SECT_NUM); - puthex8(rv); - putstr(", cyl low "); - rv = cfread8(CF_CYL_L); - puthex8(rv); - putstr(", cyl high "); - rv = cfread8(CF_CYL_H); - puthex8(rv); - putstr(", drv head "); - rv = cfread8(CF_DRV_HEAD); - puthex8(rv); - putstr(", status "); - rv = cfread8(CF_STATUS); - puthex8(rv); - putstr("\n"); -} - -int -avila_read(char *dest, unsigned source, unsigned length) -{ - if (dskinf.use_lba == 0 && source == 0) - source++; - if (dskinf.debug) - printf("avila_read: 0x%x, sect %d num secs %d\n", - (u_int32_t)dest, source, length); - while (length) { - cfwait(CF_S_READY); - /* cmd, cyl, head, sect, count, feature */ - cfcmd(ATA_READ, (source >> 8) & 0xffff, source >> 24, - source & 0xff, 1, 0); - - cfwait(CF_S_READY | CF_S_DRQ | CF_S_DSC); - if (dskinf.use_stream8) - cfreadstream8(dest, 512); - else - cfreadstream16(dest, 512); - length--; - source++; - dest += 512; - } - return 0; -} - -/* - * Gateworks Avila Support. - */ -static int -avila_probe(int boardtype_hint) -{ - volatile u_int32_t *cs; - /* - * Redboot only configure the chip selects that are needed, so - * use that to figure out if it is an Avila or ADI board. The - * Avila boards use CS2 and ADI does not. - */ - cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET); - return (*cs != 0); -} - -static void -avila_init(void) -{ - /* Config the serial port. RedBoot should do the rest. */ - ubase = (u_int8_t *)(IXP425_UART0_HWBASE); - - dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET); - dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET); - dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS1_HWBASE; - dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS2_HWBASE; - - cf_init(); -} -BOARD_CONFIG(avila, "Gateworks Avila"); - -/* - * Gateworks Cambria Support. - */ -static int -cambria_probe(int boardtype_hint) -{ - return cpu_is_ixp43x(); -} - -static void -cambria_init(void) -{ - /* Config the serial port. RedBoot should do the rest. */ - ubase = (u_int8_t *)(IXP425_UART0_HWBASE); - - dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET); - dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET); - dskinf.cs1 = (u_int8_t *)CAMBRIA_CFSEL0_HWBASE; - dskinf.cs2 = (u_int8_t *)CAMBRIA_CFSEL1_HWBASE; - - cf_init(); -} -BOARD_CONFIG(cambria, "Gateworks Cambria"); - -/* - * Pronghorn Metro Support. - */ -static int -pronghorn_probe(int boardtype_hint) -{ - volatile u_int32_t *cs; - /* - * Redboot only configure the chip selects that are needed, so - * use that to figure out if it is an Avila or ADI board. The - * Avila boards use CS2 and ADI does not. - */ - cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET); - return (*cs == 0); -} - -static void -pronghorn_init(void) -{ - /* Config the serial port. RedBoot should do the rest. */ - ubase = (u_int8_t *)(IXP425_UART1_HWBASE); - - dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET); - dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET); - dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS3_HWBASE; - dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS4_HWBASE; - - cf_init(); -} -BOARD_CONFIG(pronghorn, "Pronghorn Metro"); diff --git a/sys/boot/arm/ixp425/boot2/lib.h b/sys/boot/arm/ixp425/boot2/lib.h deleted file mode 100644 index 9c88030c2503..000000000000 --- a/sys/boot/arm/ixp425/boot2/lib.h +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2008 John Hay. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef ARM_BOOT_LIB_H -#define ARM_BOOT_LIB_H - -#include -#include - -int main(void); - -void DELAY(int); - -int getc(int); -void putchar(int); -void xputchar(int); -void putstr(const char *); -void puthex8(u_int8_t); -void puthexlist(const u_int8_t *, int); -void printf(const char *fmt,...); - -void bzero(void *, size_t); -char *strcpy(char *to, const char *from); -int strcmp(const char *to, const char *from); -int p_strlen(const char *); -int p_memcmp(const char *, const char *, unsigned); -void *memchr(const void *, int, size_t); -void memcpy(void *to, const void *from, unsigned size); -void *memmem(const void *, size_t, const void *, size_t); -void p_memset(char *buffer, char value, int size); - -#define strlen p_strlen -#define memcmp p_memcmp -#define memset p_memset - -u_int16_t swap16(u_int16_t); -u_int32_t swap32(u_int32_t); - -const char *board_init(void); -void clr_board(void); -int avila_read(char*, unsigned, unsigned); -u_int cpu_id(void); - -#endif /* !ARM_BOOT_LIB_H */ diff --git a/sys/boot/arm/uboot/Makefile b/sys/boot/arm/uboot/Makefile index 34b9a5b4c4ca..a3b228d732fc 100644 --- a/sys/boot/arm/uboot/Makefile +++ b/sys/boot/arm/uboot/Makefile @@ -1,11 +1,10 @@ # $FreeBSD$ -.include +.include FILES= ubldr ubldr.bin NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b WARNS?= 1 # Address at which ubldr will be loaded. @@ -19,80 +18,19 @@ SRCS= start.S conf.c self_reloc.c vers.c CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized .endif -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no -.if ${MK_NAND} != "no" -LOADER_NANDFS_SUPPORT?= yes -.else -LOADER_NANDFS_SUPPORT?= no -.endif LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif - -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_NANDFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt -CFLAGS+= -DLOADER_FDT_SUPPORT -LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/arm -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help @@ -103,31 +41,18 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} LDFLAGS+= -Wl,-znotext # Pull in common loader code -.PATH: ${.CURDIR}/../../uboot/common -.include "${.CURDIR}/../../uboot/common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../uboot/common - -# U-Boot standalone support library -LIBUBOOT= ${.OBJDIR}/../../uboot/lib/libuboot.a -CFLAGS+= -I${.CURDIR}/../../uboot/lib -CFLAGS+= -I${.OBJDIR}/../../uboot/lib - -# where to get libstand from -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +.include "${BOOTSRC}/uboot.mk" CFLAGS+= -fPIC -# clang doesn't understand %D as a specifier to printf -NO_WERROR.clang= - -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} -lstand +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} OBJS+= ${SRCS:N*.h:R:S/$/.o/g} -loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.uboot ${BOOTSRC}/fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} ldscript.abs: echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} @@ -149,8 +74,8 @@ ubldr.bin: ubldr.pie CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin .if !defined(LOADER_ONLY) -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" # Install loader.rc. FILES+= loader.rc diff --git a/sys/boot/arm/uboot/conf.c b/sys/boot/arm/uboot/conf.c index 03dc64125e43..777a7b20340c 100644 --- a/sys/boot/arm/uboot/conf.c +++ b/sys/boot/arm/uboot/conf.c @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include "dev_net.h" #endif +/* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ +void (*exitfn)(int) = exit; + struct devsw *devsw[] = { #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) &uboot_storage, diff --git a/sys/boot/common/disk.c b/sys/boot/common/disk.c index e9496b2b9c0d..4cb57d466a5e 100644 --- a/sys/boot/common/disk.c +++ b/sys/boot/common/disk.c @@ -88,6 +88,12 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset) dev = (struct disk_devdesc *)d; od = (struct open_disk *)dev->d_opendata; + /* + * The strategy function assumes the offset is in units of 512 byte + * sectors. For larger sector sizes, we need to adjust the offset to + * match the actual sector size. + */ + offset *= (od->sectorsize / 512); /* * As the GPT backup partition is located at the end of the disk, * to avoid reading past disk end, flag bcache not to use RA. diff --git a/sys/boot/common/md.c b/sys/boot/common/md.c index bb469a27f62b..5585218b3276 100644 --- a/sys/boot/common/md.c +++ b/sys/boot/common/md.c @@ -73,7 +73,8 @@ struct devsw md_dev = { md_open, md_close, noioctl, - md_print + md_print, + NULL }; static int diff --git a/sys/boot/defs.mk b/sys/boot/defs.mk new file mode 100644 index 000000000000..75c354c6254a --- /dev/null +++ b/sys/boot/defs.mk @@ -0,0 +1,148 @@ +# $FreeBSD$ + +.include + +.if !defined(__BOOT_DEFS_MK__) +__BOOT_DEFS_MK__=${MFILE} + +BOOTSRC= ${SRCTOP}/sys/boot +EFISRC= ${BOOTSRC}/efi +EFIINC= ${EFISRC}/include +EFIINCMD= ${EFIINC}/${MACHINE} +FDTSRC= ${BOOTSRC}/fdt +FICLSRC= ${BOOTSRC}/ficl +LDRSRC= ${BOOTSRC}/common +SASRC= ${BOOTSRC}/libsa +SYSDIR= ${SRCTOP}/sys +UBOOTSRC= ${BOOTSRC}/uboot +ZFSSRC= ${BOOTSRC}/zfs + +BOOTOBJ= ${OBJTOP}/sys/boot + +# BINDIR is where we install +BINDIR?= /boot + +# NB: The makefiles depend on these being empty when we don't build forth. +.if ${MK_FORTH} != "no" +LIBFICL= ${BOOTOBJ}/ficl/libficl.a +.if ${MACHINE} == "i386" +LIBFICL32= ${LIBFICL} +.else +LIBFICL32= ${BOOTOBJ}/ficl32/libficl.a +.endif +.endif +LIBSA= ${BOOTOBJ}/libsa/libsa.a +.if ${MACHINE} == "i386" +LIBSA32= ${LIBSA} +.else +LIBSA32= ${BOOTOBJ}/libsa32/libsa32.a +.endif + +# Standard options: + +# Filesystem support +.if ${LOADER_CD9660_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_CD9660_SUPPORT +.endif +.if ${LOADER_EXT2FS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_EXT2FS_SUPPORT +.endif +.if ${LOADER_MSDOS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_MSDOS_SUPPORT +.endif +.if ${LOADER_NANDFS_SUPPORT:U${MK_NAND}} == "yes" +CFLAGS+= -DLOADER_NANDFS_SUPPORT +.endif +.if ${LOADER_UFS_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_UFS_SUPPORT +.endif + +# Compression +.if ${LOADER_GZIP_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_GZIP_SUPPORT +.endif +.if ${LOADER_BZIP2_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_BZIP2_SUPPORT +.endif + +# Network related things +.if ${LOADER_NET_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_NET_SUPPORT +.endif +.if ${LOADER_NFS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_NFS_SUPPORT +.endif +.if ${LOADER_TFTP_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_TFTP_SUPPORT +.endif + +# Disk and partition support +.if ${LOADER_DISK_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_DISK_SUPPORT +.if ${LOADER_GPT_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_GPT_SUPPORT +.endif +.if ${LOADER_MBR_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_MBR_SUPPORT +.endif +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_GELI_SUPPORT +.endif +.endif + +# All PowerPC builds are 32 bit. We have no 64-bit loaders on powerpc +# or powerpc64. +.if ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -m32 -mcpu=powerpc +.endif + +# For amd64, there's a bit of mixed bag. Some of the tree (i386, lib*32) is +# build 32-bit and some 64-bit (lib*, efi). Centralize all the 32-bit magic here +# and activate it when DO32 is explicitly defined to be 1. +.if ${MACHINE_ARCH} == "amd64" && ${DO32:U0} == 1 +CFLAGS+= -m32 -mcpu=i386 +# LD_FLAGS is passed directly to ${LD}, not via ${CC}: +LD_FLAGS+= -m elf_i386_fbsd +AFLAGS+= --32 +.endif + +_ILINKS=machine +.if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" +_ILINKS+=${MACHINE_CPUARCH} +.endif +.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" +_ILINKS+=x86 +.endif +CLEANFILES+=${_ILINKS} + +all: ${PROG} + +beforedepend: ${_ILINKS} +beforebuild: ${_ILINKS} + +# Ensure that the links exist without depending on it when it exists which +# causes all the modules to be rebuilt when the directory pointed to changes. +.for _link in ${_ILINKS} +.if !exists(${.OBJDIR}/${_link}) +${OBJS}: ${_link} +.endif +.endfor + +.NOPATH: ${_ILINKS} + +${_ILINKS}: + @case ${.TARGET} in \ + machine) \ + if [ ${DO32:U0} -eq 0 ]; then \ + path=${SYSDIR}/${MACHINE}/include ; \ + else \ + path=${SYSDIR}/${MACHINE:C/amd64/i386/}/include ; \ + fi ;; \ + *) \ + path=${SYSDIR}/${.TARGET:T}/include ;; \ + esac ; \ + path=`(cd $$path && /bin/pwd)` ; \ + ${ECHO} ${.TARGET:T} "->" $$path ; \ + ln -fhs $$path ${.TARGET:T} + +.endif # __BOOT_DEFS_MK__ diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile index 66481f8513fc..e3b22de4a99a 100644 --- a/sys/boot/efi/Makefile +++ b/sys/boot/efi/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include # In-tree GCC does not support __attribute__((ms_abi)), but gcc newer # than 4.5 supports it. diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc index 405f4cd76018..4fd8762e1a21 100644 --- a/sys/boot/efi/Makefile.inc +++ b/sys/boot/efi/Makefile.inc @@ -1,7 +1,5 @@ # $FreeBSD$ -BINDIR?= /boot - .if ${MACHINE_CPUARCH} == "i386" CFLAGS+= -march=i386 CFLAGS+= -mno-aes diff --git a/sys/boot/efi/boot1/Makefile b/sys/boot/efi/boot1/Makefile index 189ab6aaca69..8f5aed50dce4 100644 --- a/sys/boot/efi/boot1/Makefile +++ b/sys/boot/efi/boot1/Makefile @@ -2,9 +2,10 @@ MAN= -.include +.include MK_SSP= no +MK_FORTH= no PROG= boot1.sym INTERNALPROG= @@ -25,21 +26,15 @@ CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes CWARNFLAGS.zfs_module.c += -Wno-sign-compare CWARNFLAGS.zfs_module.c += -Wno-unused-parameter CWARNFLAGS.zfs_module.c += -Wno-unused-function -CWARNFLAGS.skein.c += -Wno-cast-align -.if ${COMPILER_TYPE} == "clang" -CWARNFLAGS.skein.c += -Wno-missing-variable-declarations -.else if ${COMPILER_TYPE} == "gcc" -CWARNFLAGS.skein.c += -Wno-missing-declarations -.endif # architecture-specific loader code SRCS= boot1.c self_reloc.c start.S ufs_module.c .if ${MK_ZFS} != "no" SRCS+= zfs_module.c -SRCS+= skein.c skein_block.c -# Do not unroll skein loops, reduce code size -CFLAGS+= -DSKEIN_LOOP=111 -.PATH: ${.CURDIR}/../../../crypto/skein +CFLAGS+= -I${ZFSSRC} +CFLAGS+= -I${SYSDIR}/cddl/boot/zfs +CFLAGS+= -DEFI_ZFS_BOOT +LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201 @@ -47,32 +42,25 @@ CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized .endif CFLAGS+= -I. -CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE} -CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include -CFLAGS+= -I${.CURDIR}/../../.. +CFLAGS+= -I${EFIINC} +CFLAGS+= -I${EFIINCMD} +CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include +CFLAGS+= -I${SYSDIR} CFLAGS+= -DEFI_UFS_BOOT .ifdef(EFI_DEBUG) CFLAGS+= -DEFI_DEBUG .endif -.if ${MK_ZFS} != "no" -CFLAGS+= -I${.CURDIR}/../../zfs/ -CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs/ -CFLAGS+= -I${.CURDIR}/../../../crypto/skein -CFLAGS+= -DEFI_ZFS_BOOT -.endif - # Always add MI sources and REGULAR efi loader bits -.PATH: ${.CURDIR}/../loader/arch/${MACHINE} -.PATH: ${.CURDIR}/../loader -.PATH: ${.CURDIR}/../../common -CFLAGS+= -I${.CURDIR}/../../common +.PATH: ${EFISRC}/loader/arch/${MACHINE} +.PATH: ${EFISRC}/loader +.PATH: ${LDRSRC} +CFLAGS+= -I${LDRSRC} FILES= boot1.efi boot1.efifat FILESMODE_boot1.efi= ${BINMODE} -LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE}/ldscript.${MACHINE} +LDSCRIPT= ${EFISRC}/loader/arch/${MACHINE}/ldscript.${MACHINE} LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -shared .if ${MACHINE_CPUARCH} == "aarch64" @@ -83,15 +71,15 @@ CFLAGS+= -fPIC LDFLAGS+= -Wl,-znocombreloc .endif -LIBEFI= ${.OBJDIR}/../libefi/libefi.a +LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a # # Add libstand for the runtime functions used by the compiler - for example # __aeabi_* (arm) or __divdi3 (i386). # as well as required string and memory functions for all platforms. # -DPADD+= ${LIBEFI} ${LIBSTAND} -LDADD+= ${LIBEFI} -lstand +DPADD+= ${LIBEFI} ${LIBZFSBOOT} ${LIBSA} +LDADD+= ${LIBEFI} ${LIBZFSBOOT} ${LIBSA} DPADD+= ${LDSCRIPT} @@ -120,7 +108,7 @@ boot1.efi: ${PROG} -j .rela.dyn -j .reloc -j .eh_frame \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} -boot1.o: ${.CURDIR}/../../common/ufsread.c +boot1.o: ${SASRC}/ufsread.c # The following inserts our objects into a template FAT file system # created by generate-fat.sh @@ -141,18 +129,3 @@ boot1.efifat: boot1.efi CLEANFILES= boot1.efi boot1.efifat .include - -beforedepend ${OBJS}: machine - -CLEANFILES+= machine - -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE}/include machine - -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" -beforedepend ${OBJS}: x86 -CLEANFILES+= x86 - -x86: .NOMETA - ln -sf ${.CURDIR}/../../../x86/include x86 -.endif diff --git a/sys/boot/efi/boot1/Makefile.depend b/sys/boot/efi/boot1/Makefile.depend index 29844140c2c3..813358d57274 100644 --- a/sys/boot/efi/boot1/Makefile.depend +++ b/sys/boot/efi/boot1/Makefile.depend @@ -4,7 +4,10 @@ DIRDEPS = \ include \ include/xlocale \ - lib/libstand \ + lib/libmd \ + sys/boot/efi/libefi \ + sys/boot/libsa \ + sys/boot/zfs \ .include diff --git a/sys/boot/efi/fdt/Makefile b/sys/boot/efi/fdt/Makefile index 56fc2997a136..01dbeed05eaf 100644 --- a/sys/boot/efi/fdt/Makefile +++ b/sys/boot/efi/fdt/Makefile @@ -1,8 +1,8 @@ # $FreeBSD$ -.include +.include -.PATH: ${.CURDIR}/../../common +.PATH: ${LDRSRC} LIB= efi_fdt INTERNALLIB= @@ -17,23 +17,14 @@ CFLAGS+= -mgeneral-regs-only CFLAGS+= -msoft-float .endif -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - # EFI library headers -CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE} +CFLAGS+= -I${EFISRC}/include +CFLAGS+= -I${EFISRC}/include/${MACHINE} # libfdt headers -CFLAGS+= -I${.CURDIR}/../../fdt +CFLAGS+= -I${FDTSRC} # Pick up the bootstrap header for some interface items -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. - -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE}/include machine - -CLEANFILES+= machine +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. .include - -beforedepend ${OBJS}: machine diff --git a/sys/boot/efi/include/efilib.h b/sys/boot/efi/include/efilib.h index f625e59e4ff9..eaaae613dca0 100644 --- a/sys/boot/efi/include/efilib.h +++ b/sys/boot/efi/include/efilib.h @@ -31,6 +31,7 @@ #define _LOADER_EFILIB_H #include +#include #include extern EFI_HANDLE IH; @@ -50,13 +51,13 @@ typedef STAILQ_HEAD(pdinfo_list, pdinfo) pdinfo_list_t; typedef struct pdinfo { STAILQ_ENTRY(pdinfo) pd_link; /* link in device list */ - pdinfo_list_t pd_part; /* link of partitions */ + pdinfo_list_t pd_part; /* list of partitions */ EFI_HANDLE pd_handle; EFI_HANDLE pd_alias; EFI_DEVICE_PATH *pd_devpath; EFI_BLOCK_IO *pd_blkio; - int pd_unit; /* unit number */ - int pd_open; /* reference counter */ + uint32_t pd_unit; /* unit number */ + uint32_t pd_open; /* reference counter */ void *pd_bcache; /* buffer cache data */ } pdinfo_t; @@ -80,7 +81,8 @@ EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE); EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); -int efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +int efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); void efi_free_devpath_name(CHAR16 *); @@ -93,7 +95,7 @@ void efi_time_fini(void); EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); EFI_STATUS main(int argc, CHAR16 *argv[]); -void exit(EFI_STATUS status) __dead2; +void efi_exit(EFI_STATUS status) __dead2; void delay(int usecs); /* EFI environment initialization. */ diff --git a/sys/boot/efi/include/efizfs.h b/sys/boot/efi/include/efizfs.h index 511bd3826c66..1fd034fb2ab3 100644 --- a/sys/boot/efi/include/efizfs.h +++ b/sys/boot/efi/include/efizfs.h @@ -27,6 +27,7 @@ */ #include +#include #ifndef _EFIZFS_H_ #define _EFIZFS_H_ @@ -45,6 +46,7 @@ extern uint64_t pool_guid; extern void efi_zfs_probe(void); extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void); +extern bool efi_zfs_is_preferred(EFI_HANDLE *h); extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t); #endif diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index 8fcf25956b47..99fe2bde2f98 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -1,10 +1,9 @@ # $FreeBSD$ -.include +.include .if ${MK_FORTH} != "no" -CFLAGS+= -DBOOT_FORTH -.include "${.CURDIR}/../../Makefile.ficl" +.include "${BOOTSRC}/ficl.mk" .endif LIB= efi @@ -35,18 +34,16 @@ CFLAGS+= -mgeneral-regs-only .if ${MACHINE_ARCH} == "amd64" CFLAGS+= -fPIC -mno-red-zone .endif -CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE} -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand +CFLAGS+= -I${SYSDIR} +CFLAGS+= -I${EFIINC} +CFLAGS+= -I${EFIINCMD} .if ${MK_ZFS} != "no" -CFLAGS+= -I${.CURDIR}/../../zfs -CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs -CFLAGS+= -I${.CURDIR}/../../../crypto/skein +CFLAGS+= -I${ZFSSRC} CFLAGS+= -DEFI_ZFS_BOOT .endif # Pick up the bootstrap header for some interface items -CFLAGS+= -I${.CURDIR}/../../common +CFLAGS+= -I${LDRSRC} # Handle FreeBSD specific %b and %D printf format specifiers CFLAGS+= ${FORMAT_EXTENSIONS} diff --git a/sys/boot/efi/libefi/devicename.c b/sys/boot/efi/libefi/devicename.c index 9cc061d3b0ad..52e4799c8f3d 100644 --- a/sys/boot/efi/libefi/devicename.c +++ b/sys/boot/efi/libefi/devicename.c @@ -87,9 +87,9 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) { struct devdesc *idev; struct devsw *dv; + int i, unit, err; char *cp; const char *np; - int i, err; /* minimum length check */ if (strlen(devspec) < 2) @@ -105,6 +105,7 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) return (ENOENT); np = devspec + strlen(dv->dv_name); + idev = NULL; err = 0; switch (dv->dv_type) { @@ -117,10 +118,8 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) return (ENOMEM); err = disk_parsedev((struct disk_devdesc *)idev, np, path); - if (err != 0) { - free(idev); - return (err); - } + if (err != 0) + goto fail; break; #ifdef EFI_ZFS_BOOT @@ -130,10 +129,8 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) return (ENOMEM); err = zfs_parsedev((struct zfs_devdesc*)idev, np, path); - if (err != 0) { - free(idev); - return (err); - } + if (err != 0) + goto fail; break; #endif default: @@ -141,20 +138,23 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) if (idev == NULL) return (ENOMEM); - idev->d_unit = -1; + unit = 0; cp = (char *)np; + if (*np != '\0' && *np != ':') { - idev->d_unit = strtol(np, &cp, 0); - if (cp == np) { - free(idev); - return (EUNIT); + errno = 0; + unit = strtol(np, &cp, 0); + if (errno != 0 || cp == np) { + err = EUNIT; + goto fail; } } if (*cp != '\0' && *cp != ':') { - free(idev); - return (EINVAL); + err = EINVAL; + goto fail; } + idev->d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; @@ -168,6 +168,10 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) else free(idev); return (0); + +fail: + free(idev); + return (err); } char * diff --git a/sys/boot/efi/libefi/devpath.c b/sys/boot/efi/libefi/devpath.c index 662f0a744ef7..fd863019fd3b 100644 --- a/sys/boot/efi/libefi/devpath.c +++ b/sys/boot/efi/libefi/devpath.c @@ -139,30 +139,59 @@ efi_devpath_handle(EFI_DEVICE_PATH *devpath) return (h); } -int +bool efi_devpath_match(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { - int len; + size_t len; if (devpath1 == NULL || devpath2 == NULL) - return (0); + return (false); - while (1) { + while (true) { if (DevicePathType(devpath1) != DevicePathType(devpath2) || DevicePathSubType(devpath1) != DevicePathSubType(devpath2)) - return (0); + return (false); len = DevicePathNodeLength(devpath1); if (len != DevicePathNodeLength(devpath2)) - return (0); + return (false); - if (memcmp(devpath1, devpath2, (size_t)len) != 0) - return (0); + if (memcmp(devpath1, devpath2, len) != 0) + return (false); if (IsDevicePathEnd(devpath1)) break; devpath1 = NextDevicePathNode(devpath1); devpath2 = NextDevicePathNode(devpath2); } + return (true); +} + +int +efi_devpath_is_prefix(EFI_DEVICE_PATH *prefix, EFI_DEVICE_PATH *path) +{ + int len; + + if (prefix == NULL || path == NULL) + return (0); + + while (1) { + if (IsDevicePathEnd(prefix)) + break; + + if (DevicePathType(prefix) != DevicePathType(path) || + DevicePathSubType(prefix) != DevicePathSubType(path)) + return (0); + + len = DevicePathNodeLength(prefix); + if (len != DevicePathNodeLength(path)) + return (0); + + if (memcmp(prefix, path, (size_t)len) != 0) + return (0); + + prefix = NextDevicePathNode(prefix); + path = NextDevicePathNode(path); + } return (1); } diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c index 13c70c8151cf..724233c5ab08 100644 --- a/sys/boot/efi/libefi/efipart.c +++ b/sys/boot/efi/libefi/efipart.c @@ -58,6 +58,11 @@ static int efipart_printfd(int); static int efipart_printcd(int); static int efipart_printhd(int); +/* EISA PNP ID's for floppy controllers */ +#define PNP0604 0x604 +#define PNP0700 0x700 +#define PNP0701 0x701 + struct devsw efipart_fddev = { .dv_name = "fd", .dv_type = DEVT_FD, @@ -176,18 +181,18 @@ efipart_inithandles(void) static ACPI_HID_DEVICE_PATH * efipart_floppy(EFI_DEVICE_PATH *node) { - ACPI_HID_DEVICE_PATH *acpi = NULL; + ACPI_HID_DEVICE_PATH *acpi; if (DevicePathType(node) == ACPI_DEVICE_PATH && DevicePathSubType(node) == ACPI_DP) { acpi = (ACPI_HID_DEVICE_PATH *) node; - if (acpi->HID == EISA_PNP_ID(0x604) || - acpi->HID == EISA_PNP_ID(0x700) || - acpi->HID == EISA_ID(0x41d1, 0x701)) { + if (acpi->HID == EISA_PNP_ID(PNP0604) || + acpi->HID == EISA_PNP_ID(PNP0700) || + acpi->HID == EISA_PNP_ID(PNP0701)) { return (acpi); } } - return (acpi); + return (NULL); } /* @@ -198,12 +203,11 @@ efipart_fdinfo_add(EFI_HANDLE handle, uint32_t uid, EFI_DEVICE_PATH *devpath) { pdinfo_t *fd; - fd = malloc(sizeof(pdinfo_t)); + fd = calloc(1, sizeof(pdinfo_t)); if (fd == NULL) { printf("Failed to register floppy %d, out of memory\n", uid); return (ENOMEM); } - memset(fd, 0, sizeof(pdinfo_t)); STAILQ_INIT(&fd->pd_part); fd->pd_unit = uid; @@ -264,7 +268,7 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias, unit = 0; STAILQ_FOREACH(pd, &cdinfo, pd_link) { - if (efi_devpath_match(pd->pd_devpath, devpath) != 0) { + if (efi_devpath_match(pd->pd_devpath, devpath) == true) { pd->pd_handle = handle; pd->pd_alias = alias; return (0); @@ -272,12 +276,11 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias, unit++; } - cd = malloc(sizeof(pdinfo_t)); + cd = calloc(1, sizeof(pdinfo_t)); if (cd == NULL) { printf("Failed to add cd %d, out of memory\n", unit); return (ENOMEM); } - memset(cd, 0, sizeof(pdinfo_t)); STAILQ_INIT(&cd->pd_part); cd->pd_handle = handle; @@ -385,16 +388,15 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) if (node == NULL) return (ENOENT); /* This should not happen. */ - pd = malloc(sizeof(pdinfo_t)); + pd = calloc(1, sizeof(pdinfo_t)); if (pd == NULL) { printf("Failed to add disk, out of memory\n"); return (ENOMEM); } - memset(pd, 0, sizeof(pdinfo_t)); STAILQ_INIT(&pd->pd_part); STAILQ_FOREACH(hd, &hdinfo, pd_link) { - if (efi_devpath_match(hd->pd_devpath, disk_devpath) != 0) { + if (efi_devpath_match(hd->pd_devpath, disk_devpath) == true) { /* Add the partition. */ pd->pd_handle = part_handle; pd->pd_unit = node->PartitionNumber; @@ -417,12 +419,11 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) hd->pd_devpath = disk_devpath; STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); - pd = malloc(sizeof(pdinfo_t)); + pd = calloc(1, sizeof(pdinfo_t)); if (pd == NULL) { printf("Failed to add partition, out of memory\n"); return (ENOMEM); } - memset(pd, 0, sizeof(pdinfo_t)); STAILQ_INIT(&pd->pd_part); /* Add the partition. */ @@ -456,12 +457,11 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) if (node == NULL) return (ENOENT); /* This should not happen. */ - pd = malloc(sizeof(pdinfo_t)); + pd = calloc(1, sizeof(pdinfo_t)); if (pd == NULL) { printf("Failed to add disk, out of memory\n"); return (ENOMEM); } - memset(pd, 0, sizeof(pdinfo_t)); STAILQ_INIT(&pd->pd_part); last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) @@ -494,7 +494,14 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) return (0); } p++; /* skip the colon */ + errno = 0; unit = (int)strtol(p, NULL, 0); + if (errno != 0) { + printf("Bad unit number for partition \"%s\"\n", pathname); + free(pathname); + free(pd); + return (EUNIT); + } /* * We should have disk registered, if not, we are receiving @@ -637,8 +644,9 @@ efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose) if (blkio->Media->MediaPresent) { if (blkio->Media->RemovableMedia) printf(" (removable)"); - } else + } else { printf(" (no media)"); + } if ((ret = pager_output("\n")) != 0) break; if (!blkio->Media->MediaPresent) @@ -862,14 +870,18 @@ efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, if (pd->pd_blkio->Media->RemovableMedia && !pd->pd_blkio->Media->MediaPresent) - return (EIO); + return (ENXIO); bcd.dv_strategy = efipart_realstrategy; bcd.dv_devdata = devdata; bcd.dv_cache = pd->pd_bcache; if (dev->d_dev->dv_type == DEVT_DISK) { - return (bcache_strategy(&bcd, rw, blk + dev->d_offset, + daddr_t offset; + + offset = dev->d_offset * pd->pd_blkio->Media->BlockSize; + offset /= 512; + return (bcache_strategy(&bcd, rw, blk + offset, size, buf, rsize)); } return (bcache_strategy(&bcd, rw, blk, size, buf, rsize)); diff --git a/sys/boot/efi/libefi/efizfs.c b/sys/boot/efi/libefi/efizfs.c index 8a93b9965db0..7c434765fb54 100644 --- a/sys/boot/efi/libefi/efizfs.c +++ b/sys/boot/efi/libefi/efizfs.c @@ -81,12 +81,9 @@ efi_zfs_probe(void) { pdinfo_list_t *hdi; pdinfo_t *hd, *pd = NULL; - EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; - EFI_LOADED_IMAGE *img; char devname[SPECNAMELEN + 1]; uint64_t guid; - BS->HandleProtocol(IH, &imgid, (VOID**)&img); hdi = efiblk_get_pdinfo_list(&efipart_hddev); STAILQ_INIT(&zfsinfo); @@ -105,7 +102,7 @@ efi_zfs_probe(void) if (zfs_probe_dev(devname, &guid) == 0) { insert_zfs(pd->pd_handle, guid); - if (pd->pd_handle == img->DeviceHandle) + if (efi_zfs_is_preferred(pd->pd_handle)) pool_guid = guid; } diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile index 8e65c02e8e95..0c560d554ecb 100644 --- a/sys/boot/efi/loader/Makefile +++ b/sys/boot/efi/loader/Makefile @@ -2,7 +2,7 @@ MAN= -.include +.include MK_SSP= no @@ -11,33 +11,27 @@ INTERNALPROG= WARNS?= 3 LOADER_NET_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no + # architecture-specific loader code SRCS= autoload.c \ bootinfo.c \ conf.c \ copy.c \ efi_main.c \ + framebuffer.c \ main.c \ self_reloc.c \ smbios.c \ vers.c .if ${MK_ZFS} != "no" -SRCS+= zfs.c -.PATH: ${.CURDIR}/../../zfs -SRCS+= skein.c skein_block.c -# Do not unroll skein loops, reduce code size -CFLAGS+= -DSKEIN_LOOP=111 -.PATH: ${.CURDIR}/../../../crypto/skein - -# Disable warnings that are currently incompatible with the zfs boot code -CWARNFLAGS.zfs.c+= -Wno-sign-compare -CWARNFLAGS.zfs.c+= -Wno-array-bounds -CWARNFLAGS.zfs.c+= -Wno-missing-prototypes -.endif - -.if defined(LOADER_NET_SUPPORT) -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand +LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a +CFLAGS+= -I${ZFSSRC} +CFLAGS+= -DEFI_ZFS_BOOT .endif .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201 @@ -53,22 +47,16 @@ CWARNFLAGS.main.c+= -Wno-format .PATH: ${.CURDIR}/arch/${MACHINE} # For smbios.c -.PATH: ${.CURDIR}/../../i386/libi386 +.PATH: ${BOOTSRC}/i386/libi386 .include "${.CURDIR}/arch/${MACHINE}/Makefile.inc" CFLAGS+= -I${.CURDIR} CFLAGS+= -I${.CURDIR}/arch/${MACHINE} -CFLAGS+= -I${.CURDIR}/../include -CFLAGS+= -I${.CURDIR}/../include/${MACHINE} -CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include -CFLAGS+= -I${.CURDIR}/../../.. -CFLAGS+= -I${.CURDIR}/../../i386/libi386 -.if ${MK_ZFS} != "no" -CFLAGS+= -I${.CURDIR}/../../zfs -CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs -CFLAGS+= -I${.CURDIR}/../../../crypto/skein -CFLAGS+= -DEFI_ZFS_BOOT -.endif +CFLAGS+= -I${EFISRC}/include +CFLAGS+= -I${EFISRC}/include/${MACHINE} +CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include +CFLAGS+= -I${SYSDIR} +CFLAGS+= -I${BOOTSRC}/i386/libi386 CFLAGS+= -DNO_PCI -DEFI .if !defined(BOOT_HIDE_SERIAL_NUMBERS) @@ -83,21 +71,13 @@ CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID .endif .endif -.if ${MK_FORTH} != "no" -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -CFLAGS+= -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - LOADER_FDT_SUPPORT?= no .if ${MK_FDT} != "no" && ${LOADER_FDT_SUPPORT} != "no" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt +CFLAGS+= -I${BOOTSRC}/fdt +CFLAGS+= -I${BOOTSRC}/fdt CFLAGS+= -DLOADER_FDT_SUPPORT -LIBEFI_FDT= ${.OBJDIR}/../../efi/fdt/libefi_fdt.a -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a +LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a +LIBFDT= ${BOOTOBJ}/fdt/libfdt.a .endif # Include bcache code. @@ -108,9 +88,7 @@ CFLAGS+= -DEFI_STAGING_SIZE=${EFI_STAGING_SIZE} .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" FILES+= loader.efi FILESMODE_loader.efi= ${BINMODE} @@ -148,25 +126,10 @@ loader.efi: ${PROG} -j set_Xficl_compile_set \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} -LIBEFI= ${.OBJDIR}/../libefi/libefi.a +LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a -DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND} \ +DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} \ ${LDSCRIPT} -LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} .include - -beforedepend ${OBJS}: machine - -CLEANFILES+= machine - -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE}/include machine - -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" -beforedepend ${OBJS}: x86 -CLEANFILES+= x86 - -x86: .NOMETA - ln -sf ${.CURDIR}/../../../x86/include x86 -.endif diff --git a/sys/boot/efi/loader/Makefile.depend b/sys/boot/efi/loader/Makefile.depend index cca8fc0785db..6eec9589d9fa 100644 --- a/sys/boot/efi/loader/Makefile.depend +++ b/sys/boot/efi/loader/Makefile.depend @@ -4,9 +4,10 @@ DIRDEPS = \ include \ include/xlocale \ - lib/libstand \ sys/boot/efi/libefi \ sys/boot/ficl \ + sys/boot/libsa \ + sys/boot/zfs \ .include diff --git a/sys/boot/efi/loader/arch/amd64/Makefile.inc b/sys/boot/efi/loader/arch/amd64/Makefile.inc index 071afa100611..b6d824ce57e4 100644 --- a/sys/boot/efi/loader/arch/amd64/Makefile.inc +++ b/sys/boot/efi/loader/arch/amd64/Makefile.inc @@ -2,12 +2,11 @@ SRCS+= amd64_tramp.S \ start.S \ - framebuffer.c \ elf64_freebsd.c \ trap.c \ exc.S -.PATH: ${.CURDIR}/../../i386/libi386 +.PATH: ${BOOTSRC}/i386/libi386 SRCS+= nullconsole.c \ comconsole.c \ spinconsole.c diff --git a/sys/boot/efi/loader/arch/arm64/Makefile.inc b/sys/boot/efi/loader/arch/arm64/Makefile.inc index fbb75398fe9e..2ce5af79d0c3 100644 --- a/sys/boot/efi/loader/arch/arm64/Makefile.inc +++ b/sys/boot/efi/loader/arch/arm64/Makefile.inc @@ -4,8 +4,8 @@ LOADER_FDT_SUPPORT=yes SRCS+= exec.c \ start.S -.PATH: ${.CURDIR}/../../arm64/libarm64 -CFLAGS+=-I${.CURDIR}/../../arm64/libarm64 +.PATH: ${BOOTSRC}/arm64/libarm64 +CFLAGS+=-I${BOOTSRC}/arm64/libarm64 SRCS+= cache.c CFLAGS+= -mgeneral-regs-only @@ -14,11 +14,11 @@ CLEANFILES+= loader.help loader.help: help.common cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} .if !defined(LOADER_ONLY) -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc .endif diff --git a/sys/boot/efi/loader/arch/i386/Makefile.inc b/sys/boot/efi/loader/arch/i386/Makefile.inc index a1af3cdd84c3..70d2848ba26f 100644 --- a/sys/boot/efi/loader/arch/i386/Makefile.inc +++ b/sys/boot/efi/loader/arch/i386/Makefile.inc @@ -5,7 +5,7 @@ SRCS+= start.S \ elf32_freebsd.c \ exec.c -.PATH: ${.CURDIR}/../../i386/libi386 +.PATH: ${BOOTSRC}/i386/libi386 SRCS+= nullconsole.c \ comconsole.c \ spinconsole.c diff --git a/sys/boot/efi/loader/arch/i386/exec.c b/sys/boot/efi/loader/arch/i386/exec.c index 12a367cda5c2..579f5593b24b 100644 --- a/sys/boot/efi/loader/arch/i386/exec.c +++ b/sys/boot/efi/loader/arch/i386/exec.c @@ -36,12 +36,6 @@ __FBSDID("$FreeBSD$"); uint32_t __base; struct __v86 __v86; -/* XXX - Needed a definition here to implicitly define exit(); do not remove. */ -static void -exit(int x) -{ -} - void __v86int() { diff --git a/sys/boot/efi/loader/bootinfo.c b/sys/boot/efi/loader/bootinfo.c index bd4b3ee86217..ca06a6194f8d 100644 --- a/sys/boot/efi/loader/bootinfo.c +++ b/sys/boot/efi/loader/bootinfo.c @@ -48,9 +48,10 @@ __FBSDID("$FreeBSD$"); #if defined(__amd64__) #include -#include "framebuffer.h" #endif +#include "framebuffer.h" + #if defined(LOADER_FDT_SUPPORT) #include #endif @@ -247,12 +248,12 @@ bi_load_efi_data(struct preloaded_file *kfp) UINT32 mmver; struct efi_map_header *efihdr; -#if defined(__amd64__) +#if defined(__amd64__) || defined(__aarch64__) struct efi_fb efifb; if (efi_find_framebuffer(&efifb) == 0) { printf("EFI framebuffer information:\n"); - printf("addr, size 0x%lx, 0x%lx\n", efifb.fb_addr, + printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, efifb.fb_size); printf("dimensions %d x %d\n", efifb.fb_width, efifb.fb_height); diff --git a/sys/boot/efi/loader/efi_main.c b/sys/boot/efi/loader/efi_main.c index 045ee9bc2f7a..e424d89666ec 100644 --- a/sys/boot/efi/loader/efi_main.c +++ b/sys/boot/efi/loader/efi_main.c @@ -36,13 +36,20 @@ static EFI_PHYSICAL_ADDRESS heap; static UINTN heapsize; void -exit(EFI_STATUS exit_code) +efi_exit(EFI_STATUS exit_code) { BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); BS->Exit(IH, exit_code, 0, NULL); } +void +exit(int status) +{ + + efi_exit(EFI_LOAD_ERROR); +} + static CHAR16 * arg_skipsep(CHAR16 *argp) { @@ -92,11 +99,11 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize)); - /* Use exit() from here on... */ + /* Use efi_exit() from here on... */ status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img); if (status != EFI_SUCCESS) - exit(status); + efi_exit(status); /* * Pre-process the (optional) load options. If the option string @@ -176,6 +183,6 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) argv[argc] = NULL; status = main(argc, argv); - exit(status); + efi_exit(status); return (status); } diff --git a/sys/boot/efi/loader/arch/amd64/framebuffer.c b/sys/boot/efi/loader/framebuffer.c similarity index 100% rename from sys/boot/efi/loader/arch/amd64/framebuffer.c rename to sys/boot/efi/loader/framebuffer.c diff --git a/sys/boot/efi/loader/arch/amd64/framebuffer.h b/sys/boot/efi/loader/framebuffer.h similarity index 100% rename from sys/boot/efi/loader/arch/amd64/framebuffer.h rename to sys/boot/efi/loader/framebuffer.h diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index 8ebfab4490e5..129fd72068ba 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -72,6 +72,16 @@ EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; EFI_GUID fdtdtb = FDT_TABLE_GUID; EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; +static EFI_LOADED_IMAGE *img; + +#ifdef EFI_ZFS_BOOT +bool +efi_zfs_is_preferred(EFI_HANDLE *h) +{ + return (h == img->DeviceHandle); +} +#endif + static int has_keyboard(void) { @@ -300,7 +310,6 @@ EFI_STATUS main(int argc, CHAR16 *argv[]) { char var[128]; - EFI_LOADED_IMAGE *img; EFI_GUID *guid; int i, j, vargood, howto; UINTN k; @@ -319,6 +328,9 @@ main(int argc, CHAR16 *argv[]) archsw.arch_zfs_probe = efi_zfs_probe; #endif + /* Get our loaded image protocol interface structure. */ + BS->HandleProtocol(IH, &imgid, (VOID**)&img); + /* Init the time source */ efi_time_init(); @@ -446,9 +458,6 @@ main(int argc, CHAR16 *argv[]) if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); - /* Get our loaded image protocol interface structure. */ - BS->HandleProtocol(IH, &imgid, (VOID**)&img); - printf("Command line arguments:"); for (i = 0; i < argc; i++) printf(" %S", argv[i]); @@ -901,7 +910,7 @@ command_chain(int argc, char *argv[]) /* * d_partition should be 255 */ - if (pd->pd_unit == d_dev->d_slice) { + if (pd->pd_unit == (uint32_t)d_dev->d_slice) { loaded_image->DeviceHandle = pd->pd_handle; break; diff --git a/sys/boot/fdt/Makefile b/sys/boot/fdt/Makefile index ce11dbb42f84..a725499d2f78 100644 --- a/sys/boot/fdt/Makefile +++ b/sys/boot/fdt/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../contrib/libfdt/ +.include + +.PATH: ${SYSDIR}/contrib/libfdt/ LIB= fdt INTERNALLIB= @@ -12,7 +14,7 @@ SRCS+= fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c \ # Loader's fdt commands extension sources. SRCS+= fdt_loader_cmd.c fdt_overlay.c -CFLAGS+= -I${.CURDIR}/../../contrib/libfdt/ -I${.CURDIR}/../common/ +CFLAGS+= -I${SYSDIR}/contrib/libfdt/ -I${LDRSRC} CFLAGS+= -ffreestanding @@ -20,10 +22,6 @@ CFLAGS+= -ffreestanding CFLAGS+= -msoft-float .endif -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -.endif - CFLAGS+= -Wformat -Wall .include diff --git a/sys/boot/fdt/Makefile.depend b/sys/boot/fdt/Makefile.depend index 29844140c2c3..18be76b0cb6f 100644 --- a/sys/boot/fdt/Makefile.depend +++ b/sys/boot/fdt/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ include \ include/xlocale \ - lib/libstand \ .include diff --git a/sys/boot/fdt/dts/arm/rpi2.dts b/sys/boot/fdt/dts/arm/rpi2.dts index d127217b5920..2a5c9e97cdd3 100644 --- a/sys/boot/fdt/dts/arm/rpi2.dts +++ b/sys/boot/fdt/dts/arm/rpi2.dts @@ -30,7 +30,7 @@ / { model = "Raspberry Pi 2 Model B"; - compatible = "brcm,bcm2709"; + compatible = "brcm,bcm2836"; memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */ diff --git a/sys/boot/ficl.mk b/sys/boot/ficl.mk new file mode 100644 index 000000000000..a0a13206b495 --- /dev/null +++ b/sys/boot/ficl.mk @@ -0,0 +1,23 @@ +# $FreeBSD$ + +# Common flags to build FICL related files + +.include "defs.mk" + +.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 1 +FICL_CPUARCH= i386 +.elif ${MACHINE_ARCH:Mmips64*} != "" +FICL_CPUARCH= mips64 +.else +FICL_CPUARCH= ${MACHINE_CPUARCH} +.endif + +.PATH: ${FICLSRC} ${FICLSRC}/${FICL_CPUARCH} + +.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0 +CFLAGS+= -fPIC +.endif + +CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC} +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -DBF_DICTSIZE=15000 diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile index c16b25d8fc90..e32e3909687d 100644 --- a/sys/boot/ficl/Makefile +++ b/sys/boot/ficl/Makefile @@ -1,18 +1,16 @@ # $FreeBSD$ # -.include "${.CURDIR}/../Makefile.ficl" +.include +.include "${BOOTSRC}/ficl.mk" BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ prefix.c search.c stack.c tools.c vm.c words.c SRCS= ${BASE_SRCS} sysdep.c softcore.c CLEANFILES= softcore.c testmain testmain.o -.if ${MACHINE_CPUARCH} == "i386" || \ - (${MACHINE_CPUARCH} == "amd64" && defined(FICL32)) -CFLAGS+= -march=i386 -.endif -.if HAVE_PNP + +.if defined(HAVE_PNP) CFLAGS+= -DHAVE_PNP .endif .include @@ -28,12 +26,10 @@ INTERNALLIB= .endif # Standard softwords -.PATH: ${FICLDIR}/softwords +.PATH: ${FICLSRC}/softwords SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \ ifbrack.fr -# Optional OO extension softwords -#SOFTWORDS+= oo.fr classes.fr softcore.c: ${SOFTWORDS} softcore.awk - (cd ${FICLDIR}/softwords; cat ${SOFTWORDS} \ + (cd ${FICLSRC}/softwords; cat ${SOFTWORDS} \ | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET} diff --git a/sys/boot/ficl/Makefile.depend b/sys/boot/ficl/Makefile.depend index c04b7c302dd3..c210061155d2 100644 --- a/sys/boot/ficl/Makefile.depend +++ b/sys/boot/ficl/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ include \ include/xlocale \ - lib/libstand \ lib/msun \ diff --git a/sys/boot/ficl32/Makefile b/sys/boot/ficl32/Makefile index b27a339bc2ab..09499464ac89 100644 --- a/sys/boot/ficl32/Makefile +++ b/sys/boot/ficl32/Makefile @@ -1,5 +1,5 @@ # $FreeBSD$ -FICL32= +DO32=1 .include "${.CURDIR}/../ficl/Makefile" diff --git a/sys/boot/ficl32/Makefile.depend b/sys/boot/ficl32/Makefile.depend index c04b7c302dd3..c210061155d2 100644 --- a/sys/boot/ficl32/Makefile.depend +++ b/sys/boot/ficl32/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ include \ include/xlocale \ - lib/libstand \ lib/msun \ diff --git a/sys/boot/geli/Makefile b/sys/boot/geli/Makefile index 527d1c6a5464..b16f7a8c5ab3 100644 --- a/sys/boot/geli/Makefile +++ b/sys/boot/geli/Makefile @@ -3,7 +3,7 @@ MAN= -.include +.include MK_SSP= no LIB= geliboot @@ -14,21 +14,21 @@ NO_PIC= .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -march=i386 .endif -.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" +.if ${MACHINE_ARCH} == "amd64" CFLAGS+= -m32 .endif WARNS?= 0 # string functions from libc -.PATH: ${.CURDIR}/../../../lib/libc/string +.PATH: ${SRCTOP}/lib/libc/string SRCS+= bcmp.c bcopy.c bzero.c # Our password input method SRCS+= pwgets.c # sha256 and sha512 from sys/crypto -.PATH: ${SRCTOP}/sys/crypto/sha2 +.PATH: ${SYSDIR}/crypto/sha2 CFLAGS+= -DWEAK_REFS SRCS+= sha256c.c sha512c.c @@ -37,15 +37,15 @@ SRCS+= sha256c.c sha512c.c SRCS+= md5c.c # AES implementation from sys/crypto -.PATH: ${SRCTOP}/sys/crypto/rijndael -CFLAGS+= -I${.CURDIR}/../../ -CFLAGS+= -I${.CURDIR}/../common/ +.PATH: ${SYSDIR}/crypto/rijndael +CFLAGS+= -I${SYSDIR} +CFLAGS+= -I${LDRSRC} # Remove asserts CFLAGS+= -DNDEBUG SRCS+= rijndael-alg-fst.c rijndael-api-fst.c rijndael-api.c # local GELI Implementation -.PATH: ${SRCTOP}/sys/geom/eli +.PATH: ${SYSDIR}/geom/eli CFLAGS+= -D_STAND SRCS+= geliboot_crypto.c g_eli_hmac.c g_eli_key.c g_eli_key_cache.c pkcs5v2.c diff --git a/sys/boot/geli/Makefile.depend b/sys/boot/geli/Makefile.depend index 7b5722492e1d..106f2f62b86c 100644 --- a/sys/boot/geli/Makefile.depend +++ b/sys/boot/geli/Makefile.depend @@ -5,7 +5,6 @@ DIRDEPS = \ include \ include/xlocale \ lib/libmd \ - lib/libstand \ secure/lib/libcrypto \ diff --git a/sys/boot/i386/Makefile b/sys/boot/i386/Makefile index 0c3daed185ee..af74d6954dac 100644 --- a/sys/boot/i386/Makefile +++ b/sys/boot/i386/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot \ libi386 libfirewire loader diff --git a/sys/boot/i386/Makefile.inc b/sys/boot/i386/Makefile.inc index ac413b27d93d..b324d1adfef5 100644 --- a/sys/boot/i386/Makefile.inc +++ b/sys/boot/i386/Makefile.inc @@ -2,37 +2,30 @@ # # $FreeBSD$ -BINDIR?= /boot - LOADER_ADDRESS?=0x200000 CFLAGS+= -march=i386 -ffreestanding CFLAGS.gcc+= -mpreferred-stack-boundary=2 CFLAGS+= ${CFLAGS_NO_SIMD} -msoft-float LDFLAGS+= -nostdlib -.if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -m32 -ACFLAGS+= -m32 -# LD_FLAGS is passed directly to ${LD}, not via ${CC}: -LD_FLAGS+= -m elf_i386_fbsd -AFLAGS+= --32 -.endif - # BTX components -.if exists(${.OBJDIR}/../btx) -BTXDIR= ${.OBJDIR}/../btx -.else -BTXDIR= ${.CURDIR}/../btx -.endif +BTXDIR= ${BOOTOBJ}/i386/btx BTXLDR= ${BTXDIR}/btxldr/btxldr BTXKERN= ${BTXDIR}/btx/btx BTXCRT= ${BTXDIR}/lib/crt0.o +BTXSRC= ${BOOTSRC}/i386/btx +BTXLIB= ${BTXSRC}/lib + # compact binary with no padding between text, data, bss -LDSCRIPT= ${SRCTOP}/sys/boot/i386/boot.ldscript +LDSCRIPT= ${BOOTSRC}/i386/boot.ldscript # LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary # LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary LD_FLAGS_BIN=-static -N --gc-sections +.if ${MACHINE_CPUARCH} == "amd64" +DO32=1 +.endif + .include "../Makefile.inc" diff --git a/sys/boot/i386/boot0/Makefile b/sys/boot/i386/boot0/Makefile index d0ce8e598c60..39c0072e6638 100644 --- a/sys/boot/i386/boot0/Makefile +++ b/sys/boot/i386/boot0/Makefile @@ -75,6 +75,6 @@ CFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \ -DTICKS=${BOOT_BOOT0_TICKS} \ -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/boot2/Makefile b/sys/boot/i386/boot2/Makefile index 96946454fbfa..9f9e5191e133 100644 --- a/sys/boot/i386/boot2/Makefile +++ b/sys/boot/i386/boot2/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include FILES= boot boot1 boot2 @@ -22,7 +22,7 @@ BOOT2_UFS?= UFS1_AND_UFS2 #BOOT2_UFS?= UFS2_ONLY #BOOT2_UFS?= UFS1_ONLY -CFLAGS= -fomit-frame-pointer \ +CFLAGS+=-fomit-frame-pointer \ -mrtd \ -mregparm=3 \ -D${BOOT2_UFS} \ @@ -30,8 +30,8 @@ CFLAGS= -fomit-frame-pointer \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../btx/lib -I. \ + -I${LDRSRC} \ + -I${BTXLIB} -I. \ -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ @@ -46,10 +46,7 @@ CFLAGS.gcc+= -mno-align-long-strings CFLAGS.clang+= -Oz ${CLANG_OPT_SMALL} -LD_FLAGS=${LD_FLAGS_BIN} - -# Pick up ../Makefile.inc early. -.include +LD_FLAGS+=${LD_FLAGS_BIN} CLEANFILES= boot @@ -96,13 +93,6 @@ boot2.h: boot1.out ORG1=`printf "%d" ${ORG1}` \ REL1=`printf "%d" ${REL1}` > ${.TARGET} -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend boot2.s: machine -CLEANFILES+= machine -machine: ${.CURDIR}/../../../i386/include .NOMETA - ln -sf ${.ALLSRC} ${.TARGET} -.endif - .include # XXX: clang integrated-as doesn't grok .codeNN directives yet diff --git a/sys/boot/i386/btx/btx/Makefile b/sys/boot/i386/btx/btx/Makefile index 11fd9c7d96a6..f42e20d83b33 100644 --- a/sys/boot/i386/btx/btx/Makefile +++ b/sys/boot/i386/btx/btx/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + PROG= btx INTERNALPROG= MAN= @@ -12,7 +14,7 @@ BOOT_BTX_FLAGS=0x0 .endif CFLAGS+=-DBTX_FLAGS=${BOOT_BTX_FLAGS} -CFLAGS+=-I${.CURDIR}/../../common +CFLAGS+=-I${BOOTSRC}/i386/common .if defined(BTX_SERIAL) BOOT_COMCONSOLE_PORT?= 0x3f8 @@ -25,7 +27,7 @@ CFLAGS+=-DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ ORG= 0x9000 -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/btx/btxldr/Makefile b/sys/boot/i386/btx/btxldr/Makefile index c785b60ffeb1..32795975b7ad 100644 --- a/sys/boot/i386/btx/btxldr/Makefile +++ b/sys/boot/i386/btx/btxldr/Makefile @@ -1,19 +1,21 @@ # $FreeBSD$ +.include + PROG= btxldr INTERNALPROG= MAN= SRCS= btxldr.S CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS} -CFLAGS+=-I${.CURDIR}/../../common +CFLAGS+=-I${BOOTSRC}/i386/common .if defined(BTXLDR_VERBOSE) CFLAGS+=-DBTXLDR_VERBOSE .endif ORG=${LOADER_ADDRESS} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/btx/lib/Makefile b/sys/boot/i386/btx/lib/Makefile index c66f0fcc5169..8de62555c9dc 100644 --- a/sys/boot/i386/btx/lib/Makefile +++ b/sys/boot/i386/btx/lib/Makefile @@ -1,10 +1,12 @@ # $FreeBSD$ +.include + PROG= crt0.o INTERNALPROG= MAN= SRCS= btxcsu.S btxsys.s btxv86.s -CFLAGS+=-I${.CURDIR}/../../common -LDFLAGS=-Wl,-r +CFLAGS+=-I${BOOTSRC}/i386/common +LDFLAGS+=-Wl,-r .include diff --git a/sys/boot/i386/cdboot/Makefile b/sys/boot/i386/cdboot/Makefile index e2fec39d0e1f..7acd4046d816 100644 --- a/sys/boot/i386/cdboot/Makefile +++ b/sys/boot/i386/cdboot/Makefile @@ -1,16 +1,18 @@ # $FreeBSD$ +.include + PROG= cdboot STRIP= BINMODE=${NOBINMODE} MAN= SRCS= ${PROG}.S -CFLAGS+=-I${.CURDIR}/../common +CFLAGS+=-I${BOOTSRC}/i386/common ORG= 0x7c00 -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/gptboot/Makefile b/sys/boot/i386/gptboot/Makefile index b259f4b3bf87..9d3048a89c56 100644 --- a/sys/boot/i386/gptboot/Makefile +++ b/sys/boot/i386/gptboot/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../boot2 ${.CURDIR}/../common ${.CURDIR}/../../common +.include + +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC} FILES= gptboot MAN= gptboot.8 @@ -20,18 +22,18 @@ GPTBOOT_UFS?= UFS1_AND_UFS2 #GPTBOOT_UFS?= UFS2_ONLY #GPTBOOT_UFS?= UFS1_ONLY -CFLAGS= -DBOOTPROG=\"gptboot\" \ +CFLAGS+=-DBOOTPROG=\"gptboot\" \ -O1 \ -DGPT \ -D${GPTBOOT_UFS} \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../common \ - -I${.CURDIR}/../btx/lib -I. \ - -I${.CURDIR}/../boot2 \ - -I${.CURDIR}/../../.. \ + -I${LDRSRC} \ + -I${BOOTSRC}/i386/common \ + -I${BTXLIB} -I. \ + -I${BOOTSRC}/i386/boot2 \ + -I${SYSDIR} \ -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ @@ -39,21 +41,15 @@ CFLAGS= -DBOOTPROG=\"gptboot\" \ CFLAGS.gcc+= --param max-inline-insns-single=100 -.if !defined(LOADER_NO_GELI_SUPPORT) +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_GELI_SUPPORT -CFLAGS+= -I${.CURDIR}/../../geli -CFLAGS+= -I${.CURDIR}/../../.. -LIBGELIBOOT= ${.OBJDIR}/../../geli/libgeliboot.a -.PATH: ${.CURDIR}/../../../opencrypto +CFLAGS+= -I${BOOTSRC}/geli +LIBGELIBOOT= ${BOOTOBJ}/geli/libgeliboot.a +.PATH: ${SYSDIR}/opencrypto OPENCRYPTO_XTS= xform_aes_xts.o .endif -LD_FLAGS=${LD_FLAGS_BIN} - -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a - -# Pick up ../Makefile.inc early. -.include +LD_FLAGS+=${LD_FLAGS_BIN} CLEANFILES= gptboot @@ -76,16 +72,9 @@ gptboot.bin: gptboot.out ${OBJCOPY} -S -O binary gptboot.out ${.TARGET} gptboot.out: ${BTXCRT} gptboot.o sio.o crc32.o drv.o cons.o util.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND} + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSA32} -gptboot.o: ${.CURDIR}/../../common/ufsread.c - -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend gptboot.o: machine -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine -.endif +gptboot.o: ${SASRC}/ufsread.c .include diff --git a/sys/boot/i386/gptboot/Makefile.depend b/sys/boot/i386/gptboot/Makefile.depend index 295be1a66f91..c6ac7d89dda0 100644 --- a/sys/boot/i386/gptboot/Makefile.depend +++ b/sys/boot/i386/gptboot/Makefile.depend @@ -5,11 +5,10 @@ DIRDEPS = \ include \ include/xlocale \ lib/libmd \ - lib/libstand \ sys/boot/geli \ sys/boot/i386/btx/btx \ sys/boot/i386/btx/lib \ - sys/boot/libstand32 \ + sys/boot/libsa32 \ .include diff --git a/sys/boot/i386/gptzfsboot/Makefile b/sys/boot/i386/gptzfsboot/Makefile index dc2058d450b6..b9df313dd291 100644 --- a/sys/boot/i386/gptzfsboot/Makefile +++ b/sys/boot/i386/gptzfsboot/Makefile @@ -1,10 +1,10 @@ # $FreeBSD$ -.include +.include -.PATH: ${.CURDIR}/../boot2 ${.CURDIR}/../gptboot \ - ${.CURDIR}/../zfsboot ${.CURDIR}/../common \ - ${.CURDIR}/../../common ${.CURDIR}/../../../crypto/skein +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ + ${BOOTSRC}/i386/zfsboot ${BOOTSRC}/i386/common \ + ${SASRC} FILES= gptzfsboot MAN= gptzfsboot.8 @@ -19,20 +19,19 @@ REL1= 0x700 ORG1= 0x7c00 ORG2= 0x0 -CFLAGS= -DBOOTPROG=\"gptzfsboot\" \ +CFLAGS+=-DBOOTPROG=\"gptzfsboot\" \ -O1 \ -DGPT -DZFS -DBOOT2 \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../common \ - -I${.CURDIR}/../../zfs \ - -I${.CURDIR}/../../../cddl/boot/zfs \ - -I${.CURDIR}/../../../crypto/skein \ - -I${.CURDIR}/../btx/lib -I. \ - -I${.CURDIR}/../boot2 \ - -I${.CURDIR}/../../.. \ + -I${LDRSRC} \ + -I${BOOTSRC}/i386/common \ + -I${ZFSSRC} \ + -I${SYSDIR}/cddl/boot/zfs \ + -I${BOOTSRC}/i386/btx/lib -I. \ + -I${BOOTSRC}/i386/boot2 \ + -I${SYSDIR} \ -Wall -Waggregate-return -Wbad-function-cast \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ @@ -45,25 +44,23 @@ NO_WCAST_ALIGN= CFLAGS+= -Wno-tentative-definition-incomplete-type .endif -# Do not unroll skein loops, reduce code size -CFLAGS+= -DSKEIN_LOOP=111 +.if ${MACHINE} == "amd64" +LIBZFSBOOT=${BOOTOBJ}/zfs32/libzfsboot.a +.else +LIBZFSBOOT=${BOOTOBJ}/zfs/libzfsboot.a +.endif -.if !defined(LOADER_NO_GELI_SUPPORT) +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_GELI_SUPPORT -CFLAGS+= -I${.CURDIR}/../../geli -LIBGELIBOOT= ${.OBJDIR}/../../geli/libgeliboot.a -.PATH: ${.CURDIR}/../../../opencrypto +CFLAGS+= -I${BOOTSRC}/geli +LIBGELIBOOT= ${BOOTOBJ}/geli/libgeliboot.a +.PATH: ${SYSDIR}/opencrypto OPENCRYPTO_XTS= xform_aes_xts.o .endif CFLAGS.gcc+= --param max-inline-insns-single=100 -LD_FLAGS=${LD_FLAGS_BIN} - -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a - -# Pick up ../Makefile.inc early. -.include +LD_FLAGS+=${LD_FLAGS_BIN} CLEANFILES= gptzfsboot @@ -80,23 +77,16 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} gptldr.o CLEANFILES+= gptzfsboot.bin gptzfsboot.out zfsboot.o sio.o cons.o \ - drv.o gpt.o util.o skein.o skein_block.o ${OPENCRYPTO_XTS} + drv.o gpt.o util.o ${OPENCRYPTO_XTS} gptzfsboot.bin: gptzfsboot.out ${OBJCOPY} -S -O binary gptzfsboot.out ${.TARGET} gptzfsboot.out: ${BTXCRT} zfsboot.o sio.o gpt.o drv.o cons.o util.o \ - skein.o skein_block.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND} + ${OPENCRYPTO_XTS} + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBZFSBOOT} ${LIBSA32} -zfsboot.o: ${.CURDIR}/../../zfs/zfsimpl.c - -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend zfsboot.o: machine -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine -.endif +zfsboot.o: ${ZFSSRC}/zfsimpl.c .include diff --git a/sys/boot/i386/gptzfsboot/Makefile.depend b/sys/boot/i386/gptzfsboot/Makefile.depend index 295be1a66f91..16b58a77a452 100644 --- a/sys/boot/i386/gptzfsboot/Makefile.depend +++ b/sys/boot/i386/gptzfsboot/Makefile.depend @@ -5,11 +5,11 @@ DIRDEPS = \ include \ include/xlocale \ lib/libmd \ - lib/libstand \ sys/boot/geli \ sys/boot/i386/btx/btx \ sys/boot/i386/btx/lib \ - sys/boot/libstand32 \ + sys/boot/libsa32 \ + sys/boot/zfs32 \ .include diff --git a/sys/boot/i386/kgzldr/Makefile b/sys/boot/i386/kgzldr/Makefile index f396ae90a0f4..5a03b83e5e49 100644 --- a/sys/boot/i386/kgzldr/Makefile +++ b/sys/boot/i386/kgzldr/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + PROG= kgzldr.o STRIP= BINMODE=${LIBMODE} @@ -10,8 +12,8 @@ SRCS= start.s boot.c inflate.c lib.c crt.s sio.s CFLAGS= -Os CFLAGS+=-DKZIP NO_SHARED= -LDFLAGS=-Wl,-r -.PATH: ${.CURDIR}/../../../kern +LDFLAGS+=-Wl,-r +.PATH: ${SYSDIR}/kern BOOT_COMCONSOLE_PORT?= 0x3f8 AFLAGS+=--defsym SIO_PRT=${BOOT_COMCONSOLE_PORT} diff --git a/sys/boot/i386/libfirewire/Makefile b/sys/boot/i386/libfirewire/Makefile index 904f4abccae9..be906ff94636 100644 --- a/sys/boot/i386/libfirewire/Makefile +++ b/sys/boot/i386/libfirewire/Makefile @@ -1,30 +1,20 @@ # $FreeBSD$ +.include + LIB= firewire INTERNALLIB= -.PATH: ${.CURDIR}/../../../dev/dcons ${.CURDIR}/../../../dev/firewire +.PATH: ${SYSDIR}/dev/dcons ${SYSDIR}/dev/firewire SRCS+= firewire.c fwohci.c dconsole.c SRCS+= dcons.c fwcrom.c CFLAGS+= -D_BOOT -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand -CFLAGS+= -I${.CURDIR}/../btx/lib -CFLAGS+= -I${.CURDIR}/../libi386 +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. +CFLAGS+= -I${BTXLIB} +CFLAGS+= -I${BOOTSRC}/i386/libi386 CFLAGS+= -Wformat -Wall -.if ${MACHINE_CPUARCH} == "amd64" -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine -.endif - .include - -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend ${OBJS}: machine -.endif - diff --git a/sys/boot/i386/libi386/Makefile b/sys/boot/i386/libi386/Makefile index 2a7d1e2213df..20ce255fd50b 100644 --- a/sys/boot/i386/libi386/Makefile +++ b/sys/boot/i386/libi386/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ -# + +.include + LIB= i386 INTERNALLIB= @@ -9,15 +11,8 @@ SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \ elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \ smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c -.PATH: ${.CURDIR}/../../zfs -SRCS+= devicename_stubs.c - -# Enable PXE TFTP or NFS support, not both. -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.else -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif +.PATH: ${ZFSSRC} +SRCS+= devicename_stubs.c BOOT_COMCONSOLE_PORT?= 0x3f8 CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT} @@ -30,10 +25,10 @@ CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED} CFLAGS+= -DDISK_DEBUG .endif -.if !defined(LOADER_NO_GELI_SUPPORT) +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" # Decrypt encrypted drives CFLAGS+= -DLOADER_GELI_SUPPORT -CFLAGS+= -I${.CURDIR}/../../geli +CFLAGS+= -I${BOOTSRC}/geli .endif .if !defined(BOOT_HIDE_SERIAL_NUMBERS) @@ -54,29 +49,17 @@ CFLAGS+= -DTERM_EMU # XXX: make alloca() useable CFLAGS+= -Dalloca=__builtin_alloca -CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 \ - -I${.CURDIR}/../../common -I${.CURDIR}/../common \ - -I${.CURDIR}/../btx/lib \ - -I${.CURDIR}/../../../contrib/dev/acpica/include \ - -I${.CURDIR}/../../.. -I. -# the location of libstand -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +CFLAGS+= -I${BOOTSRC}/ficl -I${BOOTSRC}/ficl/i386 \ + -I${LDRSRC} -I${BOOTSRC}/i386/common \ + -I${BTXLIB} \ + -I${SYSDIR}/contrib/dev/acpica/include \ + -I${SYSDIR} -I. # Handle FreeBSD specific %b and %D printf format specifiers CFLAGS+= ${FORMAT_EXTENSIONS} -.if ${MACHINE_CPUARCH} == "amd64" -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine -.endif - .include # XXX: clang integrated-as doesn't grok .codeNN directives yet CFLAGS.amd64_tramp.S= ${CLANG_NO_IAS} CFLAGS.multiboot_tramp.S= ${CLANG_NO_IAS} - -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend ${OBJS}: machine -.endif diff --git a/sys/boot/i386/libi386/biosmem.c b/sys/boot/i386/libi386/biosmem.c index 9da4dd2e7f48..7105757e8104 100644 --- a/sys/boot/i386/libi386/biosmem.c +++ b/sys/boot/i386/libi386/biosmem.c @@ -63,150 +63,166 @@ static uint8_t b_bios_probed; * memory correctly. You need both maker and product as * reported by smbios. */ -#define BQ_DISTRUST_E820_EXTMEM 0x1 /* e820 might not return useful - extended memory */ +/* e820 might not return useful extended memory */ +#define BQ_DISTRUST_E820_EXTMEM 0x1 struct bios_getmem_quirks { - const char* bios_vendor; - const char* maker; - const char* product; - int quirk; + const char *bios_vendor; + const char *maker; + const char *product; + int quirk; }; static struct bios_getmem_quirks quirks[] = { - {"coreboot", "Acer", "Peppy", BQ_DISTRUST_E820_EXTMEM}, - {NULL, NULL, NULL, 0} + {"coreboot", "Acer", "Peppy", BQ_DISTRUST_E820_EXTMEM}, + {NULL, NULL, NULL, 0} }; static int bios_getquirks(void) { - int i; + int i; - for (i=0; quirks[i].quirk != 0; ++i) - if (smbios_match(quirks[i].bios_vendor, quirks[i].maker, - quirks[i].product)) - return (quirks[i].quirk); + for (i = 0; quirks[i].quirk != 0; ++i) { + if (smbios_match(quirks[i].bios_vendor, quirks[i].maker, + quirks[i].product)) + return (quirks[i].quirk); + } - return (0); + return (0); } void bios_getmem(void) { - uint64_t size; + uint64_t size; - /* Parse system memory map */ - v86.ebx = 0; - do { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap_xattr); - v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); - v86int(); - if ((V86_CY(v86.efl)) || (v86.eax != SMAP_SIG)) - break; - /* look for a low-memory segment that's large enough */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && - (smap.length >= (512 * 1024))) { - bios_basemem = smap.length; - b_bios_probed |= B_BASEMEM_E820; - } + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe820 */ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap_xattr); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((V86_CY(v86.efl)) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) { + bios_basemem = smap.length; + b_bios_probed |= B_BASEMEM_E820; + } - /* look for the first segment in 'extended' memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000) && - !(bios_getquirks() & BQ_DISTRUST_E820_EXTMEM)) { - bios_extmem = smap.length; - b_bios_probed |= B_EXTMEM_E820; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base == 0x100000) && + !(bios_getquirks() & BQ_DISTRUST_E820_EXTMEM)) { + bios_extmem = smap.length; + b_bios_probed |= B_EXTMEM_E820; + } + + /* + * Look for the highest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base > 0x100000) && + (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, + * truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + /* + * To make maximum space for the kernel and the modules, + * set heap to use highest HEAP_MIN bytes below 4GB. + */ + if (high_heap_base < smap.base && size >= HEAP_MIN) { + high_heap_base = smap.base + size - HEAP_MIN; + high_heap_size = HEAP_MIN; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; + b_bios_probed |= B_BASEMEM_12; } /* - * Look for the largest segment in 'extended' memory beyond - * 1MB but below 4GB. + * Fall back through several compatibility functions for extended + * memory. */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && - (smap.base < 0x100000000ull)) { - size = smap.length; + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801 */ + v86.eax = 0xe801; + v86int(); + if (!(V86_CY(v86.efl))) { + /* + * Clear high_heap; it may end up overlapping + * with the segment we're determining here. + * Let the default "steal stuff from top of + * bios_extmem" code below pick up on it. + */ + high_heap_size = 0; + high_heap_base = 0; - /* - * If this segment crosses the 4GB boundary, truncate it. - */ - if (smap.base + size > 0x100000000ull) - size = 0x100000000ull - smap.base; + /* + * %cx is the number of 1KiB blocks between 1..16MiB. + * It can only be up to 0x3c00; if it's smaller then + * there's a PC AT memory hole so we can't treat + * it as contiguous. + */ + bios_extmem = (v86.ecx & 0xffff) * 1024; + if (bios_extmem == (1024 * 0x3c00)) + bios_extmem += (v86.edx & 0xffff) * 64 * 1024; - if (size > high_heap_size) { - high_heap_size = size; - high_heap_base = smap.base; - } + /* truncate bios_extmem */ + if (bios_extmem > 0x3ff00000) + bios_extmem = 0x3ff00000; + + b_bios_probed |= B_EXTMEM_E801; + } } - } while (v86.ebx != 0); - - /* Fall back to the old compatibility function for base memory */ - if (bios_basemem == 0) { - v86.ctl = 0; - v86.addr = 0x12; /* int 0x12 */ - v86int(); - - bios_basemem = (v86.eax & 0xffff) * 1024; - b_bios_probed |= B_BASEMEM_12; - } - - /* Fall back through several compatibility functions for extended memory */ - if (bios_extmem == 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe801*/ - v86.eax = 0xe801; - v86int(); - if (!(V86_CY(v86.efl))) { - /* - * Clear high_heap; it may end up overlapping - * with the segment we're determining here. - * Let the default "steal stuff from top of - * bios_extmem" code below pick up on it. - */ - high_heap_size = 0; - high_heap_base = 0; - - /* - * %cx is the number of 1KiB blocks between 1..16MiB. - * It can only be up to 0x3c00; if it's smaller then - * there's a PC AT memory hole so we can't treat - * it as contiguous. - */ - bios_extmem = (v86.ecx & 0xffff) * 1024; - if (bios_extmem == (1024 * 0x3c00)) - bios_extmem += (v86.edx & 0xffff) * 64 * 1024; - - /* truncate bios_extmem */ - if (bios_extmem > 0x3ff00000) - bios_extmem = 0x3ff00000; - - b_bios_probed |= B_EXTMEM_E801; + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88 */ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; + b_bios_probed |= B_EXTMEM_8800; } - } - if (bios_extmem == 0) { - v86.ctl = 0; - v86.addr = 0x15; /* int 0x15 function 0x88*/ - v86.eax = 0x8800; - v86int(); - bios_extmem = (v86.eax & 0xffff) * 1024; - b_bios_probed |= B_EXTMEM_8800; - } - /* Set memtop to actual top of memory */ - memtop = memtop_copyin = 0x100000 + bios_extmem; + /* Set memtop to actual top of memory */ + if (high_heap_size != 0) { + memtop = memtop_copyin = high_heap_base; + } else { + memtop = memtop_copyin = 0x100000 + bios_extmem; + } - /* - * If we have extended memory and did not find a suitable heap - * region in the SMAP, use the last HEAP_MIN of 'extended' memory as a - * high heap candidate. - */ - if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { - high_heap_size = HEAP_MIN; - high_heap_base = memtop - HEAP_MIN; - } + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last HEAP_MIN of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = memtop - HEAP_MIN; + memtop = memtop_copyin = high_heap_base; + } } static int @@ -214,16 +230,16 @@ command_biosmem(int argc, char *argv[]) { int bq = bios_getquirks(); - printf("bios_basemem: 0x%llx\n", (unsigned long long) bios_basemem); - printf("bios_extmem: 0x%llx\n", (unsigned long long) bios_extmem); - printf("memtop: 0x%llx\n", (unsigned long long) memtop); - printf("high_heap_base: 0x%llx\n", (unsigned long long) high_heap_base); - printf("high_heap_size: 0x%llx\n", (unsigned long long) high_heap_size); + printf("bios_basemem: 0x%llx\n", (unsigned long long)bios_basemem); + printf("bios_extmem: 0x%llx\n", (unsigned long long)bios_extmem); + printf("memtop: 0x%llx\n", (unsigned long long)memtop); + printf("high_heap_base: 0x%llx\n", (unsigned long long)high_heap_base); + printf("high_heap_size: 0x%llx\n", (unsigned long long)high_heap_size); printf("bios_quirks: 0x%02x", bq); if (bq & BQ_DISTRUST_E820_EXTMEM) printf(" BQ_DISTRUST_E820_EXTMEM"); printf("\n"); - printf("b_bios_probed: 0x%02x", (int) b_bios_probed); + printf("b_bios_probed: 0x%02x", (int)b_bios_probed); if (b_bios_probed & B_BASEMEM_E820) printf(" B_BASEMEM_E820"); if (b_bios_probed & B_BASEMEM_12) diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile index 434ccc914946..e588d7996ba6 100644 --- a/sys/boot/i386/loader/Makefile +++ b/sys/boot/i386/loader/Makefile @@ -1,6 +1,7 @@ # $FreeBSD$ -.include +.include + MK_SSP= no LOADER?= loader @@ -13,30 +14,30 @@ LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no +LOADER_UFS_SUPPORT?= yes +LOADER_GZIP_SUPPORT?= yes +LOADER_BZIP2_SUPPORT?= yes + # architecture-specific loader code SRCS= main.c conf.c vers.c chain.c # Put LOADER_FIREWIRE_SUPPORT=yes in /etc/make.conf for FireWire/dcons support .if defined(LOADER_FIREWIRE_SUPPORT) CFLAGS+= -DLOADER_FIREWIRE_SUPPORT -LIBFIREWIRE= ${.OBJDIR}/../libfirewire/libfirewire.a +LIBFIREWIRE= ${BOOTOBJ}/i386/libfirewire/libfirewire.a .endif # Set by zfsloader Makefile .if defined(LOADER_ZFS_SUPPORT) CFLAGS+= -DLOADER_ZFS_SUPPORT -LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a +.if ${MACHINE} == "amd64" +LIBZFSBOOT= ${BOOTOBJ}/zfs32/libzfsboot.a +.else +LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif - -.if defined(LOADER_NET_SUPPORT) -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand -.endif - -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if defined(LOADER_NFS_SUPPORT) -CFLAGS+= -DLOADER_NFS_SUPPORT .endif # Include bcache code. @@ -46,62 +47,35 @@ HAVE_BCACHE= yes HAVE_PNP= yes HAVE_ISABUS= yes -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 -.if ${MACHINE_CPUARCH} == "amd64" -LIBFICL= ${.OBJDIR}/../../ficl32/libficl.a -.else -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif -.endif - -.if defined(LOADER_BZIP2_SUPPORT) -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if !defined(LOADER_NO_GZIP_SUPPORT) -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if defined(LOADER_NANDFS_SUPPORT) -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if !defined(LOADER_NO_GELI_SUPPORT) +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_GELI_SUPPORT -CFLAGS+= -I${.CURDIR}/../../geli -LIBGELIBOOT= ${.OBJDIR}/../../geli/libgeliboot.a -.PATH: ${.CURDIR}/../../../opencrypto +CFLAGS+= -I${BOOTSRC}/geli +LIBGELIBOOT= ${BOOTOBJ}/geli/libgeliboot.a +.PATH: ${SYSDIR}/opencrypto SRCS+= xform_aes_xts.c -CFLAGS+= -I${.CURDIR}/../../.. -D_STAND +CFLAGS+= -I${SYSDIR} -D_STAND .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" CFLAGS+= -I. CLEANFILES= ${LOADER} ${LOADER}.bin loader.help CFLAGS+= -Wall -LDFLAGS= -static -Ttext 0x0 +LDFLAGS+= -static -Ttext 0x0 # i386 standalone support library -LIBI386= ${.OBJDIR}/../libi386/libi386.a -CFLAGS+= -I${.CURDIR}/.. - -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a +LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a +CFLAGS+= -I${BOOTSRC}/i386 # BTX components -CFLAGS+= -I${.CURDIR}/../btx/lib +CFLAGS+= -I${BTXLIB} # Debug me! #CFLAGS+= -g #LDFLAGS+= -g -# Pick up ../Makefile.inc early. -.include - ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN} btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \ -b ${BTXKERN} ${LOADER}.bin @@ -110,15 +84,15 @@ ${LOADER}.bin: ${LOADER}.sym strip -R .comment -R .note -o ${.TARGET} ${.ALLSRC} loader.help: help.common help.i386 - cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + cat ${.ALLSRC} | awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} FILES= ${LOADER} # XXX INSTALLFLAGS_loader= -b FILESMODE_${LOADER}= ${BINMODE} -b .if !defined(LOADER_ONLY) -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= pcibios.4th FILES+= loader.rc menu.rc @@ -127,15 +101,11 @@ FILES+= loader.rc menu.rc # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} -DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND} - -.include +DPADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} +LDADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} .if ${MACHINE_CPUARCH} == "amd64" -beforedepend ${OBJS}: machine -CLEANFILES+= machine CFLAGS+= -DLOADER_PREFER_AMD64 -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine .endif + +.include diff --git a/sys/boot/i386/loader/Makefile.depend b/sys/boot/i386/loader/Makefile.depend index bbed7789c011..5d4398105e2a 100644 --- a/sys/boot/i386/loader/Makefile.depend +++ b/sys/boot/i386/loader/Makefile.depend @@ -10,7 +10,7 @@ DIRDEPS = \ sys/boot/i386/btx/btxldr \ sys/boot/i386/btx/lib \ sys/boot/i386/libi386 \ - sys/boot/libstand32 \ + sys/boot/libsa32 \ .include diff --git a/sys/boot/i386/mbr/Makefile b/sys/boot/i386/mbr/Makefile index ac10723059f6..9bfa0bd38fa0 100644 --- a/sys/boot/i386/mbr/Makefile +++ b/sys/boot/i386/mbr/Makefile @@ -12,6 +12,6 @@ BOOT_MBR_FLAGS?= 0x80 ORG= 0x600 AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/pmbr/Makefile b/sys/boot/i386/pmbr/Makefile index 243167a2177f..1bfe0ee11ab2 100644 --- a/sys/boot/i386/pmbr/Makefile +++ b/sys/boot/i386/pmbr/Makefile @@ -9,6 +9,6 @@ SRCS= ${PROG}.s ORG= 0x600 AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include diff --git a/sys/boot/i386/pxeldr/Makefile b/sys/boot/i386/pxeldr/Makefile index fea62a5aaa4e..57931a5206cd 100644 --- a/sys/boot/i386/pxeldr/Makefile +++ b/sys/boot/i386/pxeldr/Makefile @@ -1,6 +1,5 @@ # $FreeBSD$ -# Pick up ../Makefile.inc early. .include PROG= ${LDR} @@ -23,9 +22,9 @@ CFLAGS+=-DPROBE_KEYBOARD CFLAGS+=-DALWAYS_SERIAL .endif -CFLAGS+=-I${.CURDIR}/../common +CFLAGS+=-I${BOOTSRC}/i386/common -LOADERBIN= ${.OBJDIR}/../loader/loader.bin +LOADERBIN= ${BOOTOBJ}/i386/loader/loader.bin CLEANFILES+= ${BOOT}.tmp diff --git a/sys/boot/i386/zfsboot/Makefile b/sys/boot/i386/zfsboot/Makefile index f9719ce6e9c1..a83bfa960590 100644 --- a/sys/boot/i386/zfsboot/Makefile +++ b/sys/boot/i386/zfsboot/Makefile @@ -1,7 +1,10 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../boot2 ${.CURDIR}/../common \ - ${.CURDIR}/../../common ${.CURDIR}/../../../crypto/skein +LOADER_GELI_SUPPORT=no + +.include + +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC} FILES= zfsboot MAN= zfsboot.8 @@ -16,34 +19,32 @@ REL1= 0x700 ORG1= 0x7c00 ORG2= 0x2000 -CFLAGS= -DBOOTPROG=\"zfsboot\" \ +CFLAGS+=-DBOOTPROG=\"zfsboot\" \ -O1 \ -DZFS -DBOOT2 \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../common \ - -I${.CURDIR}/../../zfs \ - -I${.CURDIR}/../../../cddl/boot/zfs \ - -I${.CURDIR}/../../../crypto/skein \ - -I${.CURDIR}/../btx/lib -I. \ - -I${.CURDIR}/../boot2 \ + -I${LDRSRC} \ + -I${BOOTSRC}/i386/common \ + -I${BOOTSRC}/i386 \ + -I${ZFSSRC} \ + -I${SYSDIR}/cddl/boot/zfs \ + -I${BTXLIB} -I. \ + -I${BOOTSRC}/i386/boot2 \ -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ -Winline CFLAGS.gcc+= --param max-inline-insns-single=100 -# Do not unroll skein loops, reduce code size -CFLAGS+= -DSKEIN_LOOP=111 +.if ${MACHINE} == "amd64" +LIBZFSBOOT=${BOOTOBJ}/zfs32/libzfsboot.a +.else +LIBZFSBOOT=${BOOTOBJ}/zfs/libzfsboot.a +.endif -LD_FLAGS=${LD_FLAGS_BIN} - -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a - -# Pick up ../Makefile.inc early. -.include +LD_FLAGS+=${LD_FLAGS_BIN} CLEANFILES= zfsboot @@ -59,8 +60,7 @@ zfsldr.out: zfsldr.o ${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} zfsldr.o CLEANFILES+= zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \ - zfsboot.o zfsboot.s zfsboot.s.tmp sio.o cons.o drv.o util.o \ - skein.o skein_block.o + zfsboot.o zfsboot.s zfsboot.s.tmp sio.o cons.o drv.o util.o # We currently allow 128k bytes for zfsboot - in practice it could be # any size up to 3.5Mb but keeping it fixed size simplifies zfsldr. @@ -82,18 +82,11 @@ zfsboot.ldr: zfsboot.bin: zfsboot.out ${OBJCOPY} -S -O binary zfsboot.out ${.TARGET} -zfsboot.out: ${BTXCRT} zfsboot.o sio.o drv.o cons.o util.o skein.o skein_block.o - ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} +zfsboot.out: ${BTXCRT} zfsboot.o sio.o drv.o cons.o util.o + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBZFSBOOT} ${LIBSA32} SRCS= zfsboot.c -.if ${MACHINE_CPUARCH} == "amd64" -beforedepend zfsboot.o: machine -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../../i386/include machine -.endif - .include # XXX: clang integrated-as doesn't grok .codeNN directives yet diff --git a/sys/boot/i386/zfsboot/Makefile.depend b/sys/boot/i386/zfsboot/Makefile.depend index 63a43d89fad3..491ced5bb565 100644 --- a/sys/boot/i386/zfsboot/Makefile.depend +++ b/sys/boot/i386/zfsboot/Makefile.depend @@ -4,9 +4,11 @@ DIRDEPS = \ include \ include/xlocale \ + lib/libmd \ sys/boot/i386/btx/btx \ sys/boot/i386/btx/lib \ - sys/boot/libstand32 \ + sys/boot/libsa32 \ + sys/boot/zfs32 \ .include diff --git a/sys/boot/i386/zfsloader/Makefile b/sys/boot/i386/zfsloader/Makefile index 1825367363d6..33f1d4a0257e 100644 --- a/sys/boot/i386/zfsloader/Makefile +++ b/sys/boot/i386/zfsloader/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../loader +.include + +.PATH: ${BOOTSRC}/i386/loader LOADER= zfsloader NEWVERSWHAT= "ZFS enabled bootstrap loader" x86 @@ -8,5 +10,5 @@ LOADER_ZFS_SUPPORT=yes LOADER_ONLY= yes MAN= -.include "${.CURDIR}/../loader/Makefile" +.include "${BOOTSRC}/i386/loader/Makefile" diff --git a/sys/boot/i386/zfsloader/Makefile.depend b/sys/boot/i386/zfsloader/Makefile.depend index 49bb014d176a..d17b39324022 100644 --- a/sys/boot/i386/zfsloader/Makefile.depend +++ b/sys/boot/i386/zfsloader/Makefile.depend @@ -10,8 +10,8 @@ DIRDEPS = \ sys/boot/i386/btx/btxldr \ sys/boot/i386/btx/lib \ sys/boot/i386/libi386 \ - sys/boot/libstand32 \ - sys/boot/zfs \ + sys/boot/libsa32 \ + sys/boot/zfs32 \ .include diff --git a/lib/libstand/Makefile b/sys/boot/libsa/Makefile similarity index 77% rename from lib/libstand/Makefile rename to sys/boot/libsa/Makefile index 3654ec351fa1..057eb7615beb 100644 --- a/lib/libstand/Makefile +++ b/sys/boot/libsa/Makefile @@ -6,29 +6,25 @@ # quite large. # -PACKAGE=lib${LIB} MK_PROFILE= no MK_SSP= no -.include +.include -LIBSTAND_SRC?= ${.CURDIR} -LIBSTAND_CPUARCH?=${MACHINE_CPUARCH} -LIBC_SRC= ${LIBSTAND_SRC}/../libc +INTERNALLIB= +LIBSA_CPUARCH?=${MACHINE_CPUARCH} +LIBC_SRC= ${SRCTOP}/lib/libc -LIB= stand +LIB?= sa NO_PIC= -INCS?= stand.h -MAN?= libstand.3 - WARNS?= 0 -CFLAGS+= -I${LIBSTAND_SRC} +CFLAGS+= -I${SASRC} -I${SYSDIR} # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c environment.c getopt.c gets.c \ - globals.c pager.c printf.c strdup.c strerror.c strtol.c strtoul.c random.c \ - sbrk.c twiddle.c zalloc.c zalloc_malloc.c + globals.c pager.c panic.c printf.c strdup.c strerror.c strtol.c strtoul.c \ + random.c sbrk.c twiddle.c zalloc.c zalloc_malloc.c # private (pruned) versions of libc string functions SRCS+= strcasecmp.c @@ -58,14 +54,14 @@ CFLAGS.clang+= -mno-movt CFLAGS.clang+= -mfpu=none # Compiler support functions -.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/ +.PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/ # __clzsi2 and ctzsi2 for various builtin functions SRCS+= clzsi2.c ctzsi2.c # Divide and modulus functions called by the compiler SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c -.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/arm/ +.PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/arm/ SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S .endif @@ -85,49 +81,49 @@ SRCS+= syncicache.c SRCS+= uuid_create_nil.c uuid_equal.c uuid_from_string.c uuid_is_nil.c uuid_to_string.c # _setjmp/_longjmp -.PATH: ${LIBSTAND_SRC}/${LIBSTAND_CPUARCH} +.PATH: ${SASRC}/${LIBSA_CPUARCH} SRCS+= _setjmp.S # decompression functionality from libbz2 # NOTE: to actually test this functionality after libbz2 upgrade compile # loader(8) with LOADER_BZIP2_SUPPORT defined -.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2 +.PATH: ${SRCTOP}/contrib/bzip2 CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS -SRCS+= libstand_bzlib_private.h +SRCS+= libsa_bzlib_private.h .for file in bzlib.c crctable.c decompress.c huffman.c randtable.c SRCS+= _${file} CLEANFILES+= _${file} _${file}: ${file} - sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \ + sed "s|bzlib_private\.h|libsa_bzlib_private.h|" \ ${.ALLSRC} > ${.TARGET} .endfor -CLEANFILES+= libstand_bzlib_private.h -libstand_bzlib_private.h: bzlib_private.h +CLEANFILES+= libsa_bzlib_private.h +libsa_bzlib_private.h: bzlib_private.h sed -e 's||"stand.h"|' \ ${.ALLSRC} > ${.TARGET} # decompression functionality from zlib -.PATH: ${LIBSTAND_SRC}/../../contrib/zlib -CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../../contrib/zlib -SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h +.PATH: ${SRCTOP}/contrib/zlib +CFLAGS+=-DHAVE_MEMCPY -I${SRCTOP}/contrib/zlib +SRCS+= adler32.c crc32.c libsa_zutil.h libsa_gzguts.h .for file in infback.c inffast.c inflate.c inftrees.c zutil.c SRCS+= _${file} CLEANFILES+= _${file} _${file}: ${file} - sed -e "s|zutil\.h|libstand_zutil.h|" \ - -e "s|gzguts\.h|libstand_gzguts.h|" \ + sed -e "s|zutil\.h|libsa_zutil.h|" \ + -e "s|gzguts\.h|libsa_gzguts.h|" \ ${.ALLSRC} > ${.TARGET} .endfor # depend on stand.h being able to be included multiple times .for file in zutil.h gzguts.h -CLEANFILES+= libstand_${file} -libstand_${file}: ${file} +CLEANFILES+= libsa_${file} +libsa_${file}: ${file} sed -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ @@ -156,7 +152,7 @@ SRCS+= nandfs.c .endif # explicit_bzero -.PATH: ${SRCTOP}/sys/libkern +.PATH: ${SYSDIR}/libkern SRCS+= explicit_bzero.c .include diff --git a/lib/libstand/Makefile.depend b/sys/boot/libsa/Makefile.depend similarity index 100% rename from lib/libstand/Makefile.depend rename to sys/boot/libsa/Makefile.depend diff --git a/lib/libstand/__main.c b/sys/boot/libsa/__main.c similarity index 100% rename from lib/libstand/__main.c rename to sys/boot/libsa/__main.c diff --git a/lib/libstand/amd64/_setjmp.S b/sys/boot/libsa/amd64/_setjmp.S similarity index 100% rename from lib/libstand/amd64/_setjmp.S rename to sys/boot/libsa/amd64/_setjmp.S diff --git a/lib/libstand/arp.c b/sys/boot/libsa/arp.c similarity index 100% rename from lib/libstand/arp.c rename to sys/boot/libsa/arp.c diff --git a/lib/libstand/assert.c b/sys/boot/libsa/assert.c similarity index 100% rename from lib/libstand/assert.c rename to sys/boot/libsa/assert.c diff --git a/lib/libstand/bcd.c b/sys/boot/libsa/bcd.c similarity index 100% rename from lib/libstand/bcd.c rename to sys/boot/libsa/bcd.c diff --git a/lib/libstand/bootp.c b/sys/boot/libsa/bootp.c similarity index 100% rename from lib/libstand/bootp.c rename to sys/boot/libsa/bootp.c diff --git a/lib/libstand/bootp.h b/sys/boot/libsa/bootp.h similarity index 100% rename from lib/libstand/bootp.h rename to sys/boot/libsa/bootp.h diff --git a/lib/libstand/bootparam.c b/sys/boot/libsa/bootparam.c similarity index 100% rename from lib/libstand/bootparam.c rename to sys/boot/libsa/bootparam.c diff --git a/lib/libstand/bootparam.h b/sys/boot/libsa/bootparam.h similarity index 91% rename from lib/libstand/bootparam.h rename to sys/boot/libsa/bootparam.h index 6f0c773a0759..9c9f50ea434d 100644 --- a/lib/libstand/bootparam.h +++ b/sys/boot/libsa/bootparam.h @@ -1,4 +1,5 @@ /* $NetBSD: bootparam.h,v 1.3 1998/01/05 19:19:41 perry Exp $ */ +/* $FreeBSD$ */ int bp_whoami(int sock); int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path); diff --git a/lib/libstand/bzipfs.c b/sys/boot/libsa/bzipfs.c similarity index 100% rename from lib/libstand/bzipfs.c rename to sys/boot/libsa/bzipfs.c diff --git a/lib/libstand/cd9660.c b/sys/boot/libsa/cd9660.c similarity index 100% rename from lib/libstand/cd9660.c rename to sys/boot/libsa/cd9660.c diff --git a/lib/libstand/close.c b/sys/boot/libsa/close.c similarity index 100% rename from lib/libstand/close.c rename to sys/boot/libsa/close.c diff --git a/lib/libstand/closeall.c b/sys/boot/libsa/closeall.c similarity index 100% rename from lib/libstand/closeall.c rename to sys/boot/libsa/closeall.c diff --git a/sys/boot/common/crc32.c b/sys/boot/libsa/crc32.c similarity index 100% rename from sys/boot/common/crc32.c rename to sys/boot/libsa/crc32.c diff --git a/sys/boot/common/crc32.h b/sys/boot/libsa/crc32.h similarity index 100% rename from sys/boot/common/crc32.h rename to sys/boot/libsa/crc32.h diff --git a/lib/libstand/dev.c b/sys/boot/libsa/dev.c similarity index 100% rename from lib/libstand/dev.c rename to sys/boot/libsa/dev.c diff --git a/lib/libstand/dosfs.c b/sys/boot/libsa/dosfs.c similarity index 100% rename from lib/libstand/dosfs.c rename to sys/boot/libsa/dosfs.c diff --git a/lib/libstand/dosfs.h b/sys/boot/libsa/dosfs.h similarity index 100% rename from lib/libstand/dosfs.h rename to sys/boot/libsa/dosfs.h diff --git a/lib/libstand/environment.c b/sys/boot/libsa/environment.c similarity index 100% rename from lib/libstand/environment.c rename to sys/boot/libsa/environment.c diff --git a/lib/libstand/ether.c b/sys/boot/libsa/ether.c similarity index 100% rename from lib/libstand/ether.c rename to sys/boot/libsa/ether.c diff --git a/lib/libstand/ext2fs.c b/sys/boot/libsa/ext2fs.c similarity index 100% rename from lib/libstand/ext2fs.c rename to sys/boot/libsa/ext2fs.c diff --git a/lib/libstand/fstat.c b/sys/boot/libsa/fstat.c similarity index 100% rename from lib/libstand/fstat.c rename to sys/boot/libsa/fstat.c diff --git a/lib/libstand/getopt.c b/sys/boot/libsa/getopt.c similarity index 100% rename from lib/libstand/getopt.c rename to sys/boot/libsa/getopt.c diff --git a/lib/libstand/gets.c b/sys/boot/libsa/gets.c similarity index 100% rename from lib/libstand/gets.c rename to sys/boot/libsa/gets.c diff --git a/lib/libstand/globals.c b/sys/boot/libsa/globals.c similarity index 100% rename from lib/libstand/globals.c rename to sys/boot/libsa/globals.c diff --git a/sys/boot/common/gpt.c b/sys/boot/libsa/gpt.c similarity index 100% rename from sys/boot/common/gpt.c rename to sys/boot/libsa/gpt.c diff --git a/sys/boot/common/gpt.h b/sys/boot/libsa/gpt.h similarity index 100% rename from sys/boot/common/gpt.h rename to sys/boot/libsa/gpt.h diff --git a/lib/libstand/gzipfs.c b/sys/boot/libsa/gzipfs.c similarity index 100% rename from lib/libstand/gzipfs.c rename to sys/boot/libsa/gzipfs.c diff --git a/lib/libstand/i386/_setjmp.S b/sys/boot/libsa/i386/_setjmp.S similarity index 100% rename from lib/libstand/i386/_setjmp.S rename to sys/boot/libsa/i386/_setjmp.S diff --git a/lib/libstand/in_cksum.c b/sys/boot/libsa/in_cksum.c similarity index 100% rename from lib/libstand/in_cksum.c rename to sys/boot/libsa/in_cksum.c diff --git a/lib/libstand/inet_ntoa.c b/sys/boot/libsa/inet_ntoa.c similarity index 100% rename from lib/libstand/inet_ntoa.c rename to sys/boot/libsa/inet_ntoa.c diff --git a/lib/libstand/ioctl.c b/sys/boot/libsa/ioctl.c similarity index 100% rename from lib/libstand/ioctl.c rename to sys/boot/libsa/ioctl.c diff --git a/lib/libstand/iodesc.h b/sys/boot/libsa/iodesc.h similarity index 100% rename from lib/libstand/iodesc.h rename to sys/boot/libsa/iodesc.h diff --git a/lib/libstand/ip.c b/sys/boot/libsa/ip.c similarity index 98% rename from lib/libstand/ip.c rename to sys/boot/libsa/ip.c index 541cabc4bdd8..f2293b3cd3f9 100644 --- a/lib/libstand/ip.c +++ b/sys/boot/libsa/ip.c @@ -229,8 +229,8 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, } /* Check ip header */ - if (ip->ip_v != IPVERSION || - ip->ip_p != proto) { /* half char */ + if (ip->ip_v != IPVERSION || /* half char */ + ip->ip_p != proto) { #ifdef NET_DEBUG if (debug) { printf("readip: IP version or proto. ip_v=%d ip_p=%d\n", @@ -350,7 +350,8 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, last = NULL; STAILQ_FOREACH(ipq, &ipr->ip_queue, ipq_next) { if ((ntohs(ipq->ipq_hdr->ip_off) & IP_OFFMASK) != n / 8) { - errno = EAGAIN; + STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); + ip_reasm_free(ipr); return (-1); } diff --git a/lib/libstand/libstand.3 b/sys/boot/libsa/libstand.3 similarity index 100% rename from lib/libstand/libstand.3 rename to sys/boot/libsa/libstand.3 diff --git a/lib/libstand/lseek.c b/sys/boot/libsa/lseek.c similarity index 100% rename from lib/libstand/lseek.c rename to sys/boot/libsa/lseek.c diff --git a/lib/libstand/mips/_setjmp.S b/sys/boot/libsa/mips/_setjmp.S similarity index 100% rename from lib/libstand/mips/_setjmp.S rename to sys/boot/libsa/mips/_setjmp.S diff --git a/lib/libstand/nandfs.c b/sys/boot/libsa/nandfs.c similarity index 100% rename from lib/libstand/nandfs.c rename to sys/boot/libsa/nandfs.c diff --git a/lib/libstand/net.c b/sys/boot/libsa/net.c similarity index 100% rename from lib/libstand/net.c rename to sys/boot/libsa/net.c diff --git a/lib/libstand/net.h b/sys/boot/libsa/net.h similarity index 100% rename from lib/libstand/net.h rename to sys/boot/libsa/net.h diff --git a/lib/libstand/netif.c b/sys/boot/libsa/netif.c similarity index 100% rename from lib/libstand/netif.c rename to sys/boot/libsa/netif.c diff --git a/lib/libstand/netif.h b/sys/boot/libsa/netif.h similarity index 100% rename from lib/libstand/netif.h rename to sys/boot/libsa/netif.h diff --git a/lib/libstand/nfs.c b/sys/boot/libsa/nfs.c similarity index 100% rename from lib/libstand/nfs.c rename to sys/boot/libsa/nfs.c diff --git a/lib/libstand/nfsv2.h b/sys/boot/libsa/nfsv2.h similarity index 100% rename from lib/libstand/nfsv2.h rename to sys/boot/libsa/nfsv2.h diff --git a/lib/libstand/nullfs.c b/sys/boot/libsa/nullfs.c similarity index 100% rename from lib/libstand/nullfs.c rename to sys/boot/libsa/nullfs.c diff --git a/lib/libstand/open.c b/sys/boot/libsa/open.c similarity index 100% rename from lib/libstand/open.c rename to sys/boot/libsa/open.c diff --git a/lib/libstand/pager.c b/sys/boot/libsa/pager.c similarity index 100% rename from lib/libstand/pager.c rename to sys/boot/libsa/pager.c diff --git a/sys/boot/common/panic.c b/sys/boot/libsa/panic.c similarity index 100% rename from sys/boot/common/panic.c rename to sys/boot/libsa/panic.c diff --git a/lib/libstand/pkgfs.c b/sys/boot/libsa/pkgfs.c similarity index 100% rename from lib/libstand/pkgfs.c rename to sys/boot/libsa/pkgfs.c diff --git a/lib/libstand/powerpc/_setjmp.S b/sys/boot/libsa/powerpc/_setjmp.S similarity index 100% rename from lib/libstand/powerpc/_setjmp.S rename to sys/boot/libsa/powerpc/_setjmp.S diff --git a/lib/libstand/powerpc/syncicache.c b/sys/boot/libsa/powerpc/syncicache.c similarity index 100% rename from lib/libstand/powerpc/syncicache.c rename to sys/boot/libsa/powerpc/syncicache.c diff --git a/lib/libstand/printf.c b/sys/boot/libsa/printf.c similarity index 100% rename from lib/libstand/printf.c rename to sys/boot/libsa/printf.c diff --git a/lib/libstand/qdivrem.c b/sys/boot/libsa/qdivrem.c similarity index 100% rename from lib/libstand/qdivrem.c rename to sys/boot/libsa/qdivrem.c diff --git a/lib/libstand/quad.h b/sys/boot/libsa/quad.h similarity index 100% rename from lib/libstand/quad.h rename to sys/boot/libsa/quad.h diff --git a/lib/libstand/random.c b/sys/boot/libsa/random.c similarity index 100% rename from lib/libstand/random.c rename to sys/boot/libsa/random.c diff --git a/lib/libstand/rarp.c b/sys/boot/libsa/rarp.c similarity index 100% rename from lib/libstand/rarp.c rename to sys/boot/libsa/rarp.c diff --git a/lib/libstand/read.c b/sys/boot/libsa/read.c similarity index 100% rename from lib/libstand/read.c rename to sys/boot/libsa/read.c diff --git a/lib/libstand/readdir.c b/sys/boot/libsa/readdir.c similarity index 100% rename from lib/libstand/readdir.c rename to sys/boot/libsa/readdir.c diff --git a/lib/libstand/rpc.c b/sys/boot/libsa/rpc.c similarity index 100% rename from lib/libstand/rpc.c rename to sys/boot/libsa/rpc.c diff --git a/lib/libstand/rpc.h b/sys/boot/libsa/rpc.h similarity index 100% rename from lib/libstand/rpc.h rename to sys/boot/libsa/rpc.h diff --git a/lib/libstand/rpcv2.h b/sys/boot/libsa/rpcv2.h similarity index 100% rename from lib/libstand/rpcv2.h rename to sys/boot/libsa/rpcv2.h diff --git a/lib/libstand/saioctl.h b/sys/boot/libsa/saioctl.h similarity index 100% rename from lib/libstand/saioctl.h rename to sys/boot/libsa/saioctl.h diff --git a/lib/libstand/sbrk.c b/sys/boot/libsa/sbrk.c similarity index 100% rename from lib/libstand/sbrk.c rename to sys/boot/libsa/sbrk.c diff --git a/lib/libstand/sparc64/_setjmp.S b/sys/boot/libsa/sparc64/_setjmp.S similarity index 100% rename from lib/libstand/sparc64/_setjmp.S rename to sys/boot/libsa/sparc64/_setjmp.S diff --git a/lib/libstand/splitfs.c b/sys/boot/libsa/splitfs.c similarity index 100% rename from lib/libstand/splitfs.c rename to sys/boot/libsa/splitfs.c diff --git a/lib/libstand/stand.h b/sys/boot/libsa/stand.h similarity index 99% rename from lib/libstand/stand.h rename to sys/boot/libsa/stand.h index 8973a32d0bc9..bddfa76657d6 100644 --- a/lib/libstand/stand.h +++ b/sys/boot/libsa/stand.h @@ -376,6 +376,7 @@ extern int null_readdir(struct open_file *f, struct dirent *d); * Machine dependent functions and data, must be provided or stubbed by * the consumer */ +extern void exit(int); extern int getchar(void); extern int ischar(void); extern void putchar(int); diff --git a/lib/libstand/stat.c b/sys/boot/libsa/stat.c similarity index 100% rename from lib/libstand/stat.c rename to sys/boot/libsa/stat.c diff --git a/lib/libstand/strcasecmp.c b/sys/boot/libsa/strcasecmp.c similarity index 100% rename from lib/libstand/strcasecmp.c rename to sys/boot/libsa/strcasecmp.c diff --git a/lib/libstand/strdup.c b/sys/boot/libsa/strdup.c similarity index 100% rename from lib/libstand/strdup.c rename to sys/boot/libsa/strdup.c diff --git a/lib/libstand/strerror.c b/sys/boot/libsa/strerror.c similarity index 100% rename from lib/libstand/strerror.c rename to sys/boot/libsa/strerror.c diff --git a/lib/libstand/strtol.c b/sys/boot/libsa/strtol.c similarity index 100% rename from lib/libstand/strtol.c rename to sys/boot/libsa/strtol.c diff --git a/lib/libstand/strtoul.c b/sys/boot/libsa/strtoul.c similarity index 100% rename from lib/libstand/strtoul.c rename to sys/boot/libsa/strtoul.c diff --git a/lib/libstand/tftp.c b/sys/boot/libsa/tftp.c similarity index 100% rename from lib/libstand/tftp.c rename to sys/boot/libsa/tftp.c diff --git a/lib/libstand/tftp.h b/sys/boot/libsa/tftp.h similarity index 99% rename from lib/libstand/tftp.h rename to sys/boot/libsa/tftp.h index cbbbbd782129..c56fb81aafaa 100644 --- a/lib/libstand/tftp.h +++ b/sys/boot/libsa/tftp.h @@ -30,6 +30,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $FreeBSD$ */ diff --git a/lib/libstand/twiddle.c b/sys/boot/libsa/twiddle.c similarity index 100% rename from lib/libstand/twiddle.c rename to sys/boot/libsa/twiddle.c diff --git a/lib/libstand/udp.c b/sys/boot/libsa/udp.c similarity index 100% rename from lib/libstand/udp.c rename to sys/boot/libsa/udp.c diff --git a/lib/libstand/ufs.c b/sys/boot/libsa/ufs.c similarity index 100% rename from lib/libstand/ufs.c rename to sys/boot/libsa/ufs.c diff --git a/sys/boot/common/ufsread.c b/sys/boot/libsa/ufsread.c similarity index 100% rename from sys/boot/common/ufsread.c rename to sys/boot/libsa/ufsread.c diff --git a/sys/boot/common/util.c b/sys/boot/libsa/util.c similarity index 100% rename from sys/boot/common/util.c rename to sys/boot/libsa/util.c diff --git a/sys/boot/common/util.h b/sys/boot/libsa/util.h similarity index 100% rename from sys/boot/common/util.h rename to sys/boot/libsa/util.h diff --git a/lib/libstand/uuid_from_string.c b/sys/boot/libsa/uuid_from_string.c similarity index 100% rename from lib/libstand/uuid_from_string.c rename to sys/boot/libsa/uuid_from_string.c diff --git a/lib/libstand/uuid_to_string.c b/sys/boot/libsa/uuid_to_string.c similarity index 100% rename from lib/libstand/uuid_to_string.c rename to sys/boot/libsa/uuid_to_string.c diff --git a/lib/libstand/write.c b/sys/boot/libsa/write.c similarity index 100% rename from lib/libstand/write.c rename to sys/boot/libsa/write.c diff --git a/lib/libstand/zalloc.c b/sys/boot/libsa/zalloc.c similarity index 100% rename from lib/libstand/zalloc.c rename to sys/boot/libsa/zalloc.c diff --git a/lib/libstand/zalloc_defs.h b/sys/boot/libsa/zalloc_defs.h similarity index 100% rename from lib/libstand/zalloc_defs.h rename to sys/boot/libsa/zalloc_defs.h diff --git a/lib/libstand/zalloc_malloc.c b/sys/boot/libsa/zalloc_malloc.c similarity index 100% rename from lib/libstand/zalloc_malloc.c rename to sys/boot/libsa/zalloc_malloc.c diff --git a/lib/libstand/zalloc_mem.h b/sys/boot/libsa/zalloc_mem.h similarity index 100% rename from lib/libstand/zalloc_mem.h rename to sys/boot/libsa/zalloc_mem.h diff --git a/lib/libstand/zalloc_protos.h b/sys/boot/libsa/zalloc_protos.h similarity index 100% rename from lib/libstand/zalloc_protos.h rename to sys/boot/libsa/zalloc_protos.h diff --git a/sys/boot/libsa32/Makefile b/sys/boot/libsa32/Makefile new file mode 100644 index 000000000000..f09811b62128 --- /dev/null +++ b/sys/boot/libsa32/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +DO32=1 + +.include + +LIB=sa32 +LIBSA_CPUARCH=${MACHINE_CPUARCH:C/amd64/i386/} + +CFLAGS+= -I. + +.PATH: ${SASRC} +.include "${SASRC}/Makefile" diff --git a/sys/boot/libstand32/Makefile.depend b/sys/boot/libsa32/Makefile.depend similarity index 100% rename from sys/boot/libstand32/Makefile.depend rename to sys/boot/libsa32/Makefile.depend diff --git a/sys/boot/libstand32/Makefile b/sys/boot/libstand32/Makefile deleted file mode 100644 index 6dbf1f420910..000000000000 --- a/sys/boot/libstand32/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# $FreeBSD$ - -.include - -LIBSTAND_SRC= ${.CURDIR}/../../../lib/libstand -.if ${MACHINE_CPUARCH} == "amd64" -LIBSTAND_CPUARCH=i386 -.else -LIBSTAND_CPUARCH=${MACHINE_CPUARCH} -.endif -LIBC_SRC= ${LIBSTAND_SRC}/../libc -INTERNALLIB= -INCS= -MAN= -.PATH: ${LIBSTAND_SRC} - -.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -I. -.endif - -.include "${LIBSTAND_SRC}/Makefile" - -.if ${MACHINE_CPUARCH} == "amd64" -CLEANFILES+= machine -beforedepend ${OBJS}: machine -machine: .NOMETA - ln -fs ${.CURDIR}/../../i386/include machine -.endif diff --git a/sys/boot/common/Makefile.inc b/sys/boot/loader.mk similarity index 68% rename from sys/boot/common/Makefile.inc rename to sys/boot/loader.mk index 7b0e81c85570..26eda97df66d 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/loader.mk @@ -1,8 +1,14 @@ # $FreeBSD$ +.include "defs.mk" + +.PATH: ${LDRSRC} ${BOOTSRC}/libsa + +CFLAGS+=-I${LDRSRC} + SRCS+= boot.c commands.c console.c devopen.c interp.c SRCS+= interp_backslash.c interp_parse.c ls.c misc.c -SRCS+= module.c panic.c +SRCS+= module.c .if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64" SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c @@ -22,23 +28,12 @@ SRCS+= load_elf64.c reloc_elf64.c SRCS+= load_elf32.c reloc_elf32.c .endif -.if defined(LOADER_NET_SUPPORT) -SRCS+= dev_net.c +.if ${LOADER_DISK_SUPPORT:Uyes} == "yes" +SRCS+= disk.c part.c .endif -.if !defined(LOADER_NO_DISK_SUPPORT) -SRCS+= disk.c part.c -CFLAGS+= -DLOADER_DISK_SUPPORT -.if !defined(LOADER_NO_GPT_SUPPORT) -SRCS+= crc32.c -CFLAGS+= -DLOADER_GPT_SUPPORT -.endif -.if !defined(LOADER_NO_MBR_SUPPORT) -CFLAGS+= -DLOADER_MBR_SUPPORT -.endif -.endif -.if !defined(LOADER_NO_GELI_SUPPORT) -CFLAGS+= -DLOADER_GELI_SUPPORT +.if ${LOADER_NET_SUPPORT:Uno} == "yes" +SRCS+= dev_net.c .endif .if defined(HAVE_BCACHE) @@ -48,6 +43,8 @@ SRCS+= bcache.c .if defined(MD_IMAGE_SIZE) CFLAGS+= -DMD_IMAGE_SIZE=${MD_IMAGE_SIZE} SRCS+= md.c +.else +CLEANFILES+= md.o .endif # Machine-independant ISA PnP @@ -59,9 +56,9 @@ SRCS+= pnp.c .endif # Forth interpreter -.if defined(BOOT_FORTH) +.if ${MK_FORTH} != "no" SRCS+= interp_forth.c -.include "${SRCTOP}/sys/boot/Makefile.ficl" +.include "${BOOTSRC}/ficl.mk" .endif .if defined(BOOT_PROMPT_123) @@ -70,7 +67,6 @@ CFLAGS+= -DBOOT_PROMPT_123 .if defined(LOADER_INSTALL_SUPPORT) SRCS+= install.c -CFLAGS+=-I${.CURDIR}/../../../../lib/libstand .endif CLEANFILES+= vers.c @@ -78,6 +74,6 @@ VERSION_FILE?= ${.CURDIR}/version .if ${MK_REPRODUCIBLE_BUILD} != no REPRO_FLAG= -r .endif -vers.c: ${SRCTOP}/sys/boot/common/newvers.sh ${VERSION_FILE} - sh ${SRCTOP}/sys/boot/common/newvers.sh ${REPRO_FLAG} ${VERSION_FILE} \ +vers.c: ${LDRSRC}/newvers.sh ${VERSION_FILE} + sh ${LDRSRC}/newvers.sh ${REPRO_FLAG} ${VERSION_FILE} \ ${NEWVERSWHAT} diff --git a/sys/boot/common/Makefile b/sys/boot/man/Makefile similarity index 81% rename from sys/boot/common/Makefile rename to sys/boot/man/Makefile index fcca328b5007..15285acbafc9 100644 --- a/sys/boot/common/Makefile +++ b/sys/boot/man/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include MAN+= loader.8 .if ${MK_ZFS} != "no" diff --git a/sys/boot/man/Makefile.depend b/sys/boot/man/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/sys/boot/man/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/sys/boot/common/loader.8 b/sys/boot/man/loader.8 similarity index 100% rename from sys/boot/common/loader.8 rename to sys/boot/man/loader.8 diff --git a/sys/boot/common/zfsloader.8 b/sys/boot/man/zfsloader.8 similarity index 100% rename from sys/boot/common/zfsloader.8 rename to sys/boot/man/zfsloader.8 diff --git a/sys/boot/mips/beri/Makefile.inc b/sys/boot/mips/beri/Makefile.inc index ef5a7cee7413..a12699c3a6f7 100644 --- a/sys/boot/mips/beri/Makefile.inc +++ b/sys/boot/mips/beri/Makefile.inc @@ -1,6 +1,5 @@ # $FreeBSD$ -BINDIR?= /boot CFLAGS+= -ffreestanding LDFLAGS+= -nostdlib diff --git a/sys/boot/mips/beri/boot2/Makefile b/sys/boot/mips/beri/boot2/Makefile index a12db1b6e6b8..9a993e22cdac 100644 --- a/sys/boot/mips/beri/boot2/Makefile +++ b/sys/boot/mips/beri/boot2/Makefile @@ -29,7 +29,8 @@ # # $FreeBSD$ -BINDIR?= /boot +.include + INSTALLFLAGS= -b LOADERS= flashboot jtagboot @@ -48,8 +49,9 @@ AFLAGS= -G0 CFLAGS= -ffreestanding \ -I${.CURDIR} \ - -I${.CURDIR}/../../../common \ - -I${.CURDIR}/../../../.. \ + -I${SASRC} \ + -I${LDRSRC} \ + -I${SYSDIR} \ -D_KERNEL \ -Wall \ -G0 \ @@ -57,22 +59,18 @@ CFLAGS= -ffreestanding \ -msoft-float \ -g -# where to get libstand from -CFLAGS+= -I${.CURDIR}/../../../../../lib/libstand/ -LIBSTAND= ${.OBJDIR}/../../../../../lib/libstand/libstand.a - LDFLAGS= -nostdlib \ -static \ -Wl,-N \ -G0 \ -L${.CURDIR} -.PATH: ${.CURDIR}/../common -CFLAGS+= -I${.CURDIR}/../common +.PATH: ${BOOTSRC}/mips/beri/common +CFLAGS+= -I${BOOTSRC}/mips/beri/common flashboot.elf: relocate.o start.o boot2.o altera_jtag_uart.o cfi.o sdcard.o ${CC} ${LDFLAGS} -T ${.CURDIR}/flashboot.ldscript -o ${.TARGET} \ - ${.ALLSRC} ${LIBSTAND} + ${.ALLSRC} ${LIBSA} flashboot: flashboot.elf ${OBJCOPY} -S -O binary ${.TARGET}.elf ${.TARGET} flashboot.md5: flashboot @@ -80,7 +78,7 @@ flashboot.md5: flashboot jtagboot: start.o boot2.o altera_jtag_uart.o cfi.o sdcard.o ${CC} ${LDFLAGS} -T ${.CURDIR}/jtagboot.ldscript -o ${.TARGET} \ - ${.ALLSRC} ${LIBSTAND} + ${.ALLSRC} ${LIBSA} jtagboot.md5: jtagboot md5 jtagboot > jtagboot.md5 diff --git a/sys/boot/mips/beri/loader/Makefile b/sys/boot/mips/beri/loader/Makefile index 77262f360b08..b8a237c7878d 100644 --- a/sys/boot/mips/beri/loader/Makefile +++ b/sys/boot/mips/beri/loader/Makefile @@ -29,7 +29,8 @@ # # $FreeBSD$ -.include +.include + MK_SSP= no MAN= @@ -59,35 +60,19 @@ SRCS+= altera_jtag_uart.c \ # Since we don't have a backward compatibility issue, default to this on BERI. CFLAGS+= -DBOOT_PROMPT_123 -CFLAGS+= -DLOADER_DISK_SUPPORT -CFLAGS+= -DLOADER_UFS_SUPPORT -CFLAGS+= -DLOADER_GZIP_SUPPORT -CFLAGS+= -DLOADER_BZIP2_SUPPORT - -#CFLAGS+= -DLOADER_NET_SUPPORT -#CFLAGS+= -DLOADER_NFS_SUPPORT -#CFLAGS+= -DLOADER_TFTP_SUPPORT - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../../ficl -CFLAGS+= -I${.CURDIR}/../../../ficl/mips64 -LIBFICL= ${.OBJDIR}/../../../ficl/libficl.a -.endif - -# Common code across BERI boot loader parts -.PATH: ${.CURDIR}/../common -CFLAGS+= -I${.CURDIR}/../common +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_GZIP_SUPPORT?= yes +LOADER_BZIP2_SUPPORT?= yes # Always add MI sources -.PATH: ${.CURDIR}/../../../common -.include "${.CURDIR}/../../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../../common +.include "${BOOTSRC}/loader.mk" # BERI files common to boot2 and loader -.PATH: ${.CURDIR}/../common -CFLAGS+= -I${.CURDIR}/../common +.PATH: ${BOOTSRC}/mips/beri/common +CFLAGS+= -I${BOOTSRC}/mips/beri/common # Loader-specific MD headers CFLAGS+= -I${.CURDIR} @@ -107,19 +92,15 @@ LDFLAGS= -nostdlib \ -L${.CURDIR} \ -e __start -# where to get libstand from -CFLAGS+= -I${.CURDIR}/../../../../../lib/libstand/ -LIBSTAND= ${.OBJDIR}/../../../../../lib/libstand/libstand.a - -DPADD= ${LIBFICL} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBSTAND} +DPADD= ${LIBFICL} ${LIBSA} +LDADD= ${LIBFICL} ${LIBSA} loader.help: help.common help.mips cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../../forth -.include "${.CURDIR}/../../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc menu.rc @@ -128,8 +109,8 @@ FILES+= loader.rc menu.rc CFLAGS+= -ffunction-sections -fdata-sections CFLAGS+= -Wl,--gc-sections # Link USB BOOT library -LDADD+= ${.OBJDIR}/../../../usb/libusbboot.a -CFLAGS+= -I${.CURDIR}/../../../usb +LDADD+= ${BOOTOBJ}/usb/libusbboot.a +CFLAGS+= -I${BOOTSRC}/usb # Define USB SUPPORT CFLAGS+= -DLOADER_USB_SUPPORT .endif diff --git a/sys/boot/mips/uboot/Makefile b/sys/boot/mips/uboot/Makefile index 2a339a51377f..70369eb43da7 100644 --- a/sys/boot/mips/uboot/Makefile +++ b/sys/boot/mips/uboot/Makefile @@ -1,11 +1,10 @@ # $FreeBSD$ -.include +.include FILES= ubldr NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b WARNS?= 1 # Address at which ubldr will be loaded. @@ -15,88 +14,19 @@ UBLDR_LOADADDR?= 0xffffffff80800000 # Architecture-specific loader code SRCS= start.S conf.c vers.c -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif -LOADER_MSDOS_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no -.if ${MK_NAND} != "no" -LOADER_NANDFS_SUPPORT?= yes -.else -LOADER_NANDFS_SUPPORT?= no -.endif +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif - -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_MSDOS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_MSDOS_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_NANDFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt -CFLAGS+= -DLOADER_FDT_SUPPORT -LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -.if ${MACHINE_ARCH:Mmips64*} != "" -CFLAGS+= -I${.CURDIR}/../../ficl/mips64 -.else -CFLAGS+= -I${.CURDIR}/../../ficl/mips -.endif -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help @@ -105,32 +35,16 @@ CFLAGS+= -ffreestanding -msoft-float -g LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} -# Pull in common loader code -.PATH: ${.CURDIR}/../../uboot/common -.include "${.CURDIR}/../../uboot/common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../uboot/common +.include "${BOOTSRC}/uboot.mk" -# U-Boot standalone support library -LIBUBOOT= ${.OBJDIR}/../../uboot/lib/libuboot.a -CFLAGS+= -I${.CURDIR}/../../uboot/lib -CFLAGS+= -I${.OBJDIR}/../../uboot/lib - -# where to get libstand from -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ -LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a - -# clang doesn't understand %D as a specifier to printf -#NO_WERROR.clang= -#NO_WERROR= - -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} OBJS+= ${SRCS:N*.h:R:S/$/.o/g} -loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.uboot ${BOOTSRC}/fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} ldscript.abs: echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} @@ -146,8 +60,8 @@ ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD} CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin .if !defined(LOADER_ONLY) -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" # Install loader.rc. FILES+= loader.rc diff --git a/sys/boot/mips/uboot/conf.c b/sys/boot/mips/uboot/conf.c index 30c92610f724..3579b6a56753 100644 --- a/sys/boot/mips/uboot/conf.c +++ b/sys/boot/mips/uboot/conf.c @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include "dev_net.h" #endif +/* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ +void (*exitfn)(int) = exit; + struct devsw *devsw[] = { #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) &uboot_storage, diff --git a/sys/boot/ofw/Makefile.inc b/sys/boot/ofw/Makefile.inc index e67c0dc904eb..265f86d1ed55 100644 --- a/sys/boot/ofw/Makefile.inc +++ b/sys/boot/ofw/Makefile.inc @@ -1,8 +1,3 @@ # $FreeBSD$ -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -LDFLAGS+= -m elf32ppc_fbsd -.endif - .include "../Makefile.inc" diff --git a/sys/boot/ofw/libofw/Makefile b/sys/boot/ofw/libofw/Makefile index 3b91ea28d37a..836e2a821d1a 100644 --- a/sys/boot/ofw/libofw/Makefile +++ b/sys/boot/ofw/libofw/Makefile @@ -1,18 +1,18 @@ # $FreeBSD$ +.include + LIB= ofw INTERNALLIB= SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ ofw_time.c openfirm.c -.PATH: ${.CURDIR}/../../zfs +.PATH: ${ZFSSRC} SRCS+= devicename_stubs.c -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - # Pick up the bootstrap header for some interface items -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. CFLAGS+= -ffreestanding .if ${MACHINE_CPUARCH} == "powerpc" @@ -25,11 +25,4 @@ SRCS+= ppc64_elf_freebsd.c CFLAGS+= -DDISK_DEBUG .endif -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine - -CLEANFILES+= machine - .include - -beforedepend ${OBJS}: machine diff --git a/sys/boot/powerpc/Makefile.inc b/sys/boot/powerpc/Makefile.inc index 1b62477aa7c5..265f86d1ed55 100644 --- a/sys/boot/powerpc/Makefile.inc +++ b/sys/boot/powerpc/Makefile.inc @@ -1,7 +1,3 @@ # $FreeBSD$ -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -.endif - .include "../Makefile.inc" diff --git a/sys/boot/powerpc/boot1.chrp/Makefile b/sys/boot/powerpc/boot1.chrp/Makefile index a642f6c4b958..8439d140b68a 100644 --- a/sys/boot/powerpc/boot1.chrp/Makefile +++ b/sys/boot/powerpc/boot1.chrp/Makefile @@ -1,10 +1,11 @@ # $FreeBSD$ +.include + SSP_CFLAGS= PROG= boot1.elf NEWVERSWHAT= "Open Firmware boot block" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b FILES= boot1.hfs @@ -13,12 +14,11 @@ SRCS= boot1.c ashldi3.c syncicache.c MAN= CFLAGS= -ffreestanding -msoft-float \ - -I${.CURDIR}/../../common -I${.CURDIR}/../../../ \ + -I${LDRSRC} -I${SYSDIR} -I${SASRC} \ -D_STANDALONE LDFLAGS=-nostdlib -static -Wl,-N -.include "${.CURDIR}/../Makefile.inc" -.PATH: ${.CURDIR}/../../../libkern ${.CURDIR}/../../../../lib/libc/powerpc/gen ${.CURDIR} +.PATH: ${SYSDIR}/libkern ${SRCTOP}/lib/libc/powerpc/gen ${.CURDIR} # The following inserts out objects into a template HFS # created by generate-hfs.sh @@ -36,7 +36,7 @@ boot1.hfs: boot1.elf bootinfo.txt CLEANFILES= boot1.hfs -boot1.o: ${.CURDIR}/../../common/ufsread.c +boot1.o: ${SASRC}/ufsread.c .include diff --git a/sys/boot/powerpc/kboot/Makefile b/sys/boot/powerpc/kboot/Makefile index 6a1741b1db7c..4055b1a63fdc 100644 --- a/sys/boot/powerpc/kboot/Makefile +++ b/sys/boot/powerpc/kboot/Makefile @@ -1,12 +1,11 @@ # $FreeBSD$ -.include +.include MK_SSP= no MAN= PROG= loader.kboot NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b # Architecture-specific loader code @@ -14,10 +13,10 @@ SRCS= conf.c metadata.c vers.c main.c ppc64_elf_freebsd.c SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no @@ -25,56 +24,19 @@ LOADER_GZIP_SUPPORT?= yes LOADER_FDT_SUPPORT= yes LOADER_BZIP2_SUPPORT?= no -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt -CFLAGS+= -I${.CURDIR}/../../../contrib/libfdt +CFLAGS+= -I${FDTSRC} +CFLAGS+= -I${SYSDIR}/contrib/libfdt CFLAGS+= -DLOADER_FDT_SUPPORT -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +LIBFDT= ${BOOTOBJ}/fdt/libfdt.a .endif CFLAGS+= -mcpu=powerpc64 # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "${BOOTSRC}/loader.mk" +.PATH: ${SYSDIR}/libkern +CFLAGS+= -I${SYSDIR} CFLAGS+= -I. CLEANFILES+= loader.help @@ -89,23 +51,15 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc # 64-bit bridge extensions CFLAGS+= -Wa,-mppc64bridge -# Pull in common loader code -#.PATH: ${.CURDIR}/../../ofw/common -#.include "${.CURDIR}/../../ofw/common/Makefile.inc" +DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} -# where to get libstand from -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - -DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSTAND} - -loader.help: help.common help.kboot ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.kboot ${FDTSRC}/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc menu.rc diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile index 1d135f0a217b..883c242df33c 100644 --- a/sys/boot/powerpc/ofw/Makefile +++ b/sys/boot/powerpc/ofw/Makefile @@ -1,22 +1,21 @@ # $FreeBSD$ -.include +.include MK_SSP= no MAN= PROG= loader NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b # Architecture-specific loader code SRCS= conf.c metadata.c vers.c start.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no @@ -24,54 +23,19 @@ LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= no LOADER_FDT_SUPPORT?= yes -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" SRCS+= ofwfdt.c -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt -CFLAGS+= -I${.CURDIR}/../../../contrib/libfdt +CFLAGS+= -I${FDTSRC} +CFLAGS+= -I${SYSDIR}/contrib/libfdt CFLAGS+= -DLOADER_FDT_SUPPORT -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +LIBFDT= ${BOOTOBJ}/fdt/libfdt.a .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "${BOOTSRC}/loader.mk" + +.PATH: ${SYSDIR}/libkern +CFLAGS+= -I${SYSDIR} CFLAGS+= -I. CLEANFILES+= loader.help @@ -84,26 +48,22 @@ CFLAGS+= -DRELOC=${RELOC} LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc # Pull in common loader code -.PATH: ${.CURDIR}/../../ofw/common -.include "${.CURDIR}/../../ofw/common/Makefile.inc" +.PATH: ${BOOTSRC}/ofw/common +.include "${BOOTSRC}/ofw/common/Makefile.inc" # Open Firmware standalone support library -LIBOFW= ${.OBJDIR}/../../ofw/libofw/libofw.a -CFLAGS+= -I${.CURDIR}/../../ofw/libofw +LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a +CFLAGS+= -I${BOOTSRC}/ofw/libofw -# where to get libstand from -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} -DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSTAND} - -loader.help: help.common help.ofw ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.ofw ${FDTSRC}/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc menu.rc diff --git a/sys/boot/powerpc/ofw/conf.c b/sys/boot/powerpc/ofw/conf.c index 5666f4accae2..7cad372cef04 100644 --- a/sys/boot/powerpc/ofw/conf.c +++ b/sys/boot/powerpc/ofw/conf.c @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include "dev_net.h" #endif +/* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ +void (*exitfn)(int) = exit; + /* * We could use linker sets for some or all of these, but * then we would have to control what ended up linked into diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile index b54cebe2bd06..dd4117f4081a 100644 --- a/sys/boot/powerpc/ps3/Makefile +++ b/sys/boot/powerpc/ps3/Makefile @@ -1,12 +1,11 @@ # $FreeBSD$ -.include +.include MK_SSP= no MAN= PROG= loader.ps3 NEWVERSWHAT= "Playstation 3 loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b # Architecture-specific loader code @@ -15,7 +14,6 @@ SRCS+= lv1call.S ps3cons.c font.h ps3mmu.c ps3net.c ps3repo.c \ ps3stor.c ps3disk.c ps3cdrom.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= yes @@ -26,55 +24,18 @@ LOADER_GZIP_SUPPORT?= yes LOADER_FDT_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt +CFLAGS+= -I${FDTSRC} CFLAGS+= -DLOADER_FDT_SUPPORT -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +LIBFDT= ${BOOTOBJ}/fdt/libfdt.a .endif CFLAGS+= -mcpu=powerpc64 # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "${BOOTSRC}/loader.mk" +.PATH: ${SYSDIR}/libkern +CFLAGS+= -I${SYSDIR} CFLAGS+= -I. CLEANFILES+= loader.help @@ -86,28 +47,20 @@ CFLAGS+= -DRELOC=${RELOC} LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc -# Pull in common loader code -#.PATH: ${.CURDIR}/../../ofw/common -#.include "${.CURDIR}/../../ofw/common/Makefile.inc" - -# where to get libstand from -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - -DPADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND} +DPADD= ${LIBFICL} ${LIBOFW} ${LIBSA} +LDADD= ${LIBFICL} ${LIBOFW} ${LIBSA} SC_DFLT_FONT=cp437 font.h: uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h -loader.help: help.common help.ps3 ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.ps3 ${FDTSRC}/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc menu.rc diff --git a/sys/boot/powerpc/uboot/Makefile b/sys/boot/powerpc/uboot/Makefile index b18d8ebd6d68..41dcb2750aaf 100644 --- a/sys/boot/powerpc/uboot/Makefile +++ b/sys/boot/powerpc/uboot/Makefile @@ -1,10 +1,9 @@ # $FreeBSD$ -.include +.include PROG= ubldr NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} -BINDIR?= /boot INSTALLFLAGS= -b MAN= @@ -12,11 +11,6 @@ MAN= SRCS= start.S conf.c vers.c SRCS+= ucmpdi2.c -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no @@ -25,59 +19,12 @@ LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif - -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -I${.CURDIR}/../../fdt -CFLAGS+= -I${.OBJDIR}/../../fdt -CFLAGS+= -DLOADER_FDT_SUPPORT -LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a -LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "${BOOTSRC}/loader.mk" +.PATH: ${SYSDIR}/libkern +CFLAGS+= -I${SYSDIR} CFLAGS+= -I. CLEANFILES+= ${PROG}.help @@ -86,28 +33,16 @@ CFLAGS+= -ffreestanding LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc -# Pull in common loader code -.PATH: ${.CURDIR}/../../uboot/common -.include "${.CURDIR}/../../uboot/common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../uboot/common +.include "${BOOTSRC}/uboot.mk" -# U-Boot standalone support library -LIBUBOOT= ${.OBJDIR}/../../uboot/lib/libuboot.a -CFLAGS+= -I${.CURDIR}/../../uboot/lib -CFLAGS+= -I${.OBJDIR}/../../uboot/lib +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} -# where to get libstand from -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} - -loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt +loader.help: help.common help.uboot ${BOOTSRC}/fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth +.PATH: ${BOOTSRC}/forth FILES= loader.help .include diff --git a/sys/boot/powerpc/uboot/conf.c b/sys/boot/powerpc/uboot/conf.c index 35305371ce6b..561238d1ccf7 100644 --- a/sys/boot/powerpc/uboot/conf.c +++ b/sys/boot/powerpc/uboot/conf.c @@ -35,6 +35,9 @@ __FBSDID("$FreeBSD$"); #include "dev_net.h" #endif +/* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ +void (*exitfn)(int) = exit; + /* * We could use linker sets for some or all of these, but * then we would have to control what ended up linked into diff --git a/sys/boot/sparc64/Makefile.inc b/sys/boot/sparc64/Makefile.inc index ef5a7cee7413..a12699c3a6f7 100644 --- a/sys/boot/sparc64/Makefile.inc +++ b/sys/boot/sparc64/Makefile.inc @@ -1,6 +1,5 @@ # $FreeBSD$ -BINDIR?= /boot CFLAGS+= -ffreestanding LDFLAGS+= -nostdlib diff --git a/sys/boot/sparc64/boot1/Makefile b/sys/boot/sparc64/boot1/Makefile index 3453b286308e..7d501a0f75ba 100644 --- a/sys/boot/sparc64/boot1/Makefile +++ b/sys/boot/sparc64/boot1/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + PROG= boot1.elf INTERNALPROG= MAN= @@ -11,8 +13,8 @@ BOOTBLOCKBASE= 0x4000 CFLAGS.clang+=-mcmodel=small CFLAGS.gcc+=-mcmodel=medlow -CFLAGS+=-Os -I${.CURDIR}/../../common -LDFLAGS=-Ttext ${BOOTBLOCKBASE} -Wl,-N +CFLAGS+=-Os -I${LDRSRC} +LDFLAGS+=-Ttext ${BOOTBLOCKBASE} -Wl,-N # Construct boot1. sunlabel expects it to contain zeroed-out space for the # label, and to be of the correct size. @@ -25,6 +27,6 @@ ${FILES}: boot1.aout boot1.aout: boot1.elf elf2aout -o ${.TARGET} ${.ALLSRC} -boot1.o: ${.CURDIR}/../../common/ufsread.c +boot1.o: ${SASRC}/ufsread.c .include diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile index ad48be461cef..c5fc902f009b 100644 --- a/sys/boot/sparc64/loader/Makefile +++ b/sys/boot/sparc64/loader/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include MK_SSP= no MAN= @@ -15,6 +15,8 @@ SRCS= locore.S main.c metadata.c vers.c LOADER_DISK_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no LOADER_ZFS_SUPPORT?= no LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes @@ -26,74 +28,37 @@ LOADER_DEBUG?= no .if ${LOADER_DEBUG} == "yes" CFLAGS+= -DLOADER_DEBUG .endif -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif .if ${LOADER_ZFS_SUPPORT} == "yes" CFLAGS+= -DLOADER_ZFS_SUPPORT -CFLAGS+= -I${.CURDIR}/../../zfs -CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs -LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/sparc64 -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +CFLAGS+= -I${ZFSSRC} +CFLAGS+= -I${SYSDIR}/cddl/boot/zfs +LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help -LDFLAGS= -static +LDFLAGS+= -static # Open Firmware standalone support library -LIBOFW= ${.OBJDIR}/../../ofw/libofw/libofw.a -CFLAGS+= -I${.CURDIR}/../../ofw/libofw/ - -# where to get libstand from -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a +CFLAGS+= -I${BOOTSRC}/ofw/libofw/ # Need sys/ for crypto/intake.h CFLAGS+= -I${SRCTOP}/sys -DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} -lstand +DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} +LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} loader.help: help.common help.sparc64 cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" +.PATH: ${BOOTSRC}/forth +.include "${BOOTSRC}/forth/Makefile.inc" FILES+= loader.rc menu.rc diff --git a/sys/boot/uboot.mk b/sys/boot/uboot.mk new file mode 100644 index 000000000000..d8871bb47456 --- /dev/null +++ b/sys/boot/uboot.mk @@ -0,0 +1,20 @@ +# $FreeBSD$ + +SRCS+= main.c metadata.c + +.PATH: ${UBOOTSRC}/common + +CFLAGS+= -I${UBOOTSRC}/common + +# U-Boot standalone support library +LIBUBOOT= ${BOOTOBJ}/uboot/lib/libuboot.a +CFLAGS+= -I${UBOOTSRC}/lib +CFLAGS+= -I${BOOTOBJ}/uboot/lib + +.if ${LOADER_FDT_SUPPORT} == "yes" +CFLAGS+= -I${FDTSRC} +CFLAGS+= -I${BOOTOBJ}/fdt +CFLAGS+= -DLOADER_FDT_SUPPORT +LIBUBOOT_FDT= ${BOOTOBJ}/uboot/fdt/libuboot_fdt.a +LIBFDT= ${BOOTOBJ}/fdt/libfdt.a +.endif diff --git a/sys/boot/uboot/Makefile b/sys/boot/uboot/Makefile index 43b57480fe4c..8c3a80dd6e2e 100644 --- a/sys/boot/uboot/Makefile +++ b/sys/boot/uboot/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.include +.include SUBDIR= lib diff --git a/sys/boot/uboot/Makefile.inc b/sys/boot/uboot/Makefile.inc index e67c0dc904eb..265f86d1ed55 100644 --- a/sys/boot/uboot/Makefile.inc +++ b/sys/boot/uboot/Makefile.inc @@ -1,8 +1,3 @@ # $FreeBSD$ -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -LDFLAGS+= -m elf32ppc_fbsd -.endif - .include "../Makefile.inc" diff --git a/sys/boot/uboot/common/Makefile.inc b/sys/boot/uboot/common/Makefile.inc deleted file mode 100644 index e12804cb3903..000000000000 --- a/sys/boot/uboot/common/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= main.c metadata.c diff --git a/sys/boot/uboot/fdt/Makefile b/sys/boot/uboot/fdt/Makefile index 95c0800789a2..87bebca5c0d8 100644 --- a/sys/boot/uboot/fdt/Makefile +++ b/sys/boot/uboot/fdt/Makefile @@ -1,8 +1,8 @@ # $FreeBSD$ -.include +.include -.PATH: ${.CURDIR}/../../common +.PATH: ${LDRSRC} LIB= uboot_fdt INTERNALLIB= @@ -12,23 +12,14 @@ SRCS= uboot_fdt.c CFLAGS+= -ffreestanding -msoft-float -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - # U-Boot library headers -CFLAGS+= -I${.CURDIR}/../lib +CFLAGS+= -I${UBOOTSRC}/lib # libfdt headers -CFLAGS+= -I${.CURDIR}/../../fdt +CFLAGS+= -I${FDTSRC} # Pick up the bootstrap header for some interface items -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. - -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine - -CLEANFILES+= machine +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. .include .include - -beforedepend ${OBJS}: machine diff --git a/sys/boot/uboot/lib/Makefile b/sys/boot/uboot/lib/Makefile index 982da713c66b..6b25a415e6cd 100644 --- a/sys/boot/uboot/lib/Makefile +++ b/sys/boot/uboot/lib/Makefile @@ -1,23 +1,20 @@ # $FreeBSD$ -.include +.include -.PATH: ${.CURDIR}/../../common +.PATH: ${LDRSRC} LIB= uboot INTERNALLIB= WARNS?= 2 -SRCS= crc32.c console.c copy.c devicename.c elf_freebsd.c glue.c +SRCS= console.c copy.c devicename.c elf_freebsd.c glue.c SRCS+= module.c net.c reboot.c time.c CFLAGS+= -ffreestanding -msoft-float -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ - -.if !defined(LOADER_NO_DISK_SUPPORT) -SRCS+= disk.c -CFLAGS+= -DLOADER_DISK_SUPPORT +.if ${LOADER_DISK_SUPPORT:Uyes} == "yes" +SRCS+= disk.c .endif .if ${MK_FDT} != "no" @@ -27,26 +24,19 @@ LOADER_FDT_SUPPORT= no .endif .if ${LOADER_FDT_SUPPORT} == "yes" -CFLAGS+= -DLOADER_FDT_SUPPORT -I${.CURDIR}/../../fdt +CFLAGS+= -DLOADER_FDT_SUPPORT -I${FDTSRC} .endif # Pick up FDT includes -CFLAGS+= -I${.CURDIR}/../../../../sys/contrib/libfdt/ +CFLAGS+= -I${SYSDIR}/contrib/libfdt/ # Pick up the bootstrap header for some interface items -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. .ifdef(BOOT_DISK_DEBUG) # Make the disk code more talkative CFLAGS+= -DDISK_DEBUG .endif -machine: .NOMETA - ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine - -CLEANFILES+= machine - .include .include - -beforedepend ${OBJS}: machine diff --git a/sys/boot/userboot/Makefile b/sys/boot/userboot/Makefile index ebacf6454773..0a53a217dc15 100644 --- a/sys/boot/userboot/Makefile +++ b/sys/boot/userboot/Makefile @@ -2,7 +2,7 @@ .include -SUBDIR= ficl libstand test zfs userboot +SUBDIR= test userboot .include diff --git a/sys/boot/userboot/Makefile.inc b/sys/boot/userboot/Makefile.inc new file mode 100644 index 000000000000..265f86d1ed55 --- /dev/null +++ b/sys/boot/userboot/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +.include "../Makefile.inc" diff --git a/sys/boot/userboot/ficl/Makefile b/sys/boot/userboot/ficl/Makefile deleted file mode 100644 index 927a504d8ce0..000000000000 --- a/sys/boot/userboot/ficl/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# $FreeBSD$ -# -.include -MK_SSP= no - -.PATH: ${.CURDIR}/../../ficl -.PATH: ${.CURDIR}/../../ficl/${MACHINE_CPUARCH} -BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ - prefix.c search.c stack.c tools.c vm.c words.c - -SRCS= ${BASE_SRCS} sysdep.c softcore.c -CLEANFILES= softcore.c testmain testmain.o - -CWARNFLAGS.loader.c.c += -Wno-implicit-function-declaration - -.if HAVE_PNP -CFLAGS+= -DHAVE_PNP -.endif -.include -.ifmake testmain -CFLAGS+= -DTESTMAIN -D_TESTMAIN -SRCS+= testmain.c -PROG= testmain -.include -.else -LIB= ficl -INTERNALLIB= -.include -.endif - -# Standard softwords -.PATH: ${.CURDIR}/../../ficl/softwords -SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \ - ifbrack.fr -# Optional OO extension softwords -#SOFTWORDS+= oo.fr classes.fr - -#.if ${MACHINE_CPUARCH} == "amd64" -#CFLAGS+= -m32 -I. -#.endif - -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -I. -.endif - -CFLAGS+= -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} -CFLAGS+= -I${.CURDIR}/../../common - -softcore.c: ${SOFTWORDS} softcore.awk - (cd ${.CURDIR}/../../ficl/softwords; cat ${SOFTWORDS} \ - | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET} - -#.if ${MACHINE_CPUARCH} == "amd64" -#${SRCS:M*.c:R:S/$/.o/g}: machine -# -#beforedepend ${OBJS}: machine -# -#machine: .NOMETA -# ln -sf ${.CURDIR}/../../i386/include machine -# -#CLEANFILES+= machine -#.endif diff --git a/sys/boot/userboot/libstand/Makefile b/sys/boot/userboot/libstand/Makefile deleted file mode 100644 index d8a1100f8452..000000000000 --- a/sys/boot/userboot/libstand/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ - -.include - -LIBSTAND_SRC= ${.CURDIR}/../../../../lib/libstand - -INTERNALLIB= -INCS= -MAN= -.PATH: ${LIBSTAND_SRC} - -.include "${LIBSTAND_SRC}/Makefile" diff --git a/sys/boot/userboot/test/Makefile b/sys/boot/userboot/test/Makefile index e9ecf58c77a7..cfca6971d12c 100644 --- a/sys/boot/userboot/test/Makefile +++ b/sys/boot/userboot/test/Makefile @@ -3,13 +3,13 @@ MAN= -.include +.include MK_SSP= no PROG= test INTERNALPROG= -CFLAGS+= -I${.CURDIR}/.. -CFLAGS+= -I${.CURDIR}/../../.. +CFLAGS+= -I${BOOTSRC}/userboot +CFLAGS+= -I${SYSDIR} .include diff --git a/sys/boot/userboot/test/Makefile.depend b/sys/boot/userboot/test/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/sys/boot/userboot/test/Makefile.depend +++ b/sys/boot/userboot/test/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/sys/boot/userboot/userboot/Makefile b/sys/boot/userboot/userboot/Makefile index 44376b8bad3b..aea362d88b9a 100644 --- a/sys/boot/userboot/userboot/Makefile +++ b/sys/boot/userboot/userboot/Makefile @@ -2,9 +2,15 @@ MAN= -.include +.include + MK_SSP= no +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no + SHLIB_NAME= userboot.so MK_CTF= no STRIP= @@ -29,10 +35,8 @@ SRCS+= userboot_disk.c SRCS+= vers.c CFLAGS+= -Wall -CFLAGS+= -I${.CURDIR}/.. -CFLAGS+= -I${.CURDIR}/../../common -CFLAGS+= -I${.CURDIR}/../../.. -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand +CFLAGS+= -I${BOOTSRC}/userboot +CFLAGS+= -I${SYSDIR} CFLAGS+= -ffreestanding -I. CWARNFLAGS.main.c += -Wno-implicit-function-declaration @@ -41,27 +45,15 @@ LDFLAGS+= -nostdlib -Wl,-Bsymbolic NEWVERSWHAT= "User boot" ${MACHINE_CPUARCH} -.if ${MK_FORTH} != "no" -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/i386 -CFLAGS+= -DBF_DICTSIZE=15000 -LIBFICL= ${.OBJDIR}/../ficl/libficl.a -.endif - -LIBSTAND= ${.OBJDIR}/../libstand/libstand.a - .if ${MK_ZFS} != "no" CFLAGS+= -DUSERBOOT_ZFS_SUPPORT -LIBZFSBOOT= ${.OBJDIR}/../zfs/libzfsboot.a +LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "${BOOTSRC}/loader.mk" CFLAGS+= -I. -DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND} -LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSTAND} +DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA} +LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA} .include diff --git a/sys/boot/userboot/userboot/Makefile.depend b/sys/boot/userboot/userboot/Makefile.depend index 871417f71578..0d4affa29aee 100644 --- a/sys/boot/userboot/userboot/Makefile.depend +++ b/sys/boot/userboot/userboot/Makefile.depend @@ -4,9 +4,9 @@ DIRDEPS = \ include \ include/xlocale \ - sys/boot/userboot/ficl \ - sys/boot/userboot/libstand \ - sys/boot/userboot/zfs \ + sys/boot/ficl \ + sys/boot/libsa \ + sys/boot/zfs \ .include diff --git a/sys/boot/userboot/zfs/Makefile b/sys/boot/userboot/zfs/Makefile deleted file mode 100644 index 3180b94788b7..000000000000 --- a/sys/boot/userboot/zfs/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# $FreeBSD$ - -S= ${.CURDIR}/../../zfs - -.PATH: ${S} ${.CURDIR}/../../../crypto/skein -LIB= zfsboot -INTERNALLIB= - -SRCS+= zfs.c skein.c skein_block.c - -# Do not unroll skein loops, reduce code size -CFLAGS+= -DSKEIN_LOOP=111 - -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand -CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs -CFLAGS+= -I${.CURDIR}/../../../crypto/skein - -CFLAGS+= -ffreestanding -fPIC -CFLAGS+= -Wformat -Wall - -.include diff --git a/sys/boot/zfs/Makefile b/sys/boot/zfs/Makefile index 9180049becb1..7575aa9207eb 100644 --- a/sys/boot/zfs/Makefile +++ b/sys/boot/zfs/Makefile @@ -1,41 +1,22 @@ # $FreeBSD$ +.include + LIB= zfsboot INTERNALLIB= -SRCS+= zfs.c - -SRCS+= skein.c skein_block.c +.PATH: ${ZFSSRC} +SRCS+= zfs.c skein.c skein_block.c # Do not unroll skein loops, reduce code size CFLAGS+= -DSKEIN_LOOP=111 -.PATH: ${.CURDIR}/../../crypto/skein +.PATH: ${SYSDIR}/crypto/skein CFLAGS+= -DBOOTPROG=\"zfsloader\" -CFLAGS+= -I${.CURDIR}/../common -I${.CURDIR}/../.. -I. -CFLAGS+= -I${.CURDIR}/../../../lib/libstand -CFLAGS+= -I${.CURDIR}/../../cddl/boot/zfs -CFLAGS+= -I${.CURDIR}/../../crypto/skein - -.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -march=i386 -.endif -.if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -m32 -.endif +CFLAGS+= -I${LDRSRC} -I${SYSDIR} -I. +CFLAGS+= -I${SYSDIR}/cddl/boot/zfs +CFLAGS+= -I${SYSDIR}/crypto/skein CFLAGS+= -Wformat -Wall -.if ${MACHINE_CPUARCH} == "amd64" -CLEANFILES+= machine -machine: .NOMETA - ln -sf ${.CURDIR}/../../i386/include machine -.endif - .include .include - -.if ${MACHINE_CPUARCH} == "amd64" -.if !exists(machine) -beforedepend ${OBJS}: machine -.endif -.endif diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c index 062895eef79a..0334bddb667a 100644 --- a/sys/boot/zfs/zfs.c +++ b/sys/boot/zfs/zfs.c @@ -368,17 +368,61 @@ zfs_readdir(struct open_file *f, struct dirent *d) } static int -vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size) +vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes) { - int fd; + int fd, ret; + size_t res, size, remainder, rb_size, blksz; + unsigned secsz; + off_t off; + char *bouncebuf, *rb_buf; fd = (uintptr_t) priv; - lseek(fd, offset, SEEK_SET); - if (read(fd, buf, size) == size) { - return 0; - } else { - return (EIO); + bouncebuf = NULL; + + ret = ioctl(fd, DIOCGSECTORSIZE, &secsz); + if (ret != 0) + return (ret); + + off = offset / secsz; + remainder = offset % secsz; + if (lseek(fd, off * secsz, SEEK_SET) == -1) + return (errno); + + rb_buf = buf; + rb_size = bytes; + size = roundup2(bytes + remainder, secsz); + blksz = size; + if (remainder != 0 || size != bytes) { + bouncebuf = zfs_alloc(secsz); + if (bouncebuf == NULL) { + printf("vdev_read: out of memory\n"); + return (ENOMEM); + } + rb_buf = bouncebuf; + blksz = rb_size - remainder; } + + while (bytes > 0) { + res = read(fd, rb_buf, rb_size); + if (res != rb_size) { + ret = EIO; + goto error; + } + if (bytes < blksz) + blksz = bytes; + if (bouncebuf != NULL) + memcpy(buf, rb_buf + remainder, blksz); + buf = (void *)((uintptr_t)buf + blksz); + bytes -= blksz; + remainder = 0; + blksz = rb_size; + } + + ret = 0; +error: + if (bouncebuf != NULL) + zfs_free(bouncebuf, secsz); + return (ret); } static int diff --git a/sys/boot/zfs32/Makefile b/sys/boot/zfs32/Makefile new file mode 100644 index 000000000000..32d0074ad340 --- /dev/null +++ b/sys/boot/zfs32/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +DO32=1 + +.include "${.CURDIR}/../zfs/Makefile" diff --git a/sys/boot/userboot/libstand/Makefile.depend b/sys/boot/zfs32/Makefile.depend similarity index 87% rename from sys/boot/userboot/libstand/Makefile.depend rename to sys/boot/zfs32/Makefile.depend index 1d86fce1441d..18be76b0cb6f 100644 --- a/sys/boot/userboot/libstand/Makefile.depend +++ b/sys/boot/zfs32/Makefile.depend @@ -3,9 +3,7 @@ DIRDEPS = \ include \ - include/arpa \ include/xlocale \ - lib/libbz2 \ .include diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 5f000e05511c..22c5f8b3b74b 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -1057,6 +1057,7 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len return (ENXIO); } + memset(&ccb, 0, sizeof(ccb)); if (length > 0) { xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); ccb.ccb_h.ccb_state = ADA_CCB_DUMP; @@ -1079,8 +1080,8 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len } xpt_polled_action(&ccb); - error = cam_periph_error(&ccb, - 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); + error = adaerror(&ccb, + 0, SF_NO_RECOVERY | SF_NO_RETRY); if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); @@ -1115,8 +1116,8 @@ adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); xpt_polled_action(&ccb); - error = cam_periph_error(&ccb, - 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); + error = adaerror(&ccb, + 0, SF_NO_RECOVERY | SF_NO_RETRY); if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); @@ -3465,7 +3466,7 @@ adaspindown(uint8_t cmd, int flags) { struct cam_periph *periph; struct ada_softc *softc; - union ccb *ccb; + struct ccb_ataio local_ccb; int error; CAM_PERIPH_FOREACH(periph, &adadriver) { @@ -3485,8 +3486,11 @@ adaspindown(uint8_t cmd, int flags) if (bootverbose) xpt_print(periph->path, "spin-down\n"); - ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); - cam_fill_ataio(&ccb->ataio, + memset(&local_ccb, 0, sizeof(local_ccb)); + xpt_setup_ccb(&local_ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP; + + cam_fill_ataio(&local_ccb, 0, adadone, CAM_DIR_NONE | flags, @@ -3494,14 +3498,35 @@ adaspindown(uint8_t cmd, int flags) NULL, 0, ada_default_timeout*1000); - ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, 0); + ata_28bit_cmd(&local_ccb, cmd, 0, 0, 0); - error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0, - /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY, - softc->disk->d_devstat); + if (!SCHEDULER_STOPPED()) { + /* + * Not panicing, can just do the normal runccb + * XXX should make cam_periph_runccb work while + * XXX panicing... later + */ + error = cam_periph_runccb((union ccb *)&local_ccb, adaerror, + /*cam_flags*/0, /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY, + softc->disk->d_devstat); + } else { + /* + * Panicing, so we have to do this by hand: do + * xpt_polled_action to run the request through the SIM, + * extract the error, and if the queue was frozen, + * unfreeze it. cam_periph_runccb takes care of these + * details, but xpt_polled_action doesn't. + */ + xpt_polled_action((union ccb *)&local_ccb); + error = adaerror((union ccb *)&local_ccb, 0, + SF_NO_RECOVERY | SF_NO_RETRY); + if ((local_ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(local_ccb.ccb_h.path, + /*relsim_flags*/0, /*reduction*/0, + /*timeout*/0, /*getcount_only*/0); + } if (error != 0) xpt_print(periph->path, "Spin-down disk failed\n"); - xpt_release_ccb(ccb); cam_periph_unlock(periph); } } @@ -3509,11 +3534,29 @@ adaspindown(uint8_t cmd, int flags) static void adashutdown(void *arg, int howto) { + int how; adaflush(); - if (ada_spindown_shutdown != 0 && - (howto & (RB_HALT | RB_POWEROFF)) != 0) - adaspindown(ATA_STANDBY_IMMEDIATE, 0); + + /* + * STANDBY IMMEDIATE saves any volatile data to the drive. It also spins + * down hard drives. IDLE IMMEDIATE also saves the volatile data without + * a spindown. We send the former when we expect to lose power soon. For + * a warm boot, we send the latter to avoid a thundering herd of spinups + * just after the kernel loads while probing. We have to do something to + * flush the data because the BIOS in many systems resets the HBA + * causing a COMINIT/COMRESET negotiation, which some drives interpret + * as license to toss the volatile data, and others count as unclean + * shutdown when in the Active PM state in SMART attributes. + * + * adaspindown will ensure that we don't send this to a drive that + * doesn't support it. + */ + if (ada_spindown_shutdown != 0) { + how = (howto & (RB_HALT | RB_POWEROFF | RB_POWERCYCLE)) ? + ATA_STANDBY_IMMEDIATE : ATA_IDLE_IMMEDIATE; + adaspindown(how, 0); + } } static void @@ -3521,6 +3564,10 @@ adasuspend(void *arg) { adaflush(); + /* + * SLEEP also fushes any volatile data, like STANDBY IMEDIATE, + * so we don't need to send it as well. + */ if (ada_spindown_suspend != 0) adaspindown(ATA_SLEEP, CAM_DEV_QFREEZE); } diff --git a/sys/cam/cam_iosched.c b/sys/cam/cam_iosched.c index 52e1092dd183..c42594e22da7 100644 --- a/sys/cam/cam_iosched.c +++ b/sys/cam/cam_iosched.c @@ -415,6 +415,7 @@ cam_iosched_iops_init(struct iop_stats *ios) ios->l_value1 = ios->current / ios->softc->quanta; if (ios->l_value1 <= 0) ios->l_value1 = 1; + ios->l_value2 = 0; return 0; } @@ -422,10 +423,30 @@ cam_iosched_iops_init(struct iop_stats *ios) static int cam_iosched_iops_tick(struct iop_stats *ios) { + int new_ios; + + /* + * Allow at least one IO per tick until all + * the IOs for this interval have been spent. + */ + new_ios = (int)((ios->current * (uint64_t)ios->softc->this_frac) >> 16); + if (new_ios < 1 && ios->l_value2 < ios->current) { + new_ios = 1; + ios->l_value2++; + } + + /* + * If this a new accounting interval, discard any "unspent" ios + * granted in the previous interval. Otherwise add the new ios to + * the previously granted ones that haven't been spent yet. + */ + if ((ios->softc->total_ticks % ios->softc->quanta) == 0) { + ios->l_value1 = new_ios; + ios->l_value2 = 1; + } else { + ios->l_value1 += new_ios; + } - ios->l_value1 = (int)((ios->current * (uint64_t)ios->softc->this_frac) >> 16); - if (ios->l_value1 <= 0) - ios->l_value1 = 1; return 0; } @@ -436,9 +457,10 @@ cam_iosched_iops_caniop(struct iop_stats *ios, struct bio *bp) /* * So if we have any more IOPs left, allow it, - * otherwise wait. + * otherwise wait. If current iops is 0, treat that + * as unlimited as a failsafe. */ - if (ios->l_value1 <= 0) + if (ios->current > 0 && ios->l_value1 <= 0) return EAGAIN; return 0; } @@ -504,8 +526,11 @@ cam_iosched_bw_caniop(struct iop_stats *ios, struct bio *bp) * what we let through this quantum (to prevent the * starvation), at the cost of getting a little less * next quantum. + * + * Also note that if the current limit is <= 0, + * we treat it as unlimited as a failsafe. */ - if (ios->l_value1 <= 0) + if (ios->current > 0 && ios->l_value1 <= 0) return EAGAIN; @@ -533,7 +558,7 @@ cam_iosched_ticker(void *arg) sbintime_t now, delta; int pending; - callout_reset(&isc->ticker, hz / isc->quanta - 1, cam_iosched_ticker, isc); + callout_reset(&isc->ticker, hz / isc->quanta, cam_iosched_ticker, isc); now = sbinuptime(); delta = now - isc->last_time; @@ -673,7 +698,10 @@ cam_iosched_cl_maybe_steer(struct control_loop *clp) } #endif - /* Trim or similar currently pending completion */ +/* + * Trim or similar currently pending completion. Should only be set for + * those drivers wishing only one Trim active at a time. + */ #define CAM_IOSCHED_FLAG_TRIM_ACTIVE (1ul << 0) /* Callout active, and needs to be torn down */ #define CAM_IOSCHED_FLAG_CALLOUT_ACTIVE (1ul << 1) @@ -747,9 +775,8 @@ cam_iosched_iop_stats_init(struct cam_iosched_softc *isc, struct iop_stats *ios) { ios->limiter = none; - cam_iosched_limiter_init(ios); ios->in = 0; - ios->max = 300000; + ios->max = ios->current = 300000; ios->min = 1; ios->out = 0; ios->pending = 0; @@ -758,6 +785,7 @@ cam_iosched_iop_stats_init(struct cam_iosched_softc *isc, struct iop_stats *ios) ios->ema = 0; ios->emvar = 0; ios->softc = isc; + cam_iosched_limiter_init(ios); } static int @@ -795,7 +823,7 @@ cam_iosched_limiter_sysctl(SYSCTL_HANDLER_ARGS) return error; } /* Note: disk load averate requires ticker to be always running */ - callout_reset(&isc->ticker, hz / isc->quanta - 1, cam_iosched_ticker, isc); + callout_reset(&isc->ticker, hz / isc->quanta, cam_iosched_ticker, isc); isc->flags |= CAM_IOSCHED_FLAG_CALLOUT_ACTIVE; cam_periph_unlock(isc->periph); @@ -880,6 +908,27 @@ cam_iosched_sysctl_latencies(SYSCTL_HANDLER_ARGS) return (error); } +static int +cam_iosched_quanta_sysctl(SYSCTL_HANDLER_ARGS) +{ + int *quanta; + int error, value; + + quanta = (unsigned *)arg1; + value = *quanta; + + error = sysctl_handle_int(oidp, (int *)&value, 0, req); + if ((error != 0) || (req->newptr == NULL)) + return (error); + + if (value < 1 || value > hz) + return (EINVAL); + + *quanta = value; + + return (0); +} + static void cam_iosched_iop_stats_sysctl_init(struct cam_iosched_softc *isc, struct iop_stats *ios, char *name) { @@ -1031,7 +1080,7 @@ cam_iosched_init(struct cam_iosched_softc **iscp, struct cam_periph *periph) callout_init_mtx(&(*iscp)->ticker, cam_periph_mtx(periph), 0); (*iscp)->periph = periph; cam_iosched_cl_init(&(*iscp)->cl, *iscp); - callout_reset(&(*iscp)->ticker, hz / (*iscp)->quanta - 1, cam_iosched_ticker, *iscp); + callout_reset(&(*iscp)->ticker, hz / (*iscp)->quanta, cam_iosched_ticker, *iscp); (*iscp)->flags |= CAM_IOSCHED_FLAG_CALLOUT_ACTIVE; } #endif @@ -1101,9 +1150,9 @@ void cam_iosched_sysctl_init(struct cam_iosched_softc *isc, &isc->read_bias, 100, "How biased towards read should we be independent of limits"); - SYSCTL_ADD_INT(ctx, n, - OID_AUTO, "quanta", CTLFLAG_RW, - &isc->quanta, 200, + SYSCTL_ADD_PROC(ctx, n, + OID_AUTO, "quanta", CTLTYPE_UINT | CTLFLAG_RW, + &isc->quanta, 0, cam_iosched_quanta_sysctl, "I", "How many quanta per second do we slice the I/O up into"); SYSCTL_ADD_INT(ctx, n, @@ -1342,8 +1391,7 @@ cam_iosched_queue_work(struct cam_iosched_softc *isc, struct bio *bp) #endif } #ifdef CAM_IOSCHED_DYNAMIC - else if (do_dynamic_iosched && - (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH)) { + else if (do_dynamic_iosched && (bp->bio_cmd != BIO_READ)) { if (cam_iosched_sort_queue(isc)) bioq_disksort(&isc->write_queue, bp); else @@ -1387,7 +1435,7 @@ cam_iosched_schedule(struct cam_iosched_softc *isc, struct cam_periph *periph) } /* - * Complete a trim request + * Complete a trim request. Mark that we no longer have one in flight. */ void cam_iosched_trim_done(struct cam_iosched_softc *isc) @@ -1437,7 +1485,8 @@ cam_iosched_bio_complete(struct cam_iosched_softc *isc, struct bio *bp, /* * Tell the io scheduler that you've pushed a trim down into the sim. - * xxx better place for this? + * This also tells the I/O scheduler not to push any more trims down, so + * some periphs do not call it if they can cope with multiple trims in flight. */ void cam_iosched_submit_trim(struct cam_iosched_softc *isc) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 50ccbcdb2468..7157fc4c1eb0 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -40,8 +40,6 @@ * Author: Ken Merry */ -#define _CTL_C - #include __FBSDID("$FreeBSD$"); @@ -410,6 +408,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN, static int ctl_lun_map_size = 1024; SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN, &ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)"); +#ifdef CTL_TIME_IO +static int ctl_time_io_secs = CTL_TIME_IO_DEFAULT_SECS; +SYSCTL_INT(_kern_cam_ctl, OID_AUTO, time_io_secs, CTLFLAG_RWTUN, + &ctl_time_io_secs, 0, "Log requests taking more seconds"); +#endif /* * Supported pages (0x00), Serial number (0x80), Device ID (0x83), diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 24fcbdf6933e..eb10603254c2 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -1308,18 +1308,17 @@ cfiscsi_session_delete(struct cfiscsi_session *cs) KASSERT(TAILQ_EMPTY(&cs->cs_waiting_for_data_out), ("destroying session with non-empty queue")); + mtx_lock(&softc->lock); + TAILQ_REMOVE(&softc->sessions, cs, cs_next); + mtx_unlock(&softc->lock); + cfiscsi_session_unregister_initiator(cs); if (cs->cs_target != NULL) cfiscsi_target_release(cs->cs_target); icl_conn_close(cs->cs_conn); icl_conn_free(cs->cs_conn); - - mtx_lock(&softc->lock); - TAILQ_REMOVE(&softc->sessions, cs, cs_next); - cv_signal(&softc->sessions_cv); - mtx_unlock(&softc->lock); - free(cs, M_CFISCSI); + cv_signal(&softc->sessions_cv); } static int diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h index 140db42730f4..c3779b7f3fa6 100644 --- a/sys/cam/ctl/ctl_io.h +++ b/sys/cam/ctl/ctl_io.h @@ -40,12 +40,6 @@ #ifndef _CTL_IO_H_ #define _CTL_IO_H_ -#ifdef _CTL_C -#define EXTERN(__var,__val) __var = __val -#else -#define EXTERN(__var,__val) extern __var -#endif - #define CTL_MAX_CDBLEN 32 /* * Uncomment this next line to enable printing out times for I/Os @@ -55,7 +49,6 @@ #define CTL_TIME_IO #ifdef CTL_TIME_IO #define CTL_TIME_IO_DEFAULT_SECS 90 -EXTERN(int ctl_time_io_secs, CTL_TIME_IO_DEFAULT_SECS); #endif /* diff --git a/sys/cam/mmc/mmc.h b/sys/cam/mmc/mmc.h index 9fae837e9e03..2e31f029000b 100644 --- a/sys/cam/mmc/mmc.h +++ b/sys/cam/mmc/mmc.h @@ -87,6 +87,7 @@ struct mmc_params { #define CARD_FEATURE_SDIO 0x1 << 2 #define CARD_FEATURE_SD20 0x1 << 3 #define CARD_FEATURE_MMC 0x1 << 4 +#define CARD_FEATURE_18V 0x1 << 5 uint8_t sdio_func_count; } __packed; diff --git a/sys/cam/mmc/mmc_da.c b/sys/cam/mmc/mmc_da.c index 31bbf000e14c..6969e26c70bd 100644 --- a/sys/cam/mmc/mmc_da.c +++ b/sys/cam/mmc/mmc_da.c @@ -378,8 +378,7 @@ sddaopen(struct disk *dp) return (error); } - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, - ("sddaopen\n")); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaopen\n")); softc = (struct sdda_softc *)periph->softc; softc->flags |= SDDA_FLAG_OPEN; @@ -403,8 +402,7 @@ sddaclose(struct disk *dp) cam_periph_lock(periph); - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, - ("sddaclose\n")); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaclose\n")); while (softc->refcount != 0) cam_periph_sleep(periph, &softc->refcount, PRIBIO, "sddaclose", 1); diff --git a/sys/cam/mmc/mmc_sdio.c b/sys/cam/mmc/mmc_sdio.c deleted file mode 100644 index 093da15d6fac..000000000000 --- a/sys/cam/mmc/mmc_sdio.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2015 Ilya Bakulin - * All rights reserved. - * - * 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, - * without modification, immediately at the beginning of the file. - * 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 AUTHOR ``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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include /* for xpt_print below */ -#include /* for PRIu64 */ -#include "opt_cam.h" - - -void -sdio_print_stupid_message(struct cam_periph *periph) { - - CAM_DEBUG(periph->path, CAM_DEBUG_INFO, - ("%s\n", __func__)); -} - -/* - * f - function to read from / write to - * wr - is write - * adr - address to r/w - * data - actual data to write - */ -void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data) { - struct ccb_mmcio *mmcio; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("sdio_fill_mmcio(f=%d, wr=%d, adr=%02x, data=%02x)\n", f, wr, adr, (data == NULL ? 0 : *data))); - mmcio = &ccb->mmcio; - - mmcio->cmd.opcode = SD_IO_RW_DIRECT; - mmcio->cmd.arg = SD_IO_RW_FUNC(f) | SD_IO_RW_ADR(adr); - if (wr) - mmcio->cmd.arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); - mmcio->cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; - mmcio->cmd.data->len = 0; -} - -uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data) { - struct ccb_mmcio *mmcio; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("sdio_parse_mmcio(datap=%p)\n", data)); - mmcio = &ccb->mmcio; - - if (mmcio->cmd.error) - return (mmcio->cmd.error); - if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) - return (MMC_ERR_BADCRC); - if (mmcio->cmd.resp[0] & (R5_ILLEGAL_COMMAND | R5_FUNCTION_NUMBER)) - return (MMC_ERR_INVALID); - if (mmcio->cmd.resp[0] & R5_OUT_OF_RANGE) - return (MMC_ERR_FAILED); - - /* Just for information... */ - if (R5_IO_CURRENT_STATE(mmcio->cmd.resp[0]) != 1) - printf("!!! SDIO state %d\n", R5_IO_CURRENT_STATE(mmcio->cmd.resp[0])); - - if (mmcio->cmd.resp[0] & R5_ERROR) - printf("An error was detected!\n"); - - if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) - printf("A CRC error was detected!\n"); - - if (data != NULL) - *data = (uint8_t) (mmcio->cmd.resp[0] & 0xff); - return (MMC_ERR_NONE); - -} diff --git a/sys/cam/mmc/mmc_sdio.h b/sys/cam/mmc/mmc_sdio.h deleted file mode 100644 index 6d22ffc02c13..000000000000 --- a/sys/cam/mmc/mmc_sdio.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2014 Ilya Bakulin. All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - * - * Portions of this software may have been developed with reference to - * the SD Simplified Specification. The following disclaimer may apply: - * - * The following conditions apply to the release of the simplified - * specification ("Simplified Specification") by the SD Card Association and - * the SD Group. The Simplified Specification is a subset of the complete SD - * Specification which is owned by the SD Card Association and the SD - * Group. This Simplified Specification is provided on a non-confidential - * basis subject to the disclaimers below. Any implementation of the - * Simplified Specification may require a license from the SD Card - * Association, SD Group, SD-3C LLC or other third parties. - * - * Disclaimers: - * - * The information contained in the Simplified Specification is presented only - * as a standard specification for SD Cards and SD Host/Ancillary products and - * is provided "AS-IS" without any representations or warranties of any - * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD - * Card Association for any damages, any infringements of patents or other - * right of the SD Group, SD-3C LLC, the SD Card Association or any third - * parties, which may result from its use. No license is granted by - * implication, estoppel or otherwise under any patent or other rights of the - * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing - * herein shall be construed as an obligation by the SD Group, the SD-3C LLC - * or the SD Card Association to disclose or distribute any technical - * information, know-how or other confidential information to any third party. - * - * $FreeBSD$ - */ - -/* - * Various SDIO-related stuff - */ - -#ifndef CAM_MMC_SDIO_H -#define CAM_MMC_SDIO_H - -void sdio_print_stupid_message(struct cam_periph *periph); -void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data); -uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data); -#endif diff --git a/sys/cam/mmc/mmc_xpt.c b/sys/cam/mmc/mmc_xpt.c index 0142a6f07916..ff0521b435b5 100644 --- a/sys/cam/mmc/mmc_xpt.c +++ b/sys/cam/mmc/mmc_xpt.c @@ -58,12 +58,13 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include /* for xpt_print below */ #include /* for PRIu64 */ #include "opt_cam.h" +FEATURE(mmccam, "CAM-based MMC/SD/SDIO stack"); + static struct cam_ed * mmc_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id); static void mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, @@ -162,6 +163,7 @@ typedef struct { union ccb saved_ccb; uint32_t flags; #define PROBE_FLAG_ACMD_SENT 0x1 /* CMD55 is sent, card expects ACMD */ + uint8_t acmd41_count; /* how many times ACMD41 has been issued */ struct cam_periph *periph; } mmcprobe_softc; @@ -219,6 +221,8 @@ mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, printf("Got AC_PATH_REGISTERED -- whatever...\n"); } else if (async_code == AC_PATH_DEREGISTERED ) { printf("Got AC_PATH_DEREGISTERED -- whatever...\n"); + } else if (async_code == AC_UNIT_ATTENTION) { + printf("Got interrupt generated by the card and ignored it\n"); } else panic("Unknown async code\n"); } @@ -299,9 +303,9 @@ mmc_scan_lun(struct cam_periph *periph, struct cam_path *path, static void mmc_action(union ccb *start_ccb) { - CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mmc_action! func_code=%x, action %s\n", start_ccb->ccb_h.func_code, - xpt_action_name(start_ccb->ccb_h.func_code))); + xpt_action_name(start_ccb->ccb_h.func_code))); switch (start_ccb->ccb_h.func_code) { case XPT_SCAN_BUS: @@ -486,6 +490,7 @@ mmcprobe_register(struct cam_periph *periph, void *arg) } softc->flags = 0; + softc->acmd41_count = 0; periph->softc = softc; softc->periph = periph; softc->action = PROBE_INVALID; @@ -672,8 +677,12 @@ mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb) * We set CCS bit because we do support SDHC cards. * XXX: Don't set CCS if no response to CMD8. */ - mmcio->cmd.arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */ + uint32_t cmd_arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */ + if (softc->acmd41_count < 10 && mmcp->card_ocr != 0 ) + cmd_arg |= MMC_OCR_S18R; + mmcio->cmd.arg = cmd_arg; mmcio->cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + softc->acmd41_count++; } else { mmcio->cmd.opcode = MMC_APP_CMD; /* CMD 55 */ mmcio->cmd.arg = 0; /* rca << 16 */ @@ -769,8 +778,9 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) /* There was a device there, but now it's gone... */ if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { xpt_async(AC_LOST_DEVICE, path, NULL); - PROBE_SET_ACTION(softc, PROBE_INVALID); } + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; } path->device->protocol = PROTO_MMCSD; PROBE_SET_ACTION(softc, PROBE_SEND_IF_COND); @@ -936,12 +946,18 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) mmcp->card_features |= CARD_FEATURE_SDHC; } - } else { - CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, - ("Card not ready: %08x\n", mmcio->cmd.resp[0])); - /* Send CMD55+ACMD41 once again */ - PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); - } + /* Whether the card supports 1.8V signaling */ + if (mmcio->cmd.resp[0] & MMC_OCR_S18A) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card supports 1.8V signaling\n")); + mmcp->card_features |= CARD_FEATURE_18V; + } + } else { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card not ready: %08x\n", mmcio->cmd.resp[0])); + /* Send CMD55+ACMD41 once again */ + PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); + } break; } @@ -1054,21 +1070,6 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } - - /* Also announce each SDIO function */ - struct mmc_params *mmcp = &path->device->mmc_ident_data; - - for (int i = 0; i < mmcp->sdio_func_count; i++) { - struct cam_path *newpath; - cam_status status; - status = xpt_create_path(&newpath, NULL, - done_ccb->ccb_h.path_id, 0, i + 1); - if (status != CAM_REQ_CMP) - printf("xpt_create_path failed" - " with status %#x\n", - status); - xpt_async(AC_FOUND_DEVICE, newpath, done_ccb); - } } if (softc->action == PROBE_DONE || softc->action == PROBE_INVALID) { cam_periph_invalidate(periph); diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c index 3e829a4e8e9b..5e925811a51c 100644 --- a/sys/cam/nvme/nvme_da.c +++ b/sys/cam/nvme/nvme_da.c @@ -189,7 +189,7 @@ nda_nvme_flush(struct nda_softc *softc, struct ccb_nvmeio *nvmeio) CAM_DIR_NONE, /* flags */ NULL, /* data_ptr */ 0, /* dxfer_len */ - nda_default_timeout * 1000); /* timeout 5s */ + nda_default_timeout * 1000); /* timeout 30s */ nvme_ns_flush_cmd(&nvmeio->cmd, softc->nsid); } @@ -203,7 +203,7 @@ nda_nvme_trim(struct nda_softc *softc, struct ccb_nvmeio *nvmeio, CAM_DIR_OUT, /* flags */ payload, /* data_ptr */ num_ranges * sizeof(struct nvme_dsm_range), /* dxfer_len */ - nda_default_timeout * 1000); /* timeout 5s */ + nda_default_timeout * 1000); /* timeout 30s */ nvme_ns_trim_cmd(&nvmeio->cmd, softc->nsid, num_ranges); } @@ -217,7 +217,7 @@ nda_nvme_write(struct nda_softc *softc, struct ccb_nvmeio *nvmeio, CAM_DIR_OUT, /* flags */ payload, /* data_ptr */ len, /* dxfer_len */ - nda_default_timeout * 1000); /* timeout 5s */ + nda_default_timeout * 1000); /* timeout 30s */ nvme_ns_write_cmd(&nvmeio->cmd, softc->nsid, lba, count); } @@ -246,7 +246,7 @@ nda_nvme_rw_bio(struct nda_softc *softc, struct ccb_nvmeio *nvmeio, flags, /* flags */ payload, /* data_ptr */ bp->bio_bcount, /* dxfer_len */ - nda_default_timeout * 1000); /* timeout 5s */ + nda_default_timeout * 1000); /* timeout 30s */ nvme_ns_rw_cmd(&nvmeio->cmd, rwcmd, softc->nsid, lba, count); } @@ -379,7 +379,7 @@ ndadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len struct cam_periph *periph; struct nda_softc *softc; u_int secsize; - union ccb ccb; + struct ccb_nvmeio nvmeio; struct disk *dp; uint64_t lba; uint32_t count; @@ -398,16 +398,18 @@ ndadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len return (ENXIO); } + /* xpt_get_ccb returns a zero'd allocation for the ccb, mimic that here */ + memset(&nvmeio, 0, sizeof(nvmeio)); if (length > 0) { - xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); - ccb.ccb_h.ccb_state = NDA_CCB_DUMP; - nda_nvme_write(softc, &ccb.nvmeio, virtual, lba, length, count); - xpt_polled_action(&ccb); + xpt_setup_ccb(&nvmeio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + nvmeio.ccb_h.ccb_state = NDA_CCB_DUMP; + nda_nvme_write(softc, &nvmeio, virtual, lba, length, count); + xpt_polled_action((union ccb *)&nvmeio); - error = cam_periph_error(&ccb, + error = cam_periph_error((union ccb *)&nvmeio, 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); - if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) - cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0, + if ((nvmeio.ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(nvmeio.ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); if (error != 0) printf("Aborting dump due to I/O error.\n"); @@ -417,16 +419,16 @@ ndadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t len } /* Flush */ - xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&nvmeio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); - ccb.ccb_h.ccb_state = NDA_CCB_DUMP; - nda_nvme_flush(softc, &ccb.nvmeio); - xpt_polled_action(&ccb); + nvmeio.ccb_h.ccb_state = NDA_CCB_DUMP; + nda_nvme_flush(softc, &nvmeio); + xpt_polled_action((union ccb *)&nvmeio); - error = cam_periph_error(&ccb, + error = cam_periph_error((union ccb *)&nvmeio, 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); - if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) - cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0, + if ((nvmeio.ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(nvmeio.ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); if (error != 0) xpt_print(periph->path, "flush cmd failed\n"); @@ -792,7 +794,7 @@ ndaregister(struct cam_periph *periph, void *arg) /* * Add alias for older nvd drives to ease transition. */ - disk_add_alias(disk, "nvd"); + /* disk_add_alias(disk, "nvd"); Have reports of this causing problems */ /* * Acquire a reference to the periph before we register with GEOM. @@ -920,7 +922,12 @@ ndastart(struct cam_periph *periph, union ccb *start_ccb) nda_nvme_trim(softc, &start_ccb->nvmeio, dsm_range, 1); start_ccb->ccb_h.ccb_state = NDA_CCB_TRIM; start_ccb->ccb_h.flags |= CAM_UNLOCKED; - cam_iosched_submit_trim(softc->cam_iosched); /* XXX */ + /* + * Note: We can have multiple TRIMs in flight, so we don't call + * cam_iosched_submit_trim(softc->cam_iosched); + * since that forces the I/O scheduler to only schedule one at a time. + * On NVMe drives, this is a performance disaster. + */ goto out; } case BIO_FLUSH: @@ -1013,7 +1020,11 @@ ndadone(struct cam_periph *periph, union ccb *done_ccb) TAILQ_INIT(&queue); TAILQ_CONCAT(&queue, &softc->trim_req.bps, bio_queue); #endif - cam_iosched_trim_done(softc->cam_iosched); + /* + * Since we can have multiple trims in flight, we don't + * need to call this here. + * cam_iosched_trim_done(softc->cam_iosched); + */ ndaschedule(periph); cam_periph_unlock(periph); #ifdef notyet diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index c8a3198ef87b..c4803ba5ed46 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -468,10 +468,6 @@ static struct op_table_entry scsi_op_codes[] = { { 0x86, ALL & ~(L | R | F), "ACCESS CONTROL IN" }, /* 87 OO OO OOOOOOO ACCESS CONTROL OUT */ { 0x87, ALL & ~(L | R | F), "ACCESS CONTROL OUT" }, - /* - * XXX READ(16)/WRITE(16) were not listed for CD/DVE in op-num.txt - * but we had it since r1.40. Do we really want them? - */ /* 88 MM O O O READ(16) */ { 0x88, D | T | W | O | B, "READ(16)" }, /* 89 O COMPARE AND WRITE*/ diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index b9a98b5aac25..061ea9d93398 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -1646,6 +1646,7 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng return (ENXIO); } + memset(&csio, 0, sizeof(csio)); if (length > 0) { xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); csio.ccb_h.ccb_state = DA_CCB_DUMP; diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_sunddi.c b/sys/cddl/compat/opensolaris/kern/opensolaris_sunddi.c index 2708884d720f..4a13cd8956c0 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_sunddi.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_sunddi.c @@ -41,10 +41,6 @@ ddi_strtol(const char *str, char **nptr, int base, long *result) { *result = strtol(str, nptr, base); - if (*result == 0) - return (EINVAL); - else if (*result == LONG_MIN || *result == LONG_MAX) - return (ERANGE); return (0); } @@ -58,10 +54,6 @@ ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) } *result = strtoul(str, nptr, base); - if (*result == 0) - return (EINVAL); - else if (*result == ULONG_MAX) - return (ERANGE); return (0); } @@ -70,10 +62,14 @@ ddi_strtoull(const char *str, char **nptr, int base, unsigned long long *result) { *result = (unsigned long long)strtouq(str, nptr, base); - if (*result == 0) - return (EINVAL); - else if (*result == ULLONG_MAX) - return (ERANGE); + return (0); +} + +int +ddi_strtoll(const char *str, char **nptr, int base, long long *result) +{ + + *result = (long long)strtoq(str, nptr, base); return (0); } diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index d33b034a4d61..894675ac91a5 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -209,6 +209,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, vput(vp); vfs_unbusy(mp); vfs_freeopts(mp->mnt_optnew); + mp->mnt_vnodecovered = NULL; vfs_mount_destroy(mp); return (error); } diff --git a/sys/cddl/compat/opensolaris/sys/kcondvar.h b/sys/cddl/compat/opensolaris/sys/kcondvar.h index bae053fa2ad8..209222c89325 100644 --- a/sys/cddl/compat/opensolaris/sys/kcondvar.h +++ b/sys/cddl/compat/opensolaris/sys/kcondvar.h @@ -63,13 +63,8 @@ static clock_t cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res, int flag) { - sbintime_t sbt; - sbintime_t pr; - sbt = tim * SBT_1NS; - pr = res * SBT_1NS; - - return (cv_timedwait_sbt(cvp, mp, sbt, pr, 0)); + return (cv_timedwait_sbt(cvp, mp, nstosbt(tim), nstosbt(res), 0)); } #endif /* _KERNEL */ diff --git a/sys/cddl/compat/opensolaris/sys/mutex.h b/sys/cddl/compat/opensolaris/sys/mutex.h index b1982e7245b0..9875901242e0 100644 --- a/sys/cddl/compat/opensolaris/sys/mutex.h +++ b/sys/cddl/compat/opensolaris/sys/mutex.h @@ -47,9 +47,9 @@ typedef enum { typedef struct sx kmutex_t; #ifndef OPENSOLARIS_WITNESS -#define MUTEX_FLAGS (SX_DUPOK | SX_NOWITNESS) +#define MUTEX_FLAGS (SX_DUPOK | SX_NEW | SX_NOWITNESS) #else -#define MUTEX_FLAGS (SX_DUPOK) +#define MUTEX_FLAGS (SX_DUPOK | SX_NEW) #endif #define mutex_init(lock, desc, type, arg) do { \ @@ -57,7 +57,6 @@ typedef struct sx kmutex_t; ASSERT((type) == 0 || (type) == MUTEX_DEFAULT); \ KASSERT(((lock)->lock_object.lo_flags & LO_ALLMASK) != \ LO_EXPECTED, ("lock %s already initialized", #lock)); \ - bzero((lock), sizeof(struct sx)); \ for (_name = #lock; *_name != '\0'; _name++) { \ if (*_name >= 'a' && *_name <= 'z') \ break; \ diff --git a/sys/cddl/compat/opensolaris/sys/sunddi.h b/sys/cddl/compat/opensolaris/sys/sunddi.h index 3a493b7f00d8..b524ed05dd82 100644 --- a/sys/cddl/compat/opensolaris/sys/sunddi.h +++ b/sys/cddl/compat/opensolaris/sys/sunddi.h @@ -42,6 +42,7 @@ (copyout((from), (to), (size)), 0) int ddi_strtol(const char *str, char **nptr, int base, long *result); int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result); +int ddi_strtoll(const char *str, char **nptr, int base, long long *result); int ddi_strtoull(const char *str, char **nptr, int base, unsigned long long *result); diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h index 6116d5bd877d..64dd9bb9f918 100644 --- a/sys/cddl/compat/opensolaris/sys/time.h +++ b/sys/cddl/compat/opensolaris/sys/time.h @@ -40,6 +40,9 @@ #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) +#define USEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MICROSEC)) +#define NSEC2USEC(n) ((n) / (NANOSEC / MICROSEC)) + #define NSEC2SEC(n) ((n) / (NANOSEC / SEC)) #define SEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / SEC)) diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c index 2a4b18abb2a0..dc70c143e857 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] @@ -397,7 +397,8 @@ zfs_prop_init(void) zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY, ZFS_TYPE_DATASET, "", "WRITTEN"); zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0, - PROP_READONLY, ZFS_TYPE_DATASET, "", "LUSED"); + PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "", + "LUSED"); zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced", 0, PROP_READONLY, ZFS_TYPE_DATASET, "", "LREFER"); @@ -600,6 +601,15 @@ zfs_prop_readonly(zfs_prop_t prop) zfs_prop_table[prop].pd_attr == PROP_ONETIME); } +/* + * Returns TRUE if the property is visible (not hidden). + */ +boolean_t +zfs_prop_visible(zfs_prop_t prop) +{ + return (zfs_prop_table[prop].pd_visible); +} + /* * Returns TRUE if the property is only allowed to be set once. */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/Makefile.files b/sys/cddl/contrib/opensolaris/uts/common/Makefile.files index 66b587b0e908..01675fb3fba9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/Makefile.files +++ b/sys/cddl/contrib/opensolaris/uts/common/Makefile.files @@ -32,6 +32,35 @@ # and its children. These are the source files which may be considered # common to all SunOS systems. +LUA_OBJS += \ + ldo.o \ + lvm.o \ + lbitlib.o \ + lopcodes.o \ + lstring.o \ + ltable.o \ + ltm.o \ + lcorolib.o \ + lauxlib.o \ + ldebug.o \ + lstate.o \ + lgc.o \ + lmem.o \ + lctype.o \ + lfunc.o \ + ldump.o \ + lundump.o \ + lstrlib.o \ + ltablib.o \ + lapi.o \ + lobject.o \ + lbaselib.o \ + lcompat.o \ + lzio.o \ + lcode.o \ + llex.o \ + lparser.o + ZFS_COMMON_OBJS += \ abd.o \ arc.o \ @@ -98,6 +127,11 @@ ZFS_COMMON_OBJS += \ zap.o \ zap_leaf.o \ zap_micro.o \ + zcp.o \ + zcp_get.o \ + zcp_global.o \ + zcp_iter.o \ + zcp_synctask.o \ zfs_byteswap.o \ zfs_debug.o \ zfs_fm.o \ diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index b741ec3a2c2b..12053f5f6bc0 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -339,17 +339,17 @@ static void dtrace_nullop(void) {} -static dtrace_pops_t dtrace_provider_ops = { - (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop, - (void (*)(void *, modctl_t *))dtrace_nullop, - (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, - (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, - (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, - (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, - NULL, - NULL, - NULL, - (void (*)(void *, dtrace_id_t, void *))dtrace_nullop +static dtrace_pops_t dtrace_provider_ops = { + .dtps_provide = (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop, + .dtps_provide_module = (void (*)(void *, modctl_t *))dtrace_nullop, + .dtps_enable = (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, + .dtps_disable = (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, + .dtps_suspend = (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, + .dtps_resume = (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, + .dtps_getargdesc = NULL, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, }; static dtrace_id_t dtrace_probeid_begin; /* special BEGIN probe */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c index b38b311a3311..82353cbb235d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c @@ -1455,29 +1455,29 @@ static const dtrace_pattr_t pid_attr = { }; static dtrace_pops_t pid_pops = { - fasttrap_pid_provide, - NULL, - fasttrap_pid_enable, - fasttrap_pid_disable, - NULL, - NULL, - fasttrap_pid_getargdesc, - fasttrap_pid_getarg, - NULL, - fasttrap_pid_destroy + .dtps_provide = fasttrap_pid_provide, + .dtps_provide_module = NULL, + .dtps_enable = fasttrap_pid_enable, + .dtps_disable = fasttrap_pid_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = fasttrap_pid_getargdesc, + .dtps_getargval = fasttrap_pid_getarg, + .dtps_usermode = NULL, + .dtps_destroy = fasttrap_pid_destroy }; static dtrace_pops_t usdt_pops = { - fasttrap_pid_provide, - NULL, - fasttrap_pid_enable, - fasttrap_pid_disable, - NULL, - NULL, - fasttrap_pid_getargdesc, - fasttrap_usdt_getarg, - NULL, - fasttrap_pid_destroy + .dtps_provide = fasttrap_pid_provide, + .dtps_provide_module = NULL, + .dtps_enable = fasttrap_pid_enable, + .dtps_disable = fasttrap_pid_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = fasttrap_pid_getargdesc, + .dtps_getargval = fasttrap_usdt_getarg, + .dtps_usermode = NULL, + .dtps_destroy = fasttrap_pid_destroy }; static fasttrap_proc_t * @@ -2251,9 +2251,9 @@ fasttrap_meta_remove(void *arg, dtrace_helper_provdesc_t *dhpv, pid_t pid) } static dtrace_mops_t fasttrap_mops = { - fasttrap_meta_create_probe, - fasttrap_meta_provide, - fasttrap_meta_remove + .dtms_create_probe = fasttrap_meta_create_probe, + .dtms_provide_pid = fasttrap_meta_provide, + .dtms_remove_pid = fasttrap_meta_remove }; /*ARGSUSED*/ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/abd.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/abd.c index 94e5a220854c..2cd87c2b87bf 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/abd.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/abd.c @@ -150,6 +150,13 @@ boolean_t zfs_abd_scatter_enabled = B_TRUE; */ size_t zfs_abd_chunk_size = 4096; +#if defined(__FreeBSD__) && defined(_KERNEL) +SYSCTL_DECL(_vfs_zfs); + +SYSCTL_ULONG(_vfs_zfs, OID_AUTO, abd_chunk_size, CTLFLAG_RDTUN, + &zfs_abd_chunk_size, 0, "The size of the chunks ABD allocates"); +#endif + #ifdef _KERNEL extern vmem_t *zio_alloc_arena; #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c index ff93ff445691..d7a7fdb0e1b1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c @@ -117,3 +117,36 @@ decode_embedded_bp_compressed(const blkptr_t *bp, void *buf) buf8[i] = BF64_GET(w, (i % sizeof (w)) * NBBY, NBBY); } } + +/* + * Fill in the buffer with the (decompressed) payload of the embedded + * blkptr_t. Takes into account compression and byteorder (the payload is + * treated as a stream of bytes). + * Return 0 on success, or ENOSPC if it won't fit in the buffer. + */ +int +decode_embedded_bp(const blkptr_t *bp, void *buf, int buflen) +{ + int lsize, psize; + + ASSERT(BP_IS_EMBEDDED(bp)); + + lsize = BPE_GET_LSIZE(bp); + psize = BPE_GET_PSIZE(bp); + + if (lsize > buflen) + return (ENOSPC); + ASSERT3U(lsize, ==, buflen); + + if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF) { + uint8_t dstbuf[BPE_PAYLOAD_SIZE]; + decode_embedded_bp_compressed(bp, dstbuf); + VERIFY0(zio_decompress_data_buf(BP_GET_COMPRESS(bp), + dstbuf, buf, psize, buflen)); + } else { + ASSERT3U(lsize, ==, psize); + decode_embedded_bp_compressed(bp, buf); + } + + return (0); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index a2824c8044da..4c6064fbc4fd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -1728,6 +1728,13 @@ dmu_sync_late_arrival(zio_t *pio, objset_t *os, dmu_sync_cb_t *done, zgd_t *zgd, return (SET_ERROR(EIO)); } + /* + * In order to prevent the zgd's lwb from being free'd prior to + * dmu_sync_late_arrival_done() being called, we have to ensure + * the lwb's "max txg" takes this tx's txg into account. + */ + zil_lwb_add_txg(zgd->zgd_lwb, dmu_tx_get_txg(tx)); + dsa = kmem_alloc(sizeof (dmu_sync_arg_t), KM_SLEEP); dsa->dsa_dr = NULL; dsa->dsa_done = done; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c index 40c94f4d5dd5..3912cf743e48 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c @@ -806,8 +806,8 @@ dmu_tx_delay(dmu_tx_t *tx, uint64_t dirty) continue; mutex_exit(&curthread->t_delay_lock); #else - pause_sbt("dmu_tx_delay", wakeup * SBT_1NS, - zfs_delay_resolution_ns * SBT_1NS, C_ABSOLUTE); + pause_sbt("dmu_tx_delay", nstosbt(wakeup), + nstosbt(zfs_delay_resolution_ns), C_ABSOLUTE); #endif #else hrtime_t delta = wakeup - gethrtime(); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index 6b9ddc8ff581..2d51ed84adea 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (c) 2011 Martin Matuska - * Copyright (c) 2011, 2016 by Delphix. All rights reserved. + * Copyright (c) 2011, 2017 by Delphix. All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2014 RackTop Systems. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. @@ -1134,13 +1134,6 @@ dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx) return (0); } -typedef struct dsl_dataset_snapshot_arg { - nvlist_t *ddsa_snaps; - nvlist_t *ddsa_props; - nvlist_t *ddsa_errors; - cred_t *ddsa_cr; -} dsl_dataset_snapshot_arg_t; - int dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname, dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr) @@ -1200,7 +1193,7 @@ dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname, return (0); } -static int +int dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx) { dsl_dataset_snapshot_arg_t *ddsa = arg; @@ -1477,7 +1470,7 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, ""); } -static void +void dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx) { dsl_dataset_snapshot_arg_t *ddsa = arg; @@ -1682,7 +1675,6 @@ dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname, return (error); } - void dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) { @@ -1750,29 +1742,16 @@ dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx) dmu_buf_rele(ds->ds_dbuf, ds); } -static void -get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) +int +get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val) { uint64_t count = 0; objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; zap_cursor_t zc; zap_attribute_t za; - nvlist_t *propval = fnvlist_alloc(); - nvlist_t *val; ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool)); - /* - * We use nvlist_alloc() instead of fnvlist_alloc() because the - * latter would allocate the list with NV_UNIQUE_NAME flag. - * As a result, every time a clone name is appended to the list - * it would be (linearly) searched for for a duplicate name. - * We already know that all clone names must be unique and we - * want avoid the quadratic complexity of double-checking that - * because we can have a large number of clones. - */ - VERIFY0(nvlist_alloc(&val, 0, KM_SLEEP)); - /* * There may be missing entries in ds_next_clones_obj * due to a bug in a previous version of the code. @@ -1782,8 +1761,9 @@ get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) VERIFY0(zap_count(mos, dsl_dataset_phys(ds)->ds_next_clones_obj, &count)); } - if (count != dsl_dataset_phys(ds)->ds_num_children - 1) - goto fail; + if (count != dsl_dataset_phys(ds)->ds_num_children - 1) { + return (ENOENT); + } for (zap_cursor_init(&zc, mos, dsl_dataset_phys(ds)->ds_next_clones_obj); zap_cursor_retrieve(&zc, &za) == 0; @@ -1797,15 +1777,42 @@ get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) dsl_dataset_rele(clone, FTAG); } zap_cursor_fini(&zc); - fnvlist_add_nvlist(propval, ZPROP_VALUE, val); - fnvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES), propval); -fail: + return (0); +} + +void +get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) +{ + nvlist_t *propval = fnvlist_alloc(); + nvlist_t *val; + + /* + * We use nvlist_alloc() instead of fnvlist_alloc() because the + * latter would allocate the list with NV_UNIQUE_NAME flag. + * As a result, every time a clone name is appended to the list + * it would be (linearly) searched for for a duplicate name. + * We already know that all clone names must be unique and we + * want avoid the quadratic complexity of double-checking that + * because we can have a large number of clones. + */ + VERIFY0(nvlist_alloc(&val, 0, KM_SLEEP)); + + if (get_clones_stat_impl(ds, val) == 0) { + fnvlist_add_nvlist(propval, ZPROP_VALUE, val); + fnvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES), + propval); + } + nvlist_free(val); nvlist_free(propval); } -static void -get_receive_resume_stats(dsl_dataset_t *ds, nvlist_t *nv) +/* + * Returns a string that represents the receive resume stats token. It should + * be freed with strfree(). + */ +char * +get_receive_resume_stats_impl(dsl_dataset_t *ds) { dsl_pool_t *dp = ds->ds_dir->dd_pool; @@ -1873,84 +1880,359 @@ get_receive_resume_stats(dsl_dataset_t *ds, nvlist_t *nv) ZFS_SEND_RESUME_TOKEN_VERSION, (longlong_t)cksum.zc_word[0], (longlong_t)packed_size, str); - dsl_prop_nvlist_add_string(nv, - ZFS_PROP_RECEIVE_RESUME_TOKEN, propval); kmem_free(packed, packed_size); kmem_free(str, compressed_size * 2 + 1); kmem_free(compressed, packed_size); - strfree(propval); + return (propval); } + return (spa_strdup("")); +} + +/* + * Returns a string that represents the receive resume stats token of the + * dataset's child. It should be freed with strfree(). + */ +char * +get_child_receive_stats(dsl_dataset_t *ds) +{ + char recvname[ZFS_MAX_DATASET_NAME_LEN + 6]; + dsl_dataset_t *recv_ds; + dsl_dataset_name(ds, recvname); + if (strlcat(recvname, "/", sizeof (recvname)) < + sizeof (recvname) && + strlcat(recvname, recv_clone_name, sizeof (recvname)) < + sizeof (recvname) && + dsl_dataset_hold(ds->ds_dir->dd_pool, recvname, FTAG, + &recv_ds) == 0) { + char *propval = get_receive_resume_stats_impl(recv_ds); + dsl_dataset_rele(recv_ds, FTAG); + return (propval); + } + return (spa_strdup("")); +} + +static void +get_receive_resume_stats(dsl_dataset_t *ds, nvlist_t *nv) +{ + char *propval = get_receive_resume_stats_impl(ds); + if (strcmp(propval, "") != 0) { + dsl_prop_nvlist_add_string(nv, + ZFS_PROP_RECEIVE_RESUME_TOKEN, propval); + } else { + char *childval = get_child_receive_stats(ds); + if (strcmp(childval, "") != 0) { + dsl_prop_nvlist_add_string(nv, + ZFS_PROP_RECEIVE_RESUME_TOKEN, childval); + } + strfree(childval); + } + strfree(propval); +} + +uint64_t +dsl_get_refratio(dsl_dataset_t *ds) +{ + uint64_t ratio = dsl_dataset_phys(ds)->ds_compressed_bytes == 0 ? 100 : + (dsl_dataset_phys(ds)->ds_uncompressed_bytes * 100 / + dsl_dataset_phys(ds)->ds_compressed_bytes); + return (ratio); +} + +uint64_t +dsl_get_logicalreferenced(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_uncompressed_bytes); +} + +uint64_t +dsl_get_compressratio(dsl_dataset_t *ds) +{ + if (ds->ds_is_snapshot) { + return (dsl_get_refratio(ds)); + } else { + dsl_dir_t *dd = ds->ds_dir; + mutex_enter(&dd->dd_lock); + uint64_t val = dsl_dir_get_compressratio(dd); + mutex_exit(&dd->dd_lock); + return (val); + } +} + +uint64_t +dsl_get_used(dsl_dataset_t *ds) +{ + if (ds->ds_is_snapshot) { + return (dsl_dataset_phys(ds)->ds_unique_bytes); + } else { + dsl_dir_t *dd = ds->ds_dir; + mutex_enter(&dd->dd_lock); + uint64_t val = dsl_dir_get_used(dd); + mutex_exit(&dd->dd_lock); + return (val); + } +} + +uint64_t +dsl_get_creation(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_creation_time); +} + +uint64_t +dsl_get_creationtxg(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_creation_txg); +} + +uint64_t +dsl_get_refquota(dsl_dataset_t *ds) +{ + return (ds->ds_quota); +} + +uint64_t +dsl_get_refreservation(dsl_dataset_t *ds) +{ + return (ds->ds_reserved); +} + +uint64_t +dsl_get_guid(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_guid); +} + +uint64_t +dsl_get_unique(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_unique_bytes); +} + +uint64_t +dsl_get_objsetid(dsl_dataset_t *ds) +{ + return (ds->ds_object); +} + +uint64_t +dsl_get_userrefs(dsl_dataset_t *ds) +{ + return (ds->ds_userrefs); +} + +uint64_t +dsl_get_defer_destroy(dsl_dataset_t *ds) +{ + return (DS_IS_DEFER_DESTROY(ds) ? 1 : 0); +} + +uint64_t +dsl_get_referenced(dsl_dataset_t *ds) +{ + return (dsl_dataset_phys(ds)->ds_referenced_bytes); +} + +uint64_t +dsl_get_numclones(dsl_dataset_t *ds) +{ + ASSERT(ds->ds_is_snapshot); + return (dsl_dataset_phys(ds)->ds_num_children - 1); +} + +uint64_t +dsl_get_inconsistent(dsl_dataset_t *ds) +{ + return ((dsl_dataset_phys(ds)->ds_flags & DS_FLAG_INCONSISTENT) ? + 1 : 0); +} + +uint64_t +dsl_get_available(dsl_dataset_t *ds) +{ + uint64_t refdbytes = dsl_get_referenced(ds); + uint64_t availbytes = dsl_dir_space_available(ds->ds_dir, + NULL, 0, TRUE); + if (ds->ds_reserved > dsl_dataset_phys(ds)->ds_unique_bytes) { + availbytes += + ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes; + } + if (ds->ds_quota != 0) { + /* + * Adjust available bytes according to refquota + */ + if (refdbytes < ds->ds_quota) { + availbytes = MIN(availbytes, + ds->ds_quota - refdbytes); + } else { + availbytes = 0; + } + } + return (availbytes); +} + +int +dsl_get_written(dsl_dataset_t *ds, uint64_t *written) +{ + dsl_pool_t *dp = ds->ds_dir->dd_pool; + dsl_dataset_t *prev; + int err = dsl_dataset_hold_obj(dp, + dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev); + if (err == 0) { + uint64_t comp, uncomp; + err = dsl_dataset_space_written(prev, ds, written, + &comp, &uncomp); + dsl_dataset_rele(prev, FTAG); + } + return (err); +} + +/* + * 'snap' should be a buffer of size ZFS_MAX_DATASET_NAME_LEN. + */ +int +dsl_get_prev_snap(dsl_dataset_t *ds, char *snap) +{ + dsl_pool_t *dp = ds->ds_dir->dd_pool; + if (ds->ds_prev != NULL && ds->ds_prev != dp->dp_origin_snap) { + dsl_dataset_name(ds->ds_prev, snap); + return (0); + } else { + return (ENOENT); + } +} + +/* + * Returns the mountpoint property and source for the given dataset in the value + * and source buffers. The value buffer must be at least as large as MAXPATHLEN + * and the source buffer as least as large a ZFS_MAX_DATASET_NAME_LEN. + * Returns 0 on success and an error on failure. + */ +int +dsl_get_mountpoint(dsl_dataset_t *ds, const char *dsname, char *value, + char *source) +{ + int error; + dsl_pool_t *dp = ds->ds_dir->dd_pool; + + /* Retrieve the mountpoint value stored in the zap opbject */ + error = dsl_prop_get_ds(ds, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1, + ZAP_MAXVALUELEN, value, source); + if (error != 0) { + return (error); + } + + /* Process the dsname and source to find the full mountpoint string */ + if (value[0] == '/') { + char *buf = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP); + char *root = buf; + const char *relpath; + + /* + * If we inherit the mountpoint, even from a dataset + * with a received value, the source will be the path of + * the dataset we inherit from. If source is + * ZPROP_SOURCE_VAL_RECVD, the received value is not + * inherited. + */ + if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) { + relpath = ""; + } else { + ASSERT0(strncmp(dsname, source, strlen(source))); + relpath = dsname + strlen(source); + if (relpath[0] == '/') + relpath++; + } + + spa_altroot(dp->dp_spa, root, ZAP_MAXVALUELEN); + + /* + * Special case an alternate root of '/'. This will + * avoid having multiple leading slashes in the + * mountpoint path. + */ + if (strcmp(root, "/") == 0) + root++; + + /* + * If the mountpoint is '/' then skip over this + * if we are obtaining either an alternate root or + * an inherited mountpoint. + */ + char *mnt = value; + if (value[1] == '\0' && (root[0] != '\0' || + relpath[0] != '\0')) + mnt = value + 1; + + if (relpath[0] == '\0') { + (void) snprintf(value, ZAP_MAXVALUELEN, "%s%s", + root, mnt); + } else { + (void) snprintf(value, ZAP_MAXVALUELEN, "%s%s%s%s", + root, mnt, relpath[0] == '@' ? "" : "/", + relpath); + } + kmem_free(buf, ZAP_MAXVALUELEN); + } else { + /* 'legacy' or 'none' */ + (void) snprintf(value, ZAP_MAXVALUELEN, "%s", value); + } + return (0); } void dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) { dsl_pool_t *dp = ds->ds_dir->dd_pool; - uint64_t refd, avail, uobjs, aobjs, ratio; ASSERT(dsl_pool_config_held(dp)); - ratio = dsl_dataset_phys(ds)->ds_compressed_bytes == 0 ? 100 : - (dsl_dataset_phys(ds)->ds_uncompressed_bytes * 100 / - dsl_dataset_phys(ds)->ds_compressed_bytes); - - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, + dsl_get_refratio(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALREFERENCED, - dsl_dataset_phys(ds)->ds_uncompressed_bytes); + dsl_get_logicalreferenced(ds)); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, + dsl_get_compressratio(ds)); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, + dsl_get_used(ds)); if (ds->ds_is_snapshot) { - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, - dsl_dataset_phys(ds)->ds_unique_bytes); get_clones_stat(ds, nv); } else { - if (ds->ds_prev != NULL && ds->ds_prev != dp->dp_origin_snap) { - char buf[ZFS_MAX_DATASET_NAME_LEN]; - dsl_dataset_name(ds->ds_prev, buf); - dsl_prop_nvlist_add_string(nv, ZFS_PROP_PREV_SNAP, buf); - } - + char buf[ZFS_MAX_DATASET_NAME_LEN]; + if (dsl_get_prev_snap(ds, buf) == 0) + dsl_prop_nvlist_add_string(nv, ZFS_PROP_PREV_SNAP, + buf); dsl_dir_stats(ds->ds_dir, nv); } - dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, refd); - + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, + dsl_get_available(ds)); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, + dsl_get_referenced(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATION, - dsl_dataset_phys(ds)->ds_creation_time); + dsl_get_creation(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATETXG, - dsl_dataset_phys(ds)->ds_creation_txg); + dsl_get_creationtxg(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFQUOTA, - ds->ds_quota); + dsl_get_refquota(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRESERVATION, - ds->ds_reserved); + dsl_get_refreservation(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_GUID, - dsl_dataset_phys(ds)->ds_guid); + dsl_get_guid(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_UNIQUE, - dsl_dataset_phys(ds)->ds_unique_bytes); + dsl_get_unique(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_OBJSETID, - ds->ds_object); + dsl_get_objsetid(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS, - ds->ds_userrefs); + dsl_get_userrefs(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY, - DS_IS_DEFER_DESTROY(ds) ? 1 : 0); + dsl_get_defer_destroy(ds)); if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) { - uint64_t written, comp, uncomp; - dsl_pool_t *dp = ds->ds_dir->dd_pool; - dsl_dataset_t *prev; - - int err = dsl_dataset_hold_obj(dp, - dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev); - if (err == 0) { - err = dsl_dataset_space_written(prev, ds, &written, - &comp, &uncomp); - dsl_dataset_rele(prev, FTAG); - if (err == 0) { - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN, - written); - } + uint64_t written; + if (dsl_get_written(ds, &written) == 0) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN, + written); } } @@ -1987,27 +2269,19 @@ dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat) dsl_pool_t *dp = ds->ds_dir->dd_pool; ASSERT(dsl_pool_config_held(dp)); - stat->dds_creation_txg = dsl_dataset_phys(ds)->ds_creation_txg; - stat->dds_inconsistent = - dsl_dataset_phys(ds)->ds_flags & DS_FLAG_INCONSISTENT; - stat->dds_guid = dsl_dataset_phys(ds)->ds_guid; + stat->dds_creation_txg = dsl_get_creationtxg(ds); + stat->dds_inconsistent = dsl_get_inconsistent(ds); + stat->dds_guid = dsl_get_guid(ds); stat->dds_origin[0] = '\0'; if (ds->ds_is_snapshot) { stat->dds_is_snapshot = B_TRUE; - stat->dds_num_clones = - dsl_dataset_phys(ds)->ds_num_children - 1; + stat->dds_num_clones = dsl_get_numclones(ds); } else { stat->dds_is_snapshot = B_FALSE; stat->dds_num_clones = 0; if (dsl_dir_is_clone(ds->ds_dir)) { - dsl_dataset_t *ods; - - VERIFY0(dsl_dataset_hold_obj(dp, - dsl_dir_phys(ds->ds_dir)->dd_origin_obj, - FTAG, &ods)); - dsl_dataset_name(ods, stat->dds_origin); - dsl_dataset_rele(ods, FTAG); + dsl_dir_get_origin(ds->ds_dir, stat->dds_origin); } } } @@ -2257,14 +2531,7 @@ dsl_dataset_handoff_check(dsl_dataset_t *ds, void *owner, dmu_tx_t *tx) return (0); } -typedef struct dsl_dataset_rollback_arg { - const char *ddra_fsname; - const char *ddra_tosnap; - void *ddra_owner; - nvlist_t *ddra_result; -} dsl_dataset_rollback_arg_t; - -static int +int dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx) { dsl_dataset_rollback_arg_t *ddra = arg; @@ -2372,7 +2639,7 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx) return (0); } -static void +void dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx) { dsl_dataset_rollback_arg_t *ddra = arg; @@ -2434,22 +2701,12 @@ struct promotenode { dsl_dataset_t *ds; }; -typedef struct dsl_dataset_promote_arg { - const char *ddpa_clonename; - dsl_dataset_t *ddpa_clone; - list_t shared_snaps, origin_snaps, clone_snaps; - dsl_dataset_t *origin_origin; /* origin of the origin */ - uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap; - char *err_ds; - cred_t *cr; -} dsl_dataset_promote_arg_t; - static int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep); static int promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp, void *tag); static void promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag); -static int +int dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) { dsl_dataset_promote_arg_t *ddpa = arg; @@ -2461,14 +2718,19 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) uint64_t unused; uint64_t ss_mv_cnt; size_t max_snap_len; + boolean_t conflicting_snaps; err = promote_hold(ddpa, dp, FTAG); if (err != 0) return (err); hds = ddpa->ddpa_clone; + snap = list_head(&ddpa->shared_snaps); + origin_ds = snap->ds; max_snap_len = MAXNAMELEN - strlen(ddpa->ddpa_clonename) - 1; + snap = list_head(&ddpa->origin_snaps); + if (dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE) { promote_rele(ddpa, FTAG); return (SET_ERROR(EXDEV)); @@ -2483,9 +2745,6 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) return (0); } - snap = list_head(&ddpa->shared_snaps); - origin_ds = snap->ds; - /* compute origin's new unique space */ snap = list_tail(&ddpa->clone_snaps); ASSERT3U(dsl_dataset_phys(snap->ds)->ds_prev_snap_obj, ==, @@ -2509,6 +2768,7 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) * Note however, if we stop before we reach the ORIGIN we get: * uN + kN + kN-1 + ... + kM - uM-1 */ + conflicting_snaps = B_FALSE; ss_mv_cnt = 0; ddpa->used = dsl_dataset_phys(origin_ds)->ds_referenced_bytes; ddpa->comp = dsl_dataset_phys(origin_ds)->ds_compressed_bytes; @@ -2537,12 +2797,12 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) } err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val); if (err == 0) { - (void) strcpy(ddpa->err_ds, snap->ds->ds_snapname); - err = SET_ERROR(EEXIST); + fnvlist_add_boolean(ddpa->err_ds, + snap->ds->ds_snapname); + conflicting_snaps = B_TRUE; + } else if (err != ENOENT) { goto out; } - if (err != ENOENT) - goto out; /* The very first snapshot does not have a deadlist */ if (dsl_dataset_phys(ds)->ds_prev_snap_obj == 0) @@ -2555,6 +2815,15 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) ddpa->uncomp += dluncomp; } + /* + * In order to return the full list of conflicting snapshots, we check + * whether there was a conflict after traversing all of them. + */ + if (conflicting_snaps) { + err = SET_ERROR(EEXIST); + goto out; + } + /* * If we are a clone of a clone then we never reached ORIGIN, * so we need to subtract out the clone origin's used space. @@ -2617,7 +2886,7 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) return (err); } -static void +void dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx) { dsl_dataset_promote_arg_t *ddpa = arg; @@ -2965,6 +3234,7 @@ dsl_dataset_promote(const char *name, char *conflsnap) dsl_dataset_promote_arg_t ddpa = { 0 }; uint64_t numsnaps; int error; + nvpair_t *snap_pair; objset_t *os; /* @@ -2982,12 +3252,22 @@ dsl_dataset_promote(const char *name, char *conflsnap) return (error); ddpa.ddpa_clonename = name; - ddpa.err_ds = conflsnap; + ddpa.err_ds = fnvlist_alloc(); ddpa.cr = CRED(); - return (dsl_sync_task(name, dsl_dataset_promote_check, + error = dsl_sync_task(name, dsl_dataset_promote_check, dsl_dataset_promote_sync, &ddpa, - 2 + numsnaps, ZFS_SPACE_CHECK_RESERVED)); + 2 + numsnaps, ZFS_SPACE_CHECK_RESERVED); + + /* + * Return the first conflicting snapshot found. + */ + snap_pair = nvlist_next_nvpair(ddpa.err_ds, NULL); + if (snap_pair != NULL && conflsnap != NULL) + (void) strcpy(conflsnap, nvpair_name(snap_pair)); + + fnvlist_free(ddpa.err_ds); + return (error); } int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c index 09fa5406ec60..d11d8c5f72a6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2013 by Joyent, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -41,13 +42,7 @@ #include #include #include - -typedef struct dmu_snapshots_destroy_arg { - nvlist_t *dsda_snaps; - nvlist_t *dsda_successful_snaps; - boolean_t dsda_defer; - nvlist_t *dsda_errlist; -} dmu_snapshots_destroy_arg_t; +#include int dsl_destroy_snapshot_check_impl(dsl_dataset_t *ds, boolean_t defer) @@ -85,51 +80,33 @@ dsl_destroy_snapshot_check_impl(dsl_dataset_t *ds, boolean_t defer) return (0); } -static int +int dsl_destroy_snapshot_check(void *arg, dmu_tx_t *tx) { - dmu_snapshots_destroy_arg_t *dsda = arg; - dsl_pool_t *dp = dmu_tx_pool(tx); - nvpair_t *pair; - int error = 0; + dsl_destroy_snapshot_arg_t *ddsa = arg; + const char *dsname = ddsa->ddsa_name; + boolean_t defer = ddsa->ddsa_defer; - if (!dmu_tx_is_syncing(tx)) + dsl_pool_t *dp = dmu_tx_pool(tx); + int error = 0; + dsl_dataset_t *ds; + + error = dsl_dataset_hold(dp, dsname, FTAG, &ds); + + /* + * If the snapshot does not exist, silently ignore it, and + * dsl_destroy_snapshot_sync() will be a no-op + * (it's "already destroyed"). + */ + if (error == ENOENT) return (0); - for (pair = nvlist_next_nvpair(dsda->dsda_snaps, NULL); - pair != NULL; pair = nvlist_next_nvpair(dsda->dsda_snaps, pair)) { - dsl_dataset_t *ds; - - error = dsl_dataset_hold(dp, nvpair_name(pair), - FTAG, &ds); - - /* - * If the snapshot does not exist, silently ignore it - * (it's "already destroyed"). - */ - if (error == ENOENT) - continue; - - if (error == 0) { - error = dsl_destroy_snapshot_check_impl(ds, - dsda->dsda_defer); - dsl_dataset_rele(ds, FTAG); - } - - if (error == 0) { - fnvlist_add_boolean(dsda->dsda_successful_snaps, - nvpair_name(pair)); - } else { - fnvlist_add_int32(dsda->dsda_errlist, - nvpair_name(pair), error); - } + if (error == 0) { + error = dsl_destroy_snapshot_check_impl(ds, defer); + dsl_dataset_rele(ds, FTAG); } - pair = nvlist_next_nvpair(dsda->dsda_errlist, NULL); - if (pair != NULL) - return (fnvpair_value_int32(pair)); - - return (0); + return (error); } struct process_old_arg { @@ -473,23 +450,22 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx) dmu_object_free_zapified(mos, obj, tx); } -static void +void dsl_destroy_snapshot_sync(void *arg, dmu_tx_t *tx) { - dmu_snapshots_destroy_arg_t *dsda = arg; + dsl_destroy_snapshot_arg_t *ddsa = arg; + const char *dsname = ddsa->ddsa_name; + boolean_t defer = ddsa->ddsa_defer; + dsl_pool_t *dp = dmu_tx_pool(tx); - nvpair_t *pair; + dsl_dataset_t *ds; - for (pair = nvlist_next_nvpair(dsda->dsda_successful_snaps, NULL); - pair != NULL; - pair = nvlist_next_nvpair(dsda->dsda_successful_snaps, pair)) { - dsl_dataset_t *ds; - - VERIFY0(dsl_dataset_hold(dp, nvpair_name(pair), FTAG, &ds)); - - dsl_destroy_snapshot_sync_impl(ds, dsda->dsda_defer, tx); - dsl_dataset_rele(ds, FTAG); - } + int error = dsl_dataset_hold(dp, dsname, FTAG, &ds); + if (error == ENOENT) + return; + ASSERT0(error); + dsl_destroy_snapshot_sync_impl(ds, defer, tx); + dsl_dataset_rele(ds, FTAG); } /* @@ -509,25 +485,92 @@ int dsl_destroy_snapshots_nvl(nvlist_t *snaps, boolean_t defer, nvlist_t *errlist) { - dmu_snapshots_destroy_arg_t dsda; - int error; - nvpair_t *pair; - - pair = nvlist_next_nvpair(snaps, NULL); - if (pair == NULL) + if (nvlist_next_nvpair(snaps, NULL) == NULL) return (0); - dsda.dsda_snaps = snaps; - dsda.dsda_successful_snaps = fnvlist_alloc(); - dsda.dsda_defer = defer; - dsda.dsda_errlist = errlist; + /* + * lzc_destroy_snaps() is documented to take an nvlist whose + * values "don't matter". We need to convert that nvlist to + * one that we know can be converted to LUA. We also don't + * care about any duplicate entries because the nvlist will + * be converted to a LUA table which should take care of this. + */ + nvlist_t *snaps_normalized; + VERIFY0(nvlist_alloc(&snaps_normalized, 0, KM_SLEEP)); + for (nvpair_t *pair = nvlist_next_nvpair(snaps, NULL); + pair != NULL; pair = nvlist_next_nvpair(snaps, pair)) { + fnvlist_add_boolean_value(snaps_normalized, + nvpair_name(pair), B_TRUE); + } - error = dsl_sync_task(nvpair_name(pair), - dsl_destroy_snapshot_check, dsl_destroy_snapshot_sync, - &dsda, 0, ZFS_SPACE_CHECK_NONE); - fnvlist_free(dsda.dsda_successful_snaps); + nvlist_t *arg; + VERIFY0(nvlist_alloc(&arg, 0, KM_SLEEP)); + fnvlist_add_nvlist(arg, "snaps", snaps_normalized); + fnvlist_free(snaps_normalized); + fnvlist_add_boolean_value(arg, "defer", defer); - return (error); + nvlist_t *wrapper; + VERIFY0(nvlist_alloc(&wrapper, 0, KM_SLEEP)); + fnvlist_add_nvlist(wrapper, ZCP_ARG_ARGLIST, arg); + fnvlist_free(arg); + + const char *program = + "arg = ...\n" + "snaps = arg['snaps']\n" + "defer = arg['defer']\n" + "errors = { }\n" + "has_errors = false\n" + "for snap, v in pairs(snaps) do\n" + " errno = zfs.check.destroy{snap, defer=defer}\n" + " zfs.debug('snap: ' .. snap .. ' errno: ' .. errno)\n" + " if errno == ENOENT then\n" + " snaps[snap] = nil\n" + " elseif errno ~= 0 then\n" + " errors[snap] = errno\n" + " has_errors = true\n" + " end\n" + "end\n" + "if has_errors then\n" + " return errors\n" + "end\n" + "for snap, v in pairs(snaps) do\n" + " errno = zfs.sync.destroy{snap, defer=defer}\n" + " assert(errno == 0)\n" + "end\n" + "return { }\n"; + + nvlist_t *result = fnvlist_alloc(); + int error = zcp_eval(nvpair_name(nvlist_next_nvpair(snaps, NULL)), + program, + 0, + zfs_lua_max_memlimit, + nvlist_next_nvpair(wrapper, NULL), result); + if (error != 0) { + char *errorstr = NULL; + (void) nvlist_lookup_string(result, ZCP_RET_ERROR, &errorstr); + if (errorstr != NULL) { + zfs_dbgmsg(errorstr); + } + return (error); + } + fnvlist_free(wrapper); + + /* + * lzc_destroy_snaps() is documented to fill the errlist with + * int32 values, so we need to covert the int64 values that are + * returned from LUA. + */ + int rv = 0; + nvlist_t *errlist_raw = fnvlist_lookup_nvlist(result, ZCP_RET_RETURN); + for (nvpair_t *pair = nvlist_next_nvpair(errlist_raw, NULL); + pair != NULL; pair = nvlist_next_nvpair(errlist_raw, pair)) { + int32_t val = (int32_t)fnvpair_value_int64(pair); + if (rv == 0) + rv = val; + fnvlist_add_int32(errlist, nvpair_name(pair), val); + } + fnvlist_free(result); + return (rv); } int @@ -598,10 +641,6 @@ old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx) dsl_dataset_phys(ds)->ds_unique_bytes == 0); } -typedef struct dsl_destroy_head_arg { - const char *ddha_name; -} dsl_destroy_head_arg_t; - int dsl_destroy_head_check_impl(dsl_dataset_t *ds, int expected_holds) { @@ -647,7 +686,7 @@ dsl_destroy_head_check_impl(dsl_dataset_t *ds, int expected_holds) return (0); } -static int +int dsl_destroy_head_check(void *arg, dmu_tx_t *tx) { dsl_destroy_head_arg_t *ddha = arg; @@ -880,7 +919,7 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx) } } -static void +void dsl_destroy_head_sync(void *arg, dmu_tx_t *tx) { dsl_destroy_head_arg_t *ddha = arg; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c index 21cfc989e37b..6142de70ade5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c @@ -934,61 +934,139 @@ dsl_dir_is_clone(dsl_dir_t *dd) dd->dd_pool->dp_origin_snap->ds_object)); } + +uint64_t +dsl_dir_get_used(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_used_bytes); +} + +uint64_t +dsl_dir_get_quota(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_quota); +} + +uint64_t +dsl_dir_get_reservation(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_reserved); +} + +uint64_t +dsl_dir_get_compressratio(dsl_dir_t *dd) +{ + /* a fixed point number, 100x the ratio */ + return (dsl_dir_phys(dd)->dd_compressed_bytes == 0 ? 100 : + (dsl_dir_phys(dd)->dd_uncompressed_bytes * 100 / + dsl_dir_phys(dd)->dd_compressed_bytes)); +} + +uint64_t +dsl_dir_get_logicalused(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_uncompressed_bytes); +} + +uint64_t +dsl_dir_get_usedsnap(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_SNAP]); +} + +uint64_t +dsl_dir_get_usedds(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_HEAD]); +} + +uint64_t +dsl_dir_get_usedrefreserv(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_REFRSRV]); +} + +uint64_t +dsl_dir_get_usedchild(dsl_dir_t *dd) +{ + return (dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD] + + dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD_RSRV]); +} + +void +dsl_dir_get_origin(dsl_dir_t *dd, char *buf) +{ + dsl_dataset_t *ds; + VERIFY0(dsl_dataset_hold_obj(dd->dd_pool, + dsl_dir_phys(dd)->dd_origin_obj, FTAG, &ds)); + + dsl_dataset_name(ds, buf); + + dsl_dataset_rele(ds, FTAG); +} + +int +dsl_dir_get_filesystem_count(dsl_dir_t *dd, uint64_t *count) +{ + if (dsl_dir_is_zapified(dd)) { + objset_t *os = dd->dd_pool->dp_meta_objset; + return (zap_lookup(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT, + sizeof (*count), 1, count)); + } else { + return (ENOENT); + } +} + +int +dsl_dir_get_snapshot_count(dsl_dir_t *dd, uint64_t *count) +{ + if (dsl_dir_is_zapified(dd)) { + objset_t *os = dd->dd_pool->dp_meta_objset; + return (zap_lookup(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT, + sizeof (*count), 1, count)); + } else { + return (ENOENT); + } +} + void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv) { mutex_enter(&dd->dd_lock); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, - dsl_dir_phys(dd)->dd_used_bytes); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA, - dsl_dir_phys(dd)->dd_quota); + dsl_dir_get_quota(dd)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION, - dsl_dir_phys(dd)->dd_reserved); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, - dsl_dir_phys(dd)->dd_compressed_bytes == 0 ? 100 : - (dsl_dir_phys(dd)->dd_uncompressed_bytes * 100 / - dsl_dir_phys(dd)->dd_compressed_bytes)); + dsl_dir_get_reservation(dd)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALUSED, - dsl_dir_phys(dd)->dd_uncompressed_bytes); + dsl_dir_get_logicalused(dd)); if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) { dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP, - dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_SNAP]); + dsl_dir_get_usedsnap(dd)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDDS, - dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_HEAD]); + dsl_dir_get_usedds(dd)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDREFRESERV, - dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_REFRSRV]); + dsl_dir_get_usedrefreserv(dd)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDCHILD, - dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD] + - dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD_RSRV]); + dsl_dir_get_usedchild(dd)); } mutex_exit(&dd->dd_lock); - if (dsl_dir_is_zapified(dd)) { - uint64_t count; - objset_t *os = dd->dd_pool->dp_meta_objset; - - if (zap_lookup(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT, - sizeof (count), 1, &count) == 0) { - dsl_prop_nvlist_add_uint64(nv, - ZFS_PROP_FILESYSTEM_COUNT, count); - } - if (zap_lookup(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT, - sizeof (count), 1, &count) == 0) { - dsl_prop_nvlist_add_uint64(nv, - ZFS_PROP_SNAPSHOT_COUNT, count); - } + uint64_t count; + if (dsl_dir_get_filesystem_count(dd, &count) == 0) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_FILESYSTEM_COUNT, + count); + } + if (dsl_dir_get_snapshot_count(dd, &count) == 0) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_SNAPSHOT_COUNT, + count); } if (dsl_dir_is_clone(dd)) { - dsl_dataset_t *ds; char buf[ZFS_MAX_DATASET_NAME_LEN]; - - VERIFY0(dsl_dataset_hold_obj(dd->dd_pool, - dsl_dir_phys(dd)->dd_origin_obj, FTAG, &ds)); - dsl_dataset_name(ds, buf); - dsl_dataset_rele(ds, FTAG); + dsl_dir_get_origin(dd, buf); dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf); } + } void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/README.zfs b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/README.zfs new file mode 100644 index 000000000000..0e22de7a4a18 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/README.zfs @@ -0,0 +1,80 @@ +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# + +# +# Copyright (c) 2017 by Delphix. All rights reserved. +# + +Introduction +------------ + +This README describes the Lua interpreter source code that lives in the ZFS +source tree to enable execution of ZFS channel programs, including its +maintenance policy, the modifications that have been made to it, and how it +should (and should not) be used. + +For a description of the Lua language and features exposed by ZFS channel +programs, please refer to the zfs-program(1m) man page instead. + + +Maintenance policy +------------------ + +The Lua runtime is considered stable software. Channel programs don't need much +complicated logic, so updates to the Lua runtime from upstream are viewed as +nice-to-have, but not required for channel programs to be well-supported. As +such, the Lua runtime in ZFS should be updated on an as-needed basis for +security vulnerabilities, but not much else. + + +Modifications to Lua +-------------------- + +The version of the Lua runtime we're using in ZFS has been modified in a variety +of ways to make it more useful for the specific purpose of running channel +programs. These changes include: + +1. "Normal" Lua uses floating point for all numbers it stores, but those aren't + useful inside ZFS / the kernel. We have changed the runtime to use int64_t + throughout for all numbers. +2. Some of the Lua standard libraries do file I/O or spawn processes, but + neither of these make sense from inside channel programs. We have removed + those libraries rather than reimplementing them using kernel APIs. +3. The "normal" Lua runtime handles errors by failing fatally, but since this + version of Lua runs inside the kernel we must handle these failures and + return meaningful error codes to userland. We have customized the Lua + failure paths so that they aren't fatal. +4. Running poorly-vetted code inside the kernel is always a risk; even if the + ability to do so is restricted to the root user, it's still possible to write + an incorrect program that results in an infinite loop or massive memory use. + We've added new protections into the Lua interpreter to limit the runtime + (measured in number of Lua instructions run) and memory overhead of running + a channel program. +5. The Lua bytecode is not designed to be secure / safe, so it would be easy to + pass invalid bytecode which can panic the kernel. By comparison, the parser + is hardened and fails gracefully on invalid input. Therefore, we only accept + Lua source code at the ioctl level and then interpret it inside the kernel. + +Each of these modifications have been tested in the zfs-test suite. If / when +new modifications are made, new tests should be added to the suite located in +zfs-tests/tests/functional/channel_program/lua_core. + + +How to use this Lua interpreter +------------------------------- + +From the above, it should be clear that this is not a general-purpose Lua +interpreter. Additional work would be required to extricate this custom version +of Lua from ZFS and make it usable by other areas of the kernel. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.c new file mode 100644 index 000000000000..34820a2d8b44 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.c @@ -0,0 +1,1283 @@ +/* +** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; + + +/* value at a non-valid index */ +#define NONVALIDVALUE cast(TValue *, luaO_nilobject) + +/* corresponding test */ +#define isvalid(o) ((o) != luaO_nilobject) + +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +/* test for valid but not pseudo index */ +#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) + +#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") + +#define api_checkstackindex(L, i, o) \ + api_check(L, isstackindex(i, o), "index not in the stack") + + +static TValue *index2addr (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + TValue *o = ci->func + idx; + api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); + if (o >= L->top) return NONVALIDVALUE; + else return o; + } + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); + return L->top + idx; + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttislcf(ci->func)) /* light C function? */ + return NONVALIDVALUE; /* it has no upvalues */ + else { + CClosure *func = clCvalue(ci->func); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; + } + } +} + + +/* +** to be called by 'lua_checkstack' in protected mode, to grow stack +** capturing memory errors +*/ +static void growstack (lua_State *L, void *ud) { + int size = *(int *)ud; + luaD_growstack(L, size); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res; + CallInfo *ci = L->ci; + lua_lock(L); + if (L->stack_last - L->top > size) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else { /* no; need to grow stack */ + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; + if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ + res = 0; /* no */ + else /* try to grow stack */ + res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); + } + if (res && ci->top < L->top + size) + ci->top = L->top + size; /* adjust frame top */ + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API const lua_Number *lua_version (lua_State *L) { + static const lua_Number version = LUA_VERSION_NUM; + if (L == NULL) return &version; + else return G(L)->version; +} + + + +/* +** basic stack manipulation +*/ + + +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top - L->ci->func + idx); +} + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - (L->ci->func + 1)); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + StkId func = L->ci->func; + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); + while (L->top < (func + 1) + idx) + setnilvalue(L->top++); + L->top = (func + 1) + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + for (q = L->top; q > p; q--) /* use L->top as a temporary */ + setobjs2s(L, q, q - 1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +static void moveto (lua_State *L, TValue *fr, int idx) { + TValue *to = index2addr(L, idx); + api_checkvalidindex(L, to); + setobj(L, to, fr); + if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ + luaC_barrier(L, clCvalue(L->ci->func), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + lua_lock(L); + api_checknelems(L, 1); + moveto(L, L->top - 1, idx); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr; + lua_lock(L); + fr = index2addr(L, fromidx); + moveto(L, fr, toidx); + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2addr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (isvalid(o) ? ttypenv(o) : LUA_TNONE); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return ttypename(t); +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2addr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; +} + + +LUA_API void lua_arith (lua_State *L, int op) { + StkId o1; /* 1st operand */ + StkId o2; /* 2nd operand */ + lua_lock(L); + if (op != LUA_OPUNM) /* all other operations expect two operands */ + api_checknelems(L, 2); + else { /* for unary minus, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top, L->top - 1); + L->top++; + } + o1 = L->top - 2; + o2 = L->top - 1; + if (ttisnumber(o1) && ttisnumber(o2)) { + setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); + } + else + luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + StkId o1, o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + if (isvalid(o1) && isvalid(o2)) { + switch (op) { + case LUA_OPEQ: i = equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + if (isnum) *isnum = 1; + return nvalue(o); + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Unsigned res; + lua_Number num = nvalue(o); + lua_number2unsigned(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2addr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2addr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_rawlen (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TLCL: return clLvalue(o); + case LUA_TCCL: return clCvalue(o); + case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + luai_checknum(L, L->top, + luaG_runerror(L, "C API - attempt to push a signaling NaN")); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { + lua_Number n; + lua_lock(L); + n = lua_unsigned2number(u); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_newlstr(L, s, len); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) { + lua_pushnil(L); + return NULL; + } + else { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_new(L, s); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); + } +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + lua_lock(L); + if (n == 0) { + setfvalue(L->top, fn); + } + else { + Closure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + luaC_checkGC(L); + cl = luaF_newCclosure(L, n); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top + n); + setclCvalue(L, L->top, cl); + } + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_getglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_gettable(L, gt, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + setsvalue2s(L, L->top, luaS_new(L, k)); + api_incr_top(L); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top, luaH_getint(hvalue(t), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2s(L, L->top, luaH_get(hvalue(t), &k)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; + lua_lock(L); + luaC_checkGC(L); + t = luaH_new(L); + sethvalue(L, L->top, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2addr(L, objindex); + switch (ttypenv(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (uvalue(o)->env) { + sethvalue(L, L->top, uvalue(o)->env); + } else + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_setglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + api_checknelems(L, 1); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_settable(L, gt, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + setsvalue2s(L, L->top++, luaS_new(L, k)); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + invalidateTMcache(hvalue(t)); + luaC_barrierback(L, gcvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + luaH_setint(L, hvalue(t), n, L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top - 1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2addr(L, objindex); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + mt = hvalue(L->top - 1); + } + switch (ttypenv(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrierback(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, rawuvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: { + G(L)->mt[ttypenv(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API void lua_setuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (ttisnil(L->top - 1)) + uvalue(o)->env = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + uvalue(o)->env = hvalue(L->top - 1); + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + } + L->top--; + lua_unlock(L); +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ + "results from function overflow current stack size") + + +LUA_API int lua_getctx (lua_State *L, int *ctx) { + if (L->ci->callstatus & CIST_YIELDED) { + if (ctx) *ctx = L->ci->u.c.ctx; + return L->ci->u.c.status; + } + else return LUA_OK; +} + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k) { + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults, 1); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_call(L, func, nresults, 0); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults, 0); +} + + + +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2addr(L, errfunc); + api_checkstackindex(L, errfunc, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->extra = savestack(L, c.func); + ci->u.c.old_allowhook = L->allowhook; + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + /* mark that function may do error recovery */ + ci->callstatus |= CIST_YPCALL; + luaD_call(L, c.func, nresults, 1); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ + if (f->nupvalues == 1) { /* does it have one upvalue? */ + /* get global table from registry */ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->gcrunning = 0; + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); + g->gcrunning = 1; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: { + if (g->gckind == KGC_GEN) { /* generational mode? */ + res = (g->GCestimate == 0); /* true if it will do major collection */ + luaC_forcestep(L); /* do a single step */ + } + else { + lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; + if (g->gcrunning) + debt += g->GCdebt; /* include current debt */ + luaE_setdebt(g, debt); + luaC_forcestep(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETMAJORINC: { + res = g->gcmajorinc; + g->gcmajorinc = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + case LUA_GCISRUNNING: { + res = g->gcrunning; + break; + } + case LUA_GCGEN: { /* change collector to generational mode */ + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: { /* change collector to incremental mode */ + luaC_changemode(L, KGC_NORMAL); + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API void lua_len (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_objlen(L, L->top, t); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, NULL); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val, + GCObject **owner) { + switch (ttype(fi)) { + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(1 <= n && n <= f->nupvalues)) return NULL; + *val = &f->upvalue[n-1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_TLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->upvals[n-1]->v; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n-1].name; + return (name == NULL) ? "" : getstr(name); + } + default: return NULL; /* not a closure */ + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ + StkId fi; + lua_lock(L); + fi = index2addr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, owner, L->top); + } + lua_unlock(L); + return name; +} + + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + LClosure *f; + StkId fi = index2addr(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); + if (pf) *pf = f; + return &f->upvals[n - 1]; /* get its upvalue pointer */ +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + StkId fi = index2addr(L, fidx); + switch (ttype(fi)) { + case LUA_TLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); + return &f->upvalue[n - 1]; + } + default: { + api_check(L, 0, "closure expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + *up1 = *up2; + luaC_objbarrier(L, f1, *up2); +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.h new file mode 100644 index 000000000000..c7d34ad84866 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.h @@ -0,0 +1,24 @@ +/* +** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + +#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ + "stack overflow");} + +#define adjustresults(L,nres) \ + { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + +#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.c new file mode 100644 index 000000000000..4bd13788b459 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.c @@ -0,0 +1,791 @@ +/* +** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +/* +** {====================================================== +** Traceback +** ======================================================= +*/ + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + + + +/* +** search for 'objidx' in table at index -1. +** return 1 + string at top if find a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_pushglobaltable(L); + if (findfield(L, top + 1, 2)) { + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (*ar->namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, "function " LUA_QS, ar->name); + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what == 'C') { + if (pushglobalfuncname(L, ar)) { + lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else + lua_pushliteral(L, "?"); + } + else + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); +} + + +static int countlevels (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + lua_Debug ar; + int top = lua_gettop(L); + int numlevels = countlevels(L1); + int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; + if (msg) lua_pushfstring(L, "%s\n", msg); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level == mark) { /* too many levels? */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ + level = numlevels - LEVELS2; /* and skip to last ones */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + lua_pushfstring(L, "\n\t%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + lua_pushliteral(L, " in "); + pushfuncname(L, &ar); + if (ar.istailcall) + lua_pushliteral(L, "\n\t(...tail calls...)"); + lua_concat(L, lua_gettop(L) - top); + } + } + lua_concat(L, lua_gettop(L) - top); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +static int typeerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + typeerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + + +#if !defined(inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +/* }====================================================== */ + + +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); /* try to get metatable */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + if (p == NULL) typeerror(L, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + /* keep some extra space to run error routines, if needed */ + const int extra = LUA_MINSTACK; + if (!lua_checkstack(L, space + extra)) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + int isnum; + lua_Number d = lua_tonumberx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + int isnum; + lua_Integer d = lua_tointegerx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { + int isnum; + lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, + lua_Unsigned def) { + return luaL_opt(L, luaL_checkunsigned, narg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->initb) + + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + lua_State *L = B->L; + if (B->size - B->n < sz) { /* not enough space? */ + char *newbuff; + size_t newsize = B->size * 2; /* double buffer size */ + if (newsize - B->n < sz) /* not big enough? */ + newsize = B->n + sz; + if (newsize < B->n || newsize - B->n < sz) + luaL_error(L, "buffer too large"); + /* create larger buffer */ + newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); + /* move content to new buffer */ + memcpy(newbuff, B->b, B->n * sizeof(char)); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ + B->b = newbuff; + B->size = newsize; + } + return &B->b[B->n]; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t l; + const char *s = lua_tolstring(L, -1, &l); + if (buffonstack(B)) + lua_insert(L, -2); /* put value below buffer */ + luaL_addlstring(B, s, l); + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->initb; + B->n = 0; + B->size = LUAL_BUFFERSIZE; +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, sz); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header */ +#define freelist 0 + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = lua_absindex(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API int luaL_len (lua_State *L, int idx) { + int l; + int isnum; + lua_len(L, idx); + l = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) + luaL_error(L, "object length is not a number"); + lua_pop(L, 1); /* remove object */ + return l; +} + + +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ + switch (lua_type(L, idx)) { + case LUA_TNUMBER: + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), + lua_topointer(L, idx)); + break; + } + } + return lua_tolstring(L, -1, len); +} + + +/* +** {====================================================== +** Compatibility with 5.1 module functions +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +static const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + if (idx) lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + +/* +** Count number of elements in a luaL_Reg list. +*/ +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l && l->name; l++) size++; + return size; +} + + +/* +** Find or create a module table with a given name. The function +** first looks at the _LOADED table and, if that fails, try a +** global variable with that name. In any case, leaves on the stack +** the module table. +*/ +LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, + int sizehint) { + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ + lua_getfield(L, -1, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + lua_pushglobaltable(L); + if (luaL_findtable(L, 0, modname, sizehint) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ +} + + +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + luaL_checkversion(L); + if (libname) { + luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* remove upvalues */ +} + +#endif +/* }====================================================== */ + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkversion(L); + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + lua_getfield(L, idx, fname); + if (lua_istable(L, -1)) return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** stripped-down 'require'. Calls 'openf' to open a module, +** registers the result in 'package.loaded' table and, if 'glb' +** is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* open module */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); /* make copy of module (call result) */ + lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L, 1); /* remove _LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of 'mod' */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { + const lua_Number *v = lua_version(L); + if (v != lua_version(NULL)) + luaL_error(L, "multiple Lua VMs detected"); + else if (*v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + ver, *v); + /* check conversions number -> integer types */ + lua_pushnumber(L, -(lua_Number)0x1234); + if (lua_tointeger(L, -1) != -0x1234 || + lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) + luaL_error(L, "bad conversion number->int;" + " must recompile Lua with proper settings"); + lua_pop(L, 1); +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.h new file mode 100644 index 000000000000..f6fdac14f50b --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.h @@ -0,0 +1,176 @@ +/* +** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include + +#include "lua.h" + + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); +#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); +LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); +LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, + lua_Unsigned def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API int (luaL_len) (lua_State *L, int idx); + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +typedef struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ +} luaL_Buffer; + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + +/* compatibility with old module system */ +#if defined(LUA_COMPAT_MODULE) + +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); + +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) + +#endif + + +#endif + + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbaselib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbaselib.c new file mode 100644 index 000000000000..b580cee1f955 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbaselib.c @@ -0,0 +1,296 @@ +/* +** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + +/* The following built-in lua functions have been removed and are not available + * for use in ZFS channel programs: + * + * dofile + * loadfile + * load + * pcall + * print + * xpcall + */ + +#include +#include +#ifdef illumos +#define toupper(C) (((C) >= 'a' && (C) <= 'z')? (C) - 'a' + 'A': (C)) +#else +#define isalnum(C) (isalpha(C) || isdigit(C)) +#endif + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + +#define SPACECHARS " \f\n\r\t\v" + +static int luaB_tonumber (lua_State *L) { + if (lua_isnoneornil(L, 2)) { /* standard conversion */ + int isnum; + lua_Number n = lua_tonumberx(L, 1, &isnum); + if (isnum) { + lua_pushnumber(L, n); + return 1; + } /* else not a number; must be something */ + luaL_checkany(L, 1); + } + else { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *e = s + l; /* end point for 's' */ + int base = luaL_checkint(L, 2); + int neg = 0; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle signal */ + else if (*s == '+') s++; + if (isalnum((unsigned char)*s)) { + lua_Number n = 0; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : toupper((unsigned char)*s) - 'A' + 10; + if (digit >= base) break; /* invalid numeral; force a fail */ + n = n * (lua_Number)base + (lua_Number)digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + if (s == e) { /* no invalid trailing characters? */ + lua_pushnumber(L, (neg) ? -n : n); + return 1; + } /* else not a number */ + } /* else not a number */ + } + lua_pushnil(L); /* not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string expected"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "setmajorinc", "isrunning", "generational", "incremental", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, o, ex); + switch (o) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + lua_pushinteger(L, b); + return 2; + } + case LUA_GCSTEP: case LUA_GCISRUNNING: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushinteger(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int pairsmeta (lua_State *L, const char *method, int iszero, + lua_CFunction iter) { + if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ + luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) lua_pushinteger(L, 0); /* and initial value */ + else lua_pushnil(L); + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ + } + return 3; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + return pairsmeta(L, "__pairs", 0, luaB_next); +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 1 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + return pairsmeta(L, "__ipairs", 1, ipairsaux); +} + + +static int luaB_assert (lua_State *L) { + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, +#if defined(LUA_COMPAT_LOADSTRING) + {"loadstring", luaB_load}, +#endif + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_base (lua_State *L) { + /* set global _G */ + lua_pushglobaltable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "_G"); + /* open lib into global table */ + luaL_setfuncs(L, base_funcs, 0); + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ + return 1; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbitlib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbitlib.c new file mode 100644 index 000000000000..31c7b66f1290 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbitlib.c @@ -0,0 +1,212 @@ +/* +** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $ +** Standard library for bitwise operations +** See Copyright Notice in lua.h +*/ + +#define lbitlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* number of bits to consider in a number */ +#if !defined(LUA_NBITS) +#define LUA_NBITS 32 +#endif + + +#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) + +/* macro to trim extra bits */ +#define trim(x) ((x) & ALLONES) + + +/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ +#define mask(n) (~((ALLONES << 1) << ((n) - 1))) + + +typedef lua_Unsigned b_uint; + + + +static b_uint andaux (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = ~(b_uint)0; + for (i = 1; i <= n; i++) + r &= luaL_checkunsigned(L, i); + return trim(r); +} + + +static int b_and (lua_State *L) { + b_uint r = andaux(L); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_test (lua_State *L) { + b_uint r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; +} + + +static int b_or (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r |= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_xor (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r ^= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_not (lua_State *L) { + b_uint r = ~luaL_checkunsigned(L, 1); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_shift (lua_State *L, b_uint r, int i) { + if (i < 0) { /* shift right? */ + i = -i; + r = trim(r); + if (i >= LUA_NBITS) r = 0; + else r >>= i; + } + else { /* shift left */ + if (i >= LUA_NBITS) r = 0; + else r <<= i; + r = trim(r); + } + lua_pushunsigned(L, r); + return 1; +} + + +static int b_lshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); +} + + +static int b_rshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); +} + + +static int b_arshift (lua_State *L) { + b_uint r = luaL_checkunsigned(L, 1); + int i = luaL_checkint(L, 2); + if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) + return b_shift(L, r, -i); + else { /* arithmetic shift for 'negative' number */ + if (i >= LUA_NBITS) r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ + lua_pushunsigned(L, r); + return 1; + } +} + + +static int b_rot (lua_State *L, int i) { + b_uint r = luaL_checkunsigned(L, 1); + i &= (LUA_NBITS - 1); /* i = i % NBITS */ + r = trim(r); + if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ + r = (r << i) | (r >> (LUA_NBITS - i)); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_lrot (lua_State *L) { + return b_rot(L, luaL_checkint(L, 2)); +} + + +static int b_rrot (lua_State *L) { + return b_rot(L, -luaL_checkint(L, 2)); +} + + +/* +** get field and width arguments for field-manipulation functions, +** checking whether they are valid. +** ('luaL_error' called without 'return' to avoid later warnings about +** 'width' being used uninitialized.) +*/ +static int fieldargs (lua_State *L, int farg, int *width) { + int f = luaL_checkint(L, farg); + int w = luaL_optint(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > LUA_NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = w; + return f; +} + + +static int b_extract (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_replace (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + b_uint v = luaL_checkunsigned(L, 2); + int f = fieldargs(L, 3, &w); + int m = mask(w); + v &= m; /* erase bits outside given width */ + r = (r & ~(m << f)) | (v << f); + lua_pushunsigned(L, r); + return 1; +} + + +static const luaL_Reg bitlib[] = { + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_bit32 (lua_State *L) { + luaL_newlib(L, bitlib); + return 1; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.c new file mode 100644 index 000000000000..f155014d12c4 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.c @@ -0,0 +1,885 @@ +/* +** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + int l = from + n - 1; /* last register to set nil */ + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { + level++; /* argument is +1 to reserve 0 as non-op */ + while (list != NO_JUMP) { + int next = getjump(fs, list); + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); + list = next; + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +static int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "opcodes"); + f->lineinfo[fs->pc] = fs->ls->lastline; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); + return luaK_code(fs, CREATE_ABC(o, a, b, c)); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.info); +} + + +static int addk (FuncState *fs, TValue *key, TValue *v) { + lua_State *L = fs->ls->L; + TValue *idx = luaH_set(L, fs->h, key); + Proto *f = fs->f; + int k, oldsize; + if (ttisnumber(idx)) { + lua_Number n = nvalue(idx); + lua_number2int(k, n); + if (luaV_rawequalobj(&f->k[k], v)) + return k; + /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); + go through and create a new entry for this value */ + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setnvalue(idx, cast_num(k)); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + int n; + lua_State *L = fs->ls->L; + TValue o; + setnvalue(&o, r); + if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ + /* use raw representation as key to avoid numeric problems */ + setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); + n = addk(fs, L->top - 1, &o); + L->top--; + } + else + n = addk(fs, &o, &o); /* regular case */ + return n; +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ + freereg(fs, e->u.ind.idx); + if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ + freereg(fs, e->u.ind.t); + op = OP_GETTABLE; + } + e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKNUM: { + luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ + if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put value on it */ + return e->u.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.info; +} + + +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ + e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.info); + } + else break; + } + case VKNUM: { + e->u.info = luaK_numberK(fs, e->u.nval); + e->k = VK; + /* go through */ + } + case VK: { + if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ + return RKASK(e->u.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXED: { + OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + freeexp(fs, key); +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + invertjump(fs, e); + pc = e->u.info; + break; + } + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + pc = e->u.info; + break; + } + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + lua_assert(!hasjumps(t)); + t->u.ind.t = t->u.info; + t->u.ind.idx = luaK_exp2RK(fs, k); + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL + : check_exp(vkisinreg(t->k), VLOCAL); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) + return 0; /* do not attempt to divide by 0 */ + /* + * Patched: check for MIN_INT / -1 + */ + if (op == OP_DIV && e1->u.nval == INT64_MIN && e2->u.nval == -1) + return 0; + r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + luaK_fixline(fs, line); + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (isnumeral(e)) /* minus constant? */ + e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ + else { + luaK_exp2anyreg(fs, e); + codearith(fs, OP_UNM, e, &e2, line); + } + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2, line); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.info); + e1->k = VRELOCABLE; e1->u.info = e2->u.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2, line); + } + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); + break; + } + case OPR_EQ: case OPR_LT: case OPR_LE: { + codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); + break; + } + case OPR_NE: case OPR_GT: case OPR_GE: { + codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else if (c <= MAXARG_Ax) { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + codeextraarg(fs, c); + } + else + luaX_syntaxerror(fs->ls, "constructor too long"); + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.h new file mode 100644 index 000000000000..6a1424cf5a73 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.h @@ -0,0 +1,83 @@ +/* +** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcompat.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcompat.c new file mode 100644 index 000000000000..55564ddbd9fd --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcompat.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#include "lua.h" + +#include + +ssize_t +lcompat_sprintf(char *buf, const char *fmt, ...) +{ + ssize_t res; + va_list args; + + va_start(args, fmt); + res = vsnprintf(buf, INT_MAX, fmt, args); + va_end(args); + + return (res); +} + +int64_t +lcompat_strtoll(const char *str, char **ptr) +{ + int base; + const char *cp; + int digits; + int64_t value; + boolean_t is_negative; + + cp = str; + while (*cp == ' ' || *cp == '\t' || *cp == '\n') { + cp++; + } + is_negative = (*cp == '-'); + if (is_negative) { + cp++; + } + base = 10; + + if (*cp == '0') { + base = 8; + cp++; + if (*cp == 'x' || *cp == 'X') { + base = 16; + cp++; + } + } + + value = 0; + for (; *cp != '\0'; cp++) { + if (*cp >= '0' && *cp <= '9') { + digits = *cp - '0'; + } else if (*cp >= 'a' && *cp <= 'f') { + digits = *cp - 'a' + 10; + } else if (*cp >= 'A' && *cp <= 'F') { + digits = *cp - 'A' + 10; + } else { + break; + } + if (digits >= base) { + break; + } + value = (value * base) + digits; + } + + if (ptr != NULL) { + *ptr = (char *)cp; + } + if (is_negative) { + value = -value; + } + return (value); +} + +int64_t +lcompat_pow(int64_t x, int64_t y) +{ + int64_t result = 1; + if (y < 0) + return (0); + + while (y) { + if (y & 1) + result *= x; + y >>= 1; + x *= x; + } + return (result); +} + +int +lcompat_hashnum(int64_t x) +{ + x = (~x) + (x << 18); + x = x ^ (x >> 31); + x = x * 21; + x = x ^ (x >> 11); + x = x + (x << 6); + x = x ^ (x >> 22); + return ((int)x); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcorolib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcorolib.c new file mode 100644 index 000000000000..405350bb145b --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcorolib.c @@ -0,0 +1,154 @@ +/* +** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcorolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status; + if (!lua_checkstack(co, narg)) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { + lua_pushliteral(L, "cannot resume dead coroutine"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg); + if (status == LUA_OK || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + if (L == co) lua_pushliteral(L, "running"); + else { + switch (lua_status(co)) { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); + break; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); /* initial state */ + break; + } + default: /* some error occurred */ + lua_pushliteral(L, "dead"); + break; + } + } + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.c new file mode 100644 index 000000000000..107859811bfc --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.c @@ -0,0 +1,52 @@ +/* +** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#endif /* } */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.h new file mode 100644 index 000000000000..299a59b92e2c --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.h @@ -0,0 +1,93 @@ +/* +** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + +/* +** this 'ltolower' only works for alphabetic characters +*/ +#define ltolower(c) ((c) | ('A' ^ 'a')) + + +/* two more entries for 0 and -1 (EOZ) */ +LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.c new file mode 100644 index 000000000000..b8ddcff3c6bb --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.c @@ -0,0 +1,607 @@ +/* +** $Id: ldebug.c,v 2.90.1.4 2015/02/19 17:05:13 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +} + + +static int currentline (CallInfo *ci) { + return getfuncline(ci_func(ci)->p, currentpc(ci)); +} + + +static void swapextra (lua_State *L) { + if (L->status == LUA_YIELD) { + CallInfo *ci = L->ci; /* get function that yielded */ + StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ + ci->func = restorestack(L, ci->extra); + ci->extra = savestack(L, temp); + } +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + if (isLua(L->ci)) + L->oldpc = L->ci->u.l.savedpc; + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static const char *upvalname (Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); +} + + +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= ci->u.l.base - ci->func - nparams) + return NULL; /* no such vararg */ + else { + *pos = ci->func + nparams + n; + return "(*vararg)"; /* generic name for any vararg */ + } +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos) { + const char *name = NULL; + StkId base; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, -n, pos); + else { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + } + else + base = ci->func + 1; + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top : ci->next->func; + if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + name = "(*temporary)"; /* generic name for any valid slot */ + else + return NULL; /* no name */ + } + *pos = base + (n - 1); + return name; +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + lua_lock(L); + swapextra(L); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(L->top - 1)) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = 0; /* to avoid warnings */ + name = findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobj2s(L, L->top, pos); + api_incr_top(L); + } + } + swapextra(L); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + StkId pos = 0; /* to avoid warnings */ + const char *name; + lua_lock(L); + swapextra(L); + name = findlocal(L, ar->i_ci, n, &pos); + if (name) + setobjs2s(L, pos, L->top - 1); + L->top--; /* pop value */ + swapextra(L); + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (noLuaClosure(cl)) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (noLuaClosure(f)) { + setnilvalue(L->top); + api_incr_top(L); + } + else { + int i; + TValue v; + int *lineinfo = f->l.p->lineinfo; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue(L, L->top, t); /* push it on stack */ + api_incr_top(L); + setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ + luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ + } +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; + break; + } + case 'u': { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (noLuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': { + /* calling function is a known Lua function? */ + if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + ar->namewhat = getfuncname(L, ci->previous, &ar->name); + else + ar->namewhat = NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *cl; + CallInfo *ci; + StkId func; + lua_lock(L); + swapextra(L); + if (*what == '>') { + ci = NULL; + func = L->top - 1; + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top--; /* pop function */ + } + else { + ci = ar->i_ci; + func = ci->func; + lua_assert(ttisfunction(ci->func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) { + setobjs2s(L, L->top, func); + api_incr_top(L); + } + swapextra(L); + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name); + + +/* +** find a "name" for the RK value 'c' +*/ +static void kname (Proto *p, int pc, int c, const char **name) { + if (ISK(c)) { /* is 'c' a constant? */ + TValue *kvalue = &p->k[INDEXK(c)]; + if (ttisstring(kvalue)) { /* literal constant? */ + *name = svalue(kvalue); /* it is its own name */ + return; + } + /* else no reasonable name found */ + } + else { /* 'c' is a register */ + const char *what = getobjname(p, pc, c, name); /* search for 'c' */ + if (what && *what == 'c') { /* found a constant name? */ + return; /* 'name' already filled */ + } + /* else no reasonable name found */ + } + *name = "?"; /* no reasonable name found */ +} + + +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + +/* +** try to find last instruction before 'lastpc' that modified register 'reg' +*/ +static int findsetreg (Proto *p, int lastpc, int reg) { + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + for (pc = 0; pc < lastpc; pc++) { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + switch (op) { + case OP_LOADNIL: { + int b = GETARG_B(i); + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_TFORCALL: { + if (reg >= a + 2) /* affect all regs above its base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (reg >= a) /* affect all registers above base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_JMP: { + int b = GETARG_sBx(i); + int dest = pc + 1 + b; + /* jump is forward and do not skip `lastpc'? */ + if (pc < dest && dest <= lastpc) { + if (dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + } + break; + } + case OP_TEST: { + if (reg == a) /* jumped code can change 'a' */ + setreg = filterpc(pc, jmptarget); + break; + } + default: + if (testAMode(op) && reg == a) /* any instruction that set A */ + setreg = filterpc(pc, jmptarget); + break; + } + } + return setreg; +} + + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name) { + int pc; + *name = luaF_getlocalname(p, reg + 1, lastpc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + pc = findsetreg(p, lastpc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return getobjname(p, pc, b, name); /* get name for 'b' */ + break; + } + case OP_GETTABUP: + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + int t = GETARG_B(i); /* table index */ + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ + ? luaF_getlocalname(p, t + 1, pc) + : upvalname(p, t); + kname(p, pc, k, name); + return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; + } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: + case OP_LOADKX: { + int b = (op == OP_LOADK) ? GETARG_Bx(i) + : GETARG_Ax(p->code[pc + 1]); + if (ttisstring(&p->k[b])) { + *name = svalue(&p->k[b]); + return "constant"; + } + break; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + kname(p, pc, k, name); + return "method"; + } + default: break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + TMS tm; + Proto *p = ci_func(ci)->p; /* calling function */ + int pc = currentpc(ci); /* calling instruction index */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: /* get function name */ + return getobjname(p, pc, GETARG_A(i), name); + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* all other instructions can call only through metamethods */ + case OP_SELF: + case OP_GETTABUP: + case OP_GETTABLE: tm = TM_INDEX; break; + case OP_SETTABUP: + case OP_SETTABLE: tm = TM_NEWINDEX; break; + case OP_EQ: tm = TM_EQ; break; + case OP_ADD: tm = TM_ADD; break; + case OP_SUB: tm = TM_SUB; break; + case OP_MUL: tm = TM_MUL; break; + case OP_DIV: tm = TM_DIV; break; + case OP_MOD: tm = TM_MOD; break; + case OP_POW: tm = TM_POW; break; + case OP_UNM: tm = TM_UNM; break; + case OP_LEN: tm = TM_LEN; break; + case OP_LT: tm = TM_LT; break; + case OP_LE: tm = TM_LE; break; + case OP_CONCAT: tm = TM_CONCAT; break; + default: + return NULL; /* else no useful name can be found */ + } + *name = getstr(G(L)->tmname[tm]); + return "metamethod"; +} + +/* }====================================================== */ + + + +/* +** only ANSI way to check whether a pointer points to an array +** (used only for error messages, so efficiency is not a big concern) +*/ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->u.l.base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + CallInfo *ci = L->ci; + const char *name = NULL; + const char *t = objtypename(o); + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind && isinstack(ci, o)) /* no? try a register */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), + cast_int(o - ci->u.l.base), &name); + } + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = objtypename(p1); + const char *t2 = objtypename(p2); + if (t1 == t2) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(ci); + TString *src = ci_func(ci)->p->source; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +l_noret luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + L->top++; + luaD_call(L, L->top - 2, 1, 0); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.h new file mode 100644 index 000000000000..6445c763ea51 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.h @@ -0,0 +1,34 @@ +/* +** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue((ci)->func)) + + +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.c new file mode 100644 index 000000000000..cb49cb55e6cf --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.c @@ -0,0 +1,691 @@ +/* +** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) + +#ifdef _KERNEL +#ifdef illumos +#define LUAI_THROW(L,c) longjmp(&(c)->b) +#define LUAI_TRY(L,c,a) if (setjmp(&(c)->b) == 0) { a } +#define luai_jmpbuf label_t +#else +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf +#endif +#else +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + +#endif + +#endif + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + default: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else { /* thread has no error handler */ + L->status = cast_byte(errcode); /* mark it as dead */ + if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (G(L)->panic) { /* panic function? */ + lua_unlock(L); + G(L)->panic(L); /* call it (last chance to jump out) */ + } + panic("no error handler"); + } + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + unsigned short oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top = (ci->top - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + if (isLua(ci)) + ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; + } +} + + +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int lim = L->stacksize; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); + for (; lim < newsize; lim++) + setnilvalue(L->stack + lim); /* erase new segment */ + L->stacksize = newsize; + L->stack_last = L->stack + newsize - EXTRA_STACK; + correctstack(L, oldstack); +} + + +void luaD_growstack (lua_State *L, int n) { + int size = L->stacksize; + if (size > LUAI_MAXSTACK) /* error after extra size? */ + luaD_throw(L, LUA_ERRERR); + else { + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; + int newsize = 2 * size; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; + if (newsize < needed) newsize = needed; + if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ + luaD_reallocstack(L, ERRORSTACKSIZE); + luaG_runerror(L, "stack overflow"); + } + else + luaD_reallocstack(L, newsize); + } +} + + +static int stackinuse (lua_State *L) { + CallInfo *ci; + StkId lim = L->top; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + lua_assert(ci->top <= L->stack_last); + if (lim < ci->top) lim = ci->top; + } + return cast_int(lim - L->stack) + 1; /* part of stack in use */ +} + + +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; + if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; + if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ + goodsize >= L->stacksize) /* would grow instead of shrink? */ + condmovestack(L); /* don't change stack (change only for debugging) */ + else + luaD_reallocstack(L, goodsize); /* shrink it */ +} + + +void luaD_hook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= CIST_HOOKED; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + ci->callstatus &= ~CIST_HOOKED; + } +} + + +static void callhook (lua_State *L, CallInfo *ci) { + int hook = LUA_HOOKCALL; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + if (isLua(ci->previous) && + GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { + ci->callstatus |= CIST_TAIL; + hook = LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci->u.l.savedpc--; /* correct 'pc' */ +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + StkId base, fixed; + lua_assert(actual >= nfixargs); + /* move fixed parameters to final position */ + luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed + i); + setnilvalue(fixed + i); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) + + +/* +** returns true if function has been executed (C function) +*/ +int luaD_precall (lua_State *L, StkId func, int nresults) { + lua_CFunction f; + CallInfo *ci; + int n; /* number of arguments (Lua) or returns (C) */ + ptrdiff_t funcr = savestack(L, func); + switch (ttype(func)) { + case LUA_TLCF: /* light C function */ + f = fvalue(func); + goto Cfunc; + case LUA_TCCL: { /* C closure */ + f = clCvalue(func)->f; + Cfunc: + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = restorestack(L, funcr); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, L->top - n); + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + n = cast_int(L->top - func) - 1; /* number of real arguments */ + luaD_checkstack(L, p->maxstacksize); + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + if (!p->is_vararg) { + func = restorestack(L, funcr); + base = func + 1; + } + else { + base = adjust_varargs(L, p, n); + func = restorestack(L, funcr); /* previous call can change stack */ + } + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + ci->top = base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + L->top = ci->top; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* retry with 'function' tag method */ + return luaD_precall(L, func, nresults); /* now it must be a function */ + } + } +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci = L->ci; + if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { + if (L->hookmask & LUA_MASKRET) { + ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } + L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ + } + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->ci = ci = ci->previous; /* back to caller */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (!allowyield) L->nny++; + if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ + luaV_execute(L); /* call it */ + if (!allowyield) L->nny--; + L->nCcalls--; +} + + +static void finishCcall (lua_State *L) { + CallInfo *ci = L->ci; + int n; + lua_assert(ci->u.c.k != NULL); /* must have a continuation */ + lua_assert(L->nny == 0); + if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ + ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ + L->errfunc = ci->u.c.old_errfunc; + } + /* finish 'lua_callk'/'lua_pcall' */ + adjustresults(L, ci->nresults); + /* call continuation function */ + if (!(ci->callstatus & CIST_STAT)) /* no call status? */ + ci->u.c.status = LUA_YIELD; /* 'default' status */ + lua_assert(ci->u.c.status != LUA_OK); + ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); + lua_lock(L); + api_checknelems(L, n); + /* finish 'luaD_precall' */ + luaD_poscall(L, L->top - n); +} + + +static void unroll (lua_State *L, void *ud) { + UNUSED(ud); + for (;;) { + if (L->ci == &L->base_ci) /* stack is empty? */ + return; /* coroutine finished normally */ + if (!isLua(L->ci)) /* C function? */ + finishCcall(L); + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** check whether thread has a suspended protected call +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +static int recover (lua_State *L, int status) { + StkId oldtop; + CallInfo *ci = findpcall(L); + if (ci == NULL) return 0; /* no recovery point */ + /* "finish" luaD_pcall */ + oldtop = restorestack(L, ci->extra); + luaF_close(L, oldtop); + seterrorobj(L, status, oldtop); + L->ci = ci; + L->allowhook = ci->u.c.old_allowhook; + L->nny = 0; /* should be zero to be yieldable */ + luaD_shrinkstack(L); + L->errfunc = ci->u.c.old_errfunc; + ci->callstatus |= CIST_STAT; /* call has error status */ + ci->u.c.status = status; /* (here it is) */ + return 1; /* continue running the coroutine */ +} + + +/* +** signal an error in the call to 'resume', not in the execution of the +** coroutine itself. (Such errors should not be handled by any coroutine +** error handler and should not kill the coroutine.) +*/ +static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { + L->top = firstArg; /* remove args from the stack */ + setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + luaD_throw(L, -1); /* jump back to 'lua_resume' */ +} + + +/* +** do the work for 'lua_resume' in protected mode +*/ +static void resume_cb (lua_State *L, void *ud) { + int nCcalls = L->nCcalls; + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (nCcalls >= LUAI_MAXCCALLS) + resume_error(L, "C stack overflow", firstArg); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (ci != &L->base_ci) /* not in base level? */ + resume_error(L, "cannot resume non-suspended coroutine", firstArg); + /* coroutine is in base level; start running it */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ + luaV_execute(L); /* call it */ + } + else if (L->status != LUA_YIELD) + resume_error(L, "cannot resume dead coroutine", firstArg); + else { /* resuming from previous yield */ + L->status = LUA_OK; + ci->func = restorestack(L, ci->extra); + if (isLua(ci)) /* yielded inside a hook? */ + luaV_execute(L); /* just continue running Lua code */ + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation? */ + int n; + ci->u.c.status = LUA_YIELD; /* 'default' status */ + ci->callstatus |= CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + firstArg = L->top - n; /* yield results come from continuation */ + } + luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ + } + unroll(L, NULL); + } + lua_assert(nCcalls == L->nCcalls); +} + + +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { + int status; + int oldnny = L->nny; /* save 'nny' */ + lua_lock(L); + luai_userstateresume(L, nargs); + L->nCcalls = (from) ? from->nCcalls + 1 : 1; + L->nny = 0; /* allow yields */ + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume_cb, L->top - nargs); + if (status == -1) /* error calling 'lua_resume'? */ + status = LUA_ERRRUN; + else { /* yield or regular error */ + while (status != LUA_OK && status != LUA_YIELD) { /* error? */ + if (recover(L, status)) /* recover point? */ + status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ + else { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as `dead' */ + seterrorobj(L, status, L->top); + L->ci->top = L->top; + break; + } + } + lua_assert(status == L->status); + } + L->nny = oldnny; /* restore 'nny' */ + L->nCcalls--; + lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); + lua_unlock(L); + return status; +} + + +LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { + CallInfo *ci = L->ci; + luai_userstateyield(L, nresults); + lua_lock(L); + api_checknelems(L, nresults); + if (L->nny > 0) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->extra = savestack(L, ci->func); /* save current 'func' */ + if (isLua(ci)) { /* inside a hook? */ + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + ci->func = L->top - nresults - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + unsigned short old_nny = L->nny; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != LUA_OK) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close possible pending closures */ + seterrorobj(L, status, oldtop); + L->ci = old_ci; + L->allowhook = old_allowhooks; + L->nny = old_nny; + luaD_shrinkstack(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; +}; + + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } +} + + +static void f_parser (lua_State *L, void *ud) { + int i; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, &p->buff, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); + for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ + UpVal *up = luaF_newupval(L); + cl->l.upvals[i] = up; + luaC_objbarrier(L, cl, up); + } +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { + struct SParser p; + int status; + L->nny++; /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + L->nny--; + return status; +} + + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.h new file mode 100644 index 000000000000..d3d3082c9ba3 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.h @@ -0,0 +1,46 @@ +/* +** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ + luaD_growstack(L, n); else condmovestack(L); + + +#define incr_top(L) {L->top++; luaD_checkstack(L,0);} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, + int allowyield); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldump.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldump.c new file mode 100644 index 000000000000..64e564933268 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldump.c @@ -0,0 +1,173 @@ +/* +** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size*sizeof(char),D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttypenv(o),D); + switch (ttypenv(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: lua_assert(0); + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],D); +} + +static void DumpUpvalues(const Proto* f, DumpState* D) +{ + int i,n=f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].instack,D); + DumpChar(f->upvalues[i].idx,D); + } +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + DumpString((D->strip) ? NULL : f->source,D); + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].name,D); +} + +static void DumpFunction(const Proto* f, DumpState* D) +{ + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpUpvalues(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + lu_byte h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,&D); + return D.status; +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.c new file mode 100644 index 000000000000..684e44709a8f --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.c @@ -0,0 +1,161 @@ +/* +** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; + c->c.nupvalues = cast_byte(n); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; + c->l.p = NULL; + c->l.nupvalues = cast_byte(n); + while (n--) c->l.upvals[n] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { + GCObject *o = obj2gco(p); + lua_assert(p->v != &p->u.value); + lua_assert(!isold(o) || isold(obj2gco(L))); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, o)) /* is it dead? */ + changewhite(o); /* resurrect it */ + return p; + } + pp = &p->next; + } + /* not found: create a new one */ + uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; + uv->v = level; /* current value lives in the stack */ + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); /* remove upvalue from 'uvhead' list */ + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ + uv->v = &uv->u.value; /* now current value lives here */ + gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ + g->allgc = o; + luaC_checkupvalcolor(g, uv); + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->cache = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.h new file mode 100644 index 000000000000..ca0d3a3e0b03 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.h @@ -0,0 +1,33 @@ +/* +** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.c new file mode 100644 index 000000000000..9c9863057443 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.c @@ -0,0 +1,1220 @@ +/* +** $Id: lgc.c,v 2.140.1.3 2014/09/01 16:55:08 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +/* +** cost of sweeping one element (the size of a small object divided +** by some adjust for the sweep speed) +*/ +#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) + +/* maximum number of elements to sweep in each single step */ +#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) + +/* maximum number of finalizers to call in each GC step */ +#define GCFINALIZENUM 4 + + +/* +** macro to adjust 'stepmul': 'stepmul' is actually used like +** 'stepmul / STEPMULADJ' (value chosen by tests) +*/ +#define STEPMULADJ 200 + + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* +** 'makewhite' erases all color bits plus the old bit and then +** sets only the current white bit +*/ +#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) +#define makewhite(g,x) \ + (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) + +#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) +#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) + + +#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) + +#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) + + +#define checkconsistency(obj) \ + lua_longassert(!iscollectable(obj) || righttt(obj)) + + +#define markvalue(g,o) { checkconsistency(o); \ + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + +static void reallymarkobject (global_State *g, GCObject *o); + + +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) + + +/* +** link table 'h' into list pointed by 'p' +*/ +#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) + + +/* +** if key is not marked, mark its entry as dead (therefore removing it +** from the table) +*/ +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (valiswhite(gkey(n))) + setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ +} + + +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const TValue *o) { + if (!iscollectable(o)) return 0; + else if (ttisstring(o)) { + markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + else return iswhite(gcvalue(o)); +} + + +/* +** barrier that moves collector forward, that is, mark the white object +** being pointed by a black object. +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSpause); + lua_assert(gch(o)->tt != LUA_TTABLE); + if (keepinvariantout(g)) /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + else { /* sweep phase */ + lua_assert(issweepphase(g)); + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. (Current implementation +** only works for tables; access to 'gclist' is not uniform across +** different types.) +*/ +void luaC_barrierback_ (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); + black2gray(o); /* make object gray (again) */ + gco2t(o)->gclist = g->grayagain; + g->grayagain = o; +} + + +/* +** barrier for prototypes. When creating first closure (cache is +** NULL), use a forward barrier; this may be the only closure of the +** prototype (if it is a "regular" function, with a single instance) +** and the prototype may be big, so it is better to avoid traversing +** it again. Otherwise, use a backward barrier, to avoid marking all +** possible instances. +*/ +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { + global_State *g = G(L); + lua_assert(isblack(obj2gco(p))); + if (p->cache == NULL) { /* first time? */ + luaC_objbarrier(L, p, c); + } + else { /* use a backward barrier */ + black2gray(obj2gco(p)); /* make prototype gray (again) */ + p->gclist = g->grayagain; + g->grayagain = obj2gco(p); + } +} + + +/* +** check color (and invariants) for an upvalue that was closed, +** i.e., moved into the 'allgc' list +*/ +void luaC_checkupvalcolor (global_State *g, UpVal *uv) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o)); /* open upvalues are never black */ + if (isgray(o)) { + if (keepinvariant(g)) { + resetoldbit(o); /* see MOVE OLD rule */ + gray2black(o); /* it is being visited now */ + markvalue(g, uv->v); + } + else { + lua_assert(issweepphase(g)); + makewhite(g, o); + } + } +} + + +/* +** create a new collectable object (with given type and size) and link +** it to '*list'. 'offset' tells how many bytes to allocate before the +** object itself (used only by states). +*/ +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, + int offset) { + global_State *g = G(L); + char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); + GCObject *o = obj2gco(raw + offset); + if (list == NULL) + list = &g->allgc; /* standard list for collectable objects */ + gch(o)->marked = luaC_white(g); + gch(o)->tt = tt; + gch(o)->next = *list; + *list = o; + return o; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** mark an object. Userdata, strings, and closed upvalues are visited +** and turned black here. Other objects are marked gray and added +** to appropriate list to be visited (and turned black) later. (Open +** upvalues are already linked in 'headuv' list.) +*/ +static void reallymarkobject (global_State *g, GCObject *o) { + lu_mem size; + white2gray(o); + switch (gch(o)->tt) { + case LUA_TSHRSTR: + case LUA_TLNGSTR: { + size = sizestring(gco2ts(o)); + break; /* nothing else to mark; make it black */ + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + markobject(g, mt); + markobject(g, gco2u(o)->env); + size = sizeudata(gco2u(o)); + break; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v != &uv->u.value) /* open? */ + return; /* open upvalues remain gray */ + size = sizeof(UpVal); + break; + } + case LUA_TLCL: { + gco2lcl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TCCL: { + gco2ccl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TTABLE: { + linktable(gco2t(o), &g->gray); + return; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + return; + } + default: lua_assert(0); return; + } + gray2black(o); + g->GCmemtrav += size; +} + + +/* +** mark metamethods for basic types +*/ +static void markmt (global_State *g) { + int i; + for (i=0; i < LUA_NUMTAGS; i++) + markobject(g, g->mt[i]); +} + + +/* +** mark all objects in list of being-finalized +*/ +static void markbeingfnz (global_State *g) { + GCObject *o; + for (o = g->tobefnz; o != NULL; o = gch(o)->next) { + makewhite(g, o); + reallymarkobject(g, o); + } +} + + +/* +** mark all values stored in marked open upvalues. (See comment in +** 'lstate.h'.) +*/ +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +/* +** mark root set and reset all gray lists, to start a new +** incremental (or full) collection +*/ +static void restartcollection (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (do not + traverse it just to check) */ + int hasclears = (h->sizearray > 0); + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (hasclears) + linktable(h, &g->weak); /* has to be cleared later */ + else /* no white values */ + linktable(h, &g->grayagain); /* no need to clean */ +} + + +static int traverseephemeron (global_State *g, Table *h) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int prop = 0; /* true if table has entry "white-key -> white-value" */ + Node *n, *limit = gnodelast(h); + int i; + /* traverse array part (numeric keys are 'strong') */ + for (i = 0; i < h->sizearray; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part */ + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + prop = 1; /* must propagate again */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + if (g->gcstate != GCSatomic || prop) + linktable(h, &g->ephemeron); /* have to propagate again */ + else if (hasclears) /* does table have white keys? */ + linktable(h, &g->allweak); /* may have to clean white keys */ + else /* no white keys */ + linktable(h, &g->grayagain); /* no need to clean */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + markvalue(g, gval(n)); /* mark value */ + } + } +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + markobject(g, h->metatable); + if (mode && ttisstring(mode) && /* is there a weak mode? */ + ((weakkey = strchr(svalue(mode), 'k')), + (weakvalue = strchr(svalue(mode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + black2gray(obj2gco(h)); /* keep table gray */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h); + else /* all weak */ + linktable(h, &g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * cast(size_t, sizenode(h)); +} + + +static int traverseproto (global_State *g, Proto *f) { + int i; + if (f->cache && iswhite(obj2gco(f->cache))) + f->cache = NULL; /* allow cache to be collected */ + markobject(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobject(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobject(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobject(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; +} + + +static lu_mem traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return sizeCclosure(cl->nupvalues); +} + +static lu_mem traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobject(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->upvals[i]); + return sizeLclosure(cl->nupvalues); +} + + +static lu_mem traversestack (global_State *g, lua_State *th) { + int n = 0; + StkId o = th->stack; + if (o == NULL) + return 1; /* stack not completely built yet */ + for (; o < th->top; o++) /* mark live elements in the stack */ + markvalue(g, o); + if (g->gcstate == GCSatomic) { /* final traversal? */ + StkId lim = th->stack + th->stacksize; /* real end of stack */ + for (; o < lim; o++) /* clear not-marked stack slice */ + setnilvalue(o); + } + else { /* count call infos to compute size */ + CallInfo *ci; + for (ci = &th->base_ci; ci != th->ci; ci = ci->next) + n++; + } + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * n; +} + + +/* +** traverse one gray object, turning it to black (except for threads, +** which are always gray). +*/ +static void propagatemark (global_State *g) { + lu_mem size; + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (gch(o)->tt) { + case LUA_TTABLE: { + Table *h = gco2t(o); + g->gray = h->gclist; /* remove from 'gray' list */ + size = traversetable(g, h); + break; + } + case LUA_TLCL: { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseLclosure(g, cl); + break; + } + case LUA_TCCL: { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseCclosure(g, cl); + break; + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; /* remove from 'gray' list */ + th->gclist = g->grayagain; + g->grayagain = o; /* insert into 'grayagain' list */ + black2gray(o); + size = traversestack(g, th); + break; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; /* remove from 'gray' list */ + size = traverseproto(g, p); + break; + } + default: lua_assert(0); return; + } + g->GCmemtrav += size; +} + + +static void propagateall (global_State *g) { + while (g->gray) propagatemark(g); +} + + +static void propagatelist (global_State *g, GCObject *l) { + lua_assert(g->gray == NULL); /* no grays left */ + g->gray = l; + propagateall(g); /* traverse all elements from 'l' */ +} + +/* +** retraverse all gray lists. Because tables may be reinserted in other +** lists when traversed, traverse the original lists to avoid traversing +** twice the same table (which is not wrong, but inefficient) +*/ +static void retraversegrays (global_State *g) { + GCObject *weak = g->weak; /* save original lists */ + GCObject *grayagain = g->grayagain; + GCObject *ephemeron = g->ephemeron; + g->weak = g->grayagain = g->ephemeron = NULL; + propagateall(g); /* traverse main gray list */ + propagatelist(g, grayagain); + propagatelist(g, weak); + propagatelist(g, ephemeron); +} + + +static void convergeephemerons (global_State *g) { + int changed; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables will return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { + next = gco2t(w)->gclist; + if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + } while (changed); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearkeys (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (gch(o)->tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TLCL: { + luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); + break; + } + case LUA_TCCL: { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2t(o)); break; + case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; + case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; + case LUA_TSHRSTR: + G(L)->strt.nuse--; + /* go through */ + case LUA_TLNGSTR: { + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + default: lua_assert(0); + } +} + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); + + +/* +** sweep the (open) upvalues of a thread and resize its stack and +** list of call-info structures. +*/ +static void sweepthread (lua_State *L, lua_State *L1) { + if (L1->stack == NULL) return; /* stack not completely built yet */ + sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ + luaE_freeCI(L1); /* free extra CallInfo slots */ + /* should not change the stack during an emergency gc cycle */ + if (G(L)->gckind != KGC_EMERGENCY) + luaD_shrinkstack(L1); +} + + +/* +** sweep at most 'count' elements from a list of GCObjects erasing dead +** objects, where a dead (not alive) object is one marked with the "old" +** (non current) white and not fixed. +** In non-generational mode, change all non-dead objects back to white, +** preparing for next collection cycle. +** In generational mode, keep black objects black, and also mark them as +** old; stop when hitting an old object, as all objects after that +** one will be old too. +** When object is a thread, sweep its list of open upvalues too. +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + global_State *g = G(L); + int ow = otherwhite(g); + int toclear, toset; /* bits to clear and to set in all live objects */ + int tostop; /* stop sweep when this is true */ + if (isgenerational(g)) { /* generational mode? */ + toclear = ~0; /* clear nothing */ + toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ + tostop = bitmask(OLDBIT); /* do not sweep old generation */ + } + else { /* normal mode */ + toclear = maskcolors; /* clear all color bits + old bit */ + toset = luaC_white(g); /* make object white */ + tostop = 0; /* do not stop */ + } + while (*p != NULL && count-- > 0) { + GCObject *curr = *p; + int marked = gch(curr)->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = gch(curr)->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { + if (testbits(marked, tostop)) + return NULL; /* stop sweeping this list */ + if (gch(curr)->tt == LUA_TTHREAD) + sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ + /* update marks */ + gch(curr)->marked = cast_byte((marked & toclear) | toset); + p = &gch(curr)->next; /* go to next element */ + } + } + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { + GCObject ** old = p; + int i = 0; + do { + i++; + p = sweeplist(L, p, 1); + } while (p == old); + if (n) *n += i; + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ + int hs = g->strt.size / 2; /* half the size of the string table */ + if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ + luaS_resize(L, hs); /* halve its size */ + luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ + } +} + + +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(isfinalized(o)); + g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ + gch(o)->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ + lua_assert(!isold(o)); /* see MOVE OLD rule */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_call(L, L->top - 2, 0, 0); +} + + +static void GCTM (lua_State *L, int propagateerrors) { + global_State *g = G(L); + const TValue *tm; + TValue v; + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int running = g->gcrunning; + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top, tm); /* push finalizer... */ + setobj2s(L, L->top + 1, &v); /* ... and its argument */ + L->top += 2; /* and (next line) call the finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->allowhook = oldah; /* restore hooks */ + g->gcrunning = running; /* restore state */ + if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ + if (status == LUA_ERRRUN) { /* is there an error object? */ + const char *msg = (ttisstring(L->top - 1)) + ? svalue(L->top - 1) + : "no message"; + luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); + status = LUA_ERRGCMM; /* error in __gc metamethod */ + } + luaD_throw(L, status); /* re-throw error */ + } + } +} + + +/* +** move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized) +*/ +static void separatetobefnz (lua_State *L, int all) { + global_State *g = G(L); + GCObject **p = &g->finobj; + GCObject *curr; + GCObject **lastnext = &g->tobefnz; + /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ + while (*lastnext != NULL) + lastnext = &gch(*lastnext)->next; + while ((curr = *p) != NULL) { /* traverse all finalizable objects */ + lua_assert(!isfinalized(curr)); + lua_assert(testbit(gch(curr)->marked, SEPARATED)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &gch(curr)->next; /* don't bother with it */ + else { + l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ + *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ + gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &gch(curr)->next; + } + } +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ + isfinalized(o) || /* ... or is finalized... */ + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + GCheader *ho = gch(o); + if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ + lua_assert(issweepphase(g)); + g->sweepgc = sweeptolive(L, g->sweepgc, NULL); + } + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } + *p = ho->next; /* remove 'o' from root list */ + ho->next = g->finobj; /* link it in list 'finobj' */ + g->finobj = o; + l_setbit(ho->marked, SEPARATED); /* mark it as such */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + else + resetoldbit(o); /* see MOVE OLD rule */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** set a reasonable "time" to wait before starting a new GC cycle; +** cycle will start when memory use hits threshold +*/ +static void setpause (global_State *g, l_mem estimate) { + l_mem debt, threshold; + estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ + threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * g->gcpause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = -cast(l_mem, threshold - gettotalbytes(g)); + luaE_setdebt(g, debt); +} + + +#define sweepphases \ + (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) + + +/* +** enter first sweep phase (strings) and prepare pointers for other +** sweep phases. The calls to 'sweeptolive' make pointers point to an +** object inside the list (instead of to the header), so that the real +** sweep do not need to skip objects created between "now" and the start +** of the real sweep. +** Returns how many objects it swept. +*/ +static int entersweep (lua_State *L) { + global_State *g = G(L); + int n = 0; + g->gcstate = GCSsweepstring; + lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); + /* prepare to sweep strings, finalizable objects, and regular objects */ + g->sweepstrgc = 0; + g->sweepfin = sweeptolive(L, &g->finobj, &n); + g->sweepgc = sweeptolive(L, &g->allgc, &n); + return n; +} + + +/* +** change GC mode +*/ +void luaC_changemode (lua_State *L, int mode) { + global_State *g = G(L); + if (mode == g->gckind) return; /* nothing to change */ + if (mode == KGC_GEN) { /* change to generational mode */ + /* make sure gray lists are consistent */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + g->GCestimate = gettotalbytes(g); + g->gckind = KGC_GEN; + } + else { /* change to incremental mode */ + /* sweep all objects to turn them back to white + (as white has not changed, nothing extra will be collected) */ + g->gckind = KGC_NORMAL; + entersweep(L); + luaC_runtilstate(L, ~sweepphases); + } +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L, int propagateerrors) { + global_State *g = G(L); + while (g->tobefnz) { + resetoldbit(g->tobefnz); + GCTM(L, propagateerrors); + } +} + + +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + int i; + separatetobefnz(L, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L, 0); + g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ + g->gckind = KGC_NORMAL; + sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ + sweepwholelist(L, &g->allgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); + lua_assert(g->strt.nuse == 0); +} + + +static l_mem atomic (lua_State *L) { + global_State *g = G(L); + l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ + GCObject *origweak, *origall; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark basic metatables */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + propagateall(g); /* propagate changes */ + work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ + /* traverse objects caught by write barrier and by 'remarkupvals' */ + retraversegrays(g); + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* clear values from weak tables, before checking finalizers */ + clearvalues(g, g->weak, NULL); + clearvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + work += g->GCmemtrav; /* stop counting (objects being finalized) */ + separatetobefnz(L, 0); /* separate objects to be finalized */ + markbeingfnz(g); /* mark objects that will be finalized */ + propagateall(g); /* remark, to propagate `preserveness' */ + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ + clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ + /* clear values from resurrected weak tables */ + clearvalues(g, g->weak, origweak); + clearvalues(g, g->allweak, origall); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + work += g->GCmemtrav; /* complete counting */ + return work; /* estimate of memory marked by 'atomic' */ +} + + +static lu_mem singlestep (lua_State *L) { + global_State *g = G(L); + switch (g->gcstate) { + case GCSpause: { + /* start to count memory traversed */ + g->GCmemtrav = g->strt.size * sizeof(GCObject*); + lua_assert(!isgenerational(g)); + restartcollection(g); + g->gcstate = GCSpropagate; + return g->GCmemtrav; + } + case GCSpropagate: { + if (g->gray) { + lu_mem oldtrav = g->GCmemtrav; + propagatemark(g); + return g->GCmemtrav - oldtrav; /* memory traversed in this step */ + } + else { /* no more `gray' objects */ + lu_mem work; + int sw; + g->gcstate = GCSatomic; /* finish mark phase */ + g->GCestimate = g->GCmemtrav; /* save what was counted */; + work = atomic(L); /* add what was traversed by 'atomic' */ + g->GCestimate += work; /* estimate of total memory traversed */ + sw = entersweep(L); + return work + sw * GCSWEEPCOST; + } + } + case GCSsweepstring: { + int i; + for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) + sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); + g->sweepstrgc += i; + if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ + g->gcstate = GCSsweepudata; + return i * GCSWEEPCOST; + } + case GCSsweepudata: { + if (g->sweepfin) { + g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; + } + else { + g->gcstate = GCSsweep; + return 0; + } + } + case GCSsweep: { + if (g->sweepgc) { + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; + } + else { + /* sweep main thread */ + GCObject *mt = obj2gco(g->mainthread); + sweeplist(L, &mt, 1); + checkSizes(L); + g->gcstate = GCSpause; /* finish collection */ + return GCSWEEPCOST; + } + } + default: lua_assert(0); return 0; + } +} + + +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + +static void generationalcollection (lua_State *L) { + global_State *g = G(L); + lua_assert(g->gcstate == GCSpropagate); + if (g->GCestimate == 0) { /* signal for another major collection? */ + luaC_fullgc(L, 0); /* perform a full regular collection */ + g->GCestimate = gettotalbytes(g); /* update control */ + } + else { + lu_mem estimate = g->GCestimate; + luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ + g->gcstate = GCSpropagate; /* skip restart */ + if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) + g->GCestimate = 0; /* signal for a major collection */ + else + g->GCestimate = estimate; /* keep estimate from last major coll. */ + + } + setpause(g, gettotalbytes(g)); + lua_assert(g->gcstate == GCSpropagate); +} + + +static void incstep (lua_State *L) { + global_State *g = G(L); + l_mem debt = g->GCdebt; + int stepmul = g->gcstepmul; + if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ + /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + do { /* always perform at least one single step */ + lu_mem work = singlestep(L); /* do some work */ + debt -= work; + } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g, g->GCestimate); /* pause until next cycle */ + else { + debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ + luaE_setdebt(g, debt); + } +} + + +/* +** performs a basic GC step +*/ +void luaC_forcestep (lua_State *L) { + global_State *g = G(L); + int i; + if (isgenerational(g)) generationalcollection(L); + else incstep(L); + /* run a few finalizers (or all of them at the end of a collect cycle) */ + for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) + GCTM(L, 1); /* call one finalizer */ +} + + +/* +** performs a basic GC step only if collector is running +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + if (g->gcrunning) luaC_forcestep(L); + else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ +} + + + +/* +** performs a full GC cycle; if "isemergency", does not call +** finalizers (which could change stack positions) +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + int origkind = g->gckind; + lua_assert(origkind != KGC_EMERGENCY); + if (isemergency) /* do not run finalizers during emergency GC */ + g->gckind = KGC_EMERGENCY; + else { + g->gckind = KGC_NORMAL; + callallpendingfinalizers(L, 1); + } + if (keepinvariant(g)) { /* may there be some black objects? */ + /* must sweep all objects to turn them back to white + (as white has not changed, nothing will be collected) */ + entersweep(L); + } + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ + luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ + if (origkind == KGC_GEN) { /* generational mode? */ + /* generational mode must be kept in propagate phase */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + } + g->gckind = origkind; + setpause(g, gettotalbytes(g)); + if (!isemergency) /* do not run finalizers during emergency GC */ + callallpendingfinalizers(L, 1); +} + +/* }====================================================== */ + + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.h new file mode 100644 index 000000000000..84bb1cdf99fa --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.h @@ -0,0 +1,157 @@ +/* +** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which +** means the object is not marked; gray, which means the +** object is marked, but its references may be not marked; and +** black, which means that the object and all its references are marked. +** The main invariant of the garbage collector, while marking objects, +** is that a black object can never point to a white one. Moreover, +** any gray object must be in a "gray list" (gray, grayagain, weak, +** allweak, ephemeron) so that it can be visited again before finishing +** the collection cycle. These lists have no meaning when the invariant +** is not being enforced (e.g., sweep phase). +*/ + + + +/* how much to allocate before next GC step */ +#if !defined(GCSTEPSIZE) +/* ~100 small strings */ +#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) +#endif + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSatomic 1 +#define GCSsweepstring 2 +#define GCSsweepudata 3 +#define GCSsweep 4 +#define GCSpause 5 + + +#define issweepphase(g) \ + (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) + +#define isgenerational(g) ((g)->gckind == KGC_GEN) + +/* +** macros to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a non-generational collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. During a generational collection, the +** invariant must be kept all times. +*/ + +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) + + +/* +** Outside the collector, the state in generational mode is kept in +** 'propagate', so 'keepinvariant' is always true. +*/ +#define keepinvariantout(g) \ + check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ + g->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* Layout for bit use in `marked' field: */ +#define WHITE0BIT 0 /* object is white (type 0) */ +#define WHITE1BIT 1 /* object is white (type 1) */ +#define BLACKBIT 2 /* object is black */ +#define FINALIZEDBIT 3 /* object has been separated for finalization */ +#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ +#define FIXEDBIT 5 /* object is fixed (should not be collected) */ +#define OLDBIT 6 /* object is old (only in generational mode) */ +/* bit 7 is currently used by tests (luaL_checkmemory) */ + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) + +#define isold(x) testbit((x)->gch.marked, OLDBIT) + +/* MOVE OLD rule: whenever an object is moved to the beginning of + a GC list, its old bit must be cleared */ +#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_condGC(L,c) \ + {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} +#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrier_(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierback_(L,p); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarrierback(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } + +#define luaC_barrierproto(L,p,c) \ + { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } + +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_forcestep (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, + GCObject **list, int offset); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); +LUAI_FUNC void luaC_changemode (lua_State *L, int mode); + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.c new file mode 100644 index 000000000000..c84844aec5de --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.c @@ -0,0 +1,528 @@ +/* +** $Id: llex.c,v 2.63.1.3 2015/02/09 17:56:34 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "lctype.h" +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +static const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", "::", "", + "", "", "" +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static l_noret lexerror (LexState *ls, const char *msg, int token); + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZET/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.extra = cast_byte(i+1); /* reserved word */ + } +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + lua_assert(token == cast(unsigned char, token)); + return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : + luaO_pushfstring(ls->L, "char(%d)", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, LUA_QS, s); + else /* names, strings, and numerals */ + return s; + } +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } +} + + +static l_noret lexerror (LexState *ls, const char *msg, int token) { + char buff[LUA_IDSIZE]; + luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); +} + + +/* +** creates a new string and anchors it in function's table so that +** it will not be collected until the end of the function's compilation +** (by that time it should be anchored in function's prototype) +*/ +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TValue *o; /* entry for `str' */ + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ + o = luaH_set(L, ls->fs->h, L->top - 1); + if (ttisnil(o)) { /* not in use yet? (see 'addK') */ + /* boolean value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setbvalue(o, 1); /* t[string] = true */ + luaC_checkGC(L); + } + else { /* string already present */ + ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ + } + L->top--; /* remove string from stack */ + return ts; +} + + +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + lexerror(ls, "chunk has too many lines", 0); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { + ls->decpoint = '.'; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_new(L, LUA_ENV); /* create env name */ + luaS_fix(ls->envn); /* never collect this name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (ls->current == '\0' || !strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +/* +** change all characters 'from' in buffer to 'to' +*/ +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +#if !defined(getlocaledecpoint) +#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) + +/* +** in case of format error, try to change decimal point separator to +** the one defined in the current locale and check again +*/ +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + char old = ls->decpoint; + ls->decpoint = getlocaledecpoint(); + buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ + if (!buff2d(ls->buff, &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +/* +** this function is quite liberal in what it accepts, as 'luaO_str2d' +** will reject ill-formed numerals. +*/ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next(ls, expo)) /* exponent part? */ + check_next(ls, "+-"); /* optional exponent sign */ + if (lisxdigit(ls->current) || ls->current == '.') + save_and_next(ls); + else break; + } + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +/* +** skip a sequence '[=*[' or ']=*]' and return its number of '='s or +** -1 if sequence is malformed +*/ +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ + goto endloop; + } + break; + } + case '\n': case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void escerror (LexState *ls, int *c, int n, const char *msg) { + int i; + luaZ_resetbuffer(ls->buff); /* prepare error message */ + save(ls, '\\'); + for (i = 0; i < n && c[i] != EOZ; i++) + save(ls, c[i]); + lexerror(ls, msg, TK_STRING); +} + + +static int readhexaesc (LexState *ls) { + int c[3], i; /* keep input for error message */ + int r = 0; /* result accumulator */ + c[0] = 'x'; /* for error message */ + for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ + c[i] = next(ls); + if (!lisxdigit(c[i])) + escerror(ls, c, i + 1, "hexadecimal digit expected"); + r = (r << 4) + luaO_hexavalue(c[i]); + } + return r; +} + + +static int readdecesc (LexState *ls) { + int c[3], i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + c[i] = ls->current; + r = 10*r + c[i] - '0'; + next(ls); + } + if (r > UCHAR_MAX) + escerror(ls, c, i, "decimal escape too large"); + return r; +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) { + switch (ls->current) { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); + } + goto no_save; + } + default: { + if (!lisdigit(ls->current)) + escerror(ls, &ls->current, 1, "invalid escape sequence"); + /* digital escape \ddd */ + c = readdecesc(ls); + goto only_save; + } + } + read_save: next(ls); /* read next character */ + only_save: save(ls, c); /* save 'c' */ + no_save: break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': case '\r': { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { /* long comment? */ + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': { /* long string or simply '[' */ + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case ':': { + next(ls); + if (ls->current != ':') return ':'; + else { next(ls); return TK_DBCOLON; } + } + case '"': case '\'': { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) return '.'; + /* else go through */ + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + case EOZ: { + return TK_EOS; + } + default: { + if (lislalpha(ls->current)) { /* identifier or reserved word? */ + TString *ts; + do { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->tsv.extra - 1 + FIRST_RESERVED; + else { + return TK_NAME; + } + } + else { /* single-char tokens (+ - / ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +int luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.h new file mode 100644 index 000000000000..a4acdd30218a --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.h @@ -0,0 +1,78 @@ +/* +** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, + TK_NUMBER, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llimits.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llimits.h new file mode 100644 index 000000000000..4277c1fd03db --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llimits.h @@ -0,0 +1,308 @@ +/* +** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include + +#include "lua.h" + + +typedef unsigned LUA_INT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + +#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +#if !defined(LUAI_USER_ALIGNMENT_T) +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +#endif + +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) { if (!(c)) lua_assert(0); } +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) + +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,e) assert(e) +#else +#define luai_apicheck(L,e) lua_assert(e) +#endif + +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#define cast(t, exp) ((t)(exp)) + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) + + +/* +** non-return type +*/ +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + + + +/* +** maximum depth for nested C calls and syntactical nested non-terminals +** in a program. (Value must fit in an unsigned short int.) +** +** Note: On amd64 platform, the limit has been measured to be 45. We set +** the maximum lower to give a margin for changing the amount of stack +** used by various functions involved in parsing and executing code. +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 20 +#endif + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in an unsigned char.) +*/ +#define MAXUPVAL UCHAR_MAX + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions on threads when you defined +** LUAI_EXTRASPACE and need to do something extra when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + +/* +** lua_number2int is a macro to convert lua_Number to int. +** lua_number2integer is a macro to convert lua_Number to lua_Integer. +** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. +** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. +** luai_hashnum is a macro to hash a lua_Number value into an integer. +** The hash must be deterministic and give reasonable values for +** both small and large values (outside the range of integers). +*/ + +#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ +/* trick with Microsoft assembler for X86 */ + +#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} +#define lua_number2integer(i,n) lua_number2int(i, n) +#define lua_number2unsigned(i,n) \ + {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} + + +#elif defined(LUA_IEEE754TRICK) /* }{ */ +/* the next trick should work on any machine using IEEE754 with + a 32-bit int type */ + +union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; + +#if !defined(LUA_IEEEENDIAN) /* { */ +#define LUAI_EXTRAIEEE \ + static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; +#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) +#else +#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN +#define LUAI_EXTRAIEEE /* empty */ +#endif /* } */ + +#define lua_number2int32(i,n,t) \ + { LUAI_EXTRAIEEE \ + volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ + (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } + +#define luai_hashnum(i,n) \ + { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ + (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ + +#define lua_number2int(i,n) lua_number2int32(i, n, int) +#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) + +/* the trick can be expanded to lua_Integer when it is a 32-bit value */ +#if defined(LUA_IEEELL) +#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) +#endif + +#endif /* } */ + + +/* the following definitions always work, but may be slow */ + +#if !defined(lua_number2int) +#define lua_number2int(i,n) ((i)=(int)(n)) +#endif + +#if !defined(lua_number2integer) +#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) +#endif + +#if !defined(lua_number2unsigned) /* { */ +/* the following definition assures proper modulo behavior */ +#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) +#include +#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) +#define lua_number2unsigned(i,n) \ + ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) +#else +#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) +#endif +#endif /* } */ + + +#if !defined(lua_unsigned2number) +/* on several machines, coercion from unsigned to double is slow, + so it may be worth to avoid */ +#define lua_unsigned2number(u) \ + (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) +#endif + + + +#if defined(ltable_c) && !defined(luai_hashnum) + +extern int lcompat_hashnum(int64_t); + +#define luai_hashnum(i,n) (i = lcompat_hashnum(n)) + +#endif + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L) condmovestack(L) +#else +#define condchangemem(L) \ + ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) +#endif + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.c new file mode 100644 index 000000000000..0d070fbde83c --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.c @@ -0,0 +1,99 @@ +/* +** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no +** matter 'x'). +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL); +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *what) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +l_noret luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; + global_State *g = G(L); + size_t realosize = (block) ? osize : 0; + lua_assert((realosize == 0) == (block == NULL)); +#if defined(HARDMEMTESTS) + if (nsize > realosize && g->gcrunning) + luaC_fullgc(L, 1); /* force a GC whenever possible */ +#endif + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) { + api_check(L, nsize > realosize, + "realloc cannot fail when shrinking a block"); + if (g->gcrunning) { + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - realosize; + return newblock; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.h new file mode 100644 index 000000000000..c75a3d50984a --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.h @@ -0,0 +1,57 @@ +/* +** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +/* +** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is +** always constant. +** The macro is somewhat complex to avoid warnings: +** +1 avoids warnings of "comparison has constant result"; +** cast to 'void' avoids warnings of "value unused". +*/ +#define luaM_reallocv(L,b,on,n,e) \ + (cast(void, \ + (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e))) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) + +#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *what); + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.c new file mode 100644 index 000000000000..339c84d21d79 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.c @@ -0,0 +1,283 @@ +/* +** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* exponent */ + if (x < 8) return x; + while (x >= 0x10) { + x = (x+1) >> 1; + e++; + } + return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 0x1f; + if (e == 0) return x; + else return ((x & 7) + 8) << (e - 1); +} + + +int luaO_ceillog2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = 0; + x--; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; +} + + +lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(NULL, v1, v2); + case LUA_OPSUB: return luai_numsub(NULL, v1, v2); + case LUA_OPMUL: return luai_nummul(NULL, v1, v2); + case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); + case LUA_OPMOD: return luai_nummod(NULL, v1, v2); + case LUA_OPPOW: return luai_numpow(NULL, v1, v2); + case LUA_OPUNM: return luai_numunm(NULL, v1); + default: lua_assert(0); return 0; + } +} + + +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return ltolower(c) - 'a' + 10; +} + + +#if !defined(lua_strx2number) + + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + +static lua_Number readhexa (const char **s, lua_Number r, int *count) { + for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */ + r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s))); + (*count)++; + } + return r; +} + + +/* +** convert an hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + lua_Number r = 0.0; + int e = 0, i = 0; + int neg = 0; /* 1 if number is negative */ + *endptr = cast(char *, s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check signal */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return 0.0; /* invalid format (no '0x') */ + s += 2; /* skip '0x' */ + r = readhexa(&s, r, &i); /* read integer part */ + if (*s == '.') { + s++; /* skip dot */ + r = readhexa(&s, r, &e); /* read fractional part */ + } + if (i == 0 && e == 0) + return 0.0; /* invalid format (no digit) */ + e *= -4; /* each fractional digit divides value by 2^-4 */ + *endptr = cast(char *, s); /* valid up to here */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; + int neg1; + s++; /* skip 'p' */ + neg1 = isneg(&s); /* signal */ + if (!lisdigit(cast_uchar(*s))) + goto ret; /* must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + } + *endptr = cast(char *, s); /* valid up to here */ + ret: + if (neg) r = -r; + return (r * (1 << e)); +} + +#endif + + +int luaO_str2d (const char *s, size_t len, lua_Number *result) { + char *endptr; + if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ + return 0; + else if (strpbrk(s, "xX")) /* hexa? */ + *result = lua_strx2number(s, &endptr); + else + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* nothing recognized */ + while (lisspace(cast_uchar(*endptr))) endptr++; + return (endptr == s + len); /* OK if no trailing characters */ +} + + + +static void pushstr (lua_State *L, const char *str, size_t l) { + setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 0; + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + luaD_checkstack(L, 2); /* fmt + item */ + pushstr(L, fmt, e - fmt); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s, strlen(s)); + break; + } + case 'c': { + char buff; + buff = cast(char, va_arg(argp, int)); + pushstr(L, &buff, 1); + break; + } + case 'd': { + setnvalue(L->top++, cast_num(va_arg(argp, int))); + break; + } + case 'f': { + setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + int l = lcompat_sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff, l); + break; + } + case '%': { + pushstr(L, "%", 1); + break; + } + default: { + luaG_runerror(L, + "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), + *(e + 1)); + } + } + n += 2; + fmt = e+2; + } + luaD_checkstack(L, 1); + pushstr(L, fmt, strlen(fmt)); + if (n > 0) luaV_concat(L, n + 1); + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + size_t l = strlen(source); + if (*source == '=') { /* 'literal' source */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') { /* file name */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); + } + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (l < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, l); /* keep it */ + } + else { + if (nl != NULL) l = nl - source; /* stop at first newline */ + if (l > bufflen) l = bufflen; + addstr(out, source, l); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.h new file mode 100644 index 000000000000..9c9f23542867 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.h @@ -0,0 +1,606 @@ +/* +** $Id: lobject.h,v 2.71.1.2 2014/05/07 14:14:58 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO LUA_NUMTAGS +#define LUA_TUPVAL (LUA_NUMTAGS+1) +#define LUA_TDEADKEY (LUA_NUMTAGS+2) + +/* +** number of all possible tags (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTAGS (LUA_TUPVAL+2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* value) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +#define VARBITS (3 << 4) + + +/* +** LUA_TFUNCTION variants: +** 0 - Lua function +** 1 - light C function +** 2 - regular C function (closure) +*/ + +/* Variant tags for functions */ +#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ +#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ +#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ + + +/* Variant tags for strings */ +#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ +#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + +/* +** Union of all Lua values +*/ +typedef union Value Value; + + +#define numfield lua_Number n; /* numbers */ + + + +/* +** Tagged Values. This is the basic representation of values in Lua, +** an actual value plus a tag with its type. +*/ + +#define TValuefields Value value_; int tt_ + +typedef struct lua_TValue TValue; + + +/* macro defining a nil value */ +#define NILCONSTANT {NULL}, LUA_TNIL + + +#define val_(o) ((o)->value_) +#define num_(o) (val_(o).n) + + +/* raw type tag of a TValue */ +#define rttype(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(x) ((x) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define ttype(o) (rttype(o) & 0x3F) + +/* type tag of a TValue with no variants (bits 0-3) */ +#define ttypenv(o) (novariant(rttype(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rttype(o) == (t)) +#define checktype(o,t) (ttypenv(o) == (t)) +#define ttisnumber(o) checktag((o), LUA_TNUMBER) +#define ttisnil(o) checktag((o), LUA_TNIL) +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) +#define ttislcf(o) checktag((o), LUA_TLCF) +#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) +#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) +#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) + +#define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) + +/* Macros to access values */ +#define nvalue(o) check_exp(ttisnumber(o), num_(o)) +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) +#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) +#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) +#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) +/* a dead value may get the 'gc' field, but cannot access its contents */ +#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + + +#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) + + +/* Macros for internal tests */ +#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) + +#define checkliveness(g,obj) \ + lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && !isdead(g,gcvalue(obj)))) + + +/* Macros to set values */ +#define settt_(o,t) ((o)->tt_=(t)) + +#define setnvalue(obj,x) \ + { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } + +#define setnilvalue(obj) settt_(obj, LUA_TNIL) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } + +#define setbvalue(obj,x) \ + { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } + +#define setgcovalue(L,obj,x) \ + { TValue *io=(obj); GCObject *i_g=(x); \ + val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } + +#define setsvalue(L,obj,x) \ + { TValue *io=(obj); \ + TString *x_ = (x); \ + val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \ + checkliveness(G(L),io); } + +#define setuvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ + checkliveness(G(L),io); } + +#define setthvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ + checkliveness(G(L),io); } + +#define setclLvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ + checkliveness(G(L),io); } + +#define setclCvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ + checkliveness(G(L),io); } + +#define sethvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ + checkliveness(G(L),io); } + +#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) + + + +#define setobj(L,obj1,obj2) \ + { const TValue *io2=(obj2); TValue *io1=(obj1); \ + io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ + checkliveness(G(L),io1); } + + +/* +** different types of assignments, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + + +/* check whether a number is valid (useful only for NaN trick) */ +#define luai_checknum(L,o,c) { /* empty */ } + + +/* +** {====================================================== +** NaN Trick +** ======================================================= +*/ +#if defined(LUA_NANTRICK) + +/* +** numbers are represented in the 'd_' field. All other values have the +** value (NNMARK | tag) in 'tt__'. A number with such pattern would be +** a "signaled NaN", which is never generated by regular operations by +** the CPU (nor by 'strtod') +*/ + +/* allows for external implementation for part of the trick */ +#if !defined(NNMARK) /* { */ + + +#if !defined(LUA_IEEEENDIAN) +#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' +#endif + + +#define NNMARK 0x7FF7A500 +#define NNMASK 0x7FFFFF00 + +#undef TValuefields +#undef NILCONSTANT + +#if (LUA_IEEEENDIAN == 0) /* { */ + +/* little endian */ +#define TValuefields \ + union { struct { Value v__; int tt__; } i; double d__; } u +#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#else /* }{ */ + +/* big endian */ +#define TValuefields \ + union { struct { int tt__; Value v__; } i; double d__; } u +#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#endif /* } */ + +#endif /* } */ + + +/* correspondence with standard representation */ +#undef val_ +#define val_(o) v_(o) +#undef num_ +#define num_(o) d_(o) + + +#undef numfield +#define numfield /* no such field; numbers are the entire struct */ + +/* basic check to distinguish numbers from non-numbers */ +#undef ttisnumber +#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) + +#define tag2tt(t) (NNMARK | (t)) + +#undef rttype +#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) + +#undef settt_ +#define settt_(o,t) (tt_(o) = tag2tt(t)) + +#undef setnvalue +#define setnvalue(obj,x) \ + { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } + +#undef setobj +#define setobj(L,obj1,obj2) \ + { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ + o1_->u = o2_->u; \ + checkliveness(G(L),o1_); } + + +/* +** these redefinitions are not mandatory, but these forms are more efficient +*/ + +#undef checktag +#undef checktype +#define checktag(o,t) (tt_(o) == tag2tt(t)) +#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) + +#undef ttisequal +#define ttisequal(o1,o2) \ + (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) + + +#undef luai_checknum +#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } + +#endif +/* }====================================================== */ + + + +/* +** {====================================================== +** types and prototypes +** ======================================================= +*/ + + +union Value { + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + numfield /* numbers */ +}; + + +struct lua_TValue { + TValuefields; +}; + + +typedef TValue *StkId; /* index to stack elements */ + + + + +/* +** Header for string value; string bytes follow the end of this structure +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + unsigned int hash; + size_t len; /* number of characters in string */ + } tsv; +} TString; + + +/* get the actual string (array of bytes) from a TString */ +#define getstr(ts) cast(const char *, (ts) + 1) + +/* get the actual string (array of bytes) from a Lua value */ +#define svalue(o) getstr(rawtsvalue(o)) + + +/* +** Header for userdata; memory area follows the end of this structure +*/ +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; /* number of bytes */ + } uv; +} Udata; + + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines (debug information) */ + LocVar *locvars; /* information about local variables (debug information) */ + Upvaldesc *upvalues; /* upvalue information */ + union Closure *cache; /* last created closure with this prototype */ + TString *source; /* used for debug information */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte numparams; /* number of fixed parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* maximum stack used by this function */ +} Proto; + + + +/* +** Lua Upvalues +*/ +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define isLfunction(o) ttisLclosure(o) + +#define getproto(o) (clLvalue(o)->p) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +/* +** (address of) a fixed nil value +*/ +#define luaO_nilobject (&luaO_nilobject_) + + +LUAI_DDEC const TValue luaO_nilobject_; + + +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); +LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.c new file mode 100644 index 000000000000..4190dc762428 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.c @@ -0,0 +1,107 @@ +/* +** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADKX", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETTABUP", + "GETTABLE", + "SETTABUP", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "EXTRAARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ +}; + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.h new file mode 100644 index 000000000000..8e2f80a13141 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.h @@ -0,0 +1,288 @@ +/* +** $Id: lopcodes.h,v 1.142.1.2 2014/10/20 18:32:09 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + 'Ax' : 26 bits ('A', 'B', and 'C' together) + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C +#define POS_Ax POS_A + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + +#if SIZE_Ax < LUAI_BITSINT-1 +#define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>pos) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<= R(A - 1) */ +OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ +OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ +OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ + +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) > 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.c new file mode 100644 index 000000000000..73f1af64f834 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.c @@ -0,0 +1,1637 @@ +/* +** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + short firstlabel; /* index of first label in this block */ + short firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void statement (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + /* last token from outer function must be EOS */ + lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +/* semantic error */ +static l_noret semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove 'near to' from final message */ + luaX_syntaxerror(ls, msg); +} + + +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname (LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +static void new_localvar (LexState *ls, TString *name) { + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + int reg = registerlocalvar(ls, name); + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); + dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); +} + + +static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { + new_localvar(ls, luaX_newstring(ls, name, sz)); +} + +#define new_localvarliteral(ls,v) \ + new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) + + +static LocVar *getlocvar (FuncState *fs, int i) { + int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; + lua_assert(idx < fs->nlocvars); + return &fs->f->locvars[idx]; +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; + } +} + + +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar)->endpc = fs->pc; +} + + +static int searchupvalue (FuncState *fs, TString *name) { + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (luaS_eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].instack = (v->k == VLOCAL); + f->upvalues[fs->nups].idx = cast_byte(v->u.info); + f->upvalues[fs->nups].name = name; + luaC_objbarrier(fs->ls->L, f, name); + return fs->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + if (luaS_eqstr(n, getlocvar(fs, i)->varname)) + return i; + } + return -1; /* not found */ +} + + +/* + Mark block where variable at given level was defined + (to emit close instructions later). +*/ +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) bl = bl->previous; + bl->upval = 1; +} + + +/* + Find variable with given name 'n'. If it is an upvalue, add this + upvalue into all intermediate functions. +*/ +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + return VVOID; /* default is global */ + else { + int v = searchvar(fs, n); /* look up locals at current level */ + if (v >= 0) { /* found? */ + init_exp(var, VLOCAL, v); /* variable is local */ + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ + return VVOID; /* not found; is a global */ + /* else was LOCAL or UPVAL */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + } + init_exp(var, VUPVAL, idx); + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k == VLOCAL || var->k == VUPVAL); + codestring(ls, &key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + lua_State *L = ls->L; + ++L->nCcalls; + checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void closegoto (LexState *ls, int g, Labeldesc *label) { + int i; + FuncState *fs = ls->fs; + Labellist *gl = &ls->dyd->gt; + Labeldesc *gt = &gl->arr[g]; + lua_assert(luaS_eqstr(gt->name, label->name)); + if (gt->nactvar < label->nactvar) { + TString *vname = getlocvar(fs, gt->nactvar)->varname; + const char *msg = luaO_pushfstring(ls->L, + " at line %d jumps into the scope of local " LUA_QS, + getstr(gt->name), gt->line, getstr(vname)); + semerror(ls, msg); + } + luaK_patchlist(fs, gt->pc, label->pc); + /* remove goto from pending list */ + for (i = g; i < gl->n - 1; i++) + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** try to close a goto with existing labels; this solves backward jumps +*/ +static int findlabel (LexState *ls, int g) { + int i; + BlockCnt *bl = ls->fs->bl; + Dyndata *dyd = ls->dyd; + Labeldesc *gt = &dyd->gt.arr[g]; + /* check labels in current block for a match */ + for (i = bl->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ + if (gt->nactvar > lb->nactvar && + (bl->upval || dyd->label.n > bl->firstlabel)) + luaK_patchclose(ls->fs, gt->pc, lb->nactvar); + closegoto(ls, g, lb); /* close it */ + return 1; + } + } + return 0; /* label not found; cannot close goto */ +} + + +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].pc = pc; + l->n++; + return n; +} + + +/* +** check whether new label 'lb' matches any pending gotos in current +** block; solves forward jumps +*/ +static void findgotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + while (i < gl->n) { + if (luaS_eqstr(gl->arr[i].name, lb->name)) + closegoto(ls, i, lb); + else + i++; + } +} + + +/* +** "export" pending gotos to outer level, to check them against +** outer labels; if the block being exited has upvalues, and +** the goto exits the scope of any variable (which can be the +** upvalue), close those variables being exited. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i = bl->firstgoto; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block and try to close it + with visible labels */ + while (i < gl->n) { + Labeldesc *gt = &gl->arr[i]; + if (gt->nactvar > bl->nactvar) { + if (bl->upval) + luaK_patchclose(fs, gt->pc, bl->nactvar); + gt->nactvar = bl->nactvar; + } + if (!findlabel(fs->ls, i)) + i++; /* move to next one */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +/* +** create a label named "break" to resolve break statements +*/ +static void breaklabel (LexState *ls) { + TString *n = luaS_new(ls->L, "break"); + int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); + findgotos(ls, &ls->dyd->label.arr[l]); +} + +/* +** generates an error for an undefined 'goto'; choose appropriate +** message when label name is a reserved word (which can only be 'break') +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg = isreserved(gt->name) + ? "<%s> at line %d not inside a loop" + : "no visible label " LUA_QS " for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + semerror(ls, msg); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + if (bl->previous && bl->upval) { + /* create a 'jump to here' to close upvalues */ + int j = luaK_jump(fs); + luaK_patchclose(fs, j, bl->nactvar); + luaK_patchtohere(fs, j); + } + if (bl->isloop) + breaklabel(ls); /* close pending breaks */ + fs->bl = bl->previous; + removevars(fs, bl->nactvar); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + if (bl->previous) /* inner block? */ + movegotosout(fs, bl); /* update pending gotos to outer block */ + else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ +} + + +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction must use the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + lua_State *L = ls->L; + Proto *f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nups = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->bl = NULL; + f = fs->f; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L); + /* anchor table of constants (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + enterblock(fs, bl, 0); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, 0, 0); /* final return */ + leaveblock(fs); + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + /* last token read was anchored in defunct function; must re-anchor it */ + anchor_token(ls); + L->top--; /* pop table of constants */ + luaC_checkGC(L); +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [`;'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + /* listfield -> exp */ + expr(ls, &cc->v); + checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void field (LexState *ls, struct ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); + f->is_vararg = 1; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> `(' parlist `)' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); +} + + +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f, int line) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist ] `)' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } +} + + +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v, line); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v, line); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ + {10, 9}, {5, 4}, /* ^, .. (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + int line = ls->linenumber; + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static void block (LexState *ls) { + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (lh->v.k == VINDEXED) { /* assigning to a table? */ + /* table is the upvalue/local being assigned now? */ + if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { + conflict = 1; + lh->v.u.ind.vt = VLOCAL; + lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ + } + /* index is the local being assigned? (index cannot be upvalue) */ + if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + /* copy upvalue/local value to a temporary (in position 'extra') */ + OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (nv.v.k != VINDEXED) + check_conflict(ls, lh, &nv.v); + checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, + "C levels"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void gotostat (LexState *ls, int pc) { + int line = ls->linenumber; + TString *label; + int g; + if (testnext(ls, TK_GOTO)) + label = str_checkname(ls); + else { + luaX_next(ls); /* skip break */ + label = luaS_new(ls->L, "break"); + } + g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); + findlabel(ls, g); /* close it if label already defined */ +} + + +/* check for repeated labels on the same block */ +static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { + int i; + for (i = fs->bl->firstlabel; i < ll->n; i++) { + if (luaS_eqstr(label, ll->arr[i].name)) { + const char *msg = luaO_pushfstring(fs->ls->L, + "label " LUA_QS " already defined on line %d", + getstr(label), ll->arr[i].line); + semerror(fs->ls, msg); + } + } +} + + +/* skip no-op statements */ +static void skipnoopstat (LexState *ls) { + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); +} + + +static void labelstat (LexState *ls, TString *label, int line) { + /* label -> '::' NAME '::' */ + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l; /* index of new label being created */ + checkrepeated(fs, ll, label); /* check for repeated labels */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + /* create new entry for this label */ + l = newlabelentry(ls, ll, label, line, fs->pc); + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + findgotos(ls, &ll->arr[l]); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (bl2.upval) /* upvalues? */ + luaK_patchclose(fs, condexit, bl2.nactvar); + leaveblock(fs); /* finish scope */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int reg; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); + reg = e.u.info; + return reg; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + if (isnum) /* numeric for? */ + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + else { /* generic for */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); + } + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 4; /* gen, state, control, plus at least one declared var */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static void test_then_block (LexState *ls, int *escapelist) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { + luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + gotostat(ls, v.t); /* handle goto/break */ + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not goto/break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* `then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* `else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +} + + +static void localfunc (LexState *ls) { + expdesc b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + getlocvar(fs, b.u.info)->startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls)); + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {fieldsel} [`:' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + v.prev = NULL; + assignment(ls, &v, 1); + } + else { /* stat -> func */ + check_condition(ls, v.v.k == VCALL, "syntax error"); + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + if (block_follow(ls, 1) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ +} + + +static void statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: /* stat -> breakstat */ + case TK_GOTO: { /* stat -> 'goto' NAME */ + gotostat(ls, luaK_jump(ls->fs)); + break; + } + default: { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + leavelevel(ls); +} + +/* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + expdesc v; + open_func(ls, fs, &bl); + fs->f->is_vararg = 1; /* main function is always vararg */ + init_exp(&v, VLOCAL, 0); /* create and... */ + newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ + /* anchor closure (to avoid being collected) */ + setclLvalue(L, L->top, cl); + incr_top(L); + funcstate.f = cl->l.p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + return cl; /* it's on the stack too */ +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.h new file mode 100644 index 000000000000..0346e3c41a80 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.h @@ -0,0 +1,119 @@ +/* +** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VNONRELOC, /* info = result register */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in 'upvalues' */ + VINDEXED, /* t = table register/upvalue; idx = index R/K */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) +#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) + +typedef struct expdesc { + expkind k; + union { + struct { /* for indexed variables (VINDEXED) */ + short idx; /* index (R/K) */ + lu_byte t; /* table (register or upvalue) */ + lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ + } ind; + int info; /* for generic use */ + lua_Number nval; /* for VKNUM */ + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +/* description of active local variable */ +typedef struct Vardesc { + short idx; /* variable index in stack */ +} Vardesc; + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* local level where it appears in current block */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int jpc; /* list of pending jumps to `pc' */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + short nlocvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ +} FuncState; + + +LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.c new file mode 100644 index 000000000000..b98ce5c2b52b --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.c @@ -0,0 +1,321 @@ +/* +** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#if !defined(LUAI_GCPAUSE) +#define LUAI_GCPAUSE 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMAJOR) +#define LUAI_GCMAJOR 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMUL) +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#endif + + +#define MEMERRMSG "not enough memory" + + +/* +** a macro to help the creation of a unique random seed when a state is +** created; the seed is used to randomize hashes. +*/ +#if !defined(luai_makeseed) +#define luai_makeseed() cast(unsigned int, gethrtime()) +#endif + + + +/* +** thread state + extra space +*/ +typedef struct LX { +#if defined(LUAI_EXTRASPACE) + char buff[LUAI_EXTRASPACE]; +#endif + lua_State l; +} LX; + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + LX l; + global_State g; +} LG; + + + +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) + + +/* +** Compute an initial seed as random as possible. In ANSI, rely on +** Address Space Layout Randomization (if present) to increase +** randomness.. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast(size_t, e); \ + memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int makeseed (lua_State *L) { + char buff[4 * sizeof(size_t)]; + unsigned int h = luai_makeseed(); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, luaO_nilobject); /* global variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); +} + + +/* +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + g->totalbytes -= (debt - g->GCdebt); + g->GCdebt = debt; +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + return ci; +} + + +void luaE_freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + } +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); + L1->stacksize = BASIC_STACK_SIZE; + for (i = 0; i < BASIC_STACK_SIZE; i++) + setnilvalue(L1->stack + i); /* erase new stack */ + L1->top = L1->stack; + L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = 0; + ci->func = L1->top; + setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ + ci->top = L1->top + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + luaE_freeCI(L); + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + TValue mt; + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, &mt, L); + luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); + /* registry[LUA_RIDX_GLOBALS] = table of globals */ + sethvalue(L, &mt, luaH_new(L)); + luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); +} + + +/* +** open parts of the state that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaS_fix(g->memerrmsg); /* it should never be collected */ + g->gcrunning = 1; /* allow gc */ + g->version = lua_version(NULL); + luai_userstateopen(L); +} + + +/* +** preinitialize a state with consistent values without allocating +** any memory (to avoid errors) +*/ +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->ci = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->nCcalls = 0; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->nny = 1; + L->status = LUA_OK; + L->errfunc = 0; +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeallobjects(L); /* collect all objects */ + if (g->version) /* closing a fully built state? */ + luai_userstateclose(L); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + luaZ_freebuffer(L, &g->buff); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; + setthvalue(L, L->top, L1); + api_incr_top(L); + preinit_state(L1, G(L)); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + g->gckind = KGC_NORMAL; + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->seed = makeseed(L); + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->gcrunning = 0; /* no GC while building state */ + g->GCestimate = 0; + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->version = NULL; + g->gcstate = GCSpause; + g->allgc = NULL; + g->finobj = NULL; + g->tobefnz = NULL; + g->sweepgc = g->sweepfin = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->gcpause = LUAI_GCPAUSE; + g->gcmajorinc = LUAI_GCMAJOR; + g->gcstepmul = LUAI_GCMUL; + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + close_state(L); +} + + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.h new file mode 100644 index 000000000000..daffd9aacfbb --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.h @@ -0,0 +1,228 @@ +/* +** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* + +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed. +** +** Lua keeps most objects linked in list g->allgc. The link uses field +** 'next' of the CommonHeader. +** +** Strings are kept in several lists headed by the array g->strt.hash. +** +** Open upvalues are not subject to independent garbage collection. They +** are collected together with their respective threads. Lua keeps a +** double-linked list with all open upvalues (g->uvhead) so that it can +** mark objects referred by them. (They are always gray, so they must +** be remarked in the atomic step. Usually their contents would be marked +** when traversing the respective threads, but the thread may already be +** dead, while the upvalue is still accessible through closures.) +** +** Objects with finalizers are kept in the list g->finobj. +** +** The list g->tobefnz links all objects being finalized. + +*/ + + +struct lua_longjmp; /* defined in ldo.c */ + + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + +/* kinds of Garbage Collection */ +#define KGC_NORMAL 0 +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ +#define KGC_GEN 2 /* generational collection */ + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** information about a call +*/ +typedef struct CallInfo { + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + short nresults; /* expected number of results from this function */ + lu_byte callstatus; + ptrdiff_t extra; + union { + struct { /* only for Lua functions */ + StkId base; /* base for this function */ + const Instruction *savedpc; + } l; + struct { /* only for C functions */ + int ctx; /* context info. in case of yields */ + lua_CFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lu_byte old_allowhook; + lu_byte status; + } c; + } u; +} CallInfo; + + +/* +** Bits in CallInfo status +*/ +#define CIST_LUA (1<<0) /* call is running a Lua function */ +#define CIST_HOOKED (1<<1) /* call is running a debug hook */ +#define CIST_REENTRY (1<<2) /* call is running on same invocation of + luaV_execute of previous call */ +#define CIST_YIELDED (1<<3) /* call reentered after suspension */ +#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ +#define CIST_STAT (1<<5) /* call has an error status (pcall) */ +#define CIST_TAIL (1<<6) /* call was tail called */ +#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ + + +#define isLua(ci) ((ci)->callstatus & CIST_LUA) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCmemtrav; /* memory traversed by the GC */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcrunning; /* true if GC is running */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *allgc; /* list of all collectable objects */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject **sweepgc; /* current position of sweep in list 'allgc' */ + GCObject **sweepfin; /* current position of sweep in list 'finobj' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + UpVal uvhead; /* head of double-linked list of all open upvalues */ + Mbuffer buff; /* temporary buffer for string concatenation */ + int gcpause; /* size of pause between successive GCs */ + int gcmajorinc; /* pause between major collections (only in gen. mode) */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + const lua_Number *version; /* pointer to version number */ + TString *memerrmsg; /* memory-error message */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *oldpc; /* last pc traced */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + int stacksize; + unsigned short nny; /* number of non-yieldable calls in stack */ + unsigned short nCcalls; /* number of nested C calls */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; /* common header */ + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +#define gch(o) (&(o)->gch) + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) +#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) +#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_freeCI (lua_State *L); + + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.c new file mode 100644 index 000000000000..e20ab04b12de --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.c @@ -0,0 +1,185 @@ +/* +** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to +** compute its hash +*/ +#if !defined(LUAI_HASHLIMIT) +#define LUAI_HASHLIMIT 5 +#endif + + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->tsv.len; + lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->tsv.len) && /* equal length and ... */ + (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ +} + + +/* +** equality for strings +*/ +int luaS_eqstr (TString *a, TString *b) { + return (a->tsv.tt == b->tsv.tt) && + (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast(unsigned int, l); + size_t l1; + size_t step = (l >> LUAI_HASHLIMIT) + 1; + for (l1 = l; l1 >= step; l1 -= step) + h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); + return h; +} + + +/* +** resizes the string table +*/ +void luaS_resize (lua_State *L, int newsize) { + int i; + stringtable *tb = &G(L)->strt; + /* cannot resize while GC is traversing strings */ + luaC_runtilstate(L, ~bitmask(GCSsweepstring)); + if (newsize > tb->size) { + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; + } + /* rehash */ + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) { /* for each node in the list */ + GCObject *next = gch(p)->next; /* save next */ + unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ + gch(p)->next = tb->hash[h]; /* chain it */ + tb->hash[h] = p; + resetoldbit(p); /* see MOVE OLD rule */ + p = next; + } + } + if (newsize < tb->size) { + /* shrinking slice must be empty */ + lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + } + tb->size = newsize; +} + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, const char *str, size_t l, + int tag, unsigned int h, GCObject **list) { + TString *ts; + size_t totalsize; /* total size of TString object */ + totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); + ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.extra = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + return ts; +} + + +/* +** creates a new short string, inserting it into string table +*/ +static TString *newshrstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + GCObject **list; /* (pointer to) list where it will be inserted */ + stringtable *tb = &G(L)->strt; + TString *s; + if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + list = &tb->hash[lmod(h, tb->size)]; + s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); + tb->nuse++; + return s; +} + + +/* +** checks whether short string exists and reuses it or creates a new one +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + global_State *g = G(L); + unsigned int h = luaS_hash(str, l, g->seed); + for (o = g->strt.hash[lmod(h, g->strt.size)]; + o != NULL; + o = gch(o)->next) { + TString *ts = rawgco2ts(o); + if (h == ts->tsv.hash && + l == ts->tsv.len && + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { + if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ + changewhite(o); /* resurrect it */ + return ts; + } + } + return newshrstr(L, str, l, h); /* not found; create a new string */ +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); + } +} + + +/* +** new zero-terminated string +*/ +TString *luaS_new (lua_State *L, const char *str) { + return luaS_newlstr(L, str, strlen(str)); +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + return u; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.h new file mode 100644 index 000000000000..260e7f169bd0 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.h @@ -0,0 +1,46 @@ +/* +** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC int luaS_eqstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstrlib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstrlib.c new file mode 100644 index 000000000000..324548ed1ff3 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstrlib.c @@ -0,0 +1,1050 @@ +/* +** $Id: lstrlib.c,v 1.178.1.1 2013/04/12 18:48:47 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + +/* + * PATCHED: add missing character macros. + */ +#ifdef illumos +#define tolower(C) (((C) >= 'A' && (C) <= 'Z') ? (C) - 'A' + 'a' : (C)) +#define toupper(C) (((C) >= 'a' && (C) <= 'z') ? (C) - 'a' + 'A': (C)) +#define iscntrl(C) ((((C) >= 0) && ((C) <= 0x1f)) || ((C) == 0x7f)) +#else +#define isalnum(C) (isalpha(C) || isdigit(C)) +#define iscntrl(C) (uchar(C) <= 0x1f || uchar(C) == 0x7f) +#endif +#define isgraph(C) ((C) >= 0x21 && (C) <= 0x7E) +#define ispunct(C) (((C) >= 0x21 && (C) <= 0x2F) || \ + ((C) >= 0x3A && (C) <= 0x40) || \ + ((C) >= 0x5B && (C) <= 0x60) || \ + ((C) >= 0x7B && (C) <= 0x7E)) + +/* + * The provided version of sprintf returns a char *, but str_format expects + * it to return the number of characters printed. This version has the expected + * behavior. + */ +static size_t str_sprintf(char *buf, const char *fmt, ...) { + va_list args; + size_t len; + + va_start(args, fmt); + len = vsnprintf(buf, INT_MAX, fmt, args); + va_end(args); + + return len; +} + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; +} + + +/* translate a relative string position: negative means back from end */ +static size_t posrelat (ptrdiff_t pos, size_t len) { + if (pos >= 0) return (size_t)pos; + else if (0u - (size_t)pos > len) return 0; + else return len - ((size_t)-pos) + 1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t start = posrelat(luaL_checkinteger(L, 2), l); + size_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > l) end = l; + if (start <= end) + lua_pushlstring(L, s + start - 1, end - start + 1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i=0; i> 1) + +static int str_rep (lua_State *L) { + size_t l, lsep; + const char *s = luaL_checklstring(L, 1, &l); + int n = luaL_checkint(L, 2); + const char *sep = luaL_optlstring(L, 3, "", &lsep); + if (n <= 0) lua_pushliteral(L, ""); + else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = n * l + (n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ + memcpy(p, sep, lsep * sizeof(char)); p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi < 1) posi = 1; + if (pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* (size_t -> int) overflow? */ + return luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; /* deprecated option */ + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } + } +} + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (p >= ms->p_end - 1) + luaL_error(ms->L, "malformed pattern " + "(missing arguments to " LUA_QL("%%b") ")"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); + init: /* using goto's to optimize tail recursion */ + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; + } + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* go through */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) init = 1; + else if (init > ls + 1) { /* start after string's end? */ + lua_pushnil(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { + /* do a plain search */ + const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); + if (s2) { + lua_pushinteger(L, s2 - s + 1); + lua_pushinteger(L, s2 - s + lp); + return 2; + } + } + else { + MatchState ms; + const char *s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s + ls; + ms.p_end = p + lp; + do { + const char *res; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1 - s + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls, lp; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); + const char *src; + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s+ls; + ms.p_end = p + lp; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int str_gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) { + if (news[i] != L_ESC) + luaL_error(ms->L, "invalid use of " LUA_QL("%c") + " in replacement string", L_ESC); + luaL_addchar(b, news[i]); + } + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) { + lua_State *L = ms->L; + switch (tr) { + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); + return; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checklstring(L, 2, &lp); + int tr = lua_type(L, 3); + size_t max_s = luaL_optinteger(L, 4, srcl+1); + int anchor = (*p == '^'); + size_t n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = src; + ms.src_end = src+srcl; + ms.p_end = p + lp; + while (n < max_s) { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e, tr); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +/* +** LUA_INTFRMLEN is the length modifier for integer conversions in +** 'string.format'; LUA_INTFRM_T is the integer type corresponding to +** the previous length +*/ +#if !defined(LUA_INTFRMLEN) /* { */ +#if defined(LUA_USE_LONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif +#endif /* } */ + + +/* +** LUA_FLTFRMLEN is the length modifier for float conversions in +** 'string.format'; LUA_FLTFRM_T is the float type corresponding to +** the previous length +*/ +#if !defined(LUA_FLTFRMLEN) + +#define LUA_FLTFRMLEN "" +#define LUA_FLTFRM_T double + +#endif + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (*s == '\0' || iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + sprintf(buff, "\\%d", (int)uchar(*s)); + else + sprintf(buff, "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ + int nb = 0; /* number of bytes in added item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + nb = str_sprintf(buff, form, luaL_checkint(L, arg)); + break; + } + case 'd': case 'i': { + lua_Number n = luaL_checknumber(L, arg); + LUA_INTFRM_T ni = (LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = str_sprintf(buff, form, ni); + break; + } + case 'o': case 'u': case 'x': case 'X': { + lua_Number n = luaL_checknumber(L, arg); + unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a non-negative number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = str_sprintf(buff, form, ni); + break; + } +#if defined(LUA_USE_FLOAT_FORMATS) + case 'e': case 'E': case 'f': +#if defined(LUA_USE_AFORMAT) + case 'a': case 'A': +#endif + case 'g': case 'G': { + addlenmod(form, LUA_FLTFRMLEN); + nb = str_sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); + break; + } +#endif + case 'q': { + addquoted(L, &b, arg); + break; + } + case 's': { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + luaL_addvalue(&b); + break; + } + else { + nb = str_sprintf(buff, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; +} + +/* }====================================================== */ + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", str_gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* table to be metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); + createmetatable(L); + return 1; +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.c new file mode 100644 index 000000000000..a5279011c4fb --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.c @@ -0,0 +1,588 @@ +/* +** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT >= 32 +#define MAXBITS 30 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +#define dummynode (&dummynode_) + +#define isdummy(n) ((n) == dummynode) + +static const Node dummynode_ = { + {NILCONSTANT}, /* value */ + {{NILCONSTANT, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + int i; + luai_hashnum(i, n); + if (i < 0) { + if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ + i = 0; /* handle INT_MIN */ + i = -i; /* must be a positive value */ + } + return hashmod(t, i); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TLNGSTR: { + TString *s = rawtsvalue(key); + if (s->tsv.extra == 0) { /* no hash? */ + s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); + s->tsv.extra = 1; /* now it has its hash */ + } + return hashstr(t, rawtsvalue(key)); + } + case LUA_TSHRSTR: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + case LUA_TLCF: + return hashpointer(t, fvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signaled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + for (;;) { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaV_rawequalobj(gkey(n), key) || + (ttisdeadkey(gkey(n)) && iscollectable(key) && + deadvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + if (n == NULL) + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + } + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(gkey(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = luaO_ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + } + } + if (!isdummy(nold)) + luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = isdummy(t->node) ? 0 : sizenode(t); + luaH_resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + luaH_resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L) { + Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; + t->metatable = NULL; + t->flags = cast_byte(~0); + t->array = NULL; + t->sizearray = 0; + setnodevector(L, t, 0); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (!isdummy(t->node)) + luaM_freearray(L, t->node, cast(size_t, sizenode(t))); + luaM_freearray(L, t->array, t->sizearray); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree > t->node) { + t->lastfree--; + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp; + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) + luaG_runerror(L, "table index is NaN"); + mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' take care of TM cache and GC barrier */ + return luaH_set(L, t, key); /* insert key into grown table */ + } + lua_assert(!isdummy(n)); + othern = mainposition(t, gkey(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + setobj2t(L, gkey(mp), key); + luaC_barrierback(L, obj2gco(t), key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getint (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for short strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + lua_assert(key->tsv.tt == LUA_TSHRSTR); + do { /* check whether `key' is somewhere in the chain */ + if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNIL: return luaO_nilobject; + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) /* index is int? */ + return luaH_getint(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaV_rawequalobj(gkey(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else return luaH_newkey(L, t, key); +} + + +void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { + const TValue *p = luaH_getint(t, key); + TValue *cell; + if (p != luaO_nilobject) + cell = cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + cell = luaH_newkey(L, t, &k); + } + setobj2t(L, cell, value); +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getint(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getint(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getint(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (isdummy(t->node)) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return isdummy(n); } + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.h new file mode 100644 index 000000000000..d69449b2b863 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.h @@ -0,0 +1,45 @@ +/* +** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.tvk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define invalidateTMcache(t) ((t)->flags = 0) + +/* returns the key, given the value of a table entry */ +#define keyfromval(v) \ + (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, int key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltablib.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltablib.c new file mode 100644 index 000000000000..ac9a662448fa --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltablib.c @@ -0,0 +1,284 @@ +/* +** $Id: ltablib.c,v 1.65.1.2 2014/05/07 16:32:55 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) + + + +#if defined(LUA_COMPAT_MAXN) +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} +#endif + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int size = aux_getn(L, 1); + int pos = luaL_optint(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ; pos < size; pos++) { + lua_rawgeti(L, 1, pos+1); + lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ + } + lua_pushnil(L); + lua_rawseti(L, 1, pos); /* t[pos] = nil */ + return 1; +} + + +static void addfield (lua_State *L, luaL_Buffer *b, int i) { + lua_rawgeti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid value (%s) at index %d in table for " + LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_addvalue(b); +} + + +static int tconcat (lua_State *L) { + luaL_Buffer b; + size_t lsep; + int i, last; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 3, 1); + last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); + luaL_buffinit(L, &b); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; +} + + +/* +** {====================================================== +** Pack/unpack +** ======================================================= +*/ + +static int pack (lua_State *L) { + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_pushinteger(L, n); + lua_setfield(L, -2, "n"); /* t.n = number of elements */ + if (n > 0) { /* at least one element? */ + int i; + lua_pushvalue(L, 1); + lua_rawseti(L, -2, 1); /* insert first element */ + lua_replace(L, 1); /* move table into index 1 */ + for (i = n; i >= 2; i--) /* assign other elements */ + lua_rawseti(L, 1, i); + } + return 1; /* return table */ +} + + +static int unpack (lua_State *L) { + int i, e; + unsigned int n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */ + if (n > (INT_MAX - 10) || !lua_checkstack(L, ++n)) + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Quicksort +** (based on `Algorithms in MODULA-3', Robert Sedgewick; +** Addison-Wesley, 1993.) +** ======================================================= +*/ + + +static void set2 (lua_State *L, int i, int j) { + lua_rawseti(L, 1, i); + lua_rawseti(L, 1, j); +} + +static int sort_comp (lua_State *L, int a, int b) { + if (!lua_isnil(L, 2)) { /* function? */ + int res; + lua_pushvalue(L, 2); + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ + lua_call(L, 2, 1); + res = lua_toboolean(L, -1); + lua_pop(L, 1); + return res; + } + else /* a < b? */ + return lua_compare(L, a, b, LUA_OPLT); +} + +static void auxsort (lua_State *L, int l, int u) { + while (l < u) { /* for tail recursion */ + int i, j; + /* sort elements a[l], a[(l+u)/2] and a[u] */ + lua_rawgeti(L, 1, l); + lua_rawgeti(L, 1, u); + if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ + set2(L, l, u); /* swap a[l] - a[u] */ + else + lua_pop(L, 2); + if (u-l == 1) break; /* only 2 elements */ + i = (l+u)/2; + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, l); + if (sort_comp(L, -2, -1)) /* a[i]= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>=u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j<=l) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +static const char udatatypename[] = "userdata"; + +LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "proto", "upval" /* these last two cases are used for tests only */ +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltm.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltm.h new file mode 100644 index 000000000000..7f89c841f9c0 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltm.h @@ -0,0 +1,57 @@ +/* +** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] +#define objtypename(x) ttypename(ttypenv(x)) + +LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lua.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lua.h new file mode 100644 index 000000000000..4610dad45ed8 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lua.h @@ -0,0 +1,443 @@ +/* +** $Id: lua.h,v 1.285.1.4 2015/02/21 14:04:50 roberto Exp $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include + +#include "luaconf.h" + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "2" +#define LUA_VERSION_NUM 502 +#define LUA_VERSION_RELEASE "4" + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRGCMM 5 +#define LUA_ERRERR 6 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTAGS 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + + + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +LUA_API const lua_Number *(lua_version) (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_absindex) (lua_State *L, int idx); +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPDIV 3 +#define LUA_OPMOD 4 +#define LUA_OPPOW 5 +#define LUA_OPUNM 6 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_getglobal) (lua_State *L, const char *var); +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getuservalue) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_setglobal) (lua_State *L, const char *var); +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API void (lua_setuservalue) (lua_State *L, int idx); + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_getctx) (lua_State *L, int *ctx); + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, + const char *mode); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx, + lua_CFunction k); +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCSETMAJORINC 8 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_pushglobaltable(L) \ + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debugger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); + +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2015 Lua.org, PUC-Rio. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/luaconf.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/luaconf.h new file mode 100644 index 000000000000..e856eee264ff --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/luaconf.h @@ -0,0 +1,555 @@ +/* +** $Id: luaconf.h,v 1.176.1.2 2013/11/21 17:26:16 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#ifdef illumos +#include +#else +#include +#endif + +extern ssize_t lcompat_sprintf(char *, const char *, ...); +extern int64_t lcompat_strtoll(const char *, char **); +extern int64_t lcompat_pow(int64_t, int64_t); + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_WIN /* enable goodies for regular Windows platforms */ +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#endif + + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* does not need -ldl */ +#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionality listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#define LUA_USE_GMTIME_R +#endif + + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" + +#else /* }{ */ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_ENV is the name of the variable that holds the current +@@ environment, used to access global names. +** CHANGE it if you do not like this name. +*/ +#define LUA_ENV "_ENV" + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables +@* that are not to be exported to outside modules (LUAI_DDEF for +@* definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ + +#else /* }{ */ +#define LUAI_FUNC extern +#define LUAI_DDEC extern +#define LUAI_DDEF /* empty */ +#endif /* } */ + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ luai_writestringerror defines how to print error messages. +** (A format string with one argument is enough for Lua...) +*/ +#ifdef _KERNEL +#define luai_writestringerror(s,p) \ + (zfs_dbgmsg((s), (p))) +#else +#define luai_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + + +/* +@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, +** strings that are internalized. (Cannot be smaller than reserved words +** or tags for metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#define LUAI_MAXSHORTLEN 40 + + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_ALL controls all compatibility options. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_ALL) /* { */ + +/* +@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. +** You can replace it with 'table.unpack'. +*/ +#define LUA_COMPAT_UNPACK + +/* +@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. +** You can replace it with 'package.searchers'. +*/ +#define LUA_COMPAT_LOADERS + +/* +@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. +** You can call your C function directly (with light C functions). +*/ +#define lua_cpcall(L,f,u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L,(u)), \ + lua_pcall(L,1,0,0)) + + +/* +@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. +** You can rewrite 'log10(x)' as 'log(x, 10)'. +*/ +#define LUA_COMPAT_LOG10 + +/* +@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base +** library. You can rewrite 'loadstring(s)' as 'load(s)'. +*/ +#define LUA_COMPAT_LOADSTRING + +/* +@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. +*/ +#define LUA_COMPAT_MAXN + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +/* +@@ LUA_COMPAT_MODULE controls compatibility with previous +** module functions 'module' (Lua) and 'luaL_register' (C). +*/ +#define LUA_COMPAT_MODULE + +#endif /* } */ + +/* }================================================================== */ + + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 /* { */ +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L /* }{ */ +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else /* }{ */ +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif /* } */ + + +/* +@@ LUA_INT32 is a signed integer with exactly 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. Probably you do not need to change +** this. +*/ +#if LUAI_BITSINT >= 32 /* { */ +#define LUA_INT32 int +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else /* }{ */ +/* 16-bit ints */ +#define LUA_INT32 long +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif /* } */ + + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + +/* reserve some space for error handling */ +#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) + + + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** CHANGE it if it uses too much C-stack space. +*/ +#define LUAL_BUFFERSIZE 1024 + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER int64_t + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER int64_t + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +*/ +#define LUA_NUMBER_FMT "%" PRId64 +#define lua_number2str(s,n) lcompat_sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ + + +/* +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations +*/ +#define l_mathop(x) (x ## l) + + +/* +@@ lua_str2number converts a decimal numeric string to a number. +@@ lua_strx2number converts an hexadecimal numeric string to a number. +** In C99, 'strtod' does both conversions. C89, however, has no function +** to convert floating hexadecimal strings to numbers. For these +** systems, you can leave 'lua_strx2number' undefined and Lua will +** provide its own implementation. +*/ +#define lua_str2number(s,p) lcompat_strtoll((s), (p)) + +#if defined(LUA_USE_STRTODHEX) +#define lua_strx2number(s,p) lcompat_strtoll((s), (p)) +#endif + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ + +/* the following operations need the math library */ +#if defined(lobject_c) || defined(lvm_c) +#define luai_nummod(L,a,b) ((a) % (b)) +#define luai_numpow(L,a,b) (lcompat_pow((a),(b))) +#endif + +/* these are quite standard operations */ +#if defined(LUA_CORE) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(L,a,b) ((a)<(b)) +#define luai_numle(L,a,b) ((a)<=(b)) +#define luai_numisnan(L,a) (!luai_numeq((a), (a))) +#endif + + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + +/* +@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. +** It must have at least 32 bits. +*/ +#define LUA_UNSIGNED uint64_t + + + +/* +** Some tricks with doubles +*/ + +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ +/* +** The next definitions activate some tricks to speed up the +** conversion from doubles to integer types, mainly to LUA_UNSIGNED. +** +@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a +** DirectX idiosyncrasy. +** +@@ LUA_IEEE754TRICK uses a trick that should work on any machine +** using IEEE754 with a 32-bit integer type. +** +@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be +** defined when LUA_INTEGER is a 32-bit integer. +** +@@ LUA_IEEEENDIAN is the endianness of doubles in your machine +** (0 for little endian, 1 for big endian); if not defined, Lua will +** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). +** +@@ LUA_NANTRICK controls the use of a trick to pack all types into +** a single double value, using NaN values to represent non-number +** values. The trick only works on 32-bit machines (ints and pointers +** are 32-bit values) with numbers represented as IEEE 754-2008 doubles +** with conventional endianess (12345678 or 87654321), in CPUs that do +** not produce signaling NaN values (all NaNs are quiet). +*/ + +/* Microsoft compiler on a Pentium (32 bit) ? */ +#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ + +#define LUA_MSASMTRICK +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + + +/* pentium 32 bits? */ +#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEELL +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + +/* pentium 64 bits? */ +#elif defined(__x86_64) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 0 + +#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 1 + +#else /* }{ */ + +/* assume IEEE754 and a 32-bit integer type */ +#define LUA_IEEE754TRICK + +#endif /* } */ + +#endif /* } */ + +/* }================================================================== */ + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + +#define getlocaledecpoint() ('.') + +#define abs(x) (((x) < 0) ? -(x) : (x)) + +#if !defined(UCHAR_MAX) +#define UCHAR_MAX (0xff) +#endif + +#endif + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lualib.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lualib.h new file mode 100644 index 000000000000..da82005c9de2 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lualib.h @@ -0,0 +1,55 @@ +/* +** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + + +LUAMOD_API int (luaopen_base) (lua_State *L); + +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_BITLIBNAME "bit32" +LUAMOD_API int (luaopen_bit32) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUAMOD_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#if !defined(lua_assert) +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.c new file mode 100644 index 000000000000..4d53749a0273 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.c @@ -0,0 +1,258 @@ +/* +** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +static l_noret error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +#if !defined(luai_verifycode) +#define luai_verifycode(L,b,f) /* empty */ +#endif + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + if (x<0) error(S,"corrupted"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size*sizeof(char)); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static void LoadFunction(LoadState* S, Proto* f); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: lua_assert(0); + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=luaF_newproto(S->L); + LoadFunction(S,f->p[i]); + } +} + +static void LoadUpvalues(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,Upvaldesc); + f->sizeupvalues=n; + for (i=0; iupvalues[i].name=NULL; + for (i=0; iupvalues[i].instack=LoadByte(S); + f->upvalues[i].idx=LoadByte(S); + } +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + f->source=LoadString(S); + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + for (i=0; iupvalues[i].name=LoadString(S); +} + +static void LoadFunction(LoadState* S, Proto* f) +{ + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadUpvalues(S,f); + LoadDebug(S,f); +} + +/* the code below must be consistent with the code in luaU_header */ +#define N0 LUAC_HEADERSIZE +#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) +#define N2 N1+2 +#define N3 N2+6 + +static void LoadHeader(LoadState* S) +{ + lu_byte h[LUAC_HEADERSIZE]; + lu_byte s[LUAC_HEADERSIZE]; + luaU_header(h); + memcpy(s,h,sizeof(char)); /* first char already read */ + LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); + if (memcmp(h,s,N0)==0) return; + if (memcmp(h,s,N1)!=0) error(S,"not a"); + if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); + if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); +} + +/* +** load precompiled chunk +*/ +Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + Closure* cl; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + cl=luaF_newLclosure(L,1); + setclLvalue(L,L->top,cl); incr_top(L); + cl->l.p=luaF_newproto(L); + LoadFunction(&S,cl->l.p); + if (cl->l.p->sizeupvalues != 1) + { + Proto* p=cl->l.p; + cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); + cl->l.p=p; + setclLvalue(L,L->top-1,cl); + } + luai_verifycode(L,buff,cl->l.p); + return cl; +} + +#define MYINT(s) (s[0]-'0') +#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) +#define FORMAT 0 /* this is the official format */ + +/* +* make header for precompiled chunks +* if you change the code below be sure to update LoadHeader and FORMAT above +* and LUAC_HEADERSIZE in lundump.h +*/ +void luaU_header (lu_byte* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); + h+=sizeof(LUA_SIGNATURE)-sizeof(char); + *h++=cast_byte(VERSION); + *h++=cast_byte(FORMAT); + *h++=cast_byte(*(char*)&x); /* endianness */ + *h++=cast_byte(sizeof(int)); + *h++=cast_byte(sizeof(size_t)); + *h++=cast_byte(sizeof(Instruction)); + *h++=cast_byte(sizeof(lua_Number)); + *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ + memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.h new file mode 100644 index 000000000000..5255db259dfe --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.h @@ -0,0 +1,28 @@ +/* +** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (lu_byte* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +/* data to catch conversion errors */ +#define LUAC_TAIL "\x19\x93\r\n\x1a\n" + +/* size in bytes of header of binary files */ +#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.c new file mode 100644 index 000000000000..a06e36e5ceae --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.c @@ -0,0 +1,930 @@ +/* +** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include + +#define strcoll(l,r) (strcmp((l),(r))) + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + int l = lua_number2str(s, n); + setsvalue2s(L, obj, luaS_newlstr(L, s, l)); + return 1; + } +} + + +static void traceexec (lua_State *L) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ + } + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ + ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ + newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ + } + L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + ci->func = L->top - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } +} + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, TValue *p3, int hasres) { + ptrdiff_t result = savestack(L, p3); + setobj2s(L, L->top++, f); /* push function */ + setobj2s(L, L->top++, p1); /* 1st argument */ + setobj2s(L, L->top++, p2); /* 2nd argument */ + if (!hasres) /* no result? 'p3' is third argument */ + setobj2s(L, L->top++, p3); /* 3rd argument */ + /* metamethod may yield only when called from Lua code */ + luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); + if (hasres) { /* if has result, move it to its place */ + p3 = restorestack(L, result); + setobjs2s(L, p3, --L->top); + } +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is not nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val, 1); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = cast(TValue *, luaH_get(h, key)); + /* if previous value is not nil, there must be a previous entry + in the table; moreover, a metamethod has no relevance */ + if (!ttisnil(oldval) || + /* previous value is nil; must check the metamethod */ + ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && + /* no metamethod; is there a previous entry in the table? */ + (oldval != luaO_nilobject || + /* no previous entry; must create one. (The next test is + always true; we only need the assignment.) */ + (oldval = luaH_newkey(L, h, key), 1)))) { + /* no metamethod and (now) there is an entry with given key */ + setobj2t(L, oldval, val); /* assign new value to that entry */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); + return; + } + /* else will try the metamethod */ + } + else /* not a table; check metamethod */ + if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + /* there is a metamethod */ + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val, 0); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTM(L, tm, p1, p2, res, 1); + return 1; +} + + +static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + if (!call_binTM(L, p1, p2, L->top, event)) + return -1; /* no metamethod */ + else + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numlt(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) + luaG_ordererror(L, l, r); + return res; +} + + +int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numle(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ + luaG_ordererror(L, l, r); + return !res; +} + + +/* +** equality of Lua values. L == NULL means raw equality (no metamethods) +*/ +int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttisequal(t1, t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TLCF: return fvalue(t1) == fvalue(t2); + case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTM(L, tm, t1, t2, L->top, 1); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total) { + lua_assert(total >= 2); + do { + StkId top = L->top; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } + else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ + (void)tostring(L, top - 2); /* result is first operand */ + else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } + else { + /* at least two non-empty string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (i = 1; i < total && tostring(L, top-i-1); i++) { + size_t l = tsvalue(top-i-1)->len; + if (l >= (MAX_SIZET/sizeof(char)) - tl) + luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + n = i; + do { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); + tl += l; + } while (--i > 0); + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got 'n' strings to create 1 new */ + L->top -= n-1; /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ +} + + +void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { + const TValue *tm; + switch (ttypenv(rb)) { + case LUA_TTABLE: { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ + return; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + return; + } + default: { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (ttisnil(tm)) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + callTM(L, tm, rb, rb, ra, 1); +} + +/* + * luaV_div and luaV_mod patched in from Lua 5.3.2 in order to properly handle + * div/mod by zero (instead of crashing, which is the default behavior in + * Lua 5.2) + */ + +/* +** Integer division; return 'm // n', that is, floor(m/n). +** C division truncates its result (rounds towards zero). +** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, +** otherwise 'floor(q) == trunc(q) - 1'. +*/ +static lua_Number luaV_div (lua_State *L, lua_Number m, lua_Number n) { + if ((lua_Unsigned)(n) + 1u <= 1u) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to divide by zero"); + return (0 - m); /* n==-1; avoid overflow with 0x80000...//-1 */ + } + else { + lua_Number q = m / n; /* perform C division */ + if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ + q -= 1; /* correct result for different rounding */ + return q; + } +} + + +/* +** Integer modulus; return 'm % n'. (Assume that C '%' with +** negative operands follows C99 behavior. See previous comment +** about luaV_div.) +*/ +static lua_Number luaV_mod (lua_State *L, lua_Number m, lua_Number n) { + if ((lua_Unsigned)(n) + 1u <= 1u) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to perform 'n%%0'"); + return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ + } + else { + lua_Number r = m % n; + if (r != 0 && (m ^ n) < 0) /* 'm/n' would be non-integer negative? */ + r += n; /* correct result for different rounding */ + return r; + } +} + +/* + * End patch from 5.3.2 + */ + +void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + /* + * Patched: if dividing or modding, use patched functions from 5.3 + */ + lua_Number res; + int lop = op - TM_ADD + LUA_OPADD; + if (lop == LUA_OPDIV) { + res = luaV_div(L, nvalue(b), nvalue(c)); + } else if (lop == LUA_OPMOD) { + res = luaV_mod(L, nvalue(b), nvalue(c)); + } else { + res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); + } + setnvalue(ra, res); + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + +/* +** check whether cached closure in prototype 'p' may be reused, that is, +** whether there is a cached closure with the same upvalues needed by +** new closure to be created. +*/ +static Closure *getcached (Proto *p, UpVal **encup, StkId base) { + Closure *c = p->cache; + if (c != NULL) { /* is there a cached closure? */ + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ + TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; + if (c->l.upvals[i]->v != v) + return NULL; /* wrong upvalue; cannot reuse closure */ + } + } + return c; /* return cached closure (or NULL if no cached closure) */ +} + + +/* +** create a new Lua closure, push it in the stack, and initialize +** its upvalues. Note that the call to 'luaC_barrierproto' must come +** before the assignment to 'p->cache', as the function needs the +** original value of that field. +*/ +static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) { + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + Closure *ncl = luaF_newLclosure(L, nup); + ncl->l.p = p; + setclLvalue(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->l.upvals[i] = encup[uv[i].idx]; + } + luaC_barrierproto(L, p, ncl); + p->cache = ncl; /* save it on cache for reuse */ +} + + +/* +** finish execution of an opcode interrupted by an yield +*/ +void luaV_finishOp (lua_State *L) { + CallInfo *ci = L->ci; + StkId base = ci->u.l.base; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) { /* finish its execution */ + case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: + case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { + setobjs2s(L, base + GETARG_A(inst), --L->top); + break; + } + case OP_LE: case OP_LT: case OP_EQ: { + int res = !l_isfalse(L->top - 1); + L->top--; + /* metamethod should not be called when operand is K */ + lua_assert(!ISK(GETARG_B(inst))); + if (op == OP_LE && /* "<=" using "<" instead? */ + ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) + res = !res; /* invert result */ + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_A(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: { + StkId top = L->top - 1; /* top when 'call_binTM' was called */ + int b = GETARG_B(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ + setobj2s(L, top - 2, top); /* put TM result in proper position */ + if (total > 1) { /* are there elements to concat? */ + L->top = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + } + /* move final result to final position */ + setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); + L->top = ci->top; /* restore top */ + break; + } + case OP_TFORCALL: { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); + L->top = ci->top; /* correct top */ + break; + } + case OP_CALL: { + if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ + L->top = ci->top; /* adjust results */ + break; + } + case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: + break; + default: lua_assert(0); + } +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#if !defined luai_runtimecheck +#define luai_runtimecheck(L, c) /* void */ +#endif + + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) \ + (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) + + +/* execute a jump instruction */ +#define dojump(ci,i,e) \ + { int a = GETARG_A(i); \ + if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ + ci->u.l.savedpc += GETARG_sBx(i) + e; } + +/* for test instructions, execute the jump instruction that follows it */ +#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } + + +#define Protect(x) { {x;}; base = ci->u.l.base; } + +#define checkGC(L,c) \ + Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ + luaC_step(L); \ + L->top = ci->top;}) /* restore top */ \ + luai_threadyield(L); ) + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(L, nb, nc)); \ + } \ + else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } + + +#define vmdispatch(o) switch(o) +#define vmcase(l,b) case l: {b} break; +#define vmcasenb(l,b) case l: {b} /* nb = no break */ + +void luaV_execute (lua_State *L) { + CallInfo *ci = L->ci; + LClosure *cl; + TValue *k; + StkId base; + newframe: /* reentry point when frame changes (call/return) */ + lua_assert(ci == L->ci); + cl = clLvalue(ci->func); + k = cl->p->k; + base = ci->u.l.base; + /* main loop of interpreter */ + for (;;) { + Instruction i = *(ci->u.l.savedpc++); + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + Protect(traceexec(L)); + } + /* WARNING: several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == ci->u.l.base); + lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + vmdispatch (GET_OPCODE(i)) { + vmcase(OP_MOVE, + setobjs2s(L, ra, RB(i)); + ) + vmcase(OP_LOADK, + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADKX, + TValue *rb; + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + rb = k + GETARG_Ax(*ci->u.l.savedpc++); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADBOOL, + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ + ) + vmcase(OP_LOADNIL, + int b = GETARG_B(i); + do { + setnilvalue(ra++); + } while (b--); + ) + vmcase(OP_GETUPVAL, + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + ) + vmcase(OP_GETTABUP, + int b = GETARG_B(i); + Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); + ) + vmcase(OP_GETTABLE, + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + ) + vmcase(OP_SETTABUP, + int a = GETARG_A(i); + Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); + ) + vmcase(OP_SETUPVAL, + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + ) + vmcase(OP_SETTABLE, + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + ) + vmcase(OP_NEWTABLE, + int b = GETARG_B(i); + int c = GETARG_C(i); + Table *t = luaH_new(L); + sethvalue(L, ra, t); + if (b != 0 || c != 0) + luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); + checkGC(L, ra + 1); + ) + vmcase(OP_SELF, + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + ) + vmcase(OP_ADD, + arith_op(luai_numadd, TM_ADD); + ) + vmcase(OP_SUB, + arith_op(luai_numsub, TM_SUB); + ) + vmcase(OP_MUL, + arith_op(luai_nummul, TM_MUL); + ) + /* + * Patched: use luaV_* instead of luai_* to handle div/mod by 0 + */ + vmcase(OP_DIV, + arith_op(luaV_div, TM_DIV); + ) + vmcase(OP_MOD, + arith_op(luaV_mod, TM_MOD); + ) + vmcase(OP_POW, + arith_op(luai_numpow, TM_POW); + ) + vmcase(OP_UNM, + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(L, nb)); + } + else { + Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); + } + ) + vmcase(OP_NOT, + TValue *rb = RB(i); + int res = l_isfalse(rb); /* next assignment may change this value */ + setbvalue(ra, res); + ) + vmcase(OP_LEN, + Protect(luaV_objlen(L, ra, RB(i))); + ) + vmcase(OP_CONCAT, + int b = GETARG_B(i); + int c = GETARG_C(i); + StkId rb; + L->top = base + c + 1; /* mark the end of concat operands */ + Protect(luaV_concat(L, c - b + 1)); + ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ + rb = b + base; + setobjs2s(L, ra, rb); + checkGC(L, (ra >= rb ? ra + 1 : rb)); + L->top = ci->top; /* restore top */ + ) + vmcase(OP_JMP, + dojump(ci, i, 0); + ) + vmcase(OP_EQ, + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_LT, + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_LE, + Protect( + if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_TEST, + if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + vmcase(OP_TESTSET, + TValue *rb = RB(i); + if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) + ci->u.l.savedpc++; + else { + setobjs2s(L, ra, rb); + donextjump(ci); + } + ) + vmcase(OP_CALL, + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + if (luaD_precall(L, ra, nresults)) { /* C function? */ + if (nresults >= 0) L->top = ci->top; /* adjust results */ + base = ci->u.l.base; + } + else { /* Lua function */ + ci = L->ci; + ci->callstatus |= CIST_REENTRY; + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcase(OP_TAILCALL, + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ + base = ci->u.l.base; + else { + /* tail call: put called frame (n) in place of caller one (o) */ + CallInfo *nci = L->ci; /* called frame */ + CallInfo *oci = nci->previous; /* caller frame */ + StkId nfunc = nci->func; /* called function */ + StkId ofunc = oci->func; /* caller function */ + /* last stack slot filled by 'precall' */ + StkId lim = nci->u.l.base + getproto(nfunc)->numparams; + int aux; + /* close all upvalues from previous call */ + if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); + /* move new frame into old one */ + for (aux = 0; nfunc + aux < lim; aux++) + setobjs2s(L, ofunc + aux, nfunc + aux); + oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ + oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ + oci->u.l.savedpc = nci->u.l.savedpc; + oci->callstatus |= CIST_TAIL; /* function was tail called */ + ci = L->ci = oci; /* remove new frame */ + lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcasenb(OP_RETURN, + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (cl->p->sizep > 0) luaF_close(L, base); + b = luaD_poscall(L, ra); + if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ + return; /* external invocation: return */ + else { /* invocation via reentry: continue execution */ + ci = L->ci; + if (b) L->top = ci->top; + lua_assert(isLua(ci)); + lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcase(OP_FORLOOP, + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) + : luai_numle(L, limit, idx)) { + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + ) + vmcase(OP_FORPREP, + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); + ci->u.l.savedpc += GETARG_sBx(i); + ) + vmcasenb(OP_TFORCALL, + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb + 3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i), 1)); + L->top = ci->top; + i = *(ci->u.l.savedpc++); /* go to next instruction */ + ra = RA(i); + lua_assert(GET_OPCODE(i) == OP_TFORLOOP); + goto l_tforloop; + ) + vmcase(OP_TFORLOOP, + l_tforloop: + if (!ttisnil(ra + 1)) { /* continue loop? */ + setobjs2s(L, ra, ra + 1); /* save control variable */ + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + } + ) + vmcase(OP_SETLIST, + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) n = cast_int(L->top - ra) - 1; + if (c == 0) { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + c = GETARG_Ax(*ci->u.l.savedpc++); + } + luai_runtimecheck(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-allocate it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + luaH_setint(L, h, last--, val); + luaC_barrierback(L, obj2gco(h), val); + } + L->top = ci->top; /* correct top (in case of previous open call) */ + ) + vmcase(OP_CLOSURE, + Proto *p = cl->p->p[GETARG_Bx(i)]; + Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ + if (ncl == NULL) /* no match? */ + pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ + else + setclLvalue(L, ra, ncl); /* push cashed closure */ + checkGC(L, ra + 1); + ) + vmcase(OP_VARARG, + int b = GETARG_B(i) - 1; + int j; + int n = cast_int(base - ci->func) - cl->p->numparams - 1; + if (b < 0) { /* B == 0? */ + b = n; /* get all var. arguments */ + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, base - n + j); + } + else { + setnilvalue(ra + j); + } + } + ) + vmcase(OP_EXTRAARG, + lua_assert(0); + ) + } + } +} + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.h new file mode 100644 index 000000000000..5380270da63d --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.h @@ -0,0 +1,44 @@ +/* +** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) + +#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) + + +/* not to called directly */ +LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.c new file mode 100644 index 000000000000..53e6a3daeb5a --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.c @@ -0,0 +1,76 @@ +/* +** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ + z->p = buff; + return cast_uchar(*(z->p++)); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.h new file mode 100644 index 000000000000..441f7479cb14 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.h @@ -0,0 +1,65 @@ +/* +** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) + + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index f2235cecca51..ae6dc57b6f29 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -3096,6 +3096,8 @@ spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig, if (config && (rewind_error || state != SPA_LOAD_RECOVER)) spa_config_set(spa, config); + else + nvlist_free(config); if (state == SPA_LOAD_RECOVER) { ASSERT3P(loadinfo, ==, NULL); @@ -6245,8 +6247,6 @@ spa_async_thread_vd(void *arg) spa_t *spa = arg; int tasks; - ASSERT(spa->spa_sync_on); - mutex_enter(&spa->spa_async_lock); tasks = spa->spa_async_tasks; retry: diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h index b720482a73fe..77b1b827ac37 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h @@ -30,6 +30,7 @@ extern "C" { void encode_embedded_bp_compressed(blkptr_t *, void *, enum zio_compress, int, int); void decode_embedded_bp_compressed(const blkptr_t *, void *); +int decode_embedded_bp(const blkptr_t *, void *, int); #ifdef __cplusplus } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h index 9399554e53eb..ca555652fb8c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h @@ -920,7 +920,7 @@ uint64_t dmu_tx_get_txg(dmu_tx_t *tx); * {zfs,zvol,ztest}_get_done() args */ typedef struct zgd { - struct zilog *zgd_zilog; + struct lwb *zgd_lwb; struct blkptr *zgd_bp; dmu_buf_t *zgd_db; struct rl *zgd_rl; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h index 3da68ca4a61e..f01c33aea855 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2017 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. @@ -227,6 +227,30 @@ dsl_dataset_phys(dsl_dataset_t *ds) return (ds->ds_dbuf->db_data); } +typedef struct dsl_dataset_promote_arg { + const char *ddpa_clonename; + dsl_dataset_t *ddpa_clone; + list_t shared_snaps, origin_snaps, clone_snaps; + dsl_dataset_t *origin_origin; /* origin of the origin */ + uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap; + nvlist_t *err_ds; + cred_t *cr; +} dsl_dataset_promote_arg_t; + +typedef struct dsl_dataset_rollback_arg { + const char *ddra_fsname; + const char *ddra_tosnap; + void *ddra_owner; + nvlist_t *ddra_result; +} dsl_dataset_rollback_arg_t; + +typedef struct dsl_dataset_snapshot_arg { + nvlist_t *ddsa_snaps; + nvlist_t *ddsa_props; + nvlist_t *ddsa_errors; + cred_t *ddsa_cr; +} dsl_dataset_snapshot_arg_t; + /* * The max length of a temporary tag prefix is the number of hex digits * required to express UINT64_MAX plus one for the hyphen. @@ -259,7 +283,11 @@ uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname, dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *); uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t flags, dmu_tx_t *tx); +void dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx); +int dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx); int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors); +void dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx); +int dsl_dataset_promote_check(void *arg, dmu_tx_t *tx); int dsl_dataset_promote(const char *name, char *conflsnap); int dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head, boolean_t force); @@ -284,7 +312,36 @@ int dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx, boolean_t async); void dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx); + +int get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val); +char *get_receive_resume_stats_impl(dsl_dataset_t *ds); +char *get_child_receive_stats(dsl_dataset_t *ds); +uint64_t dsl_get_refratio(dsl_dataset_t *ds); +uint64_t dsl_get_logicalreferenced(dsl_dataset_t *ds); +uint64_t dsl_get_compressratio(dsl_dataset_t *ds); +uint64_t dsl_get_used(dsl_dataset_t *ds); +uint64_t dsl_get_creation(dsl_dataset_t *ds); +uint64_t dsl_get_creationtxg(dsl_dataset_t *ds); +uint64_t dsl_get_refquota(dsl_dataset_t *ds); +uint64_t dsl_get_refreservation(dsl_dataset_t *ds); +uint64_t dsl_get_guid(dsl_dataset_t *ds); +uint64_t dsl_get_unique(dsl_dataset_t *ds); +uint64_t dsl_get_objsetid(dsl_dataset_t *ds); +uint64_t dsl_get_userrefs(dsl_dataset_t *ds); +uint64_t dsl_get_defer_destroy(dsl_dataset_t *ds); +uint64_t dsl_get_referenced(dsl_dataset_t *ds); +uint64_t dsl_get_numclones(dsl_dataset_t *ds); +uint64_t dsl_get_inconsistent(dsl_dataset_t *ds); +uint64_t dsl_get_available(dsl_dataset_t *ds); +int dsl_get_written(dsl_dataset_t *ds, uint64_t *written); +int dsl_get_prev_snap(dsl_dataset_t *ds, char *snap); +int dsl_get_mountpoint(dsl_dataset_t *ds, const char *dsname, char *value, + char *source); + +void get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv); + void dsl_dataset_stats(dsl_dataset_t *os, nvlist_t *nv); + void dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat); void dsl_dataset_space(dsl_dataset_t *ds, uint64_t *refdbytesp, uint64_t *availbytesp, @@ -334,6 +391,9 @@ void dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds, void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx); boolean_t dsl_dataset_is_zapified(dsl_dataset_t *ds); boolean_t dsl_dataset_has_resume_receive_state(dsl_dataset_t *ds); + +int dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx); +void dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx); int dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner, nvlist_t *result); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h index 3f638643b6f8..ae3ca0cfbd5e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ @@ -46,6 +46,21 @@ int dsl_destroy_snapshot_check_impl(struct dsl_dataset *, boolean_t); void dsl_destroy_snapshot_sync_impl(struct dsl_dataset *, boolean_t, struct dmu_tx *); +typedef struct dsl_destroy_snapshot_arg { + const char *ddsa_name; + boolean_t ddsa_defer; +} dsl_destroy_snapshot_arg_t; + +int dsl_destroy_snapshot_check(void *, dmu_tx_t *); +void dsl_destroy_snapshot_sync(void *, dmu_tx_t *); + +typedef struct dsl_destroy_head_arg { + const char *ddha_name; +} dsl_destroy_head_arg_t; + +int dsl_destroy_head_check(void *, dmu_tx_t *); +void dsl_destroy_head_sync(void *, dmu_tx_t *); + #ifdef __cplusplus } #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h index a6414887c310..c5ba6e2f6e43 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h @@ -131,6 +131,20 @@ void dsl_dir_name(dsl_dir_t *dd, char *buf); int dsl_dir_namelen(dsl_dir_t *dd); uint64_t dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, const char *name, dmu_tx_t *tx); + +uint64_t dsl_dir_get_used(dsl_dir_t *dd); +uint64_t dsl_dir_get_quota(dsl_dir_t *dd); +uint64_t dsl_dir_get_reservation(dsl_dir_t *dd); +uint64_t dsl_dir_get_compressratio(dsl_dir_t *dd); +uint64_t dsl_dir_get_logicalused(dsl_dir_t *dd); +uint64_t dsl_dir_get_usedsnap(dsl_dir_t *dd); +uint64_t dsl_dir_get_usedds(dsl_dir_t *dd); +uint64_t dsl_dir_get_usedrefreserv(dsl_dir_t *dd); +uint64_t dsl_dir_get_usedchild(dsl_dir_t *dd); +void dsl_dir_get_origin(dsl_dir_t *dd, char *buf); +int dsl_dir_get_filesystem_count(dsl_dir_t *dd, uint64_t *count); +int dsl_dir_get_snapshot_count(dsl_dir_t *dd, uint64_t *count); + void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv); uint64_t dsl_dir_space_available(dsl_dir_t *dd, dsl_dir_t *ancestor, int64_t delta, int ondiskonly); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h index 4ed37b8469b3..b6c51cb3cd69 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h @@ -123,7 +123,6 @@ typedef struct dsl_pool { txg_list_t dp_sync_tasks; taskq_t *dp_sync_taskq; taskq_t *dp_zil_clean_taskq; - txg_list_t dp_early_sync_tasks; /* * Protects administrative changes (properties, namespace) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h new file mode 100644 index 000000000000..2e4ad7aac514 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h @@ -0,0 +1,144 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016, 2017 by Delphix. All rights reserved. + */ + +#ifndef _SYS_ZCP_H +#define _SYS_ZCP_H + +#include +#include + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZCP_RUN_INFO_KEY "runinfo" + +extern uint64_t zfs_lua_max_instrlimit; +extern uint64_t zfs_lua_max_memlimit; + +int zcp_argerror(lua_State *, int, const char *, ...); + +int zcp_eval(const char *, const char *, uint64_t, uint64_t, nvpair_t *, + nvlist_t *); + +int zcp_load_list_lib(lua_State *); + +int zcp_load_synctask_lib(lua_State *, boolean_t); + +typedef void (zcp_cleanup_t)(void *); + +typedef struct zcp_run_info { + dsl_pool_t *zri_pool; + + /* + * An estimate of the total ammount of space consumed by all + * synctasks we have successfully performed so far in this + * channel program. Used to generate ENOSPC errors for syncfuncs. + */ + int zri_space_used; + + /* + * The credentials of the thread which originally invoked the channel + * program. Since channel programs are always invoked from the synctask + * thread they should always do permissions checks against this cred + * rather than the 'current' thread's. + */ + cred_t *zri_cred; + + /* + * The tx in which this channel program is running. + */ + dmu_tx_t *zri_tx; + + /* + * The maximum number of Lua instructions the channel program is allowed + * to execute. If it takes longer than this it will time out. A value + * of 0 indicates no instruction limit. + */ + uint64_t zri_maxinstrs; + + /* + * The number of Lua instructions the channel program has executed. + */ + uint64_t zri_curinstrs; + + /* + * Boolean indicating whether or not the channel program exited + * because it timed out. + */ + boolean_t zri_timed_out; + + /* + * The currently registered cleanup function, which will be called + * with the stored argument if a fatal error occurs. + */ + zcp_cleanup_t *zri_cleanup; + void *zri_cleanup_arg; +} zcp_run_info_t; + +zcp_run_info_t *zcp_run_info(lua_State *); +void zcp_register_cleanup(lua_State *, zcp_cleanup_t, void *); +void zcp_clear_cleanup(lua_State *); +void zcp_cleanup(lua_State *); + +/* + * Argument parsing routines for channel program callback functions. + */ +typedef struct zcp_arg { + /* + * The name of this argument. For keyword arguments this is the name + * functions will use to set the argument. For positional arguments + * the name has no programatic meaning, but will appear in error + * messages and help output. + */ + const char *za_name; + + /* + * The Lua type this argument should have (e.g. LUA_TSTRING, + * LUA_TBOOLEAN) see the lua_type() function documentation for a + * complete list. Calling a function with an argument that does + * not match the expected type will result in the program terminating. + */ + const int za_lua_type; +} zcp_arg_t; + +void zcp_parse_args(lua_State *, const char *, const zcp_arg_t *, + const zcp_arg_t *); +int zcp_nvlist_to_lua(lua_State *, nvlist_t *, char *, int); +int zcp_dataset_hold_error(lua_State *, dsl_pool_t *, const char *, int); +struct dsl_dataset *zcp_dataset_hold(lua_State *, dsl_pool_t *, + const char *, void *); + +typedef int (zcp_lib_func_t)(lua_State *); +typedef struct zcp_lib_info { + const char *name; + zcp_lib_func_t *func; + const zcp_arg_t pargs[4]; + const zcp_arg_t kwargs[2]; +} zcp_lib_info_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_global.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_global.h new file mode 100644 index 000000000000..e227f2f4b7f5 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_global.h @@ -0,0 +1,35 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#ifndef _SYS_ZCP_GLOBALS_H +#define _SYS_ZCP_GLOBALS_H + +#include "lua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void zcp_load_globals(lua_State *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_GLOBALS_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_iter.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_iter.h new file mode 100644 index 000000000000..a021e1ce8917 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_iter.h @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#ifndef _SYS_ZCP_LIST_H +#define _SYS_ZCP_LIST_H + +#include "lua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void zcp_load_list_funcs(lua_State *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_LIST_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_prop.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_prop.h new file mode 100644 index 000000000000..97b17619565c --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp_prop.h @@ -0,0 +1,34 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#ifndef _SYS_ZCP_PROP_H +#define _SYS_ZCP_PROP_H + +#ifdef __cplusplus +extern "C" { +#endif + +int zcp_load_get_lib(lua_State *state); +boolean_t prop_valid_for_ds(dsl_dataset_t *ds, zfs_prop_t zfs_prop); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZCP_PROP_H */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h index 163e822b1dd9..c3d47ba17075 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright 2016 RackTop Systems. * Copyright (c) 2014 Integros [integros.com] */ @@ -412,19 +412,22 @@ typedef struct zfs_useracct { #define ZPOOL_EXPORT_AFTER_SPLIT 0x1 #ifdef _KERNEL +struct objset; +struct zfsvfs; typedef struct zfs_creat { nvlist_t *zct_zplprops; nvlist_t *zct_props; } zfs_creat_t; -extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr); -extern int zfs_secpolicy_rename_perms(const char *from, - const char *to, cred_t *cr); -extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr); +extern int zfs_secpolicy_snapshot_perms(const char *, cred_t *); +extern int zfs_secpolicy_rename_perms(const char *, const char *, cred_t *); +extern int zfs_secpolicy_destroy_perms(const char *, cred_t *); extern int zfs_busy(void); -extern int zfs_unmount_snap(const char *); +extern void zfs_unmount_snap(const char *); extern void zfs_destroy_unmount_origin(const char *); +extern int getzfsvfs_impl(struct objset *, struct zfsvfs **); +extern int getzfsvfs(const char *, struct zfsvfs **); /* * ZFS minor numbers can refer to either a control device instance or diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h index 57cb61246c3a..987aa4172be8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h @@ -155,6 +155,7 @@ extern boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid); extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers); extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp); +extern int zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os); extern void zfsvfs_free(zfsvfs_t *zfsvfs); extern int zfs_check_global_label(const char *dsname, const char *hexsl); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h index 098446e43f33..a88b96e7b5a5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h @@ -40,6 +40,7 @@ extern "C" { struct dsl_pool; struct dsl_dataset; +struct lwb; /* * Intent log format: @@ -140,6 +141,7 @@ typedef enum zil_create { /* * Intent log transaction types and record structures */ +#define TX_COMMIT 0 /* Commit marker (no on-disk state) */ #define TX_CREATE 1 /* Create file */ #define TX_MKDIR 2 /* Make directory */ #define TX_MKXATTR 3 /* Make XATTR directory */ @@ -388,7 +390,8 @@ typedef int zil_parse_blk_func_t(zilog_t *zilog, blkptr_t *bp, void *arg, typedef int zil_parse_lr_func_t(zilog_t *zilog, lr_t *lr, void *arg, uint64_t txg); typedef int zil_replay_func_t(); -typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf, zio_t *zio); +typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf, + struct lwb *lwb, zio_t *zio); extern int zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func, zil_parse_lr_func_t *parse_lr_func, void *arg, uint64_t txg); @@ -427,7 +430,8 @@ extern void zil_clean(zilog_t *zilog, uint64_t synced_txg); extern int zil_suspend(const char *osname, void **cookiep); extern void zil_resume(void *cookie); -extern void zil_add_block(zilog_t *zilog, const blkptr_t *bp); +extern void zil_lwb_add_block(struct lwb *lwb, const blkptr_t *bp); +extern void zil_lwb_add_txg(struct lwb *lwb, uint64_t txg); extern int zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp); extern void zil_set_sync(zilog_t *zilog, uint64_t syncval); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h index f25e7cd3c279..5554c2a91334 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -37,7 +37,30 @@ extern "C" { #endif /* - * Log write buffer. + * Possbile states for a given lwb structure. An lwb will start out in + * the "closed" state, and then transition to the "opened" state via a + * call to zil_lwb_write_open(). After the lwb is "open", it can + * transition into the "issued" state via zil_lwb_write_issue(). After + * the lwb's zio completes, and the vdev's are flushed, the lwb will + * transition into the "done" state via zil_lwb_write_done(), and the + * structure eventually freed. + */ +typedef enum { + LWB_STATE_CLOSED, + LWB_STATE_OPENED, + LWB_STATE_ISSUED, + LWB_STATE_DONE, + LWB_NUM_STATES +} lwb_state_t; + +/* + * Log write block (lwb) + * + * Prior to an lwb being issued to disk via zil_lwb_write_issue(), it + * will be protected by the zilog's "zl_writer_lock". Basically, prior + * to it being issued, it will only be accessed by the thread that's + * holding the "zl_writer_lock". After the lwb is issued, the zilog's + * "zl_lock" is used to protect the lwb against concurrent access. */ typedef struct lwb { zilog_t *lwb_zilog; /* back pointer to log struct */ @@ -45,13 +68,44 @@ typedef struct lwb { boolean_t lwb_slog; /* lwb_blk is on SLOG device */ int lwb_nused; /* # used bytes in buffer */ int lwb_sz; /* size of block and buffer */ + lwb_state_t lwb_state; /* the state of this lwb */ char *lwb_buf; /* log write buffer */ - zio_t *lwb_zio; /* zio for this buffer */ + zio_t *lwb_write_zio; /* zio for the lwb buffer */ + zio_t *lwb_root_zio; /* root zio for lwb write and flushes */ dmu_tx_t *lwb_tx; /* tx for log block allocation */ uint64_t lwb_max_txg; /* highest txg in this lwb */ list_node_t lwb_node; /* zilog->zl_lwb_list linkage */ + list_t lwb_waiters; /* list of zil_commit_waiter's */ + avl_tree_t lwb_vdev_tree; /* vdevs to flush after lwb write */ + kmutex_t lwb_vdev_lock; /* protects lwb_vdev_tree */ + hrtime_t lwb_issued_timestamp; /* when was the lwb issued? */ } lwb_t; +/* + * ZIL commit waiter. + * + * This structure is allocated each time zil_commit() is called, and is + * used by zil_commit() to communicate with other parts of the ZIL, such + * that zil_commit() can know when it safe for it return. For more + * details, see the comment above zil_commit(). + * + * The "zcw_lock" field is used to protect the commit waiter against + * concurrent access. This lock is often acquired while already holding + * the zilog's "zl_writer_lock" or "zl_lock"; see the functions + * zil_process_commit_list() and zil_lwb_flush_vdevs_done() as examples + * of this. Thus, one must be careful not to acquire the + * "zl_writer_lock" or "zl_lock" when already holding the "zcw_lock"; + * e.g. see the zil_commit_waiter_timeout() function. + */ +typedef struct zil_commit_waiter { + kcondvar_t zcw_cv; /* signalled when "done" */ + kmutex_t zcw_lock; /* protects fields of this struct */ + list_node_t zcw_node; /* linkage in lwb_t:lwb_waiter list */ + lwb_t *zcw_lwb; /* back pointer to lwb when linked */ + boolean_t zcw_done; /* B_TRUE when "done", else B_FALSE */ + int zcw_zio_error; /* contains the zio io_error value */ +} zil_commit_waiter_t; + /* * Intent log transaction lists */ @@ -94,20 +148,20 @@ struct zilog { const zil_header_t *zl_header; /* log header buffer */ objset_t *zl_os; /* object set we're logging */ zil_get_data_t *zl_get_data; /* callback to get object content */ - zio_t *zl_root_zio; /* log writer root zio */ + lwb_t *zl_last_lwb_opened; /* most recent lwb opened */ + hrtime_t zl_last_lwb_latency; /* zio latency of last lwb done */ uint64_t zl_lr_seq; /* on-disk log record sequence number */ uint64_t zl_commit_lr_seq; /* last committed on-disk lr seq */ uint64_t zl_destroy_txg; /* txg of last zil_destroy() */ uint64_t zl_replayed_seq[TXG_SIZE]; /* last replayed rec seq */ uint64_t zl_replaying_seq; /* current replay seq number */ uint32_t zl_suspend; /* log suspend count */ - kcondvar_t zl_cv_writer; /* log writer thread completion */ kcondvar_t zl_cv_suspend; /* log suspend completion */ uint8_t zl_suspending; /* log is currently suspending */ uint8_t zl_keep_first; /* keep first log block in destroy */ uint8_t zl_replay; /* replaying records while set */ uint8_t zl_stop_sync; /* for debugging */ - uint8_t zl_writer; /* boolean: write setup in progress */ + kmutex_t zl_writer_lock; /* single writer, per ZIL, at a time */ uint8_t zl_logbias; /* latency or throughput */ uint8_t zl_sync; /* synchronous or asynchronous */ int zl_parse_error; /* last zil_parse() error */ @@ -115,15 +169,10 @@ struct zilog { uint64_t zl_parse_lr_seq; /* highest lr seq on last parse */ uint64_t zl_parse_blk_count; /* number of blocks parsed */ uint64_t zl_parse_lr_count; /* number of log records parsed */ - uint64_t zl_next_batch; /* next batch number */ - uint64_t zl_com_batch; /* committed batch number */ - kcondvar_t zl_cv_batch[2]; /* batch condition variables */ itxg_t zl_itxg[TXG_SIZE]; /* intent log txg chains */ list_t zl_itx_commit_list; /* itx list to be committed */ uint64_t zl_cur_used; /* current commit log size used */ list_t zl_lwb_list; /* in-flight log write list */ - kmutex_t zl_vdev_lock; /* protects zl_vdev_tree */ - avl_tree_t zl_vdev_tree; /* vdevs to flush in zil_commit() */ avl_tree_t zl_bp_tree; /* track bps during log parse */ clock_t zl_replay_time; /* lbolt of when replay started */ uint64_t zl_replay_blks; /* number of log blocks replayed */ @@ -131,6 +180,7 @@ struct zilog { uint_t zl_prev_blks[ZIL_PREV_BLKS]; /* size - sector rounded */ uint_t zl_prev_rotor; /* rotor for zl_prev[] */ txg_node_t zl_dirty_link; /* protected by dp_dirty_zilogs list */ + uint64_t zl_dirty_max_txg; /* highest txg used to dirty zilog */ }; typedef struct zil_bp_node { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index c09f62a3dc01..8ad8953c9110 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -593,6 +593,7 @@ extern enum zio_checksum zio_checksum_dedup_select(spa_t *spa, extern enum zio_compress zio_compress_select(spa_t *spa, enum zio_compress child, enum zio_compress parent); +extern void zio_cancel(zio_t *zio); extern void zio_suspend(spa_t *spa, zio_t *zio); extern int zio_resume(spa_t *spa); extern void zio_resume_wait(spa_t *spa); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c index eee148ff9f75..884bd9f649f9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c @@ -163,7 +163,7 @@ txg_fini(dsl_pool_t *dp) tx_state_t *tx = &dp->dp_tx; int c; - ASSERT(tx->tx_threads == 0); + ASSERT0(tx->tx_threads); mutex_destroy(&tx->tx_sync_lock); @@ -204,7 +204,7 @@ txg_sync_start(dsl_pool_t *dp) dprintf("pool %p\n", dp); - ASSERT(tx->tx_threads == 0); + ASSERT0(tx->tx_threads); tx->tx_threads = 2; @@ -265,7 +265,7 @@ txg_sync_stop(dsl_pool_t *dp) /* * Finish off any work in progress. */ - ASSERT(tx->tx_threads == 2); + ASSERT3U(tx->tx_threads, ==, 2); /* * We need to ensure that we've vacated the deferred space_maps. @@ -277,7 +277,7 @@ txg_sync_stop(dsl_pool_t *dp) */ mutex_enter(&tx->tx_sync_lock); - ASSERT(tx->tx_threads == 2); + ASSERT3U(tx->tx_threads, ==, 2); tx->tx_exiting = 1; @@ -616,7 +616,7 @@ txg_wait_synced(dsl_pool_t *dp, uint64_t txg) ASSERT(!dsl_pool_config_held(dp)); mutex_enter(&tx->tx_sync_lock); - ASSERT(tx->tx_threads == 2); + ASSERT3U(tx->tx_threads, ==, 2); if (txg == 0) txg = tx->tx_open_txg + TXG_DEFER_SIZE; if (tx->tx_sync_txg_waiting < txg) @@ -641,7 +641,7 @@ txg_wait_open(dsl_pool_t *dp, uint64_t txg) ASSERT(!dsl_pool_config_held(dp)); mutex_enter(&tx->tx_sync_lock); - ASSERT(tx->tx_threads == 2); + ASSERT3U(tx->tx_threads, ==, 2); if (txg == 0) txg = tx->tx_open_txg + 1; if (tx->tx_quiesce_txg_waiting < txg) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index d67220a1c41c..849511dac11b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -193,7 +193,7 @@ vdev_geom_orphan(struct g_consumer *cp) } static struct g_consumer * -vdev_geom_attach(struct g_provider *pp, vdev_t *vd) +vdev_geom_attach(struct g_provider *pp, vdev_t *vd, boolean_t sanity) { struct g_geom *gp; struct g_consumer *cp; @@ -203,14 +203,18 @@ vdev_geom_attach(struct g_provider *pp, vdev_t *vd) ZFS_LOG(1, "Attaching to %s.", pp->name); - if (pp->sectorsize > VDEV_PAD_SIZE || !ISP2(pp->sectorsize)) { - ZFS_LOG(1, "Failing attach of %s. Incompatible sectorsize %d\n", - pp->name, pp->sectorsize); - return (NULL); - } else if (pp->mediasize < SPA_MINDEVSIZE) { - ZFS_LOG(1, "Failing attach of %s. Incompatible mediasize %ju\n", - pp->name, pp->mediasize); - return (NULL); + if (sanity) { + if (pp->sectorsize > VDEV_PAD_SIZE || !ISP2(pp->sectorsize)) { + ZFS_LOG(1, "Failing attach of %s. " + "Incompatible sectorsize %d\n", + pp->name, pp->sectorsize); + return (NULL); + } else if (pp->mediasize < SPA_MINDEVSIZE) { + ZFS_LOG(1, "Failing attach of %s. " + "Incompatible mediasize %ju\n", + pp->name, pp->mediasize); + return (NULL); + } } /* Do we have geom already? No? Create one. */ @@ -587,7 +591,7 @@ vdev_geom_read_pool_label(const char *name, LIST_FOREACH(pp, &gp->provider, provider) { if (pp->flags & G_PF_WITHER) continue; - zcp = vdev_geom_attach(pp, NULL); + zcp = vdev_geom_attach(pp, NULL, B_TRUE); if (zcp == NULL) continue; g_topology_unlock(); @@ -627,7 +631,7 @@ vdev_attach_ok(vdev_t *vd, struct g_provider *pp) struct g_consumer *cp; int nlabels; - cp = vdev_geom_attach(pp, NULL); + cp = vdev_geom_attach(pp, NULL, B_TRUE); if (cp == NULL) { ZFS_LOG(1, "Unable to attach tasting instance to %s.", pp->name); @@ -635,14 +639,12 @@ vdev_attach_ok(vdev_t *vd, struct g_provider *pp) } g_topology_unlock(); nlabels = vdev_geom_read_config(cp, &config); + g_topology_lock(); + vdev_geom_detach(cp, B_TRUE); if (nlabels == 0) { - g_topology_lock(); - vdev_geom_detach(cp, B_TRUE); ZFS_LOG(1, "Unable to read config from %s.", pp->name); return (NO_MATCH); } - g_topology_lock(); - vdev_geom_detach(cp, B_TRUE); pool_guid = 0; (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid); @@ -714,7 +716,7 @@ vdev_geom_attach_by_guids(vdev_t *vd) out: if (best_pp) { - cp = vdev_geom_attach(best_pp, vd); + cp = vdev_geom_attach(best_pp, vd, B_TRUE); if (cp == NULL) { printf("ZFS WARNING: Unable to attach to %s.\n", best_pp->name); @@ -768,7 +770,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); if (!check_guid || vdev_attach_ok(vd, pp) == FULL_MATCH) - cp = vdev_geom_attach(pp, vd); + cp = vdev_geom_attach(pp, vd, B_FALSE); } return (cp); @@ -932,13 +934,18 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, static void vdev_geom_close(vdev_t *vd) { + struct g_consumer *cp; - if (vd->vdev_reopening) - return; + cp = vd->vdev_tsd; DROP_GIANT(); g_topology_lock(); - vdev_geom_close_locked(vd); + + if (!vd->vdev_reopening || + (cp != NULL && ((cp->flags & G_CF_ORPHAN) != 0 || + (cp->provider != NULL && cp->provider->error != 0)))) + vdev_geom_close_locked(vd); + g_topology_unlock(); PICKUP_GIANT(); } @@ -989,6 +996,15 @@ vdev_geom_io_intr(struct bio *bp) break; } + /* + * We have to split bio freeing into two parts, because the ABD code + * cannot be called in this context and vdev_op_io_done is not called + * for ZIO_TYPE_IOCTL zio-s. + */ + if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) { + g_destroy_bio(bp); + zio->io_bio = NULL; + } zio_delay_interrupt(zio); } @@ -1090,21 +1106,23 @@ vdev_geom_io_done(zio_t *zio) { struct bio *bp = zio->io_bio; - if (bp == NULL) { - ASSERT3S(zio->io_error, !=, 0); - IMPLY(zio->io_type == ZIO_TYPE_READ || - zio->io_type == ZIO_TYPE_WRITE, - zio->io_error == ENXIO); + if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) { + ASSERT(bp == NULL); return; } - if (zio->io_type == ZIO_TYPE_READ) { - abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size); - } else if (zio->io_type == ZIO_TYPE_WRITE) { - abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size); + if (bp == NULL) { + ASSERT3S(zio->io_error, ==, ENXIO); + return; } + if (zio->io_type == ZIO_TYPE_READ) + abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size); + else + abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size); + g_destroy_bio(bp); + zio->io_bio = NULL; } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c index e8c305a9be92..b7254261cfb3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c @@ -29,6 +29,9 @@ #include #include +#include +#include +#include #include #include #include @@ -52,7 +55,7 @@ typedef struct mirror_map { int *mm_preferred; int mm_preferred_cnt; int mm_children; - boolean_t mm_replacing; + boolean_t mm_resilvering; boolean_t mm_root; mirror_child_t mm_child[]; } mirror_map_t; @@ -119,13 +122,13 @@ vdev_mirror_map_size(int children) } static inline mirror_map_t * -vdev_mirror_map_alloc(int children, boolean_t replacing, boolean_t root) +vdev_mirror_map_alloc(int children, boolean_t resilvering, boolean_t root) { mirror_map_t *mm; mm = kmem_zalloc(vdev_mirror_map_size(children), KM_SLEEP); mm->mm_children = children; - mm->mm_replacing = replacing; + mm->mm_resilvering = resilvering; mm->mm_root = root; mm->mm_preferred = (int *)((uintptr_t)mm + offsetof(mirror_map_t, mm_child[children])); @@ -217,9 +220,39 @@ vdev_mirror_map_init(zio_t *zio) mc->mc_offset = DVA_GET_OFFSET(&dva[c]); } } else { - mm = vdev_mirror_map_alloc(vd->vdev_children, - (vd->vdev_ops == &vdev_replacing_ops || - vd->vdev_ops == &vdev_spare_ops), B_FALSE); + /* + * If we are resilvering, then we should handle scrub reads + * differently; we shouldn't issue them to the resilvering + * device because it might not have those blocks. + * + * We are resilvering iff: + * 1) We are a replacing vdev (ie our name is "replacing-1" or + * "spare-1" or something like that), and + * 2) The pool is currently being resilvered. + * + * We cannot simply check vd->vdev_resilver_txg, because it's + * not set in this path. + * + * Nor can we just check our vdev_ops; there are cases (such as + * when a user types "zpool replace pool odev spare_dev" and + * spare_dev is in the spare list, or when a spare device is + * automatically used to replace a DEGRADED device) when + * resilvering is complete but both the original vdev and the + * spare vdev remain in the pool. That behavior is intentional. + * It helps implement the policy that a spare should be + * automatically removed from the pool after the user replaces + * the device that originally failed. + * + * If a spa load is in progress, then spa_dsl_pool may be + * uninitialized. But we shouldn't be resilvering during a spa + * load anyway. + */ + boolean_t replacing = (vd->vdev_ops == &vdev_replacing_ops || + vd->vdev_ops == &vdev_spare_ops) && + spa_load_state(vd->vdev_spa) == SPA_LOAD_NONE && + dsl_scan_resilvering(vd->vdev_spa->spa_dsl_pool); + mm = vdev_mirror_map_alloc(vd->vdev_children, replacing, + B_FALSE); for (c = 0; c < mm->mm_children; c++) { mc = &mm->mm_child[c]; mc->mc_vd = vd->vdev_child[c]; @@ -448,7 +481,7 @@ vdev_mirror_io_start(zio_t *zio) mm = vdev_mirror_map_init(zio); if (zio->io_type == ZIO_TYPE_READ) { - if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_replacing && + if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_resilvering && mm->mm_children > 1) { /* * For scrubbing reads we need to allocate a read @@ -589,7 +622,7 @@ vdev_mirror_io_done(zio_t *zio) if (good_copies && spa_writeable(zio->io_spa) && (unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER) || - ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) { + ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_resilvering))) { /* * Use the good data we have in hand to repair damaged children. */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c new file mode 100644 index 000000000000..56ccbf1c50d5 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c @@ -0,0 +1,1357 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016, 2017 by Delphix. All rights reserved. + */ + +/* + * ZFS Channel Programs (ZCP) + * + * The ZCP interface allows various ZFS commands and operations ZFS + * administrative operations (e.g. creating and destroying snapshots, typically + * performed via an ioctl to /dev/zfs by the zfs(1M) command and + * libzfs/libzfs_core) to be run * programmatically as a Lua script. A ZCP + * script is run as a dsl_sync_task and fully executed during one transaction + * group sync. This ensures that no other changes can be written concurrently + * with a running Lua script. Combining multiple calls to the exposed ZFS + * functions into one script gives a number of benefits: + * + * 1. Atomicity. For some compound or iterative operations, it's useful to be + * able to guarantee that the state of a pool has not changed between calls to + * ZFS. + * + * 2. Performance. If a large number of changes need to be made (e.g. deleting + * many filesystems), there can be a significant performance penalty as a + * result of the need to wait for a transaction group sync to pass for every + * single operation. When expressed as a single ZCP script, all these changes + * can be performed at once in one txg sync. + * + * A modified version of the Lua 5.2 interpreter is used to run channel program + * scripts. The Lua 5.2 manual can be found at: + * + * http://www.lua.org/manual/5.2/ + * + * If being run by a user (via an ioctl syscall), executing a ZCP script + * requires root privileges in the global zone. + * + * Scripts are passed to zcp_eval() as a string, then run in a synctask by + * zcp_eval_sync(). Arguments can be passed into the Lua script as an nvlist, + * which will be converted to a Lua table. Similarly, values returned from + * a ZCP script will be converted to an nvlist. See zcp_lua_to_nvlist_impl() + * for details on exact allowed types and conversion. + * + * ZFS functionality is exposed to a ZCP script as a library of function calls. + * These calls are sorted into submodules, such as zfs.list and zfs.sync, for + * iterators and synctasks, respectively. Each of these submodules resides in + * its own source file, with a zcp_*_info structure describing each library + * call in the submodule. + * + * Error handling in ZCP scripts is handled by a number of different methods + * based on severity: + * + * 1. Memory and time limits are in place to prevent a channel program from + * consuming excessive system or running forever. If one of these limits is + * hit, the channel program will be stopped immediately and return from + * zcp_eval() with an error code. No attempt will be made to roll back or undo + * any changes made by the channel program before the error occured. + * Consumers invoking zcp_eval() from elsewhere in the kernel may pass a time + * limit of 0, disabling the time limit. + * + * 2. Internal Lua errors can occur as a result of a syntax error, calling a + * library function with incorrect arguments, invoking the error() function, + * failing an assert(), or other runtime errors. In these cases the channel + * program will stop executing and return from zcp_eval() with an error code. + * In place of a return value, an error message will also be returned in the + * 'result' nvlist containing information about the error. No attempt will be + * made to roll back or undo any changes made by the channel program before the + * error occured. + * + * 3. If an error occurs inside a ZFS library call which returns an error code, + * the error is returned to the Lua script to be handled as desired. + * + * In the first two cases, Lua's error-throwing mechanism is used, which + * longjumps out of the script execution with luaL_error() and returns with the + * error. + * + * See zfs-program(1M) for more information on high level usage. + */ + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef illumos +#include +#endif + +#ifdef __FreeBSD__ +#define ECHRNG EDOM +#define ETIME ETIMEDOUT +#endif + +#define ZCP_NVLIST_MAX_DEPTH 20 + +uint64_t zfs_lua_check_instrlimit_interval = 100; +uint64_t zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT; +uint64_t zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT; + +/* + * Forward declarations for mutually recursive functions + */ +static int zcp_nvpair_value_to_lua(lua_State *, nvpair_t *, char *, int); +static int zcp_lua_to_nvlist_impl(lua_State *, int, nvlist_t *, const char *, + int); + +typedef struct zcp_alloc_arg { + boolean_t aa_must_succeed; + int64_t aa_alloc_remaining; + int64_t aa_alloc_limit; +} zcp_alloc_arg_t; + +typedef struct zcp_eval_arg { + lua_State *ea_state; + zcp_alloc_arg_t *ea_allocargs; + cred_t *ea_cred; + nvlist_t *ea_outnvl; + int ea_result; + uint64_t ea_instrlimit; +} zcp_eval_arg_t; + +/*ARGSUSED*/ +static int +zcp_eval_check(void *arg, dmu_tx_t *tx) +{ + return (0); +} + +/* + * The outer-most error callback handler for use with lua_pcall(). On + * error Lua will call this callback with a single argument that + * represents the error value. In most cases this will be a string + * containing an error message, but channel programs can use Lua's + * error() function to return arbitrary objects as errors. This callback + * returns (on the Lua stack) the original error object along with a traceback. + * + * Fatal Lua errors can occur while resources are held, so we also call any + * registered cleanup function here. + */ +static int +zcp_error_handler(lua_State *state) +{ + const char *msg; + + zcp_cleanup(state); + + VERIFY3U(1, ==, lua_gettop(state)); + msg = lua_tostring(state, 1); + luaL_traceback(state, state, msg, 1); + return (1); +} + +int +zcp_argerror(lua_State *state, int narg, const char *msg, ...) +{ + va_list alist; + + va_start(alist, msg); + const char *buf = lua_pushvfstring(state, msg, alist); + va_end(alist); + + return (luaL_argerror(state, narg, buf)); +} + +/* + * Install a new cleanup function, which will be invoked with the given + * opaque argument if a fatal error causes the Lua interpreter to longjump out + * of a function call. + * + * If an error occurs, the cleanup function will be invoked exactly once and + * then unreigstered. + */ +void +zcp_register_cleanup(lua_State *state, zcp_cleanup_t cleanfunc, void *cleanarg) +{ + zcp_run_info_t *ri = zcp_run_info(state); + /* + * A cleanup function should always be explicitly removed before + * installing a new one to avoid accidental clobbering. + */ + ASSERT3P(ri->zri_cleanup, ==, NULL); + + ri->zri_cleanup = cleanfunc; + ri->zri_cleanup_arg = cleanarg; +} + +void +zcp_clear_cleanup(lua_State *state) +{ + zcp_run_info_t *ri = zcp_run_info(state); + + ri->zri_cleanup = NULL; + ri->zri_cleanup_arg = NULL; +} + +/* + * If it exists, execute the currently set cleanup function then unregister it. + */ +void +zcp_cleanup(lua_State *state) +{ + zcp_run_info_t *ri = zcp_run_info(state); + + if (ri->zri_cleanup != NULL) { + ri->zri_cleanup(ri->zri_cleanup_arg); + zcp_clear_cleanup(state); + } +} + +/* + * Convert the lua table at the given index on the Lua stack to an nvlist + * and return it. + * + * If the table can not be converted for any reason, NULL is returned and + * an error message is pushed onto the Lua stack. + */ +static nvlist_t * +zcp_table_to_nvlist(lua_State *state, int index, int depth) +{ + nvlist_t *nvl; + /* + * Converting a Lua table to an nvlist with key uniqueness checking is + * O(n^2) in the number of keys in the nvlist, which can take a long + * time when we return a large table from a channel program. + * Furthermore, Lua's table interface *almost* guarantees unique keys + * on its own (details below). Therefore, we don't use fnvlist_alloc() + * here to avoid the built-in uniqueness checking. + * + * The *almost* is because it's possible to have key collisions between + * e.g. the string "1" and the number 1, or the string "true" and the + * boolean true, so we explicitly check that when we're looking at a + * key which is an integer / boolean or a string that can be parsed as + * one of those types. In the worst case this could still devolve into + * O(n^2), so we only start doing these checks on boolean/integer keys + * once we've seen a string key which fits this weird usage pattern. + * + * Ultimately, we still want callers to know that the keys in this + * nvlist are unique, so before we return this we set the nvlist's + * flags to reflect that. + */ + VERIFY0(nvlist_alloc(&nvl, 0, KM_SLEEP)); + + /* + * Push an empty stack slot where lua_next() will store each + * table key. + */ + lua_pushnil(state); + boolean_t saw_str_could_collide = B_FALSE; + while (lua_next(state, index) != 0) { + /* + * The next key-value pair from the table at index is + * now on the stack, with the key at stack slot -2 and + * the value at slot -1. + */ + int err = 0; + char buf[32]; + const char *key = NULL; + boolean_t key_could_collide = B_FALSE; + + switch (lua_type(state, -2)) { + case LUA_TSTRING: + key = lua_tostring(state, -2); + + /* check if this could collide with a number or bool */ + long long tmp; + int parselen; + if ((sscanf(key, "%lld%n", &tmp, &parselen) > 0 && + parselen == strlen(key)) || + strcmp(key, "true") == 0 || + strcmp(key, "false") == 0) { + key_could_collide = B_TRUE; + saw_str_could_collide = B_TRUE; + } + break; + case LUA_TBOOLEAN: + key = (lua_toboolean(state, -2) == B_TRUE ? + "true" : "false"); + if (saw_str_could_collide) { + key_could_collide = B_TRUE; + } + break; + case LUA_TNUMBER: + VERIFY3U(sizeof (buf), >, + snprintf(buf, sizeof (buf), "%lld", + (longlong_t)lua_tonumber(state, -2))); + key = buf; + if (saw_str_could_collide) { + key_could_collide = B_TRUE; + } + break; + default: + fnvlist_free(nvl); + (void) lua_pushfstring(state, "Invalid key " + "type '%s' in table", + lua_typename(state, lua_type(state, -2))); + return (NULL); + } + /* + * Check for type-mismatched key collisions, and throw an error. + */ + if (key_could_collide && nvlist_exists(nvl, key)) { + fnvlist_free(nvl); + (void) lua_pushfstring(state, "Collision of " + "key '%s' in table", key); + return (NULL); + } + /* + * Recursively convert the table value and insert into + * the new nvlist with the parsed key. To prevent + * stack overflow on circular or heavily nested tables, + * we track the current nvlist depth. + */ + if (depth >= ZCP_NVLIST_MAX_DEPTH) { + fnvlist_free(nvl); + (void) lua_pushfstring(state, "Maximum table " + "depth (%d) exceeded for table", + ZCP_NVLIST_MAX_DEPTH); + return (NULL); + } + err = zcp_lua_to_nvlist_impl(state, -1, nvl, key, + depth + 1); + if (err != 0) { + fnvlist_free(nvl); + /* + * Error message has been pushed to the lua + * stack by the recursive call. + */ + return (NULL); + } + /* + * Pop the value pushed by lua_next(). + */ + lua_pop(state, 1); + } + + /* + * Mark the nvlist as having unique keys. This is a little ugly, but we + * ensured above that there are no duplicate keys in the nvlist. + */ + nvl->nvl_nvflag |= NV_UNIQUE_NAME; + + return (nvl); +} + +/* + * Convert a value from the given index into the lua stack to an nvpair, adding + * it to an nvlist with the given key. + * + * Values are converted as follows: + * + * string -> string + * number -> int64 + * boolean -> boolean + * nil -> boolean (no value) + * + * Lua tables are converted to nvlists and then inserted. The table's keys + * are converted to strings then used as keys in the nvlist to store each table + * element. Keys are converted as follows: + * + * string -> no change + * number -> "%lld" + * boolean -> "true" | "false" + * nil -> error + * + * In the case of a key collision, an error is thrown. + * + * If an error is encountered, a nonzero error code is returned, and an error + * string will be pushed onto the Lua stack. + */ +static int +zcp_lua_to_nvlist_impl(lua_State *state, int index, nvlist_t *nvl, + const char *key, int depth) +{ + /* + * Verify that we have enough remaining space in the lua stack to parse + * a key-value pair and push an error. + */ + if (!lua_checkstack(state, 3)) { + (void) lua_pushstring(state, "Lua stack overflow"); + return (1); + } + + index = lua_absindex(state, index); + + switch (lua_type(state, index)) { + case LUA_TNIL: + fnvlist_add_boolean(nvl, key); + break; + case LUA_TBOOLEAN: + fnvlist_add_boolean_value(nvl, key, + lua_toboolean(state, index)); + break; + case LUA_TNUMBER: + fnvlist_add_int64(nvl, key, lua_tonumber(state, index)); + break; + case LUA_TSTRING: + fnvlist_add_string(nvl, key, lua_tostring(state, index)); + break; + case LUA_TTABLE: { + nvlist_t *value_nvl = zcp_table_to_nvlist(state, index, depth); + if (value_nvl == NULL) + return (EINVAL); + + fnvlist_add_nvlist(nvl, key, value_nvl); + fnvlist_free(value_nvl); + break; + } + default: + (void) lua_pushfstring(state, + "Invalid value type '%s' for key '%s'", + lua_typename(state, lua_type(state, index)), key); + return (EINVAL); + } + + return (0); +} + +/* + * Convert a lua value to an nvpair, adding it to an nvlist with the given key. + */ +void +zcp_lua_to_nvlist(lua_State *state, int index, nvlist_t *nvl, const char *key) +{ + /* + * On error, zcp_lua_to_nvlist_impl pushes an error string onto the Lua + * stack before returning with a nonzero error code. If an error is + * returned, throw a fatal lua error with the given string. + */ + if (zcp_lua_to_nvlist_impl(state, index, nvl, key, 0) != 0) + (void) lua_error(state); +} + +int +zcp_lua_to_nvlist_helper(lua_State *state) +{ + nvlist_t *nv = (nvlist_t *)lua_touserdata(state, 2); + const char *key = (const char *)lua_touserdata(state, 1); + zcp_lua_to_nvlist(state, 3, nv, key); + return (0); +} + +void +zcp_convert_return_values(lua_State *state, nvlist_t *nvl, + const char *key, zcp_eval_arg_t *evalargs) +{ + int err; + lua_pushcfunction(state, zcp_lua_to_nvlist_helper); + lua_pushlightuserdata(state, (char *)key); + lua_pushlightuserdata(state, nvl); + lua_pushvalue(state, 1); + lua_remove(state, 1); + err = lua_pcall(state, 3, 0, 0); /* zcp_lua_to_nvlist_helper */ + if (err != 0) { + zcp_lua_to_nvlist(state, 1, nvl, ZCP_RET_ERROR); + evalargs->ea_result = SET_ERROR(ECHRNG); + } +} + +/* + * Push a Lua table representing nvl onto the stack. If it can't be + * converted, return EINVAL, fill in errbuf, and push nothing. errbuf may + * be specified as NULL, in which case no error string will be output. + * + * Most nvlists are converted as simple key->value Lua tables, but we make + * an exception for the case where all nvlist entries are BOOLEANs (a string + * key without a value). In Lua, a table key pointing to a value of Nil + * (no value) is equivalent to the key not existing, so a BOOLEAN nvlist + * entry can't be directly converted to a Lua table entry. Nvlists of entirely + * BOOLEAN entries are frequently used to pass around lists of datasets, so for + * convenience we check for this case, and convert it to a simple Lua array of + * strings. + */ +int +zcp_nvlist_to_lua(lua_State *state, nvlist_t *nvl, + char *errbuf, int errbuf_len) +{ + nvpair_t *pair; + lua_newtable(state); + boolean_t has_values = B_FALSE; + /* + * If the list doesn't have any values, just convert it to a string + * array. + */ + for (pair = nvlist_next_nvpair(nvl, NULL); + pair != NULL; pair = nvlist_next_nvpair(nvl, pair)) { + if (nvpair_type(pair) != DATA_TYPE_BOOLEAN) { + has_values = B_TRUE; + break; + } + } + if (!has_values) { + int i = 1; + for (pair = nvlist_next_nvpair(nvl, NULL); + pair != NULL; pair = nvlist_next_nvpair(nvl, pair)) { + (void) lua_pushinteger(state, i); + (void) lua_pushstring(state, nvpair_name(pair)); + (void) lua_settable(state, -3); + i++; + } + } else { + for (pair = nvlist_next_nvpair(nvl, NULL); + pair != NULL; pair = nvlist_next_nvpair(nvl, pair)) { + int err = zcp_nvpair_value_to_lua(state, pair, + errbuf, errbuf_len); + if (err != 0) { + lua_pop(state, 1); + return (err); + } + (void) lua_setfield(state, -2, nvpair_name(pair)); + } + } + return (0); +} + +/* + * Push a Lua object representing the value of "pair" onto the stack. + * + * Only understands boolean_value, string, int64, nvlist, + * string_array, and int64_array type values. For other + * types, returns EINVAL, fills in errbuf, and pushes nothing. + */ +static int +zcp_nvpair_value_to_lua(lua_State *state, nvpair_t *pair, + char *errbuf, int errbuf_len) +{ + int err = 0; + + if (pair == NULL) { + lua_pushnil(state); + return (0); + } + + switch (nvpair_type(pair)) { + case DATA_TYPE_BOOLEAN_VALUE: + (void) lua_pushboolean(state, + fnvpair_value_boolean_value(pair)); + break; + case DATA_TYPE_STRING: + (void) lua_pushstring(state, fnvpair_value_string(pair)); + break; + case DATA_TYPE_INT64: + (void) lua_pushinteger(state, fnvpair_value_int64(pair)); + break; + case DATA_TYPE_NVLIST: + err = zcp_nvlist_to_lua(state, + fnvpair_value_nvlist(pair), errbuf, errbuf_len); + break; + case DATA_TYPE_STRING_ARRAY: { + char **strarr; + uint_t nelem; + (void) nvpair_value_string_array(pair, &strarr, &nelem); + lua_newtable(state); + for (int i = 0; i < nelem; i++) { + (void) lua_pushinteger(state, i + 1); + (void) lua_pushstring(state, strarr[i]); + (void) lua_settable(state, -3); + } + break; + } + case DATA_TYPE_UINT64_ARRAY: { + uint64_t *intarr; + uint_t nelem; + (void) nvpair_value_uint64_array(pair, &intarr, &nelem); + lua_newtable(state); + for (int i = 0; i < nelem; i++) { + (void) lua_pushinteger(state, i + 1); + (void) lua_pushinteger(state, intarr[i]); + (void) lua_settable(state, -3); + } + break; + } + case DATA_TYPE_INT64_ARRAY: { + int64_t *intarr; + uint_t nelem; + (void) nvpair_value_int64_array(pair, &intarr, &nelem); + lua_newtable(state); + for (int i = 0; i < nelem; i++) { + (void) lua_pushinteger(state, i + 1); + (void) lua_pushinteger(state, intarr[i]); + (void) lua_settable(state, -3); + } + break; + } + default: { + if (errbuf != NULL) { + (void) snprintf(errbuf, errbuf_len, + "Unhandled nvpair type %d for key '%s'", + nvpair_type(pair), nvpair_name(pair)); + } + return (EINVAL); + } + } + return (err); +} + +int +zcp_dataset_hold_error(lua_State *state, dsl_pool_t *dp, const char *dsname, + int error) +{ + if (error == ENOENT) { + (void) zcp_argerror(state, 1, "no such dataset '%s'", dsname); + return (0); /* not reached; zcp_argerror will longjmp */ + } else if (error == EXDEV) { + (void) zcp_argerror(state, 1, + "dataset '%s' is not in the target pool '%s'", + dsname, spa_name(dp->dp_spa)); + return (0); /* not reached; zcp_argerror will longjmp */ + } else if (error == EIO) { + (void) luaL_error(state, + "I/O error while accessing dataset '%s'", dsname); + return (0); /* not reached; luaL_error will longjmp */ + } else if (error != 0) { + (void) luaL_error(state, + "unexpected error %d while accessing dataset '%s'", + error, dsname); + return (0); /* not reached; luaL_error will longjmp */ + } + return (0); +} + +/* + * Note: will longjmp (via lua_error()) on error. + * Assumes that the dsname is argument #1 (for error reporting purposes). + */ +dsl_dataset_t * +zcp_dataset_hold(lua_State *state, dsl_pool_t *dp, const char *dsname, + void *tag) +{ + dsl_dataset_t *ds; + int error = dsl_dataset_hold(dp, dsname, tag, &ds); + (void) zcp_dataset_hold_error(state, dp, dsname, error); + return (ds); +} + +static int zcp_debug(lua_State *); +static zcp_lib_info_t zcp_debug_info = { + .name = "debug", + .func = zcp_debug, + .pargs = { + { .za_name = "debug string", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_debug(lua_State *state) +{ + const char *dbgstring; + zcp_run_info_t *ri = zcp_run_info(state); + zcp_lib_info_t *libinfo = &zcp_debug_info; + + zcp_parse_args(state, libinfo->name, libinfo->pargs, libinfo->kwargs); + + dbgstring = lua_tostring(state, 1); + + zfs_dbgmsg("txg %lld ZCP: %s", ri->zri_tx->tx_txg, dbgstring); + + return (0); +} + +static int zcp_exists(lua_State *); +static zcp_lib_info_t zcp_exists_info = { + .name = "exists", + .func = zcp_exists, + .pargs = { + { .za_name = "dataset", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_exists(lua_State *state) +{ + zcp_run_info_t *ri = zcp_run_info(state); + dsl_pool_t *dp = ri->zri_pool; + zcp_lib_info_t *libinfo = &zcp_exists_info; + + zcp_parse_args(state, libinfo->name, libinfo->pargs, libinfo->kwargs); + + const char *dsname = lua_tostring(state, 1); + + dsl_dataset_t *ds; + int error = dsl_dataset_hold(dp, dsname, FTAG, &ds); + if (error == 0) { + dsl_dataset_rele(ds, FTAG); + lua_pushboolean(state, B_TRUE); + } else if (error == ENOENT) { + lua_pushboolean(state, B_FALSE); + } else if (error == EXDEV) { + return (luaL_error(state, "dataset '%s' is not in the " + "target pool", dsname)); + } else if (error == EIO) { + return (luaL_error(state, "I/O error opening dataset '%s'", + dsname)); + } else if (error != 0) { + return (luaL_error(state, "unexpected error %d", error)); + } + + return (1); +} + +/* + * Allocate/realloc/free a buffer for the lua interpreter. + * + * When nsize is 0, behaves as free() and returns NULL. + * + * If ptr is NULL, behaves as malloc() and returns an allocated buffer of size + * at least nsize. + * + * Otherwise, behaves as realloc(), changing the allocation from osize to nsize. + * Shrinking the buffer size never fails. + * + * The original allocated buffer size is stored as a uint64 at the beginning of + * the buffer to avoid actually reallocating when shrinking a buffer, since lua + * requires that this operation never fail. + */ +static void * +zcp_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + zcp_alloc_arg_t *allocargs = ud; + int flags = (allocargs->aa_must_succeed) ? + KM_SLEEP : (KM_NOSLEEP | KM_NORMALPRI); + + if (nsize == 0) { + if (ptr != NULL) { + int64_t *allocbuf = (int64_t *)ptr - 1; + int64_t allocsize = *allocbuf; + ASSERT3S(allocsize, >, 0); + ASSERT3S(allocargs->aa_alloc_remaining + allocsize, <=, + allocargs->aa_alloc_limit); + allocargs->aa_alloc_remaining += allocsize; + kmem_free(allocbuf, allocsize); + } + return (NULL); + } else if (ptr == NULL) { + int64_t *allocbuf; + int64_t allocsize = nsize + sizeof (int64_t); + + if (!allocargs->aa_must_succeed && + (allocsize <= 0 || + allocsize > allocargs->aa_alloc_remaining)) { + return (NULL); + } + + allocbuf = kmem_alloc(allocsize, flags); + if (allocbuf == NULL) { + return (NULL); + } + allocargs->aa_alloc_remaining -= allocsize; + + *allocbuf = allocsize; + return (allocbuf + 1); + } else if (nsize <= osize) { + /* + * If shrinking the buffer, lua requires that the reallocation + * never fail. + */ + return (ptr); + } else { + ASSERT3U(nsize, >, osize); + + uint64_t *luabuf = zcp_lua_alloc(ud, NULL, 0, nsize); + if (luabuf == NULL) { + return (NULL); + } + (void) memcpy(luabuf, ptr, osize); + VERIFY3P(zcp_lua_alloc(ud, ptr, osize, 0), ==, NULL); + return (luabuf); + } +} + +/* ARGSUSED */ +static void +zcp_lua_counthook(lua_State *state, lua_Debug *ar) +{ + /* + * If we're called, check how many instructions the channel program has + * executed so far, and compare against the limit. + */ + lua_getfield(state, LUA_REGISTRYINDEX, ZCP_RUN_INFO_KEY); + zcp_run_info_t *ri = lua_touserdata(state, -1); + + ri->zri_curinstrs += zfs_lua_check_instrlimit_interval; + if (ri->zri_maxinstrs != 0 && ri->zri_curinstrs > ri->zri_maxinstrs) { + ri->zri_timed_out = B_TRUE; + (void) lua_pushstring(state, + "Channel program timed out."); + (void) lua_error(state); + } +} + +static int +zcp_panic_cb(lua_State *state) +{ + panic("unprotected error in call to Lua API (%s)\n", + lua_tostring(state, -1)); + return (0); +} + +static void +zcp_eval_sync(void *arg, dmu_tx_t *tx) +{ + int err; + zcp_run_info_t ri; + zcp_eval_arg_t *evalargs = arg; + lua_State *state = evalargs->ea_state; + + /* + * Open context should have setup the stack to contain: + * 1: Error handler callback + * 2: Script to run (converted to a Lua function) + * 3: nvlist input to function (converted to Lua table or nil) + */ + VERIFY3U(3, ==, lua_gettop(state)); + + /* + * Store the zcp_run_info_t struct for this run in the Lua registry. + * Registry entries are not directly accessible by the Lua scripts but + * can be accessed by our callbacks. + */ + ri.zri_space_used = 0; + ri.zri_pool = dmu_tx_pool(tx); + ri.zri_cred = evalargs->ea_cred; + ri.zri_tx = tx; + ri.zri_timed_out = B_FALSE; + ri.zri_cleanup = NULL; + ri.zri_cleanup_arg = NULL; + ri.zri_curinstrs = 0; + ri.zri_maxinstrs = evalargs->ea_instrlimit; + + lua_pushlightuserdata(state, &ri); + lua_setfield(state, LUA_REGISTRYINDEX, ZCP_RUN_INFO_KEY); + VERIFY3U(3, ==, lua_gettop(state)); + + /* + * Tell the Lua interpreter to call our handler every count + * instructions. Channel programs that execute too many instructions + * should die with ETIMEDOUT. + */ + (void) lua_sethook(state, zcp_lua_counthook, LUA_MASKCOUNT, + zfs_lua_check_instrlimit_interval); + + /* + * Tell the Lua memory allocator to stop using KM_SLEEP before handing + * off control to the channel program. Channel programs that use too + * much memory should die with ENOSPC. + */ + evalargs->ea_allocargs->aa_must_succeed = B_FALSE; + + /* + * Call the Lua function that open-context passed us. This pops the + * function and its input from the stack and pushes any return + * or error values. + */ + err = lua_pcall(state, 1, LUA_MULTRET, 1); + + /* + * Let Lua use KM_SLEEP while we interpret the return values. + */ + evalargs->ea_allocargs->aa_must_succeed = B_TRUE; + + /* + * Remove the error handler callback from the stack. At this point, + * if there is a cleanup function registered, then it was registered + * but never run or removed, which should never occur. + */ + ASSERT3P(ri.zri_cleanup, ==, NULL); + lua_remove(state, 1); + + switch (err) { + case LUA_OK: { + /* + * Lua supports returning multiple values in a single return + * statement. Return values will have been pushed onto the + * stack: + * 1: Return value 1 + * 2: Return value 2 + * 3: etc... + * To simplify the process of retrieving a return value from a + * channel program, we disallow returning more than one value + * to ZFS from the Lua script, yielding a singleton return + * nvlist of the form { "return": Return value 1 }. + */ + int return_count = lua_gettop(state); + + if (return_count == 1) { + evalargs->ea_result = 0; + zcp_convert_return_values(state, evalargs->ea_outnvl, + ZCP_RET_RETURN, evalargs); + } else if (return_count > 1) { + evalargs->ea_result = SET_ERROR(ECHRNG); + (void) lua_pushfstring(state, "Multiple return " + "values not supported"); + zcp_convert_return_values(state, evalargs->ea_outnvl, + ZCP_RET_ERROR, evalargs); + } + break; + } + case LUA_ERRRUN: + case LUA_ERRGCMM: { + /* + * The channel program encountered a fatal error within the + * script, such as failing an assertion, or calling a function + * with incompatible arguments. The error value and the + * traceback generated by zcp_error_handler() should be on the + * stack. + */ + VERIFY3U(1, ==, lua_gettop(state)); + if (ri.zri_timed_out) { + evalargs->ea_result = SET_ERROR(ETIME); + } else { + evalargs->ea_result = SET_ERROR(ECHRNG); + } + + zcp_convert_return_values(state, evalargs->ea_outnvl, + ZCP_RET_ERROR, evalargs); + break; + } + case LUA_ERRERR: { + /* + * The channel program encountered a fatal error within the + * script, and we encountered another error while trying to + * compute the traceback in zcp_error_handler(). We can only + * return the error message. + */ + VERIFY3U(1, ==, lua_gettop(state)); + if (ri.zri_timed_out) { + evalargs->ea_result = SET_ERROR(ETIME); + } else { + evalargs->ea_result = SET_ERROR(ECHRNG); + } + + zcp_convert_return_values(state, evalargs->ea_outnvl, + ZCP_RET_ERROR, evalargs); + break; + } + case LUA_ERRMEM: + /* + * Lua ran out of memory while running the channel program. + * There's not much we can do. + */ + evalargs->ea_result = SET_ERROR(ENOSPC); + break; + default: + VERIFY0(err); + } +} + +int +zcp_eval(const char *poolname, const char *program, uint64_t instrlimit, + uint64_t memlimit, nvpair_t *nvarg, nvlist_t *outnvl) +{ + int err; + lua_State *state; + zcp_eval_arg_t evalargs; + + if (instrlimit > zfs_lua_max_instrlimit) + return (SET_ERROR(EINVAL)); + if (memlimit == 0 || memlimit > zfs_lua_max_memlimit) + return (SET_ERROR(EINVAL)); + + zcp_alloc_arg_t allocargs = { + .aa_must_succeed = B_TRUE, + .aa_alloc_remaining = (int64_t)memlimit, + .aa_alloc_limit = (int64_t)memlimit, + }; + + /* + * Creates a Lua state with a memory allocator that uses KM_SLEEP. + * This should never fail. + */ + state = lua_newstate(zcp_lua_alloc, &allocargs); + VERIFY(state != NULL); + (void) lua_atpanic(state, zcp_panic_cb); + + /* + * Load core Lua libraries we want access to. + */ + VERIFY3U(1, ==, luaopen_base(state)); + lua_pop(state, 1); + VERIFY3U(1, ==, luaopen_coroutine(state)); + lua_setglobal(state, LUA_COLIBNAME); + VERIFY0(lua_gettop(state)); + VERIFY3U(1, ==, luaopen_string(state)); + lua_setglobal(state, LUA_STRLIBNAME); + VERIFY0(lua_gettop(state)); + VERIFY3U(1, ==, luaopen_table(state)); + lua_setglobal(state, LUA_TABLIBNAME); + VERIFY0(lua_gettop(state)); + + /* + * Load globally visible variables such as errno aliases. + */ + zcp_load_globals(state); + VERIFY0(lua_gettop(state)); + + /* + * Load ZFS-specific modules. + */ + lua_newtable(state); + VERIFY3U(1, ==, zcp_load_list_lib(state)); + lua_setfield(state, -2, "list"); + VERIFY3U(1, ==, zcp_load_synctask_lib(state, B_FALSE)); + lua_setfield(state, -2, "check"); + VERIFY3U(1, ==, zcp_load_synctask_lib(state, B_TRUE)); + lua_setfield(state, -2, "sync"); + VERIFY3U(1, ==, zcp_load_get_lib(state)); + lua_pushcclosure(state, zcp_debug_info.func, 0); + lua_setfield(state, -2, zcp_debug_info.name); + lua_pushcclosure(state, zcp_exists_info.func, 0); + lua_setfield(state, -2, zcp_exists_info.name); + lua_setglobal(state, "zfs"); + VERIFY0(lua_gettop(state)); + + /* + * Push the error-callback that calculates Lua stack traces on + * unexpected failures. + */ + lua_pushcfunction(state, zcp_error_handler); + VERIFY3U(1, ==, lua_gettop(state)); + + /* + * Load the actual script as a function onto the stack as text ("t"). + * The only valid error condition is a syntax error in the script. + * ERRMEM should not be possible because our allocator is using + * KM_SLEEP. ERRGCMM should not be possible because we have not added + * any objects with __gc metamethods to the interpreter that could + * fail. + */ + err = luaL_loadbufferx(state, program, strlen(program), + "channel program", "t"); + if (err == LUA_ERRSYNTAX) { + fnvlist_add_string(outnvl, ZCP_RET_ERROR, + lua_tostring(state, -1)); + lua_close(state); + return (SET_ERROR(EINVAL)); + } + VERIFY0(err); + VERIFY3U(2, ==, lua_gettop(state)); + + /* + * Convert the input nvlist to a Lua object and put it on top of the + * stack. + */ + char errmsg[128]; + err = zcp_nvpair_value_to_lua(state, nvarg, + errmsg, sizeof (errmsg)); + if (err != 0) { + fnvlist_add_string(outnvl, ZCP_RET_ERROR, errmsg); + lua_close(state); + return (SET_ERROR(EINVAL)); + } + VERIFY3U(3, ==, lua_gettop(state)); + + evalargs.ea_state = state; + evalargs.ea_allocargs = &allocargs; + evalargs.ea_instrlimit = instrlimit; + evalargs.ea_cred = CRED(); + evalargs.ea_outnvl = outnvl; + evalargs.ea_result = 0; + + VERIFY0(dsl_sync_task(poolname, zcp_eval_check, + zcp_eval_sync, &evalargs, 0, ZFS_SPACE_CHECK_NONE)); + + lua_close(state); + + return (evalargs.ea_result); +} + +/* + * Retrieve metadata about the currently running channel program. + */ +zcp_run_info_t * +zcp_run_info(lua_State *state) +{ + zcp_run_info_t *ri; + + lua_getfield(state, LUA_REGISTRYINDEX, ZCP_RUN_INFO_KEY); + ri = lua_touserdata(state, -1); + lua_pop(state, 1); + return (ri); +} + +/* + * Argument Parsing + * ================ + * + * The Lua language allows methods to be called with any number + * of arguments of any type. When calling back into ZFS we need to sanitize + * arguments from channel programs to make sure unexpected arguments or + * arguments of the wrong type result in clear error messages. To do this + * in a uniform way all callbacks from channel programs should use the + * zcp_parse_args() function to interpret inputs. + * + * Positional vs Keyword Arguments + * =============================== + * + * Every callback function takes a fixed set of required positional arguments + * and optional keyword arguments. For example, the destroy function takes + * a single positional string argument (the name of the dataset to destroy) + * and an optional "defer" keyword boolean argument. When calling lua functions + * with parentheses, only positional arguments can be used: + * + * zfs.sync.snapshot("rpool@snap") + * + * To use keyword arguments functions should be called with a single argument + * that is a lua table containing mappings of integer -> positional arguments + * and string -> keyword arguments: + * + * zfs.sync.snapshot({1="rpool@snap", defer=true}) + * + * The lua language allows curly braces to be used in place of parenthesis as + * syntactic sugar for this calling convention: + * + * zfs.sync.snapshot{"rpool@snap", defer=true} + */ + +/* + * Throw an error and print the given arguments. If there are too many + * arguments to fit in the output buffer, only the error format string is + * output. + */ +static void +zcp_args_error(lua_State *state, const char *fname, const zcp_arg_t *pargs, + const zcp_arg_t *kwargs, const char *fmt, ...) +{ + int i; + char errmsg[512]; + size_t len = sizeof (errmsg); + size_t msglen = 0; + va_list argp; + + va_start(argp, fmt); + VERIFY3U(len, >, vsnprintf(errmsg, len, fmt, argp)); + va_end(argp); + + /* + * Calculate the total length of the final string, including extra + * formatting characters. If the argument dump would be too large, + * only print the error string. + */ + msglen = strlen(errmsg); + msglen += strlen(fname) + 4; /* : + {} + null terminator */ + for (i = 0; pargs[i].za_name != NULL; i++) { + msglen += strlen(pargs[i].za_name); + msglen += strlen(lua_typename(state, pargs[i].za_lua_type)); + if (pargs[i + 1].za_name != NULL || kwargs[0].za_name != NULL) + msglen += 5; /* < + ( + )> + , */ + else + msglen += 4; /* < + ( + )> */ + } + for (i = 0; kwargs[i].za_name != NULL; i++) { + msglen += strlen(kwargs[i].za_name); + msglen += strlen(lua_typename(state, kwargs[i].za_lua_type)); + if (kwargs[i + 1].za_name != NULL) + msglen += 4; /* =( + ) + , */ + else + msglen += 3; /* =( + ) */ + } + + if (msglen >= len) + (void) luaL_error(state, errmsg); + + VERIFY3U(len, >, strlcat(errmsg, ": ", len)); + VERIFY3U(len, >, strlcat(errmsg, fname, len)); + VERIFY3U(len, >, strlcat(errmsg, "{", len)); + for (i = 0; pargs[i].za_name != NULL; i++) { + VERIFY3U(len, >, strlcat(errmsg, "<", len)); + VERIFY3U(len, >, strlcat(errmsg, pargs[i].za_name, len)); + VERIFY3U(len, >, strlcat(errmsg, "(", len)); + VERIFY3U(len, >, strlcat(errmsg, + lua_typename(state, pargs[i].za_lua_type), len)); + VERIFY3U(len, >, strlcat(errmsg, ")>", len)); + if (pargs[i + 1].za_name != NULL || kwargs[0].za_name != NULL) { + VERIFY3U(len, >, strlcat(errmsg, ", ", len)); + } + } + for (i = 0; kwargs[i].za_name != NULL; i++) { + VERIFY3U(len, >, strlcat(errmsg, kwargs[i].za_name, len)); + VERIFY3U(len, >, strlcat(errmsg, "=(", len)); + VERIFY3U(len, >, strlcat(errmsg, + lua_typename(state, kwargs[i].za_lua_type), len)); + VERIFY3U(len, >, strlcat(errmsg, ")", len)); + if (kwargs[i + 1].za_name != NULL) { + VERIFY3U(len, >, strlcat(errmsg, ", ", len)); + } + } + VERIFY3U(len, >, strlcat(errmsg, "}", len)); + + (void) luaL_error(state, errmsg); + panic("unreachable code"); +} + +static void +zcp_parse_table_args(lua_State *state, const char *fname, + const zcp_arg_t *pargs, const zcp_arg_t *kwargs) +{ + int i; + int type; + + for (i = 0; pargs[i].za_name != NULL; i++) { + /* + * Check the table for this positional argument, leaving it + * on the top of the stack once we finish validating it. + */ + lua_pushinteger(state, i + 1); + lua_gettable(state, 1); + + type = lua_type(state, -1); + if (type == LUA_TNIL) { + zcp_args_error(state, fname, pargs, kwargs, + "too few arguments"); + panic("unreachable code"); + } else if (type != pargs[i].za_lua_type) { + zcp_args_error(state, fname, pargs, kwargs, + "arg %d wrong type (is '%s', expected '%s')", + i + 1, lua_typename(state, type), + lua_typename(state, pargs[i].za_lua_type)); + panic("unreachable code"); + } + + /* + * Remove the positional argument from the table. + */ + lua_pushinteger(state, i + 1); + lua_pushnil(state); + lua_settable(state, 1); + } + + for (i = 0; kwargs[i].za_name != NULL; i++) { + /* + * Check the table for this keyword argument, which may be + * nil if it was omitted. Leave the value on the top of + * the stack after validating it. + */ + lua_getfield(state, 1, kwargs[i].za_name); + + type = lua_type(state, -1); + if (type != LUA_TNIL && type != kwargs[i].za_lua_type) { + zcp_args_error(state, fname, pargs, kwargs, + "kwarg '%s' wrong type (is '%s', expected '%s')", + kwargs[i].za_name, lua_typename(state, type), + lua_typename(state, kwargs[i].za_lua_type)); + panic("unreachable code"); + } + + /* + * Remove the keyword argument from the table. + */ + lua_pushnil(state); + lua_setfield(state, 1, kwargs[i].za_name); + } + + /* + * Any entries remaining in the table are invalid inputs, print + * an error message based on what the entry is. + */ + lua_pushnil(state); + if (lua_next(state, 1)) { + if (lua_isnumber(state, -2) && lua_tointeger(state, -2) > 0) { + zcp_args_error(state, fname, pargs, kwargs, + "too many positional arguments"); + } else if (lua_isstring(state, -2)) { + zcp_args_error(state, fname, pargs, kwargs, + "invalid kwarg '%s'", lua_tostring(state, -2)); + } else { + zcp_args_error(state, fname, pargs, kwargs, + "kwarg keys must be strings"); + } + panic("unreachable code"); + } + + lua_remove(state, 1); +} + +static void +zcp_parse_pos_args(lua_State *state, const char *fname, const zcp_arg_t *pargs, + const zcp_arg_t *kwargs) +{ + int i; + int type; + + for (i = 0; pargs[i].za_name != NULL; i++) { + type = lua_type(state, i + 1); + if (type == LUA_TNONE) { + zcp_args_error(state, fname, pargs, kwargs, + "too few arguments"); + panic("unreachable code"); + } else if (type != pargs[i].za_lua_type) { + zcp_args_error(state, fname, pargs, kwargs, + "arg %d wrong type (is '%s', expected '%s')", + i + 1, lua_typename(state, type), + lua_typename(state, pargs[i].za_lua_type)); + panic("unreachable code"); + } + } + if (lua_gettop(state) != i) { + zcp_args_error(state, fname, pargs, kwargs, + "too many positional arguments"); + panic("unreachable code"); + } + + for (i = 0; kwargs[i].za_name != NULL; i++) { + lua_pushnil(state); + } +} + +/* + * Checks the current Lua stack against an expected set of positional and + * keyword arguments. If the stack does not match the expected arguments + * aborts the current channel program with a useful error message, otherwise + * it re-arranges the stack so that it contains the positional arguments + * followed by the keyword argument values in declaration order. Any missing + * keyword argument will be represented by a nil value on the stack. + * + * If the stack contains exactly one argument of type LUA_TTABLE the curly + * braces calling convention is assumed, otherwise the stack is parsed for + * positional arguments only. + * + * This function should be used by every function callback. It should be called + * before the callback manipulates the Lua stack as it assumes the stack + * represents the function arguments. + */ +void +zcp_parse_args(lua_State *state, const char *fname, const zcp_arg_t *pargs, + const zcp_arg_t *kwargs) +{ + if (lua_gettop(state) == 1 && lua_istable(state, 1)) { + zcp_parse_table_args(state, fname, pargs, kwargs); + } else { + zcp_parse_pos_args(state, fname, pargs, kwargs); + } +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_get.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_get.c new file mode 100644 index 000000000000..6afdaaf1c492 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_get.c @@ -0,0 +1,855 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _KERNEL +#include +#endif + +static int +get_objset_type(dsl_dataset_t *ds, zfs_type_t *type) +{ + int error; + objset_t *os; + error = dmu_objset_from_ds(ds, &os); + if (error != 0) + return (error); + if (ds->ds_is_snapshot) { + *type = ZFS_TYPE_SNAPSHOT; + } else { + switch (os->os_phys->os_type) { + case DMU_OST_ZFS: + *type = ZFS_TYPE_FILESYSTEM; + break; + case DMU_OST_ZVOL: + *type = ZFS_TYPE_VOLUME; + break; + default: + return (EINVAL); + } + } + return (0); +} + +/* + * Returns the string name of ds's type in str (a buffer which should be + * at least 12 bytes long). + */ +static int +get_objset_type_name(dsl_dataset_t *ds, char *str) +{ + int error; + zfs_type_t type; + error = get_objset_type(ds, &type); + if (error != 0) + return (error); + switch (type) { + case ZFS_TYPE_SNAPSHOT: + (void) strcpy(str, "snapshot"); + break; + case ZFS_TYPE_FILESYSTEM: + (void) strcpy(str, "filesystem"); + break; + case ZFS_TYPE_VOLUME: + (void) strcpy(str, "volume"); + break; + default: + return (EINVAL); + } + return (0); +} + +/* + * Determines the source of a property given its setpoint and + * property type. It pushes the source to the lua stack. + */ +static void +get_prop_src(lua_State *state, const char *setpoint, zfs_prop_t prop) +{ + if (zfs_prop_readonly(prop) || (prop == ZFS_PROP_VERSION)) { + lua_pushnil(state); + } else { + const char *src; + if (strcmp("", setpoint) == 0) { + src = "default"; + } else { + src = setpoint; + } + (void) lua_pushstring(state, src); + } +} + +/* + * Given an error encountered while getting properties, either longjmp's for + * a fatal error or pushes nothing to the stack for a non fatal one. + */ +static int +zcp_handle_error(lua_State *state, const char *dataset_name, + const char *property_name, int error) +{ + ASSERT3S(error, !=, 0); + if (error == ENOENT) { + return (0); + } else if (error == EINVAL) { + return (luaL_error(state, + "property '%s' is not a valid property on dataset '%s'", + property_name, dataset_name)); + } else if (error == EIO) { + return (luaL_error(state, + "I/O error while retrieving property '%s' on dataset '%s'", + property_name, dataset_name)); + } else { + return (luaL_error(state, "unexpected error %d while " + "retrieving property '%s' on dataset '%s'", + error, property_name, dataset_name)); + } +} + +/* + * Look up a user defined property in the zap object. If it exists, push it + * and the setpoint onto the stack, otherwise don't push anything. + */ +static int +zcp_get_user_prop(lua_State *state, dsl_pool_t *dp, const char *dataset_name, + const char *property_name) +{ + int error; + char *buf; + char setpoint[ZFS_MAX_DATASET_NAME_LEN]; + /* + * zcp_dataset_hold will either successfully return the requested + * dataset or throw a lua error and longjmp out of the zfs.get_prop call + * without returning. + */ + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dataset_name, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + buf = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP); + error = dsl_prop_get_ds(ds, property_name, 1, ZAP_MAXVALUELEN, + buf, setpoint); + dsl_dataset_rele(ds, FTAG); + + if (error != 0) { + kmem_free(buf, ZAP_MAXVALUELEN); + return (zcp_handle_error(state, dataset_name, property_name, + error)); + } + (void) lua_pushstring(state, buf); + (void) lua_pushstring(state, setpoint); + kmem_free(buf, ZAP_MAXVALUELEN); + return (2); +} + +/* + * Check if the property we're looking for is stored in the ds_dir. If so, + * return it in the 'val' argument. Return 0 on success and ENOENT and if + * the property is not present. + */ +static int +get_dsl_dir_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, + uint64_t *val) +{ + dsl_dir_t *dd = ds->ds_dir; + mutex_enter(&dd->dd_lock); + switch (zfs_prop) { + case ZFS_PROP_USEDSNAP: + *val = dsl_dir_get_usedsnap(dd); + break; + case ZFS_PROP_USEDCHILD: + *val = dsl_dir_get_usedchild(dd); + break; + case ZFS_PROP_USEDDS: + *val = dsl_dir_get_usedds(dd); + break; + case ZFS_PROP_USEDREFRESERV: + *val = dsl_dir_get_usedrefreserv(dd); + break; + case ZFS_PROP_LOGICALUSED: + *val = dsl_dir_get_logicalused(dd); + break; + default: + mutex_exit(&dd->dd_lock); + return (ENOENT); + } + mutex_exit(&dd->dd_lock); + return (0); +} + +/* + * Takes a dataset, a property, a value and that value's setpoint as + * found in the ZAP. Checks if the property has been changed in the vfs. + * If so, val and setpoint will be overwritten with updated content. + * Otherwise, they are left unchanged. + */ +static int +get_temporary_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, uint64_t *val, + char *setpoint) +{ +#ifndef _KERNEL + return (0); +#else + int error; + zfsvfs_t *zfvp; + vfs_t *vfsp; + objset_t *os; + uint64_t tmp = *val; + + error = dmu_objset_from_ds(ds, &os); + if (error != 0) + return (error); + + error = getzfsvfs_impl(os, &zfvp); + if (error != 0) + return (error); + + vfsp = zfvp->z_vfs; + + switch (zfs_prop) { + case ZFS_PROP_ATIME: + if (vfs_optionisset(vfsp, MNTOPT_NOATIME, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_ATIME, NULL)) + tmp = 1; + break; + case ZFS_PROP_DEVICES: + if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_DEVICES, NULL)) + tmp = 1; + break; + case ZFS_PROP_EXEC: + if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_EXEC, NULL)) + tmp = 1; + break; + case ZFS_PROP_SETUID: + if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_SETUID, NULL)) + tmp = 1; + break; + case ZFS_PROP_READONLY: + if (vfs_optionisset(vfsp, MNTOPT_RW, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_RO, NULL)) + tmp = 1; + break; + case ZFS_PROP_XATTR: + if (vfs_optionisset(vfsp, MNTOPT_NOXATTR, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL)) + tmp = 1; + break; + case ZFS_PROP_NBMAND: + if (vfs_optionisset(vfsp, MNTOPT_NONBMAND, NULL)) + tmp = 0; + if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) + tmp = 1; + break; + default: +#ifdef illumos + VFS_RELE(vfsp); +#else + vfs_rel(vfsp); +#endif + return (ENOENT); + } + +#ifdef illumos + VFS_RELE(vfsp); +#else + vfs_rel(vfsp); +#endif + if (tmp != *val) { + (void) strcpy(setpoint, "temporary"); + *val = tmp; + } + return (0); +#endif +} + +/* + * Check if the property we're looking for is stored at the dsl_dataset or + * dsl_dir level. If so, push the property value and source onto the lua stack + * and return 0. If it is not present or a failure occurs in lookup, return a + * non-zero error value. + */ +static int +get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname, + zfs_prop_t zfs_prop) +{ + int error = 0; + objset_t *os; + uint64_t numval; + char *strval = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP); + char setpoint[ZFS_MAX_DATASET_NAME_LEN] = + "Internal error - setpoint not determined"; + zfs_type_t ds_type; + zprop_type_t prop_type = zfs_prop_get_type(zfs_prop); + (void) get_objset_type(ds, &ds_type); + + switch (zfs_prop) { + case ZFS_PROP_REFRATIO: + numval = dsl_get_refratio(ds); + break; + case ZFS_PROP_USED: + numval = dsl_get_used(ds); + break; + case ZFS_PROP_CLONES: { + nvlist_t *clones = fnvlist_alloc(); + error = get_clones_stat_impl(ds, clones); + if (error == 0) { + /* push list to lua stack */ + VERIFY0(zcp_nvlist_to_lua(state, clones, NULL, 0)); + /* source */ + (void) lua_pushnil(state); + } + nvlist_free(clones); + kmem_free(strval, ZAP_MAXVALUELEN); + return (error); + } + case ZFS_PROP_COMPRESSRATIO: + numval = dsl_get_compressratio(ds); + break; + case ZFS_PROP_CREATION: + numval = dsl_get_creation(ds); + break; + case ZFS_PROP_REFERENCED: + numval = dsl_get_referenced(ds); + break; + case ZFS_PROP_AVAILABLE: + numval = dsl_get_available(ds); + break; + case ZFS_PROP_LOGICALREFERENCED: + numval = dsl_get_logicalreferenced(ds); + break; + case ZFS_PROP_CREATETXG: + numval = dsl_get_creationtxg(ds); + break; + case ZFS_PROP_GUID: + numval = dsl_get_guid(ds); + break; + case ZFS_PROP_UNIQUE: + numval = dsl_get_unique(ds); + break; + case ZFS_PROP_OBJSETID: + numval = dsl_get_objsetid(ds); + break; + case ZFS_PROP_ORIGIN: + dsl_dir_get_origin(ds->ds_dir, strval); + break; + case ZFS_PROP_USERACCOUNTING: + error = dmu_objset_from_ds(ds, &os); + if (error == 0) + numval = dmu_objset_userspace_present(os); + break; + case ZFS_PROP_WRITTEN: + error = dsl_get_written(ds, &numval); + break; + case ZFS_PROP_TYPE: + error = get_objset_type_name(ds, strval); + break; + case ZFS_PROP_PREV_SNAP: + error = dsl_get_prev_snap(ds, strval); + break; + case ZFS_PROP_NAME: + dsl_dataset_name(ds, strval); + break; + case ZFS_PROP_MOUNTPOINT: + error = dsl_get_mountpoint(ds, dsname, strval, setpoint); + break; + case ZFS_PROP_VERSION: + /* should be a snapshot or filesystem */ + ASSERT(ds_type != ZFS_TYPE_VOLUME); + error = dmu_objset_from_ds(ds, &os); + /* look in the master node for the version */ + if (error == 0) { + error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, + sizeof (numval), 1, &numval); + } + break; + case ZFS_PROP_DEFER_DESTROY: + numval = dsl_get_defer_destroy(ds); + break; + case ZFS_PROP_USERREFS: + numval = dsl_get_userrefs(ds); + break; + case ZFS_PROP_FILESYSTEM_COUNT: + error = dsl_dir_get_filesystem_count(ds->ds_dir, &numval); + (void) strcpy(setpoint, ""); + break; + case ZFS_PROP_SNAPSHOT_COUNT: + error = dsl_dir_get_snapshot_count(ds->ds_dir, &numval); + (void) strcpy(setpoint, ""); + break; + case ZFS_PROP_NUMCLONES: + numval = dsl_get_numclones(ds); + break; + case ZFS_PROP_INCONSISTENT: + numval = dsl_get_inconsistent(ds); + break; + case ZFS_PROP_RECEIVE_RESUME_TOKEN: + VERIFY3U(strlcpy(strval, get_receive_resume_stats_impl(ds), + ZAP_MAXVALUELEN), <, ZAP_MAXVALUELEN); + if (strcmp(strval, "") == 0) { + VERIFY3U(strlcpy(strval, get_child_receive_stats(ds), + ZAP_MAXVALUELEN), <, ZAP_MAXVALUELEN); + if (strcmp(strval, "") == 0) + error = ENOENT; + } + break; + case ZFS_PROP_VOLSIZE: + ASSERT(ds_type == ZFS_TYPE_VOLUME); + error = dmu_objset_from_ds(ds, &os); + if (error == 0) { + error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", + sizeof (numval), 1, &numval); + } + if (error == 0) + (void) strcpy(setpoint, dsname); + + break; + case ZFS_PROP_VOLBLOCKSIZE: { + ASSERT(ds_type == ZFS_TYPE_VOLUME); + dmu_object_info_t doi; + error = dmu_objset_from_ds(ds, &os); + if (error == 0) { + error = dmu_object_info(os, ZVOL_OBJ, &doi); + if (error == 0) + numval = doi.doi_data_block_size; + } + break; + } + default: + /* Did not match these props, check in the dsl_dir */ + error = get_dsl_dir_prop(ds, zfs_prop, &numval); + } + if (error != 0) { + kmem_free(strval, ZAP_MAXVALUELEN); + return (error); + } + + switch (prop_type) { + case PROP_TYPE_NUMBER: { + (void) lua_pushnumber(state, numval); + break; + } + case PROP_TYPE_STRING: { + (void) lua_pushstring(state, strval); + break; + } + case PROP_TYPE_INDEX: { + const char *propval; + error = zfs_prop_index_to_string(zfs_prop, numval, &propval); + if (error != 0) { + kmem_free(strval, ZAP_MAXVALUELEN); + return (error); + } + (void) lua_pushstring(state, propval); + break; + } + } + kmem_free(strval, ZAP_MAXVALUELEN); + + /* Push the source to the stack */ + get_prop_src(state, setpoint, zfs_prop); + return (0); +} + +/* + * Look up a property and its source in the zap object. If the value is + * present and successfully retrieved, push the value and source on the + * lua stack and return 0. On failure, return a non-zero error value. + */ +static int +get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop) +{ + int error = 0; + char setpoint[ZFS_MAX_DATASET_NAME_LEN]; + char *strval = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP); + uint64_t numval; + const char *prop_name = zfs_prop_to_name(zfs_prop); + zprop_type_t prop_type = zfs_prop_get_type(zfs_prop); + + if (prop_type == PROP_TYPE_STRING) { + /* Push value to lua stack */ + error = dsl_prop_get_ds(ds, prop_name, 1, + ZAP_MAXVALUELEN, strval, setpoint); + if (error == 0) + (void) lua_pushstring(state, strval); + } else { + error = dsl_prop_get_ds(ds, prop_name, sizeof (numval), + 1, &numval, setpoint); + + /* Fill in temorary value for prop, if applicable */ + (void) get_temporary_prop(ds, zfs_prop, &numval, setpoint); + + /* Push value to lua stack */ + if (prop_type == PROP_TYPE_INDEX) { + const char *propval; + error = zfs_prop_index_to_string(zfs_prop, numval, + &propval); + if (error == 0) + (void) lua_pushstring(state, propval); + } else { + if (error == 0) + (void) lua_pushnumber(state, numval); + } + } + kmem_free(strval, ZAP_MAXVALUELEN); + if (error == 0) + get_prop_src(state, setpoint, zfs_prop); + return (error); +} + +/* + * Determine whether property is valid for a given dataset + */ +boolean_t +prop_valid_for_ds(dsl_dataset_t *ds, zfs_prop_t zfs_prop) +{ + int error; + zfs_type_t zfs_type; + + /* properties not supported */ + if ((zfs_prop == ZFS_PROP_ISCSIOPTIONS) || + (zfs_prop == ZFS_PROP_MOUNTED)) + return (B_FALSE); + + /* if we want the origin prop, ds must be a clone */ + if ((zfs_prop == ZFS_PROP_ORIGIN) && (!dsl_dir_is_clone(ds->ds_dir))) + return (B_FALSE); + + error = get_objset_type(ds, &zfs_type); + if (error != 0) + return (B_FALSE); + return (zfs_prop_valid_for_type(zfs_prop, zfs_type)); +} + +/* + * Look up a given dataset property. On success return 2, the number of + * values pushed to the lua stack (property value and source). On a fatal + * error, longjmp. On a non fatal error push nothing. + */ +static int +zcp_get_system_prop(lua_State *state, dsl_pool_t *dp, const char *dataset_name, + zfs_prop_t zfs_prop) +{ + int error; + /* + * zcp_dataset_hold will either successfully return the requested + * dataset or throw a lua error and longjmp out of the zfs.get_prop call + * without returning. + */ + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dataset_name, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + /* Check that the property is valid for the given dataset */ + const char *prop_name = zfs_prop_to_name(zfs_prop); + if (!prop_valid_for_ds(ds, zfs_prop)) { + dsl_dataset_rele(ds, FTAG); + return (0); + } + + /* Check if the property can be accessed directly */ + error = get_special_prop(state, ds, dataset_name, zfs_prop); + if (error == 0) { + dsl_dataset_rele(ds, FTAG); + /* The value and source have been pushed by get_special_prop */ + return (2); + } + if (error != ENOENT) { + dsl_dataset_rele(ds, FTAG); + return (zcp_handle_error(state, dataset_name, + prop_name, error)); + } + + /* If we were unable to find it, look in the zap object */ + error = get_zap_prop(state, ds, zfs_prop); + dsl_dataset_rele(ds, FTAG); + if (error != 0) { + return (zcp_handle_error(state, dataset_name, + prop_name, error)); + } + /* The value and source have been pushed by get_zap_prop */ + return (2); +} + +static zfs_userquota_prop_t +get_userquota_prop(const char *prop_name) +{ + zfs_userquota_prop_t type; + /* Figure out the property type ({user|group}{quota|used}) */ + for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) { + if (strncmp(prop_name, zfs_userquota_prop_prefixes[type], + strlen(zfs_userquota_prop_prefixes[type])) == 0) + break; + } + return (type); +} + +#ifdef _KERNEL +/* + * Given the name of a zfs_userquota_prop, this function determines the + * prop type as well as the numeric group/user ids based on the string + * following the '@' in the property name. On success, returns 0. On failure, + * returns a non-zero error. + * 'domain' must be free'd by caller using strfree() + */ +static int +parse_userquota_prop(const char *prop_name, zfs_userquota_prop_t *type, + char **domain, uint64_t *rid) +{ + char *cp, *end, *domain_val; + + *type = get_userquota_prop(prop_name); + if (*type >= ZFS_NUM_USERQUOTA_PROPS) + return (EINVAL); + + *rid = 0; + cp = strchr(prop_name, '@') + 1; + if (strncmp(cp, "S-1-", 4) == 0) { + /* + * It's a numeric SID (eg "S-1-234-567-89") and we want to + * seperate the domain id and the rid + */ + int domain_len = strrchr(cp, '-') - cp; + domain_val = kmem_alloc(domain_len + 1, KM_SLEEP); + (void) strncpy(domain_val, cp, domain_len); + domain_val[domain_len] = '\0'; + cp += domain_len + 1; + + (void) ddi_strtoll(cp, &end, 10, (longlong_t *)rid); + if (*end != '\0') { + strfree(domain_val); + return (EINVAL); + } + } else { + /* It's only a user/group ID (eg "12345"), just get the rid */ + domain_val = NULL; + (void) ddi_strtoll(cp, &end, 10, (longlong_t *)rid); + if (*end != '\0') + return (EINVAL); + } + *domain = domain_val; + return (0); +} + +/* + * Look up {user|group}{quota|used} property for given dataset. On success + * push the value (quota or used amount) and the setpoint. On failure, push + * a lua error. + */ +static int +zcp_get_userquota_prop(lua_State *state, dsl_pool_t *dp, + const char *dataset_name, const char *prop_name) +{ + zfsvfs_t *zfvp; + zfsvfs_t *zfsvfs; + int error; + zfs_userquota_prop_t type; + char *domain; + uint64_t rid, value; + objset_t *os; + + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dataset_name, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + error = parse_userquota_prop(prop_name, &type, &domain, &rid); + if (error == 0) { + error = dmu_objset_from_ds(ds, &os); + if (error == 0) { + zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); + error = zfsvfs_create_impl(&zfvp, zfsvfs, os); + if (error == 0) { + error = zfs_userspace_one(zfvp, type, domain, + rid, &value); + zfsvfs_free(zfvp); + } + } + if (domain != NULL) + strfree(domain); + } + dsl_dataset_rele(ds, FTAG); + + if ((value == 0) && ((type == ZFS_PROP_USERQUOTA) || + (type == ZFS_PROP_GROUPQUOTA))) + error = ENOENT; + if (error != 0) { + return (zcp_handle_error(state, dataset_name, + prop_name, error)); + } + + (void) lua_pushnumber(state, value); + (void) lua_pushstring(state, dataset_name); + return (2); +} +#endif + +/* + * Determines the name of the snapshot referenced in the written property + * name. Returns snapshot name in snap_name, a buffer that must be at least + * as large as ZFS_MAX_DATASET_NAME_LEN + */ +static void +parse_written_prop(const char *dataset_name, const char *prop_name, + char *snap_name) +{ + ASSERT(zfs_prop_written(prop_name)); + const char *name = prop_name + ZFS_WRITTEN_PROP_PREFIX_LEN; + if (strchr(name, '@') == NULL) { + (void) sprintf(snap_name, "%s@%s", dataset_name, name); + } else { + (void) strcpy(snap_name, name); + } +} + +/* + * Look up written@ property for given dataset. On success + * push the value and the setpoint. If error is fatal, we will + * longjmp, otherwise push nothing. + */ +static int +zcp_get_written_prop(lua_State *state, dsl_pool_t *dp, + const char *dataset_name, const char *prop_name) +{ + char snap_name[ZFS_MAX_DATASET_NAME_LEN]; + uint64_t used, comp, uncomp; + dsl_dataset_t *old; + int error = 0; + + parse_written_prop(dataset_name, prop_name, snap_name); + dsl_dataset_t *new = zcp_dataset_hold(state, dp, dataset_name, FTAG); + if (new == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + error = dsl_dataset_hold(dp, snap_name, FTAG, &old); + if (error != 0) { + dsl_dataset_rele(new, FTAG); + return (zcp_dataset_hold_error(state, dp, snap_name, + error)); + } + error = dsl_dataset_space_written(old, new, + &used, &comp, &uncomp); + + dsl_dataset_rele(old, FTAG); + dsl_dataset_rele(new, FTAG); + + if (error != 0) { + return (zcp_handle_error(state, dataset_name, + snap_name, error)); + } + (void) lua_pushnumber(state, used); + (void) lua_pushstring(state, dataset_name); + return (2); +} + +static int zcp_get_prop(lua_State *state); +static zcp_lib_info_t zcp_get_prop_info = { + .name = "get_prop", + .func = zcp_get_prop, + .pargs = { + { .za_name = "dataset", .za_lua_type = LUA_TSTRING}, + { .za_name = "property", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_get_prop(lua_State *state) +{ + const char *dataset_name; + const char *property_name; + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + zcp_lib_info_t *libinfo = &zcp_get_prop_info; + + zcp_parse_args(state, libinfo->name, libinfo->pargs, libinfo->kwargs); + + dataset_name = lua_tostring(state, 1); + property_name = lua_tostring(state, 2); + + /* User defined property */ + if (zfs_prop_user(property_name)) { + return (zcp_get_user_prop(state, dp, + dataset_name, property_name)); + } + /* userspace property */ + if (zfs_prop_userquota(property_name)) { +#ifdef _KERNEL + return (zcp_get_userquota_prop(state, dp, + dataset_name, property_name)); +#else + return (luaL_error(state, + "user quota properties only supported in kernel mode", + property_name)); +#endif + } + /* written@ property */ + if (zfs_prop_written(property_name)) { + return (zcp_get_written_prop(state, dp, + dataset_name, property_name)); + } + + zfs_prop_t zfs_prop = zfs_name_to_prop(property_name); + /* Valid system property */ + if (zfs_prop != ZPROP_INVAL) { + return (zcp_get_system_prop(state, dp, dataset_name, + zfs_prop)); + } + + /* Invalid property name */ + return (luaL_error(state, + "'%s' is not a valid property", property_name)); +} + +int +zcp_load_get_lib(lua_State *state) +{ + lua_pushcclosure(state, zcp_get_prop_info.func, 0); + lua_setfield(state, -2, zcp_get_prop_info.name); + + return (1); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c new file mode 100644 index 000000000000..c25431fd6703 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c @@ -0,0 +1,89 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016, 2017 by Delphix. All rights reserved. + */ + +#include + +#include "lua.h" +#include "lauxlib.h" + +typedef struct zcp_errno_global { + const char *zeg_name; + int zeg_errno; +} zcp_errno_global_t; + +static const zcp_errno_global_t errno_globals[] = { + {"EPERM", EPERM}, + {"ENOENT", ENOENT}, + {"ESRCH", ESRCH}, + {"EINTR", EINTR}, + {"EIO", EIO}, + {"ENXIO", ENXIO}, + {"E2BIG", E2BIG}, + {"ENOEXEC", ENOEXEC}, + {"EBADF", EBADF}, + {"ECHILD", ECHILD}, + {"EAGAIN", EAGAIN}, + {"ENOMEM", ENOMEM}, + {"EACCES", EACCES}, + {"EFAULT", EFAULT}, + {"ENOTBLK", ENOTBLK}, + {"EBUSY", EBUSY}, + {"EEXIST", EEXIST}, + {"EXDEV", EXDEV}, + {"ENODEV", ENODEV}, + {"ENOTDIR", ENOTDIR}, + {"EISDIR", EISDIR}, + {"EINVAL", EINVAL}, + {"ENFILE", ENFILE}, + {"EMFILE", EMFILE}, + {"ENOTTY", ENOTTY}, + {"ETXTBSY", ETXTBSY}, + {"EFBIG", EFBIG}, + {"ENOSPC", ENOSPC}, + {"ESPIPE", ESPIPE}, + {"EROFS", EROFS}, + {"EMLINK", EMLINK}, + {"EPIPE", EPIPE}, + {"EDOM", EDOM}, + {"ERANGE", ERANGE}, + {"EDEADLK", EDEADLK}, + {"ENOLCK", ENOLCK}, + {"ECANCELED", ECANCELED}, + {"ENOTSUP", ENOTSUP}, + {"EDQUOT", EDQUOT}, + {"ENAMETOOLONG", ENAMETOOLONG}, + {NULL, 0} +}; + +static void +zcp_load_errno_globals(lua_State *state) +{ + const zcp_errno_global_t *global = errno_globals; + while (global->zeg_name != NULL) { + lua_pushnumber(state, (lua_Number)global->zeg_errno); + lua_setglobal(state, global->zeg_name); + global++; + } +} + +void +zcp_load_globals(lua_State *state) +{ + zcp_load_errno_globals(state); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_iter.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_iter.c new file mode 100644 index 000000000000..0236c6474ef6 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_iter.c @@ -0,0 +1,531 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016 by Delphix. All rights reserved. + */ + +#include "lua.h" +#include "lauxlib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef int (zcp_list_func_t)(lua_State *); +typedef struct zcp_list_info { + const char *name; + zcp_list_func_t *func; + zcp_list_func_t *gc; + const zcp_arg_t pargs[4]; + const zcp_arg_t kwargs[2]; +} zcp_list_info_t; + +static int +zcp_clones_iter(lua_State *state) +{ + int err; + char clonename[ZFS_MAX_DATASET_NAME_LEN]; + uint64_t dsobj = lua_tonumber(state, lua_upvalueindex(1)); + uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2)); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + dsl_dataset_t *ds, *clone; + zap_attribute_t za; + zap_cursor_t zc; + + err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds); + if (err == ENOENT) { + return (0); + } else if (err != 0) { + return (luaL_error(state, + "unexpected error %d from dsl_dataset_hold_obj(dsobj)", + err)); + } + + if (dsl_dataset_phys(ds)->ds_next_clones_obj == 0) { + dsl_dataset_rele(ds, FTAG); + return (0); + } + + zap_cursor_init_serialized(&zc, dp->dp_meta_objset, + dsl_dataset_phys(ds)->ds_next_clones_obj, cursor); + dsl_dataset_rele(ds, FTAG); + + err = zap_cursor_retrieve(&zc, &za); + if (err != 0) { + zap_cursor_fini(&zc); + if (err != ENOENT) { + return (luaL_error(state, + "unexpected error %d from zap_cursor_retrieve()", + err)); + } + return (0); + } + zap_cursor_advance(&zc); + cursor = zap_cursor_serialize(&zc); + zap_cursor_fini(&zc); + + err = dsl_dataset_hold_obj(dp, za.za_first_integer, FTAG, &clone); + if (err != 0) { + return (luaL_error(state, + "unexpected error %d from " + "dsl_dataset_hold_obj(za_first_integer)", err)); + } + + dsl_dir_name(clone->ds_dir, clonename); + dsl_dataset_rele(clone, FTAG); + + lua_pushnumber(state, cursor); + lua_replace(state, lua_upvalueindex(2)); + + (void) lua_pushstring(state, clonename); + return (1); +} + +static int zcp_clones_list(lua_State *); +static zcp_list_info_t zcp_clones_list_info = { + .name = "clones", + .func = zcp_clones_list, + .gc = NULL, + .pargs = { + { .za_name = "snapshot", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_clones_list(lua_State *state) +{ + const char *snapname = lua_tostring(state, 1); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + boolean_t issnap; + uint64_t dsobj, cursor; + + /* + * zcp_dataset_hold will either successfully return the requested + * dataset or throw a lua error and longjmp out of the zfs.list.clones + * call without returning. + */ + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, snapname, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + cursor = 0; + issnap = ds->ds_is_snapshot; + dsobj = ds->ds_object; + dsl_dataset_rele(ds, FTAG); + + if (!issnap) { + return (zcp_argerror(state, 1, "%s is not a snapshot", + snapname)); + } + + lua_pushnumber(state, dsobj); + lua_pushnumber(state, cursor); + lua_pushcclosure(state, &zcp_clones_iter, 2); + return (1); +} + +static int +zcp_snapshots_iter(lua_State *state) +{ + int err; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; + uint64_t dsobj = lua_tonumber(state, lua_upvalueindex(1)); + uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2)); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + dsl_dataset_t *ds; + objset_t *os; + char *p; + + err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds); + if (err != 0) { + return (luaL_error(state, + "unexpected error %d from dsl_dataset_hold_obj(dsobj)", + err)); + } + + dsl_dataset_name(ds, snapname); + VERIFY3U(sizeof (snapname), >, + strlcat(snapname, "@", sizeof (snapname))); + + p = strchr(snapname, '\0'); + VERIFY0(dmu_objset_from_ds(ds, &os)); + err = dmu_snapshot_list_next(os, + sizeof (snapname) - (p - snapname), p, NULL, &cursor, NULL); + dsl_dataset_rele(ds, FTAG); + + if (err == ENOENT) { + return (0); + } else if (err != 0) { + return (luaL_error(state, + "unexpected error %d from dmu_snapshot_list_next()", err)); + } + + lua_pushnumber(state, cursor); + lua_replace(state, lua_upvalueindex(2)); + + (void) lua_pushstring(state, snapname); + return (1); +} + +static int zcp_snapshots_list(lua_State *); +static zcp_list_info_t zcp_snapshots_list_info = { + .name = "snapshots", + .func = zcp_snapshots_list, + .gc = NULL, + .pargs = { + { .za_name = "filesystem | volume", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_snapshots_list(lua_State *state) +{ + const char *fsname = lua_tostring(state, 1); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + boolean_t issnap; + uint64_t dsobj; + + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, fsname, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + issnap = ds->ds_is_snapshot; + dsobj = ds->ds_object; + dsl_dataset_rele(ds, FTAG); + + if (issnap) { + return (zcp_argerror(state, 1, + "argument %s cannot be a snapshot", fsname)); + } + + lua_pushnumber(state, dsobj); + lua_pushnumber(state, 0); + lua_pushcclosure(state, &zcp_snapshots_iter, 2); + return (1); +} + +/* + * Note: channel programs only run in the global zone, so all datasets + * are visible to this zone. + */ +static boolean_t +dataset_name_hidden(const char *name) +{ + if (strchr(name, '$') != NULL) + return (B_TRUE); + if (strchr(name, '%') != NULL) + return (B_TRUE); + return (B_FALSE); +} + +static int +zcp_children_iter(lua_State *state) +{ + int err; + char childname[ZFS_MAX_DATASET_NAME_LEN]; + uint64_t dsobj = lua_tonumber(state, lua_upvalueindex(1)); + uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2)); + zcp_run_info_t *ri = zcp_run_info(state); + dsl_pool_t *dp = ri->zri_pool; + dsl_dataset_t *ds; + objset_t *os; + char *p; + + err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds); + if (err != 0) { + return (luaL_error(state, + "unexpected error %d from dsl_dataset_hold_obj(dsobj)", + err)); + } + + dsl_dataset_name(ds, childname); + VERIFY3U(sizeof (childname), >, + strlcat(childname, "/", sizeof (childname))); + p = strchr(childname, '\0'); + + VERIFY0(dmu_objset_from_ds(ds, &os)); + do { + err = dmu_dir_list_next(os, + sizeof (childname) - (p - childname), p, NULL, &cursor); + } while (err == 0 && dataset_name_hidden(childname)); + dsl_dataset_rele(ds, FTAG); + + if (err == ENOENT) { + return (0); + } else if (err != 0) { + return (luaL_error(state, + "unexpected error %d from dmu_dir_list_next()", + err)); + } + + lua_pushnumber(state, cursor); + lua_replace(state, lua_upvalueindex(2)); + + (void) lua_pushstring(state, childname); + return (1); +} + +static int zcp_children_list(lua_State *); +static zcp_list_info_t zcp_children_list_info = { + .name = "children", + .func = zcp_children_list, + .gc = NULL, + .pargs = { + { .za_name = "filesystem | volume", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_children_list(lua_State *state) +{ + const char *fsname = lua_tostring(state, 1); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + boolean_t issnap; + uint64_t dsobj; + + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, fsname, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + issnap = ds->ds_is_snapshot; + dsobj = ds->ds_object; + dsl_dataset_rele(ds, FTAG); + + if (issnap) { + return (zcp_argerror(state, 1, + "argument %s cannot be a snapshot", fsname)); + } + + lua_pushnumber(state, dsobj); + lua_pushnumber(state, 0); + lua_pushcclosure(state, &zcp_children_iter, 2); + return (1); +} + +static int +zcp_props_list_gc(lua_State *state) +{ + nvlist_t **props = lua_touserdata(state, 1); + if (*props != NULL) + fnvlist_free(*props); + return (0); +} + +static int +zcp_props_iter(lua_State *state) +{ + char *source, *val; + nvlist_t *nvprop; + nvlist_t **props = lua_touserdata(state, lua_upvalueindex(1)); + nvpair_t *pair = lua_touserdata(state, lua_upvalueindex(2)); + + do { + pair = nvlist_next_nvpair(*props, pair); + if (pair == NULL) { + fnvlist_free(*props); + *props = NULL; + return (0); + } + } while (!zfs_prop_user(nvpair_name(pair))); + + lua_pushlightuserdata(state, pair); + lua_replace(state, lua_upvalueindex(2)); + + nvprop = fnvpair_value_nvlist(pair); + val = fnvlist_lookup_string(nvprop, ZPROP_VALUE); + source = fnvlist_lookup_string(nvprop, ZPROP_SOURCE); + + (void) lua_pushstring(state, nvpair_name(pair)); + (void) lua_pushstring(state, val); + (void) lua_pushstring(state, source); + return (3); +} + +static int zcp_props_list(lua_State *); +static zcp_list_info_t zcp_props_list_info = { + .name = "properties", + .func = zcp_props_list, + .gc = zcp_props_list_gc, + .pargs = { + { .za_name = "filesystem | snapshot | volume", + .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_props_list(lua_State *state) +{ + const char *dsname = lua_tostring(state, 1); + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + objset_t *os; + nvlist_t **props = lua_newuserdata(state, sizeof (nvlist_t *)); + + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dsname, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + VERIFY0(dmu_objset_from_ds(ds, &os)); + VERIFY0(dsl_prop_get_all(os, props)); + dsl_dataset_rele(ds, FTAG); + + /* + * Set the metatable for the properties list to free it on completion. + */ + luaL_getmetatable(state, zcp_props_list_info.name); + (void) lua_setmetatable(state, -2); + + lua_pushlightuserdata(state, NULL); + lua_pushcclosure(state, &zcp_props_iter, 2); + return (1); +} + + +/* + * Populate nv with all valid properties and their values for the given + * dataset. + */ +static void +zcp_dataset_props(dsl_dataset_t *ds, nvlist_t *nv) +{ + for (int prop = ZFS_PROP_TYPE; prop < ZFS_NUM_PROPS; prop++) { + /* Do not display hidden props */ + if (!zfs_prop_visible(prop)) + continue; + /* Do not display props not valid for this dataset */ + if (!prop_valid_for_ds(ds, prop)) + continue; + fnvlist_add_boolean(nv, zfs_prop_to_name(prop)); + } +} + +static int zcp_system_props_list(lua_State *); +static zcp_list_info_t zcp_system_props_list_info = { + .name = "system_properties", + .func = zcp_system_props_list, + .pargs = { + { .za_name = "dataset", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +/* + * Get a list of all visble properties and their values for a given dataset. + * Returned on the stack as a Lua table. + */ +static int +zcp_system_props_list(lua_State *state) +{ + int error; + char errbuf[128]; + const char *dataset_name; + dsl_pool_t *dp = zcp_run_info(state)->zri_pool; + zcp_list_info_t *libinfo = &zcp_system_props_list_info; + zcp_parse_args(state, libinfo->name, libinfo->pargs, libinfo->kwargs); + dataset_name = lua_tostring(state, 1); + nvlist_t *nv = fnvlist_alloc(); + + dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dataset_name, FTAG); + if (ds == NULL) + return (1); /* not reached; zcp_dataset_hold() longjmp'd */ + + /* Get the names of all valid properties for this dataset */ + zcp_dataset_props(ds, nv); + dsl_dataset_rele(ds, FTAG); + + /* push list as lua table */ + error = zcp_nvlist_to_lua(state, nv, errbuf, sizeof (errbuf)); + nvlist_free(nv); + if (error != 0) { + return (luaL_error(state, + "Error returning nvlist: %s", errbuf)); + } + return (1); +} + +static int +zcp_list_func(lua_State *state) +{ + zcp_list_info_t *info = lua_touserdata(state, lua_upvalueindex(1)); + + zcp_parse_args(state, info->name, info->pargs, info->kwargs); + + return (info->func(state)); +} + +int +zcp_load_list_lib(lua_State *state) +{ + int i; + zcp_list_info_t *zcp_list_funcs[] = { + &zcp_children_list_info, + &zcp_snapshots_list_info, + &zcp_props_list_info, + &zcp_clones_list_info, + &zcp_system_props_list_info, + NULL + }; + + lua_newtable(state); + + for (i = 0; zcp_list_funcs[i] != NULL; i++) { + zcp_list_info_t *info = zcp_list_funcs[i]; + + if (info->gc != NULL) { + /* + * If the function requires garbage collection, create + * a metatable with its name and register the __gc + * function. + */ + (void) luaL_newmetatable(state, info->name); + (void) lua_pushstring(state, "__gc"); + lua_pushcfunction(state, info->gc); + lua_settable(state, -3); + lua_pop(state, 1); + } + + lua_pushlightuserdata(state, info); + lua_pushcclosure(state, &zcp_list_func, 1); + lua_setfield(state, -2, info->name); + info++; + } + + return (1); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c new file mode 100644 index 000000000000..f63773b96748 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c @@ -0,0 +1,350 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2016, 2017 by Delphix. All rights reserved. + */ + +#include "lua.h" +#include "lauxlib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DST_AVG_BLKSHIFT 14 + +typedef int (zcp_synctask_func_t)(lua_State *, boolean_t, nvlist_t *); +typedef struct zcp_synctask_info { + const char *name; + zcp_synctask_func_t *func; + const zcp_arg_t pargs[4]; + const zcp_arg_t kwargs[2]; + zfs_space_check_t space_check; + int blocks_modified; +} zcp_synctask_info_t; + +/* + * Generic synctask interface for channel program syncfuncs. + * + * To perform some action in syncing context, we'd generally call + * dsl_sync_task(), but since the Lua script is already running inside a + * synctask we need to leave out some actions (such as acquiring the config + * rwlock and performing space checks). + * + * If 'sync' is false, executes a dry run and returns the error code. + * + * This function also handles common fatal error cases for channel program + * library functions. If a fatal error occurs, err_dsname will be the dataset + * name reported in error messages, if supplied. + */ +static int +zcp_sync_task(lua_State *state, dsl_checkfunc_t *checkfunc, + dsl_syncfunc_t *syncfunc, void *arg, boolean_t sync, const char *err_dsname) +{ + int err; + zcp_run_info_t *ri = zcp_run_info(state); + + err = checkfunc(arg, ri->zri_tx); + if (!sync) + return (err); + + if (err == 0) { + syncfunc(arg, ri->zri_tx); + } else if (err == EIO) { + if (err_dsname != NULL) { + return (luaL_error(state, + "I/O error while accessing dataset '%s'", + err_dsname)); + } else { + return (luaL_error(state, + "I/O error while accessing dataset.")); + } + } + + return (err); +} + + +static int zcp_synctask_destroy(lua_State *, boolean_t, nvlist_t *); +static zcp_synctask_info_t zcp_synctask_destroy_info = { + .name = "destroy", + .func = zcp_synctask_destroy, + .pargs = { + {.za_name = "filesystem | snapshot", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {.za_name = "defer", .za_lua_type = LUA_TBOOLEAN}, + {NULL, 0} + }, + .space_check = ZFS_SPACE_CHECK_NONE, + .blocks_modified = 0 +}; + +/* ARGSUSED */ +static int +zcp_synctask_destroy(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + const char *dsname = lua_tostring(state, 1); + + boolean_t issnap = (strchr(dsname, '@') != NULL); + + if (!issnap && !lua_isnil(state, 2)) { + return (luaL_error(state, + "'deferred' kwarg only supported for snapshots: %s", + dsname)); + } + + if (issnap) { + dsl_destroy_snapshot_arg_t ddsa = { 0 }; + ddsa.ddsa_name = dsname; + if (!lua_isnil(state, 2)) { + ddsa.ddsa_defer = lua_toboolean(state, 2); + } else { + ddsa.ddsa_defer = B_FALSE; + } + + err = zcp_sync_task(state, dsl_destroy_snapshot_check, + dsl_destroy_snapshot_sync, &ddsa, sync, dsname); + } else { + dsl_destroy_head_arg_t ddha = { 0 }; + ddha.ddha_name = dsname; + + err = zcp_sync_task(state, dsl_destroy_head_check, + dsl_destroy_head_sync, &ddha, sync, dsname); + } + + return (err); +} + +static int zcp_synctask_promote(lua_State *, boolean_t, nvlist_t *); +static zcp_synctask_info_t zcp_synctask_promote_info = { + .name = "promote", + .func = zcp_synctask_promote, + .pargs = { + {.za_name = "clone", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + }, + .space_check = ZFS_SPACE_CHECK_RESERVED, + .blocks_modified = 3 +}; + +static int +zcp_synctask_promote(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + dsl_dataset_promote_arg_t ddpa = { 0 }; + const char *dsname = lua_tostring(state, 1); + zcp_run_info_t *ri = zcp_run_info(state); + + ddpa.ddpa_clonename = dsname; + ddpa.err_ds = err_details; + ddpa.cr = ri->zri_cred; + + /* + * If there was a snapshot name conflict, then err_ds will be filled + * with a list of conflicting snapshot names. + */ + err = zcp_sync_task(state, dsl_dataset_promote_check, + dsl_dataset_promote_sync, &ddpa, sync, dsname); + + return (err); +} + +static int zcp_synctask_rollback(lua_State *, boolean_t, nvlist_t *err_details); +static zcp_synctask_info_t zcp_synctask_rollback_info = { + .name = "rollback", + .func = zcp_synctask_rollback, + .space_check = ZFS_SPACE_CHECK_RESERVED, + .blocks_modified = 1, + .pargs = { + {.za_name = "filesystem", .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + } +}; + +static int +zcp_synctask_rollback(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + const char *dsname = lua_tostring(state, 1); + dsl_dataset_rollback_arg_t ddra = { 0 }; + + ddra.ddra_fsname = dsname; + ddra.ddra_result = err_details; + + err = zcp_sync_task(state, dsl_dataset_rollback_check, + dsl_dataset_rollback_sync, &ddra, sync, dsname); + + return (err); +} + +static int zcp_synctask_snapshot(lua_State *, boolean_t, nvlist_t *); +static zcp_synctask_info_t zcp_synctask_snapshot_info = { + .name = "snapshot", + .func = zcp_synctask_snapshot, + .pargs = { + {.za_name = "filesystem@snapname | volume@snapname", + .za_lua_type = LUA_TSTRING}, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + }, + .space_check = ZFS_SPACE_CHECK_NORMAL, + .blocks_modified = 3 +}; + +/* ARGSUSED */ +static int +zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + int err; + dsl_dataset_snapshot_arg_t ddsa = { 0 }; + const char *dsname = lua_tostring(state, 1); + zcp_run_info_t *ri = zcp_run_info(state); + + /* + * We only allow for a single snapshot rather than a list, so the + * error list output is unnecessary. + */ + ddsa.ddsa_errors = NULL; + ddsa.ddsa_props = NULL; + ddsa.ddsa_cr = ri->zri_cred; + ddsa.ddsa_snaps = fnvlist_alloc(); + fnvlist_add_boolean(ddsa.ddsa_snaps, dsname); + + /* + * On old pools, the ZIL must not be active when a snapshot is created, + * but we can't suspend the ZIL because we're already in syncing + * context. + */ + if (spa_version(ri->zri_pool->dp_spa) < SPA_VERSION_FAST_SNAP) { + return (ENOTSUP); + } + + err = zcp_sync_task(state, dsl_dataset_snapshot_check, + dsl_dataset_snapshot_sync, &ddsa, sync, dsname); + + fnvlist_free(ddsa.ddsa_snaps); + + return (err); +} + +void +zcp_synctask_wrapper_cleanup(void *arg) +{ + fnvlist_free(arg); +} + +static int +zcp_synctask_wrapper(lua_State *state) +{ + int err; + int num_ret = 1; + nvlist_t *err_details = fnvlist_alloc(); + + /* + * Make sure err_details is properly freed, even if a fatal error is + * thrown during the synctask. + */ + zcp_register_cleanup(state, &zcp_synctask_wrapper_cleanup, err_details); + + zcp_synctask_info_t *info = lua_touserdata(state, lua_upvalueindex(1)); + boolean_t sync = lua_toboolean(state, lua_upvalueindex(2)); + + zcp_run_info_t *ri = zcp_run_info(state); + dsl_pool_t *dp = ri->zri_pool; + + /* MOS space is triple-dittoed, so we multiply by 3. */ + uint64_t funcspace = (info->blocks_modified << DST_AVG_BLKSHIFT) * 3; + + zcp_parse_args(state, info->name, info->pargs, info->kwargs); + + err = 0; + if (info->space_check != ZFS_SPACE_CHECK_NONE && funcspace > 0) { + uint64_t quota = dsl_pool_adjustedsize(dp, + info->space_check == ZFS_SPACE_CHECK_RESERVED) - + metaslab_class_get_deferred(spa_normal_class(dp->dp_spa)); + uint64_t used = dsl_dir_phys(dp->dp_root_dir)->dd_used_bytes + + ri->zri_space_used; + + if (used + funcspace > quota) { + err = SET_ERROR(ENOSPC); + } + } + + if (err == 0) { + err = info->func(state, sync, err_details); + } + + if (err == 0) { + ri->zri_space_used += funcspace; + } + + lua_pushnumber(state, (lua_Number)err); + if (fnvlist_num_pairs(err_details) > 0) { + (void) zcp_nvlist_to_lua(state, err_details, NULL, 0); + num_ret++; + } + + zcp_clear_cleanup(state); + fnvlist_free(err_details); + + return (num_ret); +} + +int +zcp_load_synctask_lib(lua_State *state, boolean_t sync) +{ + int i; + zcp_synctask_info_t *zcp_synctask_funcs[] = { + &zcp_synctask_destroy_info, + &zcp_synctask_promote_info, + &zcp_synctask_rollback_info, + &zcp_synctask_snapshot_info, + NULL + }; + + lua_newtable(state); + + for (i = 0; zcp_synctask_funcs[i] != NULL; i++) { + zcp_synctask_info_t *info = zcp_synctask_funcs[i]; + lua_pushlightuserdata(state, info); + lua_pushboolean(state, sync); + lua_pushcclosure(state, &zcp_synctask_wrapper, 2); + lua_setfield(state, -2, info->name); + info++; + } + + return (1); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index c1dad26df4de..1fb8ea62a543 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -27,7 +27,7 @@ * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2017 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] @@ -192,6 +192,7 @@ #include #include #include +#include #include #include "zfs_namecheck.h" @@ -200,8 +201,10 @@ #include "zfs_comutil.h" #include "zfs_ioctl_compat.h" -CTASSERT(sizeof(zfs_cmd_t) < IOCPARM_MAX); +#include "lua.h" +#include "lauxlib.h" +CTASSERT(sizeof(zfs_cmd_t) < IOCPARM_MAX); static struct cdev *zfsdev; extern void zfs_init(void); @@ -1436,41 +1439,78 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) return (error); } -static int -getzfsvfs(const char *dsname, zfsvfs_t **zfvp) +int +getzfsvfs_impl(objset_t *os, zfsvfs_t **zfvp) { - objset_t *os; vfs_t *vfsp; - int error; + int error = 0; - error = dmu_objset_hold(dsname, FTAG, &os); - if (error != 0) - return (error); if (dmu_objset_type(os) != DMU_OST_ZFS) { - dmu_objset_rele(os, FTAG); return (SET_ERROR(EINVAL)); } mutex_enter(&os->os_user_ptr_lock); *zfvp = dmu_objset_get_user(os); if (*zfvp) { - vfsp = (*zfvp)->z_vfs; - vfs_ref(vfsp); + vfs_ref((*zfvp)->z_vfs); } else { error = SET_ERROR(ESRCH); } mutex_exit(&os->os_user_ptr_lock); + return (error); +} + +#ifdef illumos +int +getzfsvfs(const char *dsname, zfsvfs_t **zfvp) +{ + objset_t *os; + int error; + + error = dmu_objset_hold(dsname, FTAG, &os); + if (error != 0) + return (error); + + error = getzfsvfs_impl(os, zfvp); dmu_objset_rele(os, FTAG); - if (error == 0) { - error = vfs_busy(vfsp, 0); - vfs_rel(vfsp); - if (error != 0) { - *zfvp = NULL; - error = SET_ERROR(ESRCH); - } + return (error); +} + +#else + +static int +getzfsvfs_ref(const char *dsname, zfsvfs_t **zfvp) +{ + objset_t *os; + int error; + + error = dmu_objset_hold(dsname, FTAG, &os); + if (error != 0) + return (error); + + error = getzfsvfs_impl(os, zfvp); + dmu_objset_rele(os, FTAG); + return (error); +} + +int +getzfsvfs(const char *dsname, zfsvfs_t **zfvp) +{ + objset_t *os; + int error; + + error = getzfsvfs_ref(dsname, zfvp); + if (error != 0) + return (error); + error = vfs_busy((*zfvp)->z_vfs, 0); + vfs_rel((*zfvp)->z_vfs); + if (error != 0) { + *zfvp = NULL; + error = SET_ERROR(ESRCH); } return (error); } +#endif /* * Find a zfsvfs_t for a mounted filesystem, or create our own, in which @@ -3044,27 +3084,6 @@ zfs_ioc_get_fsacl(zfs_cmd_t *zc) return (error); } -/* - * Search the vfs list for a specified resource. Returns a pointer to it - * or NULL if no suitable entry is found. The caller of this routine - * is responsible for releasing the returned vfs pointer. - */ -static vfs_t * -zfs_get_vfs(const char *resource) -{ - vfs_t *vfsp; - - mtx_lock(&mountlist_mtx); - TAILQ_FOREACH(vfsp, &mountlist, mnt_list) { - if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { - vfs_ref(vfsp); - break; - } - } - mtx_unlock(&mountlist_mtx); - return (vfsp); -} - /* ARGSUSED */ static void zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx) @@ -3546,30 +3565,29 @@ zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) * Returns 0 if the argument is not a snapshot, or it is not currently a * filesystem, or we were able to unmount it. Returns error code otherwise. */ -int +void zfs_unmount_snap(const char *snapname) { - vfs_t *vfsp; - zfsvfs_t *zfsvfs; -#ifdef illumos - int err; -#endif + vfs_t *vfsp = NULL; + zfsvfs_t *zfsvfs = NULL; if (strchr(snapname, '@') == NULL) - return (0); + return; - vfsp = zfs_get_vfs(snapname); - if (vfsp == NULL) - return (0); + int err = getzfsvfs_ref(snapname, &zfsvfs); + if (err != 0) { + ASSERT3P(zfsvfs, ==, NULL); + return; + } + vfsp = zfsvfs->z_vfs; - zfsvfs = vfsp->vfs_data; ASSERT(!dsl_pool_config_held(dmu_objset_pool(zfsvfs->z_os))); #ifdef illumos err = vn_vfswlock(vfsp->vfs_vnodecovered); VFS_RELE(vfsp); if (err != 0) - return (SET_ERROR(err)); + return; #endif /* @@ -3580,14 +3598,14 @@ zfs_unmount_snap(const char *snapname) #else (void) dounmount(vfsp, MS_FORCE, curthread); #endif - return (0); } /* ARGSUSED */ static int zfs_unmount_snap_cb(const char *snapname, void *arg) { - return (zfs_unmount_snap(snapname)); + zfs_unmount_snap(snapname); + return (0); } /* @@ -3610,7 +3628,7 @@ zfs_destroy_unmount_origin(const char *fsname) char originname[ZFS_MAX_DATASET_NAME_LEN]; dsl_dataset_name(ds->ds_prev, originname); dmu_objset_rele(os, FTAG); - (void) zfs_unmount_snap(originname); + zfs_unmount_snap(originname); } else { dmu_objset_rele(os, FTAG); } @@ -3651,9 +3669,7 @@ zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl) (name[poollen] != '/' && name[poollen] != '@')) return (SET_ERROR(EXDEV)); - error = zfs_unmount_snap(name); - if (error != 0) - return (error); + zfs_unmount_snap(nvpair_name(pair)); #if defined(__FreeBSD__) zvol_remove_minors(name); #endif @@ -3756,6 +3772,36 @@ zfs_ioc_destroy_bookmarks(const char *poolname, nvlist_t *innvl, return (error); } +static int +zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, + nvlist_t *outnvl) +{ + char *program; + uint64_t instrlimit, memlimit; + nvpair_t *nvarg = NULL; + + if (0 != nvlist_lookup_string(innvl, ZCP_ARG_PROGRAM, &program)) { + return (EINVAL); + } + if (0 != nvlist_lookup_uint64(innvl, ZCP_ARG_INSTRLIMIT, &instrlimit)) { + instrlimit = ZCP_DEFAULT_INSTRLIMIT; + } + if (0 != nvlist_lookup_uint64(innvl, ZCP_ARG_MEMLIMIT, &memlimit)) { + memlimit = ZCP_DEFAULT_MEMLIMIT; + } + if (0 != nvlist_lookup_nvpair(innvl, ZCP_ARG_ARGLIST, &nvarg)) { + return (EINVAL); + } + + if (instrlimit == 0 || instrlimit > zfs_lua_max_instrlimit) + return (EINVAL); + if (memlimit == 0 || memlimit > zfs_lua_max_memlimit) + return (EINVAL); + + return (zcp_eval(poolname, program, instrlimit, memlimit, + nvarg, outnvl)); +} + /* * inputs: * zc_name name of dataset to destroy @@ -3769,11 +3815,8 @@ zfs_ioc_destroy(zfs_cmd_t *zc) { int err; - if (zc->zc_objset_type == DMU_OST_ZFS) { - err = zfs_unmount_snap(zc->zc_name); - if (err != 0) - return (err); - } + if (zc->zc_objset_type == DMU_OST_ZFS) + zfs_unmount_snap(zc->zc_name); if (strchr(zc->zc_name, '@')) err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy); @@ -3845,7 +3888,9 @@ recursive_unmount(const char *fsname, void *arg) char fullname[ZFS_MAX_DATASET_NAME_LEN]; (void) snprintf(fullname, sizeof (fullname), "%s@%s", fsname, snapname); - return (zfs_unmount_snap(fullname)); + zfs_unmount_snap(fullname); + + return (0); } /* @@ -6021,6 +6066,11 @@ zfs_ioctl_init(void) POOL_NAME, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); + zfs_ioctl_register("channel_program", ZFS_IOC_CHANNEL_PROGRAM, + zfs_ioc_channel_program, zfs_secpolicy_config, + POOL_NAME, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, + B_TRUE); + /* IOCTLS that use the legacy function signature */ zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze, @@ -6541,12 +6591,23 @@ zfsdev_ioctl(struct cdev *dev, u_long zcmd, caddr_t arg, int flag, outnvl = fnvlist_alloc(); error = vec->zvec_func(zc->zc_name, innvl, outnvl); - if (error == 0 && vec->zvec_allow_log && + /* + * Some commands can partially execute, modfiy state, and still + * return an error. In these cases, attempt to record what + * was modified. + */ + if ((error == 0 || + (cmd == ZFS_IOC_CHANNEL_PROGRAM && error != EINVAL)) && + vec->zvec_allow_log && spa_open(zc->zc_name, &spa, FTAG) == 0) { if (!nvlist_empty(outnvl)) { fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL, outnvl); } + if (error != 0) { + fnvlist_add_int64(lognv, ZPOOL_HIST_ERRNO, + error); + } (void) spa_history_log_nvl(spa, lognv); spa_close(spa, FTAG); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 154704bbe472..a8cacd4039e7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -995,12 +995,26 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) * We claim to always be readonly so we can open snapshots; * other ZPL code will prevent us from writing to snapshots. */ + error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os); - if (error) { + if (error != 0) { kmem_free(zfsvfs, sizeof (zfsvfs_t)); return (error); } + error = zfsvfs_create_impl(zfvp, zfsvfs, os); + if (error != 0) { + dmu_objset_disown(os, zfsvfs); + } + return (error); +} + + +int +zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os) +{ + int error; + zfsvfs->z_vfs = NULL; zfsvfs->z_parent = zfsvfs; @@ -1020,7 +1034,6 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) error = zfsvfs_init(zfsvfs, os); if (error != 0) { - dmu_objset_disown(os, zfsvfs); *zfvp = NULL; kmem_free(zfsvfs, sizeof (zfsvfs_t)); return (error); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 05d79c2fa916..fc8bdb3103df 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -76,6 +76,7 @@ #include #include #include +#include /* * Programming rules. @@ -1276,7 +1277,7 @@ zfs_get_done(zgd_t *zgd, int error) VN_RELE_ASYNC(ZTOV(zp), dsl_pool_vnrele_taskq(dmu_objset_pool(os))); if (error == 0 && zgd->zgd_bp) - zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); + zil_lwb_add_block(zgd->zgd_lwb, zgd->zgd_bp); kmem_free(zgd, sizeof (zgd_t)); } @@ -1289,7 +1290,7 @@ static int zil_fault_io = 0; * Get data to generate a TX_WRITE intent log record. */ int -zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) +zfs_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio) { zfsvfs_t *zfsvfs = arg; objset_t *os = zfsvfs->z_os; @@ -1301,8 +1302,9 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) zgd_t *zgd; int error = 0; - ASSERT(zio != NULL); - ASSERT(size != 0); + ASSERT3P(lwb, !=, NULL); + ASSERT3P(zio, !=, NULL); + ASSERT3U(size, !=, 0); /* * Nothing to do if the file has been removed @@ -1320,7 +1322,7 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) } zgd = (zgd_t *)kmem_zalloc(sizeof (zgd_t), KM_SLEEP); - zgd->zgd_zilog = zfsvfs->z_log; + zgd->zgd_lwb = lwb; zgd->zgd_private = zp; /* @@ -1343,7 +1345,7 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) } else { /* indirect write */ /* * Have to lock the whole block to ensure when it's - * written out and it's checksum is being calculated + * written out and its checksum is being calculated * that no one can change the data. We need to re-check * blocksize after we get the lock in case it's changed! */ @@ -6007,6 +6009,7 @@ struct vop_vector zfs_vnodeops = { .vop_inactive = zfs_freebsd_inactive, .vop_reclaim = zfs_freebsd_reclaim, .vop_access = zfs_freebsd_access, + .vop_allocate = VOP_EINVAL, .vop_lookup = zfs_cache_lookup, .vop_cachedlookup = zfs_freebsd_lookup, .vop_getattr = zfs_freebsd_getattr, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c index 8c3232f6c682..c21bfaa582ca 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c @@ -42,31 +42,52 @@ #include /* - * The zfs intent log (ZIL) saves transaction records of system calls - * that change the file system in memory with enough information - * to be able to replay them. These are stored in memory until - * either the DMU transaction group (txg) commits them to the stable pool - * and they can be discarded, or they are flushed to the stable log - * (also in the pool) due to a fsync, O_DSYNC or other synchronous - * requirement. In the event of a panic or power fail then those log - * records (transactions) are replayed. + * The ZFS Intent Log (ZIL) saves "transaction records" (itxs) of system + * calls that change the file system. Each itx has enough information to + * be able to replay them after a system crash, power loss, or + * equivalent failure mode. These are stored in memory until either: * - * There is one ZIL per file system. Its on-disk (pool) format consists - * of 3 parts: + * 1. they are committed to the pool by the DMU transaction group + * (txg), at which point they can be discarded; or + * 2. they are committed to the on-disk ZIL for the dataset being + * modified (e.g. due to an fsync, O_DSYNC, or other synchronous + * requirement). * - * - ZIL header - * - ZIL blocks - * - ZIL records + * In the event of a crash or power loss, the itxs contained by each + * dataset's on-disk ZIL will be replayed when that dataset is first + * instantianted (e.g. if the dataset is a normal fileystem, when it is + * first mounted). * - * A log record holds a system call transaction. Log blocks can - * hold many log records and the blocks are chained together. - * Each ZIL block contains a block pointer (blkptr_t) to the next - * ZIL block in the chain. The ZIL header points to the first - * block in the chain. Note there is not a fixed place in the pool - * to hold blocks. They are dynamically allocated and freed as - * needed from the blocks available. Figure X shows the ZIL structure: + * As hinted at above, there is one ZIL per dataset (both the in-memory + * representation, and the on-disk representation). The on-disk format + * consists of 3 parts: + * + * - a single, per-dataset, ZIL header; which points to a chain of + * - zero or more ZIL blocks; each of which contains + * - zero or more ZIL records + * + * A ZIL record holds the information necessary to replay a single + * system call transaction. A ZIL block can hold many ZIL records, and + * the blocks are chained together, similarly to a singly linked list. + * + * Each ZIL block contains a block pointer (blkptr_t) to the next ZIL + * block in the chain, and the ZIL header points to the first block in + * the chain. + * + * Note, there is not a fixed place in the pool to hold these ZIL + * blocks; they are dynamically allocated and freed as needed from the + * blocks available on the pool, though they can be preferentially + * allocated from a dedicated "log" vdev. */ +/* + * This controls the amount of time that a ZIL block (lwb) will remain + * "open" when it isn't "full", and it has a thread waiting for it to be + * committed to stable storage. Please refer to the zil_commit_waiter() + * function (and the comments within it) for more details. + */ +int zfs_commit_timeout_pct = 5; + /* * Disable intent logging replay. This global ZIL switch affects all pools. */ @@ -98,6 +119,7 @@ SYSCTL_QUAD(_vfs_zfs, OID_AUTO, zil_slog_bulk, CTLFLAG_RWTUN, &zil_slog_bulk, 0, "Maximal SLOG commit size with sync priority"); static kmem_cache_t *zil_lwb_cache; +static kmem_cache_t *zil_zcw_cache; #define LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \ sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused)) @@ -445,6 +467,20 @@ zil_free_log_record(zilog_t *zilog, lr_t *lrc, void *tx, uint64_t claim_txg) return (0); } +static int +zil_lwb_vdev_compare(const void *x1, const void *x2) +{ + const uint64_t v1 = ((zil_vdev_node_t *)x1)->zv_vdev; + const uint64_t v2 = ((zil_vdev_node_t *)x2)->zv_vdev; + + if (v1 < v2) + return (-1); + if (v1 > v2) + return (1); + + return (0); +} + static lwb_t * zil_alloc_lwb(zilog_t *zilog, blkptr_t *bp, boolean_t slog, uint64_t txg) { @@ -454,10 +490,13 @@ zil_alloc_lwb(zilog_t *zilog, blkptr_t *bp, boolean_t slog, uint64_t txg) lwb->lwb_zilog = zilog; lwb->lwb_blk = *bp; lwb->lwb_slog = slog; + lwb->lwb_state = LWB_STATE_CLOSED; lwb->lwb_buf = zio_buf_alloc(BP_GET_LSIZE(bp)); lwb->lwb_max_txg = txg; - lwb->lwb_zio = NULL; + lwb->lwb_write_zio = NULL; + lwb->lwb_root_zio = NULL; lwb->lwb_tx = NULL; + lwb->lwb_issued_timestamp = 0; if (BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_ZILOG2) { lwb->lwb_nused = sizeof (zil_chain_t); lwb->lwb_sz = BP_GET_LSIZE(bp); @@ -470,9 +509,54 @@ zil_alloc_lwb(zilog_t *zilog, blkptr_t *bp, boolean_t slog, uint64_t txg) list_insert_tail(&zilog->zl_lwb_list, lwb); mutex_exit(&zilog->zl_lock); + ASSERT(!MUTEX_HELD(&lwb->lwb_vdev_lock)); + ASSERT(avl_is_empty(&lwb->lwb_vdev_tree)); + ASSERT(list_is_empty(&lwb->lwb_waiters)); + return (lwb); } +static void +zil_free_lwb(zilog_t *zilog, lwb_t *lwb) +{ + ASSERT(MUTEX_HELD(&zilog->zl_lock)); + ASSERT(!MUTEX_HELD(&lwb->lwb_vdev_lock)); + ASSERT(list_is_empty(&lwb->lwb_waiters)); + + if (lwb->lwb_state == LWB_STATE_OPENED) { + avl_tree_t *t = &lwb->lwb_vdev_tree; + void *cookie = NULL; + zil_vdev_node_t *zv; + + while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) + kmem_free(zv, sizeof (*zv)); + + ASSERT3P(lwb->lwb_root_zio, !=, NULL); + ASSERT3P(lwb->lwb_write_zio, !=, NULL); + + zio_cancel(lwb->lwb_root_zio); + zio_cancel(lwb->lwb_write_zio); + + lwb->lwb_root_zio = NULL; + lwb->lwb_write_zio = NULL; + } else { + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_ISSUED); + } + + ASSERT(avl_is_empty(&lwb->lwb_vdev_tree)); + ASSERT3P(lwb->lwb_write_zio, ==, NULL); + ASSERT3P(lwb->lwb_root_zio, ==, NULL); + + /* + * Clear the zilog's field to indicate this lwb is no longer + * valid, and prevent use-after-free errors. + */ + if (zilog->zl_last_lwb_opened == lwb) + zilog->zl_last_lwb_opened = NULL; + + kmem_cache_free(zil_lwb_cache, lwb); +} + /* * Called when we create in-memory log transactions so that we know * to cleanup the itxs at the end of spa_sync(). @@ -483,12 +567,16 @@ zilog_dirty(zilog_t *zilog, uint64_t txg) dsl_pool_t *dp = zilog->zl_dmu_pool; dsl_dataset_t *ds = dmu_objset_ds(zilog->zl_os); + ASSERT(spa_writeable(zilog->zl_spa)); + if (ds->ds_is_snapshot) panic("dirtying snapshot!"); if (txg_list_add(&dp->dp_dirty_zilogs, zilog, txg)) { /* up the hold count until we can be written out */ dmu_buf_add_ref(ds->ds_dbuf, zilog); + + zilog->zl_dirty_max_txg = MAX(txg, zilog->zl_dirty_max_txg); } } @@ -556,7 +644,7 @@ zil_create(zilog_t *zilog) */ if (BP_IS_HOLE(&blk) || BP_SHOULD_BYTESWAP(&blk)) { tx = dmu_tx_create(zilog->zl_os); - VERIFY(dmu_tx_assign(tx, TXG_WAIT) == 0); + VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx); txg = dmu_tx_get_txg(tx); @@ -573,7 +661,7 @@ zil_create(zilog_t *zilog) } /* - * Allocate a log write buffer (lwb) for the first log block. + * Allocate a log write block (lwb) for the first log block. */ if (error == 0) lwb = zil_alloc_lwb(zilog, &blk, slog, txg); @@ -594,13 +682,13 @@ zil_create(zilog_t *zilog) } /* - * In one tx, free all log blocks and clear the log header. - * If keep_first is set, then we're replaying a log with no content. - * We want to keep the first block, however, so that the first - * synchronous transaction doesn't require a txg_wait_synced() - * in zil_create(). We don't need to txg_wait_synced() here either - * when keep_first is set, because both zil_create() and zil_destroy() - * will wait for any in-progress destroys to complete. + * In one tx, free all log blocks and clear the log header. If keep_first + * is set, then we're replaying a log with no content. We want to keep the + * first block, however, so that the first synchronous transaction doesn't + * require a txg_wait_synced() in zil_create(). We don't need to + * txg_wait_synced() here either when keep_first is set, because both + * zil_create() and zil_destroy() will wait for any in-progress destroys + * to complete. */ void zil_destroy(zilog_t *zilog, boolean_t keep_first) @@ -621,7 +709,7 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first) return; tx = dmu_tx_create(zilog->zl_os); - VERIFY(dmu_tx_assign(tx, TXG_WAIT) == 0); + VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx); txg = dmu_tx_get_txg(tx); @@ -638,8 +726,8 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first) list_remove(&zilog->zl_lwb_list, lwb); if (lwb->lwb_buf != NULL) zio_buf_free(lwb->lwb_buf, lwb->lwb_sz); - zio_free_zil(zilog->zl_spa, txg, &lwb->lwb_blk); - kmem_cache_free(zil_lwb_cache, lwb); + zio_free(zilog->zl_spa, txg, &lwb->lwb_blk); + zil_free_lwb(zilog, lwb); } } else if (!keep_first) { zil_destroy_sync(zilog, tx); @@ -777,24 +865,64 @@ zil_check_log_chain(dsl_pool_t *dp, dsl_dataset_t *ds, void *tx) return ((error == ECKSUM || error == ENOENT) ? 0 : error); } -static int -zil_vdev_compare(const void *x1, const void *x2) +/* + * When an itx is "skipped", this function is used to properly mark the + * waiter as "done, and signal any thread(s) waiting on it. An itx can + * be skipped (and not committed to an lwb) for a variety of reasons, + * one of them being that the itx was committed via spa_sync(), prior to + * it being committed to an lwb; this can happen if a thread calling + * zil_commit() is racing with spa_sync(). + */ +static void +zil_commit_waiter_skip(zil_commit_waiter_t *zcw) { - const uint64_t v1 = ((zil_vdev_node_t *)x1)->zv_vdev; - const uint64_t v2 = ((zil_vdev_node_t *)x2)->zv_vdev; + mutex_enter(&zcw->zcw_lock); + ASSERT3B(zcw->zcw_done, ==, B_FALSE); + zcw->zcw_done = B_TRUE; + cv_broadcast(&zcw->zcw_cv); + mutex_exit(&zcw->zcw_lock); +} - if (v1 < v2) - return (-1); - if (v1 > v2) - return (1); +/* + * This function is used when the given waiter is to be linked into an + * lwb's "lwb_waiter" list; i.e. when the itx is committed to the lwb. + * At this point, the waiter will no longer be referenced by the itx, + * and instead, will be referenced by the lwb. + */ +static void +zil_commit_waiter_link_lwb(zil_commit_waiter_t *zcw, lwb_t *lwb) +{ + mutex_enter(&zcw->zcw_lock); + ASSERT(!list_link_active(&zcw->zcw_node)); + ASSERT3P(zcw->zcw_lwb, ==, NULL); + ASSERT3P(lwb, !=, NULL); + ASSERT(lwb->lwb_state == LWB_STATE_OPENED || + lwb->lwb_state == LWB_STATE_ISSUED); - return (0); + list_insert_tail(&lwb->lwb_waiters, zcw); + zcw->zcw_lwb = lwb; + mutex_exit(&zcw->zcw_lock); +} + +/* + * This function is used when zio_alloc_zil() fails to allocate a ZIL + * block, and the given waiter must be linked to the "nolwb waiters" + * list inside of zil_process_commit_list(). + */ +static void +zil_commit_waiter_link_nolwb(zil_commit_waiter_t *zcw, list_t *nolwb) +{ + mutex_enter(&zcw->zcw_lock); + ASSERT(!list_link_active(&zcw->zcw_node)); + ASSERT3P(zcw->zcw_lwb, ==, NULL); + list_insert_tail(nolwb, zcw); + mutex_exit(&zcw->zcw_lock); } void -zil_add_block(zilog_t *zilog, const blkptr_t *bp) +zil_lwb_add_block(lwb_t *lwb, const blkptr_t *bp) { - avl_tree_t *t = &zilog->zl_vdev_tree; + avl_tree_t *t = &lwb->lwb_vdev_tree; avl_index_t where; zil_vdev_node_t *zv, zvsearch; int ndvas = BP_GET_NDVAS(bp); @@ -803,14 +931,7 @@ zil_add_block(zilog_t *zilog, const blkptr_t *bp) if (zfs_nocacheflush) return; - ASSERT(zilog->zl_writer); - - /* - * Even though we're zl_writer, we still need a lock because the - * zl_get_data() callbacks may have dmu_sync() done callbacks - * that will run concurrently. - */ - mutex_enter(&zilog->zl_vdev_lock); + mutex_enter(&lwb->lwb_vdev_lock); for (i = 0; i < ndvas; i++) { zvsearch.zv_vdev = DVA_GET_VDEV(&bp->blk_dva[i]); if (avl_find(t, &zvsearch, &where) == NULL) { @@ -819,80 +940,85 @@ zil_add_block(zilog_t *zilog, const blkptr_t *bp) avl_insert(t, zv, where); } } - mutex_exit(&zilog->zl_vdev_lock); + mutex_exit(&lwb->lwb_vdev_lock); } -static void -zil_flush_vdevs(zilog_t *zilog) +void +zil_lwb_add_txg(lwb_t *lwb, uint64_t txg) { - spa_t *spa = zilog->zl_spa; - avl_tree_t *t = &zilog->zl_vdev_tree; - void *cookie = NULL; - zil_vdev_node_t *zv; - zio_t *zio = NULL; - - ASSERT(zilog->zl_writer); - - /* - * We don't need zl_vdev_lock here because we're the zl_writer, - * and all zl_get_data() callbacks are done. - */ - if (avl_numnodes(t) == 0) - return; - - spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); - - while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) { - vdev_t *vd = vdev_lookup_top(spa, zv->zv_vdev); - if (vd != NULL && !vd->vdev_nowritecache) { - if (zio == NULL) - zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); - zio_flush(zio, vd); - } - kmem_free(zv, sizeof (*zv)); - } - - /* - * Wait for all the flushes to complete. Not all devices actually - * support the DKIOCFLUSHWRITECACHE ioctl, so it's OK if it fails. - */ - if (zio) - (void) zio_wait(zio); - - spa_config_exit(spa, SCL_STATE, FTAG); + lwb->lwb_max_txg = MAX(lwb->lwb_max_txg, txg); } /* - * Function called when a log block write completes + * This function is a called after all VDEVs associated with a given lwb + * write have completed their DKIOCFLUSHWRITECACHE command; or as soon + * as the lwb write completes, if "zfs_nocacheflush" is set. + * + * The intention is for this function to be called as soon as the + * contents of an lwb are considered "stable" on disk, and will survive + * any sudden loss of power. At this point, any threads waiting for the + * lwb to reach this state are signalled, and the "waiter" structures + * are marked "done". */ static void -zil_lwb_write_done(zio_t *zio) +zil_lwb_flush_vdevs_done(zio_t *zio) { lwb_t *lwb = zio->io_private; zilog_t *zilog = lwb->lwb_zilog; dmu_tx_t *tx = lwb->lwb_tx; + zil_commit_waiter_t *zcw; - ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF); - ASSERT(BP_GET_TYPE(zio->io_bp) == DMU_OT_INTENT_LOG); - ASSERT(BP_GET_LEVEL(zio->io_bp) == 0); - ASSERT(BP_GET_BYTEORDER(zio->io_bp) == ZFS_HOST_BYTEORDER); - ASSERT(!BP_IS_GANG(zio->io_bp)); - ASSERT(!BP_IS_HOLE(zio->io_bp)); - ASSERT(BP_GET_FILL(zio->io_bp) == 0); + spa_config_exit(zilog->zl_spa, SCL_STATE, lwb); + + zio_buf_free(lwb->lwb_buf, lwb->lwb_sz); + + mutex_enter(&zilog->zl_lock); /* - * Ensure the lwb buffer pointer is cleared before releasing - * the txg. If we have had an allocation failure and - * the txg is waiting to sync then we want want zil_sync() - * to remove the lwb so that it's not picked up as the next new - * one in zil_commit_writer(). zil_sync() will only remove - * the lwb if lwb_buf is null. + * Ensure the lwb buffer pointer is cleared before releasing the + * txg. If we have had an allocation failure and the txg is + * waiting to sync then we want zil_sync() to remove the lwb so + * that it's not picked up as the next new one in + * zil_process_commit_list(). zil_sync() will only remove the + * lwb if lwb_buf is null. */ - abd_put(zio->io_abd); - zio_buf_free(lwb->lwb_buf, lwb->lwb_sz); - mutex_enter(&zilog->zl_lock); lwb->lwb_buf = NULL; lwb->lwb_tx = NULL; + + ASSERT3U(lwb->lwb_issued_timestamp, >, 0); + zilog->zl_last_lwb_latency = gethrtime() - lwb->lwb_issued_timestamp; + + lwb->lwb_root_zio = NULL; + lwb->lwb_state = LWB_STATE_DONE; + + if (zilog->zl_last_lwb_opened == lwb) { + /* + * Remember the highest committed log sequence number + * for ztest. We only update this value when all the log + * writes succeeded, because ztest wants to ASSERT that + * it got the whole log chain. + */ + zilog->zl_commit_lr_seq = zilog->zl_lr_seq; + } + + while ((zcw = list_head(&lwb->lwb_waiters)) != NULL) { + mutex_enter(&zcw->zcw_lock); + + ASSERT(list_link_active(&zcw->zcw_node)); + list_remove(&lwb->lwb_waiters, zcw); + + ASSERT3P(zcw->zcw_lwb, ==, lwb); + zcw->zcw_lwb = NULL; + + zcw->zcw_zio_error = zio->io_error; + + ASSERT3B(zcw->zcw_done, ==, B_FALSE); + zcw->zcw_done = B_TRUE; + cv_broadcast(&zcw->zcw_cv); + + mutex_exit(&zcw->zcw_lock); + } + mutex_exit(&zilog->zl_lock); /* @@ -904,34 +1030,144 @@ zil_lwb_write_done(zio_t *zio) } /* - * Initialize the io for a log block. + * This is called when an lwb write completes. This means, this specific + * lwb was written to disk, and all dependent lwb have also been + * written to disk. + * + * At this point, a DKIOCFLUSHWRITECACHE command hasn't been issued to + * the VDEVs involved in writing out this specific lwb. The lwb will be + * "done" once zil_lwb_flush_vdevs_done() is called, which occurs in the + * zio completion callback for the lwb's root zio. */ static void -zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb) +zil_lwb_write_done(zio_t *zio) +{ + lwb_t *lwb = zio->io_private; + spa_t *spa = zio->io_spa; + zilog_t *zilog = lwb->lwb_zilog; + avl_tree_t *t = &lwb->lwb_vdev_tree; + void *cookie = NULL; + zil_vdev_node_t *zv; + + ASSERT3S(spa_config_held(spa, SCL_STATE, RW_READER), !=, 0); + + ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF); + ASSERT(BP_GET_TYPE(zio->io_bp) == DMU_OT_INTENT_LOG); + ASSERT(BP_GET_LEVEL(zio->io_bp) == 0); + ASSERT(BP_GET_BYTEORDER(zio->io_bp) == ZFS_HOST_BYTEORDER); + ASSERT(!BP_IS_GANG(zio->io_bp)); + ASSERT(!BP_IS_HOLE(zio->io_bp)); + ASSERT(BP_GET_FILL(zio->io_bp) == 0); + + abd_put(zio->io_abd); + + ASSERT3S(lwb->lwb_state, ==, LWB_STATE_ISSUED); + + mutex_enter(&zilog->zl_lock); + lwb->lwb_write_zio = NULL; + mutex_exit(&zilog->zl_lock); + + if (avl_numnodes(t) == 0) + return; + + /* + * If there was an IO error, we're not going to call zio_flush() + * on these vdevs, so we simply empty the tree and free the + * nodes. We avoid calling zio_flush() since there isn't any + * good reason for doing so, after the lwb block failed to be + * written out. + */ + if (zio->io_error != 0) { + while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) + kmem_free(zv, sizeof (*zv)); + return; + } + + while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) { + vdev_t *vd = vdev_lookup_top(spa, zv->zv_vdev); + if (vd != NULL) + zio_flush(lwb->lwb_root_zio, vd); + kmem_free(zv, sizeof (*zv)); + } +} + +/* + * This function's purpose is to "open" an lwb such that it is ready to + * accept new itxs being committed to it. To do this, the lwb's zio + * structures are created, and linked to the lwb. This function is + * idempotent; if the passed in lwb has already been opened, this + * function is essentially a no-op. + */ +static void +zil_lwb_write_open(zilog_t *zilog, lwb_t *lwb) { zbookmark_phys_t zb; zio_priority_t prio; + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + ASSERT3P(lwb, !=, NULL); + EQUIV(lwb->lwb_root_zio == NULL, lwb->lwb_state == LWB_STATE_CLOSED); + EQUIV(lwb->lwb_root_zio != NULL, lwb->lwb_state == LWB_STATE_OPENED); + SET_BOOKMARK(&zb, lwb->lwb_blk.blk_cksum.zc_word[ZIL_ZC_OBJSET], ZB_ZIL_OBJECT, ZB_ZIL_LEVEL, lwb->lwb_blk.blk_cksum.zc_word[ZIL_ZC_SEQ]); - if (zilog->zl_root_zio == NULL) { - zilog->zl_root_zio = zio_root(zilog->zl_spa, NULL, NULL, - ZIO_FLAG_CANFAIL); - } - if (lwb->lwb_zio == NULL) { + if (lwb->lwb_root_zio == NULL) { abd_t *lwb_abd = abd_get_from_buf(lwb->lwb_buf, BP_GET_LSIZE(&lwb->lwb_blk)); + if (!lwb->lwb_slog || zilog->zl_cur_used <= zil_slog_bulk) prio = ZIO_PRIORITY_SYNC_WRITE; else prio = ZIO_PRIORITY_ASYNC_WRITE; - lwb->lwb_zio = zio_rewrite(zilog->zl_root_zio, zilog->zl_spa, - 0, &lwb->lwb_blk, lwb_abd, BP_GET_LSIZE(&lwb->lwb_blk), - zil_lwb_write_done, lwb, prio, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE, &zb); + + lwb->lwb_root_zio = zio_root(zilog->zl_spa, + zil_lwb_flush_vdevs_done, lwb, ZIO_FLAG_CANFAIL); + ASSERT3P(lwb->lwb_root_zio, !=, NULL); + + lwb->lwb_write_zio = zio_rewrite(lwb->lwb_root_zio, + zilog->zl_spa, 0, &lwb->lwb_blk, lwb_abd, + BP_GET_LSIZE(&lwb->lwb_blk), zil_lwb_write_done, lwb, + prio, ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE, &zb); + ASSERT3P(lwb->lwb_write_zio, !=, NULL); + + lwb->lwb_state = LWB_STATE_OPENED; + + mutex_enter(&zilog->zl_lock); + + /* + * The zilog's "zl_last_lwb_opened" field is used to + * build the lwb/zio dependency chain, which is used to + * preserve the ordering of lwb completions that is + * required by the semantics of the ZIL. Each new lwb + * zio becomes a parent of the "previous" lwb zio, such + * that the new lwb's zio cannot complete until the + * "previous" lwb's zio completes. + * + * This is required by the semantics of zil_commit(); + * the commit waiters attached to the lwbs will be woken + * in the lwb zio's completion callback, so this zio + * dependency graph ensures the waiters are woken in the + * correct order (the same order the lwbs were created). + */ + lwb_t *last_lwb_opened = zilog->zl_last_lwb_opened; + if (last_lwb_opened != NULL && + last_lwb_opened->lwb_state != LWB_STATE_DONE) { + ASSERT(last_lwb_opened->lwb_state == LWB_STATE_OPENED || + last_lwb_opened->lwb_state == LWB_STATE_ISSUED); + ASSERT3P(last_lwb_opened->lwb_root_zio, !=, NULL); + zio_add_child(lwb->lwb_root_zio, + last_lwb_opened->lwb_root_zio); + } + zilog->zl_last_lwb_opened = lwb; + + mutex_exit(&zilog->zl_lock); } + + ASSERT3P(lwb->lwb_root_zio, !=, NULL); + ASSERT3P(lwb->lwb_write_zio, !=, NULL); + ASSERT3S(lwb->lwb_state, ==, LWB_STATE_OPENED); } /* @@ -953,7 +1189,7 @@ uint64_t zil_block_buckets[] = { * Calls are serialized. */ static lwb_t * -zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) +zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb) { lwb_t *nlwb = NULL; zil_chain_t *zilc; @@ -965,6 +1201,11 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) int i, error; boolean_t slog; + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + ASSERT3P(lwb->lwb_root_zio, !=, NULL); + ASSERT3P(lwb->lwb_write_zio, !=, NULL); + ASSERT3S(lwb->lwb_state, ==, LWB_STATE_OPENED); + if (BP_GET_CHECKSUM(&lwb->lwb_blk) == ZIO_CHECKSUM_ZILOG2) { zilc = (zil_chain_t *)lwb->lwb_buf; bp = &zilc->zc_next_blk; @@ -984,6 +1225,7 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) * We dirty the dataset to ensure that zil_sync() will be called * to clean up in the event of allocation failure or I/O failure. */ + tx = dmu_tx_create(zilog->zl_os); /* @@ -1036,6 +1278,7 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) zilog->zl_prev_rotor = (zilog->zl_prev_rotor + 1) & (ZIL_PREV_BLKS - 1); BP_ZERO(bp); + /* pass the old blkptr in order to spread log blocks across devs */ error = zio_alloc_zil(spa, txg, bp, &lwb->lwb_blk, zil_blksz, &slog); if (error == 0) { @@ -1044,19 +1287,16 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) bp->blk_cksum.zc_word[ZIL_ZC_SEQ]++; /* - * Allocate a new log write buffer (lwb). + * Allocate a new log write block (lwb). */ nlwb = zil_alloc_lwb(zilog, bp, slog, txg); - - /* Record the block for later vdev flushing */ - zil_add_block(zilog, &lwb->lwb_blk); } if (BP_GET_CHECKSUM(&lwb->lwb_blk) == ZIO_CHECKSUM_ZILOG2) { /* For Slim ZIL only write what is used. */ wsz = P2ROUNDUP_TYPED(lwb->lwb_nused, ZIL_MIN_BLKSZ, uint64_t); ASSERT3U(wsz, <=, lwb->lwb_sz); - zio_shrink(lwb->lwb_zio, wsz); + zio_shrink(lwb->lwb_write_zio, wsz); } else { wsz = lwb->lwb_sz; @@ -1071,9 +1311,14 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb, boolean_t last) */ bzero(lwb->lwb_buf + lwb->lwb_nused, wsz - lwb->lwb_nused); - if (last) - lwb->lwb_zio->io_pipeline &= ~ZIO_STAGE_ISSUE_ASYNC; - zio_nowait(lwb->lwb_zio); /* Kick off the write for the old log block */ + spa_config_enter(zilog->zl_spa, SCL_STATE, lwb, RW_READER); + + zil_lwb_add_block(lwb, &lwb->lwb_blk); + lwb->lwb_issued_timestamp = gethrtime(); + lwb->lwb_state = LWB_STATE_ISSUED; + + zio_nowait(lwb->lwb_root_zio); + zio_nowait(lwb->lwb_write_zio); /* * If there was an allocation failure then nlwb will be null which @@ -1090,13 +1335,33 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) char *lr_buf; uint64_t dlen, dnow, lwb_sp, reclen, txg; - if (lwb == NULL) - return (NULL); + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + ASSERT3P(lwb, !=, NULL); + ASSERT3P(lwb->lwb_buf, !=, NULL); - ASSERT(lwb->lwb_buf != NULL); + zil_lwb_write_open(zilog, lwb); + + lrc = &itx->itx_lr; + lrw = (lr_write_t *)lrc; + + /* + * A commit itx doesn't represent any on-disk state; instead + * it's simply used as a place holder on the commit list, and + * provides a mechanism for attaching a "commit waiter" onto the + * correct lwb (such that the waiter can be signalled upon + * completion of that lwb). Thus, we don't process this itx's + * log record if it's a commit itx (these itx's don't have log + * records), and instead link the itx's waiter onto the lwb's + * list of waiters. + * + * For more details, see the comment above zil_commit(). + */ + if (lrc->lrc_txtype == TX_COMMIT) { + zil_commit_waiter_link_lwb(itx->itx_private, lwb); + itx->itx_private = NULL; + return (lwb); + } - lrc = &itx->itx_lr; /* Common log record inside itx. */ - lrw = (lr_write_t *)lrc; /* Write log record inside itx. */ if (lrc->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY) { dlen = P2ROUNDUP_TYPED( lrw->lr_length, sizeof (uint64_t), uint64_t); @@ -1107,7 +1372,7 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) zilog->zl_cur_used += (reclen + dlen); txg = lrc->lrc_txg; - zil_lwb_write_init(zilog, lwb); + ASSERT3U(zilog->zl_cur_used, <, UINT64_MAX - (reclen + dlen)); cont: /* @@ -1118,10 +1383,10 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) if (reclen > lwb_sp || (reclen + dlen > lwb_sp && lwb_sp < ZIL_MAX_WASTE_SPACE && (dlen % ZIL_MAX_LOG_DATA == 0 || lwb_sp < reclen + dlen % ZIL_MAX_LOG_DATA))) { - lwb = zil_lwb_write_start(zilog, lwb, B_FALSE); + lwb = zil_lwb_write_issue(zilog, lwb); if (lwb == NULL) return (NULL); - zil_lwb_write_init(zilog, lwb); + zil_lwb_write_open(zilog, lwb); ASSERT(LWB_EMPTY(lwb)); lwb_sp = lwb->lwb_sz - lwb->lwb_nused; ASSERT3U(reclen + MIN(dlen, sizeof (uint64_t)), <=, lwb_sp); @@ -1154,8 +1419,25 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) ASSERT(itx->itx_wr_state == WR_INDIRECT); dbuf = NULL; } - error = zilog->zl_get_data( - itx->itx_private, lrwb, dbuf, lwb->lwb_zio); + + /* + * We pass in the "lwb_write_zio" rather than + * "lwb_root_zio" so that the "lwb_write_zio" + * becomes the parent of any zio's created by + * the "zl_get_data" callback. The vdevs are + * flushed after the "lwb_write_zio" completes, + * so we want to make sure that completion + * callback waits for these additional zio's, + * such that the vdevs used by those zio's will + * be included in the lwb's vdev tree, and those + * vdevs will be properly flushed. If we passed + * in "lwb_root_zio" here, then these additional + * vdevs may not be flushed; e.g. if these zio's + * completed after "lwb_write_zio" completed. + */ + error = zilog->zl_get_data(itx->itx_private, + lrwb, dbuf, lwb, lwb->lwb_write_zio); + if (error == EIO) { txg_wait_synced(zilog->zl_dmu_pool, txg); return (lwb); @@ -1174,9 +1456,11 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) * equal to the itx sequence number because not all transactions * are synchronous, and sometimes spa_sync() gets there first. */ - lrcb->lrc_seq = ++zilog->zl_lr_seq; /* we are single threaded */ + lrcb->lrc_seq = ++zilog->zl_lr_seq; lwb->lwb_nused += reclen + dnow; - lwb->lwb_max_txg = MAX(lwb->lwb_max_txg, txg); + + zil_lwb_add_txg(lwb, txg); + ASSERT3U(lwb->lwb_nused, <=, lwb->lwb_sz); ASSERT0(P2PHASE(lwb->lwb_nused, sizeof (uint64_t))); @@ -1226,9 +1510,30 @@ zil_itxg_clean(itxs_t *itxs) list = &itxs->i_sync_list; while ((itx = list_head(list)) != NULL) { + /* + * In the general case, commit itxs will not be found + * here, as they'll be committed to an lwb via + * zil_lwb_commit(), and free'd in that function. Having + * said that, it is still possible for commit itxs to be + * found here, due to the following race: + * + * - a thread calls zil_commit() which assigns the + * commit itx to a per-txg i_sync_list + * - zil_itxg_clean() is called (e.g. via spa_sync()) + * while the waiter is still on the i_sync_list + * + * There's nothing to prevent syncing the txg while the + * waiter is on the i_sync_list. This normally doesn't + * happen because spa_sync() is slower than zil_commit(), + * but if zil_commit() calls txg_wait_synced() (e.g. + * because zil_create() or zil_commit_writer_stall() is + * called) we will hit this case. + */ + if (itx->itx_lr.lrc_txtype == TX_COMMIT) + zil_commit_waiter_skip(itx->itx_private); + list_remove(list, itx); - kmem_free(itx, offsetof(itx_t, itx_lr) + - itx->itx_lr.lrc_reclen); + zil_itx_destroy(itx); } cookie = NULL; @@ -1237,8 +1542,9 @@ zil_itxg_clean(itxs_t *itxs) list = &ian->ia_list; while ((itx = list_head(list)) != NULL) { list_remove(list, itx); - kmem_free(itx, offsetof(itx_t, itx_lr) + - itx->itx_lr.lrc_reclen); + /* commit itxs should never be on the async lists. */ + ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT); + zil_itx_destroy(itx); } list_destroy(list); kmem_free(ian, sizeof (itx_async_node_t)); @@ -1303,8 +1609,9 @@ zil_remove_async(zilog_t *zilog, uint64_t oid) } while ((itx = list_head(&clean_list)) != NULL) { list_remove(&clean_list, itx); - kmem_free(itx, offsetof(itx_t, itx_lr) + - itx->itx_lr.lrc_reclen); + /* commit itxs should never be on the async lists. */ + ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT); + zil_itx_destroy(itx); } list_destroy(&clean_list); } @@ -1380,7 +1687,14 @@ zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx) } itx->itx_lr.lrc_txg = dmu_tx_get_txg(tx); - zilog_dirty(zilog, txg); + + /* + * We don't want to dirty the ZIL using ZILTEST_TXG, because + * zil_clean() will never be called using ZILTEST_TXG. Thus, we + * need to be careful to always dirty the ZIL using the "real" + * TXG (not itxg_txg) even when the SPA is frozen. + */ + zilog_dirty(zilog, dmu_tx_get_txg(tx)); mutex_exit(&itxg->itxg_lock); /* Release the old itxs now we've dropped the lock */ @@ -1401,6 +1715,8 @@ zil_clean(zilog_t *zilog, uint64_t synced_txg) itxg_t *itxg = &zilog->zl_itxg[synced_txg & TXG_MASK]; itxs_t *clean_me; + ASSERT3U(synced_txg, <, ZILTEST_TXG); + mutex_enter(&itxg->itxg_lock); if (itxg->itxg_itxs == NULL || itxg->itxg_txg == ZILTEST_TXG) { mutex_exit(&itxg->itxg_lock); @@ -1426,7 +1742,8 @@ zil_clean(zilog_t *zilog, uint64_t synced_txg) } /* - * Get the list of itxs to commit into zl_itx_commit_list. + * This function will traverse the queue of itxs that need to be + * committed, and move them onto the ZIL's zl_itx_commit_list. */ static void zil_get_commit_list(zilog_t *zilog) @@ -1434,6 +1751,8 @@ zil_get_commit_list(zilog_t *zilog) uint64_t otxg, txg; list_t *commit_list = &zilog->zl_itx_commit_list; + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + if (spa_freeze_txg(zilog->zl_spa) != UINT64_MAX) /* ziltest support */ otxg = ZILTEST_TXG; else @@ -1525,142 +1844,798 @@ zil_async_to_sync(zilog_t *zilog, uint64_t foid) } } +/* + * This function will prune commit itxs that are at the head of the + * commit list (it won't prune past the first non-commit itx), and + * either: a) attach them to the last lwb that's still pending + * completion, or b) skip them altogether. + * + * This is used as a performance optimization to prevent commit itxs + * from generating new lwbs when it's unnecessary to do so. + */ static void -zil_commit_writer(zilog_t *zilog) +zil_prune_commit_list(zilog_t *zilog) { - uint64_t txg; itx_t *itx; - lwb_t *lwb; + + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + + while (itx = list_head(&zilog->zl_itx_commit_list)) { + lr_t *lrc = &itx->itx_lr; + if (lrc->lrc_txtype != TX_COMMIT) + break; + + mutex_enter(&zilog->zl_lock); + + lwb_t *last_lwb = zilog->zl_last_lwb_opened; + if (last_lwb == NULL || last_lwb->lwb_state == LWB_STATE_DONE) { + /* + * All of the itxs this waiter was waiting on + * must have already completed (or there were + * never any itx's for it to wait on), so it's + * safe to skip this waiter and mark it done. + */ + zil_commit_waiter_skip(itx->itx_private); + } else { + zil_commit_waiter_link_lwb(itx->itx_private, last_lwb); + itx->itx_private = NULL; + } + + mutex_exit(&zilog->zl_lock); + + list_remove(&zilog->zl_itx_commit_list, itx); + zil_itx_destroy(itx); + } + + IMPLY(itx != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT); +} + +static void +zil_commit_writer_stall(zilog_t *zilog) +{ + /* + * When zio_alloc_zil() fails to allocate the next lwb block on + * disk, we must call txg_wait_synced() to ensure all of the + * lwbs in the zilog's zl_lwb_list are synced and then freed (in + * zil_sync()), such that any subsequent ZIL writer (i.e. a call + * to zil_process_commit_list()) will have to call zil_create(), + * and start a new ZIL chain. + * + * Since zil_alloc_zil() failed, the lwb that was previously + * issued does not have a pointer to the "next" lwb on disk. + * Thus, if another ZIL writer thread was to allocate the "next" + * on-disk lwb, that block could be leaked in the event of a + * crash (because the previous lwb on-disk would not point to + * it). + * + * We must hold the zilog's zl_writer_lock while we do this, to + * ensure no new threads enter zil_process_commit_list() until + * all lwb's in the zl_lwb_list have been synced and freed + * (which is achieved via the txg_wait_synced() call). + */ + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); + txg_wait_synced(zilog->zl_dmu_pool, 0); + ASSERT3P(list_tail(&zilog->zl_lwb_list), ==, NULL); +} + +/* + * This function will traverse the commit list, creating new lwbs as + * needed, and committing the itxs from the commit list to these newly + * created lwbs. Additionally, as a new lwb is created, the previous + * lwb will be issued to the zio layer to be written to disk. + */ +static void +zil_process_commit_list(zilog_t *zilog) +{ spa_t *spa = zilog->zl_spa; - int error = 0; + list_t nolwb_waiters; + lwb_t *lwb; + itx_t *itx; - ASSERT(zilog->zl_root_zio == NULL); - - mutex_exit(&zilog->zl_lock); - - zil_get_commit_list(zilog); + ASSERT(MUTEX_HELD(&zilog->zl_writer_lock)); /* * Return if there's nothing to commit before we dirty the fs by * calling zil_create(). */ - if (list_head(&zilog->zl_itx_commit_list) == NULL) { - mutex_enter(&zilog->zl_lock); + if (list_head(&zilog->zl_itx_commit_list) == NULL) return; - } - if (zilog->zl_suspend) { - lwb = NULL; + list_create(&nolwb_waiters, sizeof (zil_commit_waiter_t), + offsetof(zil_commit_waiter_t, zcw_node)); + + lwb = list_tail(&zilog->zl_lwb_list); + if (lwb == NULL) { + lwb = zil_create(zilog); } else { - lwb = list_tail(&zilog->zl_lwb_list); - if (lwb == NULL) - lwb = zil_create(zilog); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_ISSUED); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_DONE); } - DTRACE_PROBE1(zil__cw1, zilog_t *, zilog); while (itx = list_head(&zilog->zl_itx_commit_list)) { - txg = itx->itx_lr.lrc_txg; + lr_t *lrc = &itx->itx_lr; + uint64_t txg = lrc->lrc_txg; + ASSERT3U(txg, !=, 0); + if (lrc->lrc_txtype == TX_COMMIT) { + DTRACE_PROBE2(zil__process__commit__itx, + zilog_t *, zilog, itx_t *, itx); + } else { + DTRACE_PROBE2(zil__process__normal__itx, + zilog_t *, zilog, itx_t *, itx); + } + /* * This is inherently racy and may result in us writing - * out a log block for a txg that was just synced. This is - * ok since we'll end cleaning up that log block the next - * time we call zil_sync(). + * out a log block for a txg that was just synced. This + * is ok since we'll end cleaning up that log block the + * next time we call zil_sync(). */ - if (txg > spa_last_synced_txg(spa) || txg > spa_freeze_txg(spa)) - lwb = zil_lwb_commit(zilog, itx, lwb); + boolean_t synced = txg <= spa_last_synced_txg(spa); + boolean_t frozen = txg > spa_freeze_txg(spa); + + if (!synced || frozen) { + if (lwb != NULL) { + lwb = zil_lwb_commit(zilog, itx, lwb); + } else if (lrc->lrc_txtype == TX_COMMIT) { + ASSERT3P(lwb, ==, NULL); + zil_commit_waiter_link_nolwb( + itx->itx_private, &nolwb_waiters); + } + } else if (lrc->lrc_txtype == TX_COMMIT) { + ASSERT3B(synced, ==, B_TRUE); + ASSERT3B(frozen, ==, B_FALSE); + + /* + * If this is a commit itx, then there will be a + * thread that is either: already waiting for + * it, or soon will be waiting. + * + * This itx has already been committed to disk + * via spa_sync() so we don't bother committing + * it to an lwb. As a result, we cannot use the + * lwb zio callback to signal the waiter and + * mark it as done, so we must do that here. + */ + zil_commit_waiter_skip(itx->itx_private); + } + list_remove(&zilog->zl_itx_commit_list, itx); - kmem_free(itx, offsetof(itx_t, itx_lr) - + itx->itx_lr.lrc_reclen); - } - DTRACE_PROBE1(zil__cw2, zilog_t *, zilog); - - /* write the last block out */ - if (lwb != NULL && lwb->lwb_zio != NULL) - lwb = zil_lwb_write_start(zilog, lwb, B_TRUE); - - zilog->zl_cur_used = 0; - - /* - * Wait if necessary for the log blocks to be on stable storage. - */ - if (zilog->zl_root_zio) { - error = zio_wait(zilog->zl_root_zio); - zilog->zl_root_zio = NULL; - zil_flush_vdevs(zilog); + zil_itx_destroy(itx); } - if (error || lwb == NULL) - txg_wait_synced(zilog->zl_dmu_pool, 0); + if (lwb == NULL) { + /* + * This indicates zio_alloc_zil() failed to allocate the + * "next" lwb on-disk. When this happens, we must stall + * the ZIL write pipeline; see the comment within + * zil_commit_writer_stall() for more details. + */ + zil_commit_writer_stall(zilog); - mutex_enter(&zilog->zl_lock); + /* + * Additionally, we have to signal and mark the "nolwb" + * waiters as "done" here, since without an lwb, we + * can't do this via zil_lwb_flush_vdevs_done() like + * normal. + */ + zil_commit_waiter_t *zcw; + while (zcw = list_head(&nolwb_waiters)) { + zil_commit_waiter_skip(zcw); + list_remove(&nolwb_waiters, zcw); + } + } else { + ASSERT(list_is_empty(&nolwb_waiters)); + ASSERT3P(lwb, !=, NULL); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_ISSUED); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_DONE); - /* - * Remember the highest committed log sequence number for ztest. - * We only update this value when all the log writes succeeded, - * because ztest wants to ASSERT that it got the whole log chain. - */ - if (error == 0 && lwb != NULL) - zilog->zl_commit_lr_seq = zilog->zl_lr_seq; + /* + * At this point, the ZIL block pointed at by the "lwb" + * variable is in one of the following states: "closed" + * or "open". + * + * If its "closed", then no itxs have been committed to + * it, so there's no point in issuing its zio (i.e. + * it's "empty"). + * + * If its "open" state, then it contains one or more + * itxs that eventually need to be committed to stable + * storage. In this case we intentionally do not issue + * the lwb's zio to disk yet, and instead rely on one of + * the following two mechanisms for issuing the zio: + * + * 1. Ideally, there will be more ZIL activity occuring + * on the system, such that this function will be + * immediately called again (not necessarily by the same + * thread) and this lwb's zio will be issued via + * zil_lwb_commit(). This way, the lwb is guaranteed to + * be "full" when it is issued to disk, and we'll make + * use of the lwb's size the best we can. + * + * 2. If there isn't sufficient ZIL activity occuring on + * the system, such that this lwb's zio isn't issued via + * zil_lwb_commit(), zil_commit_waiter() will issue the + * lwb's zio. If this occurs, the lwb is not guaranteed + * to be "full" by the time its zio is issued, and means + * the size of the lwb was "too large" given the amount + * of ZIL activity occuring on the system at that time. + * + * We do this for a couple of reasons: + * + * 1. To try and reduce the number of IOPs needed to + * write the same number of itxs. If an lwb has space + * available in it's buffer for more itxs, and more itxs + * will be committed relatively soon (relative to the + * latency of performing a write), then it's beneficial + * to wait for these "next" itxs. This way, more itxs + * can be committed to stable storage with fewer writes. + * + * 2. To try and use the largest lwb block size that the + * incoming rate of itxs can support. Again, this is to + * try and pack as many itxs into as few lwbs as + * possible, without significantly impacting the latency + * of each individual itx. + */ + } } /* - * Commit zfs transactions to stable storage. - * If foid is 0 push out all transactions, otherwise push only those - * for that object or might reference that object. + * This function is responsible for ensuring the passed in commit waiter + * (and associated commit itx) is committed to an lwb. If the waiter is + * not already committed to an lwb, all itxs in the zilog's queue of + * itxs will be processed. The assumption is the passed in waiter's + * commit itx will found in the queue just like the other non-commit + * itxs, such that when the entire queue is processed, the waiter will + * have been commited to an lwb. * - * itxs are committed in batches. In a heavily stressed zil there will be - * a commit writer thread who is writing out a bunch of itxs to the log - * for a set of committing threads (cthreads) in the same batch as the writer. - * Those cthreads are all waiting on the same cv for that batch. + * The lwb associated with the passed in waiter is not guaranteed to + * have been issued by the time this function completes. If the lwb is + * not issued, we rely on future calls to zil_commit_writer() to issue + * the lwb, or the timeout mechanism found in zil_commit_waiter(). + */ +static void +zil_commit_writer(zilog_t *zilog, zil_commit_waiter_t *zcw) +{ + ASSERT(!MUTEX_HELD(&zilog->zl_lock)); + ASSERT(spa_writeable(zilog->zl_spa)); + ASSERT0(zilog->zl_suspend); + + mutex_enter(&zilog->zl_writer_lock); + + if (zcw->zcw_lwb != NULL || zcw->zcw_done) { + /* + * It's possible that, while we were waiting to acquire + * the "zl_writer_lock", another thread committed this + * waiter to an lwb. If that occurs, we bail out early, + * without processing any of the zilog's queue of itxs. + * + * On certain workloads and system configurations, the + * "zl_writer_lock" can become highly contended. In an + * attempt to reduce this contention, we immediately drop + * the lock if the waiter has already been processed. + * + * We've measured this optimization to reduce CPU spent + * contending on this lock by up to 5%, using a system + * with 32 CPUs, low latency storage (~50 usec writes), + * and 1024 threads performing sync writes. + */ + goto out; + } + + zil_get_commit_list(zilog); + zil_prune_commit_list(zilog); + zil_process_commit_list(zilog); + +out: + mutex_exit(&zilog->zl_writer_lock); +} + +static void +zil_commit_waiter_timeout(zilog_t *zilog, zil_commit_waiter_t *zcw) +{ + ASSERT(!MUTEX_HELD(&zilog->zl_writer_lock)); + ASSERT(MUTEX_HELD(&zcw->zcw_lock)); + ASSERT3B(zcw->zcw_done, ==, B_FALSE); + + lwb_t *lwb = zcw->zcw_lwb; + ASSERT3P(lwb, !=, NULL); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_CLOSED); + + /* + * If the lwb has already been issued by another thread, we can + * immediately return since there's no work to be done (the + * point of this function is to issue the lwb). Additionally, we + * do this prior to acquiring the zl_writer_lock, to avoid + * acquiring it when it's not necessary to do so. + */ + if (lwb->lwb_state == LWB_STATE_ISSUED || + lwb->lwb_state == LWB_STATE_DONE) + return; + + /* + * In order to call zil_lwb_write_issue() we must hold the + * zilog's "zl_writer_lock". We can't simply acquire that lock, + * since we're already holding the commit waiter's "zcw_lock", + * and those two locks are aquired in the opposite order + * elsewhere. + */ + mutex_exit(&zcw->zcw_lock); + mutex_enter(&zilog->zl_writer_lock); + mutex_enter(&zcw->zcw_lock); + + /* + * Since we just dropped and re-acquired the commit waiter's + * lock, we have to re-check to see if the waiter was marked + * "done" during that process. If the waiter was marked "done", + * the "lwb" pointer is no longer valid (it can be free'd after + * the waiter is marked "done"), so without this check we could + * wind up with a use-after-free error below. + */ + if (zcw->zcw_done) + goto out; + + ASSERT3P(lwb, ==, zcw->zcw_lwb); + + /* + * We've already checked this above, but since we hadn't + * acquired the zilog's zl_writer_lock, we have to perform this + * check a second time while holding the lock. We can't call + * zil_lwb_write_issue() if the lwb had already been issued. + */ + if (lwb->lwb_state == LWB_STATE_ISSUED || + lwb->lwb_state == LWB_STATE_DONE) + goto out; + + ASSERT3S(lwb->lwb_state, ==, LWB_STATE_OPENED); + + /* + * As described in the comments above zil_commit_waiter() and + * zil_process_commit_list(), we need to issue this lwb's zio + * since we've reached the commit waiter's timeout and it still + * hasn't been issued. + */ + lwb_t *nlwb = zil_lwb_write_issue(zilog, lwb); + + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_OPENED); + + /* + * Since the lwb's zio hadn't been issued by the time this thread + * reached its timeout, we reset the zilog's "zl_cur_used" field + * to influence the zil block size selection algorithm. + * + * By having to issue the lwb's zio here, it means the size of the + * lwb was too large, given the incoming throughput of itxs. By + * setting "zl_cur_used" to zero, we communicate this fact to the + * block size selection algorithm, so it can take this informaiton + * into account, and potentially select a smaller size for the + * next lwb block that is allocated. + */ + zilog->zl_cur_used = 0; + + if (nlwb == NULL) { + /* + * When zil_lwb_write_issue() returns NULL, this + * indicates zio_alloc_zil() failed to allocate the + * "next" lwb on-disk. When this occurs, the ZIL write + * pipeline must be stalled; see the comment within the + * zil_commit_writer_stall() function for more details. + * + * We must drop the commit waiter's lock prior to + * calling zil_commit_writer_stall() or else we can wind + * up with the following deadlock: + * + * - This thread is waiting for the txg to sync while + * holding the waiter's lock; txg_wait_synced() is + * used within txg_commit_writer_stall(). + * + * - The txg can't sync because it is waiting for this + * lwb's zio callback to call dmu_tx_commit(). + * + * - The lwb's zio callback can't call dmu_tx_commit() + * because it's blocked trying to acquire the waiter's + * lock, which occurs prior to calling dmu_tx_commit() + */ + mutex_exit(&zcw->zcw_lock); + zil_commit_writer_stall(zilog); + mutex_enter(&zcw->zcw_lock); + } + +out: + mutex_exit(&zilog->zl_writer_lock); + ASSERT(MUTEX_HELD(&zcw->zcw_lock)); +} + +/* + * This function is responsible for performing the following two tasks: * - * There will also be a different and growing batch of threads that are - * waiting to commit (qthreads). When the committing batch completes - * a transition occurs such that the cthreads exit and the qthreads become - * cthreads. One of the new cthreads becomes the writer thread for the - * batch. Any new threads arriving become new qthreads. + * 1. its primary responsibility is to block until the given "commit + * waiter" is considered "done". * - * Only 2 condition variables are needed and there's no transition - * between the two cvs needed. They just flip-flop between qthreads - * and cthreads. + * 2. its secondary responsibility is to issue the zio for the lwb that + * the given "commit waiter" is waiting on, if this function has + * waited "long enough" and the lwb is still in the "open" state. * - * Using this scheme we can efficiently wakeup up only those threads - * that have been committed. + * Given a sufficient amount of itxs being generated and written using + * the ZIL, the lwb's zio will be issued via the zil_lwb_commit() + * function. If this does not occur, this secondary responsibility will + * ensure the lwb is issued even if there is not other synchronous + * activity on the system. + * + * For more details, see zil_process_commit_list(); more specifically, + * the comment at the bottom of that function. + */ +static void +zil_commit_waiter(zilog_t *zilog, zil_commit_waiter_t *zcw) +{ + ASSERT(!MUTEX_HELD(&zilog->zl_lock)); + ASSERT(!MUTEX_HELD(&zilog->zl_writer_lock)); + ASSERT(spa_writeable(zilog->zl_spa)); + ASSERT0(zilog->zl_suspend); + + mutex_enter(&zcw->zcw_lock); + + /* + * The timeout is scaled based on the lwb latency to avoid + * significantly impacting the latency of each individual itx. + * For more details, see the comment at the bottom of the + * zil_process_commit_list() function. + */ + int pct = MAX(zfs_commit_timeout_pct, 1); +#if defined(illumos) || !defined(_KERNEL) + hrtime_t sleep = (zilog->zl_last_lwb_latency * pct) / 100; + hrtime_t wakeup = gethrtime() + sleep; +#else + sbintime_t sleep = nstosbt((zilog->zl_last_lwb_latency * pct) / 100); + sbintime_t wakeup = getsbinuptime() + sleep; +#endif + boolean_t timedout = B_FALSE; + + while (!zcw->zcw_done) { + ASSERT(MUTEX_HELD(&zcw->zcw_lock)); + + lwb_t *lwb = zcw->zcw_lwb; + + /* + * Usually, the waiter will have a non-NULL lwb field here, + * but it's possible for it to be NULL as a result of + * zil_commit() racing with spa_sync(). + * + * When zil_clean() is called, it's possible for the itxg + * list (which may be cleaned via a taskq) to contain + * commit itxs. When this occurs, the commit waiters linked + * off of these commit itxs will not be committed to an + * lwb. Additionally, these commit waiters will not be + * marked done until zil_commit_waiter_skip() is called via + * zil_itxg_clean(). + * + * Thus, it's possible for this commit waiter (i.e. the + * "zcw" variable) to be found in this "in between" state; + * where it's "zcw_lwb" field is NULL, and it hasn't yet + * been skipped, so it's "zcw_done" field is still B_FALSE. + */ + IMPLY(lwb != NULL, lwb->lwb_state != LWB_STATE_CLOSED); + + if (lwb != NULL && lwb->lwb_state == LWB_STATE_OPENED) { + ASSERT3B(timedout, ==, B_FALSE); + + /* + * If the lwb hasn't been issued yet, then we + * need to wait with a timeout, in case this + * function needs to issue the lwb after the + * timeout is reached; responsibility (2) from + * the comment above this function. + */ +#if defined(illumos) || !defined(_KERNEL) + clock_t timeleft = cv_timedwait_hires(&zcw->zcw_cv, + &zcw->zcw_lock, wakeup, USEC2NSEC(1), + CALLOUT_FLAG_ABSOLUTE); + + if (timeleft >= 0 || zcw->zcw_done) + continue; +#else + int wait_err = cv_timedwait_sbt(&zcw->zcw_cv, + &zcw->zcw_lock, wakeup, SBT_1NS, C_ABSOLUTE); + if (wait_err != EWOULDBLOCK || zcw->zcw_done) + continue; +#endif + + timedout = B_TRUE; + zil_commit_waiter_timeout(zilog, zcw); + + if (!zcw->zcw_done) { + /* + * If the commit waiter has already been + * marked "done", it's possible for the + * waiter's lwb structure to have already + * been freed. Thus, we can only reliably + * make these assertions if the waiter + * isn't done. + */ + ASSERT3P(lwb, ==, zcw->zcw_lwb); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_OPENED); + } + } else { + /* + * If the lwb isn't open, then it must have already + * been issued. In that case, there's no need to + * use a timeout when waiting for the lwb to + * complete. + * + * Additionally, if the lwb is NULL, the waiter + * will soon be signalled and marked done via + * zil_clean() and zil_itxg_clean(), so no timeout + * is required. + */ + + IMPLY(lwb != NULL, + lwb->lwb_state == LWB_STATE_ISSUED || + lwb->lwb_state == LWB_STATE_DONE); + cv_wait(&zcw->zcw_cv, &zcw->zcw_lock); + } + } + + mutex_exit(&zcw->zcw_lock); +} + +static zil_commit_waiter_t * +zil_alloc_commit_waiter() +{ + zil_commit_waiter_t *zcw = kmem_cache_alloc(zil_zcw_cache, KM_SLEEP); + + cv_init(&zcw->zcw_cv, NULL, CV_DEFAULT, NULL); + mutex_init(&zcw->zcw_lock, NULL, MUTEX_DEFAULT, NULL); + list_link_init(&zcw->zcw_node); + zcw->zcw_lwb = NULL; + zcw->zcw_done = B_FALSE; + zcw->zcw_zio_error = 0; + + return (zcw); +} + +static void +zil_free_commit_waiter(zil_commit_waiter_t *zcw) +{ + ASSERT(!list_link_active(&zcw->zcw_node)); + ASSERT3P(zcw->zcw_lwb, ==, NULL); + ASSERT3B(zcw->zcw_done, ==, B_TRUE); + mutex_destroy(&zcw->zcw_lock); + cv_destroy(&zcw->zcw_cv); + kmem_cache_free(zil_zcw_cache, zcw); +} + +/* + * This function is used to create a TX_COMMIT itx and assign it. This + * way, it will be linked into the ZIL's list of synchronous itxs, and + * then later committed to an lwb (or skipped) when + * zil_process_commit_list() is called. + */ +static void +zil_commit_itx_assign(zilog_t *zilog, zil_commit_waiter_t *zcw) +{ + dmu_tx_t *tx = dmu_tx_create(zilog->zl_os); + VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); + + itx_t *itx = zil_itx_create(TX_COMMIT, sizeof (lr_t)); + itx->itx_sync = B_TRUE; + itx->itx_private = zcw; + + zil_itx_assign(zilog, itx, tx); + + dmu_tx_commit(tx); +} + +/* + * Commit ZFS Intent Log transactions (itxs) to stable storage. + * + * When writing ZIL transactions to the on-disk representation of the + * ZIL, the itxs are committed to a Log Write Block (lwb). Multiple + * itxs can be committed to a single lwb. Once a lwb is written and + * committed to stable storage (i.e. the lwb is written, and vdevs have + * been flushed), each itx that was committed to that lwb is also + * considered to be committed to stable storage. + * + * When an itx is committed to an lwb, the log record (lr_t) contained + * by the itx is copied into the lwb's zio buffer, and once this buffer + * is written to disk, it becomes an on-disk ZIL block. + * + * As itxs are generated, they're inserted into the ZIL's queue of + * uncommitted itxs. The semantics of zil_commit() are such that it will + * block until all itxs that were in the queue when it was called, are + * committed to stable storage. + * + * If "foid" is zero, this means all "synchronous" and "asynchronous" + * itxs, for all objects in the dataset, will be committed to stable + * storage prior to zil_commit() returning. If "foid" is non-zero, all + * "synchronous" itxs for all objects, but only "asynchronous" itxs + * that correspond to the foid passed in, will be committed to stable + * storage prior to zil_commit() returning. + * + * Generally speaking, when zil_commit() is called, the consumer doesn't + * actually care about _all_ of the uncommitted itxs. Instead, they're + * simply trying to waiting for a specific itx to be committed to disk, + * but the interface(s) for interacting with the ZIL don't allow such + * fine-grained communication. A better interface would allow a consumer + * to create and assign an itx, and then pass a reference to this itx to + * zil_commit(); such that zil_commit() would return as soon as that + * specific itx was committed to disk (instead of waiting for _all_ + * itxs to be committed). + * + * When a thread calls zil_commit() a special "commit itx" will be + * generated, along with a corresponding "waiter" for this commit itx. + * zil_commit() will wait on this waiter's CV, such that when the waiter + * is marked done, and signalled, zil_commit() will return. + * + * This commit itx is inserted into the queue of uncommitted itxs. This + * provides an easy mechanism for determining which itxs were in the + * queue prior to zil_commit() having been called, and which itxs were + * added after zil_commit() was called. + * + * The commit it is special; it doesn't have any on-disk representation. + * When a commit itx is "committed" to an lwb, the waiter associated + * with it is linked onto the lwb's list of waiters. Then, when that lwb + * completes, each waiter on the lwb's list is marked done and signalled + * -- allowing the thread waiting on the waiter to return from zil_commit(). + * + * It's important to point out a few critical factors that allow us + * to make use of the commit itxs, commit waiters, per-lwb lists of + * commit waiters, and zio completion callbacks like we're doing: + * + * 1. The list of waiters for each lwb is traversed, and each commit + * waiter is marked "done" and signalled, in the zio completion + * callback of the lwb's zio[*]. + * + * * Actually, the waiters are signalled in the zio completion + * callback of the root zio for the DKIOCFLUSHWRITECACHE commands + * that are sent to the vdevs upon completion of the lwb zio. + * + * 2. When the itxs are inserted into the ZIL's queue of uncommitted + * itxs, the order in which they are inserted is preserved[*]; as + * itxs are added to the queue, they are added to the tail of + * in-memory linked lists. + * + * When committing the itxs to lwbs (to be written to disk), they + * are committed in the same order in which the itxs were added to + * the uncommitted queue's linked list(s); i.e. the linked list of + * itxs to commit is traversed from head to tail, and each itx is + * committed to an lwb in that order. + * + * * To clarify: + * + * - the order of "sync" itxs is preserved w.r.t. other + * "sync" itxs, regardless of the corresponding objects. + * - the order of "async" itxs is preserved w.r.t. other + * "async" itxs corresponding to the same object. + * - the order of "async" itxs is *not* preserved w.r.t. other + * "async" itxs corresponding to different objects. + * - the order of "sync" itxs w.r.t. "async" itxs (or vice + * versa) is *not* preserved, even for itxs that correspond + * to the same object. + * + * For more details, see: zil_itx_assign(), zil_async_to_sync(), + * zil_get_commit_list(), and zil_process_commit_list(). + * + * 3. The lwbs represent a linked list of blocks on disk. Thus, any + * lwb cannot be considered committed to stable storage, until its + * "previous" lwb is also committed to stable storage. This fact, + * coupled with the fact described above, means that itxs are + * committed in (roughly) the order in which they were generated. + * This is essential because itxs are dependent on prior itxs. + * Thus, we *must not* deem an itx as being committed to stable + * storage, until *all* prior itxs have also been committed to + * stable storage. + * + * To enforce this ordering of lwb zio's, while still leveraging as + * much of the underlying storage performance as possible, we rely + * on two fundamental concepts: + * + * 1. The creation and issuance of lwb zio's is protected by + * the zilog's "zl_writer_lock", which ensures only a single + * thread is creating and/or issuing lwb's at a time + * 2. The "previous" lwb is a child of the "current" lwb + * (leveraging the zio parent-child depenency graph) + * + * By relying on this parent-child zio relationship, we can have + * many lwb zio's concurrently issued to the underlying storage, + * but the order in which they complete will be the same order in + * which they were created. */ void zil_commit(zilog_t *zilog, uint64_t foid) { - uint64_t mybatch; + /* + * We should never attempt to call zil_commit on a snapshot for + * a couple of reasons: + * + * 1. A snapshot may never be modified, thus it cannot have any + * in-flight itxs that would have modified the dataset. + * + * 2. By design, when zil_commit() is called, a commit itx will + * be assigned to this zilog; as a result, the zilog will be + * dirtied. We must not dirty the zilog of a snapshot; there's + * checks in the code that enforce this invariant, and will + * cause a panic if it's not upheld. + */ + ASSERT3B(dmu_objset_is_snapshot(zilog->zl_os), ==, B_FALSE); if (zilog->zl_sync == ZFS_SYNC_DISABLED) return; - /* move the async itxs for the foid to the sync queues */ - zil_async_to_sync(zilog, foid); - - mutex_enter(&zilog->zl_lock); - mybatch = zilog->zl_next_batch; - while (zilog->zl_writer) { - cv_wait(&zilog->zl_cv_batch[mybatch & 1], &zilog->zl_lock); - if (mybatch <= zilog->zl_com_batch) { - mutex_exit(&zilog->zl_lock); - return; - } + if (!spa_writeable(zilog->zl_spa)) { + /* + * If the SPA is not writable, there should never be any + * pending itxs waiting to be committed to disk. If that + * weren't true, we'd skip writing those itxs out, and + * would break the sematics of zil_commit(); thus, we're + * verifying that truth before we return to the caller. + */ + ASSERT(list_is_empty(&zilog->zl_lwb_list)); + ASSERT3P(zilog->zl_last_lwb_opened, ==, NULL); + for (int i = 0; i < TXG_SIZE; i++) + ASSERT3P(zilog->zl_itxg[i].itxg_itxs, ==, NULL); + return; } - zilog->zl_next_batch++; - zilog->zl_writer = B_TRUE; - zil_commit_writer(zilog); - zilog->zl_com_batch = mybatch; - zilog->zl_writer = B_FALSE; - mutex_exit(&zilog->zl_lock); + /* + * If the ZIL is suspended, we don't want to dirty it by calling + * zil_commit_itx_assign() below, nor can we write out + * lwbs like would be done in zil_commit_write(). Thus, we + * simply rely on txg_wait_synced() to maintain the necessary + * semantics, and avoid calling those functions altogether. + */ + if (zilog->zl_suspend > 0) { + txg_wait_synced(zilog->zl_dmu_pool, 0); + return; + } - /* wake up one thread to become the next writer */ - cv_signal(&zilog->zl_cv_batch[(mybatch+1) & 1]); + /* + * Move the "async" itxs for the specified foid to the "sync" + * queues, such that they will be later committed (or skipped) + * to an lwb when zil_process_commit_list() is called. + * + * Since these "async" itxs must be committed prior to this + * call to zil_commit returning, we must perform this operation + * before we call zil_commit_itx_assign(). + */ + zil_async_to_sync(zilog, foid); - /* wake up all threads waiting for this batch to be committed */ - cv_broadcast(&zilog->zl_cv_batch[mybatch & 1]); + /* + * We allocate a new "waiter" structure which will initially be + * linked to the commit itx using the itx's "itx_private" field. + * Since the commit itx doesn't represent any on-disk state, + * when it's committed to an lwb, rather than copying the its + * lr_t into the lwb's buffer, the commit itx's "waiter" will be + * added to the lwb's list of waiters. Then, when the lwb is + * committed to stable storage, each waiter in the lwb's list of + * waiters will be marked "done", and signalled. + * + * We must create the waiter and assign the commit itx prior to + * calling zil_commit_writer(), or else our specific commit itx + * is not guaranteed to be committed to an lwb prior to calling + * zil_commit_waiter(). + */ + zil_commit_waiter_t *zcw = zil_alloc_commit_waiter(); + zil_commit_itx_assign(zilog, zcw); + + zil_commit_writer(zilog, zcw); + zil_commit_waiter(zilog, zcw); + + if (zcw->zcw_zio_error != 0) { + /* + * If there was an error writing out the ZIL blocks that + * this thread is waiting on, then we fallback to + * relying on spa_sync() to write out the data this + * thread is waiting on. Obviously this has performance + * implications, but the expectation is for this to be + * an exceptional case, and shouldn't occur often. + */ + DTRACE_PROBE2(zil__commit__io__error, + zilog_t *, zilog, zil_commit_waiter_t *, zcw); + txg_wait_synced(zilog->zl_dmu_pool, 0); + } + + zil_free_commit_waiter(zcw); } /* @@ -1719,8 +2694,8 @@ zil_sync(zilog_t *zilog, dmu_tx_t *tx) if (lwb->lwb_buf != NULL || lwb->lwb_max_txg > txg) break; list_remove(&zilog->zl_lwb_list, lwb); - zio_free_zil(spa, txg, &lwb->lwb_blk); - kmem_cache_free(zil_lwb_cache, lwb); + zio_free(spa, txg, &lwb->lwb_blk); + zil_free_lwb(zilog, lwb); /* * If we don't have anything left in the lwb list then @@ -1734,16 +2709,43 @@ zil_sync(zilog_t *zilog, dmu_tx_t *tx) mutex_exit(&zilog->zl_lock); } +/* ARGSUSED */ +static int +zil_lwb_cons(void *vbuf, void *unused, int kmflag) +{ + lwb_t *lwb = vbuf; + list_create(&lwb->lwb_waiters, sizeof (zil_commit_waiter_t), + offsetof(zil_commit_waiter_t, zcw_node)); + avl_create(&lwb->lwb_vdev_tree, zil_lwb_vdev_compare, + sizeof (zil_vdev_node_t), offsetof(zil_vdev_node_t, zv_node)); + mutex_init(&lwb->lwb_vdev_lock, NULL, MUTEX_DEFAULT, NULL); + return (0); +} + +/* ARGSUSED */ +static void +zil_lwb_dest(void *vbuf, void *unused) +{ + lwb_t *lwb = vbuf; + mutex_destroy(&lwb->lwb_vdev_lock); + avl_destroy(&lwb->lwb_vdev_tree); + list_destroy(&lwb->lwb_waiters); +} + void zil_init(void) { zil_lwb_cache = kmem_cache_create("zil_lwb_cache", - sizeof (struct lwb), 0, NULL, NULL, NULL, NULL, NULL, 0); + sizeof (lwb_t), 0, zil_lwb_cons, zil_lwb_dest, NULL, NULL, NULL, 0); + + zil_zcw_cache = kmem_cache_create("zil_zcw_cache", + sizeof (zil_commit_waiter_t), 0, NULL, NULL, NULL, NULL, NULL, 0); } void zil_fini(void) { + kmem_cache_destroy(zil_zcw_cache); kmem_cache_destroy(zil_lwb_cache); } @@ -1773,9 +2775,12 @@ zil_alloc(objset_t *os, zil_header_t *zh_phys) zilog->zl_destroy_txg = TXG_INITIAL - 1; zilog->zl_logbias = dmu_objset_logbias(os); zilog->zl_sync = dmu_objset_syncprop(os); - zilog->zl_next_batch = 1; + zilog->zl_dirty_max_txg = 0; + zilog->zl_last_lwb_opened = NULL; + zilog->zl_last_lwb_latency = 0; mutex_init(&zilog->zl_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&zilog->zl_writer_lock, NULL, MUTEX_DEFAULT, NULL); for (int i = 0; i < TXG_SIZE; i++) { mutex_init(&zilog->zl_itxg[i].itxg_lock, NULL, @@ -1788,15 +2793,7 @@ zil_alloc(objset_t *os, zil_header_t *zh_phys) list_create(&zilog->zl_itx_commit_list, sizeof (itx_t), offsetof(itx_t, itx_node)); - mutex_init(&zilog->zl_vdev_lock, NULL, MUTEX_DEFAULT, NULL); - - avl_create(&zilog->zl_vdev_tree, zil_vdev_compare, - sizeof (zil_vdev_node_t), offsetof(zil_vdev_node_t, zv_node)); - - cv_init(&zilog->zl_cv_writer, NULL, CV_DEFAULT, NULL); cv_init(&zilog->zl_cv_suspend, NULL, CV_DEFAULT, NULL); - cv_init(&zilog->zl_cv_batch[0], NULL, CV_DEFAULT, NULL); - cv_init(&zilog->zl_cv_batch[1], NULL, CV_DEFAULT, NULL); return (zilog); } @@ -1812,9 +2809,6 @@ zil_free(zilog_t *zilog) ASSERT(list_is_empty(&zilog->zl_lwb_list)); list_destroy(&zilog->zl_lwb_list); - avl_destroy(&zilog->zl_vdev_tree); - mutex_destroy(&zilog->zl_vdev_lock); - ASSERT(list_is_empty(&zilog->zl_itx_commit_list)); list_destroy(&zilog->zl_itx_commit_list); @@ -1831,12 +2825,10 @@ zil_free(zilog_t *zilog) mutex_destroy(&zilog->zl_itxg[i].itxg_lock); } + mutex_destroy(&zilog->zl_writer_lock); mutex_destroy(&zilog->zl_lock); - cv_destroy(&zilog->zl_cv_writer); cv_destroy(&zilog->zl_cv_suspend); - cv_destroy(&zilog->zl_cv_batch[0]); - cv_destroy(&zilog->zl_cv_batch[1]); kmem_free(zilog, sizeof (zilog_t)); } @@ -1849,7 +2841,8 @@ zil_open(objset_t *os, zil_get_data_t *get_data) { zilog_t *zilog = dmu_objset_zil(os); - ASSERT(zilog->zl_get_data == NULL); + ASSERT3P(zilog->zl_get_data, ==, NULL); + ASSERT3P(zilog->zl_last_lwb_opened, ==, NULL); ASSERT(list_is_empty(&zilog->zl_lwb_list)); zilog->zl_get_data = get_data; @@ -1864,22 +2857,30 @@ void zil_close(zilog_t *zilog) { lwb_t *lwb; - uint64_t txg = 0; + uint64_t txg; - zil_commit(zilog, 0); /* commit all itx */ + if (!dmu_objset_is_snapshot(zilog->zl_os)) { + zil_commit(zilog, 0); + } else { + ASSERT3P(list_tail(&zilog->zl_lwb_list), ==, NULL); + ASSERT0(zilog->zl_dirty_max_txg); + ASSERT3B(zilog_is_dirty(zilog), ==, B_FALSE); + } - /* - * The lwb_max_txg for the stubby lwb will reflect the last activity - * for the zil. After a txg_wait_synced() on the txg we know all the - * callbacks have occurred that may clean the zil. Only then can we - * destroy the zl_clean_taskq. - */ mutex_enter(&zilog->zl_lock); lwb = list_tail(&zilog->zl_lwb_list); - if (lwb != NULL) - txg = lwb->lwb_max_txg; + if (lwb == NULL) + txg = zilog->zl_dirty_max_txg; + else + txg = MAX(zilog->zl_dirty_max_txg, lwb->lwb_max_txg); mutex_exit(&zilog->zl_lock); - if (txg) + + /* + * We need to use txg_wait_synced() to wait long enough for the + * ZIL to be clean, and to wait for all pending lwbs to be + * written out. + */ + if (txg != 0) txg_wait_synced(zilog->zl_dmu_pool, txg); if (zilog_is_dirty(zilog)) @@ -1889,15 +2890,16 @@ zil_close(zilog_t *zilog) zilog->zl_get_data = NULL; /* - * We should have only one LWB left on the list; remove it now. + * We should have only one lwb left on the list; remove it now. */ mutex_enter(&zilog->zl_lock); lwb = list_head(&zilog->zl_lwb_list); if (lwb != NULL) { - ASSERT(lwb == list_tail(&zilog->zl_lwb_list)); + ASSERT3P(lwb, ==, list_tail(&zilog->zl_lwb_list)); + ASSERT3S(lwb->lwb_state, !=, LWB_STATE_ISSUED); list_remove(&zilog->zl_lwb_list, lwb); zio_buf_free(lwb->lwb_buf, lwb->lwb_sz); - kmem_cache_free(zil_lwb_cache, lwb); + zil_free_lwb(zilog, lwb); } mutex_exit(&zilog->zl_lock); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 8a5b50fd6f2f..afbbae322b2e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -467,7 +467,7 @@ zio_add_child(zio_t *pio, zio_t *cio) * Vdev I/Os can only have vdev children. * The following ASSERT captures all of these constraints. */ - ASSERT(cio->io_child_type <= pio->io_child_type); + ASSERT3S(cio->io_child_type, <=, pio->io_child_type); zl->zl_parent = pio; zl->zl_child = cio; @@ -1194,9 +1194,9 @@ zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, uint64_t offset, uint64_t size) void zio_shrink(zio_t *zio, uint64_t size) { - ASSERT(zio->io_executor == NULL); - ASSERT(zio->io_orig_size == zio->io_size); - ASSERT(size <= zio->io_size); + ASSERT3P(zio->io_executor, ==, NULL); + ASSERT3P(zio->io_orig_size, ==, zio->io_size); + ASSERT3U(size, <=, zio->io_size); /* * We don't shrink for raidz because of problems with the @@ -1713,8 +1713,8 @@ zio_wait(zio_t *zio) { int error; - ASSERT(zio->io_stage == ZIO_STAGE_OPEN); - ASSERT(zio->io_executor == NULL); + ASSERT3P(zio->io_stage, ==, ZIO_STAGE_OPEN); + ASSERT3P(zio->io_executor, ==, NULL); zio->io_waiter = curthread; ASSERT0(zio->io_queued_timestamp); @@ -1736,7 +1736,7 @@ zio_wait(zio_t *zio) void zio_nowait(zio_t *zio) { - ASSERT(zio->io_executor == NULL); + ASSERT3P(zio->io_executor, ==, NULL); if (zio->io_child_type == ZIO_CHILD_LOGICAL && zio_unique_parent(zio) == NULL) { @@ -1757,7 +1757,7 @@ zio_nowait(zio_t *zio) /* * ========================================================================== - * Reexecute or suspend/resume failed I/O + * Reexecute, cancel, or suspend/resume failed I/O * ========================================================================== */ @@ -1814,6 +1814,20 @@ zio_reexecute(zio_t *pio) } } +void +zio_cancel(zio_t *zio) +{ + /* + * Disallow cancellation of a zio that's already been issued. + */ + VERIFY3P(zio->io_executor, ==, NULL); + + zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; + zio->io_done = NULL; + + zio_nowait(zio); +} + void zio_suspend(spa_t *spa, zio_t *zio) { @@ -3047,6 +3061,9 @@ zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, blkptr_t *old_bp, BP_SET_LEVEL(new_bp, 0); BP_SET_DEDUP(new_bp, 0); BP_SET_BYTEORDER(new_bp, ZFS_HOST_BYTEORDER); + } else { + zfs_dbgmsg("%s: zil block allocation failure: " + "size %llu, error %d", spa_name(spa), size, error); } return (error); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 95908a617c45..fe1c5f84f645 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -249,7 +250,8 @@ static void zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, extern int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *); static int zvol_remove_zv(zvol_state_t *); -static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio); +static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, + struct lwb *lwb, zio_t *zio); static int zvol_dumpify(zvol_state_t *zv); static int zvol_dump_fini(zvol_state_t *zv); static int zvol_dump_init(zvol_state_t *zv, boolean_t resize); @@ -1324,7 +1326,7 @@ zvol_get_done(zgd_t *zgd, int error) zfs_range_unlock(zgd->zgd_rl); if (error == 0 && zgd->zgd_bp) - zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); + zil_lwb_add_block(zgd->zgd_lwb, zgd->zgd_bp); kmem_free(zgd, sizeof (zgd_t)); } @@ -1333,7 +1335,7 @@ zvol_get_done(zgd_t *zgd, int error) * Get data to generate a TX_WRITE intent log record. */ static int -zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) +zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio) { zvol_state_t *zv = arg; objset_t *os = zv->zv_objset; @@ -1344,12 +1346,12 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) zgd_t *zgd; int error; - ASSERT(zio != NULL); - ASSERT(size != 0); + ASSERT3P(lwb, !=, NULL); + ASSERT3P(zio, !=, NULL); + ASSERT3U(size, !=, 0); zgd = kmem_zalloc(sizeof (zgd_t), KM_SLEEP); - zgd->zgd_zilog = zv->zv_zilog; - zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_READER); + zgd->zgd_lwb = lwb; /* * Write records come in two flavors: immediate and indirect. @@ -1358,12 +1360,22 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) * sync the data and get a pointer to it (indirect) so that * we don't have to write the data twice. */ - if (buf != NULL) { /* immediate write */ + if (buf != NULL) { /* immediate write */ + zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, + RL_READER); error = dmu_read(os, object, offset, size, buf, DMU_READ_NO_PREFETCH); - } else { + } else { /* indirect write */ + /* + * Have to lock the whole block to ensure when it's written out + * and its checksum is being calculated that no one can change + * the data. Contrarily to zfs_get_data we need not re-check + * blocksize after we get the lock because it cannot be changed. + */ size = zv->zv_volblocksize; offset = P2ALIGN(offset, size); + zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, + RL_READER); error = dmu_buf_hold(os, object, offset, zgd, &db, DMU_READ_NO_PREFETCH); if (error == 0) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h b/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h index 796454f9750d..42e4d12029c7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h @@ -26,7 +26,7 @@ */ /* - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, 2017 by Delphix. All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. */ @@ -107,17 +107,20 @@ extern void assfail3(const char *, uintmax_t, const char *, uintmax_t, __FILE__, __LINE__); \ _NOTE(CONSTCOND) } while (0) +#define VERIFY3B(x, y, z) VERIFY3_IMPL(x, y, z, boolean_t) #define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t) #define VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t) #define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t) #define VERIFY0(x) VERIFY3_IMPL(x, ==, 0, uintmax_t) #ifdef DEBUG +#define ASSERT3B(x, y, z) VERIFY3_IMPL(x, y, z, boolean_t) #define ASSERT3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t) #define ASSERT3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t) #define ASSERT3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t) #define ASSERT0(x) VERIFY3_IMPL(x, ==, 0, uintmax_t) #else +#define ASSERT3B(x, y, z) ((void)0) #define ASSERT3S(x, y, z) ((void)0) #define ASSERT3U(x, y, z) ((void)0) #define ASSERT3P(x, y, z) ((void)0) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h index 676e5ca85729..bd5e024444e4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012, Martin Matuska . All rights reserved. @@ -256,12 +256,18 @@ typedef int (*zprop_func)(int, void *); */ #define ZPOOL_ROOTFS_PROPS "root-props-nvl" +/* + * Length of 'written@' and 'written#' + */ +#define ZFS_WRITTEN_PROP_PREFIX_LEN 8 + /* * Dataset property functions shared between libzfs and kernel. */ const char *zfs_prop_default_string(zfs_prop_t); uint64_t zfs_prop_default_numeric(zfs_prop_t); boolean_t zfs_prop_readonly(zfs_prop_t); +boolean_t zfs_prop_visible(zfs_prop_t prop); boolean_t zfs_prop_inheritable(zfs_prop_t); boolean_t zfs_prop_setonce(zfs_prop_t); const char *zfs_prop_to_name(zfs_prop_t); @@ -905,7 +911,10 @@ typedef enum zfs_ioc { ZFS_IOC_BOOKMARK, ZFS_IOC_GET_BOOKMARKS, ZFS_IOC_DESTROY_BOOKMARKS, +#ifdef __FreeBSD__ ZFS_IOC_NEXTBOOT, +#endif + ZFS_IOC_CHANNEL_PROGRAM, ZFS_IOC_LAST } zfs_ioc_t; @@ -950,6 +959,7 @@ typedef enum { #define ZPOOL_HIST_OUTPUT_NVL "out_nvl" #define ZPOOL_HIST_DSNAME "dsname" #define ZPOOL_HIST_DSID "dsid" +#define ZPOOL_HIST_ERRNO "errno" /* * Flags for ZFS_IOC_VDEV_SET_STATE @@ -969,6 +979,24 @@ typedef enum { #define ZFS_IMPORT_MISSING_LOG 0x4 #define ZFS_IMPORT_ONLY 0x8 +/* + * Channel program argument/return nvlist keys and defaults. + */ +#define ZCP_ARG_PROGRAM "program" +#define ZCP_ARG_ARGLIST "arg" +#define ZCP_ARG_INSTRLIMIT "instrlimit" +#define ZCP_ARG_MEMLIMIT "memlimit" + +#define ZCP_ARG_CLIARGV "argv" + +#define ZCP_RET_ERROR "error" +#define ZCP_RET_RETURN "return" + +#define ZCP_DEFAULT_INSTRLIMIT (10 * 1000 * 1000) +#define ZCP_MAX_INSTRLIMIT (10 * ZCP_DEFAULT_INSTRLIMIT) +#define ZCP_DEFAULT_MEMLIMIT (10 * 1024 * 1024) +#define ZCP_MAX_MEMLIMIT (10 * ZCP_DEFAULT_MEMLIMIT) + /* * Sysevent payload members. ZFS will generate the following sysevents with the * given payloads: diff --git a/sys/cddl/dev/dtmalloc/dtmalloc.c b/sys/cddl/dev/dtmalloc/dtmalloc.c index 81ff43f92131..017d1350b48d 100644 --- a/sys/cddl/dev/dtmalloc/dtmalloc.c +++ b/sys/cddl/dev/dtmalloc/dtmalloc.c @@ -60,16 +60,16 @@ static dtrace_pattr_t dtmalloc_attr = { }; static dtrace_pops_t dtmalloc_pops = { - dtmalloc_provide, - NULL, - dtmalloc_enable, - dtmalloc_disable, - NULL, - NULL, - dtmalloc_getargdesc, - NULL, - NULL, - dtmalloc_destroy + .dtps_provide = dtmalloc_provide, + .dtps_provide_module = NULL, + .dtps_enable = dtmalloc_enable, + .dtps_disable = dtmalloc_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = dtmalloc_getargdesc, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = dtmalloc_destroy }; static struct cdev *dtmalloc_cdev; diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c index 7eb7ef15c190..df543df4cbdc 100644 --- a/sys/cddl/dev/fbt/fbt.c +++ b/sys/cddl/dev/fbt/fbt.c @@ -95,16 +95,16 @@ static dtrace_pattr_t fbt_attr = { }; static dtrace_pops_t fbt_pops = { - NULL, - fbt_provide_module, - fbt_enable, - fbt_disable, - fbt_suspend, - fbt_resume, - fbt_getargdesc, - NULL, - NULL, - fbt_destroy + .dtps_provide = NULL, + .dtps_provide_module = fbt_provide_module, + .dtps_enable = fbt_enable, + .dtps_disable = fbt_disable, + .dtps_suspend = fbt_suspend, + .dtps_resume = fbt_resume, + .dtps_getargdesc = fbt_getargdesc, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = fbt_destroy }; static struct cdev *fbt_cdev; diff --git a/sys/cddl/dev/profile/profile.c b/sys/cddl/dev/profile/profile.c index c37d4846945b..11697cc259a2 100644 --- a/sys/cddl/dev/profile/profile.c +++ b/sys/cddl/dev/profile/profile.c @@ -221,16 +221,16 @@ static dtrace_pattr_t profile_attr = { }; static dtrace_pops_t profile_pops = { - profile_provide, - NULL, - profile_enable, - profile_disable, - NULL, - NULL, - NULL, - NULL, - NULL, - profile_destroy + .dtps_provide = profile_provide, + .dtps_provide_module = NULL, + .dtps_enable = profile_enable, + .dtps_disable = profile_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = NULL, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = profile_destroy }; static struct cdev *profile_cdev; diff --git a/sys/cddl/dev/prototype.c b/sys/cddl/dev/prototype.c index 1f7f8b5f0c2d..6e31f19d5ce6 100644 --- a/sys/cddl/dev/prototype.c +++ b/sys/cddl/dev/prototype.c @@ -39,16 +39,16 @@ static dtrace_pattr_t prototype_attr = { }; static dtrace_pops_t prototype_pops = { - prototype_provide, - NULL, - prototype_enable, - prototype_disable, - NULL, - NULL, - prototype_getargdesc, - NULL, - NULL, - prototype_destroy + .dtps_provide = prototype_provide, + .dtps_provide_module = NULL, + .dtps_enable = prototype_enable, + .dtps_disable = prototype_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = prototype_getargdesc, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = prototype_destroy }; static struct cdev *prototype_cdev; diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c index cef816fc4b5b..e9d01184997e 100644 --- a/sys/cddl/dev/sdt/sdt.c +++ b/sys/cddl/dev/sdt/sdt.c @@ -76,6 +76,8 @@ static void sdt_kld_unload_try(void *, struct linker_file *, int *); static MALLOC_DEFINE(M_SDT, "SDT", "DTrace SDT providers"); +static int sdt_probes_enabled_count; + static dtrace_pattr_t sdt_attr = { { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, @@ -85,16 +87,16 @@ static dtrace_pattr_t sdt_attr = { }; static dtrace_pops_t sdt_pops = { - sdt_provide_probes, - NULL, - sdt_enable, - sdt_disable, - NULL, - NULL, - sdt_getargdesc, - NULL, - NULL, - sdt_destroy, + .dtps_provide = sdt_provide_probes, + .dtps_provide_module = NULL, + .dtps_enable = sdt_enable, + .dtps_disable = sdt_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = sdt_getargdesc, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = sdt_destroy, }; static TAILQ_HEAD(, sdt_provider) sdt_prov_list; @@ -208,6 +210,9 @@ sdt_enable(void *arg __unused, dtrace_id_t id, void *parg) probe->sdtp_lf->nenabled++; if (strcmp(probe->prov->name, "lockstat") == 0) lockstat_enabled++; + sdt_probes_enabled_count++; + if (sdt_probes_enabled_count == 1) + sdt_probes_enabled = true; } static void @@ -217,6 +222,9 @@ sdt_disable(void *arg __unused, dtrace_id_t id, void *parg) KASSERT(probe->sdtp_lf->nenabled > 0, ("no probes enabled")); + sdt_probes_enabled_count--; + if (sdt_probes_enabled_count == 0) + sdt_probes_enabled = false; if (strcmp(probe->prov->name, "lockstat") == 0) lockstat_enabled--; probe->id = 0; diff --git a/sys/cddl/dev/systrace/systrace.c b/sys/cddl/dev/systrace/systrace.c index 014a0078197b..02b089b42526 100644 --- a/sys/cddl/dev/systrace/systrace.c +++ b/sys/cddl/dev/systrace/systrace.c @@ -160,16 +160,16 @@ static dtrace_pattr_t systrace_attr = { }; static dtrace_pops_t systrace_pops = { - systrace_provide, - NULL, - systrace_enable, - systrace_disable, - NULL, - NULL, - systrace_getargdesc, - systrace_getargval, - NULL, - systrace_destroy + .dtps_provide = systrace_provide, + .dtps_provide_module = NULL, + .dtps_enable = systrace_enable, + .dtps_disable = systrace_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = systrace_getargdesc, + .dtps_getargval = systrace_getargval, + .dtps_usermode = NULL, + .dtps_destroy = systrace_destroy }; static dtrace_provider_id_t systrace_id; diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 3f57da40d68f..0d15365180b0 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -73,9 +73,7 @@ __FBSDID("$FreeBSD$"); MAPPING(CLOUDABI_RIGHT_MEM_MAP, CAP_MMAP) \ MAPPING(CLOUDABI_RIGHT_MEM_MAP_EXEC, CAP_MMAP_X) \ MAPPING(CLOUDABI_RIGHT_POLL_FD_READWRITE, CAP_EVENT) \ - MAPPING(CLOUDABI_RIGHT_POLL_MODIFY, CAP_KQUEUE_CHANGE) \ MAPPING(CLOUDABI_RIGHT_POLL_PROC_TERMINATE, CAP_EVENT) \ - MAPPING(CLOUDABI_RIGHT_POLL_WAIT, CAP_KQUEUE_EVENT) \ MAPPING(CLOUDABI_RIGHT_PROC_EXEC, CAP_FEXECVE) \ MAPPING(CLOUDABI_RIGHT_SOCK_SHUTDOWN, CAP_SHUTDOWN) \ @@ -93,9 +91,6 @@ cloudabi_sys_fd_create1(struct thread *td, struct filecaps fcaps = {}; switch (uap->type) { - case CLOUDABI_FILETYPE_POLL: - cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_KQUEUE); - return (kern_kqueue(td, 0, &fcaps)); case CLOUDABI_FILETYPE_SHARED_MEMORY: cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_MMAP_RWX); @@ -201,8 +196,6 @@ cloudabi_convert_filetype(const struct file *fp) switch (fp->f_type) { case DTYPE_FIFO: return (CLOUDABI_FILETYPE_SOCKET_STREAM); - case DTYPE_KQUEUE: - return (CLOUDABI_FILETYPE_POLL); case DTYPE_PIPE: return (CLOUDABI_FILETYPE_SOCKET_STREAM); case DTYPE_PROCDESC: @@ -316,10 +309,6 @@ cloudabi_remove_conflicting_rights(cloudabi_filetype_t filetype, CLOUDABI_RIGHT_POLL_FD_READWRITE | CLOUDABI_RIGHT_PROC_EXEC; break; - case CLOUDABI_FILETYPE_POLL: - *base &= ~CLOUDABI_RIGHT_FILE_ADVISE; - *inheriting = 0; - break; case CLOUDABI_FILETYPE_PROCESS: *base &= ~(CLOUDABI_RIGHT_FILE_ADVISE | CLOUDABI_RIGHT_POLL_FD_READWRITE); diff --git a/sys/compat/cloudabi32/cloudabi32_poll.c b/sys/compat/cloudabi32/cloudabi32_poll.c index dfffdc6c97e3..9bdd9ecb86a7 100644 --- a/sys/compat/cloudabi32/cloudabi32_poll.c +++ b/sys/compat/cloudabi32/cloudabi32_poll.c @@ -79,7 +79,6 @@ convert_signal(int sig) struct cloudabi32_kevent_args { const cloudabi32_subscription_t *in; cloudabi32_event_t *out; - bool once; }; /* Converts CloudABI's subscription objects to FreeBSD's struct kevent. */ @@ -124,9 +123,7 @@ cloudabi32_kevent_copyin(void *arg, struct kevent *kevp, int count) case CLOUDABI_EVENTTYPE_FD_READ: kevp->filter = EVFILT_READ; kevp->ident = sub.fd_readwrite.fd; - if ((sub.fd_readwrite.flags & - CLOUDABI_SUBSCRIPTION_FD_READWRITE_POLL) != 0) - kevp->fflags = NOTE_FILE_POLL; + kevp->fflags = NOTE_FILE_POLL; break; case CLOUDABI_EVENTTYPE_FD_WRITE: kevp->filter = EVFILT_WRITE; @@ -138,24 +135,7 @@ cloudabi32_kevent_copyin(void *arg, struct kevent *kevp, int count) kevp->fflags = NOTE_EXIT; break; } - if (args->once) { - /* Ignore flags. Simply use oneshot mode. */ - kevp->flags = EV_ADD | EV_ONESHOT; - } else { - /* Translate flags. */ - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ADD) != 0) - kevp->flags |= EV_ADD; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_CLEAR) != 0) - kevp->flags |= EV_CLEAR; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_DELETE) != 0) - kevp->flags |= EV_DELETE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_DISABLE) != 0) - kevp->flags |= EV_DISABLE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ENABLE) != 0) - kevp->flags |= EV_ENABLE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ONESHOT) != 0) - kevp->flags |= EV_ONESHOT; - } + kevp->flags = EV_ADD | EV_ONESHOT; ++kevp; } return (0); @@ -238,7 +218,6 @@ cloudabi32_sys_poll(struct thread *td, struct cloudabi32_sys_poll_args *uap) struct cloudabi32_kevent_args args = { .in = uap->in, .out = uap->out, - .once = true, }; struct kevent_copyops copyops = { .k_copyin = cloudabi32_kevent_copyin, @@ -369,40 +348,3 @@ cloudabi32_sys_poll(struct thread *td, struct cloudabi32_sys_poll_args *uap) return (kern_kevent_anonymous(td, uap->nsubscriptions, ©ops)); } - -int -cloudabi32_sys_poll_fd(struct thread *td, - struct cloudabi32_sys_poll_fd_args *uap) -{ - struct cloudabi32_kevent_args args = { - .in = uap->in, - .out = uap->out, - .once = false, - }; - struct kevent_copyops copyops = { - .k_copyin = cloudabi32_kevent_copyin, - .k_copyout = cloudabi32_kevent_copyout, - .arg = &args, - }; - cloudabi32_subscription_t subtimo; - struct timespec timeout; - int error; - - if (uap->timeout != NULL) { - /* Poll with a timeout. */ - error = copyin(uap->timeout, &subtimo, sizeof(subtimo)); - if (error != 0) - return (error); - if (subtimo.type != CLOUDABI_EVENTTYPE_CLOCK || - subtimo.clock.flags != 0) - return (EINVAL); - timeout.tv_sec = subtimo.clock.timeout / 1000000000; - timeout.tv_nsec = subtimo.clock.timeout % 1000000000; - return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len, - ©ops, &timeout)); - } else { - /* Poll without a timeout. */ - return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len, - ©ops, NULL)); - } -} diff --git a/sys/compat/cloudabi32/cloudabi32_proto.h b/sys/compat/cloudabi32/cloudabi32_proto.h index 108bbbc2debb..16a072278267 100644 --- a/sys/compat/cloudabi32/cloudabi32_proto.h +++ b/sys/compat/cloudabi32/cloudabi32_proto.h @@ -227,14 +227,6 @@ struct cloudabi32_sys_poll_args { char out_l_[PADL_(cloudabi32_event_t *)]; cloudabi32_event_t * out; char out_r_[PADR_(cloudabi32_event_t *)]; char nsubscriptions_l_[PADL_(size_t)]; size_t nsubscriptions; char nsubscriptions_r_[PADR_(size_t)]; }; -struct cloudabi32_sys_poll_fd_args { - char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; - char in_l_[PADL_(const cloudabi32_subscription_t *)]; const cloudabi32_subscription_t * in; char in_r_[PADR_(const cloudabi32_subscription_t *)]; - char in_len_l_[PADL_(size_t)]; size_t in_len; char in_len_r_[PADR_(size_t)]; - char out_l_[PADL_(cloudabi32_event_t *)]; cloudabi32_event_t * out; char out_r_[PADR_(cloudabi32_event_t *)]; - char out_len_l_[PADL_(size_t)]; size_t out_len; char out_len_r_[PADR_(size_t)]; - char timeout_l_[PADL_(const cloudabi32_subscription_t *)]; const cloudabi32_subscription_t * timeout; char timeout_r_[PADR_(const cloudabi32_subscription_t *)]; -}; struct cloudabi_sys_proc_exec_args { char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; char data_l_[PADL_(const void *)]; const void * data; char data_r_[PADR_(const void *)]; @@ -317,7 +309,6 @@ int cloudabi_sys_mem_protect(struct thread *, struct cloudabi_sys_mem_protect_ar int cloudabi_sys_mem_sync(struct thread *, struct cloudabi_sys_mem_sync_args *); int cloudabi_sys_mem_unmap(struct thread *, struct cloudabi_sys_mem_unmap_args *); int cloudabi32_sys_poll(struct thread *, struct cloudabi32_sys_poll_args *); -int cloudabi32_sys_poll_fd(struct thread *, struct cloudabi32_sys_poll_fd_args *); int cloudabi_sys_proc_exec(struct thread *, struct cloudabi_sys_proc_exec_args *); int cloudabi_sys_proc_exit(struct thread *, struct cloudabi_sys_proc_exit_args *); int cloudabi_sys_proc_fork(struct thread *, struct cloudabi_sys_proc_fork_args *); @@ -403,7 +394,6 @@ int cloudabi_sys_thread_yield(struct thread *, struct cloudabi_sys_thread_yield_ #define CLOUDABI32_SYS_AUE_cloudabi_sys_mem_sync AUE_NULL #define CLOUDABI32_SYS_AUE_cloudabi_sys_mem_unmap AUE_NULL #define CLOUDABI32_SYS_AUE_cloudabi32_sys_poll AUE_NULL -#define CLOUDABI32_SYS_AUE_cloudabi32_sys_poll_fd AUE_NULL #define CLOUDABI32_SYS_AUE_cloudabi_sys_proc_exec AUE_NULL #define CLOUDABI32_SYS_AUE_cloudabi_sys_proc_exit AUE_NULL #define CLOUDABI32_SYS_AUE_cloudabi_sys_proc_fork AUE_NULL diff --git a/sys/compat/cloudabi32/cloudabi32_syscall.h b/sys/compat/cloudabi32/cloudabi32_syscall.h index ba0aa0ef71b9..a09dd1258041 100644 --- a/sys/compat/cloudabi32/cloudabi32_syscall.h +++ b/sys/compat/cloudabi32/cloudabi32_syscall.h @@ -43,16 +43,15 @@ #define CLOUDABI32_SYS_cloudabi_sys_mem_sync 35 #define CLOUDABI32_SYS_cloudabi_sys_mem_unmap 36 #define CLOUDABI32_SYS_cloudabi32_sys_poll 37 -#define CLOUDABI32_SYS_cloudabi32_sys_poll_fd 38 -#define CLOUDABI32_SYS_cloudabi_sys_proc_exec 39 -#define CLOUDABI32_SYS_cloudabi_sys_proc_exit 40 -#define CLOUDABI32_SYS_cloudabi_sys_proc_fork 41 -#define CLOUDABI32_SYS_cloudabi_sys_proc_raise 42 -#define CLOUDABI32_SYS_cloudabi_sys_random_get 43 -#define CLOUDABI32_SYS_cloudabi32_sys_sock_recv 44 -#define CLOUDABI32_SYS_cloudabi32_sys_sock_send 45 -#define CLOUDABI32_SYS_cloudabi_sys_sock_shutdown 46 -#define CLOUDABI32_SYS_cloudabi32_sys_thread_create 47 -#define CLOUDABI32_SYS_cloudabi_sys_thread_exit 48 -#define CLOUDABI32_SYS_cloudabi_sys_thread_yield 49 -#define CLOUDABI32_SYS_MAXSYSCALL 50 +#define CLOUDABI32_SYS_cloudabi_sys_proc_exec 38 +#define CLOUDABI32_SYS_cloudabi_sys_proc_exit 39 +#define CLOUDABI32_SYS_cloudabi_sys_proc_fork 40 +#define CLOUDABI32_SYS_cloudabi_sys_proc_raise 41 +#define CLOUDABI32_SYS_cloudabi_sys_random_get 42 +#define CLOUDABI32_SYS_cloudabi32_sys_sock_recv 43 +#define CLOUDABI32_SYS_cloudabi32_sys_sock_send 44 +#define CLOUDABI32_SYS_cloudabi_sys_sock_shutdown 45 +#define CLOUDABI32_SYS_cloudabi32_sys_thread_create 46 +#define CLOUDABI32_SYS_cloudabi_sys_thread_exit 47 +#define CLOUDABI32_SYS_cloudabi_sys_thread_yield 48 +#define CLOUDABI32_SYS_MAXSYSCALL 49 diff --git a/sys/compat/cloudabi32/cloudabi32_syscalls.c b/sys/compat/cloudabi32/cloudabi32_syscalls.c index dfe24e7cd6eb..95b4781e3310 100644 --- a/sys/compat/cloudabi32/cloudabi32_syscalls.c +++ b/sys/compat/cloudabi32/cloudabi32_syscalls.c @@ -44,16 +44,15 @@ const char *cloudabi32_syscallnames[] = { "cloudabi_sys_mem_sync", /* 35 = cloudabi_sys_mem_sync */ "cloudabi_sys_mem_unmap", /* 36 = cloudabi_sys_mem_unmap */ "cloudabi32_sys_poll", /* 37 = cloudabi32_sys_poll */ - "cloudabi32_sys_poll_fd", /* 38 = cloudabi32_sys_poll_fd */ - "cloudabi_sys_proc_exec", /* 39 = cloudabi_sys_proc_exec */ - "cloudabi_sys_proc_exit", /* 40 = cloudabi_sys_proc_exit */ - "cloudabi_sys_proc_fork", /* 41 = cloudabi_sys_proc_fork */ - "cloudabi_sys_proc_raise", /* 42 = cloudabi_sys_proc_raise */ - "cloudabi_sys_random_get", /* 43 = cloudabi_sys_random_get */ - "cloudabi32_sys_sock_recv", /* 44 = cloudabi32_sys_sock_recv */ - "cloudabi32_sys_sock_send", /* 45 = cloudabi32_sys_sock_send */ - "cloudabi_sys_sock_shutdown", /* 46 = cloudabi_sys_sock_shutdown */ - "cloudabi32_sys_thread_create", /* 47 = cloudabi32_sys_thread_create */ - "cloudabi_sys_thread_exit", /* 48 = cloudabi_sys_thread_exit */ - "cloudabi_sys_thread_yield", /* 49 = cloudabi_sys_thread_yield */ + "cloudabi_sys_proc_exec", /* 38 = cloudabi_sys_proc_exec */ + "cloudabi_sys_proc_exit", /* 39 = cloudabi_sys_proc_exit */ + "cloudabi_sys_proc_fork", /* 40 = cloudabi_sys_proc_fork */ + "cloudabi_sys_proc_raise", /* 41 = cloudabi_sys_proc_raise */ + "cloudabi_sys_random_get", /* 42 = cloudabi_sys_random_get */ + "cloudabi32_sys_sock_recv", /* 43 = cloudabi32_sys_sock_recv */ + "cloudabi32_sys_sock_send", /* 44 = cloudabi32_sys_sock_send */ + "cloudabi_sys_sock_shutdown", /* 45 = cloudabi_sys_sock_shutdown */ + "cloudabi32_sys_thread_create", /* 46 = cloudabi32_sys_thread_create */ + "cloudabi_sys_thread_exit", /* 47 = cloudabi_sys_thread_exit */ + "cloudabi_sys_thread_yield", /* 48 = cloudabi_sys_thread_yield */ }; diff --git a/sys/compat/cloudabi32/cloudabi32_sysent.c b/sys/compat/cloudabi32/cloudabi32_sysent.c index e48bcd1d509b..40380207d59b 100644 --- a/sys/compat/cloudabi32/cloudabi32_sysent.c +++ b/sys/compat/cloudabi32/cloudabi32_sysent.c @@ -52,16 +52,15 @@ struct sysent cloudabi32_sysent[] = { { AS(cloudabi_sys_mem_sync_args), (sy_call_t *)cloudabi_sys_mem_sync, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 35 = cloudabi_sys_mem_sync */ { AS(cloudabi_sys_mem_unmap_args), (sy_call_t *)cloudabi_sys_mem_unmap, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 36 = cloudabi_sys_mem_unmap */ { AS(cloudabi32_sys_poll_args), (sy_call_t *)cloudabi32_sys_poll, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 37 = cloudabi32_sys_poll */ - { AS(cloudabi32_sys_poll_fd_args), (sy_call_t *)cloudabi32_sys_poll_fd, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 38 = cloudabi32_sys_poll_fd */ - { AS(cloudabi_sys_proc_exec_args), (sy_call_t *)cloudabi_sys_proc_exec, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 39 = cloudabi_sys_proc_exec */ - { AS(cloudabi_sys_proc_exit_args), (sy_call_t *)cloudabi_sys_proc_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 40 = cloudabi_sys_proc_exit */ - { 0, (sy_call_t *)cloudabi_sys_proc_fork, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 41 = cloudabi_sys_proc_fork */ - { AS(cloudabi_sys_proc_raise_args), (sy_call_t *)cloudabi_sys_proc_raise, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 42 = cloudabi_sys_proc_raise */ - { AS(cloudabi_sys_random_get_args), (sy_call_t *)cloudabi_sys_random_get, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 43 = cloudabi_sys_random_get */ - { AS(cloudabi32_sys_sock_recv_args), (sy_call_t *)cloudabi32_sys_sock_recv, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 44 = cloudabi32_sys_sock_recv */ - { AS(cloudabi32_sys_sock_send_args), (sy_call_t *)cloudabi32_sys_sock_send, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 45 = cloudabi32_sys_sock_send */ - { AS(cloudabi_sys_sock_shutdown_args), (sy_call_t *)cloudabi_sys_sock_shutdown, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 46 = cloudabi_sys_sock_shutdown */ - { AS(cloudabi32_sys_thread_create_args), (sy_call_t *)cloudabi32_sys_thread_create, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 47 = cloudabi32_sys_thread_create */ - { AS(cloudabi_sys_thread_exit_args), (sy_call_t *)cloudabi_sys_thread_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 48 = cloudabi_sys_thread_exit */ - { 0, (sy_call_t *)cloudabi_sys_thread_yield, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 49 = cloudabi_sys_thread_yield */ + { AS(cloudabi_sys_proc_exec_args), (sy_call_t *)cloudabi_sys_proc_exec, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 38 = cloudabi_sys_proc_exec */ + { AS(cloudabi_sys_proc_exit_args), (sy_call_t *)cloudabi_sys_proc_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 39 = cloudabi_sys_proc_exit */ + { 0, (sy_call_t *)cloudabi_sys_proc_fork, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 40 = cloudabi_sys_proc_fork */ + { AS(cloudabi_sys_proc_raise_args), (sy_call_t *)cloudabi_sys_proc_raise, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 41 = cloudabi_sys_proc_raise */ + { AS(cloudabi_sys_random_get_args), (sy_call_t *)cloudabi_sys_random_get, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 42 = cloudabi_sys_random_get */ + { AS(cloudabi32_sys_sock_recv_args), (sy_call_t *)cloudabi32_sys_sock_recv, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 43 = cloudabi32_sys_sock_recv */ + { AS(cloudabi32_sys_sock_send_args), (sy_call_t *)cloudabi32_sys_sock_send, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 44 = cloudabi32_sys_sock_send */ + { AS(cloudabi_sys_sock_shutdown_args), (sy_call_t *)cloudabi_sys_sock_shutdown, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 45 = cloudabi_sys_sock_shutdown */ + { AS(cloudabi32_sys_thread_create_args), (sy_call_t *)cloudabi32_sys_thread_create, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 46 = cloudabi32_sys_thread_create */ + { AS(cloudabi_sys_thread_exit_args), (sy_call_t *)cloudabi_sys_thread_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 47 = cloudabi_sys_thread_exit */ + { 0, (sy_call_t *)cloudabi_sys_thread_yield, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 48 = cloudabi_sys_thread_yield */ }; diff --git a/sys/compat/cloudabi32/cloudabi32_systrace_args.c b/sys/compat/cloudabi32/cloudabi32_systrace_args.c index 532ce4dd4a4f..4221955ab5e6 100644 --- a/sys/compat/cloudabi32/cloudabi32_systrace_args.c +++ b/sys/compat/cloudabi32/cloudabi32_systrace_args.c @@ -357,20 +357,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 3; break; } - /* cloudabi32_sys_poll_fd */ - case 38: { - struct cloudabi32_sys_poll_fd_args *p = params; - iarg[0] = p->fd; /* cloudabi_fd_t */ - uarg[1] = (intptr_t) p->in; /* const cloudabi32_subscription_t * */ - uarg[2] = p->in_len; /* size_t */ - uarg[3] = (intptr_t) p->out; /* cloudabi32_event_t * */ - uarg[4] = p->out_len; /* size_t */ - uarg[5] = (intptr_t) p->timeout; /* const cloudabi32_subscription_t * */ - *n_args = 6; - break; - } /* cloudabi_sys_proc_exec */ - case 39: { + case 38: { struct cloudabi_sys_proc_exec_args *p = params; iarg[0] = p->fd; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->data; /* const void * */ @@ -381,26 +369,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_proc_exit */ - case 40: { + case 39: { struct cloudabi_sys_proc_exit_args *p = params; iarg[0] = p->rval; /* cloudabi_exitcode_t */ *n_args = 1; break; } /* cloudabi_sys_proc_fork */ - case 41: { + case 40: { *n_args = 0; break; } /* cloudabi_sys_proc_raise */ - case 42: { + case 41: { struct cloudabi_sys_proc_raise_args *p = params; iarg[0] = p->sig; /* cloudabi_signal_t */ *n_args = 1; break; } /* cloudabi_sys_random_get */ - case 43: { + case 42: { struct cloudabi_sys_random_get_args *p = params; uarg[0] = (intptr_t) p->buf; /* void * */ uarg[1] = p->buf_len; /* size_t */ @@ -408,7 +396,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi32_sys_sock_recv */ - case 44: { + case 43: { struct cloudabi32_sys_sock_recv_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->in; /* const cloudabi32_recv_in_t * */ @@ -417,7 +405,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi32_sys_sock_send */ - case 45: { + case 44: { struct cloudabi32_sys_sock_send_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->in; /* const cloudabi32_send_in_t * */ @@ -426,7 +414,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_sock_shutdown */ - case 46: { + case 45: { struct cloudabi_sys_sock_shutdown_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ iarg[1] = p->how; /* cloudabi_sdflags_t */ @@ -434,14 +422,14 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi32_sys_thread_create */ - case 47: { + case 46: { struct cloudabi32_sys_thread_create_args *p = params; uarg[0] = (intptr_t) p->attr; /* cloudabi32_threadattr_t * */ *n_args = 1; break; } /* cloudabi_sys_thread_exit */ - case 48: { + case 47: { struct cloudabi_sys_thread_exit_args *p = params; uarg[0] = (intptr_t) p->lock; /* cloudabi_lock_t * */ iarg[1] = p->scope; /* cloudabi_scope_t */ @@ -449,7 +437,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_thread_yield */ - case 49: { + case 48: { *n_args = 0; break; } @@ -1083,33 +1071,8 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cloudabi32_sys_poll_fd */ - case 38: - switch(ndx) { - case 0: - p = "cloudabi_fd_t"; - break; - case 1: - p = "userland const cloudabi32_subscription_t *"; - break; - case 2: - p = "size_t"; - break; - case 3: - p = "userland cloudabi32_event_t *"; - break; - case 4: - p = "size_t"; - break; - case 5: - p = "userland const cloudabi32_subscription_t *"; - break; - default: - break; - }; - break; /* cloudabi_sys_proc_exec */ - case 39: + case 38: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1131,7 +1094,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_proc_exit */ - case 40: + case 39: switch(ndx) { case 0: p = "cloudabi_exitcode_t"; @@ -1141,10 +1104,10 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_proc_fork */ - case 41: + case 40: break; /* cloudabi_sys_proc_raise */ - case 42: + case 41: switch(ndx) { case 0: p = "cloudabi_signal_t"; @@ -1154,7 +1117,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_random_get */ - case 43: + case 42: switch(ndx) { case 0: p = "userland void *"; @@ -1167,7 +1130,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi32_sys_sock_recv */ - case 44: + case 43: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1183,7 +1146,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi32_sys_sock_send */ - case 45: + case 44: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1199,7 +1162,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_sock_shutdown */ - case 46: + case 45: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1212,7 +1175,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi32_sys_thread_create */ - case 47: + case 46: switch(ndx) { case 0: p = "userland cloudabi32_threadattr_t *"; @@ -1222,7 +1185,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_thread_exit */ - case 48: + case 47: switch(ndx) { case 0: p = "userland cloudabi_lock_t *"; @@ -1235,7 +1198,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_thread_yield */ - case 49: + case 48: break; default: break; @@ -1438,60 +1401,55 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "size_t"; break; - /* cloudabi32_sys_poll_fd */ - case 38: - if (ndx == 0 || ndx == 1) - p = "size_t"; - break; /* cloudabi_sys_proc_exec */ - case 39: + case 38: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_proc_exit */ - case 40: + case 39: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_proc_fork */ - case 41: + case 40: /* cloudabi_sys_proc_raise */ - case 42: + case 41: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_random_get */ - case 43: + case 42: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi32_sys_sock_recv */ - case 44: + case 43: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi32_sys_sock_send */ - case 45: + case 44: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_sock_shutdown */ - case 46: + case 45: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi32_sys_thread_create */ - case 47: + case 46: if (ndx == 0 || ndx == 1) p = "cloudabi_tid_t"; break; /* cloudabi_sys_thread_exit */ - case 48: + case 47: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_thread_yield */ - case 49: + case 48: default: break; }; diff --git a/sys/compat/cloudabi64/cloudabi64_poll.c b/sys/compat/cloudabi64/cloudabi64_poll.c index 3df526598934..2b80d7af6b62 100644 --- a/sys/compat/cloudabi64/cloudabi64_poll.c +++ b/sys/compat/cloudabi64/cloudabi64_poll.c @@ -79,7 +79,6 @@ convert_signal(int sig) struct cloudabi64_kevent_args { const cloudabi64_subscription_t *in; cloudabi64_event_t *out; - bool once; }; /* Converts CloudABI's subscription objects to FreeBSD's struct kevent. */ @@ -124,9 +123,7 @@ cloudabi64_kevent_copyin(void *arg, struct kevent *kevp, int count) case CLOUDABI_EVENTTYPE_FD_READ: kevp->filter = EVFILT_READ; kevp->ident = sub.fd_readwrite.fd; - if ((sub.fd_readwrite.flags & - CLOUDABI_SUBSCRIPTION_FD_READWRITE_POLL) != 0) - kevp->fflags = NOTE_FILE_POLL; + kevp->fflags = NOTE_FILE_POLL; break; case CLOUDABI_EVENTTYPE_FD_WRITE: kevp->filter = EVFILT_WRITE; @@ -138,24 +135,7 @@ cloudabi64_kevent_copyin(void *arg, struct kevent *kevp, int count) kevp->fflags = NOTE_EXIT; break; } - if (args->once) { - /* Ignore flags. Simply use oneshot mode. */ - kevp->flags = EV_ADD | EV_ONESHOT; - } else { - /* Translate flags. */ - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ADD) != 0) - kevp->flags |= EV_ADD; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_CLEAR) != 0) - kevp->flags |= EV_CLEAR; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_DELETE) != 0) - kevp->flags |= EV_DELETE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_DISABLE) != 0) - kevp->flags |= EV_DISABLE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ENABLE) != 0) - kevp->flags |= EV_ENABLE; - if ((sub.flags & CLOUDABI_SUBSCRIPTION_ONESHOT) != 0) - kevp->flags |= EV_ONESHOT; - } + kevp->flags = EV_ADD | EV_ONESHOT; ++kevp; } return (0); @@ -238,7 +218,6 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) struct cloudabi64_kevent_args args = { .in = uap->in, .out = uap->out, - .once = true, }; struct kevent_copyops copyops = { .k_copyin = cloudabi64_kevent_copyin, @@ -369,40 +348,3 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) return (kern_kevent_anonymous(td, uap->nsubscriptions, ©ops)); } - -int -cloudabi64_sys_poll_fd(struct thread *td, - struct cloudabi64_sys_poll_fd_args *uap) -{ - struct cloudabi64_kevent_args args = { - .in = uap->in, - .out = uap->out, - .once = false, - }; - struct kevent_copyops copyops = { - .k_copyin = cloudabi64_kevent_copyin, - .k_copyout = cloudabi64_kevent_copyout, - .arg = &args, - }; - cloudabi64_subscription_t subtimo; - struct timespec timeout; - int error; - - if (uap->timeout != NULL) { - /* Poll with a timeout. */ - error = copyin(uap->timeout, &subtimo, sizeof(subtimo)); - if (error != 0) - return (error); - if (subtimo.type != CLOUDABI_EVENTTYPE_CLOCK || - subtimo.clock.flags != 0) - return (EINVAL); - timeout.tv_sec = subtimo.clock.timeout / 1000000000; - timeout.tv_nsec = subtimo.clock.timeout % 1000000000; - return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len, - ©ops, &timeout)); - } else { - /* Poll without a timeout. */ - return (kern_kevent(td, uap->fd, uap->in_len, uap->out_len, - ©ops, NULL)); - } -} diff --git a/sys/compat/cloudabi64/cloudabi64_proto.h b/sys/compat/cloudabi64/cloudabi64_proto.h index 7adbea2d2d2e..2f0302f9aa11 100644 --- a/sys/compat/cloudabi64/cloudabi64_proto.h +++ b/sys/compat/cloudabi64/cloudabi64_proto.h @@ -227,14 +227,6 @@ struct cloudabi64_sys_poll_args { char out_l_[PADL_(cloudabi64_event_t *)]; cloudabi64_event_t * out; char out_r_[PADR_(cloudabi64_event_t *)]; char nsubscriptions_l_[PADL_(size_t)]; size_t nsubscriptions; char nsubscriptions_r_[PADR_(size_t)]; }; -struct cloudabi64_sys_poll_fd_args { - char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; - char in_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * in; char in_r_[PADR_(const cloudabi64_subscription_t *)]; - char in_len_l_[PADL_(size_t)]; size_t in_len; char in_len_r_[PADR_(size_t)]; - char out_l_[PADL_(cloudabi64_event_t *)]; cloudabi64_event_t * out; char out_r_[PADR_(cloudabi64_event_t *)]; - char out_len_l_[PADL_(size_t)]; size_t out_len; char out_len_r_[PADR_(size_t)]; - char timeout_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * timeout; char timeout_r_[PADR_(const cloudabi64_subscription_t *)]; -}; struct cloudabi_sys_proc_exec_args { char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; char data_l_[PADL_(const void *)]; const void * data; char data_r_[PADR_(const void *)]; @@ -317,7 +309,6 @@ int cloudabi_sys_mem_protect(struct thread *, struct cloudabi_sys_mem_protect_ar int cloudabi_sys_mem_sync(struct thread *, struct cloudabi_sys_mem_sync_args *); int cloudabi_sys_mem_unmap(struct thread *, struct cloudabi_sys_mem_unmap_args *); int cloudabi64_sys_poll(struct thread *, struct cloudabi64_sys_poll_args *); -int cloudabi64_sys_poll_fd(struct thread *, struct cloudabi64_sys_poll_fd_args *); int cloudabi_sys_proc_exec(struct thread *, struct cloudabi_sys_proc_exec_args *); int cloudabi_sys_proc_exit(struct thread *, struct cloudabi_sys_proc_exit_args *); int cloudabi_sys_proc_fork(struct thread *, struct cloudabi_sys_proc_fork_args *); @@ -403,7 +394,6 @@ int cloudabi_sys_thread_yield(struct thread *, struct cloudabi_sys_thread_yield_ #define CLOUDABI64_SYS_AUE_cloudabi_sys_mem_sync AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_mem_unmap AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi64_sys_poll AUE_NULL -#define CLOUDABI64_SYS_AUE_cloudabi64_sys_poll_fd AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_proc_exec AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_proc_exit AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_proc_fork AUE_NULL diff --git a/sys/compat/cloudabi64/cloudabi64_syscall.h b/sys/compat/cloudabi64/cloudabi64_syscall.h index af22a32eae90..091faf1fefe6 100644 --- a/sys/compat/cloudabi64/cloudabi64_syscall.h +++ b/sys/compat/cloudabi64/cloudabi64_syscall.h @@ -43,16 +43,15 @@ #define CLOUDABI64_SYS_cloudabi_sys_mem_sync 35 #define CLOUDABI64_SYS_cloudabi_sys_mem_unmap 36 #define CLOUDABI64_SYS_cloudabi64_sys_poll 37 -#define CLOUDABI64_SYS_cloudabi64_sys_poll_fd 38 -#define CLOUDABI64_SYS_cloudabi_sys_proc_exec 39 -#define CLOUDABI64_SYS_cloudabi_sys_proc_exit 40 -#define CLOUDABI64_SYS_cloudabi_sys_proc_fork 41 -#define CLOUDABI64_SYS_cloudabi_sys_proc_raise 42 -#define CLOUDABI64_SYS_cloudabi_sys_random_get 43 -#define CLOUDABI64_SYS_cloudabi64_sys_sock_recv 44 -#define CLOUDABI64_SYS_cloudabi64_sys_sock_send 45 -#define CLOUDABI64_SYS_cloudabi_sys_sock_shutdown 46 -#define CLOUDABI64_SYS_cloudabi64_sys_thread_create 47 -#define CLOUDABI64_SYS_cloudabi_sys_thread_exit 48 -#define CLOUDABI64_SYS_cloudabi_sys_thread_yield 49 -#define CLOUDABI64_SYS_MAXSYSCALL 50 +#define CLOUDABI64_SYS_cloudabi_sys_proc_exec 38 +#define CLOUDABI64_SYS_cloudabi_sys_proc_exit 39 +#define CLOUDABI64_SYS_cloudabi_sys_proc_fork 40 +#define CLOUDABI64_SYS_cloudabi_sys_proc_raise 41 +#define CLOUDABI64_SYS_cloudabi_sys_random_get 42 +#define CLOUDABI64_SYS_cloudabi64_sys_sock_recv 43 +#define CLOUDABI64_SYS_cloudabi64_sys_sock_send 44 +#define CLOUDABI64_SYS_cloudabi_sys_sock_shutdown 45 +#define CLOUDABI64_SYS_cloudabi64_sys_thread_create 46 +#define CLOUDABI64_SYS_cloudabi_sys_thread_exit 47 +#define CLOUDABI64_SYS_cloudabi_sys_thread_yield 48 +#define CLOUDABI64_SYS_MAXSYSCALL 49 diff --git a/sys/compat/cloudabi64/cloudabi64_syscalls.c b/sys/compat/cloudabi64/cloudabi64_syscalls.c index 101ed369b276..c5ce5f368b9b 100644 --- a/sys/compat/cloudabi64/cloudabi64_syscalls.c +++ b/sys/compat/cloudabi64/cloudabi64_syscalls.c @@ -44,16 +44,15 @@ const char *cloudabi64_syscallnames[] = { "cloudabi_sys_mem_sync", /* 35 = cloudabi_sys_mem_sync */ "cloudabi_sys_mem_unmap", /* 36 = cloudabi_sys_mem_unmap */ "cloudabi64_sys_poll", /* 37 = cloudabi64_sys_poll */ - "cloudabi64_sys_poll_fd", /* 38 = cloudabi64_sys_poll_fd */ - "cloudabi_sys_proc_exec", /* 39 = cloudabi_sys_proc_exec */ - "cloudabi_sys_proc_exit", /* 40 = cloudabi_sys_proc_exit */ - "cloudabi_sys_proc_fork", /* 41 = cloudabi_sys_proc_fork */ - "cloudabi_sys_proc_raise", /* 42 = cloudabi_sys_proc_raise */ - "cloudabi_sys_random_get", /* 43 = cloudabi_sys_random_get */ - "cloudabi64_sys_sock_recv", /* 44 = cloudabi64_sys_sock_recv */ - "cloudabi64_sys_sock_send", /* 45 = cloudabi64_sys_sock_send */ - "cloudabi_sys_sock_shutdown", /* 46 = cloudabi_sys_sock_shutdown */ - "cloudabi64_sys_thread_create", /* 47 = cloudabi64_sys_thread_create */ - "cloudabi_sys_thread_exit", /* 48 = cloudabi_sys_thread_exit */ - "cloudabi_sys_thread_yield", /* 49 = cloudabi_sys_thread_yield */ + "cloudabi_sys_proc_exec", /* 38 = cloudabi_sys_proc_exec */ + "cloudabi_sys_proc_exit", /* 39 = cloudabi_sys_proc_exit */ + "cloudabi_sys_proc_fork", /* 40 = cloudabi_sys_proc_fork */ + "cloudabi_sys_proc_raise", /* 41 = cloudabi_sys_proc_raise */ + "cloudabi_sys_random_get", /* 42 = cloudabi_sys_random_get */ + "cloudabi64_sys_sock_recv", /* 43 = cloudabi64_sys_sock_recv */ + "cloudabi64_sys_sock_send", /* 44 = cloudabi64_sys_sock_send */ + "cloudabi_sys_sock_shutdown", /* 45 = cloudabi_sys_sock_shutdown */ + "cloudabi64_sys_thread_create", /* 46 = cloudabi64_sys_thread_create */ + "cloudabi_sys_thread_exit", /* 47 = cloudabi_sys_thread_exit */ + "cloudabi_sys_thread_yield", /* 48 = cloudabi_sys_thread_yield */ }; diff --git a/sys/compat/cloudabi64/cloudabi64_sysent.c b/sys/compat/cloudabi64/cloudabi64_sysent.c index 3772cdbb2722..f1ef767662f2 100644 --- a/sys/compat/cloudabi64/cloudabi64_sysent.c +++ b/sys/compat/cloudabi64/cloudabi64_sysent.c @@ -52,16 +52,15 @@ struct sysent cloudabi64_sysent[] = { { AS(cloudabi_sys_mem_sync_args), (sy_call_t *)cloudabi_sys_mem_sync, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 35 = cloudabi_sys_mem_sync */ { AS(cloudabi_sys_mem_unmap_args), (sy_call_t *)cloudabi_sys_mem_unmap, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 36 = cloudabi_sys_mem_unmap */ { AS(cloudabi64_sys_poll_args), (sy_call_t *)cloudabi64_sys_poll, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 37 = cloudabi64_sys_poll */ - { AS(cloudabi64_sys_poll_fd_args), (sy_call_t *)cloudabi64_sys_poll_fd, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 38 = cloudabi64_sys_poll_fd */ - { AS(cloudabi_sys_proc_exec_args), (sy_call_t *)cloudabi_sys_proc_exec, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 39 = cloudabi_sys_proc_exec */ - { AS(cloudabi_sys_proc_exit_args), (sy_call_t *)cloudabi_sys_proc_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 40 = cloudabi_sys_proc_exit */ - { 0, (sy_call_t *)cloudabi_sys_proc_fork, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 41 = cloudabi_sys_proc_fork */ - { AS(cloudabi_sys_proc_raise_args), (sy_call_t *)cloudabi_sys_proc_raise, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 42 = cloudabi_sys_proc_raise */ - { AS(cloudabi_sys_random_get_args), (sy_call_t *)cloudabi_sys_random_get, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 43 = cloudabi_sys_random_get */ - { AS(cloudabi64_sys_sock_recv_args), (sy_call_t *)cloudabi64_sys_sock_recv, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 44 = cloudabi64_sys_sock_recv */ - { AS(cloudabi64_sys_sock_send_args), (sy_call_t *)cloudabi64_sys_sock_send, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 45 = cloudabi64_sys_sock_send */ - { AS(cloudabi_sys_sock_shutdown_args), (sy_call_t *)cloudabi_sys_sock_shutdown, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 46 = cloudabi_sys_sock_shutdown */ - { AS(cloudabi64_sys_thread_create_args), (sy_call_t *)cloudabi64_sys_thread_create, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 47 = cloudabi64_sys_thread_create */ - { AS(cloudabi_sys_thread_exit_args), (sy_call_t *)cloudabi_sys_thread_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 48 = cloudabi_sys_thread_exit */ - { 0, (sy_call_t *)cloudabi_sys_thread_yield, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 49 = cloudabi_sys_thread_yield */ + { AS(cloudabi_sys_proc_exec_args), (sy_call_t *)cloudabi_sys_proc_exec, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 38 = cloudabi_sys_proc_exec */ + { AS(cloudabi_sys_proc_exit_args), (sy_call_t *)cloudabi_sys_proc_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 39 = cloudabi_sys_proc_exit */ + { 0, (sy_call_t *)cloudabi_sys_proc_fork, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 40 = cloudabi_sys_proc_fork */ + { AS(cloudabi_sys_proc_raise_args), (sy_call_t *)cloudabi_sys_proc_raise, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 41 = cloudabi_sys_proc_raise */ + { AS(cloudabi_sys_random_get_args), (sy_call_t *)cloudabi_sys_random_get, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 42 = cloudabi_sys_random_get */ + { AS(cloudabi64_sys_sock_recv_args), (sy_call_t *)cloudabi64_sys_sock_recv, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 43 = cloudabi64_sys_sock_recv */ + { AS(cloudabi64_sys_sock_send_args), (sy_call_t *)cloudabi64_sys_sock_send, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 44 = cloudabi64_sys_sock_send */ + { AS(cloudabi_sys_sock_shutdown_args), (sy_call_t *)cloudabi_sys_sock_shutdown, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 45 = cloudabi_sys_sock_shutdown */ + { AS(cloudabi64_sys_thread_create_args), (sy_call_t *)cloudabi64_sys_thread_create, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 46 = cloudabi64_sys_thread_create */ + { AS(cloudabi_sys_thread_exit_args), (sy_call_t *)cloudabi_sys_thread_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 47 = cloudabi_sys_thread_exit */ + { 0, (sy_call_t *)cloudabi_sys_thread_yield, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 48 = cloudabi_sys_thread_yield */ }; diff --git a/sys/compat/cloudabi64/cloudabi64_systrace_args.c b/sys/compat/cloudabi64/cloudabi64_systrace_args.c index 14f10ce64fb1..6dc8fc77163a 100644 --- a/sys/compat/cloudabi64/cloudabi64_systrace_args.c +++ b/sys/compat/cloudabi64/cloudabi64_systrace_args.c @@ -357,20 +357,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 3; break; } - /* cloudabi64_sys_poll_fd */ - case 38: { - struct cloudabi64_sys_poll_fd_args *p = params; - iarg[0] = p->fd; /* cloudabi_fd_t */ - uarg[1] = (intptr_t) p->in; /* const cloudabi64_subscription_t * */ - uarg[2] = p->in_len; /* size_t */ - uarg[3] = (intptr_t) p->out; /* cloudabi64_event_t * */ - uarg[4] = p->out_len; /* size_t */ - uarg[5] = (intptr_t) p->timeout; /* const cloudabi64_subscription_t * */ - *n_args = 6; - break; - } /* cloudabi_sys_proc_exec */ - case 39: { + case 38: { struct cloudabi_sys_proc_exec_args *p = params; iarg[0] = p->fd; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->data; /* const void * */ @@ -381,26 +369,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_proc_exit */ - case 40: { + case 39: { struct cloudabi_sys_proc_exit_args *p = params; iarg[0] = p->rval; /* cloudabi_exitcode_t */ *n_args = 1; break; } /* cloudabi_sys_proc_fork */ - case 41: { + case 40: { *n_args = 0; break; } /* cloudabi_sys_proc_raise */ - case 42: { + case 41: { struct cloudabi_sys_proc_raise_args *p = params; iarg[0] = p->sig; /* cloudabi_signal_t */ *n_args = 1; break; } /* cloudabi_sys_random_get */ - case 43: { + case 42: { struct cloudabi_sys_random_get_args *p = params; uarg[0] = (intptr_t) p->buf; /* void * */ uarg[1] = p->buf_len; /* size_t */ @@ -408,7 +396,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi64_sys_sock_recv */ - case 44: { + case 43: { struct cloudabi64_sys_sock_recv_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->in; /* const cloudabi64_recv_in_t * */ @@ -417,7 +405,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi64_sys_sock_send */ - case 45: { + case 44: { struct cloudabi64_sys_sock_send_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ uarg[1] = (intptr_t) p->in; /* const cloudabi64_send_in_t * */ @@ -426,7 +414,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_sock_shutdown */ - case 46: { + case 45: { struct cloudabi_sys_sock_shutdown_args *p = params; iarg[0] = p->sock; /* cloudabi_fd_t */ iarg[1] = p->how; /* cloudabi_sdflags_t */ @@ -434,14 +422,14 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi64_sys_thread_create */ - case 47: { + case 46: { struct cloudabi64_sys_thread_create_args *p = params; uarg[0] = (intptr_t) p->attr; /* cloudabi64_threadattr_t * */ *n_args = 1; break; } /* cloudabi_sys_thread_exit */ - case 48: { + case 47: { struct cloudabi_sys_thread_exit_args *p = params; uarg[0] = (intptr_t) p->lock; /* cloudabi_lock_t * */ iarg[1] = p->scope; /* cloudabi_scope_t */ @@ -449,7 +437,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } /* cloudabi_sys_thread_yield */ - case 49: { + case 48: { *n_args = 0; break; } @@ -1083,33 +1071,8 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cloudabi64_sys_poll_fd */ - case 38: - switch(ndx) { - case 0: - p = "cloudabi_fd_t"; - break; - case 1: - p = "userland const cloudabi64_subscription_t *"; - break; - case 2: - p = "size_t"; - break; - case 3: - p = "userland cloudabi64_event_t *"; - break; - case 4: - p = "size_t"; - break; - case 5: - p = "userland const cloudabi64_subscription_t *"; - break; - default: - break; - }; - break; /* cloudabi_sys_proc_exec */ - case 39: + case 38: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1131,7 +1094,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_proc_exit */ - case 40: + case 39: switch(ndx) { case 0: p = "cloudabi_exitcode_t"; @@ -1141,10 +1104,10 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_proc_fork */ - case 41: + case 40: break; /* cloudabi_sys_proc_raise */ - case 42: + case 41: switch(ndx) { case 0: p = "cloudabi_signal_t"; @@ -1154,7 +1117,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_random_get */ - case 43: + case 42: switch(ndx) { case 0: p = "userland void *"; @@ -1167,7 +1130,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi64_sys_sock_recv */ - case 44: + case 43: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1183,7 +1146,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi64_sys_sock_send */ - case 45: + case 44: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1199,7 +1162,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_sock_shutdown */ - case 46: + case 45: switch(ndx) { case 0: p = "cloudabi_fd_t"; @@ -1212,7 +1175,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi64_sys_thread_create */ - case 47: + case 46: switch(ndx) { case 0: p = "userland cloudabi64_threadattr_t *"; @@ -1222,7 +1185,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_thread_exit */ - case 48: + case 47: switch(ndx) { case 0: p = "userland cloudabi_lock_t *"; @@ -1235,7 +1198,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; /* cloudabi_sys_thread_yield */ - case 49: + case 48: break; default: break; @@ -1438,60 +1401,55 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "size_t"; break; - /* cloudabi64_sys_poll_fd */ - case 38: - if (ndx == 0 || ndx == 1) - p = "size_t"; - break; /* cloudabi_sys_proc_exec */ - case 39: + case 38: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_proc_exit */ - case 40: + case 39: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_proc_fork */ - case 41: + case 40: /* cloudabi_sys_proc_raise */ - case 42: + case 41: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_random_get */ - case 43: + case 42: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi64_sys_sock_recv */ - case 44: + case 43: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi64_sys_sock_send */ - case 45: + case 44: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_sock_shutdown */ - case 46: + case 45: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi64_sys_thread_create */ - case 47: + case 46: if (ndx == 0 || ndx == 1) p = "cloudabi_tid_t"; break; /* cloudabi_sys_thread_exit */ - case 48: + case 47: if (ndx == 0 || ndx == 1) p = "void"; break; /* cloudabi_sys_thread_yield */ - case 49: + case 48: default: break; }; diff --git a/sys/compat/freebsd32/capabilities.conf b/sys/compat/freebsd32/capabilities.conf index 4458227fd7bf..d5681b7740f3 100644 --- a/sys/compat/freebsd32/capabilities.conf +++ b/sys/compat/freebsd32/capabilities.conf @@ -200,6 +200,7 @@ pdkill freebsd32_pipe pipe2 poll +freebsd32_posix_fallocate freebsd32_pread freebsd32_preadv profil diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index ee7d6c763d0b..4891616428f3 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -602,11 +602,11 @@ struct sysent freebsd32_sysent[] = { { AS(rctl_add_rule_args), (sy_call_t *)sys_rctl_add_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 528 = rctl_add_rule */ { AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */ #ifdef PAD64_REQUIRED - { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ + { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_POSIX_FADVISE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ #else - { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ + { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_POSIX_FADVISE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ #endif diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c index d771b46d9652..6df23d07ad92 100644 --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -133,19 +133,161 @@ linsysfs_link_scsi_host(PFS_FILL_ARGS) return (0); } -#define PCI_DEV "pci" static int -linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char *path, - char *prefix) +linsysfs_fill_data(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "%s", (char *)pn->pn_data); + return (0); +} + +static int +linsysfs_fill_vendor(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_vendor((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_device(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_device((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_subvendor(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_subvendor((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_subdevice(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_subdevice((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_revid(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%x\n", pci_get_revid((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_config(PFS_FILL_ARGS) +{ + uint8_t config[48]; + device_t dev; + uint32_t reg; + + dev = (device_t)pn->pn_data; + bzero(config, sizeof(config)); + reg = pci_get_vendor(dev); + config[0] = reg; + config[1] = reg >> 8; + reg = pci_get_device(dev); + config[2] = reg; + config[3] = reg >> 8; + reg = pci_get_revid(dev); + config[8] = reg; + reg = pci_get_subvendor(dev); + config[44] = reg; + config[45] = reg >> 8; + reg = pci_get_subdevice(dev); + config[46] = reg; + config[47] = reg >> 8; + sbuf_bcat(sb, config, sizeof(config)); + return (0); +} + +/* + * Filler function for PCI uevent file + */ +static int +linsysfs_fill_uevent_pci(PFS_FILL_ARGS) +{ + device_t dev; + + dev = (device_t)pn->pn_data; + sbuf_printf(sb, "DRIVER=%s\nPCI_CLASS=%X\nPCI_ID=%04X:%04X\n" + "PCI_SUBSYS_ID=%04X:%04X\nPCI_SLOT_NAME=%04d:%02x:%02x.%x\n", + linux_driver_get_name_dev(dev), pci_get_class(dev), + pci_get_vendor(dev), pci_get_device(dev), pci_get_subvendor(dev), + pci_get_subdevice(dev), pci_get_domain(dev), pci_get_bus(dev), + pci_get_slot(dev), pci_get_function(dev)); + return (0); +} + +/* + * Filler function for drm uevent file + */ +static int +linsysfs_fill_uevent_drm(PFS_FILL_ARGS) +{ + device_t dev; + int unit; + + dev = (device_t)pn->pn_data; + unit = device_get_unit(dev); + sbuf_printf(sb, + "MAJOR=226\nMINOR=%d\nDEVNAME=dri/card%d\nDEVTYPE=dri_minor\n", + unit, unit); + return (0); +} + +static char * +get_full_pfs_path(struct pfs_node *cur) +{ + char *temp, *path; + + temp = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + path[0] = '\0'; + + do { + snprintf(temp, MAXPATHLEN, "%s/%s", cur->pn_name, path); + strlcpy(path, temp, MAXPATHLEN); + cur = cur->pn_parent; + } while (cur->pn_parent != NULL); + + path[strlen(path) - 1] = '\0'; /* remove extra slash */ + free(temp, M_TEMP); + return (path); +} + +/* + * Filler function for symlink from drm char device to PCI device + */ +static int +linsysfs_fill_vgapci(PFS_FILL_ARGS) +{ + char *path; + + path = get_full_pfs_path((struct pfs_node*)pn->pn_data); + sbuf_printf(sb, "../../../%s", path); + free(path, M_TEMP); + return (0); +} + +#define PCI_DEV "pci" +#define DRMN_DEV "drmn" +static int +linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, + struct pfs_node *chardev, struct pfs_node *drm, char *path, char *prefix) { struct scsi_host_queue *scsi_host; - struct pfs_node *sub_dir; - int i, nchildren; + struct pfs_node *sub_dir, *cur_file; + int i, nchildren, error; device_t *children, parent; devclass_t devclass; const char *name = NULL; struct pci_devinfo *dinfo; - char *device, *host, *new_path = path; + char *device, *host, *new_path, *devname; + + new_path = path; + devname = malloc(16, M_TEMP, M_WAITOK); parent = device_get_parent(dev); if (parent) { @@ -171,6 +313,40 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char strcat(new_path, device); dir = pfs_create_dir(dir, device, NULL, NULL, NULL, 0); + cur_file = pfs_create_file(dir, "vendor", + &linsysfs_fill_vendor, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "device", + &linsysfs_fill_device, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, + "subsystem_vendor", + &linsysfs_fill_subvendor, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, + "subsystem_device", + &linsysfs_fill_subdevice, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "revision", + &linsysfs_fill_revid, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "config", + &linsysfs_fill_config, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "uevent", + &linsysfs_fill_uevent_pci, NULL, NULL, + NULL, PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_link(dir, "subsystem", + &linsysfs_fill_data, NULL, NULL, NULL, 0); + /* libdrm just checks that the link ends in "/pci" */ + cur_file->pn_data = "/sys/bus/pci"; if (dinfo->cfg.baseclass == PCIC_STORAGE) { /* DJA only make this if needed */ @@ -207,15 +383,51 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char free(host, M_TEMP); } } + + devclass = device_get_devclass(dev); + if (devclass != NULL) + name = devclass_get_name(devclass); + else + name = NULL; + if (name != NULL && strcmp(name, DRMN_DEV) == 0 && + device_get_unit(dev) >= 0) { + dinfo = device_get_ivars(parent); + if (dinfo != NULL && dinfo->cfg.baseclass == PCIC_DISPLAY) { + sprintf(devname, "226:%d", + device_get_unit(dev)); + sub_dir = pfs_create_dir(chardev, + devname, NULL, NULL, NULL, 0); + cur_file = pfs_create_link(sub_dir, + "device", &linsysfs_fill_vgapci, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dir; + cur_file = pfs_create_file(sub_dir, + "uevent", &linsysfs_fill_uevent_drm, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dev; + sprintf(devname, "card%d", + device_get_unit(dev)); + sub_dir = pfs_create_dir(drm, + devname, NULL, NULL, NULL, 0); + cur_file = pfs_create_link(sub_dir, + "device", &linsysfs_fill_vgapci, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dir; + } + } } - device_get_children(dev, &children, &nchildren); - for (i = 0; i < nchildren; i++) { - if (children[i]) - linsysfs_run_bus(children[i], dir, scsi, new_path, prefix); + error = device_get_children(dev, &children, &nchildren); + if (error == 0) { + for (i = 0; i < nchildren; i++) + if (children[i]) + linsysfs_run_bus(children[i], dir, scsi, + chardev, drm, new_path, prefix); + free(children, M_TEMP); } if (new_path != path) free(new_path, M_TEMP); + free(devname, M_TEMP); return (1); } @@ -276,9 +488,12 @@ static int linsysfs_init(PFS_INIT_ARGS) { struct pfs_node *root; + struct pfs_node *class; struct pfs_node *dir, *sys, *cpu; + struct pfs_node *drm; struct pfs_node *pci; struct pfs_node *scsi; + struct pfs_node *devdir, *chardev; devclass_t devclass; device_t dev; @@ -287,13 +502,16 @@ linsysfs_init(PFS_INIT_ARGS) root = pi->pi_root; /* /sys/class/... */ - scsi = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); - scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, NULL, 0); + class = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); + scsi = pfs_create_dir(class, "scsi_host", NULL, NULL, NULL, 0); + drm = pfs_create_dir(class, "drm", NULL, NULL, NULL, 0); - /* /sys/devices */ + /* /sys/dev/... */ + devdir = pfs_create_dir(root, "dev", NULL, NULL, NULL, 0); + chardev = pfs_create_dir(devdir, "char", NULL, NULL, NULL, 0); + + /* /sys/devices/... */ dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0); - - /* /sys/devices/pci0000:00 */ pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, NULL, 0); devclass = devclass_find("root"); @@ -302,7 +520,7 @@ linsysfs_init(PFS_INIT_ARGS) } dev = devclass_get_device(devclass, 0); - linsysfs_run_bus(dev, pci, scsi, "/pci0000:00", "0000"); + linsysfs_run_bus(dev, pci, scsi, chardev, drm, "/pci0000:00", "0000"); /* /sys/devices/system */ sys = pfs_create_dir(dir, "system", NULL, NULL, NULL, 0); diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index c66c37e0ccfa..f5dc9f438b7d 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -139,7 +139,7 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod goto done; /* - * XXX In between kern_open() and fget(), another process + * XXX In between kern_openat() and fget(), another process * having the same filedesc could use that fd without * checking below. */ diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 5bd2963507c4..66a96ab48437 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -319,7 +319,7 @@ struct l_statfs { #define LINUX_PROC_SUPER_MAGIC 0x9fa0L #define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */ #define LINUX_ZFS_SUPER_MAGIC 0x2FC12FC1 -#define LINUX_DEVFS_SUPER_MAGIC 0x1373L +#define LINUX_DEVFS_SUPER_MAGIC 0x1373L #define LINUX_SHMFS_MAGIC 0x01021994 static long diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c index 466c588157c5..2c3c259f297f 100644 --- a/sys/compat/linux/linux_util.c +++ b/sys/compat/linux/linux_util.c @@ -127,23 +127,51 @@ int linux_driver_get_major_minor(const char *node, int *major, int *minor) { struct device_element *de; + unsigned long devno; + size_t sz; if (node == NULL || major == NULL || minor == NULL) return 1; - if (strlen(node) > strlen("pts/") && - strncmp(node, "pts/", strlen("pts/")) == 0) { - unsigned long devno; - + sz = sizeof("pts/") - 1; + if (strncmp(node, "pts/", sz) == 0 && node[sz] != '\0') { /* * Linux checks major and minors of the slave device * to make sure it's a pty device, so let's make him * believe it is. */ - devno = strtoul(node + strlen("pts/"), NULL, 10); + devno = strtoul(node + sz, NULL, 10); *major = 136 + (devno / 256); *minor = devno % 256; + return (0); + } + sz = sizeof("dri/card") - 1; + if (strncmp(node, "dri/card", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("dri/controlD") - 1; + if (strncmp(node, "dri/controlD", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("dri/renderD") - 1; + if (strncmp(node, "dri/renderD", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("drm/") - 1; + if (strncmp(node, "drm/", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; return (0); } diff --git a/sys/compat/linuxkpi/common/include/asm/atomic-long.h b/sys/compat/linuxkpi/common/include/asm/atomic-long.h index 374f015e20b8..b0763f456b90 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic-long.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic-long.h @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ #ifndef _ATOMIC_LONG_H_ #define _ATOMIC_LONG_H_ -#include +#include #include #include @@ -54,13 +54,13 @@ atomic_long_add_return(long i, atomic_long_t *v) static inline void atomic_long_set(atomic_long_t *v, long i) { - atomic_store_rel_long(&v->counter, i); + WRITE_ONCE(v->counter, i); } static inline long atomic_long_read(atomic_long_t *v) { - return atomic_load_acq_long(&v->counter); + return READ_ONCE(v->counter); } static inline long diff --git a/sys/compat/linuxkpi/common/include/asm/atomic.h b/sys/compat/linuxkpi/common/include/asm/atomic.h index 4c3a1f2b560f..7f25319fce42 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic.h @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,9 +32,8 @@ #ifndef _ASM_ATOMIC_H_ #define _ASM_ATOMIC_H_ -#include +#include #include - #include #define ATOMIC_INIT(x) { .counter = (x) } @@ -73,7 +72,7 @@ atomic_sub_return(int i, atomic_t *v) static inline void atomic_set(atomic_t *v, int i) { - atomic_store_rel_int(&v->counter, i); + WRITE_ONCE(v->counter, i); } static inline void @@ -91,7 +90,7 @@ atomic_set_mask(unsigned int mask, atomic_t *v) static inline int atomic_read(const atomic_t *v) { - return atomic_load_acq_int(&__DECONST(atomic_t *, v)->counter); + return READ_ONCE(v->counter); } static inline int @@ -137,7 +136,7 @@ atomic_xchg(atomic_t *v, int i) #else int ret; for (;;) { - ret = atomic_load_acq_int(&v->counter); + ret = READ_ONCE(v->counter); if (atomic_cmpset_int(&v->counter, ret, i)) break; } @@ -153,7 +152,7 @@ atomic_cmpxchg(atomic_t *v, int old, int new) for (;;) { if (atomic_cmpset_int(&v->counter, old, new)) break; - ret = atomic_load_acq_int(&v->counter); + ret = READ_ONCE(v->counter); if (ret != old) break; } diff --git a/sys/compat/linuxkpi/common/include/asm/atomic64.h b/sys/compat/linuxkpi/common/include/asm/atomic64.h index 54eefb62739e..5cf6bcfb074e 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic64.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic64.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2016 Mellanox Technologies, Ltd. + * Copyright (c) 2016-2017 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +28,7 @@ #ifndef _ASM_ATOMIC64_H_ #define _ASM_ATOMIC64_H_ -#include +#include #include #include @@ -74,7 +74,7 @@ atomic64_set(atomic64_t *v, int64_t i) static inline int64_t atomic64_read(atomic64_t *v) { - return atomic_load_acq_64(&v->counter); + return READ_ONCE(v->counter); } static inline int64_t @@ -114,7 +114,7 @@ atomic64_xchg(atomic64_t *v, int64_t i) #else int64_t ret; for (;;) { - ret = atomic_load_acq_64(&v->counter); + ret = READ_ONCE(v->counter); if (atomic_cmpset_64(&v->counter, ret, i)) break; } @@ -130,7 +130,7 @@ atomic64_cmpxchg(atomic64_t *v, int64_t old, int64_t new) for (;;) { if (atomic_cmpset_64(&v->counter, old, new)) break; - ret = atomic_load_acq_64(&v->counter); + ret = READ_ONCE(v->counter); if (ret != old) break; } diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index 43e412c104b3..e3af17da0066 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitops.h +++ b/sys/compat/linuxkpi/common/include/linux/bitops.h @@ -269,8 +269,7 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size, atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i)) #define test_bit(i, a) \ - !!(atomic_load_acq_long(&((volatile unsigned long *)(a))[BIT_WORD(i)]) & \ - BIT_MASK(i)) + !!(READ_ONCE(((volatile unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i)) static inline int test_and_clear_bit(long bit, volatile unsigned long *var) diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h index 31ab194e5b74..04fc78df4913 100644 --- a/sys/compat/linuxkpi/common/include/linux/fs.h +++ b/sys/compat/linuxkpi/common/include/linux/fs.h @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -137,6 +137,7 @@ struct file_operations { ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long); + long (*compat_ioctl)(struct file *, unsigned int, unsigned long); int (*mmap)(struct file *, struct vm_area_struct *); int (*open)(struct inode *, struct file *); int (*release)(struct inode *, struct file *); @@ -157,7 +158,6 @@ struct file_operations { int (*readdir)(struct file *, void *, filldir_t); int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long); - long (*compat_ioctl)(struct file *, unsigned int, unsigned long); int (*flush)(struct file *, fl_owner_t id); int (*fsync)(struct file *, struct dentry *, int datasync); int (*aio_fsync)(struct kiocb *, int datasync); @@ -288,4 +288,25 @@ noop_llseek(struct linux_file *file, loff_t offset, int whence) return (file->_file->f_offset); } +/* Shared memory support */ +unsigned long linux_invalidate_mapping_pages(vm_object_t, pgoff_t, pgoff_t); +struct page *linux_shmem_read_mapping_page_gfp(vm_object_t, int, gfp_t); +struct linux_file *linux_shmem_file_setup(const char *, loff_t, unsigned long); +void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t); + +#define invalidate_mapping_pages(...) \ + linux_invalidate_mapping_pages(__VA_ARGS__) + +#define shmem_read_mapping_page(...) \ + linux_shmem_read_mapping_page_gfp(__VA_ARGS__, 0) + +#define shmem_read_mapping_page_gfp(...) \ + linux_shmem_read_mapping_page_gfp(__VA_ARGS__) + +#define shmem_file_setup(...) \ + linux_shmem_file_setup(__VA_ARGS__) + +#define shmem_truncate_range(...) \ + linux_shmem_truncate_range(__VA_ARGS__) + #endif /* _LINUX_FS_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/in6.h b/sys/compat/linuxkpi/common/include/linux/in6.h index ef012dd023dd..c72bfb6f0b88 100644 --- a/sys/compat/linuxkpi/common/include/linux/in6.h +++ b/sys/compat/linuxkpi/common/include/linux/in6.h @@ -31,8 +31,6 @@ #ifndef _LINUX_IN6_H_ #define _LINUX_IN6_H_ -#ifndef KLD_MODULE #include "opt_inet6.h" -#endif #endif /* _LINUX_IN6_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h index a5891947a60e..1958b7aef5cd 100644 --- a/sys/compat/linuxkpi/common/include/linux/io.h +++ b/sys/compat/linuxkpi/common/include/linux/io.h @@ -109,6 +109,13 @@ ioread16(const volatile void *addr) return *(const volatile uint16_t *)addr; } +#undef ioread16be +static inline uint16_t +ioread16be(const volatile void *addr) +{ + return be16toh(*(const volatile uint16_t *)addr); +} + #undef ioread32 static inline uint32_t ioread32(const volatile void *addr) diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h index c2ccb4cb96ad..a649c8c785f3 100644 --- a/sys/compat/linuxkpi/common/include/linux/mm.h +++ b/sys/compat/linuxkpi/common/include/linux/mm.h @@ -220,7 +220,6 @@ static inline void get_page(struct vm_page *page) { vm_page_lock(page); - vm_page_hold(page); vm_page_wire(page); vm_page_unlock(page); } @@ -245,7 +244,6 @@ put_page(struct vm_page *page) { vm_page_lock(page); vm_page_unwire(page, PQ_ACTIVE); - vm_page_unhold(page); vm_page_unlock(page); } diff --git a/sys/compat/linuxkpi/common/include/linux/random.h b/sys/compat/linuxkpi/common/include/linux/random.h index 28475ed2275a..04729319aaad 100644 --- a/sys/compat/linuxkpi/common/include/linux/random.h +++ b/sys/compat/linuxkpi/common/include/linux/random.h @@ -28,7 +28,8 @@ * * $FreeBSD$ */ -#ifndef _LINUX_RANDOM_H_ + +#ifndef _LINUX_RANDOM_H_ #define _LINUX_RANDOM_H_ #include @@ -37,8 +38,27 @@ static inline void get_random_bytes(void *buf, int nbytes) { + if (read_random(buf, nbytes) == 0) arc4rand(buf, nbytes, 0); } -#endif /* _LINUX_RANDOM_H_ */ +static inline u_int +get_random_int(void) +{ + u_int val; + + get_random_bytes(&val, sizeof(val)); + return (val); +} + +static inline u_long +get_random_long(void) +{ + u_long val; + + get_random_bytes(&val, sizeof(val)); + return (val); +} + +#endif /* _LINUX_RANDOM_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/workqueue.h b/sys/compat/linuxkpi/common/include/linux/workqueue.h index 6fab4845311f..152a526c4e14 100644 --- a/sys/compat/linuxkpi/common/include/linux/workqueue.h +++ b/sys/compat/linuxkpi/common/include/linux/workqueue.h @@ -215,6 +215,7 @@ extern struct workqueue_struct *system_power_efficient_wq; extern void linux_init_delayed_work(struct delayed_work *, work_func_t); extern void linux_work_fn(void *, int); +extern void linux_delayed_work_fn(void *, int); extern struct workqueue_struct *linux_create_workqueue_common(const char *, int); extern void linux_destroy_workqueue(struct workqueue_struct *); extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *); diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index ce2cf2e75a4a..46c232e89469 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -745,8 +745,6 @@ linux_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td) int error; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (0); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -879,8 +877,6 @@ linux_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, int error; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (ENXIO); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -906,7 +902,20 @@ linux_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, /* fetch user-space pointer */ data = *(void **)data; } - if (filp->f_op->unlocked_ioctl) +#if defined(__amd64__) + if (td->td_proc->p_elf_machine == EM_386) { + /* try the compat IOCTL handler first */ + if (filp->f_op->compat_ioctl != NULL) + error = -filp->f_op->compat_ioctl(filp, cmd, (u_long)data); + else + error = ENOTTY; + + /* fallback to the regular IOCTL handler, if any */ + if (error == ENOTTY && filp->f_op->unlocked_ioctl != NULL) + error = -filp->f_op->unlocked_ioctl(filp, cmd, (u_long)data); + } else +#endif + if (filp->f_op->unlocked_ioctl != NULL) error = -filp->f_op->unlocked_ioctl(filp, cmd, (u_long)data); else error = ENOTTY; @@ -935,8 +944,6 @@ linux_dev_read(struct cdev *dev, struct uio *uio, int ioflag) td = curthread; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (ENXIO); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -977,8 +984,6 @@ linux_dev_write(struct cdev *dev, struct uio *uio, int ioflag) td = curthread; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (ENXIO); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -1008,6 +1013,8 @@ linux_dev_write(struct cdev *dev, struct uio *uio, int ioflag) return (error); } +#define LINUX_POLL_TABLE_NORMAL ((poll_table *)1) + static int linux_dev_poll(struct cdev *dev, int events, struct thread *td) { @@ -1015,8 +1022,6 @@ linux_dev_poll(struct cdev *dev, int events, struct thread *td) struct file *file; int revents; - if (dev->si_drv1 == NULL) - goto error; if (devfs_get_cdevpriv((void **)&filp) != 0) goto error; @@ -1024,7 +1029,7 @@ linux_dev_poll(struct cdev *dev, int events, struct thread *td) filp->f_flags = file->f_flag; linux_set_current(td); if (filp->f_op->poll != NULL) - revents = filp->f_op->poll(filp, NULL) & events; + revents = filp->f_op->poll(filp, LINUX_POLL_TABLE_NORMAL) & events; else revents = 0; @@ -1081,7 +1086,9 @@ linux_poll_wait(struct linux_file *filp, wait_queue_head_t *wqh, poll_table *p) [LINUX_FWQ_STATE_READY] = LINUX_FWQ_STATE_QUEUED, }; - selrecord(curthread, &filp->f_selinfo); + /* check if we are called inside the select system call */ + if (p == LINUX_POLL_TABLE_NORMAL) + selrecord(curthread, &filp->f_selinfo); switch (linux_poll_wakeup_state(&filp->f_wait_queue.state, state)) { case LINUX_FWQ_STATE_INIT: @@ -1216,8 +1223,6 @@ linux_dev_kqfilter(struct cdev *dev, struct knote *kn) td = curthread; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (ENXIO); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -1268,8 +1273,6 @@ linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset, td = curthread; file = td->td_fpop; - if (dev->si_drv1 == NULL) - return (ENODEV); if ((error = devfs_get_cdevpriv((void **)&filp)) != 0) return (error); filp->f_flags = file->f_flag; @@ -1425,10 +1428,9 @@ linux_file_poll(struct file *file, int events, struct ucred *active_cred, filp = (struct linux_file *)file->f_data; filp->f_flags = file->f_flag; linux_set_current(td); - if (filp->f_op->poll != NULL) { - selrecord(td, &filp->f_selinfo); - revents = filp->f_op->poll(filp, NULL) & events; - } else + if (filp->f_op->poll != NULL) + revents = filp->f_op->poll(filp, LINUX_POLL_TABLE_NORMAL) & events; + else revents = 0; return (revents); diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c index ba58211232e7..2c474b86a820 100644 --- a/sys/compat/linuxkpi/common/src/linux_page.c +++ b/sys/compat/linuxkpi/common/src/linux_page.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #if defined(__amd64__) || defined(__aarch64__) || defined(__riscv) #define LINUXKPI_HAVE_DMAP @@ -208,6 +209,7 @@ linux_get_user_pages_internal(vm_map_t map, unsigned long start, int nr_pages, vm_page_lock(pg); vm_page_wire(pg); + vm_page_unhold(pg); vm_page_unlock(pg); } return (nr_pages); @@ -242,6 +244,7 @@ __get_user_pages_fast(unsigned long start, int nr_pages, int write, vm_page_lock(*mp); vm_page_wire(*mp); + vm_page_unhold(*mp); vm_page_unlock(*mp); if ((prot & VM_PROT_WRITE) != 0 && @@ -289,3 +292,104 @@ is_vmalloc_addr(const void *addr) { return (vtoslab((vm_offset_t)addr & ~UMA_SLAB_MASK) != NULL); } + +struct page * +linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex, gfp_t gfp) +{ + vm_page_t page; + int rv; + + if ((gfp & GFP_NOWAIT) != 0) + panic("GFP_NOWAIT is unimplemented"); + + VM_OBJECT_WLOCK(obj); + page = vm_page_grab(obj, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | + VM_ALLOC_WIRED); + if (page->valid != VM_PAGE_BITS_ALL) { + vm_page_xbusy(page); + if (vm_pager_has_page(obj, pindex, NULL, NULL)) { + rv = vm_pager_get_pages(obj, &page, 1, NULL, NULL); + if (rv != VM_PAGER_OK) { + vm_page_lock(page); + vm_page_unwire(page, PQ_NONE); + vm_page_free(page); + vm_page_unlock(page); + VM_OBJECT_WUNLOCK(obj); + return (ERR_PTR(-EINVAL)); + } + MPASS(page->valid == VM_PAGE_BITS_ALL); + } else { + pmap_zero_page(page); + page->valid = VM_PAGE_BITS_ALL; + page->dirty = 0; + } + vm_page_xunbusy(page); + } + VM_OBJECT_WUNLOCK(obj); + return (page); +} + +struct linux_file * +linux_shmem_file_setup(const char *name, loff_t size, unsigned long flags) +{ + struct fileobj { + struct linux_file file __aligned(sizeof(void *)); + struct vnode vnode __aligned(sizeof(void *)); + }; + struct fileobj *fileobj; + struct linux_file *filp; + struct vnode *vp; + int error; + + fileobj = kzalloc(sizeof(*fileobj), GFP_KERNEL); + if (fileobj == NULL) { + error = -ENOMEM; + goto err_0; + } + filp = &fileobj->file; + vp = &fileobj->vnode; + + filp->f_count = 1; + filp->f_vnode = vp; + filp->f_shmem = vm_pager_allocate(OBJT_DEFAULT, NULL, size, + VM_PROT_READ | VM_PROT_WRITE, 0, curthread->td_ucred); + if (filp->f_shmem == NULL) { + error = -ENOMEM; + goto err_1; + } + return (filp); +err_1: + kfree(filp); +err_0: + return (ERR_PTR(error)); +} + +static vm_ooffset_t +linux_invalidate_mapping_pages_sub(vm_object_t obj, vm_pindex_t start, + vm_pindex_t end, int flags) +{ + int start_count, end_count; + + VM_OBJECT_WLOCK(obj); + start_count = obj->resident_page_count; + vm_object_page_remove(obj, start, end, flags); + end_count = obj->resident_page_count; + VM_OBJECT_WUNLOCK(obj); + return (start_count - end_count); +} + +unsigned long +linux_invalidate_mapping_pages(vm_object_t obj, pgoff_t start, pgoff_t end) +{ + + return (linux_invalidate_mapping_pages_sub(obj, start, end, OBJPR_CLEANONLY)); +} + +void +linux_shmem_truncate_range(vm_object_t obj, loff_t lstart, loff_t lend) +{ + vm_pindex_t start = OFF_TO_IDX(lstart + PAGE_SIZE - 1); + vm_pindex_t end = OFF_TO_IDX(lend + 1); + + (void) linux_invalidate_mapping_pages_sub(obj, start, end, 0); +} diff --git a/sys/compat/linuxkpi/common/src/linux_schedule.c b/sys/compat/linuxkpi/common/src/linux_schedule.c index f438c314781d..97afc8c4867f 100644 --- a/sys/compat/linuxkpi/common/src/linux_schedule.c +++ b/sys/compat/linuxkpi/common/src/linux_schedule.c @@ -232,9 +232,7 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_queue_t *wq, int timeout, * Our wait queue entry is on the stack - make sure it doesn't * get swapped out while we sleep. */ -#ifndef NO_SWAPPING PHOLD(task->task_thread->td_proc); -#endif sleepq_lock(task); if (atomic_load_acq_int(&task->state) != TASK_WAKING) { ret = linux_add_to_sleepqueue(task, "wevent", timeout, state); @@ -242,9 +240,7 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_queue_t *wq, int timeout, sleepq_release(task); ret = linux_signal_pending_state(state, task) ? -ERESTARTSYS : 0; } -#ifndef NO_SWAPPING PRELE(task->task_thread->td_proc); -#endif PICKUP_GIANT(); diff --git a/sys/compat/linuxkpi/common/src/linux_tasklet.c b/sys/compat/linuxkpi/common/src/linux_tasklet.c index dbbb4d2cff44..5fe94553c9d3 100644 --- a/sys/compat/linuxkpi/common/src/linux_tasklet.c +++ b/sys/compat/linuxkpi/common/src/linux_tasklet.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -45,10 +46,10 @@ __FBSDID("$FreeBSD$"); atomic_cmpset_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev, old, new) #define TASKLET_ST_SET(ts, new) \ - atomic_store_rel_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev, new) + WRITE_ONCE(*(volatile uintptr_t *)&(ts)->entry.tqe_prev, new) #define TASKLET_ST_GET(ts) \ - atomic_load_acq_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev) + READ_ONCE(*(volatile uintptr_t *)&(ts)->entry.tqe_prev) struct tasklet_worker { struct mtx mtx; diff --git a/sys/compat/linuxkpi/common/src/linux_work.c b/sys/compat/linuxkpi/common/src/linux_work.c index ff971e3878c6..76d3a2225f0b 100644 --- a/sys/compat/linuxkpi/common/src/linux_work.c +++ b/sys/compat/linuxkpi/common/src/linux_work.c @@ -260,6 +260,23 @@ linux_work_fn(void *context, int pending) WQ_EXEC_UNLOCK(wq); } +void +linux_delayed_work_fn(void *context, int pending) +{ + struct delayed_work *dwork = context; + + /* + * Make sure the timer belonging to the delayed work gets + * drained before invoking the work function. Else the timer + * mutex may still be in use which can lead to use-after-free + * situations, because the work function might free the work + * structure before returning. + */ + callout_drain(&dwork->timer.callout); + + linux_work_fn(&dwork->work, pending); +} + static void linux_delayed_work_timer_fn(void *arg) { @@ -550,7 +567,8 @@ void linux_init_delayed_work(struct delayed_work *dwork, work_func_t func) { memset(dwork, 0, sizeof(*dwork)); - INIT_WORK(&dwork->work, func); + dwork->work.func = func; + TASK_INIT(&dwork->work.work_task, 0, linux_delayed_work_fn, dwork); mtx_init(&dwork->timer.mtx, spin_lock_name("lkpi-dwork"), NULL, MTX_DEF | MTX_NOWITNESS); callout_init_mtx(&dwork->timer.callout, &dwork->timer.mtx, 0); diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 55b22a22803e..fb9dcaaf7a8d 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -495,17 +495,21 @@ ndis_return(dobj, arg) KeReleaseSpinLock(&block->nmb_returnlock, irql); } -void -ndis_return_packet(struct mbuf *m, void *buf, void *arg) +static void +ndis_ext_free(struct mbuf *m) +{ + + return (ndis_return_packet(m->m_ext.ext_arg1)); +} + +void +ndis_return_packet(ndis_packet *p) { - ndis_packet *p; ndis_miniport_block *block; - if (arg == NULL) + if (p == NULL) return; - p = arg; - /* Decrement refcount. */ p->np_refcnt--; @@ -676,9 +680,8 @@ ndis_ptom(m0, p) return (ENOBUFS); } m->m_len = MmGetMdlByteCount(buf); - m->m_data = MmGetMdlVirtualAddress(buf); - MEXTADD(m, m->m_data, m->m_len, ndis_return_packet, - m->m_data, p, 0, EXT_NDIS); + m_extadd(m, MmGetMdlVirtualAddress(buf), m->m_len, + ndis_ext_free, p, NULL, 0, EXT_NDIS); p->np_refcnt++; totlen += m->m_len; diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h index 80b49207c25a..92e62a1fbdbc 100644 --- a/sys/compat/ndis/ndis_var.h +++ b/sys/compat/ndis/ndis_var.h @@ -1743,7 +1743,7 @@ extern int ndis_halt_nic(void *); extern int ndis_shutdown_nic(void *); extern int ndis_pnpevent_nic(void *, int); extern int ndis_init_nic(void *); -extern void ndis_return_packet(struct mbuf *, void *, void *); +extern void ndis_return_packet(ndis_packet *); extern int ndis_init_dma(void *); extern int ndis_destroy_dma(void *); extern int ndis_create_sysctls(void *); diff --git a/sys/conf/Makefile.arm b/sys/conf/Makefile.arm index 01eebf6f1bcd..53ff25ab239f 100644 --- a/sys/conf/Makefile.arm +++ b/sys/conf/Makefile.arm @@ -75,7 +75,7 @@ FILES_CPU_FUNC = \ $S/$M/$M/cpufunc_asm_pj4b.S $S/$M/$M/cpufunc_asm_armv6.S \ $S/$M/$M/cpufunc_asm_armv7.S -.if ${MACHINE_ARCH} != "armv6" && defined(KERNPHYSADDR) +.if ${MACHINE_ARCH:Marmv[67]*} == "" && defined(KERNPHYSADDR) KERNEL_EXTRA=trampoline KERNEL_EXTRA_INSTALL=kernel.gz.tramp trampoline: ${KERNEL_KO}.tramp diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 1e63b17c9163..00cec21bb96d 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -802,8 +802,8 @@ options NGATM_CCATM device mn # Munich32x/Falc54 Nx64kbit/sec cards. # Network stack virtualization. -#options VIMAGE -#options VNET_DEBUG # debug for VIMAGE +options VIMAGE +options VNET_DEBUG # debug for VIMAGE # # Network interfaces: @@ -2210,8 +2210,6 @@ device rtwnfw options MCLSHIFT=12 # mbuf cluster shift in bits, 12 == 4KB options MSIZE=512 # mbuf size in bytes -options LIBMBPOOL - # # Sound drivers # diff --git a/sys/conf/files b/sys/conf/files index 718855a94fa9..6c6ff2fc47fb 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -112,7 +112,6 @@ cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/mmc/mmc_xpt.c optional scbus mmccam cam/mmc/mmc_da.c optional scbus mmccam da -cam/mmc/mmc_sdio.c optional scbus mmccam cam/scsi/scsi_da.c optional da cam/scsi/scsi_low.c optional ncv | nsp | stg cam/scsi/scsi_pass.c optional pass @@ -229,6 +228,11 @@ cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c optional zfs compile-wi cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_get.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_iter.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}" @@ -268,6 +272,34 @@ cddl/contrib/opensolaris/uts/common/zmod/trees.c optional zfs compile-with "${ cddl/contrib/opensolaris/uts/common/zmod/zmod.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod_subr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zutil.c optional zfs compile-with "${ZFS_C}" +# zfs lua support +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbaselib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbitlib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcompat.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcorolib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldump.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstrlib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltablib.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltm.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.c optional zfs compile-with "${ZFS_C}" +cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.c optional zfs compile-with "${ZFS_C}" # dtrace specific cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \ warning "kernel contains CDDL licensed DTRACE" @@ -1395,7 +1427,7 @@ t4fw.fwo optional cxgbe \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ - dependency "$S/dev/cxgbe/firmware/t4fw-1.16.59.0.bin.uu" \ + dependency "$S/dev/cxgbe/firmware/t4fw-1.16.63.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t4fw.fw" @@ -1429,7 +1461,7 @@ t5fw.fwo optional cxgbe \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ - dependency "$S/dev/cxgbe/firmware/t5fw-1.16.59.0.bin.uu" \ + dependency "$S/dev/cxgbe/firmware/t5fw-1.16.63.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t5fw.fw" @@ -1463,7 +1495,7 @@ t6fw.fwo optional cxgbe \ no-implicit-rule \ clean "t6fw.fwo" t6fw.fw optional cxgbe \ - dependency "$S/dev/cxgbe/firmware/t6fw-1.16.59.0.bin.uu" \ + dependency "$S/dev/cxgbe/firmware/t6fw-1.16.63.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t6fw.fw" @@ -1582,6 +1614,7 @@ dev/ed/if_ed_rtl80x9.c optional ed dev/ed/if_ed_pccard.c optional ed pccard dev/ed/if_ed_pci.c optional ed pci dev/efidev/efidev.c optional efirt +dev/efidev/efirt.c optional efirt dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/em_txrx.c optional em \ @@ -1756,6 +1789,7 @@ dev/iicbus/ds1307.c optional ds1307 dev/iicbus/ds13rtc.c optional ds13rtc | ds133x | ds1374 dev/iicbus/ds1672.c optional ds1672 dev/iicbus/ds3231.c optional ds3231 +dev/iicbus/rtc8583.c optional rtc8583 dev/iicbus/icee.c optional icee dev/iicbus/if_ic.c optional ic dev/iicbus/iic.c optional iic @@ -1977,6 +2011,20 @@ iwm8000C.fw optional iwm8000Cfw | iwmfw \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8000C.fw" +iwm8265.fw optional iwm8265fw | iwmfw \ + dependency "$S/contrib/dev/iwm/iwm-8265-22.fw.uu" \ + compile-with "${NORMAL_FW}" \ + no-obj no-implicit-rule \ + clean "iwm8265.fw" +iwm8265fw.c optional iwm8265fw | iwmfw \ + compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8265.fw:iwm8265fw -miwm8265fw -c${.TARGET}" \ + no-implicit-rule before-depend local \ + clean "iwm8265fw.c" +iwm8265fw.fwo optional iwm8265fw | iwmfw \ + dependency "iwm8265.fw" \ + compile-with "${NORMAL_FWO}" \ + no-implicit-rule \ + clean "iwm8265fw.fwo" dev/iwn/if_iwn.c optional iwn iwn1000fw.c optional iwn1000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \ @@ -3783,7 +3831,6 @@ kern/subr_kdb.c standard kern/subr_kobj.c standard kern/subr_lock.c standard kern/subr_log.c standard -kern/subr_mbpool.c optional libmbpool kern/subr_mchain.c optional libmchain kern/subr_module.c standard kern/subr_msgbuf.c standard @@ -4800,6 +4847,7 @@ vm/swap_pager.c standard vm/uma_core.c standard vm/uma_dbg.c standard vm/memguard.c optional DEBUG_MEMGUARD +vm/vm_domain.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard @@ -4814,7 +4862,8 @@ vm/vm_pager.c standard vm/vm_phys.c standard vm/vm_radix.c standard vm/vm_reserv.c standard -vm/vm_domain.c standard +vm/vm_swapout.c optional !NO_SWAPPING +vm/vm_swapout_dummy.c optional NO_SWAPPING vm/vm_unix.c standard vm/vnode_pager.c standard xen/features.c optional xenhvm diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index dac143da6168..1707456ea07f 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -133,7 +133,7 @@ amd64/amd64/cpu_switch.S standard amd64/amd64/db_disasm.c optional ddb amd64/amd64/db_interface.c optional ddb amd64/amd64/db_trace.c optional ddb -amd64/amd64/efirt.c optional efirt +amd64/amd64/efirt_machdep.c optional efirt amd64/amd64/elf_machdep.c standard amd64/amd64/exception.S standard amd64/amd64/fpu.c standard @@ -182,6 +182,16 @@ aesni_wrap.o optional aesni \ crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | \ ipsec_support | netsmb +intel_sha1.o optional aesni \ + dependency "$S/crypto/aesni/intel_sha1.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ + no-implicit-rule \ + clean "intel_sha1.o" +intel_sha256.o optional aesni \ + dependency "$S/crypto/aesni/intel_sha256.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ + no-implicit-rule \ + clean "intel_sha256.o" crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock crypto/via/padlock_hash.c optional padlock diff --git a/sys/conf/files.arm b/sys/conf/files.arm index e4aacfc3c104..10c86e5ce4ac 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -25,8 +25,8 @@ arm/arm/blockio.S standard arm/arm/bus_space_asm_generic.S standard arm/arm/bus_space_base.c optional fdt arm/arm/bus_space_generic.c standard -arm/arm/busdma_machdep-v4.c optional !armv6 !ARM_USE_V6_BUSDMA -arm/arm/busdma_machdep-v6.c optional armv6 | ARM_USE_V6_BUSDMA +arm/arm/busdma_machdep-v4.c optional !armv7 !armv6 !ARM_USE_V6_BUSDMA +arm/arm/busdma_machdep-v6.c optional armv7 | armv6 | ARM_USE_V6_BUSDMA arm/arm/copystr.S standard arm/arm/cpufunc.c standard arm/arm/cpufunc_asm.S standard @@ -43,11 +43,12 @@ arm/arm/cpufunc_asm_sheeva.S optional cpu_arm9e arm/arm/cpufunc_asm_xscale.S optional cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_81342 arm/arm/cpufunc_asm_xscale_c3.S optional cpu_xscale_81342 arm/arm/cpuinfo.c standard -arm/arm/cpu_asm-v6.S optional armv6 +arm/arm/cpu_asm-v6.S optional armv7 | armv6 arm/arm/db_disasm.c optional ddb arm/arm/db_interface.c optional ddb arm/arm/db_trace.c optional ddb arm/arm/debug_monitor.c optional ddb armv6 +arm/arm/debug_monitor.c optional ddb armv7 arm/arm/disassem.c optional ddb arm/arm/dump_machdep.c standard arm/arm/elf_machdep.c standard @@ -60,14 +61,14 @@ arm/arm/gdb_machdep.c optional gdb arm/arm/generic_timer.c optional generic_timer arm/arm/gic.c optional gic arm/arm/gic_fdt.c optional gic fdt -arm/arm/identcpu-v4.c optional !armv6 -arm/arm/identcpu-v6.c optional armv6 +arm/arm/identcpu-v4.c optional !armv7 !armv6 +arm/arm/identcpu-v6.c optional armv7 | armv6 arm/arm/in_cksum.c optional inet | inet6 arm/arm/in_cksum_arm.S optional inet | inet6 arm/arm/intr.c optional !intrng kern/subr_intr.c optional intrng arm/arm/locore.S standard no-obj -arm/arm/hypervisor-stub.S optional armv6 +arm/arm/hypervisor-stub.S optional armv7 | armv6 arm/arm/machdep.c standard arm/arm/machdep_boot.c standard arm/arm/machdep_kdb.c standard @@ -85,9 +86,10 @@ arm/arm/pl310.c optional pl310 arm/arm/platform.c optional platform arm/arm/platform_if.m optional platform arm/arm/platform_pl310_if.m optional platform pl310 -arm/arm/pmap-v4.c optional !armv6 -arm/arm/pmap-v6.c optional armv6 +arm/arm/pmap-v4.c optional !armv7 !armv6 +arm/arm/pmap-v6.c optional armv7 | armv6 arm/arm/pmu.c optional pmu | fdt hwpmc +arm/arm/ptrace_machdep.c standard arm/arm/sc_machdep.c optional sc arm/arm/setcpsr.S standard arm/arm/setstack.s standard @@ -96,12 +98,12 @@ arm/arm/stdatomic.c standard \ compile-with "${NORMAL_C:N-Wmissing-prototypes}" arm/arm/support.S standard arm/arm/swtch.S standard -arm/arm/swtch-v4.S optional !armv6 -arm/arm/swtch-v6.S optional armv6 +arm/arm/swtch-v4.S optional !armv7 !armv6 +arm/arm/swtch-v6.S optional armv7 | armv6 arm/arm/sys_machdep.c standard arm/arm/syscall.c standard -arm/arm/trap-v4.c optional !armv6 -arm/arm/trap-v6.c optional armv6 +arm/arm/trap-v4.c optional !armv7 !armv6 +arm/arm/trap-v6.c optional armv7 | armv6 arm/arm/uio_machdep.c standard arm/arm/undefined.c standard arm/arm/unwind.c optional ddb | kdtrace_hooks @@ -127,6 +129,7 @@ dev/fdt/fdt_arm_platform.c optional platform fdt dev/hdmi/hdmi_if.m optional hdmi dev/hwpmc/hwpmc_arm.c optional hwpmc dev/hwpmc/hwpmc_armv7.c optional hwpmc armv6 +dev/hwpmc/hwpmc_armv7.c optional hwpmc armv7 dev/iicbus/twsi/twsi.c optional twsi dev/ofw/ofwpci.c optional fdt pci dev/pci/pci_host_generic.c optional pci_host_generic pci diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index eade07f5ffff..77d48f94ea74 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -43,6 +43,7 @@ arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt arm/allwinner/clkng/ccu_a64.c optional aw_ccu fdt arm/allwinner/clkng/ccu_h3.c optional aw_ccu fdt +arm/allwinner/clkng/ccu_sun8i_r.c optional aw_ccu fdt arm/allwinner/if_awg.c optional awg fdt arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt @@ -94,6 +95,7 @@ arm64/arm64/db_trace.c optional ddb arm64/arm64/debug_monitor.c optional ddb arm64/arm64/disassem.c optional ddb arm64/arm64/dump_machdep.c standard +arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/gicv3_its.c optional intrng fdt @@ -118,6 +120,7 @@ arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard +arm64/arm64/undefined.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 5e838cd182b4..bfb4bd3deb08 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -132,6 +132,16 @@ aesni_wrap.o optional aesni \ no-implicit-rule \ clean "aesni_wrap.o" crypto/des/arch/i386/des_enc.S optional crypto | ipsec | ipsec_support | netsmb +intel_sha1.o optional aesni \ + dependency "$S/crypto/aesni/intel_sha1.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ + no-implicit-rule \ + clean "intel_sha1.o" +intel_sha256.o optional aesni \ + dependency "$S/crypto/aesni/intel_sha256.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ + no-implicit-rule \ + clean "intel_sha256.o" crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock crypto/via/padlock_hash.c optional padlock diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index e6a3d367fd2e..932a2ae80c32 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -141,6 +141,7 @@ powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt powerpc/mpc85xx/ds1553_core.c optional ds1553 powerpc/mpc85xx/fsl_diu.c optional mpc85xx diu powerpc/mpc85xx/fsl_espi.c optional mpc85xx spibus +powerpc/mpc85xx/fsl_sata.c optional mpc85xx ata powerpc/mpc85xx/i2c.c optional iicbus fdt powerpc/mpc85xx/isa.c optional mpc85xx isa powerpc/mpc85xx/lbc.c optional mpc85xx diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index fa444e196000..204b8203d6e4 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -58,7 +58,6 @@ CWARNEXTRA?= -Wno-error=address \ -Wno-error=maybe-uninitialized \ -Wno-error=overflow \ -Wno-error=sequence-point \ - -Wno-error=strict-overflow \ -Wno-error=unused-but-set-variable .if ${COMPILER_VERSION} >= 60100 CWARNEXTRA+= -Wno-error=misleading-indentation \ @@ -185,9 +184,6 @@ CFLAGS.gcc+= -mcall-aixdesc .if ${MACHINE_CPUARCH} == "mips" CFLAGS+= -msoft-float INLINE_LIMIT?= 8000 -.if ${MACHINE_ARCH:Mmips*hf} != "" -CFLAGS+= -DCPU_HAVEFPU -.endif .endif # @@ -260,6 +256,7 @@ LD_EMULATION_amd64=elf_x86_64_fbsd LD_EMULATION_arm=armelf_fbsd LD_EMULATION_armeb=armelfb_fbsd LD_EMULATION_armv6=armelf_fbsd +LD_EMULATION_armv7=armelf_fbsd LD_EMULATION_i386=elf_i386_fbsd LD_EMULATION_mips= elf32btsmip_fbsd LD_EMULATION_mips64= elf64btsmip_fbsd diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index 72420eebac19..ba271be28865 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -62,7 +62,7 @@ __DEFAULT_NO_OPTIONS = \ # Things that don't work based on the CPU .if ${MACHINE_CPUARCH} == "arm" -. if ${MACHINE_ARCH:Marmv6*} == "" +. if ${MACHINE_ARCH:Marmv[67]*} == "" BROKEN_OPTIONS+= CDDL ZFS . endif .endif diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 74a85bbbd02e..853fad4f672a 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -24,11 +24,11 @@ _srcconf_included_: .MAKE.MODE+= curdirOk=yes .endif -.if defined(NO_OBJ) || ${MK_AUTO_OBJ} == "yes" -NO_OBJ= t +.if defined(NO_OBJWALK) || ${MK_AUTO_OBJ} == "yes" +NO_OBJWALK= t NO_MODULES_OBJ= t .endif -.if !defined(NO_OBJ) +.if !defined(NO_OBJWALK) _obj= obj .endif @@ -139,7 +139,11 @@ CDDL_CFLAGS+= -include $S/cddl/compat/opensolaris/sys/debug_compat.h CDDL_C= ${CC} -c ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC} # Special flags for managing the compat compiles for ZFS -ZFS_CFLAGS= -DBUILDING_ZFS -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs -I$S/cddl/contrib/opensolaris/uts/common/zmod -I$S/cddl/contrib/opensolaris/common/zfs ${CDDL_CFLAGS} +ZFS_CFLAGS= -DBUILDING_ZFS -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs +ZFS_CFLAGS+= -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs/lua +ZFS_CFLAGS+= -I$S/cddl/contrib/opensolaris/uts/common/zmod +ZFS_CFLAGS+= -I$S/cddl/contrib/opensolaris/common/zfs +ZFS_CFLAGS+= ${CDDL_CFLAGS} ZFS_ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${ZFS_CFLAGS} ZFS_C= ${CC} -c ${ZFS_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC} ZFS_S= ${CC} -c ${ZFS_ASM_CFLAGS} ${WERROR} ${.IMPSRC} @@ -252,6 +256,7 @@ EMBEDFS_ARCH.${MACHINE_ARCH}!= sed -n '/OUTPUT_ARCH/s/.*(\(.*\)).*/\1/p' ${LDSCR EMBEDFS_FORMAT.arm?= elf32-littlearm EMBEDFS_FORMAT.armv6?= elf32-littlearm +EMBEDFS_FORMAT.armv7?= elf32-littlearm EMBEDFS_FORMAT.aarch64?= elf64-littleaarch64 EMBEDFS_FORMAT.mips?= elf32-tradbigmips EMBEDFS_FORMAT.mipsel?= elf32-tradlittlemips diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index e2e63032ef19..6c391e2b1d14 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -44,6 +44,10 @@ # # DESTDIR The tree where the module gets installed. [not set] # +# KERNBUILDDIR +# Set to the location of the kernel build directory where +# the opt_*.h files, .o's and kernel winds up. +# # +++ targets +++ # # install: diff --git a/sys/conf/makeLINT.mk b/sys/conf/makeLINT.mk index 04dfcee05b9c..65ab59579aac 100644 --- a/sys/conf/makeLINT.mk +++ b/sys/conf/makeLINT.mk @@ -6,16 +6,13 @@ all: clean: rm -f LINT .if ${TARGET} == "amd64" || ${TARGET} == "i386" - rm -f LINT-VIMAGE LINT-NOINET LINT-NOINET6 LINT-NOIP + rm -f LINT-NOINET LINT-NOINET6 LINT-NOIP .endif NOTES= ../../conf/NOTES NOTES LINT: ${NOTES} ../../conf/makeLINT.sed cat ${NOTES} | sed -E -n -f ../../conf/makeLINT.sed > ${.TARGET} .if ${TARGET} == "amd64" || ${TARGET} == "i386" - echo "include ${.TARGET}" > ${.TARGET}-VIMAGE - echo "ident ${.TARGET}-VIMAGE" >> ${.TARGET}-VIMAGE - echo "options VIMAGE" >> ${.TARGET}-VIMAGE echo "include ${.TARGET}" > ${.TARGET}-NOINET echo "ident ${.TARGET}-NOINET" >> ${.TARGET}-NOINET echo 'makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="' >> ${.TARGET}-NOINET diff --git a/sys/conf/options b/sys/conf/options index 9e71487705ac..224d06792b94 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -432,7 +432,6 @@ IPSEC_SUPPORT opt_ipsec.h IPSTEALTH KRPC LIBALIAS -LIBMBPOOL LIBMCHAIN MBUF_PROFILING MBUF_STRESS_TEST diff --git a/sys/conf/options.arm b/sys/conf/options.arm index f3ab2fc0214e..91ca74b8edbe 100644 --- a/sys/conf/options.arm +++ b/sys/conf/options.arm @@ -1,5 +1,6 @@ #$FreeBSD$ ARMV6 opt_global.h +ARMV7 opt_global.h ARM_CACHE_LOCK_ENABLE opt_global.h ARM_KERN_DIRECTMAP opt_vm.h ARM_L2_PIPT opt_global.h diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64 index 944d99e33272..79e0befefb08 100644 --- a/sys/conf/options.arm64 +++ b/sys/conf/options.arm64 @@ -7,6 +7,10 @@ SOCDEV_VA opt_global.h THUNDERX_PASS_1_1_ERRATA opt_global.h VFP opt_global.h +# EFI Runtime services support +EFIRT opt_efirt.h + +# Devices DEV_PSCI opt_platform.h # SoC Support diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 92e830ba341b..3cbeba993528 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -39,7 +39,6 @@ CPU_PROAPTIV opt_global.h CPU_MIPS32 opt_global.h CPU_MIPS64 opt_global.h CPU_SENTRY5 opt_global.h -CPU_HAVEFPU opt_global.h CPU_SB1 opt_global.h CPU_CNMIPS opt_global.h CPU_RMI opt_global.h diff --git a/sys/contrib/cloudabi/cloudabi32_types.h b/sys/contrib/cloudabi/cloudabi32_types.h index 95dac188e4fd..58f4d7cb9bb0 100644 --- a/sys/contrib/cloudabi/cloudabi32_types.h +++ b/sys/contrib/cloudabi/cloudabi32_types.h @@ -156,7 +156,7 @@ _Static_assert(_Alignof(cloudabi32_send_out_t) == 4, "Incorrect layout"); typedef struct { _Alignas(8) cloudabi_userdata_t userdata; - _Alignas(2) cloudabi_subflags_t flags; + _Alignas(2) uint16_t unused; _Alignas(1) cloudabi_eventtype_t type; union { struct { @@ -186,7 +186,7 @@ typedef struct { }; } cloudabi32_subscription_t; _Static_assert(offsetof(cloudabi32_subscription_t, userdata) == 0, "Incorrect layout"); -_Static_assert(offsetof(cloudabi32_subscription_t, flags) == 8, "Incorrect layout"); +_Static_assert(offsetof(cloudabi32_subscription_t, unused) == 8, "Incorrect layout"); _Static_assert(offsetof(cloudabi32_subscription_t, type) == 10, "Incorrect layout"); _Static_assert(offsetof(cloudabi32_subscription_t, clock.identifier) == 16, "Incorrect layout"); _Static_assert(offsetof(cloudabi32_subscription_t, clock.clock_id) == 24, "Incorrect layout"); diff --git a/sys/contrib/cloudabi/cloudabi64_types.h b/sys/contrib/cloudabi/cloudabi64_types.h index bb624cf736c2..f45ad81e8b38 100644 --- a/sys/contrib/cloudabi/cloudabi64_types.h +++ b/sys/contrib/cloudabi/cloudabi64_types.h @@ -156,7 +156,7 @@ _Static_assert(_Alignof(cloudabi64_send_out_t) == 8, "Incorrect layout"); typedef struct { _Alignas(8) cloudabi_userdata_t userdata; - _Alignas(2) cloudabi_subflags_t flags; + _Alignas(2) uint16_t unused; _Alignas(1) cloudabi_eventtype_t type; union { struct { @@ -186,7 +186,7 @@ typedef struct { }; } cloudabi64_subscription_t; _Static_assert(offsetof(cloudabi64_subscription_t, userdata) == 0, "Incorrect layout"); -_Static_assert(offsetof(cloudabi64_subscription_t, flags) == 8, "Incorrect layout"); +_Static_assert(offsetof(cloudabi64_subscription_t, unused) == 8, "Incorrect layout"); _Static_assert(offsetof(cloudabi64_subscription_t, type) == 10, "Incorrect layout"); _Static_assert(offsetof(cloudabi64_subscription_t, clock.identifier) == 16, "Incorrect layout"); _Static_assert(offsetof(cloudabi64_subscription_t, clock.clock_id) == 24, "Incorrect layout"); diff --git a/sys/contrib/cloudabi/cloudabi_types_common.h b/sys/contrib/cloudabi/cloudabi_types_common.h index 2f0c03d8da01..1c403b00d330 100644 --- a/sys/contrib/cloudabi/cloudabi_types_common.h +++ b/sys/contrib/cloudabi/cloudabi_types_common.h @@ -59,8 +59,6 @@ typedef uint32_t cloudabi_auxtype_t; #define CLOUDABI_AT_SYSINFO_EHDR 262 #define CLOUDABI_AT_TID 261 -typedef uint32_t cloudabi_backlog_t; - typedef uint32_t cloudabi_clockid_t; #define CLOUDABI_CLOCK_MONOTONIC 1 #define CLOUDABI_CLOCK_PROCESS_CPUTIME_ID 2 @@ -191,7 +189,6 @@ typedef uint8_t cloudabi_filetype_t; #define CLOUDABI_FILETYPE_BLOCK_DEVICE 16 #define CLOUDABI_FILETYPE_CHARACTER_DEVICE 17 #define CLOUDABI_FILETYPE_DIRECTORY 32 -#define CLOUDABI_FILETYPE_POLL 64 #define CLOUDABI_FILETYPE_PROCESS 80 #define CLOUDABI_FILETYPE_REGULAR_FILE 96 #define CLOUDABI_FILETYPE_SHARED_MEMORY 112 @@ -276,9 +273,7 @@ typedef uint64_t cloudabi_rights_t; #define CLOUDABI_RIGHT_MEM_MAP 0x0000000004000000 #define CLOUDABI_RIGHT_MEM_MAP_EXEC 0x0000000008000000 #define CLOUDABI_RIGHT_POLL_FD_READWRITE 0x0000000010000000 -#define CLOUDABI_RIGHT_POLL_MODIFY 0x0000000020000000 #define CLOUDABI_RIGHT_POLL_PROC_TERMINATE 0x0000000040000000 -#define CLOUDABI_RIGHT_POLL_WAIT 0x0000000080000000 #define CLOUDABI_RIGHT_PROC_EXEC 0x0000000100000000 #define CLOUDABI_RIGHT_SOCK_SHUTDOWN 0x0000008000000000 @@ -327,14 +322,6 @@ typedef uint8_t cloudabi_signal_t; typedef uint16_t cloudabi_subclockflags_t; #define CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME 0x0001 -typedef uint16_t cloudabi_subflags_t; -#define CLOUDABI_SUBSCRIPTION_ADD 0x0001 -#define CLOUDABI_SUBSCRIPTION_CLEAR 0x0002 -#define CLOUDABI_SUBSCRIPTION_DELETE 0x0004 -#define CLOUDABI_SUBSCRIPTION_DISABLE 0x0008 -#define CLOUDABI_SUBSCRIPTION_ENABLE 0x0010 -#define CLOUDABI_SUBSCRIPTION_ONESHOT 0x0020 - typedef uint16_t cloudabi_subrwflags_t; #define CLOUDABI_SUBSCRIPTION_FD_READWRITE_POLL 0x0001 diff --git a/sys/contrib/cloudabi/cloudabi_vdso_aarch64.S b/sys/contrib/cloudabi/cloudabi_vdso_aarch64.S index 7c98e5b3f005..eeccd74b93e1 100644 --- a/sys/contrib/cloudabi/cloudabi_vdso_aarch64.S +++ b/sys/contrib/cloudabi/cloudabi_vdso_aarch64.S @@ -353,32 +353,20 @@ ENTRY(cloudabi_sys_poll) ret END(cloudabi_sys_poll) -ENTRY(cloudabi_sys_poll_fd) - str x6, [sp, #-8] - mov w8, #38 - svc #0 - ldr x2, [sp, #-8] - b.cs 1f - str x0, [x2] - mov w0, wzr -1: - ret -END(cloudabi_sys_poll_fd) - ENTRY(cloudabi_sys_proc_exec) - mov w8, #39 + mov w8, #38 svc #0 ret END(cloudabi_sys_proc_exec) ENTRY(cloudabi_sys_proc_exit) - mov w8, #40 + mov w8, #39 svc #0 END(cloudabi_sys_proc_exit) ENTRY(cloudabi_sys_proc_fork) stp x0, x1, [sp, #-16] - mov w8, #41 + mov w8, #40 svc #0 ldp x2, x3, [sp, #-16] b.cs 1f @@ -390,38 +378,38 @@ ENTRY(cloudabi_sys_proc_fork) END(cloudabi_sys_proc_fork) ENTRY(cloudabi_sys_proc_raise) - mov w8, #42 + mov w8, #41 svc #0 ret END(cloudabi_sys_proc_raise) ENTRY(cloudabi_sys_random_get) - mov w8, #43 + mov w8, #42 svc #0 ret END(cloudabi_sys_random_get) ENTRY(cloudabi_sys_sock_recv) - mov w8, #44 + mov w8, #43 svc #0 ret END(cloudabi_sys_sock_recv) ENTRY(cloudabi_sys_sock_send) - mov w8, #45 + mov w8, #44 svc #0 ret END(cloudabi_sys_sock_send) ENTRY(cloudabi_sys_sock_shutdown) - mov w8, #46 + mov w8, #45 svc #0 ret END(cloudabi_sys_sock_shutdown) ENTRY(cloudabi_sys_thread_create) str x1, [sp, #-8] - mov w8, #47 + mov w8, #46 svc #0 ldr x2, [sp, #-8] b.cs 1f @@ -432,12 +420,12 @@ ENTRY(cloudabi_sys_thread_create) END(cloudabi_sys_thread_create) ENTRY(cloudabi_sys_thread_exit) - mov w8, #48 + mov w8, #47 svc #0 END(cloudabi_sys_thread_exit) ENTRY(cloudabi_sys_thread_yield) - mov w8, #49 + mov w8, #48 svc #0 ret END(cloudabi_sys_thread_yield) diff --git a/sys/contrib/cloudabi/cloudabi_vdso_armv6.S b/sys/contrib/cloudabi/cloudabi_vdso_armv6.S index 7ca7a39419d6..36aa8f018a3d 100644 --- a/sys/contrib/cloudabi/cloudabi_vdso_armv6.S +++ b/sys/contrib/cloudabi/cloudabi_vdso_armv6.S @@ -320,30 +320,21 @@ ENTRY(cloudabi_sys_poll) bx lr END(cloudabi_sys_poll) -ENTRY(cloudabi_sys_poll_fd) - mov ip, #38 - swi 0 - ldrcc r2, [sp, #8] - strcc r0, [r2] - movcc r0, $0 - bx lr -END(cloudabi_sys_poll_fd) - ENTRY(cloudabi_sys_proc_exec) - mov ip, #39 + mov ip, #38 swi 0 bx lr END(cloudabi_sys_proc_exec) ENTRY(cloudabi_sys_proc_exit) - mov ip, #40 + mov ip, #39 swi 0 END(cloudabi_sys_proc_exit) ENTRY(cloudabi_sys_proc_fork) str r0, [sp, #-4] str r1, [sp, #-8] - mov ip, #41 + mov ip, #40 swi 0 ldrcc r2, [sp, #-4] ldrcc r3, [sp, #-8] @@ -354,38 +345,38 @@ ENTRY(cloudabi_sys_proc_fork) END(cloudabi_sys_proc_fork) ENTRY(cloudabi_sys_proc_raise) - mov ip, #42 + mov ip, #41 swi 0 bx lr END(cloudabi_sys_proc_raise) ENTRY(cloudabi_sys_random_get) - mov ip, #43 + mov ip, #42 swi 0 bx lr END(cloudabi_sys_random_get) ENTRY(cloudabi_sys_sock_recv) - mov ip, #44 + mov ip, #43 swi 0 bx lr END(cloudabi_sys_sock_recv) ENTRY(cloudabi_sys_sock_send) - mov ip, #45 + mov ip, #44 swi 0 bx lr END(cloudabi_sys_sock_send) ENTRY(cloudabi_sys_sock_shutdown) - mov ip, #46 + mov ip, #45 swi 0 bx lr END(cloudabi_sys_sock_shutdown) ENTRY(cloudabi_sys_thread_create) str r1, [sp, #-4] - mov ip, #47 + mov ip, #46 swi 0 ldrcc r2, [sp, #-4] strcc r0, [r2] @@ -394,12 +385,12 @@ ENTRY(cloudabi_sys_thread_create) END(cloudabi_sys_thread_create) ENTRY(cloudabi_sys_thread_exit) - mov ip, #48 + mov ip, #47 swi 0 END(cloudabi_sys_thread_exit) ENTRY(cloudabi_sys_thread_yield) - mov ip, #49 + mov ip, #48 swi 0 bx lr END(cloudabi_sys_thread_yield) diff --git a/sys/contrib/cloudabi/cloudabi_vdso_i686.S b/sys/contrib/cloudabi/cloudabi_vdso_i686.S index 135ea8d55bf1..6180ce90e82a 100644 --- a/sys/contrib/cloudabi/cloudabi_vdso_i686.S +++ b/sys/contrib/cloudabi/cloudabi_vdso_i686.S @@ -342,30 +342,19 @@ ENTRY(cloudabi_sys_poll) ret END(cloudabi_sys_poll) -ENTRY(cloudabi_sys_poll_fd) - mov $38, %eax - int $0x80 - jc 1f - mov 28(%esp), %ecx - mov %eax, (%ecx) - xor %eax, %eax -1: - ret -END(cloudabi_sys_poll_fd) - ENTRY(cloudabi_sys_proc_exec) - mov $39, %eax + mov $38, %eax int $0x80 ret END(cloudabi_sys_proc_exec) ENTRY(cloudabi_sys_proc_exit) - mov $40, %eax + mov $39, %eax int $0x80 END(cloudabi_sys_proc_exit) ENTRY(cloudabi_sys_proc_fork) - mov $41, %eax + mov $40, %eax int $0x80 jc 1f mov 4(%esp), %ecx @@ -378,37 +367,37 @@ ENTRY(cloudabi_sys_proc_fork) END(cloudabi_sys_proc_fork) ENTRY(cloudabi_sys_proc_raise) - mov $42, %eax + mov $41, %eax int $0x80 ret END(cloudabi_sys_proc_raise) ENTRY(cloudabi_sys_random_get) - mov $43, %eax + mov $42, %eax int $0x80 ret END(cloudabi_sys_random_get) ENTRY(cloudabi_sys_sock_recv) - mov $44, %eax + mov $43, %eax int $0x80 ret END(cloudabi_sys_sock_recv) ENTRY(cloudabi_sys_sock_send) - mov $45, %eax + mov $44, %eax int $0x80 ret END(cloudabi_sys_sock_send) ENTRY(cloudabi_sys_sock_shutdown) - mov $46, %eax + mov $45, %eax int $0x80 ret END(cloudabi_sys_sock_shutdown) ENTRY(cloudabi_sys_thread_create) - mov $47, %eax + mov $46, %eax int $0x80 jc 1f mov 8(%esp), %ecx @@ -419,12 +408,12 @@ ENTRY(cloudabi_sys_thread_create) END(cloudabi_sys_thread_create) ENTRY(cloudabi_sys_thread_exit) - mov $48, %eax + mov $47, %eax int $0x80 END(cloudabi_sys_thread_exit) ENTRY(cloudabi_sys_thread_yield) - mov $49, %eax + mov $48, %eax int $0x80 ret END(cloudabi_sys_thread_yield) diff --git a/sys/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S b/sys/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S index 009f928d71e5..a64cf070a529 100644 --- a/sys/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S +++ b/sys/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S @@ -873,40 +873,6 @@ ENTRY(cloudabi_sys_poll) ret END(cloudabi_sys_poll) -ENTRY(cloudabi_sys_poll_fd) - push %ebp - mov %esp, %ebp - mov 8(%ebp), %ecx - mov %ecx, -48(%ebp) - mov 12(%ebp), %ecx - mov %ecx, -40(%ebp) - movl $0, -36(%ebp) - mov 16(%ebp), %ecx - mov %ecx, -32(%ebp) - movl $0, -28(%ebp) - mov 20(%ebp), %ecx - mov %ecx, -24(%ebp) - movl $0, -20(%ebp) - mov 24(%ebp), %ecx - mov %ecx, -16(%ebp) - movl $0, -12(%ebp) - mov 28(%ebp), %ecx - mov %ecx, -8(%ebp) - movl $0, -4(%ebp) - mov $38, %eax - mov %ebp, %ecx - sub $48, %ecx - int $0x80 - test %eax, %eax - jnz 1f - mov 32(%ebp), %ecx - mov -48(%ebp), %edx - mov %edx, 0(%ecx) -1: - pop %ebp - ret -END(cloudabi_sys_poll_fd) - ENTRY(cloudabi_sys_proc_exec) push %ebp mov %esp, %ebp @@ -924,7 +890,7 @@ ENTRY(cloudabi_sys_proc_exec) mov 24(%ebp), %ecx mov %ecx, -8(%ebp) movl $0, -4(%ebp) - mov $39, %eax + mov $38, %eax mov %ebp, %ecx sub $40, %ecx int $0x80 @@ -937,7 +903,7 @@ ENTRY(cloudabi_sys_proc_exit) mov %esp, %ebp mov 8(%ebp), %ecx mov %ecx, -16(%ebp) - mov $40, %eax + mov $39, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -946,7 +912,7 @@ END(cloudabi_sys_proc_exit) ENTRY(cloudabi_sys_proc_fork) push %ebp mov %esp, %ebp - mov $41, %eax + mov $40, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -968,7 +934,7 @@ ENTRY(cloudabi_sys_proc_raise) mov %esp, %ebp mov 8(%ebp), %ecx mov %ecx, -16(%ebp) - mov $42, %eax + mov $41, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -985,7 +951,7 @@ ENTRY(cloudabi_sys_random_get) mov 12(%ebp), %ecx mov %ecx, -8(%ebp) movl $0, -4(%ebp) - mov $43, %eax + mov $42, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -1004,7 +970,7 @@ ENTRY(cloudabi_sys_sock_recv) mov 16(%ebp), %ecx mov %ecx, -8(%ebp) movl $0, -4(%ebp) - mov $44, %eax + mov $43, %eax mov %ebp, %ecx sub $24, %ecx int $0x80 @@ -1023,7 +989,7 @@ ENTRY(cloudabi_sys_sock_send) mov 16(%ebp), %ecx mov %ecx, -8(%ebp) movl $0, -4(%ebp) - mov $45, %eax + mov $44, %eax mov %ebp, %ecx sub $24, %ecx int $0x80 @@ -1038,7 +1004,7 @@ ENTRY(cloudabi_sys_sock_shutdown) mov %ecx, -16(%ebp) mov 12(%ebp), %ecx mov %ecx, -8(%ebp) - mov $46, %eax + mov $45, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -1052,7 +1018,7 @@ ENTRY(cloudabi_sys_thread_create) mov 8(%ebp), %ecx mov %ecx, -16(%ebp) movl $0, -12(%ebp) - mov $47, %eax + mov $46, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -1074,7 +1040,7 @@ ENTRY(cloudabi_sys_thread_exit) movl $0, -12(%ebp) mov 12(%ebp), %ecx mov %ecx, -8(%ebp) - mov $48, %eax + mov $47, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 @@ -1083,7 +1049,7 @@ END(cloudabi_sys_thread_exit) ENTRY(cloudabi_sys_thread_yield) push %ebp mov %esp, %ebp - mov $49, %eax + mov $48, %eax mov %ebp, %ecx sub $16, %ecx int $0x80 diff --git a/sys/contrib/cloudabi/cloudabi_vdso_x86_64.S b/sys/contrib/cloudabi/cloudabi_vdso_x86_64.S index 217bd1cbea0a..4703597f7a62 100644 --- a/sys/contrib/cloudabi/cloudabi_vdso_x86_64.S +++ b/sys/contrib/cloudabi/cloudabi_vdso_x86_64.S @@ -368,34 +368,22 @@ ENTRY(cloudabi_sys_poll) ret END(cloudabi_sys_poll) -ENTRY(cloudabi_sys_poll_fd) - mov %rcx, %r10 - mov $38, %eax - syscall - jc 1f - mov 8(%rsp), %rcx - mov %rax, (%rcx) - xor %eax, %eax -1: - ret -END(cloudabi_sys_poll_fd) - ENTRY(cloudabi_sys_proc_exec) mov %rcx, %r10 - mov $39, %eax + mov $38, %eax syscall ret END(cloudabi_sys_proc_exec) ENTRY(cloudabi_sys_proc_exit) - mov $40, %eax + mov $39, %eax syscall END(cloudabi_sys_proc_exit) ENTRY(cloudabi_sys_proc_fork) push %rdi push %rsi - mov $41, %eax + mov $40, %eax syscall pop %rsi pop %rcx @@ -408,38 +396,38 @@ ENTRY(cloudabi_sys_proc_fork) END(cloudabi_sys_proc_fork) ENTRY(cloudabi_sys_proc_raise) - mov $42, %eax + mov $41, %eax syscall ret END(cloudabi_sys_proc_raise) ENTRY(cloudabi_sys_random_get) - mov $43, %eax + mov $42, %eax syscall ret END(cloudabi_sys_random_get) ENTRY(cloudabi_sys_sock_recv) - mov $44, %eax + mov $43, %eax syscall ret END(cloudabi_sys_sock_recv) ENTRY(cloudabi_sys_sock_send) - mov $45, %eax + mov $44, %eax syscall ret END(cloudabi_sys_sock_send) ENTRY(cloudabi_sys_sock_shutdown) - mov $46, %eax + mov $45, %eax syscall ret END(cloudabi_sys_sock_shutdown) ENTRY(cloudabi_sys_thread_create) push %rsi - mov $47, %eax + mov $46, %eax syscall pop %rcx jc 1f @@ -450,12 +438,12 @@ ENTRY(cloudabi_sys_thread_create) END(cloudabi_sys_thread_create) ENTRY(cloudabi_sys_thread_exit) - mov $48, %eax + mov $47, %eax syscall END(cloudabi_sys_thread_exit) ENTRY(cloudabi_sys_thread_yield) - mov $49, %eax + mov $48, %eax syscall ret END(cloudabi_sys_thread_yield) diff --git a/sys/contrib/cloudabi/syscalls32.master b/sys/contrib/cloudabi/syscalls32.master index 6ed39ec7ed98..0d6eb94fb0d3 100644 --- a/sys/contrib/cloudabi/syscalls32.master +++ b/sys/contrib/cloudabi/syscalls32.master @@ -231,52 +231,44 @@ cloudabi32_event_t *out, \ size_t nsubscriptions); } -38 AUE_NULL STD { size_t cloudabi32_sys_poll_fd( \ - cloudabi_fd_t fd, \ - const cloudabi32_subscription_t *in, \ - size_t in_len, \ - cloudabi32_event_t *out, \ - size_t out_len, \ - const cloudabi32_subscription_t *timeout); } - -39 AUE_NULL STD { void cloudabi_sys_proc_exec( \ +38 AUE_NULL STD { void cloudabi_sys_proc_exec( \ cloudabi_fd_t fd, \ const void *data, \ size_t data_len, \ const cloudabi_fd_t *fds, \ size_t fds_len); } -40 AUE_NULL STD { void cloudabi_sys_proc_exit( \ +39 AUE_NULL STD { void cloudabi_sys_proc_exit( \ cloudabi_exitcode_t rval); } -41 AUE_NULL STD { void cloudabi_sys_proc_fork(); } +40 AUE_NULL STD { void cloudabi_sys_proc_fork(); } -42 AUE_NULL STD { void cloudabi_sys_proc_raise( \ +41 AUE_NULL STD { void cloudabi_sys_proc_raise( \ cloudabi_signal_t sig); } -43 AUE_NULL STD { void cloudabi_sys_random_get( \ +42 AUE_NULL STD { void cloudabi_sys_random_get( \ void *buf, \ size_t buf_len); } -44 AUE_NULL STD { void cloudabi32_sys_sock_recv( \ +43 AUE_NULL STD { void cloudabi32_sys_sock_recv( \ cloudabi_fd_t sock, \ const cloudabi32_recv_in_t *in, \ cloudabi32_recv_out_t *out); } -45 AUE_NULL STD { void cloudabi32_sys_sock_send( \ +44 AUE_NULL STD { void cloudabi32_sys_sock_send( \ cloudabi_fd_t sock, \ const cloudabi32_send_in_t *in, \ cloudabi32_send_out_t *out); } -46 AUE_NULL STD { void cloudabi_sys_sock_shutdown( \ +45 AUE_NULL STD { void cloudabi_sys_sock_shutdown( \ cloudabi_fd_t sock, \ cloudabi_sdflags_t how); } -47 AUE_NULL STD { cloudabi_tid_t cloudabi32_sys_thread_create( \ +46 AUE_NULL STD { cloudabi_tid_t cloudabi32_sys_thread_create( \ cloudabi32_threadattr_t *attr); } -48 AUE_NULL STD { void cloudabi_sys_thread_exit( \ +47 AUE_NULL STD { void cloudabi_sys_thread_exit( \ cloudabi_lock_t *lock, \ cloudabi_scope_t scope); } -49 AUE_NULL STD { void cloudabi_sys_thread_yield(); } +48 AUE_NULL STD { void cloudabi_sys_thread_yield(); } diff --git a/sys/contrib/cloudabi/syscalls64.master b/sys/contrib/cloudabi/syscalls64.master index 81a77dcbefd1..678598aff338 100644 --- a/sys/contrib/cloudabi/syscalls64.master +++ b/sys/contrib/cloudabi/syscalls64.master @@ -231,52 +231,44 @@ cloudabi64_event_t *out, \ size_t nsubscriptions); } -38 AUE_NULL STD { size_t cloudabi64_sys_poll_fd( \ - cloudabi_fd_t fd, \ - const cloudabi64_subscription_t *in, \ - size_t in_len, \ - cloudabi64_event_t *out, \ - size_t out_len, \ - const cloudabi64_subscription_t *timeout); } - -39 AUE_NULL STD { void cloudabi_sys_proc_exec( \ +38 AUE_NULL STD { void cloudabi_sys_proc_exec( \ cloudabi_fd_t fd, \ const void *data, \ size_t data_len, \ const cloudabi_fd_t *fds, \ size_t fds_len); } -40 AUE_NULL STD { void cloudabi_sys_proc_exit( \ +39 AUE_NULL STD { void cloudabi_sys_proc_exit( \ cloudabi_exitcode_t rval); } -41 AUE_NULL STD { void cloudabi_sys_proc_fork(); } +40 AUE_NULL STD { void cloudabi_sys_proc_fork(); } -42 AUE_NULL STD { void cloudabi_sys_proc_raise( \ +41 AUE_NULL STD { void cloudabi_sys_proc_raise( \ cloudabi_signal_t sig); } -43 AUE_NULL STD { void cloudabi_sys_random_get( \ +42 AUE_NULL STD { void cloudabi_sys_random_get( \ void *buf, \ size_t buf_len); } -44 AUE_NULL STD { void cloudabi64_sys_sock_recv( \ +43 AUE_NULL STD { void cloudabi64_sys_sock_recv( \ cloudabi_fd_t sock, \ const cloudabi64_recv_in_t *in, \ cloudabi64_recv_out_t *out); } -45 AUE_NULL STD { void cloudabi64_sys_sock_send( \ +44 AUE_NULL STD { void cloudabi64_sys_sock_send( \ cloudabi_fd_t sock, \ const cloudabi64_send_in_t *in, \ cloudabi64_send_out_t *out); } -46 AUE_NULL STD { void cloudabi_sys_sock_shutdown( \ +45 AUE_NULL STD { void cloudabi_sys_sock_shutdown( \ cloudabi_fd_t sock, \ cloudabi_sdflags_t how); } -47 AUE_NULL STD { cloudabi_tid_t cloudabi64_sys_thread_create( \ +46 AUE_NULL STD { cloudabi_tid_t cloudabi64_sys_thread_create( \ cloudabi64_threadattr_t *attr); } -48 AUE_NULL STD { void cloudabi_sys_thread_exit( \ +47 AUE_NULL STD { void cloudabi_sys_thread_exit( \ cloudabi_lock_t *lock, \ cloudabi_scope_t scope); } -49 AUE_NULL STD { void cloudabi_sys_thread_yield(); } +48 AUE_NULL STD { void cloudabi_sys_thread_yield(); } diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt index db25f7e5fb91..b40fa3209912 100644 --- a/sys/contrib/dev/acpica/changes.txt +++ b/sys/contrib/dev/acpica/changes.txt @@ -1,3 +1,103 @@ +---------------------------------------- +29 September 2017. Summary of changes for version 20170929: + + +1) ACPICA kernel-resident subsystem: + +Redesigned and implemented an improved ASL While() loop timeout +mechanism. This mechanism is used to prevent infinite loops in the kernel +AML interpreter caused by either non-responsive hardware or incorrect AML +code. The new implementation uses AcpiOsGetTimer instead of a simple +maximum loop count, and is thus more accurate and constant across +different machines. The default timeout is currently 30 seconds, but this +may be adjusted later. + +Renamed the ACPI_AML_INFINITE_LOOP exception to AE_AML_LOOP_TIMEOUT to +better reflect the new implementation of the loop timeout mechanism. + +Updated the AcpiGetTimerDuration interface to cleanup the 64-bit support +and to fix an off-by-one error. Jung-uk Kim. + +Fixed an EFI build problem by updating the makefiles to for a new file +that was added, utstrsuppt.c + + +2) iASL Compiler/Disassembler and Tools: + +Implemented full support for the PDTT, SDEV, and TPM2 ACPI tables. This +includes support in the table disassembler, compiler, and template +generator. + +iASL: Added an exception for an illegal type of recursive method +invocation. If a method creates named objects, the first recursive call +will fail at runtime. This change adds an error detection at compile time +to catch the problem up front. Note: Marking such a method as +"serialized" will not help with this problem, because the same thread can +acquire the method mutex more than once. Example compiler and runtime +output: + + Method (MTH1) + { + Name (INT1, 1) + MTH1 () + } + + dsdt.asl 22: MTH1 () + Error 6152 - ^ Illegal recursive call to method + that creates named objects (MTH1) + +Previous runtime exception: + ACPI Error: [INT1] Namespace lookup failure, + AE_ALREADY_EXISTS (20170831/dswload2-465) + +iASL: Updated support for External() opcodes to improve namespace +management and error detection. These changes are related to issues seen +with multiple-segment namespace pathnames within External declarations, +such as below: + + External(\_SB.PCI0.GFX0, DeviceObj) + External(\_SB.PCI0.GFX0.ALSI) + +iASL: Implemented support for multi-line error/warning messages. This +enables more detailed and helpful error messages as below, from the +initial deployment for the duplicate names error: + + DSDT.iiii 1692: Device(PEG2) { + Error 6074 - ^ Name already exists in scope +(PEG2) + + Original name creation/declaration below: + DSDT.iiii 93: External(\_SB.PCI0.PEG2, DeviceObj) + +AcpiXtract: Added additional flexibility to support differing input hex +dump formats. Specifically, hex dumps that contain partial disassembly +and/or comments within the ACPI table data definition. There exist some +dump utilities seen in the field that create this type of hex dump (such +as Simics). For example: + + DSDT @ 0xdfffd0c0 (10999 bytes) + Signature DSDT + Length 10999 + Revision 1 + Checksum 0xf3 (Ok) + OEM_ID BXPC + OEM_table_id BXDSDT + OEM_revision 1 + Creator_id 1280593481 + Creator_revision 537399345 + 0000: 44 53 44 54 f7 2a 00 00 01 f3 42 58 50 43 00 00 + ... + 2af0: 5f 4c 30 46 00 a4 01 + +Test suite: Miscellaneous changes/fixes: + More cleanup and simplification of makefiles + Continue compilation of test cases after a compile failure + Do not perform binary compare unless both files actually exist + +iASL: Performed some code/module restructuring. Moved all memory +allocation functions to new modules. Two new files, aslallocate.c and +aslcache.c + ---------------------------------------- 31 August 2017. Summary of changes for version 20170831: diff --git a/sys/contrib/dev/acpica/common/adfile.c b/sys/contrib/dev/acpica/common/adfile.c index 115a1854e81e..a3abdce55d68 100644 --- a/sys/contrib/dev/acpica/common/adfile.c +++ b/sys/contrib/dev/acpica/common/adfile.c @@ -314,7 +314,7 @@ FlGenerateFilename ( * Copy the original filename to a new buffer. Leave room for the worst * case where we append the suffix, an added dot and the null terminator. */ - NewFilename = UtStringCacheCalloc ((ACPI_SIZE) + NewFilename = UtLocalCacheCalloc ((ACPI_SIZE) strlen (InputFilename) + strlen (Suffix) + 2); strcpy (NewFilename, InputFilename); @@ -358,7 +358,7 @@ FlStrdup ( char *NewString; - NewString = UtStringCacheCalloc ((ACPI_SIZE) strlen (String) + 1); + NewString = UtLocalCacheCalloc ((ACPI_SIZE) strlen (String) + 1); strcpy (NewString, String); return (NewString); } diff --git a/sys/contrib/dev/acpica/common/ahtable.c b/sys/contrib/dev/acpica/common/ahtable.c index c288edff7b43..247ff29335a8 100644 --- a/sys/contrib/dev/acpica/common/ahtable.c +++ b/sys/contrib/dev/acpica/common/ahtable.c @@ -232,6 +232,7 @@ const AH_TABLE Gbl_AcpiSupportedTables[] = {ACPI_SIG_MTMR, "MID Timer Table"}, {ACPI_SIG_NFIT, "NVDIMM Firmware Interface Table"}, {ACPI_SIG_PCCT, "Platform Communications Channel Table"}, + {ACPI_SIG_PDTT, "Platform Debug Trigger Table"}, {ACPI_SIG_PMTT, "Platform Memory Topology Table"}, {ACPI_SIG_PPTT, "Processor Properties Topology Table"}, {ACPI_SIG_RASF, "RAS Features Table"}, @@ -240,6 +241,7 @@ const AH_TABLE Gbl_AcpiSupportedTables[] = {ACPI_SIG_S3PT, "S3 Performance Table"}, {ACPI_SIG_SBST, "Smart Battery Specification Table"}, {ACPI_SIG_SDEI, "Software Delegated Exception Interface Table"}, + {ACPI_SIG_SDEV, "Secure Devices table"}, {ACPI_SIG_SLIC, "Software Licensing Description Table"}, {ACPI_SIG_SLIT, "System Locality Information Table"}, {ACPI_SIG_SPCR, "Serial Port Console Redirection table"}, diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c index 4356d42ab702..26b6c64c423a 100644 --- a/sys/contrib/dev/acpica/common/dmtable.c +++ b/sys/contrib/dev/acpica/common/dmtable.c @@ -154,7 +154,6 @@ #include #include #include -#include /* This module used for application-level code only */ @@ -290,9 +289,9 @@ static const char *AcpiDmHestSubnames[] = "IA-32 Machine Check Exception", "IA-32 Corrected Machine Check", "IA-32 Non-Maskable Interrupt", - "Unknown SubTable Type", /* 3 - Reserved */ - "Unknown SubTable Type", /* 4 - Reserved */ - "Unknown SubTable Type", /* 5 - Reserved */ + "Unknown Subtable Type", /* 3 - Reserved */ + "Unknown Subtable Type", /* 4 - Reserved */ + "Unknown Subtable Type", /* 5 - Reserved */ "PCI Express Root Port AER", "PCI Express AER (AER Endpoint)", "PCI Express/PCI-X Bridge AER", @@ -374,7 +373,7 @@ static const char *AcpiDmPmttSubnames[] = { "Socket", /* ACPI_PMTT_TYPE_SOCKET */ "Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */ - "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */ + "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */ "Unknown Subtable Type" /* Reserved */ }; @@ -382,7 +381,14 @@ static const char *AcpiDmPpttSubnames[] = { "Processor Hierarchy Node", /* ACPI_PPTT_TYPE_PROCESSOR */ "Cache Type", /* ACPI_PPTT_TYPE_CACHE */ - "ID", /* ACPI_PMTT_TYPE_ID */ + "ID", /* ACPI_PPTT_TYPE_ID */ + "Unknown Subtable Type" /* Reserved */ +}; + +static const char *AcpiDmSdevSubnames[] = +{ + "Namespace Device", /* ACPI_SDEV_TYPE_NAMESPACE_DEVICE */ + "PCIe Endpoint Device", /* ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE */ "Unknown Subtable Type" /* Reserved */ }; @@ -396,6 +402,23 @@ static const char *AcpiDmSratSubnames[] = "Unknown Subtable Type" /* Reserved */ }; +static const char *AcpiDmTpm2Subnames[] = +{ + "Illegal Start Method value", + "Reserved", + "ACPI Start Method", + "Reserved", + "Reserved", + "Reserved", + "Memory Mapped I/O", + "Command Response Buffer", + "Command Response Buffer with ACPI Start Method", + "Reserved", + "Reserved", + "Command Response Buffer with ARM SMC", + "Unknown Subtable Type" /* Reserved */ +}; + static const char *AcpiDmIvrsSubnames[] = { "Hardware Definition Block", @@ -487,6 +510,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] = {ACPI_SIG_MTMR, NULL, AcpiDmDumpMtmr, DtCompileMtmr, TemplateMtmr}, {ACPI_SIG_NFIT, AcpiDmTableInfoNfit, AcpiDmDumpNfit, DtCompileNfit, TemplateNfit}, {ACPI_SIG_PCCT, AcpiDmTableInfoPcct, AcpiDmDumpPcct, DtCompilePcct, TemplatePcct}, + {ACPI_SIG_PDTT, AcpiDmTableInfoPdtt, AcpiDmDumpPdtt, DtCompilePdtt, TemplatePdtt}, {ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt}, {ACPI_SIG_PPTT, NULL, AcpiDmDumpPptt, DtCompilePptt, TemplatePptt}, {ACPI_SIG_RASF, AcpiDmTableInfoRasf, NULL, NULL, TemplateRasf}, @@ -494,6 +518,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] = {ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt}, {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst}, {ACPI_SIG_SDEI, AcpiDmTableInfoSdei, NULL, NULL, TemplateSdei}, + {ACPI_SIG_SDEV, AcpiDmTableInfoSdev, AcpiDmDumpSdev, DtCompileSdev, TemplateSdev}, {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic}, {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit}, {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr}, @@ -501,7 +526,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] = {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat}, {ACPI_SIG_STAO, NULL, AcpiDmDumpStao, DtCompileStao, TemplateStao}, {ACPI_SIG_TCPA, NULL, AcpiDmDumpTcpa, DtCompileTcpa, TemplateTcpa}, - {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, NULL, NULL, TemplateTpm2}, + {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, AcpiDmDumpTpm2, DtCompileTpm2, TemplateTpm2}, {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi}, {ACPI_SIG_VRTC, AcpiDmTableInfoVrtc, AcpiDmDumpVrtc, DtCompileVrtc, TemplateVrtc}, {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet}, @@ -917,6 +942,7 @@ AcpiDmDumpTable ( case ACPI_DMT_PCCT: case ACPI_DMT_PMTT: case ACPI_DMT_PPTT: + case ACPI_DMT_SDEV: case ACPI_DMT_SRAT: case ACPI_DMT_ASF: case ACPI_DMT_HESTNTYP: @@ -948,6 +974,7 @@ AcpiDmDumpTable ( case ACPI_DMT_NAME4: case ACPI_DMT_SIG: case ACPI_DMT_LPIT: + case ACPI_DMT_TPM2: ByteLength = 4; break; @@ -1583,6 +1610,20 @@ AcpiDmDumpTable ( CurrentOffset, NULL); break; + case ACPI_DMT_SDEV: + + /* SDEV subtable types */ + + Temp8 = *Target; + if (Temp8 > ACPI_SDEV_TYPE_RESERVED) + { + Temp8 = ACPI_SDEV_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, + AcpiDmSdevSubnames[Temp8]); + break; + case ACPI_DMT_SRAT: /* SRAT subtable types */ @@ -1597,6 +1638,22 @@ AcpiDmDumpTable ( AcpiDmSratSubnames[Temp8]); break; + case ACPI_DMT_TPM2: + + /* TPM2 Start Method types */ + + Temp8 = *Target; + if (Temp8 > ACPI_TPM2_RESERVED) + { + Temp8 = ACPI_TPM2_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, + AcpiDmTpm2Subnames[Temp8]); + break; + + + case ACPI_DMT_FADTPM: /* FADT Preferred PM Profile names */ diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c index 5510e36d1969..bb82bfdfacc0 100644 --- a/sys/contrib/dev/acpica/common/dmtbdump.c +++ b/sys/contrib/dev/acpica/common/dmtbdump.c @@ -623,7 +623,7 @@ AcpiDmDumpAsf ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_HEADER); - ACPI_ASF_INFO *SubTable; + ACPI_ASF_INFO *Subtable; ACPI_DMTABLE_INFO *InfoTable; ACPI_DMTABLE_INFO *DataInfoTable = NULL; UINT8 *DataTable = NULL; @@ -636,13 +636,13 @@ AcpiDmDumpAsf ( /* No main table, only subtables */ - SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Header.Length, AcpiDmTableInfoAsfHdr); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Header.Length, AcpiDmTableInfoAsfHdr); if (ACPI_FAILURE (Status)) { return; @@ -650,7 +650,7 @@ AcpiDmDumpAsf ( /* The actual type is the lower 7 bits of Type */ - Type = (UINT8) (SubTable->Header.Type & 0x7F); + Type = (UINT8) (Subtable->Header.Type & 0x7F); switch (Type) { @@ -663,9 +663,9 @@ AcpiDmDumpAsf ( InfoTable = AcpiDmTableInfoAsf1; DataInfoTable = AcpiDmTableInfoAsf1a; - DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT)); - DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts; - DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength; + DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT)); + DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts; + DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength; DataOffset = Offset + sizeof (ACPI_ASF_ALERT); break; @@ -673,9 +673,9 @@ AcpiDmDumpAsf ( InfoTable = AcpiDmTableInfoAsf2; DataInfoTable = AcpiDmTableInfoAsf2a; - DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE)); - DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls; - DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength; + DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE)); + DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls; + DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength; DataOffset = Offset + sizeof (ACPI_ASF_REMOTE); break; @@ -687,20 +687,20 @@ AcpiDmDumpAsf ( case ACPI_ASF_TYPE_ADDRESS: InfoTable = AcpiDmTableInfoAsf4; - DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS)); - DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices; + DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS)); + DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices; DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS); break; default: AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n", - SubTable->Header.Type); + Subtable->Header.Type); return; } - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Header.Length, InfoTable); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Header.Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -762,15 +762,15 @@ AcpiDmDumpAsf ( /* Point to next subtable */ - if (!SubTable->Header.Length) + if (!Subtable->Header.Length) { AcpiOsPrintf ("Invalid zero subtable header length\n"); return; } - Offset += SubTable->Header.Length; - SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, - SubTable->Header.Length); + Offset += Subtable->Header.Length; + Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable, + Subtable->Header.Length); } } @@ -793,7 +793,7 @@ AcpiDmDumpCpep ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_CPEP_POLLING *SubTable; + ACPI_CPEP_POLLING *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_CPEP); @@ -808,12 +808,12 @@ AcpiDmDumpCpep ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset); while (Offset < Table->Length) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Header.Length, AcpiDmTableInfoCpep0); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Header.Length, AcpiDmTableInfoCpep0); if (ACPI_FAILURE (Status)) { return; @@ -821,9 +821,9 @@ AcpiDmDumpCpep ( /* Point to next subtable */ - Offset += SubTable->Header.Length; - SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable, - SubTable->Header.Length); + Offset += Subtable->Header.Length; + Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable, + Subtable->Header.Length); } } @@ -846,9 +846,9 @@ AcpiDmDumpCsrt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_CSRT_GROUP *SubTable; + ACPI_CSRT_GROUP *Subtable; ACPI_CSRT_SHARED_INFO *SharedInfoTable; - ACPI_CSRT_DESCRIPTOR *SubSubTable; + ACPI_CSRT_DESCRIPTOR *SubSubtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_CSRT); UINT32 SubOffset; @@ -860,14 +860,14 @@ AcpiDmDumpCsrt ( /* Subtables (Resource Groups) */ - SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset); while (Offset < Table->Length) { /* Resource group subtable */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoCsrt0); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoCsrt0); if (ACPI_FAILURE (Status)) { return; @@ -887,19 +887,19 @@ AcpiDmDumpCsrt ( return; } - SubOffset += SubTable->SharedInfoLength; + SubOffset += Subtable->SharedInfoLength; /* Sub-Subtables (Resource Descriptors) */ - SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table, + SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table, Offset + SubOffset); - while ((SubOffset < SubTable->Length) && + while ((SubOffset < Subtable->Length) && ((Offset + SubOffset) < Table->Length)) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubTable, - SubSubTable->Length, AcpiDmTableInfoCsrt2); + Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable, + SubSubtable->Length, AcpiDmTableInfoCsrt2); if (ACPI_FAILURE (Status)) { return; @@ -909,7 +909,7 @@ AcpiDmDumpCsrt ( /* Resource-specific info buffer */ - InfoLength = SubSubTable->Length - SubSubOffset; + InfoLength = SubSubtable->Length - SubSubOffset; if (InfoLength) { Status = AcpiDmDumpTable (Length, @@ -924,16 +924,16 @@ AcpiDmDumpCsrt ( /* Point to next sub-subtable */ - SubOffset += SubSubTable->Length; - SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubTable, - SubSubTable->Length); + SubOffset += SubSubtable->Length; + SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable, + SubSubtable->Length); } /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable, + Subtable->Length); } } @@ -956,7 +956,7 @@ AcpiDmDumpDbg2 ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_DBG2_DEVICE *SubTable; + ACPI_DBG2_DEVICE *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_DBG2); UINT32 i; @@ -975,12 +975,12 @@ AcpiDmDumpDbg2 ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset); while (Offset < Table->Length) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoDbg2Device); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoDbg2Device); if (ACPI_FAILURE (Status)) { return; @@ -988,15 +988,15 @@ AcpiDmDumpDbg2 ( /* Dump the BaseAddress array */ - for (i = 0; i < SubTable->RegisterCount; i++) + for (i = 0; i < Subtable->RegisterCount; i++) { - ArrayOffset = SubTable->BaseAddressOffset + + ArrayOffset = Subtable->BaseAddressOffset + (sizeof (ACPI_GENERIC_ADDRESS) * i); AbsoluteOffset = Offset + ArrayOffset; - Array = (UINT8 *) SubTable + ArrayOffset; + Array = (UINT8 *) Subtable + ArrayOffset; Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array, - SubTable->Length, AcpiDmTableInfoDbg2Addr); + Subtable->Length, AcpiDmTableInfoDbg2Addr); if (ACPI_FAILURE (Status)) { return; @@ -1005,15 +1005,15 @@ AcpiDmDumpDbg2 ( /* Dump the AddressSize array */ - for (i = 0; i < SubTable->RegisterCount; i++) + for (i = 0; i < Subtable->RegisterCount; i++) { - ArrayOffset = SubTable->AddressSizeOffset + + ArrayOffset = Subtable->AddressSizeOffset + (sizeof (UINT32) * i); AbsoluteOffset = Offset + ArrayOffset; - Array = (UINT8 *) SubTable + ArrayOffset; + Array = (UINT8 *) Subtable + ArrayOffset; Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array, - SubTable->Length, AcpiDmTableInfoDbg2Size); + Subtable->Length, AcpiDmTableInfoDbg2Size); if (ACPI_FAILURE (Status)) { return; @@ -1023,12 +1023,12 @@ AcpiDmDumpDbg2 ( /* Dump the Namestring (required) */ AcpiOsPrintf ("\n"); - ArrayOffset = SubTable->NamepathOffset; + ArrayOffset = Subtable->NamepathOffset; AbsoluteOffset = Offset + ArrayOffset; - Array = (UINT8 *) SubTable + ArrayOffset; + Array = (UINT8 *) Subtable + ArrayOffset; Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array, - SubTable->Length, AcpiDmTableInfoDbg2Name); + Subtable->Length, AcpiDmTableInfoDbg2Name); if (ACPI_FAILURE (Status)) { return; @@ -1036,10 +1036,10 @@ AcpiDmDumpDbg2 ( /* Dump the OemData (optional) */ - if (SubTable->OemDataOffset) + if (Subtable->OemDataOffset) { - Status = AcpiDmDumpTable (Length, Offset + SubTable->OemDataOffset, - Table, SubTable->OemDataLength, + Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset, + Table, Subtable->OemDataLength, AcpiDmTableInfoDbg2OemData); if (ACPI_FAILURE (Status)) { @@ -1049,9 +1049,9 @@ AcpiDmDumpDbg2 ( /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable, + Subtable->Length); } } @@ -1074,7 +1074,7 @@ AcpiDmDumpDmar ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_DMAR_HEADER *SubTable; + ACPI_DMAR_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_DMAR); ACPI_DMTABLE_INFO *InfoTable; @@ -1094,14 +1094,14 @@ AcpiDmDumpDmar ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoDmarHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoDmarHdr); if (ACPI_FAILURE (Status)) { return; @@ -1109,7 +1109,7 @@ AcpiDmDumpDmar ( AcpiOsPrintf ("\n"); - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_DMAR_TYPE_HARDWARE_UNIT: @@ -1144,12 +1144,12 @@ AcpiDmDumpDmar ( default: AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n", - SubTable->Type); + Subtable->Type); return; } - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -1158,16 +1158,16 @@ AcpiDmDumpDmar ( /* * Dump the optional device scope entries */ - if ((SubTable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || - (SubTable->Type == ACPI_DMAR_TYPE_NAMESPACE)) + if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || + (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE)) { /* These types do not support device scopes */ goto NextSubtable; } - ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset); - while (ScopeOffset < SubTable->Length) + ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset); + while (ScopeOffset < Subtable->Length) { AcpiOsPrintf ("\n"); Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable, @@ -1208,9 +1208,9 @@ AcpiDmDumpDmar ( NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable, + Subtable->Length); } } @@ -1343,7 +1343,7 @@ AcpiDmDumpEinj ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_WHEA_HEADER *SubTable; + ACPI_WHEA_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_EINJ); @@ -1358,11 +1358,11 @@ AcpiDmDumpEinj ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); while (Offset < Table->Length) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, + Status = AcpiDmDumpTable (Length, Offset, Subtable, sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0); if (ACPI_FAILURE (Status)) { @@ -1372,7 +1372,7 @@ AcpiDmDumpEinj ( /* Point to next subtable (each subtable is of fixed length) */ Offset += sizeof (ACPI_WHEA_HEADER); - SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable, sizeof (ACPI_WHEA_HEADER)); } } @@ -1396,7 +1396,7 @@ AcpiDmDumpErst ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_WHEA_HEADER *SubTable; + ACPI_WHEA_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_ERST); @@ -1411,11 +1411,11 @@ AcpiDmDumpErst ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); while (Offset < Table->Length) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, + Status = AcpiDmDumpTable (Length, Offset, Subtable, sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0); if (ACPI_FAILURE (Status)) { @@ -1425,7 +1425,7 @@ AcpiDmDumpErst ( /* Point to next subtable (each subtable is of fixed length) */ Offset += sizeof (ACPI_WHEA_HEADER); - SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable, sizeof (ACPI_WHEA_HEADER)); } } @@ -1449,7 +1449,7 @@ AcpiDmDumpFpdt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_FPDT_HEADER *SubTable; + ACPI_FPDT_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_FPDT); ACPI_DMTABLE_INFO *InfoTable; @@ -1459,20 +1459,20 @@ AcpiDmDumpFpdt ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoFpdtHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoFpdtHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_FPDT_TYPE_BOOT: @@ -1487,31 +1487,31 @@ AcpiDmDumpFpdt ( default: AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return; } - goto NextSubTable; + goto NextSubtable; } - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, + Subtable->Length); } } @@ -1534,11 +1534,11 @@ AcpiDmDumpGtdt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_GTDT_HEADER *SubTable; + ACPI_GTDT_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_GTDT); ACPI_DMTABLE_INFO *InfoTable; - UINT32 SubTableLength; + UINT32 SubtableLength; UINT32 GtCount; ACPI_GTDT_TIMER_ENTRY *GtxTable; @@ -1553,34 +1553,34 @@ AcpiDmDumpGtdt ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoGtdtHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoGtdtHdr); if (ACPI_FAILURE (Status)) { return; } GtCount = 0; - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_GTDT_TYPE_TIMER_BLOCK: - SubTableLength = sizeof (ACPI_GTDT_TIMER_BLOCK); + SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK); GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, - SubTable))->TimerCount; + Subtable))->TimerCount; InfoTable = AcpiDmTableInfoGtdt0; break; case ACPI_GTDT_TYPE_WATCHDOG: - SubTableLength = sizeof (ACPI_GTDT_WATCHDOG); + SubtableLength = sizeof (ACPI_GTDT_WATCHDOG); InfoTable = AcpiDmTableInfoGtdt1; break; @@ -1590,12 +1590,12 @@ AcpiDmDumpGtdt ( /* Cannot continue on unknown type - no length */ AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); return; } - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -1603,15 +1603,15 @@ AcpiDmDumpGtdt ( /* Point to end of current subtable (each subtable above is of fixed length) */ - Offset += SubTableLength; + Offset += SubtableLength; /* If there are any Gt Timer Blocks from above, dump them now */ if (GtCount) { GtxTable = ACPI_ADD_PTR ( - ACPI_GTDT_TIMER_ENTRY, SubTable, SubTableLength); - SubTableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY); + ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength); + SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY); while (GtCount) { @@ -1630,7 +1630,7 @@ AcpiDmDumpGtdt ( /* Point to next subtable */ - SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, SubTable, SubTableLength); + Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength); } } @@ -1653,11 +1653,11 @@ AcpiDmDumpHest ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_HEST_HEADER *SubTable; + ACPI_HEST_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_HEST); ACPI_DMTABLE_INFO *InfoTable; - UINT32 SubTableLength; + UINT32 SubtableLength; UINT32 BankCount; ACPI_HEST_IA_ERROR_BANK *BankTable; @@ -1672,70 +1672,70 @@ AcpiDmDumpHest ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset); while (Offset < Table->Length) { BankCount = 0; - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_HEST_TYPE_IA32_CHECK: InfoTable = AcpiDmTableInfoHest0; - SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK); + SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK); BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, - SubTable))->NumHardwareBanks; + Subtable))->NumHardwareBanks; break; case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: InfoTable = AcpiDmTableInfoHest1; - SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED); + SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED); BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, - SubTable))->NumHardwareBanks; + Subtable))->NumHardwareBanks; break; case ACPI_HEST_TYPE_IA32_NMI: InfoTable = AcpiDmTableInfoHest2; - SubTableLength = sizeof (ACPI_HEST_IA_NMI); + SubtableLength = sizeof (ACPI_HEST_IA_NMI); break; case ACPI_HEST_TYPE_AER_ROOT_PORT: InfoTable = AcpiDmTableInfoHest6; - SubTableLength = sizeof (ACPI_HEST_AER_ROOT); + SubtableLength = sizeof (ACPI_HEST_AER_ROOT); break; case ACPI_HEST_TYPE_AER_ENDPOINT: InfoTable = AcpiDmTableInfoHest7; - SubTableLength = sizeof (ACPI_HEST_AER); + SubtableLength = sizeof (ACPI_HEST_AER); break; case ACPI_HEST_TYPE_AER_BRIDGE: InfoTable = AcpiDmTableInfoHest8; - SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE); + SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE); break; case ACPI_HEST_TYPE_GENERIC_ERROR: InfoTable = AcpiDmTableInfoHest9; - SubTableLength = sizeof (ACPI_HEST_GENERIC); + SubtableLength = sizeof (ACPI_HEST_GENERIC); break; case ACPI_HEST_TYPE_GENERIC_ERROR_V2: InfoTable = AcpiDmTableInfoHest10; - SubTableLength = sizeof (ACPI_HEST_GENERIC_V2); + SubtableLength = sizeof (ACPI_HEST_GENERIC_V2); break; case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: InfoTable = AcpiDmTableInfoHest11; - SubTableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK); + SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK); BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK, - SubTable))->NumHardwareBanks; + Subtable))->NumHardwareBanks; break; default: @@ -1743,13 +1743,13 @@ AcpiDmDumpHest ( /* Cannot continue on unknown type - no length */ AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); return; } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTableLength, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + SubtableLength, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -1757,15 +1757,15 @@ AcpiDmDumpHest ( /* Point to end of current subtable (each subtable above is of fixed length) */ - Offset += SubTableLength; + Offset += SubtableLength; /* If there are any (fixed-length) Error Banks from above, dump them now */ if (BankCount) { - BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, - SubTableLength); - SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK); + BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable, + SubtableLength); + SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK); while (BankCount) { @@ -1785,7 +1785,7 @@ AcpiDmDumpHest ( /* Point to next subtable */ - SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength); + Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength); } } @@ -1811,7 +1811,7 @@ AcpiDmDumpHmat ( ACPI_HMAT_LOCALITY *HmatLocality; ACPI_HMAT_CACHE *HmatCache; UINT32 Offset; - UINT32 SubTableOffset; + UINT32 SubtableOffset; UINT32 Length; ACPI_DMTABLE_INFO *InfoTable; UINT32 i, j; @@ -1829,7 +1829,7 @@ AcpiDmDumpHmat ( while (Offset < Table->Length) { AcpiOsPrintf ("\n"); - SubTableOffset = 0; + SubtableOffset = 0; /* Dump HMAT structure header */ @@ -1873,7 +1873,7 @@ AcpiDmDumpHmat ( /* Attempt to continue */ - goto NextSubTable; + goto NextSubtable; } /* Dump HMAT structure body */ @@ -1897,11 +1897,11 @@ AcpiDmDumpHmat ( case ACPI_HMAT_TYPE_LOCALITY: HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct); - SubTableOffset = sizeof (ACPI_HMAT_LOCALITY); + SubtableOffset = sizeof (ACPI_HMAT_LOCALITY); /* Dump initiator proximity domains */ - if ((UINT32)(HmatStruct->Length - SubTableOffset) < + if ((UINT32)(HmatStruct->Length - SubtableOffset) < (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4)) { AcpiOsPrintf ("Invalid initiator proximity domain number\n"); @@ -1909,15 +1909,15 @@ AcpiDmDumpHmat ( } for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++) { - Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset, - ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset), + Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset, + ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset), 4, AcpiDmTableInfoHmat1a); - SubTableOffset += 4; + SubtableOffset += 4; } /* Dump target proximity domains */ - if ((UINT32)(HmatStruct->Length - SubTableOffset) < + if ((UINT32)(HmatStruct->Length - SubtableOffset) < (UINT32)(HmatLocality->NumberOfTargetPDs * 4)) { AcpiOsPrintf ("Invalid target proximity domain number\n"); @@ -1925,15 +1925,15 @@ AcpiDmDumpHmat ( } for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++) { - Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset, - ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset), + Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset, + ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset), 4, AcpiDmTableInfoHmat1b); - SubTableOffset += 4; + SubtableOffset += 4; } /* Dump latency/bandwidth entris */ - if ((UINT32)(HmatStruct->Length - SubTableOffset) < + if ((UINT32)(HmatStruct->Length - SubtableOffset) < (UINT32)(HmatLocality->NumberOfInitiatorPDs * HmatLocality->NumberOfTargetPDs * 2)) { @@ -1944,10 +1944,10 @@ AcpiDmDumpHmat ( { for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++) { - Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset, - ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset), + Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset, + ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset), 2, AcpiDmTableInfoHmat1c); - SubTableOffset += 2; + SubtableOffset += 2; } } break; @@ -1955,11 +1955,11 @@ AcpiDmDumpHmat ( case ACPI_HMAT_TYPE_CACHE: HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct); - SubTableOffset = sizeof (ACPI_HMAT_CACHE); + SubtableOffset = sizeof (ACPI_HMAT_CACHE); /* Dump SMBIOS handles */ - if ((UINT32)(HmatStruct->Length - SubTableOffset) < + if ((UINT32)(HmatStruct->Length - SubtableOffset) < (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2)) { AcpiOsPrintf ("Invalid SMBIOS handle number\n"); @@ -1967,10 +1967,10 @@ AcpiDmDumpHmat ( } for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++) { - Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset, - ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset), + Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset, + ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset), 2, AcpiDmTableInfoHmat2a); - SubTableOffset += 2; + SubtableOffset += 2; } break; @@ -1979,7 +1979,7 @@ AcpiDmDumpHmat ( break; } -NextSubTable: +NextSubtable: /* Point to next HMAT structure subtable */ Offset += (HmatStruct->Length); @@ -2104,7 +2104,7 @@ AcpiDmDumpIort ( AcpiOsPrintf ("Invalid zero length IORT node\n"); return; } - goto NextSubTable; + goto NextSubtable; } /* Dump the node subtable header */ @@ -2227,7 +2227,7 @@ AcpiDmDumpIort ( NodeOffset += Length; } -NextSubTable: +NextSubtable: /* Point to next node subtable */ Offset += IortNode->Length; @@ -2260,7 +2260,7 @@ AcpiDmDumpIvrs ( UINT32 EntryLength; UINT32 EntryType; ACPI_IVRS_DE_HEADER *DeviceEntry; - ACPI_IVRS_HEADER *SubTable; + ACPI_IVRS_HEADER *Subtable; ACPI_DMTABLE_INFO *InfoTable; @@ -2274,20 +2274,20 @@ AcpiDmDumpIvrs ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoIvrsHdr); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoIvrsHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_IVRS_TYPE_HARDWARE: @@ -2304,23 +2304,23 @@ AcpiDmDumpIvrs ( default: AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return; } - goto NextSubTable; + goto NextSubtable; } /* Dump the subtable */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -2328,13 +2328,13 @@ AcpiDmDumpIvrs ( /* The hardware subtable can contain multiple device entries */ - if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE) + if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE) { EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE); - DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable, + DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable, sizeof (ACPI_IVRS_HARDWARE)); - while (EntryOffset < (Offset + SubTable->Length)) + while (EntryOffset < (Offset + Subtable->Length)) { AcpiOsPrintf ("\n"); /* @@ -2409,11 +2409,11 @@ AcpiDmDumpIvrs ( } } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length); } } @@ -2438,33 +2438,33 @@ AcpiDmDumpLpit ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_LPIT_HEADER *SubTable; + ACPI_LPIT_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_LPIT); ACPI_DMTABLE_INFO *InfoTable; - UINT32 SubTableLength; + UINT32 SubtableLength; /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ - Status = AcpiDmDumpTable (Length, Offset, SubTable, + Status = AcpiDmDumpTable (Length, Offset, Subtable, sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_LPIT_TYPE_NATIVE_CSTATE: InfoTable = AcpiDmTableInfoLpit0; - SubTableLength = sizeof (ACPI_LPIT_NATIVE); + SubtableLength = sizeof (ACPI_LPIT_NATIVE); break; default: @@ -2472,12 +2472,12 @@ AcpiDmDumpLpit ( /* Cannot continue on unknown type - no length */ AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); return; } - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTableLength, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + SubtableLength, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -2487,8 +2487,8 @@ AcpiDmDumpLpit ( /* Point to next subtable */ - Offset += SubTableLength; - SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, SubTable, SubTableLength); + Offset += SubtableLength; + Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength); } } @@ -2511,7 +2511,7 @@ AcpiDmDumpMadt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_SUBTABLE_HEADER *SubTable; + ACPI_SUBTABLE_HEADER *Subtable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_MADT); ACPI_DMTABLE_INFO *InfoTable; @@ -2527,20 +2527,20 @@ AcpiDmDumpMadt ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoMadtHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoMadtHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_MADT_TYPE_LOCAL_APIC: @@ -2625,32 +2625,32 @@ AcpiDmDumpMadt ( default: AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return; } - goto NextSubTable; + goto NextSubtable; } - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, + Subtable->Length); } } @@ -2673,7 +2673,7 @@ AcpiDmDumpMcfg ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_MCFG); - ACPI_MCFG_ALLOCATION *SubTable; + ACPI_MCFG_ALLOCATION *Subtable; /* Main table */ @@ -2686,7 +2686,7 @@ AcpiDmDumpMcfg ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset); while (Offset < Table->Length) { if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length) @@ -2697,7 +2697,7 @@ AcpiDmDumpMcfg ( } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0); if (ACPI_FAILURE (Status)) { @@ -2707,7 +2707,7 @@ AcpiDmDumpMcfg ( /* Point to next subtable (each subtable is of fixed length) */ Offset += sizeof (ACPI_MCFG_ALLOCATION); - SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable, sizeof (ACPI_MCFG_ALLOCATION)); } } @@ -2731,11 +2731,11 @@ AcpiDmDumpMpst ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_MPST); - ACPI_MPST_POWER_NODE *SubTable0; - ACPI_MPST_POWER_STATE *SubTable0A; - ACPI_MPST_COMPONENT *SubTable0B; - ACPI_MPST_DATA_HDR *SubTable1; - ACPI_MPST_POWER_DATA *SubTable2; + ACPI_MPST_POWER_NODE *Subtable0; + ACPI_MPST_POWER_STATE *Subtable0A; + ACPI_MPST_COMPONENT *Subtable0B; + ACPI_MPST_DATA_HDR *Subtable1; + ACPI_MPST_POWER_DATA *Subtable2; UINT16 SubtableCount; UINT32 PowerStateCount; UINT32 ComponentCount; @@ -2752,12 +2752,12 @@ AcpiDmDumpMpst ( /* Subtable: Memory Power Node(s) */ SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount; - SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset); + Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset); while ((Offset < Table->Length) && SubtableCount) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0, sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0); if (ACPI_FAILURE (Status)) { @@ -2766,33 +2766,33 @@ AcpiDmDumpMpst ( /* Extract the sub-subtable counts */ - PowerStateCount = SubTable0->NumPowerStates; - ComponentCount = SubTable0->NumPhysicalComponents; + PowerStateCount = Subtable0->NumPowerStates; + ComponentCount = Subtable0->NumPhysicalComponents; Offset += sizeof (ACPI_MPST_POWER_NODE); /* Sub-subtables - Memory Power State Structure(s) */ - SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0, + Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0, sizeof (ACPI_MPST_POWER_NODE)); while (PowerStateCount) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A, sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A); if (ACPI_FAILURE (Status)) { return; } - SubTable0A++; + Subtable0A++; PowerStateCount--; Offset += sizeof (ACPI_MPST_POWER_STATE); } /* Sub-subtables - Physical Component ID Structure(s) */ - SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A); + Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A); if (ComponentCount) { @@ -2801,14 +2801,14 @@ AcpiDmDumpMpst ( while (ComponentCount) { - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B, sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B); if (ACPI_FAILURE (Status)) { return; } - SubTable0B++; + Subtable0B++; ComponentCount--; Offset += sizeof (ACPI_MPST_COMPONENT); } @@ -2816,42 +2816,42 @@ AcpiDmDumpMpst ( /* Point to next Memory Power Node subtable */ SubtableCount--; - SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0, + Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0, sizeof (ACPI_MPST_POWER_NODE) + - (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) + - (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents)); + (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) + + (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents)); } /* Subtable: Count of Memory Power State Characteristic structures */ AcpiOsPrintf ("\n"); - SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1, + Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1, sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1); if (ACPI_FAILURE (Status)) { return; } - SubtableCount = SubTable1->CharacteristicsCount; + SubtableCount = Subtable1->CharacteristicsCount; Offset += sizeof (ACPI_MPST_DATA_HDR); /* Subtable: Memory Power State Characteristics structure(s) */ - SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, + Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1, sizeof (ACPI_MPST_DATA_HDR)); while ((Offset < Table->Length) && SubtableCount) { AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2, sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2); if (ACPI_FAILURE (Status)) { return; } - SubTable2++; + Subtable2++; SubtableCount--; Offset += sizeof (ACPI_MPST_POWER_DATA); } @@ -2876,7 +2876,7 @@ AcpiDmDumpMsct ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_MSCT); - ACPI_MSCT_PROXIMITY *SubTable; + ACPI_MSCT_PROXIMITY *Subtable; /* Main table */ @@ -2889,13 +2889,13 @@ AcpiDmDumpMsct ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0); if (ACPI_FAILURE (Status)) { @@ -2905,7 +2905,7 @@ AcpiDmDumpMsct ( /* Point to next subtable */ Offset += sizeof (ACPI_MSCT_PROXIMITY); - SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable, sizeof (ACPI_MSCT_PROXIMITY)); } } @@ -2929,7 +2929,7 @@ AcpiDmDumpMtmr ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_MTMR); - ACPI_MTMR_ENTRY *SubTable; + ACPI_MTMR_ENTRY *Subtable; /* Main table */ @@ -2942,13 +2942,13 @@ AcpiDmDumpMtmr ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0); if (ACPI_FAILURE (Status)) { @@ -2958,7 +2958,7 @@ AcpiDmDumpMtmr ( /* Point to next subtable */ Offset += sizeof (ACPI_MTMR_ENTRY); - SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Subtable, sizeof (ACPI_MTMR_ENTRY)); } } @@ -2984,7 +2984,7 @@ AcpiDmDumpNfit ( UINT32 Offset = sizeof (ACPI_TABLE_NFIT); UINT32 FieldOffset = 0; UINT32 Length; - ACPI_NFIT_HEADER *SubTable; + ACPI_NFIT_HEADER *Subtable; ACPI_DMTABLE_INFO *InfoTable; ACPI_NFIT_INTERLEAVE *Interleave = NULL; ACPI_NFIT_SMBIOS *SmbiosInfo = NULL; @@ -3002,20 +3002,20 @@ AcpiDmDumpNfit ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset); while (Offset < Table->Length) { /* NFIT subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoNfitHdr); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoNfitHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: @@ -3032,13 +3032,13 @@ AcpiDmDumpNfit ( /* Has a variable number of 32-bit values at the end */ InfoTable = AcpiDmTableInfoNfit2; - Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, SubTable); + Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable); FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE); break; case ACPI_NFIT_TYPE_SMBIOS: - SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, SubTable); + SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable); InfoTable = AcpiDmTableInfoNfit3; break; @@ -3057,27 +3057,27 @@ AcpiDmDumpNfit ( /* Has a variable number of 64-bit addresses at the end */ InfoTable = AcpiDmTableInfoNfit6; - Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, SubTable); + Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable); FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64); break; default: AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return; } - goto NextSubTable; + goto NextSubtable; } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -3085,7 +3085,7 @@ AcpiDmDumpNfit ( /* Per-subtable variable-length fields */ - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_NFIT_TYPE_INTERLEAVE: @@ -3105,7 +3105,7 @@ AcpiDmDumpNfit ( case ACPI_NFIT_TYPE_SMBIOS: - Length = SubTable->Length - + Length = Subtable->Length - sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8); if (Length) @@ -3142,11 +3142,11 @@ AcpiDmDumpNfit ( break; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, SubTable, SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length); } } @@ -3169,7 +3169,7 @@ AcpiDmDumpPcct ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_PCCT_SUBSPACE *SubTable; + ACPI_PCCT_SUBSPACE *Subtable; ACPI_DMTABLE_INFO *InfoTable; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_PCCT); @@ -3185,20 +3185,20 @@ AcpiDmDumpPcct ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Header.Length, AcpiDmTableInfoPcctHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Header.Length, AcpiDmTableInfoPcctHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Header.Type) + switch (Subtable->Header.Type) { case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: @@ -3229,13 +3229,13 @@ AcpiDmDumpPcct ( AcpiOsPrintf ( "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n", - SubTable->Header.Type); + Subtable->Header.Type); return; } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Header.Length, InfoTable); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Header.Length, InfoTable); if (ACPI_FAILURE (Status)) { return; @@ -3243,9 +3243,63 @@ AcpiDmDumpPcct ( /* Point to next subtable */ - Offset += SubTable->Header.Length; - SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable, - SubTable->Header.Length); + Offset += Subtable->Header.Length; + Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable, + Subtable->Header.Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpPdtt + * + * PARAMETERS: Table - A PDTT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length + * table that contains an open-ended number of IDs + * at the end of the table. + * + ******************************************************************************/ + +void +AcpiDmDumpPdtt ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_PDTT_CHANNEL *Subtable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_PDTT); + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Subtables. Currently there is only one type, but can be multiples */ + + Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset); + while (Offset < Table->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next subtable */ + + Offset += sizeof (ACPI_PDTT_CHANNEL); + Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable, + sizeof (ACPI_PDTT_CHANNEL)); } } @@ -3268,9 +3322,9 @@ AcpiDmDumpPmtt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_PMTT_HEADER *SubTable; - ACPI_PMTT_HEADER *MemSubTable; - ACPI_PMTT_HEADER *DimmSubTable; + ACPI_PMTT_HEADER *Subtable; + ACPI_PMTT_HEADER *MemSubtable; + ACPI_PMTT_HEADER *DimmSubtable; ACPI_PMTT_DOMAIN *DomainArray; UINT32 Length = Table->Length; UINT32 Offset = sizeof (ACPI_TABLE_PMTT); @@ -3290,14 +3344,14 @@ AcpiDmDumpPmtt ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoPmttHdr); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoPmttHdr); if (ACPI_FAILURE (Status)) { return; @@ -3305,18 +3359,18 @@ AcpiDmDumpPmtt ( /* Only Socket subtables are expected at this level */ - if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET) + if (Subtable->Type != ACPI_PMTT_TYPE_SOCKET) { AcpiOsPrintf ( "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", - SubTable->Type); + Subtable->Type); return; } /* Dump the fixed-length portion of the subtable */ - Status = AcpiDmDumpTable (Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoPmtt0); + Status = AcpiDmDumpTable (Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoPmtt0); if (ACPI_FAILURE (Status)) { return; @@ -3325,18 +3379,18 @@ AcpiDmDumpPmtt ( /* Walk the memory controller subtables */ MemOffset = sizeof (ACPI_PMTT_SOCKET); - MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable, + MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Subtable, sizeof (ACPI_PMTT_SOCKET)); while (((Offset + MemOffset) < Table->Length) && - (MemOffset < SubTable->Length)) + (MemOffset < Subtable->Length)) { /* Common subtable header */ AcpiOsPrintf ("\n"); Status = AcpiDmDumpTable (Length, - Offset + MemOffset, MemSubTable, - MemSubTable->Length, AcpiDmTableInfoPmttHdr); + Offset + MemOffset, MemSubtable, + MemSubtable->Length, AcpiDmTableInfoPmttHdr); if (ACPI_FAILURE (Status)) { return; @@ -3344,19 +3398,19 @@ AcpiDmDumpPmtt ( /* Only memory controller subtables are expected at this level */ - if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER) + if (MemSubtable->Type != ACPI_PMTT_TYPE_CONTROLLER) { AcpiOsPrintf ( "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", - MemSubTable->Type); + MemSubtable->Type); return; } /* Dump the fixed-length portion of the controller subtable */ Status = AcpiDmDumpTable (Length, - Offset + MemOffset, MemSubTable, - MemSubTable->Length, AcpiDmTableInfoPmtt1); + Offset + MemOffset, MemSubtable, + MemSubtable->Length, AcpiDmTableInfoPmtt1); if (ACPI_FAILURE (Status)) { return; @@ -3364,13 +3418,13 @@ AcpiDmDumpPmtt ( /* Walk the variable count of proximity domains */ - DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount; + DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubtable)->DomainCount; DomainOffset = sizeof (ACPI_PMTT_CONTROLLER); - DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable, + DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubtable, sizeof (ACPI_PMTT_CONTROLLER)); while (((Offset + MemOffset + DomainOffset) < Table->Length) && - ((MemOffset + DomainOffset) < SubTable->Length) && + ((MemOffset + DomainOffset) < Subtable->Length) && DomainCount) { Status = AcpiDmDumpTable (Length, @@ -3395,18 +3449,18 @@ AcpiDmDumpPmtt ( /* Walk the physical component (DIMM) subtables */ DimmOffset = DomainOffset; - DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable, + DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubtable, DomainOffset); while (((Offset + MemOffset + DimmOffset) < Table->Length) && - (DimmOffset < MemSubTable->Length)) + (DimmOffset < MemSubtable->Length)) { /* Common subtable header */ AcpiOsPrintf ("\n"); Status = AcpiDmDumpTable (Length, - Offset + MemOffset + DimmOffset, DimmSubTable, - DimmSubTable->Length, AcpiDmTableInfoPmttHdr); + Offset + MemOffset + DimmOffset, DimmSubtable, + DimmSubtable->Length, AcpiDmTableInfoPmttHdr); if (ACPI_FAILURE (Status)) { return; @@ -3414,19 +3468,19 @@ AcpiDmDumpPmtt ( /* Only DIMM subtables are expected at this level */ - if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM) + if (DimmSubtable->Type != ACPI_PMTT_TYPE_DIMM) { AcpiOsPrintf ( "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", - DimmSubTable->Type); + DimmSubtable->Type); return; } /* Dump the fixed-length DIMM subtable */ Status = AcpiDmDumpTable (Length, - Offset + MemOffset + DimmOffset, DimmSubTable, - DimmSubTable->Length, AcpiDmTableInfoPmtt2); + Offset + MemOffset + DimmOffset, DimmSubtable, + DimmSubtable->Length, AcpiDmTableInfoPmtt2); if (ACPI_FAILURE (Status)) { return; @@ -3434,23 +3488,23 @@ AcpiDmDumpPmtt ( /* Point to next DIMM subtable */ - DimmOffset += DimmSubTable->Length; - DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, - DimmSubTable, DimmSubTable->Length); + DimmOffset += DimmSubtable->Length; + DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + DimmSubtable, DimmSubtable->Length); } /* Point to next Controller subtable */ - MemOffset += MemSubTable->Length; - MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, - MemSubTable, MemSubTable->Length); + MemOffset += MemSubtable->Length; + MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + MemSubtable, MemSubtable->Length); } /* Point to next Socket subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, - SubTable, SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + Subtable, Subtable->Length); } } @@ -3473,10 +3527,10 @@ AcpiDmDumpPptt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_SUBTABLE_HEADER *SubTable; + ACPI_SUBTABLE_HEADER *Subtable; ACPI_PPTT_PROCESSOR *PpttProcessor; UINT8 Length; - UINT8 SubTableOffset; + UINT8 SubtableOffset; UINT32 Offset = sizeof (ACPI_TABLE_FPDT); ACPI_DMTABLE_INFO *InfoTable; UINT32 i; @@ -3493,20 +3547,20 @@ AcpiDmDumpPptt ( /* Common subtable header */ - SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); - if (SubTable->Length < sizeof (ACPI_SUBTABLE_HEADER)) + Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); + if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER)) { AcpiOsPrintf ("Invalid subtable length\n"); return; } - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoPpttHdr); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoPpttHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_PPTT_TYPE_PROCESSOR: @@ -3529,35 +3583,35 @@ AcpiDmDumpPptt ( default: AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - goto NextSubTable; + goto NextSubtable; } - if (SubTable->Length < Length) + if (Subtable->Length < Length) { AcpiOsPrintf ("Invalid subtable length\n"); return; } - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; } - SubTableOffset = Length; + SubtableOffset = Length; - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_PPTT_TYPE_PROCESSOR: - PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, SubTable); + PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable); /* Dump SMBIOS handles */ - if ((UINT8)(SubTable->Length - SubTableOffset) < + if ((UINT8)(Subtable->Length - SubtableOffset) < (UINT8)(PpttProcessor->NumberOfPrivResources * 4)) { AcpiOsPrintf ("Invalid private resource number\n"); @@ -3565,10 +3619,10 @@ AcpiDmDumpPptt ( } for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++) { - Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset, - ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTableOffset), + Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset, + ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset), 4, AcpiDmTableInfoPptt0a); - SubTableOffset += 4; + SubtableOffset += 4; } break; @@ -3577,10 +3631,10 @@ AcpiDmDumpPptt ( break; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; + Offset += Subtable->Length; } } @@ -3603,7 +3657,7 @@ AcpiDmDumpS3pt ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_S3PT); - ACPI_FPDT_HEADER *SubTable; + ACPI_FPDT_HEADER *Subtable; ACPI_DMTABLE_INFO *InfoTable; ACPI_TABLE_S3PT *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables); @@ -3616,20 +3670,20 @@ AcpiDmDumpS3pt ( return 0; } - SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset); + Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset); while (Offset < S3ptTable->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoS3ptHdr); + Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoS3ptHdr); if (ACPI_FAILURE (Status)) { return 0; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_S3PT_TYPE_RESUME: @@ -3644,37 +3698,205 @@ AcpiDmDumpS3pt ( default: AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return 0; } - goto NextSubTable; + goto NextSubtable; } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return 0; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length); } return (S3ptTable->Length); } + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpSdev + * + * PARAMETERS: Table - A SDEV table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a SDEV. This is a variable-length + * table that contains variable strings and vendor data. + * + ******************************************************************************/ + +void +AcpiDmDumpSdev ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_SDEV_HEADER *Subtable; + ACPI_SDEV_PCIE *Pcie; + ACPI_SDEV_NAMESPACE *Namesp; + ACPI_DMTABLE_INFO *InfoTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_SDEV); + UINT16 PathOffset; + UINT16 PathLength; + UINT16 VendorDataOffset; + UINT16 VendorDataLength; + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Subtables */ + + Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common subtable header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoSdevHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (Subtable->Type) + { + case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: + + InfoTable = AcpiDmTableInfoSdev0; + break; + + case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: + + InfoTable = AcpiDmTableInfoSdev1; + break; + + default: + goto NextSubtable; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (Subtable->Type) + { + case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: + + /* Dump the PCIe device ID(s) */ + + Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable); + PathOffset = Namesp->DeviceIdOffset; + PathLength = Namesp->DeviceIdLength; + + if (PathLength) + { + Status = AcpiDmDumpTable (Table->Length, 0, + ACPI_ADD_PTR (UINT8, Namesp, PathOffset), + PathLength, AcpiDmTableInfoSdev0a); + if (ACPI_FAILURE (Status)) + { + return; + } + } + + /* Dump the vendor-specific data */ + + VendorDataLength = + Namesp->VendorDataLength; + VendorDataOffset = + Namesp->DeviceIdOffset + Namesp->DeviceIdLength; + + if (VendorDataLength) + { + Status = AcpiDmDumpTable (Table->Length, 0, + ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset), + VendorDataLength, AcpiDmTableInfoSdev1b); + if (ACPI_FAILURE (Status)) + { + return; + } + } + break; + + case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: + + /* PCI path substructures */ + + Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable); + PathOffset = Pcie->PathOffset; + PathLength = Pcie->PathLength; + + while (PathLength) + { + Status = AcpiDmDumpTable (Table->Length, + PathOffset + Offset, + ACPI_ADD_PTR (UINT8, Pcie, PathOffset), + sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a); + if (ACPI_FAILURE (Status)) + { + return; + } + + PathOffset += sizeof (ACPI_SDEV_PCIE_PATH); + PathLength -= sizeof (ACPI_SDEV_PCIE_PATH); + } + + /* VendorData */ + + VendorDataLength = Pcie->VendorDataLength; + VendorDataOffset = Pcie->PathOffset + Pcie->PathLength; + + if (VendorDataLength) + { + Status = AcpiDmDumpTable (Table->Length, 0, + ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset), + VendorDataLength, AcpiDmTableInfoSdev1b); + } + break; + + default: + goto NextSubtable; + } + +NextSubtable: + /* Point to next subtable */ + + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable, + Subtable->Length); + } +} + + /******************************************************************************* * * FUNCTION: AcpiDmDumpSlic @@ -3794,7 +4016,7 @@ AcpiDmDumpSrat ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_SRAT); - ACPI_SUBTABLE_HEADER *SubTable; + ACPI_SUBTABLE_HEADER *Subtable; ACPI_DMTABLE_INFO *InfoTable; @@ -3808,20 +4030,20 @@ AcpiDmDumpSrat ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, AcpiDmTableInfoSratHdr); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, AcpiDmTableInfoSratHdr); if (ACPI_FAILURE (Status)) { return; } - switch (SubTable->Type) + switch (Subtable->Type) { case ACPI_SRAT_TYPE_CPU_AFFINITY: @@ -3850,32 +4072,32 @@ AcpiDmDumpSrat ( default: AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n", - SubTable->Type); + Subtable->Type); /* Attempt to continue */ - if (!SubTable->Length) + if (!Subtable->Length) { AcpiOsPrintf ("Invalid zero length subtable\n"); return; } - goto NextSubTable; + goto NextSubtable; } AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, - SubTable->Length, InfoTable); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Subtable->Length, InfoTable); if (ACPI_FAILURE (Status)) { return; } -NextSubTable: +NextSubtable: /* Point to next subtable */ - Offset += SubTable->Length; - SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, - SubTable->Length); + Offset += Subtable->Length; + Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, + Subtable->Length); } } @@ -3954,7 +4176,7 @@ AcpiDmDumpTcpa ( UINT32 Offset = sizeof (ACPI_TABLE_TCPA_HDR); ACPI_TABLE_TCPA_HDR *CommonHeader = ACPI_CAST_PTR ( ACPI_TABLE_TCPA_HDR, Table); - ACPI_TABLE_TCPA_HDR *SubTable = ACPI_ADD_PTR ( + ACPI_TABLE_TCPA_HDR *Subtable = ACPI_ADD_PTR ( ACPI_TABLE_TCPA_HDR, Table, Offset); ACPI_STATUS Status; @@ -3976,13 +4198,13 @@ AcpiDmDumpTcpa ( { case ACPI_TCPA_CLIENT_TABLE: - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Table->Length - Offset, AcpiDmTableInfoTcpaClient); break; case ACPI_TCPA_SERVER_TABLE: - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, Table->Length - Offset, AcpiDmTableInfoTcpaServer); break; @@ -4001,6 +4223,64 @@ AcpiDmDumpTcpa ( } +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpTpm2 + * + * PARAMETERS: Table - A TPM2 table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a TPM2. + * + ******************************************************************************/ + +void +AcpiDmDumpTpm2 ( + ACPI_TABLE_HEADER *Table) +{ + UINT32 Offset = sizeof (ACPI_TABLE_TPM2); + ACPI_TABLE_TPM2 *CommonHeader = ACPI_CAST_PTR (ACPI_TABLE_TPM2, Table); + ACPI_TPM2_TRAILER *Subtable = ACPI_ADD_PTR (ACPI_TPM2_TRAILER, Table, Offset); + ACPI_TPM2_ARM_SMC *ArmSubtable; + ACPI_STATUS Status; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoTpm2); + if (ACPI_FAILURE (Status)) + { + return; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, + Table->Length - Offset, AcpiDmTableInfoTpm2a); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (CommonHeader->StartMethod) + { + case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: + + ArmSubtable = ACPI_ADD_PTR (ACPI_TPM2_ARM_SMC, Subtable, + sizeof (ACPI_TPM2_TRAILER)); + Offset += sizeof (ACPI_TPM2_TRAILER); + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, ArmSubtable, + Table->Length - Offset, AcpiDmTableInfoTpm211); + break; + + default: + break; + } +} + + /******************************************************************************* * * FUNCTION: AcpiDmDumpVrtc @@ -4019,7 +4299,7 @@ AcpiDmDumpVrtc ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_VRTC); - ACPI_VRTC_ENTRY *SubTable; + ACPI_VRTC_ENTRY *Subtable; /* Main table */ @@ -4032,13 +4312,13 @@ AcpiDmDumpVrtc ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, sizeof (ACPI_VRTC_ENTRY), AcpiDmTableInfoVrtc0); if (ACPI_FAILURE (Status)) { @@ -4048,7 +4328,7 @@ AcpiDmDumpVrtc ( /* Point to next subtable */ Offset += sizeof (ACPI_VRTC_ENTRY); - SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Subtable, sizeof (ACPI_VRTC_ENTRY)); } } @@ -4072,7 +4352,7 @@ AcpiDmDumpWdat ( { ACPI_STATUS Status; UINT32 Offset = sizeof (ACPI_TABLE_WDAT); - ACPI_WDAT_ENTRY *SubTable; + ACPI_WDAT_ENTRY *Subtable; /* Main table */ @@ -4085,13 +4365,13 @@ AcpiDmDumpWdat ( /* Subtables */ - SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset); + Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset); while (Offset < Table->Length) { /* Common subtable header */ AcpiOsPrintf ("\n"); - Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0); if (ACPI_FAILURE (Status)) { @@ -4101,7 +4381,7 @@ AcpiDmDumpWdat ( /* Point to next subtable */ Offset += sizeof (ACPI_WDAT_ENTRY); - SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, + Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Subtable, sizeof (ACPI_WDAT_ENTRY)); } } @@ -4125,7 +4405,7 @@ AcpiDmDumpWpbt ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_TABLE_WPBT *SubTable; + ACPI_TABLE_WPBT *Subtable; UINT32 Length = Table->Length; UINT16 ArgumentsLength; @@ -4140,8 +4420,8 @@ AcpiDmDumpWpbt ( /* Extract the arguments buffer length from the main table */ - SubTable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table); - ArgumentsLength = SubTable->ArgumentsLength; + Subtable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table); + ArgumentsLength = Subtable->ArgumentsLength; /* Dump the arguments buffer */ diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c index 48ac7859cf4c..5487261a0e81 100644 --- a/sys/contrib/dev/acpica/common/dmtbinfo.c +++ b/sys/contrib/dev/acpica/common/dmtbinfo.c @@ -214,11 +214,13 @@ #define ACPI_MSCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MSCT,f) #define ACPI_NFIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_NFIT,f) #define ACPI_PCCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PCCT,f) +#define ACPI_PDTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PDTT,f) #define ACPI_PMTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PMTT,f) #define ACPI_RASF_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_RASF,f) #define ACPI_S3PT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_S3PT,f) #define ACPI_SBST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SBST,f) #define ACPI_SDEI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SDEI,f) +#define ACPI_SDEV_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SDEV,f) #define ACPI_SLIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIT,f) #define ACPI_SPCR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPCR,f) #define ACPI_SPMI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPMI,f) @@ -339,6 +341,7 @@ #define ACPI_PCCT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_HW_REDUCED_TYPE2,f) #define ACPI_PCCT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_EXT_PCC_MASTER,f) #define ACPI_PCCT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_EXT_PCC_SLAVE,f) +#define ACPI_PDTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PDTT_CHANNEL,f) #define ACPI_PMTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_SOCKET,f) #define ACPI_PMTT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_CONTROLLER,f) #define ACPI_PMTT1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_DOMAIN,f) @@ -351,6 +354,10 @@ #define ACPI_S3PTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_HEADER,f) #define ACPI_S3PT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_RESUME,f) #define ACPI_S3PT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_SUSPEND,f) +#define ACPI_SDEVH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_HEADER,f) +#define ACPI_SDEV0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_NAMESPACE,f) +#define ACPI_SDEV1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_PCIE,f) +#define ACPI_SDEV1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_PCIE_PATH,f) #define ACPI_SLIC_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIC,f) #define ACPI_SRATH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f) #define ACPI_SRAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_CPU_AFFINITY,f) @@ -360,6 +367,8 @@ #define ACPI_SRAT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_GIC_ITS_AFFINITY,f) #define ACPI_TCPA_CLIENT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_CLIENT,f) #define ACPI_TCPA_SERVER_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_SERVER,f) +#define ACPI_TPM2A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TPM2_TRAILER,f) +#define ACPI_TPM211_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TPM2_ARM_SMC,f) #define ACPI_VRTC0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_VRTC_ENTRY,f) #define ACPI_WDAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WDAT_ENTRY,f) @@ -415,7 +424,9 @@ #define ACPI_PCCT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_HW_REDUCED_TYPE2,f,o) #define ACPI_PCCT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_EXT_PCC_MASTER,f,o) #define ACPI_PCCT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_EXT_PCC_SLAVE,f,o) +#define ACPI_PDTT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PDTT_CHANNEL,f,o) #define ACPI_PMTTH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PMTT_HEADER,f,o) +#define ACPI_SDEVH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SDEV_HEADER,f,o) #define ACPI_WDDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WDDT,f,o) #define ACPI_WSMT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WSMT,f,o) #define ACPI_EINJ0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o) @@ -896,7 +907,6 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt1[] = ACPI_DMT_TERMINATOR }; - /* Resource Descriptor subtable */ ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2[] = @@ -1260,6 +1270,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[] = {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesExit), "Exit Services Exit", 0}, #endif + /******************************************************************************* * * GTDT - Generic Timer Description Table @@ -1853,6 +1864,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoIort4[] = ACPI_DMT_TERMINATOR }; + /******************************************************************************* * * IVRS - I/O Virtualization Reporting Structure @@ -2219,6 +2231,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt15[] = ACPI_DMT_TERMINATOR }; + /******************************************************************************* * * MCFG - PCI Memory Mapped Configuration table and Subtable @@ -2696,6 +2709,31 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPcct4[] = ACPI_DMT_TERMINATOR }; + +/******************************************************************************* + * + * PDTT - Platform Debug Trigger Table (ACPI 6.2) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt[] = +{ + {ACPI_DMT_UINT8, ACPI_PDTT_OFFSET (TriggerCount), "Trigger Count", 0}, + {ACPI_DMT_UINT24, ACPI_PDTT_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_PDTT_OFFSET (ArrayOffset), "Array Offset", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt0[] = +{ + {ACPI_DMT_UINT8, ACPI_PDTT0_OFFSET (SubchannelId), "Subchannel Id", 0}, + {ACPI_DMT_UINT8, ACPI_PDTT0_OFFSET (Flags), "Flags (Decoded Below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Runtime Trigger", 0}, + {ACPI_DMT_FLAG1, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Wait for Completion", 0}, + ACPI_DMT_TERMINATOR +}; + + /******************************************************************************* * * PMTT - Platform Memory Topology Table @@ -2768,16 +2806,6 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[] = ACPI_DMT_TERMINATOR }; -/******************************************************************************* - * - * SDEI - Software Delegated Execption Interface Descriptor Table - * - ******************************************************************************/ - -ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[] = -{ - ACPI_DMT_TERMINATOR -}; /******************************************************************************* * @@ -2801,7 +2829,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPpttHdr[] = ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0[] = { {ACPI_DMT_UINT16, ACPI_PPTT0_OFFSET (Reserved), "Reserved", 0}, - {ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Flags), "Flags (decoded below)", 0}, {ACPI_DMT_FLAG0, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Physical package", 0}, {ACPI_DMT_FLAG1, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "ACPI Processor ID valid", 0}, {ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Parent), "Parent", 0}, @@ -2821,7 +2849,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0a[] = ACPI_DMTABLE_INFO AcpiDmTableInfoPptt1[] = { {ACPI_DMT_UINT16, ACPI_PPTT1_OFFSET (Reserved), "Reserved", 0}, - {ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (Flags), "Flags (decoded below)", 0}, {ACPI_DMT_FLAG0, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Size valid", 0}, {ACPI_DMT_FLAG1, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Number of Sets valid", 0}, {ACPI_DMT_FLAG2, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Associativity valid", 0}, @@ -2855,6 +2883,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt2[] = ACPI_DMT_TERMINATOR }; + /******************************************************************************* * * RASF - RAS Feature table @@ -2867,6 +2896,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoRasf[] = ACPI_DMT_TERMINATOR }; + /******************************************************************************* * * S3PT - S3 Performance Table @@ -2925,6 +2955,86 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[] = }; +/******************************************************************************* + * + * SDEI - Software Delegated Execption Interface Descriptor Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[] = +{ + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SDEV - Secure Devices Table (ACPI 6.2) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev[] = +{ + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdevHdr[] = +{ + {ACPI_DMT_SDEV, ACPI_SDEVH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_SDEVH_OFFSET (Flags), "Flags (decoded below)", 0}, + {ACPI_DMT_FLAG0, ACPI_SDEVH_FLAG_OFFSET (Flags,0), "Allow handoff to unsecure OS", 0}, + {ACPI_DMT_UINT16, ACPI_SDEVH_OFFSET (Length), "Length", 0}, + ACPI_DMT_TERMINATOR +}; + +/* SDEV Subtables */ + +/* 0: Namespace Device Based Secure Device Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0[] = +{ + {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (DeviceIdOffset), "Device ID Offset", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (DeviceIdLength), "Device ID Length", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (VendorDataOffset), "Vendor Data Offset", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (VendorDataLength), "Vendor Data Length", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0a[] = +{ + {ACPI_DMT_STRING, 0, "Namepath", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: PCIe Endpoint Device Based Device Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1[] = +{ + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (Segment), "Segment", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (StartBus), "Start Bus", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (PathOffset), "Path Offset", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (PathLength), "Path Length", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (VendorDataOffset), "Vendor Data Offset", 0}, + {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (VendorDataLength), "Vendor Data Length", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1a[] = +{ + {ACPI_DMT_UINT8, ACPI_SDEV1A_OFFSET (Device), "Device", 0}, + {ACPI_DMT_UINT8, ACPI_SDEV1A_OFFSET (Function), "Function", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1b[] = +{ + {ACPI_DMT_RAW_BUFFER, 0, "Vendor Data", 0}, /*, DT_OPTIONAL}, */ + ACPI_DMT_TERMINATOR +}; + + /******************************************************************************* * * SLIC - Software Licensing Description Table. This table contains the standard @@ -3186,7 +3296,29 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[] = {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (PlatformClass), "Platform Class", 0}, {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (Reserved), "Reserved", 0}, {ACPI_DMT_UINT64, ACPI_TPM2_OFFSET (ControlAddress), "Control Address", 0}, - {ACPI_DMT_UINT32, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0}, + {ACPI_DMT_TPM2, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Optional trailer. LogLength and LogAddress are additionally optional */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2a[] = +{ + {ACPI_DMT_BUF12, ACPI_TPM2A_OFFSET (MethodParameters), "Method Parameters", DT_OPTIONAL}, + {ACPI_DMT_UINT32, ACPI_TPM2A_OFFSET (MinimumLogLength), "Minimum Log Length", DT_OPTIONAL}, + {ACPI_DMT_UINT64, ACPI_TPM2A_OFFSET (LogAddress), "Log Address", DT_OPTIONAL}, + ACPI_DMT_TERMINATOR +}; + +/* 11: Start Method for ARM SMC */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoTpm211[] = +{ + {ACPI_DMT_UINT32, ACPI_TPM211_OFFSET (GlobalInterrupt), "Global Interrupt", 0}, + {ACPI_DMT_UINT8, ACPI_TPM211_OFFSET (InterruptFlags), "Interrupt Flags", 0}, + {ACPI_DMT_UINT8, ACPI_TPM211_OFFSET (OperationFlags), "Operation Flags", 0}, + {ACPI_DMT_UINT16, ACPI_TPM211_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_TPM211_OFFSET (FunctionId), "Function ID", 0}, ACPI_DMT_TERMINATOR }; diff --git a/sys/contrib/dev/acpica/compiler/aslallocate.c b/sys/contrib/dev/acpica/compiler/aslallocate.c new file mode 100644 index 000000000000..e83a01f422ab --- /dev/null +++ b/sys/contrib/dev/acpica/compiler/aslallocate.c @@ -0,0 +1,303 @@ +/****************************************************************************** + * + * Module Name: aslallocate -- Local memory allocation + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + ***************************************************************************** + * + * Alternatively, you may choose to be licensed under the terms of the + * following license: + * + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + * + * Alternatively, you may choose to be licensed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + *****************************************************************************/ + +#include + +/* + * Local heap allocation wrappers. See aslcache.c for allocation from local + * cache alloctions + */ + + +/******************************************************************************* + * + * FUNCTION: UtLocalCalloc + * + * PARAMETERS: Size - Bytes to be allocated + * + * RETURN: Pointer to the allocated memory. If this function returns + * (the compiler is not aborted), the pointer is guaranteed to + * be valid. + * + * DESCRIPTION: Allocate zero-initialized memory. The point of this function + * is to abort the compile on an allocation failure, on the + * assumption that nothing more can be accomplished. + * + * NOTE: For allocation from the local caches, see aslcache.c + * + ******************************************************************************/ + +void * +UtLocalCalloc ( + UINT32 Size) +{ + void *Allocated; + + + Allocated = ACPI_ALLOCATE_ZEROED (Size); + if (!Allocated) + { + AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, + Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, + Gbl_InputByteCount, Gbl_CurrentColumn, + Gbl_Files[ASL_FILE_INPUT].Filename, NULL); + + CmCleanupAndExit (); + exit (1); + } + + TotalAllocations++; + TotalAllocated += Size; + return (Allocated); +} + + +/****************************************************************************** + * + * FUNCTION: UtExpandLineBuffers + * + * PARAMETERS: None. Updates global line buffer pointers. + * + * RETURN: None. Reallocates the global line buffers + * + * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates + * all global line buffers and updates Gbl_LineBufferSize. NOTE: + * Also used for the initial allocation of the buffers, when + * all of the buffer pointers are NULL. Initial allocations are + * of size ASL_DEFAULT_LINE_BUFFER_SIZE + * + *****************************************************************************/ + +void +UtExpandLineBuffers ( + void) +{ + UINT32 NewSize; + + + /* Attempt to double the size of all line buffers */ + + NewSize = Gbl_LineBufferSize * 2; + if (Gbl_CurrentLineBuffer) + { + DbgPrint (ASL_DEBUG_OUTPUT, + "Increasing line buffer size from %u to %u\n", + Gbl_LineBufferSize, NewSize); + } + + UtReallocLineBuffers (&Gbl_CurrentLineBuffer, Gbl_LineBufferSize, NewSize); + UtReallocLineBuffers (&Gbl_MainTokenBuffer, Gbl_LineBufferSize, NewSize); + UtReallocLineBuffers (&Gbl_MacroTokenBuffer, Gbl_LineBufferSize, NewSize); + UtReallocLineBuffers (&Gbl_ExpressionTokenBuffer, Gbl_LineBufferSize, NewSize); + + Gbl_LineBufPtr = Gbl_CurrentLineBuffer; + Gbl_LineBufferSize = NewSize; +} + + +/****************************************************************************** + * + * FUNCTION: UtReallocLineBuffers + * + * PARAMETERS: Buffer - Buffer to realloc + * OldSize - Old size of Buffer + * NewSize - New size of Buffer + * + * RETURN: none + * + * DESCRIPTION: Reallocate and initialize Buffer + * + *****************************************************************************/ + +void +UtReallocLineBuffers ( + char **Buffer, + UINT32 OldSize, + UINT32 NewSize) +{ + + *Buffer = realloc (*Buffer, NewSize); + if (*Buffer) + { + memset (*Buffer + OldSize, 0, NewSize - OldSize); + return; + } + + printf ("Could not increase line buffer size from %u to %u\n", + OldSize, NewSize); + + AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, NULL, NULL); + AslAbort (); +} + + +/****************************************************************************** + * + * FUNCTION: UtFreeLineBuffers + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Free all line buffers + * + *****************************************************************************/ + +void +UtFreeLineBuffers ( + void) +{ + + free (Gbl_CurrentLineBuffer); + free (Gbl_MainTokenBuffer); + free (Gbl_MacroTokenBuffer); + free (Gbl_ExpressionTokenBuffer); +} diff --git a/sys/contrib/dev/acpica/compiler/aslcache.c b/sys/contrib/dev/acpica/compiler/aslcache.c new file mode 100644 index 000000000000..1e54a2fa8d7c --- /dev/null +++ b/sys/contrib/dev/acpica/compiler/aslcache.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * + * Module Name: aslcache -- Local cache support for iASL + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + ***************************************************************************** + * + * Alternatively, you may choose to be licensed under the terms of the + * following license: + * + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + * + * Alternatively, you may choose to be licensed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + *****************************************************************************/ + +#include + +/* + * Local caches. The caches are fully deleted after the compilation/disassembly + * of each individual input file. Thus, individual allocations from the cache + * memory do not need to be freed or even released back into the cache. + * + * See aslallocate.c for standard heap allocations. + */ + + +/******************************************************************************* + * + * FUNCTION: UtLocalCacheCalloc + * + * PARAMETERS: Length - Size of buffer requested + * + * RETURN: Pointer to the buffer. Aborts compiler on allocation failure + * + * DESCRIPTION: Allocate a string buffer. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +char * +UtLocalCacheCalloc ( + UINT32 Length) +{ + char *Buffer; + ASL_CACHE_INFO *Cache; + UINT32 CacheSize = ASL_STRING_CACHE_SIZE; + + + if (Length > CacheSize) + { + CacheSize = Length; + + if (Gbl_StringCacheList) + { + Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); + + /* Link new cache buffer just following head of list */ + + Cache->Next = Gbl_StringCacheList->Next; + Gbl_StringCacheList->Next = Cache; + + /* Leave cache management pointers alone as they pertain to head */ + + Gbl_StringCount++; + Gbl_StringSize += Length; + + return (Cache->Buffer); + } + } + + if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_StringCacheList; + Gbl_StringCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_StringCacheNext = Cache->Buffer; + Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize; + } + + Gbl_StringCount++; + Gbl_StringSize += Length; + + Buffer = Gbl_StringCacheNext; + Gbl_StringCacheNext += Length; + return (Buffer); +} + + +/******************************************************************************* + * + * FUNCTION: UtParseOpCacheCalloc + * + * PARAMETERS: None + * + * RETURN: New parse op. Aborts on allocation failure + * + * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +ACPI_PARSE_OBJECT * +UtParseOpCacheCalloc ( + void) +{ + ASL_CACHE_INFO *Cache; + + + if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE)); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_ParseOpCacheList; + Gbl_ParseOpCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer); + Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE; + } + + Gbl_ParseOpCount++; + return (Gbl_ParseOpCacheNext++); +} + + +/******************************************************************************* + * + * FUNCTION: UtSubtableCacheCalloc - Data Table compiler + * + * PARAMETERS: None + * + * RETURN: Pointer to the buffer. Aborts on allocation failure + * + * DESCRIPTION: Allocate a subtable object buffer. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +DT_SUBTABLE * +UtSubtableCacheCalloc ( + void) +{ + ASL_CACHE_INFO *Cache; + + + if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_SubtableCacheList; + Gbl_SubtableCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); + Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; + } + + Gbl_SubtableCount++; + return (Gbl_SubtableCacheNext++); +} + + +/******************************************************************************* + * + * FUNCTION: UtFieldCacheCalloc - Data Table compiler + * + * PARAMETERS: None + * + * RETURN: Pointer to the buffer. Aborts on allocation failure + * + * DESCRIPTION: Allocate a field object buffer. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +DT_FIELD * +UtFieldCacheCalloc ( + void) +{ + ASL_CACHE_INFO *Cache; + + + if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_FieldCacheList; + Gbl_FieldCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); + Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; + } + + Gbl_FieldCount++; + return (Gbl_FieldCacheNext++); +} + + +/******************************************************************************* + * + * FUNCTION: UtDeleteLocalCaches + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Delete all local cache buffer blocks + * + ******************************************************************************/ + +void +UtDeleteLocalCaches ( + void) +{ + UINT32 BufferCount; + ASL_CACHE_INFO *Next; + + + /* + * Generic cache, arbitrary size allocations + */ + BufferCount = 0; + while (Gbl_StringCacheList) + { + Next = Gbl_StringCacheList->Next; + ACPI_FREE (Gbl_StringCacheList); + Gbl_StringCacheList = Next; + BufferCount++; + } + + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n", + Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount); + + /* Reset cache globals */ + + Gbl_StringSize = 0; + Gbl_StringCount = 0; + Gbl_StringCacheNext = NULL; + Gbl_StringCacheLast = NULL; + + + /* + * Parse Op cache + */ + BufferCount = 0; + while (Gbl_ParseOpCacheList) + { + Next = Gbl_ParseOpCacheList->Next; + ACPI_FREE (Gbl_ParseOpCacheList); + Gbl_ParseOpCacheList = Next; + BufferCount++; + } + + DbgPrint (ASL_DEBUG_OUTPUT, + "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n", + Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE, + (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount); + + /* Reset cache globals */ + + Gbl_ParseOpCount = 0; + Gbl_ParseOpCacheNext = NULL; + Gbl_ParseOpCacheLast = NULL; + Gbl_ParseTreeRoot = NULL; + + + /* + * Table Compiler - Field cache + */ + BufferCount = 0; + while (Gbl_FieldCacheList) + { + Next = Gbl_FieldCacheList->Next; + ACPI_FREE (Gbl_FieldCacheList); + Gbl_FieldCacheList = Next; + BufferCount++; + } + + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", + Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, + (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); + + /* Reset cache globals */ + + Gbl_FieldCount = 0; + Gbl_FieldCacheNext = NULL; + Gbl_FieldCacheLast = NULL; + + + /* + * Table Compiler - Subtable cache + */ + BufferCount = 0; + while (Gbl_SubtableCacheList) + { + Next = Gbl_SubtableCacheList->Next; + ACPI_FREE (Gbl_SubtableCacheList); + Gbl_SubtableCacheList = Next; + BufferCount++; + } + + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", + Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, + (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); + + /* Reset cache globals */ + + Gbl_SubtableCount = 0; + Gbl_SubtableCacheNext = NULL; + Gbl_SubtableCacheLast = NULL; +} diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c index 5bd460def46b..826ae12f189b 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompile.c +++ b/sys/contrib/dev/acpica/compiler/aslcompile.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #include #include @@ -932,70 +931,7 @@ CmCleanupAndExit ( if (!Gbl_DoAslConversion) { - CmDeleteCaches (); + UtDeleteLocalCaches (); } } - - -/******************************************************************************* - * - * FUNCTION: CmDeleteCaches - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Delete all local cache buffer blocks - * - ******************************************************************************/ - -void -CmDeleteCaches ( - void) -{ - UINT32 BufferCount; - ASL_CACHE_INFO *Next; - - - /* Parse Op cache */ - - BufferCount = 0; - while (Gbl_ParseOpCacheList) - { - Next = Gbl_ParseOpCacheList->Next; - ACPI_FREE (Gbl_ParseOpCacheList); - Gbl_ParseOpCacheList = Next; - BufferCount++; - } - - DbgPrint (ASL_DEBUG_OUTPUT, - "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n", - Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE, - (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount); - - Gbl_ParseOpCount = 0; - Gbl_ParseOpCacheNext = NULL; - Gbl_ParseOpCacheLast = NULL; - Gbl_ParseTreeRoot = NULL; - - /* Generic string cache */ - - BufferCount = 0; - while (Gbl_StringCacheList) - { - Next = Gbl_StringCacheList->Next; - ACPI_FREE (Gbl_StringCacheList); - Gbl_StringCacheList = Next; - BufferCount++; - } - - DbgPrint (ASL_DEBUG_OUTPUT, - "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n", - Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount); - - Gbl_StringSize = 0; - Gbl_StringCount = 0; - Gbl_StringCacheNext = NULL; - Gbl_StringCacheLast = NULL; -} diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h index fd7e7dbfee95..96bfc979c9f3 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompiler.h +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h @@ -181,6 +181,7 @@ #include #include #include +#include /******************************************************************************* @@ -265,8 +266,50 @@ void CmCleanupAndExit ( void); + +/* + * aslallocate - memory allocation + */ +void * +UtLocalCalloc ( + UINT32 Size); + void -CmDeleteCaches ( +UtExpandLineBuffers ( + void); + +void +UtReallocLineBuffers ( + char **Buffer, + UINT32 OldSize, + UINT32 NewSize); + +void +UtFreeLineBuffers ( + void); + + +/* + * aslcache - local cache support + */ +char * +UtLocalCacheCalloc ( + UINT32 Length); + +ACPI_PARSE_OBJECT * +UtParseOpCacheCalloc ( + void); + +DT_SUBTABLE * +UtSubtableCacheCalloc ( + void); + +DT_FIELD * +UtFieldCacheCalloc ( + void); + +void +UtDeleteLocalCaches ( void); @@ -406,6 +449,16 @@ void AslAbort ( void); +void +AslDualParseOpError ( + UINT8 Level, + UINT16 MainMessageId, + ACPI_PARSE_OBJECT *MainOp, + char *MainMessage, + UINT16 SecondMessageId, + ACPI_PARSE_OBJECT *SecondOp, + char *SecondaryMessage); + void AslError ( UINT8 Level, @@ -1150,10 +1203,6 @@ void UtEndEvent ( UINT8 Event); -void * -UtLocalCalloc ( - UINT32 Size); - void UtDisplaySummary ( UINT32 FileId); @@ -1176,18 +1225,6 @@ void UtSetParseOpName ( ACPI_PARSE_OBJECT *Op); -char * -UtStringCacheCalloc ( - UINT32 Length); - -void -UtExpandLineBuffers ( - void); - -void -UtFreeLineBuffers ( - void); - ACPI_STATUS UtInternalizeName ( char *ExternalName, diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l index 9a1a8d1e99e7..38fe15a2c922 100644 --- a/sys/contrib/dev/acpica/compiler/aslcompiler.l +++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l @@ -813,7 +813,7 @@ NamePathTail [.]{NameSeg} {NameSeg} { char *s; count (0); - s=UtStringCacheCalloc (ACPI_NAME_SIZE + 1); + s=UtLocalCacheCalloc (ACPI_NAME_SIZE + 1); if (strcmp (AslCompilertext, "\\")) { strcpy (s, "____"); @@ -826,7 +826,7 @@ NamePathTail [.]{NameSeg} {NameString} { char *s; count (0); - s=UtStringCacheCalloc (strlen (AslCompilertext)+1); + s=UtLocalCacheCalloc (strlen (AslCompilertext)+1); AcpiUtStrupr (AslCompilertext); strcpy (s, AslCompilertext); AslCompilerlval.s = s; diff --git a/sys/contrib/dev/acpica/compiler/asldebug.c b/sys/contrib/dev/acpica/compiler/asldebug.c index 780d584fca2b..2129fc977f7c 100644 --- a/sys/contrib/dev/acpica/compiler/asldebug.c +++ b/sys/contrib/dev/acpica/compiler/asldebug.c @@ -356,7 +356,7 @@ UtCreateEscapeSequences ( /* New string buffer, 3 extra chars per escape (4 total) */ - OutString = UtLocalCalloc (InStringLength + (EscapeCount * 3)); + OutString = UtLocalCacheCalloc (InStringLength + (EscapeCount * 3)); OutStringPtr = OutString; /* Convert non-ascii or non-printable chars to escape sequences */ diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c index 013826e79bc7..f8c6c98d860b 100644 --- a/sys/contrib/dev/acpica/compiler/aslerror.c +++ b/sys/contrib/dev/acpica/compiler/aslerror.c @@ -170,6 +170,37 @@ AslIsExceptionDisabled ( UINT8 Level, UINT16 MessageId); +static void AslInitEnode ( + ASL_ERROR_MSG **Enode, + UINT8 Level, + UINT16 MessageId, + UINT32 LineNumber, + UINT32 LogicalLineNumber, + UINT32 LogicalByteOffset, + UINT32 Column, + char *Filename, + char *Message, + char *SourceLine, + ASL_ERROR_MSG *SubError); + +static void +AslLogNewError ( + UINT8 Level, + UINT16 MessageId, + UINT32 LineNumber, + UINT32 LogicalLineNumber, + UINT32 LogicalByteOffset, + UINT32 Column, + char *Filename, + char *Message, + char *SourceLine, + ASL_ERROR_MSG *SubError); + +static void +AePrintSubError ( + FILE *OutputFile, + ASL_ERROR_MSG *Enode); + /******************************************************************************* * @@ -220,6 +251,7 @@ AeClearErrorLog ( ASL_ERROR_MSG *Enode = Gbl_ErrorLog; ASL_ERROR_MSG *Next; + /* Walk the error node list */ while (Enode) @@ -270,8 +302,7 @@ AeAddToErrorLog ( Prev = NULL; Next = Gbl_ErrorLog; - while ((Next) && - (Next->LogicalLineNumber <= Enode->LogicalLineNumber)) + while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber)) { Prev = Next; Next = Next->Next; @@ -294,240 +325,33 @@ AeAddToErrorLog ( /******************************************************************************* * - * FUNCTION: AePrintException + * FUNCTION: AeDecodeErrorMessageId * - * PARAMETERS: FileId - ID of output file + * PARAMETERS: OutputFile - Output file * Enode - Error node to print - * Header - Additional text before each message + * PrematureEOF - True = PrematureEOF has been reached + * Total - Total legth of line * * RETURN: None * - * DESCRIPTION: Print the contents of an error node. - * - * NOTE: We don't use the FlxxxFile I/O functions here because on error - * they abort the compiler and call this function! Since we - * are reporting errors here, we ignore most output errors and - * just try to get out as much as we can. + * DESCRIPTION: Print the source line of an error. * ******************************************************************************/ -void -AePrintException ( - UINT32 FileId, +static void +AeDecodeErrorMessageId ( + FILE *OutputFile, ASL_ERROR_MSG *Enode, - char *Header) + BOOLEAN PrematureEOF, + UINT32 Total) { - UINT8 SourceByte; - int Actual; - size_t RActual; UINT32 MsgLength; const char *MainMessage; char *ExtraMessage; UINT32 SourceColumn; UINT32 ErrorColumn; - FILE *OutputFile; - FILE *SourceFile = NULL; - long FileSize; - BOOLEAN PrematureEOF = FALSE; - UINT32 Total = 0; - if (Gbl_NoErrors) - { - return; - } - - /* - * Only listing files have a header, and remarks/optimizations - * are always output - */ - if (!Header) - { - /* Ignore remarks if requested */ - - switch (Enode->Level) - { - case ASL_WARNING: - case ASL_WARNING2: - case ASL_WARNING3: - - if (!Gbl_DisplayWarnings) - { - return; - } - break; - - case ASL_REMARK: - - if (!Gbl_DisplayRemarks) - { - return; - } - break; - - case ASL_OPTIMIZATION: - - if (!Gbl_DisplayOptimizations) - { - return; - } - break; - - default: - - break; - } - } - - /* Get the various required file handles */ - - OutputFile = Gbl_Files[FileId].Handle; - - if (!Enode->SourceLine) - { - /* - * Use the merged header/source file if present, otherwise - * use input file - */ - SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; - if (!SourceFile) - { - SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; - } - - if (SourceFile) - { - /* Determine if the error occurred at source file EOF */ - - fseek (SourceFile, 0, SEEK_END); - FileSize = ftell (SourceFile); - - if ((long) Enode->LogicalByteOffset >= FileSize) - { - PrematureEOF = TRUE; - } - } - } - - if (Header) - { - fprintf (OutputFile, "%s", Header); - } - - /* Print filename and line number if present and valid */ - - if (Enode->Filename) - { - if (Gbl_VerboseErrors) - { - fprintf (OutputFile, "%-8s", Enode->Filename); - - if (Enode->LineNumber) - { - if (Enode->SourceLine) - { - fprintf (OutputFile, " %6u: %s", - Enode->LineNumber, Enode->SourceLine); - } - else - { - fprintf (OutputFile, " %6u: ", Enode->LineNumber); - - /* - * If not at EOF, get the corresponding source code line - * and display it. Don't attempt this if we have a - * premature EOF condition. - */ - if (!PrematureEOF) - { - /* - * Seek to the offset in the combined source file, - * read the source line, and write it to the output. - */ - Actual = fseek (SourceFile, - (long) Enode->LogicalByteOffset, (int) SEEK_SET); - if (Actual) - { - fprintf (OutputFile, - "[*** iASL: Seek error on source code temp file %s ***]", - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - } - else - { - RActual = fread (&SourceByte, 1, 1, SourceFile); - if (RActual != 1) - { - fprintf (OutputFile, - "[*** iASL: Read error on source code temp file %s ***]", - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - } - else - { - /* Read/write the source line, up to the maximum line length */ - - while (RActual && SourceByte && (SourceByte != '\n')) - { - if (Total < 256) - { - /* After the max line length, we will just read the line, no write */ - - if (fwrite (&SourceByte, 1, 1, OutputFile) != 1) - { - printf ("[*** iASL: Write error on output file ***]\n"); - return; - } - } - else if (Total == 256) - { - fprintf (OutputFile, - "\n[*** iASL: Very long input line, message below refers to column %u ***]", - Enode->Column); - } - - RActual = fread (&SourceByte, 1, 1, SourceFile); - if (RActual != 1) - { - fprintf (OutputFile, - "[*** iASL: Read error on source code temp file %s ***]", - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - return; - } - Total++; - } - } - } - } - - fprintf (OutputFile, "\n"); - } - } - } - else - { - /* - * Less verbose version of the error message, enabled via the - * -vi switch. The format is compatible with MS Visual Studio. - */ - fprintf (OutputFile, "%s", Enode->Filename); - - if (Enode->LineNumber) - { - fprintf (OutputFile, "(%u) : ", - Enode->LineNumber); - } - } - } - - /* If a NULL message ID, just print the raw message */ - - if (Enode->MessageId == 0) - { - fprintf (OutputFile, "%s\n", Enode->Message); - return; - } - - /* Decode the message ID */ - fprintf (OutputFile, "%s %4.4d -", AeDecodeExceptionLevel (Enode->Level), AeBuildFullExceptionCode (Enode->Level, Enode->MessageId)); @@ -602,13 +426,328 @@ AePrintException ( } fprintf (OutputFile, "\n"); - if (Gbl_VerboseErrors) + if (Gbl_VerboseErrors && !Enode->SubError) { fprintf (OutputFile, "\n"); } } +/******************************************************************************* + * + * FUNCTION: AePrintErrorSourceLine + * + * PARAMETERS: OutputFile - Output file + * Enode - Error node to print + * PrematureEOF - True = PrematureEOF has been reached + * Total - amount of characters printed so far + * + * + * RETURN: Status + * + * DESCRIPTION: Print the source line of an error. + * + ******************************************************************************/ + +static ACPI_STATUS +AePrintErrorSourceLine ( + FILE *OutputFile, + ASL_ERROR_MSG *Enode, + BOOLEAN *PrematureEOF, + UINT32 *Total) +{ + UINT8 SourceByte; + int Actual; + size_t RActual; + FILE *SourceFile = NULL; + long FileSize; + + + if (!Enode->SourceLine) + { + /* + * Use the merged header/source file if present, otherwise + * use input file + */ + SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; + if (!SourceFile) + { + SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; + } + + if (SourceFile) + { + /* Determine if the error occurred at source file EOF */ + + fseek (SourceFile, 0, SEEK_END); + FileSize = ftell (SourceFile); + + if ((long) Enode->LogicalByteOffset >= FileSize) + { + *PrematureEOF = TRUE; + } + } + else + { + fprintf (OutputFile, + "[*** iASL: Source File Does not exist ***]\n"); + return AE_IO_ERROR; + } + } + + /* Print filename and line number if present and valid */ + + if (Gbl_VerboseErrors) + { + fprintf (OutputFile, "%-8s", Enode->Filename); + + if (Enode->SourceLine && Enode->LineNumber) + { + fprintf (OutputFile, " %6u: %s", + Enode->LineNumber, Enode->SourceLine); + } + else if (Enode->LineNumber) + { + fprintf (OutputFile, " %6u: ", Enode->LineNumber); + + /* + * If not at EOF, get the corresponding source code line + * and display it. Don't attempt this if we have a + * premature EOF condition. + */ + if (*PrematureEOF) + { + fprintf (OutputFile, "\n"); + return AE_OK; + } + /* + * Seek to the offset in the combined source file, + * read the source line, and write it to the output. + */ + Actual = fseek (SourceFile, + (long) Enode->LogicalByteOffset, (int) SEEK_SET); + if (Actual) + { + fprintf (OutputFile, + "[*** iASL: Seek error on source code temp file %s ***]", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + + fprintf (OutputFile, "\n"); + return AE_OK; + } + RActual = fread (&SourceByte, 1, 1, SourceFile); + if (RActual != 1) + { + fprintf (OutputFile, + "[*** iASL: Read error on source code temp file %s ***]", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + return AE_IO_ERROR; + } + /* Read/write the source line, up to the maximum line length */ + + while (RActual && SourceByte && (SourceByte != '\n')) + { + if (*Total < 256) + { + /* After the max line length, we will just read the line, no write */ + + if (fwrite (&SourceByte, 1, 1, OutputFile) != 1) + { + printf ("[*** iASL: Write error on output file ***]\n"); + return AE_IO_ERROR; + } + } + else if (*Total == 256) + { + fprintf (OutputFile, + "\n[*** iASL: Very long input line, message below refers to column %u ***]", + Enode->Column); + } + + RActual = fread (&SourceByte, 1, 1, SourceFile); + if (RActual != 1) + { + fprintf (OutputFile, + "[*** iASL: Read error on source code temp file %s ***]", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + + return AE_IO_ERROR; + } + *Total += 1; + } + + fprintf (OutputFile, "\n"); + } + } + else + { + /* + * Less verbose version of the error message, enabled via the + * -vi switch. The format is compatible with MS Visual Studio. + */ + fprintf (OutputFile, "%s", Enode->Filename); + + if (Enode->LineNumber) + { + fprintf (OutputFile, "(%u) : ", + Enode->LineNumber); + } + } + + return AE_OK; +} + +/******************************************************************************* + * + * FUNCTION: AePrintException + * + * PARAMETERS: FileId - ID of output file + * Enode - Error node to print + * Header - Additional text before each message + * + * RETURN: None + * + * DESCRIPTION: Print the contents of an error node. + * + * NOTE: We don't use the FlxxxFile I/O functions here because on error + * they abort the compiler and call this function! Since we + * are reporting errors here, we ignore most output errors and + * just try to get out as much as we can. + * + ******************************************************************************/ + +void +AePrintException ( + UINT32 FileId, + ASL_ERROR_MSG *Enode, + char *Header) +{ + FILE *OutputFile; + BOOLEAN PrematureEOF = FALSE; + UINT32 Total = 0; + ACPI_STATUS Status; + ASL_ERROR_MSG *Child = Enode->SubError; + + + if (Gbl_NoErrors) + { + return; + } + + /* + * Only listing files have a header, and remarks/optimizations + * are always output + */ + if (!Header) + { + /* Ignore remarks if requested */ + + switch (Enode->Level) + { + case ASL_WARNING: + case ASL_WARNING2: + case ASL_WARNING3: + + if (!Gbl_DisplayWarnings) + { + return; + } + break; + + case ASL_REMARK: + + if (!Gbl_DisplayRemarks) + { + return; + } + break; + + case ASL_OPTIMIZATION: + + if (!Gbl_DisplayOptimizations) + { + return; + } + break; + + default: + + break; + } + } + + /* Get the various required file handles */ + + OutputFile = Gbl_Files[FileId].Handle; + + if (Header) + { + fprintf (OutputFile, "%s", Header); + } + + if (!Enode->Filename) + { + AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total); + return; + } + + Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* If a NULL message ID, just print the raw message */ + + if (Enode->MessageId == 0) + { + fprintf (OutputFile, "%s\n", Enode->Message); + return; + } + + AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total); + + while (Child) + { + fprintf (OutputFile, "\n"); + AePrintSubError (OutputFile, Child); + Child = Child->SubError; + } +} + + +/******************************************************************************* + * + * FUNCTION: AePrintSubError + * + * PARAMETERS: OutputFile - Output file + * Enode - Error node to print + * + * RETURN: None + * + * DESCRIPTION: Print the contents of an error nodes. This function is tailored + * to print error nodes that are SubErrors within ASL_ERROR_MSG + * + ******************************************************************************/ + +static void +AePrintSubError ( + FILE *OutputFile, + ASL_ERROR_MSG *Enode) +{ + UINT32 Total = 0; + BOOLEAN PrematureEOF = FALSE; + const char *MainMessage; + + + MainMessage = AeDecodeMessageId (Enode->MessageId); + + fprintf (OutputFile, " %s%s", MainMessage, "\n "); + (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total); + fprintf (OutputFile, "\n"); +} + + /******************************************************************************* * * FUNCTION: AePrintErrorLog @@ -638,6 +777,87 @@ AePrintErrorLog ( } +/******************************************************************************* + * + * FUNCTION: AslInitEnode + * + * PARAMETERS: InputEnode - Input Error node to initialize + * Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer + * CurrentLineNumber - Actual file line number + * LogicalLineNumber - Cumulative line number + * LogicalByteOffset - Byte offset in source file + * Column - Column in current line + * Filename - source filename + * ExtraMessage - additional error message + * SourceLine - Line of error source code + * SubError - SubError of this InputEnode + * + * RETURN: None + * + * DESCRIPTION: Initialize an Error node + * + ******************************************************************************/ + +static void AslInitEnode ( + ASL_ERROR_MSG **InputEnode, + UINT8 Level, + UINT16 MessageId, + UINT32 LineNumber, + UINT32 LogicalLineNumber, + UINT32 LogicalByteOffset, + UINT32 Column, + char *Filename, + char *ExtraMessage, + char *SourceLine, + ASL_ERROR_MSG *SubError) +{ + ASL_ERROR_MSG *Enode; + + + *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG)); + Enode = *InputEnode; + Enode->Level = Level; + Enode->MessageId = MessageId; + Enode->LineNumber = LineNumber; + Enode->LogicalLineNumber = LogicalLineNumber; + Enode->LogicalByteOffset = LogicalByteOffset; + Enode->Column = Column; + Enode->SubError = SubError; + Enode->Message = NULL; + Enode->SourceLine = NULL; + Enode->Filename = NULL; + + if (ExtraMessage) + { + /* Allocate a buffer for the message and a new error node */ + + Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1); + + /* Keep a copy of the extra message */ + + strcpy (Enode->Message, ExtraMessage); + } + + if (SourceLine) + { + Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1); + strcpy (Enode->SourceLine, SourceLine); + } + + + if (Filename) + { + Enode->Filename = Filename; + Enode->FilenameLength = strlen (Filename); + if (Enode->FilenameLength < 6) + { + Enode->FilenameLength = 6; + } + } +} + + /******************************************************************************* * * FUNCTION: AslCommonError2 @@ -666,60 +886,8 @@ AslCommonError2 ( char *Filename, char *ExtraMessage) { - char *MessageBuffer = NULL; - char *LineBuffer; - ASL_ERROR_MSG *Enode; - - - Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG)); - - if (ExtraMessage) - { - /* Allocate a buffer for the message and a new error node */ - - MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1); - - /* Keep a copy of the extra message */ - - strcpy (MessageBuffer, ExtraMessage); - } - - LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1); - strcpy (LineBuffer, SourceLine); - - /* Initialize the error node */ - - if (Filename) - { - Enode->Filename = Filename; - Enode->FilenameLength = strlen (Filename); - if (Enode->FilenameLength < 6) - { - Enode->FilenameLength = 6; - } - } - - Enode->MessageId = MessageId; - Enode->Level = Level; - Enode->LineNumber = LineNumber; - Enode->LogicalLineNumber = LineNumber; - Enode->LogicalByteOffset = 0; - Enode->Column = Column; - Enode->Message = MessageBuffer; - Enode->SourceLine = LineBuffer; - - /* Add the new node to the error node list */ - - AeAddToErrorLog (Enode); - - if (Gbl_DebugFlag) - { - /* stderr is a file, send error to it immediately */ - - AePrintException (ASL_FILE_STDERR, Enode, NULL); - } - - Gbl_ExceptionCount[Level]++; + AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column, + Filename, ExtraMessage, SourceLine, NULL); } @@ -753,48 +921,51 @@ AslCommonError ( char *Filename, char *ExtraMessage) { - char *MessageBuffer = NULL; - ASL_ERROR_MSG *Enode; + AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber, + LogicalByteOffset, Column, Filename, ExtraMessage, + NULL, NULL); +} - if (AslIsExceptionIgnored (Level, MessageId)) - { - return; - } +/******************************************************************************* + * + * FUNCTION: AslLogNewError + * + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer + * CurrentLineNumber - Actual file line number + * LogicalLineNumber - Cumulative line number + * LogicalByteOffset - Byte offset in source file + * Column - Column in current line + * Filename - source filename + * Message - additional error message + * SourceLine - Actual line of source code + * SubError - Sub-error associated with this error + * + * RETURN: None + * + * DESCRIPTION: Create a new error node and add it to the error log + * + ******************************************************************************/ +static void +AslLogNewError ( + UINT8 Level, + UINT16 MessageId, + UINT32 LineNumber, + UINT32 LogicalLineNumber, + UINT32 LogicalByteOffset, + UINT32 Column, + char *Filename, + char *Message, + char *SourceLine, + ASL_ERROR_MSG *SubError) +{ + ASL_ERROR_MSG *Enode = NULL; - Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG)); - if (ExtraMessage) - { - /* Allocate a buffer for the message and a new error node */ - - MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1); - - /* Keep a copy of the extra message */ - - strcpy (MessageBuffer, ExtraMessage); - } - - /* Initialize the error node */ - - if (Filename) - { - Enode->Filename = Filename; - Enode->FilenameLength = strlen (Filename); - if (Enode->FilenameLength < 6) - { - Enode->FilenameLength = 6; - } - } - - Enode->MessageId = MessageId; - Enode->Level = Level; - Enode->LineNumber = CurrentLineNumber; - Enode->LogicalLineNumber = LogicalLineNumber; - Enode->LogicalByteOffset = LogicalByteOffset; - Enode->Column = Column; - Enode->Message = MessageBuffer; - Enode->SourceLine = NULL; + AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber, + LogicalByteOffset, Column, Filename, Message, SourceLine, + SubError); /* Add the new node to the error node list */ @@ -825,8 +996,8 @@ AslCommonError ( * * FUNCTION: AslIsExceptionIgnored * - * PARAMETERS: Level - Seriousness (Warning/error, etc.) - * MessageId - Index into global message buffer + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer * * RETURN: BOOLEAN * @@ -840,7 +1011,7 @@ AslIsExceptionIgnored ( UINT8 Level, UINT16 MessageId) { - BOOLEAN ExceptionIgnored; + BOOLEAN ExceptionIgnored; /* Note: this allows exception to be disabled and expected */ @@ -869,7 +1040,8 @@ void AslCheckExpectedExceptions ( void) { - UINT8 i; + UINT8 i; + for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i) { @@ -980,8 +1152,8 @@ AslDisableException ( * * FUNCTION: AslIsExceptionDisabled * - * PARAMETERS: Level - Seriousness (Warning/error, etc.) - * MessageId - Index into global message buffer + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer * * RETURN: TRUE if exception/message should be ignored * @@ -999,9 +1171,8 @@ AslIsExceptionExpected ( UINT32 i; - /* - * Mark this exception as received - */ + /* Mark this exception as received */ + EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId); for (i = 0; i < Gbl_ExpectedMessagesIndex; i++) { @@ -1080,6 +1251,61 @@ AslIsExceptionDisabled ( } +/******************************************************************************* + * + * FUNCTION: AslDualParseOpError + * + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MainMsgId - Index into global message buffer + * MainOp - Parse node where error happened + * MainMsg - Message pertaining to the MainOp + * SubMsgId - Index into global message buffer + * SubOp - Additional parse node for better message + * SubMsg - Message pertainint to SubOp + * + * + * RETURN: None + * + * DESCRIPTION: Main error reporting routine for the ASL compiler for error + * messages that point to multiple parse objects. + * + ******************************************************************************/ + +void +AslDualParseOpError ( + UINT8 Level, + UINT16 MainMsgId, + ACPI_PARSE_OBJECT *MainOp, + char *MainMsg, + UINT16 SubMsgId, + ACPI_PARSE_OBJECT *SubOp, + char *SubMsg) +{ + ASL_ERROR_MSG *SubEnode = NULL; + + + /* Check if user wants to ignore this exception */ + + if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp) + { + return; + } + + if (SubOp) + { + AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber, + SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset, + SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg, + NULL, NULL); + } + + AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber, + MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset, + MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg, + NULL, SubEnode); +} + + /******************************************************************************* * * FUNCTION: AslError diff --git a/sys/contrib/dev/acpica/compiler/aslfiles.c b/sys/contrib/dev/acpica/compiler/aslfiles.c index 1ebfb9f48ff4..e5d6f85a0be3 100644 --- a/sys/contrib/dev/acpica/compiler/aslfiles.c +++ b/sys/contrib/dev/acpica/compiler/aslfiles.c @@ -151,7 +151,6 @@ #include #include -#include #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("aslfiles") @@ -326,14 +325,14 @@ FlMergePathnames ( (*FilePathname == '/') || (FilePathname[1] == ':')) { - Pathname = UtStringCacheCalloc (strlen (FilePathname) + 1); + Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1); strcpy (Pathname, FilePathname); goto ConvertBackslashes; } /* Need a local copy of the prefix directory path */ - CommonPath = UtStringCacheCalloc (strlen (PrefixDir) + 1); + CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1); strcpy (CommonPath, PrefixDir); /* @@ -369,7 +368,7 @@ FlMergePathnames ( /* Build the final merged pathname */ ConcatenatePaths: - Pathname = UtStringCacheCalloc ( + Pathname = UtLocalCacheCalloc ( strlen (CommonPath) + strlen (FilePathname) + 2); if (LastElement && *CommonPath) { diff --git a/sys/contrib/dev/acpica/compiler/aslhelp.c b/sys/contrib/dev/acpica/compiler/aslhelp.c index 1c0278c9833f..ed3a33298fa9 100644 --- a/sys/contrib/dev/acpica/compiler/aslhelp.c +++ b/sys/contrib/dev/acpica/compiler/aslhelp.c @@ -173,6 +173,7 @@ void Usage ( void) { + printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); printf ("%s\n\n", ASL_COMPLIANCE); ACPI_USAGE_HEADER ("iasl [Options] [Files]"); diff --git a/sys/contrib/dev/acpica/compiler/aslload.c b/sys/contrib/dev/acpica/compiler/aslload.c index 7480f232afb1..19864533267a 100644 --- a/sys/contrib/dev/acpica/compiler/aslload.c +++ b/sys/contrib/dev/acpica/compiler/aslload.c @@ -327,8 +327,9 @@ LdLoadFieldElements ( * The name already exists in this scope * But continue processing the elements */ - AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, - Child->Asl.Value.String); + AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, + Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op, + Node->Op->Asl.ExternalName); } } else @@ -388,8 +389,10 @@ LdLoadResourceElements ( { /* Actual node causing the error was saved in ParentMethod */ - AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, - (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); + AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, + (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, + Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op, + Node->Op->Asl.ExternalName); return (AE_OK); } return (Status); @@ -805,8 +808,8 @@ LdNamespace1Begin ( /* * Allow one create on an object or segment that was * previously declared External only if WalkState->OwnerId and - * Node->OwnerId are found in different tables (meaning that - * they have differnt OwnerIds). + * Node->OwnerId are different (meaning that the current WalkState + * and the Node are in different tables). */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; @@ -827,8 +830,9 @@ LdNamespace1Begin ( if (Node->OwnerId == WalkState->OwnerId && !(Node->Flags & IMPLICIT_EXTERNAL)) { - AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, - Op->Asl.ExternalName); + AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, + Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, + Node->Op->Asl.ExternalName); } if (Node->Flags & IMPLICIT_EXTERNAL) { @@ -849,8 +853,9 @@ LdNamespace1Begin ( if (Node->OwnerId == WalkState->OwnerId) { - AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, - Op->Asl.ExternalName); + AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, + Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, + Node->Op->Asl.ExternalName); } } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && @@ -905,8 +910,9 @@ LdNamespace1Begin ( { /* Valid error, object already exists */ - AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, - Op->Asl.ExternalName); + AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, + Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, + Node->Op->Asl.ExternalName); return_ACPI_STATUS (AE_OK); } } diff --git a/sys/contrib/dev/acpica/compiler/aslmapenter.c b/sys/contrib/dev/acpica/compiler/aslmapenter.c index 6e391097eabb..8476654e40a0 100644 --- a/sys/contrib/dev/acpica/compiler/aslmapenter.c +++ b/sys/contrib/dev/acpica/compiler/aslmapenter.c @@ -332,7 +332,7 @@ MpCreateGpioInfo ( * sorted by both source device name and then the pin number. There is * one block per pin. */ - Buffer = UtStringCacheCalloc (sizeof (ACPI_GPIO_INFO)); + Buffer = UtLocalCacheCalloc (sizeof (ACPI_GPIO_INFO)); Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Buffer); NextGpio = Gbl_GpioList; @@ -409,7 +409,7 @@ MpCreateSerialInfo ( * Allocate a new info block and insert it into the global Serial list * sorted by both source device name and then the address. */ - Buffer = UtStringCacheCalloc (sizeof (ACPI_SERIAL_INFO)); + Buffer = UtLocalCacheCalloc (sizeof (ACPI_SERIAL_INFO)); Info = ACPI_CAST_PTR (ACPI_SERIAL_INFO, Buffer); NextSerial = Gbl_SerialList; diff --git a/sys/contrib/dev/acpica/compiler/aslmaputils.c b/sys/contrib/dev/acpica/compiler/aslmaputils.c index c17f090cea6b..37333041203e 100644 --- a/sys/contrib/dev/acpica/compiler/aslmaputils.c +++ b/sys/contrib/dev/acpica/compiler/aslmaputils.c @@ -212,7 +212,7 @@ MpGetHidFromParseTree ( /* Convert EISAID to a string */ - HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE); + HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE); AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer); return (HidString); @@ -277,7 +277,7 @@ MpGetHidValue ( /* Convert EISAID to a string */ - HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE); + HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE); AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value); return (HidString); diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.c b/sys/contrib/dev/acpica/compiler/aslmessages.c index efe7e9945c91..1ced65479513 100644 --- a/sys/contrib/dev/acpica/compiler/aslmessages.c +++ b/sys/contrib/dev/acpica/compiler/aslmessages.c @@ -350,7 +350,9 @@ const char *AslCompilerMsgs [] = /* ASL_MSG_CONSTANT_REQUIRED */ "Non-reducible expression", /* ASL_MSG_CROSS_TABLE_SCOPE */ "Illegal open scope on external object from within DSDT", /* ASL_MSG_EXCEPTION_NOT_RECEIVED */ "Expected remark, warning, or error did not occur. Message ID:", -/* ASL_MSG_NULL_RESOURCE_TEMPLATE */ "Empty Resource Template (END_TAG only)" +/* ASL_MSG_NULL_RESOURCE_TEMPLATE */ "Empty Resource Template (END_TAG only)", +/* ASL_MSG_FOUND_HERE */ "Original name creation/declaration below: ", +/* ASL_MSG_ILLEGAL_RECURSION */ "Illegal recursive call to method that creates named objects" }; /* Table compiler */ diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.h b/sys/contrib/dev/acpica/compiler/aslmessages.h index d69c05a176c6..a80184016ce1 100644 --- a/sys/contrib/dev/acpica/compiler/aslmessages.h +++ b/sys/contrib/dev/acpica/compiler/aslmessages.h @@ -353,6 +353,8 @@ typedef enum ASL_MSG_CROSS_TABLE_SCOPE, ASL_MSG_EXCEPTION_NOT_RECEIVED, ASL_MSG_NULL_RESOURCE_TEMPLATE, + ASL_MSG_FOUND_HERE, + ASL_MSG_ILLEGAL_RECURSION, /* These messages are used by the Data Table compiler only */ diff --git a/sys/contrib/dev/acpica/compiler/aslmethod.c b/sys/contrib/dev/acpica/compiler/aslmethod.c index a4b1c6f97f78..ca48bc82133f 100644 --- a/sys/contrib/dev/acpica/compiler/aslmethod.c +++ b/sys/contrib/dev/acpica/compiler/aslmethod.c @@ -347,10 +347,31 @@ MtMethodAnalysisWalkBegin ( case PARSEOP_METHODCALL: + /* Check for a recursive method call */ + if (MethodInfo && (Op->Asl.Node == MethodInfo->Op->Asl.Node)) { - AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); + if (MethodInfo->CreatesNamedObjects) + { + /* + * This is an error, as it will fail at runtime on all ACPI + * implementations. Any named object declarations will be + * executed twice, causing failure the second time. Note, + * this is independent of whether the method is declared + * Serialized, because the same thread is attempting to + * reenter the method, and this will always succeed. + */ + AslDualParseOpError (ASL_ERROR, ASL_MSG_ILLEGAL_RECURSION, Op, + Op->Asl.Value.String, ASL_MSG_FOUND_HERE, MethodInfo->Op, + MethodInfo->Op->Asl.ExternalName); + } + else + { + /* Method does not create objects, issue a remark */ + + AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); + } } break; @@ -622,20 +643,28 @@ MtCheckNamedObjectInMethod ( return; } - /* Determine if we are creating a named object */ + /* Determine if we are creating a named object within a method */ + + if (!MethodInfo) + { + return; + } OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) { /* - * If we have a named object created within a non-serialized method, - * emit a remark that the method should be serialized. + * 1) Mark the method as a method that creates named objects. + * + * 2) If the method is non-serialized, emit a remark that the method + * should be serialized. * * Reason: If a thread blocks within the method for any reason, and - * another thread enters the method, the method will fail because an - * attempt will be made to create the same object twice. + * another thread enters the method, the method will fail because + * an attempt will be made to create the same object twice. */ - if (MethodInfo && !MethodInfo->ShouldBeSerialized) + MethodInfo->CreatesNamedObjects = TRUE; + if (!MethodInfo->ShouldBeSerialized) { AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, "due to creation of named objects within"); diff --git a/sys/contrib/dev/acpica/compiler/asloperands.c b/sys/contrib/dev/acpica/compiler/asloperands.c index 0a5f1443911e..c6e001fe49bf 100644 --- a/sys/contrib/dev/acpica/compiler/asloperands.c +++ b/sys/contrib/dev/acpica/compiler/asloperands.c @@ -1037,7 +1037,7 @@ OpnDoDefinitionBlock ( * We will use the AML filename that is embedded in the source file * for the output filename. */ - Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) + + Filename = UtLocalCacheCalloc (strlen (Gbl_DirectoryPath) + strlen ((char *) Child->Asl.Value.Buffer) + 1); /* Prepend the current directory path */ @@ -1094,7 +1094,7 @@ OpnDoDefinitionBlock ( if (Child->Asl.Value.String) { Length = strlen (Child->Asl.Value.String); - Gbl_TableId = UtStringCacheCalloc (Length + 1); + Gbl_TableId = UtLocalCacheCalloc (Length + 1); strcpy (Gbl_TableId, Child->Asl.Value.String); /* diff --git a/sys/contrib/dev/acpica/compiler/aslopt.c b/sys/contrib/dev/acpica/compiler/aslopt.c index 0019a07cbf42..6aaa386a59d8 100644 --- a/sys/contrib/dev/acpica/compiler/aslopt.c +++ b/sys/contrib/dev/acpica/compiler/aslopt.c @@ -275,7 +275,7 @@ OptSearchToRoot ( /* We must allocate a new string for the name (TargetPath gets deleted) */ - *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1); + *NewPath = UtLocalCacheCalloc (ACPI_NAME_SIZE + 1); strcpy (*NewPath, Path); if (strncmp (*NewPath, "_T_", 3)) diff --git a/sys/contrib/dev/acpica/compiler/asloptions.c b/sys/contrib/dev/acpica/compiler/asloptions.c index a22949bb6317..45fe735e86d2 100644 --- a/sys/contrib/dev/acpica/compiler/asloptions.c +++ b/sys/contrib/dev/acpica/compiler/asloptions.c @@ -204,7 +204,6 @@ AslCommandLine ( if (argc < 2) { - printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); Usage (); exit (1); } @@ -538,7 +537,6 @@ AslDoOptions ( { case '^': - printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); Usage (); exit (0); diff --git a/sys/contrib/dev/acpica/compiler/aslparseop.c b/sys/contrib/dev/acpica/compiler/aslparseop.c index f23091bb62f0..7a8db74c72fc 100644 --- a/sys/contrib/dev/acpica/compiler/aslparseop.c +++ b/sys/contrib/dev/acpica/compiler/aslparseop.c @@ -158,13 +158,6 @@ ACPI_MODULE_NAME ("aslparseop") -/* Local prototypes */ - -static ACPI_PARSE_OBJECT * -TrGetOpFromCache ( - void); - - /******************************************************************************* * * FUNCTION: TrCreateOp @@ -490,7 +483,7 @@ TrCreateTargetOp ( return (NULL); } - Op = TrGetOpFromCache (); + Op = UtParseOpCacheCalloc (); /* Copy the pertinent values (omit link pointer fields) */ @@ -788,7 +781,7 @@ TrAllocateOp ( ACPI_PARSE_OBJECT *LatestOp; - Op = TrGetOpFromCache (); + Op = UtParseOpCacheCalloc (); Op->Asl.ParseOpcode = (UINT16) ParseOpcode; Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename; @@ -875,50 +868,6 @@ TrAllocateOp ( } -/******************************************************************************* - * - * FUNCTION: TrGetOpFromCache - * - * PARAMETERS: None - * - * RETURN: New parse op. Aborts on allocation failure - * - * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local - * dynamic memory manager for performance reasons (This has a - * major impact on the speed of the compiler.) - * - ******************************************************************************/ - -static ACPI_PARSE_OBJECT * -TrGetOpFromCache ( - void) -{ - ASL_CACHE_INFO *Cache; - - - if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast) - { - /* Allocate a new buffer */ - - Cache = UtLocalCalloc (sizeof (Cache->Next) + - (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE)); - - /* Link new cache buffer to head of list */ - - Cache->Next = Gbl_ParseOpCacheList; - Gbl_ParseOpCacheList = Cache; - - /* Setup cache management pointers */ - - Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer); - Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE; - } - - Gbl_ParseOpCount++; - return (Gbl_ParseOpCacheNext++); -} - - /******************************************************************************* * * FUNCTION: TrPrintOpFlags diff --git a/sys/contrib/dev/acpica/compiler/aslprintf.c b/sys/contrib/dev/acpica/compiler/aslprintf.c index a626f24a232f..00e218d05df7 100644 --- a/sys/contrib/dev/acpica/compiler/aslprintf.c +++ b/sys/contrib/dev/acpica/compiler/aslprintf.c @@ -293,7 +293,7 @@ OpcParsePrintf ( if (StringToProcess) { - NewString = UtStringCacheCalloc (StringLength + 1); + NewString = UtLocalCacheCalloc (StringLength + 1); strncpy (NewString, StartPosition, StringLength); NewOp = TrAllocateOp (PARSEOP_STRING_LITERAL); @@ -382,7 +382,7 @@ OpcParsePrintf ( if (StringToProcess) { - NewString = UtStringCacheCalloc (StringLength + 1); + NewString = UtLocalCacheCalloc (StringLength + 1); strncpy (NewString, StartPosition, StringLength); NewOp = TrAllocateOp (PARSEOP_STRING_LITERAL); diff --git a/sys/contrib/dev/acpica/compiler/aslstartup.c b/sys/contrib/dev/acpica/compiler/aslstartup.c index 8ce0375d296c..df75e1b72701 100644 --- a/sys/contrib/dev/acpica/compiler/aslstartup.c +++ b/sys/contrib/dev/acpica/compiler/aslstartup.c @@ -410,7 +410,7 @@ AslDoDisassembly ( Gbl_Files[ASL_FILE_INPUT].Filename = NULL; - CmDeleteCaches (); + UtDeleteLocalCaches (); return (AE_OK); } @@ -453,7 +453,7 @@ AslDoOneFile ( /* Take a copy of the input filename, convert any backslashes */ Gbl_Files[ASL_FILE_INPUT].Filename = - UtStringCacheCalloc (strlen (Filename) + 1); + UtLocalCacheCalloc (strlen (Filename) + 1); strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename); diff --git a/sys/contrib/dev/acpica/compiler/aslsupport.l b/sys/contrib/dev/acpica/compiler/aslsupport.l index 42cee752a952..40cead33c3c5 100644 --- a/sys/contrib/dev/acpica/compiler/aslsupport.l +++ b/sys/contrib/dev/acpica/compiler/aslsupport.l @@ -382,7 +382,7 @@ AslPushInputFileStack ( /* Reset the global line count and filename */ Gbl_Files[ASL_FILE_INPUT].Filename = - UtStringCacheCalloc (strlen (Filename) + 1); + UtLocalCacheCalloc (strlen (Filename) + 1); strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); @@ -1009,7 +1009,7 @@ CompletedString: */ *StringBuffer = 0; - CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1); + CleanString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1); strcpy (CleanString, MsgBuffer); AslCompilerlval.s = CleanString; return (TRUE); diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h index e4250871fd12..f72226d5e0c9 100644 --- a/sys/contrib/dev/acpica/compiler/asltypes.h +++ b/sys/contrib/dev/acpica/compiler/asltypes.h @@ -202,6 +202,7 @@ typedef struct asl_method_info UINT8 ArgInitialized[ACPI_METHOD_NUM_ARGS]; UINT8 HasBeenTyped; UINT8 ShouldBeSerialized; + UINT8 CreatesNamedObjects; } ASL_METHOD_INFO; @@ -337,8 +338,11 @@ typedef struct asl_include_dir } ASL_INCLUDE_DIR; -/* An entry in the exception list, one for each error/warning */ - +/* + * An entry in the exception list, one for each error/warning + * Note: SubError nodes would be treated with the same messageId and Level + * as the parent error node. + */ typedef struct asl_error_msg { UINT32 LineNumber; @@ -347,6 +351,7 @@ typedef struct asl_error_msg UINT32 Column; char *Message; struct asl_error_msg *Next; + struct asl_error_msg *SubError; char *Filename; char *SourceLine; UINT32 FilenameLength; diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c index e800970f8ef1..e34f21ee2c15 100644 --- a/sys/contrib/dev/acpica/compiler/aslutils.c +++ b/sys/contrib/dev/acpica/compiler/aslutils.c @@ -174,12 +174,6 @@ UtAttachNameseg ( ACPI_PARSE_OBJECT *Op, char *Name); -static void -UtReallocLineBuffers ( - char **Buffer, - UINT32 OldSize, - UINT32 NewSize); - /******************************************************************************* * @@ -309,45 +303,6 @@ UtDisplayConstantOpcodes ( } -/******************************************************************************* - * - * FUNCTION: UtLocalCalloc - * - * PARAMETERS: Size - Bytes to be allocated - * - * RETURN: Pointer to the allocated memory. Guaranteed to be valid. - * - * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an - * allocation failure, on the assumption that nothing more can be - * accomplished. - * - ******************************************************************************/ - -void * -UtLocalCalloc ( - UINT32 Size) -{ - void *Allocated; - - - Allocated = ACPI_ALLOCATE_ZEROED (Size); - if (!Allocated) - { - AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, - Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, - Gbl_InputByteCount, Gbl_CurrentColumn, - Gbl_Files[ASL_FILE_INPUT].Filename, NULL); - - CmCleanupAndExit (); - exit (1); - } - - TotalAllocations++; - TotalAllocated += Size; - return (Allocated); -} - - /******************************************************************************* * * FUNCTION: UtBeginEvent @@ -635,180 +590,6 @@ UtCheckIntegerRange ( } -/******************************************************************************* - * - * FUNCTION: UtStringCacheCalloc - * - * PARAMETERS: Length - Size of buffer requested - * - * RETURN: Pointer to the buffer. Aborts compiler on allocation failure - * - * DESCRIPTION: Allocate a string buffer. Bypass the local - * dynamic memory manager for performance reasons (This has a - * major impact on the speed of the compiler.) - * - ******************************************************************************/ - -char * -UtStringCacheCalloc ( - UINT32 Length) -{ - char *Buffer; - ASL_CACHE_INFO *Cache; - UINT32 CacheSize = ASL_STRING_CACHE_SIZE; - - - if (Length > CacheSize) - { - CacheSize = Length; - - if (Gbl_StringCacheList) - { - Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); - - /* Link new cache buffer just following head of list */ - - Cache->Next = Gbl_StringCacheList->Next; - Gbl_StringCacheList->Next = Cache; - - /* Leave cache management pointers alone as they pertain to head */ - - Gbl_StringCount++; - Gbl_StringSize += Length; - - return (Cache->Buffer); - } - } - - if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) - { - /* Allocate a new buffer */ - - Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); - - /* Link new cache buffer to head of list */ - - Cache->Next = Gbl_StringCacheList; - Gbl_StringCacheList = Cache; - - /* Setup cache management pointers */ - - Gbl_StringCacheNext = Cache->Buffer; - Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize; - } - - Gbl_StringCount++; - Gbl_StringSize += Length; - - Buffer = Gbl_StringCacheNext; - Gbl_StringCacheNext += Length; - return (Buffer); -} - - -/****************************************************************************** - * - * FUNCTION: UtExpandLineBuffers - * - * PARAMETERS: None. Updates global line buffer pointers. - * - * RETURN: None. Reallocates the global line buffers - * - * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates - * all global line buffers and updates Gbl_LineBufferSize. NOTE: - * Also used for the initial allocation of the buffers, when - * all of the buffer pointers are NULL. Initial allocations are - * of size ASL_DEFAULT_LINE_BUFFER_SIZE - * - *****************************************************************************/ - -void -UtExpandLineBuffers ( - void) -{ - UINT32 NewSize; - - - /* Attempt to double the size of all line buffers */ - - NewSize = Gbl_LineBufferSize * 2; - if (Gbl_CurrentLineBuffer) - { - DbgPrint (ASL_DEBUG_OUTPUT, - "Increasing line buffer size from %u to %u\n", - Gbl_LineBufferSize, NewSize); - } - - UtReallocLineBuffers (&Gbl_CurrentLineBuffer, Gbl_LineBufferSize, NewSize); - UtReallocLineBuffers (&Gbl_MainTokenBuffer, Gbl_LineBufferSize, NewSize); - UtReallocLineBuffers (&Gbl_MacroTokenBuffer, Gbl_LineBufferSize, NewSize); - UtReallocLineBuffers (&Gbl_ExpressionTokenBuffer, Gbl_LineBufferSize, NewSize); - - Gbl_LineBufPtr = Gbl_CurrentLineBuffer; - Gbl_LineBufferSize = NewSize; -} - - -/****************************************************************************** - * - * FUNCTION: UtReallocLineBuffers - * - * PARAMETERS: Buffer - Buffer to realloc - * OldSize - Old size of Buffer - * NewSize - New size of Buffer - * - * RETURN: none - * - * DESCRIPTION: Reallocate and initialize Buffer - * - *****************************************************************************/ - -static void -UtReallocLineBuffers ( - char **Buffer, - UINT32 OldSize, - UINT32 NewSize) -{ - - *Buffer = realloc (*Buffer, NewSize); - if (*Buffer) - { - memset (*Buffer + OldSize, 0, NewSize - OldSize); - return; - } - - printf ("Could not increase line buffer size from %u to %u\n", - OldSize, NewSize); - - AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, NULL, NULL); - AslAbort (); -} - - -/****************************************************************************** - * - * FUNCTION: UtFreeLineBuffers - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Free all line buffers - * - *****************************************************************************/ - -void -UtFreeLineBuffers ( - void) -{ - - free (Gbl_CurrentLineBuffer); - free (Gbl_MainTokenBuffer); - free (Gbl_MacroTokenBuffer); - free (Gbl_ExpressionTokenBuffer); -} - - /******************************************************************************* * * FUNCTION: UtInternalizeName @@ -843,7 +624,7 @@ UtInternalizeName ( /* We need a segment to store the internal name */ - Info.InternalName = UtStringCacheCalloc (Info.Length); + Info.InternalName = UtLocalCacheCalloc (Info.Length); /* Build the name */ diff --git a/sys/contrib/dev/acpica/compiler/cvcompiler.c b/sys/contrib/dev/acpica/compiler/cvcompiler.c index 57eef4b682bb..0e9746a4d2cf 100644 --- a/sys/contrib/dev/acpica/compiler/cvcompiler.c +++ b/sys/contrib/dev/acpica/compiler/cvcompiler.c @@ -193,7 +193,7 @@ CvProcessComment ( *StringBuffer = 0; CvDbgPrint ("Multi-line comment\n"); - CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1); + CommentString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1); strcpy (CommentString, MsgBuffer); CvDbgPrint ("CommentString: %s\n", CommentString); @@ -208,7 +208,7 @@ CvProcessComment ( if (LineToken) { - FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1); + FinalLineToken = UtLocalCacheCalloc (strlen (LineToken) + 1); strcpy (FinalLineToken, LineToken); /* Get rid of any carriage returns */ @@ -238,7 +238,7 @@ CvProcessComment ( } } - FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1); + FinalLineToken = UtLocalCacheCalloc (strlen (LineToken) + 1); strcat (FinalLineToken, LineToken); /* Get rid of any carriage returns */ @@ -268,7 +268,7 @@ CvProcessComment ( * spacing. */ FinalCommentString = - UtStringCacheCalloc (strlen (CommentString) + + UtLocalCacheCalloc (strlen (CommentString) + CurrentState.SpacesBefore + 1); for (i = 0; (CurrentState.CommentType != ASL_COMMENT_STANDARD) && @@ -313,7 +313,7 @@ CvProcessCommentType2 ( { *StringBuffer = 0; /* null terminate */ CvDbgPrint ("Single-line comment\n"); - CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1); + CommentString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1); strcpy (CommentString, MsgBuffer); /* If this comment lies on the same line as the latest parse op, @@ -342,7 +342,7 @@ CvProcessCommentType2 ( * [ (spaces) (comment) ( * /) ('\0') ] * */ - FinalCommentString = UtStringCacheCalloc (CurrentState.SpacesBefore + + FinalCommentString = UtLocalCacheCalloc (CurrentState.SpacesBefore + strlen (CommentString) + 3 + 1); for (i = 0; (CurrentState.CommentType != 1) && @@ -507,7 +507,7 @@ CgWriteAmlDefBlockComment( /* First, print the file name comment after changing .asl to .dsl */ - NewFilename = UtStringCacheCalloc (strlen (Op->Asl.Filename)); + NewFilename = UtLocalCacheCalloc (strlen (Op->Asl.Filename)); strcpy (NewFilename, Op->Asl.Filename); DirectoryPosition = strrchr (NewFilename, '/'); Position = strrchr (NewFilename, '.'); @@ -944,7 +944,7 @@ CvAppendInlineComment ( Size = strlen (ToAdd); Size += strlen (InlineComment); - Str = UtStringCacheCalloc (Size + 1); + Str = UtLocalCacheCalloc (Size + 1); strcpy (Str, InlineComment); strcat (Str, ToAdd); diff --git a/sys/contrib/dev/acpica/compiler/cvparser.c b/sys/contrib/dev/acpica/compiler/cvparser.c index eb89c4638958..77cffd027bae 100644 --- a/sys/contrib/dev/acpica/compiler/cvparser.c +++ b/sys/contrib/dev/acpica/compiler/cvparser.c @@ -714,7 +714,7 @@ CvCaptureCommentsOnly ( UINT8 *Aml = ParserState->Aml; UINT16 Opcode = (UINT16) ACPI_GET8 (Aml); UINT32 Length = 0; - UINT8 CommentOption = (UINT16) ACPI_GET8 (Aml+1); + UINT8 CommentOption; BOOLEAN StdDefBlockFlag = FALSE; ACPI_COMMENT_NODE *CommentNode; ACPI_FILE_NODE *FileNode; diff --git a/sys/contrib/dev/acpica/compiler/dtcompile.c b/sys/contrib/dev/acpica/compiler/dtcompile.c index b3d4fe27a5ec..67607a5f08e7 100644 --- a/sys/contrib/dev/acpica/compiler/dtcompile.c +++ b/sys/contrib/dev/acpica/compiler/dtcompile.c @@ -152,7 +152,6 @@ #define _DECLARE_DT_GLOBALS #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dtcompile") @@ -281,7 +280,6 @@ DtDoCompile ( CleanupAndExit: AcpiUtDeleteCaches (); - DtDeleteCaches (); CmCleanupAndExit (); return (Status); } @@ -412,7 +410,7 @@ DtCompileDataTable ( return (AE_ERROR); } - Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1); + Gbl_Signature = UtLocalCacheCalloc (strlen (Signature) + 1); strcpy (Gbl_Signature, Signature); /* @@ -585,7 +583,7 @@ DtCompileTable ( if (Length > 0) { - String = UtStringCacheCalloc (Length); + String = UtLocalCacheCalloc (Length); Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); } @@ -828,7 +826,7 @@ DtCompilePadding ( if (Length > 0) { - String = UtStringCacheCalloc (Length); + String = UtLocalCacheCalloc (Length); Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); } diff --git a/sys/contrib/dev/acpica/compiler/dtcompiler.h b/sys/contrib/dev/acpica/compiler/dtcompiler.h index bf4a9a84b5ce..244784da83a9 100644 --- a/sys/contrib/dev/acpica/compiler/dtcompiler.h +++ b/sys/contrib/dev/acpica/compiler/dtcompiler.h @@ -154,7 +154,6 @@ #ifndef _DTCOMPILER #define _DTCOMPILER -#include #include @@ -510,18 +509,6 @@ void DtSetTableLength( void); -DT_SUBTABLE * -UtSubtableCacheCalloc ( - void); - -DT_FIELD * -UtFieldCacheCalloc ( - void); - -void -DtDeleteCaches ( - void); - /* dttable - individual table compilation */ @@ -621,6 +608,14 @@ ACPI_STATUS DtCompileNfit ( void **PFieldList); +ACPI_STATUS +DtCompilePcct ( + void **PFieldList); + +ACPI_STATUS +DtCompilePdtt ( + void **PFieldList); + ACPI_STATUS DtCompilePmtt ( void **PFieldList); @@ -629,10 +624,6 @@ ACPI_STATUS DtCompilePptt ( void **PFieldList); -ACPI_STATUS -DtCompilePcct ( - void **PFieldList); - ACPI_STATUS DtCompileRsdt ( void **PFieldList); @@ -641,6 +632,10 @@ ACPI_STATUS DtCompileS3pt ( DT_FIELD **PFieldList); +ACPI_STATUS +DtCompileSdev ( + void **PFieldList); + ACPI_STATUS DtCompileSlic ( void **PFieldList); @@ -661,6 +656,10 @@ ACPI_STATUS DtCompileTcpa ( void **PFieldList); +ACPI_STATUS +DtCompileTpm2 ( + void **PFieldList); + ACPI_STATUS DtCompileUefi ( void **PFieldList); @@ -724,6 +723,7 @@ extern const unsigned char TemplateMsdm[]; extern const unsigned char TemplateMtmr[]; extern const unsigned char TemplateNfit[]; extern const unsigned char TemplatePcct[]; +extern const unsigned char TemplatePdtt[]; extern const unsigned char TemplatePmtt[]; extern const unsigned char TemplatePptt[]; extern const unsigned char TemplateRasf[]; @@ -731,6 +731,7 @@ extern const unsigned char TemplateRsdt[]; extern const unsigned char TemplateS3pt[]; extern const unsigned char TemplateSbst[]; extern const unsigned char TemplateSdei[]; +extern const unsigned char TemplateSdev[]; extern const unsigned char TemplateSlic[]; extern const unsigned char TemplateSlit[]; extern const unsigned char TemplateSpcr[]; diff --git a/sys/contrib/dev/acpica/compiler/dtexpress.c b/sys/contrib/dev/acpica/compiler/dtexpress.c index b5ba58b85b6e..68211c03def2 100644 --- a/sys/contrib/dev/acpica/compiler/dtexpress.c +++ b/sys/contrib/dev/acpica/compiler/dtexpress.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #include "dtparser.y.h" #define _COMPONENT DT_COMPILER diff --git a/sys/contrib/dev/acpica/compiler/dtfield.c b/sys/contrib/dev/acpica/compiler/dtfield.c index b22a1ae7946b..96c3ea9b5bff 100644 --- a/sys/contrib/dev/acpica/compiler/dtfield.c +++ b/sys/contrib/dev/acpica/compiler/dtfield.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dtfield") diff --git a/sys/contrib/dev/acpica/compiler/dtio.c b/sys/contrib/dev/acpica/compiler/dtio.c index 90015acc70bf..3b081a02dd12 100644 --- a/sys/contrib/dev/acpica/compiler/dtio.c +++ b/sys/contrib/dev/acpica/compiler/dtio.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #include #define _COMPONENT DT_COMPILER @@ -239,7 +238,7 @@ DtTrim ( if (!strcmp (String, " ")) { - ReturnString = UtStringCacheCalloc (1); + ReturnString = UtLocalCacheCalloc (1); return (ReturnString); } @@ -287,7 +286,7 @@ DtTrim ( /* Create the trimmed return string */ Length = ACPI_PTR_DIFF (End, Start) + 1; - ReturnString = UtStringCacheCalloc (Length + 1); + ReturnString = UtLocalCacheCalloc (Length + 1); if (strlen (Start)) { strncpy (ReturnString, Start, Length); diff --git a/sys/contrib/dev/acpica/compiler/dtparser.y b/sys/contrib/dev/acpica/compiler/dtparser.y index 1d6cb8e8b806..38bc96922526 100644 --- a/sys/contrib/dev/acpica/compiler/dtparser.y +++ b/sys/contrib/dev/acpica/compiler/dtparser.y @@ -151,7 +151,6 @@ *****************************************************************************/ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dtparser") diff --git a/sys/contrib/dev/acpica/compiler/dtsubtable.c b/sys/contrib/dev/acpica/compiler/dtsubtable.c index d75fa927a072..a258a61eb5ca 100644 --- a/sys/contrib/dev/acpica/compiler/dtsubtable.c +++ b/sys/contrib/dev/acpica/compiler/dtsubtable.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dtsubtable") @@ -186,7 +185,7 @@ DtCreateSubtable ( /* Create a new buffer for the subtable data */ - String = UtStringCacheCalloc (Length); + String = UtLocalCacheCalloc (Length); Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); memcpy (Subtable->Buffer, Buffer, Length); diff --git a/sys/contrib/dev/acpica/compiler/dttable.c b/sys/contrib/dev/acpica/compiler/dttable.c index 0d1df7fe612b..7c3e9db9e06d 100644 --- a/sys/contrib/dev/acpica/compiler/dttable.c +++ b/sys/contrib/dev/acpica/compiler/dttable.c @@ -152,7 +152,6 @@ /* Compile routines for the basic ACPI tables */ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dttable") diff --git a/sys/contrib/dev/acpica/compiler/dttable1.c b/sys/contrib/dev/acpica/compiler/dttable1.c index 81a61b3accf2..5d4aca11a21c 100644 --- a/sys/contrib/dev/acpica/compiler/dttable1.c +++ b/sys/contrib/dev/acpica/compiler/dttable1.c @@ -152,7 +152,6 @@ /* Compile all complex data tables, signatures starting with A-I */ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dttable1") diff --git a/sys/contrib/dev/acpica/compiler/dttable2.c b/sys/contrib/dev/acpica/compiler/dttable2.c index 4460394de9bb..51f5b2c488ff 100644 --- a/sys/contrib/dev/acpica/compiler/dttable2.c +++ b/sys/contrib/dev/acpica/compiler/dttable2.c @@ -152,7 +152,6 @@ /* Compile all complex data tables, signatures starting with L-Z */ #include -#include #define _COMPONENT DT_COMPILER ACPI_MODULE_NAME ("dttable2") @@ -902,6 +901,66 @@ DtCompilePcct ( } +/****************************************************************************** + * + * FUNCTION: DtCompilePdtt + * + * PARAMETERS: List - Current field list pointer + * + * RETURN: Status + * + * DESCRIPTION: Compile PDTT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompilePdtt ( + void **List) +{ + ACPI_STATUS Status; + DT_SUBTABLE *Subtable; + DT_SUBTABLE *ParentTable; + DT_FIELD **PFieldList = (DT_FIELD **) List; + ACPI_TABLE_PDTT *PdttHeader; + UINT32 Count = 0; + + + /* Main table */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); + PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); + + /* There is only one type of subtable at this time, no need to decode */ + + while (*PFieldList) + { + /* List of subchannel IDs, each 2 bytes */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + DtInsertSubtable (ParentTable, Subtable); + Count++; + } + + PdttHeader->TriggerCount = (UINT8) Count; + return (AE_OK); +} + + /****************************************************************************** * * FUNCTION: DtCompilePmtt @@ -1283,6 +1342,219 @@ DtCompileS3pt ( } +/****************************************************************************** + * + * FUNCTION: DtCompileSdev + * + * PARAMETERS: List - Current field list pointer + * + * RETURN: Status + * + * DESCRIPTION: Compile SDEV. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileSdev ( + void **List) +{ + ACPI_STATUS Status; + ACPI_SDEV_HEADER *SdevHeader; + DT_SUBTABLE *Subtable; + DT_SUBTABLE *ParentTable; + ACPI_DMTABLE_INFO *InfoTable; + DT_FIELD **PFieldList = (DT_FIELD **) List; + DT_FIELD *SubtableStart; + ACPI_SDEV_PCIE *Pcie = NULL; + ACPI_SDEV_NAMESPACE *Namesp = NULL; + UINT32 EntryCount; + + + /* Subtables */ + + while (*PFieldList) + { + /* Compile common SDEV subtable header */ + + SubtableStart = *PFieldList; + Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + DtPushSubtable (Subtable); + + SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); + SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); + + switch (SdevHeader->Type) + { + case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: + + InfoTable = AcpiDmTableInfoSdev0; + Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); + break; + + case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: + + InfoTable = AcpiDmTableInfoSdev1; + Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); + break; + + default: + + DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); + return (AE_ERROR); + } + + /* Compile SDEV subtable body */ + + Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + /* Optional data fields are appended to the main subtable body */ + + switch (SdevHeader->Type) + { + case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: + + /* Append DeviceId namespace string */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + if (!Subtable) + { + break; + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + Namesp->DeviceIdOffset = sizeof (ACPI_SDEV_NAMESPACE); + Namesp->DeviceIdLength = (UINT16) Subtable->Length; + + /* Append Vendor data */ + + Namesp->VendorDataLength = 0; + Namesp->VendorDataOffset = 0; + + if (*PFieldList) + { + Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + if (Subtable) + { + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + Namesp->VendorDataOffset = + Namesp->DeviceIdOffset + Namesp->DeviceIdLength; + Namesp->VendorDataLength = + (UINT16) Subtable->Length; + } + } + + /* Final size of entire namespace structure */ + + SdevHeader->Length = (UINT16) (sizeof (ACPI_SDEV_NAMESPACE) + + Subtable->Length + Namesp->DeviceIdLength); + break; + + case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: + + /* Append the PCIe path info first */ + + EntryCount = 0; + while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) + { + Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, + &Subtable, FALSE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + if (!Subtable) + { + DtPopSubtable (); + break; + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + EntryCount++; + } + + /* Path offset will point immediately after the main subtable */ + + Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); + Pcie->PathLength = (UINT16) + (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); + + /* Append the Vendor Data last */ + + Pcie->VendorDataLength = 0; + Pcie->VendorDataOffset = 0; + + if (*PFieldList) + { + Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + if (Subtable) + { + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + Pcie->VendorDataOffset = + Pcie->PathOffset + Pcie->PathLength; + Pcie->VendorDataLength = (UINT16) + Subtable->Length; + } + } + + SdevHeader->Length = + sizeof (ACPI_SDEV_PCIE) + + Pcie->PathLength + Pcie->VendorDataLength; + break; + + default: + + DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); + return (AE_ERROR); + } + + DtPopSubtable (); + } + + return (AE_OK); +} + + /****************************************************************************** * * FUNCTION: DtCompileSlic @@ -1601,6 +1873,109 @@ DtCompileTcpa ( } +/****************************************************************************** + * + * FUNCTION: DtCompileTpm2 + * + * PARAMETERS: PFieldList - Current field list pointer + * + * RETURN: Status + * + * DESCRIPTION: Compile TPM2. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileTpm2 ( + void **List) +{ + DT_FIELD **PFieldList = (DT_FIELD **) List; + DT_SUBTABLE *Subtable; + ACPI_TABLE_TPM2 *Tpm2Header; + DT_SUBTABLE *ParentTable; + ACPI_STATUS Status = AE_OK; + + + /* Compile the main table */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); + + /* Method parameters */ + /* Optional: Log area minimum length */ + /* Optional: Log area start address */ + /* TBD: Optional fields above not fully implemented (not optional at this time) */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + + + /* Subtable type depends on the StartMethod */ + + switch (Tpm2Header->StartMethod) + { + case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: + + /* Subtable specific to to ARM_SMC */ + + Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, + &Subtable, TRUE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + ParentTable = DtPeekSubtable (); + DtInsertSubtable (ParentTable, Subtable); + break; + + case ACPI_TPM2_START_METHOD: + case ACPI_TPM2_MEMORY_MAPPED: + case ACPI_TPM2_COMMAND_BUFFER: + case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: + break; + + case ACPI_TPM2_RESERVED1: + case ACPI_TPM2_RESERVED3: + case ACPI_TPM2_RESERVED4: + case ACPI_TPM2_RESERVED5: + case ACPI_TPM2_RESERVED9: + case ACPI_TPM2_RESERVED10: + + AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", + Tpm2Header->StartMethod); + Status = AE_ERROR; + break; + + case ACPI_TPM2_NOT_ALLOWED: + default: + + AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", + Tpm2Header->StartMethod); + Status = AE_ERROR; + break; + } + + return (Status); +} + + /****************************************************************************** * * FUNCTION: DtGetGenericTableInfo diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.c b/sys/contrib/dev/acpica/compiler/dttemplate.c index 7ece577c2082..309386c54939 100644 --- a/sys/contrib/dev/acpica/compiler/dttemplate.c +++ b/sys/contrib/dev/acpica/compiler/dttemplate.c @@ -151,7 +151,6 @@ #include #include -#include #include /* Contains the hex ACPI table templates */ #define _COMPONENT DT_COMPILER @@ -315,7 +314,7 @@ DtCreateTemplates ( /* Shutdown ACPICA subsystem */ (void) AcpiTerminate (); - CmDeleteCaches (); + UtDeleteLocalCaches (); return (Status); } diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.h b/sys/contrib/dev/acpica/compiler/dttemplate.h index 8d27359d9ad0..38750f79d979 100644 --- a/sys/contrib/dev/acpica/compiler/dttemplate.h +++ b/sys/contrib/dev/acpica/compiler/dttemplate.h @@ -1079,6 +1079,17 @@ const unsigned char TemplatePcct[] = 0x55,0x55,0x55,0x55,0x55,0x55 /* 00000248 "UUUUUU| */ }; +const unsigned char TemplatePdtt[] = +{ + 0x50,0x44,0x54,0x54,0x34,0x00,0x00,0x00, /* 00000000 "PDTT4..." */ + 0x01,0xCB,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */ + 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */ + 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x31,0x08,0x17,0x20,0x04,0x00,0x00,0x00, /* 00000020 "1.. ...." */ + 0x2C,0x00,0x00,0x00,0xAA,0x03,0xBB,0x02, /* 00000028 ",......." */ + 0xCC,0x01,0xDD,0x00 /* 00000030 "...." */ +}; + const unsigned char TemplatePmtt[] = { 0x50,0x4D,0x54,0x54,0xB4,0x00,0x00,0x00, /* 00000000 "PMTT...." */ @@ -1187,6 +1198,25 @@ const unsigned char TemplateSdei[] = 0x30,0x09,0x16,0x20 /* 00000028 "0.. " */ }; +const unsigned char TemplateSdev[] = +{ + 0x53,0x44,0x45,0x56,0x72,0x00,0x00,0x00, /* 00000000 "SDEVr..." */ + 0x01,0x2F,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "./INTEL " */ + 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */ + 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x31,0x08,0x17,0x20,0x00,0x01,0x2A,0x00, /* 00000020 "1.. ..*." */ + 0x0C,0x00,0x16,0x00,0x22,0x00,0x08,0x00, /* 00000028 "...."..." */ + 0x5C,0x5C,0x5F,0x53,0x42,0x5F,0x2E,0x50, /* 00000030 "\\_SB_.P" */ + 0x43,0x49,0x30,0x2E,0x55,0x53,0x42,0x31, /* 00000038 "CI0.USB1" */ + 0x2E,0x53,0x55,0x42,0x31,0x00,0x00,0x11, /* 00000040 ".SUB1..." */ + 0x22,0x33,0x44,0x55,0x66,0x77,0x01,0x01, /* 00000048 ""3DUfw.." */ + 0x24,0x00,0x10,0x00,0x20,0x00,0x10,0x00, /* 00000050 "$... ..." */ + 0x04,0x00,0x14,0x00,0x10,0x00,0x11,0x22, /* 00000058 "......."" */ + 0x33,0x44,0xEE,0xDD,0xCC,0xBB,0xAA,0x55, /* 00000060 "3D.....U" */ + 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD, /* 00000068 "fw......" */ + 0xEE,0xFF /* 00000070 ".." */ +}; + const unsigned char TemplateSlic[] = { 0x53,0x4C,0x49,0x43,0x76,0x01,0x00,0x00, /* 00000000 "SLICv..." */ @@ -1388,13 +1418,17 @@ const unsigned char TemplateTcpa[] = const unsigned char TemplateTpm2[] = { - 0x54,0x50,0x4D,0x32,0x34,0x00,0x00,0x00, /* 00000000 "TPM24..." */ - 0x03,0x42,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".BINTEL " */ - 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */ + 0x54,0x50,0x4D,0x32,0x58,0x00,0x00,0x00, /* 00000000 "TPM2X..." */ + 0x03,0xAB,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */ + 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ - 0x14,0x11,0x12,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */ - 0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00, /* 00000028 "wfUD3".." */ - 0x01,0x00,0x00,0x00 /* 00000030 "...." */ + 0x31,0x08,0x17,0x20,0x01,0x00,0x00,0x00, /* 00000020 "1.. ...." */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */ + 0x0B,0x00,0x00,0x00,0x01,0x02,0x03,0x04, /* 00000030 "........" */ + 0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C, /* 00000038 "........" */ + 0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */ + 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000048 "........" */ + 0x01,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF /* 00000050 "........" */ }; const unsigned char TemplateUefi[] = diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c index 1d4e23396967..54832f7b24bf 100644 --- a/sys/contrib/dev/acpica/compiler/dtutils.c +++ b/sys/contrib/dev/acpica/compiler/dtutils.c @@ -150,7 +150,6 @@ *****************************************************************************/ #include -#include #include #define _COMPONENT DT_COMPILER @@ -570,6 +569,7 @@ DtGetFieldLength ( case ACPI_DMT_PCCT: case ACPI_DMT_PMTT: case ACPI_DMT_PPTT: + case ACPI_DMT_SDEV: case ACPI_DMT_SRAT: case ACPI_DMT_ASF: case ACPI_DMT_HESTNTYP: @@ -602,6 +602,7 @@ DtGetFieldLength ( case ACPI_DMT_NAME4: case ACPI_DMT_SIG: case ACPI_DMT_LPIT: + case ACPI_DMT_TPM2: ByteLength = 4; break; @@ -920,153 +921,3 @@ DtWalkTableTree ( } } } - - -/******************************************************************************* - * - * FUNCTION: UtSubtableCacheCalloc - * - * PARAMETERS: None - * - * RETURN: Pointer to the buffer. Aborts on allocation failure - * - * DESCRIPTION: Allocate a subtable object buffer. Bypass the local - * dynamic memory manager for performance reasons (This has a - * major impact on the speed of the compiler.) - * - ******************************************************************************/ - -DT_SUBTABLE * -UtSubtableCacheCalloc ( - void) -{ - ASL_CACHE_INFO *Cache; - - - if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) - { - /* Allocate a new buffer */ - - Cache = UtLocalCalloc (sizeof (Cache->Next) + - (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); - - /* Link new cache buffer to head of list */ - - Cache->Next = Gbl_SubtableCacheList; - Gbl_SubtableCacheList = Cache; - - /* Setup cache management pointers */ - - Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); - Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; - } - - Gbl_SubtableCount++; - return (Gbl_SubtableCacheNext++); -} - - -/******************************************************************************* - * - * FUNCTION: UtFieldCacheCalloc - * - * PARAMETERS: None - * - * RETURN: Pointer to the buffer. Aborts on allocation failure - * - * DESCRIPTION: Allocate a field object buffer. Bypass the local - * dynamic memory manager for performance reasons (This has a - * major impact on the speed of the compiler.) - * - ******************************************************************************/ - -DT_FIELD * -UtFieldCacheCalloc ( - void) -{ - ASL_CACHE_INFO *Cache; - - - if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) - { - /* Allocate a new buffer */ - - Cache = UtLocalCalloc (sizeof (Cache->Next) + - (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); - - /* Link new cache buffer to head of list */ - - Cache->Next = Gbl_FieldCacheList; - Gbl_FieldCacheList = Cache; - - /* Setup cache management pointers */ - - Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); - Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; - } - - Gbl_FieldCount++; - return (Gbl_FieldCacheNext++); -} - - -/******************************************************************************* - * - * FUNCTION: DtDeleteCaches - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Delete all local cache buffer blocks - * - ******************************************************************************/ - -void -DtDeleteCaches ( - void) -{ - UINT32 BufferCount; - ASL_CACHE_INFO *Next; - - - /* Field cache */ - - BufferCount = 0; - while (Gbl_FieldCacheList) - { - Next = Gbl_FieldCacheList->Next; - ACPI_FREE (Gbl_FieldCacheList); - Gbl_FieldCacheList = Next; - BufferCount++; - } - - DbgPrint (ASL_DEBUG_OUTPUT, - "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", - Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, - (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); - - Gbl_FieldCount = 0; - Gbl_FieldCacheNext = NULL; - Gbl_FieldCacheLast = NULL; - - /* Subtable cache */ - - BufferCount = 0; - while (Gbl_SubtableCacheList) - { - Next = Gbl_SubtableCacheList->Next; - ACPI_FREE (Gbl_SubtableCacheList); - Gbl_SubtableCacheList = Next; - BufferCount++; - } - - DbgPrint (ASL_DEBUG_OUTPUT, - "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", - Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, - (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); - - Gbl_SubtableCount = 0; - Gbl_SubtableCacheNext = NULL; - Gbl_SubtableCacheLast = NULL; -} diff --git a/sys/contrib/dev/acpica/compiler/prexpress.c b/sys/contrib/dev/acpica/compiler/prexpress.c index 892e73dcfc90..df2fc46cdea6 100644 --- a/sys/contrib/dev/acpica/compiler/prexpress.c +++ b/sys/contrib/dev/acpica/compiler/prexpress.c @@ -150,8 +150,6 @@ *****************************************************************************/ #include -#include - #define _COMPONENT ASL_PREPROCESSOR ACPI_MODULE_NAME ("prexpress") diff --git a/sys/contrib/dev/acpica/compiler/prmacros.c b/sys/contrib/dev/acpica/compiler/prmacros.c index 82b221a7e37f..e1aaa3bcecab 100644 --- a/sys/contrib/dev/acpica/compiler/prmacros.c +++ b/sys/contrib/dev/acpica/compiler/prmacros.c @@ -150,8 +150,6 @@ *****************************************************************************/ #include -#include - #define _COMPONENT ASL_PREPROCESSOR ACPI_MODULE_NAME ("prmacros") diff --git a/sys/contrib/dev/acpica/compiler/prparser.y b/sys/contrib/dev/acpica/compiler/prparser.y index 22655076c550..ec9c0c58d807 100644 --- a/sys/contrib/dev/acpica/compiler/prparser.y +++ b/sys/contrib/dev/acpica/compiler/prparser.y @@ -151,7 +151,6 @@ *****************************************************************************/ #include -#include #define _COMPONENT ASL_PREPROCESSOR ACPI_MODULE_NAME ("prparser") diff --git a/sys/contrib/dev/acpica/compiler/prscan.c b/sys/contrib/dev/acpica/compiler/prscan.c index 02df42770571..23391d2c7f20 100644 --- a/sys/contrib/dev/acpica/compiler/prscan.c +++ b/sys/contrib/dev/acpica/compiler/prscan.c @@ -152,7 +152,6 @@ #define _DECLARE_PR_GLOBALS #include -#include /* * TBDs: diff --git a/sys/contrib/dev/acpica/compiler/prutils.c b/sys/contrib/dev/acpica/compiler/prutils.c index 45da8146222b..3d7e5fe7fc8f 100644 --- a/sys/contrib/dev/acpica/compiler/prutils.c +++ b/sys/contrib/dev/acpica/compiler/prutils.c @@ -150,8 +150,6 @@ *****************************************************************************/ #include -#include - #define _COMPONENT ASL_PREPROCESSOR ACPI_MODULE_NAME ("prutils") @@ -514,7 +512,7 @@ PrPushInputFileStack ( /* Reset the global line count and filename */ Gbl_Files[ASL_FILE_INPUT].Filename = - UtStringCacheCalloc (strlen (Filename) + 1); + UtLocalCacheCalloc (strlen (Filename) + 1); strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename); Gbl_Files[ASL_FILE_INPUT].Handle = InputFile; diff --git a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c index b23a27389538..b719a67dd95d 100644 --- a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c +++ b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c @@ -234,7 +234,8 @@ AcpiDsExecBeginControlOp ( WalkState->ParserState.PkgEnd; ControlState->Control.Opcode = Op->Common.AmlOpcode; - + ControlState->Control.LoopTimeout = AcpiOsGetTimer () + + (UINT64) (AcpiGbl_MaxLoopIterations * ACPI_100NSEC_PER_SEC); /* Push the control state on this walk's control stack */ @@ -327,15 +328,15 @@ AcpiDsExecEndControlOp ( /* Predicate was true, the body of the loop was just executed */ /* - * This loop counter mechanism allows the interpreter to escape - * possibly infinite loops. This can occur in poorly written AML - * when the hardware does not respond within a while loop and the - * loop does not implement a timeout. + * This infinite loop detection mechanism allows the interpreter + * to escape possibly infinite loops. This can occur in poorly + * written AML when the hardware does not respond within a while + * loop and the loop does not implement a timeout. */ - ControlState->Control.LoopCount++; - if (ControlState->Control.LoopCount > AcpiGbl_MaxLoopIterations) + if (ACPI_TIME_AFTER (AcpiOsGetTimer (), + ControlState->Control.LoopTimeout)) { - Status = AE_AML_INFINITE_LOOP; + Status = AE_AML_LOOP_TIMEOUT; break; } diff --git a/sys/contrib/dev/acpica/components/hardware/hwtimer.c b/sys/contrib/dev/acpica/components/hardware/hwtimer.c index f03ba6ac16e1..22a4a974987a 100644 --- a/sys/contrib/dev/acpica/components/hardware/hwtimer.c +++ b/sys/contrib/dev/acpica/components/hardware/hwtimer.c @@ -283,7 +283,7 @@ AcpiGetTimerDuration ( UINT32 *TimeElapsed) { ACPI_STATUS Status; - UINT32 DeltaTicks; + UINT64 DeltaTicks; UINT64 Quotient; @@ -302,34 +302,33 @@ AcpiGetTimerDuration ( return_ACPI_STATUS (AE_SUPPORT); } + if (StartTicks == EndTicks) + { + *TimeElapsed = 0; + return_ACPI_STATUS (AE_OK); + } + /* * Compute Tick Delta: * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. */ - if (StartTicks < EndTicks) - { - DeltaTicks = EndTicks - StartTicks; - } - else if (StartTicks > EndTicks) + DeltaTicks = EndTicks; + if (StartTicks > EndTicks) { if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0) { /* 24-bit Timer */ - DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF); + DeltaTicks |= (UINT64) 1 << 24; } else { /* 32-bit Timer */ - DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks; + DeltaTicks |= (UINT64) 1 << 32; } } - else /* StartTicks == EndTicks */ - { - *TimeElapsed = 0; - return_ACPI_STATUS (AE_OK); - } + DeltaTicks -= StartTicks; /* * Compute Duration (Requires a 64-bit multiply and divide): @@ -337,7 +336,7 @@ AcpiGetTimerDuration ( * TimeElapsed (microseconds) = * (DeltaTicks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY; */ - Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * ACPI_USEC_PER_SEC, + Status = AcpiUtShortDivide (DeltaTicks * ACPI_USEC_PER_SEC, ACPI_PM_TIMER_FREQUENCY, &Quotient, NULL); *TimeElapsed = (UINT32) Quotient; diff --git a/sys/contrib/dev/acpica/components/namespace/nsaccess.c b/sys/contrib/dev/acpica/components/namespace/nsaccess.c index 1d979cea8a79..28c32489de27 100644 --- a/sys/contrib/dev/acpica/components/namespace/nsaccess.c +++ b/sys/contrib/dev/acpica/components/namespace/nsaccess.c @@ -775,19 +775,19 @@ AcpiNsLookup ( ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; } } -#ifdef ACPI_ASL_COMPILER - if (!AcpiGbl_DisasmFlag && - (ThisNode->Flags & ANOBJ_IS_EXTERNAL)) - { - ThisNode->Flags |= IMPLICIT_EXTERNAL; - } -#endif } /* Special handling for the last segment (NumSegments == 0) */ else { +#ifdef ACPI_ASL_COMPILER + if (!AcpiGbl_DisasmFlag && (ThisNode->Flags & ANOBJ_IS_EXTERNAL)) + { + ThisNode->Flags &= ~IMPLICIT_EXTERNAL; + } +#endif + /* * Sanity typecheck of the target object: * diff --git a/sys/contrib/dev/acpica/components/namespace/nssearch.c b/sys/contrib/dev/acpica/components/namespace/nssearch.c index 0c6eaf98ccc9..8d14d5259c0c 100644 --- a/sys/contrib/dev/acpica/components/namespace/nssearch.c +++ b/sys/contrib/dev/acpica/components/namespace/nssearch.c @@ -545,6 +545,7 @@ AcpiNsSearchAndEnter ( (WalkState && WalkState->Opcode == AML_SCOPE_OP)) { NewNode->Flags |= ANOBJ_IS_EXTERNAL; + NewNode->Flags |= IMPLICIT_EXTERNAL; } #endif diff --git a/sys/contrib/dev/acpica/components/parser/psobject.c b/sys/contrib/dev/acpica/components/parser/psobject.c index 73091e32acca..0260632a5eef 100644 --- a/sys/contrib/dev/acpica/components/parser/psobject.c +++ b/sys/contrib/dev/acpica/components/parser/psobject.c @@ -500,15 +500,10 @@ AcpiPsCreateOp ( * external declaration opcode. Setting WalkState->Aml to * WalkState->ParserState.Aml + 2 moves increments the * WalkState->Aml past the object type and the paramcount of the - * external opcode. For the error message, only print the AML - * offset. We could attempt to print the name but this may cause - * a segmentation fault when printing the namepath because the - * AML may be incorrect. + * external opcode. */ - AcpiOsPrintf ( - "// Invalid external declaration at AML offset 0x%x.\n", - WalkState->Aml - WalkState->ParserState.AmlStart); WalkState->Aml = WalkState->ParserState.Aml + 2; + WalkState->ParserState.Aml = WalkState->Aml; return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); } #endif diff --git a/sys/contrib/dev/acpica/components/parser/psutils.c b/sys/contrib/dev/acpica/components/parser/psutils.c index c67a7aec9666..2d54035932fd 100644 --- a/sys/contrib/dev/acpica/components/parser/psutils.c +++ b/sys/contrib/dev/acpica/components/parser/psutils.c @@ -292,11 +292,11 @@ AcpiPsAllocOp ( { AcpiGbl_CurrentScope = Op; } - } - if (Gbl_CaptureComments) - { - ASL_CV_TRANSFER_COMMENTS (Op); + if (Gbl_CaptureComments) + { + ASL_CV_TRANSFER_COMMENTS (Op); + } } return (Op); diff --git a/sys/contrib/dev/acpica/components/utilities/utinit.c b/sys/contrib/dev/acpica/components/utilities/utinit.c index f4bd8502e03b..357ccd212d1a 100644 --- a/sys/contrib/dev/acpica/components/utilities/utinit.c +++ b/sys/contrib/dev/acpica/components/utilities/utinit.c @@ -334,7 +334,6 @@ AcpiUtInitGlobals ( AcpiGbl_NextOwnerIdOffset = 0; AcpiGbl_DebuggerConfiguration = DEBUGGER_THREADING; AcpiGbl_OsiMutex = NULL; - AcpiGbl_MaxLoopIterations = ACPI_MAX_LOOP_COUNT; /* Hardware oriented */ diff --git a/sys/contrib/dev/acpica/components/utilities/utmath.c b/sys/contrib/dev/acpica/components/utilities/utmath.c index da5efbccdddd..f9cd2b18e678 100644 --- a/sys/contrib/dev/acpica/components/utilities/utmath.c +++ b/sys/contrib/dev/acpica/components/utilities/utmath.c @@ -260,7 +260,7 @@ AcpiUtShortShiftLeft ( if ((Count & 63) >= 32) { OperandOvl.Part.Hi = OperandOvl.Part.Lo; - OperandOvl.Part.Lo ^= OperandOvl.Part.Lo; + OperandOvl.Part.Lo = 0; Count = (Count & 63) - 32; } ACPI_SHIFT_LEFT_64_BY_32 (OperandOvl.Part.Hi, @@ -305,7 +305,7 @@ AcpiUtShortShiftRight ( if ((Count & 63) >= 32) { OperandOvl.Part.Lo = OperandOvl.Part.Hi; - OperandOvl.Part.Hi ^= OperandOvl.Part.Hi; + OperandOvl.Part.Hi = 0; Count = (Count & 63) - 32; } ACPI_SHIFT_RIGHT_64_BY_32 (OperandOvl.Part.Hi, diff --git a/sys/contrib/dev/acpica/include/acapps.h b/sys/contrib/dev/acpica/include/acapps.h index 4ca3e80fb31e..faae2fb6917e 100644 --- a/sys/contrib/dev/acpica/include/acapps.h +++ b/sys/contrib/dev/acpica/include/acapps.h @@ -188,6 +188,9 @@ Prefix, ACPICA_COPYRIGHT, \ Prefix +#define ACPI_COMMON_BUILD_TIME \ + "Build date/time: %s %s\n", __DATE__, __TIME__ + /* Macros for usage messages */ #define ACPI_USAGE_HEADER(Usage) \ diff --git a/sys/contrib/dev/acpica/include/acconfig.h b/sys/contrib/dev/acpica/include/acconfig.h index 6fc043639e32..7cff0636516a 100644 --- a/sys/contrib/dev/acpica/include/acconfig.h +++ b/sys/contrib/dev/acpica/include/acconfig.h @@ -255,9 +255,9 @@ #define ACPI_ADDRESS_RANGE_MAX 2 -/* Maximum number of While() loops before abort */ +/* Maximum time (default 30s) of While() loops before abort */ -#define ACPI_MAX_LOOP_COUNT 0x000FFFFF +#define ACPI_MAX_LOOP_TIMEOUT 30 /****************************************************************************** diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h index 5d7140f59cab..a6f8cfdc7653 100644 --- a/sys/contrib/dev/acpica/include/acdisasm.h +++ b/sys/contrib/dev/acpica/include/acdisasm.h @@ -272,8 +272,10 @@ typedef enum ACPI_DMT_PMTT, ACPI_DMT_PPTT, ACPI_DMT_SDEI, + ACPI_DMT_SDEV, ACPI_DMT_SLIC, ACPI_DMT_SRAT, + ACPI_DMT_TPM2, /* Special opcodes */ @@ -502,6 +504,7 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit4[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit5[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6a[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[]; @@ -515,6 +518,7 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct1[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct2[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct3[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct4[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0a[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt1[]; @@ -529,6 +533,13 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdevHdr[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0a[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1a[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1b[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlic[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlit[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[]; @@ -546,6 +557,8 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaHdr[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaClient[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaServer[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2a[]; +extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm211[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc[]; extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc0[]; @@ -586,7 +599,7 @@ AcpiDmDumpTable ( UINT32 TableLength, UINT32 TableOffset, void *Table, - UINT32 SubTableLength, + UINT32 SubtableLength, ACPI_DMTABLE_INFO *Info); void @@ -712,6 +725,10 @@ void AcpiDmDumpPcct ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpPdtt ( + ACPI_TABLE_HEADER *Table); + void AcpiDmDumpPmtt ( ACPI_TABLE_HEADER *Table); @@ -732,6 +749,10 @@ UINT32 AcpiDmDumpS3pt ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpSdev ( + ACPI_TABLE_HEADER *Table); + void AcpiDmDumpSlic ( ACPI_TABLE_HEADER *Table); @@ -752,6 +773,10 @@ void AcpiDmDumpTcpa ( ACPI_TABLE_HEADER *Table); +void +AcpiDmDumpTpm2 ( + ACPI_TABLE_HEADER *Table); + void AcpiDmDumpVrtc ( ACPI_TABLE_HEADER *Table); diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h index d808f275144f..21db48dcb082 100644 --- a/sys/contrib/dev/acpica/include/acexcep.h +++ b/sys/contrib/dev/acpica/include/acexcep.h @@ -309,7 +309,7 @@ typedef struct acpi_exception_info #define AE_AML_CIRCULAR_REFERENCE EXCEP_AML (0x001E) #define AE_AML_BAD_RESOURCE_LENGTH EXCEP_AML (0x001F) #define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020) -#define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021) +#define AE_AML_LOOP_TIMEOUT EXCEP_AML (0x0021) #define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022) #define AE_AML_TARGET_TYPE EXCEP_AML (0x0023) @@ -441,7 +441,7 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Aml[] = EXCEP_TXT ("AE_AML_CIRCULAR_REFERENCE", "Two references refer to each other"), EXCEP_TXT ("AE_AML_BAD_RESOURCE_LENGTH", "The length of a Resource Descriptor in the AML is incorrect"), EXCEP_TXT ("AE_AML_ILLEGAL_ADDRESS", "A memory, I/O, or PCI configuration address is invalid"), - EXCEP_TXT ("AE_AML_INFINITE_LOOP", "An apparent infinite AML While loop, method was aborted"), + EXCEP_TXT ("AE_AML_LOOP_TIMEOUT", "An AML While loop exceeded the maximum execution time"), EXCEP_TXT ("AE_AML_UNINITIALIZED_NODE", "A namespace node is uninitialized or unresolved"), EXCEP_TXT ("AE_AML_TARGET_TYPE", "A target operand of an incorrect type was encountered") }; diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h index 00be20ede3e7..7a20fe6fca66 100644 --- a/sys/contrib/dev/acpica/include/aclocal.h +++ b/sys/contrib/dev/acpica/include/aclocal.h @@ -834,7 +834,7 @@ typedef struct acpi_control_state union acpi_parse_object *PredicateOp; UINT8 *AmlPredicateStart; /* Start of if/while predicate */ UINT8 *PackageEnd; /* End of if/while block */ - UINT32 LoopCount; /* While() loop counter */ + UINT64 LoopTimeout; /* While() loop timeout */ } ACPI_CONTROL_STATE; diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h index 5f96ed3169ed..38981a0ffa60 100644 --- a/sys/contrib/dev/acpica/include/acpixf.h +++ b/sys/contrib/dev/acpica/include/acpixf.h @@ -154,7 +154,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20170831 +#define ACPI_CA_VERSION 0x20170929 #include #include @@ -370,11 +370,11 @@ ACPI_INIT_GLOBAL (UINT8, AcpiGbl_OsiData, 0); ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ReducedHardware, FALSE); /* - * Maximum number of While() loop iterations before forced method abort. + * Maximum timeout for While() loop iterations before forced method abort. * This mechanism is intended to prevent infinite loops during interpreter * execution within a host kernel. */ -ACPI_INIT_GLOBAL (UINT32, AcpiGbl_MaxLoopIterations, ACPI_MAX_LOOP_COUNT); +ACPI_INIT_GLOBAL (UINT32, AcpiGbl_MaxLoopIterations, ACPI_MAX_LOOP_TIMEOUT); /* * This mechanism is used to trace a specified AML method. The method is diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h index 537c33e7c3b9..7eed2c5507ae 100644 --- a/sys/contrib/dev/acpica/include/actbl1.h +++ b/sys/contrib/dev/acpica/include/actbl1.h @@ -179,9 +179,10 @@ #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ #define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ -#define ACPI_SIG_PDTT "PDTT" /* Processor Debug Trigger Table */ +#define ACPI_SIG_PDTT "PDTT" /* Platform Debug Trigger Table */ #define ACPI_SIG_PPTT "PPTT" /* Processor Properties Topology Table */ #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ +#define ACPI_SIG_SDEV "SDEV" /* Secure Devices table */ #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ #define ACPI_SIG_NFIT "NFIT" /* NVDIMM Firmware Interface Table */ @@ -1603,7 +1604,7 @@ typedef struct acpi_nfit_flush_address /******************************************************************************* * - * PDTT - Processor Debug Trigger Table (ACPI 6.2) + * PDTT - Platform Debug Trigger Table (ACPI 6.2) * Version 0 * ******************************************************************************/ @@ -1625,16 +1626,15 @@ typedef struct acpi_table_pdtt */ typedef struct acpi_pdtt_channel { - UINT16 SubChannelId; + UINT8 SubchannelId; + UINT8 Flags; } ACPI_PDTT_CHANNEL; +/* Flags for above */ -/* Mask and Flags for above */ - -#define ACPI_PDTT_SUBCHANNEL_ID_MASK 0x00FF -#define ACPI_PDTT_RUNTIME_TRIGGER (1<<8) -#define ACPI_PPTT_WAIT_COMPLETION (1<<9) +#define ACPI_PDTT_RUNTIME_TRIGGER (1) +#define ACPI_PPTT_WAIT_COMPLETION (1<<1) /******************************************************************************* @@ -1746,6 +1746,82 @@ typedef struct acpi_table_sbst } ACPI_TABLE_SBST; +/******************************************************************************* + * + * SDEV - Secure Devices Table (ACPI 6.2) + * Version 1 + * + ******************************************************************************/ + +typedef struct acpi_table_sdev +{ + ACPI_TABLE_HEADER Header; /* Common ACPI table header */ + +} ACPI_TABLE_SDEV; + + +typedef struct acpi_sdev_header +{ + UINT8 Type; + UINT8 Flags; + UINT16 Length; + +} ACPI_SDEV_HEADER; + + +/* Values for subtable type above */ + +enum AcpiSdevType +{ + ACPI_SDEV_TYPE_NAMESPACE_DEVICE = 0, + ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE = 1, + ACPI_SDEV_TYPE_RESERVED = 2 /* 2 and greater are reserved */ +}; + +/* Values for flags above */ + +#define ACPI_SDEV_HANDOFF_TO_UNSECURE_OS (1) + +/* + * SDEV subtables + */ + +/* 0: Namespace Device Based Secure Device Structure */ + +typedef struct acpi_sdev_namespace +{ + ACPI_SDEV_HEADER Header; + UINT16 DeviceIdOffset; + UINT16 DeviceIdLength; + UINT16 VendorDataOffset; + UINT16 VendorDataLength; + +} ACPI_SDEV_NAMESPACE; + +/* 1: PCIe Endpoint Device Based Device Structure */ + +typedef struct acpi_sdev_pcie +{ + ACPI_SDEV_HEADER Header; + UINT16 Segment; + UINT16 StartBus; + UINT16 PathOffset; + UINT16 PathLength; + UINT16 VendorDataOffset; + UINT16 VendorDataLength; + +} ACPI_SDEV_PCIE; + +/* 1a: PCIe Endpoint path entry */ + +typedef struct acpi_sdev_pcie_path +{ + UINT8 Device; + UINT8 Function; + +} ACPI_SDEV_PCIE_PATH; + + /******************************************************************************* * * SLIT - System Locality Distance Information Table diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h index 951d65531a33..02a897b0fb19 100644 --- a/sys/contrib/dev/acpica/include/actbl2.h +++ b/sys/contrib/dev/acpica/include/actbl2.h @@ -1550,6 +1550,8 @@ enum AcpiSpmiInterfaceTypes * TCPA - Trusted Computing Platform Alliance table * Version 2 * + * TCG Hardware Interface Table for TPM 1.2 Clients and Servers + * * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0", * Version 1.2, Revision 8 * February 27, 2017 @@ -1622,6 +1624,8 @@ typedef struct acpi_table_tcpa_server * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table * Version 4 * + * TCG Hardware Interface Table for TPM 2.0 Clients and Servers + * * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0", * Version 1.2, Revision 8 * February 27, 2017 @@ -1643,17 +1647,25 @@ typedef struct acpi_table_tpm2 /* Values for StartMethod above */ #define ACPI_TPM2_NOT_ALLOWED 0 +#define ACPI_TPM2_RESERVED1 1 #define ACPI_TPM2_START_METHOD 2 +#define ACPI_TPM2_RESERVED3 3 +#define ACPI_TPM2_RESERVED4 4 +#define ACPI_TPM2_RESERVED5 5 #define ACPI_TPM2_MEMORY_MAPPED 6 #define ACPI_TPM2_COMMAND_BUFFER 7 #define ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD 8 +#define ACPI_TPM2_RESERVED9 9 +#define ACPI_TPM2_RESERVED10 10 #define ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC 11 /* V1.2 Rev 8 */ +#define ACPI_TPM2_RESERVED 12 -/* Trailer appears after any StartMethod subtables */ +/* Optional trailer appears after any StartMethod subtables */ typedef struct acpi_tpm2_trailer { + UINT8 MethodParameters[12]; UINT32 MinimumLogLength; /* Minimum length for the event log area */ UINT64 LogAddress; /* Address of the event log area */ diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h index 1839f936e4e5..4cc6d4fd071e 100644 --- a/sys/contrib/dev/acpica/include/actypes.h +++ b/sys/contrib/dev/acpica/include/actypes.h @@ -586,6 +586,8 @@ typedef void * ACPI_HANDLE; /* Actually a ptr to a N #define ACPI_NSEC_PER_MSEC 1000000L #define ACPI_NSEC_PER_SEC 1000000000L +#define ACPI_TIME_AFTER(a, b) ((INT64)((b) - (a)) < 0) + /* Owner IDs are used to track namespace nodes for selective deletion */ diff --git a/sys/contrib/dev/iwm/iwm-8265-22.fw.uu b/sys/contrib/dev/iwm/iwm-8265-22.fw.uu new file mode 100644 index 000000000000..9eff917762b7 --- /dev/null +++ b/sys/contrib/dev/iwm/iwm-8265-22.fw.uu @@ -0,0 +1,40270 @@ +begin 644 iwm-8265-22.fw +M`````$E73`IS=')E86TZ0V]R94-Y8VQE,3E?````"`````$`````````'@````@````"```` +MCWX#`!P````0`````````````````````````!L````$`````@```#,````, +M````````````@```@`$`,P````P````!``````"(``"````S````#`````(` +M`````$```(`&`!,```"\`@```$!```8```"A```````!``````"&@````P<6 +M(`#/`0!`````0`````$````$A`4````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````U7?1O$KMC1P!%L)AM`1@'DT[FA#1 +MOWMZR()DJ-L;GQEBIN9H[A^ZS%KH6MG.(:=CV\&$V<0:'I[5@L7;]O#+S6])Q;OTUZ` +M@Q9O#\ZQZUROU1XL3>@GIX0A'ZLQS3.]EM]`#)-:.@LH#44.K^C\7[\`!P3D +MY4F9W;8[]70ZRI8T>H?6RDCG3OM +M8]KY^9H/)$3]O$5[L'!Q8_7B]),MEL2SE/;3@!]'*Q0B!J +MSTEZ*8)Z!0@S6DLP1!FVOW/)J9&S#<5HT&$4S<7=^@(C/O$<4EJ.EO9XL_%E +MT>4]#<7,[9G60.1^$&L="\AYAH+6D>M<"8*SB6+Z(O@K2S"E-V&#A#J=*)YQ +M?A=_2W+\0QR``+XRI7=42EPB2)(!`2I!$9U:;0F'*M._3+OF[>!&+"-+#-'H +M\PZ#!\0+`..6,0`#S%^8W8&G25#,,I>V=BW:]"V:&%%;OYJG`P````<````( +M@`$```"```"``0`'````"``%``````````4`!P```%"Y````@$0`2+D``!,` +M```$@`$```"````````6````!(0%```!````````S-:``"0H@`!`_(``Q/.` +M`)04@`"`<($`````````````````````````````````;"#`$`\;"2+<'<`0 +M"@`;0"``&VX,``!A@``;;D```&$``1MN4P``80`"&VYC``!A``0;;GX``&$0 +M`!MN`0``88```&%[``!A```;)"``&R7D'<`12`GA&!\`"&(``!LE`0`;)``` +M!24!``4D``@%.0$`!6*((,`1`@`%)``(!3D!``5BC"#`$00`!20`"`4Y`0`% +M8I`@P!$(``4D``@%.0$`!6*4(,`1$``%)``(!3D!``5BF"#`$2``!20`"`4Y +M`0`%8IP@P!%```4D``@%.0$`!6*@(,`1```()0``""1(">$91`GA&10)P!(! +M`!MP"@``80\<'2($`!TF)`G`$@$;(R+H'<`0`0`C<`$``&$1`!LP`0`;,.@= +MP!&Z#P!A```;)(``&R7D'<`1"`!?<`D``&'0",`2``D;*,P(@($``,`7U`C` +M$@`)&RC("("!``#`%ZP/`&',",`2X`B`@0``P!?(",`2W`B`@0``P!>E#P!A +M```;)``!&R7D'<`1"`!?<*`/`&$```4EX@0%)-0(P!(`"1LH``4;*=P(@($` +M`,`7T`C`$@`)&R@`!1LIX`B`@0``P!>3#P!A```;)``"&R7D'<`1"`!?<`P` +M`&'L'\`0__\;,^P?P!'.[@TE@ID-)`\--R)L(,`0#QLW(O__#24._PTD#PTW +M(H(/`&'L'\`0```;,>P?P!'.[@TE@ID-)`\--R)L(,`0#QLW(O__#26._PTD +M#PTW(G8/`&$```!A```;)2``&R1<',`1````8=P=P!```!TD````(0$`6#'. +M[@TE`8$-)`\--R(/1#$7`$`$`$W`,``!A"`!8,-@>P!`*`!-``@`3;@0` +M`&$!``@D```()40)X1D!``!A`(!8,`@`9#$```!A"`!8;N,/`&$``!,E```3 +M)"00P!$`@!,D```3)3@!,B +M``#&$0,``20```$E#T4`(@!<`#GO_P`R%P``9`"`$R0!`!,E.!S`$0]W$R+@ +M',`1`@`!8@\!$R($",`1?`S`$LA)QQ&0"\`2`0`!;@,`$S`,`,T1"`!8,0\4 +M%2($`!4F`P`3)```$R4$",`1```3)#A%P!$%``!A``!8.`0`6#$``!,D`0`3 +M)3@P!`*`!-``@`3;@0``&$!``@D```()40)X1D$``!A`(!8 +M,`(``&$`(%@P````8>@=P!#F_Q,R__\3,^@=P!$```$D"``!)0\!8R(!`%(D +M"``';@(``&$``!4D#P``80X``&'H'<`0^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````-`'```` +M``````````$!`0$!`0$!O1\``&,N``#_____```````````````````````` +M```(```````````````````````````````````````````````!```````` +M`````````````0`````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````S,```$1`````````````` +M``HH```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````$0`@````````````"0````H````+````#`````T````.``` +M`#P```!`````1````$@```!,````4````%0```!8````7````&````!D```` +M:````&P```!P````=````'@```!\````@````(0```"(````C````)````"5 +M````F0```)T```"A````I0```*D```"M````L0```"H````Z````2@```%H` +M``!J````>@```(H```";````JP````(````$````!@````,````+````$P`` +M`!L````C````*P```#,````Z````0@````$`````````!`````4````````` +M`````````````/\```#^`0```O\```/_``$`_P$``0(!`@+_`@#_`P(`_@0" +M``/_````````````````".@```H````$````&-J``````````````````!SH +M```*````!````!C:@``````````````````````````````````````````` +M````````````'@```!Z('HA:````5@```%:(5H@"`0``J@```*J(JHC^`0`` +MC`H``%2,5(RD'P````#_```!`/\```/_```&_P``"?\```K_`0#_`0$!`0$! +M``+_`0(#_P$!!O\!`0G_`0`*_P$`_@("`/\#`@($`P(`!?\"``C_`@,&_P(` +M"?\"`@/_`@`*_P(`_@0#`/\%`P('_P,`"?\#`P/_`P,&_P,`"O\#`/X&```` +M````````````:)@```H````$````&-J```````````````````"9```%```` +M!````!C:@````````````````````````````````````````````)S'`0"H +MR0$`",D!`'C)`0`DQ`$`',0!`!QB```D8```>&```"`[`0`````````````` +M``````````````````````````#_!P```/\```?_``$)"```"O\!`@```0,! +M_P$#`O\!`P/_`0$$_P$"!0`!`0O_`0(,_P$$!@8!`0?_`0`(_P$`"O\"`@#_ +M`@,!_P(#`O\"`P/_`@$$`0("!0`"`0L!`@(,`0($!@8"`@<``@`(`0(`"@$# +M`/\"`P,`_P,#`?\#`P+_`P,#!`,!!`4#`@4``P$+!0,"#`4#!`8&`P,'_P,` +M"`4#``H%`P#^`P0$`/\$!`'_!`0"_P0$`_\$!`3_!`0%_P0$"_\$!`S_!`0& +M!@0$!P8$``C_!``*_P````````````#_`````0,``@("``,``@``!?\```;_ +M```$_P``!P0```C_`0#_`0$!``,!`@$"`0("`@$`!/\!`0<$`0`(_P(#``8" +M`@(&`@`%_P(`!O\"``0'`@`'!P(`"`<#`P`&`P`!!0,"`@8#`07_`P`&_P,` +M!`<#``<'`P`(!P`````````````````0``#V#P``V`\``*8/``!A#P``"0\` +M`)T.```@#@``D0T``/$,``!!#```@@L``+0*``#9"0``\@@````(```#!P`` +M_@4``/$$``#>`P``QP(``*P!``".``````````````````````$````!```` +M```````````!`````0````$```````````````$``)S0@``>``$D/@(``0`$ +M``!(MH``!``!L/2```P``0``1,V```$``T#-@``!``.4%(```0`!*-"```$` +M`RS0@``!``/H/0(``@`$```@````(`````````!54@``1T4``$Q)``!.0P`` +M1$D``%-5``!:6@``6EH``%I:``!:6@``6EH``%I:``!:6@``6EH``%I:``!: +M6@`````````(!`P""@8.`0D%#0,+!P\!`````@````P```#P/P$````!```` +M`````````````!@_`P`%```"!````!C:@````````````/\````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````#`````````$YB$`#A +M@0$`3F(0````````````````````````````V0#8``$`)`"`!Q`*`0$"`1T` +M@0J""J$(,0N\!TP*````````)P`[`%L)ZPL`````I*H"`#,S`P````0`,E4% +M````"`"KJ@H````,`,W,#``````````````````````````````````!```` +M````````````````_P```````````````````-CW```%```"!````!C:@`#_ +M````````````````````````````````````!@`````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````"@%(``"/R``!@````````` +M````````````````_LJMJP`````````````````````@`@`````A`@`````B +M`@`````C`@`````D`@`````E`@`````&``````````````!8!`,`3`0#`'@$ +M`P"8!P,`3`4#`!`%`P"\!`,```@#`"@/@`"`]8``'@```"R21``!```````` +M`$J21``````````````````````````````````!```````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````/!L!``4```($````&-J````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````@``````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````````#_ +M```!`_\```D!```*_P`#!`(```#_``#^`P$`_P0!`0D%`0$*!0$``?\!`P0" +M`0$"_P$!"/\!``#_`0#^!@(`_P<"`@D(`@(*"`("!PD"``'_`@$#_P(#!`H" +M`@+_`@``"P,#"0P#`PH,`P0%#0,#`@X#```/!`#_$`0$"1$$!`H1!`(&_P0" +M`A($!`C_!```_P0`_A,```````````````!<\P``"@````0````8VH`````` +M````````````9",```H````$````&-J``(Q[```(?```D"````!\``"0\@`` +M]/(``-SR``#D(```_"$``'0A``#$(```^"$``+P@``"P(```M"```+@@``"T +MWP``$.```.3?``#)VE````````'P#0_P``````````T/^@_P``!F0`!@8& +M``````#Z_?P`]/GY```````````"`````P````4``````-#_H/\``-#_H/\` +M`-#_H/\``-#_H/\A(2$A(2$A(2$A2$A(2$A(2$A(2%965E965E965E9Q<7%Q +M96!W='%Q2$A(2$A(2$A(2(!@@&"`8(!@@&`````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````H!`0$!`0``"`IQR;Z\```````` +M```````````````````````````````````````````````````````````` +M````````````````````_W\```````#_?P```````/]_````````_W\````` +M``#_?P```````/]_````````_W\```````#_?P```````/]_```````````` +M`/]__W]@'H``8!Z``&`>@````````````````````/]_``````$````````` +M````````````````6``H`%@`*``P``````#0_U@`*`!(`"@`2``H`#@`#``` +M`-#_2``H`%``(`!0`"``:`!(`"@`"`!0`"``4``P`%``,`!@`#@`*``(`%`` +M,`!(`"@`2``H`&@`.``H``0`2``H`%@`*`!8`"@`8``H`"@`(`!8`"@`2``H +M`$@`*`!@`"@`*``8`$@`*``````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````_LJMJP`````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````!``````D`$```"@`!`G``#H`P``Z`,``+":``!$F@`` +M0)H``)R:``#HRP(`.,P"`!S,`@!@RP(`F,L"`"S+`@`DS`(``0`````````` +M``````````````````````````-````4``````$```````"<)H`````````` +M``````````````````!$,`(`"@````0````8VH```````````````"`````` +M```````````````````````````````````````````````````````````` +M````````````````````````!````````````````````````````/@P`@`% +M````!````!C:@```````````````````````'#("``4```($````&-J````` +M`````````````#0S`@`%```"!````!C:@`#`48`````````````````````` +M``$``````````@``````````````````````````````9T4C`04````"`@(" +M`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(" +M`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(!`@("`@("`@$! +M`@("`@("`@("`@("`@("`@("`@("`O\````0`@`````````````````````` +M````````````.".!```````````````````````````````````````````` +M```````````!```````````````````````````````````````````````` +M```````````````)```````````````````````````````````````````` +M``````````````````````````````````````````````````#_________ +M_________________________________P`````````````````````````` +M``````T-#0T.#@X.#@\/#P\/$!`0$!$1$1$2$A(2$Q,3$Q04%!45%146%A87 +M%Q<8&!@9&1H:&AL;&QP<'1T='AX?'R`@(2$B(B,C)"0E)28F)R`` +M``K@``!&X```%^```!C@``!'X```*.```"G@```XX```.>````"(`0!B8F)B +M8F(```"<`0!G9V=G9V<```"0`0!D9&1D9&0``&9F9F9F9@`````````````` +M```````````````````````````````````````````````````````````` +M``#D;@``!0````0````8VH``U&X``-QN``",;P``V&X``.!N```````````` +M```````````````````````````````````````````````````````````` +M````````````````I``$``4````$````&-J````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````S!L`````R!L`````0!P` +M````3!P`````4!P`````5!P`````6!P`````7!P`````8!P`````9!P````` +M`````$0?`````(`?`````(0?`````(@?`````(P? +M`````)`?`````)0?`````)@?`````)P?`````*`?`````*0?`````*@?```` +M`*P?`````+`?`````.0?`````/`?`````/0?`````/P?`````$8````````` +M````````````````X!P`````Y!P`````Z!P`````]!P`````^!P`````#!T` +M````&!T`````+!T`````,!T`````G!T`````H!T`````,!X`````-!X````` +M.!X`````/!X`````3!X`````4!X`````5!X`````6!X`````7!X`````9!X` +M````>!X`````?!X`````A!X`````C!X`````D!X`````E!X`````F!X````` +MG!X`````H!X`````P!X`````Q!X`````T!X`````U!X``````!\`````X!X` +M````!!\`````W!X`````=!\`````>!\`````?!\`````^!\`````*@`````` +M``````````````,````?````````````````````$````$M+2TM+```````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````$````````````````````` +M`````````````````````````````````````````````````````````/\` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````/SP```````````````````,````````` +M_P``````````````````````````````````````````````__\````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````(```````````````````````````````````````````````````` +M`````/__________````````````````_(X```H````$````&-J````````` +M````.)0``.25``"(E```D),``!26``"HE0``Y),``$23`````0````$$`0$! +M``(!`0$#`0`"!P$!!`0!`04%`0(#_P(!`08"``('B!,````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````#_____```````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````"````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````#_____```````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````"````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````#_____```` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````"````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````````#_ +M____```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````"````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````#_____```````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````"````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````_P`````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````````"< +MZH``+.B``)SJ@`#H[X``C.N``%3J@`!X[X``5.J``"#K@`"`*$`I0"I`*T`L`"T`+@`NP"_`,,`Q@#*`,X` +MT0#5`-@`W`#?`.,`YP#J`.X`\0#U`/@`_`#_``(!!@$)`0T!$`$4`1 +M`2$!)`$H`2L!+@$R`34!.`$[`3\!0@%%`4@!3`%/`5(!50%9`5P!7P%B`64! +M:`%K`6\!<@%U`7@!>P%^`8$!A`&'`8H!C0&0`9,!E@&:`9T!GP&B`:4!J`&K +M`:X!L0&T`;(!Y0'H`>L! +M[0'P`?,!]@'X`?L!_@$!`@,"!@()`@P"#@(1`A0"%@(9`AP"'@(A`B0")@(I +M`BP"+@(Q`C0"-@(Y`CL"/@)!`D,"1@)(`DL"30)0`E,"50)8`EH"70)?`F(" +M9`)G`FD";`)N`G$"P)]`G\"@@*$`H<"B0*,`HX"D`*3`I4"F`*: +M`IP"GP*A`J,"I@*H`JL"K0*O`K("M`*V`KD"NP*]`L`"P@+$`L8"R0++`LT" +MT`+2`M0"U@+9`ML"W0+?`N("Y`+F`N@"Z@+M`N\"\0+S`O8"^`+Z`OP"_@(` +M`ZL````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````!DG0``!0````0````8VH`````` +M```%``!R`0``J`(```0)!`D!!@D,$0$````````````````````````````` +M````````````````````````````````_LJMJP`<``````0<``````@<```` +M``P<`````"@<`````$@<`````$P<`````%`<`````%`<`````'P<`````"@X +M``````!,``````1,``````A,``````Q,`````"!,`````"1,`````"A,```` +M`$!,`````$1,`````&!,`````(!,`````*!,`````,!,`````,1,`````,A, +M`````,Q,`````.!,``````!-`````&!-```````D`````,PF`````-PF```` +M`,0F`````"`D`````#0D`````)@E`````)PE`````*`E`````*0E`````*@E +M`````*PE`````,0E`````,@E`````-0E`````-@E`````-PE`````.`E```` +M`.0E`````.@E`````.PE`````/`E``````0G`````!@0`````"P0`````$`0 +M`````$P0`````(P-`````)0-`````)P-`````,!$`````,1$`````,A$```` +M`,Q$`````-!$`````-1$`````-A$`````.!$`````.1$`````.A$`````.Q$ +M`````/A$`````/Q$``````!%`````"1%`````"A%`````"Q%`````$1%```` +M`&`(``````@-`````!`-`````!0-```````-``````0-`````(@P`````%4` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````!.*(``3`B@`$@(H```````-`J````````````````` +M`'43+A/H$J,27Q(<$MD1F!%8$1@1VA"<$%\0(Q#H#ZX/=0\\#P4/S@Z8#F(. +M+@[Z#<<-E`UB#3(-`0W2#*,,=0Q'#!H,[@O""Y<+;0M#"QH+\0K)"J(*>PI5 +M"B\*"@KE"<$)G0EZ"5<)-0D3"?((T0BQ")$(<@A3"#4(%PCY!]P'OP>C!X<' +M:P=0!S4'&P0!W0'6`=`!R0'"`0`````#0``````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````+@`J`"`````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````#;$(Y(FY`""P`````` +M`#,``````````````````````$L#2P-+`TL#2P-+`TL#2P-+`TL#2P-+`TL# +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````*"@H*"@H*"@H*"@H*``H*"@H*"@H*"@H*"@H`"@H*"@H*"@H +M*``H*"@H*"@H*"@`````````````````````````*"@H*"@H*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*``H*"@H*"@H*"@H*"@H*"@H*"@````` +M```````````````````````````````````````````H*"@H&"@H*"@````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````H +M*"@H*"@H*"@H*"@H*```````````````````````````*"@H*"@H*"@H```` +M````````````````````````````````````````````````*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*``````````````````````` +M```H*"@H*"@H*"@H*"@H*"@H*"@`````````````*"@H*"@H*"@H`"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@`*"@H*"@H*"@H`"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@`*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H```````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````!65```.`````````!:9```/@````````!JI```/@````````!: +MI```/@````````!:I```/@````````!:9```/@````````!:5```/@`````` +M``!:I```/@````````!:9```/@`````````*(```/@````````!:9```/@`` +M``````!:9```/@````````!:5```/@````````!:9````P````````!:I``` +M`P`````````*````,0`````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````#`P``````````````$````` +M`````0```#\0``````````````````````````````4`!0`````````````` +M``0(``$```4$`0`!!``$!0`````!``$``````!K0```3@```"$`$``$`!``:,````&`$``!@!```8`0``&`$` +M*A0``"A(```F>```!K0```3@```"$`$``$`!``:(````&`$`"E0(``B$```& +MM```!.````(0`0``0`$``!@!```8`0``&`$``!@!```8`0!C`````(`$`,8` +M``#&&`<`0$`5`&,!``#&`0``"C0```AH```&N```!.0```(4`0``0`$`!H@` +M```8`0``&`$``!@!```8`0``&`$`"C0```AH```&N```!.0```(4`0``0`$` +M!H@````8`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@!```8`0`` +M&`$``!@!```8`0!"`````````*4```"EE`(`0$`5`$(```"E````"CP```AL +M```&P```!/0```(D`0``4`$``8`!``%,`0`$P````!@!```8`0``&`$`"CP` +M``AL```&P```!/0```(D`0``4`$``8`!``%,`0`$P````!@!```8`0``&`$` +M`!@!```8`0``&`$``!@!```8`0``&`$``!@!```8`0`"``````````8````& +M&```0$`5``(````&````&@```!@8```62```%'@``!*P```&X```!!@!``), +M`0``@`$``!@!```8`0``&`$`&@```!@8```62```%'@``!*P```&X```!!@! +M``),`0``@`$`"'````:L```$V````@@!```X`0``&`$``!@!```8`0``&`$` +M`!@!```8`0"$``````````@!```((00`0$`5`(0````(`0``&@@``!@T```6 +M9```%)0``!+$```&"`$`!#@!``)D`0``E`$``!@!```8`0``&`$`&@@``!@T +M```69```%)0``!+$```&"`$`!#@!``)D`0``E`$``!@!```8`0``&`$``!@! +M```8`0``&`$``!@!```8`0``&`$``!@!```8`0"$``````````@!```((00` +M0$`5`(0````(`0`````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````!````(`````,```#I`.D` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````#/[__P$```#2V```TM@``"YG__\N9___$``` +M`-+8``#2V```+F?__RYG__\0````TM@``-+8```N9___+F?__Q````#2V``` +MTM@``"YG__\N9___$````-+8``#2V```+F?__RYG__\0````TM@``-+8```N +M9___+F?__Q````#2V```TM@``"YG__\N9___$````-+8``#2V```+F?__RYG +M__\0````TM@``-+8```N9___+F?__Q````#2V```TM@``"YG__\N9___$``` +M`-+8``#2V```+F?__RYG__\0````TM@``-+8```N9___+F?__Q`````````` +M````````````````````````````````````````````````F@````$````` +M`.0,```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`/]__W__?_]__W\````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````4%!04("PL,#2$$A45%14E +M+2TQ-842%!04%!PD)"PTA!(5%145'24M-3F%$A45%14E)2TU/842$A(2$AHB +M(BHJ@A(:&AH:(BHN-CZ*`!H:&AHJ,C(Z0HH`&AH:(BHR.D)RB@`='1T=)2TQ +M.46-`!T='1TM-3D]28T`'1T='2TU/4%9C0`;&QL;)R\W/T>+`!D9&2$I,3D] +M38D`&AH:(BHZ0D9FB@`7%Q<7)S,W/T^'`!45%1TE-3U!384`#P\/%Q\G,SMC +M?P`0$!`0("0H,#R```\/#Q+`!D9 +M&2$I,3D]38D`&AH:(BHZ0D9FB@`7%Q<7)S,W/T^'`!45%1TE-3U!384`#P\/ +M%Q\G,SMC?P`0$!`0("0H,#R```\/#Q+`!D9&2$I,3D]38D`&AH:(BHZ0D9FB@`7%Q<7)S,W +M/T^'`!45%1TE-3U!384`#P\/%Q\G,SMC?P`0$!`0("0H,#R```\/#Q#"!,3$Q,C*R\S/X,(%!04%!PD)"PT +MA`@3$Q,3&R,K*S.#"!(2$A(B(BHN,H(($!`0$!@@*"@P@`@8&!@8*"@P-$"( +M`!<7%Q\G,S#"!,3$Q,C*R\S/X,(%!04 +M%!PD)"PTA`@3$Q,3&R,K*S.#"!(2$A(B(BHN,H(($!`0$!@@*"@P@`@8&!@8 +M*"@P-$"(`!<7%Q\G,SV``3$Q,3'RLO +M,S>#"!,3$Q,C*R\S/X,(%!04%!PD)"PTA`@3$Q,3&R,K*S.#"!(2$A(B(BHN +M,H(($!`0$!@@*"@P@`@8&!@8*"@P-$"(`!<7%Q\G,S`"@H +M*"@R/$1,5&``*"@H*#`X0$948``H*"@H,#A`1E1@`!`0$!`4("@H,#`-$!`0 +M$!0@*"@P.`TH*"@H+CA"2$Y8`"@H*"@R/$1,4EX`*"@H*#(\1$Q48``H*"@H +M,#A`1E1@`"@H*"@P.$!&5&``_W__?_]__W__?_]__W__?_]__W\````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````#H`>@! +MN`6X!8@)B`E8#5@-*!$H$?@4^!3(&,@8F!R8'&@@:"`X)#@D""@(*-@KV"NH +M+Z@O>#-X,T@W2#<8.Q@[Z#[H/KA"N$*(1HA&6$I82BA.*$[X4?A1R%7(59A9 +MF%EH76A=.&$X80AE"&78:-AHJ&RH;'AP>'!(=$AT&'@8>.A[Z'NX?[A_B(.( +M@UB'6(.)X(H@BBV*78I:BIJ*EXK7BM +M2+%(L1BU&+7HN.BXN+RXO(C`B,!8Q%C$*,@HR/C+^,O(S\C/F-.8TVC7:-.IXZDCN2.X8\ACRZ/7H];CYN/F(_8C]_O_^__[_ +M_O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^ +M__[__O_^__[__O_^__[__O^@NPT`X"("```````````!``$````!``$````! +M``$````!``$````!``$````!``$````!`````0````$````!`````0````$` +M```!``$````!``$````!``$````!``$````!``$````!``$````!`````0`` +M``$````!`````0````$````!``$````!``$````!``$````!``$````!``$` +M```!``$````!`````0````$````!`````0````$````!``$````!``$````! +M``$````!``$````!``$````!``$````!`````0````$````!`````0````$` +M```!``$````!``$````!``$````!``$````!``$````!``$````!`````0`` +M``$````!`````0````$````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````'=W`P,-#08& +M`P,-#08&`P,-#08&`P,-#08&`P,-#08&`P,-#0`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````F%D0!)@9BJ(````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````$````````` +MZ!N!``````````````````````````````````$````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````@0`P"T$P,`Y!`#``03`P#0$`,` +MO`\#`,00`P`````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````\`#P`/``\`#P`/``\`#P`````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````````"8 +M61`$F!F*H@$````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````"`````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````!``$``````,``D`#0```````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````"`U0``"@````0````8VH`` +M````````````````````````````````K"T`````L"T`````#"T`````$"T` +M````%"T`````&"T`````'"T`````("T`````)"T`````*"T`````+"T````` +M,"T`````-"T`````."T`````/"T`````0"T`````1"T`````2"T`````3"T` +M````4"T`````5"T`````6"T`````A"\`````B"\`````C"\`````D"\````` +ME"\`````F"\`````G"\`````H"\`````I"\`````J"\`````K"\`````L"\` +M````7"T`````""T``````"P`````""P`````I"T`````1"X`````2"X````` +MM"\`````5"X`````Z"P`````&"P`````'"P`````("P`````)"P`````*"P` +M````+"P`````,"P`````-"P`````."P`````/"P`````0"P`````1"P````` +M2"P`````3"P`````4"P`````5"P`````6"P`````7"P`````8"P`````9"P` +M````A"X`````B"X`````C"X`````D"X`````E"X`````F"X`````G"X````` +MH"X`````I"X`````J"X`````K"X`````L"X`````M"X`````N"X`````O"X` +M````P"X`````Q"X`````R"X`````S"X`````T"X`````U"X`````V"X````` +MW"X`````X"X`````Y"X`````Z"X`````["X`````\"X`````]"X`````^"X` +M````_"X``````"\`````!"\`````""\`````#"\`````$"\`````%"\````` +M&"\`````'"\`````("\`````)"\`````*"\`````+"\`````,"\``````"X` +M````!"X`````""X`````#"X`````$"X`````%"X`````&"X`````'"X````` +M("X`````)"X`````*"X`````+"X`````,"X`````-"X`````."X`````/"X` +M````J"T`````$"P``````````/____\H'8$```````````!`0@\`0$(/`$!" +M#P!`0@\`0$(/`$!"#P!`0@\`0$(/`$!"#P!`0@\`X`<``$`!``#@!P``0`$` +M`"`G``#@!P``X`<``$`!``#@!P``0`$```(``````````@`````````````` +M``````````````````````````````````````$````!`````````+2_@`#P +M-X$`&`````````````````````````#^RJVK```````````````````````` +M```````````````````````````````````````````````````````````` +M``````!`0@\`!`````$````V`0``J@````0!``""`````````(#7`P"DUP,` +MM-<#`(S7`P!\UP,`N-<#`&37`P```$```(!`````00``@$$``(!"``"`0P`` +M@$0``(!%`/]_1@`#````#````#````#```````,````,````,````,`````0 +M````T````+````"``````````&`"`````0````$``(`!``"`````(````(`` +M````````X`$````!`````0``$````(````!@````@``````"```0`0````$` +M```!``"``0``4````"````!`````L`$``*```````0````$````!``!0```` +M(````(````#P`0``H``````!`````0`````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````#"&@`$@AH`!, +M(:``<"&@`'0AH`!\(:```````/\````````````````````````````````` +M````````_P```````````````````.P`!``%```"!````!C:@``````````` +M``````"`YP``!@````0````8VH``````````````````[[ZMWN^^K=[OOJW>```` +M````````````F&@$``````#4:`0``````)A]!```````D.)$``````````(! +M@``````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````/\````!``````````$``````````@`````````````` +M```````````$``````````````````````````(````$````\=@``($!8@(" +M`WX#Y`,Y!(,$Q00`!30%9061!;L%X04%!B8&1@9D!H$&G`:V!L\&Y@;]!A,' +M*`<\!T\'8@=T!P````"8&X````````````````````````````#__P`````` +M```````````````````````````````````````````````````````````` +M3&0``'!D``"49```]&,``.QC``#\8P``7&,``%1C```````````````````` +M```````````````````````````````"`@7_`@,```(!`0$#`P#_`P$!`0,` +M`@(#`@4&```"_P````,```$#``$$!``#`P4``@4&`0$!_P$``@(!`P`%`0(% +M!@`````%`````@````````````````````$```"<$8``?!&``(P1@`",$8`` +MR!&``(P1@````````````-8```"N`0``B`(``&8#``!)!```,@4``"0&```? +M!P``)@@``#T)``!C"@``GPL``/0,``!H#@```!```,41``#"$P``!18``*,8 +M``"V&P``9A\``.\C``"N*0``/C$``+8[``!&2P``!64``#J8``!,,0$`__\` +M`/__`````0```0````$```!,YP```````$#G``#,U8`````````````````` +M`````(``!``&````!````!C:@``````````````````<$0,`"`````0````8 +MVH``````````````````)!$#``@````$````&-J``````````````````+BX +M```%````!````!C:@``````````````````HR0``!0````0````8VH`````` +M````````````\``$``8````$````&-J``````````````````"#=```%```` +M!````!C:@`````````````````"@W@``!0````0````8VH`````````````` +M````$`$$``8````$````&-J``````````````````"`4`P`(````!````!C: +M@``````````````````H%`,`"`````0````8VH``````````````````]`$$ +M``8````$````&-J```(````!````````````````````,3DZ,C@Z,#,````` +M#```"0``!@+3V-C8V-C8V`,`"]@#V-C8%@[8`P`"``("`@(```````H%.1DY +M```Y+3D`%`\4.3DC'A0H,30````"`@0$!@8&!@8&!@H````\.#0P+"@D(!P8 +M%!`,"`0```((#A,5&A\``PH1&!H@)@`&]@;V]O89'`48`!(`````0SD^%``` +M``("`@("`@``!-[?WP3>```#!0<)"Q4-#P\1$P!*3P`>=WP``!(7%1<&%PD7 +M#!&`"`-@6`0!,8`(` +M3&`"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`!``````````/`#\``@````\`/P`" +M````#P`_``(````/`#\``@````\`/P`"(`````````$````"`O\$!@8T`!X` +M$`!L`#H`'@#J`'H`/@#4`?0`>@`X`!X`$`!R`#H`'@`"`P0%``#@(@0`I448 +M`,KT)P#*]"<```$"`P0%!@@*"PP-#@\0$1(3%!46%Q@9&AL<'1X?5E>JJJJJ +MJJJJJJJJJNZJJJJJ*/\`S*JJ``"JJ@#,JJH```!``,``0`#``%``\`!0`/`` +M```````````````````````````````````````````````````````````` +M``"JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ@`````````````` +M````````;&UN;W!Q(`^0#*`>H` +M@@"9``$##P<*%#=N:@$:`=D`Z`!J`;H`>0"(`'3111?HHHLN$!B@``P8H``( +M$!`"$`@``````````````````0(#!`0$!`4%!04%!04%!04%!08&!@8&!@8& +M!@8&!@<'!P<("0D)"0````$`G&D!`,K^`0""T0(`*/L#`)B?!0![\0<`7C@+ +M```````"````!0```)S,`0!XH@$`4)\!``"I`0#8R0$`]*$!`##.`0"XI@$` +M<*@!`,BC`0!DI@$`U*4!`&BJ`0"LS@$`3&`"`$Q@`@!,8`(`$````$Q@`@!, +M8`(`3&`"`$Q@`@!,8`(`3&`"`$Q@`@!T8`(`>&`"`%!@`@!,8`(`3&`"`$Q@ +M`@!,8`(`3&`"`$Q@`@!,8`(`!````"`````D````*````"T````S````.0`` +M`$````!(````4````%H```!E````$"`P0(`(!`00(#!`4&!P@$#L`@`.0"`'SJ`@"TZP(`2.8"`)#N`@#TZ0(`>&`"`'CG`@`DZ0(`L.<"``SK`@!, +M8`(`/.H"`&#K`@!PYP(`"`````$!!0$#`0$!"`$"`0@`"``!`0,!`0$#``,! +M`@$%`0$!!````!1R`@!,8`(`^&X"`%1Q`@!,8`(`K&\"`.AR`@`L<0(`>&`" +M`%!@`@!,8`(`W&\"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`$````)@EH`"<):`` +MJ"6@`*PEH`"@):``I"6@`,0EH`#():``U"6@`-@EH`#<):``X"6@`.0EH`#H +M):``["6@`/`EH`!$!=F&1`79AH(#YEE$!=F&@@/F6?/#(F6"`^99PISH4((# +MYEG"G.A0R`'(`>0`R`'D`#`!Y`"8`.0`F`#<`MP";@'<`FX!Z`%N`?0`;@'T +M`+(%L@79`K(%V0+,`]D"Y@'9`N8!1`%$`>8!1`'F`;`!Y@$<`N8!'`*(`H@" +MS`.(`LP#8`/,`S@$S`,X!,P#S`.R!V@OH3V:'Q8IM)?0'CB.XS@PG'<1P'`0$!`0$!`0%!P0$!`0$!`0$!0<$!`0$!`0$!`4%!`0$! +M`0$!`0%!P0$!`0$!`0$!04$!`0$!`0$!`4%!`0$!`0$!`0%!00$!`0$!`0$! +M0D)!04%!04%!04%!04%!04%!04)"0D%!04%!0L)"0D-!04%!0D)"0T-#04%! +M04%!04)"0D%!04%"0D)#0T-!04%"0D-#1$3$04%"0D-$1,1&1@$"`P29F0,` +MG=B)G4[LQ$XT2(,T)W9B)QJD01H3.[$3$1B!$0_\P`\-TB`-"[W0"QH`-`!. +M`&@`G`#0`.H`!`$X`5L!-@!L`*(`V`!$`;`!Y@$<`H@"T`)U`.H`7P'4`;X" +MJ`,=!)($?`48!NH`U`&^`J@#?`50!SH()`GX"C`,"0D%!0D)#0T%!@$"`P0` +M``T/!0<)"P$#*``H`#0`,``L`"P`1``\`%5550%+:"\!5555!>,XC@.JJJH" +M<1S'`:JJJ@K'<1P'555557$<`0`$#```3&`"`$Q@`@`HY`(`8.0"`&CD`@!, +M8`(`3&`"`'1@`@!X8`(`4&`"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`3&`"`$Q@ +M`@`0``````````(``P````0`!0````#30-.`TP#70->`U\#3P-?&`/P`*P%V +M`6S[`@!,8`(`"/L"`%3[`@!,8`(`'/L"`$Q@`@!T8`(`>&`"`%!@`@!,8`(` +M3&`"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`$``````````!``(````"``,````! +M````!````!$````W`````'$#````````<0,```````!Q`P```````'$#```` +M``!8:`,`$0```/QH`P`3`````'$#````````<0,``````#QJ`P`4````X&L# +M`!P```"8<@,`$````$AS`P`0````G&\#``H```"0;@,`"@```'AO`P`0```` +M>&\#`!```````````0```/\```#!````P0```$$`````````00```!$````` +M````%1@+"PL/`PL`````````````````````$,T``"#-`````````````(3, +M``"`S```R,P```````#(S```*,P``"C,````````.*T#`+BP`P`LN`,`8+D# +M``0````<$0``'#(``!PS```<%```!````!P```"<_QC\``!P`&0`L`1Q`&X` +MT`=R`'``H`]S`'(`0!]T`',`$"=U`'0`X"YV`&``F#H``0($!`8&"`@```"5 +MF9VAI0````0,#`@4%`0$0````(```````0````(````$````0```0````$`` +M```]`F<"H`+N`EH#\`.#!/X"+`-L`\4#/03;!&X%.022!`P%M`6:!MP'%PFL +M!0\&F@98!UD(K`GG"I(!JP)'`Q,%_T%55555`0``@(B(B(@``!$```"43@$` +M&P```"!0`0`9````?)$!``<```",=P$`#````%1R`0`-````#%4!``0```#@ +MA@$``P```$!G`0"D50$`F)[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>```````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWA,````$``4````` +M`"`@@`\``$``(""`#P(`J-8@((`/`@"8>2`@@`\``/`(:2```&D@0`!I(``` +M:2!``"`@@`\"`*#>:2```&D@0`!I(```2B```$HA``!*(@``2B,``$HD``!* +M)0``2B8``$HG``!*(``02B$`$$HB`!!*(P`02B0`$$HE`!!*)@`02B<`$$H@ +M`"!*(0`@2B(`($HC`"!*)``@2B4`($HF`"!*)P`@2B``,$HA`#!*)@`P"B2` +M/X$``'!!+)PP0"R<,$(D'#0*(H`_@``D]`HC`#<"#$`62B8`<&D@0`!*)@!P +M2B8`<$HF`'!*)@!P[[ZMWN^^K=[OOJW>[[ZMWN^^K=[\'(BV_!Q(MOP<"+;\ +M',BU_!R(M?P<2+7\'`BU_!S(M/P`3<,-TT\.!X!-PLW3+PX'@$W"C=,/#@ +M>`3<)-TN\.!X!-P@W2SPX'@$W!S=*O#@>`3<&-TH\.!X!-P4W2;PX'@$W!#= +M)/#@>`3<#-TB\.!X!-P(W1_PX'@$W`3='/#@>`3<'/`T%!HP,!09,"P4&#`H +M%!'`X'\!P`HF`/"*(+\/RB!D +M`.!_+R`#`.!_BB#_#QT`(`!*(``002G(A\XA(@!"*,.'SB`B``<@R!`*(D"` +M4``A``AQ`-AI:"\M08#*)<0`+RZ!@,HFQ``")D.!RB,D`$`C?`#`*L,`J"#` +M`@(A@8#/(`8/P"&%`"\B@@`O(`*2+R`#`,X@)0#@?\XA(@`@((`/```0`C,` +M(`!*)```!R'$`"\F0/!*)0``$``F`"\D!`$.($"!`R5!`(#C#@`#``XB0H$# +M)<,`!2.%@#`!`0!Y"RB%,B0H'@?$XB`X@6``P``2C,```I@0``*(``X'^%>4XC`P``*,$`X'\">.!X +M4R)"@>!\3B(#B!8`#```*.!X +MX'@*)(#P!2!$`.`@P0=$)/Z`02K$`(0``@`O)`+Q0B$!`4(@`P'H(*($!!$$ +M`@01!0($$08"!!$'`@0;"`$$&T@!!!N(`00;R`$L`"4`1"(^@3P`(@!$(OR` +M0"'!`.`@P0=`(\,`J""``0$1A`(!&PH!("#`!P01!`($$04"!!L(`=0'X?\$ +M&T@!1"+\@`01!`+)!^__!!L(`4(A00!"($,`J""``0$1A`(!&PH!("#`!THB +M`!`M!:`)2B/`$$HB`!$A!:`)2B/`$.'%"'41\.!XX'C@>.!XX'C@>.!XX'C@ +M>.!XX'C@>.!XX'C@>.!X@.5AO>_UX'C@>.!XX'C@?\'%`-G/<(``(.`@H`/9 +MSW"``$P1X'\@H.!X`-L)\,]RH`!@#$B*`>,!&)(`4R!^@`3R[0M$@`#<"?#/ +MPGPSW*@`&`,2(H!XP$8D@#U"T2` +MX'Z&X/'``-@-],]P@0#T+J8/[_\&V0#(@K@`&A@P`=C1P.!^X'B#X/'``-@) +M],]P@0#,+H(/[_\#V0'8T<#@?N!X\<`(<<]P@0`8,B2H9@_O_P7@`=C1P.!^ +M\<"!X.'%`-@)],]P@0#R+@'=2@_O_ZEQJ7`1`\__X'CQP)(*S_^$X`#=RB!" +M`Q+TSW:!`+@N0";`%2(/[_\$V1>.MZX4KAF.%:X:CA:N`=C1`L__\<"6X.'% +M`-B,]\]U@`#P+:EP]@[O_P39`X6)N`.E`=BU`L__\<":X.'%`-B,]\]U@`#P +M+01MT@[O_P39`X6(N`.E`=B1`L__\<`6"L__SW6!`#`S)HVCP0*Y-'E`)0X2 +MCN`^9@#8)?2+<)X.[_\,V0(4@#"/'`,@GO_P#9AN#*($(`)O3/=X$`,#//=H$`<#-6 +M)Q`2J98B"N`?*'`/IX/ERB4F$+AE%'@`(`\$Z7"J#>__!MD!EPKH`(\(Z,]Q +M@`#`$P"1AK@`L:FV`=A!`<__@.``V`CTSW&``,`3`)&"N`"Q`=C@?N!X\<"^ +M",__"'7/<(``(#L"@!IQ`-X)"!$!`=@%\`L-%1')<`4!S__/=X$`N"Y`)P`3 +M/@WO_P39+H_0KU,A```1KT$HP""@N3<(9``"($(`8[TK"D4#"^K/<:````P$ +M@6&Z6&`$H6@1@``"\`^/4R""(`#9#R&!`"1X$*\:#R`B0"<`$\SQX<3\',B^ +M_!Q(ON'`X<'APN'#_!P(L?P<2+'\'(BQ_!S(L?P<"++\'$BR_!R(LOP'&X"<`(W!V`'P,`0`T;A4F' +M-&KY80.A(\A2(@(`$'9O(`L`!*%)I]'`P<1K),`0P<1K)(`0P<2?=,''P<;! +MQ004"S0$%`HT!!0)-`04"#0$%`#@?P"AX'CQP#-H-7G/RB$A`J+`T<#@?O'`C@ZO_PASSW:``"#@`(;/=8`` +MJ">3Z(()X!-H<"^-#>@!V`"FSW"``$P18*`K"5X`SW"@_MP!"_`/C1L(7@#/ +M<(``3!%@@,]PH/X(`@'9V@Y@$6ARJ0:/_^!X["AR606@!@'9*'1(DIL]SH```$!03`(99814(I0#Y8<]R@`!X5$""0H(#\`#:6&`3 +M"$4`(QO8@P'8EKC""J`B`-FEIFQPX+C`>"?T20E1(,]UH```#,2%`-P9\&@5 +M@A"$*@$L`"&!?X``3!<`(8!_@`#L%FR)`>0#NWAZ:(!G>DB@#(D!X,&X#*D" +M)P`4T0P$D,2E`=B%!8__X'CQP&8.(!$/V`H.(`H!V-'`X'[@>/'`&@V/_PAU +M(8``@"&@`*$`V`"E!!V`'ZW>`@`&A4`@#@<@A@T-01!2"^`@`MD`I@:%0"`. +M"""�U!$#X+X"`(V0"F106/__'`Q@R/_Z+!"'4Z<<]W@`"<"[X7@!``WHH. +MH!+)<8+E&G#9]ZEP*G')`4J7*/\`GI`-B6N,]QH/XX"0X)X!2I"W\@?V@^"9\F\(T0%1Z5_PC"#$@6GRC"#$@M#RC"!$A2OTJ@U@%BAP +MSW*``%#>(8*!N2&BI_#7<```!`DO\@_VC"!(A:+RC"`0@!7T?PE4`2AP`-EN +M"B`7"G*3\-=P```*&9_RUW````0@S"""CP``!"$1\A'L'PF4!`^'&PA>!7*Y +M!((P>3A@!*(2V`#9,@H@%PIR'-AU\,]P@`"@1P&`$^@C"50!BW`N".__!=D# +M%(`P$PA1`B'`A^#,(.*`S"`B@`/R`-A=\!/86_#/=8``\"U`)8`2_@^O_P'9 +M`X6`N`.E\?$="90`SW6``/`M0"4`$N(/K_\"V0.%@;CS\67IBW#2#Z__`=D@ +MP,]U@`#P+5,@`0`HK1QXP+@)K>_QJPD4@<]U@`"(**EPJ@^O_P39`I6`N`*U +MQ_'/<(``2!4`@$/HSW5%`#0X`(5["-^#>PG4@<]P@`",%'X/K_\'V1>-@>`, +M#>$BRB!A`*WQY@J@""APA^C/ +MJ7!"#Z__`=D!A8*X`:63\4SISW"``$0M+@^O_P'9`=@CASH.X!)$AX?QC"$" +MA##WSW"``$@M#@^/_P+8\_'QP%X*C__/<(``B"@"D#D('@#/<(``/`P>B,]Q +M@`#LR0.X%7@`81T(G@=-B`#9;PC?`5-H57K'B(P@`H`9\F"-+PO? +M`0.X%7C'<(``[,D@@%,C0@`$(8$/_\/__QJZ17E$N\*[8;L`,]R@`"<"[\2@`#/ +M<8``/`S!N/0A``#/<8$`4#,9J4`2@``:J8((8",!V`"5Y+@T"$(C40&/_^!X +MX<4"N,]S@`!0^Q9X`V,"(X,/````R"<+<@``VDAT!/`!X@'D%PP5$14A#0,# +MA6)X\0A3@`#8`Z7U\4APX'_!Q?'`A@B/_QIP`K@6>``@C0^``$C[SW"@```@ +M^X`"A0#>QW````!D`BI`*`$A-GD`(8`/@`"\1T`@$0@*<(0H"0_/<8``(#LP(4`.+-GB"N`' +MR7((I0@8@`0(A2*`:!E`(`B%((!@&4`@"(4`@'8-H`C)<6IP$O`!A8CH`H(" +M)P$0@.'*(8PCR_8(&H`$"(4`@,H,H`@`V0'8.G#!I14)$"!>"J`(#-@"(L$C +MB@T@(@IP#0"O_RIPX'@R:#9Y`"&"#X``2/L`V2"B:04@(BBBX'CQP*(/3__/ +M=40`<.\@A4`E#AH3:15X`"""#T0`\.\4@@'@%*($V`6E$FD4>`!F@.#*(($/ +M```B,V0)P?\`A22%`K@4>`1F`-X!AEG0=/_R<(A`\``#8S'PX$<```.C//`MY\/-$+3XG"B.`+X``I/U`(T`@,B!`#@HD +M0"X/"%$`,B"`+P``*`%`=^U#I.0L0]1D!)N%'@`),TD'64$C26-$PA1 +M`#(@@"\``"D!".`X8!!Y!&G/"*%"0A```#?`>;/?M7Q,P]1$$(E02!$*3X'SW"``*3],B!"#L]P@``L +MT#5XA>HL@`'A+*`)\#2``>$TH`/P"PI1(!78`O``V/4%;_^AP.!X\<"B#4__ +M&G`H=GIRSW"``&BZ((`*(8`O@`"<"S@1`B#/=X``'`PZ8AV7/)<*(H`OH``` +M##A@!.`">DP2`2#/<(``Y+L@H/(.8!S88@AU$!H`('01`"`N#R`69.`<%P00 +M:G"I<0#=J7)R#Z__J7.`X,H@00,'\@`F`!3F":__:G$!V'T%3__@>/'`$@U/ +M_QIP.G'T'(BPSW>``)P+OA>`$`#>Y@Y@$LEQH)>:<%IUAB+\((PB`J!*(T`@ +MQ@E@"<(CPB2,(@*@K`XA",H@`06$+`$L`"&-?X``[!8*(D`N'0@T)&P=@A,. +MV"IQ`-I(<^X.K_\*)``%A>A9`B``$]@*)8`O@0"X+JIP2B$`(U()K_\J<<*E +M#=@`I9<+$"#/<(``'!F$+`DO)H``(8!_@``@.Q7I0X`'@3!H" +M`"BX31H"`"BX3AH"`"BX3QH"``#!0B``(Y8*X!:*#B`(BG``A8#@S"#B@K#TSW"@```@^X`&A0T(Y0,C +MA0(G`A`'\.)X#B""#_____^!PX+`!2I^```8P`X`&T`.`L``(HXO@``,%P'@ +M'7@$K@2."PB2`&&X#W@"\`#8!:X%CB>..&`'K@B.`>`(K@R%`>`,I>:E`(71 +M"!$``86:#2`,)86`X`783?18%8(09!6!$`#80GG/=(``'!EBA"\A20`1"N4` +M+WE`A!4*10`"V`;P080-"80``]@`I0'8LNC/<(``G-50F`.$"0H$``2$`_`% +MA"2%(GHO(8D`!.@)"04``-@%\`38`*4!V)SH;16`$`;H`-AM'0(0!]@3\"B% +M!X40<0;8#?0&A`KHA"P)+\]P@``H.S`@0`X)"!$!`=@`I0"%DN@&C@'@!JX+ +MA0'@"Z7/<(``'!D'@`;H]@T@"(IP"=@`I40L/B?/<(``1!8P($`.CN@$(K[O +M!`0$!`CR1"P^)P`A@'^``$P6X*`!V<]P@``4#B.@`-B=`F__H\#@>.H2`[8S +M"QX$SW.@```@SW2@`(`@BX17@*O(5X"[ME>(^X0"R"!$5X`>6GH1T";_\$H>!XSW"F``#`!8#/ +M<8``2!D%H0D('P`1V`"AX'\`@?'`B@E/_QIP`-[)=!,]RI@`` +M!-&"`=_!OE*"SW*``$@9X+C,)R*0T2$A@-?S`Z(=>\.[X+C,(V*`!?("V`"B +M'/`-"1X`$]@`HACP@.7,)R*0!?06V`"B$/``$`$@@.'1(&*!"/(`V0`80"#/ +M<*```!`IH"4:@@-%`6__`(+@>,]P@`!(&0R0#P@>`P#9SW"D``"`,*#@?N'% +MSW.``*#H((L$BPBY08N!N0JZ)7HBB\]T@`!(&0RY)7JLE`;9@+H!VQL-'A// +M<*0``(!PH`?93;W"O0Z]I7H#V,]UI0"`@#:E!+@%>L]PI@``P$&@0J1@H.!_ +MP<7@>/'`1@A/_]IPSW"!`-1%P8#/<*``@"`2@*G!D.`>`28`6G$B"8`0SW>` +M`$@9%!<3$/J^02L0)$`@32C`)2(10"04,`$,]Q@``&R@.X%7@(8<]U@`!LS!9]A"H)+P`A@'^``"`[BB4#"`/: +M"!R`(``80%%`A0`8@%!"E0`8A%!$@``8@%!*D``8A%!&@``8@%`ND``81%`S +MEP`81%`3EQ79$.`3MP`81%!J<%(-[_]`)P$6`!@$4#"X`!@"4*IPR7&H/'`R@X/_X(D!#$(=@HD@"\` +M``"T02B5`%,@4@``W7W8D@@@%@6XSW"```3?`(`*(``GY[C*(4$#RB%!(W7R +M`VY&(,\`0"<`%`/:SW&@```,1J&EV0':!@C@'4AS"B$`H`SRSW&```P:0($` +M'X!`(8$`'T!``!_`0ZEQ5_#/<*8``,`3@$#:$'C1<,HCAB/*(P4@02N`(*)X +MP.#*)X80RB<%$!GO`"6`'P```+3I<78*8!$*/W"X2$"PD0(``?@$!"<6QP)P@?`,]PH```15R`&(`;"%\%!"*^ +MCP`&```']%D)A(,`W03P%-T"\!G=)0D0(`?M`]G/<*````PFH`KP`-A`'!@P +M5B0`.`39C@Z@'0':J7#%!2__@"0$,>!XX<5:8E1Z%"+-`,]R@`"HZ&9J-'FS +M8V.Y&6'/=8``TN@R)0P1`[@I8@C@+'P$*?YP)W`'X".XX'_!Q>!XX<7AQD$H +MC0#!N`#:L=L(NPOPSW&@```,FH$IV1*Y=7F`H0'C`>+O"D2#`-I(=0KPSW&@ +M`&`,*(F3;9AY.F(!Y?$-!)`IV!*X=7A`H,'&X'_!Q>!X\<#/<(``E!D@@.BY +MRB""#P``7@#4#F+_SR`B`]'`X'[QP,X,#__/=0``J&$3"%$#SW*``)09*((! +MX2BB#?"!X,HE@1\!`*"&!_+/GSW5,`$!+SW*``!38!H($@""`N6&6"F`@2'#-!`__H<'Q +MP%8,#_^BP0AV!""!#P```!@KN00@@`\``P``.+@%(%``SW6``)09,!6/$(MP +M5@T@$NEQSW&!`(@V0H$`P$$J@0/"N<]S@`#TYREC@N%$`"L`RB"K`OJ^RB!A +M`!SRSW.!`-@_]GMBBV&Y#KME>$`H`R9E>`*E!+E%(4`!0"C!(B5X17B4N)JX +M$@P@%@.E!*4`V`C<+P0O_Z+`SW&``-CHX'_P(0```-G/<(``E!DEH":@)Z#@ +M?RB@X'C/<(``E!G@?Q*`X'@`V<]P@`"4&>!_(:`$((`/`00`V,]Q@`"4&0&A +MSW"@```@&X"AP0JAX'^AP/'`9@L/_QIPSW:``)09!H8`W0'@!J9"(``E(K@4 +M>&.XX!P(L$'%0\4_V&;``X86'$0S!""!#P```!@KN00@@`\``P``.+AF#^__ +M)7A$P!D<0C-'Q67%"B0`!XH@!``CAJER)@S@(ZES"B<`D!#TSW"@```(H:`# +MA@C9389:#N`A"G.."H`43@F@("#8A.\!V!*F`_`.W^EP-0,O_ZC`X'CQP+X* +M#__/=X``E!D%A\*'`>`%I\]P@`!8%0"`BB`!)4HA`"`(Z`#8SW&@_L`&$@\@ +M%):X2B(`(,]UH```($`=@!00V,EQ%]HXVYX+X",*)(`$<0@?!@'9SW"``"S; +M(*`#V,]QH```"`*A`!@$5&3:`!B$4$V'`!B`4%R7`!B$4$^'`!B`4$`7`A$` +M&(10,1>`$`*X`!@"4``81%0$&8`$38?)<,]Q9`!4`(X-X"$XV[X)@!1^"*`@ +M$-@[A2FG`_`-V%T"#__@>,]R@`"4&3`2@``#N!5X`""!#X``[,EZB<]P@`!L +MS'9X8(`H@0*0;:(DP7!!#)<#`5@A`*<>8*X"%FA@`+=`-G/<(``E!DRH._QA>U* +M#<`:"'6I`2__J7``V86X#/`O*@$`3B*#!U)K0W+<$@*&$"#``$5Y]>B"N>!_ +MXAI8L.!X\<#V"`__&G``W:EV.G4E\/)N]'_'=X``1!L)AXP@_X\:\@J'JW@) +M\L]P``!%,,X*;_\`$`$@*X<*AP5]$PE.(,]P``!&,+8*;_\`$`$@*X:]#A21`0$/_^!X\<#AQ<]U@``$_P&%)@^@"`*`"'$!A?H+8!`!@/T`#_^= +M!$`(K01`$"D$0!`!V.!_Q1H8L/'`X<7/=8``!/\!A?(.H`@"@`AQ`87F"V`0 +M`8#)``__\" +M"V`0R7$`V"4`+_\`I>!X\<"^#^_^`-K&R<]V@``$_Z&&#N@&Z<]PH```(!N` +M!O``A@^``8!AN`':!?#%R?7H2'`*Z@#9QAI8L.(.8`C%&EBPH8:6"T`0SW"@ +M```@.X`"A8P@PX\2\@.%`B!`@`#9RB%O`(#ARB`A`-=P````$`38RB#F``/P +M`=CR#@`(L0?/_N!X50-`$`'8X'_%&ABP\.!^X'CQP`X/S_X(=87@RB"&#P``)C#T"&;_RB%&`\]V@``$_R"& +M#X&(Z"&!SW```"@PX@AO_ZER((8!@1`@0`,!H0"&+X``V`\@0`,V"V`0(8$Q +M!\_^X'CQP+H.S_X(=87@RB"&#P``(S"@"&;_RB%&`\]V@``$_R"&#X&`X,H@ +M@0\``"4PA`A!_R"&`8$/($`#`:$`V-X*8!`/($`#Y0;/_N!X\AAT,( +MG@`&EX+@`-@'],]P@``$_P"``8`7Z%X-@`B`X`#8"?3/<(``!/\`@`&`F@J@ +M%`'9`GW/<8``!/\`@:2@`(&D@`(E@!,5"%(`SW"``-@:$@P@(*EQ"?`!V`CP +MSW"``-@:K@L`(`#8.0;/_O'`Q@W/_L]PH```(-N``-W/=X``!/\`AP#94("` +MXLH@00`A\BZ`%NDGD2D)'@`BAT#@08%0=@#9RB%O`(#ARB&"`,HA@0/>#2`` +M`-H%?0OP(8)`X$H@0"#*#2```-H%?0IPV.@#[0#8)/``APZ`?>@'D/<('H"B +MAP3M!Y41"!\`SW```"HP0@\O_ZEQJ7#"""```=GIZ`*'@.#*(($/```],!P/ +M`?\"AP"`N@[O_P*G5P@1@'D%S_[QP`X-S_Y&D`AVX[K*(($/``!B,``/(?_* +M(8$#8@T@"`*&&G!`(`T"_A4`D6,(WP%`)0\89(\\C5V-,',%C\P@C(#/]AB[ +M$+D(N"5[!7O!V""%!KC"#B__97H\C62/!Y8+")X!*PM!``OP)PM!`"6/'8T? +M"0$`_A4`D1<('P$&$``A4R!^@`0/8@C*($(#Z03/_N!X\71"$^C\H@@0\``"$P4`X!_P>7IPB>``:71"". +M`&(*H`CI<`:7;0A>`,]U@``$_P"%3X!0=\H@@@\``%@P*`XB_\HAP@,!V!IP +M((4+I06!H8$/Z`*!&PC0`'H-X`<,V(?HSW&``#SS"G``H03P5@M@"`&'"^C/ +M<(``V!J^"0`@!MB""R`((H<$\%X(8`BI<`:7X+@1\L]U@``$_P"%3H!0=\H@ +M@@\``&\PO`TB_\HAP@,`V`NEM0,``(:X![=>#"`(`H?^$`&!Y[GB`@(`1Y<* +M<6:72B$`()(*(`@*)$`$.@P@"`*')I<(=40A``,3"!$#SW```%$P;@TO_T*' +M`86,(/^/!_3/<```=3!2#2__((4&EX4(G@!9)0,2GY,AAT\D`A$=C5^S@.#, +M("&@%O1/)``1W(V)N#L.\A`?LS<*GP)/)``1B;B*N!^SSW.``%@20(,!X@[P +MZKK*(($`"_*JNE^S4'C/`?X5`)&%N/X=!)`E%8`0C""#CTSV`>`E'0(0"/`1"%X!_A4`D:6X +M_AT$D$P@0*"-]`:7XKC1("&!/O+$C0#9"B&`+X``!/\`$0`@#R&!`P&`"WGR +MR21X&O*3Z((*(!7)<(_HA@H@%^X +M]`KB_\H@@@,6\`[H7@H@%^X'`OA +M_\H@@0,&E^.XT2!A@4?RQ(T`V<]P@``$_P"`#R&!`P&`"B&`+P```(`+>?+) +M)'@<\HKH_@D@%\]P``!V +M,,EQ@@LO_T"%'?`&Z-8)(!7)<"^5!>@OE1\)WP,$(4$$@.$!V\![SW```'

\,]U@``$_R&%`!44$``1$0`($1(`"!03(*(((`@"AR:7 +M"'93(4``@^#*(($/``!9,(`*`?\&ET0@/H4DCA7R`KE#P"%`-X;"`$%`H`3 +M",$$(84`@0L(000"@0D(@`0!WLEP/0#O_J;`\<#V#X_^"B8`D,H@@0\``$(P +MU`D!_\EU$O`&E88@_PR,X,H@@0\``#LPO`D!_P:5X[BP"N+_RB!"`Z"%[^U> +M"&`(R7`A`,_^\<">#X_^"B4`D!IQ.G(`V%IPSW:``&@R`*8$\@"%A^C/<``` +M;3!Z"0__`(4A@`(@0"`_N%(@`(`Q\B;P)@@@"`*'`=G^$`*!$0D0(!$*'@$& +MEX8@_X4$\BAP`_``V.>ZS"!A@`WTZ7#&"N__`-D`AH?H!I?CN"0*XO_*(,(# +M((8`A1#IX(4`A@GOB>@AAP(@0"`_N%(@`(#2]64'K_X`A@"``*4`'X`4J@\@ +M".EP[/'QP/X.C_X(=2AV?(A%@(#C)H#,(B*`S"$B@`;R$PM0``\*10#/<``` +M:##B"`__=@K@$@&%B.@@A<]P``!I,,((+_]!A0^5$P@?`R*%R7#"#R`(184" +MI1D'C_[@>/'`F@Z/_AIP`@_@!P#="'9`(`\"Z7"&#>`'`MD#EE,@00`="5$` +M*!Y"$T$H`2+/<($`[!NZ""``+WD$\`D)D`"I<`CPA[@#MLX(8`CI<`'8L0:/ +M_@GI`($`H@*!0*$HN`]X`K((\""`(*)`H`0:A`\``/__(((&Z0*"*+@/>`*Q +MX'[@>.'%"'(PVVQYSW&!`*0/H((`(4`.@(`;"$`#0I!L>B=Q@*$-["*!*+DO +M>2*T!_"`H@7L!!R$'P``___@?\'%X'CQP,(/S__/<8$`H!L(,]R1`#X\R&"_]L+"<``+0A0`"*""0G``"$(D`#/<40`6/8E +M@0MY`MD(\N$2@0`#@A!Q`=G*(2X`X'\H/'`I@M`%W8+ +MP`_*"H`(`-A*"B`7`=FR"8`(T<#@?N!X\<#N"D`7`=@R"B`7"'&R"H`(T<#@ +M?N!X^0.`"&$$@`CQP,]P1`!X]*(+H`A($(```=G/<*```!\]H-'`X'[@>/'` +MH@_/_](/``(`V<]PH```'SV@T<#@?O'`2@R/_L]U1`!X]!*%@^`!V,!X4B`. +M`(#@`=@."Z`3P'@!;H(+H!,`V1*%,PB0`%<(T0`$VL]PK0``JE"@SW&M``!$ +M2:$"VL]PK0``A$F@(!F`#P````P0V`BA%?`"VL]PK0``JE"@!-G/<*T``(0I +MH,]QK0``1$FA(!B`#P````P0V2B@-02/_N!X\<#."8`(SW$#`#`/SW"``+0; +M.@O`#\8)@`C1P.!^X'CQP,]Q1`#\\D"!`8$%(CZ`!_1#@02!!2(^@`G8`O(( +MV/8)H`@`V<]Q@`#`"`"!B^C/<*```"`;@,=P!`#@DP>A`J'1P.!^X'CQP%8+ +MC_[6#B`6+WWF#B`6"'85>`7@SW%$`/CSY!D``.`1@``9#0$0&PW1$.(1@``0 +M=@0)H@C*(((#!?"6"F`7J7"%`X_^X'CQP&(-`!89"!X`SW!$`%CV"("#X`'8 +MP'CZ"(`9T<#@?O'`Z@JO_@#8SW9$`'CT-X95)D\7@.'/=40`^//*(&$`!/*! +MX`,]PH/YT!,H)8!``V58/@`C1P.!^$PA>`,]PH/Z8!+()8!``V?;Q]O'Q +MP.'%SW&``*!'HX$%?5,E_I`'\@*!C"##C\\E`A`)[:.A9@B@%*]X3@E@&JEP +M50&O_JEP\<#2"*_^`-E6(`T$1H79$@RV!"*##P```!@KNX`D!A!`)`X6,J45 +M"EX"&(U$N,&X"&:)N`AR1O`$(KZ/``0``3?R7PJ>!MV4P[J`YLDC8@`H]-"( +MSW"!`-@_%B"/`^"/AB?_DP?TSW>!``!PXX\)#YX0`=D6Z4`K00*1N=9X`(@R +MI0#?$0A?`<]P@0``<`.(!PC>``'?!N^(N3*E`O#"ND`D`1A880:(66%0B0CP +M.(T\><*Y.&2980B(4(D]E"5Z`J48NT5[>0"O_F.E\<#Z#T_^2B``(`IU+/!` +M+1(1SW!%`&`C`"*/+T4`]"#"AP&`/0B%`P&'A2@!"3IP+W#2"*_^R7$`(H$O +M10"T*Q6A6!E`!,]PH```(!N`UZ$8H4\@`"`O(`<@`-@!IP*G`>6O?:L-TI`7 +M"!`@`MG/<$4`M"L@H(391@@@':':W0=/_N!X\<"&#T_^R\FBP:00`P"8$`(` +M#8`?SW"@`(`@T("+ +M<Q!````#!PGT!P#UE06@P=/'`[@YO +M_@#;SW&``(RK((F$*0$#SW%%`'XM-"%,#L]QH```(&@1!`#`$0(`00@1``6F`#PL>!<]S@0`T1H&#`O"!D&*00GP")``#"",# +M``3P8I"#D)MC:'0Q\('@S""B@#;TRQ(#ME8C#P3`EPT(40!^$P`!!?``W`(D`P`2\`F'%P@>!<]R@0`T1@*""PB4 +M`&&"`O!AEYAF&V,"EQMCW&2ES14(7@#+R780``%BN)U@"_!H=<;Q#PMR`&*] +MV"&`'0G>`#"(`[DU +M><=Q@`#LR4N1[!B"`"J1!O`_V>P80@``V>!_ZAA$`.!X\<"^#4_^E@L@`@AV +M"'6,)<.?`-AT\B*&(PY$<`!```!$AAL.A'``0```SW*@`(`@7H(-#H5P`$`` +M``'8C^C/4!X`FI#`_!'?4$3_[@ +M>,]P@`!4@4&`(H"MV!"X4Z`XH,]Q@`!TJQ*)`>#@?Q*I\``%2`P[W/=H``5(&&#N`5HZ;@N,HG`10M\OP7`!`` +MV04H?@,$A@O:+W?Z#F_^*',.((./`0#WTP#<`R1!$&APZ7+B#F_^`-L`(("/ +MPOUQ/8$A_P]*#V_^%=H/>$D@P`%5H!7H*N$5X0"C/`P5_(@[`%>&XRB`! +M!"KR`(8`V04H?@,$A@O:+W6:#F_^*',.((*/`0#WTP#;`R-#`*EPA@YO_@#9 +M`""`C\+]<3V!(?\/Z@YO_A7:#WA)(,`'#WH5:D5X"KI%>$`HP@-%>.&FS0-O +M_@*F\"T_^_@[@%0'>K@W@%1IPP+B!X*8-X!7`?H8@?P^"X`'?P'\J"2`+ +M"G#/=8``5(!6)0$8527`'\ERH@Z@&.EST@[/_R()(`L*<,]P@`!4@AZ8<0-O +M_D4=&!#%`*`0`=C@>/'`G@[`%0#9`O`!X1$)503/P)Z4'/`(6T`SW"``%2`(K`V>"200Y`, +MN45YSW*M`(`5(*(ED`:0#+@E>`&BT<#@?N!X\<"*"F_^_]FBP0AV`-@Z<%8* +MX"#)*``"&-?X``5&P`A4#'/0\`$`$4D#"*#>`5R7!: +M<,]Q@`!4F%`1`(:$Z#`97(3)<#(,8`D*<0(/@`DB"*`*R7#)<*X((`I*<>"E +M`=C_V?8)X"#)`(0H%@G/`*'6!X,P@HH#*(($/``#_?PGRBW!(<78,(`H`V[M]@W4,G24";_ZL +MP/'`@@E/_J+!"'>:<7IR&G,*(0`AD@S@%4AP"';.#.`5:G"Z<`'="B*`+X`` +M3#(`&D`C2B<`(`L($"`/#E(0JG!^#^`*`-F^"&`)BG!`P"8,X!5J<('@`=C" +M(`$`@.`!VEQBG-B#*`#"B3` +M!)8.H!4`P!X/@`,6#X`#A"L;(,EQZ7(`(8!_10!`!^H.H`.*<]IPI>^!P7X. +MH!6J<"'`A"B%!<]P1``X]R]QA"["&B=Q&6'*<&(-H!VKVL]P@`!4@AZ80"N! +M(#1YQW&``%2@51D"`,]PH```(!N`%J&$YQ0*(1G*($$$&@Z@%0#8`>8Y#I20 +M4@W@"@'8/@[@&`#8`-AF":`)"'$E"!`@Q@K@%6IP@>`!V,(@`0"`X`'9P'FV +M#6`0`=AV".`5:G#:#>`*JG`8[?H*X!5J<#IP#@O@%6IP&G#""N`5:G`(<@#< +M#R3,$R\D!P,J<`IQ5@[@"6IS`!K`):EPR0G`*)8"0*'`: +M

$HA0"#/<8``3#):<0`90`2.#>`*J7$`WLEP.@U@$&IQI@S@"LEP +M`=C^".`@R7%V">`"\`#@^C)=P+P*G`8`-@`V$H(H`D(<0`:@",E!R_^Z7#@ +M>/'`P@X/_CIP*'9(=XH*X!4:<^(,H!5Z<(0N`A//<40`5)0@@0*X)W$5>``@ +M4@#/=8``W%9`(D`@E.\CA1D($"`O8&IPM@SO_\EQ"2<=Q@`#4:GSA!V$"(<$C+R=)$`T/A1,O)DD0*'1( +M=0'BW0J4@1\,$Q`Z;CVYV6%#N<]P@`#DZA4@00#`B0#8&_`@W@#8&?!"*<`@ +MSW%55595!"A^``H@P`X.>$D@@`$.>$@@```.>!0B`2`&B<>)4R"-`2>X_@O` +M&,]P@`#$N`"`SW&``#`@L*$-"%$`%"5`$Q"AK@O@&*EP`=@."V`0R7'/<(`` +MW%8'@(SH`!*-(`#84@[@&*EQ`=A*#N`8J7'/<(``>`M`@*W9$+E!H0&``J&Y +M!0_^X'CQP.'%"'7/<8``5%@A@0'8X[G,)>*0#/*$+189SW&``(AK,"%!#H#A +M<`N!%80M%AD*(0"`RB%B```A@'^``$QKH04O_B"@X'C8<(AP"]P;#1``A"A! +M`R]RC'DG<@`B@`^``+Z?$?"$*-(`+W"$*L,))W!$*7X(`"$!<(Q[)W$`(8`/ +M@`"XELAQ\0&@'0O:X'CQP+X,#_ZAP18(X!4:<+IPE@^@%0IP"'6!X$HB0"#" +M(H$D`-Y:"2`AJG#/3CA]2'!`$`H +MU```'$0P01("!L]Q@`!4D19Y$.'U(8```AP$,`T-41#/<(``8!P%\,]P@`!4 +M''IP`-T#\`'EL0V5$!)M%7@P(0`@@.`!V`CTJG"F#R``J7$(=@78A"@6*9AP +MSW*``,B/+W&$+086`"&##X``U&IH&X`/``#D#``A`'4S(@``&:,`VP/P`>.Q +M"P6!`-KY"M6`0"J`(!1XO&64?)A@5'C/=(``D!PU)``0NWPU)`PS1"T^'YA@ +M]2/,()A@DFN4?"=T57P`)(\?@`"49B3GV&#'=(``M&8_9P"W!N0`V#QD`*P! +MXM;QX0,O_J'`X'CQP'X++_X(-(/8``U +M(0``SW"``&P<)("%@`T*40`U?#,@%0,#\+IU1"L^#P`A@'^``,BX)X`5"9$` +M`""!)33A-2%`!(`@`@;1YSW*``$"5-2)!`")X)H1%A+((8!@!VX#@RB",#___,/BN +M``P`E@]`%,]S1`"`WUR#@B`'"`#9#PI1`#^#-'D#N3-Y`"$1`"&&#PE>`B2Y +MP;E`(0X%'/!!*8`#PKC/&JX'F9>#8`5`[@4>!YFSW!%`+@;,R"!`X'G(G&*(#\$ +MP'@980IPA"@6"<]P@`!`:S`@0@Z$+086%B&`<,]R@`#*CQ!B.&#Q`0_^X'CQ +MP.'%^@R@%0AU@>`!V<(A00``V`':SW,S,#`P"B2`#S,P"3"X<$(/8!C8<,]P +M@`#TW?`@0@//<(``>`M@@$`J00,$(X,/_\__GP0A@0\```!@'+H$(H(/`#`` +M`$5Y97FI`2_^(*#@>`2Y-'DX8$>`SW&``(0<\"&!`.!_)J#@>/'``@D/_J+! +M"'`",-G/<(``5*`'@$H@`"!!"%$`"G`#\`'@@^`T +M!`8``-KY"I6`,FA4>=EA`!F$#P``_W\,&80/``#_?Q@9A`\``/]_)!F$#P`` +M_W\!XNOQCN48`0D`2@W@(*EP&G!"#>`@*G"Q"E$@,G4!V<(A20`8($``$'MX +M9QP0Q0!`)P@8!!Y$$1P0P@`4(<0`0+8F$,<``"`!$1P>Q!%X9R80P``0$<$` +M`"`($0`A!@`8'H015B0!Y2B!`(!#P2B"`(`[P2B#`(`KPSW````PKJ7%."6_^ +M*G)*(``@,G5*(D`@PB*)).KE(_(/]KKE'?(%]JKE;O0`V2#PRN47\MKE:/0# +MV1KPC"6"DA7R!?;ZY6#T!=D2\(PEPI8/\HPEPII8]`C9"O`!V0CP`MD&\`39 +M!/`&V0+P!]E6)P,4.&,>$,8`%")2("`>A!$>$,``5B<$%@`D@@0,$L(`.V,` +M(@4`'!Y$$1X3PP`5(%`@5B<`%0`@`@0($L(`@"<&&%MC;+8Z9P`2QP``)(0$ +M`">,`9&V`!+&`#]G`"9,`8^V`!+,``)PFV-MM@H2PP!VM@H2PP!WM@H2P@`, +M%,,`>F)4ME6V"A?!$`@0P``983*V,[9_\,]P```-*ZEQ1@AO_BIRC?%W"E$@ +M,G4!V<(A20`B>&ZX''@0>%8G`Q,:8P@2S``4(04`CK8:8P@2P@``(T$!&A'! +M`*!S`"&$`!@>!!'I<8`A"``:87P2PH`985QDC[9\$<&`@"<&$(!Q+;8:9PX2 +MP0`?9S2V#A+!`#6V#A?`$!H3P0`X8#GP0B&``Q!X5"=!&#,A`0"`)P@0++8; +M9S`3S(`?9SQDC;96$\.`]MC!ILO)$```"1,,(2,`K@)(``##GT&LP";`K@) +M(``#+R<&``"S$IL"N`D@``,O)@8`$K,,FP*X"20,$(Y_C+,))8T0KGRFLPDB +M@@%.?34D`#%2LPDD#!"&LPDG!P``&\0!"2'"\?D$[_VB +MP.!X\<"B#,_]"':V"F`5*'7/<40`"(G*880M!A8"N+1X%B&!<,]R@`#*CS%B +MSW*``/S=-2("``(A@`#9!._]#GC@>([@RB`L`,;VY.`!V,H@J@#/*EP!_`"V`7P"-@#\`38>03/_<]P``"<$^X-#_[R +M\>!XCN#*(BP`QO;DX`':RB*J`,]T@`"/'`F@O/_2AWSW&!`-A`H(&PP00EC!\````8*[P$)8$?``,` +M`#BY!2$5`R"`@.,@MP>``;>#\H'BS"*B@'_T02V`$\*XSW&``/3G"&%*(@`@ +M@N`!WL!^!"6`'P@```#B#F`502C1!!IP#PU>$@/NA,80\('&#O`-[A,)$"#/ +M<```#BLJ#2_^2G8$\(K&`O"'QHHBB"G/=8``=%F^#F`50"44$=H.8!7:<)AP +M0"01,2\C!R0$;2IQRG*(<_()[_\*),`$C<')<`8(8!T,V@'=0"V5(`3P`>6O +M?4<-$Q$$+;X4=@Y@%0H@0"Z2#F`5VG"8<``D`"0J<__"B3`!`#: +MT0J5@!0E@"`U)@$0@W!ZF`@C0P!ZL`'B]/$`)$$U&IE`GQC@"2("`$"W&YDA +MGQC@"2$!`"&WL0+O_;#`">L"NC1ZSW&``)2/-2&!``;PSW&``,X=26$S>80H +M%@G/<(``.&LP($(.SW"``%2"'IA">"QX+W`+"!,`@B`$@`/P@"`$@,`@A`\` +M`/\!X'])N.!X*NN$*!8)`KHT>L]Q@`"DCS4A@@#/<(``/&LP($$.SW"``%2" +M'Y@B>$QX+W`9"#,`BB$0``(@0(#`((0/``#_!^!_2[@`($"`P""$#P``_P?@ +M?TNX`-C@?O'`X<4(<0#=`=C/@!Z +M`MDEHQ+P`]@0\`38#O`%V`SP!M@*\`?8"/#/<```EQF""P_^J7#Y`<_]\"6``J7$!Y!X +MX<62:I5\SW6``-0=A&4(X0#;$^R$*!8)+W"$*H$$QW"``!1J-.`U($P.%&H4 +M>#4A```+"`,#:'`&\(`D`A?[#`*0`=C@?\'%\A"@6"0HE@`^``)1F`"!!$51Z+W"``YX@"`"B!!] +M#@`D`!JRT-D+"0,`.K(H=<]P@``<*:A@%+(()`P0E+*(<$(.K_]H<<]P@`"( +M"W5X`!B`#\OSF!F]!X_]X'CQP$H/K_V8<0AV2'4/>BAP(@[O_ZEQ-&U$+3X? +M-'F`<8:!"B"`'X``E&82;!1X`"!)#H0N%AD`(0(2+W`;8AIB*!)&`5)M\IM5 +M>@`BAP^``.0<0!<#!DHE``"4>\"+&F)AB\)_`B;.`,]S@`#4:GIBE7J>F@@D +MS!-?F@@B@@/$F=%TRB(L`,HD+!#*]M%R`=K*)"P0Q/;T%PP!`MI'H=)MU'Y5 +M?GYF).8&9AMC'./(H?`C0P-IH14A@Q``(P("&V)RFQIB9K$$F5*:0G@.>(`@ +M`H@0>PX`(P`:L3091`$`VP;PT-H)"@,`6K%(<\]P@``<*6A@%+$()`P0E+'/ +M<$0`@-]<@!4D0`,1"E$`SW)$``C@\")"`PCP`MI:H$29T.+#]@/:6J`F@<]P +M@`"TN`L)D0`@@`+P(8#/<(``B`NU>'4&K_T@H.!X\<#F#8_]5@A@%:O!+R$' +M(`'9"B2`+X``5)@P'%R@4!Q8H,]U@`#D'`#8'@M@"AIP5@\@&`IP_@B@&$`I +ME2,@'0`44!T`%!@=`!1('0`4*!T$%%@=!!0P'0048!T$%`IU!_"F"V`*`!:` +M(`'EKWV"Y1`!"@#/<8``:AS/<(``5%@'@(#EP2@A`L$HH@)3(!,`1""2```A +M5@-6"V`*`!:`(``6@"!Z"V`*`-D`WP+P`>>S#Y60P@NO_^EPBW;)<`K9M@P@ +M'$4EPB')<`K9J@P@'$4EPB')<`K9G@P@'$4EPB&R#>`7`=@W"1X@,PL1(,]V +M@`#(N">&@>'*(((/``"R&?P.POTS;P"&-7E!AK5Y0G@`(8(/@`!`E0"R-PE> +M(#,*$2#/=H``R+@VAH'ARB""#P``LQG(#L+],V\/AC5Y4(:U>4)X`"&"#X`` +M0I4`L@':`O`!XEL*58$`V_L+E8`S;S5Y%2%``W1XSW2``$"5-20`$%9YM7ET +M>3QD`+0!X^_QQ@E@"@'8`@X@&`'84@M`%78+0!4P'!RD4!P8I)D$K_VKP.!X +M\EP"0@>``'8'*96#B`5Z7`+"%X``=@!I1R&SW&``,BX +M#J$!A6T$K_T=H8#@SW&``-24`-@#\A>!X'\6H>!X`-H:\#)J-7G'<8``9!V< +M@0'BG&25?``D@Q^``*@Y5\FV/'!XJ.#*("L`BO:\X,H@;`#&]M#@ +M`MC*(.D`SW&``&P!X\<`6"X_][!P(L'X.(!5!P1IP2B,`("+PV6'8 +M8`KA"N`U(4$#-2!``P)Y!"E^!4IQ+W"R"*`/ZG("P`3!!"B^!2=V"N8U)D`3 +M.&``(0$E-.&Y80"Q0"-3($PC@*`D`08`0"N`(!5XSW&``-0=`&%TZ(HF@BG/ +M=H``E()`)@$2%2`#)(H@@31`)!5UEKWT.\((A`@W/<@``/!1982]Y +M@B4"'5UEKWV"(P(->F)/>B)Z+R6'(`(E4A``WP0LOA4O<00K/B8`PB]UJ.<$ +M*GX&[`;J_PHA0"ZY8;A@V6'88`SA#.#T(<$#]"#``P)Y!"E^!4IQ+W"2#V`/ +MZG("P`3"!"B^!2]PN6#980SA]"'!`R)U66&"=3;E]'T@M0'G[W\#Q,[QV0&O +M_:7`X'CQP*H)C_VAP1IP#WUZ#"`5J7"!X`'>^@L@%<(F@1,O(0<@T@L@%6/#940`-X/)DX3"R9`E/GS!":.E`'?`,+" +M)\$3"G"I<>8.K__IKQSW&``%2"A"@6*5Z9`"&`?X`` +MU&H_F5F@.J#/<(``9!Y>J"RP'0&O_:'`\<#""(_]SW6``"0>/!V$'P``_W_/ +M<(``C*MN#"`5X(B.X,]V``#_?\HAK`'%]N3@!]G*(2H"SW*``.0=%B)#`#B; +M(+4K@R^B&0_1$(P@0H6(]HP@0HD&]@R=!+45@@3PQ+4`V!&B`-D+\!8B0P`+ +M@P;H&)N>G0D@``,>M0'A[PD4@1."/IT_M07H")T)($``'[6=`(_]X'CQP"H( +MK_T`V<]P@`",JZ"("_``VV>F$FD4>)A@::`!VVJ@2Z`!X4<)E0`2:80M%AD5 +M>,]R@`#4'0=B`MK/!X\<"V#T_]"'4:<4AW`-X5\(0M%AG/<8``$&L2 +M;Q5X`"%"#L=P@`"8'C)N-7E98=8-X!P*V@'F,PZ5$+X)(!4*<-$('H``V?$) +M58&$+189$FX5>`#:)W#'<(``U&HU>%ZP7[`!X?'QN0=/_>!X\<`F#T_].W!Z +M#&`)*'>$*`$,LF_/=H``Y!RU?0`EE!^``&0=`"91'E4F6!]`(0`F&!!I\`@202$B>`YZ-"!`,W)PS">AH`/TOPI3 +M`(PCPZ_,)R&@!/2O"A(`D@M@">EP1"\^'T`HC""4?"MQ+W.$*18)`"3%$`HD +M@`^``)1F%27,!2]Q`"0#$3MC)0BB!;*;Z!:`$,=T@`"T9DQX!N0\9$(IP'"X +M8!*S`=@`K`GPYQ:`$$QX0BG`<+A@$K-P%``@H^@`WA_P%26"`P`BC`^``+1F +M!N0L9`(G@",->)+L@'(Z8K*:DIOV:()]+R5)$R\GR1,-#T43!"A^!2=TDK(! +MYLD.U)#U!4_]X'CQP$()(!7AQ5()(!4(=<]Q@`#D'('ES"!A@,H@00"`((4/ +M!?(H<(`@!0\E!F_]81D8`.!X\<"6#4_]A"@6"0'>`"&-?X``U&KEP@>!*(4`@PB%!)'H((!7IEP"'=,(`"@S"%AH!GTF@_@%,EP +M%>A5V%/9_@W@$>ER"';/<(``>%DP((`/``#L#+X-X!'I<0L.`!``V!REB05/ +M_>!XX<7AQ@#:@.`!V\(CS`"*(?\/='DO(`D`SW2``*C@!-L-\`#=#R7-$*5Z +M\"2.$!`BS0#1<,HB10-AN^L+$X!5?&&$`GN`A&Y[@G@.?`%JD7/*((H`%'@L +M>"]PP<;@?\'%\<"N#$_]ML$(=CIQ&G*V""```-VN"N`)R7#/<40`\)(`H4`D +M$S3/<(``%#)J<:X)X!PHVL]PIP``2*B@J:"Z=98.H`6.QS(.X`EJ<`'8R7$` +MVM8-X`GI`)Z7$!V,EQ"'*^#>`)Z7."P)IPC@G@">EQ2G"*<:(( +MX`D*4"NE5Z`"+!!")RF@^@"0IP(H8"N35Y`"%`!&)Q.@G@'!3:&HX$ +M$`$@E0TDD``E52`$&$`E201O_;;`\<`*#$_]OL$(=HMU5@H@"JEP0H8`V`\@ +M@`!#PD3``(9"P`2&3`X@@@\``0```-N,NU-X@.+*(6H`RB0+$,HDBA`S +M>,]R__\`\(#ERB4+$,HE2A#*(8L`RB'*`#QX4@QO_9A@K'C!`V_]+W`O(`D` +MC"`%BO'`Q_TW`X@`0,O($D`BB+_#]K@R/>T +MW`X@`0,O($D`4WH;>`3@([C/<8``[!#P(0``3'@O<-'`X'[#N@2ZP[E%>2"H +MX']AJ.!X(G@.>(+@X2#)!\H@J0"*(;\/,'#A(,L'RB!+`.!^X'@`VC!PRB"+ +M#______@(,L','#A(,P'RB",``'8X'[@>/'`F@I/_>X,X!0`W0]X`_`!Y7<- +ME1#]"$Z#`-X"\`'F\0Y5D0#<^PS5D$XD@Q"Y939Y>F-4>EEA4FU4>G5Z\=R@``4JBCBJ13+I"?^JQ;GKKF4BZ +M0G_KL88C_`,(NVY[29%,NV)Z2;$!Y-'Q@0)/_>!XX'\!V.!^X'CQP.'%:@[O +M_PAU"''R#^__J7#:#R`/"+AI`D_]!"B`#P``+[I"*<)T1"K^`@(@0`XO(`B` +M4'L$\@'B4'L)"#,!8+&$Z`#8`_"`V.!^\<#/<(``C*NF#>`'`(@*Z.8*X`X- +MV/X+(`@-V`'8`_``V-'`X'[@>/'`B@E/_3IP&G$/V`#9*'4H=A#P!"!,!`0A +M`@0%)+Z0#R6/$\HEPA-V#&_]!-H!YN4.5)*Y`6_]J7#@>/'`5@E/_0AW*'8` +MV%8A#00'I8H-(!<0B0AR5B;`%(X+8!#)<0:%!""^CP`$``$)\@F%'!V`'X`` +M``"4N`FE40\>$%H.H`3)<":%1X43"9X'"86%(@$$C+@)I4>E&/#9R8`@!@`; +M"=X'*84%(H(/0`%0`(VY*:5'I32`GKD'\)2ZEKI'I32`GKF?N32@-0%/_3+( +MQW"``!2X*(@!X2BH"(@;"#(!RQ(!MJ`9@`\#`(0`BB`(`-(:&+`)\(H@$`#2 +M&ABPH!F`#P(!A`#@?O'`A@A/_1IPZLDH=R4('@?/S`3!``!V6:# +MSW#%[H7R*'*F"Z`?"B4`!`#>)O#/=8$`B!S5?0:%/P\!$`"%&^CJR24('@?/ +MT@3!``!V6:#SW#%[H7Q*')J"Z`?"B4`!""%8'D*<`#8`*4&V`:E +M`>:Y#I21SW"!`+@<`-GU>""@)J#/<8``2!0`@0L/`1`&V`"A40!/_>!X\<#/ +M<($`B!Q2#"`",-G/<($`N!Q&#"`"8-D&V<]P@`!(%""@T<#@?O'`X<7/=8`` +M!"`TC8#ARB""#P``5BND"8+]%(V'Z!6-A>@!X!6M`=@"\`#8#0!/_?'`X<7/ +M=8``!"`UC8#ARB",#P``6"MT"8S]%8UAN.T'+_T5K?'`9@\/_0AV&G&$*`D/ +M`"&-?X``@#W/<(``(#O/<8``<"<@@7&-08DP($`.-PNC``#?4HTCB2\*0P`F +MV>H)H`4"V@@8``0@@`2^UGX`)H`?@`#<1R"@5@Q@!NEPF@E@!@S8;0`/>0.N`!,`(`2($'%(#"H'RB!*`_+)#0A/`Y(.8!.I<`?HJ7!R"^`*X!*! +MH.(.`!H!CM)P^`R&"-(/0"`ACB'HSW!$``SR`("=Z#<)D@(`CC,(D@*""N`A +M`-@$V,]R@`#\^0AQ0!I"`"BY01I"`"BY0AI"`"BYI@F@($,:0@"O\0`3`"!! +MB`T)@P!BC@.(10L"``D)@@``C@/P`HY!P$#%`8Y"P`:.0\``$0`@@.#*(`$$ +MRB*!#P``H@!(#J$;RB$A!80M`1P!V0`A@'^``%D7(*@`$P$@08X`B0T*`P!" +MC@*))PH"`#P5`""/Z`@7`2"9(1@`\@WO_ZEP`KU#=2H5`!8!X"H=&!``V14< +M0B!I!2_]I<#@>/'`'@T/_:6`H\$T;39Y`"&`#X``O$=`(!((A"T)'R]V`":1 +M'X```#T2#N`*`!&`('IP,@A@':EP/@S@!AIP`-\WZ!`2`"",(/^/2O0#$8$@ +MC"'#CT3R`":/'X``(#MY%Q06$FG'<*``@"XT$!$``"2"+P```!`"(D($4R+5 +M`DV`E.'*(T4`RB-&`(?A`($$ABW.I<+X*8!!J<@#`@.``":$+RB!!`P'8 +M5!X8$`#>\LD/)DX3RW@&]((,8!.I<`?HR7``V9X)X!(H6O?:\-DQ!*<&H)8!"I<0HF`)!/\D6&@>+*(V$F#?*# +MXLHCH2;*(&(-P"@B`D@-8OW*(4(#`8;)"(2/````&`IP:G$`VNH-8`4Z0"2H\>(.(`!*/'`I@H/_>6`SW"``#2LMV^T +M?0`@40//<*```"!L$!``A"\)'\]Q@```/3(A3@[/<8``A#LP(4`.-^@3;A9X +MSW&``-"Q`&&QZ,8*8!/I<+;H'!$`(`(@``1A"%,`QW6``)RL`(4,Z`#8`*4` +M(($O````%.EP.@N@"@3:(/`8A0;H#@A@"^EP&NA:#R`?R7".Z,]P@``$)O`@ +MP`,`(`$@Z7`."Z`*!]H*\,]Q`0#XN\EP$-IZ#&`+`-M1`@_]`-L/"E``%0J0 +M`&AR"O!!*0(!*+DB>@;P02D"`2>Y.F)0<`'8X'_"(`X`X'CQP.'%I8#V#.`* +MJ7#/<(``'+8J@(#AXR!"`,H@0@.J#R`+J7`=`@_]SW"@```@&X`#N39YQW&` +M`)RQ#Z$`V.!_$*'@>/'`@@D/_3H,8`L(=^EP`-U&"R`0J7'3;]9^QW:``)RQ +MK:9B"2`+Z7&OIK&FP0$O_;"FX'C/<:```"!;@0>X%'C'<(``G*PG@")Z*H`& +MZ2B`66$HH`#9*J#@?N!X![@4>,=P@`"!_*J#@>/'` +M!@D/_0AWP($H=80N"1_/<(```#TR(%`.BB$$`,]PH```'2Z@]@A@"\EPG@L@ +M"\EPSW&``!RV`H$0((`#`J$1#Y`26X7)<`IQG@K@"@';'0$/_?'``('/<8`` +MT*P'N!1X$&'IN*0-XA?`>-'`X'[QP.'%!8`W:#1Y`"&-#X``G*OJ"F`*$-FI +M<((+(`L`V?4`#_T%@-4"8`H$V?'`:@@/_<6`MVZT?0`ECQ^``)RK&H?\%Q`0 +M,P@?`,]Q@`!@MB"!`-B(Z<]Q@`!@%CP'@#WH%K\EPB@Z@ +M'P'9H@B@"LEPQW6``)RL,HW)<,8/H!\%V@6/,PA1`0'8!J\`)H$?@``\M@R) +M@+@,J1J5J;@:M8X*X!3)A,*40`Z@*"Y +M.J`!V2FH"/"2VD1Y'0F``#J`@+DZH,]QH```(#N!(Z"""B`+`=GU!\_\\V5\`"*##X``!#V`HU)I,"*"#Z``M"Z4XN&8%\*H*8`M(<%4& +MS_S@>"4`(``$B>!X\<#6#<_\"'8H=18((``$B,=P@`"I+9!0;/_/'` +M9(C/$*`D/SW"````]+W6N8,X,H`K)<%IP +M[@[@'.EP)6@*(``GZ7!*Z" +MEGP.(A_*(6(`T<#@?O'`,@O/_.H2#+:(=DAUJ'(C#!X4$+D%(0P`&+H,OL5] +M&+O/<,7N@YP!V85Z1@X@'Z5[<0//_.!XH<'QP/(*S_PH=D3!:'5!HXHC!``G +M"1X"42#`@0'8PB`!``>X02Y!$61Y!7D9C8FY#;@E>(ZX`J5C\!6-!>@#:D8@ +MP``!I4$N0Q3!NP0F@A\````8),$KND2YP;D!X0`IS`!AO`0FA!\(````^(U! +M+,0$^W^&)WX0![SE?.N54R;`$`J_!">/'P<``/SE?$$N3Q/`OQ6_Y7STC1:_ +MY7SYC1>_Y7Q`+$\'Y7R3O)2\GKP;"[4`@J4$ZQ,)E0""X0.Z:KE5>CIB6&#/<8``!.X(888@_0\%(/Z`RB""#P``5`#/("(# +M_`LB_`(0(`[!`2!T8EP!"E&ARP"8'#L5,E?I"$N*8"(0`)H4`M +MP"`5>``@E`^``.S)#A0`(1,(40``%``@AB#YCX("`@`*(X`O@``LSP`3`"`* +M(8`O@``LS0'@`!L`(`/P4@A`$3Z'^PG>A4<)G@53(<("`KI!*0`#CN+#N-`A +MI069]\P2#+9DNE8D`Q1(LW0<@A/`M'4<@A/'HQ"LR\G=LT&`AB+_#82Z0:02 +MB,FC$JRC"9X%S!(/MA"/EPA!!!0#84@]O_^EQS,FD$``` +M+;B&(/\+!7T,\-(,H!:J<`AR5B?`%-8*X`_,$@&V`!0`(`L(7P3,$@&V+?#+ +M$@&VF!$``.BXP2CB`-,@8@`)]!$(G@:8$8``1+C!N`/P`-C,$@&VF!$"`.BZ +MP2KB`-,B8@`)]!$*G@:8$8(`1+K!N@/P`-J)Z`?JNA$`)@'@NAD8(+/P`8'# +M"-X`F!$"`*01#P#9$@ZVBW/)<(`@!@=6)D0<5B;,'"4/'A7HNM,BH@#3(N$` +M2&#/"/`$X`BQ!-AU&@(``=X&@8`B`P62 +M"R`.*)',$@&V5B$"!.D9@@,BD@&R.&`8LLO)SW&@```@L!`,`<`1`P!B?``D +M@Q28D@)SFF,Z@5!Z,'*J!LW_`G2&&`0#!!,`(*4:7+,!X`0;`"#M!J_\H\#Q +MP!8/(`GAQ0HE`)`'\MH/(`X9V"X)H`<9V`T'K_RI!5Y4X)HA26E0"41'2,+I0!'I0(BP``- +M")4`!H43"$4`"85(I0'@":4`A9^X`*4&A0D)!0!$A5EA`GF,(1"`:@`N`"&E +M((7/=J```$N`"E!/`*A0'@"J4,A<]R@`#8V/`A`2`&@@2``(`98=(+X!U(!XSW"@`(!%.!B`#P#`)`#@?O'`>@V/_`AW.G'/=H``G`N^%H`0 +M`-U"#Z`/J7$:<,]P@0"X+@'9+*`/A@L(7P6I<"7P_P\4E>EP*G&I2BZI!`#`$]Z*+MO +M>^+A9]S,(@ -S,(P&#!_+/<```I2CB#L_\T<#@?N!X\<#/"L5>4"A`>`/>.$(TH(5\`#8$?#/<8`` +M3"KP(0,`*=H2NL]Q@0!X*_`A`0!U>B"B`>`/>.,(TH+1P.!^X'@`V!+PSW&` +M`$PJ\"$#`"G:$KK/<8``>"KP(0$`=7H@H@'@#WCA"-*"X'[@>/'`"@RO_`*Y +M&G(/VL]VIP``*$*F@.#*(&(``=T4)0\0@;D@IN2FHZ:B":`?,M@!YT`H@""! +MN`"FY*:CIHX)H!\RV#$$C_S@>.'%*=L2NQ5[`-P(\/`A``,5(PT#`*4!Y/4, +MA)#@?\'%\<"F"Z_\F'``V@_P6&(4>'0@#@$IWQ*_8I"AD!"[97W5?Z"G`>+I +M"D2`Z0./_.!XX'[@>/'`X<4(=<]P@`!4@BN`DNG/`*C$?#/<*T``*9RH,]PK0"`L&*@SW"M``!F4J#/<*T`@'!"H$"-`-@/((`` +M1"B^!P';#B&`?P``[@(#N$*-%7@,>B]PBB+/#XOISW2B``"T2(2&(L\/17@( +MI!/PSW"M``"F6*#/<*T`@+!(H(HBQP_/<*T``&98H,]PK0"`<$B@@.'*(($/ +MH@``M`CRSW"M```F<*#/<*T`@#!@H&X-P`X"A2,(T`""#6`4!-@!A8OHSW*` +M`-`J!H($@""`9.&2".`=2'#=`H_\X'AQ`\`.P0/`#B4%P`[5`\`.\<#AQ<]Q +M@`#`/>A2I"PI1`0#8%*F`X\H@*0"P"^D.RB$)`-'`X'[QP.'%SW6! +M``PL((7/<($`I"LYH`#;SW"``!@K8*#/`'HL]P@`!`P:(0 +MA`"C$(4`H!`&`0'8087Z"6`?8H7/<(``""M@@`7K`(4AA6![0H6-`8_\X'CA +MQ<]SI```2,]TI```1"F$SW"``"14(*`!A,]Q@``85`"A((3/$5Y`-I)I`&D(*2H&T"#X'_!Q?'`J@B/_#IP2B(` +M($IU/O`*((`O@`!D,T`@`"&O8,]P@``,5""`'P]C$`#8SW&```0K(($")T(0 +M`!`!(#!RRB!N`,]V@0"D*Q4E0A1Z<%1^$(X3Z`'8<@NO_`#9SW.!``PL08-B +M@T1X9'D%('Z`"?01C@\/`Q``$``@$*[QKDPC`*#*(F(@`>6)#121;PH0(`#= +M,_`*(H`O@`!D,T`B`"&N8,]P@``,5`"`30X#$!4E4!0!V`#9$@NO_`IRSW>! +M``PL88>"AP1[)'P%(SZ#SW*!`*0K%"("!`3RD8H-#@,3`!(,()"JT:J!AT*' +MA7A%>0&G(J'%X<8`VX'@--C*(J$#RB"B`\HBP@#/=*```"#;A`[P +MSW2``!#"\"2,$`(F#1,%[+%QP"-F``'BZ0H$@&APP<;@?\'%\<#F#D_\"B"` +M+P``#R<*(H`OH```(&P2`"``W7IP.G`)\&P2$2#/<8``+"``@0'@`*$"(<`D +M@0B%#P$`L*T`W@WPSW"!`(@W\""/`WX)(`#I<.X-[__I<`'FSW"``""\`(#C +M#@20;!(`(,]Q@``4*P(@0`02<,H@!2"Q<$"!SW&``##`\"&!`,HE#1"7"06` +MSW.!`!@L((,!X2"CSW&``"C`\"&!`'\)!8`"V<]P@0`,+""@SW&!`*0K6!D` +M!,]P@``L($"`MZ'/<(``%"M8H2"`SW"``+A1\"!``!4*!0#/<8$`#"P`@0D( +MD``!V`"A409/_/'`SW"``(0H((#/<(``#%0@H,]P@0`,+%X*8`$,V<]P@0"D +M*U(*8`%HV='`X'[@>,]P@``D5`"`SW&D``!$":'/<(``&%0`@,]RI```2`&A +MSW"``!14`(``H<]P@``@5`"`J!H`@.!^\<":#4_\SW*``$#!CQ*!`!4B0``W +MB`#="NE^#F_\D!*``(#A&-[`+B$6!/(`WIR^`-\4\!)O%'C'<(``$,+4$`$! +MT!```,MX!_)*""`4+WB`X,`E81`!Y\]P@``0R1B(U0\$D*$%;_RI<.!X\<`R +M#6_\"''/=:```"#;A<]P@`!T#?`@0`#/!$(5`K/<8$`&"P$@0'@!*'/ +M.!^X'CQP(8,0!%R#$`17@Q`$='`X'[@ +M>,]P``#E#FT&K_SB$@&VX'CQP&H,3_P>"B``"'8*)0"0*O(:[A$.4!""YK0/ +M(0'*(6$`(?`*#R`!`=@&A8'@RB!"`YP/(@'*(6(`SW"``(RK((@-\.H.(`$` +MV`:%@.#*($(#?`\B`D"@ +MX'[/<:````0%@02A`]@5H>!^\<#."T_\*'96(0\$)H<$(;Z/`0``P*'!,/0& +MAT#``=H5"!X"02C"`,&Z`>(QN,&X&F(.\!D(G@8@P@0@@`\"````1+K!N@'B +M,;@8>B$*4``3"I``@^(`V,H@X0'`**$#"O#/<($`B#8"@`;PSW"!`(@V`8`% +M>2:G#Y0A`0KO8,8`\`V1&GYAJ8M!&.V!I8 +MM,*XSW&``+#Q"6'/`FG`)8X8#6*.&`=MP(- +M[_W)<`2%&K?>"&`"R7`]EVB7`^$$(8$/``#\_U".<'',(@&$"O(0NQ"Z,-B, +MN&5YM@RO_`4B`@0=EPBW"8>&(/6/_`EB&LH@@@,0'<`4#_`0'<`4I`8H<4";_RAP`QQ$2$`@,H@@0\``/\`#O+/<:````0/ +MH0.!++C$N,]Q@`#4U?`A``#@?N!X\<`F"```C"##C\H@(0`*\A8(``#/<44` +ME"P#N!5X.P.!^\<#AQ<]P@`",JZ"(_]@0= +M$TAP$/""X\H@@@\```9"E`NB_,HAP@`(V`3P`=@`H0#8`0)/_/'`X<5(=80H +M"0\`(8)_@``@.WF"!NMZ"D`0$(1`"X8")XP0%/_.!XA"@)#P`A@'^``+0[X'[@>/'`(@E/_`AV&G)#:"AP +M2'$R#J`;#=JCC@#8(88Z<`6F&*[BA@P6$A`'[0D-4A`%Z0T-DA"$[P,>0A0S +M\('E`=K"(H$``=A4>`L/91`%IB*F*'="<0(A``0_N%(@`(`&\A`>@!2XKAWP +M`B!`(+X);_SI<0'@"PAD`__9&0U!$`(E`A`P=/'`6@A/_"AV2'<:!X`-D^H(@80@`C&$(`+:`_&$(`-*!; +M&$(`.Z#@?X080`#QP.'%"'7/<($`9$90@%8@0P+/<8``?%1\8H"A>F(ABHGI +M`H#PN,H@@0\``.D<]`B!_'X,0`V"#F`2J7!E!P_\\<#AQ<]P@`!8%0"`#.C+ +M$@*V`-B6N,]QH/Z(#&H+8!&@$@(`*@[`&\]PH```'`6`)PC>`P'8SW*@```( +M!J+@>.!X`-DFHJ8+@!W/<8``+-`!@0'@`:'+R:`0`0`]"1X$BB$(`(8,(`*D +M&ERPZLG)"!X`RQ(#ML]PQ>Z$-KR35!,,`0'9YA("MA"]H!,#`)X)H!X%)$03 +M4/`G"1X%V,G/`=`"P`$(H@$`#+ +M$@&VTAH8L*`1```?"!X'\@K`#L]Q@`"LSA&!%7D2@0'@$J'+$@&VH!$```\( +MG@>ES8FXI1HH!(" +M`,]SH```15R#SW#%[@)">(/^"*`>`-D#V<]PH```!"B@)08/_.!X\"T`= +MA@V@!0#8_]G/<(``!/\GH-'`X'XQ`"`4`MC@>/'`*@T/_,]PH```(+N`E@X@ +M!0S8Z@F@!:EP"B8`D,H@@0\``$/Q +M"Q2$`-O/<8$`V#\6(4(#8*IAJ@'8`JH#V`.J:'(&\#ABMGADJ`'B^0H4@:D$ +M#_P&Z,]P10"4+*#9!/`H<"39E0```>'%A"@)#\]Q@``H/3`A00Z!_P<7@?P#8\<"R"P_\JL$(=QIQ.G+:`/>,]Q@`"HT\EA(0D"`(0N"Q0R +M:#9YSW*!`(H@)W$R8K!YWPI!@`/P_]C]`@_\X'CQP`X*(!`(<@AQ`-@"\`'@ +M&PA%`(0J"P1R:'9[SW2!`'P@)W-C9.L+7H'1P.!^X'@`VD:@1:#_V2.@,*@@ +M&$(`1+"*(?\/(AB$#P``___@?R&@X'CQP.'%"'7/<:````1/@<]P@`#HNT"@ +M!M@/H225`866"2`"0KD,H#@RB-J`,H@BP!S?#-Z@.'* +M(PL#RB&+`#QY.&!"N&QXX'\O<.!XBB/_#Q-Z@.#*(VH`RB"+`'-\,WJ`X,F(7@W@'JEP +MSW>``/3I"&`>R7`(9X?@RB!"`Q'T`=@/ +M\"H-X![)<`YG(@W@'JEP"&<0=@'8P'@#\`#8U0`/_.!X!+C'<(``U.M@@8"` +M8*0BD6&`(*,@@F*`(*,C@`*2`*'@?N!X\<`R"`_\.G!5"%$``-TA\--MU7[' +M=D4`E"SAA@@6$!"%+P$9+W`6"2_\"G$R;35Y0G&?N`&AXJ$$A@P9``0$H<]P +MH```(!N``>4%H:]]"B*`+T4`M"N]#1*1)_!+"9$@`-T=\$`M$!$`((`O10#T +M(.&`PH"%+P$9+W#"""_\R7$`(@$DG[@5H?:ASW"@```@&X#7H1BA`>6O?0HB +M@"]%`+0KQ0W2D,]Q10"T*^4'[_L`&4`$`-D)\/_:%B!#`$6C`-I&HP'A]0G4 +M@.!^SW*``!0)`8*BN$4@@00AHL]PH`"`'RN@X'[@>$`H`@+/<:```"`6&9B` +MJ!D8@`D```#@>,]QH`"`'BF!"WD!V.!_PB`!`.!X@.`!V,H@(0#=`L`6.04` +M%O'`X<4(=0#80@H@`*EQW@F@$Z]X@0?O^P#8X'CQP/X.S_L(=L]U@`"`-P"- +M2PB0`;H)H!//>`\(4`"Z#^__`=@$\/H*(```V`#83@H@`,EQ`=^N#^__Z7`" +MV+X*(`#)<68((```V%8,(```V`;8`*WAK>EP`O``V`T'S_OAQ0#9SW*``(`W +M`""##X``P#>H#N'_RB`A``'?K@[O_P#8Z7"^"2``"G%F#^__Z7!6 +M"R``Z7#I<*"N#0;O^Z&NX'CQP`AQS@@@``#8`-C1P.!^\<"2#<_["'?/=H`` +M@#<`CDL(T`!."*`3Z7`/"%``3@[O_P'8!/"."2```-@`V.(((`#I<0'=J7!6 +M"2``Z7$"#^__`-CN"B```-@N#N__`-@#V`"NH:ZI<`+P`-BA!<_["',($+`D?SW&``"@[,"%!#H;AT"(!`Q`C`P/QZX#BX'_*(((``-O/ +M<8``E#?P(0$`#O`O*$$`3B""!\]P@`"L-TA@$'/*(P4`$"&!`//IX']H<.!X +M\<#6#,_["'8O?3H.8!.I<(0M`1,`(8!_10`\+3T0@0!$*3X')W`1[L]R@`!< +M$B***J@CBBNH"@R@$ZEP`-G/<(``<+<@H`$%S_O@>/'`A@S/^PAV*'H- +M8!.I<$S9+'W/<$4`/"W/2T0C@,"!!#L]P@`!<$B"@`=G/<(``<+<@H`F,#0@R`RJL"PC2`XP@0HD#]`38 +M`O``V`NLI@X@%LEPV@[@#03/^^!X\<`*#,_["'8O>('@`=W^#F`3PB5! +M$PARR7#B"J`6J7%9!,_[X'[@>/'`X<4(=0'8!@_O_ZEQH@Y@$ZEP103O^P#8 +MX'CQP,(+S_L(=\]U@`"`-P"-20C0`7X.8!/I<('@`=[)<`3R>@S/_P3PN@_/ +M_P'8$@_O_^EQ<@SO_P'8`MB"#^__Z7$N#>__`-@:"2```-@'V`"MP:T!V`/P +M`-C5`\_[X'CQP&8+S_MJ""``"'4(Z*]^&@R@$\EPN@]@$\EP#@@@`*EPM0// +M^^!X\<#/__"'8:<,]W@`"` +M-T`G`!7P((`#I(=5:`5Z0"B!`D5YG[EF#>`))'TDZ%,EOI,+]!"'$P@%(/H. +M[__/>`AW!]@5\%,E?I(+]`V'$P@%(*8+[__)<`AW!M@)\%,E/I$*]/X,[__/ +M>`AW`]C)<0#:"O!N#.__R7`(=P#8R7%3)0(1?@B`'LT"[_OI<.!XX'[@>/'` +MX<4(=0.`@>`!V&X((!;`>`2%0B`-@,HE8A"&""`6J7#`3N@\@!JEQK0+/ +M^RF`)0E1`,]QH```,#`9@`\`@```"H!`*($$)7C/<:(``(`"H>!^X'@"@(#@ +M`=@!`B`6P'C@?N!X\<#V"<_["'9(=P#=[@Q@$ZEP"'(!AM8(H!8!V0&&"0B1 +M`*"O/0+/^^!^X'CQP"6`,PE1``:`"NC/<```!4*V"R_\BB%$`!WP`=@J#>__ +M`-EN"J`3`-@.#F`3`-@!V`#9#?``V`X-[_\(<58*H!,`V/(-8!,`V`#8"'&N +M#,__T<#@?N!X*(#/<*(`L&S/`P``"/`@@&1Y!2&!#\X"```@H.!^\<#AQ22`B.DC@`T)4``%@!<(40`` +MV,]UH```$`FE"@E`%@'8":6-`<_[X'BBP?'`!@GO^YAQ`-O/07#(,3%B(/ +M`P`7!1`AA^<(08&`<2&G+0R"$Q,,$Q1`)D,``!_``)9Z"?!V>L]T@``@VR&" +M8(1Y82"D`*($&@`!#-S[`,_[X'CQP(((S_L(=@6`BB4)'ZQXSW"``"`]0"`/ +M`D`@$`,G<"*`'0E1`"&`SW*@```@6X(R>3IB(X`!XEEA(Z#J"0`118:L>C`@ +M02YF"2`1`=@2"Z`3$-@%AH0H`@H`(8!_@`",2OX-X!P"=W>0#O +M^R"GX'CQP`X(S_NJ"2`1"'=%AXHF"1_,>L]U@``@/3`E01X:"2`1`-C""J`3 +M$-@%APCEA"@""@`A@'^``(Q*K@W@'#C@!8<(V/'`SW*` +M`/`W`8)-"!$!SW"@```=-!B`#P"````X&(`/`(```,]Q@`"<"P^!"P@?!,`1 +M@``0Z!V!C""#CLSW-'`M%`-'`X'[QP,]R@`#P +M-R&"$0D1`5T2`0:`X2P)0@#1P.!^X<7AQL]U@``(.<]T@`!$*`#9BB"_#2AS +M#/!Z9""JA^A^9,]R@`!D5,"B`>,!X`UX$0L5"3,E0A#C"@.``>'\\<'&X'_! +MQ>!XSW&``/`X,X'AN>$@P@?*(&(`C""_C^$@RP?*(*L`F.#A(,D'RB#I`T`@ +MP('`(&0`''C@?L]R@`#P-Y&"C"3#GQ#R%H(.Z,]S@``(.<]Q@``?.(EA,R,` +M`#,C00`B>`/P`-C@?V`:`@#QP)H.C_O/-`0HG@`^``/`X0"<`!C,@30//=H``\#F=9<]W@``P.+&W +M(A=($>`6S9`/"$(33!<-`!<-WA`$W:&B(A^$'P``_P^CA@7P`MVAHHHE_Q^D +MIK&"C"7#GQ'R,B1-`S(D00`S($T#,R!```)]I*L/#1`%`N6DJP/P`-@$JW`: +M@`&!JS$&C_OQP.'%O@]@&A#8`M@`W0X*H!JI<<]P@`!P.*&@SW"@```=.!B` +M#P`"``!.#P``$0:/^^!XSW"``/`W`X`/")$``-@#\`/@`0@4`^!^X'[@>`#8 +M`_`#X`$(E`<`V`+P`>#_")2`X'[@>/'`SW$```__I@B@&@+8SW$```__G@F@ +M&@+8`=G/<(``<#@AH,]PH```'308@`\``@``T<#@?N!XX'[@>.!^X'CQP.'% +M"'6?X,H@A@\``(@S_`[&^\]P@`#P-[:@`X`3")$`+@[/_UX.S_^Z"T``:06/ +M^^!X\<#AQ:7!`-D*\,]P@`!,.35X`!B`#P``__\!X>\)E(#/=8$`K"U`Q<]P +M@0#4+4'`SW"``"`Z0L#/<(``)#I#P`'81,`2V`/9!MH`VPHD@`^``$@Z"B6` +M#X``*#I*)H`"P@U@#OASSW$``#"3#@B@#JEP\02O^Z7`,A("-LO)_]D``H14( +MD0(`V`"A9]@'N*(-[_NI<0+8\@Y@&JEQ$/``V`"A`MCB#F`:J7'@O;P(`@#A +MO9`(`@#BO9P(`@#Q`X_[\$`&&@.`\#<+_ +M70.O^Z*FX'CQP`+8_@Q@&@'9R@W/_]'`X'[@>/'``MCJ#&`:"'&Z#<__T<#@ +M?N!X\<`"V-8,8!H`V:H-[__$N-'`X'Z,(1>'\DX9F``!X(#CQ!D` +M`"P*(0#*("$`T<#@?@#:%O!$*CX'`-G/!^X'CQP#8*C_O/=8``\#&!#$%@`0@.$!X,0>`!"`"2$`RB!A +M`,]PH```(#N`1866(4@#SW"```0ZU@^@'$6@&0*/^^!X\<#AQ<]U@`!P.""% +MX;G*(($/``"',X0+P?L`V`"E`841Z`/8`=F^"V`:`-H#V&8-8!H"V<]PH``` +M'3@8@`^`````V0&/^^!X\<#AQ<]U@`#P-SZ%X;G*(($/``"$,SP+P?L>A48@ +MP@"$%0`07J45Z`/8<@M@&@#9`]@:#6`:`=G/<*```!TX&(`/``@``#@8@`\` +M!```A0&/^^!X\<#AQ<]Q@`#P-X01```:Z`.!,0B1`#&!C"'#CQ+RSW"``!\X +M+6`#V#39'@M@&JER`]@`V<(,8!J.N6()(!ZI<#T!C_OQP.'%SW6``/`WA!4` +M$!7H!-A."N`9`-D#V`+90"4"%A8+8!HH``/`WX;G*(((/ +M``"&,R`*POL"VD"E`^X#VD"E`845Z`/85@I@&@'9`]C^"V`:`MG/<*```!TT +M&(`/@````,EPL@@@'DX7`199`(_[X'CQP.(/3_O/=X``\#<^APAU4R%"`('@ +M`=C`>(&X!R(^@,H@@0\``(,SP`GA^\HB00,>AP#91B##`$\C0@!>IPH@@"^@ +M```@SW:@```=FKD'[44CP@`MIEZG`O`NIH07`!`-Z`/8Q@E@&@#9`]AN"V`: +M`=DT'H`?``@``&P0`"#-!V_[9!\8$.!X`=C/,]P@`#P-V80@P#/<8``\#A1@!.!4'/0(&$`SR!B`.!_$Z'@ +M>,]S@`#P.!.#SW*``/`W(X*BN!.C&0F1`)2"*((-#$00E8(I@@D)!0."N!.C +MX'[@>/'`9@G/__(+S_\V#L__SW"``/`W`X`/")$`Z@W/_Z(-S__1P.!^X'CQ +MP)H.3_L(=G8*(``H=<]P@`#P.!Z`'PB!#P``___/<8```?HSW&@```?`(&`N`"AX'[QP.'%`-T-\`H@0(/*(&(`$WC! +MN`/@E@C@$`#9`>7M#920J09/^^!X@.#QP`@(`@#1P.!^\<#AQ<]U@`#P.!V% +M@N"X#,'_`-B!!F_[':7@>.!^X'@H<@]YSW"!`*PM]0<`#N!X\<#AQ0"!`-H/ +M(@(`SW6``/`X%(5AN!2E`('/<0``__]5)<,5"0C1`SZE!/`5>R"C&852>21X +M&:4:A21X6@SO_QJE_]@A!F_[%:7@>/'``($`VP\C`P`#@4,(40#/``8@`\``/__&8)R>21X&:(:@@0@0(`:H@'8-8+"(`$` +M"PA%`'(-[_\5HM'`X'[@>/'``($`VP\C`P`#@4,(40#/``8@`\``/__&8)R>21X&:(:@@0@0(`:H@'8-8+"(`$`"PA%`!X- +M[_\5HM'`X'[@>/'`^@QO^P#;`('/*"@@H$:@H'DQ2#!`,8@P@`:HAF"97@9HAN"97@;H@*!S@SO_Q6B(05/^^!X +M\<"J#&_[`-L`@<]R@`#P.`\C`P`4@@'@%**`@54BP`6A@95XH*""@1J"@>3% +M(,$`QB#"`!JB&8)E>!FB&X)E>!NB=8("@0T+!0!Z#.__%:+)!$_[\<#AQ<]U +M@`#P.!V%SW&``/`W".AW$0`&`>!W&1@`"_`4A8#@`=@&]$8,[_\`V`+8':6= +M!$_[X'CQP.'%SW"@```@.X#/=8``<#F6(/'`X<4(<8(A@@7/=8``\#?/<(``W`T&"J`<8!U8$`'8201O^U\=&!#Q +MP.'%SW6``'`Y`84(Z,]P@`#X#8H)@!P`V`&E)01/^_'`X<7/=8``\#@?A0CH +MSW"``-P-:@F`'`#8'Z4%!$_[\<#/<8``\#@4@56!8;@4H1F!>!F`#P``__^O +MN!FA&H%0(,"#&J$!V,(@`0`+"(4`<@OO_Q6AT<#@?N!XSW*``/`X%((!X!2B +M`8$>HF*!&H*!X\\@X0/0(.(#&J(9@H^X&:("@3T#[_\5HN!X\<#/0J"'PD%``C8`*(*"R`5`MC/<*```!TT&(`/``$```[P@.,`V,H@ +M8@#N"@`5SW"@```=.!B`#P`!``#Q`D_[1""^@13RSW&@``!%.($A"=X#SW&` +M`'`Y#0A>``J!`>#@?PJA"8$!X.!_":'@?N!X\P'GY:8+"5$`)H8!X2:F.X*(Z2*$`>$B +MI`3K(X0!X2.D3PW>$R<(D0`'A`'@!Z0%ZPF$`>`)I!N"F^@+A`'@"Z07ZPV$ +M`>`-I!/P)P@1`0:$`>`&I`3K"(0!X`BD&X*)Z`J$`>`*I`7K#(0!X`RD&0)/ +M^^!X\<"B"6_[`-L*)T"0"B"`+X``\#<"N!1XSW:``'`X'69FI0KT!(4!X`2E +M">H%A0'@!:4%\&2E`^IEI0`0`"`M"!$"(@VO_P'83A`!)H8A?XX&I0SR"P]1 +M$#.&`>$SI@T(40`5A@'@%::A`4_[\<#AQ<]U@`#P-V(50!$AA0.X0B%"@`YX +MRB)B`(8/8`<`V8*%(84U"0`#`-J$<]P@`!(%0"`(H:`X,H@@0\``-@`J`N!#C$- +M7A'/<(``2!4`@"&&@.#*(($/``#4`(P+@0X`V,]Q@``4#@*A`=@%H0&&!J$/ +M#9X1`=G/<(``%`XDH*D`3_O@>,]PH```(%N`SW&``!0.!X$S")4`SW"``'`Z +M`(`A@3A@`GJ`XB``*0#*(*D`SW*````/!H($@""`@"$/"AT&8!Q(<.!^\<#A +MQ<]Q@``4#J>!!-JQ<,HECA`,"`T`30!O^ZEPX'CQP,X/#_L(=<]P@``4#B,- +MM1"GH,]R@```#P""B>@&@@2`(("`(0\*S@U@'$AP$FT4>``@C@^``#P.J7#& +M#>`=(8;/<(``2!4`@"&&@.#*(($/``#4`*@*@0[E!P_[X'CQP/(2`;;TR25X +M]Q(!M@MY`=@%\EH*`!,#\"H*`!/1P.!^X'CQP#8/#_L(=CIQ&G*$*`D/`"&- +M?X``(#T0%1(0%!43$'(-8!SRA<]PH```(#N``-KB>0`A@80!(L($R7`+"%$@ +M$@E`&P/PQ@E`&P#85!T"$$$'+_M0'4`440-`#_'`[@X/^RAUA"D)#P`A@'^` +M`"`[PH!O$``&,@Y@'1_9!MB.#R`/J7&`X,H@@@\``'PPM`BB^\HA0@.'YG`+ +MH0G*($$#$@]@$:EP@.`L#N(0RB!"`PD'#_N$*0D/SW"``-P\,"!`#N4%8!T? +MV?'`X<4H=>8.8!$H<(#@``[B$,H@0@/E!@_[X'B*(O\/`-P#\`'D&PP5$3)L +M-'G'<8``1!MJ@?$+#H`)@0+P2'#@?N!X`-D/"!\`+RH!`$XB@0<`VL]S@0#0 +M-A4C3``0($``0*0EHP?H+R@!`$X@@@<"\"AR1J,`V`CP#PD```':%2,,`$"D +M`>#S"%2!X'[@>/'`Y@T/^PAW`-VTJ,"`M:@!AL]R@``'RC"($VD5>`ABC"## +MCZ'!1?+/<($`V$0V>$"(SW"``""_1"H^#2"`0"$1`0H@0"Z+<:H+[_[)<"WH +M"-@4K\]R@`!D,0"22'$!X"\F"/``L@OT89(!XR\FR/!AL@7T8I(!XV*R`K<@ +MV*:O!Z\!D02W`I$%MP&&"MDQJ"&&`"$`)!3A:@J@&A#:(X8`D8ZX`+$`P`/H +M`8:QJ)T%+_NAP/'`-@T/^QIPSW!%`&`C`("+")X`SW5%`/0@,!6`$'\('@#/ +M=Z```"#;A]8(P!*!X,H@(0`+\H;@RB!A``?RB^`"V,H@@@\``/\`C"##CR?R +M!+@=91<($"`!V/P?`!`('X`?"````,.E&?`CA1?I#!^`'P@````-#D00`B9` +M$`?P#B&`#______88"*%.&`"I?@7`1`!A3A@`:4%!0_[X'CQP)H,#_L(=L]P +M@`",JP"(E0C0`,]UH```(/N%'>DEAA#I#0]$$`(G0!`'\`XA@`______^&`D +MACA@!*8`V`6FXZ8('8`?"````,]P`0"@ACH,P``H\,]P@`"`,]P@``HX3X( +M``#/<8``-*L9B0'@&:G1P.!^\` +M^?,"\`#;:'#@?\'%X'CAQ4`I#`(E?$`L`Q2%>R<*-`((=`3P`1Q2$&&Z4R1^ +MD/OU02J-`,&Z@"7_GP0!_P<7@>/'`U@H/^P;= +MSW2@```$;X3/"2_[#=JEP0`<@#\````@SW5$`'B[`I5APH8@ +M?PP<>$`H@0,!P,]W@`"4VR5X0<"$P-(*(`XBC8'`R@H@#B*-`HW/=H$`X#-B +MP(MRZ7#)<;X(H!A`)0,6!84CA0"V`8:#N`&F`8`X\H@@0\` +M`/\`X'\"H?'`"@D/^SIP*'7P'(BPBB<")`0H_@7/<8``O$<;<2]P`"$2`(0I +M"2\*)4`N`"&4?X``(#MP%!,@`!06($`K@2(P(``P0<&`X`#9RB%!,`;RY@A` +M!`@0&0!/#1`1>!0/('`4#B#Q=LH@:0;`*&D"RB&)`\0*:?O*(LD#%^X`V07P +MPG\!X2]Y_0^#DP`E@"^``"`\4R5^D"6H`=D&],]Q@``T+2"!)*C/<*```"!L +M$!``*6T+"10"`-DG\#,F07"``"CC0">``0H_@56"&`$,"!`/B79PH`*<'H-(`X_V@JXV6`'\,]P@``T+2&`"-T* +MZ"D,HA8@"D"F(=RB)"`P+!`B8#%"IP1@I@'`/" +MB@P@!`#``,"`X,P)(03*("$#50?O^J3`\<`V#\_ZA"@)#P`AC7^``"`[>@Z@ +M$(`5#A`-A8RX#:5.#B`=R7"!!\_ZX'CQP.'%0@AO^PAU`-H3;15X`""!#X`` +M^LEI!^_Z0+'@>/'`U@[/^BAV2'4:<]R@`"\1UEA0"$1 +M"(0H"0\`(9-_@``@.P`3`"`DV0#?:@E@`^ER0"H"(0`A@2#HH!Q(L&AUA"@) +M#R]P`"".#X``(#S@A@`@E@^``"`[`-N`XLPE(9#*(V$``-F"[8/J`=D:<4HC +M`"`*)X`O@``\W@`?P"0`()4/@`"@.P#`;!T`(#;K!(9P%@(@@.#*(<$$RB#! +M!`7R`M@`'P`@"'%LC@7KA+F$N``?`"`*NFP5#"``PX)[`O!">_\*Q(!B>@DC +M@@",(A"`QO>#N8.X`!\`("6F$![`%(;I-@\@!$IP!.@!V`/P`-B`X`';P'L+ +M[RM*<*H-(`"I<3#PZ"=@'92@A@ +M'03"5239-"MP;@GO_Q#9`!8`()?%5\`*V%O`!-A:P`#`\@F@$%G`6,"*($0! +M7,!`)!$[J7#F#&`;*G&*()4`7,"/P$7`J7#2#&`;!<$,C@;H2G`Z#R`2/!4! +M(`6&%![`%$;`__!-I*(``P"N@&P("X +M1L``%P`@@+@`'P`@!L"`X.'R*G"I<3X*8!H$V@?!0"!8,`4H?C!!*8UPG\,J +M<*EQ`-H&"6`;521$.`CH_.5&]Q_`HGC9"-2`"!X"%IW#*G``V2ARX@A@&U4D +M1#B`X(WR'P@'B7L(#\%[%J7)+ +M#P44!L"&('^)S"!AL`/R&G<;\)[#*G"I<0':E@A@&U4D1#@>P4@5`R`!X2*[ +M`B7"$`/HOPI$`$`5$"``%P`@7L*?N``?`"!"?0*]`B$J<`#:'@A@&U4D1#@^Z``@`26`%`,P(KEQ"T4`A!0!,$$L@B`- +M"8$``>&$'$`P02M/`4$I30'$NP#:#R+"`!4AS#-ANF"$4GHA#T$3Q+D`W0\E +M31`I;:5Y1'EE>2"D%?!>Q:ERC_%E>D"DA!0!,`#;Q+D/(T,`*6LE>Q4A03-` +M@65Z0*$#\`#8<0@1@*CQ",`'Q0)P`GT&P(8@?XG,(&&P$?14%0`@&P@!!%@5 +M`"`3#0$0`!<`()ZX`!\`(`#8*_!`*@`A%G@`((\/@`"\1R#G!(<&Z)H.(`0` +MV1`?P!0;#5(02G``P?_:"G."#2``F'4$IP'8"JX*\#P5`2"`X?`,(A+*((($ +M"A["%%0=`"18'4`C`=A)P`P>PA0-'L(4`-L)\!)K@W`S@$^``>-%>2^@]0L4 +M@0#?J(Y5)%DW!<#I<>ER*W/>#B`;5B3$,\\($`!P%A<@=!08,`4O?B-!*9!P +MNP@%-)IW@.#*(<$C)_)X%!$P(PD%)$`A02`%P`#:*W.B#B`;5B3$,P7H'<$O +M"$0@*G<6\`'E!2]^(T$ID'",(,&OSO=$C@'9764%+WXC02F0<$(@3R`#\`'9 +M*G>:<:D,$*`")P`6`>`"N$K`0"B8,$`J`"$6(!$`2G``P4H@0"`*<@MSB@P@ +M`"@4!#``(8$O@`#<1P"A`><`P`R_'V<*P5P=P"-@'4`@9!T`)@P>`A0+'@(4 +MJ*X*=P#!2G!Z"B```-H)P(#@S"0B`"X)L>`B"<'L(D`B`!X',:`@`(%0`@GAX"(*(. +MX!%*<,8)X!!*<`AQ2G!*#.`1`-J"#>`#`<`!P(#@9`OA`\H@(0/JR0L>PA0; +M"!X$`L`!V7N``\`">\]PQ>Z#=_H+(!T$PLT`[_J`)`(RX'CQP(0H"0_/<8`` +M)CPR(4$.C"$"@`?R)@F`!(P@PX\!V`+T`-C1P.!^\``+Q'7@@@!#`G0!X*O0@0$0!J"N`-R7",(/^/ +M#WX=\MH)X`W)(H`"(4`@+R`)``/PHG@!#000`GT) +M($`#0"J2(E)P`=B"]P#860#/^O'`[@^/^EIQA"@)#P`AC7^``"`[0!4!%@'> +M@0F1`/`5$Q"$*`(*"B!`+O1H]G\*(8`O@`"@1T`A`"?.#^`#X&`*)(`O@`#@ +M2A,*$"",(P&I!/3N"``$`^@"WE4AP"7@8!SHI@_``PAW(@Y@!,EQC",!J13T +M9H6$">9X-X!L`)``D`-BM!Z_Z0!T8 +M$.!X\<#AQ80H"0_/<8``W#LP(4$.SW*!`*Q&#ND]8FX*X!H&Y0AQSW.``#S> +M"-BI +M#L`<%O`O*$$#3B".!Q-N%7C'<(``[,DHD!$)7@`'D`T(4@#B#Z__SW@0)8T3 +M[.U-!X_ZX'CQP*H.C_I:<"AV"B"`L`#:A"@)#\]S@`"0.S`C4PX`(8-_@``@ +M/`B++W$[<`4H_@0*(4`NQW&``*`[\(%D$14`F(%<$10`LH$+$Y<``"16%0WR +M9@(F#A41#E,0*'<`V+IPFG`-\`(B@@4"(A4!#0_!%$`D`@(` +M)94@*'>H=DIPR7'I<@MS4@ZO_THD``!*<`IQ*G(+ +M`=G1=P"`PB%!`'(/X`(AX0#!"KDB<2*@IJ`+#X$3%!@`!<"`%0]1$,]P@``J +M/#(@@`0$Z$`E$R;/<*```"`;@`J]`B!2!*8/H!H*<`#!`B"`!`JY.&!$P`<< +MPC-"Q4`L@"*,)\.?RB!"`T/`0"3`,6IQ8@D@&@W:R7"!!*_ZI<#QP#X,C_JA +MP0AV*'1(=80L&P#)<0`A@']%`$`'E@H@`(ERV68T>;1YSW*``-#O,F)`(`$" +MSW.``#Q7(*,`W!3PX(E$N"&)#+\$N>5YP[@E>$#`7V0IV1*Y`,#U>0"A`>0@ +M@Y!\P.0"B4[VV0P>D..)$+@(OP5_!(D%X>5XT[A`P""CZ?$9#!\00(E$N"&) +M#+H$N45YP[@E>$#`#/!#B1"X"+I%>$2)!>%%>-.X0,`@H\]P@`#<[_0@@`,I +MVKA@$KH`P15Z(*+E`Z_ZH<#QP*8)(!+AQ1CH`-T%\*X)8`"O>`'E^PV4D,H. +M`!*!X`'8L@J@!`:J;4#C_KQP!X+P`4(Z&H,(`P# +MV,(-8`4#V-'`X'[AQ<]R@`!<5@2"SW&G``!]!NAE@@:"$+ME>`JA#(+/MS@@0EC1__ +M__^`"+ME?72"".MU@@0EC1^`____$+ME?7:"">L$)8,?_X#__[>"&+UE?:NA +M>((&ZT8DPQ^9@F5\>H()ZWN"!"2,'___/_`&NV5\C*%\@@GK78($((`/P/__ +M_Q"Z17@.H>!_P<7QP&H*C_H`W:ET&/`5($,#P(.:82R^P*K`@P+E)+[!JL"# +MX8,$OC"_Y7["JL&#!>0HOL.J88-DJHPD`IFH]YD"C_K@>/'`X<4!W0X+8!6I +M<,]PI0``.**@C0*/^O'`$@J/^@AUSW2G``"`'A0"EL]SIP``?0F#)X-H@U,B +MC@+1I00B@@\?``#X*[I2I2`4`I85I5.E-*5VI02XS@JO^A9X)[@]`J_Z!Z7Q +MP,()C_H(=2AW?@T@$DAV@@P@$JEPA"T;$('@`=O`>P`A@']%`$`'Z7$.""`` +MR7+]`8_ZA"K""H#A+W+`(*$!P"""#P``L@+@?UA@X'[@>/'`<@FO^@W8#@L@ +M'0#9SW"``,14SW6``(PS0(4PD`>*SW2``##P+'A"*<-R`XIP>R2*)+@DN?0D +M01":"V`&1HK/<8``V%7(V,X+(!D@@0H.P!O/<*```$48@"<(WP//<(``W%;Z +M#6`&`8!((`$``(4AJ`"%(8C/<(``,"`IH,]W@``P(`2'1@[@$`.X"'8^#N`0 +M!X<;>!-X%""!`PF'.&`(IR"%"@M@!@*I#MAJ"B`=((4M`8_ZX'CQP*((C_I: +M<7IRBB$/"H#@RB!!(,H@`B``WP/=SW:``-Q6H*8+V#H*(!WI<0HE@"^``'@+ +M"!41(`N&'!W`(X#@`=L8GL![(8:B"6_\2H:I<"(/(``&V:EP!@H@'>EQ"B2` +M+X``V%4HV/8*(!D`%`$@*-CN"B`9`!0!(`38X@D@'>EQ"!U`)$HA0"`J<1P= +M0"0F"Z`,R7`"#L__"G#""B`9`!0!(.EPZ7$&#._]Z7(J<.EQ_@OO_>ERJ7!> +M":`,9-G/=:<``(`"'=B3G@Z@%#IP3Q40EE`5%)8$)(TO````_@X-8`8IO1R6 +M3"$`H`'@'+:&\L]W@``P(*2G4R0`(@:G!""`+X#_```WN`.G!""`+W\``,`N +MN`6G`^W!Y.#@``J7`6#>__ +M2G%J#>__Z7"F#$`&(88:<&IPI@WO_T.&"'48GD@@``#Z"B`2`:T`K0-M`MF2 +M"Z_Z,-R$*`$L(88`(8)_@`#D'(QY0"(!!C`A00[/3`@0`[#N?0C`P`$;5(+K_HO(,<@4R/!`%(+K_HHXL]P@`!4@AZ80"4! +M$@6M`8:,>#0B0`[/=H``C#,&K0>'!ZU*<*"FZ@O@&:/:`(8X'P`4!H@/IPS8 +M:@@@':EQ4@T```H)0`;Q!F_Z*G#@>/'`K@YO^@78`-U*""`=J7'/=H``W%85 +MA@KH/Y;/<(``1%?T($``&K8!WS3PH*;)<'H)H`P!V0/8+@T@``;9&9ZI``-Q6"B6`+X``'%<^"2`2&!6`(!8,+_PAAU#9"2!` +M`!FWSW"``-Q5#("[MX#@VK?*)0(4!/0B#\__"'4`WL]P@`!`5\"@!]A>#^`< +MR7$-\$H@`"`'[4IP`=U*"B``J7&"Z`IU`>;M#I20"-@Z#^`<`-D8%Q@03"`` +ML!X"`@"`Y18"`0`!V$#`!J<#AP_H&!6`((0H%@DAAP`A@'^``%1K+.#P($`` +M@.#U]`G8^@[@'`#9`=BZ"J`,(-E^"R`5`-@"WA+P`=W/<*<``'P>@&&^!""` +M#Q\``/@KN$`H`0(`)$`T(Z`K#A(0SW"``$CJ&@L@%?`@@`-`+I$02B``(`?M +M2G"B"2``"G'>Z`IUW?&`Y;WR`\:*)A8I$!01,$(NTQ<")E"40BG7)P,CU"4* +M<(IQSW+^_VXJN@]O^HHC_P\[<07!6G`")D"00BG"!P,C@2#/%5>#V_Z`-L"(`.@`R1!(&APF@]O^A#:0L``(8"C&G$!)\$D +M6@]O^@_:"'8Z<0+`"G'/<@(`E'TF#V_Z`-L")@Z0`<`#(5$@2G'/<@$`97\. +M#V_Z`-L")@Z0`R%!(,EP2@]O^A#:^G``WCKPSW"``"CJ\""4`T(LTR>*<&IQ +MBG+>#F_Z:G,"PM8.;_H*`0XG`;>((@S`!"(`$&&9\8%8(@.&`AAP0JO@4#N31YU7G'<8``U&I\X2=Q +M`*$!YI$.E)$8%8`@!"B^!4&'`,$`(8!_@`!4:RS@57@@H`K8&@W@'`#9&!\` +M%JEPA0-O^J;`X'CQP%H+3_H(=CIQ`=@:<,]W@`#<5@"GZ7!&#F`,"G$#V/H) +M(``&V1F?`-TAAZER9@PO_*ES"@G/_\]Q@`#852C8Q@W@&""!J7"I<0X/K_VI +M<@IPJ7$"#Z_]J7(*<&(,8`QDV0H@`*`X\JEQ"_#/<*<`R'SP($``%29,$`"D +M`>'Q"52%2H:(ZB:&SW```+THY@RO^FZ&*@U@#`*'SW&``$!73"$`H`"AR`D" +M`!6'%.@2#6`,`H?/<8``,"!@&1@`5B$``R*'!@U@#$&'SW"```0B9@M`#,]P +MIP``?**@,@F`%!8)``#.#``&U0)O^@IPX'CQP'(*;_K(V<]P@`!<5@J``-Z` +MX,HE`A#*)4$0#]CZ"^`"V`,9-G/ +M#>`1X(B!X`'=P'T`WA3P$V\4>$`H@2`T>3A@U7C/<8``(*4!80IPR7*I.'%X<;/=H``W%9QAL]R@`#859WKOY8`VX&&#R,#`PZ[B>V5A@7L +M!2-``(BX$/!E>`[P!2-``('ESR`A`L\@X0+/("(#SR"B!@+P$H8`HL'&X'_! +MQ<]PIP"`?`"`SW(``!QS#G@)(((`EB(&!,]Q@`#<5AN96&`M\!J1`>`:L0(B +M@`\````R)?#Q"E.`-0H2`/D.@O`````9\0J"C___`.<#@8_H6!&``(0H&P!A +M@0`A@']%`$`-=7@ZD4BP*;#@?AJ18;@:L0`B@`\````R#GH;L>#Q\,]R@`"Y:"```0@S@$:EP6@]@#ZEP$-AR"B`1`-F2#^`$ +MJ7#/<(``C*L!@`:`#0C?!_H.P!$$\,H.P!$0V$X*(!$`V0;P)@]@#ZEPK@[` +M!!X,X`&I.!^X'CQP.X*X!'AQ8'@`=C`>`W=&@Y@%!1]X@\@#ZEP +MW04I#142%29"$Q4@0"/X[R"` +M0()0</'`I@XO^C1HH<$(=S9YSW"``+Q' +M`"!3`$8(8`WIAB!_#X+@2B1`(,(D`B40 +M$Q$@Z7``$Q(@0,;6"*`'@-E,(`"@S"0BH`0"(0``V!.-SW&``.6LSP@0`'*- +M"B8`)T(C`H`:ETR(4X%@.;*(($/``!:`P`(@?J$+PD?`"&`?X``(#L)#%`@ +M'X`#\!V`!2B^`R]P"/"$+PD?SW"``)P[,"!`#AIP`!,`(`IQJ@]@`P#:"'8* +M(8"#RB%B```>0"``V`[M$!,`(`IQC@]@`P#:#0Q1(`'8`MH`'H`@SW%%`&PN +MH*$`V8#FS"`A@,HF01`[\@'>.?`0C0'9@>`*)(`O10!L+@`4`"#`>8;H@.'* +M(((C#_2$+PD?SW"``)0[,"!!#@`3`"`R#V`#`-H:<``4`""`X`#8#O*$+PD? +MSW"``)P[,"!!#A`3`"`.#V`#`-H`'(`C3"``H,P@(8``W@/R`=X!V!.MA"\) +M'P`AC7^``(`]%8T)"%```,`SZ&H+8`-*8<2X/8`-*<`5^J@Q@`RIP"'6B#&`#2G``P0L) +M40!"A0OP&0F1`$*%8H`"(X$`"PE2`&*E`O!"H,]P@`!(%0"`@.`!V,H@@0.9 +M!"_ZH<#@>/'`7@PO^@#9"'?/=H``3%2$ +MIE4,91`!AH0M"1_/<8``6#LP(4\.1"P^'0`F0QXD$(T`"B2`#P``T+P$O0C8 +M-)-`(P(-+.,%)0430"8&%@()H!Y3)P<0@.#*(((/```&++`-0OH0\(#@RB"! +M#P``!"R@#4'Z(88`@201@0`>"F`#`=H%!`_Z\<#+R8HA"0^D$`P`Q!`"`,]P +M@`#Z/&)H+'H-#!X0-"!`#@3P-"-`#M8)@!NXZ`/9SW"@```$**`@V*0:'+#/ +M<8``+,X4@0'@%*'+R9@0`0"4&$``RQ("ME8B`00/D6"1";$=D0BQ"8&LN*VX +M":%^$@`!&V,8D6)X&+$`V`"Q?AH$``&1&;$`V-H.8!DF@PB0'8,Q&0``"N,A(!-L]P@``4N"A@"B&`+X`` +M]+`7*/SW&!`-@_MGE@JB")/'G"N02Y97D"\(#9(*H$O04@02,AJCR7 +M,;8>@`2VV,D&IE07`!$.M@"7#[:@%X$0*:;2R00@@`\"`$$`#0B!#P(```"( +MN2FFTLF&(+Z/!/*)N2FFG!<`$0'942"`@<(A00`/APRYP+@-N"5X?0(O^MH: +M&+#/<*```#`,&(`/``P0``@8@`\(````60?@'`;8\<#^"2_Z2B8``%8@#`1) +MA!$*'@8[E,]PH```!"2@K_``%@-!5B`-`GRP`!8!03VP`!8%0#P80`$`%@%! +M(+4`%@%`,:``%@%!)+5$(P$#/PD0`1C>V;4`%@]`\Z``%@]!Z+4`%@]!ZK4S +M"1$"BB0,``0C#P$G#P$1'M[9M0`6#T#VH``6#T'NM0GP$-[9M0HD@`^!`+PV +M"AR$`6AWAB?]'(PG`I('].)N\'[YM0`6#T$"\`#?\+4+#EX0`!8/000CCP\` +M`(R`%P^!'P``B(#D;O!^^;4`%@]`^:`$(KZ/````1\HA(0`H\I_I/PT>`/"( +MSW&``.S)`[_U?^%A'0F>!^BZP'G/(>("!O3NN@'9PB%!``^Y)7I)I*BZKKI) +MI`#9.J`[H`CP`!8!0#J@`!8!0#N@"-D`D#YFPG@8M88C_`#/<:````2,(P.$ +MX-C,(P*`$?0#@1![C"/$@@WT`=W/D?0`/^O'`X<56#Z`+`=@N#&`7 +M`-V:#0``3@W@'`K8D@T``/8(@`-N#X`#"/"^"F`;J7#*#>`9`>7U#121SW"` +M`!C:N@W`&>X)`!F`X*P/`1#V#(`1N@E`$-H*0!`J#<`+SW&@```<'!F`#P$` +M`/Q_V`2A$!F`#R````#/<0``2`I&"B`.!MC/<0``7`HZ"B`.!]@^"B`#`MC/ +M<:```#<`@48@P`$`H<]P@`!(%0"`@.#*(($/``"4`(P*80W*(2$&S0?/^?'` +MX<4`W98.H`NI<$H.@`O/<*4```RDH,]Q`@``*>8)(`X&V,]Q!``T*-H)(`X' +MV,H((`,"V+8,``#J"$_Z@@A`&2X*0!2*#F`4`=A]!\_Y\<#AQ<]P@`!(%0"` +MANC^"6`-5-@(=0/P`-T=#1X1SW&@``!&`('>N`"AZ@^`$%X.H`8(V,]Q```0 +M)_X+X!P`V`+8#0U>$$8.@`8$\"X.@`8I!\_Y`-K/<8$`B#9`H0/8`ZE!J4*I +M!!F`#P```$`(&8`/````P.!_0*G@>/'`@@[O^9AP`-T/\+AE%'AT(`\!K=X0 +MOF*009`0NV5Z]7Y`I@'EZ0U$D,4&S_G@>/'`4@[/^0'==@V@$ZEP@-G/<*`` +M@!P[H)8*+_H"V.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@ +M>.!XX'C@>.!XX'C@>&\F0Q#/<*```#`P&(`/`(```,]PH@"`;'08@`\```"` +M/@B@$0#?X+C*(<$#RB>"'P``P`#`><\A(@3AN,\GHA//)^(3SR'B`,]RK0`` +M0"VBVAK8`_\:6`//<*T`@(._H,]PK0``1,&@SW&M``"$P:'@>.!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>/H:6`/!H,&AH*"MV!"X-!B`#P$$#R#/ +M<:T``!8&@00@@`\/_O__!J&Y!<_YX'CQP.'%SW6``%18)X4$(;Z/`P````;T +M!"&^CPP````/\@#9K=@0N"2@`=G/<*(``(`JH/()X!%\+G1(:&$#_)` +MVL]PK0``0$2@`=K/<*T``(!'H%@8F`\```!`\+G1(:&$$_+/`L]SK0``(,]R +MK0"`'F`:@`_/VQ`14!J`#Z(H$)%,&H`/HB@0D7`:@`_+\Y@9"=@5HH$;F`\! +M`+\W70F>`L]QK0``*2`9@`_/VQ`1$!F`#Z(H$)$,&8`/HB@0D3`9@`_+\Y@9 +M"=@%H<]PK0``+$08@`\!`+\W!!F`#PQ[F!D`&8`/#'N8&<]PK0``!`08@`_( +M&^8%;03/^?'`X<7/=8``5%@GA:+H!"&^CP,````V\K((X!%'0D>!$#: +MSW"M``"`1*#/<*T``$`0&(`/`0```$L)'@3/<*T``(`0&(`/`@"``!WP!"&^ +MCPP````4\G((X!%$0F>!$#:SW"M``!`1*`7"9X$@-G/<*T``$`DH`7P +M2@C@%P#8Y0//^>!X\<#AQ<]U@`"`$P"%GNC`V<]PK0``0#Z@SW"M```$/(!! +M*0`!P[@&M4$I``+#N`>U02D``\FX"+53(<``";66#2`4(J4!V`"EE0//^?'` +M%@O/^0AV*'5(=V8/[_D&V!8-``*MV!"X\""``Z1X$0T`$(`G_Y_D!\__`-@# +M\`'840//^>!X\<#AQ<]U@`!4%0"%A^AR#\__)@S/_P'8`*5!`\_YX'C/<:T` +M`!88&8`/(````"P9@`\=`(#0<=@,H0P9@`^,``&`1]@$H8H@G0P(H0#8`*&* +M()\,"*'@>.!XX'C@>.!XX'C@>.!X!]@`H2`9@`\``'(W-0(`%.!X\29X[@Q@&Q;9$@Q` +M&]6EI0+/^>!X\<#/<(``2!4`@(#@(`O!_]'`X'[QP.'%SW6``*RX`(4="%$` +MSW&``+"X((&(Z;(*S_^F"^`"`M@`V`"EBNC/<(``L+@`@`;HU@G/_P'8`*55 +M`L_Y\<#:"<_Y"'4`V`"ESW:``$BZ!(X/"%$`+@U`$8'@`=@"\@B-":TE`N_Y +M!JY!*($"P;E!*`,#P;L=>L*ZSW2``/3GX+A*9.$@P@?*(*(`<'$!V,(@`0!0 +M<1MXX2#+!\\@*P#@?O'`;@GO^4HD```(=AIQ2'6Z#^__*'`(=R4(D0!*#*`` +MR7#@ID$H`2'"N4$HP"'"N`JNSW"``$BZ*:YP\""&$0G>`,]P@`!(NBJ.:/`$ +MA@L-`1`)CHWH$@R@`,EP"(ZDI@FN"JX#V"@>`A`!W1'P,'?*)0$1#?(1#Q\0 +M[@N@`,EP"(X)K@D/7A`(C@JN`-T*((`O@`!(N@00@"`9"%$`1@Q`$1$(40#A +MI@38`*8!V37P`(8!IN"F70\>$*7M%(ZGZ"@6@!"`X,H@@0_D`,#ARB""#PH` +M8*[/<:```"!;@6F&"PK$`#N!8GD'\%N!#B.!#_____]980\)!0"2#*``(G@( +M\)8+H`#)<`3P*@V@`,EP%(Z%Z"F."G`FJ+T`S_G@>/'`5@C/^0AV`(!!")`` +MSW6``$BZ!(T&Z*H+0!$M"%```(8I"-\`%(Z`X&P-H@#*(((#`(8!I@C8`*8* +MCB6-!JT'C0\@0``'K7T`S_G//'`X<4(=<]R@`!(N@6*1"@^ +M"P`A@'^``)BY((`7"5X`"H@&JOH.H`,!V*H,(!NI<`3P[@Z@`P'8$0#/^>'% +M08!FH.'"`-P@PS<*7@+/=(``($>\A`BYSW2``%P,@8QD?:1\";R%>25[++H$ +M(H(/````,&5Z(X!"H)ZY(Z`E\!,*'@)!*L$`P;D!X0'<"O`3"IX&/&O!N0'A +M`MS#NP+P`=D"O!2[!".##_`#``!AN85Y97F'N00B@@__`P#<)KI%>5(AP0,B +MH*'`X'_!Q<]QH`"`)@SHSW"``)P+PQ""`!:`6&`=>(2X`_``V!:AX'[@>%9I +MSW.!`-A`0V//`E,CC``#\%,CS``$ +M(X,/````.&5Z!_!]>\]T@``L[\*[;&3'<8``:!EZB0L+!0,`VVJI:HF:J1$+ +MD0``VP'>!_(*#@>/'`2@Z/^1IP`-C/=8``2!D`I0'>>@UO^N'&0"4`&%8/[_\D%8$0 +M&XV`X*0,H0+*(($#D@@```[HSW&``"@M`($!X`]X`*%^#&_ZBW``I03PP*4! +MV(3H4@Q/^@"EE.@;C8;HBW"*#6_Z"G$-\`QP^;C*(&($$`NB',!Y`]C/=8`` +M2!D`I;8.3_H`P0"EAND!VL]QH```$$FA@.#,(.*`"?0`V_X+H`(D%8`0:'4" +M\"+=Q@Q/^N8*0!RI_Y +M!M@$((U/(````%,C`$`%('Z#]?,R#V`0BB`$`=4%K_FI@X'BAP4#`SW"``*!'(8#/3.CX'[AQ>'&SW6` +M`)P+D(5`%8`0!"2"'P```!@KNE,DP1!$N%,@0P`2:A5X-'C/=H``U.X69L]P +M@`"D[FA@^[S,>)@5`!`$*'X.+W#"("($$/0#NGMC57IU>WIB66'/1#A(G@CN,'&X'_!Q?'`SW"@```@`-DZH*7-1B#"`*3-I1J`8H@!`"D&ARPSW&``"S.$H$! +MX!*ASW"``%@5`(`)Z`#8SW&@_KP+,@^@#I:XYO'F\?'`<@N`%EX*@!8F#4`0 +MT<#@?N!X\<"."H_Y`-[AQL]UH```(&P5$1#IR2D(W@#/<*```$<4&(`/```, +M#.S)!=D!X+.XM;BXN.P:&+`5N02ASW"!`#1)RQH8L,]P@`"PV\P:&+"DS3\( +M'@`^A<]P@``@1QV``N%AN`@A```0I0'8!QT8D!#8`*6B#B`;2B``(*3-)+@$ +M((Y/,````%,@#0"U\,]W@``(WP&'">@`AP\('@""N(H-X!H`IQ(.0!4(<<]P +M@`"<"[8-(`\9@!IPSW"``"S/`H",(`*-B?>2#*`"%=C/<*```!#)H`&'".@` +MAPT(G@"BN$H-X!H`IZ3-'PC?`P#>R76#\&8,H`(5V`#9SW"@```0*:!Y\`38 +MTAH8L!&%SW>@``!(@."*(`P`RB""#P````(`I00=F)]@````_@B`"^G)!""^ +MCP``#S@&\A`?@)\```P,SW"@```(`H!M'YB3!=+)AB#QCR#T!"&^CP```%`!V$#`!/($V*0:'+#^#$`5 +MSW"``"S/`H`Q"(6/``"T`.G)%0C>`L]PH```1Q`8@`\```P,I,V;"!\!L0B? +M`88@_X6Q\FQPJP@?`-+)!""^CP,`Z%/)]0QPCPA?A;((H!``WAX(@`M.#D`4 +MSW"``$BZ!HC/"""P+B@N25X`*+N#^`;!]C/=Z```"!Z%P"6@.6D +MN'H?&)#/<*```$7$H`;RSW"``&PH`("`X#`#`0!$%Q$0R@\`!(#@&@(!`.H/ +M``3"#``8+P(``*7-4R!^@`/T`=VY\`,]PQ>Z".@'9,@O@&](2`K:DS0HC@"^``"S-SW>``"S. +M7PC>`(#8I!H`AN'`-D!X!NG`!I`(.K)(P@>`,]SH```16V#SW#% +M[H-!`=GF"N`;6X<%\!.'`>`3IW$3`2;/<(``K,XU>#J``>$ZH!GN&H#J``>$ZH`7N&8@@@#^EP)_'+ +M$@&V`8$/"!X!$(D!V4X+8!,`VH8/@`K+R0#9H!```/"X*'`(\B(*P`N.",`. +M`-B6N!H+`!P$V-(:&+`V""`/`M@%\3\('P)]"%\"!""^CP```%`(\FQP#0@> +M``38TAH8L,]PH```(!N`+R%*!#A@`>#7<```4,/F][8-`!DI\-H*8!&*(`0` +M$@^@"@#?R\F@$```\+CI<`CRK@G`"QH(P`X`V)6XI@H`'`38TAH8L`G9SW"@ +M```@,:`J">`."-@.\88)X`L!V`#8@@H@')"X!-C2&ABP`O'+$@&V')&&(/\, +M%P@1`A8.8`(0B0\(40#+R8X-8`(0B!J'"2$`(.3@QO;0IS8,X!<0V(PA`:G' +M]\@7`1`P>8H(8!`0V,O)Q!`.`#"(6I`X$`0!I!```#(2`S8/"!X%SW"!`#1& +M@H`"\`'58G`QCJR2)[;WLM"!X`SW"@```$CX`0N\Z`$+S0?@BY +M)7O/<,7NA$0!V>5[E@C@&P4F!!,RR,]SH```+0*X`"""#Z```"V8@M@2`;8L +MN<2Y'0Q!$&&#,""`#Z``9"X0(T,`:W@#\@/8&*(8@J7-Z;@X"Z($RB!B`"X* +MX`X8V!+P+RI!`$XB@`<0(0$`(*.$*`D/SW&````]@@K@!C(A00[/``QP&P@?`\]PH`"`13`8@`\`(```SW"``&PHX*!J(8`!SW"` +M`'`HN@C@#""@BB`(`/JF`*81AH3HBB`$``"F!!Z8GR``/P`''IB?`0#`_`8+ +MP!K/=H``6#(@AA;II@F`!>K)X*8E"!X`,LC/<8``!+A`*`($]"$#`,]PQ>Z" +M2`'99@^@&V5ZJ7"B#^`."G'IR00@OH\```\X"?+/<*```$<0&(`/```,#)X, +M`!C2#8`.G@@@#`'8SW"``"3;_]D@H,]P@``(W0"`@.`,",(#SW"``)B[X*`5 +M!&_YH<#@>/'``=A:">`1`-D*"@`2T<#@?N!X`=BI`J`6`-GAQ0AQ`-@!VPAU +M#?#/H""#0Q%$`2*`>4#\`#;]NO@?\'%\<#/<8``&+\`J<]R@`"< +M"R^"$-N:N2^B"-G#&D(`Q!I"`,]QH`"`''NA1"@^#<]Q@``@OR"!)W$$@<]S +MH```&`*C`X$"HP*!`J,!@0*C`-@&H[@2``$@DFBXN!H$`"APAB#]#(P@`H(! +MV,!X#[B&(?^,EB"<`Q*C`_0!V!FCSW"``$@5`("`X#0)@AS1P.!^\<#R"F_Y +M$-H(=@&(1"@^#<]P@``@OZ"``98G=0"U-!:`$`*M`8X#K4`F`!G6#Z`80"4! +M&4`F@!U`)0$5Q@^@&`K:!&XD;;X/H!@0VA4#3_GQP)X*;_EANHAT`B!-`$$M +M#A,QO1IB(GI!*@\#,;I0=1_8RB#!`P#9#R$!``#8#R"``\EI8;@E?O`C00,& +M?@"!!.P%?L"A%_#&>`"A$_#%>2"@$?"Q$*18.1`D_Y\<#AQ:5Z*@T@'+(4`Q%:"<`.+0)/ +M^>!X\<#/<(``C*N""N`$`(@*Z-8*X`H,V.X+(`0,V`'8!?!B"\`*`-C1P.!^ +MX'CQP'X)3_G/<$4`E"RD$`X``_`0)DX3(NXO*($#3B"-!R(*(`.I6O?@JO^!X\<#AQ<]U@``LOP(*(``=A0'8K0!O^12ESW"@`(`-'X#@?N!XSW"``)P+ +MP!"``(#@X'_*(&(`X'C/<*````T'@-.XX'\%N.!XSW"@```-!H#3N.!_!;C@ +M>/'`C@D@``#8E@D@``#88@D@``#8:@D@``#8!-K/<:````U"H4/8`*'/<*`` +M`'Q8&(`/$8`1`%2@T<#@?O'`SW"``"R_5B"!`Q2`@>#,("*`(?1B"2``\"$` +M`,]P_P'@_PX)``#/AX'[@>"6XT[C/<:`` +M``T$H>!^X'@EN-.XSW&@```-!J$!V`&AX'[@>,]Q@`!X5""!(X$"><]PH``` +M#2*@X'[@>(#9SW"@``!\-Z`Q!L__X'CQP!8.#_D(=0(.[_\H=H7N`^@-#040 +MD@_O_ZEP:08/^?'`]@T/^0AU\@WO_RAVA>X#Z`T-!1"2#^__J7!)!@_Y\<#/ +M<8``++]4@0#85J&!XA2A$`@B`,H@8@#1P.!^X'CQP`;H`@[/_]'`X'Z^#<__ +M42!`Q`'9PB%!`%$BP,8!V,(@`0`K>`CT`]G/<*``@!TFH.SQZO'@>/'`SW`` +M`!`G0@_`#P/PK@R`#5$@0,0!V<(A00!1(L#&`=C"(`$`*W@'\L]PH```?`*` +M#0C>!VQPUP@>@%(C`$#`N-'`X'[@>/'`X<4(=14(G@'/<(``#%$`@(#@XB`" +M`,]PH@"`*+&@C04/^1#P+RM!`$XC@@<0(8$`-*@#W#)J-7D`(8,/@`!(N8"C +M-(CQZ<]P@``,XKT"0!K@>/'`V@P/^0AU"B"`+X``2+H$$(`@(PA1`#8(P!`; +M"%$`SW"@```@&X`)I<]P"@!@KL8(``!,\&X-X`(0C48+X`(`WJ2X"B2`#X`` +M2+D4K0_PA"P)'\]R@``H.S`B0@Y@H87B`=K`>@'B1*D:Z"\I`0!.(8P'`=L0 +M(``#4FQ5>@`B`0%`(0("Q:D`W\D/TY`5(L4#`!V``P'G[W_Y\<]R@``,X@:" +M!(`@@,=Q!@"`&EX*8!I(<,]PH```(!N`*(T)I0880B``&(`CQJ7'I74$#_GQ +MP,]P@`!(N@6(1"@^"P`A@'^``)BY'@_/__H(H!H!V-'`X'[/`@.+,(2&`!O0H +MB,F($0F!`P7P"0FD``+>`=Y)B$`@`0@/#H`0`]I(J0CP>X$.)($?_____WEASW,&`(`:,0G$``8.S__*#2`"$M@A\"\L@1!. +M)(X7`=T0(H(#3WH"OM5^`":,'X``2+F@I/'J2(C/<(``2+I&J,]R@``,X@:" +M(GL$@""`>6'V"&`:2'`Q`P_YX'@4B!'P+RH!`$XB@0<0($``#W@$VP*Y-7D` +M(8(/@`!(N6"B\NC/<(``#.)M`$`:X'CQP,]P@`!(N@6(1"@^"P`A@'^``)BY +M;@W/_S(-(`(2V-'`X'X(<<]P@0`H.&4$X`L`VN!X@.#,(2&`!?0`V`"B$_"& +MZ(#ARB!B`/OU!NB&Z0+8`*(!V`GPC"$$@`/8RB`B`0"B`MC@?P"CX'CQP"8* +M+_F8<.K)I\%S"!X'SW-$`'B[!HNEBPBXAXL%?;@3``84$P<`0,#/<8``0,$# +M@1`3!@!!P`2!#!,%`$+`#)$0O,J1$+C%>$/`&HG6B1"XQ7A$P!N)UXD0N,5X +M1<`0D8AR+I$0N"5X1L!DB\]PQ>Z.PP'9\@Q@&P4D1!,9`B_YI\#QP,]R@``\ +M$@""B^@&@@2`((#'<9,#`(>R#R`:2'#1P.!^X'CQP%(,X!`"V,7)!^@`V"X) +M8`+%&ABPSW"```3_H@F@`@"`T<#@?N!X503@$`+8X'CQP.'%`=C/=8``4#(` +MI<]PH```(!N`E@B``L]P@`#8&@(/`!H`V*$!+_D`I?'`(@DO^0'8SW6``%`R +M`*7/<(``!/\`@,&`SW"@```@&X!>"(`"`-D@I0SHSW"``-@:Q@X`&@;8A@A@ +M`B]H!?!B#6`"R7!-`0_YX'CQP,]Q@``\$@"!@."<#B(:RB!"``#9SW"``#PR +M(*#1P.!^X'CQP'()#_F""`_YI,%2P%/!SW"MWN^^0\#Z#Z`2`=C/<*```#`, +M&(`/`0```&D@``#/<*```"`,&(`/(```!!/!@.$']`/`0L!!P$#`#_"!X13` +M0L`#]P/`^/&"X17`0,`#]P/``O`6P$'`@@C@%P#8SW&``,#\,!G`#RP9``\H +M&<`.)!F`#B`90`[/<(``P/P<&$`+SW"``,#\&!@`"\]P@`#`_!08P`K/<(`` +MP/P0&(`*SW"``,#\#!C`",]P@`#`_`@8@`C/<(``P/P$&$`(SW*``$#\SW&` +M`,#\`!D`"'P:P`=X&H`'=!I`!W`:``=L&@`':!J`!F0:0`9@&@`&7!K`!5@: +M@`54&D`%4!H`!4P:P`1(&H`$1!I`!$`:``3OHLZBK:*,HBP:P`(H&H`")!I` +M`B`:``(<&L`!&!J``10:0`$0&@`!8Z)J(``#%J%J(,`"%:%J((`"%*%J($`! +M$J%J(``!$:%J(,``$*%J((``#Z%J($``#J%J(```#:%J((`!$Z'/<*````P% +M@`T(4``,`,]QH``` +M-`"!D+@`H0/P8@R`$FX*0`$N#H`8)-QS!N_XI,#@>/'`X<7/=8``)"#B#>`, +M`(4`'8`?K:O^RL]U@`#X4*)1`0HJ(,&H`/ +M````)!UE`8)'P0`@4`/'=0$````$V$#`8<#/<*```"`;@"J]0\!&Q0'>1<9" +MQ@XE@!\````"P@J@#D3`"'&+<(G"9@L@`HC#",`.Z`G`"KU)'Q@0#"!`H\HE +M!11*'U@3R7`#\`#8Y07O^*K`\<#/<8``K-0+@:2X"Z$1"%\`SW`#`.S[6@D` +M`-'`X'[QP%(-S_@(=L]U@`#8#@S"$B@"+R`(4=V28/(`$!VB"`SW:``-S4)*;/<:```"`[ +M@0#?(J`(V2:@B@D@`NEPS@[@`0S82Q4`%J"X2QT8$.8-[__LI@3P:@R`&,]R +M@`"01B^"SW!%`'@W$"$!!.X)(!HOHG$$S_CQP/(+S_BZ<`HC@"^``*S3"!.2 +M(,]Q@`#LR4`JP"`5>`!A`!.0(%$@0()`(PTH0",.)(KT"G"6#^`.2G&,(,./ +M.G`+]$`H`23/<```932Z#2_Y!2&!!,]W@``$,`"''-D@H`1M`:=`)0`4R@S@ +M"TIQ(8=`)1(8`8&+N(RX`:$\%8`00"44'TT(W@&$*`DO`"&`?X``@#P6($`$ +M08@:V`*G`"&`?X``8#P6($`$<9`,'P`5!+L6',0@,9##N@'A,;`CAPR117@, +ML0&',QB"``;P#!\`%1C8`J="AB.&@.+,(2*`"?00NL]P``!F-!H-+_E%>0"% +M0H9"<%RH(H;_V@BZ1'DHN3VH(X8`VSZH(X9$>2BY/Z@BAP':`"$`!0:G`8<` +MD")X!:?I<*IQ:@N@#$HD@`'/<8``)"``H4L3`":"N$L;&"`!`\_X\<#""L_X +MSW6``*S3XH7J#^`:[W@(=DL5`!;@N,!XSR#"`Y@)(AO*(>('*.[/<*```""; +M@,]U@``@,``DA1\```!]`-@0V0':"'.8=PHF@`\````8/@N@#/AUSW$#`,3\ +MJ7`!V@#;Y@J@#$HD@`'/<8``^%$`H0?P2Q4`%N"XA`J!&*T"S_C@>/'`SW"` +M`*S3`H`!W``L`!"*"2`;']G/<`,`[/L6#L__T<#@?O'`SW!%`'@WY@_`&<]P +M@`#__`=C1P.!^X'C/<(``*.%)!H_]X'CQP,]P@`#, +MU<]Q@`!@4>H.(!@$VL]Q@`#,*@"1@+@`L<]P@`!$X0'9(*!V#.`!$]C1P.!^ +M\<"B"<_X&G``W<]PH```(&P0$0!:=:EW#?``V`"FSW!%`'0MA"\!$]X+(`(P +M($`.`>@@A@D*$2`H=0CPJ@S@#*EP +M!.@@AOKQ0")2(.;QANT>#^`9"G`,\!@0`"`$@""``B%!!+EA7@_@&0IP?0'/ +M^,]Q@`#P.`#:7Z$E@(4";_V`V.!X\<`($``& +M&0B!#P``___/<```GS/J"B_YBB'-`@;P@-BV#"`.)8+1P.!^A"@)#\]R@``L +M.S`B0`X`VP\C`P`"N,]RH```(!5X9:+'<(``9-="@$""0*$#@`"`X'\!H0#; +M#R,#``*XSW*@```@%7AEHL=P@`!DUT*`0()`H0.``(#@?P&AX'CAQ0#="/#P +M($P#8((!Y85[!!K0`/,-1)#@?\'%\",_X`-V*)/\?@**`HP+P`>44(4\# +MP(^,)L.?#/*!C_,(!8,()@X0P*(!CP"C`=@#\`#8E0#/^.!X\<`F",_X"'7& +M@`"`@.#*(((/```V$0`*`OE`A@+P0((/"H`#(H4"@B)X]PA2@`&"H:)`I0&E +MH*`DA0:%'.`7"5X`((`&Z4*%(H%">0<)4@"@H`2%)H4@X14(W@``@0?H0H4" +M@$)X"0A2`*"A`84-#@$0L@V@&`:%!(7`V08F`'```@``J7((V\H/(!N*),,/ +M!0#/^/'`A@^/^*K!.G`H=`8*G#/<:```"#($0,`^X&I +MP(GP!`B>``AC7^``"`]!PA2 +M`!"EBW""P5H,X!F$PE4=`A`$P`#!$:4!P"2E!:7RI2IPR7$V""`:`-H]!Z_X +MJL#@>/'`T@Z/^+(-8`,(=L]WH```103P!@X`#1Z'!""^CW````#Z]8H@_P\< +MIQBG"B"`+Z```"`%&)BO`0``@`*&"*<$A@6GHX8`V`0EC1\``@``F@N@!#IP +M"B)`@\HB8@#XX`_9!O8[:(#@RB%,!,]S1`#8](&+0[B">##@@.`!V\H@S`#% +M]K_@RB#M#\]T@``4":*$![E$)8,1!"6-'__`>/AE>H8AX0]%>1BX)7@%?:*D +MJ@T@&P+8`X;/<8``;`P$I\@0`"`8&4`$?@B@$P.&ZLG]N$`*XAK*(((#`H;/ +M<8``T/<`H0.&40:O^`&A\<#N#:_X2'!(=MX(8!"H=26-!(T(N25X)HT0N25X +M)XT8N25X(8W#N3H,X`H!VB6-!(T(N25X)HT0N25X)XT8N25X(8UN#.`*1+GA +MC<]QI@"```V_!">/'P```.`/#M,3BB`*``2A_7\%\!`9@`\````\!@S@$LEP +MS+CE>,]QIP``0`"A+8T,C0BY)7@NC1"Y)7@OC1BY$@S@"B5XY@K@"A"-N06/ +M^.!X\<`^#8_X"'4R#N`:,A(0-@X/8!:I<#IP`-[/<```$"?V#F`/#R9.$P#? +M!O`Z"&`:`=@!YQH-X!H* +M<$D%C_CQP(()0`0(Z!X.(`H'V'8/8`,'V-'`X'[QP,8,C_@Z<,[)`-T%($`$ +MSAH8L.H/8!8J`4E#9`#\F5^SWYF>>'I +M5!(`((#FIG@%($$$5!I`(!P(8AK*(((#+R4'%*8-8!*I<*X,X!JI<.K)+P@> +M`%02`R#/<*```!R#@-!^!KP$)(P?_P```,]PQ>Z$10'9*')>#^`:!28$$V4$ +MC_C@>/'``@R/^!IP"'4`WP7PQGC.&ABPQGTC[2\H00-.(($'+WG/<(``4-;P +M(%$``-X/)DX0#PD1(,[)QGC.&ABP@@U@$BAPSW&``#04\"$```L@0(3.R=WS +MQ7C<\=X.8!8*1WI+RA!`$X@@@=/ +M>I6&_QX'_!Q>!X\<`: +M"\`$".@*#"`*!-@B#6`#!-C1P.!^SW&!``!P8XE6(`($4R-^@":""O+=N2:B +MX+O/(:('SR'A!R:B!"&^CP#````,]`&`%0@>`-G)"H#^N,\AX@?/(:$')J+@ +M?N!X\%@8)@`++$@&VH!D` +M`(8@?H\A\@'?(/#/<(``/-L`@`SHR\F@&(`/!0```(H@"`#2&ABP$?`3#5X5 +MSW&``*S/&X$!X!NA[O$,`,L2`K;/<,7N@C,! +MV0H-X!J@$@(`SW#%[@)"`-G)N`7O8>8-9^/&&4?)YFWV*`E]IBX9<0O.5\@:5"F@*X +M%'@5($P`-"0``Q"Z17@!I9AC`(";8P&E!H,&\`#8`:4!I0&E`:6%`8_XX'C/ +M!EB()D:8A"Y!IHE>`+P`-@!H^!^\<#N"*_X +M`-KAPB&`"B4`![")SW$``*CP2',_\2B2``0AV`,"`X,H@@0\```I"K`K! +M^`#!!8&$N`6AI@Z@&JEP#N@`P0&!C"#_CP3RR@UO_221`,"^#F_\(8#)<`$! +MK_BAP,]PH`"`#$`8@`\`&#``2'#F$@&V`-I-`.`:2'/QP%X(C_@Z<"AU&G(3 +M"E$`KWB"#F`2`=D`&00@&?``WA7PVWA`()(``")`(P]X9@Y@$@'9%"&/(P"W +M`B6`%`]X4@Y@$@'9`;<"YML.!)1Q`(_XX'CQP!((K_@DV1IP`-W/=H``(+R@ +MIL]W@0"(-W(,;_WI"@I`"F +M`>7C#522-0"/^.!XX<4%\""C$"!``P[H+RL!`$XCC0?/W3J_]R` +MH_/QX'_!Q?'`I@]/^`AV*'4*:3X,8!L/>$$H00'P)D$0Q+@1(0"`RB"!#P`` +M_11T">'XRB%!`^4'3_CQP%X/3_A:?/#P24 +M;0=/^/'`(@]/^,]R@`"$MD""J,%H=AL*D`"+=0*YJ@\O_JER`-C)<<(/+_ZI +MN,]QH```(%N!/QD8@.!XX'C@>.!XX'C@>.!XX'@;@>!^\<`J +M"L`)<@E@$`+8Q@T<#@?O'`SW"``+P:(@R`&4H)8!`" +MV-'`X'[@>/'`X<7/<*```""[@*H/8`$,V`(+X`&I<"*`C"'#CQOR`X``V0(@ +M0(/*(6\`@.'*("$`UW`````0!-B3]\]P@``$_R&`SW"``+P:'@R@&2.!"?#/ +M<(``O!JZ"X`9`=B.#8`!509/^.!XSW"```3_`8`"@(P@PX\$V,H@80!M!8`! +M\<"R#4_XH(`:<`2%H<$/"+0`0"41%105$1``'(`_80``\(MP(@K@%P39`(4: +M"N`7!-D!A1(*X!L,19`!%(\4SW.@`$`$X*OX\140@2`="5(`I@G@%T`@`",(\`#9SW"@`$`$ +M(*@!YE,F?I#X]5D%;_BAP/'`X<7/F6**0G``*""SW.@```@FX.R +M?;QD`>2,)`^:0_>&Z7N#8*)>#&`3):H]!4_X\<"^#$_XH@D@``AU@.">\C-M +MSW"``##[%B!$`P04@``V>0*X%G@X8``@C0^``%CZ"B"`'Z```"!4$`^00"4. +M$\EPZ7'_VABZN'+R"2``2'/)<.EQ_]H0NMARX@D@`$ASR7#IARF@D@`.ASZ7#) +M"T_X"'7/<(```!0`@!'H\@P``A\(40!*"2`0KWB`X,PEXI`'\F(.P`^!X`'8 +M,/+/=H``,/L6)D`3!8@?"%$`(@D@$*]X@.#,)>*0!_*I<-8-[_\`V1OPC"7# +MGQGT`-T5\!8F0!,%B"$(40#V""`0KWB*Z*EPK@WO_P#9R7"V>`X/+_T(V0'E +MW0W4D`#8_0)/^`0A@8#AQ1SRH(`$)8P0/&1$?$9]"PSE$*"@(0Q%$*5[8*#/ +M<(``C*M`B`'9SW"``##[5G@FJ`3PI7R`H.!_P<7QP$H*3_C/=8``J"<7C<]V +M@`#\$T"&%0@>`,]PH/Z,!<8*(`H!V4"&#PH>``'9SW"````4(*`1"EX``=G/ +M<(``,!0@H!>-&P@>`,]R@```%,]PH/ZT!0'9C@H@"D""%XT9"!X`SW*``#`4 +MSW"@_N`%`=EV"B`*0(+/<*```"`[@,]P@``0%,=Q!`#@D^8/0!DI`D_X\<#/ +M<(``,/L>#B_]&-G/<(``6/H2#B_]V-G&"4`3T<#@?N!X\<"2"4_X"';/<(`` +MC*N@B&8.[_^I<`WHN@SO_ZEPSW"``##[MG@%B#X)8!/)<=4!3_C@>&4!0!/Q +MP.'%SW"``(RKH(B.#.__J7#6#>__J7"Y`4_X\<`R"4_X"'>S:,]V@``P^Q9^ +M!(ZV?0*X%GBY8`H@@"^``%CZ;@O@#P`@42!+"!X`SW"```@4#!&!(`"`-0D$ +M`,]P@``$%!P1@2``@"4)!`#/<(``+!04$8$@`(`5"$0`SW"```P4&!&!(`"` +M"PA%`.EP`-D#\.EP`=G."\__`-@&KB2.#0E3``'A+W@DK@/P!*X"N!9XN&`" +M`AW@"<(&`AV@"9(&`AU +M@"6(&(#CRB.!#P``(`'/(V(`SR,B`JH@@0T)Z,8/S_\K(<`#*R*``RLC0`.U +M`$_XX'AJ($`!1"`^AL]Q_LK^RLH@00`,\B.X4B```,"X$WC!N(`@"`@J(``` +MX'[@>,]R@`!4%`J"`-G@?RJBX'@`V<]P@`!4%.!_*J#QP/H/+_@(#&^&`'IAKPSW"` +M`%04):`4\,]R@`!4%&6"#0G$``(AP``'\`XC@`______.&`H@CA@"*(`V`6B +M'0/'`B@XO +M^+APB'2W:+1]SW>``-"LM6<`WN6]T25BDLHF8A`?[H#CRB,"`\HC80!`+8P` +MEGP`)(`?@`!(^T`@#`./Z@#:"?"G@`'B%21.$R"F`>7!O:>@22,-`>\*1(.9 +M!@_XX'AM!H_X\<`B#@_X`-[)=PGP`(4-"%$`6@ZO^.EP`>=/#Q41LF^V?<]P +M@`!(^QUE%V\4>,]R@`#0K!!B`-GEN-$@8H+*($$`RB!B`&3HZ7`&#:_XJ7$@ +MA83I"0@5`6#I7>@R#:_XZ7`(=MKQ*08O^,EP\<".#0_X"'4!@$HG0"``WX/@ +M2B1`(`"%PB0")8+@2B5`(`.%)!43$)P<"+`$A<(E0B5!P!@5&1`*)H`O0``` +M`!P5&!`H%1$06@R@"4$N$B(*(`"@RB"!#P``NA-,#T'XSW:E```,*![`%1(/ +MP`E:#T```-G/<(``>%1"P`/8#;A#P`;P%29,(."D`>$"P`P4!#``@`"`"2`` +M`>T)!(`J#T``"X5`*!8&(!Z`%>FF[*;/<*```#Q$P`3!2G`2H03`]J`"P`"` +M((`#P`DA`0`*<`8,X`X"N:8.P`GKID`K@"`AA04@``4]>02Y)7A`+0$E!7E` +M*4`E)7@%((`/B```'@4@@`5&P"B%!840N25X#*8`P!$(G@>/N$#``<"/N$'` +M`,`!P=VXW;DTIA:F0!X`%D@>0!8N#.`,A<`"A8;H!,`$P12`WK@4H>JFR@AO +M^`;8+![`%7T$+_BYP.!X\?`X$P,@<'+,(&&`RB""#P`` +M!PF(#4+XR@Z@#^EP&G`=C4X@00`^K3Z-!"F^!``A3G3)<'8,8!H46YSW6``-0O-7TBA<2X2B$`(`\A$2`+(4"@ +M"/)J""`%"G`"A08@0`0"I38+(!+I<`'8-_`X$PP@SW.``(RK8(N1K1RM0B%!("]X +M1;C/=8``U"\5?0*%Q+E*(``@#R!0(`L@`*`(\O8/X`0J<`*%!B``!`*E`MB* +M#:`.Z7'M`B_XR7#@>,]R@`#`)B""#X(O"20`02B,``)YSW```#8D%PQE$$Z" +M$'+*((L/``!X`.`@RPP2[+[L"(P$`([DS>`T(<@`1H@#8,J+@?N!XA"@) +M#P`A@W^``(`]E8L`(8)_@``@/9OL)PE1`%H2@0"/Z3&+`K@!X3&K,(M#<`'A +M,*LE$`$&`>$E&%@`!/`2BP'@$JL`V%H:`@#@?O'`J@D/^`AVR\F@D`&`0.7T +MN,`EHA`#Y<]RH```!"2"!"6-'P``_/\3":4#W64RR!MX0W!F$``'&6$.@@(E +M3Q!/",4#`]@V"^`."K@$V<]PH```1R2@SW"@```$#H`-",4#;'#S"!Z`!-G/ +M<*```$!,('@#/<8``K,X"@0'@X'\"H14(7@#/<8``K,X#@0'@X'\#H2$(W@!L +M<,]Q@`"LSPT('@`5@0'@X'\5H1N!`>#@?QNA$PC>`<]Q@`"LS@"!`>#@?P"A +MX'[QP(X(#_B")`0^SW:!`#1&V,D`%A,0!""`#_$``/!"P,O)0"02/A"(2B`` +M(#-H-GG/0/`SW*` +M`'3O!2$$`,O)+R'"!<"Y1L$I8@"01\$&P\]T@`!H5/`DPQ`984C#9VD*)X`O +M``#\_X.&!"/#!0@C&0,H&4`@",2(<2"DRQ(!ML]R@`!V[W(1`0$B>`;!*6(X +M8!`9`"`"(<`P0!D`(!09`"8!AH`@#PH0I1#8!QU8E0"E*@]@#0#8H@Y@#0(C +M4R;/`"B7@Y@&@/8V,G/<8$`�LN,2XRQ(# +MM@2Q#X/NJ0"A0!,``3(2##8"L1"+8!,#`51HP[ME>@^I`89&L1![SW&``/2W +M%2$"`YZ"5B'$`YMC?J);A5A@P!4"$`(@E0`"AL]RH`"`#`*X+^`$(,`%$*+F +M$@*V`!^`0$*&`!^"0#+(%"$"`%"*`!^"0``?Q$/+R900`@``'X!`,LCP)`(` +M`!^$0``?Q$,`'\!#`!_`0P`?Q$/+R5"(SW"``)2V2F``'X)``!_"0]@2`K8` +M'X!`R\E`D%00``$0ND5X`!\`0,L2`[8!@R$('@%2B\]P@0#8/W"+=G@`B(8@ +M?PP<>`2X17@#\(#8`!\"0,O)4(@S$(``!+H%>@`?@D#+R5R0`!^$0,L2`K:< +M$@`!;X)1(("!`=C"(`$`#+C`NPV[97@R$@,VVAH8L'1YX+$`(X`/@``4N."H +M;WS/<(``3-V6>`"0F!G$`U`9!``5),0`SW``*`@`0<#$$@``J!G$`X0H"0_/ +M<(``_#PT($`.`!S``TG`$!0`("*&3!P`(`&&*@G@&D"&`H8%((`/Q>X`-TK` +MR\D`QB&`0.;TN0'9`)#"(4$`-'@#X`0@P`4>9@/P`GXRR!MX0W!F$``']0X% +MD,]QH```11R!.($`W0\)7P4$(+Z/``8```WR^K@!W<(E01/YN,HEHA#UN@```(#A"5X`\$%(%0`S!(!M@0D@"`X&0`% +M`!$9`5!P&MC*("$(@```(IO0!V`FA529`%`2A +M3'#_"!^"#,#/@```("A\8D$?N!<`/VH_@ +MRB(%``RZ4R8!$LW-)7H0N$5X`!\`0$`@4"#)=(8D_9X`&@`@0"(-(2_R5!_` +M%,W-SW*``/`W$+@E>``?`$`$'1`0`-@!I\]PH```(!N``B4!(`""0"!0(!,( +M$0).$@`&Y+B,#2'\RB`A!)H.@!K/<(``6!4`@`GH`-C/<:#^F`V6#.`,EKB` +MYGORSW"``%@5`(`)Z`#8SW&@_LP->@S@#):X]@ZO_\EP"/`(V0`?0$`$'5`0 +M0"!0(,]P@0`T1@*`ZP@$H,]P@0`8-`20`]T"N#`@@0^@`+0NVLDE>,]QH``` +M#`*AIZ&GI_(-@!7/<:````0)@07HJ*$`V`FA!/#^#:__`,"."B`-`MB>"0`- +M"\`HZ`39SW"@``!')*#/<:```"`;@<]R@`#P-PPE`*`,=QN!;R4+$`(E`2`` +M@A,($0).$@`&Y+BH#"'\RB`A!(#ET2=AE>3S!-G/<*```$":`.J7'K#EX0SW"@```@NJ!O\`#:%0L0(%0?P!3/<8``K,X`@0'@`*'/ +M<($`�$D`/=`K@P(($/H`"T+MK))7C/<:````P"H:>A0:=2#2`9"<"`X-`) +M(0W*(&$`I:"Q&0:O]X`D!#[@>,]PH`"`(%P8@`\#`$`-SW&``)04`('/[)`:$2>`6A[\D" +MH1)X!J'PR1)Z`Z%'H?$2`K9?H5)Z5J'/``'"V((<*(H`O@`!XM@HA@"^``'2V&0U!$``2`"`1"`$$ +M`!$`(!!V;`C!"Z"G`!H`)``9@"-1!(_WX'BJ(($,">BK)L%R```!`*H@`0+_ +M"!^"X'[QP!8(``"J(`$"_P@?@M'`X'[@>*HB@0P/ZAEA1B#"!P+P(.(3"D4` +MJR(!`ZH@`0+]"!^"]_'@?N!^X'CQP*8+K_<1V$8-@`#/<8``9`\`B<]R1``8 +MD@'@#WP`J3P2@`!C:E$,`1#/=(``90\`C,]U@`!F#P'@#WX`K`#8`*DBBBD. +M01`CB@"L(*W/<8``I.`@@<]R@`!0$3H-(`!`@L]Q@``DWP"A#?#(8WH/H`\` +MK<]P@``DWP"`@.`X"<$/E0./]^!X\<`>"X_WSW:``/P4!(X5")$``M@`W=H. +MH`^I<:2NH*9M`X_W\<#/<(``'/WL'`BPSW"```SU0<#/<(``'`]"P,]P@``@ +M#T/``-M$PPS8`]D&V@HD@`]$`#33"B6`#X``!!5*)@`%\@M@"DHG0`"EP-'` +MX'[QP`[HSW"@```@.X#/<(``0-\@H`789@Z@#P#9T<#@?L]R@``TWP""%0A1 +M`,]Q@`#\%`"!`>``H0#8`*(Y!8`/\<#/<(``&-\`@"L(40``V<]P@`!D#R"H +MSW"``&4/(*C/<$0`&)(CB,]P@`!F#R"H#?`D$H``$0A1``'9SW"``#3?(*#> +M#*``$=C1P.!^X'CQP,]P@``TWP"`$PA1`,]Q@`#\%`"!`>``H<]P@``8WP"` +M@.#`#($/T<#@?O'`[@FO]PAQ2'4`WL]P@`"DX""@J@L@`,EPSW&``%`1`*'/ +M<(``--_`H,]P@``DW\"@IPU1$,]U1``8DDP5`A')<`#96@T@``\A@0#/<(`` +M&-_`H,]R@`#\%`2*80A1`,]P@`!`WV"`A>O/<(``Z!!@@,]QH```(!N!#0C$ +M`!N!8G@(\#N!#B.`#_____\X8"F5!"F!#P\`0$(E"05PQ*H$V!X-H`\`V<]P +M@`!(%0"`@.`D"J(6RB"B``_PSW&``)!&3!6"$`^!#R"``&(-H`\/H2X/@`^) +M`8_WX'C/<*```#`P&(`/`(```,]QH@"4;@"!!""`#X#_```%((`/%P````"A +MX'[@>*'!\<#B"(_W*'4(<<]P```W,Z8)+_A(=@+8J7%^"2`/R7(!V,]Q1`!P +M[P:A"-PK`8_WX'CQP*X(C_<(=BAWM.'*((8/```S,\HAA@.8"N;WRB+&`P38 +MZ7%&"^__R7((=0^0[KC*(($/```T,\HA@0-T"N'WRB+!`P.^%2:`$P`@C@]$ +M`/#O#X8!X`^FP0"O]ZEPX'CQP.'%*'6*#:```-B!Y`.I0&!C"#_CT0(`O@`V%T`K_<,I?'` +MU@]/]PAUSW"@```@VX!`)0\8`(^IP1IQ$PA0`,W8((4&N+H)[_=&CP&%(H5` +MP`*/0\%AP`:%1L`%A4?`'(U%P`^5!""`#P```$!"(`"`RB!B`$+`T7$#A0H` +M(P!$P$/&B@P`#8C""'&+<"X-H``*/'`'@]/]PAVFG$:,]U1`!P[T`E$1E5)<$;.&`- +M#]X0(H`!X2*@"P_>$22``>$DH&T(42!%A8#BRB""#P``*#/8".+WRB&"!$&% +M4';*(((/```I,\0(XO?*(8(#0"J`(!1X,"$,(`KL$M@%IE)/`G@`'A)Z`!A1T. +M`1``A0.X%7@`(($/1`#P[Q>!`>"^#N_W%Z%`*H`@%'@P(0P@"^PBV`6ER7"* +M<0IRZ7-@?`HDP`0`WGD&;_?%I>!X\<#AQ0AR*'7/<```/3-(<3(/[_>I@[O]^'%SW6``!A%S@L@`*EP`=G/ +M<$0`<.\GH`4&;_>I<,]P1`!P[^!_`(C@>(P@PX_QP`AQ#/)#"=4",R9*<(`` +M4.-`)P!S%""``@!X_]C1P.!^`-C]\0'8^_$#V/GQ!-CW\078]?$&V//Q!]CQ +M\0C8[_$)V.WQS=@F#Z_W!KCH\<]S1`!P[T"#`-D-"($`C"##CP3TX'\H<".# +M`H,*N3A@SW&@```@.X$B>(#@X2#+!\H@:P#@?N!X\<"V"@```-G/<(``D$8Z +MH#N@T<#@?N!X\<`(<<]R1`!P[P""`-L;"0$`!8(3"%\`_]@`HHH@_P\!HF:B +M9Z($V!8(X```VC(/8``,V-'`X'[QP.'%"'(H=<]P```\,TAQG@WO]ZERSW%$ +M`'#O`8$`VAD-`1`%@14(7P#_V`"ABB#_#P&A1J%'H:EP:@C@``#9Y@Y@``S8 +MT01/]^!X\/'`%@Q/]QIP*'5(=VAVSW```$@SV@SO]PIQ@.7,)B*0 +MRB"!#P``,3/*(0$$\`VA]\HB00-`*($@-'D`(8`/1`"0[Z"@X:`Y!&_WPJ#Q +MP-(+3_<(=L]P```X,Y8,[_?)<<]U1`!P[T:%@.+*(($/```R,ZP-H??*(8$# +M_@H`#P>%@>#8#H$-`-@&I04$;_<'I?'`<@M/]SIP6G$:(0.% +M`>`#I46'@.+*(((/```C,S@-HO?*(8(#$FX4>``G%!`@%``@@.#*(($/```F +M,Q0-H??*(8$#"PA0(&,+GB$!AXP@_X\-\@"'`[@5>``@@0]$`/#O%X$!X$X+ +M[_<7H<"GSW"@```@&X`$'T`4`J?>"J``*G`&@!`?@!0#IP#=IJ>GIQ'8!:<@ +M%`P@*G!*<0IR:G-@?`HD0`40\`:%2G$!X`:E(=@%IR`4#"`J<`IR:G-@?`HD +M0`4`WEI^!X\<#AQ0AR*'7/<```.C-."^_W2''/<(``H#PP((`/```L +M"J1XP@F@&1#9V0)/]^!X\<#AQ0AUBB$0`,]PH```'2V@%@K/_Z8,H`BI<+4" +M3_?QP#8*3_<$WL]W@``@.P`G@!\``/@)SW&``*!$W*$!W4H((`"]H0`G@1\` +M`"@*R7`*#"`1J7)V"Z`(R7"""Z`(R7!A`D_WX'CQP.'%"'6*(1``SW"@```= +M+J#>"<__4@R@"*EP30)/]_'`X<4(=3X.+_Q$O`3;A5XQW"``.S)((`3"5\""(`/#0$0 +MSW@2#B`)_]D!YN$.%)0`V<]P@`"(*.$!;_4&Q0*G/ +M<8``+-`5>4>AX']"H?'`3@E/]X(D!#O/J+ +M<$X+[_<`V8#@$]@E\@84`#$E"!$"(L$H<(8@_`/`X`KT`=I6)``X*!B"`,.Y +M`KDI&$(`BW#)<1H*[_>I!`>)'H1T!;_>` +M)`0[X'CAQ6"!8(,`W##K!/!B>`'D_0L$@"&!H($6O!3JNF13(DP%D7#"(@X` +MR_?'!_P<7QP"X(3_<(=L]UH```(#N%SW>``)P+ +M'H=*(``@`GD=AR)X02B"`L]Q@0#X+A#@0+$0>*X*(`X*<%P`04B0,$+X7@1`*)``$ +M0)=TEPX/8`U3)`40"@R`#18,````VL]Q@`!8M@"!#R*"`TMX"/)&>`"AR7`R +M#:`$OA>!$#D=&)0PV#P=&)!$+CX7`"&`?X``1!;=!R_W`!@`!.!X\<#AQ0AU +MSW"``)P+`)"&(/P`C"`"@`O:>_2$+0$<`"&!?X``[!8`@8;H`8%^"2`$)8$$ +MZ`':;?#/<8$`N"X1B8?H$(F%Z)H((`6I<`/H`]I?\`0BON\$!`0$RB*A`%GR +MSW"``%CS`("`X,HB80%1\A=M%'C/<8``B*P(814(D0"$+0D?SW"``$`],"!` +M#H3H!-H_\(8@/<`)],]Q@``\#*EPX@_@!#Z)`^@&VC'PA@K`#A8-`!&`X,HB +MX@$I](0M"1\`(8!_@``@/7$0@0`C"5,`5Q"``(WH9@I@"ZEP"^@4;19XSW&` +M`-Q'`&$#Z`G:#_!$+3X7`"&!?X``1!8#@:H((`0B@8#@`-K*(B("1"T^%P`B +M@`^``$06)W`PB(#B`>$PJ`'8Q08O]\!X1"@^!P#9`"&`?X``1!8@H.!_(:#/ +M(0H`0P`V@`A@7^```@7X']`H>!X\<#AQ80H`0P`(8)_@`#L%B6B-H(O=3FB +MSW&``)S5,)DDHBB"[@@@`">B`-C'=8``#!<&K0>M!08O]PBM\/'`*@T/]X0I`0S/ +M'V>B?_>D);\`(8T/ +M@`#8S^"MSW6``*S/-7TFA?:D`>$FI32.>6$4X2=Q`*D4C@'@%*X4CL2X%*XV +MA(PA!("(]\]P```P$;X.;_=7A!T%#_>$*`$,SW.``"S/`"&`?X``[!8F$($` +M,J,E$($`SW*``&S/,Z,V@#"J((`QJCB`,JI&@"6`"PF%`")Z5:,'\`XB@`__ +M____.&`5H^!^`-D!VQ/PA"@!#,]T@`!`%R]R3&1B?,2\QW2```P7%.1*9%!Q +MRB&%``'CWPM4@?D%0`+@>/'`,@PO]PAQSW"!`-@N&H@`W0KHSW%$``B)"6&, +M(<./$_(7\,]V@`#P+0.&$0A>`O8.H`X`CHGH`([N\0?I&@@``-#@@_>I<`/P +MJ@^`#E4$+_,]P@`"@NP:`!""`#P```.#_V0\(7@//<8``/`PDB1L(G@// +M<(``K,T>@`\(10#/<(``/`PEB.!_*'#@>/'`C@L/]PHB@"^``#P,'A*`(`HC +M@"^``)P+C"`"@.7R`-U2#2`*J7'/=X$`N"XZ%Y`0"':*(0DO#0@0("8/@`X2 +M<,3T!"Y^%`'9`"&`?X``@#VUJ+2HL:BRJ+"HMJBSJ#6H-*C.#&`-R7`=Z$0N +M/A?/<(``1!8P($`.#^AX$PT@R7#I<>H+8!BI$H,@0(<#NW5[QW.``.S)`(/JNL\@H@;0(*$&T"#A!@"CJ;DCIU<)'@(A +MA\]U@`#LR40A`X,>$H`@$?(S:#5Y<"%"`X3CSR)A!-`B8@0Z#2`40*$>$H`@ +M`-D"\`'9`[@5>!UE`(6`X=`@(@?0(&('SR!A!P"E`X>HN`.GSW"``,`3`)`I +M"%X`SW"``$@5`(`.Z,]P10`T.`"`$0C?`\]P@0`8,[8)X!H4B'H)(`K)<"8) +MH`3)<,]Q@`!8M@"!A"X!'`\@@`,`H<]P@`!,%S`@00XB"&`,R7"&"*`,R7`$ +M+GX4SW&``"@[,"%`#C,($`'/<8``K,T0@0'@$*$1\`0N?A3/<8``*#LP(4`. +M$P@0`<]Q@`"LS0^!`>`/H04"#_?@>`#9#R$!`,]R@`!(&122*W@%]"5X%++_ +MV!JJX'[/<(``2!D`@(/@`=C@?\!XX'[@>`AQSW"``$@9'01@%@B`X'C/0A,/V`"FI0$/]Z'!X<7AQL]S@`"4&:&#!"6.$`#%C`3 +MC@`Q"8$#`]X+O@0B@0,KN:1^*[X=#D004")!!+*Y!"6"'P$``,"3NB5ZB7$' +M\`/9!?`"V0/P`=DU>SJ#`>$ZHT"@P<;!Q>!_H<#QP,X(+_>*(`\*D@K@#0#= +M"O`6#2_W!MC/<*8``,`+@$0@C0"$[6QPZP@>@,]V@`"4&2N&".WF#N_W`-@& +M#>_W`X8%\-8.[_<,V)8+S_?Q``_WX'CQP.'%SW&!`-A`!K@.#._W`&$*)0"0 +M!?26#<_W"'6)[<]P@`"4&>H,[_<$@`AUA>WF#L_W"'64[<]R@``4V`:"!(`@ +M@,=Q``"H85H.(!A(<`#9SW"``)09)Z`%\$X+[_>I<,]Q@`"4&3$1@``!X,6X +M,1D"`'T`+_>@H>!XSW.``)09,!."``#9"PB!``"#"PC0`RAP`O`!V.!^X'CQ +MP-H/[_83V0AV`-WAQ<]P@``\#%Z(SW>``)09,!>`$`L*`0`6#,_W@^@H=7/P +M_PX4E(MP4@PO]P/9`,%")L40*Z%";)$+*G1_2/"=X#BP@!`X,) +MWP)_")40>PI1`'<.U0`#AP0@@`\````8*[AG",$!"7!(<>ARR'.R">_W"B1` +M`K!PS"6.CP``_`=```T`SW>F``#`U*>GIR\@``)/(`$`0"]``B5X0"[!`@5Y +M0"F`$R5X"*<)AZ&X@+@)IU8+S_>F">_WJ'#'IPOP`,$&V`3P!=@"\`38'@WO +M]Q/=W@G/]ZEP+0?O]J'`X'CQP.'%SW6``+09,(T9"$$`SW"``!38?@P`&`X+ +MS_<0C8>X$*T1!\_V`-F>N1EYX\G@?R1X`-F>N1EYX\DF>.!_XQH8L`#:`KF> +MNAEZ0W'<$0"&1GC<&1B`\A(!MO3).07O]R5X`-F>N1EYX21XX1H8L.+) +M)'C@?^(:&+#@>/'`.@[/]N,2#K;)=R_P"'8M\"\MP1,3#547SW!$`!3RMG@` +M@(CHSW```/4.J7$2"&_WZ7(`V)ZXN7@&?\]PH```(#N`SW"``*@-(*#/<$0` +M%/*V>`"`0'BI<&H+H!F*(00`X\D'(+Z#T_75[SD&S_;QP.'%`-T3\,]P1``4 +M\K9X08!0=7A#527&0;/]N!X\A("MO02 +M`;9%>6D$[_<&(0``X'CR$@&V],E9!._W)7@`V9ZY&7GCR25XX'_C&ABP`-H" +MN9ZZ&7I#<=P1`(9%>-P9&(#R$@&V],DI!._W)7@`V9ZY&7GAR25XX1H8L.+) +M)7C@?^(:&+#QP#(-S_;B$@*V+RZ!$)WFRB"&#P``X@X8#R;WRB&&`\]UH``` +M(#N%SW"``*@-(*#/<$0`%/+6>`"`0'C)<'H*H!D`V8#8!QT8D%D%S_;@>`38 +MX'_B&ABP\<#*#,_V"'4H$(``6G';"!```Y7!N!,(4`#/<```43"R#B_W(H43 +ME0HA@"^!`*0/,-\O"!X#1H5!*@`"#WCL>``A3BX#EL&X$0B0`,]P``!2,(H. +M+_.QX&G``(4%T`Y'!N!,(4`#/<```+3!2 +M#B_W(H%5)L`4-@XO^`IQ"',`V1*&!?!`@`AQ2'`(Z"H3C``J$((`\0R#D%8F +M0!+>#2_X:'(#DT`E#A)&(,``@;@#L\EP&@TO^$IQR7`&"R```=F6#*``#(W' +M<($`X!LDB`'A)*A%!,_VX'CQP.8+S_8:<,]U@0"@&Q2%@.#*(($/```<,,0- +M`?<4A2*`*+DO>:X-+_A6)8`2"';B@"X([_LPV0%O#W@$)X\?````_^5X0"@! +M)B5X`J8SA0+P"'$#Z0"!_>A5)<`41@TO^,ER-(45A1!QRB"!#P``,S!L#0'W +M`Y9&(,``@+@#MLT#[_9`)@`2\"\_V&G#/=8$`H!ORA1;P*!>`$,"'D>@# +ME\&X@N#*(((/```O,"P-`O/'` +MP@K/]@AWSW"@```@VX#/<($`H!L3@`;PH(#2#>__R7&I`2X%'@`((T/@0"D#P.5P;@H=BD(40!"A5!SRB""#P`` +M*S!H#"+WRB'"`,]QH```(#N!@@WO_ZEP@.8,"@(`O0+/]N!X\<`^"L_V&G`H +M=TAU4@Y@#&AV"G#I<:ERP@P@%\ESB0+/]N!XS0$@``K8X'CQP.'%"'(H=31H +MSW"!`*0;(&"`X,H@@@\``!HP]`LB]\HA@@!^"R``J7!I`L_VX'@(<<]P@``$ +M_P"``-I!H'D!(``'V$$H`@)/>G1J='L`(X(/@0"D#R@2@P``V03K8H()",`` +M*'`(\`.2P;CY")&`+!*``.!^X'CQP*()``#^$`"!42!`@@'8P'C1P.!^X'CQ +MP(8)S_9(=D$H`@)/>@2Z5'H`(HT/@0"D#T`E`QB(BP#:!>R"A0L(``-(<"CP +MXY53)TP0]PR1D/,/'I&,B^\)`8.DOZF_\'^EOR2+J+_CM0L,01"6"@_X#O!` +M)0`2)@@@``/9$Y41"!\#)X4$A0JY.&`$I8#FT`@"``'8=0'/]IAQ`-DH<@D` +M(``H<_'`Z@C/]J7!"'5Z<>K)&G-:!`&%0"M/)4`H$01&":``#W@( +M`BY)7@\C04B`@0E>$3`SW#%[HR5`=D% +M(T,$0"R$`K8+(!D%)@83M0#O]J7`*'(/><]P@`"D_ET"@`G@>`]YSW"``*3^ +M30*@"0#:X'C/<(``4#(`@(;HSW"``$@R`(`%Z+D"[_\,V,7)@.#4!^'_RB!A +M`N!^`-C)!^__Q1H8L.!XSW"```3_`(`/@.!_`8#@>/'`M@@@`.'%"'7^$`"! +M4R!^@`ST(!6!$,]P```P,"85@A#N"2_W8851`._VJ7#@>"BXX'\/>.!XX'\X +MN/'`5@B@`.'%"'6$X,H@A@\``'$PJ`DF]\HA1@,$O<]P@0"D&QD`[_:@8.!X +M\<":#X_V"'9!*`T"KWW`Y``@C0^! +M`*0/0H45#H`0SW```!TPR7%J"2_W8Y7%!Z_VJ7#@>/'`M@_/_PC@T<#@?O'` +M0@^/]L]U@``$_P"%BB;_'X#@RB"!#P``-3`4"0'W((4.@03H!Y`)"!\`R7`< +M\`^!!>@'D!$('P#/<```4##R"`_W`(4/@`;H)Y#@N=$A8H#N]<]QH```(#N! +M`8`B>$@@``!-!X_V\<"N#X_WN@]``-'`X'[@>/X0`('@?X8@_PO@>,]T@``$ +M_V"$`-EA@P':#PL.``:$C"##CP/T*'`"\$APX'[@>/'`U@U``!,(4`#/<($` +MX!L'B`L(4@`!V`+P`-C1P.!^\``@@0^!`*`/!9'! +MN"$(40#0B1$G@)/*(((/```;,$0((O?*(<(#Q@I@#,EP`>7`Y:;WH0:/]N!X +M\<`J#H_V*'8:XEA0T.01#I=NEQ(?`*N5DE#Q(?ETHD0`'% +MI4HE0``K"!\!SW"@```@&X!"A4`N@Q(B>GEBF2`$`/8.(`#)<@*E'Y>+N!^W +MJ':(<1<($"`&A0\(``08'0`412&!`0'>@.:T#.+_RB!"`Q4&K_;)<.!X\`2X%'@`((T/@0"D#R45@!`)Z,]P``!R,,EQ8@_O]BX5@A#/=X``!/\` +MARZ`)^DCE0D)7P*BAP/PL(`:=03P((4:=2AU".TBA?<.09`FE>.YRB4A$(/M +M`-A!\""%#X`C"0$`5@Q``(WH`(`\(A0\'``#P`=@O\`*'/0T! +M$`>5AK@'M0*'@.#*(($/```],-0.P?8"AP"`<@ZO]P*GLPA1@,]QH```(#N! +MSW"``-@:[@K`%\_Q`(=0@""%"PV!$#"@`_``&$`@`-[`I4X-(`"I<,EP`06/ +M]N!X\<"&#(_V&G`H=CIR`-\*(X`O@0"@&T@3#2`<\`.%`!42$"\(`00"A3BX +M$';_W,PF`I,/]`.5P;B"X,H@@@\``#$P2`["]K8-[_<"A05_2G7F[4P3#2`; +M\`.%`!42$"T(`00"A3BX$';_W,PF`I,.]`.5P;B!X,H@@@\``#(P#`["]GH- +M[_<"A4IUZ.U,(0"@S"_VR7+//'`?@N/]L]V@``$_R&&"'<"@0T(T```A@"``*&"#\__ +M`(:A@.=]!O"B#(_W$"7-$P_M+RA!`TX@CP<`AN]_`8`1(,"#Z7#R]2X,C_?P +M\9T#C_;@>/'`!@N/]AIP"B*`+Z```"!L$A@@ZA(!M@#8\+FAPIPB`!:X(0``AA0AR)'@0<@$$P$@`H'2 +M<,HE0A`%\*EP2@D@`,EQZLD;"!X$;!(#(,]PQ>Z#=P(C`P8!V8X,X!CJ/'`G@B/]AIPSW:```3_`(8!W2Z` +MXH`/Z4>1&PH>`$*&$PF!`%"`!^HA@4#@S@CO]ZERSW"``&@RH*``ADH((``* +MV@FO_PS8,@WO_PIP(H`A"8`#'0]!$,]RH```(%N"`X"6(@@``GJ`XLHE +M*1`/"8$#SW"!`*`;$H#DZ(D`K_:I_V0($.A0?H\@^O]\EQ +M`-@.I0^E$(4&Z.(/K_?)<0#8$*7_V#D`K_8"I<]R@``$_P;H(H`FH@"`!?#_ +MV`:B`-@%HL]PH```(!N`"*+@?PFBX'CQP)H/3_;/=H``!/\#AH#@RB"!#P`` +M.C!P"<'VHX8`A0.FJ7#F"V_[$-D'E8"X![4`V`"EU0=O]JEPX'CQP%X/3_8* +M)0"0)_+/=H``!/\DA@#8!NE`@8#BRB!A`(?HSW```#@P-@GO]D"!!(:@H*2F +M$/`'E>"XRB"!#P``2C`4">'VRB%!`P>5H+@'M:2FH(7Q[7D'3_;@>/'`U@]/ +M]^(.C__1P.!^X'@"($,`%PM2`!,*E``$\$`J@P)Y83!P^@?/_^!_*'#@>/'` +MT@Y/]F^0"'8H=9<+'P,D%H`0/PA1``.&'>ABA@JX>&"6(`0`HG@_N%(@`(`) +M]""&SW```"4(([_:I/'`%@Y/]@#>"B"`+X$` +MH!M($`\@>G8)\`#95B!`(L(/K_?I`BKN(I`A!9)@\2'Y=;")X!SW"!`*`; +MH)Z"PI2`*)Y)*,OEK\)'X.LN!.SW?%`AD$J#0*O?<#E +MRB"&#P``9C`$#Z;VRB%&`Q^7%PB>`JJX'[?/<8``6!(`@6&X`*'/<($`Z!LN +M#Z_WJ7%N#2``!(['<($`X!LDB&&Y-05O]B2H\<#&#$_V"'7/<($`H!O2@!OP +M`-H%AB2&"KAHACA@0"N,`IA@6&#'L;QK01/]N!X\<`.#&_V%-FJ +MP?IP2B$`()8(;_N+<(7`C@AO^Q39*G(1\(0J"0\`(8!_@``@/2B`$0E1`&:` +M,FJ#<0>`8*$%H0'BXPH4@<]P@0"@&]*`"B!`)%KP"PD3```(#^X4B``@`3R`"$`!0*E`H7B>`*EJ7!."J__!-D^$P`A +M%P@>`2*%`B'!!0L)4@"(N#X;!"`/()`DP(8O[A.6^PA>@P.6#!:2$`\(W@*K +MN`.V#R&1)$`J@"!P(`$'A.D%@&WHA"H)+P`A@'^``"`])X!&@$`F#1)98005 +MEA`%A1<),@!`*)0"*'>2=P`'S/\")P\5^_$S?_GQE@B@#`4A`"0*<.H)(`P! +MV>4";_:JP/'`M@I/]@#="B"`+X$`H`^I0`@ +M0"!#H"P80@,PX4`@`B%982&@*6LDL`'CP..J]P@8A"\``/__SW"!`"`;M:#/ +M=H$`H!L`WPGP-&\$;CA@S@XO^Q#9`>?U#Q21LJ:SID`@`"$4ID(F`!NA`F_V +M%:;@>/'`-@IO]@#:SW>```3_PX=(=1#P!Y8!Y>"XRB""#P``>#`0#*+VRB&" +M`P"&R7((=O+N!(<0!`!$%`$+`"($$%0000\`D$8``$+M$P`:!97I%P,]PQ>Z-E`'9 +MR@R@&&*%_0%O]J;``=HD&((`X'\\J.!XSW&``'`;`K@4>.!_`&'@>/'`X<4( +M=83@RB"&#P``@C!("Z;VRB%&`\]Q@`!L&Q)M%'BY`6_V`&'QP"()3_9*(0`@ +M*G4$\$HA0"`!Y54-%1&*"2``J7`:G#O"`"$BB`)#PQ]SW:``"@[6G`P +M)D`>BB0&*-<,#J#A;<\/59%:"2``Z7`9",`$!"^^%#`F01X1)$"@S"`"A-?U +M`>?P\;X-H`0J<`T!3_;@>,]P@`!$&QJ`@N`!V.!_PB`.`.!X,F@T>0`A@`^` +M`&@;X'[@>,]R@`!$&U4B007P(0$`0"(`"@*Y-'G@?R!@X'CAQ0#%A@@*`!X_4+%($$V`2A`]I(H5*A$-@3H52AX'_!Q>!X +M#WH9"C4!`-D"NE1ZSW.``&@;0F,)"(``*'`#\`'8X'[QP.'%"'$/?87ERB"& +M#P``"##H"8;VB@DO^ZEP70!/]O'`X@\/]@AVBB7_'X7@RB"&#P``!S#$":;V +MRB&&`P#:"_`2:A1XQW"``$0;*H`)"8X#JX`!X@T*%0&,)?^?\_,1`&_VJ7#@ +M>/'`X<4(=87@RB"&#P``80#`*.8!?`FF]LHA1@,:"2_[J7#Q!R_V#WC/<8`` +MG-\@@>!_\"$``.!X\<#AQ0AQ#WV$Y.'`X<&*(/\/$R#``@1Y`"B``@`I@0(&)`P0)7S!P>!_P<#@>.'$\<#: +M#^__@(B`J`04'S3@?\'$X'[@>.!^X'C@?N!X\<#&",`-SW&``&`/&P@?`,]P +M`0!(.P"ASW%$`'CT$X&%N!.A!?#/<`$`(#L`H='`X'[@>/'`X<6.".`-"'5! +MA>"X(X+/(:(#SR'A`YT&+_8CHN!XSW"@```?'(#@?\"XSW"``#P,9(@EB,]P +M1`!8]DB`SW!$`!3S\""``#A@$',!V.!_PB`-`.!_`-CQP.(-#_8(=L]P1`!X +M]!.`SW>@```@`-T7"-X`SW4``$(8BKZ+ODT?F)\```!`#@C`#2$('P"!O8J^ +MSW&@```P"X&+OI^X"Z%-'YB?````0.P7`)"E>.P?`)!V%P"6Q7AV'QB0Z04/ +M]L]QH`"`'409@`\>````$X&%(`P`$Z$5@;FX%:'@?N!X\<#AQ<]RH```'3@: +M@`\```!`SW5$`/CSS!4!$`#;`-B.NPT)W@`#V`JX;:).#\__#@L@``#8X@P@ +M"Q"-Q@P@"Q2-U@K/_9$%#_;@>/'`X<7//1;@RCJ!-K/=:```"!.'9B0 +M`-I;HP\(D0#N"^`.*'`#\+H+P`[/<8``P`@`@5`@0(0`H1#TNX4`W`GP08$' +M@0'D6&`'H7IB2*$-#)42:('M#<60+04/]L]S1`!X]%N#+0I0``3!4H.S_^!X,H@80#P":$.RB$A`!#P%X4`WIJ^&PB>!L]P +M@`!,"0"`!^@B#L__@>#0#0$`V:6A!`_VX'CQP!H,#_;_W<]P@`"H)[>HC@P@ +M"P_82B%`(`H@@"^@```@2QA8I`#86G#/=Z``@!\+I\]V1`#X\\]Q1`!X]+*A +M`]C@'@(0XAY"$P+8%Z$?H1VA'J'^"2``0!X8$((*``MS&)BD`-@B"R`+"'$P +M'X`?\/#P\'`?@!_P\/#P=!^`'_#P\/!\'X`?\/#P\.(+``!^"D`'SW$!`/`] +MK@_@%`#8&@X``'080*0$&$"D`@[/_\8)S_T&#<__H:;R#"``HJ:Y`P_VSW!$ +M`'CT$X!3(`$`";GAN,\AX@'/Z5[>AK8@,]T@``4"6*$X(3$>^1^I7MBI,5]H*3//1.&EB`&:,# +M\$T:6(!`((`BQ@@@`"IQG0(/]O'`SW)$`-CT(8H3"$``2@]O]P&J@.`P#\+_ +MT<#@?N!X\<#AQ0HE`)#,)6*0!O3/<$0`_/1""0`+SW!$`-CT?0(O]J*HSW)% +M`-`B%7K@?R"BSW$```__S0/@%`#8SW$```__-0;@%`#8\<#/<$0`<)+L'`BP +MSW!$`*"20<#/<$0`F))"P,]P1`!HDD/``-M$PPG8!MD-V@HD@`]$`"3S"B6` +M#T0`+/9*)D`-T@K@"$HG0`"EP-'`X'X($@J""(SW!$`/CS`(`3"$4`BB`(`-(:&+"* +MV)"X!_"*(!``TAH8L$+8F+C@?H#@S""B@`?T`=B1&@*P`-@'\!,(T0``V)$: +M`K`!V)(:`K#@?L]P@`!(N@:(SW*``!0)'7A3(`$``(*@N"5X`*(5`*`8!=C@ +M>/'`D@@/]L]R@``4"0*"((*DN(.X1B$!!B"B`J(`V<]UH`"`'3JED!I"L`'8 +M/:5&#^`*D1H"L,]Q@`#`"`"!SW:@```@D+@`H<]P1`!X]!.`$PC>`!6%N;@5 +MI4X>F)\```!`%86UN!6EF0`/]O'`SW*``!0)((("@J.YA+D@HD4@``;J#^`* +M`J(!V)`:`K``V)$:`K`#V,]QH`"`'1VASW.``,`(`(//`),:0K,$\),:@K-.#N`*`=C9!\_UX'CQP.'%"'61RPWH +MDLN`X,H@@@\``/T!RB&"#ZW>[[X\"4+VD!JC +MM!$`@!<(GP,=@PGHAB)_C@GR%PW?$HZ]!_"T$0"`"P@>`*N]^?%1!^_UJ7#Q +MP,]Q@``D"0&!%P@?``"!AB###P"A.@Y@&`G8`_``V`"AT<#@?N!XSW&@`(`= +M!^A(&8`/@`"```7P2!F`#X`````3@8RX$Z$5@9JX%:'@?O'`SW&``$P)`($' +MZ`'8`:'*#^__`-C1P.!^X'CQP,]R@`!,"0""$>AA@@#9`=@+"U$`(:(#\`&B +M*'"B#\__`=C:"V`."''1P.!^X'CQP%\(40"&"(`-?0@?`,]R@`"LOP&"#>C/ +M<(``P`@N@,]PH`"`'RR@/*`]H#^@`((JZ,]P@`"<"Z00@@#&XL]Q1`#X]4KV +M$(`1"%X""!F`#PP``P#1P.!^`-@"H?SQ+@B`#24('P#/<$0`^/.(@&F`2H`K +M@,]PH`"`'XR@?*!=H#^@ZO'H\>!XSW"@```=-!B`#T`````X&(`/0````,]P +M@`#`"$&`R\F"(A0%@"`"`'B0*(!P``0`0!F`#Q\`!@`3@44@P`P3H94%S_7QP!X-S_7/=8``P`B`A:<(40"@ +MO("EA2F3"'IB+W:%*DD,`"&/YQ2!!`-`@X@70("(&%:+@?N!X\<`2#,_U"'7/<(``J"<:B!$(7@#/ +M<*#^S`2:#*`'`-E&C<]S1`!PD<*Z0*,'C<]TK0"``,*X`:,BE<]VK0"`'R*C +M)(2&(7``(KG"N2:CLX8TAF$*%0(S)H)P@``8XT`GCW)4?P!_KWHC\`0E@A\` +M``#_*+H=\`0E@A__````,+H7\`0E@A\`_P``$O`O>A'P!"&"#P```/_M\00A +M@@__````[_$$(8(/`/\``#BZ1*-M"!4",R8`<(``(.-`)P)R%'H`>J]]I:,J +M\`0EC1\```#_*+VEHR3P!"6-'_\````PO:6C'/`$)8T?`/\``#B]I:,6\"]Y +M$_`$(8$/````_RBY#?`$(8$/_P```#"Y!_`$(8$/`/\``#BY):,!V`.C!(2` +MN`2D$H:`N!*F$H:!N!*F$H:"N!*F#@D``$$#S_7QP-8*S_7/<(``J"<:B`#= +M$0A>`,]PH/[@!%H+H`>I<<]V1`!PD<]QK0"```2!1H9&(,`'!*$$@0*Z17@$ +MH02!H+@$H<]QK0"`'Q*!H+@2H1*!H;@2H1*!HK@2H<]P@`#XV4H(`!?A`N_U +MHZ;/<:T`@``$@:"X!*'@?N!XSW*M`(``)((&N("Y)*(D@H8A`P`DHB2")7@$ +MHN!^X'C/<:T``"``@:"X`*'/<:T```0(@:NX"*$(@:JX"*'@?L]RK0``!"B" +MB[DHHBB"BKDHHL]QK0``(`OH*PA0`!\(D0``@:&X`*$`@8*X!O``@:&X`*$` +M@:*X`*$`@8"X`*'@?@"!@;CW\?'`T@G/]<]U1`!PD0>%P85`A0;H`-@'I66% +M"/`!V`>E9(7)<$AV"'+/<:T`@!\2@0F[!""`#_[__P$2H1*!!7MRH<]P@`"H +M)QJ(%0A>`,]PH/Y$!`+9&@J@!\ESSW&M`(``!($$@0*^J+BLN+"X!*$$@02! +MSW*``/C9!7[$H02!`-@BA0\@0``88":"%7@D@2"!&6%F#^`62'"I`<_UX'CQ +MP#()[_4`VL]V@`"<"P^&(0C>`L]P@``@1QR`0!:!$,#=)'B&(/\.(K@:?4AP +M!/`4W0+8N!8!$0)Y$(8$X7X-(`<`VL]Q@0"X,AJA'8:YH1NA'H9-`>_U'*'@ +M>*'!\<"V",_UJ'0H'$`Q6G"X<1IR.G.(=0HC@"$$)(P?!@```$$L510%*'X! +M"B#`#B2X`2A`!4%H*!04,$`HA"`5)`0!"B6`#X``I.X4)$$$,B5#`QT,'B+/ +M=(``U.XT9(Q[`"E,=04J/@-"=`<)!7-(<``H4`49#)XFSW"``-3N,&`,>P4I +M/G0*(D`NSW"``,#L,&#/=8``>.QL>`IPBB$*`@4I/G`O=@'8)PFD`Q0E313/ +M%@L/A!-4E27P*0Z$4@A#`"99#5Y0G@; +M"$4`SW6``+3L,B5"%'5[!2H^`PT+1`X4>!<(10``)0`D0"!0``L,GB8#V1D; +M0B!1)("FRB$"!,HA(0`<&T`@"G`(W&<'C_7@>/'`(@^/]80H"0\`(8!_@``@ +M.R@0!@``(8%_@`"@/)AQ0"$%!D`A!P=1)L"`BB((`,HB(0!=L0#=$?#/=X`` +MI.VO9\F`ZV-D?G*!Q'LO*\$`3B..!\MD<*H!Y5<-%1+I@,]S@`"<[:ICSW2` +M`#3O1'\O*L$#3B*.!\YD`"1"`\"JTX'D?B\N@1-.)H\7[F3(JJL.WH!H@(;E +MTR.F`"\KP0!.(XP'SW.``,CIBV/5\0#=$?!I@.EM@.7*)T$3[F;$>]*!Q'LO +M*\$`3B..!\MD<*H!Y5T-E1))@,]V@`"X[:MFSW2``#3O9'HO*X$`3B./!^MD +M`"=/`V"OB\J@0!.(H,':V1`)`((NF)FJJ<.WH!H@(#ETR.A`"\KP0!. +M(XP'SW.``,CIBV/3\0#;%/`H@,]R@`#$Z6IB`"7,`$1Y+RE!`$XA@@?/<8`` +MR.E)80'C(*S="Q2!-0:/]?'`N@V/]0AVD(C/<($`&#\6(`0#SW*!`-@_EGI` +MB@`4`0$`V!$*7P'/`P:%!""%#P`` +M`!@C#8`/````"`PE@(\````0RB""#P``/!7*(($/``"P!`/P2]@%N!!QRB$& +M`'X6`A$`E6*56&!X8,]RH```(%J"+.`0E!QRB"&(!B5RB!%(&3@ +M$'(\`0X`SW"``.S)`[R5?(!@2B(`($$HP07"N66Y2"$/`#.XPK@-X`\B$B`# +M%)$`!H6F#:`,"G$)((`$`^!!*)(`!H62#:`,!-GX>`/@!""`#P``_/_/<8$` +M-$8#H0/@(KC/HG0:0`38R2RXQ+@8N$\@00`>HBQP`0B>!<]PH`"`+%R`ZLDK"-X`SW.@```@SW"@`(`< +M!!B`#\7NA#A[@V&@(:!`*`$B0:`%(4$$(:!!*@`%4R"0`5,B@03/=8$`-$;/ +M=X``+,X"N54*G@=1")0@`)80X$D(10`@I0@=`!28%@`0K@@@!T`E`A0!I>P6 +M@!`]AR@=`A#J%@`1$[4?AP'@'Z<`(0`$':?9R0V`#0A>`*7-H;BE&ARP`=@. +M\,]Q@``LSAZ!`>`>H<]P@0`T1@'9(J``V"$$C_7QP.'%`-T,\!)M%'@`(($/ +M@`"HW+X+;_T"V`'ESW&```C=`('E#020`-@=!*_U`*'QP)H+C_4(=L]P@`", +MJZ"(`=_2"6`-J7"`X,PEXI!L\L]QK0``&$,1``93(,"$S"""CP\`___*(,(# +M`_0`V!CH0Q$"!L]Q@`#4I@&!T[H1"B4`0Z$"@1!R`=@#]P#8C>C/<(``0#(` +M@`L(40!V#@_W0O`!V$'P*NX`W`/P`>1Y#!42SW"``,03\"```WW9!;D"($,` +MZ0N%@#A@Y0H%@,X-(`VI<,]QK0``%A$(4`#/<(``@!,!@(OH`H'PX$#8RB"" +M#P``<``"H1;P"X$$(((/!P``P-=R!@````':PB*!``ZZQW(%``#`!""`#_C_ +M_S]%>`NA`-@1`X_UX'C@?N!X\!/*`X8#FRB$"`(PA%(L,V,H@Y@%4]XPA48?*("8"4/>, +M(0Z!RB!F`DKWC"'*BLH@I@)&]XPAB8?*(.8"@>7"(*$`R2#A`0?R@N7"(.$` +MR2!A`1!XSW&M``">`!F`#P```'@+N,]QK0``7@"ASW&M``"H0!F`#P```'C/ +M<:T``&@0H3D"C_7@>/'`O@F/]<]W@`!4@AZ?SW6``%2!)84B>"\@"0`E")(' +MSW:``(RKX@\@#0".`=D'Z`".@^#*($(`!?0>GR:E!:4`V.D!C_7@>/'`%@T@ +M#>'%]@^`#\]U@`!4@<]Q@`"$,R"!!*4@B0L)TP,;>`2ESW"``%18`(`9"-X& +M!H4%Z.(-#_<`V`:ER@P/]PSPK=@0N$P8@`^4$BFE8!B`#Y02*:6F#``-F@[O +M_P#9D0&/]>!X\<#AQ<]U@`",JTX/(`T`C03H`(T;"-$``=C/<8``5($&H<]P +M@`!4@AZ8!:$+\((-#_=N#`_WSW&``%2K$XD!X!.I=@D@!QO800&/]?'`P@B/ +M]2X,``U"#"`-"'4%[<]V@`!(?0OPSW&``%1^"PB1`$`A#@L#\%DAC@//<(`` +M5%@`@$`F`1QG")X$`-H)\/`F@Q#/<*8``(15>&"@`>+S"A2#`-H)\/`A@P#/ +M<*8``(A5>&"@`>+S"A2%@!8-$H&&8H8#AB2&18;FAL]VI```1**F2J:%IF:F +MZZ8'IBBFSW&``'2K"8D!X`FID0"/]>!X\<#/<8``-*D6J?X((``!V-((``?1 +MP.!^\<#^#T_U&G#/=J```"`;A@#?R-@6#Z`'Z7'/<*<`7$0@@,]U@`#4J#FE +MR-C^#J`'Z7'/<*<`9$0`@.8((``:I0HA@"^``%2HA0@0(#F%&H4X8"6X`_`! +MYQUX_P@5B,]R@`!8WR*:]2(```4I_@,G<$#@)K@;I8(@@0X``#2I&"!``$.X%*\;A>[@RB`M`P7W"0@5#R/8%*].#&`!`-@?I<]PIP`` +M1!Z`SW&``'2K01D8(!N&!HD!X`:I6@M@`!2/E0=/]?'`_]G/<(``-*DVJ!(( +M(```V-X/P`;1P.!^X'C/#"`"`=B6"@`- +MT@P``LX+X!8!V-'`X'[@>/'`O@Y/];[!SW"@```@&X`!W:8*(!"I<&H*(`T` +MWXX,(`*+=MX+(`+I"2`"R7#/=J<``$BMID8/(!"I<,]PK0``:@08@`\" +M````SW"M``"J!!B`#QP```#N#0``@.#*(($/``!``,HAP0/*(L$#L`AA`/'`SW"``(RK((@&"2``*'#*"R`-*'`(Z,]Q@`!TJP2)`>`$J='`X'[QP%(- +M3_7/<(``C*O@B*8+(`WI<`#>&.C.""``Z7`(=4`@$@*."R`-Z7`.Z$`E%!@: +M%),@FPLR(D`D%2;/<8``0!\`@8L($`#`H<"EP:7)=\EPR7(+\%EE.(DX8%EE +M*!&!``"E/V?AI0'B[PH4A"\APB0BMBH`"75(``=@B,XB%EA22'!`#BH +M`-@'\!EEV*DH&8(#`>#Y"!2$&AR"(\]Q@`!4JP6)`>#-!&_U!:G@>"$'S_^$ +M*!8)`"&`?X``%&S@?N!X\!X\<"Z#L__C@[/_\(,X`8-V-'`X'[QP.'%@^`!W<(E01-*"B`- +M#WB`X`#8=01O]/'`\@M/]<]P@`!46`"`SW:``-2`10C>!0:&(.C/ +M=:```#`('8`?````H!H)8!@>V!()8!@>V(()0!/_V<]PH@"`>2N@#!V`'P`` +M`*#V"&`8'MCR"&`8'MAF#R`0!X8%!$_UX'C@?N!X\<"""V_U#-C/=X``C*O_ +MV48+X!=`C\?)@.#*(($/```("5@-@?4`W0/P`>6P?6L-%1+/<(``*/(6(%`# +M`!`.(,?)ZPB.@Q#8R7$."^`70(\$$!`@%0@1(,<2`;;/<```CQ,J#:_UR7(* +M<$!XQ\D0(("#QQH8L$"/"/0)V-H*X!?)<;(,;_X'V!'8R7'*"N`70(_'R,]QK0``&$`1`(:G +MN$`9&(!C$0"&A[AC&1B`X'[QP.'%`=U-"%$`SW"``%18`(!!")X'SW"``(`3 +M`8`U"%$`SW&M```88Q$`AJ>X8QD8@$`1`(:'N$`9&(!Z#\_VSW&``'2K%8D! +MX!6IJ7`%\)8/S_\`V-D"3_7@>,]QK0"`%0.!A2`"`0.A`X&BN`.AX'[@>/'` +M0@I/]0#=>@_@`:EP8@[``,]P@`!4@CZ8SW"``)2J,+`5\``ECA^``$P<_@_@ +M`0".`(XF""`"`-GR#.``J7`"""`"`(X!Y:]]W0V2D38/X`$!V%T"3_7QP,]S +M@`#4J#:#SW"B``!PBND($`&&$0D?`,]Q@``L+2"!">DW@UB#"+E%>9^Y0AA8 +M@,]P@`!46`N0$0@?`2(.`!.`X.P+P@[1P.!^M0?/__'`SW$!`(1_]`-HN""```=C1P.!^\<#/<8``5%@A@>^Y3`G"_\]P@``TJ7H-(``4 +MB-'`X'[QP.'%"'4#V*(([_TGV<]QH```(#N!(J`%V2:@BB%>"".@`]CF"._] +MJ7&I`4_UX'@G@,]RIP``2"NB*(#/(*P`$V#0``$0%/]?'`X<4`W0OPSW!$`*"0MG@!@(#@XB`"``'E\0U4DLH) +MP`;U`$_UX'C/<(``.!P`B(#@`-@,\L]P@`",JR"(SW"``#2I%H@0<0'8P'C@ +M?N!XSW"``#@<`(B&('\/@N`!V.!_P'AY!P`!\<`R"&_U_]D(=@+8]@^@%\ER +MA"X6&0'9`"&`?X``6&P@H%X((`#)<,]U@``\'`"%!^C/<(``.1P`B"4.`!`` +MWPOPSW"``&CR\"#``X#@XB`"``'G\'_O#]22!/!B#H__`-@`I?_9SW"``#D< +M(*@#V)(/H!?)"$%S_;QP+8/+_7_V0AU!-AV#Z`7J7*$+189`-D` +M(8!_@`!8;""@SW:``%18`8;LN+P,H@#*($(#`8;MN/`*XO_*($(#!=C_V3X/ +MH!>I/'`9@\O]0#:"'6$*!8)`"&!?X``C&M`H0`A@'^``%1L((@! +MWH'APB:!$T"@,@M@`*EPJ7#N#2`!R7&=!P_UX'@]`T``\<`.#P_U<@X@`1IP +M"'5(@)2`"B.`+X``C*L`$X`@BB(6*00HO@0*(8`O@`#4:T`A`"XP($,.6F)4 +M>@`CA``"%`$!G&24?)ACRI!3(04"";[/<0,``/XD?@4EA0//=J<``$@<'D`1 +M`!0/`0F0R+\)N"1XY7@=IGIB`IJ;8TN3R+@)ND1Y)7@&IC8*P`QHA0`3@2!` +M(``J!"F^!%4AP28::4&+_4AH.!X\<#AQ0HE`)`)\C(/K_\`V$(/K_\`V`(/@`8V#J__J7"" +M"``!U@Z@!@_8I08/]>!X90>/_SD`S__@?N!X\<`:#@_USW:``(RK((X(=8PA +MPX_*(((/``#*$_0/0O6.#>`,J7"@K@#>#O#/<(``:/+P(($#SW`!`+A/$''B +M($(``>;I#M22`=G/<(``/!P@H,]P@``Y',(,X`R@J"T&#_7@>.!^X'C@?N!X +M\<#'$@*V"'$/(@``QQH8L)7JSW*``(RK"-AB#:`70(K:#N`+!]B`X,H@@@\` +M`(T3;`]"]3((;_X'V-'`X'[@>/'`Q!("M@AQ#R(``,0:&+"5ZL]R@`",JP;8 +M(@V@%T"*SW$!`(1_]`-KB"^__`=C1P.!^X'CQP"X-#_4( +M=0#>#R8.$,?)RW@2\@8@@(/'&ABP#/3/.`((@#*($(#704/]?D`S__QP$"`SW&``%180*$!@&X.8`/'`H@PO]?_9.G!(=<]V +M@`",JPK89@R@%T".:PU1$`#=`_`!Y;!]50T5$L]P@``H\A8@4`,`$`\@Q,GK +M",Z##MCI<3H,H!=`C@00$"`5"!$@Q!(!ML]P``"/$U8.;_7I<@IP0'@/V.EQ +M$@R@%T".+@@@`.EPQ,G7Z`/8F@^O_2IQ!/#6"N__`-@+V/_9[@N@%T".=00/ +M]>!X\<`(<<3)$"!`@,0:&+`,],]R@`",JP?8R@N@%T"*F@RO_0/8T<#@?O'` +MK@DO_Z'!SW"``#2I%(A`P,]P@`!(%0"`@.#*(`$'RB$A`7P,H1/*(J$"H<#1 +MP.!^X'C/*40:@#UF*T.``VP` +M"/"TX,HAJ0`$]HW@RB%I`#EA-'D`(8`/@``(J>!^X'CQP'(+#_4*#Z`,`=Z^ +M#\__S@Z@#`AU@>#")H$3R7``V?H-X`]`C`/08W)<`#9H@S@#T2- +MR7`!V9H,X`]%C0#8_@C@#R*-`=CV".`/(XV-`P_USW"``'!4`("!!^_YBB$, +M"/'``@L/]0AV&G%(<,]R@`!46""":'<-"=\`(8);"=X`A"@6"0`AC7^``%1K +M+86EZ:8-@`R$+\(:+W$C"%$`#H5,(`"@P""A`<`@00#`(((/``"R`L`@0@`& +M\`Z%$P@1(`;@.&#)<;8/8!0(VACP@""*##A@^/')<`(/[_D(V?H-@`S/0T(40#U(L`#!?`*X34B0``"KLT"#_7QP%(*#_6^P3IP"B!`H'IRSW:` +M`-Q6`:8!WP#=`_("I@;P"PD1(.*F`O"BIL]QI0``#`2!"B2`+ZT```"$N`2A +MBW""".`!6G`BADC'088`V`\@@`!$P,]RK0```QB"0\'`N$_`&(*`X88@_PLD +MN%'`&(+&(($/___W_\$HX0#$(((/````",$HX@)&"F`/3L!-P`B&5L5`Q5/% +M!>@"V$?`%O!'QQD)$2`-"!$@`]A%P$;'#O`%V$7`1L4*\`L($2!%QP/8`_!% +MQ0781L!)QT@*#@?O'`-@D/]0AU*'>."Z`,&G(O(0<@SW;__P"`]@N@#*EP@>`!VL(B +M@0"#Y=$A`J0$],EP-/#/<8``5%@`@0L(WP`!@4D(W@"$+189SW"``(AK,"!` +M#IKHA"T;$$P@`*`O<80OPAHO<,`A@0]%`$`'P"&A`<`A@@]%`.`)P"&B!!EA +M!HE8Z`*)"O!88A5X]'C/<8``C*`U(0```0$/]?'`X<7/<8``5%@G@03H02D` +M`@3P02F``L&X`]W>"J`,!GW]`"_UI'C//'`0@@/]<]U@`!4H%8E`13/<$0`5)0@ +MH,]Q@`#LH<]P@`!P5%IP(*#/<8``5%@!@2\(W@``@:.X`*'/<$0`>*#/<0`` +M]!I^#,_YSW!$`%B48=ER#._Y!;D`V!:U6/`6E87H`(&CN`"A4O#/=T0`./?/ +M<$0`7I3I<:O>Z@Q@%,ERSW!$``J7Z7&`(<(*U@Q@%,ERSW5$`#CYSW!$`&Z: +MJ7&"(8(*O@Q@%,ERSW!$`!J=(6VR#&`4R7("W2+P"FT=>(0H%0G/__P'@-\""JQ@IO^A090B,0'@`4(!,`(`L(D0``V"(,0`QA +M!N_TH<#QP.X-S_0(=RAP-@B@#.`<2+`:<-((H`SI<`'90<&!X`'8PB`!`$+` +M2B<`((#@`=A&#>__P'B$+Q891,`*(H`O@`!4H,]S@`!,:R]P`L)`(@$L\"&" +M```@C@^``%1K@^?,(B*`"_0!P1MC(*.`XBVF=`XA`,H@P0/)\(?!K@M@#`#` +MM@M@#`#`A"\;$$/`SW!%`$`'`"!3#FIQ+J8*(4`^*!(!(#0>P!6`X``#=&W4%\$H@0#`!Y=,-E1`$P/D(3H,` +MP#8+K_:I<1IP)\&*)(4E"B6`+T0`./=`)4`@1L!`)98AA"W"&B,(U`(X$A!O#/<$4`\@D`($$& +M`")`!98)8!2KVB@2`""8Z"?`!L$$*#X%`"%`+@AA30@#A!)O%'@,V<=P@`"4 +MH"BP)!(!((3I*9"`N2FPF/$%P`&`X[C,("*P$O(-AI#H,F\T>0S8QW&``)2@ +M"+$"P(CH)!(`((3H"9&`N`FQM@ZO]NEP+![`%3`>P!4I!._TJ,`R:(0H%@DT +M>0#:QW&``)2@2+%)L0`A@'^``(QKX']`H/_9SW"``(@SX'\@J/'`L@OO](HB +M!@R")`G0Y5D0#?")4/)X\3"W]*)0`@ +M!/0)E0M_)?+F#6`,*G"!X$H@0"#"(`$D`-BJ#&`7"'')<%(@`2`J<@#;5@FO +M]@`4!#`+Z`B5\GDD>`BU"94$>2FU%!V"%1/8>@Q@%P#9`!M`)0'FS?$!P,]U +M@`#4I$`?`"`.A9T($```W^ZESW:``/2DF@B@`1R.G@U@#!R.2B)`(!IP%-@^ +M#&`7Z7%"%8`0016"$`BX!7I#%8`0/16#$!"X!7I$%8`0&+@%>CX5@!`(N`5[ +M/Q6`$!"X!7M`%8`0&+@%>PIPQ@JO]CR.&G`5V/(+8!?I<485@!!%%8(0"+@% +M>D<5@!`0N`5Z2!6`$!BX!7H*<&!Z2G$J"*`!'(Y*=@/!*W`N#R`4BB(&#`+` +M(!@$,+8*8`8#V`?NSW&``#2K&XD!X!NIR7`1`N_T@"0',/'`SW"``$`R`("` +MX`@.X?_*(&$`T<#@?O'`O@G/]+IPSW"``(RKH(C/<(``5%@!@,]V@`"4EN.X +M@B0&/2`6$Q%^\H0M%AG/<(``B&LP($`.[0@1`(/ERB"!#P``NRB$"P'USW"` +M`!Q7N*@`V"8+8!<(<<]P@`#D'#IPBW?I<88.(!2*(@8,+@U@#$HB0"#2#&`, +MFG"!X,(B@22V".__4B(`(`H@`*`]\@#84B(!(*ER`=N>#V_V"B1`!3;H5B2! +M/4(/(`R*<(0M&Q`R)($_``"P`0`A@']%`$`'(*`2#R`,"G`,VA)M%'@`(($/ +M@`"DH&X,8`Q`L>8)+_4#V`?H+@I@!@/8@@NO_P/8@@NO]JEPSW&``#2K&XD! +MX!NI!/!N"Z_VJ7#I<"IQV@T@%(HB!@P@'L04$]A>"F`7`-GM`._T@"0&/?'` +MG@C/]%IP*'4:,]P@`", +MJVD&8`P`B/'`#@C/]!IP`-[)=03P@+X!Y;!]S0T3$:]X2@Y@#%IP>.B$+189 +M`"&/?X``5&C-%P`6"B%`+N[HL@I@#$IP@>`!V#H/K__`>&3HSA<`%F+H`"&1 +M+X``U&IX$0(@6NJ2;91\`"2/'X``E*`)E\]Q@`!4H%8APP+-Z`\*T0"`O@': +M>!F`("KPSW"@```@&X""8\=R,0$`+4)X&0A2``F!BN@Z"*`"2G`&Z`+9>!E` +M(++Q%1?`$`(@``0O(`D`50A4BBH*8`Q*<('@`=C"(`$`4B``@*#U"9>`OD4@ +M0`,)MYKQC0>O],EPX'@`VP.X%'C'<(``U*1SH`+:5*`#V36@=J!7H.!_.*#@ +M>/'`X<7/<(``C*L`B(0H%@G/<(``#&R&"F`,,"!-#A5].)42E0JYR;@$(8$/ +M#P``_"5XSW&G``!(%:%9E1.=";K(N`0B@@\#``#^17@,H4$'C_3@>/'`H<&+ +M<$(.K_]`)($P`!1`,1(((``"%$$QH<#1P.!^\<">#H_T"'"$`! +M%@I@#`AU%7TFA0#8^6$N>:F%;@HO^.ERV64N>0'88@HO^,ERSW&``'2K$8D! +MX,D&K_01J>!X\<">"$``SW&``'2K`XD!X`.IT<#@?N!X\<`^#H_T*';/<(`` +MC*NB"6`,X(@(=7X+(`#I<`'9.Z`/#5$0V^;%XBCZP<:H!V`?P"60)"T,`,:HH/'`X<7/<(`` +MC*N@B,(+8`RI<`?HQ@H@`*EP`=DEH.4%C_3@>/'`7@V/]`AU*'8:`(#ERB)-`\HB+@`-"5X` +M4';*(HT##0F>``P@@*#*(@T$/Y!`(`P(4R%-`$`@`PU]94"M`>%4C#^P4ZP! +MV`?P"6,)"D,`,ZPH<@'@]P@4@4D%C_3@>/'`W@R/]`AU!8#/=T4`@!M`)0X8 +M".A+V!"NJ7#*""```-D*\!&.".`0KC".!Y<)"$,`$*X@C1".!PD#``"M[@@@ +M`*EP!.@+A0'@`_``V`NE*84$CRQX)X5!*@@C0>7`>$+"00`#W@"\"]X`*TGEPL(0@"*(,H/`*<>A0'@'J4!V`JE +M`-@+I0KP@.'*($$#$`@A`,HA80`"V`JE:02/],]R10"`&S`0C`!FD@@C`P.` +MB")\"0L$`V]\`_"/?`\+)`.`J(HAB@\@HF"(*!*!``L+0P"*(0L"+:(^@&&Y +MX'\^H.!XSW%%`(`;28`FB0>`3'E!*<%Q$'$!V.!_PB`.``'8SW&@```@`J'P +M&0``0-CH&0``X'[@>/'`A@N/],]P@`",J\H((```B#8/(`P(=<]P@`!46`&` +M`=[LN*EP!?0.#@``"?`"#<__Q*4`V!"EL@_O_Q6EN0./].!X\<`V"Z_T`-GA +MP<]P@`",J^"(.G'I<`'=B@@@`*EQD@X`#!IP;@@@`.EPV@X@#`AV!J:[ICD( +M42!L'D`4Q@MO_NEPC"##C\HG010%\I8)3_X(=XMQ>@V@"@C8"N@`P0#8#R!` +M`.1X"0\!$+NF+0.O]*'`X'CQP,X*C_0:""``"'8(=0H)(`#)<0#8*0.O]`2E +MA"@6"0`A@'^``)!KX'[@>/'`F@J/]"AWZ@_O_P#=@.<(=LH@0B,%]*&.`A:0 +M$,EP\@YO^7S97]D@KIC8`K9SVD2VM-@&MH#8![9#MEK8!;8%[V'8`:YDV`/P +MH:X*<`*N`-H'\$`F`!U88""H`>+Y"A2!H0*/].!X\<#AQ0#=!_"I<)(/[_\! +MV0'E^0T4D9T"C_3@>/'`X<7/<(``C*N@B%8(8`RI<`CH6@_O_ZEP.(`!X3B@ +M=0*/]/'`X<7/<(``C*N@B#((8`RI<`CH-@_O_ZEP.8`!X3F@40*/]/'`SW"` +M`%18`8`/"!X#D@_/_RH.S__1P.!^X'CQP+8)C_0(=\]UH```(-N%!("`X,PA +MXH`M\NP5`1!0APT)I``UIP(A@``'\`XB@`______.&`Q#@5P``"@#]H*(`#I +M<*X((`#I<`:'CN",#.[_RB#.`\]Q@`!4JP2)`>`$J0;PC"'_C[0-P?^:#>`6 +MZ7`>"P`&&X4+"(0#&X7">`?P.X4.)H`?_____SA@E0&O]!JG\<`6"8_TSW"` +M`(RKP(A>#R`,R7#/=T4`@!L?Z%H.[__)4$IP7%0<6\A"P"`X1P``@`GC&QY02G!<3!R;R$+`(#AG``"`.!^ +M(I#/$)"04#,'R#L"F2"PM"`(HA"P`@ +MHB20:Y(!X0<)Q0`P>R609+"/D@'A"0D%`S!\A;`KD@L+0@"*(8L`(*(FD'&2 +M`>$'"<4`,'MFL#&2#0M"`(HA"P$@HB>0V>P,Y(+"T(`BB&+ +M`2"B/8!AN>!_/:#@>"*0SW)%`(`;:))AN0<+10`P>R.08K",DF&Y"0Q%$#!\ +M@[`HD@L)P@"*(4L`(*(DD&J28;D'"T4`,'LED&2PCI)AN0D,11`P?(6P*I(+ +M"<(`BB'+`""B)I!PDF&Y!PM%`#![9K`PD@T)P@"*(4L!(*(GD'*28;D)"T4` +M,'MGL#*2"PG"`(HARP$@HCV``>'@?SV@X'CQP.'%SW"``(RKH(BF#2`,J7`( +MZ*H,[_^I<#:``>$VH,4'3_3QP.'%SW"``(RKH(B"#2`,J7`(Z(8,[_^I<#>` +M`>$WH*$'3_3QP.'%@^`!W<(E01->#2`,#WB`X`#8B0=O],H@0@/@>/'`!@]/ +M]%(,[_\(=L]U10"`&SX-[__)<3`5@!`!X%D';_0P'0(0X'CQP-X.3_3/<(`` +MC*N@B!8-(`RI<`OH&@SO_ZEP"'8*#>__J7%B".__R7"*"``&5@_@!0S8&0=/ +M]/'`H@Y/]*7!"'<*)(`/10"`&U8@#@)5($T%BW+)<$H((`"I<0"%`*8!A0&F +M`H4"I@.%`Z8$A02F`,`$P0FG`L`X8`H4`0$,>0/``<$@'T`>.&`(%`$!#'D< +M'T`>L09O]*7`X'CAQ8"!8(!P=,(DQA!&]PXCC0______O&2`HH&!H8`-#$03 +M`B1#$P?P#B6#'_____^;8V&B@H&B@`L,1!,")$,3!O`.)8,?_____YMC8J)C +M@:.`L7/"(T8#1O<.)8P?_____YMC8Z(D@62`<''"(<8`1O<.(X`/_____QEA +M)*+@?\'%X'CQP+X-3_0(=;X.8`D-V`AV7@@@`*EP@I5$E<]SI`"`1#2#BB`X +M``1YA7DTHS6#!'E%>36C(Y56@X65!'I%>3:C-X,$>25\EZ,FE5B#AY4$>D5Y +M.*,Y@R1XA7@9HUH.8`G)<`(+H`8;A<4%3_3/<8``5%@A@0AR`8@+"1X#((H) +M($``M0*@!B**\<#/<(``B*5&"4`/SW&``'2K#XD!X`^IT<#@?O'`%@U/]$8) +M(``(=P#="?``V<]PIP``1#"@`>6O?4,-DQ``WDH/X`L/)DX3Q'CO#@&0'@D@ +M`*EP.@FO]`;8`-[1#M.0SW.``$0`M`@*W9 +M$+E!H0&`2B(`(`*ASW6G``!(4R'`(H3O"*4#\`FEF@BO]`;82B%`(!$=6)0` +MWP7P$1U8E`'G&P]5$0C80@N@!@'9>.C/<*<`;$0`@`GPSW```*0H"-D*#J_T +M!=I*<`"FSW"G`'!$((``&$`@`(8:V7X(8!/)<@`0`"`:V7((8!,*.!^X'C@?N!X\<#*"T_TOL$(=XMV&@H@`"Z`.`=C/ +M<*<``$2PH-T#;_2^P.!XSW&``)2J,)DB>"\@"0"9X`'8X'_"(`4`\<`J"T_T +M"';L'$BP^G+/<8``>`N`@6APSW*``#CP]"+#!00DC!_S_^?_4VL2NV5ZA7HF +M"2`/0*&#QT`D$#3)<"#9`-KI3]G`B0!``(A00$]94(OU!?I<(IQZ7): +M#6_TBG,Z9M1^`L`K<2IR5@MO]`IS3B`"``#`%";.%0.X%'C'=H``E*H>9E&V2G"I +M<2IR,@MO]`IS3B`"`%>VQ0%O]*7`\#A@`"&!?X``4&P`H='`X'X) +M`"``2B3`!_'`+@E/]((D!C,(=2AV&G(Z6" +MY2X#!@``W@\F3A,+)H"4^/,N"^`+ZG#$>",.`1"$+4$3SW&``+Z?R-PO<$0H +M_C(G<`AA#B`!`RYY$/`2#.`+*G`F#&_VJ7%$+[XESW%$`(C:,R%!#C1X#GD` +MV*4(`J"*)!896-M2:+1Z@G)H$DX!"B2`#X``5&@))DX0!"D^(R]T;'@G=``D +M`Q&"(P0)M'O`LW020P$)(T,`QW2``%1GM'P;"+,`8K10$D,!"2-#`%P20@%V +MM`DB0@!8M`'@#WC/\4HF`"`#\$`F5B!,)H"@8@(&`'H+X`LJ<(X+;_;*<6C@ +M+R,&(%H*X`OJ<`#:#R*"!41X$'(!V6O?;$(0J-6)``D"W'I`)\C7N`J8+GS"?B +MD`?T+R#!!`D@P```J0'BPPJ4@@#:SNI`)(`R6&`R((`/``"``=QYA"^!$$`F +M#"4<>%QD+W-$+;X5`GDM>(+G)W.;8X-S)*O,)^*0!O0O(<$$"2$```2K`>+? +M\8#G>?4`W1)U``?)_Q;:!"^^(``A@']$`(C:A"^!$"]Q3'TG<=8+H!.B<0'E +MKWWM\4HD@``#\$(D1`"?#!``0"G`(!1X0"Z!(#1Y&6%`+(``%2$#`<]R@``@ +MI61B9+@X8`-B`-D#\`'A+WG/"$*@`-X8\$+?['P`)HTEM7W=92]R1"F^!2]P +M['L:8KIB,R6"("=PN&!S($T%!PV#$$"H`>;3#I22`-[A[D+?['Q`)@(EVF(O +M=40IO@4O<.Q['65=92=P6&`S)4(C$`N@2`T>1EAM7G/<(``(*4@8`IQ5B2"(BIS"B2`!0HE0`7&""```!0& +M,`'EY/'Q!2_T@"0&,^!XX'[@>,]P@`"4'B"`SW"``)26X'\PL.!X`-G/<(`` +MY!TFH.!_)Z#@>,]T@`#D'`:D$J0HI#2D5+18'(00>+1@',00SW&``)264)'/ +M<(``E!Y`H`'8X'\0L>'%X<;/=(``Y!U`)`T8-'T`M0'8!J1'I"3D-7Q@I`#9 +MSW"``)26,+#!QN!_P<7@>/'`1@TO])AS"'8H=4ATSW"``/B2R7&I/'``@T/]*'!.G`:<5IR>G.(=0HE0"%B#Z`+R'8O)@<@SW"``$3F +M`(!`P,]P@`#@W?`@5`06".`+:G`-[L]Q@`!46">!P[D/"5$`BB$_#P(<1#`* +M)H`/10#P-P#;$?"$*\$`SW2``)250"1"%"]Q*F(-"((`0"1"%``B1@`!X^,+ +M%($5%LH``-L#\`'C;WL2I1ZXGHO(880%2;"$$)RC)H.>`DD#!`$ +M+/XA-7XO<`0K?@%`*84`)W`$*SXA`""'`P`G#@(8!Q.F(LXAIBP+(!Y)!\P?%Y`R_TH<#@>,]R@`"4EE"2 +MCNK/'8@#\`#8X'[QP.'%"',H +M<@'=80LU`@#8,R;*<(``W.-`)X%R%"&!`@!Y)PJ0``AU#_`#VP+=#?`$VP/= +M"?`%VP3=!_`&VP7=`_`'VP;=#0J1`('ERB!B`(#@RB""#P``K!E@#&+TRB'" +M`-$"+_2I<`'8W_'AQ>'&A"D6"<]V@`#D'9">SW6!`%A%+W&$*@$&T9Z`M2=Q +MQW&``%1H=7G!M1#H6ID;F0DB`@-"M0D@@`.>$4('`[4O"B,#GQ%`!Q+PY!%` +M@>810H$)(``#`K4)(H(#0[7L$4(!"PHC`^X10`%(=(2U"28.$,6UP<;@?\'% +M\<#/<(``5%@`@!4('@'/<(``5)4/@(#@M`M!]DH*@`BF"D``T<#@?O'`J@D/ +M],]P@`!46`"`4P@>`<]P@`",J_X,H`O`B('@`=W")4$30@UO]JEPE@UO]JEP +MP@]O]LEPX@_O]0#8<@UO]JEPH@B/]HX+C_:R#6_VR7#/<8``5*L;B0'@&ZF] +M`0_TX'CQP#()#_1Z<80H%@G/<(``0&LO=88+H`LR(%(#+R`'(`#?+?``W@\F +MSA,+)@"4)O)$+SX?`"6`'X``M&8&X#(@0`X*(4`N&N@V"Z`+:G#$>!!V`"6` +M'X``E&:$+P86).`U($($`=D6(8!TP'G'<(``E(\XX#1X0+`!YZT/E)`1`0_T +MX'C/<8``-)44>0`9A`\``/]_X'[@>/'`C@@O]`'9.G#/<(``5%A`@.2ZSW"` +M`)26\`0A`!"0@.#H!`(`!!$!(`HF@"^``&0>!"&"#P```!@$(8`/``,``"NZ +M.+@%()``!"&"#P```$!"(A2`!"&!#P```(#*)&(@0B$5@(H@"`#*)6(@SW*` +M`(RK'!:!(,"*A"D!#`HC@"^``.0`C(B@R#/=X``Y!U&ATDC@P!ANY_JA"X6&<]Q@0!812]PA"@!)B=PQW"` +M`%1H=7@L$$*!0+$N$$*!0;%:F$*Q6YA#L9X00@>?$$`'1+$%L13P1X<-ZE"? +MSW"!`%A%,9]`L"&P0K`CL$2P);`&\"1XR7%2#>__"G+X$P`@`*<#AP6G*-A5 +M\#(BC"`-"1X"4R&#``WP"PF>!E,APP`'\#UZSW.``"SOPKI+8YID57IJNEMC +MSW>``.0=1H>BZH0N%AG/<8$`6$4O<(0H`28G<,=P@`!4:'5X;A!"AT"Q;Q!" +MAT&QY!!"@4*QYA!"@4.Q[!!"`>X00`%$L06Q%?!'AP[J4)_/<($`6$4QGT"P +M(;!"L".P1+`EL`?P)'C)<:8,[_\*%IP1A,`)IT($0#/.6:8GP")\<0%!%#(7-[`[MY82\F1@`@L@`C`0$O)$8`(;(` +M(T$!>&!\9.!S+R5&`"*R+R$&$`.R+R`&$X2R;GEELO`F`"06$4PA8)@)(P,# +M`B.#!`DC@`$`L@DC``$!L@DC0`$"L@DC0`(#L@DC``($L@DC00`ELB$,$"#P +M$P`@J7&`X,EP`-H&\L8-#_8#V!JE!/"^#@_V(0T0($$3`":I<8#@R7`!V@;R +MI@T/]@/8&Z4$\)X.#_9:A<]W@`!X"R"'&X4$(8$/_\__GPVZ!"*"#P```&`< +MN`0@@`\`,```17@E>`"G!H5*#6`.,H4IA0&'584$((`/Q__'_P.Y$[I%>25X +M`:"?\H0N&Q!`$@4`J]LO=P0M_@``)X$?10!`!\=W +M10#@"0;A$N<$@@`G2!YL>,]P@`!(:R=QA"X6&3(@0PX`W'D,$"`$@D0K_@+/ +M=(``<%0$N."$%7@?9S,G0!X*)$`.@)I`($8"VVP()@X0+R>&`PDFS@$"?LYX +M^&`!X#,@#@$!B8)X'F85FHHD/Q388`@@#`-YV`DD#!#/<(``Y%3T(`P#!XF, +M>$(IP'(0>(HAQP\)($``$'P4LI$-$"#/<(``<%3`@$0K_@)`+0`!%7@>9B]P +M5B:!'#,A`0#XFD`A1`)[;P@C0P`O)<8`"21#`2)[;GG988`A1@0S(0$``1"` +M$.)X&6%:$D`!.&"*(3\$""!!`'G8"2$!`,]P@`#D5/0@00`'$(`0+'A"*!JB?O#/=8``Y!Q6)0X2C>@"V`:E$J4HI32E-M@4M0RV`-@8M1"V!H46"V`. +M,H7/<(``>`M)A2&`=84$(8$/Q__'_P.Z$[ME>D5Y(:!(A2"`=(7/=(``./#T +M)((0!"&!#_/_Y__T),,0`[H2NV5Z17D@H$R6-)4(ND5Y'!E`(%"6.)4)NLBY +M!"*"#P,``/Y%>2`90"!2A<]V@``X*F:%\":,$,]Q@`!L#/`FSA`"O,5\A*'P +M%0$0!^D0&(`/R_.8&0KPSW&``+2X"0N1`""!`_`A@22@014!%@;I%!B`#\OS +MF!D+\,]Q@`"TN`L*D0`@@0+P(8$EH`8(X!8#V-T"[_.I<.!X\<#/$@HM'`X'X`V`"B"(,2Z,]P@`!X"P>` +MCNCZ"B`.`=C/<(``5%@`@`T('@'B"`_VZ_'I\>!X\<#/<(``5%@!@"D('@'/ +M<(``C*L`B(P@PX^`"$+VV@I@!038SW&``#2K'(D!X!RIT<#@?O'`%@K/\UX- +M8`L(=1IP.@U@"ZEP"'?6#&`+J7"!X`'>PB:!$ZEPF@TO]LEQ&@VO]:EPP@E/ +M]NH,8`NI<`ARZ7`*<:ES>@BO_THD``#N#R`+Z7`(!X\<#/QBS]@]@ +M"TNC@.#$"$+VT<#@?LO)SW&``/3)$(@#N!5XX'\U(0``\"<_SK<$(=1IQ +M"B*`+X``C*L`$HX@F@]@"\EPI0@0`-(,0`O/=X``Y!PZ<`\($2``V,,Q"Y4``-G["9.%1"N^!<]R1``\V;-\`"%`<#,B`@`!X51\ +M`"""#T0`1-J`JB]Y[?$$$@`@-@I@"P*`L@Q@"UIP"'*+=2\@1R2I<$IQF@NO +M_PIS2B$`(!+P\!<&$`38"G&I"Z__"B1`!$`A42#A"92@ +M_0#O\ZW`X'CQP*8(S_,(=L]U@`!X"P"%SW&``#CP0I$$((`/\__G_S-J$KI% +M>25X`*4`V`X(8`X(<0#8#@F@#@+9`=@&":`.`MD!A00@@`_'_\?_A+B4N`&E +MSW"``!C>\""``P]Y#W@(N00A@0\```#_)7C/<:<``$@+H:$`S_/QP"H([_,4 +MVL]Q@`!8H#(-(!,`W2CPA"T!$R]P`"""#T4`7"U\BL]Q10`\+1KK78HX8$0J +M/@<(X#8)8`LP($`."'@A"\6&0`AC7^``-1J*@PO]AF%S@U@"^EP'>A."F`+Z7"!X`'8>@LO +M]L(@`0`9A<)X+R()`!J%`B``!"\A"0#/<(``Q!T)B!!RS"&+CP``]`%#]@#8 +M`O`!V*$'C_/QP#X/C_,(=@#="_!V#6`+KWB`X(@)8O;*($(#`>7Q#121`(8. +M""``P;B%!X_SX'CQP,]Q@`!D'BN!BNGF"$`(SW&``%25[@O@!1&AT<#@?O'` +MZ@Z/\]<(E0,/"+0`2F@)"/0"`=L`VQUA`!7,$``@C@^``/22A*X.%0I,H=8`E"!"X8`00SX"H'L*3$NL` +M)800$A3%@%QDMAQ"D1P4SX!=9<``A.Z\EMA$!/#`%A@=*A981H1P0`^J+#P0B""`P\*]0A= +M?@'8"0H>``#8^'`3"G4(02J-`%,B?H`!W`+R`-Q4(4`(,R"#```B@`^``#J3 +M"B6`#X``5)1@J#,/$`!6(0,#0",``C,@A`//<(``5)-`(`\#WV?4>P`?`A$: +M$\\`U'C^J!L3PP!_J"CL*'"`(((',R!#`\]P@`"6DT`@A`*X8&"H`-@+\!4@ +M0P-6(4\%,R?/$(!SX*L!X/$(%(%6(0`&M'@,$,,`SW>``+23M']PKPT0P``1 +MKRAP@"`(`$`@!`=`((8"6V`P$\B``"6%`-0=`H)6$\*`^AV"@!\/$`#:8'P2 +MR(``)H(?@`!TE-A@`!H"`HX0P(`2JA'L5B$"#;AB`!#(```ECQ^``)24!!\" +M$KIB"A+```ZOY!/`@(@=`@`5#Q``,R:"`P`F@!^```*50*@([#,D0@,`)8`? +M@``4E4"H"NR`(8,',R%!`P`E@!^``-:3(*@=!8_S2(#/<8``-)7U(8$`X'\B +MH/'`B@R/\PAW*'5(=HX*;_8"F#IP\@AO]@.'>G#J"&_V`8<`V5IP`(6"#Z_S +M&-J:0!X%*GX``-D$'D`>J@F@!8RY +M`*8!A@#9G@F@!8RY]0.O\P&FX'CQP)H+C_,Z<"AV((``ADAW!2A^``#=C+TO +M<'8)H`6I<:)X;@F@!039N&``IP01`2`!A@H@@"]$`/"2.&`<>`&G`!``("H( +M;_8;>``0`2!:<#MY+R!)`(P@!8K*($T`RB&-#P``:`%(#(WS6MP""&_V#B$` +M`QIP!!$`("&&(G@O(P$@`!$`(`RX!@F@!2"&HGC.":_W!-D$*+X$"'8`V2]P +MZ@FO]XRY!"L^)!UE`-DO<-H)K_>,N00KOB0"?0#9HJ,N00N/A0( +M=0#9+W"Z":_WC+FX8!T#K_,#I_'`M@J/\Z+!>G`H=XMP,@]O^`C9`(="*,$' +M"'*:#:_S*',(=@&'.G%"*,$'"'**#:_S*',(=0*'6G%"*,$'"')V#:_S*',: +M<`.'FG%"*,$'"')F#:_S*',`)DZ3`2)-)``@`(0!(0$%;@VO\PS:R7)V"*`% +MJ7-`P$"'`H="*L,'-@VO\T(HP0<:<$&'.G$#AT(JPPE_:4@ +M'8`?``#`#R0=@!\``,`/Z7!*<>ER&@L@``IS.!01,`_&0-@(I0FEZ7!*<>ER +M`@L@``IS.!00,`_%-0A`)`(E@)-"+<$70B["%P,A@0".#*_S#-H"($*D0BC# +M)T(IS">.#V`%`R,#`T8,#_8/\`(E@!.`X,H@B0\``%H`!_:`X(H@O@G*(,H# +M#"!`I!```P#1==4@9`O8(&,+B0&O\[+`X'CQP'(.(```V(HA#PC/<*T`@*(A +MH,]PK0"`K#&@BB$+`,]PK0"`8B&@SW"M`(!L,:#/<*T`@!YP&(`/BJ*8&<]P +MK0``*3`8@`^*HI@9$@@``"(.(``!V-'`X'[@>*$!``#QP+X(K_,19X&6%B<0`A0@Z+FG)M=7O'F)R`")!#CR9)W(;DB.C!*/J#2_VJ7`:Z`#>1@H@"P\F3A/$>"4. +M`1!"Q8?&D<(*B\D1P3)<"H*(``APP'EO_$%`*_SM<#@ +M>/'`A@[/_U8((`49V,]Q@`!4JQ&)`>`1J='`X'[/<8``5*AY$0$&SW.``-2F +M`-H>Z<]T@``HWR"$&0F1`-#@EO8(LP':0*3/<8``;#)`H0[P&0E1`,;@"O8( +MLP':SW&``&PR0*$"V2"DB)L"(`$#+R%)``L)E`8!V@BSX'](<.!X\<#AQ<]Q +M@`!4J'D1``80Z,]U@`!L,@"%%0A1`$@10(?&X`;V=@P/]@#8`*4Z#L__?0=/ +M\_[@`-G']HP@`H,$V,H@[``*\,#@RB"I``;VCN#*($P`RB!I`$0H/@\`(8!_ +M@`#FIN!^X'CQP&H*``O*#\__SW&``(RK((F$*18)`"&!?X``#&R>#Z_^`*'1 +MP.!^\<"F#D_S"'5H=@*!6@\@#DAQSW"``'@+(("MV!"X(:`!V<]PIP``1#"@ +M/-B:#:`%`-F&[8((H`7)<`KPR7`-#5$0I@B`!03P)@B`!VRB8("*D,B[ +M";PD?(5[?:)B@(Z0R+L)O"1\A7MFHF&`#)#(NPFX)'AE>`>BX'[@>/[@`-G' +M]HP@`H,$V0`A@`^``!BHX'[@>/'` +M9@D`"\X/S__/<8``C*L@B80I%@D`(8%_@``0;.X.K_X`H='`X'[QP)X-;_/8 +M<8AU\FI$+CX/]7_2:A]GU'X5)L$0SW"``-2F&6$0%P40+W,`(<0`-AQ$`2.' +MSW2``%2H.!Q$`'D4`18ZZ0HG@`^``&PR`!/'`P@Q/\^()(``(=<]WIP``0`&' +M@+@!I[8*(`X-A3.%2B!`(`KIU(4`V&8-(`[)<0'87@T@#LEQ#H7/<:T``(-@ +M&8`/```("%-H"[@%>L]PK0``0UB@3X6*(T0`>*%`*@,"97I8H'&%8!F`#P`` +M$!!4:PR[97I8H$&%&^IRA6`9@`\``&!@56L-NV5Z6*!0A8HCF`%XH<]Q@``D +MZ/0A@@!;>0FZ17DXH$(*H`40A0"%%.C/<(``>`L@@$*%SW.``#CP]".#``0A +M@0_S_^?_4VL2NV5Z17D@H">%B^ECA0#:`MB%ZP6E1J4#\`:E1:49"9``!84R +M"B`.)H4%A2:%7@L@#DB%(X7/=J<``$04A@HA@"^G``!(MKBWN!:Y!7DTIA2& +M)(6XN+FXNK@8N25X%*:2#^`-`=@6A0SH%X4/>0]X"+D$(8$/````_R5X+!D` +M(!@?`!0:A52&+R$)`(#@T")I!<\B;`4$(H(/X/\!#E,A`P(,NR]Y.WDE>V5Z +M5*:N"T`%$H8LA48@@`$[>25X$J9@%0`1W@F@!605`1$KA12&2H4$((`/___^ +M\0FY17DE>!2F,H85A:"Y)7@2I@.%`-D/(0$`SW"E```0(:`;A3V%7(4$N5MZ +M17DE>',9&"!)`T_SX'CQP.'%`-W/<*```!"IH(8)@`W/<*0``$2IH+&@`-AN +M"V_]CK@]`T_S\<#AQ<]U@`!H*)WH+@]@!0#8T@K@#0#8SW&``&PH0($`A8#B +MSR`B`=`@(0$`I<]PH`"`13`8@`\`(``!`=@`H2KP^@Y@!0'8F@K@#0'8((55 +M"1\!SW"@```(`H``VL]PH`"`14V@SW"@```?'(`I"!\`)0D>``QP'0@?`\]P +MH`"`13`8@`\`(````-G/<(``;"@@H&H@@`'/<8``<"AJ((`!`*&5`D_S\<". +MX,HAC@\``/\`7`TN_@$A[:X'C/<(``5("J$(`` +ME>C/<8``U(!2D129,Y$:8CA@SW&B`(!M2*$)H<]Q@`!4JQ>)`>`7J>!^SW"` +M`/2`"H@*Z,]Q@`!46`"!H+@`H0&!H+@!H;$'S__QP,]P@`!4@CP0P`#/<]S@``*@3,C00`!X!QX,R,#`#MC?'NH$D`!;7L"(P$`+R%)`$DAS``0 +M04I/@,G<%X/[_^H&@0`SW&``#2K&(D!X!BIA@G@!`#8 +MT<#@?N!X\``(!4`-TH\(0M`A4%D"=QE1&"`!#@ +M)0BD``#>SW-$`$C'5&W/<($`>"X4X2(*X!=Z8H#@RB9B$""'+R:'\T`A``.X +M8,"H!_(B$8```>`B&0(``>7/=H``=-X@AD"!K0VDD`"'(A"!`)\)$``CD`+A +M([`ED&*Y);``W03P`(>FO>;(*H`MPV'+HSW"` +M`%`5`(`-"%$`R@]`%R_H`MC/C//'`F'#JR;AR_+C*(((/Q>Z%\LHA8@#*(J(`R`BB +M%43#941 +MSW"!`.@<\"!``_,)`8"&Y!.#._UJ7%! +M!0_S\<#F#,_USW$!`(B6C +M#941SW>!`+@<0"<.%K5_#(?M"$&$BPI1(""'@>'*(((/```0*T@.0O,"V`"G +MSW"``$@4&G"@H)(.K_L+V`AW@Z% +M\@'9`-H*)$`$^@Y@%0HE@`0!!"_SI<#@>/'`J@LO\P]X*'7/<:```"#;@3X( +M`!;/<8``1!_P(0``!>@"?@D-I1,!V`#8[0,/\_'`<@L/\[8+S_6C"!``"B"` +M+X``2.$Z"6`4"G#/<*```""[@`#?BB;_'^ER!/``V`"C`>(Q"A4-SW.``$0? +M57L@@WGI`B5,$,]PD]8`I.,,!9`X8`(@00,P=LHF31#*)PT0Z?&&"\_UC";_ +MGQ?RSW#_?P#_'640=LH@1@/*(,4#@.`!W4"A<@TO +M_!;8T<#@?O'`4@_`%<]QH```(#N!`=J`X4"A1@TO_!;8 +MT<#@?N!X\A> +M"D_\SW>!`!@=)A"!``*`(*X8*8.[_>0V08- +M8!3)<`X(`!/F#F`!R7"$+@(:`")-+NX/(!1")0`9Y@\@%$(E`!+>#R`46"5` +M&;H*P`[)<%H-(`D`V44"#_/@>`#9SW!$`)#BX'\@H/'`X@D/\PAU`-[/<($` +MN"[4J/X-(`FI<(0M`AH`(8!_@``@2\]R@``8VL`8@(,&V]`8P(#/<0``)%W, +M&$"`U!A`@]@8@(#<&("#[!C`@,]Q```L7>@80(#P&$"#]!B`@/@8@(-BH,]Q +M``#X6R&@HZ!$H&P8@(,%V7P80(#/<0(`1+YX&$"`@!A`@X08@(#/<0``-%V& +M#R`&J7#N".``J7"$+0D?SW&``(0[+W`!80GISW&````]"6'&#*``J7"5`0_S +MX'CQP!8)#_,(=BAWA"@)#P`AC7^``"`]`"&!?X``(#L`@3V!<16#$$`ID`+/ +M<8``<"=`@2"*4PM#`'(5@Q`BBDL+0P`FV9(+;_L#VN*@SW&@```@.X'B>3^Y +M4B$!@`/R`G?BH#J%!+XFH!39(Z`@@-9^`":`'X``W$<@H.(-+_P`V"8++_P, +MV`#8]0`O\W@=`A#QP&((#_,Z<"AU2';:`Z>EIZD'[_(FI[4$0`#QP#X/S_((=H0N"1_/ +M<(``A#LP($`.SW6!`!@=+N@#A8OHK@^O_,EP"'+/<````34."6_SR7'/<0`` +M-%TZ#2`&R7"$+@(:SW&@```@.X'/#2_\`(`.#R_\"':3Z`6&0H8* +MN!IB`B*!#P```#"I<`T(D2!.#H_U!?"6#.__2'&I<`8(8`"*(00`&?``WQ7P +MM&^"=0B%(0X!$)(-#_PIA14)4`85"9$&/(@D$(``"0D!``#8"*4!Y]L/E)"I +M!>_RH\#QP#X-S_*DP0AVA"@)#PHA0"X`(91_@``@.\(/X`AD%!4@.W``(9,O +M@``@/>`3D*`Z#J``"G!`P%H((!/)@`A@"^``&`];)!Z +M8D)Y@.$!VI<,T#S_+@>/'`5@O/\@AW&G%( +M=BAPK@D@%039@.8(=;0.H@#*(`($A"\)'P`A@'^````]!NTO+4$33B6!%P/P +M_]F%`^_R(ZCQP!X+S_((=4(1@``+"!$#5"%."`+P`-Z$+0D?SW"``(0],"!` +M#A<(4`""X,H@00-\"*$1RB$A``7PJ7!B"*`1`=G)/'` +MO@K/\@AV*'5:/'`7@K/\J3! +M"'6$*`D/+W8`)I,?@``@.](,X`AD$Q0@.G#/<(```#TR()(#3@N@`$IP0,!N +M#>`2J7`:<*EP2G%R#"```=K/<*```!TX&(`/````$`X/(!>I/$_#O^@L@!*EP0"!!(8'#J7`^""`&`,*$+0(: +M`"&.?X``X$J*#^`30"8`'H(/X!-`)@`7`_RI,#QP#X)S_((=2AW`-D."^`%&G$( +M=L]Q@`#T/(0H"0\O<`%A#.]?#Y$0SW(!`.BGR7`2".``J7$G\$HA`"``((\/ +M@``@/!&'#R%1(P8@0`01IX#AR7"I<0KR*@L@``+:,H<%(4`$$JAV#J`(R7!0'P`4>@H@!,EP(0'/\N!X\<"V",_R"'6$*`D/`"&`?X`` +M(#L`(9!_@``@/$@0`B!O$`X&1GY*(0`@=1A8!$D)D`"M[B#P+RB!`TX@CP=$ +M$``@[W\0(,$#1!A`(,]Q@`"LTP"!"PT!$`B)&0\`$*EPZ7&:"B``"-JI<'8* +M8`#I<1`FSA/A[D@80"10&$`DX@V@"*EP=@H@!*EPD0#/\N!X\<`:",_RHL%H +M=XAUA"T)'R]P`""3#X``(#LT;18A4@!`@B"#"B2`+X``H$BJ"2_SBB"$!@:')(<1VPL)`0`3VQ1X +M!J +M#*__J7"I#^`(R7`Z<(0N"1\`(91_@``@.WH4`"8*(T`N`B4!$`'G +M\7$`V,H@;P"`X,HAP0,`(X\O@``@/%@?@!0UIR,*$"`Q"!`@+0D1((0N`AH` +M(8!_@`#@2HH,X!,XX`KPA"X"&@`A@'^``.!*(@S@$SC@3"$`H,P@(J`2\AL* +M$"#/<*```"`;@`(E`1!Z%``F$0A%``#8%*>6"2`)R7!6#4_\(^C/<8```STR +M(<`$C"##CQORSW"@```@.X`")4`0)0X#<````$"$+@(:`"&`?X``X$H")8$? +M````0`8,X!,/'`"'3JR4AS%P@>!$`I`@3/<,7N@YH! +MV?(((!6%>M'`X'[@>/'`E@V/\EIPEVB4?``DCA^``!RL7(;/,=P@`!(^R*@`=G@?R&@\<#^#(_RP(&DB``)RL&I<+"%X",(<"\"Z'(G')<+(-(``"VDP@`*#*(4($P"&" +M#P````3*(((#F`TB`,HBX@(3;19XSW&``,2Q"&$7")``SW$!`*"[J7`0VKH. +MX``!V\EPS@[O_XHA3`"Y!(_R\<``@<]R@`#0K#=H-'DQ8AD)7@#/<:```"`[ +M@98A!@!"#2``"=H$\+()``#1P.!^\<#AQ:"!+@W@``2)SW"@```@.X"I<)8A +M!@`:#2``"]J-!(_R\<#AQ:"!%VT4>``@@@^``#2L"(**Z,]PH```('N`!X)B +M>$@@```(HN8,X``$B5H)(`"I<%4$C_+QP.'%*'7/<0$`7+0$C1#:"@[@``'; +M.@D@``"%-02/\O'`L@N/\@>!X('$B0?HSW"``!0F\"#-`P/P!=T*O1"12B!` +M((8@_@S(X,(@`B1J">``Z7"`X,P@(:`+],]PH```(#N`Z7"Y86X,(``&VA-N +M%GC'<(``G+$M@([I*!"``!4(T0#/<0$`H+O)$@@```(HL]R`0#8N@2)2'$0VHH- +MX```VX(((`"I<'T#C_+QP/X*C_((=2AWB.K/<(``!";P($$#!_#/<(``)";P +M(($`J7"F"R``!]H`W@GH`=X7;11X`""!#X``_*S`H3-O-GG'<8``G+$H$8(` +M`-B#XLPBHH#*(&$`"^@-@8GH`@O@"*EP@."@#>$`RB#!`_T"K_+)/'`6@J/\@AV6G&$+@D? +MSW"``"@[,"!-#H3FRB"&#P``"0%`#.;RRB&&`X7ES"7BD9CT%VX4(!$``"&- +M+X``G*P#A8#@CO(`V!IP`Z4*A=D(40#*"*_UR7`IA0B%(G@(I10=`!0&A2B% +M#@BO]4N%0"4/%1CH&I4M"%X"`=@%I<]P@``4)M5X`!B`#P$``*3/<(``!";5 +M>``8@`\!``"D,O`!AR.'T@]O]4>'A>@:E34(7P(:E0D(7@(PA0/P+H7/<(`` +M%";5>""@&I4+"%X",84"\"^%SW"```0FU7@@H!+PSW"``!0FU7@`&(`/``!\ +M%<]P@``$)M5X`!B`#P``?!4!AQL:&#!#A\EP'!J8,""'.@E@%6&'+@BO]C\ +M&8`DX*;L$8`@&PB1`!*.$PB3``'@$JXRCJEP_@\@%0C:#!X`%)D`C_+@>/'` +M.@B/\@AVA"@)#\]P@`#E6"#`+#8,;_`*B`X(D>`.BR7#R">__BB'/#^T' +M3_('N!1XQW"``)RL4H@)"G(``-DSJ.!_,JCQP.'%@(FJW4&)`!`$`&*)3"2` +M@``(@)\$PDP(+*($(#`_0'@`"`D@X@%8EQM0=/\N'%![@4>,]S +M@``TK!QCSW"@```@&X"GA#A@`B!#`Q,+4@`'I`'8":0JI$ND`O``V.!_P<7Q +MP/H.;_)*)$``&G"W:+1]QW6``)RKSW"@```@VX":%0`75B7/%(8@?P^"X+@5 +M#!#")`(!VV1*(0`@M!4`$(3L"',+\`(C#`#Y#%*0M!W`$`'8O!T`$"`?0!0" +M(<``@.``V,HAS`#%]B>G2ZEZ`(F0!`+"%(` +M0"8!%2>GA"@)+\]P@```/3(@0`[//'`,@Y/\@AU*'8'N!1X +MSW&``(BL"6$3;A9X`"""#X``G+$(Z0V"@>#@#&'URB!!`P#8#:*I,]Q@`"(K`EA$VT6>``@ +M@P^``)RQ".D-@X#@;`QA],]Q@``TK``A$0#)<'8-8`"I<3<( +M42!J"F`-`-@,AQ<(4`#/<0$`H+NI/'`,@U/\L"!Y(F*(00`SW"@```=+:"6"N__R7"W;K1] +MQW6``)RKJ7`*"*``"=G)<&(/K_]`V58E0!(F@"2!(($>"Z`3EB$$``"%T@A@ +M``39R7#B#&``Z7%%!4_RX'[@>/'`S@Q/\@AU*'<`WIH.8`7)<>]_&G!!#U$0 +M$VT6>``@@0^``,ZQP*D*<`X+;_6I<<]PH```(#N`"G"6(08`E@WO_P7:SW"! +M`.@M\"!"`ZEPR7$,\(PG@I0)\L]P@0#H+?`@0@.I<`+90'K-!$_RX'CQP%X, +M3_((=K=HM'T`)8\?@`"__"MH`V`:E"*72"F_UR7#)<`IQ:@P@``O:\LD1(("#RB"!`_P-X?_* +M(0$$.01/\N!X\<"^"T_R"';/<8``T*P'N!1X.G``(1```""-#X``G*P:E0HB +M@"^``)2LAB#_#H3@2B-`(,(CPB2N#6`/R7`(=PIP/@V@%`G9R7`R"B`5"G'/ +M<(``2!4`@`GH&I7IN,H@@@\```(!7`V"\N(+[__)<#*-R7`*"R`5`-H3"Q`@ +M&I7BN!@*80#*(($#&I4)"%X",84#\"^%SW"```0FU7@@H!J5"PA>`C"%`O`N +MA<]P@``4)M5X(*`;E0`B4B0$*(`/#P!`0LEP`!I`+@`0`2$$(8$/````"(H( +MH`<4$((@#?`O*,$#3B"-!Z]]R7#B"F``J7$0)T\3]N^$+@D?SW"````],B!! +M#LEP0@L@``;:#0-/\N!X\<"^"D_R"'6$*`D/`"&`?X``D#T!B"AV@^#*($L# +M_`RK_\HA:P"I<,EQ#@L@``/:_0)/\O'`:@I/\@AUNG%(=AIS"B(`(0HC0"%( +M<(8@_`",(`*``=G`>4APAB#^#,C@2B%`(,(A0B3MNDHF0"#")H$E`-AW;71[ +M`"./#X``G*S/G/<:```"`[@<]R@`"<"UZ"0GDIIRKPA"T)'\]P@``H.S`@ +M0`X`'X`5"0C0`24.$"``(X`/@```K2:`)($@@?H/8!.`(1``J7"J#2```MD% +M\.X,(`"I<`'8FG`1#A$@`MB>#"_\J7&*<`':SW&``!0.0Z$RZ,]R@`"<"QV" +M)H,=P@`!(^R*@`=I!H,]PH```$&00!`"I<"IRW@HO +M^DISSW>!`'`T&!^`%!P?P!30MR(?!!2I<*IQP@D@``3:0"<`%K(-+_<,V6D! +M3_+QP"()3_((=QIQ6G)H=@HA`"&$+PD?SW"``"@[,"!`#@HC0"&%X,P@XH%5 +M]`#=-PZ1$;X*@!5$(0$C->@J<(8@_@S(X"_R'PD0`BIPAB#]#(P@`H('\BIP +MAB#\`(P@`X0A],O)5V^P$`$!5'K'/'`X<5W:'1[`".,#X``G*M7%`,6 +M%>MS:79[SW6``-2Q8V6$ZQL*$0//!X\<#J +M#@_R"'4:<8((8`4`WH'@RB""`QCTSW"@```@6X!`*,\@SW"``-BQ]G_A8`>] +MSW"``)2LM'V@8#A@$'(`V,H@;P`-!P_R`[@6>,]Q@`#$L0AA@.`!V.!_P'@' +MN!1XQW"``)RK0!`"!@#9A^K\$```@.#*($$``O(!V.!^X'CQP.'%+@]O^RAU +M"KVQ<-T&+_)O(`L`X'@O>?'`$PE1`,]Q@0`H+O`A`@``V0KPC"&"A`GRSW&! +M`"@N\"$"``+90'K1P.!^X'CQP!X.#_(:<#IQ2'?/<(``-*Q`*,TAM'V^8$NF +M"G#R"2``0-D*<&((K_\@V2EO1PE5`3,F07"``##C0">`/'`@@T/\EIP*'<` +MWE8/(`7)<3IP![@4>,]Q@``TK!UASW"@```@.X`*A0`@4``?#U$00"K`(!9X +M`""!#X``SK'`J2IPK@LO]4IQ*G`*<4(.K_]+A8T%#_+QP#8-#_((=RAV`@\@ +M!0#9"'7/<*```"`[@(PF@I0)])8A!@"I__ +M`-H(\,=Q````@*EP\@VO_P/:A"T)'\]P@``H.S`@0`Z'X"`.(?_*($$#/04/ +M\O'`S@PO\@+9"'<`W0>X%'@`((X/@`"/'`X<4(=0>X%'@`(((/@``I<'$$#_)`@<]Q +M@``((*(`#)<"H,K__)3^Y4B$!@`_RS@NO_\EP%VX4>,]Q@`"NK`EAR7`$VNX* +MP!2M`P_RX'@`@0>X%'C'<(``G*N:$`$'X;G(`&$`RB'A`!L)7P+\$`$`@.&T +M`&(`RB&B``4&(``$V>!^`($'N!1XQW"``)RK60%``/'`Z@HO\@':*'80D:"! +M[;@!V<]P@`!@MB"@!X;"(H$`-^@7;11X`""0#X``G*O'<(``G*PZD`L)7@(P +M@`+P+H"I<'H+K_\&VO"6`=E$)P`3@.#I=%&6P'EFA@#8AB3\$(PD`Y3@WLPD +M@I/*(&$``^D@Z$8(8`"I<(#@"G`%\AH(8``"V1;PK@H@`.EQ$O"$+0D?SW"` +M`"@[,"!`#A4(T`&(ZA=M%'C'<(``G*NJ"$``H0(/\O'``($W:#1Y`"&"#X`` +MG*OR#P``@."P"R$`RB"!`-'`X'[@>/'`!@H/\@AV2'5Z1 +M'X``G*MV"J__"B)`(<]P@`"NK.E@R7":">`4`=J'[<]P@``$)O`@@0,&\,]P +M@``D)O`@00/)<)8*K_\'VHH/(`#)<(#@*G`&\EX/(``!V0GP:G$*,]Q@`"(K`EA2':"X0'8P'B`X`'? +MP'\3;19X`"""#X``G+$'Z0V"@>!`""'URB`!!`#8#:(*<%8)(`"I<<]P@0#H +M+;5XP*`*<*EQO@GO_P?:H0$O\NEP\<#AQ0AUSW&``!RV`X$/($`#`Z&N"R_[ +M#=BI<`(-[_^`V9$!#_+@>.T"S_FU`$``\<#^"`_R.G`H=?=H]'_/<(``B*SI +M8$H@0"""X0'8P'B`X,(@`B1S;79[QW.``)RQ2'8(Z0V#@."`#^'TRB!!!`'8 +M#:.I<)8*(`4`V;H((`"I<0`G@!^```"MA@X`$\]P@0`H+K5XP*`J<*EQ%@GO +M_PC:\0`O\@IP\<"*"`_RSW"``!RV&G`I@.2``>$IH"8*+_L!V#+P+RC!`TX@ +MC0>O?80M"1_/<(```#TR($$.BB(&`$Q]SW"``#2L`"!.#A-I%GC/0`AC0^``)RQ+861Z3=H-'G/`$0=@!\````0!/``V!&E/0`/\O'`H@_/\0AW +M6G'`@"APAB#\#(P@`X)*)D`@PB:")1=N%'@`()0/@`"(0#:1:_)<+(-H!0!V0B/AP@0`!,('B%$(@`C"P@1`@#:1Z\3\">/3"8` +MH-$@(J$1\@F/#^@*CXWHSW"``%RV`(")Z`'A+WHGK\EP;@V@%`+9!X]#"-(` +MFA0`)ZFXFAP<(!J'A[@:IP(-(`#)<.EP#0L0((X,(``"V07PW@D@``39`=@+ +MK\=V@``\M@R.@;@,K@#8!Z\`V0N/**\IKZ+H42``H,]Q@`#0L0!AANCI<`/9?@D` +M`*T&S_'QP'(.S_&@@`AV]VWT?\]P@`"8K#`@T`/:#F__J7#/<(``KJSI8*EP +M_@V@%`?:(@D@`,EP4@X@`*EP3"``H,EP#-G*(>$",@D``)$&S_'@>/'`)@[/ +M\:'!"'4H<$AW$PMR`,"%J7"Z"R```=E,\.EQAB']#(PA`H(S]`]XA@^@"\EQ +MC"##C\H@(0`3\L]Q@`"PY2"!![Y`P3(D`#``V0\A`0#/<(``[*S4?LA@)'@9 +MZ,O)H!`!`!J%#PE1`*"X&J4!V`FM`_"`N!JESW"@```@&X`#I:EPH@@@``+9 +M%/#I<(8@_`",(`.$#O1`)0`4)H`D@2"!K@L@$Y8A"@``A6()[_\0V=T%[_&A +MP.!XD>@`V!'P+RD!`$XA@P#J`0("EN3J@SW"``,`4N03@!?`@@`#@ +M>'$%(``H<.!XE07O]"APX'CQP`AR9(IPX`3K_@Z@!"]YT<#@?O'`S@S/\<]U +M@``%"!46$`'@!Z4-\,EP?@H@``39Z7`N#R__BB%,``0FUB3-#A`@+RB! +M!4X@CP<7;Q1X`"".#X``G*L`()4/@`"X%'C'<(``G*M%`@`` +MX'CQP-8+S_'/=8``'+8!A8#@RB"!#P``(0.P#0'R!H4!X`:E'O"FN!JGZ7"N +M#N__"-D6\"\H`0!.((X'A"X)'\]P@```/3(@3PY.#N__R7`3;Q9XSW&``-"Q +M`&$&Z`&%Z^CA`\_Q]V[T?\=W@`"`:>X&J?Z#:`)R7`:AZ4(GX'9 +M"%Z!)@[O_^EP&H>EN!JGZ7!:"B``!-F`X*`)(0#*(,$#W/'QP"H+[_$%V0AV +MMVBT?0`ED!^``)RK5B"-(^P<2+//<(``"/9!P,]P@`!P#T+`SW"``'@/0\`` +MWT3'"]@-VNES"B2`#X``@`\*)8`/@``\#THFP`T6#*`$2B=``,]Q`0#`L6(. +MH`2I<"H((`#)<%8@0"+/'&-V@T><=Q@`",]Q@`#0K!!AAB#W#X#@`=C@?\!X\<#/<8``P`@@D0#: +M`^E(<`7PV@_/__WH`=C1P.!^X'@'N!1XQW"``)RK80```.!X"''/">_Q"MD(=K=HM'W'=8``G*O&#.__J7#2"2`` +MR7``V`"E!:T&K0NM!ZT(K0FM"JT#I1FE&J4;I14"[_$$K9D$[_\'V>!X\<"" +M"<_Q&G`H=AF!H(&"X$HC0"#W;?1_SW"``.RLZ&#"(\(D4R#1`(0M"1_/<(`` +M`#TR(%(.-@_@$D`A``LN#^`20"8`%*EPJ@LO_QC90"K`(!9XSW&``-"Q`&&D +MZ*EPQ@JO_P39!N@&"Z_YJ7`<\,]P@`"@F@!?AV#_``V(RX#-D!VJES3B($``HE@`\````8@@J@!=AVSW$` +M`&QAR7`!V@#;`@F@!4HD@`'/<8``P!2U>0"AUW"MJ_[*`=C1`._QPB`!`/'` +MX<5W:'1[QW.``)RK`K@6>`#:`"",#X``:/M`I('ARB#!`#`+X?_*(8$`I0#/ +M\?'`*@CO\2AP*'7V"N__P(&B"._TJ7#)<)8/8!0!V0#9SW"``%RV(*#/<(`` +M8+9M`._Q(*#QP/8/C_$(=K=HM'W'=8``G*NZ#>`20"4`&[(-X!)`)0`4J@W@ +M$E8E0!+)<"8*+_\>V0#8,0#O\4$=&!#QP`"!.@]@%`#9K@R@#`#8T<#@?O'` +MX<4(=78-X!(LX`"%]@DO_PC9`-@)`._Q&:7QP(8/K_$H<"AU5@KO_^"!`-[9 +MI>EPT@DO_PC9\LD1(,"#9`RB#,H@@@/)!X_QX'CQP.'%U@RO_@AUJ7`N"2`( +M`-FB#6_ZJ7`"#R__J7!J":_ZJ7"M!X_Q\<`R#Z_Q!+@6>,]Q@`"\1SA@0"`- +M"`"%`-X>"R_[R7'`I9H)[_H,V'D'C_'QP.'%,V@V><]R@`#(L2%BSW6!`'`T +M(Z66""``!]E`)0`25@NO]A#950>/\?'`U@ZO\0G:"'7/<8``H+$#N!9X'V&X +M',BSSW"``$SV0<#/<(``7!!"P,]P@`!@$$/``-Y$Q@[8!-G)``@D0^``)RQ +MJ7`*".`$`-D(=\H/H`0`IHWH%P@0(D`H`280O:5YBB`$!!((+_+E>3@1`"`) +MZ"\A!P1`(0`A!@B@!,ER60:/\>!X\<#R#:_Q`=D:<"02CP"S:+9]QW6``)RQ +MRX6!Y\(A00""#^__!>$'[@#8"Z4*<&!^Z7$I!H_QX'CQP,(-C_'/=8$`<#0C +MI0#9*+4EI0HAP(!$M'%A4`E`!(*"J_V$-D!!J_QR7#@>/'` +MB@V/\<]U@0!P-".E`-DEI0HAP(!$M!X\<#B#*_Q&=C/=X``G+-2#J_Z +MI1<.%A?P+RB!`TX@C0>O?1-M%G@`(($/@`"C`1@0`0 +M)DX3[.X`V`D%K_&E'Q@0X'CQP((,C_$(=CIQ2'=Z,]Q +M@`#`43A@SW&``'`GX'\`H?'`^@J/\0AUA"@)#P`AD'^``"`[;@BO_F\0#B9D +M$``@#N@-\"\H@0-.((\'[W^I<.X,+__I<1`FSA/V[F00`2#/<($`&!TCH!(* +MH`>I/'`X<4(=02``^@&A87HD@SO\8H@A`8DA0:%"PD!`!1X!J4% +M`X_QX'CQP.'%A"@)#P`AC7^``"`[.84-Z31H-GG/<(``O$=J"N_Z(&`"@'\= +M&!#5`H_QX'CQP.'%SW6``(`(J7#V"^`3`=G*#X`"`(7/<:``@$01"%$`9!F` +M#P`&)@`$\`#8&:&=`H_Q\<#AQ<]U@`#8^ZEPP@O@$PS96@QO^:EPC@^``GT" +MC_'QP.H)K_$"V8(D`C6+=:(+X!.I<+H.8!2I<`#``<5:<"\D!R#/=H``(#M` +M)A$2BB<)'P7.`-D:<:X.;_:HVHHA!`L*<`;P4FA#<@P:6``!X/<(%($0&E@P +M"AI8,`L:6#`9#5`0J0V0$(/ERO(-V`JXB@OO\:EQP_!Z#F`+2G`$+/XC,"%0 +M+A\,$2!,(("AS"#BH"@Z@!XIP`""0)OL0`*8B@&!YBG`C +MAHIPT@AO_JERB@K@`HIP.@E@#8IP3"0`H:`/)?K*(`4%R@AO_(IPM@C``[CP +M!"S^(P`F4QY`)!$R0",`(BIQN@[@$!?:5210-E4C0"8*<:H.X!`,VKX-8`M* +M<`@3`2`"PE!QRB""#P``'#2X"L+Q!"S^(P`F4AZO>HIPJ@I@"T`B`2YR#:`' +MBG`,$@`@`\$;"$``BG`^"&_^`]H,$@$@BG`R"&_^`=H$+/XC0"R`($-P^Q`` +MAB=V@X`J<$`F`1(*0#:#R)"`(P@_X_*)8(0 +MRB4A$'(*H`2*<`5]#O`O*$$#3B".!Q)N0W#[$`"&$"6-$RZ`8'G)$"@O@\O_,EP`<`S")$`SW"@```@>X!`A0#`?F(/ +M?,]Q@`!$6)5YP*&&ZDX)[_I@I0?PSW"``/C7/@V/^&X,@`)-!V_QHL#QP,8. +M;_$"V;3!BW5^".`3A,!R"J`%!,`*(H`O@``@.P3!0"(4(HHG"1\A"%``+WCL +M>``B0RY`@\]P```#-"BZ3WJJ"._Q88,DP%/`['@P)%,NDL`V".`3`=D%P1D) +M4`""X7WR@^&/\L]P```5-&H(S_&=\`#8?@JO^CIP$L$(=I'ARB"&#P``)C1, +M",;Q0"8`$OH/H!,&V2^6&0G>`UR.C"+#C\H@@0\``"@T,`C!\0'8(!X"$`3` +M$L$!I@H@@"^``&CK]"!`(!&V`X:,(/^/)AY"$`WTBB`$"P.FSW"@```@&X`" +MI@^612```P^V#Y8/"-X"SW"@```@&X`"ICT+42*3P68(H`<(V!CH!!``(1&V +M$\#L>``B02X9@0P>0!3'<````+`"IBS8!J;_V!RN'1Y"%!R!!::^"0`'`(8. +M"Z_Z`=DDP.QX,"1!+H;A=`B!"`"&`J42P"CPAL`N#Z`3!MF6"0`'$L`)P48/ +MK_H*PH#@$L'*($(`2`JB^LHA8@`0\(S`!@^@$P;9$L!6">_Z`=DDP.QX,"1! +M+H;A3`B!"!+``J6*(/\/`:4$P`.E`-@`I:EP;@F@`A#9905O\;3`\<`>#4_Q +M`-[)<.8(H`G)<<]U@`#\%*EP2@F@`@C9Q*W`I>8-8!`"V,]P1``8DF();_90 +MV5D%3_'QP.8,;_$4V<]V1``8DH8.H!/)<,]U@`#\%*EP#@F@`@C9>@U@$`+8 +M,(Z`XD$3_'@>/'`8@QO\?39@B0#/7(- +MH!.+<`$4@3`"%((PB.',(B&!RB""#P``90!(#J+QSR`B`R#`(PA1``#9"O`` +MVL]P@`"$_C9X0;!`J`'A+WGO"1*!@?"!P`HA@"^``*3]*G'J">`0.-H`W@SP +M`I``(3^UG_I<;8)X!`! +MV@#8`K>$+@D?SW"``"@[,"!-#CT-$1(!EX#@RB""#P``8P#/("(#RB&"`[`- +MHO'*(D(#`(^`X,H@@@\``&0`SR`B`\HA@@.4#:+QRB)"`P#=!/`!Y:]]?0T3 +MD@&7^0A.@T0M/A<`(5(N`A*`(`H@0"Z`X,H@C`\``&(`SR`L`\HAC`-8#:SQ +MRB),`P#8"/`P!18'@`48!Y`%,]P@`"!X\!@R@$X'`&G8Z=A'P`-T/)4T0 +M"R4`E,H@@@\``!DP-`R"\04@4"-`(5$@A0D5(4`IC2"T?8-U`86,(/^/]?/^ +M"0_[(85"A6.%!^B,(@*`@-S,(PZ#QO?/<```&#`*#(_Q)(W/M!@(?J!!B` +M#P```%``VD*@`-T/)4T0I7ZU\4<@PB,3\"\H@0!.((,'SW&!`*0;%&LX8""` +M!^D`V2"@(:`/)LX0$"+"`._JU0X0$,]U@0"@#P"%,P@?``'9SW"```3_*J`` +MV@WP-&K'<8$`H!L!@0'BA2@!"4$IP'$!H02AZPH4@8X-P`:`1&G``A7\( +M7P![")0@_]\`W>EV`_`!Y:]].0T3$<8/[_JI<`3PJ7<0((``=>@O*0$`3B&" +M!X0J"0_/<8``*#LP(4$.XPE0@8?ARB9!$^[QT7?*(((/``#_`,PG`I#,)@*0 +M$?(PV@2_SW"!`*`;0"`!`OEA0*%8V02^V&`BH`'9(Z#/=8$`A`\&A1)P<`B" +M^A@=`!0`V$#`BW#N#&`"!-GY`&_QK<#@>/'`=@AO\0;9I\&!P#H*H!-:<`'! +M+R!'($P@P*#*(.8`<`JF\<`H)@//=H``1!M`*(`@%'A`)@$9`F&*)_\?`B+` +M@P+!RB!B`!\)4`""X0'#D_*#X90"`0#/<```!3`^"J_Q:'*(\`CHSW````$P +M+@JO\0'"`<%*)``@+R!'($`H@"`4>-A@^G`IH`HA`"6*=2KP%2)6)`@6`B!) +M"L`#0"14("\CAR!,(T"ARB"&#P``%##H":;QRB%&!!4FU10`%0(@\7+*(((/ +M```*,,P)HO'*(0($"!8!(`\ES10`'4`@0"%1(*\)U*`H'T`C%PP1(``2`2#/ +M<```"S"B":_Q)!<"(!02`2`O(4<@3"$`H"*_Q!!(" +M($`M@"`4>``F%!`H%``@I7BG>#IP'?`O*`$`3B"0!PIP`@T@"P#9\"8`%!D( +MP0,`$@$@SW```!`P7@BO\2@4`B``V-X/;_H/(``$$"8`)`HF`*#C]2@<0",4 +M$@$@+W@5)A00#P@U`104`B`Y"8``SW```!$P(@B/\13P+RA!`TX@D`<5"PXD +M%28!%%090`4>"V`'`($*<(X,(`L!V1`E#13M[?8,+_)*``F$Q`L$P`@*!,2(!4F#1!N +M#Z`(!87EI2'P+RB!`$X@D0<5)DT4`(7Q<,H@@0\``!(P:`]A\-A@*8#M"<"#JH!T[2\H00-.()`' +MA"@)+\]Q@``H.S`A0`X/")$!$@A@"`IP!>@:A@#=`>`:IA`E#13I\0`<0#2+ +M!X\'0"8! +M'/`E`!`$N!1X&6%R"R`&!-B(AFF&2H8KAL]PH`"`'XR@?*!=H#^@C@L@!D`F +M`!;/=H``X!``AH#@K`H!!G8-[_H!W8(.S_I3A\]Q@`#`"`"!XKK/(.$`T"#B +M`$8-+_L`H5X(#_L2AX'@`-C*(.(`*@HO^P#9H*81!`_Q\<"AP8MP3@U@$P'9 +M'@E``@#`SW)$`+CT-)+GN-,@H@'/(0(`T"$!`#2RH<#1P.!^SW"``,0;'05@ +M$PC9\<#AQ<]P@`#<5M(/[_5"F`#`-C/<(`` +MW%7J#&`30-DB"````=G/<(``5*`IH"J@J7!J#R`"BB$7!94##_'QP.X*+_&* +M(@8,"B&`+Z<`@$E`$14@"B.`+X``E)8@$P`A@B0&/D#`"B&`/X``Y!Q`)!@Q +M*W#V#V`0"W$*)(`O@`",JP`4@"#/=X``W%98'P(02B)`(,]U@`!<5B>%SW:` +M`-Q54!^`%$HG`""'Z0&&#PB0`0"&"PA0``L)40!0'\`5#(9*)H`G`^@T%A80 +M(H9*($`@/7@!IP.&$'$"#J`(PB`")!^W)X8T'X05`=B!XG!H8)IPB&"*<+A38?Q!4,Z$`G`!P*#^_\(8>`X`'8P'@*IRP?@!06#T_V +M<@^O_0#8F@V`"('@`=C"(`$`@.`!V`#V,!X[@]`"`B%(H81IPF%#KDE>"F&$J<&Z2J& +M"[D%>3*G!88:#^_\)(8#I__9SW"``(@S(*@AAE#8AN'4`2T`&;A +MZ@`4@""*#V_V(8<&#:`(&G"+<4X/8`B`(08-,B2`/P``M`$AAX0HA04O<(0I +MP@HG<``@@0]$`#CW"G`F#F`0J]H.#V`(`-BU\50?@!1`&4`E#(:`X$P*@?;/ +M<(``7"&.#:_V`=FG\3H*K_8!W1IU`H;/<8``,"`+H1J7`-T`H02&#*$%A@VA +MSW"G``!]"H#/=H``3#)!*`($R;@!H<]P@`!4@AZ80J$*H0#`(!L$(.(-K_T! +MV,X.H`NI<*EP]@EO_*EQ"W`K<9H-8!"*(@8,`!X`%`'83@X@`ZEQ"@F@"%@7 +M@!"@ID`90"6!`"_Q@"0&/@"�A1`$`90"54'X`4SW"``%PAZ@RO]@'9SW"` +M`#`@,@Y/]D_Q#H;/<8``N"`0IT`F`!\3IPJ%;@]O]@#:0?$AA\]P@``$'O4@ +M4`!`&4`ESW6``+`A.I>I<.X)K_9;GZEP$Z@V/ +M]M+QSW```+HHV@E/\1_Q\<#.#^_P`-C@'`BPSW"``+CD`(#/<8``'.9!P(+` +M3@LO\1C:SW5%`)0LJ7`>#._UJ-F+<`'94@E@$QIQ`,%`)1$5%PG?`,]P10!@ +M(R"@!.`V"6`3!=G/=J``@"`=AHHAC@$D>,]WH```(`D(0``]I@#`*PC>`$+` +M@\`."6`3!=D"P`\(40`6#^_T`=A'\(3@"`_A],H@H0!!\,]P10!@(P"`4R"^ +M@`WT#!^`'P@```!\'@`4`=CR"N_T`-DO\%\('@`!V.(*[_0`V0P?@!\(```` +M?!X`%.(-C_<_"%$`?@V/]\]P@`",JP"(C"##CQ+T`-@-\*05`1`/"0X`6X`0@OH\"`&P`#O0`AHSHSW"` +M`##1SW(``/\+M@Q@#XHA"0VV#8`'703/\/'`\@OO\`/9SW"``,SE`(#/=40` +MO)/AP(8-(!.I<,]QH```-`"!L+@`H8MP"@@@`@39`(4+Z,]QH```(#N!&6'/ +M<(``O-C6"0`2SW9%`#0X`(8/")X#`H6`X,`.`@D!V<]P@`!(%5H*H`<@H`#9 +M#PB0`,]P@`!8%2"@SW!$``SR(*#/<$0`$/(@H,]R@`#\^4`:0@`HN4$:0@`H +MN4(:0@`HN1F.0QI"`.2X;`P"%$X.``E:#P`5(@S`#QX/@!3N#``4@>`0#0$4 +MSW"@``!\$8``V0/;$+L$(,(`<'+*(N$`P"HA!L0@@0#,((&`RB%A`&SI42!` +MQ`'9PB%!`%$BP,8!V,(@`0`K>.#S!]@*N,#9&+GB#F_T`-JF"8`'$0C1`,]Q +MH```1@"!WK@`H34#[_"AP.!X'0>``?'`M@K/\,]P@`"\Y""``8"FP47`SW:@ +M```0"89$P0#="NC/<(``C*O6"*`(`(B!X,HE81"+<#(,(!,$V0#`1P@>``'" +MSW&``&@H`($&ZJ&XU@R@`@"A%_"@N(&X`*'/<*``@$4P&(`/`"```0'9SW"` +M`&PH(*!J(8`!SW"``'`H(*``P%L(7@`2#P`2`-@-#5$0":;."``+!=_/=J`` +M`#`('H`?````H`#88@VO^O_96@^@$Q[8`L#/<:(``'@F&1B``\`-OY@9``"! +MY>P.(1+*(&$`XZ8`V-(,K_K_V<]QH@``>"81`(9$P)@1``!%P(3`#@[@`0C9 +M*0+O\*;`X'CQP`'8X<#/<(``J"=:"R`3']F+<.H-X`$$V:'`T<#@?O'`N,&+ +M<$(+(!,$V0#``-M%P`'`!=I&P`?81,#/<*``@`Q`&(`/`+@(`.;)%;H`'P!` +M:Z+/<:```#P'@0FA:J$L&H`/`(#"``/8`MGJ#N`!`=J6":`%A,"XP-'`X'[@ +M>/'`X<6AP8MPW@H@$P'9`!0-,:X/8!.I<%,E`!#AO_PH<#QP*'!BW`."B`3!-D!V<]P@`!$,JH((`,@H,X)``]N#L`!H<#1 +MP.!^\<#6"._PBB#_#QIPG!P(L('`>@H@$P+9`L<$)X`?`'```#RX4R?"%AL( +MM`$!Q<]QH```!`2!N&`$H8H@?P]`P%;PSW&``(S@\"$!`,]S@`!TX/`C```; +M"(4`SW&@```$!(&X8`2ABB`_#T#`0/!3>%9X&6&#P/H+[_`'V@/&B^[/<:`` +M``0$@;A@!*$`'``T+O`0%`,Q$PW`$$,/WQ<2%(`P.P@0`1(4@#`7"!$!A<6I +M<-H)(!-H<6!^J7`E\/^_T2!B@`CRR7#""2`3:'$!V$#`#O`9"!X`#^W/<:`` +M``0$@;A@!*&*(+\/0,"+<#8,X`$$V0GP`=A`P(MP!-G)/\.!X\<`*#Z_P`=FAP0#=J@@@$XMPC@[@`@'8 +M`12",`+P`>45#942SW!$`(33MG@@D/,*08`#\`#8$>AAD,]T@``T?:*0`)!` +M)`$5/64+")$$0"0-%0#>!/`"W@#=J7,@P$L(40`"%`$Q%PM``,]P```@*Y(( +M+_%(<0(4`3&2[IH/X!*I<,]P@`",JT"(Q@Q@"$AP@.!$#F+[RB""``7P&@O@ +M"BAP`-L%\(#@RB9B$?OU0",``U,@00`X8`/@!""`#P``_/\%((`/`+@``,]R +MH`"`#!"BYLD"',0P`!\`0`#"`!^`0`#:!?!+90`?PD`!X@(4`#'W"@2``-H% +M\`#;`!_"0`'B^PI$@,EP`=F>"^`!*')I!J_PH<#@>/'`U@V/\,]P@`",JQ8+ +MK_P`$)4`A"@!#,]U@`#D',]V1`!4X,EP`"53'CH*K_7HV0HA@"^``&0>'A'` +M(`"F&!%`(0&FF!5`%P2FH!5`%P.FO!5`%P*F&!,`(`\(4`!($P`@"PA1``+8 +M`O`!V`6F`-@(\""``8`RI1.E0"1`(!!X`,I68+ +M[_(&A\]Q@`#4'0FE&)<.I02?"*4%GQ&E0"R`(!5X`F&*<`0HO@0`($`N0^HB +M@,+Q529`%0#9JG+R":_[&!,#(%8FP!0!V:IRX@FO^T@3`R`D$0`@Y!X`$,EP +M&@G@`>C9"06/\.!X\<#AQ;3!@L#.#>`2&-F+=:EP*@FO]0C95@F@$R+`SW&` +M`'18]"$``"+"`!P$,"/!B,!6#V_\)\,&P`7!`KB#/'`SW"@`(`,0!B`#P"@!`#FR0+9U@G@`0':`@Q`$-'`X'[@>/'`)@RO\`'8 +MSW:``$`5`*[/<(``5((>F'(.(`(!V4"!`-T/)8T0"WT'\@&!0'C$R:9XQ!H8L`'GWP\4D@(/+_D#V`#8-02O\`"N +MX'CQP.'%K,&+=:EP:@W@$@K9`<$5"5``&PG0`$/8H@WO\`BX"_"*P4H/X`BI +M<`7PBL&F#^`(J7"*P-(/H`$(V0$$K_"LP/'`=@N/\*?!SW&``'19`"&.#P`` +M!`T!AD`A$0'_W0B]C^B+<`H-X!('V0`4#S$"%)`PY'U(O>]_`<`-I@CPXH8, +M%I`0Y'THO:]][W\2#\`$G@S`!`AV#0C1``'=`-\8\!<($20!V)4A2B,`&0`@ +M"'4(=@#?#/!5"%$D0@S@!`'=P@[@!`AV"'>&YL!]$PA1(K(.P`1")@V1"'?* +M)6(0SW"``*@G%8@5"%X`SW"@_K@.`=EN"V`"Z7+)<.EQI@A@!:ER&0.O\*?` +MJ7#I<5()(`4*<@AVP_'@>/'`J@JO\!39SW"@```$`X#/=0``K=ZP'`BPBW8Z +M#.`2R7``P&&XB0B5!3,F`'"``.#B0">!@^@ +M`0':10*O\+3`X'CQP*'!BW!V"^`2`=D`P`79P+@4><]RH@`D<`""1B#``25X +M`*(N#X`!H<#1P.!^X'CQP.'%I,&+=:EPSW&``+3E'@VO\!#:J7"2"N`2$-D& +M#X`!`,`3"%``&PB0`)O88@OO\(VX"O`!P`+!=@]@!@/"!/`:"*`&`<#-`:_P +MI,#@>/'`1@FO\`/9@B0"-P#?1L=%QXMPY@K@$AIQSLU"N"MH`,`"Q0L(D`"I +M<.EU!?`;#141`=A"P`3H'PA4"+X-H`H2:038`_!%Q_#Q1,"$P$8-H`$,V3?P +MA\:B"N`2R7`"P@'!"6H5(0,`SW"@``!-F(`8@->\!""`#P`/```XN`JX"PDD +M`YA@#PD$`!$+!`,-"P4`$!P`--SQ`,,(ZX'CS".B@!7R`=C3\2AP>@[@#\EQ +M`L-$QT7#A,`(V@W@#ZER1,>P\>!^X'CQP%8(C_"LP0#?O@L@"&O'@>`!WL(F +M@1.+=:EPZ@G@$@O9`]C/"*_TZ7`O\"X,K_3I<+(( +M8`CI<$X,(`CI<`(,K_3I<"'PB\>I<,EQ!@ZO].ERJ7#)<=(-K_3IV!"J +M`>'O"92#&8\XCPBX!7D:CQ"X!7D;CQBX!7D!V/2YPB`!`!"GSW"``'`X(X`: +M<`'A(Z`0A\]Q@`#P.3'H68\8CPBZ17A:CQ"Z17A;CQBZ17C3N-=P```88![R +M"O8Y"!`&V.`7\HP@!88.\AGPUW`!`%A@S"""CP$`6&$+\A\(@0\%`%AA#!F` +M#P``N`L*\(H@'P0'\(H@#PH#\(H@_P\#H8WN#>T."V`/$-@($``@AB"_"Y'@ +MP`_!]`7P!>Z`Y;0(P?09#9$0$@_/])X/C_3.#X_T8@W/]`7P@N8\"L'T?@O@ +M!?_8%@T/]5X/S_0V#\_T9@L/]<8+@`&=!D_P\<#AQ:K!BW6I<#X/H!(HV:EP +MSW&``-0Y,@O@#RC:I@C/])X+@`&-!F_PJL#QP.'%SW6``-`X0"4`$@X/H!)0 +MV88(S_0B#^`20"4`$L]P@`#P.1@0P8`W$,*`C"$^@'_!2E^&`5I?8.X!+)<*X.C_3>#H_T +M.@P/]8(.S_1:#L_T9@S/].H*@`')!6_PHL#QP.'%SW6``/`W525`%UH.H!($ +MV4H.X!)5)4`7P@J``;$%3_#QP#8-;_`(V:C!BW76#J`2J7"J"H`!`,!;"-X! +M`-L-\%,B3`*+O(^\0"P.%,5\@:%4>D2Q`>,U"Q,!,FL`)$(P0X(T><=Q@``\ +M#HPBSX]`H>CW02I,`+,(N*!!?2F"`_^!?""P!H.H!()V>X) +M@`&KP-'`X'[QP*[!BW`&#J`2#MD`P![HK@[@"HH@4``0%`0P`-@"P0'"B@[@ +M"@/#`=@@%`0P!L$%PGH.X`H'PPW!0B$`@(H)H`+*(&(`!?!V#N`*`-B6"8`! +MKL#1P.!^\<`&#&_P`]G/<*```"`;@*7!1,">#:`2BW`@P0$4@C"#XZ`FP&E!,`0N0&E`12`,"5X`:4"P`'! +M`:4AI0#>"?"#P%8-H!(!V0/``>8!I2#`8[CQ#@20A,#6#V`!!-G]`V_PI<#Q +MP((+3_"EP8+``]TF#:`2J7$BP,]Q@`"P&\"X`*$)%($P$0FS``H4@C",(@2` +MAO=6#:_PBB`.`,]V@``040#?$O`S;S5Y.F9H@@/`%PL!`%*2$!0`,0\*`0#8 +M89H/+_4HV0'GWP^4D`D4@#`#N!5X`\+88`3!2*`IH`L4@3`1"5$`_]GF#R_U +M(-HL\&H/+_4@V0#?'O"+<((-H!(#V0`4`#$"%`$Q"12","=X!!0!,0.Z)WA! +M*`$")W@/>2.YV6%5>CIB((K"N`\A`0`@J@'G"A2`,,,/!)#/<*````2JH"H( +M@`$)`V_PI<#@>/'`I\$!V$;`BW`^#*`2!MD`P<4)T`#/`)+HSW*B```(!H*$N`:B!H*#N`:B +MBB(0`,]PH@``N$J@!_`#VL]PK0``!%V@SW*M`(`P(:(`V`BB.@_@!@#8AL`* +M#F`!!-D`P(/@`-C*(&$`$@A`$*?`T<#@?O'`H<&+<+(*H!($V2(/0`&AP-'` +MX'[@>/'``!8`0,]P@`#443(+H!(&V?H*``<"#T`!T<#@?N!XX'[@>.!^X'CQ +MP.'%H\&+<`X+H!(#V0'"SW2``"`[3WT;#341BB,)#VQ]`"1`'B"`"PI!``&` +M%PA0`&Q],"1#'F#8C+@Z"Z_PJ7$`P,]Q@`!0,!4(4``1")$`"!0`,14A3`,` +MI"APM7A.#6`!#-E]`6_PH\!=!0`!SW!%`#@L.05@`5S9\<#""$_P'@I@!Z3! +M&G#/<(``C*LN"^`'`!"7``]X0,#/=40`@-^I<'(*H!(UV4HB`"!2"*`"2G`" +M"R_\0"49%`HD@"]$``#@0!0!($`E&!,/Z4P@`*#*(((/``"V&8@*@O!`%`$@ +MSW"``%2@)Z`@%`(@SW>``.0<"B6`+X``9!X1Z@'8SW&``%25+!T`(`L*40`1 +MH03P1!F`!`#81@U``@/P+!V`)$"%@<%`)0`3B@QO\@IS`(6!X,P@HH!5]`#> +M*O!!*8`"P;@+(,"$%_1F"^`'ZG!Z"V_RR7%$+CX7:.`P($(^#GM.>!!SRB"% +M#P``K1D("J7PRB&%`]MX@W`@A0*80B%"@,EQRB)B`&X*+_PJ?EA!J$(AA2Q!X8( +MH46&"PBT`$FA8;@(H0F&0"%1(!BQS0F4H$B'SW:``'@+`(8TA\]S@``X\/0C +M@@`$((`/\__G__0C00`#NA*Y17DE>`"F!H>:#J`*,H=8%X`0*!>!$`BX!""` +M#P```/\%><]PIP``2"N@.)=@%P(1R+D)N@0B@@\#``#^17EQ&%@`)!<1$`#8 +M8@_@"BIQ2B-`(&IP5@_@"BIQ*8`&F!H4> +M#^`*+87/<(``E)8@&,0$`_#6"`_\3"``H.;T`87/=H``9!T+IQ>G!Z9)A1.F +M6+A!02 +M&80D#?""X"`+`?LIA1"%.; +M`%()P`>!X`'8.@TO^\!XT@N`!QF%%PC1`"0>`!0'\(+AP`NA!\H@(0`:A4(@ +M@(#N"*_SRB!B`!R%PPA1`.X+X`?J<+<($``*">`'2B%`(('@2B!`(,(@`21F +M"6_R!!0`(,]V@`!X"YAP!H8]A:NXM;@&I@D)'@"+N`:F"0E>`)6X!J8`%`,@ +M`=A\%040"G%X%080B'(F"Z`*F',(%``@#!0!((3@`=C`>(3A`=F.#*`*P'D( +M%`(@"PH1`0/:"!R`(`P4`"`-"!$!`]@,'``@((8-N@0A@0__S_^?!"*"#P`` +M`&`2"F(!U`)`;P'(4)"-$`(!V`)"04`"`A"%$`SW:` +M`,0=5B<`%U8E017>":`/$-H*C@NN#*X-KIX(X`H\%``@.@I```2X!7E$(8`#''@'N"5X`K7/<(``9!(!V2"@SW"``%14`-D@H`G83@NO^!C9 +MSW&``&!4`*$`)H$?````""*@(8TFH"&-):`CE3RH"=B&"Z_X`=G/<(``6%3J +M"2_UP*`U!`_PX'CQP+(++_`"V:;!2@Y@$H'`!!0`,6&XA.`:`0T`,B8`<(`` +MQ.-`)P%R%'D`>8/`G@Q@$@C9`\&`X0#=SR7B$LHE@1\```0&3B%``0NX`"". +M#X``2'W)<'8,8!*I<0XED!\````(`-\'\(7``@U@$@'9`>=!*(`@]0\$D,EP +M02V!$`7:'@RO]P3#;O""P-X,8!(!V6KPSW"@```$PX"Z"2_[R7`:<,]Q@`"4 +MH`:1`-W0?@'@%PZS$`:QBB88%`HA`"2`(1@C"/"*)A49K-T*(0`D@"$5*`IP +ME@Q@$D$N@1``WP;P@L"&#&`2`=D!YT$M@!#S#P20+&X*<"*Y!-JB"Z_W`!$# +M(##PSW6``%18J7!>#&`2BB%.!CX(``K//'`SW"``$#F`(#AP(MPA@X@`039H<#1P.!^ +MX'CQP#(*+_`!V:'!BW72"V`2J7!F".`'(,``WA'H`12`,!L(DP`"%(`PTN!# +M]H?H`XW2X$3V`-Z#Z`'>D>Y#C0*-&+H0N`5Z`8T@C0BX!7K/<```40G6"V_P +M17DJ#V_[(,`(=0$4@#`,Z!T(40`"%(`P`N@!K0,4@#`&Z`7P7]@!K638`JW/ +M<(``5%@!@"$('P//<(``C*L@B"#`%0A!`-H/@`>`X#P,HOO*($(#"@\``?$! +M+_"AP.!X\<%P,T/!)`!V``8`"`1\,]U@`!,5P&%@.#*(((/```*+,0*0O``V(8, +MX`<`I<]Q@`!,5PF!!*$=`2_P@"0".O'`L@@O\&K9SW6!`.`T5@I@$JEP`(4I +M"!X`SW9$`$SO0"4`$D`F@16>#6`/!-I`)0`30"8!%)(-8`\&V@"%/0A>`"6% +MC.'*((T/``"R#6`*3?``WD`E#Q8-\$2'A.+*((8/``"S#5`*9O#*(88#`>84 +MYP6%YPX$D,(-``&A``_P\<"HP2X(8`(`V(#@RB""#P```T00"D+PBW#*"6`2 +M"-F:#0`!`,`-Z",(4``M")``SW````X[^@EO\`+9&/#/<:```#`+@9^X$?#/ +M<:```#`*@9FXF[@(\,]QH```,`J!N;B[N`JA"X'>N`NA`<`-Z"\(4`!=")`` +MSW````X[L@EO\`/9.O!0V<]PK0``A"B@BB%0`,]PK0``JB&@+O!0V<]PK0`` +M1"B@SW*M```J`(*&(/`'02@!`0&"1B"`#R5X@+B*N(NX`:+/<*T``&H2\!#9 +MSW"M``!$**!`V<]PK0``A"B@BB%0`,]PK0``JB&@(!B`#P```"`"P`OH'PA0 +M`,]P```..RH);_`$V1_P(-G/<*T``(0HH!GP(-G/<*T``$0HH,]RK0``*@B" +M`\$$((`/__\?X`6Y)7@(HB>""(+$N48@P``BB!,#/!X!6"SW&D +M``!(SR"A`-`@H@`5H@7`#PB1``,1`(:"N`,9&(`%P`\(40`#$0"&HK@#&1B` +M!<`,Z`;`!\+&N`>Z!"*"#P``@#]%>`09&("HP-'`X'[@>/'`A@[/[Z[!SW:@ +M```0Z8;/<(``C*N@B`#8"@X@`AIP?@@`!H#@RB""#P```@E0"$+P@<`&"&`2 +M#=D!P`3!4B```,"X8,`"P`(<0C`#P0$<`C`B>(P@OXX+\@\(D``/")`!"G`& +M\`38!/`%V`+P`=@#'`(P`,$!V,H.8`?_VLH)X`H-P)8.0`=*#*`'J7"`X)`- +MH@?*($(#Z:9Z"P`!40;O[Z[`\<"IP8MPD@\@$@G9`,"9Z`'!SW*``#25"!1` +M,31Z`+(`V@SP\=S@`#LR8B#!PD!`P*C`>+M"A2$&?`M"%$`"A1`,0;9 +M!@PO_`':#!1`,0?9^@LO_`':#A1`,0C9[@LO_`':!?!6#2_\A,`""P`!J<#1 +MP.!^\_OBB'*",]U1`"HR`X/(!*I<.(*``'/=H$`A$I6)8`30"8!%!X+ +M8`\0VE8E`!/)<1(+8`\$VE4E0!Q6)@$5!@M@#Q#:525`&U8F@13V"F`/!-K/ +M=H$`I$NI<(`@"`!`)@$4X@I@#R#:5B6`'\EQU@I@#P3:$@J@"$`E#A<>#N`) +MR7#)<&8*H`A`V58EP!A>"J`(0-FI<(`@!0M2"J`(@-D!V<]P@`"LMS4%[^\@ +MH.!X\<"R#._O`MFBP6(.(!*+<,]W@`",JP"/Z@J@!SIP`-T*\'8(3__2#6`! +MJ7!F#Z_ZJ7`!Y5,-U1<`P+EX]P@>@`'!#.G?"5"`'0F0`,]P``"S$V8.#_#O +M\0H-8`&I<#H(3__I\0'8&G#/=H``0!4`KA$-T1/2"J_Z`(]"#6_Z"G``V`"N +MU_$`CS)PR`QB!\H@0@0V"$_XK@D``7T$[^^BP/'`SW&``(#!*(GFR0GI&@\@ +M`@'9`=C"#>`.`MD$\`H/(`("V='`X'[QP,]P@`!0Q?H,(!**(0D(:@D``='` +MX'[QP,]P10#@(^(,(!**(1\%SW!%`*`K,(BRX`"H2AP +MR@_@`(HA#`SU`\_O\<"Z#.`.X<6^#.`."'7/<8``$,@6H<]PH```(!N`LGVX +M8`'@%:%6(8`"E@_@`,C9P0//[P#8_03@#@AQ\<#AQ<+)".C7R8&XUQH8L`'= +M`_`"W<]R1`!XNR2*`MA*#*`20X(V"Z`.`-B"Y9@)(@W*(*(`@0//[^!X\<`" +M"\_OF!*"L.K)S1(,M\(2`[8`W1D('@<0O,]PQ>Z$=0'9A7H>#B`2F'7/=D0` +M>+LDC@#8^@N@$D.&PLFXZ/H.``T%EH8@?PR&Z-?)AKC7&ABP)(X`V`+P`>#_ +M"0&`YLG/<40`>,(9H0'>PAJ8L\,:6+//<0,`,+;/<@,`&*O//'`/@KO[PS9H\&+<$H+(!(:<`,4@C`I"A,(SW"``)0H`8`>Z`84@S`"%($P +M$0NS`0$4@#`)"5,")0@2!`84@#`!%($P"+@%>@(4@#`8N1"X!7J3V(VX[@LO +M\$5Y`Q2!,"_(5&E88#`2`C;/=8$`@'84(E$`(<*`XC9]S/(9"E``@N+(]`(4 +M@C``(8`/@`#D*$"HP_`%%((PSW:``)0H$NI@@$&`17M"@`.`97H%(+Z`RB"" +M#P``E`"("R+PSR!B`P,4@3#/=Z```#`2:<=PH```+S00!``T&(`/"`````#; +M`(8/(T,`:WA&\@44@C`&ZJX,H`T*<$#P.A<`EDHE0`!D>!!S`12,,,(E00$" +M%(`P!+R%>``1#"$X>I%P`=S")`$3FWP%)$`1DA<,EH1[4',!VL(B@0`"ND5X +M!Q2",&&%EKIP<@':PB*!``.Z!7H&%(,P4R2``!!S`=C"(`$`!+@%(@*`RB"" +M#P``E0#<"B+PSR!B`P,4@S``V@"&#R+"`$5X`12!,`"F%29`$(2`!+E%?(2@ +M`A2`,``CC`^``.0H!A2#,`"L=7Y\AB5X17M\ICH7`Y9E>CH?F)``&00@!12` +M,`,4@3`X>)(7`98E>)(?&)``V`"E!Q2`,):X`:4&%(`P(<&0N)&XDK@#N05Y +M!2&!#Q@!$``#%(`P`K@(%`(QQW"@```PK1B8@#080(`%\(X+H`T*<"'"@>+, +M(B*`(/0#%($PE.'*($4`RB!&`(?P"# +M`Q2",`0@@`\?````,+@A"@$`0"T!$@4A0000OV"#$+S/<```G2'E>8X)+_"% +M>@'FOPY$E`IPM@O@``39Q0>O[Z/`\#X_O2B``*,]UH```(#L=&)0`%@!` +MSW:@```4$*8`%@]`@.?*(($/```L)3`)(?#*(<$#ZJ9,'=B3`]@3I@'82QT8 +MD#P=&)2B#,``>0>/[^!X\<`.#Z_O$=G/=H$`K#>R""`2R7`NAL]U@`#LR1-I +M%7@"9>FZRB""#P``,R7D"`+P0(;/=X``$-]NAGT*WP(`AY3H$VL5>`!E_KC* +M(((/```H)<`((O#*(<(``=@`I\]R@``4WVZ&"_#/W`EP!#_V;ZX`*4`V`"GSW"``!3?(*#*"\`` +MJ0:/[^!X\<`2#J_O`MFHP=X/X!&+<`04ES``%)`PSW*``"@[0B(8`8HB"2\$ +M*+XD!125,#`B40Y3)8`@A^#*(($/```[)?`/X>_*(4$%"0]2(!$/4B'/<``` +M*27>#^_OZG$`V`3P0"1`(/)P,@$F`)IPAL!Z#^`1`MD9%(\P)L4?#S(4'!23 +M,(PGPY_*(((/```J):0/XN_*(<(#H0\3%,]V@``@OP0HOB0P($`^2B8`+8#@ +MS"&BH_* +M(<$#!"^^%0"&!.`*)D`N)W#Z#N`1!-D`ADPE0*#"<,PC8:,']``8A`\````0 +M`_``V2"P((9T(8`%!2!`!0"QSW"``$@5`(`.Z$"&="*!!4`M`!(E>`"R!O"" +MP+(.X!$$V0`E@!^``!R_X*@$*+XDSW"``-P\,"!"#H#BAO,O*($`3B"!!Q-I +MSW.```?*%7@+8Q$+3@,`)8`?@0#81#9XX*@0V+AX:W@(\@`E@!^!`-A$-GCD +MJ!`B0@#@\2H*P`#!!*_OJ,#QP(X,C^\""&`'H<&!X`'=)@A@!\(E01,(<9X, +MX`FI<.8/(`<(=40M?A0O=8;H`"6/'T4`C"X&\``ECQ]%`'POBW;)<`(.X!$! +MV=8/``?J#R`'.G`>"&`'&G`(<\]P@`!46`H0A``J<0#`"G(^#N_VN'?)<&H( +MX``$V7D$K^^AP/'`X<6DP8MUJ7"*#>`1#-DB#T_Z"@_`"18,8`>I<`'80\"# +MP#H(X``$V8(.C_E^#4_Y!@YO^0#84@]``54$K^^DP.!X\<"AP8MP?@W@$0'9 +M`,'/<(``E)9&">``,;"AP-'`X'[QP+8+K^]DVKG!BW;/<8``1.0V#Z_OR7#/ +M&!2P`'B[0H4@E'``-H+\%MY0W%N +M$0,',FJ#<7.A>&!1P`'B[PJ4@1H*``$@A07H`,!"P`"!0\`"@4W``X%.P,EP +M6@^@`&39@0.O[[G`\<`&"Z_O1-JQP8MWSW&``%CEB@ZO[^EPSW5`````SW`& +M``"`0<#/=H``>%0`AD#%`("X8(`@"`"Z"2`!1,`'Z`#`0L``A@"`0\``V0GP +M.WA#<&80`@<2:8-P1:`!X?,)%((@A@*!3<`#@4[`SW"``#C>`("X8$_`!8%0 +MP.EPT@Z@`$39[0*O[['`X'CQP.'%M\&+<"(,X!$7V8/`SW6``"R_J7%V#^`. +M4-J!P%8E@1-J#^`."-H`P$$H`000>#6E$0A0`!,(D`"#X.0(@0X'\.8(@`X# +M\+8(@`ZV#X``I0*O[[?`\<`""J_O"]FKP0A`JMC_8"[9*<`0L/B"%Y30@0"[,)>*1!?0GN`JV*[8.\!T-$1)!*`$# +M*+@'><.Y)!0`,06Y.&#(N`JV`L#I<@/!0":#%L8)(`\*)``%+R`'H!_RBG#V +M#2`2Z7$1%(`P(!X`%8:X$1P",(H@_P]&P`"&!<&&(`H`*+G`N0>Y)7@`INEP +M,@QO\XIQ`=T)\`+=!_#IN`'=RB4B$DH@`""!Y>?T+@U@">EP)!0`,0RV2G`$ +M+#X@,"5!+@`6$Q`%P`;"&PD1`A<*'@)!*`$"P+E!*\,AP+MP<=`B(@*GND;" +MI[A%P`8C@2!$>`5Y(*87"QXBZ+G*(`$%RB'!`^`/H07*(N$'$12`,!X>PA4G +M"%X!(!0!,2(4`#$GM@BV"^D!%((PBG"`XNEQRB+A![(/@`6B"^_[`"9`)"#` +M"0@?``T($2`1%(`P$0A>``(4`3$FMMH.8`'IEP$12`,!\(W@`GP>EP'A0",8ISH@MO]XHD`0"0X,HE)A&B"J`, +MZ7`@P!$4@3`/"!X`*'2&)+V?)O($%A`0"L)!IAT)'@`$(@`$$'+*(((/``"C +M(;P)XN_*(0($(8;I<-8.8`$1%((PBG$!AMH/[_8`VB##Z7!2(P,`"L$*`07``-D/(<$#SW*``-0O88(?"!X!)7ORR6&B$2``AV&B"PL>(2"")'@`HO+)(0@.!:X/H`6*<(SH`(;GN,H@ +M(0#/(,$#)`ZA$@`V`$4A#"6N"#"SW&@_N@'O@N@!`(4`S$&#:`-J7#/ +M<*``@`Q`&(`/`+@(`.;)`MD`'P!``=@V#*``"'(-!V_OL,#QP'X.;^\!V<]P +M@`"4Y@&`H\%!P"8(X!&"P"+%"B&`+X``[,FI<#H(H`(`V5QM4R7/$+-OM7T` +M(4XC((:*(`@@?HY:<,*Z"R$`A,PBP8#*(((/```'*T0(XN_*(<(#`89*<6(. +M[_8!VK(-H!'I<#J.SW"``&S,-G@BD`0<1#``@`'!8@_@#NER2G#.#*`%Z7'_ +MV`BFA@QO^.EP.@]O^.EPZ7!Z"F`!_]D`)4`44@IO]"C9SW&``(#>`($`'@`4 +M"P\!$(#8`*$`V(X+H`D/(,`#SW"@`(`,0!B`#P"X"`#FR0#9`!\`0`'80@N@ +M``AR\05O[Z/`\<#AQ0`6#4#FR?H*(`]3)0$0SW&``"S-X;T!V,H@(0#Q!6_O +M`*'@>/'`;@UO[P+9L\$6#Z`1BW".P8+&SW6``#RV0"4`$V8*X`X0VDMW@"<" +M$^EPR7%6"N`.,-J"P(()H`!$V0#`&0@>`.EPG@EO]##90"4`$Y8);_00V84% +M;^^SP.!X\<#AQ<]U@``<*ZEPM@Z@$0'9`(4S")4`!&VJ#J`1`=E`)0`2G@Z@ +M$2"%084U:C!RRB".#P``"43<#H[O0"4`$X(.H!$AA58*@`!%!4_OX'CQP*;! +MO@R@`0#8@.#*(((/```"1*`.@N^+<%H.H!$&V2H*@`!Z#B`*`-A:#B`*`=@` +MP!3H$0A0`!4(D``="-$``-@#\`'8%@U`!`CP#@U@!`'83@X@"@'8`,`#P4(@ +MP(`#N/'`)@QO[XHA1`>")`0X0"3-,*(-H!&I<"'`\@U@`@#9&G#/<8``(#N$*`D/ +M`\`P(5$.5B`3"HMW@\8*<+H/8`4AP8P@PX]`)!(W`<(*]$`H`23/<```9#3: +M#:_O17D!PB./"PG3`!$*%`3/<```4#3*#8_O8H8CA@L+9`!!A@./A>@"(<`` +M%0H%`!"[SW```%$TJ@VO[V5Y`!(!()CARB"%#P``6#2,#87OSW>``*S4"X?/ +M=H``K-,#%($PS0@?`(#AS"%B@"GR@N&']..XA?(`AHP@_X_*(($/``!2-%0- +MH>_*(0$$"X<%P:.X"Z<&A@L)!0!%P`>&1L"I<"=N3@C@#HHB1`<%P`;"8G#2 +M#6_V`"+!!&'P%0E1`!$(W@"*(?\/(*:CN`NG`<#/<8``[,D#N!5X`&&C"-\! +M`(:,(/^/2_2I<"=N!@C@#HHB1`?.#&_V*G`TZ"IP'-F:#:_W`=I`@,]Q@`#< +MU$"A`Q2!,(#A%-G*(2("28%N`NGSW`#`.S[=@Y/]@WPSW!% +M`'@W2@B`$`7!SW!%`)@WD@B@$&)QZ@]``*D";^^`)`0XX'CQP$8*;^\9V;[! +MBW7V"Z`1J7`*P,]V@``\`WAGP%B6`$RB(SW*``.S) +M$VD5>`!B42!`@L`I(@3*(((/``!B--0+HN_%(8(#`>;/?@2-T0X"D"#%BB`) +M#PQ]&G`*(8`O@`!@/$`A@"`&(`"%"=`FK-GH1D@6S`>$O>0IP#'TOH"*4FF#_/(&$#`,+//KS#K@!HY(-0`"AP-'`X'[@ +M>/'`X<7/=8$`9$:I<&8,+_2*(0L$YLD`I01ME@F@$1'95B5`$NH(H!$BE;(( +M+_,/A4D`3^_QP*(/+^\!V:?!`!:.0``6@$``)H\?@``,W0"O`!8`07X)8`+) +M<(P@PX]*)``@&W`&],X*H`%4V-D"``"R#\_XSW&``.S)0,`3;A5X"PXU%`)A +M$0I>`G;8C;AV":_OR7$*(H`O@0#8/TIP%B"1`RIP"@F@$0+9SW"!`!@_0<`6 +M()`#"G#V"*`1`MD6;D+`SW"!`-A``L5#P!UEJ7#>"*`1$-D*(X`O@0"8/VIP +MU7C."*`1`=FI<'8*(`H0V>K).0@>!<]QH`"`'`09@`_%[A=SP:$`CP&A\".` +M(P&A*G`*">`1`MD*<`()X!$"V:EP^@C@$1#9%B*`(T3``8B0X,H@B@\``'<` +MSR!J`[P(JN_*(8H#@-@`)ID?@`!4R0`9`C``W\]P@`#LS!4@D`,"&,0C"B>` +M+X``].<`&,0C8_!\:<&[`6L$)8(?`@```#&Z`"B3``7"4R71$`.Z57IX8Q5X +M6&`B<,]R@``$[@AB2B)`(%$@P('/<(``5%D0D,(B@B3EN,8A@H___\__!O*` +MV(VX+@B/[PD)$"``&<(S""34)#T($#$`P"H)X`8/>!4.]2`(<1$.$"`-#L0D +M!<`)"04`2B(`($PB`*#*(($/``!X`,\@80/X#V'ORB)!`P`5`2`1"9X'`!`` +M(0\@P`,`&`0@$0G>!P(0`"$/(,`#`A@$(`'GM0\5%`+``\'U>``A%0``%0T@ +M02V`$\*X,B<6(`0E@A\````8!"6^GP`$``%!*L`"1L5%P`'8._+HO2;!@?-! +M+<`0P;@!X$$M0Q3!NP`C$P"@XG!V\03``H@R)P`@@>#*(((/``!Y`/@. +M8N_/(&(#!,`#B#(G`2`!V(+AP'@+#%$@@>'*(&$`@.#*(($/``!Z`,P.8>_/ +M(&$#A@\@#,EP`<+/<```/!76>B"2"2$```"R0@I``-$$+^^GP.!X\<"N#"_O +M"-FBP>82#[;/=:```"[5A:H-8!&+<#'(`,'/"1X@.`!V,!X2WC*(($/``"F*&0.0>\`V!6E)@C@$#_8`,`$%`$Q%:4"#Z`0 +M@KG5I=()8`#F&MBSK00O[Z+`X'B=````\<#AQ:W!BW#>#6`1`]D!P$,(4`!] +M")$``L"Z"R`#`(`XZ(/%J7``V?8(+_0HV@'88\")V$S`SW"@`(`,0!B`#P`8 +M,`"I<`#!`-K*"V`1`-L@\`+$`,$!A$"$8(#7*$``:PA`HNP$:PA`!XNT*$H("D,]S@``)RA>VSW"``'S> +M0(@3:A5X"V//<($`V$0;8U9[A(N,),.?`-D/\D0L/AW/"2(SW"``""_1"D^#0"`)&T$X"=PI@]@#A#: +MSW"``/#W0"4!%5H(H`X"VL]P1`"(X4`E`1=*"*`.0MH0A@0@OH\```,P%?(T +MAHH@&0`)(0``%:8#X$8@PP#/<(``@%1`@*EPBB$%!NH.(`!*@@GP`-@5IA2F +MJ7!Z#B``BB$%!I4"#^_@>/'`(@HO[Q/9SW5$`#SAQ@M@$:EPE@\``$`5`1'/ +M=X``>#(@MT(5`!'/=H``>C(`MI#AS"`LA,H@B0\```@"V`M)[P#8"?`*90`@ +M@0^!`-0L0*D!X`]X()?O"$*``-@,\$`E`1@*80`@@0^!`/0L0*D!X`]X();M +M"$*`$87/<8``?#)RA0"A8:'/"2_O`=FA +MP0(+8!&+<,]U1`"0X@#`((4X8!!XEN#*((D/``"X(2P+2>\`W@WP`(788(0H +M`@4$;2=PS@I@$279`>;0?@#`Z0X$D)8.```Z#F`'`!0`,0"%`,$X8`"E;0$O +M[Z'`X'CQP,]P@`#@]V8*8!%*V6X.``#:"$`3T<#@?N!X\<#/<$0`B.%^"F`1 +M0ME2#@``T<#@?N!X\<#/<(``+/@R"F`1T-DZ#@``T<#@?N!X\<#/<(``Q.0` +M@.'``!8!0``6`$#/<*``@`P!VAT)4`!`&(`/`+@,`.;)`-D`'P!``!]`0"AP +M#_!`&(`/`+@0`.;)`!\`0``?@$``P4AP`!]`0`+9\@T@``':H<#1P.!^\<"A +MP8MP\@E@$0'9T@\@`0#8`,#/#2```*.AP-'`X'[@>/'`!@@/[\]P@``XYB"``8#X'$BP0<"+<`+=G@E@ +M$:EQ`,`UZ('@>/0`VL]P@``(WT"@0:#/<:```!`P&9B/`+B\`>;)SW.``#C- +M`!\`0`?P!!,,!`'B`!\`0\KBNO?/#Y"/2(@(," +M&1B#`]H'&9B`SW"@`(`=1J!&\,]P@``TS0#?Z7%:#._SBB(*"\]V@`",NLEP +MZ7%*#._SD-KI<0/P`>%%"=4`SW"``,RZ-'@4&(0/``#__R`8A`\``/__+!B$ +M#P``__\`V]D+%8$5(T``BB)^`-A@A!B"`'_:>!B"``'C]/$!VL]P@``(WP'! +M0:#@H`L)40!`H`3P"0F1`*"@?@P``%T'[^ZBP.!X\<#N#L_NHL$`WN(.(`') +M<(#@RB""#P``"D3$"$+OBW6I<'H(8!$"V4H,``#/<(``J"<:B`04!3$;"%X` +M!Q2$,,]PH/[T!`#"!-E"#Z``!A2#,`04`#$O)@;P#``#``0QL]Q@`#4Y-()+^_)<(MUD@RO^ZEPR7#>#R`1%]D` +MWA[``=]`QD?'!^@*#Z`)Z7`>P&&X1<`?P`?H^@Z@"0'8'\!AN$;`P!0`,`T( +M40!#QD3'!?!#QP+81,"$%``Q/>B(%``PC<)N#.```]F4%``P3L",%``P3\"0 +M%``P4,"8%``P4<"<%``P4L"@%``P5,"&%``Q'PA1`!X)@`:!X`'8PB`!`(#@ +M`=G`>7(+(`$`V!/P!@F`!H'@`=C"(`$`@.`!V_NE23+.O'`X<6")`(ZBW!.#B`1&=D`P)G% +M@>"I<-K9P'ER">_S1-JI<,H((`!$V?D$[^Z`)`(ZX'CQP*'!!@P@`0#8BW#^ +M#B`1`MFV#B`)`,#B"0``H<#1P.!^X'CQP*3!2@P@`0#8@.#*(((/```)1#0. +M(N_`>8MPX@T@$039M@D```#`A.CR"0_Y&?`C"%$``<"`X,P@8H#,(**`!/3Z +M"0_Y#?#/<```"40!V07PSW````E$`MGR#0_O`L"&Z(H)#_FDP-'`X'X;"%$` +M`\`-"!4!A@D/^??QSW````E$`]D%\,]P```)1`39O@T/[^OQ\<"Z"\_N"';/ +M=Z```!`-%P"6*'5"(``(2"`!`$`E`!(0<1`+Q1$';00@@`\``/S_!2"`#P"X +M```P'QB0YLD`'P!`(KT%\``?`$`$YF&]^PVUD`"&`MD&"2```=K)`\_N\?'?:5\]0^4D;#L`-\'\.U@`1..!`'GQWVE?/04D3)#O\P#8'/#`@B"%08+'>85Y@84"OT=\!21,D`3G +M^V/R]4`D@@`(\$E@`1.-!`'BIWDE?/4*E('F[`'8M0'/[O$&``5@@$"!'0N! +M`&*00I$5"X$`8H!"@0T+@0!&D`:1"0H```'8`_``V.!^\<"2">`##]@!V<]P +MH```'2N@C@\@!2APT<#@?@.`!""`#R````!"(`"`X'_*(&(`\<#N",_N"'8H +M=0#8%0J0``.%((7MN`'8P'CMN<\@80`%IF*%`X5!*P$&02L"!#*[P+C%N<&Z +MF@OO^,&[`X4BN'H*[_C`N`&%((4!IB"F`X4BA0.F(J8!A<]Q1`!X]"BXQ;@5 +MH0"%0X4\N,&X*+K!NEA@[0#O[A:A\<`."$`%L@A`!='`X'[@>/'`8@C/[@AU +M2'="#R`%:':`X.P-(@7*($(#$PY1$*EP,@A@!>EQR@E`!:4`S^[@>&$%0`'Q +MP#(([^X`V.'`ZLD="%X%YQ($ML]PQ>Z#<=@2`K8!V5(+(!'F$@.VF1*#L`#8 +MBW(-"W($0,",(\..B/;/<$4``!SP(,T`A.T!V2+P&PM2!(XCPP_/<$4`H"+/ +M=D4`M"+P(,T`"?#/=D4`1!QH<-H(X`&8$H&P:6:8RQ,(0P#P)0`0!>@`H@#9 +M`O`"V8#AG`DB[\H@(@[/<(``2!4`@`#!$NC-S00@@`\```"`3[B!X,PA(H`( +M\@?8"KC`V1BY=@MO\CMZ`,!`>-D'K^ZAP.!X`]G/<*````0HH#+(SW*!`+PV +M89+/<8``]+<4>022:+'+$@.VF!D$`*`3`0`#@H8APP\E>.!_H!L``.!X\<#A +MQ<]P@0#410AU`(!/"%$`#'`]"%\&SW*``)P++X+/<*``@$0+"=X"$H`"\!&` +MSW&@`(`@,H%AN!D)!`"\$@`!$0D%``.%AB#/#YNX`Z7Z#^_UJ7``V`"E10>/ +M[N!X\<#"#H_N"'7/=H$`!$8`ALEW$PA1`-8/[_7I<`#8`*8%\%_8D@@O[XRX +M`8`AR,V@U>0`A@`]$`/22A0"@`0#9"'(S:#5Y`"&`#T0`]))Q +M`*`!`MD(0`A@`]$`/2220"@`0?9 +M"'(S:#5Y`"&`#T0`])(U`*`!!-D(0`A@`]$`/22#0"@`0G9`[@5>,]Q1``8DPAA@^`!V.!_P'@#N!5XSW%$`!B3 +M"&&$X`'8X'_`>`AR,V@U>0`A@`]$`/22T0=@`0;9"'(S:#5Y`"&`#T0`])*] +M!V`!"-D(#^__"'4R#^__J7`)!H_N +M\<#AQ:X/[_\(=3(/[_^I!^X'CQ +MP%X-C^ZEP0'>`-TN\!-M%7@`((\/1`#TDD#'SW!$`""10<#/<$0`$)%"P,]P +M1``8D4/``-M$P\EP!]D+V@HD@`]$`%S4"B6`#X``0"9*)L`)2@Y@`?ASSW$" +M`,PKE@B@`>EP`>8!Y:<-5)%=!:_NI<#@>/'`X<4!V,]UH@``<$4=&)`N"J`1 +M9-A%'9B?```!#P?8[!T`$`38J1T8D!8*H!%DV,]PH@``X``8@`\!`*8)SW"B +M``#D(!B`#P"``@!0&(`/`(`&`!$%C^[QP)8,C^X(=JX/K_*H-@`N6"6`$J7#>#H_W"@SO]P78S02/ +M[LT&C_?QP$(,C^XZ<"AU2'9B#Z_W&G//<*```"`;@`'?HG@_N%(@`(`")8`3 +MPB?!$S^X4B``@,HGHA`J<`IQF@E@!.ER'0A1``GE@.?*(4$#SW"``##8)@K@ +M#\HA@@,%\",@``0`V$4$C^[@>/'`SW"``##8L@G`#T8.``;1P.!^\<#AQ<]P +M@`",JZ"(@^7*(($/```B,*P-P>XF#@`&2@P@!JEP)02/[A4"8`0"V.!X\<#2 +M"$`$&@Z/]]'`X'[@>/'`X<7V#:_W"'6I<`#9"@E@!"AR]0./[J'!\+NRB%"!5,@@"`S;D`A$`088!1X`"`3!"H+H`6J +M<"\A""!"(0`E0BB2`,]P@`"L[O`@P0,4;14@@`7/(\6ZA^(!VL!Z%!R"(`/C(KM"U$E +M@*9CNP`L]S@`#4[E)CSW.``*3N,B.#!0/F3'M&)LX0(KX0 +M'(`C!2D^<(#E#!Q`+LH@X0'`*&$$"O*!Y0/8P"CA!,H@X@#`*&(%Q7@0'``@ +M-_`LP$D-7B(A"-(-P+C/<8``W.GP(0```[X%+CX0"B#`#@'@!_`)")$"$VX# +M\!)NSW&``"!'7($LP21ZAB+_#B*ZP-E:>1EA$_`#OAQXPKC/<8``3._P(0`` +M%N8%+CX0"B#`#@'@`KA`(`$%,'@(W',!K^ZAP,]P@`"@)@"`X'^&(/X/X'C/ +M<(``H"8`@.!_AB#[#^!XSW"``*`F`(#@?X8@^0_@>/'`X<4`V,]U@`"@)@8, +MX`$`I88@^`]M`:_N`*7/<8``G-7/<```$$39`N_N,)G@>,]R@`"D)@:"!(`@ +M@,=Q``!0P_$&H`](<.'%X<8`V]=P!````%@`+@#*(,X`02B!!&&Y0"F"!$)X +M`B""#P0```"(X0C'"N2.C%2--`""#Q(7" +M>2"C`-DDI>$(!(/7<@0`````V,H@A0#!QN!_P<7@>/'`SW"``,`F$(`-")$` +M$@Y/]@3PI@U/]M'`X'[QP#8(C^[/<*```"`;@,]U@`#`)C2%#0A$``(@3@`' +M\`XAC@______'F84I4X/[__)<`AWSW*``%04(8("@AEA`X(X8`#9(J(AHB.B +M`B8!$!!VRB9-$,HF+A`"V!(,H`$`V04HO@.^#R_V+W:*(0@`.&`^9D&%*KXJ +MN-A@!^I,A1*Z66$JN0.Y+Z4CA0'APKDCI14E0A!D@B"%!*)B>3A@`*4CN`JX +M,K@^#^__#:4(Z"Z%&6$NI0H((!``V,]R@``8)P:"#B>!'P0````$@`"`&6&2 +M#:`/2'#)!T_NP1(!M@\A`0#@?\$:6+#@>,]P@``X)QT%@`_@>/'`SW*``#@G +M`(*/Z,]P@`#4J!Z`A2@/"@:"!(`@@"=Q2@V@#TAPT<#@?N!X\<#/<(``5%@! +M@!,(W@/R#Z_N#]B`X-0)PN[1P.!^X'CQP,]P@`!46`&`(0A>`](/K^X-V`KH +MSW&``*S-%($U@2BX7@HO^2BYT<#@?L$2`;80(0$`X'_!&EBPX'CQP(H@_P_! +M&ABPSW"``%18`8`C"!X#SW!%`(`;SW*``%0G)H(+@"2!(($98;8,H`](<-'` +MX'[@>/'`@@Y/[L]P@`",J\"(N@P@!LEP#NC/=8``5%@!A>RX7`_B^VXZ`@"^2X/#_F]!D_N@.#QP!`)`OK/<(``5%@!@.VXI`@"^='`X'[@>/'` +MSW"``%18`8`C"!X#SW!%`(`;SW*``%0G)H(+@"2!(($983(,H`](<-'`X'[@ +M>/'`X<7/=8``5%@!A1$('@/6#J_N#-B`X#@,`O4!A1,(7@/&#J_N#=B`X!@, +M`O$!A2$(7@2R#J_N$=@,Z"8*[_@`V`CH3@AO^1'8[@[O_Q'8)09/[@D`(``` +MV>!X\<"B#4_N"';/<(``-*M9B,]U@`!46`&%X+K,(2&`2O(1"!X`9@ZO[@#8 +M@.`P#`+[`84A"-X&5@ZO[AO8"NBF"\_X".BR#R_Y&]B2#N__&]@!A14(7@8V +M#J_N&=@$Z)H.K_'.>`&%%PC>`2(.K^X'V(#@1`CB]+SRB""`^H+``,! +MA2,(7@36#:_N$=@+Z$H)[_@!V`?H<@\O^1'8#@[O_Q'8R7`V"N`0Q!(!MC4% +M3^[QP.'%SW"``(`G`(#/=:``@$64Z#`=@!\`(``!`=G/<(``;"@@H&HA@`'/ +M<(``<"@>#^`-(*`K\!H+``[/<*````@"@`#8#:7/<*```!\<@"\('P#/<(`` +M:"@`@",('@`,L]V10"P(`@>@A0*(8`OH```#$P1`2#/<(``Y+L@H&H-8`M( +M<`AW$!D`('00`"#/<:```"!DX!"A`=@'&1B`$-@`H1R5D>#*((P$R?;I<`#9 +M"-KB"2``R7,(YXSH((ZJVA$)@0`AC@T)@0`BC@D)T```V2'P(Y8M"1`"C"$8 +M@A#R\0F!CP``AMWI<`;9`=JF"2``0"8#$@?G(]D-\"'8ZO'I<`G9`=J."2`` +M0"8#$@KG#-E(CA\*401/'`+@M/[L60SW%%`%@@%PZ`'P``___/``D,41"@N!:J-0-/[N'%X<;/=$4`L"`#E,]Q10"8((P@&(+/``#8!/`!X`]X-0B3`ACK%B(!`**1+PU1$,.1I91AN^D. +M09//``I`N#`>`+H^KQ\<#/<$4`6"!0&(`/#P#__\]Q +M@`"8WP"!`>"^#>__`*$+"%$((@_/_P#8T<#@?N!X\<#*"4_N"'4H=DAW.G,X +M8JEQ`-I(<^8+K^Z8/'`E@EO[@'8X<#/=44`6"`4A<]V#P#__Q\(@`.+<`39N@C@#&#:%(7/ +M@"B`-C@?\'%X'C@?N!X\<#/<(``2!4`@!GHSW!%`#0X`(`G"!X" +M(-K/<8``_/E`&8(`*+I!&8(`*+I"&8(`*+HR""``0QF"`-'`X'[@>.!^X'C/ +M<8``2!4@@0CI@>"'V,!XSW&``,S6`:'@?N!X\<`!V<]P1``,\B"@SW"``+S8 +M`(`&Z,]P1``0\B"@"_#/<:```#0`@9"X`*$:"F_W"MC1P.!^X'C/0:E$X(DI0>EUW$$````"*5(]Q$.17`````04R%^ +M@@;R?=CZ":_NC;@`V):X`MFI<@HD@`\``/\?%@C@$`[;70!/[N!X\<#>#P_N +MSW"``-C8I@U`#S'HSW6``.0;`-B6N`/9J7(*)(`/``#_'^(/H!`.VT6%!H4- +M"@0``B(!`!OP)(5980)Y%_#">17PBB80$,EQ1@C@#+K:!H4BA=A@#0AD``:E +M`X4&I2&%C"$0@"[W`-DAI>SIW0'U"82`SW"``%@5`("`X,HC`@?`>,\@H@7*(0($ +M7`QB`\(D`@'/<(``2!4`@*\($0`.Q<]V@``D*`.&0"62$$)PC"#'CXMW2B%` +M(([WSW"@```,,X`4@`T)`0!2"$`#*G`#\`#8".@CA@`A@`0#I@'8!O`&A@'@ +M!J8`V"_H4R#`)$`M`18%>0&&SW*!`#@C%2(,`""D`>`!I@#;"?#P)\$0%2(, +M`""D`>`!I@'C\PM$@\]PH```(#N``885>B"B)(8!X`ATAB3'GP'A)*8%\B6& +M`>$EILBX`:8DW+<&+^ZFP.!X\<#/<($`."-5V4#:-@LO\XNZU@AO]Q?8T<#@ +M?@'8SW&@```\!:'@>`#8!:'@?N!X\<`B#B_N$-JDP3IPBW#/<8``+.2J"6_N +M&G!^"```W@S`!$/`->@`WL]UH```/,"E`MDCI3$(D0#/=T````#)<07P%2=, +M$,"D`>'/<(``>%0`@`"`(KCO"02`X@]O]BB_\J76I001`"`/"($/`(````#` +MG[@"\->X0,`(VT'#!MA"P$(-X`0*<*8((`9H.XT2!A@"ST50B>`%$('P"`N`"ASW"@```(`H``V<]PH`"`12V@SW"@```? +M'(`E"!\`#'`="!\#SW"@`(!%,!B`#P`@````V<]P@`!L*""@:B&``<]P@`!P +M*""@X'[@>/'`+@T/[L]U@`!L*`8*(`S`A<]PH`"`13`8@`\`(``!`=@`I6HA +M@`'/<(``<"@@H`QP#P@>`TH*(!$*V"SPK.[/<*````@"@`#9SW"@`(!%+:#/ +M<*```!\<@#$('P#/<(``:"@`@"4('@`,`SW*``&@HP[D` +M@H'AS"&B@,\@X0""N.$&[_\`HO'`1@N/_P7H-@_``@/P-@_``M'`X'[@>/'` +M4@P/[L]P@``\#-Z(SW"``(@HH)`T;D$M#Q//<*```"Y2@.5Y#?`O*($`3B"# +M!S#(]"#``!`BP@`1"0``]NK/<@``__\'\'!ZSW"!`!@T9+#/=```K0O/<+H` +MK=O7<@``___*)0$`RB`!`QCR$FHP((P/H`"T+I3BRB"%`,H@A@"'V\`@Q@`" +MN#`@@`^@`!@L,FHP(84/H``T+Q"Z0"@$!,]PQ>X$60#9Q7JI<^H.8!`%)`0# +MC"8"D!'R'PW?$A-N%7C'<(``[,DFD`\AP@-0>4:P*@H@`,EPY0,/[N!X\\-%)*Y`P_NX'CQP.'% +M`=GAP4"`(8#/<(``C*N@B(3J)@^`!0AQSW!%`'0MA"T!$Y(/X`@P($`.BW!> +M#R__!-F-`R_NH<#QP`'9X<'J$@&V+RN!#P`(``"[N;VYZAI8L("`3B.`!U,D +M`A`8>D0D@!`O*X$/`"```$XC3`>8>$5X!7GJ&EBPBW`2#R__!-FAP-'`X'[@ +M>.'%SW2@```@6X3/T;A`"C*'`%\*)Z]PH%@`#8X'_!Q>!X +MSW"@``!%`!B`#P!```#@>`#9(*#/<*```!`IH/#)!""`#_[__P.'N.!_\!H8 +ML.!X\/'`X<6*(O\/$WN`X,HB:@#*(PH`4W@S +M?(#ARB4+$,HEBA#*(0L#/'CZ"B_N>&"L>&D"+^XO<.!X\<#:"0_N&G`*(D"@ +M2'=H=@'='``C`$HA`"!.(`"@BB7_'P#<.G4:<`,DDA0=#A,03B4`D`#<`R11 +M%`AU3B<`D`#<"'<#)(X3Z7#)<=(,+^X!V@`@`(3I<@$A@00&"R_NR7.I/'`X<5(=10A``!J"B_N.WGA`2_N`*7@>#A@60(O[F&X\`1[`-X#\`'F'0X5 +M$L]R@`#D*(IB]0Z!D$.%T0^/DT1X`Z7GZT4!#^[@>/'`"'//<(``E"A`(`P$ +M`8`4Z/`DP!`5"AX`)'@="0``SW```*0A!_`1"0``SW```*`AK@IO[FART<#@ +M?N'%SW)$`/C4`-@+\!8B`0"`@17;$[LA@95[(*,!X/$(5(/@?\'%X'CQP'8( +M#^X,<+T(W@4L<+D(G@//=*H```2BA`?802T!$B]YB;G/=H``7`QFCL]R@`"< +M"PZ[97DPHL]S@`"@NZVC+J,@A$`2CP"4YRNC&/(&]C$/D1(CN1CP&P_0'>[G +M$O1%*?X"Y[U!*<%PPB%B``?8"O!%*?X"02D!<0;P(KD$\`#9"-@NHD&$+Z-, +MH^2ZRB`B`N&ZRB`A`@\*G@$$VD&N2I."NDJS&PC1`14)M`,'V,]RH```$%2" +M!PF```C8A^!T"`(+'0`/[@#9SW"E```<)J#@?N!^X'CQP)H/S^T(=<]VI@`` +MP%@6$!`6ABAW1B#``(&X%J8!V!2F`-@4IM8++^X&V,8,X!`*V"W8"KCI<:8+ +M(`"I!X\<`N#\_M"';/=:8``,`6A0#?1B#``(&X%J4!V!2E]*5J"R_N +M!M@6A88@`P@6I1:%I+@6I4X,X!`*V`SPSW"F``#0\"#``Q4FS!/*N`"D`>>, +M)P20M//'`I@[/[0AW*'7/=H``*!+R"B_N!MC/<*<``'PA@&&]\";" +M$]NY4'',)2*0\O4+"8$``=@(\,]PH```11B`#0C>`P#8S0;/[<]P``"Y*%X( +M3^[Q\>'%SW6E``"!!*5@I1"Z17DEI1@=`!'@?\'%X'CQP.'%"'7/"N`,&ME!!L_MX'C/@ +M/X,HH&`5`18IH.!_P<7/_MF'$(=0#9`(#/."@`>3S#%25BB#?#Q"F&I42N1:X!*9`+P`$17@;ID`M0`%%(``&)7B`#9#R$!`,]PI0``$"&@ +MSW&G``!``8&@N(&XB[@!H<]QIP``?`*!@+@"H>!^X<4,N"5XSW2L```0`:2- +MZ@#:"/!BA,]PH```#&&@`>+U"D2`"O``V`;P8H05(@T`8*4!X/<(1(#@?\'% +M\<"*"\_MSW6``/`IH.C/=H``-"H`AH#@RB""#P``QRA8#0+N`=@`I@#8#_#T +M)0(0*=D2N?`A@@#/<40`R),5>4"A`>`0>.D(4H@8\`#8#_#T)0,0*=H2NL]Q +M1`#(D_`A`0!U>B"B`>`0>.D(4H@`V<]P@``T*B"@@0//[5/:SW&G`("`$;H; +MZ`'8!:)$&8`/=@#_MT@9@`\_`.0E3!F`#PX`(E(NV!2A6!F`#RDI*2E<&8`/ +M```I*1OP`-@%HD09@`]Q`/_G2!F`#R<`[C1,&8`/_`"@\%`9@`\``+$/6!F` +M#S$Q,3%<&8`/```Q,>!^.WDE>,]QIP``01"AX'[@>`BX!""`#P```/\O>05Y +MSW"D``!$*:#@?LFX0"B!`B5XSW&D`(!$"J'@?N!XSW&D``!$@.`0@=`@H@#/ +M(*$`$*'@?N!X@.#*(&(`$WC!N,]QIP``01&AX'X(<@/(1"A^!"]S$>G'":+$+DE>">+&+DE>"&+#_#'":+$+DE +M>">+&+DE>"&+70`@`,.Y\<#B"<_MSW6G``!`[X5>#6`%"'8Q#@`03R9`+D`2#;X%?L5Y!O!0)P$1J+FL +MN2^E`0+/[>!X%'B3:91\0"P#%0OJ%;P3"`4#0"D#!G1[+RG!``/P+RD!``'A +M.'LX>,]QIP"`1!"A<:'@?A"Y)7C/<:<``$03H>!^X'C/<:4``(`3H>!^X'@4 +M>"\J`0`!X@.Y-'D4N5AX6'G/`#:SW"G``!(3:#/<:<` +M`$02@:"X$J%0H56AX'[QP,]P1`!@U58-+_$ZV8/8"+C/<40`O-8F#2_QH-K1 +MP.!^X'CQP-8(S^TZ[*(L$#`-CM`,_MX'C/ +M<```"('/<@``#H$&\"G9$KGP(0$``>#W"@6`X'[@>/'`X<5F""``"'4*(@"` +MRB""#P``_Q18"B+NRB%"`\D`S^W@>/'`X<7/<(``1#(`@!KH`-T6\(0M"1\` +M(8!_@``@.R&`#>D"@(/@S"!B@,H@@@\``/L4$`HB[LHA0@,!Y=<-5)&!`,_M +M\<`&",_M"@^O\0AV+@G@!`AU@.`!VX`V(#ES"$B@,HE`1#*)6(0@.4! +MV$D`[^W`>/'`X<7/=:(``+@`A<"X4B``@,H@@0\``,@-J`D![AF%R[B"(`(` +M!2B`#P``>@TO<((-K_^*(1X`SW&``)S5$;'/<8``5((?L<]QH@`$N`"!1B#` +M!T4@P```H<]QH@``"`:!H[@&H>4'C^W@>/'`X<7/=8``W+`/>16M"0E1`0#8%:T! +MV)T'C^W@>/'`&@^/[0AU*'9(=X/@RB"&#P``#T0`"2;NRB%&`P*]M'W'=8`` +MI"K`I5T'K^WAI4T%#_'QP,]P@``@]>P<"+#/<(``2/5!P,]P@`"L#4+`SW"` +M`+`-0\``VT3##]@#V03:"B2`#X``M`T*)8`/@`#L*DHF@`+B#V``2B=``*7` +MT<#@?O'`SW"``-`J9@S`#L]QH@``"`:!I+@&H='`X'[/<8``W+<4B?`A```% +M@`!XA0?/__'`X<7R"B_QH<&R"Z`09-B+=<]Q@`!4@@N!@.#*(($/H@``M`OR +M$0@>`,]PK0``)A^`!O#/<*T`@#`/@`"EW0@>A"Z!"0E1``]X`_#%N`"ESW&` +M`&!1J7`B"R`-!-H^"F`$J7`V#L__SW&B```(!H&DN`:A;0:O[:'`X'CQP,]Q +M`@"\]P#8R@[O_P+:SW$#`&C_`MBZ#N__`MK1P.!^X'@(/'`I@V/[<]U@`"D*@#>$_#R;O1_OV<@APSI +M0H<)A14*`0!`>2&'"85):49X.&`"IP'FX0[4D`F%`>#9!:_M":4`V`/P`>`C +M"-4`,F@T><]S@`"D*GEA0(%VZD*!*8/I"D&``=@"\`#8A^C/`?9SW*@```$+Z()\"Z""2!#`"2"8GAY822B^NC@?N!X\<"R +M#(_M"'8R$@$VSW"``/2W-'@1B!#HRQ(!M@&!&0A>`\01``#/<8``4#`5>0"! +M$.``H88(X`\!W?H)X`!!AC^@`V`\@ +M@`"""^`/']G+R1"(,V@U>3%EX;E0#<+M@02/[>!X\<#R"Z_M^-J")`,^"'4: +M<8MPSW&``*3F@@^O[3IPZ"SN+6X +MN+CL&ABP%;D$H0'8>G#/=J````0)IL]Q@``LSA:!`>`6H<]P@`!8%0"`#.A` +M*`(D`-B6N,]QH/[X##((X`*E>N*]P'\%]*8.(`\`V`AWR,K/<:```"XU@0*X +M,1("-C`@@`^@`&0N1'@$>00A$@25\*04`#"XN*0<`#!6":_S*G!J#B`/`-@( +M=\]P@``'`@`04H=(8D\9\-\A$)7@*@'(`_`0"+`"KPH!R` +M/P$`B``D\#Z(P!2`,`\(0`"@'(`_`0"1`!KP`<`/")X&H!R`/P$`D``2\`K! +MC"'_CP_RSW"@```@&X`B>!,(A0\`@```H!R`/P$`AP`!W8#GS"4AD'#U(!X` +M%(#GA?53)7Z0!?(.AH#@?_5G#5X0`=I*<`3P$"!``"CH+RL!`$XC@0N;JSW"``)0H`(`* +MZ!$@0(#*(($/``"<(<@+P>T`V`/P`=B`X$WS!0*O[8`D`S[@>/'`X<7/=8`` +M&"L`A1;HV@PO]@+8SW"!``PL$@YO\@S9SW"!`*0K!@YO\FC9`-D@I<]P@0`8 +M+"B@^0&/[<]PH```(#N`SW"``!R\X'\@H.!X\X7/<8``'+Q@H8KJ`]G/<($`#"S2#^_P(*!@\,]W@``4*R"'@.', +M(**`*?3/`"H0&!`>`!H7(/S_``AUT(40`` +MAED(E0`"V!H(+_8NV3N%SW*``!"\`N$BH'N%@((-"P0#>X6">PCP6X4.)(,? +M_____UMCSW1$`'B[I(0JNPKM1H!Z8@T-A1!%A`JZ66$BH`+8,@@O]@'9X0"/ +M[?'`SW$"`'A2SW("`,A/SW,"`+1/1@PO]@+85MG/<(``A"@@H`;9SW"``*2V +M(*`%V<]P@``$*R"@T<#@?J/!\<#AQ<]U@`!`P<]T@`#`P<]S@`#@P9#H!2&^ +M@`;T`XL!X`.K!?``V`.K`JN4'4`0F!V`$`KP`HL!X`*K`HL)"%$!`-@0M"8) +M@`P0W&<`C^W@>/'`X@]/[<]U@`#`P0^5SW>``$#!`-X5Z!"5$^C/<*```"`[ +M@`"'`GF"""_Q`=@+")0`T+4%\*,?@A//M!X\<`&"@_QA>`!V,(@ +M!0#1P.!^X'CQP/()#_&2X`'8PB`.`-'`X'[@>/'`9@]/[1IP.G'/=H``&"L@ +MAFAW6G(*(P`AA>D%)_Z4!O0]V`BX5@GO[>ERSW6``!0K`!U`%,]Q@```*P`9 +M@`0`V<]P@``,*R"@SW"``!`K(*#I<)(-+_!J<<]Q@``H(`"ASW&```@K`!D` +M!`'8SW&!`!@L`*8(H06!`>#Z""_Q!:$"V$8.[_4NV<]QH```(#N!`N$BH`+8 +MD@[O]0'9SW"``$#!HA"$`*,0A0"@$`8!`-@@A0ARD@\@$`AS!0=/[?'`K@Y/ +M[:'!SW"@```@NX#<&(`/`P!`#<]V@``,*P"&`-\!X,]S@0`8+":#`*8!X2:C +MYPI1`,]Q@``L(."ASW&``!0K(($5"5$`@>`/V#X.[_0`V0'8!@I@"#IPSW"``'"W&G``&$`$SW"``+0,`(!@QP$< +M`C`"V`(<`C#/<(``F`T`@,]R@```*P,<`C``P0+8+@WO]4"".@HO]@+8^@SO +M\``8P",`AH'@/`[!\/X.S_`>"`_QI@E@"`#8SW"``!R\((`+#400`B5`$`;P +M#B&`#_____^X8,]R@``4O"""$PE0`,]Q1`!XNR6!"KD="04`SW"``!"\H*#@ +MH@;P`]G/<($`#"P@H/$%;^VAP.!XSW*``!02`(*)Z,]Q@`#0$0"!`>``H0'8 +M`*+@?H?HSW&``-`1`($!X`"AX'X`V03P`>$O>14)4P'/D"2\0B! +M@`/P_]G@?RAPX'@`V<]P@``4$N!_(*!"*`("3WG!X83VVN$!V&$]MKA`=G#]@#9A.D`V!+PUW```%I:S"""CP``4$%8W,PB`H,#]`'8`O`` +MV/#H`=C@?N!X\<#AQ<]P@`#0$0"`SW,``%I:?0@T`0#:2'1H<`OPSW&``-01 +ME7F@D2&1@.'*($(#`>0+#!41ZPC`@%$(P0`$W$AS!/`!VP'D)0P5%,]Q@`#4 +M$95YH)$AD>T)@(!0<"*.)W@CCB=X)(XG>"6._]XG>``@A0^``(3V`!6/`#$/ +M@!.N#N__:'`-"',!`-TA",,#!O`9#U(1%0P0`,]P@`#4$?5X(9`!W6&Y(;`1 +M[5X((`!H<``=`@`7"(`#SW&``-01%7D!D0'@`;$`&80!+01/[>!X\<#AQ0#= +MSW"``-`1H*#/<(``A/;_V8X(;_)!::EQ"/#/<(``U!$U>*&P`>'U"12$!01/ +M[0AQ`-R)<`?P09*`XLHD`1`!X!<(%03/F"2Z0G!@`7P_]B&Y,H@ +M!@/@?L]Q@`"$MB"!)PE1`,]R@``PVR""&PA```"BSW*@```T((*`X-`AX@3/ +M(>$$(*+@?O'`*@M/[<]PI`"`1;Z`KW[JR00EC1\```#_*+TA"-X"R@[`!$`N +M`Q(0N`5[KWK/<,7N@F0!V38.H`]E>ET#3^W/82`K;@>,]QH`"`>W*!,X'+N\NY#0M$``(C +M0@`(\,]R@`!0+$""(GIZ8D"@SW"``%`L`(`BN!!RS"+F@`'8RB`F`.!^X'C/ +M<8```%0B@0#8$PF>!?6YX2#"!V38X']/'` +MX<7/=8``6!4`A0OH`-B6N,]QH/X\`V_:!KKJ"&`,"-L`A0OH`-B6N,]QH/YH +M`P?:"KK2"&`,!=L`A0OH`-B6N,]QH/Z8`W':!KJZ"&`,!-MY`D_MX'C/!X\<"*"```-@@``-'`X'[@>`#:$?!88A1XQW"` +M`&`L(I!AD!"Y`)`E>\=PH```8&"@`>+E"I2$X'X`V!#P&6`T><=Q@`!@+$"1 +M`>`P(H,/H```8&&Q,+MBL>4(E(3@?N!X`-@1\!E@-'G'<8``S"Q"D6&1$+H@ +MD45[QW&@``!@8*$!X.4(U(/@?@#:$/!88A1XQW"``,PL()`!XC`A@P^@``!@ +M8;`PNV*PY0K4@^!^X'CQP,X(3^W/<*```""[@,]V@`!$_2^."B"`+X$`0#<2 +M:11X,"`/()(+[_4!V,]Q@``8O""!,'`!V,(@!0!`(!$BJN@&AT*'"KC/``@`2`! +M@8"X70!O[0&A\<#J#R_M`KE:<`H@@"^!`$`W-'G/=D0`>+L#A@`@42``$0\@ +MK0A>`0@1@"#/<40`;,`"N!1X`&&9"!\`$@N`"GIPO@]O]DIPHH`%\,=U`0`` +MD`HB@"]$`'"[`!(`("6&.&#M"$6#!H?/<40`;+L*N""!N&!="$4``=C6#J_U +M%ME`*XX@U'X"=@"F)HAIS"B$`(0C%"B/`(0"E"<`*(H`A`Z4('4`10"4/&&2O"L-& +MKV2E"\,EKV6E`-MFI6*O8Z\$'0`1!Q^"$?_>R7%F"R_R+W($A07HR7%:"R_R +M18\%A07H_]E."R_R18\`WPOP%2'"(R"*J7!"BJ(-[_/I/'`Z@T/[:'!"B<`D"AU&G)`(`X()HX& +M\@D-0Q`#AXWH`(=`+0(2$+@%>L]P``#I#LH/;^U%><]P@0``8!T(!"#/<($` +M`'`2<,H@C0\``/@.J`]M[@@A^_8$+D$ +MN*5YF@]O[62.`=@#KH;P`=@"KDHC`""*),,O)(X#'L(4`!:1$`:.'!<0$`QY +M0X<`(4!T"&(`W0D(``6AAQ5]1H<5ZF#!`AQ"-`3M`8T#\/_8`1P",`3M`XT# +M\/_8`QP",(MQ8'KI<"2.DG',)2*0#/0`APBY$+@%><]P``#H#@H/;^T%(4$$ +M)(Y!C4HB0"!0<<(B@20U"8``!8<`V@WH*6`7"0`%`8".("PD`!0*'\"!" +M`(#BRB!"!.,@@@#*(0($_]@$KB.-$PD`!0*'\"!"`"IP8'H*<3<*$"`!C02N +M!(G-?#9R8`@!@`="=X'*8<<'X`?0`%0`(VY*:!](/X`9*<`AR5B7`%-8-(`"I<<>G!?`<'X`?4``` +M`!$('B4D'X`?`@````/PR:<1C<]Q@`"P\<*X"F'/<8``N/'P(0$`5B45$PF' +M%!V"(`5Y!H<]R@``\[\*Y]")1`,]R@`!\[?0B4P#@N,H@PB02]"B//'G"N1,('@7/<(`` +MC.WT(%``!O#/<(``?.WT(%``R\D`D$IP`#!N`'@ +M,;G!N3A@%?`8CT2XP;A!:`0A@`\"````,;@$V0`J$``5'4(@+@RO[JEP!/`! +MV!IP0)44%8$@%16`(%EA.&`FAQVW!"&^CP$``,#*("$+Y`MA[<\@(0,O"%`@ +M3""`H,P@XJ`*\DH@`"`MV,(+;^V,N`IQ$/#/<($`V#\6((`$(X@'\,]P@0#8 +M/Q8@@`0BB`ZY`X=5)4(=)7@#IP:')@YO_CV7*8<$(;Z/````,`&W/_)#APZ7 +M1:<)MP`?Q!3+$@.V'PD>`Q38"+<^'$0D>!,#`0(AP"`9MQ*'SQH8L`KP#M@( +MMSX`,C*SW.``$S=%GL#DP/HD;DIIP0B@`\``P`` +M.+@#V09Y@N#*(2$`V7086``+\":'P+Q(`AA!Y!""`#___```PN-`?0!#4'P`0%(8UABBX5H8HN?(*;_@HNL]Q@`"< +M"Z`1@``:IJ(1@``;IJ01@`"E$8$`':8N"F_X/J:$+0D?SW"``"@[,"!`#A,( +M4`%B"@`#@.#,)6&0!?0!V!H)K_X7IG$`+^U!'U@3X'CQP,H+0`H5"%$`PLF$ +MZ`'8T<#@?@+8_O$`V/SQ\<#6#\_L"',*X"67/<($`V#_6>`*(#K@E>`"GJ0?O[*+`X'@'V3(:6##/<*````0O +MH``6`4#IR=@:6+`G"!X"SW"@``!'%!B`#P``#`SLR07:`>"SN+6XN+CL&ABP +M%;H$HL]PH`"`+#"@`!8`0.8:&+"9RP7H`!8`0.<:&+#@?N!^X'C/<8``*"O@ +M?_`A``#QP-X.S^P(=BAUSW&``.S)$VT5>`%AZ;G*(((/``#*(KP(8NW*(D(# +M%FW/<8$`V$``8>FXBB$(!`*(#K@E>`4'[^P`IL]P@``H +MWN!_`(#@>,]P@``4#@>`SW&``#P.`K@4>.!_`&'@>/'`:@[O[`AQA"@)#P`A +MC7^``"`[PH6%X,H@A@\```(T2`AF[.!_`(#@>(0H"0_/<8``+#LP(4$.SW"``/Q--GC@?P&`X'CQP)X-S^P:<"AV +M,LCPB4D@P0`!A@#=HL'!'D(30P@?`>8/0`3"N"D(T0!#A@/9#KD$(D``&0A` +M`#+(SW.``/2W%'L1BPD('@!'>2.F`">`'X``E+:@J".&`!A`()#P$V\5>,]S +M@`#LR0!C/+A3(%*`!_3/<($`V#_V>`&(`O"I<,=Q@0#8/_9Y9(DRC@@AP0`( +M(0``&F(`EM=P``#O#TDBT0/6]P`GDQ^``%3)`!.`((P@`H#*(($/``!<`.0. +M(>W/("$#`!.`(`DA$2`6;\]Q@0#80!4@0`0`8<]R@0``<""*".D\EH8A_PP) +M"1$"`8($(+Z/``0``3/R!""##P```!@KN^BX`]K*)"(6RB'B`!MAF`[L5>'5[>&`X8,]S@``$ +M[@AC#0C>`48BP@-AN25ZBW`N"^_UZ7$`P``G@A^``)2V$PD1(,]Q@``,W>EA +M(*H"\*"J`!@`('T$[^RBP.!X\<"AP8MQM@[@`@78">@`P<]P@`!0,!4@00`` +MD0+P`-BAP-'`X'[@>!UY!"&!#U55554B>,]Q,S,S,P0@0@`BN`1Y66%!*0`! +M.&`$((`/#P\/#P0H@`\!`0$!X']!*0!V\<``V@KH?0A0`,L(D`#O"-``2'#1 +MP.!^8('/B5ZA.(`V`5Z'PH4`<]P@`!8%0"`".@`V,]QH/Y4!JX/X`&6N`#:SW"` +M`!SH]""``*+QSW"``$P40(#/<(``A!0@@`'88;F`XL!X.WDE>,]Q@`#@[_0A +M``".\0'8C/'@>/'`R@KO[")Z`-T0\`#<#R3,$`$LSQ`!*,X`Y'[=96&\!'R= +M91`BP@`O+($03B2#%XPC_X_L]0$#[^PX9?'`D@K/[`AUSW"@```@VX"J#>`, +M*'`")0$0"PE2`#YF`_"B>`)^W0+O[,EP\<#AQ0`6`4`(==@:6+``%@)`YAJ8 +ML)C+%P@0!\]SH```!&2#SW```-P.2@P/[:EPX@L@#P[9H)5))0T9`_!F"4`! +MSW"@```$#H#W"$2#D0+/[.!XSW"``+"XX'\`@.!X\<#^"<_L&G"^"*_P*'4( +M=AX-X`P*<$0M/A<(G;)=3IV$/`,Z0'!#PL0(`(E0!`-"%(`2B-`("AU0"%` +M("\A!R!'";,@0L9$*3XG+W$P)$`@Z0A1@$`@`"@988'#0"0$,JIPN@BO\`#" +M`L%=Z(#ARB"!#P``-#3X"@'MP*T!P,*G`:<$VJ,+$""B>)L( +M4@"AIP+:2?"`X4HB`"#*)H$D!?($%!8P2B)`($HA`"`1\`OI`<$-"Q`@`B5` +M$`L(4@!*(T`@*'5`(4`@+R$'(&$)DR!$*3XG+W$P)$`@0L;K"-&`0"``*!EA +MJG``PNIS^@]O\$`D!#("P5SHP*>`X +M#F_P*'`(=MH/;_#I_U!MC9!X_LX'CQP%H/K^P&V-H(S_43\(&C!(Z&(/T/ +MC"`"@`'8P'B$'@`0C!8!$&!YZ7``A1`@P`,`I<]U@`!`+0"%I0@0`"\H`0!. +M((\'Y@UO\.EP`=D(=CV@/Z``B($($0,^IH0O"1_/<(``E#LP(%$.*@K@#.EP +M6G#I<"IQ<@UO\$IR&G`#CB5NB!X"$$`F`!BR#6_P2G)`)@`?0":!%*(-;_!* +M@`8@%#AH0Z.8(8!X`ZN0I8PNQ"Z125` +M$H3997HB":`/(-L:#"`.*G`!W3GP`-T$E@IQ`-_I.5X":$< +M&8`/`&D``%X.H`$`V&4%C^SQP.'%"'4N#J`!`-@%V!6XJ*`<&(`/`&H``*J` +M-@Z@`0#8406O[*EP\<#2#(_L"'8H=0(.H`$`V`78%;C(H*F@'!B`#P!I```* +M#J`!`-@=!8_LX'BBP?'`SW)%`&@A+H)3"=\`,0C1``."2PA1`!&"SW.@```@ +M`>`1HL03```(HAN#!Z(!V`FB*PG>`1(((`X!V!'P'PB1`!."SW.@```@`>`3 +MHL`3```-HAN##*+A"1^"T<#@?Z+`HL'QP$+"SW)%`&@A;H)!P0AQ9PN?``#8 +M3PE0`"L)D`!)"=$`@X)%#%$0$(+/=*```"`!X!"BP!0`$`:B&X0%HB<+7@$. +M\!*"SW2@```@`>`2HL04`!`+HAN$"J(+"YX!A@_@#0'8`=@/"%$``<,@H@+` +M8:("HM'`X'^BP/'`O@N/[,]U10!H(0Z%\0@?`2"%2PE0`$H@`"!I"9``T0G1 +M``F%S0@0`!:%)!T`%`'@%J4"A<]Q10#$(4&%`:$$A4"A`J$'A4B%0G@%H06% +M1H5">`.A*'``4I0*%SW%%`)0B`:'/<(``1"T`B$"A`J$H +M<`S99MHV\!6%(84!X!6E`H7/=D4`X"$!IL]W@`!$+02/(*8"I@6/0"8!'`.F +M9-@%I@>F0"<`%"(((`R$V@J%*X5GVB)X;[@(I@R%+84B>`JF)I<%EQ"Y)7@& +MIB27`Y<0N25X!*8*<`FF"Z;)<+39C@L`"P#8`*4#I78.X`T$I2D#C^SQP$8. +MP`2,(/^/!_(`V<]P@`#<+2"@T<#@?N!X\<"J"H_L)@[`!(P@_X\O\EL*40#/ +M=8``W"TBA0;8J@DO]?_:U@PO]0;8"'8/V`:F%=@'ID`F`1)`)0`3?@_@"P;: +M`-@+ID&%!M@`V0X.+_4/(8$`SW&``)!&#X%$C0\@@``/H78.+_4&V+$"C^S@ +M>/'`.@JO[$#:"'6$*`D/`"&.?X``(#O/<(``("ZGH"V&C+H$(8``4'#*(((/ +M```B-``,PNRI<#(-H`(^AE()8`*I<(0M`AK//'`X<52"J`""'4($*`D/`"&-?X``(#L$N!9X`"".#X``O$=O%0$6`!40 +M$!`A_H!*(4`@,O0PZB"&@.'*(((/```M-,HBP@`<"^+LRB/"`PIP)=F^"^_T +M`-K/<:```"!;@4AQ@"$?!"*@/(4EH`"``*92#J_U`=GI<`#9`-K*"^`-BB,? +M!'X)X`+I<'T=6!2^#6`"Z7`9`8_L\<"^"(_L"'8!V,]U@``@+@*EU@N@#`#8 +M`Z4!A<2E&PA1`,]U@`!`,"X(H```A0`=@!^MJ_[*^0"/[.!X\L]P@`"\1P`@D0"IZP`1`""`X,H@@0\``"XT +M3`KA[,HB00//<(``("XF@`#>&PE1`,:@SW>``$`PQ@]@``"'`!^`'ZVK_LH` +M$0`@(@SO]0'9=!B`(ZH)8`*I<&4`C^S@>/'`!@B/[`AVSW6``$`PD@]@``"% +M`!V`'ZVK_LI>"N_]R7!5`(_LX'CQP-H/3^Q(=VAVB'7/<(``5#N$+0D?,"!! +M#D#8C+@$(0(`$'+*(((/```C-*@)PNPEA@6','#4"J("RB!"`PD`C^S@>/'` +MF@]/[*[!`-W>#F__J7!""J_U%-B+<<]P@0`L2HX,X`LHVHK!B\*V":`,J7#/ +M=H``("X%ACC93,#/<*```"`;@$W`BW`*""`+D-HGAJ*FA"D)#\]P@`#``$#;`(?%I4"@`(<+@%IP*!C;@"H0X.8```$``@SW$"`&AOZ7``VDASY@X@ +M`$HD@`$`&``@P:7&I;$&3^S@>(0H`@H`(8!_@`",2A$$@`V""<_TX'C@>.!X +MX'AI((`!;R$_`&D@``#V\>!X\<`2#D_L&G`*(8`OH```#`#>"/`0$0(@OF&Z +M8A`9@"`C;F$(1"#/<*``8`R(B&B(2(A`*@T"97W=#!&3@N7,)>*3S"4BE\HF +M0A`<],]W@0#X+H*O1*](B&.O"(A%KP:O$0WR$\)I!V]>"J_L#=D-YA$-$1=` +M)P`53@JO[`W9#>80$0$@`B"`(QEA$!E`(.D%;^P!V/'`@@U/[(P@!("*`"8` +M"'6##105SW>!`+@N"B"`+X$`."]6)T`4#@JO[`+9"!``(6,(40!6)X`4^@FO +M[`39Z7"`((("[@FO[`+9"A``(4<("O!5)T`9U7C.":_L +M!-EDO0'FSWX*$``AZPX"D%4GP!BV":_L`MD,$``A#PAS`6*]`K@+#040`-@7 +M\`#>"O!5)T`:U7B2":_L!-EDO0'FSWX,$``AZPX"D,]QH```#`2!N&`$H0'8 +M*05/[.!X\<"@X`AQ`-@)]\]P@0"X+CF@6@FO[&C@`=C1P.!^X'CQP(H,;^P! +MVHP@!(#"(HT`AN`Z<+0`)0#*(&4@"B.`+Z````QH$X`@SW>!`)@O0"=2$6@3 +M@2``KP*/(:\989#A2B``(,H@CB!`)Q01`MYO"%$@`-T/\/8(K^P(X`*/`>4! +MX`*O`H^O?3-H-7DR(D$@/F8ACT<-0Q`#N!5X@G#."*_L`=DBCP.Y-7D`(8`/ +M@0#`+[H(K^P$V0*/`[@5>$)PJ@BO[`'9`H\#N!5X^&`EB*<)!`+@N"B"`+X$`."]5 +M)T`;V@]O[`+9-!``(6,(40!5)\`;Q@]O[`39Z7"`(((-N@]O[`+9-A``(4<( +M"O!6)P`6U7B:#V_L!-EDO0'FSWXV$``AZPX"D%8GP!6" +M#V_L`MDX$``A#PAS`6*]`K@+#040`-@7\`#>"O!6)X`6U7A>#V_L!-EDO0'F +MSWXX$``AZPX"D,]QH```#`2!N&`$H0'8]0)/[.!X\46Y-7TBA<2X#R$!`%T";^PBI?'`X<6J"2_Y,]@8N$\@ +M#021O<]P@`"LXN(((`R2O2BX70)O[*5XX'CQP-X)3^Q^#<`%%^B>"\`%K@K` +M!8<2@3`!X8<:0C`1"%$`%\@$Z$(+(`1@RAO8-@_@#@#9JO!V"^`%`=U"#,`% +M9@H`"YX.P`YR#(`.-@L/_LX*H`JI<&((@`5V",_T%@T/_HH@Q0_/=J```"`+ +M'AB0SW"``$@5`("-Z,]Q@`!T,@"!P+@`H<]Q@`!P,@"!P+@`H<8-``-:"L_S +M>@M/]38,``M:#8`!`-G/<*```!`IH-X+``I`V078%;@@H/X)P`6""(`-K@]` +M#1(+0`GV"(`"-@J/]3H.P`,:#,_TC@C/_C(,#_FV"D`#_@V/]$H.P`/&#`_V +M[@]``!(*0`DJ"2`$#]AF#8_O<@@/^;8.0`;2#\_]A@D`"`X(#_Y*"H`/#@I` +M!HX-@!"."P_^#@I`"U(/P`HN"\`!A@]`!?(/0`J."8`*3@F`"OH/X`4`V,]P +MH```,#`8@`\`@```P@T`"@/9SW"B`(!L-J#/<*(``("DH`*&A+@"IL(,C_2& +M#,`+SW```/[*E@J/],4`3^SQP$X(3^RZ"^`#`=V!X,!];@Z@#;M]`-G/""FSW"``)0"$'@4I\]P@``/'`"@\/[/0<"+!:<;IR +M&G.(=PHA0#$*)X`AZ'4O)```&%&MD@L"*E(X4`D189Q`2'N`"Q4R#`(`RQ(84!@:VX`:$AA0&! +ME+@!H2T&+^RCP.!X\<#N#0_L]!P(L'IQ&G)H=@HE`"'(=4(/(`)H<`AW4R#! +M`%-H57K'BH0N"1\$N(8@_@,%(%0`(((*(D`N'0E>`L]P@`#8- +M(`+)<(ZX(X6/N`&Q"!U`%`"%'-D@H"&%`8&DN`&A`840&`(%`84S&((%`84H +M&$`%`84Q&,($`84R&,($`84T&`0$`84,X$8.+__I<4D%+^RCP.!X\<"*#B_U +M`]C/<(``_"]@@,]R@```,`"*SW&``$@PSW*!`*PL8'L@@='`X'[QP.8,+^P( +M2=Q`"&`#X$`:""1!`_LX'CQP.'%D@DO\`AU#WFN#^__J7"!!`_LX'CQP.'% +M`-L$\`'C;WL]"U,`%-D`(X`/@``P+2"H`-T`(X`/@`"HTZ"HX0T3E80K"P0R +M;39Y)W$`(8`/@0!H('()+_`!Y:]]\O$Q!`_L\<"."P_L.G`:<1MR`""7#X`` +M,"T`%X$@`-Z`X@(B +M`0!0<,HAC0``)94E`!U`($(B0"`O(@<@*G$$*?X$+W*Y#:*4BG$!W0`7@2`J +M<`0H_@1AN0`?0B`*<``G4AX`(@\EZ7&^#V`+)-J*(/\/@.7*(H(#RB(!```D +M@"1!H,]R@``$@LID"#^SQP'8*#^R&#^_O"'8( +M=00F@!__````W@_O[S"X$'4!V,4"+^S`>.!XX<4`VDAT$?"$*`L$\]U +M@0!T("=S8V4+"<$``>)/>@'DCWS/`HD@"^!`&@@)W"*=PH@0"[X8"IQS@Y@"R3:!!$3 +M(!OPLFZV?4`E`!D"``J0'8R0`/[.!X +MSW&``#`M"6'@?TXA``7@>/'`:@@/[*G!"'5G"(`/K:O^RN8-S_^!X-`-(0;* +M(*$!BW$V#N__J7`S"%$`!<`K"%X!SW6@```$#X7/=H``Z+L`I@;8#Z4(%`$Q +M`<">#^_Q0KD`A@^E`=@,\`QP$PB?`<]PH```'!P8@`\!`````-AI`"_LJ<#@ +M>/'`\@_/Z^X+S__/=:````0/A<]V@`#HNP"F!M@/I>8+C^]2#2`&!MC/<*`` +M`!P<&(`/`0````"&#Z4I``_LX'CQP(;@"'$`V`?RSW````1"F@E/[/_8A@O/ +M_X#@RB"!#P``_P`"\@.`T<#@?O'`@@_/ZX;@"'<`V`CRSW````1":@EO[.EQ +M_]C/=J````0OAL]U@`#HN^^F0@OO_R"E((4OIH7H;R!#``+P!8"M!\_K\<#A +MQ0ARAN`H=0#8"/+/<```!$(F"6_L2''_V-H,[_^I<9D'S^O@>/'`AN`(<0#8 +M!_+/<```!$(""4_L_]B.#L__T<#@?N!X^0+/__'`Y@[/ZX(D"S1:<`#><@[O +M_\EP"B<`D`[RR7!Z"N__R7$PB`'=$0I.(`6`AB#_`QD($`3I=0SPKWE>"N__ +M`-@%@`T(7P$!Y?$-Q).Q=TH`+@#*(8XCR74Z=@_P+R%'!#8*[_\`V`AQ0"%1 +M(`IPF@M@"R3:`>4C#<43KWD:"N__`-@:<`6`V0A?@1)N%G@`(`$'`>;L\1IV +M*G4E\*]Y^@GO_P#8"'8?"!`@`B5!%`*Y-GD`(0`'R7%."V`+)-I"(%`@$(X= +M"@X@!8:&(/\#D.#*(8$/_____T`,X>_*(($#`>6]#<2380;OZX`D"S3@>/'` +M\@W/ZWIP`-B&#>__.G`:<"IQ"/#""^_OR7!`(5$@0")!($\))01:<2]Y>@GO +M_P#8"'8%@(8@_P/I"!&,$([="PZ@3"$`H#P+(0;*(*$!X89`(DT@PPT%E*]Y +M2@GO_P#8)8`+"5X!X:`$D!]G`>7S\=T%S^O@>.W)M;C@?^T:&+#@>.[)F[CN +M&ABP[\F5N.\:&+#PR8>X\!H8L/')@+C@?_$:&+#@>.W)E;C@?^T:&+#@>/'` +M4@W/ZPHF0)`(=0/R&PT2&,]R@`!L,<]P``#:#JEQ,@\O[$""SW"``)0QM7B5 +M!>_KP*#/<$4`F"#@?Q2(X'C/`(A`@`1#H1P`(```#!P;R`+``/P`=C@?J+! +M0<$`W/(2`[8$\'U[`>0K#%41$^OY"QZ`A"P)'P`A@7^``"`[1('E"(&`2I$$ +M%`$QW0I!@`'8`O``V.!_HL`/>1L)=0$`VH0I"0\`(8%_@``@.V"!"PC``$AP +M!?`!@?L(48`!V.!^A"@)#\]Q@``H.S`A00X`V(7AS"'B@`#9 +MD;D'"%X$)*+@?N!^X'CQP.'%SW6@```<-H7QR<]RH```("1X$PA>`7<2`(9& +M#X_U(-@&\`\('@`:#X`*`=@6I2$$S^O@>/'`X<7/=:```"`$'9B?(`!_``<= +MF)\!`$`\.@I`#8H@!```I?4#S^O/<:```"`'&9B/`0```$P1`H9$*#X+SW"` +M`"U.,B!`#L]T@`!,W2\H`0!.((,';WL6),`0`)`;>("X!'HT%(`06&"@&0`` +MX'[QP"X+S^L`W<]T@`!PX*EV`O`!Y1D-%13`A,]W@`#4";YFP[[T)X\3ZP]? +MDN%N.PTU%."D`-W/=(``5`G6?*"DH:0$N(8@^`.)N,.Y!7D*NR5[SW"``-0) +M%"",`V"T(.#5>$"@`O`0WC$#[^O)<.!XB;@`V0+P`>$7"14$SW*``-0)]")" +M`,FZ[PB!@`+P$=G@?RAPSW.``-@R\",#``*X%'@`((P/@`"8,@*$#R#```*D +M.=@$'(`?``"`'`>X%0G>`,]P@`"`'`0<@!^``(`<"0D>`9BX`:0)"1X`@K@! +MI`/J@;@!I`L)'@*6N`&DX'[QP#X*[^L`V0AVSW"``%#E`8"BP4'``=A`P,]W +M@`"8,B"G1R;-%\2]%/`O*$$#3B"$!\]Q@`#8,O`A``'_VA3A%7E`H8MQF@GO +M[RAR$"4-$>WM2B8```HD@`$K\"\H@0-.((T'SW*``-@RWEG!!$%`/`B +M0`,B@04F1@$%)$0`^V-C@R"'%.)E>2"G%7J@HJ]YA"D)#P`A@G^``"`[0"(! +M!#H)[^\8XA`F3A/8[L]RH```*``:F(&S$@&&0"P``88A`PR&(/P#)7BS&AB` +M!!J`CSH$2G#1`>_KHL#@>,'9SW"@```HSW*@```E(:+/@`B@P^``)@R0H,5?!`B`@!"HT6$$PF! +M`/_9):2+<28([^\H,]QH```*$,1`H8R$0&&AB'CCP'8!O+KNM$BHH'*("$`X'[@ +M>(0H"0_/<8``*#LP(4,.SW&``-@R\"$"`,]Q@`#0\/`AP0`#NEAY`K@4>``@ +M@@^``*0RX'\@HN!X)0@5!`#;SW*``%0)SW&``-0)%"$,`&"T%GI@HF&B(.$5 +M>6"AX'[@>/'`X<4(=<]QH```)$J!(H$`V""E%NIW"=\'SW"``)P+/8`*V&3A +MY@R@#HRX#'`7"!X'SW&@_H0*!=@5N"2@(-@E\"QP^+@`V!ST#'`5"%X'SW"@ +M```,+8`+@"3@"0A$`!C8#?`#V*8,H`X`V6QP]0@?@`QP[0B?A`#8@.#*(.($ +MSW&@```D(H$@I<4'C^O@>/'`SW&``'AC#X&'Z`'8D@Q@``^A`_#&"P``T<#@ +M?N!X\<`>#X_K"';/<8``=%D`(8\/```$"@J'0"$0`0#=A.BI/ZS0@@"\``.@,$'88 +M#$$`Y/'/<(```#//<8``>&9-@0"`'PH!`,]P@`#\,@"`@.#A(,('"-@+@8#@ +MX2#"!P;8!]C@?N!XSW*``'19)&HP(8$/```$#0#8D.F5(DH`)X*,Z2B"BNDI +M@HCI*H*&Z2N"@.'*(.$`X'[@>,]QHP"`5QB!AB###QBAX'[/<*,`@%<8@,]Q +M@`#\,H8@]P_@?P"AX'C/<*,`@%<8@.!_#WC/<*(``&P>@(8@^P_@?RBX\<#F +M#\__`>`/><]RHP"`5QB"AB###R5X&*+1P.!^X'C/@<\@(@+0("$"'J'@?N!X\<"N"```"NC/ +M<(``5%@$D!\(@P\```T.(@@```OHSW"``%18!)`/"((/```-#@'8`O``V-'` +MX'[@?P'8\<"*#8_KSW"``/PR`(#/<8``=%D`W>1IG.C/<(```#-`@``AC@\` +M``00318`EB4*`0"2#H`"#>@T)X`?```8"A$(@`\``$1)/!8`E@+H`=W/<(`` +MJ"<5B!,(7@#/<*#^U`X!V<8-;_VI`'P``!`HPH&8((``,D)4ES1+`I:(/[_\' +MV"7PC";#F]/WK@[O_P'8!]D`)X`?```$"C"@.@@@``R0>@_O_PC8+@[/_P'8 +ME27-$@"ESW*```0S!H($@""`QW')`8##E@K@#$APR02/Z^!X"''/<(``>%F4 +M(%D-(+`$(8`/````_TBX+WGE`B``!=KQP`H.S__/<8``_#(@@07I@"`##!!X +MT<#@?N!X\<#6#<__]@W/_XKH'@[O_P#8-@[O_P'8T<#@?L]P@`#\,@"`!.A> +M"```^/'V\>!X\<#R"Z_K"',H=4AW(@[O_P#9SW:``'A9#NB`X\PE89$#\BAP +M$/`P)H`?```X"OOH'@E``#`F@!\``.P,$'<`V,H@80")Y1D$K^O*(&$`X'CQ +MP-H,@`+/<8``>&:#Z`'8"Z$+@8_H`=@+H<]R@``$,P:"!(`@@,=QR0&`PZ() +MX`Q(<-'`X'[@>/'`X<7/<(``=%FD:``@@0\```0-#(D+"%$!`=@*H<]P@``@ +M,QX)X`R6)040`-@/I;4#K^L.I>!X\<`R"Z_KF'$(=DAU"B6`#X``>%D`B+X/ +M(``@B0AW%0T1$3`E@`\``!P*@.#*)R$0$PU1$3`E@`\``"@*@.#*)R$0$0U1 +M$2H-S_^`X,HG(1`3#9$0R7""#"``B'&`X,HG(1`5#5$0SW"``(2V`(""X,HG +M81`+#5$2,@W/_PAWM@KO_0#8@.#,)>&0#_3/<(``J"<5B!$(W@#/<*#^]`XV +M"V_]`-D!W_D"K^OI98C1@<@LP`B@0\``(0,'8$!X.!_':'@>/'` +M`@J/ZPAU*'=:%FPX,PG(9P%\H#ES""&``R7(:<)8A!B1L$0`@$P@!!+8.(`!*<(#@S"9BD!CTJ7#I<4IR +MQ@T@`,ES@>#*)6$1'/*I<&H/[__I<6P1`"`K"``$W@A@``IP`-T0\"\B!P3) +M<)8-[_]*<8'@RB!!`T`/X?_*(<$#`=T&#T`%O0&OZZEPX'BBP?'`6@F/ZV7` +M9L'/=J```"!L%A`0@.(#WA;AB\A"@19 +M80'AE2?,'R"G#-PK`8_K\<#@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C1P.!^X'C/<8``VEA7(<`,R0;@"C/:SW.` +M`'A9,"."#P``-`H0Z@`CC`\``.H,,"."#P``!`T`M(#B^`8!`-4$S_K@?N!X +M\(P@PX\`V1'RCN#A(,4'P"!E`*K@P"BE`.$@Q0?"("4% +MC"!"C!X\<#AQ0H-(``H=78((`"I<>D'3^O/ +M<(``>%DP((`/``#L#!T```#@>/'`X<6."2``2'72#^__J7'!!T_K\<#2#``` +M`(#!N-'`X'[@>/'`-@]/Z\]V@``XWP"&SW6``*S?BNA5V%8)(`!3V=8/S_\` +MI0'8`*9]!V_K`(7@>`L)-0,`V@"`,?`-"94#`(`BN"WP"0F1`TAP*O`+"54, +M`(`DN"/PP.$$]P"`)K@?\.#A!?<`@"BX&?",(0*$!?<`@"JX$_",(4*(!?<` +M@"RX#?",(4*)!?<`@"ZX!_"]#D3P``"U``"`,+C!N.!^X'C/%G)X@WT`(G$X`GT,".`#P``+`H+"%$``=@0\,/B#?0`B<[@"_0P(X`/ +M```L"@L(40!"V`"I\?$`V.!^X'CQP.'%"'7/<(``5%@$D"L(@@\``/__SW&` +M`'19!&DP((`/``#L#)4A2`H"N!1X`&$HN,"X!O"V#L__$'4!V,!X509/ZPL( +M%`FPX`'8PO<`V.!^X'CQP,H-;^M!VL]U@`!X64)X1"B^!D)Y`"%.#HPF"IG* +M((8/```D"9P/INO*(88#`"6`'P``1`K.8#(E@!\``#$*$';*((8/```E"7@/ +MINO*(88#Z05OZ\EP\/-H +MSW(``/W_!"&!#P``]?]$?R5_&W@%?S8/[_^*<`OH!">/'P``W_^!Y@'8P'@% +MN`5_IK\`V`\.D!"!YM$G(9$"]`'8@.#*(&(`!KCE>#L-M!,0>3(C0R,($`(@ +M?7G`N4$JS`#`O(1Y"KG/=```__T$((`/``#_^81Y!7D+"M\!X+O/(6("`!E$ +M(`'E0PW4G%8B`2(.D:FX#K$.D:JXR01OZPZQ\I<`'EZ0W4G,]P@`"4EAV(+>@`W2GPD@H@`ZEP(^B$ +M+0$3SW!%`'DM,B!!#@`A@']%`#PM1"D^!PC@:@W@`C`@0`X(=V(/X`*I<`AV +M%@_@`JEP"'+I<,EQJ7.J"B_W2B0```'EKWVS#1*1801/Z^!X\<#N"T_K2';/ +M<(``=%DD:``@CP\```0*`-T-ZQ"'%PA0`@?8$*<.AX#@7`C"_ZEP*_#Z#8__ +M4(/'`"'//%E&#:__ +M`-D)Z#`B@`\``$`*$'/*($(``O0!V-'`X'[)X$3/'`X<7/=8``>%DP)8(?```D#<]P@``@,Q2Z)H!=>B2!EB7%$2"!K@B@ +M#%EA`=CU`F_K`*4R:#1Y`"&`#X``$&+@?N!XSW.``'A9SW&``'18`=B5(,]Q@`!T6`#8E2'. +M`^!_`*'QP!(*3^N")`,W6G`:<3IRSW6``'A9SW>``'18BW;)<,]Q@``PY8X- +M;^L0V@`<@#0('`0T>0E1(#`E@!\``$`*-"6!'P``Z`R"X,PA@8\``$)#!_0$ +M'(0_``!.0P/P!!Q$,``E@1\````0.Q$"AI8E!!4"NE1Z0F4''`(P!AR",#/8 +M0\``V@CP]">#$!)J@W!DH`'B]0K4C$$1`(:.Z(3"R7`0V2(.;_S,VPCP`-A# +MP,EPM@UO_!#9N0%OZX`D`S?QP/P<#+`"'$(P`-@#'`(PBW`$V0(*X`G)VJ'` +MT<#@?L]S@`!X63(C@P\``#`*%PO0#\]T@`!46(24#PR#'P``0`X(+, +M(>*!^_7@?VAPX'CQP.'%SW6``'AF!(4+Z`#8!*4,C87@C`V!_P*%=@CO_RR- +M90%/Z^!XSW*``%180"(,"$AS,"2"'P``/`Z`(X(!!NKT(T(`()!%>2"PX'[@ +M>/'`X<7/$Z#N__/J)&#N__"'46",__+@OO_ZEP&@SO_ZEP +M5@FO]ZEP!0%/Z^!XP>`!VH?VVN`%]L'A@_;:X<+V`-JPX,PA(8P&\H#@S"$A +M@`/T`=K@?TAPX'CQP.'%SW4``*W>`8#/<:4```P(H0'8":'/<8``B!3^#^`! +M`*'/<0``556`X,H@0@"A`&_KRB!!`_'`$@A/ZZ/!"'4#W@&`&+[CN,HFXAC` +M+B(6T2`B@/'`(I`(`+P`` +M555J"R```-Z:=GIV.G;)<=IV6G8:=@GP`X4/(E(@ZAH8L.EQ0"96()D.E2$R +M)8`E]PC0C^%I`-M+C0\C@P5K>@#:SR)"`,HB(0!%?DJ-:WH`V\\C0@#*(R$` +MR0@UA04AT2`S)@!P@`#`XD`G`G(4>@!Z#R%1(-;QSW"@``!'`!`0``\C4R#. +M\4HD0"#,\8H@"`4`V0#:!@FO_I"ZQ/&*(/\/SW&E```@`:'/<*```!T@&(`/ +M``@```#8`J&T\8#ARB"!#P``K=XC\A05!!`!A2*%0X4^"R``9(7)<((*(`!* +M<2IP8@P@`&IQ$!4$$`IP%!4%$"&%0H6."R``8X5,)`"@I`L"`(H-P`'J<.T% +M#^O@>/'`N@TOZU8@0P+/=J``P$;/=:``X$;/0$ +M'E`0(H<$'5`0\0P4DC&`SW"@``!&):``V`?P\",!``'@!!I0`/D(E(`!V<]P +M@``\'R"@SW```%55Q04/Z^!X!.#//'`X<7V"^`!M,$FZ/(((`"+=4X((`"I<`#:8<(_V04< +M0C`&'$(P"-@''`(P#-ABP!+8"1P",`P<@#].T*^KBB"(!$3`"QQ",`H<@C!% +MP@(.[_^I<%$%+^NTP.!X\<#&#`_K"'88V`&F`-VBI@S?YK84V`>V$!Z$'P`` +M_P\F#2_OR7"EIA@>@!\/``"``=@Z<`>F(!Z`'P`\$``&V!IP"::*(`0`"J;@ +MIF8,[__)/'`,@PO +MZXH@SP^TP00<@#^@````"!R`/Q\`__\,'(`_H``,!$3`%!R`/Z````Q&P!P< +M@#^@````2,`D'(`_H```<(H@WP]*P"P<@#^D````,!R`/P,`__\T'(`_J``` +M`#@<@#\#`/__/!R`/Z``%```W5#%4<6*($0`4L!3P(MV]@WO_\EP@<"I<8X( +M+_`@VAP<@#\```"`1@[O_\EP!00OZ[3`\.XPC=P'W*)($0SW*@`*!'D^,0W\HG0A/* +M(X$`RB,"`__:*'00\!8@30#&A14C1```'(`#Q84!X0\DC1-0=LHD0A/E"=2` +MSW"@``!'/X#X>D9Y^'PE?)^@20,/Z^!XI<'/=*```$<"I`4DP@!0I$0<0!'@ +M?Z7`I<%`P$'!(,$!%(`P!2&!#P```#\0N`5Y!2&!#P`_``#/<*```$8HH`,4 +M@C`"%($P"+I%>2'"$+I%>044@C`8ND5Y*:#@?Z7`SW&@``!(`!F`CX`````% +MV!6X+!B`#P"`T```V($9&("`&9B/`(```.!^X'BEP<]SH```2``;`(`,&P"! +M+R)(`8$;F("`&YB/`(```.!_I<#/<:```$8`@44@P`$`H078%;@L&(`/`(#0 +M`.!^SW*@``!&(!J`#P,+`C_HR>D2`;8P<#_8RB"B`@4@@`\_/P`2":+@?J?! +M0L//<:```$<`H0@4`#%((``#$+@$((`/#P````4@@@]`!@"`"A0`,!_I\#H$@*VZ1(!MAL*0``=>,"X&WA%($$!SW*@``!&`((E>`"BX'XF>,6X +MSW&@``!&`J'@?N!X\<`^"@_KX<5$PH7#`-H+\`3C_!,,@!4@C0#P(0P#`>*` +MI03$[0H$@R3R"C`>+K"A2(X'_! +MQ>!XX<43"!`!!+@4>``@@0^```CI`-H-\,]P@`"8Z4Q@SW.@`-`=\"&``)5[ +M`*,!XNL*%(/@?\'%X'A`@,]QH```'UZA`8`?H>!^SW*@`(`=/(+%N$8AP0\E +M>!RBX'[/!^X'C/<:``@!T6@;6X%J'@?N!XSW&@`(`=%H&QN!:AX'[@>,]QH``` +M.$"!SW"``'`V0*!!@<]P@`!T-D"@0H'/<(``>#9`H$.!SW"``'PV0*``V`"A +M`:$"H0.AX'[@>,]P@`!P-@"`SW&@```X`*'/<(``=#8`@`&ASW"``'@V`(`" +MH<]P@`!\-@"``Z'@?L]QH`"`'!JAX'[@>,]QH```'A>!!2"`#S0`O"87H>!^ +MSW&@`(`?@.`;@<\@(@30("$$&Z'@?N!XSW&@`(`?@.`;@<\@H@?0(*$'&Z'@ +M?N!XSW&@```>%X&#N)2X%Z'@?L]QH```'A>!H[@7H<]P@`"$M@"`@>#,("*! +M!?07@;2X%Z'@?O'`?@_/_UX++^L"V-'`X'[QP.'%SW&@`(`#\__`=G/<*```!XYH-'`X'[QP`AS`=QN#^_N`"P`$`?P +M`-AZ#^_N#R#``'SHT<#@?@#9#R$!`,]PH`"`'BJ@X'[@?N!X\<"*#L_JSW"` +M`$@5`("AP>L($0#/=H``)"@#AD`HD(!M\L]UH```#.V%L@NO_8MP"B&`+Z`` +M`!"#Z#\/!10`AD.&02B!`")XGPB%`)L/%!Z$A@:&0"\#%)A@!J80O`#'SW"@ +M_I`!`MF%>IH((`#E>PX)```Y\$`@P"$$((`/``#\_YVXG[@P&1B@`!^`3P"` +M]P#/($(H(/``#_OX^ZH1J$`'P!#`L#U"02`SW"@```@&X`"&QB``]@' +M&QB`T<#@?ZC`X'@`V,]Q@``D*`2A`Z$!@>!_`J'@>/'`<@[/_T()@`G1P.!^ +MX'CQP,X,S^H(=RAVFG*Z&ESW>@``!% +M'(?$I0*E'8<4'0`5`Z48'4`5'!V`%"`=P!0D'4`4B@W@"@#8"J7/=J```"`: +MA@HA@"^``$@5#:4;A@ZE'(9$'8`?!0`$A`^E%M@0I0`1`""%Z%8/+_XHV`+P +M"G`2I0`1`""`X`#80`\!_A.E4R?`=12EYLE8'0`7%Z7/<:```!P$@50=`!<8 +MI06!>!T`%!FE!H%3)@(C&J4'@1"Z&Z46@1RE"($=I7P=@!H>AX`=`!"$'0`; +MSW"``$S7"!B`#,]WH`"`'#J'(Z#/<8`````D@22@+R$'!@BY)7HO(<<%17DE +MH*EP2@N@`2;9!!^`'\7NIY$;A@&GJ7"^#6`-)]DN",`-P@N/_+D#S^K@>.H2 +M`K8+>A+RSW"@```@SW*@`(`Z#X1N``:-3(8`$D[B?N`&C0:/@?N!X +MZA(,M@M\%?+/<*```"#/=*``@!P$'(`?Q>Z$X1N``:13(8`$E+B?N`&D0:1A +MI.!^X<7J$@VV"WV(=!?RSW"@```@SW6@`(`$;@`&E4R&`!).X +ME+B?N`&E0:5AI8&EX'_!Q>!XX<7AQNH2#;8+?8AT(?*B:@4EC1_%[H#ASW:@ +M```@SW"@`(`)-I$ZD4*1/I$2$`-\/)P\0 +M#>GF>J5H#R)!`PK@#R$!`"2D@-@,JQ3PY7I$I%((H`+)<`[H\"6`$^MX"O+) +M<*8+[^X!V0#8R7'^#V`-_]I1`L_J\<#B"<_JSW*``(RK0(K/^#*PG%`^R-)P_3$`'FQ*T* +MX!`D#!`"ND-R#!(`!H2C1N`,&A@`$!H8,!;P$0X3$4^#"0F%``'FQ*TLC1T) +MT0`5>Q>#`>",(`^*%Z,&]`#8%Z,,K12M:0'/ZO'`_@COZ@#;SW"``(RKH(C/ +M<8``@#=`(0`%\"!.`Q;P+RB!`TX@C`<`)(`?@`#$-V"H!(%`)((2#R"``$5L +M#R"```2A$"8.$^SNJ7!>"N_N`=D`V,]R_P#__[(.8`VI<0T!S^KQP/H)S^[/ +M<(``C*LJ#>_N`(C1P.!^X'C@?N!XW0'/[CT%S^[QP.'%"'6V#F`"#WB`X'`- +MXN[*($(#V0#/ZN!X\<#AQ<]U@`",JP"-^@GO[@#9((T`V%(.8`T2>K4`S^KQ +MP#8(S^H(=]((K_0H=@]]R@YO]*EP"'+O?QT.4!`I#I`0+0[1$`#9SW"``)0W +M]7@@H`[PT@K/[L]Q@`"4-_5Y`*$&\*EP#@@@`.EQ50#/ZO'`Z@^/ZBAUSW"` +M`(RKP(BF"N_N2'#/<8``E#>U>0"A#@Y@`J]X!^C1=5P,X>[*($$#*0#/ZN!X +MBB)0",]S@`"`-R2#&'I&>0\A`0#@?R2C`-F5X,P@(H#,("*%RB!"``+T`=@1 +MZ,]S@`!X)R&#SW2``)P+A>D(E$.$1W@`HQV$$.`X8`&CX'[/<8``5!1+@0#8 +M"Z'/`(01```8Z!^!4R#^@!3R1B#"`U^A`]@*"*`)-=D# +MV+()H`D$V<]PH```'3@8@`\`0```T<#@?O'`SW&``/`W(8%A"1$!@^#*(2$` +M!_*&X`'9RB&"#P``_P",(<./(O+/`/R9G@ +M"F_O"';/=X``\#CR#"_O%84`V!:E=A<`%@'@=A\8$$?P&86`X'P*8N_*(((#,LB# +MX,HG(1`(\H;@`=_*)X(?``#_`(PGPY\S\@'8\"3!`P#:#R+"`UL)@`\``/__ +M>X52>21[>Z5\A61Z#PY0$!KJ9'D\I1;P@.+*(((/``"?,\HA@@\``.T!5`[" +MZLO)`8#CN`/8!O04A8'@`=C*(*X`SW&``'#VX*%"#B_OPZ&A!(_JX'CQP"X, +MC^H(=\]U@`#P.!Z%*'81"($/``#__W((3^\5\$H(3^_/<8```!V,(@#@`3>,&X]@TO[P+@502/ZN!X\<#&#\_NO@Y@"0+8SW&``'`X +M\@T@``*ASW$``%R-Y@]@"0+8SW$``+R-Q@]@"0+8%@Q@!`#82@D/[\8.S^[1 +MP.!^X'C/<(``\#G@?P2`X'CQP)8+C^H(=L]R@`#P-\]U@`!P.0#8"PD?`!6% +M`>`5I5X2``8?"(`/``#__P8*P`P#I1,(4`":#P_O@-@J#^__R7'%`X_JX'CQ +MP$X+C^JV#@`"SW:``%`XV@X@`@6N^@X@`@:NM@X@`@>N`-D/(0$`$FD5>`BN +MI@G@!`:.SW6``/`W&Z4%C@T(40!N#2``"(X#A1'H)@@@`/G8K@P/[YH+#^]: +M#,_NM@E/[]H+#^\*"$_O50./ZN!X\<#>"H_J"';/=8``\#@.A0;H!B"`@PZE +M)`D![P\.7A'/<(``!#J.",`+1":^D0[R#H41"%\!SW"```0Z=@C`"SP=@!\` +M`#\\C";#GP[T`-T*\$0M/A<`(8!_@0`@+58(X`L!Y>\-%)'E`H_J\"H_J +M"'4*(H`JSW:``/`X$H8*(X`O@`#P-],(40``$P$@`-@:<+T)$0+^#<_N[H8Z +M<#WOC"("H,PE(9`A],]P@``\#!Z(^@NO_0IQ6G#/<($`N"X1B!_H:@O@`$IP +M&^C>#:_^2G`NAA?HSW"``*!'!8`C")X`A;DNI@WPC"(#I07T4"?`$`;PC"(" +MI07T4"<`$0ZF#H90(`"`#J8T"`'OA^W($P$@`>'(&T`@.0E1(,]Q@`!P.(7M +M&8$!X!FA#?`6@0'@%J&$[Q>!`>`7H0L/'A`8@0'@&*$-#QX0%($!X!2A2!X` +M%"(*[^ZI<,T!C^K@>/'`=@FOZ@'9&G#/=8``\#@/A<]V@`#P-X8@^P]"(`*` +MRB)B`+(/+^\*<`"&2P@1`@Z%(^A`*,\A]'_/<8``G*SA80_IA;@.I<]PH``` +M(#N`SW"```0Z4@^@"X`A#PH.A48@@($.I0GT=@_/[L]P@``$.N(.@`L\'8`? +M```_/&$!C^K@>/'`^@B/ZBAUSW:``/`W((9%"1$"!>A/'I@?```_/0#:$FT4 +M>``@@0^``(@X0*%N"B_O`=A.%@`6'0A?`,]PH```(#N`SW"```0ZEB$'#=8. +MH`NEH!4!C^KQP,]S@`#P-V"#,PL1`G)H='O'_N%X5?A0AV!7I?I0/85@I@"379`]C^"V`)!-G/<*```!TT&(`/`$```-H( +M(`W)<&$`C^HR:#1YSW"``(@XX'\@8.!X\<#2#V_J"'//<(``\##R9.$\]W@`#P.%4G +MT14_J<=D.!^X'CQP.X.3^H(=RAU +MSW&``/`W`8%(=D\($0$-#5$0=1$`!D,(U`#/<*```"`;@`(F`1",(2"`1O:I +M<(H*[__I<1/PC"&#CDCV!@L/[ZEP#@@O[^EQ"?"I<&X*[__I<:8*+^_)/'`SW.``/`W(8-E"1$!,A(!-H/ARB$A``?RAN$!V"\H`0!.(($'+WG"">__@-AA!D_JSW*``/`W(X(`V(#A +MRB$!``CR`=AE$H,``MF!X\HAH0)A@AD+4`!1@HPBPX_/(2(`!/2"X\\A(@'/ +M,]QH`"`'ABAX'[/<:``@!U:@1*XLKI%>!JAX'[@>/'` +MSW"@```@&X#/<8``%`X`H0&A`-I"H0'8!Z'/<(``2!4`@$2A@.#*(($/``#8 +M`(`(X?W*(8$`T<#@?O'`X<7/=8``%`X(I<]R@`#D#@:"*:4$@""`E2'(#U(+ +MH`M(<,]PH```(!N``:4^#"_O`=B)!4_J\<#//'`V@Q/ZL]V@``4#@*& +MH<$`W2+HBW4(V$X/8`"I<8GH!]A&#V``J7&#Z`2&`^@"V`+P`]BZ#`_O`-T3 +M"!`!`KC/<8``/`X4>`5ASW"````/7@J`"ZEP]01OZJ'`\@`V`.ESW:@```@!!8`EE,@_H!L#"'ORB!A`(#GS"`AH`/R&X8! +MI:4$3^K@>/'`X<7/-'`X'[@ +M>/'`Z@M/ZO42#;8/\"\H00-.((X'$FY#&`0(@(##^HO*X$`3B.,!^_IA"P)'\]S@``(/3`C0P[P\>!^\<`Z +M"V_J!-BJ#&_S`-WYR0OH#PA0`(+@RB6A$`7P^,F`X,HE8A#ZR0#>^!J8LPKH +MG@L/[_H2`;9@>:EP^AJ8LVD#3^K/<(``H$<&@(P@PX\)\H0H"0_/<(``'#TP +M($`.`O``V.!^X'CQP-(*3^H(=?3)C"7_GP8E#A#*(($/```3-*@,@>H8[JH) +M[^NIO?1)M0W#[$`"&*8!@>:EP$"9.D_/U&@L/ +M[_$"3^KQP'8*;^H(/(:&+"E"A$``]A1\`4B0P!H=1#P+R]!$TXG@!(0H"0\`(8]_@`#T/("G$"4-$/+M!B&-`/;)\QK8L`8@0(#V&ABP>`MA\\H@ +M80$/\"\H00-.((\'[W\2;T-P^Q``AA`ES1,G@&!YZ7#S[?,2`K85ZH'F/`@A +M`,H@80#S$@*V@.+,)J*0"_(!V/@:&+`+"!`@^AH8M`'8"?`&ZA8((``"V`3P +M-@H/[P#8_0%/ZN!X\<"2"4_J\Q(!M@AU^1H8L(KI^!("MH+BRB""#P``##1T +M"X+J\Q(.MA#P+RB!`TX@CP?O?Q)O0W#[$`"&$";.$TB`Z7!@>JEQ\>[B"0_O +ML0%/ZN!X$-D0\"\J`0!.(H,'4FM#/'`#@E/ZCIP&G%(=6AW$O`O*$$#3B".!Q)N0W#[$`"&*G&,@,EP"G)@?.ES +M$"6-$_#M00%/ZN!X\<#>"$_J"'4H=Q/P+RA!`TX@C@?)<*X*H`#I<1)N0W#[ +M$`"&$"6-$RV`8'G)!H)+^_R&ABPT<#@?N!X\<``V0\A`0#SR3)Y!"!` +M@/,:&+#RR21X\AH8L`KT^,D1"%$`V@IO\P38`MCX&ABPT<#@?O'`'@A/ZJ+! +M6G#Z<>()8`HZ<]R@`"\1SAB`(`Z8A`2%@!*)``@A"H) +M+P`AC7^``"`]*(4*(T`N@.'/=X``*#O*)@$EE?+R#T_S"'8P)\`4`"./+X`` +M@#T+"!$!"B8`)1'PU@]O\\IP)88%@/$)`8`,%X$@!2D^!`HF0"X#Z14?`A5X +MCQ@?`A4WA5P=0!0"A@(@@`4"(0(@+R")`-=P````0`':PB*.``/J%1\"%0`C +MCR^``&`]EH^-#!$0A.J3A84,$!`K"Y$`$^K/<*```"!;@"6&`H8*N2)X`GI! +M*H`"!.`:I4IP-@XO]R*&0?`"(4(@`-D$\`(B`@0!X0D*0@7W"92',84B>"\@ +M"0`5"(0/````$"\BB0!7"H4/````(!>/`>`7KPT+T0`"V!>O!/`!V!NE%X\[ +M")(`T@L@`$IP"M@4KQ0R7.&`"($`$&PA2`.(/ +M8`!*<`'8&Z\)\,IP[08OZJ+`%(\#Z!6/>>@`%P`@0,`$%P`@0<"+<+X,H`L* +M<2$(104JA=<)!(`*I3`=0!0"AB>%`B"`!2)X#J7A\2N%OPD$@`NE-!U`%`*& +M)X4"((`%(G@/I=/QX'CQP.'%]@[O\PAUSW&!`&@N%7D`@1`@0`/)!B_J`*'@ +M>/'`'@X/ZJ/!6G#N#R`*&G$(=4`J`"$6(!0`SW"``*!'0"`7#T`@`0<`(0`% +M`!`1`()Q!(%*)0`@0,"$*@DO+W<`)XX?@``@/0`GEA^``"`[9!Y`%8+"2G!B +M#F_Q"G%!P`+`?!X8(`B&@.!``@$`W@UO\RIP.G!*<`IQD@WO_P+".W`(%@`@ +MA.#`)X$?@`!@/` +M`&`]%X^&Z#`G`"6$Z!:/!.@!V!FF&!<$$1@?Q!0+AL]R_P___R@6%!`7"(`` +M)0H`!0(@`P4`)0$5`GD9"T4`"PH!!206%!`P%A@0.!87$`?P-!88$)IP/!87 +M$`@1`2`"P`(A008B>"\@"0!IA@(@@`\```!``B,!!2\D21"]>B\*!0,A"L4` +M-H\="5$`&0@2``HC@"\````@&!^$'P```"`!V1/PBB'_#P_P5H\;"E$`%P@2 +M``'9"B.`+P```"`8'X0?````(`T)4P`[CYL)$``GA@@1`"`<'D`5`B!0`,8- +M8`!*<"0>`!4"(,`E`"`8,`@1`2`"(,`T`B$3`*(-(`I*<%,@004$((`/P/\` +M``(E0Q``(((/0````'!QRB&%`,HA!@`*((`OH```(&P0`"`"(``&`O"X8/\( +M$H`"?4IPK@T@"J5YZLF-"!X$SW&@`(`0;PHGE`(D`@+R('(/<)18,-$((@#!"`(``B@2`" +M>0(A@``P +M0!46'T(5`<"Y`R_JH\#QP(H+#^H*((`O````R`HB@"__#___`!F`#P$``)`. +M#._S.G'/<8$`:"[P(0X`&_`O*($#3B"-!PX-(`JI<`AW8@P@"JEPU;@")P$0 +M,'#*(04`#PF%!``9P"-:<1IP$"9.$^CNA0,OZ@IPX'CQP.'%-@Q@``AUA"T) +M'P'9`"&`?X``=CV-`R_J(*C@>/'`X<6:"^_S"'7/<8$`:"X5>0"!#R!``VT# +M+^H`H>!X!8`!V80H"0\`(8!_@`![/>!_(*CQP-H*#^H(=H0H"0\`(8U_@``@ +M/0*%70B1`,]P@`!@$D"`4';*(((/``"<`,\@8@.H#&+JRB&"`Z(-X`$0V(0N +M`AH`(8!_@`",2B.%0(4%!(`@@`)QN@\@"U4E +M0!3RR?02`;8E>$H@0"`E",X#>@S@`1#8$(4$@`"``"!!!)(/(`M`)0`:Y@I/ +M_PIP!?`>"D__`M@"IL]P@`!@$J4!+^K@H/'`0@D/ZH0H"0\`(8U_@``@/2*% +M"'>&(3^-`-@(\L]Q@`!@$B"!,'?*(&$`B^C/-O>_/H`-KX +M=-AT&72X=#?P,B2.,(HE"1^L?L]Q@``@.P`A0`XT$`L`0"$*#`4FQ@+/=X`` +MX#SN$``'0"<+%@@D#!"L?B=W#I<+#0,`&A<%$:Q^-"-`'@@@"!"L?C`B0!Z` +MX,HA(1"L?B=Q,=P@`#LR8"`#0S>$0>0"0A2``\AP0`0(L(`[>K@?RAP +MX'CQP.'%"'&$*`D/SW"``-P\,"!-#H#ERB"!#P``+S24"$'J+RU!$TXE@!<) +M!^_I#W@`VX0H"0_/<(``W#PP($$.$O`O*$$`3B""!\]T@`#ZR1-J%7@49`\C +M@`"`Y,HC"0`0(8$`[^G@?VAPX'CQP$X.S^G/=H``(#O/<0``M!*N"N_NR7`` +MW1CPA"T)'XH@_P^`V0`F3!X`I``A@'^````](*BI75#521_]G/<(``H$=I!N_I(J#@>/'`\@W/Z0#>R740\(0M"1_/<(``)#LP +M($`.#PA1`&X/[_RI<`5^`>7E#521-0;OZ(0H"0_/<(``W#PP($$.SW"` +M`-0O`(#@?R1XX'@`V@/P`>(?"E4!A"H)#\]S@``H.S`C0P[M",&``=A`H0+P +M`-C@?N!X\)/>ND*$H$Y!<_I\<`(!X +MA"@)#\]P@`!\/"]R3&``V`/P`>`/>!D(`P,`(H,/@`"`/!9[8(OO"<&``_#_ +MV.!^\<`2#,_I"'4H=@#?`O`!YRL/%1&$+PD?SW"``"@[,"!`#HC@S"`B@?/U +MO@SO_^EPWPT!D."F`=@"\`#8003/Z?'`U@OOZ0AQA"@)#R]V`":-'X``(#L" +MA87@S"#B@/'`=@OOZ0ARA"H)#\]P@``H +M.R]UH&`H=H7@S"#B@/'`J@K/Z4H.[_T(=H#@RB"!#P``"32,#"'JRB&!`_7)SWT0($`# +M]1H8L`H-+_NI:EPR7#_V=(-+_,!V@;8(@OO_:EQ@.#* +M(((/``![,$@,(NK*(4(#N0+/Z>!X\<`Z"L_I"'8'\*EPE@EO_^EQ$"9.$RKN +M+RB!`TX@C0<4;19X`""0#X``H$@<$``@;^@*"@_SXH`&"B_S+!`` +M(`':`H`0=\!ZP@WO_:EPV^B`X@'9P'FI<.ER\@IO_P#;U_$Y`L_IBB$)#RQX +MSW*``"@[,")`#H7@S"#B@0[TR\D!VL00```L>`#9`"&`?X``@#U4J#"HX'[@ +M>(0H"0\`(8-_@`"@/(^##R1,$(^C!XV'`"N$-P^Q``AHJ`('S(<`ASA"L)#\]P@``H.S`@0`Z( +MX-P`(0'*(,$`\LD1(,"`P'C/($(`=`?B"\HAX@?@?O'`X<6AP0AUA.#*((8/ +M```'-%P*)NK*(48#BW%&#.__J7`0Z`#`SW&``"@[A"@)#S`A00Z(X;@((0'* +M(4$#"O#/<(``0-ZU>``8@`\(*'(9G0#OZ:'`X'CQP`#8\AH8L/,:&+#T&ABP +M$-C"">__]1H8L*8*#_O/<(``G+%J#*_NBB$2`-'`X'[QP.'%"'4H@4:Q9XSW&``+Q'.&`@@`\-0!`$@`L-`!!(<`SPA"L)#\]P@`"5/3(@ +M0`Z`X`#8RB!B`"$`S^D`V0\A`0#TR>!_)'@`V0\A`0#SR>!_)'CQP.'%5@OO +M_0AU%>@4;19XSW&``-Q'`&$-Z*X/S_*$+0D?`"&!?X``F#T`J3((+_BI<-4' +MC^G@>/'`2@^/Z?X(X`D(=SIPA"\)'P#>`"&-?X``(#T`(8!_@`!@/(0H"0\`(8%_@``@/2@9@`__#___+!F`#_\/__\`VEL9@@"$ +M*`(*SW&@```@.X'/@X'\FH.!X&0:/_?'`!@Z/Z2AU`-Z%X,P@HH+*)F$0 +MBN[/<8``H$<#@1`@0`-2#F`%`Z&I<$8-;__)<44&C^GQP,X-C^D(=RAUA"D) +M#\]P@```/3(@3@Y2#Z_\*'"`X,H@0@/(#R+WRB&"`^EPH@_O_ZEQ!0:/Z?'` +MC@V/Z3IP*':$*0D/`"&0?X``(#MO$`TF4A``)@9]#/`O*$$#3B"/!^]_R7"* +M#R_WZ7$0)T`V%(8&"!U&!@@*G!*""``R7&E!8_I\#.`+']FI(D`(``H +M<.!XSW*``*!'`X(0($``;05@!0.BX'C/`#8 +M#?"*(O\/SW&``/Q-%GE`H0#:0:$!X`]X[0@2@>!^\<#AQ78/K_\$V,]Q@`!( +M1038M@Y@`P+:T@Q@!038SW"``*!'HX`>#*__KW@`%J7`-!8_IX'CV$@&V +M#R$!`/8:6+`)!Z_R!=C@>/'`\@VO\@78H@EO__;)`-CV&ABPT<#@?O'`A@I/ +M_6LF0'D`````U@Z/_1H.#_T^#N_I/=C1P.!^&0@1`0#9SW"``&P,*:`!V<]P +MH```$"F@X'[@>/'`(@R/Z5\(D0#N#V_R`=C>""`'"'?/L]Q@0`8,L2)SW6!`+@R.0[4$(/JT.`8]*EP@B#"!H8/+_Q`(P$# +M=!6"$"MN627`%$(+(`GIO+/<(``/`P>B,]U@0"X+@#>30C?`6(-K_S)<2(-K_P:EP-8TP<,H@`@34"&+]RB'"`P#($0B>`$`5`!$B +M#F``"G'4K0`:F#--<(8@_`.,(`.`"?).``D`C"`"@"ORC"`"B#STX@S`##KH +MSW!$``SR`("TZ,]P10`T.!F(SW*``/SY-0@>`,]Q@`"<"\H1@``I")``#X$A +M")\&`-F1N0WPC"`#A.#H6\#X/3_(4\`C90!I"`"BY01I"`"BY +M0AI"`"BY0QI"`$(/(`X!V(8.X`P(V!$#C^GQP.'%"'4/#1(0$PV$'X`````& +MV(H,[^F,N`B]`-D$\`'AO'V,)0B0?/8(N<]P@```3?4@0`,T>3A@$.#I`J_I +M);C@>,]R@``DWB"2)7C@?P"RX'C/<(``:-@I`,`*X'CQP$H*C^D*)@"0SW"` +M`&RW0(`']`'87@H@``#9-O!M#AX0`-D*\,]P@```+O`@0``5(DP``*0!X>\) +M%($`W0?P`-@R"B``Z7$!Y:#M`-\/)T\3$P]0$(H@A`SN"^_IZ7$2\,]R@``` +M+@""*+A#@E,@P0!!*@`#P+@%>$,X,K_T!V`SH +MT@JO_`'8^@Y/^X'@(`OAZJ +M#V_S(*#Q`8_IX'CQP.'%C@]O\PAU$PU0$(H@A`QJ"^_IJ7$C\*O9SW"```!1 +M(*`AH"*@SW&@```@6X%,$0"&$'@:8@W;"/!,$0"&8;L0>!IBX'CU"U.`4R+` +M`,@:&+!!*@`"P;C)&ABPG0&/Z>!X\<`>":_I"'*CP0';$PA0`(H@A`P""^_I +M2'$`VDCP`-J)Z`:Y!7G/<(```%$KJ$APX0"OZ:/`\H*#/ +M<(``:-CV#8`*A0"/Z>!X\<#AQ0AU!=K/<(``M5%`J,]P@``HOR"@SW"``(38 +MS@V`"H'ERB""#P``,@'@">+IRB%"`UD`C^GQP,]R@`!HMV""!^O/T""T<#@?N!X\<"Z#T_ISW6``+11`(V,Z,]Q```/__X*8`@`V%H-[_\`V'[P +M=@G@!P+8D>@`C<]R@`!HV&&X`*T&@@2`(("`(8(%J@V@"DAP:O``W4X+8`BI +M<,]R@``DP"""SW:``"#>`*87"5$`SW&``,0;(($%Z8&X`*:@H@H@@"^````N +M`-\%\/`AP`,`I0'G(0_5$<]P@`#$&R1H`(`5(,TC\^@`V"X)8`CIJ"F[09/Z?'`=@Y/Z<]W@``DW@"7!^C/=8``M5$` +MC8/H`-A)\#8(X`"&`(084!V`+94@A@"$*%Y@E@ +M"`'8"';/<0``#_]."6`(`=@>"V`,!-@@EP'8Q7G>"6`("+D`V)JXU]FI<@3; +M"@[@"THDP`&>#Z`'`=@!V#(/S_\Q!D_IX'A)!\__\<#AQ<]Q@`"@1R6!`=B' +M"1\`SW6``)P+()6*(@P`1'F,(0B`-/3/<(``L!L`@`?H!87R"*_])H6LZ`#9 +M`O`!X1\)E0`3:15XQW"``!!1:(!#A>\+@8!2D`B5YPH!@#4)E0`"E4.5`[E' +M>$25-7E'>$$H`@)'>`]Z([K'D0@`0%%>88@ +M_PT%('Z``-X/],]P@`""&_M`-BD%P`0#R!``Z0?`!#"#^``J7``)H$? +M10"X+`"IS01/Z=-MU7X`)H$?10"4+"H(;^T`V.[Q\<#AQ<]Q10!@(R"!4R&^ +M@#CRSW&``(RK((EI"=``SW-%`!0A4(M="A\`SW%%`!0M*8%3(0P`1"&-`(5] +M1"$,`:5\AB'_#04A/H,<\F&X-0A5`3,F`'"``+SC0">!MDT#3^G@>/'`"@VO^^'%SW"``%18`(`5"%X`SW6` +M`"CA=@RO^ZEP`-@!I0H(``!%`T_I\<#AQ<]P@`!46`&``=TC"%X`SW*``)11 +M!H($@""`QW$#`)#0S@B@"DAPJ7`"\`#8$0-/Z?'`H@X/[@#8T<#@?GD$K^D_ +MV.!X\0!Y`=@#\`#8@>#`?2?T0"4"$PG8`-FF#"`($=L) +MV`#9&@X@"(^YSW:@```@NX;'=0```%`'\.H-(`@)V!,(WP,[AC!U]`?/_P#= +M`O`!W0G8`-E`(C[G/<```556`Y5$";^G*(,$#X'CQP-8)3^D$(K[O"`@( +M",]W@`"<"PWTOA>`$,]QH`"`)!BX@K@2H0^'L[@/ISSPSW6!`*PW`(7/=H`` +M7`S"N`#9&G$KKL]Q@`#DZ2F)"JXLKA#:SW&@`(`<6Z&"X,H@(@YL"Z+ISR`B +M`PJ.SW&``%#Q)H$(N"5XOA>!$!BY)7C/<:``@"02H0+8SW&@```8&:$$A0*A +M`X4"H0*%`J$!A0*A&!D`!)D!3^GQP.'%&@CO^@#=SW&``'A4((%"""``(('F +M#X_Z!>@N#*_Z`=T2\/H/C_J`X`+8#?3/<*```#P'@`CHSW"``$@5`("$Z`/8 +M"'5E`6_IJ7#@>!+ISW)`````*+HHN5EASW.@```\8;D%Z%"C,:/@?DNC+*/@ +M?N!^X'C/<(``T%$`@"#HSW"``,Q1`(`%V16Y&.C/B`=@`HF>B`Z+/<*#^``,$H=/)"Z'@?N!XX'[@>,]RH``` +M/`#9-*(@@#2B(8`AHB*`)J*$N2:B`X`"H@*"@K@"H@'8`Z(`HN!^\R@O@`D/`B^C/<:```#P`@07HP*&: +M#0`,S@D/^P/!,PF1`,]P@`"(%`"`)PA1`,]P@`!X5`"`((`#V`VX"2$``.8( +M;^D#V9^X0,`$V$'`"O``VPGI`,"?N$#`!MA!P`#80L`!VX'C4`_A_\H@00,$ +MZP/`!PC0``#8SW&``,Q1`*%H/'` +MA@\/Z<]RH```/"""`=W/<(``T%$@H#SI!=L5NPN#TQH8L,]P@`#,40"`,NA5 +M"-$`SW6@``!&B(7/<:``@$8`$00`S8(@'8`?/S\"/PXF@!\``$``BB9$$,"A +MSW:@_B`#Q;C$HP#?!O`0&X`/K0O^R@'G'7[W#X23B*4`&0`!`-@`HHX,``P* +M)0"00`[!_V$'+^FI<.!X\<#AQ1'P)(7/<```F2'>"(_I"_`V"V_I!MC/<*`` +M@"`7@.3@\??/=:```#P$A>D('H`Y!P_IX'C@?N!X"'$`V`AS"/!2:T-RW!(" +MA@'C17CU"Y2!`-J>NCEZ1'A"(`"`X'_*(&(`X'C/,]P@`#441C9\0:@!XHBEP_/<:```"`0H0'8!QD8@!#8`*'@?@+A +M,'E!:0T*!0`B>!!X`_`"V,]QH```(!"A`=@'&1B`$-@`H>!^X'CQP%#:SW.@ +M```@0:,`VE"C`B!"`%"C`=H'&YB`0-I`HP0@OL\``@`0L`_!_]'`X'X.Z`+( +MSW*@```G$'$!V,!X`KB!N`"BX'\!&E@PSW&@```@$8$9"!0&U.!*]P#8$:$7 +MV!&A`M@'&1B`X'[@?N!X`-@!&A@PSW"``!P,%)#/1&" +M$'@((0$`,'D"V`<:&(`QHN!^`N$P>4%I#0H%`")X$'@#\`+8SW&@```@$:&* +M(!@(`*$"V`<9&(#@?O'`,@T/Z0AU*';.#2__*'`*N"?MSW2@```@R!0"$`J] +MSW.``!P,-Y-0>EEA5).$+@D?NF)BN@@B0@`B>@D@@0`"V`<<&)`QI``A@'^` +M`"`[)H`.D#"Y$+@E>`(:&#!%!0_IX'B!!2`(`=C@>/'`N@P/Z3IPSW"``$@5 +M`(`:<23HSW9%`*`KL8X`WP/P`><0CC4/!1`3;Q5XSW)%`.`C6&!`(`,(!A.% +M`"1H!Q.$`$2+`8AEBY8*(`$*)D`$:.@`&,`C`_``W<4$+^FI/$%(`@!V.!X\<#AQ<]P@`!(%0"`$^C/=44`2#3/<$0`*,1`)0$4 +MV@F@",C:SW%$`$R4`($`I0&!`:5I!`_IX'CQP,]Q@`!(%2"!@.',("*`"/+/ +M<$0`#/(`@(#@,`O!^M'`X'[QP,8+#^FT:``EC!]$`"C$SW5$`$R4$0@5","% +M#R8.$,"E"/#!A4(@``@/)@X0P:7J#6`(B7`!!`_IX'CQP((++^F*(A``SW&@ +M```@X!F`#P,`0`T`W<]WH```'*JG"B"`+X``<#(`$``@SW:``/Q3SW,#`$`- +MH*8'Z-P9P``"V$*A`*8#\$.AJ7#/<8``=#(@@1+ISW`$`.B:9+@2I\]P@`!$ +M`,]Q@`!("+H*S_H`AD4@``,(.'$_!S(OOP<2+[AP.'!X<+AP_P<"+'\'$BQ_!R(L?P`-P3`R#/<*#^```#V48*[_I`AA$6@"`G"%X`SW&@`(![$H$*`'8RB8B$U3T`(8?")$`3"``H,!^ +M!?2V#H_["':`YLHF(1U%\@'81/`9"!X`)@QO_"#8'@QO_(H@"`!FWCGP[+C* +M)H(?``!Q`#/TP.`J\@WV20@0`4D($`)5"!$$1M[/<(``<"B@@"/PC"`(@!SR +M!O:,(`2`'/14WAOP+0B`#P```"`I"($/"````,]PH```3;"`7=X-\(;>"_`\ +MW@GP3-X'\&7>!?!HW@/PA-X`V('@Z`Z!!0H(3_LZ%P"6R7``V00B0B22"F_I +MJ7/1P,'$:R3`$,'$:R2`$,'$GW0$%!8T!!05-`04%#0$%!,T!!02-`04$30$ +M%!`TP`AQP0$@"`C8\`D$HP@#!NF%J02A"!,&Z>F(VN,&XSW.``)SQ"&,6 +M\!,('@?/<*8```0:@,*X06@+\"#"!""`#P(```!$NL&Z`>(QN!AZ`-B(XLHB +M+0`&]\]S@`"<\4IC&F*`X0'9P'D@V#5X57C@?Z'`X'BAP?P<"+3QP$+`!""0 +M#P```!A!*-`B%PA>`\]P'$?'<04I/@`*(,`.`_!!*8```L$-"1X"4R&"`".Y +M!O!3(<(`(L%$N4`H@R!U>U1[SW*``-3N/'`X<7/<(``5%0`B!D(4`#/=8``3#`R#N_\`(4` +M'8`?K:O^R@$'S^CQP(8.S^C/<(``5%0`B"AU&0A0`,]V@`!,,`8.[_P`A@`> +M@!^MJ_[*SW"``&!4`(`/'`$@[/Z`F" +MSW&``%14`*$/>*'!+0A1``'80,#/#<_HHL$H=@L*4`!O"YX!`-A`P,]U1`!X +MNP2%0"4!%D'`0HV+#&`&"=I"C0G8`-D2":_Q#R&!`,]P +M@`!T)\"@SW"``%14`(@G"%``SW$"`"#CSW"``)3;`-I(<[H-K_Q*)(`!SW&` +M`$PP`*&5!>_HHL"$*`D/`=D`(8)_@`"T.V4$K_X@HO'`X<6J"^_M"'4.""`` +MJ7!Q!<_HA"@)#P#9`"&"?X``M#M9`:_^(**$*`D/SW"``+0[X'\P($`.=0/O +M[8APX'C_VL]Q@`"@1\T'[_]"H>!XA"@)#X#:`"&!?X``)CQY!>_M0*GQP)(, +MS^@:<,]Q@0!D1N1I5B%3`E4AS08`WHHA"2\*(H`O@`"@.T`B`R^*ZBIQ"G`L +M>#`C00Z`X?0.`@`@EP`AP`0:\&"-C"-#AT&-$O1BC=#C$/1CC>_C#/1DC8PC +M@H8(]&6-#0M1`KYB`N8")LX4`N)=9=$-!)"`YLHF01`$*'XD`")1+A41C2!6 +M(4`"`N6X8(P@"X3*((T/```$,@@.+>G*(DT#0)<`)L`4$0ZE$!IP`"!!([() +M8`C">D`A`"4*/'`@@OOZ`#9KL%2#>_[2'<(=K1H"B"`+X``Q$>V?1_OBW'I +M<'8(8`@HVHK!B\*B#>`(R7`P($`C3<#)<+H/+_XD%X$0SW"``#PP`!B`#ZVK +M_LK:"R_NR7`'\(MPG@^O[3C9DMA)P(MP.-G6"V`'D-J$+@D?`"&-?X``(#P/ +MC6&X#ZT`A1<(D0`^"H_RA^@/C8#@@`WA\(0H"0_/ +M/'`#@K/Z!(*+_(:<,2(SW>``-Q'`@HO +M\@IP)A"``+1NMGT7"-`''P@0""<(D0@`V+]G`*<-\`#8G@_O_@\@@`,'\!8. +M[__)<(#@'`D!"RD"S^C@>+T!+^X!V>!X\<#AQ?8-[_\(=0OHA"T)'\]P@``F +M/'8((`LR($`.SW"@```=-!B`#P```"#N"R_ZJ7`!`L_HX'CQP'()S^@(=RAV +M&G*&"V`(*'`ZB+[80O"1_/<(``)CP*""`+,B!`#@/P@@@`"TPA`*#,("*@+O*$+PD? +M+W4`)8`?@``F/,"H*@OO^^EPC"#_CP]Y`-X(\IH*[_LH<(#@RB9B$`HA@(/I +M<,HA8@`!X;8/K^T!V@`E@!^``!0]`!B`!,X-K_[I<.EP,@SO_@'9&0'/Z/'` +MN@C/Z`AU_@SO_SIQ$.CRR1$@0(.*(`D/"O(,?<]P@``F/'(/X`HR($`.A"T) +M'P`ACG^``"`[;Q8`%@H@0"ZZZ!1M%G@`((\/@`"\1P"'@.#*(($/```1,LHA +M001H"B'IRB)!`P"&_]G&"R_R`=KI<,8,K^V0V0#?0![8$X#8`""!+X``)CP` +MJ:EPF@OO_NEQ"B"`+X``/##&#Z_\`!``(``8@"^MJ_[*?1[8$[()K_ZI<&D` +MS^CQP`X([^BH<"AU1"(!`T,)$0(?Z--MU7['=H``[,DI"AX#/@_`"@"&A2`& +M``"F!Y:`X,H@(0#/($$#,`_A"LHAX0<'\`"&"PC>`:>X`*8Q`,_HX'CR$@.V +M$2,`@,!XSR!"`*`&X@K*(8(`$VD5>,]R@`#\R1!BX;B,`.+MRB!"`.!^X'CQ +MP(H/C^@(=7()(``H=L]Q@`!/'`J@Z/Z*+!"'<:_MJ7`MZ(0M"1\`(8Y_@``@.R.&`8='"0``-&TV><]P@`"\1X(.[_$@ +M8#R&SW*@```@"KE;@L*``_`^9M%R_`?/_T)^BW*!PZEPV@C@""&'J7``P0'" +M/@D@"LES#!`!(`P1`B!0</'`R@V/Z`H.[_$( +M=PAUA"\)'P`ACG^``"`[`!`!V$0>&!#DY6;`(@ +MD(/*((0/```#,LHA1`,P#^3HRB*$`Q$(4B``(D$CV&$R"B`("G(`E\]Q@`!< +MV\)X`+<%@80I"2_">`6A`-D`(8!_@`#<.TD%K^@@H.!X\<#&#(_H&G+J#._Q +M\!S(L.2("':$+PD?+W``((T/@``@/``5&1``(),/@``@.P`@D@^``*`[`;"#0">!H` +M(`#8>!H`(`'8!O``V'@:`"``V(#@RB(A("?RZ7`$V;(*K^T`VHPE`:DBAECW +M+R#"!00@A`\``/S_*G":">__0"^"(@(@0`0JN``@`@'I<"IQ`-O*#*_M2B3` +M`$HB0"!""._Q2G`($P`@&P@1`NEP*G%*"<`*"^B.">`*!HW/<(``?%0@@`2)@+@$J<$"K^BDP/'`D@J/ +MZ`AUSW:``#PP+@JO_`"&`!Z`'ZVK_LI4;59ZSW&``+Q'*'``()``A"T)'R]W +M`">.'X``(#M`8<=W@``@/`87DA#/<8``-"U$CSIQ0*$'Z$X*S_$B@`090"`* +M<+(.;^V0V54F0!FJ#F_M[-F$+0(:`"&`?X``X$KZ#X`)!A^"%&\6`!9V">`* +M']EF"<`*`-A=`J_H`*?@>,]Q@`!`'`"APKC/<:<`@$D0H>!^SW)$`(#V"&+@ +M?P"ISW%$`(#V"&$+")(`''@!X`]XX'[QP-()C^@Z#0``@>`!V,!XSW&``(RK +M&@FO\Z")"''/<(``5*`6D)OHC@\OZJEP"B8`D!;R`KW/<(``IJ"T?;!@'0A1 +M`W8*[^@#V`KHO@HO^@/8%@QO\P/8`O`!WN4!K^C)<.!X\?,)^*2S"?BG`/T`-@*(P"@"12","'R`<"$*`$,`"&!?X``3!=L +MB0`A@'^``.P6`[L`+\P0:("'>VB@;(D!X\&[;*D#NWAZ:(!G>DB@#(D!X,&X +M#*D0%A`@"124,&*]B0TD%4`G5R`")0T5T77*)BX0`"2`(PIQ:G+)`(<,Z$`M`A0`V):X +MSW&@_I@(-@RO_04BP@7)<+D';^BCP/'`X<6N#N_Y"'6B#N`&J7#Q!T_H=0*'!\&!#/<(``C*OC +MH(PEPY_/=D4`O"UL'@`4!?0Z"P``':8"\+VF"-Q?!T_HX'@`V0KPSW"``%2I +M-GA%@`2``>%`H,]P@`!4J'80``;I"02`SW&``+2XSW"``#"J#07@!P3:H<%` +MP`(4@3`!%(`P#>D#%((P4"*!``*Y`N'BNL(@0@#`($$`#WC@?Z'`X'CQP!D( +M,P$(<80I`0//<$4`>"TR($`.B.CK/'`X<4(=0]XA"@!`P`A@']%`#PM/!"!`$Z`!.D1#8`0SW````X) +M.@COZ*EQJ7#Z#:_]`=FA!D_H[06O_0+9X'CQP!H.3^@(=EH)(``/>"EH+WI% +MNL]U@`#4+U5]0H7$N0#?#R=/$$M_!O(N"T_U`H7F>`*ER7"R#:_]`]E)!D_H +M!0```/'`]@OO_P]X:@Q/\]'`X'[/<8``5%@G@87H02D``L&X!/`JN5,A0`#@ +M?N!XSW"``%18(X`!V/2YPB`!`/6YSR!B`.!^\<"6#4_HSW"``(RKH(C."R`` +MJ7`>Z*(,(```W@T-T1`V"```"0A0`,EP`_`!V(#@L`TA\\H@00,_]F@@O +M\*EP"@I``_X(+_\!V$H,``"U!4_HSW"``(RKX'\#@.!X\<#AQ9X.[_\(=80M +M`1,`(8!_10`\+3T0@0`(X$0I/@>-!6_H,B!`#H[@`=C@?\(@"0#@>/'`X<5J +M#N__"'6$+0$3`"&`?T4`/"T]$($`"N!$*3X'605OZ#(@0`[QP.'%0@[O_PAU +MA"T!$\]P10![+3T%;^@R($`.\<#AQ28.[_\(=80M`1,`(8!_10`\+3T0@0`) +MX$0I/@<5!6_H,B!`#O'`X<7/=8``C*OZ#>__`(T!A?T$;^@(B/'`X<7/=8`` +MC*OB#>__`(T!A>4$;^@*B/'`X<7/=8``C*O*#>__`(T`C80H`0//<$4`>RW! +M!&_H,B!`#O'`X<7/=8``C*NF#>__`(T!A:D$;^@)B/'`X<7/=8``C*N.#>__ +M`(T!A9$$;^@+B/'`X<7/=8``C*MV#>__`(T!A7D$;^@$@/'`X<5B#>__"'6$ +M+0$3`"&!?T4`/"TH<#X1@0!$*3X'401OZ"=PX'CQP,]R@``@WP""SW.``.3? +M$.@6#L__SW&``/3G"6$;>$`IC`*%>`RY!7D@HP#8`*(`@]'`X'[@>/'`C@M/ +MZ!IPSW6``(RK^@SO_P"-`84!W@J("B&`+Z```""!X,!^VW[F"V_]#]@^&9BC +MU@[/_\]VI```1,]W@0"(-AT(40#*"V_]#]@9AH"X&:8!C\H,+_(`KPSPL@MO +M_0W8&8:@N!FF`H^Z#"_R`*^J"P_N3!F8KP``554!V$L9&*"&#.__`(U!A80H +M`2//<44`="TP(4`.;@\@`R2"SW"``$BZ!HB#X`'80@PO\,!X8@EO\0IP`84& +M@/^XC`H!_!(,#^XM`T_H\<#2"0```-D+\(0I`0,`V@'A`"&`?T4`7"U`4```#QP)8/H`'AQ7H*P`+B"B``#]A^#6_Z"'7N"4_ZSW"` +M`%2"+8!N@$\A`@2!XPN`RB&"`)?HSW*B```(!H*$N`:B!H*#N`:BBB(0`,]P +MH@``N$J@`1A8@`#9"!A8@"SP'0@>``/;SW*M```$?:+/C/#._P`]@`V1<(T`#/ +M<(``0!4`B(#@RB!!``+R`=C1P.!^&0@S`0#9A"@!`\]P10!X+3(@0`X)"%`` +M*'`#\`'8X'[/<8``C*L@B8PAPX\`V`SRA"D!`\]Q10!X+3(A00Z!X,]P@`",JP#9(Z#/ +M<$4`7"X@J".H`8A$*#X'`"&`?T4`("YY!2_M'-G_V,]Q@`",JP"I`-C@?P&A +M\/'` +MA"@!`P`A@W]%`%PM/8L`(8!_10`\+40I/@<(X+X)[_\P($`.'ZO1P.!^\ +M"$_HK@[O_PAWA"\!$R]U`"6.'T4`7"T*(8`O10`\+8GHSW````0)Z7%""J_H +M7([/<(``C*L]CAIP7H[@J!S86G`A"8``#'K//'`U@XOZ`AR +M&G$`W<]VH```$*FF`=_I<,8*X`("V;AP+R('!,]P@`!46`H0A`"I<`+9O@BO +M[ZES`]G/<*T``(`JH*W8$+BKH``8@`\``!$0Y@IOZ`;8X@IOZ`;8Z:;A!@_H +MX'CQP'8.#^@(=<]WH```(-N'@^#*(($/```N,%`(@>CR#J__J7"6#P`%&X<- +M"(0#`B"!`P?P#B:!'_____\981)M0W`,&%@`G08OZ!`:6##@>/'`X<4Z"N`* +M"'5V#>_]J7"1!@_H!0```/'`A"@)#\]Q@``@.S`A0`X1V;H(K_``VL]QH``` +M(#N!(J``@%H+;_$`V7((;_$,V-'`X'[QP&>`!X&(!`A`0#"#N_M(Z4%?B.%].F`YA`*8O'*(&(` +MW04/Z/'`-V@T><=Q@`"`V'`A"@)#\]P@```/3(@0`X( +MV4#`BW#R#:`&>-JBP-'`X'[@>/'`X<7/=8``:+8@A09Y(*4>#.`**'``A8?H +MS/'`X<7/=8``3% +M`6%O,A*,`,*M8ZTEE0CP,1*,`&%NF!$!`6*MXZTDM0#9/PSE$".ESW&``*S/ +M&PC>`1"!#!V`'T$`@P`!X!"ASW!!`(,`"_`1@0P=@!\A`((``>`1H<]P(0"" +M`(T##^AB#^`!$(H(<@1M9@TO^\L2`;8`V`P=@!\`(```G;CO\>!X\<#V"B_H +M"-D(=PH@@"]$`)"17@_O[`IPSW5$`)B1J7!.#^_L@-G/;A$H0`Q0X$D0#1+#`41$VS/ +M<8$`P"\5>`%A!"&!#_@!``!!*<&$[?,O*T$`3B.`!P]X`-X/)@X0SW.```SS +MSF,6)0,3X(,0(0&`Y7[`H^[UW/'/<8$`."\$D0?H"@K@`%8B0`07\!J1!NC^ +M">``52)`"Q'P!9(`$`(@!!`!(("ZY+C%(:($SR$A``IP(:!`H`#840(/Z.!X +M\<#6"0_H"'=:<3IR&G.(=:AV1@VO_PHC@"&$Y;A%8`0SW&!`)@O.PX%$!-N%7@9806)Z0\! +MD,]P1`"8D=9X08`+(D"$[/,`@`L@`(3H\T`A``)*<08.[^SI_LBB$&"N!XB.C/@."`>`#HN!^X'CQP/X(+^@0VK'!"'4`WA#@_@U@!XMQ0"4`&(3!\@U@!Q#: +M0"4`$XC!Y@U@!Q#:0"6`$T`DP3C:#6`'$-I`)0``!V<(A00`\V#9XBW$0\`(1`@5/>RBZ"+ME>EYF#0[>%]!Z +M,+Y>9F*X$'CE").`#0A2``")`_#0?AYF02X`E/SUTG@0>-$`+^BQP/'`6@@/ +MZ`AU`(@H=H8@_`/@X`#9"O0"E==P````&,P@@H\````@!/(H<"?P!HT?")$. +M$(Z,(,./"_)`)0`60"8!%-H,[^P0V@/H`-@5\""&`-B*Z2&&B.DBAH;I(X:` +MX,(`2`K<$P]`&770@1`@2/50B1`06/40@1`0.7C"`$@"+TSW&! +M`.`T`8$/Z$`G@Q.`DT*1`-@1#($089-#D5!SRB!A`!#H0"<#%H"31)$`V`\, +M@1!!DR61,'+*(&$`@>`!V`/R`-B#"!``0">`$\]U1`!,[T`E`1A>#&`'!-I` +M)P`20"6!%E(,8`<&VL]P@`"<"P&`SW%%`#@L#P@?``"!`>``H03P`8$!X`&A +MSW"``'C>((#/<(``6#N$*0D/,"!,#HMS"B2`#P,````(V"39J7)*)0``0"6& +M%AX,8`Q3)`<0`=@`I@#8`*9%!^_GK<#QP+H.S^<:<,]P@`"`5`"`*H`#D``@ +M40!"(0TB`]@FE0NX$'$!V<]P@``PW\!YNG`@H#`5@!",(,*!N<$$]#$5@!`' +MZ`#9`!A`(`'8I_!`)1(<5B03,P#>"B2`+X$`X#1`)`\F`_`!YA3G%!0`(#<. +M!1!`)0`>Z7$>"^_L$-KUZ``5`"`5"%``&!*`(-L(48`9$H`@TPA1@"2'`!M` +M(`'8`O``V(#@=_(8P`.X%7@`((X/@0#H-2IPQ@WO_\EQUP@0`#F5+W@HN0BX +M!2$/``X-[_^I<+\/`1!`)0`40(``V8GJ08"'ZD*`A>I#@(#BRB%A`,]W10!X +M(X3I8-DMIP?P(-@-I\]P@``8Y$`G`1C:"F`'$-HXY:EP0"!FWSW"` +M`'C>((#/<(``6#N$*0D/,"!,#HMS"B2`#P,`(`!@%`4P"-A0V>ER"B:`#X`` +ML`N&"F`,4R0'$`'9`!A`(`#8!?``V0`80"`H<'4%[^>YP/'`X<4`V<]P@`!D +M#R"HSW"``&4/(*C/<$0`&)(CB,]P@`!F#R"HN@[O\!'8`=G/<(``&-\@H,]U +M@`!$,)(,[_L`A0`=@!^MJ_[*907/Y^!X`=G/<(``_!3@?R2H\<"F#\__=@UO +M\`#8SW"``*#?((``V"H(K_`@@='`X'X"V<]P@`#\%.!_)*CQP,]P1``8D@"( +M*PA>``'9SW*``"0/SW"``$@5`(`@HH#@RB"!`,HB@0\``%0`-`U!!M'`X'[@ +M>/'`SW&``/P4`(&'Z,]P1``8D@.``*$`V*X+;_`HV<]Q@`"@WP"ASW$!`$0/ +MSW(!`!@/SW,!`*@.(@BO\`#8T<#@?N!X*'(/><]P@``<_2D&C_K@>/'`SW!$ +M`!B2`(@O"%X``-C/<8``)`\`H<]P@`!(%0"`@.#*($$`RB*!#P``5`"H#&$& +MRB%A`-'`X'[@>/'`Y@O/YPAV*'4`V,]Q@`#\%"H/[_\`HAP/'`X<7/=8``)!4`A1S9(*#/<(``@/7B#Z_L.-G/ +M<40`&)(1B4&%`+(0B8'@S""B@`3T`8*4N`&B$H$#HDP1`@'/<($`V#]6>$*( +M884#@PZZ17@#HTP1``$0JP+8,AL"``'8&K,0B8'@S""B@![:RB(B!A&)0J5" +M>`6E0"$`!5A@?0/OYP:EX'CQP/H*S^?/=D0`&)(PC@#=&PE0`!L)D``;"=`` +MSW````([U@P/Z*EQ!O`3V03P#MD"\`C9SW=$`#B2-@^O[$`F`!D$CSV/@+C! +MN0*Y)7@$K\]P@`!F#T"()(\4:B5X!*\>CR:/PK@E>`:O&-@'KPF/,(Y/((P! +M@>'*(`$#GX\/V\"\![R%>`FOSW"``&0/@(@J'@(3SW"``/P4`(`;"5$`*A:, +M$%,@S0##O`2]O&0J'@(31+@(\+R/P[S#O02]O&0J'@(3*QX"$!D)40`S'L(0 +M!M@U'@(0'(\T'H(0-AX"$,]PH```(+N`$(9"CH4H#PH\CR]P+'H""^_G+W&X +M8,]Q@``D%2&!80+OYPJA\<#V#L__SW!$`!B2`(@I"!X`SW$!`,@.SW"``"05 +M`-H`VU8*K_M*)(`!SW&``$0P`*$1\,]Q@`"DX""!SW*``%`1`-B>"V_P0(+/ +M<8``)-\`H='`X'[@>/'`X<7/<(``90\@B,]U1``8D@-M*6#/<(``9@\@J`#9 +MSW"``&0/\@WO_R"H$(7/<8``H-^%*`\*((%!*8!R!J'/<*```"`;@`*A!)4$ +M*(`/#P!`0D(I@'(%H0#8[@AO\`'9L0'/Y^!X\<`N"<_G"'?V"^__*';/=8`` +MH-\@A0#8?@QO\""!`-AB"&_P*-D`I>EP<@_O_\EQ:0'/Y_'`SW"``&PFH@H@ +M"@O9K@D``!(+``#1P.!^X'CQP,H([^G#/=Z```"`0IQ#8`*?/<($`-$G+&ABP!!^` +M'P`$```*(8`O@`!L)B@1`"`*)(`O``0``++!!^C/<8``!-\`@86X`*'"#:`* +MBB`/"@H@@"^``(RKH@[/ZJX*``"V#>_SBB`0`+8,+_(!V`OHSW:G`(!)L(8& +M":__`!"`(,*]L*::"0``!A<`EL\(7H4`'P`59@[/Z@G8,AH8,,]UH```"`\= +M&)"+OY[+`\<`Z#X_GSW"``(RKH(@&"F__J7#/ +M=X``5*`8%Q`0C@LO\@'8#.C/=J<`@$E`%A$0V@]O_ZEP4R&`(!"FSW:``&PF +M`(9?"!X`SW"``%18`8!+"-X`A"T6&<]Q@`"(:R]P`6&=Z2F'#.G'<(``U&H^ +M@`D)D0`#V3Z@'H"%Z/(,[_(`V.H*[_(`V`GH7@\O_ZEP=@^/\HH.[_(*<.(( +MK_-`)@`7_0:/Y^!X$-O/<:```"!AH0'8!QD8@,@1`@#/<(``;"8(@!!RPB"% +M`,H@)@`0H6"AX'Z*(`0`SW&@```@`:$4V!ZA`!F`#P``$!\$&9B/(`!_``<9 +MF(\!`,#\J0+/^P/:SW2@```(0J3/'*G)>#F`, +M"B3`!`AR$P@>!L]P``!>"S(/[^/'`5@R/YPAVY@_O_RAWC"#_CP'=`_2AIR;P!MB."R_P)]D@@,]R +M@`#<+2"G(*(CAF6&(:(FAB2B)(9CHB*B!-DB&$(`)X8BH"B&(Z`IAB:@+Y!% +M(<$`+[`&V+(++_"I<0#8`:==!(_G\<#N"X_GHH`H=J"A@.7*(($/```!0\P- +MP>=:#^__J7",(/^/!/0"V`&F&/``W^&F/@XO\`;8SW:``-PM$PB1`4&&!M@` +MV28);_`/(8$`!M@&#R_PJ7'@I@$$C^?QP'X+C^<(=0HD@"^``(!4`!0`(#IQ +M@.#*(($/``"[(60-P>?/<(``=-[`@(0I`B4$YB=VD1:!$`T)=01*(``@`-@] +M\$(A``0O(@@@+@\@#`IPL'U`)I,0%0VC%"#FJ7(*<0CP`N$"Y@+@!/!*<@IQ +M0PF%`$$IPP`R(\,@1"&,`9I[SW1$`#B*P;OT),,0@)#@EN=\:WSH\P`4`2!` +M(0`#(G``&`($(A&``&&X(AD"`,CQ4G4!V,(@"P`=`X_GX'CQP-(*K^>8<,]Q +M1`"0XMAQ0"$%`0#;`_`!XT\+!0$`%@``SW1$`$C'>&"$*`(%!+@?9``E30X` +MV@7PGF!5?B"F`>+["C2!`-G1"16"`(TZ>,"X$WHX9T"H08TZ>L"Z4WI(J`'A +M\O'9`H_GX'CQP.'%"'(/"%$`1@Q/\0AU`O``W<]S1`"X]!"+"0T!$$,)40"P +MJX#ES")A@`?T!-G/<*``@!TXH`KP@>7,(F&`!O0$V<]PH`"`'3F@5@E@`*EP +MK@SOZ*EP!@_OZ*EP$@]/\8$"K^>IF1H;/<40`>/1=H:8.;_$>H0H/S^B:"._XJ7"! +MX,H@80#*(2$`RB)!`"`)X?C*(P$`W0&/Y^!XSW!$`.C)+9#/``H023!"B`#P\`0$+/ +M<(``@.&=!B``+W'@>/'`X@J``0CH_@N@`0+8X@J@`0#8SW&``/SY01&``$`1 +M@@`(N`5Z0A&``!"X!7I#$8``&+@%>HPB$(`4\@7VC"((@`WR"?`C"H`/```` +M""$*@`\````0`-@,\(H@"``*\(H@$``&\`#8B[@$\`#8C+C/<8``M+<@@<]S +M10`X+"^CSW&``)RW((&,(@B`,*,`V\]Q@`"PMV"AS"*"CP````3,(H*/```` +M",PB@H\````0`_1&#,`*T<#@?N!XSW"``(#A-08``.!X`-G/<(``T-\@J,]P +M@`!DX1T&``#QP,]P@`!$XA(.``#/<8``M+<`@0'@`*'/<8``G+<`@0'@`*'/ +M<$0`*,LA@,]P@`"@MR"@T<#@?@38L0&@`0#9!]BI`:`!`-GQP.H/3^<(=EIQ +M&G+/=X``@%0`ASIS@.#*(($/``"^(=0)P>?PYLH@B0\``+\AT`GIY\HAB0,` +MAZ60#.6P?0L-510`V$#PB24"$$`J`"$6>``@E0^!`(1*0"63(`#8C@L@#)IP +M0"4!*'"]T77*)D43T'Z*<@3P`>(!X0'@1PJ%`Y+BP"`!!`7RIN+`($$$02K# +M`#(CS"!3(H,`>GS;#!Z0@(A@B00=/Y_'`-@]/YQIPSW:``(!4`-TA\,]S@0"42C1M5&W'J +M`>7##=20`(8G$(``KP@0``#?P@H@#.EP`(C/=8``J+?#N`*X=+@`I:H*(`P) +MV`"(+PB1`0"%SW&``+BW0"`"!4"AD@H@#"#@`(C/<8``O+>&(/P#1+@"N'2X +M`*$!WU\/41`@A@.1`N`#L0618K@%L0#?`_`!YSD/]1``AB3@Z&!ZZ$"%[WG/ +M"62,0A$`(HB$`#/<8``_/E`&8(`*+I!&8(`*+I"&8(`*+I# +M&8(`=@]@`0'8"-C<\8((H`$!V`"-`>``K0>.!"B`#P\`0$+/<(``9.'V"B`` +M+W'U!4_GX'CQP'X-3^?/=H``T=_/=40`J,@@C@2-,0D"`(HB"`#/<8``_/E` +M&8(`*+I!&8(`*+I"&8(`*+I#&8(``MC>#F`!`-D3\!8(H`$`V`".`>``K@:- +M!"B`#P\`0$+/<(``1.**"B``+W&)!4_GX'@!V*T&8`$`V?'`SW"``&#BS@H` +M``'9SW"``+"W(*#/<*```"`[@"]Y,GE`*0(&.X`O>1"Y>X!986]Z"+HHNV5Z +M4GI/>@BZ66%;@$]X"+@HND5X#W@98<]P@`"TMR"@`-A.#F`!"''1P.!^X'CQ +MP*(,;^<$VJ+!"'4H=@C@I@G@!HMQ`,'/=_\`_P`$(<`#*+D(N.1Y)7A#*``$ +M0,`$;8'!@@G@!@3:`<$$(<`#*+D(N.1Y)7A#*`($0<(+[D4.4!!Y#I`0<-@^ +M#J_GC;B9\,]Q@`"`)H8'PSW"``)RW`(`0` +M`/SY`>`.I$`?@A%!+@8"01^"$4$N!@)"'X(102X&`D,?@A'/<(``G`LX$`8` +M4!^"$4$N!@)1'X(102X&`E(?@A%!+@8"4Q^"$1$+@`#/<$0`Z,D-D%A@`*7/ +M<(``N+<`@,]R@`"\MT""%.`:8L]P@`"`5`"`!9!">(!P`*'>#&`!`=@+[B$. +M4!`A#I`0<-CZ#*_GC;@%\`/8F@Q@`0#980-OYZ+`!MCZ\0G8^/'AQ0#:`O`! +MXDD*U0`4:A9XQW"!`(1*-&K'<8$`5$H`W`;P`-L5(0T#8*4!Y/<,%)$`W-<, +M%9)@B)I[P+MS?9MAH*NAB)I]P+VS?:BK`>3S\>!_P<7/!X\<"""D_G@B0",`AW*'6+=LEPY@XO[(#9SW"``-SGR7%V#Z`&"-I`)X`3 +M@L%J#Z`&0B6"$^EPP@XO[*EQ3FW)<%8/H`;I<:D";^>`)`(PX'@)`(`(X<7A +MQL]Q@`"`5&"!`-Q#DR630",."%EA`GF#K@23B74%\$%M3WU#K@'@0FD?"@0` +M2H,*8HPBPX_U\PT-DQ&#K@#=]/$$LP'8`_`$LP#8@.`!V`?TSW"``%`5@*`` +MV,'&X'_!Q?'`Y@AO_`'8P@AO_`#8H@AO_`#8T<#@?L]R@`!,V`:"!(`@@,=Q +M#P!`0LT'8`A(A$`AD8@@`%Z&1B`K0%/Y_'`&@E/_`8)3_PB"4_\T<#@ +M?N!XSW"``$S8[09`".!XSW"``-3AX09`".!X\<#/4"A +MSW*``!0)`8)&(($%SW"@`(`?*Z`)BR&B!^C/<(``H-BJ#D`(T<#@?N!X\<#A +MQ1H+[_X(=3D('@#/<40`>/0<@8'@S"4AD`;T`-BN#^_Q'*$.\(#@S"5AD`KT +M`=@/'`&@AOYT`@`@-` +M(`\'`-D.\#B[PKO/=(``E/)L9,]S1`"0D:&#`>&E?(&C89`C"<4`\")#`%,C +MS`77=*P```_,)(*?\@``4.7S`=X"\`#>INX`W`3P@;I`I0'D(I!!#$40\"#!\)$0'/<40`"(0(84`H`@(%>D`H`01% +M>1BX)7@-\,]R1``(@/`B```$\$,H``)(<4EI3WK[Z>!^SW)$``B%\"(``",) +M$0$HN`]X0"@"`@5Z0"@!!$5Y&+@E>`CP0R@``DAQ26E/>OSIX'[@>/'`]@XO +MYP#8@B0".`SPSW%$`%SA"F$`(($/@0#T+$"I`>`/>,]U@`!Z,B"5XPA"@`#8 +M#?#/<40`/.$*80`@@0^!`-0L0*D!X`]XSW>``'@R()?E"$*`SW"``(!4`(!% +MD`#8:0HT##IPF@K@"XMQ@<:(P!IPE,&F"Z`&$-H*<`#9;@LO[!#:`A0!,8MR +M+W@HN0BX)7AD:&][5B0$,\]P@0#4++(,X`H@CRIQ!/`!X2]Y'0D3!``D0#!0 +M$((``"1`,&`0@`#I"@"``-B&\`*.(8X(N`5Y+W@HN0BX+WG@E04A$0`0Y^]_ +M0";`$IS!+@N@!A#:5B0!-,]P@0#T+!X+H`9`E8S`&G"!$&@(` +M*+A%&@(`*+A&&@(`*+A'&@(`&XX@C5IP`""3#X$`V$06(T`@1(C/=H``(+_L +M>B"&`=@G<0"Q((T6(T`@!(CL>""&"G`'X2=QD@J@!BIR0(T`AA<)42,6(X$@ +M)(GL>70@00Z,N2"P((T6(T`@1(CL>@"&="!"#D`J`2)%>2"P((T6(T`@)(CL +M>0"&="!!#H.Y(+`!V'T%+^>`)`(X\<`>#2_GN'`Z<1IR:@\@`"APSW:``'S> +M0(X`(9(O@0#81!8B@"`$B,]W@``@OR"'--VL>`3AJ'`G<08*H`80VD".0"D` +M(A8B@2!$B:QZ((0"'="!!#D4A@0(@L`#=#?!`($`O +MSW%$`/SAMGD,X<()H`8&V@'EKWWK#1*4]00/Y^!X\<"*#`_GHL$(=SIQ&G+: +M#B``*'#/=8``?-X@C0`ADR^!`-A$%B-`($2("B*`+X``(+\`$@$@--[,>@3A +MZ7`G<6X)H`80VD"-0"D`(A8C@2!$B!`$@T%B-`(`2(`-G,>``2`"`D'T(0)W`!P02G +M)J<$X`H@`"'((T6(T`@!(C,>``2`2`4X0>')W'.":`&!=H! +MP"6'`>!!P`2'"G($X+H+8`MHA[4#+^>BP.!X\<`^"P_G^G`*(8`O@`"`5``1 +M`"!%D./BQ@`E`((D!#T*(@`G`-@Z#Z`+2G&!QPHC`"<"CT&/"+@%>D]Y02H` +M`@BY#WTE?8D*W@($(;Z/````(X'#)O3`VD1X1'D%('Z`(/(^$X``/1.!``BX +M!7D_$X``$+@%>4`3@``8N`5YDNE"$X``01.!``BX!7E#$X``$+@%>403@``8 +MN`5Y`=@#Z0#8'^B*(@0`SW&``/SY0!F"`"BZ01F"`"BZ0AF"`"BZ0QF"`&X. +M8`I`V`OPSW"``$05`(`%Z!$/$2`-#9X1]0,@``#8BB`",.>]T24BDM$E8I+W +M\PD/$"#G#1Z37A>`$%T7@1`(N`5Y+W@HN0BX+WD%(18`"H\ICPBX!7D+CU,E +MA!`0N`5Y#(_/25X)H]ECPBY)7LGCQ"Y)7LH +MCQBY)7L$(X$`*+L(N61Z17E#*0($SW.``'PR(8-W"F2`0R@`!`T*00`@@V<) +M!8``HT&CSW&``/SYNG$D&0(`*+@E&0(`*+@F&0(`*+@G&0(`*!V"("BZ*1V" +M("BZ*AV"("BZ*QV"(!IW@"!!(TPD0(`*)(`O@0#4+%8D#C3,]`IP52;!%*8. +M8`80V@IP`-EN#N_K$-H"$P$A:G(O>"BY"+@E>`3@#WN*F#6`&RG*&)?\30BT1$:IP +M11""`$00@0`(ND5Y1A""`!"Z17E'$((`&+I%>0'A1!A"`"BY11A"`"BY1AA" +M`"BY1QA"`$`F`!ER#0X1**H+S_\$\!(+S__/<(``?-X`B`.X%7@`(($/ +M@``)R@`90@26"2``2G"*XIP$-G.#B`+0"8$'P#8 +M#/`99E`1@@`99CP1@0`P`/>.T($H0`$0(@`-A*<:8+H`M%DHMRSW"! +M`/0L8^)?#Q`@0B[!(&&Y,@X@"E8FPQ-X%H`0C"!#AQGU>1:`$&:X+R8(('H6 +M@!"`X`_U>Q:`$(_@"_5\%H`0C"`"BP?U?1:`$('@`_5^%HT05B0`.$`F`1=: +M#&`&RG+!O0OP0B[!(&&YU@T@"D`F`Q>&)?\31+VJ<$40@@!$$($`"+I%>480 +M@@`0ND5Y1Q""`!BZ17D!X4080@`HN4480@`HN4880@`HN4<80@!`)@`7J7'I +M<@L.$2A."L__`_"Z"<__SW"``'S>`(@#N!5X`""!#X``"``V1H+[^L(VJEP4>``V0X+[^L0VL]Q@`!\,F&!SW#_`/\`!","`"B[ +M"+H$>V5Z0RH#!&FM*+MJK2B[:ZTHNT"!;*T$(@$`*+H(N41X!7E#*0$$+:TH +MN2ZM*+DOK2BY`AV$'P```%])!N_F,*T(

_F +MF'#/<8``?-X`B<]R@0#81``DC0"3:!9]!(W_VR<(P0``V`/P`>`/>!L($P1$ +M*#X-SW:``""_P(8T)DX>]>X$K0#8%_`K"``!76#$;8YF'P[`$$0N/AW/=(`` +M(+^`A`#?)W3@M,")UGV3;F2M`>`/>-<($H&I!<_FX'C/`"R"?`3")X&&)0`LAJ4`;(;E`*R +M`-@`H\]R@`"`5"""&.G/<(``G`L.D%,@_H`+]$UP(((=")X"SW"``)P+#X`1 +M"-X&`-I"L078%;A%H.!^X'CQP.'%HL&+<%H/(`J!P8C@"'6`#L$`UW4``(B. +M#`N!"@#`AN@!P(#@O`V!\_H,C_,)!>_FHL#@>.'%X<;/=(``.`^`A&=Z%21, +M$<"$1'E#+@T2!"6-'P#_`/]#+@X6!":.'_\`_P#%?:"D9WFY8<=Q@EJ9>4,H +MP`8X8,'&X'_!Q?'`/@SOYF=Z0"5-`\]V@``X#\"&P[WP)D\30"4-`L.]\"9- +M$U,ES`#G?4`ECP##O_`FSQ-$>95^@(;G?:=\0RS,%X"F9WF98<=Q@EJ9>4,H +MP`99!._F.&#QP.8+[^9'>4`E30//=H``.`_`AL.]\"9-$T`E#P+#O_`FSQ-3 +M)`IIEAQW'9;J'K0RC`!@$$ +M[^8X8.!X\<"."^_F0RC`!D`E30//=H``.`_`AL.]\"9-$T`E#P+#O_`FSQ-3 +M)65YF6$"(8$/ +MY'`D0Z$#[^8X8.!X\<`N"^_F1WE`)4T#SW:``#@/P(;#O?`F31-`)0\"P[_P +M)L\34R7,`.=]0"6/`,._\";/$V=YE7Z`AN=]AWU#+53)7Z0PZ"@ +ML"CT@8"B@,=\@:!#+,X3QWVBH+QD@:`$)(X?`/\`_RB^!"2/'_\`_P`(O^5^ +MQWVBH+QD@:!#+$X7QWVBH+QD@:!#+(X0QWVBH+QD@:``W(.@`>-P>Y,+@H#% +M`L_F\"&@0J``V2"PX'\C +MH!/I88"%@(?K0X"%ZH"@(:`+\$"`>F(-#($0>6$AH`7P0X`Z8D.@`-DEH.!_ +M)J#@>$"`(8`$@%EAX'\B>$*`(X``@%EAX'\B>$&``-F#Z@.``^@H<`+P`=C@ +M?N!X08`7"80`(H`@H".`(:``V2.@(J`&\")Z0:!`@%EA(*#@?N!X\<#AQ0AU +M`X`H%6&`4\(8/S_\@ +MA1,(1`!QZ'!PRB,%`&:E087P\0#8!ND-"<0`!:4'A6:EI0'/YAD"``#QP'8) +MS_C/<*```!T8&(`/_P_W_P'9SW"@```(.:#/<```F!Z*(;\(_@QOZ@#:T<#@ +M?N!X\<"BP<]PH```,'2`SW(``"3TBW&!P`4KO@``&,`.`!E`#@#!`<`KN16X +M!7G/<*```#`6@#A@HL#1P.!^\<"J",_F&G#/<(``6!4`@"AU.G((Z`#8SW&@ +M_M@""@WO^Y:X%,B"Y0'@%!H8,`'8_@]@`,!XG@I``$()S_O2#._F#-A"#$`` +M@."1\L]WH```?`"'SW:``%@L!""`#P#````^N`"F%@]@!0IP$PB0`"*'#PG? +M!S&'+R9(\!+R0(8'V`JXP-D8N2X,;^H>NL]QH```'A>!C;B2N!>A!-B!\)/H +MSW"``(2V`(#/<:```!Z#X!>!T""A!-`@8@/0(*($%Z$!V0[P)0A1`,]QH``` +M'A>!C;B2N!>ASW"``!PN((#/<(``G!0@H"8.```B#._F!MB6"T``@.#*)B$0 +M!_+"#Z_[`=X*#._F!M@4[GH+0``0Z"IPJ7&J"R``"G(*Z,]QH```'A>!C;B2 +MN!>A`-@W\(#FR`^"^\]RH```()@2`(:7$@&&)7@2>>K)'0@>!L]SH`"`'`0; +M@`_%[H*Q&X*>N0&C(:.Z#P``&/#/Z"L1N#G[D!HB&B!-@5&A@P<0>/YN!XSW&@```>%8&AN!6A +M:0%``/'``@^/YL]P@`"0M@8/8`D`@,]UH```,#`=@!\`@```]@E``(H-C_#/ +M<(``9+;`@`3N4@L```KPSW"@`(`<&H`V#Z_[12#``W((;_C)<`'9SW"@```0 +M*:#/<(``2!4`@(;H!14`EH"X!1T8D$8.0``!!X_F\<"&#H_F&G#^#F_]`-_/ +M<(``A+8`@`'9@>#`>8'@S"`B@2/T&>G/=:```#00A48@P`-%(,``$*7I=@OP +M\84!Y@0GCQ\```"`G@KOY@;8A>^,)@.2M/=,(`"@RB""#P``D`%\"X()B0:/ +MYN!X\<#AQ0#9SW6@```P-:4`A00@@`__X/__F+@`I0"%!""`#P#___^1N).X +M`*7(V!JE#=@8I3FE$@^/^YX/(`"*(/\/G@D@``+8.!V`'P`0``#/<*```#00 +M&(`/`$$``#`=@!\`@```SW&B``R``('/D"CSW.B`'AP0(,$>B5Z0*// +M/'`5@V/YAIQSW&``$@5((%(=PAV!-@'Z<]Q +M1``,\B"!F.G/=:```"`;A8H)(``'&A@PR7`*<78,[__I"```SW"``!PN`("` +MX.P+`@!:"D_YT<#@?N!X\<#B"D``$@Q/[D8+S_HR#<`(H@Y`!-'`X'[@>/'` +M/@M```8/0`0""T_YT<#@?N!XSW*@```P">C/<(``C+8@@`:")7@#\`:"`-@& +MHN!^X'C/%1@@L]Q +M0````$"#@H,E>B&#I8-989EA@X.9882#/F3=91,(40!(<`7L2@L``,EPJ7$$ +M\`T(D0!(<#H+``!M!(_F\<#Z"X_F"B4`D$AV`O200I@0\```D]02E!/'`SW"``(2V`(`A")``4@I`!8SHSW"@``!\`H`-"-X'#'#QN(0)0@71P.!^ +M\<"""X_F<@E``#8/``"+Z,]PH```,"&`BB`.`5X-[^;#N<]VH```(#H6`);* +M"Z_[12#``S8.C_BJ"H_XK@[``!?($.B[AB8-;_%@RCN&@MRB>0XA``.`X'@( +MB0D`V`/P`=B>"@`!E@Q/_8D#C^;@>/'`!@E``,H.``"`X*`(807*(.$!T<#@ +M?O'`^@J/Y@AU`-[)V#V`$R7!:#`_X7@FO\*EP +M'@@@`*EPSW"@```PS*`!V+8(8``3&A@P)0./YO'`G@J/Y@AUSW"``)P4`(`` +MW@GHSW"``(BV`("`X,HF8A`$[@K(`_`+R%H-(`!Z<%IPL@T@`*EPH@TO_!IP +M=@WO^`AWX@OO_^EP`@E/_G(-[__)<.(-[__)<,]Q@`#\4P"!SW>@```@H;@` +MH0H?&)"*(!```Z<$'X`?````"1N'!Q("-@L(A``;AT)X!_`[APXB@`______ +M.&`Z<``@P00`(8`$`"`0(!)URB".#P``@P/*(4X#RB(.!`0,[N;*(TX$`B4- +M%(X.(`#)<&H.(`#)<'(+(`"I<"((X`<(=AN'SW&``!3:`*'/`"B!AJ8,V(*X`<(&E@T]0&/YO'`=@E``'H*C_L`V<]PH```$"F@T<#@ +M?O'`B@F/YL]P@`"<%`"`SW&``(BVH($'V0H@@"^@```@"QA8H.8-;_T$?<]P +M@`!(%0"`@."@"$']SW:@```P,(;/<(``D+8@H'H-(`"I<%8([_\(=Q]GB>W/ +M<(``%-H`@!!WPB<-$,H(X`?I<)APSW&``"S/!H'X8`:A`-@5I@`8@"\````( +M$@T@`*EP90&OYHAPX'CQP/H(C^8`W0WPNF54>G0B`P`!Y96[E[O"DN&2$+[% +M?^"CZPU$D$$!C^;@>.!^X'C@?N!XX<7AQ@#>R7/)/'`8@B/Y@#>^!R(L\]UH```()45`):_"!X` +MBW#.#J`'@<$:<.8((```P*X.+_Y`P#IPSW"``(RKX(@/"!$@E14`EH,(7@!L +M%1`0`-D5"1`@$F]#<`P0#@8!V!<:&#`%\!<:F#,H=@`4$C`*<`/9"KG>"2`` +MR7("(@$@10E2`%H/#_RIZ`#"`G8+"H0#`B*``P;P#B:`'_____]88!@:V#-V +M"N__`-DO"%$`*PD0($X);_[INC(/``!""(_[`=G/ +M<*```!`IH-'`X'[@>,]SH```'C6#$PE>``;H-H,"($(`!PI2`!:#X'[AQ>'& +M`-L-\'IC5'I=8$"5`>.5NI>ZP(+!M3"^PK7M"T2`P<;@?\'%!0'/__'`'@]/ +MYHX-S__/=H``G!0(=0"&!>BR"L__,@K/_Q()S^[^"```SW>@```@!1^8GP`( +M``#N#X__O@E/^.H)S_@R#@`%31^8GQ````!&"0``&X<-"$0#.X>B>0CP&X<. +M)8$?_____QEA0(8`V`CJSW*``(BV0(*`XLH@8@`)&E@S!.@*&E@P!/`+&E@P +M$\B*Z`7()!(!-A!QRB!-`"0:&#`!V(8.+^X`V>$&;^8!V.!X\<#/<6,(T'L% +M*'X`"B#`#F&X3R#"!\]QH```,%6AT<#@?N!XSW&@```P!H$`V`:A18$%H42! +M!*'@?N!XSW&@```P$8%%(,`#$:'@?@ASSW"@```P&(!Y81!X!"B`#P``"3U! +M*4!R.&#@?UA@SW"@```P-!B`#P`0``#/<*```#0,&(`/`$$``.!^X'B*(?\/ +MSW"@```P+:#/<*```#0CH.!^X'C/<*```#`,&(`/``P0`!$#8`EDV`'9SW"` +M`&P3(*"SV,]QH```,!BA`-@9H>!^X'@!V<]PH`"`32B@X'[QP,]P@`"(M@"` +M#^C/<(``G!0`@`GHX@_/_XHA"`#/<*```#`CH+(-3_O1P.!^X'C/<*```#0` +M@`#:PKC/<8``A+9`H14(4``-")``$0C1``/8!?`"V`/P`=@`H>!^X'CQP,]P +MH```,#B`&8"BP1!X.&#/<]PH```,!J`$'@X8*+`T<#@?O'`R@@``!4(40#/<*```#`,&(`/``@``-'` +MX'[QP,]Q@`!L$T"!SW&``'`3\"&!``4I/@`*(,`.T<#@?O'`SW"@```P+8`. +M@"1XSW&``%0R((D7"5$`SW"@```<%!B`#P`H```3\!4('@?/<(``2!4`@(#@ +M7`J"`'(.S__/<*```!P4&(`/``@``-'`X'[@>,]PH```,#&``-@-"9X`X[G* +M(&$`X'[@>,]PH```,`&`P[B$X`'8X'_`>.!X42*`PP'8X'_"(`$`SW"@```P +M`8#[N`'8X'_"(`$`X'C/<*```#`!@/&X`=C@?\(@`0#@>/'`SW"``/38SW&` +M``#9]@KO_R")SW&@```@`(&NN`"A`H&UN`*AT<#@?N!X\<"`X`#9RB!!`"3R +MSW"```39SW&``*#9O@KO_R")SW"``,#9SW&``/;9K@KO_R")`=C/<:```"#, +M&0``"=@>H1^AB-C0&0``SW"``*33`(#1P.!^\<`+Z,]P@`#TV,]Q@```V2(, +M[_\@B='`X'[@>/'`6@M/YH#@?_+/<(``(#LP((T/``#\"<]P@``$V<]Q@`"@ +MV?(+[_\@B0HA@!]%`"@A0"T($0`A#A("AB"&FK@`H4HCP!//=Z```"`4'\`2 +M`>7!O4`M!Q$`(<`1#(C/=8``P-D88!1X$&4*)H`/H`````4@@`$`$!``SW&` +M`/;9J7"6"^__((E,C@`G1P):8E1Z665BD0(1!`$0NP61"!$%`1"X!24%`!0? +MP!(,%X``!23$`!A@%'@090#;!2"``2"`4F4"(0$$`"1`@`4B@@$`H@R.`2-# +M`1A@%'@&Y1!E`"$)$@4@@`%@H`*&!!$"$)JXF[@`HEN'SW"``*330*`;ASA@ +M&Z>]`D_FX'@0V<]PH```,"*@#!B`#P@```#@?O'`SW"``&2V`(`0Z,]PH`"` +M'!J`H@IO^T8@P`/2#\__2@D@``#8!?"."F_[#-C1P.!^X'CQ!P_L(\@`V0'@ +M(QH8,(HB!`#/<*```#!"H!,:6#`$\.!X`>&,(0^*O/?/<*```"`;@,]R@``4 +MVB""(GC@?P"B\<``V0[P.&$4>,=P@`#4%$*089`0N@"017LK(P```>'/<(`` +M^!0`B-\)!(#/<(``D#//<8``PC2:".__((G/<(``R#3/<8``;#:*".__((G/ +M<(``@#;/<8``?#=V".__((G/<(``_%'/<8``^E-F".__((G1P.!^\<``V@WP +M6&(4>,=P@`#4%""0`>(J(T``8;`PNV*PSW"``/@4`(@0,]Q@`!46">!!"&^CP,````& +M]`0AOH\,````#O+/<:``@#"`X`B!SR`B`<\@(@/0("$#"*'@?N!XSW*@`(`P +M+H*`X,\AH@+0(:$"+J+@?N!X\<"`X`'8P'@/'`#@A/ +MYL]UH`"`,`J%"B&`+Z```#`T$0$@4R`0`)RY-!E`(`J%ZK@*A0CRO+@*I6(/ +M[_(!V`?PG+@*I68/[_(!V`#>!O`N#&_F!M@!YAIW%0Z5$NJ%P+\T$0`@$G?1 +M("&'\_7/<*```!P4&(`/``@```$`3^;@>`#:">@-"%``@N#*(F$,`_`:VL]S +MH```,!F#!""`#___``!!*`$$66$E>!FCX'[@>/'`3@O/_POHSW&@```P(8'K +M+,(B*! +M"/2"X,P@XH`*\N!_`-@)"I``*'#@?OT($8'@?P'8:0`@`#_8X'CQP`H/#^8H +M=M8(;_D`V0AW`O"F?B3N+RF!`TXA@`<`W0\E#1`2"B`$J7``V07PIGM@H@'A +M+WG?"5.!1"\^&P`A@G^``!Q.-GI)B@MZSW*``.03-7I@@NWSI7OL\1D'#^;Q +MP*X.#^8(=A/P+@D@`*EP#_`O*($#3B"-!Z]]L@Q@"*EP"B$`@!`F3A//?N_U +M\^[M!@_F`-H$\`'B3WH;"E,!1"D^"P`A@W^``!Q.5GMIB^D+#H`"\/_:X']( +M<`#9`-H/(@(``O`!X1<)50'/<(``Y!/P($``2WCW\R]X`O#_V.!^X'@(<0#8 +M#_`O*T$`3B."!T]Z$"&!`,]S@`#D$_`C@@`O>45X\^G@?N!X\<`"#@_F"'8H +M=4AQ,PI0`$T)D``1"=``SW````4KW@]/YC'P1"X^&\]P@``8[0`A@7^``!Q. +MW@J@!2S:(_"`Y/'`:@T/Y@AV +M"B5`D,H@@0\```$K7`]AYLHA@0,O*$$#3B"/!Q`ES1.O?`,]Q@`!$X0"!)0A1 +M``#8`*'/<(``S-6V",_\N@G/_`"5H+CAN`"US`Y!^,]PH```(#N`SW.``&!1 +M0H,+"80`&X!">`?P.X`.(H`/_____SA@Q00OY@.C\<`^#`_FK@^O_0'>@>"F +M#Z_]PB:!$\]Q@`!0%+H,[_\`H:H/C_V^#Z_]"'4(=R(/H`#)<,EPU@I@`.EQ +MY@^@`*EPR7"I<0((X``#$@(VT@^O_1IP"'//<(``5%@*$(0``-BI<>ER\@UO +M[0HE``2R#X_]SW&F```(`[BE>`"A*00/YN!XSW&``+"V`K@4>.!_"&'@>`#9 +M`K@4>,=P@`"HMB&@(*#@?RBH\<">"R_F\=S@`"HM@AU+PF``("#/&2` +MH\F8")(`3`K@C#"40P:,(BPL(TP,!X`BK`-@`HP&C!?``V`"C`:,(J^K) +M/P@>`,B+0"H``A!Q`=C`>!"^!"",#P```/_%?`"#P8.O?0(@@P,6NT)Y,'[/ +M<,7N@T#F`(Q7N)`P_FX'CQP!(++^87V0]^A"X)'P`AC7^``"`[ +M`*6F#&`(0"4`$B*%"0F5`H?ISW````8TW@Q/YE4E0!:*#&`(#-F*#2_\R7`! +MV#T#+^8!I>!X\<#&"B_F"'++R58B#02D$`$`!H4;"1X%SW:!`#1&((8N#V_W +M0"8"%`&F&;4+\(`B`P4>#V_W/94!M2*5&;4X8!BU!H7Q`B_F!:7@>-(:F+\` +M```@T0=/[/'`7@H/YH(D`S0`W0H@`"=`)!(Q"B&`+X``=%BI=@[P]"%/(RX* +MK_JI&Q`>;/?@'EZ0W4G$#&"G#/<@``__Y:"Z`$T-EQ`B_F@"0# +M-/'`X<4`W>'%BW&>#"_\"-@3Z$X,#_P`P8#@RB!"`!`)(NK*(4(#SW"``#PR +MH*``P'8((``!V5T"+^:AP/'`X<6AP7X.X`@H=0AQSW"``'18]"!``(#E`!P$ +M,-P(XOK*(`('`!0`,2T"+^:AP/'`T@_O_P#9AB#_"]'`X'[QP.'%SW&@```@ +MNX$V#L`(SW&``/3I"6'/<(``=+/4!+^:@H.!X\_O"G`O)0<@A"@)+\]Q@``H.S(A5`Y2#:_]JG`(=8(*K_T"@"J- +MVG`)%9,0`=T`V`\@0``O(@<@BW`Z<)8-[^H(V2IPRG&N"*_M2G(`WD+&HPP0 +M(4,,4"&A#!$B&N^"P8X++_P%V`;H"G`*""_JR7&#Z,EUSW"``#PR`("`X,PE +M(9`T\D'?@.40WNEU-O+^#\_L,O""P58++_P(V"[H`L#6#^_IR7$HZ`7OX@_/ +M[!OP5@W@"&IPSW:``/3I"&8?"!`"0@W@"&IP"&83"-`!-@W@"&IP"&:$X.@. +MPNS/<(``/#*@H$'=`-X(\`G=$-X$\(#GRB7B$"IP2G&I/'`3@@/Y@X)[^\(=@AW`-T7#M$0N@JO[@/8$PC0`/8*C_T+"%`` +MJ7`"\`'8FNB,)\.?&/+/<(``<+<`@)+HM@ZO[^EP"'8-\"\H@0-.((T'L'VI +M<(H.[_\!V1`F3A/V[ED`#^;QP-X/S^6BPEP +M"'42":_]`H#*C3IP`-@/((`#+R`'((MUJ7`J#._J"-FI<"IQ0@]O[0IR=@JO +M_>EP"''/<(``5%E0D."YT2(B@`OT"PD?`!,*7P#/<```_A2""6_FP+F*)T00 +M#PY0$!<.D!``V`SPSW"``!CRBB=,$`;PSW"``"#RBB=4$(#@L`]B[%8-[_\`V88@_PW1P.!^X'CQP`]X +M0@WO_P#9P+C1P.!^#_`"$`,%;WPHNPB\A7MZ8@L*W@=0>S"Z>F)BN3!YYPF3 +M@!$)4@``B`BX`_!0>AIB02H`A/SU4GC@?Q!XSW&``-3?X0-@!0;:&F(R>3!Y +M66%!*0`$.&#@?Q!XX'CQP,]P@0"4-NP<"+#/<(``5/5!P,]P@`#N#Z_X2B=``*7` +MT<#@?BAR#WG/<($`E#9=`,_XX'C/<(``L+?@?P"`X'C/<(``'-_@?P"`X'C/ +M<8``'-_@?P"AX'CQP"H.S^7/<(``L+<`@/_>`-WX'(BSX0@0`-X.;_Z+<`#! +MU0F``POI)PE0`#<)D`!PV/H/+^:-N![PSW%%`#@L"('/=40`!,D!X`BA%/#/ +M<44`."P+@<]U1`!8R0'@"Z$*\,]Q10`X+`V!SW5$`)3*`>`-H0H@@"^``+BW +MF@F@"@`0`""!P0AV0"`/!.EPM@I@!0+:Z7``V7X*[^H"VN"5=@F@"@/8()#R +M?R]X*+D(N"5X`!`!(")X(94O(`@@%.$P>?!_#PD`!.EPH@[O_PIR"'?)<`IQ +M3@[O_^ER!!0",4]Y"+DHND5Y#0A!`,EPH@BO_@#!G07OY:+`X'C/<(``8.+/ +M<9@`@):5`H_^\<`.#<_E"B8`D((D`C8`W0WR00Y0$%\.D!!PV(VX`@\OYLEQ +M>G6:=2[PSW!$`*C()9!`(`T'"!`3`4`A``(O)`@@SW%%`#@L!X$!X`>A'/#/ +M<40`Z,D:$10!&!$3`<]Q10`X+`J!SW5$`!3*`>`*H0KPSW%$`*C)!A$4`4`A +M#08$$1,!0"0`+"\B""#/<(``M+=`@,]Q_P#_``0B0``HN@BX)'I%>$,H``20 +M'``PSW"``)RW0(`$(D``*+H(N$1Y)7A#*``$E!P`,%8D@#1`)0$89@E@!03: +M521`.4`E`1E6"6`%!-II#E$0SW=$`"C+((_/<(``H+ +M"_``(8`C`"!!(]EA^@A@!0':`>8#C^T.!)`O)\H4\']`)0X;R7``V;(([^H" +MVD`E`!=`)`$E,'FN#.__Z7(/>2BX"+D/>"5XD!P$,%8D@#3)<;((8`4"VL]P +M@`!XWB"`SW"``%@[A"D)#S`@3`Z+ +M"&`*4R0'$*4#[^6`)`(V"MCY!.__`-GQP%(+S^4(=4$H#P$`W@/P`>8-#L03 +M$?!Z"D_ZSW"@```$#H#U"!2$`-GI"16!`!8`0`'A^_'#O0/P6@I/^L]PH``` +M!`Z`]PA$@P#9!/``%H!``>'["42#90//Y?'`\@KOY0AQ@B0",P]XA"@)#\]V +M@``@.R]UOV9O%P(6&G"`XLH@@@\``"$TS`P"YHMP=@P@"!?9E\!N#"`(#-G8 +M92H/K^J*(0D/0"@!(39Y`"&`#X``O$<2#Z_JD-F*(/\/`*>`V0`E@!^````] +M(*CI`N_E@"0",^'%X<8`W,]R@`#TMQ0B`P"`LXBSF!L$`QUB(!T"$P]^SW&` +M`$S=UGD@D2@=`A-0&T0``=E@'4(0>.(5>H"BJ!L$`\'&X'_!Q1)YSW*``-0O +M`((D>`"B`8(D>.!_`:+@>.!^X'CQP,]P@`!(%0"`@.#*(($/``"(`/@+`>;N +M"8__Z@_/Z]'`X'[/<(``K+@`@(#@`=C@?\!X,-D*Z,]PK0``7B"@SW"M``!H +M"?#/<*T``)X@H,]PK0``J#"@X'[@>`'9D+F`X,H@@@^M``!#RB"!#ZT``(,Y +MH.!^X'C/=`D`FIF*ZT)X!2@^`P`A@W\$`,W,!?`%*#X#+W-">3UX?0+OY7A@ +M&PC3`X[@RB"!#P``M`D+\A5XQW```&<)!/`5>)8@20P0>.!^`-BMV1"Y`Z$` +MH0/:SW"M``!`2J`_V`NAX'[@>.!^X'@`V4L(40`1\,]P@`"X$_0@0@"MV!"X +M\"""`,]P@`#`]S5X0*`!X>4)%($3\,]P@`"X$_0@0P"MVA"ZSW"``,#W\"!` +M`'5Z`*(!X>4)%('@?O'`Y@COY4X@P@^MW1"]]85H%040SW;\_S\`Q']V:F5_ +M0"@!`P4AQ`,$)DX197XE?E0=`!':I65Z17DVI3NESW*M```#.H(=?`0A@0__ +M_\#`0"@#`@5[97DZHL]SK0"``[N#SW'_@?__)'T9N`5]NZ.\@T`LSA;:O<5] +MO*-V@K5LAB//#Z5\A7MVHL]SK0``'D&#)'H%>D&CSW.M```H48-$>25X$:.M +M`,_EX'C/<:T``!4`&8`/#P!#\N!XX'C@>.!XX'C@>.!XX'B*(,D``*'@>.!X +MX'C@>.!XX'C@>.!XX'[@>`C9D[F`X,H@@@^M``!#RB"!#ZT``(,YH.!^X'C@ +M?N!X\<#AQ8;HSW!%`(PNJ6D/\$(A``D=>$EHC"$"A,HEC1#*)0X0SW!%`'PO +M1"U^%#(@0`X0<`L`@,]Q@`#$ +MN(8@\`\@@2:X@.%\".'ERB'A`-'`X'[@>/'`5@^/Y<]P@`",JP`0D```V,]V +M@`#(N`>FSW*``'@+(H(6IE,APP"#XP'&$PA1``#8!NDF@O2YRB!B`!RFSW&M`(`#!!$6`!`1 +M$0`4$1(`/!$3`$`1%`!$$14``-\(\`78!Z4,A0'@#*4!YX+G)`$&`$0O/A\` +M)DT>#85WZ(GORG`+"!X`%PB>`@#8"/#*<0#8#0E>``D)7P0!V(#@=O*([U,B +MP2(EI5,AP"(&I0WPSW'_``#P!")`("RX!:4$(4$$++DFI0Z%=P@0`(3O4R7` +M(@?P!"6`+_\``/`LN`"E)H5%A`) +MI7/Q"X4!X`NE;_'Q!8_ESW"``$2YX'\`@.!XH<&`X,]Q@``$W\H@(0`%\F&X +M&WB`N`"AX'^AP/'`SW"``(`3*)"CX`_"Y='`X'[QP'8-K^4` +MV8#@E;D*((`?K0``8,]UK0"`7@#:EKH*)X`/K0``H,]TK0"`G@HF@`^M``!H +MSW.M`(!H"B6`#ZT``*C/=ZT`@*@`V)>X"-X,\B"E0*0PHU"G`:41HX`8F)/( +M<`OP(*1`I3"G4*,!I!&G@!^8@ZAPT*!I!8_E\<#:#```&@K/ZQ((``!N#"`` +M`=C1P.!^\<#/<:(``(`1@8"X$:$!V<]P@`"`$R&@SW!$`%S;1@ZOZVG9SW"` +M`$"YU@OO_P"`;@^/Z[X-#_U:#H_KT<#@?H#9SW"@`(`#")`(E3"(` +MH,PD(J#*(($/``"2$\HA00.@#>'ERB+!!;U]1,4$&$`T1!L`)`0=P"-$'L`C +M/@F@"&38!!U`)$0>`"0N":`(^M@"P"\GPB4`WPKH]X9*(D`@4R<`$('@PB*" +M)`#=%PD0,+R&2B1`(%,E`!"!X,(D`B5,(@"@S"0BH,H@@0\``),3RB'!`RP- +MX>7*(D$#_7\$&$`T1!L`)!#9!!U`($0>0"`$P;UX/V<`P>)PX*$!P0"A`\#9 +M'A@0$0.OY:7`X'CQP-X*C^4:<"AU"8THC0BX!7D*C:W>$+@%>0N-$+X8N`5Y +MSW>M```#`-AZ<`CI(:<`'H`?````0`"F0_`!IP/8.G#/<:T``(`*H4P@`*`2 +MV,H@P@0+IF;8`*;R#J_E`]C/<*T``$!:<``8@`\```!`V@ZOY0;8U@ZOY0;8 +MS@ZOY0;8`![`%`L($2`&AP+P!X<(<2BM*+DIK2BY*JTHN2NM!2"`#X"`@(`( +MK2BX":THN`JM*+@+K2@:0"0_V`NF?0*/Y>!X\<`>"H_E&G`H<$AW:'8*(0`A +M"B)`(`%,GP!`8N("X@;B-N`HE@`^M````SW&M```#&Z$*)D`$ +M&_!`+P`6!2"`#P```QC;&A@`6!N8#PT````-V!"X"P]0$%@:&``*)8`/K0`` +M`,]QK0```]AV]!L8`Q\,7@##OT`O`A:`NH&ZC;K/<*T`@`/T'9@`%_!`+P`6 +M!2"`#P```QCT&A@`81N8#PT````-V!"X"P]0$&$:&`#/<*T`@`,Z=GT($"!` +M+@(60"X#%`0C@P__````97I`+@,2!".##P```/]E>L]^17[@X'[@ +M>/'`".C2#6`(9-C.#6`('MBV#8_KT<#@?N'%X<:!X`':P'H>ND\BPP>!X`5\A7M@ +MHL'&X'_!Q?'`6@H/_[((3__1P.!^X'CQP!8(K^7_V:W>$+Z@AL]PK0``@""@ +M4@U@"`/82@U@"`/8H*9"#6`(`]@^#6`(`]A5`(_E\<#>#T_ESW6``)03HN@! +MWWH((`#I<,]V@`"T$P"&@.#*(((/``#&**@)PN7@I@#9#?#T)4(0K=@0N/`@ +M@@#/<(``A/$"@`>'K"=2#&_``V0[P]"5#$*W:$+K/<(``A/?P($``=7H` +MH@'AZ0G4@P#8SW&``+03$@@@``"A#@Z/_\D'3^7@>/'`X<7/<8``M!,@@<<) +M$0#/=8``+-\@A2_H@.'*(((/```2.\HA@@\``"H&)`G"Y<]Q@`!X"T*!SW"` +M`!S@0*!#@<]P@``,X$"@1H'/<(``&.!`H$"!SW"``!#@0*!!@<]P@``4X$"@ +M*('/<(``".`@H`'8+O"!X`L"H<]P@``,X`"``Z'/<(``&.``@`:ASW"``!#@`(``H<]P@``4X`"` +M`:'/<(``".``@`BA`-@`I0$'3^7@>/'`?@Y/Y8#@SW6M```@SW&M```BSW>` +M`+C?SW"M```LSW2``,3?SW.``+S?SW*``,C?"B>`#X``P-\*)H`/K0"`*@HE +M@`^``,S?$_3`@<"GT(`A@<"D$8`@HP"BA!4`$``?``!$%@```!T``!'PP(>` +MA,"AD*!@@V&A(((QH``7``"$'0`0`!4``$0>``!=!D_EX'@AB,]RK0```\.Y +M$0D1`5`:@`\$`00!!O!0&H`/30--`P&(1+B&X,H@H00&\H?@&]C*("()%:+@ +M?CMY17D$NV5Y0"Q,`85Y(0`@`#!YBB)0`,]QK0"`@$2ASW&M`(!`!*'@?N!X +MSW.M`("`SW*M`(!`ANB*((\/!*,[>0?P$!N`#P\``/@+N22BX'[@>.'%X<8< +MV\]UK0``A&.EPK@"N,]SK0``1`.C#MC/=*T`@(,?I%,A@``;>,]QK0"`0Q^A +MX-[/<*T``*K'H%,B@``%N,]RK0``:@>B!!N`#P"````$'8`?`(````'8'Z$? +MI,'&X'_!Q>!X\<#AQ0HE`)`!W*W;SW&M```6SW*M```5$+LT],]PK0``0(F@ +M-_!$&X`/0@0B(BP9@`\=`X'NE=@,H0P9@`^,``"`1-@$H0#8`:'`.!XX'C@>.!XX'C@>.!XX'B>"*_KJ7#/<(``Q+CY!&_E +MH*#/<*T``(")H,]P@`"`$P&`R^A$&X`/(@(B(BP9@`\=`(#0<=@,H009@`\` +M```/#!F`#XP``8!'V`2ABB`&#@:B'!J`#P``D.(@&H`/X@1D`,?QX'C@?N!X +MSW*``'@+(((4N+2Y)7C@?P"BX'C/<8``>`O@?PBAX'CQP.H+;^5$*GX$"B4` +MD#IQ&G(O=@7TSW!%`(PN!/#/<$4`?"\>9BH)+_"I<%IP!8XDC@BX!7D&C@HD +M@"^M```8$+@%>0>.SW>M```5&+@%>36G`XXBC@BX!7D^I_H-S_P`V8WMX+C* +M(8(/,Q\'`.&XQ2&"#P``G_D+\."XRB&"#^D?!P#AN,4A@@\``$__`-JMV!"X +M>G`MH,]PH@"`;7"`((ZLNZV[KKN,NXV[<*#/.!XX'C@>.!X +MX'B*(,D``*<4AX&X%*<4AZ&X%*>J#B``"G!#%`,F02L"!4]ZT[LQ#5$0SW&` +M`(`3(8$2Z0#9@.#,(B*`RB%B``#8%^DO#L1P#0"@NR<+A`\"`""_#O``V0;H +M#0[%<`T`@&TH<`?P_0N$CP,`4#0!V('@RB""#P``JBC*(0($H`RBY$`I`2$%>4`I`"4%>4\A +M``"0N,H@0@#9&Q@@V!M8(&8,[__)<*EP6@^O_\EQSW"``(0SP*!Y`F_ER7#@ +M>`?:"KK"N0JYBNC/<*T`@)]0H,]PK0"`7S"@"O#/<*T``*I`H,]PK0``:B"@ +MX'[@>,]Q@`#$N$"!%"`!`(#BSW.``'@+0(/*(0(`!"*"#Q_^/_P6:16Y)7A% +M>.!_`*/@>`'9"NC/<*T`@&`DH,]PK0"`:@GPSW"M`("@)*#/<*T`@*HTH.!^ +MX'C/_\H$&H`/;&",>0@:@`]".51*#!J`#R8B,BPA\$`; +M@`_*M/_C1!N`#W]QH(Y(&X`/3T9D64P;@`\R+#\X`!J`#\JT_^,$&H`/?W&@ +MC@@:@`]/1F19#!J`#S(L/SC@?H#ARB.A`P7C`MP+Z#L( +M4`!+")$`SW"M`(!``]D>\`';SW"M`("`9:"`X!1B#`!V5X +M!Z$'@0J[!""`#____X-E>`>A`H%&(,`'A7@"H0J!1B#`!X5X"J'@?O'`<@A/ +MY0AU*'9(=R,(T0'/<*T`@*`(&(`/````_\]PK0"`8`@8@`\```"H!=TE#M01 +MSW"M`("J2!B`#P```/_/<*T`@&I(&(`/````J`7>0B<$D`#8RB1B`*EQ&@L@ +M`(AR`=BX<,EQ#@L@`(ARSW&``'@+!H$$((`/S___\QKO0H$&H8/ES"5BD0CT +MBK@&H0D/D1"+N`:A@^;,)F*1#/1/(`,%9J$1#Y$0E+B5N`/P0X$&H0"!K=L0 +MNP&C`8%3(OZ``J,_V`NC"/+/=*T``(`H'$`1!]@+I$ATAB3\DPGR`MC/=*T` +M`(`*I#C8"Z1`HP:!`Z/I!P_ESW*``'@+88("N**[LKL2N25X97C@?P&BSW*` +M`'@+88*'Z$8C``X#N05Y(:('\+.[M+NUNQ.Y)7MAHN!^SW*``'@+8(*)Z*J[ +MJ[NLNT`I@`)E>`"B!_"YN[J[N[L9N65Y(*+@?L]Q@`!X"^!_!Z'@>/'`"@\O +MY1ERB'"H=,AUSW*M``"`SW>M``!`Z'83Z5`:@`\``/]_9!J`#P``_W]`*($2 +M!;@E>`5]M*<*NP6\A7L4\%`:@`__/P"`9!J`#_\_`(!`*$$6%+@E>`^]I7@4 +MIQF[%+R%>P^^Q7MYIPD'#^66Z`?;PKJ+Z<]PK0"`GW>@SW"M`(!?5Z#@?L]P +MK0``JF>@SW"M``!J1Z#@?GS;`KJ*Z<]PK0``H7"@SW"M``!A4*#@?L]PK0"` +MJV"@SW"M`(!K0*#@?N!XSW&M``"$">@$VL]PK0``1$F@`]@"\`?8":'@?L]R +M@`!X"R*"@.#/(6('T"%A!^!_(J+@>,]Q@`!$N0"A$>C/<:T``$0K"%``1PB1 +M``@9@`\`&```SW"M``!``=D8\,]PK0``A`@8@`\`"```$?`(&8`/``@``,]P +MK0``A`@8@`\`$````=G/<*T``(`]H,]PK0``1`08@`\`@```SW"M``"$!!B` +M#P"```#@?L]S@`!X"R>#F^E"@R:#AB+##T*C!"&!#\____,FHQ,('@9%(L(` +M0J.*N8NY)J,3"%X&12("#$*CE+F5N2:CX'[#NICH#]L(NPBZB^G/<*T``*!P +MH,]PK0``8%"@X'[/<*T`@*I@H,]PK0"`:D"@X'X/VXOISW"M`("AI`(P("`_!`(P(#8(*& +MZ$8CPP-E>2"B!_"&(P,,%&EE>`"BX'Z*(TT%SW"M```@@!C8``#:@1B8`,]Q +MK0``+'"A4:$_V8080`#/<*T`@"HQH.!^X'CQP)X,#^4*)P"0&G'*(($/``"G +M&8@.0>7/<($`B#:CB,*]`-X/\/`G@1-!*8`#PKBE>!!URB""#P``J!E@#D+E +M`>;G#@24P00/Y>!XBB`9``#9E[DY`6_K'MK@>`':SW&``(`30:$+"%$``-@! +MH>!^`=K/<8``P+A`H<6XSW&``$"YX'\`H>!XX<7AQCM[12-,",]SK0``%9.C +M`-P+\'9IFV/P(,T`SW.M```8E7N@HP'D[PR$D,'&X'_!Q?'`Z@LOY0#9"';& +M#^__0-H!W.!X`-C/<:T``!43H0`9@`\/`$/RX'C@>.!X +MX'C@>.!XX'C@>(H@R0``H<]P@`"\N`T$+^6@H/'`C@L/Y0AU+R`'(`]X1"@^ +M"P`ACW^``)BY,@@@`"AVSW"``$BZI:C=>,*X"*_I<`L(T2"*"4_K!?#)<>8) +M;^NI/'`X<7/=8``2+I%C40J/@N,(L./`"&`?X``F+D4\L]QH``` +M(#N!(Z`3"M``8@@/[,]P@`#PX>X(0`:^#"_N$MC_V`6M@0,/Y?'``@L/Y0AV +MSW6``$BZ18W/<(``C*M@B(PBPX_,(^*`RB"!#P``EAKH#&'ERB&!`P6-1"@^ +M"P`ACW^``)BYD^X`AR\(W@`)CP:MO@]@!@+8`8<`IQ2/@.!H#^+KRB#"`P?P +M4@IOZ^EPG@]@!@+8`0,/Y>!X\<#AQ0AUO@IOZP'8&>W/<(``2+H%B$0H/@L` +M(8!_@`"8N1X*3^O//'`1@H/Y<]V@`!(N@6.1"@^"P`AC7^``)BY`(4I"%X`%(V2Z`2.$0A1 +M`(H-C_R!X`'8`_()C2:.#0A```:N"@]@!@'8<0(/Y?'`]@D/Y<]U@`!(NB2- +MSPA```2M`-[#"!``0O!$+CX;SW"``$BY52!0!58@CP(O=7`G0!."X,PFXI`P +M\@8([_S)<`;HA@RO_,EP*.@4CX#@[`[BZ\H@P@,`AP\(WP`P($`C`*<(\,]Q +M@`!(N@>)$""``P>I!-@`I\]Q@`!(N@6)&0X!$`'8!JE1(`##`=C"(`$`;@Y@ +M!@'@`>;/?H$.$I$=\$0N/AL`(8!_@`"8N2"`(PF>`"&`(*`EC1L)@0,TB`3I +M^@W/ZP3P"8@&K3(.8`8!V`'FSW[/#A*1A0$/Y>!X\<`>"0_ESW"``$BZ)8C/ +M=H``2+E$*3X+5B:-$HPAPX\G=]I@`()D>2T(D`!-"-``0!8`%D4(4`#LZ12-BNC/ +M<(``#.*&#@`&U@SOZZEP%0$/Y12-9'@4K02*8H(%*/X`!H4G<`:E!(IC@@4K +M/@`'A2=P!Z4%\!2-!'MTK0#8`*+=\?'`$0E1`)X((``!V0'8!O"2""```-D` +MV`H(``#1P.!^SW&@```PA=J!X`J!&;K%(($`T"!B!M`@X@8*H0N!WK@+H>!^ +MSW*@```P(0A1``(A@0\``#4,);D+@I^Y)7@+H@J"N;@*H@CP"H*YN`JB"X+> +MN`NBX'[@>,]QH```,`J!^[@*@<\@8@;0(&$&"J$+@=ZX"Z'@?N!XB0?O_P#8 +MX'@`V@\B`@#//8%BX#AQ2""`,8@@0"]!._N!:O@>*'!\<"J#^_D"'.L +MP2AT2'4(V$3`#!R`/P"```#/<($`B#9`B%#!1+K"N@ZZ!"2.'P$``,!+?I#! +M%O+7=@```$#,)H*?````@,PF@I\!`````_0!@`+P`H"NO*^\L+P%?("A$,1! +M+($3PKD#PD`I``8%>D/"+PN>`03`!"2.'P```!A%(,``*[X$)(\?``,``#B_ +MY7X`WP\GCQ-AOPJ_Y7A$P!\+'@'/<*```"`0@)NZ`KANN$@@``#)N`5Z!/`+ +M"QX"G;I#PD'$BW;)<&AR4@\OZP';R\D4'$0S$(C/<8``],D#N!5X`&$6'`0P +MR7"F#Z_O`=GB#R_LR7`(W!\'[^2LP.!X\<"F#L_DH<'2#B_YBW`*)0"0L@4" +M``#!X+E0`P$`1"(`4XC@SW6``)P+E@("``0BON_`P,#`"?3/<*```"0`@.*X +M?@(!`.G)`=_YI2<(W@+/<*```$<4&(`/```,#.S)!=D!X+.XM;BXN.P:&+`5 +MN02ASW"@`(`@$H"`X(?TSW*``/`W`(+/=H``\#A'"!$"37!$(#Z#'_0DN%,@ +MP0``V`\@0``OA@MY%?)NAD\C`0`NII'KP!(!``0@@`\``!\=`>%"(`"`P!I` +M`)X-;^G*(&(`'@XOZ?*F-)7/`!\)%0(S)D%P@`"PXT`G`'(T>`!X!MH%\`3:`_`"VI/+SW&` +M`$`,"6'/=H``%`G/<(``2+IFB$.Y?7O`NP"&BB25X +M`*;:#&`'!MC/<:``@!T:@01_`(;E>!JA`(7/<8``)`DO(`,``*4!@0\('P`` +M@88@PP^`N`+P`-@`H<]P!`0$!`LB`.`>\@0B`>#_V`OR+RE!`$XA@``@#8BB'6`,]SH```*&\;6(`#VL]QH```#$>A6@T/ZP38`1L8@`0B +MON\!`0$!SW6``)P+./+/<*```"`:@++H%@T/]A6%E+@5I>K)^[BT#T(!*/!% +M(0$'SW"@`(`D,J#+\0^%L[BUN`^E37#NN,\A(@+/(6("SR&B`D4A`0;/<*`` +M@"0RH+[Q`-@9I<]Q@`"LS0Z!`>`.H1#9SW"@```D(:`6#J`'`-B*#0`().@9 +MA2+HSW!%`#0X`(``VH^Z6PC>`\]P1``,\@"`E.C/<8``_/E`&8(`*+I!&8(` +M*+I"&8(`*+I#&8(`%@B@"0'8[@J/]B.%")4PN1"X!7D"R!!Q`=C`>`*X@;C/ +M<:```"<`H0.%,+@HE0CPD@SO[A7=O@J`!'4"```0N25X`1H8,!G=T_#BN=+R +MSW"@`(`@$H#/<*````P-@,]PH```*$,0`88&$`*&,Q`!AN.ZRB5B%!WT#'#[ +MN,HEHA09],]RH```#'2"$X(="P``SW"``*!'!8`-"-X"`]@'H@;P%=T'\`D) +MW@<`W0/P%]V0[<]R@`"<"R&R!"&^CP,````!V`"IR6)G!8`$$0I +M/@O/<8``K+DR(4$.$2$`@.P/@@,>"(`#!!B8KP``_W\;V`<8&*`/AO"XB_)F +M",`'SW"@```(`H``V<]PH`"`12V@SW"@```?'(`O"!\`SW"``&@H`(`C"!X` +M#'`?"!\#SW"@`(!%,!B`#P`@````V<]P@`!L*""@:B&``<]P@`!P*""@=@PO +M^@'86_"R#D`'6?"*)@@07PE>`L]U@`!T5`"%Y)!$O]X,H`!3)\`0`(6>"6`` +M4R?!$,]R@`"<"PAU#0B1!A6"@+@5HCN"`>$[HL]RH```*((2`(;#N&<(00`$ +M&IB#@A(`AL.X5PA```,:F(,G\$<)W@`(V,]VH```*`0>&)`N"$`!"'4W"!`% +MSW&``)P+0X$(D3"Z$+@%>@+($'(!V,!X`KB!N``>`)`#@3"XL07O_RB1%]CR +M"B_EC+@!V)8(H`,`V9GE1`+!_Q8*S^ZI<$$![^2AP/'`X<4(<1"`H<$$(+Z/ +M`0$!`0#;1/($(("/!`0$!!7R+RD!`$XA@``A!$ +M%8(0>H[/<8``:!D9"L$`.&`JB(#ARB%A``7R"0H1(`+9*JA:KG$*$"#F#Z_Z +M"G`AE:ER1>(`VP/P`>,C"T4`%"+/`("/X8\(O^5\4R3/$NT(P8., +MMGNN`=@"\`#83"$`H,P@(8#&\P+:SW&@```G0*$EA4R5,+D0ND5Y@@RO_P$: +M6#"Z""_K"G!1!X_D[+;[KN7QX'CQP.(.C^0$(K[O`0$!`0AWNO+/<00$!`0+ +M(D#@'O($(8&,_]@+\B\I00!.(8`'([C/<8``[#+P(0``A"@)#\]P@```/<]U +M@`"<"S(@00[/<(``/`P^J`WP!8?:"&`$)H?/=8``G`O/<8``/`P>J16%!""^ +MCQ!P``!8#\'U"B.`+P`@``!1A\]P@`!<%4"@02H``U,@T0"^%8$002H2!11I +M!2!`!!IP#PG>`1*%E;@2I6+PA@O/^,$(%03/<8``]`GP(0X`"B2`#X``5`F^ +M%8$0R[X8N8*YSW.@```H,AM8@`(B@B,`V8RY.F++ND`I#"/7<@````B0O$KW +M!22,%%,;&(,!V,D=`A!J<#CPQ7Q3&QB#20Z%<```P`]">18D`@!@@B,)-0A! +M@@#8#R!``&&X3B$,"`$K#@,X>V5X.'K%>@_P0B$!"`#:#R)"`&&Z.'ME>HH@ +M_P\%\(H@_P\(<@'9SW.``$14(*L"&P0$`:-"HVIP!/``V)RX-84%>4`G`!(U +MI1JE`MG/<*```"<@H`6'+)<]P``#__Q!R +M`-[*)D(0I1(!MP\)W@(0<@#=RB9!$Q[PI,WCN,PF(I`2\D8AP0"E&ERP,L@! +MV@`@@0^``%2X0*D0V*0:'+`:W=7P`=W/<8``K,T,@0#>`>`,H8CN>@M`!*7- +M1B"``J4:'+`!V`;P`-@(=0AV6G`AER<)$0<$$1,@@.4($1$@3`YA^\HA@02E +MS8#FT2`A@P7T`-TC\`C=J?#LN`#=RB6B%JNXK+@0V:4:'+`RR*0:7+``(((/ +M@`!4N`'9(*K/<(``K,Y$@`'B1*!1@%5X5H`!XE:@.@TO^BAP@.:'\L]V@0`8 +M-`26"G%J`3`0!$*3X'18<`(T`.0*!,EP'A0K#/BN`;0`"(J`D8`@5`*`(A1;`,&,`$1)80&$`$SW:``)2VC&9*L)JH0"H! +M`YVY!2$!!,]WH```,#^RB8A$$#&`12!,%,FD!'&N3BH&1@"!,O)6G$0B&H/;_X* +MZ&5QN``:$W%P"6`:$$&<`$!!E`!%,FP!0!H32^P:&I<.D"K^2C +MP.!X\<"B"H_DH<$P@`#=!"&^CP$!`0'*($$#RB9!$\HA00-:\L.`")`POA"X +M!7[2R00@@`\`"`@``=F/"!$"I`6H3+(SW&``/2W%7F$$@,!'H%X8!ZA`8(1"!X!$(H! +MV58.;_XH,]P@``<#!20`-IBN!"X12!!`<]PH```)R"@`1J8,.!_2'#@ +M>/'`D@F/Y`AU$("BP00@OH\!`0$!`-R-\J3-Y;C/<8``+,V!\D#8I!H`%R7#/<8``G`L0 +M@0T(7@($V,$9`@"Z">_U@<``W`?PK!$```'<`>"L&0``F.P#A2B5,+@0N05Y +M`L@0<0'8P'@"N(&XSW&@```G`*$#A2B5,+@0N25X`1H8,`#8H0"OY*+`X'\( +MV.'%SW"F```$I(#/@@@V!YJ7`]`(_DX'@A@,]R@`"<"\&Y&0G1`,]P@``<#""` +M!H$!X`:A`-D?\#V"SW*@```@9.$PH@'9!QI8@!#9(*(A@(3I;''["1Z`(8#! +MN$%`8#AN,HAH03@?RAPX'CQP.'%SW6``)P+%84$(+Z/ +M`'```%;R+RD!`,]P@`!@NO0@0``\A8*XS@K@`EJ%E0@0`!6%"PB>!]H,3_\& +M\`#9SW"``$14(*AR#4`'SW"``"!'/8"H%0`1T@AO^S1X%85;")X'SW"@```( +M`H``V<]PH`"`12V@SW"@```?'(`Q"!\`SW"``&@H`(`E"!X`#'`="!\#SW"@ +M`(!%,!B`#P`@````V<]P@`!L*""@:B&``<]P@`!P*""@!/!J">_Y`=@5!T_D +M\<":#D_D,(#/=H``G`L$(;Z/`0$!`0AU-?($(8&/!`0$!!3R+RE!`$XA@``1*& +ME;@2I@^&E[@/IA6&!""^CQ!P```+])RX!@^O]16F0"4!$CJF`-@!L;(6`!&H +M%@$1.&!BN!"X@+C/<:```"<`H06%+)4PN!"Y)7@!&A@P809OY`#8X'CQP.8- +M3^0(=<]PH```(!&`+R0(`!"%!""^CP$!`0%6\B6%SW:``)P+SW>``!P,&0D> +M`(X-S_\EA:"Y):4$AY&XSQH8L!27%0@#`0R5,+D0N`5Y`LAM"0$`,(4$(8&/ +M!`0$!!3R+RE!`$XA@` +M#^`#)H6^'@(0%88$(+Z/$'```!;T!(`+H<]Q@``<#!F1-)$X8&*X$+B`N,]QH```)P"A!84L +ME3"X$+DE>`$:&#!A!6_D`-C@>/'`V@Q/Y.G))PC>`L]PH```1Q08@`\```P, +M[,D%V0'@L[BUN+BX[!H8L!6Y!*'/=:```"#(%0`0JP@1`,]P@`"<"Q20SW-$ +M`/CSW!,!`,.X!+G/0;:!/`$V@+P`MJ3R\]Q@`!`#`AASW>``!0)0BC$`,]P@`!( +MNH:(8(>=?,"\BB`A+`0C`P2%>D`LQ`&(<(8@X0]%>`5[8*>J"^`&!MAZ%0&6 +M`(<$(0$$)7AZ'1B0`(8O(`,``*;/<00$!`0+(D#@(?($(8&,_]@+\B\I00!. +M(8`'([C/<8``[#+P(0``A"@)#\]Q@```/<]V@`"<"S(A0@[/<8``/`Q*#&_Z +M7JD(=0OPSW:``)P+`X;Z#>`#)(:^'@(0`-V^%H`0%PC?`7H-;_<`V1X,;_J< +M'@`0"'4$(K[O`0$!`0CT`88-"!\`@-B^'@(0OA:!$$`I``9'"=X!3X9/(L$% +M+Z:SNC*&M;J5N3*FSW&``$@5((&7NHCISW&``!C;(($)"5X`3Z9-<>ZYSR`B +M`L\@8@+/(*("12``!B+P`[DU><]R@`#LR2%B@K@+"9\'+X:UN2^F.88C"5$` +M88;/<8``H$=%@>"[P2HB`<$JX0#`NA>Z+X9%>0/P+X:7N2^FSW&@`(`D$J$$ +M(K[O`0$!`<]V@`"<"QWR%)8W"%\!`):&(/P`C"`#B!/R#X:0N*(+K_4/IL]P +M@`!8%0"`">@`V):XSW&@_K`*1@]O^4^&SW&``/`W0('/=X``\#A*($`@1PH1 +M`DUP1"`^@Q_T)+A3(,(``-@/((``3X<+>A7R;H=/(P(`3J>1Z\`1`@`$((`/ +M```?'0'B0B``@,`9@``."N_HRB!B`(X*K^A('P`4#X89"-\%37`-")X#*@M` +M`@;P#X;UN%`(`OO/<*````PT@,]P@`!HNB"@!-G/<*```"0AH.K)%PC>!AV& +MSW&@`(`@,($B>)3@B`W-``^&!""^CRP````&]!.&@.#*)2$0XO(,<`T(GP0L +M!`+@NZ7#6#2_I=]G/<(``\"T0V<8- +M+^D:<<]P@`!0WKH-+^D(V<]P@`!$+:X-+^F4V<]Q@`#`$P`4`"``&<0$&[@```,,X?/<(``Y+L@H)8*8`$J<`AR!*<=AL]QH```(&3@$*$!V`<9 +M&(``&0`$\-D$(D!0C"`"B#+R1@`)`-#@@-S,(`*#,O0`V<]P@0"X+CF@B!A$ +M`+081`#B&$(`X1A"`,]P@0"X,F080H!T&$(`2G!(<8(+[^2I<@AU'O",(`.` +M#O*,(`.$X-S,(`*##O1*<,(+K^1(<0AU$/!*<`(+K^=(<0AU"O#/<```,A%N +M"J_D!"&!"@#=).W/<(``6!4`@`KH`-B6N,]QH/[`"?(,;_FIT&"T_X"^C/ +M<(``G`L!@`L('@`*#L_U"'5)`&_DJ7#QP`#8X<`0V<]PH```)"&@'@BO^(MP +MA>CN#:```,"AP-'`X'[QP-8/#^0(=L]P@`"@1Z.`SWC/<8``5#N$*`D/6@EO +M]S`A3PX:<,EPE@A@`>EQR7#I<1(-;_@*'!I,U7"%X#SW"@```(`H#/<*``@$4M +MH,]PH```'QR`+P@?`,]P@`!H*`"`(P@>``QP'P@?`\]PH`"`13`8@`\`(``` +M`-G/<(``;"@@H&HA@`'/<(``<"@@H,]PH```#`6`@>#*(.(#SR`B`ZP(HN3* +M(4(#6@@@!ZEPSW*@``!%.(($(;Z/```((`#8!/0\@@<)7@8!V!,(40#/<8`` +M+,X`@0'@`*$3#=`4I@YO^(MP"B$`@`+TJ7%&".``*'!+::+B#@$-`#(F@G"` +M`(SC0">``(H0#9`=AY\,]R@``<#"""!X$!X`>A +M`8)`>`#8"'%M\&(/``'/<:```"0*@03H`M@!H<]P@``<#""`$($!X.(/H``0 +MH>SQSW"``!P,((`,@0'@#*$Z\,]Q@``<#$"!`H(!X`*B`H%`>$?PSW&``"S. +M`X$!X`.ASW&``!P,]?'/<(``'`P@@`.!`>`#H2?PZ@S``[CQSW"``!P,((`% +M@0'@!:$(\,]P@``<#""`!($!X`2AD@@``!_PSW"``!P,((`1@0'@$:$!V2AP +M%_#/<8``+,X,@0'@#*$`V`'9#_#/<8``K,T.@0'@#J&8\4'82@]OY(RX`=DH +M<`?I0@O``/X-``$$\`CHA@J/ZL]PH```"`*`SW"``)P+#X`?"-X$`-G/<(`` +M\"TCH,]P@`!0WB&@SW"``(@H(K!6"H``?04OY*'`\<#/<(``6!4`@`GH`-C/ +M<:#^"`M:"6_YEKC/<(``G`L]@&3A#@H@!PC8H@[O^@/8`_`*#(_XSW"@```D +M"H`%Z&QP\P@>@-'`X'[@>,]Q@`!0N@AA$P@>``0BON\!`0$!X2#"!P'8SW"` +M`*!'!8#AN.$@P@<"V`#8X'[@>/'`1"(`4S\($0)R"T_X"R"`C#_RSW&``)P+ +M`8$)"!\``=@X\(P@_X\*]`21$0B!#P``__\/@9*X#Z'T\8H.C_HH\$0B/M// +M<(``H$<%@!_TX;@"V![TSW"``)P+`8`1"!\`!"*^[P$!`0$$]`#8`_`!V$$J +M`5'#N<]R@```\?`B00"`X>(@0@`$\)D(WX(`V-'`X'[QP-(+#^0*(X`OH``` +M#!03`""CP8'@RB`B!,0-8N3/("(#`-[/=X``G`O2I\^GT*?`M]2WTZ?/<8`` +M7`S#J0HA@"^``*!'%!$`(,2IZ[@!V,(@`0`"N!:GU:?/=8``'`S=M8#8OA\" +M$,>EW:<*((`OH```(,`0`B!L$``@7Z=">!ZGU[7/<(``X!78H,]P@0`8-\"@ +MVZ?"J<2EQZG/&IBS!-K/<(``7!5`H,BE#HG#IPVIZ"SN+6XN+CL&ABP%;H$H@6)H+@%J8X*;_C`J8H@ +M_P]<&AB@6!H8H(H@F`U8&P`@@-@,&``@"!@`(,]QH```*``9@(.*(!@(`!@` +M($@0`"`;"%X`,Q$`A@0@OH\`P```!?(!R`/H`AH8,`$:F#-(&(`C;1J8KP`" +M`0`!V<]P@`!L*""@:B&``<]P@`!P*""@+'#/<8``+,U-")X##X>+N`^G52'` +M!0"ESW`!`!1O`:7/<`$`Q'$"I0K8%+4`$0`A!MD>M<]PH`"`'#N@`MC/<:H` +M`%``H>!XX'C@>.!X`-@`H1+P0"$``P"ESW`!`#AO`:7/<`$`Z'$"I1#8%+4" +M$0`A'K7/``H<]P@`"@A!3)T`0@^#*(&$%SR`A`_`*8>3*(<$#02]`$\*X +M+X;&'@(0!"&"#P````CFI2$)W@($N$\@00`*E25X"K4'V`?P%2`,(``<0!0# +M\`38`>#S"!2""B&`H,]P$``0$,HA8B#6#>`&^MD!W@QP]KBM\L]Q@``H+0"! +M42&`PP'@#W@`H0':SW"@```0)(#/<(``*"T`@,(B@0`P<*;T"B"`+Z```"#` +M$``@C""#CC@!#0`R``!P,?PC?`L]RI```2'D2`(;/=8``H+N@&0``?1(` +MAJ09``"P$@"`!:>P$@"`(KC$N!6WI!&``*41@0`(N25X!Z7/<(``C*L!@`:` +MZ[A<"8(`ZLDO"-X"SW"@`(```/>6@Y/^('F/_/1&IBS@N:>],]Q@``(WP&!">@`@0\(7@""N((*8`4` +MH<]PH```$"R``-LLN<]PH`"`(02`PKE`P"#`X;E":&2X2"`,`,H@P0`2\@(4 +M@#`-"`0#$'+*(&8`2O<0<@#8RB,&`,HC90#*("4`X+G*)"$0RB(A`!3R`12! +M,!$)!`,P+X5BN.NY$'BK\L]RJ@``!&*""B"`+Z````Q!*P$"+WD*)(`/@`!< +M#`84C`")N0Z\A7DPI0HA@"^``*"[-!G`(#@90"`@@D`5C!`*)8`/H```$)3D +M+!E`(!GR!?8S#)$2([D7\!T,T!WNY!'T12G^`N>[02G!<,(A8@`'W@OP12G^ +M`D$I`7$%\"*Y`_``V0C>+J5!@CP90"`P&8`@Y+K*)B(2X;K*)B$2%PJ>`03: +M`1R"`!01`B&"NA09A"`7#M$1$0FT`P?>4!4"``<*0``(W@T.T!''!2``"G7B +M#J_Z`-G/<:0``$AV$0"&H!T`$'X1`(:D'0`0L!$`@`6GL!$`@"*XQ+@5MZ45 +M@1"D%8`0"+DE>!P9`"#/<(``C*L!@`:`Z[AT#D(`ZLFO"-Z"SW"@```@SW&@ +M`(`7%PI?!L]RH`"`(%*"66$:#J_Z,'D#\#H.C_I*(``0SW.` +M`%P,`1L"`L]PI@``!$"`!]Y!*L$$PKE!*@P#P[Q`*8`#A7B'BR:K&+P%)`40 +M0!U`$5,BP`)`%880#J51)@"`T2+BA\HF(1+/=(``H+M*I!04!Q%`*00!!23! +M`2JT+R&!`0^D.!Q`$<*YSW2``/CP*60-"00`+X6/N2^EA^94I93T3"9`@V[T +M%K?/<8``;.\@@0/@!2A^``H@P`X!X`*X%.`=I4X-K_H4V#2%"?#2#^_C!MC/ +M<*8```0@@#2E!"&!CP-````;]!D(7D;/<*``@"!0@,]P@`"<"Q^`"0H%``'8 +M`_``V(OH#'`3"!\';'#/=8``G`N["!Z`'0F!#P!`````V,]U@`"<"\(=`A`` +MWY>_&_`;"8$/`0````'8SW6``)P+PAT"$`#?F+\-\"<)@0\"`````MC/=8`` +MG`O"'0(0`-^3OU2%SW&``*"[2J$-\,]PH`"`(#"`$H`#WB;P`AL"`@#?E[\` +MV!7H"M[/<`0``1'F#Z`&`-D$(,!#@.#*)N(1;'#@N,HF(A+O#I"2#/`NA1,) +MM`,'WL]PH```$!2`"0A```C>A^9<`P(`"B6`+X``7`P"%8`@SW>``)P+X;CP +M\@HA@"^F```($1$3I@#<02O`)L*X(6A!*\`@4R`$``$I`0%AN4$K`"$2$0VF +M4R!`@5,E`A"]>U,C$@!!+<,4P+M$)0X2(KX%)M004R-#(,P@XH\5\D$KCB;` +MOE$C@*;*(`(#RB`"(Q3T`=C/=(``U%$8%!`0`-R085@"`.N`5Y4R0` +M(!NX)7@%?`'8`!T"()J\K!<`$9"GSW&``&SO(($#X`4H?@`*(,`.P6B^">_Z +M$( +M%!$(E2(-")0##0X%<`@````=WB3P0!>`$$2XP;@!X",(TP#0AP0FCA\````8 +M4@QO^RN^$';*($X$RB;N$<_WN@\```AVE.#*)N(3"/"J#P``"':4X,HFXA@J +M<""`SW"``*"[+!C`!"V@P!>!$*R@![F*N:WPX+@*(8`OH```$*[R"B*`+Z8` +M``@"$A"F`Q(-IE,@@"&`V@0E@1`&N25X!"("!`2Z17A$)0$<#;DE>*EQAB'S +M#PZY!7D&%8`@X[T.N`5Y1"6`$!2X!7FI<(8@_@\5N"5XB+A2($`%$*=!+<$0 +MP+D`'4(@RB*"#P``___*(H$/```0'RZ'K!]$$$$H`2)3(4&$+J<$])2X$*=? +M#9X40!>,$`\,$1@$(+Z/````&"7R$0@>`D$HPP!3(WZ`"/0)W@J^!""#`S,+ +M@`-!*$,$P;LK"]4`%PN1`",('@)!*,,`P;L!XQ<+D0`+"!X"S.0%]@L)E`,+ +M"D4`"-XB\$$HP0#!N0'A(0G5``0@@`\````8_@IO^T$HS@(-"(0#$(<3")X" +M8@X```AVE.#*)N(3"/!0$0$@#H<0<0?>RB9B$@`2`2#/<(``H+LL&``$+:`` +M%8$@K*`'N8BY2I!%>2JP+H"(`'T1H8L(SHSW&``)P+68$`V`D*T0`9H178 +MT1H8L,]Q@`!(%2"!!^F'Z,]Q@`!<#"V)">G#"!$`SW"```C?`8"W"!``0@@@ +M!P'>.>C/<(``G`L`D(8@_`#0X(#`\]P +M1``,\@"`SW*``/SY(.A!$H$`0!*```BY)7A"$H$`$+DE>$,2@0`8N25X10@1 +M`@C9C[E`&D(`*+E!&D(`*+E"&D(`*+E#&D(`%/!`&D(`*+E!&D(`*+E"&D(` +M*+E#&D(`?@I@",EP5@U/]0+P`-X&[L]P@``(WP&`!>@5V-$:&+!J"R_YT`,]PH```)0"`H1HC2&IB_````$*3-AB#_A=P)`NJDS00@ +MOH\```!0!_*\%@`11@]O^@#9I,V&(/F/"?2$Y\PGXI`%]*0:G+\```"`,-C/ +M=Z```"`\'QB0$X8)Z,]P@`"@1P&`R@@O^M$2`;8SA8P6`!`Q"$``%);#N"4( +M%0$!A@\('P"X%@`1U.#*]M(/C_<%Z$8+3_4&\"8-0`($\&8?&)31R0$%K^.C +MP/'`O@R/X\]P@`"@1R6`SW6``)P+P!6`$`0A@0\```((3X63Z&Z%#0L1"*3- +M%PC?`!<+D0.DS88@_X4'\J7-"PC?`I&Z3Z4%Z:^ZL;I/I>^ZT2)AA`3R+-@= +MI1'P$(41")\&+H7F""_U`-H=I3V%SW"``."[U@L@`"&P#X4S"%\$#H45"%$% +MI@J/[`;HL@JO[`#8!/`B#L`!PA6`$`GHSW"``(RK`8`&@.NX7`X"`!"%"0B? +M!@#8K)Z+C*(((/Q>Z"9\HA8@"T#N(%RB)"`\EUSW:@`(`0"(83"-\&/86! +MV&3AC@B@!@RX"(8?"-X'$PB>!P#9P!U"$,VX#J68\0'8P!T"$)3Q#'#\N"#8 +MRB"A![CHSW.``%P,`(O/<8$`U$42Z`+:SW"@```G0*``V`$:&#`%BX"X!:L$ +M@84@`0@$H8#="/`$@4+=A[BJ"2``!*'/<(``H$<%@.NXT"6B$=`EXA'/<:`` +M`"BP&5B#`=@!&1B``(L$Z!H,C_X$\'()0``A`X_C`]G/<*````PFH.!XX'C@ +M>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!X)J#@?N!XH<'QP'X*C^-$P!7= +M4PC>``C8SW>@```D!*=J"0``SW:@```H/0@0!3*'$X`*X@;@`'@"0$H`$:&#`"AP\(GP!>"N_WA,""Z*EP(PA1!<]P +MH```)`*`!,'BN,H@80((#.'CSR`A`PX((``$P`C<:P*/X_'`^@FOXP38H\'/ +M=:```"C/`!+>"?#/<(``'`P@@`:!`>`&H>K)40C>`\]PH``` +M(%N`P!```$#'(A4$EI"#`GH1@S"\0"@%!!*#`-FS@T$H!@3//W"U2$`-L*\,]P@0#P-O`@S```'P!# +M`>/Q"T2``-@"&AB`HY$+@E>`"G\A(!MO3)!7DO*$$`3B""!YP5`!`0?N`/P3R!` +M)P"G`)6&(/\,0P@1`D`A`"($IQ>%-)6?N(8A_0]'N1ZY)7@]E@02@B`\>1VY +M)7@[EEEA/'D8N25X`Q*!(%:%66$]>12Y)7@`I^K))0B>`L]PH```(,]QH`"` +M'`09@`_%[H-4&X`!H:'-`:$8A0&AHQ*KC)N`BQ +MSW*D``!&"X)3($,#+KC-N!.Q#()PL5,@0P-QL2ZXS;@4L1."X'\9L>!XSW"` +M`!P,(!""`,]Q@`!/'`?@U/XP#=SW*``!R[0"(!![NRSW.``)P+P)// +M=(``7+O`M-"#O;*\L@.B'PY?$J6BSW6E``"!`84$)KZ?````P`2B`_("A06B +M`-T/\,]P@`!TNO`@3@,([BG8$KCP((`#%2%.`P"F`>7G#921#I.@$PT!&K*O +M>*(3`0$*M"]X"[3_V`BX!'TD>$BX#K2D$X``2+T6M*43@``7M,]PI```@`"` +M&K3/<(``"-\!@*VTA^A(<'C9?@W@`<3:`_"B"0``D@D``"D%3^/@>,]T@``< +MNP"D(:0!V!^T?K3@?T*DSW"E``"!08`"@,]Q@`"LT`VASW"``)P+$(`.H<]P +M@`#8T%4!X`5,H?'`$@@``-8/S__1P.!^X'CQP((D`C&.P``<@#\``'D1!!R` +M/P``!R`('(`_``!)$0P<@#\``$H1$!R`/P``2Q$4'(`_``!,$1@<@#\``$T1 +M'!R`/P``BQ$@'(`_``",$20<@#\```D@*!R`/P``!B`L'(`_```((#`<@#\` +M```@-!R`/P``DQ$IV1*Y$]K/EZ@&\*%H4:A2!0#,1'"![L$(HP/````X"V\!+R%>\.Z17L3PGR@7:`4P!;" +M`:$5P-JZP[@;N$5X!Z$7P(`4`C`(H1C`QKH)H1G`"J$-GQP"(+;^,,VJ/! +MSW&``,CDH@YOXXMPSW"``)P+,(!+"5\"SW.``!R[!(,$(;Z/````P&#`0B@" +M`@$<@C!"*`($`AR",%BX`QP",`_R!8-"*`$"!1Q",$(H`01AP%BX!AQ",`<< +M`C``V`/P`>`/>*D(TP#/=H``7+O/=(``C+H5)`(0%'XL@F&6>6$LHL]Q@`#, +MNA1YK9$+#<,0;;$%\*J1!PM#`VJQKX)JEGUEKZ*SD0D-PQ!SL0;PL)$)"T,# +M<+&R@FV6?66RHEF1"PK#`'FQ!?!6D0<+@P!VL0#9CPD3@=1H-7X5(0(`,R2# +M,)YFH(::8GUEH*:$$LT`"PW#$(0:P@!X$LT`"PM#`W@:P@`!X2]YYO%]`F_C +MH\#@>/'`!@I/XV8)(`,(=<]Q@`"<"P^!SW:@```DL+@/H0J&`^@"V`&F`-G/ +M<*````PLH`H(0`&."D``"H8$Z`+8`::`Y7`)0@#"#J`$`=@R#`_Z)0)/X_'` +MSW"``%@5`(`-Z`#8EKC/<:#^/`'/`#:#R("`,]S@`!<#`V+17@-JP7I +M#HM%>`ZKX'[QP$()3^.BP7()K_>+<`HF`)`A],]P@`!0+`&`SW&``)P+;H&" +M(`(`<'`EW,]RH```)!Z"RB2&$Q!S%MX`P,HF`1,-"!X$`MBZ&00`'X*V&00` +M@.9]"2YP[D`V`\@ +M0``OA@MY%O)NAD\C`0`NII#KP!(!``0@@`\``!\=`>%"(`"`P!I``#(([^?* +M(&(`L@BOY_*FSW>``'14J@CO_@"'"B8`D`OTSW"``%#P%B``!""`8'D`APAV +M"H4#Z`+8`:40'8`?``#_?QO8!Z6"#8__SW"``.`5&("`X.P+P@$1#I$6SW"` +M`!S=_@C@!`#>H@VO^,EPZLGIN+3RSW&@`(`@,]S +MH```($&A&X-">,@3`@!">`&A`(<"@`&AP:&:\"(++_\*<`HF`)`O\L]R@`#P +M-P""SW6``/`X`=]%"!$"37%$(3Z#'O0DN<.Y`-@/($``+X4K>!;R;H5/(P$` +M+J60Z\`2`0`$((`/```?'0'A0B``@,`:0``R#Z_GRB!B`+(/;^?RI0HA@"^` +M`'14`!$`('H/K_X*<>H,K_@(=?H/K_X`WXCES"7BE03TJ78G\/T-D)05[JH- +M```*)@"0&/0`$0$@SW"``)P+1)%`L$.!)(%!H"*@1@^O__2P"/!B#*__Z7;/ +M<(``G`OYH`\-D1;/<(``'-WB#X`$J>Y!Q\]UH```)`*%`-Y!P"L(GP`2#V_W +M@<`*)@"0#?0!PN*ZRB"A`LHA@0\``/X`R`BAX\\@(0.-[@38!*4;V`>ESW"` +M`.`5&("`X'0*P@'J""`&`-B`YM;T`=G/<(``7+8@H/D$``#@N(@$`0#/=8`` +MG`L.A;85`1$B>&2XN!T$$`^%\;C`?D;TSW$"`@("!")`8`#<$/`O*@$`3B*# +M!T$KS0#/`"&`?X``@#TTJ-"HSW"!`+@N@@DO +M_\R@SW6``)P+&:45"-$`SW&``$@5((&$Z=FE`-B'"!``[@C/_@AV&@@@!@#8 +M@.9N]$0B/M,^]$UPAB#\`XP@`H!0W,P@`H,V]`^%:0C>`L]P@0#8+AJ(+NC/ +M<8``C*LA@2F)40A``")X+R`)`&&XA.`#VLHB!0``V`7P@GDO>22K`>`Q"),` +MSW2``$#P`""##X``/`PDB_`DC!#C#$20`-GO\9X/X`4`V%8-S_ZS`P``G!4` +M$,]Q@`!$%CIP1"@^!S`A0`X`W@GH`@WOZRIP`=]*((`@Q_"ES24(W@$$(K[O +M`0$!`0SR+R"'"HP@`H8(],]Q@`"<"P^!F+@/H6X+``"."J_X"':`YC'USW6` +M`)P+#X4]"!X$/(74V'X(H`&I<@AW*@PO[0#8`)6&(/\,$P@1`L]Q@``LS@*! +M`>`"H13O&@L`!GX/;_@!V`[POA6`$,]Q@`"4NP"I%)7#N`&I#I5$N`&Q@!4! +M$`:!`>`&H;X5@1`A"=\!@86<%0`04B0,$$"52B0``'25P@MO^5,D!1`/A?.X +MN`B"^1.%".C/<(``H$!2P0`"&$ +MZ'(*``$)\`#8SW&@`(`<&:$PV!RA4@R/_P^%*0@>!A#8I!H.BJ#^_K`=@(=Q00@""!X,PG(I`8"2+PRB#"`^(/S^L(<4`E +M`!,""R`"Z7(*(`"@./+/<(``2!4`@*_H`-\`E88@_`",(`*`M?1,(("@L/2^ +M%8`05@TO]@#9A"@!#``AD'^``.P6`!`-(`CMSW&@```@.X&F#<_KSW"``!P9 +M!H`:Z$$-E1,S)DUS@`!\XT`G@'*T>`!XS16`$-+H"0B1(!7>SO'/<$0`#/(` +M@(#@D`K!],;Q`-VI<`GP`-T"V`?P:!``('CH`=@`W0'::!B`("4(D`"0[QT( +M4`#/<(``2!4`@`OHSW!%`#0X&8@)"!X!`-X#\!7>M>[/<(``++];H,]P@`!( +M%0"`)^C/<$4`-#@@@`#?D+\Y"1X$SW!$``SR`(";Z#H/H`=V&'`H`$((`/``#_OX^XH1H_K*G#/<(``2+H% +MB$0H/@O/<(``K+DR($$.*G`1(0"`U`_"`3;PI,T`V5<(7@//<*````@"@,]P +MH`"`12V@SW"@```?'(`O"!\`SW"``&@H`(`C"!X`#'`?"!\#SW"@`(!%,!B` +M#P`@````V<]P@`!L*""@:B&``<]P@`!P*""@[@O@!0#8(@]O_P#`"';)+<`HE`)`%\JEPW0$OXZ'`SW"@ +M```E(X!3(8``!"&.#__`7W_A"-$!37$/AW4)G@,$(+Z/`#0```ORSW"!`+@N +M#(`TZ+X)``$%?C#P!""^CP`*```C\DQP`0B?`$QPX+C/)F(1SW&``)P+#X'Y +MN,\F(A+/)N(2SR:B$QCT!2:`'P```&O2@00FCA\"````4B9.%"J^!7X*\(4F +M'!`(\`T(7@7>""`!R7`(=L]P@``\#!Z(Q+@8N`5^02X`%T$N@A6&(/\,P;H% +M>L]P@`#@NV"(4R/^@,PB(H`=\@/9%KD$)D`0+PA``,]P@`"@1P.`2WC*(($/ +M```9-)0*8>/*(8$#"?#@N!X\`%!=@0\`QP%PC>!2QP$PB>`\X((```WEH-X`4% +MV%X,+^,&V$T.%1$,;`?FQP-0@?``QP"PA>!2QP-0B>`PQP`-FX``V:)[SW"``)P+/!`$`,]PQ>Z# +M7)(*8`6I`#:SW&!`"PW +M%7G@?T"AX'@#VL]PH```$$Z@`-O/<8``*"U.H.!_8*'//'`S@_/]P#9SW"@`(`-(*`<&(`/````"%8,C_46"```BB'$ +M`<]PH`"`?BB@T<#@?O'`X<7/<*```'P`@/_9,+A3(,T`!]@*N`2Y'@JOYE#: +MSW&@`(`-HZ$#V`*A@0;/XO'`F@P`!0H/S_;/<`\`0$(."X_UT<#@?@AQ`-@( +M=`_P4VQ5>L=R@`#LR6""#0M?`DB"4''/(`$#`>3I#!24X'[QP,8-S^(`W@]] +M'O#/<```$C*V#P_C&/`O*$$#3B""!T]Z$"6-$!-J%7C'<(``[,D@@&B`KWT/ +M)LX0U0E?@HPCPX_F\^KM\07OXL]X`-D0\"\K`0!.(X('3WH0((```[I5>L]S +M@`#PR4)C17GRZ.!_*'#@>/'`1@WOXH#9"'?'<(``5,DZ<""HD.?*((8/``!Q +M`,\@9@,H#R;CRB'&`P#>!O#"N`/H`!F"(P'FD.;H``8`MF_5?<=U@0#80`"% +MSW&``.S,]7E@D0#:#R*"`VMZW;@`I0/RGK@`I2&12WD$\I^X`*4S;S5YSW*` +M`.S)(6(E"5X$#0@>`D$HP0#!N0GP#0B>!B"-1+G!N0/P`-D$Z9ZX`*7/<8$` +MV#_V>2")"PD>`)ZX`*5?")\'[W@`V6H.[_4:<80H"0\`(8!_@``@.RJ`#P_1 +M$P*`A.#*(0$$`(7/<@`$``$O"%\"%>E+>-$AXH71(>&`"?0;"1X&!""^CP`` +M`!@'\OZYSR#B!\\@H0<`I00@OH\`!``!D?/HN(OUP[B*\8D$S^+QP"X,[^*` +MV+0<"+#/=H``[+L`AB*XP[@+")4#3B`-!`/P3B`-"('`*VUV"._G`KD@AL]S +M_P#_`$$I0`=`*`("9'H8N$5XBW*"(@@`M7I^&A@`$VE!*`P&0"G.`L5\A'LH +MN!NY)7@$((`/`/\`_V5X?QH8`(MVR7#6#R_K3-G)<(8((``R;1D$[^*SP/'` +MV@SO]P+8%@@``-'`X'[/<:(`0%#P(0``X'X!V<]PH@``4#N@.:``V<]P@`#L +MN^!_(*#QP,]SH```(#N#QW$``#!U&X,`VC!PSW"B``!0&(#*(F\`P;B"X`'< +MP'P)")``/'`%@O/X@AW"B&`+Z(``%!H +M$0T@"B*`+Z```"!L$@`@&G$`(),/```P=4$IC@`V\.H,+^.*(`P",/`$%P$4 +M%2%,(T$I``9`*0("17@$((`/_P#_`$$I`@(8N45Y!"&!#P#_`/\E>`"D`>5A +MO@/NSPT4E%,ES9`2]&P2`"!R<`#88!$!(,H@;P!2(0$`X+G,("&`]/.="1Z` +MZN[/`@_O_P#=#O#6 +M#N__J7`%[Q4G3!,`I/`@02,!Y3!PP'[I#122H@OO]P+8I0+OXLEP\<#AQ<]R +M@``\P0""#.C/<8``7`P-B:&X#:D.B:&X#JD`V`"B`@]@``+8P\D9"%$`SW5% +M`+PBH@GO]@"%`!V`'ZVK_LJB"^_K#MB>"P``:0+/XN!X\<#AQ4AS`!*"L)AQ +M`KI4>L]Q1`!PP,]T@`!$_:^,SW2!`$`W`KVT?:1D46$<%(40SW1$`&S`0F1* +M)D``P+J!XL(F@@$&"J`%`MK/<*```"`[@,]P@``/'`>@G/X@AV&@OOZP[8L@OO^`#=\@J/['X)H`&I<,]P@`!$ +M_=(,8``/B`784@FOZJEQ5@Q``!(.8`#)<*T![^+7&EBS\<``V0+P`>$9"94! +M$FD4>,]R@0!$-P!B[P@>@`#8!O`R":`!`-@!V-'`X'[QP-X(S^+H'`BP"B6` +M+T0`>+L$%8`@"B&`/X``1/T.$8TP*':B>$D@P`!!P)8/8`!*)``@!!6!($+` +M#PER``X1@C`1"8,`SW```)`GO@H/X\]PH```(%N`SW.``!"\SW"``!R\1,`9 +M#E$0SW"``!2\`(`-"%$`!,!`HT"@%!4!(`3``(`*N3A@!PH$`$"C((,P<]R1`!LP"%BX+G*(&$`VG"^""``J7`0%0$@.G`/ +MZ0`B0"0;"04`LN\4%10@2B(`(`':SW&``!2\0*$2;10@&``*)X`O@0!`-\]P +M1``XP$7``=BR#B_K`L$(=D`H@"`4>``G$R``&X`C&!Y`%+@5`":$Z`C8(AX" +M$(#GEP+0>OXJ;` +M\<#AQ0'=\@M@`*EP`@G``0GHJ7"2#6__J7'/<(``/,&@H&4'C^+@>/'`W@Z/ +MXK)HM'T`)9`?1`#XOW00`"#/=D0`>+LE;D.&X+C!*F$!TR(A`,`B80`1\AT* +MW@'/``0@@`\?`/[_A@K/ +M]11X'V?/<$0`<,!R"6_ZJ&`5"%$``X8/"%X!=!``(`D('@`*Y\$&K^+I<.!X +M\<#AQ=?)-P@>`,]R1`!XNP'=)(JI<'(/8`5#@M?)H+C7&ABP`@M@`*EP=@C/ +M^+H/3^S/<(``#+R@H)D&C^+@>`D`(``!V^!X\<#V#8_B6G"Z<4AWC@D@`#IS +MLFBT?1IPQW6!`$`W"(T`$H&PP(4P<$HC0"#"(\(D`K@4>,]Q1`!PP!%A"B2` +M+T0`;,`P)``@'!:%$,"X@>!*)D``PB:"`4IP`=I:`!V'H/+_7`>"$%C^+@>`#9!/`!X2]YSW)$`'B[1(H7"8,`4FE4>L]S1`!P +MP%)CY0B!@`/PBB'_#^!_*'#@>`#9`_`!X1<)E0$2:11XSW*!`$0W`&+Q"!^` +MAN$`V.!_RB!%`,]Q1`!LP""@SW!$`'B[X'\$B.!X\<#AQ0AQSW*!`$`W`-T# +M\`'E$FT4>`\-M1$#8@"#]0D!@`3K$0V4$<]P``"2)UH.[^*I!EA`>$&@BJY(GC@?PJXX'CQP,(2`;;/<```C"?N#>_BPQ("M@#8 +MT<#@?N!X\<#"R8#@8`KB_\H@H@#1P.!^X'CQP.'%SW*``#S!`((,Z,]Q@`!< +M#`V)H;@-J0Z)H;@.J0#8`*+#R1L(40#/=44`O"(R"Z_V`(4`'8`?K:O^RL]P +M@`#PNUH)P`,B#"_K`=@`V<(:6+##&EBP`!I"L-<:6+#/<(``?+8@H(X.+^L! +MV,]P@`!$_<8/;^<4V<]P@0!`-[H/;^=(V>X,K^L.V+4#C^+QP`X+C^(;<`#? +MSW!$`'2[6G#@H`#+SW9$`&S``K@4>`!F2B%`(,"X0B!7@,+)RB=B((/@"B2` +M+T0`>+L,%``@PB%")!UX4B```%,@$P`*)8`O@0"X+A05@"#6$AFV0B!0@`'= +MRB!B(*(.;^NI<``2@;"8<`*YZLD*)H`O1`!PP#1Y-"9,("\('@=`*P$B!2$` +M!$`I`R0%>T`O`B80O,]PQ>Z$R*EQ97HK<](-X`0%)`0#`,LR:#1Y(&9%"!\` +MPLD]"-$`#!0`(#4(7P`4%8`@+0A0`-;)!""^CQ\`_O\0\C0F0"`9"`$&`!I` +M(P/8PAH8L,,:V+/^#*_K#MA5`H_BU\F`N-<:&+`!V,(:&+``V.!_PQH8L.!X +M\<`>"H_BSW5$`'B[8X4H=\]V@`!$_4V.#0M?`200@0`3"5``%0M>`200@0`< +MB`T)`0`!:@]Z#:X$C1$*`@"R",__@."D#\+_#8XNCD\(00`$C4L)`P#7R4,( +M'P`%A<]Q@```<]P@`#PN\H/@`,+ +M\.EPD@CO_P#9A>C7R8FXUQH8L/$!C^+@>/'`>@F/X@AV*'4:`AW +M0"6`$D`G`1)V#N`!!MI`)0`40"G`(;/0$<`C#V"R_Z*'!@P`#8`AP",`,<`C"O?0#!J7`& +M""_KR7(2#2_KJ7!-`:_BH<#QP,X(C^((=RAV2'4:<]X*K_\$V`HA`(``AQS: +M0*`8V`P?`!0"I\&G`(4!ID&%C;A#I@&F+RA!`$X@@@=/>%"N$"$"``+R!^K/ +M<```"C.*"L_BBB#_#^$`K^(*IO'`U\G/2<,"L+BU\G3"!^`#@@``-'` +MX'[@>/'`\@]/XL]U1`!XNP650"51$48@@0.&(/X#1+@;>"5X+R`((`#86G#/ +M<8``@+8`H<]Q1`!TNP"A`X7&C>6-2PA?`1CN\7;*((4/``![)\HAQ0.P">7B +MRB*%`R2%"NDP=LH@C0\``'PGF`GMXLHBC0,DA0OI,'?*((T/``!^)X0)[>+* +M(LT#`,O/=D0`<,`"N!1X$&8*<5X.[_\!VL]PH```(!N`SW=$`&S`U!H8L`38 +M5@\OZ@#9`,M#A0*X%'@!9^"YP2IA`=,B(0#`(F$`#O(7"MX!$&:!X,P@HH', +M(.*"`_0#V@+P`-HR(8`@!"&!#Q\`_O\*N,]R@``8O`"BQ@DO]=8:6+``RS)H +M-'D@9^"X`]@+\M;)B.C/<```!BC>"._B,68"V,(:&+##&IBT)0=OX@#8\<"V +M#D_B&G#:"*__!-@(=L]U@`!XVP"%'-D@H`#+SW%$`'#``K@4>)H)+_H(84HB +M0""`X,(B@B0*)(`O1``XOB04`2$*(X`O1`!8OD`C`"4X8`.E&-@"I<]W1`#@ +MP@"W"B&`+T0`>+M`*H`@%'@`(0$@*('AI2)P"8`AIP.G+RZ!$TXF@!(SW9%`-`W(FH@ +MIA;@`:8`EX#B.&``MW@(`?45)(`D59`A"G(``=D4D$`F`Q)`HT`C`24X8`&C +M`)<"V5A@`+<,$0`@'0B>`0G8%B9"$`"BSW"``,0O`:(`EP'A">``MS(4`"$? +M"%(`,!0#(18F0A``HD`C#"6;8V&B0)/'`X<4)@HP@0H)(=3KRPA(!ML,2`K:" +MX0'84@X@!0#:<05/XO'`]@Q/X@#>$O"R;K1]QW6!`$`W`847"!X` +M((4!V#X(+^L@@0&%H+@!I0'FWPZ4D34%3^+QP+X,3^((=P#>%O"R;K1]QW6! +M`$`W"(T;#P$0`847"!X`((4!V`((+^L@@0&%H+@!I0'FV0Z4D?$$3^+QP'8, +M;^("N,]QH```(&P1$``4>``@D0^!`$`W"!&-(+3ERB"*#P``CB=4#JKBRB%* +M`Q)M%'@`()(/1``XP#@2`2'/=T0`U-TO>!8G3A,N#^_Y+*X-KL]Q@`!\M@"! +M`-H.KD"ASW&``("V`(%`H0^NU,D`W`(@`Z`3>"R_J`-DA!$_B +M\<#*"T_B*'4`$H&P"'>TX!XSW%$`'B[X'\$J>!X\<#F"D_BFG"Z<4AV&G,`W\]P@``, +MO."@<@ZO_XIP.G"R:+1]QW6!`$`W"(U`A0*X%'@<$H4`"B*`+T0`<,`T(@$@ +MSW)$`&S``&(*(X`O1`!XO\"X@>!*)D``PB:"`8IPZ7+)<_X*(`4*)$`%`84+ +M#E`0S0B>(:&X`:4`RP'=`K@4>'8-[_DR(@`@SW9$`'B[@.#`?7(3`:?/<$0` +M;+X"O;1]&6''=40`F+M(C4`F`!;2".__`=M(C0'8`-GV#>_J#R&!`+@6`!:" +MX%0*+@'*(&X`)@N/_\]U@`!$_0\=0A3:#&_K#M@-C8;HSW"@```@&X`!I02& +M*NC/`!X%=@"\!38C0%/XL]P``"1)P8+C^+I\?'`_@A/X@'= +MV@OOZJEPT@RO_QIP"'?7R88@<8\']+8,C__#$@&V+PA0`,/)&0A1`,]V10"\ +M(FH(;_8`A@`>@!^MJ_[*PAI8LP#8"'7#&ABP;_",)Q"0Q?:,(!"@&_<;"5$` +MSW5%`+PB-@AO]@"%`!V`'ZVK_LJ.#&_UULG/<8``@+8`H0#8UAH8L`/9PAI8 +ML-WQE0E5`3,F2G"``#CC0"<``38PQH8L`#=SW:``$3]#X[/<8$` +M0#<"N!1X`6$!V!(*[^H@@0*F,?#6$@&V`-J(Z0/8PAH8L,,:F+`G\"\I00!. +M(8`'3@GO_]4:&+##&EBSSW$#`+BSSW"``'C;`-H`VX((+_9*)(`!SW%%`+PB +M`*$+\`38PQH8L`#=!_!/V-H)K^('N`'=.0!OXJEP\<"Z#P_BU\F&('&/!?22 +M"X__%0A0``'8PAH8L`#8PQH8L('PP\GW"!$`SW>``$3]#X_/=8$`0#<"N!1X +M`&4*(H`O1`!TNP`0$```$@`@Q0@0``#+"B2`+Z```"!2:%1ZQW)$`/B_/8(* +M(X`O1`!XNX"Y/:*`VL]Q@`!\MG((K_]`H3IP"KC/<8``&+P`H0^/U!(!M@*X +M%'@&93)Y;!0`(#A@`>`FABJX`GD,$P`@);@N""`%P+@*<"06@1`!V@#>`@FO +M_\ES#!,`(`T(7@$N#L_T&?`!V&(*[^H*<:X-S_\(<4(.K^H!V"^/`KDT>3UE +M`*48&$`$;!0!("*@`86`N`&E`=A^#J_J"'$`&H`C!_`#V,(:&+##&ABP8@AO +MZP[8`=CQ!@_BX'@!V@3P$"#``!OH+RD!`$XA@P=H<8`AP@&4X\HAQ0`"N3`A +MC`^@`!@L,FLP(8$/H`"T+B]Y,'3`>N;J`-@"\`'8X'[@>/'`X<4$(8*/\/\` +M`,]UH```,`7R-+IM'9B0%+C3N25XE!T8D`/P?@V/]I05`);["-Z'K08/XN!X +M4FC',]RH`"` +M+0J"SW&@```P3R!#`HN[\+AJH@'8PB`!``FX12!``;09`(`*@L]R@0"`>"$( +M'@#/<($`@'DP&A@P62(`"#$:F#__?___+QH8,`_P0B(`"#`:&##/<($`('`#9$O`O*P$`3B."!T]Z$""```*Z +M,"*"#Z``-"_"N@\A@0`O>?#HX'\H<.!X\<"B#"_B`-KCB,]SH```,"&(#R+" +M`P80D0`2;\=PH``T+P`8@`\8`0``DA,`AE)]I'B2&QB`.A,`AL]V@`"4**1X +M.AL8@`"&I'@`I@&&(N@5)E`0$!``($MXRB"!#P``GR%,#F'BRB+!`Q`0`2`` +M)X`?@`#D**1Y$!A`(/_9(*@#AJ1X`Z85)DX4'(:D>!RF=00/XO'`$@P/XL]P +M@`!8%0"`">@`V,]QH/[(`W((;_>6N`#>"B"`+Z```##/=:```"[5I0_?"+\# +M\"(+C_83A>1XC"`0@/OS!!B8HP/P#@N/]A.%ZWC]]24$#^+/=*``@"Q8I'FD +M#+B=N)^X!7DWI.!^X'CQP*H+#^((=HH/[_\H=,]PH@``@`@8@`]X!,X`SMR!H,]RH@"L;""" +MSW``_O__!'D%(8$/S@```""BSW.B`*AL((,D>`4@@`\>`0```*,`@HHA.``D +M>(5X`*(`@R1XA2"$!P"CX'[AQ<]RH@``@`""BB$X`"1X5MVE>`"BSW2B`,!L +M`(3/(4@`@(`I`"#)'@%?:"C`(($((`/X/__#P4@@`\'``#@`*(@ +MA,]P`/[__P1YD[F7N2"D((,D>`4@@`]T`````*//<:(`-&T`@88@PP]%($`! +M`*$"V<]PH@"`;"F@X'_!Q>!XX<5\V,]RH@``>,]QH@``=`.A!*'KV`6A!-VF +MH:BAJJ$)W$P:&(-,V,]QH@"`=0&A/-MEH0'8$J$RV2.B)**MV26BIJ*HHJJB +M$*((V3.B=]D]HD+9C!I``$P:&`-(VL]QH@"`>4&A9:$2H>!_P<7@>##9SW.@ +M`(`<.Z,#W,]RH```&!0:&(,!V`&BB!H8`P#8&:,\H^!^X'CQP(X)+^)$*#X- +MI,%*(@`HSW&@`(`<>G%L&8`$`-F:<<]VH```%""FSW"``""_`(`*(``G`"!1 +M#L]W@`"<"P`1`2%,AU,A@`!`(0TAU[I1"-$`SW"``$@5`(`)Z*H+8`8J<(#@ +MRB`!!2_R#X>;N`^G`A&!(#07@!!`(0(E%0A!``IPJ7'N"R``0"<#'`W9&O`2 +MAY&XDK@2IP#8%_`!V.RYPB`!``79%GD/AYFX#Z<`A45X0,`!A4'``H5"P`.% +M0\`#X2&F`=B(Z`^'E[@/IW`;@"03\`#``]D+I@'`!-H,I@+`#:8#P`ZF)Z:X +M%P`1`Z9D&X`@*:;Q`"_BI,#AQ>'&SW&@`(`<(-I;H58@#`0IA*+!BPE?!E<) +MW@$QB`7:([G`N39ZSW.@```4`]DSHRJ#C>)!P1#=RB7B$084#C&,)L.?"?0$ +M%`XQT77,)NJ0`=U"]@#=Z^VE@"5]JZ.QB(8E_!\8O:5Y.J`'\`W:)8#/`+:,H@"ZC`]DGHW`0``$#HPF$F;@)I*+`P<;@ +M?\'%X'CAQ<]S@0"X+BR#.>DVDS?I"'&&(1P`3R%"`@Z3BKK/`<]S@0"X +M+E"3+Y,0ND5YL9///'` +M?@_/X4QP_P@?@4$JS4#`O0:]3R7.$TD.GA'/<(``O`OD@"6``-CP?[H*+^(0 +MVL]R@``8OV"*SW*``""_1"L^#4""Y7@G"+2B0`+00O/A4*(H`O@``@OP`2`R`T(T,.2B4``,*[$0\R%`\EQ0"O +MAI>]KZ8;"@$`"B&`+X````"$XP'=PB5!$Q>]#X8<\`0E@(\``/P`T21BEP?T +M@.#1)&&7`-@"]`'8"B&`+X````"`X`'=P'T/AA>]I7B$XP'=P'T7O:5X"R!` +MA`^F<_3/=8``4/'P)<000"F'`P4G#0$8NJ5Z,AN8H`T+D0"B"J_HZ7!A\(8E +M?XT@\L]R@`!<#`**F^C/<8``'`P +M`A"X%@`1PQY"$'*XN!X$$,]PH`"`'#N@_@DOX@+8`-C/<:```!H!H00O/A4` +M$@`@)W!!@``@3250H4*``"!0)5&A0X!2H02`$Z$!A0*A`H4#H0.%!*$0$``@ +M!:$#\)>X#Z8/A@L@0(0-\L]Q@`!0\;X6@A`@@1BZ17DR&UB@L[@/IG4%S^'@ +M>/'`,@W/X:7!"'<"BRAV>7"@BV3`$1Q",P`2!`$"$@4!!!('`0@2"@$0%``Q +M!A()`4%P+R8(``"1[@@@``<@@`&`<"\D"``!EMX((``'(``!H'`O)0@``I;. +M""``!R!``>!P+R`($`.6O@@@``<@``(A<"\G"``$EJX((``'(,`!07`O(0@0 +M!9:>""``!R!``L!P)I80>`=Y/'H/N45Y`"$"`5!Y`!R$,$>61WD\>@^Y)7H` +M(D$!,'H"'$0P7'D/ND5Y`7$P>@0<1#!<>0^Z)7K@@`B +M00(('$0P,'I<>0^Z17D983!X"AQ$,%,E@1&%N0BY)7V@MR"6)W@<>`BX!2#` +M`@&W`,`!IP'``J<"P`.G@03OX:7`X'@/>DBX#WC/!_P<7QP"8+[^$(4>)&(SW"``'[>,B#0`-"*!.QH$H$`.O`3;A5XQW"``.S)"PD>`#V( +M`O`\B!9KM6D=9<=U@`"`WL]WH```!(2',LA`XAMX0W!F$``'F&!HN!.G-++/ +M<*``0`0DL(J5E;**E82PBY66LHN5A+",E9>R3)5$L$V51+!.E42P3Y5$L%"5 +M1+!1E42P%B&``\=P@0#81'5XH(@&NP6Y>6$`(8X/@`"`WA#8SW>@`(`<&Z?" +M#N_A`M@#V!FG`=C/B+),NLB"3A'D/"0$# +M*(,GHC*3+K(@D`"3#+(!DPRR#I,,LA23#+(+@P:B#(,&H@V#!J(LLN!^\<": +M"<_A&G#@B`&0LV]:<+5]QW6``.S)0B@.`L&^#PB>`Q#9W:T!V`3P`-@!V=RM +MNG`!$)$@%B;`$\=P@0#81``IE`,5(%,%&PK?(,]P@``,]P@0!0.``8@`^@``!,!!B` +M#Z``!$P(&(`/H``(3`P8@`^@``Q,SW*!`*0T`*+/<4`````AH@`A@`\&``"` +M`J+/<($`%"T`&(`/H``@3`08@`^@`"1,"!B`#Z``*$P#HL]P``````2BSW$% +M````.&`%HL]P@``PW@`8@`^@`$!,!!B`#Z``1$P)HL]P"`````JBSW$!```` +M.&`+HL]P@`#$-``8@`^@`&!,!J+/<(`````'HL]Q`0``@#A@"*+/<(``+-X` +M&(`/H`"`3`RBSW"(````#:+/<0```(`X8.!_#J+@>/'`R@^/X0AV*'<:<@#= +M`_`!Y1T-51$2;11XQW"!`*0T(8#Q#D20`H#I#@60A>7*("$`SR"A`\HA@0.8 +M"2'BRB+!`Q[O`KVT?<=U@0"D-`&%$0X$$-EG#0Y%$`*%$0A%``'8CKC)<6X) +M+^+IERO@QOZ`HD``2U!X_ASW"@`(`P`H`1"%\"BB'?#\]PH``` +M32"@X'[@>,]QH`"`3!B!1B"``ABA"0```.!X`-G/<*```$T@H.!^\<`6#Z_A +M`-K/<*``@#"B@,]P@0``<,]Q````$"H/S__/=D````#/<08``(`;#9\2SW!& +M@`!]H(#)<`X/[_\!VLEPJ7$"\,EP_@[O_P#:.0>/X>!X\<#"#J_A`-K/"EH"WD`V<]P@0#0-L6`X<'/=8``G`L/A<(D`1-;"-X"#H5`%8$0'0@0 +M!8SL1+G!N80N"1\`(8!_@`"@/!C@*6!/(4`"SW*``"!'?((1I<$5@A`D>T2Y +MP;ED>CIBSW&``*3I]"&!`+(=1!#/<8``M.GT(8$`6?#/<(``7`PBB"3I$(4- +M"!X"4R""``3P4R#"`,]Q@``4VR")!^D$((`/``0`&4#`,/`'[,]P@`"L[4A@ +M*?"$+@D?`"&`?X``H#P\*['0D1!6>(*(AP<$#`$/`&[,]P@``D[VA@"?"$+@D?`"&`?X``H#QH8&#`(,$`P#QY +MPKG/"Y +MSW"``!0)!MD$\B"`AB%_#D*`1B*"`45YH+DBH/H+(`0!V`"%+R`#``"EX02O +MX:'`H<'QP$(,C^%:<(8@_`.,(`.`.G%(=A;RSW"``#P,'H@A"-\!`[@6>,]Q +M@`#@L0!A!""`#P```!`%((`$+R(((!#8SW>@```@/!\8D`HE@"2&)?P@BB<" +M)14-P25*)@`HSW6``!P,-!40$0_P`=E1(8"FSW6``!P,PB%!``[8,A40$14@ +M5@`AED`@`"4/"$4``B$!!"\C2"`#\$HC`"#/<(``%-L`B(#@Q-S,)0*C(?($ +M(;ZO``0``0[R42&`I@'8PB`!`!4F`2#/$NHL]PH```"`08``6#AD`K`21(EC"\%)40N@(@`R`J<`4A@00:#F`$A7I. +M"@_WR!(#@RB`,!3&'$'@O"$0``X8HEC"X$+DE>`(:&#"@V`&G +M1!\`%1258KAB! +M`>`7H>8,[_8"V`#92B4`(:3-AB#_A2'TC"(#H1WR'PL1(,]P@`!(ND6(SW"` +M`)BY1"H^"S`@0`X?"%X`I!J`8H=GQI!I^EQ%-J""F`&"B0`!`L('@8*<#CPR\G/<8``X+$0B`/:`[@6>`!A!""` +M#P```!#/<:````A"H84@`PD`&`10`!@$5(HB_P\`&(!0`!B$7P``__]$A0`8 +M@%!*E0`8A%`$&0`$VF(,8`3)/'`SW&``"CD(('AP0`/'` +MO@B/X0AV*'4H<$AQ`-HB"B``2'.!X,H@@0/*(4$#E`DA`,HB(0`%`8_AH<'Q +MP(H(K^%R:0AV*'<`W<]PH```(+"@!.,0V$AQ:'*IC/<(``7!7!@>*!`A$1`:"`-+TJ\$X/S_7/<:`` +M`"@"$0"&\PB>@541`H8`W5496(,"V`09&(`O*($`3B"!!Q'JSW"``%0)-GC` +M@.&`SW"``-0)]"!1`"#@\"!-`,N]!/"I=ZEV.G4$$`$@`!A`4`@0`2$`&$10 +MSW&!`!@W`($&Z$*!`-@`&(!0`*'/<(``C*L!@`:`Z[C*(((#RB'"`\HB0@/0 +M"B+^RB-"!%,AP2`,N4`M`!4E>(*X`!@`4``8@%,`&,!3J7`J<!X\ +M""```-N!X,H@00/*(8$#$`@A`,HB80!Y!T_AX'@BN0;P`!_`0`3@8;GY";6` +M8(#/<*````QBH`/9)Z#/<*```"`#ZF886(`[@,]P@`!L,^!_(*#@>/'`S@Y/ +MX0AU*'9(=U,@?H#*(((/```&/+`(XN'*(4(#R7#I<0':(@@@`$AS@>#*($$# +MRB&!`Y0/X?_*(F$`_09/X>!X\<"*#D_AH<%(=\]R@`!(%4"""'7/=H``V"T` +MV`/JA0L0`*'-0,%/(,$#`>`$((`/``#_OX^XH1H<4A@@\`N```SR%A!\\AX0<)\(#B!^6D><\AX@;/(2(',*``P0'8`!]`0`#9 +M(*91!F_AH<#@>/'`V@U/X3((+_D:<%,@`0`.N0WAX;C/(>(#`-W/<*```""P +MH%#8#MJI<](.(`:8=0#>F+X$((\##0@?!FX,0`0$((\#F._$V0/8SW*@```( +M`J(`&$10`!@$5,]P@0`T27&``!C`4$@0`0$`&$10H:+."T`$@..!XH<'QP$X-3^&HP2AW"'8`W6;%/]@6'`0P$FY`(!$'^KD!V,(@`0`5(0$@ +M"B(`)^EPN@GO\DIR&G#/<*```""PH,]PH`"`13`8@`\`(``!`=G/<(``;"@@ +MH&HB@`'/<(``<"A`H,]RIP``?`*"%P@>`*"X`J+/``HUAA'-G6#.__Q=H!Y<]R@`!@%>`2``!'#0401"T^%R]Q.&)KD#AB"I`( +M=)3@@"3"$`:``#QP.'%SW"``$@5`("AP9[HSW"``"#@`(`8Z,]PH``` +M#*V`Y@@O](MP@^@+#141'0T4'L]P@`!,$<]R``#_#SH,[_\$V0X(C^'Q`V_A +MH<#@>/'`:@M/X<]VH```(#J&C"$"CT3WHP@0`,O)Q!```(0H"0\`(8U_@``@ +M.R8-+^Q*(``@$-@-V8ZY,-I8VTX,(`8*)``$#@TO[`AW^+_*(`($,?2*)P@0 +M31[8DP/9SW"@```((J"(V@`8A%``&`141(4`&(!02I4`&(101(4`&(!02I4` +M&(10)(4`&$!02I4`&(10`!@`5!K:!/``&(10`N+["A2,!!@`!"8)0`0!V$X> +MV)-N#`_L'0-/X>!X\<#/<8``G-50F1&9]!R(L$'`"H$#Z`:!`O#_V$+`4K&+ +M<`S91@OO_XHBTP^CP-'`X'[@>/'`0@D/Y8`80`#1P.!^X'CQP#()#^4^H-'` +MX'[/*"@L0)OX:'`\<#AQ0AUSW"``"R_%("!X,P@(H`*]/()#^@1"$4#`]G/<*`` +M@!TFH($"3^'/<(``++\5@"\('P`#VL]QH```$#`9F(\`H`@``!^`3P"````! +MV`(9&(`'&9B`SW"@`(`=1J#@?O'`&@POZ`#8`MG/<(``++\TH-'`X'[@>'$! +M#^@#V<]P@``LO^!_-*"!X`'9PB%!``'8-'C/<8``++_@?Q:AX'@!V,]Q@``L +MO]$#+^@4H>!XJ0,/Z/'`Q@LOZ`#8`]G/<(``++\TH-'`X'[@>/'`/@L/Z(H/ +M``#1P.!^X'C/<(``++\4@('@S"`B@`'8P'C@?O'`/@EOX0'9"'51($#$PB%! +M`%$BP,8!V,(@`0`K>#3T$@D/Z,]V@``LO\8/[_\7IA#H%X8=#040"@D/Z!4- +M!1#/<*```"`;@*()+^@8I@?PSW"``$@5`(`#Z`'8%?`'V`JXP-D8N=H,[^0[ +M>@/9SW"@`(`=)J!."R_H`MV`X,H@00,#\@#8*0%/X>!X\<"R"$_ASW6``"R_ +M6(4BZL]PH```(#N`%X5">0\))0"*(@\*(G@)"@0`2'``WG(*+^C)<-9X&F(#@=`8" +M`,]P@``LOQ2`@N!/'`SW"``"R_%(""X,P@XH`&\H(/S^="#^__ +M`=G1P.!^\<#AQ0AS/@[O_RAU$.@(ZL]P@``LOWF@NJ`*\&AP8@DOZ`#9J7!Z +M"2_H`=G=!P_A\79#923#"!`I!P,[?_*(*T``(8!@!!W#`SM_\H@[0``$@`@4R#^@OP+XO_* +M(*(!`".`+T````#/<8`````+H0"&!(`,H8T&+^&BP,]Q@`!$[?`A````V0\A +M`0#/<*(`@"@QH.!^X'C/3"BX'[@>/'`]@T/X2AUSW9%```C%GY!A@*Y4''*((T/```J,]@/ +M3>$`AL=PH@```/`@0`,Y!@_AX'CQP+X-#^$H=DAWSW5%```C%GU!A0*Y4''* +M((T/```J,Z`/3>$`A<=PH@```-5XX*#Y!0_A\<"�_A&G!(=\]P10``(Q8@ +M``2@@&AVQW6B````4FDU?7EA88`"N7!QRB"-#P``*C/*(8T`9`]MX +M"2```]@:"2``!-@2"2``!=@."2``!M@&"2``!]@""2``"-C/<*(```@4&(`/ +M`!$1$1`8@`\`0'9V+@D@``'8T<#@?L]R@`!$[?`B`@#/<*(`@"A5>""@X'[@ +M>/'`F@P/X<]PH@``"*.`XKW1):&2$/+/=H$`B"X`AH#@RB"!#P``+3-H#F'A +MRB%!`P"&0'CFO=$EH9,1\L]V@0"(+@*&@.#*(($/```M,T0.8>'*(4$#`H9` +M>!,-A!\``0``!@_OYT$M`!:A!`_AX'C/<8``1.WP(0$`SW"B`(`H\"!``.!^ +MX'C/,]R@0"(+A5ZX'\@HO'`"',F#^___]F6#>__:'#/<0``#_^F#>__:'``V<]P +M@0"(+G5X(*#1P.!^SW*``$3M\"(``,]RH@!`*!5Z`((%>2"BX'[@>,]QH@"` +M*!"AX'[@>,]RH@"`*#"")7@0HN!^X'BA!\_D`-L-"=$'`*(!V`?P"0G3!PD) +M$P``V.!^']P%\`\C`P-AO/T)`H,+"$X`97CM\69XZ_'@>/'`.@L/X<]R@``4 +MP&""SW&``&SQE9D#H@#=$P@B`^1I!]@!V2*B`*(]\'QCE'P\9,.<(PB"`X%K +M`O`!Y!,,%1*=9+1]-2%-`_,(0X,8\`'8&/"!G)%PRB!*`\HDRA!2]FAT`_!A +MO'7LG62T?3UEP9WU"(.#_!5-D>T(0H,!V&&\(P@>`(#DSR!A`,HA(0$%\H3K +M@;@!V2*B@**<9)1\D6,]Q`P"LW@'8<0-O\P3:X'CQP(8*#^'/ +M=8``G-4^#^__$)T(=A,('@#/<8``%,`!V.H*H`(A@0T.GA#6"J_X$)T9#EX0 +MSW$#`*S>SW*``!3``=@J"V_S0H*M`@_A\<`V"B_A`K@!WA5XSW6``$BYN6`` +MV!/P`""##X``/`R$BQ4A`@#B@@'@_&2"HD2+#WB,(@.,RB8K$.$(TH`%B0'@ +M#WH+"C,!!:D9#E$0`M@`H:(,+^H2V`3N`=A`'1@000(/X?'`SW"!`"@X[!P( +ML,]P@0`T3$'`SW"``"3@0L#/<(``*.!#P`#81,`*V`39!MH"VPHD@`^``"S@ +M"B6`#X``/,!*)D`$R@KO\THG0`"EP-'`X'[@>!4'[^<%V.!XSW"``"R_%H"! +MX`'8P'@!!^_G`^#Y!N_G`MC@>/$&[^<`V.!XZ0;OYP'8X'CAQ>H2#+8+?"'R +M`FL%((`/Q>Z`X<]UH```(,]TH`"`'`&D&X72N0&D0"O`!"5XG[@!I`#9"?#P +M(D``,""`#Z```&`!X0&D\PG$@.!_P<7@>.'%ZA(,M@M\'O(":P4@@`_%[H#A +MSW6@```@SW2@`(`<`:0;A=*Y`:1`*\`$)7B?N`&D`-D&\/`B0```@`'A`:3W +M"<2`X'_!Q?'`G@@/X:'!FG!Z<98*8``:66\L]P@`"0*`"`$^C/<8$`F"\AB0#8">G/<8``8#(@ +M@8#ARB!B`&(-[_A:<`/H`-YJ\(H@_P\#\*EP0@I``(P@PX\(=1CR2@I``,]V +M@`!0Q[9^!!:$$`,6A1`B:`&(08YBCCH.[_@*)H`$:.CEC@0G3Q0$\`#?Z76+ +M<48+[_=*<`0@0`0O(0<@!2'.(R\FAY,Z\HIP@@E@`&IQ$G@$?@1_+R3'@\]R +M@`#X3B"*!"$1(,5Y(*H>\L]Q@`!0Q[9Y((G/<(``4,E`D`\B0@!`L#1M`"&` +M#X``L,>*<6IR^@E@``ISSW&``/Q.`($/($`#`*$5"1`@`,"*<6IR"G/""^_W +M"B1`!,]Q@`"0QQN)RW@'],]P@`!D,@"`"N@]B<]R@`#X3@"*)7@`J@'8`_`` +MV)4'[^"AP/'`X<4V"6``"'6E>(H)8``/>,]P@`"`P0B(@N"<"$$`I0?/X`#9 +MSW"``$#!X'\AH.!^X'CQP.'%`@E@``AUIG@/?58)8`"I<)GMSW"``&0R`("5 +MZ,]P@`"0*`"`#^C/<(``@,$(B!$(T0`"V)H((```V07P@>"<"P'Q30?/X.!X +M!]B%`"```-G@?N!XSW"``$#!X'\`@.!XSW"``$#!X'\!@.!X\<#AQ<]Q@`!` +MP4`A#0GL'$BS52'`!$'`*'"`(((`0L!6(4`$0\``V$3`#=@&V0G:`-L*)(`/ +M@`"D\@HE@`^``.3!2B:`!IX/K_-*)T``SW$#`&SBY@GO\ZEPR0;OX*7`"',H +M`'8I0;OX,(@`0#@>,]P@`"`P0B( +M@.`!V.!_P'C/<(``@,$(B('@`=C@?\!X\<#&"4_^`X!1(("!`=C"(`$`T<#@ +M?N!XX'\!V,]P@`"`P0B(@>#,(.*``=C`>.!^SW*``$#!`H**(5`,,'#*(T8` +MRB,%`&)X`J+/<*```"`[@`4K@P\/`$!"SW"``-3AR0,@`B=QX'A=`@_Q\<#A +MQ@"V`,<`C`+\`*)#0A1`0'8`QP",`7P`QQ",P#8!>BBJ:.IKK(@@\]P +MH```(!N`,GDX8`'@0<#/<$0`>+L`@$+`+0Z0$`H/S_^2Z,]P@`!(%0"`@.#* +M(`$'RB*!#P``;0"(#6'_RB$A`P?PBW`,V?8-;_]MVH7FRB"&#P``9"NL#B;A +MRB&&`Q4%[^"CP.!X\<""#,_@SW>``,#!+X\*)8`O@`!`P14E0"#7B*+!`-T& +M[A"/>@WOX,EQ$ND!W0?N$(]V#>_@R7$"Z0#=%25`(PZ0`=U*)@`@!PB>`-IU +M'@AO_@#?.@T@`%IWP@\O_H'`!!07,(#E`=C`>!NXQW``$```0,`.\,]QDP,` +MAX(([^W)<`/H@+T`&$`C0")2(`'GSW"``!#)&(@0=_``!@`*)(`O@``0PK)O +MM'V"==05#A'6#._ZR7!MZ,]QD]8`I$(([^W)<-`5#1!Z<"\AAR/.#F_X*G"@ +MO4H@0"`$Z`IP'O!J".`#*G`Z<&((X`,DV`(A`B`*<+H.[^``V905`R"8%0(@ +M9GA&>04@?H#J\\]Q26L`TNX/K^W)<`#!*WW,("*`!O1,)@"@S",BH+/S0"J` +M(!1X`"<0(`08A",R;S1Y`"1`(-80``$`)%0@!A@$(-@4`"`(&``@SW!$`'B[ +M`X`K"%^`!"6^GQ\`_O^/\P8,[_K)_ZSWB`X'WUSW&3U@"D?/$2 +M"*_^2G``V<]P@`#X3B"HSW"``%#)(+#/<(``_$X@H,]P@`"PQVH/K^6PV8X. +MC_?/<*```"`;@``=`"`/"A$@"-B6#.__`=D#\-8/S_#Y`N_@HL#QP+H*S^"A +MP2AVSW"``%#)I@P@`*"0&G#/<(``^$[@B,]P@`"0QVH.+_X:$)(`.G#/<8`` +M0,$!@0'@`:%J"._G`=@,$0`@X[C*(((/``#G`*P.8O[*(8(#SW"``)`H`(`5 +MZ`0B`"3K>!'RSW"``$@5`(`"',(S@.``'$0SL`F"\HMP!-EV"V__V=K/<(`` +M_$Y>#"```(`6#J_W`-T%\`#80'D!Y:]]*0T3$@#8#R!``\]Q@`#\Y_`A00,/ +M>(#ARR`"H/'S"W_M\P'8[/$:"D_S,@X/_H7FRB"&#P``8ROD"R;ARB&&`S4" +M[^"AP/'`W@G/X`AUP@L@`"AVD.C/<(``9#(`@(KHSW"``)`H`("`X,H@H@`` +MV3KTSW&``$#!%0U1$1:)@^@:B3+H!($"H2;PSW.``,#!3XL5(8P`"I0"H1"+ +MEHP!X!"K#I,!X`ZS$(LC#`$0C"3#GPWR`-@!XD^K$*L/BPL(DP`5>1:)@^@` +MV`+P`=@+"%$`@@O/_PCP*@^OYP+8!MC)`!"8'@`0`-@/ +MM<]P@``4O`'?X*"C%H`0#0@2`6()3_,"Z.^U%28.%`Z63P@>`!"5(^@.E5QZ4B("`%,B`P`" +MVG1ZP+F*(_\/)@EO\THDP`<%\`?82@KO_P#9[0#/X.!XSW*``$#!`8*#Z`2" +M!O"/$H``%2(!``J1G0+O_P*BX'CQP#H*``#."0``T<#@?N!X\,]Q@`#@P@!A:WC`)V(0`>(8$X`@Z0H$@`01@2`'"5(`A^_/ +M<```F2/X/'`&@^OX`#: +M"'8%D!Q]PKV&(`\,!;8+\!)J%'C88"F``>*NN:^YL+DIH/$*E(#2"(_J#0A1 +M`%`E0I`#]*ERSW&``,#!$8D;>!&I$8E3(+Z``_0!V!&I2WCV\S1H5V@E>B66 +M17DEM@#;"O"2:Y1\W&0IA$`H@@-%>2FD`>/O"Y2`"0>/X/'`@@@``(SHSW"` +M`&0R`("&Z,]P@`"0*`"`AN@%V#(([_\`V='`X'[QP&8.C^`:<"AV`-T"\`'E +MSW"``)#'&(@C#040SW>``%#%MG\*<.EQ!@NOY0;:\>@&CPL.!!`'CP+P`-B1 +M!H_@\<#/<(``8,B6"J_ER-GZ#H__T<#@?N!XSW"``!#)X'\9B.!X`>#/<8`` +MD,0")1"B^"``A@']$`+"[X'[QP-X-K^`L +MV@AVSW6``!#(624`$YX+(`!6)4$3,0:OX-2EX'C/<8``$,G@?QFIX'CQP*H- +MC^`(=BAP*HYH=XAU!.DICA$*10!)KNBNR7&B"B``"-H*C@5]JJZF""_^Z7", +M(/^/"?)!*,$`/F8KCL*X#R$!`"NNT06/X.!XH<'QP$H-C^`:<<]Q@0#412AV +M#!F`#P"````*(H`O_O__/P0@@03/=X$`B#8*(X`O@`"<"Z./QA.`(*MX2,$A +M\K\3@"``V5,@0@`/(8$`!"%1@T*XP;@`V0\A`0`D?0WR`^T+"9`@*G4'\,]P +M@`!@#P"`0'AYZ`Z]","E>`/P`8$C``(\(PD2XPK@.N`0B@P\!``#`"WN( +MP17RUW,```!`S"."CP```(#,(X*/`0````3T`8<#\`*'!"*"!$5X`*$(Q2Z] +M4R6-D,H@@0\``%$`@`[AX,\@(0,CAD`M`!8E>`.F",!,(`"@`::*(`0&RB`B +M`@2FR7"I<0#=J7+2#._FJ7.JMMX*[^S)<`NVR7`R#6_K`MD(P0'8D"C`\$(VBZYPKE$I4.%0"D#!F5Z0Z4#PV&E#0@>`IVZ0Z4% +M\(H@!@8$I:EP`-H!WAH,[^;)<\O)SW&``)2V4(A)82JU$(C/<8``],D#N!5X +M`&$+M:EP:@QOZ\EQP*4(W.\#C^#QP'8+C^`(=2AV4R%``)(+X`).(`\!&PX$ +M$,]RH```!$Z"SW```,8B4@WOX,EQ`-D'\"IESW"@`$`$0*@!X?<)A(,C#U`0 +M%0^0$"4/T1``V<]PH`!`!""H`-G/<*``0`0@J`#9SW"@`$`$(*AU`X_@`-L) +M\/`@S`#/4"&!!^0$`3F!!8!%`0?4!`$%@$4!!]0$`06`10$'U`0 +M@"#_CP#=X_4M`H_@X'CQP+H)C^`(=BAW2'7@N-$G(9#*(((/```%/,HA@@.@ +M"^+@RB+"`ZL-$!!`)<`3)+C#O9<-%10S)DUS@`#XXT`G`7.T>2!Y0)8"'Y00 +M`N8"%@$5`A]4$`(6`14"'U00`A8!%0(?5!`"%@$5`A]4$`(6`14"'U00`A8! +M%0(?5!`"%@$5`A]4$`(6`14"'U00`A8!%0(?5!`"%@$5`A]4$`(6`14"'U00 +M`A8!%0(?5!`"%@$5`A]4$`(6`14"'U00`A8!%0(?5!"`(/^/`-VS]5D!C^#@ +M>/'`SW*``#3)`((GZ`#9(*+/<(``/,D@H,]P@``LR4"`SW"``$3)`(#/=(`` +M,,G/``*CQCV3U +M#%21`-P"\`'<@.0`W,HD8A!D[`(0S`!"?(U\2"3,$5SKN0Q#D]GQ+>O/=X`` +M.,D`AP'>B>@3;0YX!=EB#J_LR7(4\,]V@`!`R0`6P!`1#0,0$VT.>`791@ZO +M[`':`!;`$!!U`=[*)BD0#.[/<(``0,F@J`'9(*?/<(``-,D@H!_PSW*``#S) +M(((!V`KISW&``$C)`!'!`#!URB`I``_HSW"``$C)H*@!V`"BSW"@```@.X#/ +M<(``3,D@H.4'3^#@>*+!\,]V@`!HR:".4R"3`<6]D.7*((H/``#-&P`)ZN#*(4H#`([FN`#8 +M)/3/<8``;,P6(4`#!XBV>0"N`!E`!.*Q!AD"!``C@"^``&S)0(A'J4`HP2"@ +MJ#5Y`!I"(\=Q@`#LR2`9``4`@:FX`*$!V`S<]P9/X.!XHL'QP*8.;^"8<$7! +M%!0.,3"X0"X!%`5Y02D``B=X,+DG>,:X`""##X``;,D"\&=LH(N`WUD-WQ'/ +M<8``;,PH=+9\!HSK"@&`SW"```S*`[I5>D!@A"@)#R]PN'#'<(``(#M&@!4* +M`0$.D!$.`1``)8`/@```/>"H!XRV>0"KSW"``&C)0(B'O4>IH*@,W(L&3^#@ +M>`.X%7@`(((/@`#LR9J*SW"``&S,%B`#`V"#8*%:BE9X`I#@?P*QX'@#N,]Q +M@``&RA5X"6'/<(``;,PV>""`C"'_CPCT`I#7<```__\!V`/R`-C@?J+!0<$$ +M%`(Q02@!!$`J`P0E>T$K`0)G>3"[9WG&N<]S@`!LR2MC`_!GB8#9'0O?`<]Q +M@`!LS'9Y8('Q",&`8I'I"L&`!HD#\"APX'^BP.!X\#4_@I@YO]THD0"`* +MZ-((#_B!X`'8N@RO[,(@`0#/<:0``$1)@<]P@``H5$"@,8'/<(``'%0@H,]U +M@`!X"P>%@.!("@'MPX+K_H!V,]VIP``2'`6`1;/<(``.%<@ +MH,]Q@`!`,@`9``4`V'`>&!!."F`#"M@'A<$:F+\"``,`SW6``(`GC>@AA5,A +M```]><"Y$W@S><&XP;E>#"_[`MK/<:T`@("*<`>A&Z'/<:T``*4;H<]QK0"` +MKPNA'!40$"`5$A!3(,(@0"H!(8HC`RP$(<$$17G/=Z<``$0UIP*%#PA1`!"& +M12#```;P#PB1`!"&1B#``!"F!84FA8#@2B%`(,HA0B`#A:&%-!X`%52'+R$) +M`(#@T")I!<\B;`4$(H(/X/\!#E,A`P(,NR]Y.WDE>V5Z5*>2#&_R&+T#V5/8 +M$;@@H%,@PB!`*@$A!"'`!$5X%:<`V`ZF%(=`*4$BN+BYN+JX!7VTIQ*'@+@2 +MIQ2'!""`#____O$E>!2G0!\`%7()C_$I!$_@X'C/C`"&!@)\4 +M#A:>'%@0`28.$"F#GQR8$Z04`A8)HP`A@8"E%`X6I!Q8$`$F#A"B%`(6I1R8 +M$RB#!J.C%`X6`"&!@`$F#A"B'%@0HQR8$U(/[_\(HYT#3^#@>/'`)@M/X`AV +MSW"``#3F`(#/=8``+,WAP+8,;^D4V,]P@`!(%0"`BN@@A0#8BNDAA8#ARB!A +M``;P`86`X`'8P'@?Z,]PH```#`V`0B``"$@@``",(`J-F?>=V&#`H`$((`/``#_OX^XH1H\@@O^.'`@.#*(($#RB>!$PGR/@[/]^8-[_<(=O8-[_<(=PHB +M@"^``$@5`!(!(,]U@``LS1"^PJ62Z2#"C"("A\]QH`"`#(HC"@P']$`9@`\` +MN+`"`O!PH0`?0$0+#U$0(H6!N2*E!>@"A8.X`J4*(8`OH```(&P1`"#/=X$` +M`'")'1@0`8_/<8``+,]`)0X2#.A*($`@`-@!KU4A0`L`V=(.+^6*(@0-`H^` +MX,!XRB`!!`?H`H4`V8"X`J4#\(HA_P_/`0>$!`!Y(PD@IH`AK?WSW*@```,`J(#V`>B0(9$>2"F(,&,(0*'!/1F +M&1B@OJ/_H]$!;^"AP.!X50;O_P#8X'CQP.'%`-WZ":_ZJ7!&"(_R>@[/[,]R +M@``X5P""SW&G`(!)PK@0H<]P@`!`,J"@SW"``#0G`("@HL$:&+#/<(``*%0` +M@,]QI```1`FASW"``!Q4`(`1H>8/;_JI<)H.3_&)`4_@\<#AQ0AU,@@@``#; +M*6AH<@WP*&45"!(,$0B3#IH(#^V2:IAX!7L!XF&YZPD3@%D!;^!H<`AR`_`! +MX""(_NG@?T)XX'CQP,]QH```10`9@`\`0```X'@`V`"ASW"@````,]QH```'309@`]`````.!F`#T````"*(\@* +M(H(!W`\A`0`BHL]P@`!8_9*@X']H<.!X`-V.#&_@!MC/<*````X0@`'E!>B, +M)0>=M??/<(```%0`@!4('P//<*```#@P&(`/````"$H)#_<`V,]QH```/`"A +M!('_"!Z`!($+"%\``M@#H6D@0`#_\?'`SW&``-S4+($P<#0+8>?*(($`T<#@ +M?O'`X<7/=8``K-.I<"H,+^6*(00,BB#_#P"ESW"``-S4%@POY4#94@E/Y\]P +M10!P+FH-0`'/<$4`F#=B#4`!SW!%`+0W5@U``<]P10!X-TX-0`'/<$4`Y")" +M#4`!X0R740\``A@"^` +M`(`\MGC@B`IPS@^O[>EQ#R;.$P'EKWWE#8*4R7#>#&`"']DQ!@_@\<#AQ<]U +M@`"LTT"%C"+_CPAQ&?*$*0D/SW"``"`[,"!`#A!RRB""#P``532P#T+@2Q4` +M%@\('@#/<$4`M#=V"T`!%08/X.!X\<"*#0_@"'6$*`D/SW&``'P\,B%1#@H@ +M0"X`WA7P`""`+X``@#S6>."(J7#I<:(/;^T!VL]P@`"LTPB($'<(#P'G`>;/ +M?ML.0I2E!0_@X'CQP#8-#^`D$I(`SW6@```@6X7/=X``K-,GAP#>`"&1`#N% +M1H<`(E``[@XO\\EQ"'&$*0D/SW"``"`[,"!`#D"'&PB```T($0%+%P`6#P@? +M`,]P``!4-/(.3^!3"E$@SW:``*S4"X:BN`NF'0@?`">/#PE1``IP=@\OYRIQ +M*_"#N`NF*?!/"%X!SW!%`'@WC@I``3N%!H<98<]P10"8-](*0`$+AJ6X"Z85 +M\,]U@`#B6"*_I`-G`I1(/+^D,V"R%!>GF#Z_H"MC,I;8,S__%!`_@ +MX'CQP,]P@`"LU`N`X+B<#,'_T<#@?O'`.@P/X*_!"'52#&_I6G+/=H``W-0@ +MAN2(`-@1#4`0)(8-#4`0+(8'#4$0`=AZ<(H@"0^Z<`Q_SW"````],B!1#@\/ +M$1'/<(``K-/@B#,+$"`$+WX5SW&``"`[,"%!#L]P@`"LTT"`,'+*(((/``!6 +M-,HAP@/P#6+@RB-"`P"&$'7,(F&@/O2J<`Q_`"&0?X``H#P\$`$@SW"``*S3 +M`H`*)(`O@`"LU!`A```*"V`"']DL%``@SW(#`-#Y@;@L'``@Z7"."B_N*G&` +MX"IP!O0J#.__`-D6\-H,S^T2Z,]PH```(!N`:!`!(!EASW!%`.0BD@E``2P4 +M`""$N"P<`"`$AA!US")AH`STSW"@```@.X#/<$4`<"YJ"6`!@"$0``R&WPT! +M$`^&`!R`-,=P````0$'`SW6``*S3`H4,V4+`BW#."Z_^JMJW"E$@2Q4`%@HF +M@"^@```@@+A+'1@0;!8!(,]P10!P+AH)8`&`(1``.@VOZ`K8"'=`(!`,0"01 +M,PIP*G'F#V__+-H$%Q00SW&``"@[0(T$*GX%`"%`#NEQR@]O_US:*G`*<<(/ +M;_\LV@0?`!4!V`"GCL%`)0`3K@]O_P3:#L$*V*X)K^C_VKX.K^@*V,]Q@`"0 +M1@^!2(T/((``#Z%L%@$@#X8980:%`GG/<$4`>#>."&`!F2$$``\+$"!,(@"@ +MD`K!_X$"+^"OP/'`X<4`W0GP%@U@`:EP(@@@``'EKWWU#1*1SW"``!C:#@@` +M`#(,3^B9`@_@\<#AQ0AU!/#J#P`!+@A@`:EP_.B!`@_@\<#AQ1X(8`$(=4*% +M"^AB@"""!H4&>06%)7@`H@.%8*`,\`"")H4D>`"BSW"@```<'!B`#P!\``!% +M`@_@\<#/<(``R-4@@,]P@`"FB"````_`F"```T<#@?N!X\<`%Z.X. +MC_X&\`'9SW"``)S5)Z#1P.!^\<"."2_@`-O/=8``G-5`A81M$[6$ZFAP(O`! +MX_4DP1`)"0,`]PN$@$6%C"+#CP;T`-AEI6AR#?`5"X``#0N%`#*=8KD)"$,` +M`=@#\`#8".@I:U!SRB'.`":E9:4#Z`'9*J6$Z`>%!^@`WG(.K_['I%!.@`V`>E%O`PG0':\.'"(HH``=ARG55X`B'"`"\B +MB0`2Z"4*!`#/<(``2!4`@(7H)@Z/_@CP]N'*((H/``#/*,`*2N`0G<]Q@`"L +MSAZA$9TQ`2_@'Z'@>&D#+^D6V.!XSW!$`!#R`(`1"%$`SW&@```T`(&0N`"A +MX'[@>/'`X<7/=8``,"L@A5,A@`<+"%0"02G^AP7TSW`/`$!"!?!_R`(7> +MN'X-C_+9``_@X'CQP(8+K^@)V!H.[^0$V-'`X'[@>%$"3^CQP,]P@`!`P0*` +M!>AF"@__!?`#V.8)+_\`V='`X'[@>/'`(@@/X,]U@``PR0"%'.C/<8``1,D@ +M@<]R@``HXAL)!0`B>`"E!H($@`"`&6$>#B`!2'!6\`#9(*4F@B2!(($98??Q +MSW"``"SS`(`+Z,]R@``HX@:"!(`@@,=Q3`!`2^?QSW"``#S)((``WC'IP*#/ +M<(``2,D`$,``SW&``$#)`*D#N`YX!=G^#2_L`=K/<*```"`[@,]P@`!,R0"` +MSW*``"S)8((;8\]P@`!$R0"`(GO/2%B(('/H""4R%#!9MC`B,,`'!PRB,.`P&"-KDX8!:X*0?OWV5XX'CQP.'%"'-2 +M""``*'*$*PD/SW&``"P[,"%!#L]T@`!HUP*Y-7DA9("!4R)!!5,D316B>3A@ +M@.'*(0L`SW"!`&1%=G@@H$$J@04VO()YU0;OWR&@X'B$*`D/SW&``"P[,"%` +M#L]Q@`!DUP*X%7@`80"`X'[@>(0H"0_/`!B +M(*#@?N!X`-D+\`#;SW*!`(Q%-GI@HF&B`>$O>?$)!(#@?N'%A"@)#\]S@``L +M.S`C3`[/Z"#`8,"(4&#`R("`!)L%7C'<(``9-=B@""C`X!`H.!_ +MP<7@>/'`N@W/WZ+!"'4H=TAVV@POYXMQSW"!`(Q%MGA@@`#"`8``(L*``<$! +M($``0_?HL#@>/'`?@W/WZ+!"'=(=FAUBW(H<,X,+^=(<<]P +M@0",1?9X8(``P@&``"+"@`'!`2!``$'`0*8!P`"EL07OWZ+`X'CQP#X-S]^D +MP0AW*'9(=5X,+^>"P0+!`\`")DZ0`R4-$,]P@0",1?9XP*"AH'T%[]^DP.!X +M\<`.#<_?I,$(=BAU*@POYXMQSW"!`(Q%UG@@@`#"66$"(8&``<,@H`,ES1"A +MH%$%[]^DP(0H"0_/<8``+#LP(4$.SW*``'37`KDU>2%B0('/<8$`C$46>0"! +MX']88.!XA"@)#\]R@``L.S`B0@[/>!_0*'QP'(,S]]:<"AUP8(Z1`J%/(4`A +M!7I0>$>Q"!`#(&&A(0X>$`L/'A!/(L``![$+#YX0A+@'L038!K$#E8.X`[4? +M#IX0"P\>$0>1@[@'L0T/GA$'D82X![$&D82X!K%*<-X+8```$`(@1":^DC3R +M:@Q/Z0AQ`H5GD0*A3R%`(05[9[$,$``@<'IAN`&A(0Y>$`L/7A!/(\(`1[$+ +M#]X0A+I'L0C8!K$#E:.X`[4?#MX0"P]>$0>1@[@'L0T/WA$'D82X![$&D86X +M!K%*<'(+8```$`(@Z0//W_'`:@O/WZK!NG#Z<4HA`"`*((`_@`!T.@00#C`* +M)H`/@`#8]<]W@`"TUP&'!!Y"!`FG!H$*)(`O@`"X]20<0#1`)QD5BNC/<(`` +MS-H$@,)X$0B%#P```!`*(D`D*G$0\$H/(``$%P`@A.`(<'!N71I +M8V(!Y0D-%1'S"Q*(^@X``(3E&G#*(08$5?<`W0IQ#_`!AP'E`>#!N-X.(``! +MIPAQ`=@`'```!!X"``L-%1'E"1*$;PT1$0+8`!P```0>`@`$%P00BB?##Q$( +M,R0$'\`10"1``%,@1`!*)0``B'4<\,K)5&V6(`8`6&!A@(2`FMJ;8PDC@@!$ +MH`&'%0C!`7H.(`"I<`D(,@0(<:&G`>7!O4`E10#-#12!`8?!","!0H?*R0#; +MC+M`PY8@!@!A@$`ID`(?',(@98#/=8``S-H>',(@:8#_V1TP@!H@`(>P@!L@!"``!X"``"%`1["`&D(00"+ZL2EQ:4@I0'8`J5U!"`` +M&!P`(`*%">A$A<]P```7,"*_I +M(J4!@('!1(5EA4(/(`!*)````<"'Z`/!JG"Z#>```=H%I038\0,@`!@<`"`+ +M"I0``84-"$$`2B8`()GP!(4*(X`O````0``FP10B>#^X4B``@$HF`"!M\H(( +MK^D!AX'!`8#)`L(4@!#P0GP +M0\)(<0?P`8<`I1#8&!P`("6EQ*6J<*X,X``!VNT"```8%1@0!84"(``&"PA3 +M``2%`"#8!)H/;^D`A8'!`8`+```=H%I8H@$``8'``@!O#$ +MI1@<@"\````(C06OWZK`X'CQP$X-C]\Z<`P0%0!:(R>2&@]0H4@0#9 +M*'=`)!,[0"06/*EP`-IJ84$0`@@PT% +M$`#`>PB$`X#<#B8`$W,(!`4`W4HD0``*)0`!R7?%#X6?``"``!01`""Y#060 +MM0A$@8W!Z7!J$@@``#@?PD@@`#@>`#:SW.` +M`+370J-(<1'PRLF4:94@3`"`8!,(%`$!@P'BC"##CT*C`_0AHP'A+WGC"1*! +MA.K_V`&CX'](/'`+@N/WZ3!.G!:1R>V"@]0P4D0#8.G<(=P;P!.]I:0`DHE```@A'U\2\H@0-.((,'`-JI"A6!%&M5>#)J'&6# +MA'`A#P>X8!>`Y7P&?("A`>+Q\>SN&0T1``#:"/`2:G`@`0Q@WO_\ER%^@%P7_:C"'_C\HB0@`$PPDB`@4"(L$``>$9 +M"2,$1<(,)("@RB`A`$`B4P#%"%"`#_`@A0R[>6$(&D`@`6H@A0RX&6$,&D`@ +M`!J`(_T`K]^FP,]P@`"TUR&``-H#\`'B&0H5`'!N94@3`!T:6!@[0@4 +M@>!_*'#QP(X(K]\(`#AD*4@!@H>!_ +M,*!!@0&$0G@1"%,`B7.`@_KL(*/@?B"CX'^`H>!X\<#*#T_?@B0#,`AV>G$` +MB#X/+^FZ<".&^G`-"74!%!80$(?ISW````\QO@G/WV8+K_,`AH#@S",BH`CT +MSW```!`QI@GOWR"&"G#@N-$@88#*(($/```8,8P)X=_*(0$$:G#^"V_D$-D` +MW2*&J7`:"J``0884%A80GP@>(,]P@`!LM@"`X(`Z=4#P*A>1$#[P"(E;"%$` +M!(DE"-,`(0Y?(""&`X='"0$`"PZ>(!.7$0C>`SL.WB`3ES,(W@,2;11X@W#A +MH/_9(*@CEPT-(A1MSW&``(`Z.&`CAK(-K^9J<@'E)0U5$0#8#R!` +M`P0@P(71(&*B!?3HZ-$('J+/<8``T#H4;>KQ*09OWX`D`S#QP-H-3]^DP3IP +M*'9`(14!2B(`(,]P@`!8$@`0$P!*<`/P0"!`(/_?4G<:<'CR0"J!(#1Y,"5` +M(.4($`!I"Q`@V6$`W$IRZ77I=EAJPK!@XHDPR\*)H`D0"Z-(+1]W64!A2.`#0E!!#.0 +M!-L'"=X#`-N+<=8*(``*-A@(*@7\%IQ%?`` +MP025%0E1`!\(GP**N`2U0"-`(`CP#PB>`JJX!+5"(T`@>G`*)(`E`!66$)D/ +M@96%\0T%;]^DP.!X\<#.#&_?%-FEP0AV.@EOY(MP#H:@@&(++^D"AAIP"O`L +MN0T,01`GDZBY)[.@H*"%@PT0$`:5?PB0`%(-K^@"A62([PC.H`^0YPC>@P:5 +MAB#_A>_S(87/`\( +M<@!5)<05`M@`IK/P(H4`V#!WRB!O`(#@RB)"(""%RB+!(P(@0*``VLHB;P`L +MN(#BRB4"`,HE(0`*)H`O``#_#P`B@"4B>(#@++C*($P&C"7!CW_9%`$F``D@ +M60!!+4$!,PL0(`#?./`O*$$%3B"#!RAR"_"4:Q)J57PP)`P#@W#C@`'BY7R# +MH.\*%($0)=4@VPT1H`#?"_`O*$$$3B""!Q1J,"0``!`AD2`%?^\)$:`4\`## +M4FD$NP`D@#!Z8F.`NF()#Q`@5X(#\$."97I#H%)Z0Z`!X=T)%(&!PT`D!#(+ +M<*AQ2B$`(*8/K_\J`!5]`F_?I\#QP#(*3]\(=2AW#(@:<\@<"+!`)148!!6`(/IRC"## +MC\H@@0\``/X`!/(,%8$@(G@"(,`%PH5!P`B%*+X"<$`HE`(#E<]^#0@>`0'` +M`>!!P`'80L``IP/80\`!IP05@R`!P!4+!0`BA<]P```%,?X+K]\!PL]P@`!0 +M*]5X((!$P`>%"B"`/X``=#H*N`4H_@5,)P"@`"%1<``A$R7")H(ERB#"),HF +M0A3*(D(D;_0#E6D('@$!AZ"X`:<$$`XP`B;`%#^X4B``@`(CE",1]`45@2"% +MZ0.5&PA?`AKI`Y4Q"%\!#0\1(`T5@"`">9#IY@CO_ZEP)X4*N04I_@4G<`*G +M*(4*N3A@`Z<"V`"G2B8`(`H@P"1:=COP!!`!,`(A0`03"%(``"&`+P````@B +M>`\(4P`J=@HB0"0%\`(C5"`H=EIQ#!6`((3H!86%Z$HF`"`;\`JX`"!.!`(F +M0A`_NE(B`H`!V`?R`B&"!#^Z4B("@`/TVG`)\$B%VG`"Y +M`B``"B$`-<)X(0A2``45@2`/#Q$@!>D-%8`@`GF`X9("(0#*(0$U`-@SE8^X +M1<`D>$(@!(``V(ZX1L`D>,HD8@!"(`"`2G'*(&(`1\``P`IRZ7,.#.__'!0% +M,`"'.0@1`5.5!<``(H$O````$$1X0B`$@`;`RB1B`$1X0B``@`IRRB!B`$C` +M`,#I<]8+[_\@%`4P0(=*PF*'3,,#ATW`&?!3E07`BL-$>$(@!(`&P,HD8@!$ +M>$(@`(`*,\(0H9BIPW``Z<* +MP!D(T0`5#(4O!P``\`/``*<($``P0"!1`$"'(H<#AP(@60"WZFL)@S\``&0` +M!16"("_J"!`",!<(@0`#P`'9`*?/<(``S-HLJ"/P`B#`!#^X4B``@`3R`L`` +MIQOP`Y4S"!\!`\"6(0@``:<%PA.5!'I"(@2`!L+*)&(`1'A"(`6``,#*)6(` +M"G+*"N__Z7,@AX#AC/1"AP(B@`-7"%(`!16#(`\/$2`%ZPT5@"`">XWK`L`( +M'T`4`*<(A2IR"K@B<`.G`=D5\`&'H+B"N`&G`X<"(``$&PA2``@0`#``VPP@ +M`*#*(V\`@./*(`$$`Z<#AP(@F0#3"1$``B:`%#^X4B``@!7R)PY1(`(F@!`_ +MN%(@`(`%\@3`0*`)\`&'#PB>``T5@""#Z`3`P*`$P$.'P(`(A2%J"K@>9@>% +M"K@%*/X%)W8")D`0?PA2``@0`#!%"@$`6@W/Z,]Q@`#,VI/H!16`()'H$Y4? +M"-\#PZ=(@0(F@!`/"%(`"8'(H8&X":$@AR/P`8>AN`&G"8&`N`FA^?$%%8$@ +M#0\1(`3I#16`(`)YB^D"P`'9`*<('T`4"(4*N")P`Z<)\`&'((>AN(.X`:<# +M\""'PZ>#X0'``-[*)@(0E.D,(0"URB(&!1.5RB)%!@0@@`\```"`0B`#@`#` +MRB-B`-8(8``BAP#8`^X);HD%+]^NP/'`8@TOW__;"'8"@,]W@`"TUT`G#14+ +M",$``X8$IR&&1(8-"<```H<9")4`(J9$IT`G`!6F"2_D$-D!V`:F,_#*R02Y +ME2!,`!EA9(<#@6)Z@"((`&6&*KI">`\+40"`X,H@*P"%]HHCOP,((,```Z$` +MV`6F(8$3"84/````4`&&\"4`$%A@&G!`)P`53@DOY!#9`885?0`=`!0!A@*F +M!(8$IRD%#]_@>/'`X<4C$((`SW6``,S:57U*A2)Z#PI2`"JE.@WOZ`2(#J49 +M!0_?X'CQP&X,#]_('`BP*'9(=28/[_]:`,]P +M@`!T.@&`BL),P$W`"-A+P`'82L!*<*EQ@@\O_P#;",`GA@)Y)0E2`,]Q@`!T +M.B*!,'`*``\`+(X1"5$`8;@'I@F&@K@)I@#8#*Y`(5$@`L!;"!"`SW:``,S: +M`H8'Z"6&`\`P__`-L-\`/9`\!&P4C`1\%`)0`2U@[O +M_P/!`-@GA4+``\`*N3A@0\`&P(#@@?0SE=D)WP.`AHPDPY\(]`G#`!Y`%F6F +M",`$IBWP"<,DA@(AP@`_NE(B`H`(PA'R"PQ!%D2F9?``'D`6):9$IF:F`=@" +MIDIP?@\@``':6?`4%@00`B(/`2D/4A`"A@\,0!:+Z$6F`=@"I@?PA^AEII,) +M$2!FID7P0"4`$BCP-PQ!%@(C#`$7#%(0@H81#%$0`]A&P`#;0L,#\&6FL^A" +M>0D)4@!$IB:&"<,"(T``4PA2`.'Q1:8!V`*F2G!(<08/(``!V@C"0"4`$O(- +M[_](<0/81L``V$+`%?#/<(``=#H(P0&`(G@_N%(@`(`$'D`6"?(LC002`"`/ +M($``!!H`(`;"@^(E\P?`1"`^@^WR(Y4O"5X!*PD1("<(G@#/<(``=#H!@(K" +M3,!-P`C82\`!V$K`2G"I<<8-+_\`VQP4%C`/#AX@3R:6(!P<@#4/#EX@3R;6 +M(!P<@#4#E>6XS"$AH`CT#0[>($\FEB`<'(`U!1.5(!$)$2`-#1`@#1.`(`(E +M%2!$)H`@@N!*)$`@!<#")`(E)X4`@`JY!2E^!"B%)W`*N0`A$`"&QTIPJ7'I +MER`(`*N04I?@2I<2=P2,`!V$?` +M1L!*ER1@PO +M_P#;GO&?#!$@SW"``'0Z`H`"(``$CPA2`"0<`#0"V$?``=A&P.ER./`%$X,@ +M@./,(F*`#_(CE>6YS"$AH,PB(8`$](*X1\!/"%X`@[A'P"/P1PI1`".5/PD> +M`3L)$2")ZX&X1\#/<(``=#H!@$G`$_`G"5X!SW"``'0Z`8"*PDS`3<`(V$O` +M`=A*P$IPJ7&R"R__`-N&PDIPJ7&F"R__`-L!P`;"`>`!P8+BRB$!``"&C"## +MCT'!I/*!X@OT!!.`((/@S@/+_P43@""`X,PA0828]">%.!(/(`JY0"%`(`4H +M?@`"A0H3ER`HN`3"#WCP(@``2B8`(``@00X(A0H@@#\````0"K@X8``@%`8" +M(14&%!80$`(@0"4_N%(@`(!9\@/PX(`.F!84B>`2F$@@@`$IPE0;OWJ[` +MX'CQP'(.S]X(=L]W@`#,V@"'C"##CP*F`-T']`(/;^@.AJZFKZ9R\*(-C^@A +MA@&`)GBN#F_H`:8/I@*'C>C/<(``;+8`@`"`A^BBIR^&!Y&!N`>Q(H<`V`;I +M*8?CN`!H0^&`MDFL`^&H*`OA@>1@K@' +ML26'R7`V"B```]HJATZ'!/`FI$JD`>4E#141%2=`$VJ``B-,`#^\4B0,D!4F +M3!/Q]6:D3H!*I&AQ[_$OALEP@@UO_P#:CH;/<(``=#HA@$&$KX8"(D``/[A2 +M(`"`884*\@(C@``1"%(`Y.`)]P"$#PT!$,]P```),88/#]^B"*__R7#5!<_> +M\"'8H=]X);_\:!'P<``/`BI0(G`!3+N`(G`A!` +MI<]S@`#,VN2CY:/FHP`A@`\@````!Z,HHP#:!_`5(XP`*J3_V`ZD`>+W"A2! +MSW"``&RV`(#@@`_P`HQY:8-!<_>\<"6#,_>>G`*(8`O@`!T.@`1`"`:0#8#R!``V&X!GD`$``@)7@$ +M&!`@`B9`$P'@`G\`W=KO#03/WE4AP"71\>!X\<">"\_>>G`.@%IR^!P(L$`3 +M`"":<4'`SW"``'0Z`8!*(0`@#0D!``D*'B`$&T`D`-@'\`&&0"!1`$`E0""A +M"+4`NG!*(``@#R!0)0L@@*3U\T`M@"`P)`XPB.X`W0?P`(6I=@AU`_"@AH#F +MS"4BD!WR`84"(``%/[A2(`"`\O,`V`"F'PJ?(*EW#/`&EQ,(G@#>"R_H`H=B +M#J__(8?@A_;OO@MOZ*EPVO&3"!Z@!I:&(/^%P/7/<(``M-<#@`#9#H`!@,=P +M!P``\))PRB%O`(#ARB$")@A@`(A`04_N5(A`8`' +M\FH+3^@`V4`;0"`J2B1``."!@("A@/%TP8'")`X! +MT74!V\![T74!W<(E3A,/#,$3@./*(V(`"?2&[8#CS"0B@`3R`ML#\`#;%>L? +M"U``-PN1`("`H($!@`(D3),A@8"B`R!```&B#_``V`"B`:(+\("!H(`A@0(D +M3),!@("B`R$!`"&BG0+OWFAP\<`J"L_>"'4`@!WHX87&A08-+]^I<`T/@1,2 +M"._^!H4$A08F`7```@``ZLDK>`GRSW#%[H+!`=DV#2`!0X4!V`+P`-A1`L_> +M((`P<,HA(0#@?RAP\<#6"<_>"'6F#^__*'<(=N*EI@DOYJEP*0+OWLEPX'C/ +M<*```!P<&(`/0````.!X;'`!")X%X'Y`@`/P0((/"(``9((K>_SS`O``VN!_ +M2'#/#`X``H0'8`_``V.!^\_>?-GPR1BY)7CP +M&ABPSW6@```@!QU8D`#>R7<+\.EPG@SO_@#9Z7`V#._^`-D!Y^]_[P\2D2(+ +M[_X%V-NE`!V`'P`,#P`('8`?````\``=@!_^````BB`(``*E`=C,'0`0P@Z/ +M_FT!S][@>/'`_@C/WL]VH```'*>&$0V>%\]P@``8VB()```/#9X6L@L@``#8 +M%@D``!$-WA:F"R```=@&"0``#PT>%Y8+(``"V/H(```1#5X7B@L@``/8Z@@` +M`!P>@!\`?```$0'/WA78SW&@```@81D8``@9@`\#`.``"=@>H1^AB-C0&0`` +M!!F`#P`$````V!NA`!F`#P`,`!G@?N!X\",_>SW:@```@`!Z`'P`,#P`( +M'H`?````\)(.[_\(=QN&^&`;IFP6$!``W1SP,FTU><=Q@`!DUP#8#R!``P6F +M0H$#@0#<8((`@``CPX-@HB.!`2```P"AX+U0#L+_`>6O?<=Q@`!DU^EP3@]OYP':X+TL#L+_`>6O?>4-$I'/<(``&-K2#8_^)@L``"T` +M[]X*X;J"B`!"G(<\`2%((`" +MAR)X.0A3`'X*+]_I<,]VH```(&P6$!`CAV!YZ7`0%P80ZLD&)H%Q``(``"MX +MV_6*#>__J7`*)P"0XO5>#:_^J7"]!X_>X'CQP)X-S__/<*```"`$&(`/``0/ +M``P8@`\```#PT<#@?O'`*@^/WJC!"'OWJC` +MX'CQP)8.C]X(=CIQ7@CO_AIRF'`=>`#:BB$)#RQ^FG'/<8``8#U`(1(&+W,* +M)8`O@``@/4`E%B=Y896)`".3#X``(#L`)<\@<8`$".#`+EA +M)Z#SZP0J/@4T(D`N,"9!+A,(0P#6#$_H@.`<".'GRB`A`P':)O`4B0'@%*DE +M"!$@%(D-"),"%HD9"%$`R7`J<03:)@YOXQIR`M@9IPIR$O`"VA#PR7`J<03? +M#@YOX^ERZ7(`W0;P`-VTJ5`?0!0(VLEPX@IOWZEQ706OWNIPX'B$*`D/SW&` +M`"P[,"%`#@*X%GC'<(``/-K@?N!XHL'QP`(-C]XZ<1IR"'>J#:_T:'5&"^__ +M0"B.`E,E0!40=LH@A0\``#41RB%%`^0.Y=[*(H4#Z7`N"._^*G'I<,8/K_X* +M<>EPE@ZO_LEQZ7`:#J_^J7'I<)H.[_0!V0S<"P6/WO'`@@_O_P#8H@J/_G8/ +M[_\!V)H*C_YN#^__`MB."H_^8@_O_P/8A@J/_M'`X'[@>.!^X'C/<(``A+8` +M@!,(40#/<:```#0`@5(@P`0`H>!^X'[@>/'`5@R/WNG))PC>`,]PH```1Q08 +M@`\```P,[,D%V0'@L[BUN+BX[!H8L!6Y!*'/<(``;#$`@`0@@`\/``#@+R@! +M`$X@000R&E@P`=T/"9`!SW"``/2W#I`MZ`;>>@RO\LEPX+C1(&&`)?1"#*_R +MR7`R$@$V"'(G"9$!SW"``/2W"9`-Z&();^(!V(P@PX\3\B,*`0`R&E@S#?`; +M"5$`2@EOX@'8C"##CP7R"PH!`#(:F#,R$@(VSW>@```$3Z=/(@`"SW:@`(!^ +M"*8.A\#@V_?JR=(:6+/@N,H@@@_%[H)&N`[B`,HA8@!N#R_T,LC."`_EBB#$ +M`0BF!]@/IS(:&#`&\,]PH`"((%5XH*"U`X_>SW&!``1&8H&AP00C@P\/_)__ +M4R#"`!2Z)KB&(/X'17AE>`*AX'^AP/'`!/!:"@_SSW"@``!%'H`$(+Z/<``` +M`/;UT<#@?N!X\<#R"H_>"';/<(``2+K6#^__IH@*(H`OH`"`1$`2`"#/=Z`` +M`$5&(`$-0!I`(`2'!""`#_]O_\,$IPR'!""`#_]__\,,IP`?@!\`0```X'@` +MV!IP`*<3;:5X#:=2#>_DJ7#/<8``>`L'@8[H`X&&(,,/`Z$)#1X0@+@#H0D- +M7A"$N`.A"B&`+X``L-\`$8`@#0T`$%(,3^D`&4(C0!(!(`4A@0\`@#0`0!I` +M(#+N%PY0$$L.D!"*(%H*0@SOWLEQ*/#/<:```!`)@0;H)!D`!-H(S_@0O8^] +MF[W/<(``%`D`@)^]Q+@*N`5]K*?V#L__BB#_#QRG&*<,\!"]C[W/<(``%`D` +M@)^]Q+@*N`5]K*=!`H_>\<"!@"AR`(``VU8+K]Z)<4APT<#@?N!X`-C/!^X'CQP)H)C][V#V`!"'?/=J```"`[AL]P@`"`,PX/[^4@H`AU`=F`YEPW@C/\\$!K]ZI<.!X\`-B* +M(!`@SW6``%C])H7/=J``B"`ZG/4@A`0`PI0#?6_`+ +M#%$00))(LP`90@0`W,]Q@``XVT"!#R3,$XMZ$!,$`0KRSW*``#3;H((`&4`$ +M`>6@HL]QH```'4R!!"(!`32S&6'/<(``0`D"@(MX'?3/<(``($<>@`(A`@`0 +M<""@!.9*(0`@`>># +M#S42*G`2I?D/T)$0A8#@S">BDF2*AX6;8WA@SW.``#2X]'N/Z0`G@1^` +M`%2X@(F"Y'7UB)-!DIM\@+R$>G+Q5),)"D4`&6*M\32S&6&I\0"E!!T`&,]P +MH```(!&`SW:``$`)`J4"AEC9$:4`V)&XJ7(*)(`/`P#__[X/X``3VQP=0!0$ +M'D`4W0=OW@IP\"'8H=P#=@^#*((8/```.1&`)YM[*(88#SW&``%C] +M0"$"`Q4A@P,)#I$0XZ,+\,]P@``@1Q^`!2C^`T$I`'0#HP#8!_#P(@,``>!P +M=`]HR$@$VSW6``/2W5B7/$_`G01`DL,]Q +MH```!%6AL@L@`P#>,LC+$@*V%"4!$,"Q`8)=")\#R+&H&80#$(K/3/0A2`&&X![-0BA-J%7@089;H`-@/((``"@Z@`!_9 +MR\D0B#-H-7DT($$@X;G4#X+>I2"1F!V$$U`=1!#+$@&V%7\!@00@@`\```!@ +MP*<;"($/````(,01``#/<8``4#`5>0"!$.``H9$&3][@>/'`$@Y/WC'(2B'` +M(<]QH``<+CF!SW>@```P!'DO*$$`3B"-!Y47%)8$%Q.6,A(0-L]VH```!#P> +M0!1*"F_\@-C/<*```'Y:<&`8@`\`@(``R@Z@`"IP!/`#V`JF#H8'Z'SH=@J/ +M^`Z&_/%@$@$@]0G?AZH.H``*<*EP@"#"`93ERB!%`P*X,""!#Z``&"P2;<=P +MH`"T+B"@+\@$O;M@0(,A@[A@17E"@R5Z(X`%(8&`RB""#P``PB%H#X+>@-G/ +M<*```!PDH)4?&)4$']B4G05/WN!X\"'((=AIQ`-\1\"\I@0!.(8`' +M#W@R:#`A@0^@`#0O$"("`,*Y#R=/$/+J&O`O*,$#3B"-!PX.H`"I<,C*,1(" +M-@*X,""!#Z``9"X0)T\31'D*7H*K_BI<.?OX@V@``?8205/WO'` +MV@QOW@/8L,$:<,]UH```!`BE$!41$`Z%P."^]P`6`$``%@!`0,`@P)S@RB!B +M#:0.HM[/("(#@6G`*)(`OH```,`HC +M@"^@```N5!,5(`04%J9($Q`@SW"``%@5`(!*(0`@".@`V,]QH/XL#GH(K_.6 +MN.H/+_Q*=07PL@ZOY>EP*>TO*$$#3B"/!^]Y,<@"N3`AC@^@`&0N$"7-$P1^ +M!2&1(PKP,F@P(8$/H`"T+@#:!@AO_$AS8NXO*8$#3B&`!P#9#R$!``L@0*`F +M?O;SZ_%*<#X-+_PJ<50;0"4$')BEQ0-/WN!X\`-G/<(``/-L@H.G) +MSW?_#___H<'/&EBP*0A>`,]PH```1Q08@`\```P,[,D%V@'@L[BUN+BX[!H8 +ML!6Z!*(#VL]VH```!%6F`=MIILL2`K8*((`OH```"*`:P`#,&D``I,W@N.(" +M`0#/<*``@$4P&(`/`"```<]P@`!L*&"@:B&``<]P@`!P*""@F@BO\4APRQ(" +MMC"*4R'``$2YPKG`&D(`,V@U>1"JQW&``.S)8($W"U\"I@QO\0#9RQ(!MH0H +M"0_$&0```"&!?X``(#O9&EBP1"@^"TZ!`"&!?X``'$Y`H1OP5B(#!`B#D+@( +MH__8$:,D$8``SW.``!#*`>`D&0(`,(H3:15X"&.#X,H@B0\```@K;`R)WB2& +MR\G/=8``1-VT&$0`Q!```,8.+_2I<<]WH```(#N'.&`!I=+)RQ(!MMH-+_$R +M$@(VSW*``,`(`(+/"`B#2``\*4R`(@O$+!8!*(@`@ +MRQ(!MK`1``%2<,`!!@`A@<]P1`#X\]P0```$(8$/````&`2XSW)$`/SU'6(` +M8N"XRB&B`03T*[D[><]R@``4"0*"1B"``05Y(J)&">```-@`A2\@`P``I00@ +MOL]@````RQ("ME8B`00'\B`9@`\`$0``"_#/<(``@#;04`!$>X!.F4H:&(L,/17D3IC*F#O!6)`$4&I$3 +MIA*&1"`^@P;TAB#\`\#@!/)J=9+P`)1*(``@0B`5!AJ1"G48X!.F"B0`)`;P +MXGDB?;A@$Z;=#465,H8$Y4#!2B$`(2]X02D/`N]_`N?O?S\(T0"T%``1&."X +M8&2X$Z;/<$0`X,(0B)X*;_$`V2X)+^A*($`@3@_/Y_X+[_4/>`(<`C``P!*F +M*G$A\!T)@0\`4-T',H8$Y4#!2B$`(@T)@`\``/((*G$5\+04`!%*)$`@&."X +M8&2X$Z:_J`-A#N`,<`C``P"IQ$J;+$@RV3"0`H,P@(J">];04`!%1#V20 +M&.`B?_UEIO&>"D_H(?``%@!`V!H8L``6`4#F&EBPF,NSR`B +M`\L2#+:T%``1!*:4%``0Z;C*)0$4RB+!(PCR(@AO]5IWRQ(,M@IU,LC/<8`` +M]+=`(0\,%'D(D:KH$(S/#20!"*"#P``\/_#N25Z +M5+`&\*@1``&X'`00SW"``(RKX(B@%``0@>`0%)`0[/3""N_UZ7!AN`]Y1;G/ +M:X +MSO0!A!$(G@:@'(`?`0"0`,;P0"C!(`HA@"^``.S)0"&`)S5Y*6#`%(`0#PA` +M`*`<@!\!`)$`LO#/<(``A+8`@""4#0B1``Z&$'$`V`/W`=B-Z*`<@!\``P`` +MSW&``"S.$8$!X!&AW/#/<*````P-@$(@``A((`$`BB`$"Q<)!0`Z#@`!RQ(, +MMJ`<@!^``0``$(P#N!5X<"!"!`0BOH\``(`3//)6)`$4$0I>`B`9@`\!`(L` +MMO!;"A\#!Y"AZ,]R@`"4*&&"V,D*ZRRXQ+@`VP\C`P`#@@1["/#`VABZ1'A0 +M<`';P'L&ZR`9@`\0`0``F/`@&8`/`0"(`)+P"8&TN`FA"9&GN`FQ#Y&GN`^Q +MB/`@&8`/`0"%`(3P)I`S%(`06PD.`,]Q@`"4*`&!V!("M@KH++K$N@#8#R"` +M`".!)'@(\,#8&+@$>A!R`=C`>`WH5B0!%`F!M+@)H0F1I[@)L0^1I[@/L0GP +M`80/")X!H!R`'P$`C0!4\(0O%AD`(8!_@`#4:CZ`"0F1``/9/J`>@(?HH!R` +M'P!!``!"\-+)'P@>``(*C_/+$@RV#"(`H,HC!@#*(X4$J!S`$`7PSW"@```@ +M>H!6)`(4&))!"P4`(!J`#P`%``#/<*```!TT&(`/0````#@8@`]`````SW"` +M`%@5`(`,Z`#8EKC/<:#^.`P2"F_S6)++$@RVSW"``(`W`8@-"%$`H!R`'P`) +M``!6)`,4"(//=P$!``#K>!'T"9-5)$0=)8-(DY8*X`)YD\L2#+:@%`$0)7B@ +M'``0ZW@%\@X.S^'S`$``[@HOY(EPTLD-"!\`RQ(!MF7PSW.``$3=SW&@```@ +M6X$!@T)X2"`,`,O)_)"&)_T(P@!(L*@LHC!@,0<\HC!@#(RL]T@`!,W19\`Y00<\H@Q0",(`>- +M:Z)"]P#8B.B)@K&\B:(%\&J":Z+Y\0AS!!F`#P`#``#`$0(`@6J1<\HDS1!" +M?)JA`!F`#P`!``#+$@&V#.BD$0(`I`Z7- +M@+BE&ARP4(G/X8@_PQ\L8$($`$RR,]T@`",N/0D`!`%>P&!?+$7"%X#5!$``;@1#`'#N(5X +M5!D$`&APAB#]#(P@`H(8]!-J%7C'<(``[,F'D"4,4A!(D!T*7@`5#%$08!$" +M`82Z8!F$``B0"0B>`(V[?+&&(_X,R.//`WTAB#UCPGRK@HO_"AP`]G/<*```!0IH`X*``$%Z'()#_S0 +M\#+(SW&``"3;`*'+R:00`0`5"1X%$0E?!96Y5@UOZ*080`#+R:00``#K>,_R +M]+@!WV`)0>'+R:00``#W"!X#"@ROWP'8RQ(!ML]T@`!(NAVQDQ*!L,]P@`!` +M#"A@AHS/<8``%`E`@4.X1"*#`9U\P+R&(MX#A7L'N(8@X0]E>$5X`*$R"J`` +M!-C+R1"(`[@6>#`@`2`$(8$$`]@"I84A`@T`&$10R\E=D``8A%#+R4^`%0H> +M`-G)1H``&(!0V:5ZE@W@ +M`+(4`Q%*"J_S`=C""8_SR\F4$```Z;@4"@'U>@[/XP\&```:"Z_?`MC+$@&V +M';'/<(``+-O2#Z_DX*#+R9@0`0"4&$``RQ(!MH`A`@`/D5V1";%(L9X-;_TF +M@!@/8"*:*(!``DP4@`-(:&+#+R:00`0"&(?6/"?+6"`_\`]G/ +M<*```!0IH,L2`[96(P($Z8)!#QX5SW2!`#1&"!0$$`F2&0RT`"6"0(16#B_A +M0"0#%(X(#^9#!0``I[@)LK2_"9+IHH`C`P4Z#B_A2)(#V`*ER\G/=Z```"`Q +MB,]R@``0[<*Y,B)0`,]R@`!T[2EBC+C+$@&V5B$"!`:"#0B>!AV29+B? +MN`JE$(D#N!9X,"$`(*'H')$_"!X#SW"``$BZ)8C/<(``F+E$*3X+,"!`#B,( +M7@`1@@>X%'C'<(``G*PZD!,)7@("@(#@(`WA^,H@80#+R3R0`!A$4,O)/9`` +M&$10R\DO@``80%#+R4`0`0$`&$10R\DQ@``80%#+R4@0`0$`&$10RQ(!MAR1 +MAB#_##\($`$S@8HB#```&$!0R\E0$`$!`!A$4,O)5!`!`0`81%#+$@&V')%$ +M>!<(@0`V@0`80%#+R5P0`0$`&$10RQ(!MAR1AB#]#(P@`H(3]&`1`0$`&$10 +MRQ(!MAR1!""`#P``C(`/"($/``"(@#F!`!A`4,L2`;:D$0``!""^CP``0(@' +M\@&!\+C0#T+?$/`Z@0`80%#+$@&VI!$```0@OH\```!'!/([@0`80%`$AA.F +M(!V`%`/8!:7+R0&`0PC>`,]R@``4"0*"((*&('\.1B&!`25X`**&#F```]C+ +MR<]R@`#P-X(0`0$`@AT($0).$@`&X[@P#&'BRB`A`@3P7@Y@``C8.X?`%P`0 +M`GG+R58@`@0]H@&2`=FF"N``2)+F#F_S`-A:#D_SSW"@``!%/(`8@%D(7P4$ +M(;Z/``8``";T!(4O)@CP(O++R;`0`0&`(0\*P@O@`$#8#'`5"%\#SW"@```( +M!(`O)@CP$/(!V<]P@``\VR"@:@MO_RAPSW&``*S/%8$!X!6AW@MOY0/=RQ(" +MMAIP+X*I<`8*;_%0@@0@OJ\&`,H`)_+/<(``="@#@(#@RB#B"L\@(@/*(0($ +M(`ABWLHB`@3/<8``K,\3@0'@$Z'/<(``6!4`@`GH`-C/<:#^T`QJ"B_SEKCV +M#P_S\P$``,]PH```!*J@RQ(!M@&!+PC>`*01#`"*(@D/Q!$!`,]P@`#Z/&)H +M3'D-#!X0-"!/#@GPN@WO]#0C3PX#\'81#P&ES5,@?H`(\M+)S!(!MKX)K^$R +M$@(VSW6``!S=J7"6"N_CRQ(!MLO)TA(1ML]V@`#0+Z`0$``!V%IP`*;6"V__ +MZ7``V2"F">B&('Z/L?++R:`8``32&EBT0@AO\P'8RQ(!ML]S@`#TMX(1``%^ +M$0(!6&"`$0(!&F(RR%!Z%7L>@UA@'J,!@9,(W@""">_U@-@(VJ42`;>D&IRP +MI[FKN:RYRQ(,MJ4:7+"PC`AS,Q2`$`2]I7C/=8$`<`:U`80]")X!B[F, +MN:4:7+#/<*```"[R@`WP+RC!`TX@C@!X>YI1I`4H23P$-BD&ARP<@UO +M_ZEPR\D!@!4(GP,RR``@@0^``%2X`!F"!*7-4R!^@`_RS!(!ML]P@`"4ME") +M2F"*(`0`J@SO^)@1`0``VZ7-+0A>`"\+7@>#N*4:'+#/<($`O#8!@,L2`;:8 +M&0``TLG"#Z_P,A("-@7PH[BE&ARPI'8B$*`$,`"&$?X``Y!S/<(``C*L`B$`D +M`0*$*!8)`"&`?X``U&M.@&:!?!`%`'AC%"7-```51Q$4>("9#!5&$6&9$+R% +M>\]T@`"LT'"DI(%>8&:!&+T4NZ5[IX%88!"]97UPD1+BI7MOI'21()80NV5Y +M,:0AE@*8$+DE>!*D0"\`!`4@@`$3I$`D`0YF@10ES0`&%441>&/IG11XH)D> +M8F&9$+VE>W6D9(&F@1B[%+VE>Z>!&F(0O65]<)&E>W2D-)%@EA"Y97DVI"&6 +M`IH0N25X%Z1`+0`$Y7@8I`04```9I,]P@`#HT%X)0``]`\_=SW&``/#)`[@5 +M>"$$K_L`8?'`M@KOW9AP*'<*(,"@2B4```\E!0``W`#;#R,#``#8"'$.\,]R@``T%/`B0@!K>@3R#R!```]X`>$O>>D) +M4H'@?N!X,1(!-@*X,""`#Z``9"[.$@*V)'@$>@#8#O`O*X$`3B.!!R]Y$")" +M`,]S@`!0UO`C00`E>//JZ0//^N!X\<"F"<_=*'8!W"8,[_H`+``0"'5J"Z_W +MR7#/_=)'C1`2``_]C@>,]P@`#P +M42"`*'"`(,(!E.'*($4``K@P(((/H``8+`*Y,"&`#Z``M"X/>`X@@(#@?\H@ +M8@#QP,]Q@`#4+T"!(8%%>1,)#P#/<(``]%%&#"_E`(#1P.!^X'CQP`H)S]TH +M=\]Q@`#4+T"!(8%%>08@38`4\JEPZ7'J#2_E`=IR"^_ZJ7`(=KH*K_?I<`H, +M+^7$>*EPX@GO\>EQ-0'/W0#:#R("`,]Q@`#T44"ASW&``/!1X'\`H<]P@`#T +M4:$$+^4`@/'`H@COW0#:"':6#2_E*'4>"^_ZR7`(=V8*K_>I<'X,+^7D>,EP +M?@KO\:EQX0#/W?'`<@C/W0AU`-X/)@X0SW&``/#)`[@5>`=AR7"V#^__']FI +M<`#=J7'IX#WA`*($"\,DE>-D"+^;P&ABP&WA#<&80`0?/<*````0.@.!_#B!``.!X +MX<7AQL]P@`!X5`"`SW&@```(`(`A&1B`@"`(``#;'/#/WP` +M(@$S9A$!!T-T+*)HN4@A#0`U:\=QH``$?:"A`-DIHF84`1!X3R`"`L]QH`"`?DBASW&@```$#Z'@?S(:&##@>/'`\@Z/W0AW*'9& +M(RB'"`^EP?@@@`$$N@1`$\`(.#_+/<*`` +M``0.@%,F01#Q"$2`'0E0`!$)D``;"=$``!:`0`$=$A``%H!``1T2$``6@$`` +MK?D&C]W@>/'`B@Z/W0AU*'8$\+H-#_+/<*````0.@/4(A(,`V0?P`!:`0`'A +M`1T2$/D)A(/-!H_=X'CQP%(.C]T(=RAU4R!^@,H@@@\```$\.`@BWLHAP@/' +M#1`00"7.$R2^P[V`Y`!X\!X\<"V#<__>@Z/^@'9SW"@```,,:`EH*X.C_K1P.!^X'BDX,H@*P"/]L3@ +MRB!K`(OVY.#*(*L`A_:,($*%`]C*("H!`-P-\)ID57H4>L]S@`!8H#4C@@`4 +M(0,#0+,!Y.L,E)#@?O'`@@V/W4+!SW*@`(`<`:+/,AHO<+!(#1P.!_J,#@>.'%ZA(,ML<,'A3/=*```"#/ +M=:``@!P$'8`?Q>Z-EYN$@:4!I2&E`HHAB@BX!7D#BA"X!7D$BABX!7DAI06* +M`:4'BB:*"+@%>0B*$+@%>0F*&+@%>2&E"XHJB@BX!7D,BA"X!7D-BABX!7DA +MI0^*+HH(N`5Y$(H0N`5Y$8H8N`5Y(:42B@&E%(HSB@BX!7D5BA"X!7D6BABX +M!7DAI3B*%XH(N25X.8H0N25X.HH8N25X`:4\BAN*"+DE>#V*$+DE>#Z*&+DE +M>`&E8:7@?\'%X'CAQ>H2`;9`(`P'52!#!7T)W@3/<:```"#/=:``@!P$'8`? +MQ>Z1[CN!(:4]@"&E/H`AI2"((:5"D".0$+I%>2&E1)`ED!"Z17DAI2:01Y`0 +MN45Y(:4@A"&E(80AI2*$(:4@@R&E(8,AI2*#(:4C@R&E)(,AI<]Q@`",JUN` +M((D(ND5Y(:4<@`&EX'_!Q>H2`;8I"=X&SW&@```@SW*@`(`.H2`;99"=X&SW&@```@SW*@`(``(:(H@"&B*8`A +MHBJ`(:(K@"&B+(`AHBV`(:(.@`&BX'[@>/'`@@J/W0AVSW"``(RKH(AZ<80M +M%AD`(8!_@`#4:S@0$0`\$!(`?!`0`+8(;_6I<.D($`#JR>4(W@3/<*```"#/ +M=Z``@!P$'X`?Q>ZX[QN`"B2`+X``5(`!I\&GSW:``%2!)H;/<(``5((?F!"Y +M)7@!I^H-+_48O1"XI!0!(:5X)7@!I_P4`"`!IP"&`:<#A@&G!(8!IR8102$J +M$4`A$+DE>`&G+A%`(3(102$0N"5X`:"?"I<,EQ*G)*""_E2G,!YL]^\PX2D0#>WP[3D*EPR7&2 +M""_E"G(!YL]^^/$$'T`1!!]`$00?0!$$'T`1!!]`$00?P!3!`8_=SW&@```@ +MSW*@`(``(:(H@"&B*8`AH@J``:+@?N!XZA(!MBL)'@3/<:```"#/Z#93N!(:-!D""0$+I%>2&C`I`!H^!^\<`&"8_="'7JR:+!00@>!,]PH``` +M(,]VH`"`'`0>@!_%[H:=&X"+<0&FH::!PAX+K_VI<`#``:8!P`&F=@JO_:EP +M`:;*":_]J7`!IBD!K]VBP.!XZA(!MB4)G@;/<:```"#/ZS +MV3N!(:(@@"&B`8`!HN!^X'CJ$@&V2PG>!<]QH```(,]RH`"`'`0:@`_%[H7; +M.X$AH@&BSW"``$BZ98C/<8``F+E$*SX+!H@P(4$.$+@E>`&BSW&``!0)`($! +MH@*!`:+@?NH2`[8E"]X$SW.@```@SW2@`(``&D +M(:3@?N!XZA(!M@?:+0F>!L]QH```(,]SH`"`'`0;@`_%[H??.X$AHP7P!!`! +M!"&C@.)ANOSUX'[@>.'%ZA(-M@M]B'09\@BY!2&!#\7N@`!E><]PH```(,]S +MH`"`'"&C&X`!HPCP"0P>$`""`:,$XIU\^NS@?\'%X'CQP.H2`;8A"9X'SW*@ +M```@(1J8C\7NF(4[@B$:6("2"2``&-G1P.!^ZA(!MA\)G@?/<:```"#/Z"A#N!(:(!HN!^ZA("MB$*G@?/Z# +M@UN"0:,AHP&CX'[@>.H2`;8?"9X'SW&@```@SW*@`(`!\]QH```(,]SH`"`'`0;@`_%[JV'.X$AHP#:!O#P(($``>(AH_D* +M%(,`V@CP0"`!##,A@0`!XB&C]0H4B.!^X'CJ$@&V)0F>!\]QH```(,]RH`"` +M'`0:@`_%[H*&.X$AHB"`(:(!@`&BX'[@>/'`5@Y/W2AVZA(!ML]W@`#<5C07 +M$!%A"=X$SW&@```@SW6@`(``$%@7@1`,N`4@0`04N25X#>XACD*.!KD.NB5Z!1;!$!:Y)7H%()`@ +M`:4$'0`4109/W0?P!!`#!,]RH`"`'&&B@.%AN?GUX'[@>`>X%'C'<(``G*LH +MJ`#;(X!JJ/00`@"6(1@`0GD)"5(``=DJJ.!_8Z#QP.'%LL$)V#(:&##/=:`` +M``0/I8MP0@^O_P+9#H4$%`$Q_0A$@`#`$'H_"E$!#'"`W>>XRB#A!F`/H=W` +M*&$"(@Y/\#8-C^[/<*```!RDH.G)A0@>`L]PH```1Q`8@`\```P,./`="I$` +M@L#J#J__!-D"P`/!!,(^#Z_=!<,L\!,*$0Y1"5,$@L#.#J__0KDB\-@:F+^0 +M````YAH8L-'B`<#G&ABP%O3IR2D('@+/<*```$<4&(`/```,#.S)!=D!X+.X +MM;BXN.P:&+`5N02AJ@R/[@(4`#$$((`/````@$^X*PA1``84`#$C"!X``-A! +MP(MP`-E2""``*'()V3(:6##/<*````0OH!D%;]VRP/'`(9`$(8$/````@$^Y +M%PE1`".0#PD>``#9(:`:""``*'+/<*```!P8&(`/(````-'`X'[QP&(,3]T( +M=2AWPI`'ZK;-(6C.N;8:7+`!M0C8,AH8,,]QH```!`^A#($N@2)X0"8!$@T) +M!0!3)GZ0!_+/<````386#H_=J7`6">_\`MD'[NEP#@GO_$$N@1!U!$_=X'CQ +MP%X.S__/<*```!P8&(`/(````-'`X'Z$*`D/BB3\'P`A@'^``"`[28#FN@0B +M`P/*(8$``_)0(L$!Y;K$(0(#Y+K0(V(!X[K0(2(!07RR\D``@@P^```?* +M@*L.\,]P@``&2H8*@!XD]ZYPH2@>!_P<7@?N!XZLD] +M"%X`SW"@```@SW&@`(`.K).0B>`<]PH```(,]QH`"`'`09@`_%[H9H&X#/ +M`ARG.#,(N*%%_+JR2L( +M'@'/<*```"#/Z#X!N`17D!H\]P@`"H#0"``:,AH^!^ZA(" +MMB$*'@;/Z#%5N"0:,!HR&CX'[@>.H2`[8C"QX& +MSW.@```@SW2@`(`!L]SH``` +M(,]TH`"`'`0<@!_%[H2R>X-AI`&D(:1!I.!^ZA("MB$*'@;/Z#LUN"0:,!HR&CX'[@>.H2`[8C"QX&SW.@```@SW2@`(`!L]QH```(,]RH`"`'`0:@`_%[H*W +M.X$AH@&BX'[J$@*V4PH>!L]SH```(,]RH`"`'`0:@`_%[H\8>X-AH@&B`)$! +MH@&1`:(!@0&B`H$!H@.!`:($@0&B%(D!HA6)`:(+D0&B#)$!HAJ)`:(;B0&B +M'(D!HN!^ZA(!MA\)'@;/<:```"#/Z"M#N!(:(!HN!^ZA(" +MMB$*'@;/Z#M5N"0:,!HR&CX'[@>.'%ZA(-MHAT +M+0T>%@B\A7D(N45Y"+EE><]RH```(,]SH`"`'`0;@`_%[H,06X)!HP&C(:/@ +M?\'%ZA("MB$*'@;/Z#%%N"0:,!HR&CX'[@>.H2 +M`[8M"QX&SW.@```@SW2@`(`H2#+8G#!X6SW2@```@SW6@`(`!L]QH```(,]RH`"`'`0:@`_%[H*V.X$AH@&BX'[/ +M<(```%0`$`0``=D($`4`SW#%[H>2V!("MDHF``#F$@.V[0*O_PHG@`'@>/'` +MX<6AP5EP.7$9!T#`SW#%[HC%`=E)/'`X<59<#EQ&7+X<^H2`;:H<(ATR'4I"1X'$+T( +MN`5]SW#%[H;*`=E)/'`"'0H<^K)F'+\N,H@@@_%[H3$RB%B +M`/P)HO_*(@(#T<#@?O'`"'0H<^K)F'+\N,H@@@_%[H3'RB%B`-@)HO_*(@(# +MT<#@?N'%N'+J$@*VB'0M"IX!0"T"`D5XSW*@```@SW6@`(`Z%4QN` +M`:'/<(``G`MO@&&A0:'2R0&ASW"@```,#8!"(``(2"````&A4PH1`C4+W@($ +M&8`/Q>X%6X';"+L-\%)K%=P3O/`DP!`$XH)B`N,0ND5X`:'M#L7P```)@0_P +M!!F`#\7N`V//`L]P@0"X+B"`4-L!@$AT"+L%(X,/Q>Z, +M`,]UH`"`'&&E?H)AI7V"8:5N@F&ESW.``*"[:I-AI7""8:5/@D&E891`E!"[ +M97I!I4&$9)0PNA"[97I!I4.$:)0PNA"[97I!I524;I00NF5Z0:4AI0&EX'_! +MQ>!XX<7J$@RV*0Q>$<]TH```(,]UH`"`'`0=@!_%[H4YFX0,N8&E(:4!I4&E +M8:7@?\'%X<7J$@RV)PR>$<]TH```(,]UH`"`'`0=@!_%[H5IFX2!I0&E(:5! +MI6&EX'_!Q>!XX<7AQNH2#+8K#)X0SW6@```@SW:@`(`Z%,AN``:38R0&D`(,!I"&D0:3@?N!XX<7AQ@AS +MZLF8<9T('@#+R3R01"$``Q$($0+FN4/8RB!A#`/P,-@(N`4@@`_%[H\`SW2@ +M```@SW6@`(`<`:7;A,`4`!`"?L&E8:78R0&E0"P`!D5X`:7+R2&`(:56(`$$ +M28%!I4:!0:5'@4&E0"`"#F&2P)(0N\5[8:5A@D22,+L0NF5Z0:5@$`(!5!`` +M`1"Z17@!I1J$`:72R0&E$X$!I12!`:7!QN!_P<7@>,]PH`"`'`08@`_%[@$$ +M!!B`#P4`!(3@?O'`X<4(<<]P1``(B2U@C"7#GP7RC"%"C<7V_M@Z#6_=B[BU +M`R_=J7#QP#(+#]T(=>"(P8"$Y\H@A@\``!(T&`UFW%`@""%P'Q0<0';P'N'>X'F`=S")`$3SW````$T@..5>.0,0MU) +M`P_=`-H#\`'B02B!`/T*1(#@?@OI@+C/,]RH```('N"!_#/<:```#P$@14('P`;@F)XC"`'C;?W +M`-@&\`2!\P@>@`'8X'[@>'RX`_!NN`$(4P#@?O'`-@H/W2AU#PE?!00@OH\` +M!@``'O(]#1\5SW:@```@;!80$!3P.(<.#&_=BB":"@[PSW>@``!%N(=""8_Q +M&X8"(``$XPB#CP``$"?G#1Z530(/W?'`X<7/=:````@VA02%$'@X8(HA$@H6 +M>0#8!@_O_XNX&@_O_PK8%@_O_PK8`-G/<*```$4DH`/8!Z6R"T_R)0(/W>!X +M\<#AQ0QQSW"@```(SW6@``!(10D>`S:`!(`0>#A@BB$2"A9YM@[O_X#8#'`I +M"!X#SW"``#S;`=D@H#`5`);BN&0.8O[*($(`SW&``*S/%8$!X!6A`-A$'1B0 +M`]G/<*````@GH$(+3_*U`0_=\<#AQ0#=F+T`V`K9SW*@```@,*(!V0<:6(`0 +MV2"B"',(<0AR%/!2"(_QSW&@``!%'($`VSB!`-J5NA$)7P4$(+Z/``8```/R +M`=L$>@QT[+S,(R&`S"(A@`3T;'++"AZ`;'(E"AX``=G/<(``/-L@H,H-;_XH +M<,]Q@`"LSQ6!`>`5H0GP!.MZ#L__!?`,<.RXP'T*[<]Q@`"LSQN!`>">"F_R +M&Z$-`2_=J7#@>/'`A@@/W0AUSW"@```@;!`0`$X.K_NI<`3>SW>@``!'Q*<8 +M\,6GSW*@``!\48+/<```SB):"F_=J7$,\%X*3^7/<`\`0$*""N_I"G'9"%"` +MSW"@```,#8!"(``(2"```-T(1(/%IXD`#]W@>/'`_@_/W$AW0(D(=@&)&+H0 +MN`=Z`HECA@BX1WA#B0=Z`(8'((D`!(E%B1BX$+I'>$:)"+I'>$>)!WH!A@<@ +MA0`(B4F)&+@0ND=X2HD(ND=X2XD'>@*&!R"$``R)38D8N!"Z1WA.B0BZ+XE' +M>"=X!WM*)$`A9/`Z"._U`-EZ<,IP+@CO]0'9!R,3("EP(@CO]0+9!R,3(`EP +M%@CO]0/9((8'(,`$!R$)`$$J`!8""._U`-D9<.AP^@^O]0'9!R`'`HAP[@^O +M]0+9!R<'`*APX@^O]0/9(88'(,`!!R$%`$$M`!;.#Z_U`-D(=#Z_U`-D(&.&!WM!*0`6;@^O]0#9"'5!*P`$ +M#WAB#Z_U`=D'?4$L``(/>%(/K_4"V0=]+R!'`48/K_4#V22&IW@'(1,`02T` +M!C8/K_4`V0AU02D`%`]X)@^O]0'9!WU!*P`"#W@:#Z_U`MD'?2\@!P$.#Z_U +M`]DEAJ=X!R$*`$$L``;Z#J_U`-D(=4$M``0/>.X.K_4!V0=]02D`$@]XW@ZO +M]0+9!WUO>-8.K_4#V:=XIH8O(<T$M``(/>*8.K_4"V0=[+R!'`IH.K_4#V6=X9X:`)/^O!WL@YD$K``1! +M+0$2+R"'$D$K!R1!*P("+R5'`T$J!A1!*PLB+R#'($$M%11!*A(2+R8'("\A +M1Q`O)\$$H`08@KT$H`00AKT$H`0(B +MKP.O02H`%L8-K_4$V00@R`3H<+H-K_4$V00@``4'(`@0B'"J#:_U!-D$($`" +M!R`($*APF@VO]039#W@AA@<@``(G>$$H`08DKT$H`00EKT$H`0(FKP>O02T` +M%G(-K_4$V00@S03(<&8-K_4$V00@``4'?6EP6@VO]039!"!``@=]"G!*#:_U +M!-D/>`=]`H:G>$$H`08HKT$H`00IKT$H`0(+KRJO02L`!B8-K_4$V00@PP2J +MTIP"@VO]039!"!``@=[*G#^#*_U!-D/>`=[`X9G>$$H +M`08LKT$H`00MKT$H`0(NKWD$[]P/K_'`2@S/W*()(``(=0#;*-@7\!4EP1`5 +M)0(0@(+`@8"AP**!@L&!@:'!HH*"PH&"H<*B@X+#@8.APZ($XV2XUPL"@`'; +MJ_`0%0`2.+C"#*_U!-D/>((,K_4`V0AV`(4PN`]XK@RO]039#WAN#*_U`=D' +M?@"%*+@/>)8,K_4$V0]X5@RO]0+9!WX`C88,K_4$V0]X1@RO]0/9QW@`I0&% +M.+AN#*_U!-D/>"X,K_4`V0AV`84PN`]X6@RO]039#W@:#*_U`=D'?@&%*+@/ +M>$(,K_4$V0]X`@RO]0+9!WX$C3(,K_4$V0]X\@NO]0/9QW@!I0*%.+@:#*_U +M!-D/>-H+K_4`V0AV`H4PN`]X!@RO]039#WC&"Z_U`=D'?@*%*+@/>.X+K_4$ +MV0]XK@NO]0+9!WX(C=X+K_4$V0]XG@NO]0/9QW@"I0.%.+C&"Z_U!-D/>(8+ +MK_4`V0AV`X4PN`]XL@NO]039#WAR"Z_U`=D'?@.%*+@/>)H+K_4$V0]X6@NO +M]0+9!WX,C8H+K_4$V0]X2@NO]0/9QW@#I0'CBN.J!LO_&0//W/'`H@K/W$") +M"'4!B1BZ$+@'>@*)"+@'>@.)1W@`I42)!8D8NA"X!WH&B0BX!WH'B4=X`:4( +MB4F)&+@0N@=Z"HD(N`=Z"XE'>`*E#(E-B1BX$+H'>@Z)"+@'>@^)1W@#I0#? +M//##A4$N`!0/>/X*K_4$V6"%!""`#P#_```'>T$N`!(/>.8*K_4$V00@@`__ +M````!WO/>-8*K_4$V00@@`\```#_!WM!+@`6P@JO]039#WC/<40`Z)#P(<$# +M9W@G>"&%!*4G>"*%!:4G>".%!J4G>`>E$.4!YXT/DI(Q`L_<37#/<8``G`L` +MV@L(W@%4D<.Z@8'/<$0`/.'/`@'8`_``V.!^\#B_\"-I`)0`20"W1($IQ3@XO_"IR +MAL!Z<.H,[_\*<078`_!")D`@"B8`H&(`!`!"(0XB0G:J=^\/4I""Q8IPJ7$: +M#B_\"-H$+GXE#Q2!,``AP',G>`\<`C!`)!`TR7`*""`` +M"B>``5H*(``!V-'`X'[QP.'%HL$'V&'``=@%'`(P`]D&'$(PSW"``'C>`(#/ +M=8``.#N$*`D/@<(&V$#`T-@`VYASN',`)48>@@X@`?AS40#OW*+`X'CQP,H/ +MK]P9<*;!.7.(=ZATR'7H<$H@0"(#WF/Q",(/I"G$Q\!<)4`!!"9``SW`` +M`+$-E@D/W?7Q#AR",`\<`C-(O&3$0"B`$(&X0"F!$05Y,'@1'$(P2+@2'`(P +M$QS",TB_9`("$*`D/`"&,?X``(#N#PA\+'@"!P]#82B0``$HE``!`)`86 +M2@P@`4HG```,\`;80,#0V`#;F'.X-AQ^'(" +MV0#:2'.8/'` +MX<7/=8``@%0`A83HQ@I``0"E">@BD(?IZ@E``?GQU@I``0"E!>@"D/D('H#* +M"4`!@.`T".+ERB"B`OT&C]PY`H_T\<#/<$4`E#<`@,]Q@0!@.*X(8`&*(AH. +ME@_/___:SW"``/SY+!B"`"BZ+1B"`-'`X'[@>/'`X<7/<$4`-#@`@`#=".C/ +M<(``2!4`@`D(4`"I<`;P`@J/\_SH`=B9!H_<\<#/<(``?-X`B.8/K^\`V<]Q +M@`!XWMX-X```H=(*``'/<44`-#@7B1,(40`6B0?HU@W/_RX((```V,]P@`"L +MMP"`@."D",+V`@F/]-'`X'X`VL]Q@`!!X\<#/<8``2!4@@0OI +M`=K/<8``7-X6>4&A7@COY0G8T<#@?N!X\<#AQ0#=#?#/<(``7-ZV>"&`"PE1 +M``"`0'@!Y:]][0W2D,]P10`T.!:(@.`4#Z'ERB!A`MT%C]SQP$X-C]P:<#IQ +M2B,`(``8P`1J<#()8`$`&<`$"';/<8``Y.>V#R`!HY#/=X``@%21Z,]Q@`#4 +MYZ(/(`')<(#@S"6"GP``@3?,)8*?``"`\PGR((<#D0C@`[$%D6BX!;$6\,]Q +M@`#LYTX/(`')<$"')9()Z`.29+D$X`.R);((W0;P+WTHN0B]+WDE?7(/(`$` +MV,]V@0!X+HPE&)(*(H`O``"&W0>V!/(`WPSPSW"!`.`T`(#U"!Z`S@RO]`IP +M`=\=#8$4SW"!`.`T`(`1"%X`O@VO]"IP@.#*)V$0.@A``3IPSW"``)P+`)!` +M(1`D%P@>`@IPR7&R"B_\`]I`(8`B"/!`(0`AR7&>"B_\`]H*<"9NE@HO_`/: +MIK:'[\]Q@`"8%``9P`2%!*_4(6@!`0N`5Y0Q:`$!BX!7F`X7/=44`-#A`A44*W@%!%H$00!:`$`BY)7A"%H$0$+DE>$,6@1`8 +MN25X!""^CP(`;``.\NH.3_,`V'X/(`$`I8X/0`!.#:_E"M@0\.MZ#O)2#8_V +M".A"#8_V@.!H#J+VRB"B`.H*3^[I`X_<\`^"*_A`-G)<$(((`"I<:EP`-DXV@3P:+H`V2(( +MC^$$AA2F!885ILEP(@@@`*EQR7#I<38(+_P0VLEP`-D""*_A!-I]`X_<\<#N +M"H_<`!`7`(.`PH"A@`@`1%@`'(@\#`B:#+Y4HB%O[8^)S5VLYNV5Z +MNF(')D,31'L$$08`!R./`P(F@P\X%ZI(^V.;8T`K#`,TNV5\7&0')8,0A'L( +M$0@`!R-/`P`@@Q\@)-MP^V/;8T`K3@0ON\5[FV,')(X09'X,$04`!R:/$`(E +MC@]"/A(Q_F;=94`MCA4JO<5]?64'),X0I'X0$1,`!R8/$P(CCB^#"E'P_F;: +M8M=J.;K%>KIB!R-/`T1_%!$2`&=_`"*.+X='*L;^9MQD0"P.$S2\A7Y>9@QP1%``' +M(X\``B2#+[D"_VK[8[MC0"N-!2J[97V=90R`1$0`'(X\#`"&#+X!I +MV)C[8WIB=VHYND5[NV,')$(39'HD$1``!R(/`P(@@B^[=%$(7V?^9D`N`A,T +MOL5Z>F(')S01!P`'(\X#`B>##V<";8[;8WIB +M0"H.`S2Z17Z>9@C@1!``'(D,#`B2"#X997EA!R--`,1]!R7/$`(F +MC0_A"9[:_66\9+5L.[R%?3UE!R%,`V1\!R1/$`(AC!^_/\!,_&2>9D`N3!(W +MOL5\O&0')$X3)'X')D\3`"*.'UXF45K^9MMC0"N.`S*[Q7N;8P7EA!R-.`(1^!R;/$`(BCB_0*:/O_F;= +M9=5M.[W%?3UE!R%.`V1^!R9/$``CCA]$`E,4_F;<9$`L3A(WO,5\O&0')$X3 +M)'X')D\3`B*.#UXG?QG^9MMC0"N.`S*[Q7N;8P\A7T]90?+\ +M9)MC0"N,`S*[A7N[8P.#QQ6^Q;^9MEAU6D[N<5YF6$')$X09'X')@\3`B".'Q`#"%S^ +M9MUE0"U.$C>]Q7T]90[MC!R7/$"=_`B:,#T%;O!7\9)YFE&X\OL5\?&0'(P\#IW\`(XXOWDNIS_YF +MV6%`*9EA!R$/`V=_`B2.+T0)H+3^9MUE0"T.%#"]Q7T]90%0;8_&2984`IS`(UN85YV6$'(8P#9WP")8\/$"M[ +MSY]G_65`+0P4,+VE?#QD!R$-`\=]`"&/'X@$!1W]9;MC0"O-!2F[97V=90[MC!R7.$(=^`B6/+R09&V;?9_EA0"G. +M`C6YQ7EY80;EADGLE>Z=[`B6/#_-P;C/[8WYF +M0"Z#$C:^Q7L[8[)^97XG?@(CCQ\0`(,+WV?\9$`LSA,QO(5^?F8R?,5\9WP" +M)H\/>WHOHI]G_65`+4P5*[VE?-QD:5YAWD"(H(/TP$@&5EA.V-`*X\"-KME?[]GDGGE>:=Y`B&"'_Y<[+Q9 +M8=EA0"G"`S&Y)7KZ8K)Y17GG>0`G@P\(3J$1.V.;8T`K004KNV5Y66'R>R5[ +M1WL"(XPOK`A^@9MC?65V;3J]I7L[8U)\97PG?`(BC1_%0LL-O&3\9$`LC1(V +MO*5\?&0R?H5^9WX`((T?URJ[TMUENF)`*LT#,;JE>IIB)S(8!@H+EA(:`B@#IB(X!"H)EAA0-OW".@\<`V +M"T_<@B0#/!IP*'=ZX/+^%!VD`D`"?)<>(/+^%! +MV@IPRG$&"._[Z7(*<$`D`2?Z#Z_[Z7(0\``D@#-8$($``>9'(8$-6!A"`)P0 +M@0"'(0$'G!A"`,#FL?=>""``J7"I<,IQ?@@@`$#:`-X*\/`B@2,R)8(C:@@@ +M`*EP`>;Q#L24*G`:#Z__J7$N""``J7"I<$`D`2=*""``0-JI<"IQ0@@@`!#: +M*G#V#J__J7&9`F_<@"0#/``8@`]%9P$C!!B`#\WOB:L(&(`/NIC^W`P8@`\R +M$'94`-DDH.!_):#QP"X*3]P(=4AW1(`H=A8BP0,DH`L)I0`%@`'@!:5!+T$7 +M.&`CNE,B0H$%I4`E$18>\D#<#B(0`P`A@2`Y#R04R7`*#Z_["G*I<.(.K_\J +M<0)V`B*+!\',(:*`9/0!B!CH@>#,(**`7O*Y"-$`3@W@``38 +M((@!V(+AP'A/"5``@N'^W,PA`H,D\@#8)/`N#>``!-@`B(T(40`B#>``"-@` +MB($(40"`VL]Q@`#\^4`9@@`HND$9@@`HND(9@@`HND,9@@`@V"SP"@H/]03P +MI@T/]<]Q@`!$%0"AI.C/$,2@0`8 +MN25XC"`$@!#R$-@(<4`:0@`HN4$:0@`HN4(:0@`HN4,:0@"&#(__T<#@?O'` +ML@A/W,]U@0`P,P>-!.@&C06M`-XR""``R7`FC06-]0D!@,:MQ:WY`&_,]Q@``L^$"1"0HC``&Q0;&M`L``\@!ZBB7^ +M&1;PBB5^&Q+PBB4^&Q#PBB4^'`SPBB5^'`KPBB5^'0;PBB7^'03PBB6^'AF. +MHG@'W0&IP^7*((T/``"](3`)K=S*(4T#SW"``'C>`(#/=H``.#N$*`D/!MA` +MP-#8J7$*<@#;F'.X`, +M)P"``"1-,("-RB`N`("OP*T!XHPB!("K]P#8"'$(=`[P`>`/>``D#C"@C@'D +MN6$O>0`D3S!`CT"NH*_G#$21`-T9\`'@#W@`)`XP0(X!Y5EA+WD`)$\P@(^` +MKD"O,B0,,)IB3WHR)(PP0(N'>@$;D@#5#021M08OW(`D!##@>`ATF'%(<&AQ +M`-H]!^__B7/QP!X.+]P`V,]Q@`!(%2"!@.'$\D0B`%.$X._RS@]/_X#@[/+/ +M<(``@%0`@`?HSW!$``SR`("`X*_T1"(`4XC@SW6``)P+F/3`%8`0@."4],8) +M``#J"2``"-C/=H``@%0`AH#@%=@X\L]P@`!HN@"`SW&``.2[/@\O^2"!SW&@ +M```,!*$`A@J`4@IOW"Z%#X43"%X&((8#D03@`[$%D62X&/`A"-X&((8#D0C@ +M`[$%D6RX!;$!V<]P@`!0%2"@"_`3")X&((8#D0C@`[$%D6BX!;$`V`H@`*!* +M(0`@"B*`+X``F!0`&D`D((8O]"KI%)4!V@`:@"!)"-X!HY'ED0CP<@AO]0(G +MSQ1B=;!]-0]R$$`E`A,`ABJ`,F)/>0BY*+I%>26P0"6"$P[A0[!#:=4/99!& +M(M,`!!A$!`3P-@A/];H/+_4*<`"&"N@"D`CH$0@1(*X(P``^",``!/"&#X`` +M`!(`((#@%=C*("$`37&E"9X!3_``E88@_`",(`*`#?3/<(``'!D&@(?HSW!% +M`#0X&8@+"!\!`-@\\,]Q@`"@NP&!SW6``##1`*4"@0&E`X$"I02!`Z4*D0BU +M"Y$)M0Z!!:4/@<]Q@`#DNV2X!J7/<(``:+H`@-X-+_D@@<]QH```#`2A)H6* +M(`D&"2$!`.X(;]Q`)0`7#?#/<(``G`L`D(8@_`#0X(#/'`+P@1 +M`DUQ)PF?`<]Q@`"<"V&!SW*@```D'X*.@13@""0`$+@1`0%?@L"[$/"6Z,]S +M@`"<"\]RH```)!^"+H,((0``N!,!`5^";X-J#H``SW&``(!4`*'1P.!^\<#/ +M<(``7!4`@"79++C#N)H,;_\`VKH-;_\"V-'`X'[QP'8++]Q`(0(%HL$(=BAU +M`-D1\(3A;R`+`/`B`P!3(4P`3B3`$`.X&7L`)$`P8*@!X>4)%(+/=X``N..I +M<.EQ`_"I<")OI@E@``':!86&(/@!C"`'@/?UBW>I<.EQC@E@``C:`-H/\$$J +M@`#P)0`04R)#`$XCP0`#N3EX7&8`K`'BZ0H4A:EP`-G6#^_@!-KI<`#9R@_O +MX`C:20,OW*+``!B`#T5G`2,$&(`/S>^)JP@8@`^ZF/[<#!B`#S(0=E00&(`/ +MTL/PX0#9)J#@?R6@\<"F"B_<^'#/<(``.`\@H``7#P`$%PX`Z7`(%PD`R7$, +M%P8`*7(0%P@`R',*)``"\@TO]4HE````(`T"0RZ($*EPZ7$)#"_U +M2B5`!``@3P)#+8D0Z7#)<2ERR',*)``"0@PO]4HE@`0`(`T"0RZ($*EPZ7$) +M() +M+_5*)8`+`"".`4,OAA#)<*EQR'()"2_U2B5`#0`@3P)#+8D0Z7#)<2ERR',*)``"`@DO +M]4HE@`T`(`T"0RZ($*EPZ7$)8(+_5*)<`-`"".`4,OAA#)<*EQ +MR'()#N_TBB5!`P`@CP%#+8T0Z7#)<:ER"7,*)$`"P@[O](HE +M@0,A<-AP0RZ.$.EQR7*I9A`7```,'X`#'64%`N_;$!]``^!X +M\<"&"<_;"'8:<06`2'=!*,(`Q;IS;_9X!:8-".4`)H8!X2:F02]`%SA@!J;X +M8K_@W?=`)A$7`"&!($#<#B(-`PIP8@XO^ZERR7"B#J__*G$'\``E`126#J__ +MR7!`Y4`EP!_S",2#`-H"\`#=`"4`%$`F`1=982X.+_L")T(3;0'/V^!XHL'Q +MP/((S]N")`,Y0AR8,$,?Q#U20J7#N#*__R7&&#:__R7#) +M<$`B`2C"#N__0-K)<*EQN@[O_Q3:J7#*#*__R7$,W'L`[]N`)`,YX'B$*`D/ +MSW&!`"@T`"&`?X``(#M`(`($&.!!H0>AX'\-H<]T1``\X504`1;/<($`*#0B +MH,]R@`#@]T`B`08CH`#;9*`TA'2H**!`(H$(*:!`(@$+*J#0%`$0+!C"`"Z@ +M0"*!#2^@5B(!`C"@X']$&,(`\<"R#X_;:'5EBAIP!(H(NV=X`+4'BD:*"+A' +M>`&U08D`B0BZ1W@"M4.)`HD(ND=X`[4$B26)"+DG>`2U`-]-\%,G$1`4($XD +M08X@C@BZ1WDG>%X+[_D0>&"50"&"('A@%""!(`"U0(DAB0BY1WDG>#X+[_D0 +M>&&50"$"(7A@%""!(`&U0(DAB0BY1WDG>"(+[_D0>&*50"&"(7A@%""!(`*U +M0(DAB0BY1WDG>`(+[_D0>".5.&`#M4&.((X(ND=Y)WCN"N_Y$'@DE1EA^6$! +MYS!X[W\DM6T/$I(]!X_;X'BAP?'`U@ZOVSEQI<$D'$(Q"'09EPN@OO]`/:Z7"H<;(+[_3)X+H"VM4AX@S*(F$` +MU2'A!!9Y(*/3:L]P@0`H-$`@$05Z<`&!U'Y:ER`>`$H0"#(8,$X&X,[_]C@P&/*G$` +MK@&/QKB%N`&N`(\"KB#8`ZX!AP&F0X4*<-(.K_G),]P10`T.`*0 +M$."=`6_Z$'CQP+X/C^[/<44`-#APN`*QT<#@?O'`X<4D$H``@>`!V,(@`0`O +M"8`/K:O^R@#=`_`!Y1D-%152;51ZSW-$`#C#0F/Q"8&`!/"*)?\?C"7_GP?T +MSW```,8AB@W/VPWP,FTT><=Q1``XPT*!!.I@>B&!`@H@`*EP[0./V^!X\<#A +MQ<]Q@`!XWB"!*PA!``#=$?`2;11X`""!#T0`.,-"@07J`]A@>B&!S@D@`*EP +M`>7E#125L0./V^!X\<``V@7PM@D@`$AP`>+["A2%T<#@?N!X\<`6"X_;SW&` +M`'C>(($W"$$``-X5\+)NM'W'=40`.,,`A<]WK:O^RA4(P`.&"H_O0H4%Z@+8 +M8'HAA>"E`>;;#A2500./V^!X\<"R"H_;J<%"P%IQ2'5H=@P<`#$0'$`Q"B.` +M(<]Q10`T.!@1E0!`(Q$"SW&``'S>((G/``.#WA"@)#P`A@G^``"`[ +M#H(`(98DX+C")4(E0"8'(>EP:G$0XJES"B2`!`HE0`4V"^__"B:`!1#?"B0` +M)"+P@N#`?R#TSW%$`'SB!I%`(0(#`>`O)@CP!K$*]&>1`>,O)LCP9[$$]&B1 +M`>-HL0"V`-@"KB#8`ZX!D@C?`K8"D@.V,G7*($(#RB%"!,0.XOK*(H($R74" +M\`#?!MA`P``G@10"P#!Y#!0$,*ER$!0%,(IS"B;`!"H((``$%`!_(J#QP#8)C]LZ<'`<2+!!PD+#"B0` +M(0H@0"$,'(`QSW"``-#E`(`0',`Q1\"(QLEPSW&``%#FO@ROVSC:EL6I<,]Q +M@`">#*_;'-J'P%W`7L:`'$`S`-T#\`'E(0T5 +M%1)M%'C'<$0`.,,@@/$)@8^MJ_[*`H#RZ`3PBB7_'T0A%2-,)0"B`=C`>$;` +M`-X-#1$BSW!%`#0XV(@"P`_HSW"``'S>((C/`(![!$*F$[Q$9@@4@ +M\(/GRB#A`A;R@N?*(*$"$O(C#U$042(`HQ$90@;*($$&`_()V!&I0BH"(L&Z +M!KI%>!&I`L`4X<(,[_H0VA[!#]@H&0`&0"$""!$:@@42J@3`-!F$!=.J-AF$ +M!2[H!L`LZ(`4`#"*(08"(+``$P$@SW"``%@[A"D)#S`@0`Z`YD0@`02`%``P +M++"`%`$P#)'*)B$0!/+%>`RQ&M@>P5_``8&4N`&ASW%%`#0XU'D#D1#@`[$? +M\`;`$>B`YLH@8@3`**("'`GBV\HA@@.*(00"@!0`,""P!?"`%``P`!A$!!C8 +M7\#/<44`-#@"D1#@`K&`%`$P"[&`%`$P!.\`D8ZX`+&`%``PSW:``"`[`AB$ +M!0`3`""*)PD?['B`%`$P0"8`%@3A)W#2"^_Z!MH`$P`@$.:`%`$P['@*X0`F +M0!ZZ"^_Z!MH9#1$A*G"&(/P#C"`"A`3T$-A?P`GP@!0!,`/`$.&6"^_Z!MH> +MP@"2'\$X8`"R`,#/<00`7(V('``P`<``VHP<`#`%P$ASX@XO[\@4A#`="($/ +MK:O^RDPD`*#*(&(`XR`"!"P1(+[_H&V@X< +MA#\``(B.A,'I!_$&'@>,]P10"4-P"`20.O]`#9 +MX'CQP#X-;]N8<@AWSW-%`)0W*'4&\"APB@NO]"""`(,C@`WI7@N/]!#P`8$` +MV@3H0($'@1IB\.H`V!OP.@NO],"`""8`$$`G#AOA"*2#((,H<'(+K_3)<0WH +MP*"EL$`@`0LJH`88!`$`V2*P(AA"`#T%3]O@>,]P10"4-Q$#K_0`@/'`SW!% +M`)0WSW.``(!4((,`@`X+K_0@@0"#`(#1P.!^\<#/<(``@%0`@(#@3`]BY,H@ +MH@+1P.!^X<5@@("!H8%G?&""A'N!@(=]@8*D?(5[HH""@8=]@H*D?(5[@X`# +M@0=\`X*$>`4@_H`!V,!XX'_!Q>!XSW"``(!4`(#@?PJ`SW"``(!4`(#@?PJ` +MSW"``(!4((#/!X"'+/<(``@%0`@"J``Y`X8.!_6&`( +M=,]P@`"`5&"`"H-CDWA@"0'O^IA@X'CQP,]S10"4-S(*K_0`@X7H0(,!@H/H +M`-@$\`"")X(X8-'`X'[AQ>'&SW"``(!4`(#/`@B"01X2@A`(@C@`= +M#F(3.V:B>Z&$HGL;"Q(``X07"P,`6&,*\$*$0GM#A`L+@P`X8`+P`-C!QN!_ +MP<7@>/'`$PA1`%X/#_^"#R__`-@+\`38`-DH +M@1)O,""-#Z``M"[I<(`@P@&4Y\HG!A`"OS`G@!^@`!@LSW&@`(`,@"`$`*)X +M#W@_"#4",-I`&8`/`*`P``D(%`$`VP/P`=O:$@*VR7#F$@&V@@JO_:5Z*8;) +M<$(.+_XR$@(V@@S/\/T"3]M0H3X)#_J`X,H@(@$H"B+ZP'GB\>!XH<'QP&8* +M3]NBP2AU2<%:<$AV&G,*(0`A`-_/<(``6#+@H'$)7@("V<]PH`"`'#N@*<%3 +M;N[A4'@%]%8(+]Z+<1_P%0G1#1MX$'A&""_>BW'I)VXSQK8LP+PZ7`%O@5^4]@1 +MN,&@Y*#/<*``@"`2@`0E@!\````8*[@$)8T?``,``#B]!7W/<(``K,ZQH,]P +MH```102``-X$(+Z/`"@``$HA0"#/<*```"`.@,(A0B0#\(((S^_/<*```$6\ +M@`'?!"6$'X`````$)8`?(`````0E@A\`!@``!""!3V`"``#7<0`"``#`?\]S +MH```(`#9$PD0(,@3#``+#-40@.?*(6$`!1,,A@0EOI\`.```!"2/'P```(#, +M(2&`P"9A$`4@``$%?P4GOI`#](L.E)(/#-X3];W,(B&`A/+/`.H9R^5O)3 +M)7Z04O0RR`#9#R$!`,]P@``XVR"@2O`;"-X`SW&``"S.#X$!X`^A2@NO\`38 +M0MX\\`ATAB3]E]$@H8$U].VXJ`_"^C'P%0U>%<]Q@`"LSQN!`>`;H2GP'^KZ +MO%L]Q@`"LSQ2!`>`4H?X*K_`"V$+>"/`^@SG87(,""J_; +MC+@`WJEPO@TO_BIQ"O!6#\_ZSW&``*S/'($!X!RA`-[JR9B^;0@>`,]PQ>Z" +M-0'9#@NO_,HF(1`2\AR!`=C/=:````@&I>!XX'@`V2:E>@RO +M_`7>`]@'I9B^J^X1"M\A`]G/<*````@BH,]S@``(W4"#$FH)Q!1X`""!#X`` +MJ-R`H<]P@`!D'AV("!D`!(0H`0P`(8!_@`#D'(28`>(`X!P-`?X(W*L&+]NAP.^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>$P```$RY```` +M@$0``UN@L]T`P`!0I_114V5!?L.D%QJ67BMZ;;_:65*5+8.^U-,A=%@I:>!) +M1,C)CFJ)PG5X>8[T:SY8F=UQN2>V3^&^%ZV(\&:L(,FT.LY]&$K?8X(Q&N5@ +M,U&717]38N!W9+&$KFN['*"!_I0K"/E8:$AP&?U%CX=LWI2W^'M2(]-SJ^(" +M2W)7CQ_C*JM59@:?P\@?SH>)I3LWTVF75O@4&'V(TT8K^IL2=4RXTH%7SHC+AB@5UZ_:D +M.>R#"ZKO8$`&GW%>41!NO?F*(3X]!MV6K@4^W4:]YDVUC521!5W$<6_4!@3_ +M%5!@)/N8&9?IO=;,0T")=Y[99[U"Z+"(BXD'.%L9Y]ONR'E'"GRAZ0]"?,D> +MA/@`````@X:`"4CM*S*L3G):;/O_#OU6.(4/'M6N/2%(49\5=,!W6ON]V9[OU@?Z.? +M)@'WO/5R7,4[9D0T?OM;=BE#B]S&(\MH_.VV8_'DN,K<,=<0A6-"0"*7$R`1 +MQH1])$J%^#V[TA$R^:YMH2G'2R^>'?,PLMSL4H8-T./!=VP6LRN9N7"I^DB4 +M$2)DZ4?$C/RH&C_PH-@L?5;OD#,BQTY)A\'1.-G^HLJ,-@O4F,^!]:8HWGJE +M)HZWVJ2_K3_DG3HL#9)X4)O,7VIB1GY4PA.-]NBXV)!>]SDN]:_#@KZ`79]\ +MD]!IJ2W5;[,2)<\[F:S(IWT8$&YCG.A[NSO;"7@FS?0866X!MYKLJ)I/@V5N +ME>9^YO^J",^\(>;H%>_9F^>ZSC9O2M0)G^K6?+`IK[*D,3$C/RHPE*7&P&:B +M-3>\3G2FRH+\L-"0X!78IS-*F`3Q]]KL00Y0S7\O]I$7C=9-=DVP[T-43:K, +MWP26Y..UT9X;B&I,N!\LP7]1948$ZEZ=736,`7-TA_HN00O[6AUGLU+2VY(S +M5A#I$T?6;8QAUYIZ#*$WCA3X68D\$^ON)ZG.-LPP(G.2TV)#!5F1AA,M[<+8RU71<;$A"5[C0 +M4@EJU3`VI3B_0*.>@?/7^WSC.8*;+_^'-(Y#1,3>ZY0RIL(C/>Y,E0M" +M^L-.""ZA9BC9)+)V6Z));8O1)7+X]F2&:)@6U*1VYVEX5 +M1E>GC9V$D-BK`(R\TPKWY%@%N+-%!M`L'H_*/P\"P:^]`P$3BFLZD1%!3V?< +MZI?RS\[PM.9SEJQT(N>M-87B^3?H''7?;D?Q&G$=*<6);[=B#JH8OAO\5CY+ +MQM)Y()K;P/YXS5KT']VH,X@'QS&Q$A!9)X#L7V!1?ZD9M4H-+>5ZGY/)G.^@ +MX#M-KBKUL,CKNSR#4YEA%RL$?KIWUB;A:11C52$,?:5C8\:$?'SXF7=W[HU[ +M>_8-\O+_O6MKUK%O;]Y4Q<614#`P8`,!`0*I9V?.?2LK5AG^_N=BU]>UYJNK +M39IV=NQ%RLJ/G8*"'T#)R8F'?7WZ%?KZ[^M96;+)1T>."_#P^^RMK4%GU-2S +M_:*B7^JOKT6_G)PC]Z2D4Y9RW=1S]_>&NDY,]:B8F3%HV-FQ! +M/S]^`O?W]4_,S(-<-#1H]*6E433EY=$(\?'YDW%QXG/8V*M3,3%B/Q45*@P$ +M!`A2Q\>592,C1E[#PYTH&!@PH9:6-P\%!0JUFIHO"0<'#C82$B2;@(`;/>+B +MWR;KZ\UI)R=.S;*R?Y]U=>H;"0D2GH.#'70L+%@N&AHT+1L;-K)N;MSN6EJT +M^Z"@6_924J1-.SMV8=;6M\ZSLWU[*2E2/N/CW7$O+UZ7A(03]5-3IFC1T;D` +M````+.WMP6`@($`?_/SCR+&Q>>U;6[:^:FK41LO+C=F^OF=+.3ERWDI*E-1, +M3)CH6%BP2L_/A6O0T+LJ[^_%Y:JJ3Q;[^^W%0T.&UTU-FE4S,V:4A841ST5% +MBA#Y^>D&`@($@7]__O!04*!$/#QXNI^?)>.HJ$OS45&B_J.C7G58)^ +M?OQ'/3UZK&1DR.==7;HK&1DRE7-SYJ!@8,"8@8$9T4]/GG_WJ?B7EZ\'0L+%G;;VZT[X.#; +M5C(R9$XZ.G0>"@H4VTE)D@H&!@QL)"1(Y%Q7GR,N?GU4/(R(M9-S=NMVUMVHR-C0%DU=6QTDY.G."I +MJ4FT;&S8^E96K`?T]/,EZNK/KV5ERHYZ>O3IKJY'&`@($-6ZNF^(>'CP;R4E +M2G(N+EPD'!PX\::F5\>TM'-1QL:7(^CHRWS=W:&<='3H(1\?/MU+2Y;4E#.VFYLM(AX>/)*'AQ4@Z>G)2<[.A_]55:IX*"A0>M_? +MI8^,C`/XH:%9@(F)"1<-#1K:O[]E,>;FU\9"0H2X:&C0PT%!@K"9F2EW+2U: +M$0\/'LNPL'O\5%2HUKN[;3H6%BS_``$"`P0%!@<("0H+#`W_____________ +M______________\.____#____Q#___\1____$O___Q/___\4____%?___Q;_ +M__\7____&/___QG___\:____&____QS___\=____'O___Q____\@____(?__ +M_R+___\C____)/___R7___\F____)____RC___\I_____RK___\K____+/__ +M_RW___\N____+____S#___\Q____,@```0````$```````````````$````` +M```````````````!`````0`````````!```````````````````````````` +M``````````````$```````````````$```"`````_P```)`!```&```````` +M``````````````#_``#___^EQH3XF>Z-]@W_O=:QWE214&`#`JG.?589YV*U +MYDV:[$6/G1]`B8?Z%>_KLLF."_OL06>S_5_J1;\C]U.6Y%N;PG4G2@PH33\E6"_$=ZK,CGNBLRE>:@P)@9T9Y_HV9$ +M?E2K.X,+RHPIQ]-K/"AYI^*\'19VK3O;5F1.=!X4VY(*#&Q(Y+A=GVZ][T.F +MQ*@YI#$WTXOR,M5#BUENM]J,`62QTIS@2;38^JP'\R7/K\J.].E'&!#5;XCP +M;TIR7"0X\5?'G,[8M(CR2%2#)28?_JGA0 +M>J6/`_A9@`D7&MIE,=?&A+C0PX*P*7=:$1[+>_RHUFTZ+!$````````````` +M``````!D````$````/\`#"`(`@``$@```````````````````"P!```0```` +M_P`,(`(````3````````````````````+`$``!````#_``P@!P(``!0````` +M````0`8````````!````$`````$`#$`$`0``%0````````!`!@````````$` +M```0`````0`,0`,!```6`````````$`&`````````0```!`````!``Q``P`` +M`!<````````````````````!````$````/\`!``$````&`````````!`!@`` +M`````#(````R`````0+,0`,````9`````````````````````0````$````! +M`@"``0```!H````````````````````!`````0```/__`*`%````&P`````` +M```0``````````$````0`````0($``8!```<``````````0``````````0`` +M``$````!``P``0```!T`````````!``````````!`````0````$`#``!```` +M'@`````````$``````````$````!`````0``@`$#```?```````````````` +M`````0````@```#_``P@!@(``"`````````````````````!````"````/\` +M#"`"````(0````````````````````$````!````_P(,H`,#```B```````` +M`````````````0````$````!`@R``0,``",````````````````````!```` +M`0```/\``*`&`0``)`````````````````````$````!`````0)$``(!```E +M`````````````````````0```!````#_``P@`P$``"8`````````!``````` +M```!````9`````$`#``"````)P`````````L`0````````$````!`````0`, +M0`0!```H`````````"P!`````````0````$```#_``Q`!````"D````````` +M+`$````````!`````0````$`#$`$````*@`````````L`0````````$````! +M`````0`,0`,````K`````````"P!`````````0````$````!``Q`!0```"P` +M`````````@`````````!`````0````$`!``%````+0`````````$```````` +M``$````!`````0`,0`$````N`````````"P!`````````0```&D````!``Q` +M`P$``"\``````````````````````@``$@```/\`#&`"````,``````````R +M`````````&0````0````_P`,8`8````Q``````````````````````(``!`` +M```!``Q`!@```#(``````````````````````@``$`````$`#$`%````,P`` +M```````L`0````````$```!N`````0`,0`0````#````X&`!``$````\U@(` +M`````,R7`0`8````_',!`!$```"03@$`#````%QO`0`<````>%T!``0```!@ +M?P$`$P```)17`0`````!`````@````0````(````$````"````!`````@``` +M`!L````V```````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````#_`````/\``0$#``$%!``"`@,```/_``#^ +M!@$`_P$!``#_`0$!_P$"`O\!``0%`0$%_P$!`P<"`/\"`@``_P(!`?\"`@+_ +M`@(%_P("`P<``%@`L`,``!(`#`,`````&P`@``@$```9`"X!G"D``!H`]`#, +M*@``!@`(`2@$```<`"0`P"L```<`D@!L+0``#P`L`/`K```1``P`D"D````! +M"_\```0"```&_P```/\```S_```'_P``"/\```G_```*_P```O\!`/\``0(` +M#P$!`@$!`0/_`0$$`@$!!@,!`0<$`0$(!0$!"0T!`0H.`0`,_P$`_O\"`/\& +M`@$!_P("`@<"`@,(`@($"0("!@H"`@<+`@((#`(""0P"`@H+`@`,_P(`_A`` +M`0#_`0#_``$``?\!`@+_`@#_`0(``?\"`0/_`@,$_P(""O\"`@G_`@((_P,` +M`?\#`0,)`P4%"0,$!O\#!@H'`P,)_P0`_P,$``'_!`$#"@0"!PH$`@@*!`,$ +M_P0""@@$!`G_!`0&_P4`_P(%!`;_!0$#!04``?\%!0K_!04)!`8`__\&!`;_ +M!@$#!08``?\&`P3_!@8)!@8&"O\!D0```3\```*1```^/0```Y$``#T]```$ +MD0``/P,```61```)$```!I$``!8<```'D0``'Q\```B1```<%@``"9$``!`) +M```*D0```S\```N1```]/0``#)$``#T^```-D0``/P$``.<1'@(.>#1@@0$` +M```1238```@10$`5``D1;E\```\1(P```!41`CP<\ +MWFX'.ITN![D<#@YG$X'NMV.!SQ>KP<]W^\'P*!0",,A +MD0A%H_$(R*12"ET.@U*I5()2J42"<CP<\'H\'/!Z/!SQ>KP>]GL\'O]\/"$!@ +M,`C!8%`(0J$P",%@,`A`(/`'O]_/!SZ?SP<^G\\'OQ\P"$$AL0A'I%()2J52 +M"SP<^G^\'/R`P"$&A4`C#X7`(P^%P"$.A4`C!(!`( +MOY_/!SY?KP<^G\\'/V!0",/A<`BY7"X'N5P.![8:;08R62P&,!@,!C*;S@=! +M(I$(Q6+1"$;C\0C'X_$(Q^/Q"$>CT0C%8I$(Q.%P"$*A4`C!8#`(P6`P"$&A +M4`C"X7`(1&*Q"$6CT0C'X_$(Q^/Q",?CT0A&8[$(12*1"$&?S@8R&`P&L%A, +M!K(9K08V7"X'N5PN![5:K08UVDP&LE@L!C$:C@=`HM$(QR,2"C@:Q6"P&,MF,!K5:K09$1$1$1#PX-"0D1$1$ +M1$0\.#0D)```1$1$1$0\.#0D)$1$1$1$/#@T)"0``$1$1$1$/#@T)"1$1$1$ +M1#PX-"0D``"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"PL+"P +ML+```#@X.#@X-"XH```X.#@X.#0N*```.CI$1$1$1#PX-"0D1$1$1$0\.#0D +M)```-`R@`$`,H`!4#*``4`R@`$P,H``T#J``0`Z@`%0.H`!0#J``3`Z@`)@- +MH``<'*``0""@`"@DH`!L$*``&"2@`'@DH`!\)*``@"2@`(0DH`!0$*``2":@ +M`&`0H`!,)J``9!"@`&@0H`!8$*``,!"@`#P0H``T$*``+`R@``"!I``!@:0` +M`X&D`(@DH`",)*``D"2@`)0DH`"8)*``G"2@`*`DH`"D)*``6PD````"ZPL` +M```"D0>`````(0J`````D@D```$`(@P```$`E0<6$@``)0H6$@``T@D,```` +M8@P,````!@$```!`"``$````!P`A!```306T$^`/AP4R````1@7Z````1P68 +M.@``2`5DX),$405_@/H#B`7R-P``8@4%`2`8B@4"````C04`````C`5Q```` +M8P7;````004``@``4`5"@:(`0P6`A/`SNP<`E"AD2PH`E"AD+``"````0``" +M````)`CR.0``M`KR.0``A```4!(`G@``4!(``0$&!\@;`@$`)X`#L0>8&0S# +ML`>8&0S#00J8&0S#0`J8&0S#L@<)````0@H)````M@<`@"S+1@H`@"S+@0C_ +M>P$`$0O_>P$`N`<0$<_S2`H0$<_SM0<_````10H_````M`<0$:J@LP<0$:J@ +M1`H0$:J@0PH0$:J@O`>8&8JB3`J8&8JB@P<````5$PH````5A`?5__\D%`K5 +M__\DA0B````90JB```` +M#@`"0D0$$``"0D0$P@!29```PP!`P```Q``00@@`Q0`00@@`6P`@````9``@ +M````?0``````EP``````H0B0`@``,0N0`@``E`=0`%``)`I0`%``.8!`)`=`@"4X@$`D!T"`)`=`@`T^`$`D!T"`)`=`@#X'`(`".0! +M`)`=`@"0'0(`*.H!`)`=`@`P&0(`U/`!`)`=`@"0'0(`:.P!`)`=`@"0'0(` +MW!@"`)`=`@"D`@(`P-P!`)@3`@"0'0(`D!T"`$@#`@!8X0$`D!T"`)`=`@"( +M]P$`D!T"`)`=`@"0'0(`W!8"`)`=`@"0]`$`D!T"`)`=`@"0'0(`D!T"`"SH +M`0#(W0$`D!T"`)`=`@"0'0(`D!T"`)`=`@"0'0(`D!T"`)`=`@"0'0(`D!T" +M`)`=`@"0'0(`D!T"`)`=`@"(_`$`O"0"`)`=`@"0'0(`D!T"`)`=`@"0'0(` +MD!T"`$S4`0`4U`$`L.T!`)`=`@#H(`(`+/4!`)`=`@"0'0(`D!T"`,#4`0"L +M]0$`M`X"`"#6`0!`Y0$`?``"`#CX`0#``P(`D!T"`#@D`@"0'0(`1/@!`$#K +M`0"8]@$`D!T"`)`=`@!<#0(`U!\"`-P=`@!8(`(`/"`"``P?`@#\'0(`<"`" +M`)`=`@"0'0(`D!T"`)`=`@"8#`(`D!T"`(3D`0#\\P$`P!,"`'3F`0!4Z`$` +MF. +M`````P```/____\````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````_P`````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````&SF```*````!````!C: +M@``!9+8$S,S$`P````#W(0````)DN`3,S,8#`````.4A`````V2[!,S,R`,` +M````TR$````$9+T$S,S*`P````#!(0````5DP`3,S,P#`````*\A````!F3" +M!,S,S@,`````G2$````'9,4$S,S0`P````",(0````ADQP3,S-(#`````'HA +M````"63*!,S,U`,`````:2$````*9,P$S,S6`P````!7(0````MDSP3,S-@# +M`````$8A````#&31!,S,V@,`````-2$````-9-0$S,S<`P`````D(0````YD +MV@29F>$#`````/L@```````D=0\%```,!`````#1#P```"9U$04```X$```` +M`,D/````*'04!0``$`0`````P0\````J=18%```2!`````"Y#P```"QU&04` +M`!0$`````+(/````+G4;!0``%@0`````J@\````P=1X%```8!`````"B#P`` +M`#)U(`4``!H$`````)H/````-'4C!0``'`0`````DP\````V=24%```>!``` +M``"+#P```#AU*`4``"`$`````(0/````.G4J!0``(@0`````?`\````\=2T% +M```D!`````!U#P```#YU+P4``"8$`````&T/````0'4R!0``*`0`````9@\` +M``!"=30%```J!`````!?#P```$1U-P4``"P$`````%#@```&AU9`4``%`$`````-<.````:G5F!0``4@0`````T`X```!L +M=6D%``!4!`````#)#@```&YU:P4``%8$`````,,.````<'5N!0``6`0````` +MO`X```!R=7`%``!:!`````"U#@```'1U@4``&($`````)H.```` +M?'5]!0``9`0`````E`X```!^=7\%``!F!`````"-#@```(!U@@4``&@$```` +M`(8.````@G6$!0``:@0`````?PX```"$=8<%``!L!`````!Y#@```(9UB04` +M`&X$`````',.````B'6,!0``<`0`````;`X```"*=8X%``!R!`````!F#@`` +M`(QUD04``'0$`````%\.````CG63!0``=@0`````60X```"0=98%``!X!``` +M``!2#@```)5UG`4``'T$`````$(.````EW6>!0``?P0`````/`X```"9=:$% +M``"!!``````V#@```)MUHP4``(,$`````"\.````G76F!0``A00`````*0X` +M``"?=:@%``"'!``````C#@```*%UJP4``(D$`````!T.````HW6M!0``BP0` +M````%PX```"E=;`%``"-!``````0#@```*=UL@4``(\$``````H.````J76U +M!0``D00`````!`X```"K=;<%``"3!`````#^#0```*UUN@4``)4$`````/@- +M````KW6\!0``EP0`````\@T```"Q=;\%``"9!`````#L#0```+-UP04``)L$ +M`````.8-````M77$!0``G00`````WPT````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````].8```H````$````&-J``!C#1``````````````````8YP``"@````0` +M```8VH``````````````````&.<```H````$````&-J````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````D!T"`)`=`@"0'0(`8.D!`*#W +M`0"0'0(`Y.\!`)`=`@"0'0(`'!0"`+S=`0"0'0(`E.\!`)CV`0#D_@$``/\! +M`"#C`0!,&`(`N/\!`'P-`@"0'0(`D!T"`#PD`@"()`(`D!T"`)`=`@"0'0(` +MD!T"`$0B`@#@)`(`*"$"`)`=`@#`]P$`Q/[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=X3````)````,S,__\#6Z"SW0#``%"G]%%394%^PZ07&I9>)SK+:ZL[ +M\46='Q,```"\`@```%!```8```"A```````!``````"&@````P<6(*5Y``!` +M````0`````$````$A`4````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````U7?1O$KMC1P!%L)AM`1@'DT[FA#1OWMZR()D +MJ-L;GQEBIN9H[A^ZS%KH6MG.(:=CV\&$V<0:'I[5@L7;]O#+S6])Q;OTUZ`@Q9O#\ZQ +MZUROU1XL3>@GIX0A'ZLQS3.]EM]`#)-:.@LH#44.K^C\7[\`!P3DY4F9W;8[ +M]70ZRI8T>H?6RDCG3OM8]KY^9H/ +M)$3]O$5[=\V\'S +M]3*IT5]XV-2&AP*WU:;=,^V0JBXO@E62MAGPTBVIY+3BQ#1TG&@N]FD:+-N" +M6*^ZY^2N*=!&9\%&T$CZ3F/G")6\74FLR_^J]ZO:H"S4[JY"C*6X)@$Q\1Q@ +M_&X;,XE6JU3\M7B?*IN2V]H!8BD5%G4D6XT&[[ZMWN^^ +MK=[OOJW>[[ZMWB`@@`\(P`QV(""`#PC`2`\@((`/",!P#R`@@`\(P+B7(""` +M#PC`>((*)(`_B,#\?T$LG#!`+)PP0B0<-`HB@#^(P&@@"B,`-^(,@`-*)@!P +M:2!``.^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X$&A@W +M"B"`#PC```!K($`)(2#`!THF`'!I(``"2B8`<`42`#9"($"`!1H8,)```0`$ +M%``P:R"```@4`3!K(<``#!0",`HD@'`0%!\P%!0=,%04##!8%`LP7!0*,&`4 +M"3!D%`@P:!0',&P4!C!P%`4P=!0$,'@4`S!\%`(P@!0!,(@4`#"K($$`C!0` +M,*L@`0&0%``PJR!!`904`#"K(($!F!0`,&L@P`*<%``PJR#0!(04`#"`)`(X +M+R0_``$2`#9"(#Z``Q("-A0!(0!"(CZ``A($-@P`(@`"(#Z!G``"``@0'``, +M$`$`JR$("`04`#!K((``"!0!,&LAP``,%`(P"B2`!0#,'P4`C"`%`$PB!0` +M,*L@00",%``PJR`!`9`4`#"K($$!E!0`,*L@@0&8%``P:R#``IP4`#"K(-`$ +MA!0`,(`D`C@O)#\`"!`'`$HF0```'X`!&!_`!AP?@`8@'T`&)!\`!B@?P`4L +M'X`%,!]`!30?``4X'\`$/!^`!$`?0`1$'P`$2!_``TP?@`-0'T`##!("-D(B +M/H!*)P``#``!`!@8@``,&M@Q`1K8,6HBP`*&(@$`:R+``@HE@#\(P)0(+R0_ +M`&D@``)*)@!P!1(`-D(@0(`%&A@PE``!``04`#!K((``"!0!,&LAP``,%`(P +M"B2``)`(X:2"``0(2`#9"(#Z`^`?!_VD@``!*)@!P`1H8,`00 +M`P`8$`0`0"-#``08P``($!P`#!`!`*LA"`@,&A@Q`!0!,$(A/H!8``(`!!0? +M,`@4&S`,%!HP$!09,!04&#`8%!`)`$R"B6`/PC`2`E* +M(``":R#``B`@0(=*)@!P!!0`,&L@@``(%`$P:R'```P4`C`*)(!P$!0?,!04 +M'3"8%``P:R#``IP4`#"K(-`$&!0;,!P4&C`@%!DP)!08,"@4%S`L%!8P,!05 +M,#04%#`X%!,P/!02,$`4$3!$%!`P2!0/,$P4#C!0%`TP5!0,,%@4"S!<%`HP +M8!0),&04"#!H%`!0#,'P4`C"`%`$PB!0`,*L@00", +M%``PJR`!`9`4`#"K($$!E!0`,*L@@0&$%``P@"0"."\D/P`0$`,`A",_#X(C +M`@X`&X`/```!`$HE```$&T`!"!M``0P;0`$0&T`!"B9``!0;@`$8&T`!'!N` +M!B`;0`$D&T`!*!M``2P;0`$P&T`!-!M``3@;0`$\&T`!0!M``40;0`%(&T`! +M3!M``5`;0`%4&T`!6!M``5P;0`%@&T`!9!M``6@;0`%L&T`!__`1K8,&D@``!*)@!P"Q(`-@P2 +M`C9`($``0B(^@`L:&#`<`"$`2B$``$(B0H`,&I@P#``"`$HA0``(&E@P!A(` +M-@`0`@!"(CZ`$``!`$HA0``E`"``!QI8,`D2`C9`(``!`B"^@`8:&#`,``(` +M"A("-@8:F#!"(3Z`6``!```4`#`$%`$P"!0",!``3<.-TX\.!X!-PTW3;PX'@$W##=-/#@>`3<+-TR\.!X!-PHW3#PX'@$ +MW"3=+O#@>`3<(-TL\.!X!-P`3<%-TF\.!X!-P0W23P +MX'@$W`S=(O#@>`3<"-T?\.!X!-P$W1SPX'@$W!SP-!0:,#`4&3`L%!@P*!07 +M,"04%C`@%!4P'!04,!@4$S`4%!(P$!01,`P4$#`"QP'&L"1-,[`D'S/@?N!X +M_!R(L?P<2+'\'`BQX'T*$``% +M($0`1"3^@'0``@`*(P``02H\@>@@H@0$$00$!!$%!`01!@0$$0<$!!L0`00; +M4`$$&Y`!!!O0`40B_H/@(,$'%0K>``01!`0$$04$!!L0`00;4`$-"IX`!!$$ +M!`0;$`$-"EX``A$$!0(;%`$-"AX``1&$!`$;$@$@(,`'"B2`<$(A00!"($,` +MJ""``0$1A`(!&PH!("#`!X(D`C@`'``P!!Q`,`@<@#"*(`0`"B&`#Z#`'#@` +M&2``2B````HA@`^@P%0>`!D@``H@@`\#`$`-"B&`#Z#`X"``&2``(""`#PC` +M=`N")`(X`!P`,`0<0#!*(```"B&`#Z#`5!X`&2``$!S`-P`4`#`$%`$PK@Z/ +M_T(D'#2F#\`"0"0<-"`@@`\(P!@"@B0".!``-C +MC"/#C^+SSW!%@`SB=G@!@"RX6&!!:`'A[/$@((`/",#\#.!X`-I`L"+:0[`F +MVGH8A``JVL`8G``^V.!_$K'@>/'`(B"`#PC`@`S$D,]UB,#4$`-N1B#/``2- +MX[B")`@P"?+/<*C^\`L`V2(@@`\(P'!9C"8(D,H@C0\0``/'`(B"`#PC`<`R")`(T +M"'8`W8MP`]DZ<2(@@`\(P&2;0"8/%0S8!*:BIZ&G))8`PD*Y`L!CN5IP@N+* +M(D(C"_1,(@"A1/X!".##P`/```XNW)P"KL;8P3W#,(**`%O(!V`"G*/`"ND`G`!(B((`/",`@#@2&`L%DN`2F-7@$ +MIJ"G`L`!IQ?PSW.@P(`P"!,#".J[!/0"V`"G0?`"NH'@RB*"!"APA,$B((`/ +M",`@#J"G`-B`X#/TSW4``0``(#@S"$B@,H@(0`5 +M\B#@7XB%XLPBXH$$]`':1JE#B(#B`_($B`7P1XB`X@3R"(@'J0'8X'[QP"(@ +M@`\(P(0,2'9!BE!Q`-W7]V&(`B&,`%UCL7'*)<80RB4%$]IB`N(B:$APJ7(B +M((`/",`H?@&.N&`!KJEP(""`#PC`]`S/(`K$]ZX'\T&8(`X'CQP"(@@`\(P(`,"'?/=@``___/<$:`[#J@@`/P`>7/ +M<$6`(.5`(`$"`8`0=4WW6B4`&P;:.&#I<2(@@`\(P+QV@.#N]0+PR76I<"`@ +M@`\(P.P,X'C/<$:`[#H`@`AR#/!:(@$++&-:(`$+*6,P=,H@B0`!XL]Q18`@ +MY4`APP,A@3!R\/?@?N!X\<`B((`/","`#*O!"'<'B2AU!AP","(@@`\(P+B> +M"''/<$:`(`8B((`/","@I(#@/O("A2(@@`\(P`AT!QP",`*%@\8!@"#90L#) +M<"(@@`\(P$!^08^`XL?V(F_)<"(@@`\(P"A^BW"I<0;:(B"`#PC`*'Z+=:EP +M(B"`#PC`I%\B((`/",!H8X#@RB!"`^(@@@\(P+QE(B"`#PC`T&:`X,H@0@/B +M(((/",`<::O`(""`#PC`[`S@>/'`(B"`#PC`<`PO>%H@#0<*(X`O1H`4!`#; +MSW=&@)0%.G!B=6"E2 +M'T:`%`00$@$@>G"&X=(`+0!,&``%,R9!<(C`$!-`)X!R-'@`>,]P","@%$`E +M`1,*<@IS"B0`!`HE``4B((`/",!P@TWPSW`(P*`40"4!$XIR`=M*)```'_#/ +M<`C`H!1`)0$3"G**<_;QSW`(P*`40"4!$PIR[_'/<`C`H!1`)0$3BG('\,]P +M","@%$`E`1,*<@';F'-*)4``(B"`#PC`<(,?\`HF`"6*=Q?P0"(`)>EQ(B"` +M#PC`H*2`X`SRZ7`B((`/",#(I``EC"6,'`(00"96(`'GM.>J]T`=@A5`%8`0 +M!*U`)0`3B!P`,%03`"#@N$3R5215-"(@@`\(P"QT3!T"$"(@@`\(P"QT31T" +M$"(@@`\(P"QT3AT"$"(@@`\(P"QT3QT"$"(@@`\(P"QT4!T"$"(@@`\(P"QT +M41T"$,]P1H#4!4`@SP=`($,&2B2`<0#8J"``!`IC"6<`(0P@S!2,$$9YA'I% +M>0`E#"`@K`'@#WA,'``TSW"(P,PV*W')0<8#W$3$SW1&@-0%N(Q/(D0&`>6O?;BL$+U#Q@4E#!%%Q%HB#0=& +MQD?!,J=YN'UE(*5H<8`A1PDB((`/","LA,]PB,#,-@IQ(B"`#T6`F*N`X`3R +MP*72I]2GSW!&@!0&YA""@(PBPX\-\L]W1H"4!32'SW-&@!0$@.$%]#*'@.&S +M\ZK`(""`#PC`Y`SQP"(@@`\(P&`,@B0#,0AU"B=`H`H@@"]&@!0$0"`2)D`@ +M%25`(!$B0"`3(T`@%"1@]`.%@.",`"X`2B8`(%#<&B8`(T`E#A<>9@R.`-]: +M(`$'`8:"<0"A#(Y:(`$'`(9B<0"A#(Y:(`$'`H8B<0"A#(Y:(``'HG#@H`R. +M6B``!T)PX*`-CH#@UO<5)L`3$H@B((`/","XG@AQ#(X!VEH@``*^`X`7TP!0`,(#@"?3/<)]`#8NV,$HP*C`Z,%HP:C`>*0XJ?W"B&`+T:`E`5` +M$0`@@N`1](MQZ7`B((`/18#$KX#@RB""#Q``=A#B(((/",!P$(PFPY\?\EHF +M`!<=90&%@.`9]!@2@2"9OA"Y`=@!I<]PB,#,-L5Y(B"`#T6`G*J#X,H@@0\0 +M`'D0XB"!#PC``XP3T`]@_\"*`Y.$\]X#C<``N``#=GW/@ +M>*@@``U0W!HE`A-`(`$'66%-B9#B+/:`X@7T08&`XN;S@.4,\AHEC!\``%`` +M0B`""HQB3(E0=+0'R?^`Y0WR&B6,'P``4`!"(`(-A&)`@5!TG`?-_T&!AN*4 +M!\W_(H&"X8P'S?\!Y0#8P<7@?N!X\<`B((`/",!<#*+!"'4Z<1MR^G,*)``A +M"B5`(0HC@"$`WHMP6G#/<8C`1!4#VB(@@`\(P"`.0<9,(`"PS"0BH,PC(J#, +M(2*@._)(&X`C!?!(&T`@`G8R=O@`!@``)983`!:/((PGPY\!%H`@-@`I`$`@ +MD```)@`4,G`5]TP@`*`1\@MPZ7$B((`/","$(H#@XO.,)T.7%_+T),`C8G"Y +M9E+PSW"(P-00$(CAN`GRSW"H_D@0`-DB((`/",!P60#82?!,)P"@S"4BH,;S +M(FZY84IP`]HB((`/",`H?@46CR!*<,]QB,#T$P/:(B"`#PC`('Z`X`[RK>?, +M)V*?"O3T),`C)6YB<+EA!A:"(`'B'?"!PDIPZ7$B((`/",!H'P'!E.&:\R]Y +MZG`B((`/","$(H#@DO,!P)/@N6:,\P]X]"4`(&)P"G(B((`/",`H?H3Q`=BB +MP"`@@`\(P*0,\<`B((`/",!\#!IP*'=(=138`*(*<,]QB,#T$P/>R7(B((`/ +M",`@?H#@`-A_\@IPSW&(P,0?R7(B((`/",`@?H#@%O1AOX3GY``-`#,FSW.( +MP,`30"<`H``T`,R;/`781_`&V$7P$MA#\!/80?`* +M<,]QB,#P$\ER(B"`#PC`('Z`X!_TE.=L``T`,R;/`?8 +M*?`(V"?P"=@E\`K8(_`+V`"E#-@?\`W8'?`.V!OP#]@9\`IPSW&(P+@?R7(B +M((`/",`@?H#@$-@-\@IPSW&(P+P?R7(B((`/",`@?H#@!/01V`"E(""`#PC` +MY`PC@(#A`-O2]P#:`_`!XAHCC`\``%``0"!!"HEA,'*X]R.``>,P<[+WX'[@ +M>/'`(B"`#PC`N&J`V<]PH,``.!`88`#1P.!^X'CQP&:`@.,(\A&*@.`+\@J2`^!&(,``UW`````@P_<'VV:B!X(#X$8@P`",(!"`R_<( +MVPCP@N,']`""@.`#\@;;9J*"X\KW(X+/&%P=`#IP'8(""`#PC`U`P`V<]P18`$]""@(:`BH.!_(Z#@>.'% +MX<;/<46`!/0`@4`A`P3P(PT`SW2H_D0+4R6`$R*X06C/<*#````0&"`#$!A@ +M`\]TH,``$+`<>),`@0/P@1RXDZ"!`>!=96&]4R!.`K%P\"..`[7W`>#)N((< +MN),`H0*!0G@"H0.!8;@#H<'&P<7@?N!XSW!&@"P&"9#@?N!XX'\`V'UI56OP +M(,``0GD`V@\B0@!$>!!R`=C@?\!XX'C/"`@@`\(P/P,`-C/<46`J,>*(A0` +M(""`#PC`!%?QP.'%SW5%@*C;(86`X/'`(B"`#PC`@`P*)@"0SW5%@*C;$O+)=\]Q +MH,``#F@1`0@`V"(@@`\(P&18`(5AOP3@@.<`I3+W`87">`&E(""`#PC`[`S@ +M>/'`(B"`#PC`>`PZ<`H@0*#/=T6`J-L`W1#R"G;P(4$C`-@B((`/",!D6`"' +M`>4$X&&^@.8`IS3W`8<"(``$`:<@((`/",#<#/'`(B"`#PC`A`S/=46`J-LA +MA0AV@.'*(((/$``$#^(@@@\(P'P0`-C)<2(@@`\(P,18P:4`I2`@@`\(P/0, +MX'A`*`(%SW&@P``X6!F@`,]QH,"`'C`9(``@((`/",!`),]QH,"`'C01`0@+ +M>0'8X'_"(`$`SW`0``\/(""`#PC`/'`X<$@P8PAPX\-\NMRSW`0`"0# +M(B"`#PC`B!"AP-'`X'[/<8C`Q#4,B8#@Q/9AN`RI]O'T\>!X\<#AQ<]UH,`` +M.%@5`!CAN`CR(B"`#PC`^)("V%@=(!`@((`/",#\#`AR('HH<.!X(""`#PC` +M&$O/%O\D`` +M"0#1X4WR"O:!X7/RG.'B(($/",#@EX?PTN%-\N/A;O+DX8'T@<`B((`/",#\ +M('A"/3/<8C`Q#4. +MB0'@#JG@?N!X(""`#PC`J";@?N!X\<`(`HB0(#QP$7R4R!^@`GT4R)^@`?T +M(KJ(XDGW`-D*\`#9(B"`#PC`!'60<*]]$/*"Y0WV!&N!P2(@@`\(P#23`<#7<```_W^E +M]\EPT7#*(R$`:'"BP"`@@`\(P.P,X'CQP"(@@`\(P(`,"'8`W^"@;R!#`2AU +M(B"`#PC`R"<*(P"`$O)`(P`"J7$B((`/",`TDP1KR7$B((`/",`TDT`C``,$ +M\."EZ7`@((`/",#L#/'``-CAP&\@PP`B((`/",#()X#@RB$"!\`@(@+B(((/ +M",`TDP#`H<#1P.!^\<`B((`/","$#`AU*'8*V`#9J7("VR(@@`\(P("18XT* +MV&&[`MG)1'P```%`)\`K8(B"`#PC`N)+ON`AU!_1L%@$8#"%`H.H' +MS_]L%@`8SW&(P`01XG@`H0K8`-F/N2(@@`\(P)R2!"4`%"`@@`\(P-P,X'CQ +MP"(@@`\(P(`,"'8H=\]PB,#L$0"`2'40/'`(B"`#PC`>`S/=HC`\!$'AH'@"_0*AHP@!(!']R(@@`\(P-QL@.`/]"(@ +M@`\(P-QL)X8(`` +MH0J&(B"`#PC`5(`-IB(@@`\(P)B`"'4*AB(@@`\(P(R`4R5/$HPG!)!']\]P +M1H!H)>I@`O#^VHPB@X^(``8`SW"(P.@1`(!`*@$#[;TX8!IP#*9`+P`32Z8` +M()$/``$``,!ZRB$"!,HC8@#/(B(#RB!"!.(@@@\(P(!,_]D`)X`?1H!H)2"H +M*G`B((`/",#`3NZ]-_("A@'@`J;I<"(@@`\(P%2`#J;I<"(@@`\(P$"`"G`N +MA@#:(B"`#PC`#$\"V"_PSW>(P`P1SW"(P.P1`(`@CQ!QRB%&`\H@A@\0`#<" +MXB"&#PC`B!``C\]QB,#H$2"!0"@"`PNF66$LI@'@`*\,ABJ&(B"`#PC`I'\, +MA@#:+88B((`/",!03038(B"`#PC`_"L@((`/",#<#.!X\!_!Z'@ +M>,]PH,``(&P0`0C/%@.#R\R`@@`\(P/P,X'CQP.'%SW6(P/`1!X6"X,H@@@\0`#T" +MXB""#PC`,]QHL``2P01``@`$0((4B````01 +M`0C@?\"XX'CQP"(@@`\(P(`,SW&@P``.3!$."`#8$!D@`&@1``C/=Z#``!`$ +M((T/`!@``#R]:!$!"*ER(B"`#PC`@'"`X,H@8@`=N(#EQW``(```G[@%?F0? +MN),'\A'(@.`%]`'881\XD,]PH,``.!@8H`\`(```(B"`#PC`Y(J`X,H@@@\0 +M`",!XB""#PC`/'`(B"`#PC`>`P*)0"0*'=(=AISBB'#+Q?T*16`$!!WD_8J%8`0 +M$':/]C)V_MS,)@*3RB&"`\H@@@\0`.H.XB""#PC`?!`R=A#T`X6`X,H@@0\0 +M`.L.XB"!#PC`/'`(B"` +M#PC`1`TB((`/",!T#$?`2,'/=ZW>[[YI(```SW6@P``@#!V@'R````0`V"(@ +M@`\(P`21","`X,HBP2,%\H'@)!02,`3W&G/'`(B"`#PC`A`RCP<]VB,"%$\]UB,#<$<]PB,`,-LEQ`]I@A8HD`0A* +M)0`.(B"`#PC`B$4@A8#@8.$@I'3/=8C` +MX!$`%000`-M`PP'80<"XV$+`0"9!%`/>"K[/<(C`P#>X=DHF@``*)X`!(B"` +M#PC`X$8@A8#@V6$@I"K[/<(C`>#BX=MAS^',B((`/",#@1B"%@.#9 +M82"ERB""#Q``$@'B(((/",!P$*/`(""`#PC`]`SQP"(@@`\(P!"6(B"`#PC` +M.&HB((`/",!TDR(@@`\(P*!LT<#@?N!X\<`B((`/",``,"(@@`\(P!PQ(B"` +M#PC`<##/<(C`Y!$@@,]PB,"T-1!Q"_?/<(C`W!$@@,]PB,"T)1!QR/?/`Y*/`(""`#PC`[`SQP*LF"'`````!(B"`#PC`($XB((`/",!42DHD@'$`V:@@ +MP`-:(8`!QW!%@(RR0I!AD!"Z`)!%>RLC```!X<]PB,"($B"`SW"@P``@;!`` +M"#)Y.&`!X$$H`(/B(((/",#\F2(@@`\(P(B7T<#@?N!X\<#/<:#``"!L$0(( +MSW&(P(@2@.!`H0WR6&#/<:#``!Y8&2``5!$`"(&X5!D@`$HD@'$`VJ@@@`-: +M(H$!QW%%@(RR`)$!XBHC``!AL3"[8K$B((`/",`(3B(@@`\(P"Q,T<#@?O'` +M(B"`#PC`<'TB((`/",`HEB(@@`\(P#!:(B"`#PC`;%G/<8C``&``V`_:,-LB +M((`/",!H2B(@@`\(P%2#(B"`#PC`7$XB((`/",#L3='`X'[@>,]PH,``'D`8 +MH`\`(```X'X@((`/",`TE_'`(B"`#PC`;`RJ)Q`1"B*`+XC`?"``$@`H@N#* +M(<8#RB"&#Q``1`+B((8/",!\$,]VB,#P$0>&@^!`\L]U``$``(7@%?*,X$OR +MJB$0)@(G0!-!*!,#C",$H.@`)@"*)(,OSW%&@&@E,B'-!&OP2H8KA@`B@`]& +M@&@E(*@B((`/",`T@`J&+(8,N$^&N&`B((`/",!P3E4F01@(AB(@@`\(P)29 +M`-@B((`/",#\*R(@@`\(P`@LB/`,ABJ&(B"`#PC`I'\,A@#:+88B((`/",!0 +M3038(B"`#PC`_"MT\"(@@`\(P$`L"88"($$#++F,(02`*J9&]\]R1H!H)2IB +M`_#^VHPB@X]4]R^&(B"`#PC`D"E5)D$8"(8B((`/","4F0#8(B"`#PC`_"M. +M\`'8(B"`#PC`_"LB((`/",#L*43P_MV2=1'TJB`0("(@@`\(P-Q-Z7$(<\]P +M$``R`@IR(B"`#PC`F!"2=4[WZ7`J<:ER(B"`#PC`D"D'AB(@@`\(P/PK(O`` +M$@`H@N!,]P$2#396)@$4J7`B((`/",#(F0/P`-T'AH#@"?3IIJBF/!Y`%"@> +MP!2\\>EP*G&I@(#B(?(`VWV@*X)"(4&`*Z(*\H`0`0!_@(`;0`!_H2J",'`#]&JB +M+X"%X0WT)(*`X0O9RB&A`I`80``B((`/",#@/='`X'[@>/'`(B"`#PC`>`P( +M=1IQ2'=H=@HA`"$XV2(@@`\(P#0G!!T`%.*E,F\J<"(@@`\(P'P-'2#"`\FE +MQJ45)H$0R*4GI06E`Z5J((`"!""!#____?\I($``2B8`<,]RB,`D```=@!]5 +M455%(((!X2"B@>'/$$$`($!!Z0$,SW0B%!@,HD +M0G#@>.@@H@$$$`$$!!Y0$">%,'`"]`:%"*4%A0'@!:4$A6&X!*4I((`$2B8` +M<`#8O_#JA8#G+O)6)P,4`X.!X"CT(H4"@X'A!!`"!`0>D!#,]T(A08#*)$)P +MX'CH(*(!!!`!!`0>4!!"(4"@9/(_ARJE0(.`&8``/Z(+I0#8':>0'P`0Z7`B +M((`/",#@/`#&A@P*2"`!$HF`'!J((`"!""! +M#____?\I($``2B8`<%IP`\B(%P$08;@#&A@P0H6!X@F%!!$#!`08T`#-]T(B +M0H#*)()PX'CH(.(!!!$"!`08D``GA3!P`_0&A0FE0B%`H.J%!?0`V2JEH?%? +MATJE@!1`(0,AS/=")$R0 +MRB0"<^!XZ""B`003#`0$&1`#Q*(B((`/",#@/0!0`V8#D(Z8%]`JE'Z``I@GP*H4_H(`1`@!`IA^B@!D```'D +MBZ4%V2^@"G$B((`/","(/BD@@`1*)@!P!(8'\"D@@`1*)@!P"]@@((`/",#4 +M#.!X\<`B((`/",!L#`AU&G$Z9L2E5B4.%.ZE"<#HI@:E!Z4@V))W"J8& +M\@#8$J4)I@3P\J7II@/8#Z7/<`C`3$`8I;FESW$(P`P]J7`B((`/",`0"FH@ +M@`($(($/___]_RD@0`!*)@!PSW&(P#0`&G``'8`?2%1$4@"!`>``H8'@SW&( +MP#@`!?2@H:6FIJ8*\`"!F!`!`)@80`.4&4`#)J8%I@K!`-B!X0JE"Z4,I/'`(B"`#PC`?`P(=6H@@`($(($/___]_RD@0`!*)@!P&G`/A8/@ +M&/2I<"(@@`\(P.`]*2``!$HF`'!J((`"!""!#____?\I($``2B8`/'`(B"`#PC` +M?`P!$@TV-(5@>16%SW"(P$``(("`X>,@0@#*($(#:B"``@0@@0____W_*2!` +M`$HF`'`:<`'8+(4/I8#AXR!"`,H@0@.I<`#9(B"`#PC`B#XI(``$2B8`<"`@ +M@`\(P.0,\<`B((`/",!\#`AU:B"``@0@@0____W_*2!``$HF`'`:<`^%@.`0 +M]`/8#Z6I<`#9(B"`#PC`B#XI(``$2B8`<`#=$?""X,P@8H#*)2$5!_*#X`3R +M`=@0I0#=*2``!$HF`'"I<"`@@`\(P.0,\<#AQ0AU'("`X`CR5B7`$B(@@`\( +MP#!%#X6`X#3R,(6`X0#8+?0/I2Z%SW"(P+0@-7A`@(#B'_2@H,]RB,!$``"" +MJ*4/($```*+/%#!H8,"B%SW2(P+0@,'5.A0F%%22#$`GR":$HH`"# +M$'5=]""C6_``V2"CSW.(P$0``(,0(("``*,2]"#:SW"(P#P`0*`"&E@P!<@# +M$@$V!2!^@.(@@0\(P.`*3_`3>D1XD.!(]X3@P2BF`,HAI@`Q\(P@!(!*]T$H +M`@&$XD@`)0`$V2:X!MDE\-=P`0```$OW02@"`I#B"-F4]T$H`@,,V1#P02@" +M!#BXC"($@!C9RB(&`,HA)020XL$J)@'`(28!A.)$]TAP!?!!*H```N$=>#A@ +MSW&(P#P``*$"R!!U"_3/<(C`/```@/`D`!`"&A@PK/$0=JKU(""`#PC`]`S@ +M>/'``\@%$@$V!2!^@`GT`A(!-@'(,'#B(((/",#@"M'`X'[@>/'`X<4!$@TV +M:B"``@0@@0____W_*2!``$HF`'``V8#E"!I8,!WR+X6`X1OT)X5HA2:E<'4, +M&E@P$_)2A2Z%4'$/],]RB,"T(!4B00!@H<]QB,`\`""!\")!``(:6#`I(``` +M2B8`<"`@@`\(P/P,X'CQP"(@@`\(P'P,"'5J((`"!""!#____?\I($``2B8` +M,@0@#*($(#*2``!$HF`'`@((`/ +M",#D#/'`*("`X07T(H"`X0/T%]@'\`C@(B"`#PC`M$0`V-'`X'[@>/'`(B"` +M#PC`@`P(=2AV2'=J((`"!""!#____?\I($``2B8`<)AP"(6`X`3TPJ7CI2D@ +M``%*)@!P`-@@((`/",#L#.!X\<`B((`/",!P#`AU*'9(=QIS"B(`(0HA0"$* +M(X`A+-DB((`/",`T)\&E"!V`%`P=0!3DI10=`!1J((`"!""!#____?\I($`` +M2B8`<,]RB,!(```=@!]404U)(((!X2"B@>'/`(\`(DPA#">4*Y0KH!X5AA +M((6@X<3W0B$!"#A@`*6`Y!3R)(4P=0CT((0P=0#8#/0`I`KP!84%H22@`(00 +M=03TAJ$@I`#8!J4I(``!2B8`<`#8(""`#PC`]`S@>/'`(B"`#PC`@`RBP0#? +M0<=J((`"!""!#____?\I($``2B8`<)APSW&(P%```(&`X`3T!\B`X`OT*2`` +M`4HF`'"BP"`@@`\(P.P,`=@`H082`C8`@H#@0,`#\HMQ)J``V2"B!L@)$@(V +M!.!0<`8:&#`$]`K(!AH8,`<:6#`I(``!2B8`<`SP`-@&I2D@``%*)@!PJ7`B +M((`/","T1&H@@`($(($/___]_RD@0`!*)@!PF'`Z\"2%L7$$]`#80,`(\`6% +M0,$%H22@BW`&H0"%H.#&]T(@``@`I0#>"/#"A0&%XX6`X`"E!O*!P`:EI*4$ +M\`#8!J4I(``!2B8`<(#FXR""`\H@P@-J((`"!""!#____?\I($``2B8`<)AP +M)H6!P#!PL_,`Q8#EQO4'R(#@D?4`V<]PB,!0`""@@/'QP"(@@`\(P'0,&G`H +M=DAW:'4*(@`A"B%`(6H@@`($(($/___]_RD@0`!*)@!P@.:8<`7R!!``(`"F +M@.=`(`,B`_(`V`"G@.4#\@"#`*4*$@PV)H.1<4P`!0`)$@(V4'%```8`!A(. +M-M%QPB&&`\(II@#`(68`2/>"><)Z0KI"N0'B66%`@T(B#`B@XCQDRB$-`X#G +M`_(!V`"G@.4"\B"E3"(`H`3R(8,`&D`@3"$`H`7R)!`!(``90"`I(``!2B8` +M<`#8(""`#PC`U`SQP"(@@`\(P(0,`-T+&E@S#!I8,P@:6#,'&E@SSW:(P#0A +MR7"`V2(@@`\(P#0GR7`*&A@P!AH8,%8F`!0)&A@PSW"(P%``H*#/<(C`3`"@ +MH,]PB,!(`*"@(""`#PC`]`SQP.'%"'5J((`"!""!#____?\I($``2B8`<""% +MF'"`XT'PB%N +M``;(-7@)$@$V,'"%]R)X.F@*R#5X(("`X0;TI*6EI:"@!_!%@:2BI:$DI46E +M!J79\>!X\<#AQ0AU:B"``@0@@0____W_*2!``$HF`'!&A8#B%?)DA7!U!_1@ +M@G!U`-D+]""B"?`EA26C9*$@@C!U`_1&HV"B`-DFI2D@``!*)@!P(""`#PC` +M_`S@>/'`(B"`#PC`=`P*)@"06G%(=QIS"B$`(:AP!/*XX`3R"=A?\&H@@`($ +M(($/___]_RD@0`!*)@!P`Q(!-@'A`QI8,"D@``!*)@!PSW"(P"@`H(``V`/P +MK(4!X,]QB,`D`""!,'!#][%V]_5J((`"!""!#____?\I($``2B8`<`,2`39A +MN0,:6#`I(```2B8`<"(@@`\(P+@_L7;$\TP@`*#*(.$`'?*`YP/RD.?#]P78 +M%_!!*8`@$'<[]P7(@.`'\M=P\/#P\!/8B_?)<$IQZ7(*`HC`(`&\@"#UW!5455%!/()V.!^@.'A +M(,$'RB#A`(#B!O(%R(#@X2#"!P38:'`@((`/",#@.>!X\<`B((`/",!H#*+! +M"B8`D+IQ2'>:$@P0<6V`7( +MUW#P\/#PX2#&!Q/8:'`@((`/",#`0/'`(B"`#PC`:`P*)@"0NG&:$#&E@P*2```$HF`'#/<(C`3`"@@`#8`_"IA0'@SW&(P$@`(($P<$/WL7;W +M]6H@@`($(($/___]_RD@0`!*)@!P`Q(!-F&Y`QI8,"D@``!*)@!P(B"`#PC` +MN#^Q=L3S3"$`H,H@H04=\DP@0*#,("*@%]@7]`7(@.`'\M=P\/#P\!/8C_?) +M<*IQBG)J(#@\<`&\B"` +MUW%404U)!/(5V`;P(B"`#PC`J$'1P.!^\<"`X/AR!_)`@-=R5$%-20/R%=@& +M\.AR(B"`#PC`B$/1P.!^G6F`XG5LE7AB>0#;#R-#`""`Q2'"`,8AP0#@?R"@ +MX'CQP"(@@`\(P(0,"'2AB&AV`(,"Y;M@<''*("4!C/=88(EQJ7(B((`/",`H +M?@"&N&``I@#8(""`#PC`]`S/<:+``&QX$0`(@;AX&2``X'[@>/'`(B"`#PC` +M@`P4>)AQ"'>`)P@8"':`)D@8"'6`)8@8@./*(X$/```@`<\C8@#/(R("JB"! +M#8#@"_(B((`/",!42BLDP`,K(H`#*R-``R`@@`\(P.P,X'C//'`!)!"N"(@@`\(P$B<`-@(<2(@@`\(P!A+T<#@?N!X\<`B((`/","$#`AU +MSW"(P-00#(CCN"AV"O+/<*C^```!V:ER(B"`#PC`<%G/<(C`5`#P($$#8'G) +M<"`@@`\(P/0,X'CQP.'%H<&+<0#8(B"`#PC`@%<`P0AU@N'*(((/$``*#^(@ +M@@\(P'P0H8T`V"(@@`\(P"!78;V(Y0WW]29-"(@@`\( +MP%!WH<`@((`/",#\#/'`X<4\V,]UH,``#A`=(!#/<8C`O!(`@0`=(!`!@0`= +M(!!$V!`=(!`"@=VX`!T@$$C8$!T@$`.!W;@`'2`0(B"`#PC`!",4V!`=(!`" +MV"(@@`\(P.`C`M@B((`/",!0(R(@@`\(P!@C`=@@((`/",#\#.!XJB"!#(#@ +M"O*K)L%R```!`*H@`0+HN/[UX'[@>/'`(B"`#PC`8$RJ(`$"Z+C]]='`X'[@ +M>*HB@0R`X@SR&6$@X48AP0>K(8$#1B#`!ZL@00/@?N!XJB0!$H'CSR2A$=`D +MHA&K)`$2JR$!!QIB1B#!!P+P(.$P)/#/<4:`:"4(88P@ +M@X\P``4``!<`&&H@@`($(($/___]_RD@0`!*)@!P&G#I<"(@@`\(P,!.*2`` +M!$HF`'``V(RX'V<>9L]P18`,XK9X`8`0=DWWSW$``0```B=`$"RXC"`$@*`' +MQ?_^V-#Q`=@@((`/",#D#/'`(B"`#PC`@`P(=2AW2'8`V8RY`-HB((`/",#< +M@:EPZ7$`VHRZ(B"`#PC`6%J`YL!XSR!B!^(@@@\(P*A:(""`#PC`[`S@>/'` +M(B"`#PC`A`P(=@#=`_`!Y83E4O<4;L]Q18`"(@@`\(P-!_(B"`#PC`W'\B((`/",!\@2(@ +M@`\(P.Q-T<#@?N!^X'C/<$:`:"7^V4)I(""`#PC`!'?@>('B;-K*(J(-!""` +M#_]_`/"%(`P`!"&!#___`/"`N45YJR!0`:LAD`&K)A!R```$`*H@T`'_N`SR +MJR80<@```P"J(-`!JR80<@```0#@?N!X"'$$((`/_W\`\*L@4`&K)A!R```$ +M`*H@T`'_N`KRX+@5\L]P$``T`B`@@`\(P'P0JR90<0````"K)I!Q`````*LF +M$'(```$`X'[@?O'`X<5(=0#:C+I;8B(@@`\(P/!:@.7`>,\@H@?B(((/","H +M6B`@@`\(P/P,JB$0`*HBT`#//'`X<6BP8MU +MJ7`"V2(@@`\(P&2;SW"(P,PVJ7$B((`/18"XH*+`(""`#PC`_`S@>/'`X<7/ +M=46`@+NI<(?9(B"`#PC`9)O/<(C`S#:I<2(@@`]%@#RC(""`#PC`_`S@>"`@ +M@`\(P&@2\<#AQ:/!`-@B((`/","838MUJ7`#V2(@@`\(P&2;T]@,V:ER(B"` +M#PC`*'.CP"`@@`\(P/P,X'@$D`/@1B#!`"*YSW"(P-00(""`#PC`9)OQP"(@ +M@`\(P%@,@B0$,L]U1H``?0`5`!C/<4"````E>,]QB,#H$0"A!!4`&,]V1(`` +M`"RXSW&(P.P1`*'/<0`!``#/<*#````0&&``"B6`+T6`V+*J<"39(B"`#PC` +M9)O/<0`!``#/<``!```0<"(@@`\(P-!_Z7`B((`/",#$?R(@@`\(P,!_(B"`#PC`W'\* +M)X`OH,``.!0?H"\`8```#!4`((#@5O(BA9'AS"'BC,`E(1,1\J+A_]S,(0*# +M!?16)@T4"?#/'_)<`IQZ7(B((`/",!86LEPR7'I<@#;(B"`#PC`@$P`V)VX(B"`#PC`J%JI +M<,EQ"G+I$`(L`D$'&W +M]P@5`"`!Y1!U&`?%_PP5`""`X!'R@L``V2(@@`\(P$R/@.#*(($/$`!``N(@ +M@0\(P'`0R7``V8ZY`=HB((`/",#<@2(@@`\(P+B`%!^@+P!@```$%P`HG;B> +MN`0?("`B((`/",`\$2(@@`\(P)QV@"0$,B`@@`\(P)P,X'CQP"(@@`\(P'P, +MQ)`(=Z-N1B7-$"*]H<'7=0````C*((T/$``I`>(@C0\(P'`0C"4$D$`G`!69 +M]__9&G$B((`/",!DFQ)US?<")0T4BW`!V2(@@`\(P&2;8;V`Y3CWBB`/#P2G +M!_"I<2(@@`\(P&2;Q*?/=8C`U!`$C>"X"?+/<*C^N`L`V2(@@`\(P'!9!(W@ +MN`ORSW"H_L@+`=G).!^ +MX'CQP"(@@`\(P'0,"'?/<4:`W#@:<:1I0"`.!0@0$@%`(!$&C"((H\H@C0\0 +M```&XB"-#PC`.!^X'C@?N!X\<#A +MQ220SW"(P-@50(`!@/@%H@`P4H<,=S18`(PB2C0*-(<2`@ +M@`\(P#0GX'CQP"(@@`\(P(0,6B``!0`@C@]%@`C"!(8CAA4@00"@D6H@@`($ +M(($/___]_RD@0`!*)@!P(88"Y6&Y(:8CAD*&N6%0<2.F!?0`V2.F(J8I(``` +M2B8`<"`@@`\(P/0,X'CQP"(@@`\(P(0,6B``!2AV`""-#T6`",(!A8#@RB"! +M#Q``!0_B(($/",!P$$2%`X7P(@$`UW'Q\?'Q!/0`V`.E\"(```0@@`___P`` +MUW`()P``RB""#Q``!@_B(((/",!P$`2%(X45($$``)$`IB.%!(4"N03A.&`@ +M((`/",#T#%H@``7QP.'%`""-#T6`",)J((`"!""!#____?\I($``2B8`<,]Q +MH,``(&P1`P@DA4*%57E@H22%0H4$X55Y`!F`#^7EY>4AA0'A(:4BA0'A(J4I +M(```2B8`<"`@@`\(P/P,X'CQP"(@@`\(P'P,6B``!2AV`""-#T6`",)J((`" +M!""!#____?\I($``2B8`<$"%(H4:<%!QRB"&#Q```P_B((8/","($"2%`H45 +M><"A`>`"I2D@``1*)@!P(""`#PC`Y`SQP"(@@`\(P'P,6B``!2AV`""-#T6` +M",+CA6H@@`($(($/___]_RD@0`!*)@!P(H4:<#!WRB+-`P+W0(7880+@$'+, +M)TZ0RB>-$`KW!(4U>`#9`!B`#_'Q\?$BI=AA`N`0=\HCC@/*(LX#RB".#Q`` +M`@_B((X/","8$"2%`H70?A5Y!2:.'P@G``#`H0'@`J6DA15]*2``!$HF`'"I +M<"`@@`\(P.0,X'C@?N!X\<`B((`/",!$#2(@@`\(P(0,J,$(=4S!(B"`#PC` +MW&R`X$GR#,)3)<$40"H`!HW&)7A`P`#9@.+*)(UPRB--`.@@;0($YA4DP##\ +M%@R0`>.!H,]TH,``(&P4`Q@5)(`P8:`"X@4B@@_`[H`PSW.@P(`/'`#-G/<*#```X0&&`` +M:!`!"(#AP'CB(((/","\I='`X'[@>.'%X<8`W<]SH,``?D`;8`-`*0X#SW2@ +MP`!X5!RX$T`I!`($)($/`/```$5Y51QX$',<.!!(&Z`/$``#$,0<>!-`&Z`/ +M0(```,'&P<7@?N!X\<`B((`/","$#`AUSW:@P``X%!8`&*MX_?-@V&39(B"` +M#PC`O*44%@`8JWC*(($/$``B`N(@@0\(P'`0%!Y@$R`@@`\(P/0,X<7AQ@#> +MSW6@P`!\(!V@$PC<,!T@$\]TH,"`>V@/'`(B"`#PC`?`P:<"AUSW&(P+`?`(%(=O@<"+`"D8MW +M!!P$,$#8`+4$;>EQ!MHB((`/",`H?D`E@!(*<0;:(B"`#PC`*'Y`)0`4Z7$& +MVB(@@`\(P"A^&-@`IJ+`(""`#PC`Y`SQP"(@@`\(P&@,"'8H=UIR&G,*(0`A +M"B-`(0HE@"%P<>AUQ?9,(0"@"_3/ER +M_]LB((`/","$+@'G"A2`(/!_\7`T]B.%@.$$\O_8V6$`J22%@.$$\O_8V6$` +MJ0'F"12`(,]^T7"Z!\G_3",`H`#?TO9J=L]^%B'"(R"*J7!!DNES(B"`#PC` +MA"X!YV&^@.;O?S/W3"4`H`KRSW$(P.1/'`(B"`#PC`:`RB +MP0AW*'5`(`X(*HZ@YAIR!_(P=47V`H>`X`[T`(=`+0(2$+@%>L]P$`#I#D5Y +M(B"`#PC`?!#/<(C``&`2<`_WSW"(P`!@$G#*(0T$RB"-#Q``]`[B((T/",!\ +M$!"7L+<1MP2.@.`<'P`4(_+/<(C`U!`'B..X"_+/<*C^#`T"V4"'J7,B((`/ +M",!P606.@.`.\B"'SW`0`/`.$+E1EZ5Y:(XB((`/","8$`'8!:Z_\`'8!*Y* +M(P`@BB3#+P4>PA0JC@B.(!<1$1T@0``<%Q`0(H` +MX@B.%/)@P(#E`AQ$-`3R`8T#\/_8@.4!'`(P`_(!A0+P`-A!P(MQ8'KI<`B. +MDG`.]""'"+@0N05YSW`0`.@.!2%!!"(@@`\(P'P0@.5(C@KTSW`0`.8.(($&`@.+*(0($RB!" +M!.(@@@`%CH#@2_4$'L(4HL`@((`/","\#/'`(B"`#PC`@`P*)0"0*'=(=LH@ +M@0\0`.<.XB"!#PC`/'`(B"`#PC`@`P(=2(@@`\( +MP+04SW9%@"#EUW```/__0";/$Q+R6B`!"P>-*F<0``ICUE8*W'<4:`;#)NJ4^I<*D0W"`@@`\(P/8, +MX'C/<$6`I.(`@.!^X'CQP"(@@`\(P(`,"'<`WB'P6B8!'<]R1H!2,@`AC0]& +M@&PR#XV,((./$O0H8B(@@`\(P+B>"''I<"(@@`\(P*"D@.`&\@Z-`>`/>`ZM +M`>;/<$:`\#H`@!!VN`?%_R`@@`\(P.P,\<`B((`/","$#(#@`-PY\HEUB7(< +M\%HB`0W'<4:`;#)OB8PC@X\3]'")SHF`X\]S1H#,.&"#RB1B$'!VA_>`X`7R +M_]MOJ0'=L*D!XL]Q1H#P.B"!,'+"!\7_@.3*(((/``#^`.(@@@\(P'1D@.7* +M(((/``#_`.(@@@\(P'1D(""`#PC`]`S@>,]Q18"DX@"!@.`!V`/R`-@`H>!^ +M\<`B((`/",!T##IP`-W^V%IP#"$`H`'9PB%!`,]P18`&`B((`/ +M",`H?@'E`-@0KP'FSW!&@/`Z`(`0=KH'Q?\$&$`C(B"`#PC`W&R`X`KTSW&@ +MP``T`!$`")"X`!D@`(H@FP^*(18""G(!VR(@@`\(P"QM@.`-],]R18"DQR"" +M#"&`I,\A80#/(:(`(*(@((`/",#4#.!X\<`B((`/","$#*/!SW)%@*3B(((( +M=H'A`=@L\@#=SW%&@/`Z`*(!CJ"AH.!$`"D`RB#I`(#@V/9:)8$2#-J+<-EA +M!.$B((`/",`@#@#``<$"PB(@@`\(P/QB`>4!CK!]$'6L]B".SW!&@,PX(*`` +MV*/`(""`#PC`]`S@>/'`(B"`#PC`?`P:<`#=`_`!Y<]P1H#P.@"`$'5@``8` +M6B4.'<]W1H!,,@IP!MK99R(@@`\(P"!^@.#L]0`F@1]&@&PR#XF,(,./!Q"" +M(!/T#8E0<-3V_M@/J0'8$*D`V`ZIV&<*<2S:(B"`#PC`*'X&\`R)$')$]@#8 +M#JD@((`/",#D#/'`SW!&@!0$BB$(`B(@@`\(P$!^SW$(P%P9`]@B((`/18#H +MKB(@@`\(P,@9T<#@?J/!\<`B((`/","$#$/`1,'/=D:`]#H`AB/!!;C/=46` +MX..X8""@#12!,$7"(:"$P1'@!MHB((`/",`H?@"&-6@`VCUE3*U-K0X4@3!" +MI2^M4*T!X`"F$-P@((`/",#V#,]P18"HX@"`X'[@>/'`(B"`#PC`@`P(=P#> +M'O"U;@#8QW5%@.#C#:T.K0^-(B"`#PC`N)X(<>EP(B"`#PC`H*2`X`CR#(V, +M(,./1/8!X`RM`>;/?L]P1H#T.@"`$';`!\7_(""`#PC`[`S@>/'`@.``V2GR +M*',8\!5KSW)&@-`XQW!%@.#C0(*,B%!TA?(@A@\(P.QGT<#@?N!XX<7AQIAP +MSW!&@/@Z8(#/L0"Q` +M`5A@-Z@PB#!SP_!^`-C/<46`J.+@?P"A\<`B((`/","`#`#> +MSW!&@/0Z`(#/=46`',*`X`"EU_4#CJ]]$'6L]@#8H\`@((`/",#T#/'`(B"`#PC`@`P(=@#?!/`!Y^]_SW!& +M@/0Z`(`0=WX`!@"U;\EPQW5%@.#C0"5!%`;:(B"`#PC`('Z`X.KU#HV!X">. +M!_07C3!P4@`,`#>M!O#I<"(@@`\(P)AG)X[I<"(@@`\(P."=!HX/K<]P1H#X +M.@"`,(T0<0':CO<`A6*%'2!``'!PA_2X"?(!V"(@@`\(P-!@ +M`(6DN`"EY;@)\@#8(B"`#PC`T&``A:6X`*4@((`/",#\#.!X(""`#PC`\)(B +M@$`@`@,@>4APX'CQP"(@@`\(P(`,"'71B/"(D>;*(H8#RB'&`\H@)@[B((8/ +M","($,]P18#(X<]Q18!LL\EA\""``S!WB/?/<0C`:!(BI0'8!O#V>""`(J4! +M@`&ESW`(P&@2,'`!V,(@`0``I2`@@`\(P.P,X'CQP"(@@`\(P(0,SW9&@"P& +M#X`!D@`"`@@`\( +MP/0,\<`B((`/",!\#`#?SW5%@`3T0"4$%`HE@`^@P``0Z78&\"(@@`\(P``B +M`>8!A2"%$'$5\O`D0`#.N"*X`>#R:(T5`8X$N#!P[??/<*#`@`UG';B/``#_ +M_P3PSW"@P(`-&G``V!$:&#"4%0".`=F?N!`8("`$&&`@SW"@P``X&!B@#P`0 +M```!A2"%$'$3\NEP(B"`#PC`S(J`Y@;R`H6,(!"`B??//'`(B"`#PC`E)R`V,]QH,``.!`9(```$0`( +MA[@`&2``T<#@?L]P1H`L!@2`X'[@>/'`#QJ8/P#```#/<$:`+`80&(`/``#_ +M_R(@@`\(P.PASW"@P(`."!``"!`:&#`B((`/",!PG-'`X'[@>,]PB,`($0"` +MX'[@>/'`X<7/<4:`+`8&@8'@*'4#]`#8!J&I<"(@@`\(P.0@!(5`)0(8)X4# +MVR(@@`\(P"QM(B"`#PC`<&P@((`/",#\#.!X\<`B((`/",!P#*'!>G`Z"[H-_`+R(6RB7,):*0S"4BD0GT'\PA:#!YCKF/N1\:7#`%\"(@@`\(P'0B`AP$,,]P +M18`$]""``8`0<17T"G`B((`/",#,BL]PH,``.!@0``@$((`/`#```-=P`!`` +M``#8`O(!V(#@&/+/<:C^'`O/<*#````0&&``A.4,\@4G@!,`P2IR(B"`#PC` +M3"$(=2'P`-T?\`4G@!,`P2IR(B"`#PC`^(H`V!$:&##/<:#``!"4$0".`=V? +MN&09.(!A&7B#SW"@P``X&!B@#P`0``!O(S\`*2"`!$HF`'"I<*'`(""`#PC` +MS`S@>,]QB,`($>!_`*'@>/'`X<7/#B(((/",#H;"`@@`\(P/P,\<#AQ8#8 +MSW6@P``X`!T@$(H@!``,'2`0"!V@'Q`P```B((`/",#PE0+86!T@$'P=(!`@ +M((`/",#\#.!X\<`B((`/","$#,]UH,``(&P5`!C/=HC`M#4`IL]PH,``."`0 +M``B`X`*F#?+RN`7R$M@#I@[P+R@!`$X@@0&P5`!@!IB`@@`\(P/0,0Y""X@#9QO9"D$`@`00(\$>0 +M@N+%]D:00"`!!%EA@.$2\@")@>`0]&)I:'("\`'B`8EX8!!R2/<`BL:X@N#Y +M]0'8`_``V.!^5'CAQ:&(_]R1=0#;"?0`B)%P!_0`B1!RRB#"``+T`=C!Q>!^ +M\<`B((`/",!P+A2`T<#@?O'`(B"`#PC`A`P-R++!#AH8,`C:#1J8,,]VH,`` +M"!`6`!@.%@&>$'@P<#OWSW6@P``%/!V@$(MP`MDB((`/",!DFP04`3$X%0`8 +M$'$]]R*Y@L`B((`/",!DFPX2`C8-R`T:F#`.&A@P$!8`&`X6`9X0>#!P.O<\ +M':`0LL`@((`/",#T#/'`:B"``@0@@0____W_*2!``$HF`'`E$@$W)!I<,"]Y +M`>$O>8^Y)1I<,"D@``!*)@!P),S1P.!^H<'QP"(@@`\(P'P,*'<(=<]PH,"` +M#1@0``A(=AIP^[W1(.*'RB"!#Q``)`'B(($/",!P$"(@@`\(P)1L$'?B(($/ +M",!P;(#F"_)1($"GRB"!#Q``_P[B(($/",!P$*EPZ7')(P@PH3AQLKRD``)`+'@ +MV/(;]H3@X`$!``SV@>#@`0(`(B"`#PC`N$O5`2``"':!2W,P@`H/4],]PB,#,-B(@@`\(P+1O@.#,\@'? +MZ7`B((`/",#$B0AV0,?"\.3@#/+MX+[TSW"(P,PV(B"`#PC`M&^`X+;R`]AM +M\(P@0XM'\G8`"0",(,.$D_)(``D`C"`#@&?RC"!#@*3T@.'*(($/$``.#^(@ +M@0\(P'P0BW(*<*EQ(B"`#PC`N(<(=B(@@`\(P-QL`=F`X`#`P'DE>$#`B/", +M($.'3?*,(,.)@O3/<(C`S#8B((`/","T;X#@>/)KV"_PUW````'[%!P.O=/'7B0 +MBW`"V2(@@`\(P'2<0BB!($IP(B"`#PC`=)P.$@(V#<@-&I@P#AH8,!`5`!@. +M%0&>$'@P<#OW3QVXD"D@0`1*)@!PHL`@((`/",#,#.!X*'!(<6AR(""`#PC` +M*'/@>`#8(""`#PC`(%?@>`AQ`-@@((`/","`5P>`_]H/>00@@`\```#_*+B` +MX!_RB!%`,]PH,``'3`0``C@?@AS`=P`+``0\<`B((`/ +M",`@)`GP`-@/(,``(B"`#PC`0"2`X/CST<#@?N!X`-D/(0$`SW"@P(`>.!A@ +M`.!^X'BCP<]UB,`,-HMVSW>(P)`1J7#)<8HB_P\B((`/",!P1@`4`#&"X,H@ +MB@\0`/4.XB"*#PC`.@@;0//O`E3!`!X("B`:,!X22#"'2& +M),^?`>$DHP7R)8,!X26CR;@!HR`@@`\(P/0,X'@`V,]QB,"T$`2A`Z$!@>!_ +M`J'@>/'`(B"`#PC`;`RBP0AVFG%Z(P,P2`*?! +MIR.G1*=EIQ@?`!$<'T`1(!^`$1;8":\]PH,``(&P0`@@`'``T`>)! +MQ<]PP.Z)0`'9%;K)*HAT`"J(A`!JB,0`,]P$``#`B`@@`\(P)@0X'CQP"(@@`\(P)0S(B"` +M#PC`&'[@>.!X:2!``-'`X'[@>`AS*'('V&AQ(""`#PC`Y"8(*'!\<`H<@AQ`]@B((`/",#D)M'`X'^A +MP`#9(""`#PC`2';@>`G8`-DH*HA$`#//'`(B"`#PC`?`RFP0#9SW"@P``T`!``",]VH,``(&P6 +M#1A#P2(@@`\(P)`HA<%!P(3`(B"`#PC`0"@*)P"0!?1`V$+`K?`4%!`P(B"` +M#PC`^'F`X,H@8@`3>!!X`>`O)@?P0L"9]"(@@`\(P)"2`<$0<=@`+@!`P(#@ +M(_(B((`/","H>8#@`-G/(6($RB&A``+`)7@O)@?P0L`/\HMRL=@0V0';(B"` +M#PC`+&TB((`/",`(>GWP(B"`#PC`T'D`V&39(B"`#PC`O*4B((`/",#D>07` +M(B"`#PC`@'F`X`#9SR&B!,HA(0$"P"5X+R8'\$+`+_02\`7!Z7`B((`/",`4 +M>H#@$?($P15_&"$!`$3!!<$5>0+`1<$$PH#B#WG9]H#AZ_,5\,]PB,#4$!2( +MX;@)\L]PJ/ZL"@#9(B"`#PC`<%D"P(.X!/`"P(>X0L`O)@?P'_0!P0IP(B"` +M#PC`6'F`X`#8SR`B!$+`(B"`#PC`"'IL%@`8HGA#P(MRL=@0V0';(B"`#PC`+&VFP"`@@`\( +MP.0,\<`B((`/","$#`K8`-DB((`/",`XD<]VB,#$$0AU`(80=1+RSW"(P-00 +M%(CAN`ORSW"H_NP*`=FI`O8(""`#PC`!)'@ +M>/'`(B"`#PC`@`RBP0AW*'9(=8MPSW&(P``4`]HB((`/",`@#@'E_]@0=` +M(@@@0"(`*<]QB,"$'RC:(B"`#PC`(`Z`YEP`]D! +MVB(@@`\(P/A)Z7`]V0':(B"`#PC`^$GI<-W9`=HB((`/",#X2>EPP-D!VB(@ +M@`\(P/A)B,"8.!XX'C@>.!X(""`#PC`_`S@>/'`X<7/<(C`P!P` +M@*;!0<``V$7`SW6(P-00#XWCN`ORSW"H_L`'`=D`VB(@@`\(P'!9!<+_V!!R +M`_*%XE3W$'(#]$'"!_#/<(C`5"#P((``0<"!POG8!-D!VR(@@`\(P"QM#?`/ +MC>&X"?+/<*C^)`@!V2(@@`\(P'!9IL`@((`/",#\#/'`SW"(P-00#XCCN`GR +MSW"H_I0*`-DB((`/",!P6='`X'[@>/'`+R0'`,]QB,#($0"I"=@$J038!:G/ +M<(C`U!`/B$HE0`'CN`$90@$+\L]PJ/Y@"`39"=HH/*),(0!?3/<@C`D':=)0\:Z'$)<(ES2B4``$$M!!-*)P`+(B"`#PC`Q$@B +M((`/",!(?B`@@`\(P/P,\<`B((`/","T22(@@`\(P$A^T<#@?N!X\<`B((`/ +M","$#*'!*':+`38(""`#PC`="O@>/'`(B"`#PC`E'\!V<]P +MH,``2``88`#1P.!^X'C/.!^X'C/<:#``$@,&2``X'[/<:#``$@L&2``X'[QP.'% +MSW.@``!*`-K/=4:``'R*)`%P2'&H(``#\"5,D$\C@`>?N``8(`,$XX=Z`>$` +M%0$8UW',]QH,``4"@9 +M(`#@?L]PB,"`$@"`SW&(P(02GKB?N``0``@@@3EXX'\0>.!XX<7AQL]PB,`P +M%2"``8#X'$BP0<#/<(C`[!'`@`#:R7`/W,]SH,``4``;(`//<4:`:":`H1+P +MH.`5)(TPB/>*)/\?@*4!XD(@``@(\`#<#R0,$&&\@*4`V(#@[_4`P@'`0:$" +MH0@;H``"@2EN#!L@`#UYSW"@``!2-7C/<8C`@!(`H5(F`!#`N`2XSW&(P(02 +M`*&BP,'&P<7@?N!X2B0`>`#9J"!`!,]PH```4C5XGKB?N``0`@C/<$:`="8U +M>$"@`>'@?N'%`-C/!*)(!P`-BH($`#SW.@``A0%7OP(0P`GKN?NP`;(`,!X"""SW"@ +MP`!0`!A@`,'%X'[@>"ASSW%`@```(GA!*`$#>&#'<```_P\LN#!P0@`E`.'% +M(GA`('P`X'BH($`&02E-`5,A``$`W,]SH```3+5[#R0,$)Z[G[L`$P`(@.+% +M(`(#QB`!`P`;(``!X<'%X'[@>/'`X<6IP0AUBW#/<8C``!8BVB(@@`\(P"`. +M`8TB;0$<`C!`)(`P(-HB((`/",`H?JG`(""`#PC`_`S@>/'`(B"`#PC`A`RJ +M)A`0JB70$"(@@`\(P,!*J7$(*G!HV2(@@`\(P$!^BW?I +M<`C9(B"`#PC`0'Z`Y40`+@``WEIU%2"-(P"5`A43$2(@@`\(P+B>"'$4(4P@ +M`951(P"@`+3*(F(`RB#"`^(@@@\(P)2E0B)-((#E`>8D]^EP`=DB((`/",#< +MCZ+`(""`#PC`S`S@>/'`(B"`#PC`>`P(=2AW2'8`$9``_]@!$9$`$G#,($*$ +M"/*I<"(@@`\(P)!O@.`*],]P$`#2$,EQ(B"`#PC`?!`4)8`3,G9AB`/T8:\% +M\$"(%"6!$&&I$G9`B`3T0*\%\"&(-'U`K?_9(:@@J"`@@`\(P-P,X<4`W?_; +M@.+*)(UPX'CH("T"%"!"`V"J8:H!Y6"I8:G!Q>!^`=C/<:+``$L(&2```-@( +M&2``X'[QP"(@@`\(P'@,@B0".X'`&G#/<8C`Z!1(VB(@@`\(P"`.E,6I<,]Q +MB,#@%1#:(B"`#PC`(`Y6)!$SSW&(P-`<*G!,VB(@@`\(P"`.BW;)<"(@@`\( +MP/QS`,((<0*Z"G`B((`/",`H?B(@@`\(P/!SR7`B((`/",#\$:]('"():I@AV(B"`#PC`\'.!YLHA003* +M($$#XB"!#PC`*)!?\""0AB'\`(PA`H`>]$`@#0G`ED(F#AD5\`"-X8V,($.' +M`N<)])/`(FT$VB(@@`\(P"`._671=\(FQ1/*)B80@.;L]3GPC"$#A#7T0"`! +M!@"1UW````0)+_23P`+A!-HB((`/",`@#B?P112-,"'P+RA!`TX@CP>$YTCW +MSW!%@!#<\"#``X#@"_1%%($PSW`0`!@IQ$"7-$X#EW_4B((`/",#P'%X<:AP4/!`=D@ +MHL]TH,``#F@4`1AH%`$8SW,``/S_0,$`%`$QAB'\`(PA`X1D>#KT)-D0'&`0 +M:!0!&#!YUW$```0A,/0XW0?P02X!$B]Y`N$]91`<8!,C;61Y,'!$``X`:!0. +M&,]YI^'P]6@4`1@O>8CAS"'B@NKU`-D0'&`0(*($V!`<(!`1V&/``\``'"`0 +M"-@0'"`0^=@`'"`0$!Q@$`#8H<#!QL'%X'^AP*'!\<`B((`/",!D#/0<2+"Z +M<$AW!""`#P``_/]"(!`!`,)!*(`@JG$B((`/",!(G<]R1H`<)4`2@0!6(A0" +MPXI!$HT`"B*`+Z#```YH$@`H2B,`(F@2%B@0&N`DD.%*(0`@*O2,)L.?RB&! +M`\H@@0\0``P/XB"!#PC`?!#/=46`L++5?0"%@.#*(8$#RB"!#Q``#0_B(($/ +M",!\$`#8`*>`A:IP`,'*(#E`*?6]2IU@.4.\B(@@`\(P-R&$!K@ +M)$$H@"`B((`/",#$B:EPH\`(W"`@@`\(P+8,X'BBP4'"`=@`HP04`#$`V88@ +M_`",(`*`4-S,(`*#T-S,(`*#RB!"``/T`=C@?Z+`X'C/<(C`N!(`B."XH<$$ +M\@'8`*(#\`#8X'^AP.!XHL'QP.'%0\)H=2(@@`\(P)B0`*4,%``Q`-F&(/P` +MC"`"@%#!XH<'Q +MP,]SB,"X$F"+X+L'\B(@@`\(P"2)!?`B((`/",`(A]'`X'^AP*+!\`$)#@ +M#_0CCXPAPX_*(($/$``8#^(@@0\(P'P0`X^!X`/R`=@%\"(@@`\(P)B0@.`` +MIA3T0.7/<$:`9"4`@$"%01\"$$C8SW&@P``.$!D@``"%`!D@`$"E"-P@((`/ +M",#N#.!X`=D0N!$:6#"!N,]QH,"`#009(`#@?N!XSW"@P(`-&!``"`0@@`\` +M$`<`X'[AQ>'&4R"#`R*[SW2@P``0L!PXD,]TH,``#H'CT/<$'&`0`-D$\`0< +M8!,!X(@I.!^\<#A +MQ<]PH,``,#`0#0@`V,]Q`0"@AB(@@`\(P,R0@.#*(4$#RB"!#P``!`/B(($/ +M",!\$"(@@`\(P$2%`]G/<*+``$L`&&``(""`#PC`_`P`V"`@@`\(P`21X'CQ +MP"(@@`\(P(0,SW6@P``@;!4#&,=S`0"@AFP5`!@`WG!PRB9O$"(@@`\(P(@M +M@.#,)B&0\_.`X,H@@0\```<#XB"!#PC`?`@@P">N9^Y`!G@``'BX'[@>(HD`7``VJ@@@`//<:(``$A5>?`@ +M@P">N9^Y`!G@``'BX'[@>/'`(B"`#PC`A`R`V+0<"+#/=HC`C!(`AB*XP[B. +MX$7W3B`-!`/P3B`-""MM`KF!P"(@@`\(P#0G((;/<_\`_P!!*4`'0"G.`D`H +M`@(8N&1Z17B+GX:&``3:4$H#`8;N<5\*+B$>R5X!""`#P#_`/]E +M>'\:&`"+=LEP3-DB((`/",!(3#)MR7`B((`/","$CK/`(""`#PC`]`SQP`+8 +M(B"`#PC`.'0B((`/",`8CM'`X'[/<:(`0%`5>4\A@`>?N``0``C@?@'9SW"B +MP`!0;!A@`&088```V<]PB,",$N!_(*#QP,]SH,``(&P3`0C'<0``,'5L$P`( +M`-HP<,]PHL``4&`0``C*(F\`P;B"X`'/'`(B"`#PC`<`P(=@HB@"^BP`!0:!(-*`HA@"^@P``@ +M;!$`*$$ICP``(),/```P=1IQ./`$%@$40B=/D$`I``)!*0(&!7I!*0`"&+D$ +M(H(/_P#_`"5X!""`#P#_`/\%>L]PH@``4+5XGKB?N``8H``!Y07RD.7`!\7_ +M4R7-D!+T;!$`*')P`-A@$@$HRB!O`%(A`0#@N4P<,!^B.6P]P+8(B"`#PC`9'3)<"`@@`\(P.0,X'CQP"(@@`\(P'`N +M!X\<`B +M((`/",!\#!IP"B=`D,]P1H#T)@AU!/05@(#@$_1`)0X6`MC)</'`F'`H<,]Q18``WV"!@.,' +M\L]R18!HLT""8'N(<='`X'[@>/'`(B"`#PC`@`P*)@"0*'?/=46``-\@A0?T +M@.$.],]P$`"P$`;P@.$(\L]P$`"Q$"(@@`\(P'P0P*7/<$6`:+/@H"`@@`\( +MP.P,X'CQP"(@@`\(P-QL@.`!V`;RSW"(P)`2`(#1P.!^SW&(P)`2X'\`H>!X +MSW&@P(`L0!D@`.!^\<#AQ<]SH,``(&P3`@B8<#IB;!,`"`#=4'#*)6\0B'`B +M((`/",`8D8#@S"4AD//S(""`#PC`_`P`V0\A`0#/<*+```@$&&``X'[@>`#9 +M#R$!`,]PHL``"``88```$``()'A"(`"`X'_*(&(`\<`B((`/","$#"AVSW5% +M@+#;%GT"N4&%4''*((T/```J,^(@C0\(P(@0`(4"((`/7C\``-5XGKB?N``0 +M``@@((`/",#T#.!X\<`B((`/",!\#`AWSW!%@+#;]G@:?N``0``@$ +MY00>$!`@((`/",#D#/'`(B"`#PC`?`P(=\]P18"PV_9X&G.@@$AV`B6-'UX_ +M``!2:35]>6%A@`*Y<''*(8T`RB(-!,H@C0\``"HSXB"-#PC`F!!3)GZ0RB+" +M`\HA@@/*(((/```L,^(@@@\(P(@03"``H,HD`G3@>.@@H@)/)8$7!!8`%)^Y +M`!D@``3E(""`#PC`Y`S/<*/``$`@$``(X'[/ +MN)^X`!A@`.!^SW&(P"0@\"$!`,]PH@"`*#5XGKB?N``0``C@?L]RB,`D(/`B +M`@#/<*(``"A5>)ZXG[@`&&``X'X@((`/","`(O'`X<7/<*+```@,$`$(Y+G1 +M(2&#$/+/=8C`W#4&A8#@RB"!#P``+C/B(($/",!\$`:%0'@@((`/",#\#$"` +M.+I`J4"`,+I!J4"`*+I"J0"`X'\#J?'`SW"(P-00"(CCN`GRSW"H_J`/`-DB +M((`/",!P66D@0`#@>-'`X'X@((`/",#H,_'`SW"(P-00"8CCN*'!"O+/<*C^ +M%!``V2(@@`\(P'!9:2```(MP(B"`#PC`/#*`X!+R`,`B((`/",`P,\]PH,`` +M'3@8H`\$````(B"`#PC`F`\&\&D@@`%O(3\`SW&(P)@1`(&"X!+T`=@`H2(@ +M@`\(P,`R(B"`#PC`$)8B((`/",`HEFD@@`'/<(C`U!`)B..X"O+/<*C^-!`` +MV2(@@`\(P'!9SW"@P``=-!B@#P0```"AP-'`X'[QP.'%"'4B((`/18`0I0:E +MJ7`B((`/18!DJ@FEJ7`B((`/18"TG`BEJ7`B((`/18`LH0NE`-@.I2`@@`\( +MP/P,\<#AQ0AU!O`B((`/",!PE:EP(B"`#PC`!):`X/;U(""`#PC`_`S@>/'` +MX<4(=2(@@`\(P`260H7`V1BY@.`E>@_R@H``$@`(9H5F>&6%97@`&B```X4E +M>``8(`,'\``2``@FA21X`!H@`"`@@`\(P/P,X'@B((`/",`(>2(@@`\(P$26 +M(B"`#PC`?)/T\>!XH\$`V"(@@`\(P)A-SW$``0``SW```0``$''B(($/","H +M)L]VB,!$-HMUSW>(P)P1R7"I<8HB_P\B((`/",!P1@`4`3&*X0AR0_:`X@CR +MSW`0`/4.(B"`#PC`B!``%``Q`L'P)P(08'H!P.3Q\<`B((`/",!\#`AU`("` +MX#/R:B"``@0@@0____W_*2!``$HF`'`:<*EPX87&A2(@@`\(P+@0T7<&]`:% +M(B"`#PC`G)0$A8HA"``&><]PB,`($P"`*W@+\D.%SW#`[H)2`=DB((`/",#` +MG"D@``1*)@!P`=@"\`#8(""`#PC`Y`S/<:#``#@($0`(D[@(&2``X'[@>""` +M,'#*(2$`X'\H<,]PH,``((`8H`\````0`!B@#P```$#@?O'`(B"`#PC`1);/ +M<*#``"`(&*`/(````-'`X'[/<*#`@"!@&*`/`P!`#>!^0(`#\$""4'`%\F2" +M*WO\\P+P`-K@?TAP\<`B((`/",!\#`AW)?`$AP`0`0@"A2)X@.!.``D`J7`B +M((`/","X$,]VH,``(&P6$!BI<0.%(B"`#PC`2'80%080SW"(P`@3`(`&)H%Q +M`````BMX$O3I<"(@@`\(P`26"B4`D-7UZ7`B((`/",",]PB,"4$B`@@`\(P'24X'CQP"(@@`\(P(0,SW:@ +MP``X&!8-&/.]"?+/<(C`E!(B((`/",!LE@0EOI\'``"`RB%"`\H@@@\0`#,! +MXB""#PC`?!`8'J`?#P``@"`@@`\(P/0,X'C/<(C`E!(@((`/",!LEN!X\<"J +M()``X;@&\B(@@`\(P``T!O`B((`/",#,-='`X'ZJ(=``JB(0`:HC$`#/.!^X'C@?P#8H<'QP"(@@`\(P'P,H<$(=D;`&A0` +M,00@@0\```"`3[F!X3+T(B"`#PC`V"):(`$+"'7/<$6`!-_D:'`G0A!`()`! +M4';*(8(#RB""#Q``!P/B(((/","($(MP(B"`#PC`_'-AAPAR!8<0B&![((G`:ZERPO'@>/'`(B"` +M#PC`Q#$B((`/",#L,2(@@`\(P*!NSW"(P-00"HCCN`GRSW"H_NP/`-DB((`/ +M",!P6='`X'[@>/'`X<6`X"AU$O(B((`/",`P2`HA`(``A0'@`*7*(((/$``8 +M`>(@@@\(P'P0(""`#PC`_`SQP.'%@.`H=1+R(B"`#PC`4$@*(0"``(4!X`"E +MRB""#Q``%P'B(((/",!\$"`@@`\(P/P,\<`B((`/",!\#`HE`)!B\FH@@`($ +M(($/___]_RD@0`!*)@!P&G`+R+A@"QH8,`S(@.`)\A!UPB!%`\H@9@`,&A@P +M!A(,-@#:2'$+\,ER8*0)R`3D$'2$]PH2##8!X:#A/``&``"$@.#T\P#;X("@ +MY\?W3B$.",)_`>?@H`+P(*#`A`2`T7#T]06&@.)DH,"$WO,%@L2@!88%HMOQ +M"L@&&A@P#/`!V`"B`-@&HDAP(B"`#PC`M$3)`!X"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0"!$` +M"`0>$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0 +M"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$ +M'A`0"!$`"`0>$!!")4V0$-^J]2`@@`\(P.P,\<#AQ8#@H<'+]PAUBW`!V2(@ +M@`\(P&2;8;V`Y3CWH<`@((`/",#\#.!^X'@`VH#ARB1-<.!XZ"#M`O`@@P#/ +M<:#```5`&>```>+@?@W(!]L.&A@P#1K8,,]RH,``"!`2``@.$@&.$'@P<#CW +M3QKX@`/851HX@.!^\<`B((`/",!$#4+!SW&@P(`.[%O+/`0<(!`$'&`0X'[@>.'%SW*(P`@30(+FNC/RSW.@P``@SW*@P(`&HB +M@`+CN@7RJB'0`@/PJB&0`L]P$``"`B`@@`\(P(@0X<7AQ@#:SW-%@.#C0",, +M`DAU"/!Y9=5H%^')80'E.F+/<4:`^#H@@3!UMO<%N!QD0*3!QL'%X'[AQ>'& +MB'3!C*1LM.;6?4OV!*T@I46M8[4!C`'@`:P!V`+P`-C!QL'%X'[@>/'`(B"` +M#PC`@`P(2"Y%(`!@"#XSP`#0!`)X]V,R;#<(C`3!/P(@X# +M='\5(0T#`'\`V^"%Y'X+\`';X(7E?@?P`MO@A>=^`_`#V])^P*6`X`#=!?3P +M(0`#@.#7\P'8UO$@((`/",#L#.!X\<`*(P"`RB#A#!/RCN,$]TEK!?!!*X(` +M!>)(<"(@@`\(P,BD$'/*(($`RB#B#-'`X'[@>/'`(B"`#PC`6`QZ<+P<2+`` +MW43%A`#]@&M`-IAC0&/<'+,(@N`8`?* +M_P`D@#`F$(P`2V$!XH5[)AC"`$]Z\/%,(0"@RB'!(Y[Q0"%9,!@3@"`O(4Q`-\+\`3`!!`",0'G`B"!``881##O?X'G?@$) +M`,]QB,"`'R"!`^!/P<]QB,"L'R"!@.=0P0`3`2!/P0/!!'D`P$3!%2#8`P08 +M1#`!V6S!#\``V@;T%!,#((#C`_)(<4`DA2!`)$8@5B0',@':`-M*)``"(B"` +M#PC`W*2*<(HA"`"J%1U"$2?P"!`!$#(A0`'X<"(@@`\(P+B>&7#I<`EQ +M(B"`#PC`H*2`X!/R0"4$%>AP"G$!V@#;(B"`#PC`&)[(<`EQ`-HB((`/","4 +MI4`E10!6)@@4!!"`$+!PK`?-_P#8)_``$`$03B>`#(#ARB("`,HBP0%(<"(@ +M@`\(P,BD"B4`@!/RR'!(<2(@@`\(P*"D@.`+\D`E!!6H<`IQ`=H`VR(@@`\( +MP!B>0"=``++@M`?N__APJ70!V8`DAAX@K!"&@.`$]`*',*8/IA.&@.`,]%4F +M0!1`)P$3!MHB((`/",`H?@'8$Z9`)@`?J7&`(0`L@P($5\L]TB,`8(``E@0#L +M9`'B"R8`@,\DXA&`J4"K$GD`E21X`+4!E21X`;4!YDP@`)`+\@"+D'!)]O_9 +M`"4%```=0@`!X`"K"-P@((`/",#N#$$I0P'$N0#<@N,/)$P03/=U>(#B((`% +M\B5\X'^`H(9YX'\@H.!^X'@(<@H@0(#QP`;R(B"`#PC`%*:$NIVZGKK/<*#` +M`!Y`&*``X'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XT<#@?N!X@.#*)`UPX'CH +M(*T!X'C@>.!XX'C@?N!XSW&@P``@2!DX``@9H`\0````X'[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWA,```#@ +M8P```(!%@.!_".`)@.!^"X#@?O'`(B"`#PC`A`P(=<]PB,#4$!&(X[@H=@GR +MSW"H_J`#`-DB((`/",!P64`E`1S)<(HB&0\B((`/",`H?B`@@`\(P/0,X'[@ +M>/'`(B"`#PC`<`RAP2AU2'

!IP(B"`#T6`(((*(8`OB,#4$'IP$1&`(`#> +MX[ABCT#&#?+/<*C^7`8#V:ER"B3`!"(@@`\(P'!9&B.!+P``K`8*(H`O1H!, +M"@*/0"(-(8'@/64;\H+@)/*/X`KR!H6`X"#RJ7`B((`/18`0B1SPJ7`B((`/ +M18`0B8#@%/00V`*O!H6`X!#T#/`&A8#@"O(CCXMR:G`B((`/18"DA`3P`=A` +MP`#`@.`N\A$1@"#CN`GRSW"H_IP&`-DB((`/",!P6<*E(H\*<"(@@`]%@%2# +M!H6`X`/R`!J`(ZEP(B"`#T6`4(#/=4:`3"15)4`;:G$B((`/18",FLP5@!!A +MN`]XS!T"$*'`(""`#PC`S`S@>/'`(B"`#PC`>`PH=QIR,'@B((`/18`@@@AV +MSW"(P-00$8CCN$`@#2$+\L]PJ/ZX`P+9Z7+)**X%*T! +MV"`@@`\(P-P,X'CQP"(@@`\(P(`,H<$(=<]W1H#L)(MV0"<`%`R")`8\*'.X#O(%%(0PSW"H_@@'`]G)<@IS(B"` +M#PC`<%DB((`/",#<;(#@"_*+/'`(B"`#PC`@`RDP0AV*'4B((`/18`@@@AWSW"(P-00$8CCN`SRSW"H +M_C0#`]G)6(>B4#&8<`=B7IB +M!1P",!"*!AQ",P<<`C``V$+`0\"+<@_8$-D!VR(@@`\(P"QMI,`@((`/",#L +M#/'`(B"`#PC`@`RDP0AW*':+=:EPSW&(P+`<$-HB((`/",`@#L]PB,#4$!&( +MX;A`QPORSW"H_L0``MGI/'`X<6@@<]PB,#4$!&( +M?HWCN$*%#_(@%000SW"H_E0''16%$`79`!4&$"(@@`\(P'!9`H6`X`?R@>`* +M]`+8`J4&\*EP(B"`#T6`M(8@((`/",#\#/'`(B"`#PC`?`P(`,\H+@#/0`V`*EJ7`B((`/18"TA@3P`-@"I2`@@`\(P.0,\<`B +M((`/",!\#`AU*(`R()`/``#J`8#A]!`.!UZ(?8C,(B&`S"-A@`CRSW`0`$D0 +M(B"`#PC`F!`!WTP@`*#HI0KT`-@=K:EP(B"`#T6`Y(7]K2CPFB8/&A#8R7$B +M((`/18`XL`HA`(#*(((/$`!*$.(@@@\(P'P0SW"(P-00$8CCN!#R`!4%$,]P +MJ/[`!`397HW)/JTU>!20&B".#P``Z`,0V,EQ(B"`#T6`.+`*(0"`RB""#Q`` +M2!#B(((/",!\$,]PB,#4$!&(X[@/\@`5!1#/<*C^5`0$V5Z-R7.8=R(@@`\( +MP'!9H<`@((`/",#L#/'`(B"`#PC`@`P(=GZ(@"`'"'5XSW6(P-00ZH@1C>.X +M'1:%$`[R(!8$$,]PJ/XL!0`6!A`%V4*&(B"`#PC`<%D=C@'@':[)<"(@@`]% +M@!")@.`HAA3R@.'*(($#XB"!#T6`/(4=CA!W'?2,)\.?RB""`^(@@@]%@.2% +M%?"`X1/T$-B*(0\*(B"`#T6`.+`*(0"`RB""#Q``1Q#B(((/",!\$!&-X[@2 +M\B`6!!#/<*C^K`4=%H40!=D`%@800H9^CB(@@`\(P'!9(""`#PC`[`SQP"(@ +M@`\(P(0,SW9&@$P*R7#/<0``T!HB((`/",!`?@#=`=E*)`!QJ7"H((`$&B"# +M#P``K`9$;@'@>F(CHJ6BO:JBHKZJJ**PJJ:BSW!&@``E!-DB((`/18`HFL]Q +M18!0A`'8(B"`#T6`Z*Z@IB`@@`\(P/0,X'CQP"(@@`\(P(0,FB`:"Z/!`""- +M#T:`4`KX%0`7`-L:(($/``#H`WVM8J5^K8#@RB9"$,]PB,#4$!&(RB9A$>.X +M:*4,\L]PJ/X8`0/9R7*8/'`(B"`#PC`?`RBP2AW +M,'[)<"(@@`]%@"""SW6(P-00&G`1C>.X#/+/<*C^\`,"V>ER"G,B((`/",!P +M61&-X[A`Q@SRSW"H_B`$`MG)<@IS(B"`#PC`<%DB((`/",#<;(#@RB("!\HC +M8@#*(2("RB""#P``L@#B(((/",`L;:+`(""`#PC`Y`SQP"(@@`\(P'P,JL$( +M=@#?BW6I<,]QB,!P%2C:(B"`#PC`(`X$%A`0SW!&@$P*+(9)P,]P18!T@4#` +MSW!%@%2`3"``H$+`!?+/=T6`B(CEN4''!O+/<$6`N((#\`#80\`%AB"&1,#/ +M`/>`VJ'*X0N`#?)7A%P`.&1L='P.&FSW"(P,PVJ7$B((`/ +M18"8JPAUSW"(P-00$8CCN`ORSW"H_FP!`ME`AJES(B"`#PC`<%F`Y0SR3"`` +MH`3R`=@!IAV.XJ9AN!VN`-@$\`'8`J:JP"`@@`\(P.0,X'CQP"(@@`\(P(0, +M"';/<(C`U!`1B..X*'4)\L]PJ/X``0#9(B"`#PC`<%E`)0``P(=<&(&G$"\,F/BB'#+S)V'/(5)8\3 +M"(\2Y82(@@`]%@#R-+(X`&$`@ +M#!X"%0KP8((`&,`@`!H`!0R.$'$$\@#8*O`"AS)P?/<#AX#@^O,1$H`@X[@* +M\L]PJ/Z$$0#9(B"`#PC`<%D,CEH@`0>Y82(@@`]%@#R-18<&AV!Z(8?@\<]P +M$``'$.EQ(B"`#PC`?!`!V*'`(""`#PC`Q`S@>/'`X<4(=<]PB,#4$!&(Y[@- +M\C(E@A\```P!SW"H_A@1`=DB((`/",!P60#;"-I:(P$'!&T986AP(B"`#T6` +M/(T!XV&Z@.)O>S/W(""`#PC`_`S@>/'`(B"`#PC`@`P(=RAUQ&DH<(HA!`8B +M((`/",!`?O_8J72`)`03`*Q*)`!R`-BH((`"6B`"!__9`>`/>-IB(*)5)4`> +M"-DB((`/18`HFN"E(""`#PC`[`S@?N!XX'[@>/'`(B"`#PC`>`P(=0HG0)`` +M$!``SW&(P/@3`($A@?@<"+#5A5`5$1!!P0ST@.8*\HMQ0"4"%@'8(B"`#PC` +M1)ZI<%C9(B"`#PC`0'Z`YPWT@.8+\D`E`1:+<@'8(B"`#PC`1)[5I5`=0!0` +M'0`4HL`@((`/",#<#.!^X'CQP.'%SW5&@$PG`*5`)0`>#-DB((`/",!`?@#: +M3*5-I5&E!&T%V2(@@`\(P#1=(""`#PC`_`S@>/'`(B"`#PC`A`P`((X/```` +M"52&*'50=0/9"?15AH#B!_*!X@SR@N(,\BAP"_`UIJEQ(B"`#T6`-*<%\`+9 +M^?$`V(#@"_)4AL]P$``0$'6&J7$B((`/","8$"`@@`\(P/0,X'CQP"(@@`\( +MP'@,@B0:,PAV*'6+<#IPSW&(P"06BB(:`"(@@`\(P"`.R7"I<2(@@`]%@-B/ +M&G",(,./RB%!`\H@@0\0``\0XB"!#PC`?!!:(`\MJ7'?9V.'#(=@>RIR@.`S +M]`HA`">`(1H@*G`,V2(@@`\(P$!^#M@"&0(@`(:I<0':(B"`#T6`^)QEAZEQ +M#(=@>RIRR7"`(`8+"G$B((`/18",FH#@RB%"`\H@@@\0`!,0XB""#PC`?!`` +MAB(@@`]%@+B?+/#)<"IQ"G(B((`/18#PD'4>6!/).'%@.)``"P``-N8*@@@`86(<(`6B,-`X2*'66"M86*@[6#DH*E@(*<9`0DOI\`&```@*4$ +M])N\@*4!XV][P<7@?O'`(B"`#PC`?`RAP0AV*'<:<(`@!BN+=0IPJ7$B((`/ +M18"0F0?P"G"I<2(@@`]%@-29@.`/]"#`6B`!#=EA2(%0=_/U#.$B((`/18!` +MC2#``O#_V*'`(""`#PC`Y`S@>/'`(B"`#PC`?`PH=>1I-8\(=K3A&G($]H#A +M"?;//!ZX$CPBN`H<$I@.'!:8$ +M$``@&&"`N`6V(85!*8``X[G`N,\@8@#DN<\@H@#EN<\@X@#FN<\@(@'IN<\@ +M8@+GN<\@8@%@A4\@@@&`X\H@@@#JN<\@X@$#I@#8!J8($`$@@.$'A@/R@+@' +MIH4@`0$'I@2'N!X8$"`@@`\(P.0,X'CQP"(@@`\(P'`,.G`H=AIRI&D(=X`G +M!Q4`%1(0Z7"*(1T/(B"`#PC`0'X`(9,O``!8">EPR7%JEA,'21]U8C`0R5>?R1%26!$/:Q"'&`(1(- +M57G:C@'BSJD!WL^I`>2"Y*+W!=D]M0SP,B.!#P``N@$(=(`D$ATNK%:U`=DO +MK#2+@"`3!#RU58M`(P$&(B"`#T6`D(\@((`/",#L#.!X\<`B((`/",!X#`AW +M*'8:GWO653)8`0@.#*)6$02WWV +M\TM]RB%!`\H@@0\0``H0XB"!#PC`B!"FITPA`*"*((@"RB!A`PFF#=@,I@#: +M'/!:(@$#42!`H-EA"(%/($,#:*$%\HRXC;@(H1"/`>(H&0(`0"V`$VF!!""` +M#P$``,!E>`FA@N*F]R`@@`\(P-P,\<#AQ4`@`P,`W0C:6B4!':]X>6$B((`/ +M18!`C6&Z@.(!Y3;W(""`#PC`_`SQP"(@@`\(P(`,"'7@@,]Q``!X"<&`(B"` +M#PC`0'ZI<(`@!@L(V2(@@`]%@"B:P:7@I:EP(B"`#T6`;*D@((`/",#L#-AP +M*'-$@PHE@`]%@/B-`(`*)(`/18!/'` +M(B"`#PC`>`RBP1IP`-VI<"(@@`]%@!B4:B"``@0@@0____W_*2!``$HF`'`Z +M<,]V1H`0,54F0!^+<2(@@`\(P!1_@.#*(((/$``B$.(@@@\(P'`0`,'/=T:` +M$#*`X&3X4_W6B$``]M@`(.`X/CS3J`,!V:ER(B"`#PC`<%F$Y\X` +M"@`:)X$?``"L!@H@@"]&@$P*0"`.(3YF!H:`X![R`-A`P(MQ$-@Z<"(@@`]% +M@'BO`,"`X!+T!!Q`-('!`=@B((`/18#$KX#@RB""#Q``0Q#B(((/",!P$`*& +M@.`C]*EP`MDB((`/18!4@P:&@.`%\@#9`!A`(,EP(B"`#T6`4(#/=4:`3"15 +M)4`;Z7$B((`/18",FLP5@!!AN`]XS!T"$!7P/(Z8O1"YSW"(P,PVI7DB((`/ +M18"$%]BJ*@>'"]@'8!J4#AZ"X +M`Z<&A8#@(/(`$@`@@.`<\A$3@"#AN`KRSW"H_D`"`=G),"X`:4<'4(40"<`$ZEQ +M(B"`#T6`](DFA0`:0"`*(H`O1H`,)0P2@"`!X`]X#!H"(`"'P+@#I0@7!!`1 +M$X`@%!T`$>.X$!U"%`SR*L//<*C^G`(#V`P:`B"KP"`@@`\(P,0,X'CQP,]PB,#4$!&(X[@)\L]PJ/Y$``#9(B"` +M#PC`<%DB((`/18"$A]'`X'[@>/'`X<4(=2AR`=LB((`/18#`BB&-(*J,(<./ +MRB#*`,H@2P/B((L/18`XBB`@@`\(P/P,X'CQP.'%"'(B((`/18#`B@.*`=T` +MJ02J0(G/<(C`U!",(L./$8C`?>.X"?+/<*C^2`\!V2(@@`\(P'!9J7`@((`/ +M",#\#/'`X<4(.X"?+/<*C^=`\!V2(@@`\(P'!9J7`@((`/",#\#/'` +M(B"`#PC`@`P(=BAW`KD`W0CA(B"`#PC`0'Z`Y\HDS7/*(4T#Z"`M`Q4F0A`H +M<*NJ**H!X2FJ8;@*JA4FP!/_V26H*JZAK@EO`JXCKN"NR7`B((`/18#`BB`@ +M@`\(P.P,X'CQP"(@@`\(P'@,"'7#B(HAPR\R=AIQ$_3/<(C`U!`1B..X"_+/ +M<*C^X`X!V0IR(B"`#PC`<%D!WCCP%26/$PB/$G`'\LF/,G;Y]0'>&?"I<,EQ +M`=HB((`/18#$BB*-,G$%]`H?0A3!K07P%25`$,FH*J__V`FO`-@+K\*M"';/ +M<(C`U!`1B.6X"_+/<*C^)`\"V0IRR7,B((`/",!P6:EP(B"`#T6`P(K)<"`@ +M@`\(P-P,X'BEP?'`(B"`#PC`=`RAP4C"2<,H'``Q+!Q`,3`<@#&H@`HA@"^( +MP-00$1&`(..X*'<*\L]PJ/[`$0'9Z7(B((`/",!P654E4AZ+<4IP(B"`#T6` +M7)F`X,HAP@/*(((/$```$.(@@@\(P'P0(,#$;5H@``<>9A$1@"#CN$`D$#@. +M\B04!##/<*C^Q!`(PP/9Z7(B((`/",!P6>&F0"8`$@IQ%-HB((`/",`H?JEP +M(B"`#T6`D(Q6)1`8_]D,$(`@,'``%(0P(O0,&`(A(*81$8`@X[@,\A`0`B#/ +M<*C^_!$!V2(@@`\(P'!9(,#)<2(@@`]%@#R-$!``((#@!O1$A@:&8'HAA@#> +M"_`(PZEPR7'ITP@`*`,K@/R`=@$I@`3`B"*(,,O +M$G(1%($@'_($AH#@'?1:(P\'X[DB=PSR!!<$$,]PJ/[<$@/92G(B((`/",!P +M60R.Z7$B((`/18`\C42'!H=@>B&'"_#CN0GRSW"H_CP3`-DB((`/",!P60`; +M`"15)4`>2G$B((`/18",F@HF`)#*(8($RB""#Q``!!#B(((/",!\$*EP(B"` +M#T6`D(S)<"`@@`\(P,0,\<`B((`/",!H#"`0$``H=U8@$2A*)``@#!&-($`@ +M%2%:)0X7"G`B((`/18"0C$`@$B&*(\,O\,]PB,#4$!&(X[@+\L]PJ/ZP$P+9J7+I/'`(B"`#PC`A`P(@.`']"*%R7`B((`/18#\ +MHB`@@`\(P/0,X'C/"'5`(`<#SW!%@,3C0,#/<$6`O.-!P,]P18#`XT+`SW```*\- +M!-D'VLES"B2`#T6`K.)*)8`"(B"`#PC`E%O_V`"EP:4('8`?V@``\$`E`!Z* +M(0@&(B"`#PC`0'[I<*/`(""`#PC`[`SQP,]Q18`@W"AP(B"`#T6``(`(/'`(B"`#PC`@`PH +M=\]V18`@W,EP(B"`#T6``(`(=#-HB((`/ +M",`H?@"'8;B#X#H`#0`S)@!PB,#L$T`G`7,4>2!Y#.6I<`;9"O`!A@#:)(8B +M((`/18#XG*EP!=D`VB(@@`\(P#1=(""`#PC`[`S@>/'`(B"`#PC`@`REP<]V +M18`@W,EWZ7`B((`/18``@!39"'6+<"(@@`\(P$!^!MI`P@#;0<,*)(`/18`@ +MHP@<`#$*)8`/18#\H@P<0#$AA43'R;G'<=H``/`BI0&&V'$``-HB((`/",`T7='`X'[Q +MP"(@@`]%@`"``=D,X`#:(B"`#PC`-%W1P.!^\<`B((`/","$#"AV(B"`#T6` +M"(`(<2(@@`]%@`"`"'4H<"(@@`]%@#"+@.`5\D`E`![)<8HB"`8B((`/",`H +M?H86`!8`V0&E0"4`$RAR(B"`#PC`-%T@((`/",#T#.!X\<`B((`/","`#*/! +MSW=%@"#,]P18`@W`&`OMD`VDAS(""`#PC`X'/@>/'`(B"`#PC`;`R" +M)`@V"B2`+T6`(-R*<'IP(B"`#T6``("*)@\:"'5`(`\(&8\:((`#"MI"*,$' +M(B"`#PC`]`TZ/'`(B"` +M#PC`<`REP7IP*'4B((`/",!P+@AV`(7AN`#9"/+)<"(@@`]%@$2-Q0$``.*X +M!?(2AH#@`_(H=P/P`=_RI@"%XK@(\A*&@.`$\@#8$J8!WP"%Z+@'\@&%(880 +M<0/R`:8!WP"%Z;@(\@*%(H80<03R`J8!WP"%ZK@(\B(5@!`LCA!Q!/(,K@'? +M`(7NN`/R`X4(I@"%[[@+\D`F`!E`)0$7!MHB((`/",`H?@"%\+@$\@'8"Z8` +MA?&X`_(`V`NF`(7RN`?R!8:!X`/R`=_EI@"%\[@(\@6&@.`$\@#8!:8!WP"% +M]+@&\@2&@>`$\@'?Y*8`A?6X!_($AH#@!?(`V`2F`=\`A>NX%/)`)@`<0"40 +M%`IQ#-HB((`/",`H?D`F`!\*<0S:(B"`#PC`*'X`A>NX"O)`)@`?0"4!%`S: +M(B"`#PC`*'X`A>VX!?(C%8`0*AX"$`"%!""`CP#\```M\C6&@.$K]$$HD09` +M)A`6`M@*<0IR(B"`#PC`1)Y,(0"@`-C;]RIQ6G$Z<$`E`1D(82(@@`\(P+B> +M"'&SX,HB8@#*(`($XB""#PC`E*5"(D$@@.%`(4`@*/<`A>"X!?(!W_2F\Z83 +MAH#@S"/'`(B"`#PC`A`S/ +M=4:`3">I<"(@@`]%@+R-#(5/(`$`P;B`N(/@+*4-]`+8.AT"$`1M`]D`WLER +M(B"`#PC`-%W,I2`@@`\(P/0,X'CQP"(@@`\(P(0,SW%&@$PG*'6I<"(@@`]% +M@+R-#(%/($(`P;B!N(/@3*$%\A*!@N`.]`+8.AT"$`1I`]D`WLER(B"`#PC` +M-%W,I=*E(""`#PC`]`SQP"(@@`\(P(0,H\$(=L]U1H!,)ZEP3-DB((`/",!` +M?@1M+-DB((`/",!`?L]P18#PY$#`SW!%@.#D0<#/<$6`Z.1"P`#8!MD(V@AS +M"B2`#T6`_.)*)0`&2B9``$`E!Q$B((`/","46\"EJ7"CP"`@@`\(P/0,X'CQ +MP`ARSW-&@$PG:'`B((`/18"\C0"*@.``V$`BB]Y$'&\]@"#+8,B((`/ +M18#,]P1H!,)R`@@`]%@+R-X'CQP,]S1H!,)RVC:'`B((`/18"\ +MC5&C!&L`V2AR(B"`#PC`-%T`V-'`X'[@>/'`X<7/=4:`3">I<"(@@`]%@+R- +M0"4`'@S9(B"`#PC`0'X$;0+9`-HB((`/",`T72`@@`\(P/P,(""`#T6`P(WQ +MP.'%"''/=4:`3">I<"(@@`]%@+R-0"4`'@S:(B"`#PC`*'X$;039`-HB((`/ +M",`T72`@@`\(P/P,X'CQP,]R1H!,)TAP(B"`#T6`O(T`@BV"..(B((`/18"0 +MK-'`X'[QP,]Q1H!,)RAP(B"`#T6`O(T`@2(@@`]%@&"J4MD`VDAS(B"`#PC` +MX'/1P.!^X'CQP.'%SW5&@$PG`(4B((`/18!@JG&%4=F*(AT/(B"`#PC`X'.I +M<"(@@`]%@+R-(""`#PC`_`S@>/'`SW%&@$PG*'`B((`/18"\C01I!MD`VB(@ +M@`\(P#1=T<#@?@"`X'[QP.'%SW5&@)@G`*6I<"(@@`]%@$BH`:6I<"(@@`]% +M@)"3J7`B((`/18!DDZEP(""`#PC`_`S@>/'`(B"`#T6`!(`B((`/18"TJM'` +MX'[@>/'`(B"`#PC`>`RCP0AV*'4B((`/18#8C\]QB,!(%1IPBW`Z<`S:(B"` +M#PC`(`Z,(,.ORB%!`\H@@0\0``D0XB"!#PC`?!``)H$?````"12!$'4-]!6! +M@.`'\H+@'O*#X!KR`]@Z\`'8%:$`AJEQ(B"`#T6`1)X*)P"0$O*"Y\HAP@/* +M(((/$``7$.(@@@\(P'P0&O`"V!6A`-@@\,EP@"`&"PIQ(B"`#T6`C)H"V`(< +M`C!:(``M&6;88&6`#(&I<6![*G+)<"(@@`]%@&23Z7`B((`/18#XDZ/`(""` +M#PC`W`S@>/'`*'(B((`/18`$@`AS_]@B((`/18!`C6AP2'$B((`/18#`J]'` +MX'[QP"(@@`\(P'@,"'5`(!`#*'8`W_P`X0#8!?))AX#B-?3Z<(#A`-@)\BF'@.',)N&@S"8!E\CP?0!0!$(`@0"PIR(""`#PC`Y`S@>/'`X<4B((`/ +M18`$@!3:"'66(,0*(B"`#PC`*'X!V0`E@!\````).Z`\H*EP(B"`#T6`/*H@ +M((`/",#\#/'`X<7/=4:`$#&I<(HA!`\B((`/",!`?L]R18#XE54E0!\`V2AS +M2B1``;AQ(B"`#PC`:'Z`X,H@@@\0`"D0XB""#PC`I:(3ERB"&#Q``*A#B((8/",!P$,]Q1H`0,<]P1H#T +M,;5X@.7@H!?R@>4F\H+E#/*#Y27RSW`0`"L0R7$B((`/",!\$!#P*'#`V2(@ +M@`\(P$!^"/!6(0`&#-DB((`/",!`?@#8(B"`#T6`B)0`V"`@@`\(P.P,52'` +M#._Q5B'`!NWQ\<`B((`/","$#`AV*'63X,HAA@/*((8/$``O$.(@A@\(P'P0 +M6B8.$\]P1H`0,+/#/<$:`-#+(8$(@40`5)%(T6B8` +M$[]@`(=,$A`F@.`;\D@5`!8AAQ!Q%_>`X(/`5)(`S3!`-!H#E&?), +MW!HF`!.+<<]W1H"0,=5_`"$0`!F'@.#*(($/$``P$.(@@0\(P'`068>I<&!Z +M"G$!YH3FP@?%_P'8(B"`#T6`B)2`)`4Q(""`#PC`U`P@`@`````A`@`````B +M`@`````C`@`````D`@`````E`@``````````0(D(P````````````````+") +M",``````](@(P``````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````/__``````8#```````# +M``,`````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`#!3",``````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!@$@C` +M`0```&@2",`!````;%8(P`````"L5@C``````#16",``````:!((P`$```!4 +M50C``````&`2",`!````]$\(P`````!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```/A4",`!````V%8( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$````,4`C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!43PC````` +M`(1/",``````:!((P`$```"T3PC``0```&@2",`!````6%4(P`````!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```"\3PC``````&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```/A*",``````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````O!$(P`````!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````!;`0```0```$33N:$-&_>WK(@F2HVQN?&6*FYFCN'[K,6NA:VN1N[6T([:05*G@))1.*9)JI\0*8VUH15!M/]Y!H +M>GM6"Q=OV\,O-;TG%N_37H"#%F\/SK'K7*_5'BQ-Z">GA"$?JS'-,[V6WT`, +MDUHZ"R@-10ZOZ/Q?OP`'!.3E29G=MCOU=#K*EC1ZA];*2-P\8N4`RN]>A?B( +M[N8``2@:XKO1L^2P;EZ=.^UCVOGYF@\D1/V\17MS)_)MBCMA<(_(]IW#NB"* +MDW'NC3(TEK*",%-%'Z%K5'S1`0`!`&MU+^&3Y!/5FZE^8[;E+Z'F@W,AL>#Y +M\1%B`NFM?SNB$@?.'7KOC8=LNL&6VB.`U0)_:G&;EH=S2"5+A.\ENCA&41*P +M,G\,OG8Y6^'RKG`2L?G:C;C!C-CU5O'$5\=FT^UE5@\&I=PLZC3-QS>J +M=*/<),$@E`9KTO%99=-L5D?M@8@[JG;V;B7&HM$HJ$OX&&L`UWM+>S#9<)DL +M?B%:YV6)CL!7?*?JL`NFQ>3$D6V^SD-VXY7Q1;V_.S,0"^:1%`_CPJ$HG'VD +M,A;9NJ=.!(&I'.7S1N,W*!Q&A+U-EX=,LT%1+QM.CRY052[>;K`($OZ`(Y3A +MIJ:E^\@GRL4!````!P````@0```````!`!```!,````$$````````?[*_LKO +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X4```` +MS`(```!`0``&````H0```````0``````AH````,'%B"$SP$`0````$`````! +M````!(0%```````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`-5WT;Q*[8W)8R5H$YN``GD<`1;"8;0$8!Y-.YH0T;][>LB"9*C;&Y\98J;F +M:.X?NLQ:Z%K9SB&G8]O!A-G')N_JA`DE$XID +MFJGQ`IC;6A%4&T_WD&AZ>U8+%V_;PR\UO2<6[]->@(,6;P_.L>M+$WH +M)Z>$(1^K,W,G +M\FV*.V%PC\CVG<.Z((J3<>Z-,C26LH(P4T4?H6M4?-$!``$`WLU?3M!9+;2H +M4HM5MF@,U*K@8.ZZNF +MYPY/K"DT^DAJ)C/C+%0$;]B;X7,P!/8?<5^[.I41D`.J9)!F$0ZWCM!["X8* +M"7]D?.G/Y=ZB83X3YQ/NU6ZF&9REX!!/DV7BR$V!"H];T'@&EAE0%U2`7\_]C*EQ +MP#A-!683^UV8!D7"Z>*W0#5/'\C>M@0````'````"(`!````@```@`$`!P`` +M``@`!0`````````%``<```#\40```(!$`/11```'````7&D`````00!4:0`` +M%`````2``0```(```````!8````$A`4```D```````#\%X$`%!*```PO@0#( +M*X$`Q`V``(!P@0````````````````````````````````!L(,`0#QL)(MP= +MP!`*`!M`(``;;@P``&&``!MN&P``80`!&VX<``!A``(;;AT``&$`!!MN.``` +M81``&VX!``!A.@``834``&$``!LD(``;)>0=P!%$!\`2`0`;<`H``&$/'!TB +M!``=)E0'P!(!&R,BZ!W`$`$`(W`!``!A$0`;,`$`&S#H'<`1WP\`80``&R2` +M`!LEY!W`$0``&R0``1LEY!W`$0``&R0``ALEY!W`$0@`7W`,``!A[!_`$/__ +M&S/L'\`1SNX-)8*9#20/#3@=P!!X^`$D_\`!)0`!$SD/$P$B3`?`$@`!$SCH +M'<`1`0!2)'A%P!`!`!-P"0``80@`6##8'L`0"@`30`(`$VX!``!A`0``80"` +M6#`(`&0Q````80@`6&[F#P!A```3)0``$R0D$,`1`(`3)```$R4X',`1H`G` +M$@$`$W`%``!A```3)0``$R0``"$E```A)!(``&$``!,E`P`3)```(242`"$D +M#T0`(@H``$```0!P!```8?[_$S("`#!P^/\A,OK_(3(``@!P!```8?W_$S(" +M`#!PQ_\A,M?_(3(H`,T1#R$3(BP`S1&`"<`2!`#-$80)P!((`,T1B`G`$@`` +MS1&0"<`2\![-$90)P!(P*$7`$`$`$W`"``!A"`!D,>,/`&&< +M"<`2`0`3;F<``&'.[@TE`8`-)`\--R(/7#!N!@0``P!8&`1-B!`C`$`0` +M$V0/7``B"@``0``&`'`:``!A```3)```$R4``,`7(`!8,<@@P!!P1<`0$`C` +M$```$R4#`!,D'`C`$1P(P!$``!,D!`C`$0\4%2($`!4F#S`@(OO_,#(#`!,D +M&`C`$0\4%2("`!4F#R`P(@``$R001<`1&`C`$1``6#$``!,E`P`3)```(24_ +M`"$D#TP`(@H``$`!``!P!```8?[_$S("`#!P^/\A,OK_(3("``!P!```8?W_ +M$S("`#!PQ_\A,M?_(3(H`,T1#R$3(BP`S1$``!,E```3)`P`S1&,"<`2``#- +M$0]-$R($$,41`@`3)/`[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X````````````````(```````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````#,P```1$```````````````"B@````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````1`"``````````````````$!`0$!`0$!`0$!`0$!`+2XO+C`P,#`Q,3(R +M,C,S-#0T-34V-C8W-S@X.#DZ.CL\/#T^/C\_/S\_/S\_/T!`0$!`,3(R,S,S +M,S,S-#0T-#0U-34U-C8W-S`P``QP(``*P!``".```````````````#``````#_ +M`_P_````P`````$````!```````````````!`````0````$````````````` +M``$``#06@0`>``'\]@```0`$``#0!X$`!``!M"R!``P``0``W!*!``$``]@2 +M@0`!``/$#8```0`!P!6!``$``\05@0`!``/`]@```@`$```@````(``````` +M`````````````&2!`0`%```"!````)0:@0`#`````````$YB$`#A@0$`3F(0 +M````````````````````````````V0#8``$`)`"`!Q`*`0$"`1T`@0J""J$( +M,0N\!TP*```````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````"`"`````"$"```` +M`"("`````","`````"0"`````"4"``````8````````````````````!```` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````_____________________P0` +M``#_______________\#````_____P``````````_____P``````````____ +M_P```````````P```!`````#````_P```/\```#_````_P````,````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````&@/\` +M``````````0!`@(````',%1XG:4``)`.!0`````````````````````````` +M``````````````````````````````````````````````````````"\-P`` +M4#<``$PW``"H-P``8$,!`+!#`0"40P$`V$(!`!!#`0"D0@$`G$,!```````` +M``````````````",\@``"@````0```"4&H$``````````````"`````````` +M```````````````````````````````````````````````````````````` +M````````````````````!````````````````````````````$#S```%```` +M!````)0:@0#<+(``9T4C`04````"`@("`@("`@("`@("`@("`@("`@("`@(" +M`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(" +M`@("`@("`@("`@("`@(!`@("`@("`@$!`@("`@("`@("`@("`@("`@("`@(" +M`O\````0`@``````````````````````````````````9#"!```````!```` +M````````````````````````````````````````````````"0`````````` +M```````````````````````````````````````````````````````````` +M````````````````````````____________________________________ +M______\```````````````````````````````!1T`_2"](!T`;2!](=TA72 +M#-(5T1/1$M$0TA'2%-$-TA#1$=$(T@G2"1$1$0[2`.``RA+2$])0T`1#`41P +MT@_0!M`````````````````````````````````````````````````````` +M`````````````````````````````$@Q```%````!````)0:@0`X,0``0#$` +M`/`Q```\,0``1#$````````````````````````````````````````````` +M`````&CJ`0`%````!````)0:@0````````````````#,&P````#(&P````!` +M'`````!,'`````!0'`````!4'`````!8'`````!<'`````!@'`````!D'``` +M``!P'``````('`````!H'`````!L'`````!$'`````!('``````0'``````` +M'`````"8'@````"<'@````"D'@````"H'@````#`'@````"X'@````"\'@`` +M````'0`````@'0````!`'0````!@'0````"`'0````"@'0````#`'0````#@ +M'0`````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````!`>`$`G`,!``2!`0"<`P$`)`T"`)P#`0!L +M[```F.T!`&P5`0"<`P$`G`,!`##P`0`P\`$`,/`!`##P`0`P\`$`,/`!`##P +M`0"<`P$`G`,!`)P#`0"<`P$`2'$``)P#`0"<`P$`;!4!`)P#`0"<`P$`:!4! +M`%`5`0"<`P$`G`,!```!`````0```````````````0````$````!```````` +M```````!`````````0````````````````````$````!````!R@P.DA06&!H +M<'B`B)"9FZ&E```````````````````````````````````````````````` +M``````````````````````````````````````````````$````"`````P`` +M``````#_````_P```/\```#_`````````.&^K=X```````````````!T'`$` +M!@````0```"4&H$`````````````````E!D!``4```($````E!J!`/\``0,$ +M!08'"`(``````````````````!A&`````"!&`````"1&`````(!&`````(1& +M`````(A&`````(Q&`````)!&`````)1&`````)A&`````)Q&`````*!&```` +M`,!&`````,1&`````,A&`````,Q&`````-!&`````-1&`````-A&`````-Q& +M`````.!&`````.1&`````.A&`````.Q&`````/!&`````/1&`````/A&```` +M`/Q&`````!1&``````!'``````1'``````A'``````Q'`````$!'`````$1' +M`````'Q'`````(!'`````(1'`````(A'`````)!'`````)1'`````)A'```` +M`*!'`````*1'`````*A'`````*1&``````1&``````A&``````Q&`````!!& +M``````!&`````#,``````&`<`````&0<`````&@<`````&P<`````'`<```` +M`'0<`````'@<`````(`<`````(@<`````(P<`````)`<`````)0<`````)@< +M`````)P<`````*`<`````*0<`````*@<`````*P<`````+`<`````+0<```` +M`+@<`````+P<`````,`<`````,0<`````,@<`````,P<`````-`<`````-0< +M`````-@<`````-P<`````*@=`````+@=`````+P=`````,`=`````,0=```` +M`,@=`````,P=`````-`=`````-0=`````-@=`````-P=`````.`=`````.0= +M`````.@=`````.P=`````/`=`````/0=`````/@=`````/P=`````&0?```` +M`.P?`````'0>`````$0?`````(`?`````(0?`````(@?`````(P?`````)`? +M`````)0?`````)@?`````)P?`````*`?`````*0?`````*@?`````*P?```` +M`+`?`````.0?`````/`?`````/0?`````/P?`````$8````````````````` +M````````X!P`````Y!P`````Z!P`````]!P`````^!P`````#!T`````&!T` +M````+!T`````,!T`````G!T`````H!T`````,!X`````-!X`````.!X````` +M/!X`````3!X`````4!X`````5!X`````6!X`````7!X`````9!X`````>!X` +M````?!X`````A!X`````C!X`````D!X`````E!X`````F!X`````G!X````` +MH!X`````P!X`````Q!X`````T!X`````U!X``````!\`````X!X`````!!\` +M````W!X`````=!\`````>!\`````?!\`````^!\`````*@```/____\````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````"````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````#_____```````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M@``````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````_____P`````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````(`````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````/____\````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````"````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````#_____```````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````@``````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````/\````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````Y"2!``PC@0#D)($`Y"2! +M`.0D@0"<)($`Y"2!`)PD@0#D)($`Y"2!`/____\`````_____P````#_____ +M`````/____\```````````\`/P`!````#P`_``$````/`#\``0````\`/P`! +M````#P`_``$`````````#P`_``$````/`#\``0````\`/P`!````#P`_``$` +M```/`#\``0`````````/`#\``0````\`/P`!````#P`_``$````/`#\``0`` +M``\`/P`!``````````\`/P`!````#P`_``$````/`#\``0````\`/P`!```` +M#P`_``$`````````#P`_``$````/`#\``0````\`/P`!````#P`_``$````/ +M`#\``0```*L````````````````````````````````````````````````` +M````````````````````````````````````````````````````````=#@` +M``4````$````E!J!````````!0``!`D$"0$&"0P1`0`````````````````` +M`````````````````````````````````!P`````!!P`````"!P`````#!P` +M````*!P`````2!P`````3!P`````4!P`````4!P`````?!P`````*#@````` +M`$P`````!$P`````"$P`````#$P`````($P`````)$P`````*$P`````0$P` +M````1$P`````8$P`````@$P`````H$P`````P$P`````Q$P`````R$P````` +MS$P`````X$P``````$T`````8$T``````"0`````S"8`````W"8`````Q"8` +M````("0`````-"0`````F"4`````G"4`````H"4`````I"4`````J"4````` +MK"4`````Q"4`````R"4`````U"4`````V"4`````W"4`````X"4`````Y"4` +M````Z"4`````["4`````\"4`````!"<`````&!``````+!``````0!`````` +M3!``````C`T`````E`T`````G`T`````P$0`````Q$0`````R$0`````S$0` +M````T$0`````U$0`````V$0`````X$0`````Y$0`````Z$0`````[$0````` +M^$0`````_$0``````$4`````)$4`````*$4`````+$4`````1$4`````8`@` +M````"`T`````$`T`````%`T```````T`````!`T`````B#``````50`````` +M````````````````_____________________P`````7T0``&-$``!G1```: +MT0``&]$``!S1```````````````````````````````````````````````` +M````````!`0````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````Q!8"```````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````/__________```````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````$P(H`!("*``/`B````````` +M``$"``````8.0F.&H+4`N`"X`)0`D`"X`,``P`"<`)P`P`#;`(Y;```````` +M`````#,```````$```#B!````````$L#2P-+`TL#2P-+`TL#2P-+`TL#2P-+ +M`TL#```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````*"@H*"@H*"@H*"@H*``H*"@H*"@H*"@H*"@H`"@H*"@H +M*"@H*``H*"@H*"@H*"@`````````````````````````*"@H*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*``H*"@H*"@H*"@H*"@H*"@H*"@` +M```````````````````````````````````````````````H*"@H&"@H*"@` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```H*"@H*"@H*"@H*"@H*```````````````````````````*"@H*"@H*"@H +M````````````````````````````````````````````````````*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*``````````````````` +M```````H*"@H*"@H*"@H*"@H*"@H*"@`````````````*"@H*"@H*"@H`"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@`*"@H*"@H*"@H +M`"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@`*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H```````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````!65```.`````````!:9```/@````````!JI```/@`````` +M``!:I```/@````````!:I```/@````````!:9```/@````````!:5```/@`` +M``````!:I```/@````````!:9```/@`````````*(```/@````````!:9``` +M/@````````!:9```/@````````!:5```/@````````!:9````P````````!: +MI````P`````````*````,0`````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````#`P``````````````$` +M`````````0```#\0``````````````````````````````4`!0`````````` +M``````0(``$```4$`0`!!``$!0`````!``$``````!K0```3@```"$`$``$`!``:,````&`$``!@!```8`0``&`$`*A0``"A( +M```F>```!K0```3@```"$`$``$`!``:(````&`$`"E0(``B$```&M```!.`` +M``(0`0``0`$``!@!```8`0``&`$``!@!```8`0!C`````(`$`,8```#&&`<` +M0$`5`&,!``#&`0``"C0```AH```&N```!.0```(4`0``0`$`!H@````8`0`` +M&`$``!@!```8`0``&`$`"C0```AH```&N```!.0```(4`0``0`$`!H@````8 +M`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@! +M```8`0!"`````````*4```"EE`(`0$`5`$(```"E````"CP```AL```&P``` +M!/0```(D`0``4`$``8`!``%,`0`$P````!@!```8`0``&`$`"CP```AL```& +MP```!/0```(D`0``4`$``8`!``%,`0`$P````!@!```8`0``&`$``!@!```8 +M`0``&`$``!@!```8`0``&`$``!@!```8`0`"``````````8````&&```0$`5 +M``(````&````&@```!@8```62```%'@``!*P```&X```!!@!``),`0``@`$` +M`!@!```8`0``&`$`&@```!@8```62```%'@``!*P```&X```!!@!``),`0`` +M@`$`"'````:L```$V````@@!```X`0``&`$``!@!```8`0``&`$``!@!```8 +M`0"$``````````@!```((00`0$`5`(0````(`0``&@@``!@T```69```%)0` +M`!+$```&"`$`!#@!``)D`0``E`$``!@!```8`0``&`$`&@@``!@T```69``` +M%)0``!+$```&"`$`!#@!``)D`0``E`$``!@!```8`0``&`$``!@!```8`0`` +M&`$``!@!```8`0``&`$``!@!```8`0"$``````````@!```((00`0$`5`(0` +M```(`0`````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````!````(`````,```#I`.D`````#P\/ +M#P\/#P\/#P\/#P\/#P\,"08#``````````````````````````#[^_O[^_O[ +M^_O[^_O]``,'"0P/%!89'B,F*2XY14U-34U-34U-30`````````````````` +M````````````````#/[__P$```#2V```TM@``"YG__\N9___$````-+8``#2 +MV```+F?__RYG__\0````TM@``-+8```N9___+F?__Q````#2V```TM@``"YG +M__\N9___$````-+8``#2V```+F?__RYG__\0````TM@``-+8```N9___+F?_ +M_Q````#2V```TM@``"YG__\N9___$````-+8``#2V```+F?__RYG__\0```` +MTM@``-+8```N9___+F?__Q````#2V```TM@``"YG__\N9___$````-+8``#2 +MV```+F?__RYG__\0````TM@``-+8```N9___+F?__Q`````````````````` +M````````````````````````````````````````F@````$``````.0,```` +M```````!``0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8%.@:`!LD&%@=D![4' +M!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK"R(,6`R*#+4,U0P$ +M``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI"/D( +M1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``$``8$'@0[ +M!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI"/D(1PF3"=P) +M(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``&!!X$.P1=!(,$K03: +M!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8"LT* +M_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#`@`!``&!!X$.P1=!(,$K03:!`L%/P5X +M!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8"LT*_0HL"UH+ +MB`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8%.@:` +M!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK"R(, +M6`R*#+4,U0P.``0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8%.@:`!LD&%@=D +M![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK"R(,6`R*#+4, +MU0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI +M"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,)``$``8$ +M'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI"/D(1PF3 +M"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``&!!X$.P1=!(,$ +MK03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8 +M"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5##@`!``&!!X$.P1=!(,$K03:!`L% +M/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8"LT*_0HL +M"UH+B`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8% +M.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK +M"R(,6`R*#+4,U0Q```0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8%.@:`!LD& +M%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK"R(,6`R* +M#+4,U0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8( +M6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,3``$ +M``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI"/D( +M1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``&!!X$.P1= +M!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`* +M7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#%8`!``&!!X$.P1=!(,$K03: +M!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8"LT* +M_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$V@0+!3\%>`6U +M!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+ +MN`OK"R(,6`R*#+4,U0Q@``0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8%.@:` +M!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK"R(, +M6`R*#+4,U0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U +M!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4, +M:@`$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8(6`BI +M"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``&!!X$ +M.P1=!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG< +M"2`*7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#'0`!``&!!X$.P1=!(,$ +MK03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`*7PJ8 +M"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$V@0+!3\% +M>`6U!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M: +M"X@+N`OK"R(,6`R*#+4,U0Q^``0`!@0>!#L$702#!*T$V@0+!3\%>`6U!?8% +M.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+N`OK +M"R(,6`R*#+4,U0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8' +M9`>U!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU +M#-4,B``$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U!P8( +M6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4,!``& +M!!X$.P1=!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<) +MDPG<"2`*7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#)(`!``&!!X$.P1= +M!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG<"2`* +M7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$V@0+ +M!3\%>`6U!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT* +M+`M:"X@+N`OK"R(,6`R*#+4,U0R<``0`!@0>!#L$702#!*T$V@0+!3\%>`6U +M!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M:"X@+ +MN`OK"R(,6`R*#+4,U0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;) +M!A8'9`>U!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@, +MB@RU#-4,I0`$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8'9`>U +M!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU#-4, +M!``&!!X$.P1=!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY +M"$<)DPG<"2`*7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#*L`!``&!!X$ +M.P1=!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@(J0CY"$<)DPG< +M"2`*7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#`0`!@0>!#L$702#!*T$ +MV@0+!3\%>`6U!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K- +M"OT*+`M:"X@+N`OK"R(,6`R*#+4,U0RP``0`!@0>!#L$702#!*T$V@0+!3\% +M>`6U!?8%.@:`!LD&%@=D![4'!@A8"*D(^0A'"9,)W`D@"E\*F`K-"OT*+`M: +M"X@+N`OK"R(,6`R*#+4,U0P$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H& +M@`;)!A8'9`>U!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB +M#%@,B@RU#-4,M0`$``8$'@0[!%T$@P2M!-H$"P4_!7@%M07V!3H&@`;)!A8' +M9`>U!P8(6`BI"/D(1PF3"=P)(`I?"I@*S0K]"BP+6@N("[@+ZPLB#%@,B@RU +M#-4,!``&!!X$.P1=!(,$K03:!`L%/P5X!;4%]@4Z!H`&R086!V0'M0<&"%@( +MJ0CY"$<)DPG<"2`*7PJ8"LT*_0HL"UH+B`NX"^L+(@Q8#(H,M0S5#``````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````/]__W__ +M?_]__W\````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````4%!04("PL,#2$$A45%14E+2TQ-842 +M%!04%!PD)"PTA!(5%145'24M-3F%$A45%14E)2TU/842$A(2$AHB(BHJ@A(: +M&AH:(BHN-CZ*`!H:&AHJ,C(Z0HH`&AH:(BHR.D)RB@`='1T=)2TQ.46-`!T= +M'1TM-3D]28T`'1T='2TU/4%9C0`;&QL;)R\W/T>+`!D9&2$I,3D]38D`&AH: +M(BHZ0D9FB@`7%Q<7)S,W/T^'`!45%1TE-3U!384`#P\/%Q\G,SMC?P`0$!`0 +M("0H,#R```\/#Q+`!D9&2$I,3D] +M38D`&AH:(BHZ0D9FB@`7%Q<7)S,W/T^'`!45%1TE-3U!384`#P\/%Q\G,SMC +M?P`0$!`0("0H,#R```\/#Q+`!D9&2$I,3D]38D`&AH:(BHZ0D9FB@`7%Q<7)S,W/T^'`!45 +M%1TE-3U!384`#P\/%Q\G,SMC?P`0$!`0("0H,#R```\/#Q#"!,3$Q,C*R\S/X,(%!04%!PD)"PTA`@3$Q,3 +M&R,K*S.#"!(2$A(B(BHN,H(($!`0$!@@*"@P@`@8&!@8*"@P-$"(`!<7%Q\G +M,S#"!,3$Q,C*R\S/X,(%!04%!PD)"PT +MA`@3$Q,3&R,K*S.#"!(2$A(B(BHN,H(($!`0$!@@*"@P@`@8&!@8*"@P-$"( +M`!<7%Q\G,SV``3$Q,3'RLO,S>#"!,3 +M$Q,C*R\S/X,(%!04%!PD)"PTA`@3$Q,3&R,K*S.#"!(2$A(B(BHN,H(($!`0 +M$!@@*"@P@`@8&!@8*"@P-$"(`!<7%Q\G,S`"@H*"@R/$1, +M5&``*"@H*#`X0$948``H*"@H,#A`1E1@`!`0$!`4("@H,#`-$!`0$!0@*"@P +M.`TH*"@H+CA"2$Y8`"@H*"@R/$1,4EX`*"@H*#(\1$Q48``H*"@H,#A`1E1@ +M`"@H*"@P.$!&5&``_W__?_]__W__?_]__W__?_]__W\````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````#H`>@!N`6X!8@) +MB`E8#5@-*!$H$?@4^!3(&,@8F!R8'&@@:"`X)#@D""@(*-@KV"NH+Z@O>#-X +M,T@W2#<8.Q@[Z#[H/KA"N$*(1HA&6$I82BA.*$[X4?A1R%7(59A9F%EH76A= +M.&$X80AE"&78:-AHJ&RH;'AP>'!(=$AT&'@8>.A[Z'NX?[A_B(.(@UB'6(.)X(H@BBV*78I:BIJ*EXK7BM2+%(L1BU +M&+7HN.BXN+RXO(C`B,!8Q%C$*,@HR/C+^,O(S\C/F-.8TVC7:-.IXZDCN2.X8\ACRZ/7H];CYN/F(_8C]_O_^__[__O_^__[_ +M_O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^ +M__[__O_^__[__O^@NPT`X"("```````````!``$````!``$````!``$````! +M``$````!``$````!``$````!`````0````$````!`````0````$````!``$` +M```!``$````!``$````!``$````!``$````!``$````!`````0````$````! +M`````0````$````!``$````!``$````!``$````!``$````!``$````!``$` +M```!`````0````$````!`````0````$````!``$````!``$````!``$````! +M``$````!``$````!``$````!`````0````$````!`````0````$````!``$` +M```!``$````!``$````!``$````!``$````!``$````!`````0````$````! +M`````0````$````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````'=W`P,-#08&`P,-#08& +M`P,-#08&`P,-#08&`P,-#08&`P,-#0`````````````````````````````` +M```````/__\`$"<````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````F%D0!)@9BJ(````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````0`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````#P`/``\`#P`/``\`#P`/```````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````)A9$`28&8JB +M`0``````````````(``````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````$``0``````P`"0`-`````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````K"T`````L"T` +M````#"T`````$"T`````%"T`````&"T`````'"T`````("T`````)"T````` +M*"T`````+"T`````,"T`````-"T`````."T`````/"T`````0"T`````1"T` +M````2"T`````3"T`````4"T`````5"T`````6"T`````A"\`````B"\````` +MC"\`````D"\`````E"\`````F"\`````G"\`````H"\`````I"\`````J"\` +M````K"\`````L"\`````7"T`````""T``````"P`````""P`````I"T````` +M1"X`````2"X`````M"\`````5"X`````Z"P`````&"P`````'"P`````("P` +M````)"P`````*"P`````+"P`````,"P`````-"P`````."P`````/"P````` +M0"P`````1"P`````2"P`````3"P`````4"P`````5"P`````6"P`````7"P` +M````8"P`````9"P`````A"X`````B"X`````C"X`````D"X`````E"X````` +MF"X`````G"X`````H"X`````I"X`````J"X`````K"X`````L"X`````M"X` +M````N"X`````O"X`````P"X`````Q"X`````R"X`````S"X`````T"X````` +MU"X`````V"X`````W"X`````X"X`````Y"X`````Z"X`````["X`````\"X` +M````]"X`````^"X`````_"X``````"\`````!"\`````""\`````#"\````` +M$"\`````%"\`````&"\`````'"\`````("\`````)"\`````*"\`````+"\` +M````,"\``````"X`````!"X`````""X`````#"X`````$"X`````%"X````` +M&"X`````'"X`````("X`````)"X`````*"X`````+"X`````,"X`````-"X` +M````."X`````/"X`````J"T`````$"P``````````````````````````)0- +M@0!@48$`&`````````````````````````#^RJVK```````````````````` +M```````````````````````````````````````````````````````````` +M``````````!`0@\`!`````$```````````!```"`0````$$``(!!``"`0@`` +M@$,``(!$``"`10#_?T8``P````P````P````P``````#````#````#````#` +M````$````-````"P````@`````````!@`@````$````!``"``0``@````"`` +M``"``````````.`!`````0````$``!````"`````8````(```````@``$`$` +M```!`````0``@`$``%`````@````0````+`!``"@``````$````!`````0`` +M4````"````"`````\`$``*```````0````$`@````````````````````(`` +M``"`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("` +M@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("` +M@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@``"```` +M````````````````````````````@```````_P```````````@`````````` +M`````````````````````(```````/\```````````(````````````````` +M``````````````"```````#_```````````"```````````````````````` +M````````@```````_P```````````@`````````````````````````````` +M`(```````/\```````````(```````````````````````````````"````` +M``#_```````````"````````````````````````````````@```````_P`` +M`````````@```````````````````````````````(```````/\````````` +M``(```````````````````````````````"```````#_```````````"```` +M````````````````````````````@```````_P```````````@`````````` +M`````````````````````(```````/\```````````(````````````````` +M``````````````"```````#_```````````"```````````````````````` +M````````@```````_P```````````@`````````````````````````````` +M`(```````/\```````````(```````````````````````````````"````` +M``#_```````````"````````````````````````````````@```````_P`` +M````````````````@0````````""`````````(,`````````A`````````"% +M`````````(8`````````AP````````"(`````````(D`````````B@`````` +M``"+`````````(P`````````C0````````".`````````(\`````````P``` +M```````````````````````````````````````````````````````````` +M```````````````````````!```````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````&.8!``4` +M```$````E!J!`````````````````````````````````/\```#_```````` +M`/0!!P#H`P````````$``````````````/\```#_````_P```/\```#_```` +M_P```/\```#_````_P```/\```#_````_P```/\```#_````_P```/\```#_ +M````_P```/\```#_````_P```/\```#_````_P```/\```#_````_P```/\` +M``#_````_P```/\````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````8(*``'""@`"@@H``L(*``.""@`"`@H``D +M(*``,""@`#0@H``\(*``0"&@`$0AH`!H(:``;"&@`'@AH`!((:``3"&@`'`A +MH`!T(:``?"&@`````````````````)SJ`0`%```"!````)0:@0`````````` +M``````#`3@``!0```@0```"4&H$`````````````````V$%"@X,0````("!`0&!@8&!@8&"@```#PX-#`L*"0@'!@4$`P(!``` +M`@@.$Q4:'P`#"A$8&B`F2D\`'G=\```$!04$`@(````**7Q\,3M\?'Q\?&Q\ +M4%AI375B17Q\?'Q\.T4[%GQRJJJJJJJJJ +MJJJJJNZJJJJJ*/\`S*JJ``"JJ@#,JJH```!``,``0`#``%``\`!0`/`````` +M``````````````````````````````````````````````````````````"J +MJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ@`````````````````` +M````;&UN;W!Q(`^0#*`>H`@@"9 +M``$##P<*%#=N:@$:`=D`Z`!J`;H`>0"(`'3111?HHHLN```````````````! +M`@,$!`0$!04%!04%!04%!04%!@8&!@8&!@8&!@8&!P<'!P@)"0D)`-B^``!X +MJ```>*4``-RM``!$O```!*@``-B_``#4JP``7*T``&BI``"0JP``4*L``"2O +M``!4P```9`L!`&0+`0!D"P$`$````&0+`0!D"P$`9`L!`&0+`0!D"P$`9`L! +M`&0+`0","P$`D`L!`&@+`0!D"P$`9`L!`&0+`0!D"P$`9`L!`&0+`0!D"P$` +M!````!`@,$"`"`0$$"`P0%!@<(`!`04!`P$!`0@!`@$(``@``0$#`0$!`P`# +M`0(!!0$!`00```"8):``G"6@`*@EH`"L):``H"6@`*0EH`#$):``R"6@`-0E +MH`#8):``W"6@`.`EH`#D):``Z"6@`.PEH`#P):``1`79AD0%V8:"`^991`79 +MAH(#YEGSPR)E@@/F6<*0`F`#D`)@` +MW`+<`FX!W`)N`>@!;@'T`&X!]`"R!;(%V0*R!=D"S`/9`N8!V0+F`40!1`'F +M`40!Y@&P`>8!'`+F`1P"B`*(`LP#B`+,`V`#S`,X!,P#.`3,`\P#L@7,`[(% +M$`6R!50&L@54!@8&$@82#!(>$AX``#0`:`!H`-``T``X`3@!.`&@`:`!;`#8 +M`-@`L`&P`8@"B`*(`F`#8`/J`-0!U`&H`Z@#?`5\!7P%4`=0!^H`J`.H`U`' +M4`?X"O@*^`J@#J`.``$"`0,&````````#P`_``$````/`#\``0````\`/P`! +M````#P`_``$````/`#\``0````(````"````!@````8````%````!0````0` +M```$`````0`````````````````````$"`00$```*``H`#``+``L`"@`/``T +M`"P`+``\`#0`,``L`%0`1`!__P0GMH+Z$]FA\6*;27T!XX +MCN,X',=Q'+V$]A*.XS@.',=Q'([C.`Y>0GL)QW$8!'`*(`M`"=0#J`%\!U`&^`J@#'022!'P%&`;J`-0!O@*H`WP%4`<*D@&K +M`D<#$P4((```$!````$```"<20$``````$"B```8````!)(``!X```"@A@`` +M'````&R+```9````()L``!H```"DG0``!P```(23```&````((4```0````X +ME0```P```"".```3````%(@``!(```!@@P```````'2C``!\A@``%*(``#"$ +M``#X@@``T)P``.R=``#0A```%(T`````````````W(\```[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````#OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>%`````0`!0`` +M````(""`#P``0``@((`/`0`$2B`@@`\!`"@4(""`#P``V`5I(```:2!``&D@ +M``!I($``(""`#P$`L$YI(```:2!``&D@``!*(```2B$``$HB``!*(P``2B0` +M`$HE``!*)@``2B<``$H@`!!*(0`02B(`$$HC`!!*)``02B4`$$HF`!!*)P`0 +M2B``($HA`"!*(@`@2B,`($HD`"!*)0`@2B8`($HG`"!*(``P2B$`,$HF`#`* +M)(`_@0``<$$LG#!`+)PP0B0<-`HB@#^!`%PL"B,`-R(+``I*)@!P:2!``$HF +M`'!*)@!P2B8`<$HF`'#OOJW>[[ZMWN^^K=[OOJW>[[ZMWOP.!^X'@$W#C=./#@>`3<--TV\.!X!-PPW33PX'@$W"S=,O#@>`3<*-TP +M\.!X!-PDW2[PX'@$W"#=+/#@>`3<'-TJ\.!X!-P8W2CPX'@$W!3=)O#@>`3< +M$-TD\.!X!-P,W2+PX'@$W`C='_#@>`3/P'#X<+AP>'`!\`<',`QX<#@?P'`"B8`\(H@OP_* +M(&0`X'\O(`,`X'^*(/\/'0`@`$H@`!!!*`AT`-@%*GX`+W$%*CX#`"!`C@$AP0X%*SX#X'\G +M<>!X4R)"@>!\3B(#B!8`#``!*,P``"F!```H@`#@?X5Y3B,#```HP0#@?P)X +MX'A3(D*!X'Q.(@.(%@`,```IS``"*8$``2B``.!_A7A.(P,``BG``.!_0BG! +M!U,B0H'@?$XB`X@6``P``"G,``$I@0`!*(``X'^%>$XC`P`!*<``X'\B>>!X +MX'C@>`HD@/`%($0`X"#!!T0D_H!!*L0`A``"`"\D`O%"(0$!0B`#`>@@H@0$ +M$00"!!$%`@01!@($$0<"!!L(`00;2`$$&X@!!!O(`2P`)0!$(CZ!/``B`$0B +M_(!`(<$`X"#!!T`CPP"H((`!`1&$`@$;"@$@(,`'!!$$`@01!0($&P@!U`?A +M_P0;2`%$(OR`!!$$`LD'[_\$&P@!0B%!`$(@0P"H((`!`1&$`@$;"@$@(,`' +M2B)`$\D%8`-*(\`12B)`%;T%8`-*(T`2X<4(=1'PX'C@>.!XX'C@>.!XX'C@ +M>.!XX'C@>.!XX'C@>.!XX'B`Y6&][_7@>.!XX'C@>.!_P<4`V<]P@0!L'B"@ +M`]G/<(``9`S@?R"@X'CAQ/P'"X``/@4"8<6$@XV!+CX8"*@"!4!E@0A@H_/5";A0*<:\@\)W@4O +M*8$/@`````CP#0E>`6\I`0@$\"\I@0`AH,]P@``@%?`@0`!`>(X/``,%\(HA +M_P\AH/()0`/<'8`?`P!`#1N%28/'`,V@U +M><]R@0"2#S%B^!Q(L$'`BW`(V:8)H`Z>VJ+`T<#@?O'`#@KO_PASSW:!`&P> +M`(;/=8``F!&3Z(X-8`AH<"^-#>@!V`"FSW"``&0,8*`K"5X`SW"@_F`!"_`/ +MC1L(7@#/<(``9`Q@@,]PH/Z,`0'9V@Q@!VAR*0+/_^!XX,F5N.`:&+#AR9NX +MX1H8L./)BKB-N)"XX'_C&ABPX'@5`F`"`-G@>"AR#0)@`@'9*'1("<__"'4A@`"`(:``H0#8 +M`*4$'8`?K=X"``:%0"`.!R"�U!$/H,(`\"V0"F!H5`(`X(((8-#4$0Y@P@ +M#PC9`*:)`<__\<`*"<__&G``W:EV.G4E\/)N]'_'=X``M`\)AXP@_X\:\@J' +MJW@)\L]P``!%,&(/[_\`$`$@*X<*AP5]$PE.(,]P``!&,$H/[_\`$`$@*X:]#A21%0'/_^!XSW%$`,B[A>@`V`BA&?#/<$0`Z+F6@%6`<8"%[`L* +MQ0`)\`T+A0`#V`BA"_`0@`T*!0`"V`BA!?`(@?L(E(#/`%N`@E@"0#9$H4S")``5PC1``3:SW"M``"J4*#/<:T``$1) +MH0+:SW"M``"$2:`@&8`/````#!#8"*$5\`+:SW"M``"J4*`$V<]PK0``A"F@ +MSW&M``!$2:$@&(`/````#!#9**"-!X__X'CQP-X,0`//<0$`P&K/<(``(!`" +M"@`'U@Q``]'`X'[@>,]Q1`!LN$"!`8$%(CZ`"/1#@02!!2(^@`G8`_((V`D% +M8`,`V?'`T@Z/_QH)X`HO?2H)X`H(=A5X!>#/<40`:+GD&0``X!&``!D-`1`; +M#=$0XA&``!!V.`QB`\H@@@,%\.X)(`NI<`$'C__@>/'`U@^`"AD('@#/<$0` +MR+L(@(/@`=C`>%H)0`S1P.!^\`X<]U1`!H +MN$`E +M`1P98:(/(`D$V`'8?0:/__'`$@Z/_\]U1`#(NP&%*+A.#Z`*4R!.`24('P#/ +M<40`:+L7#E0:`H&`X)#T"!F`#P`0`!"*\`#8`J&(\`.%SW&``&0+8('BN-$@ +M8H%1\N&XT2`A@,$H(0+3(&$`S""A@$?TSW*``&@+&NM@@AD+40#/<(``1`J$ +MB,]P1`!%(!@P+P@9!BD$)\`B0``P@C`P`$\&*0@Y";8VAT +M,?"!X,P@HH`V],(2`[96(P\$P)<-"%$`?A,``07P`-W)<*EV>!,-`9,2`[?D +MN]$C8H`&\H)X0G@")`,`$O`)AQ<('@7/89AMC +M`I<;8]QDD\T5"%X`PLEV$``!8KB=8`OP:'7&\0\+<@!BOP8 +M@@`JD0;P/]GL&$(``-G@?^H81`#@>,]P@`"LTDV`+H"MV!"X4Z`XH,]Q@``, +M_0*)`>#@?P*I\$`H +MSP,%?R8*@`KAN,H@`00J\@R%`-D%*+X#$(4+VB]VI@NO_RAS#B""CP$`]],` +MVP,C0P#)<)(+K_\`V0`@@(_"_7$]@2'_#_8+K_\5V@]X22#`!P]Z%6I%>`JZ +M17A`*,(#17CMI=D`K_\.I?'`9@B/_](*H`H!W[()H`HZ<,"X@>"J":`*P'^& +M('\/@N`!WL!^L@B@!"IPSW6``*S5"B"`+X``K-*I<((@"P6I<8(A"P3I"*`$*G`V%4&7;0"O_T080"#QP`H(C_\(=2AW2'8H<*EQW@F@ +M#@S:0"8`'$`E`1S2":`.%-I6)P`4(("`)@(0@!U($"*`(J4EAB6E)H8FI6&` +M08;)N\]Q#P``_"1Z97I!I0.`0X;)N$1Y)7@=`*__`Z7QP(X/3_\:<)IQ>G*Z +M +M)O``V`\@@`,%?;!]BG!J<2=P.&``(($/@``(TZ"IBG!J<0"A`>75#121&0=/_^!X\<":#D__&G)H=0AR?@FO +M_RAS"'HAQ2'.805/__D&(`.!XX'C@>.!XX'B* +M(,D``*'@>.!XX'C@>.!XX'C@>.!X`=G/<($`"`G@?R"@\T@B@"P#8S'@`(8Y_1`!(QPGPP@B@"P'8S'@`(8Y_1``X +MR'8(@`L%CB2."+@%>0:.SW>M```5$+@%>0>.&+@%>36G`XXBC@BX!7D^IQ#8 +M%*<2V!2GB@K@#V38SW:M```9((93(7Z`"/+/<```YPU2"J__0(TIAL]R_P`` +M\`0A@``LN"\F"/#/BRZ7;/+N!ZS"/3/<``` +M11(B"J__8(T`V!2GZ0-/__'`@@MO_P#;:'5H/'`'@M/_PAV*'4:-S"Y4`:F;/<(``#/)U>$"@ +M`-SM#%61SW"``(BUB&!U>`IA>&,5>)1X`""-#X``%/)`M0'D\/$`V@/P`>(W +M"I4``=G/<(``#/)5>""@`-GM"56!6&(5>#1XSW.``)BU-2,,```@@P^``!3R +M@+,!X?#QD0)O_Z+`\<`>"D__"'<`WLEU(/"I<`H+;_\#V<]R@0!4(_`B00#/ +M0"!^6;`N$$I0@%5>T"#Q+D0(D(`.'@%>D"C`>8+Y8PF +M$)!,]\]P@`"$M0"`((`#V`RX"2$``*L-!)`A`D__\<"J"4__@B0#,`#=SW:` +M`"SHKJX>#2``BW`.CHHAA".*(`0F*>@F\)(.(`"I<([ERB)+!,HB"@0`W!CP +MA"P&%H04P#`6(4%S1"S^',=Q@`"LX:09`H``(4!S,B0#,`'D`B+``*89!(#5 +M#)20`>6O?;D-TIQE\`X/(`!6)$`T?MBD'`0P@]BF'`0PA-BH'`0PB-BJ'`0P +MO=BL'`0PKAP$,+?9L!Q$,+78LAP$,+06O?6\-TQSF#2``J7".Y +M^0Z5D$0N/A<5(0%PA"P&%I1Y@W&($4$!%B%#.'% +MX<:$:2&1(;``V1#P%"!-`"YDSW*``(X00(IAE$O>4(IPG!Z8D*UXPG2 +MB<'&X'_!Q>!X\<#AQ3H((`H#V`HE`)`:\E8E0!,!VL]Q@``LZ$VISW&``(#D +M8@I@#HHBQ`0`)8`?````"<]Q@`"FYDX*8`X&VFT`3__QP.X/+_^8<+AQX1"+ +M``+8!/!`(4`0#WC%"/,!.7``V`/P0"=``.\(]8#X<`#8!?!`(D`0#WCO"/.` +M67#/<($`V!SP((@"`-GI"9."`!3#`$XC@A!3(\``A"W2``2XAB/\`PUX;7L" +M*(X`6GLOJQ`)$0``N$O>;CQ?0P(KPP(*)$`.!"F^ +M$H!U`"5!'EUAP'63"K."U(V&)/P3C7Q^9M2MH6JY80`F3@`TC@(LS!*9832N +M3"$`D,P@(:`7](0M00,O<00OO@(`(41P`"2.`,]Q@``L\3YF^HZ`=?MC>JZY +M87J)FV-ZJ0'@`N)/>KCQ508/_^!X\<`&#@__HL$RWS3=`-XW\`H@`"?I<`IQ +M>@Z@"4S:$^C/<($`N!T`@('@RB"!#P``KAE4#&'_RB&!`P'`P@[O_\EQJ7`* +M<4X.H`GDV@'G[W\2Z,]P@0"X'0"`@>#*(($/``"O&2`,8?_*(8$#`<"R#>__ +MR7$!Y:]]`>:9#I20\04O_Z+`\<"�__H\'/<(``K+4$D,]Q@`".$-=P``!1 +M#@O8RB`K`@"I#-X+\+@500'/<(``+.$4(``!(+`!YL4.%12,YLPF8I,!WV,YDHD0``" +MP,(D`0$$(+Z/````#P04!3#:\P#?H0\3D40O/AN(<>ER`"%`<7X*(`"IER`"$` +M<48*(`"I/'`HL&+<2;8R@R@"03:"N@!P,]Q@``JYV8- +M(`X#V@WP`-D)\/_:`"&`#X``*N=`J`'A]0G4@*+`T<#@?O'`X<7/=8``K.82 +M#.`)!=@`V'D$+_\;I?'`^@LO_R'8@B0"-E8D@31N#*`)D-KA"!```=G/<($` +MN!T@H)04`#"+<0(-(`Z0VDHF```#\$`F1@"]#A4!A"[!`$`N@``*)(`/@``L +MYQ9X0"1"`'(@`P@*Z3*X!Y5,-E1)*((`5O7L;8Q4D`A-Z8L**4B4#$."[TR;B$,8F@1__ +M_P__PBXA$0L.$A)POLU^!"P^$D`NA1"^88!V)W8"'D(15(JM"Q^`AB+\`T2Z +MT?$`W9,-E9`!$,(``"7#$0*Z.V.6&X*`K!N"@`'E]/%U`R__@"0"-H;@X2#+ +M!\H@*P".X.$@RP?*(&L`DN#A(,L'RB"K`)G@X2#+!\H@ZP"BX.$@RP?*("L! +MJ>#A(,L'!=@&V.!^X'CQP.'%P@K@"0/8"^B6((4`SW&``"3G^@P@#@/:%/`` +MVP+P`>,A"Y4``-G["=6`%"/``#A@_]P`(((/@``DYX"J`>'U\?$"#__QP.'% +M"'2$ZP3B3WJ$*H()8(PO<``A@G^```S4A"F!!,=P@`#LTWBJ.N!AC"=P8+!` +M(H`&)W#6">__B7&Q`@__B-I`L(K9(;!"L(S9(["YV22P);#"V2:POMDGL,39 +M*+#!V2FPR-DJL+39*["_V2RPLMG@?RVPX'CAQ>'&`-J`X`';PB/,`(HA_P]T +M>2\@"0#/=($`I!X$VPWP`-T/)X"$;GN">`Y\`6J1<\H@B@`4>"QX+W#!QN!_P<7QP(()#_^VP0AV.G$: +M`#Z7%*<(IQE@C@`PIR0H8!Y0*Z57H`(L$$(G*.#Z`# +M"G`BA@*Y-7D`(4`$8G$N"B`.%-H:C@00`2"5#220`"55(`080"4=`2__ML#Q +MP.'%(8$!@(AU`GF$*0\*0GLO<(0KAPT*N`X/H`8O<34!+_\`I>!X\<"V"`__ +MOL$(=HMU?@D@!*EP0H8`V`\@@`!#PD3``(9"P`2&3`X@@@\``0```-N, +MNU-X@.+*(6H`RB0+$,HDBA`S>,]R__\`\(#ERB4+$,HE2A#*(8L`RB'*`#QX +M_@@O_YA@K'AM`"__+W`O(`D`C"`%BO'`Q_?:""__BB$%"BAPC""$@P':R/>T +MW`X@`0,O($D`BB+_#]K@R/>TW`X@`0,O($D`4WH;>`3@([C/<8``!`SP(0`` +M3'@O<-'`X'[#N@2ZP[E%>2"HX']AJ.!X(G@.>(+@X2#)!\H@J0"*(;\/,'#A +M(,L'RB!+`.!^X'@`VC!PRB"+#______@(,L','#A(,P'RB",``'8X'[@>/'` +MX<7/<($`!"$@@`&`\!Q(L(H)X`-!P(MQ%=BR#V`)?-K/<8``K/L%H3'H`<$` +MW`+P`>17#)40`-H#\`'B]PI5@0#;^0O5@)AD%GA]8[1]N&"@@40J/@_'<(`` +M;/C(O2=PHK"@@00EC1\#``#^*;VAL`01#00$)8T?_`<``"N]KGU'O:.P`>/> +M\3D'[_ZDP.!_`=C@?N!X\<"B#N_^`MB")`(U&1P",`;8&AP",`#8!?`6#\`# +M0"%`(*T(=0$Z<,]Q@0!,*PAAY@[@`V/``-X"\`'FWP[UD"/`!@_@`\EQSW"! +M`%`?R&!!QD#``-]$Q^,/E9``W:(/X`D/)#.__J7+/<(``;`O(8)'!9L!6)!(T"G"&#.__0"("(54DQ#:I<$`B`2$# +MVC(-[_\FPQ)O%'@5(($#&\)`*0`A%'C'<8``K/D,X1EA0*$!Y\CQ-0;O_H`D +M`C7QP.'%D@WO_PAU"'$>#^__J7`6#*`&"+@]!L_^!"B`#P``+[I"*<)T1"K^ +M`@(@0`XO(`B`4'L$\@'B4'L)"#,!8+&$Z`#8`_"`V.!^\<".#<_^"'8H=P#8 +M5B$-!`>E)E8AP`0&"6`'48H&A00@OH\`!``!"/()A1P=@!^` +M````E+@)I4\.'A`N#Z`!Z7`FA4>%%0F>!PF%A2(!!(RX":5'I1GPS,F`(`0` +M'0G>!RF%!2*"#T`!4`"-N2FE1Z4Z@)ZY"/"4NI:Z1Z4Z@)ZYG[DZH&T%S_[@ +M>"7(QW"!`&`(*(@!X2BH"(@;"#(!PA(!MJ`9@`\#`(0`BB`(`,D:&+`)\(H@ +M$`#)&ABPH!F`#P(!A`#@?O'`O@S/_@AV*'>$*`@%`"&-?X``I!S/<8``D!%` +M@6F-(8K/<(``I!HQ"V,`,"!`#FJ-(XHE"T,`)MG6"&`"`MKBH""`!+[6?@`F +M@!^``%@E(*!B#&`"#-@`V-$$[_X0K?'`1@SO_A3:I<$(=AIQA"@(!0`AC7^` +M`*0<0"4/$@2X%B`5``HD@"^``%@EBW#/<8$`H""^#^_^.G#)<*(,X`$*<0HC +M@"^``)`12B(`(`L(4"`IC2OP#8VCZ(#9SW"@```=+:`NH!&-#>@+C0'@#WD+ +MK0`3`"`$B!!QI`FJ`LH@B@/ER0T(CP,R#.`(R7`'Z,EPC@B@!'@5@9#Z"``- +M(8\+"50!A@Q``R&/`!,`($&(#0F#`&*/`X@U"P(`"0F"``"/`_`"CT'`0,8! +MCQ390L`&CT/`*G`:"Z`-HMH!V1-N%7@`(((/@`#L#B"B`!,!($&/`(D-"@,` +M0H\"B2<*`@`P)$`EC^@($@$@F2$8`)8.[__)<`*^0W8=%@`6`>`='A@0#1V" +M%'4#[_ZEP/'`(@O/_L6`H\$4;A9XSW&``#@E.&!`(!((A"X(%2]U`"61'X`` +M!!P:"J`$&!&`('IPY@T@#LEP#@Q@`AIP`-\NZ!`2`"",(/^/*O0;$8`@C"## +MCR3R`"6!'X``I!I?$0(&`K@P((`/H`"T+@`B@P\````0`GO+NR4(@`",(P2` +M3O<`@1O9_@X@`NER((#BH!`:0""2"F`"#-@!WZ7OQW6``*0:&84AZ$`@02&+ +M<\EP5@E@!VIR`,"`X``)X03*(($#`=C$'0`0`-WER0\EC1.K>`;TN@K@",EP +M!^BI<`#9M@J@""ARF0+O_J/`P0,@``6`X'AY`2``!8#@>/'`+@K/_N6`SW"` +M`+S]MV^T?0`@40//<*```"!L$!``A"\(%<]Q@``<'#(A3@[/<8``"!LP(4`. +M,^@3;A9XSW&!`%@#`&&VZ$H*X`CI<++H'!$`(`(@``19"%,`QW6``"3^`(4, +MZ`#8`*4`(($O````%.EPR@M@!`3:'/`8A9KH_@W@#LEPCNC/<(``L!#P(,`# +M`"`!(.EPI@M@!`?:"O#/<0``'+G)!X\<`^"<_^,@Z@!`AWZ7``W48,(`>I<=-OUG['=H$`)`.M +MIMX+H`3I<:^FL:9]`>_^L*;@>,]QH```(%N!![@4>,=P@``D_B>`(GHJ@`;I +M*(!982B@`-DJH.!^X'@'N!1XQW"``"3^SW&@```@.X$GH`'9X'\JH.!XA"@( +M!<]Q@``?'"]P"6&,(<./'_)2:3`B@P^@`+0N*'*`(L(!E.'*(88``KDP(8$/ +MH``8+&]\#]H(NI%QUB,E"&1Z)7H`(($/@``@'$"AX'[QP'H([_X(<@*!)0A1 +M`(0J`@K/=H``7"@O=0&!H@X@!TAQ"''B"R`.N&8%\-(.H`1(<+D`S_[@>"4` +M(``$B>!X\<`Z",_^"'8H=18((``$B,=P@0`D`TN`!NH`V2N@J7!@>I+9:0#/_O'`9(C//_N!X\<#AQ62)`=P`@3-K-GD`(8(/@0!5`X"JR@F@!&AQ@0>/ +M_N!X\<#Z#J_^`-LH=>2)SW&!`"0%I1$`!@'>$"#``Z49&``CA1-O%GC'<($` +M)`,:<"N@`-@#I<]Q``!TO<]P@0"8#0"A'PB` +M#ZVK_LK/<($`8%#%H`B5#PB!#P```!`R&((C\0:/_N!X\C'=8``I!I5%0`6+@S@#A_9&@D@!^EP@.#*(,(#1`EB!,HA@@/$%0`0 +M@.``V`OT8@L@!NEP`=@%\&X+(`;I<"IP@.#*(,(#C`WB_\HA`@1-!J_^H\#@ +M>*'!\<#N#8_^*'9$P6AU0:.*(P0`)PD>`E$@P($!V,(@`0`'N$$N01%D>05Y +M&8V)N0VX)7B.N`*E8_`5C07H`VI&(,```:5!+D,4P;L$)H(?````&"3!*[I$ +MN<&Y`>$`*\Y7SKE5,FP!`*OP0G +MCQ\'``#\Y7Q!+D\3P+\5O^5\](T6O^5\^8T7O^5\0"Q/!^5\D[R4O)Z\&PNU +M`(*E!.L3"94`@N',(JZ`S"!N@@#;PO +M$@.A`H4$H0_PSW&F```!$*$#A1.A`H41H02%$J$9C0/H!X44H0C<*P6/_O'` +MH@R/_L(2`;:CP1`1DP#/<(``%/T`B`#>A"@!`\]P1`!:QC0@4@[/=Z``@"TE +MR!VGS,F3$@VW@"$"`+@0$0=&)<`0DQHA_L*WH5'"IX%4R+!`@*Y02H``X[AP[C0(J4% +MF??#$@RV9+E6)`,4*+-T'((3P+1U'((3QZ,0K,+)W;,A@(8A_PV$N2&D$HC) +MHQ*LH0J>!<,2`;80B94(P03"R0&`C0@>`1L*7@4N#J__`-C#R:00```MN(8@ +M_PL%?0OP)E8AP`0N#^`&48H`%0`@#0A?!,,2`;8N\,(2`;:8 +M$0``Z+C!*.(`TR!B``KT#PB>!I@1@`!$N,&X`O``V,,2`;:8$0(`Z+K!*N(` +MTR)B``KT#PJ>!I@1@@!$NL&Z`O``VHCH".JZ$``F`>"Z&!@@M/`!@<4(W@"8 +M$0(`I!$/`,P2#K:+<\EP@"`$#58F!!E6)HP9)P\>%>BZTR*B`-,BX0!(8,]R +M@0`8)P"C'7C"N/0B```!HT+P-PI>`D$J``'!N`ADB;A`P,]P@`"D)!J`(,)$ +M>$2ZP;J&(/\.6&#/,*X]"(```&C$O!=>,*X,B0``,]R@0`()T#`'7C" +MN/0B``!!P`3P0,9!Q@#`B!D``,,2`K8!P%8B`01F@0*Q$PM>`@F!@+@)H0K8 +M=AH$``?P$-AV&@0`")$+"Y\&`-X'\`3@"+$$V'4:`@`!W@:!@"(#!?H((`8H +MD<,2`;96(0($Z1F"`R*2`;(X8!BRPLG/<:```""P$`P!P!$#`&)\`"1#%)B2 +M0G.:8SJ!4'HP=`*(`@@;@`IN2FHZ9Z""`/,MC-`8_^X'CA +MQ2G;$KL5>P#<"/#P(0`#%2,-`P"E`>3U#(20X'_!Q?'`0@FO_IAP`-H/\%AB +M%'AT(`X!*=\2OV*0H9`0NV5]U7^@IP'BZ0I$@(4!C_[@>.!^X'CQP.'%"'7/ +M<(``K-,W@)+ISW*B```(!H*$N`:B!H*#N`:BBB(0`,]PH@``N$J@!_`#VL]P +MK0``!%V@0(T'VXOISW.B``"T`H-&(,`!17@"HQ'PSW"M``"F0"/ +M_N!XW01`!BT%0`:1!D`&005`!O'`X<7/<8$`*`@4B?`A#0#/<(``5!,."^`- +MH<$"A5L(40"+<<]R@`"LTQ>"@.#*(($/H@``M`SR#P@>`,]PK0``)A^`!?#/ +M<*T`@#`/@`"AVP@>A%J""PI1``]X`O#%N`"A`,$&A0':(*`&A42HR@^@"038 +M!O#/<```$RO>#8_^SW"``*S3%H"!X&`+0@;/<:(```@&@:2X!J$!V%8-8`8` +MV<$';_ZAP%D%0`;QP,]Q@0`H"!:)%.AAN`][%JD4B0'@#WH4J0L*40$`V!2I +M@./*("D`'`UI!LHA"0#1P.!^X'[@>/'`)@D`"!()``C^"``(T<#@?N!XSW`` +M`.4.906O_M42`;;@>,=PH```8&"`)GME>D"@X'[QP+X.3_XH=E8A#P0FAP0A +MOH\!``#`H<$P]`:'0,`!VA4('@)!*,(`P;H!XC&XP;@:8@[P&0B>!B#"!""` +M#P(```!$NL&Z`>(QN!AZ(0I0`!,*D`"#X@#8RB#A`<`HH0,*\,]P@0#04`*` +M!O#/<($`T%`!@`5Y)J`8H<$%;_ZAP.!X#'$1(0"`RB"!#P``_P`.\L]QH```!`^A +M`X$LN,2XSW&!``07\"$``.!^X'CQP.'%SW"````.`(`,Z,(2`K8`V):XSW&@ +M_MP'Q@L@"*`2`@"B#(`-SW"@````!H<+)H!`!`#T)'@2*(0@`1@I@`)(:7+#=R;L('@#" +M$@.VSW#%[H0VO)-4$PP!`=G9$@*V$+V@$P,`^@V@#@4D1!-)\"<)'@7+R<]R +MH```+BRX4R`!`16"`=P0($``%:(ER"H+(`X`+``0BB`0`,(2`;;)&ABPH!$` +M`!\('@>.#D`&SW&!`$04$8$5>1*!`>`2H<(2`;:@$0``#PB>!Y/-B;B3&ARP +MW`,]PQ>Z"-7X-H`X!V<]SH```15R#SW#%[@)">(-F#:`.`-D# +MV<]PH```!"B@C01/_O'`$@Q/_@AU*';/<($`P"`@@$$.$!%"#>`!R7"F#6`) +M#WC/<8$`T%`A@24(40"$+@@5SW"``,@:,"!`#H#@SR%A`,\AX0#/(6$"!/)% +M(4$#`-L*\!9M=7@`(((/@0#H4B"B`>/Q"Q2$`-O/<8$`:%(6(4(#8*IAJ@'8 +M`JH#V`.J:'(&\#ABMGADJ`'B^0H4@?$#3_[@?P#8BB/_#Q-Z@.#*(VH`RB"+ +M`'-\,WJ`XH#ARB,+`\HABP`\>3A@3+AL>.!_+W#@>,]P@`#,%>!_`(#@>/'`$@M/ +M_@AV4@S@`2AP"'5*#.`!R7`(=HH@_P\0=LPE`I`P\L(-8`FO>*F(N@U@"<]X +MR8C6".`.J7#/=X$`:"0(9RD($0+&".`.R7`(9P#=%0@0`K8(X`[)<`AGA^#* +M($(#$?0!V`_PH@C@#LEP#F>:".`.J7`(9Q!V`=C`>`/P`-C]`D_^X'@$N,=P +M@0!@)6"!@(!@I"*188`@HR""8H`@HR.``I(`H>!^X'@`V0GP_]H6($,`1:,` +MVD:C`>'U"=2`X'[/*8$+>0'8X'_"(`$`X'CQP.42`;;G +MR25XZA(!M@MY`=@%\F8*@`D#\#X*@`G1P.!^X'A9!L`&\<#B"4_^*'6$*0@% +M`"&`?X``I!K"@%40``:V#V`.']D&V.8,X`:I<8#@RB""#P``?#`H"*+^RB%" +M`X?F*`AA!,H@00,""F`(J7"`X&@+(@C*($(#_0%/_H0I"`7/<(``^!LP($`. +M:0=@#A_9\<#AQ2AUU@E@""AP@.`\"R((RB!"`]D!3_[@>(HB_P\`W`/P`>0; +M#!41,FPT><=Q@`"T#VJ!\0L.@`F!`O!(<.!^X'@`V0\('P`O*@$`3B*!!P#: +MSW.!`/!0%2-,`!`@0`!`I"6C!^@O*`$`3B""!P+P*')&HP#8"/`/"0```=H5 +M(PP`0*0!X/,(5('@?N!X\<#/<(``K+4!@!T(7@#/<($`)!\^"```SW&``,S\ +M"8D!X`FIT<#@?O'`)@\`!H#@T`_"_\]R@`"X+`:"!(`@@,=Q`P"0T"X,H`U( +M<-'`X'[/<8``K--8@<]Q@0`D'_4$(`9`J2AR+0`@``#9X<4`W0+P`>43#8,0 +MJV"L88)[+R/'@/GS`O``VVAPX'_!Q>!XX<5`*0P")7Q`+`,4A7LG"C0""'0$ +M\`$<4A!ANE,D?I#[]4$JC0#!NH`E_Y\$'-`0_/4'ZH`B_X\!'%(0_/7@?\'% +MX'CQP.'%L@_@"`'=`-C/@_@"(Z]@.#*($(# +M.O0!V\]TH@"`PG"D>-@1I"W9,J0$V3.D`-I4I%6D5J0*V3>D"-DXI%FD6J1; +MI,]QH@"`P7"A$:$2V!*ARM@3H8_8%*%VV!6A@=@6H7S8%Z$"V!NA>*$1V!FA +M"]@:H5RA7:'J#*`.9-B#PLEPJ@D@"0'9"-RK!@_^X'B`X,PAH8(9\H#@S"'A +M@17R@.#,(:&!$?*#X,PAX8`-\H/@S"%A@`GR@.#,(2&"S"!B@`#8`O0!V.!^ +MX'CQP/(-#_X(=RAPSW6``"P+0*W/=H``+0NF"J`"8*[/":`(`-FV#6`"J7#/ +M<(``%/T!@`:`#0C?!Q(+0`D$\.(*0`D0V+H)H`@`V0/P*@U``KT%#_[@>.!^ +MX'CQP'8/(`GAQ8'@`=C`>`W=O@A@"A1]R@^@!ZEPG04/_O'`%@T/_J/!`-X% +MW2'P`-^+OP`F@!^``-#.&G""":_^02^!$$+`!=@`'`0P`AR$/P``"`@J<`S9 +M"G(`VXN[BB3!"NH,X`Q*)4``_F9AO1L-$A"+<#IP3@SO_PS90<79[8HG&!'7 +M\14%+_ZCP/'`L@P/_@AW*'8Z#6`,2'7I<*H-8`S)<:EP3@Y@#*EQ_00/_O'` +MA@P/_@AW.G%(=D`I4`$`()`OHP``5@#=!?`@@B"@`>4I#142%29"$Q4@0"/X +M[R"`0()0</'`PLF*(0@%I!`,`,00`@#/ +M<(``%AQB:"QZ#0P>$#0@0`X$\#0C0`YR#8`-L>@#V<]PH```!"B@(-B2&ARP +MSW&!`,03%($!X!2APLF8$`$`E!A``,(2`;96(0($#Y)@D@FR'9((L@F"K+BM +MN`FB?A$``1MC&))B>!BR`-@`LGX9!``!DAFR`-CR"R`-)H+1P.!^X'CQP((+ +M#_X(=%")`=@S$8T``*PE$@,VSW:!`&`(;F;/<($`0`C!K!0@SP#1CW5XPZS0 +MC\*L;(!AI,]S@0`,"$MC=JQA@4`D#A@="QX!P/P@-L$NJ5Z8*Y!KER14;0>@`2TR\D&I%01``$.M`"1#[2@$8(`2:3) +MR00@@`\"`$$`#0B!#P(```"(NDFDRV;,` +M%@]`\Z``%@]!Z+,`%@]!ZK,S#1$2BB0,``0A#P$G#P$1'M[9LP`6#T#VH``6 +M#T'NLPGP$-[9LPHD@`^!`-Q0"AR$`2AWAB?]'(PG`I('].)N\'[YLP`6#T$" +M\`#?\+,+#EX0`!8/000A@0\``(R`%PF!#P``B(`D;C!^.;,`%@%`.:`$(KZ/ +M````1\HA(0`H\I_M/PT>`+"(SW&!`(0/`[VU?:%A'0F>!^BZP'G/(>("!O3N +MN@'9PB%!``^Y)7I)I*BZKKI)I`#9.J`[H`CP`!8!0#J@`!8!0#N@"-D`D#YF +MPG@8LYBZ2:3/<*````0$@!NTO0$/_N!X\<``V<]PI0``#"2@SW$``'#LH@R@ +M!@;8SW$!`)CME@R@!@?83@B@`0+8J@P``'(/#_Y2"``-3@X`"@()8`H!V-'` +MX'[QP.'%7@F@!E38"'4;"!X!SW&@``!&`('>N`"A#@Q`"+H+(`,(V,]Q```0 +M)V(/8`X`V`+8"PU>$*(+``,#\(X+``-!`0_^X'@`VL]Q@0#04$"A`]@#J4&I +M0JD$&8`/````0`@9@`\```#`X']`J>!X\<"6""_^F'``W0_PN&44>'0@#P&M +MWA"^8I!!D!"[97KU?D"F`>7I#420V0`/_N!X\.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@ +M>.!XX'C@>.!XX'C@>.!X;R9#$,]PH```,#`8@`\`@```SW"B`(!L=!B`#P`` +M`(!*"2`)`-_@N,HAP0/*)X(?``#``,!YSR$B!.&XSR>B$\\GXA//(>(`SW*M +M``!`+:+:&M@#_QI8`\]PK0"`@[^@SW"M``!$P:#/<:T``(3!H>!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!X^AI8`\&@P:&@H*W8$+@T&(`/`00/ +M(,]QK0``%@:!!""`#P_^__\&H/'`X<7/=8``K+4GA00AOH\#```` +M!O0$(;Z/#`````_R`-FMV!"X)*`!V<]PH@``@"J@J@Q@#"AP)X7PN=$AH80/ +M\D#:SW"M``!`1*`!VL]PK0``@$>@6!B8#P```$#PN=$AH803\L]RK0``@`D) +MG@0@V`>BSW"M``!`$!B`#P``@"!A&I@/````0`3:\+G1(:&$RB"!#ZT``(`% +M\L]PK0``0$B@&PD>!(HB$`#/<*T``(!'H`':SW"M``!$1:`_"9X"SW.M```@ +MSW*M`(`>8!J`#\_;$!%0&H`/HB@0D4P:@`^B*!"1Y@9SW"M```$!!B` +M#\@;Y@6!!L_]\<#AQ<]U@`"LM2>%HN@$(;Z/`P```#;R:@M@#`'8)X4="1X$ +M0-K/<*T``(!$H,]PK0``0!`8@`\!````2PD>!,]PK0``@!`8@`\"`(``'?`$ +M(;Z/#````!3R*@M@#`'8)X41"9X$0-K/<*T``$!$H!<)G@2`V<]PK0``0"2@ +M!?`""V`,`-CY!<_]X'CQP.'%SW6``"0-`(6>Z,#9SW"M``!`/J#/<*T```0\ +M@$$I``'#N`:U02D``L.X![5!*0`#R;@(M5,AP``)M3X*(`HBI0'8`*6I!<_] +M\<`J#<_]"'8H=4AW>@DO_@;8V@A``:W8$+CP((`#I'@1#0`0@"?_G^0'S_\` +MV`/P`=AE!<_]X'CQP.'%SW6``/P-`(6'Z'(/S_\F#,__`=@`I54%S_W@>,]Q +MK0``%A@9@`\@````+!F`#QT`@-!QV`RA#!F`#XP``8!'V`2ABB"=#`BA`-@` +MH8H@GPP(H>!XX'C@>.!XX'C@>.!XX'@'V`"A(!F`#P```L]T@`"D)+J$"+G/=(``9`J!C&1]I'P)O(5Y)7LL +MN@0B@@\````P97HC@$*@GKDCH"7P$PH>`D$JP0#!N0'A`=P*\!,*G@8\:\&Y +M`>$"W,.[`O`!V0*\%+L$(X,/\`,``&&YA7EE>8>Y!"*"#_\#`-PFND5Y4B'! +M`R*@H<#@?\'%SW&@`(`F#.C/<(``I`G#$((`%H!88!UXA+@#\`#8%J'@?N!X +M\<#AQ4(-X`@(=2T(40#/<($`]"*M8(#ERB#A!V0)(?[/("$#SW&J``!0@>4! +MV,H@+@`(H54#S_TO*`$`3B"!!\]P@0#P4.!_)Z#@>*'!0,#/<(``I"0_@,]R +M@`"D"1.")7@3H@0BON\("`@($/+/`).XE;@/ +MH@'80,``P(GHSW&``"0E(X'MN3.CX'X$(K[O"`@("!/RSW*``*0)(8(/"1X`#X*5N`^B`=@@D@\) +MG@,!VL]Q@0"`2TFAX'[/<8``)"4C@>RYRB!B`.!^$^@$(K[O"`@(",]S@`"D +M"03R+X.3N2^CSW&``*0D7X$S@T5Y,Z/@?N'%X<;/=8``I`F0A4`5@!`$)((? +M````&"NZ4R3!$$2X4R!#`!)J%7@T>,]V@0!@*!9FSW"!`#`H:&#[O,QXF!4` +M$`0H?@XO<,(@(@00]`.Z>V-5>G5[>F)98<]R@0"0)REBPKDY831Y$.$B>".X +MP<;@?\'%\<#/<*```"``V3J@D\U&(,(`DLV3&IRP=0C>`(#8SW&!`,03DAH< +ML#L*W@);@=W)`>);H1D('@#/Z#048*(`X!V<]P@```#@"` +M%N@`V,]QH/[D!I:X#O`3@0'@$Z'/<(````X`@`CH`-B6N,]QH/X4!SX/0`>3 +MS:>XDQH;Q\<"Z#<`+I@S`"[(,``C1P.!^X'CQP&8(S_T` +MWN'&SW6@```@;!40$-S)*0C>`,]PH```1Q08@`\```P,W\D%V0'@L[BUN+BX +MWQH8L!6Y!*'/<($`Z%?"&ABPSW"!`'P;PQH8L)+-.P@>`#Z%SW"``*0D&X`" +MX6&X""$``!"E`=@''1B0$-@`I4X/0`V2S22X!""-3S````!3(`X`L?#/=X$` +M\!T!APGH`(@``!(@."*(`P`RB""#P````(`I00=F)]@ +M````1@]`!=S)!""^CP``#S@&\A`?@)\```P,SW"@```(`H!M'YB3!`L]PH```1Q`8@`\` +M``P,DLWDN'0"`@#FN(H"`@"&(/^%/`,!`&QPX+B``@(`RA\8D,]PH```1:2@??+/<(``.!(`@(#@ +M=_+1AU(.P`$%Z%(.P`$:"(`,&H<))@`0Y.#&]K"GS@M@#!#8Y.;(]\@7`1`P +M>5H*(`@0V,L2`K9!*@`#Q+@R:#`A@0^@`+0N"'.`(\(!E.#*(,8``K@P((,/ +MH``8+"]Y5B,."-W)(G[/?BT('@#/<*````2O@!"^CH`0O9!\"+DE?L]PQ>Z$ +M1`'9Q7O:#N`-!21$$R7(SW*@```M`K@`((,/H```+9B#RQ(!MBRYQ+D_#$$0 +M08(P((`/H`!D+A`B0@!+>`/R`]@8HQB#$?`O*D$`3B*`!Q`A`0`@HX0H"`7/ +M<8``'!QR#B`#,B%!#L]S@0#@!R"#[>D,<<]PH```"`<)'@,B@`*``-W/<*`` +M@$6MH,]QH```('`1`(`M"!\`SW"``#02`(`A"!X`#'`="!\#SW"@`(!%,!B` +M#P`@``#/<(``.!*@H&HB@`'/<(``/!)`H(H@"`"ZH0"A$8&%Z(H@!```H009 +MF(\@`#\`!QF8CP$`P/QZ#@`-SW:``-05((87Z=H(0`+=R:"F(P@>`"7(SW&! +M`%`(0"@"!/0A`P#/<,7N@D@!V;X-X`UE>MS)!""^CP``#S@(\L]PH```1Q`8 +M@`\```P,1@Z@!0'8SW"!`%`;_]D@H,]P@0#4'`"`@.`8#8(!SW"!`$0*H*") +M!*_]H<"3S5,@?H`$]`'>?/##R<(2`;;"&ABPPQI8L&8+0`WV\0QP];CS]=W) +M"B$`)Q4('@#/<,7N@CH!V3H-X`W)$@*VDLT*(H`O@0#$$L]W@0#$$UT(W@"` +MV)(:'+"3S2\(W@(;AP#9`>`;IP`90"#=R24('@#/Z#00'9 +M\@S@#5N'!/`3AP'@$Z=Q$@$FSW"!`$04-7@Z@`'A.J`:[1J'`>`:IQ;PBB`$ +M`)(:'+`2A\]Q@0!$%`'@$J=Q$@`F%7D:@0'@&J$$[1F'`>`9IY+-8PC>`9/- +M!""`#P```!@`P34(@0\````()@H@!BAP#P@>`,D:F+\`"`@`"_`$V,D:&+`E +MR`+:`""!#X$`H`A`J3'P*@_`!,+)H!```/"X`-@&\@(*@`4`V):X3@_`#1[P +M10@?`GL(7P($(+Z/````4`CR;'`-"!X`!-C)&ABPSW"@```@&X`O(0H$.&`! +MX-=P``!0P\?W&@K`#`38R1H8L!WP2@O@"(H@!`#"#N`$`-_"R:`0``#PN.EP +M!?*:"8`%`-B5N.8.P`T$V,D:&+`)V<]PH```(#&@^P//_WH)H`4!V`#8D+BZ +M\>!X\<`!V)8+X`@`V9X,P`C1P.!^X'CQP%H*K_UANHAT`B!-`$$M#A,QO1IB +M(GI!*@\#,;I0=1_8RB#!`P#9#R$!``#8#R"``\EI8;@E?O`C00,&?@"!!.P% +M?L"A%_#&>`"A$_#%>2"@$?"Q$*18--`H_]PLG/<8$`:`,0B`/:`[@6>`!A!""`#P```!"%(`,!SW&@ +M```(0J$`&`10PLE=D``8A%#"R5&``!B`4,+)2!`"`0`8A%``V`&AX'[@>*'! +M\<"*"8_]&G``V,]V@`"LM02VBB#_#^'`A@E@"`S8"B4`D!'R0"8!%)X*H`P$ +MV@1M0"8!%9(*H`P"VHMQJ7"&"J`,!-H!W58)8`BI<`HG`)`C\D`F`1)N"J`, +M`MH&;T`F@15B"J`,`MI`)P`20"8!%E8*H`P$VD`G`!-`)@$71@J@#`3:!I?# +MN`T(T0`0V`JN`_"JKB26SW"``"PO(*``VDAP$?!`(`$$`-L/(T,``,%`(`P& +M$2$`@\LC`H3%(L(``>`/>.,($H(CAD1Y(Z;RN=$AH84,]`0AOH\/````!O($ +M(;Z/\`````GT`,+/<```(@DN#Z_]"G,(W/L`K_VAP.!X\<"*"(_]"B4`D"AW +M2'8:/'`X<4(=14(G@'/<(``@"P`@(#@XB`"`,]PH@"`*+&@>0"/ +M_8#@S"$A@`7T`-@`HA/PANB`X$4P$+``_<#P/CQ@N$5P$#` +M`_<#P`+P%L!!P,]Q@0",+S`9P`\L&0`/*!G`#B09@`X@&4`.SW"!`(PO'!A` +M"\]P@0",+Q@8``O/<($`C"\4&,`*SW"!`(PO$!B`"L]P@0",+PP8P`C/<($` +MC"\(&(`(SW"!`(PO!!A`",]R@0`,+\]Q@0",+P`9``A\&L`'>!J`!W0:0`=P +M&@`';!H`!V@:@`9D&D`&8!H`!EP:P`58&H`%5!I`!5`:``5,&L`$2!J`!$0: +M0`1`&@`$[Z+.HJVBC*(L&L`"*!J``B0:0`(@&@`"'!K``1@:@`$4&D`!$!H` +M`6.B:B```Q:A:B#``A6A:B"``A2A:B!``1*A:B```1&A:B#``!"A:B"```^A +M:B!```ZA:B````VA:B"``1.ASW"@```,!8`+"%``#'`5"%X$`]G/<*````PF +MH%H)``?/<*```$<4&(`/```,#`78%;@L&(`/`(!``,]P@```#@"`">@`V,]Q +MH/[X`"(,(`>6N!+`4R?!-0@4!#!3)<(U`!0%,%,FPS6B"B`'!!0&,`#9SW"@ +M```0*:#/<```K=YJ"<``2@W`"PC8`-GR#>`%F;G^"L``$@V`#"3<>P5O_:3` +MX'C/<($`)!_!!`__X'CQP,]P@0#\%L]Q@`"$+'(.8`P$VL]Q@`!0$P"1@+@` +ML<]P@0!`'P'9(*`F#>``$]C1P.!^A"@(!<]R@`"P&C`B0`X`VP\C`P`"N,]R +MH```(!5X9:+'<($`E!A"@$""0*$#@`"`X'\!H?'`Y@Q/_0AUQH``@(#@RB"" +M#P``-A%`"X+]0(8"\$""#PJ``R*%`H(B>/<(4H`!@J&B0*4!I:"@)(4&A1S@ +M%PE>`""`!NE"A2*!0GD'"5(`H*`$A2:%(.$5"-X``($'Z$*%`H!">`D(4@"@ +MH0&%#0X!$+H,H`P&A02%P-D&)@!P``(``*ER"-N*#J`-BB3##\4$3_WQP$H, +M3_T.#*`!"';/=:```$4$\'(+0`8>A00@OH]P````^O6*(/\/'*48I<]WH``` +M(`4?F)\!``"``H8!V@BE!(8%I0.&^;C/<$0`2+HAB,(B@0`S>3#A@.$!V,HA +M#`#$]K_ARB'M#\]S@`!$!X*#2B``($0D@!$$)(P?_\!X^`5Z&+E%>85Y(J-R +M#:`-`M@#AL]Q@`!T"@2ER!<`$!@9``3^"^`)`X;/<8$`S"X"A@"A`X;]`V_] +M`:'@>/'`E@MO_0#9"';\'$JP`I"+=2(((`"I<@.6@.#*(6(`$`@B`,HB0@,@ +MP-T#;_VAP/'`6@M/_:'!"'C`(%AN`"A`90!X!![UW,``/^/`;3&]@()@@2OK`8%3"@4`I)$"VT`EP!($((`/``#\_\]TH```$#`<&)#/=($`6!O` +MA``?@$,`'\)``!]$0P$4@S``'\)``-L$D6&X$'B/"R.`JXD`'T)#`>-P>_;Q +M#^O/<*```"!;@`J)&&`5>%E@SW"!`"`:`@Z`#.$";_VAP/'`9@I/_<]R@0#H +M(D""`]WAP@$<0C#/=Z```!`P'YB?`+@(`-D2`;9@P``?0$``P`+9`=Y.#*`$ +MR7(P'YB?`*`(```?@$\`@````A^8DPAR\G/<:``@"P0H0#8 +M":9Q`6_]L,#@>/'`%@EO_4AP2';J"F`(J'4EC02-"+DE>":-$+DE>">-&+DE +M>"&-P[E."R`%`=HEC02-"+DE>":-$+DE>">-&+DE>"&-@@L@!42YX8W/<:8` +M@``-OP0GCQ\```#@#P[3$XH@"@`$H?U_!?`0&8`/````/!(,8`G)<,RXY7C/ +M<:<``$``H2V-#(T(N25X+HT0N25X+XT8N28+(`4E>%X*(`40C>$`3_W@>/'` +M:@A/_0AUG@]@#242#S;:"J`+J7`:<`#>SW```!`GU@N@!P\F3A,`W0;P.@[@ +M#`'8`>47#044"R"`PP3T;'#Y"!Z`"R"`P_+U7@]@#>EP@0!/_?'`#@A/_3IP +MQE4$@`@@.:F>`4@0014&D`@/`[B#,H@@@,O)0<4Z@L@":EP4@Y@ +M#:EPW!X\,4:&+#&?2/M+RA!`TX@@0<]P@0"`%_`@40``W@\F3A`/"1$@Q,4:&+#&"R`)*'#/<8``<`WP(0`` +M"R!`A,7)W?/%>-SQR@J@"PIP&G`(<<]VH```+NEU.G<&\`4A$2`&>2]Y'>DO +M*$$`3B""!T]ZE89R:B3(,".##Z``9"YD>,42`[8$?&M\`-@/((``Z/,&),R0 +MA7_F\P5]KWWB\16&@.7F>!6F-`WB#,H@0@-"#6`-+R!'!-X*(`D*<-W)+P@> +M`'6&SW"@```<@X"P?0:\!"2,'_\```#/<,7NA$4!V0+:H@]@#04E!!.Q!@_] +MX'CAQ0?P!GV@I!`AP0`O>0_I+RQ!$$XD@Q=O>\]T@`!P#75\H(1PZ@5][_'@ +M?\'%X'C/<8$``'!CB58@`@13(WZ`)H(*\MVY)J+@N\\AH@?/(>$')J($(;Z/ +M`,````ST`8`5"!X`S,D*@/ZXSR'B!\\AH0"$_^+?`;#5X6"@S``,(2`;:@&0``AB!^CR'R`=\@\,]P@0!X +M&P"`#.C"R:`8@`\%````BB`(`,D:&+`1\!,.7A7/<8$`1!4;@0'@&Z'N\0QR +M,MB,N,(+;_VI<0#?WZ",P'9:@Y@#:`2`@#/<,7N`D(` +MV:ER5@Y@#ASW"``+@4`("`X,PG(I`$]`@9 +MF(#"R:`0``!-!0_]X'CQP,X,#_TZ<"AU&G(3"E$`KW@^#2`)`=D`&00@&?`` +MWA7PVWA`()(``")`(P]X(@T@"0'9%"&/(P"W`B6`%`]X#@T@"0'9`;<"YML. +M!)3A!`_]X'CAQ07P(*,0($`##N@O*P$`3B.-!\]S@0`$%[5[=.K_W("C\_'@ +M?\'%\)VXGKC/<:`` +M`"!;@3\9&(#@>.!XX'C@>.!XX'C@>.!X&X'@?FH@0`&8N.!_:R!``?'`L@LO +M_11X"'>`)P@8"':`)D@8"'6`)8@8@./*(X$/```@`<\C8@#/(R("JB"!#0GH +MQ@_/_RLAP`,K(H`#*R-``]T##_W@>&H@0`%$(#Z&SW'^RO[*RB!!``SR([A2 +M(```P+@3>,&X@"`(""H@``#@?N!XSW*``(P-"H(`V>!_*J+@>`#9SW"``(P- +MX'\JH/'`(@LO_0AR*'7/<*```"`[@(7B-`$M``#8,B:"<($`Q!]`)X-R5'L` +M>T*%@.*.\L]V@`",#2*&66$BIBX(H`6I<2*%!2A^``J&)W`*I@N&(H4X8`NF +M!8:`X'CT`H4IACA@":9R\"&%#0Y%<```$"&`*IL]P@```#@"`"N@`V):XSW&@_M`$2@G@!D&% +M!8:XZ`&%)H8X8`:F1O#/<(``C`TDH$+PSW:``(P-!(8+"00``B$/``;P#B"/ +M#_____\_9\]P@``<$36@`X;7=Q````#X8`.F`-@)]P/8;@]@!:EQ!2C^`R]P +M*H8X8`JF!X;X8`>F&O#/<(``C`TEH!3PSW*``(P-98(-"<0``B'```?P#B.` +M#_____\X8"B".&`(H@#8!:)%`@_]SW&``(@-0('/<8``A`U`H<]Q@`"\#8#@ +M`MC*(&$`X'\`H>!X\<"*"0_]"'4!@$HG0"``WX/@2B1`(`"%PB0")8+@2B5` +M(`.%)!43$)P<"+`$A<(E0B5!P!@5&1`*)H`O0````!P5&!`H%1$0J@J@!$$N +M$B(*(`"@RB"!#P``NA/(#P']SW:E```,*![`%8(-@`0```-G/<(``A+5" +MP`/8#+A#P`;P%29,(."D`>$"P`P4!#``@`"`"2```>T)!(#6#$``"X5`*!8& +M(!Z`%>FF[*;/<*```#Q$P`3!2G`2H03`]J`"P`"`((`#P`DA`0`*02Y)7A`+0$E!7E`*4`E)7@%((`/B```'@4@ +M@`5&P"B%!840N25X#*8`P!$(G@>/N$#``<"/N$'``,`!P=VXW;DTIA:F0!X` +M%D@>0!:""F`&A<`"A8;H!,`$P12`WK@4H>JFQ@PO_0;8+![`%7D`+_VYP.!X +M\0`#H)B>06Y+[DB>".X)0@S`!&B +M"'$,\")[!+LONP(C`0`CN3-X#0AR`!&B`-@RHN!^X'B$*`@%`"&"?X``I!QM +MBIOK)PE1`/(2@8"/Z2F*`K@!X2FJ*(I#<`'A**H8$`$&`>$8&%@`!/`*B@'@ +M"JH`V/(:`H#@?O'`/@_/_`AVPLF@D`&`0.7TN,`EHA`#Y<]RH```!"2"!"6- +M'P``_/\3":4#W64ER!MX0W!,$``'&6$.@@(E3Q!/",4#`]B""F`'"K@$V<]P +MH```1R2@SW"@```$#H`-",4#;'#S"!Z`!-G/<*```$!,('@#/<8$`1!0"@0'@ +MX'\"H14(7@#/<8$`1!0#@0'@X'\#H2$(W@!L<,]Q@0!$%0T('@`5@0'@X'\5 +MH1N!`>#@?QNA$PC>`<]Q@0!$%`"!`>#@?P"AX'[QP"(.S_R")`4PSW6!`+A7 +M`(5*(0`@0L#+R58D$#($((`/\0``\,(2`;9#P!")SW*!`&@#`[@6>`!B"B2` +M+X$`0`@$((`/````$$3`5B3`(R42`C9&P!0D@"`1B$?`SW"!``!P`H"3$@.W +M#0@>`40C``0%\$0C@``#N$7`SW:@```@6H8%Q`&%#NS`%@$0(G@"(@$`+R-( +M(,(2`;9V$0`!6&`3\(01$P%B"6`'`ME*)D`@"B*`+Z````@D&H`E(!J`)4H@P#`( +M&@`F"B6`+Z````08%0`@0,!`X!`=`"#"R3&(I!```%,AEP`$(+Z/````00#? +M#/01")X"SW```!TEE@L/_03P.1[8DP`6`$!`*P$D$'@%>03`SW*!`/@H!2$$ +M`,+)+R'"!<"Y2,$I8@"02<$(P\]T@`!XM?`DPQ`984K#9VD*)X`O``#\_X.% +M!"/#!0@C&0,H&D`@"L3/`C!*6(X8!`:`"`" +M(<`P0!H`(!0:`"8!A<]R@`!$!X`@#PH0I@<>F)40V`"F`H)$(($!`()&((`! +M)7@`HB(.(`T#V`+`SW&!`%!0`B!2!LO)PA(#MBRXQ+@$L0^#[JD`H4`3``$" +ML1"+8!,#`51HP[ME>D:Q884/J242`C9P>14D@"!>@%EA/J`;AL`6`1!X8")X +M2\`"A<]QH`"`#`*X+^`$(,`%$*'9$@&V`!]`0"*%`!]"0"42`384)$`@,(@` +M'T)``!_$0\+)E!`!```?0$`E$@$V!L#P($$``!]$0``?Q$,`'\!#`!_`0P`? +MQ$/"R3"(SW"!``P(*6``'T)``!_"0\L2`;8`'T!`PLD@D%00``$0N25X`!\` +M0,(2`K8!@B$('@$RBL]P@0!H4E"*5G@`B(8@?PP<>`2X)7@#\(#8`!\"0,+) +MSW:!`"0=,(@S$(``!+D%>0`?0D#"R3R0`!]$0,(2`[8!V9P3``%1(("!PB%! +M``^##+G`N`VX)7@E$@$VS1H8L!0D0"``(8P/@0!@"."L+WR6?H"6F!C$`U`8 +M!`,&Q."P-7RH&,0#SW``*`@`0<#$$P``X*2$*`@%SW"``!@<-"!`#CMZ3,`0 +M%0`@`=E,'0`@`H4%((`/Q>X`-TW``8,`Q?2XPB%!``"30.4T>`/@!"#`!1UE +M`O`"?0`B@#!,$``']PT%D,]QH```11R!.($`W@\)7P4$(+Z/``8```WR^K@! +MWL(F@1/YN,HFHA#UN!L@H)8* +M8`PH<`C>SW&@```(!('_N,PF(9#2\P3N.!Q`-#/P`-@)&1B`R\G/#PE?!00@OH\`!@``#?+ZN`'>PB:!$_FXRB:B$/6Y +MRB8B$KX(0`W/=Z````@6ASD(E`QL@```(#AMO`!V<]P@0!X&R"@K@A@#"AP"-X# +MV,]QH```!`JA@.;/=Z````BD]`'8":%5)4`4!*%,``?`$`$&!`@#\##$@&VV1H8L,+)`=K# +M&ABP`8'"&EBP]+C"(H$``)%6)0\25'@#X`0@@`\``/S_'V<"\`)_)<@;>$-P +M3!``!_``? +M`$!`(5$@J72&)/V>`!@`($`@#B$<\E0?@!2SS1"X)7@`'P!`!!X0$`#8`:>^ +M#2`-0"%1(,]P@```#@"`".@`V,]QH/Z\"*X,8`:6N,L-$!#/<(````X`@`CH +M`-C/<:#^\`B2#&`&EKAV#Z__J7`)\`C9`!]`0`0>4!!`(5$@SW"!`+A7`H#M +M"02@SW"!`%!0!)`#V@*X,""!#Z``M"[-R25XSW&@```,`J%'H4>GSW&@```$ +M"8$&Z$BA`-@)H07P@@ZO_P#`#L`8Z`39SW"@``!')*#/<*```"`[@`O`,'!O +M(0L`#'"`X=$@887T\P39SW"@``!'):`!P`#>R1H8L`S`&@D@!\EQX0U>$,]P +MH```(-J@:O``VA4*$"!4'X`4SW&!`$04`($!X`"ASW"!`%!0!)`#W0*X,""! +M#Z``M"[-R25XSW&@```,`J&GH4&GL@X@#`S`D\T1"%X`SW:@```$#H;`X`3W +M`<4]\+6F`=@)IH(+(`7#R22&P\FT&$0`J*8PB%,AP@!$N<*YP!A"`%"H2'`" +M""`%`-G#$@&VQ!D```7`@;B-N!"XG@O@!"42`C;#$@&VSW*@```@L!$``5J" +M9."E"(6`!<`!Q8&X$+@%?0#8#@V@"Y@1`0".#J`$`-C)&EBS`-[=R1L(7@`- +MP,]QH`"`'`&A#<&0P/(.X`S&N<]P@0"X5T&`SW"!`-0<`(`I:(?@RB!"``*X +M%'@`(($/@0!\'$"A)<"Q902O_(`D!3#/<*``@"!<&(`/`P!` +M#<]Q@`#$#0"!SW*!`.08`>``H0:"!(`@@)8A20RI!^`+2'#QP!8,C_P(=L]Q +M@`!@"P"!E^@!W(0H"`4`(8-_@`"D&D"#SW````$V*+I/>LEQ%@KO +M_&�"U0$<]Q1``0?S`A``00=')`:$2>`6AXLD"H1)X!J'CR1)Z`Z%'H>02`K9?H5)Z +M5J'/!`/`'((<*(H`O +M@0#X!PHA@"^!`/0'&0U!$``2`"`1"`$$`!$`(!!V^`X!!:"G`!H`)``9@"/) +M`H_\X'BJ(($,">BK)L%R```!`*H@`0+_"!^"X'[QP!8(``"J(`$"_P@?@M'` +MX'[@>*HB@0P/ZAEA1B#"!P+P(.(3"D4`JR(!`ZH@`0+]"!^"]_'@?N!^X'C@ +M?N!XSW"@```P,!B`#P"```#/<:(`E&X`@00@@`^`_P``!2"`#Q<`````H>!^ +MX'C@?N!XX'[@>.!^X'C@?N!XX'[@>/'`X<4(=8HA$`#/<*```!TMH-X/S_^6 +M#^`#J7`U`H_\\<#AQ0AUBB$0`,]PH```'2Z@P@_/_XH/X`.I$O`3;A5XQW"!`(0/((`3"5\""(`/#0$0SWC:#B`$_]D!YN$.%)0` +MV<]P@`!0$M$!K_PBL.!XX<5@@6"#`-PPZP3P8G@!Y/T+!(`A@:"!%KP4ZKID +M4R),!9%PPB(.`,OWQW)`````!"*"#\#_``";8P)[>F(5\`(E`A-3(DP%'&21 +M<\`B!@!+]P(B@@]`````!"*"#\#_``!B?)IB0*'@?\'%`-F>N1EYULDF>.!_ +MUAH8L`#9GKD9>=3),GDD>-0:&+#5R21XX'_5&ABPX'CQP+H(C_S/<*```"`: +M<-P8@`\#`$`-UA(.MLEW+?`(=BOP+RW!$Q,-51?/<$0`A+>V>`"`B.C/<``` +M]0ZI<08/K_SI<@#8GKBY>`9_;!`!(,]P@`"\"B"@SW!$`(2WMG@`@$!XJ7!F +M#>`,BB$$`-;)!R"^@]7UU^^I`(_\\<#AQ0#=$_#/<$0`A+>V>$&`4'7*(((/ +M``!W`,`H8@&D#J+\RB%"`P'EX0U4EY$`C_S@>`#9GKD9>=;))7C@?]8:&+`` +MV9ZY&7G4R25XU!H8L-7))7C@?]4:&+#QP.H/3_S5$@*VSW6@```@+RZ!$-P= +M@!\#`$`-G>;*((8/``#B#D0.IOS*(88#.X7/<(``O`H@H,]P1`"$M]9X`(!` +M>,EPK@S@#`#9@-@''1B0"0"/_.!XX'[@>/'`X<4(=83@RB"&#P``@C#T#:;\ +MRB%&`\]Q@`#<#Q)M%'CE!V_\`&'QP$X/3_Q*(0`@*G4$\$HA0"`!Y54-%1': +M""``J7`:G#O"`"$BB`(!0Q]SW:``*P:6G`P)D`>BB0&*-<,#J#A;<\/ +M59&J""``Z7`9",`$!"^^%#`F01X1)$"@S"`"A-?U`>?P\9(-8`(J<#D'3_S@ +M>,]P@`"T#QJ`@N`!V.!_PB`.`.!X\<#AQ0AQ#WV%Y,=P@`"T#RJ`"0F.`ZN``>(-"A4!C"7_G_/S[09O_*EPX'CQP.'%"'6%X,H@ +MA@\``&$`P"CF`=@,IOS*(48#`@TO_JEPS09O_`]XSW&!`"0>(('@?_`A``#@ +M>/'`X<4(=83@RB"&#P``@3"D#*;\RB%&`^();_ZI<)D&;_P/>.'`X<&*(/\/ +M$R#``@1Y`"B``@`I@0(&)`P0)7S!P>!_P<#@>.'$\<#:#^__@("`H`04'S3@ +M?\'$X'[@>.!^X'CQP"8/0`?/<8``<`L;"!\`SW```,!S`*'/<40`Z+D3@86X +M$Z$%\,]P``"8@```@`-T7"-X`SW4``$(8BKZ+ODT?F)\```!`C@Y`!R$('P"!O8J^SW&@ +M```P"X&+OI^X"Z%-'YB?````0.P7`)"E>.P?`)!V%P"6Q7AV'QB0<05/_,]Q +MH`"`'409@`\>````$X&%(`P`$Z$5@;FX%:'@?N!X\<#AQ<]RH```'3@:@`\` +M``!`SW5$`&BYS!4!$`#;`-B.NPT)W@`#V`JX;:).#\__3@H@``#8D@[@!1"- +M=@[@!12-'05/_.!XSW-$`.BY6X,/Z@3!9(.S_^!X,H@80!0#:$'RB$A +M`+FF`_`7AHT$3_S@>/'`!@Q/_/_=SW"``)@1MZBB#N`%#]A*(4`@"B"`+Z`` +M`"!+&%BD`-A:<,]WH`"`'PNGSW9$`&BYSW%$`.BYLJ$#V.`>`A#B'D(3`M@7 +MH1^A':$>H:()(`!`'A@0E@S`!7,8F*0`V#8-X`4(<3`?@!_P\/#P&XSR'B`<]RH`"`'1:" +M)7@6HN!^X'@$V&D!(```V?'`X<7/=40`R+NI<"C9L@H@"\[:`-B:N-[9J7(' +MVT(-H`R*)`\,A0-/_.!X\<#Z"D_\.G`H=8#E2B!`(%H-8`?"(`(DSW*@```@ +M`-F5N27M%7@%X'H2`X9`*,T"!"6-'P,``/C/=OS__P?$>Z5[>AK8@,]T@`!$ +M!V*$X(3$>^1^I7MBI,5]H*3//'`!]C2#^__`-D!V<]PH```'R&@T<#@?L]P``"MWN!^SW"@``!% +M&(`["-\#SW&!`,03$($!X!"A)&@*PX'[/<($`'`H&B,]R@`!$!QUX4R`!``""H+@E +M>`"BG0*@#`78X'CQP.X(3_S/@K@!0*B +M`=A<&@*P`-A=&@*P`]C/<:``@!T=H<]P1`#HN1.`SW*@```@$PC>`!6!F;@5 +MH4T:F(\```!`%8&5N!6AT<#@?O'`,@A/_,]R@`!$!P*"((*DN(.X1B$!!B"B +M`J(`W<]PH`"`';J@7!I"LP'>71J"LPH)X`7)<$H)0`RX#@T"6B$R_TSW"!`!P*)HC//'`&@\/_`AUSW"``)@1&H@1"%X` +MSW"@_O`#(@K@`P#91HW/1/P!"&!#P```/\HN0WP!"&!#_\````PN0?P!"&!#P#_```XN26C`=@#HP2$ +M@+@$I!*&@+@2IA*&@;@2IA*&@K@2I@X)``!)!@_\\<#>#0_\SW"``)@1&H@` +MW1$(7@#/<*#^!`3B".`#J7'/=D0`\(7/<:T`@``$@4:&1B#`!P2A!($"ND5X +M!*$$@:"X!*'/<:T`@!\2@:"X$J$2@:&X$J$2@:*X$J'/<($`=!JV"(`+Z04O +M_*.FSW&M`(``!(&@N`2AX'[@>,]RK0"``"2"!KB`N22B)(*&(0,`)*(D@B5X +M!*+@?N!XSW&M```@`(&@N`"ASW&M```$"(&KN`BA"(&JN`BAX'[/(L]T +M@0!@*#1DC'L`*4QU!2H^`T)T!PD%!L( +M10#/=8$`0"8R)4(4=7L%*CX##0M$#A1X%PA%```E`"1`(%``"PR>)@/9&1M" +M(%$D@*;*(0($RB$A`!P;0"`*<`CO9\F`ZV-D?GB!Q'LO*\$`3B..!\MD<*H!Y5<-%1+I@,]S@0`H)ZIC +MSW2!`+@H1'\O*L$#3B*.!\YD`"1"`\"JV8'D?B\N@1-.)H\7[F3(JJL.WH!H +M@(;ETR.F`"\KP0!.(XP'SW.!`$PDBV/5\0#=$?!I@.EM@.7*)T$3[F;$>]B! +MQ'LO*\$`3B..!\MD<*H!Y5T-E1))@,]V@0!$)ZMFSW2!`+@H9'HO*X$`3B./ +M!^MD`"=/`V"O>8%D>B\J@0!.(H,':V1`)`((NF)FJJ<.WH!H@(#ETR.A`"\K +MP0!.(XP'SW.!`$PDBV/3\0#;%/`H@,]R@0!()&IB`"7,`$1Y+RE!`$XA@@?/ +M<8$`3"1)80'C(*S="Q2!E0$/_/'`&@D/_`AVD(C/<($`J%$6(`0#SW*!`&A2 +MEGI`B@`4`0$`V!$*7P'/`P:%!""% +M#P```!@C#8`/````"`PE@(\````0RB""#P``/!7*(($/``"P!`/P2]@%N!!Q +MRB$&`'X6`A$`E6*56&!X8,]RH```(%J"+.`0E!QRB"&(!B5RB!% +M(&3@$'(\`0X`SW"!`(0/`[R5?(!@2B(`($$HP07"N66Y2"$/`#.XPK@-X`\B +M$B`#%)$`!H6^#*`&"G$)((`$`^!!*)(`!H6J#*`&!-GX>`/@!""`#P``_/_/ +M<8$`N%<#H0/@(KC/HG0:0`3+R2RXQ+@8N$\@00`>HBQP`0B>!<]PH`"`+%R`WP6@!`]AR@=`A#J%@`1$[4?AP'@'Z<`(0`$':?,R0V`#0A>`)/-H;B3&ARP +M`=@.\,]Q@0#$$QZ!`>`>H<]P@0"X5P'9(J``V($'S_OQP.'%`-T,\!)M%'@` +M(($/@0!T'/8+[_X"V`'ESW&!`-0<`('E#020`-A]!^_[`*'QP/X.S_L*)0"0 +M`-X$\H#ARB9A$,]P@`"P%@"`(8C#N<]P@`"LTH3A$(#!**$`"?+/<3,S,S,% +M*3X`"B#`#AUY@.;*(0(`C"$4BPS8RB#F`53WC"%1A\H@)@)0]XPA#H'*(&8" +M2O>,(`NXSW&M``!>`*'/<:T``*A`&8`/````>,]QK0``:!"A +ML0;/^^!X\<">""`'X<6:"0`(SW6``*S2SW&``+`6(($0I2")"PG3`QMX$*7/ +M<(``K+4`@!D(W@82A07HE@U/_`#8$J6&#$_\#/"MV!"X3!B`#Y02*:5@&(`/ +ME!(II2X(``?B#N__`-E1!L_[X'CQP-(-[_L0V*+!BW6I<4H.8`:&ZRB(!``3RSW*``$#1`@U/_'D%[_NB +MP.!X\<#^#,_[,@_`!D8/X`8(=<]Q@`"LSP7M6"'.#0CP#0B1`%4AS@4$\%DA +M#@+/<(``K+4`@$`F`1QE")X$`-H*\/`F@Q#/<*8``(15>&"@`>+Q"A2#`-H* +M\/`A@P#/<*8``(A5>&"@`>+Q"A2%@!8-$H&&8H8#AB2&18;FAL]VI```1**F +M2J:%IF:FZZ8'IBBFSW&``.S\&8D!X!FIS03/^_'`8@S/^Y(.X`8!W8'@H@[@ +M!L(E01.$+0$>"'8`V0`A@W^``*S3A!.$@)@3A8"L$X:`P!.'@%P3@H`""V`( +M;?#I60_0F.HP(.;_S)<'CH`-_V[^][SWH*<-(+;_RI<0'G^/$R"^`` +M`=B]`\_[\!1*%'^C/=J```#`('H`?````H(X)8`P> +MV(H)8`P>V,((0`K_V<]PH@"`>2N@#!Z`'P```*!N"6`,'MAF"6`,'MA*#&`( +M$X4I`\_[X'[@>.!^X'C/<:T``!A`$0"&I[A`&1B`8Q$`AH>X8QD8@.!^\<". +M"L_[`=T`WJEW#?`)[>X-;_P`W0?8#@O@``#9(@YO_,EP`>8E#I44SW"``.05 +MR&#?"!*)=>__\`-\JV.8*X``"V>WQM@U/_`'9SW"``*S1I0+O^RR@X'CQ +MP.'%`=U-"%$`SW"``*RU`(!!")X'SW"``"0-`8`U"%$`SW&M```88Q$`AJ>X +M8QD8@$`1`(:'N$`9&(#^#$_\SW&```S]!8D!X`6IJ7`%\#H/S_\`V%D"S_O@ +M>,]QK0"`%0.!A2`"`0.A`X&BN`.AX'[@>/'`P@G/^P#==@G@`*EPH@M``,]P +M@`#LTS:8SW"``"S\*+`5\``ECA^``(@0^@G@``".`(XB"N```-EJ"F``J7#^ +M">```(X!Y:]]W0V2D3()X``!V-T!S_OQP,]S@`"L^B*#SW"B``!PBND($`&& +M$0D?`,]Q@`"0%""!">DC@T2#"+E%>9^Y0AA8@,]P@`"LM0N0$0@?`48.``J` +MX"P/0@?1P.!^\<`6">_[!-FCP0'=BB#!+XMVC@BO_/'`L@K`!NX)S__""X``V@R` +M`/X+``#1P.!^X'CQP`X(S_L`W13PSW"!`*@JMG@@@,&`SW"``*RU`(`1($"` +MS"8BD`7RH@L/_T!^`>7;#5230@P``$4`S_O@?P#8X'\`V.!^X'CQP,8/K_L( +M<80H"@P!V@`A@'^``+S&0*!2""``*'#/=H``?!``A@CHSW"``'@0`(@C"0`` +M`-T,\,]P@0`8*_`@0`.`X.(@`@`!Y;!][0W4D@/P/@G/_P#8`*;_V<]P@`!X +M$-4'K_L@J.!^X'B$*`H,`-D`(8!_@`"\QN!_(*#@>.!^X'CQP#(/C_L:<`#= +M"(5TA0HB@"^``!3]`!*!((HA"BP$*7X$SW&``'#&,"%"#AA@%'@`(@0``A0, +M`7MC='MY8LJ14R0%$D`N3!+/=@,``/[$?`4E!0//=*<``$@<'$`1`!0/`2F1 +MR+\)N<1YY7D]I%A@`IAZ8BN2R+@)N<1Y)7@&I"8)P`9HA0`2@2!`(``J!"E^ +M!,]Q@`"TQC`A00Y4A10AS`!@G%1YAIS+N\N\#+R%>V"@0YDIF/'`>@Z/^\]V@``4_2"."'6,(<./RB""#P``RA/4#,+[Q@S@ +M!JEPH*X`W@[PSW"!`!@K\""!`\]P``#X@A!QXB!"``'FZ0[4D@'9SW"``'P0 +M(*#/<(``>!"6"^`&H*B-!H_[X'C@?N!XX'[@>*4"S__QP$"`SW&``*RU0*$! +M@&(+H`,!H>H-S__1P.!^X'[@>/'`8@MO_Z'!SW"``,SZ!(@$V4#`BW!B#6`* +M"MJAP-'`X'[@>/'`8@[@!P'8$@@``%8.X`<`V-'`X'[@>/'`G@V/^_8.H`:^ +MP5IPBW!R#J``.G`$V%K``=A"P`#=2L`@V%?`BB`9`%G`SW&``(`)`(%,Q=VX +MG[@`H0*!G;@"H0;PY@V@`,EP`>55#941&@DO_TH@0"#/<($`["*N8+(-H`#) +M<,EPV@V@``#9CN;"(`XD`-_1#Y60`-D/(<$#!"&`!!D)`0!#QT3!T@J@`"IP +M"G"I<68((`#I<@'G[?%=!:_[OL#@>,]Q@0"@*N!_"&'@>-#@`-G+]HP@`H3* +M(6D!#O;TX`39RB'L``CPM.#*(:D`!/:-X,HA:0`Y831Y`"&`#X``D/K@?N!X +MSW&!`%@KX'\(8>!X\<"R#(_["'EPR7$.""``J7(%!8_[X'CQ +MP(8,C_NHP5IP&G$Z0`A@"^``(SZ.&"HJ*:H=02O^ZC`X'CQP!X,C_M^#J`&`=X:#\__ +M0@Z@!@AU@>#")H$3R7``V:8,(`A`C#"`(08W)<`#9,@L@"$2-R7`! +MV2H+(`A%C0#8C@@@""*-`=B&""`((XTY!(_[\<#AQ0AU&@CO^P;8`=G/<*<` +M`$0PH(H@$@R>#F`#`-E:#&`#J7`9!(_[X'CQP)8+K_L@V*+!SW=$`.#!SW9$ +M`/C"BW6I<08,(`:*(@0&SW&``$SR`^@!P`+PZ7`0X4H-H`I&VB/8J7'B"R`& +MBB(,",]Q@`!L\P3H`<`#\,EP".$F#:`*R-JI`Z_[HL`0>14)DP"$*!@$`"&` +M?T0`Z(<+\(0H%0D"(8!_``#("L=P1``(E.!^\<#J"H_[H<%6"&_\`-_I<.X* +M8`8"V0HB`*#*(,$C!/($$A`@"B&`+X``K/<*<%@A02H2#*`*"-K/&02@!`<.Y02@"`L.Z@N',(JR`Q_;/<```PA3Z +M",_[%X9!*`$#P[DPN%,@P@""X',(FN!RB"*#P``Q!2\",K[8!&!H-#ARB")#P``Q12D",G[%X9!*`$#,+C# +MN<.X`"!8`$HD`"`&\$`D0"`O)`<@K0P#)DPD@*!*)T`@PB?*)4HA`"`%\$`A +M0"`O(0<@W0F3H`T/$"`%V`<)4"`$V+IP2B8`("CPN@B`!@AV10@!!<]W@`"0 +MM8X.[_]*)T`@@N;)9\(GRB4BL`,3@"`DN",(@04$$X`@P[@7"$$$:G#)<2IR +MI@MO_0##@"7"&K!]FG9`)E8@DPY%I0`<@#4$\(`EPAJP?0`@4R,`$X`@A^@( +M$@$A@B&%!>L-1)#'Z'T!K_NAP.!XX'[@>/'`0@F/^YH*H`:")`(Z"':+$%#%3\<'\`L.7A`" +MV%#`3\59QT['6L>,',`S5L58QX0*(`@`0\!$P!@<@#\`@```'!R`/P"```!%QR`< +M@#0"V$G`2L<`WB[PR@YO_@IPSW"G``!$L*"*(`<-7@M@`P#9SW"@```\6!`1 +M`,]P@`"$M0"`((`#V`RX"2$``$H)K_L#V0AR,G#*(((/``"U%+@.HOO*(4($ +M$@XO_$`N@!(!YJD.E)#/+` +MXK7W40"O^X`D`CK@>/'`X<7/<(``%/T`B(0H"@S/<(``<,8N"J`&,"!-#A5] +M.)42E0JYR;@$(8$/#P``_"5XSW&G``!(%:%9E1.=";K(N`0B@@\#``#^17@, +MH2$`C_O@>/'``-C\'`RP`AP$,`X((``(<:'`T<#@?O'`A@]/^PAWY@F@!BAV +M"@Q``,8)H`8(=15])H4`V/EA+GFIA;H-[_SI"Q!V_[`:G@>.!^X'C@?N!XX'[@>.!^X'C@?N!XSW"``!#WR0``".!X +M\<`>#T_[#@D@``AW`-T)\`#9SW"G``!$,*`!Y:]]0PV3$`#>2@B@!@\F3A/$ +M>.\.`9#F""``J7!""Z_[!M@`WM$.TY#/T"+J7#I<2H)(`!ABP'F +MT'[R\2T'3_O@>/'`K@Y/^PAW.G%H=@H@`"%2#>`'2''/<(``@`E`@*W9$+E! +MH0&`2B(`(`*ASW6G``!(4R'`(H3O"*4#\`FEV@JO^P;82B%`(!$=6)0`WP7P +M$1U8E`'G&P]5$0C84@E@`P'9>.C/<*<`;$0`@`GPSW```*0H"-G*#*_[!=I* +M<`"FSW"G`'!$((``&$`@`(8:V8H+8`K)<@`0`"`:V7X+8`H*.!^ +MX'C@?N!X\<`*#D_[OL$(=XMVU@Y@`,EP0\H5Z7@K@!T"A@\=`)!`TR7`@V0#:Z7.J#N__ +M"B0`!`/`SW6!`#0P`*4$P(HA/P@$IE0(4\8^&%0GP8%000`B33$Q`5!1``(!(!I84"(E(A`B)2(V)Y0GD_ +M9P(D`0`"(4$!/65"+]07Z7"*<>ERK@]O^XIS.G`:<4(MU1>I<*IQJ7*:#V_[ +MJG,`(1&@0BO8)P$@4"!J<`MQZ7*"#V_[BG,[<$'!0BK6)TIPRG&IER3@]O^XIS"'=:<6IP"W&I80`6S1``((,/@`"LX]0; +M0@,.%L\0SW6``(SD"B2`#X``K.7B&\(#%^Q;81P3PP!=97"M7V$F%\\00"$# +M"/JM5'L0$\T`SW>``*SD5'^DKQ$3PP!EK^@6PQ``)`T`O!W"D/86PQ#*'<*0 +M*'.`(P@`>&`$$,Z`V!V"DQ/L`".$`!(4Q8``(HX/@`",Y08>0A$<%,^`6V/P +MKB83PX!ZKK00PX"`(0<`B!W"$(#DPA#`@)8=`A"W\EAA$!#````B@P^``$SF +M!*M981H1P``.JZOP;K@/"/4('7T!V@D('@``VIAR$PAU"$$HC`!3('Z``=L" +M\@#;5"%""#,B`@`*)X`/@`"LY0`G"``6&(*0,0P0`%8A`@-`(@X",R9/$P`E +MCA^``.CDX*ZT>AH2S@#/=X``[.2T?\ZO&Q+"`$^O)^LH@P2 +MS@#/=X``3.64?\"O#1+"`$&O*':`)@@00"8%%]A@,!#"@$`FAA($&((05A#" +M@"H8@A`?#!``NF9\$L^``"="`[YF4!K"`XX6SI!B&H(#$.M6(0X-FF8`$L(` +M`"2/'X``#.94KYYF"A;"$%ZOY!#`@+@8`A`3#!``,R9"`P`E@!^``(KF0*@) +MZS,E`@,`)(`?@`"0![R#N`"C+D` +MI@&&`-GF#N`"C+G5`&_[`:;@>/'`>@A/^SIP*'8@@`"&2'<%*'X``-V,O2]P +MO@[@`JEQHGBV#N`"!-FX8`"G!!$!(`&&"B"`+T0`F(8X8!QX`:<`$``@7@AO +M_!MX`!`!(%IP.WDO($D`C"`%BLH@30#*(8T/``!H`2@)3?M:W#8(;_P.(0`# +M&G`$$0`@(88B>"\C`2``$0`@#+A.#N`"((:B>(8,[_P$V00HO@0(=@#9+W"B +M#._\C+D$*SXD'64`V2]PD@SO_(RY!"N^)`)]`-FBIR]P@@SO_(RY!"X^%`AU +M`-DO<'(,[_R,N;A@_0:<4(HP0<(/'`V@XO^R#9LL%: +M<(K`7@[O_!IPBW7/<(``>`RI/'`S@T@``#8BB$/",]PK0"`HB&@ +MSW"M`("L,:"*(0L`SW"M`(!B(:#/<*T`@&PQH,]PK0"`'G`8@`^*HI@9SW"M +M```I,!B`#XJBF!D2"```?@T@``'8T<#@?N!X;08/_/'`G@TO^QS9M<%*(@`@ +MBW`B#>_\&G`$V&;``M@9'`(P!M@:'`(PSW"``.S35I@*(X`O@`!L^``;A"`& +M\/(-(`!`(E(@T0I5(<]Q@0!$*S(A@`3``8\`6":_^`-\#\`'GW0_UD"/` +MW@T@`.EQSW"!`$0?\"#``T''0,#/<($`$![P(,`#3B>1$$3``-W5#960`"%! +M)+AE1"H^+S1Y%G@986)Q`"%"#H.:\=S@`"@%4*2@J,G<2&10:,@HU)M +M`<%4>C5Z8G(`(D$.-)DG#B`&#R9.$\1X)0X! +M$$+%A\:1P@IP'@LO_,EQ+R&'!*]Z+R1'!,EPC@D@`"'#`>6_\>4$+_NUP.!X +M_N``V/'`Q@X`!LH/S__/<8``%/T@B80I"@P`(8%_@`!PQE(,K_\`H='` +MX'[QP#H,#_L(=6AV`H'2"J`'2''/<(``@`D@@*W8$+@AH`'9SW"G``!$,*`\ +MV/X.X`(`V8;M`@W@`LEP"O#)<`T-41`F#<`"!/"F#,`"700/^S*01(`*N<]RIP``2#6BD)#/<0,``/YC@`F\R+LD?(5[;*)@@(J0R+L) +MO"1\A7M]HF*`CI#(NPF\)'R%>V:B88`,D,B[";@D>&5X!Z+@?N!X\(=12Q"B2`#X``K/L4%```..@*((`?@`#8%0`0 +M`!`OZ+AE6F(4>%9Z6&"88!MC`I,Z"R_\(I?8<`*3M7[`<`*S`YM&"R_\))^X +M<`.;H'`#LP&3%@LO_""7"'(!DT`OP0!88`&S-'D`)@`1&.`X8,AQZ@HO_*AS +M`-D`&$`0#_"]95IBM'U6>EUE`8>\9)MC`K,`AP&S`H<#L\$"#_O@>/'`1@H/ +M^^()(``(=<]WIP``0`&'@+@!IQX/8`<-A3.%2B!`(`KIU(4`V,X(H`?)<0'8 +MQ@B@!\EQ#H7/<:T``(-@&8`/```("%-H"[@%>L]PK0``0UB@3X6*(T0`>*%` +M*@,"97I8H'&%8!F`#P``$!!4:PR[97I8H$&%&^IRA6`9@`\``&!@56L-NV5Z +M6*!0A8HCF`%XH<]Q@0`$(_0A@@!;>0FZ17DXH+(+X`(0A0"%%.C/<(``@`D@ +M@$*%SW.!``0I]".#``0A@0_S_^?_4VL2NV5Z17D@H">%B^ECA0#:`MB%ZP6E +M1J4#\`:E1:49"9``!85R#F`')H4%A2:%`@]@!TB%(X7/=J<``$04A@HA@"^G +M``!(MKBWN!:Y!7DTIA2&)(6XN+FXNK@8N25X%*;Z"V`'`=@6A0SH%X4/>0]X +M"+D$(8$/````_R5X+!D`(!@?`!0:A52&+R$)`(#@T")I!<\B;`4$(H(/X/\! +M#E,A`P(,NR]Y.WDE>V5Z5*:&"<`"$H8LA48@@`$[>25X$J9@%0`13@O@`F05 +M`1$KA12&2H4$((`/___^\0FY17DE>!2F,H85A:"Y)7@2I@.%`-D/(0$`SW"E +M```0(:`;A3V%7(4$N5MZ17DE>',9&"#-``_[X'CQP.'%`-W/<*```!"IH.X+ +M``?/<*0``$2IH+&@`-A^"._^CKC!``_[\<#AQ<]U@``T$IWHC@G@`@#82@A@ +M!P#8SW&``#@20($`A8#BSR`B`=`@(0$`I<]PH`"`13`8@`\`(``!`=@`H2KP +M6@G@`@'8$@A@!P'8((55"1\!SW"@```(`H``VL]PH`"`14V@SW"@```?'(`I +M"!\`)0D>``QP'0@?`\]PH`"`13`8@`\`(````-G/<(``.!(@H&H@@`'/<8`` +M/!)J((`!`*$9``_[\<".X,HAC@\``/\`'`NN_LH@+@#1P.!^\<".X,HAC@\` +M`/\`W`JN_LH@+@#1P.!^\<``V\]RH```$&FBCN`!VL(BC0#\'(JP`1P",`(< +M0C`#',(P!.EBN`$<`C``P0'85@[@!?_:1@[`!:'`T<#@?@AQSW!$`+B`!0$@ +M"A[:X'C/<8``;-(:B9'H2I$,F2N1&F(X8,]QH@"`;4BA":'/<8``[/P'B0'@ +M!ZG@?O'`Z@[/^L]PH@``;`*`"B"`+X``[-,$((`/`!```$(@`(#*(&(`SW>` +M`&S2&J\:C\]U@`"LT:+!W0@1`,]P@0`,(2"``8!`P4'`BW$>V"H/8`50V@CH +M`<"I<8`APP;&#^`)3]KN#F`%`-C/=H``D!"`X,HA@@.L#^()RB(B`:"&4R7` +M$('@S""B@`KT!"6^GP``\!\DO=,E(A(#].G=BW$BV-8.8`4(V@[H`<$`F001 +MP0`=98PA_X^P?0;R+WG)<'(*#_O/<(``K+4!@."X`-@?\@"&SW&``)+2+;@- +M>!QZ`>`<>#,A```S(8(`6&`<>`UX`GTL$,`@L'T<>@'@''@S(0``,R&"`%A@ +M''@->*JWJ[<,MQJ/"^C/<8``K+4`@:"X`*$!@:"X`:&N#L__)0;O^J+`\<#A +MQ0AU*'+8X#,)B61RB"&#P``*C3*(<8#;`LF^\HBA@,]#5`0>0W1$,]U +M@`!X*]9]3"!`H/'`.@SO^C1H"'8V><]S@``D)4`C +M``4@8`OH`-@F$(P`SW*!`%0P`H"`H@&B`J)`(P`%.&"&"Z_\D-DR"F`*R7`F +M#``*>@K@`,EPA"X"&@`AC7^``*0H'@\@"D(E`!L6#R`*0B4`%`X/(`I8)<`9 +M_@D`",EP,@G@!`#9,03/^N!X\<"Z"\_Z"'4`WL]P@0"`2]2H<@G@!*EPA"T" +M&@`A@'^``*0HSW*!`)0:N!B`@P;;R!C`@,]Q``#H)L080(#,&$"#T!B`@-08 +M@(/D&,"`SW$``/`FX!A`@.@80(/L&("`\!B`@V"@SW$``/PE_!A`@*&@0J!D +M&("#!=ET&$"`SW$!`.0[$*`@%`"&-?X``I!P` +M(8%_@`"D&@"!/8%IC4`ID`+/<8``D!%`@2"*30M#`&J-(HI%"T,`)MD.#R_^ +M`]KBH,]QH```(#N!XGD_N5(A`8`#\@)WXJ`@A02^)J`4V2.@((#6?@`F@!^` +M`%@E(*!^"F_^#-@`V.4"[_H0K?'`4@K/^CIP*'5(=MIS"B<`(80H"`4`(9-_ +M@`"D&G03&"``$Q`@?!,9(`2X%G@`((\/@``X)0IP:'&2#B_^`-I:<`"`0"B5 +M,@"G!!^`%0IP$MG:<78.+_X`VAIP`(`4'X`5!*?/<*```"`[@$`IE#("\*)U +ML7'^!\__`_""=M%Q_`?/_P/P`B5-%0`A0`40=?8'S_\#\`(F#A4`(0`%$';V +M!\__`B7-%0@:0",4&@`FHJ<")LX5"!B`(Q080"8"A\:G91L8("IP(@^@!`'9 +M"!,`(#4(T0&0$P$@*'"&(/T/C"`"@`'8P'B,(?^/4R&"`07R"N@1"A4$!NH( +MV1@:0"`8&$`@D0'/^O'`;@GO^C#9"'77:-1^"B"`+X``O/T`((\CW@BO_.EP +MSW&!`)0:`-@`()`C`!@`(`;8!*?/<```^"8#IZ6GF0'O^B:G/0)``/'`+@G/ +M^@AUA"T(%<]P@``(&S`@0`[/=H$`5#`EZ`.&B^C""F_^J7`(D`A +M#`5<9(0N"!4`(8]_@`"D'&"$"B%`+D`D`AA`)Q(230C!`"#:SW"@```=3J!* +M(``@`H$/()`C!B``!`*A#X^`X,H@@0/\"^'[RB$!`0#>SZ]6#Z`$"G`)&H(C +M(H4`(8`O@``X'""@-_`DA!\(00`0V<]PH```'2Z@`=@1KP+8B@MO_LEQ)_`@ +M@D<(00"@H@6%(H4*N!EA#@WO_\EPR7"B#B``BB$$`!?P-&U986B!(0C!`&F! +M`-P5"U`&%0N1!MR,)!2#$`D.P1``VVBA`>7=#920(0#/^N!X\<"B#X_ZI,$( +M=80H"`4O=@`FD1^``*0:8@R@!&01%"`;<``FDA^``*0<>!*0H*H.8``*<$#` +M=@H@"JEP^G`*(X`OH```($T;F*\````0QW:``"0;$89*)0`@".CGR1`@0`/G +M&ABPAO#B#"`"J7`AZ`^&51$/)@9_YLE;&5@E$"!``^8:&+`2\"\IP0-.(8`' +M+R8'(`Z&$">/%1`@@`4.IJEP/@I@`,IQ\.\\'D`53@P@`JEP`,)`)T$AJ7"! +MQ]X-(`/I,]Q@``X)0!A%>@`VFP3`R!M$0$F +M`H(B>/@1`2/'`3@Z/^@AV*'=>"2`#`-D(=1GO5P^1$(0M"!7/<(``9!LP($`. +M#PB/`VX*X`K)<`GHSW(``."JJ7!*#V``R7$5\`#8#R"``[H+X`H?V80M"!4` +M(8!_@``D&RZ`$"&!@RZ@^`HA`LH@00-1!H_ZX'CQP-H-C_H(=QIQ2'8H<$8+ +MX`H$V8#F"'54#F(`RB`"!(0O"!4`(8!_@``$'`;M+RU!$TXE@1<#\/_9"0:O +M^CNH\<"2#8_Z"'/$_#O7@H@`JEP +M0"!!(8'#J7"."R`#`,*$+0(:`"&.?X``1"CB#^`)5B:`$MH/X`E`)@`=`<`] +M"%$`"PP0(`L)$"``V`[PN!,`(,]R``#PK`\@@`2X&P`@J7`Z#F``2G&2Z!\, +M$"!*<"8((```V0SPQ!,`(.?HG@D@`JEP!/!N"2`"J7"!!*_ZI,#@>/'`.@R/ +M^@AV*'<`V4H/X`(:<0AUSW&``!`A.">_ZBB"$ +M!@:')(<1VPL)`0`3VQ1X!J/'`7@F/^AIP![@4>``@C@^``*3]7(;/=(``*/X$(D,`@.(!W``!D@.#*),$3`O(!W!R&)G@3%B +M&0E>`,]QH```(#N!EB$&`"8*(``)V@3P)@D``-'`X'[QP.'%H(%&"V``!(G/ +M<*```"`[@*EPEB$&`/X)(``+VFD`C_KQP.'%H($7;11X`"""#X``O/T(@HKH +MSW"@```@>X`'@F)X2"````BB_@I@``2)S@@@`*EP,0"/^O'`X<4H=<]Q``#T +MM`2-$-HB#&```=NN""```(41`(_Z\<#AQ4>!`(&DB0CJSW*``,`0\"("``3P +M!=H*NC"1AB'^#,CA"?+/<:```"`[@5EA:@D@``;:$VT6>,=P@0`D`RV`CNDH +M$(``%0C1`,]Q``#$N*EP$-J^"V```=NQ!T_Z\<#AQ:"!%VT4>``@@@^``+S] +MSW"@```@>X`'@F)X2"````BBSW(``)2X!(E(<1#:N@M@``#;#@@@`*EP<0=/ +M^O'`X<4'N!1X`""-#X``)/T>"N`)5B7`%`#850=O^E@=&!#@>.!^X'CQP,8. +M3_H(=H0H"`7/<(``^!LP($T.`-\+\"\H00-.((\'[W]J#:_[Z7`0)`)6"#`*<]R@0"D!P*")'@"H@.")'@#HLEPQ@SO_XHASP^!!D_ZX'@'N!1X +MQW"``"3^4H@)"G(``-DSJ.!_,JC@?N!X\<#Z#6_ZN'"8`X\P@(8`$]`"'G^@"(D``"PA2`$`B`04GIX0M"`7/<(``'!PR($`. +MSW.!`%@#`[@6>`!CB>@&AT)Y!(!`@%EAU@C@">EPR:>I!6_Z6!V8$_'`.@U/ +M^@AU*'8'N!1XSW&``!#^"6$3;A9X`"""#X$`)`,(Z0V"@>`L#*'[RB!!`P#8 +M#:*I<,(/(`#)<:EPR7'""R``"MIE!4_ZX'CQP.X,3_H(=BAU![@4>,]Q@``0 +M_@EA$VT6>``@@P^!`"0#".D-@X#@N`NA^\H@@0,!V`VCJ7#.#Z`"`-EN#R`` +MJ7')<*EQ<@L@``G:$05/^O'`D@Q/^AIP*'?`@:2)%VX4>,]Q@`"\_0`A$0#) +M<#X/(`"I<3$(42`,AQD(4`#/<0``Q+BI"6``J7`<$0$@ +MR7!6#N__+!$"(*$$3_K@?N!XX'[@>/'`-@Q/^@AU*'<`WD8/H`+)<>]_&G!! +M#U$0$VT6>``@@0^!`%8#P*D*<+H*K_NI<<]PH```(#N`"G"6(08`!@[O_P7: +MSW"!`,!*\"!"`ZEPR7$,\(PG@I0)\L]P@0#`2O`@0@.I<`+90'HU!$_ZX'CQ +MP,H+3_H(=K=HM'W'=8``)/X6A2AW@.#*(($/```$`% +M`=B&Z1>ER7":#"``0-G)<#8*K_OI<<]PH```(#N`R7#'<9P``$!^#>__"MH` +MV`:E"*6*"J_[R7#)<.EQ+@H@``O:YTAP +MAB#^#,C@`=K`>E$A0*,!W<(E01,`V)=NE'P`)(\?@``D_L]Q@``@_@FG&0T0 +M`)EAH*&`X@';G`SA_\H@@0-H<#3P#.O/<:```"`[@<]R@`"D"5Z"0GDIIRCP +MA"X(%<]P@`"L&C`@0`Z@IP<(T`$1[0`D@!^``(C^)H`D@2"!^@V@"8`A$`#) +M<&8+(``"V03PL@H@`,EP`=B:<(;M`MBR#>_]R7&*<"/HSW"``*0)'8`FASA@ +M!J<-"Q`@SW"@```0&8#/=8$`8%`8'8`4'!W`%"`=1!0B'004R7"J<=H((``$ +MVD`E`!:&"2_\#-DY`D_ZX'CQP.8)3_JEP28+[_\(=K=NM'T`)8\?@``D_E:' +MSW&``.S]2B-`((L*$0"X83IP0,#/<($`1"U!P,]P@`!T"T+`SW"``'@+0\`` +MV%IP1,`&V!IP`]D-VDIS"B2`#T0`_*X*)8`/1`"0T4HF@`CV#6`""B>`!,]Q +M```PLT((H`(J<`8(K__)<,]P@`"(_KE@SW*!`)0:N&``&(`$$!D`!,]P``"L +M)P.AQ:%&H5@?P!1<'\`4R7!&"B``0-F)`6_ZI<#QP.'%=VAT>P`CC`^``"3] +M5Q0#%A7K\]U@0!<`V-EA.L;"A$#SW.!`&!0`*,DJT]Y5B1`%C(.8`)H +M`.X%GC/<8$`5@/@?PAAX'CQP-X(3_H(=1IQN@N@`@#>@>#*(((# +M&/3/<*```"!;@$`HSR#/<($`8`/V?^%@![W/<(``'/ZT?:!@.&`0<@#8RB!O +M``$!3_HO>?'`$PE1`,]Q@0``2_`A`@``V0KPC"&"A`GRSW&!``!+\"$"``+9 +M0'K1P.!^X'CQP%X(3_I:<"AW`-YV"Z`"R7$Z<`>X%'C/<8``O/T=8<]PH``` +M(#N`"H4`(%``'P]1$$`JP"`6>``@@0^!`%8#P*DJ<,X.;_M*<2IP"G$F"N__ +M2X5I`$_Z\<`2"$_Z"'__`-H<\!,.41"I<.EQJ@[O_P#:"/#'<0```("I<-8)[_\#VH0M"!7/<(`` +MK!HP($`.A^#\#F'_RB!!`QD`3_KQP*H/+_H"V0AW`-T'N!1X`"".#X``)/Z@ +MIC(.K__I<*&F0-G/<*```!TNH`+8Y@KO_>EQX0``@C@^!`"0#`(8!WX;HK@H@`*EPX*;NI@(.;_NI +M<*$'#_KQP.'%"'60X,H@B@\``%T#G`UJ^LHA2@/>#6_[J7``VA-M%G@`(($/ +M@0!<`X$'+_I`H>!X5VA4>@`B@P^``*3]7(-%>8T`(`0\H^!XX'[@>.!^X'C@ +M?N!XX'[@>.!^X'C@?N!X\<#*#@_Z&G`H=0>X%'C/<8``$/X)84AV@N$!V,!X +M@.`!W\!_$VT6>``@@@^!`"0#!^D-@H'@N`UA^\H@`00`V`VB"G!*"2``J7'/ +M<($`P$JU>,"@"G"I<4(-[_\'VM4&+_KI/'`,@X/^CIP*'7W:/1_SW"` +M`!#^Z6!*($`@@N$!V,!X@.#"(`(D\=S@0`D`TAV".D-@X#@^`QA^\H@ +M000!V`VCJ7`.":`"`-FN""``J7$`)X`?@`"(_AX)@`G/<($``$NU>,"@*G"I +M<9H,[_\(VB4&+_H*,]T@0!D +M`P!D@.`8#&+[RB!"`TQ]SW"``(3^,"!`#@?H)X.I<%X/K_]+@Q`F3A/4[@#8 +MM04O^@2G\<#AQ0.Y-GD`(8T/@0`D`RV%D>DW:#1YSW*``!#^*6(="9$`+@@` +M`(KH,16`$!$('@!$'8`?````$`3P`-@1I7T%#_K@?N!XX'[@>.!^X'C@?P'8 +MX'[@>/'`X<6R"&__"'6I<#X.(`0`V48+K_VI<`H.K_^I<$D%#_K@>/'`X<4S +M:#9YSW*!`%`#(6+/=8$`8%`CI98((``'V4`E`!(J#._[$-D9!0_Z\<":#"_Z +M"=H(=<]Q@0`H`P.X%G@?8;@V"&`"2B=``,]Q```PLP(+ +M8`+I<&;%J7!*#V`"R7%%P(7!Y@QO^\EPC00O^K+`X'CQP!(,#_H(=1IQSW:! +M`&!0!*X#N!9X`""1#X$`)`.I@7"!`B0"@!)A"] +MI7F*(`0$5@IO^N5Y.!$`(`GH+R$'!$`A`"'Z"&`"R7(=!`_ZX'CQP+8++_H! +MV1IP)!*/`+-HMGW'=8$`)`/+A8'GPB%!`((/[_\%X0?N`-@+I0IP8'[I<>T# +M#_K@>/'`A@L/^L]U@0!@4".E`-DHM26E"B'`@$2URB%B`$X/[_\!X<6%0"4` +M$MX*[_L0V<4#+_K)<.!X\"N_[$-F%`R_ZR7#@>/'`!@L/^@AU`[@6 +M>``@C@^!`"0#J7``WPH.8`+I<1IPJ7#2#N__"-GKIC`>PA,Q'L(3SW&!`*0' +M!8$0($`#!:$*<(H-[_^I<24##_H`VS-H-GD`(8(/@0!6`V"JE0;O_P39X'CQ +MP*8*+_H9V,]W@0`D!;()K_VE%PX6%_`O*($#3B"-!Z]]$VT6>``@@0^!`"0# +M2X$'Z@#8"Z&I<&!Z,!&!`!`F3A/L[@#8S0(O^J4?&!#@>/'`5@H/^@#<)(S/ +M=H``)"5T:79[0"8-%;MCX(-`(PT(:0C!`Q=I%'C/!_`*'QP%()#_H(=80H"`4`(9!_@`"D&@X-+_]5 +M$`XF9!``(`[H#?`O*($#3B"/!^]_J7`^#*__Z7$0)LX3]NYD$`$@SW"!`%0P +M(Z#B"^`#J7!M`0_ZX'CQP.'%"'4$@`/H!H6%Z&H/+_J*((0&)(4&A0L)`0`4 +M>`:E70$/^N!XA"@(!0`A@'^``*0:.8`&Z0#9(H%E&%@`X'[@>/'`X<7/=8`` +M0`>I<*8(8`H!V;(*0`$`A<]QH`"`1!$(40!D&8`/``8F``3P`-@9H0D!#_KQ +MP.'%SW6!`-PNJ7!R"&`*#-G*#N_\J7!V"D`!Z0`/^O'`5@@O^@+9@B0"-8MU +M4@A@"JEP=@Y@"JEP`,`!QUIP+R0'(,]U@`"D&D`E$1**)@@5^,\`V1IQX@^O +M^ZC:BB$$"PIP!O!2:$-R_QI8@`'@]P@4@0,:6##]&EBP_AI8L!D/4!"=#Y`0 +M@^?$\@W8"KAV#B_ZZ7'P\#(/X`5*<`0LOB,P(5`N'PP1($P@@*',(.*AS"`B +MH@?TSW```"PT0@X/^L]P@`!0*_`@`01`+)`@`"(`-.X86(`$++XC)W7O>HIP +MJ@S@!4`E`1[&#>`#BG``()`F[A``IB*`8'F*<".%BG!V"B__Z7)F#&`!BG`> +M#2`'BG"R#R_^BG#^"L`!K/`$++XC`"53'D`D$3)`(P`B*G$^"2`)%]I5)%`V +M52-`)@IQ+@D@"0S:@@[@!4IP"!,!(`+"4''*(((/```<-+`-`OH$++XC`"52 +M'N]ZBG`>#.`%0"(!+CH-X`.*<`P2`"`#P1L(0`"*<.X)+_\#V@P2`2"*<.() +M+_\!V@0LOB-`+(`@0W#N$`"&)W6#@"IP0"4!$@IR525#%F!\"B0`!2X*8`** +M<`]Y`-H/(D(`C"#_C\HE@A#*)2$0+@I@`HIP!7T.\"\H00-.((X'$FY#<.X0 +M`(80)8T3+H!@>8IP=@D@!E45`!:N""`&2G`N#"`'BG"B"6_Z`-CN'AB4M@Y/ +M_18(0`%1!N_Y@"0"-?'`^@WO^0+9M,&+=^X-(`J$P-()H`($P`HA@"^``*0: +M!,%`(0XBBB4(%2$(4``O>*QX`"%#+D"#SW````,T*+I/>E8,+_IA@R3`4\"L +M>#`F4AZ2P*8-(`H!V07!&0E0`-D)D`#C"=``SW```!4T%@P/^G3P$L$`WI'A +MRB"&#P``)C0`#`;Z"-AR#2`*!MDOEA<)W@-`A`$P!+!`:8*((`O@0`\)?0@0"`1M@.&C"#_CR8>0A`.](H@!`L#IL]P +MH```(!N``J8/ED4@``,/M@^6$0C>`L]PH```(!N``J8Y"E$BD\'>">`#"-@6 +MZ`00`"$`VA&V$\"L>``A02X9@4.FQW````"P`J8LV`:F_]@/'`<@SO^0;9I\&!P'H,(`I:<`'! +M+R!'($P@P*#*(.8`[`HF^L`H)@//=H``M`]`*(`@%'A`)@$9`F&*)_\?`B+` +M@P+!RB!B`!\)4`""X0'#D_*#X7H"`0#/<```!3"Z"B_Z:'*(\`CHSW````$P +MJ@HO^@'"`<%*(P`@+R!'($`H@"`4>-A@^G`IH`HAP"1J=2KP%2)6)`@6`B!) +M"L`#0"-3("\DAR!,)$"ARB"&#P``%#!D"B;ZRB%&!!4F%14`%0(@\7+*(((/ +M```*,$@*(OK*(0($"!8!(`\E#14`'4`@0"%1(*\)U*`H'T`C%PL1(``2`2#/ +M<```"S`>"B_Z)!<"(!02`2`O(4<@3"$`H"^`%`=D0)4T4[^TF"^`$%!,`(!8*+_I*<.GP!.@1"X`` +MSW````TPE@DO^FAQ2B``(`04E3`*(0`D"G4*(P`D!_`@H`\C$R5`(5$@2PG5 +M(!4B5B0(%@$@\PG`@R\D1R`9#'0A0"!0(,]P```6,$8)#_H(%@$@%28`%4"` +M#R4-%<4*P(-0<``F$1`H$0`@I7BG>)IP&/`O*`$`3B"0!PIP$@O@!0#9\"8`%!D( +MP0,`$@$@SW```!`PV@@O^B@1`B`0)@`D"B8`H.?U*!E`(Q02`2`O>!4F$1`- +M"#4!%!$"(#<)@`#/<```$3"J"`_Z%?`O*$$#3B"0!Q,+#B05)@$45!E`!7(( +MX`,`@0IPI@K@!0'9$"4-%.[MY@@O^DIP$/`O*`$%3B"0!Q4F#12.".`#`(7@ +MI?_8%:40)!0DY0P1H/()X`04$0`@/?`$Z!$+@`#/<```!#`^""_Z:'%`*(`@ +M%'@`)A(0+!(`(!4F#1#*">`$!87EI2+P+RB!`$X@D0<5)DT4`(7Q<,H@@0\` +M`!(P``@A^LHA`00JZB0:P",`V3JF*'(H

,]"Q4!$FL4>-A@B8#U#,"3"H!VZ"\M`1!. +M)8P7A"P(%<]U@`"L&C`E31X+#9`1`>):I@#8$"```^[Q0,&+<,8)(`$$V2D! +M[_FGP/'`^@CO^0;9SW9$`&RXW@@@"LEPY@H@`07=V@H@"LEP`=C)<0#:X@L@ +M`0AS((8!A@4A/H`&]".&!(8%(3Z`!/*I<`/P#-@/>.(.;_T`V1T!S_G@>/'` +MH@CO^0+9SW=$`&BYB@@@"E8G0!:2"@`!"@H@"E8G0!;/=D0`Z+DRAE4F31`D)40!["%$`@>'_W,PA`H,#\F\(4``N#V_]$J87AD`G`1SP)0`0!+@4>!EA +MS@E@`P38B(=IATJ'*X?/<*``@!^,H'R@7:`_H.H)8`-`)P`6SW6````,`(6` +MX`@)00-""D_],@M/_;8,3_T2AH'@`-C*(.(`,@YO_0#9`=@`I6$`S_G@>/'` +MH<&+<-X/X`D!V>8)``$`P,]R1``HNC22Y[C3(*(!SR$"`-`A`0`TLJ'`T<#@ +M?L]P@``P$*T'X`D(V?'`X<4!V*`<"+``W8'`@@@@"@+9!!0!,:ER!/`!XE!Z +MBNK/<($`$"M6>&"`\0G!@`&``_``V(#@RB"!#P``"0GL#<'Y@L#"#N`)!A0! +M,8MP)@@@`039V0>O^;C`@07``/'`5@^O^0S:I,&+=<]Q@0"T(-8*[_FI<,]P +M@0#<(<"`J7`F#^`)`]D`P1L)4`!G"9``C0D0`<]P```+1)(-S_E"\`'!#0Y$ +M<```_S\/"94,SW````Q$>@W/^0'!SW"``!P1+*`2N8`A"``JN0.Y+Z#/=8`` +M=!$`A:;HK@N/_`:%!(`@@,=Q!````%H*(`FI+Y"A2"SW"``'01V@D`"0;PSW"``!P1S8#/<*``@`Q`&(`/ +M`+@(`-G)`MD`'P!`R7"2""`!`=KE!J_YI,"5!,``\`/8-``D`V`T-41`)IF() +MP`4%W\]VH```,`@>@!\```"@`-A."6_]_]E:#"`*'M@"P,]QH@``>"89&(`# +MP`V_F!D``('ET`TA"/'``=CAP,]P@`"8$4X-X`D?V8MP%@[@``39H<#1 +MP.!^\<"XP8MP-@W@"039`,``VT7``<`%VD;`!]A$P,]PH`"`#$`8@`\`N`@` +MV!":%JH2P:@`\`@,(``]@"V18/X``!VIX/X`*$ +MP+C`T<#@?N!X\<"AP8MP-@S@"039`=G/<(``S!5>"*`!(*"V#``(S@[``*'` +MT<#@?O'`N@RO^8H@_P\:<)P<"+"!P*(,X`D"V0+'!">`'P!P```\N%,GPA8; +M"+0!`<7/<:````0$@;A@!*&*('\/0,!6\,]Q@0",'O`A`0#/!EA@\#>#Z_Y!]H#QHONSW&@ +M```$!(&X8`2A`!P`-"[P$!0#,1,-P!!##]\7$A2`,#L($`$2%(`P%P@1`87% +MJ7`"#.`):'%@?JEP)?#_O]$@8H`(\LEPZ@O@"6AQ`=A`P`[P&0@>``_MSW&@ +M```$!(&X8`2ABB"_#T#`BW"6#.``!-D)\`'80,"+<`39R7+B#.```KL=!*_Y +MN<#QP+3-A.#*(((/``";(1@*POD!V<]P@`!8$B&@B@O@"0C@E@W``-'`X'[@ +M>(D%P`#QP,]PH`"`#$`8@`\`H`0`V!X\<"&"J_Y%-G/ +M<*````0#@,]U``"MWK`<"+"+=EH*X`G)<`#`8;A_")4%,R8`<($`?!]`)X%R +M%'D`>?(,X`+)<`AU-?"Z#>`"R7`(=2_PU@[@`LEP"'4K\#(/X`+)<`AU)?!> +M#.`"R7`(=2'P6@W@`LEP"'4;\(8(;_W)<`AU%_`&#.`"R7`(=1'PV@K@`\EP +M"'4-\+X(``,(=0GPQ@_`"07P?-A2"._YC;C/<*``@`Q`&(`/`+@(`-G)B;T` +M'P!`J7`"V=H+X``!VBT"K_FTP/'`H<&+<*()X`D!V0#`!=G`N!1YSW*B`"1P +M`()&(,`!)7@`HI(+P`"AP-'`X'[@>/'`?@FO^0/9@B0"-P#?1L=%QXMP8@G@ +M"1IQM,U"N"MH`,`"Q0L(D`"I<.EU!?`;#141`=A"P`3H'PA4"&H+H`42:038 +M`_!%Q_#Q1,"$P/H)X``,V3?PA\8>">`)R7`"P@'!"6H5(0,`SW"@``!-F(`8 +M@->\!""`#P`/```XN`JX"PDD`YA@#PD$`!$+!`,-"P4`$!P`--SQ`,,(ZX'C +MS".B@!7R`=C3\2APO@J@",EQ`L-$QT7#A,`(VP\>!^X'BY!H`` +M\<"NP8MP>@C@"0[9`,`>Z#X*X`6*(%``$!0$,`#8`L$!PAH*X`4#PP'8(!0$ +M,`;!!<(*"N`%!\,-P4(A`(`B"F`!RB!B``7P!@K@!0#80@K``*[`T<#@?O'` +M-@BO^0/9SW"@```@&X"EP43`$@C@"8MP(,$!%((P@^'*((L/``!&'XP.B_D@ +MP<]UH`"`'`%I!2"`#\7N@)L!I03`$+D!I0$4@#`E>`&E`L`!P0&E(:4`W@GP +M@\#*#Z`)`=D#P`'F`:4@P&.X\0X$D(3`@@C@``39+0"O^:7`\<#AQ:7!@L"> +M#Z`)`]D*%((PC"($@(CWBB`.`!H.K_D)%($P`-T0\(MP9@C@"0'90"2`,%H( +MX`D!V8'`4@C@"0'9`>4*%(`PX0T$D&H)P`#=!V_YI<#@>/'`I\$!V$;`BW!& +M#Z`)!MD`PH)/(`$$@>/*(0$`%X*7Z,]RH@``"`:"A+@&H@:"@[@& +MHHH@$`#//'``@YO^039I<'V#J`) +MBW`"%)0P`-@$%`XQ#!P"-084#3$('(0S`120,`H<1#,`%)(P#AP$,`,4DS!, +M($"@S"(AH%P-`01J<,H-(`2*<0AW$PH0($4*4"!,(H"@B?("V)3P08<7ZD$M +MOI"!\@27$';Z``8`V64-"$4``B"-`[!]"AQ$,X+`VF((V;X.H`"I;Q`=D$EP(@`R`?"U(`>&#/#Z06W2B0``%,E?I`)]`&'BG').!^X'C@?N!X$0*```T"@``)`H``\<"HP:8/(`$`V(#@RB"" +M#P```T0X"H+YBW"V"Z`)"-F^#8```,`-Z",(4``M")``SW````X[(@JO^0+9 +M&/#/<:```#`+@9^X$?#/<:```#`*@9FXF[@(\,]QH```,`J!N;B[N`JA"X'> +MN`NA`<`-Z"\(4`!=")``SW````X[V@FO^0/9.O!0V<]PK0``A"B@BB%0`,]P +MK0``JB&@+O!0V<]PK0``1"B@SW*M```J`(*&(/`'02@!`0&"1B"`#R5X@+B* +MN(NX`:+/<*T``&H2\!#9SW"M``!$**!`V<]PK0``A"B@BB%0`,]PK0``JB&@ +M(!B`#P```"`"P`OH'PA0`,]P```..U()K_D$V1_P(-G/<*T``(0HH!GP(-G/ +M<*T``$0HH,]RK0``*@B"`\$$((`/__\?X`6Y)7@(HB>""(+$N48@P``BB +M!,#/!X!6"SW&D``!(SR"A`-`@H@`5H@7`#PB1``,1`(:"N`,9&(`% +MP`\(40`#$0"&HK@#&1B`!<`,Z`;`!\+&N`>Z!"*"#P``@#]%>`09&("HP-'` +MX'[@>.!^X'C@?N!XX'[@>.!^X'CQP!H*;_D,V:/!BW!J":`)&G`#%((P*0H3 +M",]P@`!8$@&`'N@&%(,P`A2!,!$+LP$!%(`P"0E3`B4($@0&%(`P`12!,`BX +M!7H"%(`P&+D0N`5ZD]B-N$H(K_E%>0,4@3`BR%1I6&`C$@(VSW6!`(!V%")1 +M`"'"@.(V?@```P$FG' +M<*```"\T$`0`-!B`#P@`````VP"&#R-#`&MX1O(%%((P!NHN#:`'"G!`\#H7 +M`)9*)4``9'@0U!S`=K"(H$``KI%>`<4@C!AA9:Z<'(!VL(B@0`#N@5Z!A2#,%,D +M@``0`$4@3``IA4F0!"$@`2Y17R$H`(4@#``(XP/@`"H$@84@S``K'5^?(8E>$5[ +M?*8Z%P.697HZ'YB0`!D$(`44@#`#%($P.'B2%P&6)7B2'QB0`-@`I0<4@#"6 +MN`&E!A2`,"'!D+B1N)*X`[D%>04A@0\8`1```Q2`,`*X"!0",<=PH```,*T8 +MF(`T&$"`!?`.#*`'"G`APH'BS"(B@"#T`Q2!,)3ARB!%`,H@1@"'W,`@!@," +MN#`@@P^@`!@L$FDP((`/H`"T+@]X$'/*(((/``"2`%`.8OG/(&(#:@Z@"638 +M/@J@!P84@#`&%($P`KG'<:```"Y(@:"!+^A`(@`$L7*I=LHA!2#*(88@(_`& +M%(PP4R;/$'9LQW.!`(!T]7L`@P,4@C`$((`/'P```#"X(0H!`$`M`1(%(4$$ +M$+]@@Q"\SW```)TAY7GJ#6_YA7H!YK\.1)0*<`X(H``$V:$'+_FCP``6`$`` +M%@!`.0&``/'`X<4`%@U`A.7*((T/```Q)9P-;?G*(4T#$VTZ"6`%%'@6"8`` +MB0!X\<#^#@_Y.@E@!*'!@>`!W5X)8`3")4$3"'&&"V`%J7`>"6`$"'5$ +M+7X4+W6&Z``ECQ]$`$C'!O``)8\?1``XR(MVR7"V#F`)`=D."4`$(@E@!#IP +M5@E@!!IP"'//<(``K+4*$(0`*G$`P`IRA@WO^[AWR7!6#V``!-GI!B_YH<#Q +MP.'%I,&+=:EP/@Y@"0S9`=A#P(/`-@]@``39*@Q`!%X(C_V""T`%3@U@!*EP +M4@^``=$&+_FDP/'`4@XO^63:N<&+=L]Q@0`\(-();_G)<,]S0````$##SW`& +M``"`SW6``(2U((5!P`"!SW*!`-0=>&"`(`@`0()$P'IB3\(E@5+`4,$`V@SP +M6WE#<4P1`P+M"A2"4<``V@OP6WE#<501`P+O"I2!"@^``""%!>@`P$+``(%#P`*!3<`#@4[`R7!R#F``9-D=!B_Y +MN<#QP*(-+_E$VK'!BW?/<8$`F"$F"6_YZ7#/=4````#/<`8``(!!P,]V@`"$ +MM0"&0,4`@+A@@"`(`*H.H`!$P`?H`,!"P`"&`(!#P`#9"?`[>$-P3!`"!Q)I +M@W!%H`'A\PD4@B"&`H%-P`.!3L#/<($`U!T`@+A@3\`%@5#`Z7#J#6``1-F) +M!2_YL<#@>/'`M\&+<`8-8`D7V0X/0`"WP-'`X'[@>/'`W@PO^0O9J\'J#&`) +MBW#/<(````X`@"3"#.@8%`0P`-B6N,]QH/[L!-8+X`(%PR3`4R#/`$2X4R"7 +M`!,/,Q0!P9H(X`$H<`'!$PA0`,]P```0-"X+;_DDP@04E##/<(``I!I`(!4" +M0"`0!XH@"`4$+#X@6G`P)4TN$V\@P0HA@"^!`(0/%2`6```ACB4`AJ,)'P`1 +M"%\"<]B-N.EQY@IO^07"`-DD'D(0*K8_V`NV2G`$+#X@A>4T($`NS"7BD07T +M)[@*MBNV#O`=#1$202@!`RBX!WG#N204`#$%N3A@R+@*M@+`Z7(#P4`F@Q8Z +M#R`("B0`!2\@!Z`;\A$4@#`@'@`5AK@1'`(PBB#_#T;``(8%P88@"@`HN<"Y +M![DE>`"FZ7#.#Z_ZBG$!W0GP`MT'\.FX`=W*)2(22B``(('EW_0D%``Q#+9* +M<`0L/B`P)4$N`!83$`7`!L(="1$"&0H>`D$H`0+`N4$KPR'`NW!QT"(B`J>Z +M1L*GN$7`!B.!($1X!7D@IAD+'B+HNV"+8*Z0$4@C"*<(#BZ7'*(N$'-@L``[8)[_T`)D`D +M(,`+"!\`#P@1(!$4@#`3"%X``A0!,2:V(@K@`.EP$12`,!D('@$=%(`P`-D/ +M(0$`+WEF".``Z7`1%(`P'0C>`"?!Z7`>%`(QBG.2"B_\BB0!`)#@RB4F$;8) +M8`?I<"#`$12!,`T('@`H=(8DO9\G\@06$!`*PD&F&PD>``0B``00^7)8:(1(`"%RB!" +M`#P(8@G*(>(#"O`R>`1[8:(-"QXA(((D>`"BYX +MRB`A`,\@P0/,#R$)RB'A`R#"BG!2(@(`Z7%V"2`#P+K/<*``@`Q`&(`/`+@( +M`-G)`MD`'P!`J7`&#&```=H-`B_YJ\#@>/'`L,&+<,H)8`D0V<]P@```#@"` +M#>@`V`$4A#"6N"#"SW&@_BP%M@C@`@(4`S'/<*``@`Q`&(`/`+@(`-G)`MD` +M'P!``=BR"V``"'*PP-'`X'[@>/'`>@DO^0'9SW"!`.`A`8"CP4'`9@E@"8+` +M(L4*(8`O@0"$#ZEP>@Q@`0#97&U3)<\0LV^U?0`A3B,@AHH@""!^CEIPPKH+ +M(0"$S"+!@,H@@@\```EP.H[/<($` +M!!(V>"*0!!Q$,`"``<'V#"`(Z7)*<(X((`/I`!0+#P$0@-@`H0#8"@P@!0\@P`//<*``@`Q`&(`/ +M`+@(`-G)`-D`'P!``=C&"F``"'+Y`"_YH\#QP)X(+_D"V;/!B@A@"8MPCL&" +MQL]U@0#$!T`E`!.V"2`($-I+=X`G`1;I<,EQI@D@"##:@L`N"6``1-D`P!D( +M'@#I<-X/K_HPV4`E`!/6#Z_Z$-FU`"_YL\#@>/'`X<7/=8``A!.I<"H(8`D! +MV0"%,PB5``1M'@A@"0'90"4`$A((8`D@A4&%-6HP!X\<"FP;X+X```V(#@RB""#P```D10#@+YBW#. +M#R`)!MG6"4``C@]@!0#8;@]@!0'8`,`4Z!$(4``5")``'0C1``#8`_`!V&X* +M@`((\&8*H`(!V&(/8`4!V`#``\%"(,"``[G*(&(`I@EO_2YY7@]@!0'`!<`% +MZ!$(40`!V`+P`-A*"H`"IL#1P.!^X'CQP.'%SW6!`,P6J7!.#R`)!=D`V<]P +M@0#X%HH-X`<@H""%B.'*((T/```-1+0-#?F*(`\*$K7/<*``@`Q`&(`/`+@( +M`-G)`MD`'P!``-@V"6```=K/<0$`L.D"V,(+X``"VH$'S_C@>/'`H<&+<.X. +M(`D!V0+84@J@"`#![@A``*'`T<#@?N!X\<#>#N_X!-FDP2H.(`F+<"#``-TJ +MZ/$(4`""X'_T@!EASW"!`"`:#@I`"*EQ6/#/=8$`4Q\@ +MC0$4@#`0<00A1``'8 +M`*T5@0"C!2"`#_]___\5H0#:$?#/<(``(!55>&"`SW$!`##P#0M!`,]Q```H +M5R"@`>+E"A2(&/``@P#:%:%`K1#PSW"``"`557A@@,]Q```H5P\+00#/<0$` +M,/`@H`'BXPH4B`#9"O"!P"X-(`D$V4(*K_N+<`AQ9@NO^R#`,0;O^*3`\<"A +MP8MPK@T@"0'9`,&`X@\``*'`T<#@?N!X\_X`=FG +MP0`6CD``%H!``":/'X$`Y!P`KP`6`$%B"&`!R7",(,./2B0`(!MP!O06#.`` +M5-C9`@``=@Y/_,]Q@0"$#T#`$VX5>`L.-10"81$*7@)VV(VXE@LO^X7<\&A`(\!H?`C@",!H2IP_@X@"0+9"G#V#B`) +M`MFI<.X.(`D0V18B@"-$P`&(D.#*((H/``!W`,\@:@/<"BKYRB&*`X#8`":9 +M'X$`\`X`&0(P`-_/<($`A!(5()`#`AC$(PHG@"^!`/0B`!C$(V/P?&G!NP%K +M!"6"'P(````QN@`HDP`%PE,ET1`#NE5Z>&,5>%A@(G#/`##W@5#O4@"'$1#A`@#0[$)`7`"0D%`$HB`"!,(@"@RB"! +M#P``>`#/(&$#&`HA^!P`0`"$/(,`#`!@$(!$)W@<"$``A +M#R#``P(8!"`!Y[4/%10"P`/!]7@`(14``!4-($$M@!/"N#(G%B`$)8(?```` +M&`0EOI\`!``!02K``D;%1<`!V#ORZ+TFP8'S02W`$,&X`>!!+4,4P;L`(Q,` +MH.',(B&`%_(+#1X2$PB5``G<"KP$)0(3'PH``QL+U0`/"Y$`$PT>$@\(D0`1 +M#1X2S.'$]DHB`"`$\$HB0"#/<(``K+80D%,ED1#EN,8A@H___^?_>/-[V(VX +M0`8"2+YSR!B`P3``X@R)P$@`=B" +MX@#L""'YSR!A`U()(`?)<`'"SW```#P5 +MUGH@D@DA````LEX,``!Q`N_XI\#@>/'`3@KO^`C9HL'9$@^VSW6@```NU86. +M"2`)BW`DR`#!SW.@`!PN!B$"`(#B`=IY@\!Z9'@D>(#@`=C`>$MXRB"!#P`` +MIBB$"`'Y`-@5I9X(H`@_V`#`!!0!,16E>@]@"(*YU:7N"R``V1K8LTT"[_BB +MP.!X!0```/'`V@G/^,]P@`!8$@*`,F@P(8T/H`"T+@AQ@"'"`93@RB!&``*X +M,"".#Z``&"P`V$H+(`!D$H&P.-C9$@&VJ7(F""_YR7,%`L_XX'CQP(X)S_BB +MP0#>4@V@`,EP@.#*(((/```*1.0/POB+=:EP7@D@"0+99@L``,]P@`"8$1J( +M!!0%,1L(7@`'%(0PSW"@_A@$`,($V6(,8``&%(,P!!0`,2\F!O`,``,`!!R$ +M,P?P"PC2`@K8!!P$,`#!SW!$`/"%`X`3"5$`@.`T"X+\\@FO_*EP!/"`X"0+ +M@OQM`>_XHL#@>/'`\@CO^%S:@B0#-9[&SW&!`!0A<@SO^,EPBW6N">_]J7#) +M<,(((`D7V0#?'L`!WD#'1\8'Z(X/(`7)"Z```-B`X,H@@@\` +M``E$.`[B^,!YBW"J#^`(!-FV"0```,"$Z&X*C_P9\",(40`!P(#@S"!B@,P@ +MHH`$]'8*C_P-\,]P```)1`'9!?#/<```"40"V?8-S_@"P(;H!@J/_*3`T<#@ +M?AL(40`#P`T(%0$""H_\]_'/<```"40#V07PSW````E$!-G"#<_XZ_'QP#X/ +MC_@(=L]WH```$`T7`)8H=4(@``A((`$`0"4`$A!QG`\%"0=M!""`#P``_/\% +M((`/`+@``#`?&)#9R0`?`$`BO07P`!\`0`3F8;W[#;60`(8"V08)(``!VDT' +MC_CQP-8.C_@(=BAW"B&`+Z```!`-$0"F&G-"(``(2"`!``1O>&`$X!!Q2'4T +M#P4)`"#`(P?@!""`#P``_/\%((`/`+@``#`9&*#9R0`?`$`BOP;P!!8!%&&_ +M`!]`0/OO02B!(`;P`!\`0`3E8;GY";6``(4"V88((``!VL$&C_C@>`/;SW*@ +M```0!AK8@#`:F(\`N!@``MH<&H*PQQ(#M@`?P$"/$@*W`>*/&IRP`!\`0-D2 +M`K;/<*```"``'X!``!]`0`'9):#/<8$`E!@"@4"``!^`0`.!`MD`@"$`(``! +MVL]PH`"`#$`8@`\`N`0`VDSW"@```@`^IF&-B`.X#/<(``J!;@?R"@X'B9 +M`,`"8(!`@1T+@0!BD$*1%0N!`&*`0H$-"X$`1I`&D0D*```!V`/P`-C@?O'` +M&@A@`@_8`=G/<*```!TKH#8)X`(H<-'`X'X#@`0@@`\@````0B``@.!_RB!B +M``#;%PJ0`$.!`=OMND"!P'OMNL\C80!EH&"!08%@H$&@8H%#@6*@0Z`!@<]R +M1`#HN2BXQ;@5H@"!/+@C@<&X*+G!N3A@X'\6HO'`Y@G``HH*P`+1P.!^X'CQ +MP/(,C_@(=4AW&@G@`FAV@.#$#Z("RB!"`Q,.41"I<`H*X`+I<:(+P`(U!8_X +MX'@Q!X``\<#"#*_X`-CAP-W)'0A>!=H2!+;/<,7N@W'+$@*V`=GB#>`(V1(# +MMF42@[``V(MR#0MR!$#`C"/#CHCVSW!$`*B\\"#-`(3M`=DB\!L+4@2.(\,/ +MSW!$`$#!SW9$`%3!\"#-``GPSW9$`.R\:'`6#^``9!*!L&EF9,L3"$,`\"4` +M$`7H`*(`V0+P`MF`X:P*XOC*("(.SW"``/0-`(``P1+HL\T$((`/````@$^X +M@>#,(2*`"/('V`JXP-D8N28-+_H[>@#`0'AI!*_XH<#@>`/9SW"@```$**`E +MR,]R@0#<4&&2SW&!`$`(%'D$DFBQPA(#MI@9!`"@$P$``X*&(<,/)7C@?Z`; +M``#@>/'`X<7/<($`6%<(=0"`3PA1``QP/0A?!L]R@`"D"2^"SW"@`(!$"PG> +M`A*``O`1@,]QH`"`(#*!8;@9"00`O!(``1$)!0`#A88@SP^;N`.E%@\O^ZEP +M`-@`I=4#C_C@>/'`4@N/^`AUSW:!`(A7`(;)=Q,(40#R#B_[Z7``V`"F!?!? +MV*()[_B,N`&'D0.O^`"EX'@(0`A +M@`]$`)R&,0#@``+9"'(S:#5Y`"&`#T0`G(8=`.``!=D(0`A@`]$`)R&]0>@``39"'(S:#5Y`"&`#T0`G(;A!Z`` +M"MD(,]Q1`#`A@AAA.`!V.!_P'@(0`A +M@`]$`)R&?0>@``C9"'(S:#5Y`"&`#T0`G(9I!Z```=GQP.'%7@_O_PAU,@_O +M_ZEPF0*/^/'`X<6N#^__"'4R#^__J7"%`H_X"'(S:#5Y`"&`#T0`G(8M!Z`` +M`]G@?N!X\<#N"8_XI<$!W@#=+O`3;15X`""/#T0`G(9`Q\]P1`"@A4'`SW!$ +M`)"%0L#/<$0`F(5#P`#;1,/)<`?9"]H*)(`/1`"$KPHE@`^``-`02B;`"0H. +MH`#X<\]Q```\[U8(X`#I<`'F`>6G#521[0&O^*7`X'CQP.'%`=C/=:(``'!% +M'1B0#@@@"63811V8GP```0\'V.P=`!`$V*D=&)#V#^`(9-C/<*(``.``&(`/ +M`0"F"<]PH@``Y"`8@`\`@`(`4!B`#P"`!@"A`8_XH<'QP`()C_BAP;IP3,`H +M=@0@OH\`!``!FG+:\A4-'B)3)8\@02W`(%,@5@!`V`GP+,!3)<\@1+A3(%8` +M@-@$)8TO````&"N],VT`)H(E-7E5>EEA^6'/)@'8&1P"(`IP`,&I`%\E,@`0`X8"D-7B//<8$`-"@@ +M@04I/@``(8)_``#_#RRZ0"+#`R2[`"-!!`;P%2$!(`#;:'),)`"@>?(`W!4< +M`B,9#5XCQ;J'X@':P'H4'((@`^,BNT)S!O``(@,@%!P"(W1[426`IF.[`!S` +M(%_R4FU5>O1ZSW.!`&`H4F//T8FSA`BOA`<@",%*3YP +M@.4,'$`NRB#A`<`H800*\H'E`]C`*.$$RB#B`,`H8@7%>!`<`"`W\"S`20U> +M(B$(T@W`N,]Q@0!@)/`A```#O@4N/A`*(,`.`>`'\`D(D0(3;@/P$F[/<8`` +MI"1:@2S!)'J&(O\.(KK`V5IY&6$3\`.^''C"N,]Q@0#0*/`A```6Y@4N/A`* +M(,`.`>`"N$`@`04P>`C<'P=O^*'`SW"``/P0`(#@?X8@_@_@>,]P@`#\$`"` +MX'^&(/L/X'C/<(``_!``@.!_AB#Y#^!XSW&``/P0BB`$`.!_`*'@>,]Q@0#, +M%L]P```01!$%K_@PF>!XSW*````1!H($@""`QW$``%###0+@!TAPX<7AQ@#; +MUW`$````6``N`,H@S@!!*($$8;E`*8($0G@"(((/!````(CA"-S*)$40:'`2 +M\,]S@``<$2.#`>`!X<*Y(Z,5(TT`((/$A<)Y(*,`V22EX0@$@]=R!`````#8 +MRB"%`,'&X'_!Q>!X\<#/<(``'!$0@`T(D0`^#D_[!/#2#4_[T<#@?O'`[@U/ +M^,]PH```(!N`SW6``!P1-(4-"$0``B!.``?P#B&.#_____\>9A2E3@_O_\EP +M"'?/'"N2.E%25"$&2"((4$HF)Y.&``I2.X"K@RN#X/[_\-I0CH+H4982ZEF@@@ +M"`#8SW*``'01!H(.)X$?!`````2``(`98:X(X`=(<($%3_CQP,]P@``4_?8) +MH`,`B,8-C_S1P.!^X'B`X/'`S`W"_-'`X'[/,\@H@7*(0($RB."`]@+(@+")`(!#L7/=X``%!(#AT`EDA!"<(P@QX]* +M(4`@CO?/<*````PS@!2`#0D!`.H/P`$J<`/P`-@(Z".'`"&`!`.G`=@&\`:' +M`>`&IP#8+^A3(,`D0"T!%@5Y`8?//S"T2#SW"@```@.X`!AQ5Z(*(DAP'@"'2&),>?`>$DIP7R +M)8!X`-@%H>!^X'C/<8``-!(`@>.XT2!A@"ST50B>`%$( +M'P"`N`"ASW"@```(`H``V<]PH`"`12V@SW"@```?'(`E"!\`#'`="!\#SW"@ +M`(!%,!B`#P`@````V<]P@``X$B"@:B&``<]P@``\$B"@X'[@>/'`4@M/^,]U +M@``X$LX(X`;`A<]PH`"`13`8@`\`(``!`=@`I6HA@`'/<(``/!(@H`QP#P@> +M`[X)X`@*V"SPK.[/<*````@"@`#9SW"@`(!%+:#/<*```!\<@#$('P#/<(`` +M-!(`@"4('@`,/'`F@I/^`AW +M*'8`W0OP%0Y.$Q1OE@_@`*5XD>`L"@(!`>7O#122X0)/^.!X\<#AQ0'9X<%` +M@"&`SW"``!3]H(B$ZA8-0`,(<<]P1`!0QH0M`1/.#.`$,"!`#HMP`@NO_P39 +MM0)O^*'`\<`!V>'!W1(!MB\K@0\`"```N[F]N=T:6+"`@$XC@`=3)`(0&'I$ +M)(`0+RN!#P`@``!.(TP'F'A%>`5YW1I8L(MPM@JO_P39H<#1P.!^X'CAQ<]T +MH```(%N$SW.!`%0?H(,!V87M&X0`HRAP!?"B>O<*!8``V.!_P<7@>/'`X<6* +M(O\/$WN`X,HB:@#*(PH`4W@S?(#ARB4+$,HEBA#*(0L#/'B2"F_X>&"L>`$" +M;_@O<.!X\"F_XR7.I<@8,;_@J/'`X<5(=10A```""F_X.WEY +M`6_X`*7@>/'`\@A/^`AVSW6``%@2`84H=T`E$!0QZ/_9"+D$)T`0,'#*(((/ +M``"A(4@/8OC*(<(#\G_O?_`@@R,>\$5Y(Z4:\"\HP0!.((P'`-D/(0$#,G@$ +M>P#>`_`!YAT.%1+/`.EY^OE`$_XX'CQP`AS +MSW"``%@20"`,!`&`%.CP),`0%0H>`"1X'0D``,]P``"D(0?P$0D``,]P``"@ +M(R"C`>#Q"%2# +MX'_!Q>!X\<`6"$_X#'"]"-X%+'"Y")X#SW2J```$HH0'V$$M`1(O>8FYSW:` +M`&0*9H[/]02G!<,(A8@`'V`KP12G^`D$I`7$&\"*Y!/`` +MV0C8+J)!A"^C3*/DNLH@(@+ANLH@(0(/"IX!!-I!KDJ3@KI*LQL(T0$5";0# +M!]C/@P@!QK9!85`)0(5 +M;@P@!QK9A025XSW&G``!!$*'@?N!XR;A`*($")7C/<:0`@$0*H>!^X'B`X,H@8@`3>,&X +MSW&G``!!$:'@?O'`]@T/^,]UIP``0.^%.@A@`PAV,0X`$$\G`1&(N8RY@.;, +M)F*0"?(E#I$0!2>!'P``,!$,\`'F0"Y`$@V^!7[%>0;P4"!1XDVF4?$`L`Q4+ZA6\$P@%`T`I`P9T>R\IP0`#\"\I`0`!X3A[.'C/ +M<:<`@$00H7&AX'X0N25XSW&G``!$$Z'@?N!XSW&E``"`$Z'@?N!X%'@O*@$` +M`>(#N31Y%+E8>%AYSW*G`(!$,J(3HN!^X'CQP,]P1`"(L.H+K_DZV8/8"+C/ +M<40`Y+&Z"Z_YH-K1P.!^X'CQP`8-#_@Z#W"@6`X'[@>/'` +MX<5F""``"'4*(@"`RB""#P``_Q0("V+XRB%"`_D$#_C@>/'`X<7/<(``S!4` +M@!KH`-T6\(0M"!4`(8!_@`"D&B&`#>D"@(/@S"!B@,H@@@\``/L4P`IB^,HA +M0@,!Y=<-5)&Q!`_X\<`V#`_X$@GO^0AVG@S@`@AU@.`!VX`V(#ES"$B +M@,HE`1#*)6(0@.4!V'D$+_C`>/'`X<7/=:(``+@`A<"X4B``@,H@@0\``,@- +M6`I!^!F%R[B"(`(`!2B`#P``>@TO/'`X<7/=8$` +M*`@VC87ARB`A`!GR58T!X14E@A``HB]X-JV!X,H@(0!T"2$`RB$!`!6-`>`/ +M>16M"0E1`0#8%:T!V,T##_C@>/'`2@L/^`AU*'9(=X/@RB"&#P``#T2P"6;X +MRB%&`P*]M'W'=8``*!/`I8T#+_CAI>$#C_GQP,]P@0`0+>P<"+#/<($`."U! +MP,]P@``P"T+`SW"``#0+0\``VT3##]@#V03:"B2`#X``.`L*)8`/@`!P$THF +M@`)"#R``2B=``*7`T<#@?O'`SW"``%03^@U`!\]QH@``"`:!I+@&H='`X'[/ +M<8$`*`@4B?`A```%@`!XA0?/__'`X<6&":_YH<$R":`(9-B+=<]Q@`"LTQ>! +M@.#*(($/H@``M`OR$0@>`,]PK0``)A^`!O#/<*T`@#`/@`"EW0@>A#J!"0E1 +M``]X`_#%N`"ESW&``(0LJ7!R"R`'!-K*"6`"J7`V#L__SW&B```(!H&DN`:A +MG0(O^*'`X'CQP,]Q`0!@9@#8R@[O_P+:SW$!`+#I`MBZ#N__`MK1P.!^X'@( +M/'`U@D/^,]U@``H$P#> +M$_#R;O1_OV<@APSI0H<)A14*`0!`>2&'"85):49X.&`"IP'FX0[4D`F%`>`) +M`B_X":4`V`/P`>`C"-4`,F@T><]S@``H$WEA0(%VZD*!*8/I"D&``=@"\`#8 +MA^C/'EA)*+ZZ.!^X'CQP`H)#_@(=B42`3;/<($`0`@T>!&($.C"$@&V`8$9 +M"%X#Q!$``,]Q@`#D%!5Y`($0X`"A[@P`",8+(`0ER,+)`=F@&$``R7!:""`` +M)!(!-L(2`K;/!!AC^@`V`\@@`!R#B`(']G"R1"(,V@U>3%EX;E$#@+XX0`/^.!X\"SN+6XN+C?&ABP%;D$H0'86G#/=J````0)IL]Q@0#$$Q:!`>`6H<]P +M@```#@"`#.A`*0(D`-B6N,]QH/Y,")(.H`&E>N*]P'\%]-X-H`<`V`AWE,K/ +M<:```"XU@0*X)!("-C`@@`^@`&0N1'@$>00A42"5\*04`#"XN*0<`#`:#>_Y +M"G"B#:`'`-@(=\]P@0#T')AP&@SO^0IQ@@B@"(AP??#&#L``#H;["!2"`]AZ +M'`@`04H=(8D\9\-\A$)7@*@'(`_ +M`0"+`"KPH!R`/P$`B``D\#Z(P!2`,`\(0`"@'(`_`0"1`!KP`<`/")X&H!R` +M/P$`D``2\`K!C"'_CP_RSW"@```@&X`B>!,(A0\`@```H!R`/P$`AP`!W8#G +MS"4AD'#U(![`%(#GA?53)7Z0!?(.AH#@?_5G#5X0`=HJ<`3P$"!``"CH+RL! +M`$XC@0N;J +MSW"``%@2`(`*Z!$@0(#*(($/``"<(:@,`?@`V`/P`=B`X$WS90;O]X`D`S[@ +M>,]Q@0#\!R"!)PE1`,]R@0!L&R""&PA```"BSW*@```T((*`X-`AX@3/(>$$ +M(*+@?O'`Z@W/]\]PI`"`1;Z`KW[=R00EC1\```#_*+TA"-X"4@@``T`N`Q(0 +MN`5[KWK/<,7N@F0!V?8.(`AE>AT&S_?/,]QH`"`>W*!,X'+N\NY#0M$``(C0@`( +M\,]R@`"X$T""(GIZ8D"@SW"``+@3`(`BN!!RS"+F@`'8RB`F`.!^X'C/<8`` +M$"\B@0#8$PF>!?6YX2#"!V38X']/'`X<7/ +M=8````X`A0OH`-B6N,]QH/Z0`F_:!KJ*"^`&"-L`A0OH`-B6N,]QH/Z\`@?: +M"KIR"^`&!=L`A0OH`-B6N,]QH/[L`G':!KI:"^`&!-LY!<_WX'C/!X\<"*"```-@@``-'`X'[@>`#:$?!88A1XQW"``,03 +M(I!AD!"Y`)`E>\=PH```8&"@`>+E"I2$X'X`V!#P&6`T><=Q@`#$$T"1`>`P +M(H,/H```8&&Q,+MBL>4(E(3@?N!X`-@1\!E@-'G'<8``,!1"D6&1$+H@D45[ +MQW&@``!@8*$!X.4(U(/@?@#:$/!88A1XQW"``#`4()`!XC`A@P^@``!@8;`P +MNV*PY0K4@^!^X'CQP(8+[_AIS"B$`(0C%"B/`(0"E"<`*(H`A`Z4('4`1 +M0"4/&&2O"L-&KV2E"\,EKV6E`-MFI6*O8Z\$'0`1!Q^"$?_>R7'^"J_Y+W($ +MA07HR7'R"J_Y18\%A07H_]GF"J_Y18\`WPOP%2'"(R"*J7!"BI8*;_KI/'`N@K/]Z'!"B<`D"AU +M&G)`(`X()HX&\@D-0Q`#AXWH`(=`+0(2$+@%>L]P``#I#AH)+_A%><]P@0`` +M8!T(!"#/<($``'`2<,H@C0\``/@.^`@M^,HA#01`CJ"N`HY!KAP?`!0.Z`.. +M">@@A^_8$+D$N*5YZ@@O^&2.`=@#KH;P`=@"KDHC`""*),,O)(X#'L(4`!:1 +M$`:.'!<0$`QY0X<`(4!T"&(`W0D(``6AAQ5]1H<5ZF#!`AQ"-`3M`8T#\/_8 +M`1P",`3M`XT#\/_8`QP",(MQ8'KI<"2.DG',)2*0#/0`APBY$+@%><]P``#H +M#EH(+_@%(4$$)(Y!C4HB0"!0<<(B@20U"8``!8<`V@WH*6`7"0`%`8".( +M"PD`!0*'\"!"`(#BRB!"!.,@@@#*(0($_]@$KB.-$PD`!0*'\"!"`"IP8'H* +M<3<*$"`!C02N!(`"7(SW*!`$`(%'I6)\`4Z7%.#"``48J2"J_ZZ7`FAA$) +MG@<)AHRX":90V`>F-_#,R8`@!``="=X'*88<'H`?0`%0`(VY*:8Z@)ZY.J`G +M\*FF'!Z`'U`````Z@)ZYG[DZH!WP'PA>!R7(SW*!`$`(%'I6)\`4Z7'F"R`` +M48JGI@7P'!Z`'U`````1"!XE)!Z`'P(````#\*FF,8_/<($`."K"N2I@SW"! +M`$`J\"!!`%8G!!,)AA0<@@`E>":&":96)Q$2%0E>`@K:-AF$(#@9A""`N`FF +M%_`0VC89A"!QAL]Q@`#,&H0K"`4P(4$.$PG>``K:.!F$((.X":8#\#@9A"!Z +M"R_XZ7`IAD0A?H),CA;RSW"``*0D&H!$>$2ZP;J&(/\.6&#/`QN<&Y.&`5\!B.1+C!N$%H!"&` +M#P(````QN`39`"H0`!4<0@!>#2_XZ7`$\`'8&G`@EQ04@``X8!44@0`X8":& +M';8$(;Z/`0``P,H@(0M0#>'WSR`A`R\(4"!,(("@S"#BH`KR2B``("W8+@WO +M]XRX"G`0\,]P@0!H4A8@P`0#B`?PSW"!`&A2%B#`!`*(#K@CAE4G0ATE>`.F +M!H9F#2__/99IA@0COH\````P`;9`\B.&#I8EI@FV`!X$%<(2#+8?"QX#%-@( +MMCX9A"1X%`(1`B*`(!FV$H;&&ABP"O`.V`BV/AE$(W@4`A$")(`@&;87"]X` +ME,K/@.2`^B1NVFF!"&!#P`#```XN0/8)GB"X0#9RB$"`,S)"[E: +M$`(&17E:&%@`#/`FAJ"V):8OECX91",IMCV6&;8HMCX1`B$`EB&6&F("EEEA +M.&`5!J_W&+;@>.!^X'CQP.'%"'6$*`@%SW"``/@;,"!`#F8+X`)`P__20,/_P?9)1I8,,]PH```!"^@`!8!0-S)RQI8L"<('@+/<*`` +M`$<4&(`/```,#-_)!=H!X+.XM;BXN-\:&+`5N@2BSW"@`(`L,*``%@!`V1H8 +ML&7+!>@`%@!`VAH8L.!^X'[@>,]Q@`"0$^!_\"$``,]P@0#$'>!_`(#@>/'` +M)@VO]PAQA"@(!0`AC7^``*0:PH6%X,H@A@\```(TA`OF]\HBA@.%YLPFXI$` +MV`+T&85A!8_W\<#AQ8P@`H"8<`38&_)`+,T`M7W'=8$`A`\`A88@]X_,(2*` +MRB""#P``_P`+](7H"(41"%0!*]@(N"X+[_>(<0B%)06/]^!XA"@(!<]Q@`"P +M&C`A00[/<(``>"LV>.!_`(#@>(0H"`7/<8``L!HP(4$.SW"``'@K-GC@?P&` +MX'CQP%H,C_<:<"AW)#8`"PK@G"-$`0X<# +MV0ZY!")``!L(0``ER,]S@0!`"!1[$8L+"!X`1WDCIP`F@!^!``P(H*@CAP`8 +M0""-\!-N%7C/62),H\((<$`""$``!IB`)?7<```[P])(M(#U?<`)I,?@0#P#@`3@"",(`*` +MRB"!#P``7``D"N'WSR`A`P`3@"`)(A(@%FX5((`$SW&!`.A2`F'/<8$``'`` +MB0?H')>&(/\,!P@1`D&!!"*^CP`$``$P\@0B@`\````802C$`NBZ`]O*(2(& +MRB#B`'DE>BD*G@9`+,$`G&0U +M>95\F6$98<]S@0"0)REC#0G>`48BP@-AN`5Z`":!'X$`#`@1"A$@SW"!`.0< +MR&``J0/PH*D`&(`@10./]^!X'7D$(8$/555552)XSW$S,S,S!"!"`"*X!'E9 +M84$I``$X8`0@@`\/#P\/!"B`#P$!`0'@?T$I`';QP`#:"NA]"%``RPB0`.\( +MT`!(<-'`X'Y@@<]R@0#T(D$K@`/"N`IB`ID-"E$`"0O>`P.9SW&``(@-((%A +MNH#A`=G`>5MZ)7J$X@#9RB&%`-#@2/;/<($`F"KT($``W/&"(`$$1"F^`R2X +MA^``VLHB!0`4(8!PSW&!`&`J$&',\0"!`=HNN,*XSW&!`/0B"&&`X,]Q@`"( +M#2"!RB!A`(#AP'IAN!MX!7H?"A0!SW"````.`(`(Z`#8SW&@_K`$G@A@`9:X +M`-K/<($`_"+T((``HO'/<(``A`U`@,]P@`"\#2"``=AAN8#BP'@[>25XSW&! +M`/PH]"$``([Q`=B,\>!X\<"^"8_W"'7/<*```"#;@(X,X`8H<`(E`1`+"5(` +M/F8#\*)X`GX)`J_WR7#QP.'%`!8!0`AURQI8L``6`D#9&IBP9,L7"!`'SW.@ +M```$9(//<```W`[V#X_WJ7!2">`'#MF@E4DE#1D#\(H(@`#/<*````0.@/<( +M1(.]`8_WX'C/<($`_`C@?P"`X'@`V`*C`=C@?P"CX'C@?N!X\<`2"8_WSW:! +M`%!0))8"N3`AD`^@`+0N)I93(=(`JP@0`"^.SW"!`&A2-GA"B,S)SW&@```@ +MNA`1![J!#HZ`X(@`*0#*):D0T.6``"4`RB4E$0#?\*%0V$4B00(8VB#;M@T@ +M"$HD``#XN,HE(A(N]`/8SW&@```(`J&$V@`8A%!")0T8`!A$4T"&`!B`4$*6 +M`!B$4,S)1(``&(!0S,E*D``8A%!`*@`C@KA`*`(E!7H`&(!0X:$.C@'@#J[F +M"2`'*G`!W3CP`-T$E@IQ`-_I/'`X@]/]PAU +M*'9(=QX+(`$`V`79%;FHH1P9@`\`:@``"H&HH<9XY7@)H1P9@`\`:0``&@L@ +M`0#8%0"/]_'`X<4(=>H*(`$`V`78%;BHH!P8@`\`:@``JH#R"B`!`-@!`*_W +MJ7#QP((/3_<(=BAUO@H@`0#8!=@5N,B@J:`<&(`/`&D``,8*(`$`V,T'3_?@ +M>.!^X'@B#,_ZX'C@>.!XX'AI((`!;R$_`&D@``#V\>!X\<#AQ1(*K_PSV!BX +M3R`-!)&]SW"!`%P?+@Z@!I*]*+B-!V_WI7C@>/'``=GAP<]P@`"4%""@BW`$ +MV8H.(`8H#NAN#``#@@L``U/*`>!3&@(P +M&]C6"^`'R7&!\%(,``,B#0`#!@E`!GX+P`?6#X`'R@H/_X(/X`4!V&H*P`*. +M#,_Z[@L/_XH@Q0_/=:```"`+'1B0SW&``.`5`('`N`"ASW&``-P5`('`N`(+ +MX`$`H6(*3_HJ#L_Z3@I`!L]PH```$,F@L@G`!4#9!=@5N""@\@H``Q8+P`9" +M"L`&F@R`!6H.0`$R"H`"6@S/^A8-0`)."H`"&@H/^_H,``#&"X`%F@V@`@_8 +M"@W/^&X)@`-&#(`$P@H/_SX-0`9:#,`%]@W`!;8-P`5V#0`"*@_`!?H(8`,! +MV,]PH```,#`8@`\`@````H6$N`*EN@O/^J8*@`;/<```_LJZ"<_Z.09/]^!X +M\<"^#4_W\@]@`@'=@>#`??H.X`:[?0#9SW*@``!(SW>@`(!$SW"@`(Q$.*!D +M&IB/"`````C89!H8@,]VH```10`>@!\`0```X'@@IL]P@`!\`1!X%*?/<(`` +M^`,0>!6G--@1IQS8$J`&`=AX'X`?@````'P?@!^`````8!^`'P!&.`!L'X`?``8;`'D% +M3_?@>/'`X<6:"6_Z:B5`$0ARRW-\V(8+K_>I<6D%3_?/<*VK_LK@?N!^X'C@ +M?P'8X'\`V.#)M;C@?^`:&+#@>.')F[CA&ABPXLF5N.(:&+#CR8>XXQH8L.3) +M@+C@?^0:&+#@>.#)E;C@?^`:&+#@>/'`G@Q/]PHF0)`(=0/R&PT2&,]R@`#X +M%,]P``#:#JEQ_@JO]T""SW"``"`5M7CA!&_WP*!!*$(!SW&``(P3\"&!`%,@ +M`@$`V`\@@``D>$(@`(#@?\H@8@`"(0(`$PZ$<`"````P<`'8PB`-``+P`=C@ +M?N!X#WD;"74!`-J$*0@%`"&!?X``I!I@@0L(P`!(<`7P`8'["%&``=C@?H0H +M"`7/<8``K!HP(4$.`-B%X/'`X<7/=:```!PVA>3)SW*@```@)'@3"%X!=Q(`AF(/ +MS_H@V`;P#P@>`/8/``8!V!:E#01/]^!X\<#AQ<]UH```(`0=F)\@`'\`!QV8 +MGP$`0#P^#<`&BB`$``"EX0-/]_'`8@M/]P#=SW2!`'`>J78"\`'E&0T5%,"$ +MSW>``-P'OF;#OO0GCQ/K#U^2X6X[#344X*0`W<]T@`!0J[)7O/<(``W`<4((P#8+0@X-5X0*`"\!#>90-O]\EPX'B)N`#9 +M`O`!X1<)%03/!_*'#/``@C`^``/@5`H0/(,```J0YV`0<@!\``(``I:X`:3@?O'`<@IO]P#9"';/ +M<($`D"$!@*+!0<`!V$#`SW>``/@5(*=')LT7Q+T4\"\H00-.((0'SW&``#@6 +M\"$``?_:%.$5>4"ABW&F#^_X*'(0)0T1[>U*)@``"B2``2OP+RB!`TX@C0?/ +M6<$$04`\")``R*!!29&`04D1`#[8V.#((<4XF5Y(*<5>J"B +MKWF$*0@%`"&"?X``I!I`(@$$1@_O^!CB$"9.$]CNSW*@```H`!J8@;,2`89` +M+``!AB$##(8@_`,E>+,:&(`$&H"/.@1*<`4";_>BP.!XP=G/<*```"C/D&ABB($`$.A`-FU&%B`X'[@>,]P@`#X%>!_`(#@>/'` +MG@_/_\]P@`"X$P&`SW&@```H@B`"``T9&(#/<:``@"83@8*X$Z$3@88@`PP3 +MH='`X'[QP`AQSW"!`"P@`8"BP4'``=A`P,]T@``X%O`D0!!2:51Z`"*##X`` +M^!5"@Q5\$"("`$*C1803"8$`_]DEI(MQ,@[O^"ARHL#1P.!^`-K/<*```"A5 +M&)B`SW&@```D$!F`#P``_W\;V`>A2Z'@?N!XA"@(!<]Q@`"L&C`A0P[/<8`` +M.!;P(0(`SW&!`(PI\"'!``.Z6'D"N!1X`"""#X``!!;@?R"BX'@E"!4$`-O/ +MF"B8:(@X15Y8*'@?N!X\<#AQ0AUSW&@```D +M2H$B@0#8(*46ZG<)WP?/<(``I`D]@`K89.&.#J`'C+@,,]Q +MHP"`5QB!AB###QBAX'[/<*,`@%<8@,]Q@`!<%H8@]P_@?P"AX'C/<*,`@%<8 +M@.!_#WC/<*(``&P>@(8@^P_@?RBX\<#F#\__`>`/><]RHP"`5QB"AB###R5X +M&*+1P.!^X'C/ +M@<\@(@+0("$"'J'@?N!X\F;WEW"5$`!".!#P````\HN6<)40`$(X$/?P``\"RYJ=I7"8$` +M!.`E\&"``"6!'P``0`K$N_5Y9*E@@`'G!".##P```/\HN\2[9:E@@.]_!".# +M#_\````PN\2[9JD$$`,$!".##P#_```XN\2[9ZF]#X*0`=@2\`38&*YGI@_P +M"!``(3)P`MB*]L(-X`$#V`\(@0\``!@*!=@8KN$%#_?@>/'`L@@```KHSW"` +M`*RU!)`?"(,/```-#B((```+Z,]P@`"LM020#PB"#P``#0X!V`+P`-C1P.!^ +MX'\!V/'`2@T/]\]P@`!<%@"`SW&``,RV`-WD:9SHSW"``&`60(``(8X/```$ +M$$T6`)8E"@$`D@W``0WH-">`'P``&`H1"(`/``!$23P6`)8"Z`'=SW"``)@1 +M%8@3"%X`SW"@_G@)`=D&"._^J7)-!2_WJ7#@?P#8X'\`V/'`X<"+<,]R``#_ +M#%8,X`4$V:'`T<#@?O'`M@P/]\]W@`#,ML8-[_^D;PAVSW"``%P6U@WO_P`0 +M$``S"!`@5PZ4%P#>X@WO_\EP!]D`)X`?```$"C"@9@@@``R0E27-$L"EH@_O +M_P?8)?",)L.;T_>V#>__`=@'V0`G@!\```0*,*`Z""``#)!Z#^__"-@V#<__ +M`=B5)9D"(``%VO'`$@W/_\]Q@`!<%B"!!>F`(`,, +M$'C1P.!^X'CQP-X,S__^#,__BN@F#>__`-@^#>__`=C1P.!^SW"``%P6`(`$ +MZ%X(``#X\?;QX'CQP*X++_<(#N__`-G/=H``T+8.Z(#CS"5AD0/R +M*'`0\#`F@!\``#@*^^AV"T``,":`'P``[`P0=P#8RB!A`(GEU0,O]\H@80#@ +M>/'`U@O``<]Q@`#0PX/H`=@+H0N!C^@!V`NASW*``&06!H($@""`QW')`8## +MP@Y@!DAPT<#@?N!X\<#AQ<]P@`#,MJ1H`""!#P``!`T,B0L(40$!V`JASW"` +M`(`6/@Y@!I8E!1``V`^E<0,O]PZEX'CQP.X*+_>8<0AV2'4*)8`/@`#0M@"( +M)@I@`"")"'<5#1$1,"6`#P``'`J`X,HG(1`3#5$1,"6`#P``*`J`X,HG(1`1 +M#5$1)@W/_X#@RB`,]PH/Z8 +M"7(-K_X`V0'?M0(O]^EPSW*``,RV9&H(N`0@@`\```#_!7F6(T8'(+,`(H$/ +M``"$#!V!`>#@?QVAX'CQP`H*#_<(=2AW6G)H=@HA@"^``-"VL.#,)R&__2G&!X,H@00-`#^'_RB'!`P'=6@D``\4! +M+_>I<.!XHL'QP&()#_=EP&;!SW:@```@;!80$(#B`]TJ"V``RB6"$(#@`=C` +M>"\@`(#/=X``T+8L](7`AL%&#N__J7*`X`38)/(EP";!VN!:W,PA`8,&\K#@ +MS"$AC`#;%?0`)X,?````"DR3A>4$(H`/````_TBX96;"S"5BD@+RL(,! +MV]8.[_^O>HGH6X8O(0H$66$!X94GS!\@IPS<,P$/]_'`X'C@>.!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XT<#@?N!XSW&` +M`#*V5R'`#-T"(`8SVO'`A@@/]\]V@`#0ML((```(=83@RB"&#P``)@G@#B;W +MRB%&`X0MB!G-`"_W`"&`<_'`X<5Z"^__"'6`X*EP!?(2"````_!2"```M0`/ +M]^!XC"##CP#9%_*.X.$@Q0?`(&4`EN#`**4`X2#%!\(@)06BX,`HI0#A(,4' +MP"`E`PL(U`DH<.!^`KB"(`("X'^`($(%X'B,(,./`-D1\H[@X2#%!\`@90"J +MX,`HI0#A(,4'PB`E!8P@0HW#]RAPX'X"N((@`@K@?X`@0@7@>`L)-0,`V@"` +M,?`-"94#`(`BN"WP"0F1`TAP*O`+"54,`(`DN"/PP.$$]P"`)K@?\.#A!?<` +M@"BX&?",(0*$!?<`@"JX$_",(4*(!?<`@"RX#?",(4*)!?<`@"ZX!_"]#D3P +M``"U``"`,+C!N.!^X'C/<8``S+:`D``A@P\```0*C+,!D$1I4R`!`">C'7G` +MN2BC02B!`,"Y*:-!*,$`4B$!`,"Y*J-!*`$!4B$!`,"Y*Z//<8``K+4DD2$) +M@@\``$`.!""!#P``X`\EN3`;0@#LN`'8P'@)\#_9,!M"`"6X4B```,"XEB*& +M!P"B`-C@?PVCX'CQP+X.S_8`WL]Q@`#,M@`AC0\```0-`=_/<(``K+7EI<"E +M!)#7<```#0Y`(1`!G/;%I9X.H`$#V`AVK@Z@`0/8".BF#J`!`]@1"((/``"0 +M"98.H`$#V(CHY:4`WHH.H`$#V`"E$-@`()`O```Q"@`8`B"U!N_VR7#QP$X. +MS_:&#\__O@CO_PAUSW:``-"V!N@!V)8F11$`IB7M5@G/_PSH+@Z@`0/8".C/ +M<8``S+5J""`&,]H`V@[PSW"``,RU]""````B@0^``)BV2;@`J0'BZ0K4C`X* +M``"`X(`*(0#*($$#50;/]N!X\<#6#<_VHL$(=BAW"B"`+X``T+8`W8KPBW') +M<&X#K@E +M>`,4@3`&Y@0A@P!&NQ"[97AR;71[FV,&HT0A``-"N,&Y`KD%>0(4@#`!Y00@ +MC`!&O`2\A7E$(`P,1+P&O(5Y1"`,`T*\P;@(O`JXA7D%>044@#`$>D:Z#+I% +M>40@`@R&(/\,1+I"N`ZZ$+A%>05Y(<`GHPAQ"'*&(?X/GFF&(OT/FWQ'NH5Z +M1"`,"$6\`KR%>D0@#`2&(/\-1+Q#N`.\!+A"N85Z!7H%N45Y**,`EP/@`+#A@1J`AP@,4@3`(ND5Y!12",`CG$+I%>2>@ +M!Q2",`84@3`(ND5Y**``$``A`>8$X``8!"`R)8`?```Q"I\.!)"6)0086!V` +M'P``=?1<'8`?``!JI(H@Q`X8I4T$[_:BP.!XX'\`V/'`V@O/]AIP`@^O_RAU +MSW:``,RVBB<1$R/H[@Z/_Z'H"G`D;@X.X`6*(D4+"G"`((L&R7&`(8@*^@W@ +M!8HB10L*<(`@%@W)<8`A$03F#>`%BB)%"P"5@"!1`@"U"O`*<"1NT@W@!8HB +M$0,`E1]GX+71`\_V\0`$0HO@9">0`A3@Z,)@J9RB"& +M#P``)`D,"2;WRB&&`P`E@!\``$0*SF`R)8`?```Q"A!VRB"&#P``)0GH"";W +MRB&&`]D"[_;)__J7":<$`@`"%^"N__BG$(=@HA@(/*(6(`H+_E>9,.$!""Y@'8P'CS:,]R +M``#]_P0A@0\``/7_1'\E?QMX!7\V#^__BG`+Z`0GCQ\``-__@>8!V,!X!;@% +M?Z:_`-@/#I`0@>;1)R&1`O0!V(#@RB!B``:XY7@[#;03$'DR(T,C"!`"('UY +MP+E!*LP`P+R$>0JYSW0``/_]!""`#P``__F$>05Y"PK?`>"[SR%B`@`91"`! +MY4,-U)Q6(@$B#I&IN`ZQ#I&JN+D![_8.L?'`<@G/]@AV`-T.\!()[_^I<`AQ +MV@CO_\EP"'&2#6_[J7`!Y>D-U)RY`<_V\/'`"'//``,RUBW;)<,]Q@0!P(38+[_80V@`< +M@#0('`0T>0E1(#`E@!\``$`*-"6!'P``Z`R"X,PA@8\``$)#!_0$'(0_``!. +M0P/P!!Q$,``E@1\````0.Q$"AI8E!!4"NE1Z0F4''`(P!AR",#/80\``V@CP +M]">#$!)J@W!DH`'B]0K4C$$1`(:.Z(3"R7`0V48(+_[,VPCP`-A#P,EPV@_O +M_1#980>O]H`D`S?QP`H/C_:Z",__SW&``-#`S)$$)H`?````_T(H#0((V!"A +MJ7#/?KH((`#)<8#@RB"!#P``(PG*(4$#4`WA]LHB@0.I<,EQ!]JJ#*__`-LM +M!X_VX'C/2"PX'[@>/'`X<7/%R#N__/J*R#:__"'7>"^__J7#*#.__ +MJ7"I!H_VP>`!VH?VVN`%]L'A@_;:X<+V`-JPX,PA(8P&\H#@S"$A@`/T`=K@ +M?TAPX'CQP.'%SW4``*W>`8#/<:4```P(H0'8":'/<8``P`VV#^```*'/<0`` +M556`X,H@0@!)!J_VRB!!`_'`N@V/]J/!"'4#W@&`&+[CN,HFXAC`+B(6T2`B +M@_V#-HAA/'`(I`(`+P``555J"R`` +M`-Z:=GIV.G;)<=IV6G8:=@GP`X4/(E(@W1H8L.EQ0"96()D.E2$R)8`E]PC0 +MC^%I`-M+C0\C@P5K>@#:SR)"`,HB(0!%?DJ-:WH`V\\C0@#*(R$`R0@UA04A +MT2`S)@!P@0!H'T`G`G(4>@!Z#R%1(-;QSW"@``!'`!`0``\C4R#.\4HD0"#, +M\8H@"`4`V0#:_@LO_Y"ZQ/&*(/\/SW&E```@`:'/<*```!T@&(`/``@```#8 +M`J&T\8#ARB"!#P``K=XC\A05!!`!A2*%0X4^"R``9(7)<((*(`!*<2IP8@P@ +M`&IQ$!4$$`IP%!4%$"&%0H6."R``8X5,)`"@I`L"`$(-P`#J<)4#C_;@>/'` +M8@NO]E8@0P+/=J``P$;/=:``X$;/0$'E`0(H<$ +M'5`0\0P4DC&`SW"@``!&):``V`?P\",!``'@!!I0`/D(E(`!V<]P@`"L$""@ +MSW```%55;0./]N!X!.#//'`X<6Z"^``M,$FZ/(((`"+=4X((`"I<`#:8<(_V04<0C`&'$(P +M"-@''`(P#-ABP!+8"1P",`P<@#].T*^KBB"(!$3`"QQ",`H<@C!%P@(.[_^I +MV$!Z$'P``_P_R#R_X +MR7"EIA@>@!\/``"``=@Z<`>F(!Z`'P`\$``&V!IP"::*(`0`"J;@IF8,[__) +M<,(/+_C)<`/8!:88'H`?^____P78!Z8"W^BF)!X`%*JF#M@`ICX,[__)<)8/ +M+_C)<*6FIJ8<'D`4J*;IIJJF$]@`IAX,[__)<#D"C_;@>/'`V@FO]HH@SP^T +MP00<@#^@````"!R`/Q\`__\,'(`_H``,!$3`%!R`/Z````Q&P!P<@#^@```` +M2,`D'(`_H```<(H@WP]*P"P<@#^D````,!R`/P,`__\T'(`_J````#@<@#\# +M`/__/!R`/Z``%```W5#%4<6*($0`4L!3P(MV]@WO_\EP@<"I.XPC=P'W*)($0SW*@`*!'D^,0W\HG0A/*(X$`RB," +M`__:*'00\!8@30#&A14C1```'(`#Q84!X0\DC1-0=LHD0A/E"=2`SW"@``!' +M/X#X>D9Y^'PE?)^@\0"/]N!XI<'/=*```$<"I`4DP@!0I$0<0!'@?Z7`I<%` +MP$'!(,$!%(`P!2&!#P```#\0N`5Y!2&!#P`_``#/<*```$8HH`,4@C`"%($P +M"+I%>2'"$+I%>044@C`8ND5Y*:#@?Z7`SW&@``!(`!F`CX`````%V!6X+!B` +M#P"`T```V($9&("`&9B/`(```.!^X'BEP<]SH```2``;`(`,&P"!+R)(`8$; +MF("`&YB/`(```.!_I<#/<:```$8`@44@P`$`H078%;@L&(`/`(#0`.!^SW*@ +M``!&(!J`#P,+`C_;R=P2`;8P<#_8RB"B`@4@@`\_/P`2":+@?J?!0L//<:`` +M`$<`H0@4`#%((``#$+@$((`/#P````4@@@]`!@"`"A0`,!_I\#; +M$@*VW!(!MAL*0``=>,"X&WA%($$!SW*@``!&`((E>`"BX'XF>,6XSW&@``!& +M`J'@?N!X`-G/<*``@!TUH#:@/:#@?@/8SW&@`(`=':$6@44@0`P6H509@`\0 +M````X'[/R"C`>+K"A2(X'_!Q>!XX<43"!`! +M!+@4>``@@0^!`(PC`-H-\,]P@0`<)$Q@SW.@`-`=\"&``)5[`*,!XNL*%(/@ +M?\'%X'A`@,]QH```'UZA`8`?H>!^SW*@`(`=/(+%N$8AP0\E>!RBX'[/!^X'C/ +M<:``@!T6@;6X%J'@?N!XSW&@`(`=%H&QN!:AX'[@>,]QH```.$"!SW"``)09 +M0*!!@<]P@`"8&4"@0H'/<(``G!E`H$.!SW"``*`90*``V`"A`:$"H0.AX'[@ +M>,]P@`"4&0"`SW&@```X`*'/<(``F!D`@`&ASW"``)P9`(`"H<]P@`"@&0"` +M`Z'@?L]QH`"`'!JAX'[@>,]QH```'A>!!2"`#S0`O"87H>!^SW&@`(`?@.`; +M@<\@(@30("$$&Z'@?N!XSW&@`(`?@.`;@<\@H@?0(*$'&Z'@?N!XSW&@```> +M%X&#N)2X%Z'@?L]QH```'A>!H[@7H<]P@0#\!P"`@>#,("*!!?07@;2X%Z'@ +M?O'`?@_/_S8)K_8"V-'`X'[QP'H/S_\!V<]PH```'CF@T<#@?O'`"',!W(8* +M+_@`+``0!_``V)(*+_@/(,``?.C1P.!^`-D/(0$`SW"@`(`>*J#@?N!^X'CQ +MP'X,3_;/=8``%!(#A4`HD("AP6WRSW:@```,[8;R#F_^BW`*(8`OH```$(/H +M/P\%%`"%0X5!*($`(GB?"(4`FP\4'H2%!H5`+P,4F&`&I1"\`,?/<*#^%`$" +MV85ZF@@@`.5[#@D``#GP0"#`(00@@`\``/S_G;B?N#`9&*``'X!/`(#W`,]R +M@0!D,`/PR+DBI62%(H7P(D``&.N`(_^/.+ADI0';PB/!``'C>&``V]\+!8#P +M(D\``!_`0X.%`>%AO(.E`>/V\0'A`J8#V`>F`X4BI6&X`Z4AI2V&`(4"N`\) +M!0`#V<]PH`"`'2:@]0-O]J'`\``? +M`$"#P@#9"/`$XOP2#(`!X0`?`$,"P/4)!(#/<*```"`;@`(;&(`#V`<;&(#1 +MP.!_J,#@>`#8SW&``!02!*$#H0&!X'\"H>!X\/'` +MS@I/]@AW*';ZQ*!"B6`(5,@T0(3@0HD0"%3(-`"SW"@ +M``!\!!`6`,]U@0#\%P#86G!`)0$;(@V@!4`E`AP&V`"ESW&@``!%'('AI0*E +M'8'$I0.E%!W`%1@=`!8<'<`4(!T`%20=0!7R"Z`%`-@*I<]QH```(!J!SW>! +M`/P7#:4;@<]VH`"`'`ZE'(%$'8`?!0`$A`^E%M@0I:8*[_XHV!*EG@KO_@#8 +M$Z53)\!U%*79R5@=`!<7I<]QH```'`2!5!T`%QBE!8%X'8`4&:4&@5,F`B,: +MI0>!$+H;I1:!'*4(@<]Q@0#\%QVE?!F`"L]PH```11Z`SW6@```@@!D``,]P +M@0!\&`08``O/<($`?!@(&(`,.H8CH,]Q@````"2!)*`O(4<$"+DE>B\A!P1% +M>26@Z7!6"Z``)MD$'H`?Q>ZGD1N%`:;I<`X,H`8GV78/@`:U`4_VW1("M@MZ +M$O+/<*```"#/Z"X1N``:)3(8`$G[@!HN!^X'C=$@.V"WL4 +M\L]PH```(,]SH`"`'`0;@`_%[H/A&X`!HU,A@`23N)^X`:-!H^!^X'C=$@RV +M"WP5\L]PH```(,]TH`"`'`0<@!_%[H3A&X`!I%,A@`24N)^X`:1!I&&DX'[A +MQ=T2#;8+?8AT%_+/<*```"#/=:``@!P$'8`?Q>Z%X1N``:53(8`$D[B4N)^X +M`:5!I6&E@:7@?\'%X'CAQ>'&W1(-M@M]B'0A\J)J!26-'\7N@.'/=J```"#/ +M<*``@!RAH+N&TKFAH$`JS02E>9^Y(:``W07P\"1!$R&@`>4/#840>^OP(T$# +M^?'!QN!_P<7QP'8(3_;H$@VV#_`O*$$#3B".!Q)N0W#N$`"&$"6-$S"`8'G) +MS)"^@/"%`` +M@N#*):$0!?#KR8#@RB5B$.W)`-[K&IBS"N@"#L_W[1(!MF!YJ7#M&IBS:0!/ +M]O'`]@\/]@AUY\F,)?^?!B4.$,H@@0\``!,T3`Y!]ACN4@NO]JEPY\FE>.<: +M&+`O*($#3B"-!Z]]$FU#<.X0`(8I@&!YJ7`0)DZ3\_6B#<_W%0!/]O'`F@\O +M]@AS&G%(=H#B`=S`?`#8ZQH8L.P:F+#F$@*VLPL0`.@2#;;ER00EP9"D>.4: +M&+`(]&9XY1H8L*4*$0`#V%'P!2)#`&AU$/`O+T$33B>`%P]XA"@(!0`ACW^` +M`!`<@*<0)0T0\NT&(8T`Z`8'GI8\""$`RB!A`.82`K:` +MXLPFHI`+\@'8ZQH8L`L($"#M&ABT`=@)\`;J%@@@``+8!/"^#,_W`-@A!P_V +MX'CQP+8.#_;F$@&V"'7L&ABPBNGK$@*V@N+*(((/```,-!@-0O;F$@ZV$/`O +M*($#3B"/!^]_$F]#<.X0`(80)LX32(#I<&!ZJ7'Q[FH,S_?5!@_VX'CJ$@&V +M#R$!`%4$[_?J&EBP$0`/_/'``-H/(@(`Y\E&>.<:&+`'Z>7)17@V#._WY1H8 +ML-'`X'[@>/'``-D/(0$`YLDR>00@0(#F&ABPY

.4:&+`*].O)$0A1`/H- +MK_D$V`+8ZQH8L-'`X'[QP.'%J@^O^0AUSW&!`$!+%7D`@1`@0`-9!B_V`*'@ +M>/'`R@T/]@H@@"\```#("B*`+_\/__\`&8`/`0``D'(/K_DZ<<]Q@0!`2_`A +M#@`;\"\H@0-.((T'M@]@!:EP"'<*#V`%J7#5N`(G`1`P<,HA!0`/"84$`!G` +M(UIQ&G`0)DX3Z.[%!2_V"G#@>/'`X<4>#Z_Y"'7/<8$`0$L5>0"!#R!``\T% +M+_8`H>!X!8`!V80H"`4`(8!_@`"7'.!_(*C@?N!XX'[@>.!^X'CQP"H-+_9* +M(4`0HL$`W$HD``B)`'C;WOSZ`#: +M^'38=!ETN'0W\#(DCC"*)0@5K'[/<8``I!H`(4`.-!`+`$`A"@P%)L8"SW>` +M`.0;NA``!T`G"QP()`P0K'XG=QJ7"PT#`#(7!1&L?C0C0!X((`@0K'XP(D`> +M@.#*(2$0K'XG<581``8!X@4G!P`+@4]Z!"0$`)<*PH#//'`U@LO]JS9SW:``*0:R7!&"^_WC+D` +MW1?PA"T(%8HA_P^`VJEP`"9,'B"D`"&!?X``'!Q`J?X,(```V:EP!@D@``#9 +M`>77#521_]G/<(``)"7U`R_V(*#QP`#8`O`!X!T(50&$*`@%SW&``*P:,"%! +M#N\)48$^#D_^`_``V-'`X'[@>(0H"`7/<(``^!LP($$.SW"``+P4`(#@?R1X +MX'@`V@/P`>(?"E4!A"H(!<]S@`"L&C`C0P[M",&``=A`H0+P`-C@?N!X\<`& +M"P_V"':$*`@%+W4`)9`?@`"D&C`0`"``)8\?@`#D&P;H"=@8MR[8!?`4V!BW +M,M@9MTX*[_[))/>ND*$H'Y`@_V\<"2"B_V_]J*(P@%;'C/=8`` +M)"5$I<]T@`"D&@`A@'^``#0<(*``V4AV"_`=@%,@?H#,)H*0!/0DI2AV`>$; +M"54!;'D`)$`>9!`/!GCOXH#=#Q&2)*6I`@_VX'CQP.'%"'&$*`@%`"&-?X`` +MI!H"A87@S"#B@/'`X<4N#:_^"'6`X,H@@0\` +M``DTO`\A]LHA00/HR:]]$"!``^@:&+`J#V_]J7`2;4-P[A``AB:`8'FI<`;8 +M0@RO_JEQ@.#*(((/``![,(0/(O;*(4(#?0$/]N!X\<`((HA"`4L>,]R +M@`"L&C`B0`Z%X,P@XH$.],+)`=K$$```+'@`V0`A@'^``*0<3*@HJ.!^X'B$ +M*`@%`"&#?X``I!N5@P\D3!"5HW)H0W/N$P.&:X,`>_'`;@@O]@AR*':$*`@% +MSW.``*P:`"&-?X``I!LUA3`C4`X`WP\GCQ/D>3!WRB""#P``)S3*(8(`O`XB +M]LHB@@,5A4P@0*'F>!6ES"#BH?0(X?O*(($#@0`/]N!XV'`"N$-P[A``AHJ` +M('S(,\@0@"8#2(&RB'B +M!]'`X'[@>/'``-CE&ABPYAH8L.<:&+`0V/8+[__H&ABPT@U/_<]P@0`D`S8/ +MK_>*(1(`T<#@?@#9#R$!`.?)X'\D>`#9#R$!`.;)X'\D>/'`A@_/]:()8`4( +M=3IPA"T(%0#>`"&/?X``)!S/IP`A@7^``)0<"B!`+L"Q.@@@`*EP`""`+X`` +MA!S,J,^HSW"@```@&X`9V1JG*G`^""_V#+DA:(#@RB!!``.X%7B-!^_U'J>$ +M*`@%`"&"?X``)!Q`&H`/_P___T0:@`__#___`-L`(8)_@`"7'&"JA"@""L]Q +MH```(#N!SW*```@HQW%=``#`>0)@!0`B0`[QP.8.[_4(<80H"`4`(8U_@`"D +M&L*%A>#*((8/```K-$0-)O;*(H8#$PX0$87FS";BD0#8!/09A0+P`=@9!\_U +MA"@(!0`A@'^``"0<+J``V2V@X'\LH.!X\<".#L_U*'4`WH7@S""B@LHF81"* +M[L]Q@``D)0&!$"!``U(,(`,!H:EP%@CO_\EQS0;/]?'`5@[/]0AW*'6$*0@% +MSW"``!P<,B!.#AX);_XH<(#@RB!"`T@)HOO*(8(#Z7"B#^__J7&-!L_U\<`6 +M#L_U.G`H=H0I"`4`(9!_@`"D&E40#2:\$``@!GT,\"\H00-.((\'[W_)<`H) +MK_OI<1`ES1/U[0#9O!A`(%L86"`J<$H((`#)<2T&S_7QP-(-S_4H=80I"`7/ +M<(``'!PR($X.SW"``/@;,"!`#F(+(`8?V:EP<@BO^\EQ%0;/]>!X,0`@`"AP +MX'C/,]R@``D)0&"$"!``%D#(`,!HN!XZ1(! +MM@\A`0#I&EBP405O^078X'CQP&X,;_D%V%X-K__IR0#8Z1H8L-'`X'[QP%8. +M3_YK)D!Y`````&H(C_[B#4_^G@LO]CW8T<#@?L]R@0#`'2"2)7C@?P"RX'C/ +M<($`'!E%`$`%X'CQP`(-S_4*)@"0SW"!`"`(0(`']`'87@H@``#9-O!M#AX0 +M`-D*\,]P@`"8%/`@0``5(DP``*0!X>\)%($`W0?P`-@R"B``Z7$!Y:#M`-\/ +M)T\3$P]0$(H@A`PF"R_VZ7$2\,]R@`"8%`""*+A#@E,@P0!!*@`#P+@%>$!((K_X!V`SH-@\O_@'8B@J/_8'@6`HA]LH@80`` +MV<]P@`#4+""@SW"``-@L(*C/<($`'`@:"J_Y(*"I!,_UX'CQP.'%_@FO^0AU +M$PU0$(H@A`RB"B_VJ7$C\*O9SW"``'0L(*`AH"*@SW&@```@6X%,$0"&$'@: +M8@W;"/!,$0"&8;L0>!IBX'CU"U.`4R+``,`:&+!!*@`"P;C!&ABP503/]>!X +M\<#6"^_U"'*CP0';$PA0`(H@A`PZ"B_V2'$`VDCP`-J)Z<')2'$!X,&XP1H8 +ML&AR,O"$B0"!8<2,B04<`C.-B08<`C..B0<<`C./B0'&,(EBQ`D<0C#/=(`` +M="P@A`@4#3$7"$$`(80/"8$#))2Q<`:Y!7G/<(``="PKJ$APF0/O]:/` +M\<`>"\_U"'!X\<#AQ0AU +M!=K/<(``V2Q`J,]P@0"(#2"@SW"!`#@9Z@T`!8'ERB""#P``,@$8"2+VRB%" +M`Q$#S_7QP,]R@0`<"&""!^O/T""T<#@?N!X\@`C<]R@0`<&6&X`*T& +M@@2`(("`(8(%Q@T@!4AP:O``W?8.H`2I<,]R@0`$#B""SW:!`+P=`*87"5$` +MSW&``#`0(($%Z8&X`*:@H@H@@"^``)@4`-\%\/`AP`,`I0'G(0_5$<]P@``P +M$"1H`(`5(,TC\^@`V%8-H`3IJ"FI0'/ +M]?'`+@G/]<]W@0#`'0"7!^C/=8``V2P`C8/H`-A)\+H*8`0!V)#H`(W/@R@!$*%C@V@!`'8"';/<0``#__V#*`$`=@F#R`& +M!-@@EP'8Q7F&#:`$"+D`V)JXU]FI<@3;P@H@!DHDP`$B"F`$`=@!V#(/S__I +M`,_UX'A)!\__\EPZ7)*"^_U*'-:<"AUZ7(^"^_U +M`-N5%@*6M0J0`)H6`I93"E$`C]HF"^_U`-L:<#IQ2G"I<<]R``"O4Q(+[_4` +MVP`@#83I<`$A42``V<]RE@&VEOH*[_4H`,]U@0`D'^8,K_VI<`#8`:7I +M!X_U\<#AQ<]P@`"LM0&``=TC"%X`SW*``+@L!H($@""`QW$#`)#0U@H@!4AP +MJ7`"\`#8M0>/]?'`5@Y/]P#8T<#@?IT%[_4_V.!XSW```*W>X'[@?N!X\<#A +MQ5((;_T`W<]Q@`"$M2"!-@@@`""!'@A/_07H@@TO_0'=#?`R"$_]@.`"V`CT +MSW"@```\!X`#Z`/8"'55!Z_UJ7`2Z<]R0````"BZ*+E98<]SH```/&&Y!>A0 +MHS&CX'Y+HRRCX'[@?N!XSW"``.PL`(`@Z,]P@`#H+`"`!=D5N1CHSW*@``!' +M`(+>N`"BSW*@```\9X()@B:X>&`'H@'8`*)GH@.BSW"@_E0"!*'*R0NAX'[@ +M>.!^X'C/`39SW"@``!' +M)*"A````X'CQP'8-C_7//'`X<41\"2%SW```)DA3@O/]0OP +M)@GO]0;8SW"@`(`@%X#DX/'WSW6@```\!(7I"!Z`*06/]>!XX'[@>,]R@`#P +M+`""SW&F```$&*$!@AFA`H(4H0."%:$$@A:A!8(7H>!^X'C/<:```"`0H0'8 +M!QD8@!#8`*'@?@+A,'E!:0T*!0`B>!!X`_`"V,]QH```(!"A`=@'&1B`$-@` +MH>!^X'CQP%#:SW.@```@0:,`VE"C`B!"`%"C`=H'&YB`0-I`HP0@OL\``@`0 +ML`_!_]'`X'X.Z/7)SW*@```G$'$!V,!X`KB!N`"BX'_T&EBPSW&@```@$8$9 +M"!0&U.!*]P#8$:$7V!&A`M@'&1B`X'[@?N!X`-CT&ABPSW"``"0*%)#/1&"$'@((0$`,'D"V`<:&(`QHN!^`N$P>4%I#0H%`")X$'@# +M\`+8SW&@```@$:&*(!@(`*$"V`<9&(#@?O'`<@NO]8HB$`#/<:```"#@&8`/ +M`P!`#0#=SW>@```!XX<3\',B^_!Q(ON'`X<'APN'#_!P(L?P<2+'\'(BQ_!S(L?P<"++\'$BR +M_!R(LOP'&X`-P3`P#/<*#^``#&#"_] +M`]D1%8`@)PA>`,]QH`"`>Q*!"G*3@5,@Q`++O&*'SW"@_F@`!-F:#"_]N'0X +M%`"F`(<)"!X"+!W`%*H.P`5"#\`%!]@*N,#9&+EZ"B_W`-K/<(``P!,BAP"` +M*W@!V,HE(A-4]`"''PB1`$P@`*#`?07T]@N/_0AU@.7*)2$=1?(!V$3P&0@> +M`'8)+_X@V&X)+_Z*(`@`9MTY\.RXRB6"'P``<0`S],#@*O(-]DD($`%)"!`" +M50@1!$;=SW"``#P2P(`C\(P@"(`<\@;VC"`$@!ST5-T;\"T(@`\````@*0B! +M#P@```#/<*```$W0@%W=#?"&W0OP/-T)\$S=!_!EW07P:-T#\(3=`-B!X.@. +M00/:"T_].A0`IJEP`-D$(D(D$@^O]/'``@BO]0'8`][/=Z```!`P'YB?`*`(```?@$\`@```.G#/=:````P"I<>E +MSW"@`(`=QJ#6#&``&G#/<8``?+0`H2AP_-E6#R`$K=HP'YB?`*`(```?@$\` +M@```"!U`%,>E&!B`(P$`C_7@>/'`X<4(=:8/(``%V(#@RB`A``?RSW&``'`O +MJ6$T>/T'3_7@>!$`(```V^!X"0`@``';X'CQP%8/3_6AP1IP*'9:`?9P250KAI#P40%233(XMQ:G`^"*`$!-H@P0#`X0D! +MA`"F0(8/W0B]JWI`(P`A`:89\B\)$2!!*H`@++K+NE!PP"JB!,H@@@\``&\` +MP"AB`!D)%00&N!5X`KDU>3A@SW&` +M`("O`&$#\`#8X'X"V,]Q@0!`4`"A`=@!H0/8`J$`V\]R@``<+P`:@`\```@( +M!!J`#P``"$`(&H`/```(.,]PH@``;`B`8Z%CHC,('@`9\"D+T`#P(<``SW2C +M``!`8;CP)``04R``A`CR`B"`#P$``(`5(LP``*0!X]D+%('@?O'`"',H<@/8 +M:@_O_PAQSW&!`$!0\"'!``7H!.`U>$"@!O#/<(``:`PU>$"@T<#@?O'`X<5: +M#^__`-WB#P``"O"*(?\/SW"!`/!/M7@@H`'E\0T4E`#9#_`2:11XQW"!`+0X +M0H`!X6*0SW"!`/!/=7A`H,]P@0`P4`"`X0D$@,D%3_7@>/'`0@U/]0AU&G,> +M8DPD`(#,(2&#!/1N#0``".C)$`HCR#U?_A@SW&` +M`(RO$6$7;A9X`KDT>3A@SW&!`+PX`6'/<(``'"_P((`#(KTU>+5X^@TO]RIQ +M3@P@``AU"05O]:EPX'CQP*H,3_4H=@#=B.BI<(H,(``!V0&`A.BI<`/P!9`` +MV0\A@0,D>!!Q`=CQ!&_UP'CQP'H,3_4H=@#=B.BI<%H,(``!V0&`A.BI<`/P +M!)``V0\A@0,D>!!Q`=C!!&_UP'CQP'X.0``(Z,]QI```1!F!H+@9H='`X'[Q +MP#H)@``+Z%X.0``'Z,]QI```1!F!@+@9H='`X'[@>*'!0,`(<88A^P\E"!X" +M02C"`,&Z86I!*$($P;IZ8C:XP;C/!\]PI@``!!J`PKA! +M:`OP(,($((`/`@```$2ZP;H!XC&X&'H`V(CBRB(M``;WSW.!`"PJ2F,:8H#A +M`=G`>2#8-7A5>.!_H<#@>*'!_!P(M/'`0L`$()`/````&$$HT"(7"%X#SW`< +M1\=Q!2D^``H@P`X#\$$I@``"P0T)'@)3(8(`([D&\%,AP@`BP42Y0"B#('5[ +M5'O/04H?@Y"(8!U([C1P`04$#3@?Z'`X'[@ +M>/'`'@MO]9AP*'1(`(;/=8`` +M="^I=P(@P@-!L4>Q9+%EL0&A>&``I@`E@1\```"`,'#*((8/```M"Q(+[__)<`AQR7#&"^__ +M97D4'(`_`/`!`(7""G#J#"```=DZ<$`@`"$*O0`E@1\!``"`1L&&PLX,(``! +MV04@4`2$PJEPP@P@``'9!2`0(`1MZ7&R#"``2G(%(``$!L+/<8$`X$_5>4"A +M!/``V(NX70%O]:?`X'CQP!X);_44VJ;!`-W/<8``H+.F#&_UBW`$%!`PSW"` +M`'BO!=D@J%,($"`,%``QC.@(%`(Q`]A"NJES,@[O_PHD``0<\*EW%/#!;YX) +M(``2;D7`\"#!(Q<(0``E>$7`A<+)<"X,(``!V05]`><(%``Q0KC9#P20J7`- +M`6_UIL#@>%,B?H``W`GT`K,BN2"S(KI!LXEP`O`$V.!^X'CQP,X((`#AQ<]U +MH```(!N%1@D``!N%[0!/]>!XSW&B```(!H&AN`:AX'[@>/'`SW&B```(!H&! +MN`:A\@Z@!0K8Z@Z@!0K8`-C1P.!^\<`^"$_U*'5(=@;PRK@"N`3@'67J""`` +MJ7`)#843^.B-`&_UJ7#@>!D)%00&N!5X`KDU>1EA`"&`#X``?*\#\`#8X'[Q +MP`AQ`-KB#^__2'`#Z`&``O!(<-'`X'[QP`AQ`-K*#^__2'`#Z`20`O!(<-'` +MX'[/<*(``&P'@.!_P+CQP.'%SW6!`&@>`(4/Z,]Q@`!TKP"!(K@!X`*X`*$` +MV1X/[_:/N0#8`*4-`$_UX'CQP,]PH`"`3%.`O@_/_P#9@^HH<`/P_^@!V-'` +MX'[@>,]PH@``P`2``=H(<88A_`\FN88@_P,DN(#@P'H`V`T)40"`XLH@8@#@ +M?N!X,""`#Z,``(#@?N!X\<`*#P_UH<$*)X`O@`!T+PHA@#^!`"`>P@[O_P`9 +MP#5`P`H@@#^!`#!0"W"*#N_V$-D`P$HE`"#O"!$`N@CO_PHA0"56"<__.@D` +M`*IQ!/!`(5$@TPD5(4HB0"`F\"+M0"F`(15X0"J"(%5Z&F+'%1Z6&``((X/@0"T.`*6 +M4PB!!`&60"B6``"60BZ"(``@4P45)]`D*G`*<4H((`!BAL]P@`!TKR"`"G`5 +M(<$$%@A@!$(N@B``EB&6&6&S>#5X2"```!UE(K@`)!0@Z7$!Y\CQI@W/_P#` +M(08O]:'`X'CQP.X-#_5Z<%IQ.G(:&?#/=X``'"\5)\\4`(<`)@T4C"#_ +MC\H@@0\``.,51`Q!]0"'C@[O_[5X%2*,(P"D`>;3#D24!08/]>!X\<":#2_U +M"=FBP0HC@"^!`+0X:G`B#>_V";D*(8`O@0`P4"IP$@WO]A#9"B2`+X$`X$^* +M<`(-[_80V0#>`O`!YL<.%1$*(H`O@``<+_`BD".*)?\OZPA`I0#="G`/\`'@ +M'645(H\C`(>R<,H@@0\``.,5M`M!]0"'M7C^#<__8>@$(($/`/```#RY!!Q$ +M,`0@@@__``#`+KH`'(0PRK@"'`0PEVX5(8,C0(.6?/)J]'_\9``4!#!B=`04 +M!3``'``1!!Q`$>%M`>+@XN*D0*.Y\X\)T8,5(HTC`(6R<,H@@0\``.,50`M! +M]0"%C@WO__5X`B"-#P$``(`")0T4(KT5)(PC`*2O\>D$+_6BP(HA_P_/<*`` +M@$PSH.!^X'CQP(H,#_6")`0P&G`Z<5IR`-[/<(``;"_`H(MP_@OO]HHA!``" +M\`'F:0Y%%!4@CR,J#>__Z7#YZ!4BC2/I<&(((``@A0AR%@WO_^EP((4P<,PB +M(8#I\\]QH@``P"2!SW.``'RT(://<8``>*]`B<]Q@`#\M%5Y3X''=Z,``(`! +MXD^A((4)HRBCYZ.*(!```_``V%D$+_6`)`0PX'CQP.H++_4`VGIP"B9`D,]W +MH```(&P7$1#*(($`;/(*(H`O@`!L+P`2`""*X(H@$`!B\MH(K_W)<((/;_@: +M<``CC2^C``"`P*5`(``A12C^#4X*H`4O<$H*H`6*(`\*0@J@!8H@#PHN#,__ +M@.`!V,!X>X$OI"7PAH*Q=,HD1A.&HL]T@`!XK^",%2+,`_^$`>?_I"4) +MD0*\%`$0`>&\'$`0)X*,(?^/#?3(HB"%IZ(IHH:X!_"!@@L,11`AHJRB*X)Y +M82NB40,/]?'`Y@H/]:7!H@KO_P#?"B.`+Z```"!L$P`@`=G/>$YU`!!@#/<(``'"_P(,`#C"#_C_7S`=@0\$(M@B!*(0`@%21$ +M).EP2G&:#Z__*G,%(!`@0")`(,<(-81:<(/GS")AH?CSUP@1(#9O-7E`*H`@ +M%7@98<=Q@`!\KXMPL@TO]13:Z7!R#:__2G'DZ`04%##%#!"@"!05,;T-4J!3 +M)7Z@VO4,%``QFP@0``H4%C%"+I$@`-T.\`(E@Q,5),0@Z7!*<1X/K__)<@4@ +M$"`!Y5,-110`W@3P`>8!Y2,-110.%`(Q%21`(T*ZSW&``'2O((&Z8E5Y,@GO +M]@3:[NAI[NEP;@OO]DIQ6.C'#8&EZ7!*<2IR`-O.#J__"B0`!04@$"`U#D.E +MZ7!&"^_V2G&`X(7U`B6")4*ZA?$*<)$!+_6EP$(MC2``WH#EAO.*(-\/"241 +M$!4DA"/I<$IQ*G*&#J__R7,%(!`@`B5-%")V[O%L$P`@O@C/_^'QX'C@?N!X +MSW%$`/"["&$+")(`''@!X`]XX'[QP.'%=@JO_`AU@@^@`ZEP<0$/]4T#[_8# +MV.!XX'[@>*'!\<#>"`_U&G$(=TAUSW9$`!C&529`'E(([_9,V0'9SW!$`#C' +M(*@#V$<>&!#/<(``%/WCH(PEPY_/=D0`F,9L'@`4!?2>"P``':8"\+VF"-S[ +M``_UX'@`V0KPSW"``*SZ-GA1@!"``>%`H,]R@`"L^P*"Z0D$@,]Q@0``"4`B +M``.Y`B`$!-JAP4#``A2!,`$4@#`-Z0,4@C!0(H$``KD"X>*ZPB!"`,`@00`/ +M>.!_H<#@>/'`&0@S`0AQA"D!`\]P1`!4QC(@0`Z(Z.MRSW````H)E@X/]='` +MX'[QP`AQ#WB$*`$#`"&`?T0`&,8\$(,`3H`#ZQ$)@`#/<```#@EJ#@_UT<#@ +M?N!^X'CQP.H)(``/>&&X#WE%N<]R@`"\%#5Z(H+$N`#;#R,#`"M[!/)F>2*B +MT<#@?@':SW.@```=2Z,,HTR#+*,,@U!Z$'@0N$5XSW&@`(`P`J'@?O'`@@_O +M]`'8_!P,L`(_V!MX8\)(+;_6*(<8`@QD8H(HC&`0"',0P +M`!S$,PIP!-FI@L@`*EP%.@.#"```-X-#=$0(@@` +M``D(4`#)<`/P`=B`X!0/(?G*($$#V@L``-$&S_3/<(``%/W@?P.`X'CQP.'% +M&@[O_PAUA"T!$P`A@']$`!C&/1"!``C@1"D^!ZD&[_0R($`.CN`!V.!_PB`) +M`.!X\<#AQ>8-[_\(=80M`1,`(8!_1``8QCT0@0`*X$0I/@=U!N_T,B!`#O'` +MX<6^#>__"'6$+0$3`"&`?T0`&,8]$($`">!$*3X'30;O]#(@0`[QP.'%SW6` +M`!3]D@WO_P"-`84U!N_T"(CQP.'%SW6``!3]>@WO_P"-`84=!N_T"HCQP.'% +MSW6``!3]8@WO_P"-`(V$*`$#SW!$`%?&^07O]#(@0`[QP.'%SW6``!3]/@WO +M_P"-`87A!>_T"8CQP.'%SW6``!3])@WO_P"-`87)!>_T"XCQP.'%SW6``!3] +M#@WO_P"-`86Q!>_T!(#QP.'%^@SO_PAUA"T!$P`A@7]$`!C&*'`^$8$`1"D^ +M!XD%[_0G<.!X\<#/#`?MM^1@]O_@_8/AF8H]8.S__/=J0``$3/=X$`T%`="%$` +M*@]O_@_8&8:`N!FF`8^>#F_X`*\,\!(/;_X-V!F&H+@9I@*/C@YO^`"O(@^/ +M]DP9F*\``%55`=A+&1B@'@SO_P"-086$*`$CSW%$`%#&,"%`#KH.8`$D@L]P +M@0`<"@:(@^`!V%(*[_?`>`&%!H#_N%P.0?W^#X_V;03/].!X\<"""0```-D+ +M\(0I`0,`V@'A`"&`?T0`.,9`4```#QP-(,8`#AQ=X+ +M``%."R``#]@6#:_\"'6*"X_\SW"``*S3.8!Z@$\A`@2!XQ>`RB&"`)?HSW*B +M```(!H*$N`:B!H*#N`:BBB(0`,]PH@``N$J@`1A8@`#9"!A8@"SP'0@>``/; +MSW*M```$?:+/C/'*(&$`X'[@>.!^X'CQP,]Q +MH@``@!&!H+@1H28,S_]*#L``#-G/<*``@!P[H`8/[_0"V"H*@`"'Z/H-P`"` +MX!`(`@'^"X``T<#@?N!X_]C/<8``%/T`J0#8X'\!H?'`I@U/_8X*0`0`V<]P +MH```$"F@SW"@```<$!B`#R````#1P.!^X'CQP*X-3_VB#\`"T<#@?N!X\<`^ +M"N_T%MBBP$+P$3+W4`)8X?1``XQ@HA@"]$`!C&B>C/<```!`GI<>H/[_1CN"H'-A:<"$)@``,>L]SH```(!N#`"5!%/X,;_TP(4$.!.@> +MCAVN_@CO_^EP78X`(4`C!"J^!"=P<0'O]`08`"#@>/'`$@G/]`AV%@FO_PS8 +M">@$X,]Q@`#,MDX+X`,!V@()K_\#V`?HSW&``,RU.@O@`S/:SW6@```@^X5* +M#R_W`(;."B_Y!&[*"2_^\'^[A7H/+_FP?>EP$@GO_ZEQ+@G/_Y8(P``9`<_T +M\<#AQ5H*[_\(=80M`1.!X``A@7]$`%C&"MC*("($"0'O]`&Q\<#AQ<]QH`"` +M'+J!&@M/_M(,[_0"V.T`[_2IH*!> +M"N__H(Z!X`'9P'D:#6_XJ7!]`,_T\<`2",_T>@[O_PAU1@[O_ZEP5@_O_ZEP +MO@G@`*EP*@KO_P'>@>!2"N__PB:!$PAQ=@S@`,EP]AH8L,H)+_FI<`#9SW"@ +M```0*:!>#\__L@DO^:EP+0#/].!^X'CQP,]R@0#L!R""!B$!@""B!_3$R8#@ +MH`\B^,H@X@;1P.!^X'C/%#*`>#U`F``4!H" +M,/'`;@^/]"42`C;/`<%J,A&,`.*M +MPZUEE0CP,1&,`,%OF!,#`<*M0ZUDM0#;/PRE$V.ESW&!`$05&PC>`1"!#!V` +M'T$`@P`!X!"ASW!!`(,`"_`1@0P=@!\A`((``>`1H<]P(0""`%T'C_2&"B_] +M!&T`V`P=@!\`(```G;CU\>!X\<#AQ0AR#PA1`"X)3_@(=0+P`-W/?,("*@S"4BD#?RSW9$`,B[$!X`%,EPI@@O_*EQ'>C)<*EQ\@@O_.ER +M`=A>#^__"''*#\_TS@WO]`'8!J;&#>_T`M@'ID:&SW%$`.BY7:'B"F_X'J'^ +M#\_TJ@@O_*EP@>#*(&$`RB$A`,HB00``"2'\RB,!`$T&C_3@>/'`)@\O_@'8 +M`@\O_@#8X@XO_@#8T<#@?L]R@0``&0:"!(`@@,=Q#P!`0DD!(`1(A$` +MAD8@@`%Z&1B`Q06/]/'`6@\/_D8/#_YB#P_^T<#@?N!XSW"!```9:0``!.!X +M\<#/4"ASW*``$0'`8)&(($%SW"@`(`?*Z`)BR&B!^C/ +M<($`5!DR"``$T<#@?N!X\<#AQ38.K_\(=3D('@#/<40`Z+D<@8'@S"4AD`;T +M`-BB#._X'*$.\(#@S"5AD`KT`=@#D!``#QP*+!SW"@```P=(#/<@``)/2+<8'`!2N^```8P`X`&4`. +M`,$!P"NY%;@%><]PH```,!:`.&"BP-'`X'[QP.X+C_1Z<,]P@```#@"`&G%: +M<@CH`-C/<:#^+`)6"F_^EK@'R$P@@*`!X`<:&#`!V.X.8`#`>*8)8```W;(. +M#_X:"._T#-@N"T``SW:@```>FP@0`,]PH```?"*`2B%`("'?#;\/"=\'$8`O +M)@CP#?('V`JXP-D8N:H,+_8`VA>&Y7@7I@38-O`7AN5X%Z;/<(``M!0@@,]P +M@`#(#;(-(``@H+8/K_0&V,X*0``(Z((-+_XJ=:8/K_0&V`_MN@I```WH2G`* +M<2(+(`!J<@?H%X;E>!>F`-@,\(#ED`T"_AB&%X92#P```_`8AA>&!-@(&A@P +M50./],]QH```'A6!H;@5H2$!0`#QP/H*C_3/=:```#`P'8`?`(```+H)0``^ +M"4_XSW"!`.@'P(`$[E8+```*\,]PH`"`'!J`8@TO_D4@P`/"#2_\R7`!V<]P +MH```$"F@!14`EH"X!1T8D/H-0``1`X_TX'CQP)(*C_0:#,("*!(_09Z<]UH```-!"%1B#``T4@P``0I>EV"_#QA0'F +M!">/'P```("J#J_T!MB%[XPF`Y*T]TP@`*#*(((/``"0`=@(`@65`H_TX'CQ +MP.'%`-G/=:```#`UI0"%!""`#__@__^8N`"E`(4$((`/`/___Y&XD[@`IO#9)7I`H\]S +MH@!P<$"#!'HE>D"CSW.B`'1P0(,$>B5Z0*//'!`@P1Z)7I`H\]SH@", +M<$"#1'@E>`"CZ0&/].!X\__:')$(#Z#"_+/<:```!!)@8/J`=I)H:$!C_1.'9B?$````"X*(`#) +M<,(-``#U\>!X\<`,Z&((``"*(0@`SW"@```P(J"2#L_WT<#@?O'`SW"!```( +M`(`/Z`X*P`0>"```SW"``+04`("`X/@+`@"Z"X_\T<#@?N!X\<"F"D``"@U/ +M]S(/#_V6#X`$9@O``M'`X'[@>/'``@M``,H+P`)B#(_\T<#@?N!XSW*@```P +M">C/<($`!`@@@`:")7@#\`:"`-@&HN!^X'C/B&#I8-989EA@X.9882# +M/F3=91,(40!(<`7L5@L``,EPJ7$$\`T(D0!(<$8+``"-`(_T\<`:"(_T"B4` +MD$AV`O200I@0\```D]02E!,]P@0#\!P"`00B0`,]PH```?`*`-0C> +M!PQP,0A>!`/:SW&@```0,!F8CP"@"```'X!/`(````'8`AD8@`<9F(#/<*`` +M@!U&H.!^X'CQP((/3_06"4``V@X``(OHSW"@```P(8"*(`X!W@VO],.YSW:@ +M```@.A8`EO()+_Y%(,`#D@A/_`H/#_S&#(``"L@0Z+N&Q@CO^"S*.X:"W*)Y +M#B$``X#@R`W)!`#8`_`!V`X/@`!Z"L_^B0=/].!X\<"J"$``;@X``(#@/`EA +M`\H@X0'1P.!^\<#Z#D_T"'4`WLEPR@MO]\EQ9@S@`LEPS@D/_!X-+_BI<"(( +M(`"I<,]PH```,,R@`=AF"&``!AH8,#$'3_3@>/'`I@Y/]`AUSW"``,@-`(`` +MW@GHSW"!```(`("`X,HF8A`$[OW)`_#^R2(-(`!Z<%IP>@T@`*EP4@UO_!IP +MY@OO_P#8J@N/_UX-[__)<-(-[__)<,]Q@``,+P"!SW>@```@H;@`H0H?&)"* +M(!```Z<$'X`?````"1N'^A("M@T(A``;AT)X"/`[APXB@`______.&`Z<``@ +MP00`(8`$`"`0(!)URB".#P``@P/*(4X#RB(.!)`,KO3*(TX$`B4-%#X.(`#) +M`"B +M^1J8L]8+X`/[&EBT!09/].!X\<`F"4``K@@/_@#9SW"@```0*:#1P.!^\<"6 +M#4_TSW"``,@-`(#/<8$```B@@<]VH```(`1]!]@+'AB0`@K/_LH.C_X*((`O +MH```,$`0`2#/<($`"`@@H#(-(`"IW/<($`D!H`@!!WPB<- +M$$(*X`/I<)APSW&!`,04!H'X8`:A`-E4&$`@`!Z`'P````C&#"``J7!Y!6_T +MB'#QP`X-3_0`W0WPNF54>G0B`P`!Y96[E[O"DN&2$+[%?^"CZPU$D%4%3_3@ +M>.!^X'C@?N!XX<7AQ@#>R7/)/'`?@Q/]`#>^!R(L\]UH```()45`):?"!X`BW!&".`#@<$:<+X( +M(```P&8)K_]`P,]Q@``4_>")#0@1()45`99C"5X`NX4`V0GH$F]#-8,3"5X`!N@V@P(@0@`'"E(`%H/@?N'%X<8`VPWP>F-4 +M>EU@0)4!XY6ZE[K`@L&U,+["M>T+1(#!QN!_P<4U`<__\#R_W`-DA`V_T`=C@>/'`SW%C"-![!2A^``H@P`YAN$\@ +MP@?/<:```#!5H='`X'[@>,]QH```,`:!`-@&H46!!:%$@02AX'[@>,]QH``` +M,!&!12#``Q&AX'X(<\]PH```,!B`>6$0>`0H@`\```D]02E`#A@SW,``"3TBW*!P04H_@``&<`.`!I`#@#``<$KN!6Y!7G/<*```#`:@!!X +M.&"BP-'`X'[QP*X(```5"%$`SW"@```P#!B`#P`(``#1P.!^\<#/<8``$`U` +M@<]Q@``4#?`A@0`%*3X`"B#`#M'`X'[QP,]PH```,"V`#H#/<(``T!4`B,]Q +MH```'!$(40`4&8`/`"@```CPA@[/_Q09@`\`"```T<#@?L]PH```,#&``-@- +M"9X`X[G*(&$`X'[@>,]PH```,`&`P[B$X`'8X'_`>.!X42*`PP'8X'_"(`$` +MSW"@```P`8#[N`'8X'_"(`$`X'C/<*```#`!@/&X`=C@?\(@`0#@>/'`SW"! +M`'`9SW&!`'P9/@OO_R")SW&@```@`(&NN`"A`H&UN`*AT<#@?N!X\<"`X`#9 +MRB!!`"3RSW"!`(`9SW&!`!P:!@OO_R")SW"!`#P:SW&!`'(:]@KO_R")`=C/ +M<:```"#,&0``"=@>H1^AB-C0&0``SW"!`,@6`(#1P.!^\<`+Z,]P@0!P&<]Q +M@0!\&4(,[_\@B='`X'[@>/'`M@\/](#@?_+/<(``I!HP((T/``!<",]P@0"` +M&<]Q@0`<&A(,[_\@B0HA@!]$``#!0"T($0`A#A("AB"&FK@`H4HCP!//=Z`` +M`"`4'\`2`>7!O4`M!Q$`(<`1#(C/=8$`/!H88!1X$&4*)H`/H`````4@@`$` +M$!``SW&!`'(:J7"V"^__((E,C@`G1P):8E1Z665BD0(1!`$0NP61"!$%`1"X +M!24%`!0?P!(,%X``!23$`!A@%'@090#;!2"``2"`4F4"(0$$`"1`@`4B@@$` +MH@R.`2-#`1A@%'@&Y1!E`"$)$@4@@`%@H`*&!!$"$)JXF[@`HEN'SW"!`,@6 +M0*`;ASA@&Z<9!P_TX'@0V<]PH```,"*@#!B`#P@```#@?O'`SW"!`.@'`(`0 +MZ,]PH`"`'!J`)@GO_48@P`/2#\__2@D@``#8!?`2">_]#-C1P.!^X'BQ`P_V +M%L@`V0'@%AH8,(HB!`#/<*```#!"H`8:6#`$\.!X`>&,(0^*O/?/<*```"`; +M@,]R@0"0&B""(GC@?P"B\<``V0[P.&$4>,=P@`#,#4*089`0N@"017LK(P`` +M`>'/<(``\`T`B-\)!(#/<(``M!;/<8``YA?B".__((G/<(``[!?/<8``D!G2 +M".__((G/<(``I!G/<8``H!J^".__((G/<(``#"W/<8``"B^N".__((G1P.!^ +M\<``V@WP6&(4>,=P@`#,#2"0`>(J(T``8;`PNV*PSW"``/`-`(@0,]Q@`"LM2>!!"&^ +MCP,````&]`0AOH\,````#O+/<:``@#"`X`B!SR`B`<\@(@/0("$#"*'@?N!X +MSW*@`(`P+H*`X,\AH@+0(:$"+J+@?N!X\<"`X`'8P'@/'`]@O/_POHSW&@```P(8'K+,(B*!"/2"X,P@XH`*\N!_`-@)"I``*'#@?OT($8'@ +M?P'8:0`@`#_8X'CQP`X,#_0H=AX/;_P`V0AW`O"F?B3N+RF!`TXA@`<`W0\E +M#1"Z#V`"J7``V07PIGM@H@'A+WG?"5.!1"\^&P`A@G^``)@K-GI)B@MZSW*` +M`%P--7I@@NWSI7OL\1T$#_3QP+(+#_0(=A/P+@D@`*EP#_`O*($#3B"-!Z]] +MR@A@!*EP"B$`@!`F3A//?N_U\^[Q`P_T`-H$\`'B3WH;"E,!1"D^"P`A@W^` +M`)@K5GMIB^D+#H`"\/_:X'](<`#9`-H/(@(``O`!X1<)50'/<(``7`WP($`` +M2WCW\R]X`O#_V.!^X'@(<0#8#_`O*T$`3B."!T]Z$"&!`,]S@`!<#?`C@@`O +M>45X\^G@?N!X\<`&"P_T"'8H=4AQ,PI0`$T)D``1"=``SW````4K8@E/]#'P +M1"X^&\]P@0"D)@`A@7^``)@K`@P@`RS:(_"`Y/'`;@H/]`AV"B5`D,H@@0\```$KX`AA],HA@0,O*$$#3B"/ +M!Q`ES1.O?4(+(`,(VBGP0[`G\"\H00-. +M((\'R7""#N__Z7%*<2Q_`"%!=!9Y%B"`(V*10)`0)`,]Q@0!`'P"!)0A1``#8`*'/<($`_!86"4_^&@I/_@"5H+CAN`"U +MH`_!^\]PH```(#N`SW.``(0L0H,+"80`&X!">`?P.X`.(H`/_____SA@R0$O +M]`.C\@LO_P'>@>!R"R__PB:!$\]Q@`"(#;H,[_\`H78+#_^*"R__ +M"'4(=QX+8`#)<,EPO@P@`.EQX@M@`*EPR7"I<>H+8`#V$@*VG@LO_QIP"'// +M<(``K+4*$(0``-BI<>ERS@^O]@HE``1^"P__SW&F```(`[BE>`"A+0$/].!X +M\<#&""_T%]D/?H0N"!4`(8U_@`"D&@"EG@A@!$`E`!(BA0D)E0*'Z<]P```& +M-!(/#_15)4`6@@A@!`S9?@WO_/'`>@@O]`ARPLE6(@T$ +MI!`!``:%&PD>!<]V@0"X5R"&-@]O^T`F`A0!IAFU"_"`(@,%)@]O^SV5`;4B +ME1FU.&`8M0:%I0`O]`6EX'C)&IB_````(+$'#_;QP!((#_2")`,T`-T*(``G +M0"02,0HA@"^``,RUJ78.\/0A3R.J#^_\J7`5(D$C`+'AL0'FSWX!Y>D-U)Q` +MQ@IPSW(``/_^'@C@`M#9)0`O](`D`S3QP.'%`-WAQ8MQD@SO_0C8$^A"#,_] +M`,&`X,H@0@"<#*+URB%"`\]P@`#(%:"@`,`^""```=D1`"_TH<#QP.'%H<&" +M#6`$*'4(<<]P@`#,M?0@0`"`Y0`0L:C#!`A0PQ0(:$,$2(:[X+!N@OO_078!N@*<,X+K_7)<8/HR77/ +M<(``R!4`@(#@S"4AD#3R0=^`Y1#>Z74V\AX/3_8R\(+!@@OO_0C8+N@"P)H+ +MK_7)<2CH!>\"#T_V&_"2#&`$:G#/=H$`:"0(9A\($`)^#&`$:G`(9A,(T`%R +M#&`$:G`(9H3@L`Y"]L]P@`#(%:"@0=T`W@CP"=T0W@3P@.?*)>(0*G!*<:ER +MR7/N">_V"B1`!74&[_.CP.!X\<`Z#L_S_@]O]PAV"'<`W0T.T1#.#\_^"0A0 +M`*EP`_`!V)OHC"?#GQ?RSW"!`"0(`("3Z'X.;_?I<`AV#/`O*($#3B"-![!] +MJ7"6#N__`=D0)DX3]>Y1!L_SX'CQP-X-S_,(=4$H#P$`W@/P`>8-#L03$?#^ +M#,_\SW"@```$#H#U"!2$`-GI"16!`!8`0`'A^_'#O0/PW@S/_,]PH```!`Z` +M]PA$@P#9!/``%H!``>'["42#\07/\_'`?@WO\PAQ@B0",P]XA"@(!<]V@`"D +M&B]UOV95%P(6&G"`XLH@@@\``"$TV`L"](MP1@T@!!?9E\`^#2`$#-G89<8, +MK_6*(0@%0"@!(39Y`"&`#X``."6N#*_UD-F*(/\/`*>`V0`E@!^``!P<(*AU +M!>_S@"0",^'%X<8`W,]R@0!`"!0B`P"`LXBSF!L$`QUB(!T"$P]^SW&!`"0= +MUGD@D2@=`A-0&T0``=E@'4(0>.(5>H"BJ!L$`\'&X'_!Q1)YSW*``+P4`((D +M>`"B`8(D>.!_`:+@>.!^X'C/<($`^`@`@(#@`=C@?\!X&PC3`X[@RB"!#P`` +MM`D+\A5XQW```&<)!/`5>)8@20P0>.!^`-BMV1"Y`Z$`H0/:SW"M``!`2J`_ +MV`NAX'[@>.!^X'CQP%(,[_-.(,(/K=T0O?6%:!4%$,]V_/\_`,1_=FIE?T`H +M`0,%(<0#!"9.$65^)7Y4'0`1VJ5E>D5Y-J4[I<]RK0```SJ"'7P$(8$/___` +MP$`H`P(%>V5Y.J+/!&C&03/ +M\^!XSW&M```5`!F`#P\`0_+@>.!XX'C@>.!XX'C@>.!XBB#)``"AX'C@>.!X +MX'C@>.!XX'C@>.!^X'C@?N!X\<#AQ8;HSW!$`$C'J6D/\$(A``D=>$EHC"$" +MA,HEC1#*)0X0SW!$`#C(1"U^%#(@0`X0<0/O\P".\<#/<(``)`TH +MD*/ARB""#P``PPUD"0+TT<#@?O'`Z@H``.X-S_42"```Q@H@``'8T<#@?O'` +MSW&B``"`$8&`N!&A`=G/<(``)`TAH,]P1``,M1H*[_5IV<]P@0`4"5(.[_\` +M@$(+S_4*"L_^+@K/]='`X'Z`V<]PH`"`'#R@X'[QP(X-S_6R#\__T<#@?N!X +M\$+[9%@`6`-U#P,]PK0``@V08@`\!``$``=@( +M!!U` +M)`HF@"^M``!H1!X`).8(8`3ZV`+`@.#*(F$@`-T)\K>&2B)`(%,E`!"!X,(B +M@B1,(0"PRB1A($HG`"`+\G`6%Q!*)$`@4R<`(('@PB0")4PB`*#,)"*@RB"! +M#P``DA/*(4$#"`@A],HBP06]?43%!!A`-$0;`"0$'<`C1![`(W8(8`1DV`0= +M0"1$'@`D9@A@!/K8`L`O)\(E`-\*Z/>&2B)`(%,G`!"!X,(B@B0`W1<)$#"\ +MADHD0"!3)0`0@>#")`(E3"(`H,PD(J#*(($/``"3$\HAP0.4#^'SRB)!`_U_ +M!!A`-$0;`"00V00=0"!$'D`@!,&]>#]G`,'B<."A`<$`H0/`V1X8$/D`[_.E +MP.!X\<#&",_S&G`H=0F-*(T(N`5Y"HVMWA"X!7D+C1"^&+@%><]WK0```P#8 +M>G`(Z2&G`!Z`'P```$``ID/P`:<#V#IPSW&M``"`"J%,(`"@$MC*(,($"Z9F +MV`"FV@SO\P/8SW"M``!`6G``&(`/````0,(,[_,&V+X,[_,&V+8,[_,&V``> +MP!0+"!$@!H<"\`>'"'$HK2BY*:THN2JM*+DKK04@@`^`@("`"*THN`FM*+@* +MK2BX"ZTH&D`D/]@+IF4`S_/@>/'`".BR#B`$9-BN#B`$'M@R"\_UT<#@?O'` +M\@U/_X8+C__1P.!^X'CQP.H/C_//=8``.`VBZ`'?>@@@`.EPSW:``%@-`(:` +MX,H@@@\``,8H-`["\^"F`-D-\/0E0A"MV!"X\"""`,]P@0"0+C5X0*`!X>L) +MU(,;\`#9#O#T)4,0K=H0NL]P@0"0+O`@0`!U>@"B`>'I"=2#`-C/<8``6`T2 +M""```*'^"L__U0>/\^!X\<#AQ<]Q@`!8#2"!QPD1`,]U@0``'B"%+^B`X0*!& +M@<]P@0!@'D"@0('/<($`6!Y`H$&!SW"!`%P>0*`H@<]P@0!0'B"@`=@N\('A +MRB""#P``$CO*(8(/```X!E0-PO//<($`9!X`@,]Q@`"`"0*ASW"!`%0>`(`# +MH<]P@0!@'@"`!J'/<($`6!X`@`"ASW"!`%P>`(`!H<]P@0!0'@"`"*$`V`"E +M#0>/\^!X(8C/45Y!+ME>4`L3`&%>2$`(``P>8HB4`#/<:T` +M@(!$H<]QK0"`0`2AX'[@>,]SK0"`@,]RK0"`0(;HBB"/#P2C.WD'\!`;@`\/ +M``#X"[DDHN!^X'CQP.'%"B4`D`'Z5V`RA#!F`#XP``(!$V`2A`-@!H=S8!J(< +M&H`/``#8UB`:@`_B!!X`X'C@>.!XX'C@>.!XX'C@>)(/K_6I<,]P@0`0"0$& +MK_.@H,]PK0``@(F@SW"``"0-`8#+Z$0;@`\B`B(B+!F`#QT`@-!QV`RA!!F` +M#P````\,&8`/C``!@$?8!*&*(`8.!J(<&H`/``"0XB`:@`_B!&0`Q_'@>.!^ +MX'C/<8``@`G@?PBAX'CQP`8-K_-$*GX$"B4`D#IQ&G(O=@7TSW!$`$C'!/#/ +M<$0`.,@>9L8*[_>I<%IP!8XDC@BX!7D&C@HD@"^M```8$+@%>0>.SW>M```5 +M&+@%>36G`XXBC@BX!7D^IPX.C_X`V8WMX+C*(8(/,Q\'`.&XQ2&"#P``G_D+ +M\."XRB&"#^D?!P#AN,4A@@\``$__`-JMV!"X>G`MH,]PH@"`;7"`((ZLNZV[ +MKKN,NXV[<*#/.!XX'C@>.!XX'B*(,D``*<4AX&X%*<4AZ&X +M%*>6#2``"G!#%`,F02L"!4]ZT[LQ#5$0SW&``"0-(8$2Z0#9@.#,(B*`RB%B +M``#8%^DO#L1P#0"@NR<+A`\"`""_#O``V0;H#0[%<`T`@&TH<`?P_0N$CP,` +M4#0!V('@RB""#P``JBC*(0($/`KB\\HB0@-,(@"@S`GB]\H@0@//<($`!"/T +M($$$3"$`H#MX$;DE>$`I`2$%>4`I`"4%>4\A``"0N,H@0@#9&Q@@V!M8(.(, +M[__)<*EPC@KO_\EQSW"``+`6P*"5`Z_SR7#@>`?:"KK"N0JYBNC/<*T`@)]0 +MH,]PK0"`7S"@"O#/<*T``*I`H,]PK0``:B"@X'[@>,]Q@0`0"4"!%"`!`(#B +MSW.``(`)0(/*(0(`!"*"#Q_^/_P6:16Y)7A%>.!_`*/@>,]SK0``'\]RK0"` +M*87@S"%B@2/T0!N`#[*>_\I$&X`/;&",>4@;@`]".51*3!N`#R8B,BP`&H`/ +MLI[_R@0:@`]L8(QY"!J`#T(Y5$H,&H`/)B(R+"'P0!N`#\JT_^-$&X`/?W&@ +MCD@;@`]/1F193!N`#S(L/S@`&H`/RK3_XP0:@`]_<:"."!J`#T]&9%D,&H`/ +M,BP_..!^\!X\<`F":_S&7*( +M<*ATR'7/Q3P4!J`#_\_`(!D&H`/_S\`@$`H0184N"5X#[VE>!2G&;L4 +MO(5[#[[%>WFG)0&/\Y;H!]O"NHOISW"M`("?=Z#/<*T`@%]7H.!^SW"M``"J +M9Z#/<*T``&I'H.!^?-L"NHKISW"M``"A<*#/<*T``&%0H.!^SW"M`("K8*#/ +M<*T`@&M`H.!^X'C/<:T``(0)Z`3:SW"M``!$2:`#V`+P!]@)H>!^SW*``(`) +M(H*`X,\A8@?0(6$'X'\BHN!XSW&!`!@)`*$1Z,]QK0``1"L(4`!'")$`"!F` +M#P`8``#/<*T``$`!V1CPSW"M``"$"!B`#P`(```1\`@9@`\`"```SW"M``"$ +M"!B`#P`0```!V<]PK0``@#V@SW"M``!$!!B`#P"```#/<*T``(0$&(`/`(`` +M`.!^SW.``(`))X.;Z4*#)H.&(L,/0J,$(8$/S___\R:C$P@>!D4BP@!"HXJY +MB[DFHQ,(7@9%(@(,0J.4N96Y)J/@?L]Q``$``8#@RB""#ZT``$/*(($/K0`` +M@SF@X'[#NICH#]L(NPBZB^G/<*T``*!PH,]PK0``8%"@X'[/<*T`@*I@H,]P +MK0"`:D"@X'X/VXOISW"M`("AI`(P("`_!`(P(#8(*&Z$8CPP-E>2"B!_"&(P,,%&EE>`"B +MX'[QP,X.3_,*)P"0&G'*(($/``"G&3@-@?//<($`T%"CB,*]`-X/\/`G@1-! +M*8`#PKBE>!!URB""#P``J!D0#8+S`>;G#@24\09/\^!XBB`9``#9E[E5`:_U +M'MK@>`':SW&!``P)0*'%N,]Q@0`4">!_`*'@>/'`5@Y/\PAWSW6M```6`X4* +M(8`OK0``&(ZX`Z4!V,]VK0``%12F`-@:AP#8!/`!X!!X.PB3`C.&&WH$(8$/__WA +M_S.F,X:9ND5Y,Z8`V>$)$X+/$%;_,`&0`$#WI$*CX+1"&#`P`A@G^!`&P) +M?7MHJAL)'@`HY*JH#\&FJ:JK/<8$`'`IFJ>!_!:G@ +M>$$!K_4"V.!XSW&!`!P*!8E$*#X+SW"!`'4),B!`#@:I507@`@'8X'C/<8$` +M'`K@?P2IX'C@?N!XH<'QP`(-;_,(/$V&_"K_E>$3`(0L>`<]P +MH```(!"`F[H"N&ZX2"```,FX17A#P`;P"0L>`IVZ0\)!Q(MVR7!H`L]PH```1Q08@`\```P,W\D%V@'@ +ML[BUN+BXWQH8L!6Z!*+/=:```"#(%0`0N0@1`!21SW-$`&BYW!,!`,.X!+G/ +M@;9 +M!?`$V0/P`ME?R\]R@`!("@ABSW:``$0'SW*!`!P*1HI#N%UZP+J`AHH@(2P$ +M)`P417D'N(8@X0\%>25\@*:^#*`#!MAZ%0&6`(8$(0$$)7AZ'1B0`(?/<8`` +M5``.HA#:SW"@```D +M0:!#@1G=")$PNA"X!7KUR1!R`=C`>`*X@;C/@```0&0@>!'`0`2"4V!H,X`$* +M``QP'P@?`\]PH`"`13`8@`\`(````-G/<(``.!(@ +MH&HA@`'/<(``/!(@H&#PM@R``USPBB8($&$)7@+/=8``@+4`A>201+^:"*`` +M4R?`$`"%>@\@`%,GP1#/<8``I`D(=0L(D085@8"X%:$;@<]RH```*`'@&Z&" +M$@&&P[EM"0$`!!J8@X(2`8;#N6$)```#&IB#+/!-"=X`"-C/=J```"@$'AB0 +MK@H``0AU00@0!<]R@`"D"0."*)(PN!"Y!7GUR1!Q`=C`>`*X@;@`'@"0`X(H +MDC"X$+DE>/0:&+`9W0;P%]BR#6_SC+B9Y2@#P?_J#\_VJ7"%!R_SH<#@>/'` +M"@\/\P0BON\!`0$!"'>Z\L]Q!`0$!`LB0.`>\@0A@8S_V`OR+RE!`$XA@`L5Z#_!"(0$(`-H/(D(`8;HX>V5ZBB#_#P7PBB#_#PAR`=G//0:&+#)!2_S`-C@>/'`8@T/\PAV52!0!``0`""CP4'`!!0`,4$H%`,&%``Q +M!"*^[P$!`0%"*!$!?/(#ABB6,+@0N04A$@"3S>VXT2!B@`7RX@FO^H+`SW$$ +M!`0$"R)`X!?R!"&!C/_8"_(O*4$`3B&`!R.XSW&``$P6\"$``(0H"`7/<(`` +M'!PR($`.!?`%AG8)8`(FAL]R@`"D";X:`@`!V0\(W@$R@I6Y,J(`V02XSW.! +M`%!01I,%(``%4'!$D\!YSW```/__$'(`W\HG0A"3$@&W#PG>`A!R`-W*)T$3 +M'O"2S>.XS"\.RX`-W* +M):(6J[BLN!#9DQH$DH#&` +M-7@V@`'A-J"`YX#RSW>!`%!0!)(BL,]Q@`!$"IZ)SW:!``P(B*@)&`(%0"D!(26P#!C`!"27 +M$!@`!(QF*K":J.`;@`!`*0(#G;H%(8,@SW*@```P-QK8@`*Y,"&!#Z``M"[/ +M=*``@"U_A"NP!O"3$@&&?X0+"1\!]PO>@03PY[O*(R$`0,,!%(PP4R.!`<:\ +MF*@YJ,]V@0#$$K\6`!:88+\>&!#`%@`6&6'=R<`>6!`U"!X"SW"@```@SW&@ +M`(`6XSW&!`,02@?)`V)(: +M'+!5$0`&SW*!`$04`>!5&1@`<1$`!A5Z%H+/<8$`0`@!X!:B)<@4><+)@*E6 +M(`($,H*O"5X$T(C/V"+$PM?`<]S@0``<&.+"0O>``'%OMG +M`[QU>Y5\FV,[8\]T@0"0)VMD#PO>`48FSA-AN25^C@@O_\:BZ@B@`LEPSW&` +M`*0)$($-"%X"!-C!&0(`D@UO^H'``-P'\*P1```!W`'@K!D``)CL`X4HE3"X +M$+D%>?7)$'$!V,!X`KB!N,]QH```)P"A`X4HE3"X$+DE>/0:&+``V`D!+_.B +MP.!_"-CAQ<]PI@``!*2`SW*``*0)02U`$<@2@0#!N#!PRB1&$,HD!1!`+$$2 +M3R$#!)`:P``1#1\1#0@``Y"YDKF0&D``X'_!Q?'`X<4(=<]S@0`,*39[(8,! +MD!!Q"-@)]Q8((`"I<(7H((-@>:EPI0`/\^!X(8#/`&H0#9'_`]@L]RH```(&3A,*(!V0<:6(`0V2"B(8"$Z6QQ^PD> +M@"&`P;G+"="`(8#@N0#9RB'A!0&`X;C*(:$$X'\H<.!X\<#AQ<]U@`"D"16% +M!""^CP!P``!2\B\I`0#/<($`-`KT($``/(6"N`(+H`%:A8T($``5A0L(G@=. +M"H__!O``V<]P@`!@+R"HY@Y``\]P@`"D)#N`J!4`$?(*;_TT>!6%60B>!\]P +MH```"`*``-G/<*``@$4MH,]PH```'QR`,0@?`,]P@``T$@"`)0@>``QP'0@? +M`\]PH`"`13`8@`\`(````-G/<(``.!(@H&HA@`'/<(``/!(@H(4'S_+QP`H/ +MS_(P@,]V@`"D"00AOH\!`0$!"'4U\@0A@8\$!`0$%/(O*4$`3B&`!R.XSW&` +M`$P6\"$``(0H"`7/<(``'!PR($`.!O`%A4(+(`(FA;X>`A`1"-X!$H:5N!*F +M#X:7N`^F%88$(+Z/$'````OTG+CF"F_Z%:9`)0$2.J8`V`&QLA8`$:@6`1$X +M8&*X$+B`N,]QH```)P"A!84LE3"X$+DE>/0:&+#1!N_R`-C@>/'`5@[/\@AU +MSW"@```@$8`O)`@`$(4$(+Z/`0$!`5;R)87/=H``I`G/=X``)`H9"1X`E@W/ +M_R6%H+DEI02'D;C&&ABP%)<5"`,!#)4PN1"X!7GUR6T)`0`PA00A@8\$!`0$ +M%/(O*4$`3B&`!R.XSW&``$P6\"$``(0H"`7/<(``'!PR($`.!O`%A5(*(`(F +MA;X>`A`5A@0@OH\0<```%O0$ARD(GP0""D_Z%8:>N!6F0"4`$AJF'(;IN%@) +M@?T&\""'"X$!X`NASW&``"0*&9$TD3A@8K@0N("XSW&@```G`*$%A2R5,+@0 +MN25X]!H8L-$%[_(`V.!X\"SN+6XN+C?&ABP%;D$H<]UH```(,@5`!"M"!$`SW"``*0)%)#/`"$(%0(S)@!P@0#,'T`G +M@G(4>@!Z!MD$\`39`O`"V5_+SW*``$@*"&+/=X``1`="*,0`SW"!`!P*1HA@ +MAUUZ4R(,`(H@(2P$(P,$A7E`+,0!B'"&(.$/!7DE>V"G1@X@`P;8>A4!E@"' +M!"$!!"5X>AT8D`"&+R`#``"FSW$$!`0$"R)`X"'R!"&!C/_8#/(O*4$`3B&` +M!R.XSW&``$P6\"$``(0H"`7/<8``'!S/=8``I`DR(4(.SW&``$0*%@CO_%ZI +M"O#/=8``I`D#A:X((`(DA;X=`A"^%8`0$PC?`2X/+_L`V>X/K_R<'0`0!"*^ +M[P$!`0$(]`&%#0@?`(#8OAT"$+X5@!!`*`$&/0C>`0^%3R#"!4^EL[A2A;6X +ME;I2I<]R@0!,&T""E[@'"EX`#Z5-<.ZXSR$B`L\A8@+/(:("12$!!B/P`[@5 +M>,]R@0"$#P!B@KD-")\'#X6UN`^E&84E"%$`887/<(``)"5#@."[P2HB`<$J +MX0#`NA>Z#X5%>`3P#X67N`^ESW"@`(`D,J`$(K[O`0$!`<]U@`"D"0^%'/(T +ME34)7P$@E88A_`",(0.($O*0N(X/+_H/I<]P@```#@"`3X4(Z`#8SW&@_C0& +MQ@FO_):X#X45"-\%37`-")\##X7UN/0+`OW/<*````PT@,]P@0`\"B"@!-G/ +M<*```"0AH-W)%PC>!AV%SW&@`(`@,($B>)3@W`C-``^%!""^CRP````#]!.% +M'^@,<`L(GP0L@`V,]QH/YD!D()K_R6 +MN!Z-#PC?`:X-+_L`V6X.C_SQ`N_R`-CQP`#8X<`0V<]PH```)"&@3@JO^XMP +MA>BR#*```,"AP-'`X'[QP%X*S_((=L]P@``D):&`SWC/<8``V!J$*`@%)@TO +M^S`A3PX:<,EPD@_@`.EQR7#I<68/;_L*0+/\O'`X<4(=87@RB"&#P``60#/ +M("8#8`@F\\HA1@.&#^``J7#B"*_[J7!-`L_R\<#/<(``2"]*":_T&-G/<(`` +ME!`^":_T&-G1P.!^X'CQP.'%"'4`V>'!DLU7"%X#SW"@```(`H#/<*``@$4M +MH,]PH```'QR`+P@?`,]P@``T$@"`(P@>``QP'P@?`\]PH`"`13`8@`\`(``` +M`-G/<(``.!(@H&HA@`'/<(``/!(@H,]PH```#`6`@>#*(.(#SR`B`[0/XO+* +M(4(#SW*@``!%.(($(;Z/```((`#8!?0\@@D)7@8!V!$(40#/<8$`Q!,`@0'@ +M`*$1#=`4V@BO^XMP"B$`@`/TJ7'>#J``*'!+::+B#`$-`#(F@G"!`-0?0"<` +M`(H0#9`=AZ\,]R@``D"B""!X$!X`>A`8)`>`#8 +M"'%N\&(.P`#/<:```"0*@0/H`M@!H<]P@``D"B"`$($!X'H.H``0H>OQSW"` +M`"0*((`,@0'@#*$Y\,]Q@``D"D"!`H(!X`*B`H%`>$;PSW&!`,03`X$!X`.A +MSW&``"0*]/'/<(``)`H@@`.!`>`#H2;PE@_``;GQSW"``"0*((`%@0'@!:$) +M\,]P@``D"B"`!($!X`2AE@@``"#PSW"``"0*((`1@0'@$:$!V2AP&/#/<8$` +MQ!,,@0'@#*$`V`'9#O#/<8$`1!,.@0'@#J&9\4'86@[O\HRX`=DH<`;IU@V` +M``(-P``%\`?H0@_/],]PH```"`*`SW"``*0)#X`A"-X$`-G/<($`I#@CH,]P +M@0#H'2&@SW"``%`2(K`>"8``"0#O\J'`X'CQP,]P@```#@"`">@`V,]QH/Z, +M!N8-;_R6N,]P@`"D"3V`9.'J#2`#"-CF"B_]`]@#\(X.C_O/<*```"0*@`7H +M;'#S"!Z`T<#@?N!XSW&!`"0*"&$3"!X`!"*^[P$!`0'A(,('`=C/<(``)"4# +M@.&XX2#"!P+8`-C@?N!X\E_:8*((`OH``` +M(,`0`B!L$``@7Z9">!ZF][7/<(``B`[XH,]P@0`X4>"@^Z;BJ>2EYZG&&MBS +M!-K/<(``!`Y`H.BE#HGCI@VIW,GII0HA@"^@``!(Z+8A"!X`%!F`KP``#`S? +MR07:`>"SN+6XN+C?&ABP%;H$H@6)H+@%J>X,;_O@J8H@_P]<&1B@6!D8H(H@ +MF`U8&@`@@-@,&``@"!@`(,]QH```*``9P(.*(!@(`!@`($@0`"`;"%X`,Q$` +MA@0@OH\`P```!?+TR0/H]1H8L/0:V+-(&,`C;1F8KP`"`0`!V<]P@``X$B"@ +M:B&``<]P@``\$B"@+'#/.!X +MX'C@>`#8`*$1\$`B``,`I<]P``#TD0&ESW````"2`J40V!2U'9$>M<]RH``` +M#!."BB&:``.E#8(1WT(@``A((`,`SW"!`/P'`(`!VH+@P'K/<```@@Z`XLH@ +M00!P<,HG+A"`Y]0"(@#(&MBSSW"``%P6`("`X,HG(AD9],]P@``D)0*`@.!: +MV,H@H0<,<1$)7@;/=H``I`D_AA<(10#/<8$`1!4=@0'@':$#WXD"``"`%@$0 +MSW6!`$P*`(%`)1`6`>``H<]P@0#H(2"``8!`P4'`(-BN#^`!`*7E$@&VY\E* +M(0`@!7DO*4$`3B&`!XMQ5@[@`8'"3@W@`2IPSW2@```@P!0#$`#"`<<"(L*` +M`R=/%$#"0<<[A&)X8GDAI4*EXZ4Z#J_]!*7B#:_]"[6!X`'8P'@*M<]PI0`` +M#.*`4R?"$+\>@A!3)T`0@^#*(&$%SR`A`P`*X?+*(<$#02]`$\*X+X;&'@(0 +M!"&"#P````CFI1\)W@($N$\@00`*E25X"K4'V`CP%2`,(``<0!0"\`38`>#U +M"!2""B&`H,]P$``0$,HA8B"R"2`#^MD!WPQP]KBL\L]Q@`",%`"!42&`PP'@ +M#W@`H0':SW"@```0)(#/<(``C!0`@,(B@0`P<*7T"B"`+Z```"#`$``@C""# +MCCH!#0`R``/? +MW@B/^X'G0//(&MBS@N>>],]Q@0#P'0&!".@`@0T(7@""N&X((`(`H<]PH``` +M$$R``-LLNL]PH`"`(02`PKI`P"#`X;J":&2X2"```,HAP0`1\@(4@3`/"00` +M,'3*(68`2?@,<@#8 +MSW&@_I0%,@\O_):X!""^SX`!```&V`;T#'#\N"#8RB`A`NL(D(#/<:```!`O +M@07?@.'*)P$0R!K8L\]U@`"D"8;GRB6"'Z````RL!@(`SW:``"0*%)8'WR^% +M8KCKN1!XJ_+/@L]PH```(,]QH`"`'`09@`_% +M[H92&X`!H1@1`"`!H166`:$0E@&A$98!H0F&`:&]\<]QI@``!".!-+G!N3>V +M#'(WEA<*7P;/`"N!3@':66">_\%-@4A0GP8@JO\@;8SW"F```$`(`4 +MI00@@(\#0```&_09"%Y&SW&@`(`@4('/<8``I`D_@0D*10`!V0/P`-F+Z0QQ +M$PD?!VQQSW6``*0)NPD>@!T(@0\`0````-C/=8``I`G"'0(0`-Z7OAOP&PB! +M#P$````!V,]U@`"D"<(=`A``WIB^#?`G"($/`@````+8SW6``*0)PAT"$`#> +MD[Y4A<]Q@0!,"DJA#?#/<*``@"`P@!*``]\F\`(;`@(`WI>^`-@5Z`K?SW`$ +M``$1Q@O@`@#9!""`0X#@RB?B$6QPX+C*)R(2[P^0D@SP+H43";0#!]_/<*`` +M`!`4@`D(0``(WX?G7@,"``HE@"^``&0*`A6`(,]U@`"D">&X\?(*(H`OI@`` +M"!$2%*8`W$$LPB;"N@'B02S`(%,@!``!*@(!8;I!+``A$A(.IE,@0(%3)@,0 +MW7E3(1$`02[!%,"Y1"8/$B*_!2=0$%,D02#,(.*/%?)!+(\FP+]1)("FRB`" +M`\HC`B,4]`'8SW2``/`L&!03$`#4`L0@03N$5Y!7D&%8`@#K@E>%,@`2`;N25X!7P! +MV``=`B":O*P5`!&0I<]Q@0#P*""!`^`%*'X`"B#`#N%H!@@O_1"%,(5TN"*X +M`G\A"5X#SW"!`/0H`(`%*/X#`"&`?P``_P\PN`(@3P07"-$@!"&^CP8````! +MV,(@`0`!X`)_"B"`+Z8```@0$`"FRK@?#P`0SW"````.`(`)Z`#8EKC/<:#^ +MP`5*"B_\Z7*8'<`3!N_F"8_T#J4(\`#9$(4NI92X$*4H`C"-,`\(4$)X\?````&*H-;_TKOQ!W +MRB`.!,HG[A'0]X8.```(=Y3@RB?B$PIP"/!V#@``"'>4X,HGXAA*<""`SW"! +M`$P*+!@`!2V@P!6!$,R@![F*N:SPX+@*(8`OH```$*WR"B*`+Z8```@"$A"F +M`Q(.IE,@@"&`V@0F@1`&N25X!"("!`2Z17A$)@$<#;DE>,EQAB'S#PZY!7D& +M%8`@X[X.N`5Y1":`$!2X!7G)<(8@_@\5N"5XB+A2($`%$*5!+L$0P+D`'4(@ +MRB*"#P``___*(H$/```0'RZ%02@#(E,C0X2L'400;J4#])2X$*5A#IX40!6, +M$!$,$1@$(+Z/````&";R#P@>`D$HP0!3(7Z`!_0)WPJ_!"#!`S4)P`-!*$$$ +MP;DI"=4`%0F1`"$('@)!*,$`P;D!X14)D0`)"!X"S.0&]@D+E`,)"L4`"-\C +M\$$HP0#!N0'A'PG5``0@@`\````84@QO_4$HSP(+",0#$(45")X"+@T```AW +ME.#*)^(3"?!0$0$@#H40<0??RB=B$@`2`2#/<($`3`HL&``$+:``%8$@S*`' +MN8BY2I!%>2JP+H4OH#"%+J#/=:````S(&MBS#P_1$3()```(=\@:&+"*[\]P +M@`!D"@V(A.@`W\@:V+.,[\]P@`"D"3F``-\)"=$`^:`5W\@:V+.)[\]P@0#P +M'0&`!>@5W\@:V+,&[ZH/;__I`,]PH``` +M)0"`CQHFONK&Z3Z7ONM$B880$\BS8':41\!"%$0B?!BZ%Z@ZO^0#:':4]A<]P@0", +M"L(+(``AL`^%'PA?!+()P`#"%8`0">C/<(``%/T!@`:`Z[C,#0(`$(4)")\& +M`-AR\*$('@?/<*8```2S@!38SW&@```@$*$!V`<9&(`0V`"A!?#/<*8```2S +M@`T-WQ=L3"FSW>!`$P*J@UO]"ZG#Z=`V,]QH```#`2A#H<`H438!*$/ +MAP"AW@K/_@3P&@T``.4&#_(#V<]PH```#":@X'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'@FH.!^X'BAP?'`0@X/\D3`%=U3 +M"-X`"-C/=Z```"0$IVH)``#/=J```"@]"!`%,H<3AS"Y$+@%>?7)$'$!V,!X +M`KB!N``>`)`2AS.',+@0N25X]!H8L`*'#PB?`,H-[_J$P(+HJ7`C"%$%SW"@ +M```D`H`$P>*XRB!A`DP,8?+/("$##@@@``3`"-PO!@_R\<"^#2_R!-BCP<]U +MH```*,]SH```)!@3!P"R%0^6!*,;V`>C)@_O_Q7>42<`@A&#,+Q`*`4$$H,`V;.#02@&!,]S@`"D"0Z#$+U! +MP!"#!24%`T+`?8//<,7NB5U>#F`"!29&`\EP?04O\J/`P=@<&@*PSW&``*0) +M%H%.(`(!#H%">!>A#."P&00`L!$``<]RH`"`#`/@!""`#P``_/\0HL?)`!\` +M0#>!`!]`0.!^X'CQP.'%SW"!`!P*!HC/%,@`0``@J"X)7@`HE(. +M8`('V,]QH```('H1`(:DN'H9&(#/<(``I`D=@"7HP!$$``(@``%JN$@@C0`[ +M#=00SW"@```D"H"7Z"QP*P@?!MW)&PC>`\]S@`"D"<]PQ>Z$50'9J7*2#6`" +M?8,`V,X*H`*I<;T$+_(`V.'%Y1(!MN?)SW.!`$@*)7C/<8$`3`I`&0(`_]A! +MB0.I$FI,X`"CP-L<&L*P`^`$((`/``#\_\]SH```$#`;&(#'$@RV`!\`0P#< +M!_#P(0T#`!]`0P'D^0Q4E`#9"?#/<($`$%'P($P``!\`0P'A\PF$@`#8`AL8 +M@(_-SW&@```E`>`$((`/``#_OX^XCQH!X\<">"R_R`-K/=8`` +MI`DOA0H@@"^``&0*SW:@```,HL&;"=\##1"!(,]W@0!,"A#ISW"!`$@*1*8` +M@)NXG+@`ID$?0A!(V`2F$(<`IA"%%PB>!AS8!*8JEPN7I[D0N"5X`*;E$@&V +MY\D%>2\H00!.((('G!4`$!!RT2$"@!SRBW&6#6`!@<+/<*```"`;@"&'`-HB +M>`#!`<,"(0&``R.#`"*G8Z<0V`2F`H<`IA38!*8#AP"F08\"NE#B1*;//'P``_/]/)\`6G+B`Y,H@P0.=N)^X`*8` +ME88@_PP_"!$"".)$IA>%5)4\>88B_0]'NI^X'KH=N45X)7@[DP00@B!983QY +M&+DE>`,0@2!6A5EA/7D4N25X`*;=R24(G@+/<*```"#/<:``@!P$&8`/Q>Z# +M5!N``:&/S0&A&(4!H8_-`>`$((`/``#_OX^XCQH`NH-3_4>""``&(6%`B_RHL#@?N!XX'[@>.!^X'C@?N!XX'[@>.!^X'C@ +M?N!X\<`""@_R?@E@`0AUSW&``*0)#X'/=J```"2PN`^A"H8#Z`+8`:8`V<]P +MH```#"R@`@\```J&!.@"V`&F@.7D#0(`]@F@`0'8Z@U/_"4"#_+QP,]P@``` +M#@"`#>@`V):XSW&@_L``SW)$`&2T>@@@`2K;@@P/^M'`X'[@>`'9SW"@```0 +M*:``V<]P@0#$%"*@E0"O]178X'CQP%X)#_*BP38)[_J+<`HF`)`A],]P@`"X +M$P&`SW&``*0);H&"(`(`<'`EW,]RH```)!Z"RB2&$Q!S%MX`P,HF`1,-"!X$ +M`MBZ&00`'X*V&00`@.;&]`#`Z;B*(0@`Q/(*(8`O@`"`M0`1`"#/=Z```"2D +MD`H@@"^``*0))*<\$``@1+W#O94(7@2^""__`!$`(`HF`)`+],]P@0`,*;9X +M((!@>0`1`"`(=@J'`^@"V`&G$!^`'P``_W\;V`>G-@K/_\]P@`"(#AB`@.#@ +M"<(`$0Z1%L]P@0#T'$X,H`$`WMW)Z;AW\L]RH`"`'`0:@`_%[H1B>!`!(,]S +MH```("&B&X,B>,@3`0`B>`&B`!$`(`*``:+!HE_P%@EO_ZEP"'8`$0`@]@_O +M_JEQ?@@O_PAUB.7,)>*5!/2I=BCP_0V0E!?N)@L```HF`)`9]``1`2!$D0`8 +MA"!#@22!!!B`(`@80"``V6(,[_\H&$0@!_"&"<__`-ED&$`@*'81#9$6SW"! +M`/0X$V`2G&]@'I\]P@`"(#AB`@.#@",(`@.9_]`'9SW"! +M`.0'(*!]`@``X+@6`@$`SW&``*0)#H&V$0(!0GADN+@9!``/@?&X`-@_],]Q +M`@("`@0B0&``W!'P+RH!`$XB@P=!*\T`SW*``$P6\")"`Q`@P``/)(P0\N@9 +M[`0A@8S_V`OR+RE!`$XA@`"0``"B8`D,;TSW6``*0)#X4["!X$/(74V.H)H`"I +M<@AW;@VO]0#8`)6&(/\,$0@1`L]Q@0#$$P*!`>`"H8#GR`U"`A'PT@L/_Z/P +MOA6`$,]Q@0!`"@"I%)7#N`&I#I5$N`&Q@!4!$`:!`>`&H;X5@1`?"=\!@86< +M%0`04B0,$$"52B0``'25`@[O^U,D!1#/<8$`@$L)@4^%@.#1(F*%!/(.D0GH +M`-C/<:``@!P9H3#8'*%*"L__+X4I"1X&$-B2&ARPSW"!`/0B,2X&+@%?D$N`!=!+H(5AB#_#,&Z!7K/<($`C`I@B%,C +M_H#,(B*`'/(#V1:Y!"9`$#$(0`#/<(``)"4!@$MXRB"!#P``&32<"B'RRB&! +M`PCPX+G*)>$5!/+AN<]P@`"D"=B@?_'QP-X+ +M[_$%V`#>SW>@```@NX<+N&8/+_S)<88/#_7/<(``I`D/@*4(W@($'YB?`!`` +M`%(*8`(%V!#P#'`7"-X%+'`3")X#S@@@``#>-@I@`@78Z@_O\0;830X5$0QP +M]+@!YL!^;'`U"!\`#'`+"%X%+'`U")X##'``V9RYOP@>A\]PH```'"2@SW"` +M`"0*((`0@0'@$*$(\,]Q@0#$%`*!`>`"H6X(````V<]PI```12*@&O`,;`?FQP&0@?`'H/[_$&V!T.%1$,<.D(7H4*\#X(``#/<8$`Q!0"@0'@`J'= +MR2D(G@//<*```"![@`#9HGO/<(``I`D\$`0`SW#%[H-<'@P@`JER/0//\?'` +MX<4`V,]UH```$`FE'@_O\0/8<@@```'8":4M`\_QX0?/_T[;SW*!`$Q1%7K@ +MN6"BRB#!``7RBB"%`P"B"PG>`HFX`*+@?@#;#O`O*0$`3B&"!\]Q@0!,4?`A +M@0`0((``)7OTZ,]PH```$'"@X'[@?N!X`-K/<8$`3%$5>>!_0*'@>`/:SW"@ +M```03J``V\]Q@`",%$Z@X']@H<]RH```$"$:&(#/<8``A+5@@2*#(AI8@#A@ +MH1H8@`.#HAH8@.!^X'CQP((-3_L`V<]PH`"`#2"@'!B`#P````@^#<_Y%@@` +M`(HAQ`'/<*``@'XHH-'`X'[QP.'%SW"@``!\`(#_V3"X4R#-``?8"K@$N>8* +M;_-0VL]QH`"`#:.A`]@"H2D"S_'QP%8/P`'/<`\`0$+Z"\_YT<#@?O'`F@G/ +M\0#>#WT>\,]P```2,@H(#_(8\"\H00-.((('3WH0)8T0$VH5>,=P@0"$#R"` +M:("O?0\FSA#5"5^"C"/#C^;SZNW%`>_QSW@`V1#P+RL!`$XC@@=/>A`@@``# +MNE5ZSW.!`(@/0F-%>?+HX'\H<.!X\<`:">_Q@-D(=\=P@0#P#CIP(*B0Y\H@ +MA@\``'$`SR!F`WP/YO'*(<8#`-X&\,*X`^@`&8(C`>:0YN@`!@"V;]5]QW6! +M`.A2`(7/<8$`A!+U>6"1`-H/(H(#:WK=N`"E`_*>N`"E(9%+>03RG[@`I3-O +M-7G/`#9@@LO^AIQA"@(!0`A@'^``*0: +M*H`/#]$3`H"$X,HA`00`A<]R``0``2\(7P(5Z4MXT2'BA=$AX8`)]!L)'@8$ +M(+Z/````&`?R_KG/(.('SR"A!P"E!""^CP`$``&1\^BXB_7#N(KQ70#/\?'` +M`@CO\8#8M!P(L,]V@0"0"@"&(KC#N`L(E0-.(`T$`_!.(`T(@<`K;5H/;_," +MN2"&SW/_`/\`02E`!T`H`@)D>ABX17B+GX:&``3:4$H#`9`*RBX&[DE>`0@@`\`_P#_97A_&A@`BW;)<#(-+_5,VO +M\;/`\<"Z"F_[`M@6"```T<#@?L]QH@!`4/`A``#@?@'9SW"B``!0.Z`YH`#9 +MSW"!`)`*X'\@H/'`SW.@```@.X/'<0``,'4;@P#:,'#/<*(``%`8@,HB;P#! +MN(+@`=S`?`D(D`!RZH#DRB"!#P``#`-X#<'QT<#@?N!X\<#J#H_Q"'<*(8`O +MH@``4&@1#2`*(H`OH```(&P2`"`:<0`@DP\``#!U02F.`#;P/@WO\8H@#`(P +M\`07`105(4PC02D`!D`I`@)%>`0@@`__`/\`02D"`ABY17D$(8$/`/\`_R5X +M`*0!Y6&^`^[/#1244R7-D!+T;!(`(')P`-A@$0$@RB!O`%(A`0#@NN;J`-@"\`'8X'[@>/'`X<4$(8*/\/\` +M`,]UH```,`7R-+IM'9B0%+C3N25XE!T8D`/PT@R/^I05`);["-Z'"0:/\>!X +M4FC',]RH`"` +M+0J"SW&@```P3R!#`HN[\+AJH@'8PB`!``FX12!``;09`(`*@L]R@0"`>"$( +M'@#/<($`@'DC&A@P62(`""0:F#__?___(AH8,`_P0B(`"",:&##/<($`('`#9$O`O*P$`3B."!T]Z$""```*Z +M,"*"#Z``-"_"N@\A@0`O>?#HX'\H<.!X\<#^"Z_Q`-KCB,]SH```,"&(#R+" +M`P80D0`2;\=PH``T+P`8@`\8`0``DA,`AE)]I'B2&QB`.A,`AL]V@`!8$J1X +M.AL8@`"&I'@`I@&&(N@5)E`0$!``($MXRB"!#P``GR$H"N'QRB+!`Q`0`2`` +M)X`?@`"H$J1Y$!A`(/_9(*@#AJ1X`Z85)DX4'(:D>!RFT0./\?'`;@N/\<]P +M@```#@"`">@`V,]QH/X<`\X);_N6N`#>"B"`+Z```##/=:```"[5I0_?"+\# +M\'8*C_H3A>1XC"`0@/OS!!B8HP/P8@J/^A.%ZWC]]8$#C_'/=*``@"Q8I'FD +M#+B=N)^X!7DWI.!^X'CQP`8+C_$(=HH/[_\H=!X\<#A +MQ<]QH@``<`(1`H8`V$`1`8;\NM$A(8`D\L]QH@#D;`"!`=V`N`"ASW&B`%AQ +M`(&`N`"A5@D@`F38SW&B``"``X&@N`.ASW&B`,1M`($$((`/__\``(4@`@D` +MH:EP`0./\<]QH@``@`BAX'[@>,]PH@``@`@8@`]X!,X`SMR!H,]RH@"L;""" +MSW``_O__!'D%(8$/S@```""BSW.B`*AL((,D>`4@@`\>`0```*,`@HHA.``D +M>(5X`*(`@R1XA2"$!P"CX'[AQ7S8SW*B``!XSW&B``!T`Z$$H>O8!:$$W::A +MJ*&JH0G<3!H8@TS8SW&B`(!U`:$\VV6A`=@2H3+9(Z(DHJW9):*FHJBBJJ(0 +MH@C9,Z)WV3VB0MF,&D``3!H8`TC:SW&B`(!Y0:%EH1*AX'_!Q>!XSW"!`)A1 +M`!B`#Z```$P$&(`/H``$3`@8@`^@``A,#!B`#Z``#$S/BSW$!``"` +M.&`(HL]P@0#('0`8@`^@`(!,#*+/<(@````-HL]Q````@#A@X'\.HN!X\<#& +M"(_Q"'8H=QIR`-T#\`'E'0U5$1)M%'C'<($`E%`A@/$.1)`"@.D.!9"%YER(87)<&"%Z7+^#>_S"B0`!+$`C_'/<*``@#`"@!$( +M7P**(=\/SW"@``!-(*#@?N!XSW&@`(!,&(%&((`"&*$)````X'@`V<]PH``` +M32"@X'[QP`X(K_$`VL]UH`"`,,*%SW"!``!PSW$````0*@_/_\]W0````,]Q +M!@``@"\.GQ+/<$:``'W`@.EP#@_O_P':Z7#)<0(/[_\`VL]P00```,]Q```` +M@`':`_#I<`#:Z@[/_\]V@0#8'0"&A.@"EB+HX(5!A5!Z`-P"\`'DFNS/<($` +MX!T6)@,3((.6>*"`I'GD?>L)08,"D"*3!'E$>-\)`8#/<*(``&QX&(`/```` +M@,D'3_'QP%X/3_$H=N:X`-W*($(##O16#R_\!]@'\/`@00,5)DP3(*0!Y<#E +MN?-"X`B"` +M#P$```#/=*``@'H\A`CP/(1;@Y!R`-K*(F\`!"!.``<(@`-VZM%PRB""#P`` +M"@-0#8+Q10=/\?'`S@Y/\8(D!##/<*``@##"@,H.+_P&V,]U1H``?4`E#Q,; +MZ(MQ4@_O_\EP@.#*(*$(%/+GOC/8RB!A!`*E`-D(\!)I,"0`,!4G3!``I`'A +MP.&Y]P/P_]@"I>$&;_&`)`0PX'@`V0\A`0#/<*(```@AH.!^`-D/(0$`SW"B +M```((*``@"1X0B``@.!_RB!B`/'`0@Y/\>42`;;GR0'<)7@I:`MY`-G/<($` +M\%#%@.'!SW6``*0)#X7")`$36PC>`@Z%0!6!$!T($`6,[$2YP;F$+@@5`"&` +M?X``O!L8X"E@3R%``L]R@`"D)'J"$:7!%8(0)'M$N<&Y9'HZ8L]Q@0`H)/0A +M@0"R'400SW&!`#@D]"&!`%GPSW"``&0*(H@DZ1"%#0@>`E,@@0`$\%,@P0#/ +M<*YSW*!``@G]")"`!&E +MLAV$$,]R@0`8)_0B00"T'4000@Q@``#9PLDNA5"(SW!$`&BYW!`#``2[QW-$ +M`&B["PD0!4`C#0,#\$`C#03H$``!`-D'"(\`((7@N<]P@`!$!P;9!/(@@(8A +M?PY"@$8B@@%%>:"Y(J!:#J`!`=@`A2\@`P``I14%;_&AP*'!\R"N_X2G`*)(`/@0`X5THE`""J<$IQRG).#>`!*G,*\`#8 +M2G'*H#BRB),!7&& +M4'HE"L0`]1H8L*#8`:9$'D`5%)=BN()P$:8"V`<>&)"`V`"F`=HM\#D-P!6, +M)0.5'_)$'D`5R!8!$!27!^`B>(#@RB!,!1&F`M@''AB0(-@`IL]Q@0!$%1F! +M`>`9H0_PSW&!`$05%X$!X!>A!_#/<8$`1!48@0'@&*$`V@39DLV&(/^%&O2, +M)0.1%O(?#!$@SW"!`!P*98C/<($`;`E$*SX+,"!`#A$(7@"2&IR_````$`3P +MDAIL*Z]".#`,]RH```(%J"<+L9"N0` +M`-X0>'![%-K>#N`!F'8)"!X&R7`K\,+)SW&!`&@#$(C/C/<(``!`[!@>*!`A$1`:"` +M-+TJ\&X(3_K/<:```"@"$0"&\PB>@541`H8`W5496(,"V`09&(`O*($`3B"! +M!Q'JSW"``%P'-GC`@.&`SW"``-P']"!1`"#@\"!-`,N]!/"I=ZEV.G4$$`$@ +M`!A`4`@0`2$`&$10SW&!`#A1`($&Z$*!`-@`&(!0`*'/<(``%/T!@`:`Z[C* +M(((#RB'"`\HB0@.@#B+_RB-"!%,AP2`,N4`M`!4E>(*X`!@`4``8@%,`&,!3 +MJ7`J<ESU0!/\>!X\/'`[@\/\3IP*'8:""`` +MR7$*<.EQG@_O_ZER(0!/\>!X\<"^#P_Q"'4H=DAW4R!^@,H@@@\```8\(`YB +M\/'`9@\/\:'!2'?/$'"?"`X@?EI'G/(>(&SR$B!S"@`,$!V``?0$``V2"F +M+0``HUAA'-DR#N__Q=H!Y<]R@``( +M#N`2``!'#0401"T^%R]Q.&)KD#AB"I`(=)3@@"3"$`:``#QP.'%SW"! +M`&P>`("AP1GHSW"@```,K8"R"&_YBW"$Z`D-%1$;#10>SW"``&0,SW(``/\/ +MG@WO_P39G@I/\8$&+_&AP.!^X'CQP,]Q@0#,%E"9$9GT'(BP0<`*@0/H!H$" +M\/_80L!2L8MP#-EF#>__BB+3#Z/`T<#@?N!XSW*!`,0=((*"Z0"BX'[@>/'` +MI@T/\0(/K_BBP>H.K_B*)P@0"''/<($`_`<`@`HA@"\&``"`@^`!V,!XBW*2 +M#:_S@<,`P,]U@0!0#@6X'&5`A,]V@`"$M2&$@*9984*$'64Z8B.$!X4`(9,` +M)(1%A&)QAH0[8IMC`"#0`,]P@0#4'5IP(*#/<$:``'T@H$&@`-TE&E@S%_`! +MP+MY1"@^!\]R@0!D'4-Q%"%`79#923 +M#"!`I#@/[?_*(*T``(8!@!!W*`_M_\H@[0``$@`@4R#^@A@/XO_*(*(!`".` +M+T````#/<8`````+H0"&!(`,H0T%+_&BP,]Q@0#0)O`A````V0\A`0#/<*(` +M@"@QH.!^X'C//'` +M3@P/\2AV2'?/=40`@,$6?4&%`KE0<"2```-@6"2```=@2"2```M@*"2```]@&"2``!-C^""`` +M!=CZ""``!MCR""``!]CN""``"-C/<*(```@4&(`/`!$1$1`8@`\`0'9V&@D@ +M``'8T<#@?L]R@0#0)O`B`@#/<*(`@"A5>""@X'[@>/'`J@L/\<]PH@``"*.` +MXKW1):&2$/+/=H$`4$L`AH#@RB"!#P``+3/X"6'QRB%!`P"&0'CFO=$EH9,1 +M\L]V@0!02P*&@.#*(($/```M,]0)8?'*(4$#`H9`>!,-A!\``0``*@NO\T$M +M`!:Q`P_QX'C/<8$`T";P(0$`SW"B`(`H\"!``.!^X'C/N!_(*+QP`AS.@_O___9.@[O_VAPSW$```__ +M2@[O_VAP`-G/<($`4$MU>""@T<#@?L]R@0#0)O`B``#/@""!7D@ +MHN!^X'C/<:(`@"@0H>!^X'@M!X_R`-L-"=$'`*(!V`?P"0G3!PD)$P``V.!^ +M']P%\`\C`P-AO/T)`H,+"$X`97CM\69XZ_'@>/'`;@H/\<]R@0#T#6""SW&! +M`/PIE9D#H@#=$P@B`^1I!]@!V2*B`*(]\'QCE'P\9,.<(PB"`X%K`O`!Y!,, +M%1*=9+1]-2%-`_,(0X,8\`'8&/"!G)%PRB!*`\HDRA!2]FAT`_!AO'7LG62T +M?3UEP9WU"(.#_!5-D>T(0H,!V&&\(P@>`(#DSR!A`,HA(0$%\H3K@;@!V2*B +M@**<9)1\D6,]Q`0!XWP'8=0;O^`3:X'CQP+H)#_'/=8$`S!8^ +M#^__$)T(=A,('@#/<8$`]`T!V/8,H``A@0T.GA"*""_\$)T9#EX0SW$!`'C? +MSW*!`/0-`=@N#N_X0H+A`0_QX<7=$@RV"WPA\@)K!2"`#\7N@.'/=:```"#/ +M=*``@!P!I!N%TKD!I$`KP`0E>)^X`:0`V0GP\")``#`@@`^@``!@`>$!I/,) +MQ(#@?\'%X'CAQ=T2#+8+?![R`FL%((`/Q>Z`X<]UH```(,]TH`"`'`&D&X72 +MN0&D0"O`!"5XG[@!I`#9!O#P(D```(`!X0&D]PG$@.!_P<7@?P'8X'[@>.!^ +MX'BAP?'`L@@/\1IQSW&!`%A7*'8,&8`/`(````HB@"_^__\_!""!!,]W@0#0 +M4`HC@"^``*0)HX_&$X`@JWA(P2'ROQ.`(`#94R!"``\A@0`$(5�KC!N`#9 +M#R$!`"1]#?(#[0L)D"`J=0?PSW"``'`+`(!`>'GH#KT(P*5X`_`!AR5X2,`` +MCPC"1+C"N`ZX!"*##P$``,`+>XC!%?+7*'!\<">#\_PSW*!`(A72'4, +M&H`/`(```,]R@0#04("*0\%$O,*\#KP$(8X/`0``P(M^@\,5\M=V````0,PF +M@I\```"`S":"GP$````#]$&"`O!"@JZYK[FPN25Z0*,#P0C:+KG"N42E0X5` +M*0,&97I#I0/#8:4-"!X"G;I#I07PBB`&!@2EJ7``V@'>4@LO\\ESPLDPB,]P +M@0`,""A@%AV$'P``_P\*M:EPN@\O]/U"T2`X'[AQ:L*$`!`(L,#)+O#NI<*%00S)H)P@0`4($`G#'-4?"!\ +MH(@!&5(#`>`!$(($`1F2``$0@@0!&9(``1""!`$9D@`!$(($`1F2``$0@@0! +M&9(``1""!`$9D@`!$(($`1F2``$0@@0!&9(``1""!`$9D@`!$(($`1F2``$0 +M@@0!&9(``1""!`$9D@`!$(($`1F2``$0@@0!&9(``1""!`$9D@"`(_^/`-JS +M]>!_P<7@>/'`'@[/\`AV4R!^@"AW2'4$]%,G?I`)\L]P```#/,EQ@@PO\>ER +M(^T#;2*XP;TW#141,R9-4"&!!^0$`3F!!8!%`0?4!`$ +M%@$4!!]0$`06`10$'U`0@"#_CP#=X_4A!L_PX'CQP*X-S_`(=BAW2'7@N-$G +M(9#*(((/```%/,HA@@,4#"+QRB+"`ZL-$!!`)<`3)+C#O9<-%10S)DUS@0`$ +M($`G`7.T>2!Y0)8"'Y00`N8"%@$5`A]4$`(6`14"'U00`A8!%0(?5!`"%@$5 +M`A]4$`(6`14"'U00`A8!%0(?5!`"%@$5`A]4$`(6`14"'U00`A8!%0(?5!`" +M%@$5`A]4$`(6`14"'U00`A8!%0(?5!`"%@$5`A]4$`(6`14"'U00`A8!%0(? +M5!"`(/^/`-VS]4T%S_#@>*+!\<#"#,_P.G!*P1IRB'"$*`@%+W``(($/@`"D +M&D:!"B0`(5IS*!0/,1D*000ND1$)P0,`(($/@``<'``9`@1!*0`D0"\!%`5Y +M02D``B=X,+DG>,]V@0``#Z".4R"3`<6]D.7*((H/``#-&^@**O'*(4H#`([F +MN`#8)/3/<8$`!!(6(4`#!XBV>0"N`!E`!.*Q!AD"!``C@"^!``0/0(A'J4`H +MP2"@J#5Y`!I"(\=Q@0"$#R`9``4`@:FX`*$!V`S<7P3/\.!XHL'QP`X,[_"8 +M<$7!%!0.,3"X0"X!%`5Y02D``B=X,+DG>,:X`""##X$`!`\"\&=LH(N`WUD- +MWQ'/<8$`!!(H=+9\!HSK"@&`SW"!`*0/`[I5>D!@A"@(!2]PN'#'<(``I!I& +M@!4*`0$.D!$.`1``)8`/@``<'."H!XRV>0"KSW"!```/0(B'O4>IH*@,W/,# +MS_#@>*+!0<$$%`(Q02@!!$`J`P0E>T$K`0)G>3"[9WG&N<]S@0`$#RMC`_!G +MB8#9'0O?`<]Q@0`$$G9Y8('Q",&`8I'I"L&`!HD#\"APX'^BP.!XSW*!`*P6 +M!H($@""`@"$/"JT&(`!(<.!X\<`:"\_PSW"@```@NX#/!>@" +M)0X0!X,"?L]T@0#$$J`4`A8`V``B@H.A%`$6H!R8$`$A`0"A'%@0)H.@HYX4 +M`A8'HP`A@8"?%`X6GAQ8$`$F#A`I@Y\Z,]PH``` +M#`V`0B``"$@@``",(`J-F/>=V&#`C\T"'`0P`>`$((`/``#_OX^XCQH`@_O^^'`@.#* +M(($#RB>!$PGR<@S/^QH,[_L(=BH,[_L(=Q"^SW6!`,02PJ4`%)0PBB,")PHB +M@"^@```0BB(*#`\,P20P&IBO`+BP`@/P,!J8H``?0$0-#U$0(H6!N2*E!.@" +MA8.X`J4*(8`OH```(&P1`"#/=X$``'")'1@0`8_/<8$`Q!1`)0X2#>A*($`@ +M`-@!KU4A0`L`V0X)K_**(@0-`H^`X,!XRB`!!`;H`H4`V8"X`J4$\(HA_P_/ +M`0>$!`!XHPB@HH`AK?W`AH8H`/:!QJ8H`"& +M)'@`I@L,P21F&9B@OJ/_HT$![_"AP(4&[_\`V.!X\<#AQ0AU,@@@``#;*6AH +M<@WP*&45"!(,$0B3#K8+S_62:IAX!7L!XF&YZPD3@#T![_!H<`AR`_`!X""( +M_NG@?T)XX'CQP,]QH```10`9@`\`0```X'@`V`"ASW"@```4%Z(PE!YVU]\]P@``0+P"`%0@?`\]PH``` +M.#`8@`\````(?@L/^P#8SW&@```\`*$$@?\('H`$@0L(7P`"V`.A:2!``/_Q +M\<#AQ0#="?`J#B``J7`B""```>6O??4-$I'/<($`E!H."```F@L/]%$`S_#Q +MP.'%"'4$\`8+``!*"R``J7#\Z#D`S_#QP.'%.@L@``AU0H4+Z&*`(((&A09Y +M!84E>`"B`X5@H`SP`((FA21X`*+/<*```!P<&(`/`'P``/T'C_#QP,]P@0#X +M%B"`SW"!`,P6$)@%Z:((```#\"8(``#1P.!^X'CQP`7H7@F/_P;P`=G/<($` +MS!8GH-'`X'[QP$8/K_``V\]U@0#,%D"%A&T3M83J:'`B\`'C]23!$`D)`P#W +M"X2`186,(L./!O0`V&6E:'(-\!4+@``-"X4`,IUBN0D(0P`!V`/P`-@(Z"EK +M4'/*(X@BO_\>ERJ5%!X_PX'C@?N!X\<#A +MQ<]U@`"8$R"%4R&`!PL(5`)!*?Z'!?3/<`\`0$(%\,((S_@`A=ZX^@C/^!4' +MC_#@>%$"#_3QP.'%H@@@``AUA"T(%<]Q@`"P&C`A00[//'` +MX<4(2%D@(%3(D$%4R1- +M%:)Y.&"`X""@02J!!3:\@GEM!J_P(:#@>(0H"`7/<8`` +ML!HP(4`.SW&!`)08`K@5>`!A`(#@?N!XA"@(!<]R@`"P&C`B0`[/F"B8:(!X2]Y\0D$@.!^\<".#8_P +MHL$(=2AW2'9N"&_SBW'/<($`$%>V>&"``,(!@``BPH`!P0$@0`!!P$"G`<`` +MIL4%K_"BP.!X\2%B0('/ +M<8$`$%<6>0"!X']88.!XA"@(!<]R@`"P&C`B0@[/>!_0*'QP,8,C_`(=0"`'>CAA<:%7@OO\*EP#0^!$_8,[_\& +MA02%!B8!<``"``#=R2MX"?+/<,7N@L$!V=(-X`!#A0'8`O``V.T$C_`@@#!P +MRB$A`.!_*'#QP'(,C_`(=:8/[_\H=PAVXJ6"#R_SJ7#%!*_PR7#@>,]PH``` +M'!P8@`]`````X'AL<`$(G@7@?D"``_!`@@\(@`!D@BM[_/,"\`#:X'](<,]S +M@0"4&D>#".I"@D"@!X,#@`"A`=@#\`#8X'[QP`8,K_!\V>/)&+DE>.,:&+#/ +M=:```"`''5B0`-[)=POPZ7#R#N__`-GI<(H.[_\`V0'G[W_O#Q*1)@[O_P78 +MVZ4`'8`?``P/``@=@!\```#P`!V`'_X```"*(`@``J4!V,P=`!"F"\__"02/ +M\.!X\<":"X_PSW:@```%IX)(``!V`8)```/#1X7C@D@``+8^@@``!$-7A>""2```]CJ"```'!Z` +M'P!\``"M`X_P%=C/<:```"!A&1@`"!F`#P,`X``)V!ZA'Z&(V-`9```$&8`/ +M``0```#8&Z$`&8`/``P`&>!^X'CQP/H*C_#/=J```"``'H`?``P/``@>@!\` +M``#PD@[O_PAW&X;X8!NF;!80$`#='/`R;35YQW&!`)08`-@/($`#!:9"@0.! +M`-Q@@@"``"/#@V"B(X$!(``#`*'@O5`.PO\!Y:]]S0T2D0#=$/`R;35YQW&! +M`)08Z7`R"2_T`=K@O2P.PO\!Y:]]Y0T2D<]P@0"4&K8*S_\>"0``R0*O\`IP +M\/'`G@W/_\]PH```(`08@`\`!`\`#!B` +M#P```/#1P.!^A"@(!<]Q@`"P&C`A0`X"N!9XQW"!`+@:X'[@>*+!\<"F"8_P +M.G$:<@AWJ@UO^FAU3@WO_T`HC@)3)4`5$';*((4/```U$EP)@OO_ZEQZ7"Z"J_Z`=D,W*\! +MC_#QP((/[_\`V(X)S_]V#^__`=B&"<__;@_O_P+8>@G/_V(/[_\#V'()S__1 +MP.!^X'C@?N!XSW"!`/P'`(`3"%$`SW&@```T`(%2(,`$`*'@?O'``@F/\-S) +M)PC>`,]PH```1Q08@`\```P,W\D%V0'@L[BUN+BXWQH8L!6Y!*'/<(``^!0` +M@`0@@`\/``#@+R@!`$X@000E&E@P`=L/"9`!SW"!`$`(#I`>Z"4)D0'/<($` +M0`@)D`SH*@LO\@'8C"##CQ+RD.@E&M@P#O`9"5$`$@LO\@'8C"##CP;RA.@& +MV"4:&#`E$@(VSW:@```$3Z9/(@`"SW6@`(!^"*4.AL#@U_?=R`*AX'^AP/'` +M!/`>#T_YSW"@``!%'H`$(+Z/<````/;UT<#@?N!X\<"^#T_P"';/<($`'`K6 +M#^__IH@*(H`OH`"`1$`2`"#/=Z```$5&(`$-0!I`(`2'!""`#_]O_\,$IPR' +M!""`#_]__\,,IP`?@!\`0```X'@`V!IP`*<3;:5X#:=B#*_RJ7#/<8``@`D' +M@8[H`X&&(,,/`Z$)#1X0@+@#H0D-7A"$N`.A"B&`+X$`*!X`$8`@#0T`$+X( +MS_0`&4(C0!(!(`4A@0\`@#0`0!I`(#+N%PY0$$L.D!"*(%H*C@VO\,EQ*/#/ +M<:```!`)@0;H)!D`!(H*C_P0O8^]F[W/<(``1`<`@)^]Q+@*N`5]K*?V#L__ +MBB#_#QRG&*<,\!"]C[W/<(``1`<`@)^]Q+@*N`5]K*<-!T_P`-C/!^ +MX'CQP'X.3_#F#>``"'?/=J```"`[AL]P@`"L%I((;_,@H`AU`=F`Y4@A`0`PI@#;4/`)#U$0()$HMJ"J +MSW&!`'0;0($0%@01%0K.`,]R@0!P&^""H*$!Y^"BSW&@```=3($$(@$!-+8X +M8,]Q@`"D)#R!`B!"`#!PRB"-`,H@;@`,<1\)S@#/<8$`4!L@@8PAPX\#\@\+ +M0`!3($"`RB!A`(HASP\)($$`(*0,<1$)S@`@A`D)!00`%!`0SW:!`.@O0"8! +M&'5Y`*$$Y`#=`>-G"Q4"`-FRIO<+T($0AH#@S".B@0/T*'`#\/\+T(!`A&]_ +MSW&!`"0=]GGDB<>&_F;88,]V@0"`"'1^C^H`(X(/@0"@"."*(0^1D.B6(9'[ +M?X"_Y'F+\326"0F%`#A@N_%4MEA@M_&@I@0>`!C/<*```"`1@+&F`J8`V)&X +M6-G)<@HD@`\#`/__X@Z@`!/;IZ8-!6_P"G#@>/'`H@Q/\`AV*'<`W8/@RB"& +M#P``#D0("Z;PRB&&`\]Q@0#H+T`A`@,5(8,#"0Z1$..C"_#/<(``I"0=@`4H +M_@-!*0!T`Z,`V`?P\"(#``'@<'7*)$`C$`1`(X$#&V,'DST(4@!AN`>S4(H3 +M:A5X$&&6Z`#8#R"``,()H``?V<+)$(@S:#5Y-"!!(.&YD`F"\)/-1B#``),: +M'+#"R>H*;_K$$```)<@`(($/@0!@"!1]P*G(J0]ZSW&!`"0=5GD@D9@=A!-0 +M'400PA(!MA5_`8$$((`/````8,"G&PB!#P```"#$$0``SW&``.04%7D`@1#@ +M`*&Y`T_PX'CQP#H+3_`DR$HAP"'/<:``'"XY@<]WH```,`1Y+RA!`$X@C0>5 +M%Q26!!<3EB42$#;/=J````0\'D`4%@CO_H#8SW"@``!^6G!@&(`/`("``#8* +MH``J<`3P`]@*I@Z&!^A\Z!(-3_P.AOSQ8!(!(/4)WX<6"J``"G"I<(`@P@&4 +MYB.` +M!2&!@,H@@@\``,(A$`F"\(#9SW"@```<)*"5'QB5!!_8E,4"3_#@>/'`=@IO +M\`AR"'8:<0#?$?`O*8$`3B&`!P]X,F@P(8$/H``T+Q`B`@#"N0\G3Q#RZAKP +M+RC!`TX@C0=Z":``J7"4RB02`C8"N#`@@0^@`&0N$"=/$T1Y"G"^"6_XQ'D6 +M#6_\J7#G[TX)H``'V'$"3_#QP`(*;_`#V+#!&G#/=:````0(I1`5$1`.A<#@ +MOO<`%@!``!8`0$#`(,"23(`KDP(8X/H`!D+A`ES1,$?@4AD2,*\#)H,"&!#Z``M"X`VM(-K_Y(T`3_#@ +M>/'`J@AO\`#9SW"!`'@;(*#"XMO+/<*``@$4P&(`/`"```<]P@``X$F"@:B&``<]P@``\$B"@ +MH@ZO^$APPA(#MC"+4R'``$2YPKG`&T(`,V@U>1"KQW&!`(0/0($U"E\"&@NO +M^`#9PA(!MH0H"`7$&0```"&!?X``I!K,&EBP1"@^"TZ!`"&!?X``F"M`H1SP +M5B,"!`B"D+@(HO_8$:(D$8``SW*!`*@/`>`D&0(`,(L3:15X"&*#X,H@B0\` +M``@K'`Y)\"2&PLG/=H$`'!VT&$0`Q!```+H)+_K)<<]QH```(#N!.&`!ILG) +MPA(!MCX.;_@E$@(VPA(!MK`1``&["$4#(8'/<$0`:+G<$```!"&!#P```!@$ +MN,]R1`!LNQYB`&+@N,HAH@$#]"NY.WG/2*BT@B@``#8 +M`(8O(`,``*8$(+[/8````,+)5B`!!`CR(!F`#P`1```)`P``4(C/<($`#`A* +M8`F1Z@GO_"6!'?``%@!`RQH8L``6`4#9&EBP9,N`HH*S_K"$@&VSW"!`$`()1("-D`@#`Q4>&B0I.O0 +MB<]S@0"$#P.^U7[#8U$C0()6(0,$'/31B(3NQH-5?,"DD8//46Y\")!`,2X$2$`@,(2`;8,\J`9@`\!`)0` +MSW&!`$05%H$!X!:AP/#)R>:XO/0!@0\(G@:@&8`/`0"0`.'P`[[/=X$`A`]` +M)X`7U7[*8,`1@``1"(``H!F`#P$`D0#1\,]P@0#\!P"`0)$5")$`SW"@```$ +M#H`0<@#8`_%!P`=K`>@;J(!F`#Q`!``!Q\"`9@`\!`(@` +M:_`)@;2X":$)D:>X";$/D:>X#[%A\"`9@`\!`(4`7?!&ES,1@`!;"@X`SW.` +M`%@2`8/+$@*V"N@LNL2Z`-@/((``0X-$>`CPP-@8N`1Z$'(!V,!X#>A6(0($ +M"8*TN`FB"9*GN`FR#Y*GN`^R"?`!@0\(G@&@&8`/`0"-`"WPR!#T"9-5)$0=)8-(DZ(-H`!YD\(2#+:@%`$0)7B@'``0JW@&\K8. +MC_$%`$``5@DO\HEPR(P@ +M!(L*@\HA!@,0<0.1$'3*(`4#C"`'C8NC0_<` +MV(GH*8.QN2FC!O"*@XNC^/$(=`0:@`\``P``P!(#`"%K,'3*(0T#8GDZH@`: +M@`\``0``PA(!M@OHI!$"`)/-\;K%(*($SR!A`),:'+`!@0T(G@.3S8"XDQH< +ML%")SW>!`&@#$VH6>`-G`-V,O1R1I'L%>X8@_PQ\L8,($`$ER,]T@0#8"/0D +M`!`%>P&!?+$5"%X#5!$``;@1#`'#N(5X5!D$`&APAB#]#(P@`H(9]`.Z57K' +M`(V[?+&&(_X, +MR.//#+[+>`GTAB#UCP?R`]G/ +M<*```!0IH"X*@`"`X+[T)8`U!\<+)I!```,\('@-F#V_P`=C" +M$@&VSW:@```(';%?$H&PSW"``$@**F#/`@T.ZSW"!`!P*!HA$)($1 +M'7C`N(8DWA,E>`>ZAB+A#T5X!7R`HVX+8``$V,+)$(@#N!9X`&<$?0/8`J:% +M)0(=`!A$4\+)/9``&$10PLDO@!4)'@#,R2:``!A`4,S)+I`'\``80%#"R4`0 +M`0$`&$10PLDQ@,@0``#QN,\A(@``&$!0PLE($`$!`!A$4`#8`:;"R900``#I +MN`P-@?HZ#<_Q704``)X.;_`"V,(2`;8=L<]P@0!H&U8/;_+`H,+)F!`!`)08 +M0`#"$@&V@"$"``^179$)L4BQ=@DO_R:!PLF."J__>!```8#@%`4"`*X-;_>+ +M<,+)5B`#!%4@1`T)DR6#2)-Z"J``89/XN+`(@0`;"!X&`]G/<*````0HH(H@ +M$`#=!"``R1H8L,(2`[:D$P``AB#UCU8C`@0'\@/9SW"@```4*:"I@O2]RB:! +M'Z````@B\L]T@0"X5\*$"9(;#K00)8)`A)8*;_%`)`,4-@H/\XT$``"GN`FR +MM+T)DJFB@",#!78*;_%(D@/8SW:@```(`J;"R<]UH```(#&(SW*!`)PFPKDO +M8L]R@0``)REB&)`!V`BF1:;"R0&`'PC>`,]S@`!$!P*# +M((.&('\.1B&!`25X`*-(<`+P"-A&"$``&X7`%0$0(GC"$@&V]!D``,]PH``` +M15R`&(!5"%\%!"*^CP`&```D]`2&+R8(\"#RL!$!`8`A#PKF#&``0-@,`*01#`"*(@@%Q!$!`,]P@``6'&)H3'D+#!X0-"!/#@CP +M7@FO^C0C3PX$\'81#P&3S5,@?H`)\LG)PQ(!MKH.;_$E$@(VSW6!`/0_QPA(!ML+)R1(1ML]V@`"X%*`0$``!V`"FW@YO_^EP`-D@I@GHAB!^CZ[R +MPLF@&``$R1I8M,(2`;;/A5['H-8 +M8!ZC`8&5"-X`I@TO^X#8"'((W),2`;>2&ARSI[FKN:RYPA(#MI,:7+`0BS,3 +MC0`$N*5XSW6!`%!0F'`&M0&#.PB>`8NYC+F3&ERPSW"@```N\H`,\"\HP0-. +M((X'(\CT((`#$">/$Q$(``'U[P@=A!\``/__`_#$M9(:'+,!@PL(7@>'N9,: +M7+#/<8$`Q!,4@0'@%*$E\!#8DAH/'`X<6JP8MU +MJ7#/<8$`T"!J#^_O*-JI<$X([_'"$@&VL@Q@`*EP/03O[ZK`SW&!`(@/`[@5 +M>+$%+_X`8?'`H@OO[YAP*'<*(,"@2B4```\E!0``W`#;#R,#``#8"'$.\,]R@`!P#?`B0@!K>@3R#R!```]X`>$O>>D) +M4H'@?N!X)!(!-@*X,""`#Z``9"[%$@*V)'@$>@#8#O`O*X$`3B.!!R]Y$")" +M`,]S@0"`%_`C00`E>//J`0$/_N!X\<"2"L_O*'8!W#X)+_X`+``0"'52#Z_[ +MR7#//'`4@K/ +M[RAVSW&``+P40($A@45Y!B!-@!#RJ7#)<>8+K_(!VN((+_ZI<`AU^@ZO^\EP +M!@JO\J1XB0+/[_'`%@KO[P#:"':^"Z_R*'6Z""_^R7`(=M(.K_NI<*8*K_+$ +M>&$"S^_QP.H)S^\(=0#>#R8.$,]Q@0"(#P.X%7@'8``!\`0R`0 +M#`(`'P!#(8``'T!`2'`"V74#+_=HX#WA`*($"X\DF>!D&+_/C&ABPI[@/ +M>$`H@0+CR25X!08O\^,:&+#AQ>'&SW"``(2U`(#/<:````@`@"$9&("`(`@` +M`-L<\,]RH```!&^B#:)[?``B`3-,$0$'0W0LHFBY2"$-`#5KQW&@``1]H*$` +MV2FB3!0!%P'C.&#-"Y2#P<;@?\'%X'A/(`("SW&@`(!^2*'/<:````0/H>!_ +M)1H8,.!X\<"N",_O"'$!'1(0^0F$@XD`S^_@>/'`#@C/[PAW*'53('Z` +MRB""#P```3QT#N+ORB'"`\<-$!!`)``6`$`$'Q`0`!8`0`0? +M$!``%@!`!!\0$``6`$`$'Q`0`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0`!8` +M0`0?$!``%@!`!!\0$``6`$`$'Q`0`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0 +M`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0@";_GQ#=J_69!X_OX'CQP"H/C^\( +M=2AVX+C*(((/```"/(P-XN_*(4(#`_!"#H_XSW"@```$#H#;>?,(1(``V0?P +M`!8`00'A`AT4$/D)A(-9!X_OX'CQP+8-S_^J#,_]`=G/<*````PQH"6@P@S/ +M_='`X'[@>/'`@@^/[T+!SW*@`(`<`:+/,AHO<+!(#1P.!_J,#@>-T2`;8E"9X&SW&@```@SW*@`(`Z%VSN!(:(!HL]P@0`<"F6(SW&!`&P)1"L^"P:(,"%!#A"X)7@!HL]Q@`!$ +M!P"!`:("@0&BX'[=$@&V!]HM"9X&SW&@```@SW.@`(`Z``&5YSW"@ +M```@SW.@`(`<(:,;@`&C"/`)#!X0`((!HP3BG7SZ[.!_P<7@>`?P!!`#!,]R +MH`"`'&&B@.%AN?GUX'[@>/'`X<6RP0G8)1H8,,]UH```!`^EBW!:#>__`MD. +MA004`3']"$2``,`0>C\*40$,<(#=Y[C*(.$&M`OA[\`H80*B#\_W>@@/]\]P +MH```'*2@W,F%"!X"SW"@``!'$!B`#P``#`PX\!T*D0""P`(-[_\$V0+``\$$ +MPI(+[^\%PRSP$PH1#E$)4P2"P.8,[_]"N2+PRQJ8OY````#9&ABPT>(!P-H: +M&+`6]-S)*0@>`L]PH```1Q08@`\```P,W\D%V0'@L[BUN+BXWQH8L!6Y!*'N +M#\_V`A0`,00@@`\```"`3[@K"%$`!A0`,2,('@``V$'`BW``V1X((``H<@G9 +M)1I8,,]PH```!"^@[02O[[+`\$`F`1(-"04`4R9^D`?RSW````$VG@K/[ZEP +M/@VO_@+9!^[I<#8-K_Y!+H$0?02/[^!X\<"2#L__SW"@```<&!B`#R````#1 +MP.!^A"@(!8HD_!\`(8!_@`"D&DF`YKH$(@,#RB&!``/R4"+!`>6ZQ"$"`^2Z +MT"-B`>.ZT"$B`5@8V`#@?UD86`#@>`AR!""^CV`````ER,]Q@0!`"``@@P^! +M`*`(%'D%\L+)')`7")X"!"*"#V$````3"H$/`0````#8`+$!V!SPDLW"$@*V +M&PC>`0&),A*"``T(@0``V`&I\_$!X`&I"_``B3$2@@`+"($``-@`J>?Q`>`` +MJ0+8X'\`J^!^X'C=R3T(7@#/<*```"#/<:``@!P$&8`/Q>Z$5AN``:'/<(`` +MI`D/@`&ASW"@```F$H`!H<]PH```$!F``:'@?N!X"'* +M`<]PH```(,]SH`"`'`0;@`_%[H/@&X!%>0&CSW"``+P*`(`!HR&CX'[/<(`` +M$"\`$`0``=D($`4`SW#%[H>2RQ("MDHF``#9$@.VX0/O_PHG@`'@>.'%W1(, +MMBD,7A'/=*```"#/=:``@!P$'8`?Q>Z%.9N$#+F!I2&E`:5!I6&EX'_!Q8;B +M"',`V@KRR\DLN,2X`K@P(((/H`"T+L]PH```(,]TH`"`'`0<@!_%[H4R&X`! +MI,O)`:0`@P&D(:1!I.!^X'C/<*``@!P$&(`/Q>X!!`08@`\%``2$X'[QP.'% +M"''/<$0``(`M8(PEPY\%\HPA0HW%]O[8:@CO[XNX90*O[ZEP\<#B"8_O"'7@ +MB,&`A.?*((8/```2-$@(YN_*(<8#A"\(%0`A@'^``*0:(8`!W('A0(`@A\@W<]SH```(**CU!N``P#85@UO\HVXHZ.A`8_OX'C/ +M(P@!XVW]P#8!O`$@?,('H`!V.!^ +MX'A\N`/P;K@!"%,`X'[QP.8(C^\H=0\)7P4$(+Z/``8``![R/0T?%<]VH``` +M(&P6$!`4\#B'/@^O[XH@F@H.\,]WH```1;B'Z@]/^!N&`B``!.,(@X\``!`G +MYPT>E?T`C^_QP.'%#''/<*````C/=:```$A%"1X#-H`$@!!X.&"*(1(*%GGZ +M#N__@-@,<"D('@//<($`>!L!V2"@,!4`EN*XC`@B_\H@0@#/<8$`1!45@0'@ +M%:$`V$0=&)`#V<]PH```"">@K0"/[_'`X<4`W9B]`-@*V<]RH```(#"B`=D' +M&EB`$-D@H@AS"'$(@&QR)0H>``'9SW"!`'@;(*#V +M#^_^*'#/<8$`1!45@0'@%:$)\`3KP@[/_P7P#'`+"!\#J7`"\`#8!^C/.!^X'CQP!8/3^\(=0/P1@Y/ +M^,]WH```,),7`);S"!Z!RQ(.MB7(,!^8DV\(D`$LOL2^!/`>#D_XDQ<`EOD( +M'H$2;C`@@@^@`+0NR7"`(,(!E.;*)@80`KXP)H`?H``8+,]QH`"`#(`@!`!" +M>`]X.P@U`C#;0!F`#P"@,``)"!0!`-L#\`';V1(!MJEPS1(,MNX,K_^%>BF% +MJ7`B#.__)1("-N4&3^]PH>SQX'BAP?'`7@Y/[Z+!*'5)P5IP2'8:"@<0E>`@+9SW"@`(`<.Z`IP5-N[N%0>`7T>@BO\(MQ'_`5"=$- +M&W@0>&H(K_"+<>EP%_`-"1$%''@`'`0P"_`+"9$"`!R$,`7P`!R$/P``__\` +MV`+P`>#_")2"`-@`%`(Q5=D1N<*A0*&"N`.A-/`$);Z?``0``13R70K?(4PA +M`*#*(($/``!3`#@,H>_/("$#2G"I<,]Q@0!$%!&ASW"@``!%!(``W@0@OH\`*```2B%` +M(,]PH```(`Z`PB%")`/P<@Q/^,]PH```1;R``=\$)80?@`````0E@!\@```` +M!"6"'P`&```$((%/8`(``-=Q``(``,!_SW.@```@`-D3"1`@R!,,``L,U1"` +MY\HA80`%$PR&!"6^GP`X```$)(\?````@,PA(8#`)F$0!2```05_!2>^D`/T +MBPZ4D@\,WA/UO!"6^GP````P!X`ZAG+Y0\E,E?I!,]"7(`-D/(0$`SW"!`'0; +M(*!$\!4(W@#/<8$`Q!,/@0'@#Z%"WCKP"'2&)/V7T2"A@3/T[;C$"X+^+_`3 +M#5X5SW&!`$05&X$!X!NA)?`=ZOJ]P'[/)F(4$O07#5X6SW&!`$05%($!X!2A +M0MX(\#Z#.=A<@X8*K^^,N`#>J7`2"^__*G$*\'8+C_[/<8$`1!4<@0'@'*$` +MWMW)F+YM"!X`SW#%[H(U`=D2#:__R7+/<,7N`D(`V:ER`@VO_RIS)O`%$P"& +M\+C*("$`SR"A`S`*X?_*(2$`SW&@``!%6($%@4MXRB8A$!+R'($!V,]UH``` +M"`:EX'C@>`#9)J6R"^_^!=X#V`>EF+Z;[A$*WR$#V<]PH```""*@SW.!`-0< +M`(,R:#1Y"<+'<8$`=!P!X$"AA^`(&0`$RB#F`0"C#?#/<(````X`@`GH`-C/ +M<:#^!`B:"2_YEKC/<8$`Q!,-@0'@#:')<`C<9P-O[Z+`H<'QP/X*3^^AP2AU +M"'8Z` +MX$@*P?\(W,\";^^AP.^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X4````^%$` +M``"`1`#_``$"`P0%!@<("0H+#`W___________________________\.____ +M#____Q#___\1____$O___Q/___\4____%?___Q;___\7____&/___QG___\: +M____&____QS___\=____'O___Q____\@____(?___R+___\C____)/___R7_ +M__\F____)____RC___\I_____RK___\K____+/___RW___\N____+____S#_ +M__\Q____,@```0````$```````````````$````````````````````!```` +M`0`````````!``````````````````````````````````````````$````` +M``````````$```"`````_P```)`!```&````````````````````$0`````` +M`````````````&0````0````_P`,(`@"```2````````````````````+`$` +M`!````#_``P@`@```!,````````````````````L`0``$````/\`#"`'`@`` +M%`````````!`!@````````$````0`````0`,0`0!```5`````````$`&```` +M`````0```!`````!``Q``P$``!8`````````0`8````````!````$`````$` +M#$`#````%P````````````````````$````0````_P`$``0````8```````` +M`$`&````````,@```#(````!`LQ``P```!D````````````````````!```` +M`0````$"`(`!````&@````````````````````$````!````__\`H`4````; +M`````````!```````````0```!`````!`@0`!@$``!P`````````!``````` +M```!`````0````$`#``!````'0`````````$``````````$````!`````0`, +M``$````>``````````0``````````0````$````!``"``0,``!\````````` +M```````````!````"````/\`#"`&`@``(`````````````````````$````( +M````_P`,(`(````A`````````````````````0````$```#_`@R@`P,``"(` +M```````````````````!`````0````$"#(`!`P``(P`````````````````` +M``$````!````_P``H`8!```D`````````````````````0````$````!`D0` +M`@$``"4````````````````````!````$````/\`#"`#`0``)@`````````$ +M``````````$```!D`````0`,``(````G`````````"P!`````````0````$` +M```!``Q`!`$``"@`````````+`$````````!`````0```/\`#$`$````*0`` +M```````L`0````````$````!`````0`,0`0````J`````````"P!```````` +M`0````$````!``Q``P```"L`````````+`$````````!`````0````$`#$`% +M````+``````````"``````````$````!`````0`$``4````M``````````0` +M`````````0````$````!``Q``0```"X`````````+`$````````!````:0`` +M``$`#$`#`0``+P`````````````````````"```2````_P`,8`(````P```` +M`````#(`````````9````!````#_``Q@!@```#$````````````````````` +M`@``$`````$`#$`&````,@`````````````````````"```0`````0`,0`4` +M```S`````````"P!`````````0```&X````!``Q`!``````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````$+_P``!`(```;_````_P``#/\```?_```( +M_P``"?\```K_```"_P$`_P`!`@`/`0$"`0$!`_\!`00"`0$&`P$!!P0!`0@% +M`0$)#0$!"@X!``S_`0#^_P(`_P8"`0'_`@("!P("`P@"`@0)`@(&"@("!PL" +M`@@,`@()#`(""@L"``S_`@#^$``!`/\!`/\``0`!_P$"`O\"`/\!`@`!_P(! +M`_\"`P3_`@(*_P(""?\"`@C_`P`!_P,!`PD#!04)`P0&_P,&"@<#`PG_!`#_ +M`P0``?\$`0,*!`('"@0""`H$`P3_!`(*"`0$"?\$!`;_!0#_`@4$!O\%`0,% +M!0`!_P4%"O\%!0D$!@#__P8$!O\&`0,%!@`!_P8#!/\&!@D&!@8*_P&1```! +M/P```I$``#X]```#D0``/3T```21```_`P``!9$```D0```&D0``%AP```>1 +M```?'P``")$``!P6```)D0``$`D```J1```#/P``"Y$``#T]```,D0``/3X` +M``V1```_`0``YQ$>`@YX-&"!`0```!%)-@``"!%`0!4`"1%N7P``#Q$C```` +M%1$!P'`$&A$"````'1$D"0``,!'5````,A&,````,Q%:````-!&;5`$`-1&" +M``$`-A%S``$`-Q%:``$`.!&T+`$`X!$$````]1$!````#2#\````$2#3A0$` +M$B"4`P``($,Y`````D````#&"#)0``5F#__P``8F`8`@```7,0 +M`````G,`````9&`&````,'0!````!8`!````08`!````"L`/`0\!"\`/`0\! +M4=`#````#](`````$-(;````$=(#````&-+X__\?9](/`0``:-(/`0``<-(` +M````'-_N`@$`'=\8```0']\8````(=\P````2M]``$``2]\!4`$`3-\$`0`` +M3=]`````3M\R`3\``."``0``-N`I*2DI1>"DF0$`9N`!````-F`&````Z70Z +M#>FT40C`'D\'.=S-!C7:3`8Q&.P%KY?+!:T6BP4L%HL%+!:+!2S62P8VG2\( +MQ&+1"$;C\0A'9#()RN62"4QFLPG-IM,)SN?S"<_GTPG.9K,)3"9S"4NE,@G( +MH]$(12)Q"$.A,`C`W\\'O5Z/!SS>;@ZW8X'/%ZO!SW?[P?`H%`(PR&1"$6C\0C(I%()RR63"_'Q`(P&`P",&@4`A"83`(P6`0"$#@[P<_GZ\'O5Z/!SP> +MCP<\'H\'/%ZO![V>SP>_WP\(0&`P",%@4`A"H3`(P6`P"$`@\`>_W\\'/I_/ +M!SZ?SP>_'S`(02&Q"$>D4@E*I5()P^%P"$-A$`@_G\\'OE[/!SZ?[P<_(#`( +M0:%0",/A<`C#X7`(0Z%0",$@$`B_G\\'/E^O!SZ?SP<_8%`(P^%P"+E<+@>Y +M7`X'MAIM!C)9+`8P&`P&,IO.!T$BD0C%8M$(1N/Q",?C\0C'X_$(1Z/1",5B +MD0C$X7`(0J%0",%@,`C!8#`(0:%0",+A<`A$8K$(1:/1",?C\0C'X_$(Q^/1 +M"$9CL0A%(I$(09_.!C(8#`:P6$P&LAFM!C9<+@>Y7"X'M5JM!C7:3`:R6"P& +M,1J.!T"BT0C'(Q()R:12"``[$' +MF!D,P[`'F!D,PT$*F!D,PT`*F!D,P[('"0```$(*"0```+8'`(`LRT8*`(`L +MRX$(_WL!`!$+_WL!`+@'$!'/\T@*$!'/\[4'/P```$4*/P```+0'$!&JH+,' +M$!&JH$0*$!&JH$,*$!&JH+P'F!F*HDP*F!F*HH,'````%1,*````%80'U?__ +M)!0*U?__)(4')0```!4*)0```(`'`3N10!`*`3N10*('^A9X(C(*^A9X(J,' +M_`[\#C,*_`[\#J0'^A9X(C0*^A9X(J$'!D&?`#$*!D&?`"4``0```/`'1TP! +M`(`*1TP!``@!``(``%$(X/#@`.$*X/#@`%`(-*H``.`*-*H``-4'H@```&4* +MH@````X``D)$!!```D)$!,(`4F0``,,`0,```,0`$$((`,4`$$((`%L`(``` +M`&0`(````'T``````)<``````*$(D`(``#$+D`(``)0'4`!0`"0*4`!0`',( +M%`````,+%````'0(%`````0+%````"@!`,`2`"D!`,`2`%@%`@`*````0#(` +M``````!LNP```0```*2C```"````3!0!``,```#X.`$`!````-A#`0`%```` +M#!`!``8```"`A@``!P```-P1`0`(````%!("``D````0$@(`"@```#2\```+ +M````H'$```P```!X:0$`#0```"#+`0`.````$/`!``\````,5@$`$````!1O +M```1````))0!`!(```!\?P$`$P```#CH`0`4````K+\!`!4```#TI```%@`` +M`"PV`0`7````.+P``!@```"(O@``&0```$1@`0`:````M&D!`!L````H,@`` +M'```````````````_P``````````````_P``````````````9````&0````` +M`0`````!_P```O\```,!```%_P``!O\```C_```'_P``"?\```K_```+_P`` +M#/\!`/\#`0$```$!`@H!`@4$`0$&_P$!!_\!`PH'`0$+_P$!#/\#`/\"`P,` +M``,$!00#!0;_`P,*!P,!"_\#`PS_`@#_`P("```"`@0&`@(%_P("!O\"`@?_ +M`@0*!P(""_\"`0P%!`#_`@0$```$`0$)!`0$!@0$!?\$!0;_!`0*!P0""_\$ +M`0P%!0#_`P4%```%!`C_!04'"`4#"?\%!0;_!04$_P4``````````````!X` +M```0````$``````B`")1(A$1`/``\,#`P,#\_/S\_O[^_JJJJJJJJJJJJJJJ +MKJJJJJHH_P#,JJH``*JJ`,RJJ@```$``P```````4`#P`%``\*JJJJJJJJJJ +MJJJJJJJJJJHH_P#,JJH``*JJ`,RJJ@``````````````4`#P`%``\*JJJJJJ +MJJJJJJJJ[JJJJJHH_P#,JJH``*JJ`,RJJ@```$``P`!``,``4`#P`%``\`<` +M```/```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````#__P``__\`````````````__\``/__```````` +M`````/__``#__PP)``"0"0``5`D``%`)```X"0``&`D``!P*``!@"@``/`H` +M`'@)``!8"0`````````````````````````````````````````````````` +M```````````````!`0$!`0$!`?___________________________P("`@(" +M`@("`@("`@("`@(#`P,#`P,#`P,#`P,#`P,$!`0$!`0$!`0$!`0$!`0$!04% +M!04%!04%!04%!04%!04&!@8&!@8&!@8&!@8&!@8&!@8'!P<'!P<'!P<'!P<' +M!P<'!P@("`@("`@("`@("`@)"0D)"0D)"0D)"0D)"@H*"@H*"@H*"@H+"PL+ +M"PL+"PL+````O40``+U$`$S11``LT40`--%$``S11`!,T40`+-%$`"S11``, +MT40`#-%$`$C11`!,T40``-%$`%#11``8T40``````/__`0(%`P```````0`# +M"P4`````6.<``%CG``!8YP``J,T``%CG``!8YP``K,T``%CG``!8YP``R,L` +M`%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8YP`` +M6.<``%CG``!4WP``,-P``*C?``!8YP``6.<``%CG```,UP``X.8``%CG``#\ +MV0``\-D``%CG``!8YP``6.<``(S;``!8YP``6.<``,3````HPP``6.<``)S$ +M``"8Q```6.<``%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8YP``6.<` +M`%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8YP`` +M6.<``%CG```\Z```6.<``%CG``!8YP``?,\``*3```!8YP``6.<``%CG``!8 +MYP``Q.,``%CG``"DT```"-<``/S6``#0S0``6.<``%CG```$UP``6.<``%CG +M``!8YP``6.<``%CG``!`R0``.,@``%CG``!8YP``6.<``$#5``!8YP``6.<` +M`%CG``!8YP``6.<``%CG``!8YP``6.<``*C:``!8YP``1-4``%CG````UP`` +M6.<``%CG``!PP```6.<``%CG``!8YP``6.<``%CG``!8YP``6.<``%CG``!8 +MYP``6.<``%CG``!8YP``,.(``%CG``!8YP``6.<``%CG``#(R@``6.<``%CG +M``!8YP``6.<```S3``!8YP``6.<``%CG``!8YP``6.<``'S)``!8YP``6.<` +M`%CG``"@$`(````.!&`0`@`````&@!```$```` +M2`$```@``````````````&0!```$````<`$```0```!0`0``"```!XA0:!!@ +M@"``(`(@!"`%(`4@!2`'B%!H.'R`(((@`B`$(`4@!2`%(`*(4&A@``!``"T` +M(`,@!2`&(`<@`HA0:&```#H`+0`@`B`$(`4@!R`"B%!H8```0``M`"`"(`,@ +M!2`&(`*(4&A@``!:`#(`(`$@`B`#(`8@`HA0:&```#(`+0`@`"`!(`0@`R`' +MB%!H.'R`((`@@B`!(`(@`R`$(`>(4&@X?(`@@"``(((@`B`"(`,@`HA0:&`` +M`$``*``@`R`%(`8@!R`"B%!H8``!2``D`2`#(`4@!B`'(`&(4&A@``"``%H` +M,@`@`2`%(`4@`8A0:&```(``.``E`2`"(`,@`R`!B%!H8```H``M`"`!(`(@ +M`R`!(`P```````@("`@(#```````"`@("`@,````````"`@("`P````````( +M"`@(#`````````@("`@,````````"`@("`P````````("`@(```````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````, +M```````("`@("`P```````@("`@(#`````````@("`@,````````"`@("`P` +M```````("`@(#`````````@("`@,````````"`@("``````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````%DM@3,S,0#`````/B$````)9,H$S,S4`P````!I(0`` +M``IDS`3,S-8#`````%=5<% +M``!&!`````#Z#@```&!U6@4``$@$`````/,.````8G5!`````"H#@```'AU>`4``&`$ +M`````*$.````>G5Z!0``8@0`````F@X```!\=7T%``!D!`````"4#@```'YU +M?P4``&8$`````(T.````@'6"!0``:`0`````A@X```""=80%``!J!`````!_ +M#@```(1UAP4``&P$`````'D.````AG6)!0``;@0`````[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>%````%AI`````$$`@````0````@2``05`````(`` +M``(``&DT``"``"`@@`\``#"`(""`#P``!,X@((`/``#8RR`@@`\``'S,(""` +M#P``_,P@((`/``#\S`HG@#\```"`2B```$HA``!*(@``2B,``$HD``!*)0`` +M2B8``$HG``!*(``02B$`$$HB`!!*(P`02B0`$$HE`!!*)@`02B<`$$H@`"!* +M(0`@2B(`($HC`"!*)``@2B4`($HF`"!*)P`@2B``,$HA`#"K)@%R```!`&LF +M0'0```$`"B"`#P```(`*)(`_@`!L#PHB@#^``*0!2B,`,"`@@`\``&#!:2!` +M`$HF`'!*)@!P2B8``3<.-TX +M\.!X!-PTW3;PX'@$W##=-/#@>`3<+-TR\.!X!-PHW3#PX'@$W"3=+O#@>`3< +M(-TL\.!X!-P`3<%-TF\.!X!-P0W23PX'@$W`S=(O#@ +M>`3<"-T?\.!X!-P$W1SPX'@$W!SP-!0:,#`4&3`L%!@P*!07,"04%C`@%!4P +M'!04,!@4$S`4%!(P$!01,`P4$#`"QP'&L"1-,[`D'S/@?N!X:B"``D4@@`$A +M(,`'*2```&H@@`)%((``(2#`!RD@``!J((`"12```2$@P`*@@``,`(`"` +M`2%!``(AOH#`((8!PB&&`$HG``!")?Z`SB#"`40E?H#.(<(!("#`!^!XX'C@ +M>.!X"B2`\`4@1`#@(,$'1"3^@$$JQ`"$``(`+R0"\4(A`0%"(`,!Z""B!`01 +M!`($$04"!!$&`@01!P($&P@!!!M(`00;B`$$&\@!+``E`$0B/H$\`"(`1"+\ +M@$`AP0#@(,$'0"/#`*@@@`$!$80"`1L*`2`@P`<$$00"!!$%`@0;"`'4!^'_ +M!!M(`40B_(`$$00"R0?O_P0;"`%"(4$`0B!#`*@@@`$!$80"`1L*`2`@P`<* +M)@#PBB"_#\H@9`#@?R\@`P#@?XH@_P_@?N!X\<#^#,__"'T0")R>`(]`&)SN`$]`*)R>`$ +M\@'8!_`#B8/@`MC*("P`!NCK_QD%[_^AP`.)$PC2`$`A#@+A@0[P".8,\!#7 +MQ&D*\`CFBW/)<&!_J7$#Y2*]M7ZAAH3M`(92Z&_MZ0USD$"&2'``V;X((`"S +M>@CF\O'@>!3C``"8X```'(0```HG@#\```"`2B```$HA``!*(@``2B,``$HD +M``!*)0``2B8``$HG``!*(``02B$`$$HB`!!*(P`02B0`$$HE`!!*)@`02B<` +M$$H@`"!*(0`@2B(`($HC`"!*)``@2B4`($HF`"!*)P`@2B``,$HA0#"K)@%R +M```!`&LF0'0```$`"B"`#P```(`*)(`_@`!L#PHB@#^``*0!2B,`,"`@@`\` +M`&#!X<4O>4`I`P(E>T`K`01E>24*-`((.!_P<7@>,]P``!:AL]Q@``` +M$/P9((`(<.'`*'#AP$APXG#!P%IPP<`Z<,'`&G#!P`AWP<`(=L'` +M"'7!P`ATP"8```=BQ`,__X'CQ +MP#(([_\H\$.-B\9ANLEPE@Q@`HAQ(XUAN3(((`#)/'`7@^O_^S:"'4H=@`5 +MPQ`%V`#9Z@B@`)AV`!7#$(#CRB!B`/__'`X<4("=#,BPP`$;71Z('HI;@0'"@T0$Q890@]``!_P"@]` +M`!OPH@Y``!GPT@Y``!7PK@U``!/PW@U```_P$@Y```WP5@Y```GP!=@"V>3: +MX@]@`$HD```!V*D&C__@>/'`*@ZO_^C:"'<:<0#>`!?#$`78R7&^#V``"B0` +M!``7PQ`!W0KK(PM0``78`MGGVJ(/8`"8=@OP$PB1(.(+8``!A\EP$?`+")`@ +MJ7`-\`&'!.@*#$`""/!V#$`"R7!V#B`"J7$`V"T&C__@>-=P````@`#9B/?7 +M<```___A(,X'RB!.`!$(A`^0``0`&0X%<+\`_/\5"(0/W`````T.!'#=`/S_ +M`-C@?A$(A`^`````]0X%\(``_P_@?P'8\$!RB(A`%T%C__QP.(,K_\!VJ/!"'5AN"G1 +M#WCP(0\`BW;)<,X)8`+I<0#$!=A!+(,0)+P`V8S:P;M:#F``4R3$$`,4A#`% +MV`#9C=I*#F```12#,`#`)+C#N$`G$!$-")$``Q2`,`D(E0`!V2+P@#.__J7,(<2X/[_^I<*$$K_^CP&`"@`#QP.'%"'4`V'H,X`&I<0\( +MW@,^#^__J7`%\`#9&@S@`:ERC02/_^!X\<#AQ0AS&=$9T`"A&=`!H14+40`% +MV`+92-J6#6``2B0``"'P`=T,\)^`!=@!V4[:J7-^#6``F'0!Y:]])PW3$!5M +M,"",C]T``$$+T+5X;NS0O,=TW````)^@!=@`V4W:Z/$E!(__X'A@`H```&3= +M``!@W0#@`8```=I"J"&H`-DCL.!_(K#@>/'`@@NO_P#9IL$(=8*0!MACE8W: +M$@U@`$(LA!"+=^EPT@_O_R&-`Y5W"-``.0B0!6\(T07$A0#9`(93($,'02B$ +M!P;8X@Q@`([:!(5"E03@9+K)<2*ZI@KO_S[;I.CI<`'9&_#$A0;8@(8`V5,D +M0Q=!+(07L@Q@`([:)(5"E03A9+K)<"*Z%@KO_S[;C.@8V`.UJ7`"V>X((``! +MV@3PD@G@`:EP20.O_Z;`X'CQP-8*C_^FP0AUBW-H<#H/[_\AC6AP`=F^""`` +M*'(DA0C8X($"M0"!`K@0T11X.&`$I0/80"$.`@.UJ7`"V9H((``!V@K0(8TJ +M#B`"\"!``/KH$F\4>!%F`8W&#B`"`=KA`J__IL#@>+CH```DZ0``\/'`_@FO_PAS*'0:9B32\")/`*EQ0@C/ +M_[8(S_]3),$0Q@C/_R.3Q;G6",__J7%N",__(I-"N2.H(8N"KB&N!]D@KB*3 +M`Z8$X22V)(.EMB2F0I,7"E(`"0HS#SS=3WT$X)(.(`*I#B`"!-B6#B`"`-B2#B`" +M`=C1P.!^`]$$TK4!(```V.!XH`6````&@`#QP`;1!M#R"B``!M+""B`"`-C1 +MP.!^X'C0!8``!`"0`(`&@`#QP`#8C[@`V2()X`$!V@#8C[@`V18)X`$"VH/8 +M";C."N`!`-D1V*X/X`$`V2(.(`(1V-'`X'[@>/'`@@BO_P78`-EQVBAS&@I@ +M`)AQ<@K@`0#8"'49"%X"!=@`V7/:`=O^"6``F'$F#.__`=@9#9X2!=@`V7/: +M`MOF"6``F'$.#.__`MA##1X4$@K``?X)X`$(=>()X`$(=ZH)X`$(=A4-4!`K +M#9`0(PT1$078`]D$\`78`=D"VNESF'9*)0``D@L@``HF0`%A`(__!=@"V?3Q +M\<`(T"`0``C:"^__P+B2"B`"`-@>#\__L@[/_]'`X'X`;-P`\<"Z"(__T<#@ +M?N!X\!^X'CQP)X/3_\(=2AV +M#-$`@0\-`1`+T$"H`=@'\`&!#PT!$`?06*@&V&8)``*I<#H+(`+)<=T'3__@ +M>"3I``"@!8``\<#AQ0H*(`((=070!-GP($`#L@_O_P/:O0=/_R3I``#QP#(/ +M3_\:<"AU.G)0T/`@#@3B"B`"R7`,V`#?Z7%4VLESO@A@`)AW8(T="]``70L0 +M`0S8(-D!VIAWN'>2"B``V'=$\,EP*G$$V@H+(`+I"3I``#QP.8-3_\(=RAU&G)Z"B`"`-D,V`#98-KIEP"G&""B`"R7(Z"B`"Z7`, +MV`#98MK)EP"G%:"B`"0-H%E2*5.&`0>@6U +M!(4X8"*-!*4$E0L)D`$L:#!X)+5">,#@`K7#]T#8`K4&V`*M0@Y@`:EP#-@` +MV67:*'/F#B``F'&A!4__X'CQP.'%#]44%0`8HK@4'2`0%!4`&*.X%!T@$`8* +M(`(!V!05`!BAN!0=(!#V"2`"`=@4%0`8H+@4'2`0>05/_^!X`'S<`/'`]@QO +M_P?8&M;L'B`0`=@9U10=(!#&"2`"R-@4%0`8@;@4'2`0M@D@`@'8%!4`&(*X +M%!T@$*8)(`(!V!05`!B#N!0=(!"6"2`",M@(V*D>.)`*T0K0`!A@`&\@0P$) +MT0@9.(!O($,#/!DX@/D$3_\`<-P``'S<`*8)`0``X-P``.C<`/'`7@Q/_PAU +M*'=(=CIS"B``(0HC0"$>"J__"B*`(7<.51%`)X!S,R".`]1X`'@#`P,6%@"I +M<`/9Z7(J<]8-(``*)``$J7`#V>ER*G,*)``$2B4```HF0`$;\*EP`]GIER*G,*)``$"B7`!`HF@`0R +M"````@D``"4$3__@>`?2C>@!V0CP`-@5(DP``!P@$`'AC"$$@+CWX'X`<-T` +M\<"R"V__^'"CP1EQ2'&(=!W7`(<=TJAU`-ZSZ-.YBW`""H__`ME2"H__4R=! +M`58*C_]3($$09@J/_T'#0L0+\!)N,"0`,!4BC`,`'"`0`>;/?O$.U)!!Q0@< +M@#$,T@#8"O`R:#`D03`5(@P``!Q@$`'@#WCO"-2``=@`'R`0H0-O_Z/`!'#= +M``APW0`4<-T`P@D``GX(``*N""`"$=BK)L%P```#`-(+3_\!\&LF0'$``0`` +MJR8(>````("K)DAX``#__ZLFB'@``!(!X'[@>,$'S_\`\.!X\<#AQ0#9X<$" +MR!GH*M``@`/H*'`%\"G0`(#]Z`'8#^A^"(__BW$*#:`!`-AF"``"@^@`P`;H +M=@B/_QT#;_^AP`?8`-G@V@#;-@P@`$HD```;T0"!`>``H6H/X`&*(`\*,@@` +M`@KH%]$`@>':`>``H0?8`-D`VQOP7@@``A+58(4'V`'C8*4`V=_:]@L@`$HD +M``#F",`!Y@Y/_QH(``)B"0``8(4'V`#9XMK6"R``2B0``,/Q%`"``!``@``< +M`(``#`"``!@`@`#@?P(:&##@>/'`#@IO_][:"'4H=@?8`-FI!_.&#@>&CC```)TS7:$KH4 +M&N```=P`&B`#`-L`&N``#!I@`!`:(``$&B`#X'Y-/"L:`=DUV!*X"!A@`.!^ +M`-DUV!*X!!A@`.!^-=D2N0P9(`#@?N!X`!`""$5Y`!A@`.!^`!`"""9Z`!B@ +M`.!^\<#Z"B``H<$2V&#``-@!'`(P!-@"'`(P%=@#'`(P`-@(<4#:$MOF"B`` +MF'``V`AQ0=H$V]8*(`!*)$`%`,$1T&P88``!V`H:'#`&V`L:'#`-T"`0``B^ +M"6`!P+@B"<__*@F``%(,@`':",`!`-@(<4+:"'.6"B``F'"AP-'`X'Z`#X`` +M`&S<`/'`;@H``!8(```F#(`!B@^``='`X'[@>/'`\@[``;X-S__1P.!^X'C@ +M?P'8\<"8<14)$`(*V`+9X]I*"B``!-L!V`[P`-H)\/`@@P`%T55Y`!G@``'B +M]0H2@@#8T<#@?L`"V`#QP)AQ%0D0`@K8`MGCVA(*(``%VP'8#O``V@GP\""# +M``7157D`&>```>+U"A*"`-C1P.!^X`+8`/'`F'$5"5``"M@"V>/:V@D@``;; +M`=@:\!O9$[F%$0,.0(B&(\,/97J%&;@`H!$"#F&(!"*"#___```"B&5Z"+A% +M>*`9.```V-'`X'[QP)AQ%0E0``K8`MGCVHX)(``'VP'8!_`@@`30$!A@``#8 +MT<#@?N!X``/8`/'`F'$5"5``"M@"V>/:8@D@`"AS`=@-\`?2`!(!"`"`1B'! +M`<*X)7@`&B```-C1P.!^X'@``M@`\<"8<14)4``*V`+9X]HJ"2```]L!V`?P +M((`$T`P88```V-'`X'[@>``#V`#QP.'%F'$9"9``"M@"V>/:`=WZ""``J7.I +M<`KP((`!@`,:6##!N`0:&#``V+4'#__QP`ASF'$`VA4)T``*V`+9X]K*""`` +M`-L!V$3PC@@``""+`8O%N<6X"+@%>0*+'M3%N!"X!7D#B\6X&+@E>"`<(!`D +M%``8)(L$((`/__\`P,6Y)7@EB\6Y"+DE>"0<(!`(%``8)HM&(,`'Q+DE>`@< +M(!`$%``8*(L$((`/__\```5Y"8L(N"5X!!P@$!@4`!@GBT8@P`?$N25X&!P@ +M$$APT<#@?@`"V``&T0`1``B?N``9(``$$0`(OK@$&2``X'X``M@`!0````#8 +M!!H8,(H@_P_@?P,:&##QP&(.#_\(=2AV!,A(<:/!30XD$(AT`\A%"$X#T[F+ +M<*X,;_^+<@+9^@Q/_U,E01'^#$__4R9!$`X-3_]!PT+$"=!MVQ&[`!L@``#8 +M!O`$$@$$`>``&V``]PC4@'4&+_^CP.!X`_^N[O'``=@`V=K:*'.2#^__F''& +M"D`!=@E``3H)X`$!V`/8S@OO_P#9T<#@?N!X`M#Y!V`!!-G__P``\<`2V-(, +MH`$`V0K0X@]@`039`=@"#*`!`MD(V+H,H`$!V0'8\@N@`0+9T<#@?N!X__\` +M`/'`X<4(=0'8V@N@`0+9"-B2#*`!`-FO>%(-8`$1V>D%#__@>/'`#@ZO_P'8 +MS@C@`0'87@N@`0'8`-@(<0/3N@V@`6C:T<#@?J"&`0#QP$(+H`$!V)((X`$! +MV`#8"'%HVI8-H`&*(P\*T<#@?@AS!=``V0@0A``!V+4&[__=VN!XE`*``.!^ +MX'CQP`/8]@KO_P'9`-@(<0737@V@`6C:E@VO_P'8T<#@?J"&`0``V`T'8`$$ +MV?'`$MB^"Z`!`-D`V/H.8`$$V='`X'[@>`#8806@`0AQ\<`4T/0<"+`3T`G9 +M0<`3T`K:0L!(%P1P`]A(%P=P`=M*)4`)`@@@`MAS`-@(<0[3\@R@`6C:`=@@ +MV:H*H`$!V@/8;@KO_P'9H\#1P.!^X'B@`H``_`*``&@"@`".!^X'A)`:__*'#@>/'`#WCR"V`!$]D`V*X,H`$(<='`X'[@>`/0"=GY`"`" +M`-K@>'0"@`#QP`'8`-G__F''1P.!^X'A0S`'@X']0&APP +MX'@0Z"L(4``_")$`6,Q7$@0W`>`0>U@:'#`#V`#9Q=H1\%?,`>#@?U<:'#!6 +MS%<2!#`S2%GH`D@'@`+(*Z1D)4``="9$``Y(!X.!_`[(!D@'@X'\!L@*2`>#@ +M?P*RX'[@>"``@`#QP`X+#_\(=BAU!@P@``'8"',0O@/8`=G.VI8,[_\%)D03 +M70,/_^!X\<`9"%$`4D&Z%G,`>!9&APP!O!:S`'@ +M6AH<,%H2!#<#V`#9P]HF#.__61(#-S_*%.@'[5/,`>!3&APP!?!4S`'@5!H< +M,%02!#<#V`#9Q-KZ"^__4Q(#-\D"#__QP!D(40!;S`#9`>`0>UL:'#`#V,+: +M#/`=")$`7,P`V0'@$'M<&APP`]C!VL(+[_]*)```T<#@?O'`I@^@`0S8G@^@ +M`1#8F@^@`0_8D@^@`0W8C@^@`1G8A@^@`1K8T<#@?N!X\<`/V,X(H`$`V1#8 +MQ@B@`0#9'-CF"Z`!`-D/'`#]BZ"*`!`-D0V+((H`$`V1S8S@N@`0#9'-C&"Z`!`=D;V+X+ +MH`$`V1O8M@N@`0'9#-BN"Z`!`-D-V*8+H`$`V='`X'[@>/'`6@D/_VH-H`$A +MT$H/+_\(=9AP%PT`$`38`MD'VN8*[_^INEQ]@R@`030A.C."J`!#-@Y`0__!`"P`$3F +M``#QP,((#_\(=1IQ2'9H=P/8`=G6VJES6@KO_PHD``0#V`'9U]K)`#TW``"T4P9(`#@?H#T +MW``#VPZ["PG!``G1%7D@D0T*P0`'TA5Z09+-N1"YS;HZ8@31%7D`&:``X'[@ +M>`@#@`!$]-P`"-*!X(#TW``*T`O1-!D@`);:.!F@`(H@!PT\&2``0!F@ +M``#84!D@``G85!D@`.!^'"4``(#TW`"=`"```-C@>/'`S@@@``AQ@>'0(&$! +MT""B`'/(&$!SR"B`8X(``#1P.!^X'@&TB`2`0B`X`'8P'@/(0$` +M(!I@`.!^X'B`]-P`!]%D$0$($PA1``0A@`__`P``,+@#\%,A0`+@?H#TW``& +MTA@2`0B!X,\AH0#0(:(`&!I@`.!^X'@`'-P`!=&@X""!SR%A`0307!A@`.!^ +MX'@DXP``@/3<``+08!``".!^@/3<``+18!D@`.!^@/3<``+03!``".!^@/3< +M``?1%7E`D@`:(``!X>D)U($.V0[P"=`U>$"0 +MS;H!D!"ZS;@:8@;0-7@`&*```>'G"=2%X'[@>`@#@`!$]-P`\V'X*H`$?V-'`X'[@>`8&`@#QP.'%"'7:#B`!!M@)"%X&`=DAI0D(G@8" +MV`&EG@P@`*EP-07/_N!X\<"R#._^!MBN#@`!"'$`;8S@P@`0+9P[@&V78,(`$"V@/8`MG+ +MV@#;"@ZO_YAS)P]>$@;8J@P@`0'9"';_W0B]I'@&V4X,(`$!V@'8R@@@``0F +M01,I#YX2!MB"#"`!`MD(=?_>"+[$>`;9)@P@`0+:`MBB""``!"6!$_&_M`^" +M`'D$S_[@>/'`X<5AB`AU(0M0`2$+D`$#V`;9`=I*)```"B4``7X/;_\*)@`! +M!O`!V`/P`M@!I.!^X'CQP.'%T@H@``'8T!`-",2]6@WO +M_ZEP`=@(<>()(`"I$-07`!B.#*``P[CAO1`( +M(@#*(((#.0//_N!X\<#AQ0AU'PA1`,X)(``!V`00``@=><"YP+@98?X(8``` +MV"<-D1"R"2```M@$$`T(+@Q``2\A!X`$\L"]N6$O>=H(8``!V/T"S_[@>/'` +MX<4H=1,(40"]><"YP+VY80+8%?`2#$`!+R$'@!#R4R4`$#A@#WE!+0`2P[@+ +M&A@P02W`$,2X"AH8,`/8D@A``+4"S_[@>/'`+@K/_AIP*'9(=170`(!H=^'` +M.@L@``IP(>@Z"2``"G`(+<'((#_\` +MP+ZX!!H@`('FRB"A`,HA`01`"B$!RB*A`3T"[_ZAP#SC``#QP,X)S_X(=RAV +M%]``@$AUX<#:"B``Z7`CZ-H((`#I<`AR(0]1$%,E`1&+<#8(+_^!Y@#``!H@ +M`!/T`=@(<0[PO7G#N8MP$@@O_X'F`,``&B``!_0!V`+9U@D@`0;:W0'O_J'` +M+.,``/'`8@G/_AIP*'9(=Q+0`(!H=>'`;@H@``IP&^AN""``"G`(#*(($/W0``1,H@@@_= +M``!8X'Z!X`'8PB`!``FXQW#=``!\X'[@>`AR`-@U`2`!!MG@>/'`X<4(=0?0 +M!MFZ""`!J7(%T`;9&@D@`:ER(0'/_N!X__\```__``"!X!'8RB!B`*T"(`$& +MV>!X\<#""$__+@OO_P#8G@A``,(*```#V`'9E]H`VPX*K_]*)```J@A/_]'` +MX'[QP)8(3_\""<__]@V``'H-``"&"$``\@KO_P'8G@B```/8`=F6V@#;U@FO +M_YAS=@A/_]'`X'[@>/'`X<6DB`#8#R!``XX)(`$&V0/8`-F9VJESK@FO_YAQ +M?0#/_@#9"PA1`.!_!-""X.$@P@?*($(``M#@?N@#@`!D`X``\<#:#X_^8@CO +M_Z/!`M@!V?H-(`$H<@'8Y@D@`0;9!\AZ">__"!(!-@/9*=`%VD#`*-!*)0`% +M0<`GT$+``-B<%P1P"'.8%P=P!@N@`4HF0``DU@/9)-=`QB300<!<'<`+8*'(`VYAU2B5``T'' +M"!P`-+H*H`%*)D``@@N``"H,@`"6"H``F@OO_P'8E@OO_P+8U@GO_P#8"@^` +M`/()S_\.#8__?0>O_J/`V`.``*0#@`"H`X``G.4``*P#@`"8`X``D`.``)0# +M@``TY0``Z`.``&0#@``+"%$`!=`(B`/P!=`(B('@`=C@?\!XX'@(!(``A`.` +M`/'`B@T@`0_81@\``-'`X'X#T`39L0.@`0#:X'BL`X``\<"F#H_^I(B6""`! +MJ7"&(/\+02@.`4X.(`&I<`AW`]@`V9K:R7,F"*__F'=^#N__J7"`YLHA80`$ +M\H#G`MG`>68+H`&I`]Y`]!5`Z`!`-K@>*P#@`#QP.'%"'4CR`T( +M40`+T`B('0B0``/8"-D!VJES2B0```HE``&Z"6__"B8``0#8%@QO_ZEQD0:/ +M_LP#@`#QP.'%I(BR#6`!J7#&#"`!$'@#V`#9F-JI"B```-C1 +MP.!^\<``V`8,(``(<0'8_@L@``#9`MCV"R```-D#V.X+(```V='`X'[@>/'` +MX<4X$H$P"'4/"1`!.1*,,$,,$1$!V(3AP'@;>#P:`C`YRH3@`=C`>!MX/1H" +M,`'8W@M@``AQ.,H-"!$!`M@X&@(P.`+:%'H` +MV0?P`-L`(D`P/!C"``'A]PF$@.!^\<#AQ3@2C#`(=0T,D1`\RA,(D0`Y$H,P +M$PN1`#W*#PB0``'8`=DHL]R@\(D0`!V`'9`-H6\(7I/LH/ +M")``A^H_R@L(D0`"V/3QA>P\R@\(4`"+ZSW*$PA1``'8`-DH7*(.$`[O,M!(_^X'@(__J7`( +M\`/8`MG3V@#;A@QO_YAS50./_B$&[_\`V.!X.,H`V8;H.$-P`-I`&((`#,B` +M(/^/#!H8,!3T#<@2Z$AS#/``(L`P0!"!``L)40(!V4`80@`!X^T+%($-&I@P +M`=D"T.!_(*`4!(``0W``V4`80@`,R`?H#!^ +MX'CQP.'%"'4,R(#@S`_!_P+80W5`'0(0#,@!V0'@#!H8,`+080*O_B"@%`2` +M``P2`38*Z4-P"=E`&$(`#<@!X`T:&#`(\$-P`=E`&$(``M`@H.!^X'@4!(`` +M\<"J":_^F'$(=4-P>@D@`$`0@```W@AW6M`:<,"@J7!2#F__B'&I<'X.;__I +M<6\/U1A`)P!T,R#*`Q0@@`(`>"D2%BTM+2TM+2TM+2TM+2T=*1HM+2TM+2TM +M+2TM+2TM(24I`/8.[_^I<"'PJ@[O_ZEP'?"B#N__J7!>#^__J7`5\"H/[_^I +M6E#141`,JO?8L(40"`Y#\``,@L@`0+8_@M``-'`X'[QP,8*0``F +M"B`!`MB`X*0/00!>#$``T<#@?N!X\<`3R`'@$QH8,&8.X``0V$((``""#T`` +MT<#@?BAS"'*`(L(&`]@`V24!;_^8<>!X\<"^#L``T@H@`0+8`=@7&A@P$L@! +MX!(:&##1P.!^X'@`V.!_%QH8,/'`-@]O_IO:X<$/?T$OP!!3(!4``-X`PP/8 +MR7%!+PT102]0$=((;_^8=IX(K_]3(!0@02C!`%(A`0#`N5-I4R4!$`2Y1B`` +M!J2Z17@E>%,@`2`%N:6XW@YO_R5X'@!V!X:&#!,(D"@4`I!`!7(&1J8-1@:6#4:&A@U'0A1 +M``'8"'$`VFX+K_](/'`9@U/_B75((4/?@#?2PE1`$<(W@`DOL.^VWD@ +MU@"&I]HE>`"F`]CI<>ESW@XO_YAW'-``@$"&$0A1`,X.;_](<$"&`=@#\`+8 +M4@NO_P'9X*7@IA_P@.'1)N&0%/0#V`#9IMHH$"K0`=DR($X$)[W`O0+8R7**"J__J7,!V`'9R7)^ +M"J__J7,'O<5]*!]@$QW(B^@!V(HA40\#VK8+;_\.ND+8`-D?\`;8`=D#VJ(+ +M;_\.N@'8`=GR\2@?(!0&V`/9#KF."V__`=H!V`/9#KF""V__BB)1#T#=J@T@ +M``+>J7#)<0#:M@IO_U)[!M@#V0ZY7@MO_RAR`=@#V0ZY4@MO_RARO0-/_N!X +M`/3<`#SF``#@?N!X\$?(.+_\"V/H+3_]3(@$@`KFB +MN%H*;_\E>..]`-[/)F(4RB#"(\H@@2\"````RB;!$^2]SR:B%,\@H20!RH+@ +MT26AD1#T`=CJ"N``"''J#B__`1K",U,B`""*#R__4R$!(,EP"G$]\(X.+_\! +MV`'*$PA1``'8N@K@``AQ`1K",_H)S_\["%$`=PU>$C_*I+H0<0'8P'@$N`5Z +M/,JENA!Q`=C`>`6X!7H]RJ.Z$'$!V,!X`[A%>&#`#?`*"<__$PB1`!S1BW`@ +MB`22XP+@>9@+P`-X*[A3($0X`$$X* +M(``+R`8*(``*R!0:F#,6"2``(,`#V`K6`-D`%H00`1I",[S:9@HO_R##(,`` +MKJH*(`"I<"4!;_ZAP#CC``"4`8``H<'AQ6'!"''`NH"(![I0),`1!2"-`*"I +M#0M0`$D+D```V$'P(<"&)`,0)KC`N`:XA7H%>D"I(<"DNB2XP+@$N`5Z0*D\ +MRJ6Z@.#*(&(`!;@%>D"I/D"I/LJFNH#@RB!B``:X!7I`J3_*I+J`X,H@8@`$ +MN$5X`*G!Q>!_H<#@>/'`^@\/_@AU%\@H=HKH)@A@`,EPJ7*`(L(+`]@!V07P +M`]@!V;O:R7-R"2__2B0``#D`3_[QP.'%"'4#V`#9K]JI"/C``#QP&8/#_X(=2'0`(@Z/1H1B$`!E,A#B`'OJ>XI[\%?P+80@_O_P4G@1,#V`#9L=H%)X,3 +MQ@@O_YAQBW`"V5H-;_X`'`(T(,&#N6#!+R%"!,.Y7@U/_@+8"@_O_R#!`]@` +MV;G:J7.6""__"B1`!$4'+_ZAP"CC``#QP.(.+_X(<@[0`(@&W?P<"K"+<*EQ +M"@U/_E,B`0$.#6_^M]H@Q@/8`-G),` +M`/'`X<4(=1#0`(@`V?P<"K`#V+C:*',J""__F'4'VHMP2'&Z#$_^(,&CN6#! +M4R7!$,(,3_Y(<'(.[_\@P=D&+_ZAP.!X,.,``/'`X<4(=0_0`(@`V?P<"K`# +MV+C:`=OB#^_^F'6+<`?9<@Q/_B#!@[E@P5,EP1!^#$_^!]@J#N__(,&5!B_^ +MH<`JXP``\<#AQ0`B`3!8$8T``1H",*EP(@\O_CS9`B4#$`'8"'%:#J``:-IE +M!@_^X'@!V`+9:-I)!J``BB.1"N!X\<#"#8__J@JO_P#8T<#@?O'``]@`V#^_^F'$!V%8.H``"V0'8"'$`VD(,;_\`VP+8`=D`VC8,;_\`V]'`X'[Q +MP.'%-@G@``+8"'6^".```MCDO&E@PX'\!&D(PX'CQP.'%`=WF#2__J7"R +M"0``@.#*(8$/```L`1#RS@TO_ZEP"'$@R!4)!0`1R`D(10`A&E@S@"$/"BD% +M+_XH<.!X\<`-T/0<"+`,T`/90<`,T`3:0L`L%P1P!]@L%P=P`-M*)8`#\@_@ +M`$HF0`"CP-'`X'[@>%0$@``8!(``(`2``&3F```H!(``\<"2"8__"N@AR(7H +M:@Y/_P3P`-@A&A@PA@TO_R#8T<#@?N!X`]``V34!(`$H"@$@`#QP`'8B@R@``#9^@U/_[8/S__1P.!^X'@#T`#9S0`@ +M`2ARX'AX!(``\<#AQ0_0]!P(L`_0`-U!P`[0!-I"P`78-!<$<`AQ-!<'<*ES +M2B7`!`H/X`!*)D``"=`B&E@SH*`%!"_^H\#@>*@$@`!H!(``<`2``-3F``!X +M!(``I`2``"$`(``#V.!X&0`@``+8X'@#T`'950`@`0#:X'AX!(``\<`(<070 +M`(`-"%$`!-`^""`!`-K1P.!^I`2``'@$@``$T`B(@N#,("*!`=C`>.!^F`2` +M`/'`#]#T'`BP#M`$V4'`#M`%VD+`-!<$<`;8-!<'<`#;2B5`!&(.X`!*)D`` +M`]A""J``#KBCP-'`X'[@>#@%@`#D!(``Z`2``&SG``#L!(``\<`=V*X)H``` +MV8()H``=V-'`X'X#T`/9K0?@``#:X'CL!(```]`"V9T'X```VN!X[`2``/'` +M]@R@``+8!M&!X"AP`]G*(:(`?@_@``#:T<#@?N!X[`2```/0!-EI!^```-K@ +M>.P$@`#QP%H*#_XCR-$(40`TT#76J8!8%@$8(!`0`,JY7!8`&&(++_[4N&06 +M#AA2"&_^"'=3)L$2!":.'___`/`LOA$-I1,D&A@P`B9`$P?P#B6`'P\`___8 +M8$HD`'@`VJ@@P`$O)\*3P"(%`!MX`"(`!#A@$@LO_FC9#@LO_AO1*'4H<"() +M(``!V:EP&@D@``#9J7!""2```=FI<#H)(```V1/2$]$`@C09(``!@C@9(``" +M@CP9(``#@D`9(``$@E`9(``%@@_:5!D@``#8`-G*""__)!(#-N()#__I`0_^ +MO`2````!U@`0)P``&`6``(#TW``#T`#9:0;@`"ARX'CL!(``"'(#T%D&X``! +MV>!X[`2``/'`X<4CR#[H']58%0$87!4`&,JY7@HO_M2X"',!V!O16!DX@&05 +M`!A3(,("0GL8T@0@@`___P#P:*(LN#H1`XX)H@0C@`__/P``,+@`HLV[.1$! +MCF&B4R%``@.B!"&`#P```#PJN`6B!"&`#_\#```PN`*B!"&!#P`\```ZN22B +M20$/_@`!U@``^-P`O`2```K2"PE1`$""`O!!@E!PUB*-#P``X@0">@70"PE1 +M`$"@`O!!H.!^X'B\!(``&`6``/'`A@@/_@AW*':J"2_^BB$/"A;0"PY1$**` +M!(`#\*.`!8`7#640.G`.(8`/``#H`QUE`=@#\")]`-@:<`(G0!!R"2_^BB$/ +M"B)P`G!F"2_^"MD'T`L.41"BH"2@`_"CH"6@B0`/_N!XO`2``!@%@`"!!V`` +M`MC@>/'`"]D`V!2Y$!D@``O0'!D@``O0'!D@``'8!!D@`"7(8;@8&2``!]`0 +M&2``[@T/_L(-#_[1P.!^"O\```#_`0`,`#8``M#@?P"(X'B``+```M'@?Q"I +MX'A``+``\/'`X<4(=?H/;_X!V)8*S_X$V$X,(`"I<0X(``"^ +M#\__L0?/_?'`Q@H```#8.@E@``39N@R@`!+8L@R@`!78T<#@?N!X\<#AQ2(+ +M[_X(=6*-*6N3X?H`#0!`)P!S,R!!`#1X`'A2=74;&RMU8&@7=75U=75U=75U +M"@'8`-F!VBAS>@CO_IAQC@H@``.5J7`(V2'PS@P@``#88O`!V`#9@MI:"._^ +MF'%"E0.%)(6J"Z``0KHZ#*```=A2\`"-AN`!V`#9#?2#VBAS,@CO_IAQJ7`' +MV88,;_X`VD+PA-HH@,##2,C&P38`*W#I22E`=@!&A@P`-ENVB3PA.P5UBC9 +M)+4&V2"M))7$I2*U`:V&#N__J7`:\`'8`-EOVBAS*@^O_IAQ]O$#V`"M`=@` +MV5O:&@^O_IAQ8HT!V`+9B]H*#Z_^2B0``,D%S_UH`(``0`"```#8)AH8,`/0 +M>0<@``39X'C__P``\<`R#>_]:=H:<"AW`-@Z<`"I`[$(V`*I%-@"L02Q*-`! +MW2C6`Z')<*&I"AE$!`2AJ7`J<0ISK@ZO_@HD0`0F&E@S$!Y$%!(>1!0J=2SP +M+R`'!#X-(`"O>5IP'PB>`Q38`J\#EX+HH[45#142 +M!]"H8-'H%"9,$P`<1!3W\=D$S_W`!H``$`>```0`@```V*4&(``$V?'`X<4` +MW0OP!]"H8`;HKWH`V,X,(``$V0'E\0T4DLT$S_W@>`0`@`#QP#(,[_T#VEIP +M,=2>8,07$W`@CD`C`"'P($$`I<%`(10")@F@`(MP0(Z!P")JT@HO_@#=(VJ+ +M<`X++_X5WB1J0"2`,"H*#_XN\(+`&G`R;31Y@G$Z0L4@#`5(XPC$+@%>2/``>48N`5Y)+G.N3?8$K@U>`"D4R:!$T`D0#+J +M"2_^"Q^"%"IP"G&J"*```]H!YL#F4?<+U)]F"X^`X,P@@H3W]0#`(KC"N(\- +M!)``V`NO[_'%`^_]I<`$`(``:`"``$@!@`#QP.'%'@^O_J;!B.@`V`;9(@^O +M_@#:&/`!V`#90#8C[AN"R``!-H!Y>T-%))] +M`\_]!`"``/'`^@KO_;AP*',TUC31(:8TT4`M@@+D:C/5(J:Y9S/4(Z:99R2F +M,M$_9PCBY:9=95QD,-=9806XO!<&<*BF+]7FIHFF*J8!W"W7!MG`<.>F@:TB +MK8'CRB`!`\HAH0!(VLHD(0`V\DHD``").]996"IT+\WV1*Y/V<5)L<0`!_``_5JP'?P)T^10"-'`-"_^6$5)L<1`!]` +M``7C`-G%"56!`"2/#X``0`"`KP'D0"1$``'A]?$!V`#93-K."X_^D0+/_6@` +M@```:-T``$C=```DW`"`)-P`0"3<``!TW0``0=T`!`"```!`G +M&A@PT<#@?@#8-0)@``AQ\<`&V)H+8```V0'8`-E/'`X<5F#:_^"'4#E8/@&_(&]CD(40`` +MV`'9$?`/"!`$*0B1!`#8`]D%\";(D.@`V`39Z@RO_@AR"O#B#*_^J7(&\`#8 +M`MG[\0/8`*V%`<_]#0?/_P#8!]G!!*_^"'+@>/'``=@`V5W:*'.2"J_^F'$' +MT@C1J@EO_@'8S@I@``;8!M@2"V```-G1P.!^0`:``+@%@`#QP`C2"-#6"F_^ +M"-&F"F``!=@%V.H*8```V='`X'[@>,`&@``$`*``Z`6``/'`X<4^#&```=@( +M=<8+8``!V.2]RB!B`,HA(@'*(@(`RB,"`,(D`@'*)0(!_`MB_LHF`@'BO!X`-@%V>T#K_X(0`9(`#@?O'`X<6AP0W1BW`>"N_]`]H`VP_P,B3- +M,`#8J7%"""```MH`V*EQ.@@@``':`>/I"]2`.0#O_:'`(.,```JXQW#<`(`D +M\"!`@.!^X'@*NL=RW```)#5Z`!H@`.!^"KG'<=P`0"15>0`9(`#@?H#@RB!A +M`@7R$H@`H0#8X'Z(=&"@8Z!BH%"H$1@"`0#9,J@SJ$HD`'@`V:@@``(O(H*` +MP"$%`YM\-7O@?V&@X'CQP$8/C_T(=1*(*':&Z(#BRB"A`BCR`>@)V`#91MHH +M<\8(K_Z8<>(,S_U0C2&%`H48(8$`"0D!``"%`_!5>`*E`-D)\`*%%29,$/`@ +M0``!X0"D$(WQ"02`$HUAN+8,[_T2K0#840>/_>'%D8ARB!,,P1"`XLH@X0(= +M\@,,P!"0B&&`0X`8(P,#"0N!`$"``_"5>D.@`-H(\&.`\"&,`%5[@*,!XG"( +M]0K$@#*(`>$RJ`#8X'_!Q>!X"KG'<=P`Q"0`&2``X'[@>`#9`]`(&&``X'[@ +M>``$W`#QP`#8E@@@``AQ`-B.""``!-D`V(8((``&V='`X'[@>`70"!``"`0@ +M@`\"````X'\QN.!X``3<``/0"!``".!_T+C@>``$W``%T`@0``@$((`/'``` +M`.!_,KC@>``$W``*N#`@@(_<`,`DX'X*N#`@@(_<``P$X'X*N<=QW``4!``9 +M(`#@?N!X"KG'<=P`P"0`&2``X'[@>`JYQW'<`!`$`!D@`.!^X'A2:`3457J8 +M8GD&[_\`VN!X3`6``%)H57H"U"D&[_^88DP%@``(<@*X!]$&N@?4%7@X8)MB +M`-D"VDHD``(5!N__2B4`!$P%@`!@!8``\@[O_P#:P06/_>!X3`6``.'$X<#AP>'"X/'`!@T/ +M_@#8"@TO_H^XT<#@?N!XX<3AP.'!X<+AP_P<"+'\'$BQ_!R(L?P,*XU@WO +M_\EQ"B0`@`WR88T)V'U[&MD"VL*[2B4``,(.+_Y*)@``F0.O_:7`%.,``"SH +M``#AQ.'`X<'APN'#_!P(L?P<2+'\'(BQ_!S(L?P<"++\'$BR_!R(LOP0#:%7D`&:```>`/>/;QX'[@>``"W@`#T@#9 +M%7H`&F``X'XH`-X`!>@1"%``'0B1``?2"-D%\`72`-F+N0`2``@F>``:(`#@ +M?N!XP`'>``G38(/`NN'#"--@P0#!&;JXN;FYF+DE>A5[`!N@`.!_H<#@>!SC +M```H`-X`;]P1O`P4`AA&(L,`&WHX>F1Z#!R@$`CH$PA0`!\(D0`'T`/P!]`( +MV03P`-F+N070`!`"""5Z`!B@`.!^Q`'>`,`!W@`!V378$K@`&&```MIOV!&X +M"!B@`.!X!!A@`.!^`]EOV!&X"!A@`.!^\`/'`X<4H=3X/+_X->""(`=Q3(8(`!=!6>+5X +M([F*#R_^`"Q!$&T!C_T``MX`\<#AQ2AU$@\O_@UX((@!W%,A@@`%T%9XM7@C +MN5(/+_X`+$$000&/_0`"W@``V`315!D@`!#83!D@`.!^@`#>`-.X;]D1N1P9 +M(`#@?A#H.0A0`$T(D0`$VA+10!F@``K81!D@`$@9H`#%!\__`=D-T``88``, +M&&``!MD$&&``"!A@`.!^`=@'T2`9(``L&2``!M@D&2``*!D@`.!^X'[@>(`` +MW@"!X$#8SR#A`\H@@@\``$B$,""`C]P```"&(/X/X'\FN(D"[_\`V.!X[@VO +M_:+!(->+=@3P.@T/_@#83@KO_\EQ"B``H!_T(,`!%(,P\"<-$!8EP!`!@(#@ +MRB!A`LHAX0;*(F$`RB0A`,HE(0!L"R'^RB8A``$4@#`6?2&%8'G)!X+.@``/'` +MF@]/_0AVL@@@`"AUR7"I<=(((```VLEPM@@@`*EQR7"I<78((```VLEPJ7%6 +M""```=K5!T_]\<#AQ0AU*',1N,=PT`!0``:Y&6$`$0`(H[@`&2``J7!H<2H( +M(```V@H@0(,`V(!V,!X`!D@`.!^$;C'<-``4``&N1MA`!,!"`*Z"-A8>"5X`!L@`.!^ +MX'@1N,=PT`!(``:Y&6$`&:``X'[@>!&XQW#0`$``!KD"VAEA`!F@`.!^$;C' +M<-``5``&N55Y.&``&.``X'[QP.'%`-VI<&(((`"I<0`88`,!VP+P`>,="]4` +M`-K["I.`;7A&""``2'$`&&`#`>)/>O?QZ09/_030$!``"(8@?P_@?QUXX'B` +M`-8``]`0$``(X'_`N.!X@`#6`&O8$;@<$``(X'[@>`?H$PA0`!,(D`#@?P#8 +MX'\#T`30`O`$T#5XX'Y``=8`1`'6`$P!U@#QP#X,#_X`B`;24R"#`".X`-D/ +M(0$`=7H`&F``T<#@?@`!U@#QP.'%%@PO_BAU"'(`B,*XI@_O_ZEQ((H!W".Y +M8@PO_@`L01!%!D_]\<#AQ>X++_XH=0AR`(C"N'X/[_^I<2"*`=PCN2X,+_X` +M+$$0'09/_?'`"',2T/`@P(`$((`/!P```#"X\0A5@4`G`7,S(0``%'D`>0,. +M\!#P``O87MD!VDHD```*)0`!^@@O_@HF``$`V`/P`=C1P.!^X'A``-8`\<#A +MQ:X,[_\(=1S0`-FU>$"`#!I@`$"`!=D`&F``0(`7T1@:8``@@/_8"+@8&2`` +M%-&I<"J18@D@``#:!.T7#5`0$/`0T4`1``A%(,``0!D@``W10!$`"(4@'`!` +M&2``7@@@`*EP"]@`V57:!-N&#B_^F'%5!4_]).D```K_``"XZ`````'6`/'` +MX<6!X`AUK`[A_\H@X0&"Y:0.X?_*(&$#*05/_>!X!-'P(0$``-@,&2``X'[@ +M>"3I```(Z!T(40`'T?`A`0`&T`;P!-'P(0$`!=`,&2``X'[@>"3I```,`S8! +M#`,``1P0``@$((`/````_^!_*+@4N#`@@(^0`!0`X'X8$`$*!"&!#P#___\` +M&&``X'[@>/'`.@QO_5':"'4H=@O8`-FI<\H-+_Z8<1@5`!I`+@P4!""`#P#_ +M__\`'2`0!7P`'2`3"]@`V5+:R7.B#2_^F'1I!$_]'!``".!_#WCQP.H+3_T` +MW0?P?!".`'QE/&3`K`'E]PV$D&"!"]A`(T0``-EJ#2_^4]HM!$_]X'CQP+H+ +M3_T(=2AW2':!XLH@@0\``-`'C`@!`/X.[_^I<`G0\"!``Q08X`,"#^__J7"! +MYLH@@0\``-`':`@!`.D#3_W@>"3I```8$`$*U[D`&&``X'Z8`#03PX'@!XOT)A8#@?N!X +M\<#^"D_]"'<:<0HF@)`*V,HAH0#*(H$/``!F`,HCP0/*)`$$&?(`$`0@"M@` +MW:EQ9]IV#"_^J7,%\/`@0",!Y0"A^PVDDQ4G01-I;?P1!(`*V`#9:-I2#`_^ +M#0-/_>!X\<``VP?P`-BZ""``:'$!XVU[]PO2@-'`X'[@>`?9%;GP(0"`X'[@ +M>`+1\"$`@.!^``+@`/'`F@@/_B"(`=Q3(8(`!]@5N%5X([G>""_^`"Q!$-'` +MX'[@>/'``-H#\`'B37H3"M,`Q@_O_TAP>>@!V`+P`-C1P.!^\<``VPGP!]#P +M(,``/@@@`&AQ`>-M>_,+TH#1P.!^X'@`!X``\<``V@GP?@_O_TAP!=%5>0'B +M37H`H?,*TH#1P.!^X'@`!X``!]H5NC5Z`!H@`.!^\<`,T`H(+_X+T0#8`=D+ +MTS(*[_]HVB#8U@CO_P#93@_O_R#81@_O_Q;8T<#@?N!X@%A/`("ZC`'P20(` +M\<``V`AQ1]H(__:-K1P.!^@+J,`?!)`@#QP.'%"M4)Z.(/K_\@V`"%`>`` +MI0?P`-@`I0;2!M%X&:``!M$`&2``>0%/_0P'@`#(A```@`^```!PW0#QP.H( +M3_T(=RAV+WT6"*_^J7""""``J7`0?:EPN@^O_P'9J7"R#Z__`-GI<"X((`#) +M<24!3_W@>/'`X<4O?:EP>@UO_@#9Z@]O_JEP)@@@`*EP%0%/_>!X*'(#T(T% +M(```V>!XK`.``"]X405O_@'9\<`B""``X<40?:EPA@^O_P'9J7!^#Z__`-G= +M`$_]X'B!X`'8PB`!`.!_'N#5`$_^\<#^#@__S@A/_M'`X'[@>/'`$]`HB!/0 +M@.$(B,P@(8#*(:$`!_*!X!X\<#*#P_]"'8H=2H/;_X`V,EP.@@@`*EQ(0!/ +M_?'`(\@+"%$`-@X/_P7P`-B2#>_]"''1P.!^X'@)!T_^]09O_@'8X'C@?N!X +M!-`(B`'9@>#`>6T%[_T`V,P#@`#QP"/(@>"T#`'_T<#@?N!X\<`!V)H/+_X1 +M$@$V&@AO_@'8T<#@?N!XT0"T#`'_T<#@?A$`(```V.!X"0`@``'8X'@#T8'@`=C`>.!_`*&D!(``P0(/ +M__'`X<4!W:H(K_ZI<)(.;_XB&E@S70/'`X<4H=1W8 +MM@VO_P#9;@BO_JEP.0/'`3@RO_P+8$-@^#:__`-G1P.!^\<`Z +M#@_]"B8`D"AU.G(:<\H@H0+*(2$#RB(A`,HC@0#*)($`RB6!`+`)X?W*)H$` +M0"8/&"F/-0UB$(HBPR\*CRD)`B`,(8"D_MS,(0*C#O((%X00"M@4V03:8(X* +M)4`$>@GO_4HF```K"8$D`X:.Z`@7A!`*V!79!-I@C@HE0`1:">_]2B8```.& +MN&``&`($)_",(8.O%?0$AH[H"!>$$`K8%MD$VF"."B5`!"X)[_U*)@``!(:X +M8``8`@01\"J/2B0`>`#8J"```B\E0I/`($4`.WDBAB)P&6$`&0($O04/_>!X +MX<#AP8H@_P\3(,`"!'D`*(`"`"F!`@8D#!`E?,'!X'_!P.!XX<3APO'``1"" +M```0C`!`*@("S@_O_T5\`!@"`T$L#!(!&`(#T<#!PN!_P<3AQ.'"\<`#$((` +M`A",`$`J`@9`+`P4!22?$`$0@@``$(P`0"H"`@4DC!`%),P7A@_/_P`8`@-! +M+`P2`1@"`T$L#!("&`(#02P,$@,8`@/1P,'"X'_!Q.!XX<3QP%8/[_^`@("@ +M!!0?-.!_P<3AQ/'`0@_O_X"(@*@$%!\TX'_!Q/'`=@P/_1IP*'9:6E!!O" +M(P4;PB,$'0`5"QM")0[P(X4%Z?_8^6$`J22%!.G_V/EA`*D!Y^]_"1.`("$/ +M`Q``W@H3@"#=#@.0J7#I<;0?O7Q`-X,\!8D@B,@BJEP09(R +M#>__R7,!YL]^[0Y"E0\.$"`'T:EPI@H@``#:"M@`V8#:"G/V#._]F'%]`P_] +MV-T``/'`1@LO_7S:"'8H=0`1A``*V`#9T@SO_6"."M@"%001`-E]VL(,[_UA +MC0K8'!8$$`#9?MJR#._]*'-]`P_]X'CQP.H*#_VBP0HF`)`Z<4AU2B``(,H@ +MH0+*(2$#RB(!!,HC`03*)`$$RB4!!&@.H?W*)@$$0"8/&`J/#PDC(`@6!A`; +M#A$`"!>$$`K88(X0V03:1@ZO_0HE0`00EB`>1!01M@2/IZ8;Z&"."M@`V7_: +M-@SO_0HD0`0%CP[H"!>$$`K8$=D$VF"."B5`!`H.K_U*)@```=@%K]3P`=@$ +MKXHBPR\@%A,1!1\"%!P6$1"`YLH@H0+*(2$#RB(A`,HC@0#*)($`RB6!`,P- +MH?W*)H$`"!>$$$HD`'@JCXAT`-BH(``"+R%"@,`@!0.;?"*&8G`R(10`"X\? +M#`(@&PR`)`K8%]D$VF"."B4`!8X-K_U*)@```-T+#(`DH886)0T5188(CQ/J +M8,`"',0T!.T!C0/P_]@!'`(P!.T!A0/P`-A!P(MQ8'K)<`@7A!`;#($$"M@2 +MV03:8(X*)<`$/@VO_4HF```(%X00C.T*V!/9!-I@C@HEP`0B#:_]2B8```@7 +ME1`AC4HD0"`,)4"@PB0!)4T)0`4)CQT-`B`*V!C9!-I@C@HD0`4*)4`%[@RO +M_4HF```$A@;H,B!!!0D)@00`V@7P`88V>$&`@.+*(,($XR""`,HA0@3_V`BO +M086`XLH@P@3C(((`RB%"!$\,$"`!%800"8\('P(1`164$!L,`B`*V!G9!-I@ +MC@HE``6.#*_]2B8```.&!>@R(`$%"PF!!`#:!/`!AC9X08"`XLH@P@3C(((` +MRB%"!`6/@.`U]00?`A3]`"_]HL#@>/'`N@@/_0HE`)`H=TAVRB"A`LHA(0/* +M(B$`RB.!`,HD@0#*)8$`*`RA_0``0````$`````!````!(0% +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````-5WT;Q* +M[8W)8R5H$YN``GD<`1;"8;0$8!Y-.YH0T;][>LB"9*C;&Y\98J;F:.X?NLQ: +MZ%K9SB&G8]O!A-G')N_JA`DE$XIDFJGQ`IC; +M6A%4&T_WD&AZ>U8+%V_;PR\UO2<6[]->@(,6;P_.L>M+$WH)Z>$(1^K +M,W,G\FV*.V%P +MC\CVG<.Z((J3<>Z-,C26LH(P4T4?H6M4?-$!``$`!HX`1%9_8S/-C4AH<"M]6F +MW3/MD*HN+X)5DK89\-(MJ>2TXL0T=)QH+O9I&BS;@EBONN?DKBG01F?!1M!( +M^DYCYPB5O%U)K,O_JO>KVJ`LU.ZN0HREN"8!,?$<8/QN&S.)5JM4_+5XGRJ; +MDMO:`6(I%19U)%N-!G)BAP,````'````"(``````B,``@```!P````@``0`` +M``C````!``<```#D8P```(!%@-QC```4````!(``````B,`````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````0$0C`S'P(P!!]",!`?0C` +M)'P(P-27",#8EPC`U)<(P*^^K=X````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````$`0````````` +M`````````````````````````'0`B,`$````!P<'!P<'!P<'!P<'!P<'!P<' +M!P<'!P<'!P<'!P<'!P<'!P<'!P```````````````0````````"0%`C`D!0( +MP*`B","0%`C`D!0(P)PD","0%`C`D!0(P)`4","0%`C`D!0(P)`4",!T+@C` +M."X(P*0M","0%`C`^#,(P)`4","\(@C`R"`(P)`4","0%`C`D!0(P)`4","0 +M%`C`D!0(P)`4","0%`C`D!0(P)`4","0%`C`D!0(P%0D",!D)`C``````-0D +M",#D)`C`S"0(P/PD",#L)`C`7"8(P'PF",#$)`C`>"8(P'`F",`````````` +M``````````````````````"T(8C``&"(P+0EB,`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````!````E!*(P)02B,`8(J``$"*@`&P@H```,``` +M_X___P`````````````````````9````S!*(P+00B,`````````````````` +M```````````````````````````````````````````````````````````` +M``!_"````````#\`$!HB*3``+0`Y.3DY.3DY.3DY.3D(``0`!``$``0`!``$ +M``0`!```````/#@T,"PH)"`<&!00#`@$```$"`P.``($!@@*#'1H[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWA0` +M```$``$````(P"`@@`\(P%``(""`#PC`\'8@((`/",`X3VD@``!I($``:2`` +M`&D@0``@((`/",`(#R`@@`\(P+P.(""`#PC`P)T@((`/","@?2`@@`\(P,"= +M:2````H@@`^(P)@1`!`!`!4)$`!*(8```!A``"`@@`\(P!`02B%````80`!* +M(```2B$``$HB``!*(P``2B0``$HE``!*)@``2B<``$H@`!!*(0`02B(`$$HC +M`!!*)``02B4`$$HF`!!*)P`02B``($HA`"!*(@`@2B,`($HD`"!*)0`@2B8` +M($HG`"!*(``P2B$`,"`@@`\(P"@![[ZMWN^^K=[OOJW>[[ZMWN^^K=X@((`/ +M",`,=B`@@`\(P$@/(""`#PC`<`\@((`/","XER`@@`\(P'B""B2`/XC`_']! +M+)PP0"R<,$(D'#0*(H`_B,!H(`HC`#?B#(`#2B8`<&D@0`#OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>!!H8-PH@@`\(P```:R!`"2$@ +MP`=*)@!P:2```DHF`'`%$@`V0B!`@`4:&#"0``$`!!0`,&L@@``(%`$P:R'` +M``P4`C`*)(!P$!0?,!04'3!4%`PP6!0+,%P4"C!@%`DP9!0(,&@4!S!L%`8P +M!S`,$(@/H!\'(`PA``A`$`@0``%&A@P5!P`,U@`)`(X:2```$HF`'"`'$`PA!P`,`42`#9X',`P0B`^@'P<@#"(`"$` +M0"!```4:&#!4'``S6!S`,EP<@#)@'$`R9!P`,F@!M``7P;0`&`&T`!A!M` +M`8@;0`&,&T`!D!M``90;0`%*)H`!F!N``9P;0`&@&T`!I!M``:@;0`$A(,`' +M"!C``&HB@`*")`$R2B,````.!^X'@$W#C=./#@>`3< +M--TV\.!X!-PPW33PX'@$W"S=,O#@>`3<*-TP\.!X!-PDW2[PX'@$W"#=+/#@ +M>`3<'-TJ\.!X!-P8W2CPX'@$W!3=)O#@>`3<$-TD\.!X!-P,W2+PX'@$W`C= +M'_#@>`3/P'# +MX<+AP>'`!\`<',`QX<#@?P'`"B8`\(H@OP_*(&0`X'\O(`,`X'^*(/\/'0`@ +M`$H@`!!!*!\3B(#B!8`#```*``01!`0$&Q`!#0I>``(1!`4" +M&Q0!#0H>``$1A`0!&Q(!("#`!PHD@'!"(4$`0B!#`*@@@`$!$80"`1L*`2`@ +MP`>")`(X`!P`,`0<0#`('(`PBB`$``HA@`^@P!PX`!D@`$H@```*(8`/H,!4 +M'@`9(``*((`/`P!`#0HA@`^@P.`@`!D@`"`@@`\(P'0+@B0".``<`#`$'$`P +M2B````HA@`^@P%0>`!D@`!``!`!"$\A`0`` +M&&``:2"``6\A/P!*)@!P2B8`<$HF`'!*)@!P2B$```H@@`^@P%0>`!A@``H@ +M@`^(P'PV`!`?``00&P`($!D`#!`8`!`0%P`4$!8`&!`5`!P0%``@$!,`)!`2 +M`"@0$0`L$!``,!`/`#00#@`X$`T`2!`:`$P0'``@(,`'`-D@((`/",`L+^!X +M*'(!V2`@@`\(P"PO*'1( +M`@`&A4`@#@<@AC!U"/0"V2(@@`\(P%26`*8&A4`@#@@@AC!U"/0(V2(@@`\( +MP%26`*8@((`/",#T#/'`SW"(P-00#(CCN`GRSW"H_B@``-DB((`/",!P62(@ +M@`\(P*A\T<#@?N!X\<#AQ0#=$O#/<(C`[!%@@'!RRB%-`\H@C0\0`$4"XB"- +M#PC`F!`!Y8#E&?0`VDAQA.%L]Q1MSW-%@!SB-7@#8XPCPX_B\\]P18`,XG9X +M`8`LN%A@06@!X>SQ(""`#PC`_`S@>`#:0+`BVD.P)MIZ&(0`*MK`&)P`/MC@ +M?Q*QX'CQP"(@@`\(P(`,Q)#/=8C`U!`#;D8@SP`$C>.X@B0(,`GRSW"H_O`+ +M`-DB((`/",!P68PF")#*((T/$``'#^(@C0\(P'`0BW9!+X$0R7`B((`/",!D +MFP'"@.(.\@2-X[@;\L]PJ/X`#`'9(B"`#PC`<%D3\`+`@N#*(((/$``(#^(@ +M@@\(P'`0(X8`@2&!(B"`#PC`6':`)`@P(""`#PC`[`S@>`/9X'\CH.!X`MDC +MH`78`-DHAIR26`,)"N0+`8[E:<(+BRB)"(POT3"(`H43W`=A" +MP`7P0L5:=:EP@.`#\J#@S_>`X.@@(@+/<*#```4($``(!-@`IXOP +MA,`B((`/",!DFP'!`L)3(5,'"6K/+,(N*!!/0! +MVD:I0XB`X@/R!(@%\$>(@.($\@B(!ZD!V.!^\<`B((`/","$#$AV08I0<0#= +MU_=AB`(AC`!=8[%QRB7&$,HE!1/:8@+B(FA(<*ER(B"`#PC`*'X!CKA@`:ZI +M<"`@@`\(P/0,SW`0``0"(""`#PC`#01@@!<80'B`*Q/>N!_-!F"`.!X +M\<`B((`/","`#`AWSW8``/__SW!&@.PZH(`#\`'ESW!%@"#E0"`!`@&`$'5- +M]UHE`!L&VCA@Z7$B((`/","\=H#@[O4"\,EUJ7`@((`/",#L#.!XSW!&@.PZ +M`(`(<@SP6B(!"RQC6B`!"REC,'3*((D``>+/<46`(.5`(<,#(8$P/'`(B"`#PC`@`RKP0AW!XDH=08<`C`B((`/","XG@AQSW!&@"`&(B"`#PC` +MH*2`X#[R`H4B((`/",`(=`<<`C`"A8/&`8`@V4+`R7`B((`/",!`?D&/@.+' +M]B)OR7`B((`/",`H?HMPJ7$&VB(@@`\(P"A^BW6I<"(@@`\(P*1?(B"`#PC` +M:&.`X,H@0@/B(((/","\92(@@`\(P-!F@.#*($(#XB""#PC`'&FKP"`@@`\( +MP.P,X'CQP"(@@`\(P'`,+WA:(`T'"B.`+T:`%`0`V\]W1H"4!3IP8G5@I7*G +M`HIAN([@B``-`#,F`'"(P!@30">,+<#MPSW&(P`04C-HB((`/",`@#E8D#30*(0`G"B4`)T`E`!//<8C`H!4U +MVB(@@`\(P"`.SW"(P,@<((!*)``@`8#$'$`PR!P`,`0<`#4`'``U"!P`-0'8 +M&G!#P!`<`#5.P'P<`#5X'``U@!P`-<]P1H"4!0`GDA]&@!0$$!(!('IPAN'2 +M`"T`3!@`!3,F07"(P!`30">`81Z17D`)0P@(*P!X`]X3!P` +M-,]PB,#,-BMQR7(B((`/","HCX#@RB`"!3ST"G#)=``?`""`)(8>`!P"%$03 +M`2"`X12.W!X<%0CT$!(!((#AQ2#B`03TAB#\`12N%8Z`X!`>`!76]Q8F`!4< +MB"(@@`\(P+B>`=H(<54E0!0B((`/","4I16.0"14())P+O<($@(@"W!5)4$4 +M(B"`#PC`S&$!V(`D`S4@((`/","<#/'`(B"`#PC`=`P:<8#@4``N``#9.G$5 +M($$@6G"@B<]W1H#T!<]V1H#4!0=O0"9!&:ER(B"`#PC`D&^`X`GT!V]`)D$9 +MJ7(B((`/",``@T(B0""`X$`A02"\!\W_(B"`#PC`$!H@((`/",#4#/'`X<7/ +M=4:`U`7/<4:`^07/<$:`^P40VB(@@`\(P""%`-G/<$:`E`4QH#"@-:!*)(!Q +M*'*H((`!6&4YJ#^H`>(@((`/",#\#/'`(B"`#PC`?`RJP8MP&G#/<8C`3!TH +MVB(@@`\(P"`.._`!V32G:'1)Q,]T","X%D#$SW0(P/050L0`WD'&`]Q$Q,]T +M1H#4!;B,3R)$!@'EKWVXK!"]0\8%)0P11<1:(@T'1L9'P3*G>;A]92"E:'&` +M(4<)(B"`#PC`K(3/<(C`S#8*<2(@@`]%@)BK@.`$\L"ETJ?4I\]P1H`4!N80 +M@H",(L./#?+/=T:`E`4TA\]S1H`4!(#A!?0RAX#AL_.JP"`@@`\(P.0,\<`B +M((`/",!@#((D`S$(=0HG0*`*((`O1H`4!$`@$B9`(!4E0"`1(D`@$R-`(!0D +M8/0#A8#@C``N`$HF`"!0W!HF`"-`)0X7'F8,C@#?6B`!!P&&@G$`H0R.6B`! +M!P"&8G$`H0R.6B`!!P*&(G$`H0R.6B``!Z)PX*`,CEH@``="<."@#8Z`X-;W +M%2;`$Q*((B"`#PC`N)X(<0R.`=I:(``'`>>B<"(@@`\(P)2E#8X0=ZWW`X5` +M)E8@TG""!\W_`87/=D:`U`5U&!@@0"6!%4`F0!8&VB(@@`\(P"A^0"4!%$`F +MP!<&VB(@@`\(P"A^`MAP&!@@`-[)=RWP6B<`%PIQ`"$1``#8P!P`,%8D`3;I +M<"(@@`]%@'BO@.`%],`4`#"`X`GTSW`0`&T0Z7$B((`/",!\$`P1`""`X`KR +M6B8`$X-PX*`,$0$@`>8AH.*@`>>0YZ@'Q?^+<SW5&@!0$"B*`+T:`U`6I<8`A1PG/<$:`^P40 +MVB(@@`\(P""%Z7(:\%HB`P>Y8P.!@.`3\A4DP#-`H`"!@.#*)H(03"``H`'G +M"?0`V+MC!*,"HP.C!:,&HP'BD.*G]PHA@"]&@)0%0!$`((+@$?2+<>EP(B"` +M#T6`Q*^`X,H@@@\0`'80XB""#PC`2(@@`]%@)RJ@^#*(($/$`!Y$.(@@0\(P'`03"`` +MH`;R`=E`&4`@#?``V4`90"`B((`/","$8B(@@`\(P,@9L,`@((`/",#4#.'% +M8X"0XP3W@.,$]`/8/_`B@.3A//>`XW``+@``W9]SX'BH(``-4-P:)0(30"`! +M!UEA38F0XBSV@.(%]$&!@.+F\X#E#/(:)8P?``!0`$(@`@J,8DR)4'2T!\G_ +M@.4-\AHEC!\``%``0B`"#81B0(%0=)P'S?]!@8;BE`?-_R*!@N&,!\W_`>4` +MV,'%X'[@>/'`(B"`#PC`7`RBP0AU.G$;>IP(B"`#PC`A"*`X)+S +M`<"3X+EFC/,/>/0E`"!B<`IR(B"`#PC`*'Z$\0'8HL`@((`/","D#/'`(B"` +M#PC`?`P:<"AW2'44V`"B"G#/<8C`]!,#WLER(B"`#PC`('Z`X`#8?_(*<,]Q +MB,#$'\ER(B"`#PC`('Z`X!;T8;^$Y^0`#0`S)L]SB,#`$T`G`'+T>`!X`=AG +M\`+89?#`I63P!-AA\`IPSW&(P,`?R7(B((`/",`@?H#@%?1IOXKGJ``-`#,F +MSW.(P,@30">``(:(XP/``!0`$`@00J)83!RN/"`^!&(,``C"`0@,OW"-L(\(+C!_0`@H#@`_(& +MVV:B@N/*]R."SW`0```#1((B((`/","8$-'`X'[QP"(@@`\(P'0,&G!:<3IR +M4R"-`P3E(KW/=T6`!/1`)PX4`8>*(Q``((=X8")XR;@">W!URB)-`\HAC03* +M((T/$``A`>(@C0\(P)@0C"4$D$@`)@``V"&'%29,$`%IR;@5)@`0`!P`%``8 +M@`0"VPKP0B$"(A4F`!#P(L(``>-`H'AA<'7)N#;W`:<"A[A@`J<#AP'@`Z'&SW%%@`3T`(%`(0,$ +M\",-`,]TJ/Y$"U,E@!,BN$%HSW"@P```$!@@`Q`88`//=*#``!"P''B3`($# +M\($,]P1H`L!@F0X'[@>.!_`-A]:55K\"#``$)Y`-H/(D(`1'@0 +M<@'8X'_`>.!XSW*@P``X%!(!"`02``@D>!0:(``@((`/",!T@/'`(B"`#PC` +MQ&_/<*#``#@8&*`/$````-'`X'[QP.'%!""-#P```'](O0AQD.7*((8/$``. +M`^(@A@\(P'P0L'@@((`/",#\#`#8SW%%@*C'BB(4`"`@@`\(P`17\<#AQ<]U +M18"HVR&%@.'*(((/$``-#^(@@@\(P'P0`-@B((`/",``6`"%!.``I2`@@`\( +MP/P,X'CQP"(@@`\(P(`,"B8`D,]U18"HVQ+RR7?/<:#```YH$0$(`-@B((`/ +M",!D6`"%8;\$X(#G`*4R]P&%PG@!I2`@@`\(P.P,X'CQP"(@@`\(P'@,.G`* +M($"@SW=%@*C;`-T0\@IV\"%!(P#8(B"`#PC`9%@`AP'E!.!AOH#F`*/'`X<7/=:#``#A8%0`8X;@(\B(@@`\( +MP/B2`MA8'2`0(""`#PC`_`P("`@@`\(P!A+SW`0`/L.(""`#PC` +M"`@@`\(P%QNSW`0`/X.(""`#PC`*'!\<#AQ:+!SW"(P$`5`(!$ +MP4#``-U!Q8MPA,$$VB(@@`\(P"A^`,`0>>WA;_)```D`T>%-\@KV@>%S\ISA +MXB"!#PC`X)>'\-+A3?+CX6[RY.&!]('`(B"`#PC`_',(<:EP(B"`#T6`"*)Q +M\(PAPXE#\@SVC"'"A&3RC"%#@"3RC"%#AU[R9_#7<0``__M:\@;VUW$```'[ +M5/)=\-=Q``#__5#RUW$``/_^5?2!P"(@@`\(P/QS"'$!P"(@@`\(P`B$1?`B +M((`/",!8A4/P@<`B((`/",#\"`@@`\( +MP*@FX'[@>/'`"',*(D"`S",A@,HAP@#*(((/$``Q$.(@@@\(P(@0(B"`#T6` +M9+'1P.!^\<#/<(C`S#8B((`/",`TE"(@@`\(P"27(B"`#T6`:*XB((`/18`P +MF2(@@`\(P$!F(B"`#PC`4$_1P.!^\<#AQ0AU*'/T'`RP(B"`#PC`>"U"P@(< +M!#!!P\]PB,!$-HMQ`-HB((`/","H1H#@RB%"`\H@@@\0``L/XB""#PC`?!"C +MP"`@@`\(P/P,X'@*(D"`\EP(""`#PC`[`SQ +MP`#8X`X,HA`@?`("("XB""#PC`-),`P*'`T<#@?O'` +M(B"`#PC`A`P(=2AV"M@`V:ER`MLB((`/","`D6.-"MAANP+9R7(B((`/","` +MD2`@@`\(P/0,\<`B((`/",!X#`AV&G$`W0G8J7')<@+;(B"`#PC`"))CC@G8 +M8;L"V0IR(B"`#PC`")()V`#9C[D:<2(@@`\(P-22SW:@P``@;!8/&``GD1\` +M``!0"?`*V"(@@`\(P+B2[[@(=0?T;!8!&`PA0*#J!\__;!8`&,]QB,`$$>)X +M`*$*V`#9C[DB((`/","`#HLEPZ7(B((`/",!P3B`@@`\(P.P,X'CQP"(@@`\(P'@,SW:( +MP/`1!X:!X`OT"H:,(`2`1_&"'-)AL]P +M$``Q`B(@@`\(P)@0(B"`#PC`+"P/AA4F`1``@0'@`*$*AB(@@`\(P%2`#:8B +M((`/","8@`AU"H8B((`/",",@%,E3Q*,)P201_?/<$:`:"7J8`+P_MJ,(H./ +MB``&`,]PB,#H$0"`0"H!`^V].&`:<`RF0"\`$TNF`""1#P`!``#`>LHA`@3* +M(V(`SR(B`\H@0@3B(((/","`3/_9`">`'T:`:"4@J"IP(B"`#PC`P$[NO3?R +M`H8!X`*FZ7`B((`/",!4@`ZFZ7`B((`/",!`@`IP+H8`VB(@@`\(P`Q/`M@O +M\,]WB,`,$<]PB,#L$0"`((\0</'`2B3`<@ARJ""``L]QH,``2"`1`0@$(8.` +M`O2`XP3RX[D)\L]P$``P`B(@@`\(P(@0T<#@?N!X\<#AQ<]UB,#P$0>%A.#* +M(((/$``[`N(@@@\(P'`0#(4`V8RY`=HB((`/",#<@078(B"`#PC`_"LB((`/ +M",``-"(@@`\(P.0L(""`#PC`_`S/<8C`\!'@?P>AX'C/<*#``"!L$`$(SW*( +MP/`1!((">0:".&`&H@6"$''#]R6BX'[/<*#``"!L$`$(SW"(P/`1X'\DH/'` +MX<7/=8C`\!$1A3*%"*43A2FE#Z40A8#@S"$B@,H@@0\0`#@"XB"!#PC`(QH#6`,J`V@#.@$(40)0I;A@\J!$&``$TZ`@((`/",#D#.!X\<#AQ<]UB,#P$0>%@.#*(((/ +M$``\`N(@@@\(P'`0"_`,V"(@@`\(P/PK(B"`#PC``#00A8#@!?('A8#@\O,@ +M((`/",#\#.!X\<#AQ<]UB,#P$0>%@N#*(((/$``]`N(@@@\(P'`0`]@B((`/ +M",#\*R(@@`\(P``T!X6$X,H@@@\0`#X"XB""#PC```H>!_$'C/<:+``$L$$0`(`!$""%(@```$$0$(X'_`N.!X\<`B((`/ +M","`#,]QH,``#DP1#@@`V!`9(`!H$0`(SW>@P``0!""-#P`8```\O6@1`0BI +M(@@@\(P'`0(""` +M#PC`[`S@>/'`SW"@P``.3!`!"%`0``@0<MWN^^:2```,]UH,``(`P=H!\@```$`-@B((`/",`$D0C`@.#*(L$C +M!?*!X"04$C`$]QIW.G<*\"@4$3""X,H@SB/$]RP4$##K<:MR!\;+<\EP"B2` +M!`HE0`0*)@`$(B"`#PC`6'7/<(C`U!`(B."X#_+/<*C^O`\$V(@@@\(P'`0SW((P'ATSW6(P.`1`!4$$`#;0,,!V$'` +MN-A"P$`F010#W@J^SW"(P,`WN'9*)H``"B>``2(@@`\(P.!&((6`X-EA(*7* +M(((/$``2`>(@@@\(P'`0H\`@((`/",#T#.!X\<`B((`/","$#*/!SW:(P&,3 +MSW6(P.01SW"(P$0VR7$#VF"%BB0#`$HE``XB((`/","(12"%@."`(0,`(*7* +M(((/$``2`>(@@@\(P'`0SW((P`25SW6(P.`1`!4$$`#80,`!VT'#N-A"P$`F +M01,#W@J^SW"(P'@XN';8<_AS(B"`#PC`X$8@A8#@V6$@I/'`(B"`#PC``#`B((`/",`<,2(@@`\(P'`PSW"(P.01((#/ +M<(C`M#40<0OWSW"(P-P1((#/<(C`M"40<``=Z`X,!^BW`B((`/",#4 +MF@AU`,""P0RX0,"!P"(@@`\(P`27@.7,("*`!_(`P0'",'+*(84`!O"`Y0/R +M`,$"\`'!!2!^@R"G"?+7<0```!`!V,(@#@`"\`'8Q'BCP"`@@`\(P.P,\<"K +M)@AP`````2(@@`\(P"!.(B"`#PC`5$I*)(!Q`-FH(,`#6B&``<=P18",LD*0 +M89`0N@"017LK(P```>'/<(C`B!(@@,]PH,``(&P0``@R>3A@`>!!*`"#XB"" +M#PC`_)DB((`/","(E]'`X'[@>/'`SW&@P``@;!$"",]QB,"($H#@0*$-\EA@ +MSW&@P``>6!D@`%01``B!N%09(`!*)(!Q`-JH((`#6B*!`<=Q18",L@"1`>(J +M(P``8;$PNV*Q(B"`#PC`"$XB((`/",`L3-'`X'[QP"(@@`\(P'!](B"`#PC` +M*)8B((`/",`P6B(@@`\(P&Q9SW&(P`!@`-@/VC#;(B"`#PC`:$HB((`/",!4 +M@R(@@`\(P%Q.(B"`#PC`[$W1P.!^X'C/<*#``!Y`&*`/`"```.!^(""`#PC` +M-)?QP"(@@`\(P&P,JB<0$0HB@"^(P'P@`!(`*(+@RB'&`\H@A@\0`$0"XB"& +M#PC`?!#/=HC`\!$'AH/@0/+/=0`!``"%X!7RC.!+\JHA$"8")T`302@3`XPC +M!*#H`"8`BB2#+\]Q1H!H)3(AS01K\$J&*X8`(H`/1H!H)2"H(B"`#PC`-(`* +MABR&#+A/AKA@(B"`#PC`<$Y5)D$8"(8B((`/","4F0#8(B"`#PC`_"LB((`/ +M",`(+(CP#(8JAB(@@`\(P*1_#(8`VBV&(B"`#PC`4$T$V"(@@`\(P/PK=/`B +M((`/",!`+`F&`B!!`RRYC"$$@"JF1O?/EQ"'//0!0H'L`4O/'I<"IQJ7(B((`/ +M","<+"`@@`\(P,0,\<#AQ<]UB,#P$8@5`!`!X(@=`!`B((`/",``-!#P`-B> +MN"(@@`\(P*A:(B"`#PC`+"T&\(+@]?.$X`GR!X6`X/KU(""`#PC`_`P`V)VX +M(B"`#PC`J%HB((`/","L*_#Q\<`B((`/",`D/"(@@`\(P%1$`-G/<(C`,``@ +MH,]PB,`L`""@SW"(P"@`(*#/<(C`)``@H,]PB,`8`""@SW"(P!0`(*#/<(C` +M!``@H,]PB,```""@SW"(P!``(*#/<(C`#``@H,]PB,`@`""@SW"(P!P`(*#1 +MP.!^\<#AQ07(SW7P\/#PUW#P\/'P#/(%&E@S(B"`#PC```(B((`/",`L-@#( +M!1I8,R(@@`\(P%B9`-@%&A@P(B"`#PC`E`@@((`/",#\#/'`7H"`XB'R`-M] +MH"N"0B%!@"NB"O*`$`$`?X"`&T``?Z$J@C!P`_1JHB^`A>$-]"2"@.$+V$@HH'ASW*( +MP"@`!O2@HJREK:4(\"""38&MH:RB3:4LI2D@``!*)@!P`-@@((`/",#<#.!X +M\<`B((`/",!T#`AU*'8:D!#,]T(A08#*)$)PX'CH(*(!!!`!!`0> +M4!`GA3!P`O0&A0BE!84!X`6E!(5AN`2E*2"`!$HF`'``V+_PZH6`YR[R5B<# +M%`.#@>`H]"*%`H.!X000`@0$'I`0S/="(4&`RB1"<.!XZ""B`000`00$'E`0 +M0B%`H&3R/X($$`$$!!Y0$,SW0B)"@,HD@G#@>.@@H@$$$`$$!!Y0$">% +M,'`"]`:%"*4#R`'@`QH8,"D@@`1*)@!P:B"``@0@@0____W_*2!``$HF`'!: +M<`/(B!()A001`P0$&-``S?="(D*`RB2"<.!XZ"#B`001 +M`@0$&)``)X4P<`/T!H4)I4(A0*#JA07T`-DJI:'Q7X=*I8`7`1"`&D``7Z&9 +M\4P@`*`L\@'(SW$(P/`V/:!6(`\$OJ#"IP#93"$`H".G!O0*I1^@`*<*\$J% +M7Z"`$@$`(*)`(0$AS?="(D*`RB2"<.!XZ"#B`001`@0$&)``)X4P<`/T!H4)I2D@ +M@`1*)@!P`-AC\`J%@.',("*`+/)")$R05B`"!`#>`_3*I0?P?X!JI2""@!M` +M`'^ABZ7=H"*"`!$#((*%!!G0`('D0"$#(.@@H@$$$PP$ +M!!D0`\2B(B"`#PC`X#W,\4P@`*`J\@'(SW$(P/`V/:!6(`X$OJ`('D`4`-F` +MY".F!?0*I1^@`*8)\"J%/Z"`$0(`0*8?HH`9```!Y(NE!=DOH`IQ(B"`#PC` +MB#XI((`$2B8`<`2&!_`I((`$2B8`<`O8(""`#PC`U`S@>/'`(B"`#PC`;`P( +M=1IQ.G):E(-B2=PJF!O(`V!*E":8$\/*EZ:8# +MV`^ESW`(P$Q`&*6YI<]Q",`,/:EP(B"`#PC`$`IJ((`"!""!#____?\I($`` +M2B8`<,]QB,`T`!IP`!V`'TA41%(`@0'@`*&!X,]QB,`X``7TH*&EIJ:F"O`` +M@9@0`0"8&$`#E!E``R:F!:8*P0#8@>$*I0NE#*7*($$#XB"!#PC`X#TI(``$ +M2B8`<`#8(""`#PC`Q`S@>/'`X<4`W0$:6#,"&E@SSW"(P$0`!-DB((`/",`T +M)R#9SW"(P#P`(*#/<(C`M""`V2(@@`\(P#0GSW"(P#@`H*#/<(C`-`"@H,]P +MB,!``*"@SW&(P`@``($#&E@S!2"`#ZJ!````H2`@@`\(P/P,X'CQP"(@@`\( +MP'P,"'5J((`"!""!#____?\I($``2B8`,@0@#*($(#J7``V2(@@`\(P(@^*2``!$HF`'`@((`/",#D#/'`(B"`#PC` +M?`P(=6H@@`($(($/___]_RD@0`!*)@!P&G`/A8#@$/0#V`^EJ7``V2(@@`\( +MP(@^*2``!$HF`'``W1'P@N#,(&*`RB4A%0?R@^`$\@'8$*4`W2D@``1*)@!P +MJ7`@((`/",#D#/'`X<4(=1R`@.`(\E8EP!(B((`/",`P10^%@.`T\C"%@.$` +MV"WT#Z4NA<]PB,"T(#5X0("`XA_TH*#/)#@2/>$X,$HI@#*(:8`,?",(`2`2O=!*`(!A.)(`"4`!-DFN`;9 +M)?#7<`$```!+]T$H`@*0X@C9E/=!*`(##-D0\$$H`@0XN(PB!(`8V%:(4FI7!U#!I8,!/R4H4NA5!Q#_3/ +M/'`(B"`#PC`<`P(=2AV2'<:$@HH'ASW*(P$P`!?2@HJFEJJ4'\"""2H&JH:FB2J4II2D@``!* +M)@!P3"-`H`CT0"4`$B(@@`\(P+1$`-@@((`/",#,#.!X\<`B((`/","$#$`@ +M#0)J((`"!""!#____?\I($``2B8`<`H2`S:&A7!T/@`E`)AP"1(!-C!T6?<& +M$@XVT72']P(D@!-"N`'@"/`"),(0PGE"N4*Z`>%882"%H.'$]T(A`0@X8`"E +M@.04\B2%,'4(]""$,'4`V`ST`*0*\`6%!:$DH`"$$'4$](:A(*0`V`:E*2`` +M`4HF`'``V"`@@`\(P/0,X'CQP"(@@`\(P(`,HL$`WT'':B"``@0@@0____W_ +M*2!``$HF`'"8<,]QB,!0``"!@.`$]`?(@.`+]"D@``%*)@!PHL`@((`/",#L +M#`'8`*$&$@(V`(*`X$#``_*+<2:@`-D@H@;("1("-@3@4'`&&A@P!/0*R`8: +M&#`'&E@P*2```4HF`'`,\`#8!J4I(``!2B8`<*EP(B"`#PC`M$1J((`"!""! +M#____?\I($``2B8`<)AP.O`DA;%Q!/0`V$#`"/`%A4#!!:$DH(MP!J$`A:#@ +MQO="(``(`*4`W@CPPH4!A>.%@.``I0;R@<`&I:2E!/``V`:E*2```4HF`'"` +MYN,@@@/*(,(#:B"``@0@@0____W_*2!``$HF`'"8<":%@<`P<+/S`,6`Y<;U +M!\B`X)'U`-G/<(C`4``@H(#Q\<`B((`/",!T#!IP*'9(=VAU"B(`(0HA0"%J +M((`"!""!#____?\I($``2B8`<(#FF'`%\@00`"``IH#G0"`#(@/R`-@`IX#E +M`_(`@P"E"A(,-B:#D7%,``4`"1("-E!Q0``&``82#C;1<<(AA@/"*:8`P"%F +M`$CW@GG">D*Z0KD!XEEA0(-"(@P(H.(\9,HA#0.`YP/R`=@`IX#E`O(@I4PB +M`*`$\B&#`!I`($PA`*`%\B00`2``&4`@*2```4HF`'``V"`@@`\(P-0,\<`B +M((`/","$#`#="QI8,PP:6#,(&E@S!QI8,\]VB,`T(#IH"L@U>""`@.$&]*2EI:6@H`?P18&DHJ6A)*5%I0:EV?'@>/'`X<4(=6H@ +M@`($(($/___]_RD@0`!*)@!P1H6`XA7R9(5P=0?T8()P=0#9"_0@H@GP)84E +MHV2A(((P=0/T1J-@H@#9)J4I(```2B8`<"`@@`\(P/P,X'CQP"(@@`\(P'0, +M"B8`D%IQ2'<:#/<8C`)``@@3!P +M0_>Q=O?U:B"``@0@@0____W_*2!``$HF`'`#$@$V8;D#&E@P*2```$HF`'`B +M((`/","X/[%VQ/-,(`"@RB#A`!WR@.<#\I#GP_<%V!?P02F`(!!W._<%R(#@ +M!_+7ER"G,*)$`$(B"`#PC`/#<@((`/",#4#.!X"B,` +M@`;R`(/7<%51544$\@G8X'Z`X>$@P0?*(.$`@.(&\@7(@.#A(,('!-AH<"`@ +M@`\(P-PWX'@*(P"`!O(`@]=P55%5103R"=C@?H#AX2#!!\H@X0"`X@;R!/'`(B"`#PC`:`RBP0HF`)"Z<4AWFG,*(``A +M"B)`(0HA@"$*(\`A!O(.P(P@`HX$\@[8BO!J((`"!""!#____?\I($``2B8` +M<`,2`38!X0,:6#`I(```2B8`<,]PB,`X`*"`0B)#(`)S`-D%\)05#1`!X<]P +MB,`T``"`$'%0][%V#O)#A1)R!?<$A1)P!O=0(#@\<`& +M\B"`UW%(5$12!/(.V`;P(B"`#PC`E#S1P.!^@.#QP`;R((#7<4A41%($\@[8 +M!O`B((`/",!T/='`X'Z`X/'`!O(@@-=Q5$%-203R%=@&\"(@@`\(P)Q`T<#@ +M?@HC`(`&\@"#UW!404U)!/(5V.!^@.'A(,$'%M@%R-=P\/#P\.$@Q@<3V&AP +M(""`#PC`P$#QP"(@@`\(P&@,"B8`D+IQFG)ZAP!/*L +MX`3R%=A?\&H@@`($(($/___]_RD@0`!*)@!P`Q(!-@'A`QI8,"D@``!*)@!P +MSW"(P$P`H(``V`/PJ84!X,]QB,!(`""!,'!#][%V]_5J((`"!""!#____?\I +M($``2B8`<`,2`39AN0,:6#`I(```2B8`<"(@@`\(P+@_L7;$\TPA`*#*(*$% +M'?),($"@S"`BH!?8%_0%R(#@!_+7!$`"(&X>!D@`.!^X'CQP"(@@`\(P(`,%'B8<0AW@"<(&`AV +M@"9(&`AU@"6(&(#CRB.!#P``(`'/(V(`SR,B`JH@@0V`X`OR(B"`#PC`5$HK +M),`#*R*``RLC0`,@((`/",#L#.!XSW'^RO[*JB#0``0@A`__``#_#"2`CR0` +M``+*($(`#/0/>(+@`=C`>!-XP;B`(`@(*B```.!^X'CQP`200K@B((`/",!( +MG`#8"'$B((`/",`82]'`X'[@>/'`(B"`#PC`A`P(=<]PB,#4$`R(X[@H=@KR +MSW"H_@```=FI`*H@@0R`X`KRJR;!<@```0"J(`$" +MZ+C^]>!^X'CQP"(@@`\(P&!,JB`!`NBX_?71P.!^X'BJ(H$,@.(,\AEA(.%& +M(<$'JR&!`T8@P`>K($$#X'[@>*HD`1*!X\\DH1'0)*(1JR0!$JLA`0<:8D8@ +MP0<"\"#A,'+)]ZLA@0*J(`$"Z+C^]??QX'[QP"(@@`\(P'P,"'4B((`/",#< +M38#@`-@^\L]P18`,XK9XX(``WB3PSW%&@&@E"&&,((./,``%```7`!AJ((`" +M!""!#____?\I($``2B8``&`$'9-]\]Q``$```(G0!`LN(P@!("@!\7__MC0\0'8(""`#PC` +MY`SQP"(@@`\(P(`,"'4H=TAV`-F,N0#:(B"`#PC`W(&I<.EQ`-J,NB(@@`\( +MP%A:@.;`>,\@8@?B(((/","H6B`@@`\(P.P,X'CQP"(@@`\(P(0,"'8`W0/P +M`>6$Y5+W%&[/<46`'.*U>`!AC"##CPKR(B"`#PC`M$R`X/#U`-@#\`'8(""` +M#PC`]`S@>,]P18#8L@*`@.#@?\H@8@#/<0`!``#/<``!```0<0;RJR90<@"` +M``#@?N!X\<`B((`/",#<38#@XB""#PC`5('1P.!^\<`B((`/",#<38#@$/+/ +M<$:``'@B((`/",#0?R(@@`\(P-Q_(B"`#PC`?($B((`/",#L3='`X'[@?N!X +MSW!&@&@E_ME":2`@@`\(P`1WX'B!XFS:RB*B#00@@`__?P#PA2`,``0A@0__ +M_P#P@+E%>:L@4`&K(9`!JR80<@``!`"J(-`!_[@,\JLF$'(```,`JB#0`:LF +M$'(```$`X'[@>`AQ!""`#_]_`/"K(%`!JR80<@``!`"J(-`!_[@*\N"X%?+/ +M.!^X'CQP.'%HL&+=:EP`MDB((`/",!DF\]P +MB,#,-JEQ(B"`#T6`N*"BP"`@@`\(P/P,X'CQP.'%SW5%@("[J7"'V2(@@`\( +MP&2;SW"(P,PVJ7$B((`/18`\HR`@@`\(P/P,X'@@((`/",!H$O'`X<6CP0#8 +M(B"`#PC`F$V+=:EP`]DB((`/",!DF]/8#-FI`+Z#``#@4'Z`O`&`` +M``P5`""`X%;R(H61XER(B"`#PC` +M6%K)<,EQZ7(`VR(@@`\(P(!,`-B=N"(@@`\(P*A:J7#)<0IRZ7,B((`/",!8 +M3B(@@`\(P&Q_#!4`((#@RB'"`\H@@@/B(((/","$CD(D02"`X80'[?]`(4`@ +M`"+`)')PSO=J40=1@'Q?\, +M%0`@@.`1\H+``-DB((`/",!,CX#@RB"!#Q``0`+B(($/",!P$,EP`-F.N0': +M(B"`#PC`W($B((`/","X@!0?H"\`8```!!<`*)VXGK@$'R`@(B"`#PC`/!$B +M((`/","<=H`D!#(@((`/","<#.!X\<`B((`/",!\#,20"'>C;D8ES1`BO:'! +MUW4````(RB"-#Q``*0'B((T/",!P$(PE!)!`)P`5F??_V1IQ(B"`#PC`9)L2 +M=/'`(B"`#PC`A`P(=L]U18"`NZEP%=DB +M((`/",!DFZEP(B"`#PC`C&@%I@38!*8@((`/",#T#.!X\<`B((`/","$#`AV +MSW5%@("[J7"*(<4!(B"`#PC`9)NI<"(@@`\(P)!B!:8$V`2F(""`#PC`]`SQ +MP.'%"'4B((`/",#48@6E!-@$I2`@@`\(P/P,\<#AQ:'!"'6+<`'9(B"`#PC` +M9)L`P$`E`A4$V0"B(:(`PX/C`-@$\@&B!/`"HBAP".`$I0&"@.`$\HP@#XV* +M]P#!SW`0`#`!(B"`#PC`?!"AP"`@@`\(P/P,X'C@?N!X\<`B((`/",!T#`AW +MSW%&@-PX&G&D:4`@#@4($!(!0"`1!HPB"*/*((T/$```!N(@C0\(P'`00"+` +M($8@P0`BN0IP(B"`#PC`9)L!C9?@S""BA@7T`M@`IC?P`XU"N`C@4G`%\@/8 +M`*8O\$`E`1*I<"(@@`\(P/0HUW````"`!?(!V`"F(?``V`"F`!``((#@&_(" +MN$`A`2((X`2G*G`B((`/","\*``0`B`#$8$@,'($](PA0H#)]L]P$``!!B(@ +M@`\(P(@0(""`#PC`U`S@>.!^X'C@?N!XX'[@>/'`X<4DD,]PB,#8%4"``8#X +M'(BP0<"+=2*YJ7`B((`/",!DFZEP(B"`#T6`$):BP"`@@`\(P/P,\<#AQ;;! +MBW6I<,]QB,"0%%C:(B"`#PC`(`ZI0`9@`_EY>7E(84!X2&E(H4!X2*E*2```$HF`'`@((`/",#\ +M#.!X\<`B((`/",!\#%H@``4H=@`@C0]%@`C":B"``@0@@0____W_*2!``$HF +M`'!`A2*%&G!0<04FCA\()P``P*$!X`*EI(45?2D@``1*)@!PJ7`@((`/",#D#.!XX'[@ +M>/'`(B"`#PC`1`TB((`/","$#*C!"'5,P2(@@`\(P-QL@.!)\@S"4R7!%$`J +M``:-QB5X0,``V8#BRB2-<,HC30#H(&T"!.85),`P_!8,D`'C@:#/=*#``"!L +M%`,8%22`,&&@`N(%(H(/P.Z`,,]SH,"`'`0;H`!L%``8!!L@``0;8`,,P(#@ +MR_<5)$`P`8`!X00;(``,P#!P./>+=:EQ(B"`#PC`U'0,P*EQ(B"`#PC`P'2H +MP"3<(""`#PC`]@S@>.!^X'CQP`S9SW"@P``.$!A@`&@0`0B`X'&`-W/%054<>!!S'#@02!N@#Q```Q#$''@30!N@#T"```#!QL'%X'[@>/'` +M(B"`#PC`A`P(=<]VH,``.!06`!BK>/WS8-ADV2(@@`\(P+RE%!8`&*MXRB"! +M#Q``(@+B(($/",!P$!0>8!,@((`/",#T#.'%X<8`WL]UH,``?"`=H!,(W#`= +M(!//=*#`@'MH'*`3+!V@$`2YG[M@'&`09!R@$VP<(!`@'>`0P<;!Q>!^X'CQ +MP"(@@`\(P'P,&G`H=<]QB,"P'P"!2';X'`BP`I&+=P0Q:4$'((C!1R" +M(P0=0!2`YU8`+``+',(D"A2`((#@`-_0]JEPR7'I=AOH#F[W\S]TPE +M`*`*\L]Q",#D7*EP`-HB((`/",!T7R`@@`\(P+P,\<`B((`/","$#`AUSW"( +MP-00!XCCN$"%*'81\@$6A!#/<*C^,`T"%@41!=D<%0808(XB((`/",!P60"% +MR7$B((`/",`,G2`@@`\(P/0,X'CQP"(@@`\(P&@,HL$(=RAU0"`.""J.H.8: +M<@?R,'5%]@*'@.`.]`"'0"T"$A"X!7K/2(@@`\(P'P0SW"(P`!@ +M$G`/]\]PB,``8!)PRB$-!,H@C0\0`/0.XB"-#PC`?!`0E["W$;<$CH#@'!\` +M%"/RSW"(P-00!XCCN`ORSW"H_@P-`ME`AZES(B"`#PC`<%D%CH#@#O(@A\]P +M$`#P#A"Y49>E>6B.(B"`#PC`F!`!V`6NO_`!V`2N2B,`((HDPR\%'L(4*HX( +MCB`7$1$=($``'!<0$"*'(G`R(1(`*XY2<1+V#"(`I0[R`(=`*@(B$+@%>L]P +M$`#M#D5Y(B"`#PC`?!`,(@"E`-T%\J&'%B6-%$6'@.((CA3R8,"`Y0(<1#0$ +M\@&-`_#_V(#E`1P",`/R`84"\`#80<"+<6!ZZ7`(CI)P#O0@APBX$+D%><]P +M$`#H#@4A000B((`/",!\$(#E2(X*],]P$`#F#B"'*G,B((`/","8$"&-"!:5 +M$$HB0"`,)4"@PB*!)+)Q(O))CK)RRB%,!`X`3RJ6"2<03T`-H%\`&'-GA!@(#BRB$"!,H@0@3B(((`!8Z`X$OU!![" +M%*+`(""`#PC`O`SQP"(@@`\(P(`,"B4`D"AW2';*(($/$`#G#N(@@0\(P'`0 +MY:7&I2`@@`\(P.P,X'CQP"(@@`\(P(`,"'4B((`/","T%,]V18`@Y==P``#_ +M_T`FSQ,2\EH@`0L'C2IG$'*,``P`0"8`$CA@J7$LVB(@@`\(P"A^//#/<$:` +MV#@`@"&&$''5]R(@@`\(P`@56B`!"P>-*F=0<%GV0"8`$CA@J7$LVB(@@`\( +MP"A^#_!:(0$++-I`)@`2.&"I<2(@@`\(P"A^`88!X`&F`89DW!T@`0//<$6` +MZ/(`@)T@`000<!X\<"`X,H@8@#B(((/",#08-'`X'[Q +MP"(@@`\(P(0,"';/=46`(.4`I2(@@`\(P-QL@.`*],]QH,``-``1``B0N``9 +M(``AA8H@VP]=(0$+`=NI`';SW)&@!P&8*H@((`/",!H8.!X`-G/<$:`'`;@?R"H\<#A +MQ9APSW!&@)0%$("`X`+8%O2(<"(@@`\(P)P@B'`B((`/",!\'8#@"O2(<`#= +MJ7$B((`/",#8&JEP(""`#PC`_`SQP.'%SW!&@)0%$("`X`38"/(`W:EP(B"` +M#PC`+/<4:` +M\#H@@3!RP@?%_X#DRB""#P``_@#B(((/",!T9(#ERB""#P``_P#B(((/",!T +M9"`@@`\(P/0,X'C/<46`I.(`@8#@`=@#\@#8`*'@?O'`(B"`#PC`=`PZ<`#= +M_MA:<`PA`*`!V<(A00#/<$6`',(:<""@J78?\%HF`AW/<4:`3#(`(H\/1H!L +M,A"/@.`2\@^/,G`0]%HE`QM984`@`"(LVGA@(B"`#PC`*'X!Y0#8$*\!YL]P +M1H#P.@"`$':Z!\7_!!A`(R(@@`\(P-QL@.`*],]QH,``-``1``B0N``9(`"* +M()L/BB$6`@IR`=LB((`/",`L;8#@#?3//'`(B"`#PC`A`RCP<]R18"DXB"""':!X0'8+/(`W<]Q1H#P +M.@"B`8Z@H:#@1``I`,H@Z0"`X-CV6B6!$@S:BW#9803A(B"`#PC`(`X`P`'! +M`L(B((`/",#\8@'E`8ZP?1!UK/8@CL]P1H#,.""@`-BCP"`@@`\(P/0,X'CQ +MP"(@@`\(P'P,&G``W0/P`>7/<$:`\#H`@!!U8``&`%HE#AW/=T:`3#(*<`;: +MV6``IA#<(""` +M#PC`]@S/<$6`J.(`@.!^X'CQP"(@@`\(P(`,"'<`WA[PM6X`V,=U18#@XPVM +M#JT/C2(@@`\(P+B>"''I<"(@@`\(P*"D@.`(\@R-C"##CT3V`>`,K0'FSW[/ +M<$:`]#H`@!!VP`?%_R`@@`\(P.P,X'CQP(#@`-DI\BAS&/`5:\]R1H#0.,=P +M18#@XT""C(A0=(7W`=I-J`#:4*@-B(#@!/(!X2]Y`>-O>\]P1H#T.@"`$'.F +M]\]P1H#H.@"`$''B((8/",#L9]'`X'[@>.'%X<:8<,]P1H#X.F"`SW)%@.#C +M0B--@,HD27/@>.@@J0)`+$X!7&7<9-:,8;W7K$`L0`%88#>H,(@P<\/W`>$P +MJ,'&P<7@?@#8SW%%@*CBX'\`H?'`(B"`#PC`@`P`WL]P1H#T.@"`SW5%@!S" +M@.``I=?W-&X$;?5N.&#'=T6`X.-`)\$3$-HB((`/",`H?@#8#:\!Y@"%SWX0 +M=JSW(B"`#PC`W&R`X`GTSW&@P``T`!$`")"X`!D@`""%BB!;#P2YJ7($X0'; +M(B"`#PC`+&V`X`GTSW%%@*3'`(&#N`"A!O``V<]P18"HXB"@(""`#PC`[`SQ +MP"(@@`\(P(0,H\'/$!V#?R`-T`HD..SW%&@/0ZB.*@H0WV +M(8[/<$:`T#@@H"".SW!&@/@ZB.$@H,/V`]@?\"*.SW!&@.@Z@.(@H-CV6B6! +M$@S:BW#9803A(B"`#PC`(`X`P`'!`L(B((`/",!P9@'E`XZO?1!UK/8`V*/` +M(""`#PC`]`SQP"(@@`\(P(`,"'8`WP3P`>?O?\]P1H#T.@"`$'=^``8`M6_) +M<,=U18#@XT`E010&VB(@@`\(P"!^@.#J]0Z-@>`GC@?T%XTP<%(`#``WK0;P +MZ7`B((`/","89R>.Z7`B((`/",#@G0:.#ZW/<$:`^#H`@#"-$'$!VH[W`(5B +MA1T@0`!P<(?W`84=($``$'-"]TVM`-@,K4ZM(""`#PC`[`S@>/'`X<7/=46` +MI,<`A>.X"?(B((`/",#L9P"%H[@`I>&X"?+^V"(@@`\(P'1D`(6AN`"EXK@) +M\O_8(B"`#PC`=&0`A:*X`*7DN`GR`=@B((`/",#08`"%I+@`I>6X"?(`V"(@ +M@`\(P-!@`(6EN`"E(""`#PC`_`S@>"`@@`\(P/"2(H!`(`(#('E(<.!X\<`B +M((`/","`#`AUT8CPB)'FRB*&`\HAQ@/*("8.XB"&#PC`B!#/<$6`R.'/<46` +M;+/)8?`@@`,P=XCWSW$(P&@2(J4!V`;P]G@@@"*E`8`!I<]P",!H$C!P`=C" +M(`$``*4@((`/",#L#.!X\<`B((`/","$#,]V1H`L!@W(R74.&A@P!]H-&I@P +MSW&@P``($!$`"`X1`8X0>#!P-_?/<:#```4\&:```-@&I0>E!:4,$0`(`Z50 +M$0`(!*6I<"(@@`\(P$QJSW"(P-00"HCCN``5!!`+\D.%SW"H_FP+9(4#V2(@ +M@`\(P'!9`(6`X"3R`X8B((`/",#`D!&-0"4.$PHA`(#)<,HA8@`"X2(@@`\( +MP&2;`86!X`CT`X4DA2(@@`\(P%QN&O#)<"(@@`\(P&AV#/"I<"(@@`\(P$!J +MJ7`B((`/",#D(,]QH,``.``1``BGN``9(``@((`/",#T#/'`(B"`#PC`?`P` +MW\]U18`$]$`E!!0*)8`/H,``$.EV!O`B((`/",``(@'F`84@A1!Q%?+P)$`` +MSK@BN`'@\FB-%0&.!+@P<.WWSW"@P(`-9QVXCP``__\$\,]PH,"`#1IP`-@1 +M&A@PE!4`C@'9G[@0&"`@!!A@(,]PH,``.!@8H`\`$````84@A1!Q$_+I<"(@ +M@`\(P,R*@.8&\@*%C"`0@(GWSW`0`"`!(B"`#PC`X`!D@`-'`X'[/<$:` +M+`8$@.!^X'CQP`\:F#\`P```SW!&@"P&$!B`#P``__\B((`/",#L(<]PH,"` +M#@@0``@0&A@P(B"`#PC`<)S1P.!^X'C/<(C`"!$`@.!^X'CQP.'%SW%&@"P& +M!H&!X"AU`_0`V`:AJ7`B((`/",#D(`2%0"4"&">%`]LB((`/",`L;2(@@`\( +MP'!L(""`#PC`_`S@>/'`(B"`#PC`<`RAP7IP.G)H=0OA1B'0`$(@#B'@NZ#? +MP"\B%LHG(1!J((`"!""!#____?\I($``2B8`<%IP`!S`-('ES"6BD,PE(I$) +M]!_,(6@P>8ZYC[D?&EPP!?`B((`/",!T(@(/'`(B"` +M#PC`A`S/=:#``"!L%0`8SW:(P+0U`*;/<*#``#@@$``(@.`"I@WR\K@%\A+8 +M`Z8.\"\H`0!.(($'(Z8(\,]P$``6`2(@@`\(P'`0(X;/<(C`$!'P($``0'AL +M%0`8`:8@((`/",#T#$.0@N(`V<;V0I!`(`$$"/!'D(+BQ?9&D$`@`01988#A +M$O(`B8'@$/1B:6AR`O`!X@&)>&`0$'@P<#KW/!V@$++`(""`#PC`]`SQ +MP&H@@`($(($/___]_RD@0`!*)@!P)1(!-R0:7#`O>0'A+WF/N24:7#`I(``` +M2B8`<"3,T<#@?J'!\<`B((`/",!\#"AW"'7/<*#`@`T8$``(2'8:*'!\<`B +M((`/",!\#"AU&G!(<0#>L'B,(,*$X<;*\I``"0"QX-CR&_:$X.`!`0`,]H'@ +MX`$"`"(@@`\(P+A+U0$@``AVG.#,`0(`BW(*<*EQ(B"`#PC`<)A*\./@F?(9 +M]M'@4MS,(`*#U/3/<(C`S#8B((`/","T;X#@S/(!W^EP(B"`#PC`Q(D(=D#' +MPO#DX`SR[>"^],]PB,#,-B(@@`\(P+1O@."V\@/8;?",($.+1_)V``D`C"## +MA)/R2``)`(P@`X!G\HP@0X"D](#ARB"!#Q``#@_B(($/",!\$(MR"G"I<2(@ +M@`\(P+B'"'8B((`/",#<;`'9@.``P,!Y)7A`P(CPC"!#ATWRC"##B8+TSW"( +MP,PV(B"`#PC`M&^`X'CR:]@O\-=P```!^W+R/``)`(P@QX15\HP@1XMJ],]P +MB,#4$!&(X[@)\L]PJ/Y<#`#9(B"`#PC`<%D!V"(@@`\(P%!N`-Y6\-=P``#_ +M^U+RUW```/_^3O0B((`/",#PB07P(B"`#PC`Q(D(=B'PR7#Y\8MR"G"I<2(@ +M@`\(P"2*./#/<(C`N!(`B..X,O)^\<]PB,"X$@"(X+C1(.&`*O($((`O``#\ +M_V2X(KC;\0'80,`@\"(@@`\(P#1:&O#/<(C`U!`1B..X"?+/<*C^'`P`V2(@ +M@`\(P'!9`-@B((`/",!0;@#>Y?$B((`/",!4>8#FRB%"`\H@`@3B(((/",!X +M=@#`H<`(W"`@@`\(P.8,\<`B((`/",!P#*+!>G`:<5IR:B"``@0@@0____W_ +M*2!``$HF`'`Z<``$'A0<#KW3QUXD(MP`MDB((`/",!TG$(H +M@2!*<"(@@`\(P'2<#A("-@W(#1J8,`X:&#`0%0`8#A4!GA!X,'`[]T\=N)`I +M($`$2B8`<*+`(""`#PC`S`S@>"AP2'%H`#9#R$!`,]PH,"`'C@88`#@?N!XH\'/=8C`##:+ +M=L]WB,"0$:EPR7&*(O\/(B"`#PC`<$8`%``Q@N#*((H/$`#U#N(@B@\(P'`0 +M`!0`,0+!\"<"$&!Z`<#F\>!X`K@H"`H@&C`>$D@PATAB3/GP'A)*,%\B6#`>$E +MH\FX`:,@((`/",#T#.!X`-C/<8C`M!`$H0.A`8'@?P*AX'CQP"(@@`\(P&P, +MHL$(=IIQ>G):&D@0`#1 +MP.!^X'@(`?P`1&#!`$0C`1P=`?T +M8;J,(O^/]_4`V`SP_Q""@/\1@(`!V1!RBB#_#\(A2P`T>.!^X'BJ(1``SW`0 +M```"(""`#PC`?!#@>.'%B^+*)`L0F/8O>T`K#`)E?$`L`Q2%>PAT!?`!'-(0 +M8;I3)'Z0_/5!*HT`P;I")4V0!!S0$/WU@.+']D(B0H`!'%(0_/7!Q>!^X'CQ +MP"(@@`\(P'P,IL$`V<]PH,``-``0``C/=J#``"!L%@T80\$B((`/","0*(7! +M0<"$P"(@@`\(P$`H"B<`D`7T0-A"P*WP%!00,"(@@`\(P/AY@.#*(&(`$W@0 +M>`'@+R8'\$+`F?0B((`/","0D@'!$''8`"X`0,"`X"/R(B"`#PC`J'F`X`#9 +MSR%B!,HAH0`"P"5X+R8'\$+`#_*+"\F!_!"P"_T$O`%P>EP(B"`#PC`%'J`X!'R!,$5?Q@A`0!$ +MP07!%7D"P$7!!,*`X@]YV?:`X>OS%?#/<(C`U!`4B.&X"?+/<*C^K`H`V2(@ +M@`\(P'!9`L"#N`3P`L"'N$+`+R8'\!_T`<$*<"(@@`\(P%AY@.``V,\@(@7* +M("$$`L$E>$+`(B"`#PC`D)(!P3!P`-G/(6$%RB$B"`+`)7A"P"(@@`\(P`AZ +M;!8`&*)X0\"+ +M!/;)=0WPBW#I<2(@@`\(P/0HUW````"`8;WT]:EPHL`@((`/",#L#.!X\<`B +M((`/",!H#((D"3,(=1IQ.G)H=@HD`"&+=^EPSW&(P"@=(-HB((`/",`@#@#8 +M2,!`)!,Y:G#/<8C`@!V*(HEP`-D!VKIR(B"`#PC`^$GI<`/9`=HB((`/",#X2>EP/=D! +MVB(@@`\(P/A)Z7#=V0':(B"`#PC`^$GI<,#9`=HB((`/",#X28C`F'`2V0': +M(B"`#PC`^$F(@.`/\@@>0!2CIA81`"')<0>NBG`B((`/",`4%(#@`_0`V`_P +M0"6!$LEP!MHB((`/",`H?HIP(B"`#PC`/(*J<(`D"3,@((`/","\#.!X\<#A +MQ<]PB,#4$`B(X[@H=0GRSW"H_IP,`-DB((`/",!P68#ERB1-<^!XZ"!M`N!X +MX'C@>.!XX'C@>"`@@`\(P/P,X'CQP.'%SW"(P,`<`("FP4'``-A%P,]UB,#4 +M$`^-X[@+\L]PJ/[`!P'9`-HB((`/",!P607"_]@0<@/RA>)4]Q!R`_1!P@?P +MSW"(P%0@\""``$'`@<+YV`39`=LB((`/",`L;0WP#XWAN`GRSW"H_B0(`=DB +M((`/",!P6:;`(""`#PC`_`SQP,]PB,#4$`^(X[@)\L]PJ/Z4"@#9(B"`#PC` +M<%G1P.!^X'CQP"\D!P#/<8C`R!$`J0G8!*D$V`6ISW"(P-00#XA*)4`!X[@! +M&4(!"_+/<*C^8`@$V0G:*',B((`/",!P6='`X'[@>/'`"]C/<8C`R!$$J0#8 +M!:G/<(C`U!`/B..X"O+/<*C^Y`@`V2(@@`\(P'!9T<#@?O'`"'+/<(C`U!`O +MB,]PB,#($62(X[D%$(0`"O+/<*C^G`D#V2(@@`\(P'!9T<#@?A?8SW&@P``0 +MN1DX@`?891DX@,]PH,``."@8H`\```#,JR8(<`````%I(``!X'[@>,]SB,#0 +M$<]QH,``.`0;@`<(&T`'+!$`""@1`0@$>2"CSW"@P``0N!`#CM=Q````(&80 +M`([+"`@@`\(P*0V(""`#PC`O';QP.'% +M"'4B((`/",`@#JEP(""`#PC`_`P@((`/",`T)X#@X'_*(&(`\<`B((`/",!P +M2"(@@`\(P$A^T<#@?N!X\<#AQ1EP^'%(=(AU"B9``8'CRB3"$`7TSW((P)!V +MG24/&NAQ"7")/'`(B"`#PC`A`RAP2AVBW,`V2AR +MF'&X<2(@@`\(P-1)"'4`P(HA#PH,N"(@@`\(P'P-`*:I<"(@@`\(P$A^H<`@ +M((`/",#T#/'`X<6AP2AUBW(`V2ASF'&X<2(@@`\(P-1)`,&`X@'A`!4!&-=QW+KN#\PB(H#* +M(($/$``_`N(@@0\(P'P0(""`#PC`_`S@>`'8(""`#PC`="O@>`/:SW&@P`!( +M`!F@``09(`#@?N!XSW)%@-BR(8(0XFRY`2A,`!,@0``0($,`\"(``^!_>&#] +MN.`@@@\(P*PK_KC@(((/",`L+>!^X'C/<:#``%`H&2``X'[/<(C`@!(`@,]Q +MB,"$$IZXG[@`$``((($Y>.!_$'C@>.'%X<;/<(C`,!4@@`&`^!Q(L$'`SW"( +MP.P1P(``VLEP#]S/)"(``("/``W`\D#!!AO("E`-B`X._U`,(!P$&A`J$(&Z```H$I;@P;(``] +M><]PH```4C5XSW&(P(`2`*%2)@`0P+@$N,]QB,"$$@"AHL#!QL'%X'[@>$HD +M`'@`V:@@0`3/<*```%(U>)ZXG[@`$`((SW!&@'0F-7A`H`'AX'[AQ0#8SW)& +M@&@F)&I*)`!X0"(-`Z@@0`//_`E#!">NY^[`!L@`P'@2B2`<`#8 +MJ"!``\]SH``(4!5[\"$,`)Z[G[L`&R`#`>`@@L]PH,``4``88`#!Q>!^X'@H +M<\]Q0(```")X02@!`WA@QW```/\/++@P<$(`)0#AQ2)X0"!\`.!XJ"!`!D$I +M30%3(0`!`-S/P\D#!">NY^[`!,`"(#BQ2`"`\8@`0,`&R```>'! +MQ>!^X'CQP.'%J<$(=8MPSW&(P``6(MHB((`/",`@#@&-(FT!'`(P0"2`,"#: +M(B"`#PC`*'ZIP"`@@`\(P/P,X'CQP"(@@`\(P(0,JB80$*HET!`B((`/",#` +M2JEQ"'*'V,ES(B"`#PC`F!`@((`/",#T#.!X\<`B((`/",!\#!IP*'=(=<&) +M(B"`#PC`D&^`X,HA0@/*(((/$`#0$.(@@@\(P'P0%"!`(Z&OP:C_V3!V(*@& +M\A0@@".@J`/PH*\@((`/",#D#.!X\<`B((`/",!\#!IP*'=(=<")(B"`#PC` +MD&^`X,HA0@/*(((/$`#1$.(@@@\(P'P0%"!`(Z"OP*C_V3!V(:@&\A0@@".A +MJ`/PH:\@((`/",#D#.!XSW"@P``T`!``"`#9PK@/(0$`SW"(P``1X'\@H/'` +M(B"`#PC`;`P*)P"0FG$Z&!_BG$! +MY;3EJ`?%_R`@@`\(P,0,\<`B((`/",!P#*+!"'4:<;3@RB%-`\H@C0\0`!(/ +MXB"-#PC`?!`*(8`O18"(WBIP:-DB((`/",!`?HMWZ7`(V2(@@`\(P$!^@.5$ +M`"X``-Y:=14@C2,`E0(5$Q$B((`/","XG@AQ%"%,(`&542,`H`"TRB)B`,H@ +MP@/B(((/","4I4(B32"`Y0'F)/?I<`'9(B"`#PC`W(^BP"`@@`\(P,P,X'CQ +MP"(@@`\(P'@,"'4H=TAV`!&0`/_8`1&1`!)PS"!"A`CRJ7`B((`/","0;X#@ +M"O3/5@J6&IP<7@?@'8SW&BP`!+"!D@``#8"!D@`.!^\<`B((`/",!X +M#((D`CN!P!IPSW&(P.@42-HB((`/",`@#I3%J7#/<8C`X!40VB(@@`\(P"`. +M5B01,\]QB,#0'"IP3-HB((`/",`@#HMVR7`B((`/",#\'H(=B(@@`\(P/!S@>;*(4$$RB!!`^(@@0\(P"B07_`@ +MD(8A_`",(0*`'O1`(`T)P)9")@X9%?``C>&-C"!#AP+G"?23P")M!-HB((`/ +M",`@#OUET7?")L43RB8F$(#F[/4Y\(PA`X0U]$`@`08`D==P```$"2_TD\`" +MX03:(B"`#PC`(`XG\$44C3`A\"\H00-.((\'A.=(]\]P18`0W/`@P`.`X`OT +M112!,,]P$``7#R(@@`\(P'P0SW!%@!#<\"#"`\EP8'H*<1`ES1.`Y=_U(B"` +M#PC`\'.`)`([(""`#PC`W`S@>/'`$M@B((`/",#@(\]P1H`<)1+9(B"`#PC` +MF",B((`/",`8(P#8T<#@?N!XH<'AQ>'&H<%#P0'9(*+/=*#```YH%`$8:!0! +M&,]S``#\_T#!`!0!,88A_`",(0.$9'@Z]"39$!Q@$&@4`1@P>==Q```$(3#T +M.-T'\$$N`1(O>0+A/640'&`3(VUD>3!P1``.`&@4#AC/>:?A\/5H%`$8+WF( +MX!_H<"AP?'`(B"`#PC`9`ST'$BPNG!(=P0@@`\``/S_0B`0 +M`0#"02B`(*IQ(B"`#PC`2)W/$YDGWSW!%@/#>\""``X#@"O0! +M%($@SW`0`!4/(B"`#PC`?!``V$+`SW!%@/#>\""#`X+"`,%@>ZIP!2$1(`"' +M`L$0)8T3)'B`Y0"GUO4J=8#E#O(B((`/",#*+!\<#AQ4/":'4B((`/","8D`"E#!0`,0#9AB#\`(P@`H!0W,P@`H/*($(` +M`O0!V`S<(""`#PC`_@S@>,]Q1H!D)>!_`*'@>*'!\<#/`#\@'8!?`B((`/","8D(#@`*84]$#ESW!&@&0E`(!` +MA4$?`A!(V,]QH,``#A`9(```A0`9(`!`I0C<(""`#PC`[@S@>`'9$+@1&E@P +M@;C/<:#`@`T$&2``X'[@>,]PH,"`#1@0``@$((`/`!`'`.!^X<7AQE,@@P,B +MN\]TH,``$+`<.)#/=*#```Z!X]#W!!Q@$`#9!/`$'&`3`>'*:]%Q\")-`+GW +M"!Q@$P3P"!Q@$/VX"/(#V<]PH,"`'1@88`#!QL'%X'[@>(#9(""`#PC`A([@ +M>`ARH1`!!H`B"@$$N4AP!.$@((`/","$CO'`(B"`#PC`A`P(=BAU`=@B((`/ +M",`X=,]QHL``"!@1``B`N!@9(``B((`/",!8C,EP(B"`#PC`!(VI<"(@@`\( +MP"B-(""`#PC`]`SQP"(@@`\(P(0,"',H=B(@@`\(P(@M@.`)](#CRB`A`"7R +M(B"`#PC`M(S/<*+``$L$$``(AB!_#H;@RB""#P``"0/B(((/",!P$,EP(B"` +M#PC`-(PB((`/","HC`'=J7`B((`/",!D=*EP(""`#PC`]`S@>(HD`7``VJ@@ +MP`//<:(``$I5>14@C`">N9^Y`!$!"`'B(*3@?O'`X<7/<*#``#`P$`T(`-C/ +M<0$`H(8B((`/",#,D(#@RB%!`\H@@0\```0#XB"!#PC`?!`B((`/",!$A0/9 +MSW"BP`!+`!A@`"`@@`\(P/P,`-@@((`/",`$D>!X\<`B((`/","$#,]UH,`` +M(&P5`QC'D5XBW*"(@@` +MM7I^&A@`$VE!*`P&&[G%?"BXA'LE>`0@@`\`_P#_97A_&A@`BW;)<$S9(B"` +M#PC`2$PR;`0@@`\` +M_P#_!7K/<*(``%"U>)ZXG[@`&*```>4%\I#EP`?%_U,ES9`2]&P1`"AR<`#8 +M8!(!*,H@;P!2(0$`X+G,("&`]//@N0_R@.?J]<]RB,",$B""`"$`!`"B(""` +M#PC`S`R*(`P"(B"`#PC`/'`(B"`#PC`?`P:<`HG0)#/ +M<$:`]"8(=03T%8"`X!/T0"4.%@+8R7')`=C)<0IR(B"`#PC` +M1)[UI2`@@`\(P.0,X'CQP)AP*'#/<46``-]@@8#C!_+/,]QH,"`+$`9(`#@?O'` +MX<7/)ZXG[@`$``((""`#PC`]`S@>/'` +M(B"`#PC`?`P(=\]P18"PV_9X&G.@@$AV`B6-'UX_``!2:35]>6%A@`*Y<''* +M(8T`RB(-!,H@C0\``"HSXB"-#PC`F!!3)GZ0RB+"`\HA@@/*(((/```L,^(@ +M@@\(P(@03"``H,HD`G3@>.@@H@)/)8`7G[@`$``(!.4$'A`0(""`#PC`Y`SQ +MP"(@@`\(P'P,"'?/<$6`L-OV>!ISH(!(=@(EC1]>/P``4FDU?7EA88`"N7!Q +MRB&-`,HB#03*((T/```J,^(@C0\(P)@04R9^D,HBP@/*(8(#RB""#P``+#/B +M(((/","($$P@`*#*)`)TX'CH(*("3R6!%P06`!2?N0`9(``$Y2`@@`\(P.0, +MSW"CP`!`(!``".!^SW*(P"0@\"("`,]PH@"`*%5XGKB?N``88`#@?L]QB,`D +M(/`A`0#/<*(`@"@U>)ZXG[@`$``(X'[/N)^X +M`!A@`.!^(""`#PC`@"+QP.'%SW"BP``(#!`!".2YT2$A@Q#RSW6(P-PU!H6` +MX,H@@0\``"XSXB"!#PC`?!`&A4!X(""`#PC`_`Q`@#BZ0*E`@#"Z0:E`@"BZ +M0JD`@.!_`ZGQP,]PB,#4$`B(X[@)\L]PJ/Z@#P#9(B"`#PC`<%EI($``X'C1 +MP.!^(""`#PC`Z#/QP,]PB,#4$`F(X[BAP0KRSW"H_A00`-DB((`/",!P66D@ +M``"+<"(@@`\(P#PR@.`2\@#`(B"`#PC`,#//<*#``!TX&*`/!````"(@@`\( +MP)@/!O!I((`!;R$_`,]QB,"8$0"!@N`2]`'8`*$B((`/",#`,B(@@`\(P!"6 +M(B"`#PC`*)9I((`!SW"(P-00"8CCN`KRSW"H_C00`-DB((`/",!P6<]PH,`` +M'308H`\$````H<#1P.!^\<#AQ0AU(B"`#T6`$*4&I:EP(B"`#T6`9*H)I:EP +M(B"`#T6`M)P(I:EP(B"`#T6`+*$+I0#8#J4@((`/",#\#/'`X<4(=0;P(B"` +M#PC`<)6I<"(@@`\(P`26@.#V]2`@@`\(P/P,X'CQP.'%"'4B((`/",`$ED*% +MP-D8N8#@)7H/\H*``!(`"&:%9GAEA65X`!H@``.%)7@`&"`#!_``$@`()H4D +M>``:(``@((`/",#\#.!X(B"`#PC`"'DB((`/",!$EB(@@`\(P'R3]/'@>*/! +M`-@B((`/","83<]Q``$``,]P``$``!!QXB"!#PC`J";/=HC`1#:+=<]WB,"< +M$(#@3@`)`*EP(B"`#PC`N!#/=J#``"!L +M%A`8J7$#A2(@@`\(P$AV$!4&$,]PB,`($P"`!B:!<0````(K>!+TZ7`B((`/ +M",`$E@HE`)#5]>EP(B"`#PC`G)0@((`/",#D#`@5!!#/<,#NA5,,%040`-EL +M%@,8"G(B((`/",#`G.'QSW.(P)021X.`X@GR0H)`H`>#`X``H0'8`O``V.!^ +MX'C/<(C`E!(@((`/",!TE.!X\<`B((`/","$#,]VH,``.!@6#1CSO0GRSW"( +MP)02(B"`#PC`;)8$);Z?!P``@,HA0@/*(((/$``S`>(@@@\(P'P0&!Z@'P\` +M`(`@((`/",#T#.!XSW"(P)02(""`#PC`;);@>/'`JB"0`.&X!O(B((`/",`` +M-`;P(B"`#PC`S#71P.!^JB'0`*HB$`&J(Q``SW`0``<"(""`#PC`F!#@>.!^ +MX'C@?N!XX'\`V*'!\<`B((`/",!\#*'!"'9&P!H4`#$$(($/````@$^Y@>$R +M]"(@@`\(P-@B6B`!"PAUSW!%@`3?Y&AP)T(00""0`5!VRB&"`\H@@@\0``<# +MXB""#PC`B!"+<"(@@`\(P/QS88<(<@6'$(A@>R"'(B"`#PC`\'-:)0T;`-@` +M(%`C`!@$(*'`"-P@((`/",#F#*'!\<`B((`/",!P#*K!*'92P7IP&G)*%``Q +M`-D$(((/````@$^ZBW6!XLH@0@!`]"(@@`\(P-@B6B`/"SIPSW!%@`C?<"<" +M$$`@D@!0=LHA@@/*(((/$``&`^(@@@\(P(@0`8>`X`3T`-@2\`0C@2\``/S_ +M9+D"AR*Y@.`>\@'=*'`B((`/",#$B:EP(8>`X03R(H>`X0GT6B$!*P#:`")2 +M(``:A"`!V@`8@""JP`C<(""`#PC`S@P`V(#ARB1-<.!XZ"`M`\]QH,``#F@1 +M`0@5)0P0(*0!X`6'88<0B""'8'NI``I&@X3P`!@``A(#@]/,`V^"`H.?']TXA#@C"?P'GX*`" +M\""@P(0$@-%P]/4%AH#B9*#`A-[S!8+$H`6&!:+;\0K(!AH8,`SP`=@`H@#8 +M!J)(<"(@@`\(P+1$R7*`X@CR`(+$@A!UB>/'Q*2``!$HF`'`@((`/",#D +M#/'`(B"`#PC`?`P:<(HG_Q]J((`"!""!#____?\I($``2B8`<)AP!A(--@#; +M"/`)R`3E$'6#]PH2#38!XZ#C5_=`A8#B]?-(<0"!3B,,"`(@#@.@X,H@C0/* +M(,X`)($0=\HG!A!04``T`,R;/`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`( +M$0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0"!$`"`0> +M$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$'A`00B5- +MD!#?JO4@((`/",#L#/'`X<6`X*'!R_<(=8MP`=DB((`/",!DFV&]@.4X]Z'` +M(""`#PC`_`S@?N!X`-J`X.@@[0+P((,`SW&@P``%0!G@``'BX'X- +MR`?;#AH8,`T:V##/4$&B``D.5+ +M]TXE/!3@>*@@P`$$&J`/555551`9X`#!Q>!^X'AJ(H`"X[H%\JHAT`(#\*HA +MD`+/675:!?AR6$! +MY3IBSW%&@/@Z(($P=;;W!;@<9$"DP<;!Q>!^X<7AQHATP8RD;+3FUGU+]@2M +M(*5%K6.U`8P!X`&L`=@"\`#8P<;!Q>!^X'CQP"(@@`\(P(`,"',`V`AT`_"I +M<`'D@N12``8`@^,\``T`0">/=C,FPW"(P$P3\"(.`W1_%2$-`P!_`-O@A>1^ +M"_`!V^"%Y7X'\`+;X(7G?@/P`]O2?L"E@.``W07T\"$``X#@U_,!V-;Q(""` +M#PC`[`S@>/'`"B,`@,H@X0P3\H[C!/=):P7P02N"``7B2'`B((`/",#(I!!S +MRB"!`,H@X@S1P.!^X'CQP"(@@`\(P%@,>G"\'$BP`-U$Q87`0<#/<8C`\!40 +MVB(@@`\(P"`.B`#!1,`&L1@3@"`:=8#@RB9,(\HA +M3"/*(DPC``$L`,HG3",[==IU.G5:=?IU%B-`)NB`#I``(-@#"?!,(`"@RB#! +M(P&/`N`?9R)O$W&^``T``8\:81-RL@`-`$"/R.(N\@SV@^+L\XKB'?*MXLPG +M(:#*)\$CZ/'_XB?RC"+"CT#RC")#A^#UZ7"*(0@`JG+)*% +M>R88P@!/>O#Q3"$`H,HAP2.>\4`A63`8$X`@+R%'-C-P%@?)_P#!!,!FD0(@ +MP@!'L0#?"_`$P`00`C$!YP(@@0`&&$0P[W^!YWX!"0#/<8C`@!\@@0/@3\'/ +M<8C`K!\@@8#G4,$`$P$@3\$#P01Y`,!$P14@V`,$&$0P`=ELP0_``-H&]!03 +M`R"`XP/R2'%`)(4@0"1&(%8D!S(!V@#;2B0``B(@@`\(P-RDBG"*(0@`JG+) +M/'`(B"`#PC`?`P(=RAV2'7/<(C`.!4@@`&` +M^!Q(L$'`2'"*(1D/(B"`#PC`0'X$AB"%P+@88`5Y(*4!AL"X`[@E>`"E(X:` +MX0/R@K@`I2*&@.$$\HFX`*4BAH#A"_1#AH#BRB"!#Q``4`+B(($/","($""& +M@.$%;13T)8?`N5=I((5%>2"E`MDDI4`G`1L#VB(@@`\(P"A^"8<"I0J'#O`& +MV22E0"'X:`X`OR`=C(<<]RB,#('R(@@`\(P$2>`-BX<,AQZ7(B((`/",!$ +MGA4=0A$G\`@0`1`R(4`!^'`B((`/","XGAEPZ7`)<2(@@`\(P*"D@.`3\D`E +M!!7H<`IQ`=H`VR(@@`\(P!B>R'`)<0#:(B"`#PC`E*5`)44`5B8(%`00@!"P +M<*P'S?\`V"?P`!`!$$XG@`R`X(*P0AH#@!/0"AS"F#Z83AH#@#/15)D`40"HL`@((`/",#D#$$I0@$`VT]ZQ+D/ +M(T,``-F"XLH@2@!)]O`@@`!D>$(@`(#*(&(`X'ZRX`?WSW&(P-@?"&$"\`#8 +MX'[@>*'!\<`B((`/","`#$3`&7/(<^AU`*42%``Q$!0&,8#A!2"'`0#8`=G` +M>0"K@.+*(F(`!-A6>-)IT7!<``X`&"!\`.!XJ"``"D"+D')(``H`A.9%]T`F +M#Q("\.QN`-@/(,`#$'@+(,"!%?+/=(C`&"``)8$`[&0!X@LF`(#/).(1@*E` +MJQ)Y`)4D>`"U`94D>`&U`>9,(`"0"_(`BY!P2?;_V0`E!0``'4(``>``JPC< +M(""`#PC`[@Q!*4,!Q+D`W(+C#R1,$$SW=7B`XB"`!?(E?.!_@*"&>>!_(*#@ +M?N!X"'(*($"`\<`&\B(@@`\(P!2FA+J=NIZZSW"@P``>0!B@`.!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>-'`X'[@>(#@RB0-<.!XZ""M`>!XX'C@>.!XX'[@ +M>,]QH,``($@9.``(&:`/$````.!^[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X4````X&,```"`18#@?PC@"8#@ +M?@N`X'[QP"(@@`\(P(0,"'7/<(C`U!`1B..X*'8)\L]PJ/Z@`P#9(B"`#PC` +M<%E`)0$,P=`A"AP"`@@`\( +MP,P,X'CQP"(@@`\(P'@,*'<:ERR7,B((`/",!P61HFD1\``*P&J7'/=D:`4`H`)D`4(B"` +M#T6`#(``W^EP(B"`#PC`M)``&,`CZ7`B((`/",!\B58E`1W>'=P3`=C^J=P= +MW!,:J>`=W!,B=A".@.`(\A2-H;@/>*"X#WBBN!2M`=@@((`/",#<#.!X\<`B +M((`/","`#*'!"'7/=T:`["2+=D`G`!7)<2(@@`]%@)"9"/!`)P`5R7$B((`/ +M18#4F8#@'?0@P\]P1H!0"AHC@0\``*P&(&`0=>WUSW"(P-00$8CDN!KRSW"H +M_E0``MFIB'V(S"(A@,PC88`(\L]P$`!)$"(@@`\(P)@0`=],(`"@ +MZ*4*]`#8':VI<"(@@`]%@.2%_:TH\)HF#QH0V,EQ(B"`#T6`.+`*(0"`RB"" +M#Q``2A#B(((/",!\$,]PB,#4$!&(X[@0\@`5!1#/<*C^P`0$V5Z-R7,*)``$ +M(B"`#PC`<%D@((`/",#D#/'`(B"`#PC`@`Q6(`$/?H@(=14AP`"AP>Z)@>-* +MB`'>/8W`?C!RRB""#Q``11#B(((/","($(#F$-@$](#G%/1`P(MQ`=@B((`/ +M18#$KPHA`(#*(((/$`!&$.(@@@\(P'P0,_``V#Z-':T!X2]Y5B4`'CZM-7@4 +MD!H@C@\``.@#$-C)<2(@@`]%@#BP"B$`@,H@@@\0`$@0XB""#PC`?!#/<(C` +MU!`1B..X#_(`%040SW"H_E0$!-E>C,]UB,#4$.J($8WCN!T6A1`.\B`6!!#/<*C^ +M+`4`%@80!=E"AB(@@`\(P'!9'8X!X!VNR7`B((`/18`0B8#@*(84\H#ARB"! +M`^(@@0]%@#R%'8X0=QWTC"?#G\H@@@/B(((/18#DA17P@.$3]!#8BB$/"B(@ +M@`]%@#BP"B$`@,H@@@\0`$<0XB""#PC`?!`1C>.X$O(@%@00SW"H_JP%'1:% +M$`79`!8&$$*&?HXB((`/",!P62`@@`\(P.P,\<`B((`/","$#,]V1H!,"LEP +MSW$``-`:(B"`#PC`0'X`W0'92B0`<:EPJ""`!!H@@P\``*P&1&X!X'IB(Z*E +MHKVJHJ*^JJBBL*JFHL]P1H``)039(B"`#T6`*)K/<46`4(0!V"(@@`]%@.BN +MH*8@((`/",#T#.!X\<`B((`/","$#)H@&@NCP0`@C0]&@%`*^!4`%P#;&B"! +M#P``Z`-]K6*E?JV`X,HF0A#/<(C`U!`1B,HF81'CN&BE#/+/<*C^&`$#V.X0,8,\L]PJ/X@ +M!`+9R7(*SW"(P-00$8CE +MN`ORSW"H_J0.`MD*/'`X<4H=!4@0P"8$JH(""`#PC`_`S@>)80``;@?N!X\<`B((`/",!L#*'!0"`% +M`QIQ2'ER*G,*)<`$(B"`#PC`<%E,(P"@5?(`P0R. +M6B$"!Q!Q6B`/![IBOV`A4*\&""`!C`(``: +M``4,CA!Q!/(`V"KP`H`X/KS$1*`(..X"O+/<*C^A!$`V2(@@`\( +MP'!9#(Y:(`$'N6$B((`/18`\C46'!H=@>B&'X/'/X#?(R)8(?```,`<]PJ/X8 +M$0'9(B"`#PC`<%D`VPC:6B,!!P1M&6%H<"(@@`]%@#R-`>-ANH#B;WLS]R`@ +M@`\(P/P,X'CQP"(@@`\(P(`,"'.!^X'CQP"(@@`\(P'@,"'4*)T"0`!`0`,]QB,#X$P"!(8'X +M'`BPU850%1$00<$,](#F"O*+<4`E`A8!V"(@@`\(P$2>J7!8V2(@@`\(P$!^ +M@.<-](#F"_)`)0$6BW(!V"(@@`\(P$2>U:50'4`4`!T`%*+`(""`#PC`W`S@ +M?N!X\<#AQ<]U1H!,)P"E0"4`'@S9(B"`#PC`0'X`VDRE3:51I01M!=DB((`/ +M",`T72`@@`\(P/P,X'CQP"(@@`\(P(0,`"".#P````E4ABAU4'4#V0GT58:` +MX@?R@>(,\H+B#/(H<`OP-::I<2(@@`]%@#2G!?`"V?GQ`-B`X`OR5(;/I<0R'8'LJI<6![`-K)<"(@@`]% +M@&23@"0:,R`@@`\(P-P,X'CAQ8#B0``L``#;F'(O)`=QX'BH((`&%B'"`%HC +M#0.$BAUE@K6%BH.U@Y*"I8""G&0$)+Z?`!@``("E!/2;O("E`>-O>\'%X'[Q +MP"(@@`\(P'P,H<$(=BAW&G"`(`8KBW4*<*EQ(B"`#T6`D)D'\`IPJ7$B((`/ +M18#4F8#@#_0@P%H@`0W984B!4'?S]0SA(B"`#T6`0(T@P`+P_]BAP"`@@`\( +MP.0,X'CQP"(@@`\(P'P,*'7D:36/"':TX1IR!/:`X0GVSW`0`!$0(B"`#PC` +M?!`5CP2N!8\%K@:/!JX'CP>N!(\(K@*'!*8#AP6F!!``(!A@@+@%MB&%02F` +M`..YP+C/(&(`Y+G/(*(`Y;G/(.(`YKG/("(!Z;G/(&("Y[G/(&(!8(5/(((! +M@./*(((`ZKG/(.(!`Z8`V`:F"!`!((#A!X8#\H"X!Z:%(`$!!Z8$A[@>&!`@ +M((`/",#D#.!X\<`B((`/",!P##IP*'8:`)P<5`!42$.EPBB$=#R(@ +M@`\(P$!^`"&3+P``6`GI<,EQ:G(B((`/18`XD*EV@"8'$J7&`(0\%BB(*"B(@@`\(P"A^42(`H!SR +M6B``+0`A`2!/@>`5`!>`XC41@P`+\H`E!A!U?4Z!')50<,H@)0#"((8`-!&! +M`+D?6!`%\`#8N1\8$+H?&!`$CX#@`-G%]P2/`>$0<;WW(""`#PC`S`S@>/'` +M(B"`#PC`@`PH/'`(B"`#PC`>`P(=RAV&G(Z'EA(B"`#T6`0(UANH#B`>4V]R`@ +M@`\(P/P,\<`B((`/","`#`AUX(#/<0``>`G!@"(@@`\(P$!^J7"`(`8+"-DB +M((`/18`HFL&EX*6I<"(@@`]%@&RI(""`#PC`[`S8<"AS1(,*)8`/18#XC0"` +M"B2`#T6`7(XE@6>#(""`#T6`0)N`X`KR@>`,\H+@"/*#X`CTX'\$V.!_`-C@ +M?P+8`]C@?O'`X<6BP8#@RB3B=.!XZ"#B`,]U1H#P,8#@RB0B<>!XZ""B`(MQ +M0"4`%2(@@`\(P!1_@.#*(((/$``@$.(@@@\(P'`0@<%`)0`5(B"`#PC`S'Z` +MX,H@@@\0`"$0XB""#PC`O*`X2`7$!`8\E4F0!^!P2(@@`\(P,Q^@.`$]`'`@.`)],]P$``C$"(@@`\( +MP'`0`<$"(%`@`=@.IP#:2*=(<0OP`B``!!!U`:,#]X#E`O0(=0'AD^%/]UHA +M``/;8`"#@.#X\TZG`8.`X,P@`H3J]0"#ZO$`P(#@$?)5)D`?(B"`#PC`M'Z` +MX,H@@@\0`"00XB""#PC`/'``-@B((`/ +M18`8E"(@@`\(P*QVT<#@?O'`(B"`#PC`>`R@D*+!J7`B((`/18`@@@AWSW"( +MP-00$8CCN`KRSW"H_G@#`=FI!'P``K`8*((`O +M1H!,"D`@#B$^9@:&@.`>\@#80,"+<1#8.G`B((`/18!XKP#`@.`2]`0<0#2! +MP0'8(B"`#T6`Q*^`X,H@@@\0`$,0XB""#PC`,P=`A`5\#R.F+T0N<]PB,#,-J5Y(B"`#T6`G*J#X,H@@0\0`$00 +MXB"!#PC`@N`.G!H6`X"#R`!(`((#@ +M'/(1$X`@X;@*\L]PJ/Y``@'9R7(B((`/",!P62K!521`*R(@@`]%@(R:R7`$ +MV2(@@`]%@-B#:O``A\"E'7C`N`&E'!U"%$`G`!.I<2(@@`]%@/2))H4`&D`@ +M"B*`+T:`#"4,$H`@`>`/>`P:`B``A\"X`Z4(%P00$1.`(!0=`!'CN!`=0A0, +M\BK#SW"H_IP"`]G)$IJF&X"JH5 +M)L`3_]DEJ"JNH:X);P*N(Z[@KLEP(B"`#T6`P(H@((`/",#L#.!X\<`B((`/ +M",!X#`AUPXB*(<,O,G8:<1/TSW"(P-00$8CCN`ORSW"H_N`.`=D*ER(B"`#PC`<%E5)5(>BW%*<"(@@`]%@%R9@.#*(<(#RB""#Q`` +M`!#B(((/",!\$"#`Q&U:(``''F81$8`@X[A`)!`X#O(D%`0PSW"H_L00",,# +MV>ER(B"`#PC`<%GAID`F`!(*<13:(B"`#PC`*'ZI<"(@@`]%@)",5B40&/_9 +M#!"`(#!P`!2$,"+T#!@"(2"F$1&`(..X#/(0$`(@SW"H_OP1`=DB((`/",!P +M62#`R7$B((`/18`\C1`0`""`X`;T1(8&AF!Z(88`W@OP",.I<,EQZ7(B((`/ +M18`XBPAV@.82\B#!2G`B((`/18",FH#@"O(@PL]P$``!$.EQ(B"`#PC`B!`1 +M$8`@Y;@+\L]PJ/Y4$@'9R7(B((`/",!P6:EP(B"`#T6`D(S)<*'`&-P@((`/ +M",#6#.!X\<`B((`/","$#`AVSW"(P-00$8CCN`KRSW"H_@@1`-DB((`/",!P +M6<]U18#L\LEPJ7$B((`/18#DC*EP(""`#PC`]`SQP"(@@`\(P&P,*'>H@`HD +M@"^(P-00$12`(%8E#ACCN!IR#O+/<*C^>!(#V>ER;(X*)``$(B"`#PC`<%FI +M<"(@@`]%@)",+(Y`)1$16B$`!XCA`"$3(,HAR@/*((H/$``"$.(@B@\(P'P0 +M!!,"(%!WRB'"`\H@@@\0``,0XB""#PC`B!`DAH#ARB""#Q``&A#B(((/",!\ +M$``3`"`,%I(0#WM,(`"@#*X#\@'8!*8`$P(@BB##+Q)R$12!(!_R!(:`X!WT +M6B,/!^.Y(G<,\@07!!#/<*C^W!(#V4IR(B"`#PC`<%D,CNEQ(B"`#T6`/(U$ +MAP:'8'HAAPOPX[D)\L]PJ/X\$P#9(B"`#PC`<%D`&P`D525`'DIQ(B"`#T6` +MC)H*)@"0RB&"!,H@@@\0``00XB""#PC`?!"I<"(@@`]%@)",R7`@((`/",#$ +M#/'`(B"`#PC`:`P@$!``*'=6(!$H2B0`(`P1C2!`(!4A6B4.%PIP(B"`#T6` +MD(Q`(!(ABB/#+W)U0G83],]PB,#4$!&(X;@+\L]PJ/YD$P'9Z7(B((`/",!P +M60'>A_`!AA!W0?(*(0`E!O!`(5$@+R%')(IU3"$`HKH`"@``AG)PRB'!`\H@ +M@0\0``40XB"!#PC`?!``%I006B0.)T)V`880=^7USW"(P-00$8CCN`SR8(;/ +M<*C^`!0"V:ER(B"`#PC`<%F*<,EQ(B"`#T6`/(U:)0T7`(8`)54C`!T`((IU +M'O#/<(C`U!`1B..X"_+/<*C^L!,"V:ERZ7,B((`/",!P6:EPR7$B((`/18`\ +MC1`1`""`X`GR((8,&4(@`![`%`'8"'8)\$6&!H8AAF!Z`MX"\`'>`-B`X!3R +M52!`+JEQ(B"`#T6`C)H*)@"0RB%"`\H@@@\0``80XB""#PC`?!`*<"(@@`]% +M@)",R7`@((`/","\#/'`(B"`#PC`A`P(@%8@#0A,C03@6B(.!QYFSW"(P-00 +M$8CCN`GRSW"H_D`4`=DB((`/",!P602%@.#*(($/$``;$.(@@0\(P'`0`-@$ +MI0R-C"##CP7R1(8&AF!Z(88@((`/",#T#.!X\<"AP<]P18`@W"(@@`]%@`"` +M`8"+EP(B"`#T6``(``W@AU0"`' +M`\]P18#$XT#`SW!%@+SC0<#/<$6`P.-"P,]P``"O#039!]K)BB$(!B(@@`\(P$!^Z7"C +MP"`@@`\(P.P,\<#/<46`(-PH<"(@@`]%@`"`"'(H<"(@@`]%@#"+@.`)\D`B +M``,"V0#:(B"`#PC`-%W1P.!^X'CQP"(@@`\(P(`,*'?/=D6`(-S)<"(@@`]% +M@`"`"'7)<"(@@`]%@#"+@.`I\L]P18!\W@S:(B"`#PC`*'X`AV&X@^`Z``T` +M,R8`<(C`[!-`)P%S%'D@>0SEJ7`&V0KP`88`VB2&(B"`#T6`^)RI<`79`-HB +M((`/",`T72`@@`\(P.P,X'CQP"(@@`\(P(`,I<'/=D6`(-S)=^EP(B"`#T6` +M`(`4V0AUBW`B((`/",!`?@;:0,(`VT'#"B2`#T6`(*,('``Q"B6`#T6`_*(, +M'$`Q(85$Q\FYQW':``#P(J4!AMAW(B"`#T6`0)NEP"`@@`\(P.P,\<`B((`/ +M18``@`P0`02`X039RB'A``#:(B"`#PC`-%W1P.!^\<`B((`/18``@`'9#.`` +MVB(@@`\(P#1=T<#@?O'`(B"`#PC`A`PH=B(@@`]%@`B`"'$B((`/18``@`AU +M*'`B((`/18`PBX#@%?)`)0`>R7&*(@@&(B"`#PC`*'Z&%@`6`-D!I4`E`!,H +M/'`(B"`#PC`@`RCP<]W18`@W.EP(B"`#T6` +M`("+=0AVJ7#/<8C`9!4,VB(@@`\(P"`.EQ<`%@S90,"8%P`6J7)"P`&&`=M! +MP/_8`*:WV"(@@`\(P"QMH\`@((`/",#L#,]P18`@W"`@@`]%@`"`X'C/<$6` +M(-P!@+[9`-I(R7$B((`/",#T#8HA"`8:<(MP6G`B((`/",!`?AB/`1Q"-&#`&H]> +ME0(<`C`?E08/;S&6"&(7\,3R$"```;`"`$'(0P4X6&P%8E@1)%PB(@@`\(P"A^!!,` +M(&'9BB((!DIS(B"`#PC`X'.`)`@V(""`#PC`Q`S@>/'`X<7/=4:`]"8`I0#8 +M%*6I<`'9(B"`#T6`1(VI<"`@@`\(P/P,X'CQP"(@@`\(P'`,I<%Z<"AU(B"` +M#PC`<"X(=@"%X;@`V0CRR7`B((`/18!$C<4!``#BN`7R$H:`X`/R*'<#\`'? +M\J8`A>*X"/(2AH#@!/(`V!*F`=\`A>BX!_(!A2&&$'$#\@&F`=\`A>FX"/(" +MA2*&$'$$\@*F`=\`A>JX"/(B%8`0+(X0<03R#*X!WP"%[K@#\@.%"*8`A>^X +M"_)`)@`90"4!%P;:(B"`#PC`*'X`A?"X!/(!V`NF`(7QN`/R`-@+I@"%\K@' +M\@6&@>`#\@'?Y:8`A?.X"/(%AH#@!/(`V`6F`=\`A?2X!O($AH'@!/(!W^2F +M`(7UN`?R!(:`X`7R`-@$I@'?`(7KN!3R0"8`'$`E$!0*<0S:(B"`#PC`*'Y` +M)@`?"G$,VB(@@`\(P"A^`(7KN`KR0"8`'T`E`10,VB(@@`\(P"A^`(7MN`7R +M(Q6`$"H>`A``A00@@(\`_```+?(UAH#A*_1!*)$&0"80%@+8"G$*3"$`H`#8V_I<$S9(B"`#PC`0'X$;2S9(B"`#PC`0'[/ +M<$6`\.1`P,]P18#@Y$'`SW!%@.CD0L``V`;9"-H(1!QO/8`@RV#(B"`#T6`W*W1P.!^X'C/<$:` +M3"<@((`/18"\C>!X\<#/"B<`D!+R@N?*(<(#RB""#Q``%Q#B(((/",!\ +M$!KP`M@5H0#8(/#)<(`@!@L*<2(@@`]%@(R:`M@"'`(P6B``+1EFV&!E@`R! +MJ7%@>RIRR7`B((`/18!DD^EP(B"`#T6`^).CP"`@@`\(P-P,X'CQP"AR(B"` +M#T6`!(`(<__8(B"`#T6`0(UH<$AQ(B"`#T6`P*O1P.!^\<`B((`/",!X#`AU +M0"`0`RAV`-_\',JS)8$B((`/18#8CXP@PX_*(((/$``2$.(@@@\(P'`0.G6` +M(08KBW$J<"(@@`]%@%R9@.#*(((/$``($.(@@@\(P'`0(,!:(`$-`G$B((`/ +M18!`C2#`R7%:(``-*-H"<"(@@`\(P"A^(,#)<5H@``VX8.^@[J`T&,(#-1C" +M`ZEP(B"`#T6`U),*)@"0"/(@P2IP(B"`#T6`C)JI<"(@@`]%@&23R7`B((`/ +M18#XDZ'`(""`#PC`W`S@>/'`(B"`#PC`8`P(=2AV&G(`()4/````"505%B!0 +M%10@(B"`#T6`9),$V50=0""I<,EQ(B"`#T6`V(]:<(P@PX_*(8$#RB"!#Q`` +M"Q#B(($/",!\$`"%R7$!VCIR(B"`#T6`^)Q:(@\M>G"_9RJ'@.$`V`7R28>` +MXC7T^G"`X0#8"?(IAX#AS";AH,PF`97*(&$`@.`$\@_9`AA"($PG`*`&]&6' +MR7$,AV!["G),(P"@-/1,)P"@'O(\'T`4`1"`($`G`1,T'P(0`!"`(#4?`A`$ +M$``A#J>I<"(@@`]%@-23+?!,)L"@S"8!EEQ8'L*`! +MV!2J`MDUJ@39-JI.'1@0(B"`#T6`&)0@((`/",#\#/'`(B"`#PC`@`P(=BAW +MJ6B$Y(#EX*`7\H'E)O*" +MY0SR@^4E\L]P$``K$,EQ(B"`#PC`?!`0\"APP-DB((`/",!`?@CP5B$`!@S9 +M(B"`#PC`0'X`V"(@@`]%@(B4`-@@((`/",#L#%4AP`SO\58AP`;M\?'`(B"` +M#PC`A`P(=BAUD^#*(88#RB"&#Q``+Q#B((8/",!\$%HF#A//<$:`$#'`8(#@ +M`=C`>`"E`-@B((`/18`8E`#8(""`#PC`]`SQP"(@@`\(P'P,&G&`X%0`+@`` +MW14@3R,@AY/A"'9*]UHA``//4`V"(@@`]%@(B4`-@@ +M((`/",#D#/'`(B"`#PC`A`P(=<]P1H`T,JI@D^4H=E#W6B4`$\]Q1H`0,0!A +M@.`(\L]P1H#P,?`@@`"`X`OTSW`0`"T0J7')/'`(B"`#PC` +M?`P:<8#@RB0-<.!XZ""M`(#@B``N``#?6B<-$PAVSW!&@#0R`G4BA9/A*F!3 +M]UHA``//<`V"(@@`]%@(B4`-@@((`/",#D#/'`(B"`#PC` +M=`R")`4Q5B2`.<]QB,!4%1#:(B"`#PC`(`X`V"(@@`]%@!B4SW5&@!`Q525` +M'U8D`3HB((`/",`4?X#@RB""#Q``)Q#B(((/",!P$%`4`#:`X,H@@@\0`"@0 +MXB""#PC`:3YJH'Q?\`WB#P%22`,TP0#0:`Y1GR3-P:)@`3BW'/=T:`D#'5 +M?P`A$``9AX#@RB"!#Q``,!#B(($/",!P$%F'J7!@>@IQ`>:$YL('Q?\!V"(@ +M@`]%@(B4@"0%,2`@@`\(P-0,(`(`````(0(`````(@(`````(P(`````)`(` +M````)0(``````````$")",````````````````"PB0C``````/2(",`````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````#__P`````&`P```````P`#`````&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$````P4PC``````&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````8!((P`$```!H$@C``0```&Q6 +M",``````K%8(P``````T5@C``````&@2",`!````5%4(P`````!@$@C``0`` +M`/1/",``````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```#X5`C``0```-A6",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````#%`(P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````5$\(P`````"$3PC``````&@2",`! +M````M$\(P`$```!H$@C``0```%A5",``````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!````O$\(P`````!H$@C``0```&@2",`!````:!((P`$` +M``!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!(( +MP`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!```` +M:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C``0```&@2",`! +M````:!((P`$```#X2@C``````&@2",`!````:!((P`$```!H$@C``0```&@2 +M",`!````:!((P`$```!H$@C``0```+P1",``````:!((P`$```!H$@C``0`` +M`&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H$@C` +M`0```&@2",`!````:!((P`$```!H$@C``0```&@2",`!````:!((P`$```!H +M$@C``0```&@2",`!```````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````6P$```$```!'`0```0```'P!```!```` +M1`$```(```!Z`0`@````X$8!`"``````:`$```0```!(`0``"``````````` +M````9`$```0```!P`0``!````%`!```(``````````````````#1P!%L)AM`1@'DT[ +MFA#1OWMZR()DJ-L;GQEBIN9H[A^ZS%KH6MG.(:=CV\&$V<0:'I[5@L7;]O#+S6])Q;O +MTUZ`@Q9O#\ZQZUROU1XL3>@GIX0A'ZLQS3.]EM]`#)-:.@LH#44.K^C\7[\` +M!P3DY4F9W;8[]70ZRI8T>H?6RDC +MG3OM8]KY^9H/)$3]O$5['3+-!42\;3H\N4%4NWFZP"!+^@".4X::FI?O()\K%`0````<` +M```($````````0`0```4````!!````````'^RO[*[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>%0```+P"````0$``!@```*$` +M``````$``````(:````#!Q8@`,\!`$````!``````0````2$!0`````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````#5=]&\2NV-R6,E:!.; +M@`)Y'`$6PF&T!&`>33N:$-&_>WK(@F2HVQN?&6*FYFCN'[K,6NA:VN1N[6T([:05*G@))1.*9)JI\0*8VUH15!M/]Y!H +M>GM6"Q=OV\,O-;TG%N_37H"#%F\/SK'K7*_5'BQ-Z">GA"$?JS'-,[V6WT`, +MDUHZ"R@-10ZOZ/Q?OP`'!.3E29G=MCOU=#K*EC1ZA];*2-P\8N4`RN]>A?B( +M[N8``2@:XKO1L^2P;EZ=.^UCVOGYF@\D1/V\17MS)_)MBCMA<(_(]IW#NB"* +MDW'NC3(TEK*",%-%'Z%K5'S1`0`!`.>+%K6F37\U^9E`>'!)%___X-7O6I97 +MD4NV13&4P!#LWVD8S&'.FMI2'UZP<'%C]>+TDRV6Q+.4]M.`'T=RB]V3C^/< +M?\QG%?)AMS)!EUA!XK%"(&K/27HI@GH%"#-:2S!$&;:_<\FID;,-Q6C0813- +MQ=WZ`B,^\1Q26HZ6]GBS\671Y3T-QCS#H,'Q`L`XY8Q``/,7YC=@:=)4,PRE[9V+=KT +M+9H845N_FJ<#````!P````B``0```(```(`!``<````(``4`````````!0`' +M````4+D```"`1`!(N0``%0````2``0```(```````!8````$A`4```$````` +M``#,UH``)"B``$#\@`#$\X``E!2``(!P@0`````````````````````````` +M``````!L(,`0#QL)(MP=P!`*`!M`(``;;@P``&&``!MN0```80`!&VY3``!A +M``(;;F,``&$`!!MN?@``81``&VX!``!A@```87L``&$``!LD(``;)>0=P!%( +M">$8'P`(8@``&R4!`!LD```%)0$`!20`"`4Y`0`%8H@@P!$"``4D``@%.0$` +M!6*,(,`1!``%)``(!3D!``5BD"#`$0@`!20`"`4Y`0`%8I0@P!$0``4D``@% +M.0$`!6*8(,`1(``%)``(!3D!``5BG"#`$4``!20`"`4Y`0`%8J`@P!$```@E +M```()$@)X1E$">$9%`G`$@$`&W`*``!A#QP=(@0`'28D"<`2`1LC(N@=P!`! +M`"-P`0``81$`&S`!`!LPZ!W`$;H/`&$``!LD@``;)>0=P!$(`%]P"0``8=`( +MP!(`"1LHS`B`@0``P!?4",`2``D;*,@(@($``,`7K`\`80=P!$(`%]PH`\`80``!27B!`4D +MU`C`$@`)&R@`!1LIW`B`@0``P!?0",`2``D;*``%&RG@"("!``#`%Y,/`&$` +M`!LD``(;)>0=P!$(`%]P#```8>P?P!#__QLS[!_`$<[N#26"F0TD#PTW(FP@ +MP!`/&SP?P!```!LQ[!_`$<[N#26"F0TD#PTW +M(FP@P!`/&S/@!)/_``24``1,Y#Q,!(AP)P!(``1,XZ!W`$0$`4B1X1<`0`0`3<`P``&$( +M`%@PV![`$`H`$T`"`!-N!```80$`""0```@E1`GA&0$``&$`@%@P"`!D,0`` +M`&$(`%ANXP\`80``$R4``!,D)!#`$0"`$R0``!,E.!S`$9@+P!(!`!-P!0`` +M80``$R4``!,D```A)0``(202``!A```3)0,`$R0``"$E$@`A)`]$`"(*``!` +M``$`<`0``&'^_Q,R`@`P`O`$@0`S1%\"\`2"`#-$8`+P!(``,T1B`O`$O`> +MS1&,"\`2,"G-$0]$`"(*``!``$``<`@``&$``!,E`@`3).P!,B!`#* +M$0```20```$E!```80]X$R(``,81`P`!)````24/10`B`%P`.>__`#(7``!D +M`(`3)`$`$R4X',`1#W<3(N`@=P!`/$P@=P!!P^`$D +M__\!)0`!$SD/$P$B%`G`$@`!$SCH'<`1`0!2)'A%P!`!`!-P`@``80@`9#'C +M#P!AE`O`$@$`$VYG``!ASNX-)0&`#20/#30#("!``#`%P\4 +M%2(0`!4F!@`3)%!$Q!$``!,D<$3$$0``%20````A```;)0``&R0!`&1N`0`; +M)`(`9&X"`!LD!`!D;@0`&R0,`!MB#QL+(@\+8R(!`!M``@`;00```&$``!LE +MJ`R`@0`;&B@``,`6```;)0(`&T```!MQ#V1C(@``'20````A[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMW@`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````T`<``````````````0$!`0$!`0&]'P``8RX``/____\` +M``````````````````````````@````````````````````````````````` +M``````````````$````````````````````!```````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`#,P```1$```````````````"B@````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````1`"`````````````)````"@` +M```L````,````#0````X````/````$````!$````2````$P```!0````5``` +M`%@```!<````8````&0```!H````;````'````!T````>````'P```"````` +MA````(@```",````D````)4```"9````G0```*$```"E````J0```*T```"Q +M````*@```#H```!*````6@```&H```!Z````B@```)L```"K`````@````0` +M```&`````P````L````3````&P```",````K````,P```#H```!"`````0`` +M```````$````!0``````````````````````_P```/X!```"_P```_\``0#_ +M`0`!`@$"`O\"`/\#`@#^!`(``_\````````````````(Z```"@````0````8 +MVH``````````````````'.@```H````$````&-J````````````````````` +M```````````````````````````````````>````'H@>B%H```!6````5HA6 +MB`(!``"J````JHBJB/X!``","@``5(Q4C*0?`````/\```$`_P```_\```;_ +M```)_P``"O\!`/\!`0$!`0$``O\!`@/_`0$&_P$!"?\!``K_`0#^`@(`_P," +M`@0#`@`%_P(`"/\"`P;_`@`)_P("`_\"``K_`@#^!`,`_P4#`@?_`P`)_P,# +M`_\#`P;_`P`*_P,`_@8```````````````!HF```"@````0````8VH`````` +M`````````````)D```4````$````&-J````````````````````````````` +M````````````````G,,D!`"3$`0``0#`)@'`P!,!0,`$`4#`+P$`P``"`,`*`^``(#U +M@``>````+))$``$`````````2I)$```````````````````````````````` +M``$````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````\&P$`!0```@0````8VH`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````"````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````/\```$#_P``"0$```K_``,$`@```/\``/X#`0#_ +M!`$!"04!`0H%`0`!_P$#!`(!`0+_`0$(_P$``/\!`/X&`@#_!P(""0@"`@H( +M`@('"0(``?\"`0/_`@,$"@("`O\"```+`P,)#`,#"@P#!`4-`P,"#@,```\$ +M`/\0!`0)$00$"A$$`@;_!`("$@0$"/\$``#_!`#^$P```````````````%SS +M```*````!````!C:@`````````````````!D(P``"@````0````8VH``C'L` +M``A\``"0(````'P``)#R``#T\@``W/(``.0@``#\(0``="$``,0@``#X(0`` +MO"```+`@``"T(```N"```+3?```0X```Y-\``-S?``#_________________ +M____!````/_______________P,```#_____``````````#_____```````` +M``#_____```````````#````$`````,```#_````_P```/\```#_`````P`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````&0```!D````9````&0```#(````D`$``.@# +M``#0!P```/\```````````````0!`@(````',%1XG:4````````?`-#_```` +M``````#0_Z#_```&9``&!@8``````/K]_`#T^?D```````````(````#```` +M!0``````T/^@_P``T/^@_P``T/^@_P``T/^@_R$A(2$A(2$A(2%(2$A(2$A( +M2$A(5E965E965E965G%Q<7%E8'=T<7%(2$A(2$A(2$A(@&"`8(!@@&"`8``` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````````"@$! +M`0$!```("G')OKP````````````````````````````````````````````` +M``````````````````````````````````````````#_?P```````/]_```` +M````_W\```````#_?P```````/]_````````_W\```````#_?P```````/]_ +M````````_W\`````````````_W__?V`>@`!@'H``8!Z````````````````` +M````_W\``````0````````````````````````!8`"@`6``H`#```````-#_ +M6``H`$@`*`!(`"@`.``,````T/](`"@`4``@`%``(`!H`$@`*``(`%``(`!0 +M`#``4``P`&``.``H``@`4``P`$@`*`!(`"@`:``X`"@`!`!(`"@`6``H`%@` +M*`!@`"@`*``@`%@`*`!(`"@`2``H`&``*``H`!@`2``H```````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````#^RJVK```````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````$`````"0`0```*``$"<` +M`.@#``#H`P``L)H``$2:``!`F@``G)H``.C+`@`XS`(`',P"`&#+`@"8RP(` +M+,L"`"3,`@`!`````````````````````````````````````T```!0````` +M`0```````)PF@````````````````````````````$0P`@`*````!````!C: +M@```````````````(``````````````````````````````````````````` +M```````````````````````````````````````````````$```````````` +M````````````````^#`"``4````$````&-J````````````````````````< +M,@(`!0```@0````8VH``````````````````-#,"``4```($````&-J``,!1 +M@````````````````````````0`````````"```````````````````````` +M``````!G12,!!0````("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(" +M`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(" +M`@("`@("`@$"`@("`@("`0$"`@("`@("`@("`@("`@("`@("`@("_P```!`" +M```````````````````````````````````X(X$````````````````````` +M``````````````````````````````````$````````````````````````` +M``````````````````````````````````````D````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````/__________________________________________```` +M````````````````````````````#0T-#0X.#@X.#P\/#P\0$!`0$1$1$1(2 +M$A(3$Q,3%!04%145%186%A<7%Q@8&!D9&AH:&QL;'!P='1T>'A\?("`A(2(B +M(R,D)"4E)B8G)R@H*2HJ*RLL+2TN+R\P,3(R,S0T-38W.#@Y.CL\/3T^/T!! +M0D-$149'2$E*2TQ-3E!14E-45E=865M<75]@86-D9F=I:FQM;W!R='5W>7M\ +M?H""A(:(BHR.D)*4EIB:G9^AHZ:HJZVPLK6WNKW`PL7(R\[1U-?:W>#DY^KN +M\?7X_/\```!1T`_2"](!T`;2!](=TA72#-(5T1/1$M$0TA'2%-$-TA#1$=$( +MT@G2"1$1$0[2`.``RA+2$])0T`1#`41PT@_0!M````````````````````$` +M```"`````@```$7@```)X```"N```$;@```7X```&.```$?@```HX```*>`` +M`#C@```YX````(@!`&)B8F)B8@```)P!`&=G9V=G9P```)`!`&1D9&1D9``` +M9F9F9F9F```````````````````````````````````````````````````` +M`````````````````````````.1N```%````!````!C:@`#4;@``W&X``(QO +M``#8;@``X&X````````````````````````````````````````````````` +M``````````````````````````````````````"D``0`!0````0````8VH`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``#,&P````#(&P````!`'`````!,'`````!0'`````!4'`````!8'`````!< +M'`````!@'`````!D'`````!P'``````('`````!H'`````!L'`````!$'``` +M``!('``````0'```````'`````"8'@````"<'@````"D'@````"H'@````#` +M'@````"X'@````"\'@``````'0`````@'0````!`'0````!@'0````"`'0`` +M``"@'0````#`'0````#@'0``````````````````%``````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````!````````````````````@`8```#_`P!L +M"````/\%`/@&````_RT`U`8```#_/0`H!@```/\$`$P&````_R4`H`8```#_ +M/`!@=0(``/_=`(@'````_TP`5`@```#_(@`("(D)F;H:4````````````````````````````````````` +M`````````````````````````````````````````````````````````0`` +M``(````#`````````/\```#_````_P```/\`````````X;ZMW@`````````` +M`````#",`@`&````!````!C:@`````````````````#LB0(`!0```@0````8 +MVH``_P`!`P0%!@<(`@```````````````````)<"``4```($````&-J````` +M`````````````````````````````````````````````/\`````````&$8` +M````($8`````)$8`````@$8`````A$8`````B$8`````C$8`````D$8````` +ME$8`````F$8`````G$8`````H$8`````P$8`````Q$8`````R$8`````S$8` +M````T$8`````U$8`````V$8`````W$8`````X$8`````Y$8`````Z$8````` +M[$8`````\$8`````]$8`````^$8`````_$8`````%$8``````$<`````!$<` +M````"$<`````#$<`````0$<`````1$<`````?$<`````@$<`````A$<````` +MB$<`````D$<`````E$<`````F$<`````H$<`````I$<`````J$<`````I$8` +M````!$8`````"$8`````#$8`````$$8``````$8`````,P``````8!P````` +M9!P`````:!P`````;!P`````!P`````@!P`````B!P` +M````C!P`````D!P`````E!P`````F!P`````G!P`````H!P`````I!P````` +MJ!P`````K!P`````L!P`````M!P`````N!P`````O!P`````P!P`````Q!P` +M````R!P`````S!P`````T!P`````U!P`````V!P`````W!P`````J!T````` +MN!T`````O!T`````P!T`````Q!T`````R!T`````S!T`````T!T`````U!T` +M````V!T`````W!T`````X!T`````Y!T`````Z!T`````[!T`````\!T````` +M]!T`````^!T`````_!T`````9!\`````[!\`````=!X`````1!\`````@!\` +M````A!\`````B!\`````C!\`````D!\`````E!\`````F!\`````G!\````` +MH!\`````I!\`````J!\`````K!\`````L!\`````Y!\`````\!\`````]!\` +M````_!\`````1@````````````````````````#@'`````#D'`````#H'``` +M``#T'`````#X'``````,'0`````8'0`````L'0`````P'0````"<'0````"@ +M'0`````P'@`````T'@`````X'@`````\'@````!,'@````!0'@````!4'@`` +M``!8'@````!<'@````!D'@````!X'@````!\'@````"$'@````",'@````"0 +M'@````"4'@````"8'@````"<'@````"@'@````#`'@````#$'@````#0'@`` +M``#4'@``````'P````#@'@`````$'P````#<'@````!T'P````!X'P````!\ +M'P````#X'P`````J`````````````````````P```!\````````````````` +M```0````2TM+2TL````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`0`````````````````````````````````````````````````````````` +M````````````````````_P`````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````_/``````` +M`````````````P````````#_```````````````````````````````````` +M``````````#__P`````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````@````````````````````````````` +M````````````````````````````__________\```````````````#\C@`` +M"@````0````8VH`````````````XE```Y)4``(B4``"0DP``%)8``*B5``#D +MDP``1),````!`````00!`0$``@$!`0,!``('`0$$!`$!!04!`@/_`@$!!@(` +M`@>($P`````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````````/__ +M__\````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````(`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````/____\````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````(`````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````/____\````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````(`````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````/____\````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`(`````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````/____\````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````(`````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````#_```````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````)SJ@``LZ(``G.J``.CO@`",ZX``5.J``'CO@`!4 +MZH``(.N``)SJ@`#_____`````/____\`````_____P````#_____```````` +M```/`#\``0````\`/P`!````#P`_``$````/`#\``0````\`/P`!```````` +M``\`/P`!````#P`_``$````/`#\``0````\`/P`!````#P`_``$````````` +M#P`_``$````/`#\``0````\`/P`!````#P`_``$````/`#\``0`````````/ +M`#\``0````\`/P`!````#P`_``$````/`#\``0````\`/P`!``````````\` +M/P`!````#P`_``$````/`#\``0````\`/P`!````#P`_``$````````````` +M````!``)``T`$0`6`!H`'@`B`"8`*P`O`#,`-P`[`#\`0P!'`$P`4`!4`%@` +M7`!@`&0`:`!L`&\``%[`7X!@0&$`8@!ZP'M`?`!\P'V`?@!^P'^`0$"`P(&`@D"#`(.`A$" +M%`(6`AD"'`(>`B$")`(F`BD"+`(N`C$"-`(V`CD".P(^`D$"0P)&`D@"2P)- +M`E`"4P)5`E@"6@)=`E\"8@)D`F<":0)L`FX"<0)S`G8">`)[`GT"?P*"`H0" +MAP*)`HP"C@*0`I,"E0*8`IH"G`*?`J$"HP*F`J@"JP*M`J\"L@*T`K8"N0*[ +M`KT"P`+"`L0"Q@+)`LL"S0+0`M("U`+6`MD"VP+=`M\"X@+D`N8"Z`+J`NT" +M[P+Q`O,"]@+X`OH"_`+^`@`#JP`````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````````&2= +M```%````!````!C:@`````````4``'(!``"H`@``!`D$"0$&"0P1`0`````` +M``````````````````````````````````````````````````````#^RJVK +M`!P`````!!P`````"!P`````#!P`````*!P`````2!P`````3!P`````4!P` +M````4!P`````?!P`````*#@``````$P`````!$P`````"$P`````#$P````` +M($P`````)$P`````*$P`````0$P`````1$P`````8$P`````@$P`````H$P` +M````P$P`````Q$P`````R$P`````S$P`````X$P``````$T`````8$T````` +M`"0`````S"8`````W"8`````Q"8`````("0`````-"0`````F"4`````G"4` +M````H"4`````I"4`````J"4`````K"4`````Q"4`````R"4`````U"4````` +MV"4`````W"4`````X"4`````Y"4`````Z"4`````["4`````\"4`````!"<` +M````&!``````+!``````0!``````3!``````C`T`````E`T`````G`T````` +MP$0`````Q$0`````R$0`````S$0`````T$0`````U$0`````V$0`````X$0` +M````Y$0`````Z$0`````[$0`````^$0`````_$0``````$4`````)$4````` +M*$4`````+$4`````1$4`````8`@`````"`T`````$`T`````%`T```````T` +M````!`T`````B#``````50`````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````$XH@`!,"*``2`B@```` +M```T"H``````````````````=1,N$^@2HQ)?$AP2V1&8$5@1&!':$)P07Q`C +M$.@/K@]U#SP/!0_.#I@.8@XN#OH-QPV4#6(-,@T!#=(,HPQU#$<,&@SN"\(+ +MEPMM"T,+&@OQ"LD*H@I["E4*+PH*"N4)P0F="7H)5PDU"1,)\@C1"+$(D0AR +M"%,(-0@7"/D'W`>_!Z,'AP=K!U`'-0<;!P$'YP;.!K4&G0:%!FT&508^!B<& +M$0;[!>4%SP6Z!:4%D`5\!6@%5`5!!2T%&@4(!?4$XP31!,`$K@2=!(P$?`1K +M!%L$2P0\!"P$'00.!/\#\`/B`]0#Q@.X`ZH#G0.0`X,#=@-I`UT#4`-$`S@# +M+0,A`Q4#"@/_`O0"Z0+?`M0"R@+``K8"K`*B`I@"CP*%`GP"L!Y`'=`=8!T`')`<(!``````-` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```N`"H`(``````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````-L0CDB;D`(+````````,P``````````````````````2P-+`TL#2P-+ +M`TL#2P-+`TL#2P-+`TL#2P,````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````H*"@H*"@H*"@H*"@H`"@H*"@H +M*"@H*"@H*"@`*"@H*"@H*"@H`"@H*"@H*"@H*``````````````````````` +M```H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H`"@H*"@H +M*"@H*"@H*"@H*"@H*``````````````````````````````````````````` +M`````"@H*"@8*"@H*``````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````"@H*"@H*"@H*"@H*"@H```````````````````` +M```````H*"@H*"@H*"@````````````````````````````````````````` +M```````````H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H +M`````````````````````````"@H*"@H*"@H*"@H*"@H*"@H*``````````` +M```H*"@H*"@H*"@`*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H +M*"@H*``H*"@H*"@H*"@`*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H +M*"@H*"@H*``H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````%94```X`````````%ID```^```` +M`````&JD```^`````````%JD```^`````````%JD```^`````````%ID```^ +M`````````%I4```^`````````%JD```^`````````%ID```^``````````H@ +M```^`````````%ID```^`````````%ID```^`````````%I4```^```````` +M`%ID```#`````````%JD```#``````````H````Q```````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M,#```````````````0`````````!````/Q`````````````````````````` +M````!0`%````````````````!`@``0``!00!``$$``0%``````$``0``!P$` +M`````````P@```````0%```+```!```!````````!`0`````!```````!``` +M``$`````````````#````0`$``X```````````````0````````````````` +M```$```````````$```````````````!````!0````````````0````````` +M```````````````!```!````!``!!```````````"00```````````4````` +M!`0````````````````````````!``P&```````````````````,```!```` +M````````"@`````,``````4````````$``````````````0$!``````,```, +M!```````!```````````!`4`!0$%``````````4``0``!```!`$````````` +M```%````````````````!``````````````````!`````0`!!0``#00````` +M````!``````!``4````````````````````````````````````````````` +M````````!```!``.``4````%``````0!``0`!``````````````````````` +M```$```%```````/````!``!```0```!!````````````````````````@`` +M`````0```````0``````````!0`````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````0````````````````````````````,```` +M```I*?____\````````````````````````````````````````````````` +M```````````````>`0``+`L````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````0`````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````J%```*$@``"9X```&M```!.````(0`0``0`$`!HP` +M```8`0``&`$``!@!```8`0`J%```*$@``"9X```&M```!.````(0`0``0`$` +M!H@````8`0`*5`@`"(0```:T```$X````A`!``!``0``&`$``!@!```8`0`` +M&`$``!@!`&,`````@`0`Q@```,88!P!`0!4`8P$``,8!```*-```"&@```:X +M```$Y````A0!``!``0`&B````!@!```8`0``&`$``!@!```8`0`*-```"&@` +M``:X```$Y````A0!``!``0`&B````!@!```8`0``&`$``!@!```8`0``&`$` +M`!@!```8`0``&`$``!@!```8`0``&`$``!@!`$(`````````I0```*64`@!` +M0!4`0@```*4````*/```"&P```;````$]````B0!``!0`0`!@`$``4P!``3` +M````&`$``!@!```8`0`*/```"&P```;````$]````B0!``!0`0`!@`$``4P! +M``3`````&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$` +M`!@!``(`````````!@````88``!`0!4``@````8````:````&!@``!9(```4 +M>```$K````;@```$&`$``DP!``"``0``&`$``!@!```8`0`:````&!@``!9( +M```4>```$K````;@```$&`$``DP!``"``0`(<```!JP```38```""`$``#@! +M```8`0``&`$``!@!```8`0``&`$``!@!`(0`````````"`$```@A!`!`0!4` +MA`````@!```:"```�``!9D```4E```$L0```8(`0`$.`$``F0!``"4`0`` +M&`$``!@!```8`0`:"```�``!9D```4E```$L0```8(`0`$.`$``F0!``"4 +M`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@!```8`0``&`$``!@! +M`(0`````````"`$```@A!`!`0!4`A`````@!```````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``$````@`````P```.D`Z0`````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````,_O__`0```-+8 +M``#2V```+F?__RYG__\0````TM@``-+8```N9___+F?__Q````#2V```TM@` +M`"YG__\N9___$````-+8``#2V```+F?__RYG__\0````TM@``-+8```N9___ +M+F?__Q````#2V```TM@``"YG__\N9___$````-+8``#2V```+F?__RYG__\0 +M````TM@``-+8```N9___+F?__Q````#2V```TM@``"YG__\N9___$````-+8 +M``#2V```+F?__RYG__\0````TM@``-+8```N9___+F?__Q````#2V```TM@` +M`"YG__\N9___$``````````````````````````````````````````````` +M``````````":`````0``````Y`P````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````_W__?_]__W__?P`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`!04%!0@+"PP-(02%145%24M+3$UA1(4%!04'"0D+#2$$A45%14=)2TU.842 +M%145%24E+34]A1(2$A(2&B(B*BJ"$AH:&AHB*BXV/HH`&AH:&BHR,CI"B@`: +M&AHB*C(Z0G**`!T='1TE+3$Y18T`'1T='2TU.3U)C0`='1T=+34]05F-`!L; +M&QLG+S<_1XL`&1D9(2DQ.3U-B0`:&AHB*CI"1F:*`!<7%Q)BXN.GX`#P\/%R)BXN.GX`#P\/%R +M)BXN.GX`#P\/%R'!X<$AT +M2'08>!AXZ'OH>[A_N'^(@XB#6(=8ARB+*(OXCOB.R)+(DIB6F)9HFFB:.)XX +MG@BB"*+8I=BEJ*FHJ7BM>*U(L4BQ&+48M>BXZ+BXO+B\B,"(P%C$6,0HR"C( +M^,OXR\C/R,^8TYC3:-=HUSC;.-L(WPC?V.+8XJCFJ.9XZGCJ2.Y([ACR&/+H +M]>CUN/FX^8C]B/W^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^__[_ +M_O_^__[__O_^__[__O_^__[__O_^__[__O_^__[__O_^_Z"[#0#@(@(````` +M``````$``0````$``0````$``0````$``0````$``0````$``0````$````! +M`````0````$````!`````0````$``0````$``0````$``0````$``0````$` +M`0````$``0````$````!`````0````$````!`````0````$``0````$``0`` +M``$``0````$``0````$``0````$``0````$````!`````0````$````!```` +M`0````$``0````$``0````$``0````$``0````$``0````$``0````$````! +M`````0````$````!`````0````$``0````$``0````$``0````$``0````$` +M`0````$``0````$````!`````0````$````!`````0`````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````=W<#`PT-!@8#`PT-!@8#`PT-!@8#`PT-!@8#`PT-!@8#`PT- +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````"861`$F!F*H@`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````0````````#H&X$````````````````````````````````` +M`0`````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````````"!`# +M`+03`P#D$`,`!!,#`-`0`P"\#P,`Q!`#```````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````#P`/``\` +M#P`/``\`#P`/```````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````)A9$`28&8JB`0`````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````(``````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````$``0``````P`"0`-`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`(#5```*````!````!C:@`````````````````````````````````"L+0`` +M``"P+0`````,+0`````0+0`````4+0`````8+0`````<+0`````@+0`````D +M+0`````H+0`````L+0`````P+0`````T+0`````X+0`````\+0````!`+0`` +M``!$+0````!(+0````!,+0````!0+0````!4+0````!8+0````"$+P````"( +M+P````",+P````"0+P````"4+P````"8+P````"<+P````"@+P````"D+P`` +M``"H+P````"L+P````"P+P````!<+0`````(+0``````+``````(+`````"D +M+0````!$+@````!(+@````"T+P````!4+@````#H+``````8+``````<+``` +M```@+``````D+``````H+``````L+``````P+``````T+``````X+``````\ +M+`````!`+`````!$+`````!(+`````!,+`````!0+`````!4+`````!8+``` +M``!<+`````!@+`````!D+`````"$+@````"(+@````",+@````"0+@````"4 +M+@````"8+@````"<+@````"@+@````"D+@````"H+@````"L+@````"P+@`` +M``"T+@````"X+@````"\+@````#`+@````#$+@````#(+@````#,+@````#0 +M+@````#4+@````#8+@````#<+@````#@+@````#D+@````#H+@````#L+@`` +M``#P+@````#T+@````#X+@````#\+@``````+P`````$+P`````(+P`````, +M+P`````0+P`````4+P`````8+P`````<+P`````@+P`````D+P`````H+P`` +M```L+P`````P+P``````+@`````$+@`````(+@`````,+@`````0+@`````4 +M+@`````8+@`````<+@`````@+@`````D+@`````H+@`````L+@`````P+@`` +M```T+@`````X+@`````\+@````"H+0`````0+```````````_____R@=@0`` +M`````````$!"#P!`0@\`0$(/`$!"#P!`0@\`0$(/`$!"#P!`0@\`0$(/`$!" +M#P#@!P``0`$``.`'``!``0``("<``.`'``#@!P``0`$``.`'``!``0```@`` +M```````"```````````````````````````````````````````````````` +M`0````$`````````M+^``/`W@0`8`````````````````````````/[*K:L` +M```````````````````````````````````````````````````````````` +M`````````````````````````````$!"#P`$`````0```#8!``"J````!`$` +M`((`````````@-<#`*37`P"TUP,`C-<#`'S7`P"XUP,`9-<#````0```@$`` +M``!!``"`00``@$(``(!#``"`1```@$4`_W]&``,````,````,````,`````` +M`P````P````P````P````!````#0````L````(``````````8`(````!```` +M`0``@`$``(`````@````@`````````#@`0````$````!```0````@````&`` +M``"```````(``!`!`````0````$``(`!``!0````(````$````"P`0``H``` +M```!`````0````$``%`````@````@````/`!``"@``````$````!```````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````-SH`P"TXP,`S.@#`%3G`P"L +MZ`,`(!@#`/CG`P",Y`,`:.8#`)CC`P""&@`$`!```__O__``````````"HVH``J-J``(`AH`"P(*``?"&@```, +M``#_\?__``````````#_````_P`````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````$`````````_P```````````````````````````````````$`N@`!T +M+($`&``````````!```````````````\+8``/"R!`!@``````````0`````` +M````````1#1%`.#"1``8``````````$``````````````%!4@`#@,X$`&``` +M```````!```````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````#__P``__\````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````#P`_``$````/`#\``0````\`/P`! +M````#P`_``$````/`#\``0````\`/P`!````#P`_``$````/`#\``@`````< +M`#``)``@`"``#``&@`$``@`(@```````````"P`@`"``"P`+``L`!H`!``(` +M"(````````````H`"@`*``H`"0`+``:``0`"``B````````````````````` +M`0````(````"`````P````(```#-`,P`S0#-`.8`XP#@`-T`VP#:`-@`V0#7 +M`-D`#P```!$``````````````````````````````````````````````.^^ +MK=[OOJW>[[ZMWN^^K=X```````````````"8:`0``````-1H!```````F'T$ +M``````"0XD0``````````@&````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````_P````$``````````0`` +M```````"``````````````````````````0````````````````````````` +M`@````0```#QV```@0%B`@(#?@/D`SD$@P3%!``%-`5E!9$%NP7A!04&)@9& +M!F0&@0:```%```` +M!````!C:@``````````````````0`00`!@````0````8VH`````````````` +M````(!0#``@````$````&-J``````````````````"@4`P`(````!````!C: +M@`````````````````#T`00`!@````0````8VH```@````$````````````` +M```````Q.3HR.#HP,P`````,```)```&`M/8V-C8V-C8`P`+V`/8V-@6#M@# +M``(``@("`@``````"@4Y&3D``#DM.0`4#Q0Y.2,>%"@Q-`````("!`0&!@8& +M!@8&"@```#PX-#`L*"0@'!@4$`P(!````@@.$Q4:'P`#"A$8&B`F``;V!O;V +M]AD`.H`>@`^`-0!]`!Z`#@`'@`0`'(` +M.@`>``(#!`4``.`B!`"E11@`RO0G`,KT)P```0(#!`4&"`H+#`T.#Q`1$A,4 +M%187&!D:&QP='A]65ZJJJJJJJJJJJJJJ[JJJJJHH_P#,JJH``*JJ`,RJJ@`` +M`$``P`!``,``4`#P`%``\``````````````````````````````````````` +M`````````````````````````*JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ +MJJJJJJJJ``````````````````````!L;6YO<'%R.`L```````(````%````G,P!`'BB`0!0GP$``*D! +M`-C)`0#TH0$`,,X!`+BF`0!PJ`$`R*,!`&2F`0#4I0$`:*H!`*S.`0!,8`(` +M3&`"`$Q@`@`0````3&`"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`3&`"`'1@`@!X +M8`(`4&`"`$Q@`@!,8`(`3&`"`$Q@`@!,8`(`3&`"`$Q@`@`$````(````"0` +M```H````+0```#,````Y````0````$@```!0````6@```&4````0(#!`@`@$ +M!!`@,$!08'"`0.P"`!SG`@!XY`(`?.H"`+3K`@!(Y@(`D.X"`/3I`@!X8`(` +M>.<"`"3I`@"PYP(`#.L"`$Q@`@`\Z@(`8.L"`'#G`@`(`````0$%`0,!`0$( +M`0(!"``(``$!`P$!`0,``P$"`04!`0$$````%'("`$Q@`@#X;@(`5'$"`$Q@ +M`@"L;P(`Z'("`"QQ`@!X8`(`4&`"`$Q@`@#<;P(`3&`"`$Q@`@!,8`(`3&`" +M`$Q@`@`0````F"6@`)PEH`"H):``K"6@`*`EH`"D):``Q"6@`,@EH`#4):`` +MV"6@`-PEH`#@):``Y"6@`.@EH`#L):``\"6@`$0%V89$!=F&@@/F640%V8:" +M`^99\\,B98(#YEG"G.A0@@/F6<*0`,`'D`)@`Y`"8`-P" +MW`)N`=P";@'H`6X!]`!N`?0`L@6R!=D"L@79`LP#V0+F`=D"Y@%$`40!Y@%$ +M`>8!L`'F`1P"Y@$<`H@"B`+,`X@"S`-@`\P#.`3,`S@$S`/,`[(%S`.R!1`% +ML@54!K(%5`8&!A(&$@P2'A(>```T`&@`:`#0`-``.`$X`3@!H`&@`6P`V`#8 +M`+`!L`&(`H@"B`)@`V`#Z@#4`=0!J`.H`WP%?`5\!5`'4`?J`*@#J`-0!U`' +M^`KX"O@*H`Z@#@`!`@$#!@````````\`/P`!````#P`_``$````/`#\``0`` +M``\`/P`!````#P`_``$````"`````@````8````&````!0````4````$```` +M!`````$`````````````````````!`@$$!```"@`*``P`"P`+``H`#P`-``L +M`"P`/``T`#``+`!4`$0`?_\'#Q\_`0,%``<"`P0&!@T%!0D)"0D)"0D```$' +M#Q\_?_____\``/____\```"`555550```$#07D)[:"^A/9H?%BFTE]`>.([C +M.!S'<1R]A/82CN,X#AS'<1R.XS@.7D)["<=Q'`&\#`!````!X;P,`$``````````!````_P```,$```#!```` +M00````````!!````$0`````````5&`L+"P\#"P`````````````````````0 +MS0``(,T`````````````A,P``(#,``#(S````````,C,```HS```*,P````` +M```XK0,`N+`#`"RX`P!@N0,`!````!P1```<,@``'#,``!P4```$````'``` +M`)S_&/P``'``9`"P!'$`;@#0!W(`<`"@#W,`<@!`'W0`<*D@&K`D<#$P7_0555554! +M``"`B(B(B```$0```)1.`0`;````(%`!`!D```!\D0$`!P```(QW`0`,```` +M5'(!``T````,50$`!````."&`0`#````0&[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=X````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````#OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>%0````0`!0``````(""`#P``0``@((`/`@"HUB`@@`\"`)AY(""` +M#P``\`AI(```:2!``&D@``!I($``(""`#P(`H-YI(```:2!``&D@``!*(``` +M2B$``$HB``!*(P``2B0``$HE``!*)@``2B<``$H@`!!*(0`02B(`$$HC`!!* +M)``02B4`$$HF`!!*)P`02B``($HA`"!*(@`@2B,`($HD`"!*)0`@2B8`($HG +M`"!*(``P2B$`,$HF`#`*)(`_@0``<$$LG#!`+)PP0B0<-`HB@#^``"3T"B,` +M-P(,0!9*)@!P:2!``$HF`'!*)@!P2B8`<$HF`'#OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWOP.!^X'@$W#C=./#@>`3<--TV\.!X!-PPW33P +MX'@$W"S=,O#@>`3<*-TP\.!X!-PDW2[PX'@$W"#=+/#@>`3<'-TJ\.!X!-P8 +MW2CPX'@$W!3=)O#@>`3<$-TD\.!X!-P,W2+PX'@$W`C='_#@>`3/P'#X<+AP>'`!\`<',`Q +MX<#@?P'`"B8`\(H@OP_*(&0`X'\O(`,`X'^*(/\/'0`@`$H@`!!!*`AT`-@%*GX`+W$%*CX# +M`"!`C@$AP0X%*SX#X'\G<>!X4R)"@>!\3B(#B!8`#``!*,P``"F!```H@`#@ +M?X5Y3B,#```HP0#@?P)XX'A3(D*!X'Q.(@.(%@`,```IS``"*8$``2B``.!_ +MA7A.(P,``BG``.!_0BG!!U,B0H'@?$XB`X@6``P``"G,``$I@0`!*(``X'^% +M>$XC`P`!*<``X'\B>>!XX'C@>`HD@/`%($0`X"#!!T0D_H!!*L0`A``"`"\D +M`O%"(0$!0B`#`>@@H@0$$00"!!$%`@01!@($$0<"!!L(`00;2`$$&X@!!!O( +M`2P`)0!$(CZ!/``B`$0B_(!`(<$`X"#!!T`CPP"H((`!`1&$`@$;"@$@(,`' +M!!$$`@01!0($&P@!U`?A_P0;2`%$(OR`!!$$`LD'[_\$&P@!0B%!`$(@0P"H +M((`!`1&$`@$;"@$@(,`'2B(`$"T%H`E*(\`02B(`$2$%H`E*(\`0X<4(=1'P +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'B`Y6&][_7@>.!XX'C@ +M>.!_P<4`V<]P@``@X""@`]G/<(``3!'@?R"@X'@`VPGPSW*@`&`,2(H!XP$8 +MD@!3('Z`!/+M"T2``-P)\,]RH```#%J"`>0$&)```B'"`"*Z[0R$D)5["?#/ +M(/@\<``V`GTSW"!`,PN@@_O_P/9`=C1P.!^X'CQP`AQSW"! +M`!@R)*AF#^__!>`!V-'`X'[QP('@X<4`V`GTSW"!`/(N`=U*#^__J7&I/'`D@K/_X3@`-W*($(#$O3/=H$`N"Y`)L`5(@_O_P39%XZWKA2N&8X5 +MKAJ.%JX!V-$"S__QP);@X<4`V(SWSW6``/`MJ7#V#N__!-D#A8FX`Z4!V+4" +MS__QP)K@X<4`V(SWSW6``/`M!&W2#N__!-D#A8BX`Z4!V)$"S__QP!8*S__/ +M=8$`,#,FC:/!`KDT>4`E#A*.X#YF`-@E](MPG@[O_PS9`A2`,)SH$-G/<(`` +MP!,@L`2-)&X`KB#``:X#%(`P`JZ!P*(/(!\"V@:-`>`/>48AP@`GC<&X17DG +MK0:M`=@A`N__H\#QP.'%SW&``%P,+(DP<`#8"O3/=8$`N"XZ#N__0"4`%P'8 +M%K7]`<__\<`?"%$`SW"@`&`,*(C/<($`&#,2""``-*@!V`+P`-C1P.!^SW"` +M`"SX(9#/<($`&#,4B!$)``#/<8``P!,`D8&X`+'@?N!X\<`R">__`-F&X,H@ +M0@`F],]W@0`P,\]V@0!P,U8G$!*IEB(*X!\H<`^G@^7*)280N&44>``@#P3I +M<*H-[_\&V0&7"N@`CPCHSW&``,`3`)&&N`"QJ;8!V$$!S_^`X`#8"/3/<8`` +MP!,`D8*X`+$!V.!^X'CQP+X(S_\(=<]P@``@.P*`&G$`W@D($0$!V`7P"PT5 +M$__!-DNC]"O4R$``!&O02C`(*"Y-PAD``(@ +M0@!CO2L*10,+ZL]QH```#`2!8;I88`2A:!&```+P#X]3(((@`-D/(8$`)'@0 +MKQH/(")`)P`3S/'AQ/P'"X``&PQ"8`6\I`0@$\"\I@0`AH,]P@`"4,?`@0`!`>.X*``@%\(HA_P\A +MH%X)P`C<'8`?`P!`#1N%28`#9#R$!`,') +M)'A"(`"`X'_*(&(`26@&(($`UW``@```']@&\B\I00!.(8`'X'[@>/'`@@S` +M!8#9SW"@```<)*#1P.!^SW&``)04`($!X.!_`*'@>/'`,V@U><]R@`#ZR3%B +M^!Q(L$'`SW"``$@5`("`X,H@`0?*(H$/``">`%`/(1[*(2$"HL#1P.!^\<". +M#J__"'//=H``(.``AL]U@`"H)Y/H@@G@$VAP+XT-Z`'8`*;/<(``3!%@H"L) +M7@#/<*#^W`$+\`^-&PA>`,]P@`!,$6"`SW"@_@@"`=G:#F`1:'*I!H__X'CM +MR96X[1H8L.[)F[CN&ABP\,F*N(VXD+C@?_`:&+#@>&$%H`8`V>!X*')9!:`& +M`=DH=$AS`ME-!:`&B7+QP.'%*'5(=)AS`]FI'IH@&=Z2*`,B0'@P;@,J0(G`!31#`20Q*4!V(4%C__@>/'`9@X@$0_8"@X@ +M"@'8T<#@?N!X\<`:#8__"'4A@`"`(:``H0#8`*4$'8`?K=X"``:%0"`.!R"& +M#0U!$%(+X"`"V0"F!H5`(`X(((8-#4$0/@O@(`C9`*9%!8__\<#&#(__HL$( +M=3IQSW>``)P+OA>`$`#>B@Z@$LEQ@N4:<-GWJ7`J<D`V):XSW&@_C@)#@G@ +M%*ERSW*@```,:!(``<]S@0"X+@FS*FVRBQ,-DQ(`W`\D3!.&)#(4C*,(\/[E +M!/0!W(RC!/#,HP#P?"90$#X<;"%X%F+<-(/K_\!V2#`SW6``/`M4R`!`"BM''C`N`FM[_&K"12!SW6` +M`(@HJ7"J#Z__!-D"E8"X`K7'\<]P@`!(%0"`0^C/=44`-#@`A7L(WX-["=2! +MSW"``(P4?@^O_P?9%XV!X`P-X2+*(&$`K?'F"J`(*'"'Z,]R@`!0WB&"@+DA +MH@4#K_^BP$,)5(#/=8``4-ZI<$(/K_\!V0&%@K@!I9/Q3.G/<(``1"TN#Z__ +M`=D!V".'.@[@$D2'A_&,(0*$,/?/<(``2"T.#X__`MCS\?'`7@J/_\]P@`"( +M*`*0.0@>`,]P@``\#!Z(SW&``.S)`[@5>`!A'0B>!TUP&0B>`\]Q@0"X+@R! +M!N@:D<#@!/3*#4`1SW6``/`M`X55"%``?PB1`,]P@``\#!Z(`-EO"-\!4VA5 +M>L=R@`#LR6""A)6*)D00Q'RQNV"B#0R!$Y&[8*(%\('DRB%A`(#AT",B!]`C +M8@?/(V$'=@R@'&"B%_#/<(``/`P>B",(WP%*C0.X%7C'<(``[,D@@(#BSR&B +M!M`AH0;0(>$&(*``V`.ESW6``%#>`87@N+@(@@@!A>&X]`I"%@&%1PB>`,]P +M@``\#!Z(C"`"@!GR8(TO"]\!`[@5>,=P@`#LR2"`4R-"``0A@0__P___&KI% +M>42[PKMANQR[97D@H`#8`:7/<(``2!4`@"?HSW!%`#0X`(!#"-\#SW6``,`3 +M`)4O")X`SW*``)P+OQ*``,]Q@``\#,&X]"$``,]Q@0!0,QFI0!*``!JI@@A@ +M(P'8`)7DN#0(0B-1`8__X'CAQ0*XSW.``%#[%G@#8P(C@P\```#()PMR``#: +M2'0$\`'B`>07#!41%2$-`P.%8GCQ"%.``-@#I?7Q2'#@?\'%\<"&"(__&G`" +MN!9X`""-#X``2/O/<*```"#[@`*%`-['<````&0")P$0/[E2(0$``">"'P`` +M`!"`X0`A@`^``+Q'0"`1"`IPA"@) +M#\]Q@``@.S`A0`XLV>(*X`?)<@BE"!B`!`B%(H!H&4`@"(4@@&`90"`(A0"` +M=@V@",EQ:G`2\`&%B.@"@@(G`1"`X#)H-GD`(8(/@`!(^P#9 +M(*)I!2`B**+@>/'`H@]/_\]U1`!P[R"%0"4.&A-I%7@`(((/1`#P[Q2"`>`4 +MH@38!:42:11X`&:`X,H@@0\``"(S9`G!_P"%)(4"N!1X!&8`W@&%R7+)/'`[@Y/_PAW`B"`#P``.S,H=BT(=0%(=0H/H`BI<,#@2?8* +M#Z`(J7`+#@$0C";#GP;TZ7#)<;X([_^I``DS20=902-)8T3"%$`,B"`+P``*0$(X#A@$'D$:<]R@``<#%R2$'@? +M"@(``"$`!(MQ(@O@'@3:`,$#A21X(H4)"$```-\!YL]^U?$S#U$00B5!($0I +M/@?/<(``I/TR($(.SW"``"S0-7B%ZBR``>$LH`GP-(`!X32@`_`+"E$@%=@" +M\`#8]05O_Z'`X'CQP*(-3_\:<"AV>G+/<(``:+H@@`HA@"^``)P+.!$"(,]W +M@``<##IB'9<\EPHB@"^@```,.&`$X`)Z3!(!(,]P@`#DNR"@\@Y@'-AB"'40 +M&@`@=!$`("X/(!9DX!P7!!!J<*EQ`-VIE#ARB7`H!'>0@5`B$G>@H5`2%'>2BE#0A1`<"E`=@"I0WP"M@`I0GP`H`+ +M"%$!"]@`I0/P`!U`%,]P@`!(%0"`'^C/$\2@0`8N25X`>!,&@(`*+A-&@(`*+A.&@(`*+A/&@(``,%"(``CE@K@ +M%HIRSW"``(RK`(@1"-$`-@_@%@/83@I`&4PC`*"X\EX.(`B*<`"%@.#,(.*" +ML/3/<*```"#[@`:%#0CE`R.%`B<"$`?PXG@.(((/_____X'#@L`%*GX``!C` +M#@`;0`X"P``BCB^```P7`>`=>`2N!(X+")(`8;@/>`+P`-@%K@6.)XXX8`>N +M"(X!X`BN#(4!X`REYJ4`A=$($0`!A9H-(`PEA8#@!=A-]%@5@A!D%8$0`-A" +M><]T@``<&6*$+R%)`!$*Y0`O>4"$%0I%``+8!O!!A`T)A``#V`"E`=BRZ,]P +M@`"B\AB0`$Z`D)!0``V`7P!-@`I0'8G.AM +M%8`0!N@`V&T=`A`'V!/P*(4'A1!Q!M@-]`:$"NB$+`DOSW"``"@[,"!`#@D( +M$0$!V`"E`(62Z`:.`>`&K@N%`>`+I<]P@``<&0>`!NCV#2`(BG`)V`"E1"P^ +M)\]P@`!$%C`@0`Z.Z`0BON\$!`0$"/)$+#XG`"&`?X``3!;@H`'9SW"``!0. +M(Z``V)T";_^CP.!XZA(#MC,+'@3/Z%GGN#A"@) +M#V&D`:0AI$&DSW"``$0],"!`#@&DX'[QP"(*3_^@D4(M`Q/`N^R]`]S"+6(3 +MTR6B$`;T`=Q!*,T`P;U!*,(!*[A3($X`(HG/<(``H.A"*80`SW&``$@9)1&/ +M`,&ZR&`)#L`3&-_@H0.ZI7H&OL5Z"+A%>`J\A7@+NV5XC[A`+(($17@!Y:>A +M'0)O_P2AX'C/<*8``,`%@,]Q@`!(&06A"0@?`!'8`*'@?P"!\<"*"4__&G`` +MWLEUR7?>#6__!MC/<*8``,`$@,]Q@`!(&0&A;'&+[0QR$PK>!0'=SW*F```$ +M8()!@HSO#'(5"MX$SW*F```$T8(!W\&^4H+/B*+SW2``$@9 +M#+DE>JR4!MF`N@';&PT>$\]PI```@'"@!]E-O<*]#KVE>@/8SW6E`("`-J4$ +MN`5ZSW"F``#`0:!"I&"@X'_!Q>!X\`C"B0`!8#@P`X!(M,( +M$0#/<*````B:<`L.GA9DO9^]JJ`D%X`0SW&```;*`[@5>`AASW6``&S,%GV$ +M*@DO`"&`?X``(#N*)0,(`]H('(`@`!A`44"%`!B`4$*5`!B$4$2``!B`4$J0 +M`!B$4$:``!B`4"Z0`!A$4#.7`!A$4!.7%=D0X!.W`!A$4&IP4@WO_T`G`18` +M&`10,+@`&`)0JG#)<:ARE@H@(F"%SW&```P:`8$`&<`$`>`!H68((``*<`0< +M0"3>#J`4"'4!V9(-("(`'D`@!O!F#N`>$MT"\!K=J7!1!R__J<#QP.'%"'4? +M"-$`"/!F"V__!MAL<`T('P`,-%PRB.&(\HC!2!!*X`@HGC`X,HGAA#*)P40&>\`)8`?````M.EQ=@I@$0IR +M_64R;0#:"_#P((,@`!C`4`D)$"``'\!``>+Q"L2#.0U!%34*$"`Q#L$4`"4` +M%2G:$KKP(@(``-L'\!-K`2H,```8`E,!X_<+A(0+"1`@`!^`0$)Q;'`G"!\` +MSW"@``!%7(`8@!L(7P4$(KZ/``8```?T60F$@P#=!/`4W0+P&=TE"1`@!^T# +MV<]PH```#":@"O``V$`<&#!6)``X!-F.#J`=`=JI<,4%+_^`)`0QX'CAQ5IB +M5'H4(LT`SW*``*CH9FHT>;-C8[D98<]U@`#2Z#(E#!$#N"EB".`L?`0I_G`G +M<`?@([C@?\'%X'CAQ>'&02B-`,&X`-JQVPB["_#/<:````R:@2G9$KEU>8"A +M`>,!XN\*1(,`VDAU"O#/<:``8`PHB9-MF'DZ8@'E\0T$D"G8$KAU>$"@P<;@ +M?\'%X'CQP,]P@`"4&2"`Z+G*(((/``!>`-0.8O_/("(#T<#@?O'`S@P/_\]U +M``"H81,(40//"`>$G +MH@#>SW>``)09TJ?>"B``R7$'AQ$(%`+N"```QZ?/=4P`0$O/V*+8;D.NV5X0"@#)F5X`J4$ +MN44A0`%`*,$B)7A%>)2XFK@2#"`6`Z4$I0#8"-PO!"__HL#/<8``V.C@?_`A +M````V<]P@`"4&26@)J`GH.!_**#@>,]P@`"4&>!_$H#@>`#9SW"``)09X'\A +MH`0@@`\!!`#8SW&``)09`:'/<*```"`;@*'!"J'@?Z'`\`&ID(@`"4BN!1X8[C@'`BP0<5#Q3_89L`#AA8<1#,$(($/```` +M&"NY!""`#P`#```XN&8/[_\E>$3`&1Q",T?%9<4*)``'BB`$`".&J7(F#.`C +MJ7,*)P"0$/3/<*````BAH`.&"-E-AEH.X"$*/'`O@H/_\]W@`"4&06'PH!_(*#QP*X)#_\(=L]U@`"4&14E#Q`3AQIQ +M`>`3I\]P@`!8%0"`P*4+Z$`H`B(`V):XSW&@_MP&'@X@%,5Z3!<$$,EP,!6" +M$`IQY@K@(6:%R0$/__'`X<40W0;P`-VV#2__!M@?#1$4#'#U"%^%;'#O"!Z` +M`MT`V<]P@`"4&3*@[_&%[4H-P!H(=:D!+_^I<`#9A;@,\"\J`0!.(H,'4FM# +MK>`GRSW```$4PS@IO_P`0`2`KAPJ'!7T3"4X@SW`` +M`$8PM@IO_P`0`2`KAP\A42`!YKT.%)$!`0__X'CQP.'%SW6```3_`84F#Z`( +M`H`(<0&%^@M@$`&`_0`/_YT$0`BM!$`0*01`$`'8X'_%&ABP\<#AQ<]U@``$ +M_P&%\@Z@"`*`"'$!A>8+8!`!@,D`#__QP$8(#__/<*```"#;@,]W@``$_P&' +M&G&`X,H@@0\``#XP'`I!_P'8SW6``$@RC"#_KP"E`(<']`&`H@R@%`#9'F8@ +MAPN!C"##CPKRH@Z`"+X.@!0*N-A@((<&\``F@!\```!`9H$`VG!PRB)O`(#B +MRB+"`,HB`0`!@<]S`0!()X(+8!#)<0#8)0`O_P"EX'CQP+X/[_X`VL;)SW:` +M``3_H88.Z`;ISW"@```@&X`&\`"&#X`!@&&X`=H%\,7)]>A(<`KJ`-G&&EBP +MX@Y@",4:6+"AAI8+0!#/<*```"`[@`*%C"##CQ+R`X4"($"``-G*(6\`@.'* +M("$`UW`````0!-C*(.8``_`!V/(.``BQ!\_^X'A5`T`0`=C@?\4:&+#QP'(, +M@`CN#4`(`-@#\`'@#WC_"%*!T<#@?N!XX'[@>/'`#@_/_@AUA>#*((8/```F +M,/0(9O_*(48#SW:```3_((8/@8CH(8'/<```*##B"&__J7(@A@&!$"!``P&A +M`(8O@`#8#R!``S8+8!`A@3$'S_[@>/'`N@[/_@AUA>#*((8/```C,*`(9O_* +M(48#SW:```3_((8/@8#@RB"!#P``)3"$"$'_((8!@0\@0`,!H0#8W@I@$`\@ +M0`/E!L_^X'CQP&H.S_X*)P"0!?('EQ$('P#/<```*3!&"$__!N\'E^"XT2!B +M@#;TSW"@```@VX`'EZ&'0PB>``:7@N``V`?TSW"```3_`(`!@!?H7@V`"(#@ +M`-@)],]P@``$_P"``8":"J`4`=D"?<]Q@``$_P"!I*``@:2``B6`$Q4(4@#/ +M<(``V!H2#"`@J7$)\`'8"/#/<(``V!JN"P`@`-@Y!L_^\<#&#<_^SW"@```@ +MVX``W<]W@``$_P"'`-E0@(#BRB!!`"'R+H`6Z2>1*0D>`"*'0.!!@5!V`-G* +M(6\`@.'*(8(`RB&!`]X-(```V@5]"_`A@D#@2B!`(,H-(```V@5]"G#8Z`/M +M`-@D\`"'#H!]Z`>0]P@>@**'!.T'E1$('P#/<```*C!"#R__J7&I<,(((``! +MV>GH`H>`X,H@@0\``#TP'`\!_P*'`("Z#N__`J=7"!&`>07/_O'`#@W/_D:0 +M"';CNLH@@0\``&(P``\A_\HA@0-B#2`(`H8:<$`@#0+^%0"18PC?`4`E#QAD +MCSR-78TP\'8((4&N,(.+_]E>CR-9(\'E@L( +MG@$K"T$`"_`G"T$`)8\=C1\)`0#^%0"1%P@?`080`"%3('Z`!`]B",H@0@/I +M!,_^X'CQP&H,S_ZFP0AW!I`:<8#@RB"!#P``(#!8#@'_)Y=$(3Z/RB"!#P`` +M(3!0#@'_!Y>G")X`!I=$((X`8@J@".EP!I=M"%X`SW6```3_`(5/@%!WRB"" +M#P``6#`H#B+_RB'"`P'8&G`@A0NE!8&A@0_H`H$;"-``>@W@!PS8A^C/<8`` +M//,*<`"A!/!6"V`(`8<+Z,]P@`#8&KX)`"`&V((+(`@BAP3P7@A@"*EP!I?@ +MN!'RSW6```3_`(5.@%!WRB""#P``;S"\#2+_RB'"`P#8"Z6U`P``AK@'MUX, +M(`@"A_X0`8'GN>("`@!'EPIQ9I=*(0`@D@H@"`HD0`0Z#"`(`H`%DE +M`Q*?DR&'3R0"$1V-7[.`X,P@(:`6]$\D`!',]S@`!8$D"#8;I`HT`E +M`QA$BXPB@X]#]@'B1*L%&T($"PA>`0'8!:NI<`8,8`@*`%DE`A(_ +MD@&'I+D_LC^2J;D_LC^2J+D_LB*%(G@3"%(`#Y4/"!\#!84*N#A@`J4FET0A +M``P1"!$,SW```%,PC@PO_T*'!I?+))'@:\I/H@@H@%"B`5R7"*Z``1`B#/<``` +M=##)<>(++_]!@@^5[[@<"^'_RB"!`P:7X[C1(&&!1_+$C0#9SW"```3_`(`/ +M(8$#`8`*(8`O````@`MY\LDD>!SRBNC^"2`5R7"&Z`(*(!7)<"^5!>@OE5<) +MW@,$(4$$@.$!V\![SW```'8PR7&""R__0(4=\`;HU@D@%7Z+B("N+_RB""`P>7=0C>`#() +M(`@"A\]U@``$_PAVSW"@```@&X!`P`"%@.#*(($/```>,/P*`?\`A0"`0<`` +MAD+``89#P`:7(KC`N$3`)I$3`)I$3`)I<4'``T +M);G`N06Y)7A$P(MP&-E^"6`=*MH'EPL('P$`WE[PSW6```3_(84`%100`!$1 +M``@1$@`(%!,@H@@@"`*')I<(=E,A0`"#X,H@@0\``%DP@`H!_P:71"`^A22. +M%?("N4-Q^Q$!AH"!SW$"`$Q@3PQ`$$$H@P#`NP*[)+A3(`\`!K\5\$0@/HH; +M\@*Y0W'[$0&&@8'/<0(`3&`C"0`#02C#`,"[`[LEN,"X]V@E%H00"G(`AB06 +M@1!@?.5[`(4`WAL(`04"@!,(P00AA0"!"PA!!`*!"0B`!`'>R7`]`._^IL#Q +MP/8/C_X*)@"0RB"!#P``0C#4"0'_R742\`:5AB#_#(S@RB"!#P``.S"\"0'_ +M!I7CN+`*XO_*($(#H(7O[5X(8`C)<"$`S_[QP)X/C_X*)0"0&G$Z<@#86G#/ +M=H``:#(`I@3R`(6'Z,]P``!M,'H)#_\`A2&``B!`(#^X4B``@#'R)O`F""`( +M`H`0:7AB#_A03R*'`#\`#8Y[K,(&&`#?3I<,8*[_\` +MV0"&A^@&E^.X)`KB_\H@P@,@A@"%$.G@A0"&">^)Z"&'`B!`(#^X4B``@-+U +M90>O_@"&`(``I0`?@!2J#R`(Z7#L\?'`_@Z/_@AU*'9\B$6`@.,F@,PB(H#, +M(2*`!O(3"U``#PI%`,]P``!H,.((#_]V"N`2`86(Z""%SW```&DPP@@O_T&% +M#Y43"!\#(H7)<,(/(`A%A0*E&0>/_N!X\<":#H_^&G`"#^`'`-T(=D`@#P+I +M<(8-X`<"V0.64R!!`!T)40`H'D(302@!(L]P@0#L&[H((``O>03P"0F0`*EP +M"/"'N`.VS@A@".EP`=BQ!H_^">D`@0"B`H%`H2BX#W@"L@CP((`@HD"@!!J$ +M#P``__\@@@;I`H(HN`]X`K'@?N!XX<4(P$'(0?``#__^!_P<7@>/'`P@_/ +M_\]Q@0"@&PAS52'`!#.!?@_O_VAR`Y-&(,``@+@#L]'`X'[QP+8-C_X(=BAU +MP.'*((8/``!E,)@/QO[)<((/[_^I<0ASSW6!`*`;-856)8`2/@_O_VAR=:4# +MDT8@P``#LP#8Y06O_B@;`@"`X,]Q1`!8]@#8(?+//06@H;H=8(1@B$+ +M!0`6\,]S@`!,"0"#"0A1``&##NAU@A&""0C%``/8"?`0@@T+!``(@0D(E0`" +MV`BASW*``#S?(((+"$```*(!V`+P`-C@?N!XSW)$`/CS(8+_VPL)P``M"%`` +M(H()"<``(0B0`,]Q1`!8]B6!"WD"V0CRX1*!``."$'$!V`%N@@N@$P#9$H4S")``5PC1 +M``3:SW"M``"J4*#/<:T``$1)H0+:SW"M``"$2:`@&8`/````#!#8"*$5\`+: +MSW"M``"J4*`$V<]PK0``A"F@SW&M``!$2:$@&(`/````#!#9**`U!(_^X'CQ +MP,X)@`C/<0,`,`_/<(``M!LZ"\`/Q@F`"-'`X'[@>/'`SW%$`/SR0($!@04B +M/H`']$.!!($%(CZ`"=@"\@C8]@F@"`#9SW&``,`(`(&+Z,]PH```(!N`QW`$ +M`."3!Z$"H='`X'[@>/'`5@N/_M8.(!8O?>8.(!8(=A5X!>#/<40`^//D&0`` +MX!&``!D-`1`;#=$0XA&``!!V!`FB",H@@@,%\)8*8!>I<(4#C_[@>/'`8@T` +M%AD('@#/<$0`6/8(@(/@`=C`>/H(@!G1P.!^\<#J"J_^`-C/=D0`>/0WAE4F +M3Q>`X<]U1`#X\\H@80`$\H'ARB"A`+X-S_]`%0$6,'#*("$`$/(WAD`=&!`U +M?P"G!+@4>$`E`1P98?X)H!,$V`'8`0./_O'`E@J/_L]U1`!8]@&%*+C:#"`6 +M4R!.`24('P#/<40`^/47#E0:`H&`X)#T"!F`#P`0`!"*\`#8`J&(\`.%SW&` +M`#`/8('BN-$@8H%1\N&XT2`A@,$H(0+3(&$`S""A@$?TSW*``#0/&NM@@AD+ +M40#/<(``/`R$B,]P10#`(@"`'0P$$)L+$0#/<(``/`QDB,]P10#`(@"`APC% +M``'<@*'/<(``/`S$B,]P10#`(J"`SW-$`/CSSW%$`/CU$0VE$P#8@*((HP.A +M!*$/\`"B(!N`#_#P\/`,&8`/__\``!`9@`___P``SW"``*CB%_#/<(``J.(K +M"U$``-I`H<]Q1`#X\R`9@`\`\`#P@QF8#___``"$&9@/__\```'9(*#/<8`` +MJ.(`@1+HSW!$`/CSJ(")@&J`2X#/<*``@!^LH)R@?:!?H`#8`*&]`8_^\<#/ +M<$0`<)$C@,]P@`"H)QJ(#ND1"%X`SW"@_G0$R@E@$`#95@^`"-'`X'X3"%X` +MSW"@_I@$L@E@$`#9]O'V\?'`X<7/<8``H$>C@05]4R7^D`?R`H&,(,./SR4" +M$`GMHZ%F"*`4KWA."6`:J7!5`:_^J7#QP-((K_X`V58@#01&A=D2#+8$(H,/ +M````&"N[@"0&$$`D#A8RI14*7@(8C42XP;@(9HFX"')&\`0BOH\`!``!-_)? +M"IX&W93#NH#FR2-B`"CTT(C/<($`V#\6((\#X(^&)_^3!_3/=X$``'#CCPD/ +MGA`!V1;I0"M!`I&YUG@`B#*E`-\1"%\!SW"!``!P`X@'"-X``=\&[XBY,J4" +M\,*Z0"0!&%AA!HA985")"/`XC3QYPKDX9)EA"(A0B3V4)7H"I1B[17MY`*_^ +M8Z7QP/H/3_Y*(``@"G4L\$`M$A'/<$4`8",`(H\O10#T(,*'`8`]"(4#`8>% +M*`$).G`O<-((K_[)<0`B@2]%`+0K%:%8&4`$SW"@```@&X#7H1BA3R``("\@ +M!R``V`&G`J`$AP\@O@#P#:"'4'\`'A2'#F"^`/ +M`-JL:)X-@!_/<*``@"#0@(MQR\F!PH8)H![$$````,'"?0'`/65!:#!URB(& +M```80%,`&(!0`!8`0``6`$#+R<]TH```"%8@`P(XDVBY)*0XD\P80`-HN3BS +MT!B``&D';_ZBP.!X\<#N#F_^`-O/<8``C*L@B80I`0//<44`?BTT(4P.SW&@ +M```@:!$$`,`1`@!!"!$!R\FE$@.W=A`-`8`@`@`G"QX!:8`/"QX%SW.!`#1& +M@8,"\(&08I!"?`(D``,((P,`!/!BD(.0FV-H=#'P@>#,(**`-O3+$@.V5B,/ +M!,"7#0A1`'X3``$%\`#=R7"I=G@3#0&E$@.WY+O1(V*`!O*">$)X`B0#`!+P +M"8<7"!X%SW*!`#1&`H(+")0`88("\&&7F&8;8P*7&V/<9*7-%0A>`,O)=A`` +M`6*XG6`+\&AUQO$/"W(`8KW9R>P0``<=9:#8`:$`V!&AL:$"V`<9&("`V`"A +M609O_G!X(8`="=X`,(@#N35YQW&``.S)2Y'L&((`*I$&\#_9[!A"``#9X'_J +M&$0`X'CQP+X-3_Z6"R`""'8(=8PEPY\`V'3R(H8C#D1P`$```$2&&PZ$<`!` +M``#/@@T.A7``0````=B/Z,]R10`4+4F"$PI.`\]R10!@(T&""PI$ +M``#=2/".Z!-M%7C'<$4`E"Q"@`2`$')T`"X`RB4N$`&&`KV%*`$).@YO_B]P +M`*8'ID\@P@=`IL]T10!@(R*$M7W'=44`M"MAA1L))0#>NR2$?&$3#`00.&`/ +M",0``-@$\".$]_$!V",(40!!I2&&SW*@```@(J4BAB.E)(8DI3N"):4!V?P: +M0``/?0#8J@A@`LEQ"NT!V<]P10"T*R"@A-E^#>`5`"P$>SW"``(RK1@W@%0"(SW"M```9`X#/<8``U*;3N`.ASW&``%2K +M"8F!Y0'@":D,#\$=]01/_N!XSW"``%2!08`B@*W8$+A3H#B@SW&``'2K$HD! +MX.!_$JGQP$X,3_[/<(``A#,`@`H@@"^4$BFEH8C/=X``5(##O<]V@`!4@88. +MX!6CIN"XRB@JX +M17A`*,\#!7\B#L`5X;C*(`$$*O(`A@#9!2A^`P2&"]HO=9H.;_XH$D@P`A5J +M17@*ND5X0"C"`T5XX:;-`V_^`J;QP%X+3_[^#N`5`=ZN#>`5&G#`N('@I@W@ +M%#L`5`-D"\`'A$0E5 +M!,]R@`"%,BIB\PB%@)'ARB%A!`_R`"&,#X``A#)`C`(@@P!!C'%[`GI0<\`A +M;0#/<(``5(`BL#9X))!#D`RY17G/G(:`!V,(@`0"`X`'9P'D6#V`0`-A^#N`*`-@!V-8*X"`` +MV4PA`*#*)D$3&?*$*Q8I`"&`?X``5&M+@,]Q``#D#(;J#("`X,H@00`%\L]P +M``"^"B(+X!P0>`AV`MB6"N`@`-GA#A`0U@[@"JIP2B$`(`#>9O``P,<(C@,+ +M#Q$1OPY1$!,/$1$2"X`8.G"V"B`9`MC)<.EQ$@B@"6IR"B4`D$7RSWC/<8`` +M."KU>4"1Z7&*`*`=@^#N`8`-@`V&8)H`D(<24($"#&"N`5 +M:G"!X`'8PB`!`(#@`=G`>;8-8!`!V'8(X!5J<-H-X`JJR7`Z#6`0:G&F#.`*R7`!V/X(X"#)<78)X!R*(`\*"'<"V.H(X"#)<2CO +MSW>``-Q6Z7"J"R`#7-G/<(``,"">"R`#BB$7!<.GU*<*<`0?`!2_MP'9L@P@ +M":ER8@C``RIQ-:<'Z,]P@`!<(9X+P`.#Z,EW`O`J=S8,X`H!V"(-X!@`V`#8 +M2@B@"0AQ`!J`(R4'+_[I<.!X\<#"#@_^.G`H=DAWB@K@%1ISX@R@%7IPA"X" +M$\]Q1`!4E""!`K@G<15X`"!2`,]U@`#<5D`B0""4[R.%&0@0("]@:G"V#.__ +MR7$))P\0+R'&(_BU*G#)<0':"@D@"F.%!H77"!$`6!6`$(0H%@EAA2]P`""! +M#X``5&LLX?`AP0`NZ<]T_P#__XEV`-VI55YQW&``-1J?.$'80(A +MP2,O)TD0#0^%$R\F21`H=$AU`>+="I2!'PP3$#IN/;G984.YSW"``.3J%2!! +M`,")`-@;\"#>`-@9\$(IP"#/<5555E4$*'X`"B#`#@YX22"``0YX2"````YX +M%"(!(`:)QXE3((T!)[C^"\`8SW"``,2X`(#/<8``,""PH0T(40`4)4`3$*&N +M"^`8J7`!V`X+8!#)<<]P@`#<5@>`C.@`$HT@`-A2#N`8J7$!V$H.X!BI<<]P +M@`!X"T"`K=D0N4&A`8`"H;D%#_[@>/'`X<4(=<]Q@`!46"&!`=CCN-APB'`+W!L-$`"$*$$#+W*,>2=R`"*`#X``OI\1\(0HT@`O<(0JPPDG +M<$0I?@@`(0%PC'LG<0`A@`^``+B6R''Q`:`="]K@>/'`O@P/_J'!%@C@%1IP +MNG"6#Z`5"G`(=8'@2B)`(,(B@20`WEH)("&J<,]R@`#D'`HA@"^``-0=\!(# +M`,]Q@`"4CQ9Y..'U(<$`0"C4```<1#!!$@(&SW&``%21%GD0X?4A@``"'`0P +M#0U1$,]P@`!@'`7PSW"``%0<>G``W0/P`>6Q#940$FT5>#`A`""`X`'8"/2J +M<*8/(`"I<0AV!=B$*!8IF'#/,]T@`"0 +M'#4D`!"[?#4D##-$+3X?F&#U(\P@F&"2:Y1\)W15?``DCQ^``)1F).?88,=T +M@`"T9C]G`+<&Y`#8/&0`K`'BUO'A`R_^H<#@>/'`?@LO_@AS)]_/<(``C*L` +MB`#=A"@6"0HF@"^``!1J".$4W@H@0"Z$*X$$`"!,+@`D@!6$$!,!0""4#<)T +M%&LV%!(1"B%`+A1XT@]@`#4A``#/<(``;!PD@(6`#0I1`#5\,R`5`P/PNG5$ +M*SX/`"&`?X``R+@G@!4)D0``(($E-.$U(4`$@"`"!S;P%0G1``IP`""!!33A +M-2%`!&2X+/`($!<`R7`&\-I@6G')=4AV(6TP=\PG0I,-\HH)(!`"V?0D@2/E +M#T6@`B8"$'IQR7?O\0(C@20N>0(G@"0`((,E-.,U(TX$#GBU?IH((!`"N-A@ +MHG#5`B_^#GC@>/'`F@H/_@AUSW"``(RK`!"0`%8A0`/P($`#*'9$+3X?@^`! +MWP`AC'^``,BX`(0AA,(GP1,B>#-O-7E6>75YM'G/0.Y,WD`(1$`(88/"5X")+G!N4`A#@4<\$$I@`/"N,]R@`#TYPAB"PD>`E,A +MC@`,\`T)G@93(<*YSW*``"SO+F(88!5X:K@>9EX-@!4#N!1X'F;/ +M<$4`N!LS(($#@>!EA"G"$*!8)SW"``$!K,"!"#H0M!A86(8!P +MSW*``,J/$&(X8/$!#_[@>/'`X<7Z#*`5"'6!X`'9PB%!``#8`=K/:D!+_X@H.!X!+DT>3A@1X#/<8``A!SP +M(8$`X'\FH.!X\<`""0_^HL$(=RAV2'4Z` +M2B``($$(40`*<`/P`>"#X#0$!@``VOD*E8`R:%1YV6$`&80/``#_?PP9A`\` +M`/]_&!F$#P``_W\D&80/``#_?P'BZ_&.Y1@!"0!*#>`@J7`:<$(-X"`J<+$* +M42`R=0'9PB%)`!@@0``0>WAG'!#%`$`G"!@$'D01'!#"`!0AQ`!`MB80QP`` +M(`$1'![$$7AG)A#``!`1P0``(`@1`"$&`!@>A!%6)P$8?&$2%,D0>6$`(4`1 +M`[82%,`0&F)!MAP4P!#@<`^V'!3`$,!P#;96)P`9?&`&%,(0>&!4M@84PA"` +M)P<45;8&$,``$!#"$%A@$K83MC,GPA!(MA(1P`!&MEA@";8'MLWP`"<`%``0 +MPP``)P$48+8.$<$`5B<"%RRV`"(`!`@0S`"`)P@0FV-AMA80P``"V"A+"``P4PP!Z8E2V5;8*%\$0"!#``!EA,K8SMG_PSW`` +M``TKJ7%&"&_^*G*-\7<*42`R=0'9PB%)`")X;K@<>!!X5B<#$QIC"!+,`!0A +M!0".MAIC"!+"```C00$:$<$`H',`(80`&!X$$>EQ@"$(`!IA?!+"@!EA7&2/ +MMGP1P8"`)P80@'$MMAIG#A+!`!]G-+8.$L$`-;8.%\`0&A/!`#A@.?!"(8`# +M$'A4)T$8,R$!`(`G"!`LMAMG,!/,@!]G/&2-ME83PX!RME87P)`3ML]P@`"4 +MEA&0CGH?Z(PE`I0=]C<-$AW/<(``%)4*$,P`FWP))$$0++8*$,$`#A#,`)EA +M.WD)(8$`+;82$,``&W@)(,``$K83MH'!9@D@`*EP0"2!,>H((`"I<(MQ/@A@ +M(*EP2B4```/P0"5%`(D-U0``V?<)E8`&%((P0"V#`#1[VV,&FR\D0```)$PP +MA(P"N`D@``,.?0:S`)L"N`D@``,O)P8``+,2FP*X"2```R\F!@`2LPR;`K@) +M)`P0CG^,LPDEC1"N?*:S"2*"`4Y]-20`,5*S"20,$(:S"2<'```;Q`$))P\0 +M[+,)($`#$K,!X<+Q^03O_:+`X'CQP*(,S_T(=K8*8!4H=<]Q1``(B.!XCN#*("P` +MQO;DX`'8RB"J`,]R@`"BE0ABX'\`J8[@RB`L`,KVO.#*(&P`QO;DX`+8RB#I +M`.!_`*'QP.'%"'$K"'4!`=TS)D%P@`#DXT`G`'(T>`!XJ7`'\`+8!?`(V`/P +M!-AY!,_]SW```)P3[@T/_O+QX'B.X,HB+`#&]N3@`=K*(JH`SW2``)R52F1C +M;([@0*G*("P`QO;DX`'8RB"J``ACX'\!J>!X\<":"\_]*'?/<8$`V$"@@;#! +M!"6,'P```!@KO`0E@1\``P``.+D%(14#(("`XR"W!X`!MX/R@>+,(J*`?_1! +M+8`3PKC/<8``].<(84HB`"""X`'>P'X$)8`?"````.(.8!5!*-$$&G`/#5X2 +M`^Z$QA#P@<8.\`WN$PD0(,]P```.*RH-+_Y*=@3PBL8"\(?&BB*(*<]U@`!T +M6;X.8!5`)101V@Y@%=IPF'!`)!$Q+R,')`1M*G'*+T\0`D +M034:F4"?&.`)(@(`0+<;F2&?&.`)(0$`(;>Q`N_]L,`)ZP*Z-'K/<8``E(\U +M(8$`!O#/<8``SAU)83-YA"@6"<]P@``X:S`@0@[/<(``5((>F$)X+'@O<`L( +M$P""(`2``_"`(`2`P""$#P``_P'@?TFXX'@JZX0H%@D"NC1ZSW&``*2/-2&" +M`,]P@``\:S`@00[/<(``5((?F")X3'@O"!#PE0`(+AS"'B@`?T +M!>C)<-X)8`"I<0'ERPV4D(D!S_WAQ>'&Y)IE'R;8P`CC`^``""ESW6! +M`%A%-'UT:71[>&`7"5$`SW.``%2@9H,%ZR2=)+`$V2'P8)UDL,]S@`#D'4`C +M#@EG@Y?K((0FH"T*T`!$F"*=)0F"`,]Q@`#4E#:!@^DAA":@1)@DG1$)@@`B +MA`/P\"9!$":@P<;@?\'%X'CAQ9)JE7S/=8``U!V$90CA`-L3[(0H%@DO<(0J +M@03'<(``%&HTX#4@3`X4:A1X-2$```L(`P-H<`;P@"0"%_L,`I`!V.!_P<7Q +MP$X([_V8<4AS1"L^#\]Q@0!81?4AC``$N@H@0!Z$*!8)"B6`#X``E&8`($$1 +M5'HO<(!RA+(=81EA*!%&`3)K-7D`(8".P8[B?0(FA@,_ +M8,]Q@`#4:C]GWI\()DX3OY\()8T1D7;*)2P0RB0L$,KVD74!WBTFO4?K5^/F8DY@9F&6'(HASA\"'!`!4@3A,IH@`F31$>9=*>`-D= +M9<:R!)JRG:)X#GB`(`*($'T.`"0`&K+0V0L)`P`ZLBAUSW"``!PIJ&`4L@@D +M#!"4LHAP0@ZO_VAQSW"``(@+=7@`&(`/R_.8&;T'C_W@>/'`2@^O_9AQ"'9( +M=0]Z*'`B#N__J7$T;40M/A\T>8!QAH$*((`?@`"49A)L%'@`($D.A"X6&0`A +M`A(OF*5>IZ:""3,$U^:""*"`\29T73*(BP`RB0L$,KVT7(!VLHD +M+!#$]O07#`$"VD>ATFW4?E5^?F8DY@9F&V,`YX@"`"B!![#@`C`!JQ-!E$`0#;!O#0V@D*`P!:L4AS +MSW"``!PI:&`4L0@D#!"4L<]P1`"`WUR`%21``Q$*40#/ +M"V`*&G!6#R`8"G#^"*`80"F5(R`=`!10'0`4&!T`%$@=`!0H'0046!T$%#`= +M!!1@'004"G4'\*8+8`H`%H`@`>6O?8+E$`$*`,]Q@`!J',]P@`!46`>`@.7! +M*"$"P2BB`E,@$P!$()(``"%6`U8+8`H`%H`@`!:`('H+8`H`V0#?`O`!Y[,/ +ME9#""Z__Z7"+=LEP"MFV#"`<127"(#"`<127" +M(;(-X!4&& +MM7E">``A@@^``$"5`+(W"5X@,PH1(,]V@`#(N#:&@>'*(((/``"S&<@.POTS +M;P^&-7E0AK5Y0G@`(8(/@`!"E0"R`=H"\`'B6PI5@0#;^PN5@#-O-7D5(4`# +M='C/=(``0)4U)``05GFU>71Y/&0`M`'C[_'&"6`*`=@"#B`8`=A2"T`5=@M` +M%3`<'*10'!BDF02O_:O`X'CQP&(,C_T(=BAU%@@@`"APR7`2"2``J7&Y!(_] +M\<=Q@`!D'9R!`>*<9)5\`"2#'X``J!Q^H7R!'&`"NW5[E7R; +M8\=S@`"\''^AT0J4@.!^X'B$*!8)SW"``$1K,"!!#L]PI@```2&@SW"``%25 +MA0#@#Q&`X'B@X,H@*P"*]KC@RB!K`(;VZ.`"V,H@Z@#/<8``;!S@?P6AX'BH +MX,H@*P"*]KS@RB!L`,;VT.`"V,H@Z0#/<8``;!S@?P2AX'CQP!8+C_WL'`BP +M?@X@%4'!&G!*(P`@(O#98=A@"N$*X#4A00,U($`#`GD$*7X%2G$O<+((H`_J +M<@+`!,$$*+X%)W8*YC4F0!,X8``A`24TX;EA`+%`(U,@3".`H"0!!@!`*X`@ +M%7C/<8``U!T`873HBB:"*<]V@`"4@D`F`1(5(`,DBB"!-$`D%S2*(18Y"B2` +M+X``%&J"Q(/"`-A"P`'80\`(\`"$`>``I`""`>``H@0HO@4R(4T."0A"(^D( +M%(0"P`0HO@4#Q"]P!"R^%0]A,B%-#@'"%2?!$[5]B>K/<@``9PE982]Y766O +M?0[P@B$"#<]R```\%%EA+WF")0(=766O?8(C`@UZ8D]Z(GHO)8<@`B52$`#? +M!"R^%2]Q!"L^)@#"+W6HYP0J?@;L!NK_"B%`+KEANb=A@#.$,X/0AP0/T +M(,`#`GD$*7X%2G$O<)(/8`_J<@+`!,($*+X%+W"Y8-EA#.'T(<$#(G5988)U +M-N7T?2"U`>?O?P/$SO'9`:_]I<#@>/'`J@F/_:'!&G`/?7H,(!6I<('@`=[Z +M"R`5PB:!$R\A!R#2"R`5R7!:<+H,(!6I<$8-K_^+<0#=`O`!Y8\-E1``W@\F +M3A,+)D"4^?,$)HZ4`=\`PL(GP1,*<*EQY@ZO_^ESF'``P@IPJ7$N#Z__Z7.` +MY@':P'H!V14AA0``V@/P`>*["D6!`-L+\,=V@`"49MQDTIP`(`$!V6$RM`'C +MY0O5@$0M/A_2:@IQU'XG=H0I%@EU?@`F@1^``+1F+W298>:)9>\`W(:IZO'/ +M<8``5(*$*!8I7ID`(8!_@`#4:C^96:`ZH,]P@`!D'EZH++`=`:_]H<#QP,(( +MC_W/=8``)!X\'80?``#_?\]P@`",JVX,(!7@B([@SW8``/]_RB&L`<7VY.`' +MV@( +MG0D@0``?M9T`C_W@>/'`*@BO_0#9SW"``(RKH(@+\`#;9Z82:11XF&!IH`'; +M:J!+H`'A1PF5`!)IA"T6&15XSW*``-0=!V("VL]S@`#4:B]P?&`5)$X09>]' +MI@#,FXU>5EAU@W@'`K:`>8S +M#I40O@D@%0IPT0@>@`#9\0E5@80M%AD2;A5X`-HG<,=P@`#4:C5X7K!?L`'A +M\?&Y!T_]X'CQP"8/3_T[<'H,8`DH=X0H`0RR;\]V@`#D'+5]`"64'X``9!T` +M)E$>5298'T`A`"9P%`(@,-FZ<8#B2B``(,HF(B@']"Q_YA;6$#`@4`ZJ<`Q_ +M`"%2+AP2%R!F"B`5*!(3(8'@`=MP%``@PB/!`(#@Z7`J<07R/@MO_VAR!?`R +M#&__"G(.>,]Q@`"4E@H:!"`PD8KIC"`@C`?T9!8`%@'@9!X8$&GP"!)!(2)X +M#GHT($`S'_`5)8(#`"*,#X``M&8&Y"QD`B>`(PUXDNR`/'`0@D@%>'%4@D@%0AUSW&` +M`.0<@>7,(&&`RB!!`(`@A0\%\BAP@"`%#R4&;_UA&1@`X'CQP)8-3_V$*!8) +M`=X`(8U_@`#4:MRE#W]6""`5Z7"!X$HA0"#"(4$D>@@@%>EP&G"V""`5Z7`( +M=TP@`*#,(6&@&?2:#^`4R7`5Z%784]G^#>`1Z7((=L]P@`!X63`@@`\``.P, +MO@W@$>EQ"PX`$`#8'*6)!4_]X'CAQ>'&`-J`X`';PB/,`(HA_P]T>2\@"0#/ +M=(``J.`$VPWP`-T/)X"$ +M;GN">`Y\`6J1<\H@B@`4>"QX+W#!QN!_P<7QP*X,3_VVP0AV.G$:ESBW!:<*()X`GI<0'8R7$(`)Z7%*<(IQH@C@"0IR0H8!Y0*Z57H`(L$$(G*:#Z`)"G`BA@*Y +M-7D`(4`$8G$Z">`<%-H:C@00`2"5#220`"55(`080"5)!&_]ML#QP`H,3_V^ +MP0AVBW56"B`*J7!"A@#8#R"``$/"1,``AD+`!(9-P$R.SW"``,@1#0KR`P'9 +M`8`#\`"``-I7P$["8H8"V(3K1 +M#N`)J7`5!&_]OL#QP.'%#'B*(?\/`-V,O4$IP',$#;_TO<"\@"0",(`6*\<#']RX,;_V*(04**'",((2#`=K(][3< +M#B`!`R\@20"*(O\/VN#(][3<#B`!`R\@20!3>AMX!.`CN,]Q@`#L$/`A``!, +M>"]PT<#@?L.Z!+K#N45Y(*C@?V&HX'@B>`YX@N#A(,D'RB"I`(HAOP\P<.$@ +MRP?*($L`X'[@>`#:,'#*((L/_____^`@RP;Q#E61`-S[#-603B2#$+EE +M-GEZ8U1Z66%2;51Z=7IS;G1[QW*``!2J*.)S8D0N/A]3(\(`#+I.>L=Q@`#4 +MIB=QZI%,ND)_ZK%N>NN92+I"?^NQAB/\`PB[;GM)D4R[8GI)L0'DT?&!`D_] +MX'C@?P'8X'[@>/'`X<5J#N__"'4(P3R`>)0>PD(,P%@L83H`-@#\(#8X'[QP,]P +M@`",JZ8-X`<`B`KHY@K@#@W8_@L@"`W8`=@#\`#8T<#@?N!X\<"*"4_].G`: +M<0_8`-DH=2AV$/`$($P$!"$"!`4DOI`/)8\3RB7"$W8,;_T$V@'FY0Y4DKD! +M;_VI<.!X\EB@T@%Q")"')6)L`4C@M@$,EQ!H4$ +M(+Z/``0``0GR"84<'8`?@````)2X":51#QX06@Z@!,EP)H5'A1,)G@<)A84B +M`02,N`FE1Z48\-G)@"`&`!L)W@E-(">N0?PE+J6 +MND>E-(">N9^Y-*`U`4_],LC'<(``%+@HB`'A**@(B!L(,@'+$@&VH!F`#P,` +MA`"*(`@`TAH8L`GPBB`0`-(:&+"@&8`/`@&$`.!^\<"&"$_]&G#JR2AW)0@> +M!\]S@0"X'/5[,!,$``'99H//<,7NA?(H!\]S@0"X'/5[2!,$``'99H//<,7NA?$H0IP`-@`I0;8!J4!YKD.E)'/<($`N!P`V?5X(*`FH,]Q@`!(%`"! +M"P\!$`;8`*%1`$_]X'CQP,]P@0"('%(,(`(PV<]P@0"X'$8,(`)@V0;9SW"` +M`$@4(*#1P.!^\<#AQ<]U@``$(#2-@.'*(((/``!6*Z0)@OT4C8?H%8V%Z`'@ +M%:T!V`+P`-@-`$_]\<#AQ<]U@``$(#6-@.'*((P/``!8*W0)C/T5C6&X[0$*`D/`"&2?X``(#T`(91_ +M@`"`/02X%G@`()4/@`"@1]H.8`8<%0`@5B*.(_IPBW`:<,]Q@`"C/<$0`#/(` +M@)WH-PF2`@".,PB2`H(*X"$`V`38SW*``/SY"'%`&D(`*+E!&D(`*+E"&D(` +M*+FF":`@0QI"`*_Q`!,`($&(#0F#`&*.`XA%"P(`"0F"``".`_`"CD'`0,4! +MCD+`!HY#P``1`""`X,H@`03*(H$/``"B`$@.H1O*(2$%A"T!'`'9`"&`?X`` +M61<@J``3`2!!C@")#0H#`$*.`HDG"@(`/!4`((_H"!__J7`" +MO4-U*A4`%@'@*AT8$`#9%1Q"(&D%+_VEP.!X\<`>#0_]I8"CP31M-GD`(8`/ +M@`"\1T`@$@B$+0D?+W8`)I$?@```/1(.X`H`$8`@>G`R"&`=J7`^#.`&&G`` +MWS?H$!(`((P@_X]*]`,1@2",(<./1/(`)H\?@``@.WD7%!82:<=PH`"`+C00 +M$0``)((O````$`(B0@13(M4"38"4X`;T@@Q@$ZEP!^C)<`#9 +MG@G@$BAR300O_:/`*0!@``6`X'AE!2``!8#@>/'`W@L/_9(-(!!:<#IP0"H. +M(=9^"B2`+X``H$=`)``GV&!`(!,(`-\,\+1O8G4(A0?H`-G.#V`&&G$@'0`4 +M`>?K#Y203"$`H'GRA"H)+P`AE7^``"`[`!40($`D`"<>9D`F%!A*(T`F`-T2 +M\$*&@.,JND6G&(X!X +M\<"F"@_]Y8#/<(``-*RW;[1]`"!1`\]PH```(&P0$`"$+PD?SW&````],B%. +M#L]Q@`"$.S`A0`XWZ!-N%GC/<8``T+$`8;'HQ@I@$^EPMN@<$0`@`B``!&$( +M4P#'=8``G*P`A0SH`-@`I0`@@2\````4Z7`Z"Z`*!-H@\!B%!N@."&`+Z7`: +MZ%H/(!_)<([HSW"```0F\"#``P`@`2#I<`X+H`H'V@KPSW$!`/B[R7`0VGH, +M8`L`VU$"#_T`VP\*4``5"I``:'(*\$$I`@$HN2)Z!O!!*0(!)[DZ8E!P`=C@ +M?\(@#@#@>/'`X<6E@/8,X`JI<,]P@``!X\<"""0_].@Q@"PAWZ7`` +MW48+(!"I<=-OUG['=H``G+&MIF()(`OI<:^FL:;!`2_]L*;@>,]QH```(%N! +M![@4>,=P@`"`(GHJ@`;I*(!982B@`-DJH.!^X'@'N!1XQW"``)RLSW&@ +M```@.X$GH`'9X'\JH.!X\<`&"0_]"'?`@2AUA"X)'\]P@```/3(@4`Z*(00` +MSW"@```=+J#V"&`+R7">"R`+R7#/<8``'+8"@1`@@`,"H1$/D!);A +M"N`*`=L=`0_]\<``@<]Q@`#0K`>X%'@08>FXI`WB%\!XT<#@?O'`X<4%@#=H +M-'D`(8T/@`"`/>@6OR7"*#J`?`=FB"*`*R7#'=8``G*PRC/'`X<5(=9()(!``V0>X%'C' +M<(``G*LIA2]Z$PI1`#J`H+DZH`'9*:@(\)+:1'D="8``.H"`N3J@SW&@```@ +M.X$CH((*(`L!V?4'S_SQP'(/S_S`@`AWMVZT?<=U@``@@2AVA"T)'\]P@``` +M/3(@4`[2"2`+*'`3#Y$1J7#6"N`*(-E&#R`+R7!`*,`@%GC/<8``T+$`89CH +MJ7!B".`*!-F4Z!=M%'C/<8``G*P`88SHJ7"N":`2`-F(Z!J&AK@:IKH,(`NI +M<`4'S_SQP*(.S_R$*`D/SW&```,]+W))88PAPX\W\G)I,".##Z``M"Z4X/'`%@[O_`AR`H$E"%$`A"H""L]V@`#@2B]U`8%J"R`02'$( +M<1H,(!ZX9@7PJ@I@"TAP50;/_.!X)0`@``2)X'CQP-8-S_P(=BAU%@@@``2) +MR7`J"2``J7$M!L_\\<#AQ0AUSW"``-2_1@W@$/`@0`,3;19XQW"``)RQ2X`& +MZ@#9*Z"I<&!ZDMD%!L_\\L=R@`",=P +M@`"0`AC`^``,VQ8*S*#.`*2'%!!<_\X'CQP.'%9(D!W`"! +M,VLV>0`A@@^``,VQ@*JF#.`*:'$=!<_\X'CQP)(,[_P`VP"!*':$*`D/SW"` +M```],B!`#@01D0#/:42``8!W1`@0`2E&A@`0X9`*<`@ +M%GC'<(``G+$:<$N@`-@#I@B6"+DE>,]W@`"XORB.J7(*)$`$+R7*``HF@`\` +M```8^@R@$/AWSW$!`#C+Z7"I<@#;H@R@$$HD@`'/<8``U+\5(4$$`*$A"(`/ +MK:O^RL]P@0!P-*6@")8-"($/````$#(80B-!!,_\\<#6"\_\H\$(=X0H"0_/ +M<(```#TO=:Y@S@R@"LEP6G#N#N`Z#G`'9A7I&#B`?I7MQ`\_\X'BAP?'` +M\@K/_"AV1,%H=4&CBB,$`"<)'@)1(,"!`=C"(`$`![A!+D$19'D%>1F-B;D- +MN"5XCK@"I6/P%8T%Z`-J1B#```&E02Y#%,&[!":"'P```!@DP2NZ1+G!N0'A +M`"G,`&&\!":$'P@```#XC4$LQ`3[?X8G?A`'O.5\ZY53)L`0"K\$)X\?!P`` +M_.5\02Y/$\"_%;_E?/2-%K_E?/F-%[_E?$`L3P?E?).\E+R>O!L+M0""I03K +M$PF5`(+AS"*N@,P@;H(`V\+W`=LY835Y`[IJN55Z.F)88,]Q@``$[@AAAB#] +M#P4@_H#*(((/``!4`,\@(@/\"R+]RB&"`P"%4]D%N!&Y`:$!A0\.'A(#H0*% +M!*$/\,]QI@```1"A`X43H0*%$:$$A1*A&8T#Z`>%%*$(W"\"S_SQP,X+``7/ +M<*``@"!<&(`/`P!`#='`X'[QP(X)S_S+$@&VH\$0$94`SW"``(RK`(@`WH0H +M`0//<$4`?BTT(%`.SW>@`(`M,L@=I]G)I1(-MX`A`@#L$!('1B7`$*4:'+`) +M@<.Q4R5^D(2XI@(A``FA0"W`(!5X`""4#X``[,D.%``A$PA1```4`""&(/F/ +M@@("``HC@"^``"S/`!,`(`HA@"^``"S-`>``&P`@`_!2"$`1/H?["=Z%1PF> +M!5,AP@("ND$I``..XL.XT"&E!9GWS!(,MF2Z5B0#%$BS=!R"$\"T=1R"$\>C +M$*S+R=VS08"&(O\-A+I!I!*(R:,2K*,)G@7,$@^V$(^7"$$%R\D!@(\('@$= +M"5X%`-A2#V__Z7',R:00```MN(8@_PL%?0SPT@R@%JIP"')6)\`4U@K@#\P2 +M`;8`%``@"PA?!,P2`;8M\,L2`;:8$0``Z+C!*.(`TR!B``GT$0B>!I@1@`!$ +MN,&X`_``V,P2`;:8$0(`Z+K!*N(`TR)B``GT$0J>!I@1@@!$NL&Z`_``VHGH +M!^JZ$0`F`>"Z&1@@L_`!@<,(W@"8$0(`I!$/`-D2#K:+<\EP@"`&!U8F1!Q6 +M)LP<)0\>%>BZTR*B`-,BX0!(8,]R@`",[0"C'7C"N/0B```!HT/P-0I>`D$J +M``'!N`ADB;A`P,]P@``@1QR`(,)$>$2ZP;J&(/\.6&#/,*X]"(```&C +M$?!=>,*X,B0``,]R@`!\[4#`'7C"N/0B``!!P`/P0,9!Q@#`B!D``,P2`K8! +MP%8B`01F@0*Q%0M>`@F!@+@)H0K8=AH$``CP$-AV&@0`")$)"Y\&`-X(\`3@ +M"+$$V'4:`@`!W@:!@"(#!9(+(`XHD'%"B4`D`?RV@\@#AG8+@F@!QG8#0>O +M_*EP\@```@;!<0$,]RH```/#""SW6``.0;$H((N1!X%7E3@FB% +M):5`)1$=(PNE`$>E`B+```T(E0`&A1,(10`)A4BE`>`)I0"%G[@`I0:%"0D% +M`$2%66$">8PA$(!J`"X`(:4@A<]VH```1P'A(*40'H`?!@#\AHHA$`!:<<(. +M(!NZV@#8EK@!V:ER`]LJ#B`?F',4'H`?!P#__P:%(H5"`*I0R%SW*``-C8\"$!(`:" +M!(``@!EAT@O@'4AP&X<"(``$[06O_`NEX'C/<*``@$4X&(`/`,`D`.!^\@`V):XSW&@ +M_HP)P@G@$>ERSW"@`&`,*(@(B`IO`-FF"R`4"G)E!8_\X'CQP,]PIP``@"J` +M*+E8@"]Y*+JD$`,`3WHHNV][XN%GW,PB`8-DW,PC`8,'\L]P``"E*.(.S_S1 +MP.!^X'CQP,]RIP``@"""@.#&(2(&Q2$A!B"B#PA1`!8((``!V`/P;@@``-'` +MX'[@>/'`F>B6#\__`-@2\,]Q@`!,*O`A`@`IV1*Y\"&"`,]Q@0!X*Q5Y0*$! +MX`]XX0C2@A7P`-@1\,]Q@`!,*O`A`P`IVA*ZSW&!`'@K\"$!`'5Z(*(!X`]X +MXPC2@M'`X'[@>`#8$O#/<8``3"KP(0,`*=H2NL]Q@`!X*O`A`0!U>B"B`>`/ +M>.$(TH+@?N!X\<`*#*_\`KD:<@_:SW:G```H0J:`X,H@8@`!W10E#Q"!N2"F +MY*:CIJ()H!\RV`'G0"B`((&X`*;DIJ.FC@F@'S+8,02/_.!XX<4IVQ*[%7L` +MW`CP\"$``Q4C#0,`I0'D]0R$D.!_P<7QP*8+K_R8<`#:#_!88A1X="`.`2G? +M$K]BD*&0$+ME?=5_H*`QZ+W"*(L\/ +MB^G/=*(``+1(A(8BSP]%>`BD$_#/<*T``*98H,]PK0"`L$B@BB+'#\]PK0`` +M9EB@SW"M`(!P2*"`X'$#P`[! +M`\`.)07`#M4#P`[QP.'%SW&``-RW%(GP(0T`SW"``-`J#@C@':'!`H5;"%$` +MBW'/`+PQ;@`H0#!!H4!VB"@!H5$J+8,8!0$V`;PSW```!,K +MP@O/_,]P@`!4@@J`@>#T"<(.SW&B```(!H&DN`:A`=CJ"^`.`-DE`J_\H<#M +M`\`.\<#/<8``W+<6B13H8;@/>Q:I%(D!X`]Z%*D+"E$!`-@4J8#CRB`I`+`+ +MZ0[*(0D`T<#@?O'`X<7/=8$`#"P@A<]P@0"D*SF@`-O/<(``&"M@H,]R@0`8 +M+`>":*(!X`>BSW"``$#!HA"$`*,0A0"@$`8!`=A!A?H)8!]BA<]P@``(*V"` +M!>L`A2&%8'M"A8T!C_S@>.'%SW.D``!(SW2D``!$*83/<(``)%0@H`&$SW&` +M`!A4`*$@A,]R@``45""BJ!,-@,]R@``@5*"BHKU_VD5X17D`VDFD`:0@I*@; +M0(/@?\'%\<"J"(_\.G!*(@`@2G4^\`H@@"^``&0S0"``(:]@SW"```Q4((`? +M#V,0`-C/<8``!"L@@0(G0A``$`$@,'+*(&X`SW:!`*0K%25"%'IP5'X0CA/H +M`=AR"Z_\`-G/04@?H`)]!&.#P\#$``0`"`0KO&N3",` +MH,HB8B`!Y8D-%)%O"A`@`-TS\`HB@"^``&0S0"(`(:Y@SW"```Q4`(!-#@,0 +M%250%`'8`-D2"Z_\"G+/=X$`#"QAAX*'!'LD?`4C/H//%>$5Y`:/'`M@]/_`#= +MJ78:=0/P0"!0(#\(E2``WP+P`>?S#U62;@H@`.EP`-GS"16!SW"``&@S*F#/ +M<(``A"B`@-MB`6V1'N\<]W@``,5(#ERB""`\HA0@,`#6(. +MRB+"`\]P@`"DMB"``(`"GSW&!`*0KI0=O_`"AX<7AQ@#;@>`TV,HBH0/* +M(*(#RB+"`,]TH```(-N$#O#/=(``$,+P)(P0`B8-$P7LL7'`(V8``>+I"@2` +M:'#!QN!_P<7QP.8.3_P*((`O```/)PHB@"^@```@;!(`(`#=>G`Z<`GP;!(1 +M(,]Q@``L(`"!`>``H0(AP"2!"(4/`0"PK0#>#?#/<($`B#?P((\#?@D@`.EP +M[@WO_^EP`>;/<(``(+P`@.,.!)!L$@`@SW&``!0K`B!`!!)PRB`%(+%P0('/ +M<8``,,#P(8$`RB4-$)<)!8#/(`-T*Z7X.;_R0$H``@.$8WL`N(18$\@#>G+X` +MWQ3P$F\4>,=P@``0PM00`0'0$```RW@'\DH((!0O>(#@P"5A$`'GSW"``!#) +M&(C5#P20H05O_*EPX'CQP#(-;_P(<<]UH```(-N%SW"``'0-\"!``,]R@`!$ +M#?`B00#/`$H<]RI```2'X2`(;/<8``9#,/>(`2`H8`H42I!"*` +M#P```/\HN`6I!"*`#_\````PN`:I!"*"#P#_```XN@D%;_Q'J>!XX'[@>/'` +MA@Q`$7(,0!%>#$`1T<#@?N!XSW```.4.;0:O_.(2`;;@>/'`:@Q/_!X*(``( +M=@HE`)`J\AKN$0Y0$(+FM`\A`#*($(#G`\B`V5Z0*#@?L]QH```!`6!!*$#V!6AX'[QP,X+3_PH=E8A +M#P0FAP0AOH\!``#`H<$P]`:'0,`!VA4('@)!*,(`P;H!XC&XP;@:8@[P&0B> +M!B#"!""`#P(```!$NL&Z`>(QN!AZ(0I0`!,*D`"#X@#8RB#A`<`HH0,*\,]P +M@0"(-@*`!O#/<($`B#8!@`5Y)J8(&ZWH*0!S5N+A@$?!`*8`" +MSW&@```@.X%\$@(&0GD#\`)Y`0A$`+A@(GC!`4_\X'B$*`D/`"&`?X``M#O@ +M?N!X\<`B"4_\"'8:4!VL(B@0`!V%1X"P]E$`6F(J8H=T)Q`B$` +M!#^X4B``@`;R$!Z`%+BN'?`"($`@O@EO_.EQ`>`+"&0#_]D9#4$0`B4"$#!U +MRB&"`#BN!2C^`P;P!2]^$Q@>0A0`(8!T!*;E`$_\X'CQP+APZLDH<]AR&P@> +M!`@3!`#/<,7NAIA`@P'9L@N@'F&#T<#@?N!X\D"@/"XRB"!#P``Z1ST"('\?@Q`#8(.8!*I<&4' +M#_SQP.'%SW"``%@5`(`,Z,L2`K8`V):XSW&@_H@,:@M@$:`2`@`J#L`;SW"@ +M````!H1*!`>`2H!Z7-B;BE&ARPH!$``/NX[`Q"$>K),0@>`,L2 +M`K;/<,7N@C4!V18)H!Z@$@(`SW.@``!%7(//<,7N`D)X@_X(H!X`V0/9SW"@ +M```$**`E!@_\X'CQP&X+P`4J"8`-<@@@%`+8Q@T<#@?C$`(!0"V.!X +M\<`J#0_\SW"@```@NX"6#B`%#-CJ":`%J7`*)@"0RB"!#P``1S#\#F'\RB&! +M`P*&C"##CQ+R`X8`V0(@0(/*(6\`@.'*("$`UW`````0!-C*(.8`@@Q`!4$% +M#_S@?P'8\<#*#`_\"'4H=L]P@`#DY2"`00X0$=8,X`7)<'H/H!,/>,]Q@0"( +M-B&!)0A1`(0N"1_/<(``1#LP($`.@.#/(6$`SR'A`,\A80($\D4A00,`VPKP +M%FUU>``@@@^!`-A`(*(!X_$+%(0`V\]Q@0#8/Q8A0@-@JF&J`=@"J@/8`ZIH +M<@;P.&*V>&2H`>+Y"A2!J00/_`;HSW!%`)0LH-D$\"AP)-F5```!X<6$*`D/ +MSW&``"@],"%!#ISIA"@""@`A@7^``(!*SW6``!C:`-R*H0;;;J'/<@``((E- +MH0^AL*&1H76ASW(``*B(5*$6H;>AX'_!Q>!_`-CQP+(+#_RJP0AW&G$Z&Y2"0`H=`X88@?P\X8`/@!""4 +M#P``_/_*)4$5"?+/<```!$)^#6_\J7'_W8G!>@GO_^EP08<`)!0@()(982"R +M_@[@#ZEP@.#*(($/```'0E`-8?S*(8$#%!R`/P"````#AP"0AB#]#(P@`H)O +M(4,`"/1O(<,`%!R`/P"``0`#AP"0AB#\`(P@`H`#]("Y1<$,'(`T9,88'``T +M'!Q`-"`<@C4('`0U0,>+<:EP2@_@#VIR)0,O_*K`X'CQP.X*#_P(=00@@`__ +M````,+@O)@>0RB!B",`H8@+(#&+\RB%"`\]P@``P+/'`#@H@$`AR"'$`V`+P`>`;"$4`A"H+!')H=GO/=($`?"`G@='` +MX'[@>`#:1J!%H/_9(Z`PJ"`80@!$L(HA_P\B&(0/``#__^!_(:#@>/'`X<4( +M=<]QH```!$^!SW"``.B[0*`&V`^A))4!A98)(`)"N0QP%0B?`<]PH```'!P8 +M@`\!````SW"``.B[((#/<*````0OH`6%I;A=`B_\!:7@>/'`S@DO_`;:IL$( +M=BAUSW>@```$+X?/<(``Z+LZ<""@3Z<4%Q`0,@I@'DAP))8P<,H@A0\```A" +MG`M%_(HB_R\3#8`4H::EIP^'#PB1`:>G`_`$'@`4!8:%N`6F`(:+=D#`C@O@ +M`,EPN@N@`\EP%0V`%!0?`!0/APD(D0$<'P`4`!$`(`^GJ0$O_*;`BB/_#Q-Z +M@.#*(VH`RB"+`'-\,WJ`XH#ARB,+`\HABP`\>3A@3+AL>.!_+W#@>,]P@`!$,N!_ +M`(#@>/'`Z@@/_`AV!@G@!2AP"'7^".`%R7`(=HH@_P\0=LPE`I`P\M(,H!.O +M>*F(R@R@$\]XR8A>#>`>J7#/=X``].D(9RD($0).#>`>R7`(9P#=%0@0`CX- +MX![)<`AGA^#*($(#$?0!V`_P*@W@'LEP#F`>J7`(9Q!V`=C`>`/P`-C5 +M``_\X'@$N,=P@`#4ZV"!@(!@I"*188`@HR""8H`@HR.``I(`H>!^X'CQP#(( +M#_PZ<%4(40``W2'PTVW5?L=V10"4+.&&"!80$(4O`1DOA&*$!Y:]]"B*`+T4`M"O%#=*0SW%%`+0KY0?O^P`90`0`V0GP +M_]H6($,`1:,`VD:C`>'U"=2`X'[/*8$+>0'8X'_"(`$` +MX'B`X`'8RB`A`-T"P!8Y!0`6\<#AQ0AU`-A""B``J7'>":`3KWB!!^_[`-C@ +M>/'`_@[/^PAVSW6``(`W`(U+")`!N@F@$\]X#PA0`+H/[_\!V`3P^@H@``#8 +M`-A."B``R7$!WZX/[__I<`+8O@H@`,EQ9@@@``#85@P@``#8!M@`K>&MZ7`" +M\`#8#0?/^^'%`-G/0GT +M"N`/(0$`#(LDH@'@#*L(\,F\*WP&]`7@#R$!`"2BX'_!Q>!^X'CQP%8.S_L( +M=3H((``H=H#@S"8BD`?R!@^@$ZEPH@J@$ZEP$@@@`*EPO@L`#ID&S_OQP`AQ +M3@D@``#8`-C1P.!^\<`.#L_[&G``W=H(H!,/>('@`=_/=H``@#<`CL(GP1.# +MX,P@HH$-\H?@J7`=]&()(``*<8#G_`DA`,H@00.!YZ@.X?_*("$``=^N#N__ +M`-CI<+X)(``*<68/[__I<%8+(`#I<.EPH*X-!N_[H:[@>/'`"''.""```-@` +MV-'`X'[QP)(-S_L(=\]V@`"`-P".2PC0`$X(H!/I<`\(4`!.#N__`=@$\(X) +M(```V`#8X@@@`.EQ`=VI<%8)(`#I<0(/[_\`V.X*(```V"X.[_\`V`/8`*ZA +MKJEP`O``V*$%S_L(`!W?X.8!/")4$3"'+)<.(*H!:I<5D$S_O@?N!X\<#AQ0AU`=@& +M#^__J7&B#F`3J7!%!._[`-C@>/'`P@O/^PAWSW6``(`W`(U)"-`!?@Y@$^EP +M@>`!WLEP!/)Z#,__!/"Z#\__`=@2#^__Z7%R#.__`=@"V((/[__I<2X-[_\` +MV!H)(```V`?8`*W!K0'8`_``V-4#S_O@>/'`9@O/^VH((``(=0CHKWX:#*`3 +MR7"Z#V`3R7`.""``J7"U`\_[X'CQP,]R@`"`-V"*&0LU`@#9,R;#<(``N.)` +M)P)R='H`>BAP#O`Z#^__#W@*\/8+S_\&\&H-S_\$\.(,S_^2"``.T<#@?O'` +M\@K/^_(-[_\(=AIPSW>``(`W0"<`%?`@@`.DAU5H!7I`*($"17F?N68-X`DD +M?23H4R6^DPOT$(<3"`4@^@[O_\]X"'<'V!7P4R5^D@OT#8<3"`4@I@OO_\EP +M"'<&V`GP4R4^D0KT_@SO_\]X"'<#V,EQ`-H*\&X,[__)<`AW`-C)<5,E`A%^ +M"(`>S0+O^^EPX'C@?N!X\<#AQ0AU`X"!X`'8;@@@%L!X!(5"(`V`RB5B$(8( +M(!:I<,8-0!.Z#R`&J7&M`L_[*8`E"5$`SW&@```P,!F`#P"````*@$`H@00E +M>,]QH@``@`*AX'[@>`*`@.`!V`$"(!;`>.!^X'CQP/8)S_L(=DAW`-WN#&`3 +MJ7`(<@&&U@B@%@'9`88)")$`H*\]`L_[X'[@>/'`)8`S"5$`!H`*Z,]P```% +M0K8++_R*(40`'?`!V"H-[_\`V6X*H!,`V`X.8!,`V`'8`-D-\`#8#@WO_PAQ +M5@J@$P#8\@U@$P#8`-@(<:X,S__1P.!^X'@H@,]PH@"P;,]S`/S__R$)4`!` +M@(+A!"+!`,4A@@\>`0``Q2&!#QX#```(\""`9'D%(8$/S@(``""@X'[QP.'% +M)("(Z2.`#0E0``6`%PA1``#8SW6@```0":4*"4`6`=@)I8T!S_O@>*+!\<`& +M">_[F'$`V\]R@0!80`HG@`^``&3)`!<&`*&"3"8`A!#>RB:%$6AT"/`P=/'`@@C/^PAV +M!8"*)0D?K'C/<(``(#U`(`\"0"`0`R=P(H`="5$`(8#//'`#@C/^ZH)(!$(=T6'BB8)'\QZSW6` +M`"`],"5!'AH)(!$`V,(*H!,0V`6'".6$*`(*`"&`?X``C$JN#>`<..`%APC9 +MS'@G=3$`[_L@I>!X\<#/'&SW6` +M``@YSW2``$0H`-F*(+\-*',,\'ID(*J'Z'YDSW*``&14P*(!XP'@#7@1"Q4) +M,R5"$.,*`X`!X?SQP<;@?\'%X'C/<8``\#@S@>&YX2#"!\H@8@",(+^/X2#+ +M!\H@JP"8X.$@R0?*(.D#0"#`@<`@9``<>.!^SW*``/`WD8*,),.?$/(6@@[H +MSW.```@YSW&``!\XB6$S(P``,R-!`")X`_``V.!_8!H"`/'`F@Z/^\]R@`#P +M-P&"R0A0`,]S@`!0.":+`!/,`$(A1@`($X4`SW"``!`X0"#$`T`@!P0?#1`% +MRVG=8+"-V&#TB`%I\77*)@D`RB:,`V*\C7PR)XT!"B>`#X``\#A`)P`&,R!- +M`\]V@`#P.9UESW>``#`XL;$`3=H:(B'X0? +M``#_#Z.&!?`"W:&BBB7_'Z2FL8*,)<.?$?(R)$T#,B1!`#,@30,S($```GVD +MJP\-$`4"Y:2K`_``V`2K":`:`M@!V<]P@`!P."&@SW"@```=-!B`#P`"``#1 +MP.!^X'C@?N!XX'[@>/'`X<4(=9_@RB"&#P``B#/\#L;[SW"``/`WMJ`#@!,( +MD0`N#L__7@[/_[H+0`!I!8_[X'CQP.'%I<$`V0KPSW"``$PY-7@`&(`/``#_ +M_P'A[PF4@,]U@0"L+4#%SW"!`-0M0<#/<(``(#I"P,]P@``D.D/``=A$P!+8 +M`]D&V@#;"B2`#X``2#H*)8`/@``H.DHF@`+"#6`.^'//<0``,),."*`.J7#Q +M!*_[I<`R$@(VR\G_V1R0'0K0`!4*D0&&(/P#P.#0W,P@`H,$\BAP`_`!V.!^ +MSW*@```?((((Z`""H+@`HD$I0`'`N`CPAB']#T(A`(#*(&(`X'[@>`'8SW&` +M`/`W`*$!H<]PH```'3@8@`\`$```.!B`#P`@````VE:A8!F"`&(9A`\``/\/ +M4Q$`!F09@@"CN%,9&`!>H8H@_P_@?X09&`#QP.'%J@]@&@+8"'7/<(``<#@! +M@,]Q@`"DWY/H`($!X`"A%0B1`@#8`*%GV`>XH@WO^ZEQ`MCR#F`:J7$0\`#8 +M`*$"V.(.8!JI<>"]O`@"`.&]D`@"`.*]G`@"`/$#C_OQP&X+K_L"V#(-0!I& +M#F`:`M@(=0H@@"^``/`WSW:``'`XXH:&(+\+D.#*(($/``"),\HA00-`#>'[ +MRB+!`S$-'A`,$``@&0T?$1CH`8:`X&`-PO^>#V`:$-@0\`[H`8:`X%`-PO]2 +M#```"/`-#QX0`8:`X#P-PO]=`Z_[HJ;@>/'``MC^#&`:`=G*#<__T<#@?N!X +M\<`"V.H,8!H(<;H-S__1P.!^X'CQP`+8U@Q@&@#9J@WO_\2XT<#@?HPA%X?Q +MP$@`*0`(+9"A2!X'[@>/'`-@J/^\]U +M@`#P-R.%%.E/%0X6!8#)<88A^P]"(0*`RB)B`&H(8```V3(/X!`FV$\=F!-Q +M`H_[\<#^"8_["'7/=H``\#<#AB/HA@N@#@6%/PA1`$X6`19/(4``3AX8$,06 +M`!"`X0'@Q!X`$(`)(0#*(&$`SW"@```@.X!%A98A2`//<(``!#K6#Z`<1:`9 +M`H_[X'CQP.'%SW6``'`X((7ANI17H`]AR"V`:`-D#V!H-8!H!V<]P +MH```'3@8@`\`"```.!B`#P`$``"%`8_[X'CQP.'%SW&``/`WA!$``!KH`X$Q +M")$`,8&,(<./$O+/<(``'S@M8`/8--D>"V`:J7(#V`#9P@Q@&HZY8@D@'JEP +M/0&/^_'`X<7/=8``\#>$%0`0%>@$V$X*X!D`V0/8`ME`)0(6%@M@&BAS9@K@ +M&038`]B&#&`:BB$$``4!C_O@>/'`X<7/=8``\#>$%0`0%>@$V!(*X!D`V0/8 +M!=E6)4(7V@I@&@S;*@K@&038`]A*#&`:BB$(`,D`C_O@>/'`1@B/^PAVSW6` +M`'`X((7/=X``\#?AN3A/'`X@]/ +M^\]W@`#P-SZ'"'53(4(`@>`!V,!X@;@'(CZ`RB"!#P``@S/`">'[RB)!`QZ' +M`-E&(,,`3R-"`%ZG"B"`+Z```"#/=J```!V:N0?M12/"`"VF7J<"\"ZFA!<` +M$`WH`]C&"6`:`-D#V&X+8!H!V30>@!\`"```;!``(,T';_MD'Q@0X'@!V,]R +M@`#P-P&B`-C/<8``4#@$J0."8AJ$#P``_P\M")$`!8DE"%$`"(D="!`*.X(= +M>`(A`P`X8"B"#0M$`"F""0D%`(#8`:+@?N!XSW"``/`W9A"#`,]Q@`#P.%&` +M$X%0<]`@80#/(&(`X'\3H>!XSW.``/`X$X///'`F@Y/^PAV=@H@`"AUSW"``/`X'H`?"($/``#_ +M_\]Q@`!P]L&AI*$!V`*A<@@@``38V09/^^!X!^C/<:```!\`@8"X`*'@?O'` +MX<4`W0WP"B!`@\H@8@`3>,&X`^"6".`0`-D!Y>T-E)"I!D_[X'B`X/'`"`@" +M`-'`X'[QP.'%SW6``/`X'86"X+@,P?\`V($&;_L=I>!XX'[@>"AR#WG/<($` +MK"WU!P`.X'CQP.'%`($`V@\B`@#/=8``\#@4A6&X%*4`@<]Q``#__U4EPQ4) +M"-$#/J4$\!5[(*,9A5)Y)'@9I1J%)'A:#.__&J7_V"$&;_L5I>!X\<``@0#; +M#R,#``.!0PA1`,]R@`#P.!2"8;@4HB"!52+`!35X`!B`#P``__\9@G)Y)'@9 +MHAJ"!"!`@!JB`=@U@L(@`0`+"$4`<@WO_Q6BT<#@?N!X\<``@0#;#R,#``.! +M0PA1`,]R@`#P.!2"8;@4HB"!52+`!35X`!B`#P``__\9@G)Y)'@9HAJ"!"!` +M@!JB`=@U@L(@`0`+"$4`'@WO_Q6BT<#@?N!X\<#Z#&_[`-L`@<]R@`#P.`\C +M`P`4@@'@%**`@54BP`6A@95XH*""@1J"@>3%(,$`QB#"`!JB&8)E>!FB&X)E +M>!NB`H'.#.__%:(A!4_[X'CQP*H,;_L`VP"!SW*``/`X#R,#`!2"`>`4HH"! +M52+`!:&!E7B@H(*!&H*!Y,4@P0#&(,(`&J(9@F5X&:(;@F5X&Z)U@@*!#0L% +M`'H,[_\5HLD$3_OQP.'%SW6``/`X'87/<8``\#<(Z'<1``8!X'<9&``+\!2% +M@.`!V`;T1@SO_P#8`M@=I9T$3_O@>/'`X<7/<*```"`[@,]U@`!P.98AS0K/ +M<(``^`TJ"J`<(J4!V'$$;_L!I>!X\<#AQ0AQ@B&"!<]U@`#P-\]P@`#<#08* +MH!Q@'5@0`=A)!&_[7QT8$/'`X<7/=8``<#D!A0CHSW"``/@-B@F`'`#8`:4E +M!$_[\<#AQ<]U@`#P.!^%".C/<(``W`UJ"8`<`-@?I04$3_OQP,]Q@`#P.!2! +M58%AN!2A&8%X&8`/``#__Z^X&:$:@5`@P(,:H0'8PB`!``L(A0!R"^__%:'1 +MP.!^X'C/`4H@&!'J)B@1J"@>//(.$#T"#B`QJB&8)U +M@H^X&:("@0L+!0`&"^__%:+1P.!^X'CQP.'%SW*``/`W8X(!V`"B/PN1`&42 +M@``W"%$`:!*``#N"'7B+@AUA#0Q$$P)Y"H(?"04`"-@`H@H+(!4"V,]PH``` +M'308@`\``0``#O"`XP#8RB!B`.X*`!7/<*```!TX&(`/``$``/$"3_M$(+Z! +M%/+/<:```$4X@2$)W@//<8``<#D-"%X`"H$!X.!_"J$)@0'@X'\)H>!^X'CQ +MP$(*;_L!V\]V@`!P.<]QH```1;B!SW*``/`X-8)`)@P5@>'EAL![`>?EI@L) +M40`FA@'A)J8[@HCI(H0!X2*D!.LCA`'A(Z1/#=X3)PB1``>$`>`'I`7K"80! +MX`FD&X*;Z`N$`>`+I!?K#80!X`VD$_`G"!$!!H0!X`:D!.L(A`'@"*0;@HGH +M"H0!X`JD!>L,A`'@#*09`D_[X'CQP*();_L`VPHG0)`*((`O@`#P-P*X%'C/ +M=H``<#@=9F:E"O0$A0'@!*4)Z@6%`>`%I07P9*4#ZF6E`!``("T($0(B#:__ +M`=A.$`$FAB%_C@:E#/(+#U$0,X8!X3.F#0A1`!6&`>`5IJ$!3_OQP.'%SW6` +M`/`W8A5`$2&%`[A"(4*`#GC*(F(`A@]@!P#9@H4AA34)``,`VIRZSW"@```= +M`-N=NPL)$0%-H&V@!_`+"9$`3:`"\$Z@;J"$Y)P*P?\!A0*E`@O`$%D!3_OQ +MP,]Q@``4#B>!,'`$"04`T<#@?L]P@``4#MT$8`D(@/'`'7G/<(``2!4`@(#@ +MRB"!#P``5`+8"Z$.TR&A`-'`X'[@>/'`F@A/^Z"`"'8?#1X1SW"``$@5`(`B +MAH#@RB"!#P``V`"H"X$.,0U>$<]P@`!(%0"`(8:`X,H@@0\``-0`C`N!#@#8 +MSW&``!0.`J$!V`6A`88&H0\-GA$!V<]P@``4#B2@J0!/^^!XSW"@```@6X#/ +M<8``%`X'@3,(E0#/<(``<#H`@"&!.&`">H#B(``I`,H@J0#//'`S@\/^PAUSW"``!0.(PVU$*>@SW*````/`(*)Z`:"!(`@@(`A#PK.#6`< +M2'`2;11X`"".#X``/`ZI<,8-X!TAAL]P@`!(%0"`(8:`X,H@@0\``-0`J`J! +M#N4'#_O@>/'`\A(!MO3))7CW$@&V"WD!V`7R6@H`$P/P*@H`$]'`X'[@>/'` +M-@\/^PAV.G$:(HB_P\`W`/P`>0;#!41,FPT><=Q@`!$&VJ!\0L.@`F!`O!(<.!^X'@`V0\( +M'P`O*@$`3B*!!P#:SW.!`-`V%2-,`!`@0`!`I"6C!^@O*`$`3B""!P+P*')& +MHP#8"/`/"0```=H5(PP`0*0!X/,(5('@?N!X\<#F#0_["'<`W;2HP("UJ`&& +MSW*```?*,(@3:15X"&*,(,./H<%%\L]P@0#81#9X0(C/<(``(+]$*CX-((!` +M(1$!"B!`+HMQJ@OO_LEP+>@(V!2OSW*``&0Q`))(<0'@+R8(\`"R"_1AD@'C +M+R;(\&&R!?1BD@'C8K("MR#8IJ\'KP&1!+<"D06W`88*V3&H(88`(0`D%.%J +M"J`:$-HCA@"1CK@`L0#``^@!AK&HG04O^Z'`\<`V#0_[&G#/<$4`8",`@(L( +MG@#/=44`]"`P%8`0?P@>`,]WH```(-N'U@C`$H'@RB`A``ORAN#*(&$`!_*+ +MX`+8RB""#P``_P",(,./)_($N!UE%P@0(`'8_!\`$`@?@!\(````PZ49\".% +M%^D,'X`?"`````T.1!`")D`0!_`.(8`/_____]A@(H4X8`*E^!/'`F@P/^PAVSW"``(RK`(B5"-``SW6@```@^X4=Z26&$.D-#T00 +M`B=`$`?P#B&`#______X8"2&.&`$I@#8!:;CI@@=@!\(````SW`!`*"&.@S` +M`"CPSW"``)SA%@I`'`P=@!\(````(X86Z0L/1!`")T`0!O`.(8`/______A@ +M(H8X8`*F`-@#IO@5`1`!ACA@`:;)<$X.K_P`V>6F`=C\'0`0800/^_'`SW"` +M`%18`8`="%X`SW"``"CA/@@``,]Q@``TJQF)`>`9J='`X'[QP&8.0`V`X-`/ +MPO_/.'%`-T" +M\`'E$PV#$*M@K&&">R\CQX#Y\P+P`-MH<.!_P<7@>.'%0"D,`B5\0"P#%(5[ +M)PHT`@AT!/`!'%(08;I3)'Z0^_5!*HT`P;J`)?^?!!S0$/SU!^J`(O^/`1Q2 +M$/SUX'_!Q>!X\<#6"@_[!MW/=*````1OA,]R@`#HNV"BKZ00%`00181L$@TW +M66%?93!U`B%.`P)_RB9-$`(G0!/Q=@0'``1;,P"(0(`,'#*(8X`):0/A`<(D0$GI&^DI0(/^_'`SW&@```@.X'/ +M+L"E6'"AB!_#!QX0"B!`P'`SW>``)3;)7A!P(3`T@H@#B*- +M@<#*"B`.(HT"C<]V@0#@,V+`BW+I<,EQO@B@&$`E`Q8%A2.%`+8!AH.X`:8! +MAS(80@!`)0```@@2\````H`=T9\'H*(`XJ<`]X!"C^!58(8`0P($`^)=G"@`IP>@T@#C_: +M"KC98`?PSW"``#0M(8`(W0IP_@T@$@'""';*!0!((/"):``@(+!$!H`(`(*(!LJ +M<('ES"6BD!#R.PT1$0(A@C,"PT(JP`<`(L*``\%"P@$@0`!#P`_P`B8`%`'! +M$W@T>((@`0E"P$/'>AS8(WL/'`X<5" +M"&_["'4`VA-M%7@`(($/@`#ZR6D'[_I`L>!X\<#6#L_Z*'9(=1IS70IR``HB +M`"$T:#9YSW*``+Q'66%`(1$(A"@)#P`ADW^``"`[`!,`("39`-]J"6`#Z7)` +M*@(A`"&!(.BARJ&KH<*@IJ`9"!`@0(!(H2^0C;DOL/_9/*AP$P$@):#)!L_Z +M\`!_`)``@E0^``*`[`,!L'0`@ +M-NL$AG`6`B"`X,HAP03*(,$$!?("V``?`"`(<6R.!>N$N82X`!\`(`JZ;!4, +M(`##@GL"\$)[_PK$@&)Z"2."`(PB$(#&]X.Y@[@`'P`@):80'L`4ANDV#R`$ +M2G`$Z`'8`_``V(#@`=O`>POO)P]0$'$/D1"QZTIPJ@T@`*EQ,/!P%0`@+NOD +MX"ST`=@`IBCP)NL"V`"F%H,(!T?V0#!2G"*#B```=KR"2`$`=A*(``@!/``'L`43"`` +MH`#`C@0A`'\>&""`Y0'=P'W/<*```"!"P!N`0<5#P.K)`-D+"!\$1,$,\,]P +MH/X\!D3`SW#%[H)V`=E*"&`=!,)5)-DT*W!N">__$-D`%@`@E\57P`K86\`$ +MV%K``,#R":`06-D(U(`( +M'@(6G<,J<`#9*'+B"&`;521$.(#@C?(=P$`HD``?",4CGL,J<*EQ`=K&"&`; +M521$.!["`>)>P@/P7L6I
PI^X`!\`($)] +M`KT")P\4\77*(,8#RB!%`TC`2!T`($`=`"0<%!0P!?`'P``D%""Q#(4O```` +M`@C!`B1`("*X8;B$'``PA!0!,%8D`S0!X2IP`-H>"&`;521$.#[H`"`!)8`4 +M`S`BN7$+10"$%`$P02R"(`T)@0`!X80<0#!!*T\!02E-`<2[`-H/(L(`%2', +M,V&Z8(12>B$/01/$N0#=#R5-$"EMI7E$>65Y(*05\%[%J7*/\65Z0*2$%`$P +M`-O$N0\C0P`I:R5[%2%!,T"!97I`H0/P`-AQ"!&`J/$(P`?%`G`"?0;`AB!_ +MB``@ +MCP^``+Q'(.<$AP;HF@X@!`#9$!_`%!L-4A!*<`#!_]H*PA0`VPGP +M$FN#<#.`3X`!XT5Y+Z#U"Q2!`-^HCE4D63<%P.EQZ7(K<]X.(!M6),0SSP@0 +M`'`6%R!T%!@P!2]^(T$ID'"["`4TFG>`X,HAP2,G\G@4$3`C"04D0"%!(`7` +M`-HK@=P2\(1"`J=Q;P`>4%+WXC02F0<(P@P:_.]T2.`=E= +M904O?B-!*9!P0B!/(`/P`=DJ=YIQJ0P0H`(G`!8!X`*X2L!`*)@P0"H`(18@ +M$0!*<`#!2B!`(`IR"W.*#"``*!0$,``A@2^``-Q'`*$!YP#`#+\?9PK!7!W` +M(V`=0"!D'0`F#!X"%`L>`A2HK@IW`,%*<'H*(```V@G`@.#,)R&0+/(+CH/H +M"HXHZ`N.!>@*CH#@&M@"]`W8529"*0S9FAY"(`+@FQX"()P>PB1S$H``G1X" +M(`'@'@(@H@[@$4IPQ@G@$$IP"'%*<$H,X!$`VH(-X`,!P`'` +M@.!D"^$#RB`A`^K)"Q["%!L('@0"P`'9>X`#P`)[SW#%[H-W^@L@'03"S0#O +M^H`D`C+@>/'`A"@)#\]Q@``F/#(A00Z,(0*`!_(F"8`$C"##CP'8`O0`V-'` +MX'[QP'((S_H(=H0N"1_/<(``D#LP($T.6G&0V!IP#'[/=X``O$=>""`$,"=` +M'@J]"!`1`&H*X`W)<(P@_X\/?AWRV@G@#@*<`Q^-@@@!#`G0!XB@`(A +M0"`O(`D``_"B>`$-!!`"?0D@0`-`*I(B4G`!V(+W`-A9`,_Z\<#N#X_Z6G&$ +M*`D/`"&-?X``(#M`%0$6`=Z!"9$`\!43$(0H`@H*($`N]&CV?PHA@"^``*!' +M0"$`)\X/X`/@8`HD@"^``.!*$PH0((PC`:D$].X(``0#Z`+>52'`)>!@'.BF +M#\`#"'/^O'`*@^O^A_9!8"$*`D/ +MSW"``-P\,"!-#FX.X!RI<%X.P!P6\"\H00-.((X'$VX5>,=P@`#LR2B0$0E> +M``>0#0A2`.(/K__/>!`EC1/L[4T'C_K@>/'`J@Z/^EIP*'8*(("P`-J$*`D/ +MSW.``)`[,"-3#@`A@W^``"`\"(LO<3MP!2C^!`HA0"['<8``H#OP@601%0"8 +M@5P1%`"R@0L3EP``)%85#?)R=]8F@1\````$.G*Z-%7)WP"4A$@SP!>T"(\,%#0M3``#=^G4$ +M\`(E#2`?"9(P0B%",`4J_@0`(<)S0"J``AYF`B8.%1$.4Q`H=P#8NG":<`WP +M`B*"!0(B%0$-#\$40"0"`@`EE2`H=ZAV2G#)<>ER"W-2#J__2B0``$IP"G$J +M<@MS0@ZO_THD0`!*<.IQJ7(+G"`(\(GRB:!$!3R_]X!V=%W`(#"(4$`<@_@`B'A`,$*N2)Q(J"FH`L/ +M@1,4&``%P(`5#U$0SW"``"H\,B"`!`3H0"43)L]PH```(!N`"KT"(%($I@^@ +M&@IP`,$"((`$"KDX8$3`!QS",T+%0"R`(HPGPY_*($(#0\!`),`Q:G%B"2`: +M#=K)<($$K_JEP/'`/@R/^J'!"'8H=$AUA"P;`,EQ`"&`?T4`0`>6"B``B7+9 +M9C1YM'G/7[#920R@X`$H'@`=BR"J`%P'A*"0`2SW&``%2K&HD!X!JI +MM0./^O'`'@O`!0CH:@P@#`/8P@U@!0/8T<#@?N'%SW*``%Q6!(+/<:<``'T& +MZ&6"!H(0NV5X"J$,@L]S@`#<5@2C#H(%HPV"'K,/@AVSJX&,@0Z!<((&ZW&" +MAB7!'V5]X($)(P?__\_\`:[ +M97R,H7R"">M=@@0@@`_`____$+I%>`ZAX'_!Q?'`:@J/^@#=J708\!4@0P/` +M@YIA++[`JL"#`N4DOL&JP(/A@P2^,+_E?L*JP8,%Y"B^PZIA@V2JC"0"F:CW +MF0*/^N!X\<#AQ0'=#@M@%:EPSW"E```XHJ"-`H_Z\<`2"H_Z"'7/=*<``(`> +M%`*6SW.G``!]"8,G@VB#4R*.`M&E!"*"#Q\``/@KNE*E(!0"EA6E4Z4TI7:E +M!+C."J_Z%G@GN#T"K_H'I?'`P@F/^@AU*'=^#2`22':"#"`2J7"$+1L0@>`! +MV\![`"&`?T4`0`?I<0X((`#)$(IPW(#BG![)(HDN"2Y]"1!$)H+8`9&BL]Q@`#85` +M`#`@!(=&#N`0`[@(=CX.X!`'AQMX$W@4(($#"8/'`H@B/^EIQ>G**(0\*@.#*($$@RB`"(`#?`]W/=H``W%:@ +MI@O8.@H@'>EQ"B6`+X``>`L(%1$@"X8<'<`C@.`!VQB>P'LAAJ();_Q*AJEP +M(@\@``;9J7`&"B`=Z7$*)(`O@`#852C8]@H@&0`4`2`HV.X*(!D`%`$@!-CB +M"2`=Z7$('4`D2B%`("IQ'!U`)"8+H`S)<`(.S_\*<,(*(!D`%`$@Z7#I<08, +M[_WI#J`4.G!/%1"64!44 +ME@0DC2\```#^#@U@!BF]')9,(0"@`>```#`@I*=3)``B!J<$((`O +M@/\``#>X`Z<$((`O?P``P"ZX!:<#[<'EQ_?/<```O"B2">_ZJ7'/=8``:!*I +M<.X/8`PDAXX.``"I__0X8(=1B> +M2"```/H*(!(!K0"M`VT"V9(+K_HPW(0H`2PAA@`A@G^``.0@F@ +M#`'9`]@N#2``!MD9GJER(8::#R_\J7-"#,__SW&``-A5*-C^""`9((&I<*X/ +M8`QDV0AWSW*G``"`,!(`ACJ6#7@X8`(:6(/B#*`4&K;"#```>@A`!@;8R@_@ +M'*EQB09O^NEPX'CQP.X-3_JFP5IP*'9(=4H@0"#/=X``W%8*)8`O@``<5SX) +M(!(8%8`@%@PO_"&'4-D)($``&;?/<(``W%4,@+NW@.#:M\HE`A0$]"(/S_\( +M=0#>SW"``$!7P*`'V%X/X!S)<0WP2B``(`?M2G`!W4H*(`"I<8+H"G4!YNT. +ME)`(V#H/X!P`V1@7&!!,(`"P'@("`(#E%@(!``'80,`&IP.'#^@8%8`@A"@6 +M"2&'`"&`?X``5&LLX/`@0`"`X/7T"=CZ#N`<`-D!V+H*H`P@V7X+(!4`V`+> +M$O`!W<]PIP``?!Z`8;X$((`/'P``^"NX0"@!`@`D0#0CH"L.$A#/<(``2.H: +M"R`5\""``T`ND1!*(``@!^U*<*()(``*<=[H"G7=\8#EO?(#QHHF%BD0%!$P +M0B[3%P(F4)1"*=.O#/ +M<(``*.KP()0#0BS3)XIP:G&*<=Q@`#4:GSA)W$`H0'FD0Z4D1@5@"`$*+X%08<`P0`A@'^``%1K +M+.!5>""@"M@:#>`<`-D8'P`6J7"%`V_ZIL#@>/'`6@M/^@AV.G$!V!IPSW>` +M`-Q6`*?I<$8.8`P*<0/8^@D@``;9&9\`W2&'J7)F#"_\J7,*"<__SW&``-A5 +M*-C&#>`8((&I<*EQ#@^O_:ER"G"I<0(/K_VI<@IP8@Q@#&39"B``H#CRJ7$+ +M\,]PIP#(?/`@0``5)DP0`*0!X?$)5(5*AHCJ)H;/<```O2CF#*_Z;H8J#6`, +M`H?/<8``0%=,(0"@`*'("0(`%8<4Z!(-8`P"A\]Q@``P(&`9&`!6(0`#(H<& +M#6`,08?/<(``!")F"T`,SW"G``!\HJ`R"8`4%@D``,X,``;5`F_Z"G#@>/'` +M<@IO^LC9SW"``%Q6"H``WH#@RB4"$,HE01`/V/H+X!S)<038SW>``-Q6`*?I +M<#X-8`P!V0/8\@@@``;9&)\AATJ'7@LO_,ES!@C/_\]Q@`#85:EPP@S@&""! +MR7#)<08.K_W)<@'8R7'^#:_]R7($V%X+8`QDV<]RIP``?2>"SW"``#`@-*`H +M@L]UIP``@#:@*8+J""``-:`"'9B3@@B`%&8(```>#``&$-AJ"^`%/`3;Q1X0"B!(#1Y. +M>,]Q@``@I0%A"G#);0?ML.TI#5`4_Z\<#AQ0#=5@H@%:EP +MSW"E```XHJ!>#J`;`=@Z#H`;S0%/^N!XX<7AQL]V@`#<5G&&SW*``-A5G>N_ +ME@#;@88/(P,##KN)[96&!>P%(T``B+@0\&5X#O`%(T``@>7/("$"SR#A`L\@ +M(@//(*(&`O`2A@"BP<;@?\'%SW"G`(!\`(#/<@``'',.>`D@@@"6(@8$SW&` +M`-Q6&YE88"WP&I$!X!JQ`B*`#P```#(E\/$*4X`U"A(`^0Z"\````!GQ"H*/ +M__\`YP.!C^A8$8``A"@;`&&!`"&`?T4`0`UU>#J12+`IL.!^&I%AN!JQ`"*` +M#P```#(.>ANQX/'QP'H(3_HN#L_]"B4`D"GR(X4BZ<]RH```(-N""PY$$`(F +M0!`&\`XA@`______V&`BA3A@`J4`V`.E^!(!``&%.&`!I0'8_!H``*EP<@KO +M^P'9PZ7/<`$`H(8."```C0!/^N!XSW*``)SA)H(D@2"!&6$Q!F`;2'#QP`(( +M3_H(=0#>$0C1`!8.P!&`X,HF8A!V#V`/J7"J""`2J7"A[EH(``!"#.`1J7!: +M#V`/J7`0V'(*(!$`V9(/X`2I<,]P@`",JP&`!H`-"-\'^@[`$03PR@[`$1#8 +M3@H@$0#9!O`F#V`/J7"N#L`$'@S@`:EP_0/'`[@K@$>'%@>`! +MV,!X#=T:#F`4%'WB#R`/J7#=!P_Z\#P_Z"'EP*@Q@%\EQ +MJ7#.#&`7J7&I!P_Z\<`R#P_Z"'0;#!41,FPT><=Q@`!$&VN!\0C!@`F!`O!(<.!^X'C@?N!X\<"F +M#B_Z-&BAP0AW-GG/<(``O$<`(%,`1@A@#>EP&G`7;Q0@%0``)8TO@`"`V4P@`*#,)"*@!`(A +M``#8$XW/<8``Y:S/"!``@".*[8#BS"1BH,H@(0#*)@$0/O(9[3(A3@6`YLH@@0\``%H#``B! +M^H0O"1\`(8!_@``@.PD,4"`?@`/P'8`%*+X#+W`(\(0O"1_/<(``G#LP($`. +M&G``$P`@"G&J#V`#`-H(=@HA@(/*(6(``!Y`(`#8#NT0$P`@"G&.#V`#`-H- +M#%$@`=@"V@`>@"#/<44`;"Z@H0#9@.;,("&`RB9!$#OR`=XY\!"-`=F!X`HD +M@"]%`&PN`!0`(,!YANB`X`_(!W@'8$ZV$+PD?`"&-?X``@#T5C0D(4```P#/H:@M@`TIP&G`N +M"V`#*G`(<2IP<@M@`P#:#>@J<`#9"G((VS(.(`=*)```7@]@`RIP!7X&"V`# +M2G`(<4IP1@M@`P#:$>@5C83H`=@7K4IP`-D*<@C;_@T@!YAQ+@]@`TIP!7ZJ +M#&`#*G`(=:(,8`-*<`#!"PE1`$*%"_`9"9$`0H5B@`(C@0`+"5(`8J4"\$*@ +MSW"``$@5`("`X`'8RB"!`YD$+_JAP.!X\#"_Z`-D(=\]V@`!,5R(.(`T@ +M%H`0)(9)A@AU4''*((8/```#+#@.1OJ#Y\H@@0\```@L)`YA^LHAP0.)#Y`0 +M#0]1$`*&`>`"IH2&*88!Y(2F50QE$`&&A"T)'\]Q@`!8.S`A3PY$+#X=`"9# +M'B00C0`*)(`/``#0O`2]"-@TDT`C`@TLXP4E!1-`)@86`@F@'E,G!Q"`X,H@ +M@@\```8LL`U"^A#P@.#*(($/```$+*`-0?HAA@"!)!&!`!X*8`,!V@4$#_KQ +MP,O)BB$)#Z00#`#$$`(`SW"``/H\8F@L>@T,'A`T($`.!/`T(T`.U@F`&[CH +M`]G/<*````0HH"#8I!H`4H6"J((D\><*Y!+EE +M>0+P@-D@J@2]!2!!(R&J/)!CN4SW"@```$)*"O\``6`T%6(`T"?+`` +M%@%!/;``%@5`/!A``0`6`4$@M0`6`4`QH``6`4$DM40C`0,_"1`!&-[9M0`6 +M#T#SH``6#T'HM0`6#T'JM3,)$0**)`P`!",/`2WMFU`!8/0/:@`!8/ +M0>ZU"?`0WMFU"B2`#X$`O#8*'(0!:'>&)_TDFDJ+JNNDFD`-DZH#N@"/``%@%`.J``%@%`.Z`(V0"0/F;" +M>!BUAB/\`,]QH```!(PC`X3@V,PC`H`1]`.!$'N,(\2"#?0!W<]S10!H(:.C +M!""`#_\````PN`2CF+I)I`2!&[3Q``_ZX'CQP'X(+_H5($,`SW2@```$I(1% +MA&P2#C<"(X\#<';*(\X#9*0%I.^$!P^1$0>D6&9B>`(@@P,0=LHC#0`BNP#8 +M!?``%@Y``>#0I/L(Q("DI&S,&F(8(D(``B(!`%!PRB&-`"6D#X0)")$!)Z1] +M``_Z\<#AQ58/H`L!V"X,8!<`W9H-``!.#>`<"MB2#0``]@B``VX/@`,(\+X* +M8!NI<,H-X!D!Y?4-%)'/<(``&-JZ#<`9[@D`&8#@K`\!$/8,@!&Z"4`0V@I` +M$"H-P`O/<:```!P<&8`/`0``_'_8!*$0&8`/(````,]Q``!("D8*(`X&V,]Q +M``!<"CH*(`X'V#X*(`,"V,]QH```-P"!1B#``0"ASW"``$@5`("`X,H@@0\` +M`)0`C`IA#!X\<""#N_Y +MF'``W0_PN&44>'0@#P&MWA"^8I!!D!"[97KU?D"F`>7I#420Q0;/^>!X\.!XX'C@>.!XX'C@>.!X +MX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!X;R9#$,]PH```,#`8@`\` +M@```SW"B`(!L=!B`#P```(`^"*`1`-_@N,HAP0/*)X(?``#``,!YSR$B!.&X +MSR>B$\\GXA//(>(`SW*M``!`+:+:&M@#_QI8`\]PK0"`@[^@SW"M``!$P:#/ +M<:T``(3!H>!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!X^AI8`\&@ +MP:&@H*W8$+@T&(`/`00/(,]QK0``%@:!!""`#P_^__\&H;D%S_G@>/'`X<7/ +M=8``5%@GA00AOH\#````!O0$(;Z/#`````_R`-FMV!"X)*`!V<]PH@``@"J@ +M\@G@%RAP)X7PN=$AH80/\D#:SW"M``!`1*`!VL]PK0``@$>@6!B8#P```$#P +MN=$AH803\L]RK0``@`D)G@0@V`>BSW"M``!`$!B`#P``@"!A&I@/````0`3: +M\+G1(:&$RB"!#ZT``(`%\L]PK0``0$B@&PD>!(HB$`#/<*T``(!'H`':SW"M +M``!$1:`_"9X"SW.M```@SW*M`(`>8!J`#\_;$!%0&H`/HB@0D4P:@`^B*!"1 +MY@9SW"M```$!!B`#\@;Y@5M!,_Y\<#AQ<]U@`!46">%HN@$(;Z/`P`` +M`#;RL@C@%P'8)X4="1X$0-K/<*T``(!$H,]PK0``0!`8@`\!````2PD>!,]P +MK0``@!`8@`\"`(``'?`$(;Z/#````!3R<@C@%P'8)X41"9X$0-K/<*T``$!$ +MH!<)G@2`V<]PK0``0"2@!?!*".`7`-CE`\_YX'CQP.'%SW6``(`3`(6>Z,#9 +MSW"M``!`/J#/<*T```0\@$$I``'#N`:U02D``L.X![5!*0`#R;@(M5,AP``) +MM98-(!0BI0'8`*65`\_Y\<`6"\_Y"'8H=4AW9@_O^0;8%@T``JW8$+CP((`# +MI'@1#0`0@"?_G^0'S_\`V`/P`=A1`\_YX'CQP.'%SW6``%05`(6'Z'(/S_\F +M#,__`=@`I4$#S_G@>,]QK0``%A@9@`\@````+!F`#QT`@-!QV`RA#!F`#XP` +M`8!'V`2ABB"=#`BA`-@`H8H@GPP(H>!XX'C@>.!XX'C@>.!XX'@'V`"A(!F` +M#P```!V`+R"(T)K24"[_D&KD$H@0+!N4$H`P/!NQUZPKK/=(``].?@N$ID +MX2#"!\H@H@!P<0'8PB`!`%!Q&WCA(,L'SR`K`.!^\_Y2B0```AV&G%( +M=;H/[_\H<`AW)0B1`$H,H`#)<."F02@!(<*Y02C`(<*X"J[/<(``2+HIKG#P +M((81"=X`SW"``$BZ*HYH\`2&"PT!$`F.C>@2#*``R7`(CJ2F":X*K@/8*!X" +M$`'=$?`P=\HE`1$-\A$/'Q#N"Z``R7`(C@FN"0]>$`B."JX`W0H@@"^``$BZ +M!!"`(!D(40!&#$`1$0A1`.&F!-@`I@'9-?``A@&FX*9=#QX0I>T4CJ?H*!:` +M$(#@RB"!#^0`P.'*(((/"@!@KL]QH```(%N!:88+"L0`.X%B>0?P6X$.(X$/ +M_____UEA#PD%`)(,H``B>`CPE@N@`,EP!/`J#:``R7`4CH7H*8X*<":HO0#/ +M^>!X\-#R!```>M?0#/^<]R@`!(NF>*$_`A +M@""@$?`O*,$`3B"!!T0I/@L0(T,``"&`?X``F+D@@.,)WX#RZP#8X'\'JN!X +M\<#AQ0AUSW*``$BZ!8I$*#X+`"&`?X``F+D@@!<)7@`*B`:J^@Z@`P'8J@P@ +M&ZEP!/#N#J`#`=@1`,_YX<5!@&:@X<(`W"##-PI>`L]T@``@1[R$"+G/=(`` +M7`R!C&1]I'P)O(5Y)7LLN@0B@@\````P97HC@$*@GKDCH"7P$PH>`D$JP0#! +MN0'A`=P*\!,*G@8\:\&Y`>$"W,.[`O`!V0*\%+L$(X,/\`,``&&YA7EE>8>Y +M!"*"#_\#`-PFND5Y4B'!`R*@H<#@?\'%SW&@`(`F#.C/<(``G`O#$((`%H!8 +M8!UXA+@#\`#8%J'@?N!X5FG/M8(#ERB#A!R@/X?G/("$#SW&J +M``!0@>4!V,H@+@`(H9D%C_DO*`$`3B"!!\]P@0#0-N!_)Z#@>*'!0,#/<(`` +MH$ +M`).XE;@/H@'80,``P(GHSW&``*!')8'MN3.CX'[QP.'%!"*^[P@("`@(=1OR$@[`',]Q@`"<"PT( +M40`/@9.X#Z$!@0\('@`/@0'=E;@/H0"1#PB>`P'9SW"!`+@N+*"A!*_YJ7#/ +M<8``H$RYRB!B`.!^$^@$(K[O"`@(",]S@`"<"P3R+X.3N2^CSW&``*!' +M08$S@T5Y,Z/@?N'%X<;/=8``G`N0A4`5@!`$)((?````&"NZ4R3!$$2X4R!# +M`!)J%7@T>,]V@`#4[A9FSW"``*3N:&#[O,QXF!4`$`0H?@XO<,(@(@00]`.Z +M>V-5>G5[>F)98<]R@``$[BEBPKDY831Y$.$B>".XP<;@?\'%\<#/<*```"`` +MV3J@I`(#8SW&``"S.I!HK)`>);H1D( +M'@#/Z#07(.X!L!V<]P@`!8%0"`%N@`V,]QH/Y@"Y:X#O`3 +M@0'@$Z'/<(``6!4`@`CH`-B6N,]QH/Z0"VH/@`ZES:>XI1H;Q\`,]PH```1Q08@`\```P,[,D%V0'@L[BUN+BX[!H8L!6Y!*'/<($`-$G+ +M&ABPSW"``+#;S!H8L*3-/P@>`#Z%SW"``"!''8`"X6&X""$``!"E`=@''1B0 +M$-@`I:(.(!M*(``@I,TDN`0@CD\P````4R`-`+7PSW>```C?`8<)Z`"'#P@> +M`(*XB@W@&@"G$@Y`%0AQSW"``)P+M@T@#QF`&G#/<(``+,\"@(P@`HV)]Y(, +MH`(5V,]PH```$,F@`8<(Z`"'#0B>`**X2@W@&@"GI,T?"-\#`-[)=8/P9@R@ +M`A78`-G/<*```!`IH'GP!-C2&ABP$87/=Z```$B`X(H@#`#*(((/`````@"E +M!!V8GV````#^"(`+Z``QP'P@?`\]PH`"`13`8@`\`(````-G/<(`` +M;"@@H&HA@`'/<(``<"A)!2``(*`,<*02`;=)"%X%TLF&(/&/(/0$(;Z/```` +M4`'80,`$\@38I!H'@B`"TX.0!3/<(``2+H&B,]R@``4"1UX((+`N*"Y)7@`HNX/ +MX!L'V,]WH```('H7`):`Y:2X>A\8D,]PH```1<2@!O+/<(``;"@`@(#@,`,! +M`$07$1#*#P`$@.`:`@$`Z@\`!,(,`!@O`@``I8*X!M;AP7P$XX:AP'@&J<5\(H@!`"D&ARP$H=Q$P$F`>`2I\]P@`"LSC5X +M.H`!X3J@!>X9AP'@&:>DS9\(W@&ES00@@`\````8`,%+"($/````"+((X`PH +MX=-@2`K9!*@`#Q+@R:#`A +M@0^@`+0N"'.`(\(!E.#*(,8``K@P((\/H``8+"]Y5B<#&.K)(GMO>RT('@#/ +M<*````2/@!"[SH`0O-!^"+DE>\]PQ>Z$1`'9Y7N6".`;!28$$S+(SW.@```M +M`K@`(((/H```+9B"V!(!MBRYQ+D=#$$088,P((`/H`!D+A`C0P!K>`/R`]@8 +MHAB"IF)\!`,#\!@O`&L]V@`!8,B"&%NFF"8`%ZLG@IB4('@`RR,]Q +M@``$N$`H`@3T(0,`SW#%[H)(`=EF#Z`;97JI<*(/X`X*<>G)!""^CP``#S@) +M\L]PH```1Q`8@`\```P,G@P`&-(-@`Z>""`,`=C/<(``)-O_V2"@SW"```C= +M`("`X`P(P@//<(``F+O@H!4$;_FAP.!X\<`!V%H)X!$`V0H*`!+1P.!^X'@! +MV*D"H!8`V>'%"'$`V`';"'4-\,]R10#(([9Z@((-#$40!(H!Y0/P`-OVZ^!_ +MP<7QP,]Q@``8OP"ISW*``)P++X(0VYJY+Z((V<,:0@#$&D(`SW&@`(`<>Z%$ +M*#X-SW&``""_(($G<02!SW.@```8`J,#@0*C`H$"HP&!`J,`V`:CN!(``2"2 +M:+BX&@0`*'"&(/T,C"`"@@'8P'@/N(8A_XR6()P#$J,#]`'8&://<(``2!4` +M@(#@-`F"'-'`X'[QP/(*;_D0V@AV`8A$*#X-SW"``""_H(`!EB=U`+4T%H`0 +M`JT!C@.M0"8`&=8/H!A`)0$90":`'4`E`17&#Z`8"MH$;B1MO@^@&!#:%0-/ +M^?'`G@IO^6&ZB'0"($T`02T.$S&]&F(B>D$J#P,QNE!U']C*(,$#`-D/(0$` +M`-@/((`#R6EAN"5^\"-!`P9^`($$[`5^P*$7\,9X`*$3\,5Y(*`1\+%R']C* +M(,$#`-D/(0$`"6D%>?`C0`/`@/'L)G[`H`'EX0I%@Y$"3_GQP.'%R\G/<8`` +MX+$0B`.X%G@#800C@P\````0A2,#`0/8SW&@```(`J$`&,10R\E=D``8A%#+ +MR5&``!B`4,O)2!`"`0`8A%``V`&ARQ(,MCV43X00N4`4#1$PNA"]E!0`$&5Y +MI7HJ#2`/'`?@E/^<]P10"4+*00#@`#\!`F3A,B[B\H +M@0-.((T'(@H@`ZEP_@_``G7H+RD!`$XA@P>$*PD/SW&``"@[,"%,#C-M-7D` +M(X(/10"T+#IB@*H0(,``Z_&1`4_Y\<#AQ0#='_"$+0$3SW!%`'@M,B!`#A7H +MSW%%`)0LI!$```\@0`.D&0``0@S@$*EP,VTU>0`A@@]%`+@L`*H!Y:]]R0W2 +MD,]P10`4+0F`4R`!`$0@@@`E>D0@`0&&(/\-17D%('Z``=@U`6_YPB`!`/'` +MK@A/^0HE`)`H=TAV&G,/\B45@!`G#R(0_]DF%8`0&PX"$#!V_MS,)@*3!_+/ +M<```Z@YZ"J_YR7&,)L.?!_0$A?A@`!@"!!'PC":#GP?T!87X8``8`@0)\"85 +M@!#L>`.%)W;88``8`@2M`$_YX'CQP.'%SW6``"R_`@H@`!V%`=BM`&_Y%*7/ +M<*``@`T?@.!^X'C/<(``G`O`$(``@.#@?\H@8@#@>,]PH```#0>`T[C@?P6X +MX'C/<*````T&@-.XX'\%N.!X\<"."2```-B6"2```-AB"2```-AJ"2```-@$ +MVL]QH```#4*A0]@`H<]PH```?%@8@`\1@!$`5*#1P.!^\<#/<(``++]6(($# +M%("!X,P@(H`A]&()(`#P(0``SW#_`>#_#@D``,]P_P'@_R8)``#/<*````T` +M&(`/`'S_`,]PH```?%@8@`_1@=$!4!B`#P,`___1P.!^X'CQP%8/+_D`V.X( +M``#Z""```-C&""```-C.""```-BZ"$`,`@D@$(`@`P('V`JXP-D8N28+[_PS +M>@?8"K@`V0#:%@OO_(^Z!/!*#H`-SW&@``!\`H$G"-\'$8$#VQ"[!"#"``#9 +M"0K``"AP"/`#VABZ1'CY"(&``=B$Z&QPS0@>@&QP,P@>`,]QH```?`*!!""` +M#P"```!"(`V`T8$Z"&`,RB5B$`ASBB`.!:EQM@BO^"N_\ +M`-H'V`JXP-D8N8X*[_P`VOD&#_G@>"6XT[C/<:````T%H>!^X'@EN-.XSW&@ +M```-!Z'@?N!X);C3N,]QH```#02AX'[@>"6XT[C/<:````T&H0'8`:'@?N!X +MSW&``'A4(($C@0)YSW"@```-(J#@?N!X@-G/<*```'PWH#$&S__@>/'`%@X/ +M^0AU`@[O_RAVA>X#Z`T-!1"2#^__J7!I!@_Y\<#V#0_Y"'7R#>__*':%[@/H +M#0T%$)(/[_^I<$D&#_GQP,]Q@``LOU2!`-A6H8'B%*$0""(`RB!B`-'`X'[@ +M>/'`!N@"#L__T<#@?KX-S_]1($#$`=G"(4$`42+`Q@'8PB`!`"MX"/0#V<]P +MH`"`'2:@[/'J\>!X\<#/<```$"="#\`/`_"N#(`-42!`Q`'9PB%!`%$BP,8! +MV,(@`0`K>`?RSW"@``!\`H`-"-X';'#7"!Z`4B,`0,"XT<#@?N!X\<#AQ0AU +M%0B>`<]P@``,40"`@.#B(`(`SW"B`(`HL:"-!0_Y$/`O*T$`3B."!Q`A@0`T +MJ`/<,FHU>0`A@P^``$BY@*,TB/'ISW"```SBO0)`&N!X\<#:#`_Y"'4*((`O +M@`!(N@00@"`C"%$`-@C`$!L(40#/<*```"`;@`FESW`*`&"NQ@@``$SP;@W@ +M`A"-1@O@`@#>I+@*)(`/@`!(N12M#_"$+`D?SW*``"@[,")"#F"AA>(!VL!Z +M`>)$J1KH+RD!`$XAC`?O?_GQSW*```SB!H($@""`QW$&`(`:7@I@&DAPSW"@```@&X`HC0FE +M!AA"(``8@"/&I<>E=00/^?'`SW"``$BZ!8A$*#X+`"&`?X``F+D>#\__^@B@ +M&@'8T<#@?L]R@`#PX2:")($@@1EA"0)@&DAP\<#:"P_YSW6``$BZ((4+"5$` +MR(@0\$:`)X"`XLPA(8`&]"B(R8@1"8$#!?`)":0``MX!WDF(0"`!"`\.@!`# +MVDBIR:@)\$B)"PI2`&&Z3WH"\`#:2*F`XLHA@0_D`,#ARB&"#PH`8*[/6'/@*^U7X`)HP?@`!(N:"D\>I( +MB,]P@`!(ND:HSW*```SB!H(B>P2`((!Y8?8(8!I(<#$##_G@>!2($?`O*@$` +M3B*!!Q`@0``/>`3;`KDU>0`A@@^``$BY8*+RZ,]P@``,XFT`0!K@>/'`SW"` +M`$BZ!8A$*#X+`"&`?X``F+EN#<__,@T@`A+8T<#@?@AQSW"!`"@X903@"P#: +MX'B`X,PA(8`%]`#8`*(3\(;H@.'*(&(`^_4&Z(;I`M@`H@'8"?",(02``]C* +M("(!`*("V.!_`*/@>/'`)@HO^9APZLFGP7,('@?/+L&BZ6+"+B'BP5] +MN!,`!A03!P!`P,]Q@`!`P0.!$!,&`$'`!($,$P4`0L`,D1"\RI$0N,5X0\`: +MB=:)$+C%>$3`&XG7B1"XQ7A%P!"1B'(ND1"X)7A&P&2+SW#%[H[#`=GR#&`; +M!21$$QD"+_FGP/'`SW*``#P2`(*+Z`:"!(`@@,=QDP,`A[(/(!I(<-'`X'[@ +M>/'`4@S@$`+8Q/'`X<4!V,]U@`!0,@"ESW"@```@&X"6"(`"SW"``-@:`@\`&@#8H0$O +M^0"E\<`B"2_Y`=C/=8``4#(`I<]P@``$_P"`P8#/<*```"`;@%X(@`(`V2"E +M#.C/<(``V!K&#@`:!MB&"&`"+V@%\&(-8`+)<$T!#_G@>/'`SW&``#P2`(&` +MX)P.(AK*($(``-G/<(``/#(@H-'`X'[@>/'`<@D/^8((#_FDP5+`4\'/<*W> +M[[Y#P/H/H!(!V,]PH```,`P8@`\!````:2```,]PH```(`P8@`\@```$$\&` +MX0?T`\!"P$'`0,`/\('A%,!"P`/W`\#X\8+A%!`/9SW"@```,)J!^"``.SW"@ +M``!'%!B`#P``#`P%V!6X+!B`#P"`0`#/<(``6!4`@`CH`-C/<:#^=`%2"R`. +MEK@2P%,GP34(%`0P4R7"-0`4!3!3)L,UT@D@#@04!C#*#T`.`-G/<*```!`I +MH,]P``"MWN8(0`%R#P`7SW6``$@5`(6`X,H@(0+*(2$`O`EA#,\A808`A1'H +MSW!$`+R3`8`3"!X`SW&@```T`(&0N`"A`_!B#(`2;@I``2X.@!@DW',&[_BD +MP.!X\<#AQ<]U@``D(.(-X`P`A0`=@!^MJ_[*SW6``/A1S@W@#`"%`!V`'ZVK +M_LJ=!L_X\<`:#N_X`-FJP<]W@`"LTT`G`A0'CTC!@.`%V,`H(0/`>,\@8@.B +M@HPE$)!(]XHE$!"BH@P:@`\````D'64!@D?!`"!0`\=U`0````380,!AP,]P +MH```(!N`*KU#P$;%`=Y%QD+&#B6`'P````+""J`.1,`(<8MPB<)F"R`"B,,( +MP`[H"<`*O4D?&!`,($"CRB4%%$H?6!/)<`/P`-CE!>_XJL#QP,]Q@`"LU`N! +MI+@+H1$(7P#/<`,`[/M:"0``T<#@?O'`4@W/^`AVSW6``-S4`(4:<0?H`-]. +M"6`"Z7'@I<]P10"T-V(+(!H*<<]WH```(!N'$PB%`SN'`B9`$$$HD`(#\$H@ +M`"`*(8`O@`"LTQ\($"``$0`@'MF^#R`!`=H@@"BE.X<8&``$(J!)$0`F`B8! +M$$H1`"83"&0``B!/``\/A1\!`````-^0OPK8(@Q@`2W9((#OI2REPJ`JO^:@ +MSW$#`-C\SW(#`$3ZSW,#`%3YD@B@`0K8Y@D@`@'8^03/^/'`E@S/^,]U@`"L +MTP@5D!#/#<0(0$$[@D@&B^B<03/^/'` +M\@O/^+IP"B.`+X``K-,($Y(@SW&``.S)0"K`(!5X`&$`$Y`@42!`@D`C#2A` +M(PXDBO0*<)8/X`Y*<8P@PX\Z<`OT0"@!),]P``!E-+H-+_D%(8$$SW>```0P +M`(< +M`80H"2\`(8!_@`"`/!8@0`1!B!K8`J<`(8!_@`!@/!8@0`1QD`P?`!4$NQ8< +MQ"`QD,.Z`>$QL".'#)%%>`RQ`82BY/:@CA@#;/J@CAD1Y +M*+D_J"*'`=H`(0`%!JH/X!KO>`AV2Q4`%N"XP'C/(,(# +MF`DB&\HAX@#?F#\`9SW"``-S4+(`'Z6H-8`$*V&(-[_\!V-'`X'[@>,]P +M@``HX4D&C_W@>/'`SW"``,S5SW&``&!1Z@X@&`3:SW&``,PJ`)&`N`"QSW"` +M`$3A`=D@H'8,X`$3V-'`X'[QP*()S_@:<`#=SW"@```@;!`1`%IUJ7<-\`#8 +M`*;/<$4`="V$+P$3W@L@`C`@0`X!YS.FB#.`,*G#I +MZ""&"0H1("AU"/"J#.`,J7`$Z""&^O%`(E(@YO&&[1X/X!D*<`SP&!``(`2` +M((`"(4$$N6%>#^`9"G!]`<_XSW&``/`X`-I?H26`A0)O_8#8X'CQP`ARSW"` +M`/`W`-EA&%@`8QA8`%X0``89"($/``#__\]P``"?,^H*+_F*(&6BQW"``&370H!`@D"A +M`X``@.!_`:'@>.'%`-T(\/`@3`-@@@'EA7L$&M``\PU$D.!_P<7QP%X(S_@` +MW8HD_Q^`HH"C`O`!Y10A3P/`CXPFPY\,\H&/\P@%@P@F#A#`H@&/`*,!V`/P +M`-B5`,_XX'CQP"8(S_@(=<:``("`X,H@@@\``#81``H"^4"&`O!`@@\*@`,B +MA0*"(GCW"%*``8*AHD"E`:6@H"2%!H4``"!!^A"A0*`0G@)"%(`H*$!A0T.`1"R#:`8!H4$A<#9!B8` +M<``"``"I<@C;R@\@&XHDPP\%`,_X\<"&#X_XJL$Z<"AUS@W@&1IR@L&#PL() +MX!@J<,]QH```(,@1`P#[@:ER@"(0`!N"`B?,$`(D#A`9&I@S&AH8,P`8@"/$ +M$0```!4$$)J"(849@GQD`GP`)`R1`-@!($``0,1!P!J"/((;8QF"A"D)+P)[ +M`B?`$")X`"&-?X``(#T'"%(`$*6+<(+!6@S@&83"51T"$`3``,$1I0'`)*4% +MI?*E*G#)<38((!H`VCT'K_BJP.!X\<#2#H_XL@U@`PAVSW>@``!%!/`&#@`- +M'H<$(+Z/<````/KUBB#_#QRG&*<*((`OH```(`48F*\!``"``H8(IP2&!:>C +MA@#8!"6-'P`"``":"Z`$.G`*(D"#RB)B`/C@#]D&]CMH@.#*(4P$SW-$`-CT +M@8M#N()X,."`X`';RB#,`,7VO^#*(.T/SW2``!0)HH0'N40E@Q$$)8T?_\!X +M^&5ZAB'A#T5Y&+@E>`5]HJ2J#2`;`M@#AL]Q@`!L#`2GR!``(!@90`1^"*`3 +M`X;JR?VX0`KB&LH@@@,"AL]Q@`#0]P"A`X91!J_X`:'QP.X-K_A(<$AVW@A@ +M$*AU)8T$C0BY)7@FC1"Y)7@GC1BY)7@AC<.Y.@S@"@':)8T$C0BY)7@FC1"Y +M)7@GC1BY)7@AC6X,X`I$N>&-SW&F`(``#;\$)X\?````X`\.TQ.*(`H`!*'] +M?P7P$!F`#P```#P&#.`2R7#,N.5XSW&G``!``*$MC0R-"+DE>"Z-$+DE>"^- +M&+D2#.`*)7CF"N`*$(VY!8_XX'CQP#X-C_@(=3(.X!HR$A`V#@]@%JEP.G`` +MWL]P```0)_8.8`\/)DX3`-\&\#H(8!H!V`'G%P]%%`L@@,,$]&QP^0@>@`L@ +M@,/R]:EP5@_@#0#9Z@W@&@IP206/^/'`@@E`!`CH'@X@"@?8=@]@`P?8T<#@ +M?O'`Q@R/^#IPSLD`W04@0`3.&ABPZ@]@%BIP&G`(<0HB@"^@```NJ78@\"\H +M00!.((('3WI4$@,@DFHQR#`DC!^@`&0NA'C.$@RV9'@$(`\#`-L/(X,`$PC` +M`X9X!24-D`/R97[/?F9YX>E4$@`@@.:F>`4@0014&D`@'`AB&LH@@@,O)0<4 +MI@U@$JEPK@S@&JEPZLDO"!X`5!(#(,]PH```'(.`T'X&O`0DC!__````SW#% +M[H1%`=DH,X:&+#&?2/M +M+RA!`TX@@0<]P@`!0UO`@40``W@\F3A`/"1$@SLG&>,X:&+""#6`2*'#/ +M<8``-!3P(0``"R!`A,[)W?/%>-SQW@Y@%@IP&G`(<<]VH```+NEU.G<&\`4A +M$2`&>2]Y'>DO*$$`3B""!T]ZE89R:C'(,".##Z``9"YD>,X2`[8$?&M\`-@/ +M((``Z/,&),R0A7_F\P5]KWWB\16&@.7F>!6F%`\B&LH@0@.>"^`:+R!'!)H, +M8!(*<.K)+P@>`'6&SW"@```<@X"P?0:\!"2,'_\```#/<,7NA$4!V0+:6@[@ +M&@4E!!-I`X_XX'CAQ0?P!GV@I!`AP0`O>0_I+RQ!$$XD@Q=O>\]T@``T%'5\ +MH(1PZ@5][_'@?\'%X'CQP!H+P`0(Z`H,(`H$V"(-8`,$V-'`X'[/<8$``'!C +MB58@`@13(WZ`)H(*\MVY)J+@N\\AH@?/(>$')J($(;Z/`,````ST`8`5"!X` +MVZ",P'9"@W@&J`2`@#/<,7N`D(`VET@]`%L]P@`#0+P"`@.#,)R*0!_0('9B3<@S@#0+8 +MR\F@$```X0&/^/'`<@FO^$`B!`G/=:``@!R"X,PAZX!>]AY@UGX\891\GF;? +M8H"7VF+AEQ"\Y7R!I4*:`K@4>!4@3``T)``#$+I%>`&EF&,`@)MC`:4&@P;P +M`-@!I0&E`:4!I84!C_C@>,]SH`"`'(+@S"'K@$OV&&`4>#1X&6(@F1IB$+D& +MFB5X`O``V`&CX'[QP.X(K_@`VN'"(8`*)0`'L(G/<0``J/!(((.8!(!V0`9!"`9\`#>%?#;>$`@D@`` +M(D`C#WAF#F`2`=D4(8\C`+<")8`4#WA2#F`2`=D!MP+FVPX$E'$`C_C@>/'` +M$@BO^"39&G``W<]V@``@O*"FSW>!`(@W<@QO_>EP$?``V`\@0`,`V00@``0% +M('Z`"/(`AA4G#!`!X*"D`*8!Y>,-5)(U`(_XX'CAQ07P(*,0($`##N@O*P$` +M3B.-!\]S@`#4U;5[=.K_W("C\_'@?\'%\<"F#T_X"'8H=0II/@Q@&P]X02A! +M`?`F01#$N!$A`(#*(($/``#]%'0)X?C*(4$#Y0=/^/'`7@]/^%IP&G%(=CIS +M"B,`(0#?&O`4(LTC()4$(8`#$';+(4&$$?)2"R`0+R#'!"*`0"X#%$"5SW`` +M`/P40@GO^`4C0P0!Y\\/!)1M!T_X\<`B#T_XSW*``(2V0(*HP6AV&PJ0`(MU +M`KFJ#R_^J7(`V,EQP@\O_JER:0=O^*C`\<#AQ<]U@`"D)R"%UW$C`6=%RB"" +M#P``P2C0",+X`!V`'U1V$#)%!T_XX'B=N)ZXSW&@```@6X$_&1B`X'C@>.!X +MX'C@>.!XX'C@>!N!X'[QP"H*P`ER"6`0`MC%R0CH`-A.#J`!Q1H8L!#PSW"` +M``3_(8`"@8P@PX\(\L]P@`"\&IH,H!DC@:H.X`$`V/_9SW"```3_)Z#1P.!^ +M\<#/<(``O!HB#(`92@E@$`+8T<#@?N!X\<#AQ<]PH```(+N`J@]@`0S8`@O@ +M`:EP(H",(<./&_(#@`#9`B!`@\HA;P"`X#*`9(X$)\,]P@`"\&KH+@!D!V(X-@`%5!D_XX'C/<(``!/\! +M@`*`C"##CP38RB!A`&T%@`'QP+(-3_B@@!IP!(6AP0\(M`!`)1$5%!41$``< +M@#]A``#PBW`B"N`7!-D`A1H*X!<$V0&%$@K@%SC9(H4!A4"0`^D1"D4`SW`` +M``-"<@^/^`.%]@G@%R*%%!"!(`T)4@#F">`70"``(02%*^@`WLER!/``@`'B +M'F8$A2,*!0`6(8`@@8`@@)EAZPQ%D`$4CQ3/`70"``(PCP`-G/<*``0`0@J`'F4R9^D/CU605O^*'`\<#AQ<]R@``P^Q9Z +M98HI"<``H(+/X-@HEX,8!,EJCT%3_CQ +MP+X,3_BB"2``"'6`X)[R,VW/<(``,/L6($0#!!2``#9Y`K@6>#A@`""-#X`` +M6/H*((`?H```(%00#Y!`)0X3R7#IAR*@D@`.ASZ7#)$X8(P@ +MPX\(I83W`=D&'$(`X0-/^/'`<@M/^`AVSW>``##[%G_/=8``$!0V":`9J7`^ +M""``R7`,Z`:/@.#)<`7R#@H```3P3@[O_R6/SW"@```@.X#/<(``^!,@H,=Q +M!`#@DU()H!FI<(D#3_CQP!X+3_@(=<]P@```%`"`$>CR#``"'PA1`$H)(!"O +M>(#@S"7BD`?R8@[`#X'@`=@P\L]V@``P^Q8F0!,%B!\(40`B"2`0KWB`X,PE +MXI`'\JEPU@WO_P#9&_",)<.?&?0`W17P%B9`$P6((0A1`/8((!"O>(KHJ7"N +M#>__`-G)<+9X#@\O_0C9`>7=#=20`-C]`D_X!"&!@.'%'/*@@`0EC!`\9$1\ +M1GT+#.40H*`A#$40I7M@H,]P@`",JT"(`=G/<(``,/M6>":H!/"E?("@X'_! +MQ?'`2@I/^,]U@`"H)Q>-SW:``/P30(85"!X`SW"@_HP%Q@H@"@'90(8/"AX` +M`=G/<(```!0@H!$*7@`!V<]P@``P%""@%XT;"!X`SW*````4SW"@_K0%`=F. +M"B`*0((7C1D('@#/BZ#.__J7#/<(``,/NV>`6( +M/@E@$\EQU0%/^.!X90%`$_'`X<7/<(``C*N@B(X,[_^I<-8-[_^I<+D!3_CQ +MP#()3_@(=[-HSW:``##[%GX$CK9]`K@6>+E@"B"`+X``6/IN"^`/`"!1($L( +M'@#/<(``"!0,$8$@`(`U"00`SW"```04'!&!(`"`)0D$`,]P@``L%!01@2`` +M@!4(1`#/<(``#!08$8$@`(`+"$4`Z7``V0/PZ7`!V$O>"2N`_`$K@*X%GBX8`)P%@TO_239]0!/^&H@0`&8N.!_:R!``?'`B@AO +M^!1X"'>`)P@8"':`)D@8"'6`)8@8@./*(X$/```@`<\C8@#/(R("JB"!#0GH +MQ@_/_RLAP`,K(H`#*R-``[4`3_C@>&H@0`%$(#Z&SW'^RO[*RB!!``SR([A2 +M(```P+@3>,&X@"`(""H@``#@?N!XSW*``%04"H(`V>!_*J+@>`#9SW"``%04 +MX'\JH/'`^@\O^`AR*'7/<*```"`[@(7B-`$M``#8,B:"<(``7.-`)X-R5'L` +M>T*%@.*.\L]V@`!4%"*&66$BIO8+8`NI<2*%!2A^``J&)W`*I@N&(H4X8`NF +M!8:`X'CT`H4IACA@":9R\"&%#0Y%<```$"&`*IL]P@`!8%0"`"N@`V):XSW&@_G0&(@Q@#4&% +M!8:XZ`&%)H8X8`:F1O#/<(``5!0DH$+PSW:``%04!(8+"00``B$/``;P#B"/ +M#_____\_9\]P@`#`)C6@`X;7=Q````#X8`.F`-@)]P/8-@M@"ZEQ!2C^`R]P +M*H8X8`JF!X;X8`>F&O#/<(``5!0EH!3PSW*``%0498(-"<0``B'```?P#B.` +M#_____\X8"B".&`(H@#8!:(=!P_XSW&``%`40('/<8``3!1`H<]Q@`"$%(#@ +M`MC*(&$`X'\`H>!X\<"*#B_XN'"(=+=HM'W/=X``T*RU9P#>Y;W1)6*2RB9B +M$!_N@./*(P(#RB-A`$`MC`"6?``D@!^``$C[0"`,`X_J`-H)\*>``>(5)$X3 +M(*8!Y<&]IZ!)(PT![PI$@YD&#_C@>&T&C_CQP"(.#_@`WLEW"?``A0T(40!: +M#J_XZ7`!YT\/%1&R;[9]SW"``$C['647;Q1XSW*``-"L$&(`V>6XT2!B@LH@ +M00#*(&(`9.CI<`8-K_BI<2"%A.D)"!4!8.E=Z#(-K_CI<`AVVO$I!B_XR7#Q +MP(X-#_@(=0&`2B=`(`#?@^!*)$`@`(7")`(E@N!*)4`@`X4D%1,0G!P(L`2% +MPB5")4'`&!49$`HF@"]`````'!48$"@5$1!:#*`)02X2(@H@`*#*(($/``"Z +M$TP/0?C/=J4```PH'L`5$@_`"5H/0```V<]P@`!X5$+``]@-N$/`!O`5)DP@ +MX*0!X0+`#!0$,`"``(`)(``![0D$@"H/0``+A4`H%@8@'H`5Z:;LIL]PH``` +M/$3`!,%*NF0"N`("&% +M!2``!3UY!+DE>$`M`24%>4`I0"4E>`4@@`^(```>!2"`!4;`*(4%A1"Y)7@, +MI@#`$0B>!X^X0,`!P(^X0<``P`'!W;C=N32F%J9`'@`62!Y`%BX,X`R%P`*% +MAN@$P`3!%(#>N!2AZJ;*"&_X!M@L'L`5?00O^+G`X'CQP%H,#_@(=R8)8`PH +M=@AUD.#*((8/``!T`,\@9@/*(<8#/`YF^,HBA@.=!"_XJ7#QP!H,#_@:<."( +M:@K@#^EPA"\!$QS96G$`(8U_10!<+5V-`"&3?T4`/"TL>@00`2`*(<`D`"%. +M=!T)4```$`(@4PF0`-,)T`#/<```"0GB#4_XG/`(Z,]P```&"=(-;_@`$`(@ +MR7#6#&`:'-D`$`$@.!M`(!V-'JT!V!RM&@O@#^EPT@O@#^EPN@L@$NEP`-AY +M\#@3`R!PT"+_C)<.!XSW*``,`F(((/@B\))`!! +M*(P``GG/<```-B07#&403H(0$PJR40`08!X2486``$\!*+`>`2JP#86AH"`.!^ +M\<"J"0_X"';+R:"0`8!`Y?2XP"6B$`/ESW*@```$)(($)8T?``#\_Q,)I0/= +M93+(&WA#<&80``<980Z"`B5/$$\(Q0,#V#8+X`X*N`39SW"@``!')*#/<*`` +M``0.@`T(Q0-L`,]Q@`"LS@*!`>#@?P*A%0A>`,]Q +M@`"LS@.!`>#@?P.A(0C>`&QPSW&``*S/#0@>`!6!`>#@?Q6A&X$!X.!_&Z$3 +M"-X!SW&``*S.`($!X.!_`*'@?O'`C@@/^((D!#[/=H$`-$;8R0`6$Q`$((`/ +M\0``\$+`R\E`)!(^$(A*(``@,V@V><]R@`#@L2%B!"&!#P```!"Z#.`10\%% +MP,]P@0``<`*`I1(!MPL('@%$(0`$!/!$(8```[A$P,]UH```(%J%!,,!A@_K +MP!4!$,L2`[8B>`(B`0`O)D@@=A,``5A@%/#+$@.VA!,6`<)P'0E>`(PB`X+' +M]U8F@2(O)D@@4.`$\*&YI1I*(*X`X"V4HE0"`*(8`O +MH```""090"4@&4`E2B#`,`@9`"8*)(`OH```!!@4`"!`P$#@$!P`(,O),8A3 +M(9<`I!`!``0AOH\```!!`-\$\L(+`!8,\!$)G@+/<```'26."4_X!/`Y'=B3 +M`!8`0$`N`200>`5Y`\#/#F`: +M`]C8R<]Q@0`8-"RXQ+C+$@.V!+$/@^ZI`*%`$P`!,A(,-@*Q$(M@$P,!5&C# +MNV5Z#ZD!AD:Q$'O/<8``]+<5(0(#GH)6(<0#FV-^HEN%6&#`%0(0`B"5``*& +MSW*@`(`,`K@OX`0@P`40HN82`K8`'X!`0H8`'X)`,L@4(0(`4(H`'X)``!_$ +M0\O)E!`"```?@$`RR/`D`@``'X1``!_$0P`?P$,`'\!#`!_$0\O)4(C/<(`` +ME+9*8``?@D``'\)#V!("M@`?@$#+R4"05!```1"Z17@`'P!`RQ(#M@&#(0@> +M`5*+SW"!`-@_<(MV>`"(AB!_#!QX!+A%>`/P@-@`'P)`R\E0B#,0@``$N@5Z +M`!^"0,O)7)``'X1`RQ("MIP2``%O@E$@@($!V,(@`0`,N,"[#;ME>#(2`S;: +M&ABP='G@L0`C@`^``!2XX*AO?,]P@`!,W99X`)"8&<0#4!D$`!4DQ`#/<``H +M"`!!P,02``"H&<0#A"@)#\]P@`#\/#0@0`X`',`#2<`0%``@(H9,'``@`88J +M">`:0(8"A@4@@`_%[@`W2L#+R0#&(8!`YO2Y`=D`D,(A00`T>`/@!"#`!1YF +M`_`"?C+(&WA#<&80``?U#@60SW&@``!%'($X@0#=#PE?!00@OH\`!@``#?+Z +MN`'=PB5!$_FXRB6B$/6YRB4B$J(*P!J0[6QPX+C*)2$0"O(!V<]P@``\VR"@ +MP@E@&2AP"-T*(8`OH```"!`1`"#_N,PE(9#0\P3M+!P`-%CP`-@)&1B@V,G/ +M<:``@"P/H<]PH```(!N`SW*``/`W`B4!(`""$P@1`DX2``;DN+@)8?S*("$$ +MR\G,$@*V.I!*)T`@.K+$$`$`Q!I``*00`0"D&D``$(@0JBP<`#0B\`#8"1D8 +MH-C)SW&@`(`L#Z'/<*```"`;@,]R@`#P-P(E`2``@A4($0).$@`&Y+A8"6'\ +MRB`A!`'80"=7($#&2\#I=L]P@0`T1@*`:0\$(,<"```,<#D('P//<:```$4< +M@3B!`-T1"5\%!""^CP`&```.\OJX`=W")4$3^;C*):(0];G*)2(2?@G`&L]W +MH```"!:'-PB4#&QP&0@>`,]R@0`T1E?8(H*,N)H-+_A`@LX*0`S/=Z````@. +M%P&6!(<0>%C@D0D$@`GPSW&``*S.`8&*)1`1`>`!H8#E>?3/<:````33H1*! +MV!H8L!*!3#"_X#<'8 +M$@*V`L`$(H$/\0``\`\(0`!'V(RX"@PO^`+!!<`"(U,DC^#*(.8##+C(O05] +MS``?`$`$&A`@#<#,$@&VYAH8L,O)`=K,&ABP`8'+&EBP]+C" +M(H$``)%6)@\25'@#X`0@@`\``/S_'V<"\`)_,L@;>$-P9A``!_<]QH```11R!.($`W@\)7P4$(+Z/``8```WR^K@!WL(F@1/YN,HF +MHA#UN`]C/ +M=Z````@*'QB01^X%P`_:C^#*(@4`#+I3)@$2SA"X17@`'P!`0"!0(,ET +MAB3]G@`:`"!`(@TA+_)4'\`4S@`V,]QH/Z8#98,X`R6N(#F>_+/<(``6!4`@`GH`-C/<:#^S`UZ#.`,EKCV +M#J__R7`(\`C9`!]`0`0=4!!`(%`@SW"!`#1&`H#K"`2@SW"!`!@T!)`#W0*X +M,""!#Z``M"[:R25XSW&@```,`J&GH:>G\@V`%<]QH```!`F!!>BHH0#8":$$ +M\/X-K_\`P(X*(`T"V)X)``T+P"CH!-G/<*```$L.7A#/<*```""ZH&_P`-H5"Q`@ +M5!_`%,]Q@`"LS@"!`>``H<]P@0`8-`20`]T"N#`@@0^@`+0NVLDE>,]QH``` +M#`*AIZ%!IU(-(!D)P(#@T`DA#"J`*,A("-LP2`;;/K)&0A>``K`SW&@ +M`(`<`:$*P8[`4@A@&L:YSW"!`#1&08#/<(``"-T`@"EHA^#*($(``K@4>``@ +M@0^``+#<0*$RR,]Q@``$N!1YH+$9!J_W@"0$/N!XSW"@`(`@7!B`#P,`0`W/ +M<8``E!0`@<]R@`#`2A[LD!H1)X!:'OR0*A$G@&H?#)$GH#H4>A\1("ME^A4GI6H<]R@``X +MP"""`>$@HL.Y=PE1`RJX4R"!`5,@@$$$($"`,_(O*`$`3B"-!T`E@!(`V0\A +M`0`+(T#`)_0R;3`AD`^@`(@@SW"@```@T8#/=X``<+8@APHB@"^``'BV"B&` +M+X``=+89#4$0`!(`(!$(`00`$0`@$'9L",$+H*<`&@`D`!F`(U$$C_?@>*H@ +M@0P)Z*LFP7(```$`JB`!`O\('X+@?O'`%@@``*H@`0+_"!^"T<#@?N!XJB*! +M#`_J&6%&(,('`O`@XA,*10"K(@$#JB`!`OT('X+W\>!^X'[@>/'`I@NO]Q'8 +M1@V``,]Q@`!D#P")SW)$`!B2`>`/?`"I/!*``&-J40P!$,]T@`!E#P",SW6` +M`&8/`>`/?@"L`-@`J2***0Y!$".*`*P@K<]Q@`"DX""!SW*``%`1.@T@`$"" +MSW&``"3?`*$-\,AC>@^@#P"MSW"``"3?`("`X#@)P0^5`X_WX'CQP!X+C_?/ +M=H``_!0$CA4(D0`"V`#=V@Z@#ZEQI*Z@IFT#C_?QP,]P@``<_>P<"+#/<(`` +M#/5!P,]P@``<#T+`SW"``"`/0\``VT3##-@#V0;:"B2`#T0`--,*)8`/@``$ +M%4HF``7R"V`*2B=``*7`T<#@?O'`#NC/<*```"`[@,]P@`!`WR"@!=AF#J`/ +M`-G1P.!^SW*``#3?`((5"%$`SW&``/P4`($!X`"A`-@`HCD%@`_QP,]P@``8 +MWP"`*PA1``#9SW"``&0/(*C/<(``90\@J,]P1``8DB.(SW"``&8/(*@-\"02 +M@``1"%$``=G/<(``--\@H-X,H``1V-'`X'[@>/'`SW"``#3?`(`3"%$`SW&` +M`/P4`($!X`"ASW"``!C?`("`X,`,@0_1P.!^\<#N":_W"'%(=0#>SW"``*3@ +M(*"J"R``R7#/<8``4!$`H<]P@``TW\"@SW"``"3?P*"G#5$0SW5$`!B23!4" +M$`CP.X$.(X`/_____SA@*94$*8$/#P!` +M0B4)!7#$J@38'@V@#P#9SW"``$@5`("`X"0*HA;*(*(`#_#/<8``D$9,%8(0 +M#X$/((``8@V@#P^A+@^`#XD!C_?@>,]PH```,#`8@`\`@```SW&B`)1N`($$ +M((`/@/\```4@@`\7`````*'@?N!XH<'QP.((C_/'`K@B/]PAV*'>TX/'`X<4H=8H-H``` +MV('ES`JA`,H@(0.U`(_WX'CQP,]Q1`#P[PV!SW)$`'#O`>`-H0'8#*$@@HPA +MPX_*(((/```A,P@*PO?1P.!^X'CQP.'%SW5$`/#O#H7/<40`<.\!X`ZE`8&, +M(/^/1`@"^`#870"O]PRE\<#6#T_W"'7/<*```"#;@$`E#Q@`CZG!&G$3"%`` +MS=@@A0:XN@GO]T:/`84BA4#``H]#P6'`!H5&P`6%1\`/'`X<4(=<]P``!),R8(+_BI<3)M-'D`(8`/1`"0[P#9(*`AH+4';_#T_W"'::<1IR:'=B#Z``"B,`(5IPSW```$QJ4: +M""`/QZ4D\">``>$GH`&%'0X!$`"%`[@5>``@@0]$`/#O%X$!X+X.[_<7H4`J +M@"`4>#`A#"`+["+8!:7)<(IQ"G+I>09O]\6EX'CQP.'%"'(H +M=<]P```],TAQ,@_O]ZER2@R@`*EPC09/]_'`$@YO]PAS*'9(=<]P```^,VAQ +M#@_O]\ERSW%$`'#O`8$`VA\.`1`$@1L-`1`%@1,(7P#_V`"ABB#_#P&A1J%' +MH/'`"''/<```-C-Z#N_W +MX<7/=8``&$7."R``J7`!V<]P1`!P[R>@!09O]ZEPSW!$`'#OX'\`B.!XC"## +MC_'`"'$,\D,)U0(S)DIP@`!0XT`G`',4((`"`'C_V-'`X'X`V/WQ`=C[\0/8 +M^?$$V/?Q!=CU\0;8\_$'V/'Q"-CO\0G8[?'-V"8/K_<&N.CQSW-$`'#O0(,` +MV0T(@0",(,./!/3@?RAP(X,"@PJY.&#/<:```"`[@2)X@.#A(,L'RB!K`.!^ +MX'CQP+8*````V<]P@`"01CJ@.Z#1P.!^X'CQP`AQSW)$`'#O`((`VQL)`0`% +M@A,(7P#_V`"BBB#_#P&B9J)GH@38%@C@``#:,@]@``S8T<#@?O'`X<4(#>_WJ7+/<40`<.\!@0#:&0T!$`6!%0A?`/_8`*&*(/\/`:%& +MH4>AJ7!J".```-GF#F``#-C1!$_WX'CQP%(,;_<("8+H!D0V8X(@`N9!&_W!"6`$^!X\<`6#$_W&G`H=4AW:';/ +M<```2#/:#._W"G&`Y0`A +M@`]$`)#OH*#AH#D$;_?"H/'`T@M/]PAVSW```#@SE@SO]\EQSW5$`'#O1H6` +MXLH@@0\``#(SK`VA]\HA@0/^"@`/!X6!X-@.@0T`V`:E!01O]P>E\G.Z"Z``"B4`(0AVSW```$8S0@SO]\EQ$VX5>,]W1`!P[U4GS1L= +M90L+GB`!A0'@`:4-"YXA`X4!X`.E18>`XLH@@@\``",S.`VB]\HA@@,2;A1X +M`"<4$"`4`""`X,H@@0\``"8S%`VA]\HA@0,+"%`@8PN>(0&'C"#_CPWR`(<# +MN!5X`""!#T0`\.\7@0'@3@OO]Q>AP*?/<*```"`;@`0?0!0"I]X*H``J<`:` +M$!^`%`.G`-VFIZ>G$=@%IR`4#"`J<$IQ"G)JSW>``"`[`">`'P``^`G/<8`` +MH$3!'P``*`K)<`H,(!&I/'`X<4(=8HA$`#/<*```!TNH-X)S_]2#*`(J7!-`D_W\<#AQ0AU/@XO_%S9 +M`=@`I0#8`:5`)0$!(.(`G_V0'FX0X4E`#9SW"``(@HX0%O]R*P +MX'@`VL]Q@`"$_A9Y0;%`J<]Q@``LT!5Y1Z'@?T*A\0")`-V`X,H@00/*(&(%RB5B$&"2)"H07P1X$!XD>A'0%O]X`D!#O@>.'%8(%@@P#<,.L$\&)X`>3]"P2`(8&@ +M@1:\%.JZ9%,B3`61<,(B#@#+]\=R0`````0B@@_`_P``FV,">WIB%?`")0(3 +M4R),!1QDD7/`(@8`2_<"(H(/0`````0B@@_`_P``8GR:8D"AX'_!Q?'`+@A/ +M]PAVSW6@```@.X7/=X``G`L>ATH@`"`">1V'(GA!*(("SW&!`/@N$.!`L1!X +MK@H@#@IQ^@W@$PIPSW*``-`6!H($@""`@"$0`!(.8!A(<,]PH```$"08``2! +MAYP7`!!2)`P0OA>!$`HD``1`EW27#@]@#5,D!1`*#(`-%@P```#:SW&``%BV +M`($/(H(#2W@(\D9X`*')<#(-H`2^%X$0.1T8E##8/!T8D$0N/A<`(8!_@`!$ +M%MT'+_<`&``$X'CQP.'%"'7/<(``G`L`D(8@_`",(`*`"]I[](0M`1P`(8%_ +M@`#L%@"!AN@!@7X)(`0E@03H`=IM\,]Q@0"X+A&)A^@0B87HF@@@!:EP`^@# +MVE_P!"*^[P0$!`3*(J$`6?+/<(``6/,`@(#@RB)A`5'R%VT4>,]Q@`"(K`AA +M%0B1`(0M"1_/<(``0#TP($`.A.@$VC_PAB`]P`GTSW&``#P,J7#B#^`$/HD# +MZ`;:,?"&"L`.%@T`$8#@RB+B`2GTA"T)'P`A@'^``"`]<1"!`",)4P!7$(`` +MC>AF"F`+J7`+Z!1M%GC/<8``W$<`80/H"=H/\$0M/A<`(8%_@`!$%@.!J@@@ +M!"*!@.``VLHB(@)$+3X7`"*`#X``1!8G<#"(@.(!X3"H`=C%!B_WP'A$*#X' +M`-D`(8!_@`!$%B"@X'\AH,]R@``<&2J"&>F$*`D/SW&``)0[,"%!#DF"8[DL +M>D`I@7)$*#X'SW"``#RV`"&"?X``4!8@H@'9,:C@?O'`SW"``-`6P@M`&,]Q +MH```$`F!@^@!V`FAT<#@?N!XA"@!#`#:`"&!?X``"!?@?T"AX'CQP.'%A"@! +M#``A@G^``.P6):(V@B]U.:+/<8``G-4PF22B*(+N""``)Z(`V,=U@``,%P:M +M!ZT%!B_W"*WQP'X-#_<(=<]P@``\##^(A"T!',&Y!.`N8``A@'^``.P6&G#8 +MH"40CP`%\"X((`!AO\EPJ7'\[R((``!H$``@B>@?WP;PR7`2""``J7%AO_OO +ME04/]^!X\<`J#0_WA"D!#,]S@``,%P`ACG^``"P7M(X`(8Q_@`#L%GUE%.7W +MA#(E31X?9Z)_]Z0EOP`AC0^``-C/X*W/=8``K,\U?2:%]J0!X2:E-(YY813A +M)W$`J12.`>`4KA2.Q+@4KC:$C"$$@(CWSW```#`1O@YO]U>$'04/]X0H`0S/ +M/?"U2!^05``N!X\<`R#"_W"''/<($` +MV"X:B`#="NC/<40`"(D)88PAPX\3\A?PSW:``/`M`X81"%X"]@Z@#@".B>@` +MCN[Q!^D:"```T."#]ZEP`_"J#X`.500O]P]XSW"``*"[!H`$((`/````X/_9 +M#PA>`\]Q@``\#"2)&PB>`\]P@`"LS1Z`#PA%`,]P@``\#"6(X'\H<.!X\<". +M"P_W"B*`+X``/`P>$H`@"B.`+X``G`N,(`*`Y?(`W5(-(`JI<<]W@0"X+CH7 +MD!`(=HHA"2\-"!`@)@^`#A)PQ/0$+GX4`=D`(8!_@`"`/;6HM*BQJ+*HL*BV +MJ+.H-:@TJ,X,8`W)EQ4@Q@#`AX2@R!`AP.[=7O'`B&'SW6``.S)1"$#@QX2@"`1\C-H-7EP(4(#A.// +M(F$$T")B!#H-(!1`H1X2@"``V0+P`=D#N!5X'64`A8#AT"`B!]`@8@?/(&$' +M`*4#AZBX`Z?/<(``P!,`D"D(7@#/<(``2!4`@`[HSW!%`#0X`(`1"-\#SW"! +M`!@SM@G@&A2(>@D@"LEP)@F@!,EPSW&``%BV`(&$+@$<#R"``P"ASW"``$P7 +M,"!!#B((8`S)<(8(H`S)<`0N?A3/<8``*#LP(4`.,P@0`<]Q@`"LS1"!`>`0 +MH1'P!"Y^%,]Q@``H.S`A0`X3"!`!SW&``*S-#X$!X`^A!0(/]^!X`-D/(0$` +MSW*``$@9%)(K>`7T)7@4LO_8&JK@?L]P@`!(&0"`@^`!V.!_P'C@?N!X"''/ +M<(``2!D=!&`6"(#@>,]R@`!(&322$"$!`.!_-++QP&8)#_<(=2D)'@#/=H`` +ME!DP%H`0'0T`$.>XC`H!`(X-S_<^#^_W,!Y"$P_8`*:E`0_WH<'AQ>'&SW.` +M`)09H8,$)8X0`-P]#IX6,!..`#$)@0,#W@N^!"*!`RNYI'XKOAT.1!!0(D$$ +MLKD$)8(?`0``P).Z)7J)<0?P`]D%\`+9`_`!V35[.H,!X3JC0*#!QL'%X'^A +MP/'`S@@O]XH@#PJ2"N`-`-T*\!8-+_<&V,]PI@``P`N`1""-`(3M;'#K"!Z` +MSW:``)09*X8([>8.[_<`V`8-[_<#A@7PU@[O]PS8E@O/]_$`#_?@>/'`X<7/ +M<8$`V$`&N`X,[_<`80HE`)`%])8-S_<(=8GMSW"``)09Z@SO]P2`"'6%[>8. +MS_<(=93MSW*``!38!H($@""`QW$``*AA6@X@&$AP`-G/<(``E!DGH`7P3@OO +M]ZEPSW&``)09,1&```'@Q;@Q&0(`?0`O]Z"AX'C//'`V@_O]A/9"'8`W>'%SW"``#P,7HC/=X``E!DP +M%X`0"PH!`!8,S_>#Z"AU<_#_#A24BW!2#"_W`]D`P4(FQ1`KIS$7C!!3(8@` +M02G"`,*Z02F``5,@1P!!*0`"4R!&`$$I@P+`NT$I``-3(+Z`02F`!,6X`=X4 +M)LD0LJ='](\)W@.+"`$#@PG?`G\(E1!["E$`=P[5``.'!""`#P```!@KN&<( +MP0$)<$AQZ'+(<[()[_<*)$`"L'#,)8Z/``#\!T``#0#/=Z8``,#4IZ>G+R`` +M`D\@`0!`+T`")7A`+L$"!7E`*8`3)7@(IPF'H;B`N`FG5@O/]Z8)[_>H<,>G +M"_``P0;8!/`%V`+P!-@>#>_W$]W>"<_WJ7`M!^_VH<#@>/'`X<7/=8``M!DP +MC1D(00#/<(``%-A^#``8#@O/]Q"-A[@0K1$'S_8`V9ZY&7GCR>!_)'@`V9ZY +M&7GCR29XX'_C&ABP`-H"N9ZZ&7I#<=P1`(9&>-P9&(#R$@&V],DY!>_W)7@` +MV9ZY&7GAR3)Y)'CA&ABPXLDD>.!_XAH8L.!X\<`Z#L_VXQ(.MLEW+_`(=BWP +M+RW!$Q,-51?/<$0`%/*V>`"`B.C/<```]0ZI<1((;_?I<@#8GKBY>`9_SW"@ +M```@.X#/<(``J`T@H,]P1``4\K9X`(!`>*EP:@N@&8HA!`#CR0<@OH/3]=7O +M.0;/]O'`X<4`W1/PSW!$`!3RMGA!@%!URB""#P``=P#`*&(!K`\B]\HA0@,! +MY>$-5)<9!L_VX'CR$@*V]!(!MD5Y:03O]P8A``#@>/(2`;;TR5D$[_`#9 +MGKD9>>/))7C@?^,:&+``V@*YGKH9>D-QW!$`AD5XW!D8@/(2`;;TR2D$[_`#9GKD9>>'))7CA&ABPXLDE>.!_XAH8L/'`,@W/]N(2`K8O+H$0G>;*((8/ +M``#B#A@/)O?*(88#SW6@```@.X7/<(``J`T@H,]P1``4\M9X`(!`>,EP>@J@ +M&0#9@-@''1B0607/]N!X!-C@?^(:&+#QP,H,S_8(=2@0@`!:<=L($``#E<&X +M$PA0`,]P``!1,+(.+_.QX`"%. +M+@.6P;@1")``SW```%(PB@XO]R*%`Y:&N`.V`H7/=H$`H!LHN`]X['@:<``A +M070#D<&X$PA0`,]P```M,%(.+_$DJ$4$S_;@>/'`Y@O/]AIPSW6! +M`*`;%(6`X,H@@0\``!PPQ`T!]Q2%(H`HN2]YK@TO^%8E@!((=N*`+@CO^S#9 +M`6\/>`0GCQ\```#_Y7A`*`$F)7@"IC.%`O`(<0/I`(']Z%4EP!1_XR7(T +MA16%$''*(($/```S,&P-`?<#ED8@P`"`N`.VS0/O]D`F`!+QP%X+S_8:<,]U +M@0"@&_*%%O`H%X`0P(>1Z`.7P;B"X,H@@@\``"\P+`T"]R*'*+DO>5H-+_A6 +M)4`2R7?K[V8((``*<($#S_;QP!8+S_8(=T$H#@+/?A1N%'@`((T/@0"D#T*% +M&G%0=\H@@@\``'`P]`PB]\HAP@,#E<&X%PB1`"@5@!"'Z,]P@0#H&_X,+_C) +M<>EP/@@@``IQ+0//]N!X\<#""L_V"'?/<*```"#;@,]P@0"@&Q.`!O"@@-(- +M[__)<:EP^^B`YU@*`@`!`\_V\<"6"N_V"',HN`]X!+@4>``@C0^!`*0/`Y7! +MN"AV*0A1`$*%4'/*(((/```K,&@,(O?*(<(`SW&@```@.X&"#>__J7"`Y@P* +M`@"]`L_VX'CQP#X*S_8:<"AW2'52#F`,:'8*<.EQJ7+"#"`7R7.)`L_VX'C- +M`2``"MC@>/'`X<4(`AQSW"```3_`(``VD&@>0$@``?802@"`D]Z=&IT>P`C@@^! +M`*0/*!*#``#9!.MB@@D(P``H<`CP`Y+!N/D(D8`L$H``X'[@>/'`H@D``/X0 +M`(%1($""`=C`>-'`X'[@>/'`A@G/]DAV02@"`D]Z!+I4>@`BC0^!`*0/0"4# +M&(B+`-H%[(*%"P@``TAP*/#CE5,G3!#W#)&0\P\>D8R+[PD!@Z2_J;_P?Z6_ +M)(NHO^.U"PQ!$)8*#_@.\$`E`!(F""```]D3E1$('P,GA02%"KDX8`2E@.;0 +M"`(``=AU`<_VF'$`V2AR"0`@`"AS\<#J",_VI<$(=7IQZLD:`AS$;Y`)0$8`(GE?A"XAHG%>`B\!7P#A0@5!Q!` +MP`2%PHE!P`6%`!4%$$+`#Y48%0000\`%B4`J`B3]C1BX$+\DB>5X"+DE>#R- +M!2("!"5X1,#/<,7NC)4!V04C0P1`+(0"M@L@&04F!A.U`._VI<`H<@]YSW"` +M`*3^70*`">!X#WG/<(``I/Y-`J`)`-K@>,]P@`!0,@"`ANC/<(``2#(`@`7H +MN0+O_PS8Q0$0@?`,]P``!0,/((#_<`A0^`!N@G +MD."YT2%B@.[USW&@```@.X$!@")X2"```$T'C_;QP*X/C_>Z#T``T<#@?N!X +M_A``@>!_AB#_"^!XSW2```3_8(0`V6&#`=H/"PX`!H2,(,./`_0H<`+P2'#@ +M?N!X\<#6#4``$PA0`,]P@0#@&P>("PA2``'8`O``V-'`X'[QP'8.C_8(=P#= +M&_`4;11X`""!#X$`H`\%D<&X(0A1`-")$2>`D\H@@@\``!LP1`@B]\HAP@/& +M"F`,R7`!Y<#EIO>A!H_VX'CQP"H.C_8H=AIR*@[O_P#?"'4%[B6%#0Y!$.EV +MZ7$A\`JY624/$A^72B1``<6E2B5``"L('P'/<*```"`;@$*%0"Z#$B)Z>6*9 +M(`0`]@X@`,ER`J4?EXNX'[>H=HAQ%P@0(`:%#P@`!!@=`!1%(8$!`=Z`YK0, +MXO_*($(#%0:O]LEPX'CQP$X.0`#/<8``!/\@@2*!C"'#CPCR#W@-"0$``M@N +M#>__*VC1P.!^\``@C0^!`*0/)16`$`GHSW```'(P +MR7%B#^_V+A6"$,]W@``$_P"'+H`GZ2.5"0E?`J*'`_"P@!IU!/`@A1IU*'4( +M[2*%]PY!D":5X[G*)2$0@^T`V$'P((4/@",)`0!6#$``C>@`AR&%#X`!@")X +M#PB%#P<``/`!V"_P`H<]#0$0!Y6&N`>U`H>`X,H@@0\``#TPU`[!]@*'`(!R +M#J_W`J>S"%&`SW&@```@.X'/<(``V!KN"L`7S_$`AU"`((4+#8$0,*`#\``8 +M0"``WL"E3@T@`*EPR7`!!8_VX'CQP(8,C_8:<"AV.G(`WPHC@"^!`*`;2!,- +M(!SP`X4`%1(0+P@!!`*%.+@0=O_;M3!,-(!OP`X4`%1(0+0@!!`*%.+@0=O_@WO]P*%2G7H[4PA`*#,)R*0P`O"_TD$C_;QP.'% +M6@WO]RAU@.7,("*`J`O"_V$$C_;QP.8+C_;/=8``!/\!A2"%`*4AI8#@RB"! +M#P``/#"X#<'V((7.@<*E!.X'EA,('P`B@<]P```V,*X-[_;)`+Z#^\`#/<,7N@G8!V3H.X!CJ<@HC@"^```3_ +M!!,-(``<`#0BA8HFPR_2<`3"!4!-&@A8GSI2B%`("7P\H,*)$`D +M!_``'D`5`=@Z<)IPX(<;[R@7@!"'Z,]P``!+,&X,[_8BAQ.7Z0@?@R2'`B%` +M!=<(4H`/#!`@`(8B>,\(4H`@IN/Q3"$`H'7R;!(!(`#8$G'*(&\`@.#*(0$$ +MSW"``%@2`(`D&T`@@.``#`(`,@\`#`#!"')`(P`E@@U@%ZES`H5["(`%K@A` +M`"&%"'(D>!!QRB""#P``3C#X"\+VA@A@``*%C"#_C\H@@0\``'HPU`O!]@Z% +M3X4!@`.E`8($I2:2$0E?`,]P``!?,,H+[_9"@@^%((`'Z<]P``!@,+8+[_9` +MA5((8``"A2^%"'(.A2&!`8"*"&`,984;\!"%&>@#\"AP((#^Z<&`5B4`$@'F +MR7'6">_W`-H)Z`03`2`"@=)PRB5"$`7PJ7!*"2``R7'JR1L('@1L$@,@SW#% +M[H-W`B,#!@'9C@S@&.IRJ7!E`:_VH<#@>,]R@``$_P#;$/`4:T`@#`16(L$% +MF6%88+@80`#&$`$!`>.@N<881`",(T./K_<`V<]S@0"$#PN3(J.@N`NS5B+, +M!8.B0",``@2B0"(`#`"B52)`!P&B@J+_W"AS"O"$*P$!`>,`(D`.CJ`ZH#N@ +M/*#O"Y2`AJ*'HL]P@`#8&I4&H! +M"(_V&G#/=H``!/\`A@'=+H#B@`_I1Y$;"AX`0H83"8$`4(`'ZB&!0.#."._W +MJ7+/<(``:#*@H`"&2@@@``IQ_][:":__#-@R#>__"G`B@"$)@`,=#T$0SW*@ +M```@6X(#@)8B"``">H#BRB4I$`\)@0//<($`H!L2@.3HB0"O]JEP\<`B"(_V +M"B4`D"AVRB"!#P``03#\"<'VSW&```3_)($`V`;I0(&`XLH@80"'Z,]P``!# +M,.X)[_9`@0Z%!^CR#Z_WR7$`V`ZE#Z40A0;HX@^O]\EQ`-@0I?_8.0"O]@*E +MSW*```3_!N@B@":B`(`%\/_8!J(`V`6BSW"@```@&X`(HN!_":+@>/'`F@]/ +M]L]V@``$_P.&@.#*(($/```Z,'`)P?:CA@"%`Z:I<.8+;_L0V0>5@+@'M0#8 +M`*75!V_VJ7#@>/'`7@]/]@HE`)`G\L]V@``$_R2&`-@&Z4"!@.+*(&$`A^C/ +M<```.#`V">_V0($$AJ"@I*80\`>5X+C*(($/``!*,!0)X?;*(4$#!Y6@N`>U +MI*:@A?'M>0=/]N!X\<#6#T_WX@Z/_]'`X'[@>`(@0P`7"U(`$PJ4``3P0"J# +M`GEA,'#Z!\__X'\H<.!X\<#2#D_V;Y`(=BAUEPL?`R06@!`_"%$``X8=Z&*& +M"KAX8)8@!`"B>#^X4B``@`GT((;/<```)S"F"._VJ7("AA!URB""`X0-HO_* +M(2("HJ8I\!R.3PB2`$*&"?`%A@JX&F)"I@/P^0L>@P(E@!`/"%(`]PX$\``` +M``@")8$002G`!U(@`(`&\AL)A`\````($+L@EL]P```D,&5Y0@CO]JESH09/ +M]N!X\<`6#D_V`-X*((`O@0"@&T@0#R!Z=@GP`-E6($`BP@^O]^ERX(4Z[RH7 +M@!!R<,!^RB,"("07@!!="-(``Y=3")X"*NXBES#86G`,>0HA@"^!`*0/(H<` +M(4TN*+DO>;(/K_=6($`B"'$0=\H@@@\``(0PN`^B]LHBP@,BEIT)@(\``/__ +M!"F^!``A073'\8#FRB;!$^EUR/'9!4_V\<"*#4_V"';/<*```"";@`#8(!X" +M$%DF#Q(?EUL(G@'/<($`H!MR@`3P!(8&HV"#(^L3D_L('H-&@R"&\PI!@$2# +M(H99822C7YI<6X-(``$CL=P@0#@&R2(8;DU!6_V)*CQ +MP,8,3_8(=<]P@0"@&]*`&_``V@6&)(8*N&B&.&!`*XP"F&!88,=P$````+%P +M&``/`!"[0H;/<```8S!E>I8.K_:I<\"&(^X3EOT('X,#EA\('@$;"!\")(8P +M=1(`#P!"AL]P``!K,&H.K_:I<\]P@`!L,2F`4B$!``2Y.&`D@,GI0X`"@`)Z +MQO&M!$_VX'CQP`X,;_84V:K!^G!*(0`@E@AO^XMPA<"."&_[%-DJ+C"A2!SW"!`*`;TH`*($`D +M6O`+"1,`!P]2$/-_`(7J"Z`,RG%9)1,2<0A1`#X3`"%*($`P42!`@D`E%1@` +MA<(@`C8$%8$@)@JO_P#:+0A1`$`N@"!#)X`J6I<$X*K_\$V3X3`"$7"!X!(H4"(<$%"PE2`(BX/AL$(`\@D"3`AB_N +M$Y;["%Z#`Y8,%I(0#PC>`JNX`[8/(9$D0"J`('`@`0>$Z06`;>B$*@DO`"&` +M?X``(#TG@$:`0"8-$EEA!!66$`6%%PDR`$`HE`(H=Y)W``?,_P(G#Q7[\3-_ +M^?&6"*`,!2$`)`IPZ@D@#`'9Y0)O]JK`\<"V"D_V`-T*((`O@0"@#ZES%_!` +M*P("!"*"#P```/\T:S1Y`"!`($.@+!A"`S#A0"`"(5EA(:`I:R2P`>/`XZKW +M"!B$+P``___/<($`(!NUH,]V@0"@&P#?"?`T;P1N.&#.#B_[$-D!Y_4/%)&R +MIK.F0"``(12F0B8`&Z$";_85IN!X\<`V"F_V`-K/=X``!/_#ATAU$/`'E@'E +MX+C*(((/``!X,!`,HO;*(8(#`(;)<@AV\NX$AQ!R_MS,)0&3RB""#P``>3#T +M"Z+VRB%"`U4"3_;QP.'%"'4&D*;!$PA>`,]P@`"X]48.+_LHV>K)2P@>!&>5 +M1I7/<8``N/4#@0@1!P!`P`2!!!$&`$'`!X$`$04`0L`(@005!!!#P"01@``0 +MNT3`!H%E>D7`SW#%[HV4`=G*#*`88H7]`6_VIL`!VB08@@#@?SRHX'C/<8`` +M!X\<#AQ0AUA.#*((8/``"",$@+IO;*(48#SW&``&P;$FT4 +M>+D!;_8`8?'`(@E/]DHA`"`J=03P2B%`(`'E50T5$8H)(`"I>!_(&#@>.'%`-S/<8``1!M`(0()0"$#!0CPBB#_#Q4A#0,`I0'D]0Q4D0#< +M"/"*(/\/%2,-`P"E`>3U#!21`-L)\(HD_Q\2:Q1X6&"`H`'C]0L4@038!*$# +MVDBA4J$0V!.A5*'@?\'%X'@/>AD*-0$`V0*Z5'K/7*((8/```(,.@)AO:*"2_[J7!=`$_V\<#B#P_V"':* +M)?\?A>#*((8/```',,0)IO;*(88#`-H+\!)J%'C'<(``1!LJ@`D)C@.K@`'B +M#0H5`8PE_Y_S\Q$`;_:I<.!X\<#AQ0AUA>#*((8/``!A`,`HY@%\":;VRB%& +M`QH)+_NI,]Q@`"/'`X<7/=8``I/[L'$BSSW"``,S^0<#/<(``%!I"P,]P@``<&D/` +M`=A$P`#8!=D+V@AS"B2`#X``)!H*)8`/@`#T&DHF@`D2""`)^'#/<0``(")> +M"B`)J7``V"()+_H(<34'+_:EP.!XX<#AP8H@_P\3(,`"!'D`*(`"`"F!`@8D +M#!`E?,'!X'_!P.!XX<3QP-H/[_^`B("H!!0?-.!_P<3@?N!XX'[@>.!^X'CQ +MP,8(P`W/<8``8`\;"!\`SW`!`$@[`*'/<40`>/03@86X$Z$%\,]P`0`@.P"A +MT<#@?N!X\<#AQ8X(X`T(=4&%X+@C@L\AH@//(>$#G08O]B.BX'C/<*```!\< +M@.!_P+C/<(``/`QDB"6(SW!$`%CV2(#/<$0`%//P((``.&`0'8?&)#I!0_VSW&@`(`=1!F`#QX````3@84@#``3H16!N;@5 +MH>!^X'CQP.'%SW*@```=.!J`#P```$#/=40`^//,%0$0`-L`V(Z[#0G>``/8 +M"KAMHDX/S_\."R```-CB#"`+$(W&#"`+%(W6"L_]D04/]N!X\<#AQ<]S1`!X +M]%N#*.H$VL]UH```($X=F)``VENC#PB1`.X+X`XH<`/PN@O`#L]Q@`#`"`"! +M4"!`A`"A$/2[A0#<"?!!@0>!`>188`>A>F)(H0T,E1)H@>T-Q9`M!0_VSW-$ +M`'CT6X,M"E``!-S/E+X;"!X%2@[/_X'@RB!A`/`)H0[* +M(2$`$/`7A0#>FKX;")X&SW"``$P)`(`'Z"(.S_^!X-`-`0#9I:$$#_;@>/'` +M&@P/]O_=SW"``*@GMZB.#"`+#]A*(4`@"B"`+Z```"!+&%BD`-A:<,]WH`"` +M'PNGSW9$`/CSSW%$`'CTLJ$#V.`>`A#B'D(3`M@7H1^A':$>H?X)(`!`'A@0 +M@@H`"W,8F*0`V"(+(`L(<3`?@!_P\/#P/03@%,@`0`)N>&XSR'B`<]RH`"`'1:")7@6 +MHN!^X'@$V+D!(```V?'`SW!%`,0B"8@8Z,]P@`"@V/X(0!?/<$0`>/0;@!T( +M40#/T5>`7@>A(# +MAD`HS0($)8T?`P``^,]V_/__!\1[I7MZ&MB`SW2``!0)8H3@A,1[Y'ZE>V*D +MQ7V@I,]S1`!X]$X:6(`9HP/P31I8@$`@@"+&""``*G&=`@_V\<#/N!_(*+/<0``#__-`^`4`-C/<0``#_\U +M!N`4`-CQP,]P1`!PDNP<"+#/<$0`H))!P,]P1`"8DD+`SW!$`&B20\``VT3# +M"=@&V0W:"B2`#T0`)/,*)8`/1``L]DHF0`W2"N`(2B=``*7`T<#@?@AS*'+/ +M<$0`<)*!`^`(:''QP'H)#_8(=@;8`-WF#^__J7'/<*```!^AH-(/K_W)<,D! +M#_;QP`?8R@_O_P#9`=G/<*```!\AH.8/C_W1P.!^\<`."\`'SW```%55T<#@ +M?L]PH```11B`.PC?`\]Q@``LSA"!`>`0H3+(QW"``!2X((@!X2"H((C/<$0` +M^/,`@!,(10"*(`@`TAH8L(K8D+@'\(H@$`#2&ABP0MB8N.!^@.#,(**`!_0! +MV)$:`K``V`?P$PC1``#8D1H"L`'8DAH"L.!^SW"``$BZ!HC/%,@ +M`0``@J"X)7@`HA4`H!@%V.!X\<"2"`_VSW*``!0)`H(@@J2X@[A&(0$&(*(" +MH@#9SW6@`(`=.J60&D*P`=@]I48/X`J1&@*PSW&``,`(`('/=J```""0N`"A +MSW!$`'CT$X`3"-X`%86YN!6E3AZ8GP```$`5A;6X%:69``_V\<#//03@!,(W@`5@9FX%:%-&IB/````0!6!E;@5 +MH='`X'[QP+X/S_7/"8`-#P@?`-8)@`T-"!X`DQI"LP3PDQJ"LTX.X`H! +MV-D'S_7@>/'`X<4(=9'+#>B2RX#@RB""#P``_0'*(8(/K=[OOCP)0O:1RZOH +MDLN`X-`EHA,O],]P@`!(NB:(SW*``!0)`(+AN<\@(@#0("$``*+/`T5X&J.T$0"`%PB?`QV#">B&(G^."?(7#=\2CKT'\+01 +M`(`+"!X`J[WY\5$'[_6I!^\<#/<8``3`D`@0?H`=@!H/'`SW*``$P)`((1 +MZ&&"`-D!V`L+40`AH@/P`:(H<*(/S_\!V-H+8`X(<='`X'[@>/'`7PA1`(8( +M@`U]"!\`SW*``*R_`8(-Z,]P@`#`""Z`SW"@`(`?+*`\H#V@/Z``@BKHSW"` +M`)P+I!""`,;BSW%$`/CU2O80@!$(7@((&8`/#``#`-'`X'X`V`*A_/$N"(`- +M)0@?`,]P1`#X\XB`:8!*@"N`SW"@`(`?C*!\H%V@/Z#J\>CQX'C/<*```!TT +M&(`/0````#@8@`]`````SW"``,`(08#+R8(B%`6`(`(`>)`H@'!RSR$E!,\A +M)@;@?RB@X'CQP'(-S_4`WL]U@`#`"+H/8`W`I>"XRB9B$0"%SW&@`(`=#R"` +M`P"EBB`/"@:ESW"@```@9!B`CQX`!`!`&8`/'P`&`!.!12#`#!.AE07/]?'` +M'@W/]<]U@`#`"("%IPA1`*"\@*6%*9,(>F(O=H4J20P`(8]S1H7AI0(G@1`E +MI0`AP',$I0#8FKC5V:ER"ML.#6`8BB3'#X#FS"`@@9@`\,``,`&?``V`*A%?"`O,(. +M8`V`I2,('P#/<$0`^/.(@&F`2H`K@,]PH`"`'XR@?*!=H#^@#@@``*T$S_7@ +M>,]P@`#`"`"0SW*@`(`=`]F`X!6"%[G%($$`T"#B!=`@(@85HN!^X'CQP!(, +MS_4(=<]P@`"H)QJ($0A>`,]PH/[,!)H,H`<`V4:-SW-$`'"1PKI`HP>-SW2M +M`(``PK@!HR*5SW:M`(`?(J,DA(8A<``BN<*Y)J.SAC2&80H5`C,F@G"``!CC +M0">/B/P!"6"'P```/\HNAWP!"6"'_\````PNA?P!"6"'P#_```2 +M\"]Z$?`$(8(/````_^WQ!"&"#_\```#O\00A@@\`_P``.+I$HVT(%0(S)@!P +M@``@XT`G`G(4>@!ZKWVEHRKP!"6-'P```/\HO:6C)/`$)8T?_P```#"]I:,< +M\`0EC1\`_P``.+VEHQ;P+WD3\`0A@0\```#_*+D-\`0A@0__````,+D'\`0A +M@0\`_P``.+DEHP'8`Z,$A("X!*02AH"X$J82AH&X$J82AH*X$J8."0``00// +M]?'`U@K/]<]P@`"H)QJ(`-T1"%X`SW"@_N`$6@N@!ZEQSW9$`'"1SW&M`(`` +M!(%&AD8@P`<$H02!`KI%>`2A!(&@N`2ASW&M`(`?$H&@N!*A$H&AN!*A$H&B +MN!*ASW"``/C92@@`%^$"[_6CIL]QK0"```2!H+@$H>!^X'C/`2BX'[@>,]QK0``(`"!H+@`H<]QK0``!`B!J[@( +MH0B!JK@(H>!^SW*M```$*(*+N2BB*(**N2BBSW&M```@"^@K"%``'PB1``"! +MH;@`H0"!@K@&\`"!H;@`H0"!HK@`H0"!@+@`H>!^`(&!N/?Q\<#2"<_USW5$ +M`'"1!X7!A4"%!N@`V`>E984(\`'8!Z5DAW*ASW"``*@G&H@5"%X`SW"@_D0$`MD:"J`'R7//<:T`@``$ +M@02!`KZHN*RXL+@$H02!!('/"2! +M(($9868/X!9(<*D!S_7@>/'`,@GO]0#:SW:``)P+#X8A"-X"SW"``"!''(!` +M%H$0P-TD>(8@_PXBN!I]2'`$\!3=`MBX%@$1`GD0A@3A?@T@!P#:SW&!`+@R +M&J$=AKFA&Z$>ADT![_4!XH<'QP+8(S_6H="@<0#%:<+AQ&G(Z(L]T@`#4[C1DC'L`*4QU!2H^`T)T!PD%!L(10#/=8``M.PR)4(4=7L%*CX##0M$#A1X%PA% +M```E`"1`(%``"PR>)@/9&1M"(%$D@*;*(0($RB$A`!P;0"`*<`C<9P>/]>!X +M\<`B#X_UA"@)#P`A@'^``"`[*!`&```A@7^``*`\F'%`(04&0"$'!U$FP("* +M(@@`RB(A`%VQ`-T1\,]W@`"D[:]GR8#K8V1^R\KP0!.(XX'RV1PJ@'E +M5PT5$NF`SW.``)SMJF//=(``-.]$?R\JP0-.(HX'SF0`)$(#P*K3@>1^+RZ! +M$TXFCQ?N9,BJJP[>@&B`AN73(Z8`+RO!`$XCC`?/R\KP0!.(XX'RV1PJ@'E70V5$DF`SW:``+CMJV;/ +M=(``-.]D>B\K@0!.(X\'ZV0`)T\#8*]S@61Z+RJ!`$XB@P=K9$`D`@BZ8F:J +MIP[>@&B`@.73(Z$`+RO!`$XCC`?/,@K-T+%($U!H_U\<"Z#8_U"':0B,]P +M@0`8/Q8@!`//D"*`!0!`0#8$0I?`<]R@0``<$.*!PK>``'85B8- +M%"#H"84]"!X#!H4$((4/````&",-@`\````(#"6`CP```!#*(((/```\%9^Y!2&!!#NBSW*``*S/'H(!X!ZB+'`!")X%SW"@`(`L7(#J +MR2L(W@#/Z$.'N#8:`AH$`H`2)!H`4A000AH$$J +M``53()`!4R*!!,]U@0`T1L]W@``LS@*Y50J>!U$(E"``EA#@20A%`""E"!T` +M%)@6`!"N""`'0"4"%`&E[!:`$#V'*!T"$.H6`!$3M1^'`>`?IP`A``0=I]G) +M#8`-"%X`I``@@0^``*C7/<8``"-T`@>4-!)``V!T$ +MK_4`H?'`F@N/]0AVSW"``(RKH(@!W]()8`VI<(#@S"7BD&SRSW&M```80Q$` +M!E,@P(3,((*/#P#__\H@P@,#]`#8&.A#$0(&SW&``-2F`8'3NA$*)0!#H0*! +M$'(!V`/W`-B-Z,]P@`!`,@"`"PA1`'8.#_="\`'80?`J[@#<`_`!Y'D,%1+/ +M<(``Q!/P(``#?=D%N0(@0P#I"X6`.&#E"@6`S@T@#:EPSW&M```6$0A0`,]P +M@`"`$P&`B^@"@?#@0-C*(((/``!P``*A%O`+@00@@@\'``#`UW(&`````=K" +M(H$`#KK'<@4``,`$((`/^/__/T5X"Z$`V!$#C_7@>.!^X'CQP$(+(`<1V,]Q +M@`!4JPF)`>`)J='`X'[QP(8*C_4*)0"0`-X$\H#ARB9A$,]P@`"$,P"`(8C# +MN<]P@`!4@83A!(#!**$`"?+/<3,S,S,%*3X`"B#`#AUY@.;*(0(`C"$4BPS8 +MRB#F`53WC"%1A\H@)@)0]XPA#H'*(&8"2O>,(`NXSW&M``!> +M`*'/<:T``*A`&8`/````>,]QK0``:!"A.0*/]>!X\<"^"8_USW>``%2"'I_/ +M=8``5($EA2)X+R`)`"4(D@?/=H``C*OB#R`-`(X!V0?H`(Z#X,H@0@`%]!Z? +M)J4%I0#8Z0&/]>!X\<`6#2`-X<7V#X`/SW6``%2!SW&``(0S(($$I2")"PG3 +M`QMX!*7/<(``5%@`@!D(W@8&A07HX@T/]P#8!J7*#`_W#/"MV!"X3!B`#Y02 +M*:5@&(`/E!(II:8,``V:#N__`-F1`8_UX'CQP.'%SW6``(RK3@\@#0"-!.@` +MC1L(T0`!V,]Q@`!4@0:ASW"``%2"'I@%H0OP@@T/]VX,#_?/<8``5*L3B0'@ +M$ZEV"2`'&]A!`8_U\<#""(_U+@P`#4(,(`T(=07MSW:``$A]"_#/<8``5'X+ +M")$`0"$."P/P62&.`\]P@`!46`"`0"8!'&<(G@0`V@GP\":#$,]PI@``A%5X +M8*`!XO,*%(,`V@GP\"&#`,]PI@``B%5X8*`!XO,*%(6`%@T2@89BA@.&)(9% +MAN:&SW:D``!$HJ9*IH6F9J;KI@>F**;/<8``=*L)B0'@":F1`(_UX'CQP,]Q +M@``TJ1:I_@@@``'8T@@`!]'`X'[QP/X/3_4:<,]VH```(!N&`-_(V!8/H`?I +M<<]PIP!<1""`SW6``-2H.:7(V/X.H`?I<<]PIP!D1`"`Y@@@`!JE"B&`+X`` +M5*B%"!`@.84:A3A@);@#\`'G'7C_"!6(SW*``%C?(IKU(@``!2G^`R=P0.`F +MN!NE@B"!#AREF@Q@`0#8/(7/=X``-*D8($``0[@4KQN%[N#*("T#!?<)"!4/ +M(]@4KTX,8`$`V!^ESW"G``!$'H#/<8``=*M!&1@@&X8&B0'@!JE:"V``%(^5 +M!T_U\<#_V<]P@``TJ3:H$@@@``#8W@_`!M'`X'[@>,]R@``X'""*@.#/(2(` +MT"$A`.!_(*K@>,]R@``X'""*@.#/(6(`T"%A`.!_(*K@>/'`.@E``=(/(!`` +MV-8*(!``V!X,(`(!V)8*``W2#``"S@O@%@'8T<#@?N!X\<"^#D_UOL'/<*`` +M`"`;@`'=I@H@$*EP:@H@#0#?C@P@`HMVW@L@`NEP\@P@`LEP0,=!QT/%1,=' +MQ4C%2L5+QTS'`]A%P$;%5<=6Q__86,!D'(`_````")X)(`+)<,]VIP``2*VF +M1@\@$*EPSW"M``!J!!B`#P(```#/<*T``*H$&(`/'````.X-``"`X,H@@0\` +M`$``RB'!`\HBP0.P"&$!RB/!`WX((!"*(%```=@%V0#:2'-:""`0F'(1V,]Q +MIP``1!6A\J;SIA*!@[@2H;"A609O];[`X'[@>/'`Y@U/]4X)(`T!W8'@7@D@ +M#<(E01.$+0$>"'8`V0`A@W^``%2"5!.$@&@3A8!\$X:`D!.'@"P3@H"B#B`0 +M0!.#@*EPF@HO]\EQ#09/]>!X\<#/<(``C*L@B`8)(``H<,H+(`TH<`CHSW&` +M`'2K!(D!X`2IT<#@?O'`4@U/]<]P@`",J^"(I@L@#>EP`-X8Z,X((`#I<`AU +M0"`2`HX+(`WI<`[H0"44&!H4DR";"S(B0"05)L]Q@`!`'P"!BP@0`,"AP*7! +MI+O"A2$+R'")")P\@UO]6IQ +M&G`"I0`AP"/F#6_U:G$#I0P@`*`!V,(@#0!2(`,`\"("(/`BP2""<")ZV*@` +M)=4@`!V"(SB(66%)(<$`.*@`V`?P&678J2@9@@,!X/D(%(0:'((CSW&``%2K +M!8D!X,T$;_4%J>!X(0?/_X0H%@D`(8!_@``4;.!^X'CQP'8,3_4(=RAVSW"` +M`(RK((CB#^__*'`(=:8*(`TH(#@`-AU!&_URB!"`^!X\<#R"T_USW"``%18 +M`(#/=H``U(!%"-X%!H8@Z,]UH```,`@=@!\```"@&@E@&![8$@E@&![8@@E` +M$__9SW"B`(!Y*Z`,'8`?````H/8(8!@>V/((8!@>V&8/(!`'A@4$3_7@>.!^ +MX'CQP((+;_4,V,]W@`",J__91@O@%T"/Q\F`X,H@@0\```@)6`V!]0#=`_`! +MY;!]:PT5$L]P@``H\A8@4`,`$`X@Q\GK"(Z#$-C)<0X+X!=`CP00$"`5"!$@ +MQQ(!ML]P``"/$RH-K_7)<@IP0'C'R1`@@(/'&ABP0(\(]`G8V@K@%\EQL@QO +M_@?8$=C)<!XSW&M```80!$`AJ>X0!D8@&,1`(:'N&,9&(#@?O'`X<4!W4T(40#/ +M<(``5%@`@$$(G@?/<(``@!,!@#4(40#/<:T``!AC$0"&I[AC&1B`0!$`AH>X +M0!D8@'H/S_;/<8``=*L5B0'@%:FI<`7PE@_/_P#8V0)/]>!XSW&M`(`5`X&% +M(`(!`Z$#@:*X`Z'@?N!X\#6(,(N45YG[E"&%B`SW"``%18"Y`1"!\!(@X`$X#@[`O"#M'`X'ZU +M!\__\<#/<0$`A%S/@T@`!2(T<#@?O'`X<4(=0/8H@CO_2?9SW&@```@.X$B +MH`79)J"*(5X((Z`#V.8([_VI<:D!3_7@>">`SW*G``!(*Z(H@,]S@`!D'G$: +M6``\BSVK`>'`N3RK*!`!`BBB`8`)HN!^\<#/<(``5%@!@.^XN`G"_]'`X'[Q +MP.H(3_7/<(``C*N>#.`,P(@(=<]P1``(B:A@C"##CPKRK@Y@``&`@.#B(`(``>7Q#522R@G`!O4`3_7@>,]P@``X'`"(@.``V`SRSW"``(RK +M((C/<(``-*D6B!!Q`=C`>.!^X'C/<(``.!P`B(8@?P^"X`'8X'_`>'D'``'Q +MP#((;_7_V0AV`MCV#Z`7R7*$+A89`=D`(8!_@`!8;""@7@@@`,EPSW6``#P< +M`(4'Z,]P@``Y'`"()0X`$`#?"_#/<(``:/+P(,`#@.#B(`(``>?P?^\/U)($ +M\&(.C_\`V`"E_]G/<(``.1P@J`/8D@^@%\ER*0!/]>!X(07/]O'`M@\O]?_9 +M"'4$V'8/H!>I!X\@>'")H$30*`R"V``J7"I<.X-(`')<9T'#_7@ +M>#T#0`#QP`X/#_5R#B`!&G`(=4B`E(`*(X`O@`",JP`3@""*(A8I!"B^!`HA +M@"^``-1K0"$`+C`@0PY:8E1Z`".$``(4`0&<9)1\F&/*D%,A!0()OL]Q`P`` +M_B1^!26%`\]VIP``2!P>0!$`%`\!"9#(OPFX)'CE>!VF>F("FIMC2Y/(N`FZ +M1'DE>`:F-@K`#&B%`!.!($`@`"H$*;X$52'!)S`A00Y4A10AS`!@G%1YAIS+ +MN\N\#+R%>V"@0YDIF(@0@`!YND.U)(!V<]P@``\'""@SW"``#D!XX'[@>.!^X'CQP,<2`K8(<0\B``#'&ABPE>K//'`+@T/]0AU`-X/)@X0Q\G+>!+R!B"`@\<:&+`,],]R@`", +MJPG8J7'2#*`70(JJ#B_^!]C$R!X\<"B#"_U_]DZ<$AUSW:``(RK"MAF#*`70(YK#5$0`-T#\`'EL'U5#142 +MSW"``"CR%B!0`P`0#R#$R>L(SH,.V.EQ.@R@%T".!!`0(!4($2#$$@&VSW`` +M`(\35@YO]>ER"G!`>`_8Z7$2#*`70(XN""``Z7#$R=?H`]B:#Z_]*G$$\-8* +M[_\`V`O8_]GN"Z`70(YU!`_UX'CQP`AQQ,D0($"`Q!H8L`STSW*``(RK!]C* +M"Z`70(J:#*_]`]C1P.!^\<"N"2__H<'/<(``-*D4B$#`SW"``$@5`("`X,H@ +M`0?*(2$!?`RA$\HBH0*AP-'`X'[@>,]R@`#TJ!6*-XI1!J`/68K0X`#9R_:, +M(`*$RB%I`0[V].`$V#*(6D`.6$T>0`A@`^```BI +MX'[@>/'`<@L/]0H/H`P!WKX/S__.#J`,"'6!X,(F@1/)<`#9^@W@#T"-R7`! +MV?(-X`]!CG+/=H``W%8!I@'?`-T#\@*F!O`+"1$@XJ8"\**FSW&E +M```,!($*)(`OK0```(2X!*&+<(((X`%:<"*&2,=!A@#8#R"``$3`SW*M```# +M&()#P<"X3\`8@H#AAB#_"R2X4<`8@L8@@0____?_P2CA`,0@@@\````(P2CB +M`D8*8`].P$W`"(96Q4#%4\4%Z`+81\`6\$?'&0D1(`T($2`#V$7`1L<.\`78 +M1$'`6L6^ +M#*`!2G#/<8``>`M`@00<@"`A@0@<0""Q`2_UOL`0>14)DP"$*!@$`"&`?T0` +M6)0+\(0H%0D"(8!_``#("L=P1`!XH.!^\<`V"0_U"'4H=XX+H`P:`(0M%AG/<(``B&LP($`.FNB$+1L03"``H"]QA"_"&B]PP"&!#T4`0`?` +M(:$!P"&"#T4`X`G`(:($&6$&B5CH`HD*\%AB%7CT>,]Q@`",H#4A```!`0_U +M\<#AQ<]Q@`!46">!!.A!*0`"!/!!*8`"P;@#W=X*H`P&??T`+_6D>,]R@`", +MJT"*&PK0`(0J&P``(8)_10!`#6B:8+`*F@"Q!/``VD"P0+'@?N!X\ +M``"!H[@`H<]P1`!XH,]Q``#T&GX,S_G/<$0`6)1AV7(,[_D%N0#8%K58\!:5 +MA>@`@:.X`*%2\,]W1``X]\]P1`!>E.EQJ][J#&`4R7+/<$0`"I?I<8`AP@K6 +M#&`4R7+/=40`./G/<$0`;IJI<8(A@@J^#&`4R7+/<$0`&ITA;;(,8!3)<@+= +M(O`*;1UXA"@5"<]R1`!^H`H@0"Z$+845`"(`!`HA0"X`)T$>A@Q@%*O:SW)$ +M`"JC`"&!(_EA`"(`!&X,8!2KV@'EP0T4DP`2`""^"^_YBB$,")4'S_3QP"H/ +MS_2AP0HA@"^``(RK`!&/(%8*H`SI<$8-8`P`W8HA%@DL?UIQ+W8`)H$?@`!( +M:P"IV@\@`.EPSW"``%2@>G"FH/H,8`RI<-L/T!#/<(``3#(`@,\($0`:#4`, +MQP@0`,]P@`"(:T`@%`'`8`CH_]G/<(``B#,@J%7PSW:E```,$!80$!`>@!\" +M``$`=@J`#,(,8`R+<0`1@R`@P@0KO@0P)$`N((!0<@0'@`4&@F@#.EP@>`!V*(-[__`>`WP(*K&"F_Z%!E"(Q`> +M`!0@$P`@"PB1``#8(@Q`#&$&[_2AP/'`[@W/]`AW*'`V"*`,X!Q(L!IPT@B@ +M#.EP`=E!P8'@`=C"(`$`0L!*)P`@@.`!V$8-[__`>(0O%AE$P`HB@"^``%2@ +MSW.``$QK+W`"PD`B`2SP(8(``"".#X``5&N#Y\PB(H`+]`'!&V,@HX#B+:9T +M#B$`RB#!`\GPA\&N"V`,`,"V"V`,`,"$+QL00\#/<$4`0`<`(%,.:G$NI@HA +M0#XH$@$@-![`%8#ARB&!#P``P`;8">'YP"!!!BP2`"$/Z`+`@."*(A@$RB*" +M#P``9`4*<&IQ&@M@%"*Z)\``&P`@SW"``%181<`!@$H@`##C"-X``-T;=07P +M2B!`,`'ETPV5$`3`^0A.@P#`-@NO]JEQ&G`GP8HDA24*)8`O1``X]T`E0"!& +MP$`EEB&$+<(:(PAS*`HA0"X!P`0I/@4-I@`A0"["<``8P@6>#2``Z7`GP`0H +M/@4`(4(N,B:`(%#HSW!$`%24`("$+0(3`\$G<`*Y`>`U>2A@"2``!"\@!B"% +M[4`C@2$&\,]P10#R"0`@008`(D`%E@E@%*O:*!(`()CH)\`&P00H/@4`(4`N +M"&%-"`.$$F\4>`S9QW"``)2@*+`D$@$@A.DID("Y*;"8\07``8#CN,P@(K`2 +M\@V&D.@R;S1Y#-C'<8``E*`(L0+`B.@D$@`@A.@)D8"X";&V#J_VZ7`L'L`5 +M,![`%2D$[_2HP#)HA"@6"31Y`-K'<8``E*!(L4FQ`"&`?X``C&O@?T"@_]G/ +M<(``B#/@?R"H\<"R"^_TBB(&#((D!S!`P`HG@"^G`(!)0!<`(`#>0<`*((`_ +M@`"4EB`0`#%`)!DT0L#/<(``Y!Q#P+8(8!0K<5IV"/":":`!BG`!WD`B4B## +M"A4AA"H6*<]P@`",:S`@0`YVZ$`JC2"T?<=U@`"4H`B5A.@)E6SH2B9`(`HC +M@"^``$PR`!N`)2\AAR3/<(``'%<8&(($%@P@`"IPA@Y@#"IP)@F@`9IP`-Z= +M#E61`-\(E0\GCQ,+?THE`"`$]`F5"W\E\N8-8`PJ<('@2B!`(,(@`20`V*H, +M8!<(<21X"+4)E01Y*;44'8(5$]AZ +M#&`7`-D`&T`E`>;-\0'`SW6``-2D0!\`(`Z%G0@0``#?[J7/=H``]*2:"*`! +M'(Z>#6`,'(Y*(D`@&G`4V#X,8!?I<4(5@!!!%8(0"+@%>D,5@!`]%8,0$+@% +M>D05@!`8N`5Z/A6`$`BX!7L_%8`0$+@%>T`5@!`8N`5["G#&"J_V/(X:@IP8'I*<2H(H`$< +MCDIV`\$K<"X/(!2*(@8,`L`@&`0PM@I@!@/8!^[/<8``-*L;B0'@&ZG)XJ`#8)@M@%PAQSW"``.0<.G"+=^EQA@X@ +M%(HB!@PN#6`,2B)`(-(,8`R:<('@PB*!)+8([_]2(@`@"B``H#WR`-A2(@$@ +MJ7(!VYX/;_8*)$`%-NA6)($]0@\@#(IPA"T;$#(D@3\``+`!`"&`?T4`0`<@ +MH!(/(`P*<`S:$FT4>``@@0^``*2@;@Q@#$"QY@DO]0/8!^@N"F`&`]B""Z__ +M`]B""Z_VJ7#/<8``-*L;B0'@&ZD$\&X+K_:I<.EP*G':#2`4BB(&#"`>Q!03 +MV%X*8!<`V>T`[_2`)`8]\<">",_T6G`H=1IRSW>``-Q6Z7`*#:_Y7-D*(8`O +M@``P("IP^@RO^8HA%P6CIU@?`A0!W;2G2G"I<0X.K_\"V@#>:@X@#,EP"B*` +M+X``4"%`(@`C'ME""F_ZR7*PIT`B`2.`X#.GR7`+\E8A022&#R_Z"G*`X,H@ +M@0/*($(#@0#/].!XSW"``(RK:09@#`"(\<`.",_T&G``WLEU!/"`O@'EL'W- +M#1,1KWA*#F`,6G!XZ(0M%AD`(8]_@`!4:,T7`!8*(4`N[NBR"F`,2G"!X`'8 +M.@^O_\!X9.C.%P`68N@`(9$O@`#4:G@1`B!:ZI)ME'P`)(\?@`"4H`F7SW&` +M`%2@5B'#`LWH#PK1`("^`=IX&8`@*O#/<*```"`;@()CQW(Q`0`M0G@9"%(` +M"8&*Z#H(H`)*<`;H`MEX&4`@LO$5%\`0`B``!"\@"0!5"%2**@I@#$IP@>`! +MV,(@`0!2(`"`H/4)EX"^12!``PFWFO&-!Z_TR7#@>`#;`[@4>,=P@`#4I'.@ +M`MI4H`/9-:!VH%>@X'\XH.!X\<#AQ<]P@`",JP"(A"@6"<]P@``,;(8*8`PP +M($T.%7TXE1*5"KG)N`0A@0\/``#\)7C/<:<``$@5H5F5$YT)NLBX!"*"#P,` +M`/Y%>`RA00>/].!X\<"AP8MP0@ZO_T`D@3``%$`Q$@@@``(403&AP-'`X'[Q +MP)X.C_0(=S8*8`PH=IX(0`$6"F`,"'45?2:%`-CY82YYJ85N"B_XZ7+992YY +M`=AB"B_XR7+/<8``=*L1B0'@R0:O]!&IX'CQP)X(0`#/<8``=*L#B0'@`ZG1 +MP.!^X'CQP#X.C_0H=L]P@`",JZ()8`S@B`AU?@L@`.EP`=D[H`\-41#;YMR@ +MP_<`V3N@N@O@!BAP=0:/]/'``@Z/]`AU*';/<(``C*O@B#X,8`SI<`H@@"]% +M`(`;+>@Z"R``Z7``V26@SW&``$BZ)HD.$`,A"PD>`'!URB-%`PT)7@!P=LHC +MA0,^D$`@`@A3(4T`0"`,#IUE8*T!X7B*/K!QJ@'8!_`)9`D+0P`QJBAS`>#W +M"!2!\06/].!X\<#AQ<]P@`",JZ"(P@M@#*EP!^C&"B``J7`!V26@Y06/].!X +M\#8_T"'4H=AIRSW"``(RKX(B6"V`,Z7`SZ)H*(`#I<,]Q@`!(NB:)`-H/ +M"1X`@.7*(DT#RB(N``T)7@!0=LHBC0,-"9X`#""`H,HB#00_D$`@#`A3(4T` +M0"`##7UE0*T!X52,/[!3K`'8!_`)8PD*0P`SK"AR`>#W"!2!206/].!X\<#> +M#(_T"'4%@,]W10"`&T`E#A@(Z$O8$*ZI<,H((```V0KP$8X(X!"N,(X'EPD( +M0P`0KB"-$(X'"0,``*WN""``J7`$Z`N%`>`#\`#8"Z4IA02/+'@GA4$IP'$P +M<&\@"P"`X*EP"O)^""```=D`V`JE$XX2KC;PL@@``"J%@.#,(2*`)?(3CE*. +M`N`)"(4`!84&Z`N%E.``V,/W`=@9Z""-!Y`+P+W@`K2>7"PA" +M`(H@R@\`IQZ%`>`>I0'8"J4`V`NE"O"`X4$IP7$0<0'8 +MX'_"(`X``=C/<:```"`"H?`9``!`V.@9``#@?N!X\<"&"X_TSW"``(RKR@@@ +M``"(-@\@#`AUSW"``%18`8`!WNRXJ7`%]`X.```)\`(-S__$I0#8$*6R#^__ +M%:6Y`X_TX'CQP#8+K_0`V>'!SW"``(RKX(@Z<>EP`=V*""``J7&2#@`,&G!N +M""``Z7#:#B`,"'8&IKNF.0A1(&P>0!3&"V_^Z7",(,./RB=!%`7RE@E/_@AW +MBW%Z#:`*"-@*Z`#!`-@/($``Y'@)#P$0NZ8M`Z_TH<#@>/'`S@J/]!H((``( +M=@AU"@D@`,EQ`-@I`Z_T!*6$*!8)`"&`?X``D&O@?N!X\<":"H_T*'?J#^__ +M`-V`YPAVRB!"(P7TH8X"%I`0R7#R#F_Y?-E?V2"NF-@"MG/:1+:TV`:V@-@' +MMD.V6M@%M@7O8=@!KF38`_"AK@IP`JX`V@?P0"8`'5A@(*@!XOD*%(&A`H_T +MX'CQP.'%`-T'\*EPD@_O_P'9`>7Y#121G0*/].!X\<#AQ<]P@`",JZ"(5@A@ +M#*EP".A:#^__J7`X@`'A.*!U`H_T\<#AQ<]P@`",JZ"(,@A@#*EP".@V#^__ +MJ7`Y@`'A.:!1`H_T\<#/<(``5%@!@`\('@.2#\__*@[/_]'`X'[@>/'`M@F/ +M]`AWSW6@```@VX4$@(#@S"'B@"WR[!4!$%"'#0FD`#6G`B&```?P#B*`#___ +M__\X8#$.!7```*`/V@H@`.EPK@@@`.EP!H>.X(P,[O_*(,X#SW&``%2K!(D! +MX`2I!O",(?^/M`W!_YH-X!;I`$`'@ +M,A\"$"$!C_3@>,]T10"`&VF`)8Q(@&QY02G!<5!Q;R$+`(#A'``"`">,;'E! +M*<%Q,')O(0L`@.&<``(`X'XBD,]R10"`&VF2`>$'"<4`,'LCD&*PC9(!X0D) +M!0,P?(.P*9(+"T(`BB$+`""B))!KD@'A!PG%`#![)9!DL(^2`>$)"04#,'R% +ML"N2"PM"`(HABP`@HB:0<9(!X0<)Q0`P>V:P,9(-"T(`BB$+`2"B)Y!SD@'A +M"0G%`#![9[`SD@L+0@"*(8L!(*(]@&&YX'\]H.!X(I#/R60 +M9+".DF&Y"0Q%$#!\A;`JD@L)P@"*(0V>P,I(+"<(`BB'+`2"B/8`!X>!_/:#@>/'` +MX<7/<(``C*N@B*8-(`RI<`CHJ@SO_ZEP-H`!X3:@Q0=/]/'`X<7/<(``C*N@ +MB((-(`RI<`CHA@SO_ZEP-X`!X3>@H0=/]/'`X<6#X`'=PB5!$UX-(`P/>(#@ +M`-B)!V_TRB!"`^!X\<`&#T_T4@SO_PAVSW5%`(`;/@WO_\EQ,!6`$`'@60=O +M]#`=`A#@>/'`W@Y/],]P@`",JZ"(%@T@#*EP"^@:#.__J7`(=@H-[_^I<6(( +M[__)<(H(``96#^`%#-@9!T_T\<"B#D_TI<$(=PHD@`]%`(`;5B`.`E4@306+ +M1P?0!ZQ!F_TI<#@>.'%@(%@@'!TPB3&$$;W#B.- +M#_____^\9("B@8&A@`T,1!,")$,3!_`.)8,?_____YMC8:*"@:*`"PQ$$P(D +M0Q,&\`XE@Q______FV-BHF.!HX"Q<\(C1@-&]PXEC!______FV-CHB2!9(!P +M<<(AQ@!&]PXC@`______&6$DHN!_P<7@>/'`O@U/]`AUO@Y@"0W8"'9>""`` +MJ7""E425SW.D`(!$-(.*(#@`!'F%>32C-8,$>45Y-:,CE5:#A94$>D5Y-J,W +M@P1Y)7R7HR:56(.'E01Z17DXHSF#)'B%>!FC6@Y@" +M2@_@"P\F3A/$>.\.`9`>"2``J7`Z":_T!M@`WM$.TY#/T"+J7#I +M<78)(`!ABP'FT'[R\24%3_3@>)O@X2#,!\H@+`#"X.$@S`?*(&P`YN#A(,P' +MRB"L`(P@@H+A(,P'RB#L`(P@@HGA(,P'!-@%V.!^\<;#U41"-A""Z`&`=EXZ,]PIP!L +M1`"`"?#/<```I"@(V0H.K_0%VDIP`*;/<*<`<$0@@``80"``AAK9?@A@$\ER +M`!``(!K9<@A@$PIR+01/].!XX'[@>.!^X'CQP,H+3_2^P0AWBW8:"B`!R7!# +MQP'=`-@/(,`#1,`&V$[``-A-P`+9A.]%P4;`!/!&P47`2<57P%K`6,!0V%G` +M3,55Q;X.X`#)<)X+H`X!V,]PIP``1+"@W0-O]+[`X'C/<8``E*HPF2)X+R`) +M`)G@`=C@?\(@!0#QP"H+3_0(=NP<2+#ZB8)(`]`H8/'0"00-,EP(-D`VNESE@[O_PHD``0# +MP,]U@0#X&P"E!,"*(3\(!*7)<`#:Z7-V#N__"B0`!`/`(-D!I03``MH%I#N__"B0`!`/`BB$_"`*E!,`"V@:ER7#I4)Y/V<")`$` +M`B%!`3UE0B_4%^EPBG'IER+@UO](IS.W!!P4(JUB=*<,IQJ7(:#6_TJG,!P@`@ +M0(8!(8$`*@UO]`7:0L`[<4IPRG'I,=V@`"4JAYF4;9*<*EQ*G(R"V_T"G-.(`(`5[;%`6_TI<#QP&8/S_Y& +M"N`%!]C/<8``-*L?B0'@'ZG1P.!^\<`(!*)T`@D@O@"\(GP24O(@<@3@^@"ZEP&W!6)!0X5B2`(JEQR7+:"R`` +M"G-`)!4QS0G1(`#=`_`!Y8+E+@,&``#>#R9.$PLF@)3X\RX+X`OJ<,1X(PX! +M$(0M01//<8``OI_(W"]P1"C^,B=P"&$.(`$#+GD0\!(,X`LJ<"8,;_:I<40O +MOB7/<40`B-HS(4$.-'@.>0#8I0@"H(HD%AE8VU)HM'J""=T`"0#$8(C!`FT>\"S=!)#`0DC0P#'=(``5&>T?!L( +MLP!BM%`20P$)(T,`7!)"`7:T"2)"`%BT`>`/>,_Q2B8`(`/P0"96($PF@*!B +M`@8`>@O@"RIPC@MO]LIQ:.`O(P8@6@K@"^IP`-H/(H(%1'@0<@'9P'E`P1!R +M`=G"(4$``=@4(%D`2B(`(`[PA"^!$``A@']$`#S9`"%!=?H,H!-"VD`B4B!, +M(L"@(`$&`$`IP"!`+H$@%'@T>3A@%2"`!,]Q@``@I0=A`,"`X,HF@A\``,@` +M"/0J<.EQ:@XO_\IR"':Y#H`?__\`@`#=!/`!Y:]]L0A"HU8D`"0+<>ERJ7,* +M)(`%8@HO]@`4!3``VB#PA"^!$``F@24U>5EA+W!$+;X5)W`980`D@""B<8`0 +M@`#X"I@N?,)^*0!_0O(,$$"2#```"I`>+#"I2"`-K.ZD`D@#)8 +M8#(@@`\``(`!W'F$+X$00"8,)1QX7&0O2UX@N6O?>WQ2B2```/P0B1$`)\,$`!`*<`@%'A`+H$@ +M-'D984`L@``5(0,!SW*``""E9&)DN#A@`V(`V0/P`>$O><\(0J``WACP0M_L +M?``FC26U?=UE+W)$*;X%+W#L>QIBNF(S)8(@)W"X8',@304'#8,00*@!YM,. +ME)(`WN'N0M_L?$`F`B7:8B]U1"F^!2]P['L=95UE)W!88#,E0B-S($T%!PV# +M$$"H`>;I\0#=,W72!<;_0"G`(!1X0"Z!(#1Y&6&U><]P@``@I2!@"G%6)((B +M*G,*)(`%"B5`!<8((```%`8P`>7D\?$%+_2`)`8SX'C@?N!XSW"``)0>((#/ +M<(``E);@?S"PX'@`V<]P@`#D'2:@X'\GH.!XSW2``.0D).0U?&"D`-G/<(``E)8PL,'&X'_!Q>!X\-O>Q)S2`$)``#8#R!``P0@ +MBX58\@#95/!$*[X%`"9``(HG!`**)0$&+W2:8`$2S@"88`L0P@"$*8$@N&45 +M>#A@)W2*)!8)'&0S)0PCTWX4)@`3NWXU)(\S"B"`'X``%&?B>%-ZE'KB>B\A +MAA`5)L(00G*,F@YX"20,$`0L_B$U?B]P!"M^`4`IA0`G<`0K/B$`((<#`"<. +M`ASF)W:`ME*:"B1`#@DB0@)`)0P*M'R88`%P'."`<$"P`>$P>5T)DH(_"Y.` +M.PL0D`#<-PQ3D(0I@2"9913ANW\O<$0KO@4G<#A@,R4`($XB`1`4>34DP#// +M14GSA``(H`C`)@N>0DA!P"$+`0BE7\O<(0K`08`(01PA"L6*8!W +M7V/'`)@@@ +M``AQA"@!#`2Y-'D`(8!_@`#D'`C@-2!``-'`X'[@>,]P@`"4EA"0ANC/<(`` +M9!X=B`/P`-C@?O'`X<4(7*(&(` +M@.#*(((/``"L&6`,8O3*(<(`T0(O]*EP`=C?\>'%X<:$*18)SW:``.0=D)[/ +M=8$`6$4O<80J`0;1GH"U)W''<8``5&AU><&U$.A:F1N9"2("`T*U"2"``YX1 +M0@<#M2\*(P.?$4`'$O#D$4"!YA%"@0D@``,"M0DB@@-#M>P10@$+"B,#[A%` +M`4ATA+4))@X0Q;7!QN!_P<7QP,]P@`!46`"`%0@>`<]P@`!4E0^`@."T"T'V +M2@J`"*8*0`#1P.!^\<"J"0_TSW"``%18`(!3"!X!SW"``(RK_@R@"\"(@>`! +MW<(E01-"#6_VJ7"6#6_VJ7#"#V_VR7#B#^_U`-AR#6_VJ7"B"(_VC@N/]K(- +M;_;)<,]Q@`!4JQN)`>`;J;T!#_3@>/'`,@D/]'IQA"@6"<]P@`!`:R]UA@N@ +M"S(@4@,O(`<@`-\M\`#>#R;.$PLF`)0F\D0O/A\`)8`?@`"T9@;@,B!`#@HA +M0"X:Z#8+H`MJ<,1X$'8`)8`?@`"49H0O!A8DX#4@0@0!V18A@'3`><=P@`"4 +MCSC@-'A`L`'GK0^4D!$!#_3@>,]Q@``TE11Y`!F$#P``_W_@?N!X\<".""_T +M`=DZ<,]P@`!46$"`Y+K/<(``E);P!"$`$)"`X.@$`@`$$0$@"B:`+X``9!X$ +M(8(/````&`0A@`\``P``*[HXN`4@D``$(8(/````0$(B%(`$(8$/````@,HD +M8B!"(16`BB`(`,HE8B#/"P00H%`L2X00H%!L5J80K%;F$.QGA!" +M!Y\00`=$L06Q%/!'APWJ4)_/<($`6$4QGT"P(;!"L".P1+`EL`;P)'C)<5(- +M[_\*FJZ6V//=X``Y!U&AZ+JA"X6&<]Q@0!812]PA"@!)B=P +MQW"``%1H=7AN$$*'0+%O$$*'0;'D$$*!0K'F$$*!0['L$$(![A!``42Q!;$5 +M\$>'#NI0G\]P@0!813&?0+`AL$*P([!$L"6P!_`D>,EQI@SO_PIR_!,`(`"G +M!(<%IQ38]!L$(`2W!!$`("ZXPK@R(@`@@N`8V,!X6G!&$P`FG0@1`,]R@0!8 +M10P60R$!FB":`B#$``*:8GD"(,4``YJ$FF)XY9IB?`(GQQ`4$4,A66R\"8`)!813"%@F`DC`P,"(X,$"2.``0"R"2,``0&R"2-``0*R"2-``@.R +M"2,``@2R"2-!`"6R(0P0(/`3`""I<8#@R7``V@;RQ@T/]@/8&J4$\+X.#_8A +M#1`@01,`)JEQ@.#)<`':!O*F#0_V`]@;I03PG@X/]EJ%SW>``'@+((<;A00A +M@0__S_^?#;H$(H(/````8!RX!""`#P`P``!%>"5X`*<&A4H-8`XRA2F%`8=5 +MA00@@`_'_\?_`[D3ND5Y)7@!IRB%`(=4A<]S@``X\/0C00`$((`/\__G__0C +M@@`#N1*Z17DE>`"G6!4!$125"+DE>!P9`"!`)0(2"8*!X)_RA"X;$$`2!0"K +MVR]W!"W^```G@1]%`$`'QW=%`.`)!N$2YP2"`"=('FQXSW"``$AK)W&$+A89 +M,B!##@#<>0P0(`2"1"O^`L]T@`!P5`2XX(05>!]G,R=`'@HD0`Z`FD`@1@+; +M;`@F#A`O)X8#"2;.`0)^SGCX8`'@,R`.`0&)@G@>9A6:BB0_%-A@""`,`WG8 +M"20,$,]P@`#D5/0@#`,'B8QX0BG`!YF+W!6)H$<,R$!`/B:0"%$`GMO""-#`"\EQ@`))$,! +M(GMN>=EA@"%&!#,A`0`!$(`0XG@985H20`$X8(HA/P0(($$`>=@)(0$`SW"` +M`.14]"!!``<0@!`L>$(IP'(0>(HAQP\)($$`,'A8&D0`!/"4DE@2``$)N`5\ +M(!D`(Q*%SW&``#@J9H7P(0``SW*``&P,\"'!``*X)7@$HB2=')T(($``0G`. +M>$`@P8'/0!0[ED$L``+GDX8,]Q@`!D5""!"6$7H@&"@>"*\L]R +MH`"`'1J"$[D$((`/!____R5X&J)^\,]U@`#D'%8E#A*-Z`+8!J42I2BE-*4V +MV!2U#+8`V!BU$+8&A18+8`XRA<]P@`!X"TF%(8!UA00A@0_'_\?_`[H3NV5Z +M17DAH$B%((!TA<]T@``X\/0D@A`$(8$/\__G__0DPQ`#NA*[97I%>2"@3)8T +ME0BZ17D<&4`@4)8XE0FZR+D$(H(/`P``_D5Y(!E`(%*%SW:``#@J9H7P)HP0 +MSW&``&P,\";.$`*\Q7R$H?`5`1`'Z1`8@`_+\Y@9"O#/<8``M+@)"Y$`(($# +M\"&!)*!!%0$6!ND4&(`/R_.8&0OPSW&``+2X"PJ1`""!`O`A@26@!@C@%@/8 +MW0+O\ZEPX'CQP,]S@`!D'B6#SW*``.00`>$EHR""$PG5`0\(50$!X2"BT<#@ +M?@#8`*((@Q+HSW"``'@+!X".Z/H*(`X!V,]P@`!46`"`#0@>`>((#_;K\>GQ +MX'CQP,]P@`!46`&`*0@>`<]P@`",JP"(C"##CX`(0O;:"F`%!-C/<8``-*L< +MB0'@'*G1P.!^\<`6"L_S7@U@"PAU&G`Z#6`+J7`(=]8,8`NI<('@`=[")H$3 +MJ7":#2_VR7$:#:_UJ7#""4_VZ@Q@"ZEP"'+I<`IQJ7-Z"*__2B0``.X/(`OI +M<`ARJ7`."F_VR7$B#&_VJ7`"#6`+J7!:#H`6A"T6&0`A@7^``$!K!0+O\P"A +MX'CQP,]S@`#D'39[&+/V#V`+2Z.`X,0(0O;1P.!^R\G/<8``],D0B`.X%7C@ +M?S4A``#QP%X)S_.MP0AU&G$*(H`O@`",JP`2CB":#V`+R7"E"!``T@Q`"\]W +M@`#D'#IP#P@1(`#8QQ\<$$3PQQ]<$P#;`O`!XS$+E0``V?L)DX5$*[X%SW)$ +M`#S9LWP`(4!P,R("``'A5'P`(((/1`!$VH"J+WGM\002`"`V"F`+`H"R#&`+ +M6G`(/'`I@C/\PAVSW6``'@+`(7/<8`` +M./!"D00@@`_S_^?_,VH2ND5Y)7@`I0#8#@A@#@AQ`-@.":`.`MD!V`8)H`X" +MV0&%!""`#\?_Q_^$N)2X`:7/<(``&-[P((`##WD/>`BY!"&!#P```/\E>,]Q +MIP``2`NAH0#/\_'`*@CO\Q3:SW&``%B@,@T@$P#=*/"$+0$3+W``(((/10!< +M+7R*SW%%`#PM&NM=BCA@1"H^!PC@-@E@"S`@0`X(=S(+8`NI<`AVY@I@"ZEP +M"'+I<,EQJ7-V#F__2B0```'EKWVS#1*1+0#/\_'`N@^/\PAV&G$`V<]P@`", +MJ^SFX(C*(6D`!/;GYD;VSW"``-24-Z"$+Q89`"&-?X``U&HJ#"_V&87.#6`+ +MZ7`=Z$X*8`OI<('@`=AZ"R_VPB`!`!F%PG@O(@D`&H4"(``$+R$)`,]P@`#$ +M'0F($'+,(8N/``#T`4/V`-@"\`'8H0>/\_'`/@^/\PAV`-T+\'8-8`NO>(#@ +MB`EB]LH@0@,!Y?$-%)$`A@X((`#!N(4'C_/@>/'`SW&``&0>*X&*Z>8(0`C/ +M<8``5)7N"^`%$:'1P.!^\<#J#H_SUPB5`P\(M`!*:`D(]`(!VP#;'6$`%``!237F>`KEQA)A3,$$`A!`B* +MKA0DC``0%,X05'_4KQ$4S!"5K^@5SQ#/=(``5)0>9(P>PI/V%PI,2ZP`EA!`2%,6`7&2V'$*1'!3/@%UEP!S"DR85S9#* +M'$*3M!#,@(`A!P!8'@(3PA#,@(#CSW"``+249AX"$[KR6V$0$\,`6&!TJ%EA +M&A'!`#ZHL/!"(((##PKU"%U^`=@)"AX``-CX/ZH&Q/#`'^H*.PH<(`@@@`P0 +MPP#/=X``M).T?W"O#1#``!&O*'"`(`@`0"`$!T`@A@);8#`3R(``)84`U!T" +M@E83PH#Z'8*`'P\0`-I@?!+(@``F@A^``'24V&``&@("CA#`@!*J$>Q6(0(- +MN&(`$,@``"6/'X``E)0$'P(2NF(*$L``#J_D$\"`B!T"`!4/$``S)H(#`":` +M'X```I5`J`CL,R1"`P`E@!^``!250*@*[(`A@P0!ZJ":`%C+D`I@&&`-F>":`%C+GU`Z_S`:;@>/'`F@N/\SIP +M*'8@@`"&2'<%*'X``-V,O2]P=@F@!:EQHGAN":`%!-FX8`"G!!$!(`&&"B"` +M+T0`\)(X8!QX`:<`$``@*@AO]AMX`!`!(%IP.WDO($D`C"`%BLH@30#*(8T/ +M``!H`4@,C?-:W`((;_8.(0`#&G`$$0`@(88B>"\C`2``$0`@#+@&":`%((:B +M>,X)K_<$V00HO@0(=@#9+W#J":_WC+D$*SXD'64`V2]PV@FO]XRY!"N^)`)] +M`-FBIR]PR@FO]XRY!"X^%`AU`-DO<+H)K_>,N;A@'0.O\P.G\<"V"H_SHL%Z +M<"AWBW`R#V_X"-D`AT(HP0<(:<4(HP0<(/'`^@FO\R#9LL%:<(K`;@YO^!IPBW7/<(``5!&I/'` +M<@X@``#8BB$/",]PK0"`HB&@SW"M`("L,:"*(0L`SW"M`(!B(:#/<*T`@&PQ +MH,]PK0"`'G`8@`^*HI@9SW"M```I,!B`#XJBF!D2"```(@X@``'8T<#@?N!X +MH0$``/'`O@BO\QS9M<%*(@`@BW`R#6_X&G`$V&;``=@9'`(P`M@:'`(PSW"` +M`%2"7I@*(X`O@`#4IA`;A"`&\)8.(`!`(E(@T0I5(<]Q@`"<\C(A@`1J#B`` +M8\"&"N_[`-\#\`'GW0_UD"/`@@X@`.EQSW"``)CB\"#``T''0,#/<(``3-_P +M(,`#3B>1$$3``-W5#960`"%!)+AE1"H^+S1Y%G@986)Q`"%"#HN:\=S +M@``4,DJ2@J,G<2F10:,@HU)M`<%4>C5Z8G(`(D$./)DG6_\04`K_.UP.!X\<"&#L__5@@@!1G8SW&``%2K$8D!X!&IT<#@ +M?L]Q@`!4J'D1`0;/1$`!A#HSW6``&PR`(45"%$`2!%`A\;@ +M!O9V#`_V`-@`I3H.S_]]!T_S_N``V/'`:@H`"\H/S__/<8``C*L@B80I +M%@D`(8%_@``,;)X/K_X`H='`X'[QP*8.3_,(=6AV`H%:#R`.2''/<(``>`L@ +M@*W8$+@AH`'9SW"G``!$,*`\V)H-H`4`V8;M@@B@!<]RIP``2#6BD)#/<0,``/YC +M@`F\R+LD?(5[;*)@@(J0R+L)O"1\A7M]HF*`CI#(NPF\)'R%>V:B88`,D,B[ +M";@D>&5X!Z+@?N!X_N``V10!%CKI"B>`#X``;#(`%P$` +M,>FY95IB-'E6>EEA.&`;8PJ39@HO]B*7F'`*DX!P"K,+FW8*+_8DG[AP"YN@ +M<`NS"9-&"B_V()<(<@F30"[!`%A@";,5)D`3-'G'<(``%*HHX#A@B'$2"B_V +MJ',`V``?```/\%IBO656>K1]NF)88"&'&V,JLP"'";,"APNS/05/\^!X\<#" +M#$_SX@D@``AUSW>G``!``8>`N`&GM@H@#@V%,X5*($`@"NG4A0#89@T@#LEQ +M`=A>#2`.R7$.A<]QK0``@V`9@`\```@(4V@+N`5ZSW"M``!#6*!/A8HC1`!X +MH4`J`P)E>EB@<85@&8`/```0$%1K#+ME>EB@084;ZG*%8!F`#P``8&!5:PV[ +M97I8H%"%BB.8`7BASW&``"3H]"&"`%MY";I%>3B@0@J@!1"%`(44Z,]P@`!X +M"R"`0H7/2"@)X6+Z6.%`-H"V(7K +M!:5&I0/P!J5%I1D)D``%A3(*(`XFA06%)H5>"R`.2(4CA<]VIP``1!2&"B&` +M+Z<``$BVN+>X%KD%>32F%(8DA;BXN;BZN!BY)7@4II(/X`T!V!:%#.@7A0]Y +M#W@(N00A@0\```#_)7@L&0`@&!\`%!J%5(8O(0D`@.#0(FD%SR)L!00B@@_@ +M_P$.4R$#`@R[+WD[>25[97I4IJX+0`42ABR%1B"``3MY)7@2IF`5`!'>":`% +M9!4!$2N%%(9*A00@@`____[Q";E%>25X%*8RAA6%H+DE>!*F`X4`V0\A`0#/ +M<*4``!`AH!N%/8525X/'`X<4`W<]PH```$*F@ +MA@F`#<]PI```1*F@L:``V&X+;_V.N#T#3_/QP.'%SW6``&@HG>@N#V`%`-C2 +M"N`-`-C/<8``;"A`@0"%@.+/("(!T"`A`0"ESW"@`(!%,!B`#P`@``$!V`"A +M*O#Z#F`%`=B:"N`-`=@@A54)'P'/<*````@"@`#:SW"@`(!%3:#/<*```!\< +M@"D('P`E"1X`#'`="!\#SW"@`(!%,!B`#P`@````V<]P@`!L*""@:B"``<]Q +M@`!P*&H@@`$`H94"3_/QP([@RB&.#P``_P!<#2[]RB`N`-'`X'[QP([@RB&. +M#P``_P#D#"[]RB`N`-'`X'[QP`#;SW*@```0::*.X`':PB*-`/P,]P@`!4@*H0@`"5Z,]Q@`#4@%*1%)DSD1IB.&#/<:(`@&U(H0FA +MSW&``%2K%XD!X!>IX'[/<(``](`*B`KHSW&``%18`(&@N`"A`8&@N`&AL0?/ +M__'`SW"``%2"/!#``,]R@`!4@!QYSW.```J!,R-!``'@''@S(P,`.V-\>Z@2 +M0`%M>P(C`0`O(4D`22',`!!S`=O"(\P`BB'_#W1Y!2D^`R=P7@_O_Z@:!`#/ +M<8``-*L8B0'@&*F&">`$`-C1P.!^X'CQP&X.3_FF#F_YNMBR#D_YSW"``+"X +M`(`8Z"8)``H$V<]PH```1R6@G@Y`!N.XBB#_#P+9RB%A`$(+H`P`VH'@Y`TB +M%LH@H@+1P.!^SW*``+"X(((&>>!_(*+@>,]R@`"PN""")7C@?P"BX'CQP+(( +M(`L0V'(/P`K1P.!^0B``#.!_#WCQP$8(3_,(=RAV2'6$*`D/`"&1?X``(#L( +M$1`@A>#,)B61RB"&#P``*C3*(<8#)`JF\\HBA@,]#5`0>0W1$,]U@`#\3=9] +M3"!`H`,]V@`"` +M5""&!9'FX);V`Y$C&4(#!+&I=P;P0@W@"V#8'0A0`(KO0(8CD@62.&`DDH(@ +M@0GG"$6`N0!S5^,!8$$,]PQ>Z%\F:&`=D$VF8(H!5*)4```-B2#._U((6%!0_S\<`2 +M#2_S"'%(=@#=`O`!Y1,-E1'/<($`Z!SP($`#\PD!@(;ERB"&#P``$2O<#D;S +M@>8!V,(@`0`!X$X,[_6I<4$%#_/QP.8,S_7/<0$`B)S/<@$`()S/! +MX!P$`G`1)"":`2 +M!MJ#P$`G`10V":`2!MH/V`:G%=@'IT38"Z<0V<]P@`"@/)8@A0$@H``0`"#P +M)@$0+WCR#J`*`1Q",&#``-@"'`(P`QP",`#!"]@""Z_[_]H."._["]CJR24( +M'@?/<($`T!SP($,#SW#%[H7R`=D`V@HD0`3Z#F`5"B6`!`$$+_.EP.!X\<"J +M"R_S#W@H=<]QH```(-N!/@@`%L]Q@`!$'_`A```%Z`)^"0VE$P'8`-CM`P_S +M\R"#>>D")4P0SW"3U@"DXPP%D#A@`B!!`S!V +MRB9-$,HG#1#I\88+S_6,)O^?%_+/G/ +M<8```#T)8<8,H`"I<)4!#_/@>/'`%@D/\PAV*'>$*`D/`"&-?X``(#T`(8%_ +M@``@.P"!/8%Q%8,00"F0`L]Q@`!P)T"!((I3"T,`)Y/[E2(0&``_("=^*@.H4$OB:@%-DCH""`UGX`)H`? +M@`#<1R"@X@TO_`#8)@LO_`S8`-CU`"_S>!T"$/'`8@@/\SIP*'5(=MIS"B<` +M(80H"0\`(9-_@``@.W03&"``$Q`@?!,9(`2X%G@`((\/@`"\1PIP:'$."V_[ +M`-I:<`"`0"B5,@"G!!^`%0IP$MG:!($/)DX3QG@$H1>/@.#*($$# +M,`^A]O3@M@"`+8X@L@"`+Z```"!-'YBO````$``AC2^``"`\%(5*(@`@!^CTR1`@@`/T +M&ABPB?`&#R`$R7`@Z!*%;Q0/)@9_\\EU')@D$""``_,:&+`1\"\IP0-.(8`' +M+R8'(!&%$">/%1`@@`41I]('8`4;@X@!,EP`,)`($$QR7"! +MQQ(+(`;I<\EP@@[O]>EQN@G@",EP%&X6>,]Q@`"\1P!A%>A^#`_\;!\7#1`@"G`J""```-D-\-(-(`3)<`GP;Q0`)N8*(!4? +MV8(-(`3)F#>`%`-D(=1GO9P^1$(0M"1_/<(`` +M;#PP($`.#PB/`^8((!7)<`GHSW(!`%2EJ7`*"N``R7$=\*EPR7'2#2``(-H` +MV`\@@`.""B`5']F$+0D?`"&`?X``(#PQ@!`A@8,QH`?T"@T@!*EP_@\@%ZEP +MS0//\N!X\"L_RI,$(=80H"0\O=@`FDQ^``"`[T@S@"&03%"`Z<,]P +M@```/3(@D@-."Z``2G!`P&X-X!*I@@_@$T`F`!@R"R`$J7`%\`(+(`2I<(D![_*DP/'` +M/@G/\@AU*'<`V0X+X`4:<0AVSW&``/0\A"@)#R]P`6$,[U\/D1#/<@$`Z*?) +M)Z'8.H`C)<%`?`!1Z"B`$R7`A`<_RX'CQ +MP+8(S_((=80H"0\`(8!_@``@.P`AD'^``"`\2!`"(&\0#@9&?DHA`"!U&%@$ +M20F0`*WN(/`O*($#3B"/!T00`"#O?Q`@P0-$&$`@SW&``*S3`($+#0$0"(D9 +M#P`0J7#I<9H*(``(VJEP=@I@`.EQ$";.$^'N2!A`)%`80"3B#:`(J7!V"B`$ +MJ7"1`,_RX'CQP!H(S_*BP6AWB'6$+0D?+W``(),/@``@.S1M%B%2`$""((,* +M)(`O@`"@1S!R`!,0(%4DT22.\@`@C@^``*`\T0D0`,]Q@```/0EA@@M@`*EP +M"!,`(!$(40%H'H`?````$`7PBB`0`!JFEM@;I@2'0"00*0/H!H>%Z*H)+_.* +M((0&!H#*`(J7`G\`#?^J;[IIX,K_^I<*EP]@@@">EQ9@UO^ZEPR@X@`*EP"G#_ +MV68*+_SIO\J+`X'CQP+(.C_((=BAW2'4"""_\6G,:A0`)@HC0"X")0$0`>?Q<0#8RB!O`(#@RB'!`P`CCR^``"`\6!^`%#6G +M(PH0(#$($"`M"1$@A"X"&@`A@'^``.!*B@S@$SC@"O"$+@(:`"&`?X``X$HB +M#.`3..!,(0"@S"`BH!+R&PH0(,]PH```(!N``B4!$'H4`"81"$4``-@4IY8) +M(`G)<%8-3_PCZ,]Q@``#/3(AP`2,(,./&_+/<*```"`[@`(E0!`E#@-P```` +M0(0N`AH`(8!_@`#@2@(E@1\```!`!@S@$QS@-@^O]Z#F@'9\@@@%85ZT<#@?N!X\<"6#8_R6G"7:)1\`"2. +M'X``'*Q`(!C`^@!W5R& +M2G`F>ERFB@Q@%4AQ'(:&(#\-%>\1"!`@ANB`Y10,H@#*((($'(:`X`'8P'@/ +M"1$@@."H"6((RB""!($%C_+@>`"!SW&@```@.X$"N!9XQW"``$C[(J`!V>!_ +M(:#QP/X,C_+`@:2)R7`2#F``J7$:<,]P@`"8K/=N]'\P(-(#SW"@```@;!`1 +M`'H.H`7)<#7H3"``H,PB(:`O\B,*$"#'=X``G*P:EPL(7@(PAP+P+H3%B&0E>`,]QH```(#N!EB$&`$(-(``)V@3PL@D``-'`X'[QP.'%H($N +M#>``!(G/<*```"`[@*EPEB$&`!H-(``+VHT$C_+QP.'%H($7;11X`"""#X`` +M-*P(@HKHSW"@```@>X`'@F)X2"````BBY@S@``2)6@D@`*EP502/\O'`X<4H +M=<]Q`0!,=P@`"```=NE`X_R\<#AQ:"!%VT4>``@@@^``#2LSW"@```@>X`'@F)X2"`` +M``BBSW(!`-BZ!(E(<1#:B@W@``#;@@@@`*EP?0./\O'`_@J/\@AU*'>(ZL]P +M@``$)O`@00,'\,]P@``D)O`@@0"I<*8+(``'V@#>">@!WA=M%'@`(($/@`#\ +MK,"A,V\V><=Q@`"@""^`(J7"`X*`- +MX0#*(,$#_0*O\LEP\<#AQ0>X%'@`((T/@`"7,)>*1F/07;A0@$0``(8TO@`"`BE%!T`%`:%*(4."*_U2X5`)0\5&.@:E2T(7@(!V`6ESW"``!0F +MU7@`&(`/`0``I,]P@``$)M5X`!B`#P$``*0R\`&'(X?2#V_U1X>%Z!J5-0A? +M`AJ5"0A>`C"%`_`NA<]P@``4)M5X(*`:E0L(7@(QA0+P+X7/<(``!";5>""@ +M$O#/<(``%";5>``8@`\``'P5SW"```0FU7@`&(`/``!\%0&'&QH8,$.'R7`< +M&I@P((A`V<]PH```'2V@SW&```"M +M`"%`!":`)($@@5(/H!.6(0H`R7`"#6```MD!V`&ER7!*<8H)8``"VED!C_+Q +MP/8(C_((=80M"1_/<(``*#LP($`.A>#,(.*!4?3/<8$`N"X0B4(@$H`1B``@C@^``)RL,:Y0 +MKL]Q@`"<"SZ!QW"``)RK.G#T&$``@.?*(*$`@`MA_,HA00/RR4H@0"`-"$X# +MY@C@"*EP!NC2".`(J7`5Z/P9@"3@INP1@"`;")$`$HX3"),``>`2KC*.J7#^ +M#R`5"-H,'@`4F0"/\N!X\<`Z"(_R"':$*`D/SW"``-P\,"!-#@#?"_`O*$$# +M3B"/!^]_F@YO]>EP$"7-$_?MT@BO_\EP,@Z@`,EPMVZT?0`ED!^``)RMS@V@ +M$U@@P"G)<.EQ9@A@``S:`"6`'X``C*Q2#&_W1-D!V,=U@`"X%'C'<(``G*Q2B`D*<@``V3.HX'\RJ/'` +MX<6`B:K=08D`$`0`8HE,)("!S"2B@P3T!X``B`GP3"3`@LH@0@,#]`>``("2 +M#B`5B7&U!T_RX<4'N!1XSW.``#2L'&//<*```"`;@*>$.&`"($,#$PM2``>D +M`=@)I"JD2Z0"\`#8X'_!Q?'`^@YO\DHD0``:<+=HM'W'=8``G*O/<*```"#; +M@)H5`!=6)<\4AB!_#X+@N!4,$,(D`@';9$HA`""T%0`0A.P($*`DOSW"````],B!`#L]R@`#0L0.X +M%G@`8H_H!H?">02`0(!987H,H!/I<$>'"G#">BH,(!4KAR0?0!25!F_R6!U8 +M%.!X\<`R#D_R"'4H=@>X%'C/<8``B*P)81-N%G@`(((/@`"/'`Y@U/\@AV*'4' +MN!1XSW&``(BL"6$3;19X`""##X``G+$(Z0V#@.!L#&'URB"!`P'8#:.I<((/ +M8`4`V:8-8`"I<F@Y@!__!=K/<($`Z"WP($(#J7#)<0SPC">"E`GRSW"!`.@M\"!" +M`ZEP`ME`>LT$3_+@>/'`7@Q/\@AVMVBT?0`ECQ^``)RKQW6``)RL%H4:<8#@ +MRB"!#P``!`'*(>$`.`ZA\LHB@0,WA0'8B.D7I<"G!*_)<`H(8`!`VX%'@Z +M<``A$```((T/@`"@:E>FXRB""#P```@%<#8+RX@OO +M_\EP,HW)<`H+(!4`VA,+$"`:E>*X&`IA`,H@@0,:E0D(7@(QA0/P+X7/<(`` +M!";5>""@&I4+"%X",(4"\"Z%SW"``!0FU7@@H!N5`")2)`0H@`\/`$!"R7`` +M&D`N`!`!(00A@0\````(B@B@!Q00@B`-\"\HP0-.((T'KWW)<.(*8`"I<1`G +M3Q/V[X0N"1_/<(```#TR($$.R7!""R``!MH-`T_RX'CQP+X*3_((=80H"0\` +M(8!_@`"0/0&(*':#X,H@2P/\#*O_RB%K`*EPR7$."R```]K]`D_R\2FG*O"$+0D?SW"``"@[,"!`#@`?@!4)"-`!)0X0(``C@`^```"M)H`D@2"! +M^@]@$X`A$`"I<*H-(``"V07P[@P@`*EP`=B:"B_Z2G//=X$`<#08'X`4'!_`%-"W(A\$%*EPJG'" +M"2``!-I`)P`6L@TO]PS9:0%/\O'`(@E/\@AW&G%:L=R@`"/'`1@A/\J7!%@CO_PAVMVZT?0`EDQ^``)RL6!,`(``EE!^` +M`)RK`=^1"!$`5B1`)CIP0,#/<(``X/5!P,]P@`!H#T+`SW"``&P/0\``V%IP +M1,`&V!IP`]D-VDIS"B2`#T0`U-,*)8`/10#@.$HF@`@F"2`%"B>`!,]Q`0#` +ML7(+(`4J<%8(;__)<*8,8`#)<,]P@```K;E@SW*``!C:N&``&(`$$!D`!,]P +M``!H7P.AQ:%&H5@;P"-<&\`C`!R`(P058D0!92"2`%:'+%!P_RX'CQP.'%`@@O_`#=C"##CP?TJ7`'\!`@P``# +M\,X-S_L0Z"\I`0!.(8,'-VLT><]R@`"PK"%BX0E1@`'8`_``V($'#_+@>`.X +M%GC/<8``SK'@?PAAX'CQP.H.#_((=1IQ@@A@!0#>@>#*(((#&/3/<*```"!; +M@$`HSR#/<(``V+'V?^%@![W/<(``E*RT?:!@.&`0<@#8RB!O``T'#_(#N!9X +MSW&``,2Q"&&`X`'8X'_`>`>X%'C'<(``G*M`$`(&`-F'ZOP0``"`X,H@00`" +M\@'8X'[@>/'`X<4N#V_[*'4*O;%PW08O\F\@"P#@>"]Y\<`3"5$`SW&!`"@N +M\"$"``#9"O",(8*$"?+/<8$`*"[P(0(``ME`>M'`X'[@>/'`'@X/\AIP.G%( +M=\]P@``TK$`HS2&T?;Y@2Z8*`3?BB`0``JF&?#'=8``G*P:E0+?#0A>`A"%"J8/\`Z%"J8+ +M\"@>@!\````H!=\%\"@>@!\````,>@P@``IPSW"!`'`T[*`*<"IQ%@[O_P': +M\04/\N!X\<""#0_R6G`H=P#>5@\@!``@C@^``)RLH*86 +M#V__Z7"AID#9SW"@```=+J`"V)8/[_OI<<()H`<@V`$%#_+@>/'`C@P/\@AU +MD.#*((H/``!<`W@.:O+*(4H#$VT6>``@C@^``)RQ`(8!WX;HC@U@`*EPX*;N +MIMH*+_6I<+T$#_+QP.'%"'60X,H@B@\``%T#.`YJ\LHA2@.V"B_UJ7``VA-M +M%G@`(($/@`#4L9T$+_)`H>!X\<#AQ0AU![@4>``@@@^``!RL'((%>3RB*@O@ +M%*EP5@O@!ZEP<00/\D"!SW&``!RV`H$/((```J%M!B_["]C@>/'`W@L/\L"! +MSW*``+Q'A"X)'P`AC7^``"`]<16!$!1N)0GR`!9X@@H@`,EP*@RO_\EP%VX4 +M>,]Q@`"NK`EAR7`#VB_P7PE2`)8+;_L`8B*`SW*@```@6X(%@#!R`-H*N,HB +M;P`X8(#BRB$"`,]P@`!(%0"`"N@4A<=P#@``$`)Y/[E2(0&`#_+."Z__R7`7 +M;A1XSW&``*ZL"6')<`3:[@K`%*T##_+@>`"!![@4>,=P@`"$`&PE?`OP0`0"`X;0`8@#*(:(`!08@``39X'X`@0>X%'C'<(``G*M9 +M`4``\<#J"B_R`=HH=A"1H('MN`'9SW"``&"V(*`'AL(B@0`WZ!=M%'@`()`/ +M@`"`C"``O`N@*EP>@NO_P;:\)8!V40G`!.`X.ET49;` +M>6:&`-B&)/P0C"0#E.#>S"2"D\H@80`#Z2#H1@A@`*EP@.`*<`7R&@A@``+9 +M%O"N"B``Z7$2\(0M"1_/<(``*#LP($`.%0C0`8CJ%VT4>,=P@`"/'`E@D/\AIP*'4'N!1XSW&` +M`(BL"6%(=H+A`=C`>(#@`=_`?Q-M%G@`(((/@`"__!]JA`2_RZ7#QP.'%"'7/ +M<8``'+8#@0\@0`,#H:X++_L-V*EP`@WO_X#9D0$/\N!X[0+/^;4`0`#QP/X( +M#_(Z<"AU]VCT?\]P@`"(K.E@2B!`((+A`=C`>(#@PB`")'-M=GO'`'X```*V&#@`3 +MSW"!`"@NM7C`H"IPJ7$6">__"-KQ`"_R"G#QP(H(#_+/<(``'+8:<"F`Y(`! +MX2F@)@HO^P'8,O`O*,$#3B"-!Z]]A"T)'\]P@```/3(@00Z*(@8`3'W/<(`` +M-*P`($X.$VD6>,]S@`#<]R@`"(K"EB'0F1`*8-``"*Z#$5@!`1"!X`1!V`'P```!`$ +M\`#8$:4]``_R\<"B#\_Q"'=:<<"`*'"&(/P,C"`#@DHF0"#")H(E%VX4>``@ +ME`^``)RK&8?\%!,@@N!*(4`@PB%"),]PH```$#F`&(`:<@#=!NL-")0`$''* +M)6(0A"X)'\]P@```/3(@50X3"!XA`-I%K\EPL@V@%`'9"(^'"!``$P@>(40B +M`",+"!$"`-I'KQ/P)X],)@"@T2`BH1'R"8\/Z`J/C>C/<(``7+8`@(GH`>$O +M>B>OR7!N#:`4`MD'CT,(T@":%``GJ;B:'!P@&H>'N!JG`@T@`,EPZ7`-"Q`@ +MC@P@``+9!?#>"2``!-D!V`NOQW:``#RV#(Z!N`RN`-@'KP#9"X\HKRFOHNA1 +M(`"AS"4AD,PA(:`.\DPC`*#,)2&0!_+\'$`@Z7`%V0[PZ7`$V0SP0"W`(!9X +MSW&``-"Q`&&&Z.EP`]E^"0``K0;/\?'`<@[/\:"`"';W;?1_SW"``)BL,"#0 +M`]H.;_^I<,]P@`"NK.E@J7#^#:`4!]HB"2``R7!2#B``J7!,(`"@R7`,V!X\<`F#L_QH<$(=2AP2'<3"W(`P(6I<+H+(``!V4SPZ7&& +M(?T,C"$"@C/T#WB&#Z`+R7&,(,./RB`A`!/RSW&``+#E(($'OD#!,B0`,`#9 +M#R$!`,]P@`#LK-1^R&`D>!GHR\F@$`$`&H4/"5$`H+@:I0'8":T#\("X&J7/ +M<*```"`;@`.EJ7"B""```MD4\.EPAB#\`(P@`X0.]$`E`!0F@"2!((&N"R`3 +MEB$*``"%8@GO_Q#9W07O\:'`X'B1Z`#8$?`O*0$`3B&#!S=K-'G/_T*'#@>/'`"')DBG#@!.O^ +M#J`$+WG1P.!^\<#.#,_QSW6``!RV!X4(%180`>`'I0WPR7!^"B``!-GI<"X/ +M+_^*(4P`!";6),T.$"`O*($%3B"/!Q=O%'@`((X/@`"D"A00@P`0"I>P6@!"_")&`A"\)'\]P@```/3(@ +M00[\%A00?@VO_^EP.G`J"B``Z7`:@`V10=0"#)<,() +M(``%V:+Q10P0H,EP#0@0(*X)(``"V9KQ_@[O_P#9EO$"A8#@;`WA^LH@X0(5 +M!,_Q![@4>,=P@`"/'`U@O/\<]U@``\*:X&J?I<*X.[_\(V1;P+R@!`$X@C@>$+@D?SW"````],B!/ +M#DX.[__)``)RK&H`]#P`#?1,<+V`W:Z7,*)(`/@`"`#PHE@`^``#P/2B;` +M#18,H`1*)T``SW$!`,"Q8@Z@!*EP*@@@`,EP5B!`(L]R@``8VN"@!MDDH,]Q +M``"X8".@Q:!&H`D#[_&EP.'%X<8W:#1YQW&``)RK0"$,"\]S@``8V@#>P*0& +MW:2DSW(``,!@0Z0%I&:D$!F(`Z2ASW(``)1@0Z$%H6:AP<;@?\'%\<#AQ0AU +M.Z`/"5$`)@W/_ZEP"-D"\`;90@W/_[D"S_$'N!1XSW&``-"L$&&&(/@!V-'`X'[@>`>X%'C'<(`` +MG*MA````X'@(<<]R@``'*(,$`,`OA_\HA@0"E`,_Q\<`J"._Q*'`H=?8*[__`@:(([_2I<,EPE@]@ +M%`'9`-G/<(``7+8@H,]P@`!@MFT`[_$@H/'`]@^/\0AVMVBT?<=U@`"`25B5`$LEP)@HO_Q[9`-@Q`._Q01T8$/'``($Z +M#V`4`-FN#*`,`-C1P.!^\<#AQ0AU=@W@$BS@`(7V"2__"-D`V`D`[_$9I?'` +MA@^O\2AP*'56"N__X($`WMFEZ7#2"2__"-GRR1$@P(-D#*(,RB""`\D'C_'@ +M>/'`X<76#*_^"'6I<"X)(`@`V:(-;_JI<`(/+_^I<&H)K_JI<*T'C_'QP#(/ +MK_$$N!9XSW&``+Q'.&!`(`T(`(4`WAX++_O)<<"EF@GO^@S8>0>/\?'`X<4S +M:#9YSW*``,BQ(6+/=8$`<#0CI98((``'V4`E`!)6"Z_V$-E5!X_Q\<#6#J_Q +M"=H(=<]Q@`"@L0.X%G@?8;@@7"!`B0"@!)A"] +MI7F*(`0$$@@O\N5Y.!$`(`GH+R$'!$`A`"$&"*`$R7)9!H_QX'CQP/(-K_$! +MV1IP)!*/`+-HMGW'=8``G+'+A8'GPB%!`((/[_\%X0?N`-@+I0IP8'[I<2D& +MC_'@>/'`P@V/\<]U@0!P-".E`-DHM26E"B'`@$2URB%B`$X/[_\!X<6%0"4` +M$@H*K_80V0$&K_')<.!X\<"*#8_QSW6!`'`T(Z4`V26E"B'`@$2URB%B`!`= +MA!\````0,WD.#^__P;G%A4`E`!+*":_V$-G!!:_QR7#@>/'`0@V/\0AU`[@6 +M>``@C@^``)RQJ7``WP(/H`3I<1IPJ7#2#N__"-GKIC`>PA,Q'L(3SW&``!RV +M!8$0($`#!:$*<`8-K_^I<6$%C_$`VS-H-GD`(8(/@`#.L6"JE0;O_P39X'CQ +MP.(,K_$9V,]W@`"``@@0^``)RQ +M2X$'Z@#8"Z&I<&!Z,!&!`!`F3A/L[@#8"06O\:4?&!#@>/'`@@R/\0AV.G%( +M=WISB@SO^@HB`"&DB+8,[_K)<%1M5GH*((`O@`"@1T`@`2=984`A`@@7"%$` +MR7`J<>ER:G/^#V`1"B2`!(3P`(&!#@$00@L@%*EP%VT4>,]Q@`"0K`%ASW:@ +M```@&X8R>3A@`>`1"(4/``"@#^8*K_^I<&KPA"T)'P`A@'^``"`]=A"!``'A +M=AA"`!`0`2`/(4(#$!B`(+$/41`[@(#A`-H!V07RBB%(`%N@Q@]O_ZEP(-A- +M'AB0`-C:"B`'J7%$\`2!)PX!$($/41`0V<]PH```'2V@`=B^"B`'J7$"V/X. +M;_NI<3#P!((-#@$0BB#_#P2B*O`8@A$.`1"I<((*K__I<2+P`((3#@$0J7!B +M#V__BB$$`!CPSW"``$@5`(`4Z!"")0X`$!2"'0X`$/8.8`G)<(#@RB""`\HA +M0@0D#V()RB+"`XT#C_'QP.'%"'6$*`(*`"&`?X``X$H&">`2H\$`VD+"BW&: +M"F_UJ7"5`Z_QH\#@>!5XSW&``,!1.&#/<8``<"?@?P"A\<#Z"H_Q"'6$*`D/ +M`"&0?X``(#MN"*_^;Q`.)F00`"`.Z`WP+RB!`TX@CP?O?ZEP[@PO_^EQ$";. +M$_;N9!`!(,]P@0`8'2.@$@J@!ZEP%0./\>!X\<#AQ0AU!(`#Z`:%A>B2#._Q +MBB"$!B2%!H4+"0$`%'@&I04#C_'@>/'`X<6$*`D/`"&-?X``(#LYA0WI-&@V +M><]P@`"\1VH*[_H@8`*`?QT8$-4"C_'@>/'`X<7/=8``@`BIHIP0@M@"T`F`1X*#J`' +MBG``()`F^Q``IB*`8'F*<".&BG#2"&_^J7**"N`"BG`Z"6`-BG!,)`"AH`\E +M^LH@!07*"&_\BG"V",`#N/`$+/XC`"93'D`D$3)`(P`B*G&Z#N`0%]I5)%`V +M52-`)@IQJ@[@$`S:O@U@"TIP"!,!(`+"4''*(((/```<-+@*PO$$+/XC`"92 +M'J]ZBG"J"F`+0"(!+G(-H`>*<`P2`"`#P1L(0`"*<#X(;_X#V@P2`2"*<#(( +M;_X!V@0L_B-`+(`@0W#[$`"&)W:#@"IP0"8!$@IR529#%F!\"B0`!7(*H`2* +M<`]Y`-H/(D(`C"#_C\HE@A#*)2$0<@J@!(IP!7T.\"\H00-.((X'$FY#8IPB@V@"V\6`!;"#*`+2G`^"&`-BG"F#N_R`-CV#Z`&BG!, +M)`"A-`XE^LH@!05`+(`@0W#[&!B$4@X/^PH-@`+!!V_Q@"0"-?'`=@]O\0C9 +MHL&+=7H(X!.I<"#&.@MO^:EP"'4@P(/@RB"&#P``"PE`"<;Q`<`S"-$`Z@\O +M^P#``,&,(/^/RB""#P``!0DL"<+Q(,$`VL]P@`!$6#5X0*"^#R_\R7`!P#,( +MD0#/<*```"![@$"%`,!^8@]\SW&``$18E7G`H8;J3@GO^F"E!_#/<(``^-<^ +M#8_X;@R``DT';_&BP/'`Q@YO\0+9M,&+=7X(X!.$P'(*H`4$P`HB@"^``"`[ +M!,%`(A0BBB<)'R$(4``O>.QX`")#+D"#SW````,T*+I/>JH([_%A@R3`4\#L +M>#`D4RZ2P#8(X!,!V07!&0E0`(+A??*#X8_RSW```!4T:@C/\9WP`-A^"J_Z +M.G`2P0AVD>'*((8/```F-$P(QO%`)@`2^@^@$P;9+Y89"=X#7(Z,(L./RB"! +M#P``*#0P",'Q`=@@'@(0!,`2P0&F"B"`+X``:.OT($`@$;8#AHP@_X\F'D(0 +M#?2*(`0+`Z;/<*```"`;@`*F#Y9%(``##[8/E@\(W@+/<*```"`;@`*F/0M1 +M(I/!9@B@!PC8&.@$$``A$;83P.QX`")!+AF!#!Y`%,=P````L`*F+-@&IO_8 +M'*X='D(4'($%IKX)``<`A@X+K_H!V23`['@P)$$NAN%T"($(`(8"I1+`*/"& +MP"X/H!,&V98)``<2P`G!1@^O^@K"@.`2P#0#T$)Z01/ +M\>!X\$O>>\)$H&!\('`"B&` +M+X``I/TJ<>H)X!`XV@#>#/`"EP'F!.`0>8H@!``)(0```K?/?M<.$Q%5)$`^ +MU7C/=X``A/[6?^EQM@G@$`':`-@"MX0N"1_/<(``*#LP($T./0T1$@&7@.#* +M(((/``!C`,\@(@/*(8(#L`VB\`/>`(2@2"U"$.` +M`"!!)%)H5'I;862+66$EB4*7[NL((8$`[?&F"(`";0-O\8`D`SW@>/'`_@IO +M\2S9SW>``!P9$@R@$^EP`-U"\(0M`1S/`!1@'D`4SW"``)S5$)AD'H`4!*;/ +M<*```"`;@`:F!:9."V`'J7`HAP4I/@!`*8!R`:8Z"V`'J7`(<0#8E;@J"&`# +M0"8"$](-+_JI<`'E@0U4D48,+_H`V/8/0`*U`D_QX'CQP%H*;_$,V:W!`-X& +M#*`3@<`:=CIV$?``W0\E31`+)0"4RB""#P``&3`T#(+Q!2!0(T`A42"%"14A +M0"F-(+1]@W4!A8P@_X_U\_X)#_LAA4*%8X4'Z(PB`H"`W,PC#H/&]\]P```8 +M,`H,C_$DC<]R@0"D&Q1I8H5P((\`G0O`@\]T@0"@#T"$X+K*(\(#`_1@H$"$ +M"0I?`$.%0:`)ZT&`A^H$&(`/````4`#:0J``W0\E31"E?K7Q1R#"(Q/P+RB! +M`$X@@P?/<8$`I!L4:SA@((`'Z0#9(*`AH`\FSA`0(L(`[^K5#A`0SW6!`*`/ +M`(4S"!\``=G/<(``!/\JH`#:#?`T:L=Q@0"@&P&!`>*%*`$)02G`<0&A!*'K +M"A2!C@W`!H8-@!$:<`"%?PA?`'L(E"#_WP#=Z78#\`'EKWTY#1,1Q@_O^JEP +M!/"I=Q`@@`!UZ"\I`0!.(8('A"H)#\]Q@``H.S`A00[C"5"!A^'*)D$3[O'1 +M=\H@@@\``/\`S"<"D,PF`I`1\C#:!+_/<($`H!M`(`$"^6%`H5C9!+[88"*@ +M`=DCH,]U@0"$#P:%$G!P"(+Z&!T`%`#80,"+<.X,8`($V?D`;_&MP.!X\$`F`1D"88HG_Q\"(L"#`L'*(&(`'PE0`(+A`<.3\H/AE`(!`,]P```% +M,#X*K_%H#&`'`($J<,X-(`L!V1`E313O[=H(X`@4 +M$P`@+@XO\DIPN?`$Z!$+@`#/<```#3`:":_Q:'%*)``@!!25,`HA`"6*=0HC +M`"4'\""@#R,3)$`A42!+"=4@%2)6)`@6`2#S"<"#+R!'(!D(="%`)%0@SW`` +M`!8PR@B/\0@6`2`5)@`40(`/)0T4Q0K`@U!QRB""#P``#C"P"(+QV_$9#!$@ +M`!(!(,]P```/,)X(K_$$$@(@0"V`(!1X`"84$"@4`""E>*=X.G`=\"\H`0!. +M()`'"G`"#2`+`-GP)@`4&0C!`P`2`2#/<```$#!>"*_Q*!0"(`#8W@]O^@\@ +M``00)@`D"B8`H./U*!Q`(Q02`2`O>!4F%!`/"#4!%!0"(#D)@`#/<```$3`B +M"(_Q%/`O*$$#3B"0!Q4+#B05)@$45!E`!1X+8`<`@0IPC@P@"P'9$"4-%.WM +M]@PO\DIP$O`O*$$$3B"3!Q4FT!0Z"V`'`!``(``8P"/_V5080"`0(=$DWPD1 +MH``2`""B"V_ZJ7&:#Z`(%!0`($3P`^@3"X``SW````0PI@]O\6AQ0"B`(!1X +M`"83$"P3`"`H$Q(@%28-$&X/H`@%A>6E(?`O*($`3B"1!Q4F310`A?%PRB"! +M#P``$C!H#V'QRB$!!"IPZ@L@"P#9L@I@!P"%*!,!(."E$"%!!"@;0"#_V!6E +M*!,"(-_J"G`B"V_Z2G$D&\`C`-@Z$*`DOSW&``"@[,"%`#@\(D0$2"&`("G`%Z!J& +M`-T!X!JF$"4-%.GQ`!Q`-(MP&@E@`@39]00O\:?`X'CQP,8,+_$&V<]V1`#\ +M\F8.8!/)<#8*8`(%W:8,H!/)<`'8R7$`VCX,8`((``V,H@X@`J"B_[`-F@ +MIA$$#_'QP*'!BW!.#6`3`=D>"4`"`,#/XTR"B`<\A`@#0(0$` +M-+*AP-'`X'[/<(``Q!L=!6`3"-GQP.'%SW"``-Q6T@_O]5S9SW6``#`@J7#" +M#^_UBB$7!=X*8`,`V,]P@`#<5>H,8!-`V2((```!V<]P@`!4H"F@*J"I<&H/ +M(`**(1<%E0,/\?'`[@HO\8HB!@P*(8`OIP"`24`1%2`*(X`O@`"4EB`3`"&" +M)`8^0,`*(8`_@`#D'$`D&#$K`&G`X80<0(.H`C"(`(D'[`JG+!^`%!8/3_9R#Z_]`-B:#8`(@>`!V,(@`0"`X`'9P'GJ#R`# +M`-@@A@&'#0E1`%^7"G$$\`IQ`MJ:#\_[SW"``%2@"("!X`/8P'CN#T`("(4B +MAA&G"84.N25X*882IP;I*H8+N05Y,J<%AAH/[_PDA@.G_]G/<(``B#,@J"&& +M4-B&X=0!+0`9MS(F2G!$``"`0">`$H@0"!>\`"&DP@1``H@@"^` +M`%`A.I=`(``C;@NO]EN?0!^`%$`@`",3IPJ%SW&``+@@L@BO]@#:`H8=>*H/ +MK_8/>%H/8`@#V.8/3_9#AZ'J`!2`((H/;_8AAP8-H`@:<(MQ3@]@"(`A!@TR +M)(`_``"T`2&'A"B%!2]PA"G""B=P`""!#T0`./<*<"8.8!"KV@X/8`@`V+7Q +M5!^`%$`90"4,AH#@3`J!]L]P@`!<(8X-K_8!V:?Q.@JO]@'=&G4"AL]Q@``P +M(`NA&I<`W0"A!(8,H06&#:'/<*<``'T*@,]V@`!,,D$H`@3)N`&ASW"``%2" +M'IA"H0JA`,`@&P0@X@VO_0'8S@Z@"ZEPJ7#V"6_\J7$+<"MQF@U@$(HB!@P` +M'@`4`=A.#B`#J7$*":`(6!>`$*"F0!E`)8$`+_&`)`8^`(8-"%$`0!E`)50? +M@!3/<(``7"'J#*_V`=G/<(``,"`R#D_V3_$.AL]Q@`"X(!"G0"8`'Q.G"H5N +M#V_V`-I!\2&'SW"```0>]2!0`$`90"7/=8``L"$ZEZEP[@FO]EN?J7`3IR&' +M"G!*AT`?@!0>">_R`-MZ#8_VTO'/<```NBC:"4_Q'_'QP,X/[_``V.`<"+#/ +M<(``N.0`@,]Q@``@ +M```@"0A``#VF`,`K"-X`0L"#P`X)8!,%V0+`#PA1`!8/[_0!V$?PA.`(#^'T +MRB"A`$'PSW!%`&`C`(!3(+Z`#?0,'X`?"````'P>`!0!V/(*[_0`V2_P7P@> +M``'8X@KO]`#9#!^`'P@```!\'@`4X@V/]S\(40!^#8_WSW"``(RK`(B,(,./ +M$O0`V`WPI!4!$`\)#@!;AS-H-7DB<4"A`>`/>.T($H$%\&(*K_0"V!N'0<"! +MP`(+(`($V0#`$PC>`,]P10"T*X397@]@#Z':_0;O\*C`\<"6#L_P`-\J#B`# +MZ7"6#0`)SW"@```<&!B`#R````#/=:0``$0IA<]P@``H5!IP(*`1A<]V@``< +M5`"FZ:7QI<]R@`!L)B""SW```/\/,PD>`">"^KG*(((/?P#__P?TZ+G*(((/ +M`P#__TF"4'#*((X/``!H"R@(3O%�`)`!``(`FE`(81I74&S_#QP!(.[_`, +MVJ3!BW7/<8``J.22"2_QJ7#/<(``U.7`@*EPG@\@$P/9`,$;"5``9PF0`(T) +M$`'/<```"T3.#P_Q0O`!P0T.1'```/\_#PF5#,]P```,1+8/#_$!P<]P@`#` +M)BR@$KF`(0@`*KD#N2^@SW6``!@G`(6FZ)(-C_@&A02`((#'<00```"R"R`2 +MJ7`:\`#9SW*``,`F0"(`!""B*'(&\!4@C``@I`'B^0H4@L]P@``8)S(+`!(& +M\,]P@`#`)LV`SW"@`(`,0!B`#P"X"`#FR0+9`!\`0,EPT@H@`@':H07O\*3` +M\<"^#"`#`-C/<(``@"?*#B`3"=E6"(`"T<#@?O'`X<6CP8MUJ7#/<8``B.:. +M""_Q#-JI<`(.(!,,V<8)H`*I<&X*``)=!>_PH\#@>/'`X<6CP8MUJ7#/<8`` +MV.5>""_Q#-JI<-(-(!,,V6H+H`*I<#X*``(M!>_PH\#@>/'`J@S/\'8+@`<3 +M"-$`SW&@``!&`(&?N`"A`-W/<$0`$/*@H,]V@`!(%:"F`=G/<(``6!4@H,]P +M1``,\J"@SW"``'C>4@E@%0"`1@O`"'8*S_T""0`+SW=%`#0XT@T@%*"G5@A` +M%$,2@0`8N25X +M!""^CP(`;``.]`"&C.C/<(``,-'/<@``_PNV#&`/BB$)#;8-@`==!,_P\<#R +M"^_P`]G/<(``S.4`@,]U1`"\D^'`A@T@$ZEPSW&@```T`(&PN`"ABW`*""`" +M!-D`A0OHSW&@```@.X$98<]P@`"\V-8)`!+/=D4`-#@`A@\(G@,"A8#@P`X" +M"0'9SW"``$@56@J@!R"@`-D/")``SW"``%@5(*#/<$0`#/(@H,]P1``0\B"@ +MSW*``/SY0!I"`"BY01I"`"BY0AI"`"BY&8Y#&D(`Y+AL#`(43@X`"5H/`!4B +M#,`/'@^`%.X,`!2!X!`-`13/<*```'P1@`#9`]L0NP0@P@!P(.;_0`VJ8)@`<1"-$`SW&@``!&`('>N`"A-0/O\*'`X'@=!X`!\<"V"L_P +MSW"``+SD((`!@*;!1<#/=J```!`)AD3!`-T*Z,]P@`",J]8(H`@`B('@RB5A +M$(MP,@P@$P39`,!'"!X``<+/<8``:"@`@0;JH;C6#*`"`*$7\*"X@;@`H<]P +MH`"`13`8@`\`(``!`=G/<(``;"@@H&HA@`'/<(``<"@@H`#`6PA>`!(/`!(` +MV`T-41`)ILX(``L%W\]VH```,`@>@!\```"@`-AB#:_Z_]E:#Z`3'M@"P,]Q +MH@``>"89&(`#P`V_F!D``('E[`XA$LH@80#CI@#8T@RO^O_9SW&B``!X)A$` +MAD3`F!$``$7`A,`.#N`!"-DI`N_PIL#@>/'``=CAP,]P@`"H)UH+(!,?V8MP +MZ@W@`039H<#1P.!^\<"XP8MP0@L@$P39`,``VT7``<`%VD;`!]A$P,]PH`"` +M#$`8@`\`N`@`YLD5N@`?`$!KHL]QH```/`>!":%JH2P:@`\`@,(``]@"V>H. +MX`$!VI8)H`6$P+C`T<#@?N!X\<#AQ:'!BW#>"B`3`=D`%`TQK@]@$ZEP4R4` +M$.&]S1H8L'@(H@K*(&(`E@[``84![_"AP/'`H<&+<`X*(!,$V0'9SW"``$0R +MJ@@@`R"@S@D`#VX.P`&AP-'`X'[QP-8([_"*(/\/&G"<'`BP@""0\PI!@`/P +M`-@1Z&&0SW2``#1]HI``D$`D`14]90L(D01`)`T5`-X$\`+>`-VI+["D2`R7`!V9X+X`$H +M.@JO]>C9"B&`+X``9!X>$<`@`*88$4`A`::8%4`7!*:@%4`7`Z:\%4`7`J88 +M$P`@#PA0`$@3`"`+"%$``M@"\`'8!:8`V`CP((`!@#*E$Z5`)$`@$'AS"+,` +MFG!`+`\A]'^*<(0H`0%B=R2'`"9-'B:E!8<*((`O@`#(N`>E%)<-I0B'#*4I +MARJE*(=*(@`O!.D!X`RE9@OO\@:'SW&``-0=":48EPZE!)\(I06?$:5`+(`@ +M%7@"88IP!"B^!``@0"Y#ZB*`PO%5)D`5`-FJ`!Z-D)!8_PX'CQP.'%M,&"P,X-X!(8V8MU +MJ7`J":_U"-E6":`3(L#/<8``=%CT(0``(L(`'`0P(\&(P%8/;_PGPP;`!<$" +MN(-P$PE1`$0000$"'$0P1A!``0SP!,&&Z3"8`AQ$,!&8!O`\F!V8`AQ$,`0< +M!#"I<*((X`$(V`!`=H" +M#$`0T<#@?N!X\<`F#*_P`=C/=H``0!4`KL]P@`!4@AZ8<@X@`@'9Q\F`X(`( +M0OO$R1GH`-\2\,]Q@``H\O9Y0($`W0\EC1`+?0?R`8%`>,3)IGC$&ABP`>?? +M#Q22`@\O^0/8`-@U!*_P`*[@>/'`X<6LP8MUJ7!J#>`2"MD!P14)4``;"=`` +M0]BB#>_P"+@+\(K!2@_@"*EP!?"*P:8/X`BI<(K`T@^@`0C9`02O\*S`\#,`$"'8-"-$``=T` +MWQCP%P@1)`'8E2%*(P`9`"`(=0AV`-\,\%4(421"#.`$`=W"#N`$"'8(=X;F +MP'T3"%$BL@[`!$(F#9$(=\HE8A#/<(``J"<5B!4(7@#/<*#^N`X!V6X+8`+I +M!X\<"J"J_P%-G/<*`` +M``0#@,]U``"MWK`<"+"+=CH,X!+)<`#`8;B)")4%,R8`<(``X.)`)X%R%'D` +M>;X*8`7)<`AU.O"&"V`%R7`(=33PH@Q@!/'`H<&+<'8+X!(!V0#`!=G` +MN!1YSW*B`"1P`()&(,`!)7@`HBX/@`&AP-'`X'[@>/'`X<6DP8MUJ7#/<8`` +MM.4>#:_P$-JI<)(*X!(0V08/@`$`P!,(4``;")``F]AB"^_PC;@*\`'``L%V +M#V`&`\($\!H(H`8!P,T!K_"DP.!X\/, +M(Z*`%?(!V-/Q*'!Z#N`/R7$"PT3'1<.$P`C9R7(V#:`!`KOM`*_P@"0"-\]P +MH`"`,`*`ZKC*(*$`N?/)<`L+40!"#L`/!/!Z#>`/J7)$Q[#QX'[@>/'`5@B/ +M\*S!`-^^"R`(:\>!X`'>PB:!$XMUJ7#J">`2"]D#V,]R@`"`-P#!`Z(AH@7` +M`J(FZ1L)4``Q"9``1PG0`,]P```%0@H*S_`[\`X)K_3I<,H(8`CI<&H,(`CI +M<-X(K_3I<"_P+@RO].EPL@A@".EP3@P@".EP`@RO].EP(?"+QZEPR7$&#J_T +MZ7*I<,EQT@VO].ERN@VO]*EP7@VO]*EPN@VO]*EP@@VO]*EP-@ZO]*EPU@VO +M]*EP9@ZO]*EP'@V``?T';_"LP/'`A@]O\#+9SW>``/`WPX>*".`20"<`$^8) +MS_3>#^`20"<`$Z.'60V1$`F'"N`)IPB':K@(IPN'"N`+IPJ':K@*IP#9"_`` +M(8(/@``0.!"*"0C1!Q[8$*H!X>\)E(,9CSB/"+@%>1J/$+@%>1N/&+@%>0'8 +M]+G"(`$`$*?/<(``<#@C@!IP`>$CH!"'SW&``/`Y,>A9CQB/"+I%>%J/$+I% +M>%N/&+I%>-.XUW```!A@'O(*]CD($`;8X!?RC"`%A@[R&?#7<`$`6&#,((*/ +M`0!880OR'PB!#P4`6&$,&8`/``"X"PKPBB`?!`?PBB`/"@/PBB#_#P.AC>X- +M[0X+8`\0V`@0`""&(+\+D>#`#\'T!?`%[H#EM`C!]!D-D1`2#\_TG@^/],X/ +MC_1B#<_T!?""YCP*P?1^"^`%_]@6#0_U7@_/]#8/S_1F"P_UQ@N``9T&3_#Q +MP.'%JL&+=:EP/@^@$BC9J7#/<8``U#DR"^`/*-JF",_TG@N``8T&;_"JP/'` +MX<7/=8``T#A`)0`2#@^@$E#9A@C/]"(/X!)`)0`2SW"``/`Y&!#!@#<0PH", +M(3Z`?]S,(@&#RB""#P``BC/,#X+P?@Z/]$H+@`$Y!D_P\<"Z#6_P"-FBP8MV +MO@Z@$LEP`,#/=8``\#<1I0'!$J4SI0#?#R=/$`*_]7\6#*`*$'C]>2)X%*7X +M8!6E]@[@$LEPK@Z/]-X.C_0Z#`_U@@[/]%H.S_1F#,_TZ@J``F%XLPBXH$% +M]*8(#_X%\(+`&@Z@$@G9[@F``:O`T<#@?O'`KL&+<`8.H!(.V0#`'NBN#N`* +MBB!0`!`4!#``V`+!`<**#N`*`\,!V"`4!#`&P07">@[@"@?##<%"(0"`B@F@ +M`LH@8@`%\'8.X`H`V)8)@`&NP-'`X'[QP`8,;_`#V<]PH```(!N`I<%$P)X- +MH!*+<"#!`12",(/ARB"+#P``1A_<#8OP(,'/=:``@!P!:04@@`_%[H";`:4$ +MP!"Y`:4!%(`P)7@!I0+``<$!I2&E`-X)\(/`5@V@$@'9`\`!Y@&E(,!CN/$. +M!)"$P-8/8`$$V?T#;_"EP/'`@@M/\*7!@L`#W28-H!*I<2+`SW&``+`;P+@` +MH0D4@3`1";,`"A2",(PB!("&]U8-K_"*(`X`SW:``!!1`-\2\#-O-7DZ9FB" +M`\`7"P$`4I(0%``Q#PH!`-AAF@\O]2C9`>??#Y20"12`,`.X%7@#PMA@!,%( +MH"F@"Q2!,!$)40#_V>8/+_4@VBSP:@\O]2#9`-\>\(MP@@V@$@/9`!0`,0(4 +M`3$)%((P)W@$%`$Q`[HG>$$H`0(G>`]Y([G9855Z.F(@BL*X#R$!`""J`><* +M%(`PPP\$D,]PH```!*J@*@B``0D#;_"EP.!X\<"GP0'81L"+<#X,H!(&V0#! +MQ0G0`,]R@`!4@BFB#^D"P`NB`\`,H@7`#:($P`ZB`<`>L@<)$0$0H@V";H)/ +M(`$$@>/*(0$`"X*7Z,]RH@``"`:"A+@&H@:"@[@&HHH@$`#//'`X<6CP8MP#@N@$@/9`<+/=(``(#M/?1L--1&* +M(PD/;'T`)$`>((`+"D$``8`7"%``;'TP)$,>8-B,N#H+K_"I<0#`SW&``%`P +M%0A0`!$(D0`(%``Q%2%,`P"D*'"U>$X-8`$,V7T!;_"CP%T%``'/<$4`."PY +M!6`!7-GQP,((3_`>"F`'I,$:<,]P@`",JRX+X`<`$)<`#WA`P,]U1`"`WZEP +M<@J@$C792B(`(%((H`)*<`(++_Q`)1D4"B2`+T0``.!`%`$@0"48$P_I3"`` +MH,H@@@\``+89B`J"\$`4`2#/<(``5*`GH"`4`B#/=X``Y!P*)8`O@`!D'A'J +M`=C/<8``5)4L'0`@"PI1`!&A!/!$&8`$`-A`"`_`L'8`D0(6!P4`E`!.* +M#&_R"G,`A8'@S""B@%7T`-XJ\$$I@`+!N`L@P(07]&8+X`?J<'H+;_+)<40N +M/A=HX#`@0CX.>TYX$'/*((4/``"M&0@*I?#*(84#VWB#<""%`IA"(4*`R7'* +M(F(`;@HO_"IS`>:"YE8!!@!*(P`@`,`/(Y,C"R,`H/7S`(45")$`1"X^%S`A +M0#[^#"_\(H4#\`#8NPBT@#IPLPD0H0X+P`<*)H`O@`!46!P6`2!G"%&`02D` +M`K'Q@^!_]$P@`*#*(((/```/*V@)@O!*(0`@'?!$*3XG`"5.'@2&K@PO_"*% +M0"D!(31Y^6$&H0B&%+$'A@BA188+"+0`2:%AN`BA"89`(5$@&+'-"92@2(?/ +M=H``>`L`AC2'SW.``#CP]"."``0@@`_S_^?_]"-!``.Z$KE%>25X`*8&AYH. +MH`HRAU@7@!`H%X$0"+@$((`/````_P5YSW"G``!(*Z`XEV`7`A'(N0FZ!"*" +M#P,``/Y%>7$86``D%Q$0`-AB#^`**G%*(T`@:G!6#^`**G$IAP&&58<$((`/ +MQ__'_P.Y$[I%>25X`:8&A1X/X`HMA<]P@`"4EB`8Q`0#\-8(#_Q,(`"@YO0! +MA<]V@`!D'0NG%Z<'IDF%$Z98MS"%"B"`+X``)!T@&$0@4+8*(8`O@`"D'1`9 +M1""*Z#(?A!0B&(0D(AZ$%!(9A"0-\(+@(`L!^RF%$(4YMR(8!"`QMA(9!"`8 +MA5/9$;D+")$``=@7H0/P7!F`!#F%SW:``%2@**8D'H`4@>',(>*`'/3/!*($`@PB`!)&8);_($%``@SW:``'@+F'`&ACV%J[BUN`:F"0D> +M`(NX!J8)"5X`E;@&I@`4`R`!V'P5!1`*<7@5!A"(0@4`B`+"A$!`]H('(`@#!0`(`T($0$#V`P<`"`@ +MA@VZ!"&!#__/_Y\$(H(/````8!RX!""`#P`P```%>D5Y(*8@'4`D!O`#"`$`(4`'8`?K:O^RJ8/K_@)V#H*+_4"V.4$#_#@>/'`9@P/ +M\,]PH```(-N`.@X`#P?HSW"``&02`(`&Z,]P```'*#(.3_#/=40`>+NI<$(- +M8!**(0@&L@E``2*51"&``QQX!+@%>40A@`,<>`>X)7@"M<]P@`!D$@'9(*#/ +M<(``5%0`V2"@"=A."Z_X&-G/<8``8%0`H0`F@1\````((J`AC2:@(8TEH".5 +M/*@)V(8+K_@!V<]P@`!85.H)+_7`H#4$#_#@>/'`L@LO\`+9IL%*#F`2@<`$ +M%``Q8;B$X!H!#0`R)@!P@`#$XT`G`7(4>0!Y@\">#&`2"-D#P8#A`-W/)>(2 +MRB6!'P``!`9.(4`!"[@`((X/@`!(?#*_W!,-N\(+`W@Q@$@'9:O#/<*`` +M``3#@+H)+_O)`7#K,0!K&*)A@4"B$`)(`A&",( +M\(HF%1FLW0HA`"2`(14H"G"6#&`202Z!$`#?!O""P(8,8!(!V0'G02V`$/,/ +M!)`L;@IP(KD$VJ(+K_<`$0,@,/#/=8``5%BI<%X,8!**(4X&/@@`"L]S@`!4 +M9D`E`!B*(0X$`=IV"Z_W>(,:\`#=!O"+/'`,@HO\`'9H<&+==(+8!*I<&8(X`<@P`#> +M$>@!%(`P&PB3``(4@##2X$/VA^@#C=+@1/8`WH/H`=Z1[D.-`HT8NA"X!7H! +MC2"-"+@%>L]P``!1"=8+;_!%>2H/;_L@P`AU`12`,`SH'0A1``(4@#`"Z`&M +M`Q2`,`;H!?!?V`&M9-@"K<]P@`!46`&`(0@?`\]P@`",JR"((,`5"$$`V@^` +M!X#@/`RB^\H@0@,*#P`!\0$O\*'`X'CQP'()+_`JV8(D`CH:"V`2BW#N#@`! +M`,$5"5``>0F0`,]P```"+$X+3_!%\('`"B"`+X``3%=`(`$E4@Y@#Q3:!<&$ +MX0"4/%@WP1(>$XLH@ +MA@\``+,-4`IF\,HAA@,!YA3G!87G#@20P@T``:$`#_#QP*C!+@A@`@#8@.#* +M(((/```#1!`*0O"+<,H)8!((V9H-``$`P`WH(PA0`"T(D`#/<```#COZ"6_P +M`MD8\,]QH```,`N!G[@1\,]QH```,`J!F;B;N`CPSW&@```P"H&YN+NX"J$+ +M@=ZX"Z$!P`WH+PA0`%T(D`#/<```#CNR"6_P`]DZ\%#9SW"M``"$**"*(5`` +MSW"M``"J(:`N\%#9SW"M``!$**#/`BB)X((@L2Y1B#`!R5X +M"*($P,]RI`"`1X'@%8+/<:0``$C/(*$`T""B`!6B!<`/")$``Q$`AH*X`QD8 +M@`7`#PA1``,1`(:BN`,9&(`%P`SH!L`'PL:X![H$(H(/``"`/T5X!!D8@*C` +MT<#@?N!X\<"&#L_OKL'/=J```!#IAL]P@`",JZ"(`-@*#B`"&G!^"``&@.#* +M(((/```""5`(0O"!P`8(8!(-V0'`!,%2(```P+A@P`+``AQ",`/!`1P",")X +MC""_C@OR#PB0``\(D`$*<`;P!-@$\`78`O`!V`,<`C``P0'8R@Y@!__:R@G@ +M"@W`E@Y`!TH,H`>I<(#@D`VB!\H@0@/IIGH+``%1!N_OKL#QP*G!BW"2#R`2 +M"=D`P)GH`<'/``(RK`(_J +M"J`'.G``W0KP=@A/_](-8`&I<&8/K_JI<`'E4PW5%P#`N7CW"!Z``<$,Z=\) +M4(`="9``SW```+,39@X/\._Q"@U@`:EP.@A/_^GQ`=@:<,]V@`!`%0"N$0W1 +M$](*K_H`CT(-;_H*<`#8`*[7\0"/,G#(#&('RB!"!#8(3_BN"0`!?03O[Z+` +M\<#/<8``@,$HB>;)">D:#R`"`=D!V,(-X`X"V03P"@\@`@+9T<#@?O'`SW"` +M`%#%^@P@$HHA"0AJ"0`!T<#@?O'`SW!%`.`CX@P@$HHA'P7/<$4`H"LPB++A +MRB")#P``_BJT#0GP/@D``='`X'[@>/'`[@S@#N'%\@S@#@AUSW%%`$@T`Z'/ +M<*```"`;@+)]N&`!X`*A*'#*#^``BB$,#/4#S^_QP+H,X`[AQ;X,X`X(=<]Q +M@``0R!:ASW"@```@&X"R?;A@`>`5H58A@`*6#^``R-G!`\_O`-C]!.`."''Q +MP.'%PLD(Z-?)@;C7&ABP`=T#\`+=SW)$`'B[)(H"V$H,H!)#@C8+H`X`V(+E +MF`DB#!Q"\SW#% +M[H1U`=F%>AX.(!*8=<]V1`!XNR2.`-CZ"Z`20X;"R;CH^@X`#066AB!_#(;H +MU\F&N-<:&+`DC@#8`O`!X/\)`8#FR<]Q1`!XPAFA`=["&IBSPQI8L\]Q`P`P +MML]R`P`8J\]S`P!(IV(.;_C)<,EP;@D@#@Z#V`-#-@+\*H.0`+)<`X* +M;_C)<07P3@K@!@W8P0+/[^!X\<`^"N_O#-FCP8MP2@L@$AIP`Q2","D*$PC/ +M<(``E"@!@![H!A2#,`(4@3`1"[,!`12`,`D)4P(E"!($!A2`,`$4@3`(N`5Z +M`A2`,!BY$+@%>I/8C;CN"R_P17D#%($P+\A4:5A@,!("-L]U@0"`=A0B40`A +MPH#B-GW,\AD*4`""XLCT`A2",``A@`^``.0H0*C#\`44@C#/=H``E"@2ZF"` +M08!%>T*``X!E>@4@OH#*(((/``"4`(@+(O#/(&(#`Q2!,,]WH```,!)IQW"@ +M```O-!`$`#08@`\(`````-L`A@\C0P!K>$;R!12",`;JK@R@#0IP0/`Z%P"6 +M2B5``&1X$',!%(PPPB5!`0(4@#`$O(5X`!$,(3AZD7`!W,(D`1.;?`4D0!&2 +M%PR6A'M0@84@S!3)(`` +M$',!V,(@`0`$N`4B`H#*(((/``"5`-P*(O#/(&(#`Q2#,`#:`(8/(L(`17@! +M%($P`*85)D`0A(`$N45\A*`"%(`P`".,#X``Y"@&%(,P`*QU?GR&)7A%>WRF +M.A<#EF5Z.A^8D``9!"`%%(`P`Q2!,#AXDA!!SRB""#P``D@#T"2+PSR!B`SX-H!)DV+X) +MH`T&%(`P!A2!,`*YQW&@```N2(&@@2_H0"(`!+%RJ7;*(04@RB&&("/P!A2, +M,%,FSQ!V;,=S@0"`=/5[`(,#%((P!""`#Q\````PN"$*`0!`+0$2!2%!!!"_ +M8(,0O,]P``"=(>5YC@DO\(5Z`>:_#D24"G"V"^``!-G%!Z_OH\#QP%X/C^]* +M(``HSW6@```@.QT8E``6`$#/=J```!00I@`6#T"`Y\H@@0\``"PE,`DA\,HA +MP0/JIDP=V),#V!.F`=A+'1B0/!T8E*(,P`!Y!X_OX'CQP`X/K^\1V<]V@0"L +M-[(((!+)<"Z&SW6``.S)$VD5>`)EZ;K*(((/```S)>0(`O!`AL]W@``0WVZ& +M?0K?`@"'E.@3:Q5X`&7^N,H@@@\``"@EP`@B\,HAP@`!V`"GSW*``!3?;H8+ +M\,]R@``4WR""$VD5>`!E"PB?!V"B"O`P<\H@@@\``#4EB`@B\,HBP@!.AA-J +M%7AP($$#GKD@H"V&A.',(6*!RB""#P``-"5D"`+P#_`#NW5[<"7`$/_9OK@` +MI0#8`*?/<(``%-\@H,H+P`"I!H_OX'CQP!(.K^\"V:C!W@_@$8MP!!27,``4 +MD##/`MC$0M.`P`E@!^!`-A$-GC@J!#8 +MN'AK>`CR`"6`'X$`V$0V>.2H$")"`.#Q*@K``,$$K^^HP/'`C@R/[P((8`>A +MP8'@`=TF"&`'PB5!$PAQG@S@":EPY@\@!PAU1"U^%"]UAN@`)8\?10",+@;P +M`"6/'T4`?"^+=LEP`@[@$0'9U@\`!^H/(`02O[Z'`\<#AQ:3!BW6I<(H-X!$,V2(/ +M3_H*#\`)%@Q@!ZEP`=A#P(/`.@C@``39@@Z/^7X-3_D&#F_Y`-A2#T`!502O +M[Z3`X'CQP*'!BW!^#>`1`=D`P<]P@`"4ED8)X``QL*'`T<#@?O'`M@NO[V3: +MN<&+=L]Q@`!$Y#8/K^_)<,]S0````$##SW`&``"`SW6``'A4((5!P`"!SW*` +M`#C>>&"`(`@`0()$P'IB3\(E@5+`4,$`V@SP6WE#<681`P+M"A2"4<``V@OP6WE#<6X1`P+O"I2!&@H``2"%!>@` +MP$+``(%#P`*!3<`#@4[`R7!:#Z``9-F!`Z_ON<#QP`8+K^]$VK'!BW?/<8`` +M6.6*#J_OZ7#/=4````#/<`8``(!!P,]V@`!X5`"&0,4`@+A@@"`(`+H)(`%$ +MP`?H`,!"P`"&`(!#P`#9"?`[>$-P9A`"!Q)I@W!%H`'A\PD4@B"&`H%-P`.! +M3L#/<(``.-X`@+A@3\`%@5#`Z7#2#J``1-GM`J_OL<#@>/'`X<6WP8MP(@S@ +M$1?9@\#/=8``++^I<78/X`Y0VH'`5B6!$VH/X`X(V@#`02@!!!!X-:41"%`` +M$PB0`(/@Y`B!#@?PY@B`#@/PM@B`#K8/@`"E`J_OM\#QP`(*K^\+V:O!R@O@ +M$8MPSW"``%@5`(`DP@SH&!0$,`#8EKC/<:#^J`?Z#J`$!<,DP%,@SP!$N%,@ +MEP`3#S,4`<&*#:`#*'`!P1,(4`#/<```$#32"^_O),($%)0PSW"``"`[0"`5 +M`D`@$`>*(`D/!"P^(%IP,"5-+A-O(,$*(8`O@`#LR14@%@``(8XE`(:K"1\` +M$0A?`G/8C;CI<8H+[^\%P@#9)!Y"$"JV/]@+MDIP!"P^((7E-"!`+LPEXI$% +M]">X"K8KM@[P'0T1$D$H`0,HN`=YP[DD%``Q!;DX8,BX"K8"P.ER`\%`)H,6 +MQ@D@#PHD``4O(`>@'_**`"FZ7`R#&_SBG$!W0GP`MT'\.FX`=W*)2(22B``(('E +MY_0N#6`)Z7`D%``Q#+9*<`0L/B`P)4$N`!83$`7`!L(;"1$"%PH>`D$H`0+` +MN4$KPR'`NW!QT"(B`J>Z1L*GN$7`!B.!($1X!7D@IA<+'B+HNV"+8+Z0$4@C"*<(#BZ7'* +M(N$'L@^`!:(+[_L`)D`D(,`)"!\`#0@1(!$4@#`1"%X``A0!,2:VV@Y@`>EP +M$12`,!<('@$=%(`P`-D/(0$`+WFB#&`!Z7`1%(`P'PC>`"?!Z7`>%`(QBG.B +M"V_WBB0!`)#@RB4F$:(*H`SI<"#`$12!,`\('@`H=(8DO9\F\@06$!`*PD&F +M'0D>``0B``00_+)8:(1(`"%RB!"`,`.HA'*(>(#"?`R>`1[8:(+"QXA(((D>`"B\LDA +M"`X%K@^@!8IPC.@`AN>XRB`A`,\@P0,D#J$1RB'A`R#"BG!2(@(`Z7&"#:`% +MP+KI<+8-;_@F%`$QSW"@`(`,0!B`#P"X"`#FR0+9`!\`0*EPE@R@``':&0=O +M[ZO`X'CQP.'%L,&+=:EPC@C@$1#9SW"``%@5`(`-Z`#8`12$,):X(,+/<:#^ +MZ`>^"Z`$`A0#,08-H`VI<,]PH`"`#$`8@`\`N`@`YLD"V0`?`$`!V#8,H``( +M<@T';^^PP/'`?@YO[P'9SW"``)3F`8"CP4'`)@C@$8+`(L4*(8`O@`#LR:EP +M.@B@`@#97&U3)<\0LV^U?0`A3B,@AHH@""!^CEIPPKH+(0"$S"+!@,H@@@\` +M``EP.H[/<(``;,PV>"*0!!Q$,`"` +M`<%B#^`.Z7)*<,X,H`7I`!0+#P$0@-@`H0#8C@N@"0\@P`//<*``@`Q`&(`/ +M`+@(`.;)`-D`'P!``=A""Z``"'+Q!6_OH\#QP.'%`!8-0.;)^@H@#U,E`1#/ +M<8``+,WAO0'8RB`A`/$%;^\`H>!X\`)P(3Z7#)<58*X`XPVH+`@@F@`$39`,`9"!X`Z7"> +M"6_T,-E`)0`3E@EO]!#9A05O[[/`X'CQP.'%SW6``!PKJ7"V#J`1`=D`A3,( +ME0`$;:H.H!$!V4`E`!*>#J`1((5!A35J,'+*((X/```)1-P.CN]`)0`3@@Z@ +M$2&%5@J``$4%3^_@>/'`IL&^#*`!`-B`X,H@@@\```)$H`Z"[XMP6@Z@$0;9 +M*@J``'H.(`H`V%H.(`H!V`#`%.@1"%``%0B0`!T(T0``V`/P`=@6#4`$"/`. +M#6`$`=A.#B`*`=@`P`/!0B#`@`.YRB!B`)H/+_HN>4H.(`H!P`7`!>@1"%$` +M`=@"\`#8\@Q`!*;`T<#@?N!X\<`F#&_OBB%$!X(D!#A`),TPH@V@$:EP(<#R +M#6`"`-D:<,]Q@``@.X0H"0\#P#`A40Y6(!,*BW>#Q@IPN@]@!2'!C"##CT`D +M$C0'"(X\+"=,`$0H4!,]P``!0-,H-C^]B +MAB.&"PMD`$&&`X^%Z`(AP``5"@4`$+O/<```432J#:_O97D`$@$@F.'*((4/ +M``!8-(P-A>_/=X``K-0+A\]V@`"LTP,4@3#-"!\`@.',(6*`*?*"X8?TX[B% +M\@"&C"#_C\H@@0\``%(T5`VA[\HA`00+AP7!H[@+IP:&"PD%`$7`!X9&P*EP +M)VY.".`.BB)$!P7`!L)B<-(-;_8`(L$$8?`5"5$`$0C>`(HA_P\@IJ.X"Z#=*"(`0!<'/<$4`F#>2"*`08G'J#T``J0)O +M[X`D!#C@>/'`1@IO[QG9OL&+=?8+H!&I<`K`SW:``!S5`*:+P"1N1@^@#@[: +M0"8`'Z8+H!$BEO(-8`,@P(CHSW```&`T$@RO[P#!)(V$X&?`6)8`3*(C/A&2!;,!X2]Y"G`,?2]S +M,B+`($$)`P#/<(``@#P:8S9Z@(I2:8-R(G,V>W&3:!H$`VH:Q```W"'#S0S# +MD'-L@W/HBV@2#@&K#L"3`>2/?/7Q`^@AP(OH!"T^%`44@3``(4`N/:@&%`$Q +M+[`APAT*4@`$+3X4SW.``(`\@L`#N@`C00X:#J`.(KH$+3X4(<$`(E(N`!I" +M()G`-@U@`!39/0%O[[[`\<#AQ<]U@`"X-0`"AP-'`X'[@>);830*O[XVX\<"AP8MP_@F@$0'9`,&`X,X(H!$!V:EP=@H@"A#9ZLDY"!X%SW&@`(`< +M!!F`#\7N%W/!H0"/`:'P(X`C`:$J<`H)X!$"V0IP`@G@$0+9J7#Z".`1$-D6 +M(H`C1,`!B)#@RB"*#P``=P#/(&H#O`BJ[\HAB@.`V``FF1^``%3)`!D",`#? +MSW"``.S,%2"0`P(8Q",*)X`O@`#TYP`8Q"-C\'QIP;L!:P0E@A\"````,;H` +M*),`!<)3)=$0`[I5>GAC%7A88")PSW*```3N"&)*(D`@42#`@<]P@`!461"0 +MPB*").6XQB&"C___S_\&\H#8C;@N"(_O"0D0(``9PC,()-0D/0@0,0#`*@G@ +M!@]X%0[U(`AQ$0X0(`T.Q"0%P`D)!0!*(@`@3"(`H,H@@0\``'@`SR!A`_@/ +M8>_*(D$#`!4!(!$)G@<`$``A#R#``P`8!"`1"=X'`A``(0\@P`,"&`0@`>>U +M#Q44`L`#P?5X`"$5```5#2!!+8`3PK@R)Q8@!"6"'P```!@$);Z?``0``4$J +MP`)&Q47``=@[\NB])L&!\T$MP!#!N`'@02U#%,&[`",3`*#AS"(A@!?R"PT> +M$A,(E0`)W`J\!"4"$Q\*``,;"]4`#PN1`!,-'A(/")$`$0T>$LSAQ/9*(@`@ +M!/!*(D`@SW"``%19$)!3)9$0Y;C&(8*/___G_WCS>]B-N'+Q6G!Z<';Q!,`" +MB#(G`""!X,H@@@\``'D`^`YB[\\@8@,$P`.(,B`L,42"!X8/`>F1X)'B`X`'8P'A+>,H@@0\``*8H9`Y![P#8%:4F +M".`0/]@`P`04`3$5I0(/H!""N=6ET@E@`.8:V+.M!"_OHL#@>)T```#QP.'% +MK<&+<-X-8!$#V0'`0PA0`'T(D0`"P+H+(`,`@#CH@\6I<`#9]@@O]"C:`=AC +MP(G83,#/<*``@`Q`&(`/`!@P`*EP`,$`VLH+8!$`VR#P`L0`P0&$0(1@@-=R +MK:O^RLPAP8`,]`&0!""`#P```(!/N`D(40`%A(;H:-C*#6_OC+@"P,H*K_8$ +MX`+!`*$A!"_OK<#@>/'`H@L/[\]P@`"4*`*`,F@P(8T/H`"T+@AQ@"'"`93@ +MRB!&``*X,"".#Z``&"P`V)8(8`"8$H&P.-CF$@&VJ7)N#6_OR7/-`P_OX'CQ +MP,]P10`T./H,8!$'V#?``A=A@A"@"!01M)W#."F`1)=D!YM!^`,#I#@20E@X``#H. +M8`<`%``Q`(4`P3A@`*5M`2_OH<#@>/'`SW"``.#W9@I@$4K9;@X``-H(0!/1 +MP.!^X'CQP,]P1`"(X7X*8!%"V5(.``#1P.!^X'CQP,]P@``L^#(*8!'0V3H. +M``#1P.!^X'CQP,]P@`#$Y`"`X<``%@%``!8`0,]PH`"`#`':'0E0`$`8@`\` +MN`P`YLD`V0`?`$``'T!`*'`/\$`8@`\`N!``YLD`'P!``!^`0`#!2'``'T!` +M`MGR#2```=JAP-'`X'[QP*'!BW#R"6`1`=G2#R`!`-@`P,]S@``$WR"##P@> +M`5`A0@%$(`$(17FGN88@_0\E>)X-(```HZ'`T<#@?N!X\<`&"`_OSW"``#CF +M((`!@/@<2+!!P(MP`MV>"6`1J7$`P#7H@>!X]`#:SW"```C?0*!!H,]QH``` +M$#`9F(\`N+P!YLG/(`'P!#RN*Z]\]S@`",N@#8 +M!O``'P!#!.,!X/D(](B`@P(9&(,#V@<9F(#/<*``@!U&H$;PSW"``#3-`-_I +M<5H,[_.*(@H+SW:``(RZR7#I<4H,[_.0VNEQ`_`!X44)U0#/<(``S+HT>!08 +MA`\``/__(!B$#P``__\L&(0/``#__P#;V0L5@14C0`"*(GX`V&"$&((`?]IX +M&((``>/T\0':SW"```C?`<%!H."@"PE1`$"@!/`)"9$`H*!^#```70?O[J+` +MX'CQP.X.S^ZBP0#>X@X@`@A@$0+92@P` +M`,]P@`"H)QJ(!!0%,1L(7@`'%(0PSW"@_O0$`,($V4(/H``&%(,P!!0`,2\F +M!O`,``,`!!R$,P?P"PC2`@K8!!P$,`#!SW!$`'"1`X`3"5$`@."<"P+Y6@HO +M^:EP!/"`X(P+`OG-!N_NHL#@>/'`4@[O[ES:@B0#-9[&SW&``-3DT@DO[\EP +MBW62#*_[J7#)<-X/(!$7V0#>'L`!WT#&1\<'Z`H/H`GI`!V,(@`0"`X`'9 +MP'E6"R`!`=C/<(``C*L.#F`&`(BD%``P$>BH%``P2L"P%``P3,"L%``P5<"T +M%``P6,"X%``P6<"\%``P5L9:P,@4`#!)QUO`S!0`,$C'7,#0%``P7`L"A<04`3`#I4(A`("""B`!RB!B``"%K=D0N0&A`84"H8H*``!I +M!>_N@"0#->!^X'CQP.'%F"3+.HMPF@X@$8HAA0T`P(MU@."`)1805B7`$@?T +M@<%B""_OBB(7!0;P`-FJ">_SBB(7!58EP!+^""``BB$7!2D%[^Z5),LZ\<#A +MQ8(D`CJ+<$X.(!$9V0#`F<6!X*EPVMG`>7()[_-$VJEPR@@@`$39^03O[H`D +M`CK@>/'`H<$&#"`!`-B+/'`I,%* +M#"`!`-B`X,H@@@\```E$-`XB[\!YBW#B#2`1!-FV"0```,"$Z/()#_D9\",( +M40`!P(#@S"!B@,P@HH`$]/H)#_D-\,]P```)1`'9!?#/<```"40"V?(-#^\" +MP(;HB@D/^:3`T<#@?AL(40`#P`T(%0&&"0_Y]_'/<```"40#V07PSW````E$ +M!-F^#0_OZ_'QP+H+S^X(=L]WH```$`T7`)8H=4(@``A((`$`0"4`$A!Q$`O% +M$0=M!""`#P``_/\%((`/`+@``#`?&)#FR0`?`$`BO07P`!\`0`3F8;W[#;60 +M`(8"V08)(``!VLD#S^[QP%(+S^X(=BAW"B&`+Z```!`-$0"F&G-"(``(2"`! +M``1O>&`$X!!Q2'6H"L41`"#`(P?@!""`#P``_/\%((`/`+@``#`9&*#FR0`? +M`$`BOP;P!!8!%&&_`!]`0/OO02B!(`;P`!\`0`3E8;GY";6``(4"V88((``! +MVCT#S^[@>`/;SW*@```0!AK8@#`:F(\`N!@``MI`&H*PT!(#M@`?P$"A$@*W +M`>*A&IRP`!\`0.82`K;/<*```"``'X!``!]`0`'9):#/<8``9-<"@4"``!^` +M0`.!`MD`@"$`(``!VL]PH`"`#$`8@`\`N`0`YLD"V0D`(``!V@/;SW2@```$ +M:J3/=*````P'Z1,)4``1"9$``J0$\`BL`O`$M&>DSW"@```@`^IF&-B`.X#/ +M<(``;#/@?R"@X'CQP"(*S^[/?' +M?:5\]P^4D:;L`-\(\.Y@`1.-!`'GQWVE?/4/!)&:['BY(KGA:4`B#0,"\`SE +M%2+!`R4-11`@@L"%QWDE?"&%P8+'>25\(H7"@L=Y!21,D._S`-@<\,""((5! +M@L=YA7F!A0*_1WP%)$R0!.?[8_+U0"2"``CP26`!$XT$`>*G>25\]0J4@>;L +M`=BU`<_N\08`!6"`0($="X$`8I!"D14+@0!B@$*!#0N!`$:0!I$)"@```=@# +M\`#8X'[QP)()X`,/V`'9SW"@```=*Z".#R`%*'#1P.!^`X`$((`/(````$(@ +M`(#@?\H@8@#QP.X(S^X(=BAU`-@5"I```X4@A>VX`=C`>.VYSR!A``6F8H4# +MA4$K`09!*P($,KO`N,6YP;J:"^_XP;L#A2*X>@KO^,"X`84@A0&F(*8#A2*% +M`Z8BI@&%SW%$`'CT*+C%N!6A`(5#A3RXP;@HNL&Z6&#M`._N%J'QP`X(0`6R +M"$`%T<#@?N!X\82`[:9$H.P`-B+<@T+<@1`P(PCPXZ(]L]P10``'/`@S0"$[0'9 +M(O`;"U($CB/##\]P10"@(L]V10"T(O`@S0`)\,]V10!$'&APV@C@`9@2@;!I +M9IC+$PA#`/`E`!`%Z`"B`-D"\`+9@.&<"2+ORB`B#L]P@`!(%0"``,$2Z,W- +M!""`#P```(!/N('@S"$B@`CR!]@*N,#9&+EV"V_R.WH`P$!XV0>O[J'`X'@# +MV<]PH```!"B@,LC/EP`-@`I@7P7]B2""_OC+@!AP$'K^X`I>!X"'(S:#5Y`"&`#T0`])*%`*`! +M`-D(0`A@`]$`/2270"@`079"'(S +M:#5Y`"&`#T0`])))`*`!!]D(0`A +M@`]$`/22(0"@`0K9"'(S:#5Y`"&`#T0`])(-`*`!"=D#N!5XSW%$`!B3"&&# +MX`'8X'_`>`.X%7C/<40`&),(883@`=C@?\!X"'(S:#5Y`"&`#T0`])+1!V`! +M!MD(0`A@`]$`/22J0=@`0'9\<#A +MQ5X/[_\(=3(/[_^I<`D&C^[QP.'%K@_O_PAU,@_O_ZEP]06/[@AR,V@U>0`A +M@`]$`/22;0=@`0/9X'[@>/'`7@V/[J7!`=X`W2[P$VT5>``@CP]$`/220,?/ +M<$0`()%!P,]P1``0D4+`SW!$`!B10\``VT3#R7`'V0O:"B2`#T0`7-0*)8`/ +M@`!`)DHFP`E*#F`!^'//<0(`S"N6"*`!Z7`!Y@'EIPU4D5T%K^ZEP.!X\<#A +MQ0'8SW6B``!P11T8D"X*H!%DV$4=F)\```$/!]CL'0`0!-BI'1B0%@J@$638 +MSW"B``#@`!B`#P$`I@G/<*(``.0@&(`/`(`"`%`8@`\`@`8`$06/[O'`E@R/ +M[@AVK@^O]RAUR7`2""``J7'Q!(_NX'CU!H_W\<#AQ0AU!@T@!B]XJ@V`"Y8) +M8`2I<-X.C_<*#._W!=C-!(_NS0:/]_'`0@R/[CIP*'5(=F(/K_<:<\]PH``` +M(!N``=^B>#^X4B``@`(E@!/")\$3/[A2(`"`RB>B$"IP"G&:"6`$Z7(="%$` +M">6`Y\HA00//<(``,-@F"N`/RB&"`P7P(R``!`#8102/[N!X\<#/<(``,-BR +M"<`/1@X`!M'`X'[QP.'%SW"``(RKH(B#YEEA^6'/)@'8&1P"(`IP +M`,&I_X"B8`!9/H`!0$,&IP!2@^`0H@P`X$);ZO!@`` +M`"2X`>`%\E,@`0`X8"D-7B//<8``J.X@@04I/@``(8)_``#_#RRZ0"+#`R2[ +M`"-!!`;P%2$!(`#;:'),)`"@>?(`W!4<`B,9#5XCQ;J'X@':P'H4'((@`^,B +MNT)S!O``(@,@%!P"(W1[426`IF.[`!S`(%_R4FU5>O1ZSW.``-3N4F//T8FSA`BOA`<@",%*3YP@.4,'$`NRB#A`<`H800*\H'E`]C` +M*.$$RB#B`,`H8@7%>!`<`"`W\"S`20U>(B$(T@W`N,]Q@`#`'\`D(D0(3;@/P$F[/<8``($=<@2S!)'J&(O\.(KK`V5IY&6$3 +M\`.^''C"N,]Q@`!,[_`A```6Y@4N/A`*(,`.`>`"N$`@`04P>`C<,]P@`"@)@"`X'^&(/L/X'C/<(``H"8`@.!_AB#Y +M#^!X\<#AQ0#8SW6``*`F!@S@`0"EAB#X#VT!K^X`I<]Q@`"!XSW*``*0F!H($@""`QW$``%##\0:@#TAPX<7AQ@#;UW`$````6``N +M`,H@S@!!*($$8;E`*8($0G@"(((/!````(CA"-S*)$40:'`2\,]S@`#`)B.# +M`>`!X<*Y(Z,5(TT`((/$A<)Y(*,`V22EX0@$@]=R!`````#8RB"%`,'&X'_! +MQ>!X\<#/<(``P"80@`T(D0`2#D_V!/"F#4_VT<#@?O'`-@B/[L]PH```(!N` +MSW6``,`F-(4-"$0``B!.``?P#B&.#_____\>9A2E3@_O_\EP"'?/'"N2.E%25" +M$&2"((4$HF)Y.&``I2.X"K@RN#X/[_\-I0CH+H4982ZE"@@@$`#8SW*``!@G +M!H(.)X$?!`````2``(`989(-H`](<,D'3^[!$@&V#R$!`.!_P1I8L.!XSW"` +M`#@G'06`#^!X\<#/`_(/K^X/V(#@U`G"[M'`X'[@>/'`SW"` +M`%18`8`A"%X#T@^O[@W8"NC/<8``K,T4@36!*+A>"B_Y*+G1P.!^P1(!MA`A +M`0#@?\$:6+#@>/'`BB#_#\$:&+#/<(``5%@!@",('@//<$4`@!O/`]8.K^X,V(#@.`P" +M]0&%$PA>`\8.K^X-V(#@&`P"\0&%(0A>!+(.K^X1V`SH)@KO^`#8".A."&_Y +M$=CN#N__$=@E!D_N"0`@``#9X'CQP*(-3^X(=L]P@``TJUF(SW6``%18`87@ +MNLPA(8!*\A$('@!F#J_N`-B`X#`,`OL!A2$(W@96#J_N&]@*Z*8+S_@(Z+(/ +M+_D;V)(.[_\;V`&%%0A>!C8.K^X9V`3HF@ZO\`0H.K^X$V`GHSW&``%2"R7`Z"N_U/YD!A14(W@#N#:_N +M`]B`X,0)XO/*(((#Z@L``P&%(PA>!-8-K^X1V`OH2@GO^`'8!^AR#R_Y$=@. +M#N__$=C)<#8*X!#$$@&V-05/[O'`X<7/<(``@"<`@,]UH`"`193H,!V`'P`@ +M``$!V<]P@`!L*""@:B&``<]P@`!P*!X/X`T@H"OP&@L`#L]PH```"`*``-@- +MI<]PH```'QR`+P@?`,]P@`!H*`"`(P@>``QP'P@?`\]PH`"`13`8@`\`(``` +M`-G/<(``;"@@H&HA@`'/<(``<"@@H+$$3^[@>/'`(@Q/[L]P@`!HNB"`"B"` +M+X``G`LX$`(@2B(`(,]U@``<#!R5.F($X`)ZSW9%`+`@"!Z"%`HA@"^@```, +M3!$!(,]P@`#DNR"@:@U@"TAP"'<0&0`@=!``(,]QH```(&3@$*$!V`<9&(`0 +MV`"A')61X,H@C`3)]NEP`-D(VN()(`#)EP!MD!VJ8)(`!`)@,2!^EP"=D!VHX)(`!`)@,2"N<,V4B.'PI1!%R58FD7"X4`Z7`"VFX) +M(`!`)H,2@.#*(&$(A0-/[N!X\<`N"T_NQ9#/<44`6"`7#H`?``#__\]R10"8 +M('6*$PN3`"AP`-GN#R_S6-H>\#T.DQ(`W18AC`.BM(608;L6(0X#H*:%D'6J +MEGFCL6]\)9!WBG!Q%HK0(&$`!_(-"%X`"0Q1$*"X%JHU`T_NX<7AQL]T10"P +M(`.4SW%%`)@@C"`8@L]R10!8('6)%O06B2D(7@!WB18BP```@,]Q10#`(!2B +M%2'"``""`>``H@R!`>`,H2;P"(Q)"%$$%HE!"!X``-@$\`'@#W@U"),"&.L6 +M(@$`HI$O#5$0PY&EE&&[Z0Y!D\]S10#`(!4C#```A`'@`*0*@P'@"J,`@12B +MP<;@?\'%Q0W1D,.1I91AN[D.0)//.!^X'CQP,]P@`!( +M%0"`&>C/<$4`-#@`@"<('@(@VL]Q@`#\^4`9@@`HND$9@@`HND(9@@`HNC(( +M(`!#&8(`T<#@?N!XX'[@>,]Q@`!(%2"!".F!X(?8P'C/<8``S-8!H>!^X'CQ +MP`'9SW!$``SR(*#/<(``O-@`@`;HSW!$`!#R(*`+\,]QH```-`"!D+@`H1H* +M;_<*V-'`X'[@>,]RH```'!.B-*+@?O'`X<7/C/=8``Y!L`V):X`]FI<@HD +M@`\``/\?X@^@$`[;184&A0T*!``"(@$`&_`DA5EA`GD7\,)Y%?"*)A`0R7%& +M".`,NMH&A2*%V&`-"&0`!J4#A0:E(86,(1"`+O<`V2&E[.G=!P_NX'CQP"8( +M3^Y2#R_N*'*FP1IP3L&/PP#9"?`$X_P3#(`2:8-P@*`!X?4)A(#/<(``6!4` +M@(#@RB,"!\!XSR"B!/BW=*(4`@CO?/<*````PS@!2`#0D!`%((0`,J<`/P`-@( +MZ".&`"&`!`.F`=@&\`:&`>`&I@#8+^A3(,`D0"T!%@5Y`8;//S"T2#SW"@```@.X`!AA5Z(*(D +MA@'@"'2&),>?`>$DI@7R)88!X26FR+@!IB3!X`-@%H>!^X'CQP"(.+^X0 +MVJ3!.G"+<,]Q@``LY*H);^X:<'X(``#>#,`$0\`UZ`#>SW6@```\P*4"V2.E +M,0B1`,]W0````,EQ!?`5)TP0P*0!X<]P@`!X5`"``(`BN.\)!(#B#V_V*+_R +MI=:E!!$`(`\(@0\`@````,"?N`+PU[A`P`C;0<,&V$+`0@W@!`IPI@@@!FAP +M^04O[J3`X'[@>,]Q@`!H*`"!X[C1(&&`+/15")X`40@?`("X`*'/<*````@" +M@`#9SW"@`(!%+:#/<*```!\<@"4('P`,``QP'0@? +M`\]PH`"`13`8@`\`(````-G/<(``;"@@H&HA@`'/<(``<"@@H`8/3_$%!0_N +MSW"``%18)X#/',(:*`SR#A`(*XX0;O_P"B\@V +M#\`"`_`V#\`"T<#@?N!X\JESZ@Y@$`4D!`.,)@*0$?(?#=\2$VX5>,=P@`#LR2:0#R'"`U!Y +M1K`J"B``R7#E`P_NX'CQP'(+#^X(=RAV`-T+\!4.3A,4;Z((8`*E>)'@7`M" +M`@'E[PT4DKD##^[@>/'`X<4!V>'!0(`A@,]P@`",JZ"(A.HF#X`%"''/<$4` +M="V$+0$3D@_@"#`@0`Z+<%X/+_\$V8T#+^ZAP/'``=GAP>H2`;8O*X$/``@` +M`+NYO;GJ&EBP@(!.(X`'4R0"$!AZ1"2`$"\K@0\`(```3B-,!YAX17@%>>H: +M6+"+XX'_P&ABPX'CQP&(*+^X3>TAUBB+_#X#@RB)J`,HC"@!3 +M>#-\@.'*)@L0RB:*$,HA"P,4(<``-@LO[CMYS'B=`B_N`!U`'N!X\<#AQ8HB +M_P\3>X#@RB)J`,HC"@!3>#-\@.'*)0L0RB6*$,HA"P,\>/H*+^YX8*QX:0(O +M[B]PX'CQP-H)#^X:<`HB0*!(=VAV`=T<`",`2B$`($X@`*"*)?\?`-PZ=1IP +M`R22%!T.$Q!.)0"0`-P#)%$4"'5.)P"0`-P(=P,DCA/I<,EQT@PO[@':`"`` +MA.ER`2&!!`8++^[)>$! +M+^X`I>!X.&!9`B_N8;CQP%()#^X(=L]U@`"4*`&%*'=`)1`4,>C_V0BY!"=` +M$#!PRB""#P``H2$H"V+NRB'"`_)_[W_P((,C'O!%>2.E&O`O*,$`3B",!P#9 +M#R$!`S)X!'L`W@/P`>8=#A42SW*``.0HBF+U#H&00X71#X^31'@#I>?K10$/ +M[N!X\<`(<\]P@`"4*$`@#`0!@!3H\"3`$!4*'@`D>!T)``#/<```I"$'\!$) +M``#/<```H"&N"F_N:'+1P.!^X<7//'`=@@/[@QPO0C>!2QPN0B>`\]TJ@``!**$!]A!+0$2 +M+WF)N<]V@`!<#&:.SW*``)P+#KME>3"BSW.``*"[K:,NHR"$0!*/`)3G*Z,8 +M\@;V,0^1$B.Y&/`;#]`=[N<2]$4I_@+GO4$IP7#"(6(`!]@*\$4I_@)!*0%Q +M!O`BN03P`-D(V"ZB080OHTRCY+K*("("X;K*("$"#PJ>`03:0:Y*DX*Z2K,; +M"-$!%0FT`P?8SW*@```05(('"8``"-B'X'0(`@L=``_N`-G/<*4``!PFH.!^ +MX'[@>/'`F@_/[0AUSW:F``#`6!80$!:&*'=&(,``@;@6I@'8%*8`V!2FU@LO +M[@;8Q@S@$`K8+=@*N.EQI@L@`*ER*6\(\`QM\"#``Q4E3!``I`'AP>&Y]P#9 +M!_`)A14E3!``I`'A^0E4@E@>`!29!\_MX'CQP"X/S^T(=L]UI@``P!:%`-]& +M(,``@;@6I0'8%*7TI6H++^X&V!:%AB`#"!:E%H6DN!:E3@S@$`K8#/#/<*8` +M`-#P(,`#%2;,$\JX`*0!YXPG!)"T]RX,X!`*V`#:$/#/<*8``-3P((``%2:# +M$,JX0"@!!`"#`>(E>`"CC"($@+#W&0?/[>!X\<"F#L_M"'26E&!T`$>!_ +MP<7@>/'`X<4(=<]RIP``1!>"`*48@@&E&8("I1J"`Z4;@@2E/((EI3V")J4^ +M@B>E0"4"%)H*X`P:V06%0"4"%8X*X`P:V7$&S^W@>/'`X<4(=<]QIP``1!N! +M0"4"%`2E/($EI6H*X`P:V06%0"4"%5X*X`P:V4$&S^W@>,]RIP``1#>"(*`X +M@B&@.8(BH#J"X'\CH,]PIP``00Z`X'[@>.'%I]S/=:<``$C/$(Z`T@R2@-8,EH#:#"_`HA"*@*80CH#>#)*`X@R6@.8,FH(7J(H0@ +MH".$!/`DA""@)80AH#Z#)Z`_@RB@8!4!%BF@X'_!Q<]RIP``2,]QIP``0`;H +M`-@1HA"!@+@&\`/8$:(0@:"X$*'@?O'`%@P``'H(;_$`V-'`X'[QP`8-[^V8 +M<0AU`-D`@,]R@``H$HHG%1!UA<]V```H"H#CRB>"`\HGP0/P(@P`BB(*``/H +M`NL#V;AQSW.G``"`V'$/"-$``(-%(``&`*,%A0+H794$A03H/!4'$<*%`84$ +MO@:X!7X4A0BXQ7C/=J<``'P"IH"F$(4`W!;H"O`3A?`@#P//<*<`&'R5>."@ +M`>3O#%25#?``W\]PIP`8?)5XX*`!Y/,,5)6*(-\/$*8:E1*Y%K@$ID`O``1% +M>!NF0"U``44@``8E>)RX':9`+D`!12``!A^F%86`X(H@A0`%]!^512``#"$; +M&(`A#!``.YT`V`H(;_$H!X`-D/(0$`SW"E```0(:#/<:<``$`!@:"X@;B+N`&ASW&G``!\`H&`N`*A +MX'[AQ0RX)7C/=*P``!`!I(WJ`-H(\&*$SW"@```,8:`!XO4*1(`*\`#8!O!B +MA!4B#0!@I0'@]PA$@.!_P<7QP(H+S^W/=8``\"F@Z,]V@``T*@"&@.#*(((/ +M``#'*%@-`NX!V`"F`-@/\/0E`A`IV1*Y\"&"`,]Q1`#(DQ5Y0*$!X!!XZ0A2 +MB!CP`-@/\/0E`Q`IVA*ZSW%$`,B3\"$!`'5Z(*(!X!!XZ0A2B`#9SW"``#0J +M(*"!`\_M4]K/<:<`@(`1NAOH`=@%HD09@`]V`/^W2!F`#S\`Y"5,&8`/#@`B +M4B[8%*%8&8`/*2DI*5P9@`\``"DI&_``V`6B1!F`#W$`_^=(&8`/)P#N-$P9 +M@`_\`*#P4!F`#P``L0]8&8`/,3$Q,5P9@`\``#$QX'X[>25XSW&G``!!$*'@ +M?N!X"+@$((`/````_R]Y!7G/<*0``$0IH.!^R;A`*($")7C/<:0`@$0*H>!^ +MX'C/<:0``$2`X!"!T""B`,\@H0`0H>!^X'B`X,H@8@`3>,&XSW&G``!!$:'@ +M?@AR`\A$*'X$+W,1Z<=S10",+B6+!(L(N25X)HL0N25X)XL8N25X(8L/\,=S +M10!\+R6+!(L(N25X)HL0N25X)XL8N25X(8M=`"``P[GQP.()S^W/=:<``$#O +MA5X-8`4(=C$.`!!/)P$1B+F,N8#FS"9BD`GR)0Z1$`4G@1\``#`1#/`!YD`N +M0!(-O@5^Q7D&\%`G`1&HN:RY+Z4!`L_MX'@4>)-IE'Q`+`,5"^H5O!,(!0-` +M*0,&='LO*<$``_`O*0$``>$X>SAXSW&G`(!$$*%QH>!^$+DE>,]QIP``1!.A +MX'[@>,]QI0``@!.AX'[@>!1X+RH!``'B`[DT>12Y6'A8><]RIP"`1#*B$Z+@ +M?N!X`-K/<*<``$A-H,]QIP``1!*!H+@2H5"A5:'@?O'`SW!$`7@TO\3K9 +M@]@(N,]Q1`"\UB8-+_&@VM'`X'[@>/'`U@C/[3IP&G'2:,]UIP``1!,($"`7 +MA0HG`)#*)V(0`_#VA<"_`=B3[Q(-S^V`YF&^\?5,(`"@RB"!#P``I"C*(4$$ +MG`HA[LHBP0,`V.T`S^W@>,]P```(@<]R```.@0;P*=D2N?`A`0`!X/<*!8#@ +M?N!X\<#AQ68((``(=0HB`(#*(((/``#_%%@*(N[*(4(#R0#/[>!X\<#AQ<]P +M@`!$,@"`&N@`W1;PA"T)'P`A@'^``"`[(8`-Z0*`@^#,(&*`RB""#P``^Q00 +M"B+NRB%"`P'EUPU4D8$`S^WQP`8(S^T*#Z_Q"'8N">`$"'6`X`'9P'D)[@#8 +M@.7,(2*`RB4!$,HE8A"`Y0'820#O[/[>!X\<#A +MQ<]U@`#'*("$`&?)5C0'A%26"$`"B+W@VK8'@RB`A`'0)(0#*(0$` +M%8T!X`]Y%:T)"5$!`-@5K0'8G0>/[>!X\<`:#X_M"'4H=DAW@^#*((8/```/ +M1``))N[*(48#`KVT?<=U@`"D*L"E70>O[>&E304/\?'`SW"``"#U[!P(L,]P +M@`!(]4'`SW"``*P-0L#/<(``L`U#P`#;1,,/V`/9!-H*)(`/@`"T#0HE@`^` +M`.PJ2B:``N(/8`!*)T``I<#1P.!^\<#/<(``T"IF#,`.SW&B```(!H&DN`:A +MT<#@?L]Q@`#/'`SW$"`+SW`-C*#N__`MK/<0,`:/\"V+H.[_\"VM'` +MX'[@>`AS*'+/<(``(/7!!V``:''/<8``W+<4B?`A```#@`!X\<"F#8_MSW6` +M`*0J`-X3\/)N]'^_9R"'#.E"APF%%0H!`$!Y(8<)A4EI1G@X8`*G`>;A#M20 +M"84!X-D%K^T)I0#8`_`!X",(U0`R:#1YSW.``*0J>6%`@7;J0H$I@^D*08`! +MV`+P`-B'Z,]R@`"D*BF"`>$IHN!^SW&``-RW%(FU`2_Q\"$``,]QH@`$N`"! +M1B#`!T4@P`,`H<]QH@``N`"!@+@`H>!^X'[@>.!^X'BAP?'`SW*@`(`,0!J` +M#P`8"```'P!`*'`"V7X*[_X!VM'`X'^AP.!X!]G/'EA)*+ZZ.!^X'CQP+(,C^T(=C(2`3;/<(``]+!&($.C+$@&V`8$9 +M"%X#Q!$``,]Q@`!0,!5Y`($0X`"AA@C@#P'=^@G@!S+(R\F@&$`#R7!B""`` +M,1(!-C+(N@[@`JEQRQ("ML]S@`#LR1"*0",-!`.X%7A`(X$#&V,'DR\(4@!A +MN`>S4(H3:A5X$&&/Z`#8#R"``((+X`\?V`1Y!"$2!)7PI!0`,+BX +MI!P`,%8)K_,J<&H.(`\`V`AWSW"``!S=&G!&"*_S*G'R#R`2"G!]\&X*``(. +MAOL(%((#V!IP%:8D'L`4N@C@`"IP),)6)`$T4R+``$2ZPKI`&8(`,V@U>0HD +M@"^``.S),"1!(&3`#0E?`KX,H```V0/P_]B&)7\;Q!P`,!T-7A"@'(`_`0". +M`(\-'A&@'(`_`0"&`$'P!N^@'(`_`0",`#OP),`#N!5X<"`!!2ATAB3QGPWR +M$0E>`J`<@#\!`(L`*O"@'(`_`0"(`"3P/HC`%(`P#PA``*`<@#\!`)$`&O`! +MP`\(G@:@'(`_`0"0`!+P"L&,(?^/#_+/<*```"`;@")X$PB%#P"```"@'(`_ +M`0"'``'=@.?,)2&0%]5,E?I`%\@Z&@.!_]6<-7A`!VDIP!/`0 +M($``*.@O*P$`3B.!!RAS@"/"`93ARB-%``*[,".##Z``&"R2:3`DC!^@`+0N +MCWR1<\!ZYNK/<(``E"@`@`KH$2!`@,H@@0\``)PAR`O![0#8`_`!V(#@3?,% +M`J_M@"0#/N!X\<#AQ<]U@``8*P"%%NC:#"_V`MC/<($`#"P2#F_R#-G/<($` +MI"L&#F_R:-D`V2"ESW"!`!@L**#Y`8_MSW"@```@.X#/<(``'+S@?R"@X'CQ +MP&8)C^W/=H``$"L`AL]UH```(`'@`*9[A<]Q@````!0K((>`X@`V`*A88(" +M@@4C/H`%]`.!`>`#H0/PA+@"H@*"SW&!`*0K88("H6&A`=@#H0?P`H$!X`*A +M`8$!X`&A<@_/\`"'70A1``"&60B5``+8&@@O]B[9.X7/X6` +M@@T+!`-[A8)["/!;A0XD@Q______6V//=$0`>+NDA"J["NU&@'IB#0V%$$6$ +M"KI982*@`M@R""_V`=GA`(_M\<#/<0(`>%+/<@(`R$_/!X\<#B#T_MSW6``,#!#Y7/=X`` +M0,$`WA7H$)43Z,]PH```(#N``(<">8((+_$!V`L(E`#0M07PHQ^"$\^USK41 +M`(_MX'CQP`8*#_&%X`'8PB`%`-'`X'[@>/'`\@D/\9+@`=C"(`X`T<#@?N!X +M\_MZ7+/ +M=8``%"L`'4`4SW&````K`!F`!`#9SW"```PK(*#/<(``$"L@H.EPD@TO\&IQ +MSW&``"@@`*'/<8``""L`&0`$`=C/<8$`&"P`I@BA!8$!X/H(+_$%H0+81@[O +M]2[9SW&@```@.X$"X2*@`MB2#N_U`=G/<(``0,&B$(0`HQ"%`*`0!@$`V""% +M"'*2#R`0"',%!T_M\<"N#D_MH<'/<*```""[@-P8@`\#`$`-SW:```PK`(8` +MWP'@SW.!`!@L)H,`I@'A)J/G"E$`SW&``"P@X*'/<8``%"L@@14)40"!X`_9 +MRB&"#P``\`$$\(HAQP_/<(``*"``@"1X/@[O]`#9`=@&"F`(.G#/<(``<+<: +M<``80`3/<(``M`P`@&#'`1P",`+8`AP",,]P@`"8#0"`SW*````K`QP",`#! +M`M@N#>_U0((Z"B_V`MCZ#._P`!C`(P"&@>`\#L'P_@[/\!X(#_&F"6`(`-C/ +M<(``'+P@@`L-1!`")4`0!O`.(8`/_____[A@SW*``!2\(((3"5``SW%$`'B[ +M)8$*N1T)!0#/<(``$+R@H."B!O`#V<]P@0`,+""@\05O[:'`X'C/!_*'#@>`#9SW"``!02X'\@H$(H`@)/ +M><'AA/;:X0'9P_8`V0KI#WG!X83VVN$!V:"1(9&`X0E#!44SW&``-01E7F@D2&1[0F`@%!QRB,M`,H@30/*(DT`[_$) +M"M0`&0M1`,]Q@`#4$0F1`^@(D03PSW```%I:V@G``=4$3^WQP%8,;^V8"..)W@DCB=X)8[_ +MWB=X`""%#X``A/8`%8\`,0^`$ZX.[_]H<`T(0&1`>`! +ML0`9A`$M!$_MX'CQP.'%`-W/<(``T!&@H,]P@`"$]O_9C@AO\D%IJ7$(\,]P +M@`#4$35XH;`!X?4)%(0%!$_M"'$`W(EP!_!!DH#BRB0!$`'@%P@5!,]R@`#4 +M$15Z8)+I"<&`!?#_V(;DRB`&`^!^SW&``(2V(($G"5$`SW*``##;(((;"$`` +M`*+/L]PQ>Z"9`'9-@Z@#V5Z70-/[<]R +M@``T*R:")($@@1EA!0&@#DAPSW&``&PQ(('/<```VP[)!*_MYA("MN!XSW&@ +M`(![GIB0*#/<(``4"P`@"*X +M$'+,(N:``=C*("8`X'[@>,]Q@```5"*!`-@3"9X%];GA(,('9-C@?US8X'[Q +MP#H)``#F"```T<#@?N!X\<#AQ<]U@`!8%0"%"^@`V):XSW&@_CP#;]H&NNH( +M8`P(VP"%"^@`V):XSW&@_F@#!]H*NM((8`P%VP"%"^@`V):XSW&@_I@#<=H& +MNKH(8`P$VWD"3^W@>,]RH```?`""SW&``(2V,+@@@<.X@^'*("$`SR!A`P?R +MSW&``!#K"&$(N,]Q@`!0+`&A`((TN,.X,0A5`S,F"G"``/CB0">"@C:#?`0V@OP(-H)\`#:#R("``7P`-J,N@/P`-K@?T"AX'CQP(H(```V"``` +MT<#@?N!X`-H1\%AB%'C'<(``8"PBD&&0$+D`D"5[QW"@``!@8*`!XN4*E(3@ +M?@#8$/`98#1YQW&``&`L0)$!X#`B@P^@``!@8;$PNV*QY0B4A.!^X'@`V!'P +M&6`T><=Q@`#,+$*189$0NB"117O'<:```&!@H0'@Y0C4@^!^`-H0\%AB%'C' +M<(``S"P@D`'B,"&##Z```&!AL#"[8K#E"M2#X'[@>/'`S@A/[<]PH```(+N` +MSW:``$3]+XX*((`O@0!`-Q)I%'@P(`\@D@OO]0'8SW&``!B\(($P<`'8PB`% +M`$`@$2*JZ`:'0H<*N,]S1`!PNV"#6&!P<`P``P"EAPJ]764<\,]P@``0O$"` +M"PV$$`(E@!`&\`XB@`______N&#/+MD@BJX".L980T+10`%@@JX'64! +MV*H+[_4@AP^.`K@4>'H+X`HR(0`@`=A^#Z_U%MD(=P^.`K@4>`)PX*`Z":`* +M`,NBIP:G#XX"N!1X`"`!(`&!@+A=`&_M`:'QP.H/+^T"N5IP"B"`+X$`0#<]V1`!XNP.&`"!1(``1#R"M"%X!"!&`(,]Q1`!LP`*X%'@`89D('P`2"X`* +M>G"^#V_V2G"B@`7PQW4!``"0"B*`+T0`<+L`$@`@)88X8.T(18,&A\]Q1`!L +MNPJX((&X8%T(10`!V-8.K_46V4`KCB#4?@)V`*8FAR:@`(:BH""&`-@#H0@1 +M@"`(K@'8#@^O]0AQ"!&`(,]Q1`!PP`*X%'@08:EQ1H?F#^`/?(\!AH"X`:8& +MAPJX'64`&D`C=0C)<5H++_)%CP6%!>C_V4X++_)%CP#?"_`5(<(C((JI<$** +MH@WO\^ES`>?O?^\/@I03"Q`@SW$"`"Q;S@D@`*EP#,`6Z`K``-H.Z#(@`005 +M"8`#`84U>".(#0F``P*%\"!"`(#BP'CC(((`RB$"`%$&#^W@?N!X\<#J#0_M +MH<$*)P"0*'4:@`AT`M`A(0N`5ZSW```.D.R@]O +M[45YSW"!``!@'0@$(,]P@0``PA0`%I$0!HX<%Q`0#'E#AP`A0'0(8@#="0@`!:&'%7U&AQ7J8,$"'$(T +M!.T!C0/P_]@!'`(P!.T#C0/P_]@#'`(PBW%@>NEP)(Z2<@I8!<) +M``4!AS5X(X@+"0`%`H?P($(`@.+*($($XR""`,HA`@3_V`2N(XT3"0`%`H?P +M($(`*G!@>@IQ-PH0(`&-!*X$AR&-`-H,Z"E@%0D`!0&'-7@CB`T)``4"A_`@ +M0@"`XLH@0@3C(((`RB$"!`..@."&]0(>PA2Y!"_MH<#@>.!_)J#QP%(,#^T: +M<"AU$!&2``#>5B$/!-G)R:?/#!P`=C`>!CH:@@@!TIPSW&!`!@_%B&!!"*)'0A#`#+(SW&` +M`/2W%'D1B8;H"G"J"N_OJ7%-\`IP90@>`#8((`=*<`AR5B7`%#H.(`"I<2() +MK_2I<":'$0F>!PF'C+@)IU#8!Z)20?@!\"`````_#)IQ&-SW&``+#QPK@* +M8<]Q@`"X\?`A`0!6)143"8<4'8(@!7D&ARFG5B44$A4(7@(*VC8<*Y$P@>!<]P@`",[?0@4``&\,]P@`!\[?0@4`#+R1R0AB#_##"- +M$P@1`GH*+_8H<&39"0A0``#9`"$`!"&%$'CCN`QN<&Y.&`5\!B/1+C!N$%H!"&`#P(````QN`39 +M`"H0`!4=0B`N#*_NJ7`$\`'8&G!`E105@2`5%8`@66$X8":'';<$(;Z/`0`` +MP,H@(0OD"V'MSR`A`R\(4"!,(("@S"#BH`KR2B``("W8P@MO[8RX"G$0\,]P +M@0#8/Q8@@`0CB`?PSW"!`-@_%B"`!"*(#KD#AU4E0ATE>`.G!HP.3`^B1N2FG!"*`#P`#```XN`/9!GF"X,HA(0#9R0NY=!`"!D5Y=!A8``OP +M)H?`MR6G+Y<^'(0C*;<]EQFW*+<^%``A()/'`X<4(=80H"0_/<(``W#PP($`.P@\@#Q_9*@MO_JEP.0$/[3$#3_[Q`D_^ +M\<"R"`_M"'5$+3X7SW"``$06,"!!#@#8SW:``*S-$J;/` +M`"S-$Z;/<*4```P%@!FFE>E[$@"&$'D$((`/__\``#"XT!]`$-0?`!`4AC6& +M*+A6ABBY\@IO^"BZSW&``)P+H!&``!JFHA&``!NFI!&``*41@0`=IBX*;_@^ +MIH0M"1_/<(``*#LP($`.$PA0`6(*``.`X,PE89`%]`'8&@FO_A>F<0`O[4$? +M6!/@>/'`R@M`"A4(40#"R83H`=C1P.!^`MC^\0#8_/'QP-8/S^P(=RAV$VD5 +M>,=P@`#LR2B`HL&$*0D/SW&``*`\`"%-#D`E$!8@@$`E$1?IN`D2YP;DR($$@B;D$\#QXPK@)9<]P@0#8/]9X`H@.N"5X`*>I!^_L +MHL#@>`?9,AI8,,]PH```!"^@`!8!0.G)V!I8L"<('@+/<*```$<4&(`/```, +M#.S)!=H!X+.XM;BXN.P:&+`5N@2BSW"@`(`L,*``%@!`YAH8L)G+!>@`%@!` +MYQH8L.!^X'[@>,]Q@``H*^!_\"$``/'`W@[/[`AV*'7/<8``[,D3;15X`6'I +MNX'\`@.!XSW"``!0.!X#/<8``/`X"N!1XX'\` +M8>!X\@(A1$(5`$KV`BX\@\O[8AQ"(5I!L_LX'B$*`D/ +MSW&``"P[,"%!#L]P@`#\339XX'\`@.!XA"@)#\]Q@``L.S`A00[/<(``_$TV +M>.!_`8#@>/'`G@W/[!IP*'8RR/")22#!``&&`-VBP<$>0A-#"!\!Y@]`!,*X +M*0C1`$.&`]D.N00B0``9"$``,LC/Q&+"0@>`$=Y(Z8`)X`?@`"4 +MMJ"H(X8`&$`@D/`3;Q5XSW.``.S)`&,\N%,@4H`'],]P@0#8/_9X`8@"\*EP +MQW&!`-@_]GEDB3*.""'!``@A```:8@"6UW```.\/22+1`];W`">3'X``5,D` +M$X`@C"`"@,H@@0\``%P`Y`XA[<\@(0,`$X`@"2$1(!9OSW&!`-A`%2!`!`!A +MSW*!``!P((H(Z3R6AB'_#`D)$0(!@@0@OH\`!``!,_($((,/````&"N[Z+@# +MVLHD(A;*(>(!RB(A`$#!"`.`UE^!'F&>`DFC!18?`4D`A`E"IX& +MV&8#NQ5X=7MX8#A@SW.```3N"&,-"-X!1B+"`V&Y)7J+<"X+[_7I<0#``">" +M'X``E+83"1$@SW&```S=Z6$@J@+PH*H`&``@?03O[*+`X'CQP*'!BW&V#N`" +M!=@)Z`#!SW"``%`P%2!!``"1`O``V*'`T<#@?N!X'7D$(8$/555552)XSW$S +M,S,S!"!"`"*X!'E984$I``$X8`0@@`\/#P\/!"B`#P$!`0'@?T$I`';QP`#: +M"NA]"%``RPB0`.\(T`!(<-'`X'Y@@<]R@`#TYT$K@`/"N`IB`ID-"E$`"0O> +M`P.9SW&``%`4((%ANH#A`=G`>5MZ)7J$X@#9RB&%`-#@2/;/<(``$/+T($`` +MW/&"(`$$1"F^`R2XA^``VLHB!0`4(8!PSW&``-CQ$&',\0"!`=HNN,*XSW&` +M`/3G"&&`X,]Q@`!0%""!RB!A`(#AP'IAN!MX!7H?"A0!SW"``%@5`(`(Z`#8 +MSW&@_E0&K@_@`9:X`-K/<(``'.CT((``HO'/<(``3!1`@,]P@`"$%""``=AA +MN8#BP'@[>25XSW&``.#O]"$``([Q`=B,\>!X\<#*"N_L(GH`W1#P`-P/),P0 +M`2S/$`$HS@#D?MUE8;P$?)UE$"+"`"\L@1!.)(,7C"/_C^SU`0/O[#AE\<"2 +M"L_L"'7/<*```"#;@*H-X`PH<`(E`1`+"5(`/F8#\*)X`G[=`N_LR7#QP.'% +M`!8!0`AUV!I8L``6`D#F&IBPF,L7"!`'SW.@```$9(//<```W`Y*#`_MJ7#B +M"R`/#MF@E4DE#1D#\&8)0`'/<*````0.@/<(1(.1`L_LX'C/<(``L+C@?P"` +MX'CQP/X)S^P:<+X(K_`H=0AV'@W@#`IP1"T^%PAR(.8*<"]U`"9/'@8*K_#I +M<0/FJ&:`X,HG(1`Q`N_LZ7#QP,H)S^P(=8((K_`H=@AR`-MR"J_P?Z",&H`# +M?:*$+0D?`"&`?X``(#LB@`T)40&0&,```=@=H@$"S^SQP&8)S^RZ&G!`(!0-PJ<>@(7H=!``(`"GO?!Z=LEU.G80\`SI`<$/"Q`@ +M`B5`$`T(4@!*(T`@*'5`(4`@+R$'($<)LR!"QD0I/BW`IP':0JP*>`XJ<.EQ0-IF#T_P +M#0#O[*/`\<#B#X_L"'/'`6@^O +M[`;8V@C/]1/P@:,$CH8@_0^,(`*``=C`>(0>`!",%@$08'GI<`"%$"#``P"E +MSW6``$`M`(6E"!``+R@!`$X@CP?F#6_PZ7`!V0AV/:`_H`"(@0@1`SZFA"\) +M'\]P@`"4.S`@40XJ"N`,Z7!:<.EP*G%R#6_P2G(:<`..)6Z('@(00"8`&+(- +M;_!*B()H`\@VQH,(`XJ<`'=.?``W026"G$` +MW^ERX@F@"NESSW&``"S.'('NK@'@'*$`AL]Q@`!@%0"A`I9/C@*Q2*D)&<($ +M0"@`(06Q!);DH<]S@`"4MDIC"K%:J<]R@0`T1D*"XZ%8J0*X,""`#Z``M"[Y +MJ0NQ`=@."6`+X!D``(4%K^RI*+!\<#/`0[P$H+/=*```"`!X!*BQ!0`$`NB&X0*H@L+G@&& +M#^`-`=@!V`\(40`!PR"B`L!AH@*BT<#@?Z+`\<"^"X_LSW5%`&@A#H7Q"!\! +M((5+"5``2B``(&D)D`#1"=$`"87-"!``%H4D'0`4`>`6I0*%SW%%`,0A084! +MH02%0*$"H0>%2(5">`6A!85&A4)X`Z$H` +M`$0M!(\@I@*F!8]`)@$<`Z9DV`6F!Z9`)P`4(@@@#(3:"H4KA6?:(GAON`BF +M#(4MA2)X"J8FEP67$+DE>`:F))<#EQ"Y)7@$I@IP":8+ILEPM-F."P`+`-@` +MI0.E=@[@#02E*0./[/'`1@[`!(P@_X\'\@#9SW"``-PM(*#1P.!^X'CQP*H* +MC^PF#L`$C"#_CR_R6PI1`,]U@`#<+2*%!MBJ"2_U_]K6#"_U!M@(=@_8!J85 +MV`>F0"8!$D`E`!-^#^`+!MH`V`NF084&V`#9#@XO]0\A@0#/<8``D$8/@42- +M#R"```^A=@XO]0;8L0*/[.!X\<`Z"J_L0-H(=80H"0\`(8Y_@``@.\]P@``@ +M+J>@+8:,N@0A@`!0<,H@@@\``"(T``S"[*EP,@V@`CZ&4@E@`JEPA"T"&L]S +M@`",2@`C0@[/=(``&-H`V2=S(*,%V`2BSW`"`$2^`Z*EHD$"K^R&HO'`2'#/ +M<8``0#``&8`/K:O^RB00@0#/\""``-=P""AR +M&EP`-D`VLH+X`V*(Q\$?@G@`NEP?1U8%+X-8`+I/'`V@]/[$AW +M:':(=<]P@`!4.X0M"1\P($$.0-B,N`0A`@`0&HJ:$*0D/SW"``-P\,"!"#O+)$2!`@,H@@@`D#J(.RB'B!]((K_4(V)4' +M;^RNP/'`%@]/[!H/K_5(=J2(PPY1$(0M"1_/<(``W#PP($`.6@Z@#A_9@@N@ +M`*EP&@J@#*EPSW6``"`N(X66(0H`(GC7<`"`````V4+W(J4"A2&E%0A1``2% +M$0A1`"6E>@FO]0C8-_`BI0'>SW&!`&1&0('/=X``0-L`A\6E0*``AQS:0*@$ +M:0&G5B%``@.G&-@"IU8A``,&IP*1"B"`+X``0#!XN`6G`H&-N`*A#@Y@```0 +M`"#/<0(`:&_I<`#:2'/F#B``2B2``0`8`"#!I<:EL09/[.!XA"@""@`A@'^` +M`(Q*$02`#8()S_3@>.!XX'C@>&D@@`%O(3\`:2```/;QX'CQP!(.3^P:<`HA +M@"^@```,`-X(\!`1`B"^8;IB$!F`("-N80A$(,]PH`!@#(B(:(A(B$`J#0)E +M?=T,$9."Y!`/@N@J]$KTB(8Z\(B$6O!J\1#?(3 +MPFD';UX*K^P-V0WF$0T1%T`G`!5."J_L#=D-YA`1`2`"((`C&6$0&4`@Z05O +M[`'8\<""#4_LC"`$@(H`)@`(=8,-%!7/=X$`N"X*((`O@0`X+U8G0!0."J_L +M`MD($``A8PA1`%8G@!3Z":_L!-GI<(`@@@+N":_L`MD*$``A1PAS`6B]`K@_ +M#000`-X*\%4G0!G5>,X)K^P$V62]`>;/?@H0`"'K#@*052?`&+8)K^P"V0P0 +M`"$/"',!8KT"N`L-!1``V!?P`-X*\%4G0!K5>)()K^P$V62]`>;/?@P0`"'K +M#@*0SW&@```,!(&X8`2A`=@I!4_LX'CQP*#@"'$`V`GWSW"!`+@N.:!:":_L +M:.`!V-'`X'[@>/'`B@QO[`':C"`$@,(BC0"&X#IPM``E`,H@92`*(X`OH``` +M#&@3@"#/=X$`F"]`)U(1:!.!(`"O`H\AKQEAD.%*(``@RB".($`G%!$"WF\( +M42``W0_P]@BO[`C@`H\!Y0'@`J\"CZ]],V@U>3(B02`^9B&/1PU#$`.X%7B" +M<,X(K^P!V2*/`[DU>0`A@`^!`,`ON@BO[`39`H\#N!5X0G"J"*_L`=D"CP.X +M%7CX8"6(IPERB`;F2B``(!`3`2`"(8`C&6$0&T`@&01O[`IPX'CQP-(+3^RA +MP0AU*'9K#301`-B+<&8(K^P$V0#`UW#R!0!0'O(*]D,(@0_R`0!0J7!.""`` +MR7$A\!L(@`^:"5!O)PB!#YH34&^I<+X.+_#)<1/PJ7!B#>__R7$/\*EPU@[O +M_\EQ"?#/<:````P$@62]N&`$H0'8S0-O[*'`\)H/;^P$V62] +M`>;/?C80`"'K#@*05B?`%8(/;^P"V3@0`"$/"',!8KT"N`L-!1``V!?P`-X* +M\%8G@!;5>%X/;^P$V62]`>;/?C@0`"'K#@*0SW&@```,!(&X8`2A`=CU`D_L +MX'CQP'X*3^Q:<0#>BB$)#SIQ+'C/<8```#W6"2_V,B%0#@AW!O"Z"8`.$"=/ +M$Q;O+RC!`TX@C0<$+7X4`"&`?X``(#MO$`$&`H`E?MT($(*I<%H,[_D*<>KQ +MSW6``-0O`(7%>`"ER7"&":`.']EF#>`#2G!AN`]Y1;DU?2*%Q+@/(0$`70)O +M["*E\<#AQ:H)+_DSV!BX3R`-!)&]SW"``*SBX@@@#)*]*+A=`F_LI7C@>/'` +MW@E/['X-P`47Z)X+P`6N"L`%AQ*!,`'AAQI",!$(40`7R`3H0@L@!&#*&]@V +M#^`.`-FJ\'8+X`4!W4(,P`5F"@`+G@[`#G(,@`XV"P_^S@J@"JEP8@B`!78( +MS_06#0_^BB#%#\]VH```(`L>&)#/<(``2!4`@(WHSW&``'0R`('`N`"ASW&` +M`'`R`('`N`"AQ@T``UH*S_-Z"T_U-@P`"UH-@`$`V<]PH```$"F@W@L`"D#9 +M!=@5N""@_@G`!8((@`VN#T`-$@M`"?8(@`(V"H_U.@[``QH,S_2.",_^,@P/ +M^;8*0`/^#8_T2@[``\8,#_;N#T``$@I`"2H)(`0/V&8-C^]R"`_YM@Y`!M(/ +MS_V&"0`(#@@/_DH*@`\."D`&C@V`$(X+#_X."D`+4@_`"BX+P`&&#T`%\@]` +M"HX)@`I."8`*^@_@!0#8SW"@```P,!B`#P"```#"#0`*`]G/<*(`@&PVH,]P +MH@``@*2@`H:$N`*FP@R/](8,P`O/<```_LJ6"H_TQ0!/[/'`3@A/[+H+X`,! +MW8'@P'UN#J`-NWT`V<]RH```2,]WH`"`1,]PH`",1#B@9!J8CP@````(V&0: +M&(#/=J```$4`'H`?`$```.!X(*;/<(``E`(0>!2GSW"``!P%$'@5IS38$:<< +MV!*G,Z?/<(``2+J."J_R!HC/<(``*-L`@`4EC1\`@#R@`^@1IK"GQ@R@#0'8 +M>!^`'X````!\'X`?@````&`?@!\`1C@`;!^`'P`&&P`)`$_LX'CQP.'%4@_O +M\VHE0!$(B"R_PR'`(=0#` +M@.#*(($/```)0DP)@>P`P0&!C"#_CP7R=@PO\221`,!J#2_P(8"I<+4'+^RA +MP.!X\<`*#P_L]!P(L%IQNG(:``.S)/H^$+@D?!+F&(?X#!2$6`""'`"&8?X``(#L* +M(4`N%PE>`F\0`C;/<```PR':"*_LR7,!A0#9J@LO\3C:@<>*<*((X`OI<X`+%3 +M(,`@#+$AA0&!K;@!H2&%`8&4N`&A+08O[*/`X'CQP.X-#^ST'`BP>G$:L=R@`#LR1Z*A"X)'P2XAB#^`P4@5``@ +M@@HB0"X="5X"SW"``-P\,"""!,]P``##(<8/;^S)EPA@^@"RIQR7`B"F`"*G$`(H`O@`!$/`.E`85*(0`D`!A$!`&%!!B` +M#P`"&"``P".%A2`""0"QY@T@`LEPCK@CA8^X`;$('4`4`(4R"!T<#@?O'`Y@PO[`ARJ<&&X"AVRB4A$`GRSW````1"Q@YO[$AQ_]V+ +M<7X+(`"I<$L(40`'PA"]!L,DP"(4`3&E>3,*40#/!_"&'@>/'`8@P/[`AVSW"``#`MRF`3"C,%*'7/<(``J-/(8!4(0P//<``` +M"T+)<48.;^RI/'`X<62"2_P"'4/ +M>:X/[_^I<($$#^S@>/'`X<4`VP3P`>-O>ST+4P`4V0`C@`^``#`M(*@`W0`C +M@`^``*C3H*CA#1.5A"L+!#)M-GDG<0`A@`^!`&@@<@DO\`'EKWWR\3$$#^SQ +MP(X+#^PZ*$PHE@`^``*C3R74#\(EU`"5!!$")0"5$ +M$/)M+0IB`_9_:G`$*3X@SW.!`(@@`"=`'@AC(!"#(!$(X@`O)`<1C"##C^;U +M`>(O(H<@+R`'`4\(H@1`J!("IP!"C^!&&Y`!]"(`IP`"=2'@`B#R7I<;X/8`LD +MVHH@_P^`Y#^_O,+@0=0'8Q0(O[,!XX'CA +MQ0#:2'01\(0H"P1R;'9[SW6!`'0@)W-C90L)P0`!XD]Z`>2/?,]S@`"HTPMC +MW0L#@TAPX'_!Q?'`%@H/[`AU(@_O[RAV"'$$)8`?_P```#"X#@@@`,ER90(/ +M[/'`V@D/[%IP*'8-"3,%.G()"E(@`-A*\(0H"P02;A9X"B2`+X$`:"`G<(IW +M"B!`+OA@*G'.#F`+)-H$$1,@&_"R;K9]0"4`&0)P^&`"=?EEL@Y@"R3:%!$` +M(!<(7@$`)$$C!!G`!()U))4`(U,@`>;/?@`B@R^``*C3((O%#D*0`KDV>0`A +M``06#^_O^&``BPD(4@!AN`"K`"*!+X``,"T`B0'@`*D!V(D!#^SQP#()#^P: +M<'IQ`""2#X``J-.R#N_O`!*1(`AVL@@@``IP$':B`"8``-B$*`LDSW>!`&@@ +M0"<`$R]UH&",(,./RB"!#P```4+L"D'L$FX6>+A@^&!J<0(.8`LDV@`2@"!) +M"%(``!*"(,]^.PZ#$,]P@`!8%0"`"N@`V):XSW&@_D0'D@T@`4`A +M``FX8/A@N6'Y8;X-8`LDV@'FXO%AN@`:@B!`*8`@%GBX8$(.[^_X8``@@2^` +M`#`M`(D!X`"I`=C)``_LX'C/<8``,"T)8>!_3B$`!>!X\/'`AN`(<0#8 +M!_+/<```!$*:"4_L_]B&"\__@.#*(($/``#_``+R`X#1P.!^\<""#\_KAN`( +M=P#8"/+/<```!$)J"6_LZ7'_V,]VH```!"^&SW6``.B[[Z9""^__(*4@A2^F +MA>AO($,``O`%@*T'S^OQP.'%"'*&X"AU`-@(\L]P```$0B8);^Q(5X*[_\`V`6`#0A?`0'E\0W$D[%W2@`N`,HACB/)=3IV +M#_`O(4<$-@KO_P#8"'%`(5$@"G":"V`+)-H!Y2,-Q1.O>1H*[_\`V!IP!8#9 +M"%^!$FX6>``@`0__`-@(=A\($"`")4$4`KDV>0`A +M``?)<4X+8`LDVD(@4"`0CAT*#B`%AH8@_P.0X,HA@0______0`SA[\H@@0,! +MY;T-Q)-A!N_K@"0+-.!X\<#R#<_K>G``V(8-[_\Z__`-@(=@6`AB#_`^D($8P0CMT+#J!,(0"@/`LA +M!LH@H0'AAD`B32###064KWE*">__`-@E@`L)7@'AH`20'V)4%[^O`H,]P10"8(.!_%(C@>,]R10!8(%02@0`` +MV`?I-(+7<0\`___*(&(`X'Y!*$(!SW&``"0K\"&!`%,@`@$`V`\@@``D>$(@ +M`(#@?\H@8@`"(0(`$PZ$<`"````P<`'8PB`-``+P`=C@?N!X`B$"`!$.A'`` +M@```,'!O(`L``_`!V.!^HL%!P0#<\A(#M@3P?7L!Y"L,51$3Z_D+'H"$+`D? +M`"&!?X``(#M$@>4(@8!*D004`3'="D&``=@"\`#8X'^BP`]Y&PEU`0#:A"D) +M#P`A@7^``"`[8($+",``2'`%\`&!^PA1@`'8X'Z$*`D/SW&``"@[,"%!#@#8 +MA>',(>*!RB!A`.!^\<#AQ0'=$@PO_JEP`-D'Z,]P@`!46`20@^@H<`+PJ7!Q +M!,_KSW*@```<)((`@B1X`-F1N0<(7@0DHN!^X'[@>/'`X<7/=:```!PVA?') +MSW*@```@)'@3"%X!=Q(`AD8/C_4@V`;P#P@>`!H/@`H!V!:E(03/Z^!X\<#A +MQ<]UH```(`0=F)\@`'\`!QV8GP$`0#PZ"D`-BB`$``"E]0//Z\]QH```(`<9 +MF(\!````3!$"AD0H/@O/<(``+4XR($`.SW2``$S=+R@!`$X@@P=O>Q8DP!`` +MD!MX@+@$>C04@!!88*`9``#@?O'`+@O/ZP#=SW2``'#@J78"\`'E&0T5%,"$ +MSW>``-0)OF;#OO0GCQ/K#U^2X6X[#344X*0`W<]T@`!4"=9\H*2AI`2XAB#X +M`XFXP[D%>0J[)7O/<(``U`D4((P#8+0@X-5X0*`"\!#>,0/OZ\EPX'B)N`#9 +M`O`!X1<)%03/!_*'#/``@C`^``)@R`H0/(,```J0YV`0<@!\``(``I:X`:3@?O'`/@KOZP#9"';/ +M<(``4.4!@*+!0<`!V$#`SW>``)@R(*=')LT7Q+T4\"\H00-.((0'SW&``-@R +M\"$``?_:%.$5>4"ABW&:">_O*'(0)0T1[>U*)@``"B2``2OP+RB!`TX@C0?/ +M6<$$04`\")``R*!!29&`04D1`#[8V.#((<4XF5Y(*<5>J"B +MKWF$*0D/`"&"?X``(#M`(@$$.@GO[QCB$"9.$]CNSW*@```H`!J8@;,2`89` +M+``!AB$##(8@_`,E>+,:&(`$&H"/.@1*<-$![^NBP.!XP=G/<*```"C/D&ABB($`$.A`-FU&%B`X'[@>,]P@`"8,N!_`(#@>/'` +MG@_/_\]P@`!0+`&`SW&@```H@B`"``T9&(#/<:``@"83@8*X$Z$3@88@`PP3 +MH='`X'[QP`AQSW"``#SD`8"BP4'``=A`P,]T@`#8,O`D0!!2:51Z`"*##X`` +MF#)"@Q5\$"("`$*C1803"8$`_]DEI(MQ)@CO[RARHL#1P.!^`-K/<*```"A5 +M&)B`SW&@```D$!F`#P``_W\;V`>A2Z'@?N!XSW&@```H0Q$"AC(1`8:&(>./ +M`=@&\NNZT2*B@F"B8:(@X15Y8*'@?N!X\<#AQ0AUSW&@```D2H$B@0#8(*46 +MZG<)WP?/<(``G`L]@`K89.'F#*`.C+@,/Z^!X\<#/<8``>&,/@8?H +M`=B2#&``#Z$#\,8+``#1P.!^X'CQP!X/C^L(=L]Q@`!T60`ACP\```0*"H=` +M(1`!`-V$Z*EP%/!&"<`!_.@P((`O```H#?CH#H>,Z!"'Z0A4@58(8`#)<.[H +M`=@]!X_K-""`+P``Z`P0=A@,00#D\<]P@```,\]Q@`!X9DV!`(`?"@$`SW"` +M`/PR`("`X.$@P@<(V`N!@.#A(,('!M@'V.!^X'C/,]PHP"`5QB`X'\/>,]P +MH@``;!Z`AB#[#^!_*+CQP.8/S_\!X`]YSW*C`(!7&(*&(,,/)7@8HM'`X'[@ +M>,]RHP"`5P7H.(*)N0+P`-DXHL]Q@`#\,N!_`*'/<:(``&R`X!Z!SR`B`M`@ +M(0(>H>!^X'CQP*X(```*Z,]P@`!46`20'PB##P``#0XB"```"^C/<(``5%@$ +MD`\(@@\```T.`=@"\`#8T<#@?N!_`=CQP(H-C^O/<(``_#(`@,]Q@`!T60#= +MY&F`,]PH/[4#@'9Q@UO_:ERC06OZZEP +MX'\`V/'`X<"+<,]R``#_#,(-(`H$V:'`T<#@?O'`^@R/Z\]W@`!T6;X.[_^D +M;PAVSW"``/PRS@[O_P`0$``S"!`@5PZ4%P#>V@[O_\EP!]D`)X`?```$"C"@ +M9@@@``R0E27-$L"EH@_O_P?8)?",)L.;T_>N#N__`=@'V0`G@!\```0*,*`Z +M""``#)!Z#^__"-@N#L__`=B5)>4"(``%VO'`"@[/ +M_\]Q@`#\,B"!!>F`(`,,$'C1P.!^X'CQP-8-S__V#<__BN@>#N__`-@V#N__ +M`=C1P.!^SW"``/PR`(`$Z%X(``#X\?;QX'CQP/(+K^L(%D.Z(#CS"5AD0/R*'`0\#`F@!\``#@*^^@>"4``,":`'P``[`P0=P#8 +MRB!A`(GE&02OZ\H@80#@>/'`V@R``L]Q@`!X9H/H`=@+H0N!C^@!V`NASW*` +M``0S!H($@""`QW')`8##H@G@#$APT<#@?N!X\<#AQ<]P@`!T6:1H`""!#P`` +M!`T,B0L(40$!V`JASW"``"`S'@G@#)8E!1``V`^EM0.OZPZEX'CQP#(+K^N8 +M<0AV2'4*)8`/@`!X60"(O@\@`"")"'<5#1$1,"6`#P``'`J`X,HG(1`3#5$1 +M,"6`#P``*`J`X,HG(1`1#5$1*@W/_X#@RBV"N_]`-B`X,PEX9`/],]P +M@`"H)Q6($0C>`,]PH/[T#C8+;_T`V0'?^0*OZ^EP\<"*"H_KO@SO_PAVSW6` +M`'A9.0A1`#`E@!\```0-E.A&"^__R7`2Z,]P@`!(%0"`@.#)<`3R]@W/_PCP +MT@D@``79!/#&#L_ZL0*/Z\]R@`!T661J"+@$((`/````_P5YEB-&!R"S`"*! +M#P``A`P=@0'@X'\=H>!X\<`""H_K"'4H=UIR:'8*(8`O@`!X6;#@S"#"``Z7%*<9X(8`#)"&``"G``W1#P+R('!,EPE@WO_TIQ@>#*($$#0`_A_\HAP0,!W08/0`6] +M`:_KJ7#@>*+!\``'A9+/2%P(;!^@WO_ZER@.`$V"3R)<`FP=K@6MS,(0&#!O*P +MX,PA(8P`VQ7T`">#'P````I,DX7E!"*`#P```/](N&7`3WEFPLPE8I("\K"# +M`=O6#N__KWJ)Z%N&+R$*!%EA`>&5)\P?(*<,W"L!C^OQP.!XX'C@>.!XX'C@ +M>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>-'`X'[@>,]Q +M@`#:6%%DP(X(/```T"A#J`".,#P``Z@PP(X(/```$ +M#0"T@.+X!@$`U03/^N!^X'CQP$X(C^O/=H``>%D^"0``"'6$X,H@A@\``"8) +M*`KFZ\HA1@.$+8@9E0"OZP`A@'/QP.'%_@KO_PAU@."I<`7R$@@```/P4@@` +M`'T`C^O@>(P@PX\`V1?RCN#A(,4'P"!E`);@P"BE`.$@Q0?"("4%HN#`**4` +MX2#%!\`@)0,+"-0)*'#@?@*X@B`"`N!_@"!"!>!XC"##CP#9$?*.X.$@Q0?` +M(&4`JN#`**4`X2#%!\(@)06,($*-P_!X"PDU`P#:`(`Q\`T)E0,` +M@"*X+?`)"9$#2'`J\`L)50P`@"2X(_#`X03W`(`FN!_PX.$%]P"`*+@9\(PA +M`H0%]P"`*K@3\(PA0H@%]P"`++@-\(PA0HD%]P"`+K@'\+T.1/```+4``(`P +MN,&XX'[@>,]R@`!T621J-"&##P``Z`R5(DH`"PC!`#""%PE0`2R2,'/,((&/ +M``!:6@#8`O0!V.!^X'A`B,]S@`!X6/'`X<4(=<]P +M@`!46`20*PB"#P``___/<8``=%D$:3`@@`\``.P,E2%("@*X%'@`82BXP+@& +M\+8.S_\0=0'8P'A5!D_K"P@4";#@`=C"]P#8X'[@>/'`R@UOZT':SW6``'A9 +M0GA$*+X&0GD`(4X.C"8*F`^FZ\HAA@/I!6_KR7#QP%H-3^L:<`#=SW&``%18 +M0"$2"%4ATPY@\!0B42,`$0\A-@WO_ZEPFG!`(``A0@[O_XIQ"'8*(8"#RB%B +M`*"_Y7F3#A`0@N8!V,!X\VC/<@``_?\$(8$/``#U_T1_)7\;>`5_-@_O_XIP +M"^@$)X\?``#?_X'F`=C`>`6X!7^FOP#8#PZ0$('FT2<"Y02K,`,"\A'D*N<]T``#__00@@`\``/_Y +MA'D%>0L*WP'@N\\A8@(`&40@`>5##=2<5B(!(@Z1J;@.L0Z1JKC)!&_K#K'Q +MP'X,3^L(=@#=#O!:#.__J7`(<2(,[__)<`AQ>@VO]ZEP`>7I#=22TR($$.`"&`?T4`/"U$*3X'".!J +M#>`","!`#@AW8@_@`JEP"'86#^`"J7`(6O?;,- +M$I%A!$_KX'CQP.X+3^M(=L]P@`!T621H`""/#P``!`H`W0WK$(<7"%`"!]@0 +MIPZ'@.!<",+_J7`K\/H-C_]0AR3HSW"``#PSRV!(8$$(P@`+#E$2`@C/_Q7P +M#H<&Z`T.51$N",__#_"`X,PF89$+]!,*A`,P(8`/```$#8#@U`@!`-"G`-@% +M\/L*A8,!V-4#3^O@>/'`X<7/%DP(XP/```D"@3L`=@;\(7BS"(B@1/T +M0"@,`@0DC!\```#_EB,&!K63)7P/#$$3*AN$#P``*2GJ\3H(``#HZ`#8E0-/ +MZ^!X\<`(<\]R@`!X648-K_\`V0GH,"*`#P``0`H0<\H@0@`"]`'8T<#@?LG@ +M1-S,(0&#$O+2X%7!'W,PA`8,(\L/@3MS,(0&#S"*A@`3T`=@# +M\`#8X'[QP$X/C_\."```T<#@?N!X\<#AQ<]U@`!X63`E@A\``"0-SW"``"`S +M%+HF@%UZ)(&6)<41((&N"*`,66$!V/4";^L`I3)H-'D`(8`/@``08N!^X'C/ +M%G/<8``=%@!V)4AS@,`H3`C@`\``"`-SW*``$@S)H(4N"2!(($986$` +MH`Q(<.!XSW&``'18`-B5(%G/ +M=X``=%B+=LEPSW&``##EC@UOZQ#:`!R`-`@+U"M2,01$`AH[H +MA,+)!_:'#@>/'`X<7/=8``>&8$A0OH`-@$ +MI0R-A>",#8'_`H5V".__+(UE`4_KX'C/&#]MKA +MPO8`VK#@S"$AC`;R@.#,(2&``_0!VN!_2'#@>/'`X<7/=0``K=X!@,]QI0`` +M#`BA`=@)H<]Q@`"(%/X/X`$`H<]Q``!558#@RB!"`*$`;^O*($$#\<`2"$_K +MH\$(=0/>`8`8ON.XRB;B&,`N(A;1("*!RB;B&L`N(A:+<$`E`1@0%1(0%!41 +M$!@5$!#GA7H+;^L,VB&%R7!"A0HD@`1CA0HE0`0*)@`$Z@T@`/AW=@P@`*EP +MSW```%55#0!OZZ/`\<"N#P_K(8#H&EBP(H#J&IB_0````.D:6+#L&IB_T/X` +M`""``-\)"=$"XX``V`7=%;T+I<]VH```1Q`>@!\```P,SW"``#P?`(`*((`O +M```,#(#@,`L!`%(-``#B#```I@T@`.EP$@_``>@2`;:`X +M!Q0>`!3LR0'@L[BUN+BX[!H8L`2ESW```%55@0!`3!``4$P4`(8-"@QH,(`!C@\]P``!55='`X'[Q +MP+X.#^L(=4`@%0$*)X`O``!556H+(```WIIV>G8Z=LEQVG9:=AIV"?`#A0\B +M4B#J&ABPZ7%`)E8@F0Z5(3(E@"7W"-"/X6D`VTN-#R.#!6MZ`-K/(D(`RB(A +M`$5^2HUK>@#;SR-"`,HC(0#)"#6%!2'1(#,F`'"``,#B0"<"IP[04/Z^!X\<"Z#2_K5B!#`L]VH`#`1L]UH`#@1L]R +MH`"`1@#<"_`6(`\#(84!`BAP0=4!#Q#!22,8#/<*```$8EH`#8!_#P +M(P$``>`$&E``^0B4@`'9SW"``#P?(*#/<```557%!0_KX'@$X,]SH`"(1@#: +M!_#P(($``>($&U``^0H4@L]P``!55>!^X'C@?N!X\<#AQ?8+X`&TP2;H\@@@ +M`(MU3@@@`*EP`-IAPC_9!1Q",`8<0C`(V`<<`C`,V&+`$M@)'`(P#!R`/T[0 +MKZN*((@$1,`+'$(P"AR",$7"`@[O_ZEP404OZ[3`X'CQP,8,#^L(=AC8`:8` +MW:*F#-_FMA38![80'H0?``#_#R8-+^_)<*6F&!Z`'P\``(`!V#IP!Z8@'H`? +M`#P0``;8&G`)IHH@!``*IN"F9@SO_\EP]@PO[\EP`]@%IA@>@!_[____!=@' +MI@+?Z*8D'@`4JJ8.V`"F/@SO_\EPR@PO[\EPI::FIAP>0!2HINFFJJ83V`"F +M'@SO_\EPD00/Z^!X\<`R#"_KBB#/#[3!!!R`/Z`````('(`_'P#__PP<@#^@ +M``P$1,`4'(`_H```#$;`'!R`/Z````!(P"0<@#^@``!PBB#?#TK`+!R`/Z0` +M```P'(`_`P#__S0<@#^H````.!R`/P,`__\\'(`_H``4``#=4,51Q8H@1`!2 +MP%/`BW;V#>__R7"!P*EQC@@O\"#:'!R`/P```(!&#N__R7`%!"_KM,#QP'8* +MC_R`X,H@8@`*N`;@D+C1P.!^X'@F>,6XG[C/<:```$8&H>!^SW"@``!&"!B` +M#P`'``#@?O'`4@LOZP#98H`%VA6Z:Z+/=*``@$=@@,]RH`"01X[C"-W`?3XQ#?RB="$\HC@0#*(P(#_]HH=!#P%B!-`,:%%2-$```<@`/% +MA0'A#R2-$U!VRB1"$^4)U(#/<*```$<_@/AZ1GGX?"5\GZ!)`P_KX'BEP<]T +MH```1P*D!23"`%"D1!Q`$>!_I<"EP4#`0<$@P0$4@#`%(8$/````/Q"X!7D% +M(8$/`#\``,]PH```1BB@`Q2",`(4@3`(ND5Y(<(0ND5Y!12",!BZ17DIH.!_ +MI<#/<:```$@`&8"/@`````78%;@L&(`/`(#0``#8@1D8@(`9F(\`@```X'[@ +M>*7!SW.@``!(`!L`@`P;`($O(D@!@1N8@(`;F(\`@```X'^EP,]QH```1@"! +M12#``0"A!=@5N"P8@`\`@-``X'[/`&AX'^GP.@2`K;I$@&V&PI``!UXP+@;>$4@00'/ +M!^X'CQP#X*#^OAQ43"A<,`V@OP +M!./\$PR`%2"-`/`A#`,!XH"E!,3M"@2#)-S/`0_KX'@`V<]PH`"`'36@-J`] +MH.!^`]C/<:``@!T=H1:!12!`#!:A5!F`#Q````#@?L]SH`"`'3:#4"&"!).Z +MA.A6HP7PDKF3N3:CX'[/$"`SW&@```?7J$!@!^A +MX'[/,]QH`"`'1:!M;@6H>!^X'C/<:`` +M@!T6@;&X%J'@?N!XSW&@```X0('/<(``<#9`H$&!SW"``'0V0*!"@<]P@`!X +M-D"@0X'/<(``?#9`H`#8`*$!H0*A`Z'@?N!XSW"``'`V`(#/<:```#@`H<]P +M@`!T-@"``:'/<(``>#8`@`*ASW"``'PV`(`#H>!^SW&@`(`<&J'@?N!XSW&@ +M```>%X$%((`/-`"\)A>AX'[/<:``@!^`X!N!SR`B!-`@(00;H>!^X'C/<:`` +M@!^`X!N!SR"B!]`@H0<;H>!^X'C/<:```!X7@8.XE+@7H>!^SW&@```>%X&C +MN!>ASW"``(2V`("!X,P@(H$%]!>!M+@7H>!^\ +M*J#@?N!^X'CQP(H.S^K/<(``2!4`@*'!ZP@1`,]V@``D*`.&0"B0@&WRSW6@ +M```,[86R"Z_]BW`*(8`OH```$(/H/P\%%`"&0X9!*($`(GB?"(4`FP\4'H2& +M!H9`+P,4F&`&IA"\`,?/<*#^D`$"V85ZF@@@`.5[#@D``#GP0"#`(00@@`\` +M`/S_G;B?N#`9&*``'X!/`(#W`,]R@0`X(P/PR+DBIF2&(H;P(D``&.N`(_^/ +M.+ADI@';PB/!``'C>&``V]\+!8#P(D\``!_`0X.&`>%AO(.F`>/V\0'A`J4# +MV`>E`X8BIF&X`Z8AIBV%`(8"N`\)!0`#V<]PH`"`'2:@]07OZJ'`\``?`$"#P@#9"/`$XOP2#(`!X0`?`$,"P/4) +M!(#/<*```"`;@`(;&(`#V`<;&(#1P.!_J,#@>`#8SW&``"0H!*$#H0&!X'\" +MH>!X\/'`S@S/Z@AW*'::Q*! +M"B&`(5,@V`(3@0HC0"%3(-<"SW"@``!\!!`6`,]U@`#,U@#8&G!`)0$;]@[@ +M"D`E`AP&V`"EX:7/=Z```$4`*`-@*I<]VH```(!J&"B&`+X``2!4-I1N&#J4!$+H;I1:!'*4( +M@1VE?!V`&AZ'@!T`$(0=`!O/<(``3-<(&(`,SW>@`(`<.HB\AQP5%>26@J7!*"Z`!)MD$'X`?Q>ZGD1N&`:>I<+X-8`TG +MV2X(P`W""X_\N0//ZN!XZA("M@MZ$O+/<*```"#/Z"X1N` +M`:)3(8`$G[@!HN!^X'CJ$@.V"WL4\L]PH```(,]SH`"`'`0;@`_%[H/A&X`! +MHU,A@`23N)^X`:-!H^!^X'CJ$@RV"WP5\L]PH```(,]TH`"`'`0<@!_%[H3A +M&X`!I%,A@`24N)^X`:1!I&&DX'[AQ>H2#;8+?8AT%_+/<*```"#/=:``@!P$ +M'8`?Q>Z%X1N``:53(8`$D[B4N)^X`:5!I6&E@:7@?\'%X'CAQ>'&ZA(-M@M] +MB'0A\J)J!26-'\7N@.'/=J```"#/<*``@!RAH+N&TKFAH$`JS02E>9^Y(:`` +MW07P\"1!$R&@`>4/#840>^OP(T$#^?'!QN!_P<7QP'(*S^K/9ZI6@/(D$#"N`/(0$`)*2`V`RK%/#E>D2D +M4@B@`LEP#NCP)8`3ZW@*\LEPI@OO[@'9`-C)^#%P]%$.EN[W[DK4`@CP(/ +M),P3A*,,%800'0Q2`/2-`>?TK?2-$0]1$0#?]*U")$\`[*W@BV$/D1$S#A$1 +M[X,K"<4#[(TG#],0`>;$K0K@$"0,$`*Z0W(,$@`&A*-&X`P:&``0&A@P%O`1 +M#A,13X,)"84``>;$K2R-'0G1`!5[%X,!X(P@#XH7HP;T`-@7HPRM%*UI`<_J +M\<#^"._J`-O/<(``C*N@B,]Q@`"`-T`A``7P($X#%O`O*($#3B",!P`D@!^` +M`,0W8*@$@4`D@A(/((``16P/((``!*$0)@X3[.ZI<%X*[^X!V0#8SW+_`/__ +ML@Y@#:EQ#0'/ZO'`^@G/[L]P@`",JRH-[^X`B-'`X'[@>.!^X'C=`<_N/07/ +M[O'`X<4(=;8.8`(/>(#@<`WB[LH@0@/9`,_JX'CQP.'%SW6``(RK`(WZ">_N +M`-D@C0#84@Y@#1)ZM0#/ZO'`-@C/Z@AWT@BO]"AV#WW*#F_TJ7`(""@#O#2"L_NSW&``)0W]7D`H0;PJ7`.""`` +MZ7%5`,_J\<#J#X_J*'7/<(``C*O`B*8*[^Y(<,]Q@`"4-[5Y`*$.#F`"KW@' +MZ-%U7`SA[LH@00,I`,_JX'B*(E`(SW.``(`W)(,8>D9Y#R$!`.!_)*,`V97@ +MS"`B@,P@(H7*($(``O0!V!'HSW.``'@G(8//=(``G`N%Z0B40X1'>`"C'800 +MX#A@`:/@?L]Q@`!4%$N!`-@+H<]S@0!80"B$AH\]Q@`!<,D$$H`4`H?'` +MX<7/=8$`6$"I<*(+K^^`V0#9SW"``!!4(*#/<(``(-L@H,]P@`!<,B"@`=K/ +M<(``9,E`H"&E_]@`I<]P@`!4%'4'K^HKH,]Q@`!4%`#8"Z$!V,]Q@`!<,N$# +MH`4`H?'`X<6YP0#<"O#/Z&#3O#!*4SW.``&3)8(-2 +MP5##SW.``"#;8(-5P%'#SW.``!!48(//<(``2!4`@%/#5,*'Z(MP9-E"#R`) +MBB*/#_T&K^JYP/'`0@_/_P'8SW&``%PR;@N@!0"AT<#@?L]Q@`!4%$N!`-@+ +MH<]S@0!80"B$AH\]Q@`!<,D4#H`4`H<]P@`!<,@"`!^C/<8``$%0`@0'@ +M`*'@?O'`X<7/<(``7#(`@`SHSW6``'@G(84&Z0"%@.``#<+N`-@!I7T&C^KQ +MP,]Q@`#P-P.!)NAE$8``10A1``&!#PA1`%,1``8Y"!X`A!$``!CH'X%3(/Z` +M%/)&(,(#7Z$#V`H(H`DUV0/8L@F@"039SW"@```=.!B`#P!```#1P.!^\<#/ +M<8``\#!RBSW.``'#V%((@HX'@`=C" +M(`T``>!.#R_O:''1P.!^\<#*"F_O"'+/<8``\#!V'Q@0 +M1_`9A8#@?`IB[\H@@@,RR(/@RB3RE%O"`XLH@ +M@@\``)\SRB&"#P``[0%4#L+JR\D!@..X`]@&]!2%@>`!V,H@K@#/<8``/'`+@R/Z@AWSW6``/`X'H4H=A$(@0\``/__<@A/[Q7P +M2@A/[\]Q@`!P]N&A#]@`H12%Q*&!X`'8PB`.`!-XP;CV#2_O`N!5!(_JX'CQ +MP,8/S^Z^#F`)`MC/<8``<#CR#2```J'/<0``7(WF#V`)`MC/<0``O(W&#V`) +M`M@6#&`$`-A*"0_OQ@[/[M'`X'[@>,]P@`#P.>!_!(#@>/'`E@N/Z@AVSW*` +M`/`WSW6``'`Y`-@+"1\`%84!X!6E7A(`!A\(@`\``/__!@K`#`.E$PA0`)H/ +M#^^`V"H/[__)<<4#C^K@>/'`3@N/ZK8.``+/=H``4#C:#B`"!:[Z#B`"!JZV +M#B`"!ZX`V0\A`0`2:15X"*ZF">`$!H[/=8``\#<;I06.#0A1`&X-(``(C@.% +M$>@F""``^=BN#`_OF@L/[UH,S^ZV"4_OV@L/[PH(3^]5`X_JX'CQP-X*C^H( +M=L]U@`#P.`Z%!N@&(("##J4D"0'O#PY>$<]P@``$.HX(P`M$)KZ1#O(.A1$( +M7P'/<(``!#IV",`+/!V`'P``/SR,)L.?#O0`W0KP1"T^%P`A@'^!`"`M5@C@ +M"P'E[PT4D>4"C^KQP%X*C^H(=0HB@"K/=H``\#@2A@HC@"^``/`WTPA1```3 +M`2``V!IPO0D1`OX-S^[NACIP/>^,(@*@S"4AD"'TSW"``#P,'HCZ"Z_]"G%: +M<,]P@0"X+A&('^AJ"^``2G`;Z-X-K_Y*<"Z&%^C/<(``H$<%@",(G@"%N2ZF +M#?",(@.E!?10)\`0!O",(@*E!?10)P`1#J8.AE`@`(`.IC0(`>^'[<@3`2`! +MX<@;0"`Y"5$@SW&``'`XA>T9@0'@&:$-\!:!`>`6H83O%X$!X!>A"P\>$!B! +M`>`8H0T/'A`4@0'@%*%('@`4(@KO[JEPS0&/ZN!X\F!\``#\]`-H2;11X`""!#X``B#A`H6X*+^\!V$X6`!8="%\`SW"@ +M```@.X#/<(``!#J6(0<-U@Z@"Z6@%0&/ZO'`SW.``/`W8(,S"Q$"\=S +M@`!P.(2##PR5$1\*40!%@POJ1"@^!P`A@'^!`"`MF@Z@"X(A`P+1P.!^X'CQ +MP&((C^K/=8``\#<#A3+H916`$%T(40`!A0\(40!3%0`640@>`(05`!`DZ#^% +M4R'^@,H@@@\``($S(`K"ZB()[^X7A5^%"'8%>E^E`]A6"F`)-=D#V/X+8`D$ +MV<]PH```'308@`\`0```V@@@#``/`X52?1%1R'!"""`Q3K#NK+R:00`@#/<```GS,$(H(/ +M````$'X)[^IQV1R'Q7@K&>!RG*'`"\`#89PA0`/`A0"-?"($/``#_ +M_\]Q@`!P]LO)H*$/'`[@Y/Z@AW*'7/<8``\#!%03``8)")0``=@#\`+8*@@O[TAQT<#@?O'` +MX<7/=8``<#D#A24(40"F#(`,`Z6.Z/(2`;;TR25X+R@!`$X@@0<()[_^` +MV&$&3^K/&*'@?L]QH`"` +M'5J!$KBRND5X&J'@?N!X\<#/<*```"`;@,]Q@``4#@"A`:$`VD*A`=@'H<]P +M@`!(%0"`1*&`X,H@@0\``-@`@`CA_#@N(!VL(BC@`$ZJ8/S__W\0#8T<#@ +M?N!X\<#:#$_JSW:``!0.`H:AP0#=(NB+=0C83@]@`*EQB>@'V$8/8`"I<8/H +M!(8#Z`+8`O`#V+H,#^\`W1,($`$"N,]Q@``\#A1X!6'/<(````]>"H`+J7#U +M!&_JH<#QP'8,3^H(=\]U@``4#@*%&G$5Z`#8`Z7/=J```"`$%@"64R#^@&P, +M(>_*(&$`@.?,("&@`_(;A@&EI01/ZN!X\<#AQ<]S@``4#D*##.I#@X'BS"`B +M@`CRANG/<(``+/,`@`3H`-@'\`'=.@LO[ZEPJ7"%!$_JX'CQP,]Q@``4#B*! +M@.',(**!&`LB[\!XT<#@?N!X\<#J"T_J]1(-M@_P+RA!`TX@C@<2;D-P^Q`` +MAA`EC1,P@&!YR7#T[3$$3^KQP+X+3^KU$@VV#_`O*$$#3B".!Q)N0W#[$`"& +M$"6-$R^`8'G)"P_O^A(!MF!YJ7#Z&IBS:0-/ZL]P@`"@1P:` +MC"##CPGRA"@)#\]P@``/'`T@I/Z@AU],F,)?^?!B4. +M$,H@@0\``!,TJ`R!ZACNJ@GOZZEP],FE>/0:&+`O*($#3B"-!Z]]$FU#/(:&+`(]&9X\AH8L*4*$0`#V%'P +M!2)#`&AU$/`O+T$33B>`%P]XA"@)#P`ACW^``/0\@*<0)0T0\NT&(8T`]LGS +M&MBP!B!`@/8:&+!X"V'SRB!A`0_P+RA!`TX@CP?O?Q)O0W#[$`"&$"7-$R>` +M8'GI8\""$`RB!A`/,2`K:`XLPFHI`+\@'8^!H8L`L($"#Z +M&ABT`=@)\`;J%@@@``+8!/`V"@_O`-C]`4_JX'CQP)()3^KS$@&V"'7Y&ABP +MBNGX$@*V@N+*(((/```,-'0+@NKS$@ZV$/`O*($#3B"/!^]_$F]#"$_JHL%:%7!U`%`*&`B"`!0(A`B`O((D`UW`` +M``!``=K"(HX``^H5'P(5`"./+X``8#V6CXT,$1"$ZI.%A0P0$"L+D0`3ZL]P +MH```(%N`)88"A@JY(G@">D$J@`($X!JE2G`V#B_W(H9!\`(A0B``V03P`B(" +M!`'A"0I"!?<)E(O +M#0O1``+8%Z\$\`'8&Z47CSL(D@#2"R``2G`*V!2O%Q\"%1:/F^@BA@>%`B&! +M!0)Y#)'Q*X6_"02`"Z4T'4`4`H8GA0(@@`4B>`^ET_'@>/'`X<7V#N_S"'7/<8$` +M:"X5>0"!$"!``\D&+^H`H>!X\<`>#@_JH\%:<.X/(`H:<0AU0"H`(18@%`#/ +M<(``H$=`(!6'X``(#MD'D`5@L)*<&(.;_$*<4'``L!\'A@@"(:`X$`"`0#>#6_S*G`Z +M<$IP"G&2#>__`L([<`@6`""$X,`G@1^``&`]RB-!)1KRSW"``"SS`("'Z.8, +MS_.`X&38`_**(`\*>G#'=X``8#T7CX;H,"<`)83H%H\$Z`'8&:88%P01&!_$ +M%`N&SW+_#___*!84$!<(@``E"@`%`B`#!0`E`14">1D+10`+"@$%)!84$#`6 +M&!`X%A<0!_`T%A@0FG`\%A<0"!$!(`+``B%!!B)X+R`)`&F&`B"`#P```$`" +M(P$%+R1)$+UZ+PH%`R$*Q0`VCQT)40`9"!(`"B.`+P```"`8'X0?````(`'9 +M$_"*(?\/#_!6CQL*40`7"!(``=D*(X`O````(!@?A!\````@#0E3`#N/FPD0 +M`">&"!$`(!P>0!4"(%``Q@U@`$IP)!X`%0(@P"4`(!@P"!$!(`(@P#0"(1,` +MH@T@"DIP4R!!!00@@`_`_P```B5#$``@@@]`````<''*(84`RB$&``H@@"^@ +M```@;!``(`(@``8"\+A@_P@2@`)]2G"N#2`*I7GJR8T('@3/<:``@!P$&8`/ +MQ>Z"GVP0`"`!H009@`0X\"Z&`B,3(0(AP00NIB^&`B'!!"^F"!8!(%D)$`$- +M$($@40E0`$T($P!)"1$P!@QO\P#`2B(`("*`"!$`(`)Y!O"B>4`B0"`O(@<@ +M]PE%@PT0@B`,$(`@`"*!(`)Y`B&``#!RRB!-``4H?@,`(U,N&0L0(/H*[_,8 +M'L`4@.`\#B'SRB`A`P3P&!Y`%18?0A4!P+D#+^JCP/'`B@L/Z@H@@"\```#( +M"B*`+_\/__\`&8`/`0``D`X,[_,Z<<]Q@0!H+O`A#@`;\"\H@0-.((T'#@T@ +M"JEP"'=B#"`*J7#5N`(G`1`P<,HA!0`/"84$`!G`(UIQ&G`0)DX3Z.Z%`R_J +M"G#@>/'`X<4V#&``"'6$+0D?`=D`(8!_@`!V/8T#+^H@J.!X\<#AQ9H+[_,( +M=<]Q@0!H+A5Y`($/($`#;0,OZ@"AX'@%@`'9A"@)#P`A@'^``'L]X'\@J/'` +MV@H/Z@AVA"@)#P`AC7^``"`]`H5=")$`SW"``&`20(!0=LH@@@\``)P`SR!B +M`Z@,8NK*(8(#H@W@`1#8A"X"&@`A@'^``(Q*(X5`A1S@(GHF@"2!((&J"&`+ +M66'/<*```"`;@((+;_\!I0'8`J79`@_J\$X8`.EA"X"&@`A@'^``(Q*X@\@"QS@I@I/_P+8`J72#.`!$-AI +M`@_JX'CQP.8)#^HZ<80H"0\`(8Y_@``@/2*&&G((=P#8!.F&(?^,`_(!V(CH +MG=@BAHVXQ@MOZNERG@WO[>EPSW"@```@&X``'D`4`:8`V`.FA"\"&@`AC7^` +M`(!*%X4$@""``G&Z#R`+525`%/+)]!(!MB5X2B!`("4(S@-Z#.`!$-@0A02` +M`(``($$$D@\@"T`E`!KF"D__"G`%\!X*3_\"V`*FSW"``&`2I0$OZN"@\ER%@MOZF"#A"\"&@`ACG^``(!*S@X@"T`F`!K&#B`+529` +M%(8*3_\"A1L(40`!A<]QH```(#N!$G@980.%`>$X8`.E`H4/"!`"(X4"V.() +M;__I<@38`J6*"^`!$-@5`0_J\<"$*`D/SW"``"@],"!`#E,@?H#*(((/```4 +M-GP*0NK1P.!^\<""""_J2B%`$*+!`-Q*)``(B7,.\"\I`0!.(8('3WT`),$P +M0*D0($`##W@!XV][\^@`VOATV'09=+AT-_`R)(XPBB4)'ZQ^SW&``"`[`"%` +M#C00"P!`(0H,!2;&`L]W@`#@/.X0``=`)PL6""0,$*Q^)W<.EPL-`P`:%P41 +MK'XT(T`>""`($*Q^,")`'H#@RB$A$*Q^)W%P$0`&`>(%)P<`"X%/>@0D!`"7 +M"L*`SW&``"!'3"0`@`38RB`A`!RASW*``*!'%!J``6P90`)T&0`"$PA1$GP9 +M@`\``'$<`M@&\'P9@`\``,P,`=@>H8&R`!I$`00:P`'U!^_IHL#@>(0H"0\` +M(8!_@``@.R*`#PE0`1$)T`$`V.!^X'^($```X'^($```X'B$*`D/`"&`?X`` +M(#LB@!,)4`$3"=`!$PD0`F38X'[@?QV`X'\=@.!_'(#@>/'`X<4(<80H"0\` +M(8!_@``@.T*``-T9"A`!&0H0`L]P```6-`X)3^JI<`;P'H`$\(00``!U!\_I +M`-F$*`D/SW"``-P\,"!"#A3P+RB!`$X@@P<3:Q5XQW"``.S)@(`-#-X1!Y`) +M"%(`#R'!`!`BP@#MZN!_*'#@>/'`X<4(<80H"0_/<(``W#PP($T.@.7*(($/ +M```O-)0(0>HO+4$33B6`%PD'[^D/>`#;A"@)#\]P@`#!1D#R.``(#DRB,)`!`A@0#OZ>!_:'#@>/'`3@[/Z<]V +M@``@.\]Q``"T$JX*[^[)<`#=&/"$+0D?BB#_#X#9`"9,'@"D`"&`?X```#T@ +MJ*EP]@\@``#9J7!N"2```-D!Y=4-5)'_V<]P@`"@1VD&[^DBH.!X\<#R#<_I +M`-[)=1#PA"T)'\]P@``D.S`@0`X/"%$`;@_O_*EP!7X!Y>4-5)$U!N_IR7#@ +M>/'``-@"\`'@'0A5`80H"0_/<8``*#LP(4$.[PE1@3H/S_P#\`#8T<#@?N!X +MA"@)#\]P@`#`#:`_`!XA\*50&$*@D/SW.` +M`"@[,"-##NT(P8`!V$"A`O``V.!^X'CQP$8-S^D(=H0H"0\O=0`ED!^``"`[ +M,!``(``ECQ^``.`\!N@)V`RW+M@%\!38#+""("0F2`&&Y(*@!XD]Z +MZ0H2@3D%S^GQP`ASA"@)#P`A@'^``"`[0H`;"A`!&PH0`L]P```:-+8.+^IH +M<='`X'X^H/WQA!A``/OQ\<">#._I_]N*)`D?C'C/$;"54!C'D`)TT>?A4. +M%GCNPH7=#A&2)J*U!,_IX'B$*`D/SW"``'P\+W),8`#8`_`!X`]X&0@#`P`B +M@P^``(`\%GM@B^\)P8`#\/_8X'[QP!(,S^D(=2AV`-\"\`'G*P\5$80O"1_/ +M<(``*#LP($`.B.#,("*!\_6^#.__Z7#?#0&0X*8!V`+P`-A!!,_I\<#6"^_I +M"'&$*`D/+W8`)HT?@``@.P*%A>#,(.*!RB""#P``-32H#0+JSW"``$0\'F8D +M;D`E`!:N"&`)!MI`)H$20"4`%*((8`D&VD`F`11`)0`6D@A@"0;:[0//Z>!X +M\#,(.*!RB""#P``-S1(#2+JRB&" +M`,]P@`!$/+E@!.')<$X(8`D&VJ4#S^GQP.'%A"@)#P`A@'^``"`[*H`$(;Z/ +M@`$``&\0#080\D*`'0H1`KZY*J`*\"\I00-.(8`'K@W@!A`E#1#X[6T#S^G@ +M>/'`[@K/Z0AVB@[O_0]]@>#*(((/```*-,P,(NK*(8(#]:EP(0//Z>!X\<"J"L_I2@[O_0AV@.#*(($/```) +M-(P,(>K*(8$#]_]J7#;Z(#B`=G`>:EPZ7+R +M"F__`-O7\3D"S^F*(0D/+'C/#,(.*!#O3+R0':Q!```"QX +M`-D`(8!_@`"`/52H,*C@?N!XA"@)#P`A@W^``*`\CX,/)$P0CZ-R:$-S^Q,# +MAFN#`'OQP'H)S^D(=BAWA"X)'\]P@``H.S`@30[>"2``R7#),\@0@!T!^(+RB'B +M!^!^\<#AQ:'!"'6$X,H@A@\```/'``-CR&ABP\QH8L/0:&+`0V,()[__U&ABPI@H/^\]P@`"`#9 +M#R$!`//)X'\D>/'`X<56"^_]"'45Z!1M%GC/<8``W$<`80WHK@_/\H0M"1\` +M(8%_@`"8/0"I,@@O^*EPU0>/Z>!X\%4'K^D8I>!XA"@)#P`A@7^``"`]*!F`#_\/ +M__\L&8`/_P___P#:6QF"`(0H`@K/<:```"`[@<]R@`",2L=Q70``P.4$X`H` +M(D`.X'CQP+(.K^D(<80H"0\`(8U_@``@.\*%A>#*((8/```K-)`()NK*(H8# +M$PX0$87FS";BD0#8!/09A0+P`=CE!H_I\!XB0`@`"APX'C/,]R@`"@ +M1P."$"!``%D%8`4#HN!X`-@-\(HB_P_/<8``_$T6>4"A`-I!H0'@#WCM"!*! +MX'[QP.'%=@^O_P38SW&``$A%!-BV#F`#`MK2#&`%!-C/<(``H$>C@!X,K_^O +M>`8-8`6I<`T%C^G@>/82`;8/(0$`]AI8L`D'K_(%V.!X\<#R#:_R!=BB"6__ +M]LD`V/8:&+#1P.!^\<"&"D_]:R9`>0````#6#H_]&@X/_3X.[^D]V-'`X'X9 +M"!$!`-G/<(``;`PIH`'9SW"@```0*:#@?N!X\<`B#(_I7PB1`.X/;_(!V-X( +M(`<(=\]S@`"<"P"3`=J&(/P`C"`"@,!ZSW&!`!@RQ(G/=8$`N#(Y#M00@^K0 +MX!CTJ7""(,(&A@\O_$`C`0-T%8(0*VY9)<`40@L@">ES"/"$X,P@(H($\I#@ +M/`Y!]AT$C^GQP*H+C^E6"\_]@.!Z\L]P@``\#!Z(SW6!`+@N`-Y-"-\!8@VO +M_,EQ(@VO_!IP'NCJ"V_S"G`."D_S#W\4C1T(40"V#B`!Z7`UC3!PRB`"!-0( +M8OW*(<(#`,@1")X`0!4`$2(.8``*<=2M`!J8,TUPAB#\`XP@`X`)\DX`"0", +M(`*`*_*,(`*(//3B#,`,.NC/<$0`#/(`@+3HSW!%`#0X&8C/&\?8PE")!\]@BYSW"` +M``!-]2!``S1Y.&`0X.D"K^DEN.!XSW*``"3>()(E>.!_`++@>,]P@`!HV"D` +MP`K@>/'`2@J/Z0HF`)#/<(``;+=`@`?T`=A>"B```-DV\&T.'A``V0KPSW"` +M```N\"!``!4B3```I`'A[PD4@0#=!_``V#(*(`#I<0'EH.T`WP\G3Q,3#U`0 +MBB"$#.X+[^GI<1+PSW*````N`((HN$."4R#!`$$J``/`N`5YR0I?A`@"^'IRB!A``#9SW"``+!1 +M(*#/<(``M%$@J,]P@`!HMZH/;_,@H/$!C^G@>/'`X<6.#V_S"'43#5`0BB"$ +M#&H+[^FI<2/PJ]G/<(```%$@H"&@(J#/<:```"!;@4P1`(80>!IB#=L(\$P1 +M`(9ANQ!X&F+@>/4+4X!3(L``R!H8L$$J``+!N,D:&+"=`8_IX'CQP!X)K^D( +M##N,@:&+#)R<&D`>#!N,D: +M&+`!VDAQ#.K(R<]P@```42NH2'#A`*_IH\#QP&8(C^D( +M=RAV`-W/<0``#_\Z"F`(J7`%V<]P@`"T42"H`=G/<(``L%$@H,]P@`!HM\"@ +MSW"``&RWX*#/<(``(-Z@H,]P@`!HV/8-@`J%`(_IX'CQP.'%"'4%VL]P@`"U +M44"HSW"``"B_(*#/<(``A-C.#8`*@>7*(((/```R`>`)XNG*(4(#60"/Z?'` +MSW*``&BW8(('Z\]R@`!LMV![0(+1P.!^X'CQP+H/3^G/=8``M%$`C8SHSW$` +M``___@I@"`#86@WO_P#8?O!V">`'`MB1Z`"-SW*``&C88;@`K0:"!(`@@(`A +M@@6J#:`*2'!J\`#=3@M@"*EPSW*``"3`((+/=H``(-X`IA<)40#/<8``Q!L@ +M@07I@;@`IJ"B"B"`+X```"X`WP7P\"'``P"E`>#D_ISW*``"3>()(`W:"RSW:``"B_0(8$ZD!ZH*;M!D_I\``"3>`)<'Z,]U@`"U40"-@^@`V$GP-@C@!P'8D.@`C<]R@`"$V&&X`*T& +M@@2`(("`(8(%9@R@"DAP.?``E\]U@```42,('@`!V`#99@A@"$"%`=@(<5X( +M8`A!A0'8`ME2"&`(0H7F"6`(`=@(=L]Q```/_TX)8`@!V!X+8`P$V""7`=C% +M>=X)8`@(N0#8FKC7V:ER!-L*#N`+2B3``9X/H`$D' +MS__QP.'%SW&``*!')8$!V(<)'P#/=8``G`L@E8HB#`!$>8PA"(`T],]P@`"P +M&P"`!^@%A?((K_TFA:SH`-D"\`'A'PF5`!-I%7C'<(``$%%H@$.%[PN!@%*0 +M")7G"@&`-0F5``*50Y4#N4=X1)4U>4=X02@"`D=X#WHCNL=R@``042EBPK@- +M"0X``=@%\`<)@0`#V*4%3^G@>/'`'@U/Z2AUSW%%`&`C((%3(;Z`4O([Z*4( +M4`"=")$`SW=%`!0M"8=*($`@$"!``PFG`[VU?0`E@1]%`)0LM@AO[0#8"8=3 +M(`$`1"""`"5Z1"`!`45YAB#_#04@?H``W@_TSW"``)SAD@J`"L]QH```(`P9 +M@`\(````_!D`!``E@!]%`+@LP*@8\--MU7[/=T4`E"SY9EX(;^T`V*07`!`/ +M($`#I!\`$,(/X`"I<``F@1]%`+@L`*G-!$_ITVW5?@`F@1]%`)0L*@AO[0#8 +M[O'QP.'%SW%%`&`C((%3(;Z`./+/<8``C*L@B6D)T`#/8X/[^P`V`SPA@_O[`'8"/"`NE"K!O"@NM8+[^I0JTT$3^GQ +MP,(+;^D`V>"`SW:``%2"Z7#I!X\<`*#:_[ +MX<7/<(``5%@`@!4(7@#/=8``*.%V#*_[J7``V`&E"@@``$4#3^GQP.'%SW"` +M`%18`8`!W2,(7@#/02OZ3_8X'CQP'X*3^D(=0*`SW<``*W>X+A$#"'[RB!! +M`P.%!""`#P```/\HN':X&0C5`C,F`'"``-3B0"/'`U@E/Z00BON\("`@(SW>``)P+#?2^%X`0SW&@`(`D&+B"N!*A#X>S +MN`^G//#/=8$`K#<`A<]V@`!<#,*X`-D:<2NNSW&``.3I*8D*KBRN$-K/<:`` +M@!Q;H8+@RB`B#FP+HNG/("(#"H[/<8``4/$F@0BX)7B^%X$0&+DE>,]QH`"` +M)!*A`MC/<:```!@9H02%`J$#A0*A`H4"H0&%`J$8&0`$F0%/Z?'`X<4:"._Z +M`-W/<8``>%0@@4(((``@@>8/C_H%Z"X,K_H!W1+P^@^/^H#@`M@-],]PH``` +M/`>`".C/<(``2!4`@(3H`]@(=64!;^FI<.!X$NG/,]P@`#040"`(.C/<(``S%$`@`79%;D8 +MZ,]RH```1P""WK@`HL]RH```/&>""8(FN'A@!Z(!V`"B9Z(#HL]PH/X``P2A +MT\D+H>!^X'C@?N!XSW*@```\`-DTHB"`-*(A@"&B(H`FHH2Y)J(#@`*B`H*" +MN`*B`=@#H@"BX'[QP$((;^D0VJ3!BW7/<8``0.7""V_IJ7#V#N__`-[*"^`" +M0\"+Z,]QH```/`"!!>C`H9H-``S."0_[`\$S"9$`SW"``(@4`(`G"%$`SW"` +M`'A4`(`@@`/8#;@)(0``Y@AOZ0/9G[A`P`380<`*\`#;">D`P)^X0,`&V$'` +M`-A"P`';@>-0#^'_RB!!`P3K`\`'"-```-C/<8``S%$`H6AP$0!OZ:3`X'@$ +MV<]PH```1R2@H0```.!X\<"&#P_ISW*@```\(((!W<]P@`#042"@/.D%VQ6[ +M"X/3&ABPSW"``,Q1`(`RZ%4(T0#/=:```$:(A<]QH`"`1@`1!`#-@B`=@!\_ +M/P(_#B:`'P``0`"*)D00P*'/=J#^(`/%N,2C`-\&\!`;@`^M"_[*`><=?O`Y.#Q]\]UH```/`2%Z0@>@#D'#^G@>.!^ +MX'@(<0#8"',(\%)K0W+<$@*&`>-%>/4+E($`VIZZ.7I$>$(@`(#@?\H@8@#@ +M>,]R@`#440""SW&F```$&*$!@AFA`H(4H0."%:$$@A:A!8(7H>!^X'B8X/'` +M"-@)],]P@`#44?X*;^D8V0#8T<#@?N!XSW"``-11&-GQ!J`'BB*7#\]QH``` +M(!"A`=@'&1B`$-@`H>!^`N$P>4%I#0H%`")X$'@#\`+8SW&@```@$*$!V`<9 +M&(`0V`"AX'[@>/'`4-K/`@A`0`P>0+8!QH8@#&BX'X"X3!Y06D-"@4` +M(G@0>`/P`MC/<:```"`1H8H@&`@`H0+8!QD8@.!^\<`R#0_I"'4H=LX-+_\H +M<`JX)^W/=*```"#(%`(0"KW/($%(`@! +MV.!X\<"Z#`_I.G#/<(``2!4`@!IQ).C/=D4`H"NQC@#?`_`!YQ".-0\%$!-O +M%7C//'` +MSW&``$@5((&`XH-8`B)<`$$ +M#^G@>/'`@@LOZ8HB$`#/<:```"#@&8`/`P!`#0#=SW>@```!XX<3\',B^_!Q(ON'`X<'APN'# +M_!P(L?P<2+'\'(BQ_!S(L?P<"++\'$BR_!R(LOP'&X`BP=`"6>"<`+\@W`"P?8"KC`V1BY6@VO[`#:SW"``%PL(H8`@"MX`=C* +M)B(35/0`AA\(D0!,(`"@P'X%]+8.C_L(=H#FRB8A'47R`=A$\!D('@`F#&_\ +M(-@>#&_\BB`(`&;>.?#LN,HF@A\``'$`,_3`X"KR#?9)"!`!20@0`E4($01& +MWL]P@`!P**"`(_",(`B`'/(&]HP@!(`<]%3>&_`M"(`/````("D(@0\(```` +MSW"@``!-L(!=W@WPAMX+\#S>"?!,W@?P9=X%\&C>`_"$W@#8@>#H#H$%"@A/ +M^SH7`);)<`#9!")"))(*;^FI<]'`P<1K),`0P<1K)(`0P<2?=`04%C0$%!4T +M!!04-`04$S0$%!(T!!01-`04$#3!Q\'&P<4$%`LT!!0*-`04"30$%`@T!!0' +M-`04!C0$%`4T!!0$-,'#P<+!P<'`P<1%+'X0"B9`?L'$:R2`%,'$(""`A^!X +M"''!`2`("-CQP&X+@``(Z,]QI```1!F!H+@9H='`X'[QP$X.@``+Z$X+@``' +MZ,]QI```1!F!@+@9H='`X'[@>*'!0,`(<88A^P\E"!X"02C"`,&Z86I!*$($ +MP;IZ8C:XP;C/!\]PI@``!!J`PKA!:`OP(,($((`/`@`` +M`$2ZP;H!XC&X&'H`V(CBRB(M``;WSW.``)SQ2F,:8H#A`=G`>2#8-7A5>.!_ +MH<#@>*'!_!P(M/'`0L`$()`/````&$$HT"(7"%X#SW`<1\=Q!2D^``H@P`X# +M\$$I@``"P0T)'@)3(8(`([D&\%,AP@`BP42Y0"B#('5[5'O/04H?@Y"(8!U([C1P`04$#3@?Z'`X'[@>,]PH@``;`>`X'_` +MN/'`SW"@`(!,4X#N#\__`-F#ZBAP`_#_Z`'8T<#@?N!X\<#AQ<]P@`!45`"( +M&0A0`,]U@`!,,#(.[_P`A0`=@!^MJ_[*`0?/Z/'`A@[/Z,]P@`!45`"(*'49 +M"%``SW:``$PP!@[O_`"&`!Z`'ZVK_LK/<(``8%0`@!R($'48#.'MRB!A`+D& +MS^CQP,]Q`@"4X\]R`@"LXL]S`@"$XA8*K_$)V,]P@`"DV?H+``H`V<]P@`!D +M$B"@T<#@?N!X\<`2#L_H"8+/<8``5%0`H0]XH<$M"%$``=A`P,]R@`"DV0:" +M!(`@@,=Q!P`@H0X,(`I(<(MP!-F.#F`'8]H8\,]V@`!@5""&"=@@@<]U@`!T +M)[(/;_%`A0KH`(8@A0':`(`(VRH/[_]*)```%0;OZ*'`X'CQP)X-S^BBP2AV +M"PI0`&\+G@$`V$#`SW5$`'B[!(5`)0$60/_:SW&``*!'S0?O_T*AX'B$*`D/@-H` +M(8%_@``F/'D%[^U`J?'`D@S/Z!IPSW&!`&1&Y&E6(5,"52'-!@#>BB$)+PHB +M@"^``*`[0"(#+XKJ*G$*<"QX,"-!#H#A]`X"`""7`"'`!!KP8(V,(T.'08T2 +M]&*-T.,0]&.-[^,,]&2-C"."A@CT98T-"U$"OF("Y@(FSA0"XEUET0T$D(#F +MRB9!$`0H?B0`(E$N%1&-(%8A0`("Y;A@C"`+A,H@C0\```0R"`XMZ(0H"0_/<(``W#PP($$.!/`0(8$`+RA!`$X@@@<+ +MZ1-J%7C/EP=@A@""C:BL&+PJ(-X`C)<#`@0"--P,EPN@\O +M_B07@1#/<(``/#``&(`/K:O^RMH++^[)<`?PBW">#Z_M.-F2V$G`BW`XV=8+ +M8`>0VH0N"1\`(8U_@``@/`^-8;@/K0"%%PB1`#X*C_*'Z`^-@."`#>'QRB`A +M`U$#[^BNP/'`Y@K/Z+8+[_X(=0ARSW"``$#>\""``-=P""AR&)W+`H@;8!*'/<```"*H# +MH:6AA@P@`&:AA"T)'P`ACW^``"`\!H^,(`*`RB!"`\HA(@)`">+MRB)B`,"G +MF@P@`*EPS0+/Z.!XA"@)#\]S@`"T.P`C00[=VB=S0*L'B0?@`:E0V`*I;]@# +MJ9K8!*D)V.!_!:D"\%EA,'#^!\__`_!">1QBD7'\!\__X'\H<.!X\<`."L_H +M$@HO\AIPQ(C/=X``W$<""B_R"G`F$(``M&ZV?1<(T`#^_^#R"``P?P%@[O_\EP@.`<"0$+*0+/Z.!XO0$O[@'9X'CQP.'% +M]@WO_PAU"^B$+0D?SW"``"8\=@@@"S(@0`[/<*```!TT&(`/````(.X++_JI +M<`$"S^C@>/'`<@G/Z`AW*'8:__Z7`-Z(OMA"\)'\]P@``F/`H((`LR($`.`_"" +M"``+3"$`H,P@(J`N\H0O"1\O=0`E@!^``"8\P*@J"^_[Z7",(/^/#WD`W@CR +MF@KO^RAP@.#*)F(0"B&`@^EPRB%B``'AM@^O[0':`"6`'X``%#T`&(`$S@VO +M_NEPZ7`R#._^`=D9`<_H\<"Z",_H"'7^#.__.G$0Z/+)$2!`@XH@"0\*\@Q] +MSW"``"8\<@_@"C(@0`Z$+0D?`"&.?X``(#MO%@`6"B!`+KKH%&T6>``@CP^` +M`+Q'`(>`X,H@@0\``!$RRB%!!&@*(>G*(D$#`(;_V<8++_(!VNEPQ@RO[9#9 +M`-]`'M@3@-@`(($O@``F/`"IJ7":"^_^Z7$*((`O@``\,,8/K_P`$``@`!B` +M+ZVK_LI]'M@3L@FO_JEP:0#/Z/'`#@COZ*AP*'5$(@$#0PD1`A_HTVW5?L=V +M@`#LR2D*'@,^#\`*`(:%(`8``*8'EH#@RB`A`,\@00,P#^$*RB'A!P?P`(8+ +M"-X!I[@`IC$`S^C@>/(2`[81(P"`P'C/($(`H`;B"LHA@@`3:15XSW*``/S) +M$&+AN(P`XNW*($(`X'[@>/'`B@^/Z`AU<@D@`"AVSW&``%S;`8$#@`0@OH\! +M``#`+`FA\LH@00"$+0D?SW"``-P[,"!`#@KH]@SO_ZEPJ7#)<:8*[_\!VK$' +MC^CQP#X/C^@(=L]PH```'3@8@`\````@SW6``#PPN@ZO_`"%`!V`'ZVK_LIF +M#L`*A"X"&@`A@'^``.!*V@S`"78)+_K)<&D'C^CQP.'%2@[O[0AU&>BI<&H. +M[^TDV1/HA"T)'P#9`"&`?X``(#P@H*EP!-F:#:_M`=H`V(8,[_X/($`#-0>/ +MZ.!X\<"J#H_HHL$(=QIR.G.(=?X-[^VI<"WHA"T)'P`ACG^``"`[(X8!AT<) +M```T;39YSW"``+Q'@@[O\2!@/(;/I<`#!`<(^"2`*R7,,$`$@#!$"(%!QRB""#P``%3(T"`+I +M_@ZO[:EPA0:OZ*+`A"@)#P39`"&`?X``+SS@?R"HX'C/<8``7-O/+@%H0*"B[B,N(VX +MX'\"HN!X\<#*#8_H"@[O\0AW"'6$+PD?`"&.?X``(#MP%A`0\!X`$`'81!X8 +M$.3E9MS,(`&CRB4!%.EPF@WO[0'94R5^D,PE`I3&)>(0P"4B$>4%K^CT'D`3 +M[0%/_O'`:@V/Z#IP"B5`D,]Q@0!D1N1I5B%2`BAV2>9"D03R$0V$$,]P```! +M,E(/[^BI<:YF`)<"YJ)X`B"0@\H@A`\```,RRB%$`S`/Y.C*(H0#$0A2(``B +M02/883(*(`@*<@"7SW&``%S;PG@`MP6!A"D)+\)X!:$`V0`A@'^``-P[206O +MZ""@X'CQP,8,C^@:<]P@`"\1P`@5@"$+P(:!!Q`/@@6$1!P +M$Q<@H@VO_NEP0L`*#J_^Z7!#P"86@!`*((`_@`#@2D`F%"A%"-`'H.#8\J3@ +MY?0+"%`@`,#FN-_R3"&`L&3!H`(`#8@.#*(B$@)_+I +M<`39L@JO[0#:C"4!J2*&6/EP*G$`V\H,K^U*),``2B)`($(([_%*<`@3`"`;"!$"Z7`J<4IR2B`` +M(!(-K^T*`"#RR=<(S@/3"A$@)(W/=8``?%0`A<]V@``\,"*H +M^@JO_`"&SW$"`*CESW"``%S;`-_I`*"X!*F2#<_S-_`)C0'@":T(C2F- +M%PDD``#>Z7`J<``"`\!A>2$,]Q@``T+42/ +M.G%`H0?H3@K/\2*`!!E`(`IPL@YO[9#9529`&:H.;^WLV80M`AH`(8!_@`#@ +M2OH/@`D&'X(4;Q8`%G8)X`H?V68)P`H`V%T"K^@`I^!XSW&``$`<`*'"N,]Q +MIP"`21"AX'[/`'@#WC@?O'`T@F/ +MZ#H-``"!X`'8P'C/<8``C*L:":_SH(D(<<]P@`!4H!:0F^B.#R_JJ7`*)@"0 +M%O("O<]P@`"FH+1]L&`="%$#=@KOZ`/8"NB^"B_Z`]@6#&_S`]@"\`'>Y0&O +MZ,EPX'CQP$H)C^@(=?0<2+!!PL]Q@`"<"R"1`-B&(?P`C"$"@$HB0"`"W@OT +M`<'/^D*)8`D2B,`(`HF@"^@ +M```,"B?`)&@6`"$('`0P(L=?#1`@`=B%Y\PGXI+,)^*<`_0`V`HC`*`)%((P +M(?(!P(0H`0P`(8%_@`!,%VR)`"&`?X``[!8#NP`OS!!H@(=[:*!LB0'CP;ML +MJ0.[>'IH@&=Z2*`,B0'@P;@,J1`6$"`)%)0P8KV)#2050"=7(`(E#171=``0$@`&B`D/`1`/"A$@SW```#$10@K/Z(IP(R"`!`#!"B(`H#CR%P]1$<]P +M@``<&0J`!>C""&_Q`<"/Z``D`"00'@`@@.:&]2;P2B$`((PG0Y?*(6$@'O`! +MP,]R@`!$%H0H`0P`(8!_@`#L%B>``MLHH`'``=E$*#X'`")`#B"@(:``V"=R +MF+@1V08((`M*),`#SW>``%@5`(=,(0"@S"(BH,!^"_0(Z`#8SW&@_F`()@RO +M_9:X$]X`APSH0"T"%`#8EKC/<:#^F`@V#*_]!2+"!(/@\I@MO[4S9`=G/<$4` +M7"X@J`/81QX8$,]P@`",J^.@C"7#G\]V10"\+6P>`!0%]#H+```=I@+PO:8( +MW%\'3^C@>`#9"O#/<(``5*DV>$6`!(`!X4"@SW"``%2H=A``!ND)!(#/<8`` +MM+C/<(``,*H-!>`'!-JAP4#``A2!,`$4@#`-Z0,4@C!0(H$``KD"X>*ZPB!" +M`,`@00`/>.!_H<#@>/'`&0@S`0AQA"D!`\]P10!X+3(@0`Z(Z.MRSW````H) +M=@C/Z-'`X'[QP-H(``!"#0``T<#@?N!X\<#AQ0AU#WB$*`$#`"&`?T4`/"T\ +M$($`3H`$Z1$-@!#/<```#@DZ"._HJ7&I/'` +M&@Y/Z`AV6@D@``]X*6@O>D6ZSW6``-0O57U"A<2Y`-\/)T\02W\&\BX+3_4" +MA>9X`J7)<+(-K_T#V4D&3^@%````\<#V"^__#WAJ#$_ST<#@?L]Q@`!46">! +MA>A!*0`"P;@$\"JY4R%``.!^X'C/<(``5%@C@`'8]+G"(`$`];G/(&(`X'[Q +MP)8-3^C/<(``C*N@B,X+(`"I#0W1$#8(```)"%``R7`#\`'8 +M@."P#2'SRB!!`P8-C_V:""_PJ7`*"D`#_@@O_P'82@P``+4%3^C/<(``C*O@ +M?P.`X'CQP.'%G@[O_PAUA"T!$P`A@']%`#PM/1"!``C@1"D^!XT%;^@R($`. +MCN`!V.!_PB`)`.!X\<#AQ6H.[_\(=80M`1,`(8!_10`\+3T0@0`*X$0I/@=9 +M!6_H,B!`#O'`X<5"#N__"'6$+0$3SW!%`'LM/05OZ#(@0`[QP.'%)@[O_PAU +MA"T!$P`A@']%`#PM/1"!``G@1"D^!Q4%;^@R($`.\<#AQ<]U@`",J_H-[_\` +MC0&%_01OZ`B(\<#AQ<]U@`",J^(-[_\`C0&%Y01OZ`J(\<#AQ<]U@`",J\H- +M[_\`C0"-A"@!`\]P10![+<$$;^@R($`.\<#AQ<]U@`",JZ8-[_\`C0&%J01O +MZ`F(\<#AQ<]U@`",JXX-[_\`C0&%D01OZ`N(\<#AQ<]U@`",JW8-[_\`C0&% +M>01OZ`2`\<#AQ6(-[_\(=80M`1,`(8%_10`\+2AP/A&!`$0I/@=1!&_H)W#@ +M>/'`SW*``"#?`(+/2"C +M`-@`H@"#T<#@?N!X\<"."T_H&G#/=8``C*OZ#.__`(T!A0'>"H@*(8`OH``` +M(('@P'[;?N8+;_T/V#X9F*/6#L__SW:D``!$SW>!`(@V'0A1`,H+;_T/V!F& +M@+@9I@&/R@PO\@"O#/"R"V_]#=@9AJ"X&:8"C[H,+_(`KZH+#^Y,&9BO``!5 +M50'82QD8H(8,[_\`C4&%A"@!(\]Q10!T+3`A0`YN#R`#)(+/<(``2+H&B(/@ +M`=A"#"_PP'AB"6_Q"G`!A0:`_[B,"@'\$@P/[BT#3^CQP-()````V0OPA"D! +M`P#:`>$`(8!_10!<+5RH7:CO"12!T<#@?N!X!0```/'`E@^@`>'%>@K``N(* +M(``/V'X-;_H(=>X)3_K/<(``5((M@&Z`3R$"!('C"X#*(8(`E^C//'`7@M/_)()0`71P.!^X'CQ +MP#8)S__F"4`%T<#@?N!X\<"$*`$#`"&#?T4`7"T]BP`A@']%`#PM1"D^!PC@ +MO@GO_S`@0`X?J]'`X'[QP%X(3^BN#N__"'>$+P$3+W4`)8X?10!<+0HA@"]% +M`#PMB>C/<```!`GI<4(*K^ACN"H'-A:<"$)@``,>L]S +MH```(!N#`"5!%$H+;_PP(4$.!.@>CAVN=@GO_^EP78X`(4`C!"J^!"=P20!O +MZ`08`"#@>/'`"@LO\P3@>@T``M'`X'[QP.'%I@KO_PAUA"T!$X'@`"&!?T4` +M?"T*V,H@(@0Y`&_H`;'QP.'%SW&@`(`@R`"0#9SW"@```0*:#/<*```""[@#X+``+/=H``C*OF".__`([>".__ +M`(X!AL]W@`!$WPF(`*?/<(``2-^@H,8*[_^@CH'@`=G`>9(,+_*I@>"V"N__ +MPB:!$PAQ*@]@`LEP`QH8,%8)+_.I<`#9SW"@```0*:!:#\__G@KO_@+8-@DO +M\ZEP50/'`=@X/Z`AUSW>@```@VX>#X,H@@0\``"XP +M4`B!Z/(.K_^I<)8/``4;APT(A`,"(($#!_`.)H$?_____QEA$FU#<`P86`"= +M!B_H$!I8,.!X\<#AQ3H*X`H(=78-[_VI<)$&#^@%````\<"$*`D/SW&``"`[ +M,"%`#A'9N@BO\`#:SW&@```@.X$BH`"`6@MO\0#9<@AO\0S8T<#@?O'`9X`' +M@8AR$'/H">(*RB""`-'`X'[@>/'`SW"``$@5`("`X)0*X0?*("$`T<#@?O'` +MK@T/Z,]U@```(I18/+_$-V`#>#?`O*D$`3B*`!P]X$"$!`,(.[^TC +MI05^(X7TZ8#F$`IB\I&BP0':0J$A"QX# +M8<"$*`D/SW"````],B!`#@C90,"+`"EF@XO\1O8[@O@"@"%704/Z(3*`>!M!*`!A!H",/'`U@P/Z,]U@`!, +M5P"%+>@!A8#@RB""#P``!RRH#D+H(!6`$`#>@@XO^\EQA"@)#\]Q@``@.S`A +M0`["I<.E%]E.#V_PR7+/<:```"`[@0&E@"$'#2*@`84EA26@`84`@.();_$! +MV>$$#^C@>,]S@`!,5T"#`-D$ZD&#A.HH<`;P(((P<`'8P'C@?N!X\<#AQ<]U +M@`!,5P&%!^@`@#X(K_$!V0#8`:6I!`_HX'CQP!H,#^A:<3IRSW6``$Q7(!6` +M$`#>Y@TO^\EQ&G`$A>F%`G\`A8#@RB"!#P``"2SH#4'H!.\#A?A@`Z5)"5$@ +MQ*6$*`DOSW&``%@[,"%,#@HD@`\``-"\"-@TE4`E`AU`)0,;0"H%(4`E!A;N +M"*`,4R0'$`HA`(#*(((/```%+*`-0NCU`P_H\<">"P_H,A(#-L]Q@`#TM\L2 +M`K;/=8$`O#9T>?&)T(D3"-X!86\R$HP`PJUCK265"/`Q$HP`86Z8$0$!8JWC +MK22U`-D_#.40(Z7/<8``K,\;"-X!$($,'8`?00"#``'@$*'/<$$`@P`+\!&! +M#!V`'R$`@@`!X!&ASW`A`((`C0,/Z&(/X`$0B@AR!&UF#2_[RQ(!M@#8#!V` +M'P`@``"=N._QX'CQP/8*+^@(V0AW"B"`+T0`D)%>#^_L"G#/=40`F)&I<$X/ +M[^R`V<]R@0"X+@#>HP\0$!_P$V[/<8$`P"\5>`%A)+G.N2\K00!.(X`'#W@` +MW`\D#!#/`_`!YN$5@!#/<8$` +MF"\[#@40$VX5>!EA!8GI#P&0SW!$`)B1UGA!@`LB0(3L\P"`"R``A.CS0"$` +M`DIQ!@[O[.ERX.@!V`+P`-A]`0_HA^C/<44`."P"@0'@`J'@?L]P@0#@-(T% +M[^R*(08*X'B(Z,]R10`X+#5Z`X(!X`.BX'[@>/'`_@@OZ!#:L<$(=0#>$.#^ +M#6`'BW%`)0`8A,'R#6`'$-I`)0`3B,'F#6`'$-I`)8`30"3!.-H-8`<0VD`E +M`!R)P.4(DX`-"%(``(D#\-!^'F9!+@"4 +M_/72>!!XT0`OZ+'`\@!V%4`#^C@ +M>/'`V@_/YPAVSW"``(!4((`*@>.1'V<`EXP@!("MP3#T`9=="!$"!(]5")$! +M!8]1"!$!`Y>,(`2`(O3/<8$`X#0!@0_H0">#$X"30I$`V!$,@1!ADT.14'/* +M(&$`$.A`)P,6@)-$D0#8#PR!$$&3)9$P-X@@,]P@`!8.X0I"0\P($P.BW,*)(`/ +M`P````C8)-FIMP/'`N@[/ +MYQIPSW"``(!4`(`J@`.0`"!1`$(A#2(#V":5"[@0<0'9SW"``##?P'FZ<""@ +M,!6`$(P@PH&YP03T,16`$`?H`-D`&$`@`=BG\$`E$AQ6)!,S`-X*)(`O@0#@ +M-$`D#R8#\`'F%.<4%``@-PX%$$`E`![I<1X+[^P0VO7H`!4`(!4(4``8$H`@ +MVPA1@!D2@"#3"%&`)(<`&T`@`=@"\`#8@.!W\AC``[@5>``@C@^!`.@U*G#& +M#>__R7'7"!``.94O>"BY"+@%(0\`#@WO_ZEPOP\!$$`E`!1`@`#9B>I!@(?J +M0H"%ZD.`@.+*(6$`SW=%`'@CA.E@V2VG!_`@V`VGSW"``!CD0"O@I@!Q#:0"8`&%0G01FR"F`'!MJ>#.__ +MZ7`/>2BX"+D/>"5X&;?/<(``>-X@@,]P@`!8.X0I"0\P($P.BW,*)(`/`P`@ +M`&`4!3`(V%#9Z7(*)H`/@`"P"X8*8`Q3)`<0`=D`&$`@`-@%\`#9`!A`("AP +M=07OY[G`\<#AQ0#9SW"``&0/(*C/<(``90\@J,]P1``8DB.(SW"``&8/(*BZ +M#N_P$=@!V<]P@``8WR"@SW6``$0PD@SO^P"%`!V`'ZVK_LIE!<_GX'@!V<]P +M@`#\%.!_)*CQP*8/S_]V#6_P`-C/<(``H-\@@`#8*@BO\""!T<#@?@+9SW"` +M`/P4X'\DJ/'`SW!$`!B2`(@K"%X``=G/(/K^PXV<]Q1``8DA&)084`LA")@>#,(**`!/0!@I2X`:(2 +M@0.B3!$"`<]P@0#8/U9X0HAAA0.##KI%>`.C3!$``1"K`M@R&P(``=@:LQ") +M@>#,(**`'MK*(B(&$8E"I4)X!:5`(0`%6&!]`^_G!J7@>/'`^@K/Y\]V1``8 +MDC".`-T;"5``&PF0`!L)T`#/<````CO6#`_HJ7$&\!/9!/`.V0+P"-G/=T0` +M.)(V#Z_L0"8`&02//8^`N,&Y`KDE>`2OSW"``&8/0(@DCQ1J)7@$KQZ/)H_" +MN"5X!J\8V`>O"8\PCD\@C`&!X +M`A//<(``_!0`@!L)40`J%HP04R#-`,.\!+V\9"H>`A-$N`CPO(_#O,.]!+V\ +M9"H>`A,K'@(0&0E1`#,>PA`&V#4>`A`@A`V'@(0SW"@```@NX`0AD*. +MA2@/"CR/+W`L>@(+[^__(*@0A<]Q@`"@WX4H#PH@@4$I +M@'(&H<]PH```(!N``J$$E00H@`\/`$!"0BF`<@6A`-CN"&_P`=FQ`<_GX'CQ +MP"X)S^<(=_8+[_\H=L]U@`"@WR"%`-A^#&_P(($`V&((;_`HV0"EZ7!R#^__ +MR7%I`<_G\<#/<(``;":B"B`*"]FN"0``$@L``-'`X'[@>/'`R@COYP'9SW"@ +M`(!%6G`P&(`/`"```<]P@`!L*""@:B&``<]P@`!P*""@`-AZ<,]WH```(!"G +M$-@`I\]P@0`T2A0`?`!5F +M#L_J"=@R&A@PSW6@```(#QT8D(MP&G"Z"2`*`MD@P!,(4`'/<```:POR"2_H +M`,$$%`XQ$.Y"OI#FRB"-#P```S;8"2WHRB&-`X+`A@D@"LEQ.@M@"@IP!]@/ +M'1B0?@CO^C(:&#"8$H&PC"%"@@(7H\@SO\@#8Z@KO\@#8">A> +M#R__J7!V#X_RB@[O\@IPX@BO\T`F`!?]!H_GX'@0V\]QH```(&&A`=@'&1B` +MR!$"`,]P@`!L)@B`$'+"((4`RB`F`!"A8*'@?HH@!`#/<:```"`!H138'J$` +M&8`/```0'P09F(\@`'\`!QF8CP$`P/RI`L_[`]K/=*````A"I,]S@`!L)D># +M"PJ>!I^Y*J0(V@`8A%``V0`81%"!@P`8`%.$DP`8!%.#@P`8`%.(DP`8!%.% +M@P`8`%-LDP`8Q%``&$10"_``&`!0`!@`4``8`%``&`!09+CXZ.!^X'C/<*`` +M@`Q`&(`/`+@,`.;)SW*``)@F`!\`0"""`!]`0`&"`ME5`^_X`=K@>/'`G@VO +MYP':SW>``&PF*8>HP0>'(KGZN`#>PB*!`$8AT@!`*HT@'.5FQC_9%AQ$,!4E +MD1`*(P`G*G$""B_Y:G(:<`"''P@>`==U````",H@A@\``&P+3`_&YTIP$@_O +M_ZEQ+R,(!!#8)X'`(?DN,H@ +M@03@#N'_RB%!`\]PH```",&@<@N`"@QPZ[C*(((/``!J"_0.PN=)!:_GJ,#Q +MP,]P10`X+&()K^P`4H@`\/`$!"SW!%`"0Y +M#0`@```80`[@>/'`P@R/Y\]U10`D.4"%SW;_?P#_SW"``'SBSW&@```@.X$1 +M"H4#Q@K@"%EA`-@'\+H*X`C980"%PGCY!*_G`*7/<8``W"T@@3!P`=C"(`$` +MX'\3>,]P@`#<+0"`@.#*(&(`X'\3>.!X\,(/^/`=T# +M]*&G)O`&V(X++_`GV2"`SW*``-PM(*<@HB.&988AHB:&)*(DAF.B(J($V2(8 +M0@`GAB*@*(8CH"F&)J`OD$4AP0`OL`;8L@LO\*EQ`-@!IUT$C^?QP.X+C^>B +M@"AVH*&`Y"F`02/Y_'`?@N/ +MYPAU"B2`+X``@%0`%``@.G&`X,H@@0\``+LA9`W!Y\]P@`!TWL"`A"D")03F +M)W:1%H$0#0EU!$H@`"``V#WP0B$`!"\B""`N#R`,"G"P?4`FDQ`5#:,4(.:I +M<@IQ"/`"X0+F`N`$\$IR"G%#"84`02G#`#(CPR!$(8P!FGO/=$0`.(K!N_0D +MPQ"`D."6YWQK?.CS`!0!($`A``,B<``8`@0B$8``8;@B&0(`R/%2=0'8PB`+ +M`!T#C^?@>/'`T@JOYYAPSW%$`)#BV'%`(04!`-L#\`'C3PL%`0`6``#/=$0` +M2,=X8(0H`@4$N!]D`"5-#@#:!?">8%5^(*8!XOL*-($`V=$)%8(`C3IXP+@3 +M>CAG0*A!C3IZP+I3>DBH`>'R\=D"C^?@>/'`X<4(<@\(40!&#$_Q"'4"\`#= +MSW-$`+CT$(L)#0$00PE1`+"K@.7,(F&`!_0$V<]PH`"`'3B@"O"!Y`!3)<)8([_BI<1WHR7"I +M<>(([_CI<@'87@_O_PAQU@[/Z+8,[^@!V`:FK@SOZ`+8!Z9&AL]Q1`!X]%VA +MI@YO\1ZA"@_/Z)H([_BI<('@RB!A`,HA(0#*(D$`(`GA^,HC`0#=`8_GX'C/ +M<$0`Z,DMD,]R@`"TMP""SW-$`"C+.&``HB.+SW*``*2W`)(X8`"RSW&``*"W +M`($!X`"A!),$*(`/#P!`0L]P@`"`X9T&(``O<>!X\<#B"H`!".C^"Z`!`MCB +M"J`!`-C/<8``_/E!$8``0!&"``BX!7I"$8``$+@%>D,1@``8N`5ZC"(0@!3R +M!?:,(@B`#?()\",*@`\````((0J`#P```!``V`SPBB`(``KPBB`0``;P`-B+ +MN`3P`-B,N,]Q@`"TMR"!SW-%`#@L+Z//<8``G+<@@8PB"(`PHP#;SW&``+"W +M8*',(H*/````!,PB@H\````(S"*"CP```!`#]$8,P`K1P.!^X'C/<(``@.$U +M!@``X'@`V<]P@`#0WR"HSW"``&3A'08``/'`SW"``$3B$@X``,]Q@`"TMP"! +M`>``H<]Q@`"``H<]P1``HRR&`SW"``*"W(*#1P.!^!-BQ`:`!`-D' +MV*D!H`$`V?'`Z@]/YPAV6G$:GGRB&)`P"'I9`,Y;!]"PU5%`#80/"))0(00"H`(19X`""5 +M#X$`A$I`)9,@`-B."R`,FG!`)0$H<+W1=!'"H4# +MDN+`(`$$!?*FXL`@001!*L,`,B/,(%,B@P!Z?-L,'I"`B&")!R,^@^?S((=` +M(0`#0G``&`(%(A&``&&X(AD"`,'Q`=AY!T_G\<`V#T_G&G#/=H``@%0`W2'P +MSW.!`)1*-&U4;<=R@0!42@."-GD$((`/\/___P.BSW"!`'@N@@H@#'EA((9` +M(0(().&Y80"I!.@'B@'@!ZH!Y<,-U)``AB<0@`"O"!```-_""B`,Z7``B,]U +M@`"HM\.X`KATN`"EJ@H@#`G8`(@O")$!`(7/<8``N+=`(`(%0*&2"B`,(.`` +MB,]Q@`"\MX8@_`-$N`*X=+@`H0'?7P]1$""&`Y$"X`.Q!9%BN`6Q`-\#\`'G +M.0_U$`"&).#H8'KH0(7O><]S@`"\MW#87@[O_V"#<.C/<(``4!4`@`T(40#F +M#X`+"^@`&,`C((8#D6*X`[$%D0+@!;&5!D_GX'CQP"X.3^?/=8``T-_/=D0` +MJ,@@C06.,0D"`(HB"`#/<8``_/E`&8(`*+I!&8(`*+I"&8(`*+I#&8(`!=B. +M#V`!`-DU\,]P@`"@MP"`H18!%L]R1``HRR)X)9(Q"$0`BB(0`,]Q@`#\^4`9 +M@@`HND$9@@`HND(9@@`HND,9@@!V#V`!`=@(V-SQ@@B@`0'8`(T!X`"M!XX$ +M*(`/#P!`0L]P@`!DX?8*(``O/'`?@U/Y\]V@`#1W\]U1`"HR"". +M!(TQ"0(`BB((`,]Q@`#\^4`9@@`HND$9@@`HND(9@@`HND,9@@`"V-X.8`$` +MV1/P%@B@`0#8`(X!X`"N!HT$*(`/#P!`0L]P@`!$XHH*(``O<8D%3^?@>`'8 +MK09@`0#9\<#/<(``8.+."@```=G/<(``L+<@H,]PH```(#N`+WDR>4`I`@8[ +M@"]Y$+E[@%EA;WH(NBB[97I2>D]Z"+I985N`3W@(N"BZ17@/>!EASW"``+2W +M(*``V$X.8`$(<='`X'[@>/'`H@QOYP3:HL$(=2AV"."F">`&BW$`P<]W_P#_ +M``0AP`,HN0BXY'DE>$,H``1`P`1M@<&"">`&!-H!P00AP`,HN0BXY'DE>$,H +M`@1!P@ON10Y0$'D.D!!PV#X.K^>-N)GPSW&``)RW`($)"(4`0*'/<(``M+<` +M@`#!`>`0<9GTSW%%`#@L"(%AN`BA"8$!X`FA@?#/<(``G+<`@!!RB?3/<40` +MZ,G/<(``M+-N`7P`]B:#&`!`-EA`V_G +MHL`&V/KQ"=CX\>'%`-H"\`'B20K5`!1J%GC'<($`A$HT:L=Q@0!42@#")`(P"'`D`@`CAQ>'&SW&``(!48($`W$.3)9-`(PX(66$">8.N!).) +M=07P06U/?4.N`>!":1\*!`!*@PIBC"+#C_7S#0V3$8.N`-WT\02S`=@#\`2S +M`-B`X`'8!_3/<(``4!6`H`#8P<;@?\'%\<#F"&_\`=C""&_\`-BB"&_\`-C1 +MP.!^SW*``$S8!H($@""`QW$/`$!"S0=@"$AP\<#AQ<]Q10#$(D`A`@/P(@P` +MSW6``!0):(G/`,]Q1`!X]!R!@>#,)2&0!O0` +MV*X/[_$/3*("$`!O(%@!!W`=C* +M(*(`8@VOZ!>AB(9IADJ&*X;/<*``@!^,H'R@7:`_H.(6@!`0=0P.(O'*($(# +MC0!/Y^!X\<`:"&_G0"`"`T`@#P<`V0[P.+O"N\]T@`"4\FQDSW-$`)"1H8,! +MX:5\@:-AD",)Q0#P(D,`4R/,!==TK```#\PD@I_R``!0Y?,!W@+P`-ZF[@#< +M!/"!ND"E`>0BD$$,11#P)P$34R'"!==RK```#\PB@H_R``!0$?0XN6&YSW5$ +M`)"1U0FU@4"%,R9!<(``2.-`)X-R-'L`>P'>Z0!X'PD1`<]Q +M1``(A`AA0"@"`@5Z0"@!!$5Y&+@E>`WPSW)$``B`\"(```3P0R@``DAQ26E/ +M>OOIX'[/#(@E^4(0H#/<(``@%0`@$60`-AI"C0,.G":"N`+BW&!QHC`&G"4P:8+H`80 +MV@IP`-EN"R_L$-H"%`$QBW(O>"BY"+@E>&1H;WM6)`0SSW"!`-0LL@S@"B"/ +M*G$$\`'A+WD="1,$`"1`,%`0@@``)$`P8!"``.D*`(``V(;P`HXAC@BX!7DO +M>"BY"+@O>>"5!2$1`!#G[W]`)L`2G,$N"Z`&$-I6)`$TSW"!`/0L'@N@!D"5 +MC,`:<)S"*G'"#^`*Z7//$+DE +M>$<2@0`TWQBY)7@!X$0:`@`HN$4:`@`HN$8:`@`HN$<:`@`;CB"-6G``(),/ +M@0#81!8C0"!$B,]V@``@O^QZ((8!V"=Q`+$@C18C0"`$B.QX((8*<`?A)W&2 +M"J`&*G)`C0"&%PE1(Q8C@2`DB>QY="!!#HRY(+`@C18C0"!$B.QZ`(9T($(. +M0"H!(D5Y(+`@C18C0"`DB.QY`(9T($$.@[D@L`'8?04OYX`D`CCQP!X-+^>X +M<#IQ&G)J#R``*'#/=H``?-Y`C@`ADB^!`-A$%B*`(`2(SW>``""_((0SAP@F@!@;:`>6O?>L-$I3U!`_G +MX'CQP(H,#^>BP0AW.G$:0SA`@F@!@;: +M`>?O?^T/$I0@C0'"%B-`("2(S'D`$@`@`N`G<$"H((W/=X$`2#06(T`@!(@` +MV`@0AOH\````C@<,F],#:1'A$ +M>04@?H`@\CX3@``]$X$`"+@%>3\3@``0N`5Y0!.``!BX!7F2Z4(3@`!!$X$` +M"+@%>4,3@``0N`5Y1!.``!BX!7D!V`/I`-@?Z(HB!`#/<8``_/E`&8(`*+I! +M&8(`*+I"&8(`*+I#&8(`;@Y@"D#8"_#/<(``1!4`@`7H$0\1(`T-GA'U`R`` +M`-B*(`(PY[W1)2*2T25BDO?S"0\0(.<-'I->%X`071>!$`BX!7DO>"BY"+@O +M>04A%@`*CRF/"+@%>0N/4R6$$!"X!7D,C\]R_P#_`!BX!7D$(8``*+D(N$1Y +M)7@FCV6/"+DE>R>/$+DE>RB/&+DE>P0C@0`HNPBY9'I%>4,I`@3/`($$C3"1`@`HD@"^! +M`-0L5B0.-,ST"G!5)L$4I@Y@!A#:"G``V6X.[^L0V@(3`2%JXIP$-FV#Z`*0"8$'P#8#/`99DP1@@`99CP1@0`P`/>.T($H0` +M$0(@`-A*<3H-H`M%DD`G0!M5)L$61@Y@!A#:SW"!`/0L52;!%S8.8`80V@HA +M`">`(<$H:0\0(%4FP!8@V8HB!``J`?]1*- +M0"8!%U,@40!`)0`5Q@U@!LIR%O!5)L`6(-F*(@0`*G.F">`*"B2`!2IP0"8! +M%Z8-8`;*4<0@@`8ND5Y +M`>%$&$(`*+E%&$(`*+E&&$(`*+E'&$(`0"8`%RIQZ7(-#A$HJ@O/_P3P$@O/ +M_\]P@`!\W@"(`[@5>``@@0^```G*`!E"!)8)(`!*<(IP$-EJA:`$(#@#_5[%H`0C^`+]7P6@!",(`*+!_5]%H`0 +M@>`#]7X6C1!6)``X0"8!%UH,8`;*0'A1!A"`"BY11A"`"BY +M1AA"`"BY1QA"`$`F`!>I<>ER"PX1*$X*S_\#\+H)S__/<(``?-X`B`.X%7@` +M(($/@``)RJ"I/@@@`$IPBG`0V6IR8]NR#2`+529$%E4F0!8*<;X+8`80VFH* +M@`L@D$IPB@B@"P0A`08!V+4&[^:`)`0]\<#AQ0AU!HTEC0BX!7DO>"BY"+C& +MN:RX)7@/>2BX"+DE>`6M*+@&K0#9*'!A'0(0*+AB'0(0*'`'K2BX"*U`)4`4 +M,@OOZR#:0"5`'`#9)@OOZQ#:J7!!X`#9&@OOZPC:J7!1X`#9#@OOZQ#:SW&` +M`'PR88'/4,I`00MK2BY+JTHN2^M*+D"'80?````7TD&[^8PK0AS`^`` +MW("K(:O@?T*KX'CQP+8-[^:8<,]Q@`!\W@")SW*!`-A$`"2-`)-H%GT$C?_; +M)PC!``#8`_`!X`]X&P@3!$0H/@W/=H``(+_`AC0F3A[U[@2M`-@7\"L(``%= +M8,1MCF8?#L`01"X^'<]T@``@OX"$`-\G=."TP(G6?9-N9*T!X`]XUP@2@:D% +MS^;@>,]S@`!8WD"#&^K/=(``G`L/A!L(W@8-A`&B,!2!$#(4@!`(N25X`+() +M\!,(G@88E`"R&I0!LAN4`K(`V`"CSW*``(!4(((8Z<]P@`"<"PZ04R#^@`OT +M37`@@AT(G@+/<(``G`L/@!$(W@8`VD*Q!=@5N$6@X'[@>/'`X<6BP8MP6@\@ +M"H'!B.`(=8`.P0#7=0``B(X,"X$*`,"&Z`'`@."\#8'S^@R/\PD%[^:BP.!X +MX<7AQL]T@``X#X"$9WH5)$P1P(1$>4,N#1($)8T?`/\`_T,N#A8$)HX?_P#_ +M`,5]H*1G>;EAQW&"6IEY0RC`!CA@P<;@?\'%\<`^#._F9WI`)4T#SW:``#@/ +MP(;#O?`F3Q-`)0T"P[WP)DT34R7,`.=]0"6/`,._\";/$T1YE7Z`AN=]IWQ# +M+,P7@*9G>9EAQW&"6IEY0RC`!ED$[^8X8/'`Y@OOYD=Y0"5-`\]V@``X#\"& +MP[WP)DT30"4/`L._\";/$U,ES`#G?4`ECP##O_`FSQ-G>95^@(;G?8=]0RW, +M%X"FF6''<=ENH>M#*,`&`03OYCA@X'CQP(X+[^9#*,`&0"5-`\]V@``X#\"& +MP[WP)DT30"4/`L._\";/$U,ES`"G?T`EC0##O?`F31.5?H"&YWVG?$,LS!>` +MI@4B30"D>T1Y97F980(A@0_D<"1#H0/OYCA@X'CQP"X+[^9'>4`E30//=H`` +M.`_`AL.]\"9-$T`E#P+#O_`FSQ-3)`IIEA`B&!#YTU*CY#*,`&20/OYCA@\<#6"N_F`-LX\*"0;V%3)4P0 +M`[S#@)A_Y7X!Y5,E?I##H*"P*/2!@**`QWR!H$,LSA/'?:*@O&2!H`0DCA\` +M_P#_*+X$)(\?_P#_``B_Y7['?:*@O&2!H$,L3A?'?:*@O&2!H$,LCA#'?:*@ +MO&2!H`#<@Z`!XW![DPN"@,4"S^;QP%H*[^8!V@AU6MCX'`JP`-A!P(MQ;@_O +M_ZEP@<:I<,EQ8@_O_P3:`)7)<<&X3B`"`:EP3@_O_\&ZD0+OYJ+`88!@H0*` +MX'\`HN!X(:!"H`#9(+#@?R.@$^EA@(6`A^M#@(7J@*`AH`OP0(!Z8@T,@1!Y +M82&@!?!#@#IB0Z``V26@X'\FH.!X0(`A@`2`66'@?R)X0H`C@`"`66'@?R)X +M08``V8/J`X`#Z"AP`O`!V.!^X'A!@!<)A``B@""@(X`AH`#9(Z`BH`;P(GI! +MH$"`66$@H.!^X'CQP.'%"'4#@"AS@."I%9J6E`<_F&0(``/'`=@G/^,]PH```'1@8@`__#_?_`=G/<*````@YH,]P +M``"8'HHAOPC^#&_J`-K1P.!^X'CQP*+!SW"@```P=(#/<@``)/2+<8'`!2N^ +M```8P`X`&4`.`,$!P"NY%;@%><]PH```,!:`.&"BP-'`X'[QP*H(S^8:<,]P +M@`!8%0"`*'4Z<@CH`-C/<:#^V`(*#>_[EK@4R(+E`>`4&A@P`=C^#V``P'B> +M"D``0@G/^](,[^8,V$(,0`"`X)'RSW>@``!\`(?/=H``6"P$((`/`,```#ZX +M`*86#V`%"G`3")``(H%X&-N)*X%Z$$V('PD^C/<(``A+8`@,]QH```'H/@%X'0(*$$T"!B`]`@ +MH@07H0'9#O`E"%$`SW&@```>%X&-N)*X%Z'/<(``'"X@@,]P@`"<%""@)@X` +M`"(,[^8&V)8+0`"`X,HF(1`'\L(/K_L!W@H,[^8&V!3N>@M``!#H*G"I<:H+ +M(``*<@KHSW&@```>%X&-N)*X%Z$`V#?P@.;(#X+[SW*@```@F!(`AI<2`88E +M>!)YZLD="!X&SW.@`(`>K)'0@>!L]RH`"`'`0:@`_%[H*Q&X.?N0&B(:($V!4:&#!Q +M!X_FX'C/<:```!X5@:&X%:%I`4``\<`"#X_FSW"``)"V!@]@"0"`SW6@```P +M,!V`'P"```#V"4``B@V/\,]P@`!DML"`!.Y2"P``"O#/<*``@!P:@#8/K_M% +M(,`#<@AO^,EP`=G/<*```!`IH,]P@`!(%0"`AN@%%0"6@+@%'1B01@Y```$' +MC^;QP(8.C^8:#,("*!(_09Z<]UH``` +M-!"%1B#``T4@P``0I>EV"_#QA0'F!">/'P```(">"N_F!MB%[XPF`Y*T]TP@ +M`*#*(((/``"0`7P+@@F)!H_FX'CQP.'%`-G/=:```#`UI0"%!""`#__@__^8 +MN`"E`(4$((`/`/___Y&XD[@`I"2`` +M`M@X'8`?`!```,]PH```-!`8@`\`00``,!V`'P"```#/<:(`#(``@<]SH@!H +M<("X`*%`@XH@X`,$>O#9)7I`H\]SH@!P<$"#!'HE>D"CSW.B`'1P0(,$>B5Z +M0*//'!`@P1Z)7I`H\]SH@",<$"#1'@E>`"CW06/YN!X\ +M#0``]O'QP`SH8@@``(HA"`#/<*```#`BH.H(#^_1P.!^\<#/<(``B+8`@`_H +MJ@_`"!X(``#/<(``'"X`@(#@[`L"`%H*3_G1P.!^X'CQP.(*0``2#$_N1@O/ +M^C(-P`BB#D`$T<#@?N!X\<`^"T``!@]`!`(+3_G1P.!^X'C/`/P!H(`V`:BX'[@>,]RH```,`:"SW&``(RV(($F>`:BX'[@ +M>/'`1@R/YL]R@`!X5&""SW%`````0(."@R5Z(8.E@UEAF6&#@YEAA(,^9-UE +M$PA1`$AP!>Q*"P``R7"I<03P#0B1`$AP.@L``&T$C^;QP/H+C^8*)0"02'8" +M])SI@@P@`*EPSW&@```P.($!VC!Y!"F!#P``"3U!*4%REB$&`#!VPB*.``#9 +M"0T!$(3J*'`#\`'8)02/YN!X\<#/<(``A+8`@"$(D`!2"D`%C.C/<*```'P" +M@`T(W@<,`B)"0#8`_`!V)X*``&6#$_]B0./YN!X\<`&"4`` +MR@X``(#@H`AA!":_PJ7`>""``J7#/<*```##,H`'8M@A@`!,:&#`E`X_F +M\<">"H_F"'7/<(``G!0`@`#>">C/<(``B+8`@(#@RB9B$`3N"L@#\`O(6@T@ +M`'IP6G"R#2``J7"B#2_\&G!V#>_X"'?B"^__Z7`""4_^<@WO_\EPX@WO_\EP +MSW&``/Q3`('/=Z```""AN`"A"A\8D(H@$``#IP0?@!\````)&X<'$@(V"PB$ +M`!N'0G@'\#N'#B*`#_____\X8#IP`"#!!``A@`0`(!`@$G7*((X/``"#`\HA +M3@/*(@X$!`SNYLHC3@0")0T4C@X@`,EP:@X@`,EP<@L@`*EP(@C@!PAV&X?/ +M<8``%-H`H<]R@`"DTR""!1I8,R)X`*(&&I@S8@K@!P@:6#3U`8_F\@J/^P#9SW"@```0*:#1P.!^\<"*"8_FSW"``)P4`(#/<8``B+:@@0?9"B"` +M+Z```"`+&%B@Y@UO_01]SW"``$@5`("`X*`(0?W/=J```#`PAL]P@`"0MB"@ +M>@T@`*EP5@CO_PAW'V>)[<]P@``4V@"`$'?")PT0R@C@!^EPF'#/<8``+,\& +M@?A@!J$`V!6F`!B`+P````@2#2``J7!E`:_FB'#@>/'`^@B/Y@#=#?"Z951Z +M="(#``'EE;N7N\*2X9(0OL5_X*/K#42000&/YN!XX'[@>.!^X'CAQ>'&`-[) +M<\ERR701\,]U@`!8P/`EC1,/#000@.3*)&$0RB.!`[%QRB*&`P'FXPY4D@[P +MSW"``'S`\"#``,]T@`",MB"$`>,E>`"DZ0N$@,'&X'_!Q>!X\!P1IPY@@@``#`K@XO_D#`.G#/<(`` +MC*O@B`\($2"5%0"6@PA>`&P5$!``V14)$"`2;T-P#!`.!@'8%QH8,`7P%QJ8 +M,RAV`!02,`IP`]D*N=X)(`#)<@(B`2!%"5(`6@\/_*GH`,("=@L*A`,"(H`# +M!O`.)H`?_____UA@&!K8,W8*[_\`V2\(40`K"1`@3@EO_NEP&X41&A@P#?`: +M#P_\"?`7&I@SBB#_#\EQ2@KO_P#"\0=OYJ+`\<#/<(``6"Q`@`?8"KC`V1BY +MB@LOZAZZ,@\``$((C_L!V<]PH```$"F@T<#@?N!XSW.@```>-8,3"5X`!N@V +M@P(@0@`'"E(`%H/@?N'%X<8`VPWP>F-4>EU@0)4!XY6ZE[K`@L&U,+["M>T+ +M1(#!QN!_P<4%`<__\<`>#T_FC@W/_\]V@`"<%`AU`(8%Z+(*S_\R"L__$@G/ +M[OX(``#/=Z```"`%'YB?``@``.X/C_^^"4_XZ@G/^#(.``5-'YB?$````$8) +M```;APT(1`,[AZ)Y"/`;APXE@1______&6%`A@#8".K/P4H?@`*(,`.8;A/(,('SW&@```P5:'1P.!^X'C/ +M<:```#`&@0#8!J%%@06A1($$H>!^X'C/<:```#`1@44@P`,1H>!^"'//<*`` +M`#`8@'EA$'@$*(`/```)/4$I0'(X8.!_6&#/<*```#`T&(`/`!```,]PH``` +M-`P8@`\`00``X'[@>(HA_P_/<*```#`MH,]PH```-".@X'[@>,]PH```,`P8 +M@`\`#!``$0-@"638`=G/<(``;!,@H+/8SW&@```P&*$`V!FAX'[@>`'9SW"@ +M`(!-**#@?O'`SW"``(BV`(`/Z,]P@`"<%`"`">CB#\__BB$(`,]PH```,".@ +ML@U/^]'`X'[@>,]PH```-`"``-K"N,]Q@`"$MD"A%0A0``T(D``1"-$``]@% +M\`+8`_`!V`"AX'[@>/'`SW"@```P.(`9@*+!$'@X8,]S```D](MR@<$%*/X` +M`!G`#@`:0`X`P`'!*[@5N05YSW"@```P&H`0>#A@HL#1P.!^\<#*"```%0A1 +M`,]PH```,`P8@`\`"```T<#@?O'`SW&``&P30('/<8``!\]P@`!(%0"`@.!<"H(`<@[/_\]PH```'!08@`\`"```T<#@?N!X +MSW"@```P,8``V`T)G@#CN,]PH```,`&`\;@!V.!_ +MPB`!`.!X\<#/<(``]-C/<8```-GV"N__((G/<:```"``@:ZX`*$"@;6X`J'1 +MP.!^X'CQP(#@`-G*($$`)/+/<(``!-G/<8``H-F^"N__((G/<(``P-G/<8`` +M]MFN"N__((D!V,]QH```(,P9```)V!ZA'Z&(V-`9``#/<(``I-,`@-'`X'[Q +MP`OHSW"``/38SW&```#9(@SO_R")T<#@?N!X\!!E`-L%((`!((!290(A +M`00`)$"`!2*"`0"B#(X!(T,!&&`4>`;E$&4`(0D2!2"``6"@`H8$$0(0FKB; +MN`"B6X?/<(``I--`H!N'.&`;I[T"3^;@>!#9SW"@```P(J`,&(`/"````.!^ +M\<#/<(``9+8`@!#HSW"@`(`<&H"B"F_[1B#``](/S_]*"2```-@%\(X*;_L, +MV-'`X'[@>/$'#^PCR`#9`>`C&A@PBB($`,]PH```,$*@$QI8,`3PX'@!X8PA +M#XJ\]\]PH```(!N`SW*``!3:(((B>.!_`*+QP`#9#O`X811XQW"``-040I!A +MD!"Z`)!%>RLC```!X<]P@`#X%`"(WPD$@,]P@`"0,\]Q@`#"-)H([_\@B<]P +M@`#(-,]Q@`!L-HH([_\@B<]P@`"`-L]Q@`!\-W8([_\@B<]P@`#\4<]Q@`#Z +M4V8([_\@B='`X'[QP`#:#?!88A1XQW"``-04()`!XBHC0`!AL#"[8K#/<(`` +M^!0`B!!RK_?/<(``D#//<8``PC36">__((G/<(``R#3/<8``;#;"">__((G/ +M<(``@#;/<8``?#>R">__((G/<(``_%'/<8``^E.>">__((D:",__T<#@?N!X +MSW&``%18)X$$(;Z/`P````;T!"&^CPP````.\L]QH`"`,(#@"('/("(!SR`B +M`]`@(0,(H>!^X'C/!RX +M,@D@`$4@PP.`X$+8P"@B!LH@X0#`*"$&SW&@```P;Z'/<:```#0%H='`X'[@ +M>/'`SW"@```P#!B`#P$````R#,___NC1P.!^X'CQP,]PH```,`@8@`\!```` +M%@S/_W[HT<#@?N!X\<`."$_FSW6@`(`P"H4*(8`OH```,#01`2!3(!``G+DT +M&4`@"H7JN`J%"/*\N`JE8@_O\@'8!_"MR8@FOYHH@C`G1P.!^X'C/<*```#0`@`#9AB#^ +M`\]R@`"$MD"")+B!XLPB(H$(](+@S"#B@`KRX'\`V`D*D``H<.!^_0@1@>!_ +M`=AI`"``/]C@>/'`"@\/YBAVU@AO^0#9"'<"\*9^).XO*8$#3B&`!P#=#R4- +M$!(*(`2I<`#9!?"F>V"B`>$O>=\)4X%$+SX;`"&"?X``'$XV>DF*"WK/F""[?.E>^SQ&0)/>AL*4P%$*3X+`"&#?X`` +M'$Y6>VF+Z0L.@`+P_]K@?TAP`-D`V@\B`@`"\`'A%PE5`<]P@`#D$_`@0`!+ +M>/?S+W@"\/_8X'[@>`AQ`-@/\"\K00!.(X('3WH0(8$`SW.``.03\"."`"]Y +M17CSZ>!^X'CQP`(.#^8(=BAU2'$S"E``30F0`!$)T`#/<```!2O>#T_F,?!$ +M+CX;SW"``!CM`"&!?X``'$[>"J`%+-HC\(#ERB"!#P```RNH#T'F1"X^&P`A +M@7^``!Q.J7#O\8#ERB"!#P``!"N,#T'F1"X^&ZEP`"&!?X``'$Z:"J`%+-IR +M#L__\04/YN!X\;*(8$#+-@,?UIP"B&` +M+X``'$Y`(0`A)W`6(``$"B"`+X``3-T*<=9Y'@J@!0C:*?!#L"?P+RA!`TX@ +MCP?)<((.[__I<4IQ+'\`(4%T%GD6((`C8I%`D!`ES1,+"N,`KWU@L&.109`) +M"L,`8;!HB42(!PK#`&2H19$CD+D*0H#<[04%#^;QP.'%5@XO[Q/8SW6``,PJ +M`)4Q"!X`SW&``$3A`($E"%$``-@`H<]P@`#,U;8(S_RZ"<_\`)6@N.&X`+7, +M#D'XSW"@```@.X#/!X`-D"N!1XQW"``*BV(:`@H.!_**CQP)X++^9R:'1[ +MQW.``*BV"'4O"8``@(,\9("CP8->9@(D@!,"N",,)1#!HPB+"PC3`P'@"*L` +MV`"C`:,%\`#8`*,!HPBKZLD_"!X`R(M`*@`"$'$!V,!X$+X$((P/````_\5\ +M`(/!@Z]]`B"#`Q:[0GDP?L]PQ>Z#1P'9!24"$UX.8`C%>XD##^;@>/'`$@LO +MYA?9#WZ$+@D?`"&-?X``(#L`I:8,8`A`)0`2(H4)"94"A^G/<```!C3>#$_F +M525`%HH,8`@,V8H-+_S)<`'8/0,OY@&EX'CQP,8*+^8(!XTAJ8OP```"#1!T_L\"@_F@B0#-`#="B``)T`D$C$* +M(8`O@`!T6*EV#O#T(4\C+@JO^JEP%2)!(P"QX;$!YL]^`>7I#=2<0,8*<,]R +M``#__EH+H`30V7$"+^:`)`,T\<#AQ0#=X<6+<9X,+_P(V!/H3@P/_`#!@.#* +M($(`$`DBZLHA0@//<(``/#*@H`#`=@@@``'970(OYJ'`\<#AQ:'!?@[@""AU +M"''/<(``=%CT($``@.4`'`0PW`CB^LH@`@<`%``Q+0(OYJ'`\<#2#^__`-F& +M(/\+T<#@?O'`X<7/<:```""[@38.P`C/<8``].D)8<]P@`!TMS5X]0$OYJ"@ +MX'CQP%8)#^:CP1IP5@TO^BAW@."&\H()[^\*<"\E!R"$*`DOSW&``"@[,B%4 +M#E(-K_VJ<`AU@@JO_0*`*HW:<`D5DQ`!W0#8#R!``"\B!R"+<#IPE@WOZ@C9 +M*G#*<:X(K^U*<@#>0L:C#!`A0PQ0(:$,$2(:[X+!C@LO_`78!N@*<`H(+^K) +M<8/HR77/<(``/#(`@(#@S"4AD#3R0=^`Y1#>Z74V\OX/S^PR\(+!5@LO_`C8 +M+N@"P-8/[^G)<2CH!>_B#\_L&_!6#>`(:G#/=H``].D(9A\($`)"#>`(:G`( +M9A,(T`$V#>`(:G`(9H3@Z`["[,]P@``\,J"@0=T`W@CP"=T0W@3P@.?*)>(0 +M*G!*<:ERR7/R"*_M"B1`!8D`+^:CP.!X\P?:EPB@[O_P'9$"9.$_;N60`/YO'`W@_/Y:+!S@LO +M^EIPIP@0`"\GAQ3B"Z_]Z7`(=1()K_T"@,J-.G``V`\@@`,O(`<@BW6I<"H, +M[^H(V:EP*G%"#V_M"G)V"J_]Z7`(<<]P@`!465"0X+G1(B*`"_0+"1\`$PI? +M`,]P``#^%(();^;`N8HG1!`/#E`0%PZ0$`#8#/#/<(``&/**)TP0!O#/<(`` +M(/**)U00@."P#V+MRB%"!*EP"G'I<@#;U@]O[0HD@`2-!^_EHL#QP`]X5@WO +M_P#9AB#_#='`X'[@>/'`#WA"#>__`-G`N-'`X'X/\`(0`P5O?"B["+R%>WIB +M"PK>!U![,+IZ8F*Y,'GG"9.`$0E2``"("+@#\%!Z&F)!*@"$_/52>.!_$'C/ +M<8``U-_A`V`%!MH:8C)Y,'E984$I``0X8.!_$'C@>/'`SW"!`)0V[!P(L,]P +M@`!4]4'`SW"``-S?0L#/<(``X-]#P`#;1,,'V`39"]H*)(`/@`!L#@HE@`^` +M`,"W2B:`!ZX/K_A*)T``I<#1P.!^*'(/><]P@0"4-ET`S_C@>,]P@`"PM^!_ +M`(#@>,]P@``,]Q@``/'`*@[/Y<]P@`"PMP"`_]X` +MW?@`+H0KPSW%%`#@L#8'/ +M=40`E,H!X`VA"B"`+X``N+>:":`*`!``(('!"'9`(`\$Z7"V"F`%`MKI<`#9 +M?@KOZ@+:X)5V":`*`]@@D/)_+W@HN0BX)7@`$`$@(G@AE2\@""`4X3!Y\'\/ +M"0`$Z7"B#N__"G((=\EP"G%.#N__Z7($%`(Q3WD(N2BZ17D-"$$`R7"B"*_^ +M`,&=!>_EHL#@>,]P@`!@XL]QF`"`EI4"C_[QP`X-S^4*)@"0@B0"-@#=#?)! +M#E`07PZ0$'#8C;@"#R_FR7%Z=9IU+O#/<$0`J,@ED$`@#0<($!,!0"$``B\D +M""#/<44`."P'@0'@!Z$<\,]Q1`#HR1H1%`$8$1,!SW%%`#@L"H'/=40`%,H! +MX`JA"O#/<40`J,D&$10!0"$-!@01$P%`)``L+R(((,]P@`"TMT"`SW'_`/\` +M!")``"BZ"+@D>D5X0R@`!)`<`##/<(``G+=`@`0B0``HN@BX1'DE>$,H``24 +M'``P5B2`-$`E`1AF"6`%!-I5)$`Y0"4!&58)8`4$VFD.41#/=T0`*,L@C\]P +M@`"@MS#A+WFY83H)8`5!C\]Q@`"DMR"10"<`$P`A$0`"C]=Q````"$`@$`S* +M((D/``!Q`.P-*>;/(&D#`-X+\``A@",`($$CV6'Z"&`%`=H!Y@./[0X$D"\G +MRA3P?T`E#AO)<`#9L@COZ@+:0"4`%T`D`24P>:X,[__I<@]Y*+@(N0]X)7B0 +M'`0P5B2`-,EQL@A@!0+:SW"``'C>((#/<(``6#N$*0D/,"!,#HMS"-A*<:ER +M2B0``$HE```*)H`/@`#4WYX(8`I3)`<0I0/OY8`D`C8*V/D$[_\`V?'`4@O/ +MY0AU02@/`0#>`_`!Y@T.Q!,1\'H*3_K/<*````0.@/4(%(0`V>D)%8$`%@!` +M`>'[\<.]`_!:"D_ZSW"@```$#H#W"$2#`-D$\``6@$`!X?L)1(-E`\_E\<#R +M"N_E"'&")`(S#WB$*`D/SW:``"`[+W6_9F\7`A8:<(#BRB""#P``(33,#`+F +MBW!V#"`(%]F7P&X,(`@,V=AE*@^OZHHA"0]`*`$A-GD`(8`/@`"\1Q(/K^J0 +MV8H@_P\`IX#9`"6`'X```#T@J.D"[^6`)`(SX<7AQ@#2"1*!T"$U`;1``!V6`=0A!XXA5Z@**H +M&P0#P<;@?\'%$GG//'`SW"``$@5 +M`("`X,H@@0\``(@`^`L!YNX)C__J#\_KT<#@?L]P@`"LN`"`@.`!V.!_P'@P +MV0KHSW"M``!>(*#/<*T``&@)\,]PK0``GB"@SW"M``"H,*#@?N!X`=F0N8#@ +MRB""#ZT``$/*(($/K0``@SF@X'[@>,]T"0":F8KK0G@%*#X#`"&#?P0`S&`;"-,#CN#*(($/``"T"0OR%7C'<```9PD$\!5X +MEB!)#!!XX'X`V*W9$+D#H0"A`]K/<*T``$!*H#_8"Z'@?N!XX'[@>`#92PA1 +M`!'PSW"``+@3]"!"`*W8$+CP(((`SW"``,#W-7A`H`'AY0D4@1/PSW"``+@3 +M]"!#`*W:$+K/<(``P/?P($``=7H`H@'AY0D4@>!^\<#F"._E3B#"#ZW=$+WU +MA6@5!1#/=OS_/P#$?W9J97]`*`$#!2'$`P0F3A%E?B5^5!T`$=JE97I%>3:E +M.Z7/3JBSW.M`(`#NX//W:BSW.M```>08,D>@5Z +M0://,]QK0``%0`9@`\/`$/RX'C@>.!XX'C@ +M>.!XX'C@>(H@R0``H>!XX'C@>.!XX'C@>.!XX'C@?N!X"-F3N8#@RB""#ZT` +M`$/*(($/K0``@SF@X'[@>.!^X'CQP.'%ANC/<$4`C"ZI:0_P0B$`"1UX26B, +M(0*$RB6-$,HE#A#/<$4`?"]$+7X4,B!`#A!QRB""#P``AAF@"0+F'0#OY:EP +MX'CQP,]P@`!X"P"`SW&``,2XAB#P#R"!)KB`X7P(X>7*(>$`T<#@?N!X\`LB@A:F4R'#`(/C`=S`?(8A +M_`.PX0'9:(;`>8VF/*83"U$`!NQF@NJ[RB!B``VF%X83"%$``-@&Z2:"]+G* +M(&(`'*;/<:T`@`,$$18`$!$1`!01$@`\$1,`0!$4`$01%0``WPCP!=@'I0R% +M`>`,I0'G@N_*<`L('@`7")X"`-@(\,IQ`-@- +M"5X`"0E?!`'8@.!V\HCO4R+!(B6E4R'`(@:E#?#/`*I9?QB.]3(\$B(*53 +M),`B#/#/E"84!X`FE<_$+A0'@"Z5O\?$%C^7/<(``1+G@?P"`X'BA +MP8#@SW&```3?RB`A``7R8;@;>("X`*'@?Z'`\<#/<(``@!,HD*/ARB""#P`` +MPPUX#\+ET<#@?O'`=@VOY0#9@."5N0H@@!^M``!@SW6M`(!>`-J6N@HG@`^M +M``"@SW2M`(">"B:`#ZT``&C/`'YB#J'#0H&D%C^7Q +MP-H,```:"L_K$@@``&X,(``!V-'`X'[QP,]QH@``@!&!@+@1H0'9SW"``(`3 +M(:#/<$0`7-M&#J_K:=G/<(``0+G6"^__`(!N#X_KO@T/_5H.C^O1P.!^@-G/ +M<*``@!P\H.!^\<"Z"<_KL@_/_]'`X'[@>/'`7@R/Y>P<"+!!P4+".W.MWA"^ +MV18`%@#=0\#/<*T``(-D&(`/`0`!``'8"''J"V``J7("P`H@@#^M``">@.#* +M(4$C!O)*(0`A$-D$&$`P"B.`+ZT``*A*(``@#PD0,$H@`"$0V40;0"`(WP08 +MP#-$&\`CS@F@"(H@#PH*)8`OK0``7@0=0"0*)H`OK0``:$0>`"2N":`(^M@" +MP(#@RB)A(`#="?*WADHB0"!3)0`0@>#"(H(D3"$`L,HD82!*)P`@"_)P%A<0 +M2B1`(%,G`""!X,(D`B5,(@"@S"0BH,H@@0\``)(3RB%!`Z`-X>7*(L$%O7U$ +MQ0080#1$&P`D!!W`(T0>P",^":`(9-@$'4`D1!X`)"X)H`CZV`+`+R?")0#? +M"NCWADHB0"!3)P`0@>#"(H(D`-T7"1`PO(9*)$`@4R4`$('@PB0")4PB`*#, +M)"*@RB"!#P``DQ/*(<$#+`WAY&!`1`Z_EI<#@>/'`W@J/Y1IP*'4)C2B-"+@% +M>0J-K=X0N`5Y"XT0OABX!7G/=ZT```,`V'IP".DAIP`>@!\```!``*9#\`&G +M`]@Z<,]QK0``@`JA3"``H!+8RB#"!`NF9M@`IO(.K^4#V,]PK0``0%IP`!B` +M#P```$#:#J_E!MC6#J_E!MC.#J_E!M@`'L`4"P@1(`:'`O`'APAQ**THN2FM +M*+DJK2BY*ZT%((`/@("`@`BM*+@)K2BX"JTHN`NM*!I`)#_8"Z9]`H_EX'CQ +MP!X*C^4:<"AP2'=H=@HA`"$*(D`AR'7/<8``R+A(H48,+_U7H9AP`]C/`,._0"\"%H"Z@;J- +MNL]PK0"``_0=F``7\$`O`!8%((`/```#&/0:&`!A&Y@/#0````W8$+@+#U`0 +M81H8`,]PK0"``SIV?0@0($`N`A9`+@,4!".##_\```!E>D`N`Q($(X,/```` +M_V5ZSWY%?MRAU:!`*@(C!"*"#P```/!`*@,B!".##P````]%>T`J`B&&(OP# +M17M3(L(@97I=H5:@5FV&(OP/=&V&(_\#97IR;88C_PQE>L&]I7I>H5>@#/!P +M&8`!5!A`!'09@`18&(`$OJ&WH`$!C^4$V\]RK0``@,P:P`!'&M@`!>C/<*T` +M@$!SH`;ISW"M``!!9Z#@?N!X\<`(Z-(-8`ADV,X-8`@>V+8-C^O1P.!^X<7A +MQH'@`=K`>AZZ3R+#!X'ARB3!$,HD@A#/`M@@L]V@`#`[_0F#1#T)D`0 +M!".##_P_^'\/N*5X!7R%>V"BP<;@?\'%\/'`%@BO +MY?_9K=X0OJ"&SW"M``"`(*!2#6`(`]A*#6`(`]B@ID(-8`@#V#X-8`@#V%4` +MC^7QP-X/3^7/=8``E!.BZ`'?>@@@`.EPSW:``+03`(:`X,H@@@\``,8HJ`G" +MY>"F`-D-\/0E0A"MV!"X\"""`,]P@`"$]S5X0*`!X>L)U(,;\`#9#O#T)4,0 +MK=H0NL]P@`"$]_`@0`!U>@"B`>'I"=2#`-C/<8``M!,2""```*$.#H__R0=/ +MY>!X\<#AQ<]Q@`"T$R"!QPD1`,]U@``LWR"%+^B`X!X\"&(SW*M```#P[D1"1$!4!J`#P0!!`$&\%`:@`]-`TT#`8A$N(;@ +MRB"A!`;RA^`;V,H@(@D5HN!^.WE%>02[97E`+$P!A7DA`"``,'F*(E``SW&M +M`("`1*'/<:T`@$`$H>!^X'C/@4R*```6XSW*M``!J!Z($&X`/ +M`(````0=@!\`@````=@?H1^DP<;@?\'%X'CQP.'%"B4`D`'Z5V`RA#!F`#XP` +M`(!$V`2A`-@!H=S8!J(<&H`/``#8UB`:@`_B!!X`X'C@>.!XX'C@>.!XX'C@ +M>)X(K^NI<,]P@`#$N/D$;^6@H,]PK0``@(F@SW"``(`3`8#+Z$0;@`\B`B(B +M+!F`#QT`@-!QV`RA!!F`#P````\,&8`/C``!@$?8!*&*(`8.!J(<&H`/``"0 +MXB`:@`_B!&0`Q_'@>.!^X'C/`L@@A2XM+DE>.!_`*+@>,]Q@`!X"^!_ +M"*'@>/'`Z@MOY40J?@0*)0"0.G$:0:."B2`+ZT``!@0N`5Y!X[/=ZT``!48N`5Y-:<#CB*. +M"+@%>3ZG^@W/_`#9C>W@N,HA@@\S'P<`X;C%(8(/``"?^0OPX+C*(8(/Z1\' +M`.&XQ2&"#P``3_\`VJW8$+AZ<"V@SW"B`(!M<(`@CJR[K;NNNXR[C;MPH,]S +MK0``'>3ABB#+#.!XX'C@>.!XX'C@>(H@R0``IQ2'@;@4IQ2'H;@4IZH.(``*<$,4 +M`R9!*P(%3WK3NS$-41#/<8``@!,A@1+I`-F`X,PB(H#*(6(``-@7Z2\.Q'`- +M`*"[)PN$#P(`(+\.\`#9!N@-#L5P#0"`;2AP!_#]"X2/`P!0-`'8@>#*(((/ +M``"J*,HA`@2@#*+ERB)"`TPB`*`P""+PRB!"`\]P@``DZ/0@001,(0"@.W@1 +MN25X0"D!(05Y0"D`)05Y3R$``)"XRB!"`-D;&"#8&U@@9@SO_\EPJ7!:#Z__ +MR7'/<(``A#/`H'D";^7)<.!X!]H*NL*Y"KF*Z,]PK0"`GU"@SW"M`(!?,*`* +M\,]PK0``JD"@SW"M``!J(*#@?N!XSW&``,2X0($4(`$`@.+/`M`@\HA +M`@`$(H(/'_X__!9I%;DE>$5XX'\`H^!X`=D*Z,]PK0"`8"2@SW"M`(!J"?#/ +M<*T`@*`DH,]PK0"`JC2@X'[@>,]SK0``'\]RK0"`*87@S"%B@2/T0!N`#[*> +M_\I$&X`/;&",>4@;@`]".51*3!N`#R8B,BP`&H`/LI[_R@0:@`]L8(QY"!J` +M#T(Y5$H,&H`/)B(R+"'P0!N`#\JT_^-$&X`/?W&@CD@;@`]/1F193!N`#S(L +M/S@`&H`/RK3_XP0:@`]_<:"."!J`#T]&9%D,&H`/,BP_..!^@.'*(Z$!RB3A +M$`?R@N(!V\![!>,"W`OH.PA0`$L(D0#/<*T`@$`#V1[P`=O/<*T`@(!EH(#A +MRB3A$!"KL$((`/____@V5X!Z$"@48@P`>%>`*A +M"H%&(,`'A7@*H>!^\`L&@00@@`_/ +M___S&N]"@0:A@^7,)6*1"/2*N`:A"0^1$(NX!J&#YLPF8I$,]$\@`P5FH1$/ +MD1"4N)6X`_!#@0:A`(&MVQ"[`:,!@5,B_H`"HS_8"Z,(\L]TK0``@"@<0!$' +MV`ND2'2&)/R3"?("V,]TK0``@`JD.-@+I$"C!H$#H^D'#^7/`MA@@*X +MHKNRNQ*Y)7AE>.!_`:+/`MA@H?H1B,`#@.Y!7DAH@?PL[NTN[6[$[DE +M>V&BX'[/`M@@HGHJKNKNZR[0"F``F5X`*('\+F[NKN[NQFY97D@HN!^ +MSW&``'@+X'\'H>!X\<`*#R_E&7*(<*ATR'7/Q3P4!J`#_\_`(!D&H`/ +M_S\`@$`H0184N"5X#[VE>!2G&;L4O(5[#[[%>WFG"0!^SW*``'@+(H*`X,\A8@?0(6$'X'\BHN!XSW&``$2Y +M`*$1Z,]QK0``1"L(4`!'")$`"!F`#P`8``#/<*T``$`!V1CPSW"M``"$"!B` +M#P`(```1\`@9@`\`"```SW"M``"$"!B`#P`0```!V<]PK0``@#V@SW"M``!$ +M!!B`#P"```#/<*T``(0$&(`/`(```.!^SW.``'@+)X.;Z4*#)H.&(L,/0J,$ +M(8$/S___\R:C$P@>!D4BP@!"HXJYB[DFHQ,(7@9%(@(,0J.4N96Y)J/@?L.Z +MF.@/VPB["+J+Z<]PK0``H'"@SW"M``!@4*#@?L]PK0"`JF"@SW"M`(!J0*#@ +M?@_;B^G/<*T`@*%RH,]PK0"`85*@X'[/<*T``*QBH,]PK0``;$*@X'[/`L%ZD`C`@(#\$`C`@-@@H;H1B/#`V5Y(*('\(8C`PP4:65X`*+@?HHC307/ +M<*T``""`&-@``-J!&)@`SW&M```L<*%1H3_9A!A``,]PK0"`*C&@X'[@>/'` +MG@P/Y0HG`)`:<!$T$I@`/" +MN*5X$'7*(((/``"H&6`.0N4!YN<.!)3!!`_EX'B*(!D``-F7N3D!;^L>VN!X +M`=K/<8``@!-!H0L(40``V`&AX'X!VL]Q@`#`N$"AQ;C/<8``0+G@?P"AX'CA +MQ>'&.WM%(TP(SW.M```5DZ,`W`OP=FF;8_`@S0#/Z"C`>3O#(20 +MP<;@?\'%\<#J"R_E`-D(=L8/[_]`V@'=R7"I<;H/[_\4VN!XX'@`V,]QK0`` +M%1.A`!F`#P\`0_+@>.!XX'C@>.!XX'C@>.!XBB#)``"ASW"``+RX#00OY:"@ +M\<"."P_E"'4O(`<@#WA$*#X+`"&/?X``F+DR""``*';/<(``2+JEJ-UXPK@( +MK^EP"PC1((H)3^L%\,EQY@EOZZERM0,/Y>!X\<#AQ<]U@`!(ND6-1"H^"XPB +MPX\`(8!_@`"8N13RSW&@```@.X$CH!,*T`!B"`_LSW"``/#A[@A`!KX,+^X2 +MV/_8!:V!`P_E\<`""P_E"';/=8``2+I%C<]P@`",JV"(C"+#C\PCXH#*(($/ +M``"6&N@,8>7*(8$#!8U$*#X+`"&/?X``F+F3[@"'+PC>``F/!JV^#V`&`M@! +MAP"G%(^`X&@/XNO*(,(#!_!2"F_KZ7">#V`&`M@!`P_EX'CQP.'%"'6^"F_K +M`=@9[<]P@`!(N@6(1"@^"P`A@'^``)BY'@I/Z\]R@`"XX0:"!(`@@,=QF`"` +MEH((8`9(<,T"#^7@>'T";^L"V.!X\`!YL]^@0X2D1WP1"X^&P`A@'^``)BY((`C +M"9X`(8`@H"6-&PF!`S2(!.GZ#<_K!/`)B`:M,@Y@!@'8`>;/?L\.$I&%`0_E +MX'CQP!X)#^7/<(``2+HEB,]V@`!(N40I/@M6)HT2C"'#CR=URB"*#P``DAKL +M"DKEF@HO[A+8-(T7\"\J00!.(H`'`-H/(@(``K@5>%)[VF``@F1Y+0B0`$T( +MT`!`%@`610A0`.SI%(V*Z,]P@``,XH8.``;6#._KJ7`5`0_E%(UD>!2M!(IB +M@@4H_@`&A2=P!J4$BF."!2L^``>%)W`'I07P%(T$>W2M`-@`HMWQ\<`1"5$` +MG@@@``'9`=@&\)(((```V0#8"@@``-'`X'[/<:```#"%VH'@"H$9NL4@@0#0 +M(&(&T"#B!@JA"X'>N`NAX'[/`NB +M"H*YN`JB"/`*@KFX"J(+@MZX"Z+@?N!XSW&@```P"H'[N`J!SR!B!M`@808* +MH0N!WK@+H>!^X'B)!^__`-C@>`#:#R("`,]S1`!X]@6+@.'%(((`QB"!`+T$ +M[^X%J^!XH<'QP*H/[^0(/$V&_"K_E>$3`'PL>`<]PH```(!"` +MF[H"N&ZX2"```,FX!7H$\`L+'@*=ND/"0<2+=LEP:')2#R_K`=O+R10<1#,0 +MB,]Q@`#TR0.X%7@`818(/+^S)<`C<'P?OY*S`X'CQP*8. +MS^2AP=(.+_F+<`HE`)"R!0(``,'@N5`#`0!$(@!3B.#/=8``G`N6`@(`!"*^ +M[\#`P,`)],]PH```)`"`XKA^`@$`Z`L]PH```1Q08@`\```P, +M[,D%V0'@L[BUN+BX[!H8L!6Y!*'/<*``@"`2@(#@A_3/O`$@$` +M!""`#P``'QT!X4(@`(#`&D``G@UOZ#B_I\J8TE<]S1`#X\]P3``## +MN02XSW)$``#V'6(`8@#:(0@?`,P3```C"!X`'PD5`C,F07"``+#C0"<`\"[`(:* +M)R$@>YAB'A#T5Y)7@`IMH,8`<&V,]QH`"`'1J!!'\`AN5X&J$`A<]Q +M@``D"2\@`P``I0&!#P@?``"!AB###X"X`O``V`"ASW`$!`0$"R(`X![R!"(! +MX/_8"_(O*4$`3B&`!R.XSW&``.PR\"$``,]U@`"<"YP=`!"$*`D/SW"````] +M,B!`#KX=`A`2\,]U@`"<"P.%$@]@!"2%SW&``#P,'JF:#N_W`-F<'0`0!"*^ +M[P$!`0$$](#8OAT"$+X5@!!`*`$&D0C?`4UP?PB>`XX-P`+/<(``G`L/@`0@ +MOH^`&@```-@"]`'8SW&``*!')8$'"=X"`-B*(=8`SW.@```H;QM8@`/:SW&@ +M```,1Z%:#0_K!-@!&QB`!"*^[P$!`0'/=8``G`LX\L]PH```(!J`LN@6#0_V +M%864N!6EZLG[N+0/0@$H\$4A`0?/<*``@"0RH,OQ#X6SN+6X#Z5-<.ZXSR$B +M`L\A8@+/(:("12$!!L]PH`"`)#*@OO$`V!FESW&``*S-#H$!X`ZA$-G/<*`` +M`"0AH!8.H`<`V(H-``@DZ!F%(NC/<$4`-#@`@`#:C[I;"-X#SW!$``SR`("4 +MZ,]Q@`#\^4`9@@`HND$9@@`HND(9@@`HND,9@@`6"*`)`=CN"H_V(X4(E3"Y +M$+@%>0+($'$!V,!X`KB!N,]QH```)P"A`X4PN"B5"/"2#._N%=V^"H`$=0(` +M`!"Y)7@!&A@P&=W3\.*YTO+/<*``@"`2@,]PH```#`V`SW"@```H0Q`!A@80 +M`H8S$`&&X[K*)6(4'?0,B!O`5W0?P"0G>!P#=`_`7W9#MSW*``)P+(;($(;Z/`P````'9 +MP'D/@A"Y)7@/HE((;_JI<(#EB?3/=H``G`L/AL]W@``LS@H@@"^@```H%0@> +M!#R&E-@R#B`#R7+B">_N`-B6#T`'OA:!$!\)WP&!AIP6`!!2)`P00)9*)``` +M=):^"2_[4R0%$,]PH```$#F`".D+AP'@"Z<)AQEA*:>2$`"F*H``C8SW:@ +M```H!!X8D"X(0`$(=3<($`7/<8``G`M#@0B1,+H0N`5Z`L@0<@'8P'@"N(&X +M`!X`D`.!,+BQ!>__*)$7V/(*+^6,N`'8E@B@`P#9F>5$`L'_%@K/[JEP00'O +MY*'`\<#AQ0AQ$("AP00@OH\!`0$!`-M$\@0@@(\$!`0$%?(O*0$`3B&`!R.X +MSW&``.PR%2$``""(SW"````]A"D)#S(@0`X.\`6!H+@%H06!R@I@!":!,V@U +M><]R@``,RB%BSW*``#P,'JK/=8``2!E`A0T*T0`D%8(0"0B```#;#/#V#V_E +MBW``I0#;ANB:#J_M)!6`$`"%@.#*(Z((:'"U`._DH<#QP"8(S^0`W\]V@`!( +M&>"F,(`(=0.`!"&1#P$!`0&,(/^/!_0(E0\(@`\``/__6G<#\$HB0"!,(0"@ +MS"(AH##R!"&!CP0$!`06\B\I00!.(8`'([C/<8``[#(5(0```!"0``IPA"@) +M#\]P@```/3(@0`X0\`6%H+@%I06%]@E@!":%,VC/3`B4`#/<8`` +M/`P>J0D(W@$`V$SP)!X"$$05@A!ZCL]Q@`!H&1D*P0`X8"J(@.'*(6$`!?() +M"A$@`MDJJ%JN<0H0(.8/K_H*<"&5R[AQN3QYJ7)%X@#;`_`!XR,+10`4(L\` +M@(_ACPB_Y7Q3),\2[0C!@XRV>ZX!V`+P`-A,(0"@S"`A@,;S`MK/<:```"=` +MH26%3)4PN1"Z17F"#*__`1I8,+H(+^L*<%$'C^3LMONNY?'@>/'`X@Z/Y`0B +MON\!`0$!"'>Z\L]Q!`0$!`LB0.`>\@0A@8S_V`OR+RE!`$XA@`L5Z#_!" +M(0$(`-H/(D(`8;HX>V5ZBB#_#P7PBB#_#PAR`=G/`$:&#"A +M!:_D`-C@>/'`.@V/Y`AW52!1!``1`""CP4'`!!0`,4$H%`,&%``Q!"*^[P$! +M`0%"*!`!?/(#ARB7,+@0N04A$@"ES>VXT2!B@`7R2@[O]8+`SW$$!`0$"R)` +MX!?R!"&!C/_8"_(O*4$`3B&`!R.XSW&``.PR\"$``(0H"0_/<(```#TR($`. +M!?`%APH/(`0FA\]R@`"<"[X:`@`!V0\(W@$R@I6Y,J(`V02XSW.!`!@T1I,% +M(``%4'!$D\!YSW```/__$'(`WLHF0A"E$@&W#PG>`A!R`-W*)D$3'O"DS>.X +MS"8BD!+R1B'!`*4:7+`RR`':`""!#X``5+A`J1#8I!H)$H%&`57A6@`'B +M5J`Z#2_Z*'"`YH?RSW:!`!@T!)8*<6IR[@]@`BISSW.``&`5X!,!`$0I/@=% +MAP`C0`Y`H$R7`>%"L,]R@``\#)Z*X!M``(BH"1@"!4`H`B%%L`P8P`1$EA`8 +M0`3/=H``E+:,9DJPFJA`*@$#G;D%(0$$SW>@```P-Q]8D`*Z,"*!#Z``M"[/ +MD07PY[[*)B$00,8!%($P4R:0$<:Y +M.*@9&`($R\E:<1"(:@]O_@IRSW*``"S-OQ(!!@`A@`2_&A@`P!(`!@)PP!H8 +M`.K)-P@>`L]PH```(,]QH`"`'`09@`_%[H97&X`!H3<7`)8!H009P`0$&4`$ +M4R;`%`&A-+[!H:EPZ0*OY*/`X'CQP*(*C^2AP3"``-T$(;Z/`0$!`_W1()Q%0`6SW&``*S.%7D6@802 +M`P$>@7A@'J$!@A$('@$0B@'95@YO_BAR8@LO^@'8&MT!V`#9"/#/<(``K,U, +M@`'B3*`H<(#A!`QA^\HA@0.I<#$"K^2AP.!XSW"``!P,%)``VF*X$+A%($$! +MSW"@```G(*`!&I@PX'](<.!X\<"2"8_D"'40@*+!!""^CP$!`0$`W(WRI,WE +MN,]Q@``LS8'R0-BD&ARP51$`!L]R@`"LS@'@51D8`'$1``85>A:"SW&``/2W +M`>`6HC+(%'G+R8"I5B`"!#*"KPE>!-"(SW.!`-@_UGM@BQ,+7P'/2<.GA;[9P.\=7N5?)MC.V//=(``!.YK9`\+W@%&)LX38;DE?MH- +M;_[&HDX-X`7)<,]Q@`"<"Q"!#0A>`@38P1D"`+H)[_6!P`#`*X@;C/<:```"<`H0.%*)4PN!"Y +M)7@!&A@P`-BA`*_DHL#@?PC8X<7/<*8```2D@,]R@`"<"T$M0!'($H$`P;@P +M<,HD1A#*)`400"Q!$D\A`P20&L``$0T?$0T(``.0N9*YD!I``.!_P<7QP.'% +M"'7/R&#`9`0<0C8"?<6""``J7"%Z""#8'FI<#T`C^3@>"&`SW*` +M`)P+P;D9"=$`SW"``!P,((`&@0'@!J$`V1_P/8+//'`X<7/=8``G`L5A00@OH\`<```5O(O*0$`SW"``&"Z]"!``#R%@KC."N`" +M6H65"!``%84+")X'V@Q/_P;P`-G/<(``1%0@J'(-0`?/<(``($<]@*@5`!'2 +M"&_[-'@5A5L(G@?/<*````@"@`#9SW"@`(!%+:#/<*```!\<@#$('P#/<(`` +M:"@`@"4('@`,`A`1"-X!$H:5N!*F#X:7N`^F%88$(+Z/$'````OTG+@&#Z_U +M%:9`)0$2.J8`V`&QLA8`$:@6`1$X8&*X$+B`N,]QH```)P"A!84LE3"X$+DE +M>`$:&#!A!F_D`-C@>/'`Y@U/Y`AUSW"@```@$8`O)`@`$(4$(+Z/`0$!`5;R +M)87/=H``G`O/=X``'`P9"1X`C@W/_R6%H+DEI02'D;C/&ABP%)<5"`,!#)4P +MN1"X!7D"R&T)`0`PA00A@8\$!`0$%/(O*4$`3B&`!R.XSW&``.PR\"$``(0H +M"0_/<(```#TR($`.!O`%A9X/X`,FA;X>`A`5A@0@OH\0<```%O0$ARD(GP0B +M#H_U%8:>N!6F0"4`$AJF'(;IN#`-0?L&\""'"X$!X`NASW&``!P,&9$TD3A@ +M8K@0N("XSW&@```G`*$%A2R5,+@0N25X`1H8,&$%;^0`V.!X\<#:#$_DZ"SN+6XN+CL&ABP%;D$H<]UH```(,@5 +M`!"K"!$`SW"``)P+%)#/`"$(%0(S)@!P@`!TXT`G@7(4>0!Y!MH$\`3:`O`"VI/+SW&``$`, +M"&'/=X``%`E"*,0`SW"``$BZAHA@AYU\P+R*("$L!",#!(5Z0"S$`8APAB#A +M#T5X!7M@IZH+X`8&V'H5`98`AP0A`00E>'H=&)``AB\@`P``IL]Q!`0$!`LB +M0.`A\@0A@8S_V`OR+RE!`$XA@`J0AU"_#/=H``G`L#AOH-X`,DAKX>`A``W;X6 +M@!`7"-\!>@UO]P#9'@QO^IP>`!`(=00BON\!`0$!"/0!A@T('P"`V+X>`A"^ +M%H$00"D`!D<)W@%/AD\BP04OIK.Z,H:UNI6Y,J;/<8``2!4@@9>ZB.G/<8`` +M&-L@@0D)7@!/IDUQ[KG/("("SR!B`L\@H@)%(``&(O`#N35YSW*``.S)(6*" +MN`L)GPY+Z;/<:``@"02H00BON\!`0$!SW:``)P+'?(4EC<(7P$`EH8@_`", +M(`.($_(/AI"XH@NO]0^FSW"``%@5`(`)Z`#8EKC/<:#^L`I&#V_Y3X;/<8`` +M\#=`@<]W@`#P.$H@0"!'"A$"37!$(#Z#'_0DN%,@P@``V`\@@`!/APMZ%?)N +MAT\C`@!.IY'KP!$"``0@@`\``!\=`>)"(`"`P!F```X*[^C*(&(`C@JOZ$@? +M`!0/AAD(WP5-<`T(G@,J"T`"!O`/AO6X4`@"^\]PH```##2`SW"``&BZ(*`$ +MV<]PH```)"&@ZLD7"-X&'8;/<:``@"`P@2)XE."(#AL]P@`!8%0"`SW:``)P+OA:"$`GH`-C/ +M<:#^X`I6#F_YEKB^%H`0$PC?`7X+;_<`V2(*3_H(=0^�B>!$X(#^T(=;KP +MN!8"$<,6@!!*(P`@`B(2``HD@"^``&BZ`!0`("Z&!.(X8`(@D0#/=X$`N"[I +M<-8-+^EWV<]P@`#P+1#9Q@TOZ1IQSW"``%#>N@TOZ0C9SW"``$0MK@TOZ939 +MSW&``,`3`!0`(``9Q`0;MS@?1!3/=Z````PSA\]P@`#DNR"@E@I@`2IP"'($ +MIQV&SW&@```@9.`0H0'8!QD8@``9``3PV00B0%",(`*(,O)&``D`T."`W,P@ +M`H,R]`#9SW"!`+@N.:"(&$0`M!A$`.(80@#A&$(`SW"!`+@R9!A"@'080@!* +M<$AQ@@OOY*ER"'4>\(P@`X`.\HP@`X3@W,P@`H,.]$IPP@NOY$AQ"'40\$IP +M`@NOYTAQ"'4*\,]P```R$6X*K^0$(8$*`-TD[<]P@`!8%0"`"N@`V):XSW&@ +M_L`)\@QO^:ERSW&``)P+#X&(:#/<(`` +MB"@BL,HE01"-[08+3_@+Z,]P@`"<"P&`"P@>``H.S_4(=4D`;^2I"*_XBW"%Z.X-H```P*'`T<#@?O'`U@\/Y`AVSW"``*!' +MHX#/>,]Q@`!4.X0H"0]:"6_W,"%/#AIPR7"6"&`!Z7')<.EQ$@UO^`IR$26` +MDPP((@#*($(#^0#*((8/``!9`,\@)@-8":;DRB%&`XH(8`&I<(X.;_BI<,4'#^3Q +MP,]P@``L5+(++^D8V<]P@``D'Z8++^D8V='`X'[@>/'`X<4(=0#9X<&DS5<( +M7@//<*````@"@,]PH`"`12V@SW"@```?'(`O"!\`SW"``&@H`(`C"!X`#'`? +M"!\#SW"@`(!%,!B`#P`@````V<]P@`!L*""@:B&``<]P@`!P*""@SW"@```, +M!8"!X,H@X@//("(#K`BBY,HA0@-:""`'J7#/!@'8$PA1`,]Q@``LS@"!`>``H1,-T!2F#F_XBW`*(0"``O2I<48( +MX``H<$MIHN(.`0T`,B:"<(``C.-`)X!R5'@`>,]P@``<#""`"($!X`BA`-D! +MV'GPSW*``!P,((('@0'@!Z$!@D!X`-@(<6WP8@\``<]QH```)`J!!.@"V`&A +MSW"``!P,((`0@0'@X@^@`!"A[/'/<(``'`P@@`R!`>`,H3KPSW&``!P,0($" +M@@'@`J("@4!X1_#/<8``+,X#@0'@`Z'/<8``'`SU\<]P@``<#""``X$!X`.A +M)_#J#,`#N/'/<(``'`P@@`6!`>`%H0CPSW"``!P,((`$@0'@!*&2"```'_#/ +M<(``'`P@@!&!`>`1H0'9*'`7\,]Q@``LS@R!`>`,H0#8`=D/\,]Q@`"LS0Z! +M`>`.H9CQ0=A*#V_DC+@!V2AP!^E""\``_@T``03P".B&"H_JSW"@```(`H#/ +M<(``G`L/@!\(W@0`V<]P@`#P+2.@SW"``%#>(:#/<(``B"@BL%8*@`!]!2_D +MH<#QP,]P@`!8%0"`">@`V,]QH/X("UH);_F6N,]P@`"<"SV`9.$."B`'"-BB +M#N_Z`]@#\`H,C_C/<*```"0*@`7H;'#S"!Z`T<#@?N!XSW&``%"Z"&$3"!X` +M!"*^[P$!`0'A(,('`=C/<(``H$<%@.&XX2#"!P+8`-C@?N!X\#*("($Q`UBY,\@(@,`WL]W@`"< +M"]*GSZ?0I\"WU+?3I\]Q@`!<#,.I"B&`+X``H$<4$0`@Q*GKN`'8PB`!``*X +M%J?5I\]U@``<#-VU@-B^'P(0QZ7=IPH@@"^@```@P!`"(&P0`"!?IT)X'J?7 +MM<]P@`#@%=B@SW"!`!@WP*#;I\*IQ*7'J<\:F+,$VL]P@`!<%4"@R*4.B<.G +M#:GIR.!XX'@`V`"A$O!`(0`#`*7/<`$` +M.&\!I<]P`0#H<0*E$-@4M0(1`"$>M<]RH```#!."BB&:``.E#8(1WD(@``A( +M(`,`SW"``(2V`(`!VH+@P'K/<```@@Z`XLH@00!P<,HF+A"`YLX"(@#1&IBS +MSW"``/PR`("`X,HF(AD8]!`1`""`X%K8RB"A!PQQ$PE>!L]V@`"<"S^&&0A% +M`,]Q@`"LSQV!`>`=H0/>AP(``(`6`1#/=8``H+L`@4`E$!8!X`"ASW"``)SF +M((`!@$#!0<`@V+H/(`4`I?(2`;;TR4HA`"`%>2\I00!.(8`'BW&:"R`$@<): +M"B`$*G#/=*```"#`%`,0`,(!QP(BPH`#)T\40,)!QSN$8GAB>2&E0J7CI>8, +MK_L$I8H,K_L+M8'@`=C`>`JUSW"E```,XH!3)\(0OQZ"$%,G0!"#X,H@807/ +M("$#\`IAY,HAP0-!+T`3PK@OAL8>`A`$(8(/````".:E(0G>`@2X3R!!``J5 +M)7@*M0?8!_`5(`P@`!Q`%`/P!-@!X/,(%((*(8"@SW`0`!`0RB%B(-8-X`;Z +MV0'>#'#VN*WRSW&``"@M`(%1(8##`>`/>`"A`=K/<*```!`D@,]P@``H+0"` +MPB*!`#!PIO0*((`OH```(,`0`"",((...`$-`#)RD/3/<8``G`L/@44(W@+/ +M1(`AL]U@`"@NZ`9``!]$@"&I!D``+`2`(`%I[`2`(`BN,2X%;>D$8``I1&! +M``BY)7@'I<]P@`",JP&`!H#KN%P)@@#JR2\(W@+/<*``@!P$&(`/Q>Z&4FP0 +M`2`AH":%(:`UER&@,)`!H1'P!""^SV`````$ +M]`3>"_`,8_\]$:F+."YI[TSW&```C? +M`8$)Z`"!#PA>`(*X@@I@!0"ASW"@```0+(``VRRYSW"@`(`A!(#"N4#`(,#A +MN4)H9+A((`P`RB#!`!+R`A2`,`T(!`,0F#Z@+9 +M!?"`Y`#9RB%B`(#BS"$A@,H@0@#*(&$`@./,(&&`RB"A`,]R@`!<#">J"*K/ +M<````1-6"^`&`-G/<(``6!4`@`GH#'(`V,]QH/X0"J(*+_F6N`0@OL^``0`` +M!M@&]`QP_+@@V,H@(0+K")"`SW&@```0+X$%WH#ARB8!$-$:F+//=8``G`N& +MYLHE@A^@```,J@8"`,]W@``<#!27!]XOA6*XZ[D0>*ORSW*J```$8H(*((`O +MH```#$$K`0(O>0HD@`^``%P,!A2,`(FY#KR%>3"E"B&`+X``H+LT&<`@.!E` +M("""0!6,$`HE@`^@```0E.0L&4`@&?(%]C,,D1(CN1?P'0S0'>[D$?1%*?X" +MY[M!*<%PPB%B``?>"_!%*?X"02D!<07P(KD#\`#9"-XNI4&"/!E`(#`9@"#D +MNLHF(A+ANLHF(1(7"IX!!-H!'((`%!$"(8*Z%!F$(!<.T1$1";0#!]Y0%0(` +M!PI```C>#0[0$<<%(``*=>(.K_H`V<]QI```2'81`(:@'0`0?A$`AJ0=`!"P +M$0"`!:>P$0"`(KC$N!6WI16!$*05@!`(N25X'!D`(,]P@`",JP&`!H#KN'0. +M0@#JR:\(WH+/<*```"#/<:``@!P$&8`/Q>Z&4AN``:$8$0`@`:$5EP&A$)0/P.@Z/^DH@`!#/(>+)JL8O`4D!1!`'4`14R+``D`5AA`.I5$F`(#1(N*'RB8A$L]T +M@`"@NTJD%!0'$4`I!`$%),$!*K0O(8$!#Z0X'$`1PKG/=(``^/`I9`T)!``O +MA8^Y+Z6'YE2EE/1,)D"#;O06M\]Q@`!L[R"!`^`%*'X`"B#`#@'@`K@4X!VE +M3@VO^A38-(4)\-(/[^,&V,]PI@``!""`-*4$(8&/`T```!OT&0A>1L]PH`"` +M(%"`SW"``)P+'X`)"@4``=@#\`#8B^@,)O`"&P("`-^7OP#8%>@*WL]P!``!$>8/H`8`V00@P$.`X,HFXA%L +M<."XRB8B$N\.D)(,\"Z%$PFT`P?>SW"@```0%(`)"$``"-Z'YEP#`@`*)8`O +M@`!<#`(5@"#/=X``G`OAN/#R"B&`+Z8```@1$1.F`-Q!*\`FPK@A:$$KP"!3 +M(`0``2D!`6&Y02L`(1(1#:93($"!4R4"$+U[4R,2`$$MPQ3`NT0E#A(BO@4F +MU!!3(T,@S"#BCQ7R02N.)L"^42.`ILH@`@/*(`(C%/0!V,]T@`#441@4$!`` +MW)R\"O!!+0`14R#0`$$M`!+`N`#0N[97E`+$($ +M$[A%>05Y!A6`(`ZX!7E3)``@&[@E>`5\`=@`'0(@FKRL%P`1D*?/<8``;.\@ +M@0/@!2A^``H@P`[!:+X)[_H0AS"'=+@BN`)^(0E>`\]P@`!P[P"`!2B^`P`A +M@'\``/\/,+@"((X$%PS1(`0AOH\&`````=C"(`$``>`"?@HA@"^F```($!$` +MILJX'PX`$,]P@`!8%0"`">@`V):XSW&@_CP*N@WO^,ERF!^`$P;N*@T/Z@ZG +M"/``V1"'+J>4N!"G*'`5#9X4$0B5(@T(E`,-#@5P"````!W>)/!`%X`01+C! +MN`'@(PC3`-"'!":.'P```!A2#&_[*[X0=LH@3@3*)NX1S_>Z#P``"':4X,HF +MXA,(\*H/```(=I3@RB;B&"IP((#/<(``H+LL&,`$+:#`%X$0K*`'N8JYK?#@ +MN`HA@"^@```0KO(*(H`OI@``"`(2$*8#$@VF4R"`(8#:!"6!$`:Y)7@$(@($ +M!+I%>$0E`1P-N25XJ7&&(?,/#KD%>085@"#CO0ZX!7E$)8`0%+@%>:EPAB#^ +M#Q6X)7B(N%(@0`40IT$MP1#`N0`=0B#*(H(/``#__\HB@0\``!`?+H>L'T00 +M02@!(E,A080NIP3TE+@0IU\-GA1`%XP0#PP1&`0@OH\````8)?(1"!X"02C# +M`%,C?H`(]`G>"KX$((,#,PN``T$H0P3!NRL+U0`7"Y$`(P@>`D$HPP#!NP'C +M%PN1``L('@+,Y`7V"PF4`PL*10`(WB+P02C!`,&Y`>$A"=4`!""`#P```!C^ +M"F_[02C.`@T(A`,0AQ,(G@)B#@``"':4X,HFXA,(\%`1`2`.AQ!Q!][*)F(2 +M`!(!(,]P@`"@NRP8``0MH``5@2"LH`>YB+E*D$5Y*K`NAR^@,($(2 +M@0`0N25X0Q*!`!BY)7A%"!$""-F/N4`:0@`HN4$:0@`HN4(:0@`HN4,:0@`4 +M\$`:0@`HN4$:0@`HN4(:0@`HN4,:0@!^"F`(R7!6#4_U`O``W@;NSW"```C? +M`8`%Z!78T1H8L&H++_G1R=')!>BF#D__%/"+=LEPSW&``.CE3@GOXPS:SW&` +M`)P+$(%`P!V!0<`#V*X-;^O)<4H@P"`<'0`4SW:``)P+Q1:`$-$2#[83"!X` +MSW"@```E`("A&ARPSW&``)B[B>\0A@\('@8(+_4`VAVE/87/<(``X+O6 +M"R``(;`/A3,(7P0.A14(406F"H_L!NBR"J_L`-@$\"(.P`'"%8`0">C/<(`` +MC*L!@`:`Z[A<#@(`$(4)")\&`-AR\*$('@?/<*8```2S@!38SW&@```@$*$! +MV`<9&(`0V`"A!?#/<*8```2S@`T-WQ=L3"FSW>``*"[N@_OZ2ZG#Z=` +MV,]QH```#`2A#H<`H438!*$/AP"AZLGHN,H@@@_%[H)GRB%B`+0.X@7*(D(# +MR77/=J``@!`(AA,(WP8]A8'89.&."*`&#+@(AA\(W@<3")X'`-G`'4(0S;@. +MI9CQ`=C`'0(0E/$,.!XX'C@>.!XX'C@>.!XX'C@>.!XX'C@>.!XX'@F +MH.!^X'BAP?'`?@J/XT3`%=U3"-X`"-C/=Z```"0$IVH)``#/=J```"@]"!`% +M,H<3AS"Y$+@%>0+($'$!V,!X`KB!N``>`)`2AS.',+@0N25X`1H8,`*'#PB? +M`%X*[_>$P(+HJ7`C"%$%SW"@```D`H`$P>*XRB!A`@@,X>//("$##@@@``3` +M"-QK`H_C\<#Z":_C!-BCP<]UH```*,]SH```)!@3!P"R%0^6!*,;V`>C)@_O +M_Q7>42<`@A&#,+Q`*`4$$H,` +MV;.#02@&!,]S@`"<"PZ#$+U!P!"#!24%`T+`?8//<,7NB5V:#.`%!29&`\EP +MN0&OXZ/`P=A`&@*PSW&``)P+%H%.(`(!#H%">!>A#."P&00`L!$``<]RH`"` +M#`/@!""`#P``_/\0HM#)`!\`0#>!`!]`0.!^X'CQP.'%SW"``$BZ!HC/%,@`0``@J"X)7@`HF(((`8'V,]QH```('H1`(:DN'H9&(#/<(``G`L= +M@"7HP!$$``(@``%JN$@@C0`[#=00SW"@```D"H"7Z"QP*P@?!NK)&PC>`\]S +M@`"<"\]PQ>Z$50'9J7+."^`%?8,`V+H-8`:I$`=`A#B"B_L_]CF"@_L(8T#K1)I3.#/@ +M```,RB%"($[T#1*"(,]V@`"@NQ#JSW"``)R[)*<`@)NXG+@`IT$>@A!(V`2G +M$(8`IQ"%%PB>!AS8!*2\H00!.((('G!4` +M$!!RT2$"@!SRBW&:":`#@<+/<*```"`;@"&&`-HB>`#!`<,"(0&``R.#`"*F +M8Z80V`2G`H8`IQ38!*<#A@"G`8X"N%8@D0(0'T`4SW:``!P,/988EAEA,'@X +MM@T2@2`#X`0@@`\``/S_3R#"!IRZ@.'*(((@G@T@`LH@`2#/<8``++\#Z!N! +M!^@`V!NA3R!`)Y^X`_!/($`G`*<`E88@_PQ#"!$"0"$`(@2G%X4TE9^XAB'] +M#T>Y'KDE>#V6!!*"(#QY';DE>#N666$\>1BY)7@#$H$@5H5983UY%+DE>`"G +MZLDE")X"SW"@```@SW&@`(`.!^X'C/!L]Q@`"<"S"!#PF>`E08A`!6&(0`X']?L.!X\<-E)$.DZ`3#0$:LJ]XHA,!`0JT+W@+M/_8"+@$?21X2+@.M*03@`!( +MO1:TI1.``!>TSW"D``"``(`:M,]P@``(WP&`K;2'Z$AP>-E^#>`!Q-H#\*() +M``"2"0``*05/X^!XSW2``!R[`*0AI`'8'[1^M.!_0J3/<*4``(%!@`*`SW&` +M`*S0#:'/<(``G`L0@`ZASW"``-C050'@!4RA\<`2"```U@_/_]'`X'[@>/'` +M@B0",8[``!R`/P``>1$$'(`_```'(`@<@#\``$D1#!R`/P``2A$0'(`_``!+ +M$10<@#\``$P1&!R`/P``31$<'(`_``"+$2`<@#\``(P1)!R`/P``"2`H'(`_ +M```&("P<@#\```@@,!R`/P```"`T'(`_``"3$2G9$KD3VL]S``#B$4`C1``* +M)H`/```"0PHG@`\``'T14@IO^$`CA0`/P<]P@``LT`["/Z`0P\]Q@`"LT&"A +M&L13(@,"!"*"#P,``/X'NF5Z7J`;PH6A1J%(%`,Q$<('NP0BC`\```#@+;P$ +MO(5[P[I%>Q/"?*!=H!3`%L(!H17`VKK#N!NX17@'H1?`@!0",`BA&,#&N@FA +M&<`*H1S``Z$>P`*A'\#+N`>X17@+H<]P@`";$%\%:1!PN#`':Q +M`-F/"1.!U&@U?A4A`@`S)(,PGF:@AIIB?66@IH02S0`+#<,0A!K"`'@2S0`+ +M"T,#>!K"``'A+WGF\7T";^.CP.!X\<`&"D_C9@D@`PAUSW&``)P+#X'/=J`` +M`"2PN`^A"H8#Z`+8`:8`V<]PH```#"R@"@A``8X*0``*A@3H`M@!IH#E<`E" +M`,(.H`0!V#(,#_HE`D_C\<#/<(``6!4`@`WH`-B6N,]QH/X\`<]R1`"TVIH( +M8`(JVT(/S_71P.!^X'@!V<]PH```$"F@`-G/<(``+,\BH!D#;^P5V.!X`-H/ +M(@(`SW.``%P,#8M%>`VK!>D.BT5X#JO@?O'`0@E/XZ+!<@FO]XMP"B8`D"'T +MSW"``%`L`8#/<8``G`MN@8(@`@!P<"70"'"'8*A0/H`M@!I1`=@!\``/]_&]@'I8(-C__/<(`` +MX!48@(#@[`O"`1$.D1;/<(``'-W^".`$`-ZB#:_XR7#JR>FXM/+/<:``@!P$ +M&8`/Q>Z$8L]P@`"<"UZ`SW.@```@0:$;@T)XR!,"`$)X`:$`AP*``:'!H9KP +M(@LO_PIP"B8`D"_RSW*``/`W`(+/=8``\#@!WT4($0)-<40A/H,>]"2YP[D` +MV`\@0``OA2MX%O)NA4\C`0`NI9#KP!(!``0@@`\``!\=`>%"(`"`P!I``#(/ +MK^?*(&(`L@]OY_*E"B&`+X``=%0`$0`@>@^O_@IQZ@RO^`AU^@^O_@#?B.7, +M)>*5!/2I=B?P_0V0E!7NJ@T```HF`)`8]``1`2#/<(``G`M$D4"P0X$D@4&@ +M(J!&#Z__]+`(\&(,K__I=L]P@`"<"_F@#PV1%L]P@``(/@`2I[D''SW6@ +M```D`H4`WD'`*PB?`!(/;_>!P`HF`)`-]`'"XKK*(*$"RB&!#P``_@#("*'C +MSR`A`XWN!-@$I1O8!Z7/<(``X!48@(#@=`K"`>H((`8`V(#FUO0!V<]P@`!< +MMB"@^00``."XB`0!`,]U@`"<"PZ%MA4!$2)X9+BX'000#X7QN,!^1O3/<0(" +M`@($(D!@`-P0\"\J`0!.(H,'02O-`,]R@`#L,O`B0@,0(,``#R2,$/'H@.3* +M)B$0&?($(8&,_]@+\B\I00!.(8`'([C/<8``[#+P(0``A"@)#P'9`-X`(8!_ +M@`"`/32HT*C/<($`N"Z""2__S*#/=8``G`L9I14(T0#/<8``2!4@@83IV:4` +MV(<($`#N",_^"'8:""`&`-B`YF[T1"(^TS[T37"&(/P#C"`"@%#2]Y)*L!X#$(DP#/=(``0/``((,/@``\#"2+\"2,$.,,1)``V>_Q +MG@_@!0#85@W/_K,#``"<%0`0SW&``$06.G!$*#X',"%`#@#>">@"#>_K*G`! +MWTH@@"#'\*7-)0C>`00BON\!`0$!#/(O((<*C"`"A@CTSW&``)P+#X&8N`^A +M;@L``(X*K_@(=H#F,?7/=8``G`L/A3T('@0\A=38?@B@`:ER"'`.@! +MV`#=`=IH&(`@)0B0`)#O'0A0`,]P@`!(%0"`"^C/<$4`-#@9B`D('@$`W@/P +M%=ZU[L]P@``LOUN@SW"``$@5`(`GZ,]P10`T.""``-^0OSD)'@3/<$0`#/(` +M@)OH.@^@!P'8SW&``/SY0!G"`RB_01G"`RB_0AG"`RB__@GO]$,9P@,'\!F( +MY+@`WLHF8176"V_Y*G`HZ*CNSW"``+3D`(!!P,]PH```#`V`0B``"(#@RB!, +M`XP@"HW6]YW88<"AS08`\]PH```"`*`SW"@`(!%+:#/<*```!\<@"\('P#/<(``:"@`@",( +M'@`, +M`P0@OH\`-```"_+/<($`N"X,@#3HO@D``05^,/`$(+Z/``H``"/R3'`!")\` +M3'#@N,\F8A'/<8``G`L/@?FXSR8B$L\FXA+/)J(3&/0%)H`?````:]*!!":. +M'P(```!2)DX4*KX%?@KPA28<$`CP#0A>!=X((`')<`AVSW"``#P,'HC$N!BX +M!7Y!+@`702Z"%88@_PS!N@5ZSW"``."[8(A3(_Z`S"(B@!WR`]D6N00F0!`O +M"$``SW"``*!'`X!+>,H@@0\``!DTE`IAX\HA@0,)\."YRB7A%07RX;G*):$4 +M#'#RN,H@(@B<#>(%P'G/<(``G`O8H''QX'CQP%((+^,%V`#>SW>@```@NX<+ +MN"(*[_G)<4H*3^O/<(``G`L/@*4(W@($'YB?`!```'8-X`4%V!#P#'`7"-X% +M+'`3")X#S@@@``#>6@W@!0787@POXP;830X5$0QP]+@!YL!^;'`U"!\`#'`+ +M"%X%+'`U")X##'``V9RYOP@>A\]PH```'"2@SW"``!P,((`0@0'@$*$(\,]Q +M@``LSP*!`>`"H6X(````V<]PI```12*@&O`,;`?FQP&0@?`.X++^,& +MV!T.%1$,<.D(7H4*\#X(``#/<8``+,\"@0'@`J'JR2D(G@//<*```"![@`#9 +MHGO/<(``G`L\$`0`SW#%[H-`HFX`*+@?@#;#O`O*0$`3B&"!\]Q@0`L-_`A@0`0((``)7OTZ,]PH``` +M$'"@X'[@?N!X`-K/<8$`+#<5>>!_0*'@>`/:SW"@```03J``V\]Q@``H+4Z@ +MX']@H<]RH```$"$:&(#/<8``>%1@@2*#(AI8@#A@H1H8@`.#HAH8@.!^X'C/ +M%1`@D*"6&`B>`(@@0!0<.!_RB!&`.!X\<#.#\_W`-G/<*``@`T@H!P8 +M@`\````(5@R/]18(``"*(<0!SW"@`(!^**#1P.!^\<#AQ<]PH```?`"`_]DP +MN%,@S0`'V`JX!+D>"J_F4-K/<:``@`VCH0/8`J&!!L_B\<":#``%"@_/]L]P +M#P!`0@X+C_71P.!^"'$`V`AT#_!3;%5ZQW*``.S)8((-"U\"2()0<<\@`0,! +MY.D,%)3@?O'`Q@W/X@#>#WT>\,]P```2,K8/#^,8\"\H00-.((('3WH0)8T0 +M$VH5>,=P@`#LR2"`:("O?0\FSA#5"5^"C"/#C^;SZNWQ!>_BSW@`V1#P+RL! +M`$XC@@=/>A`@@``#NE5ZSW.``/#)0F-%>?+HX'\H<.!X\_B@-D(=\=P +M@`!4R3IP(*B0Y\H@A@\``'$`SR!F`R@/)N/*(<8#`-X&\,*X`^@`&8(C`>:0 +MYN@`!@"V;]5]QW6!`-A``(7/<8``[,SU>6"1`-H/(H(#:WK=N`"E`_*>N`"E +M(9%+>03RG[@`I3-O-7G/`#9:@[O]1IQ +MA"@)#P`A@'^``"`[*H`/#]$3`H"$X,HA`00`A<]R``0``2\(7P(5Z4MXT2'B +MA=$AX8`)]!L)'@8$(+Z/````&`?R_KG/(.('SR"A!P"E!""^CP`$``&1\^BX +MB_7#N(KQB03/XO'`+@SOXH#8M!P(L,]V@`#LNP"&(KC#N`L(E0-.(`T$`_!. +M(`T(@<`K;78([^<"N2"&SW/_`/\`02E`!T`H`@)D>ABX17B+GX: +M&``3:4$H#`9`*RBX&[DE>`0@@`\`_P#_97A_&A@`BW;)<-8/+^M, +MV`0@@`__`/\`02D"`ABY +M17D$(8$/`/\`_R5X`*0!Y6&^`^[/#1244R7-D!+T;!(`(')P`-A@$0$@RB!O +M`%(A`0#@N_V`(4`'8`?K:O^RJ(+[^L.V)X+``!I +M`L_BX'CQP.'%2',`$H*PF'$"NE1ZSW%$`'#`SW2``$3]KXS/=($`0#<"O;1] +MI&1181P4A1#/=$0`;,!"9$HF0`#`NH'BPB:"`08*H`4"VL]PH```(#N`SW"` +M`!R\5@_O_R"@`=C"&ABP`-C]`>_BPQH8L.!X\^"@_CSW"@```@ +M6X#/#`G`"`"@)8@!``"I@`B4B1,)D"@RB`!!!`)H?7*(4$$!<`` +M(!$&.A$`(3,(L@!&A@`@F#]$`/B_?!`!,#!RRB"&#P``F"<("@;C?!``,`6F +M.A$`(1RN#Y:LN`^V.!$`(2*&1H:."*`%?(X(&T(C!!,`(`'E@+@$&P`@`><* +M<$/``<"E#P40H0X1(!8+```,%0$@&G``V!<)7@$R;31YSW)$`&S`(6+@NBI<)(-;_^I<<]P +M@``\P:"@90>/XN!X\<#>#H_BLFBT?0`ED!]$`/B_=!``(,]V1`!XNR5N0X;@ +MN,$J80'3(B$`P")A`!'R'0K>`<]R1`!PP+)B@>+,(J*!S"+B@@3T`]H#\`#: +M3V$5"!X`!""`#Q\`_O^&"L_U%'@?9\]P1`!PP'();_JH8!4(40`#A@\(7@%T +M$``@"0@>``KGP0:OXNEPX'CQP.'%U\DW"!X`SW)$`'B[`=TDBJEP<@]@!4." +MU\F@N-<:&+`""V``J7!V",_XN@]/[,]P@``,O*"@F0:/XN!X"0`@``';X'CQ +MP/8-C^):<+IQ2'>."2``.G.R:+1]&G#'=8$`0#<(C0`2@;#`A3!P2B-`(,(C +MPB0"N!1XSW%$`'#`$6$*)(`O1`!LP#`D`"`<%H40P+B!X$HF0`#")H(!2G`! +MVEIRZ7,2#F`%"B1`!+L#@"4(7@$(C0*X%'@P)``@&0@?`"06@1`@\O]+M$BA<)@P!2:51ZSW-$`'#`4F/E"(&``_"*(?\/X'\H<.!X`-D#\`'A%PF5 +M`1)I%'C/+O@?P2( +MX'CQP.'%"''/42;11X#PVU$0-B`(/U"0&`!.L1#901SW`` +M`)(G6@[OXJERO02OXJEPX'C/<$0`>+O@?L]P@`!$_>!_`(#@>,]P@`!$_0^( +MSW&!`$`W`K@4>`)ASW&@```@U,D[@1)X&6$!X0:"*KDB>.!_"KC@>/'`PA(! +MML]P``",)^X-[^+#$@*V`-C1P.!^X'CQP,+)@.!@"N+_RB"B`-'`X'[@>/'` +MX<7/`PLG*)V(@@^`*)(`O1`!XNPP4`"#"(4(D'7A2(```4R`3``HE@"^! +M`+@N%!6`(-82&;9"(%"``=W*(&(@H@YOZZEP`!*!L)AP`KGJR0HF@"]$`'#` +M-'DT)DP@+P@>!T`K`2(%(0`$0"D#)`5[0"\")A"\SW#%[H3(J7%E>BMST@W@ +M!`4D!`,`RS)H-'D@9D4('P#"R3T(T0`,%``@-0A?`!05@"`M"%``ULD$(+Z/ +M'P#^_Q#R-"9`(!D(`08`&D`C`]C"&ABPPQK8L_X,K^L.V%4"C^+7R8"XUQH8 +ML`'8PAH8L`#8X'_#&ABPX'CQP!X*C^+/=40`>+MCA2AWSW:``$3]38X-"U\! +M)!"!`!,)4``5"UX!)!"!`!R(#0D!``%J#WH-K@2-$0H"`+((S_^`X*0/PO\- +MCBZ.3PA!``2-2PD#`-?)0P@?``6%SW&``!R\(($*N!EASW"@```@&X`9"$4` +M`X41"%X!SW"``/"[R@^``POPZ7"2".__`-F%Z-?)B;C7&ABP\0&/XN!X\2EB`!I"L`7RV@ZO_XAP!?`6#,__ +M"PB1``'8&_`*#,__%PA0``(,S_\(<<]P``"7)R(*S^+#$@&V@.'*(((/``!Y +M)PP*PN+7R=,('X`."```T<#@?N!X\<#R#T_BSW5$`'B[!95`)5$11B"!`X8@ +M_@-$N!MX)7@O(`@@`-A:<,]Q@`"`M@"ASW%$`'2[`*$#A<:-Y8U+"%\!&.[Q +M=LH@A0\``'LGRB'%`[`)Y>+*(H4#)(4*Z3!VRB"-#P``?">8">WBRB*-`R2% +M"^DP=\H@C0\``'XGA`GMXLHBS0,`R\]V1`!PP`*X%'@09@IQ7@[O_P':SW"@ +M```@&X#/=T0`;,#4&ABP!-A6#R_J`-D`RT.%`K@4>`%GX+G!*F$!TR(A`,`B +M80`.\A<*W@$09H'@S""B@2!GX+@#V`ORULF(Z,]P```&*-X([^(Q9@+8 +MPAH8L,,:F+0E!V_B`-CQP+8.3^(:<-H(K_\$V`AVSW6``'C;`(4``A`2`H@>&E(G`) +M@"&G`Z`@!]14D@"15D"$*<@`! +MV1200"8#$D"C0",!)3A@`:,`EP+96&``MPP1`"`=")X!"=@6)D(0`*+/<(`` +MQ"\!H@"7`>$)X`"W,A0`(1\(4@`P%`,A%B9"$`"B0",,)9MC8:)`EP'A6&`` +MMR2E#PE1``"&!:4!A@:E`O#%I4&&`-@*$0$AU@X@!4""P05/XN!X\<#AQ0F" +MC"!"@DAU.O+"$@&VPQ("MH+AS")A@,H@@@\``(DG5`^"XM42`;;6R1`@0`#6 +M&ABP*87/<(``7%0O>R"@!-@O"U``PN//;?#I21-05/XO'` +MO@Q/X@AW`-X6\+)NM'W'=8$`0#<(C1L/`1`!A1<('@`@A0'8`@@OZR"!`86@ +MN`&E`>;9#I21\01/XO'`=@QOX@*XSW&@```@;!$0`!1X`""1#X$`0#<($8T@ +MM.7*((H/``".)U0.JN+*(4H#$FT4>``@D@]$`#C`.!(!(<]W1`#4W2]X%B=. +M$RX/[_DLK@VNSW&``'RV`($`V@ZN0*'/<8``@+8`@4"A#Z[4R0#<`B`#H!-Y +MRB1O$``A``2`Y,HAP@#*(0$`!!$`(.&XRB&"``2&.&`$I@3M`(\-"$,#.!(` +M(:"O`Z\%V-X++^H`V2$$3^+QP,H+3^(H=0`2@;`(=[3ARB"*#P``ER>T#:KB +MRB)*`\]V1`#4W0#9#PU1$R"N`M@!KB.N!?``CJ&N`>``KG8-#^PD;@*N`-C* +M#6`"0"8"$I8-0`$3"%$`R7"*(08+H@S@`.ER$/#/<(``2!4`@(#@RB"!`\HA +M@0\``*P!!`SA`,HBP0-`)@`3`-DJ"&_GBB(&"*4#3^+@>/'`X<6,X`AU1`[" +M]$(*P`$>"V_YJ7"9`T_BX'C/<8``1/W@?P"AX'C/<40`>+O@?P2IX'CQP.8* +M3^*:<+IQ2'8:!P2A0`*(H`O1`!PP#0B`2#/+N`X,!]DEA@JY(0D%`#N"SW"``!"\(*#@HPCP@;@! +MI8IPQ@DO]2IQ\0%/XO'`M@E/XL(2`;:$X%KHO0%/XO'`X<7/<40`>+L#@1;= +M"PA>`:EP$/"X$0$&(0D5`C,F07"``$#C0">`__U1H8L,,:6+//<0,`N+//<(``>-L` +MV@#;@@@O]DHD@`'/<44`O"(`H0OP!-C#&ABP`-T'\$_8V@FOX@>X`=TY`&_B +MJ7#QP+H/#^+7R88@<8\%])(+C_\5"%```=C"&ABP`-C#&ABP@?##R?<($0#/ +M=X``1/T/C\]U@0!`-P*X%'@`90HB@"]$`'2[`!`0```2`"#%"!```,L*)(`O +MH```(%)H5'K'`9E,GEL%``@.&`!X":&*K@">0P3`"`EN"X( +M(`7`N`IP)!:!$`':`-X"":__R7,,$P`@#0A>`2X.S_09\`'88@KOZ@IQK@W/ +M_PAQ0@ZOZ@'8+X\"N31Y/64`I1@80`1L%`$@(J`!A8"X`:4!V'X.K^H(<0`: +M@",'\`/8PAH8L,,:&+!B"&_K#M@!V/$&#^+@>`':!/`0(,``&^@O*0$`3B&# +M!VAQ@"'"`93CRB'%``*Y,"&,#Z``&"PR:S`A@0^@`+0N+WDP=,!ZYNH`V`+P +M`=C@?N!X\<#AQ00A@H_P_P``SW6@```P!?(TNFT=F)`4N-.Y)7B4'1B0`_!^ +M#8_VE!4`EOL(WH>M!@_BX'A2:,=RH```+BB"0(+/,.XX'[QP,]P@`#PO/H,K_M:V<]P@``PO,]R_P$` +M`"X((``@V<]P@``DO,]R__\``!H((``"V<]P@``,O\H,K_L"V='`X'[@>/'` +MM@TOXIAP`-L/\'UCM'UT)0X1`>.5OI>^XI4!E1"_Y7A%>`"FZ0M$@/D%#^+@ +M>/'`SW"``/"\-@ZO^UK9SW"``#"\*@ZO^R#9SW"``"2\'@ZO^P+9SW"```R_ +M$@ZO^P+9T<#@?N!XSW*@`(`M"H+/<:```#!/($,"B[OPN&JB`=C"(`$`";A% +M($`!M!D`@`J"SW*!`(!X(0@>`,]P@0"`>3`:&#!9(@`(,1J8/_]___\O&A@P +M#_!"(@`(,!H8,,]P@0`@=R\:&#`Q&I@_#P#__\]P@0"`<``9&(#@?N!X`-D2 +M\"\K`0!.(X('3WH0((```KHP(H(/H``T+\*Z#R&!`"]Y\.C@?RAPX'CQP*(, +M+^(`VN.(SW.@```P(8@/(L(#!A"1`!)OQW"@`#0O`!B`#Q@!``"2$P"&4GVD +M>)(;&(`Z$P"&SW:``)0HI'@Z&QB``(:D>`"F`88BZ!4F4!`0$``@2WC*(($/ +M``"?(4P.8>+*(L$#$!`!(``G@!^``.0HI'D0&$`@_]D@J`.&I'@#IA4F3A0< +MAJ1X'*9U!`_B\<`2#`_BSW"``%@5`(`)Z`#8SW&@_L@#<@AO]Y:X`-X*((`O +MH```,,]UH```+M6E#]\(OP/P(@N/]A.%Y'B,(!"`^_,$&)BC`_`."X_V$X7K +M>/WU)00/XL]TH`"`+%BD>:0,N)VXG[@%>3>DX'[@>/'`J@L/X@AVB@_O_RAU +MR7`V#>__J7$%!`_BX'CQP.'%SW&B``!P`A$"A@#80!$!AORZT2$A@"3RSW&B +M`.1L`($!W8"X`*'/<:(`6'$`@8"X`*&J""`%9-C/<:(``(`#@:"X`Z'/<:(` +MQ&T`@00@@`___P``A2`""0"AJ7"E`P_BSW&B``"`"*'@?N!XSW"B``"`"!B` +M#W@$S@#.W(&@SW*B`*QL((+/<`#^__\$>04A@0_.````(*+/`5]H*,`@@0@ +M@`_@__\/!2"`#P<``.``HB"$SW``_O__!'F3N9>Y(*0@@R1X!2"`#W0````` +MH\]QH@`T;0"!AB###T4@0`$`H0+9SW"B`(!L*:#@?\'%X'CAQ7S8SW*B``!X +MSW&B``!T`Z$$H>O8!:$$W::AJ*&JH0G<3!H8@TS8SW&B`(!U`:$\VV6A`=@2 +MH3+9(Z(DHJW9):*FHJBBJJ(0H@C9,Z)WV3VB0MF,&D``3!H8`TC:SW&B`(!Y +M0:%EH1*AX'_!Q>!X,-G//'`C@DOXD0H/@VDP4HB`"C/<:``@!QZ<6P9@`0`V9IQSW:@```4 +M(*;/<(``(+\`@`H@`"<`(%$.SW>``)P+`!$!(4R'4R&``$`A#2'7NE$(T0#/ +M<(``2!4`@`GHJ@M@!BIP@.#*(`$%+_(/AYNX#Z<"$8$@-!>`$$`A`B45"$$` +M"G"I<>X+(`!`)P,<#=D:\!*'D;B2N!*G`-@7\`'8[+G"(`$`!=D6>0^'F;@/ +MIP"%17A`P`&%0<`"A4+``X5#P`/A(:8!V(CH#X>7N`^G`3&(!=HCN<"Y-GK/(1!A0.,8PFPY\)]`04#C'1=C +M.'%SW.!`+@N+(,YZ3:3-^D(<88A'`!/ +M(4("#I.*NL]S@0"L-VV#R[B/N@T(P`!0(L$`!O`%(8$/```8QDQP`0@?`4$J +MP$#`N`:X)7@O")X!SW.!`+@N4),ODQ"Z17FQD\]S@0"L-U"#CX-0=!X\$<]P +M@`"\"^2`)8``V/!_N@HOXA#:SW*``!B_8(K/"=R:H*) +M@G!QS"`!@P;W3R7.$8^^!/`)HBJBSW"!`+@NVK"!!^_AR7#@>/'`]@[/X0HC +M@"^@```H&Q,,IL]V@`"<"P&&OA:"$%,@!@`*((`O@`"`W@`0`"`-"@$`4R0! +M$`3P02R!%Q8A@P#'(3C`=W`?1>]I7@+($"$#Z9S],]U@`!0\?`EQ!!`*8<#!2<-`1BZI7HR +M&YB@#0N1`*(*K^CI<&'PAB5_C2#RSW*``%P,`HJ;Z,]Q@``<#!R1C*9DN!RQ +M!-@#J@2J&0O1`!P3`*8-IAR19+@3(;6*"SN`^F=07/X>!X\<`R#<_AI<$(=P*+*'9Y<*"+9,`1'$(S`!($ +M`0(2!0$$$@@^Y17D`(0(! +M4'D`'(0P1Y9'>3QZ#[DE>@`B00$P>@(<1#!<>0^Z17D!<3!Z!!Q$,%QY#[HE +M>N!R4'D&'(0P/'H/N25Z`")!`@@<1#`P>EQY#[I%>1EA,'@*'$0P4R6!$86Y +M"+DE?:"W()8G>!QX"+@%(,`"`;<`P`&G`<`"IP+``Z>!!._AI<#@>`]Z2+@/ +M>,]S1`!`BO0C``!`*`$"2+@%>?0C@``P>>!_)WC@>!#:SW&@`(`<6Z$!V\]R +MH```&&:BI!`!`!\)W@("V!FBSW&!`*PW!($"H@.!`J("@0*B`8$.\#R0AB'_ +MC`+T>:(4X".`(J(B@"*B(8`BH@"``J+@?N'%!+E`(`(.QW&``.3I@(%A@HHE +M#!!@I&228+1C@F"D:))@M&6"8*1LDF"T8)*D>PT+00-H@F"DSW>@```$A(88&BX$Z$-C/=Z``@!P;I\(.[^$"V`/8&:$`@`PXA@\]RH```&B>B)).*)`P0+K(C@R>B*),N +MLB6#)Z(LDRZR().$>0\)`0,H@R>B,I,NLB"0`),,L@&3#+(.DPRR%),,L@N# +M!J(,@P:B#8,&HBRRX'[QP)H)S^$:<."(`9"S;UIPM7W'=8``[,E"*`X"P;X/ +M")X#$-G=K0'8!/``V`'9W*VZ<`$0D2`6)L`3QW"!`-A$`"F4`Q4@4P4;"M\@ +MSW"``!R_R6``&T(@.XT%(0`%&ZU-\&8.;^@*+3(2$`@N;*((H/```O)0@+ +M*N+*(8H#SW6``(#>0(6,(@*``_3@I0KP4'?*(((/```\)>P*(N+*(<(#0"`` +M)4`M@2$%OCYFW64D;>8-(`$0VL]Q-EPX7,]P-EPV7"6E!J4'I0BE]0#/X>!X +MSW"!`%`X`!B`#Z```$P$&(`/H``$3`@8@`^@``A,#!B`#Z``#$S/`!B`#Z``0$P$&(`/H`!$ +M3`FBSW`(````"J+/<0$````X8`NBSW"``,0T`!B`#Z``8$P&HL]P@`````>B +MSW$!``"`.&`(HL]P@``LW@`8@`^@`(!,#*+/<(@````-HL]Q````@#A@X'\. +MHN!X\<#*#X_A"'8H=QIR`-T#\`'E'0U5$1)M%'C'<($`I#0A@/$.1)`"@.D. +M!9"%Y+*(L$#'N\"O;1]QW6!`*0T`841#@00V6<- +M#D40`H41"$4``=B.N,EQ;@DOXNER(87)<&"%Z7*^#&_H"B0`!+4'C^'/<*`` +M@#`"@!$(7P**(=\/SW"@``!-(*#@?N!XSW&@`(!,&(%&((`"&*$)````X'@` +MV<]PH```32"@X'[QP!8/K^$`VL]PH`"`,**`SW"!``!PSW$````0*@_/_\]V +M0````,]Q!@``@!L-GQ+/<$:``'V@@,EP#@_O_P':R7"I<0+PR7#^#N__`-HY +M!X_AX'CQP,(.K^$`VL]SH```(+N#@.``)80?:@#`SP'8P'@3>-"X`B"`#P$` +M``#/=*``@'H\A`CP/(1;@Y!R`-K*(F\`!"!.``<(@`-VZM%PRB""#P``"@-D +M"`+BV0:/X?'`X<7/$(@`(#@ +M?\H@8@#QP`X.C^'R$@&V],D!W"5X*6@+>0#9SW"!`-`VQ8#AP<]U@`"<"P^% +MPB0!$UL(W@(.A4`5@1`="!`%C.Q$N<&YA"X)'P`A@'^``*`\&.`I8$\A0`+/ +MB"$(WP$#N!9XSW&``."Q`&$$((`/````$`4@@`0O(@@@$-C/=Z`` +M`"`\'QB0"B6`)(8E_""*)P(E%0W!)4HF`"C/=8``'`PT%1`1#_`!V5$A@*;/ +M=8``'`S"(4$`#M@R%1`1%2!6`"&60"``)0\(10`"(0$$+R-((`/P2B,`(,]P +M@``4VP"(@.#$W,PE`J,A\@0AOJ\`!``!#O)1(8"F`=C"(`$`%28!(,]R@0"T +M128(+_,J<`HD@`^!`+1%2B0`((IP*G'*<@X)8`8*`/H>8* +M(`#)<,()0`"`X,H@X@"L"F(`P'E*)0`A%?#/<$4`:"$`@".&3@[O]$2&((4- +M@0'@#:'R\0#80(6.N"Z"NG`!X2ZBSW"@```(!!@`!8.&0"L!)$B6,+P4E1"Z +M`B`#("IP!2&!!!H.8`2%>DX*#_?(%P$0`"#`)")X@.#*(`P%,8<0>"\(1``# +MABB6,+@0N25X`AH8,*#8`:=$'P`5%)5BN&)P$:<"V`(#@RB`,!1&G`M@''QB0(-@`I\]Q@`"L +MSQF!`>`9H0KPSW&``*S/%X$!X!>AY@SO]@+8`-E*)0`AI,V&(/^%(?2,(@.A +M'?(?"Q$@SW"``$BZ18C/<(``F+E$*CX+,"!`#A\(7@"D&IR_````$`OPSW&` +M`*S/&($!X!BAV?&D&ERU*'`(W/,!C^'@>/'`N@F/X-![Z7$4VH(*8`8*)``$"P@>!@IP./#+R<]Q +M@`#@L1"(`]H#N!9X`&$$((`/````$,]QH```"$*AA2`#"0`8!%``&`14BB+_ +M#P`8@%``&(1?``#__T2%`!B`4$J5`!B$4`09``39R>399H!.D#"[$+KI<&5Z +M8@Q@!,ESE@@/]TX/0`0!V$D!K^&AP.!X\<#/<8``*.0@@>'!`!P$,(MP!-F" +M"2``BB*3#Z'`T<#@?N!X\<"^"(_A"'8H=2AP2'$`VB(*(`!(#W",2# +MH:.B#D`$`=@(W*<`C^'@>/'`*@B/X1IPSW&``$14`(D-Z,]P@`!<%<&!XH$" +M$1$!H(`TO2KP3@_/]<]QH```*`(1`(;S")Z!51$"A@#=51E8@P+8!!D8@"\H +M@0!.(($'$>K/<(``5`DV>,"`X8#/<(``U`GT(%$`(.#P($T`R[T$\*EWJ78Z +M=000`2``&$!0"!`!(0`81%#/<8$`&#<`@0;H0H$`V``8@%``H<]P@`",JP&` +M!H#KN,H@@@/*(<(#RB)"`]`*(O[*(T($4R'!(`RY0"T`%25X@K@`&`!0`!B` +M4P`8P%.I<"IQR7)B"F`$Z7.M!T_AX'CQP$H/3^$(=2AV2'=3('Z`RB""#P`` +M!CPL">+ARB%"`\EPZ7$!VIX((```VX'@RB!!`\HA@0,0""$`RB)A`'D'3^'@ +M>"*Y!O``'\!`!.!AN?D)M8!@@,]PH```#&*@`]DGH,]PH```(`/J9AA8@#N` +MSW"``&PSX'\@H.!X\<#.#D_A"'4H=DAW4R!^@,H@@@\```8\L`CBX'AN,\AX@,`W<]PH```(+"@4-@.VJEST@X@!IAU`-Z8O@0@CP,-"!\&;@Q` +M!`0@CP.8[\39`]C/_R2G(:<,]PH```(+"@SW"@`(!% +M,!B`#P`@``$!V<]P@`!L*""@:B*``<]P@`!P*$"@SW*G``!\`H(7"!X`H+@" +MHL]SH```$"FCJ:.`N`*B$=A^#N`#`-DO(P@$$-CI<2IRY@T@!@HD@`3XN,!] +M.O0#V,]QH```"`*A"P^>%D\AP"<*H8HB!`(`&(10`!A$4\]P@0`T27&`SW*! +M`'1)`!C`4(22`!@$4Y&``!@`4X22`!@$4W&``!C`4$22`!B$4``81%,`V@3P +M`!B`4`'B^PJ$@Z&A=@I@!`'=$MCV#>`#`-FJ":_MBB`0`*EP"-R3!&_AJ,#@ +M>/'`X<4`W0[PSW.``*B_`(,!X`"C6&$.#@K`?%_\]S@`"DOP"#`>``H]3Q`-A!!&_AX!H``/'`X<7/<(``2!4`@*'! +MGNC/<(``(.``@!CHSW"@```,K8#F""_TBW"#Z`L-%1$=#10>SW"``$P1SW(` +M`/\/.@SO_P39#@B/X?$#;^&AP.!X\C"!`` +MR\G$$```A"@)#P`AC7^``"`[)@TO[$H@`"`0V`W9CKDPVEC;3@P@!@HD``0. +M#2_L"'?XO\H@`@0Q](HG"!!-'MB3`]G/<*````@BH(C:`!B$4``8!%1$A0`8 +M@%!*E0`8A%!$A0`8@%!*E0`8A%`DA0`80%!*E0`8A%``&`!4&MH$\``8A%`" +MXOL*%(P$&``$)@E`!`'83A[8DVX,#^P=`T_AX'CQP,]Q@`"/'`,@D/Y3Z@T<#@?L]R@``HWB""@ND`HN!^X'CQP.'%H<$(=8MQ +MV@QO]P78!^@`P<]P@`!0,#5XH*"Q`F_AH<#QP.'%"'7/<(``++\4@('@S"`B +M@`KT\@D/Z!$(10,#V<]PH`"`'2:@@0)/X<]P@``LOQ6`+P@?``/:SW&@```0 +M,!F8CP"@"```'X!/`(````'8`AD8@`<9F(#/<*``@!U&H.!^\<`:#"_H`-@" +MV<]P@``LOS2@T<#@?N!X<0$/Z`/9SW"``"R_X'\TH('@`=G"(4$``=@T>,]Q +M@``LO^!_%J'@>`'8SW&``"R_T0,OZ!2AX'BI`P_H\<#&"R_H`-@#V<]P@``L +MOS2@T<#@?N!X\<`^"P_HB@\``-'`X'[@>,]P@``LOQ2`@>#,("*``=C`>.!^ +M\<`^"6_A`=D(=5$@0,3"(4$`42+`Q@'8PB`!`"MX-/02"0_HSW:``"R_Q@_O +M_Q>F$.@7AAT-!1`*"0_H%0T%$,]PH```(!N`H@DOZ!BF!_#/<(``2!4`@`/H +M`=@5\`?8"KC`V1BYV@SOY#MZ`]G/<*``@!TFH$X++^@"W8#@RB!!`P/R`-@I +M`4_AX'CQP+((3^'/=8``++]8A2+JSW"@```@.X`7A4)Y#PDE`(HB#PHB>`D* +M!`!(<`#><@HOZ,EQS@@OZ-BESW"``%@L0(`'V`JXP-D8N6H,[^0>NM$`3^'Q +MP%((3^$(=L]U@`"<"P"5.G&&(/\,B.!*($`@SW>``"R_-(?"(`(DA.',)F61 +MB/>*((X$*@JOX<%0`0A.`!V,H@`02&Z0;H%H:"ZH`KP:'!B"2_H`-FI<'H)+^@!V=T'#^'QP&(/#^'/=H``++\9A@SH`-T^ +M"2_HJ7$:AKFF4@DOZ*EQNJ:M!P_A\<`F#P_A+@ZO\J+!%@ZO\HHG"!`(<<]P +M@`"$M@"`"B&`+P8``("#X`'8P'B+ +M6G`@H,]P1H``?2"@0:``W3(:6#,7\`'`NWE$*#X'SW*``(S=0W$4(4!S$&)F +M&1P`4R"^@1]G+`SB_\H@8@`!Y=D-E),,($"D'`SM_\H@K0``A@&`$'<,#.W_ +MRB#M```2`"!3(/Z"_`OB_\H@H@$`(X`O0````,]Q@`````NA`(8$@`RAC08O +MX:+`SW&``$3M\"$```#9#R$!`,]PH@"`*#&@X'[@>,]R@`!$[?`B``#/@"")G@`HN!^X'C//'`O@T/X2AV +M2'?/=44``",6?4&%`KE0<6%A@`*Y<''*((T/ +M```J,\HAC0!D#VWARB*-`U,G?I#*(((/```L,\HAP@-`#V+ARB("!`?P!!<` +M%&&^!!T0$/SNB04/X<]Q@`!$[?`A```*N#`@@`^B`,`DX'[@>/'`F@D``#() +M(```V"H)(``!V"8)(``"V!X)(``#V!H)(``$V!()(``%V`X)(``&V`8)(``' +MV`()(``(V,]PH@``"!08@`\`$1$1$!B`#P!`=G8N"2```=C1P.!^SW*``$3M +M\"("`,]PH@"`*%5X(*#@?N!X\<":#`_ASW"B```(HX#BO=$EH9(0\L]V@0"( +M+@"&@.#*(($/```M,V@.8>'*(4$#`(9`>.:]T26ADQ'RSW:!`(@N`H:`X,H@ +M@0\``"TS1`YAX,]Q@`!$ +M[?`A`0#/<*(`@"CP($``X'[@>,]R@`!$[?`B`@#/<*(``"A5>""@X'[@>(+@ +MS"#B@`;TSW"```Q1(*#@?N!XSW*!`(@N%7K@?R"B\<`(!"BX'[@>*$'S^0` +MVPT)T0<`H@'8!_`)"=,'"0D3``#8X'X?W`7P#R,#`V&\_0D"@PL(3@!E>.WQ +M9GCK\>!X\<`Z"P_ASW*``!3`8(+/<8``;/&5F0.B`-T3""(#Y&D'V`'9(J(` +MHCWP?&.4?#QDPYPC"((#@6L"\`'D$PP5$IUDM'TU(4T#\PA#@QCP`=@8\(&< +MD7#*($H#RB3*$%+V:'0#\&&\=>R=9+1]/67!G?4(@X/\%4V1[0A"@P'88;PC +M"!X`@.3/(&$`RB$A`07RA.N!N`'9(J*`HIQDE'R19R&B!0,/X>!XSW$#`*S> +M`=AQ`V_S!-K@>/'`A@H/X<]U@`"`,]Q@``4P`'8Z@J@ +M`B&!#0Z>$-8*K_@0G1D.7A#/<0,`K-[/%7C/=8``2+FY8`#8$_``((,/@``\#(2+%2$"`.*"`>#\9(*B1(L/ +M>(PB`XS*)BL0X0C2@`6)`>`/>@L*,P$%J1D.41`"V`"AH@POZA+8!.X!V$`= +M&!!!`@_A\<#/<($`*#CL'`BPSW"!`#1,0<#/<(``).!"P,]P@``HX$/``-A$ +MP`K8!-D&V@+;"B2`#X``+.`*)8`/@``\P$HF0`3*"N_S2B=``*7`T<#@?N!X +M%0?OYP78X'C/<(``++\6@('@`=C`>`$'[^<#X/D&[^<"V.!X\0;OYP#8X'CI +M!N_G`=C@>.'%ZA(,M@M\(?(":P4@@`_%[H#ASW6@```@SW2@`(`<`:0;A=*Y +M`:1`*\`$)7B?N`&D`-D)\/`B0``P((`/H```8`'A`:3S"<2`X'_!Q>!XX<7J +M$@RV"WP>\@)K!2"`#\7N@.'/=:```"#/=*``@!P!I!N%TKD!I$`KP`0E>)^X +M`:0`V0;P\")```"``>$!I/<)Q(#@?\'%\<">"`_AH<&:<'IQE@I@`!IR.G`+ +M"!$@7@R/^!IPG@@/]`HE`)`%\GX*``"#Z`+8F?"!Y9;RSW"``)`H`(`3Z,]Q +M@0"8+R&)`-@)Z<]Q@`!@,B"!@.'*(&(`8@WO^%IP`^@`WFKPBB#_#P/PJ7!" +M"D``C"##CPAU&/)*"D``SW:``%#'MGX$%H00`Q:%$")H`8A!CF*..@[O^`HF +M@`1HZ.6.!"=/%`3P`-_I=8MQ1@OO]TIP!"!`!"\A!R`%(`1^!'\O),>#SW*``/A.((H$(1$@Q7D@JA[RSW&``%#'MGD@B<]P +M@`!0R4"0#R)"`$"P-&T`(8`/@`"PQXIQ:G+Z"6``"G//<8``_$X`@0\@0`,` +MH14)$"``P(IQ:G(*<\(+[_<*)$`$SW&``)#'&XG+>`?TSW"``&0R`(`*Z#V) +MSW*``/A.`(HE>`"J`=@#\`#8E0?OX*'`\<#AQ38)8``(=:5XB@E@``]XSW"` +M`(#!"(B"X)P(00"E!\_@`-G/<(``0,'@?R&@X'[@>/'`X<4""6``"'6F>`]] +M5@E@`*EPF>W/<(``9#(`@)7HSW"``)`H`(`/Z,]P@`"`P0B($0C1``+8F@@@ +M``#9!?"!X)P+`?%-!\_@X'@'V(4`(```V>!^X'C/<(``0,'@?P"`X'C/<(`` +M0,'@?P&`X'CQP.'%SW&``$#!0"$-">P<2+-5(<`$0<`H<(`@@@!"P%8A0`1# +MP`#81,`-V`;9"=H`VPHD@`^``*3R"B6`#X``Y,%*)H`&G@^O\THG0`#/<0,` +M;.+F">_SJ7#)!N_@I<`(,]P@`"`P0B(@>`!V.!_P'CQP,8) +M3_X#@%$@@($!V,(@`0#1P.!^X'C@?P'8SW"``(#!"(B!X,P@XH`!V,!XX'[/ +M%T"#_'QP.'%R@H@``AUJ7`.""```MG]!<_@X'CQP'H-S^"C +MP0AW*'8`W;H/(`"I<.EP6@RO^3A@`>!!P,]P1`!XNP"`0L`M#I`0 +M"@_/_Y+HSW"``$@5`("`X,H@`0?*(H$/``!M`(@-8?_*(2$#!_"+<`S9]@UO +M_VW:A>;*((8/``!D*ZP.)N'*(88#%07OX*/`X'CQP((,S^#/=X``P,$OCPHE +M@"^``$#!%25`(->(HL$`W0;N$(]Z#>_@R7$2Z0'=!^X0CW8-[^#)<0+I`-T5 +M)4`C#I`!W4HF`"`'")X`VG4>"&_^`-\Z#2``6G?"#R_^@<`$%!?/<(``$,D8 +MB!!W\``&``HD@"^``!#"LF^T?8)UU!4.$=8,[_K)<&WHSW&3U@"D0@CO[\&H(X`,J<#IP8@C@`R38`B$" +M(`IPN@[OX`#9E!4#()@5`B!F>$9Y!2!^@.KSSW%):P#2[@^O[+L#@"L(7X`$);Z?'P#^_X_S!@SO^LEP%0@1@(8) +M[_K/>(#@??7/<9/6`*1\\1((K_Y*<`#9SW"``/A.(*C/<(``4,D@L,]P@`#\ +M3B"@SW"``+#':@^OY;#9C@Z/]\]PH```(!N``!T`(`\*$2`(V)8,[_\!V0/P +MU@_/\/D"[^"BP/'`N@K/X*'!*';/<(``4,FF#"``H)`:<,]P@`#X3N"(SW"` +M`)#':@XO_AH0D@`Z<,]Q@`!`P0&!`>`!H6H([^0'EKWTI#1,2 +M`-@/($`#SW&``/SG\"%!`P]X@.'+(`*@\?,+?^WS`=CL\1H*3_,R#@_^A>;* +M((8/``!C*^0+)N'*(88#-0+OX*'`\<#>"<_@"'7""R``*':0Z,]P@`!D,@"` +MBNC/<(``D"@`@(#@RB"B``#9.O3/<8``0,$5#5$1%HF#Z!J),N@$@0*A)O#/ +M`!``V`^USW"``!2\`=_@H*,6@!`-"!(!8@E/\P+H[[45 +M)@X4#I9/"!X`$)4CZ`Z5S@GOX`79'^D/E9WH*@E/\QGH+I;/<`(`^%#/+M%DCUY7'I2(@(`4R(#``+:='K`N8HC_P\F"6_S2B3`!P7P!]A*"N__`-GM +M`,_@X'C//'`.@H``,X) +M``#1P.!^X'CQP$(([^"*(0L)`-_/=8``0,'/=H``P,'OKO"NSW!$`'B[0@D@ +M`SIP\@L/_@00D@`:<$PB`*W*((D/``!F*Q`**>'*(8D$"B.`+X``$,D8&X(D +M0"4`$PX)(`,8V<]P@`#@P@()(`.*(0D,SW!$`%R^\@@@`XHA"`06C8#@RB"! +M#P``!2C`"0'A#!``(,]Q@`!D,L"X`*$,$``@SW&``)`HAB#W#P"A#!``($0@ +M`03/<(``8#(@H`.%$*X0C@D(4@!AN!"N+I4`V`L)'P`PE0D)'@`!V!"V$):& +MZ*(=PA.C'<(3[K;V#,_Q&-L8NP#:#/`2:A1XSW&``.#"`&%K>,`G8A`!XA@3 +M@"#I"@2`!!&!(`<)4@"'[\]P``"9)SH)+^'I-A@*8`!XJZY +MK[FPN2F@\0J4@-((C^H-"%$`4"5"D`/TJ7+/<8``P,$1B1MX$:D1B5,@OH`# +M]`'8$:E+>/;S-&A7:"5Z)99%>26V`-L*\))KE'S<9"F$0"B"`T5Y*:0!X^\+ +ME(`)!X_@\<"""```C.C/<(``9#(`@(;HSW"``)`H`("&Z`78,@CO_P#9T<#@ +M?O'`9@Z/X!IP*'8`W0+P`>7/<(``D,<8B",-!1#/=X``4,6V?PIPZ7$&"Z_E +M!MKQZ`:/"PX$$`>/`O``V)$&C^#QP,]P@`!@R)8*K^7(V?H.C__1P.!^X'C/ +M<(``$,G@?QF(X'@!X,]Q@`"0QSF)_]HP<.!_RB"&`,]Q@`!0QQ9Y`(E$*+X( +M`"&`?T0`L+O@?O'`W@VOX"S:"';/=8``$,A9)0`3G@L@`%8E01,Q!J_@U*7@ +M>,]Q@``0R>!_&:G@>/'`J@V/X`AV*'`JCFAWB'4$Z2F.$0I%`$FNZ*[)<:(* +M(``(V@J.!7VJKJ8(+_[I<(P@_X\)\D$HP0`^9BN.PK@/(0$`*Z[1!8_@X'BA +MP?'`2@V/X!IQSW&!`-1%*'8,&8`/`(````HB@"_^__\_!""!!,]W@0"(-@HC +M@"^``)P+HX_&$X`@JWA(P2'ROQ.`(`#94R!"``\A@0`$(5�KC!N`#9#R$! +M`"1]#?(#[0L)D"`J=0?PSW"``&`/`(!`>'GH#KT(P*5X`_`!AR5X2,``CPC" +M1+C"N`ZX!"*##P$``,`+>XC!%?+7*'!\<`V#(_@SW*!``1&2'4,&H`/ +M`(```,]R@0"(-H"*0\%$O,*\#KP$(8X/`0``P(M^@\,5\M=V````0,PF@I\` +M``"`S":"GP$````#]$&"`O!"@JZYK[FPN25Z0*,#P0C:+KG"N42E0X5`*0,& +M97I#I0/#8:4-"!X"G;I#I07PBB`&!@2EJ7``V@'>&@SOYLESR\G/<8``E+90 +MB$EA*K40B,]Q@`#TR0.X%7@`80NUJ7!J#&_KR7'`I0C<[P./X/'`=@N/X`AU +M*'93(4``D@O@`DX@#P$;#@00SW*@```$3H+/<```QB)2#>_@R7$`V0?P*F7/ +M<*``0`1`J`'A]PF$@R,/4!`5#Y`0)0_1$`#9SW"@`$`$(*@`V<]PH`!`!""H +M`-G/<*``0`0@J'4#C^``VPGP\"#,`,]RH```!)"B`>/U"T2`X'[AQ:L*$`!` +M(L,#)+O#NI<*%00S)H)P@``(Y$`G#'-4?"!\H(@!&5(#`>`!$(($`1F2``$0 +M@@0!&9(``1""!`$9D@`!$(($`1F2``$0@@0!&9(``1""!`$9D@`!$(($`1F2 +M``$0@@0!&9(``1""!`$9D@`!$(($`1F2``$0@@0!&9(``1""!`$9D@`!$(($ +M`1F2``$0@@0!&9(``1""!`$9D@"`(_^/`-JS]>!_P<7@>%A@66$&\/\0@X)A +MNO\9RH#[ZN!^\<`J"H_@"'93('Z`*'=(=03T4R=^D`GRSW````,\R7$.#._@ +MZ7(C[0-M(KC!O3<-%1$S)DUS@`#TXT`G`7.T>2!Y0(8$'Y`0!.8$%@$4!!]0 +M$`06`10$'U`0!!8!%`0?4!"`(/^/`-WC]2T"C^#@>/'`N@F/X`AV*'=(=>"X +MT2B:#0*0D@2"!&6$&\`:# +M(*0$@""`66'"#J`!:'#1P.!^X'CQP(H(C^``W`+P`>05#%41SW6``*CQC67S +M"T&#`=L#\`#;@.-W\@#;:'4&\`';B75CN0/@2PG4`,"(C"9#D@#<5/;AB!+O +M"?#/=X``J/&/9P\.P!,!Y/4,5)$`W`+P`=R`Y`#I0"C!(*"H-7D`&D(CQW&``.S)(!D`!0"!J;@`H0'8#-SW +M!D_@X'BBP?'`I@YOX)AP1<$4%`XQ,+A`+@$4!7E!*0`")W@PN2=XQK@`((,/ +M@`!LR0+P9VR@BX#?60W?$<]Q@`!LS"ATMGP&C.L*`8#/<(``#,H#NE5Z0&"$ +M*`D/+W"X<,=P@``@.T:`%0H!`0Z0$0X!$``E@`^````]X*@'C+9Y`*O/<(`` +M:,E`B(>]1ZF@J`S``@@@^``.S)FHK/<(``;,P6(`,#8(-@ +MH5J*5G@"D.!_`K'@>`.XSW&```;*%7@)8<]P@`!LS#9X((",(?^/"/0"D-=P +M``#__P'8`_(`V.!^HL%!P004`C%!*`$$0"H#!"5[02L!`F=Y,+MG><:YSW.` +M`&S)*V,#\&>)@-D="]\!SW&``&S,=GE@@?$(P8!BD>D*P8`&B0/P*'#@?Z+` +MX'CQP%X-3^"F#F_W2B1`(`KHT@@/^('@`=BZ#*_LPB`!`,]QI```1$F!SW"` +M`"A40*`Q@<]P@``<5""@SW6``'@+!X6`X$@*`>W!R<]Q@``T)P"A[@NO^@'8 +MSW:G``!(%P1J8 +MOP(``P#/=8``@">-Z"&%4R$``#UYP+D3>#-YP;C!N5X,+_L"VL]QK0"`@(IP +M!Z$;H<]QK0``I1NASW&M`("O"Z$<%1`0(!42$%,@PB!`*@$ABB,#+`0AP01% +M><]WIP``1#6G`H4/"%$`$(9%(,``!O`/")$`$(9&(,``$*8%A2:%@.!*(4`@ +MRB%"(`.%H84T'@`55(25[97I4IY(,;_(8O0/94]@1N""@4R#"($`J`2$$(<`$17@5IP#8#J84AT`I +M02*XN+FXNK@%?;2G$H>`N!*G%(<$((`/___^\25X%*=`'P`5<@F/\2D$3^#@ +M>,]R@``4T0:"!(`@@(`A#PKY`:`!2'#@>/'`R@M/X,]PH```(+N`SW.``%04 +M`(,`W@7H`B4.$`>#`G[/=(``+,V@%`(6`-@`(H*#H10!%J`%`(6!Z,`(8&`GQ0.%IX<6!`!)@X0*8.?')@3I!0"%@FC`"&!@*44 +M#A:D'%@0`28.$*(4`A:E')@3*(,&HZ,4#A8`(8&``28.$*(<6!"C')@34@_O +M_PBCG0-/X.!X\<`F"T_@"';/<(``-.8`@,]U@``LS>'`M@QOZ138SW"``$@5 +M`("*Z""%`-B*Z2&%@.'*(&$`!O`!A8#@`=C`>!_HSW"@```,#8!"(``(2"`` +M`(P@"HV9]YW88,"AS0(/'`X<4` +MW?H)K_JI<$8(C_)Z#L_LSW*``#A7`(+/<:<`@$G"N!"ASW"``$`RH*#/<(`` +M-"<`@*"BP1H8L,]P@``H5`"`SW&D``!$":'/<(``'%0`@!&AY@]O^JEPF@Y/ +M\8D!3^#QP.'%"'4R""```-LI:&AR#?`H914($@P1"),.F@@/[9)JF'@%>P'B +M8;GK"1.`60%OX&AP"'(#\`'@((C^Z>!_0GC@>/'`SW&@``!%`!F`#P!```#@ +M>`#8`*'/<*```!P%@.^XJ`VB``#8`*4$I?4`3^#@>,]R@`!`"2""`-LS"1X`SW&@```=-!F` +M#T`````X&8`/0````(HCR`HB@@'<#R$!`"*BSW"``%C]DJ#@?VAPX'@`W8X, +M;^`&V,]PH```#A"``>4%Z(PE!YVU]\]P@```5`"`%0@?`\]PH```.#`8@`\` +M```(2@D/]P#8SW&@```\`*$$@?\('H`$@0L(7P`"V`.A:2!``/_Q\<#/<8`` +MW-0L@3!P-`MAY\H@@0#1P.!^\<#AQ<]U@`"LTZEP*@POY8HA!`R*(/\/`*7/ +M<(``W-06#"_E0-E2"4_GSW!%`'`N:@U``<]P10"8-V(-0`'/<$4`M#=6#4`! +MSW!%`'@W3@U``<]P10#D(D(-0`'A!P_@X'[@>/'`8@\/X"AV`-TJ"6_SJ7$( +M<80I"0_/<(``(#LP($,.SW"``*S30(!0<\H@@@\``%,T,`F"X)#NSW&``*S4 +M"X&AN`NA+0@?`<]P`P#L^PH+3^<0\,]V@`##@_@"'?F#F_I6G*DB,]Q@``@.XH@"0\Z<`Q]SW"``-P\ +M,"!0#@T-$1'/<(``K-.@B,]V@`#@"6'GRB"!!`2&$'=L#L'_?08/X/'`&@X/X!IPA"@)#\]Q@`!\/#(A +M4@X*(4`N`-[)=1#P`"&`+X``@#RV>."("G#.#Z_MZ7$/)LX3`>6O?>4-@I3) +M<-X,8`(?V3$&#^#QP.'%SW6``*S30(6,(O^/"'$9\H0I"0_/<(``(#LP($`. +M$'+*(((/``!5-+`/0N!+%0`6#P@>`,]P10"T-W8+0`$5!@_@X'CQP(H-#^`( +M=80H"0_/<8``?#PR(5$."B!`+@#>%?``((`O@`"`/-9XX(BI<.EQH@]O[0': +MSW"``*S3"(@0=P@/`>/'`-@T/X"02D@#/=:```"!; +MA<]W@`"LTR>'`-X`(9$`.X5&AP`B4`#N#B_SR7$(<80I"0_/<(``(#LP($`. +M0(<;"(``#0@1`4L7`!8/"!\`SW```%0T\@Y/X%,*42#/=H``K-0+AJ*X"Z8= +M"!\`)X\/"5$`"G!V#R_G*G$K\(.X"Z8I\$\(7@'/<$4`>#>."D`!.X4&AQEA +MSW!%`)@WT@I``0N&I;@+IA7PSW6``-S4`(4)Z)8(K^D`V<"E$@\OZ0S8+(4% +MZ>8/K^@*V,REM@S/_\4$#^#@>/'`SW"``*S4"X#@N)P,P?_1P.!^\<`Z#`_@ +MK\$(=5(,;^E:8/;_\LV@07%!#/<8``*#M`C00J?@4` +M(4`.Z7'*#V__7-HJ<`IQP@]O_RS:!!\`%0'8`*>.P4`E`!.N#V__!-H.P0K8 +MK@FOZ/_:O@ZOZ`K8SW&``)!&#X%(C0\@@``/H6P6`2`/AAEA!H4"><]P10!X +M-XX(8`&9(00`#PL0($PB`*"0"L'_@0(OX*_`\<#AQ0#="?`6#6`!J7`B""`` +M`>6O??4-$I'/<(``&-H."```,@Q/Z)D"#^#QP.'%"'4$\.H/``$N"&`!J7#\ +MZ($"#^#QP.'%'@A@`0AU0H4+Z&*`(((&A09Y!84E>`"B`X5@H`SP`((FA21X +M`*+/<*```!P<&(`/`'P``$4"#^#QP,]P@`#(U2"`SW"``)S5$)@%Z:((```# +M\"8(``#1P.!^X'CQP`7H[@Z/_@;P`=G/<(``G-4GH-'`X'[QP(X)+^``V\]U +M@`"<@ZO_L>ERJ6-`0_@X'CQP.'%SW6``)S5!X4$Z`#8!Z46\#"=`=KP +MX<(BB@`!V'*=57@"(<(`+R*)`!+H)0H$`,]P@`!(%0"`A>@F#H_^"/#VX!X:0,OZ1;8X'C/<$0`$/(` +M@!$(40#/<:```#0`@9"X`*'@?N!X\<#AQ<]U@``P*R"%4R&`!PL(5`)!*?Z' +M!?3/<`\`0$(%\$8-C_(`A=ZX?@V/\MD`#^#@>/'`A@NOZ`G8&@[OY`38T<#@ +M?N!X40)/Z/'`SW"``$#!`H`%Z&8*#_\%\`/8Y@DO_P#9T<#@?N!X\<`B"`_@ +MSW6``##)`(4,>G`H,]P@`!(R0`0P`#/<8``0,D`J0.X#G@%V?X-+^P! +MVL]PH```(#N`SW"``$S)`(#/\]R@``HX@L( +MQ0`">V"EO?$&@L"E!(`@@'EAL?')<`79M@TO[,ERSW"``#C)P*"Q!\_?\<#/ +M<$4`)#D`@)KHSW"``'SB`@T``0#:CKK/<8``_/E`&8(`*+I!&8(`*+I"&8(` +M*+IR#J_Q0QF"``3P0@I/^-'`X'[QP.'%H@@@``AUA"T)'\]Q@``L.S`A00[/ +M/'`X<4(2%D@(%3(D$%4R1-%:)Y.&"`X""@02J!!3:\@GG5!N_? +M(:#@>(0H"0_/<8``+#LP(4`.SW&``&37`K@5>`!A`(#@?N!XA"@)#\]R@``L +M.S`B0`[/F"B8:(!X2]Y +M\0D$@.!^X<6$*`D/SW.``"P[,"-,#L]S@0",119[H(,!@P(A08,#(@(`$FP5 +M>,=P@`!DUV*`(*,#@$"@X'_!Q>!X\<"Z#<_?HL$(=2AW2';:#"_GBW'/<($` +MC$6V>&"``,(!@``BPH`!P0$@0`!!P$"G`<``IO$%[]^BP.!X\_?HL#@>/'`/@W/WZ3!"'""` +M`,)980(A@8`!PR"@`R7-$*&@407OWZ3`A"@)#\]Q@``L.S`A00[/E!X1[$($`,@8:$A#AX0"P\>$$\BP``'L0L/ +MGA"$N`>Q!-@&L0.5@[@#M1\.GA`+#QX1!Y&#N`>Q#0^>$0>1A+@'L0:1A+@& +ML4IPW@M@```0`B!$)KZ2-/)J#$_I"'$"A6>1`J%/(4`A!7MGL0P0`"!P>F&X +M`:$A#EX0"P]>$$\CP@!'L0L/WA"$ND>Q"-@&L0.5H[@#M1\.WA`+#UX1!Y&# +MN`>Q#0_>$0>1A+@'L0:1A;@&L4IP<@M@```0`B#I`\_?\``+37`8<$'D($":<&@0HD@"^` +M`+CU)!Q`-$`G&16*Z,]P@`#,V@2`PG@1"(4/````$`HB0"0J<1#P2@\@``07 +M`""$X`AQRB)%)(;W!!<`($HB0"`!IT*'V0H1($`D!#D`V4!X,&XW@X@``&G"'$!V``<```$'@(`"PT5$>4)$H1O#1$1`M@` +M'```!!X"``07!!"*)\,/$0@S)`0?P!%`)$``4R!$`$HE``"(=1SPRLE4;98@ +M!@!88&&`A(":VIMC"2."`$2@`8<5",$!>@X@`*EP"0@R!`AQH:"R_@984"AQ\( +M40`)A0L($0$'A07P`":`'P<``/`%I0@=0!0&\``F`!0%I0'8`J4!A\2E`*4" +MV"4$(``8'``@FNH!V=X(K^DBI0&`@<%$A66%0@\@`$HD```!P(?H`\&J<+H- +MX``!V@6E!-CQ`R``&!P`(`L*E``!A0T(00!*)@`@F?`$A0HC@"\```!``";! +M%")X/[A2(`"`2B8`(&WR@@BOZ0&'@<$!@,ER9(7F#B``2B2```'`2B9`(+L( +M$0`#P0`0`#"9"0$`5@A@`."%`*4(V1@<0"!M#P$01@B/Z42%A<$!@&6%J@X@ +M`$HD```%P`L(40`%A4?`[@P@``"%!\(*N!EF`B&``#^X4B``@`KR184"(D`` +M"0A2`$?!&_!'P@OP!,%DA0`AP`0">S^[4B,#@`/T2'$-\$?!`,`8'``@"?`$ +MPB2%`"+`!")X"PA2`$/!"?!#PDAQ!_`!AP"E$-@8'``@):7$I:IPK@S@``': +M[0(``!@5&!`%A0(@``8+"%,`!(4`(-@$F@]OZ0"%@<$!@`MR987Z#2``2B2` +M``'`B>@#P:IP<@S@``':`\`%I4&'8(5P`T(!2`"AUT(40`"A<2E +M2PA0``*'#0B4``)VQ:4=\"F%#0D1`0>%!:45\(+AS"&B@0WT"(5GA0#:$'/* +M(F\`@.+*(,$`!:4%\,=V!P``\,6E@[DII0'8`J4@V$4"(``8'``@`=@DA0*E +M`B&,`PHA@"\```!``"!`)"<,!!#$I00@@2___P#PV6$EI:IPT@O@``':0-@- +M`B``&!P`(,K)]&J6($8`X&!-"(4/````4/`A@C!">$`H@@(`)$`4.0H%`#4, +MA!\```"$`B&!#P```$0EI<2EJG"&"^```=H@A8#8%2%9,!@<@"\````@`!D` +M,-CP<@YOZ6AP@<%EA0`F`A0!@")ST@P@`$HD```!P,2EC>@#P:IP1@O@``': +M`\`%I8#8&!P`(+SPBB`$`!@<`""X\$HC`"!*($`P"!T`%N$*$2`C#E$@'@YO +MZ6AP`8"!P62%R7*"#"``2B2```'`@.#*(P$FT0L1(,(*(```A0HB@"___P#P +M"K@$((`$)H4`)A$0`B%`(%,(<@`@A007`"`-"$$`"```=J*(`@`&!P`(!+PQ*6J<-H) +MX``!V@6EBB`0`!@<`"`&\,2E&!R`+P````B-!:_?JL#@>/'`3@V/WSIP#!`5 +M`%IS`!I`!0#>P*,&@!IR`^`BN$`@E``0$0`@(KBH'`BP`!$`($7`!!&`($G` +M!-A(P`P1`"!'P(H@U`!*P`@1`"!&P07HBB#<`$K`A<"!Q2H-(`"I<0#:"/`2 +M:H-P(8`!XC)Y(:#U"A2!`-DH=T`D$SM`)!8\J7``VFISH@D@``HD@`4,PA;H +M"\%")$`@`B)#`"$+!`#[>(-P-!A"`(HA_P\U&((`"PI!`'_9-1A"``'GBB#_ +M#R%J"PH``+4/%)3_V/M_@W$(D02`/"$0``,`0=L`E;A`<$0`@!2A^`4$ICW#? +M9T`E10#1\24$K]^VP)1HSW.!`*0;F6,C@9MC2"$"`,]Q@`#(U_`A`0`!@R)X +M2"```.!_"2"``.!X`-K/*, +M(,./0J,#]"&C`>$O>>,)$H&$ZO_8`:/@?TAP\<#AQ<]P@`!T.NX/;^2LV<]P +M@`!0*^(/;^2*(00`SW6``,S:J7#2#V_D2-G_V`"E`:4`V,D#K]\"I>!X\<`N +M"X_?I,$Z<%IR&G,*)``ABB7_+P`<0`5!*4X!4R$3`8MQ^@@O_P3:`-]+"E$@ +MZ7(#\`'B.PH5`4XBP```VP*X@W!@H&AT[0P5DO`AC2`R;#E]P[W/<8``&!*M +M84XDP1$"N3A]I7M@H`'D[O%.)LX03B/3)Q)N<"`!!P`MPB1$>2"@Z7$Z=WIW +M`_!(=LER&?"R;G`E`!<4Z*X+[]\!WP#9#R$!`$EI17E`A4PB0*!%>2"E-6X9 +M87_8)#A419^\E"Q$@`!A`($AT"/`2;'`@`P0+8%"!0`!,.'A')"?`0(X,`!?!')L`7R7,( +M=BGK+RC!`$X@@@<`V>D)%8&4:C5\$FDP)`P#<"`/!^5\@*`!X?7Q+RB!`TX@ +M@P<`VJD*%8$4:U5X,FH<98.$<"$/![A@%X#E?`9\@*$!XO'Q[.X9#1$``-H( +M\!)J<"`!!P'B,GD@H/4*%(&$PT`D!#4J<&IQ`-[&#>__R7(7Z`7!?]J,(?^/ +MRB)"``3#"2("!0(BP0`!X1D)(P1%P@PD@*#*("$`0")3`,4(4(`/\""%#+MY +M80@:0"`!:B"%#+@980P:0"``&H`C_0"OWZ;`SW"``+37(8``V@/P`>(9"A4! +MRLD!X<&YE2!,`'1I8&#M"!2!X'\H!$(4P")_?((8*<."XT2!A@,H@@0\``!@Q +MC`GAW\HA`01J(!.7,PC>`Q)M%'B#<.&@_]D@J".7#0UR$"2P]!A"@P'EKWV0Y(3(.#^D#\`\E`!!:<,]P@`!LM@"`X(`#\."'<.]` +M)P(8*HH$AFD(1``HB@#8-0E1`"2*C"'#CQ7T3(\I"HX@RG2&)/Z;!/(3EQ<( +MW@/*=(8D_9<%\A.7"PC?`P#8`O`!V$"&(X`YIU`-DZ +M<5#HBW'I<"IR]@L@`(IS0"%!(/?Q`-T0\!L-0147")XB%&W/<8``@#HX8".& +ML@VOYFIR`>4E#541`-@/($`#!"#`A=$@8J(%].CHT0@>HL]Q@`#0.A1MZO$I +M!F_?@"0#,/'`V@U/WZ3!.G`H=D`A%0%*(@`@SW"``%@2`!`3`$IP`_!`($`@ +M_]]2=QIP>/)`*H$@-'DP)4`@Y0@0`&D+$"#980#<2G+I=>ES!)$9")\"`8$D +M$(``$0C2`(GL:'5(``@A`/88``80@$3#<`3 +M$FT4>'(@C0.@J4"H!/``&8($6G)(=8AQ0(DR:C1YV6&K"L&#BB3#+PHF@"1` +M+HT@M'W=90&%(X`-"4$$,Y`$VP<)W@,`VXMQU@H@``IRC^@`V`&E((T3#P`5 +M0"R`(!1XV&`@J!?P6G$5\`#!!)45"5$`'PB?`HJX!+5`(T`@"/`/")X"JK@$ +MM4(C0"!Z<`HD@"4`%980F0^!E87Q#05OWZ3`X'CQP,X,;]\4V:7!"'8Z"6_D +MBW`.AJ"`8@LOZ0*&&G`*\"RY#0Q!$">3J+DGLZ"@H(6##1`0!I5_")``4@VO +MZ`*%9(CO",Z@#Y#G"-Z#!I6&(/^%[_,AA<]R@`!T.@`A@`\````0P8)`(@P# +MPGB`X"RXRB`L`'_>"2"/`T$O0!'5:,)_U&L5?L!D"PC/`P>5B+@'M1)K<"`# +M!TKK08*!@T)\@.0LO,HD+!!">7D)4X``V;GQA01OWZ7`\<#R"T_?Y!P(L!IQ +M2'=H=@HC`"&H=6H++^E*(0`P.G`?W`8D%1`%)=<40"08,PMP7@AOY!#92B1` +M(``>`!7/=8``=#H!A>)X#PAR`%4EQ!4"V`"FL_`BA0#8,'?*(&\`@.#*(D(@ +M((7*(L$C`B!`H`#:RB)O`"RX@.+*)0(`RB4A``HF@"\``/\/`"*`)2)X@.`L +MN,H@3`:,)<&/?]D4`28`"2!9`$$M00$S"Q`@`-\X\"\H005.((,'*'(+\)1K +M$FI5?#`D#`.#<..``>+E?(.@[PH4@1`EU2#;#1&@`-\+\"\H001.((('%&HP +M)```$"&1(`5_[PD1H!3P`,-2:02[`"2`,'IB8X"Z8@D/$"!7@@/P0X)E>D.@ +M4GI#H`'AW0D4@8'#0"0$,@MPJ'%*(0`@I@^O_RIR@P@0``+!?]B,(?^/RB!" +M``D@0@8!PP`>0!0@A4`K``,X8`*F`B+!``RY&6'"<2.F8H5B>0<)4@!CIB&% +M`B$#`(#CRB$,`,GV(J:`XM$G(9`#]`38`*8"($`@@.#*($P@P_8('@`4`B"` +M)#^X4B``@`GR`H4+"($$`]@`I@/P`!X`%7T";]^GP/'`,@I/WPAU*'<,B!IS +MR!P(L$`E%1@$%8`@^G*,(,./RB"!#P``_@`$\@P5@2`B>`(@P`7"A4'`"(4H +MO@)P0"B4`@.5SWX-"!X!`<`!X$'``=A"P`"G`]A#P`&G!!6#(`'`%0L%`"*% +MSW````4Q_@NOWP'"SW"``%`KU7@@@$3`!X4*((`_@`!T.@JX!2C^!4PG`*`` +M(5%P`"$3)<(F@B7*(,(DRB9"%,HB0B1O]`.5:0@>`0&'H+@!IP00#C`")L`4 +M/[A2(`"``B.4(Q'T!16!((7I`Y4;"%\"&ND#E3$(7P$-#Q$@#16`(`)YD.GF +M".__J7`GA0JY!2G^!2=P`J%"KD%*?X%)W`"IRB%"KDX8`.GLP(@``HA`#4($`(P`B*!(#^Y +M4B$!@`KR`\`#V0"G`-@!I[D"(``*(0`UPG@A"%(`!16!(`\/$2`%Z0T5@"`" +M>8#AD@(A`,HA`34`V#.5C[A%P"1X0B`$@`#8CKA&P"1XRB1B`$(@`(!*<"^__)!0%,`K"#,,2 +MZ@W!0B19(`(AP``S"$,&EB$(``(F0!`_N%(@`(`1\EGJ#_`")L`0/[A2(`"` +M#<#I\V)XSPA"AF*G#<`#IPK`&0C1`!4,A2\'``#P`\``IP@0`#!`(%$`0(D(B!(`& +MPLHD8@!$>$(@!8``P,HE8@`*L"P`@?0!0`IPB%*G(*N")P`Z@N(*X`:<# +MAP(@``0;"%(`"!``,`#;#"``H,HC;P"`X\H@`00#IP.'`B"9`-,)$0`")H`4 +M/[A2(`"`%?(G#E$@`B:`$#^X4B``@`7R!,!`H`GP`8@3E1\(WP/#ITB!`B:`$`\(4@`)@``+370"<-%0L(P0`#A@2G(89$A@T)P``"AQD(E0`BID2G0"<` +M%:8)+^00V0'8!J8S\,K)!+F5($P`&6%DAP.!8GJ`(@@`988JND)X#PM1`(#@ +MRB`K`(7VBB._`P@@P``#H0#8!:8A@1,)A0\```!0`8;P)0`06&`:<$`G`!5. +M"2_D$-D!AA5]`!T`%`&&`J8$A@2G*04/W^!X\<#AQ2,0@@#/=8``S-I5?4J% +M(GH/"E(`*J4Z#>_H!(@.I1D%#]_@>/'`;@P/W\@<"+`H=DAU)@_O_UIS2G#) +M<1H/(`"I$+``-A!P,]P@`!0*T3`U7A%P`"`0\`$%!$P-/`&P&$(T0`# +ME3$(7@$M"1$@!\`E")X`SW"``'0Z`8"*PDS`3<`(V$O``=A*P$IPJ7&"#R__ +M`-L(P">&`GDE"5(`SW&``'0Z(H$P<`H`#P`LCA$)40!AN`>F"8:"N`FF`-@, +MKD`A42`"P%L($(#/=H``S-H"A@?H)88#P#!P%``/`(;!J7`J%0L`#P`JY.&!#P`;`@."!]#.5V0G? +M`X"&C"3#GPCT"<,`'D`69:8(P`2F+?`)PR2&`B'"`#^Z4B("@`C"$?(+#$$6 +M1*9E\``>0!8EID2F9J8!V`*F2G!^#R```=I9\!06!!`"(@\!*0]2$`*&#PQ` +M%HOH1:8!V`*F!_"'Z&6FDPD1(&:F1?!`)0`2*/`W#$$6`B,,`1<,4A""AA$, +M41`#V$;``-M"PP/P9::SZ$)Y"0E2`$2F)H8)PP(C0`!3"%(`X?%%I@'8`J9* +M<$AQ!@\@``':",)`)0`2\@WO_TAQ`]A&P`#80L`5\,]P@`!T.@C!`8`B>#^X +M4B``@`0>0!8)\BR-!!(`(`\@0``$&@`@!L*#XB7S!\!$(#Z#[?(CE2\)7@$K +M"1$@)PB>`,]P@`!T.@&`BL),P$W`"-A+P`'82L!*<*EQQ@TO_P#;'!06,`\. +M'B!/)I8@'!R`-0\.7B!/)M8@'!R`-0.5Y;C,(2&@"/0-#MX@3R:6(!P<@#4% +M$Y4@$0D1(`T-$"`-$X`@`B45($0F@"""X$HD0"`%P,(D`B4GA0"`"KD%*7X$ +M*(4G<`JY`"$0`(;'2G"I<>ER3@TO_P#;,PX?(`.5"0@>`2<)$"`%P">%Z7(` +M@`JY!2E^!*EQ)W!(P`'81\!&P$IP'@TO_P#;#-A'P`#81L!*)D`@"/`#V$;` +M2B1`($`F5B###!$@OPY%)0;`NP@1``G!SW"``'0Z0H"6(0@``B&``#^X4B`` +M@.CU#!68$`'81L`3E0HG@"\```"`!"#"!4(B!(`$((`/````0,HD8@!"(`6` +M"W#*)6(`"G(*#:__Z7,&P)SH"<("(@`$#0A2``P?`!0*@0@P`5" +M(`.`*KK*(V(`"W!.#"``"KH!AT4@``,!IP;`E.@)P`(@``0_N%(@`(`&\@?` +M2B1`((&X1\!*<*EQZ7)&#"__`-N>\9\,$2#/<(``=#H"@`(@``2/"%(`)!P` +M-`+81\`!V$;`Z7(X\`43@R"`X\PB8H`/\B.5Y;G,(2&@S"(A@`3T@KA'P$\( +M7@"#N$?`(_!'"E$`(Y4_"1X!.PD1((GK@;A'P,]P@`!T.@&`2<`3\"<)7@'/ +M<(``=#H!@(K"3,!-P`C82\`!V$K`2G"I<;(++_\`VX;"2G"I<:8++_\`VP'` +M!L(!X`'!@N+*(0$``(:,(,./0<&D\H'B"_0$$X`@@^#.`\O_!1.`((#@S"%! +MA)CT)X4X$@\@"KE`(4`@!2A^``*%"A.7("BX!,(/>/`B``!*)@`@`"!!#@B% +M"B"`/P```!`*N#A@`"`4!@(A%084%A`0`B!`)3^X4B``@%GR`_#@AR_O(8<, +M)4"@^`?/_RGPC@\OZ`*'(A"!`"L)Q`4FES,)W@`]B)?I/(@K"=(`!H`AAPJX +M`GD"($`@@.#*($D@#O`'A0JX`"45(``D%"`!V!#P`B!`)8#@RB!))>"'">\A +MAP(D0"`_N%(@`(#2]0#8L^C/<(``=#I!@`P@@*`2``\`SW```!8Q%@EOWPIQ +M2G`*<58+(``%VD`E`!)""N__`"4!)A0>`!0!V`*F%/`"AI'HSW"``'0Z(H"R +M<0#8RB!O`(#@RB!"!``'0Z(8?/=H``N/4B>`"F!84B>`&F`(4"IDIP!@LO_P#!!(4AAR)X`Z8% +MA2)X!*82""``2G"5!N_>KL#@>/'`<@[/W@AVSW>``,S:`(>,(,./`J8`W0?T +M`@]OZ`Z&KJ:OIG+PH@V/Z"&&`8`F>*X.;^@!I@^F`H>-Z,]P@`!LM@"``("' +MZ**G+X8'D8&X![$BAP#8!NDIA^.YRB!A``6F#H8@AR*@#X8BH`6'+X8!X`&A +M#X8"V2:P#X:@H"^&!Y&"N`>Q)8?)<#8*(``#VBJ'3H<$\":D2J0!Y24-%1$5 +M)T`3:H`"(TP`/[Q2)`R0%29,$_'U9J1.@$JD:''O\2^&R7""#6__`-J.AL]P +M@`!T.B&`082OA@(B0``_N%(@`(!AA0KR`B.``!$(4@#DX`GW`(0/#0$0SW`` +M``DQA@\/WZ((K__)<-4%S][QP&(-S]X(=BAWW@EO_QIRSW6``'0ZX:4`)X$? +M!P``\"*E`B<`%,NX`B<"$$"ESW.``,S:Y*/EH^:C`"&`#R`````'HRBC`-H' +M\!4CC``JI/_8#J0!XO<*%('/<(``;+8`@."`#_`"ARBX+R`'('(,;__I<,]Q +M@`!0*Q4A`00`H>"'\^\<[@#?SW&``+37`('AI@'@`*'#H3H-;^@`I@ZF`=DF +ML`Z&XJ`.AN"@(84.AB&@+H8'D8*X!['EI@T%S][QP)8,S]YZ<`HA@"^``'0Z +M`!$`(!IS`B$.`(#F++[*)BP0.F)AN@(B#0"`Y2R]RB4L$`01`B`"(8``/[A2 +M(`"`RB"!#P``#C%@#@'?PGWA;4$N4A%`*D`A`B8-$-AG8;C_X,H@C0\```TQ +MRB&-`\HCC0\``'\`0`XMW\HBS0-`*P`A%2"!!&4($"!`(0`C`"!0`"GPN&=A +MN$D@S@0`0`"`E>`08$"`")D`3`>`"?P#=VN\-!,_>52'`)='QX'CQ +MP)X+S]YZ<`Z`6G+X'`BP0!,`()IQ0<#/<(``=#H!@$HA`"`-"0$`"0H>(`0; +M0"0`V`?P`89`(%$`0"5`(*$(M0"Z<$H@`"`/(%`E"R"`I/7S0"V`(#`D#C"( +M[@#=!_``A:EV"'4#\*"&@.;,)2*0'?(!A0(@``4_N%(@`(#R\P#8`*8?"I\@ +MJ7<,\`:7$PB>`-X++^@"AV(.K_\AA^"']N^^"V_HJ7#:\9,('J`&EH8@_X7` +M]<]P@`"TUP.``-D.@`&`QW`'``#PDG#*(6\`@.'*(0(ERB$!(+'Q(PI>($`3 +M`"`-Z"&``B$!!3^Y4B$!@`?R:@M/Z`#90!M`("IP\0+OWJ+`X'CQP*X*[]Y* +M)$``X(&`@*&`\73!@<(D#@'1=0';P'O1=0'=PB5.$P\,P1.`X\HC8@`)](;M +M@./,)"*`!/("VP/P`-L5ZQ\+4``W"Y$`@("@@0&``B1,DR&!@*(#($```:(/ +M\`#8`*(!H@OP@(&@@"&!`B1,DP&`@*(#(0$`(:*=`N_>:'#QP"H*S]X(=0"` +M'>CAA<:%!@TOWZEP#0^!$Q(([_X&A02%!B8!<``"``#JR2MX"?+/<,7N@L$! +MV38-(`%#A0'8`O``V%$"S]X@@#!PRB$A`.!_*'#QP-8)S]X(=:8/[_\H=PAV +MXJ6F"2_FJ7`I`N_>R7#@>,]PH```'!P8@`]`````X'AL<`$(G@7@?D"``_!` +M@@\(@`!D@BM[_/,"\`#:X'](<,]S@``8VD>#".I"@D"@!X,#@`"A`=@#\`#8 +MX'[QP&H)[]Y\V?#)&+DE>/`:&+#/=:```"`''5B0`-[)=POPZ7">#._^`-GI +M<#8,[_X`V0'G[W_O#Q*1(@OO_@78VZ4`'8`?``P/``@=@!\```#P`!V`'_X` +M``"*(`@``J4!V,P=`!#"#H_^;0'/WN!X\<#^",_>SW:@```%J8+(``!V`8)```/#1X7E@L@``+8 +M^@@``!$-7A>*"R```]CJ"```'!Z`'P!\```1`<_>%=C/<:```"!A&1@`"!F` +M#P,`X``)V!ZA'Z&(V-`9```$&8`/``0```#8&Z$`&8`/``P`&>!^X'CQP%X( +MS][/=J```"``'H`?``P/``@>@!\```#PD@[O_PAW&X;X8!NF;!80$`#='/`R +M;35YQW&``&37`-@/($`#!:9"@0.!`-Q@@@"``"/#@V"B(X$!(``#`*'@O5`. +MPO\!Y:]]S0T2D0#=$/`R;35YQW&``&37Z7!.#V_G`=K@O2P.PO\!Y:]]Y0T2 +MD<]P@``8VM(-C_XF"P``+0#OW@IP\<"^#X_>"'4H\`@7!!#/<,7NA<(,%P40 +M`-E[ANH*(`$*/'` +MG@W/_\]PH```(`08@`\`!`\`#!B`#P```/#1P.!^\<`J#X_>J,$(=RAU<@WO +M_QIRSW"@```@VX"+<8'"7@GO_NEP0(4")A$41,(AA80O"1\`(8U_@``@/1"% +M`B$#(``BPH``V`$@0`!%P$3"A,"+<38,[_^"PE4=`A`"P`3!$:4%P"2E!:72 +MI>EP"G$2""```=H9!Z_>J,#@>/'`E@Z/W@AV.G%>"._^&G*8(+DRB7!$,HE`A`8AP4HO@"3 +M"T4.R7`J<0'?R@YOX^ER#!,!((#E`KDU><=Q@`!DU\HBR@/*($H#1/8O($D# +M`-I*#6_G`-^R">_RR7"`X,H@P0,,".+QRB""`P\@@P/)<@_P+RC!`$X@@@=/ +M>@0J/@4`)4`N)X`0(X,`N6$GH//K!"H^!30B0"XP)D$N$PA#`-8,3^B`X!P( +MX>?*("$#`=HF\!2)`>`4J24($2`4B0T(DP(6B1D(40#)<"IQ!-HF#F_C&G(" +MV!FG"G(2\`+:$/#)<"IQ!-\.#F_CZ7+I<@#=!O``W;2I4!]`%`C:R7#B"F_? +MJ7%=!:_>ZG#@>(0H"0_/<8``+#LP(4`.`K@6>,=P@``\VN!^X'BBP?'``@V/ +MWCIQ&G((=ZH-K_1H=48+[_]`*(X"4R5`%1!VRB"%#P``-1'*(44#Y`[EWLHB +MA0/I<"X([_XJ<>EPQ@^O_@IQZ7"6#J_^R7'IEPF@[O]`'9#-P+ +M!8_>\<""#^__`-BB"H_^=@_O_P'8F@J/_FX/[_\"V(X*C_YB#^__`]B&"H_^ +MT<#@?N!XX'[@>,]P@`"$M@"`$PA1`,]QH```-`"!4B#`!`"AX'[@?N!X\Z"SN+6XN+CL&ABP%;D$H<]P +M@`!L,0"`!""`#P\``.`O*`$`3B!!!#(:6#`!W0\)D`'/<(``]+<.D"WH!MYZ +M#*_RR7#@N-$@88`E]$(,K_+)<#(2`38(&5X`J'@?Z'`\<`$\%H* +M#_//<*```$4>@`0@OH]P````]O71P.!^X'CQP/(*C]X(=L]P@`!(NM8/[_^F +MB`HB@"^@`(!$0!(`(,]WH```148@`0U`&D`@!(<$((`/_V__PP2G#(<$((`/ +M_W__PPRG`!^`'P!```#@>`#8&G``IQ-MI7@-IU(-[^2I<,]Q@`!X"P>!CN@# +M@88@PP\#H0D-'A"`N`.A"0U>$(2X`Z$*(8`O@`"PWP`1@"`-#0`04@Q/Z0`9 +M0B-`$@$@!2&!#P"`-`!`&D`@,NX7#E`02PZ0$(H@6@I"#._>R7$H\,]QH``` +M$`F!!N@D&0`$V@C/^!"]C[V;O<]P@``4"0"`G[W$N`JX!7VLI_8.S_^*(/\/ +M'*<8IPSP$+V/O<]P@``4"0"`G[W$N`JX!7VLIT$"C][QP(&`*'(`@`#;5@NO +MWHEQ2'#1P.!^X'@`V,]RH```2,]QH`"`1!BA&:$:H8_89!H8@$$:F(\`0``` +M01J8CP`0``#/<(``[`<0>!:AX'[@>/'`F@F/WO8/8`$(=\]VH```(#N&SW"` +M`(`S#@_OY2"@"'4!V8#EP'G/<(``6#(@H$#8`:;(%@$0,'E&"V_UZ7#>",_S +MP0&OWJEPX'CQP$8)K]X`V(H@$"#/=8``6/TFA<]VH`"((#IP$*4AZ<]RH``` +M()N"SW"``(`S8(`+#,00&X)B>`?P6X(.(X`/_____UA@SW*``"!'7X(%*CX` +M02D`=`)Y2"$!`#"E`-];\`L,41!`DDBS`!E"!`#\]R@`!,W79Z9(J'A9MC +M>&#/X_I`">!'X``5+B`B8+D=?6(DT&2FWR`O(1Z0!3=!V_>"G#QP'H/3]X(=BAW`-V#X,H@A@\` +M``Y$8`GFWLHAA@//<8``6/U`(0(#%2&#`PD.D1#CHPOPSW"``"!''X`%*/X# +M02D`=`.C`-@'\/`B`P`!X'!URB7.$/<(U("-!V_>IJ'QP!8/;]X#VC(2`3;/ +M=8``]+=6)<\3\"=!$"2PSW&@```$5:&R"R`#`-XRR,L2`K84)0$0P+$!@ET( +MGP/(L:@9A`,0BL]S@`#LR0.X%7A`(Q`$0".!`QMC!Y,]"%(`8;@'LU"*$VH5 +M>!!AEN@`V`\@@``*#J``']G+R1"(,V@U>30@02#AN=0/@MZES48@P`"E&ARP +MR\FV#*_TQ!```#+(`""!#X``%+@4?<"IR*D/>L]Q@`!,W59Y()&8'8034!U$ +M$,L2`;85?P&!!""`#P```&#`IQL(@0\````@Q!$``,]Q@`!0,!5Y`($0X`"A +MD09/WN!X\<`2#D_>,2\H00!.((T'E1<4 +ME@07$Y8R$A`VSW:@```$/!Y`%$H*;_R`V,]PH```?EIP8!B`#P"`@`#*#J`` +M*G`$\`/8"J8.A@?H?.AV"H_X#H;\\6`2`2#U"=^'J@Z@``IPJ7"`(,(!E.7* +M($4#`K@P(($/H``8+!)MQW"@`+0N(*`OR`2]NV!`@R&#N&!%>4*#)7HC@`4A +M@8#*(((/``#"(6@/@MZ`V<]PH```'"2@E1\8E00?V)2=!4_>X'CQP$X-;]X( +M<@AV&G$`WQ'P+RF!`$XA@`#)H,"&!#Z``-"\0(@(`PKD/)T\0\NH:\"\H +MP0-.((T'#@Z@`*EPR,HQ$@(V`K@P(($/H`!D+A`G3Q-$>0IP]@CO\,1Y>@JO +M^*EPY^_B#:``!]A)!4_>\<#:#&_>`]BPP1IPSW6@```$"*40%1$0#H7`X+[W +M`!8`0``6`$!`P"#`G.#*(&(-I`ZBWL\@(@.!P%H.H``.V004`#$*%($P"Q2" +M,$#@"+I%>>2YP""B``/@!""/#P``_/]9)PX2!/"Z"\_R#H7]"(2#(G?DI50= +M`!0.A1D(%`(4A4_`+\&SR`B`P+`!""`#P```$"A!&_>L,#Q +MP"(,3]Y:<`HD@"^@```P"B.`+Z```"Y4$Q4@!!06ID@3$"#/<(``6!4`@$HA +M`"`(Z`#8SW&@_BP.>@BO\Y:XZ@\O_$IU!?"R#J_EZ7`I[2\H00-.((\'[WDQ +MR`*Y,"&.#Z``9"X0)X'CQ +MP'(+;]X`V<]P@``\VR"@Z"SN+6XN+CL&ABP%;H$H@/:SW:@```$5:8!VVFFRQ("M@H@@"^@ +M```(H!K``,P:0`"DS>"XX@(!`,]PH`"`13`8@`\`(``!SW"``&PH8*!J(8`! +MSW"``'`H(*":"*_Q2'#+$@*V,(I3(<``1+G"N<`:0@`S:#5Y$*K'<8``[,E@ +M@3<+7P*F#&_Q`-G+$@&VA"@)#\09````(8%_@``@.]D:6+!$*#X+3H$`(8%_ +M@``<3D"A&_!6(@,$"(.0N`BC_]@1HR01@`#/)(;+R<]U@`!$W;081`#$$```Q@XO]*EQSW>@```@ +M.X`&H.+^H`V$.XRQ(,M@]YM!0`$1[@$Z92AH8B +MPP]%>1.F,J8.\%8D`10:D1.F$H9$(#Z#!O2&(/P#P.`$\FIUDO``E$H@`"!" +M(!4&&I$*=1C@$Z8*)``D!O#B>2)]N&`3IMT-194RA@3E0,%*(0`A+WA!*0\" +M[W\"Y^]_/PC1`+04`!$8X+A@9+@3IL]P1`#@PA"(G@IO\0#9+@DOZ$H@0"!. +M#\_G_@OO]0]X`AP",`#`$J8J<2'P'0F!#P!0W00B1JN@0C,]R@`#LR3-H-7DA8DT) +M7P(:#`_XRQ(,MC(2`396)`,4A.@&@S5_`*=1@\]P@`!0,/`@@@#/<(``=+A< +MLS1X-)`$(H(/``#P_\.Y)7I4L`;PJ!$``;@!J`<@!\!`)``QO!`*,$@"B&`+X`` +M[,E`(8`G-7DI8,`4@!`/"$``H!R`'P$`D0"R\,]P@`"$M@"`()0-")$`#H80 +M<0#8`_%!P`=O`>P;K(!F`#Q`!``"8\"`9@`\!`(@`DO`) +M@;2X":$)D:>X";$/D:>X#[&(\"`9@`\!`(4`A/`FD#,4@!!;"0X`SW&``)0H +M`8'8$@*V"N@LNL2Z`-@/((``(X$D>`CPP-@8N`1Z$'(!V,!X#>A6)`$4"8&T +MN`FA"9&GN`FQ#Y&GN`^Q"?`!A`\(G@&@'(`?`0"-`%3PA"\6&0`A@'^``-1J +M/H`)"9$``]D^H!Z`A^B@'(`?`$$``$+PTLD?"!X``@J/\\L2#+8,(@"@RB,& +M`,HCA02H',`0!?#/<*```"!Z@%8D`A08DD$+!0`@&H`/``4``,]PH```'308 +M@`]`````.!B`#T````#/<(``6!4`@`SH`-B6N,]QH/XX#!(*;_-8DLL2#+;/ +M<(``@#*`<`!#K>`7R#@[/X?,`0`#N"B_DB7#2R0T('P#+ +M$@&V9?#/>@`(,`VX)XC"`$BPJ"RB,&`Q!SRB,&`,C*SW2` +M`$S=%GP#E!!SRB#%`(P@!XUKHD+W`-B(Z(F"L;R)H@7P:H)KHOGQ"',$&8`/ +M``,``,`1`@"!:I%SRB3-$$)\FJ$`&8`/``$``,L2`;8,Z*01`@"ES?&ZQ2"B +M!,\@80"E&ARP`8$/")X#I,=P@`#LR8>0 +M)0Q2$$B0'0I>`!4,41!@$0(!A+I@&80`")`)")X`C;M\L88C_@S(X\]R@0"\ +M-@3T`-@%L@;P"AJ$#P````BD$0```]\,O^MX#?2&(/6/"?*N"B_\*'`#V<]P +MH```%"F@#@H``07H<@D/_-#P,LC/<8``)-L`HP>XAB#A#V5X17@`H3(*H``$V,O)$(@#N!9X,"`!(`0A@00#V`*EA2$"#0`8 +M1%#+R5V0`!B$4,O)3X`5"AX`V``LA0#$4H*K_,!V,()C_/+R900``#IN!0*`?5Z +M#L_C#P8``!H+K]\"V,L2`;8=L<]P@``LV](/K^3@H,O)F!`!`)080`#+$@&V +M@"$"``^179$)L4BQG@UO_2:!R\DR"*__>!```8#@Q@4"`/X*;^^+<,O)5B`# +M!%4@1`T)DR6#2),R#Z`"89/XN&@(`0$5"!X&`]@(IHH@$`"3!2``TAH8L,O) +MI!`!`(8A]8\)\M8(#_P#V<]PH```%"F@RQ(#ME8C`@3I@D$/'A7/=($`-$8( +M%`00"9(9#+0`)8)`A%8.+^%`)`,4C@@/YD,%``"GN`FRM+\)DNFB@",#!3H. +M+^%(D@/8`J7+R<]WH```(#&(SW*``!#MPKDR(E``SW*``'3M*6)P$`(!`")3 +M`*00`0`$(;Z/````R4HB0"`)\@(-#_S+R5(-+_P`V1CP,0F>`L]P@`!46"6` +MZ+G!*2$"RB"!#P``,"6\"F'>TR$A`)(-+_S+R:X.+_S+R1`=P!0Y'QB4R\FD +M$```Y+CX#@'ARQ(!M@&!$PA?!J8)K]\$V,L2`;8=L1:%!^@SV'(*;]Z,N,L2 +M`;96(0($!H(-")X&'9)DN)^X"J40B0.X%G@P(0`@H>@`!&"![@4>,=P@`"`@*`@.`@#>'X +MRB!A`,O)/)``&$10R\D]D``81%#+R2^``!A`4,O)0!`!`0`81%#+R3&``!A` +M4,O)2!`!`0`81%#+$@&V')&&(/\,/P@0`3.!BB(,```80%#+R5`0`0$`&$10 +MR\E4$`$!`!A$4,L2`;8+* +M("$"!/!>#F``"-@[A\`7`!`">"V_E`]W+$@*V&G`O@JEP!@IO\5""!""^KP8`R@`G\L]P@`!T +M*`.`@.#*(.(*SR`B`\HA`@0@"&+>RB("!,]Q@`"LSQ.!`>`3H<]P@`!8%0"` +M">@`V,]QH/[0#&H*+_.6N/8/#_/S`0``SW"@```$JJ#+$@&V`8$O"-X`I!$, +M`(HB"0_$$0$`SW"``/H\8FA,>0T,'A`T($\."?"Z#>_T-"-/#@/P=A$/`:7- +M4R!^@`CRTLG,$@&VO@FOX3(2`C;/=8``'-VI<)8*[^/+$@&VR\G2$A&VSW:` +M`-`OH!`0``'86G``IM8+;__I<`#9(*8)Z(8@?H^Q\LO)H!@`!-(:6+1""&_S +M`=C+$@&VSW.``/2W@A$``7X1`@%88(`1`@$:8C+(4'H5>QZ#6&`>HP&!DPC> +M`(()[_6`V`C:I1(!MZ0:G+"GN:NYK+G+$@RVI1I,]U +M@0`8-)AP!K4!A#T(G@&+N8RYI1I!X.X +MI1H&,4)V^D=)$@EA"[97DQI"&6`I@0N25X$J1`+P`$!2"``1.D0"0!#F:! +M%"7-``8511%X8^F=%'B@F1YB89D0O:5[=:1D@::!&+L4O:5[IX$:8A"]97UP +MD:5[=*0TD6"6$+EE>3:D(98"FA"Y)7@7I$`M``3E>!BD!!0``!FDSW"``.C0 +M7@E``#T#S]W/<8``\,D#N!5X(02O^P!A\<"V"N_=F'`H=PH@P*!*)0``#R4% +M``#=RB%"(\HF0A,(]`8BS0.2""``!B>.$#IP`-KI<0CP!B1,D8"@QB'!``'B +M3WHA"M,'`-L/(X,`ZWO/<(``4-95>("`[_,%)$P1@*#P\5(+K_>(!X`-L/(P,``-@(<0[PSW*``#04\")" +M`&MZ!/(/($``#W@!X2]YZ0E2@>!^X'@Q$@$V`K@P((`/H`!D+LX2`K8D>`1Z +M`-@.\"\K@0!.(X$'+WD0(D(`SW.``%#6\"-!`"5X\^KI`\_ZX'CQP*8)S]TH +M=@'<)@SO^@`L`!`(=6H+K_?)<,]R@`"4*"&"!.DC@@;PSW&@```N,H&D>.4! +M[]TD>-$!(`#_V.!XSW"``/!1((`H<(`@P@&4X/'`"@G/W2AWSW&``-0O0($A@45Y!B!-@!3RJ7#I<>H-+^4! +MVG(+[_JI<`AVN@JO]^EP"@POY<1XJ7#B">_QZ7$U`<_=`-H/(@(`SW&``/11 +M0*'/<8``\%'@?P"ASW"``/11H00OY0"`\<"B"._=`-H(=I8-+^4H=1X+[_K) +M<`AW9@JO]ZEP?@POY>1XR7!^"N_QJ7'A`,_=\ERC@WO_ZES"?#/<(``-!2U>""``>7& +M>2"@\PU4D9D`S]W@>``?0$"`@``?`$.!@``?`$."@``?`$.#@``?`$.$@``? +M`$.%@``?`$.&@``?`$.'@``?`$,@$`P"`!\`0R&``!]`0$AP`MF!!>_N:'+Q +MP,]PH```!"^`%0F5`TZ`.WE#<681``=">`CPSW```,X +M#WA`*($"\,DF>.T"+^;P&ABPI[@/>$`H@0+PR25XV0(OYO`:&+`;>$-P9A`! +M!\]PH```!`Z`X'\.($``X'CAQ>'&SW"``'A4`(#/<:````@`@"$9&("`(`@` +M`-L<\,]RH```!&^B#:)[?``B`3-F$0$'0W0LHFBY2"$-`#5KQW&@``1]H*$` +MV2FB9A0!%P'C.&#-"Y2#P<;@?\'%X'A/(`("SW&@`(!^2*'/<:````0/H>!_ +M,AH8,.!X\<#R#H_="'!X\<"*#H_="'4H=@3PN@T/\L]PH``` +M!`Z`]0B$@P#9!_``%H!``>$!'1(0^0F$@\T&C]W@>/'`4@Z/W0AW*'53('Z` +MRB""#P```3PX""+>RB'"`\<-$!!`)``6`$`$'Q`0`!8`0`0? +M$!``%@!`!!\0$``6`$`$'Q`0`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0`!8` +M0`0?$!``%@!`!!\0$``6`$`$'Q`0`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0 +M`!8`0`0?$!``%@!`!!\0$``6`$`$'Q`0@";_GQ#=J_7=!8_=X'CQP&X-C]T( +M=2AVX+C*(((/```"/%`/XMW*(4(#`_".#`_RSW"@```$#H#;>?,(1(``V0?P +M`!8`00'A`AT4$/D)A(.=!8_=X'CQP+8-S_]Z#H_Z`=G/<*````PQH"6@K@Z/ +M^M'`X'[@>*3@RB`K`(_VQ.#*(&L`B_;DX,H@JP"']HP@0H4#V,H@*@$`W`WP +MFF15>A1ZSW.``%B@-2."`!0A`P-`LP'DZPR4D.!^\<""#8_=0L'/%,]TH```(,]UH`"`'`0=@!_%[HV7FX2!I0&E(:4"BB&*"+@% +M>0.*$+@%>02*&+@%>2&E!8H!I0>*)HH(N`5Y"(H0N`5Y"8H8N`5Y(:4+BBJ* +M"+@%>0R*$+@%>0V*&+@%>2&E#XHNB@BX!7D0BA"X!7D1BABX!7DAI1**`:44 +MBC.*"+@%>16*$+@%>1:*&+@%>2&E.(H7B@BY)7@YBA"Y)7@ZBABY)7@!I3R* +M&XH(N25X/8H0N25X/HH8N25X`:5AI>!_P<7@>.'%ZA(!MD`@#`=5($,%?0G> +M!,]QH```(,]UH`"`'`0=@!_%[I'N.X$AI3V`(:4^@"&E((@AI4*0(Y`0ND5Y +M(:5$D"60$+I%>2&E)I!'D!"Y17DAI2"$(:4AA"&E(H0AI2"#(:4A@R&E(H,A +MI2.#(:4D@R&ESW&``(RK6X`@B0BZ17DAI1R``:7@?\'%ZA(!MBD)W@;/<:`` +M`"#/Z$Z#N!(:(@@"&B(8`AH@*``:+@?N!XZA(!MED)W@;/ +M<:```"#/Z0YSN!(:(@@"&B(8`AHB*`(:(C@"&B)(`AHB6` +M(:(F@"&B)X`AHBB`(:(I@"&B*H`AHBN`(:(L@"&B+8`AH@Z``:+@?N!X\<"" +M"H_="';/<(``C*N@B'IQA"T6&0`A@'^``-1K.!`1`#P0$@!\$!``M@AO]:EP +MZ0@0`.K)Y0C>!,]PH```(,]WH`"`'`0?@!_%[KCO&X`*)(`O@`!4@`&GP:?/ +M=H``5($FAL]P@`!4@A^8$+DE>`&GZ@TO]1B]$+BD%`$AI7@E>`&G_!0`(`&G +M`(8!IP.&`:<$A@&G)A%!(2H10"$0N25X`:`&G`-BX<`&G"'4#\`'EKWTU#9,0`-X)\*EPR7$JZ,[3N!(:(@@"&B(8`AHB*` +M(:(C@"&B)(`AHB6`(:(F@"&B)X`AHBB`(:(I@"&B"H`!HN!^X'CJ$@&V*PD> +M!,]QH```(,]SH`"`'`0;@`_%[H-E.X$AHT&0()`0ND5Y(:,"D`&CX'[QP`8) +MC]T(=>K)HL%!"!X$SW"@```@SW:@`(`!L]Q +MH```(,]RH`"`'`0:@`_%[K/9.X$AHB"`(:(!@`&BX'[@>.H2`;9+"=X%SW&@ +M```@SW*@`(`Z#Z7N#"+IAI$5X`:0AI.!^X'CJ$@&V!]HM"9X&SW&@```@SW.@`(`< +M!!N`#\7NA]\[@2&C!?`$$`$$(:.`XF&Z_/7@?N!XX<7J$@VV"WV(=!GR"+D% +M(8$/Q>Z``&5YSW"@```@SW.@`(`<(:,;@`&C"/`)#!X0`((!HP3BG7SZ[.!_ +MP<7@>/'`ZA(!MB$)G@?/Z8A3N"(1I8@)()(``8V='`X'[J +M$@&V'PF>!\]QH```(,]RH`"`'`0:@`_%[H*$.X$AH@&BX'[J$@*V(0J>!\]R +MH```(,]SH`"`'`0;@`_%[H.#6X)!HR&C`:/@?N!XZA(!MA\)G@?/<:```"#/ +MZ"B3N!(:(!HN!^ZA(!MB$)G@?/<:```"#/Z"B#N!(:(`@`&BX'[@>.H2`;9!"9X'SW&@```@SW.@`(`.H2 +M`;8E"9X'SW&@```@SW*@`(```-Q6-!<0$6$)W@3/<:```"#/=:``@!P$'8`?Q>Z#ZCN! +M(:4AAP6Y!7D#AP>X!2!1`&8)+_58%X`06!>!$`RX!2!`!!2Y)7@-[B&.0HX& +MN0ZZ)7H%%L$0%KDE>@4@D"`!I00=`!1%!D_=!_`$$`,$SW*@`(`<8:*`X6&Y +M^?7@?N!X![@4>,=P@`"0D)4@`!V2JHX']C +MH/'`X<6RP0G8,AH8,,]UH```!`^EBW!"#Z__`MD.A004`3']"$2``,`0>C\* +M40$,<(#=Y[C*(.$&8`^AW<`H80(B#D_P-@V/[L]PH```'*2@Z(!P.<:&+`6].G)*0@>`L]PH``` +M1Q08@`\```P,[,D%V0'@L[BUN+BX[!H8L!6Y!*&J#(_N`A0`,00@@`\```"` +M3[@K"%$`!A0`,2,('@``V$'`BW``V5(((``H<@G9,AI8,,]PH```!"^@&05O +MW;+`\<`AD`0A@0\```"`3[D7"5$`(Y`/"1X``-DAH!H((``H_\02Z!$'4$3]W@>/'`7@[/_\]PH```'!@8@`\@````T<#@?H0H"0^* +M)/P?`"&`?X``(#M)@.:Z!"(#`\HA@0`#\E`BP0'ENL0A`@/DNM`C8@'CNM`A +M(@%R&-@`X']S&%@`X'@(<@0@OH]@````,LC/<8``]+<`((,/@`!4N!1Y!?++ +MR1R0%PB>`@0B@@]A````$PJ!#P$`````V`"Q`=@<\*3-RQ("MAL(W@$!B3(2 +M@@`-"($``-@!J?/Q`>`!J0OP`(DQ$H(`"PB!``#8`*GG\0'@`*D"V.!_`*OA +MQ0#:_]P3:15X`""##X``!\J`JP[PSW"``!R_2V``(H`/@0#81#9X9*A@J`'B +M3WKG"A*!X'_!Q>!^X'CJR3T(7@#/<*```"#/<:``@!P$&8`/Q>Z$5AN``:'/ +M<(``G`L/@`&ASW"@```F$H`!H<]PH```$!F``:'@?N!XZLDY")X!SW"@```@ +MSW&@`(``<]PH```(,]SH`"`'`0;@`_%[H/@&X!%>0&C +MSW"``*@-`(`!HR&CX'[J$@*V(0H>!L]RH```(,]SH`"`'`0;@`_%[H,56X)! +MHP&C(:/@?N!XZA(#MB,+'@;/Z$$GN#8:0!I"&D +M0:3@?NH2`[8C"QX&SW.@```@SW2@`(`!L]RH```(,]SH`"`'`0;@`_%[H.S6X)!HP&C(:/@?N!XZA(#MB,+ +M'@;/Z$%GN#8:0!I"&D0:3@?NH2`;8?"1X&SW&@ +M```@SW*@`(`!L]QH```(,]RH`"`'`0: +M@`_%[H*T.X$AH@&BX'[J$@*V(0H>!L]RH```(,]SH`"`'`0;@`_%[H.U6X)! +MHP&C(:/@?N!XX<7J$@VVB'0M#1X6"+R%>0BY17D(N65YSW*@```@SW.@`(`< +M!!N`#\7N@Q!;@D&C`:,AH^!_P<7J$@*V(0H>!L]RH```(,]SH`"`'`0;@`_% +M[H,46X)!HP&C(:/@?N!XZA(#MBT+'@;/Z%%WN# +M8:0!I"&D0:3/<(``2!4`@`&DX'[@>.'%ZA(,MB<,'A;/=*```"#/=:``@!P$ +M'8`?Q>Z%$YN$@:4!I2&E0:5AI>!_P<7@>.H2`;8?"1X&SW&@```@SW*@`(`< +M!!J`#\7N@K8[@2&B`:+@?L]P@```5``0!``!V0@0!0#/<,7NAY+8$@*V2B8` +M`.82`[;M`J__"B>``>!X\<#AQ:'!67`Y<1ER:'3J$@&V"B=``8AUR'`A"1X' +M0,#/<,7NB,4!V4ER*7,*)``"N'2R"J__V'7A!R_=H<#@>/'`V'`H=)ARZLFX +M<_RXRB""#\7NA<;*(6(`RB*"`80*HO_*(P(#T<#@?N!X\<#AQ5EP.7$9Z#R20*HO_*(6(`T<#@?N!X\<`(="AS +MZLF8Z%:EN"0:4!I2&E8:6!I>!_P<4(`\]PH``` +M(,]QH`"`'`09@`_%[H53&X`!H<]P@`"<"V^`8:%!H=+)`:'/<*````P-@$(@ +M``A((````:%3"A$"-0O>`@09@`_%[@5;@=L(NPWP4FL5W!.\\"3`$`3B@F(" +MXQ"Z17@!H>T.Q?````F!#_`$&8`/Q>X#8\]RI@``!`""`:$"@@&A`X(!H>!^ +MX<7/<8``H$`L]Q@`!T5("!8=L(Y`AQ"_!S"1X"SW"!`+@N +M((!0VP&`2'0(NP4C@P_%[HP`SW6@`(`<8:5^@F&E?8)AI6Z"8:7/D&E081DE#"Z$+ME>D&E0X1HE#"Z$+ME>D&E +M5)1NE!"Z97I!I2&E`:7@?\'%X'CAQ>H2#+8I#%X1SW2@```@SW6@`(`!_P<7AQ>H2#+8G#)X1SW2@```@SW6@`(`< +M!!V`'\7NA6F;A(&E`:4AI4&E8:7@?\'%X'CAQ>'&ZA(,MBL,GA#/=:```"#/ +M=J``@!P$'H`?Q>Z%-)N%P!4-$*)\@:9AI@&F(:9!IL'&X'_!Q8;B"',`V@KR +MV,DLN,2X`K@P(((/H`"T+L]PH```(,]TH`"`'`0<@!_%[H4R&X`!I-C)`:0` +M@P&D(:1!I.!^X'CAQ>'&"'/JR9AQG0@>`,O)/)!$(0`#$0@1`N:Y0]C*(&$, +M`_`PV`BX!2"`#\7NCP#/=*```"#/=:``@!P!I=N$P!0`$`)^P:5AI=C)`:5` +M+``&17@!I!0:5`(`(.89+`DA"[Q7MAI6&" +M1)(PNQ"Z97I!I6`0`@%4$``!$+I%>`&E&H0!I=+)`:43@0&E%($!I<'&X'_! +MQ>!XSW"@`(`X=[@>8!W,(D +M`1//<````32`XY5XY`Q"W4D##]T`V@/P`>)!*($`_0I$@.!^"^F`N,]RH``` +M(#"B`=D'&EB`$-D@HO4#C^3@>/'`L@H/W0AVUW`/`/__RB"-#P``<`.,#$W= +M(-W/!XSW*@```@>X('\,]QH``` +M/`2!%0@?`!N"8GB,(`>-M_<`V`;P!('S"!Z``=C@?N!X?+@#\&ZX`0A3`.!^ +M\<`V"@_=*'4/"5\%!""^CP`&```>\CT-'Q7/=J```"!L%A`0%/`XAPX,;]V* +M()H*#O#/=Z```$6XAT()C_$;A@(@``3C"(./```0)^<-'I5-`@_=\<#AQ<]U +MH```"#:%!(40>#A@BB$2"A9Y`-@&#^__B[@:#^__"M@6#^__"M@`V<]PH``` +M122@`]@'I;(+3_(E`@_=X'CQP.'%#''/<*````C/=:```$A%"1X#-H`$@!!X +M.&"*(1(*%GFV#N__@-@,<"D('@//<(``/-L!V2"@,!4`EN*X9`YB_LH@0@#/ +M<8``K,\5@0'@%:$`V$0=&)`#V<]PH```"">@0@M/\K4!#]WQP.'%`-V8O0#8 +M"MG/!X +M\<#^#\_<2'=`B0AV`8D8NA"X!WH"B6.&"+A'>$.)!WH`A@<@B0`$B46)&+@0 +MND=X1HD(ND=X1XD'>@&&!R"%``B)28D8N!"Z1WA*B0BZ1WA+B0=Z`H8'((0` +M#(E-B1BX$+I'>$Z)"+HOB4=X)W@'>THD0"%D\#H([_4`V7IPRG`N"._U`=D' +M(Q,@*7`B"._U`MD'(Q,@"7`6"._U`]D@A@<@P`0'(0D`02H`%@(([_4`V1EP +MZ'#Z#Z_U`=D'(`<"B'#N#Z_U`MD')P<`J'#B#Z_U`]DAA@<@P`$'(04`02T` +M%LX/K_4`V0AUR'#"#Z_U`=D'?6EPN@^O]0+9!WT*<*X/K_4#V2*&IW@'(00` +M02L`!IX/K_4`V0ASJG"2#Z_U`=D'>TIPB@^O]0+9!WLJ<'X/K_4#V6=X8X8' +M>T$I`!9N#Z_U`-D(=4$K``0/>&(/K_4!V0=]02P``@]X4@^O]0+9!WTO($`!H/K_4"V0=]+R`'`0X/K_4#V26&IW@'(0H`02P`!OH.K_4`V0AU02T`!`]X +M[@ZO]0'9!WU!*0`2#WC>#J_U`MD'?6]XU@ZO]0/9IWBFAB\AQR0'?4$K``;" +M#J_U`-D(+(.K_4!V0=[02T``@]XI@ZO]0+9!WLO($<"F@ZO]0/9 +M9WAGAH`D_Z\'>R#F02L`!$$M`1(O((<202L')$$K`@(O)4<#02H&%$$K"R(O +M(,<@02T5%$$J$A(O)@<@+R%'$"\GQP$O)(<`+R:'`2\CQQ(O)4#J_U!-D*)(`O_P````0@``4' +M(-8%*7`&#J_U!-D*(8`?````_P0@0`(')A8@"7#N#:_U!-D/>""&!R"`!2=X +M02@!!B"O02@!!"&O02@!`B*O`Z]!*@`6Q@VO]039!"#(!.APN@VO]039!"`` +M!0<@"!"(<*H-K_4$V00@0`('(`@0J'":#:_U!-D/>"&&!R```B=X02@!!B2O +M02@!!"6O02@!`B:O!Z]!+0`6<@VO]039!"#-!,AP9@VO]039!"``!0=]:7!: +M#:_U!-D$($`"!WT*<$H-K_4$V0]X!WT"AJ=X02@!!BBO02@!!"FO02@!`@NO +M*J]!*P`&)@VO]039!"##!*IP&@VO]039!"``!0=[2G`*#:_U!-D$($`"!WLJ +M03OW`^O\&X,K_4!V0=^`(4HN`]XE@RO]039#WA6#*_U`MD'?@"-A@RO +M]039#WA&#*_U`]G'>`"E`84XN&X,K_4$V0]X+@RO]0#9"'8!A3"X#WA:#*_U +M!-D/>!H,K_4!V0=^`84HN`]X0@RO]039#W@"#*_U`MD'?@2-,@RO]039#WCR +M"Z_U`]G'>`&E`H4XN!H,K_4$V0]XV@NO]0#9"'8"A3"X#W@&#*_U!-D/>,8+ +MK_4!V0=^`H4HN`]X[@NO]039#WBN"Z_U`MD'?@B-W@NO]039#WB>"Z_U`]G' +M>`*E`X4XN,8+K_4$V0]XA@NO]0#9"'8#A3"X#WBR"Z_U!-D/>'(+K_4!V0=^ +M`X4HN`]XF@NO]039#WA:"Z_U`MD'?@R-B@NO]039#WA*"Z_U`]G'>`.E`>.* +MXZH&R_\9`\_<\<"B"L_<0(D(=0&)&+H0N`=Z`HD(N`=Z`XE'>`"E1(D%B1BZ +M$+@'>@:)"+@'>@>)1W@!I0B)28D8N!"Z!WH*B0BX!WH+B4=X`J4,B4V)&+@0 +MN@=Z#HD(N`=Z#XE'>`.E`-\\\,.%02X`%`]X_@JO]0398(4$((`/`/\```=[ +M02X`$@]XY@JO]039!""`#_\````'>\]XU@JO]039!""`#P```/\'>T$N`!;" +M"J_U!-D/>,]Q1`#HD/`AP0-G>"=X(84$I2=X(H4%I2=X(X4&I2=X!Z40Y0'G +MC0^2DC$"S]Q-<,]Q@`"<"P#:"PC>`521P[J!@<]P1``\X<]S@`!8WN"\U2#B +M#-4@X016>`"C>Y%"D"D*P@`I"X(`>I%!D!T*P@`="X(`.)$`D!$(0@`1"0(` +M37`)"-X"`=@#\`#8X'[QP$8)S]R")`,R&G"Z<4AU6G,*)``G2'"*<5X.+_P( +MVD`E`!)`+=$@2G%.#B_\*G*&P'IPZ@SO_PIQ!=@#\$(F0"`*)@"@8@`$`$(A +M#B)"=JIW[P]2D(+%BG"I<1H.+_P(V@0N?B4/%($P`"'``/>!T($P(`V@\B`@`K>OCS1GDVJR79@@D@``#:!?">"B`` +M`-C1P.!^X'CQP,]R@`",%"&*@XH::40A`P,BBL.X"+D[8R2*1KL(N3QD+R0( +M`P'90(I*)4`)2B8``%X((``*)X`!6@H@``'8T<#@?O'`X<6BP0?88<`!V`4< +M`C`#V08<0C#/<(``>-X`@,]U@``X.X0H"0^!P@;80,#0V`#;F'.X/'`R@^OW!EPIL$YAP2B!`(@/>8\8-'$(P +M@^D*<3'P%PE0`$$)D`#/<```L0V6"0_=]?$.'((P#QP",TB\9,1`*(`0@;A` +M*8$1!7DP>!$<0C!(N!(<`C`3',(S2+]EQ]_Q"[A`*`$3)7@0>0X<`C!(N0\< +M0C!DQ4B]$1Q",P;9SW!%`#0X>8C/<(``>-X`@(0H"0\`(8Q_@``@.X/"'PL> +M`('#T-A*)```2B4``$`D!A9*#"`!2B<```SP!MA`P-#8`-N8<[AS0"0&%J(- +M(`'X@,H)0`&`X#0(XN7*(*("_0:/W#D"C_3QP,]P10"4 +M-P"`SW&!`&`XK@A@`8HB&@Z6#\___]K/<(``_/DL&((`*+HM&((`T<#@?N!X +M\<#AQ<]P10`T.`"``-T(Z,]P@`!(%0"`"0A0`*EP!O`""H_S_.@!V)D&C]SQ +MP,]P@`!\W@"(Y@^O[P#9SW&``'C>W@W@``"AT@H``<]Q10`T.!>)$PA1`!:) +M!^C6#<__+@@@``#8SW"``*RW`("`X*0(PO8""8_TT<#@?@#:SW&``%S>%GG@ +M?T&AX'CQP,]Q@`!(%2"!"^D!VL]Q@`!"._E"=C1P.!^X'CQP.'% +M`-T-\,]P@`!`'EKWWM#=*0SW!%`#0X%HB`X!0/H>7* +M(&$"W06/W/'`3@V/W!IP.G%*(P`@`!C`!&IP,@E@`0`9P`0(=L]Q@`#DY[8/ +M(`&CD,]W@`"`5)'HSW&``-3GH@\@`25]<@\@`0#8SW:!`'@NC"48D@HB@"\``(;=![8$\@#?#/#/ +M<($`X#0`@/4('H#.#*_T"G`!WQT-@13/<($`X#0`@!$(7@"^#:_T*G"`X,HG +M81`Z"$`!.G#/<(``G`L`D$`A$"07"!X""G#)<;(*+_P#VD`A@"((\$`A`"') +M<9X*+_P#V@IP)FZ6"B_\`]JFMH?OSW&``)@4`!G`!(4$K]RI8#ARB"!#P``:P#P +M#>'`4$6@1!`%H`0 +M"+DE>$(6@1`0N25X0Q:!$!BY)7@$(+Z/`@!L``[RZ@Y/\P#8?@\@`0"EC@]` +M`$X-K^4*V!#PZWH.\E(-C_8(Z$(-C_:`X&@.HO;*(*(`Z@I/[ND#C]SQP'H+ +MK]R`V@AW!($H=B.X4R!!`4`F#18X94"H3B'"#QT*-0(!X#X(K^$`VP01!@`'(X\#`B:##S@7JDC[8YMC +M0"L,`S2[97Q<9`P@1"``'(T\#`""#'R`DVW#[8]MC0"M.!"^[Q7N; +M8PF)W:CFZ17N[8PB01$``'(@\# +M`B""+[MT40A?9_YF0"X"$S2^Q7IZ8@F)`*@X#-+I%?IYF!R4"$\1Z.!$$``]MC!R8/$V1_3X&'?P`B@0^T22$(^6&Y84`IC04J +MN:5Y>6$'(TT`Q'T')<\0`B:-#^$)GMK]9;QDM6P[O(5]/64'(4P#9'P')$\0 +M`B&,'[\_P$S\9)YF0"Y,$C>^Q7R\9`YMC!R3.$*1^!R8/$P(FCB])%E8X_F;984`I#@4LN<5Y>6$'(TX` +MA'X')L\0`B*.+]`IH^_^9MUEU6T[O<5]/64'(4X#9'X')D\0`"..'T0"4Q3^ +M9MQD0"Q.$C>\Q7R\9`YMC +M!R3.$*1^AWX"(X\O+!@X!-]G^6%`*0X%++DE?GYF!R./`X1_9W\`(($OX2'F +MS?EA/64U;3N]I7G980[MC!R7/$"1_IW\`(8PO6D7M +M%/QDGF9`+@P5++[%?'QD!R,/`Z1_9W\")XX/'%;[%OYFV6'5:3NYQ7F980[MC!R7.$"1^IWX")8\OU7)VL]]G_&1`+`X5++S%?'QD +M!R,/`Z=_`B*.+P4`OL;^9MEAU&D\N25^GF8')(\39W\"(8$OCGA_"?EA/65` +M+<$2-;VE>=EA!R&/`X=_`"*-'YUM(F']9;MC0"L-!#"[97T]902ZG/_F;984`IS@(UN<5YF6$'(0\#9W\")(XO1`F@M/YF +MW65`+0X4,+W%?3UE!R%/`X=_`B..'T!!D$/^9MMC0"O.!2F[Q7N[8P7EA!R'.`*=^`"*/#Z(?^'S?9_QD0"P. +M%#"\Q7P\9`[MCDGYE?@00R5[IWL")8\/\W!N,_MC?F9`+H,2-K[%>SMCLGYE?B=^`B./'Q``@PO?9_QD +M0"S.$S&\A7Y^9C)\Q7QG?`(FCP][>B^BGV?]94`M3!4KO:5\W&1R?85]QWT` +M(8\OJ&]/?K]G^6&V:3JY)7V=9=)YI7F'>0(B@@_3`2`966$[8T`KCP(VNV5_ +MOV>2>>5YIWD"(8(?_ESLO%EAV6%`*<(#,;DE>OIBLGE%>>=Y`">##PA.H1$[ +M8YMC0"M!!2N[97E98?)[)7M'>P(CC"^L"'Z!FV-]979M.KVE>SMC4GQE?"=\ +M`B*-'\5"RPV\9/QD0"R-$C:\I7Q\9#)^A7YG?@`@C1_7*KO2W66Z8D`JS0,Q +MNJ5ZFF)R?45]AWT"((XO>11O+-UEN6%`*4T%*[DE?5UEXG,A@&"@N6$AH"*` +M.F(C@$*@F6&%`V_<(Z#QP#8+3]R")`,\&G`H=WIR6G,*)0`A"B%`(<#A5B04 +M-(MUTO;2""``J7"I<`IQ\@@@`.ER5B0`(Z(/K_^I<58D$",0WY;`VG``WLEQ +M[@\OX4':0"0`)\EQX@\OX4':"G#*<08([_OI<@IP0"0!)_H/K_OI<&$(`P.:Q]UX((`"I<*EPRG%^""`` +M0-H`W@KP\"*!(S(E@B-J""``J7`!YO$.Q)0J^)JP@8@`^ZF/[<#!B`#S(0=E0`V22@X'\EH/'`+@I/W`AU2'=$@"AV%B+! +M`R2@"PFE``6``>`%I4$O01\KD(T0!.#>``!-@@B`'8@N'`>$\)4`""X?[$(2@0`0N25X0Q*!`!BY)7B,(`2`$/(0V`AQ0!I"`"BY01I"`"BY0AI" +M`"BY0QI"`(8,C__1P.!^\<"R"$_!XSW&``"SX0)$)"B,``;%!L:T"P`#QP%H(;]P# +MV;+!0"00,7IQ!^BG"%``A0B0`&IUB/`*(H`O@0`P,P42C2`*<-)MU'Y"=@@6 +MD1`!V6X*;_4J<@AW`O`H=P)O)]D@KP_9(:\`V2*H(:@FL"F.`>4@J"J.P;TC +MJ"9O0"8`$Q8-K_L(VA#8$*]`(T`D+R,((`82@"!`)T$4$PT`$-)MU'Y"=@B. +MMPA`A`4:0B/#\<]Q@0!P,Q:)M(F'N!:I`^5`(8`%"G'2#*_[J7(\\,]V@0!0 +M,PIPZ@EO]5B.(]I`J`+:0:@B:,]P@``L^$*0".!(8`"I&HYAN$4(]0,`W3,F +M`'"``&3C0">"&8ZB>`?=`:G#Y-X`@,]V@``X.X0H"0\&V$#`T-BI<0IR`-N8<[AS`"9&'JH-H`#X&,(02`NO<`VDAQ2'`4\``D +MCS#`CS(F#`#989EA+WD!X`PG`(``)$TP@(W*("X`@*_`K0'BC"($@*OW`-@( +M<0AT#O`!X`]X`"0.,*".`>2Y82]Y`"1/,$"/0*Z@K^<,1)$`W1GP`>`/>``D +M#C!`C@'E66$O>0`D3S"`CX"N0*\R)`PPFF)/>C(DC#!`BX=Z`1N2`-4-!)&U +M!B_<@"0$,.!X"'28<4AP:'$`VCT'[_^)<_'`'@XOW`#8SW&``$@5((&`X<3R +M1"(`4X3@[_+.#T__@.#L\L]P@`"`5`"`!^C/<$0`#/(`@(#@K_1$(@!3B.#/ +M=8``G`N8],`5@!"`X)3TQ@D``.H)(``(V,]V@`"`5`"&@.`5V#CRSW"``&BZ +M`(#/<8``Y+L^#R_Y(('/<:````P$H0"&"H!2"F_<+H4/A1,(7@8@A@.1!.`# +ML0619+@8\"$(W@8@A@.1".`#L061;+@%L0'9SW"``%`5(*`+\!,(G@8@A@.1 +M".`#L061:+@%L0#8"B``H$HA`"`*(H`O@`"8%``:0"0@AB_T*ND4E0':`!J` +M($D(W@&CD>61"/!R"&_U`B?/%&)UL'TU#W(00"4"$P"&*H`R8D]Y"+DHND5Y +M);!`)8(3#N%#L$-IU0]ED$8BTP`$&$0$!/`V"$_UN@\O]0IP`(8*Z`*0".@1 +M"!$@K@C``#X(P``$\(8/@```$@`@@.`5V,H@(0!-<:4)G@%/\`"5AB#\`(P@ +M`H`-],]P@``<&0:`A^C/<$4`-#@9B`L('P$`V#SPSW&``*"[`8'/=8``,-$` +MI0*!`:4#@0*E!($#I0J1"+4+D0FU#H$%I0^!SW&``.2[9+@&I<]P@`!HN@"` +MW@TO^2"!SW&@```,!*$FA8H@"08)(0$`[@AOW$`E`!<-\,]P@`"<"P"0AB#\ +M`-#@@-S,(`*#Q?,5V&D$#]SQP,]P10"4-P"`SW&!`&`X3@Z@`(HB&@X`V<]P +M@`"`5""@T<#@?N!X\<`O"!$"37$G"9\!SW&``)P+88'/P`D +M0#!@J`'AY0D4@L]W@`"XXZEPZ7$#\*EP(F^F"6```=H%A88@^`&,(`>`]_6+ +M=ZEPZ7&."6``"-H`V@_P02J``/`E`!!3(D,`3B/!``.Y.7A<9@"L`>+I"A2% +MJ7``V=8/[^`$VNEP`-G*#^_@"-I)`R_#2_U2B7````@#0)#+H@0J7#I +M<0ER*7,*)(`!@@TO]4HE``$`((X!0R^&$,EPJ7'(<@ES"B1``F8-+_5*)4`! +M`"!/`D,MB1#I<,EQ*7+(@PO]4HE``0`((X!0R^& +M$,EPJ7'(<@ES"B1``EX,+_5*)4`$`"!/`D,MB1#I<,EQ*7+("R_U2B7`!@`@#0)#+H@0J7#I<0ER +M*7,*)(`!@@LO]4HE``<`((X!0R^&$,EPJ7'(<@ES"B1``F8++_5*)4`'`"!/ +M`D,MB1#I<,EQ*7+(G&(=58D43@* +M(``GE\?I<`#>R7'*#:_@0=I6)!(T0"(`*,EQN@VOX$':BG#I<=H-+_MJ9'(8$-7!A"`*`0@0"'(0$'H!A" +M`,#FL/>+=K8-K__)<,EPZ7'V#N__0-H`WPKP\"'!(_`@PB/B#N__R7`!Y_$/ +M5)"I<.X,K__)<88-K__)<,EP0"(!*,(.[_]`VLEPJ7&Z#N__%-JI<,H,K__) +M<0S<>P#OVX`D`SG@>(0H"0_/<8$`*#0`(8!_@``@.T`@`@08X$&A!Z'@?PVA +MSW1$`#SA5!0!%L]P@0`H-"*@SW*``.#W0"(!!B.@`-MDH#2$=*@HH$`B@0@I +MH$`B`0LJH-`4`1`L&,(`+J!`(H$-+Z!6(@$",*#@?T08P@#QP+(/C]MH=66* +M&G`$B@B[9W@`M0>*1HH(N$=X`;5!B0")"+I'>`*U0XD"B0BZ1W@#M02))8D( +MN2=X!+4`WTWP4R<1$!0@3B1!CB"."+I'>2=X7@OO^1!X8)5`(8(@>&`4(($@ +M`+5`B2&)"+E'>2=X/@OO^1!X895`(0(A>&`4(($@`;5`B2&)"+E'>2=X(@OO +M^1!X8I5`(8(A>&`4(($@`K5`B2&)"+E'>2=X`@OO^1!X(Y4X8`.U08X@C@BZ +M1WDG>.X*[_D0>"25&6'Y80'G,'CO?R2U;0\2DCT'C]O@>*'!\<#6#J_;.7&E +MP20<0C$(=!ERN'.(=LAU`-A`P(''((3I<*X,[_1!A.EP*7':"^_T!MKI<`EQ +MS@OO]`;:B<'I<,8+[_0!VHMQZ7"Z"^_T`]KI<*AQL@OO],ER*@SO].EPZ7"I +M<6(,[_3H<@CD:$`@$`0@C<]P@`#@]^"Y +MP"`B!,`@(0(@ESIP1"$``Q4($0(H<(8@_`.,(`*``MA#]P#8&.#HN=$A8H(& +MV0+T`-DX8/A@0"`2`L]V@`"`5`"&[@E@``60`-E`EP(@@`3GNLHE00`$\BR7 +M4R'%`!!\"B8`!T`D!S$J<*EQ"G)*"B_["-H` +MV<]P@`!0%2"@`L$`P!$)`0`#P0'`$'$!V`/R`-CY!:_;I,#QP(X-C]NBP0AU +MSW&``,P+37#GN,]R@`"<"P#8`_(4DL.X8(F"B0B[X8$%)-`008+/<40`/.'/ +M$$%GD@H]-JSW"!`"@T0"`1!7IP`8'4?EIR +M$0\D$&)V$0\!$`"1"0@"!`#88O`"AB,/`1`4C@SH`X9`)0$5H*9>"R_[!=H` +MAN*H`-@4KD_P`>#9#P&0%(X="%``!(9`)0$5H*8Z"R_[!=H`AN*H`=@4K@P@ +M@*\```"``=_J]@H@@"^``*C?`!"!(*"F#R&!!``80B!*(@`@`!"`(`M_'/)` +M*LT@M'T`)/'`5@R/ +MVPAV.G$:/'`O@^/[L]Q10`T.'"X`K'1P.!^ +M\<#AQ202@`"!X`'8PB`!`"\)@`^MJ_[*`-T#\`'E&0T5%5)M5'K/(($K"$$``-T1\!)M%'@`(($/1``X +MPT*!!>H#V&!Z(8'."2``J7`!Y>4-%)6Q`X_;X'CQP`#:!?"V"2``2'`!XOL* +M%(71P.!^X'CQP!8+C]O/<8``>-X@@3<(00``WA7PLFZT?<=U1``XPP"%SW>M +MJ_[*%0C``X8*C^]"A07J`MA@>B&%X*4!YML.%)5!`X_;X'CQP+(*C]NIP4+` +M6G%(=6AV#!P`,1`<0#$*(X`ASW%%`#0X&!&5`$`C$0+/<8``?-X@B<]R@``' +MRG-I=7MJ8@#8C"+#CP0$"(SW"``""_1"H^#2"` +M="%`#L*X0"$4`8#@S"!B@%OR7PC1`$`D$#7)<(IQ\@WO_PIRSW"``'C>`(#/ +M=X``X/>$*`D/`"&"?X``(#L.@@`AEB3@N,(E0B5`)@!%`+`,'D,%`0PJ7(0%`4PBG,* +M)L`$*@@@``04!S"Q`:_;J<#@>`*X%'C'<$0`.,,`&(`/K:O^R@#9X'\BH/'` +M-@F/VSIPQH`<0#,`W0/P`>4A#145$FT4>,=P1``XPR"`\0F!CZVK_LH"@/+H!/"* +M)?\?1"$5(TPE`*(!V,!X1L``W@T-$2+/<$4`-#C8B`+`#^C/<(``?-X@B,]R +M@``'RA-I%7@(8HP@PX\%]$HB`"!*=Q#PSW"!`-A$-G@@B,]P@``@OT0I/@T` +M@#0@4@Y3(H\@7@FO[\@4@#"4X"`")@!*(4`PBB#_/Q-U$`(!``HC@"^``'C> +M`!,!(/+)#PA.`+(([_$H'@BO[@`7 +M@2``%X`@'L$0J83O$1F"!2#P@^?*(.$"%O*"Y\H@H0(2\B,/41!1(@"C$1E" +M!LH@008#\@G8$:E"*@(BP;H&ND5X$:D"P!3AP@SO^A#:'L$/V"@9``9`(0(( +M$1J"!1*J!,`T&80%TZHV&80%+N@&P"SH@!0`,(HA!@(@L``3`2#/<(``6#N$ +M*0D/,"!`#H#F1"`!!(`4`#`LL(`4`3`,D0.1$.`#L1_P!L`1Z(#FRB!B!,`HH@(<">+;RB&"`XHA!`*` +M%``P(+`%\(`4`#``&$0$&-A?P,]Q10`T.`*1$.`"L8`4`3`+L8`4`3`$[P"1 +MCK@`L8`4`##/=H``(#L"&(0%`!,`((HG"1_L>(`4`3!`)@`6!.$G<-(+[_H& +MV@`3`"`0YH`4`3#L>`KA`"9`'KH+[_H&VAD-$2$J<(8@_`.,(`*$!/00V%_` +M"?"`%`$P`\`0X98+[_H&VA["`)(?P3A@`+(`P,]Q!`!/'`%@Y/V[_!"'?&"2``*'8( +M=<]P@`#4YX+!$@OO^@;:#AR$/P``B(Z$P>EP_@KO^F3:@L*+.!^X'@`VV*@8*!CH&&@9J!EH">@X']$ +MH("(8(D`V@\,P1"!B&&)"PS`$$AP!O!BB`*)^PL!@`'8X'\/>("08)$`V@\, +MP1"!D&&1"PS`$$AP!O!BD`*1^PL!@`'8X'\/>,]Q@`"`5""!2H$CD5EAX'\0 +M8>!XSW!%`)0W`(!)`Z_T`-G@>/'`/@UOVYAR"'?/E>"X_T$/`!@0#:!.A`@0>!&F+PZ@#8&_`Z"Z_TP(`()@`00"<. +M&^$(I(,@@RAP<@NO],EQ#>C`H*6P0"`!"RJ@!A@$`0#9(K`B&$(`/05/V^!X +MSW!%`)0W$0.O]`"`\<#/<$4`E#?/X&`AWV!@J1\ +MA7NB@(*!AWV"@J1\A7N#@`.!!WP#@H1X!2#^@`'8P'C@?\'%X'C/<(``@%0` +M@.!_"H#/<(``@%0`@.!_"H#/<(``@%0@@,]R10"4-P"")0*O]""!X'@(&`)`>_ZF&#@>/'`SW-% +M`)0W,@JO]`"#A>A`@P&"@^@`V`3P`((G@CA@T<#@?N'%X<;/<(``@%0`@,]R +M10"4-X""()!'A*"$`B".`!T.8A,[9J)[H82B>QL+$@`#A!<+`P!88PKP0H1" +M>T.$"PN#`#A@`O``V,'&X'_!Q>!X\<`3"%$`7@\/_X(/+_\`V`OP!-@`V2AR +M)@[O_RASSW&``(!4`*$F#\__M@[/_]'`X'[@>/'`1@M/VPAV`_!^"L_OSW6@ +M```PDQ4`EO,('H'8$@^V,L@P'=B3$0B1`0;8.@XO[\EQ._#/<(``2!4`@+7H +M++_$OP3P0@K/[Y,5`);Y"!Z!$F\P((T/H`"T+NEP@"#"`93GRB<&$`*_,">` +M'Z``&"S/<:``@`R`(`0`HG@/>#\(-0(PVD`9@`\`H#``"0@4`0#;`_`!V]H2 +M`K;)<.82`;:""J_]I7HIALEP0@XO_C(2`C:"#,_P_0)/VU"A/@D/^H#@RB`B +M`2@*(OK`>>+QX'BAP?'`9@I/VZ+!*'5)P5IP2'8:`@+9SW"@`(`<.Z`IP5-N[N%0>`7T5@@OWHMQ'_`5"=$-&W@0>$8(+]Z+ +M<>EP%_`-"1$%''@`'`0P"_`+"9$"`!R$,`7P`!R$/P``__\`V`+P`>#_")2" +M`-@`%`(Q5=D1N<*A0*&"N`.A-/`$);Z?``0``13R70K?(4PA`*#*(($/``!3 +M`,`+H=O/("$#2G"I<^D`/TBPZ4D@\,WA/U +MO +M!"6^GP````P!X`ZAG+Y6\E,E?I!2]#+(`-D/(0$`SW"``#C;(*!*\!L(W@#/ +M<8``+,X/@0'@#Z%*"Z_P!-A"WCSP"'2&)/V7T2"A@37T[;BH#\+Z,?`5#5X5 +MSW&``*S/&X$!X!NA*?`?ZOJ]P'[/)F(4%O0;#5X6SW&``*S/%($!X!2A_@JO +M\`+80MX(\#Z#.=A<@P(*K]N,N`#>J7"^#2_^*G$*\%8/S_K/<8``K,\<@0'@ +M'*$`WNK)F+YM"!X`SW#%[H(U`=D."Z_]R7+/<,7N`D(`V:ER_@JO_2IS)O`% +M$P"&\+C*("$`SR"A`]P,(?[*(2$`SW&@``!%6($%@4MXRB8A$!+R'($!V,]U +MH```"`:EX'C@>`#9)J5Z#*_\!=X#V`>EF+ZK[A$*WR$#V<]PH```""*@SW.` +M``C=0(,2:@G$%'@`(($/@`"HW("ASW"``&0>'8@(&0`$A"@!#``A@'^``.0< +MA)@!XAR8@K$#L8?B!]C*((4``*,-\,]P@`!8%0"`">@`V,]QH/ZP#'8+;_"6 +MN,]Q@``LS@V!`>`-H$D$MP!#!N`'@02U!%,&Y&6$.\!D-GA8@P$2XP;@A +M:`0E@!\"````,;@8>2$)4``3"9``@^$`V,H@X0'`**$#"O#/<($`B#8"@`;P +MSW"!`(@V`8`%?[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=X5````3+D```"`1``#6Z"SW0#``%"G]%%394%^PZ07&I9>)SK+ +M:ZL[\46='ZM8^JR3`^-+5?HP(/9M=JV1=LR()4P"]?S7Y4_7RRK%@$0U)H^C +M8K5)6K'>9QNZ)9@.ZD7AP/Y=`G4OPQ+P3(&CET:-QOG3:^=?CP.5G)(5ZWIM +MO]I94I4M@[[4TR%T6"EIX$E$R,F.:HG"=7AYCO1K/EB9W7&Y)[9/X;X7K8CP +M9JP@R;0ZSGT82M]C@C$:Y6`S49=%?U-BX'=DL82N:[LE+?X>U(CTW.KX@)+/'^,JJU5F!RCKL@/"M2^:>\6&I0@WT_*' +M*#"RI;\CNFH#`ER"%NTK',^*DK1YI_#R!_.AXFE.S?3:9=6^!08?8C31BOZF +MQ)U3+C2@5?.B,N&*!77K]J0Y[(,+JN]@0`:?<5Y1$&Z]^8HA/CT&W9:N!3[= +M1KWF3;6-5)$%7<1Q;]0&!/\54&`D^Y@9E^F]ULQ#0(EWGMEGO4+HL(B+B04<*?*'I#T)\R1Z$^`````"#AH`)2.TK,JQP$1Y.U:X])SDM-F39#PHAIEQHT51;FSHN-B2Q9PH,#^=7D]*6[K2>D9L;3\7` +M@*(@W&%I2W=:%AH2'`JZD^+E*J#`0^`B/!T7&Q(+#0D.K<>+\KFHMBW(J1X4 +MA1GQ5TP'=:^[W9GN_6!_HY\F`?>\]7)2XRMPQUQ"%8T)`(I<3(!'&A'TD2H7X/;O2$3+YKFVA*<=++YX=\S"RW.Q2 +MA@W0X\%W;!:S*YFY<*GZ2)01(F3I1\2,_*@:/_"@V"Q]5N^0,R+'3DF'P=$X +MV?ZBRHPV"]28SX'UIBC>>J4FCK?:I+^M/^2=.BP-DGA0F\Q?:F)&?E3"$XWV +MZ+C8D%[W.2[UK\."OH!=GWR3T&FI+=5OLQ(ESSN9K,BG?1@0;F.";-]!A9;@&WFNRHFD^#96Z5YG[F_ZH(S[PAYN@5[]F;Y[K.-F]*U`F?ZM9\ +ML"FOLJ0Q,2,_*C"4I<;`9J(U-[Q.=*;*@ORPT)#@%=BG,TJ8!/'WVNQ!#E#- +M?R_VD1>-UDUV3;#O0U1-JLS?!);DX[71GAN(:DRX'RS!?U%E1@3J7IU=-8P! +MS4M+;DC-6$.D31]9MC&'7FGH,H3>.%/A9B3P3Z^XGJ4('S +MK\H^Q&BY+#0D.%]`H\)RPQT6#"7BO(M)/"A!E0W_<0&H.=ZS#`B-G820V*L`C+S3"O?D6`6XLT4&T"P>C\H_ +M#P+!K[T#`1.*:SJ1$4%/9]SJE_+/SO"TYG.6K'0BYZTUA>+Y-^@<==]N1_$: +M<1TIQ8EOMV(.JAB^&_Q6/DO&TGD@FMO`_GC-6O0?W:@SB`?',;$2$%DG@.Q? +M8%%_J1FU2@TMY7J?D\F<[Z#@.TVN*O6PR.N[/(-3F6$7*P1^NG?6)N%I%&-5 +M(0Q]I6-CQH1\?/B9=W?NC7M[]@WR\O^]:VO6L6]OWE3%Q9%0,#!@`P$!`JEG +M9\Y]*RM6&?[^YV+7U[7FJZM-FG9V[$7*RH^=@H(?0,G)B8=]??H5^OKOZUE9 +MLLE'1XX+\/#[[*VM06?4U+/]HJ)?ZJ^O1;^@X,=="PL +M6"X:&C0M&QLVLFYNW.Y:6K3[H*!;]E)2I$T[.W9AUM:WSK.S?7LI*5(^X^/= +M<2\O7I>$A!/U4U.F:-'1N0`````L[>W!8"`@0!_\_./(L;%Y[5M;MKYJ:M1& +MR\N-V;Z^9TLY.7+>2DJ4U$Q,F.A86+!*S\^%:]#0NRKO[\7EJJI/%OO[[<5# +M0X;734V:53,S9I2%A1'/146*$/GYZ08"`@2!?W_^\%!0H$0\/'BZGY\EXZBH +M2_-14:+^HZ-=P$!`@(J/CP6MDI(_O)V=(4@X.'`$]?7QW[R\8\&VMG=UVMJO +M8R$A0C`0$"`:___E#O/S_6W2TK],S?]S[NQ].XN&L\%!0H>=[> +MI^)>7KP="PL6=MO;K3O@X-M6,C)D3CHZ=!X*"A3;24F2"@8&#&PD)$CD7%RX +M7<+"GV[3T[WOK*Q#IF)BQ*B1D3FDE94Q-^3DTXMY>?(RY^?50\C(BUDW-VZW +M;6W:C(V-`635U;'23DZ/!O)25*NT+FY:9&&AA=8P<&9)QT=.KF>GB'9$_CXZ[.8F"LS$1$BNVEITG#9V:F)CHX'IY24,[:;FRTB'AX\DH>'%2#I +MZR["P>_Q45*C6N[MM.A86+/\``0(#!`4& +M!P@)"@L,#?___________________________P[___\/____$/___Q'___\2 +M____$____Q3___\5____%O___Q?___\8____&?___QK___\;____'/___QW_ +M__\>____'____R#___\A____(O___R/___\D____)?___R;___\G____*/__ +M_RG_____*O___RO___\L____+?___R[___\O____,/___S'___\R```!```` +M`0```````````````0````````````````````$````!``````````$````` +M`````````````````````````````````````0```````````````0```(`` +M``#_````D`$```8``````````````````````/\``/___Z7&A/B9[HWV#?^] +MUK'>5)%08`,"J'718+C0M-K+<[K3[6_:D +M379AM\Y]>U(^W7%>EQ/UIFBY```LP6!`'^/(>>VVOM1&C=EG2W+>E-28Z+!* +MA6N[*L7E3Q;MQ8;7FE5FE!'/BA#I!@2!_O"@1'BZ)>-+\Z+^7<"`B@6M/[PA +M2'`$\=]CP7=UKV-","`:Y0[];;],@108-28OP^&^HC7,B#DN5Y/R58+\1WJL +MR.>Z*S*5YJ#`F!G1GG^C9D1^5*L[@PO*C"G'TVL\*'FGXKP=%G:M.]M69$YT +M'A3;D@H,;$CDN%V?;KWO0Z;$J#FD,3?3B_(RU4.+66ZWVHP!9+'2G.!)M-CZ +MK`?S)<^ORH[TZ4<8$-5OB/!O2G)<)#CQ5\=S49%!ZI8\#^%F`"1<:VF4QU\:$N-##@K`I=UH1'LM[ +M_*C6;3HL$0```````````````````&0````0````_P`,(`@"```2```````` +M````````````+`$``!````#_``P@`@```!,````````````````````L`0`` +M$````/\`#"`'`@``%`````````!`!@````````$````0`````0`,0`0!```5 +M`````````$`&`````````0```!`````!``Q``P$``!8`````````0`8````` +M```!````$`````$`#$`#````%P````````````````````$````0````_P`$ +M``0````8`````````$`&````````,@```#(````!`LQ``P```!D````````` +M```````````!`````0````$"`(`!````&@````````````````````$````! +M````__\`H`4````;`````````!```````````0```!`````!`@0`!@$``!P` +M````````!``````````!`````0````$`#``!````'0`````````$```````` +M``$````!`````0`,``$````>``````````0``````````0````$````!``"` +M`0,``!\````````````````````!````"````/\`#"`&`@``(``````````` +M``````````$````(````_P`,(`(````A`````````````````````0````$` +M``#_`@R@`P,``"(````````````````````!`````0````$"#(`!`P``(P`` +M``````````````````$````!````_P``H`8!```D```````````````````` +M`0````$````!`D0``@$``"4````````````````````!````$````/\`#"`# +M`0``)@`````````$``````````$```!D`````0`,``(````G`````````"P! +M`````````0````$````!``Q`!`$``"@`````````+`$````````!`````0`` +M`/\`#$`$````*0`````````L`0````````$````!`````0`,0`0````J```` +M`````"P!`````````0````$````!``Q``P```"L`````````+`$````````! +M`````0````$`#$`%````+``````````"``````````$````!`````0`$``4` +M```M``````````0``````````0````$````!``Q``0```"X`````````+`$` +M```````!````:0````$`#$`#`0``+P`````````````````````"```2```` +M_P`,8`(````P`````````#(`````````9````!````#_``Q@!@```#$````` +M`````````````````@``$`````$`#$`&````,@`````````````````````" +M```0`````0`,0`4````S`````````"P!`````````0```&X````!``Q`!``` +M``,```#@8`$``0```#S6`@``````S)1```? +M'P``")$``!P6```)D0``$`D```J1```#/P``"Y$``#T]```,D0``/3X```V1 +M```_`0``YQ$>`@YX-&"!`0```!%)-@``"!%`0!4`"1%N7P``#Q$C````%1$! +MP'`$&A$"````'1$D"0``,!'5````,A&,````,Q%:````-!&;5`$`-1&"``$` +M-A%S``$`-Q%:``$`.!&T+`$`X!$$````]1$!````#2#\````$2#3A0$`$B"4 +M`P``($,Y`````D````#&"#)0``5F#__P``8F`8`@```7,0```` +M`G,`````9&`&````,'0!````!8`!````08`!````"L`/`0\!"\`/`0\!4=`# +M````#](`````$-(;````$=(#````&-+X__\?9](/`0``:-(/`0``<-(````` +M'-_N`@$`'=\8```0']\8````(=\P````2M]``$``2]\!4`$`3-\$`0``3=]` +M````3M\R`3\``."``0``-N`I*2DI1>"DF0$`9N`!````-F`&````Z70Z#>FT +M40C`'D\'.=S-!C7:3`8Q&.P%KY?+!:T6BP4L%HL%+!:+!2S62P8VG2\(Q&+1 +M"$;C\0A'9#()RN62"4QFLPG-IM,)SN?S"<_GTPG.9K,)3"9S"4NE,@G(H]$( +M12)Q"$.A,`C`W\\'O5Z/!SS>;@Z +MW8X'/%ZO!SW?[P?`H%`(PR&1"$6C\0C(I%()RR63"_'Q`(P&`P",&@4`A"83`(P6`0"$#@[P<_GZ\'O5Z/!SP>CP<\ +M'H\'/%ZO![V>SP>_WP\(0&`P",%@4`A"H3`(P6`P"$`@\`>_W\\'/I_/!SZ? +MSP>_'S`(02&Q"$>D4@E*I5()P^%P"$-A$`@_G\\'OE[/!SZ?[P<_(#`(0:%0 +M",/A<`C#X7`(0Z%0",$@$`B_G\\'/E^O!SZ?SP<_8%`(P^%P"+E<+@>Y7`X' +MMAIM!C)9+`8P&`P&,IO.!T$BD0C%8M$(1N/Q",?C\0C'X_$(1Z/1",5BD0C$ +MX7`(0J%0",%@,`C!8#`(0:%0",+A<`A$8K$(1:/1",?C\0C'X_$(Q^/1"$9C +ML0A%(I$(09_.!C(8#`:P6$P&LAFM!C9<+@>Y7"X'M5JM!C7:3`:R6"P&,1J. +M!T"BT0C'(Q()R:12""2@`'PD +MH`"`)*``A"2@`%`0H`!()J``8!"@`$PFH`!D$*``:!"@`%@0H``P$*``/!"@ +M`#00H``L#*```(&D``&!I``#@:0`B"2@`(PDH`"0)*``E"2@`)@DH`"<)*`` +MH"2@`*0DH`!;"0````+K"P````*1!X`````A"H````"2"0```0`B#````0"5 +M!Q82```E"A82``#2"0P```!B#`P````&`0```$`(``0````'`"$$``!-!;03 +MX`^'!3(```!&!?H```!'!9@Z``!(!63@DP11!7^`^@.(!?(W``!B!04!(!B* +M!0(```"-!0````",!7$```!C!=L```!!!0`"``!0!4*!H@!#!8"$\#.[!P"4 +M*&1+"@"4*&0L``(```!```(````D"/(Y``"T"O(Y``"$``!0$@">``!0$@`! +M`08'R!L"`0`G@`.Q!Y@9#,.P!Y@9#,-!"I@9#,-`"I@9#,.R!PD```!""@D` +M``"V!P"`+,M&"@"`+,N!"/][`0`1"_][`0"X!Q`1S_-("A`1S_.U!S\```!% +M"C\```"T!Q`1JJ"S!Q`1JJ!$"A`1JJ!#"A`1JJ"\!Y@9BJ),"I@9BJ*#!P`` +M`!43"@```!6$!]7__R04"M7__R2%!R4````5"B4```"`!P$[D4`0"@$[D4"B +M!_H6>"(R"OH6>"*C!_P._`XS"OP._`ZD!_H6>"(T"OH6>"*A!P9!GP`Q"@9! +MGP`E``$```#P!T=,`0"`"D=,`0`(`0`"``!1".#PX`#A"N#PX`!0"#2J``#@ +M"C2J``#5!Z(```!E"J(````.``)"1`00``)"1`3"`%)D``##`$#```#$`!!" +M"`#%`!!""`!;`"````!D`"````!]``````"7``````"A")`"```Q"Y`"``"4 +M!U``4``D"E``4`!S"!0````#"Q0```!T"!0````$"Q0````H`0#`$@`I`0#` +M$@!8!0(`"@`````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````JJH#````"`8``0@`!@0``@`` +M````````````````````````_P```/____\````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````"(;@(`;&X"`&QN`@`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````+AT````````H,`!``$```!````$````!``````(@`B42(1$0#P`/#` +MP,#`_/S\_/[^_OZJJJJJJJJJJJJJJJZJJJJJ*/\`S*JJ``"JJ@#,JJH```!` +M`,```````%``\`!0`/"JJJJJJJJJJJJJJJJJJJJJ*/\`S*JJ``"JJ@#,JJH` +M`````````````%``\`!0`/"JJJJJJJJJJJJJJNZJJJJJ*/\`S*JJ``"JJ@#, +MJJH```!``,``0`#``%``\`!0`/`'````#P`````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````__\``/__ +M`````````````/__``#__P````````````#__P``__]D+```Z"P``*PL``"H +M+```D"P``'`L``!T+0``W"T``)0M``#0+```L"P````````````````````` +M`````````````````````````````````````````````0$!`0$!`0'_____ +M______________________\"`@("`@("`@("`@("`@("`P,#`P,#`P,#`P,# +M`P,#!`0$!`0$!`0$!`0$!`0$!`4%!04%!04%!04%!04%!04%!@8&!@8&!@8& +M!@8&!@8&!@8&!P<'!P<'!P<'!P<'!P<'!P<("`@("`@("`@("`@("0D)"0D) +M"0D)"0D)"0H*"@H*"@H*"@H*"PL+"PL+"PL+"P`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````_P`````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````_P`````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````_P`````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````<'`0'(`,@```!A`)8`H`!S`.@`.@$`(````.!&`0`@`````&@!```$```` +M2`$```@``````````````&0!```$````<`$```0```!0`0``"``````````` +M$``!`````@````4````!````JJH#````AMU@`````"`Z_P`````````````` +M````````````````````````````B````&`````````````````````````` +M`@$`````````````!P```!X````#````_____P`````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````#_```````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````;.8```H````$````&-J```%DM@3,S,0#`````/B$````)9,H$S,S4`P````!I(0````IDS`3,S-8# +M`````%=5<%``!&!`````#Z +M#@```&!U6@4``$@$`````/,.````8G5!`````"H#@```'AU>`4``&`$`````*$.```` +M>G5Z!0``8@0`````F@X```!\=7T%``!D!`````"4#@```'YU?P4``&8$```` +M`(T.````@'6"!0``:`0`````A@X```""=80%``!J!`````!_#@```(1UAP4` +M`&P$`````'D.````AG6)!0``;@0`````[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWA4````D````S,S__P-;H+/=`,``4*?T +M45-E07[#I!<:EEXG.LMKJSOQ19T?%0```+P"````4$``!@```*$```````$` +M`````(:````#!Q8@I7D``$````!``````0````2$!0`````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````#5=]&\2NV-R6,E:!.;@`)Y'`$6 +MPF&T!&`>33N:$-&_>WK(@F2HVQN?&6*FYFCN'[K,6NA:VN1N[6T([:05*G@))1.*9)JI\0*8VUH15!M/]Y!H>GM6"Q=O +MV\,O-;TG%N_37H"#%F\/SK'K7*_5'BQ-Z">GA"$?JS'-,[V6WT`,DUHZ"R@- +M10ZOZ/Q?OP`'!.3E29G=MCOU=#K*EC1ZA];*2-P\8N4`RN]>A?B([N8``2@: +MXKO1L^2P;EZ=.^UCVOGYF@\D1/V\17MS)_)MBCMA<(_(]IW#NB"*DW'NC3(T +MEK*",%-%'Z%K5'S1`0`!``:.`$16?V,SW,4_W`]+W9468T=OT/7?^%B7\KM#A7%.1([\QUP=:P3?HQ`R1>L&OV/0C-TX9&6QCZ^6Z +MW"SU\>44[JZIIN_3,VJ!9(",7TG"`MAFAH\\-866:E]6CBZ^''`!K+!0)\JFY+;V@%B*146=21;C09R +M8H<#````!P````B``````(C``(````<````(``$````(P````0`'````Y&,` +M``"`18#<8P``%0````2``````(C````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````$!$(P,Q\",`0?0C`0'T(P"1\",#4EPC`V)<(P-27 +M","OOJW>```````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````!`$```````````````````````````` +M``````!T`(C`!`````<'!P<'!P<'!P<'!P<'!P<'!P<'!P<'!P<'!P<'!P<' +M!P<'!P<```````````````$`````````D!0(P)`4","@(@C`D!0(P)`4","< +M)`C`D!0(P)`4","0%`C`D!0(P)`4","0%`C`="X(P#@N","D+0C`D!0(P/@S +M","0%`C`O"((P,@@","0%`C`D!0(P)`4","0%`C`D!0(P)`4","0%`C`D!0( +MP)`4","0%`C`D!0(P)`4",!4)`C`9"0(P`````#4)`C`Y"0(P,PD",#\)`C` +M["0(P%PF",!\)@C`Q"0(P'@F",!P)@C````````````````````````````` +M````M"&(P`!@B,"T)8C````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````0```)02B,"4$HC`&"*@`!`BH`!L(*```#```/^/__\````````````` +M````````&0```,P2B,"T$(C````````````````````````````````````` +M````````````````````````````````````````````?P@````````_`!`: +M(BDP`"T`.3DY.3DY.3DY.3DY"``$``0`!``$``0`!``$``0``````#PX-#`L +M*"0@'!@4$`P(!```!`@,#@`"!`8("@QT:')E861)9&QE`&US9U%U975E36%I +M;@!T:')E861-86EN1&ES<&%T8VAE<@!M'R`A(B,D)69G:&EJ:VQM0`````````````` +M```,$A@D,$A@;`($"Q8"`````@````8````&````!0````4````$````!``` +M``$```````````````````````````````$````!`````@`````````````` +M````````````````\/#P\``````````````````````````````````````` +M`````````````````````````````(`````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=X5````!``!````",`@((`/ +M",!0`"`@@`\(P/!V(""`#PC`.$]I(```:2!``&D@``!I($``(""`#PC`"`\@ +M((`/","\#B`@@`\(P,"=(""`#PC`H'T@((`/",#`G6D@```*((`/B,"8$0`0 +M`0`5"1``2B&````80``@((`/",`0$$HA0```&$``2B```$HA``!*(@``2B,` +M`$HD``!*)0``2B8``$HG``!*(``02B$`$$HB`!!*(P`02B0`$$HE`!!*)@`0 +M2B<`$$H@`"!*(0`@2B(`($HC`"!*)``@2B4`($HF`"!*)P`@2B``,$HA`#`@ +M((`/",`H`>^^K=[OOJW>[[ZMWN^^K=[OOJW>(""`#PC`#'8@((`/",!(#R`@ +M@`\(P'`/(""`#PC`N)<@((`/",!X@@HD@#^(P/Q_02R<,$`LG#!")!PT"B*` +M/XC`:"`*(P`WX@R``THF`'!I($``[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMW@0:&#<*((`/",```&L@0`DA(,`'2B8`<&D@``)*)@!P +M!1(`-D(@0(`%&A@PD``!``04`#!K((``"!0!,&LAP``,%`(P"B2`!0#,'P4 +M`C"`%`$PB!0`,*L@00",%``PJR`!`9`4`#"K($$!E!0`,*L@@0&8%``P:R#` +M`IP4`#"K(-`$A!0`,(`D`C@O)#\``1(`-D(@/H`#$@(V%`$A`$(B/H`"$@0V +M#``B``(@/H&<``(`"!`<``P0`0"K(0@(!!0`,&L@@``(%`$P:R'```P4`C`* +M)(!P$!0?,!04'3!4%`PP6!0+,%P4"C!@%`DP9!0(,&@4!S!L%`8P!0#,'P4`C"`%`$PB!0`,*L@00", +M%``PJR`!`9`4`#"K($$!E!0`,*L@@0&8%``PJR"0`)P4`#"K(%``A!0`,(`D +M`C@O)#\``1(`-D(@/H`#$@(V&`$A`$(B/H`"$@0V#``B``(@/H&@``(`"!`< +M``P0`0"K(0@(!!0`,&L@@``(%`$P:R'```P4`C`*)(!P$!0?,!04`C"K(A`` +M5!0,,%@4"S!<%`HP8!0),&04"#!H%`!0#,'P4`C"` +M%`$PB!0`,*L@00",%``PJR`!`9`4`#"K($$!E!0`,*L@@0&8%``PJR"0`)P4 +M`#"K(%``A!0`,(`D`C@O)#\`"!`'`$HF0```'X`!&!_`!AP?@`8@'T`&)!\` +M!B@?P`4L'X`%,!]`!30?``4X'\`$/!^`!$`?0`1$'P`$2!_``TP?@`-0'T`# +M#!("-D(B/H!*)P``#``!`!@8@``,&M@Q`1K8,:HBD`"&(@$`JR*0``H@@`\( +MP)0(JR`0`"\D/P!I(```2B8`<(`<0#"$'``P!1(`-G@!S`,$(@/H!\'(`PB``A`$`@0``%&A@P5!P`,U@< +MP#)<'(`R8!Q`,F0<`#)H',`Q;!R`,7`<0#%T'``Q:B*`$&HAP!`,'``_!!R` +M,@@<0#*J($$`B!P`,*H@`0&,'``PJB!!`9`<`#"J(($!E!P`,*H@D`"8'``P +M1"``!RD@``"J(%``G!P`,*H@$``A(,`'%!P`,`4:&#`!$@$V5!P`,T(A/H!8 +M',`RD``!`%P<@#)@'$`R9!P`,F@J()``F!P`,$0@```3<,-TT\.!X +M!-PLW3+PX'@$W"C=,/#@>`3<)-TN\.!X!-P@W2SPX'@$W!S=*O#@>`3<&-TH +M\.!X!-P4W2;PX'@$W!#=)/#@>`3<#-TB\.!X!-P(W1_PX'@$W`3='/#@>`3< +M'/`T%!HP,!09,"P4&#`H%!'` +MX'\!P`HF`/"*(+\/RB!D`.!_+R`#`.!_BB#_#QT`(`!*(``002G(A\XA(@!" +M*,.'SB`B``<@R!`*(D"`4``A``AQ`-AI:"\M08#*)<0`+RZ!@,HFQ``")D.! +MRB,D`$`C?`#`*L,`J"#``@(A@8#/(`8/P"&%`"\B@@`O(`*2+R`#`,X@)0#@ +M?\XA(@`@((`/",!D#5,B0H'@?$XB`X@6``P``"G,``$I@0`!*(``X'^%>$XC +M`P`!*<``X'\B>>!X?0H0``4@1`!$)/Z`=``"``HC``!!*CR!Z""B!`01!`0$ +M$04$!!$&!`01!P0$&Q`!!!M0`00;D`$$&]`!1"+^@^`@P0<5"MX`!!$$!`01 +M!00$&Q`!!!M0`0T*G@`$$00$!!L0`0T*7@`"$00%`AL4`0T*'@`!$80$`1L2 +M`2`@P`<*)(!P0B%!`$(@0P"H((`!`1&$`@$;"@$@(,`'@B0".``<`#`$'$`P +M"!R`,(H@!``*(8`/H,`<.``9(`!*(```"B&`#Z#`5!X`&2``"B"`#P,`0`T* +M(8`/H,#@(``9(``@((`/",!T"X(D`C@`'``P!!Q`,$H@```*(8`/H,!4'@`9 +M(``0',`W`!0`,`04`3"N#H__0B0<-*8/P`)`)!PT(""`#PC`&`*")`(X$!S` +M-^8/C_]")!PTJR80=@`````Z"$`$0"0<-"`@@`\(P/0#@B0".!`^#X__ +M0B0<-*LF$'8```$`$@A`!$`D'#0@((`/",#T`PH@@`^(P'PV`!C`!P08P`8( +M&$`&#!@`!A`8P`44&(`%&!A`!1P8``4@&,`$)!B`!"@80`0L&``$,!C``S08 +M@`,X&$`#2!B`!DP8``<*((`/H,!4'@`0`0A/(0$``!A@`&D@@`%O(3\`2B8` +M<$HF`'!*)@!P2B8`<$HA```*((`/H,!4'@`88``*((`/B,!\-@`0'P`$$!L` +M"!`9``P0&``0$!<`%!`6`!@0%0`<$!0`(!`3`"00$@`H$!$`+!`0`#`0#P`T +M$`X`.!`-`$@0&@!,$!P`("#`!P#9(""`#PC`+"_@>"AR`=D@((`/",`L+RAT +M2',"V8ER(""`#PC`+"_QP.'%*'5(=)AS`]FI/'` +MX<4`W1+PSW"(P.P18(!P6`Y1GT`-I( +M<83A;/<4;<]S18``&`++A88$%H`>'L\2`@ +M@`\(P/P,X'@`VD"P(MI#L";:>AB$`"K:P!B<`#[8X'\2L>!X\<`B((`/","` +M#,20SW6(P-00`VY&(,\`!(WCN((D"#`)\L]PJ/[P"P#9(B"`#PC`<%F,)@B0 +MRB"-#Q``!P_B((T/",!P$(MV02^!$,EP(B"`#PC`9)L!PH#B#O($C>.X&_+/ +M<*C^``P!V2(@@`\(P'!9$_`"P(+@RB""#Q``"`_B(((/",!P$".&`($A@2(@ +M@`\(P%AV@"0(,"`@@`\(P.P,X'@#V>!_(Z#@>`+9(Z`%V`#9*'(@((`/",`H +M<^!X\<`B((`/",!P#((D`C0(=@#=BW`#V3IQ(B"`#PC`9)M`)@\5#-@$IJ*G +MH:+\(3`(B"`#PC`9)L!P0+" +M4R%3!PEJSW.@P`!-%2,0(&`3``A@$P,(U[@$(X,/``\``#B[`2FH*<"P`&G%_#/#*(H($*'"$P2(@@`\(P"`.H*<`V(#@,_3/=0`!``!R=0?WSW```0`` +MI`=C@?O'`(B"`#PC`A`Q(=D&*4'$`W=?W88@"(8P`76.Q</'`(B"`#PC`@`P(=\]V +M``#__\]P1H#L.J"``_`!Y<]P18`@Y4`@`0(!@!!U3?=:)0`;!MHX8.EQ(B"` +M#PC`O':`X.[U`O#)=:EP(""`#PC`[`S@>,]P1H#L.@"`"'(,\%HB`0LL8UH@ +M`0LI8S!TRB")``'BSW%%@"#E0"'#`R&!,'+P]^!^X'CQP"(@@`\(P(`,J\$( +M=P>)*'4&'`(P(B"`#PC`N)X(<<]P1H`@!B(@@`\(P*"D@.`^\@*%(B"`#PC` +M"'0''`(P`H6#Q@&`(-E"P,EP(B"`#PC`0'Y!CX#BQ_8B;\EP(B"`#PC`*'Z+ +M<*EQ!MHB((`/",`H?HMUJ7`B((`/","D7R(@@`\(P&AC@.#*($(#XB""#PC` +MO&4B((`/",#09H#@RB!"`^(@@@\(P!QIJ\`@((`/",#L#.!X\<`B((`/",!P +M#"]X6B`-!PHC@"]&@!0$`-O/=T:`E`4Z<&)U8*5RIP**8;B.X(@`#0`S)@!P +MB,`8$T`GC'(4?`!\$X>`X&&E-O0BA2IP`-HN\,]V1H#T!0H@P"2`($`X`/T`XH1IR*%*G`!VB(@@`\(P%QA(B"`#PC`$!H@ +M((`/",#,#/'`(B"`#PC`6`R")`,U^G+$:B\@1S!:(`\WBW`[<,]QB,`$%(S: +M(B"`#PC`(`Y6)`TT"B$`)PHE`"=`)0`3SW&(P*`5-=HB((`/",`@#L]PB,#( +M'""`2B0`(`&`Q!Q`,,@<`#`$'``U`!P`-0@<`#4!V!IP0\`0'``U3L!\'``U +M>!P`-8`<`#7/<$:`E`4`)Y(?1H`4!!`2`2!Z<(;AT@`M`$P8``4S)D%PB,`0 +M$T`G@'(T>`!XSW`(P*`40"4!$PIR"G,*)``$"B4`!2(@@`\(P'"#3?#/<`C` +MH!1`)0$3BG(!VTHD```?\,]P","@%$`E`1,*>TYZKW0!V"%4`5@!`$K4`E`!.('``P5!,`(."X1/)5)%4T(B"`#PC` +M+'1,'0(0(B"`#PC`+'1-'0(0(B"`#PC`+'1.'0(0(B"`#PC`+'1/'0(0(B"` +M#PC`+'10'0(0(B"`#PC`+'11'0(0SW!&@-0%0"#/!T`@0P9*)(!Q`-BH(``$ +M"F,)9P`A#"#,%(P01GF$>D5Y`"4,(""L`>`/>$P<`#3/<(C`S#8K<'!4(]!`2 +M`2"`X<4@X@$$](8@_`$4KA6.@.`0'@`5UO<6)@`5'(@B((`/","XG@':"'%5 +M)4`4(B"`#PC`E*45CD`D5""2<"[W"!("(`MP525!%"(@@`\(P,QA`=B`)`,U +M(""`#PC`G`SQP"(@@`\(P'0,&G&`X%``+@``V3IQ%2!!(%IPH(G/=T:`]`7/ +M=D:`U`4';T`F01FI`X;/SJL`@((`/",#D#/'`(B"`#PC`8`R")`,Q"'4* +M)T"@"B"`+T:`%`1`(!(F0"`5)4`@$2)`(!,C0"`4)&#T`X6`X(P`+@!*)@`@ +M4-P:)@`C0"4.%QYF#(X`WUH@`0B<."@#(Y:(``'0G#@H`V.@.#6]Q4FP!,2B"(@@`\(P+B> +M"'$,C@':6B``!P'GHG`B((`/","4I0V.$'>M]P.%0"96(-)P@@?-_P&%SW9& +M@-0%=1@8($`E@15`)D`6!MHB((`/",`H?D`E`11`)L`7!MHB((`/",`H?@+8 +MR7H!\7_BW')<"(@@`]%@+"P"B$`@,H@@@\0`&\0XB""#PC`?!!, +M)P"@!_0`A2*%(B"`#PC`<&*`)`,Q(""`#PC`K`S@>/'`(B"`#PC`=`RPP1IP +M`-__WL]U1H`4!`HB@"]&@-0%J7&`(4<)SW!&@/L%$-HB((`/",`@A>ER&O!: +M(@,'N6,#@8#@$_(5),`S0*``@8#@RB:"$$P@`*`!YPGT`-B[8P2C`J,#HP6C +M!J,!XI#BI_<*(8`O1H"4!4`1`"""X!'TBW'I<"(@@`]%@,2O@.#*(((/$`!V +M$.(@@@\(P'`0C";#GQ_R6B8`%QUE`86`X!GT&!*!()F^$+D!V`&ESW"(P,PV +MQ7DB((`/18"1#B(($/",!P$$P@`*`&\@'90!E`(`WP`-E` +M&4`@(B"`#PC`A&(B((`/",#(&;#`(""`#PC`U`SAQ6.`D.,$]X#C!/0#V#_P +M(H#DX3SW@.-P`"X``-V?<^!XJ"``#5#<&B4"$T`@`0=984V)D.(L]H#B!?1! +M@8#BYO.`Y0SR&B6,'P``4`!"(`(*C&),B5!TM`?)_X#E#?(:)8P?``!0`$(@ +M`@V$8D"!4'2!^X'CQP"(@@`\( +MP%P,HL$(=3IQ&W+ZBW!:<,]QB,!$%0/:(B"`#PC` +M(`Y!QDP@`+#,)"*@S",BH,PA(J`[\D@;@",%\$@;0"`"=C)V^``&```EEA,` +M%H\@C"?#GP$6@"`V`"D`0""0```F`!0R(=\('"2G#I +M<2(@@`\(P&@?`<&4X9KS+WGJ<"(@@`\(P(0B@."2\P'`D^"Y9HSS#WCT)0`@ +M8G`*`'89_`"V&7PP*5D\`388?`* +M<,]QB,#`'\ER(B"`#PC`('Z`X!7T:;^*YZ@`#0`S)L]SB,#($T`G@'+T>`!X +M!=A'\`;81?`2V$/P$]A!\`IPSW&(P/`3R7(B((`/",`@?H#@'_24YVP`#0`S +M)L]SB,#4$T`G@'+T>`!X!]@I\`C8)_`)V"7P"M@C\`O8`*4,V!_P#=@=\`[8 +M&_`/V!GP"G#/<8C`N!_)/'`9H"`XPAR'/0`@H#@RB-A`1[R$8J`X`OR"I(#X$8@P`#7<````"##]P?; +M9J('@@/@1B#``(P@$(#+]PC;"/""XP?T`(*`X`/R!MMFHH+CRO&`B>,FX`GMP=X8`*G`X`*A`X%AN`.AP<;!Q>!^X'C/<$:` +M+`8)D.!^X'C@?P#8?6E5:_`@P`!">0#:#R)"`$1X$'(!V.!_P'C@>,]RH,`` +M.!02`0@$$@`()'@4&B``(""`#PC`=(#QP"(@@`\(P,1OSW"@P``X&!B@#Q`` +M``#1P.!^\<#AQ00@C0\```!_2+T(<9#ERB"&#Q``#@/B((8/",!\$+!X(""` +M#PC`_`P`V,]Q18"HQXHB%``@((`/",`$5_'`X<7/=46`J-LAA8#ARB""#Q`` +M#0_B(((/",!\$`#8(B"`#PC``%@`A03@`*4@((`/",#\#.!X\<`B((`/","` +M#`HF`)#/=46`J-L2\LEWSW&@P``.:!$!"`#8(B"`#PC`9%@`A6&_!."`YP"E +M,O$`H`@7/<:#``#A8&:``SW&@P(`>,!D@`"`@ +M@`\(P$`DSW&@P(`>-!$!"`MY`=C@?\(@`0#/BAPX'@@((`/",`82\]P$`#[#B`@@`\(P'`0X'@@((`/",!<;L]P +M$`#^#B`@@`\(P'`0X'BAP?'`X<6BP<]PB,!`%0"`1,%`P`#=0<6+<(3!!-HB +M((`/",`H?@#`$'GMX6_R0``)`-'A3?(*]H'A<_*(@@0\(P."7A_#2X4WR +MX^%N\N3A@?2!P"(@@`\(P/QS"'&I<"(@@`]%@`BB\F?PUW$``/_[6O(&]M=Q```!^U3R7?#7<0``__U0\M=Q +M``#__E7T@<`B((`/",#\$(],]QB,#$-0Z)`>`.J>!^X'@@((`/","H)N!^X'CQP`AS"B)` +M@,PC(8#*(<(`RB""#Q``,1#B(((/","($"(@@`]%@&2QT<#@?O'`SW"(P,PV +M(B"`#PC`-)0B((`/",`DER(@@`]%@&BN(B"`#T6`,)DB((`/",!`9B(@@`\( +MP%!/T<#@?O'`X<4(=2AS]!P,L"(@@`\(P'@M0L("'`0P0``T`,R:"<(C`4!-`)PQS5'P@?`#;"'(=\`AR&?`(/'`(B"`#PC`@`RBP9APSW-!@````-V+=VAPZ7$B((`/",`T +MD__>G[X)\!MC".-H<.EQ(B"`#PC`-),`P-%P%/(!Y9!PKWT0\H+E#?8$:X'! +M(B"`#PC`-),!P-=P``#_?Z7WR7#1<,HC(0!H<*+`(""`#PC`[`S@>/'`(B"` +M#PC`@`P(=@#?X*!O($,!*'4B((`/",#()PHC`(`2\D`C``*I<2(@@`\(P#23 +M!&O)<2(@@`\(P#230",``P3PX*7I<"`@@`\(P.P,\<``V.'`;R##`"(@@`\( +MP,@G@.#*(0('P"`B`N(@@@\(P#23`,"AP-'`X'[QP"(@@`\(P(0,"'4H=@K8 +M`-FI<@+;(B"`#PC`@)%CC0K88;L"V`P(=AIQ`-T)V*EQR7("VR(@@`\(P`B28XX)V&&[`MD*`"A"M@`V8^Y(B"`#PC` +MG)($)0`4(""`#PC`W`S@>/'`(B"`#PC`@`P(=BAWSW"(P.P1`(!(=1!RRB&& +M`\H@A@\0`#8"XB"&#PC`B!#/<(C`Z!$@@`R]SW*(P/`1`X*Y80'@`Z+)<.ER +M(B"`#PC`<$X@((`/",#L#.!X\<`B((`/",!X#,]VB,#P$0>&@>`+]`J&C"`$ +M@$?W(B"`#PC`W&R`X`_T(B"`#PC`W&PGA@AS28;/`"INEP(B"`#PC` +M5(`.INEP(B"`#PC`0(`*<"Z&`-HB((`/",`,3P+8+_#/=XC`#!'/<(C`[!$` +M@""/$''*(48#RB"&#Q``-P+B((8/","($`"/SW&(P.@1((%`*`(#"Z9982RF +M`>``KPR&*H8B((`/","D?PR&`-HMAB(@@`\(P%!-!-@B((`/",#\*R`@@`\( +MP-P,X'CQP$HDP'((/'`X<7/=8C`\!$'A83@RB""#Q``.P+B(((/",!P +M$`R%`-F,N0':(B"`#PC`W($%V"(@@`\(P/PK(B"`#PC``#0B((`/",#D+"`@ +M@`\(P/P,SW&(P/`1X'\'H>!XSW"@P``@;!`!",]RB,#P$02"`GD&@CA@!J(% +M@A!QP_!_)*#QP.'%SW6(P/`1$84RA0BE +M$X4II0^E$(6`X,PA(H#*(($/$``X`N(@@0\(P'`0$(6`X`#:SO=:(@`#N&`T +M@`'B,:`U@#*@-H`SH!"%$'*U]V&X$*4@((`/",#\#/'`(B"`#PC`?`P(=RAV +MSW6(P/`1$(4:/'`X<7/=8C`\!$'A8#@RB""#Q``/`+B(((/",!P$`OP +M#-@B((`/",#\*R(@@`\(P``T$(6`X`7R!X6`X/+S(""`#PC`_`S@>/'`X<7/ +M=8C`\!$'A8+@RB""#Q``/0+B(((/",!P$`/8(B"`#PC`_"LB((`/",``-`>% +MA.#*(((/$``^`N(@@@\(P'`0(""`#PC`_`S/<8C`#!,`@0'@`*'@?Q!XSW&B +MP`!+!!$`"``1`@A2(```!!$!".!_P+C@>/'`(B"`#PC`@`S/<:#```Y,$0X( +M`-@0&2``:!$`",]WH,``$`0@C0\`&```/+UH$0$(J7(B((`/","`<(#@RB!B +M`!VX@.7'<``@``"?N`5^9!^XDP?R$(@@@\(P'`0(B"`#PC`K&LB((`/",#`:='` +MX'[@>`:`X'[/3]BH5@!`0=H_V,G;^W,PF`I/*(8(#RB""#Q``Z@[B(((/ +M",!\$#)V$/0#A8#@RB"!#Q``ZP[B(($/",!P$`.%^&``&`($'?",)H.?$/0$ +MA8#@RB"!#Q``[`[B(($/",!P$`2%^&``&`($"_`J%8`0(H4=(,`#V&`980`9 +M`@0@((`/",#<#.!X\<`B((`/",!$#2(@@`\(P'0,1\!(P<]WK=[OOFD@``#/ +M=:#``"`,':`?(```!`#8(B"`#PC`!)$(P(#@RB+!(P7R@>`D%!(P!/<:=SIW +M"O`H%!$P@N#*(,XCQ/``2(@@`\(P.!&((6`X-EA(*7*(((/$``2 +M`>(@@@\(P'`0H\`@((`/",#T#.!X\<`B((`/","$#*/!SW:(P(43SW6(P-P1 +MSW"(P`PVR7$#VF"%BB0!"$HE``XB((`/","(12"%@.!@X2"ERB""#Q``$@'B +M(((/",!P$,]R",!X=,]UB,#@$0`5!!``VT##`=A!P+C80L!`)D$4`]X*OL]P +MB,#`-[AV2B:```HG@`$B((`/",#@1B"%@.#982"ERB""#Q``$@'B(((/",!P +M$*/`(""`#PC`]`S@>/'`(B"`#PC`A`RCP<]VB,!C$\]UB,#D$<]PB,!$-LEQ +M`]I@A8HD`P!*)0`.(B"`#PC`B$4@A8#@@"$#`""ERB""#Q``$@'B(((/",!P +M$,]R",`$E<]UB,#@$0`5!!``V$#``=M!P[C80L!`)D$3`]X*OL]PB,!X.+AV +MV'/X(@@@\(P'`0H\`@((`/",#T +M#/'`(B"`#PC`$)8B((`/",`X:B(@@`\(P'23(B"`#PC`H&S1P.!^X'CQP"(@ +M@`\(P``P(B"`#PC`'#$B((`/",!P,,]PB,#D$2"`SW"(P+0U$'$+]\]PB,#< +M$2"`SW"(P+0E$''(]\]P$``3`2(@@`\(P'`0T<#@?O'`(B"`#PC`@`P(=P#8 +M]!P(L$'`0L#/<(C`\!$'@`'>@.#`?HMP(B"`#PC`U)H(=0#`@L$,N$#`@<`B +M((`/",`$EX#ES"`B@`?R`,$!PC!RRB&%``;P@.4#\@#!`O`!P04@?H,@IPGR +MUW$````0`=C"(`X``O`!V,1XH\`@((`/",#L#/'`JR8(<`````$B((`/",`@ +M3B(@@`\(P%1*2B2`<0#9J"#``UHA@`''<$6`C+)"D&&0$+H`D$5[*R,```'A +MSW"(P(@2((#/<*#``"!L$``(,GDX8`'@02@`@^(@@@\(P/R9(B"`#PC`B)?1 +MP.!^X'CQP,]QH,``(&P1`@C/<8C`B!*`X$"A#?)88,]QH,``'E@9(`!4$0`( +M@;A4&2``2B2`<0#:J""``UHB@0''<46`C+(`D0'B*B,``&&Q,+MBL2(@@`\( +MP`A.(B"`#PC`+$S1P.!^\<`B((`/",!P?2(@@`\(P"B6(B"`#PC`,%HB((`/ +M",!L6<]QB,``8`#8#]HPVR(@@`\(P&A*(B"`#PC`5(,B((`/",!<3B(@@`\( +MP.Q-T<#@?N!XSW"@P``>0!B@#P`@``#@?B`@@`\(P#27\<`B((`/",!L#*HG +M$!$*(H`OB,!\(``2`"B"X,HAQ@/*((8/$`!$`N(@A@\(P'P0SW:(P/`1!X:# +MX$#RSW4``0``A>`5\HS@2_*J(1`F`B=`$T$H$P.,(P2@Z``F`(HD@R_/<4:` +M:"4R(&(B"`#PC`_"LB\``2`"B"X$SW`1(--E8F`12I<"(@@`\(P,B9`_`` +MW0>&@.`)].FFJ*8\'D`4*![`%+SQZ7`J<:ER(B"`#PC`G"P@((`/",#$#/'` +MX<7/=8C`\!&(%0`0`>"('0`0(B"`#PC``#00\`#8GK@B((`/","H6B(@@`\( +MP"PM!O""X/7SA.`)\@>%@.#Z]2`@@`\(P/P,`-B=N"(@@`\(P*A:(B"`#PC` +MK"OP\?'`(B"`#PC`)#PB((`/",!41`#9SW"(P#``(*#/<(C`+``@H,]PB,`H +M`""@SW"(P"0`(*#/<(C`&``@H,]PB,`4`""@SW"(P`0`(*#/<(C````@H,]P +MB,`0`""@SW"(P`P`(*#/<(C`(``@H,]PB,`<`""@T<#@?O'`X<4%R,]U\/#P +M\-=P\/#Q\`SR!1I8,R(@@`\(P``"(B"`#PC`+#8`R`4:6#,B((`/",!8F0#8 +M!1H8,"(@@`\(P)0((""`#PC`_`SQP%Z`@.(A\@#;?:`K@D(A08`KH@KR@!`! +M`'^`@!M``'^A*H(P<`/T:J(O@(7A#?0D@H#A"]G*(:$"D!A``"(@@`\(P.`] +MT<#@?N!X\<`B((`/",!X#`AU&G%(=VAV"B$`(3C9(B"`#PC`-"<$'0`4XJ4R +M;RIP(B"`#PC`?`T=(,(#R:7&I14F@1#(I2>E!:4#I6H@@`($(($/___]_RD@ +M0`!*)@!PSW*(P"0``!V`'U51544@@@'A(**!X<]RB,`H``;TH**LI:VE"/`@ +M@DV!K:&LHDVE+*4I(```2B8`<`#8(""`#PC`W`S@>/'`(B"`#PC`=`P(=2AV +M&G)J((`"!""!#____?\I($``2B8`<"P5$1!,(0"@6G`I]`2%@.`E\B*%"(6! +MX000`@0$'I`0S/="(4&`RB1"<.!XZ""B`000`00$'E`0)X4P<`+T!H4(I06% +M`>`%I02%8;@$I2D@@`1*)@!P`-B_\.J%@.$$ +M$`($!!Z0$,SW0B%!@,HD0G#@>.@@H@$$$`$$!!Y0$$(A0*!D\C^'*J5`@X`9 +M@``_H@NE`-@=IY`?`!#I<"(@@`\(P.`]S?$$A8#@S"4!#,]T(B0H#*)()PX'CH(*(!!!`!!`0>4!`GA3!P`O0&A0BE`\@!X`,: +M&#`I((`$2B8`<&H@@`($(($/___]_RD@0`!*)@!P6G`#R(@7`1!AN`,:&#!" +MA8'B"84$$0,$!!C0`,WW0B)"@,HD@G#@>.@@X@$$$0($!!B0`">%,'`#]`:% +M":5"(4"@ZH4%]`#9*J6A\5^'2J6`%P$0@!I``%^AF?%,(`"@+/(!R,]Q",#P +M-CV@5B`/!+Z@PJ<`V4PA`*`CIP;T"J4?H`"G"O!*A5^@@!(!`""G'Z&`&@`` +M0"%!("NE!=DOH`IQ(B"`#PC`B#XI((`$2B8`<`2'!_`I((`$2B8`<`K8(""` +M#PC`U`S@>/'`(B"`#PC`=`P(=3IQ&G)J((`"!""!#____?\I($``2B8`<"6% +MBX6`X5IP*/*`Y";T8;D$A26E`>`$I0F%`!$!($*%!!A0`('B0"$!(.@@X@$$$0($!!B0`">%,'`#]`:%":4I((`$2B8`<`#88_`*A8#A +MS"`B@"SR0B1,D%8@`@0`W@/TRJ4'\'^`:J4@@H`;0`!_H8NEW:`B@@`1`R"" +MA009T`"!Y$`A`R',]T(D3)#*)`)SX'CH(*(!!!,,!`09$`/$HB(@@`\(P.`] +MS/%,(`"@*O(!R,]Q",#P-CV@5B`.!+Z@"!Y`%`#9@.0CI@7T"J4?H`"F"?`J +MA3^@@!$"`$"F'Z*`&0```>2+I079+Z`*<2(@@`\(P(@^*2"`!$HF`'`$A@?P +M*2"`!$HF`'`+V"`@@`\(P-0,X'CQP"(@@`\(P&P,"'4:<3IR6G.(=@HC0"'( +M=PHDP"&XV2(@@`\(P#0G-!T`%%`=0!14'8`4PZ44'<`40B-`(!YFQ*56)0X4 +M[J4)P.BF!J4'I2#8DG<*I@;R`-@2I0FF!/#RI>FF`]@/I<]P",!,0!BEN:7/ +M<0C`##VI<"(@@`\(P!`*:B"``@0@@0____W_*2!``$HF`'#/<8C`-``:<``= +M@!](5$12`($!X`"A@>#/<8C`.``%]*"AI::FI@KP`(&8$`$`F!A``Y090`,F +MI@6F"L$`V('A"J4+I0RERB!!`^(@@0\(P.`]*2``!$HF`'``V"`@@`\(P,0, +MX'CQP.'%`-T!&E@S`AI8,\]PB,!$``39(B"`#PC`-"<@V<]PB,`\`""@SW"( +MP+0@@-DB((`/",`T)\]PB,`X`*"@SW"(P#0`H*#/<(C`0`"@H,]QB,`(``"! +M`QI8,P4@@`^J@0```*$@((`/",#\#.!X\<`B((`/",!\#`AU:B"``@0@@0__ +M__W_*2!``$HF`'`:<`^%@^`8]*EP(B"`#PC`X#TI(``$2B8`<&H@@`($(($/ +M___]_RD@0`!*)@!P&G``W0KP$(6`X`7R`-@0I1G=`O`2W2D@``1*)@!PJ7`@ +M((`/",#D#.!X\<`B((`/",!\#`$2#38TA6!Y%87/<(C`0``@@(#AXR!"`,H@ +M0@-J((`"!""!#____?\I($``2B8`$"`@.(?]*"@SW*(P$0``(*HI0\@0```HL]RB,`\`&""<'$"R*FE5O>`X""B +M!?0"&E@S$/`2@!!Q3O<"&E@S#_`)@JB@J:()I4BE!/`0I0/8#Z4"$@$V`<@P +M<`KR!<@#$@$V!2!^@.(@@0\(P.`*(""`#PC`_`SQP"(@@`\(P(0,`1(.-M%P +M"'42](#AS"&"C_____\,\E8EP!(VI2(@@`\(P+1$!X4,&A@P*(7/=(C`M"`P +M=4Z%"845)(,0"?()H2B@`(,0=5WT(*-;\`#9(*///'`(B"`#PC`?`P(=6H@ +M@`($(($/___]_RD@0`!*)@!P&G`/A83@"/2I<"(@@`\(P.`]"/`]A8#AXR!" +M`,H@0@,I(``$2B8`<"`@@`\(P.0,\<`H@(#A!?0B@(#A`_07V`?P".`B((`/ +M","T1`#8T<#@?N!X\<`B((`/","`#`AU*'9(=VH@@`($(($/___]_RD@0`!* +M)@!PF'`(A8#@!/3"I>.E*2```4HF`'``V"`@@`\(P.P,X'CQP"(@@`\(P'`, +M"'4H=DAW&G,*(@`A"B%`(0HC@"$LV2(@@`\(P#0GP:4('8`4#!U`%.2E%!T` +M%&H@@`($(($/___]_RD@0`!*)@!PSW*(P$@``!V`'U1!34D@@@'A(**!X<]R +MB,!,``7TH**II:JE!_`@@DJ!JJ&IHDJE*:4I(```2B8`<$PC0*`(]$`E`!(B +M((`/","T1`#8(""`#PC`S`S@>/'`(B"`#PC`A`Q`(`T":B"``@0@@0____W_ +M*2!``$HF`'`*$@,VAH5P=#X`)0"8<`D2`38P=%GW!A(.-M%TA_<")(`30K@! +MX`CP`B3"$,)Y0KE"N@'A6&$@A:#AQ/="(0$(.&``I8#D%/(DA3!U"/0@A#!U +M`-@,]`"D"O`%A06A)*``A!!U!/2&H2"D`-@&I2D@``%*)@!P`-@@((`/",#T +M#.!X\<`B((`/","`#*+!`-]!QVH@@`($(($/___]_RD@0`!*)@!PF'#/<8C` +M4```@8#@!/0'R(#@"_0I(``!2B8`<*+`(""`#PC`[`P!V`"A!A("-@""@.!` +MP`/RBW$FH`#9(*(&R`D2`C8$X%!P!AH8,`3T"L@&&A@P!QI8,"D@``%*)@!P +M#/``V`:E*2```4HF`'"I<"(@@`\(P+1$:B"``@0@@0____W_*2!``$HF`'"8 +M<#KP)(6Q<03T`-A`P`CP!85`P06A)*"+<`:A`(6@X,;W0B``"`"E`-X(\,*% +M`87CA8#@`*4&\H'`!J6DI03P`-@&I2D@``%*)@!P@.;C(((#RB#"`VH@@`($ +M(($/___]_RD@0`!*)@!PF'`FA8'`,'"S\P#%@.7&]0?(@."1]0#9SW"(P%`` +M(*"`\?'`(B"`#PC`=`P:<"AV2'=H=0HB`"$*(4`A:B"``@0@@0____W_*2!` +M`$HF`'"`YIAP!?($$``@`*:`YT`@`R(#\@#8`*>`Y0/R`(,`I0H2##8F@Y%Q +M3``%``D2`C90<4``!@`&$@XVT7'"(88#PBFF`,`A9@!(]X)YPGI"ND*Y`>)9 +M84"#0B(,"*#B/&3*(0T#@.<#\@'8`*>`Y0+R(*5,(@"@!/(A@P`:0"!,(0"@ +M!?(D$`$@`!E`("D@``%*)@!P`-@@((`/",#4#/'`(B"`#PC`A`P`W0L:6#,, +M&E@S"!I8,P<:6#//=HC`-"')<(#9(B"`#PC`-"?)<`H:&#`&&A@P5B8`%`D: +M&##/<(C`4`"@H,]PB,!,`*"@SW"(P$@`H*`@((`/",#T#/'`X<4(=6H@@`($ +M(($/___]_RD@0`!*)@!P((68<(#AS"&"C_____\)]"D@``%*)@!P(""`#PC` +M_`P&A8#@]_6@X`D2`38P<(7W(G@Z:`K(-7@@@(#A!O2D +MI:6EH*`'\$6!I**EH22E1:4&I=GQX'CQP.'%"'5J((`"!""!#____?\I($`` +M2B8`<$:%@.(5\F2%<'4']&""<'4`V0OT(*()\"6%):-DH2"",'4#]$:C8*(` +MV2:E*2```$HF`'`@((`/",#\#.!X\<`B((`/",!T#`HF`)!:<4AW&G,*(0`A +MJ'`$\KC@!/()V%_P:B"``@0@@0____W_*2!``$HF`'`#$@$V`>$#&E@P*2`` +M`$HF`'#/<(C`*`"@@`#8`_"LA0'@SW&(P"0`(($P<$/WL7;W]6H@@`($(($/ +M___]_RD@0`!*)@!P`Q(!-F&Y`QI8,"D@``!*)@!P(B"`#PC`N#^Q=L3S3"`` +MH,H@X0`=\H#G`_*0Y\/W!=@7\$$I@"`0=SOW!`HC`(`&\@"#UW!5455%!/() +MV.!^@.'A(,$'RB#A`(#B!O(%R(#@X2#"!P38:'`@((`/",#<-^!X"B,`@`;R +M`(/7<%51544$\@G8X'Z`X>$@P0?*(.$`@.(&\@7(@.#A(,('!-AH<"`@@`\( +MP.`YX'CQP"(@@`\(P&@,HL$*)@"0NG%(=YIS"B``(0HB0"$*(8`A"B/`(0;R +M#L",(`*.!/(.V(KP:B"``@0@@0____W_*2!``$HF`'`#$@$V`>$#&E@P*2`` +M`$HF`'#/<(C`.`"@@$(B0R`"'/<(C`-```@!!Q4/>Q=@[R +M0X42<@7W!(42<`;W4'.N]P2%$'-L]TH@`"!J((`"!""!#____?\I($``2B8` +M<`,2`39AN0,:6#`I(```2B8`<"(@@`\(P+@_L7:R\TP@`*#,)R*0RB#A`#;R +MC"(,J&0`)0#*(&4!3"$`J%@`)@#*(.8##"'`I$P`)0`8V`W`@>!$`"T`RB`M +M!`42`3:`X0?RUW'P\/#PRB#E!)3W#,%!P$#!R7"J<>ERBG,*)``$"B6`!`HF +M0`0*)\`$(B"`#PC`*#NBP"`@@`\(P+P,X'B`X/'`!O(@@-=Q2%1$4@3R#M@& +M\"(@@`\(P)0\T<#@?H#@\<`&\B"`UW%(5$12!/(.V`;P(B"`#PC`=#W1P.!^ +M@.#QP`;R((#7<51!34D$\A78!O`B((`/","<0-'`X'X*(P"`!O(`@]=P5$%- +M203R%=C@?H#AX2#!!Q;8!G,*(0`A"B)`(0H@@"'H<`3RK.`$\A787_!J((`"!""! +M#____?\I($``2B8`<`,2`38!X0,:6#`I(```2B8`<,]PB,!,`*"``-@#\*F% +M`>#/<8C`2``@@3!P0_>Q=O?U:B"``@0@@0____W_*2!``$HF`'`#$@$V8;D# +M&E@P*2```$HF`'`B((`/","X/[%VQ/-,(0"@RB"A!1WR3"!`H,P@(J`7V!?T +M!&)Y`-L/ +M(T,`((#%(<(`QB'!`.!_(*#@>/'`(B"`#PC`A`P(=*&(:'8`@P+ENV!P<,]Q_LK^RJH@T``$((0/_P``_PPD@(\D```"RB!"``ST#WB"X`'8 +MP'@3>,&X@"`(""H@``#@?N!X\<`$D$*X(B"`#PC`2)P`V`AQ(B"`#PC`&$O1 +MP.!^X'CQP"(@@`\(P(0,"'7/<(C`U!`,B..X*'8*\L]PJ/X```'9J7(B((`/ +M",!P6<]PB,!4`/`@00-@>/'`X<6AP8MQ`-@B((`/","` +M5P#!"'6"X`!X(B"`#PC`4'>AP"`@@`\(P/P,\<#AQ3S8SW6@P``.$!T@ +M$,]QB,"\$@"!`!T@$`&!`!T@$$38$!T@$`*!W;@`'2`02-@0'2`0`X'=N``= +M(!`B((`/",`$(Q38$!T@$`+8(B"`#PC`X","V"(@@`\(P%`C(B"`#PC`&",! +MV"`@@`\(P/P,X'BJ(($,@.`*\JLFP7(```$`JB`!`NBX_O7@?N!X\<`B((`/ +M",!@3*H@`0+HN/WUT<#@?N!XJB*!#(#B#/(982#A1B'!!ZLA@0-&(,`'JR!! +M`^!^X'BJ)`$2@>//)*$1T"2B$:LD`1*K(0$'&F)&(,$'`O`@X3!RR?>K(8$" +MJB`!`NBX_O7W\>!^\<`B((`/",!\#`AU(B"`#PC`W$V`X`#8/O+/<$6`#.*V +M>."``-XD\,]Q1H!H)0AAC""#CS``!0``%P`8:B"``@0@@0____W_*2!``$HF +M`'`:<.EP(B"`#PC`P$XI(``$2B8`<`#8C+@?9QYFSW!%@`SBMG@!@!!V3??/ +M<0`!```")T`0++B,(`2`H`?%__[8T/$!V"`@@`\(P.0,\<`B((`/","`#`AU +M*'=(=@#9C+D`VB(@@`\(P-R!J7#I<0#:C+HB((`/",!86H#FP'C/(&('XB"" +M#PC`J%H@((`/",#L#.!X\<`B((`/","$#`AV`-T#\`'EA.52]Q1NSW%%@!SB +MM7@`88P@PX\*\B(@@`\(P+1,@.#P]0#8`_`!V"`@@`\(P/0,X'C/<$6`V+(" +M@(#@X'_*(&(`SW$``0``SW```0``$'$&\JLF4'(`@```X'[@>/'`(B"`#PC` +MW$V`X.(@@@\(P%2!T<#@?O'`(B"`#PC`W$V`X!#RSW!&@`!X(B"`#PC`T'\B +M((`/",#,]P1H!H)?[90FD@((`/ +M",`$=^!X@>)LVLHBH@T$((`/_W\`\(4@#``$(8$/__\`\("Y17FK(%`!JR&0 +M`:LF$'(```0`JB#0`?^X#/*K)A!R```#`*H@T`&K)A!R```!`.!^X'@(<00@ +M@`__?P#PJR!0`:LF$'(```0`JB#0`?^X"O+@N!7RSW`0`#0"(""`#PC`?!"K +M)E!Q`````*LFD'$`````JR80<@```0#@?N!^\<#AQ4AU`-J,NEMB(B"`#PC` +M\%J`Y`20`^!&(,$`(KG/ +M<(C`U!`@((`/",!DF_'`(B"`#PC`6`R")`0RSW5&@`!]`!4`&,]Q0(```"5X +MSW&(P.@1`*$$%0`8SW9$@```++C/<8C`[!$`H<]Q``$``,]PH,```!`88``* +M)8`O18#8LJIP)-DB((`/",!DF\]Q``$``,]P``$``!!QRB"!#Q``2`+B(($/ +M",!P$`05`2!*(@`@0B$``T#`#R(2(``5@"``VD'`0B&``P\B`@!-(8"##MC* +M($8`RB"%,,H@9C``WP\G#Q!"(!D#SW!&@`!X(B"`#PC`T'_I<"(@@`\(P,1_ +M(B"`#PC`P'\B((`/",#', +M(>*,P"4A$Q'RHN'_W,PA`H,%]%8F#10)\,]P$`!#`B(@@`\(P'P0`-W)<`#9 +MCKD`VB(@@`\(P-R!R7`,%0$@BB(-#B(@@`\(P%A:R7#)<8HB#0X`VR(@@`\( +MP(!,`-B=N"(@@`\(P*A:R7&`(08!J7`B((`/",!TBX+!`=@B((`/",#`BR(@ +M@`\(P.R-R7`B((`/",!0B\EP(B"`#PC`7(L)\,]P$`!!`B(@@`\(P'`0!!<` +M*)VX!!\@(`@5`""`X/0`+@``W14E5B,0%@$@@.%L\F&X$'4-]`#?C+_I<"(@ +M@`\(P,1_`ER`-LB((`/ +M","`3`#8G;@B((`/","H6JEPR7$*/'`(B"`#PC`?`S$D`AWHVY&)*(`\/!*<'\*EQ(B"`#PC`9)O$I\]UB,#4$`2-X+@)\L]P +MJ/ZX"P#9(B"`#PC`<%D$C>"X"_+/<*C^R`L!V"X#/)B +MA\]PJ/[<"P+9R7(B((`/",!P6:'`(""`#PC`Y`S@>/'`X<4(=2(@@`\(P&!D +M!:4$V`2E(""`#PC`_`SQP.'%"'4B((`/",#@9P6E!-@$I2`@@`\(P/P,\<`B +M((`/","$#`AVSW5%@("[J7!1V2(@@`\(P&2;J7`B((`/",!`906F!-@$IB`@ +M@`\(P/0,X'CQP"(@@`\(P(0,"';/=46`@+NI/'`(B"`#PC`A`P(=L]U18"`NZEPBB'%`2(@ +M@`\(P&2;J7`B((`/","08@6F!-@$IB`@@`\(P/0,\<#AQ0AU(B"`#PC`U&(% +MI038!*4@((`/",#\#/'`X<6AP0AUBW`!V2(@@`\(P&2;`,!`)0(5!-D`HB&B +M`,.#XP#8!/(!H@3P`J(H<`C@!*4!@H#@!/*,(`^-BO<`P<]P$``P`2(@@`\( +MP'P0H<`@((`/",#\#.!XX'[@>/'`(B"`#PC`=`P(=\]Q1H#<.!IQI&E`(`X% +M"!`2`4`@$0:,(@BCRB"-#Q````;B((T/",!P$$`BP"!&(,$`(KD*<"(@@`\( +MP&2;`8V7X,P@HH8%]`+8`*8W\`.-0K@(X%)P!?(#V`"F+_!`)0$2J7`B((`/ +M",#T*-=P````@`7R`=@`IB'P`-@`I@`0`""`X!OR`KA`(0$B".`$IRIP(B"` +M#PC`O"@`$`(@`Q&!(#!R!/2,(4*`R?;/.!^X'CQP.'%))#/<(C`V!5`@`&`^!R(L$'`BW4BN:EP(B"` +M#PC`9)NI<"(@@`]%@!"6HL`@((`/",#\#/'`X<6VP8MUJ7#/<8C`D!18VB(@ +M@`\(P"`.J7`6V2(@@`\(P&2;SW"(P,PVJ7$B((`/18`XI;;`(""`#PC`_`SQ +MP.'%SW5%@("[J7"*(88((B"`#PC`9)NI<"(@@`]%@""7(""`#PC`_`S@>/'` +MH\&+<`/9(B"`#PC`9)L`V$'``,'//'`(B"`#PC`A`Q:(``%`"".#T6` +M",($AB.&%2!!`*"1:B"``@0@@0____W_*2!``$HF`'`AA@+E8;DAIB.&0H:Y +M85!Q(Z8%]`#9(Z8BIBD@``!*)@!P(""`#PC`]`S@>/'`(B"`#PC`A`Q:(``% +M*'8`((T/18`(P@&%@.#*(($/$``%#^(@@0\(P'`01(4#A?`B`0#76"A)(5"A03A57D`&8`/ +MY>7EY2&%`>$AI2*%`>$BI2D@``!*)@!P(""`#PC`_`S@>/'`(B"`#PC`?`Q: +M(``%*'8`((T/18`(PFH@@`($(($/___]_RD@0`!*)@!P0(4BA1IP4''*((8/ +M$``##^(@A@\(P(@0)(4"A15YP*$!X`*E*2``!$HF`'`@((`/",#D#/'`(B"` +M#PC`?`Q:(``%*'8`((T/18`(PN.%:B"``@0@@0____W_*2!``$HF`'`BA1IP +M,'?*(LT#`O=`A=AA`N`0`"I:2%%7TI(``$2B8`<*EP(""`#PC`Y`S@>.!^X'CQP"(@@`\(P$0-(B"` +M#PC`A`RHP0AU3,$B((`/",#<;(#@2?(,PE,EP11`*@`&C<8E>$#``-F`XLHD +MC7#*(TT`Z"!M`@3F%23`,/P6#)`!XX&@SW2@P``@;!0#&!4D@#!AH`+B!2*" +M#\#N@##/$$&R`` +M#,`P<#CWBW6I<2(@@`\(P-1T#,"I<2(@@`\(P,!TJ,`DW"`@@`\(P/8,X'C@ +M?N!X\<`,V<]PH,``#A`88`!H$`$(@.'`>.(@@@\(P+RET<#@?N!XX<7AQ@#= +MSW.@P`!^0!M@`T`I#@//=*#``'A4'+@30"D$`@0D@0\`\```17E5''@0!^X'CQP"(@@`\(P(0,"'7/=J#` +M`#@4%@`8JWC]\V#89-DB((`/","\I106`!BK>,H@@0\0`"("XB"!#PC`'&`-[/=:#``'P@':`3"-PP'2`3SW2@P(![:!R@$RP= +MH!`$N9^[8!Q@$&0#G_W<*%(`@\'_Q<#3V(X6`X03R +M_]C980"I)(6`X03R_]C980"I`>8)%(`@SW[1<+H'R?],(P"@`-_2]FIVSWX6 +M(<(C((JI<$&2Z7,B((`/","$+@'G8;Z`YN]_,_=,)0"@"O+/<0C`Y%RI<`#: +M(B"`#PC`=%\@((`/","\#/'`(B"`#PC`A`P(=<]PB,#4$`>(X[A`A2AV$?(! +M%H00SW"H_C`-`A8%$079'!4&$&".(B"`#PC`<%D`APMQ&W!(Z`X!P?`!0C\L]PB,#4$`>(X[@+ +M\L]PJ/X,#0+90(>I2(@@`\(P'P0 +M#"(`I0#=!?*AAQ8EC11%AX#B"(X4\F#`@.4"'$0T!/(!C0/P_]B`Y0$<`C`# +M\@&%`O``V$'`BW%@>NEP"(Z2<`[T((<(N!"Y!7G/`X0;R,B%!!9)Q!/0`V@7P +M`8$&`@.+*(0($RB!"!.(@@@#_V`BN086`XLHA`@3*($($XB""`$PB`*`B +M\@&-28X(KJ&-L7+*(4P#RB",#Q``[P[B((P/","($`.'@.`$\JE@DG$$]`#: +M!?`!AS9X08"`XLHA`@3*($($XB""``6.@.!+]00>PA2BP"`@@`\(P+P,\<`B +M((`/","`#`HE`)`H=TAVRB"!#Q``YP[B(($/",!P$.6EQJ4@((`/",#L#.!X +M\<`B((`/","`#`AU(B"`#PC`M!3/=D6`(.77<```__]`)L\3$O):(`$+!XTJ +M9Q!RC``,`$`F`!(X8*EQ+-HB((`/",`H?CSPSW!&@-@X`(`AAA!QU?`!I@&&9-P=(`$#SW!%@.CR`("=(`$$$''*("T` +MXB"-#PC`T&`@((`/",#L#`#;SW)%@"#E8:+//'`@.#*(&(`XB""#PC`TP.!^\<`B((`/","$#`AVSW5% +M@"#E`*4B((`/",#<;(#@"O3/<:#``#0`$0`(D+@`&2``(86*(-L/72$!"P'; +MJ7(TX2(@@`\(P"QM@.`,],]Q18"DQP"!@>;/("$!SR!B`0"AJ7#/<0``R`TB +M((`/",!`?@#9(:7/<$:`[#H@H,]P1H#8.""@(""`#PC`]`SQP"(@@`\(P(0, +M*'9(=0#8"'$B((`/",!,D`#8(B"`#PC`?(G)<"(@@`\(P+Q@(B"`#PC`:&.` +MX,H@0@/B(((/",#88R(@@`\(P-!F@.#*($(#XB""#PC`/&?/<*#``!TX&*`/ +M"````"`@@`\(P/0,\<`B((`/","`#"AV2'7/=T:`'`8$;PC:(B"`#PC`*'ZC +MI\]P",`\%0#9(B"`#PC`3)#/<*#``!TT&*`/"````(+E"?0`V"(@@`\(P+20 +M`=@'\`'8(B"`#PC`M)``V"(@@`\(P'R)(B"`#PC`E&`B((`/",!H8X#@RB"" +M`^(@@@\(P'1C(B"`#PC`T&:`X,H@@@/B(((/",#<9B`@@`\(P.P,X'@!V\]R +M1H``#9SW!&@!P&X'\@J/'`X<68<,]P1H"4!1"`@.`" +MV!;TB'`B((`/","<((AP(B"`#PC`?!V`X`KTB'``W:EQ(B"`#PC`V!JI<"`@ +M@`\(P/P,\<#AQ<]P1H"4!1"`@.`$V`CR`-VI<"(@@`\(P'`,]P18"DX@"`X'[@>/'`(B"`#PC`@`P(=P#> +M(?!:)@$=SW)&@%(R`"&-#T:`;#(/C8P@@X\2]"AB(B"`#PC`N)X(<>EP(B"` +M#PC`H*2`X`;R#HT!X`]X#JT!YL]P1H#P.@"`$':X!\7_(""`#PC`[`SQP"(@ +M@`\(P(0,@.``W#GRB76)4`V!"O`>;/<$:`\#H`@!!VN@?%_P08 +M0",B((`/",#<;(#@"O3/<:#``#0`$0`(D+@`&2``BB";#XHA%@(*<@';(B"` +M#PC`+&V`X`WTSW)%@*3'(((,(8"DSR%A`,\AH@`@HB`@@`\(P-0,X'CQP"(@ +M@`\(P(0,H\'/$!V"SR`-W/<4:`\#H`H@&.H*&@X$0`*0#* +M(.D`@.#8]EHE@1(,VHMPV6$$X2(@@`\(P"`.`,`!P0+"(B"`#PC`_&(!Y0&. +ML'T0=:SV(([/<$:`S#@@H`#8H\`@((`/",#T#.!X\<`B((`/",!\#!IP`-T# +M\`'ESW!&@/`Z`(`0=6``!@!:)0X=SW=&@$PR"G`&VMEG(B"`#PC`('Z`X.SU +M`":!'T:`;#(/B8P@PX\'$((@$_0-B5!PU/;^V`^I`=@0J0#8#JG89PIQ+-HB +M((`/",`H?@;P#(D0`&VB(@@`\(P"A^ +M`(8U:`#:/65,K4VM#A2!,$*E+ZU0K0'@`*80W"`@@`\(P/8,SW!%@*CB`(#@ +M?N!X\<`B((`/","`#`AW`-X>\+5N`-C'=46`X.,-K0ZM#XTB((`/","XG@AQ +MZ7`B((`/","@I(#@"/(,C8P@PX]$]@'@#*T!YL]^SW!&@/0Z`(`0=L`'Q?\@ +M((`/",#L#.!X\<"`X`#9*?(H$O>0'C;WO/<$:`]#H`@!!SIO?/<$:`Z#H`@!!QXB"& +M#PC`[&?1P.!^X'CAQ>'&F'#/<$:`^#I@@,]R18#@XT(C38#*)$ESX'CH(*D" +M0"Q.`5QEW&36C&&]UZQ`+$`!6&`WJ#"(,'/#]P'A,*C!QL'%X'X`V,]Q18"H +MXN!_`*'QP"(@@`\(P(`,`-[/<$:`]#H`@,]U18`8`A<]^$':L]R(@@`\(P-QL@.`) +M],]QH,``-``1``B0N``9(``@A8H@6P\$N:ER!.$!VR(@@`\(P"QM@.`)],]Q +M18"DQP"!@[@`H0;P`-G/<$6`J.(@H"`@@`\(P.P,\<`B((`/","$#*/!SW)% +M@*CB((((=H'A`=@W\@#=`*)#CL]Q1H#T.HCBH*$-]B&.SW!&@-`X(*`@CL]P +M1H#X.HCA(*##]@/8'_`BCL]P1H#H.H#B(*#8]EHE@1(,VHMPV6$$X2(@@`\( +MP"`.`,`!P0+"(B"`#PC`<&8!Y0..KWT0=:SV`-BCP"`@@`\(P/0,\<`B((`/ +M","`#`AV`-\$\`'G[W_/<$:`]#H`@!!W?@`&`+5OR7#'=46`X.-`)4$4!MHB +M((`/",`@?H#@ZO4.C8'@)XX']!>-,'!2``P`-ZT&\.EP(B"`#PC`F&*X"?+_V"(@@`\(P'1D`(6B +MN`"EY+@)\@'8(B"`#PC`T&``A:2X`*7EN`GR`-@B((`/",#08`"%I;@`I2`@ +M@`\(P/P,X'@@((`/",#PDB*`0"`"`R!Y2'#@>/'`(B"`#PC`@`P(==&(\(B1 +MYLHBA@/*(<8#RB`F#N(@A@\(P(@0SW!%@,CASW%%@&RSR6'P((`#,'>(]\]Q +M",!H$B*E`=@&\/9X((`BI0&``:7/<`C`:!(P<`'8PB`!``"E(""`#PC`[`S@ +M>/'`(B"`#PC`A`S/=D:`+`8-R,EU#AH8,`?:#1J8,,]QH,``"!`1``@.$0&. +M$'@P<#?WSW&@P``%/!F@``#8!J4'I06E#!$`"`.E4!$`"`2EJ7`B((`/",!, +M:L]PB,#4$`J(X[@`%000"_)#A<]PJ/YL"V2%`]DB((`/",!P60"%@.`D\@.& +M(B"`#PC`P)`1C4`E#A,*(0"`R7#*(6(``N$B((`/",!DFP&%@>`(]`.%)(4B +M((`/",!<;AKPR7`B((`/",!H=@SPJ7`B((`/",!`:JEP(B"`#PC`Y"#/<:#` +M`#@`$0`(I[@`&2``(""`#PC`]`SQP"(@@`\(P'P,`-_/=46`!/1`)004"B6` +M#Z#``!#I=@;P(B"`#PC``"(!Y@&%((40<17R\"1``,ZX(K@!X/)HC14!C@2X +M,'#M]\]PH,"`#6<=N(\``/__!/#/<*#`@`T:<`#8$1H8,)05`(X!V9^X$!@@ +M(`088"#/<*#``#@8&*`/`!````&%((40<1/RZ7`B((`/",#,BH#F!O("A8P@ +M$(")]\]P$``@`2(@@`\(P'`0'!B@+P````@@((`/",#D#.!X\<`B((`/","4 +MG(#8SW&@P``X$!D@```1``B'N``9(`#1P.!^SW!&@"P&!(#@?N!X\<`/&I@_ +M`,```,]P1H`L!A`8@`\``/__(B"`#PC`["'/<*#`@`X($``($!H8,"(@@`\( +MP'"`H=0/T`-@&H:EP +M(B"`#PC`Y"`$A4`E`A@GA0/;(B"`#PC`+&TB((`/",!P;"`@@`\(P/P,X'CQ +MP"(@@`\(P'`,H<%Z<#IR:'4+X48AT`!"(`XAX+N@W\`O(A;*)R$0:B"``@0@ +M@0____W_*2!``$HF`'!:<```$P#!*G(B((`/",!,(0AU(?``W1_P!2>`$P#!*G(B((`/",#XB@#8 +M$1H8,,]QH,``$)01`(X!W9^X9!DX@&$9>(//<*#``#@8&*`/`!```&\C/P`I +M((`$2B8`<*EPH<`@((`/",#,#.!XSW&(P`@1X'\`H>!X\<#AQ<]S1H`L!D.# +M4'!H=03T!(,0<0GRSW`0```/(B"`#PC`(!B7A@$')(]P"*QKB"X/GU`=@#\`#8X'Y4>.'%H8C_W)%U`-L)]`"(D7`' +M]`")$'+*(,(``O0!V,'%X'[QP"(@@`\(P'`N%(#1P.!^\<`B((`/","$#`W( +MLL$.&A@P"-H-&I@PSW:@P``($!8`&`X6`9X0>#!P._?/=:#```4\':`0BW`" +MV2(@@`\(P&2;!!0!,3@5`!@0<3WW(KF"P"(@@`\(P&2;#A("-@W(#1J8,`X: +M&#`0%@`8#A8!GA!X,'`Z]SP=H!"RP"`@@`\(P/0,\(@@0\( +MP'`0(B"`#PC`E&P0=^(@@0\(P'!L@.8+\E$@0*?*(($/$`#_#N(@@0\(P'`0 +MJ7#I<#8\AOVA.#@`0$`#/:!X.`!`@`B((`/","X2]4! +M(``(=IS@S`$"`(MR"G"I<2(@@`\(P'"82O#CX)GR&?;1X%+25X0,"(\(P@0X=-\HP@PXF"],]PB,#,-B(@@`\(P+1O@.!X +M\FO8+_#7<````?MR\CP`"0",(,>$5?*,($>+:O3/<(C`U!`1B..X"?+/<*C^ +M7`P`V2(@@`\(P'!9`=@B((`/",!0;@#>5O#7<```__M2\M=P``#__D[T(B"` +M#PC`\(D%\"(@@`\(P,2)"'8A\,EP^?&+<@IPJ7$B((`/",`DBCCPSW"(P+@2 +M`(CCN#+R?O'/<(C`N!(`B."XT2#A@"KR!""`+P``_/]DN"*XV_$!V$#`(/`B +M((`/",`T6AKPSW"(P-00$8CCN`GRSW"H_AP,`-DB((`/",!P60#8(B"`#PC` +M4&X`WN7Q(B"`#PC`5'F`YLHA0@/*(`($XB""#PC`>'8`P*'`"-P@((`/",#F +M#/'`(B"`#PC`<`RBP7IP&G%:)"+<`+9(B"`#PC`=)Q"*($@2G`B((`/",!TG`X2 +M`C8-R`T:F#`.&A@P$!4`&`X5`9X0>#!P._=/';B0*2!`!$HF`'"BP"`@@`\( +MP,P,X'@H<$AQ:'(@((`/",`H<^!X`-@@((`/",`@5^!X"'$`V"`@@`\(P(!7 +M!X#_V@]Y!""`#P```/\HN(#ARB&!`(#@RB"!`!!QX'_*($4`SW"@P``=,!`` +M".!^"',!W``L`!#QP"(@@`\(P"`D"?``V`\@P``B((`/",!`)(#@^//1P.!^ +MX'@`V0\A`0#/<*#`@!XX&&``X'[@>*/!SW6(P`PVBW;/=XC`D!&I<,EQBB+_ +M#R(@@`\(P'!&`!0`,8+@RB"*#Q``]0[B((H/",!P$``4`#$"P?`G`A!@>@'` +MYO'@>`*X*')`(`$"]]@"VR`@@`\(P"QM\<`B((`/","$#$)HSW.(P+00`X,H +M=5A@C"#/C^(@A@\(P$1U`X,`V5A@`Z,!@X#BRB2-<.!XZ"!M`\]RB,!T`!5Z +M\"5,$`'@@*(!HP'A)(,(=(8DSY\!X22C!?(E@P'A):/)N`&C(""`#PC`]`S@ +M>`#8SW&(P+00!*$#H0&!X'\"H>!X\<`B((`/",!L#*+!"'::<7IR6G,*(0`A +M"B!`(/'`(B"`#PC`E#,B((`/",`8?N!XX'AI($``T<#@?N!X"',H<@?8:'$@ +M((`/",#D)@AS*'("V&AQ(""`#PC`Y"8@@$&``=@@((`/",#D)N!XH<'QP"AR +M"'$#V"(@@`\(P.0FT<#@?Z'``-D@((`/",!(=N!X"=@`V2AR(""`#PC`Y";@ +M>`;8`-DH8#@RB!B`!-X$'@!X"\F!_!"P)GT(B"` +M#PC`D)(!P1!QV``N`$#`@.`C\B(@@`\(P*AY@.``V<\A8@3*(:$``L`E>"\F +M!_!"P`_RBW*QV!#9`=LB((`/",`L;2(@@`\(P`AZ??`B((`/",#0>0#89-DB +M((`/","\I2(@@`\(P.1Y!<`B((`/","`>8#@`-G/(:($RB$A`0+`)7@O)@?P +M0L`O]!+P!<'I<"(@@`\(P!1Z@.`1\@3!%7\8(0$`1,$%P15Y`L!%P03"@.(/ +M>=GV@.'K\Q7PSW"(P-00%(CAN`GRSW"H_JP*`-DB((`/",!P60+`@[@$\`+` +MA[A"P"\F!_`?]`'!"G`B((`/",!8>8#@`-C/("(%RB`A!`+!)7A"P"(@@`\( +MP)"2`<$P<`#9SR%A!FP6`!BB>$/`BW*QV!#9 +M`=LB((`/",`L;:;`(""`#PC`Y`SQP"(@@`\(P(0,"M@`V2(@@`\(P#B1SW:( +MP,01"'4`AA!U$O+/<(C`U!`4B.&X"_+/<*C^[`H!V:ER(B"`#PC`<%F@IB`@ +M@`\(P/0,X'\!V*'!\<"BP4/!SW&(P$@=((%!P$#!BW"#P2(@@`\(P/0HHL#1 +MP.!_H<"AP?'`HL'/<8C`Q!P@@4/`0,%!P(MP@\$B((`/",#T**+`T<#@?Z'` +M\<#/<(C`F!4@@`&`]!Q(L$'``-A"P(MP@L$B((`/",#T**/`T<#@?@+8SW&B +MP`!L,!D@``'8-!D@`.!^`=C/<:+``&PP&2```]@T&2``X'X%V0RY"]@@((`/ +M",#,D.!X"]@@((`/",`$D>!X\<`B((`/","`#*+!"'7_V!!URB!%`T'&#WT#'`(P@>4`W@3VR74-\(MPZ7$B((`/ +M",#T*-=P````@&&]]/6I<*+`(""`#PC`[`S@>/'`(B"`#PC`:`R")`DS"'4: +M<3IR:'8*)``ABW?I<,]QB,`H'2#:(B"`#PC`(`X`V$C`0"03.6IPSW&(P(`= +MBB*'#R(@@`\(P"`."B(`)X`B""!`(@`ISW&(P(0?*-HB((`/",`@#H#ES"`B +MH&?R3"``J,H`!0``E88@_`#0X(#EPW=D! +MVB(@@`\(P/A)Z7#`V0':(B"`#PC`^$F(P)AP$MD!VB(@@`\(P/A)B'`3V0': +M(B"`#PC`^$E`)0`90B`!*>ERB',*),`$0"(%*0HF``4B((`/",`,'H#@#_(( +M'D`4HZ86$0`AR7$'KHIP(B"`#PC`%!2`X`/T`-@/\$`E@1+)<`;:(B"`#PC` +M*'Z*<"(@@`\(P#R"JG"`)`DS(""`#PC`O`S@>/'`X<7/<(C`U!`(B..X*'4) +M\L]PJ/Z<#`#9(B"`#PC`<%F`Y.@@;0+@>.!XX'C@>.!XX'@@((`/ +M",#\#.!X\<#AQ<]PB,#`'`"`IL%!P`#81<#/=8C`U!`/C>.X"_+/<*C^P`.X`1E"`0ORSW"H_F`(!-D) +MVBAS(B"`#PC`<%G1P.!^X'CQP`O8SW&(P,@1!*D`V`6ISW"(P-00#XCCN`KR +MSW"H_N0(`-DB((`/",!P6='`X'[QP`ARSW"(P-00+XC/<(C`R!%DB..Y!1"$ +M``KRSW"H_IP)`]DB((`/",!P6='`X'X7V,]QH,``$+D9.(`'V&49.(#/<*#` +M`#@H&*`/````S*LF"'`````!:2```>!^X'C/`X.!_RB!B`/'`(B"`#PC`<$@B((`/",!(?M'`X'[@ +M>/'`X<49)TA#PH`VO'`++DB((`/","02"(@@`\(P$A^T<#@?N!X!-@@((`/",!T +M*^!X\<`B((`/","4?P'9SW"@P`!(`!A@`-'`X'[@>,]RH,``2`@:(``$&F`` +MX'[QP"(@@`\(P)1_`MG/<*#``$@`&&``T<#@?N!XX'[@>,]QH,``2`P9(`#@ +M?L]QH,``2"P9(`#@?O'`X<7/,]R +M18#8LB&"$.)LN0$H3``3($``$"!#`/`B``/@?WA@_;C@(((/","L*_ZXX""" +M#PC`+"W@?N!XSW&@P`!0*!D@`.!^SW"(P(`2`(#/<8C`A!*>N)^X`!``"""! +M.7C@?Q!XX'CAQ>'&SW"(P#`5((`!@/@<2+!!P,]PB,#L$<"``-K)<`_,]QB,"` +M$@"A4B8`$,"X!+C/<8C`A!(`H:+`P<;!Q>!^X'A*)`!X`-FH($`$SW"@``!2 +M-7B>N)^X`!`"",]P1H!T)C5X0*`!X>!^X<4`V,]R1H!H)B1J2B0`>$`B#0.H +M($`#SW.@``!2%7OP)0P0GKN?NP`;(`,!X$HD@'``V*@@0`//_`A +M#`">NY^[`!L@`P'@((+/<*#``%``&&``P<7@?N!X*'//<4"````B>$$H`0-X +M8,=P``#_#RRX,'!"`"4`X<4B>$`@?`#@>*@@0`9!*4T!4R$``0#/'`(B"`#PC`?`P:<"AW2'7!B2(@@`\(P)!O@.#*(4(# +MRB""#Q``T!#B(((/",!\$!0@0".AK\&H_]DP=B"H!O(4((`CH*@#\*"O(""` +M#PC`Y`S@>/'`(B"`#PC`?`P:<"AW2'7`B2(@@`\(P)!O@.#*(4(#RB""#Q`` +MT1#B(((/",!\$!0@0".@K\"H_]DP=B&H!O(4((`CH:@#\*&O(""`#PC`Y`S@ +M>,]PH,``-``0``@`V<*X#R$!`,]PB,``$>!_(*#QP"(@@`\(P&P,"B<`D)IQ +M.G(:]"!. +M`ZEP(B"`#PC`R*0!V8[@PB%-``':@.'`>N"^&/),(P"@S"$B@`?T3"(`H,PB +M(H`.\DPA`*#1)B*1!_1,(`"@!O+DO@3T$'A@?XIQ`>6TY:@'Q?\@((`/",#$ +M#/'`(B"`#PC`<`RBP0AU&G&TX,HA30/*((T/$``2#^(@C0\(P'P0"B&`+T6` +MB-XJ<&C9(B"`#PC`0'Z+=^EP"-DB((`/",!`?H#E1``N``#>6G45((TC`)4" +M%1,1(B"`#PC`N)X(<10A3"`!E5$C`*``M,HB8@#*(,(#XB""#PC`E*5"(DT@ +M@.4!YB3WZ7`!V2(@@`\(P-R/HL`@((`/",#,#.!X\<`B((`/",!X#`AU*'=( +M=@`1D`#_V`$1D0`2<,P@0H0(\JEP(B"`#PC`D&^`X`KTSW`0`-(0R7$B((`/ +M",!\$!0E@!,R=F&(`_1AKP7P0(@4)8$08:D2=D"(!/1`KP7P(8@T?4"M_]DA +MJ""H(""`#PC`W`SAQ0#=_]N`XLHDC7#@>.@@+0(4($(#8*IAJ@'E8*EAJ<'% +MX'X!V,]QHL``2P@9(```V`@9(`#@?O'`(B"`#PC`>`R")`([@<`:<,]QB,#H +M%$C:(B"`#PC`(`Z4Q:EPSW&(P.`5$-HB((`/",`@#E8D$3//<8C`T!PJ<$S: +M(B"`#PC`(`Z+=LEP(B"`#PC`_',`P@AQ`KH*<"(@@`\(P"A^(B"`#PC`\'/) +M<"(@@`\(P/QS,<$(=I#A!.!2]`<4@3"!X1KT@<(@EJES"B1`!"(@@`\(P'AZ +M"'8B((`/",#P*'!X<7AQJ'!0\$!V2"BSW2@P``.:!0!&&@4`1C/*"ZO4`V1`<8!`@ +MH@38$!P@$!'88\`#P``<(!`(V!`<(!#YV``<(!`0'&`0`-BAP,'&P<7@?Z'` +MH<'QP"(@@`\(P&0,]!Q(L+IP2'<$((`/``#\_T(@$`$`PD$H@""J<2(@@`\( +MP$B=SW)&@!PE0!*!`%8B%`+#BD$2C0`*(H`OH,``#F@2`"A*(P`B:!(6*!`: +MX"20X4HA`"`J](PFPY_*(8$#RB"!#Q``#`_B(($/",!\$,]U18"PLM5]`(6` +MX,HA@0/*(($/$``-#^(@@0\(P'P0`-@`IX"%JG``P*+!0<(!V`"C!!0`,0#9AB#\`(P@`H!0W,P@`H/0W,P@`H/*($(``_0!V.!_ +MHL#@>,]PB,"X$@"(X+BAP03R`=@`H@/P`-C@?Z'`X'BBP?'`X<5#PFAU(B"` +M#PC`F)``I0P4`#$`V88@_`",(`*`4-S,(`*#RB!"``+T`=@,W"`@@`\(P/X, +MX'C/<4:`9"7@?P"AX'BAP?'`SW.(P+@28(O@NP?R(B"`#PC`)(D%\"(@@`\( +MP`B'T<#@?Z'`HL'QP&AR(B"`#PC`B(G1P.!_HL#QP.'%"'4B((`/",#@(ZEP +M(B"`#PC`4",B((`/",`8(P'8(""`#PC`_`S@>/'`X<7/<*#```YH$`T(J7`B +M((`/",#@(ZEP(B"`#PC`4",B((`/",`8(P'8(""`#PC`_`RAP?'`(B"`#PC` +M@`Q(=@0@@`\``/S_9+A!*(&`SW5&@!PEJ7<`V,HD0G#@>.@@X@+/<:#```YH +M$0$(%24,$""D`>!`%X`0D.`/]"./C"'#C\H@@0\0`!@/XB"!#PC`?!`#CX'@ +M`_(!V`7P(B"`#PC`F)"`X`"F%/1`Y<]P1H!D)0"`0(5!'P(02-C/<:#```X0 +M&2```(4`&2``0*4(W"`@@`\(P.X,X'@!V1"X$1I8,(&XSW&@P(`-!!D@`.!^ +MX'C/<*#`@`T8$``(!""`#P`0!P#@?N'%X<93((,#(KO/=*#``!"P'#B0SW2@ +MP``.@>/0]P0<8!``V03P!!Q@$P'ARFO1!^X'B`V2`@@`\(P(2.X'@(/'`(B"`#PC`A`S/=:#``"!L%0,8QW,!`*"&;!4` +M&`#><'#*)F\0(B"`#PC`B"V`X,PF(9#S\X#@RB"!#P``!P/B(($/",!P$"`@ +M@`\(P/0,BB0!<`#:J""``\]QH@``255Y\""#`)ZYG[D`&>```>+@?N!XBB0! +M<`#:J""``\]QH@``2%5Y\""#`)ZYG[D`&>```>+@?N!X\<`B((`/","$#(#8 +MM!P(L,]VB,",$@"&(KC#N([@1?=.(`T$`_!.(`T(*VT"N8'`(B"`#PC`-"<@ +MAL]S_P#_`$$I0`=`*(MR@B((`+5Z?AH8`!-I02@,!ANY +MQ7PHN(1[)7@$((`/`/\`_V5X?QH8`(MVR7!,V2(@@`\(P$A,,FW)<"(@@`\( +MP(2.L\`@((`/",#T#/'``M@B((`/",`X="(@@`\(P!B.T<#@?L]QH@!`4!5Y +M3R&`!Y^X`!``".!^`=G/<*+``%!L&&``9!A@``#9SW"(P(P2X'\@H/'`SW.@ +MP``@;!,!",=Q```P=6P3``@`VC!PSW"BP`!08!``",HB;P#!N(+@`=S`?(+@ +M!/*`XN_S@.3*(($/```,`^(@@0\(P'`0T<#@?N!X\<`B((`/",!P#`AV"B*` +M+Z+``%!H$@TH"B&`+Z#``"!L$0`H02F/```@DP\``#!U&G$X\`06`11")T^0 +M0"D``D$I`@8%>D$I``(8N00B@@__`/\`)7@$((`/`/\`_P5ZSW"B``!0M7B> +MN)^X`!B@``'E!?*0Y<`'Q?]3)(B"`#PC`3(TB((`/",`TC@#=$?"I<"(@ +M@`\(P`2.@.<$\A4G3!,`I/`@02,!Y3!PP'Z(Y;#W`M@B((`/",!D=,EP(""` +M#PC`Y`S@>/'`(B"`#PC`<"YS@(#C!?0(V-'`X'YR@(#C!_)@@8#CRB!A`O?S +M&.`B((`/",!(HO'QX'CQP"(@@`\(P'P,&G`*)T"0SW!&@/0F"'4$]!6`@.`3 +M]$`E#A8"V,EQR7(B((`/",!$G@'8R7$*]:4@((`/",#D#.!X +M\<"8<"APSW%%@`#?8(&`XP?RSW)%@&BS0()@>XAQT<#@?N!X\<`B((`/","` +M#`HF`)`H=\]U18``WR"%!_2`X0[TSW`0`+`0!O"`X0CRSW`0`+$0(B"`#PC` +M?!#`I<]P18!HL^"@(""`#PC`[`S@>/'`(B"`#PC`W&R`X`'8!O+/<(C`D!(` +M@-'`X'[/<8C`D!+@?P"AX'C/<:#`@"Q`&2``X'[QP.'%SW.@P``@;!,"")AP +M.F)L$P`(`-U0<,HE;Q"(<"(@@`\(P!B1@.#,)2&0\_,@((`/",#\#`#9#R$! +M`,]PHL``"`088`#@?N!X`-D/(0$`SW"BP``(`!A@```0``@D>$(@`(#@?\H@ +M8@#QP"(@@`\(P(0,*';/=46`L-L6?0*Y0850</P``U7B>N)^X`!``""`@@`\(P/0,X'CQP"(@@`\(P'P,"'?/<$6` +ML-OV>!ISH(!(=@(EC1]>/P``4FDU?7EA88`"N7!QRB&-`,HB#03*((T/```J +M,^(@C0\(P)@04R9^D,HBP@/*(8(#RB""#P``+#/B(((/","($$P@`*#*)`)T +MX'CH(*("3R6`%Y^X`!``"`3E!!X0$"`@@`\(P.0,\<`B((`/",!\#`AWSW!% +M@+#;]G@:)ZXG[@`&&``X'[/<8C`)"#P(0$`SW"B`(`H-7B> +MN)^X`!``".!^SW*(P"0@\"("`,]PH@``*%5XGKB?N``88`#@?B`@@`\(P(`B +M\<#AQ<]PHL``"`P0`0CDN=$A(8,0\L]UB,#<-0:%@.#*(($/```N,^(@@0\( +MP'P0!H5`>"`@@`\(P/P,0(`XND"I0(`PND&I0(`HND*I`(#@?P.I\<#/<(C` +MU!`(B..X"?+/<*C^H`\`V2(@@`\(P'!9:2!``.!XT<#@?B`@@`\(P.@S\<#/ +M<(C`U!`)B..XH<$*\L]PJ/X4$`#9(B"`#PC`<%EI(```BW`B((`/",`\,H#@ +M$O(`P"(@@`\(P#`SSW"@P``=.!B@#P0````B((`/","8#P;P:2"``6\A/P#/ +M<8C`F!$`@8+@$O0!V`"A(B"`#PC`P#(B((`/",`0EB(@@`\(P"B6:2"``<]P +MB,#4$`F(X[@*\L]PJ/XT$`#9(B"`#PC`<%G/<*#``!TT&*`/!````*'`T<#@ +M?O'`X<4(=2(@@`]%@!"E!J6I<"(@@`]%@&2J":6I<"(@@`]%@+2<"*6I<"(@ +M@`]%@"RA"Z4`V`ZE(""`#PC`_`SQP.'%"'4&\"(@@`\(P'"5J7`B((`/",`$ +MEH#@]O4@((`/",#\#.!X\<#AQ0AU(B"`#PC`!)9"A<#9&+F`X"5Z#_*"@``2 +M``AFA69X985E>``:(``#A25X`!@@`P?P`!(`"":%)'@`&B``(""`#PC`_`S@ +M>"(@@`\(P`AY(B"`#PC`1)8B((`/",!\D_3QX'BCP0#8(B"`#PC`F$W/<0`! +M``#/<``!```0<>(@@0\(P*@FSW:(P$0VBW7/=XC`G!')<*EQBB+_#R(@@`\( +MP'!&`!0!,8KA"')#]H#B"/+/@'` +MY/'QP"(@@`\(P'P,"'4`@(#@,_)J((`"!""!#____?\I($``2B8``OR +M0X7/<,#N@E(!V2(@@`\(P,"<*2``!$HF`'`!V`+P`-@@((`/",#D#,]QH,`` +M.`@1``B3N`@9(`#@?N!X((`P<,HA(0#@?RAPSW"@P``@@!B@#P```!``&*`/ +M````0.!^\<`B((`/",!$EL]PH,``(`@8H`\@````T<#@?L]PH,"`(&`8H`\# +M`$`-X'Y`@`/P0()0<`7R9((K>_SS`O``VN!_2'#QP"(@@`\(P'P,"'#@.()\D*"0*`'@P.``*$!V`+P`-C@?N!XSW"(P)02(""`#PC` +M=)3@>/'`(B"`#PC`A`S/=J#``#@8%@T8\[T)\L]PB,"4$B(@@`\(P&R6!"6^ +MGP<``(#*(4(#RB""#Q``,P'B(((/",!\$!@>H!\/``"`(""`#PC`]`S@>,]P +MB,"4$B`@@`\(P&R6X'CQP*H@D`#AN`;R(B"`#PC``#0&\"(@@`\(P,PUT<#@ +M?JHAT`"J(A`!JB,0`,]P$``'`B`@@`\(P)@0X'C@?N!XX'[@>.!_`-BAP?'` +M(B"`#PC`?`RAP0AV1L`:%``Q!""!#P```(!/N8'A,O0B((`/",#8(EH@`0L( +M=<]P18`$W^1H<"="$$`@D`%0=LHA@@/*(((/$``'`^(@@@\(P(@0BW`B((`/ +M",#\+*($(`0/0B((`/",#8(EH@#PLZ<,]P18`(WW`G`A!`()(`4';*(8(#RB"" +M#Q``!@/B(((/","($`&'@.`$]`#8$O`$(X$O``#\_V2Y`H.@@+0//<:#```YH$0$(%24,$""D`>`%AV&' +M$(@@AV![J7+"\>!X\<`B((`/",#$,2(@@`\(P.PQ(B"`#PC`H&[/<(C`U!`* +MB..X"?+/<*C^[`\`V2(@@`\(P'!9T<#@?N!X\<#AQ8#@*'42\B(@@`\(P#!( +M"B$`@`"%`>``I(@@@\(P'P0(""`#PC`_`SQP"(@ +M@`\(P'P,"B4`D&+R:B"``@0@@0____W_*2!``$HF`'`:<`O(N&`+&A@P#,B` +MX`GR$'7"($4#RB!F``P:&#`&$@PV`-I(<0OPR7)@I`G(!.00=(3W"A(,-@'A +MH.$\``8``(2`X/3S`-O@@*#GQ_=.(0X(PG\!Y^"@`O`@H,"$!(#1\P6"Q*`%A@6BV_$*R`8:&#`,\`'8`*(`V`:B2'`B((`/","T1,ER +M@.((\@""Q((0=7+WHGCQ\2D@``1*)@!P(""`#PC`Y`SQP"(@@`\(P'P,&G"* +M)_\?:B"``@0@@0____W_*2!``$HF`'"8<`82#38`VPCP"<@$Y1!U@_<*$@TV +M`>.@XU?W0(6`XO7S2'$`@4XC#`@"(`X#H.#*((T#RB#.`"2!$'?*)P804''R +M]>/Q*2```4HF`'",)_^?!O(`&,`C`=@&\`#9`!A`("AP(""`#PC`Y`SQP"(@ +M@`\(P(`,@.$(=FCR0"'-`R2]P[F`X1#?RB="$`;P#-@B((`/",#\I<]QH,`` +M!3@1``A2;Q!R-?=AOX_GE``-`#,FSW.(P#P30"<`$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0 +M$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$`@1``@$'A`0"!$`"`0>$!`($0`( +M!!X0$`@1``@$'A`0"!$`"`0>$!`($0`(!!X0$$(E39`0WZKU(""`#PC`[`SQ +MP.'%@."APAP"`@@`\(P/P,X'[@>`#: +M@.'*)$UPX'CH(.T"\""#`,]QH,``!4`9X``!XN!^#<@'VPX:&#`-&M@PSW*@ +MP``($!(`"`X2`8X0>#!P./=/&OB``]A5&CB`X'[QP"(@@`\(P$0-0L'/<:#` +M@!P$&2```L//.@@[0$$ +MXOP2`(`$&2``T<#@?ZC`0('/.@@K0*0Y4;W:!$`"`'E!!H@`)#E2_=.)3P4X'BH(,`!!!J@ +M#U555540&>``P<7@?N!X:B*``N.Z!?*J(=`"`_"J(9`"SW`0``("(""`#PC` +MB!#AQ>'&`-K/4Z8L]Q1H#X.B"!,'6V +M]P6X'&1`I,'&P<7@?N'%X<:(=,&,I&RTYM9]2_8$K2"E1:UCM0&,`>`!K`'8 +M`O``V,'&P<7@?N!X\<`B((`/","`#`AS`-@(=`/PJ7`!Y(+D4@`&`(/C/``- +M`$`GCW8S)L-PB,!,$_`B#@-T?Q4A#0,`?P#;X(7D?@OP`=O@A>5^!_`"V^"% +MYWX#\`/;TG[`I8#@`-T%]/`A``.`X-?S`=C6\2`@@`\(P.P,X'CQP`HC`(#* +M(.$,$_*.XP3W26L%\$$K@@`%XDAP(B"`#PC`R*00<\H@@0#*(.(,T<#@?N!X +M\<`B((`/",!8#'IPO!Q(L`#=1,6%P$'`SW&(P/`5$-HB((`/",`@#HG`0L#/ +M<8C`'!T+VB(@@`\(P"`.C,":<,]QB,!T'0K:(B"`#PC`(`X$$P`@@.#V`@$` +M$!,`((#@Z@(!``#``,&@L$`C`")`(14$A,:J<+,)R&@RB?!(^CQ_^(G\HPB +MPH]`\HPB0X?@]>EPBB$(`*IRR7,B((`/",`82H#@U/,?`@```<"(($`!AA$,.]_@>=^`0D`SW&(P(`?(($#X$_!SW&(P*P?((&`YU#!`!,! +M($_!`\$$>0#`1,$5(-@#!!A$,`'9;,$/P`#:!O04$P,@@.,#\DAQ0"2%($`D +M1B!6)`=(]4PA`*!&\RIPBB$(`*IRR7,B((`/",`82H#@.O,#V`+P`-BQP"`@@`\( +MP)P,X'CQP"(@@`\(P'P,"'2"E`8;`N`.X)7@`I2.&@.$#\H*X`*4BAH#A!/*) +MN`"E(H:`X0OT0X:`XLH@@0\0`%`"XB"!#PC`B!`@AH#A!6T4]"6'P+E7:2"% +M17D@I0+9)*5`)P$;`]HB((`/",`H?@F'`J4*AP[P!MDDI4`G`1@#VB(@@`\( +MP"A^!H<"I0>'`Z4.AH#@`-@(\@#9J7"`(`\`-*@UJ`'8&G!`)@(8%(J`X-OV +MH.!9]@#86B"!**ES@",/`#MC%*L4BD`F`145JU2*0".`!2(@@`\(P"A^`"`` +M)$\@$``2CQ2M/H:`X0HF``<+\@'8R''/ER(B"`#PC`1)X5'4(1)_`($`$0,B%` +M`?AP(B"`#PC`N)X9<.EP"7$B((`/","@I(#@$_)`)005Z'`*<0':`-LB((`/ +M",`8GLAP"7$`VB(@@`\(P)2E0"5%`%8F"!0$$(`0L'"L!\W_`-@G\``0`1!. +M)X`,@.'*(@(`RB+!`4AP(B"`#PC`R*0*)0"`$_+(<$AQ(B"`#PC`H*2`X`OR +M0"4$%:AP"G$!V@#;(B"`#PC`&)Y`)T``LN"T!^[_^'"I=`'9@"2&'B"L$(:` +MX`3T`HL2Y#R-#``#9@N+*($H`2?;P +M((``9'A"(`"`RB!B`.!^LN`']\]QB,#8'PAA`O``V.!^X'BAP?'`(B"`#PC` +M@`Q$P!ESR'/H=0"E$A0`,1`4!C&`X04@AP$`V`'9P'D`JX#BRB)B``385GC2 +M:=%P7``.`!@@?`#@>*@@``I`BY!R2``*`(3F1?=`)@\2`O#L;@#8#R#``Q!X +M"R#`@17RSW2(P!@@`"6!`.QD`>(+)@"`SR3B$8"I0*L2>0"5)'@`M0&5)'@! +MM0'F3"``D`OR`(N0<$GV_]D`)04``!U"``'@`*L(W"`@@`\(P.X,02E#`<2Y +M`-R"XP\D3!!,]W5X@.(@@`7R)7S@?X"@AGG@?R"@X'[@>`AR"B!`@/'`!O(B +M((`/",`4IH2ZG;J>NL]PH,``'D`8H`#@>.!XX'C@>.!XX'C@>.!XX'C@>.!X +MX'C1P.!^X'B`X,HD#7#@>.@@K0'@>.!XX'C@>.!^X'C/<:#``"!(&3@`"!F@ +M#Q````#@?N^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>%0```.!C````@$6`X'\(X`F`X'X+@.!^\<`B((`/","$ +M#`AUSW"(P-00$8CCN"AV"?+/<*C^H`,`V2(@@`\(P'!90"4!',EPBB(9#R(@ +M@`\(P"A^(""`#PC`]`S@?N!X\<`B((`/",!P#*'!*'5(=S!X&G`B((`/18`@ +M@@HA@"^(P-00>G`1$8`@`-[CN&*/0,8-\L]PJ/Y`]91OR@N`D\H_@"O(&A8#@(/*I +M<"(@@`]%@!")'/"I<"(@@`]%@!")@.`4]!#8`J\&A8#@$/0,\`:%@.`*\B./ +MBW)J<"(@@`]%@*2$!/`!V$#``,"`X"[R$1&`(..X"?+/<*C^G`8`V2(@@`\( +MP'!9PJ4BCPIP(B"`#T6`5(,&A8#@`_(`&H`CJ7`B((`/18!0@,]U1H!,)%4E +M0!MJ<2(@@`]%@(R:S!6`$&&X#WC,'0(0H<`@((`/",#,#.!X\<`B((`/",!X +M#"AW&G(P>"(@@`]%@""""';/<(C`U!`1B..X0"`-(0ORSW"H_K@#`MGI/'`(B"`#PC`@`RAP0AUSW=& +M@.PDBW9`)P`5R7$B((`/18"0F0CP0"<`%.X#/+/ +M<*C^S`8"V>ER"G,B((`/",!P64#&@<`J<8HB!@LB((`/",`H?A&-X[@.\@44 +MA##/<*C^"`<#V#'P``K`;/ +MF(%'`(P$(H&'$(S!QP",`#80L!#P(MR#]@0V0'; +M(B"`#PC`+&VDP"`@@`\(P.P,\<`B((`/","`#*3!"'ERR7,B((`/",!P608< +M@C,B((`/",#<;(#@RB#B`\HC8@#*(D(#RB$B!.(@@@\(P"QMI,`@((`/",#L +M#.!X\<#AQ:"!SW"(P-00$8A^C>.X0H4/\B`5!!#/<*C^5`<=%840!=D`%080 +M(B"`#PC`<%D"A8#@!_*!X`KT`M@"I0;PJ7`B((`/18"TAB`@@`\(P/P,\<`B +M((`/",!\#`ASFB`:"RAV&G(`((T/1H!0"E8E`!^>C4J(@.0NB,HA@0`=C1!Q +M`-\&](PAPX_*)V(0SW"(P-00$8CCN`ORSW"H_B@&`=EHC$O>58E`!X^K35X%)`:((X/``#H`Q#8R7$B +M((`/18`XL`HA`(#*(((/$`!($.(@@@\(P'P0SW"(P-00$8CCN`_R`!4%$,]P +MJ/Y4!`397HW)`=KLEP(B"`#T6`$(F`X"B&%/*`X!Z8B.BI:*]JJ*BOJJHHK"JIJ+/ +M<$:``"4$V2(@@`]%@"B:SW%%@%"$`=@B((`/18#HKJ"F(""`#PC`]`S@>/'` +M(B"`#PC`A`R:(!H+H\$`((T/1H!0"O@5`!<`VQH@@0\``.@#?:UBI7ZM@.#* +M)D(0SW"(P-00$8C*)F$1X[AHI0SRSW"H_A@!`]G)$7``X9& +MQT?`X:;/<(C`S#:I<2(@@`]%@)BK"'7/<(C`U!`1B..X"_+/<*C^;`$"V4"& +MJ7,B((`/",!P68#E#/),(`"@!/(!V`&F'8[BIF&X':X`V`3P`=@"IJK`(""` +M#PC`Y`S@>/'`(B"`#PC`A`P(=L]PB,#4$!&(X[@H=0GRSW"H_@`!`-DB((`/ +M",!P64`E`!S)<8HB&0\B((`/",`H?B`@@`\(P/0,\<`B((`/",!X#`AUP8@: +M<0+PR8^*(<,O,G8<\A4ECQ,(CQ)P]_6I<,EQ`-HB((`/18#$BB.-,G$$\A4E +M0!#*J/_8"J\IKP'8"Z_#K0#>`_`!WL]PB,#4$!&(Y;@+\L]PJ/ZD#@+9"G+) +M.!^X'CQP.'%*'05($,` +MF'(IBR\E!Q%*BVN+L7,1\L]PB,#4$!&(X;@?\L]PJ/Y$#@/9B7(B((`/",!P +M617P_]R1<@;R%2"#`"FK"_!,)`"``_(CJ`7PD7$AJ`/T@JB1<0/R-7A*J"`@ +M@`\(P/P,X'B6$``&X'[@>/'`(B"`#PC`;`RAP4`@!0,:<4AW.G,*)``A5B`. +M"`HF``=,CO_;0,.8D:+EA@8&1=Q;RD'.`@0ST<'0'\EHD#!@`"8Z8K]G +M(O0"AS)P0``&``2&@.`<\A$2@"#CN`KRSW"H_E@1`-DB((`/",!P60R.6B`! +M![EA(B"`#T6`/(TLC@`80"`,'@(5"O!@@@`8P"``&@`%#(X0<03R`-@J\`*' +M,G!\]P.'@.#Z\Q$2@"#CN`KRSW"H_H01`-DB((`/",!P60R.6B`!![EA(B"` +M#T6`/(U%AP:'8'HAA^#QSW`0``<0Z7$B((`/",!\$`'8H<`@((`/",#$#.!X +M\<#AQ0AUSW"(P-00$8CGN`WR,B6"'P``#`'/<*C^&!$!V2(@@`\(P'!9`-L( +MVEHC`0<$;1EA:'`B((`/18`\C0'C8;J`XF][,_<@((`/",#\#.!X\<`B((`/ +M","`#`AW*'7$:2APBB$$!B(@@`\(P$!^_]BI=(`D!!,`K$HD`'(`V*@@@`): +M(`('_]D!X`]XVF(@HE4E0!X(V2(@@`]%@"B:X*4@((`/",#L#.!^X'C@?N!X +M\<`B((`/",!X#`AU"B=`D``0$`#/<8C`^!,`@2&!^!P(L-6%4!41$$'!#/2` +MY@KRBW%`)0(6`=@B((`/",!$GJEP6-DB((`/",!`?H#G#?2`Y@OR0"4!%HMR +M`=@B((`/",!$GM6E4!U`%``=`!2BP"`@@`\(P-P,X'[@>/'`X<7/=4:`3"<` +MI4`E`!X,V2(@@`\(P$!^`-I,I4VE4:4$;079(B"`#PC`-%T@((`/",#\#.!X +M\<`B((`/","$#``@C@\````)5(8H=5!U`]D)]%6&@.('\H'B#/*"X@SR*'`+ +M\#6FJ7$B((`/18`TIP7P`MGY\0#8@.`+\E2&SW`0`!`0=8:I<2(@@`\(P)@0 +M(""`#PC`]`S@>/'`(B"`#PC`>`R")!HS"'8H=8MP.G#/<8C`)!:*(AH`(B"` +M#PC`(`[)<*EQ(B"`#T6`V(\:<(P@PX_*(4$#RB"!#Q``#Q#B(($/",!\$%H@ +M#RVI<=]G8X<,AV![*G*`X#/T"B$`)X`A&B`J<`S9(B"`#PC`0'X.V`(9`B`` +MAJEQ`=HB((`/18#XG&6'J7$,AV![*G+)<(`@!@L*<2(@@`]%@(R:@.#*(4(# +MRB""#Q``$Q#B(((/",!\$`"&(B"`#T6`N)\L\,EP*G$*P#:R7`B((`/18!DDX`D&C,@((`/",#< +M#.!XX<6`XD``+```VYAR+R0'<>!XJ""`!A8AP@!:(PT#A(H=98*UA8J#M8.2 +M@J6`@IQD!"2^GP`8``"`I03TF[R`I0'C;WO!Q>!^\<`B((`/",!\#*'!"'8H +M=QIP@"`&*XMU"G"I<2(@@`]%@)"9!_`*<*EQ(B"`#T6`U)F`X`_T(,!:(`$- +MV6%(@5!W\_4,X2(@@`]%@$"-(,`"\/_8H<`@((`/",#D#.!X\<`B((`/",!\ +M#"AUY&DUCPAVM.$:<@3V@.$)]L]P$``1$"(@@`\(P'P0%8\$K@6/!:X&CP:N +M!X\'K@2/"*X"AP2F`X<%I@00`"`88("X!;8AA4$I@`#CN<"XSR!B`.2YSR"B +M`.6YSR#B`.:YSR`B`>FYSR!B`N>YSR!B`6"%3R""`8#CRB""`.JYSR#B`0.F +M`-@&I@@0`2"`X0>&`_*`N`>FA2`!`0>F!(>X'A@0(""`#PC`Y`S@>/'`(B"` +M#PC`<`PZ<"AV&G*D:0AW@"<'%0`5$A#I<(HA'0\B((`/",!`?@`ADR\``%@) +MZ7#)<6IR(B"`#T6`.)"I=H`F!Q')<"(@@`\(P$AO0(4("Y@"42%2?R2'0@\%8C#@V5?CJ.@.$9\EHD#PU`($$-Z6$P=)'W5B,! +M#)5Y_)$5)8$0]K$(<8`A$@U5>=J.`>+.J0'>SZD!Y(+DHO<%V3VU#/`R(X$/ +M``"Z`0AT@"02'2ZL5K4!V2^L-(N`(!,$/+55BT`C`08B((`/18"0CR`@@`\( +MP.P,X'CQP"(@@`\(P'@,"'`X,HE@A`;]*:'`_`!X8/A +M2?>]95,E@!"`X,HE81!+??;S2WW*(4$#RB"!#Q``"A#B(($/","($*:G3"$` +MH(H@B`+*(&$#":8-V`RF`-H<\%HB`0-1($"@V6$(@4\@0P-HH07RC+B-N`BA +M$(\!XB@9`@!`+8`3:8$$((`/`0``P&5X":&"XJ;W(""`#PC`W`SQP.'%0"`# +M`P#="-I:)0$=KWAY82(@@`]%@$"-8;J`X@'E-O<@((`/",#\#/'`(B"`#PC` +M@`P(=>"`SW$``'@)P8`B((`/",!`?JEP@"`&"PC9(B"`#T6`*)K!I>"EJ7`B +M((`/18!LJ2`@@`\(P.P,V'`H.@@X@#/=4:`\#&`X,HD(G'@>.@@H@"+<4`E`!4B((`/",`4?X#@ +MRB""#Q``(!#B(((/",!P$('!0"4`%2(@@`\(P,Q^@.#*(((/$``A$.(@@@\( +MP'`0HL`@((`/",#\#.!X\<`B((`/",!X#*+!&G``W:EP(B"`#T6`&)1J((`" +M!""!#____?\I($``2B8`<#IPSW9&@!`Q529`'XMQ(B"`#PC`%'^`X,H@@@\0 +M`"(0XB""#PC``X'KR@.$@%Q`0&/)5)D`? +M@<$B((`/",#,?H#@!/0!P(#@"?3/`Y0+T"'4!X9/A3_=:(0`#VV``@X#@^/-.IP&# +M@.#,(`*$ZO4`@^KQ`,"`X!'R529`'R(@@`\(P+1^@.#*(((/$``D$.(@@@\( +MP'`0#H>`X"STJ*=5)D`?J7$B((`/",!,?X#@!/2`Y0STSW`0`"40529!'ZER +M(B"`#PC`B!!5)D`?(B"`#PC`4'Z`X,H@@@\0`"80XB""#PC`*\`P(#@$O0$'$`T@<$!V"(@@`]%@,2O@.#* +M(((/$`!#$.(@@@\(P'`0`H:`X"/TJ7`"V2(@@`]%@%2#!H:`X`7R`-D`&$`@ +MR7`B((`/18!0@,]U1H!,)%4E0!OI<2(@@`]%@(R:S!6`$&&X#WC,'0(0%?`\ +MCIB]$+G/<(C`S#:E>2(@@`]%@)RJ@^#*(($/$`!$$.(@@0\(P'`0HL`@((`/ +M",#<#/'`(B"`#PC`;`RKP0AWPI``V#IP:L`*(X`OB,#4$!$3@"#CN`GRSW"H +M_J@!`-DB((`/",!P6)HJ! +MX07V*HJ!X<+V`=@&I0.'H+@#IP:%@.`@\@`2`""`X!SR$1.`(.&X"O+/<*C^ +M0`(!V/'`SW"(P-00 +M$8CCN`GRSW"H_D0``-DB((`/",!P62(@@`]%@(2'T<#@?N!X\<#AQ0AU*'(! +MVR(@@`]%@,"*(8T@JHPAPX_*(,H`RB!+`^(@BP]%@#B*(""`#PC`_`S@>/'` +MX<4(/'`(B"`#PC`>`P(=<.(BB'#+S)V +M&G$3],]PB,#4$!&(X[@+\L]PJ/[@#@'9"G(B((`/",!P60'>./`5)8\3"(\2 +M<`?RR8\R=OGU`=X9\*EPR7$!VB(@@`]%@,2*(HTR<07T"A]"%,&M!?`5)4`0 +MR:@JK__8":\`V`NOPJT(=L]PB,#4$!&(Y;@+\L]PJ/XD#P+9"G+)*7!\<`B((`/",!T#*'!2,))PR@< +M`#$L'$`Q,!R`,:B`"B&`+XC`U!`1$8`@X[@H=PKRSW"H_L`1`=GIB&&`-X+\`C#J7#)<>ER(B"`#T6`.(L(=H#F$O(@P4IP +M(B"`#T6`C)J`X`KR(,+//'`(B"`#PC` +MA`P(=L]PB,#4$!&(X[@*\L]PJ/X($0#9(B"`#PC`<%G/=46`[/+)<*EQ(B"` +M#T6`Y(RI<"`@@`\(P/0,\<`B((`/",!L#"AWJ(`*)(`OB,#4$!$4@"!6)0X8 +MX[@:<@[RSW"H_G@2`]GI(X0`A$R#*(ER(B"`#PC`<%D!WH?P`880=T'R"B$` +M)0;P0"%1("\A1R2*=4PA`**Z``H``(9R<,HAP0/*(($/$``%$.(@@0\(P'P0 +M`!:4$%HD#B="=@&&$'?E]<]PB,#4$!&(X[@,\F"&SW"H_@`4`MFIP!0!V`AV"?!%A@:&(89@>@+>`O`!W@#8@.`4\E4@0"ZI<2(@@`]%@(R: +M"B8`D,HA0@/*(((/$``&$.(@@@\(P'P0"G`B((`/18"0C,EP(""`#PC`O`SQ +MP"(@@`\(P(0,"(!6(`T(3(T$X%HB#@<>9L]PB,#4$!&(X[@)\L]PJ/Y`%`'9 +M(B"`#PC`<%D$A8#@RB"!#Q``&Q#B(($/",!P$`#8!*4,C8P@PX\%\D2&!H9@ +M>B&&(""`#PC`]`S@>/'`H<'/<$6`(-PB((`/18``@`&`BW)`P+;8!-D!VR(@ +M@`\(P"QMH<#1P.!^\<`B((`/","`#*/!SW5%@"#,]R18`@W`+8EQH8``#9F!I8 +M``78(""`#T6`G*/QP"(@@`\(P(`,H\$(=<]W18`@W.EPBB$)"B(@@`\(P$!^ +MH:=*)D```!^`$98?F!'I<"(@@`]%@`"``-X(=4`@!P//<$6`Q.-`P,]P18"\ +MXT'`SW!%@,#C0L#/<```KPT$V0?:R7,*)(`/18"LXDHE@`(B((`/","46__8 +M`*7!I0@=@!_:``#P0"4`'HHA"`8B((`/",!`?NEPH\`@((`/",#L#/'`SW%% +M@"#<*'`B((`/18``@`AR*'`B((`/18`PBX#@"?)`(@`#`MD`VB(@@`\(P#1= +MT<#@?N!X\<`B((`/","`#"AWSW9%@"#G`B((`/18``@(HF#QH( +M=4`@#P@9CQH@@`,*VD(HP0:#YDGW&&!3(($`@.'*(&(`2WCV\QE@AB%_#$\A +M`@``&P`@!!R$,%.%AL!6)8$21<(B((`/",`H?@03`"!AV8HB"`9*G`H=2(@@`\(P'`N"'8`A>&X`-D( +M\LEP(B"`#T6`1(W%`0``XK@%\A*&@.`#\BAW`_`!W_*F`(7BN`CR$H:`X`3R +M`-@2I@'?`(7HN`?R`84AAA!Q`_(!I@'?`(7IN`CR`H4BAA!Q!/("I@'?`(7J +MN`CR(A6`$"R.$'$$\@RN`=\`A>ZX`_(#A0BF`(7ON`OR0"8`&4`E`1<&VB(@ +M@`\(P"A^`(7PN`3R`=@+I@"%\;@#\@#8"Z8`A?*X!_(%AH'@`_(!W^6F`(7S +MN`CR!8:`X`3R`-@%I@'?`(7TN`;R!(:!X`3R`=_DI@"%];@'\@2&@.`%\@#8 +M!*8!WP"%Z[@4\D`F`!Q`)1`4"G$,VB(@@`\(P"A^0"8`'PIQ#-HB((`/",`H +M?@"%Z[@*\D`F`!]`)0$4#-HB((`/",`H?@"%[;@%\B,5@!`J'@(0`(4$(("/ +M`/P``"WR-8:`X2OT02B1!D`F$!8"V`IQ"G(B((`/",!$GDPA`*``V-OW*G%: +M<3IP0"4!&0AA(B"`#PC`N)X(<;/@RB)B`,H@`@3B(((/","4I4(B02"`X4`A +M0"`H]P"%X+@%\@'?]*;SIA.&@.#,)R*0$O(,CHMQ9,`%AD/``H9!P`&&0,`$ +MAD+`:G`B((`/18`LKJ7`(""`#PC`S`S@>/'`X<7//'`"'+/<4:`3"R7(B((`/",`T7/'`(B"`#PC` +MA`S/<4:`3"R7(B((`/",`T7/'`"'+//'` +MSW-&@$PG+:-H<"(@@`]%@+R-4:,$:P#9*'(B((`/",`T70#8T<#@?N!X\<#A +MQ<]U1H!,)ZEP(B"`#T6`O(U`)0`>#-DB((`/",!`?@1M`MD`VB(@@`\(P#1= +M(""`#PC`_`P@((`/18#`C?'`X<4(<<]U1H!,)ZEP(B"`#T6`O(U`)0`>#-HB +M((`/",`H?@1M!-D`VB(@@`\(P#1=(""`#PC`_`S@>/'`SW)&@$PG2'`B((`/ +M18"\C0""+8(XXB(@@`]%@)"LT<#@?O'`SW%&@$PG*'`B((`/18"\C0"!(B"` +M#T6`8*I2V0#:2',B((`/",#@<]'`X'[@>/'`X<7/=4:`3"<`A2(@@`]%@&"J +M<851V8HB'0\B((`/",#@\H/@&O(#V#KP`=@5H0"&J7$B((`/ +M18!$G@HG`)`2\H+GRB'"`\H@@@\0`!<0XB""#PC`?!`:\`+8%:$`V"#PR7"` +M(`8+"G$B((`/18",F@+8`AP",%H@`"T99MA@98`,@:EQ8'LJ`P(=4`@$`,H=@#?_!S*LR6! +M(B"`#T6`V(^,(,./RB""#Q``$A#B(((/",!P$#IU@"$&*XMQ*G`B((`/18!< +MF8#@RB""#Q``"!#B(((/",!P$"#`6B`!#0)Q(B"`#T6`0(T@P,EQ6B``#2C: +M`G`B((`/",`H?B#`R7%:(``-N&#OH.Z@-!C"`S48P@.I<"(@@`]%@-23"B8` +MD`CR(,$J<"(@@`]%@(R:J7`B((`/18!DD\EP(B"`#T6`^).AP"`@@`\(P-P, +MX'CQP"(@@`\(P&`,"'4H=AIR`""5#P````E4%18@4!44("(@@`]%@&23!-E4 +M'4`@J7#)<2(@@`]%@-B/6G",(,./RB&!`\H@@0\0``L0XB"!#PC`?!``A` +MXPIR3",`H#3T +M3"<`H![R/!]`%`$0@"!`)P$3-!\"$``0@"`U'P(0!!``(0ZGJ7`B((`/18#4 +MDRWP3";`H,PF`97*($$$Q_&I<(`@!@M*<2(@@`]%@(R:@.#*(8(#RB""#Q`` +M#!#B(((/",!\$!/PJ7`B((`/18!DDU`5`B#/"@%_*!Y2;R@N4,\H/E)?+/3X0AV2O=: +M(0`#SW)&@!`Q`&*`X`GTSW`0`"X0(B"`#PC`?!``AUH@`0,`(8`/1H`0,0S9 +M(B"`#PC`0'X);H#@O`?M_P'E`-@B((`/18"(E`#8(""`#PC`Y`SQP"(@@`\( +MP(0,"'7/<$:`-#*J8)/E*'90]UHE`!//<4:`$#$`88#@"/+/<$:`\#'P((`` +M@.`+],]P$``M$*EQR7(B((`/","($(#F6B4-$P78RB""`P#>QW5&@!`Q`*7) +M<,&E(B"`#T6`B)3)<"`@@`\(P/0,X'CQP"(@@`\(P'P,&G&`X,HD#7#@>.@@ +MK0"`X(@`+@``WUHG#1,(=L]P1H`T,@)U(H63X2I@4_=:(0`#SW-&@!`Q`&.` +MX`OTSW!&@/`Q\""``(#@!?(!A8#@"/3/`X,H@@0\0 +M`#`0XB"!#PC`@$`(``` +M`.!&`0`@`````&@!```$````2`$```@``````````````&0!```$````<`$` +M``0```!0`0``"```````````````````W)<(P``````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````````(B)",`` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````@+-%@("S18"D +MXD6`=.)%@'3B18!$XD6`=.)%@%SB18!TXD6`1.)%@$3B18!TXD6`=.)%@"SB +M18"DXD6`1.)%@``````````!``````````$```````````$```#_```````` +M`&@2",`!````M$\(P`````!H$@C``0```&@2",`!````?!((P`````!H$@C` +M`0```"A6",``````+%8(P``````P5@C``````*14",``````W%0(P``````T +M5`C``````/Q3",``````;%0(P``````85`C```````````````````$``(RB +M18`!`@$`)*1%@`$``P`0H46``0`$`!"A18`"`@(`(*!%@`(#`P`,I$6``@`$ +M`!"A18`"``8`3*!%@`,#`@#\HT6``P`%`)RC18````4`^*A%@``!!@#XJ$6` +M`0(```2J18`!``4`^*A%@`$!!@```````@0!`/BH18`"`P(`^*A%@`("!`#X +MJ$6``@`%`/BH18`"`@8```````,%`0#4J46``P$$`+"I18`#``4`^*A%@`,# +M!@``````!`0!`/BH18`$!0(`U*E%@`0`!0#XJ$6`!`0&```````%!0$`^*A% +M@`4!`P"PJ46`!04$`*BG18`%``4`^*A%@`4%!@``````!04'`/2G18`````` +M`````````````````````````````````````!4````(````N[NJJKN[JJH5 +M````G`(`````1``&````H0```````0``````AH````,'%B"F!```0````$`` +M```!````!(0%```````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````-5WT;Q*[8W)8R5H$YN``GD<`1;"8;0$8!Y-.YH0T;][>LB"9*C;&Y\9 +M8J;F:.X?NLQ:Z%K9SB&G8]O!A-G')N_JA`DE +M$XIDFJGQ`IC;6A%4&T_WD&AZ>U8+%V_;PR\UO2<6[]->@(,6;P_.L>M +M+$WH)Z>$(1^K,W,G\FV*.V%PC\CVG<.Z((J3<>Z-,C26LH(P4T4?H6M4?-$!``$`:W4OX9/D +M$]6;J7YCMN4OH>:#N^-AVRZP9;:(X#5`G]J +M<9N6AW-()4N$[R6Z.$91$K`R?PR^=CE;X?*NTM[,-EPF2Q^(5KG98F.P%=\I^JP"Z;%Y,21;;[.0W;CE?%% +MO;\[,Q`+YI$4#^/"H2B[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW> +M[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[O +MOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^ +MK=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZMWN^^K=[OOJW>[[ZM +MWN^^K=[OOJW>[[ZMWA8````,`````````-L0CDB;D`(+%@````P````!```` +MVP".6P`````6````#`````(```#;$(Y(FY`""Q<````$````&``S`!\````$ +M````-````#````"8`````P0!`$,``@#!``$`=P`&``$``P"(``,`2``"`!X` +M`0`L``$`4@`!`!D``@`<``4`G``!`"@``0#```0`HP`!`!@`!P"8``$`FP`& +M`-```0!.``$`U``#`%T``@`7``$`'0`!`'X``0#N``(`GP`#`%4``0#2``,` +MU0`$``D``0`I``(`40`!``@``0#1``,`J0`!`"L``0`C````!`````!P0``R +M````(``````0```0````$`````@```!D````(`````@````R````)`````P` +.```6````!(0%```````` +` +end diff --git a/sys/contrib/ena-com/ena_com.c b/sys/contrib/ena-com/ena_com.c index c17ac243df02..4314b31cbb59 100644 --- a/sys/contrib/ena-com/ena_com.c +++ b/sys/contrib/ena-com/ena_com.c @@ -45,6 +45,13 @@ #define ENA_ASYNC_QUEUE_DEPTH 16 #define ENA_ADMIN_QUEUE_DEPTH 32 +#ifdef ENA_EXTENDED_STATS + +#define ENA_HISTOGRAM_ACTIVE_MASK_OFFSET 0xF08 +#define ENA_EXTENDED_STAT_GET_FUNCT(_funct_queue) (_funct_queue & 0xFFFF) +#define ENA_EXTENDED_STAT_GET_QUEUE(_funct_queue) (_funct_queue >> 16) + +#endif /* ENA_EXTENDED_STATS */ #define MIN_ENA_VER (((ENA_COMMON_SPEC_VERSION_MAJOR) << \ ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) \ | (ENA_COMMON_SPEC_VERSION_MINOR)) @@ -65,6 +72,10 @@ #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF +#define ENA_COM_BOUNCE_BUFFER_CNTRL_CNT 4 + +#define ENA_REGS_ADMIN_INTR_MASK 1 + /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ @@ -102,7 +113,7 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev, } ena_addr->mem_addr_low = (u32)addr; - ena_addr->mem_addr_high = (u64)addr >> 32; + ena_addr->mem_addr_high = (u16)((u64)addr >> 32); return 0; } @@ -238,12 +249,9 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu tail_masked = admin_queue->sq.tail & queue_size_mask; /* In case of queue FULL */ - cnt = admin_queue->sq.tail - admin_queue->sq.head; + cnt = ATOMIC32_READ(&admin_queue->outstanding_cmds); if (cnt >= admin_queue->q_depth) { - ena_trc_dbg("admin queue is FULL (tail %d head %d depth: %d)\n", - admin_queue->sq.tail, - admin_queue->sq.head, - admin_queue->q_depth); + ena_trc_dbg("admin queue is full.\n"); admin_queue->stats.out_of_space++; return ERR_PTR(ENA_COM_NO_SPACE); } @@ -278,6 +286,7 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu if (unlikely((admin_queue->sq.tail & queue_size_mask) == 0)) admin_queue->sq.phase = !admin_queue->sq.phase; + ENA_DB_SYNC(&admin_queue->sq.mem_handle); ENA_REG_WRITE32(admin_queue->bus, admin_queue->sq.tail, admin_queue->sq.db_addr); @@ -362,21 +371,43 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev, io_sq->desc_addr.phys_addr, io_sq->desc_addr.mem_handle); } - } else { - ENA_MEM_ALLOC_NODE(ena_dev->dmadev, - size, - io_sq->desc_addr.virt_addr, - ctx->numa_node, - dev_node); + if (!io_sq->desc_addr.virt_addr) { - io_sq->desc_addr.virt_addr = - ENA_MEM_ALLOC(ena_dev->dmadev, size); + ena_trc_err("memory allocation failed"); + return ENA_COM_NO_MEM; } } - if (!io_sq->desc_addr.virt_addr) { - ena_trc_err("memory allocation failed"); - return ENA_COM_NO_MEM; + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { + /* Allocate bounce buffers */ + io_sq->bounce_buf_ctrl.buffer_size = ena_dev->llq_info.desc_list_entry_size; + io_sq->bounce_buf_ctrl.buffers_num = ENA_COM_BOUNCE_BUFFER_CNTRL_CNT; + io_sq->bounce_buf_ctrl.next_to_use = 0; + + size = io_sq->bounce_buf_ctrl.buffer_size * io_sq->bounce_buf_ctrl.buffers_num; + + ENA_MEM_ALLOC_NODE(ena_dev->dmadev, + size, + io_sq->bounce_buf_ctrl.base_buffer, + ctx->numa_node, + dev_node); + if (!io_sq->bounce_buf_ctrl.base_buffer) + io_sq->bounce_buf_ctrl.base_buffer = ENA_MEM_ALLOC(ena_dev->dmadev, size); + + if (!io_sq->bounce_buf_ctrl.base_buffer) { + ena_trc_err("bounce buffer memory allocation failed"); + return ENA_COM_NO_MEM; + } + + memcpy(&io_sq->llq_info, &ena_dev->llq_info, sizeof(io_sq->llq_info)); + + /* Initiate the first bounce buffer */ + io_sq->llq_buf_ctrl.curr_bounce_buf = + ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); + memset(io_sq->llq_buf_ctrl.curr_bounce_buf, + 0x0, io_sq->llq_info.desc_list_entry_size); + io_sq->llq_buf_ctrl.descs_left_in_line = + io_sq->llq_info.descs_num_before_header; } io_sq->tail = 0; @@ -507,7 +538,7 @@ static int ena_com_comp_status_to_errno(u8 comp_status) case ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE: return ENA_COM_NO_MEM; case ENA_ADMIN_UNSUPPORTED_OPCODE: - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; case ENA_ADMIN_BAD_OPCODE: case ENA_ADMIN_MALFORMED_REQUEST: case ENA_ADMIN_ILLEGAL_PARAMETER: @@ -532,7 +563,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c ENA_SPINLOCK_UNLOCK(admin_queue->q_lock, flags); if (comp_ctx->status != ENA_CMD_SUBMITTED) - break; + break; if (ENA_TIME_EXPIRE(timeout)) { ena_trc_err("Wait for completion (polling) timeout\n"); @@ -567,6 +598,75 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c return ret; } +static int ena_com_config_llq_info(struct ena_com_dev *ena_dev, + struct ena_admin_feature_llq_desc *llq_desc) +{ + struct ena_com_llq_info *llq_info = &ena_dev->llq_info; + + memset(llq_info, 0, sizeof(*llq_info)); + + switch (llq_desc->header_location_ctrl) { + case ENA_ADMIN_INLINE_HEADER: + llq_info->inline_header = true; + break; + case ENA_ADMIN_HEADER_RING: + llq_info->inline_header = false; + break; + default: + ena_trc_err("Invalid header location control\n"); + return -EINVAL; + } + + switch (llq_desc->entry_size_ctrl) { + case ENA_ADMIN_LIST_ENTRY_SIZE_128B: + llq_info->desc_list_entry_size = 128; + break; + case ENA_ADMIN_LIST_ENTRY_SIZE_192B: + llq_info->desc_list_entry_size = 192; + break; + case ENA_ADMIN_LIST_ENTRY_SIZE_256B: + llq_info->desc_list_entry_size = 256; + break; + default: + ena_trc_err("Invalid entry_size_ctrl %d\n", + llq_desc->entry_size_ctrl); + return -EINVAL; + } + + if ((llq_info->desc_list_entry_size & 0x7)) { + /* The desc list entry size should be whole multiply of 8 + * This requirement comes from __iowrite64_copy() + */ + ena_trc_err("illegal entry size %d\n", + llq_info->desc_list_entry_size); + return -EINVAL; + } + + if (llq_info->inline_header) { + llq_info->desc_stride_ctrl = llq_desc->descriptors_stride_ctrl; + if ((llq_info->desc_stride_ctrl != ENA_ADMIN_SINGLE_DESC_PER_ENTRY) && + (llq_info->desc_stride_ctrl != ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY)) { + ena_trc_err("Invalid desc_stride_ctrl %d\n", + llq_info->desc_stride_ctrl); + return -EINVAL; + } + } else { + llq_info->desc_stride_ctrl = ENA_ADMIN_SINGLE_DESC_PER_ENTRY; + } + + if (llq_info->desc_stride_ctrl == ENA_ADMIN_SINGLE_DESC_PER_ENTRY) + llq_info->descs_per_entry = llq_info->desc_list_entry_size / + sizeof(struct ena_eth_io_tx_desc); + else + llq_info->descs_per_entry = 1; + + llq_info->descs_num_before_header = llq_desc->desc_num_before_header_ctrl; + + return 0; +} + + + static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx, struct ena_com_admin_queue *admin_queue) { @@ -614,13 +714,14 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset) struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read; volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp = mmio_read->read_resp; - u32 mmio_read_reg, timeout, ret; + u32 mmio_read_reg, ret, i; unsigned long flags; - int i; + u32 timeout = mmio_read->reg_read_to; ENA_MIGHT_SLEEP(); - timeout = mmio_read->reg_read_to ? : ENA_REG_READ_TIMEOUT; + if (timeout == 0) + timeout = ENA_REG_READ_TIMEOUT; /* If readless is disabled, perform regular read */ if (!mmio_read->readless_supported) @@ -745,17 +846,20 @@ static void ena_com_io_queue_free(struct ena_com_dev *ena_dev, if (io_sq->desc_addr.virt_addr) { size = io_sq->desc_entry_size * io_sq->q_depth; - if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - ENA_MEM_FREE_COHERENT(ena_dev->dmadev, - size, - io_sq->desc_addr.virt_addr, - io_sq->desc_addr.phys_addr, - io_sq->desc_addr.mem_handle); - else - ENA_MEM_FREE(ena_dev->dmadev, io_sq->desc_addr.virt_addr); + ENA_MEM_FREE_COHERENT(ena_dev->dmadev, + size, + io_sq->desc_addr.virt_addr, + io_sq->desc_addr.phys_addr, + io_sq->desc_addr.mem_handle); io_sq->desc_addr.virt_addr = NULL; } + + if (io_sq->bounce_buf_ctrl.base_buffer) { + size = io_sq->llq_info.desc_list_entry_size * ENA_COM_BOUNCE_BUFFER_CNTRL_CNT; + ENA_MEM_FREE(ena_dev->dmadev, io_sq->bounce_buf_ctrl.base_buffer); + io_sq->bounce_buf_ctrl.base_buffer = NULL; + } } static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, @@ -807,7 +911,7 @@ static int ena_com_get_feature_ex(struct ena_com_dev *ena_dev, if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) { ena_trc_dbg("Feature %d isn't supported\n", feature_id); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } memset(&get_cmd, 0x0, sizeof(get_cmd)); @@ -1366,7 +1470,7 @@ int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, u32 groups_flag) ena_trc_warn("Trying to set unsupported aenq events. supported flag: %x asked flag: %x\n", get_resp.u.aenq.supported_groups, groups_flag); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } memset(&cmd, 0x0, sizeof(cmd)); @@ -1480,7 +1584,6 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev) if (admin_queue->comp_ctx) ENA_MEM_FREE(ena_dev->dmadev, admin_queue->comp_ctx); - admin_queue->comp_ctx = NULL; size = ADMIN_SQ_SIZE(admin_queue->q_depth); if (sq->entries) @@ -1503,6 +1606,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev) void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling) { + u32 mask_value = 0; + + if (polling) + mask_value = ENA_REGS_ADMIN_INTR_MASK; + + ENA_REG_WRITE32(ena_dev->bus, mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF); ena_dev->admin_queue.polling = polling; } @@ -1790,11 +1899,20 @@ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev, if (!rc) memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints, sizeof(get_resp.u.hw_hints)); - else if (rc == ENA_COM_PERMISSION) + else if (rc == ENA_COM_UNSUPPORTED) memset(&get_feat_ctx->hw_hints, 0x0, sizeof(get_feat_ctx->hw_hints)); else return rc; + rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ); + if (!rc) + memcpy(&get_feat_ctx->llq, &get_resp.u.llq, + sizeof(get_resp.u.llq)); + else if (rc == ENA_COM_UNSUPPORTED) + memset(&get_feat_ctx->llq, 0x0, sizeof(get_feat_ctx->llq)); + else + return rc; + return 0; } @@ -1827,6 +1945,7 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data) struct ena_admin_aenq_common_desc *aenq_common; struct ena_com_aenq *aenq = &dev->aenq; ena_aenq_handler handler_cb; + unsigned long long timestamp; u16 masked_head, processed = 0; u8 phase; @@ -1838,11 +1957,12 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data) /* Go over all the events */ while ((aenq_common->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) { - ena_trc_dbg("AENQ! Group[%x] Syndrom[%x] timestamp: [%jus]\n", + timestamp = (unsigned long long)aenq_common->timestamp_low | + ((unsigned long long)aenq_common->timestamp_high << 32); + ena_trc_dbg("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n", aenq_common->group, aenq_common->syndrom, - (u64)aenq_common->timestamp_low + - ((u64)aenq_common->timestamp_high << 32)); + timestamp); /* Handle specific event*/ handler_cb = ena_com_get_specific_aenq_cb(dev, @@ -1872,8 +1992,30 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data) mb(); ENA_REG_WRITE32(dev->bus, (u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF); } +#ifdef ENA_EXTENDED_STATS +/* + * Sets the function Idx and Queue Idx to be used for + * get full statistics feature + * + */ +int ena_com_extended_stats_set_func_queue(struct ena_com_dev *ena_dev, + u32 func_queue) +{ -int ena_com_dev_reset(struct ena_com_dev *ena_dev) + /* Function & Queue is acquired from user in the following format : + * Bottom Half word: funct + * Top Half Word: queue + */ + ena_dev->stats_func = ENA_EXTENDED_STAT_GET_FUNCT(func_queue); + ena_dev->stats_queue = ENA_EXTENDED_STAT_GET_QUEUE(func_queue); + + return 0; +} + +#endif /* ENA_EXTENDED_STATS */ + +int ena_com_dev_reset(struct ena_com_dev *ena_dev, + enum ena_regs_reset_reason_types reset_reason) { u32 stat, timeout, cap, reset_val; int rc; @@ -1901,6 +2043,8 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev) /* start reset */ reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK; + reset_val |= (reset_reason << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT) & + ENA_REGS_DEV_CTL_RESET_REASON_MASK; ENA_REG_WRITE32(ena_dev->bus, reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF); /* Write again the MMIO read request address */ @@ -1973,6 +2117,51 @@ int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev, return ret; } +#ifdef ENA_EXTENDED_STATS + +int ena_com_get_dev_extended_stats(struct ena_com_dev *ena_dev, char *buff, + u32 len) +{ + struct ena_com_stats_ctx ctx; + struct ena_admin_aq_get_stats_cmd *get_cmd = &ctx.get_cmd; + ena_mem_handle_t mem_handle; + void *virt_addr; + dma_addr_t phys_addr; + int ret; + + ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev, len, + virt_addr, phys_addr, mem_handle); + if (!virt_addr) { + ret = ENA_COM_NO_MEM; + goto done; + } + memset(&ctx, 0x0, sizeof(ctx)); + ret = ena_com_mem_addr_set(ena_dev, + &get_cmd->u.control_buffer.address, + phys_addr); + if (unlikely(ret)) { + ena_trc_err("memory address set failed\n"); + return ret; + } + get_cmd->u.control_buffer.length = len; + + get_cmd->device_id = ena_dev->stats_func; + get_cmd->queue_idx = ena_dev->stats_queue; + + ret = ena_get_dev_stats(ena_dev, &ctx, + ENA_ADMIN_GET_STATS_TYPE_EXTENDED); + if (ret < 0) + goto free_ext_stats_mem; + + ret = snprintf(buff, len, "%s", (char *)virt_addr); + +free_ext_stats_mem: + ENA_MEM_FREE_COHERENT(ena_dev->dmadev, len, virt_addr, phys_addr, + mem_handle); +done: + return ret; +} +#endif int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu) { @@ -1983,7 +2172,7 @@ int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu) if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) { ena_trc_dbg("Feature %d isn't supported\n", ENA_ADMIN_MTU); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } memset(&cmd, 0x0, sizeof(cmd)); @@ -2037,7 +2226,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev) ENA_ADMIN_RSS_HASH_FUNCTION)) { ena_trc_dbg("Feature %d isn't supported\n", ENA_ADMIN_RSS_HASH_FUNCTION); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } /* Validate hash function is supported */ @@ -2049,7 +2238,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev) if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) { ena_trc_err("Func hash %d isn't supported by device, abort\n", rss->hash_func); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } memset(&cmd, 0x0, sizeof(cmd)); @@ -2108,7 +2297,7 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) { ena_trc_err("Flow hash function %d isn't supported\n", func); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } switch (func) { @@ -2201,7 +2390,7 @@ int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev) ENA_ADMIN_RSS_HASH_INPUT)) { ena_trc_dbg("Feature %d isn't supported\n", ENA_ADMIN_RSS_HASH_INPUT); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } memset(&cmd, 0x0, sizeof(cmd)); @@ -2282,7 +2471,7 @@ int ena_com_set_default_hash_ctrl(struct ena_com_dev *ena_dev) ena_trc_err("hash control doesn't support all the desire configuration. proto %x supported %x selected %x\n", i, hash_ctrl->supported_fields[i].fields, hash_ctrl->selected_fields[i].fields); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } } @@ -2360,7 +2549,7 @@ int ena_com_indirect_table_set(struct ena_com_dev *ena_dev) ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) { ena_trc_dbg("Feature %d isn't supported\n", ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG); - return ENA_COM_PERMISSION; + return ENA_COM_UNSUPPORTED; } ret = ena_com_ind_tbl_convert_to_device(ena_dev); @@ -2636,7 +2825,7 @@ int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev) ENA_ADMIN_INTERRUPT_MODERATION); if (rc) { - if (rc == ENA_COM_PERMISSION) { + if (rc == ENA_COM_UNSUPPORTED) { ena_trc_dbg("Feature %d isn't supported\n", ENA_ADMIN_INTERRUPT_MODERATION); rc = 0; @@ -2759,3 +2948,33 @@ void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev, intr_moder_tbl[level].pkts_per_interval; entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval; } + +int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, + struct ena_admin_feature_llq_desc *llq) +{ + int rc; + int size; + + if (llq->max_llq_num == 0) { + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; + return 0; + } + + rc = ena_com_config_llq_info(ena_dev, llq); + if (rc) + return rc; + + /* Validate the descriptor is not too big */ + size = ena_dev->tx_max_header_size; + size += ena_dev->llq_info.descs_num_before_header * + sizeof(struct ena_eth_io_tx_desc); + + if (unlikely(ena_dev->llq_info.desc_list_entry_size < size)) { + ena_trc_err("the size of the LLQ entry is smaller than needed\n"); + return ENA_COM_INVAL; + } + + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV; + + return 0; +} diff --git a/sys/contrib/ena-com/ena_com.h b/sys/contrib/ena-com/ena_com.h index 3d8bf0e6737e..9425205f5811 100644 --- a/sys/contrib/ena-com/ena_com.h +++ b/sys/contrib/ena-com/ena_com.h @@ -133,6 +133,15 @@ struct ena_com_tx_meta { u16 l4_hdr_len; /* In words */ }; +struct ena_com_llq_info { + bool inline_header; + u16 desc_stride_ctrl; + + u16 desc_list_entry_size; + u16 descs_num_before_header; + u16 descs_per_entry; +}; + struct ena_com_io_cq { struct ena_com_io_desc_addr cdesc_addr; void *bus; @@ -171,6 +180,20 @@ struct ena_com_io_cq { } ____cacheline_aligned; +struct ena_com_io_bounce_buffer_control { + u8 *base_buffer; + u16 next_to_use; + u16 buffer_size; + u16 buffers_num; /* Must be a power of 2 */ +}; + +/* This struct is to keep tracking the current location of the next llq entry */ +struct ena_com_llq_pkt_ctrl { + u8 *curr_bounce_buf; + u16 idx; + u16 descs_left_in_line; +}; + struct ena_com_io_sq { struct ena_com_io_desc_addr desc_addr; void *bus; @@ -183,6 +206,9 @@ struct ena_com_io_sq { u32 msix_vector; struct ena_com_tx_meta cached_tx_meta; + struct ena_com_llq_info llq_info; + struct ena_com_llq_pkt_ctrl llq_buf_ctrl; + struct ena_com_io_bounce_buffer_control bounce_buf_ctrl; u16 q_depth; u16 qid; @@ -190,6 +216,7 @@ struct ena_com_io_sq { u16 idx; u16 tail; u16 next_to_comp; + u16 llq_last_copy_tail; u32 tx_max_header_size; u8 phase; u8 desc_entry_size; @@ -321,6 +348,7 @@ struct ena_com_dev { void __iomem *mem_bar; void *dmadev; void *bus; + enum ena_admin_placement_policy_type tx_mem_queue_type; u32 tx_max_header_size; u16 stats_func; /* Selected function for extended statistic dump */ @@ -337,6 +365,8 @@ struct ena_com_dev { u16 intr_delay_resolution; u32 intr_moder_tx_interval; struct ena_intr_moder_entry *intr_moder_tbl; + + struct ena_com_llq_info llq_info; }; struct ena_com_dev_get_features_ctx { @@ -345,6 +375,7 @@ struct ena_com_dev_get_features_ctx { struct ena_admin_feature_aenq_desc aenq; struct ena_admin_feature_offload_desc offload; struct ena_admin_ena_hw_hints hw_hints; + struct ena_admin_feature_llq_desc llq; }; struct ena_com_create_io_ctx { @@ -426,10 +457,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev); /* ena_com_dev_reset - Perform device FLR to the device. * @ena_dev: ENA communication layer struct + * @reset_reason: Specify what is the trigger for the reset in case of an error. * * @return - 0 on success, negative value on failure. */ -int ena_com_dev_reset(struct ena_com_dev *ena_dev); +int ena_com_dev_reset(struct ena_com_dev *ena_dev, + enum ena_regs_reset_reason_types reset_reason); /* ena_com_create_io_queue - Create io queue. * @ena_dev: ENA communication layer struct @@ -939,6 +972,15 @@ void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev, enum ena_intr_moder_level level, struct ena_intr_moder_entry *entry); + +/* ena_com_config_dev_mode - Configure the placement policy of the device. + * @ena_dev: ENA communication layer struct + * @llq: LLQ feature descriptor, retrieve via ena_com_get_dev_attr_feat. + * + */ +int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, + struct ena_admin_feature_llq_desc *llq); + static inline bool ena_com_get_adaptive_moderation_enabled(struct ena_com_dev *ena_dev) { return ena_dev->adaptive_coalescing; @@ -1048,6 +1090,30 @@ static inline void ena_com_update_intr_reg(struct ena_eth_io_intr_reg *intr_reg, intr_reg->intr_control |= ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK; } +static inline u8 *ena_com_get_next_bounce_buffer(struct ena_com_io_bounce_buffer_control *bounce_buf_ctrl) +{ + u16 size, buffers_num; + u8 *buf; + + size = bounce_buf_ctrl->buffer_size; + buffers_num = bounce_buf_ctrl->buffers_num; + + buf = bounce_buf_ctrl->base_buffer + + (bounce_buf_ctrl->next_to_use++ & (buffers_num - 1)) * size; + + prefetch(bounce_buf_ctrl->base_buffer + + (bounce_buf_ctrl->next_to_use & (buffers_num - 1)) * size); + + return buf; +} + +#ifdef ENA_EXTENDED_STATS +int ena_com_get_dev_extended_stats(struct ena_com_dev *ena_dev, char *buff, + u32 len); + +int ena_com_extended_stats_set_func_queue(struct ena_com_dev *ena_dev, + u32 funct_queue); +#endif #if defined(__cplusplus) } #endif /* __cplusplus */ diff --git a/sys/contrib/ena-com/ena_defs/ena_admin_defs.h b/sys/contrib/ena-com/ena_defs/ena_admin_defs.h new file mode 100644 index 000000000000..f32bfccb672d --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_admin_defs.h @@ -0,0 +1,1484 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ +#ifndef _ENA_ADMIN_H_ +#define _ENA_ADMIN_H_ + +enum ena_admin_aq_opcode { + ENA_ADMIN_CREATE_SQ = 1, + + ENA_ADMIN_DESTROY_SQ = 2, + + ENA_ADMIN_CREATE_CQ = 3, + + ENA_ADMIN_DESTROY_CQ = 4, + + ENA_ADMIN_GET_FEATURE = 8, + + ENA_ADMIN_SET_FEATURE = 9, + + ENA_ADMIN_GET_STATS = 11, +}; + +enum ena_admin_aq_completion_status { + ENA_ADMIN_SUCCESS = 0, + + ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE = 1, + + ENA_ADMIN_BAD_OPCODE = 2, + + ENA_ADMIN_UNSUPPORTED_OPCODE = 3, + + ENA_ADMIN_MALFORMED_REQUEST = 4, + + /* Additional status is provided in ACQ entry extended_status */ + ENA_ADMIN_ILLEGAL_PARAMETER = 5, + + ENA_ADMIN_UNKNOWN_ERROR = 6, +}; + +enum ena_admin_aq_feature_id { + ENA_ADMIN_DEVICE_ATTRIBUTES = 1, + + ENA_ADMIN_MAX_QUEUES_NUM = 2, + + ENA_ADMIN_HW_HINTS = 3, + + ENA_ADMIN_LLQ = 4, + + ENA_ADMIN_RSS_HASH_FUNCTION = 10, + + ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, + + ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12, + + ENA_ADMIN_MTU = 14, + + ENA_ADMIN_RSS_HASH_INPUT = 18, + + ENA_ADMIN_INTERRUPT_MODERATION = 20, + + ENA_ADMIN_AENQ_CONFIG = 26, + + ENA_ADMIN_LINK_CONFIG = 27, + + ENA_ADMIN_HOST_ATTR_CONFIG = 28, + + ENA_ADMIN_FEATURES_OPCODE_NUM = 32, +}; + +enum ena_admin_placement_policy_type { + /* descriptors and headers are in host memory */ + ENA_ADMIN_PLACEMENT_POLICY_HOST = 1, + + /* descriptors and headers are in device memory (a.k.a Low Latency + * Queue) + */ + ENA_ADMIN_PLACEMENT_POLICY_DEV = 3, +}; + +enum ena_admin_link_types { + ENA_ADMIN_LINK_SPEED_1G = 0x1, + + ENA_ADMIN_LINK_SPEED_2_HALF_G = 0x2, + + ENA_ADMIN_LINK_SPEED_5G = 0x4, + + ENA_ADMIN_LINK_SPEED_10G = 0x8, + + ENA_ADMIN_LINK_SPEED_25G = 0x10, + + ENA_ADMIN_LINK_SPEED_40G = 0x20, + + ENA_ADMIN_LINK_SPEED_50G = 0x40, + + ENA_ADMIN_LINK_SPEED_100G = 0x80, + + ENA_ADMIN_LINK_SPEED_200G = 0x100, + + ENA_ADMIN_LINK_SPEED_400G = 0x200, +}; + +enum ena_admin_completion_policy_type { + /* completion queue entry for each sq descriptor */ + ENA_ADMIN_COMPLETION_POLICY_DESC = 0, + + /* completion queue entry upon request in sq descriptor */ + ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND = 1, + + /* current queue head pointer is updated in OS memory upon sq + * descriptor request + */ + ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND = 2, + + /* current queue head pointer is updated in OS memory for each sq + * descriptor + */ + ENA_ADMIN_COMPLETION_POLICY_HEAD = 3, +}; + +/* basic stats return ena_admin_basic_stats while extanded stats return a + * buffer (string format) with additional statistics per queue and per + * device id + */ +enum ena_admin_get_stats_type { + ENA_ADMIN_GET_STATS_TYPE_BASIC = 0, + + ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1, +}; + +enum ena_admin_get_stats_scope { + ENA_ADMIN_SPECIFIC_QUEUE = 0, + + ENA_ADMIN_ETH_TRAFFIC = 1, +}; + +struct ena_admin_aq_common_desc { + /* 11:0 : command_id + * 15:12 : reserved12 + */ + uint16_t command_id; + + /* as appears in ena_admin_aq_opcode */ + uint8_t opcode; + + /* 0 : phase + * 1 : ctrl_data - control buffer address valid + * 2 : ctrl_data_indirect - control buffer address + * points to list of pages with addresses of control + * buffers + * 7:3 : reserved3 + */ + uint8_t flags; +}; + +/* used in ena_admin_aq_entry. Can point directly to control data, or to a + * page list chunk. Used also at the end of indirect mode page list chunks, + * for chaining. + */ +struct ena_admin_ctrl_buff_info { + uint32_t length; + + struct ena_common_mem_addr address; +}; + +struct ena_admin_sq { + uint16_t sq_idx; + + /* 4:0 : reserved + * 7:5 : sq_direction - 0x1 - Tx; 0x2 - Rx + */ + uint8_t sq_identity; + + uint8_t reserved1; +}; + +struct ena_admin_aq_entry { + struct ena_admin_aq_common_desc aq_common_descriptor; + + union { + uint32_t inline_data_w1[3]; + + struct ena_admin_ctrl_buff_info control_buffer; + } u; + + uint32_t inline_data_w4[12]; +}; + +struct ena_admin_acq_common_desc { + /* command identifier to associate it with the aq descriptor + * 11:0 : command_id + * 15:12 : reserved12 + */ + uint16_t command; + + uint8_t status; + + /* 0 : phase + * 7:1 : reserved1 + */ + uint8_t flags; + + uint16_t extended_status; + + /* serves as a hint what AQ entries can be revoked */ + uint16_t sq_head_indx; +}; + +struct ena_admin_acq_entry { + struct ena_admin_acq_common_desc acq_common_descriptor; + + uint32_t response_specific_data[14]; +}; + +struct ena_admin_aq_create_sq_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + /* 4:0 : reserved0_w1 + * 7:5 : sq_direction - 0x1 - Tx, 0x2 - Rx + */ + uint8_t sq_identity; + + uint8_t reserved8_w1; + + /* 3:0 : placement_policy - Describing where the SQ + * descriptor ring and the SQ packet headers reside: + * 0x1 - descriptors and headers are in OS memory, + * 0x3 - descriptors and headers in device memory + * (a.k.a Low Latency Queue) + * 6:4 : completion_policy - Describing what policy + * to use for generation completion entry (cqe) in + * the CQ associated with this SQ: 0x0 - cqe for each + * sq descriptor, 0x1 - cqe upon request in sq + * descriptor, 0x2 - current queue head pointer is + * updated in OS memory upon sq descriptor request + * 0x3 - current queue head pointer is updated in OS + * memory for each sq descriptor + * 7 : reserved15_w1 + */ + uint8_t sq_caps_2; + + /* 0 : is_physically_contiguous - Described if the + * queue ring memory is allocated in physical + * contiguous pages or split. + * 7:1 : reserved17_w1 + */ + uint8_t sq_caps_3; + + /* associated completion queue id. This CQ must be created prior to + * SQ creation + */ + uint16_t cq_idx; + + /* submission queue depth in entries */ + uint16_t sq_depth; + + /* SQ physical base address in OS memory. This field should not be + * used for Low Latency queues. Has to be page aligned. + */ + struct ena_common_mem_addr sq_ba; + + /* specifies queue head writeback location in OS memory. Valid if + * completion_policy is set to completion_policy_head_on_demand or + * completion_policy_head. Has to be cache aligned + */ + struct ena_common_mem_addr sq_head_writeback; + + uint32_t reserved0_w7; + + uint32_t reserved0_w8; +}; + +enum ena_admin_sq_direction { + ENA_ADMIN_SQ_DIRECTION_TX = 1, + + ENA_ADMIN_SQ_DIRECTION_RX = 2, +}; + +struct ena_admin_acq_create_sq_resp_desc { + struct ena_admin_acq_common_desc acq_common_desc; + + uint16_t sq_idx; + + uint16_t reserved; + + /* queue doorbell address as an offset to PCIe MMIO REG BAR */ + uint32_t sq_doorbell_offset; + + /* low latency queue ring base address as an offset to PCIe MMIO + * LLQ_MEM BAR + */ + uint32_t llq_descriptors_offset; + + /* low latency queue headers' memory as an offset to PCIe MMIO + * LLQ_MEM BAR + */ + uint32_t llq_headers_offset; +}; + +struct ena_admin_aq_destroy_sq_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + struct ena_admin_sq sq; +}; + +struct ena_admin_acq_destroy_sq_resp_desc { + struct ena_admin_acq_common_desc acq_common_desc; +}; + +struct ena_admin_aq_create_cq_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + /* 4:0 : reserved5 + * 5 : interrupt_mode_enabled - if set, cq operates + * in interrupt mode, otherwise - polling + * 7:6 : reserved6 + */ + uint8_t cq_caps_1; + + /* 4:0 : cq_entry_size_words - size of CQ entry in + * 32-bit words, valid values: 4, 8. + * 7:5 : reserved7 + */ + uint8_t cq_caps_2; + + /* completion queue depth in # of entries. must be power of 2 */ + uint16_t cq_depth; + + /* msix vector assigned to this cq */ + uint32_t msix_vector; + + /* cq physical base address in OS memory. CQ must be physically + * contiguous + */ + struct ena_common_mem_addr cq_ba; +}; + +struct ena_admin_acq_create_cq_resp_desc { + struct ena_admin_acq_common_desc acq_common_desc; + + uint16_t cq_idx; + + /* actual cq depth in number of entries */ + uint16_t cq_actual_depth; + + uint32_t numa_node_register_offset; + + uint32_t cq_head_db_register_offset; + + uint32_t cq_interrupt_unmask_register_offset; +}; + +struct ena_admin_aq_destroy_cq_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + uint16_t cq_idx; + + uint16_t reserved1; +}; + +struct ena_admin_acq_destroy_cq_resp_desc { + struct ena_admin_acq_common_desc acq_common_desc; +}; + +/* ENA AQ Get Statistics command. Extended statistics are placed in control + * buffer pointed by AQ entry + */ +struct ena_admin_aq_get_stats_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + union { + /* command specific inline data */ + uint32_t inline_data_w1[3]; + + struct ena_admin_ctrl_buff_info control_buffer; + } u; + + /* stats type as defined in enum ena_admin_get_stats_type */ + uint8_t type; + + /* stats scope defined in enum ena_admin_get_stats_scope */ + uint8_t scope; + + uint16_t reserved3; + + /* queue id. used when scope is specific_queue */ + uint16_t queue_idx; + + /* device id, value 0xFFFF means mine. only privileged device can get + * stats of other device + */ + uint16_t device_id; +}; + +/* Basic Statistics Command. */ +struct ena_admin_basic_stats { + uint32_t tx_bytes_low; + + uint32_t tx_bytes_high; + + uint32_t tx_pkts_low; + + uint32_t tx_pkts_high; + + uint32_t rx_bytes_low; + + uint32_t rx_bytes_high; + + uint32_t rx_pkts_low; + + uint32_t rx_pkts_high; + + uint32_t rx_drops_low; + + uint32_t rx_drops_high; +}; + +struct ena_admin_acq_get_stats_resp { + struct ena_admin_acq_common_desc acq_common_desc; + + struct ena_admin_basic_stats basic_stats; +}; + +struct ena_admin_get_set_feature_common_desc { + /* 1:0 : select - 0x1 - current value; 0x3 - default + * value + * 7:3 : reserved3 + */ + uint8_t flags; + + /* as appears in ena_admin_aq_feature_id */ + uint8_t feature_id; + + uint16_t reserved16; +}; + +struct ena_admin_device_attr_feature_desc { + uint32_t impl_id; + + uint32_t device_version; + + /* bitmap of ena_admin_aq_feature_id */ + uint32_t supported_features; + + uint32_t reserved3; + + /* Indicates how many bits are used physical address access. */ + uint32_t phys_addr_width; + + /* Indicates how many bits are used virtual address access. */ + uint32_t virt_addr_width; + + /* unicast MAC address (in Network byte order) */ + uint8_t mac_addr[6]; + + uint8_t reserved7[2]; + + uint32_t max_mtu; +}; + +enum ena_admin_llq_header_location { + /* header is in descriptor list */ + ENA_ADMIN_INLINE_HEADER = 1, + + /* header in a separate ring, implies 16B descriptor list entry */ + ENA_ADMIN_HEADER_RING = 2, +}; + +enum ena_admin_llq_ring_entry_size { + ENA_ADMIN_LIST_ENTRY_SIZE_128B = 1, + + ENA_ADMIN_LIST_ENTRY_SIZE_192B = 2, + + ENA_ADMIN_LIST_ENTRY_SIZE_256B = 4, +}; + +enum ena_admin_llq_num_descs_before_header { + ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_0 = 0, + + ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1 = 1, + + ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2 = 2, + + ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4 = 4, + + ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8 = 8, +}; + +/* packet descriptor list entry always starts with one or more descriptors, + * followed by a header. The rest of the descriptors are located in the + * beginning of the subsequent entry. Stride refers to how the rest of the + * descriptors are placed. This field is relevant only for inline header + * mode + */ +enum ena_admin_llq_stride_ctrl { + ENA_ADMIN_SINGLE_DESC_PER_ENTRY = 1, + + ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2, +}; + +struct ena_admin_feature_llq_desc { + uint32_t max_llq_num; + + uint32_t max_llq_depth; + + /* use enum ena_admin_llq_header_location */ + uint16_t header_location_ctrl; + + /* if inline header is specified - this is the size of descriptor + * list entry. If header in a separate ring is specified - this is + * the size of header ring entry. use enum + * ena_admin_llq_ring_entry_size + */ + uint16_t entry_size_ctrl; + + /* valid only if inline header is specified. First entry associated + * with the packet includes descriptors and header. Rest of the + * entries occupied by descriptors. This parameter defines the max + * number of descriptors precedding the header in the first entry. + * Values: use enum llq_num_descs_before_header + */ + uint16_t desc_num_before_header_ctrl; + + /* valid, only if inline header is specified. Note, use enum + * ena_admin_llq_stide_ctrl + */ + uint16_t descriptors_stride_ctrl; +}; + +struct ena_admin_queue_feature_desc { + /* including LLQs */ + uint32_t max_sq_num; + + uint32_t max_sq_depth; + + uint32_t max_cq_num; + + uint32_t max_cq_depth; + + uint32_t max_legacy_llq_num; + + uint32_t max_legacy_llq_depth; + + uint32_t max_header_size; + + /* Maximum Descriptors number, including meta descriptor, allowed for + * a single Tx packet + */ + uint16_t max_packet_tx_descs; + + /* Maximum Descriptors number allowed for a single Rx packet */ + uint16_t max_packet_rx_descs; +}; + +struct ena_admin_set_feature_mtu_desc { + /* exclude L2 */ + uint32_t mtu; +}; + +struct ena_admin_set_feature_host_attr_desc { + /* host OS info base address in OS memory. host info is 4KB of + * physically contiguous + */ + struct ena_common_mem_addr os_info_ba; + + /* host debug area base address in OS memory. debug area must be + * physically contiguous + */ + struct ena_common_mem_addr debug_ba; + + /* debug area size */ + uint32_t debug_area_size; +}; + +struct ena_admin_feature_intr_moder_desc { + /* interrupt delay granularity in usec */ + uint16_t intr_delay_resolution; + + uint16_t reserved; +}; + +struct ena_admin_get_feature_link_desc { + /* Link speed in Mb */ + uint32_t speed; + + /* bit field of enum ena_admin_link types */ + uint32_t supported; + + /* 0 : autoneg + * 1 : duplex - Full Duplex + * 31:2 : reserved2 + */ + uint32_t flags; +}; + +struct ena_admin_feature_aenq_desc { + /* bitmask for AENQ groups the device can report */ + uint32_t supported_groups; + + /* bitmask for AENQ groups to report */ + uint32_t enabled_groups; +}; + +struct ena_admin_feature_offload_desc { + /* 0 : TX_L3_csum_ipv4 + * 1 : TX_L4_ipv4_csum_part - The checksum field + * should be initialized with pseudo header checksum + * 2 : TX_L4_ipv4_csum_full + * 3 : TX_L4_ipv6_csum_part - The checksum field + * should be initialized with pseudo header checksum + * 4 : TX_L4_ipv6_csum_full + * 5 : tso_ipv4 + * 6 : tso_ipv6 + * 7 : tso_ecn + */ + uint32_t tx; + + /* Receive side supported stateless offload + * 0 : RX_L3_csum_ipv4 - IPv4 checksum + * 1 : RX_L4_ipv4_csum - TCP/UDP/IPv4 checksum + * 2 : RX_L4_ipv6_csum - TCP/UDP/IPv6 checksum + * 3 : RX_hash - Hash calculation + */ + uint32_t rx_supported; + + uint32_t rx_enabled; +}; + +enum ena_admin_hash_functions { + ENA_ADMIN_TOEPLITZ = 1, + + ENA_ADMIN_CRC32 = 2, +}; + +struct ena_admin_feature_rss_flow_hash_control { + uint32_t keys_num; + + uint32_t reserved; + + uint32_t key[10]; +}; + +struct ena_admin_feature_rss_flow_hash_function { + /* 7:0 : funcs - bitmask of ena_admin_hash_functions */ + uint32_t supported_func; + + /* 7:0 : selected_func - bitmask of + * ena_admin_hash_functions + */ + uint32_t selected_func; + + /* initial value */ + uint32_t init_val; +}; + +/* RSS flow hash protocols */ +enum ena_admin_flow_hash_proto { + ENA_ADMIN_RSS_TCP4 = 0, + + ENA_ADMIN_RSS_UDP4 = 1, + + ENA_ADMIN_RSS_TCP6 = 2, + + ENA_ADMIN_RSS_UDP6 = 3, + + ENA_ADMIN_RSS_IP4 = 4, + + ENA_ADMIN_RSS_IP6 = 5, + + ENA_ADMIN_RSS_IP4_FRAG = 6, + + ENA_ADMIN_RSS_NOT_IP = 7, + + /* TCPv6 with extension header */ + ENA_ADMIN_RSS_TCP6_EX = 8, + + /* IPv6 with extension header */ + ENA_ADMIN_RSS_IP6_EX = 9, + + ENA_ADMIN_RSS_PROTO_NUM = 16, +}; + +/* RSS flow hash fields */ +enum ena_admin_flow_hash_fields { + /* Ethernet Dest Addr */ + ENA_ADMIN_RSS_L2_DA = BIT(0), + + /* Ethernet Src Addr */ + ENA_ADMIN_RSS_L2_SA = BIT(1), + + /* ipv4/6 Dest Addr */ + ENA_ADMIN_RSS_L3_DA = BIT(2), + + /* ipv4/6 Src Addr */ + ENA_ADMIN_RSS_L3_SA = BIT(3), + + /* tcp/udp Dest Port */ + ENA_ADMIN_RSS_L4_DP = BIT(4), + + /* tcp/udp Src Port */ + ENA_ADMIN_RSS_L4_SP = BIT(5), +}; + +struct ena_admin_proto_input { + /* flow hash fields (bitwise according to ena_admin_flow_hash_fields) */ + uint16_t fields; + + uint16_t reserved2; +}; + +struct ena_admin_feature_rss_hash_control { + struct ena_admin_proto_input supported_fields[ENA_ADMIN_RSS_PROTO_NUM]; + + struct ena_admin_proto_input selected_fields[ENA_ADMIN_RSS_PROTO_NUM]; + + struct ena_admin_proto_input reserved2[ENA_ADMIN_RSS_PROTO_NUM]; + + struct ena_admin_proto_input reserved3[ENA_ADMIN_RSS_PROTO_NUM]; +}; + +struct ena_admin_feature_rss_flow_hash_input { + /* supported hash input sorting + * 1 : L3_sort - support swap L3 addresses if DA is + * smaller than SA + * 2 : L4_sort - support swap L4 ports if DP smaller + * SP + */ + uint16_t supported_input_sort; + + /* enabled hash input sorting + * 1 : enable_L3_sort - enable swap L3 addresses if + * DA smaller than SA + * 2 : enable_L4_sort - enable swap L4 ports if DP + * smaller than SP + */ + uint16_t enabled_input_sort; +}; + +enum ena_admin_os_type { + ENA_ADMIN_OS_LINUX = 1, + + ENA_ADMIN_OS_WIN = 2, + + ENA_ADMIN_OS_DPDK = 3, + + ENA_ADMIN_OS_FREEBSD = 4, + + ENA_ADMIN_OS_IPXE = 5, +}; + +struct ena_admin_host_info { + /* defined in enum ena_admin_os_type */ + uint32_t os_type; + + /* os distribution string format */ + uint8_t os_dist_str[128]; + + /* OS distribution numeric format */ + uint32_t os_dist; + + /* kernel version string format */ + uint8_t kernel_ver_str[32]; + + /* Kernel version numeric format */ + uint32_t kernel_ver; + + /* 7:0 : major + * 15:8 : minor + * 23:16 : sub_minor + */ + uint32_t driver_version; + + /* features bitmap */ + uint32_t supported_network_features[4]; +}; + +struct ena_admin_rss_ind_table_entry { + uint16_t cq_idx; + + uint16_t reserved; +}; + +struct ena_admin_feature_rss_ind_table { + /* min supported table size (2^min_size) */ + uint16_t min_size; + + /* max supported table size (2^max_size) */ + uint16_t max_size; + + /* table size (2^size) */ + uint16_t size; + + uint16_t reserved; + + /* index of the inline entry. 0xFFFFFFFF means invalid */ + uint32_t inline_index; + + /* used for updating single entry, ignored when setting the entire + * table through the control buffer. + */ + struct ena_admin_rss_ind_table_entry inline_entry; +}; + +/* When hint value is 0, driver should use it's own predefined value */ +struct ena_admin_ena_hw_hints { + /* value in ms */ + uint16_t mmio_read_timeout; + + /* value in ms */ + uint16_t driver_watchdog_timeout; + + /* Per packet tx completion timeout. value in ms */ + uint16_t missing_tx_completion_timeout; + + uint16_t missed_tx_completion_count_threshold_to_reset; + + /* value in ms */ + uint16_t admin_completion_tx_timeout; + + uint16_t netdev_wd_timeout; + + uint16_t max_tx_sgl_size; + + uint16_t max_rx_sgl_size; + + uint16_t reserved[8]; +}; + +struct ena_admin_get_feat_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + struct ena_admin_ctrl_buff_info control_buffer; + + struct ena_admin_get_set_feature_common_desc feat_common; + + uint32_t raw[11]; +}; + +struct ena_admin_get_feat_resp { + struct ena_admin_acq_common_desc acq_common_desc; + + union { + uint32_t raw[14]; + + struct ena_admin_device_attr_feature_desc dev_attr; + + struct ena_admin_feature_llq_desc llq; + + struct ena_admin_queue_feature_desc max_queue; + + struct ena_admin_feature_aenq_desc aenq; + + struct ena_admin_get_feature_link_desc link; + + struct ena_admin_feature_offload_desc offload; + + struct ena_admin_feature_rss_flow_hash_function flow_hash_func; + + struct ena_admin_feature_rss_flow_hash_input flow_hash_input; + + struct ena_admin_feature_rss_ind_table ind_table; + + struct ena_admin_feature_intr_moder_desc intr_moderation; + + struct ena_admin_ena_hw_hints hw_hints; + } u; +}; + +struct ena_admin_set_feat_cmd { + struct ena_admin_aq_common_desc aq_common_descriptor; + + struct ena_admin_ctrl_buff_info control_buffer; + + struct ena_admin_get_set_feature_common_desc feat_common; + + union { + uint32_t raw[11]; + + /* mtu size */ + struct ena_admin_set_feature_mtu_desc mtu; + + /* host attributes */ + struct ena_admin_set_feature_host_attr_desc host_attr; + + /* AENQ configuration */ + struct ena_admin_feature_aenq_desc aenq; + + /* rss flow hash function */ + struct ena_admin_feature_rss_flow_hash_function flow_hash_func; + + /* rss flow hash input */ + struct ena_admin_feature_rss_flow_hash_input flow_hash_input; + + /* rss indirection table */ + struct ena_admin_feature_rss_ind_table ind_table; + } u; +}; + +struct ena_admin_set_feat_resp { + struct ena_admin_acq_common_desc acq_common_desc; + + union { + uint32_t raw[14]; + } u; +}; + +struct ena_admin_aenq_common_desc { + uint16_t group; + + uint16_t syndrom; + + /* 0 : phase */ + uint8_t flags; + + uint8_t reserved1[3]; + + uint32_t timestamp_low; + + uint32_t timestamp_high; +}; + +/* asynchronous event notification groups */ +enum ena_admin_aenq_group { + ENA_ADMIN_LINK_CHANGE = 0, + + ENA_ADMIN_FATAL_ERROR = 1, + + ENA_ADMIN_WARNING = 2, + + ENA_ADMIN_NOTIFICATION = 3, + + ENA_ADMIN_KEEP_ALIVE = 4, + + ENA_ADMIN_AENQ_GROUPS_NUM = 5, +}; + +enum ena_admin_aenq_notification_syndrom { + ENA_ADMIN_SUSPEND = 0, + + ENA_ADMIN_RESUME = 1, + + ENA_ADMIN_UPDATE_HINTS = 2, +}; + +struct ena_admin_aenq_entry { + struct ena_admin_aenq_common_desc aenq_common_desc; + + /* command specific inline data */ + uint32_t inline_data_w4[12]; +}; + +struct ena_admin_aenq_link_change_desc { + struct ena_admin_aenq_common_desc aenq_common_desc; + + /* 0 : link_status */ + uint32_t flags; +}; + +struct ena_admin_aenq_keep_alive_desc { + struct ena_admin_aenq_common_desc aenq_common_desc; + + uint32_t rx_drops_low; + + uint32_t rx_drops_high; +}; + +struct ena_admin_ena_mmio_req_read_less_resp { + uint16_t req_id; + + uint16_t reg_off; + + /* value is valid when poll is cleared */ + uint32_t reg_val; +}; + +/* aq_common_desc */ +#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) +#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0) +#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1 +#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1) +#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2 +#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2) + +/* sq */ +#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5 +#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5) + +/* acq_common_desc */ +#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) +#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0) + +/* aq_create_sq_cmd */ +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5 +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5) +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0) +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4 +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4) +#define ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK BIT(0) + +/* aq_create_cq_cmd */ +#define ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_SHIFT 5 +#define ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK BIT(5) +#define ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0) + +/* get_set_feature_common_desc */ +#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0) + +/* get_feature_link_desc */ +#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0) +#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1 +#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1) + +/* feature_offload_desc */ +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK BIT(0) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_SHIFT 1 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK BIT(1) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_SHIFT 2 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK BIT(2) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_SHIFT 3 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK BIT(3) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT 4 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK BIT(4) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK BIT(0) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT 1 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK BIT(1) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT 2 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK BIT(2) +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3 +#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3) + +/* feature_rss_flow_hash_function */ +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK GENMASK(7, 0) +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_SELECTED_FUNC_MASK GENMASK(7, 0) + +/* feature_rss_flow_hash_input */ +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT 1 +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1) +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT 2 +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2) +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT 1 +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK BIT(1) +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT 2 +#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK BIT(2) + +/* host_info */ +#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0) +#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8 +#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8) +#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16 +#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16) + +/* aenq_common_desc */ +#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) + +/* aenq_link_change_desc */ +#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0) + +#if !defined(ENA_DEFS_LINUX_MAINLINE) +static inline uint16_t get_ena_admin_aq_common_desc_command_id(const struct ena_admin_aq_common_desc *p) +{ + return p->command_id & ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK; +} + +static inline void set_ena_admin_aq_common_desc_command_id(struct ena_admin_aq_common_desc *p, uint16_t val) +{ + p->command_id |= val & ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK; +} + +static inline uint8_t get_ena_admin_aq_common_desc_phase(const struct ena_admin_aq_common_desc *p) +{ + return p->flags & ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK; +} + +static inline void set_ena_admin_aq_common_desc_phase(struct ena_admin_aq_common_desc *p, uint8_t val) +{ + p->flags |= val & ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK; +} + +static inline uint8_t get_ena_admin_aq_common_desc_ctrl_data(const struct ena_admin_aq_common_desc *p) +{ + return (p->flags & ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK) >> ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT; +} + +static inline void set_ena_admin_aq_common_desc_ctrl_data(struct ena_admin_aq_common_desc *p, uint8_t val) +{ + p->flags |= (val << ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT) & ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK; +} + +static inline uint8_t get_ena_admin_aq_common_desc_ctrl_data_indirect(const struct ena_admin_aq_common_desc *p) +{ + return (p->flags & ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK) >> ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT; +} + +static inline void set_ena_admin_aq_common_desc_ctrl_data_indirect(struct ena_admin_aq_common_desc *p, uint8_t val) +{ + p->flags |= (val << ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT) & ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK; +} + +static inline uint8_t get_ena_admin_sq_sq_direction(const struct ena_admin_sq *p) +{ + return (p->sq_identity & ENA_ADMIN_SQ_SQ_DIRECTION_MASK) >> ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT; +} + +static inline void set_ena_admin_sq_sq_direction(struct ena_admin_sq *p, uint8_t val) +{ + p->sq_identity |= (val << ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT) & ENA_ADMIN_SQ_SQ_DIRECTION_MASK; +} + +static inline uint16_t get_ena_admin_acq_common_desc_command_id(const struct ena_admin_acq_common_desc *p) +{ + return p->command & ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK; +} + +static inline void set_ena_admin_acq_common_desc_command_id(struct ena_admin_acq_common_desc *p, uint16_t val) +{ + p->command |= val & ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK; +} + +static inline uint8_t get_ena_admin_acq_common_desc_phase(const struct ena_admin_acq_common_desc *p) +{ + return p->flags & ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK; +} + +static inline void set_ena_admin_acq_common_desc_phase(struct ena_admin_acq_common_desc *p, uint8_t val) +{ + p->flags |= val & ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_sq_cmd_sq_direction(const struct ena_admin_aq_create_sq_cmd *p) +{ + return (p->sq_identity & ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK) >> ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT; +} + +static inline void set_ena_admin_aq_create_sq_cmd_sq_direction(struct ena_admin_aq_create_sq_cmd *p, uint8_t val) +{ + p->sq_identity |= (val << ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT) & ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_sq_cmd_placement_policy(const struct ena_admin_aq_create_sq_cmd *p) +{ + return p->sq_caps_2 & ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK; +} + +static inline void set_ena_admin_aq_create_sq_cmd_placement_policy(struct ena_admin_aq_create_sq_cmd *p, uint8_t val) +{ + p->sq_caps_2 |= val & ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_sq_cmd_completion_policy(const struct ena_admin_aq_create_sq_cmd *p) +{ + return (p->sq_caps_2 & ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK) >> ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT; +} + +static inline void set_ena_admin_aq_create_sq_cmd_completion_policy(struct ena_admin_aq_create_sq_cmd *p, uint8_t val) +{ + p->sq_caps_2 |= (val << ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT) & ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_sq_cmd_is_physically_contiguous(const struct ena_admin_aq_create_sq_cmd *p) +{ + return p->sq_caps_3 & ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK; +} + +static inline void set_ena_admin_aq_create_sq_cmd_is_physically_contiguous(struct ena_admin_aq_create_sq_cmd *p, uint8_t val) +{ + p->sq_caps_3 |= val & ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_cq_cmd_interrupt_mode_enabled(const struct ena_admin_aq_create_cq_cmd *p) +{ + return (p->cq_caps_1 & ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK) >> ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_SHIFT; +} + +static inline void set_ena_admin_aq_create_cq_cmd_interrupt_mode_enabled(struct ena_admin_aq_create_cq_cmd *p, uint8_t val) +{ + p->cq_caps_1 |= (val << ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_SHIFT) & ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK; +} + +static inline uint8_t get_ena_admin_aq_create_cq_cmd_cq_entry_size_words(const struct ena_admin_aq_create_cq_cmd *p) +{ + return p->cq_caps_2 & ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK; +} + +static inline void set_ena_admin_aq_create_cq_cmd_cq_entry_size_words(struct ena_admin_aq_create_cq_cmd *p, uint8_t val) +{ + p->cq_caps_2 |= val & ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK; +} + +static inline uint8_t get_ena_admin_get_set_feature_common_desc_select(const struct ena_admin_get_set_feature_common_desc *p) +{ + return p->flags & ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK; +} + +static inline void set_ena_admin_get_set_feature_common_desc_select(struct ena_admin_get_set_feature_common_desc *p, uint8_t val) +{ + p->flags |= val & ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK; +} + +static inline uint32_t get_ena_admin_get_feature_link_desc_autoneg(const struct ena_admin_get_feature_link_desc *p) +{ + return p->flags & ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK; +} + +static inline void set_ena_admin_get_feature_link_desc_autoneg(struct ena_admin_get_feature_link_desc *p, uint32_t val) +{ + p->flags |= val & ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK; +} + +static inline uint32_t get_ena_admin_get_feature_link_desc_duplex(const struct ena_admin_get_feature_link_desc *p) +{ + return (p->flags & ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK) >> ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT; +} + +static inline void set_ena_admin_get_feature_link_desc_duplex(struct ena_admin_get_feature_link_desc *p, uint32_t val) +{ + p->flags |= (val << ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT) & ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_TX_L3_csum_ipv4(const struct ena_admin_feature_offload_desc *p) +{ + return p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK; +} + +static inline void set_ena_admin_feature_offload_desc_TX_L3_csum_ipv4(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= val & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_TX_L4_ipv4_csum_part(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_TX_L4_ipv4_csum_part(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_TX_L4_ipv4_csum_full(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_TX_L4_ipv4_csum_full(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_TX_L4_ipv6_csum_part(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_TX_L4_ipv6_csum_part(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_TX_L4_ipv6_csum_full(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_TX_L4_ipv6_csum_full(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_tso_ipv4(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_tso_ipv4(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_tso_ipv6(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_tso_ipv6(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_tso_ecn(const struct ena_admin_feature_offload_desc *p) +{ + return (p->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_tso_ecn(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->tx |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_RX_L3_csum_ipv4(const struct ena_admin_feature_offload_desc *p) +{ + return p->rx_supported & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK; +} + +static inline void set_ena_admin_feature_offload_desc_RX_L3_csum_ipv4(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->rx_supported |= val & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_RX_L4_ipv4_csum(const struct ena_admin_feature_offload_desc *p) +{ + return (p->rx_supported & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_RX_L4_ipv4_csum(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->rx_supported |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_RX_L4_ipv6_csum(const struct ena_admin_feature_offload_desc *p) +{ + return (p->rx_supported & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_RX_L4_ipv6_csum(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->rx_supported |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK; +} + +static inline uint32_t get_ena_admin_feature_offload_desc_RX_hash(const struct ena_admin_feature_offload_desc *p) +{ + return (p->rx_supported & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK) >> ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT; +} + +static inline void set_ena_admin_feature_offload_desc_RX_hash(struct ena_admin_feature_offload_desc *p, uint32_t val) +{ + p->rx_supported |= (val << ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT) & ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK; +} + +static inline uint32_t get_ena_admin_feature_rss_flow_hash_function_funcs(const struct ena_admin_feature_rss_flow_hash_function *p) +{ + return p->supported_func & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK; +} + +static inline void set_ena_admin_feature_rss_flow_hash_function_funcs(struct ena_admin_feature_rss_flow_hash_function *p, uint32_t val) +{ + p->supported_func |= val & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK; +} + +static inline uint32_t get_ena_admin_feature_rss_flow_hash_function_selected_func(const struct ena_admin_feature_rss_flow_hash_function *p) +{ + return p->selected_func & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_SELECTED_FUNC_MASK; +} + +static inline void set_ena_admin_feature_rss_flow_hash_function_selected_func(struct ena_admin_feature_rss_flow_hash_function *p, uint32_t val) +{ + p->selected_func |= val & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_SELECTED_FUNC_MASK; +} + +static inline uint16_t get_ena_admin_feature_rss_flow_hash_input_L3_sort(const struct ena_admin_feature_rss_flow_hash_input *p) +{ + return (p->supported_input_sort & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK) >> ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT; +} + +static inline void set_ena_admin_feature_rss_flow_hash_input_L3_sort(struct ena_admin_feature_rss_flow_hash_input *p, uint16_t val) +{ + p->supported_input_sort |= (val << ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT) & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK; +} + +static inline uint16_t get_ena_admin_feature_rss_flow_hash_input_L4_sort(const struct ena_admin_feature_rss_flow_hash_input *p) +{ + return (p->supported_input_sort & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK) >> ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT; +} + +static inline void set_ena_admin_feature_rss_flow_hash_input_L4_sort(struct ena_admin_feature_rss_flow_hash_input *p, uint16_t val) +{ + p->supported_input_sort |= (val << ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT) & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK; +} + +static inline uint16_t get_ena_admin_feature_rss_flow_hash_input_enable_L3_sort(const struct ena_admin_feature_rss_flow_hash_input *p) +{ + return (p->enabled_input_sort & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK) >> ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT; +} + +static inline void set_ena_admin_feature_rss_flow_hash_input_enable_L3_sort(struct ena_admin_feature_rss_flow_hash_input *p, uint16_t val) +{ + p->enabled_input_sort |= (val << ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT) & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK; +} + +static inline uint16_t get_ena_admin_feature_rss_flow_hash_input_enable_L4_sort(const struct ena_admin_feature_rss_flow_hash_input *p) +{ + return (p->enabled_input_sort & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK) >> ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT; +} + +static inline void set_ena_admin_feature_rss_flow_hash_input_enable_L4_sort(struct ena_admin_feature_rss_flow_hash_input *p, uint16_t val) +{ + p->enabled_input_sort |= (val << ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT) & ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK; +} + +static inline uint32_t get_ena_admin_host_info_major(const struct ena_admin_host_info *p) +{ + return p->driver_version & ENA_ADMIN_HOST_INFO_MAJOR_MASK; +} + +static inline void set_ena_admin_host_info_major(struct ena_admin_host_info *p, uint32_t val) +{ + p->driver_version |= val & ENA_ADMIN_HOST_INFO_MAJOR_MASK; +} + +static inline uint32_t get_ena_admin_host_info_minor(const struct ena_admin_host_info *p) +{ + return (p->driver_version & ENA_ADMIN_HOST_INFO_MINOR_MASK) >> ENA_ADMIN_HOST_INFO_MINOR_SHIFT; +} + +static inline void set_ena_admin_host_info_minor(struct ena_admin_host_info *p, uint32_t val) +{ + p->driver_version |= (val << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) & ENA_ADMIN_HOST_INFO_MINOR_MASK; +} + +static inline uint32_t get_ena_admin_host_info_sub_minor(const struct ena_admin_host_info *p) +{ + return (p->driver_version & ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK) >> ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT; +} + +static inline void set_ena_admin_host_info_sub_minor(struct ena_admin_host_info *p, uint32_t val) +{ + p->driver_version |= (val << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT) & ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK; +} + +static inline uint8_t get_ena_admin_aenq_common_desc_phase(const struct ena_admin_aenq_common_desc *p) +{ + return p->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK; +} + +static inline void set_ena_admin_aenq_common_desc_phase(struct ena_admin_aenq_common_desc *p, uint8_t val) +{ + p->flags |= val & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK; +} + +static inline uint32_t get_ena_admin_aenq_link_change_desc_link_status(const struct ena_admin_aenq_link_change_desc *p) +{ + return p->flags & ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK; +} + +static inline void set_ena_admin_aenq_link_change_desc_link_status(struct ena_admin_aenq_link_change_desc *p, uint32_t val) +{ + p->flags |= val & ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK; +} + +#endif /* !defined(ENA_DEFS_LINUX_MAINLINE) */ +#endif /*_ENA_ADMIN_H_ */ diff --git a/sys/contrib/ena-com/ena_defs/ena_common_defs.h b/sys/contrib/ena-com/ena_defs/ena_common_defs.h new file mode 100644 index 000000000000..66b381ba4077 --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_common_defs.h @@ -0,0 +1,49 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ +#ifndef _ENA_COMMON_H_ +#define _ENA_COMMON_H_ + +#define ENA_COMMON_SPEC_VERSION_MAJOR 0 /* */ +#define ENA_COMMON_SPEC_VERSION_MINOR 10 /* */ + +/* ENA operates with 48-bit memory addresses. ena_mem_addr_t */ +struct ena_common_mem_addr { + uint32_t mem_addr_low; + + uint16_t mem_addr_high; + + /* MBZ */ + uint16_t reserved16; +}; + +#endif /*_ENA_COMMON_H_ */ diff --git a/sys/contrib/ena-com/ena_defs/ena_eth_io_defs.h b/sys/contrib/ena-com/ena_defs/ena_eth_io_defs.h new file mode 100644 index 000000000000..f2cc0f0dea45 --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_eth_io_defs.h @@ -0,0 +1,959 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ +#ifndef _ENA_ETH_IO_H_ +#define _ENA_ETH_IO_H_ + +enum ena_eth_io_l3_proto_index { + ENA_ETH_IO_L3_PROTO_UNKNOWN = 0, + + ENA_ETH_IO_L3_PROTO_IPV4 = 8, + + ENA_ETH_IO_L3_PROTO_IPV6 = 11, + + ENA_ETH_IO_L3_PROTO_FCOE = 21, + + ENA_ETH_IO_L3_PROTO_ROCE = 22, +}; + +enum ena_eth_io_l4_proto_index { + ENA_ETH_IO_L4_PROTO_UNKNOWN = 0, + + ENA_ETH_IO_L4_PROTO_TCP = 12, + + ENA_ETH_IO_L4_PROTO_UDP = 13, + + ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE = 23, +}; + +struct ena_eth_io_tx_desc { + /* 15:0 : length - Buffer length in bytes, must + * include any packet trailers that the ENA supposed + * to update like End-to-End CRC, Authentication GMAC + * etc. This length must not include the + * 'Push_Buffer' length. This length must not include + * the 4-byte added in the end for 802.3 Ethernet FCS + * 21:16 : req_id_hi - Request ID[15:10] + * 22 : reserved22 - MBZ + * 23 : meta_desc - MBZ + * 24 : phase + * 25 : reserved1 - MBZ + * 26 : first - Indicates first descriptor in + * transaction + * 27 : last - Indicates last descriptor in + * transaction + * 28 : comp_req - Indicates whether completion + * should be posted, after packet is transmitted. + * Valid only for first descriptor + * 30:29 : reserved29 - MBZ + * 31 : reserved31 - MBZ + */ + uint32_t len_ctrl; + + /* 3:0 : l3_proto_idx - L3 protocol. This field + * required when l3_csum_en,l3_csum or tso_en are set. + * 4 : DF - IPv4 DF, must be 0 if packet is IPv4 and + * DF flags of the IPv4 header is 0. Otherwise must + * be set to 1 + * 6:5 : reserved5 + * 7 : tso_en - Enable TSO, For TCP only. + * 12:8 : l4_proto_idx - L4 protocol. This field need + * to be set when l4_csum_en or tso_en are set. + * 13 : l3_csum_en - enable IPv4 header checksum. + * 14 : l4_csum_en - enable TCP/UDP checksum. + * 15 : ethernet_fcs_dis - when set, the controller + * will not append the 802.3 Ethernet Frame Check + * Sequence to the packet + * 16 : reserved16 + * 17 : l4_csum_partial - L4 partial checksum. when + * set to 0, the ENA calculates the L4 checksum, + * where the Destination Address required for the + * TCP/UDP pseudo-header is taken from the actual + * packet L3 header. when set to 1, the ENA doesn't + * calculate the sum of the pseudo-header, instead, + * the checksum field of the L4 is used instead. When + * TSO enabled, the checksum of the pseudo-header + * must not include the tcp length field. L4 partial + * checksum should be used for IPv6 packet that + * contains Routing Headers. + * 20:18 : reserved18 - MBZ + * 21 : reserved21 - MBZ + * 31:22 : req_id_lo - Request ID[9:0] + */ + uint32_t meta_ctrl; + + uint32_t buff_addr_lo; + + /* address high and header size + * 15:0 : addr_hi - Buffer Pointer[47:32] + * 23:16 : reserved16_w2 + * 31:24 : header_length - Header length. For Low + * Latency Queues, this fields indicates the number + * of bytes written to the headers' memory. For + * normal queues, if packet is TCP or UDP, and longer + * than max_header_size, then this field should be + * set to the sum of L4 header offset and L4 header + * size(without options), otherwise, this field + * should be set to 0. For both modes, this field + * must not exceed the max_header_size. + * max_header_size value is reported by the Max + * Queues Feature descriptor + */ + uint32_t buff_addr_hi_hdr_sz; +}; + +struct ena_eth_io_tx_meta_desc { + /* 9:0 : req_id_lo - Request ID[9:0] + * 11:10 : reserved10 - MBZ + * 12 : reserved12 - MBZ + * 13 : reserved13 - MBZ + * 14 : ext_valid - if set, offset fields in Word2 + * are valid Also MSS High in Word 0 and bits [31:24] + * in Word 3 + * 15 : reserved15 + * 19:16 : mss_hi + * 20 : eth_meta_type - 0: Tx Metadata Descriptor, 1: + * Extended Metadata Descriptor + * 21 : meta_store - Store extended metadata in queue + * cache + * 22 : reserved22 - MBZ + * 23 : meta_desc - MBO + * 24 : phase + * 25 : reserved25 - MBZ + * 26 : first - Indicates first descriptor in + * transaction + * 27 : last - Indicates last descriptor in + * transaction + * 28 : comp_req - Indicates whether completion + * should be posted, after packet is transmitted. + * Valid only for first descriptor + * 30:29 : reserved29 - MBZ + * 31 : reserved31 - MBZ + */ + uint32_t len_ctrl; + + /* 5:0 : req_id_hi + * 31:6 : reserved6 - MBZ + */ + uint32_t word1; + + /* 7:0 : l3_hdr_len + * 15:8 : l3_hdr_off + * 21:16 : l4_hdr_len_in_words - counts the L4 header + * length in words. there is an explicit assumption + * that L4 header appears right after L3 header and + * L4 offset is based on l3_hdr_off+l3_hdr_len + * 31:22 : mss_lo + */ + uint32_t word2; + + uint32_t reserved; +}; + +struct ena_eth_io_tx_cdesc { + /* Request ID[15:0] */ + uint16_t req_id; + + uint8_t status; + + /* flags + * 0 : phase + * 7:1 : reserved1 + */ + uint8_t flags; + + uint16_t sub_qid; + + uint16_t sq_head_idx; +}; + +struct ena_eth_io_rx_desc { + /* In bytes. 0 means 64KB */ + uint16_t length; + + /* MBZ */ + uint8_t reserved2; + + /* 0 : phase + * 1 : reserved1 - MBZ + * 2 : first - Indicates first descriptor in + * transaction + * 3 : last - Indicates last descriptor in transaction + * 4 : comp_req + * 5 : reserved5 - MBO + * 7:6 : reserved6 - MBZ + */ + uint8_t ctrl; + + uint16_t req_id; + + /* MBZ */ + uint16_t reserved6; + + uint32_t buff_addr_lo; + + uint16_t buff_addr_hi; + + /* MBZ */ + uint16_t reserved16_w3; +}; + +/* 4-word format Note: all ethernet parsing information are valid only when + * last=1 + */ +struct ena_eth_io_rx_cdesc_base { + /* 4:0 : l3_proto_idx + * 6:5 : src_vlan_cnt + * 7 : reserved7 - MBZ + * 12:8 : l4_proto_idx + * 13 : l3_csum_err - when set, either the L3 + * checksum error detected, or, the controller didn't + * validate the checksum. This bit is valid only when + * l3_proto_idx indicates IPv4 packet + * 14 : l4_csum_err - when set, either the L4 + * checksum error detected, or, the controller didn't + * validate the checksum. This bit is valid only when + * l4_proto_idx indicates TCP/UDP packet, and, + * ipv4_frag is not set + * 15 : ipv4_frag - Indicates IPv4 fragmented packet + * 23:16 : reserved16 + * 24 : phase + * 25 : l3_csum2 - second checksum engine result + * 26 : first - Indicates first descriptor in + * transaction + * 27 : last - Indicates last descriptor in + * transaction + * 29:28 : reserved28 + * 30 : buffer - 0: Metadata descriptor. 1: Buffer + * Descriptor was used + * 31 : reserved31 + */ + uint32_t status; + + uint16_t length; + + uint16_t req_id; + + /* 32-bit hash result */ + uint32_t hash; + + uint16_t sub_qid; + + uint16_t reserved; +}; + +/* 8-word format */ +struct ena_eth_io_rx_cdesc_ext { + struct ena_eth_io_rx_cdesc_base base; + + uint32_t buff_addr_lo; + + uint16_t buff_addr_hi; + + uint16_t reserved16; + + uint32_t reserved_w6; + + uint32_t reserved_w7; +}; + +struct ena_eth_io_intr_reg { + /* 14:0 : rx_intr_delay + * 29:15 : tx_intr_delay + * 30 : intr_unmask + * 31 : reserved + */ + uint32_t intr_control; +}; + +struct ena_eth_io_numa_node_cfg_reg { + /* 7:0 : numa + * 30:8 : reserved + * 31 : enabled + */ + uint32_t numa_cfg; +}; + +/* tx_desc */ +#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0) +#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16 +#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16) +#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23 +#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23) +#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24 +#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24) +#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26 +#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26) +#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27 +#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27) +#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28 +#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28) +#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0) +#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4 +#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4) +#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7 +#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7) +#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8 +#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8) +#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13 +#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13) +#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14 +#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14) +#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15 +#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15) +#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17 +#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17) +#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22 +#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22) +#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0) +#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24 +#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24) + +/* tx_meta_desc */ +#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0) +#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14 +#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14) +#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16 +#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16) +#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20 +#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20) +#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21 +#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21) +#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23 +#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23) +#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24 +#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24) +#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26 +#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26) +#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27 +#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27) +#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28 +#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28) +#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0) +#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0) +#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8 +#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8) +#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16 +#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16) +#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22 +#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22) + +/* tx_cdesc */ +#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0) + +/* rx_desc */ +#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0) +#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2 +#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2) +#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3 +#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3) +#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4 +#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4) + +/* rx_cdesc_base */ +#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0) +#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5 +#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5) +#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8 +#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8) +#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13 +#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13) +#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14 +#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14) +#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15 +#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15) +#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24 +#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24) +#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25 +#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25) +#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26 +#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26) +#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27 +#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27) +#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30 +#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30) + +/* intr_reg */ +#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0) +#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15 +#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15) +#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30 +#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30) + +/* numa_node_cfg_reg */ +#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0) +#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31 +#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31) + +#if !defined(ENA_DEFS_LINUX_MAINLINE) +static inline uint32_t get_ena_eth_io_tx_desc_length(const struct ena_eth_io_tx_desc *p) +{ + return p->len_ctrl & ENA_ETH_IO_TX_DESC_LENGTH_MASK; +} + +static inline void set_ena_eth_io_tx_desc_length(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= val & ENA_ETH_IO_TX_DESC_LENGTH_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_req_id_hi(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK) >> ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_req_id_hi(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT) & ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_meta_desc(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_META_DESC_MASK) >> ENA_ETH_IO_TX_DESC_META_DESC_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_meta_desc(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_META_DESC_SHIFT) & ENA_ETH_IO_TX_DESC_META_DESC_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_phase(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_PHASE_MASK) >> ENA_ETH_IO_TX_DESC_PHASE_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_phase(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_PHASE_SHIFT) & ENA_ETH_IO_TX_DESC_PHASE_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_first(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_FIRST_MASK) >> ENA_ETH_IO_TX_DESC_FIRST_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_first(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_FIRST_SHIFT) & ENA_ETH_IO_TX_DESC_FIRST_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_last(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_LAST_MASK) >> ENA_ETH_IO_TX_DESC_LAST_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_last(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_LAST_SHIFT) & ENA_ETH_IO_TX_DESC_LAST_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_comp_req(const struct ena_eth_io_tx_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_DESC_COMP_REQ_MASK) >> ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_comp_req(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT) & ENA_ETH_IO_TX_DESC_COMP_REQ_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_l3_proto_idx(const struct ena_eth_io_tx_desc *p) +{ + return p->meta_ctrl & ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK; +} + +static inline void set_ena_eth_io_tx_desc_l3_proto_idx(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= val & ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_DF(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_DF_MASK) >> ENA_ETH_IO_TX_DESC_DF_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_DF(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_DF_SHIFT) & ENA_ETH_IO_TX_DESC_DF_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_tso_en(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_TSO_EN_MASK) >> ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_tso_en(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT) & ENA_ETH_IO_TX_DESC_TSO_EN_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_l4_proto_idx(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK) >> ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_l4_proto_idx(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT) & ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_l3_csum_en(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK) >> ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_l3_csum_en(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT) & ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_l4_csum_en(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK) >> ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_l4_csum_en(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT) & ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_ethernet_fcs_dis(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK) >> ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_ethernet_fcs_dis(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT) & ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_l4_csum_partial(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK) >> ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_l4_csum_partial(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT) & ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_req_id_lo(const struct ena_eth_io_tx_desc *p) +{ + return (p->meta_ctrl & ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK) >> ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_req_id_lo(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->meta_ctrl |= (val << ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT) & ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_addr_hi(const struct ena_eth_io_tx_desc *p) +{ + return p->buff_addr_hi_hdr_sz & ENA_ETH_IO_TX_DESC_ADDR_HI_MASK; +} + +static inline void set_ena_eth_io_tx_desc_addr_hi(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->buff_addr_hi_hdr_sz |= val & ENA_ETH_IO_TX_DESC_ADDR_HI_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_desc_header_length(const struct ena_eth_io_tx_desc *p) +{ + return (p->buff_addr_hi_hdr_sz & ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK) >> ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT; +} + +static inline void set_ena_eth_io_tx_desc_header_length(struct ena_eth_io_tx_desc *p, uint32_t val) +{ + p->buff_addr_hi_hdr_sz |= (val << ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT) & ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_req_id_lo(const struct ena_eth_io_tx_meta_desc *p) +{ + return p->len_ctrl & ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK; +} + +static inline void set_ena_eth_io_tx_meta_desc_req_id_lo(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= val & ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_ext_valid(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK) >> ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_ext_valid(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT) & ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_mss_hi(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK) >> ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_mss_hi(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT) & ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_eth_meta_type(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK) >> ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_eth_meta_type(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT) & ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_meta_store(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_META_STORE_MASK) >> ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_meta_store(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT) & ENA_ETH_IO_TX_META_DESC_META_STORE_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_meta_desc(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_META_DESC_MASK) >> ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_meta_desc(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT) & ENA_ETH_IO_TX_META_DESC_META_DESC_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_phase(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_PHASE_MASK) >> ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_phase(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT) & ENA_ETH_IO_TX_META_DESC_PHASE_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_first(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_FIRST_MASK) >> ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_first(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT) & ENA_ETH_IO_TX_META_DESC_FIRST_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_last(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_LAST_MASK) >> ENA_ETH_IO_TX_META_DESC_LAST_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_last(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_LAST_SHIFT) & ENA_ETH_IO_TX_META_DESC_LAST_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_comp_req(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->len_ctrl & ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK) >> ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_comp_req(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->len_ctrl |= (val << ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT) & ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_req_id_hi(const struct ena_eth_io_tx_meta_desc *p) +{ + return p->word1 & ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK; +} + +static inline void set_ena_eth_io_tx_meta_desc_req_id_hi(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->word1 |= val & ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_l3_hdr_len(const struct ena_eth_io_tx_meta_desc *p) +{ + return p->word2 & ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK; +} + +static inline void set_ena_eth_io_tx_meta_desc_l3_hdr_len(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->word2 |= val & ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_l3_hdr_off(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->word2 & ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK) >> ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_l3_hdr_off(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->word2 |= (val << ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT) & ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_l4_hdr_len_in_words(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->word2 & ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK) >> ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_l4_hdr_len_in_words(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->word2 |= (val << ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT) & ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK; +} + +static inline uint32_t get_ena_eth_io_tx_meta_desc_mss_lo(const struct ena_eth_io_tx_meta_desc *p) +{ + return (p->word2 & ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK) >> ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT; +} + +static inline void set_ena_eth_io_tx_meta_desc_mss_lo(struct ena_eth_io_tx_meta_desc *p, uint32_t val) +{ + p->word2 |= (val << ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT) & ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK; +} + +static inline uint8_t get_ena_eth_io_tx_cdesc_phase(const struct ena_eth_io_tx_cdesc *p) +{ + return p->flags & ENA_ETH_IO_TX_CDESC_PHASE_MASK; +} + +static inline void set_ena_eth_io_tx_cdesc_phase(struct ena_eth_io_tx_cdesc *p, uint8_t val) +{ + p->flags |= val & ENA_ETH_IO_TX_CDESC_PHASE_MASK; +} + +static inline uint8_t get_ena_eth_io_rx_desc_phase(const struct ena_eth_io_rx_desc *p) +{ + return p->ctrl & ENA_ETH_IO_RX_DESC_PHASE_MASK; +} + +static inline void set_ena_eth_io_rx_desc_phase(struct ena_eth_io_rx_desc *p, uint8_t val) +{ + p->ctrl |= val & ENA_ETH_IO_RX_DESC_PHASE_MASK; +} + +static inline uint8_t get_ena_eth_io_rx_desc_first(const struct ena_eth_io_rx_desc *p) +{ + return (p->ctrl & ENA_ETH_IO_RX_DESC_FIRST_MASK) >> ENA_ETH_IO_RX_DESC_FIRST_SHIFT; +} + +static inline void set_ena_eth_io_rx_desc_first(struct ena_eth_io_rx_desc *p, uint8_t val) +{ + p->ctrl |= (val << ENA_ETH_IO_RX_DESC_FIRST_SHIFT) & ENA_ETH_IO_RX_DESC_FIRST_MASK; +} + +static inline uint8_t get_ena_eth_io_rx_desc_last(const struct ena_eth_io_rx_desc *p) +{ + return (p->ctrl & ENA_ETH_IO_RX_DESC_LAST_MASK) >> ENA_ETH_IO_RX_DESC_LAST_SHIFT; +} + +static inline void set_ena_eth_io_rx_desc_last(struct ena_eth_io_rx_desc *p, uint8_t val) +{ + p->ctrl |= (val << ENA_ETH_IO_RX_DESC_LAST_SHIFT) & ENA_ETH_IO_RX_DESC_LAST_MASK; +} + +static inline uint8_t get_ena_eth_io_rx_desc_comp_req(const struct ena_eth_io_rx_desc *p) +{ + return (p->ctrl & ENA_ETH_IO_RX_DESC_COMP_REQ_MASK) >> ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT; +} + +static inline void set_ena_eth_io_rx_desc_comp_req(struct ena_eth_io_rx_desc *p, uint8_t val) +{ + p->ctrl |= (val << ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT) & ENA_ETH_IO_RX_DESC_COMP_REQ_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_l3_proto_idx(const struct ena_eth_io_rx_cdesc_base *p) +{ + return p->status & ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK; +} + +static inline void set_ena_eth_io_rx_cdesc_base_l3_proto_idx(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= val & ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_src_vlan_cnt(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_src_vlan_cnt(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_l4_proto_idx(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_l4_proto_idx(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_l3_csum_err(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_l3_csum_err(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_l4_csum_err(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_l4_csum_err(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_ipv4_frag(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_ipv4_frag(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_phase(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_phase(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_l3_csum2(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_l3_csum2(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_first(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_first(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_last(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_last(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK; +} + +static inline uint32_t get_ena_eth_io_rx_cdesc_base_buffer(const struct ena_eth_io_rx_cdesc_base *p) +{ + return (p->status & ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT; +} + +static inline void set_ena_eth_io_rx_cdesc_base_buffer(struct ena_eth_io_rx_cdesc_base *p, uint32_t val) +{ + p->status |= (val << ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT) & ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK; +} + +static inline uint32_t get_ena_eth_io_intr_reg_rx_intr_delay(const struct ena_eth_io_intr_reg *p) +{ + return p->intr_control & ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK; +} + +static inline void set_ena_eth_io_intr_reg_rx_intr_delay(struct ena_eth_io_intr_reg *p, uint32_t val) +{ + p->intr_control |= val & ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK; +} + +static inline uint32_t get_ena_eth_io_intr_reg_tx_intr_delay(const struct ena_eth_io_intr_reg *p) +{ + return (p->intr_control & ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK) >> ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT; +} + +static inline void set_ena_eth_io_intr_reg_tx_intr_delay(struct ena_eth_io_intr_reg *p, uint32_t val) +{ + p->intr_control |= (val << ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT) & ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK; +} + +static inline uint32_t get_ena_eth_io_intr_reg_intr_unmask(const struct ena_eth_io_intr_reg *p) +{ + return (p->intr_control & ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK) >> ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT; +} + +static inline void set_ena_eth_io_intr_reg_intr_unmask(struct ena_eth_io_intr_reg *p, uint32_t val) +{ + p->intr_control |= (val << ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT) & ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK; +} + +static inline uint32_t get_ena_eth_io_numa_node_cfg_reg_numa(const struct ena_eth_io_numa_node_cfg_reg *p) +{ + return p->numa_cfg & ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK; +} + +static inline void set_ena_eth_io_numa_node_cfg_reg_numa(struct ena_eth_io_numa_node_cfg_reg *p, uint32_t val) +{ + p->numa_cfg |= val & ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK; +} + +static inline uint32_t get_ena_eth_io_numa_node_cfg_reg_enabled(const struct ena_eth_io_numa_node_cfg_reg *p) +{ + return (p->numa_cfg & ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK) >> ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT; +} + +static inline void set_ena_eth_io_numa_node_cfg_reg_enabled(struct ena_eth_io_numa_node_cfg_reg *p, uint32_t val) +{ + p->numa_cfg |= (val << ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT) & ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK; +} + +#endif /* !defined(ENA_DEFS_LINUX_MAINLINE) */ +#endif /*_ENA_ETH_IO_H_ */ diff --git a/sys/contrib/ena-com/ena_defs/ena_gen_info.h b/sys/contrib/ena-com/ena_defs/ena_gen_info.h new file mode 100644 index 000000000000..0ff47871ea22 --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_gen_info.h @@ -0,0 +1,34 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ +#define ENA_GEN_DATE "Sun Nov 20 11:22:05 IST 2016" +#define ENA_GEN_COMMIT "44da4e8" diff --git a/sys/contrib/ena-com/ena_defs/ena_includes.h b/sys/contrib/ena-com/ena_defs/ena_includes.h new file mode 100644 index 000000000000..5ea312f823f7 --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_includes.h @@ -0,0 +1,4 @@ +#include "ena_common_defs.h" +#include "ena_regs_defs.h" +#include "ena_admin_defs.h" +#include "ena_eth_io_defs.h" diff --git a/sys/contrib/ena-com/ena_defs/ena_regs_defs.h b/sys/contrib/ena-com/ena_defs/ena_regs_defs.h new file mode 100644 index 000000000000..5a540d8f47f0 --- /dev/null +++ b/sys/contrib/ena-com/ena_defs/ena_regs_defs.h @@ -0,0 +1,168 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ +#ifndef _ENA_REGS_H_ +#define _ENA_REGS_H_ + +enum ena_regs_reset_reason_types { + ENA_REGS_RESET_NORMAL = 0, + + ENA_REGS_RESET_KEEP_ALIVE_TO = 1, + + ENA_REGS_RESET_ADMIN_TO = 2, + + ENA_REGS_RESET_MISS_TX_CMPL = 3, + + ENA_REGS_RESET_INV_RX_REQ_ID = 4, + + ENA_REGS_RESET_INV_TX_REQ_ID = 5, + + ENA_REGS_RESET_TOO_MANY_RX_DESCS = 6, + + ENA_REGS_RESET_INIT_ERR = 7, + + ENA_REGS_RESET_DRIVER_INVALID_STATE = 8, + + ENA_REGS_RESET_OS_TRIGGER = 9, + + ENA_REGS_RESET_OS_NETDEV_WD = 10, + + ENA_REGS_RESET_SHUTDOWN = 11, + + ENA_REGS_RESET_USER_TRIGGER = 12, + + ENA_REGS_RESET_GENERIC = 13, +}; + +/* ena_registers offsets */ +#define ENA_REGS_VERSION_OFF 0x0 +#define ENA_REGS_CONTROLLER_VERSION_OFF 0x4 +#define ENA_REGS_CAPS_OFF 0x8 +#define ENA_REGS_CAPS_EXT_OFF 0xc +#define ENA_REGS_AQ_BASE_LO_OFF 0x10 +#define ENA_REGS_AQ_BASE_HI_OFF 0x14 +#define ENA_REGS_AQ_CAPS_OFF 0x18 +#define ENA_REGS_ACQ_BASE_LO_OFF 0x20 +#define ENA_REGS_ACQ_BASE_HI_OFF 0x24 +#define ENA_REGS_ACQ_CAPS_OFF 0x28 +#define ENA_REGS_AQ_DB_OFF 0x2c +#define ENA_REGS_ACQ_TAIL_OFF 0x30 +#define ENA_REGS_AENQ_CAPS_OFF 0x34 +#define ENA_REGS_AENQ_BASE_LO_OFF 0x38 +#define ENA_REGS_AENQ_BASE_HI_OFF 0x3c +#define ENA_REGS_AENQ_HEAD_DB_OFF 0x40 +#define ENA_REGS_AENQ_TAIL_OFF 0x44 +#define ENA_REGS_INTR_MASK_OFF 0x4c +#define ENA_REGS_DEV_CTL_OFF 0x54 +#define ENA_REGS_DEV_STS_OFF 0x58 +#define ENA_REGS_MMIO_REG_READ_OFF 0x5c +#define ENA_REGS_MMIO_RESP_LO_OFF 0x60 +#define ENA_REGS_MMIO_RESP_HI_OFF 0x64 +#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF 0x68 + +/* version register */ +#define ENA_REGS_VERSION_MINOR_VERSION_MASK 0xff +#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT 8 +#define ENA_REGS_VERSION_MAJOR_VERSION_MASK 0xff00 + +/* controller_version register */ +#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK 0xff +#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT 8 +#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK 0xff00 +#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT 16 +#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK 0xff0000 +#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT 24 +#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK 0xff000000 + +/* caps register */ +#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK 0x1 +#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT 1 +#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e +#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8 +#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00 +#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16 +#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000 + +/* aq_caps register */ +#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff +#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT 16 +#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK 0xffff0000 + +/* acq_caps register */ +#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK 0xffff +#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT 16 +#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK 0xffff0000 + +/* aenq_caps register */ +#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK 0xffff +#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT 16 +#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK 0xffff0000 + +/* dev_ctl register */ +#define ENA_REGS_DEV_CTL_DEV_RESET_MASK 0x1 +#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT 1 +#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK 0x2 +#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT 2 +#define ENA_REGS_DEV_CTL_QUIESCENT_MASK 0x4 +#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT 3 +#define ENA_REGS_DEV_CTL_IO_RESUME_MASK 0x8 +#define ENA_REGS_DEV_CTL_RESET_REASON_SHIFT 28 +#define ENA_REGS_DEV_CTL_RESET_REASON_MASK 0xf0000000 + +/* dev_sts register */ +#define ENA_REGS_DEV_STS_READY_MASK 0x1 +#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT 1 +#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK 0x2 +#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT 2 +#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK 0x4 +#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT 3 +#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK 0x8 +#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT 4 +#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK 0x10 +#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT 5 +#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK 0x20 +#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT 6 +#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK 0x40 +#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT 7 +#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK 0x80 + +/* mmio_reg_read register */ +#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK 0xffff +#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT 16 +#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK 0xffff0000 + +/* rss_ind_entry_update register */ +#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK 0xffff +#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16 +#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000 + +#endif /*_ENA_REGS_H_ */ diff --git a/sys/contrib/ena-com/ena_eth_com.c b/sys/contrib/ena-com/ena_eth_com.c index fbf561e1637b..190de1f0ea42 100644 --- a/sys/contrib/ena-com/ena_eth_com.c +++ b/sys/contrib/ena-com/ena_eth_com.c @@ -64,7 +64,7 @@ static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq) io_cq->phase ^= 1; } -static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) +static inline void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq) { u16 tail_masked; u32 offset; @@ -76,22 +76,27 @@ static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset); } -static inline void ena_com_copy_curr_sq_desc_to_dev(struct ena_com_io_sq *io_sq) +static inline void ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq, + u8 *bounce_buffer) { - u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1); - u32 offset = tail_masked * io_sq->desc_entry_size; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; - /* In case this queue isn't a LLQ */ - if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - return; + u16 dst_tail_mask; + u32 dst_offset; - memcpy_toio(io_sq->desc_addr.pbuf_dev_addr + offset, - io_sq->desc_addr.virt_addr + offset, - io_sq->desc_entry_size); -} + dst_tail_mask = io_sq->tail & (io_sq->q_depth - 1); + dst_offset = dst_tail_mask * llq_info->desc_list_entry_size; + + /* Make sure everything was written into the bounce buffer before + * writing the bounce buffer to the device + */ + wmb(); + + /* The line is completed. Copy it to dev */ + ENA_MEMCPY_TO_DEVICE_64(io_sq->desc_addr.pbuf_dev_addr + dst_offset, + bounce_buffer, + llq_info->desc_list_entry_size); -static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) -{ io_sq->tail++; /* Switch phase bit in case of wrap around */ @@ -99,26 +104,124 @@ static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) io_sq->phase ^= 1; } -static inline int ena_com_write_header(struct ena_com_io_sq *io_sq, - u8 *head_src, u16 header_len) +static inline int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq, + u8 *header_src, + u16 header_len) { - u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1); - u8 __iomem *dev_head_addr = - io_sq->header_addr + (tail_masked * io_sq->tx_max_header_size); + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; + u8 *bounce_buffer = pkt_ctrl->curr_bounce_buf; + u16 header_offset; if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) return 0; - if (unlikely(!io_sq->header_addr)) { - ena_trc_err("Push buffer header ptr is NULL\n"); - return ENA_COM_INVAL; + header_offset = + llq_info->descs_num_before_header * io_sq->desc_entry_size; + + if (unlikely((header_offset + header_len) > llq_info->desc_list_entry_size)) { + ena_trc_err("trying to write header larger than llq entry can accommodate\n"); + return ENA_COM_FAULT; } - memcpy_toio(dev_head_addr, head_src, header_len); + if (unlikely(!bounce_buffer)) { + ena_trc_err("bounce buffer is NULL\n"); + return ENA_COM_FAULT; + } + + memcpy(bounce_buffer + header_offset, header_src, header_len); return 0; } +static inline void *get_sq_desc_llq(struct ena_com_io_sq *io_sq) +{ + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + u8 *bounce_buffer; + void *sq_desc; + + bounce_buffer = pkt_ctrl->curr_bounce_buf; + + if (unlikely(!bounce_buffer)) { + ena_trc_err("bounce buffer is NULL\n"); + return NULL; + } + + sq_desc = bounce_buffer + pkt_ctrl->idx * io_sq->desc_entry_size; + pkt_ctrl->idx++; + pkt_ctrl->descs_left_in_line--; + + return sq_desc; +} + +static inline void ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq) +{ + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; + + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) + return; + + /* bounce buffer was used, so write it and get a new one */ + if (pkt_ctrl->idx) { + ena_com_write_bounce_buffer_to_dev(io_sq, + pkt_ctrl->curr_bounce_buf); + pkt_ctrl->curr_bounce_buf = + ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); + memset(io_sq->llq_buf_ctrl.curr_bounce_buf, + 0x0, llq_info->desc_list_entry_size); + } + + pkt_ctrl->idx = 0; + pkt_ctrl->descs_left_in_line = llq_info->descs_num_before_header; +} + +static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) +{ + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + return get_sq_desc_llq(io_sq); + + return get_sq_desc_regular_queue(io_sq); +} + +static inline void ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq) +{ + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; + + if (!pkt_ctrl->descs_left_in_line) { + ena_com_write_bounce_buffer_to_dev(io_sq, + pkt_ctrl->curr_bounce_buf); + + pkt_ctrl->curr_bounce_buf = + ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); + memset(io_sq->llq_buf_ctrl.curr_bounce_buf, + 0x0, llq_info->desc_list_entry_size); + + pkt_ctrl->idx = 0; + if (llq_info->desc_stride_ctrl == ENA_ADMIN_SINGLE_DESC_PER_ENTRY) + pkt_ctrl->descs_left_in_line = 1; + else + pkt_ctrl->descs_left_in_line = + llq_info->desc_list_entry_size / io_sq->desc_entry_size; + } +} + +static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) +{ + + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { + ena_com_sq_update_llq_tail(io_sq); + return; + } + + io_sq->tail++; + + /* Switch phase bit in case of wrap around */ + if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0)) + io_sq->phase ^= 1; +} + static inline struct ena_eth_io_rx_cdesc_base * ena_com_rx_cdesc_idx_to_ptr(struct ena_com_io_cq *io_cq, u16 idx) { @@ -228,7 +331,6 @@ static inline void ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *i memcpy(&io_sq->cached_tx_meta, ena_meta, sizeof(struct ena_com_tx_meta)); - ena_com_copy_curr_sq_desc_to_dev(io_sq); ena_com_sq_update_tail(io_sq); } @@ -271,10 +373,11 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, { struct ena_eth_io_tx_desc *desc = NULL; struct ena_com_buf *ena_bufs = ena_tx_ctx->ena_bufs; - void *push_header = ena_tx_ctx->push_header; + void *buffer_to_push = ena_tx_ctx->push_header; u16 header_len = ena_tx_ctx->header_len; u16 num_bufs = ena_tx_ctx->num_bufs; - int total_desc, i, rc; + u16 start_tail = io_sq->tail; + int i, rc; bool have_meta; u64 addr_hi; @@ -282,7 +385,7 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, "wrong Q type"); /* num_bufs +1 for potential meta desc */ - if (ena_com_sq_empty_space(io_sq) < (num_bufs + 1)) { + if (!ena_com_sq_have_enough_space(io_sq, num_bufs + 1)) { ena_trc_err("Not enough space in the tx queue\n"); return ENA_COM_NO_MEM; } @@ -293,8 +396,10 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, return ENA_COM_INVAL; } - /* start with pushing the header (if needed) */ - rc = ena_com_write_header(io_sq, push_header, header_len); + if (unlikely((io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) && !buffer_to_push)) + return ENA_COM_INVAL; + + rc = ena_com_write_header_to_bounce(io_sq, buffer_to_push, header_len); if (unlikely(rc)) return rc; @@ -305,11 +410,14 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, /* If the caller doesn't want send packets */ if (unlikely(!num_bufs && !header_len)) { - *nb_hw_desc = have_meta ? 0 : 1; + ena_com_close_bounce_buffer(io_sq); + *nb_hw_desc = io_sq->tail - start_tail; return 0; } desc = get_sq_desc(io_sq); + if (unlikely(!desc)) + return ENA_COM_FAULT; memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc)); /* Set first desc when we don't have meta descriptor */ @@ -361,10 +469,12 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, for (i = 0; i < num_bufs; i++) { /* The first desc share the same desc as the header */ if (likely(i != 0)) { - ena_com_copy_curr_sq_desc_to_dev(io_sq); ena_com_sq_update_tail(io_sq); desc = get_sq_desc(io_sq); + if (unlikely(!desc)) + return ENA_COM_FAULT; + memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc)); desc->len_ctrl |= (io_sq->phase << @@ -387,14 +497,11 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, /* set the last desc indicator */ desc->len_ctrl |= ENA_ETH_IO_TX_DESC_LAST_MASK; - ena_com_copy_curr_sq_desc_to_dev(io_sq); - ena_com_sq_update_tail(io_sq); - total_desc = ENA_MAX16(num_bufs, 1); - total_desc += have_meta ? 1 : 0; + ena_com_close_bounce_buffer(io_sq); - *nb_hw_desc = total_desc; + *nb_hw_desc = io_sq->tail - start_tail; return 0; } @@ -456,10 +563,13 @@ int ena_com_add_single_rx_desc(struct ena_com_io_sq *io_sq, ENA_WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); - if (unlikely(ena_com_sq_empty_space(io_sq) == 0)) + if (unlikely(!ena_com_sq_have_enough_space(io_sq, 1))) return ENA_COM_NO_SPACE; desc = get_sq_desc(io_sq); + if (unlikely(!desc)) + return ENA_COM_FAULT; + memset(desc, 0x0, sizeof(struct ena_eth_io_rx_desc)); desc->length = ena_buf->len; @@ -501,6 +611,11 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id) if (cdesc_phase != expected_phase) return ENA_COM_TRY_AGAIN; + if (unlikely(cdesc->req_id >= io_cq->q_depth)) { + ena_trc_err("Invalid req id %d\n", cdesc->req_id); + return ENA_COM_INVAL; + } + ena_com_cq_inc_head(io_cq); *req_id = READ_ONCE(cdesc->req_id); diff --git a/sys/contrib/ena-com/ena_eth_com.h b/sys/contrib/ena-com/ena_eth_com.h index ec32d77ef9d2..d0c8b9080589 100644 --- a/sys/contrib/ena-com/ena_eth_com.h +++ b/sys/contrib/ena-com/ena_eth_com.h @@ -98,7 +98,7 @@ static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq, ENA_REG_WRITE32(io_cq->bus, intr_reg->intr_control, io_cq->unmask_reg); } -static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq) +static inline int ena_com_free_desc(struct ena_com_io_sq *io_sq) { u16 tail, next_to_comp, cnt; @@ -109,6 +109,25 @@ static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq) return io_sq->q_depth - 1 - cnt; } +/* Check if the submission queue has enough space to hold required_buffers */ +static inline bool ena_com_sq_have_enough_space(struct ena_com_io_sq *io_sq, + u16 required_buffers) +{ + int temp; + + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) + return ena_com_free_desc(io_sq) >= required_buffers; + + /* This calculation doesn't need to be 100% accurate. So to reduce + * the calculation overhead just Subtract 2 lines from the free descs + * (one for the header line and one to compensate the devision + * down calculation. + */ + temp = required_buffers / io_sq->llq_info.descs_per_entry + 2; + + return ena_com_free_desc(io_sq) > temp; +} + static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq) { u16 tail; diff --git a/sys/contrib/ena-com/ena_plat.h b/sys/contrib/ena-com/ena_plat.h index 48127d1d8d7b..199427013dd9 100644 --- a/sys/contrib/ena-com/ena_plat.h +++ b/sys/contrib/ena-com/ena_plat.h @@ -186,6 +186,7 @@ static inline long PTR_ERR(const void *ptr) #define ENA_COM_NO_MEM ENOMEM #define ENA_COM_NO_SPACE ENOSPC #define ENA_COM_TRY_AGAIN -1 +#define ENA_COM_UNSUPPORTED EOPNOTSUPP #define ENA_COM_NO_DEVICE ENODEV #define ENA_COM_PERMISSION EPERM #define ENA_COM_TIMER_EXPIRED ETIMEDOUT @@ -281,6 +282,17 @@ void ena_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nseg, int ena_dma_alloc(device_t dmadev, bus_size_t size, ena_mem_handle_t *dma, int mapflags); +#define ENA_MEMCPY_TO_DEVICE_64(dst, src, size) \ + do { \ + int count, i; \ + volatile uint64_t *to = (volatile uint64_t *)(dst); \ + const uint64_t *from = (const uint64_t *)(src); \ + count = (size) / 8; \ + \ + for (i = 0; i < count; i++, from++, to++) \ + *to = *from; \ + } while (0) + #define ENA_MEM_ALLOC(dmadev, size) malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO) #define ENA_MEM_ALLOC_NODE(dmadev, size, virt, node, dev_node) (virt = NULL) #define ENA_MEM_FREE(dmadev, ptr) free(ptr, M_DEVBUF) @@ -321,6 +333,9 @@ int ena_dma_alloc(device_t dmadev, bus_size_t size, ena_mem_handle_t *dma, ((struct ena_bus*)bus)->reg_bar_h, \ (bus_size_t)(offset)) +#define ENA_DB_SYNC(mem_handle) bus_dmamap_sync((mem_handle)->tag, \ + (mem_handle)->map, BUS_DMASYNC_PREREAD) + #define time_after(a,b) ((long)((unsigned long)(b) - (unsigned long)(a)) < 0) #define VLAN_HLEN sizeof(struct ether_vlan_header) @@ -359,9 +374,6 @@ void prefetch(void *x) __var; \ }) -#include "ena_common_defs.h" -#include "ena_admin_defs.h" -#include "ena_eth_io_defs.h" -#include "ena_regs_defs.h" +#include "ena_defs/ena_includes.h" #endif /* ENA_PLAT_H_ */ diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index 0fbd124223d6..1b148fbaa9dc 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -6093,8 +6093,8 @@ ipf_nat_icmpquerytype(icmptype) { case ICMP_ECHOREPLY: case ICMP_ECHO: - /* route aedvertisement/solliciation is currently unsupported: */ - /* it would require rewriting the ICMP data section */ + /* route advertisement/solicitation is currently unsupported: */ + /* it would require rewriting the ICMP data section */ case ICMP_TSTAMP: case ICMP_TSTAMPREPLY: case ICMP_IREQ: diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c index edabfa460ad9..35ef8c0ac56f 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ b/sys/contrib/ipfilter/netinet/ip_state.c @@ -1449,7 +1449,7 @@ ipf_state_add(softc, fin, stsave, flags) is->is_die = 1 + softc->ipf_ticks; /* * We want to check everything that is a property of this packet, - * but we don't (automatically) care about it's fragment status as + * but we don't (automatically) care about its fragment status as * this may change. */ is->is_pass = pass; diff --git a/sys/contrib/libnv/cnvlist.c b/sys/contrib/libnv/cnvlist.c index 0886da69674d..aff1c8e612ec 100644 --- a/sys/contrib/libnv/cnvlist.c +++ b/sys/contrib/libnv/cnvlist.c @@ -53,6 +53,20 @@ __FBSDID("$FreeBSD$"); #include "nvlist_impl.h" #include "nvpair_impl.h" +const char * +cnvlist_name(void *cookiep) +{ + + return (nvpair_name(cookiep)); +} + +int +cnvlist_type(void *cookiep) +{ + + return (nvpair_type(cookiep)); +} + #define CNVLIST_GET(ftype, type, NVTYPE) \ ftype \ cnvlist_get_##type(void *cookiep) \ diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c index 1481515bba00..06cae8f06a09 100644 --- a/sys/contrib/libnv/nvlist.c +++ b/sys/contrib/libnv/nvlist.c @@ -280,8 +280,7 @@ nvlist_get_pararr(const nvlist_t *nvl, void **cookiep) return (ret); } - ret = nvlist_get_parent(nvl, cookiep); - return (ret); + return (nvlist_get_parent(nvl, cookiep)); } bool @@ -708,16 +707,17 @@ nvlist_size(const nvlist_t *nvl) static int * nvlist_xdescriptors(const nvlist_t *nvl, int *descs) { + void *cookie; nvpair_t *nvp; - const char *name; int type; NVLIST_ASSERT(nvl); PJDLOG_ASSERT(nvl->nvl_error == 0); - nvp = NULL; + cookie = NULL; do { - while ((name = nvlist_next(nvl, &type, (void**)&nvp)) != NULL) { + while (nvlist_next(nvl, &type, &cookie) != NULL) { + nvp = cookie; switch (type) { case NV_TYPE_DESCRIPTOR: *descs = nvpair_get_descriptor(nvp); @@ -739,7 +739,7 @@ nvlist_xdescriptors(const nvlist_t *nvl, int *descs) } case NV_TYPE_NVLIST: nvl = nvpair_get_nvlist(nvp); - nvp = NULL; + cookie = NULL; break; case NV_TYPE_NVLIST_ARRAY: { @@ -751,12 +751,12 @@ nvlist_xdescriptors(const nvlist_t *nvl, int *descs) PJDLOG_ASSERT(nitems > 0); nvl = value[0]; - nvp = NULL; + cookie = NULL; break; } } } - } while ((nvl = nvlist_get_pararr(nvl, (void**)&nvp)) != NULL); + } while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL); return (descs); } @@ -786,8 +786,8 @@ size_t nvlist_ndescriptors(const nvlist_t *nvl) { #ifndef _KERNEL + void *cookie; nvpair_t *nvp; - const char *name; size_t ndescs; int type; @@ -795,16 +795,17 @@ nvlist_ndescriptors(const nvlist_t *nvl) PJDLOG_ASSERT(nvl->nvl_error == 0); ndescs = 0; - nvp = NULL; + cookie = NULL; do { - while ((name = nvlist_next(nvl, &type, (void**)&nvp)) != NULL) { + while (nvlist_next(nvl, &type, &cookie) != NULL) { + nvp = cookie; switch (type) { case NV_TYPE_DESCRIPTOR: ndescs++; break; case NV_TYPE_NVLIST: nvl = nvpair_get_nvlist(nvp); - nvp = NULL; + cookie = NULL; break; case NV_TYPE_NVLIST_ARRAY: { @@ -816,7 +817,7 @@ nvlist_ndescriptors(const nvlist_t *nvl) PJDLOG_ASSERT(nitems > 0); nvl = value[0]; - nvp = NULL; + cookie = NULL; break; } case NV_TYPE_DESCRIPTOR_ARRAY: @@ -830,7 +831,7 @@ nvlist_ndescriptors(const nvlist_t *nvl) } } } - } while ((nvl = nvlist_get_pararr(nvl, (void**)&nvp)) != NULL); + } while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL); return (ndescs); #else @@ -1070,24 +1071,24 @@ nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds, int inarrayf; if (*leftp < sizeof(nvlhdr)) - goto failed; + goto fail; memcpy(&nvlhdr, ptr, sizeof(nvlhdr)); if (!nvlist_check_header(&nvlhdr)) - goto failed; + goto fail; if (nvlhdr.nvlh_size != *leftp - sizeof(nvlhdr)) - goto failed; + goto fail; /* * nvlh_descriptors might be smaller than nfds in embedded nvlists. */ if (nvlhdr.nvlh_descriptors > nfds) - goto failed; + goto fail; if ((nvlhdr.nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) - goto failed; + goto fail; inarrayf = (nvl->nvl_flags & NV_FLAG_IN_ARRAY); nvl->nvl_flags = (nvlhdr.nvlh_flags & NV_FLAG_PUBLIC_MASK) | inarrayf; @@ -1098,7 +1099,7 @@ nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds, *leftp -= sizeof(nvlhdr); return (ptr); -failed: +fail: ERRNO_SET(EINVAL); return (NULL); } @@ -1121,20 +1122,20 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, tmpnvl = array = NULL; nvl = retnvl = nvlist_create(0); if (nvl == NULL) - goto failed; + goto fail; ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left); if (ptr == NULL) - goto failed; + goto fail; if (nvl->nvl_flags != flags) { ERRNO_SET(EILSEQ); - goto failed; + goto fail; } while (left > 0) { ptr = nvpair_unpack(isbe, ptr, &left, &nvp); if (ptr == NULL) - goto failed; + goto fail; switch (nvpair_type(nvp)) { case NV_TYPE_NULL: ptr = nvpair_unpack_null(isbe, nvp, ptr, &left); @@ -1152,7 +1153,7 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds, &tmpnvl); if (tmpnvl == NULL || ptr == NULL) - goto failed; + goto fail; nvlist_set_parent(tmpnvl, nvp); break; #ifndef _KERNEL @@ -1170,14 +1171,14 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, break; case NV_TYPE_NVLIST_UP: if (nvl->nvl_parent == NULL) - goto failed; + goto fail; nvl = nvpair_nvlist(nvl->nvl_parent); nvpair_free_structure(nvp); continue; case NV_TYPE_NVLIST_ARRAY_NEXT: if (nvl->nvl_array_next == NULL) { if (nvl->nvl_parent == NULL) - goto failed; + goto fail; nvl = nvpair_nvlist(nvl->nvl_parent); } else { nvl = __DECONST(nvlist_t *, @@ -1185,7 +1186,7 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left); if (ptr == NULL) - goto failed; + goto fail; } nvpair_free_structure(nvp); continue; @@ -1202,13 +1203,14 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, ptr = nvpair_unpack_nvlist_array(isbe, nvp, ptr, &left, &array); if (ptr == NULL) - goto failed; + goto fail; + PJDLOG_ASSERT(array != NULL); tmpnvl = array; - while (array != NULL) { + do { nvlist_set_parent(array, nvp); array = __DECONST(nvlist_t *, nvlist_get_array_next(array)); - } + } while (array != NULL); ptr = nvlist_unpack_header(tmpnvl, ptr, nfds, &isbe, &left); break; @@ -1216,9 +1218,9 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp)); } if (ptr == NULL) - goto failed; + goto fail; if (!nvlist_move_nvpair(nvl, nvp)) - goto failed; + goto fail; if (tmpnvl != NULL) { nvl = tmpnvl; tmpnvl = NULL; @@ -1226,7 +1228,7 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, } return (retnvl); -failed: +fail: nvlist_destroy(retnvl); return (NULL); } @@ -1258,7 +1260,6 @@ nvlist_send(int sock, const nvlist_t *nvl) return (-1); ret = -1; - data = NULL; fdidx = 0; data = nvlist_xpack(nvl, &fdidx, &datasize); diff --git a/sys/contrib/libnv/nvpair.c b/sys/contrib/libnv/nvpair.c index ae7c9bf04a0e..3625de551957 100644 --- a/sys/contrib/libnv/nvpair.c +++ b/sys/contrib/libnv/nvpair.c @@ -614,7 +614,7 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr, struct nvpair_header nvphdr; if (*leftp < sizeof(nvphdr)) - goto failed; + goto fail; memcpy(&nvphdr, ptr, sizeof(nvphdr)); ptr += sizeof(nvphdr); @@ -622,12 +622,12 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr, #if NV_TYPE_FIRST > 0 if (nvphdr.nvph_type < NV_TYPE_FIRST) - goto failed; + goto fail; #endif if (nvphdr.nvph_type > NV_TYPE_LAST && nvphdr.nvph_type != NV_TYPE_NVLIST_UP && nvphdr.nvph_type != NV_TYPE_NVLIST_ARRAY_NEXT) { - goto failed; + goto fail; } #if BYTE_ORDER == BIG_ENDIAN @@ -643,14 +643,14 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr, #endif if (nvphdr.nvph_namesize > NV_NAME_MAX) - goto failed; + goto fail; if (*leftp < nvphdr.nvph_namesize) - goto failed; + goto fail; if (nvphdr.nvph_namesize < 1) - goto failed; + goto fail; if (strnlen((const char *)ptr, nvphdr.nvph_namesize) != (size_t)(nvphdr.nvph_namesize - 1)) { - goto failed; + goto fail; } memcpy(nvp->nvp_name, ptr, nvphdr.nvph_namesize); @@ -658,7 +658,7 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr, *leftp -= nvphdr.nvph_namesize; if (*leftp < nvphdr.nvph_datasize) - goto failed; + goto fail; nvp->nvp_type = nvphdr.nvph_type; nvp->nvp_data = 0; @@ -666,7 +666,7 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr, nvp->nvp_nitems = nvphdr.nvph_nitems; return (ptr); -failed: +fail: ERRNO_SET(EINVAL); return (NULL); } @@ -1087,7 +1087,7 @@ nvpair_unpack_nvlist_array(bool isbe __unused, nvpair_t *nvp, return (ptr); fail: ERRNO_SAVE(); - for (j = 0; j < ii; j++) + for (j = 0; j <= ii; j++) nvlist_destroy(value[j]); nv_free(value); ERRNO_RESTORE(); @@ -1108,10 +1108,10 @@ nvpair_unpack(bool isbe, const unsigned char *ptr, size_t *leftp, ptr = nvpair_unpack_header(isbe, nvp, ptr, leftp); if (ptr == NULL) - goto failed; + goto fail; tmp = nv_realloc(nvp, sizeof(*nvp) + strlen(nvp->nvp_name) + 1); if (tmp == NULL) - goto failed; + goto fail; nvp = tmp; /* Update nvp_name after realloc(). */ @@ -1120,7 +1120,7 @@ nvpair_unpack(bool isbe, const unsigned char *ptr, size_t *leftp, nvp->nvp_magic = NVPAIR_MAGIC; *nvpp = nvp; return (ptr); -failed: +fail: nv_free(nvp); return (NULL); } @@ -1407,12 +1407,10 @@ nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value, { unsigned int ii; nvlist_t **nvls; - nvpair_t *nvp; + nvpair_t *parent; int flags; - nvp = NULL; nvls = NULL; - ii = 0; if (value == NULL || nitems == 0) { ERRNO_SET(EINVAL); @@ -1434,33 +1432,40 @@ nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value, goto fail; if (ii > 0) { + nvpair_t *nvp; + nvp = nvpair_allocv(" ", NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvls[ii], 0, 0); - if (nvp == NULL) + if (nvp == NULL) { + ERRNO_SAVE(); + nvlist_destroy(nvls[ii]); + ERRNO_RESTORE(); goto fail; + } nvlist_set_array_next(nvls[ii - 1], nvp); } } flags = nvlist_flags(nvls[nitems - 1]) | NV_FLAG_IN_ARRAY; nvlist_set_flags(nvls[nitems - 1], flags); - nvp = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY, + parent = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY, (uint64_t)(uintptr_t)nvls, 0, nitems); + if (parent == NULL) + goto fail; + + for (ii = 0; ii < nitems; ii++) + nvlist_set_parent(nvls[ii], parent); + + return (parent); fail: - if (nvp == NULL) { - ERRNO_SAVE(); - for (; ii > 0; ii--) - nvlist_destroy(nvls[ii - 1]); + ERRNO_SAVE(); + for (; ii > 0; ii--) + nvlist_destroy(nvls[ii - 1]); + nv_free(nvls); + ERRNO_RESTORE(); - nv_free(nvls); - ERRNO_RESTORE(); - } else { - for (ii = 0; ii < nitems; ii++) - nvlist_set_parent(nvls[ii], nvp); - } - - return (nvp); + return (NULL); } #ifndef _KERNEL @@ -1685,11 +1690,10 @@ nvpair_move_number_array(const char *name, uint64_t *value, size_t nitems) nvpair_t * nvpair_move_nvlist_array(const char *name, nvlist_t **value, size_t nitems) { + nvpair_t *parent; unsigned int ii; - nvpair_t *nvp; int flags; - nvp = NULL; if (value == NULL || nitems == 0) { ERRNO_SET(EINVAL); return (NULL); @@ -1702,6 +1706,8 @@ nvpair_move_nvlist_array(const char *name, nvlist_t **value, size_t nitems) goto fail; } if (ii > 0) { + nvpair_t *nvp; + nvp = nvpair_allocv(" ", NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value[ii], 0, 0); if (nvp == NULL) @@ -1712,25 +1718,27 @@ nvpair_move_nvlist_array(const char *name, nvlist_t **value, size_t nitems) flags = nvlist_flags(value[nitems - 1]) | NV_FLAG_IN_ARRAY; nvlist_set_flags(value[nitems - 1], flags); - nvp = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY, + parent = nvpair_allocv(name, NV_TYPE_NVLIST_ARRAY, (uint64_t)(uintptr_t)value, 0, nitems); -fail: - if (nvp == NULL) { - ERRNO_SAVE(); - for (ii = 0; ii < nitems; ii++) { - if (value[ii] != NULL && - nvlist_get_pararr(value[ii], NULL) != NULL) { - nvlist_destroy(value[ii]); - } - nv_free(value); - } - ERRNO_RESTORE(); - } else { - for (ii = 0; ii < nitems; ii++) - nvlist_set_parent(value[ii], nvp); - } + if (parent == NULL) + goto fail; - return (nvp); + for (ii = 0; ii < nitems; ii++) + nvlist_set_parent(value[ii], parent); + + return (parent); +fail: + ERRNO_SAVE(); + for (ii = 0; ii < nitems; ii++) { + if (value[ii] != NULL && + nvlist_get_pararr(value[ii], NULL) != NULL) { + nvlist_destroy(value[ii]); + } + } + nv_free(value); + ERRNO_RESTORE(); + + return (NULL); } #ifndef _KERNEL @@ -1740,7 +1748,6 @@ nvpair_move_descriptor_array(const char *name, int *value, size_t nitems) nvpair_t *nvp; size_t i; - nvp = NULL; if (value == NULL || nitems == 0) { ERRNO_SET(EINVAL); return (NULL); @@ -1755,19 +1762,20 @@ nvpair_move_descriptor_array(const char *name, int *value, size_t nitems) nvp = nvpair_allocv(name, NV_TYPE_DESCRIPTOR_ARRAY, (uint64_t)(uintptr_t)value, sizeof(value[0]) * nitems, nitems); - -fail: - if (nvp == NULL) { - ERRNO_SAVE(); - for (i = 0; i < nitems; i++) { - if (fd_is_valid(value[i])) - close(value[i]); - } - nv_free(value); - ERRNO_RESTORE(); - } + if (nvp == NULL) + goto fail; return (nvp); +fail: + ERRNO_SAVE(); + for (i = 0; i < nitems; i++) { + if (fd_is_valid(value[i])) + close(value[i]); + } + nv_free(value); + ERRNO_RESTORE(); + + return (NULL); } #endif diff --git a/sys/contrib/ncsw/Peripherals/BM/bm.h b/sys/contrib/ncsw/Peripherals/BM/bm.h index 157315629e86..e9708666e244 100644 --- a/sys/contrib/ncsw/Peripherals/BM/bm.h +++ b/sys/contrib/ncsw/Peripherals/BM/bm.h @@ -41,6 +41,7 @@ #ifndef __BM_H #define __BM_H +#include "xx_common.h" #include "bm_ext.h" #include "mm_ext.h" @@ -261,7 +262,7 @@ typedef struct { t_Handle h_Bm; struct bm_portal *p_BmPortalLow; t_BmPortalCallbacks cbs[BM_NUM_OF_RINGS]; - int irq; + uintptr_t irq; int cpu; /* This is used for any "core-affine" portals, ie. default portals * associated to the corresponding cpu. -1 implies that there is no core * affinity configured. */ @@ -303,7 +304,7 @@ typedef struct { uint32_t exceptions; t_BmExceptionsCallback *f_Exception; t_Handle h_App; - int errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */ + uintptr_t errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */ t_BmDriverParams *p_BmDriverParams; } t_Bm; @@ -339,7 +340,7 @@ static __inline__ void BmCommit(t_BmPortal *p_BmPortal, bmRingType_t type, uint8 static __inline__ uint32_t BmBpidGet(t_Bm *p_Bm, bool force, uint32_t base) { uint64_t ans, size = 1; - uint32_t alignment = 1; + uint64_t alignment = 1; if (force) { @@ -347,7 +348,7 @@ static __inline__ uint32_t BmBpidGet(t_Bm *p_Bm, bool force, uint32_t base) { ans = MM_GetForce(p_Bm->h_BpidMm, base, - (int)size, + size, "BM BPID MEM"); ans = base; } @@ -394,6 +395,7 @@ static __inline__ uint32_t BmBpidGet(t_Bm *p_Bm, bool force, uint32_t base) size, alignment, "BM BPID MEM"); + KASSERT(ans < UINT32_MAX, ("Oops, %lx > UINT32_MAX!\n", ans)); return (uint32_t)ans; } diff --git a/sys/contrib/ncsw/Peripherals/BM/bm_pool.c b/sys/contrib/ncsw/Peripherals/BM/bm_pool.c index d7a38c26b714..c908846760ad 100644 --- a/sys/contrib/ncsw/Peripherals/BM/bm_pool.c +++ b/sys/contrib/ncsw/Peripherals/BM/bm_pool.c @@ -545,26 +545,6 @@ t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff) return *(t_Handle *)PTR_MOVE(p_Buff, -(sizeof(t_Handle))); } -void * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr) -{ - t_BmPool *p_BmPool = (t_BmPool *)h_BmPool; - - SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL); - - return p_BmPool->bufferPoolInfo.f_PhysToVirt(addr); -} - -physAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *p_Buff) -{ - t_BmPool *p_BmPool = (t_BmPool *)h_BmPool; - - SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, (physAddress_t)0); - SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, (physAddress_t)0); - - return p_BmPool->bufferPoolInfo.f_VirtToPhys(p_Buff); -} - uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter) { t_BmPool *p_BmPool = (t_BmPool *)h_BmPool; diff --git a/sys/contrib/ncsw/Peripherals/BM/bman_low.c b/sys/contrib/ncsw/Peripherals/BM/bman_low.c index e3a83c83f2b3..818e62df31c0 100644 --- a/sys/contrib/ncsw/Peripherals/BM/bman_low.c +++ b/sys/contrib/ncsw/Peripherals/BM/bman_low.c @@ -38,6 +38,10 @@ @Description BM low-level implementation *//***************************************************************************/ +#include +#include +#include + #include "std_ext.h" #include "core_ext.h" #include "xx_ext.h" @@ -259,7 +263,7 @@ void bm_rcr_pci_commit(struct bm_portal *portal, uint8_t myverb) rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit); RCR_INC(rcr); rcr->available--; - hwsync(); + mb(); bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor)); #ifdef BM_CHECKING rcr->busy = 0; @@ -281,7 +285,7 @@ void bm_rcr_pce_commit(struct bm_portal *portal, uint8_t myverb) rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit); RCR_INC(rcr); rcr->available--; - lwsync(); + wmb(); bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor)); #ifdef BM_CHECKING rcr->busy = 0; @@ -294,7 +298,7 @@ void bm_rcr_pvb_commit(struct bm_portal *portal, uint8_t myverb) struct bm_rcr_entry *rcursor; ASSERT_COND(rcr->busy); ASSERT_COND(rcr->pmode == e_BmPortalPVB); - lwsync(); + rmb(); rcursor = rcr->cursor; rcursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit); dcbf_64(rcursor); @@ -432,7 +436,7 @@ void bm_mc_commit(struct bm_portal *portal, uint8_t myverb) { register struct bm_mc *mc = &portal->mc; ASSERT_COND(mc->state == mc_user); - lwsync(); + rmb(); mc->cr->__dont_write_directly__verb = (uint8_t)(myverb | mc->vbit); dcbf_64(mc->cr); dcbit_ro(mc->rr + mc->rridx); diff --git a/sys/contrib/ncsw/Peripherals/BM/bman_private.h b/sys/contrib/ncsw/Peripherals/BM/bman_private.h index 2d70428f3778..972c57cecb0a 100644 --- a/sys/contrib/ncsw/Peripherals/BM/bman_private.h +++ b/sys/contrib/ncsw/Peripherals/BM/bman_private.h @@ -54,76 +54,13 @@ * and that dcbzl(), dcbfl(), and dcbi() won't fall victim to compiler or * execution reordering with respect to other code/instructions that manipulate * the same cacheline. */ -#ifdef CORE_E500MC - -#if defined(_DIAB_TOOL) -#define hwsync() \ -do { \ -__asm__ __volatile__ ("sync"); \ -} while(0) - -#define lwsync() \ -do { \ -__asm__ __volatile__ ("lwsync"); \ -} while(0) - -__asm__ __volatile__ void dcbf (volatile void * addr) -{ -%reg addr - dcbf r0, addr -} - -__asm__ __volatile__ void dcbt_ro (volatile void * addr) -{ -%reg addr - dcbt r0, addr -} - -__asm__ __volatile__ void dcbt_rw (volatile void * addr) -{ -%reg addr - dcbtst r0, addr -} - -__asm__ __volatile__ void dcbzl (volatile void * addr) -{ -%reg addr - dcbzl r0, addr -} - -#define dcbz_64(p) \ - do { \ - dcbzl(p); \ - } while (0) - -#define dcbf_64(p) \ - do { \ - dcbf(p); \ - } while (0) - -/* Commonly used combo */ -#define dcbit_ro(p) \ - do { \ - dcbi(p); \ - dcbt_ro(p); \ - } while (0) - -#else /* GNU C */ -#define hwsync() \ - do { \ - __asm__ __volatile__ ("sync" : : : "memory"); \ - } while(0) - -#define lwsync() \ - do { \ - __asm__ __volatile__ ("lwsync" : : : "memory"); \ - } while(0) #define dcbf(addr) \ do { \ __asm__ __volatile__ ("dcbf 0, %0" : : "r" (addr)); \ } while(0) +#ifdef CORE_E500MC #define dcbt_ro(addr) \ do { \ __asm__ __volatile__ ("dcbt 0, %0" : : "r" (addr)); \ @@ -156,46 +93,34 @@ __asm__ __volatile__ void dcbzl (volatile void * addr) dcbt_ro(p); \ } while (0) -#endif /* _DIAB_TOOL */ - #else -#define hwsync CORE_MemoryBarrier -#define lwsync hwsync -#define dcbf(p) \ - do { \ - __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p)); \ - } while(0) #define dcbt_ro(p) \ do { \ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)); \ lwsync(); \ } while(0) -#define dcbt_rw(p) \ - do { \ - __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)); \ - } while(0) #define dcbz(p) \ do { \ __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p)); \ } while (0) #define dcbz_64(p) \ do { \ - dcbz((uint32_t)p + 32); \ + dcbz((char *)p + 32); \ dcbz(p); \ } while (0) #define dcbf_64(p) \ do { \ - dcbf((uint32_t)p + 32); \ + dcbf((char *)p + 32); \ dcbf(p); \ } while (0) /* Commonly used combo */ #define dcbit_ro(p) \ do { \ dcbi(p); \ - dcbi((uint32_t)p + 32); \ + dcbi((char *)p + 32); \ dcbt_ro(p); \ - dcbt_ro((uint32_t)p + 32); \ + dcbt_ro((char *)p + 32); \ } while (0) #endif /* CORE_E500MC */ diff --git a/sys/contrib/ncsw/Peripherals/FM/HC/hc.c b/sys/contrib/ncsw/Peripherals/FM/HC/hc.c index 134d13b10e3d..278e7c7ae6ed 100644 --- a/sys/contrib/ncsw/Peripherals/FM/HC/hc.c +++ b/sys/contrib/ncsw/Peripherals/FM/HC/hc.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "std_ext.h" #include "error_ext.h" #include "sprint_ext.h" @@ -39,24 +40,54 @@ #include "fm_hc.h" +/**************************************************************************//** + @Description defaults +*//***************************************************************************/ +#define DEFAULT_dataMemId 0 + #define HC_HCOR_OPCODE_PLCR_PRFL 0x0 #define HC_HCOR_OPCODE_KG_SCM 0x1 #define HC_HCOR_OPCODE_SYNC 0x2 #define HC_HCOR_OPCODE_CC 0x3 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4 #define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16 #define HC_HCOR_GBL 0x20000000 -#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(t_FmPcdKgInterModuleSchemeRegs)+sizeof(t_FmPcdKgPortRegs)) +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400 + +#if (DPAA_VERSION == 10) +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800 +#else +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00 +#endif /* (DPAA_VERSION == 10) */ + +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs)) #define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame) -#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(t_FmPcdKgInterModuleSchemeRegs)+sizeof(t_FmPcdPlcrInterModuleProfileRegs)) -#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrInterModuleProfileRegs)+sizeof(uint32_t)) +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs)) +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t)) #define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES) + #define BUILD_FD(len) \ do { \ memset(&fmFd, 0, sizeof(t_DpaaFD)); \ - DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \ + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \ DPAA_FD_SET_OFFSET(&fmFd, 0); \ DPAA_FD_SET_LENGTH(&fmFd, len); \ } while (0) @@ -65,50 +96,29 @@ do { \ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START -/**************************************************************************//** - @Description PCD KG scheme registers -*//***************************************************************************/ -typedef _Packed struct t_FmPcdKgSchemeRegsWithoutCounter { - volatile uint32_t kgse_mode; /**< MODE */ - volatile uint32_t kgse_ekfc; /**< Extract Known Fields Command */ - volatile uint32_t kgse_ekdv; /**< Extract Known Default Value */ - volatile uint32_t kgse_bmch; /**< Bit Mask Command High */ - volatile uint32_t kgse_bmcl; /**< Bit Mask Command Low */ - volatile uint32_t kgse_fqb; /**< Frame Queue Base */ - volatile uint32_t kgse_hc; /**< Hash Command */ - volatile uint32_t kgse_ppc; /**< Policer Profile Command */ - volatile uint32_t kgse_gec[FM_PCD_KG_NUM_OF_GENERIC_REGS]; - /**< Generic Extract Command */ - volatile uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */ - volatile uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */ - volatile uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/ - volatile uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */ -} _PackedType t_FmPcdKgSchemeRegsWithoutCounter; - -typedef _Packed struct t_FmPcdKgPortRegs { +typedef struct t_FmPcdKgPortRegs { volatile uint32_t spReg; volatile uint32_t cppReg; -} _PackedType t_FmPcdKgPortRegs; +} t_FmPcdKgPortRegs; -typedef _Packed struct t_HcFrame { +typedef struct t_HcFrame { volatile uint32_t opcode; volatile uint32_t actionReg; volatile uint32_t extraReg; volatile uint32_t commandSequence; union { - t_FmPcdKgInterModuleSchemeRegs schemeRegs; - t_FmPcdKgInterModuleSchemeRegs schemeRegsWithoutCounter; - t_FmPcdPlcrInterModuleProfileRegs profileRegs; + struct fman_kg_scheme_regs schemeRegs; + struct fman_kg_scheme_regs schemeRegsWithoutCounter; + t_FmPcdPlcrProfileRegs profileRegs; volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */ t_FmPcdKgPortRegs portRegsForRead; volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP]; t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout; + t_FmPcdCcReassmTimeoutParams ccReassmTimeout; } hcSpecificData; -} _PackedType t_HcFrame; +} t_HcFrame; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -119,34 +129,102 @@ typedef struct t_FmHc { t_Handle h_HcPortDev; t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */ t_Handle h_QmArg; /**< A handle to the QM module */ - uint8_t padTill16; + uint8_t dataMemId; /**< Memory partition ID for data buffers */ - uint32_t seqNum; - volatile bool wait[32]; + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when + taking buffer */ + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */ + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued + and not confirmed yet */ + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE]; } t_FmHc; -static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, volatile uint32_t *p_SeqNum) +static t_Error FillBufPool(t_FmHc *p_FmHc) +{ + uint32_t i; + + ASSERT_COND(p_FmHc); + + for (i = 0; i < HC_CMD_POOL_SIZE; i++) + { +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))), + p_FmHc->dataMemId, + 16); +#else + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame), + p_FmHc->dataMemId, + 16); +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ + if (!p_FmHc->p_Frm[i]) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!")); + } + + /* Initialize FIFO of seqNum to use during GetBuf */ + for (i = 0; i < HC_CMD_POOL_SIZE; i++) + { + p_FmHc->seqNum[i] = i; + } + p_FmHc->nextSeqNumLocation = 0; + + return E_OK; +} + +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum) +{ + uint32_t intFlags; + + ASSERT_COND(p_FmHc); + + intFlags = FmPcdLock(p_FmHc->h_FmPcd); + + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE) + { + /* No more buffers */ + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); + return NULL; + } + + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation]; + p_FmHc->nextSeqNumLocation++; + + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); + return p_FmHc->p_Frm[*p_SeqNum]; +} + +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum) +{ + uint32_t intFlags; + + UNUSED(p_Buf); + + intFlags = FmPcdLock(p_FmHc->h_FmPcd); + ASSERT_COND(p_FmHc->nextSeqNumLocation); + p_FmHc->nextSeqNumLocation--; + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum; + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); +} + +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum) { t_Error err = E_OK; - uint32_t savedSeqNum; uint32_t intFlags; uint32_t timeout=100; intFlags = FmPcdLock(p_FmHc->h_FmPcd); - *p_SeqNum = p_FmHc->seqNum; - savedSeqNum = p_FmHc->seqNum; - p_FmHc->seqNum = (uint32_t)((p_FmHc->seqNum+1)%32); - ASSERT_COND(!p_FmHc->wait[savedSeqNum]); - p_FmHc->wait[savedSeqNum] = TRUE; + ASSERT_COND(!p_FmHc->enqueued[seqNum]); + p_FmHc->enqueued[seqNum] = TRUE; FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - DBG(TRACE, ("Send Hc, SeqNum %d, FD@0x%x, fd offset 0x%x", - savedSeqNum,DPAA_FD_GET_ADDR(p_FmFd),DPAA_FD_GET_OFFSET(p_FmFd))); + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x", + seqNum, + DPAA_FD_GET_ADDR(p_FmFd), + DPAA_FD_GET_OFFSET(p_FmFd))); err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd); - if(err) + if (err) RETURN_ERROR(MINOR, err, ("HC enqueue failed")); - while (p_FmHc->wait[savedSeqNum] && --timeout) + while (p_FmHc->enqueued[seqNum] && --timeout) XX_UDelay(100); if (!timeout) @@ -155,86 +233,12 @@ static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, volatile uint return err; } -static t_Error CcHcDoDynamicChange(t_FmHc *p_FmHc, t_Handle p_OldPointer, t_Handle p_NewPointer) -{ - t_HcFrame *p_HcFrame; - t_DpaaFD fmFd; - t_Error err = E_OK; - - ASSERT_COND(p_FmHc); - - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); - if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); - - memset(p_HcFrame, 0, sizeof(t_HcFrame)); - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC); - p_HcFrame->actionReg = FmPcdCcGetNodeAddrOffsetFromNodeInfo(p_FmHc->h_FmPcd, p_NewPointer); - if(p_HcFrame->actionReg == (uint32_t)ILLEGAL_BASE) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something wrong with base address")); - } - - p_HcFrame->actionReg |= 0xc0000000; - p_HcFrame->extraReg = FmPcdCcGetNodeAddrOffsetFromNodeInfo(p_FmHc->h_FmPcd, p_OldPointer); - if(p_HcFrame->extraReg == (uint32_t)ILLEGAL_BASE) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something wrong with base address")); - } - - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } - - XX_FreeSmart(p_HcFrame); - - return E_OK; -} - -static t_Error HcDynamicChange(t_FmHc *p_FmHc,t_List *h_OldPointersLst, t_List *h_NewPointersLst, t_Handle *h_Params) -{ - - t_List *p_PosOld, *p_PosNew; - uint16_t i = 0; - t_Error err = E_OK; - uint8_t numOfModifiedPtr; - - SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_NewPointersLst) == LIST_NumOfObjs(h_OldPointersLst)),E_INVALID_STATE); - - numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_NewPointersLst); - p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst); - p_PosOld = NCSW_LIST_FIRST(h_OldPointersLst); - for(i = 0; i < numOfModifiedPtr; i++) - { - err = CcHcDoDynamicChange(p_FmHc, p_PosOld, p_PosNew); - if(err) - { - FmPcdCcReleaseModifiedDataStructure(p_FmHc->h_FmPcd, h_OldPointersLst, h_NewPointersLst, i, h_Params); - RETURN_ERROR(MAJOR, err, ("For part of nodes changes are done - situation is danger")); - } - p_PosNew = NCSW_LIST_NEXT(p_PosNew); - p_PosOld = NCSW_LIST_NEXT(p_PosOld); - } - - err = FmPcdCcReleaseModifiedDataStructure(p_FmHc->h_FmPcd, h_OldPointersLst, h_NewPointersLst, i, h_Params); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - return E_OK; -} - t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams) { t_FmHc *p_FmHc; t_FmPortParams fmPortParam; - t_Error err = E_OK; + t_Error err; p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc)); if (!p_FmHc) @@ -247,17 +251,19 @@ t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams) p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd; p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue; p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg; + p_FmHc->dataMemId = DEFAULT_dataMemId; + + err = FillBufPool(p_FmHc); + if (err != E_OK) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + FmHcFree(p_FmHc); + return NULL; + } if (!FmIsMaster(p_FmHcParams->h_Fm)) return (t_Handle)p_FmHc; -/* -TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle -TKT038900 - FM dma lockup occur due to AXI slave protocol violation -*/ -#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 - p_FmHc->padTill16 = 16 - (sizeof(t_FmHc) % 16); -#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ memset(&fmPortParam, 0, sizeof(fmPortParam)); fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr; fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND; @@ -270,24 +276,36 @@ TKT038900 - FM dma lockup occur due to AXI slave protocol violation fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel; p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam); - if(!p_FmHc->h_HcPortDev) + if (!p_FmHc->h_HcPortDev) { REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!")); XX_Free(p_FmHc); return NULL; } - /* final init */ - if ((err = FM_PORT_Init(p_FmHc->h_HcPortDev)) != E_OK) + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev, + (uint16_t)sizeof(t_HcFrame)); + + if (err != E_OK) { - REPORT_ERROR(MAJOR, err, ("FM HC port!")); + REPORT_ERROR(MAJOR, err, ("FM HC port init!")); FmHcFree(p_FmHc); return NULL; } - if ((err = FM_PORT_Enable(p_FmHc->h_HcPortDev)) != E_OK) + /* final init */ + err = FM_PORT_Init(p_FmHc->h_HcPortDev); + if (err != E_OK) { - REPORT_ERROR(MAJOR, err, ("FM HC port!")); + REPORT_ERROR(MAJOR, err, ("FM HC port init!")); + FmHcFree(p_FmHc); + return NULL; + } + + err = FM_PORT_Enable(p_FmHc->h_HcPortDev); + if (err != E_OK) + { + REPORT_ERROR(MAJOR, err, ("FM HC port enable!")); FmHcFree(p_FmHc); return NULL; } @@ -298,28 +316,40 @@ TKT038900 - FM dma lockup occur due to AXI slave protocol violation void FmHcFree(t_Handle h_FmHc) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + int i; if (!p_FmHc) return; + for (i=0; ip_Frm[i]) + XX_FreeSmart(p_FmHc->p_Frm[i]); + else + break; + if (p_FmHc->h_HcPortDev) FM_PORT_Free(p_FmHc->h_HcPortDev); XX_Free(p_FmHc); } -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FmHcDumpRegs(t_Handle h_FmHc) +/*****************************************************************************/ +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc, + uint8_t memId) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + int i; SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmHc->h_HcPortDev, E_INVALID_HANDLE); - return FM_PORT_DumpRegs(p_FmHc->h_HcPortDev); + p_FmHc->dataMemId = memId; + for (i=0; ip_Frm[i]) + XX_FreeSmart(p_FmHc->p_Frm[i]); + + return FillBufPool(p_FmHc); } -#endif /* (defined(DEBUG_ERRORS) && ... */ void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd) { @@ -335,134 +365,55 @@ void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd) DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x", p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd))); - if (!(p_FmHc->wait[p_HcFrame->commandSequence])) + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence])) REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!")); else - p_FmHc->wait[p_HcFrame->commandSequence] = FALSE; + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE; FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); } -t_Handle FmHcPcdKgSetScheme(t_Handle h_FmHc, t_FmPcdKgSchemeParams *p_Scheme) +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc, + t_Handle h_Scheme, + struct fman_kg_scheme_regs *p_SchemeRegs, + bool updateCounter) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_Error err = E_OK; - t_FmPcdKgInterModuleSchemeRegs schemeRegs; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; - uint32_t intFlags; - uint8_t physicalSchemeId, relativeSchemeId; + uint8_t physicalSchemeId; + uint32_t seqNum; - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - { - REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); - return NULL; - } + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); - if(!p_Scheme->modify) - { - /* check that schemeId is in range */ - if(p_Scheme->id.relativeSchemeId >= FmPcdKgGetNumOfPartitionSchemes(p_FmHc->h_FmPcd)) - { - REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of range")); - XX_FreeSmart(p_HcFrame); - return NULL; - } - - relativeSchemeId = p_Scheme->id.relativeSchemeId; - - if (FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) - { - XX_FreeSmart(p_HcFrame); - return NULL; - } - - physicalSchemeId = FmPcdKgGetPhysicalSchemeId(p_FmHc->h_FmPcd, relativeSchemeId); - - memset(p_HcFrame, 0, sizeof(t_HcFrame)); - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); - p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - p_HcFrame->extraReg = 0xFFFFF800; - - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } - - /* check if this scheme is already used */ - if (FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode)) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is already used")); - XX_FreeSmart(p_HcFrame); - return NULL; - } - } - else - { - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1); - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); - if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } - err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, TRUE); - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - if (err) - { - XX_FreeSmart(p_HcFrame); - return NULL; - } - } - - err = FmPcdKgBuildScheme(p_FmHc->h_FmPcd, p_Scheme, &schemeRegs); - if(err) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - REPORT_ERROR(MAJOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); - p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_Scheme->schemeCounter.update); - p_HcFrame->extraReg = 0xFFFFF800; - memcpy(&p_HcFrame->hcSpecificData.schemeRegs, &schemeRegs, sizeof(t_FmPcdKgInterModuleSchemeRegs)); - if(!p_Scheme->schemeCounter.update) + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter); + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs)); + if (!updateCounter) { - p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = schemeRegs.kgse_dv0; - p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = schemeRegs.kgse_dv1; - p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = schemeRegs.kgse_ccbs; - p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = schemeRegs.kgse_mv; + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0; + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1; + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs; + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv; } + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } + err = EnQFrm(p_FmHc, &fmFd, seqNum); - FmPcdKgValidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId); + PutBuf(p_FmHc, p_HcFrame, seqNum); - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - - return (t_Handle)(UINT_TO_PTR(physicalSchemeId + 1)); + return E_OK; } t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme) @@ -471,151 +422,127 @@ t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme) t_Error err = E_OK; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; - uint8_t relativeSchemeId; - uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); + uint32_t seqNum; - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); - - if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - - if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - } - - err = FmPcdKgCheckInvalidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId); - if (err) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); - } + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); - p_HcFrame->extraReg = 0xFFFFF800; - memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(t_FmPcdKgInterModuleSchemeRegs)); + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs)); + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) RETURN_ERROR(MINOR, err, NO_MSG); - } - - FmPcdKgInvalidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId); - - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - - XX_FreeSmart(p_HcFrame); return E_OK; } -t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction) +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_Error err = E_OK; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; uint8_t relativeSchemeId; - uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); uint32_t tmpReg32 = 0; + uint32_t seqNum; + + /* Scheme is locked by calling routine */ + /* WARNING - this lock will not be efficient if other HC routine will attempt to change + * "kgse_mode" or "kgse_om" without locking scheme ! + */ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); - if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if (FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Lock of the scheme FAILED")); - - if(!FmPcdKgGetPointedOwners(p_FmHc->h_FmPcd, relativeSchemeId) || + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) || !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction)) { - - if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) - { - if((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) && (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)) - + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR)) { - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); - if (!p_HcFrame) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); - } - memset(p_HcFrame, 0, sizeof(t_HcFrame)); - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); - p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - p_HcFrame->extraReg = 0xFFFFF800; - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } - - /* check if this scheme is already used */ - if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode)) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is already used")); - } - tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; - - ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); - - p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; - - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); - p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); - p_HcFrame->extraReg = 0x80000000; - - BUILD_FD(sizeof(t_HcFrame)); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } - - XX_FreeSmart(p_HcFrame); - } - else if (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR) - { - - if((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) || + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) || (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE)) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); - } err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction); - if(err) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - } - } - } - } + } + else /* From here we deal with KG-Schemes only */ + { + /* Pre change general code */ + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + p_HcFrame->commandSequence = seqNum; + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) + { + PutBuf(p_FmHc, p_HcFrame, seqNum); + RETURN_ERROR(MINOR, err, NO_MSG); + } - FmPcdKgUpatePointedOwner(p_FmHc->h_FmPcd, relativeSchemeId,TRUE); - FmPcdKgUpdateRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId,requiredAction); - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); + /* specific change */ + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) && + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME))) + { + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; + } + + if ((requiredAction & UPDATE_KG_NIA_CC_WA) && + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC)) + { + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); + tmpReg32 &= ~NIA_FM_CTL_AC_CC; + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC; + } + + if (requiredAction & UPDATE_KG_OPT_MODE) + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value; + + if (requiredAction & UPDATE_KG_NIA) + { + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK); + tmpReg32 |= value; + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32; + } + + /* Post change general code */ + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + + BUILD_FD(sizeof(t_HcFrame)); + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + } + } return E_OK; } @@ -623,60 +550,53 @@ t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t re uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Error err = E_OK; + t_Error err; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; uint32_t retVal; uint8_t relativeSchemeId; - uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); + uint32_t seqNum; relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); - if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) { REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); return 0; } - if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK) - { - REPORT_ERROR(MAJOR, err, ("Scheme lock")); - return 0; - } - /* first read scheme and check that it is valid */ - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) { - REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); return 0; } memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - p_HcFrame->extraReg = 0xFFFFF800; + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + p_HcFrame->commandSequence = seqNum; BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + err = EnQFrm(p_FmHc, &fmFd, seqNum); + if (err != E_OK) { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); + PutBuf(p_FmHc, p_HcFrame, seqNum); REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); return 0; } if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode)) { + PutBuf(p_FmHc, p_HcFrame, seqNum); REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid")); - XX_FreeSmart(p_HcFrame); return 0; } retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc; - - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); return retVal; } @@ -687,55 +607,31 @@ t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t t_Error err = E_OK; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; - uint8_t relativeSchemeId, physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + uint8_t relativeSchemeId, physicalSchemeId; + uint32_t seqNum; + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); - if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - /* first read scheme and check that it is valid */ - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); - p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - p_HcFrame->extraReg = 0xFFFFF800; - - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } - - /* check that scheme is valid */ - if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode)) - { - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid")); - } - - /* Write scheme back, with modified counter */ - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); - p_HcFrame->extraReg = 0xFFFFF800; + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER; /* write counter */ - p_HcFrame->hcSpecificData.schemeRegs.kgse_spc = value; + p_HcFrame->hcSpecificData.singleRegForWrite = value; + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence); - - FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId); - XX_FreeSmart(p_HcFrame); + err = EnQFrm(p_FmHc, &fmFd, seqNum); + PutBuf(p_FmHc, p_HcFrame, seqNum); return err; } @@ -744,33 +640,37 @@ t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_S t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; - uint32_t i; + uint8_t i, idx; + uint32_t seqNum; t_Error err = E_OK; ASSERT_COND(p_FmHc); - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); - for(i=p_Set->baseEntry;ibaseEntry+p_Set->numOfClsPlanEntries;i+=8) + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8) { memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); - p_HcFrame->extraReg = 0xFFFFF800; - memcpy((void*)&p_HcFrame->hcSpecificData.clsPlanEntries, (void *)&p_Set->vectors[i-p_Set->baseEntry], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + + idx = (uint8_t)(i - p_Set->baseEntry); + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } } - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); return err; } @@ -779,10 +679,10 @@ t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId) t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; - /* clear clsPlan entries in memory */ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); if (!p_ClsPlanSet) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSetd")); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId); @@ -790,9 +690,12 @@ t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId) ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS); if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK) + { + XX_Free(p_ClsPlanSet); RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - XX_Free(p_ClsPlanSet); + } + XX_Free(p_ClsPlanSet); FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId); return E_OK; @@ -802,28 +705,99 @@ t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeo { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_HcFrame *p_HcFrame; - uint32_t intFlags; t_DpaaFD fmFd; t_Error err; + uint32_t seqNum; SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT); memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams)); + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence); + err = EnQFrm(p_FmHc, &fmFd, seqNum); - XX_FreeSmart(p_HcFrame); - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); + PutBuf(p_FmHc, p_HcFrame, seqNum); return err; } +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err; + uint32_t seqNum; + + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION); + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT); + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID; + if (fill == TRUE) + { + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers; + } + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(sizeof(t_HcFrame)); + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) + { + PutBuf(p_FmHc, p_HcFrame, seqNum); + RETURN_ERROR(MINOR, err, NO_MSG); + } + + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg; + + PutBuf(p_FmHc, p_HcFrame, seqNum); + return E_OK; +} + +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err; + uint32_t seqNum; + + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT); + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT); + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt; + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(sizeof(t_HcFrame)); + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) + { + PutBuf(p_FmHc, p_HcFrame, seqNum); + RETURN_ERROR(MINOR, err, NO_MSG); + } + + *p_Result = (uint8_t) + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + return E_OK; +} t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction) { @@ -832,58 +806,49 @@ t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, ui t_DpaaFD fmFd; t_Error err; uint32_t tmpReg32 = 0; - uint32_t requiredActionTmp, pointedOwnersTmp; + uint32_t requiredActionTmp, requiredActionFlag; + uint32_t seqNum; SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); - if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range")); - - if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE)) - return ERROR_CODE(E_BUSY); - + /* Profile is locked by calling routine */ + /* WARNING - this lock will not be efficient if other HC routine will attempt to change + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile ! + */ requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId); - pointedOwnersTmp = FmPcdPlcrGetPointedOwners(p_FmHc->h_FmPcd, absoluteProfileId); + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId); - if(!pointedOwnersTmp || !(requiredActionTmp & requiredAction)) + if (!requiredActionFlag || !(requiredActionTmp & requiredAction)) { - - if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) { - - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); /* first read scheme and check that it is valid */ memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); p_HcFrame->extraReg = 0x00008000; + p_HcFrame->commandSequence = seqNum; BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } - /* check that profile is valid */ - if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode)) + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia; + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used")); + PutBuf(p_FmHc, p_HcFrame, seqNum); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); } - tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia; - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); - } tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); @@ -894,19 +859,19 @@ t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, ui BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia; - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) { - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); } + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); @@ -917,19 +882,19 @@ t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, ui BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia; - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) { - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); } + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); @@ -940,163 +905,81 @@ t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, ui BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } - XX_FreeSmart(p_HcFrame); + + PutBuf(p_FmHc, p_HcFrame, seqNum); } } - FmPcdPlcrUpatePointedOwner(p_FmHc->h_FmPcd, absoluteProfileId, TRUE); - FmPcdPlcrUpdateRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId, requiredAction); - - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - return E_OK; } -t_Handle FmHcPcdPlcrSetProfile(t_Handle h_FmHc,t_FmPcdPlcrProfileParams *p_Profile) +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_FmPcdPlcrInterModuleProfileRegs profileRegs; t_Error err = E_OK; - uint32_t intFlags; uint16_t profileIndx; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; + uint32_t seqNum; - if (p_Profile->modify) - { - profileIndx = (uint16_t)(PTR_TO_UINT(p_Profile->id.h_Profile)-1); - if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, profileIndx, FALSE)) - return NULL; - } - else - { - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - err = FmPcdPlcrGetAbsoluteProfileId(p_FmHc->h_FmPcd, - p_Profile->id.newParams.profileType, - p_Profile->id.newParams.h_FmPort, - p_Profile->id.newParams.relativeProfileId, - &profileIndx); - if (err) - { - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; - } - err = FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, profileIndx, TRUE); - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - if (err) - return NULL; - } - - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - { - REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); - return NULL; - } + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); - if(!p_Profile->modify) - { - memset(p_HcFrame, 0, sizeof(t_HcFrame)); - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); - p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(profileIndx); - p_HcFrame->extraReg = 0x00008000; - - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx); - REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } - - /* check if this scheme is already used */ - if (FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode)) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx); - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used")); - XX_FreeSmart(p_HcFrame); - return NULL; - } - } - - memset(&profileRegs, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs)); - err = FmPcdPlcrBuildProfile(p_FmHc->h_FmPcd, p_Profile, &profileRegs); - if(err) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx); - REPORT_ERROR(MAJOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile); memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx); p_HcFrame->extraReg = 0x00008000; - memcpy(&p_HcFrame->hcSpecificData.profileRegs, &profileRegs, sizeof(t_FmPcdPlcrInterModuleProfileRegs)); + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs)); + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx); - REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return NULL; - } + err = EnQFrm(p_FmHc, &fmFd, seqNum); - FmPcdPlcrValidateProfileSw(p_FmHc->h_FmPcd, profileIndx); + PutBuf(p_FmHc, p_HcFrame, seqNum); - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - - return UINT_TO_PTR((uint64_t)profileIndx+1); + return E_OK; } t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1); + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); t_Error err = E_OK; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; + uint32_t seqNum; - if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE)) - return ERROR_CODE(E_BUSY); - - FmPcdPlcrInvalidateProfileSw(p_FmHc->h_FmPcd, absoluteProfileId); - - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); p_HcFrame->actionReg |= 0x00008000; p_HcFrame->extraReg = 0x00008000; - memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs)); + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs)); + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) RETURN_ERROR(MINOR, err, NO_MSG); - } - - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - - XX_FreeSmart(p_HcFrame); return E_OK; } @@ -1105,58 +988,32 @@ t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmP { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1); + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); t_Error err = E_OK; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; - - if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE)) - return ERROR_CODE(E_BUSY); + uint32_t seqNum; /* first read scheme and check that it is valid */ - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); memset(p_HcFrame, 0, sizeof(t_HcFrame)); - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); - p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); - p_HcFrame->extraReg = 0x00008000; - - BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } - - /* check that profile is valid */ - if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode)) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used")); - } - p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter); p_HcFrame->extraReg = 0x00008000; p_HcFrame->hcSpecificData.singleRegForWrite = value; + p_HcFrame->commandSequence = seqNum; BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) RETURN_ERROR(MINOR, err, NO_MSG); - } - - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - - XX_FreeSmart(p_HcFrame); return E_OK; } @@ -1164,45 +1021,35 @@ t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmP uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1); - t_Error err = E_OK; + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); + t_Error err; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; uint32_t retVal = 0; + uint32_t seqNum; SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); - if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE)) - return 0; - /* first read scheme and check that it is valid */ - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) { - REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); return 0; } memset(p_HcFrame, 0, sizeof(t_HcFrame)); p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); p_HcFrame->extraReg = 0x00008000; + p_HcFrame->commandSequence = seqNum; BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + err = EnQFrm(p_FmHc, &fmFd, seqNum); + if (err != E_OK) { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); + PutBuf(p_FmHc, p_HcFrame, seqNum); REPORT_ERROR(MINOR, err, NO_MSG); - XX_FreeSmart(p_HcFrame); - return 0; - } - - /* check that profile is valid */ - if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode)) - { - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - XX_FreeSmart(p_HcFrame); - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("invalid Policer profile")); return 0; } @@ -1227,310 +1074,40 @@ uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmP REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } - FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId); - - XX_FreeSmart(p_HcFrame); - + PutBuf(p_FmHc, p_HcFrame, seqNum); return retVal; } -t_Error FmHcPcdCcModifyTreeNextEngine(t_Handle h_FmHc, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Error err = E_OK; - uint32_t intFlags; - t_List h_OldPointersLst, h_NewPointersLst; - t_Handle h_Params; - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - err = FmPcdCcTreeTryLock(h_CcTree); - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - if (err) - return err; - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - err = FmPcdCcModifyNextEngineParamTree(p_FmHc->h_FmPcd, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams, - &h_OldPointersLst, &h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcTreeReleaseLock(h_CcTree); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcTreeReleaseLock(h_CcTree); - - return err; -} - - -t_Error FmHcPcdCcModifyNodeMissNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Handle h_Params; - t_List h_OldPointersLst, h_NewPointersLst; - t_Error err = E_OK; - t_List h_List; - uint32_t intFlags; - - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - err = FmPcdCcModifyMissNextEngineParamNode(p_FmHc->h_FmPcd, h_CcNode, p_FmPcdCcNextEngineParams, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcNodeTreeReleaseLock(&h_List); - - - return E_OK; -} - -t_Error FmHcPcdCcRemoveKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Handle h_Params; - t_List h_OldPointersLst, h_NewPointersLst; - t_Error err = E_OK; - t_List h_List; - uint32_t intFlags; - - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - - err = FmPcdCcRemoveKey(p_FmHc->h_FmPcd,h_CcNode,keyIndex, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcNodeTreeReleaseLock(&h_List); - - return err; - -} - -t_Error FmHcPcdCcAddKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Handle h_Params; - t_List h_OldPointersLst, h_NewPointersLst; - t_Error err = E_OK; - t_List h_List; - uint32_t intFlags; - - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - - err = FmPcdCcAddKey(p_FmHc->h_FmPcd,h_CcNode,keyIndex,keySize, p_KeyParams, &h_OldPointersLst,&h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcNodeTreeReleaseLock(&h_List); - - return err; -} - - -t_Error FmHcPcdCcModifyKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_List h_OldPointersLst, h_NewPointersLst; - t_Error err = E_OK; - t_List h_List; - uint32_t intFlags; - t_Handle h_Params; - - UNUSED(keySize); - - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - err = FmPcdCcModifyKey(p_FmHc->h_FmPcd, h_CcNode, keyIndex, keySize, p_Key, p_Mask, &h_OldPointersLst,&h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcNodeTreeReleaseLock(&h_List); - - return err; -} - -t_Error FmHcPcdCcModifyNodeNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_Error err = E_OK; - t_List h_OldPointersLst, h_NewPointersLst; - t_List h_List; - uint32_t intFlags; - t_Handle h_Params; - - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - - err = FmPcdCcModiyNextEngineParamNode(p_FmHc->h_FmPcd, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - FmPcdCcNodeTreeReleaseLock(&h_List); - return err; -} - - -t_Error FmHcPcdCcModifyKeyAndNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams) -{ - t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; - t_List h_OldPointersLst, h_NewPointersLst; - t_Error err = E_OK; - t_List h_List; - uint32_t intFlags; - t_Handle h_Params; - - INIT_LIST(&h_OldPointersLst); - INIT_LIST(&h_NewPointersLst); - INIT_LIST(&h_List); - - intFlags = FmPcdLock(p_FmHc->h_FmPcd); - - if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK) - { - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - return err; - } - - FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); - - - err = FmPcdCcModifyKeyAndNextEngine(p_FmHc->h_FmPcd,h_CcNode,keyIndex,keySize, p_KeyParams, &h_OldPointersLst,&h_NewPointersLst, &h_Params); - if(err) - { - FmPcdCcNodeTreeReleaseLock(&h_List); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params); - - FmPcdCcNodeTreeReleaseLock(&h_List); - - - return err; -} - - t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add) { t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; t_HcFrame *p_HcFrame; t_DpaaFD fmFd; t_Error err = E_OK; + uint32_t seqNum; ASSERT_COND(p_FmHc); - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); memset(p_HcFrame, 0, sizeof(t_HcFrame)); /* first read SP register */ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); - p_HcFrame->extraReg = 0xFFFFF800; + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; + p_HcFrame->commandSequence = seqNum; BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) { - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); RETURN_ERROR(MINOR, err, NO_MSG); } /* spReg is the first reg, so we can use it both for read and for write */ - if(add) + if (add) p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg; else p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg; @@ -1539,13 +1116,12 @@ t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, b BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } + err = EnQFrm(p_FmHc, &fmFd, seqNum); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); return E_OK; } @@ -1556,29 +1132,100 @@ t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg) t_HcFrame *p_HcFrame; t_DpaaFD fmFd; t_Error err = E_OK; + uint32_t seqNum; ASSERT_COND(p_FmHc); - p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16); + p_HcFrame = GetBuf(p_FmHc, &seqNum); if (!p_HcFrame) - RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj")); + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); memset(p_HcFrame, 0, sizeof(t_HcFrame)); /* first read SP register */ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); - p_HcFrame->extraReg = 0xFFFFF800; + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; p_HcFrame->hcSpecificData.singleRegForWrite = cppReg; + p_HcFrame->commandSequence = seqNum; BUILD_FD(sizeof(t_HcFrame)); - if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK) - { - XX_FreeSmart(p_HcFrame); - RETURN_ERROR(MINOR, err, NO_MSG); - } + err = EnQFrm(p_FmHc, &fmFd, seqNum); - XX_FreeSmart(p_HcFrame); + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); return E_OK; } +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err = E_OK; + uint32_t seqNum; + + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC); + p_HcFrame->actionReg = newAdAddrOffset; + p_HcFrame->actionReg |= 0xc0000000; + p_HcFrame->extraReg = oldAdAddrOffset; + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); + + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FmHcPcdSync(t_Handle h_FmHc) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + t_HcFrame *p_HcFrame; + t_DpaaFD fmFd; + t_Error err = E_OK; + uint32_t seqNum; + + ASSERT_COND(p_FmHc); + + p_HcFrame = GetBuf(p_FmHc, &seqNum); + if (!p_HcFrame) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); + memset(p_HcFrame, 0, sizeof(t_HcFrame)); + /* first read SP register */ + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC); + p_HcFrame->actionReg = 0; + p_HcFrame->extraReg = 0; + p_HcFrame->commandSequence = seqNum; + + BUILD_FD(sizeof(t_HcFrame)); + + err = EnQFrm(p_FmHc, &fmFd, seqNum); + + PutBuf(p_FmHc, p_HcFrame, seqNum); + + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return E_OK; +} + +t_Handle FmHcGetPort(t_Handle h_FmHc) +{ + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; + return p_FmHc->h_HcPortDev; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c index d543132b0f02..b6a18340efe9 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ /****************************************************************************** @File dtsec.c - @Description FM dTSEC ... + @Description FMan dTSEC driver *//***************************************************************************/ #include "std_ext.h" @@ -41,12 +41,13 @@ #include "string_ext.h" #include "xx_ext.h" #include "endian_ext.h" -#include "crc_mac_addr_ext.h" #include "debug_ext.h" +#include "crc_mac_addr_ext.h" #include "fm_common.h" #include "dtsec.h" - +#include "fsl_fman_dtsec.h" +#include "fsl_fman_dtsec_mii_acc.h" /*****************************************************************************/ /* Internal routines */ @@ -54,255 +55,141 @@ static t_Error CheckInitParameters(t_Dtsec *p_Dtsec) { - if(ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000) + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds")); - if(p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS) + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs")); - if(p_Dtsec->addr == 0) + if (p_Dtsec->addr == 0) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address")); - if(((p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) && - p_Dtsec->p_DtsecDriverParam->halfDuplex) + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) && + p_Dtsec->p_DtsecDriverParam->halfdup_on) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex")); - if(p_Dtsec->p_DtsecDriverParam->halfDuplex && (p_Dtsec->p_DtsecDriverParam)->loopback) + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode")); -#ifdef FM_NO_RX_PREAM_ERRATA_DTSECx1 - if(p_Dtsec->p_DtsecDriverParam->preambleRxEn) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn")); -#endif /* FM_NO_RX_PREAM_ERRATA_DTSECx1 */ - if(((p_Dtsec->p_DtsecDriverParam)->preambleTxEn || (p_Dtsec->p_DtsecDriverParam)->preambleRxEn) &&( (p_Dtsec->p_DtsecDriverParam)->preambleLength != 0x7)) +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */ + if (p_Dtsec->p_DtsecDriverParam->rx_preamble) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn")); +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */ + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes")); - if((p_Dtsec->p_DtsecDriverParam)->fifoTxWatermarkH<((p_Dtsec->p_DtsecDriverParam)->fifoTxThr+8)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoTxWatermarkH has to be at least 8 larger than fifoTxThr")); - if((p_Dtsec->p_DtsecDriverParam)->halfDuplex && - (p_Dtsec->p_DtsecDriverParam->txTimeStampEn || p_Dtsec->p_DtsecDriverParam->rxTimeStampEn)) + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on && + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable")); - if((p_Dtsec->p_DtsecDriverParam)->actOnRxPauseFrame && (p_Dtsec->p_DtsecDriverParam)->controlFrameAccept ) + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc ) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept ")); - if((p_Dtsec->p_DtsecDriverParam)->packetAlignmentPadding > MAX_PACKET_ALIGNMENT) + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT )); - if(((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg1 > MAX_INTER_PACKET_GAP) || - ((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg2 > MAX_INTER_PACKET_GAP) || - ((p_Dtsec->p_DtsecDriverParam)->backToBackIpg > MAX_INTER_PACKET_GAP)) + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) || + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) || + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP)) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP )); - if((p_Dtsec->p_DtsecDriverParam)->alternateBackoffVal > MAX_INTER_PALTERNATE_BEB) + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB )); - if((p_Dtsec->p_DtsecDriverParam)->maxRetransmission > MAX_RETRANSMISSION) + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION )); - if((p_Dtsec->p_DtsecDriverParam)->collisionWindow > MAX_COLLISION_WINDOW) + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW )); /* If Auto negotiation process is disabled, need to */ /* Set up the PHY using the MII Management Interface */ - if (p_Dtsec->p_DtsecDriverParam->tbiPhyAddr > MAX_PHYS) + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS)); - if(!p_Dtsec->f_Exception) + if (!p_Dtsec->f_Exception) RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception")); - if(!p_Dtsec->f_Event) + if (!p_Dtsec->f_Event) RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event")); + +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ + return E_OK; } -static uint8_t GetMiiDiv(int32_t refClk) +/* ......................................................................... */ + +static uint32_t GetMacAddrHashCode(uint64_t ethAddr) { - uint32_t div,tmpClk; - int minRange; + uint32_t crc; - div = 1; - minRange = (int)(refClk/40 - 1); + /* CRC calculation */ + GET_MAC_ADDR_CRC(ethAddr, crc); - tmpClk = (uint32_t)ABS(refClk/60 - 1); - if (tmpClk < minRange) - { - div = 2; - minRange = (int)tmpClk; - } - tmpClk = (uint32_t)ABS(refClk/60 - 1); - if (tmpClk < minRange) - { - div = 3; - minRange = (int)tmpClk; - } - tmpClk = (uint32_t)ABS(refClk/80 - 1); - if (tmpClk < minRange) - { - div = 4; - minRange = (int)tmpClk; - } - tmpClk = (uint32_t)ABS(refClk/100 - 1); - if (tmpClk < minRange) - { - div = 5; - minRange = (int)tmpClk; - } - tmpClk = (uint32_t)ABS(refClk/140 - 1); - if (tmpClk < minRange) - { - div = 6; - minRange = (int)tmpClk; - } - tmpClk = (uint32_t)ABS(refClk/280 - 1); - if (tmpClk < minRange) - { - div = 7; - minRange = (int)tmpClk; - } + crc = GetMirror32(crc); - return (uint8_t)div; + return crc; } -/* ........................................................................... */ - -static void SetDefaultParam(t_DtsecDriverParam *p_DtsecDriverParam) -{ - p_DtsecDriverParam->errorDisabled = DEFAULT_errorDisabled; - - p_DtsecDriverParam->promiscuousEnable = DEFAULT_promiscuousEnable; - - p_DtsecDriverParam->pauseExtended = DEFAULT_pauseExtended; - p_DtsecDriverParam->pauseTime = DEFAULT_pauseTime; - - p_DtsecDriverParam->halfDuplex = DEFAULT_halfDuplex; - p_DtsecDriverParam->halfDulexFlowControlEn = DEFAULT_halfDulexFlowControlEn; - p_DtsecDriverParam->txTimeStampEn = DEFAULT_txTimeStampEn; - p_DtsecDriverParam->rxTimeStampEn = DEFAULT_rxTimeStampEn; - - p_DtsecDriverParam->packetAlignmentPadding = DEFAULT_packetAlignment; - p_DtsecDriverParam->controlFrameAccept = DEFAULT_controlFrameAccept; - p_DtsecDriverParam->groupHashExtend = DEFAULT_groupHashExtend; - p_DtsecDriverParam->broadcReject = DEFAULT_broadcReject; - p_DtsecDriverParam->rxShortFrame = DEFAULT_rxShortFrame; - p_DtsecDriverParam->exactMatch = DEFAULT_exactMatch; - p_DtsecDriverParam->debugMode = DEFAULT_debugMode; - - p_DtsecDriverParam->loopback = DEFAULT_loopback; - p_DtsecDriverParam->tbiPhyAddr = DEFAULT_tbiPhyAddr; - p_DtsecDriverParam->actOnRxPauseFrame = DEFAULT_actOnRxPauseFrame; - p_DtsecDriverParam->actOnTxPauseFrame = DEFAULT_actOnTxPauseFrame; - - p_DtsecDriverParam->preambleLength = DEFAULT_PreAmLength; - p_DtsecDriverParam->preambleRxEn = DEFAULT_PreAmRxEn; - p_DtsecDriverParam->preambleTxEn = DEFAULT_PreAmTxEn; - p_DtsecDriverParam->lengthCheckEnable = DEFAULT_lengthCheckEnable; - p_DtsecDriverParam->padAndCrcEnable = DEFAULT_padAndCrcEnable; - p_DtsecDriverParam->crcEnable = DEFAULT_crcEnable; - - p_DtsecDriverParam->nonBackToBackIpg1 = DEFAULT_nonBackToBackIpg1; - p_DtsecDriverParam->nonBackToBackIpg2 = DEFAULT_nonBackToBackIpg2; - p_DtsecDriverParam->minIfgEnforcement = DEFAULT_minIfgEnforcement; - p_DtsecDriverParam->backToBackIpg = DEFAULT_backToBackIpg; - - p_DtsecDriverParam->alternateBackoffVal = DEFAULT_altBackoffVal; - p_DtsecDriverParam->alternateBackoffEnable = DEFAULT_altBackoffEnable; - p_DtsecDriverParam->backPressureNoBackoff = DEFAULT_backPressureNoBackoff; - p_DtsecDriverParam->noBackoff = DEFAULT_noBackoff; - p_DtsecDriverParam->excessDefer = DEFAULT_excessDefer; - p_DtsecDriverParam->maxRetransmission = DEFAULT_maxRetransmission; - p_DtsecDriverParam->collisionWindow = DEFAULT_collisionWindow; - - p_DtsecDriverParam->maxFrameLength = DEFAULT_maxFrameLength; - - p_DtsecDriverParam->fifoTxThr = DEFAULT_fifoTxThr; - p_DtsecDriverParam->fifoTxWatermarkH = DEFAULT_fifoTxWatermarkH; - - p_DtsecDriverParam->fifoRxWatermarkL = DEFAULT_fifoRxWatermarkL; -} - -static void DtsecException(t_Handle h_Dtsec) -{ - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - uint32_t event; - t_DtsecMemMap *p_DtsecMemMap; - - ASSERT_COND(p_Dtsec); - p_DtsecMemMap = p_Dtsec->p_MemMap; - ASSERT_COND(p_DtsecMemMap); - - event = GET_UINT32(p_DtsecMemMap->ievent); - /* handle only MDIO events */ - event &= (IMASK_MMRDEN | IMASK_MMWREN); - if(event) - { - event &= GET_UINT32(p_DtsecMemMap->imask); - - WRITE_UINT32(p_DtsecMemMap->ievent, event); - - if(event & IMASK_MMRDEN) - p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET); - if(event & IMASK_MMWREN) - p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET); - } -} +/* ......................................................................... */ static void UpdateStatistics(t_Dtsec *p_Dtsec) { - t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; - uint32_t car1 = GET_UINT32(p_DtsecMemMap->car1); - uint32_t car2 = GET_UINT32(p_DtsecMemMap->car2); + uint32_t car1, car2; - if(car1) + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2); + + if (car1) { - WRITE_UINT32(p_DtsecMemMap->car1, car1); - if(car1 & CAR1_TR64) + if (car1 & CAR1_TR64) p_Dtsec->internalStatistics.tr64 += VAL22BIT; - if(car1 & CAR1_TR127) + if (car1 & CAR1_TR127) p_Dtsec->internalStatistics.tr127 += VAL22BIT; - if(car1 & CAR1_TR255) + if (car1 & CAR1_TR255) p_Dtsec->internalStatistics.tr255 += VAL22BIT; - if(car1 & CAR1_TR511) + if (car1 & CAR1_TR511) p_Dtsec->internalStatistics.tr511 += VAL22BIT; - if(car1 & CAR1_TRK1) + if (car1 & CAR1_TRK1) p_Dtsec->internalStatistics.tr1k += VAL22BIT; - if(car1 & CAR1_TRMAX) + if (car1 & CAR1_TRMAX) p_Dtsec->internalStatistics.trmax += VAL22BIT; - if(car1 & CAR1_TRMGV) + if (car1 & CAR1_TRMGV) p_Dtsec->internalStatistics.trmgv += VAL22BIT; - if(car1 & CAR1_RBYT) + if (car1 & CAR1_RBYT) p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT; - if(car1 & CAR1_RPKT) + if (car1 & CAR1_RPKT) p_Dtsec->internalStatistics.rpkt += VAL22BIT; - if(car1 & CAR1_RMCA) + if (car1 & CAR1_RMCA) p_Dtsec->internalStatistics.rmca += VAL22BIT; - if(car1 & CAR1_RBCA) + if (car1 & CAR1_RBCA) p_Dtsec->internalStatistics.rbca += VAL22BIT; - if(car1 & CAR1_RXPF) + if (car1 & CAR1_RXPF) p_Dtsec->internalStatistics.rxpf += VAL16BIT; - if(car1 & CAR1_RALN) + if (car1 & CAR1_RALN) p_Dtsec->internalStatistics.raln += VAL16BIT; - if(car1 & CAR1_RFLR) + if (car1 & CAR1_RFLR) p_Dtsec->internalStatistics.rflr += VAL16BIT; - if(car1 & CAR1_RCDE) + if (car1 & CAR1_RCDE) p_Dtsec->internalStatistics.rcde += VAL16BIT; - if(car1 & CAR1_RCSE) + if (car1 & CAR1_RCSE) p_Dtsec->internalStatistics.rcse += VAL16BIT; - if(car1 & CAR1_RUND) + if (car1 & CAR1_RUND) p_Dtsec->internalStatistics.rund += VAL16BIT; - if(car1 & CAR1_ROVR) + if (car1 & CAR1_ROVR) p_Dtsec->internalStatistics.rovr += VAL16BIT; - if(car1 & CAR1_RFRG) + if (car1 & CAR1_RFRG) p_Dtsec->internalStatistics.rfrg += VAL16BIT; - if(car1 & CAR1_RJBR) + if (car1 & CAR1_RJBR) p_Dtsec->internalStatistics.rjbr += VAL16BIT; - if(car1 & CAR1_RDRP) + if (car1 & CAR1_RDRP) p_Dtsec->internalStatistics.rdrp += VAL16BIT; } - if(car2) + if (car2) { - WRITE_UINT32(p_DtsecMemMap->car2, car2); - if(car2 & CAR2_TFCS) + if (car2 & CAR2_TFCS) p_Dtsec->internalStatistics.tfcs += VAL12BIT; - if(car2 & CAR2_TBYT) + if (car2 & CAR2_TBYT) p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT; - if(car2 & CAR2_TPKT) + if (car2 & CAR2_TPKT) p_Dtsec->internalStatistics.tpkt += VAL22BIT; - if(car2 & CAR2_TMCA) + if (car2 & CAR2_TMCA) p_Dtsec->internalStatistics.tmca += VAL22BIT; - if(car2 & CAR2_TBCA) + if (car2 & CAR2_TBCA) p_Dtsec->internalStatistics.tbca += VAL22BIT; - if(car2 & CAR2_TXPF) + if (car2 & CAR2_TXPF) p_Dtsec->internalStatistics.txpf += VAL16BIT; - if(car2 & CAR2_TDRP) + if (car2 & CAR2_TDRP) p_Dtsec->internalStatistics.tdrp += VAL16BIT; } } @@ -311,145 +198,163 @@ static void UpdateStatistics(t_Dtsec *p_Dtsec) static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0); - return (uint16_t)GET_UINT32(p_Dtsec->p_MemMap->maxfrm); + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap); } -static void DtsecErrException(t_Handle h_Dtsec) +/* .............................................................................. */ + +static void DtsecIsr(t_Handle h_Dtsec) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; uint32_t event; - t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; - event = GET_UINT32(p_DtsecMemMap->ievent); /* do not handle MDIO events */ - event &= ~(IMASK_MMRDEN | IMASK_MMWREN); + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN))); - event &= GET_UINT32(p_DtsecMemMap->imask); + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap); - WRITE_UINT32(p_DtsecMemMap->ievent, event); + fman_dtsec_ack_event(p_DtsecMemMap, event); - if(event & IMASK_BREN) + if (event & DTSEC_IMASK_BREN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX); - if(event & IMASK_RXCEN) + if (event & DTSEC_IMASK_RXCEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL); - if(event & IMASK_MSROEN) + if (event & DTSEC_IMASK_MSROEN) UpdateStatistics(p_Dtsec); - if(event & IMASK_GTSCEN) + if (event & DTSEC_IMASK_GTSCEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET); - if(event & IMASK_BTEN) + if (event & DTSEC_IMASK_BTEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX); - if(event & IMASK_TXCEN) + if (event & DTSEC_IMASK_TXCEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL); - if(event & IMASK_TXEEN) + if (event & DTSEC_IMASK_TXEEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR); - if(event & IMASK_LCEN) + if (event & DTSEC_IMASK_LCEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL); - if(event & IMASK_CRLEN) + if (event & DTSEC_IMASK_CRLEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT); - if(event & IMASK_XFUNEN) + if (event & DTSEC_IMASK_XFUNEN) { #ifdef FM_TX_LOCKUP_ERRATA_DTSEC6 - uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i; - /* a. Write 0x00E0_0C00 to DTSEC_ID */ - /* This is a read only regidter */ - - /* b. Read and save the value of TPKT */ - tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt); - - /* c. Read the register at dTSEC address offset 0x32C */ - tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); - - /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */ - if((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F)) + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) { - /* If they are not equal, save the value of this register and wait for at least - * MAXFRM*16 ns */ - XX_UDelay((uint32_t)(NCSW_MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1))); - } + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i; + /* a. Write 0x00E0_0C00 to DTSEC_ID */ + /* This is a read only regidter */ - /* e. Read and save TPKT again and read the register at dTSEC address offset - 0x32C again*/ - tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt); - tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); + /* b. Read and save the value of TPKT */ + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt); - /* f. Compare the value of TPKT saved in step b to value read in step e. Also - compare bits [9:15] of the register at offset 0x32C saved in step d to the value - of bits [9:15] saved in step e. If the two registers values are unchanged, then - the transmit portion of the dTSEC controller is locked up and the user should - proceed to the recover sequence. */ - if((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000))) - { - /* recover sequence */ + /* c. Read the register at dTSEC address offset 0x32C */ + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); - /* a.Write a 1 to RCTRL[GRS]*/ - - WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS); - - /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */ - for(i = 0 ; i < 100 ; i++ ) + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */ + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F)) { - if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN) - break; - XX_UDelay(1); + /* If they are not equal, save the value of this register and wait for at least + * MAXFRM*16 ns */ + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1))); } - if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN) - WRITE_UINT32(p_DtsecMemMap->ievent, IMASK_GRSCEN); - else - DBG(INFO,("Rx lockup due to dTSEC Tx lockup")); + /* e. Read and save TPKT again and read the register at dTSEC address offset + 0x32C again*/ + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt); + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); - /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/ - FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId); + /* f. Compare the value of TPKT saved in step b to value read in step e. Also + compare bits [9:15] of the register at offset 0x32C saved in step d to the value + of bits [9:15] saved in step e. If the two registers values are unchanged, then + the transmit portion of the dTSEC controller is locked up and the user should + proceed to the recover sequence. */ + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000))) + { + /* recover sequence */ - /* d.Wait 4 Tx clocks (32 ns) */ - XX_UDelay(1); + /* a.Write a 1 to RCTRL[GRS]*/ - /* e.Write a 0 to bit n of FM_RSTC. */ - /* cleared by FMAN */ - } - else - { - /* If either value has changed, the dTSEC controller is not locked up and the - controller should be allowed to proceed normally by writing the reset value - of 0x0824_0101 to DTSEC_ID. */ - /* Register is read only */ + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS); + + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */ + for (i = 0 ; i < 100 ; i++ ) + { + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN) + break; + XX_UDelay(1); + } + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN) + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN); + else + DBG(INFO,("Rx lockup due to dTSEC Tx lockup")); + + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/ + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId); + + /* d.Wait 4 Tx clocks (32 ns) */ + XX_UDelay(1); + + /* e.Write a 0 to bit n of FM_RSTC. */ + /* cleared by FMAN */ + } } #endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN); } - if(event & IMASK_MAGEN) + if (event & DTSEC_IMASK_MAGEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT); - if(event & IMASK_GRSCEN) + if (event & DTSEC_IMASK_GRSCEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET); - if(event & IMASK_TDPEEN) + if (event & DTSEC_IMASK_TDPEEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR); - if(event & IMASK_RDPEEN) + if (event & DTSEC_IMASK_RDPEEN) p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR); /* - masked interrupts */ - ASSERT_COND(!(event & IMASK_ABRTEN)); - ASSERT_COND(!(event & IMASK_IFERREN)); + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN)); + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN)); } -static void Dtsec1588Exception(t_Handle h_Dtsec) +static void DtsecMdioIsr(t_Handle h_Dtsec) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; uint32_t event; - t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap; + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; + + event = GET_UINT32(p_DtsecMemMap->ievent); + /* handle only MDIO events */ + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN); + if (event) + { + event &= GET_UINT32(p_DtsecMemMap->imask); + + WRITE_UINT32(p_DtsecMemMap->ievent, event); + + if (event & DTSEC_IMASK_MMRDEN) + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET); + if (event & DTSEC_IMASK_MMWREN) + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET); + } +} + +static void Dtsec1588Isr(t_Handle h_Dtsec) +{ + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + uint32_t event; + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; if (p_Dtsec->ptpTsuEnabled) { - event = GET_UINT32(p_DtsecMemMap->tmr_pevent); - event &= GET_UINT32(p_DtsecMemMap->tmr_pemask); - if(event) + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap); + + if (event) { - WRITE_UINT32(p_DtsecMemMap->tmr_pevent, event); - ASSERT_COND(event & PEMASK_TSRE); + ASSERT_COND(event & TMR_PEVENT_TSRE); p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR); } } @@ -459,16 +364,13 @@ static void Dtsec1588Exception(t_Handle h_Dtsec) static void FreeInitResources(t_Dtsec *p_Dtsec) { - /*TODO - need to ask why with mdioIrq != 0*/ - if ((p_Dtsec->mdioIrq != 0) && (p_Dtsec->mdioIrq != NO_IRQ)) + if (p_Dtsec->mdioIrq != NO_IRQ) { XX_DisableIntr(p_Dtsec->mdioIrq); XX_FreeIntr(p_Dtsec->mdioIrq); } - else if (p_Dtsec->mdioIrq == 0) - FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR); - FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); /* release the driver's group hash table */ FreeHashTable(p_Dtsec->p_MulticastAddrHash); @@ -481,56 +383,41 @@ static void FreeInitResources(t_Dtsec *p_Dtsec) /* ........................................................................... */ -static void HardwareClearAddrInPaddr(t_Dtsec *p_Dtsec, uint8_t paddrNum) -{ - WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match1, 0x0); - WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match2, 0x0); -} - -/* ........................................................................... */ - -static void HardwareAddAddrInPaddr(t_Dtsec *p_Dtsec, uint64_t *p_Addr, uint8_t paddrNum) -{ - uint32_t tmpReg32 = 0; - uint64_t addr = *p_Addr; - t_DtsecMemMap *p_DtsecMemMap = (t_DtsecMemMap*)p_Dtsec->p_MemMap; - - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match1, tmpReg32); - - tmpReg32 = (uint32_t)(addr>>32); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match2, tmpReg32); -} - -/* ........................................................................... */ - static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode) { - t_DtsecMemMap *p_MemMap; + struct dtsec_regs *p_MemMap; ASSERT_COND(p_Dtsec); - p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); + p_MemMap = p_Dtsec->p_MemMap; ASSERT_COND(p_MemMap); /* Assert the graceful transmit stop bit */ if (mode & e_COMM_MODE_RX) - WRITE_UINT32(p_MemMap->rctrl, - GET_UINT32(p_MemMap->rctrl) | RCTRL_GRS); + { + fman_dtsec_stop_rx(p_MemMap); #ifdef FM_GRS_ERRATA_DTSEC_A002 - XX_UDelay(100); + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) + XX_UDelay(100); +#else /* FM_GRS_ERRATA_DTSEC_A002 */ +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 + XX_UDelay(10); +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */ #endif /* FM_GRS_ERRATA_DTSEC_A002 */ + } -#ifdef FM_GTS_ERRATA_DTSEC_A004 - DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); -#else /* not FM_GTS_ERRATA_DTSEC_A004 */ if (mode & e_COMM_MODE_TX) - WRITE_UINT32(p_MemMap->tctrl, - GET_UINT32(p_MemMap->tctrl) | TCTRL_GTS); -#endif /* not FM_GTS_ERRATA_DTSEC_A004 */ +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata.")); +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ + fman_dtsec_stop_tx(p_MemMap); +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ return E_OK; } @@ -539,21 +426,18 @@ static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode) static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode) { - t_DtsecMemMap *p_MemMap; + struct dtsec_regs *p_MemMap; ASSERT_COND(p_Dtsec); - - p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); + p_MemMap = p_Dtsec->p_MemMap; ASSERT_COND(p_MemMap); /* clear the graceful receive stop bit */ - if(mode & e_COMM_MODE_TX) - WRITE_UINT32(p_MemMap->tctrl, - GET_UINT32(p_MemMap->tctrl) & ~TCTRL_GTS); + if (mode & e_COMM_MODE_TX) + fman_dtsec_start_tx(p_MemMap); - if(mode & e_COMM_MODE_RX) - WRITE_UINT32(p_MemMap->rctrl, - GET_UINT32(p_MemMap->rctrl) & ~RCTRL_GRS); + if (mode & e_COMM_MODE_RX) + fman_dtsec_start_rx(p_MemMap); return E_OK; } @@ -563,7 +447,6 @@ static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode) /* dTSEC Configs modification functions */ /*****************************************************************************/ - /* .............................................................................. */ static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal) @@ -588,7 +471,7 @@ static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal) SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_Dtsec->p_DtsecDriverParam->maxFrameLength = newVal; + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal; return E_OK; } @@ -602,7 +485,7 @@ static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal) SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_Dtsec->p_DtsecDriverParam->padAndCrcEnable = newVal; + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal; return E_OK; } @@ -616,7 +499,21 @@ static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal) SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_Dtsec->p_DtsecDriverParam->halfDuplex = newVal; + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal; + + return E_OK; +} + +/* .............................................................................. */ + +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal) +{ + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); + + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal; return E_OK; } @@ -625,22 +522,18 @@ static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal) static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal) { -#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 -UNUSED(h_Dtsec); - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); - -#else t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_Dtsec->p_DtsecDriverParam->lengthCheckEnable = newVal; + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal; return E_OK; -#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ } +/* .............................................................................. */ + static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; @@ -649,10 +542,10 @@ static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exceptio SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) { GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) + if (bitMask) { if (enable) p_Dtsec->exceptions |= bitMask; @@ -664,21 +557,19 @@ static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exceptio } else { - if(!p_Dtsec->ptpTsuEnabled) + if (!p_Dtsec->ptpTsuEnabled) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); - switch(exception){ - case(e_FM_MAC_EX_1G_1588_TS_RX_ERR): - if(enable) - p_Dtsec->enTsuErrExeption = TRUE; - else - p_Dtsec->enTsuErrExeption = FALSE; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - } + + if (enable) + p_Dtsec->enTsuErrExeption = TRUE; + else + p_Dtsec->enTsuErrExeption = FALSE; } + return E_OK; } + + /*****************************************************************************/ /* dTSEC Run Time API functions */ /*****************************************************************************/ @@ -687,21 +578,14 @@ static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exceptio static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_MemMap ; - uint32_t tmpReg32 = 0; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap); - - tmpReg32 = GET_UINT32(p_MemMap->maccfg1); - if (mode & e_COMM_MODE_RX) - tmpReg32 |= MACCFG1_RX_EN; - if (mode & e_COMM_MODE_TX) - tmpReg32 |= MACCFG1_TX_EN; - WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); + fman_dtsec_enable(p_Dtsec->p_MemMap, + (bool)!!(mode & e_COMM_MODE_RX), + (bool)!!(mode & e_COMM_MODE_TX)); GracefulRestart(p_Dtsec, mode); @@ -712,132 +596,94 @@ static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode) static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_MemMap ; - uint32_t tmpReg32 = 0; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE); - - p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); GracefulStop(p_Dtsec, mode); - tmpReg32 = GET_UINT32(p_MemMap->maccfg1); - if (mode & e_COMM_MODE_RX) - tmpReg32 &= ~MACCFG1_RX_EN; - if (mode & e_COMM_MODE_TX) - tmpReg32 &= ~MACCFG1_TX_EN; - WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); + fman_dtsec_disable(p_Dtsec->p_MemMap, + (bool)!!(mode & e_COMM_MODE_RX), + (bool)!!(mode & e_COMM_MODE_TX)); return E_OK; } /* .............................................................................. */ -static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime) +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - uint32_t ptv = 0; - t_DtsecMemMap *p_MemMap; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + + UNUSED(priority);UNUSED(threshTime); SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); - p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); - - if (pauseTime) - { #ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 - { - if (pauseTime <= 320) - RETURN_ERROR(MINOR, E_INVALID_VALUE, - ("This pause-time value of %d is illegal due to errata dTSEC-A003!" - " value should be greater than 320.")); - } + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) + if (0 < pauseTime && pauseTime <= 320) + RETURN_ERROR(MINOR, E_INVALID_VALUE, + ("This pause-time value of %d is illegal due to errata dTSEC-A003!" + " value should be greater than 320.")); #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */ -#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - pauseTime += 2; - } -#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ - - ptv = GET_UINT32(p_MemMap->ptv); - ptv |= pauseTime; - WRITE_UINT32(p_MemMap->ptv, ptv); - - /* trigger the transmission of a flow-control pause frame */ - WRITE_UINT32(p_MemMap->maccfg1, - GET_UINT32(p_MemMap->maccfg1) | MACCFG1_TX_FLOW); - } - else - { - WRITE_UINT32(p_MemMap->maccfg1, - GET_UINT32(p_MemMap->maccfg1) & ~MACCFG1_TX_FLOW); - } - + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime); return E_OK; } +/* .............................................................................. */ +/* backward compatibility. will be removed in the future. */ +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime) +{ + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0); +} + /* .............................................................................. */ static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_MemMap; - uint32_t tmpReg32; + bool accept_pause = !en; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); - p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap); - - tmpReg32 = GET_UINT32(p_MemMap->maccfg1); - if (en) - tmpReg32 &= ~MACCFG1_RX_FLOW; - else - tmpReg32 |= MACCFG1_RX_FLOW; - WRITE_UINT32(p_MemMap->maccfg1, tmpReg32); + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause); return E_OK; } - /* .............................................................................. */ static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -#ifdef FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 - if((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("1588TimeStamp in 10/100 SGMII")); -#endif /* FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 */ + p_Dtsec->ptpTsuEnabled = TRUE; - WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) | RCTRL_RTSE); - WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) | TCTRL_TTSE); + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE); return E_OK; } +/* .............................................................................. */ + static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); p_Dtsec->ptpTsuEnabled = FALSE; - WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) & ~RCTRL_RTSE); - WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) & ~TCTRL_TTSE); + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE); return E_OK; } @@ -847,89 +693,84 @@ static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec) static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; + struct dtsec_regs *p_DtsecMemMap; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); + p_DtsecMemMap = p_Dtsec->p_MemMap; + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled")); - p_DtsecMemMap = p_Dtsec->p_MemMap; memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics)); if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS) { - p_Statistics->eStatPkts64 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr64)) - + p_Dtsec->internalStatistics.tr64; /**< r-10G tr-DT 64 byte frame counter */ - p_Statistics->eStatPkts65to127 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr127)) - + p_Dtsec->internalStatistics.tr127; /**< r-10G 65 to 127 byte frame counter */ - p_Statistics->eStatPkts128to255 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr255)) - + p_Dtsec->internalStatistics.tr255; /**< r-10G 128 to 255 byte frame counter */ - p_Statistics->eStatPkts256to511 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr511)) - + p_Dtsec->internalStatistics.tr511; /**< r-10G 256 to 511 byte frame counter */ - p_Statistics->eStatPkts512to1023 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr1k)) - + p_Dtsec->internalStatistics.tr1k; /**< r-10G 512 to 1023 byte frame counter */ - p_Statistics->eStatPkts1024to1518 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmax)) - + p_Dtsec->internalStatistics.trmax; /**< r-10G 1024 to 1518 byte frame counter */ - p_Statistics->eStatPkts1519to1522 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmgv)) - + p_Dtsec->internalStatistics.trmgv; /**< r-10G 1519 to 1522 byte good frame count */ + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64) + + p_Dtsec->internalStatistics.tr64; + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127) + + p_Dtsec->internalStatistics.tr127; + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255) + + p_Dtsec->internalStatistics.tr255; + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511) + + p_Dtsec->internalStatistics.tr511; + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K) + + p_Dtsec->internalStatistics.tr1k; + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX) + + p_Dtsec->internalStatistics.trmax; + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV) + + p_Dtsec->internalStatistics.trmgv; + /* MIB II */ - p_Statistics->ifInOctets = GET_UINT32(p_DtsecMemMap->rbyt) - + p_Dtsec->internalStatistics.rbyt; /**< Total number of byte received. */ - p_Statistics->ifInPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rpkt)) - + p_Dtsec->internalStatistics.rpkt; /**< Total number of packets received.*/ - p_Statistics->ifInMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rmca)) - + p_Dtsec->internalStatistics.rmca; /**< Total number of multicast frame received*/ - p_Statistics->ifInBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rbca)) - + p_Dtsec->internalStatistics.rbca; /**< Total number of broadcast frame received */ - p_Statistics->ifOutOctets = GET_UINT32(p_DtsecMemMap->tbyt) - + p_Dtsec->internalStatistics.tbyt; /**< Total number of byte sent. */ - p_Statistics->ifOutPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tpkt)) - + p_Dtsec->internalStatistics.tpkt; /**< Total number of packets sent .*/ - p_Statistics->ifOutMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tmca)) - + p_Dtsec->internalStatistics.tmca; /**< Total number of multicast frame sent */ - p_Statistics->ifOutBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tbca)) - + p_Dtsec->internalStatistics.tbca; /**< Total number of multicast frame sent */ + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT) + + p_Dtsec->internalStatistics.rbyt; + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT) + + p_Dtsec->internalStatistics.rpkt; + p_Statistics->ifInUcastPkts = 0; + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA) + + p_Dtsec->internalStatistics.rmca; + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA) + + p_Dtsec->internalStatistics.rbca; + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT) + + p_Dtsec->internalStatistics.tbyt; + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT) + + p_Dtsec->internalStatistics.tpkt; + p_Statistics->ifOutUcastPkts = 0; + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA) + + p_Dtsec->internalStatistics.tmca; + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA) + + p_Dtsec->internalStatistics.tbca; } -/* */ - p_Statistics->eStatFragments = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rfrg)) - + p_Dtsec->internalStatistics.rfrg; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ - p_Statistics->eStatJabbers = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rjbr)) - + p_Dtsec->internalStatistics.rjbr; /**< Total number of packets longer than valid maximum length octets */ - p_Statistics->eStatsDropEvents = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rdrp)) - + p_Dtsec->internalStatistics.rdrp; /**< number of dropped packets due to internal errors of the MAC Client. */ - p_Statistics->eStatCRCAlignErrors = (MASK16BIT & GET_UINT32(p_DtsecMemMap->raln)) - + p_Dtsec->internalStatistics.raln; /**< Incremented when frames of correct length but with CRC error are received.*/ + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG) + + p_Dtsec->internalStatistics.rfrg; + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR) + + p_Dtsec->internalStatistics.rjbr; + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP) + + p_Dtsec->internalStatistics.rdrp; + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN) + + p_Dtsec->internalStatistics.raln; + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND) + + p_Dtsec->internalStatistics.rund; + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR) + + p_Dtsec->internalStatistics.rovr; + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF) + + p_Dtsec->internalStatistics.rxpf; + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF) + + p_Dtsec->internalStatistics.txpf; + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse; - p_Statistics->eStatUndersizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rund)) - + p_Dtsec->internalStatistics.rund; /**< Total number of packets that were less than 64 octets long with a good CRC.*/ - p_Statistics->eStatOversizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rovr)) - + p_Dtsec->internalStatistics.rovr; /**< T,B.D*/ -/* Pause */ - p_Statistics->reStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rxpf)) - + p_Dtsec->internalStatistics.rxpf; /**< Pause MAC Control received */ - p_Statistics->teStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->txpf)) - + p_Dtsec->internalStatistics.txpf; /**< Pause MAC Control sent */ - - p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; /**< Frames received, but discarded due to problems within the MAC RX. */ - - p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents - + p_Statistics->eStatCRCAlignErrors - + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rflr)) - + p_Dtsec->internalStatistics.rflr - + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcde)) - + p_Dtsec->internalStatistics.rcde - + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcse)) - + p_Dtsec->internalStatistics.rcse; - - p_Statistics->ifOutDiscards = (MASK16BIT & GET_UINT32(p_DtsecMemMap->tdrp)) - + p_Dtsec->internalStatistics.tdrp; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ - p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */ - + (MASK12BIT & GET_UINT32(p_DtsecMemMap->tfcs)) - + p_Dtsec->internalStatistics.tfcs; + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP) + + p_Dtsec->internalStatistics.tdrp; + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */ + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS) + + p_Dtsec->internalStatistics.tfcs; return E_OK; } @@ -938,27 +779,15 @@ static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statist static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; - uint32_t tmpReg32 = 0; - uint64_t addr; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; /* Initialize MAC Station Address registers (1 & 2) */ /* Station address have to be swapped (big endian to little endian */ - addr = ((*(uint64_t *)p_EnetAddr) >> 16); - p_Dtsec->addr = addr; - - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32); - - tmpReg32 = (uint32_t)(addr>>32); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32); + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr); + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr)); return E_OK; } @@ -967,15 +796,16 @@ static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr) static t_Error DtsecResetCounters (t_Handle h_Dtsec) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); /* clear HW counters */ - WRITE_UINT32(p_Dtsec->p_MemMap->ecntrl, GET_UINT32(p_Dtsec->p_MemMap->ecntrl) | ECNTRL_CLRCNT); + fman_dtsec_reset_stat(p_Dtsec->p_MemMap); /* clear SW counters holding carries */ - memset((char *)&p_Dtsec->internalStatistics, (char)0x0, sizeof(t_InternalStatistics)); + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics)); return E_OK; } @@ -989,8 +819,9 @@ static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthA uint8_t paddrNum; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); if (ethAddr & GROUP_ADDRESS) /* Multicast address has no effect in PADDR */ @@ -1012,7 +843,7 @@ static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthA p_Dtsec->paddr[paddrNum] = ethAddr; /* put in hardware */ - HardwareAddAddrInPaddr(p_Dtsec, ðAddr, paddrNum); + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(ðAddr), paddrNum); p_Dtsec->numOfIndAddrInRegs++; return E_OK; @@ -1031,8 +862,9 @@ static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthA uint8_t paddrNum; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); /* Find used PADDR containing this address */ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) @@ -1043,7 +875,7 @@ static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthA /* mark this PADDR as not used */ p_Dtsec->indAddrRegUsed[paddrNum] = FALSE; /* clear in hardware */ - HardwareClearAddrInPaddr(p_Dtsec, paddrNum); + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum); p_Dtsec->numOfIndAddrInRegs--; return E_OK; @@ -1058,51 +890,56 @@ static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthA static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; - uint32_t crc; - uint8_t crcMirror, reg; - uint32_t bitMask; t_EthHashEntry *p_HashEntry; uint64_t ethAddr; + int32_t bucket; + uint32_t crc; + bool mcast, ghtx; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE); + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE); - /* CRC calculation */ - GET_MAC_ADDR_CRC(ethAddr, crc); + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */ + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket")); - /* calculate the "crc mirror" */ - crcMirror = MIRROR((uint8_t)crc); + crc = GetMacAddrHashCode(ethAddr); - /* 3 MSB bits define the register */ - reg = (uint8_t)(crcMirror >> 5); - /* 5 LSB bits define the bit within the register */ - bitMask = 0x80000000 >> (crcMirror & 0x1f); + /* considering the 9 highest order bits in crc H[8:0]: + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register + * and H[5:1] (next 5 bits) identify the hash bit + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register + * and H[4:0] (next 5 bits) identify the hash bit. + * + * In bucket index output the low 5 bits identify the hash register bit, + * while the higher 4 bits identify the hash register + */ + + if (ghtx) + bucket = (int32_t)((crc >> 23) & 0x1ff); + else { + bucket = (int32_t)((crc >> 24) & 0xff); + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ + if (mcast) + bucket += 0x100; + } + + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE); /* Create element to be added to the driver hash table */ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); p_HashEntry->addr = ethAddr; INIT_LIST(&p_HashEntry->node); - if (ethAddr & GROUP_ADDRESS) - { + if (ethAddr & MAC_GROUP_ADDRESS) /* Group Address */ - LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])); - /* Set the appropriate bit in GADDR0-7 */ - WRITE_UINT32(p_DtsecMemMap->gaddr[reg], - GET_UINT32(p_DtsecMemMap->gaddr[reg]) | bitMask); - } + NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])); else - { - LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])); - /* Set the appropriate bit in IADDR0-7 */ - WRITE_UINT32(p_DtsecMemMap->igaddr[reg], - GET_UINT32(p_DtsecMemMap->igaddr[reg]) | bitMask); - } + NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])); return E_OK; } @@ -1112,65 +949,66 @@ static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; t_List *p_Pos; - uint32_t crc; - uint8_t crcMirror, reg; - uint32_t bitMask; t_EthHashEntry *p_HashEntry = NULL; uint64_t ethAddr; + int32_t bucket; + uint32_t crc; + bool mcast, ghtx; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE); + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE); - /* CRC calculation */ - GET_MAC_ADDR_CRC(ethAddr, crc); + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */ + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket")); - /* calculate the "crc mirror" */ - crcMirror = MIRROR((uint8_t)crc); + crc = GetMacAddrHashCode(ethAddr); - /* 3 MSB bits define the register */ - reg =(uint8_t)( crcMirror >> 5); - /* 5 LSB bits define the bit within the register */ - bitMask = 0x80000000 >> (crcMirror & 0x1f); + if (ghtx) + bucket = (int32_t)((crc >> 23) & 0x1ff); + else { + bucket = (int32_t)((crc >> 24) & 0xff); + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ + if (mcast) + bucket += 0x100; + } - if (ethAddr & GROUP_ADDRESS) + if (ethAddr & MAC_GROUP_ADDRESS) { /* Group Address */ - LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])) + NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])) { p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); - if(p_HashEntry->addr == ethAddr) + if (p_HashEntry->addr == ethAddr) { - LIST_DelAndInit(&p_HashEntry->node); + NCSW_LIST_DelAndInit(&p_HashEntry->node); XX_Free(p_HashEntry); break; } } - if(LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror])) - WRITE_UINT32(p_DtsecMemMap->gaddr[reg], - GET_UINT32(p_DtsecMemMap->gaddr[reg]) & ~bitMask); + if (NCSW_LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])) + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE); } else { /* Individual Address */ - LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])) + NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])) { p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); - if(p_HashEntry->addr == ethAddr) + if (p_HashEntry->addr == ethAddr) { - LIST_DelAndInit(&p_HashEntry->node); + NCSW_LIST_DelAndInit(&p_HashEntry->node); XX_Free(p_HashEntry); break; } } - if(LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror])) - WRITE_UINT32(p_DtsecMemMap->igaddr[reg], - GET_UINT32(p_DtsecMemMap->igaddr[reg]) & ~bitMask); + if (NCSW_LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])) + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE); } /* address does not exist */ @@ -1179,29 +1017,17 @@ static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) return E_OK; } - /* .............................................................................. */ static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; - uint32_t tmpReg32; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; - - tmpReg32 = GET_UINT32(p_DtsecMemMap->rctrl); - - if (newVal) - tmpReg32 |= RCTRL_PROM; - else - tmpReg32 &= ~RCTRL_PROM; - - WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32); + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal); + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal); return E_OK; } @@ -1210,38 +1036,29 @@ static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal) static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); - - p_DtsecMemMap = p_Dtsec->p_MemMap; + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); p_Dtsec->statisticsLevel = statisticsLevel; - switch (p_Dtsec->statisticsLevel) + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap, + (enum dtsec_stat_level)statisticsLevel); + if (err != E_OK) + return err; + + switch (statisticsLevel) { - case(e_FM_MAC_NONE_STATISTICS): - WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff); - WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff); - WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) & ~ECNTRL_STEN); - WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) & ~IMASK_MSROEN); - p_Dtsec->exceptions &= ~IMASK_MSROEN; + case (e_FM_MAC_NONE_STATISTICS): + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN; break; - case(e_FM_MAC_PARTIAL_STATISTICS): - WRITE_UINT32(p_DtsecMemMap->cam1, CAM1_ERRORS_ONLY); - WRITE_UINT32(p_DtsecMemMap->cam2, CAM2_ERRORS_ONLY); - WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN); - WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN); - p_Dtsec->exceptions |= IMASK_MSROEN; + case (e_FM_MAC_PARTIAL_STATISTICS): + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN; break; - case(e_FM_MAC_FULL_STATISTICS): - WRITE_UINT32(p_DtsecMemMap->cam1,0); - WRITE_UINT32(p_DtsecMemMap->cam2,0); - WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN); - WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN); - p_Dtsec->exceptions |= IMASK_MSROEN; + case (e_FM_MAC_FULL_STATISTICS): + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN; break; default: RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); @@ -1252,51 +1069,59 @@ static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel stati /* .............................................................................. */ -static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex) +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; - uint32_t tmpReg32; + + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); + + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en); + + return E_OK; +} + +/* .............................................................................. */ + +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex) +{ + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + int err; + enum enet_interface enet_interface; + enum enet_speed enet_speed; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); - p_DtsecMemMap = p_Dtsec->p_MemMap; - SANITY_CHECK_RETURN_ERROR(p_DtsecMemMap, E_INVALID_HANDLE); - - if ((!fullDuplex) && (speed >= e_ENET_SPEED_1000)) - RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed); + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode); + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode); p_Dtsec->halfDuplex = !fullDuplex; - tmpReg32 = GET_UINT32(p_DtsecMemMap->maccfg2); - if(p_Dtsec->halfDuplex) - tmpReg32 &= ~MACCFG2_FULL_DUPLEX; - else - tmpReg32 |= MACCFG2_FULL_DUPLEX; + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex); - tmpReg32 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE); - if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)|| - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) - tmpReg32 |= MACCFG2_NIBBLE_MODE; - else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| - (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)) - tmpReg32 |= MACCFG2_BYTE_MODE; - WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32); + if (err == -EINVAL) + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); - tmpReg32 = GET_UINT32(p_DtsecMemMap->ecntrl); - if (!(tmpReg32 & ECNTRL_CFG_RO)) - { - if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) - tmpReg32 |= ECNTRL_R100M; - else - tmpReg32 &= ~ECNTRL_R100M; - WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32); - } + return (t_Error)err; +} + +/* .............................................................................. */ + +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec) +{ + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + uint16_t tmpReg16; + + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); + + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16); + + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 ); + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); + + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16); return E_OK; } @@ -1305,10 +1130,10 @@ static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDup static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); *macId = p_Dtsec->macId; @@ -1319,15 +1144,12 @@ static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId) static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecMemMap *p_DtsecMemMap; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; - *macVersion = GET_UINT32(p_DtsecMemMap->tsec_id1); + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap); return E_OK; } @@ -1336,118 +1158,53 @@ static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion) static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - uint32_t tmpReg, bitMask = 0; - t_DtsecMemMap *p_DtsecMemMap; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + uint32_t bitMask = 0; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - p_DtsecMemMap = p_Dtsec->p_MemMap; - - if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) { GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) + if (bitMask) { if (enable) p_Dtsec->exceptions |= bitMask; else p_Dtsec->exceptions &= ~bitMask; - } + } else RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - tmpReg = GET_UINT32(p_DtsecMemMap->imask); - if(enable) - tmpReg |= bitMask; + if (enable) + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask); else - tmpReg &= ~bitMask; - WRITE_UINT32(p_DtsecMemMap->imask, tmpReg); - - /* warn if MIB OVFL is disabled and statistic gathering is enabled */ - if((exception == e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL) && - !enable && - (p_Dtsec->statisticsLevel != e_FM_MAC_NONE_STATISTICS)) - DBG(WARNING, ("Disabled MIB counters overflow exceptions. Counters value may be inaccurate due to unregistered overflow")); - + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask); } else { - if(!p_Dtsec->ptpTsuEnabled) + if (!p_Dtsec->ptpTsuEnabled) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); - tmpReg = GET_UINT32(p_DtsecMemMap->tmr_pemask); - switch(exception){ - case(e_FM_MAC_EX_1G_1588_TS_RX_ERR): - if(enable) - { - p_Dtsec->enTsuErrExeption = TRUE; - WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg | PEMASK_TSRE); - } - else - { - p_Dtsec->enTsuErrExeption = FALSE; - WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg & ~PEMASK_TSRE); - } - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - } - } - return E_OK; -} - -/* ........................................................................... */ - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -static t_Error DtsecDumpRegs(t_Handle h_Dtsec) -{ - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - int i = 0; - - DECLARE_DUMP; - - if (p_Dtsec->p_MemMap) - { - - DUMP_TITLE(p_Dtsec->p_MemMap, ("MAC %d: ", p_Dtsec->macId)); - DUMP_VAR(p_Dtsec->p_MemMap, tsec_id1); - DUMP_VAR(p_Dtsec->p_MemMap, tsec_id2); - DUMP_VAR(p_Dtsec->p_MemMap, ievent); - DUMP_VAR(p_Dtsec->p_MemMap, imask); - DUMP_VAR(p_Dtsec->p_MemMap, edis); - DUMP_VAR(p_Dtsec->p_MemMap, ecntrl); - DUMP_VAR(p_Dtsec->p_MemMap, ptv); - DUMP_VAR(p_Dtsec->p_MemMap, tmr_ctrl); - DUMP_VAR(p_Dtsec->p_MemMap, tmr_pevent); - DUMP_VAR(p_Dtsec->p_MemMap, tmr_pemask); - DUMP_VAR(p_Dtsec->p_MemMap, tctrl); - DUMP_VAR(p_Dtsec->p_MemMap, rctrl); - DUMP_VAR(p_Dtsec->p_MemMap, maccfg1); - DUMP_VAR(p_Dtsec->p_MemMap, maccfg2); - DUMP_VAR(p_Dtsec->p_MemMap, ipgifg); - DUMP_VAR(p_Dtsec->p_MemMap, hafdup); - DUMP_VAR(p_Dtsec->p_MemMap, maxfrm); - - DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr1); - DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr2); - - DUMP_SUBSTRUCT_ARRAY(i, 8) + if (enable) { - DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match1); - DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match2); + p_Dtsec->enTsuErrExeption = TRUE; + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap); + } + else + { + p_Dtsec->enTsuErrExeption = FALSE; + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap); } } return E_OK; } -#endif /* (defined(DEBUG_ERRORS) && ... */ /*****************************************************************************/ -/* FM Init & Free API */ +/* dTSEC Init & Free API */ /*****************************************************************************/ /* .............................................................................. */ @@ -1455,354 +1212,115 @@ static t_Error DtsecDumpRegs(t_Handle h_Dtsec) static t_Error DtsecInit(t_Handle h_Dtsec) { t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_DtsecDriverParam *p_DtsecDriverParam; - t_DtsecMemMap *p_DtsecMemMap; - int i; - uint32_t tmpReg32; - uint64_t addr; + struct dtsec_cfg *p_DtsecDriverParam; t_Error err; + uint16_t maxFrmLn; + enum enet_interface enet_interface; + enum enet_speed enet_speed; + t_EnetAddr ethAddr; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo); CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters); p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam; - p_Dtsec->halfDuplex = p_DtsecDriverParam->halfDuplex; - p_Dtsec->debugMode = p_DtsecDriverParam->debugMode; - p_DtsecMemMap = p_Dtsec->p_MemMap; + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on; - /*************dtsec_id2******************/ - tmpReg32 = GET_UINT32(p_DtsecMemMap->tsec_id2); + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode); + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode); + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr); - if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) - if(tmpReg32 & ID2_INT_REDUCED_OFF) - { - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for reduced interface in current DTSEC version")); - } - - if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| - (p_Dtsec->enetMode == e_ENET_MODE_MII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_MII_100)) - if(tmpReg32 & ID2_INT_NORMAL_OFF) - { - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for normal interface in current DTSEC version")); - } - /*************dtsec_id2******************/ - - /***************EDIS************************/ - WRITE_UINT32(p_DtsecMemMap->edis, p_DtsecDriverParam->errorDisabled); - /***************EDIS************************/ - - /***************ECNTRL************************/ - tmpReg32 = 0; - if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)) - tmpReg32 |= ECNTRL_GMIIM; - if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)) - tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM); - if (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000) - tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM | ECNTRL_QSGMIIM); - if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10)|| - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)) - tmpReg32 |= ECNTRL_RPM; - if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) - tmpReg32 |= ECNTRL_R100M; - if ((p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_RMII_100)) - tmpReg32 |= ECNTRL_RMM; - WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32); - /***************ECNTRL************************/ - - /***************PTV************************/ - tmpReg32 = 0; -#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap, + p_DtsecDriverParam, + enet_interface, + enet_speed, + (uint8_t*)ethAddr, + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev, + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev, + p_Dtsec->exceptions); + if (err) { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - p_DtsecDriverParam->pauseTime += 2; + FreeInitResources(p_Dtsec); + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode")); } -#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ - if (p_DtsecDriverParam->pauseTime) - tmpReg32 |= (uint32_t)p_DtsecDriverParam->pauseTime; - if (p_DtsecDriverParam->pauseExtended) - tmpReg32 |= ((uint32_t)p_DtsecDriverParam->pauseExtended) << PTV_PTE_OFST; - WRITE_UINT32(p_DtsecMemMap->ptv, tmpReg32); - /***************PTV************************/ - - /***************TCTRL************************/ - tmpReg32 = 0; - if(p_DtsecDriverParam->halfDuplex) - { - if(p_DtsecDriverParam->halfDulexFlowControlEn) - tmpReg32 |= TCTRL_THDF; - } - else - { - if(p_DtsecDriverParam->txTimeStampEn) - tmpReg32 |= TCTRL_TTSE; - } - WRITE_UINT32(p_DtsecMemMap->tctrl, tmpReg32); - /***************TCTRL************************/ - - /***************RCTRL************************/ - tmpReg32 = 0; - if (p_DtsecDriverParam->packetAlignmentPadding) - tmpReg32 |= ((uint32_t)(0x0000001f & p_DtsecDriverParam->packetAlignmentPadding)) << 16; - if (p_DtsecDriverParam->controlFrameAccept) - tmpReg32 |= RCTRL_CFA; - if (p_DtsecDriverParam->groupHashExtend) - tmpReg32 |= RCTRL_GHTX; - if(p_DtsecDriverParam->rxTimeStampEn) - tmpReg32 |= RCTRL_RTSE; - if (p_DtsecDriverParam->broadcReject) - tmpReg32 |= RCTRL_BC_REJ; - if (p_DtsecDriverParam->rxShortFrame) - tmpReg32 |= RCTRL_RSF; - if (p_DtsecDriverParam->promiscuousEnable) - tmpReg32 |= RCTRL_PROM; - if (p_DtsecDriverParam->exactMatch) - tmpReg32 |= RCTRL_EMEN; - - WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32); - /***************RCTRL************************/ - - /* Assign a Phy Address to the TBI (TBIPA). */ - /* Done also in case that TBI is not selected to avoid */ - /* conflict with the external PHY’s Physical address */ - WRITE_UINT32(p_DtsecMemMap->tbipa, p_DtsecDriverParam->tbiPhyAddr); - - /* Reset the management interface */ - WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, MIIMCFG_RESET_MGMT); - WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, ~MIIMCFG_RESET_MGMT); - /* Setup the MII Mgmt clock speed */ - WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, - (uint32_t)GetMiiDiv((int32_t)(((p_Dtsec->fmMacControllerDriver.clkFreq*10)/2)/8))); - - if(p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII) { uint16_t tmpReg16; /* Configure the TBI PHY Control Register */ - tmpReg16 = PHY_TBICON_SPEED2 | PHY_TBICON_SRESET; + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET; + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16); - DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16); + tmpReg16 = PHY_TBICON_CLK_SEL; + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16); - tmpReg16 = PHY_TBICON_SPEED2; + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16); - DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16); + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX) + tmpReg16 = PHY_TBIANA_1000X; + else + tmpReg16 = PHY_TBIANA_SGMII; + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16); - if(!p_DtsecDriverParam->halfDuplex) - tmpReg16 |= PHY_CR_FULLDUPLEX | 0x8000 | PHY_CR_ANE; + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); - DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16); - - tmpReg16 = 0x01a0; - DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 4, tmpReg16); - - tmpReg16 = 0x1340; - DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16); + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16); } - /***************TMR_CTL************************/ - WRITE_UINT32(p_DtsecMemMap->tmr_ctrl, 0); - - if(p_Dtsec->ptpTsuEnabled) - { - tmpReg32 = 0; - if (p_Dtsec->enTsuErrExeption) - tmpReg32 |= PEMASK_TSRE; - WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg32); - WRITE_UINT32(p_DtsecMemMap->tmr_pevent, tmpReg32); - } - - /***************DEBUG************************/ - tmpReg32 = 0; - if(p_DtsecDriverParam->debugMode) - WRITE_UINT32(p_DtsecMemMap->tsec_id1, TSEC_ID1_DEBUG); - /***************DEBUG************************/ - - /***************MACCFG1***********************/ - WRITE_UINT32(p_DtsecMemMap->maccfg1, MACCFG1_SOFT_RESET); - WRITE_UINT32(p_DtsecMemMap->maccfg1, 0); - tmpReg32 = 0; - if(p_DtsecDriverParam->loopback) - tmpReg32 |= MACCFG1_LOOPBACK; - if(p_DtsecDriverParam->actOnRxPauseFrame) - tmpReg32 |= MACCFG1_RX_FLOW; - if(p_DtsecDriverParam->actOnTxPauseFrame) - tmpReg32 |= MACCFG1_TX_FLOW; - WRITE_UINT32(p_DtsecMemMap->maccfg1, tmpReg32); - /***************MACCFG1***********************/ - - /***************MACCFG2***********************/ - tmpReg32 = 0; - if( (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RMII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_MII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_MII_100) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)|| - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100)) - tmpReg32 |= MACCFG2_NIBBLE_MODE; - else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) || - (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)|| - (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)|| - (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) - tmpReg32 |= MACCFG2_BYTE_MODE; - - tmpReg32 |= (((uint32_t)p_DtsecDriverParam->preambleLength) & 0x0000000f)<< PREAMBLE_LENGTH_SHIFT; - - if(p_DtsecDriverParam->preambleRxEn) - tmpReg32 |= MACCFG2_PRE_AM_Rx_EN; - if(p_DtsecDriverParam->preambleTxEn) - tmpReg32 |= MACCFG2_PRE_AM_Tx_EN; - if(p_DtsecDriverParam->lengthCheckEnable) - tmpReg32 |= MACCFG2_LENGTH_CHECK; - if(p_DtsecDriverParam->padAndCrcEnable) - tmpReg32 |= MACCFG2_PAD_CRC_EN; - if(p_DtsecDriverParam->crcEnable) - tmpReg32 |= MACCFG2_CRC_EN; - if(!p_DtsecDriverParam->halfDuplex) - tmpReg32 |= MACCFG2_FULL_DUPLEX; - WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32); - /***************MACCFG2***********************/ - - /***************IPGIFG************************/ - tmpReg32 = 0; - ASSERT_COND(p_DtsecDriverParam->nonBackToBackIpg1 <= p_DtsecDriverParam->nonBackToBackIpg2); - tmpReg32 = (uint32_t)((((uint32_t)p_DtsecDriverParam->nonBackToBackIpg1 << - IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_1) | - (((uint32_t)p_DtsecDriverParam->nonBackToBackIpg2 << - IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_2) | - (((uint32_t)p_DtsecDriverParam->minIfgEnforcement << - IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) & IPGIFG_MIN_IFG_ENFORCEMENT) | - ((uint32_t)p_DtsecDriverParam->backToBackIpg & IPGIFG_BACK_TO_BACK_IPG)); - WRITE_UINT32(p_DtsecMemMap->ipgifg, tmpReg32); - /***************IPGIFG************************/ - - /***************HAFDUP************************/ - tmpReg32 = 0; - if(p_DtsecDriverParam->alternateBackoffEnable) - { - tmpReg32 = (uint32_t) (HAFDUP_ALT_BEB | (((uint32_t)p_DtsecDriverParam->alternateBackoffVal & 0x0000000f) << - HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT)); - } - - if(p_DtsecDriverParam->backPressureNoBackoff) - tmpReg32 |= HAFDUP_BP_NO_BACKOFF; - if(p_DtsecDriverParam->noBackoff) - tmpReg32 |= HAFDUP_NO_BACKOFF; - if(p_DtsecDriverParam->excessDefer) - tmpReg32 |= HAFDUP_EXCESS_DEFER; - tmpReg32 |= (((uint32_t)p_DtsecDriverParam->maxRetransmission << - HAFDUP_RETRANSMISSION_MAX_SHIFT )& HAFDUP_RETRANSMISSION_MAX); - tmpReg32|= ((uint32_t)p_DtsecDriverParam->collisionWindow & HAFDUP_COLLISION_WINDOW); - - WRITE_UINT32(p_DtsecMemMap->hafdup, tmpReg32); - /***************HAFDUP************************/ - - /***************MAXFRM************************/ - /* Initialize MAXFRM */ - WRITE_UINT32(p_DtsecMemMap->maxfrm, - p_DtsecDriverParam->maxFrameLength); - err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, - e_FM_MAC_1G, - p_Dtsec->fmMacControllerDriver.macId, - p_DtsecDriverParam->maxFrameLength); + /* Max Frame Length */ + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap); + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn); if (err) - RETURN_ERROR(MAJOR, err, NO_MSG); - /***************MAXFRM************************/ + RETURN_ERROR(MINOR,err, NO_MSG); - /***************CAM1************************/ - WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff); - WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff); - - /***************IMASK************************/ - WRITE_UINT32(p_DtsecMemMap->imask, p_Dtsec->exceptions); - /***************IMASK************************/ - - /***************IEVENT************************/ - WRITE_UINT32(p_DtsecMemMap->ievent, EVENTS_MASK); - - /***************MACSTNADDR1/2*****************/ - /* Initialize MAC Station Address registers (1 & 2) */ - /* Station address have to be swapped (big endian to little endian */ - addr = p_Dtsec->addr; - - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32); - - tmpReg32 = (uint32_t)(addr>>32); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32); - /***************MACSTNADDR1/2*****************/ - - /***************DEBUG*****************/ - WRITE_UINT32(p_DtsecMemMap->tx_threshold, (uint32_t)(p_DtsecDriverParam->fifoTxThr & 0x7f)); - WRITE_UINT32(p_DtsecMemMap->tx_watermark_high, (uint32_t)(p_DtsecDriverParam->fifoTxWatermarkH & 0x7f)); - WRITE_UINT32(p_DtsecMemMap->rx_watermark_low, (uint32_t)(p_DtsecDriverParam->fifoRxWatermarkL & 0x7f)); - /***************DEBUG*****************/ - - /*****************HASH************************/ - for(i=0 ; iigaddr[i], 0); - /* Initialize GADDRx */ - WRITE_UINT32(p_DtsecMemMap->gaddr[i], 0); - } - - p_Dtsec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); - if(!p_Dtsec->p_MulticastAddrHash) - { + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE); + if (!p_Dtsec->p_MulticastAddrHash) { FreeInitResources(p_Dtsec); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED")); } p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); - if(!p_Dtsec->p_UnicastAddrHash) + if (!p_Dtsec->p_UnicastAddrHash) { FreeInitResources(p_Dtsec); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED")); } /* register err intr handler for dtsec to FPM (err)*/ - FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR, DtsecErrException , p_Dtsec); + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, + e_FM_MOD_1G_MAC, + p_Dtsec->macId, + e_FM_INTR_TYPE_ERR, + DtsecIsr, + p_Dtsec); /* register 1588 intr handler for TMR to FPM (normal)*/ - FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL, Dtsec1588Exception , p_Dtsec); + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, + e_FM_MOD_1G_MAC, + p_Dtsec->macId, + e_FM_INTR_TYPE_NORMAL, + Dtsec1588Isr, + p_Dtsec); /* register normal intr handler for dtsec to main interrupt controller. */ if (p_Dtsec->mdioIrq != NO_IRQ) { - XX_SetIntr(p_Dtsec->mdioIrq, DtsecException, p_Dtsec); + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec); XX_EnableIntr(p_Dtsec->mdioIrq); } XX_Free(p_DtsecDriverParam); p_Dtsec->p_DtsecDriverParam = NULL; - err = DtsecSetStatistics(p_Dtsec, e_FM_MAC_FULL_STATISTICS); - if(err) + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS); + if (err) { FreeInitResources(p_Dtsec); - RETURN_ERROR(MAJOR, err, NO_MSG); + RETURN_ERROR(MAJOR, err, ("Undefined statistics level")); } return E_OK; @@ -1816,14 +1334,17 @@ static t_Error DtsecFree(t_Handle h_Dtsec) SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); - FreeInitResources(p_Dtsec); - if (p_Dtsec->p_DtsecDriverParam) { + /* Called after config */ XX_Free(p_Dtsec->p_DtsecDriverParam); p_Dtsec->p_DtsecDriverParam = NULL; } - XX_Free (h_Dtsec); + else + /* Called after init */ + FreeInitResources(p_Dtsec); + + XX_Free(p_Dtsec); return E_OK; } @@ -1844,20 +1365,26 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc; p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex; p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck; + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr; p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException; + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL; p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable; p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable; + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL; p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException; p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous; p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink; + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan; + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg; p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp; p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp; p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause; + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames; p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause; p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters; @@ -1875,14 +1402,11 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg; p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg; -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) - p_FmMacControllerDriver->f_FM_MAC_DumpRegs = DtsecDumpRegs; -#endif /* (defined(DEBUG_ERRORS) && ... */ } /*****************************************************************************/ -/* dTSEC Config Main Entry */ +/* dTSEC Config Main Entry */ /*****************************************************************************/ /* .............................................................................. */ @@ -1890,45 +1414,41 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam) { t_Dtsec *p_Dtsec; - t_DtsecDriverParam *p_DtsecDriverParam; + struct dtsec_cfg *p_DtsecDriverParam; uintptr_t baseAddr; - uint8_t i; SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); baseAddr = p_FmMacParam->baseAddr; + /* allocate memory for the UCC GETH data structure. */ - p_Dtsec = (t_Dtsec *) XX_Malloc(sizeof(t_Dtsec)); + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec)); if (!p_Dtsec) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure")); return NULL; } - /* Zero out * p_Dtsec */ memset(p_Dtsec, 0, sizeof(t_Dtsec)); InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver); /* allocate memory for the dTSEC driver parameters data structure. */ - p_DtsecDriverParam = (t_DtsecDriverParam *) XX_Malloc(sizeof(t_DtsecDriverParam)); + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg)); if (!p_DtsecDriverParam) { XX_Free(p_Dtsec); REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters")); return NULL; } - /* Zero out */ - memset(p_DtsecDriverParam, 0, sizeof(t_DtsecDriverParam)); + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg)); /* Plant parameter structure pointer */ p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam; - SetDefaultParam(p_DtsecDriverParam); + fman_dtsec_defconfig(p_DtsecDriverParam); - for (i=0; i < sizeof(p_FmMacParam->addr); i++) - p_Dtsec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8)); - - p_Dtsec->p_MemMap = (t_DtsecMemMap *)UINT_TO_PTR(baseAddr); - p_Dtsec->p_MiiMemMap = (t_MiiAccessMemMap *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET); + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr); + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET); + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); p_Dtsec->enetMode = p_FmMacParam->enetMode; p_Dtsec->macId = p_FmMacParam->macId; p_Dtsec->exceptions = DEFAULT_exceptions; @@ -1936,6 +1456,9 @@ t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam) p_Dtsec->f_Exception = p_FmMacParam->f_Exception; p_Dtsec->f_Event = p_FmMacParam->f_Event; p_Dtsec->h_App = p_FmMacParam->h_App; + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en; + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en; + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr; return p_Dtsec; } diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h index 4bb7a8617972..c26f40cc9664 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,81 +41,58 @@ #include "std_ext.h" #include "error_ext.h" #include "list_ext.h" +#include "enet_ext.h" + #include "dtsec_mii_acc.h" #include "fm_mac.h" -#define PEMASK_TSRE 0x00010000 +#define DEFAULT_exceptions \ + ((uint32_t)(DTSEC_IMASK_BREN | \ + DTSEC_IMASK_RXCEN | \ + DTSEC_IMASK_BTEN | \ + DTSEC_IMASK_TXCEN | \ + DTSEC_IMASK_TXEEN | \ + DTSEC_IMASK_ABRTEN | \ + DTSEC_IMASK_LCEN | \ + DTSEC_IMASK_CRLEN | \ + DTSEC_IMASK_XFUNEN | \ + DTSEC_IMASK_IFERREN | \ + DTSEC_IMASK_MAGEN | \ + DTSEC_IMASK_TDPEEN | \ + DTSEC_IMASK_RDPEEN)) -#define IMASK_BREN 0x80000000 -#define IMASK_RXCEN 0x40000000 -#define IMASK_MSROEN 0x04000000 -#define IMASK_GTSCEN 0x02000000 -#define IMASK_BTEN 0x01000000 -#define IMASK_TXCEN 0x00800000 -#define IMASK_TXEEN 0x00400000 -#define IMASK_LCEN 0x00040000 -#define IMASK_CRLEN 0x00020000 -#define IMASK_XFUNEN 0x00010000 -#define IMASK_ABRTEN 0x00008000 -#define IMASK_IFERREN 0x00004000 -#define IMASK_MAGEN 0x00000800 -#define IMASK_MMRDEN 0x00000400 -#define IMASK_MMWREN 0x00000200 -#define IMASK_GRSCEN 0x00000100 -#define IMASK_TDPEEN 0x00000002 -#define IMASK_RDPEEN 0x00000001 - -#define EVENTS_MASK ((uint32_t)(IMASK_BREN | \ - IMASK_RXCEN | \ - IMASK_MSROEN | \ - IMASK_GTSCEN | \ - IMASK_BTEN | \ - IMASK_TXCEN | \ - IMASK_TXEEN | \ - IMASK_ABRTEN | \ - IMASK_LCEN | \ - IMASK_CRLEN | \ - IMASK_XFUNEN | \ - IMASK_IFERREN | \ - IMASK_MAGEN | \ - IMASK_MMRDEN | \ - IMASK_MMWREN | \ - IMASK_GRSCEN | \ - IMASK_TDPEEN | \ - IMASK_RDPEEN)) - -#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \ - case e_FM_MAC_EX_1G_BAB_RX: \ - bitMask = IMASK_BREN; break; \ - case e_FM_MAC_EX_1G_RX_CTL: \ - bitMask = IMASK_RXCEN; break; \ - case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \ - bitMask = IMASK_GTSCEN ; break; \ - case e_FM_MAC_EX_1G_BAB_TX: \ - bitMask = IMASK_BTEN ; break; \ - case e_FM_MAC_EX_1G_TX_CTL: \ - bitMask = IMASK_TXCEN ; break; \ - case e_FM_MAC_EX_1G_TX_ERR: \ - bitMask = IMASK_TXEEN ; break; \ - case e_FM_MAC_EX_1G_LATE_COL: \ - bitMask = IMASK_LCEN ; break; \ - case e_FM_MAC_EX_1G_COL_RET_LMT: \ - bitMask = IMASK_CRLEN ; break; \ - case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \ - bitMask = IMASK_XFUNEN ; break; \ - case e_FM_MAC_EX_1G_MAG_PCKT: \ - bitMask = IMASK_MAGEN ; break; \ - case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \ - bitMask = IMASK_MMRDEN; break; \ - case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \ - bitMask = IMASK_MMWREN ; break; \ - case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \ - bitMask = IMASK_GRSCEN; break; \ - case e_FM_MAC_EX_1G_TX_DATA_ERR: \ - bitMask = IMASK_TDPEEN; break; \ - case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \ - bitMask = IMASK_MSROEN ; break; \ +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ + case e_FM_MAC_EX_1G_BAB_RX: \ + bitMask = DTSEC_IMASK_BREN; break; \ + case e_FM_MAC_EX_1G_RX_CTL: \ + bitMask = DTSEC_IMASK_RXCEN; break; \ + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \ + bitMask = DTSEC_IMASK_GTSCEN ; break; \ + case e_FM_MAC_EX_1G_BAB_TX: \ + bitMask = DTSEC_IMASK_BTEN ; break; \ + case e_FM_MAC_EX_1G_TX_CTL: \ + bitMask = DTSEC_IMASK_TXCEN ; break; \ + case e_FM_MAC_EX_1G_TX_ERR: \ + bitMask = DTSEC_IMASK_TXEEN ; break; \ + case e_FM_MAC_EX_1G_LATE_COL: \ + bitMask = DTSEC_IMASK_LCEN ; break; \ + case e_FM_MAC_EX_1G_COL_RET_LMT: \ + bitMask = DTSEC_IMASK_CRLEN ; break; \ + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \ + bitMask = DTSEC_IMASK_XFUNEN ; break; \ + case e_FM_MAC_EX_1G_MAG_PCKT: \ + bitMask = DTSEC_IMASK_MAGEN ; break; \ + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \ + bitMask = DTSEC_IMASK_MMRDEN; break; \ + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \ + bitMask = DTSEC_IMASK_MMWREN ; break; \ + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \ + bitMask = DTSEC_IMASK_GRSCEN; break; \ + case e_FM_MAC_EX_1G_TX_DATA_ERR: \ + bitMask = DTSEC_IMASK_TDPEEN; break; \ + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \ + bitMask = DTSEC_IMASK_MSROEN ; break; \ default: bitMask = 0;break;} @@ -145,192 +122,18 @@ typedef uint32_t t_ErrorDisable; #define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */ -#define DTSEC_TO_MII_OFFSET 0x1120 /* number of pattern match registers (entries) */ - -#define DEFAULT_errorDisabled 0 -#define DEFAULT_promiscuousEnable FALSE -#define DEFAULT_pauseExtended 0x0 -#define DEFAULT_pauseTime 0xf000 -#define DEFAULT_halfDuplex FALSE -#define DEFAULT_halfDulexFlowControlEn FALSE -#define DEFAULT_txTimeStampEn FALSE -#define DEFAULT_rxTimeStampEn FALSE -#define DEFAULT_packetAlignment 0 -#define DEFAULT_controlFrameAccept FALSE -#define DEFAULT_groupHashExtend FALSE -#define DEFAULT_broadcReject FALSE -#define DEFAULT_rxShortFrame TRUE -#define DEFAULT_exactMatch FALSE -#define DEFAULT_debugMode FALSE -#define DEFAULT_loopback FALSE -#define DEFAULT_actOnRxPauseFrame TRUE -#define DEFAULT_actOnTxPauseFrame TRUE - -#define DEFAULT_PreAmLength 0x7 -#define DEFAULT_PreAmRxEn FALSE -#define DEFAULT_PreAmTxEn FALSE -#define DEFAULT_lengthCheckEnable FALSE -#define DEFAULT_padAndCrcEnable TRUE -#define DEFAULT_crcEnable FALSE - -#define DEFAULT_nonBackToBackIpg1 0x40 -#define DEFAULT_nonBackToBackIpg2 0x60 -#define DEFAULT_minIfgEnforcement 0x50 -#define DEFAULT_backToBackIpg 0x60 - -#define DEFAULT_altBackoffVal 0x0A -#define DEFAULT_altBackoffEnable FALSE -#define DEFAULT_backPressureNoBackoff FALSE -#define DEFAULT_noBackoff FALSE -#define DEFAULT_excessDefer TRUE -#define DEFAULT_maxRetransmission 0x0F -#define DEFAULT_collisionWindow 0x37 - -#define DEFAULT_maxFrameLength 0x600 - -#define DEFAULT_collisionWindow 0x37 - -#define DEFAULT_fifoTxThr 0x10 -#define DEFAULT_fifoTxWatermarkH 0x7e -#define DEFAULT_fifoRxWatermarkL 0x08 -#define DEFAULT_tbiPhyAddr 5 - -#define DEFAULT_exceptions ((uint32_t)(IMASK_BREN | \ - IMASK_RXCEN | \ - IMASK_BTEN | \ - IMASK_TXCEN | \ - IMASK_TXEEN | \ - IMASK_ABRTEN | \ - IMASK_LCEN | \ - IMASK_CRLEN | \ - IMASK_XFUNEN | \ - IMASK_IFERREN | \ - IMASK_MAGEN | \ - IMASK_TDPEEN | \ - IMASK_RDPEEN)) +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */ +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */ +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */ #define MAX_PHYS 32 /* maximum number of phys */ -#define DTSEC_ID1_ID 0xffff0000 -#define DTSEC_ID1_REV_MJ 0x0000FF00 -#define DTSEC_ID1_REV_MN 0x000000ff - -#define ID2_INT_REDUCED_OFF 0x00010000 -#define ID2_INT_NORMAL_OFF 0x00020000 - -#define ECNTRL_CLRCNT 0x00004000 -#define ECNTRL_AUTOZ 0x00002000 -#define ECNTRL_STEN 0x00001000 -#define ECNTRL_CFG_RO 0x80000000 -#define ECNTRL_GMIIM 0x00000040 -#define ECNTRL_TBIM 0x00000020 -#define ECNTRL_SGMIIM 0x00000002 -#define ECNTRL_RPM 0x00000010 -#define ECNTRL_R100M 0x00000008 -#define ECNTRL_RMM 0x00000004 -#define ECNTRL_QSGMIIM 0x00000001 - -#define TCTRL_THDF 0x00000800 -#define TCTRL_TTSE 0x00000040 -#define TCTRL_GTS 0x00000020 -#define TCTRL_TFC_PAUSE 0x00000010 - -/* PTV offsets */ -#define PTV_PTE_OFST 16 - -#define RCTRL_CFA 0x00008000 -#define RCTRL_GHTX 0x00000400 -#define RCTRL_RTSE 0x00000040 -#define RCTRL_GRS 0x00000020 -#define RCTRL_BC_REJ 0x00000010 -#define RCTRL_MPROM 0x00000008 -#define RCTRL_RSF 0x00000004 -#define RCTRL_EMEN 0x00000002 -#define RCTRL_UPROM 0x00000001 -#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM) - -#define TMR_CTL_ESFDP 0x00000800 -#define TMR_CTL_ESFDE 0x00000400 - -#define TSEC_ID1_DEBUG 0x00e00c00 -#define DEBUG_ENABLE 0x80000000 -#define DPERROR_Tx_ERROR_ON_SEC 0x00400000 -#define DPERROR_Tx_ERROR_ON_WRITE 0x10000000 -#define DPERROR_Rx_ERROR_ON_SEC 0x00000040 -#define DPERROR_Rx_ERROR_ON_WRITE 0x00001000 -#define DPERROR_STT 0x80000000 -#define DPERROR_STR 0x00008000 - -#define MACCFG1_SOFT_RESET 0x80000000 -#define MACCFG1_LOOPBACK 0x00000100 -#define MACCFG1_RX_FLOW 0x00000020 -#define MACCFG1_TX_FLOW 0x00000010 -#define MACCFG1_TX_EN 0x00000001 -#define MACCFG1_RX_EN 0x00000004 -#define MACCFG1_RESET_RxMC 0x00080000 -#define MACCFG1_RESET_TxMC 0x00040000 -#define MACCFG1_RESET_RxFUN 0x00020000 -#define MACCFG1_RESET_TxFUN 0x00010000 - -#define MACCFG2_NIBBLE_MODE 0x00000100 -#define MACCFG2_BYTE_MODE 0x00000200 -#define MACCFG2_PRE_AM_Rx_EN 0x00000080 -#define MACCFG2_PRE_AM_Tx_EN 0x00000040 -#define MACCFG2_LENGTH_CHECK 0x00000010 -#define MACCFG2_MAGIC_PACKET_EN 0x00000008 -#define MACCFG2_PAD_CRC_EN 0x00000004 -#define MACCFG2_CRC_EN 0x00000002 -#define MACCFG2_FULL_DUPLEX 0x00000001 - -#define PREAMBLE_LENGTH_SHIFT 12 - -#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24 -#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16 -#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8 - -#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000 -#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000 -#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00 -#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F - -#define HAFDUP_ALT_BEB 0x00080000 -#define HAFDUP_BP_NO_BACKOFF 0x00040000 -#define HAFDUP_NO_BACKOFF 0x00020000 -#define HAFDUP_EXCESS_DEFER 0x00010000 -#define HAFDUP_COLLISION_WINDOW 0x000003ff - -#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20 -#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12 -#define HAFDUP_RETRANSMISSION_MAX 0x0000f000 - -#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */ - -#define DEBUG_GET_FIFO_READ_INDEX 0x007f0000 -#define DEBUG_GET_FIFO_WRITE_INDEX 0x0000007f -/* Pause Time Value Register */ -#define PTV_PTE_SHIFT 16 - -#define MASK22BIT 0x003FFFFF -#define MASK16BIT 0x0000FFFF -#define MASK12BIT 0x00000FFF -#define MASK8BIT 0x000000FF - #define VAL32BIT 0x100000000LL #define VAL22BIT 0x00400000 #define VAL16BIT 0x00010000 #define VAL12BIT 0x00001000 -/* PHY Control Register */ -#define PHY_CR_LOOPBACK 0x4000 -#define PHY_CR_SPEED0 0x2000 -#define PHY_CR_ANE 0x1000 -#define PHY_CR_FULLDUPLEX 0x0100 -#define PHY_CR_SPEED1 0x0040 - -#define PHY_TBICON_SRESET 0x8000 -#define PHY_TBICON_SPEED2 0x0020 - /* CAR1/2 bits */ #define CAR1_TR64 0x80000000 #define CAR1_TR127 0x40000000 @@ -363,19 +166,6 @@ typedef uint32_t t_ErrorDisable; #define CAR2_TXPF 0x00000200 #define CAR2_TDRP 0x00000001 -#define CAM1_ERRORS_ONLY (CAR1_RXPF | \ - CAR1_RALN | \ - CAR1_RFLR | \ - CAR1_RCDE | \ - CAR1_RCSE | \ - CAR1_RUND | \ - CAR1_ROVR | \ - CAR1_RFRG | \ - CAR1_RJBR | \ - CAR1_RDRP) - -#define CAM2_ERRORS_ONLY (CAR2_TFCS | CAR2_TXPF | CAR2_TDRP) - typedef struct t_InternalStatistics { uint64_t tr64; @@ -408,202 +198,11 @@ typedef struct t_InternalStatistics uint64_t tfcs; } t_InternalStatistics; -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(push,1) -#endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START - -typedef _Packed struct -{ - uint32_t exact_match1; /* octets 1-4 */ - uint32_t exact_match2; /* octets 5-6 */ -} _PackedType macRegs; - -typedef _Packed struct -{ - volatile uint32_t tsec_id1; /* 0x000 ETSEC_ID register */ - volatile uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */ - volatile uint32_t ievent; /* 0x008 Interrupt event register */ - volatile uint32_t imask; /* 0x00C Interrupt mask register */ - volatile uint32_t edis; /* 0x010 Error disabled register */ - volatile uint32_t ecntrl; /* 0x014 E control register */ - volatile uint32_t ptv; /* 0x018 Pause time value register */ - volatile uint32_t tbipa; /* 0x01C TBI PHY address register */ - volatile uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */ - volatile uint32_t tmr_pevent; /* 0x024 Time-stamp event register */ - volatile uint32_t tmr_pemask; /* 0x028 Timer event mask register */ - volatile uint32_t DTSEC_RESERVED2; /* 0x02C */ - volatile uint32_t iobistctl; /* 0x030 IO BIST Control register */ - volatile uint32_t DTSEC_RESERVED3[3]; /* 0x034 */ - - volatile uint32_t tctrl; /* 0x040 Transmit control register */ - volatile uint32_t DTSEC_RESERVED4[3]; /* 0x044-0x04C */ - volatile uint32_t rctrl; /* 0x050 Receive control register */ - volatile uint32_t DTSEC_RESERVED5[11]; /* 0x054- 0x07C */ - - volatile uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address registers 0-7 */ - volatile uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */ - volatile uint32_t ETSEC_RESERVED6[16]; /* 0x0C0-0x0FC */ - - volatile uint32_t maccfg1; /* 0x100 MAC configuration #1 */ - volatile uint32_t maccfg2; /* 0x104 MAC configuration #2 */ - volatile uint32_t ipgifg; /* 0x108 IPG/IFG */ - volatile uint32_t hafdup; /* 0x10C Half-duplex */ - volatile uint32_t maxfrm; /* 0x110 Maximum frame */ - volatile uint32_t DTSEC_RESERVED7[3]; /* 0x114-0x11C register */ - t_MiiAccessMemMap miiMemMap; - volatile uint32_t ifctrl; /* 0x138 MII Mgmt:interface control */ - volatile uint32_t ifstat; /* 0x13C Interface status */ - volatile uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */ - volatile uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */ - volatile macRegs macaddr[DTSEC_NUM_OF_PADDRS]; /* 0x148-0x1BC mac exact match addresses 1-15, parts 1-2 */ - volatile uint32_t DTSEC_RESERVED8[16]; /* 0x1C0-0x1FC register */ - - /* RMON MIB REGISTERS */ - /* TRANSMIT and RECEIVE COUNTERS */ - - volatile uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */ - volatile uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame counter */ - volatile uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame counter */ - volatile uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame counter */ - volatile uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame counter */ - volatile uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame counter */ - volatile uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good VLAN frame count */ - - /* RECEIVE COUNTERS */ - volatile uint32_t rbyt; /* 0x21C receive byte counter */ - volatile uint32_t rpkt; /* 0x220 receive packet counter */ - volatile uint32_t rfcs; /* 0x224 receive FCS error counter */ - volatile uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */ - volatile uint32_t rbca; /* 0x22C receive broadcast packet counter */ - volatile uint32_t rxcf; /* 0x230 receive control frame packet counter */ - volatile uint32_t rxpf; /* 0x234 receive PAUSE frame packet counter */ - volatile uint32_t rxuo; /* 0x238 receive unknown OP code counter */ - volatile uint32_t raln; /* 0x23C receive alignment error counter */ - volatile uint32_t rflr; /* 0x240 receive frame length error counter */ - volatile uint32_t rcde; /* 0x244 receive code error counter */ - volatile uint32_t rcse; /* 0x248 receive carrier sense error counter */ - volatile uint32_t rund; /* 0x24C receive undersize packet counter */ - volatile uint32_t rovr; /* 0x250 receive oversize packet counter */ - volatile uint32_t rfrg; /* 0x254 receive fragments counter */ - volatile uint32_t rjbr; /* 0x258 receive jabber counter */ - volatile uint32_t rdrp; /* 0x25C receive drop */ - - /* TRANSMIT COUNTERS */ - volatile uint32_t tbyt; /* 0x260 transmit byte counter */ - volatile uint32_t tpkt; /* 0x264 transmit packet counter */ - volatile uint32_t tmca; /* 0x268 transmit multicast packet counter */ - volatile uint32_t tbca; /* 0x26C transmit broadcast packet counter */ - volatile uint32_t txpf; /* 0x270 transmit PAUSE control frame counter */ - volatile uint32_t tdfr; /* 0x274 transmit deferral packet counter */ - volatile uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */ - volatile uint32_t tscl; /* 0x27C transmit single collision packet counter */ - volatile uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */ - volatile uint32_t tlcl; /* 0x284 transmit late collision packet counter */ - volatile uint32_t txcl; /* 0x288 transmit excessive collision packet counter */ - volatile uint32_t tncl; /* 0x28C transmit total collision counter */ - volatile uint32_t DTSEC_RESERVED9; /* 0x290 */ - volatile uint32_t tdrp; /* 0x294 transmit drop frame counter */ - volatile uint32_t tjbr; /* 0x298 transmit jabber frame counter */ - volatile uint32_t tfcs; /* 0x29C transmit FCS error counter */ - volatile uint32_t txcf; /* 0x2A0 transmit control frame counter */ - volatile uint32_t tovr; /* 0x2A4 transmit oversize frame counter */ - volatile uint32_t tund; /* 0x2A8 transmit undersize frame counter */ - volatile uint32_t tfrg; /* 0x2AC transmit fragments frame counter */ - - /* GENERAL REGISTERS */ - volatile uint32_t car1; /* 0x2B0 carry register one register* */ - volatile uint32_t car2; /* 0x2B4 carry register two register* */ - volatile uint32_t cam1; /* 0x2B8 carry register one mask register */ - volatile uint32_t cam2; /* 0x2BC carry register two mask register */ - volatile uint32_t DTSEC_RESERVED10[16]; /* 0x2C0-0x2FC */ - - /* Debug and Factory Test Registers */ - volatile uint32_t debug; /* 0x300 DEBUG - Debug Register */ - volatile uint32_t dperror; /* 0x304 DPERROR - Parity Error Register */ - volatile uint32_t hwassert; /* 0x308 HWASSERT */ - volatile uint32_t RESERVED11; /* 0x30C Reserved */ - volatile uint32_t rx_fifo_ptr; /* 0x310 RXFIFOPTR - Rx FIFO R/W Pointer Register */ - volatile uint32_t rx_fifo_dath; /* 0x314 RXFIFODATH - Rx FIFO Data Register */ - volatile uint32_t rx_fifo_datl; /* 0x318 RXFIFODATL - Rx FIFO Data Register */ - volatile uint32_t rx_fifo_stat; /* 0x31C RXFIFOSTAT - Rx FIFO Status Register */ - volatile uint32_t tx_fifo_ptr; /* 0x320 TXFIFOPTR - Tx FIFO R/W Pointer Register */ - volatile uint32_t tx_fifo_dath; /* 0x324 TXFIFODATH - Rx FIFO Data Register */ - volatile uint32_t tx_fifo_datl; /* 0x328 TXFIFODATL - Rx FIFO Data Register */ - volatile uint32_t tx_fifo_stat; /* 0x32C TXFIFOSTAT - Tx FIFO Status Register */ - volatile uint32_t pkt_rcv_cnt; /* 0x330 PKTRCVCNT - Number of packets accepted and written to Rx FIFO */ - volatile uint32_t RESERVED12[3]; /* 0x334-0x33C Reserved */ - volatile uint32_t tx_threshold; /* 0x340 Transmit threshold; Number of entries (4 bytes units) before starting to transmit to the MAC */ - volatile uint32_t tx_watermark_high;/* 0x344 Transmit watermark high; Number of entries (4 byte units) before de-asserting Ready to packet Interface */ - volatile uint32_t rx_watermark_low; /* 0x348 Receive watermark low; Number of entries (4 byte units) before unloading to packet Interface */ -} _PackedType t_DtsecMemMap; - -#define MEM_MAP_END -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(pop) -#endif /* defined(__MWERKS__) && ... */ - - -typedef struct { - uint32_t errorDisabled; - bool halfDuplex; - uint16_t pauseTime; - uint16_t pauseExtended; - uint8_t tbiPhyAddr; /**< TBI Physical address (1-31) [DEFAULT_tbiPhyAddr] */ - - bool autoZeroCounters; - bool promiscuousEnable; - - bool halfDulexFlowControlEn; - bool txTimeStampEn; - bool rxTimeStampEn; - - uint8_t packetAlignmentPadding; - bool controlFrameAccept; - bool groupHashExtend; - bool broadcReject; - bool rxShortFrame; - bool exactMatch; - - bool debugMode; - - bool loopback; - bool actOnRxPauseFrame; - bool actOnTxPauseFrame; - - uint8_t nonBackToBackIpg1; - uint8_t nonBackToBackIpg2; - uint8_t minIfgEnforcement; - uint8_t backToBackIpg; - - uint8_t preambleLength; - bool preambleRxEn; - bool preambleTxEn; - bool lengthCheckEnable; - bool magicPacketEnable; - bool padAndCrcEnable; - bool crcEnable; - - bool alternateBackoffEnable; - uint8_t alternateBackoffVal; - bool backPressureNoBackoff; - bool noBackoff; - bool excessDefer; - uint8_t maxRetransmission; - uint16_t collisionWindow; - - uint16_t maxFrameLength; - - uint8_t fifoTxThr; - uint8_t fifoTxWatermarkH; - uint8_t fifoRxWatermarkL; -} t_DtsecDriverParam; - typedef struct { t_FmMacControllerDriver fmMacControllerDriver; t_Handle h_App; /**< Handle to the upper layer application */ - t_DtsecMemMap *p_MemMap; /**< pointer to dTSEC memory mapped registers. */ - t_MiiAccessMemMap *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */ + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */ + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */ uint64_t addr; /**< MAC address of device; */ e_EnetMode enetMode; /**< Ethernet physical interface */ t_FmMacExceptionCallback *f_Exception; @@ -612,23 +211,18 @@ typedef struct { bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */ uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */ - bool debugMode; bool halfDuplex; t_InternalStatistics internalStatistics; t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */ t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */ uint8_t macId; + uint8_t tbi_phy_addr; uint32_t exceptions; bool ptpTsuEnabled; bool enTsuErrExeption; e_FmMacStatisticsLevel statisticsLevel; - - t_DtsecDriverParam *p_DtsecDriverParam; + struct dtsec_cfg *p_DtsecDriverParam; } t_Dtsec; -t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data); -t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); - - #endif /* __DTSEC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c index be85fa21b206..87da25ff9e35 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File dtsec_mii_acc.c @@ -40,6 +41,7 @@ #include "std_ext.h" #include "fm_mac.h" #include "dtsec.h" +#include "fsl_fman_dtsec_mii_acc.h" /*****************************************************************************/ @@ -48,33 +50,20 @@ t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t reg, uint16_t data) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_MiiAccessMemMap *p_MiiAccess; - uint32_t tmpReg; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + struct dtsec_mii_reg *miiregs; + uint16_t dtsec_freq; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); - p_MiiAccess = p_Dtsec->p_MiiMemMap; + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1); + miiregs = p_Dtsec->p_MiiMemMap; - /* Stop the MII management read cycle */ - WRITE_UINT32(p_MiiAccess->miimcom, 0); - /* Dummy read to make sure MIIMCOM is written */ - tmpReg = GET_UINT32(p_MiiAccess->miimcom); + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq); - /* Setting up MII Management Address Register */ - tmpReg = (uint32_t)((phyAddr << MIIMADD_PHY_ADDR_SHIFT) | reg); - WRITE_UINT32(p_MiiAccess->miimadd, tmpReg); - - /* Setting up MII Management Control Register with data */ - WRITE_UINT32(p_MiiAccess->miimcon, (uint32_t)data); - /* Dummy read to make sure MIIMCON is written */ - tmpReg = GET_UINT32(p_MiiAccess->miimcon); - - /* Wait till MII management write is complete */ - while ((GET_UINT32(p_MiiAccess->miimind)) & MIIMIND_BUSY) ; - - return E_OK; + return err; } /*****************************************************************************/ @@ -83,38 +72,26 @@ t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t reg, uint16_t *p_Data) { - t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; - t_MiiAccessMemMap *p_MiiAccess; - uint32_t tmpReg; + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; + struct dtsec_mii_reg *miiregs; + uint16_t dtsec_freq; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); - p_MiiAccess = p_Dtsec->p_MiiMemMap; + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1); + miiregs = p_Dtsec->p_MiiMemMap; - /* Setting up the MII Management Address Register */ - tmpReg = (uint32_t)((phyAddr << MIIMADD_PHY_ADDR_SHIFT) | reg); - WRITE_UINT32(p_MiiAccess->miimadd, tmpReg); - - /* Perform an MII management read cycle */ - WRITE_UINT32(p_MiiAccess->miimcom, MIIMCOM_READ_CYCLE); - /* Dummy read to make sure MIIMCOM is written */ - tmpReg = GET_UINT32(p_MiiAccess->miimcom); - - /* Wait till MII management read is complete */ - while ((GET_UINT32(p_MiiAccess->miimind)) & MIIMIND_BUSY) ; - - /* Read MII management status */ - *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->miimstat); - - WRITE_UINT32(p_MiiAccess->miimcom, 0); - /* Dummy read to make sure MIIMCOM is written */ - tmpReg = GET_UINT32(p_MiiAccess->miimcom); + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq); if (*p_Data == 0xffff) RETURN_ERROR(MINOR, E_NO_DEVICE, ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x", phyAddr, reg)); + if (err) + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG); return E_OK; } + diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h index 7c529c2bd02d..75cc658a5c50 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,43 +36,7 @@ #include "std_ext.h" -/* MII Management Configuration Register */ -#define MIIMCFG_RESET_MGMT 0x80000000 -#define MIIMCFG_MGMT_CLOCK_SELECT 0x00000007 - -/* MII Management Command Register */ -#define MIIMCOM_READ_CYCLE 0x00000001 -#define MIIMCOM_SCAN_CYCLE 0x00000002 - -/* MII Management Address Register */ -#define MIIMADD_PHY_ADDR_SHIFT 8 - -/* MII Management Indicator Register */ -#define MIIMIND_BUSY 0x00000001 - - -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(push,1) -#endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START - -/*----------------------------------------------------*/ -/* MII Configuration Control Memory Map Registers */ -/*----------------------------------------------------*/ -typedef _Packed struct t_MiiAccessMemMap -{ - volatile uint32_t miimcfg; /* MII Mgmt:configuration */ - volatile uint32_t miimcom; /* MII Mgmt:command */ - volatile uint32_t miimadd; /* MII Mgmt:address */ - volatile uint32_t miimcon; /* MII Mgmt:control 3 */ - volatile uint32_t miimstat; /* MII Mgmt:status */ - volatile uint32_t miimind; /* MII Mgmt:indicators */ -} _PackedType t_MiiAccessMemMap ; - -#define MEM_MAP_END -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(pop) -#endif /* defined(__MWERKS__) && ... */ - +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data); +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); #endif /* __DTSEC_MII_ACC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c index 4eb39540ee9b..20bf150a36ff 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_mac.c @@ -45,18 +46,34 @@ #include "fm_mac.h" -/* ........................................................................... */ +/* ......................................................................... */ t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam) { t_FmMacControllerDriver *p_FmMacControllerDriver; + uint16_t fmClkFreq; SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL); - if(ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000) + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm); + if (fmClkFreq == 0) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!")); + return NULL; + } + +#if (DPAA_VERSION == 10) + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000) p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam); else - p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam); +#if FM_MAX_NUM_OF_10G_MACS > 0 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam); +#else + p_FmMacControllerDriver = NULL; +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */ +#else + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam); +#endif /* (DPAA_VERSION == 10) */ if (!p_FmMacControllerDriver) return NULL; @@ -66,10 +83,12 @@ t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam) p_FmMacControllerDriver->macId = p_FmMacParam->macId; p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit; + p_FmMacControllerDriver->clkFreq = fmClkFreq; + return (t_Handle)p_FmMacControllerDriver; } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_Init (t_Handle h_FmMac) { @@ -78,20 +97,19 @@ t_Error FM_MAC_Init (t_Handle h_FmMac) SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); if (p_FmMacControllerDriver->resetOnInit && + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit && (FmResetMac(p_FmMacControllerDriver->h_Fm, - ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ? e_FM_MAC_10G : e_FM_MAC_1G), - p_FmMacControllerDriver->macId) != E_OK)) + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ? + e_FM_MAC_10G : e_FM_MAC_1G), + p_FmMacControllerDriver->macId) != E_OK)) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!")); - if ((p_FmMacControllerDriver->clkFreq = FmGetClockFreq(p_FmMacControllerDriver->h_Fm)) == 0) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!")); - if (p_FmMacControllerDriver->f_FM_MAC_Init) return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac); RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_Free (t_Handle h_FmMac) { @@ -105,7 +123,7 @@ t_Error FM_MAC_Free (t_Handle h_FmMac) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable) { @@ -113,12 +131,15 @@ t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable) SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit) + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable); + p_FmMacControllerDriver->resetOnInit = enable; return E_OK; } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal) { @@ -132,7 +153,7 @@ t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal) { @@ -145,7 +166,7 @@ t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag) { @@ -159,7 +180,7 @@ t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal) { @@ -173,7 +194,7 @@ t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal) { @@ -187,7 +208,21 @@ t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ + +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; + + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr) + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +/* ......................................................................... */ t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal) { @@ -201,7 +236,7 @@ t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) { @@ -216,7 +251,7 @@ t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool ena } #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac) { @@ -236,7 +271,7 @@ t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac) /* Run Time Control */ /*****************************************************************************/ -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode) { @@ -250,7 +285,7 @@ t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode) { @@ -264,7 +299,19 @@ t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +t_Error FM_MAC_Resume (t_Handle h_FmMac) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; + + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacControllerDriver->f_FM_MAC_Resume) + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac); + + return E_OK; +} + +/* ......................................................................... */ t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac) { @@ -278,7 +325,7 @@ t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac) { @@ -292,21 +339,43 @@ t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ -t_Error FM_MAC_SetTxAutoPauseFrames (t_Handle h_FmMac, uint16_t pauseTime) +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac, + uint16_t pauseTime) { t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames) - return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac, pauseTime); + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac, + pauseTime); RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ + +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; + + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames) + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac, + priority, + pauseTime, + threshTime); + + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); +} + +/* ......................................................................... */ t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en) { @@ -320,7 +389,21 @@ t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ + +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; + + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan) + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +/* ......................................................................... */ t_Error FM_MAC_ResetCounters (t_Handle h_FmMac) { @@ -334,7 +417,7 @@ t_Error FM_MAC_ResetCounters (t_Handle h_FmMac) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) { @@ -348,7 +431,7 @@ t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel) { @@ -358,10 +441,11 @@ t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statistic if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics) return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics) { @@ -375,7 +459,7 @@ t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) { @@ -389,7 +473,7 @@ t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) { @@ -403,7 +487,7 @@ t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) { @@ -417,7 +501,7 @@ t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) { @@ -431,7 +515,7 @@ t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) { @@ -445,7 +529,7 @@ t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAdd RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion) { @@ -460,7 +544,7 @@ t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion) } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId) { @@ -474,7 +558,7 @@ t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal) { @@ -488,7 +572,7 @@ t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex) { @@ -502,7 +586,21 @@ t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ + +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; + + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg) + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +/* ......................................................................... */ t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data) { @@ -516,7 +614,7 @@ t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data) { @@ -530,7 +628,7 @@ t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, u RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); } -/* ........................................................................... */ +/* ......................................................................... */ uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac) { diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h index 9a64f14bfc92..a73e198405ee 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_mac.h @@ -42,11 +43,18 @@ #include "error_ext.h" #include "list_ext.h" #include "fm_mac_ext.h" +#include "fm_common.h" #define __ERR_MODULE__ MODULE_FM_MAC +/**************************************************************************//** + @Description defaults +*//***************************************************************************/ + +#define DEFAULT_halfDuplex FALSE +#define DEFAULT_padAndCrcEnable TRUE #define DEFAULT_resetOnInit FALSE @@ -54,7 +62,7 @@ typedef struct { uint64_t addr; /* Ethernet Address */ t_List node; } t_EthHashEntry; -#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node) +#define ETH_HASH_ENTRY_OBJ(ptr) NCSW_LIST_OBJECT(ptr, t_EthHashEntry, node) typedef struct { uint16_t size; @@ -72,7 +80,9 @@ typedef struct { t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal); t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal); t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal); + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal); t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable); + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable); #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac); #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ @@ -81,11 +91,17 @@ typedef struct { t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode); t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode); + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac); t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac); t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac); t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait); - t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac, uint16_t pauseTime); + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac, + uint16_t pauseTime); + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime); t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en); t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac); @@ -99,6 +115,9 @@ typedef struct { t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal); t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex); + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac); + + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en); t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId); @@ -113,16 +132,21 @@ typedef struct { t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac); #endif /* (defined(DEBUG_ERRORS) && ... */ - t_Handle h_Fm; - e_EnetMode enetMode; - uint8_t macId; - bool resetOnInit; - uint16_t clkFreq; + t_Handle h_Fm; + t_FmRevisionInfo fmRevInfo; + e_EnetMode enetMode; + uint8_t macId; + bool resetOnInit; + uint16_t clkFreq; } t_FmMacControllerDriver; +#if (DPAA_VERSION == 10) t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam); t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams); +#else +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam); +#endif /* (DPAA_VERSION == 10) */ uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac); @@ -131,10 +155,10 @@ uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac); static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst) { t_EthHashEntry *p_HashEntry = NULL; - if (!LIST_IsEmpty(p_AddrLst)) + if (!NCSW_LIST_IsEmpty(p_AddrLst)) { p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next); - LIST_DelAndInit(&p_HashEntry->node); + NCSW_LIST_DelAndInit(&p_HashEntry->node); } return p_HashEntry; } @@ -146,21 +170,25 @@ static __inline__ void FreeHashTable(t_EthHash *p_Hash) t_EthHashEntry *p_HashEntry; int i = 0; - if (!p_Hash || !p_Hash->p_Lsts) - return; - - for(i=0; isize; i++) + if (p_Hash) { - p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); - while (p_HashEntry) + if (p_Hash->p_Lsts) { - XX_Free(p_HashEntry); - p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); - } - } + for (i=0; isize; i++) + { + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); + while (p_HashEntry) + { + XX_Free(p_HashEntry); + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); + } + } - XX_Free(p_Hash->p_Lsts); - XX_Free(p_Hash); + XX_Free(p_Hash->p_Lsts); + } + + XX_Free(p_Hash); + } } /* ........................................................................... */ @@ -171,7 +199,7 @@ static __inline__ t_EthHash * AllocHashTable(uint16_t size) t_EthHash *p_Hash; /* Allocate address hash table */ - p_Hash = (t_EthHash *)XX_Malloc(size*sizeof(t_EthHash *)); + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash)); if (!p_Hash) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table")); @@ -187,7 +215,7 @@ static __inline__ t_EthHash * AllocHashTable(uint16_t size) return NULL; } - for(i=0 ; isize; i++) + for (i=0 ; isize; i++) INIT_LIST(&p_Hash->p_Lsts[i]); return p_Hash; diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.c new file mode 100644 index 000000000000..b6a4ca25f80c --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.c @@ -0,0 +1,119 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fman_crc32.h" +#include "common/general.h" + + +/* precomputed CRC values for address hashing */ +static const uint32_t crc_tbl[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */ +static inline uint8_t get_mirror8(uint8_t n) +{ + uint8_t mirror[16] = { + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f + }; + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))); +} + +static inline uint32_t get_mirror32(uint32_t n) +{ + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) | + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) | + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) | + ((uint32_t)get_mirror8((uint8_t)(n>>24))); +} + +uint32_t get_mac_addr_crc(uint64_t _addr) +{ + uint32_t i; + uint8_t data; + uint32_t crc; + + /* CRC calculation */ + crc = 0xffffffff; + for (i = 0; i < 6; i++) { + data = (uint8_t)(_addr >> ((5-i)*8)); + crc = crc ^ data; + crc = crc_tbl[crc&0xff] ^ (crc>>8); + } + + crc = get_mirror32(crc); + return crc; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.h b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.h new file mode 100644 index 000000000000..6e32fdc6c5f6 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_crc32.h @@ -0,0 +1,43 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +#ifndef __FMAN_CRC32_H +#define __FMAN_CRC32_H + +#include "common/general.h" + + +uint32_t get_mac_addr_crc(uint64_t _addr); + + +#endif /* __FMAN_CRC32_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c new file mode 100644 index 000000000000..5b092865632f --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c @@ -0,0 +1,845 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_dtsec.h" + + +void fman_dtsec_stop_rx(struct dtsec_regs *regs) +{ + /* Assert the graceful stop bit */ + iowrite32be(ioread32be(®s->rctrl) | RCTRL_GRS, ®s->rctrl); +} + +void fman_dtsec_stop_tx(struct dtsec_regs *regs) +{ + /* Assert the graceful stop bit */ + iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_GTS, ®s->tctrl); +} + +void fman_dtsec_start_tx(struct dtsec_regs *regs) +{ + /* clear the graceful stop bit */ + iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_GTS, ®s->tctrl); +} + +void fman_dtsec_start_rx(struct dtsec_regs *regs) +{ + /* clear the graceful stop bit */ + iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_GRS, ®s->rctrl); +} + +void fman_dtsec_defconfig(struct dtsec_cfg *cfg) +{ + cfg->halfdup_on = DEFAULT_HALFDUP_ON; + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT; + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW; + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER; + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF; + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF; + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL; + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN; + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST; + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM; + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK; + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC; + cfg->tx_crc = DEFAULT_TX_CRC; + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC; + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME; + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/ + cfg->rx_prepend = DEFAULT_RX_PREPEND; + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN; + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN; + cfg->preamble_len = DEFAULT_PREAMBLE_LEN; + cfg->rx_preamble = DEFAULT_RX_PREAMBLE; + cfg->tx_preamble = DEFAULT_TX_PREAMBLE; + cfg->loopback = DEFAULT_LOOPBACK; + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN; + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN; + cfg->rx_flow = DEFAULT_RX_FLOW; + cfg->tx_flow = DEFAULT_TX_FLOW; + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD; + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD; + cfg->rx_promisc = DEFAULT_RX_PROMISC; + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1; + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2; + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT; + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG; + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME; + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR; + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN; +} + +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg, + enum enet_interface iface_mode, + enum enet_speed iface_speed, + uint8_t *macaddr, + uint8_t fm_rev_maj, + uint8_t fm_rev_min, + uint32_t exception_mask) +{ + bool is_rgmii = FALSE; + bool is_sgmii = FALSE; + bool is_qsgmii = FALSE; + int i; + uint32_t tmp; + +UNUSED(fm_rev_maj);UNUSED(fm_rev_min); + + /* let's start with a soft reset */ + iowrite32be(MACCFG1_SOFT_RESET, ®s->maccfg1); + iowrite32be(0, ®s->maccfg1); + + /*************dtsec_id2******************/ + tmp = ioread32be(®s->tsec_id2); + + /* check RGMII support */ + if (iface_mode == E_ENET_IF_RGMII || + iface_mode == E_ENET_IF_RMII) + if (tmp & DTSEC_ID2_INT_REDUCED_OFF) + return -EINVAL; + + if (iface_mode == E_ENET_IF_SGMII || + iface_mode == E_ENET_IF_MII) + if (tmp & DTSEC_ID2_INT_REDUCED_OFF) + return -EINVAL; + + /***************ECNTRL************************/ + + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE); + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE); + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE); + + tmp = 0; + if (is_rgmii || iface_mode == E_ENET_IF_GMII) + tmp |= DTSEC_ECNTRL_GMIIM; + if (is_sgmii) + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM); + if (is_qsgmii) + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM | + DTSEC_ECNTRL_QSGMIIM); + if (is_rgmii) + tmp |= DTSEC_ECNTRL_RPM; + if (iface_speed == E_ENET_SPEED_100) + tmp |= DTSEC_ECNTRL_R100M; + + iowrite32be(tmp, ®s->ecntrl); + /***************ECNTRL************************/ + + /***************TCTRL************************/ + tmp = 0; + if (cfg->halfdup_on) + tmp |= DTSEC_TCTRL_THDF; + if (cfg->tx_time_stamp_en) + tmp |= DTSEC_TCTRL_TTSE; + + iowrite32be(tmp, ®s->tctrl); + + /***************TCTRL************************/ + + /***************PTV************************/ + tmp = 0; + +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 + if ((fm_rev_maj == 1) && (fm_rev_min == 0)) + cfg->tx_pause_time += 2; +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ + + if (cfg->tx_pause_time) + tmp |= cfg->tx_pause_time; + if (cfg->tx_pause_time_extd) + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST; + iowrite32be(tmp, ®s->ptv); + + /***************RCTRL************************/ + tmp = 0; + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16; + if (cfg->rx_ctrl_acc) + tmp |= RCTRL_CFA; + if (cfg->rx_group_hash_exd) + tmp |= RCTRL_GHTX; + if (cfg->rx_time_stamp_en) + tmp |= RCTRL_RTSE; + if (cfg->rx_drop_bcast) + tmp |= RCTRL_BC_REJ; + if (cfg->rx_short_frm) + tmp |= RCTRL_RSF; + if (cfg->rx_promisc) + tmp |= RCTRL_PROM; + + iowrite32be(tmp, ®s->rctrl); + /***************RCTRL************************/ + + /* + * Assign a Phy Address to the TBI (TBIPA). + * Done also in cases where TBI is not selected to avoid conflict with + * the external PHY's Physical address + */ + iowrite32be(cfg->tbipa, ®s->tbipa); + + /***************TMR_CTL************************/ + iowrite32be(0, ®s->tmr_ctrl); + + if (cfg->ptp_tsu_en) { + tmp = 0; + tmp |= TMR_PEVENT_TSRE; + iowrite32be(tmp, ®s->tmr_pevent); + + if (cfg->ptp_exception_en) { + tmp = 0; + tmp |= TMR_PEMASK_TSREEN; + iowrite32be(tmp, ®s->tmr_pemask); + } + } + + /***************MACCFG1***********************/ + tmp = 0; + if (cfg->loopback) + tmp |= MACCFG1_LOOPBACK; + if (cfg->rx_flow) + tmp |= MACCFG1_RX_FLOW; + if (cfg->tx_flow) + tmp |= MACCFG1_TX_FLOW; + iowrite32be(tmp, ®s->maccfg1); + + /***************MACCFG1***********************/ + + /***************MACCFG2***********************/ + tmp = 0; + + if (iface_speed < E_ENET_SPEED_1000) + tmp |= MACCFG2_NIBBLE_MODE; + else if (iface_speed == E_ENET_SPEED_1000) + tmp |= MACCFG2_BYTE_MODE; + + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f) + << PREAMBLE_LENGTH_SHIFT; + + if (cfg->rx_preamble) + tmp |= MACCFG2_PRE_AM_Rx_EN; + if (cfg->tx_preamble) + tmp |= MACCFG2_PRE_AM_Tx_EN; + if (cfg->rx_len_check) + tmp |= MACCFG2_LENGTH_CHECK; + if (cfg->tx_pad_crc) + tmp |= MACCFG2_PAD_CRC_EN; + if (cfg->tx_crc) + tmp |= MACCFG2_CRC_EN; + if (!cfg->halfdup_on) + tmp |= MACCFG2_FULL_DUPLEX; + iowrite32be(tmp, ®s->maccfg2); + + /***************MACCFG2***********************/ + + /***************IPGIFG************************/ + tmp = (((cfg->non_back_to_back_ipg1 << + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) + & IPGIFG_NON_BACK_TO_BACK_IPG_1) + | ((cfg->non_back_to_back_ipg2 << + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) + & IPGIFG_NON_BACK_TO_BACK_IPG_2) + | ((cfg->min_ifg_enforcement << + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) + & IPGIFG_MIN_IFG_ENFORCEMENT) + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG)); + iowrite32be(tmp, ®s->ipgifg); + + /***************IPGIFG************************/ + + /***************HAFDUP************************/ + tmp = 0; + + if (cfg->halfdup_alt_backoff_en) + tmp = (uint32_t)(HAFDUP_ALT_BEB | + ((cfg->halfdup_alt_backoff_val & 0x0000000f) + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT)); + if (cfg->halfdup_bp_no_backoff) + tmp |= HAFDUP_BP_NO_BACKOFF; + if (cfg->halfdup_no_backoff) + tmp |= HAFDUP_NO_BACKOFF; + if (cfg->halfdup_excess_defer) + tmp |= HAFDUP_EXCESS_DEFER; + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT) + & HAFDUP_RETRANSMISSION_MAX); + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW); + + iowrite32be(tmp, ®s->hafdup); + /***************HAFDUP************************/ + + /***************MAXFRM************************/ + /* Initialize MAXFRM */ + iowrite32be(cfg->maximum_frame, ®s->maxfrm); + + /***************MAXFRM************************/ + + /***************CAM1************************/ + iowrite32be(0xffffffff, ®s->cam1); + iowrite32be(0xffffffff, ®s->cam2); + + /***************IMASK************************/ + iowrite32be(exception_mask, ®s->imask); + /***************IMASK************************/ + + /***************IEVENT************************/ + iowrite32be(0xffffffff, ®s->ievent); + + /***************MACSTNADDR1/2*****************/ + + tmp = (uint32_t)((macaddr[5] << 24) | + (macaddr[4] << 16) | + (macaddr[3] << 8) | + macaddr[2]); + iowrite32be(tmp, ®s->macstnaddr1); + + tmp = (uint32_t)((macaddr[1] << 24) | + (macaddr[0] << 16)); + iowrite32be(tmp, ®s->macstnaddr2); + + /***************MACSTNADDR1/2*****************/ + + /*****************HASH************************/ + for (i = 0; i < NUM_OF_HASH_REGS ; i++) { + /* Initialize IADDRx */ + iowrite32be(0, ®s->igaddr[i]); + /* Initialize GADDRx */ + iowrite32be(0, ®s->gaddr[i]); + } + + fman_dtsec_reset_stat(regs); + + return 0; +} + +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs) +{ + return (uint16_t)ioread32be(®s->maxfrm); +} + +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length) +{ + iowrite32be(length, ®s->maxfrm); +} + +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr) +{ + uint32_t tmp; + + tmp = (uint32_t)((adr[5] << 24) | + (adr[4] << 16) | + (adr[3] << 8) | + adr[2]); + iowrite32be(tmp, ®s->macstnaddr1); + + tmp = (uint32_t)((adr[1] << 24) | + (adr[0] << 16)); + iowrite32be(tmp, ®s->macstnaddr2); +} + +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr) +{ + uint32_t tmp1, tmp2; + + tmp1 = ioread32be(®s->macstnaddr1); + tmp2 = ioread32be(®s->macstnaddr2); + + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16); + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24); + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff); + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8); + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16); + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24); +} + +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx) +{ + int32_t bucket; + if (ghtx) + bucket = (int32_t)((crc >> 23) & 0x1ff); + else { + bucket = (int32_t)((crc >> 24) & 0xff); + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ + if (mcast) + bucket += 0x100; + } + fman_dtsec_set_bucket(regs, bucket, TRUE); +} + +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable) +{ + int reg_idx = (bucket >> 5) & 0xf; + int bit_idx = bucket & 0x1f; + uint32_t bit_mask = 0x80000000 >> bit_idx; + uint32_t *reg; + + if (reg_idx > 7) + reg = ®s->gaddr[reg_idx-8]; + else + reg = ®s->igaddr[reg_idx]; + + if (enable) + iowrite32be(ioread32be(reg) | bit_mask, reg); + else + iowrite32be(ioread32be(reg) & (~bit_mask), reg); +} + +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast) +{ + int i; + bool ghtx; + + ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? TRUE : FALSE); + + if (ucast || (ghtx && mcast)) { + for (i = 0; i < NUM_OF_HASH_REGS; i++) + iowrite32be(0, ®s->igaddr[i]); + } + if (mcast) { + for (i = 0; i < NUM_OF_HASH_REGS; i++) + iowrite32be(0, ®s->gaddr[i]); + } +} + +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs, + uint8_t addr) +{ + if (addr > 0 && addr < 32) + iowrite32be(addr, ®s->tbipa); + else + return -EINVAL; + + return 0; +} + +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en) +{ + uint32_t tmp; + + tmp = ioread32be(®s->maccfg2); + if (en) + tmp |= MACCFG2_MAGIC_PACKET_EN; + else + tmp &= ~MACCFG2_MAGIC_PACKET_EN; + iowrite32be(tmp, ®s->maccfg2); +} + +int fman_dtsec_adjust_link(struct dtsec_regs *regs, + enum enet_interface iface_mode, + enum enet_speed speed, bool full_dx) +{ + uint32_t tmp; + + UNUSED(iface_mode); + + if ((speed == E_ENET_SPEED_1000) && !full_dx) + return -EINVAL; + + tmp = ioread32be(®s->maccfg2); + if (!full_dx) + tmp &= ~MACCFG2_FULL_DUPLEX; + else + tmp |= MACCFG2_FULL_DUPLEX; + + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE); + if (speed < E_ENET_SPEED_1000) + tmp |= MACCFG2_NIBBLE_MODE; + else if (speed == E_ENET_SPEED_1000) + tmp |= MACCFG2_BYTE_MODE; + iowrite32be(tmp, ®s->maccfg2); + + tmp = ioread32be(®s->ecntrl); + if (speed == E_ENET_SPEED_100) + tmp |= DTSEC_ECNTRL_R100M; + else + tmp &= ~DTSEC_ECNTRL_R100M; + iowrite32be(tmp, ®s->ecntrl); + + return 0; +} + +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->rctrl); + + if (enable) + tmp |= RCTRL_UPROM; + else + tmp &= ~RCTRL_UPROM; + + iowrite32be(tmp, ®s->rctrl); +} + +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->rctrl); + + if (enable) + tmp |= RCTRL_MPROM; + else + tmp &= ~RCTRL_MPROM; + + iowrite32be(tmp, ®s->rctrl); +} + +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs, + uint32_t *car1, uint32_t *car2) +{ + /* read carry registers */ + *car1 = ioread32be(®s->car1); + *car2 = ioread32be(®s->car2); + /* clear carry registers */ + if (*car1) + iowrite32be(*car1, ®s->car1); + if (*car2) + iowrite32be(*car2, ®s->car2); + + return (bool)((*car1 | *car2) ? TRUE : FALSE); +} + +void fman_dtsec_reset_stat(struct dtsec_regs *regs) +{ + /* clear HW counters */ + iowrite32be(ioread32be(®s->ecntrl) | + DTSEC_ECNTRL_CLRCNT, ®s->ecntrl); +} + +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level) +{ + switch (level) { + case E_MAC_STAT_NONE: + iowrite32be(0xffffffff, ®s->cam1); + iowrite32be(0xffffffff, ®s->cam2); + iowrite32be(ioread32be(®s->ecntrl) & ~DTSEC_ECNTRL_STEN, + ®s->ecntrl); + iowrite32be(ioread32be(®s->imask) & ~DTSEC_IMASK_MSROEN, + ®s->imask); + break; + case E_MAC_STAT_PARTIAL: + iowrite32be(CAM1_ERRORS_ONLY, ®s->cam1); + iowrite32be(CAM2_ERRORS_ONLY, ®s->cam2); + iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, + ®s->ecntrl); + iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, + ®s->imask); + break; + case E_MAC_STAT_MIB_GRP1: + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, ®s->cam1); + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, ®s->cam2); + iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, + ®s->ecntrl); + iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, + ®s->imask); + break; + case E_MAC_STAT_FULL: + iowrite32be(0, ®s->cam1); + iowrite32be(0, ®s->cam2); + iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, + ®s->ecntrl); + iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, + ®s->imask); + break; + default: + return -EINVAL; + } + + return 0; +} + +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en) +{ + if (en) { + iowrite32be(ioread32be(®s->rctrl) | RCTRL_RTSE, + ®s->rctrl); + iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_TTSE, + ®s->tctrl); + } else { + iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_RTSE, + ®s->rctrl); + iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_TTSE, + ®s->tctrl); + } +} + +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->maccfg1); + + if (apply_rx) + tmp |= MACCFG1_RX_EN ; + + if (apply_tx) + tmp |= MACCFG1_TX_EN ; + + iowrite32be(tmp, ®s->maccfg1); +} + +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num) +{ + iowrite32be(0, ®s->macaddr[paddr_num].exact_match1); + iowrite32be(0, ®s->macaddr[paddr_num].exact_match2); +} + +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs, + uint64_t addr, + uint8_t paddr_num) +{ + uint32_t tmp; + + tmp = (uint32_t)(addr); + /* swap */ + tmp = (((tmp & 0x000000FF) << 24) | + ((tmp & 0x0000FF00) << 8) | + ((tmp & 0x00FF0000) >> 8) | + ((tmp & 0xFF000000) >> 24)); + iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match1); + + tmp = (uint32_t)(addr>>32); + /* swap */ + tmp = (((tmp & 0x000000FF) << 24) | + ((tmp & 0x0000FF00) << 8) | + ((tmp & 0x00FF0000) >> 8) | + ((tmp & 0xFF000000) >> 24)); + iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match2); +} + +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->maccfg1); + + if (apply_rx) + tmp &= ~MACCFG1_RX_EN; + + if (apply_tx) + tmp &= ~MACCFG1_TX_EN; + + iowrite32be(tmp, ®s->maccfg1); +} + +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time) +{ + uint32_t ptv = 0; + + /* fixme: don't enable tx pause for half-duplex */ + + if (time) { + ptv = ioread32be(®s->ptv); + ptv &= 0xffff0000; + ptv |= time & 0x0000ffff; + iowrite32be(ptv, ®s->ptv); + + /* trigger the transmission of a flow-control pause frame */ + iowrite32be(ioread32be(®s->maccfg1) | MACCFG1_TX_FLOW, + ®s->maccfg1); + } else + iowrite32be(ioread32be(®s->maccfg1) & ~MACCFG1_TX_FLOW, + ®s->maccfg1); +} + +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en) +{ + uint32_t tmp; + + /* todo: check if mac is set to full-duplex */ + + tmp = ioread32be(®s->maccfg1); + if (en) + tmp |= MACCFG1_RX_FLOW; + else + tmp &= ~MACCFG1_RX_FLOW; + iowrite32be(tmp, ®s->maccfg1); +} + +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs) +{ + return ioread32be(®s->rctrl); +} + +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs) +{ + return ioread32be(®s->tsec_id); +} + +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->ievent) & ev_mask; +} + +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ev_mask, ®s->ievent); +} + +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs) +{ + return ioread32be(®s->imask); +} + +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs) +{ + uint32_t event; + + event = ioread32be(®s->tmr_pevent); + event &= ioread32be(®s->tmr_pemask); + + if (event) + iowrite32be(event, ®s->tmr_pevent); + return event; +} + +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs) +{ + iowrite32be(ioread32be(®s->tmr_pemask) | TMR_PEMASK_TSREEN, + ®s->tmr_pemask); +} + +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs) +{ + iowrite32be(ioread32be(®s->tmr_pemask) & ~TMR_PEMASK_TSREEN, + ®s->tmr_pemask); +} + +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); +} + +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); +} + +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs, + enum dtsec_stat_counters reg_name) +{ + uint32_t ret_val; + + switch (reg_name) { + case E_DTSEC_STAT_TR64: + ret_val = ioread32be(®s->tr64); + break; + case E_DTSEC_STAT_TR127: + ret_val = ioread32be(®s->tr127); + break; + case E_DTSEC_STAT_TR255: + ret_val = ioread32be(®s->tr255); + break; + case E_DTSEC_STAT_TR511: + ret_val = ioread32be(®s->tr511); + break; + case E_DTSEC_STAT_TR1K: + ret_val = ioread32be(®s->tr1k); + break; + case E_DTSEC_STAT_TRMAX: + ret_val = ioread32be(®s->trmax); + break; + case E_DTSEC_STAT_TRMGV: + ret_val = ioread32be(®s->trmgv); + break; + case E_DTSEC_STAT_RBYT: + ret_val = ioread32be(®s->rbyt); + break; + case E_DTSEC_STAT_RPKT: + ret_val = ioread32be(®s->rpkt); + break; + case E_DTSEC_STAT_RMCA: + ret_val = ioread32be(®s->rmca); + break; + case E_DTSEC_STAT_RBCA: + ret_val = ioread32be(®s->rbca); + break; + case E_DTSEC_STAT_RXPF: + ret_val = ioread32be(®s->rxpf); + break; + case E_DTSEC_STAT_RALN: + ret_val = ioread32be(®s->raln); + break; + case E_DTSEC_STAT_RFLR: + ret_val = ioread32be(®s->rflr); + break; + case E_DTSEC_STAT_RCDE: + ret_val = ioread32be(®s->rcde); + break; + case E_DTSEC_STAT_RCSE: + ret_val = ioread32be(®s->rcse); + break; + case E_DTSEC_STAT_RUND: + ret_val = ioread32be(®s->rund); + break; + case E_DTSEC_STAT_ROVR: + ret_val = ioread32be(®s->rovr); + break; + case E_DTSEC_STAT_RFRG: + ret_val = ioread32be(®s->rfrg); + break; + case E_DTSEC_STAT_RJBR: + ret_val = ioread32be(®s->rjbr); + break; + case E_DTSEC_STAT_RDRP: + ret_val = ioread32be(®s->rdrp); + break; + case E_DTSEC_STAT_TFCS: + ret_val = ioread32be(®s->tfcs); + break; + case E_DTSEC_STAT_TBYT: + ret_val = ioread32be(®s->tbyt); + break; + case E_DTSEC_STAT_TPKT: + ret_val = ioread32be(®s->tpkt); + break; + case E_DTSEC_STAT_TMCA: + ret_val = ioread32be(®s->tmca); + break; + case E_DTSEC_STAT_TBCA: + ret_val = ioread32be(®s->tbca); + break; + case E_DTSEC_STAT_TXPF: + ret_val = ioread32be(®s->txpf); + break; + case E_DTSEC_STAT_TNCL: + ret_val = ioread32be(®s->tncl); + break; + case E_DTSEC_STAT_TDRP: + ret_val = ioread32be(®s->tdrp); + break; + default: + ret_val = 0; + } + + return ret_val; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c new file mode 100644 index 000000000000..8819f8fcafbd --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c @@ -0,0 +1,163 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "common/general.h" +#include "fsl_fman_dtsec_mii_acc.h" + + +/** + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider + * @dtsec_freq: dtsec clock frequency (in Mhz) + * + * This function calculates the dtsec mii clock divider that determines + * the MII MDC clock. MII MDC clock will be set to work in the range + * of 1.5 to 2.5Mhz + * The output of this function is the value of MIIMCFG[MgmtClk] which + * implicitly determines the divider value. + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock. + * + * The table below which reflects dtsec_mii_get_div() functionality + * shows the relations among dtsec_freq, MgmtClk, actual divider + * and the MII frequency: + * + * dtsec freq MgmtClk div MII freq Mhz + * [0.....80] 1 (1/4)(1/8) [0 to 2.5] + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5] + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5] + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5] + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5] + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5] + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5] + * [560..frq] 7 (1/28)(1/8) [frq/224] + * + * Returns: the MIIMCFG[MgmtClk] appropriate value + */ + +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq) +{ + uint16_t mgmt_clk; + + if (dtsec_freq < 80) mgmt_clk = 1; + else if (dtsec_freq < 120) mgmt_clk = 2; + else if (dtsec_freq < 160) mgmt_clk = 3; + else if (dtsec_freq < 200) mgmt_clk = 4; + else if (dtsec_freq < 280) mgmt_clk = 5; + else if (dtsec_freq < 400) mgmt_clk = 6; + else mgmt_clk = 7; + + return (uint8_t)mgmt_clk; +} + +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs) +{ + /* Reset the management interface */ + iowrite32be(ioread32be(®s->miimcfg) | MIIMCFG_RESET_MGMT, + ®s->miimcfg); + iowrite32be(ioread32be(®s->miimcfg) & ~MIIMCFG_RESET_MGMT, + ®s->miimcfg); +} + + +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr, + uint8_t reg, uint16_t data, uint16_t dtsec_freq) +{ + uint32_t tmp; + + /* Setup the MII Mgmt clock speed */ + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), ®s->miimcfg); + wmb(); + + /* Stop the MII management read cycle */ + iowrite32be(0, ®s->miimcom); + /* Dummy read to make sure MIIMCOM is written */ + tmp = ioread32be(®s->miimcom); + wmb(); + + /* Setting up MII Management Address Register */ + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); + iowrite32be(tmp, ®s->miimadd); + wmb(); + + /* Setting up MII Management Control Register with data */ + iowrite32be((uint32_t)data, ®s->miimcon); + /* Dummy read to make sure MIIMCON is written */ + tmp = ioread32be(®s->miimcon); + wmb(); + + /* Wait until MII management write is complete */ + /* todo: a timeout could be useful here */ + while ((ioread32be(®s->miimind)) & MIIMIND_BUSY) + /* busy wait */; + + return 0; +} + +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr, + uint8_t reg, uint16_t *data, uint16_t dtsec_freq) +{ + uint32_t tmp; + + /* Setup the MII Mgmt clock speed */ + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), ®s->miimcfg); + wmb(); + + /* Setting up the MII Management Address Register */ + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); + iowrite32be(tmp, ®s->miimadd); + wmb(); + + /* Perform an MII management read cycle */ + iowrite32be(MIIMCOM_READ_CYCLE, ®s->miimcom); + /* Dummy read to make sure MIIMCOM is written */ + tmp = ioread32be(®s->miimcom); + wmb(); + + /* Wait until MII management read is complete */ + /* todo: a timeout could be useful here */ + while ((ioread32be(®s->miimind)) & MIIMIND_BUSY) + /* busy wait */; + + /* Read MII management status */ + *data = (uint16_t)ioread32be(®s->miimstat); + wmb(); + + iowrite32be(0, ®s->miimcom); + /* Dummy read to make sure MIIMCOM is written */ + tmp = ioread32be(®s->miimcom); + + if (*data == 0xffff) + return -ENXIO; + + return 0; +} + diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac.c new file mode 100644 index 000000000000..00995a1066d0 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac.c @@ -0,0 +1,511 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_memac.h" + + +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->ievent) & ev_mask; +} + +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs) +{ + return ioread32be(®s->imask); +} + +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ev_mask, ®s->ievent); +} + +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + if (val) + tmp |= CMD_CFG_PROMIS_EN; + else + tmp &= ~CMD_CFG_PROMIS_EN; + + iowrite32be(tmp, ®s->command_config); +} + +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs, + uint8_t paddr_num) +{ + if (paddr_num == 0) { + iowrite32be(0, ®s->mac_addr0.mac_addr_l); + iowrite32be(0, ®s->mac_addr0.mac_addr_u); + } else { + iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_l); + iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_u); + } +} + +void fman_memac_add_addr_in_paddr(struct memac_regs *regs, + uint8_t *adr, + uint8_t paddr_num) +{ + uint32_t tmp0, tmp1; + + tmp0 = (uint32_t)(adr[0] | + adr[1] << 8 | + adr[2] << 16 | + adr[3] << 24); + tmp1 = (uint32_t)(adr[4] | adr[5] << 8); + + if (paddr_num == 0) { + iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l); + iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u); + } else { + iowrite32be(tmp0, ®s->mac_addr[paddr_num-1].mac_addr_l); + iowrite32be(tmp1, ®s->mac_addr[paddr_num-1].mac_addr_u); + } +} + +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + if (apply_rx) + tmp |= CMD_CFG_RX_EN; + + if (apply_tx) + tmp |= CMD_CFG_TX_EN; + + iowrite32be(tmp, ®s->command_config); +} + +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + if (apply_rx) + tmp &= ~CMD_CFG_RX_EN; + + if (apply_tx) + tmp &= ~CMD_CFG_TX_EN; + + iowrite32be(tmp, ®s->command_config); +} + +void fman_memac_reset_stat(struct memac_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->statn_config); + + tmp |= STATS_CFG_CLR; + + iowrite32be(tmp, ®s->statn_config); + + while (ioread32be(®s->statn_config) & STATS_CFG_CLR); +} + +void fman_memac_reset(struct memac_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + tmp |= CMD_CFG_SW_RESET; + + iowrite32be(tmp, ®s->command_config); + + while (ioread32be(®s->command_config) & CMD_CFG_SW_RESET); +} + +int fman_memac_init(struct memac_regs *regs, + struct memac_cfg *cfg, + enum enet_interface enet_interface, + enum enet_speed enet_speed, + bool slow_10g_if, + uint32_t exceptions) +{ + uint32_t tmp; + + /* Config */ + tmp = 0; + if (cfg->wan_mode_enable) + tmp |= CMD_CFG_WAN_MODE; + if (cfg->promiscuous_mode_enable) + tmp |= CMD_CFG_PROMIS_EN; + if (cfg->pause_forward_enable) + tmp |= CMD_CFG_PAUSE_FWD; + if (cfg->pause_ignore) + tmp |= CMD_CFG_PAUSE_IGNORE; + if (cfg->tx_addr_ins_enable) + tmp |= CMD_CFG_TX_ADDR_INS; + if (cfg->loopback_enable) + tmp |= CMD_CFG_LOOPBACK_EN; + if (cfg->cmd_frame_enable) + tmp |= CMD_CFG_CNT_FRM_EN; + if (cfg->send_idle_enable) + tmp |= CMD_CFG_SEND_IDLE; + if (cfg->no_length_check_enable) + tmp |= CMD_CFG_NO_LEN_CHK; + if (cfg->rx_sfd_any) + tmp |= CMD_CFG_SFD_ANY; + if (cfg->pad_enable) + tmp |= CMD_CFG_TX_PAD_EN; + if (cfg->wake_on_lan) + tmp |= CMD_CFG_MG; + + tmp |= CMD_CFG_CRC_FWD; + + iowrite32be(tmp, ®s->command_config); + + /* Max Frame Length */ + iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm); + + /* Pause Time */ + iowrite32be((uint32_t)cfg->pause_quanta, ®s->pause_quanta[0]); + iowrite32be((uint32_t)0, ®s->pause_thresh[0]); + + /* IF_MODE */ + tmp = 0; + switch (enet_interface) { + case E_ENET_IF_XGMII: + case E_ENET_IF_XFI: + tmp |= IF_MODE_XGMII; + break; + default: + tmp |= IF_MODE_GMII; + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable) + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; + } + iowrite32be(tmp, ®s->if_mode); + + /* TX_FIFO_SECTIONS */ + tmp = 0; + if (enet_interface == E_ENET_IF_XGMII || + enet_interface == E_ENET_IF_XFI) { + if(slow_10g_if) { + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G | + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); + } else { + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G | + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); + } + } else { + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G | + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G); + } + iowrite32be(tmp, ®s->tx_fifo_sections); + + /* clear all pending events and set-up interrupts */ + fman_memac_ack_event(regs, 0xffffffff); + fman_memac_set_exception(regs, exceptions, TRUE); + + return 0; +} + +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->imask); + if (enable) + tmp |= val; + else + tmp &= ~val; + + iowrite32be(tmp, ®s->imask); +} + +void fman_memac_reset_filter_table(struct memac_regs *regs) +{ + uint32_t i; + for (i = 0; i < 64; i++) + iowrite32be(i & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); +} + +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc) +{ + iowrite32be(crc | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); +} + +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val) +{ + iowrite32be(val, ®s->hashtable_ctrl); +} + +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->maxfrm); + + return(uint16_t)tmp; +} + + +void fman_memac_set_tx_pause_frames(struct memac_regs *regs, + uint8_t priority, + uint16_t pause_time, + uint16_t thresh_time) +{ + uint32_t tmp; + + tmp = ioread32be(®s->tx_fifo_sections); + + if (priority == 0xff) { + GET_TX_EMPTY_DEFAULT_VALUE(tmp); + iowrite32be(tmp, ®s->tx_fifo_sections); + + tmp = ioread32be(®s->command_config); + tmp &= ~CMD_CFG_PFC_MODE; + priority = 0; + } else { + GET_TX_EMPTY_PFC_VALUE(tmp); + iowrite32be(tmp, ®s->tx_fifo_sections); + + tmp = ioread32be(®s->command_config); + tmp |= CMD_CFG_PFC_MODE; + } + + iowrite32be(tmp, ®s->command_config); + + tmp = ioread32be(®s->pause_quanta[priority / 2]); + if (priority % 2) + tmp &= 0x0000FFFF; + else + tmp &= 0xFFFF0000; + tmp |= ((uint32_t)pause_time << (16 * (priority % 2))); + iowrite32be(tmp, ®s->pause_quanta[priority / 2]); + + tmp = ioread32be(®s->pause_thresh[priority / 2]); + if (priority % 2) + tmp &= 0x0000FFFF; + else + tmp &= 0xFFFF0000; + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2))); + iowrite32be(tmp, ®s->pause_thresh[priority / 2]); +} + +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + if (enable) + tmp |= CMD_CFG_PAUSE_IGNORE; + else + tmp &= ~CMD_CFG_PAUSE_IGNORE; + + iowrite32be(tmp, ®s->command_config); +} + +void fman_memac_set_wol(struct memac_regs *regs, bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + if (enable) + tmp |= CMD_CFG_MG; + else + tmp &= ~CMD_CFG_MG; + + iowrite32be(tmp, ®s->command_config); +} + +#define GET_MEMAC_CNTR_64(bn) \ + (ioread32be(®s->bn ## _l) | \ + ((uint64_t)ioread32be(®s->bn ## _u) << 32)) + +uint64_t fman_memac_get_counter(struct memac_regs *regs, + enum memac_counters reg_name) +{ + uint64_t ret_val; + + switch (reg_name) { + case E_MEMAC_COUNTER_R64: + ret_val = GET_MEMAC_CNTR_64(r64); + break; + case E_MEMAC_COUNTER_R127: + ret_val = GET_MEMAC_CNTR_64(r127); + break; + case E_MEMAC_COUNTER_R255: + ret_val = GET_MEMAC_CNTR_64(r255); + break; + case E_MEMAC_COUNTER_R511: + ret_val = GET_MEMAC_CNTR_64(r511); + break; + case E_MEMAC_COUNTER_R1023: + ret_val = GET_MEMAC_CNTR_64(r1023); + break; + case E_MEMAC_COUNTER_R1518: + ret_val = GET_MEMAC_CNTR_64(r1518); + break; + case E_MEMAC_COUNTER_R1519X: + ret_val = GET_MEMAC_CNTR_64(r1519x); + break; + case E_MEMAC_COUNTER_RFRG: + ret_val = GET_MEMAC_CNTR_64(rfrg); + break; + case E_MEMAC_COUNTER_RJBR: + ret_val = GET_MEMAC_CNTR_64(rjbr); + break; + case E_MEMAC_COUNTER_RDRP: + ret_val = GET_MEMAC_CNTR_64(rdrp); + break; + case E_MEMAC_COUNTER_RALN: + ret_val = GET_MEMAC_CNTR_64(raln); + break; + case E_MEMAC_COUNTER_TUND: + ret_val = GET_MEMAC_CNTR_64(tund); + break; + case E_MEMAC_COUNTER_ROVR: + ret_val = GET_MEMAC_CNTR_64(rovr); + break; + case E_MEMAC_COUNTER_RXPF: + ret_val = GET_MEMAC_CNTR_64(rxpf); + break; + case E_MEMAC_COUNTER_TXPF: + ret_val = GET_MEMAC_CNTR_64(txpf); + break; + case E_MEMAC_COUNTER_ROCT: + ret_val = GET_MEMAC_CNTR_64(roct); + break; + case E_MEMAC_COUNTER_RMCA: + ret_val = GET_MEMAC_CNTR_64(rmca); + break; + case E_MEMAC_COUNTER_RBCA: + ret_val = GET_MEMAC_CNTR_64(rbca); + break; + case E_MEMAC_COUNTER_RPKT: + ret_val = GET_MEMAC_CNTR_64(rpkt); + break; + case E_MEMAC_COUNTER_RUCA: + ret_val = GET_MEMAC_CNTR_64(ruca); + break; + case E_MEMAC_COUNTER_RERR: + ret_val = GET_MEMAC_CNTR_64(rerr); + break; + case E_MEMAC_COUNTER_TOCT: + ret_val = GET_MEMAC_CNTR_64(toct); + break; + case E_MEMAC_COUNTER_TMCA: + ret_val = GET_MEMAC_CNTR_64(tmca); + break; + case E_MEMAC_COUNTER_TBCA: + ret_val = GET_MEMAC_CNTR_64(tbca); + break; + case E_MEMAC_COUNTER_TUCA: + ret_val = GET_MEMAC_CNTR_64(tuca); + break; + case E_MEMAC_COUNTER_TERR: + ret_val = GET_MEMAC_CNTR_64(terr); + break; + default: + ret_val = 0; + } + + return ret_val; +} + +void fman_memac_adjust_link(struct memac_regs *regs, + enum enet_interface iface_mode, + enum enet_speed speed, bool full_dx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->if_mode); + + if (full_dx) + tmp &= ~IF_MODE_HD; + else + tmp |= IF_MODE_HD; + + if (iface_mode == E_ENET_IF_RGMII) { + /* Configure RGMII in manual mode */ + tmp &= ~IF_MODE_RGMII_AUTO; + tmp &= ~IF_MODE_RGMII_SP_MASK; + + if (full_dx) + tmp |= IF_MODE_RGMII_FD; + else + tmp &= ~IF_MODE_RGMII_FD; + + switch (speed) { + case E_ENET_SPEED_1000: + tmp |= IF_MODE_RGMII_1000; + break; + case E_ENET_SPEED_100: + tmp |= IF_MODE_RGMII_100; + break; + case E_ENET_SPEED_10: + tmp |= IF_MODE_RGMII_10; + break; + default: + break; + } + } + + iowrite32be(tmp, ®s->if_mode); +} + +void fman_memac_defconfig(struct memac_cfg *cfg) +{ + cfg->reset_on_init = FALSE; + cfg->wan_mode_enable = FALSE; + cfg->promiscuous_mode_enable = FALSE; + cfg->pause_forward_enable = FALSE; + cfg->pause_ignore = FALSE; + cfg->tx_addr_ins_enable = FALSE; + cfg->loopback_enable = FALSE; + cfg->cmd_frame_enable = FALSE; + cfg->rx_error_discard = FALSE; + cfg->send_idle_enable = FALSE; + cfg->no_length_check_enable = TRUE; + cfg->lgth_check_nostdr = FALSE; + cfg->time_stamp_enable = FALSE; + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; + cfg->max_frame_length = DEFAULT_FRAME_LENGTH; + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA; + cfg->pad_enable = TRUE; + cfg->phy_tx_ena_on = FALSE; + cfg->rx_sfd_any = FALSE; + cfg->rx_pbl_fwd = FALSE; + cfg->tx_pbl_fwd = FALSE; + cfg->debug_mode = FALSE; + cfg->wake_on_lan = FALSE; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac_mii_acc.c new file mode 100755 index 000000000000..ccda11ec25e1 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_memac_mii_acc.c @@ -0,0 +1,213 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_memac_mii_acc.h" + +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t data) +{ + uint32_t tmp_reg; + + tmp_reg = ioread32be(&mii_regs->mdio_cfg); + /* Leave only MDIO_CLK_DIV bits set on */ + tmp_reg &= MDIO_CFG_CLK_DIV_MASK; + /* Set maximum MDIO_HOLD value to allow phy to see + change of data signal */ + tmp_reg |= MDIO_CFG_HOLD_MASK; + /* Add 10G interface mode */ + tmp_reg |= MDIO_CFG_ENC45; + iowrite32be(tmp_reg, &mii_regs->mdio_cfg); + + /* Wait for command completion */ + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Specify phy and register to be accessed */ + iowrite32be(phy_addr, &mii_regs->mdio_ctrl); + iowrite32be(reg, &mii_regs->mdio_addr); + wmb(); + + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Write data */ + iowrite32be(data, &mii_regs->mdio_data); + wmb(); + + /* Wait for write transaction end */ + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) + udelay(1); +} + +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t *data) +{ + uint32_t tmp_reg; + + tmp_reg = ioread32be(&mii_regs->mdio_cfg); + /* Leave only MDIO_CLK_DIV bits set on */ + tmp_reg &= MDIO_CFG_CLK_DIV_MASK; + /* Set maximum MDIO_HOLD value to allow phy to see + change of data signal */ + tmp_reg |= MDIO_CFG_HOLD_MASK; + /* Add 10G interface mode */ + tmp_reg |= MDIO_CFG_ENC45; + iowrite32be(tmp_reg, &mii_regs->mdio_cfg); + + /* Wait for command completion */ + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Specify phy and register to be accessed */ + iowrite32be(phy_addr, &mii_regs->mdio_ctrl); + iowrite32be(reg, &mii_regs->mdio_addr); + wmb(); + + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Read cycle */ + tmp_reg = phy_addr; + tmp_reg |= MDIO_CTL_READ; + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); + wmb(); + + /* Wait for data to be available */ + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) + udelay(1); + + *data = (uint16_t)ioread32be(&mii_regs->mdio_data); + + /* Check if there was an error */ + return ioread32be(&mii_regs->mdio_cfg); +} + +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t data) +{ + uint32_t tmp_reg; + + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ + tmp_reg = ioread32be(&mii_regs->mdio_cfg); + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); + iowrite32be(tmp_reg, &mii_regs->mdio_cfg); + + /* Wait for command completion */ + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Write transaction */ + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT); + tmp_reg |= reg; + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); + + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + iowrite32be(data, &mii_regs->mdio_data); + + wmb(); + + /* Wait for write transaction to end */ + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) + udelay(1); +} + +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t *data) +{ + uint32_t tmp_reg; + + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ + tmp_reg = ioread32be(&mii_regs->mdio_cfg); + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); + iowrite32be(tmp_reg, &mii_regs->mdio_cfg); + + /* Wait for command completion */ + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Read transaction */ + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT); + tmp_reg |= reg; + tmp_reg |= MDIO_CTL_READ; + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); + + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) + udelay(1); + + /* Wait for data to be available */ + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) + udelay(1); + + *data = (uint16_t)ioread32be(&mii_regs->mdio_data); + + /* Check error */ + return ioread32be(&mii_regs->mdio_cfg); +} + +/*****************************************************************************/ +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t data, + enum enet_speed enet_speed) +{ + /* Figure out interface type - 10G vs 1G. + In 10G interface both phy_addr and devAddr present. */ + if (enet_speed == E_ENET_SPEED_10000) + write_phy_reg_10g(mii_regs, phy_addr, reg, data); + else + write_phy_reg_1g(mii_regs, phy_addr, reg, data); + + return 0; +} + +/*****************************************************************************/ +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t *data, + enum enet_speed enet_speed) +{ + uint32_t ans; + /* Figure out interface type - 10G vs 1G. + In 10G interface both phy_addr and devAddr present. */ + if (enet_speed == E_ENET_SPEED_10000) + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data); + else + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data); + + if (ans & MDIO_CFG_READ_ERR) + return -EINVAL; + return 0; +} + +/* ......................................................................... */ + diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c new file mode 100644 index 000000000000..fff9d5de80e3 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c @@ -0,0 +1,367 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_tgec.h" + + +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr) +{ + uint32_t tmp0, tmp1; + + tmp0 = (uint32_t)(adr[0] | + adr[1] << 8 | + adr[2] << 16 | + adr[3] << 24); + tmp1 = (uint32_t)(adr[4] | adr[5] << 8); + iowrite32be(tmp0, ®s->mac_addr_0); + iowrite32be(tmp1, ®s->mac_addr_1); +} + +void fman_tgec_reset_stat(struct tgec_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + + tmp |= CMD_CFG_STAT_CLR; + + iowrite32be(tmp, ®s->command_config); + + while (ioread32be(®s->command_config) & CMD_CFG_STAT_CLR) ; +} + +#define GET_TGEC_CNTR_64(bn) \ + (((uint64_t)ioread32be(®s->bn ## _u) << 32) | \ + ioread32be(®s->bn ## _l)) + +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name) +{ + uint64_t ret_val; + + switch (reg_name) { + case E_TGEC_COUNTER_R64: + ret_val = GET_TGEC_CNTR_64(r64); + break; + case E_TGEC_COUNTER_R127: + ret_val = GET_TGEC_CNTR_64(r127); + break; + case E_TGEC_COUNTER_R255: + ret_val = GET_TGEC_CNTR_64(r255); + break; + case E_TGEC_COUNTER_R511: + ret_val = GET_TGEC_CNTR_64(r511); + break; + case E_TGEC_COUNTER_R1023: + ret_val = GET_TGEC_CNTR_64(r1023); + break; + case E_TGEC_COUNTER_R1518: + ret_val = GET_TGEC_CNTR_64(r1518); + break; + case E_TGEC_COUNTER_R1519X: + ret_val = GET_TGEC_CNTR_64(r1519x); + break; + case E_TGEC_COUNTER_TRFRG: + ret_val = GET_TGEC_CNTR_64(trfrg); + break; + case E_TGEC_COUNTER_TRJBR: + ret_val = GET_TGEC_CNTR_64(trjbr); + break; + case E_TGEC_COUNTER_RDRP: + ret_val = GET_TGEC_CNTR_64(rdrp); + break; + case E_TGEC_COUNTER_RALN: + ret_val = GET_TGEC_CNTR_64(raln); + break; + case E_TGEC_COUNTER_TRUND: + ret_val = GET_TGEC_CNTR_64(trund); + break; + case E_TGEC_COUNTER_TROVR: + ret_val = GET_TGEC_CNTR_64(trovr); + break; + case E_TGEC_COUNTER_RXPF: + ret_val = GET_TGEC_CNTR_64(rxpf); + break; + case E_TGEC_COUNTER_TXPF: + ret_val = GET_TGEC_CNTR_64(txpf); + break; + case E_TGEC_COUNTER_ROCT: + ret_val = GET_TGEC_CNTR_64(roct); + break; + case E_TGEC_COUNTER_RMCA: + ret_val = GET_TGEC_CNTR_64(rmca); + break; + case E_TGEC_COUNTER_RBCA: + ret_val = GET_TGEC_CNTR_64(rbca); + break; + case E_TGEC_COUNTER_RPKT: + ret_val = GET_TGEC_CNTR_64(rpkt); + break; + case E_TGEC_COUNTER_RUCA: + ret_val = GET_TGEC_CNTR_64(ruca); + break; + case E_TGEC_COUNTER_RERR: + ret_val = GET_TGEC_CNTR_64(rerr); + break; + case E_TGEC_COUNTER_TOCT: + ret_val = GET_TGEC_CNTR_64(toct); + break; + case E_TGEC_COUNTER_TMCA: + ret_val = GET_TGEC_CNTR_64(tmca); + break; + case E_TGEC_COUNTER_TBCA: + ret_val = GET_TGEC_CNTR_64(tbca); + break; + case E_TGEC_COUNTER_TUCA: + ret_val = GET_TGEC_CNTR_64(tuca); + break; + case E_TGEC_COUNTER_TERR: + ret_val = GET_TGEC_CNTR_64(terr); + break; + default: + ret_val = 0; + } + + return ret_val; +} + +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + if (apply_rx) + tmp |= CMD_CFG_RX_EN; + if (apply_tx) + tmp |= CMD_CFG_TX_EN; + iowrite32be(tmp, ®s->command_config); +} + +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx) +{ + uint32_t tmp_reg_32; + + tmp_reg_32 = ioread32be(®s->command_config); + if (apply_rx) + tmp_reg_32 &= ~CMD_CFG_RX_EN; + if (apply_tx) + tmp_reg_32 &= ~CMD_CFG_TX_EN; + iowrite32be(tmp_reg_32, ®s->command_config); +} + +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + if (val) + tmp |= CMD_CFG_PROMIS_EN; + else + tmp &= ~CMD_CFG_PROMIS_EN; + iowrite32be(tmp, ®s->command_config); +} + +void fman_tgec_reset_filter_table(struct tgec_regs *regs) +{ + uint32_t i; + for (i = 0; i < 512; i++) + iowrite32be(i & ~TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl); +} + +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc) +{ + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ + iowrite32be(hash | TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl); +} + +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value) +{ + iowrite32be(value, ®s->hashtable_ctrl); +} + +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time) +{ + iowrite32be((uint32_t)pause_time, ®s->pause_quant); +} + +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + if (en) + tmp |= CMD_CFG_PAUSE_IGNORE; + else + tmp &= ~CMD_CFG_PAUSE_IGNORE; + iowrite32be(tmp, ®s->command_config); +} + +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en) +{ + uint32_t tmp; + + tmp = ioread32be(®s->command_config); + if (en) + tmp |= CMD_CFG_EN_TIMESTAMP; + else + tmp &= ~CMD_CFG_EN_TIMESTAMP; + iowrite32be(tmp, ®s->command_config); +} + +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->ievent) & ev_mask; +} + +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ev_mask, ®s->ievent); +} + +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs) +{ + return ioread32be(®s->imask); +} + +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr) +{ + uint32_t tmp0, tmp1; + + tmp0 = (uint32_t)(adr[0] | + adr[1] << 8 | + adr[2] << 16 | + adr[3] << 24); + tmp1 = (uint32_t)(adr[4] | adr[5] << 8); + iowrite32be(tmp0, ®s->mac_addr_2); + iowrite32be(tmp1, ®s->mac_addr_3); +} + +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs) +{ + iowrite32be(0, ®s->mac_addr_2); + iowrite32be(0, ®s->mac_addr_3); +} + +uint32_t fman_tgec_get_revision(struct tgec_regs *regs) +{ + return ioread32be(®s->tgec_id); +} + +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); +} + +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) +{ + iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); +} + +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs) +{ + return (uint16_t) ioread32be(®s->maxfrm); +} + +void fman_tgec_defconfig(struct tgec_cfg *cfg) +{ + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE; + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE; + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE; + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE; + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE; + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE; + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE; + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD; + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE; + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE; + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR; + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE; + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH; + cfg->pause_quant = DEFAULT_PAUSE_QUANT; +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 + cfg->skip_fman11_workaround = FALSE; +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ +} + +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg, + uint32_t exception_mask) +{ + uint32_t tmp; + + /* Config */ + tmp = 0x40; /* CRC forward */ + if (cfg->wan_mode_enable) + tmp |= CMD_CFG_WAN_MODE; + if (cfg->promiscuous_mode_enable) + tmp |= CMD_CFG_PROMIS_EN; + if (cfg->pause_forward_enable) + tmp |= CMD_CFG_PAUSE_FWD; + if (cfg->pause_ignore) + tmp |= CMD_CFG_PAUSE_IGNORE; + if (cfg->tx_addr_ins_enable) + tmp |= CMD_CFG_TX_ADDR_INS; + if (cfg->loopback_enable) + tmp |= CMD_CFG_LOOPBACK_EN; + if (cfg->cmd_frame_enable) + tmp |= CMD_CFG_CMD_FRM_EN; + if (cfg->rx_error_discard) + tmp |= CMD_CFG_RX_ER_DISC; + if (cfg->send_idle_enable) + tmp |= CMD_CFG_SEND_IDLE; + if (cfg->no_length_check_enable) + tmp |= CMD_CFG_NO_LEN_CHK; + if (cfg->time_stamp_enable) + tmp |= CMD_CFG_EN_TIMESTAMP; + iowrite32be(tmp, ®s->command_config); + + /* Max Frame Length */ + iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm); + /* Pause Time */ + iowrite32be(cfg->pause_quant, ®s->pause_quant); + + /* clear all pending events and set-up interrupts */ + fman_tgec_ack_event(regs, 0xffffffff); + fman_tgec_enable_interrupt(regs, exception_mask); + + return 0; +} + +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs) +{ + uint32_t tmp; + + /* restore the default tx ipg Length */ + tmp = (ioread32be(®s->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12; + + iowrite32be(tmp, ®s->tx_ipg_len); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/memac.c b/sys/contrib/ncsw/Peripherals/FM/MAC/memac.c new file mode 100644 index 000000000000..85426c5feda9 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/memac.c @@ -0,0 +1,1096 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File memac.c + + @Description FM mEMAC driver +*//***************************************************************************/ + +#include "std_ext.h" +#include "string_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "endian_ext.h" +#include "debug_ext.h" + +#include "fm_common.h" +#include "memac.h" + + +/*****************************************************************************/ +/* Internal routines */ +/*****************************************************************************/ + +/* ......................................................................... */ + +static uint32_t GetMacAddrHashCode(uint64_t ethAddr) +{ + uint64_t mask1, mask2; + uint32_t xorVal = 0; + uint8_t i, j; + + for (i=0; i<6; i++) + { + mask1 = ethAddr & (uint64_t)0x01; + ethAddr >>= 1; + + for (j=0; j<7; j++) + { + mask2 = ethAddr & (uint64_t)0x01; + mask1 ^= mask2; + ethAddr >>= 1; + } + + xorVal |= (mask1 << (5-i)); + } + + return xorVal; +} + +/* ......................................................................... */ + +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr) +{ + uint16_t tmpReg16; + e_EnetMode enetMode; + + /* In case the higher MACs are used (i.e. the MACs that should support 10G), + speed=10000 is provided for SGMII ports. Temporary modify enet mode + to 1G one, so MII functions can work correctly. */ + enetMode = p_Memac->enetMode; + + /* SGMII mode + AN enable */ + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500) + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII; + + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); + + /* Device ability according to SGMII specification */ + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII; + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); + + /* Adjust link timer for SGMII - + According to Cisco SGMII specification the timer should be 1.6 ms. + The link_timer register is configured in units of the clock. + - When running as 1G SGMII, Serdes clock is 125 MHz, so + unit = 1 / (125*10^6 Hz) = 8 ns. + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so + unit = 1 / (312.5*10^6 Hz) = 3.2 ns. + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120. + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, + we always set up here a value of 2.5 SGMII. */ + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007); + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120); + + /* Restart AN */ + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); + + /* Restore original enet mode */ + p_Memac->enetMode = enetMode; +} + +/* ......................................................................... */ + +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr) +{ + uint16_t tmpReg16; + e_EnetMode enetMode; + + /* In case the higher MACs are used (i.e. the MACs that should support 10G), + speed=10000 is provided for SGMII ports. Temporary modify enet mode + to 1G one, so MII functions can work correctly. */ + enetMode = p_Memac->enetMode; + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); + + /* 1000BaseX mode */ + tmpReg16 = PHY_SGMII_IF_MODE_1000X; + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); + + /* AN Device capability */ + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X; + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); + + /* Adjust link timer for SGMII - + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. + The link_timer register is configured in units of the clock. + - When running as 1G SGMII, Serdes clock is 125 MHz, so + unit = 1 / (125*10^6 Hz) = 8 ns. + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so + unit = 1 / (312.5*10^6 Hz) = 3.2 ns. + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, + we always set up here a value of 2.5 SGMII. */ + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f); + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08); + + /* Restart AN */ + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); + + /* Restore original enet mode */ + p_Memac->enetMode = enetMode; +} + +/* ......................................................................... */ + +static t_Error CheckInitParameters(t_Memac *p_Memac) +{ + e_FmMacType portType; + + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); + +#if (FM_MAX_NUM_OF_10G_MACS > 0) + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS)); +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */ + + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS)); + if (p_Memac->addr == 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address")); + if (!p_Memac->f_Exception) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception")); + if (!p_Memac->f_Event) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event")); +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ + + return E_OK; +} + +/* ........................................................................... */ + +static void MemacErrException(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + uint32_t event, imask; + + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); + + /* Imask include both error and notification/event bits. + Leaving only error bits enabled by imask. + The imask error bits are shifted by 16 bits offset from + their corresponding location in the ievent - hence the >> 16 */ + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); + + fman_memac_ack_event(p_Memac->p_MemMap, event); + + if (event & MEMAC_IEVNT_TS_ECC_ER) + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR); + if (event & MEMAC_IEVNT_TX_ECC_ER) + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER); + if (event & MEMAC_IEVNT_RX_ECC_ER) + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER); +} + +static void MemacException(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + uint32_t event, imask; + + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); + + /* Imask include both error and notification/event bits. + Leaving only error bits enabled by imask. + The imask error bits are shifted by 16 bits offset from + their corresponding location in the ievent - hence the >> 16 */ + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); + + fman_memac_ack_event(p_Memac->p_MemMap, event); + + if (event & MEMAC_IEVNT_MGI) + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION); +} + +/* ......................................................................... */ + +static void FreeInitResources(t_Memac *p_Memac) +{ + e_FmMacType portType; + + portType = + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); + + if (portType == e_FM_MAC_10G) + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); + else + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); + + /* release the driver's group hash table */ + FreeHashTable(p_Memac->p_MulticastAddrHash); + p_Memac->p_MulticastAddrHash = NULL; + + /* release the driver's individual hash table */ + FreeHashTable(p_Memac->p_UnicastAddrHash); + p_Memac->p_UnicastAddrHash = NULL; +} + + +/*****************************************************************************/ +/* mEMAC API routines */ +/*****************************************************************************/ + +/* ......................................................................... */ + +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal); + + return E_OK; +} + +/* .............................................................................. */ + +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex)) + RETURN_ERROR(MAJOR, E_CONFLICT, + ("Ethernet MAC 1G or 10G does not support half-duplex")); + + fman_memac_adjust_link(p_Memac->p_MemMap, + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), + (enum enet_speed)speed, + fullDuplex); + return E_OK; +} + + +/*****************************************************************************/ +/* Memac Configs modification functions */ +/*****************************************************************************/ + +/* ......................................................................... */ + +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->loopback_enable = newVal; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->max_frame_length = newVal; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->pad_enable = newVal; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + GET_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_Memac->exceptions |= bitMask; + else + p_Memac->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + p_Memac->p_MemacDriverParam->reset_on_init = enable; + + return E_OK; +} + + +/*****************************************************************************/ +/* Memac Run Time API functions */ +/*****************************************************************************/ + +/* ......................................................................... */ + +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + if (priority != 0xFF) + { + bool PortConfigured, PreFetchEnabled; + + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0) + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled")); + + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm, + p_Memac->fmMacControllerDriver.macId, + &PortConfigured, + &PreFetchEnabled); + + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured) + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); + + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled) + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); + } + + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac, + uint16_t pauseTime) +{ + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0); +} + +/* ......................................................................... */ + +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_set_wol(p_Memac->p_MemMap, en); + + return E_OK; +} + +/* .............................................................................. */ + +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); +UNUSED(p_Memac); +DBG(WARNING, ("mEMAC has 1588 always enabled!")); + + return E_OK; +} + +/* Counters handling */ +/* ......................................................................... */ + +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); + + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); +/* */ + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG); + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR); + + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP); + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN); + + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND); + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR); +/* Pause */ + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF); + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF); + +/* MIB II */ + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT); + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA); + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA); + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA); + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts + + p_Statistics->ifInMcastPkts + + p_Statistics->ifInBcastPkts; + p_Statistics->ifInDiscards = 0; + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR); + + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT); + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA); + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA); + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA); + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts + + p_Statistics->ifOutMcastPkts + + p_Statistics->ifOutBcastPkts; + p_Statistics->ifOutDiscards = 0; + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacResetCounters (t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + fman_memac_reset_stat(p_Memac->p_MemMap); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) +{ + t_Memac *p_Memac = (t_Memac *) h_Memac; + uint64_t ethAddr; + uint8_t paddrNum; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); + + if (ethAddr & GROUP_ADDRESS) + /* Multicast address has no effect in PADDR */ + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); + + /* Make sure no PADDR contains this address */ + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) + if (p_Memac->indAddrRegUsed[paddrNum]) + if (p_Memac->paddr[paddrNum] == ethAddr) + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); + + /* Find first unused PADDR */ + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) + if (!(p_Memac->indAddrRegUsed[paddrNum])) + { + /* mark this PADDR as used */ + p_Memac->indAddrRegUsed[paddrNum] = TRUE; + /* store address */ + p_Memac->paddr[paddrNum] = ethAddr; + + /* put in hardware */ + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum); + p_Memac->numOfIndAddrInRegs++; + + return E_OK; + } + + /* No free PADDR */ + RETURN_ERROR(MAJOR, E_FULL, NO_MSG); +} + +/* ......................................................................... */ + +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) +{ + t_Memac *p_Memac = (t_Memac *) h_Memac; + uint64_t ethAddr; + uint8_t paddrNum; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); + + /* Find used PADDR containing this address */ + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) + { + if ((p_Memac->indAddrRegUsed[paddrNum]) && + (p_Memac->paddr[paddrNum] == ethAddr)) + { + /* mark this PADDR as not used */ + p_Memac->indAddrRegUsed[paddrNum] = FALSE; + /* clear in hardware */ + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum); + p_Memac->numOfIndAddrInRegs--; + + return E_OK; + } + } + + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); +} + +/* ......................................................................... */ + +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + *macId = p_Memac->macId; + + return E_OK; +} + +/* ......................................................................... */ + + +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + t_EthHashEntry *p_HashEntry; + uint32_t hash; + uint64_t ethAddr; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); + + if (!(ethAddr & GROUP_ADDRESS)) + /* Unicast addresses not supported in hash */ + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address")); + + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; + + /* Create element to be added to the driver hash table */ + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); + p_HashEntry->addr = ethAddr; + INIT_LIST(&p_HashEntry->node); + + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])); + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN)); + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + t_EthHashEntry *p_HashEntry = NULL; + t_List *p_Pos; + uint32_t hash; + uint64_t ethAddr; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); + + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; + + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])) + { + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); + if (p_HashEntry->addr == ethAddr) + { + LIST_DelAndInit(&p_HashEntry->node); + XX_Free(p_HashEntry); + break; + } + } + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash])) + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN)); + + return E_OK; +} + + +/* ......................................................................... */ + +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); + + GET_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_Memac->exceptions |= bitMask; + else + p_Memac->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable); + + return E_OK; +} + +/* ......................................................................... */ + +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0); + + return fman_memac_get_max_frame_len(p_Memac->p_MemMap); +} + +static t_Error MemacInitInternalPhy(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + uint8_t i, phyAddr; + + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII) + { + /* Configure internal SGMII PHY */ + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR); + else + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR); + } + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII) + { + /* Configure 4 internal SGMII PHYs */ + for (i = 0; i < 4; i++) + { + /* QSGMII PHY address occupies 3 upper bits of 5-bit + phyAddress; the lower 2 bits are used to extend + register address space and access each one of 4 + ports inside QSGMII. */ + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i); + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr); + else + SetupSgmiiInternalPhy(p_Memac, phyAddr); + } + } + return E_OK; +} + +/*****************************************************************************/ +/* mEMAC Init & Free API */ +/*****************************************************************************/ + +/* ......................................................................... */ +void *g_MemacRegs; +static t_Error MemacInit(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + struct memac_cfg *p_MemacDriverParam; + enum enet_interface enet_interface; + enum enet_speed enet_speed; + t_EnetAddr ethAddr; + e_FmMacType portType; + t_Error err; + bool slow_10g_if = FALSE; + if (p_Memac->macId == 3) /* This is a quick WA */ + g_MemacRegs = p_Memac->p_MemMap; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); + + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 && + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4) + slow_10g_if = TRUE; + + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters); + + p_MemacDriverParam = p_Memac->p_MemacDriverParam; + + portType = + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); + + /* First, reset the MAC if desired. */ + if (p_MemacDriverParam->reset_on_init) + fman_memac_reset(p_Memac->p_MemMap); + + /* MAC Address */ + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr); + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0); + + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode); + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode); + + fman_memac_init(p_Memac->p_MemMap, + p_Memac->p_MemacDriverParam, + enet_interface, + enet_speed, + slow_10g_if, + p_Memac->exceptions); + +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 + { + uint32_t tmpReg = 0; + + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); + /* check the FMAN version - the bug exists only in rev1 */ + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) && + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0)) + { + /* MAC strips CRC from received frames - this workaround should + decrease the likelihood of bug appearance + */ + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config); + tmpReg &= ~CMD_CFG_CRC_FWD; + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg); + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/ + } + } +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */ + + MemacInitInternalPhy(h_Memac); + + /* Max Frame Length */ + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm, + portType, + p_Memac->fmMacControllerDriver.macId, + p_MemacDriverParam->max_frame_length); + if (err) + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED")); + + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); + if (!p_Memac->p_MulticastAddrHash) + { + FreeInitResources(p_Memac); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); + } + + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); + if (!p_Memac->p_UnicastAddrHash) + { + FreeInitResources(p_Memac); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); + } + + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, + p_Memac->macId, + e_FM_INTR_TYPE_ERR, + MemacErrException, + p_Memac); + + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, + p_Memac->macId, + e_FM_INTR_TYPE_NORMAL, + MemacException, + p_Memac); + + XX_Free(p_MemacDriverParam); + p_Memac->p_MemacDriverParam = NULL; + + return E_OK; +} + +/* ......................................................................... */ + +static t_Error MemacFree(t_Handle h_Memac) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + + if (p_Memac->p_MemacDriverParam) + { + /* Called after config */ + XX_Free(p_Memac->p_MemacDriverParam); + p_Memac->p_MemacDriverParam = NULL; + } + else + /* Called after init */ + FreeInitResources(p_Memac); + + XX_Free(p_Memac); + + return E_OK; +} + +/* ......................................................................... */ + +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) +{ + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit; + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree; + + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL; + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback; + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength; + + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan; + + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad; + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */ + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck; + + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException; + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit; + + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException; + + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */ + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL; + + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous; + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink; + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL; + + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable; + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable; + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy; + + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames; + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames; + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames; + + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan; + + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters; + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics; + + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress; + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress; + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress; + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress; + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress; + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId; + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL; + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength; + + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg; + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg; +} + + +/*****************************************************************************/ +/* mEMAC Config Main Entry */ +/*****************************************************************************/ + +/* ......................................................................... */ + +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam) +{ + t_Memac *p_Memac; + struct memac_cfg *p_MemacDriverParam; + uintptr_t baseAddr; + + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); + + baseAddr = p_FmMacParam->baseAddr; + /* Allocate memory for the mEMAC data structure */ + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac)); + if (!p_Memac) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure")); + return NULL; + } + memset(p_Memac, 0, sizeof(t_Memac)); + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver); + + /* Allocate memory for the mEMAC driver parameters data structure */ + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg)); + if (!p_MemacDriverParam) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters")); + XX_Free(p_Memac); + return NULL; + } + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg)); + + /* Plant parameter structure pointer */ + p_Memac->p_MemacDriverParam = p_MemacDriverParam; + + fman_memac_defconfig(p_MemacDriverParam); + + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); + + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr); + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET); + + p_Memac->enetMode = p_FmMacParam->enetMode; + p_Memac->macId = p_FmMacParam->macId; + p_Memac->exceptions = MEMAC_default_exceptions; + p_Memac->f_Exception = p_FmMacParam->f_Exception; + p_Memac->f_Event = p_FmMacParam->f_Event; + p_Memac->h_App = p_FmMacParam->h_App; + + return p_Memac; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/memac.h b/sys/contrib/ncsw/Peripherals/FM/MAC/memac.h new file mode 100644 index 000000000000..2fd89dae20d6 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/memac.h @@ -0,0 +1,110 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File memac.h + + @Description FM Multirate Ethernet MAC (mEMAC) +*//***************************************************************************/ +#ifndef __MEMAC_H +#define __MEMAC_H + +#include "std_ext.h" +#include "error_ext.h" +#include "list_ext.h" + +#include "fsl_fman_memac_mii_acc.h" +#include "fm_mac.h" +#include "fsl_fman_memac.h" + + +#define MEMAC_default_exceptions \ + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI)) + +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ + case e_FM_MAC_EX_10G_1TX_ECC_ER: \ + bitMask = MEMAC_IMASK_TECC_ER; break; \ + case e_FM_MAC_EX_10G_RX_ECC_ER: \ + bitMask = MEMAC_IMASK_RECC_ER; break; \ + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \ + bitMask = MEMAC_IMASK_TSECC_ER; break; \ + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \ + bitMask = MEMAC_IMASK_MGI; break; \ + default: bitMask = 0;break;} + + +typedef struct +{ + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */ + t_Handle h_App; /**< Handle to the upper layer application */ + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */ + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */ + uint64_t addr; /**< MAC address of device */ + e_EnetMode enetMode; /**< Ethernet physical interface */ + t_FmMacExceptionCallback *f_Exception; + int mdioIrq; + t_FmMacExceptionCallback *f_Event; + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */ + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */ + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */ + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */ + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */ + bool debugMode; + uint8_t macId; + uint32_t exceptions; + struct memac_cfg *p_MemacDriverParam; +} t_Memac; + + +/* Internal PHY access */ +#define PHY_MDIO_ADDR 0 + +/* Internal PHY Registers - SGMII */ +#define PHY_SGMII_CR_PHY_RESET 0x8000 +#define PHY_SGMII_CR_RESET_AN 0x0200 +#define PHY_SGMII_CR_DEF_VAL 0x1140 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008 +#define PHY_SGMII_IF_MODE_AN 0x0002 +#define PHY_SGMII_IF_MODE_SGMII 0x0001 +#define PHY_SGMII_IF_MODE_1000X 0x0000 + + +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */ + +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data); +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); + + +#endif /* __MEMAC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.c new file mode 100644 index 000000000000..56eaffbcf66d --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.c @@ -0,0 +1,78 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "error_ext.h" +#include "std_ext.h" +#include "fm_mac.h" +#include "memac.h" +#include "xx_ext.h" + +#include "fm_common.h" +#include "memac_mii_acc.h" + + +/*****************************************************************************/ +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, + uint8_t phyAddr, + uint8_t reg, + uint16_t data) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE); + + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap, + phyAddr, + reg, + data, + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode)); +} + +/*****************************************************************************/ +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, + uint8_t phyAddr, + uint8_t reg, + uint16_t *p_Data) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; + + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE); + + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap, + phyAddr, + reg, + p_Data, + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode)); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.h b/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.h new file mode 100644 index 000000000000..325ec082ffde --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/memac_mii_acc.h @@ -0,0 +1,73 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +#ifndef __MEMAC_MII_ACC_H +#define __MEMAC_MII_ACC_H + +#include "std_ext.h" + + +/* MII Management Registers */ +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80 +#define MDIO_CFG_CLK_DIV_SHIFT 7 +#define MDIO_CFG_HOLD_MASK 0x0000001c +#define MDIO_CFG_ENC45 0x00000040 +#define MDIO_CFG_READ_ERR 0x00000002 +#define MDIO_CFG_BSY 0x00000001 + +#define MDIO_CTL_PHY_ADDR_SHIFT 5 +#define MDIO_CTL_READ 0x00008000 + +#define MDIO_DATA_BSY 0x80000000 + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(push,1) +#endif /* defined(__MWERKS__) && ... */ + +/*----------------------------------------------------*/ +/* MII Configuration Control Memory Map Registers */ +/*----------------------------------------------------*/ +typedef struct t_MemacMiiAccessMemMap +{ + volatile uint32_t mdio_cfg; /* 0x030 */ + volatile uint32_t mdio_ctrl; /* 0x034 */ + volatile uint32_t mdio_data; /* 0x038 */ + volatile uint32_t mdio_addr; /* 0x03c */ +} t_MemacMiiAccessMemMap ; + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(pop) +#endif /* defined(__MWERKS__) && ... */ + + +#endif /* __MEMAC_MII_ACC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c index cbe35351252a..452913d154ae 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File tgec.c @@ -41,10 +42,11 @@ #include "error_ext.h" #include "xx_ext.h" #include "endian_ext.h" -#include "crc_mac_addr_ext.h" #include "debug_ext.h" +#include "crc_mac_addr_ext.h" #include "fm_common.h" +#include "fsl_fman_tgec.h" #include "tgec.h" @@ -54,131 +56,116 @@ static t_Error CheckInitParameters(t_Tgec *p_Tgec) { - if(ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000) + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed")); #if (FM_MAX_NUM_OF_10G_MACS > 0) - if(p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS) + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0")); -#endif - if(p_Tgec->addr == 0) +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */ + + if (p_Tgec->addr == 0) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address")); - if(!p_Tgec->f_Exception) + if (!p_Tgec->f_Exception) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception")); - if(!p_Tgec->f_Event) + if (!p_Tgec->f_Event) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event")); +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ -static void SetDefaultParam(t_TgecDriverParam *p_TgecDriverParam) +static uint32_t GetMacAddrHashCode(uint64_t ethAddr) { - p_TgecDriverParam->wanModeEnable = DEFAULT_wanModeEnable; - p_TgecDriverParam->promiscuousModeEnable = DEFAULT_promiscuousModeEnable; - p_TgecDriverParam->pauseForwardEnable = DEFAULT_pauseForwardEnable; - p_TgecDriverParam->pauseIgnore = DEFAULT_pauseIgnore; - p_TgecDriverParam->txAddrInsEnable = DEFAULT_txAddrInsEnable; + uint32_t crc; - p_TgecDriverParam->loopbackEnable = DEFAULT_loopbackEnable; - p_TgecDriverParam->cmdFrameEnable = DEFAULT_cmdFrameEnable; - p_TgecDriverParam->rxErrorDiscard = DEFAULT_rxErrorDiscard; - p_TgecDriverParam->phyTxenaOn = DEFAULT_phyTxenaOn; - p_TgecDriverParam->sendIdleEnable = DEFAULT_sendIdleEnable; - p_TgecDriverParam->noLengthCheckEnable = DEFAULT_noLengthCheckEnable; - p_TgecDriverParam->lgthCheckNostdr = DEFAULT_lgthCheckNostdr; - p_TgecDriverParam->timeStampEnable = DEFAULT_timeStampEnable; - p_TgecDriverParam->rxSfdAny = DEFAULT_rxSfdAny; - p_TgecDriverParam->rxPblFwd = DEFAULT_rxPblFwd; - p_TgecDriverParam->txPblFwd = DEFAULT_txPblFwd; + /* CRC calculation */ + GET_MAC_ADDR_CRC(ethAddr, crc); - p_TgecDriverParam->txIpgLength = DEFAULT_txIpgLength; - p_TgecDriverParam->maxFrameLength = DEFAULT_maxFrameLength; + crc = GetMirror32(crc); - p_TgecDriverParam->debugMode = DEFAULT_debugMode; - - p_TgecDriverParam->pauseTime = DEFAULT_pauseTime; - -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 - p_TgecDriverParam->skipFman11Workaround = DEFAULT_skipFman11Workaround; -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ + return crc; } -/* ........................................................................... */ +/* ......................................................................... */ static void TgecErrException(t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; uint32_t event; - t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap; + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap; - event = GET_UINT32(p_TgecMemMap->ievent); /* do not handle MDIO events */ - event &= ~(IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL); + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap); - event &= GET_UINT32(p_TgecMemMap->imask); + fman_tgec_ack_event(p_TgecMemMap, event); - WRITE_UINT32(p_TgecMemMap->ievent, event); - - if (event & IMASK_REM_FAULT) + if (event & TGEC_IMASK_REM_FAULT) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT); - if (event & IMASK_LOC_FAULT) + if (event & TGEC_IMASK_LOC_FAULT) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT); - if (event & IMASK_1TX_ECC_ER) + if (event & TGEC_IMASK_TX_ECC_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER); - if (event & IMASK_TX_FIFO_UNFL) + if (event & TGEC_IMASK_TX_FIFO_UNFL) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL); - if (event & IMASK_TX_FIFO_OVFL) + if (event & TGEC_IMASK_TX_FIFO_OVFL) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL); - if (event & IMASK_TX_ER) + if (event & TGEC_IMASK_TX_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER); - if (event & IMASK_RX_FIFO_OVFL) + if (event & TGEC_IMASK_RX_FIFO_OVFL) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL); - if (event & IMASK_RX_ECC_ER) + if (event & TGEC_IMASK_RX_ECC_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER); - if (event & IMASK_RX_JAB_FRM) + if (event & TGEC_IMASK_RX_JAB_FRM) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM); - if (event & IMASK_RX_OVRSZ_FRM) + if (event & TGEC_IMASK_RX_OVRSZ_FRM) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM); - if (event & IMASK_RX_RUNT_FRM) + if (event & TGEC_IMASK_RX_RUNT_FRM) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM); - if (event & IMASK_RX_FRAG_FRM) + if (event & TGEC_IMASK_RX_FRAG_FRM) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM); - if (event & IMASK_RX_LEN_ER) + if (event & TGEC_IMASK_RX_LEN_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER); - if (event & IMASK_RX_CRC_ER) + if (event & TGEC_IMASK_RX_CRC_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER); - if (event & IMASK_RX_ALIGN_ER) + if (event & TGEC_IMASK_RX_ALIGN_ER) p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER); } +/* ......................................................................... */ + static void TgecException(t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - uint32_t event; - t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + uint32_t event; + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap; - event = GET_UINT32(p_TgecMemMap->ievent); /* handle only MDIO events */ - event &= (IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL); - event &= GET_UINT32(p_TgecMemMap->imask); + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap); - WRITE_UINT32(p_TgecMemMap->ievent, event); + fman_tgec_ack_event(p_TgecMemMap, event); - if(event & IMASK_MDIO_SCAN_EVENTMDIO) + if (event & TGEC_IMASK_MDIO_SCAN_EVENT) p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO); - if(event & IMASK_MDIO_CMD_CMPL) + if (event & TGEC_IMASK_MDIO_CMD_CMPL) p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL); } +/* ......................................................................... */ + static void FreeInitResources(t_Tgec *p_Tgec) { - if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ)) + if (p_Tgec->mdioIrq != NO_IRQ) { XX_DisableIntr(p_Tgec->mdioIrq); XX_FreeIntr(p_Tgec->mdioIrq); } - else if (p_Tgec->mdioIrq == 0) - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG)); + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR); /* release the driver's group hash table */ @@ -190,133 +177,49 @@ static void FreeInitResources(t_Tgec *p_Tgec) p_Tgec->p_UnicastAddrHash = NULL; } -/* .............................................................................. */ - -static void HardwareClearAddrInPaddr(t_Tgec *p_Tgec, uint8_t paddrNum) -{ - if (paddrNum != 0) - return; /* At this time MAC has only one address */ - - WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_2, 0x0); - WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_3, 0x0); -} - -/* ........................................................................... */ - -static void HardwareAddAddrInPaddr(t_Tgec *p_Tgec, uint64_t *p_Addr, uint8_t paddrNum) -{ - uint32_t tmpReg32 = 0; - uint64_t addr = *p_Addr; - t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap; - - if (paddrNum != 0) - return; /* At this time MAC has only one address */ - - tmpReg32 = (uint32_t)(addr>>16); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_TgecMemMap->mac_addr_2, tmpReg32); - - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - tmpReg32 >>= 16; - WRITE_UINT32(p_TgecMemMap->mac_addr_3, tmpReg32); -} /*****************************************************************************/ /* 10G MAC API routines */ /*****************************************************************************/ -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_MemMap ; - uint32_t tmpReg32 = 0; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap); - - tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl); - - switch (mode) - { - case e_COMM_MODE_NONE: - tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN); - break; - case e_COMM_MODE_RX : - tmpReg32 |= CMD_CFG_RX_EN ; - break; - case e_COMM_MODE_TX : - tmpReg32 |= CMD_CFG_TX_EN ; - break; - case e_COMM_MODE_RX_AND_TX: - tmpReg32 |= (CMD_CFG_TX_EN | CMD_CFG_RX_EN); - break; - } - - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32); + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_MemMap ; - uint32_t tmpReg32 = 0; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap); - - tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl); - switch (mode) - { - case e_COMM_MODE_RX: - tmpReg32 &= ~CMD_CFG_RX_EN; - break; - case e_COMM_MODE_TX: - tmpReg32 &= ~CMD_CFG_TX_EN; - break; - case e_COMM_MODE_RX_AND_TX: - tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); - } - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32); + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal) { t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; - uint32_t tmpReg32; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - - tmpReg32 = GET_UINT32(p_TgecMemMap->cmd_conf_ctrl); - - if (newVal) - tmpReg32 |= CMD_CFG_PROMIS_EN; - else - tmpReg32 &= ~CMD_CFG_PROMIS_EN; - - WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, tmpReg32); + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal); return E_OK; } @@ -326,80 +229,65 @@ static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal) /* Tgec Configs modification functions */ /*****************************************************************************/ -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -#ifdef FM_NO_TGEC_LOOPBACK - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("no loopback in this chip rev!")); - } -#endif /* FM_NO_TGEC_LOOPBACK */ - - p_Tgec->p_TgecDriverParam->loopbackEnable = newVal; + p_Tgec->p_TgecDriverParam->loopback_enable = newVal; return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_Tgec->p_TgecDriverParam->wanModeEnable = newVal; + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal; return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_Tgec->p_TgecDriverParam->maxFrameLength = newVal; + p_Tgec->p_TgecDriverParam->max_frame_length = newVal; return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal) { -#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 -UNUSED(h_Tgec); - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); - -#else - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; UNUSED(newVal); SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_Tgec->p_TgecDriverParam->noLengthCheckEnable = !newVal; + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal; return E_OK; -#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable) { @@ -408,19 +296,9 @@ static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo); - if((revInfo.majorRev <=2) && - enable && - ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT))) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !")); - } -#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */ GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) + if (bitMask) { if (enable) p_Tgec->exceptions |= bitMask; @@ -434,7 +312,7 @@ static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, } #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec) { @@ -443,7 +321,7 @@ static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec) SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_Tgec->p_TgecDriverParam->skipFman11Workaround = TRUE; + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE; return E_OK; } @@ -454,217 +332,179 @@ static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec) /* Tgec Run Time API functions */ /*****************************************************************************/ -/* .............................................................................. */ - +/* ......................................................................... */ +/* backward compatibility. will be removed in the future. */ static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - uint32_t ptv = 0; - t_TgecMemMap *p_MemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE); + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime); - p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap); - - ptv = (uint32_t)pauseTime; - - WRITE_UINT32(p_MemMap->pause_quant, ptv); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ + +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime) +{ + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); + + UNUSED(priority); UNUSED(threshTime); + + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime); + + return E_OK; +} + +/* ......................................................................... */ static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_MemMap; - uint32_t tmpReg32; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE); - p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap); - tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl); - if (en) - tmpReg32 |= CMD_CFG_PAUSE_IGNORE; - else - tmpReg32 &= ~CMD_CFG_PAUSE_IGNORE; - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32); + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en); return E_OK; } -/* Counters handling */ -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + struct tgec_regs *p_TgecMemMap; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); p_TgecMemMap = p_Tgec->p_MemMap; - p_Statistics->eStatPkts64 = GET_UINT64(p_TgecMemMap->R64); - p_Statistics->eStatPkts65to127 = GET_UINT64(p_TgecMemMap->R127); - p_Statistics->eStatPkts128to255 = GET_UINT64(p_TgecMemMap->R255); - p_Statistics->eStatPkts256to511 = GET_UINT64(p_TgecMemMap->R511); - p_Statistics->eStatPkts512to1023 = GET_UINT64(p_TgecMemMap->R1023); - p_Statistics->eStatPkts1024to1518 = GET_UINT64(p_TgecMemMap->R1518); - p_Statistics->eStatPkts1519to1522 = GET_UINT64(p_TgecMemMap->R1519X); + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64); + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127); + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255); + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511); + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023); + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518); + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X); /* */ - p_Statistics->eStatFragments = GET_UINT64(p_TgecMemMap->TRFRG); - p_Statistics->eStatJabbers = GET_UINT64(p_TgecMemMap->TRJBR); + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG); + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR); - p_Statistics->eStatsDropEvents = GET_UINT64(p_TgecMemMap->RDRP); - p_Statistics->eStatCRCAlignErrors = GET_UINT64(p_TgecMemMap->RALN); + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP); + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN); - p_Statistics->eStatUndersizePkts = GET_UINT64(p_TgecMemMap->TRUND); - p_Statistics->eStatOversizePkts = GET_UINT64(p_TgecMemMap->TROVR); + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND); + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR); /* Pause */ - p_Statistics->reStatPause = GET_UINT64(p_TgecMemMap->RXPF); - p_Statistics->teStatPause = GET_UINT64(p_TgecMemMap->TXPF); - + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF); + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF); /* MIB II */ - p_Statistics->ifInOctets = GET_UINT64(p_TgecMemMap->ROCT); - p_Statistics->ifInMcastPkts = GET_UINT64(p_TgecMemMap->RMCA); - p_Statistics->ifInBcastPkts = GET_UINT64(p_TgecMemMap->RBCA); - p_Statistics->ifInPkts = GET_UINT64(p_TgecMemMap->RUCA) + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT); + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA); + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA); + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA); + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts + p_Statistics->ifInMcastPkts + p_Statistics->ifInBcastPkts; p_Statistics->ifInDiscards = 0; - p_Statistics->ifInErrors = GET_UINT64(p_TgecMemMap->RERR); + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR); - p_Statistics->ifOutOctets = GET_UINT64(p_TgecMemMap->TOCT); - p_Statistics->ifOutMcastPkts = GET_UINT64(p_TgecMemMap->TMCA); - p_Statistics->ifOutBcastPkts = GET_UINT64(p_TgecMemMap->TBCA); - p_Statistics->ifOutPkts = GET_UINT64(p_TgecMemMap->TUCA); + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT); + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA); + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA); + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA); + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts + + p_Statistics->ifOutMcastPkts + + p_Statistics->ifOutBcastPkts; p_Statistics->ifOutDiscards = 0; - p_Statistics->ifOutErrors = GET_UINT64(p_TgecMemMap->TERR); + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE); - - WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) | CMD_CFG_EN_TIMESTAMP); + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE); - - WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) & ~CMD_CFG_EN_TIMESTAMP); + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; - uint32_t tmpReg32 = 0; - uint64_t addr; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - - /* Initialize MAC Station Address registers (1 & 2) */ - /* Station address have to be swapped (big endian to little endian */ - - addr = ((*(uint64_t *)p_EnetAddr) >> 16); - p_Tgec->addr = addr; - - tmpReg32 = (uint32_t)(addr>>16); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_TgecMemMap->mac_addr_0, tmpReg32); - - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - tmpReg32 >>= 16; - WRITE_UINT32(p_TgecMemMap->mac_addr_1, tmpReg32); + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr); + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr)); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecResetCounters (t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_MemMap ; - uint32_t tmpReg32, cmdConfCtrl; - int i; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap); - - cmdConfCtrl = GET_UINT32(p_MemMap->cmd_conf_ctrl); - - cmdConfCtrl |= CMD_CFG_STAT_CLR; - - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl); - - for (i=0; i<1000; i++) - { - tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl); - if (!(tmpReg32 & CMD_CFG_STAT_CLR)) - break; - } - - cmdConfCtrl &= ~CMD_CFG_STAT_CLR; - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl); + fman_tgec_reset_stat(p_Tgec->p_MemMap); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) { - t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; - uint64_t ethAddr; - uint8_t paddrNum; + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; + uint64_t ethAddr; + uint8_t paddrNum; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); if (ethAddr & GROUP_ADDRESS) /* Multicast address has no effect in PADDR */ @@ -672,15 +512,9 @@ static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAdd /* Make sure no PADDR contains this address */ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) - { if (p_Tgec->indAddrRegUsed[paddrNum]) - { if (p_Tgec->paddr[paddrNum] == ethAddr) - { RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); - } - } - } /* Find first unused PADDR */ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) @@ -693,7 +527,7 @@ static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAdd p_Tgec->paddr[paddrNum] = ethAddr; /* put in hardware */ - HardwareAddAddrInPaddr(p_Tgec, ðAddr, paddrNum); + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */); p_Tgec->numOfIndAddrInRegs++; return E_OK; @@ -704,18 +538,18 @@ static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAdd RETURN_ERROR(MAJOR, E_FULL, NO_MSG); } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) { - t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; - uint64_t ethAddr; - uint8_t paddrNum; + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; + uint64_t ethAddr; + uint8_t paddrNum; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); /* Find used PADDR containing this address */ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) @@ -726,7 +560,7 @@ static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAdd /* mark this PADDR as not used */ p_Tgec->indAddrRegUsed[paddrNum] = FALSE; /* clear in hardware */ - HardwareClearAddrInPaddr(p_Tgec, paddrNum); + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */); p_Tgec->numOfIndAddrInRegs--; return E_OK; @@ -736,142 +570,118 @@ static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAdd RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) { t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; t_EthHashEntry *p_HashEntry; uint32_t crc; uint32_t hash; uint64_t ethAddr; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); if (!(ethAddr & GROUP_ADDRESS)) /* Unicast addresses not supported in hash */ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address")); /* CRC calculation */ - GET_MAC_ADDR_CRC(ethAddr, crc); - crc = MIRROR_32(crc); + crc = GetMacAddrHashCode(ethAddr); - hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK; /* Take 9 MSB bits */ + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ /* Create element to be added to the driver hash table */ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); p_HashEntry->addr = ethAddr; INIT_LIST(&p_HashEntry->node); - LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])); - WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash | HASH_CTRL_MCAST_EN)); + NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])); + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN)); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; - t_EthHashEntry *p_HashEntry = NULL; - t_List *p_Pos; - uint32_t crc; - uint32_t hash; - uint64_t ethAddr; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_EthHashEntry *p_HashEntry = NULL; + t_List *p_Pos; + uint32_t crc; + uint32_t hash; + uint64_t ethAddr; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); /* CRC calculation */ - GET_MAC_ADDR_CRC(ethAddr, crc); - crc = MIRROR_32(crc); + crc = GetMacAddrHashCode(ethAddr); - hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK; /* Take 9 MSB bits */ + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ - LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) + NCSW_LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) { - p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); - if(p_HashEntry->addr == ethAddr) + if (p_HashEntry->addr == ethAddr) { - LIST_DelAndInit(&p_HashEntry->node); + NCSW_LIST_DelAndInit(&p_HashEntry->node); XX_Free(p_HashEntry); break; } } - if(LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) - WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash & ~HASH_CTRL_MCAST_EN)); + if (NCSW_LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN)); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); UNUSED(p_Tgec); UNUSED(macId); RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported")); } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecMemMap *p_TgecMemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - p_TgecMemMap = p_Tgec->p_MemMap; - *macVersion = GET_UINT32(p_TgecMemMap->tgec_id); + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - uint32_t bitMask = 0, tmpReg; - t_TgecMemMap *p_TgecMemMap; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + uint32_t bitMask = 0; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER); - - p_TgecMemMap = p_Tgec->p_MemMap; -#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo); - if((revInfo.majorRev <=2) && - enable && - ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT))) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !")); - } -#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */ + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) + if (bitMask) { if (enable) p_Tgec->exceptions |= bitMask; @@ -881,250 +691,147 @@ static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bo else RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - tmpReg = GET_UINT32(p_TgecMemMap->imask); - if(enable) - tmpReg |= bitMask; + if (enable) + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask); else - tmpReg &= ~bitMask; - WRITE_UINT32(p_TgecMemMap->imask, tmpReg); + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask); + return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec) { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0); - return (uint16_t)GET_UINT32(p_Tgec->p_MemMap->maxfrm); + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap); } -/* .............................................................................. */ +/* ......................................................................... */ #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec) { t_Error err; - XX_Print("Applying 10G tx-ecc error workaround (10GMAC-A004) ..."); +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0) + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... "); +#endif /* (DEBUG_ERRORS > 0) */ /* enable and set promiscuous */ - WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, CMD_CFG_PROMIS_EN | CMD_CFG_TX_EN | CMD_CFG_RX_EN); + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE); + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE); err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId); /* disable */ - WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, 0); + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE); + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE); + fman_tgec_reset_stat(p_Tgec->p_MemMap); + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff); +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0) if (err) XX_Print("FAILED!\n"); else XX_Print("done.\n"); - TgecResetCounters (p_Tgec); +#endif /* (DEBUG_ERRORS > 0) */ return err; } #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -/* .............................................................................. */ - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -static t_Error TgecDumpRegs(t_Handle h_Tgec) -{ - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - - DECLARE_DUMP; - - if (p_Tgec->p_MemMap) - { - DUMP_TITLE(p_Tgec->p_MemMap, ("10G MAC %d: ", p_Tgec->macId)); - DUMP_VAR(p_Tgec->p_MemMap, tgec_id); - DUMP_VAR(p_Tgec->p_MemMap, scratch); - DUMP_VAR(p_Tgec->p_MemMap, cmd_conf_ctrl); - DUMP_VAR(p_Tgec->p_MemMap, mac_addr_0); - DUMP_VAR(p_Tgec->p_MemMap, mac_addr_1); - DUMP_VAR(p_Tgec->p_MemMap, maxfrm); - DUMP_VAR(p_Tgec->p_MemMap, pause_quant); - DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_sections); - DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_sections); - DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_almost_f_e); - DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_almost_f_e); - DUMP_VAR(p_Tgec->p_MemMap, hashtable_ctrl); - DUMP_VAR(p_Tgec->p_MemMap, mdio_cfg_status); - DUMP_VAR(p_Tgec->p_MemMap, mdio_command); - DUMP_VAR(p_Tgec->p_MemMap, mdio_data); - DUMP_VAR(p_Tgec->p_MemMap, mdio_regaddr); - DUMP_VAR(p_Tgec->p_MemMap, status); - DUMP_VAR(p_Tgec->p_MemMap, tx_ipg_len); - DUMP_VAR(p_Tgec->p_MemMap, mac_addr_2); - DUMP_VAR(p_Tgec->p_MemMap, mac_addr_3); - DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_rd); - DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_wr); - DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_rd); - DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_wr); - DUMP_VAR(p_Tgec->p_MemMap, imask); - DUMP_VAR(p_Tgec->p_MemMap, ievent); - DUMP_VAR(p_Tgec->p_MemMap, udp_port); - DUMP_VAR(p_Tgec->p_MemMap, type_1588v2); - } - - return E_OK; -} -#endif /* (defined(DEBUG_ERRORS) && ... */ - - /*****************************************************************************/ /* FM Init & Free API */ /*****************************************************************************/ -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecInit(t_Handle h_Tgec) { t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; - t_TgecDriverParam *p_TgecDriverParam; - t_TgecMemMap *p_MemMap; - uint64_t addr; - uint32_t tmpReg32; + struct tgec_cfg *p_TgecDriverParam; + t_EnetAddr ethAddr; t_Error err; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE); - -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 - if (!p_Tgec->p_TgecDriverParam->skipFman11Workaround && - ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK)) -#ifdef NCSW_LINUX - { - /* the workaround fails in simics, just report and continue initialization */ - REPORT_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED, skipping workaround")); - } -#else - { - FreeInitResources(p_Tgec); - RETURN_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED")); - } -#endif -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo); CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters); p_TgecDriverParam = p_Tgec->p_TgecDriverParam; - p_MemMap = p_Tgec->p_MemMap; - /* MAC Address */ - addr = p_Tgec->addr; - tmpReg32 = (uint32_t)(addr>>16); - SwapUint32P(&tmpReg32); - WRITE_UINT32(p_MemMap->mac_addr_0, tmpReg32); + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr); + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr); - tmpReg32 = (uint32_t)(addr); - SwapUint32P(&tmpReg32); - tmpReg32 >>= 16; - WRITE_UINT32(p_MemMap->mac_addr_1, tmpReg32); + /* interrupts */ +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 + { + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2) + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT); + } +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */ - /* Config */ - tmpReg32 = 0; - if (p_TgecDriverParam->wanModeEnable) - tmpReg32 |= CMD_CFG_WAN_MODE; - if (p_TgecDriverParam->promiscuousModeEnable) - tmpReg32 |= CMD_CFG_PROMIS_EN; - if (p_TgecDriverParam->pauseForwardEnable) - tmpReg32 |= CMD_CFG_PAUSE_FWD; - if (p_TgecDriverParam->pauseIgnore) - tmpReg32 |= CMD_CFG_PAUSE_IGNORE; - if (p_TgecDriverParam->txAddrInsEnable) - tmpReg32 |= CMD_CFG_TX_ADDR_INS; - if (p_TgecDriverParam->loopbackEnable) - tmpReg32 |= CMD_CFG_LOOPBACK_EN; - if (p_TgecDriverParam->cmdFrameEnable) - tmpReg32 |= CMD_CFG_CMD_FRM_EN; - if (p_TgecDriverParam->rxErrorDiscard) - tmpReg32 |= CMD_CFG_RX_ER_DISC; - if (p_TgecDriverParam->phyTxenaOn) - tmpReg32 |= CMD_CFG_PHY_TX_EN; - if (p_TgecDriverParam->sendIdleEnable) - tmpReg32 |= CMD_CFG_SEND_IDLE; - if (p_TgecDriverParam->noLengthCheckEnable) - tmpReg32 |= CMD_CFG_NO_LEN_CHK; - if (p_TgecDriverParam->lgthCheckNostdr) - tmpReg32 |= CMD_CFG_LEN_CHK_NOSTDR; - if (p_TgecDriverParam->timeStampEnable) - tmpReg32 |= CMD_CFG_EN_TIMESTAMP; - if (p_TgecDriverParam->rxSfdAny) - tmpReg32 |= RX_SFD_ANY; - if (p_TgecDriverParam->rxPblFwd) - tmpReg32 |= CMD_CFG_RX_PBL_FWD; - if (p_TgecDriverParam->txPblFwd) - tmpReg32 |= CMD_CFG_TX_PBL_FWD; - tmpReg32 |= 0x40; - WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32); - - /* Max Frame Length */ - WRITE_UINT32(p_MemMap->maxfrm, (uint32_t)p_TgecDriverParam->maxFrameLength); - err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MAC_10G, p_Tgec->fmMacControllerDriver.macId, p_TgecDriverParam->maxFrameLength); - if(err) +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround && + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK)) { FreeInitResources(p_Tgec); - RETURN_ERROR(MAJOR, err, NO_MSG); + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED")); + } +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ + + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions); + if (err) + { + FreeInitResources(p_Tgec); + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode")); } - /* Pause Time */ - WRITE_UINT32(p_MemMap->pause_quant, p_TgecDriverParam->pauseTime); + /* Max Frame Length */ + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm, + e_FM_MAC_10G, + p_Tgec->fmMacControllerDriver.macId, + p_TgecDriverParam->max_frame_length); + if (err != E_OK) + { + FreeInitResources(p_Tgec); + RETURN_ERROR(MINOR, err, NO_MSG); + } +/* we consider having no IPC a non crasher... */ #ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 - WRITE_UINT32(p_Tgec->p_MemMap->tx_ipg_len, - (GET_UINT32(p_Tgec->p_MemMap->tx_ipg_len) & ~TX_IPG_LENGTH_MASK) | DEFAULT_txIpgLength); + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2) + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap); #endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */ - /* Configure MII */ - tmpReg32 = GET_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status); -#ifdef FM_10G_MDIO_HOLD_ERRATA_XAUI3 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - tmpReg32 |= (MIIMCOM_MDIO_HOLD_4_REG_CLK << 2); - } -#endif /* FM_10G_MDIO_HOLD_ERRATA_XAUI3 */ - tmpReg32 &= ~MIIMCOM_DIV_MASK; - /* (one half of fm clock => 2.5Mhz) */ - tmpReg32 |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT); - WRITE_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status, tmpReg32); - p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); - if(!p_Tgec->p_MulticastAddrHash) + if (!p_Tgec->p_MulticastAddrHash) { FreeInitResources(p_Tgec); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); } p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); - if(!p_Tgec->p_UnicastAddrHash) + if (!p_Tgec->p_UnicastAddrHash) { FreeInitResources(p_Tgec); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); } - /* interrupts */ -#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo); - if (revInfo.majorRev <=2) - p_Tgec->exceptions &= ~(IMASK_REM_FAULT | IMASK_LOC_FAULT); - } -#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */ - WRITE_UINT32(p_MemMap->ievent, EVENTS_MASK); - WRITE_UINT32(p_MemMap->imask, p_Tgec->exceptions); - - FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR, TgecErrException , p_Tgec); - if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ)) + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, + e_FM_MOD_10G_MAC, + p_Tgec->macId, + e_FM_INTR_TYPE_ERR, + TgecErrException, + p_Tgec); + if (p_Tgec->mdioIrq != NO_IRQ) { XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec); XX_EnableIntr(p_Tgec->mdioIrq); } - else if (p_Tgec->mdioIrq == 0) - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG)); XX_Free(p_TgecDriverParam); p_Tgec->p_TgecDriverParam = NULL; @@ -1132,7 +839,7 @@ static t_Error TgecInit(t_Handle h_Tgec) return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static t_Error TgecFree(t_Handle h_Tgec) { @@ -1140,25 +847,29 @@ static t_Error TgecFree(t_Handle h_Tgec) SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); - FreeInitResources(p_Tgec); - if (p_Tgec->p_TgecDriverParam) { + /* Called after config */ XX_Free(p_Tgec->p_TgecDriverParam); p_Tgec->p_TgecDriverParam = NULL; } - XX_Free (p_Tgec); + else + /* Called after init */ + FreeInitResources(p_Tgec); + + XX_Free(p_Tgec); return E_OK; } -/* .............................................................................. */ +/* ......................................................................... */ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) { p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit; p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree; + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL; p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback; p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength; @@ -1168,6 +879,7 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck; p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException; + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL; #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround; @@ -1180,11 +892,15 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous; p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL; + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL; + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL; p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable; p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable; + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL; p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause; + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames; p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause; p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters; @@ -1201,10 +917,6 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg; p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg; - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) - p_FmMacControllerDriver->f_FM_MAC_DumpRegs = TgecDumpRegs; -#endif /* (defined(DEBUG_ERRORS) && ... */ } @@ -1212,50 +924,45 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController /* Tgec Config Main Entry */ /*****************************************************************************/ -/* .............................................................................. */ +/* ......................................................................... */ t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam) { - t_Tgec *p_Tgec; - t_TgecDriverParam *p_TgecDriverParam; - uintptr_t baseAddr; - uint8_t i; + t_Tgec *p_Tgec; + struct tgec_cfg *p_TgecDriverParam; + uintptr_t baseAddr; SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); baseAddr = p_FmMacParam->baseAddr; /* allocate memory for the UCC GETH data structure. */ - p_Tgec = (t_Tgec *) XX_Malloc(sizeof(t_Tgec)); + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec)); if (!p_Tgec) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure")); return NULL; } - /* Zero out * p_Tgec */ memset(p_Tgec, 0, sizeof(t_Tgec)); InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver); /* allocate memory for the 10G MAC driver parameters data structure. */ - p_TgecDriverParam = (t_TgecDriverParam *) XX_Malloc(sizeof(t_TgecDriverParam)); + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg)); if (!p_TgecDriverParam) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters")); - TgecFree(p_Tgec); + XX_Free(p_Tgec); return NULL; } - /* Zero out */ - memset(p_TgecDriverParam, 0, sizeof(t_TgecDriverParam)); + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg)); /* Plant parameter structure pointer */ p_Tgec->p_TgecDriverParam = p_TgecDriverParam; - SetDefaultParam(p_TgecDriverParam); + fman_tgec_defconfig(p_TgecDriverParam); - for (i=0; i < sizeof(p_FmMacParam->addr); i++) - p_Tgec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8)); - - p_Tgec->p_MemMap = (t_TgecMemMap *)UINT_TO_PTR(baseAddr); + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr); p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET); + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); p_Tgec->enetMode = p_FmMacParam->enetMode; p_Tgec->macId = p_FmMacParam->macId; p_Tgec->exceptions = DEFAULT_exceptions; diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h index db22eadd669f..2aa392385588 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File tgec.h @@ -41,190 +42,72 @@ #include "std_ext.h" #include "error_ext.h" #include "list_ext.h" +#include "enet_ext.h" + #include "tgec_mii_acc.h" #include "fm_mac.h" -/* Interrupt Mask Register (IMASK) */ -#define IMASK_MDIO_SCAN_EVENTMDIO 0x00010000 /* MDIO_SCAN_EVENTMDIO scan event interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_MDIO_CMD_CMPL 0x00008000 /* 16 MDIO_CMD_CMPL MDIO command completion interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_REM_FAULT 0x00004000 /* 17 REM_FAULT Remote fault interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_LOC_FAULT 0x00002000 /* 18 LOC_FAULT Local fault interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_1TX_ECC_ER 0x00001000 /* 19 TX_ECC_ER Transmit frame ECC error interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_TX_FIFO_UNFL 0x00000800 /* 20 TX_FIFO_UNFL Transmit FIFO underflow interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_TX_FIFO_OVFL 0x00000400 /* 21 TX_FIFO_OVFL Transmit FIFO overflow interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_TX_ER 0x00000200 /* 22 TX_ER Transmit frame error interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_FIFO_OVFL 0x00000100 /* 23 RX_FIFO_OVFL Receive FIFO overflow interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_ECC_ER 0x00000080 /* 24 RX_ECC_ER Receive frame ECC error interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_JAB_FRM 0x00000040 /* 25 RX_JAB_FRM Receive jabber frame interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_OVRSZ_FRM 0x00000020 /* 26 RX_OVRSZ_FRM Receive oversized frame interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_RUNT_FRM 0x00000010 /* 27 RX_RUNT_FRM Receive runt frame interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_FRAG_FRM 0x00000008 /* 28 RX_FRAG_FRM Receive fragment frame interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_LEN_ER 0x00000004 /* 29 RX_LEN_ER Receive payload length error interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_CRC_ER 0x00000002 /* 30 RX_CRC_ER Receive CRC error interrupt mask. - * 0 masked - * 1 enabled - */ -#define IMASK_RX_ALIGN_ER 0x00000001 /* 31 RX_ALIGN_ER Receive alignment error interrupt mask. - * 0 masked - * 1 enabled - */ +#define DEFAULT_exceptions \ + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \ + TGEC_IMASK_REM_FAULT | \ + TGEC_IMASK_LOC_FAULT | \ + TGEC_IMASK_TX_ECC_ER | \ + TGEC_IMASK_TX_FIFO_UNFL | \ + TGEC_IMASK_TX_FIFO_OVFL | \ + TGEC_IMASK_TX_ER | \ + TGEC_IMASK_RX_FIFO_OVFL | \ + TGEC_IMASK_RX_ECC_ER | \ + TGEC_IMASK_RX_JAB_FRM | \ + TGEC_IMASK_RX_OVRSZ_FRM | \ + TGEC_IMASK_RX_RUNT_FRM | \ + TGEC_IMASK_RX_FRAG_FRM | \ + TGEC_IMASK_RX_CRC_ER | \ + TGEC_IMASK_RX_ALIGN_ER)) -#define EVENTS_MASK ((uint32_t)(IMASK_MDIO_SCAN_EVENTMDIO | \ - IMASK_MDIO_CMD_CMPL | \ - IMASK_REM_FAULT | \ - IMASK_LOC_FAULT | \ - IMASK_1TX_ECC_ER | \ - IMASK_TX_FIFO_UNFL | \ - IMASK_TX_FIFO_OVFL | \ - IMASK_TX_ER | \ - IMASK_RX_FIFO_OVFL | \ - IMASK_RX_ECC_ER | \ - IMASK_RX_JAB_FRM | \ - IMASK_RX_OVRSZ_FRM | \ - IMASK_RX_RUNT_FRM | \ - IMASK_RX_FRAG_FRM | \ - IMASK_RX_LEN_ER | \ - IMASK_RX_CRC_ER | \ - IMASK_RX_ALIGN_ER)) - -#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \ - case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \ - bitMask = IMASK_MDIO_SCAN_EVENTMDIO; break; \ - case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \ - bitMask = IMASK_MDIO_CMD_CMPL ; break; \ - case e_FM_MAC_EX_10G_REM_FAULT: \ - bitMask = IMASK_REM_FAULT ; break; \ - case e_FM_MAC_EX_10G_LOC_FAULT: \ - bitMask = IMASK_LOC_FAULT ; break; \ - case e_FM_MAC_EX_10G_1TX_ECC_ER: \ - bitMask = IMASK_1TX_ECC_ER ; break; \ - case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \ - bitMask = IMASK_TX_FIFO_UNFL ; break; \ - case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \ - bitMask = IMASK_TX_FIFO_OVFL ; break; \ - case e_FM_MAC_EX_10G_TX_ER: \ - bitMask = IMASK_TX_ER ; break; \ - case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \ - bitMask = IMASK_RX_FIFO_OVFL ; break; \ - case e_FM_MAC_EX_10G_RX_ECC_ER: \ - bitMask = IMASK_RX_ECC_ER ; break; \ - case e_FM_MAC_EX_10G_RX_JAB_FRM: \ - bitMask = IMASK_RX_JAB_FRM ; break; \ - case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \ - bitMask = IMASK_RX_OVRSZ_FRM ; break; \ - case e_FM_MAC_EX_10G_RX_RUNT_FRM: \ - bitMask = IMASK_RX_RUNT_FRM ; break; \ - case e_FM_MAC_EX_10G_RX_FRAG_FRM: \ - bitMask = IMASK_RX_FRAG_FRM ; break; \ - case e_FM_MAC_EX_10G_RX_LEN_ER: \ - bitMask = IMASK_RX_LEN_ER ; break; \ - case e_FM_MAC_EX_10G_RX_CRC_ER: \ - bitMask = IMASK_RX_CRC_ER ; break; \ - case e_FM_MAC_EX_10G_RX_ALIGN_ER: \ - bitMask = IMASK_RX_ALIGN_ER ; break; \ +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \ + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \ + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \ + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \ + case e_FM_MAC_EX_10G_REM_FAULT: \ + bitMask = TGEC_IMASK_REM_FAULT ; break; \ + case e_FM_MAC_EX_10G_LOC_FAULT: \ + bitMask = TGEC_IMASK_LOC_FAULT ; break; \ + case e_FM_MAC_EX_10G_1TX_ECC_ER: \ + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \ + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \ + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \ + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \ + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \ + case e_FM_MAC_EX_10G_TX_ER: \ + bitMask = TGEC_IMASK_TX_ER ; break; \ + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \ + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \ + case e_FM_MAC_EX_10G_RX_ECC_ER: \ + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \ + case e_FM_MAC_EX_10G_RX_JAB_FRM: \ + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \ + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \ + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \ + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \ + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \ + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \ + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \ + case e_FM_MAC_EX_10G_RX_LEN_ER: \ + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \ + case e_FM_MAC_EX_10G_RX_CRC_ER: \ + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \ + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \ + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \ default: bitMask = 0;break;} - -/* Default Config Params */ -#define DEFAULT_wanModeEnable FALSE -#define DEFAULT_promiscuousModeEnable FALSE - - -#define DEFAULT_pauseForwardEnable FALSE -#define DEFAULT_pauseIgnore FALSE -#define DEFAULT_txAddrInsEnable FALSE - -#define DEFAULT_loopbackEnable FALSE -#define DEFAULT_cmdFrameEnable FALSE -#define DEFAULT_rxErrorDiscard FALSE -#define DEFAULT_phyTxenaOn FALSE -#define DEFAULT_sendIdleEnable FALSE -#define DEFAULT_noLengthCheckEnable TRUE -#define DEFAULT_lgthCheckNostdr FALSE -#define DEFAULT_timeStampEnable FALSE -#define DEFAULT_rxSfdAny FALSE -#define DEFAULT_rxPblFwd FALSE -#define DEFAULT_txPblFwd FALSE -#define DEFAULT_txIpgLength 12 - -#define DEFAULT_maxFrameLength 0x600 - -#define DEFAULT_debugMode FALSE -#define DEFAULT_pauseTime 0xf000 -#define DEFAULT_imask 0xf000 -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -#define DEFAULT_skipFman11Workaround FALSE -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ - -#define DEFAULT_exceptions ((uint32_t)(IMASK_MDIO_SCAN_EVENTMDIO | \ - IMASK_REM_FAULT | \ - IMASK_LOC_FAULT | \ - IMASK_1TX_ECC_ER | \ - IMASK_TX_FIFO_UNFL | \ - IMASK_TX_FIFO_OVFL | \ - IMASK_TX_ER | \ - IMASK_RX_FIFO_OVFL | \ - IMASK_RX_ECC_ER | \ - IMASK_RX_JAB_FRM | \ - IMASK_RX_OVRSZ_FRM | \ - IMASK_RX_RUNT_FRM | \ - IMASK_RX_FRAG_FRM | \ - IMASK_RX_CRC_ER | \ - IMASK_RX_ALIGN_ER)) - #define MAX_PACKET_ALIGNMENT 31 #define MAX_INTER_PACKET_GAP 0x7f #define MAX_INTER_PALTERNATE_BEB 0x0f #define MAX_RETRANSMISSION 0x0f #define MAX_COLLISION_WINDOW 0x03ff - #define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */ #define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */ @@ -238,225 +121,11 @@ #define TGEC_ID_MAC_VERSION 0x0000FF00 #define TGEC_ID_MAC_REV 0x000000ff -/* Command and Configuration Register (COMMAND_CONFIG) */ -#define CMD_CFG_TX_PBL_FWD 0x00800000 /* 08 Transmit Preamble Forwarding (custom preamble). - */ -#define CMD_CFG_RX_PBL_FWD 0x00400000 /* 09 Receive Preamble Forwarding (custom preamble). - */ -#define RX_SFD_ANY 0x00200000 /* 10 Enables, when set, that any character is allowed at the SFD position of the preamble and the frame will be accepted. - */ -#define CMD_CFG_EN_TIMESTAMP 0x00100000 /* 11 EN_TIMESTAMP IEEE 1588 timeStamp functionality control. - * 0 disabled - * 1 enabled - */ -#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000 /* 12 TX_ADDR_INS_SEL Transmit MAC address select - * 0 insert using first MAC address - * 1 insert using second MAC address - */ -#define CMD_CFG_LEN_CHK_NOSTDR 0x00040000 /* 13 LEN_CHK_NOSTDR - */ -#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 NO_LEN_CHK Payload length check disable - * 0 MAC compares the frame payload length with the frame length/type field. - * 1 Payload length check is disabled. - */ -#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 SEND_IDLE Force idle generation - * 0 Normal operation. - * 1 MAC permanently sends XGMII idle sequences even when faults are received. - */ -#define CMD_CFG_PHY_TX_EN 0x00008000 /* 16 PHY_TX_EN PHY transmit enable - * 0 PHY transmit is disabled. - * 1 PHY transmit is enabled. - */ -#define CMD_CFG_RX_ER_DISC 0x00004000 /* 17 RX_ER_DISC Receive error frame discard enable - * 0 Received error frames are processed. - * 1 Any frame received with an error is discarded. - */ -#define CMD_CFG_CMD_FRM_EN 0x00002000 /* 18 CMD_FRM_EN Command frame reception enable - * 0 Only Pause frames are accepted (all other command frames are rejected). - * 1 All command frames are accepted. - */ -#define CMD_CFG_STAT_CLR 0x00001000 /* 19 STAT_CLR Clear statistics - * 0 Normal operations. - * 1 All statistics counters are cleared. - */ -#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 LOOPBAC_EN PHY interface loopback enable - * 0 Configure PHY for normal operation. - * 1 Configure PHY for loopback mode. - */ -#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 TX_ADDR_INS Transmit source MAC address insertion - * 0 MAC transmits the source MAC address unmodified. - * 1 MAC overwrites the source MAC address with address specified by COMMAND_CONFIG[TX_ADDR_INS_SEL]. - */ -#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 PAUSE_IGNORE Ignore Pause frame quanta - * 0 MAC stops transmit process for the duration specified in the Pause frame quanta of a received Pause frame. - * 1 MAC ignores received Pause frames. - */ -#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 PAUSE_FWD Terminate/forward received Pause frames - * 0 MAC terminates and discards received Pause frames. - * 1 MAC forwards Pause frames to the user application. - */ -#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 PROMIS_EN Promiscuous operation enable - * 0 Unicast frames with a destination address not matching the core MAC address (defined by registers, MAC_ADDR_0 and MAC_ADDR_1) are rejected. - * 1 All frames are received without any MAC address filtering. - */ -#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN_MODE WAN mode enable - * 0 Configure MAC for LAN mode. - * 1 Configure MAC for WAN mode. - */ -#define CMD_CFG_RX_EN 0x00000002 /* 30 RX_EN MAC receive path enable - * 0 MAC receive path is disabled - * 1 MAC receive path is enabled. - */ -#define CMD_CFG_TX_EN 0x00000001 /* 31 TX_EN MAC transmit path enable - * 0 MAC transmit path is disabled - * 1 MAC transmit path is enabled. - */ - -/* Hashtable Control Register (HASHTABLE_CTRL) */ -#define HASH_CTRL_MCAST_SHIFT 23 - -#define HASH_CTRL_MCAST_RD 0x00000400 /* 22 MCAST_READ Entry Multicast frame reception for the hash entry. - * 0 disabled - * 1 enabled - */ -#define HASH_CTRL_MCAST_EN 0x00000200 /* 22 MCAST_EN Multicast frame reception for the hash entry. - * 0 disabled - * 1 enabled - */ -#define HASH_ADDR_MASK 0x000001ff /* 23-31 HASH_ADDR Hash table address code. - */ - -/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ -#define TX_IPG_LENGTH_MASK 0x000003ff - - - -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(push,1) -#endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START - -/* - * 10G memory map - */ -typedef _Packed struct { -/* 10Ge General Control and Status */ - volatile uint32_t tgec_id; /* 0x000 10GEC_ID - Controller ID register */ - volatile uint32_t scratch; /* 0x004 */ - volatile uint32_t cmd_conf_ctrl; /* 0x008 COMMAND_CONFIG - Control and configuration register */ - volatile uint32_t mac_addr_0; /* 0x00C MAC_ADDR_0 - Lower 32 bits of the first 48-bit MAC address */ - volatile uint32_t mac_addr_1; /* 0x010 MAC_ADDR_1 - Upper 16 bits of the first 48-bit MAC address */ - volatile uint32_t maxfrm; /* 0x014 MAXFRM - Maximum frame length register */ - volatile uint32_t pause_quant; /* 0x018 PAUSE_QUANT - Pause quanta register */ - volatile uint32_t rx_fifo_sections; /* 0x01c */ - volatile uint32_t tx_fifo_sections; /* 0x020 */ - volatile uint32_t rx_fifo_almost_f_e; /* 0x024 */ - volatile uint32_t tx_fifo_almost_f_e; /* 0x028 */ - volatile uint32_t hashtable_ctrl; /* 0x02C HASHTABLE_CTRL - Hash table control register */ - volatile uint32_t mdio_cfg_status; /* 0x030 */ - volatile uint32_t mdio_command; /* 0x034 */ - volatile uint32_t mdio_data; /* 0x038 */ - volatile uint32_t mdio_regaddr; /* 0x03c */ - volatile uint32_t status; /* 0x040 */ - volatile uint32_t tx_ipg_len; /* 0x044 TX_IPG_LENGTH - Transmitter inter-packet-gap register */ - volatile uint32_t mac_addr_2; /* 0x048 MAC_ADDR_2 - Lower 32 bits of the second 48-bit MAC address */ - volatile uint32_t mac_addr_3; /* 0x04C MAC_ADDR_3 - Upper 16 bits of the second 48-bit MAC address */ - volatile uint32_t rx_fifo_ptr_rd; /* 0x050 */ - volatile uint32_t rx_fifo_ptr_wr; /* 0x054 */ - volatile uint32_t tx_fifo_ptr_rd; /* 0x058 */ - volatile uint32_t tx_fifo_ptr_wr; /* 0x05c */ - volatile uint32_t imask; /* 0x060 IMASK - Interrupt mask register */ - volatile uint32_t ievent; /* 0x064 IEVENT - Interrupt event register */ - volatile uint32_t udp_port; /* 0x068 Defines a UDP Port number. When an UDP/IP frame is received with a matching UDP destination port, the receive status indication pin ff_rx_ts_frm will be asserted.*/ - volatile uint32_t type_1588v2; /* 0x06c Type field for 1588v2 layer 2 frames. IEEE1588 defines the type 0x88f7 for 1588 frames. */ - volatile uint32_t TENGEC_RESERVED4[4]; -/*10Ge Statistics Counter */ - volatile uint64_t TFRM; /* 80 aFramesTransmittedOK */ - volatile uint64_t RFRM; /* 88 aFramesReceivedOK */ - volatile uint64_t RFCS; /* 90 aFrameCheckSequenceErrors */ - volatile uint64_t RALN; /* 98 aAlignmentErrors */ - volatile uint64_t TXPF; /* A0 aPAUSEMACCtrlFramesTransmitted */ - volatile uint64_t RXPF; /* A8 aPAUSEMACCtrlFramesReceived */ - volatile uint64_t RLONG; /* B0 aFrameTooLongErrors */ - volatile uint64_t RFLR; /* B8 aInRangeLengthErrors */ - volatile uint64_t TVLAN; /* C0 VLANTransmittedOK */ - volatile uint64_t RVLAN; /* C8 VLANReceivedOK */ - volatile uint64_t TOCT; /* D0 ifOutOctets */ - volatile uint64_t ROCT; /* D8 ifInOctets */ - volatile uint64_t RUCA; /* E0 ifInUcastPkts */ - volatile uint64_t RMCA; /* E8 ifInMulticastPkts */ - volatile uint64_t RBCA; /* F0 ifInBroadcastPkts */ - volatile uint64_t TERR; /* F8 ifOutErrors */ - volatile uint32_t TENGEC_RESERVED6[2]; - volatile uint64_t TUCA; /* 108 ifOutUcastPkts */ - volatile uint64_t TMCA; /* 110 ifOutMulticastPkts */ - volatile uint64_t TBCA; /* 118 ifOutBroadcastPkts */ - volatile uint64_t RDRP; /* 120 etherStatsDropEvents */ - volatile uint64_t REOCT; /* 128 etherStatsOctets */ - volatile uint64_t RPKT; /* 130 etherStatsPkts */ - volatile uint64_t TRUND; /* 138 etherStatsUndersizePkts */ - volatile uint64_t R64; /* 140 etherStatsPkts64Octets */ - volatile uint64_t R127; /* 148 etherStatsPkts65to127Octets */ - volatile uint64_t R255; /* 150 etherStatsPkts128to255Octets */ - volatile uint64_t R511; /* 158 etherStatsPkts256to511Octets */ - volatile uint64_t R1023; /* 160 etherStatsPkts512to1023Octets */ - volatile uint64_t R1518; /* 168 etherStatsPkts1024to1518Octets */ - volatile uint64_t R1519X; /* 170 etherStatsPkts1519toX */ - volatile uint64_t TROVR; /* 178 etherStatsOversizePkts */ - volatile uint64_t TRJBR; /* 180 etherStatsJabbers */ - volatile uint64_t TRFRG; /* 188 etherStatsFragments */ - volatile uint64_t RERR; /* 190 ifInErrors */ -} _PackedType t_TgecMemMap; - -#define MEM_MAP_END -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(pop) -#endif /* defined(__MWERKS__) && ... */ - - -typedef struct { - bool wanModeEnable; /* WAN Mode Enable. Sets WAN mode (1) or LAN mode (0, default) of operation. */ - bool promiscuousModeEnable; /* Enables MAC promiscuous operation. When set to '1', all frames are received without any MAC address filtering, when set to '0' (Reset value) Unicast Frames with a destination address not matching the Core MAC Address (MAC Address programmed in Registers MAC_ADDR_0 and MAC_ADDR_1 or the MAC address programmed in Registers MAC_ADDR_2 and MAC_ADDR_3 ) are rejected. */ - bool pauseForwardEnable; /* Terminate / Forward Pause Frames. If set to '1' pause frames are forwarded to the user application. When set to '0' (Reset value) pause frames are terminated and discarded within the MAC. */ - bool pauseIgnore; /* Ignore Pause Frame Quanta. If set to '1' received pause frames are ignored by the MAC. When set to '0' (Reset value) the transmit process is stopped for the amount of time specified in the pause quanta received within a pause frame. */ - bool txAddrInsEnable; /* Set Source MAC Address on Transmit. - If set to '1' the MAC overwrites the source MAC address received from the Client Interface with one of the MAC addresses (Refer to section 10.4) - If set to '0' (Reset value), the source MAC address from the Client Interface is transmitted unmodified to the line. */ - bool loopbackEnable; /* PHY Interface Loopback. When set to '1', the signal loop_ena is set to '1', when set to '0' (Reset value) the signal loop_ena is set to '0'. */ - bool cmdFrameEnable; /* Enables reception of all command frames. When set to '1' all Command Frames are accepted, when set to '0' (Reset Value) only Pause Frames are accepted and all other Command Frames are rejected. */ - bool rxErrorDiscard; /* Receive Errored Frame Discard Enable. When set to ‘1’, any frame received with an error is discarded in the Core and not forwarded to the Client interface. When set to ‘0’ (Reset value), errored Frames are forwarded to the Client interface with ff_rx_err asserted. */ - bool phyTxenaOn; /* PHY Transmit Enable. When set to '1', the signal phy_txena is set to '1', when set to '0' (Reset value) the signal phy_txena is set to '0' */ - bool sendIdleEnable; /* Force Idle Generation. When set to '1', the MAC permanently sends XGMII Idle sequences even when faults are received. */ - bool noLengthCheckEnable; /* Payload Length Check Disable. When set to ‘0’ (Reset value), the Core checks the frame's payload length with the Frame Length/Type field, when set to ‘1’, the payload length check is disabled. */ - bool lgthCheckNostdr; /* The Core interprets the Length/Type field differently depending on the value of this Bit */ - bool timeStampEnable; /* This bit selects between enabling and disabling the IEEE 1588 functionality. - 1: IEEE 1588 is enabled. - 0: IEEE 1588 is disabled. */ - bool rxSfdAny; /* Enables, when set, that any character is allowed at the SFD position of the preamble and the frame will be accepted. - If cleared (default) the frame is accepted only if the 8th byte of the preamble contains the SFD value 0xd5. If another value is received, the frame is discarded and the alignment error counter increments. */ - bool rxPblFwd; /* Receive Preamble Forwarding (custom preamble). - If set, the first word (ff_rx_sop) of every received frame contains the preamble of the frame. The frame data starts with the 2nd word from the FIFO. - If the bit is cleared (default) the preamble is removed from the frame before it is written into the receive FIFO. */ - bool txPblFwd; /* Transmit Preamble Forwarding (custom preamble). - If set, the first word written into the TX FIFO is considered as frame preamble. The MAC will not add a preamble in front of the frame. Note that bits 7:0 of the preamble word will still be overwritten with the XGMII start character upon transmission. - If cleared (default) the MAC */ - uint32_t txIpgLength; /*Transmit Inter-Packet-Gap (IPG) value. - A 6-bit value: Depending on LAN or WAN mode of operation (see COMMAND_CONFIG, 19.2.1 page 91) the value has the following meaning: - - LAN Mode: Number of octets in steps of 4. Valid values are 8, 12, 16, ... 100. DIC is fully supported (see 10.6.1 page 49) for any setting. A default of 12 (reset value) must be set to conform to IEEE802.3ae. Warning: When set to 8, PCS layers may not be able to perform clock rate compensation. - - WAN Mode: Stretch factor. Valid values are 4..15. The stretch factor is calculated as (value+1)*8. A default of 12 (reset value) must be set to conform to IEEE 802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). */ -/*.. */ - uint16_t maxFrameLength; - bool debugMode; - uint16_t pauseTime; -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 - bool skipFman11Workaround; -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -} t_TgecDriverParam; typedef struct { t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */ t_Handle h_App; /**< Handle to the upper layer application */ - t_TgecMemMap *p_MemMap; /**< pointer to 10G memory mapped registers. */ + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */ t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */ uint64_t addr; /**< MAC address of device; */ e_EnetMode enetMode; /**< Ethernet physical interface */ @@ -471,7 +140,7 @@ typedef struct { bool debugMode; uint8_t macId; uint32_t exceptions; - t_TgecDriverParam *p_TgecDriverParam; + struct tgec_cfg *p_TgecDriverParam; } t_Tgec; diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c index c9753be15069..e0fafd1d174d 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,12 +31,15 @@ */ + #include "error_ext.h" #include "std_ext.h" #include "fm_mac.h" #include "tgec.h" #include "xx_ext.h" +#include "fm_common.h" + /*****************************************************************************/ t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, @@ -46,12 +49,20 @@ t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, { t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; t_TgecMiiAccessMemMap *p_MiiAccess; + uint32_t cfgStatusReg; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE); p_MiiAccess = p_Tgec->p_MiiMemMap; + /* Configure MII */ + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); + cfgStatusReg &= ~MIIMCOM_DIV_MASK; + /* (one half of fm clock => 2.5Mhz) */ + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT); + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg); + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) XX_UDelay (1); @@ -82,13 +93,20 @@ t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, { t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; t_TgecMiiAccessMemMap *p_MiiAccess; - uint32_t cfg_status; + uint32_t cfgStatusReg; SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE); p_MiiAccess = p_Tgec->p_MiiMemMap; + /* Configure MII */ + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); + cfgStatusReg &= ~MIIMCOM_DIV_MASK; + /* (one half of fm clock => 2.5Mhz) */ + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT); + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg); + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) XX_UDelay (1); @@ -110,12 +128,12 @@ t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data); - cfg_status = GET_UINT32(p_MiiAccess->mdio_cfg_status); + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); - if (cfg_status & MIIMIND_READ_ERROR) + if (cfgStatusReg & MIIMIND_READ_ERROR) RETURN_ERROR(MINOR, E_INVALID_VALUE, - ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfg_status 0x%x", - ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfg_status)); + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x", + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg)); return E_OK; } diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h index 81fd6efdf045..645cdde57973 100644 --- a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h +++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __TGEC_MII_ACC_H #define __TGEC_MII_ACC_H @@ -59,7 +60,6 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START /*----------------------------------------------------*/ /* MII Configuration Control Memory Map Registers */ @@ -72,7 +72,6 @@ typedef _Packed struct t_TgecMiiAccessMemMap volatile uint32_t mdio_regaddr; /* 0x03c */ } _PackedType t_TgecMiiAccessMemMap ; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.c b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.c new file mode 100644 index 000000000000..0a1b31f11d5f --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.c @@ -0,0 +1,237 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ +/****************************************************************************** + + @File fm_macsec.c + + @Description FM MACSEC driver routines implementation. +*//***************************************************************************/ + +#include "std_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "string_ext.h" +#include "sprint_ext.h" +#include "debug_ext.h" + +#include "fm_macsec.h" + + +/****************************************/ +/* API Init unit functions */ +/****************************************/ +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver; + + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL); + + if (p_FmMacsecParam->guestMode) + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam); + else + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam); + + if (!p_FmMacsecControllerDriver) + return NULL; + + return (t_Handle)p_FmMacsecControllerDriver; +} + +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init) + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free) + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException) + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision) + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + + +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable) + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable) + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) +{ + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); + + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException) + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable); + + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.h b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.h new file mode 100644 index 000000000000..fbe51875f92f --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec.h @@ -0,0 +1,203 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec.h + + @Description FM MACSEC internal structures and definitions. +*//***************************************************************************/ +#ifndef __FM_MACSEC_H +#define __FM_MACSEC_H + +#include "error_ext.h" +#include "std_ext.h" +#include "fm_macsec_ext.h" + +#include "fm_common.h" + + +#define __ERR_MODULE__ MODULE_FM_MACSEC + + +typedef struct +{ + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec); + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec); + + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode); + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled); + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode); + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr); + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec); + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec); + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); + + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision); + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec); + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec); + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); + +} t_FmMacsecControllerDriver; + +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam); +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams); + +/***********************************************************************/ +/* MACSEC internal routines */ +/***********************************************************************/ + +/**************************************************************************//** + + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit + + @Description FM MACSEC Inter Module functions - + These are not User API routines but routines that may be called + from other modules. This will be the case in a single core environment, + where instead of using the XX messaging mechanism, the routines may be + called from other modules. In a multicore environment, the other modules may + be run by other cores and therefore these routines may not be called directly. + + @{ +*//***************************************************************************/ + +#define MAX_NUM_OF_SA_PER_SC 4 + +typedef enum +{ + e_SC_RX = 0, + e_SC_TX +} e_ScType; + +typedef enum +{ + e_SC_SA_A = 0, + e_SC_SA_B , + e_SC_SA_C , + e_SC_SA_D +} e_ScSaId; + +typedef struct +{ + uint32_t scId; + macsecSCI_t sci; + bool replayProtect; + uint32_t replayWindow; + e_FmMacsecValidFrameBehavior validateFrames; + uint16_t confidentialityOffset; + e_FmMacsecSecYCipherSuite cipherSuite; +} t_RxScParams; + +typedef struct +{ + uint32_t scId; + macsecSCI_t sci; + bool protectFrames; + e_FmMacsecSciInsertionMode sciInsertionMode; + bool confidentialityEnable; + uint16_t confidentialityOffset; + e_FmMacsecSecYCipherSuite cipherSuite; +} t_TxScParams; + +typedef enum e_FmMacsecGlobalExceptions { + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */ + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */ +} e_FmMacsecGlobalExceptions; + +typedef enum e_FmMacsecGlobalEvents { + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */ +} e_FmMacsecGlobalEvents; + +/**************************************************************************//** + @Description Enum for inter-module interrupts registration +*//***************************************************************************/ +typedef enum e_FmMacsecEventModules{ + e_FM_MACSEC_MOD_SC_TX, + e_FM_MACSEC_MOD_DUMMY_LAST +} e_FmMacsecEventModules; + +typedef enum e_FmMacsecInterModuleEvent { + e_FM_MACSEC_EV_SC_TX, + e_FM_MACSEC_EV_ERR_SC_TX, + e_FM_MACSEC_EV_DUMMY_LAST +} e_FmMacsecInterModuleEvent; + +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2) + +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \ + switch(mod){ \ + case e_FM_MACSEC_MOD_SC_TX: \ + event = (intrType == e_FM_INTR_TYPE_ERR) ? \ + e_FM_MACSEC_EV_ERR_SC_TX: \ + e_FM_MACSEC_EV_SC_TX; \ + event += (uint8_t)(2 * id);break; \ + break; \ + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \ + break;} + +void FmMacsecRegisterIntr(t_Handle h_FmMacsec, + e_FmMacsecEventModules module, + uint8_t modId, + e_FmIntrType intrType, + void (*f_Isr) (t_Handle h_Arg, uint32_t id), + t_Handle h_Arg); + +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec, + e_FmMacsecEventModules module, + uint8_t modId, + e_FmIntrType intrType); + +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds); +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds); +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams); +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId); +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams); +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId); +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key); +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key); +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId); +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId); +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive); +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN); +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN); +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an); +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An); +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable); + +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable); +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable); + + + +#endif /* __FM_MACSEC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_guest.c b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_guest.c new file mode 100644 index 000000000000..31d789d042a7 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_guest.c @@ -0,0 +1,59 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec.c + + @Description FM MACSEC driver routines implementation. +*//***************************************************************************/ + +#include "std_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "string_ext.h" +#include "sprint_ext.h" +#include "debug_ext.h" +#include "fm_macsec.h" + + +/****************************************/ +/* static functions */ +/****************************************/ + +/****************************************/ +/* API Init unit functions */ +/****************************************/ +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam) +{ + UNUSED(p_FmMacsecParam); + return NULL; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.c b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.c new file mode 100644 index 000000000000..623612aca2d0 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.c @@ -0,0 +1,1031 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec.c + + @Description FM MACSEC driver routines implementation. +*//***************************************************************************/ + +#include "std_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "string_ext.h" +#include "sprint_ext.h" +#include "fm_mac_ext.h" + +#include "fm_macsec_master.h" + + +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac); + + +/****************************************/ +/* static functions */ +/****************************************/ +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec) +{ + if (!p_FmMacsec->f_Exception) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); + + return E_OK; +} + +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id) +{ + UNUSED(h_Arg); UNUSED(id); + + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!")); +} + +static void MacsecEventIsr(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t events,event,i; + + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); + + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr); + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events); + + for (i=0; iintrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i); + } +} + +static void MacsecErrorIsr(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t errors,error,i; + + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); + + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err); + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors); + + for (i=0; iintrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i); + } + + if (errors & FM_MACSEC_EX_ECC) + { + uint8_t eccType; + uint32_t tmpReg; + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec); + ASSERT_COND(tmpReg & MECC_CAP); + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT); + + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC)) + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC); + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC)) + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC); + else + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg); + } +} + +static t_Error MacsecInit(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL; + uint32_t tmpReg,i,macId; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters); + + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam; + + for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; + + tmpReg = 0; + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)| + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) | + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) | + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) | + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) | + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) | + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) | + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) | + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg); + + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac); + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL. + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */ + tmpReg -= p_FmMacsecDriverParam->mflSubtract; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr); + + if (!p_FmMacsec->userExceptions) + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); + + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC; + if (p_FmMacsecDriverParam->reservedSc0) + p_FmMacsec->numRxScAvailable --; + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC; + + XX_Free(p_FmMacsecDriverParam); + p_FmMacsec->p_FmMacsecDriverParam = NULL; + + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId); + FmRegisterIntr(p_FmMacsec->h_Fm, + e_FM_MOD_MACSEC, + (uint8_t)macId, + e_FM_INTR_TYPE_NORMAL, + MacsecEventIsr, + p_FmMacsec); + + FmRegisterIntr(p_FmMacsec->h_Fm, + e_FM_MOD_MACSEC, + 0, + e_FM_INTR_TYPE_ERR, + MacsecErrorIsr, + p_FmMacsec); + + return E_OK; +} + +static t_Error MacsecFree(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t macId; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId); + FmUnregisterIntr(p_FmMacsec->h_Fm, + e_FM_MOD_MACSEC, + (uint8_t)macId, + e_FM_INTR_TYPE_NORMAL); + + FmUnregisterIntr(p_FmMacsec->h_Fm, + e_FM_MOD_MACSEC, + 0, + e_FM_INTR_TYPE_ERR); + + if (p_FmMacsec->rxScSpinLock) + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock); + if (p_FmMacsec->txScSpinLock) + XX_FreeSpinlock(p_FmMacsec->txScSpinLock); + + XX_Free(p_FmMacsec); + + return E_OK; +} + +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode; + + return E_OK; +} + +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled; + + return E_OK; +} + +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled; + + return E_OK; +} + +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled; + + return E_OK; +} + +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled; + + return E_OK; +} + +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode; + + return E_OK; +} + +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr; + + return E_OK; +} + +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE; + + return E_OK; +} + +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE; + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE; + + return E_OK; +} + +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + GET_USER_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_FmMacsec->userExceptions |= bitMask; + else + p_FmMacsec->userExceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1); + + return E_OK; +} + +static t_Error MacsecEnable(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t tmpReg; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg); + tmpReg |= CFG_BYPN; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg); + + return E_OK; +} + +static t_Error MacsecDisable(t_Handle h_FmMacsec) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t tmpReg; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg); + tmpReg &= ~CFG_BYPN; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg); + + return E_OK; +} + +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t bitMask; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + GET_USER_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_FmMacsec->userExceptions |= bitMask; + else + p_FmMacsec->userExceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + if (!p_FmMacsec->userExceptions) + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC; + else + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); + + return E_OK; +} + +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver) +{ + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit; + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI; + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException; + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision; + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable; + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable; + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException; +} + +/****************************************/ +/* Inter-Module functions */ +/****************************************/ + +void FmMacsecRegisterIntr(t_Handle h_FmMacsec, + e_FmMacsecEventModules module, + uint8_t modId, + e_FmIntrType intrType, + void (*f_Isr) (t_Handle h_Arg, uint32_t id), + t_Handle h_Arg) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint8_t event= 0; + + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); + + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event); + + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST); + p_FmMacsec->intrMng[event].f_Isr = f_Isr; + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg; +} + +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec, + e_FmMacsecEventModules module, + uint8_t modId, + e_FmIntrType intrType) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint8_t event= 0; + + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); + + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event); + + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST); + p_FmMacsec->intrMng[event].f_Isr = NULL; + p_FmMacsec->intrMng[event].h_SrcHandle = NULL; +} + +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + bool *p_ScTable; + uint32_t *p_ScAvailable,i; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE); + + if (type == e_SC_RX) + { + p_ScTable = (bool *)p_FmMacsec->rxScTable; + p_ScAvailable = &p_FmMacsec->numRxScAvailable; + i = (NUM_OF_RX_SC - 1); + } + else + { + p_ScTable = (bool *)p_FmMacsec->txScTable; + p_ScAvailable = &p_FmMacsec->numTxScAvailable; + i = (NUM_OF_TX_SC - 1); + + } + if (*p_ScAvailable < numOfScs) + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available")); + + if (isPtp) + { + i = 0; + if (p_ScTable[i]) + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available")); + } + + for (;numOfScs;i--) + { + if (p_ScTable[i]) + continue; + numOfScs --; + (*p_ScAvailable)--; + p_ScIds[numOfScs] = i; + p_ScTable[i] = TRUE; + } + + return err; +} + +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + bool *p_ScTable; + uint32_t *p_ScAvailable,maxNumOfSc,i; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE); + + if (type == e_SC_RX) + { + p_ScTable = (bool *)p_FmMacsec->rxScTable; + p_ScAvailable = &p_FmMacsec->numRxScAvailable; + maxNumOfSc = NUM_OF_RX_SC; + } + else + { + p_ScTable = (bool *)p_FmMacsec->txScTable; + p_ScAvailable = &p_FmMacsec->numTxScAvailable; + maxNumOfSc = NUM_OF_TX_SC; + } + + if ((*p_ScAvailable + numOfScs) > maxNumOfSc) + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs")); + + for (i=0;ip_FmMacsecRegs->cfg); + if (enable && (tmpReg & CFG_S0I)) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode")); + + if (enable) + tmpReg |= CFG_S0I; + else + tmpReg &= ~CFG_S0I; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg); + + return E_OK; +} + +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId); + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg); + if (tmpReg & RX_SCCFG_SCI_EN_MASK) + { + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId)); + } + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci)); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci)); + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK); + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK); + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK); + tmpReg |= RX_SCCFG_SCI_EN_MASK; + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + tmpReg &= ~RX_SCCFG_SCI_EN_MASK; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId); + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); + if (tmpReg & TX_SCCFG_SCE_MASK) + { + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId)); + } + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci)); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci)); + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG); + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA); + + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK); + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK); + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK); + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK); + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK); + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK); + tmpReg |= TX_SCCFG_SCE_MASK; + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + tmpReg &= ~TX_SCCFG_SCE_MASK; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn); + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t)); + + tmpReg |= RX_SACFG_ACTIVE; + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn); + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t)); + + tmpReg |= TX_SACFG_ACTIVE; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, i, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0); + for (i=0; i<4; i++) + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0); + + tmpReg |= RX_SACFG_ACTIVE; + tmpReg &= ~RX_SACFG_EN_MASK; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, i, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0); + for (i=0; i<4; i++) + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0); + + tmpReg |= TX_SACFG_ACTIVE; + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs); + if (enableReceive) + tmpReg |= RX_SACFG_EN_MASK; + else + tmpReg &= ~RX_SACFG_EN_MASK; + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN); + + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); + + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK); + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + return err; +} + +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + t_Error err = E_OK; + uint32_t tmpReg = 0, intFlags; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE); + + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); + + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); + + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); + + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT); + + return err; +} + +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t bitMask; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + GET_EXCEPTION_FLAG(bitMask, exception, scId); + if (bitMask) + { + if (enable) + p_FmMacsec->exceptions |= bitMask; + else + p_FmMacsec->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); + + return E_OK; +} + +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable) +{ + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; + uint32_t bitMask; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); + + GET_EVENT_FLAG(bitMask, event, scId); + if (bitMask) + { + if (enable) + p_FmMacsec->events |= bitMask; + else + p_FmMacsec->events &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event")); + + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events); + + return E_OK; +} + +/****************************************/ +/* API Init unit functions */ +/****************************************/ +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam) +{ + t_FmMacsec *p_FmMacsec; + uint32_t macId; + + /* Allocate FM MACSEC structure */ + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec)); + if (!p_FmMacsec) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure")); + return NULL; + } + memset(p_FmMacsec, 0, sizeof(t_FmMacsec)); + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver); + + /* Allocate the FM MACSEC driver's parameters structure */ + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam)); + if (!p_FmMacsec->p_FmMacsecDriverParam) + { + XX_Free(p_FmMacsec); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters")); + return NULL; + } + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam)); + + /* Initialize FM MACSEC parameters which will be kept by the driver */ + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm; + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac; + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr); + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception; + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App; + p_FmMacsec->userExceptions = DEFAULT_userExceptions; + p_FmMacsec->exceptions = DEFAULT_exceptions; + p_FmMacsec->events = DEFAULT_events; + p_FmMacsec->rxScSpinLock = XX_InitSpinlock(); + p_FmMacsec->txScSpinLock = XX_InitSpinlock(); + + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */ + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment; + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment; + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment; + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment; + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable; + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP; + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode; + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr; + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead; + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract; + /* build the FM MACSEC master IPC address */ + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE); + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId); + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master", + FmGetId(p_FmMacsec->h_Fm),macId) != 24) + { + XX_Free(p_FmMacsec->p_FmMacsecDriverParam); + XX_Free(p_FmMacsec); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); + return NULL; + } + return p_FmMacsec; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.h b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.h new file mode 100644 index 000000000000..2296a0f10d54 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_master.h @@ -0,0 +1,479 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec_master.h + + @Description FM MACSEC internal structures and definitions. +*//***************************************************************************/ +#ifndef __FM_MACSEC_MASTER_H +#define __FM_MACSEC_MASTER_H + +#include "error_ext.h" +#include "std_ext.h" + +#include "fm_macsec.h" + + +#define MACSEC_ICV_SIZE 16 +#define MACSEC_SECTAG_SIZE 16 +#define MACSEC_SCI_SIZE 8 +#define MACSEC_FCS_SIZE 4 + +/**************************************************************************//** + @Description Exceptions +*//***************************************************************************/ + +#define FM_MACSEC_EX_TX_SC_0 0x80000000 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc)) +#define FM_MACSEC_EX_ECC 0x00000001 + +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \ + case e_FM_MACSEC_EX_TX_SC: \ + bitMask = FM_MACSEC_EX_TX_SC(id); break; \ + case e_FM_MACSEC_EX_ECC: \ + bitMask = FM_MACSEC_EX_ECC; break; \ + default: bitMask = 0;break;} + +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000 + +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \ + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \ + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \ + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \ + default: bitMask = 0;break;} + +/**************************************************************************//** + @Description Events +*//***************************************************************************/ + +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc)) + +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \ + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \ + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \ + default: bitMask = 0;break;} + +/**************************************************************************//** + @Description Defaults +*//***************************************************************************/ +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\ + FM_MACSEC_USER_EX_MULTI_BIT_ECC) + +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\ + FM_MACSEC_EX_TX_SC(1) |\ + FM_MACSEC_EX_TX_SC(2) |\ + FM_MACSEC_EX_TX_SC(3) |\ + FM_MACSEC_EX_TX_SC(4) |\ + FM_MACSEC_EX_TX_SC(5) |\ + FM_MACSEC_EX_TX_SC(6) |\ + FM_MACSEC_EX_TX_SC(7) |\ + FM_MACSEC_EX_TX_SC(8) |\ + FM_MACSEC_EX_TX_SC(9) |\ + FM_MACSEC_EX_TX_SC(10) |\ + FM_MACSEC_EX_TX_SC(11) |\ + FM_MACSEC_EX_TX_SC(12) |\ + FM_MACSEC_EX_TX_SC(13) |\ + FM_MACSEC_EX_TX_SC(14) |\ + FM_MACSEC_EX_TX_SC(15) |\ + FM_MACSEC_EX_ECC ) + +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\ + FM_MACSEC_EV_TX_SC_NEXT_PN(15) ) + +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH +#define DEFAULT_invalidTagsFrameTreatment FALSE +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE +#define DEFAULT_keysUnreadable FALSE +#define DEFAULT_normalMode TRUE +#define DEFAULT_sc0ReservedForPTP FALSE +#define DEFAULT_initNextPn 1 +#define DEFAULT_pnExhThr 0xffffffff +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE) +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE + + +/**************************************************************************//** + @Description Memory Mapped Registers +*//***************************************************************************/ + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(push,1) +#endif /* defined(__MWERKS__) && ... */ + +typedef _Packed struct +{ + /* MACsec configuration */ + volatile uint32_t cfg; /**< MACsec configuration */ + volatile uint32_t et; /**< MACsec EtherType */ + volatile uint8_t res1[56]; /**< reserved */ + volatile uint32_t mfl; /**< Maximum Frame Length */ + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */ + volatile uint8_t res2[56]; /**< reserved */ + volatile uint32_t rxsca; /**< RX SC access select */ + volatile uint8_t res3[60]; /**< reserved */ + volatile uint32_t txsca; /**< TX SC access select */ + volatile uint8_t res4[60]; /**< reserved */ + + /* RX configuration, status and statistic */ + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */ + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */ + volatile uint8_t res5[8]; /**< reserved */ + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */ + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */ + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */ + volatile uint8_t res6[4]; /**< reserved */ + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */ + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */ + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */ + volatile uint32_t rpw; /**< replayWindow */ + volatile uint8_t res7[16]; /**< reserved */ + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */ + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */ + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */ + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */ + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */ + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */ + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */ + volatile uint8_t res8[4]; /**< reserved */ + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */ + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */ + _Packed struct + { + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */ + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */ + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */ + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */ + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */ + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */ + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */ + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */ + volatile uint8_t res9[8]; /**< reserved */ + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC]; + + /* TX configuration, status and statistic */ + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */ + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */ + volatile uint8_t res10[8]; /**< reserved */ + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */ + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */ + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */ + volatile uint32_t opus; /**< OutPktsUntagged Statistic */ + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */ + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */ + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */ + volatile uint32_t optls; /**< OutPktsTooLong Statistic */ + volatile uint8_t res11[16]; /**< reserved */ + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */ + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */ + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */ + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */ + volatile uint8_t res12[48]; /**< reserved */ + _Packed struct + { + volatile uint32_t txsacs; /**< TX Security Association configuration and status */ + volatile uint32_t txsanpn; /**< TX Security Association nextPN */ + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */ + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */ + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */ + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */ + volatile uint8_t res13[16]; /**< reserved */ + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC]; + volatile uint8_t res14[248]; /**< reserved */ + + /* Global configuration and status */ + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */ + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */ + volatile uint32_t evr; /**< MACsec Event Register */ + volatile uint32_t ever; /**< MACsec Event Enable Register */ + volatile uint32_t evfr; /**< MACsec Event Force Register */ + volatile uint32_t err; /**< MACsec Error Register */ + volatile uint32_t erer; /**< MACsec Error Enable Register */ + volatile uint32_t erfr; /**< MACsec Error Force Register */ + volatile uint8_t res15[40]; /**< reserved */ + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */ + volatile uint32_t idle; /**< MACsec Idle status Register */ + volatile uint8_t res16[184]; /**< reserved */ + /* DEBUG */ + volatile uint32_t rxec; /**< MACsec RX error capture Register */ + volatile uint8_t res17[28]; /**< reserved */ + volatile uint32_t txec; /**< MACsec TX error capture Register */ + volatile uint8_t res18[220]; /**< reserved */ + + /* Macsec Rx global statistic */ + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */ + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */ + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */ + volatile uint8_t res19[4]; /**< reserved */ + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */ + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */ + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */ + volatile uint8_t res20[4]; /**< reserved */ + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */ + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */ + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */ + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */ + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */ + volatile uint32_t ipkays; /**< InPktsKaY Statistic */ + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */ + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */ + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */ + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */ + volatile uint32_t iptls; /**< InPktsTooLong Statistic */ + volatile uint8_t res21[52]; /**< reserved */ + + /* Macsec Tx global statistic */ + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */ +#if (DPAA_VERSION >= 11) + volatile uint8_t res22[124]; /**< reserved */ + _Packed struct + { + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */ + volatile uint8_t res23[32]; /**< reserved */ + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC]; + _Packed struct + { + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */ + volatile uint8_t res24[32]; /**< reserved */ + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC]; +#endif /* (DPAA_VERSION >= 11) */ +} _PackedType t_FmMacsecRegs; + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(pop) +#endif /* defined(__MWERKS__) && ... */ + + +/**************************************************************************//** + @Description General defines +*//***************************************************************************/ + +#define SCI_HIGH_MASK 0xffffffff00000000LL +#define SCI_LOW_MASK 0x00000000ffffffffLL + +#define LONG_SHIFT 32 + +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT) +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK) + +/**************************************************************************//** + @Description Configuration defines +*//***************************************************************************/ + +/* masks */ +#define CFG_UECT 0x00000800 +#define CFG_ESCBT 0x00000400 +#define CFG_USFT 0x00000300 +#define CFG_ITT 0x00000080 +#define CFG_KFT 0x00000040 +#define CFG_UFT 0x00000030 +#define CFG_KSS 0x00000004 +#define CFG_BYPN 0x00000002 +#define CFG_S0I 0x00000001 + +#define ET_TYPE 0x0000ffff + +#define MFL_MAX_LEN 0x0000ffff + +#define RXSCA_SC_SEL 0x0000000f + +#define TXSCA_SC_SEL 0x0000000f + +#define IP_REV_1_IP_ID 0xffff0000 +#define IP_REV_1_IP_MJ 0x0000ff00 +#define IP_REV_1_IP_MM 0x000000ff + +#define IP_REV_2_IP_INT 0x00ff0000 +#define IP_REV_2_IP_ERR 0x0000ff00 +#define IP_REV_2_IP_CFG 0x000000ff + +#define MECC_CAP 0x80000000 +#define MECC_CET 0x40000000 +#define MECC_SERCNT 0x00ff0000 +#define MECC_MEMADDR 0x000001ff + +/* shifts */ +#define CFG_UECT_SHIFT (31-20) +#define CFG_ESCBT_SHIFT (31-21) +#define CFG_USFT_SHIFT (31-23) +#define CFG_ITT_SHIFT (31-24) +#define CFG_KFT_SHIFT (31-25) +#define CFG_UFT_SHIFT (31-27) +#define CFG_KSS_SHIFT (31-29) +#define CFG_BYPN_SHIFT (31-30) +#define CFG_S0I_SHIFT (31-31) + +#define IP_REV_1_IP_ID_SHIFT (31-15) +#define IP_REV_1_IP_MJ_SHIFT (31-23) +#define IP_REV_1_IP_MM_SHIFT (31-31) + +#define IP_REV_2_IP_INT_SHIFT (31-15) +#define IP_REV_2_IP_ERR_SHIFT (31-23) +#define IP_REV_2_IP_CFG_SHIFT (31-31) + +#define MECC_CAP_SHIFT (31-0) +#define MECC_CET_SHIFT (31-1) +#define MECC_SERCNT_SHIFT (31-15) +#define MECC_MEMADDR_SHIFT (31-31) + +/**************************************************************************//** + @Description RX SC defines +*//***************************************************************************/ + +/* masks */ +#define RX_SCCFG_SCI_EN_MASK 0x00000800 +#define RX_SCCFG_RP_MASK 0x00000400 +#define RX_SCCFG_VF_MASK 0x00000300 +#define RX_SCCFG_CO_MASK 0x0000003f + +/* shifts */ +#define RX_SCCFG_SCI_EN_SHIFT (31-20) +#define RX_SCCFG_RP_SHIFT (31-21) +#define RX_SCCFG_VF_SHIFT (31-23) +#define RX_SCCFG_CO_SHIFT (31-31) +#define RX_SCCFG_CS_SHIFT (31-7) + +/**************************************************************************//** + @Description RX SA defines +*//***************************************************************************/ + +/* masks */ +#define RX_SACFG_ACTIVE 0x80000000 +#define RX_SACFG_AN_MASK 0x00000006 +#define RX_SACFG_EN_MASK 0x00000001 + +/* shifts */ +#define RX_SACFG_AN_SHIFT (31-30) +#define RX_SACFG_EN_SHIFT (31-31) + +/**************************************************************************//** + @Description TX SC defines +*//***************************************************************************/ + +/* masks */ +#define TX_SCCFG_AN_MASK 0x000c0000 +#define TX_SCCFG_ASA_MASK 0x00020000 +#define TX_SCCFG_SCE_MASK 0x00010000 +#define TX_SCCFG_CO_MASK 0x00003f00 +#define TX_SCCFG_CE_MASK 0x00000010 +#define TX_SCCFG_PF_MASK 0x00000008 +#define TX_SCCFG_AIS_MASK 0x00000004 +#define TX_SCCFG_UES_MASK 0x00000002 +#define TX_SCCFG_USCB_MASK 0x00000001 + +/* shifts */ +#define TX_SCCFG_AN_SHIFT (31-13) +#define TX_SCCFG_ASA_SHIFT (31-14) +#define TX_SCCFG_SCE_SHIFT (31-15) +#define TX_SCCFG_CO_SHIFT (31-23) +#define TX_SCCFG_CE_SHIFT (31-27) +#define TX_SCCFG_PF_SHIFT (31-28) +#define TX_SCCFG_AIS_SHIFT (31-29) +#define TX_SCCFG_UES_SHIFT (31-30) +#define TX_SCCFG_USCB_SHIFT (31-31) +#define TX_SCCFG_CS_SHIFT (31-7) + +/**************************************************************************//** + @Description TX SA defines +*//***************************************************************************/ + +/* masks */ +#define TX_SACFG_ACTIVE 0x80000000 + + +typedef struct +{ + void (*f_Isr) (t_Handle h_Arg, uint32_t id); + t_Handle h_SrcHandle; +} t_FmMacsecIntrSrc; + +typedef struct +{ + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode; + bool invalidTagsDeliverUncontrolled; + bool changedTextWithNoEncryptDeliverUncontrolled; + bool onlyScbIsSetDeliverUncontrolled; + bool encryptWithNoChangedTextDiscardUncontrolled; + e_FmMacsecUntagFrameTreatment untagTreatMode; + uint32_t pnExhThr; + bool keysUnreadable; + bool byPassMode; + bool reservedSc0; + uint32_t sectagOverhead; + uint32_t mflSubtract; +} t_FmMacsecDriverParam; + +typedef struct +{ + t_FmMacsecControllerDriver fmMacsecControllerDriver; + t_Handle h_Fm; + t_FmMacsecRegs *p_FmMacsecRegs; + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */ + char fmMacsecModuleName[MODULE_NAME_SIZE]; + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS]; + uint32_t events; + uint32_t exceptions; + uint32_t userExceptions; + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */ + t_Handle h_App; /**< A handle to an application layer object; This handle will + be passed by the driver upon calling the above callbacks */ + bool rxScTable[NUM_OF_RX_SC]; + uint32_t numRxScAvailable; + bool txScTable[NUM_OF_TX_SC]; + uint32_t numTxScAvailable; + t_Handle rxScSpinLock; + t_Handle txScSpinLock; + t_FmMacsecDriverParam *p_FmMacsecDriverParam; +} t_FmMacsec; + + +#endif /* __FM_MACSEC_MASTER_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.c b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.c new file mode 100644 index 000000000000..7c72dc98e7f1 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.c @@ -0,0 +1,883 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec_secy.c + + @Description FM MACSEC SECY driver routines implementation. +*//***************************************************************************/ + +#include "std_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "string_ext.h" +#include "sprint_ext.h" + +#include "fm_macsec_secy.h" + + +/****************************************/ +/* static functions */ +/****************************************/ +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + UNUSED(id); + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE); + + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED); +} + +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + UNUSED(id); + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE); + + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN); +} + +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY) +{ + if (!p_FmMacsecSecY->f_Exception) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); + + if (!p_FmMacsecSecY->f_Event) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided")); + + if (!p_FmMacsecSecY->numOfRxSc) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'")); + + + return E_OK; +} + +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY, + macsecSCI_t sci, + e_FmMacsecSecYCipherSuite cipherSuite, + e_ScType type) +{ + t_SecYSc *p_ScTable; + void *p_Params; + uint32_t numOfSc,i; + t_Error err = E_OK; + t_RxScParams rxScParams; + t_TxScParams txScParams; + + ASSERT_COND(p_FmMacsecSecY); + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec); + + if (type == e_SC_RX) + { + memset(&rxScParams, 0, sizeof(rxScParams)); + i = (NUM_OF_RX_SC - 1); + p_ScTable = p_FmMacsecSecY->p_RxSc; + numOfSc = p_FmMacsecSecY->numOfRxSc; + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset; + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect; + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow; + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames; + rxScParams.cipherSuite = cipherSuite; + p_Params = &rxScParams; + } + else + { + memset(&txScParams, 0, sizeof(txScParams)); + i = (NUM_OF_TX_SC - 1); + p_ScTable = p_FmMacsecSecY->p_TxSc; + numOfSc = p_FmMacsecSecY->numOfTxSc; + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode; + txScParams.protectFrames = p_FmMacsecSecY->protectFrames; + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable; + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset; + txScParams.cipherSuite = cipherSuite; + p_Params = &txScParams; + } + + for (i=0;iscId = p_ScTable[i].scId; + ((t_RxScParams *)p_Params)->sci = sci; + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC")); + return NULL; + } + } + else + { + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId; + ((t_TxScParams *)p_Params)->sci = sci; + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC")); + return NULL; + } + } + + p_ScTable[i].inUse = TRUE; + return &p_ScTable[i]; +} + +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type) +{ + t_Error err = E_OK; + + ASSERT_COND(p_FmMacsecSecY); + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec); + ASSERT_COND(p_FmSecYSc); + + if (type == e_SC_RX) + { + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + } + else + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->inUse = FALSE; + + return err; +} + +/****************************************/ +/* API Init unit functions */ +/****************************************/ +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam) +{ + t_FmMacsecSecY *p_FmMacsecSecY; + + /* Allocate FM MACSEC structure */ + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY)); + if (!p_FmMacsecSecY) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure")); + return NULL; + } + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY)); + + /* Allocate the FM MACSEC driver's parameters structure */ + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam)); + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam) + { + XX_Free(p_FmMacsecSecY); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters")); + return NULL; + } + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam)); + + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */ + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec; + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event; + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception; + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App; + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable; + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset; + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames; + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable; + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow; + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames; + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode; + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp; + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels; + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc; + p_FmMacsecSecY->exceptions = DEFAULT_exceptions; + p_FmMacsecSecY->events = DEFAULT_events; + + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams, + &p_FmMacsecSecYParam->txScParams, + sizeof(t_FmMacsecSecYSCParams)); + return p_FmMacsecSecY; +} + +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL; + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE); + + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters); + + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam; + + if ((p_FmMacsecSecY->isPointToPoint) && + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK)) + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point")); + + /* Rx Sc Allocation */ + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc); + if (!p_FmMacsecSecY->p_RxSc) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC")); + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc); + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK) + { + if (p_FmMacsecSecY->p_TxSc) + XX_Free(p_FmMacsecSecY->p_TxSc); + if (p_FmMacsecSecY->p_RxSc) + XX_Free(p_FmMacsecSecY->p_RxSc); + return ERROR_CODE(err); + } + for (i=0; inumOfRxSc; i++) + { + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i]; + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX; + for (j=0; jp_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE; + } + + /* Tx Sc Allocation */ + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc); + if (!p_FmMacsecSecY->p_TxSc) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC")); + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc); + + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK) + { + if (p_FmMacsecSecY->p_TxSc) + XX_Free(p_FmMacsecSecY->p_TxSc); + if (p_FmMacsecSecY->p_RxSc) + XX_Free(p_FmMacsecSecY->p_RxSc); + return ERROR_CODE(err); + } + for (i=0; inumOfTxSc; i++) + { + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i]; + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX; + for (j=0; jp_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE; + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec, + e_FM_MACSEC_MOD_SC_TX, + (uint8_t)txScIds[i], + e_FM_INTR_TYPE_ERR, + FmMacsecSecYExceptionsIsr, + p_FmMacsecSecY); + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec, + e_FM_MACSEC_MOD_SC_TX, + (uint8_t)txScIds[i], + e_FM_INTR_TYPE_NORMAL, + FmMacsecSecYEventsIsr, + p_FmMacsecSecY); + + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE); + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE); + } + + FmMacsecSecYCreateSc(p_FmMacsecSecY, + p_FmMacsecSecYDriverParam->txScParams.sci, + p_FmMacsecSecYDriverParam->txScParams.cipherSuite, + e_SC_TX); + XX_Free(p_FmMacsecSecYDriverParam); + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_Error err = E_OK; + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + if (p_FmMacsecSecY->isPointToPoint) + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE); + if (p_FmMacsecSecY->p_RxSc) + { + for (i=0; inumOfRxSc; i++) + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId; + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK) + return ERROR_CODE(err); + XX_Free(p_FmMacsecSecY->p_RxSc); + } + if (p_FmMacsecSecY->p_TxSc) + { + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX); + + for (i=0; inumOfTxSc; i++) { + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId; + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec, + e_FM_MACSEC_MOD_SC_TX, + (uint8_t)txScIds[i], + e_FM_INTR_TYPE_ERR); + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec, + e_FM_MACSEC_MOD_SC_TX, + (uint8_t)txScIds[i], + e_FM_INTR_TYPE_NORMAL); + + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE); + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE); + } + + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK) + return ERROR_CODE(err); + XX_Free(p_FmMacsecSecY->p_TxSc); + } + + XX_Free(p_FmMacsecSecY); + + return err; +} + +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->protectFrames = protectFrames; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->replayProtect = replayProtect; + p_FmMacsecSecY->replayWindow = replayWindow; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->validateFrames = validateFrames; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable; + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + p_FmMacsecSecY->numOfRxSc = 1; + p_FmMacsecSecY->isPointToPoint = TRUE; + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP; + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + GET_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_FmMacsecSecY->exceptions |= bitMask; + else + p_FmMacsecSecY->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + + GET_EVENT_FLAG(bitMask, event); + if (bitMask) + { + if (enable) + p_FmMacsecSecY->events |= bitMask; + else + p_FmMacsecSecY->events &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event")); + + return E_OK; +} + +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL); + + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX); +} + +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX); +} + +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an)); + + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++; + return err; +} + +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an)); + + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->numOfSa--; + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE; + /* TODO - check if statistics need to be read*/ + return err; +} + +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->sa[an].active = TRUE; + return err; +} + +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->sa[an].active = FALSE; + return err; +} + +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return err; +} + +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return err; +} + +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if (p_FmSecYSc->sa[an].active) + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + /* TODO - statistics should be read */ + + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + if (p_FmSecYSc->sa[an].active) + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return err; +} + + +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an)); + + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++; + return err; +} + +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an)); + + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + p_FmSecYSc->numOfSa--; + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE; + /* TODO - check if statistics need to be read*/ + return err; +} + +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + macsecAN_t currentAn; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec, + p_FmSecYSc->scId, + ¤tAn)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec, + p_FmSecYSc->scId, + p_FmSecYSc->sa[nextActiveAn].saId, + nextActiveAn)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + /* TODO - statistics should be read */ + + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return err; +} + +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); + + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); + + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec, + p_FmSecYSc->scId, + p_FmSecYSc->sa[an].saId, + an)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return err; +} + +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE); + + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec, + p_FmSecYSc->scId, + p_An)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + + return err; +} + +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId) +{ + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); +#ifdef DISABLE_SANITY_CHECKS + UNUSED(h_FmMacsecSecY); +#endif /* DISABLE_SANITY_CHECKS */ + + *p_ScPhysId = p_FmSecYSc->scId; + return err; +} + +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId) +{ + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; + t_SecYSc *p_FmSecYSc; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); + + *p_ScPhysId = p_FmSecYSc->scId; + return err; +} + +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable) +{ + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable) +{ + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics) +{ + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics) +{ + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics) +{ + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics) +{ + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics) +{ + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics); + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); +} + diff --git a/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.h b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.h new file mode 100644 index 000000000000..0cf624e68e2a --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/MACSEC/fm_macsec_secy.h @@ -0,0 +1,144 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/****************************************************************************** + @File fm_macsec_secy.h + + @Description FM MACSEC SecY internal structures and definitions. +*//***************************************************************************/ +#ifndef __FM_MACSEC_SECY_H +#define __FM_MACSEC_SECY_H + +#include "error_ext.h" +#include "std_ext.h" + +#include "fm_macsec.h" + + +/**************************************************************************//** + @Description Exceptions +*//***************************************************************************/ + +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000 + +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \ + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \ + default: bitMask = 0;break;} + +/**************************************************************************//** + @Description Events +*//***************************************************************************/ + +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000 + +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \ + case e_FM_MACSEC_SECY_EV_NEXT_PN: \ + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \ + default: bitMask = 0;break;} + +/**************************************************************************//** + @Description Defaults +*//***************************************************************************/ + +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED) +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN) +#define DEFAULT_numOfTxSc 1 +#define DEFAULT_confidentialityEnable FALSE +#define DEFAULT_confidentialityOffset 0 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT +#define DEFAULT_replayEnable FALSE +#define DEFAULT_replayWindow 0 +#define DEFAULT_protectFrames TRUE +#define DEFAULT_ptp FALSE + +/**************************************************************************//** + @Description General defines +*//***************************************************************************/ + +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC + + +typedef struct { + e_ScSaId saId; + bool active; + union { + t_FmMacsecSecYRxSaStatistics rxSaStatistics; + t_FmMacsecSecYTxSaStatistics txSaStatistics; + }; +} t_SecYSa; + +typedef struct { + bool inUse; + uint32_t scId; + e_ScType type; + uint8_t numOfSa; + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC]; + union { + t_FmMacsecSecYRxScStatistics rxScStatistics; + t_FmMacsecSecYTxScStatistics txScStatistics; + }; +} t_SecYSc; + +typedef struct { + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */ +} t_FmMacsecSecYDriverParam; + +typedef struct { + t_Handle h_FmMacsec; + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection + FALSE - no confidentiality protection, only integrity protection*/ + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection + common values are 0, 30, and 50 */ + bool replayProtect; /**< replay protection function mode */ + uint32_t replayWindow; /**< the size of the replay window */ + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */ + e_FmMacsecSciInsertionMode sciInsertionMode; + bool protectFrames; + bool isPointToPoint; + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */ + uint32_t numOfRxSc; /**< Number of receive channels */ + uint32_t numOfTxSc; /**< Number of transmit channels */ + t_SecYSc *p_RxSc; + t_SecYSc *p_TxSc; + uint32_t events; + uint32_t exceptions; + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */ + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */ + t_Handle h_App; + t_FmMacsecSecYStatistics statistics; + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam; +} t_FmMacsecSecY; + + +#endif /* __FM_MACSEC_SECY_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/crc64.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/crc64.h new file mode 100644 index 000000000000..335ee6819188 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/crc64.h @@ -0,0 +1,360 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + + /**************************************************************************//** + @File crc64.h + + @Description brief This file contains the CRC64 Table, and __inline__ + functions used for calculating crc. +*//***************************************************************************/ +#ifndef __CRC64_H +#define __CRC64_H + +#include "std_ext.h" + + +#define BITS_PER_BYTE 8 + +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL + +#define CRC64_BYTE_MASK 0xFF +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE ) +#define CRC64_ODD_MASK 1 + + +/** + \brief '64 bit crc' Table + */ +struct crc64_t { + uint64_t initial; /**< Initial seed */ + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */ +}; + + +static struct crc64_t CRC64_ECMA_182 = { + CRC64_DEFAULT_INITVAL, + { + 0x0000000000000000ULL, + 0xb32e4cbe03a75f6fULL, + 0xf4843657a840a05bULL, + 0x47aa7ae9abe7ff34ULL, + 0x7bd0c384ff8f5e33ULL, + 0xc8fe8f3afc28015cULL, + 0x8f54f5d357cffe68ULL, + 0x3c7ab96d5468a107ULL, + 0xf7a18709ff1ebc66ULL, + 0x448fcbb7fcb9e309ULL, + 0x0325b15e575e1c3dULL, + 0xb00bfde054f94352ULL, + 0x8c71448d0091e255ULL, + 0x3f5f08330336bd3aULL, + 0x78f572daa8d1420eULL, + 0xcbdb3e64ab761d61ULL, + 0x7d9ba13851336649ULL, + 0xceb5ed8652943926ULL, + 0x891f976ff973c612ULL, + 0x3a31dbd1fad4997dULL, + 0x064b62bcaebc387aULL, + 0xb5652e02ad1b6715ULL, + 0xf2cf54eb06fc9821ULL, + 0x41e11855055bc74eULL, + 0x8a3a2631ae2dda2fULL, + 0x39146a8fad8a8540ULL, + 0x7ebe1066066d7a74ULL, + 0xcd905cd805ca251bULL, + 0xf1eae5b551a2841cULL, + 0x42c4a90b5205db73ULL, + 0x056ed3e2f9e22447ULL, + 0xb6409f5cfa457b28ULL, + 0xfb374270a266cc92ULL, + 0x48190ecea1c193fdULL, + 0x0fb374270a266cc9ULL, + 0xbc9d3899098133a6ULL, + 0x80e781f45de992a1ULL, + 0x33c9cd4a5e4ecdceULL, + 0x7463b7a3f5a932faULL, + 0xc74dfb1df60e6d95ULL, + 0x0c96c5795d7870f4ULL, + 0xbfb889c75edf2f9bULL, + 0xf812f32ef538d0afULL, + 0x4b3cbf90f69f8fc0ULL, + 0x774606fda2f72ec7ULL, + 0xc4684a43a15071a8ULL, + 0x83c230aa0ab78e9cULL, + 0x30ec7c140910d1f3ULL, + 0x86ace348f355aadbULL, + 0x3582aff6f0f2f5b4ULL, + 0x7228d51f5b150a80ULL, + 0xc10699a158b255efULL, + 0xfd7c20cc0cdaf4e8ULL, + 0x4e526c720f7dab87ULL, + 0x09f8169ba49a54b3ULL, + 0xbad65a25a73d0bdcULL, + 0x710d64410c4b16bdULL, + 0xc22328ff0fec49d2ULL, + 0x85895216a40bb6e6ULL, + 0x36a71ea8a7ace989ULL, + 0x0adda7c5f3c4488eULL, + 0xb9f3eb7bf06317e1ULL, + 0xfe5991925b84e8d5ULL, + 0x4d77dd2c5823b7baULL, + 0x64b62bcaebc387a1ULL, + 0xd7986774e864d8ceULL, + 0x90321d9d438327faULL, + 0x231c512340247895ULL, + 0x1f66e84e144cd992ULL, + 0xac48a4f017eb86fdULL, + 0xebe2de19bc0c79c9ULL, + 0x58cc92a7bfab26a6ULL, + 0x9317acc314dd3bc7ULL, + 0x2039e07d177a64a8ULL, + 0x67939a94bc9d9b9cULL, + 0xd4bdd62abf3ac4f3ULL, + 0xe8c76f47eb5265f4ULL, + 0x5be923f9e8f53a9bULL, + 0x1c4359104312c5afULL, + 0xaf6d15ae40b59ac0ULL, + 0x192d8af2baf0e1e8ULL, + 0xaa03c64cb957be87ULL, + 0xeda9bca512b041b3ULL, + 0x5e87f01b11171edcULL, + 0x62fd4976457fbfdbULL, + 0xd1d305c846d8e0b4ULL, + 0x96797f21ed3f1f80ULL, + 0x2557339fee9840efULL, + 0xee8c0dfb45ee5d8eULL, + 0x5da24145464902e1ULL, + 0x1a083bacedaefdd5ULL, + 0xa9267712ee09a2baULL, + 0x955cce7fba6103bdULL, + 0x267282c1b9c65cd2ULL, + 0x61d8f8281221a3e6ULL, + 0xd2f6b4961186fc89ULL, + 0x9f8169ba49a54b33ULL, + 0x2caf25044a02145cULL, + 0x6b055fede1e5eb68ULL, + 0xd82b1353e242b407ULL, + 0xe451aa3eb62a1500ULL, + 0x577fe680b58d4a6fULL, + 0x10d59c691e6ab55bULL, + 0xa3fbd0d71dcdea34ULL, + 0x6820eeb3b6bbf755ULL, + 0xdb0ea20db51ca83aULL, + 0x9ca4d8e41efb570eULL, + 0x2f8a945a1d5c0861ULL, + 0x13f02d374934a966ULL, + 0xa0de61894a93f609ULL, + 0xe7741b60e174093dULL, + 0x545a57dee2d35652ULL, + 0xe21ac88218962d7aULL, + 0x5134843c1b317215ULL, + 0x169efed5b0d68d21ULL, + 0xa5b0b26bb371d24eULL, + 0x99ca0b06e7197349ULL, + 0x2ae447b8e4be2c26ULL, + 0x6d4e3d514f59d312ULL, + 0xde6071ef4cfe8c7dULL, + 0x15bb4f8be788911cULL, + 0xa6950335e42fce73ULL, + 0xe13f79dc4fc83147ULL, + 0x521135624c6f6e28ULL, + 0x6e6b8c0f1807cf2fULL, + 0xdd45c0b11ba09040ULL, + 0x9aefba58b0476f74ULL, + 0x29c1f6e6b3e0301bULL, + 0xc96c5795d7870f42ULL, + 0x7a421b2bd420502dULL, + 0x3de861c27fc7af19ULL, + 0x8ec62d7c7c60f076ULL, + 0xb2bc941128085171ULL, + 0x0192d8af2baf0e1eULL, + 0x4638a2468048f12aULL, + 0xf516eef883efae45ULL, + 0x3ecdd09c2899b324ULL, + 0x8de39c222b3eec4bULL, + 0xca49e6cb80d9137fULL, + 0x7967aa75837e4c10ULL, + 0x451d1318d716ed17ULL, + 0xf6335fa6d4b1b278ULL, + 0xb199254f7f564d4cULL, + 0x02b769f17cf11223ULL, + 0xb4f7f6ad86b4690bULL, + 0x07d9ba1385133664ULL, + 0x4073c0fa2ef4c950ULL, + 0xf35d8c442d53963fULL, + 0xcf273529793b3738ULL, + 0x7c0979977a9c6857ULL, + 0x3ba3037ed17b9763ULL, + 0x888d4fc0d2dcc80cULL, + 0x435671a479aad56dULL, + 0xf0783d1a7a0d8a02ULL, + 0xb7d247f3d1ea7536ULL, + 0x04fc0b4dd24d2a59ULL, + 0x3886b22086258b5eULL, + 0x8ba8fe9e8582d431ULL, + 0xcc0284772e652b05ULL, + 0x7f2cc8c92dc2746aULL, + 0x325b15e575e1c3d0ULL, + 0x8175595b76469cbfULL, + 0xc6df23b2dda1638bULL, + 0x75f16f0cde063ce4ULL, + 0x498bd6618a6e9de3ULL, + 0xfaa59adf89c9c28cULL, + 0xbd0fe036222e3db8ULL, + 0x0e21ac88218962d7ULL, + 0xc5fa92ec8aff7fb6ULL, + 0x76d4de52895820d9ULL, + 0x317ea4bb22bfdfedULL, + 0x8250e80521188082ULL, + 0xbe2a516875702185ULL, + 0x0d041dd676d77eeaULL, + 0x4aae673fdd3081deULL, + 0xf9802b81de97deb1ULL, + 0x4fc0b4dd24d2a599ULL, + 0xfceef8632775faf6ULL, + 0xbb44828a8c9205c2ULL, + 0x086ace348f355aadULL, + 0x34107759db5dfbaaULL, + 0x873e3be7d8faa4c5ULL, + 0xc094410e731d5bf1ULL, + 0x73ba0db070ba049eULL, + 0xb86133d4dbcc19ffULL, + 0x0b4f7f6ad86b4690ULL, + 0x4ce50583738cb9a4ULL, + 0xffcb493d702be6cbULL, + 0xc3b1f050244347ccULL, + 0x709fbcee27e418a3ULL, + 0x3735c6078c03e797ULL, + 0x841b8ab98fa4b8f8ULL, + 0xadda7c5f3c4488e3ULL, + 0x1ef430e13fe3d78cULL, + 0x595e4a08940428b8ULL, + 0xea7006b697a377d7ULL, + 0xd60abfdbc3cbd6d0ULL, + 0x6524f365c06c89bfULL, + 0x228e898c6b8b768bULL, + 0x91a0c532682c29e4ULL, + 0x5a7bfb56c35a3485ULL, + 0xe955b7e8c0fd6beaULL, + 0xaeffcd016b1a94deULL, + 0x1dd181bf68bdcbb1ULL, + 0x21ab38d23cd56ab6ULL, + 0x9285746c3f7235d9ULL, + 0xd52f0e859495caedULL, + 0x6601423b97329582ULL, + 0xd041dd676d77eeaaULL, + 0x636f91d96ed0b1c5ULL, + 0x24c5eb30c5374ef1ULL, + 0x97eba78ec690119eULL, + 0xab911ee392f8b099ULL, + 0x18bf525d915feff6ULL, + 0x5f1528b43ab810c2ULL, + 0xec3b640a391f4fadULL, + 0x27e05a6e926952ccULL, + 0x94ce16d091ce0da3ULL, + 0xd3646c393a29f297ULL, + 0x604a2087398eadf8ULL, + 0x5c3099ea6de60cffULL, + 0xef1ed5546e415390ULL, + 0xa8b4afbdc5a6aca4ULL, + 0x1b9ae303c601f3cbULL, + 0x56ed3e2f9e224471ULL, + 0xe5c372919d851b1eULL, + 0xa26908783662e42aULL, + 0x114744c635c5bb45ULL, + 0x2d3dfdab61ad1a42ULL, + 0x9e13b115620a452dULL, + 0xd9b9cbfcc9edba19ULL, + 0x6a978742ca4ae576ULL, + 0xa14cb926613cf817ULL, + 0x1262f598629ba778ULL, + 0x55c88f71c97c584cULL, + 0xe6e6c3cfcadb0723ULL, + 0xda9c7aa29eb3a624ULL, + 0x69b2361c9d14f94bULL, + 0x2e184cf536f3067fULL, + 0x9d36004b35545910ULL, + 0x2b769f17cf112238ULL, + 0x9858d3a9ccb67d57ULL, + 0xdff2a94067518263ULL, + 0x6cdce5fe64f6dd0cULL, + 0x50a65c93309e7c0bULL, + 0xe388102d33392364ULL, + 0xa4226ac498dedc50ULL, + 0x170c267a9b79833fULL, + 0xdcd7181e300f9e5eULL, + 0x6ff954a033a8c131ULL, + 0x28532e49984f3e05ULL, + 0x9b7d62f79be8616aULL, + 0xa707db9acf80c06dULL, + 0x14299724cc279f02ULL, + 0x5383edcd67c06036ULL, + 0xe0ada17364673f59ULL + } +}; + + +/** + \brief Initializes the crc seed + */ +static __inline__ uint64_t crc64_init(void) +{ + return CRC64_ECMA_182.initial; +} + +/** + \brief Computes 64 bit the crc + \param[in] data Pointer to the Data in the frame + \param[in] len Length of the Data + \param[in] crc seed + \return calculated crc + */ +static __inline__ uint64_t crc64_compute(void const *data, + uint32_t len, + uint64_t seed) +{ + uint32_t i; + uint64_t crc = seed; + uint8_t *bdata = (uint8_t *) data; + + for (i = 0; i < len; i++) + crc = + CRC64_ECMA_182. + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8); + + return crc; +} + + +#endif /* __CRC64_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c index fe765a475614..c633fce847ee 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,11 +30,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_cc.c - @Description FM CC ... -*//***************************************************************************/ + @Description FM Coarse Classifier implementation + *//***************************************************************************/ +#include +#include #include "std_ext.h" #include "error_ext.h" #include "string_ext.h" @@ -43,376 +46,1178 @@ #include "fm_muram_ext.h" #include "fm_common.h" +#include "fm_pcd.h" #include "fm_hc.h" #include "fm_cc.h" +#include "crc64.h" + +/****************************************/ +/* static functions */ +/****************************************/ -#if defined(FM_CAPWAP_SUPPORT) -#define FM_PCD_CC_MANIP -#endif /* defined(FM_CAPWAP_SUPPORT) || ... */ - - -t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx) +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree) { - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; - ASSERT_COND(p_FmPcdCcTree); + ASSERT_COND(h_FmPcdCcTree); - return p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx]; + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock)) + return E_OK; + + return ERROR_CODE(E_BUSY); } -void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t manipIndx) +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree) { - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; - ASSERT_COND(p_FmPcdCcTree); + ASSERT_COND(h_FmPcdCcTree); - p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx] = h_SavedManipParams; + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock); } -uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode) +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add) { - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t intFlags; - ASSERT_COND(p_FmPcdCcNode); - return p_FmPcdCcNode->parseCode; -} + ASSERT_COND(p_CcNode); -uint8_t FmPcdCcGetOffset(t_Handle h_CcNode) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode; + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); - ASSERT_COND(p_FmPcdCcNode); - return p_FmPcdCcNode->offset; -} - -uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode; - - ASSERT_COND(p_FmPcdCcNode); - return p_FmPcdCcNode->numOfKeys; -} -static void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo) -{ - t_CcNodeInformation *p_CcInformation; - uint32_t intFlags; - - p_CcInformation = (t_CcNodeInformation *)XX_Malloc(sizeof(t_CcNodeInformation)); - if (p_CcInformation) + if (add) + p_CcNode->owners++; + else { - memset(p_CcInformation, 0, sizeof(t_CcNodeInformation)); - memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation)); - INIT_LIST(&p_CcInformation->node); + ASSERT_COND(p_CcNode->owners); + p_CcNode->owners--; + } - intFlags = XX_DisableAllIntr(); - LIST_AddToTail(&p_CcInformation->node, p_List); - XX_RestoreAllIntr(intFlags); + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); +} + +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List) +{ + t_FmPcdStatsObj *p_StatsObj = NULL; + t_List *p_Next; + + if (!NCSW_LIST_IsEmpty(p_List)) + { + p_Next = NCSW_LIST_FIRST(p_List); + p_StatsObj = NCSW_LIST_OBJECT(p_Next, t_FmPcdStatsObj, node); + ASSERT_COND(p_StatsObj); + NCSW_LIST_DelAndInit(p_Next); + } + + return p_StatsObj; +} + +static __inline__ void EnqueueStatsObj(t_List *p_List, + t_FmPcdStatsObj *p_StatsObj) +{ + NCSW_LIST_AddToTail(&p_StatsObj->node, p_List); +} + +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram) +{ + t_FmPcdStatsObj *p_StatsObj; + + while (!NCSW_LIST_IsEmpty(p_List)) + { + p_StatsObj = DequeueStatsObj(p_List); + ASSERT_COND(p_StatsObj); + + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); + + XX_Free(p_StatsObj); + } +} + +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode) +{ + t_FmPcdStatsObj* p_StatsObj; + t_Handle h_FmMuram; + + ASSERT_COND(p_CcNode); + + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated + upon node initialization */ + if (p_CcNode->maxNumOfKeys) + { + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst); } else - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information")); -} - - -static t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info) -{ - t_CcNodeInformation *p_CcInformation; - t_List *p_Pos; - uint32_t intFlags; - - intFlags = XX_DisableAllIntr(); - for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos)) { - p_CcInformation = CC_NODE_F_OBJECT(p_Pos); - ASSERT_COND(p_CcInformation->h_CcNode); - if(p_CcInformation->h_CcNode == h_Info) + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; + ASSERT_COND(h_FmMuram); + + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); + if (!p_StatsObj) { - XX_RestoreAllIntr(intFlags); - return p_CcInformation; + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object")); + return NULL; } + + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem( + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_StatsObj->h_StatsAd) + { + XX_Free(p_StatsObj); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs")); + return NULL; + } + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( + h_FmMuram, p_CcNode->countersArraySize, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_StatsObj->h_StatsCounters) + { + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); + XX_Free(p_StatsObj); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters")); + return NULL; + } + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); } - XX_RestoreAllIntr(intFlags); - return NULL; + + return p_StatsObj; } -static void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info) +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj) { - t_CcNodeInformation *p_CcInformation = NULL; - uint32_t intFlags; - t_List *p_Pos; + t_Handle h_FmMuram; - intFlags = XX_DisableAllIntr(); - if (LIST_IsEmpty(p_List)) - { - XX_RestoreAllIntr(intFlags); - return; - } + ASSERT_COND(p_CcNode); + ASSERT_COND(p_StatsObj); - for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos)) + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated + upon node initialization and now will be enqueued back to the list */ + if (p_CcNode->maxNumOfKeys) { - p_CcInformation = CC_NODE_F_OBJECT(p_Pos); - ASSERT_COND(p_CcInformation->h_CcNode); - if (p_CcInformation->h_CcNode == h_Info) - break; + /* Nullify counters */ + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); + + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); + } + else + { + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; + ASSERT_COND(h_FmMuram); + + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); + + XX_Free(p_StatsObj); } - if (p_CcInformation) - LIST_DelAndInit(&p_CcInformation->node); - XX_RestoreAllIntr(intFlags); } -static t_Error FmPcdCcSetRequiredAction(t_Handle h_FmPcd, uint32_t requiredAction, t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParamsTmp, - t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd, + uint32_t statsCountersAddr) { + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK); - t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp; - uint32_t tmpReg32; - t_Error err; - t_FmPcdCcNode *p_FmPcdCcNode; - int i = 0; - uint16_t tmp = 0; - uint16_t profileId; - uint8_t relativeSchemeId, physicalSchemeId; + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp); +} + + +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, + t_Handle h_Ad, uint64_t physicalMuramBase) +{ + t_AdOfTypeStats *p_StatsAd; + uint32_t statsCountersAddr, nextActionAddr, tmp; +#if (DPAA_VERSION >= 11) + uint32_t frameLengthRangesAddr; +#endif /* (DPAA_VERSION >= 11) */ + + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd; + + tmp = FM_PCD_AD_STATS_TYPE; + +#if (DPAA_VERSION >= 11) + if (p_FmPcdCcStatsParams->h_StatsFLRs) + { + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys( + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase)); + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK); + } +#endif /* (DPAA_VERSION >= 11) */ + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp); + + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase)); + tmp = 0; + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT) + & FM_PCD_AD_STATS_NEXT_ACTION_MASK); + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE); + +#if (DPAA_VERSION >= 11) + if (p_FmPcdCcStatsParams->h_StatsFLRs) + tmp |= FM_PCD_AD_STATS_FLR_EN; +#endif /* (DPAA_VERSION >= 11) */ + + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp); + + statsCountersAddr = (uint32_t)((XX_VirtToPhys( + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase)); + SetStatsCounters(p_StatsAd, statsCountersAddr); +} + +static void FillAdOfTypeContLookup(t_Handle h_Ad, + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, + t_Handle h_FmPcd, t_Handle p_CcNode, + t_Handle h_Manip, t_Handle h_FrmReplic) +{ + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode; + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad; + t_Handle h_TmpAd; + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t tmpReg32; + t_Handle p_AdNewPtr = NULL; + + UNUSED(h_Manip); + UNUSED(h_FrmReplic); + + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD. + * Case 1: No Manip. The action descriptor is built within the match table. + * p_AdResult = p_AdNewPtr; + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized + * either in the FmPcdManipUpdateAdResultForCc routine or it was already + * initialized and returned here. + * p_AdResult (within the match table) will be initialized after + * this routine returns and point to the existing AD. + * Case 3: Manip exists. The action descriptor is built within the match table. + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr. + */ + + /* As default, the "new" ptr is the current one. i.e. the content of the result + * AD will be written into the match table itself (case (1))*/ + p_AdNewPtr = p_AdContLookup; + + /* Initialize an action descriptor, if current statistics mode requires an Ad */ + if (p_FmPcdCcStatsParams) + { + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); + + /* Swapping addresses between statistics Ad and the current lookup AD */ + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; + p_FmPcdCcStatsParams->h_StatsAd = h_Ad; + h_Ad = h_TmpAd; + + p_AdNewPtr = h_Ad; + p_AdContLookup = h_Ad; + + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); + } + +#if DPAA_VERSION >= 11 + if (h_Manip && h_FrmReplic) + FmPcdManipUpdateAdContLookupForCc( + h_Manip, + h_Ad, + &p_AdNewPtr, + (uint32_t)((XX_VirtToPhys( + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic)) + - p_FmPcd->physicalMuramBase))); + else + if (h_FrmReplic) + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr); + else +#endif /* (DPAA_VERSION >= 11) */ + if (h_Manip) + FmPcdManipUpdateAdContLookupForCc( + h_Manip, + h_Ad, + &p_AdNewPtr, + +#ifdef FM_CAPWAP_SUPPORT + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/ + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)) +#else /* not FM_CAPWAP_SUPPORT */ + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad) + - p_FmPcd->physicalMuramBase)) +#endif /* not FM_CAPWAP_SUPPORT */ + ); + + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ + if (p_AdNewPtr) + { + /* cases (1) & (2) */ + tmpReg32 = 0; + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; + tmpReg32 |= + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : + 0; + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) + - p_FmPcd->physicalMuramBase); + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32); + + tmpReg32 = 0; + tmpReg32 |= p_Node->numOfKeys << 24; + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0); + tmpReg32 |= + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys( + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : + 0; + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32); + + tmpReg32 = 0; + tmpReg32 |= p_Node->prsArrayOffset << 24; + tmpReg32 |= p_Node->offset << 16; + tmpReg32 |= p_Node->parseCode; + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32); + + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, + CC_GLBL_MASK_SIZE); + } +} + +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t intFlags; + + ASSERT_COND(p_CcNode); + + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + if (!p_CcNode->h_Ad) + { + if (p_CcNode->maxNumOfKeys) + p_CcNode->h_Ad = p_CcNode->h_TmpAd; + else + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem( + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram, + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + if (!p_CcNode->h_Ad) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC action descriptor")); + + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd, + p_CcNode, NULL, NULL); + } + else + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + return E_OK; +} + +static t_Error SetRequiredAction1( + t_Handle h_FmPcd, uint32_t requiredAction, + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) +{ + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp; + uint32_t tmpReg32; + t_Error err; + t_FmPcdCcNode *p_CcNode; + int i = 0; + uint16_t tmp = 0; + uint16_t profileId; + uint8_t relativeSchemeId, physicalSchemeId; t_CcNodeInformation ccNodeInfo; - for(i = 0; i < numOfEntries; i++) - { - if(i == 0) + for (i = 0; i < numOfEntries; i++) + { + if (i == 0) h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE); else h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE); - if(p_CcNextEngineParamsTmp[i].shadowAction & requiredAction) - continue; - switch(p_CcNextEngineParamsTmp[i].nextEngineParams.nextEngine) + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine) { - case(e_FM_PCD_CC): - if(requiredAction) + case (e_FM_PCD_CC): + if (requiredAction) { - p_FmPcdCcNode = p_CcNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode; - ASSERT_COND(p_FmPcdCcNode); - if(p_FmPcdCcNode->shadowAction == requiredAction) + p_CcNode = + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode; + ASSERT_COND(p_CcNode); + if (p_CcNode->shadowAction == requiredAction) break; - if((requiredAction & UPDATE_CC_WITH_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE)) + if ((requiredAction & UPDATE_CC_WITH_TREE) + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE)) { - ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 0); - if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE) - p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_DELETE_TREE; memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); ccNodeInfo.h_CcNode = h_Tree; - EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNode->ccTreesLst, &ccNodeInfo); - p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_TREE; + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst, + &ccNodeInfo, NULL); + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= + UPDATE_CC_WITH_TREE; } - if((requiredAction & UPDATE_CC_WITH_DELETE_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE)) + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR) + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR)) { - ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 1); - if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE) - p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_TREE; - DequeueNodeInfoFromRelevantLst(&p_FmPcdCcNode->ccTreesLst, h_Tree); - p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_DELETE_TREE; + + p_CcNode->shadowAction = 0; } - if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID) - tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1); + + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE) + && !(p_CcNode->shadowAction + & UPDATE_CC_WITH_DELETE_TREE)) + { + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst, + h_Tree, NULL); + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= + UPDATE_CC_WITH_DELETE_TREE; + } + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine + != e_FM_PCD_INVALID) + tmp = (uint8_t)(p_CcNode->numOfKeys + 1); else - tmp = p_FmPcdCcNode->numOfKeys; - err = FmPcdCcSetRequiredAction(h_FmPcd, requiredAction, p_FmPcdCcNode->nextEngineAndRequiredAction, p_FmPcdCcNode->h_AdTable, tmp, h_Tree); - if(err != E_OK) + tmp = p_CcNode->numOfKeys; + err = SetRequiredAction1(h_FmPcd, requiredAction, + p_CcNode->keyAndNextEngineParams, + p_CcNode->h_AdTable, tmp, h_Tree); + if (err != E_OK) return err; - p_FmPcdCcNode->shadowAction |= requiredAction; + if (requiredAction != UPDATE_CC_SHADOW_CLEAR) + p_CcNode->shadowAction |= requiredAction; } break; - case(e_FM_PCD_KG): - if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA)) + case (e_FM_PCD_KG): + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction + & UPDATE_NIA_ENQ_WITHOUT_DMA)) { - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)-1); - relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, physicalSchemeId); - if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + physicalSchemeId = + FmPcdKgGetSchemeId( + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme); + relativeSchemeId = FmPcdKgGetRelativeSchemeId( + h_FmPcd, physicalSchemeId); + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme.")); - if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this action scheme has to be direct.")); - err = FmPcdKgCcGetSetParams(h_FmPcd, p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, requiredAction); - if(err != E_OK) + if (!FmPcdKgIsSchemeValidSw( + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Invalid direct scheme.")); + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("For this action scheme has to be direct.")); + err = + FmPcdKgCcGetSetParams( + h_FmPcd, + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, + requiredAction, 0); + if (err != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); - p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction; + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= + requiredAction; } break; - case(e_FM_PCD_PLCR): - if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA)) + case (e_FM_PCD_PLCR): + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction + & UPDATE_NIA_ENQ_WITHOUT_DMA)) { - if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes")); - if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes")); - err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, e_FM_PCD_PLCR_SHARED, NULL, p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, &profileId); - if(err!= E_OK) + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams) + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("In this initialization only overrideFqid can be initialized")); + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile) + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("In this initialization only overrideFqid can be initialized")); + err = + FmPcdPlcrGetAbsoluteIdByProfileParams( + h_FmPcd, + e_FM_PCD_PLCR_SHARED, + NULL, + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, + &profileId); + if (err != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); - err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, requiredAction); - if(err != E_OK) + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, + requiredAction); + if (err != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); - p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction; + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= + requiredAction; } break; - case(e_FM_PCD_DONE): - if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA)) + case (e_FM_PCD_DONE): + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction + & UPDATE_NIA_ENQ_WITHOUT_DMA)) { tmpReg32 = GET_UINT32(p_AdTmp->nia); - if((tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine was previosely assigned not as PCD_DONE")); + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("Next engine was previously assigned not as PCD_DONE")); tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; WRITE_UINT32(p_AdTmp->nia, tmpReg32); - p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction; + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= + requiredAction; } break; default: break; } - } - - return E_OK; -} - -static t_Error CcUpdateParam(t_Handle h_FmPcd, - t_Handle h_FmPort, - t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParams, - uint16_t numOfEntries, - t_Handle h_Ad, - bool validate, - uint16_t level, - t_Handle h_FmTree, - bool modify) -{ - t_CcNodeInformation *p_CcNodeInfo; - t_FmPcdCcNode *p_FmPcdCcNode; - t_Error err; - uint16_t tmp = 0; - int i = 0; - - level++; - - if(numOfEntries) - { - for(i = 0; i < numOfEntries; i++) - { - if(i == 0) - h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE); - else - h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE); - - if(p_CcNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - { - p_FmPcdCcNode = p_CcNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; - ASSERT_COND(p_FmPcdCcNode); - p_CcNodeInfo = FindNodeInfoInReleventLst(&p_FmPcdCcNode->ccTreesLst,h_FmTree); - ASSERT_COND(p_CcNodeInfo); - p_CcNodeInfo->index = level; -#ifdef FM_PCD_CC_MANIP - if(p_CcNextEngineParams[i].nextEngineParams.h_Manip) - { - err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, p_CcNodeInfo->index, h_FmTree, modify); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - } -#endif /* FM_PCD_CC_MANIP */ - - if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID) - tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1); - else - tmp = p_FmPcdCcNode->numOfKeys; - - err = CcUpdateParam(h_FmPcd, h_FmPort, p_FmPcdCcNode->nextEngineAndRequiredAction, tmp, p_FmPcdCcNode->h_AdTable, validate,level, h_FmTree, modify); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - } -#ifdef FM_PCD_CC_MANIP - else - { - if(p_CcNextEngineParams[i].nextEngineParams.h_Manip) - { - err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, level,h_FmTree, modify); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - } - } -#endif /* FM_PCD_CC_MANIP */ - } } return E_OK; } -static bool IsNodeInModifiedState(t_Handle h_CcNode) + +static t_Error SetRequiredAction( + t_Handle h_FmPcd, uint32_t requiredAction, + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) { - t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; - - ASSERT_COND(p_CcNode); - - return p_CcNode->modifiedState; + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction, + p_CcKeyAndNextEngineParamsTmp, h_AdTmp, + numOfEntries, h_Tree); + if (err != E_OK) + return err; + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR, + p_CcKeyAndNextEngineParamsTmp, h_AdTmp, + numOfEntries, h_Tree); } -static void UpdateNodeWithModifiedState(t_Handle h_CcNode, bool modifiedState) +static t_Error ReleaseModifiedDataStructure( + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, + t_List *h_FmPcdNewPointersLst, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, + bool useShadowStructs) { - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode; + t_List *p_Pos; + t_Error err = E_OK; + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation; + t_Handle h_Muram; + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode; + t_List *p_UpdateLst; + uint32_t intFlags; - ASSERT_COND(p_FmPcdCcNode); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode, + E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE); - p_FmPcdCcNode->modifiedState = modifiedState; + /* We don't update subtree of the new node with new tree because it was done in the previous stage */ + if (p_AdditionalParams->h_NodeForAdd) + { + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd; + + if (!p_AdditionalParams->tree) + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; + else + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; + + p_CcNodeInformation = FindNodeInfoInReleventLst( + p_UpdateLst, p_AdditionalParams->h_CurrentNode, + p_FmPcdCcNextNode->h_Spinlock); + + if (p_CcNodeInformation) + p_CcNodeInformation->index++; + else + { + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode; + ccNodeInfo.index = 1; + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo, + p_FmPcdCcNextNode->h_Spinlock); + } + if (p_AdditionalParams->h_ManipForAdd) + { + p_CcNodeInformation = FindNodeInfoInReleventLst( + FmPcdManipGetNodeLstPointedOnThisManip( + p_AdditionalParams->h_ManipForAdd), + p_AdditionalParams->h_CurrentNode, + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd)); + + if (p_CcNodeInformation) + p_CcNodeInformation->index++; + else + { + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = + (t_Handle)p_AdditionalParams->h_CurrentNode; + ccNodeInfo.index = 1; + EnqueueNodeInfoToRelevantLst( + FmPcdManipGetNodeLstPointedOnThisManip( + p_AdditionalParams->h_ManipForAdd), + &ccNodeInfo, + FmPcdManipGetSpinlock( + p_AdditionalParams->h_ManipForAdd)); + } + } + } + + if (p_AdditionalParams->h_NodeForRmv) + { + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv; + + if (!p_AdditionalParams->tree) + { + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; + p_FmPcdCcWorkingOnNode = + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); + + for (p_Pos = NCSW_LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst); + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos = + NCSW_LIST_NEXT(p_Pos)) + { + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); + + ASSERT_COND(p_CcNodeInformation->h_CcNode); + + err = + SetRequiredAction( + h_FmPcd, + UPDATE_CC_WITH_DELETE_TREE, + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), + 1, p_CcNodeInformation->h_CcNode); + } + } + else + { + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; + + err = + SetRequiredAction( + h_FmPcd, + UPDATE_CC_WITH_DELETE_TREE, + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), + 1, p_AdditionalParams->h_CurrentNode); + } + if (err) + return err; + + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage + Update ccPrevNodesLst or ccTreeIdLst of the removed node + Update of the node owner */ + p_CcNodeInformation = FindNodeInfoInReleventLst( + p_UpdateLst, p_AdditionalParams->h_CurrentNode, + p_FmPcdCcNextNode->h_Spinlock); + + ASSERT_COND(p_CcNodeInformation); + ASSERT_COND(p_CcNodeInformation->index); + + p_CcNodeInformation->index--; + + if (p_CcNodeInformation->index == 0) + DequeueNodeInfoFromRelevantLst(p_UpdateLst, + p_AdditionalParams->h_CurrentNode, + p_FmPcdCcNextNode->h_Spinlock); + + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE); + + if (p_AdditionalParams->h_ManipForRmv) + { + p_CcNodeInformation = FindNodeInfoInReleventLst( + FmPcdManipGetNodeLstPointedOnThisManip( + p_AdditionalParams->h_ManipForRmv), + p_AdditionalParams->h_CurrentNode, + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv)); + + ASSERT_COND(p_CcNodeInformation); + ASSERT_COND(p_CcNodeInformation->index); + + p_CcNodeInformation->index--; + + if (p_CcNodeInformation->index == 0) + DequeueNodeInfoFromRelevantLst( + FmPcdManipGetNodeLstPointedOnThisManip( + p_AdditionalParams->h_ManipForRmv), + p_AdditionalParams->h_CurrentNode, + FmPcdManipGetSpinlock( + p_AdditionalParams->h_ManipForRmv)); + } + } + + if (p_AdditionalParams->h_ManipForRmv) + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE); + + if (p_AdditionalParams->p_StatsObjForRmv) + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode), + p_AdditionalParams->p_StatsObjForRmv); + +#if (DPAA_VERSION >= 11) + if (p_AdditionalParams->h_FrmReplicForRmv) + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv, + FALSE/* remove */); +#endif /* (DPAA_VERSION >= 11) */ + + if (!useShadowStructs) + { + h_Muram = FmPcdGetMuramHandle(h_FmPcd); + ASSERT_COND(h_Muram); + + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow) + || (!p_AdditionalParams->tree + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys)) + { + /* We release new AD which was allocated and updated for copy from to actual AD */ + for (p_Pos = NCSW_LIST_FIRST(h_FmPcdNewPointersLst); + p_Pos != (h_FmPcdNewPointersLst); p_Pos = NCSW_LIST_NEXT(p_Pos)) + { + + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); + ASSERT_COND(p_CcNodeInformation->h_CcNode); + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode); + } + } + + /* Free Old data structure if it has to be freed - new data structure was allocated*/ + if (p_AdditionalParams->p_AdTableOld) + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld); + + if (p_AdditionalParams->p_KeysMatchTableOld) + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld); + } + + /* Update current modified node with changed fields if it's required*/ + if (!p_AdditionalParams->tree) + { + if (p_AdditionalParams->p_AdTableNew) + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable = + p_AdditionalParams->p_AdTableNew; + + if (p_AdditionalParams->p_KeysMatchTableNew) + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable = + p_AdditionalParams->p_KeysMatchTableNew; + + /* Locking node's spinlock before updating 'keys and next engine' structure, + as it maybe used to retrieve keys statistics */ + intFlags = + XX_LockIntrSpinlock( + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock); + + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys = + p_AdditionalParams->numOfKeys; + + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, + &p_AdditionalParams->keyAndNextEngineParams, + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS)); + + XX_UnlockIntrSpinlock( + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock, + intFlags); + } + else + { + uint8_t numEntries = + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries; + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS); + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, + &p_AdditionalParams->keyAndNextEngineParams, + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries); + } + + ReleaseLst(h_FmPcdOldPointersLst); + ReleaseLst(h_FmPcdNewPointersLst); + + XX_Free(p_AdditionalParams); + + return E_OK; +} + +static t_Handle BuildNewAd( + t_Handle h_Ad, + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, + t_FmPcdCcNode *p_CcNode, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_FmPcdCcNodeTmp; + t_Handle h_OrigAd = NULL; + + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); + if (!p_FmPcdCcNodeTmp) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp")); + return NULL; + } + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode)); + + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys; + p_FmPcdCcNodeTmp->h_KeysMatchTable = + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew; + p_FmPcdCcNodeTmp->h_AdTable = + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew; + + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask; + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode; + p_FmPcdCcNodeTmp->offset = p_CcNode->offset; + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset; + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow; + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction; + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction; + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize; + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask; + + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) + { + if (p_FmPcdCcNextEngineParams->h_Manip) + { + h_OrigAd = p_CcNode->h_Ad; + if (AllocAndFillAdForContLookupManip( + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) + != E_OK) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + XX_Free(p_FmPcdCcNodeTmp); + return NULL; + } + } + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL); + } + +#if (DPAA_VERSION >= 11) + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR) + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)) + { + FillAdOfTypeContLookup( + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, + p_FmPcdCcNextEngineParams->h_Manip, + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); + } +#endif /* (DPAA_VERSION >= 11) */ + + XX_Free(p_FmPcdCcNodeTmp); + + return E_OK; +} + +static t_Error DynamicChangeHc( + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, + bool useShadowStructs) +{ + t_List *p_PosOld, *p_PosNew; + uint32_t oldAdAddrOffset, newAdAddrOffset; + uint16_t i = 0; + t_Error err = E_OK; + uint8_t numOfModifiedPtr; + + ASSERT_COND(h_FmPcd); + ASSERT_COND(h_OldPointersLst); + ASSERT_COND(h_NewPointersLst); + + numOfModifiedPtr = (uint8_t)NCSW_LIST_NumOfObjs(h_OldPointersLst); + + if (numOfModifiedPtr) + { + p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst); + p_PosOld = NCSW_LIST_FIRST(h_OldPointersLst); + + /* Retrieve address of new AD */ + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, + p_PosNew); + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE) + { + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, + h_NewPointersLst, + p_AdditionalParams, useShadowStructs); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address")); + } + + for (i = 0; i < numOfModifiedPtr; i++) + { + /* Retrieve address of current AD */ + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, + p_PosOld); + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE) + { + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, + h_NewPointersLst, + p_AdditionalParams, + useShadowStructs); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address")); + } + + /* Invoke host command to copy from new AD to old AD */ + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc, + oldAdAddrOffset, newAdAddrOffset); + if (err) + { + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, + h_NewPointersLst, + p_AdditionalParams, + useShadowStructs); + RETURN_ERROR( + MAJOR, + err, + ("For part of nodes changes are done - situation is danger")); + } + + p_PosOld = NCSW_LIST_NEXT(p_PosOld); + } + } + return E_OK; +} + +static t_Error DoDynamicChange( + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, + bool useShadowStructs) +{ + t_FmPcdCcNode *p_CcNode = + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); + t_List *p_PosNew; + t_CcNodeInformation *p_CcNodeInfo; + t_FmPcdCcNextEngineParams nextEngineParams; + t_Handle h_Ad; + uint32_t keySize; + t_Error err = E_OK; + uint8_t numOfModifiedPtr; + + ASSERT_COND(h_FmPcd); + + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); + + numOfModifiedPtr = (uint8_t)NCSW_LIST_NumOfObjs(h_OldPointersLst); + + if (numOfModifiedPtr) + { + + p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst); + + /* Invoke host-command to copy from the new Ad to existing Ads */ + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, + p_AdditionalParams, useShadowStructs); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (useShadowStructs) + { + /* When the host-command above has ended, the old structures are 'free'and we can update + them by copying from the new shadow structures. */ + if (p_CcNode->lclMask) + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); + else + keySize = p_CcNode->ccKeySizeAccExtraction; + + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld, + p_AdditionalParams->p_KeysMatchTableNew, + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t)); + + MemCpy8( + p_AdditionalParams->p_AdTableOld, + p_AdditionalParams->p_AdTableNew, + (uint32_t)((p_CcNode->maxNumOfKeys + 1) + * FM_PCD_CC_AD_ENTRY_SIZE)); + + /* Retrieve the address of the allocated Ad */ + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew); + h_Ad = p_CcNodeInfo->h_CcNode; + + /* Build a new Ad that holds the old (now updated) structures */ + p_AdditionalParams->p_KeysMatchTableNew = + p_AdditionalParams->p_KeysMatchTableOld; + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld; + + nextEngineParams.nextEngine = e_FM_PCD_CC; + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode; + + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams); + + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */ + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, + p_AdditionalParams, useShadowStructs); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, + h_NewPointersLst, + p_AdditionalParams, useShadowStructs); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +#ifdef FM_CAPWAP_SUPPORT +static bool IsCapwapApplSpecific(t_Handle h_Node) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node; + bool isManipForCapwapApplSpecificBuild = FALSE; + int i = 0; + + ASSERT_COND(h_Node); + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/ + for (i = 0; i < p_CcNode->numOfKeys; i++) + { + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip && + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)) + { + isManipForCapwapApplSpecificBuild = TRUE; + break; + } + } + return isManipForCapwapApplSpecificBuild; + +} +#endif /* FM_CAPWAP_SUPPORT */ + +static t_Error CcUpdateParam( + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams, + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level, + t_Handle h_FmTree, bool modify) +{ + t_FmPcdCcNode *p_CcNode; + t_Error err; + uint16_t tmp = 0; + int i = 0; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; + + level++; + + if (p_CcTree->h_IpReassemblyManip) + { + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, + p_CcTree->h_IpReassemblyManip, NULL, validate, + level, h_FmTree, modify); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if (p_CcTree->h_CapwapReassemblyManip) + { + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, + p_CcTree->h_CapwapReassemblyManip, NULL, validate, + level, h_FmTree, modify); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if (numOfEntries) + { + for (i = 0; i < numOfEntries; i++) + { + if (i == 0) + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE); + else + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE); + + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) + { + p_CcNode = + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + ASSERT_COND(p_CcNode); + + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) + { + err = + FmPcdManipUpdate( + h_FmPcd, + NULL, + h_FmPort, + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, + h_Ad, validate, level, h_FmTree, modify); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine + != e_FM_PCD_INVALID) + tmp = (uint8_t)(p_CcNode->numOfKeys + 1); + else + tmp = p_CcNode->numOfKeys; + + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, + p_CcNode->keyAndNextEngineParams, tmp, + p_CcNode->h_AdTable, validate, level, + h_FmTree, modify); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + else + { + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) + { + err = + FmPcdManipUpdate( + h_FmPcd, + NULL, + h_FmPort, + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, + h_Ad, validate, level, h_FmTree, modify); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + } + } + + return E_OK; } static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam) { switch (p_CcNodeParam->extractCcParams.extractNonHdr.action) { - case(e_FM_PCD_ACTION_EXACT_MATCH): - switch(p_CcNodeParam->extractCcParams.extractNonHdr.src) + case (e_FM_PCD_ACTION_EXACT_MATCH): + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) { - case(e_FM_PCD_EXTRACT_FROM_KEY): + case (e_FM_PCD_EXTRACT_FROM_KEY): return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH; - case(e_FM_PCD_EXTRACT_FROM_HASH): + case (e_FM_PCD_EXTRACT_FROM_HASH): return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH; default: return CC_PRIVATE_INFO_NONE; } - case(e_FM_PCD_ACTION_INDEXED_LOOKUP): - switch(p_CcNodeParam->extractCcParams.extractNonHdr.src) + + case (e_FM_PCD_ACTION_INDEXED_LOOKUP): + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) { - case(e_FM_PCD_EXTRACT_FROM_HASH): + case (e_FM_PCD_EXTRACT_FROM_HASH): return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP; - case(e_FM_PCD_EXTRACT_FROM_FLOW_ID): + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID): return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP; default: - return CC_PRIVATE_INFO_NONE; + return CC_PRIVATE_INFO_NONE; } - default: - break; + + default: + break; } + return CC_PRIVATE_INFO_NONE; } -static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(t_List *p_List) +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst( + t_List *p_List) { - t_CcNodeInformation *p_CcNodeInfo = NULL; - uint32_t intFlags; + t_CcNodeInformation *p_CcNodeInfo = NULL; - intFlags = XX_DisableAllIntr(); - if (!LIST_IsEmpty(p_List)) + if (!NCSW_LIST_IsEmpty(p_List)) { p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next); - LIST_DelAndInit(&p_CcNodeInfo->node); + NCSW_LIST_DelAndInit(&p_CcNodeInfo->node); } - XX_RestoreAllIntr(intFlags); + return p_CcNodeInfo; } -static void ReleaseLst(t_List *p_List) +void ReleaseLst(t_List *p_List) { - t_CcNodeInformation *p_CcNodeInfo = NULL; + t_CcNodeInformation *p_CcNodeInfo = NULL; - if(!LIST_IsEmpty(p_List)) + if (!NCSW_LIST_IsEmpty(p_List)) { p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); while (p_CcNodeInfo) @@ -421,64 +1226,95 @@ static void ReleaseLst(t_List *p_List) p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); } } - LIST_DelAndInit(p_List); + + NCSW_LIST_Del(p_List); } -void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree) +static void DeleteNode(t_FmPcdCcNode *p_CcNode) { - RELEASE_LOCK(((t_FmPcdCcTree *)h_FmPcdCcTree)->lock); -} + uint32_t i; -void FmPcdCcNodeTreeReleaseLock(t_List *p_List) -{ - t_List *p_Pos; - t_CcNodeInformation *p_CcNodeInfo; - t_Handle h_FmPcdCcTree; + if (!p_CcNode) + return; - LIST_FOR_EACH(p_Pos, p_List) + if (p_CcNode->p_GlblMask) { - p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); - h_FmPcdCcTree = p_CcNodeInfo->h_CcNode; - FmPcdCcTreeReleaseLock(h_FmPcdCcTree); + XX_Free(p_CcNode->p_GlblMask); + p_CcNode->p_GlblMask = NULL; } - ReleaseLst(p_List); -} -static void DeleteNode(t_FmPcdCcNode *p_FmPcdCcNode) -{ - if(p_FmPcdCcNode) + if (p_CcNode->h_KeysMatchTable) { - if(p_FmPcdCcNode->p_GlblMask) - { - XX_Free(p_FmPcdCcNode->p_GlblMask); - p_FmPcdCcNode->p_GlblMask = NULL; - } - if(p_FmPcdCcNode->h_KeysMatchTable) - { - FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_KeysMatchTable); - p_FmPcdCcNode->h_KeysMatchTable = NULL; - } - if(p_FmPcdCcNode->h_AdTable) - { - FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_AdTable); - p_FmPcdCcNode->h_AdTable = NULL; - } - - ReleaseLst(&p_FmPcdCcNode->ccPrevNodesLst); - ReleaseLst(&p_FmPcdCcNode->ccTreeIdLst); - ReleaseLst(&p_FmPcdCcNode->ccTreesLst); - - XX_Free(p_FmPcdCcNode); + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), + p_CcNode->h_KeysMatchTable); + p_CcNode->h_KeysMatchTable = NULL; } + + if (p_CcNode->h_AdTable) + { + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), + p_CcNode->h_AdTable); + p_CcNode->h_AdTable = NULL; + } + + if (p_CcNode->h_Ad) + { + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), + p_CcNode->h_Ad); + p_CcNode->h_Ad = NULL; + p_CcNode->h_TmpAd = NULL; + } + + if (p_CcNode->h_StatsFLRs) + { + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), + p_CcNode->h_StatsFLRs); + p_CcNode->h_StatsFLRs = NULL; + } + + if (p_CcNode->h_Spinlock) + { + XX_FreeSpinlock(p_CcNode->h_Spinlock); + p_CcNode->h_Spinlock = NULL; + } + + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */ + if (p_CcNode->isHashBucket + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)) + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters = + p_CcNode->h_PrivMissStatsCounters; + + /* Releasing all currently used statistics objects, including 'miss' entry */ + for (i = 0; i < p_CcNode->numOfKeys + 1; i++) + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj) + PutStatsObj(p_CcNode, + p_CcNode->keyAndNextEngineParams[i].p_StatsObj); + + if (!NCSW_LIST_IsEmpty(&p_CcNode->availableStatsLst)) + { + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); + ASSERT_COND(h_FmMuram); + + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); + } + + NCSW_LIST_Del(&p_CcNode->availableStatsLst); + + ReleaseLst(&p_CcNode->ccPrevNodesLst); + ReleaseLst(&p_CcNode->ccTreeIdLst); + ReleaseLst(&p_CcNode->ccTreesLst); + + XX_Free(p_CcNode); } static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd) { - if(p_FmPcdTree) + if (p_FmPcdTree) { - if(p_FmPcdTree->ccTreeBaseAddr) + if (p_FmPcdTree->ccTreeBaseAddr) { - FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr)); + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr)); p_FmPcdTree->ccTreeBaseAddr = 0; } @@ -488,296 +1324,398 @@ static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd) } } -static void UpdateNodeOwner(t_FmPcdCcNode *p_FmPcdCcNode, bool add) +static void GetCcExtractKeySize(uint8_t parseCodeRealSize, + uint8_t *parseCodeCcSize) { - ASSERT_COND(p_FmPcdCcNode); - - if(add) - p_FmPcdCcNode->owners++; - else - { - ASSERT_COND(p_FmPcdCcNode->owners); - p_FmPcdCcNode->owners--; - } -} - -static void GetCcExtractKeySize(uint8_t parseCodeRealSize, uint8_t *parseCodeCcSize) -{ - if((parseCodeRealSize > 0) && (parseCodeRealSize < 2)) + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2)) *parseCodeCcSize = 1; - else if(parseCodeRealSize == 2) - *parseCodeCcSize = 2; - else if((parseCodeRealSize > 2) && (parseCodeRealSize <= 4)) - *parseCodeCcSize = 4; - else if((parseCodeRealSize > 4) && (parseCodeRealSize <= 8)) - *parseCodeCcSize = 8; - else if((parseCodeRealSize > 8) && (parseCodeRealSize <= 16)) - *parseCodeCcSize = 16; - else if((parseCodeRealSize > 16) && (parseCodeRealSize <= 24)) - *parseCodeCcSize = 24; - else if((parseCodeRealSize > 24) && (parseCodeRealSize <= 32)) - *parseCodeCcSize = 32; - else if((parseCodeRealSize > 32) && (parseCodeRealSize <= 40)) - *parseCodeCcSize = 40; - else if((parseCodeRealSize > 40) && (parseCodeRealSize <= 48)) - *parseCodeCcSize = 48; - else if((parseCodeRealSize > 48) && (parseCodeRealSize <= 56)) - *parseCodeCcSize = 56; else - *parseCodeCcSize = 0; + if (parseCodeRealSize == 2) + *parseCodeCcSize = 2; + else + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4)) + *parseCodeCcSize = 4; + else + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8)) + *parseCodeCcSize = 8; + else + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16)) + *parseCodeCcSize = 16; + else + if ((parseCodeRealSize > 16) + && (parseCodeRealSize <= 24)) + *parseCodeCcSize = 24; + else + if ((parseCodeRealSize > 24) + && (parseCodeRealSize <= 32)) + *parseCodeCcSize = 32; + else + if ((parseCodeRealSize > 32) + && (parseCodeRealSize <= 40)) + *parseCodeCcSize = 40; + else + if ((parseCodeRealSize > 40) + && (parseCodeRealSize <= 48)) + *parseCodeCcSize = 48; + else + if ((parseCodeRealSize > 48) + && (parseCodeRealSize <= 56)) + *parseCodeCcSize = 56; + else + *parseCodeCcSize = 0; } -static void GetSizeHeaderField(e_NetHeaderType hdr,t_FmPcdFields field,uint8_t *parseCodeRealSize) +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field, + uint8_t *parseCodeRealSize) { - switch(hdr) + switch (hdr) { case (HEADER_TYPE_ETH): - switch(field.eth) + switch (field.eth) { - case(NET_HEADER_FIELD_ETH_DA): + case (NET_HEADER_FIELD_ETH_DA): *parseCodeRealSize = 6; break; - case(NET_HEADER_FIELD_ETH_SA): + + case (NET_HEADER_FIELD_ETH_SA): *parseCodeRealSize = 6; break; - case(NET_HEADER_FIELD_ETH_TYPE): + + case (NET_HEADER_FIELD_ETH_TYPE): *parseCodeRealSize = 2; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; - case(HEADER_TYPE_PPPoE): - switch(field.pppoe) + + case (HEADER_TYPE_PPPoE): + switch (field.pppoe) { - case(NET_HEADER_FIELD_PPPoE_PID): + case (NET_HEADER_FIELD_PPPoE_PID): *parseCodeRealSize = 2; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_VLAN): - switch(field.vlan) + switch (field.vlan) { - case(NET_HEADER_FIELD_VLAN_TCI): + case (NET_HEADER_FIELD_VLAN_TCI): *parseCodeRealSize = 2; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_MPLS): - switch(field.mpls) + switch (field.mpls) { - case(NET_HEADER_FIELD_MPLS_LABEL_STACK): + case (NET_HEADER_FIELD_MPLS_LABEL_STACK): *parseCodeRealSize = 4; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_IPv4): - switch(field.ipv4) + switch (field.ipv4) { - case(NET_HEADER_FIELD_IPv4_DST_IP): - case(NET_HEADER_FIELD_IPv4_SRC_IP): + case (NET_HEADER_FIELD_IPv4_DST_IP): + case (NET_HEADER_FIELD_IPv4_SRC_IP): *parseCodeRealSize = 4; break; - case(NET_HEADER_FIELD_IPv4_TOS): - case(NET_HEADER_FIELD_IPv4_PROTO): + + case (NET_HEADER_FIELD_IPv4_TOS): + case (NET_HEADER_FIELD_IPv4_PROTO): *parseCodeRealSize = 1; break; - case(NET_HEADER_FIELD_IPv4_DST_IP | NET_HEADER_FIELD_IPv4_SRC_IP): + + case (NET_HEADER_FIELD_IPv4_DST_IP + | NET_HEADER_FIELD_IPv4_SRC_IP): *parseCodeRealSize = 8; break; - case(NET_HEADER_FIELD_IPv4_TTL): + + case (NET_HEADER_FIELD_IPv4_TTL): *parseCodeRealSize = 1; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_IPv6): - switch(field.ipv6) + switch (field.ipv6) { - case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): - *parseCodeRealSize = 4; + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL + | NET_HEADER_FIELD_IPv6_TC): + *parseCodeRealSize = 4; break; - case(NET_HEADER_FIELD_IPv6_NEXT_HDR): - case(NET_HEADER_FIELD_IPv6_HOP_LIMIT): - *parseCodeRealSize = 1; + + case (NET_HEADER_FIELD_IPv6_NEXT_HDR): + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): + *parseCodeRealSize = 1; break; - case(NET_HEADER_FIELD_IPv6_DST_IP): - case(NET_HEADER_FIELD_IPv6_SRC_IP): - *parseCodeRealSize = 16; + + case (NET_HEADER_FIELD_IPv6_DST_IP): + case (NET_HEADER_FIELD_IPv6_SRC_IP): + *parseCodeRealSize = 16; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; - case (HEADER_TYPE_GRE): - switch(field.gre) + + case (HEADER_TYPE_IP): + switch (field.ip) { - case(NET_HEADER_FIELD_GRE_TYPE): - *parseCodeRealSize = 2; + case (NET_HEADER_FIELD_IP_DSCP): + case (NET_HEADER_FIELD_IP_PROTO): + *parseCodeRealSize = 1; break; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); + *parseCodeRealSize = CC_SIZE_ILLEGAL; + break; + } + break; + + case (HEADER_TYPE_GRE): + switch (field.gre) + { + case (NET_HEADER_FIELD_GRE_TYPE): + *parseCodeRealSize = 2; + break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_MINENCAP): - switch(field.minencap) + switch (field.minencap) { - case(NET_HEADER_FIELD_MINENCAP_TYPE): - *parseCodeRealSize = 1; + case (NET_HEADER_FIELD_MINENCAP_TYPE): + *parseCodeRealSize = 1; break; - case(NET_HEADER_FIELD_MINENCAP_DST_IP): - case(NET_HEADER_FIELD_MINENCAP_SRC_IP): - *parseCodeRealSize = 4; + + case (NET_HEADER_FIELD_MINENCAP_DST_IP): + case (NET_HEADER_FIELD_MINENCAP_SRC_IP): + *parseCodeRealSize = 4; break; - case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP): - *parseCodeRealSize = 8; + + case (NET_HEADER_FIELD_MINENCAP_SRC_IP + | NET_HEADER_FIELD_MINENCAP_DST_IP): + *parseCodeRealSize = 8; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_TCP): - switch(field.tcp) + switch (field.tcp) { - case(NET_HEADER_FIELD_TCP_PORT_SRC): - case(NET_HEADER_FIELD_TCP_PORT_DST): - *parseCodeRealSize = 2; + case (NET_HEADER_FIELD_TCP_PORT_SRC): + case (NET_HEADER_FIELD_TCP_PORT_DST): + *parseCodeRealSize = 2; break; - case(NET_HEADER_FIELD_TCP_PORT_SRC | NET_HEADER_FIELD_TCP_PORT_DST): - *parseCodeRealSize = 4; + + case (NET_HEADER_FIELD_TCP_PORT_SRC + | NET_HEADER_FIELD_TCP_PORT_DST): + *parseCodeRealSize = 4; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; + case (HEADER_TYPE_UDP): - switch(field.udp) + switch (field.udp) { - case(NET_HEADER_FIELD_UDP_PORT_SRC): - case(NET_HEADER_FIELD_UDP_PORT_DST): - *parseCodeRealSize = 2; + case (NET_HEADER_FIELD_UDP_PORT_SRC): + case (NET_HEADER_FIELD_UDP_PORT_DST): + *parseCodeRealSize = 2; break; - case(NET_HEADER_FIELD_UDP_PORT_SRC | NET_HEADER_FIELD_UDP_PORT_DST): - *parseCodeRealSize = 4; + + case (NET_HEADER_FIELD_UDP_PORT_SRC + | NET_HEADER_FIELD_UDP_PORT_DST): + *parseCodeRealSize = 4; break; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } break; - default: + + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10")); *parseCodeRealSize = CC_SIZE_ILLEGAL; break; } } -static t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +t_Error ValidateNextEngineParams( + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, + e_FmPcdCcStatsMode statsMode) { - uint16_t absoluteProfileId; - t_Error err = E_OK; - uint8_t relativeSchemeId; + uint16_t absoluteProfileId; + t_Error err = E_OK; + uint8_t relativeSchemeId; - switch(p_FmPcdCcNextEngineParams->nextEngine) + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE) + && (p_FmPcdCcNextEngineParams->statisticsEn)) + RETURN_ERROR( + MAJOR, + E_CONFLICT, + ("Statistics are requested for a key, but statistics mode was set" + "to 'NONE' upon initialization")); + + switch (p_FmPcdCcNextEngineParams->nextEngine) { - case(e_FM_PCD_INVALID): - err = E_NOT_SUPPORTED; - break; - case(e_FM_PCD_DONE): - if(p_FmPcdCcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME) - { - if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid && - !p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not defined fqid for control flow for BMI next engine ")); - if(p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid & ~0x00FFFFFF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidForCtrlFlow must be between 1 and 2^24-1")); - } + case (e_FM_PCD_INVALID): + err = E_NOT_SUPPORTED; break; - case(e_FM_PCD_KG): - relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, (uint8_t)(PTR_TO_UINT(p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)-1)); - if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) - RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if(!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not valid schemeIndex in KG next engine param")); - if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("CC Node may point only to a scheme that is always direct.")); - break; - case(e_FM_PCD_PLCR): - if(p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams) + case (e_FM_PCD_DONE): + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action + == e_FM_PCD_ENQ_FRAME) + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) { - /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */ - if(p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile) - { - err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, &absoluteProfileId); - if(err) - RETURN_ERROR(MAJOR, err, ("Shared profile offset is out of range")); - if(!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile")); - } - else - { - } - /* TODO - add check according to the revision of the chip. - if(!p_FmPcdCcNextEngineParams->params.plcrParams.newFqid || - (p_FmPcdCcNextEngineParams->params.plcrParams.newFqid & ~0x00FFFFFF)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("newFqid must be between 1 and 2^24-1")); - */ + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid) + RETURN_ERROR( + MAJOR, + E_CONFLICT, + ("When overrideFqid is set, newFqid must not be zero")); + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid + & ~0x00FFFFFF) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("fqidForCtrlFlow must be between 1 and 2^24-1")); } break; - case(e_FM_PCD_CC): - if(!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) - RETURN_ERROR(MAJOR, E_NULL_POINTER, ("handler to next Node is NULL")); + + case (e_FM_PCD_KG): + relativeSchemeId = + FmPcdKgGetRelativeSchemeId( + h_FmPcd, + FmPcdKgGetSchemeId( + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)); + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); + if (!FmPcdKgIsSchemeValidSw( + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("not valid schemeIndex in KG next engine param")); + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("CC Node may point only to a scheme that is always direct.")); break; + + case (e_FM_PCD_PLCR): + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams) + { + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile) + { + err = + FmPcdPlcrGetAbsoluteIdByProfileParams( + h_FmPcd, + e_FM_PCD_PLCR_SHARED, + NULL, + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, + &absoluteProfileId); + if (err) + RETURN_ERROR(MAJOR, err, + ("Shared profile offset is out of range")); + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Invalid profile")); + } + } + break; + + case (e_FM_PCD_HASH): + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC; + case (e_FM_PCD_CC): + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) + RETURN_ERROR(MAJOR, E_NULL_POINTER, + ("handler to next Node is NULL")); + break; + +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_FR): + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) + err = E_NOT_SUPPORTED; + break; +#endif /* (DPAA_VERSION >= 11) */ + default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine is not correct")); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Next engine is not correct")); } + + return err; } -static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset, bool fromIc, ccPrivateInfo_t icCode) +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, + uint32_t offset, bool glblMask, + uint8_t *parseArrayOffset, bool fromIc, + ccPrivateInfo_t icCode) { - if(!fromIc) + if (!fromIc) { - switch(src) + switch (src) { - case(e_FM_PCD_EXTRACT_FROM_FRAME_START): - if(glblMask) - return CC_PC_GENERIC_WITH_MASK ; + case (e_FM_PCD_EXTRACT_FROM_FRAME_START): + if (glblMask) + return CC_PC_GENERIC_WITH_MASK; else - return CC_PC_GENERIC_WITHOUT_MASK; - case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): + return CC_PC_GENERIC_WITHOUT_MASK; + + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; - if(offset) + if (offset) return CC_PR_OFFSET; else return CC_PR_WITHOUT_OFFSET; + default: REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); return CC_PC_ILLEGAL; @@ -787,403 +1725,548 @@ static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glb { switch (icCode) { - case(CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH): - *parseArrayOffset = 0x50; - return CC_PC_GENERIC_IC_GMASK; - case(CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH): - *parseArrayOffset = 0x48; - return CC_PC_GENERIC_IC_GMASK; - case(CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP): + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH): + *parseArrayOffset = 0x50; + return CC_PC_GENERIC_IC_GMASK; + + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH): *parseArrayOffset = 0x48; - return CC_PC_GENERIC_IC_HASH_INDEXED; - case(CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP): + return CC_PC_GENERIC_IC_GMASK; + + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP): + *parseArrayOffset = 0x48; + return CC_PC_GENERIC_IC_HASH_INDEXED; + + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP): *parseArrayOffset = 0x16; - return CC_PC_GENERIC_IC_HASH_INDEXED; + return CC_PC_GENERIC_IC_HASH_INDEXED; + default: REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); break; } } + return CC_PC_ILLEGAL; } -static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field) +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, + t_FmPcdFields field) { + switch (hdr) + { + case (HEADER_TYPE_NONE): + ASSERT_COND(FALSE); + return CC_PC_ILLEGAL; - switch(hdr) - { - case(HEADER_TYPE_NONE): - ASSERT_COND(FALSE); - return CC_PC_ILLEGAL; - - case(HEADER_TYPE_ETH): - switch(field.eth) - { - case(NET_HEADER_FIELD_ETH_DA): - return CC_PC_FF_MACDST; - case(NET_HEADER_FIELD_ETH_SA): - return CC_PC_FF_MACSRC; - case(NET_HEADER_FIELD_ETH_TYPE): - return CC_PC_FF_ETYPE; - default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); - return CC_PC_ILLEGAL; - } - - case(HEADER_TYPE_VLAN): - switch(field.vlan) + case (HEADER_TYPE_ETH): + switch (field.eth) { - case(NET_HEADER_FIELD_VLAN_TCI): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_ETH_DA): + return CC_PC_FF_MACDST; + case (NET_HEADER_FIELD_ETH_SA): + return CC_PC_FF_MACSRC; + case (NET_HEADER_FIELD_ETH_TYPE): + return CC_PC_FF_ETYPE; + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; + } + + case (HEADER_TYPE_VLAN): + switch (field.vlan) + { + case (NET_HEADER_FIELD_VLAN_TCI): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_TCI1; - if(index == e_FM_PCD_HDR_INDEX_LAST) + if (index == e_FM_PCD_HDR_INDEX_LAST) return CC_PC_FF_TCI2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); - return CC_PC_ILLEGAL; + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; } - case(HEADER_TYPE_MPLS): - switch(field.mpls) + case (HEADER_TYPE_MPLS): + switch (field.mpls) { - case(NET_HEADER_FIELD_MPLS_LABEL_STACK): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_MPLS_LABEL_STACK): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_MPLS1; - if(index == e_FM_PCD_HDR_INDEX_LAST) + if (index == e_FM_PCD_HDR_INDEX_LAST) return CC_PC_FF_MPLS_LAST; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index")); return CC_PC_ILLEGAL; - default: + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; - } + } - case(HEADER_TYPE_IPv4): - switch(field.ipv4) + case (HEADER_TYPE_IPv4): + switch (field.ipv4) { - case(NET_HEADER_FIELD_IPv4_DST_IP): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv4_DST_IP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV4DST1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV4DST2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv4_TOS): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv4_TOS): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV4IPTOS_TC1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV4IPTOS_TC2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv4_PROTO): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv4_PROTO): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV4PTYPE1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV4PTYPE2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv4_SRC_IP): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv4_SRC_IP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV4SRC1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV4SRC2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv4_SRC_IP | NET_HEADER_FIELD_IPv4_DST_IP): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv4_SRC_IP + | NET_HEADER_FIELD_IPv4_DST_IP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV4SRC1_IPV4DST1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV4SRC2_IPV4DST2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv4_TTL): + case (NET_HEADER_FIELD_IPv4_TTL): return CC_PC_FF_IPV4TTL; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } - case(HEADER_TYPE_IPv6): - switch(field.ipv6) + case (HEADER_TYPE_IPv6): + switch (field.ipv6) { - case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL + | NET_HEADER_FIELD_IPv6_TC): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv6_NEXT_HDR): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + + case (NET_HEADER_FIELD_IPv6_NEXT_HDR): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV6PTYPE1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV6PTYPE2; + if (index == e_FM_PCD_HDR_INDEX_LAST) + return CC_PC_FF_IPPID; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv6_DST_IP): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + + case (NET_HEADER_FIELD_IPv6_DST_IP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV6DST1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV6DST2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv6_SRC_IP): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + + case (NET_HEADER_FIELD_IPv6_SRC_IP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) return CC_PC_FF_IPV6SRC1; - if(index == e_FM_PCD_HDR_INDEX_2) + if (index == e_FM_PCD_HDR_INDEX_2) return CC_PC_FF_IPV6SRC2; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return CC_PC_ILLEGAL; - case(NET_HEADER_FIELD_IPv6_HOP_LIMIT): + + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): return CC_PC_FF_IPV6HOP_LIMIT; - default: + + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } - case(HEADER_TYPE_GRE): - switch(field.gre) + case (HEADER_TYPE_IP): + switch (field.ip) { - case(NET_HEADER_FIELD_GRE_TYPE): + case (NET_HEADER_FIELD_IP_DSCP): + if ((index == e_FM_PCD_HDR_INDEX_NONE) + || (index == e_FM_PCD_HDR_INDEX_1)) + return CC_PC_FF_IPDSCP; + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); + return CC_PC_ILLEGAL; + + case (NET_HEADER_FIELD_IP_PROTO): + if (index == e_FM_PCD_HDR_INDEX_LAST) + return CC_PC_FF_IPPID; + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); + return CC_PC_ILLEGAL; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; + } + + case (HEADER_TYPE_GRE): + switch (field.gre) + { + case (NET_HEADER_FIELD_GRE_TYPE): return CC_PC_FF_GREPTYPE; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; - } - case(HEADER_TYPE_MINENCAP): - switch(field.minencap) + } + + case (HEADER_TYPE_MINENCAP): + switch (field.minencap) { - case(NET_HEADER_FIELD_MINENCAP_TYPE): + case (NET_HEADER_FIELD_MINENCAP_TYPE): return CC_PC_FF_MINENCAP_PTYPE; - case(NET_HEADER_FIELD_MINENCAP_DST_IP): + + case (NET_HEADER_FIELD_MINENCAP_DST_IP): return CC_PC_FF_MINENCAP_IPDST; - case(NET_HEADER_FIELD_MINENCAP_SRC_IP): + + case (NET_HEADER_FIELD_MINENCAP_SRC_IP): return CC_PC_FF_MINENCAP_IPSRC; - case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP): + + case (NET_HEADER_FIELD_MINENCAP_SRC_IP + | NET_HEADER_FIELD_MINENCAP_DST_IP): return CC_PC_FF_MINENCAP_IPSRC_IPDST; - default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); - return CC_PC_ILLEGAL; - } - case(HEADER_TYPE_TCP): - switch(field.tcp) - { - case(NET_HEADER_FIELD_TCP_PORT_SRC): - return CC_PC_FF_L4PSRC; - case(NET_HEADER_FIELD_TCP_PORT_DST): - return CC_PC_FF_L4PDST; - case(NET_HEADER_FIELD_TCP_PORT_DST | NET_HEADER_FIELD_TCP_PORT_SRC): - return CC_PC_FF_L4PSRC_L4PDST; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } - case(HEADER_TYPE_PPPoE): - switch(field.pppoe) + case (HEADER_TYPE_TCP): + switch (field.tcp) { - case(NET_HEADER_FIELD_PPPoE_PID): + case (NET_HEADER_FIELD_TCP_PORT_SRC): + return CC_PC_FF_L4PSRC; + + case (NET_HEADER_FIELD_TCP_PORT_DST): + return CC_PC_FF_L4PDST; + + case (NET_HEADER_FIELD_TCP_PORT_DST + | NET_HEADER_FIELD_TCP_PORT_SRC): + return CC_PC_FF_L4PSRC_L4PDST; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; + } + + case (HEADER_TYPE_PPPoE): + switch (field.pppoe) + { + case (NET_HEADER_FIELD_PPPoE_PID): return CC_PC_FF_PPPPID; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } - case(HEADER_TYPE_UDP): - switch(field.udp) + case (HEADER_TYPE_UDP): + switch (field.udp) { - case(NET_HEADER_FIELD_UDP_PORT_SRC): + case (NET_HEADER_FIELD_UDP_PORT_SRC): return CC_PC_FF_L4PSRC; - case(NET_HEADER_FIELD_UDP_PORT_DST): + + case (NET_HEADER_FIELD_UDP_PORT_DST): return CC_PC_FF_L4PDST; - case(NET_HEADER_FIELD_UDP_PORT_DST | NET_HEADER_FIELD_UDP_PORT_SRC): + + case (NET_HEADER_FIELD_UDP_PORT_DST + | NET_HEADER_FIELD_UDP_PORT_SRC): return CC_PC_FF_L4PSRC_L4PDST; + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } - default: + default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return CC_PC_ILLEGAL; } } -static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset) +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, + uint32_t offset, bool glblMask, + uint8_t *parseArrayOffset) { bool offsetRelevant = FALSE; - if(offset) + if (offset) offsetRelevant = TRUE; - switch(hdr){ - case(HEADER_TYPE_NONE): + switch (hdr) + { + case (HEADER_TYPE_NONE): ASSERT_COND(FALSE); return CC_PC_ILLEGAL; - case(HEADER_TYPE_ETH): + + case (HEADER_TYPE_ETH): *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; break; - case(HEADER_TYPE_USER_DEFINED_SHIM1): - if(offset || glblMask) + + case (HEADER_TYPE_USER_DEFINED_SHIM1): + if (offset || glblMask) *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; else return CC_PC_PR_SHIM1; break; - case(HEADER_TYPE_USER_DEFINED_SHIM2): - if(offset || glblMask) + + case (HEADER_TYPE_USER_DEFINED_SHIM2): + if (offset || glblMask) *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; else return CC_PC_PR_SHIM2; break; - case(HEADER_TYPE_LLC_SNAP): + + case (HEADER_TYPE_LLC_SNAP): *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; break; - case(HEADER_TYPE_PPPoE): + + case (HEADER_TYPE_PPPoE): *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; break; - case(HEADER_TYPE_MPLS): - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) - *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; + + case (HEADER_TYPE_MPLS): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; else { REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); return CC_PC_ILLEGAL; } - break; - case(HEADER_TYPE_IPv4): - case(HEADER_TYPE_IPv6): - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_IP1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_2) - *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; - else - { - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); - return CC_PC_ILLEGAL; - - } - break; - case(HEADER_TYPE_MINENCAP): - *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; - break; - case(HEADER_TYPE_GRE): - *parseArrayOffset = CC_PC_PR_GRE_OFFSET; - break; - case(HEADER_TYPE_TCP): - case(HEADER_TYPE_UDP): - case(HEADER_TYPE_IPSEC_AH): - case(HEADER_TYPE_IPSEC_ESP): - case(HEADER_TYPE_DCCP): - case(HEADER_TYPE_SCTP): - *parseArrayOffset = CC_PC_PR_L4_OFFSET; - break; - - default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation")); - return CC_PC_ILLEGAL; - } - - if(offsetRelevant) - return CC_PR_OFFSET; - else - return CC_PR_WITHOUT_OFFSET; -} - -static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, uint32_t offset, uint8_t *parseArrayOffset, e_FmPcdHdrIndex hdrIndex) -{ - bool offsetRelevant = FALSE; - - if(offset) - offsetRelevant = TRUE; - - switch(hdr) - { - case(HEADER_TYPE_NONE): - ASSERT_COND(FALSE); - case(HEADER_TYPE_ETH): - switch(field.eth) - { - case(NET_HEADER_FIELD_ETH_TYPE): - *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; - break; - default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); - return CC_PC_ILLEGAL; - } break; - case(HEADER_TYPE_VLAN): - switch(field.vlan) - { - case(NET_HEADER_FIELD_VLAN_TCI): - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) - *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; - break; - default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + + case (HEADER_TYPE_IPv4): + case (HEADER_TYPE_IPv6): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_IP1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_2) + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; + else + { + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); return CC_PC_ILLEGAL; - } - break; + } + break; + + case (HEADER_TYPE_MINENCAP): + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; + break; + + case (HEADER_TYPE_GRE): + *parseArrayOffset = CC_PC_PR_GRE_OFFSET; + break; + + case (HEADER_TYPE_TCP): + case (HEADER_TYPE_UDP): + case (HEADER_TYPE_IPSEC_AH): + case (HEADER_TYPE_IPSEC_ESP): + case (HEADER_TYPE_DCCP): + case (HEADER_TYPE_SCTP): + *parseArrayOffset = CC_PC_PR_L4_OFFSET; + break; + default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header ")); + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation")); return CC_PC_ILLEGAL; } - if(offsetRelevant) + + if (offsetRelevant) return CC_PR_OFFSET; else return CC_PR_WITHOUT_OFFSET; } -static void FillAdOfTypeResult(t_Handle p_Ad, t_FmPcd *p_FmPcd, t_FmPcdCcNextEngineParams *p_CcNextEngineParams) +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, + uint32_t offset, uint8_t *parseArrayOffset, + e_FmPcdHdrIndex hdrIndex) { - t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad; - uint32_t tmp = 0, tmpNia = 0; - uint16_t profileId; - t_Handle p_AdNewPtr = NULL; + bool offsetRelevant = FALSE; + if (offset) + offsetRelevant = TRUE; + + switch (hdr) + { + case (HEADER_TYPE_NONE): + ASSERT_COND(FALSE); + break; + case (HEADER_TYPE_ETH): + switch (field.eth) + { + case (NET_HEADER_FIELD_ETH_TYPE): + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; + break; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; + } + break; + + case (HEADER_TYPE_VLAN): + switch (field.vlan) + { + case (NET_HEADER_FIELD_VLAN_TCI): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; + break; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return CC_PC_ILLEGAL; + } + break; + + default: + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header ")); + return CC_PC_ILLEGAL; + } + + if (offsetRelevant) + return CC_PR_OFFSET; + else + return CC_PR_WITHOUT_OFFSET; +} + +static void FillAdOfTypeResult(t_Handle h_Ad, + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, + t_FmPcd *p_FmPcd, + t_FmPcdCcNextEngineParams *p_CcNextEngineParams) +{ + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad; + t_Handle h_TmpAd; + uint32_t tmp = 0, tmpNia = 0; + uint16_t profileId; + t_Handle p_AdNewPtr = NULL; + t_Error err = E_OK; + + /* There are 3 cases handled in this routine of building a "result" type AD. + * Case 1: No Manip. The action descriptor is built within the match table. + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized + * either in the FmPcdManipUpdateAdResultForCc routine or it was already + * initialized and returned here. + * p_AdResult (within the match table) will be initialized after + * this routine returns and point to the existing AD. + * Case 3: Manip exists. The action descriptor is built within the match table. + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr. + * + * If statistics were enabled and the statistics mode of this node requires + * a statistics Ad, it will be placed after the result Ad and before the + * manip Ad, if manip Ad exists here. + */ + + /* As default, the "new" ptr is the current one. i.e. the content of the result + * AD will be written into the match table itself (case (1))*/ p_AdNewPtr = p_AdResult; -#ifdef FM_PCD_CC_MANIP - if (p_CcNextEngineParams->h_Manip) - FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, p_Ad, &p_AdNewPtr); -#endif /* FM_PCD_CC_MANIP */ - - if(p_AdNewPtr) + /* Initialize an action descriptor, if current statistics mode requires an Ad */ + if (p_FmPcdCcStatsParams) { - switch(p_CcNextEngineParams->nextEngine) + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); + + /* Swapping addresses between statistics Ad and the current lookup AD addresses */ + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; + p_FmPcdCcStatsParams->h_StatsAd = h_Ad; + h_Ad = h_TmpAd; + + p_AdNewPtr = h_Ad; + p_AdResult = h_Ad; + + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); + } + + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */ + if (p_CcNextEngineParams->h_Manip) + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, + p_CcNextEngineParams, h_Ad, &p_AdNewPtr); + + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ + if (p_AdNewPtr) + { + /* case (1) and (2) */ + switch (p_CcNextEngineParams->nextEngine) { - case(e_FM_PCD_DONE): - if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME) + case (e_FM_PCD_DONE): + if (p_CcNextEngineParams->params.enqueueParams.action + == e_FM_PCD_ENQ_FRAME) { - if(p_CcNextEngineParams->params.enqueueParams.overrideFqid) + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid) { - tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; - tmp |= p_CcNextEngineParams->params.enqueueParams.newFqid; + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; + tmp |= + p_CcNextEngineParams->params.enqueueParams.newFqid; +#if (DPAA_VERSION >= 11) + tmp |= + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId + & FM_PCD_AD_RESULT_VSP_MASK) + << FM_PCD_AD_RESULT_VSP_SHIFT; +#endif /* (DPAA_VERSION >= 11) */ } else { - tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; - tmp |= FM_PCD_AD_RESULT_PLCR_DIS; + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; + tmp |= FM_PCD_AD_RESULT_PLCR_DIS; } } - if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_DROP_FRAME) - tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_DISCARD); - else - tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_ENQ_FRAME); - if(p_CcNextEngineParams->params.enqueueParams.statisticsEn) - tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN; + + if (p_CcNextEngineParams->params.enqueueParams.action + == e_FM_PCD_DROP_FRAME) + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); + else + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); break; - case(e_FM_PCD_KG): - if(p_CcNextEngineParams->params.kgParams.overrideFqid) + + case (e_FM_PCD_KG): + if (p_CcNextEngineParams->params.kgParams.overrideFqid) { tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; tmp |= p_CcNextEngineParams->params.kgParams.newFqid; +#if (DPAA_VERSION >= 11) + tmp |= + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId + & FM_PCD_AD_RESULT_VSP_MASK) + << FM_PCD_AD_RESULT_VSP_SHIFT; +#endif /* (DPAA_VERSION >= 11) */ } else { @@ -1192,790 +2275,1206 @@ static void FillAdOfTypeResult(t_Handle p_Ad, t_FmPcd *p_FmPcd, t_FmPcdCcNextEng } tmpNia = NIA_KG_DIRECT; tmpNia |= NIA_ENG_KG; - tmpNia |= (uint8_t)(PTR_TO_UINT(p_CcNextEngineParams->params.kgParams.h_DirectScheme)-1); - if(p_CcNextEngineParams->params.kgParams.statisticsEn) - tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN; - break; - case(e_FM_PCD_PLCR): - tmp = 0; - if(p_CcNextEngineParams->params.plcrParams.overrideParams) + tmpNia |= NIA_KG_CC_EN; + tmpNia |= FmPcdKgGetSchemeId( + p_CcNextEngineParams->params.kgParams.h_DirectScheme); + break; + + case (e_FM_PCD_PLCR): + if (p_CcNextEngineParams->params.plcrParams.overrideParams) { tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; - /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */ - if(p_CcNextEngineParams->params.plcrParams.sharedProfile) + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ + if (p_CcNextEngineParams->params.plcrParams.sharedProfile) { tmpNia |= NIA_PLCR_ABSOLUTE; - FmPcdPlcrGetAbsoluteProfileId((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, &profileId); + err = FmPcdPlcrGetAbsoluteIdByProfileParams( + (t_Handle)p_FmPcd, + e_FM_PCD_PLCR_SHARED, + NULL, + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, + &profileId); + if (err != E_OK) + return; + } else - profileId = p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; + profileId = + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; tmp |= p_CcNextEngineParams->params.plcrParams.newFqid; - WRITE_UINT32(p_AdResult->plcrProfile,(uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT)); +#if (DPAA_VERSION >= 11) + tmp |= + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId + & FM_PCD_AD_RESULT_VSP_MASK) + << FM_PCD_AD_RESULT_VSP_SHIFT; +#endif /* (DPAA_VERSION >= 11) */ + WRITE_UINT32( + p_AdResult->plcrProfile, + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT)); } else - tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; - tmpNia |= NIA_ENG_PLCR | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; - if(p_CcNextEngineParams->params.kgParams.statisticsEn) - tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN; - break; + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; + + tmpNia |= + NIA_ENG_PLCR + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; + break; + default: return; - } - WRITE_UINT32(p_AdResult->fqid, tmp); + }WRITE_UINT32(p_AdResult->fqid, tmp); -#ifdef FM_PCD_CC_MANIP - if(p_CcNextEngineParams->h_Manip) + if (p_CcNextEngineParams->h_Manip) { tmp = GET_UINT32(p_AdResult->plcrProfile); - tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) - (p_FmPcd->physicalMuramBase)) >> 4; + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) + - (p_FmPcd->physicalMuramBase)) >> 4; WRITE_UINT32(p_AdResult->plcrProfile, tmp); tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE; tmpNia |= FM_PCD_AD_RESULT_NADEN; } -#endif /* FM_PCD_CC_MANIP */ +#if (DPAA_VERSION >= 11) + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE; +#endif /* (DPAA_VERSION >= 11) */ WRITE_UINT32(p_AdResult->nia, tmpNia); } } -static void FillAdOfTypeContLookup(t_Handle p_Ad, t_Handle h_FmPcd, t_Handle p_FmPcdCcNode, t_Handle h_Manip) +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_Handle h_FmTree, + bool validate) { - t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_FmPcdCcNode; - t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)p_Ad; - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t tmpReg32; - t_Handle p_AdNewPtr = NULL; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; - p_AdNewPtr = p_AdContLookup; - -#ifdef FM_PCD_CC_MANIP - if (h_Manip) - FmPcdManipUpdateAdContLookupForCc(h_Manip, p_Ad, &p_AdNewPtr, (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))); -#else - UNUSED(h_Manip); -#endif /* FM_PCD_CC_MANIP */ - - if(p_AdNewPtr) - { - tmpReg32 = 0; - tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; - tmpReg32 |= p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : 0; - tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase); - WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32); - - tmpReg32 = 0; - tmpReg32 |= p_Node->numOfKeys << 24; - tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0); - tmpReg32 |= p_Node->h_KeysMatchTable ? - (uint32_t)(XX_VirtToPhys(p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : 0; - WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32); - - tmpReg32 = 0; - tmpReg32 |= p_Node->prsArrayOffset << 24; - tmpReg32 |= p_Node->offset << 16; - tmpReg32 |= p_Node->parseCode; - WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32); - - Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, CC_GLBL_MASK_SIZE); - } -} - -static void NextStepAd(t_Handle p_Ad, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_FmPcd *p_FmPcd) -{ - switch(p_FmPcdCcNextEngineParams->nextEngine) - { - case(e_FM_PCD_KG): - case(e_FM_PCD_PLCR): - case(e_FM_PCD_DONE): - FillAdOfTypeResult(p_Ad, p_FmPcd, p_FmPcdCcNextEngineParams); - break; - case(e_FM_PCD_CC): - FillAdOfTypeContLookup(p_Ad, - p_FmPcd, - p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, -#ifdef FM_PCD_CC_MANIP - p_FmPcdCcNextEngineParams->h_Manip -#else - NULL -#endif /* FM_PCD_CC_MANIP */ - ); - UpdateNodeOwner (p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, - TRUE); - break; - default: - return; - } + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, + p_CcTree->keyAndNextEngineParams, + p_CcTree->numOfEntries, + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0, + h_FmTree, FALSE); } -static void ReleaseNewNodeCommonPart(t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) +static void ReleaseNewNodeCommonPart( + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) { - if(p_AdditionalInfo->p_AdTableNew) - FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_AdTableNew); - if(p_AdditionalInfo->p_KeysMatchTableNew) - FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_KeysMatchTableNew); + if (p_AdditionalInfo->p_AdTableNew) + FM_MURAM_FreeMem( + FmPcdGetMuramHandle( + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), + p_AdditionalInfo->p_AdTableNew); + + if (p_AdditionalInfo->p_KeysMatchTableNew) + FM_MURAM_FreeMem( + FmPcdGetMuramHandle( + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), + p_AdditionalInfo->p_KeysMatchTableNew); } -static t_Error UpdateGblMask(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keySize, uint8_t *p_Mask) +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize, + uint8_t *p_Mask) { - if (p_Mask && - !p_FmPcdCcNode->glblMaskUpdated && - (keySize <= 4) && - !p_FmPcdCcNode->lclMask ) + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize; + + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4) + && !p_CcNode->lclMask) { - memcpy(p_FmPcdCcNode->p_GlblMask, p_Mask, (sizeof(uint8_t))*keySize); - p_FmPcdCcNode->glblMaskUpdated = TRUE; - p_FmPcdCcNode->glblMaskSize = 4; - } - else if (p_Mask && - (keySize <= 4) && - !p_FmPcdCcNode->lclMask) - { - if (memcmp(p_FmPcdCcNode->p_GlblMask, p_Mask, keySize) != 0) + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1) + && (p_CcNode->parseCode != CC_PC_FF_TCI2) + && (p_CcNode->parseCode != CC_PC_FF_MPLS1) + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)) { - p_FmPcdCcNode->lclMask = TRUE; - p_FmPcdCcNode->glblMaskSize = 0; + p_CcNode->glblMaskSize = 0; + p_CcNode->lclMask = TRUE; + } + else + { + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize); + p_CcNode->glblMaskUpdated = TRUE; + p_CcNode->glblMaskSize = 4; } } - else if (!p_Mask && (p_FmPcdCcNode->glblMaskUpdated) && (keySize <= 4)) - { - uint32_t tmpMask = 0xffffffff; - if (memcmp(p_FmPcdCcNode->p_GlblMask, &tmpMask, 4) != 0) + else + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask) { - p_FmPcdCcNode->lclMask = TRUE; - p_FmPcdCcNode->glblMaskSize = 0; - } - } - else if (p_Mask) - { - p_FmPcdCcNode->lclMask = TRUE; - p_FmPcdCcNode->glblMaskSize = 0; - } - - return E_OK; -} - -static t_Error BuildNewNodeCommonPart(t_FmPcdCcNode *p_FmPcdCcNode, - int *size, - t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -{ - - p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), - (uint32_t)( (p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE), - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_AdditionalInfo->p_AdTableNew) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table ")); - - IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE)); - - if(p_FmPcdCcNode->lclMask) - *size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction; - else - *size = p_FmPcdCcNode->ccKeySizeAccExtraction; - - p_AdditionalInfo->p_KeysMatchTableNew = - (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), - (uint32_t)(*size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)), - FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); - if(!p_AdditionalInfo->p_KeysMatchTableNew) - { - FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_AdditionalInfo->p_AdTableNew); - p_AdditionalInfo->p_AdTableNew = NULL; - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table")); - } - IOMemSet32((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)); - - p_AdditionalInfo->p_AdTableOld = p_FmPcdCcNode->h_AdTable; - p_AdditionalInfo->p_KeysMatchTableOld = p_FmPcdCcNode->h_KeysMatchTable; - - return E_OK; -} - -static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(t_Handle h_FmPcd ,t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdCcKeyParams *p_KeyParams,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add) -{ - t_Error err = E_OK; - t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; - t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; - int size; - int i = 0, j = 0; - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t requiredAction = 0; - bool prvLclMask; - t_CcNodeInformation *p_CcNodeInformation; - t_List *p_Pos; - - /*check that new NIA is legal*/ - err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - prvLclMask = p_FmPcdCcNode->lclMask; - - /*check that new key is not require update of localMask*/ - err = UpdateGblMask(p_FmPcdCcNode, - p_FmPcdCcNode->ccKeySizeAccExtraction, - p_KeyParams->p_Mask); - if (err != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - - /*update internal data structure for next engine per index (index - key)*/ - memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); - - /*update numOfKeys*/ - if(add) - p_AdditionalInfo->numOfKeys = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1); - else - p_AdditionalInfo->numOfKeys = (uint8_t)p_FmPcdCcNode->numOfKeys; - /*function which build in the memory new KeyTbl, AdTbl*/ - err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - -#ifdef FM_PCD_CC_MANIP - /*check that manip is legal and what requiredAction is necessary for this manip*/ - if(p_KeyParams->ccNextEngineParams.h_Manip) - { - err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams,&requiredAction); - if(err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); - - } -#endif /* FM_PCD_CC_MANIP */ - - p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction; - - p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE; - - - /*update new Ad and new Key Table according to new requirement*/ - i = 0; - for(j = 0; j < p_AdditionalInfo->numOfKeys; j++) - { - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); - if(j == keyIndex) - { - NextStepAd(p_AdTableNewTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd); - p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t)); - Mem2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, p_FmPcdCcNode->userSizeOfExtraction); - if(p_FmPcdCcNode->lclMask) + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0) { - if(p_KeyParams->p_Mask) - Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->userSizeOfExtraction); - else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4) - IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction); - else - Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction); + p_CcNode->lclMask = TRUE; + p_CcNode->glblMaskSize = 0; } - if(!add) - i++; - } - else - { - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); - p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t)); - p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i*size * sizeof(uint8_t)); - - if(p_FmPcdCcNode->lclMask) + } + else + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4)) { - if(prvLclMask) - IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), - PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), - p_FmPcdCcNode->ccKeySizeAccExtraction); - else + uint32_t tmpMask = 0xffffffff; + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0) { - p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction*sizeof(uint8_t)); - - if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4) - IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction); - else - IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction); + p_CcNode->lclMask = TRUE; + p_CcNode->glblMaskSize = 0; } } - IO2IOCpy32(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction); - i++; - } + else + if (p_Mask) + { + p_CcNode->lclMask = TRUE; + p_CcNode->glblMaskSize = 0; + } + + /* In static mode (maxNumOfKeys > 0), local mask is supported + only is mask support was enabled at initialization */ + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask) + { + p_CcNode->lclMask = FALSE; + p_CcNode->glblMaskSize = prvGlblMaskSize; + return ERROR_CODE(E_NOT_SUPPORTED); } - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + return E_OK; +} +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree) +{ + t_FmPcd *p_FmPcd; + t_Handle h_Ad; - if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst)) + if (isTree) + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd); + else + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd); + + if ((isTree && p_FmPcd->p_CcShadow) + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys)) { - LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst) + /* The allocated shadow is divided as follows: + 0 . . . 16 . . . + --------------------------------------------------- + | Shadow | Shadow Keys | Shadow Next | + | Ad | Match Table | Engine Table | + | (16 bytes) | (maximal size) | (maximal size) | + --------------------------------------------------- + */ + if (!p_FmPcd->p_CcShadow) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); + return NULL; + } + + h_Ad = p_FmPcd->p_CcShadow; + } + else + { + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!h_Ad) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor")); + return NULL; + } + } + + return h_Ad; +} + +static t_Error BuildNewNodeCommonPart( + t_FmPcdCcNode *p_CcNode, int *size, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + if (p_CcNode->lclMask) + *size = 2 * p_CcNode->ccKeySizeAccExtraction; + else + *size = p_CcNode->ccKeySizeAccExtraction; + + if (p_CcNode->maxNumOfKeys == 0) + { + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem( + FmPcdGetMuramHandle(p_FmPcd), + (uint32_t)((p_AdditionalInfo->numOfKeys + 1) + * FM_PCD_CC_AD_ENTRY_SIZE), + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_AdditionalInfo->p_AdTableNew) + RETURN_ERROR( + MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC node action descriptors table")); + + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem( + FmPcdGetMuramHandle(p_FmPcd), + (uint32_t)(*size * sizeof(uint8_t) + * (p_AdditionalInfo->numOfKeys + 1)), + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); + if (!p_AdditionalInfo->p_KeysMatchTableNew) + { + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), + p_AdditionalInfo->p_AdTableNew); + p_AdditionalInfo->p_AdTableNew = NULL; + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC node key match table")); + } + + MemSet8( + (uint8_t*)p_AdditionalInfo->p_AdTableNew, + 0, + (uint32_t)((p_AdditionalInfo->numOfKeys + 1) + * FM_PCD_CC_AD_ENTRY_SIZE)); + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)); + } + else + { + /* The allocated shadow is divided as follows: + 0 . . . 16 . . . + --------------------------------------------------- + | Shadow | Shadow Keys | Shadow Next | + | Ad | Match Table | Engine Table | + | (16 bytes) | (maximal size) | (maximal size) | + --------------------------------------------------- + */ + + if (!p_FmPcd->p_CcShadow) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); + + p_AdditionalInfo->p_KeysMatchTableNew = + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE); + p_AdditionalInfo->p_AdTableNew = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize); + + MemSet8( + (uint8_t*)p_AdditionalInfo->p_AdTableNew, + 0, + (uint32_t)((p_CcNode->maxNumOfKeys + 1) + * FM_PCD_CC_AD_ENTRY_SIZE)); + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys)); + } + + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable; + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable; + + return E_OK; +} + +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine( + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, + t_FmPcdCcKeyParams *p_KeyParams, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add) +{ + t_Error err = E_OK; + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; + int size; + int i = 0, j = 0; + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t requiredAction = 0; + bool prvLclMask; + t_CcNodeInformation *p_CcNodeInformation; + t_FmPcdCcStatsParams statsParams = { 0 }; + t_List *p_Pos; + t_FmPcdStatsObj *p_StatsObj; + + /* Check that new NIA is legal */ + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams, + p_CcNode->statisticsMode); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + prvLclMask = p_CcNode->lclMask; + + /* Check that new key is not require update of localMask */ + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, + p_KeyParams->p_Mask); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + + /* Update internal data structure with new next engine for the given index */ + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); + + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction); + + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + + if (p_KeyParams->p_Mask) + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction); + else + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, + p_CcNode->userSizeOfExtraction); + + /* Update numOfKeys */ + if (add) + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1); + else + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys; + + /* Allocate new tables in MURAM: keys match table and action descriptors table */ + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + /* Check that manip is legal and what requiredAction is necessary for this manip */ + if (p_KeyParams->ccNextEngineParams.h_Manip) + { + err = FmPcdManipCheckParamsForCcNextEngine( + &p_KeyParams->ccNextEngineParams, &requiredAction); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = + requiredAction; + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= + UPDATE_CC_WITH_TREE; + + /* Update new Ad and new Key Table according to new requirement */ + i = 0; + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++) + { + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); + + if (j == keyIndex) + { + if (p_KeyParams->ccNextEngineParams.statisticsEn) + { + /* Allocate a statistics object that holds statistics AD and counters. + - For added key - New statistics AD and counters pointer need to be allocated + new statistics object. If statistics were enabled, we need to replace the + existing descriptor with a new descriptor with nullified counters. + */ + p_StatsObj = GetStatsObj(p_CcNode); + ASSERT_COND(p_StatsObj); + + /* Store allocated statistics object */ + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = + p_StatsObj; + + statsParams.h_StatsAd = p_StatsObj->h_StatsAd; + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; +#if (DPAA_VERSION >= 11) + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; + +#endif /* (DPAA_VERSION >= 11) */ + + /* Building action descriptor for the received new key */ + NextStepAd(p_AdTableNewTmp, &statsParams, + &p_KeyParams->ccNextEngineParams, p_FmPcd); + } + else + { + /* Building action descriptor for the received new key */ + NextStepAd(p_AdTableNewTmp, NULL, + &p_KeyParams->ccNextEngineParams, p_FmPcd); + } + + /* Copy the received new key into keys match table */ + p_KeysMatchTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t)); + + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, + p_CcNode->userSizeOfExtraction); + + /* Update mask for the received new key */ + if (p_CcNode->lclMask) + { + if (p_KeyParams->p_Mask) + { + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + p_KeyParams->p_Mask, + p_CcNode->userSizeOfExtraction); + } + else + if (p_CcNode->ccKeySizeAccExtraction > 4) + { + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + 0xff, p_CcNode->userSizeOfExtraction); + } + else + { + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + p_CcNode->p_GlblMask, + p_CcNode->userSizeOfExtraction); + } + } + + /* If key modification requested, the old entry is omitted and replaced by the new parameters */ + if (!add) + i++; + } + else + { + /* Copy existing action descriptors to the newly allocated Ad table */ + p_AdTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, + FM_PCD_CC_AD_ENTRY_SIZE); + + /* Copy existing keys and their masks to the newly allocated keys match table */ + p_KeysMatchTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); + p_KeysMatchTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t)); + + if (p_CcNode->lclMask) + { + if (prvLclMask) + { + MemCpy8( + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), + p_CcNode->ccKeySizeAccExtraction); + } + else + { + p_KeysMatchTableOldTmp = + PTR_MOVE(p_CcNode->h_KeysMatchTable, + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); + + if (p_CcNode->ccKeySizeAccExtraction > 4) + { + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + 0xff, p_CcNode->userSizeOfExtraction); + } + else + { + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + p_CcNode->p_GlblMask, + p_CcNode->userSizeOfExtraction); + } + } + } + + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, + p_CcNode->ccKeySizeAccExtraction); + + i++; + } + } + + /* Miss action descriptor */ + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE); + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + + if (!NCSW_LIST_IsEmpty(&p_CcNode->ccTreesLst)) + { + NCSW_LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) { p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); ASSERT_COND(p_CcNodeInformation->h_CcNode); - /*update the manipulation which has to be updated from parameters of the port*/ - /*it's has to be updated with restrictions defined in the function*/ - err = FmPcdCcSetRequiredAction(p_FmPcdCcNode->h_FmPcd, - p_FmPcdCcNode->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, - &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex], - PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), - 1, - p_CcNodeInformation->h_CcNode); - if (err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); + /* Update the manipulation which has to be updated from parameters of the port */ + /* It's has to be updated with restrictions defined in the function */ + err = + SetRequiredAction( + p_CcNode->h_FmPcd, + p_CcNode->shadowAction + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), + 1, p_CcNodeInformation->h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); - err = CcUpdateParam(p_FmPcdCcNode->h_FmPcd, - NULL, - &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex], - 1, - PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), - TRUE, - p_CcNodeInformation->index, - p_CcNodeInformation->h_CcNode, - TRUE); - if (err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); + err = + CcUpdateParam( + p_CcNode->h_FmPcd, + NULL, + NULL, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], + 1, + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), + TRUE, p_CcNodeInformation->index, + p_CcNodeInformation->h_CcNode, TRUE); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); } - } + } - if(p_FmPcdCcNode->lclMask) - memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + if (p_CcNode->lclMask) + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForAdd = + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode; + if (p_KeyParams->ccNextEngineParams.h_Manip) + p_AdditionalInfo->h_ManipForAdd = + p_KeyParams->ccNextEngineParams.h_Manip; - if(p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForAdd = p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode; +#if (DPAA_VERSION >= 11) + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR) + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForAdd = + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ - if(!add) + if (!add) { - if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -#ifdef FM_PCD_CC_MANIP - if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip) - p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip; -#endif /* FM_PCD_CC_MANIP */ + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; + + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) + p_AdditionalInfo->h_ManipForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; + + /* If statistics were previously enabled, store the old statistics object to be released */ + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) + { + p_AdditionalInfo->p_StatsObjForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; + } + +#if (DPAA_VERSION >= 11) + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ } return E_OK; } -static t_Error BuildNewNodeRemoveKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) +static t_Error BuildNewNodeRemoveKey( + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) { - int i = 0, j = 0; - t_Handle p_AdTableNewTmp,p_KeysMatchTableNewTmp; - t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; - int size; - t_Error err = E_OK; + int i = 0, j = 0; + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; + int size; + t_Error err = E_OK; /*save new numOfKeys*/ - p_AdditionalInfo->numOfKeys = (uint16_t)(p_FmPcdCcNode->numOfKeys - 1); + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1); /*function which allocates in the memory new KeyTbl, AdTbl*/ - err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo); - if(err) + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); /*update new Ad and new Key Table according to new requirement*/ - for(i = 0, j = 0; j < p_FmPcdCcNode->numOfKeys; i++, j++) + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++) { - if(j == keyIndex) - { - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE); + if (j == keyIndex) j++; - } - if(j == p_FmPcdCcNode->numOfKeys) + + if (j == p_CcNode->numOfKeys) break; - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE); - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp,p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); - p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j*size * sizeof(uint8_t)); - p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i*size * sizeof(uint8_t)); - IO2IOCpy32(p_KeysMatchTableNewTmp,p_KeysMatchTableOldTmp, size * sizeof(uint8_t)); + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + + p_KeysMatchTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t)); + p_KeysMatchTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t)); + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, + size * sizeof(uint8_t)); } - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE); - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); - if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -#ifdef FM_PCD_CC_MANIP - if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip) - p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip; -#endif /* FM_PCD_CC_MANIP */ + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; - return E_OK; + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) + p_AdditionalInfo->h_ManipForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; + + /* If statistics were previously enabled, store the old statistics object to be released */ + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) + { + p_AdditionalInfo->p_StatsObjForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; + } + +#if (DPAA_VERSION >= 11) + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ + + return E_OK; } -static t_Error BuildNewNodeModifyKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, uint8_t *p_Key, uint8_t *p_Mask,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) +static t_Error BuildNewNodeModifyKey( + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key, + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) { - t_Error err = E_OK; - t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; - t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; - int size; - int i = 0, j = 0; - bool prvLclMask; + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + t_Error err = E_OK; + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; + int size; + int i = 0, j = 0; + bool prvLclMask; + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj; + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys; - p_AdditionalInfo->numOfKeys = p_FmPcdCcNode->numOfKeys; + prvLclMask = p_CcNode->lclMask; - prvLclMask = p_FmPcdCcNode->lclMask; + /* Check that new key is not require update of localMask */ + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); - /*check that new key is not require update of localMask*/ - err = UpdateGblMask(p_FmPcdCcNode, - p_FmPcdCcNode->sizeOfExtraction, - p_Mask); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + /* Update internal data structure with new next engine for the given index */ + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key, + p_CcNode->userSizeOfExtraction); + + if (p_Mask) + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask, + p_CcNode->userSizeOfExtraction); + else + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, + p_CcNode->userSizeOfExtraction); /*function which build in the memory new KeyTbl, AdTbl*/ - err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo); - if(err) + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); /*fill the New AdTable and New KeyTable*/ - for(j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++) + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++) { - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); - p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); - if(j == keyIndex) + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableOldTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); + + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + + if (j == keyIndex) { - p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t)); - Mem2IOCpy32(p_KeysMatchTableNewTmp, p_Key, p_FmPcdCcNode->userSizeOfExtraction); - if(p_FmPcdCcNode->lclMask) + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) { - if(p_Mask) - Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_Mask, p_FmPcdCcNode->userSizeOfExtraction); - else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4) - IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction); + /* As statistics were enabled, we need to update the existing + statistics descriptor with a new nullified counters. */ + p_StatsObj = GetStatsObj(p_CcNode); + ASSERT_COND(p_StatsObj); + + SetStatsCounters( + p_AdTableNewTmp, + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters) + - p_FmPcd->physicalMuramBase))); + + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd; + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters; + + /* As we need to replace only the counters, we build a new statistics + object that holds the old AD and the new counters - this will be the + currently used statistics object. + The newly allocated AD is not required and may be released back to + the available objects with the previous counters pointer. */ + p_StatsObj->h_StatsAd = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; + + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd = + tmpStatsObj.h_StatsAd; + + /* Store allocated statistics object */ + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = + p_StatsObj; + + /* As statistics were previously enabled, store the old statistics object to be released */ + p_AdditionalInfo->p_StatsObjForRmv = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; + } + + p_KeysMatchTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); + + MemCpy8(p_KeysMatchTableNewTmp, p_Key, + p_CcNode->userSizeOfExtraction); + + if (p_CcNode->lclMask) + { + if (p_Mask) + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + p_Mask, p_CcNode->userSizeOfExtraction); else - Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction); + if (p_CcNode->ccKeySizeAccExtraction > 4) + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + 0xff, p_CcNode->userSizeOfExtraction); + else + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + p_CcNode->p_GlblMask, + p_CcNode->userSizeOfExtraction); } } else { - p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t)); - p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*size * sizeof(uint8_t)); - if (p_FmPcdCcNode->lclMask) + p_KeysMatchTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); + p_KeysMatchTableOldTmp = + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t)); + + if (p_CcNode->lclMask) { - if(prvLclMask) - IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), - PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), - p_FmPcdCcNode->userSizeOfExtraction); + if (prvLclMask) + MemCpy8( + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), + p_CcNode->userSizeOfExtraction); else { - p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); + p_KeysMatchTableOldTmp = + PTR_MOVE(p_CcNode->h_KeysMatchTable, + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); - if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4) - IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction); + if (p_CcNode->ccKeySizeAccExtraction > 4) + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, + p_CcNode->ccKeySizeAccExtraction), + 0xff, p_CcNode->userSizeOfExtraction); else - IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction); + MemCpy8( + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), + p_CcNode->p_GlblMask, + p_CcNode->userSizeOfExtraction); } } - IO2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction); + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, + p_CcNode->ccKeySizeAccExtraction); } } - p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); - p_AdTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); - IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableNewTmp = + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE); + + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); return E_OK; } -static t_Error BuildNewNodeModifyNextEngine(t_Handle h_FmPcd ,t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) +static t_Error BuildNewNodeModifyNextEngine( + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) { - - t_Error err = E_OK; - uint32_t requiredAction = 0; - t_List *p_Pos; + t_Error err = E_OK; + uint32_t requiredAction = 0; + t_List *p_Pos; t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo; - t_Handle p_Ad; + t_Handle p_Ad; t_FmPcdCcNode *p_FmPcdCcNode1 = NULL; t_FmPcdCcTree *p_FmPcdCcTree = NULL; + t_FmPcdStatsObj *p_StatsObj; + t_FmPcdCcStatsParams statsParams = { 0 }; ASSERT_COND(p_CcNextEngineParams); - /*check that new NIA is legal*/ - err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams); - if(err) + + /* check that new NIA is legal */ + if (!p_AdditionalInfo->tree) + err = ValidateNextEngineParams( + h_FmPcd, p_CcNextEngineParams, + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode); + else + /* Statistics are not supported for CC root */ + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams, + e_FM_PCD_CC_STATS_MODE_NONE); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - /*update internal data structure for next engine per index (index - key)*/ - memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); + /* Update internal data structure for next engine per index (index - key) */ + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); -#ifdef FM_PCD_CC_MANIP - /*check that manip is legal and what requiredAction is necessary for this manip*/ - if(p_CcNextEngineParams->h_Manip) + /* Check that manip is legal and what requiredAction is necessary for this manip */ + if (p_CcNextEngineParams->h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(p_CcNextEngineParams,&requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams, + &requiredAction); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); - } -#endif /* FM_PCD_CC_MANIP */ - if(!p_AdditionalInfo->tree) + if (!p_AdditionalInfo->tree) { p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys; p_Ad = p_FmPcdCcNode1->h_AdTable; - if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -#ifdef FM_PCD_CC_MANIP - if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip) - p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip; -#endif /* FM_PCD_CC_MANIP */ + + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForRmv = + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; + + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) + p_AdditionalInfo->h_ManipForRmv = + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; + +#if (DPAA_VERSION >= 11) + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForRmv = + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ } else { p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); - if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -#ifdef FM_PCD_CC_MANIP - if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip) - p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip; -#endif /* FM_PCD_CC_MANIP */ + + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForRmv = + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; + + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) + p_AdditionalInfo->h_ManipForRmv = + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; + +#if (DPAA_VERSION >= 11) + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForRmv = + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ } + + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) + && p_CcNextEngineParams->h_Manip) + { + err = AllocAndFillAdForContLookupManip( + p_CcNextEngineParams->params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + ASSERT_COND(p_Ad); + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE); - EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo); + + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled, + only the actual Nia-Ad should be modified. */ + if ((!p_AdditionalInfo->tree) + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) + && (p_CcNextEngineParams->statisticsEn)) + ccNodeInfo.h_CcNode = + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; + + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - p_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree); + if (!p_Ad) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC node action descriptor")); + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - if(!p_Ad) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + /* If statistics were not enabled before, but requested now - Allocate a statistics + object that holds statistics AD and counters. */ + if ((!p_AdditionalInfo->tree) + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) + && (p_CcNextEngineParams->statisticsEn)) + { + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree); + ASSERT_COND(p_StatsObj); + + /* Store allocated statistics object */ + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = + p_StatsObj; + + statsParams.h_StatsAd = p_StatsObj->h_StatsAd; + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; + +#if (DPAA_VERSION >= 11) + statsParams.h_StatsFLRs = + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs; + +#endif /* (DPAA_VERSION >= 11) */ + + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd); + } + else + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd); - IOMemSet32((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - if(p_CcNextEngineParams) - NextStepAd(p_Ad,p_CcNextEngineParams, h_FmPcd); ccNodeInfo.h_CcNode = p_Ad; - EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo); + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); - p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction; + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = + requiredAction; + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= + UPDATE_CC_WITH_TREE; - p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE; - - if(!p_AdditionalInfo->tree) + if (!p_AdditionalInfo->tree) { ASSERT_COND(p_FmPcdCcNode1); - if(!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst)) + if (!NCSW_LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst)) { - LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst) + NCSW_LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst) { p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); + ASSERT_COND(p_CcNodeInformation->h_CcNode); - /*update the manipulation which has to be updated from parameters of the port*/ - /*it's has to be updated with restrictions defined in the function*/ - err = FmPcdCcSetRequiredAction(p_FmPcdCcNode1->h_FmPcd, p_FmPcdCcNode1->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex], - p_Ad, 1, p_CcNodeInformation->h_CcNode); - if(err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); - err = CcUpdateParam(p_FmPcdCcNode1->h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, p_CcNodeInformation->index, p_CcNodeInformation->h_CcNode, TRUE); - if(err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); + /* Update the manipulation which has to be updated from parameters of the port + it's has to be updated with restrictions defined in the function */ + + err = + SetRequiredAction( + p_FmPcdCcNode1->h_FmPcd, + p_FmPcdCcNode1->shadowAction + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], + p_Ad, 1, p_CcNodeInformation->h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + + err = CcUpdateParam( + p_FmPcdCcNode1->h_FmPcd, NULL, NULL, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1, + p_Ad, TRUE, p_CcNodeInformation->index, + p_CcNodeInformation->h_CcNode, TRUE); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); } } } else { - ASSERT_COND(p_FmPcdCcTree); - err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->requiredAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex], - p_Ad, 1, (t_Handle)p_FmPcdCcTree); - if(err) + ASSERT_COND(p_FmPcdCcTree); + + err = + SetRequiredAction( + h_FmPcd, + p_FmPcdCcTree->requiredAction + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], + p_Ad, 1, (t_Handle)p_FmPcdCcTree); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); - err = CcUpdateParam(h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE); - if(err) + + err = CcUpdateParam(h_FmPcd, NULL, NULL, + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); } - if(p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) - p_AdditionalInfo->h_NodeForAdd = p_CcNextEngineParams->params.ccParams.h_CcNode; + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) + p_AdditionalInfo->h_NodeForAdd = + p_CcNextEngineParams->params.ccParams.h_CcNode; + if (p_CcNextEngineParams->h_Manip) + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip; + + /* If statistics were previously enabled, but now are disabled, + store the old statistics object to be released */ + if ((!p_AdditionalInfo->tree) + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) + && (!p_CcNextEngineParams->statisticsEn)) + { + p_AdditionalInfo->p_StatsObjForRmv = + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj; + + + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL; + } +#if (DPAA_VERSION >= 11) + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR) + && (p_CcNextEngineParams->params.frParams.h_FrmReplic)) + p_AdditionalInfo->h_FrmReplicForAdd = + p_CcNextEngineParams->params.frParams.h_FrmReplic; +#endif /* (DPAA_VERSION >= 11) */ + return E_OK; } -static t_Handle BuildNewAd(t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, - t_FmPcdCcNode *p_FmPcdCcNode, - t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode( + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, + t_FmPcdCcNextEngineParams **p_NextEngineParams) { + t_CcNodeInformation *p_CcNodeInformation; + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL; + t_List *p_Pos; + int i = 0; + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; + t_CcNodeInformation ccNodeInfo; - t_Handle p_Ad; - t_FmPcdCcNode *p_FmPcdCcNodeTmp; - - p_Ad = (t_Handle)FM_MURAM_AllocMem(((t_FmPcd *)(p_FmPcdCcNode->h_FmPcd))->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Ad) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM for AD")); - return NULL; - } - IOMemSet32(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - - p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); - if(!p_FmPcdCcNodeTmp) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp")); - return NULL; - } - memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode)); - - p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys; - p_FmPcdCcNodeTmp->h_KeysMatchTable = p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew; - p_FmPcdCcNodeTmp->h_AdTable = p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew; - - p_FmPcdCcNodeTmp->lclMask = p_FmPcdCcNode->lclMask; - p_FmPcdCcNodeTmp->parseCode = p_FmPcdCcNode->parseCode; - p_FmPcdCcNodeTmp->offset = p_FmPcdCcNode->offset; - p_FmPcdCcNodeTmp->prsArrayOffset = p_FmPcdCcNode->prsArrayOffset; - p_FmPcdCcNodeTmp->ctrlFlow = p_FmPcdCcNode->ctrlFlow; - p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_FmPcdCcNode->ccKeySizeAccExtraction; - p_FmPcdCcNodeTmp->sizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction; - p_FmPcdCcNodeTmp->glblMaskSize = p_FmPcdCcNode->glblMaskSize; - p_FmPcdCcNodeTmp->p_GlblMask = p_FmPcdCcNode->p_GlblMask; - - if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) - FillAdOfTypeContLookup(p_Ad, - p_FmPcdCcNode->h_FmPcd, - p_FmPcdCcNodeTmp, -#ifdef FM_PCD_CC_MANIP - p_FmPcdCcNextEngineParams->h_Manip -#else - NULL -#endif /* FM_PCD_CC_MANIP */ - ); - - XX_Free(p_FmPcdCcNodeTmp); - - return p_Ad; -} - -static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst) -{ - t_CcNodeInformation *p_CcNodeInformation; - t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL; - t_List *p_Pos; - int i = 0; - t_Handle p_AdTablePtOnCrntCurrentMdfNode, p_AdTableNewModified; - t_CcNodeInformation ccNodeInfo; - - LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst) + NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst) { p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); - p_NodePtrOnCurrentMdfNode = (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; + p_NodePtrOnCurrentMdfNode = + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; + ASSERT_COND(p_NodePtrOnCurrentMdfNode); - /*search in the prev node which exact index points on this current modified node for getting AD */ - for(i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++) + + /* Search in the previous node which exact index points on this current modified node for getting AD */ + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++) { - if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) { - if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode) + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode + == (t_Handle)p_CrntMdfNode) { - p_AdTablePtOnCrntCurrentMdfNode = PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad; + else + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj) + p_AdTablePtOnCrntCurrentMdfNode = + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; + else + p_AdTablePtOnCrntCurrentMdfNode = + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; - EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo); + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); - p_AdTableNewModified = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams); - memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - ccNodeInfo.h_CcNode = p_AdTableNewModified; - EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo); + if (!(*p_NextEngineParams)) + *p_NextEngineParams = + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; } } } + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys); } } -static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst) +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode( + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, + t_FmPcdCcNextEngineParams **p_NextEngineParams) { - t_CcNodeInformation *p_CcNodeInformation; - t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL; - t_List *p_Pos; - int i = 0; - t_Handle p_AdTableTmp, p_AdTableTmp1; - t_CcNodeInformation ccNodeInfo; + t_CcNodeInformation *p_CcNodeInformation; + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL; + t_List *p_Pos; + int i = 0; + t_Handle p_AdTableTmp; + t_CcNodeInformation ccNodeInfo; - LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst) + NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst) { p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); - p_TreePtrOnCurrentMdfNode = (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode; + p_TreePtrOnCurrentMdfNode = + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode; ASSERT_COND(p_TreePtrOnCurrentMdfNode); - /*search in the trees which exact index points on this current modified node for getting AD - */ - for(i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++) + + /*search in the trees which exact index points on this current modified node for getting AD */ + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++) { - if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) { - if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode) + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode + == (t_Handle)p_CrntMdfNode) { - p_AdTableTmp = UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE); + p_AdTableTmp = + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE); memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); ccNodeInfo.h_CcNode = p_AdTableTmp; - EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo); + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); - p_AdTableTmp1 = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams); - memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - ccNodeInfo.h_CcNode = p_AdTableTmp1; - EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo); + if (!(*p_NextEngineParams)) + *p_NextEngineParams = + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; } + } } - } + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries); - } + } } -static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, t_Handle *h_Params, e_ModifyState modifyState, bool check, bool tree) +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart( + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree) { - t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams; - int i = 0, j = 0; - bool wasUpdate = FALSE; - t_FmPcdCcNode *p_FmPcdCcNode = NULL; - t_FmPcdCcTree *p_FmPcdCcTree; - uint16_t numOfKeys; - t_FmPcdCcNextEngineAndRequiredActionParams *p_nextEngineAndRequiredAction = NULL; + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams; + int i = 0, j = 0; + bool wasUpdate = FALSE; + t_FmPcdCcNode *p_CcNode = NULL; + t_FmPcdCcTree *p_FmPcdCcTree; + uint16_t numOfKeys; + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams; - SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNodeOrTree,E_INVALID_HANDLE); + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL); - p_nextEngineAndRequiredAction = XX_Malloc(FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction)); - if(!p_nextEngineAndRequiredAction) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate memory for p_nextEngineAndRequiredAction")); - - memset(p_nextEngineAndRequiredAction, 0, FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction)); - - if(!tree) + if (!tree) { - p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; - numOfKeys = p_FmPcdCcNode->numOfKeys; + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; + numOfKeys = p_CcNode->numOfKeys; - /*node has to be pointed by another node or tree*/ - if (!LIST_NumOfObjs(&p_FmPcdCcNode->ccPrevNodesLst) && - !LIST_NumOfObjs(&p_FmPcdCcNode->ccTreeIdLst)) + /* node has to be pointed by another node or tree */ + + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1)); + if (!p_KeyAndNextEngineParams) { - XX_Free(p_nextEngineAndRequiredAction); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be pointed by node or tree")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); + return NULL; } + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams, + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams)); - if(!LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) || - (LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) != 1)) + if (ttlCheck) { - XX_Free(p_nextEngineAndRequiredAction); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be belonging to some tree and only to one tree")); - } - - memcpy(p_nextEngineAndRequiredAction, - p_FmPcdCcNode->nextEngineAndRequiredAction, - FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams)); - - if(check) - { - if((p_FmPcdCcNode->parseCode == CC_PC_FF_IPV4TTL) || - (p_FmPcdCcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT) || - (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL) + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT)) { - XX_Free(p_nextEngineAndRequiredAction); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for addKey, removeKey, modifyKey")); + XX_Free(p_KeyAndNextEngineParams); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for this operation")); + return NULL; + } + } + + if (hashCheck) + { + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) + { + XX_Free(p_KeyAndNextEngineParams); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation")); + return NULL; } } } @@ -1983,36 +3482,52 @@ static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree, uint16_t keyI { p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; numOfKeys = p_FmPcdCcTree->numOfEntries; - memcpy(p_nextEngineAndRequiredAction, - p_FmPcdCcTree->nextEngineAndRequiredAction, - FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams)); + + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( + sizeof(t_FmPcdCcKeyAndNextEngineParams) + * FM_PCD_MAX_NUM_OF_CC_GROUPS); + if (!p_KeyAndNextEngineParams) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); + return NULL; + } + memcpy(p_KeyAndNextEngineParams, + p_FmPcdCcTree->keyAndNextEngineParams, + FM_PCD_MAX_NUM_OF_CC_GROUPS + * sizeof(t_FmPcdCcKeyAndNextEngineParams)); } p_FmPcdModifyCcKeyAdditionalParams = - (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(sizeof(t_FmPcdModifyCcKeyAdditionalParams)); - if(!p_FmPcdModifyCcKeyAdditionalParams) + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc( + sizeof(t_FmPcdModifyCcKeyAdditionalParams)); + if (!p_FmPcdModifyCcKeyAdditionalParams) { - XX_Free(p_nextEngineAndRequiredAction); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED")); + XX_Free(p_KeyAndNextEngineParams); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED")); + return NULL; } - memset(p_FmPcdModifyCcKeyAdditionalParams, 0, sizeof(t_FmPcdModifyCcKeyAdditionalParams)); + memset(p_FmPcdModifyCcKeyAdditionalParams, 0, + sizeof(t_FmPcdModifyCcKeyAdditionalParams)); p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree; - p_FmPcdModifyCcKeyAdditionalParams->keyIndex = keyIndex; + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex; - while(i < numOfKeys) + while (i < numOfKeys) { - if((j == keyIndex) && !wasUpdate) + if ((j == keyIndex) && !wasUpdate) { - if(modifyState == e_MODIFY_STATE_ADD) + if (modifyState == e_MODIFY_STATE_ADD) j++; - else if(modifyState == e_MODIFY_STATE_REMOVE) - i++; + else + if (modifyState == e_MODIFY_STATE_REMOVE) + i++; wasUpdate = TRUE; } else { - memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams)); + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], + p_KeyAndNextEngineParams + i, + sizeof(t_FmPcdCcKeyAndNextEngineParams)); i++; j++; } @@ -2022,34 +3537,65 @@ static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree, uint16_t keyI { if (modifyState == e_MODIFY_STATE_ADD) j++; - else if(modifyState == e_MODIFY_STATE_REMOVE) - i++; } - memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[numOfKeys], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams)); + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], + p_KeyAndNextEngineParams + numOfKeys, + sizeof(t_FmPcdCcKeyAndNextEngineParams)); - XX_Free(p_nextEngineAndRequiredAction); - *h_Params = p_FmPcdModifyCcKeyAdditionalParams; + XX_Free(p_KeyAndNextEngineParams); - return E_OK; + return p_FmPcdModifyCcKeyAdditionalParams; } -static t_Error UpdatePtrWhichPointOnCrntMdfNode(t_FmPcdCcNode *p_FmPcdCcNode, t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams ,t_List *h_OldLst, t_List *h_NewLst) +static t_Error UpdatePtrWhichPointOnCrntMdfNode( + t_FmPcdCcNode *p_CcNode, + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, + t_List *h_OldLst, t_List *h_NewLst) { - if(!LIST_IsEmpty(&p_FmPcdCcNode->ccPrevNodesLst)) - UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst); + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL; + t_CcNodeInformation ccNodeInfo = { 0 }; + t_Handle h_NewAd; + t_Handle h_OrigAd = NULL; - if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreeIdLst)) - UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst); + /* Building a list of all action descriptors that point to the previous node */ + if (!NCSW_LIST_IsEmpty(&p_CcNode->ccPrevNodesLst)) + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, + &p_NextEngineParams); + if (!NCSW_LIST_IsEmpty(&p_CcNode->ccTreeIdLst)) + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, + &p_NextEngineParams); + + /* This node must be found as next engine of one of its previous nodes or trees*/ + if (p_NextEngineParams) + { + /* Building a new action descriptor that points to the modified node */ + h_NewAd = GetNewAd(p_CcNode, FALSE); + if (!h_NewAd) + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + h_OrigAd = p_CcNode->h_Ad; + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode, + p_NextEngineParams); + + ccNodeInfo.h_CcNode = h_NewAd; + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); + + if (p_NextEngineParams->h_Manip && !h_OrigAd) + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE); + } return E_OK; } -static void FmPcdCcUpdateTreeOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add) +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add) { ASSERT_COND(p_FmPcdCcTree); - if(add) + /* this routine must be protected by the calling routine! */ + + if (add) p_FmPcdCcTree->owners++; else { @@ -2058,728 +3604,2412 @@ static void FmPcdCcUpdateTreeOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add) } } -#ifdef FM_PCD_CC_MANIP -static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_FmPcdCcNode) +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode) { t_Error err = E_OK; - int i = 0; + int i = 0; - for(i = 0; i < p_FmPcdCcNode->numOfKeys; i++) + for (i = 0; i < p_CcNode->numOfKeys; i++) { - if(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip) + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) { - err = FmPcdManipCheckParamsWithCcNodeParams(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, (t_Handle)p_FmPcdCcNode); - if(err) + err = + FmPcdManipCheckParamsWithCcNodeParams( + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, + (t_Handle)p_CcNode); + if (err) return err; } } return err; } -#endif /* FM_PCD_CC_MANIP */ - -static t_Error CcUpdateParams(t_Handle h_FmPcd, - t_Handle h_FmPort, - t_Handle h_FmTree, - bool validate) +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode, + t_FmPcdCcNodeParams *p_CcNodeParam, + uint32_t *p_NumOfRanges, + uint32_t *p_CountersArraySize) { - t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *) h_FmTree; + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode; + uint32_t i; - return CcUpdateParam(h_FmPcd, - h_FmPort, - p_CcTree->nextEngineAndRequiredAction, - p_CcTree->numOfEntries, - UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), - validate, - 0, - h_FmTree, - FALSE); + UNUSED(p_CcNodeParam); + + switch (statisticsMode) + { + case e_FM_PCD_CC_STATS_MODE_NONE: + for (i = 0; i < p_CcNode->numOfKeys; i++) + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i)); + return E_OK; + + case e_FM_PCD_CC_STATS_MODE_FRAME: + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME: + *p_NumOfRanges = 1; + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; + return E_OK; + +#if (DPAA_VERSION >= 11) + case e_FM_PCD_CC_STATS_MODE_RMON: + { + uint16_t *p_FrameLengthRanges = + p_CcNodeParam->keysParams.frameLengthRanges; + uint32_t i; + + if (p_FrameLengthRanges[0] <= 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); + + if (p_FrameLengthRanges[0] == 0xFFFF) + { + *p_NumOfRanges = 1; + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; + return E_OK; + } + + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++) + { + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i]) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Frame length range must be larger at least by 1 from preceding range")); + + /* Stop when last range is reached */ + if (p_FrameLengthRanges[i] == 0xFFFF) + break; + } + + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR) + || (p_FrameLengthRanges[i] != 0xFFFF)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("Last Frame length range must be 0xFFFF")); + + *p_NumOfRanges = i + 1; + + /* Allocate an extra counter for byte count, as counters + array always begins with byte count */ + *p_CountersArraySize = (*p_NumOfRanges + 1) + * FM_PCD_CC_STATS_COUNTER_SIZE; + + } + return E_OK; +#endif /* (DPAA_VERSION >= 11) */ + + default: + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); + } } -static t_Error CheckParams(t_Handle h_FmPcd, - t_FmPcdCcNodeParams *p_CcNodeParam, - t_FmPcdCcNode *p_FmPcdCcNode, - bool *isKeyTblAlloc) +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) { - int tmp = 0; - t_FmPcdCcKeyParams *p_KeyParams; - t_Error err; - uint32_t requiredAction = 0; + int tmp = 0; + t_FmPcdCcKeyParams *p_KeyParams; + t_Error err; + uint32_t requiredAction = 0; - err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss); - if(err) - RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid")); + /* Validate statistics parameters */ + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, + &(p_CcNode->numOfStatsFLRs), + &(p_CcNode->countersArraySize)); + if (err) + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); -#ifdef FM_PCD_CC_MANIP - if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) + /* Validate next engine parameters on Miss */ + err = ValidateNextEngineParams( + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + p_CcNode->statisticsMode); + if (err) + RETURN_ERROR(MAJOR, err, + ("For this node MissNextEngineParams are not valid")); + + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine( + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + &requiredAction); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); } -#endif /* FM_PCD_CC_MANIP */ - memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams)); - p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction; + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + sizeof(t_FmPcdCcNextEngineParams)); - for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++) + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = + requiredAction; + + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) { p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; - if(!p_KeyParams->p_Key) + if (!p_KeyParams->p_Key) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized")); - - err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams); - if(err) + err = ValidateNextEngineParams(h_FmPcd, + &p_KeyParams->ccNextEngineParams, + p_CcNode->statisticsMode); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); - err = UpdateGblMask(p_FmPcdCcNode, - p_CcNodeParam->keysParams.keySize, + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize, p_KeyParams->p_Mask); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); -#ifdef FM_PCD_CC_MANIP - if(p_KeyParams->ccNextEngineParams.h_Manip) + if (p_KeyParams->ccNextEngineParams.h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine( + &p_KeyParams->ccNextEngineParams, &requiredAction); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); } -#endif /* FM_PCD_CC_MANIP */ - memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp],&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); - p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction; + /* Store 'key' parameters - key, mask (if passed by the user) */ + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key, + p_CcNodeParam->keysParams.keySize); + + if (p_KeyParams->p_Mask) + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask, + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize); + else + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF, + p_CcNodeParam->keysParams.keySize); + + /* Store next engine parameters */ + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, + &p_KeyParams->ccNextEngineParams, + sizeof(t_FmPcdCcNextEngineParams)); + + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; + + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + } + + if (p_CcNode->maxNumOfKeys) + { + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Number of keys exceed the provided maximal number of keys")); } *isKeyTblAlloc = TRUE; + return E_OK; } -static t_Error Ipv4TtlOrIpv6HopLimiCheckParams( t_Handle h_FmPcd, - t_FmPcdCcNodeParams *p_CcNodeParam, t_FmPcdCcNode *p_FmPcdCcNode, - bool *isKeyTblAlloc) +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams( + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) { - int tmp = 0; - t_FmPcdCcKeyParams *p_KeyParams; - t_Error err; - uint8_t key = 0x01; - uint32_t requiredAction = 0; + int tmp = 0; + t_FmPcdCcKeyParams *p_KeyParams; + t_Error err; + uint8_t key = 0x01; + uint32_t requiredAction = 0; - if(p_FmPcdCcNode->numOfKeys != 1 ) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for IPV4TTL and IPV6_HOP_LIMIT has to be only 1 key - TTL = 1, otherwise it's Miss")); + if (p_CcNode->numOfKeys != 1) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1")); - err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss); - if(err) - RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid")); + if ((p_CcNodeParam->keysParams.maxNumOfKeys) + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1")); -#ifdef FM_PCD_CC_MANIP - if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) + /* Validate statistics parameters */ + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, + &(p_CcNode->numOfStatsFLRs), + &(p_CcNode->countersArraySize)); + if (err) + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); + + err = ValidateNextEngineParams( + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + p_CcNodeParam->keysParams.statisticsMode); + if (err) + RETURN_ERROR(MAJOR, err, + ("For this node MissNextEngineParams are not valid")); + + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine( + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + &requiredAction); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); } -#endif /* FM_PCD_CC_MANIP */ - memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams)); - p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction; + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + sizeof(t_FmPcdCcNextEngineParams)); - for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++) + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = + requiredAction; + + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) { p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; - if(p_KeyParams->p_Mask) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized")); - if(memcmp(p_KeyParams->p_Key, &key, 1) != 0) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1")); - err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams); - if(err) + + if (p_KeyParams->p_Mask) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized")); + + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1")); + + err = ValidateNextEngineParams(h_FmPcd, + &p_KeyParams->ccNextEngineParams, + p_CcNode->statisticsMode); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); -#ifdef FM_PCD_CC_MANIP - if(p_KeyParams->ccNextEngineParams.h_Manip) - { - err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction); - if(err) - RETURN_ERROR(MAJOR, err, (NO_MSG)); - } -#endif /* FM_PCD_CC_MANIP */ + if (p_KeyParams->ccNextEngineParams.h_Manip) + { + err = FmPcdManipCheckParamsForCcNextEngine( + &p_KeyParams->ccNextEngineParams, &requiredAction); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } - memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams, &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); - p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction; + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */ + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key; + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF; + + /* Store NextEngine parameters */ + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, + &p_KeyParams->ccNextEngineParams, + sizeof(t_FmPcdCcNextEngineParams)); + + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + } + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; } *isKeyTblAlloc = FALSE; + return E_OK; } static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd, - t_FmPcdCcNodeParams *p_CcNodeParam, - t_FmPcdCcNode *p_FmPcdCcNode, - /*uint16_t *ccInfo,*/ - /*t_List *ccNextDifferentNodesLst,*/ - bool *isKeyTblAlloc) + t_FmPcdCcNodeParams *p_CcNodeParam, + t_FmPcdCcNode *p_CcNode, + bool *isKeyTblAlloc) { - int tmp = 0, countOnes = 0; - t_FmPcdCcKeyParams *p_KeyParams; - t_Error err; - uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask; - uint16_t countMask = (uint16_t)(glblMask >> 4); -#ifdef FM_PCD_CC_MANIP - uint32_t requiredAction; -#endif /* FM_PCD_CC_MANIP */ + int tmp = 0, countOnes = 0; + t_FmPcdCcKeyParams *p_KeyParams; + t_Error err; + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask; + uint16_t countMask = (uint16_t)(glblMask >> 4); + uint32_t requiredAction = 0; if (glblMask & 0x000f) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("icIndxMask has to be with last nibble 0")); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("icIndxMask has to be with last nibble 0")); while (countMask) { countOnes++; - countMask=(uint16_t)(countMask>>1); + countMask = (uint16_t)(countMask >> 1); } - if (!POWER_OF_2(p_FmPcdCcNode->numOfKeys)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type INDEXED numOfKeys has to be powerOfTwo")); - if (p_FmPcdCcNode->numOfKeys != ((uint32_t)1<numOfKeys)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo")); - err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss); - if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED) - RETURN_ERROR(MAJOR, err, ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized")); + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo")); - for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++) + if (p_CcNodeParam->keysParams.maxNumOfKeys + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'")); + + /* Validate statistics parameters */ + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, + &(p_CcNode->numOfStatsFLRs), + &(p_CcNode->countersArraySize)); + if (err) + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); + + err = ValidateNextEngineParams( + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + p_CcNode->statisticsMode); + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) + RETURN_ERROR( + MAJOR, + err, + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized")); + + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) { p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; - if(p_KeyParams->p_Mask || p_KeyParams->p_Key) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL")); - if((glblMask & (tmp * 16)) == (tmp * 16)) + if (p_KeyParams->p_Mask || p_KeyParams->p_Key) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL")); + + if ((glblMask & (tmp * 16)) == (tmp * 16)) { - err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams); - if(err) - RETURN_ERROR(MAJOR, err, ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask ")); + err = ValidateNextEngineParams(h_FmPcd, + &p_KeyParams->ccNextEngineParams, + p_CcNode->statisticsMode); + if (err) + RETURN_ERROR( + MAJOR, + err, + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask ")); -#ifdef FM_PCD_CC_MANIP - if(p_KeyParams->ccNextEngineParams.h_Manip) + if (p_KeyParams->ccNextEngineParams.h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine( + &p_KeyParams->ccNextEngineParams, &requiredAction); + if (err) + RETURN_ERROR(MAJOR, err, (NO_MSG)); + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = + requiredAction; + } + + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, + &p_KeyParams->ccNextEngineParams, + sizeof(t_FmPcdCcNextEngineParams)); + + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); + if (err) RETURN_ERROR(MAJOR, err, (NO_MSG)); } - p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction; -#endif /* FM_PCD_CC_MANIP */ - - memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); } else { - err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams); - if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED) - RETURN_ERROR(MAJOR, err, ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask")); + err = ValidateNextEngineParams(h_FmPcd, + &p_KeyParams->ccNextEngineParams, + p_CcNode->statisticsMode); + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) + RETURN_ERROR( + MAJOR, + err, + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask")); } } + *isKeyTblAlloc = FALSE; - memcpy(PTR_MOVE(p_FmPcdCcNode->p_GlblMask, 2), &glblMask, 2); + glblMask = htobe16(glblMask); + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2); return E_OK; } -t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams) +static t_Error ModifyNextEngineParamNode( + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) { - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; - t_Error err = E_OK; - uint16_t keyIndex; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_List h_OldPointersLst, h_NewPointersLst; t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + t_Error err = E_OK; - SANITY_CHECK_RETURN_ERROR((grpId <= 7),E_INVALID_VALUE); - SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree,E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); - if(grpId >= p_FmPcdCcTree->numOfGrps) - RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree")); + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("keyIndex > previously cleared last index + 1")); - if(index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup) - RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup")); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; - keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry + index); + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); - err = ModifyKeyCommonPart1(h_FmPcdCcTree, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, TRUE); - if(err) + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_CHANGE, FALSE, + FALSE, FALSE); + if (!p_ModifyKeyParams) RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - p_ModifyKeyParams->tree = TRUE; - - err = BuildNewNodeModifyNextEngine (h_FmPcd, h_FmPcdCcTree, keyIndex,p_FmPcdCcNextEngineParams, h_OldLst, h_NewLst, p_ModifyKeyParams); - if(err) + if (p_CcNode->maxNumOfKeys + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) { XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcNextEngineParams, + &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams); + if (err) + { + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); RETURN_ERROR(MAJOR, err, NO_MSG); } - return E_OK; + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, FALSE); + + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; } -t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams) +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, + uint8_t *p_Mask, uint16_t *p_KeyIndex) { + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY]; + uint16_t i; - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *) h_FmPcdCcNode; - t_Error err = E_OK; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + ASSERT_COND(p_Key); + ASSERT_COND(p_KeyIndex); + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY); - if(keyIndex >= p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("impossible to remove key when numOfKeys <= keyIndex")); + if (keySize != p_CcNode->userSizeOfExtraction) + RETURN_ERROR( + MINOR, E_INVALID_VALUE, + ("Key size doesn't match the extraction size of the node")); - if(!p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("keyIndex you asked > numOfKeys of relevant node that was initialized")); + /* If user didn't pass a mask for this key, we'll look for full extraction mask */ + if (!p_Mask) + memset(tmpMask, 0xFF, keySize); - if(p_FmPcdCcNode->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time")); - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_REMOVE, TRUE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - err = BuildNewNodeRemoveKey (p_FmPcdCcNode, keyIndex, p_ModifyKeyParams); - if(err) + for (i = 0; i < p_CcNode->numOfKeys; i++) { - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst); - if(err) - { - ReleaseNewNodeCommonPart(p_ModifyKeyParams); - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - return E_OK; - -} - -t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst,t_Handle *h_AdditionalParams) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_Error err = E_OK; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; - - if(keyIndex >= p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1")); - - if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255")); - - if(keySize != p_FmPcdCcNode->userSizeOfExtraction) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size for ModifyKey has to be the same as defined in SetNode")); - - if(p_FmPcdCcNode->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time")); - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - - err = BuildNewNodeModifyKey (p_FmPcdCcNode, keyIndex, p_Key, p_Mask, p_ModifyKeyParams); - if(err) - { - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst); - if(err) - { - ReleaseNewNodeCommonPart(p_ModifyKeyParams); - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - return E_OK; -} - - -t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_Error err = E_OK; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_VALUE); - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_HANDLE); - - if(keyIndex >= p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1")); - - if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255")); - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, FALSE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - - err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams); - if(err) - { - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - return E_OK; -} - -t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_Error err = E_OK; - uint16_t keyIndex; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; - - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_VALUE); - - keyIndex = p_FmPcdCcNode->numOfKeys; - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - - err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams); - if(err) - { - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - return E_OK; -} - -t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; - t_Error err = E_OK; - - if(keyIndex > p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1")); - - if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255")); - - if(keySize != p_FmPcdCcNode->userSizeOfExtraction) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step.")); - - if(p_FmPcdCcNode->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time")); - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_ADD, TRUE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, TRUE); - if(err) - { - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst); - if(err) - { - ReleaseNewNodeCommonPart(p_ModifyKeyParams); - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - return E_OK; -} - -t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; - t_Error err = E_OK; - - if(keyIndex > p_FmPcdCcNode->numOfKeys) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1")); - - if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255")); - - if(keySize != p_FmPcdCcNode->userSizeOfExtraction) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step")); - - if(p_FmPcdCcNode->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time")); - - err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams; - - err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, FALSE); - if(err) - { - ReleaseNewNodeCommonPart(p_ModifyKeyParams); - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst); - if(err) - { - ReleaseNewNodeCommonPart(p_ModifyKeyParams); - XX_Free(p_ModifyKeyParams); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - return E_OK; -} - -t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params) -{ - t_FmPcdModifyCcKeyAdditionalParams *p_CcNewModifyAdditionalParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_Params; - t_List *p_Pos; - t_Error err = E_OK; - t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation; - t_Handle h_Muram; - t_FmPcdCcNode *p_FmPcdCcNextNode; - t_List *p_UpdateLst; - - UNUSED(numOfGoodChanges); - - SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_CcNewModifyAdditionalParams->h_CurrentNode,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdOldPointersLst)),E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_FmPcdOldPointersLst) == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE); - - /*we don't update subtree of the new node with new tree because it was done in the previose stage*/ - if(p_CcNewModifyAdditionalParams->h_NodeForAdd) - { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForAdd; - if(!p_CcNewModifyAdditionalParams->tree) - p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; - else - p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; - p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode); - if(p_CcNodeInformation) - p_CcNodeInformation->index++; - else + /* Comparing received key */ + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize) + == 0) { - memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - ccNodeInfo.h_CcNode = (t_Handle)p_CcNewModifyAdditionalParams->h_CurrentNode; - ccNodeInfo.index = 1; - EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo); + if (p_Mask) + { + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */ + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask, + keySize) == 0) + { + *p_KeyIndex = i; + return E_OK; + } + } + else + { + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */ + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask, + keySize) == 0) + { + *p_KeyIndex = i; + return E_OK; + } + } } } - if(p_CcNewModifyAdditionalParams->h_NodeForRmv) - { + return ERROR_CODE(E_NOT_FOUND); +} - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForRmv; - if(!p_CcNewModifyAdditionalParams->tree) +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode, + bool isKeyTblAlloc, + uint32_t *p_MatchTableSize, + uint32_t *p_AdTableSize) +{ + uint32_t shadowSize; + t_Error err; + + /* Calculate keys table maximal size - each entry consists of a key and a mask, + (if local mask support is requested) */ + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t) + * p_CcNode->maxNumOfKeys; + + if (p_CcNode->maskSupport) + *p_MatchTableSize *= 2; + + /* Calculate next action descriptors table, including one more entry for miss */ + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1) + * FM_PCD_CC_AD_ENTRY_SIZE); + + /* Calculate maximal shadow size of this node. + All shadow structures will be used for runtime modifications host command. If + keys table was allocated for this node, the keys table and next engines table may + be modified in run time (entries added or removed), so shadow tables are requires. + Otherwise, the only supported runtime modification is a specific next engine update + and this requires shadow memory of a single AD */ + + /* Shadow size should be enough to hold the following 3 structures: + * 1 - an action descriptor */ + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE; + + /* 2 - keys match table, if was allocated for the current node */ + if (isKeyTblAlloc) + shadowSize += *p_MatchTableSize; + + /* 3 - next action descriptors table */ + shadowSize += *p_AdTableSize; + + /* Update shadow to the calculated size */ + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize, + FM_PCD_CC_AD_TABLE_ALIGN); + if (err != E_OK) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow")); + } + + return E_OK; +} + +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode) +{ + t_FmPcdStatsObj *p_StatsObj; + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters; + uint32_t i; + + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); + if (!h_FmMuram) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); + + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters) + will be allocated to support runtime modifications */ + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++) + { + /* Allocate list object structure */ + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); + if (!p_StatsObj) { - p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; - LIST_FOR_EACH(p_Pos, &p_FmPcdCcNextNode->ccTreesLst) + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object")); + } + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj)); + + /* Allocate statistics AD from MURAM */ + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!h_StatsAd) + { + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); + XX_Free(p_StatsObj); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for statistics ADs")); + } + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Allocate statistics counters from MURAM */ + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( + h_FmMuram, p_CcNode->countersArraySize, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!h_StatsCounters) + { + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd); + XX_Free(p_StatsObj); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for statistics counters")); + } + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize); + + p_StatsObj->h_StatsAd = h_StatsAd; + p_StatsObj->h_StatsCounters = h_StatsCounters; + + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); + } + + return E_OK; +} + +static t_Error MatchTableGetKeyStatistics( + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, + t_FmPcdCcKeyStatistics *p_KeyStatistics) +{ + uint32_t *p_StatsCounters, i; + + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Statistics were not enabled for this match table")); + + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Statistics were not enabled for this key")); + + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics)); + + p_StatsCounters = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; + ASSERT_COND(p_StatsCounters); + + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters); + + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++) + { + p_StatsCounters = + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE); + + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters); + +#if (DPAA_VERSION >= 11) + p_KeyStatistics->frameLengthRangeCount[i - 1] = + GET_UINT32(*p_StatsCounters); +#endif /* (DPAA_VERSION >= 11) */ + } + + return E_OK; +} + +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, + t_FmPcdCcNodeParams *p_CcNodeParam) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdCcNode *p_FmPcdCcNextNode; + t_Error err = E_OK; + uint32_t tmp, keySize; + bool glblMask = FALSE; + t_FmPcdCcKeyParams *p_KeyParams; + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp; +#if (DPAA_VERSION >= 11) + t_Handle h_StatsFLRs; +#endif /* (DPAA_VERSION >= 11) */ + bool fullField = FALSE; + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE; + bool isKeyTblAlloc, fromIc = FALSE; + uint32_t matchTableSize, adTableSize; + t_CcNodeInformation ccNodeInfo, *p_CcInformation; + t_FmPcdStatsObj *p_StatsObj; + t_FmPcdCcStatsParams statsParams = { 0 }; + t_Handle h_Manip; + + ASSERT_COND(h_FmPcd); + ASSERT_COND(p_CcNode); + ASSERT_COND(p_CcNodeParam); + + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc( + CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + + p_CcNode->h_FmPcd = h_FmPcd; + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys; + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys; + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport; + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode; + + /* For backward compatibility - even if statistics mode is nullified, + we'll fix it to frame mode so we can support per-key request for + statistics using 'statisticsEn' in next engine parameters */ + if (!p_CcNode->maxNumOfKeys + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)) + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME; + + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd); + if (!h_FmMuram) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); + + INIT_LIST(&p_CcNode->ccPrevNodesLst); + INIT_LIST(&p_CcNode->ccTreeIdLst); + INIT_LIST(&p_CcNode->ccTreesLst); + INIT_LIST(&p_CcNode->availableStatsLst); + + p_CcNode->h_Spinlock = XX_InitSpinlock(); + if (!p_CcNode->h_Spinlock) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); + } + + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr + == HEADER_TYPE_IPv4) + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr + == HEADER_TYPE_IPv6)) + && (p_CcNodeParam->extractCcParams.extractByHdr.type + == e_FM_PCD_EXTRACT_FULL_FIELD) + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT) + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 + == NET_HEADER_FIELD_IPv4_TTL))) + { + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, + &isKeyTblAlloc); + glblMask = FALSE; + } + else + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src + == e_FM_PCD_EXTRACT_FROM_KEY) + || (p_CcNodeParam->extractCcParams.extractNonHdr.src + == e_FM_PCD_EXTRACT_FROM_HASH) + || (p_CcNodeParam->extractCcParams.extractNonHdr.src + == e_FM_PCD_EXTRACT_FROM_FLOW_ID))) + { + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src + == e_FM_PCD_EXTRACT_FROM_FLOW_ID) + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0)) { - p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); - ASSERT_COND(p_CcNodeInformation->h_CcNode); - err = FmPcdCcSetRequiredAction(h_FmPcd, - UPDATE_CC_WITH_DELETE_TREE, - &((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex], - PTR_MOVE(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable, p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), - 1, - p_CcNodeInformation->h_CcNode); + DeleteNode(p_CcNode); + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0")); + } + + icCode = IcDefineCode(p_CcNodeParam); + fromIc = TRUE; + if (icCode == CC_PRIVATE_INFO_NONE) + { + DeleteNode(p_CcNode); + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way")); + } + + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP)) + { + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, + &isKeyTblAlloc); + glblMask = TRUE; + } + else + { + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, + &isKeyTblAlloc); + if (p_CcNode->glblMaskSize) + glblMask = TRUE; } } else { - p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; - err = FmPcdCcSetRequiredAction(h_FmPcd, - UPDATE_CC_WITH_DELETE_TREE, - &((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex], - UINT_TO_PTR(((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), - 1, - p_CcNewModifyAdditionalParams->h_CurrentNode); + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc); + if (p_CcNode->glblMaskSize) + glblMask = TRUE; } - if(err) - return err; - /*we remove from the subtree of the removed node tree because it wasn't done in the previose stage*/ - /*update ccPrevNodesLst or ccTreeIdLst of the removed node*/ - /*update of the nodeOwner*/ - p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode); - ASSERT_COND(p_CcNodeInformation); - ASSERT_COND(p_CcNodeInformation->index); - p_CcNodeInformation->index--; - if(p_CcNodeInformation->index == 0) - DequeueNodeInfoFromRelevantLst(p_UpdateLst,p_CcNewModifyAdditionalParams->h_CurrentNode); - ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNextNode->ccTreesLst) == 1); - UpdateNodeOwner(p_FmPcdCcNextNode, FALSE); + if (err) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, err, NO_MSG); } -#ifdef FM_PCD_CC_MANIP - if(p_CcNewModifyAdditionalParams->h_ManipForRmv) - FmPcdManipUpdateOwner(p_CcNewModifyAdditionalParams->h_ManipForRmv, FALSE); -#endif /* FM_PCD_CC_MANIP */ - - h_Muram = FmPcdGetMuramHandle(h_FmPcd); - ASSERT_COND(h_Muram); - - /*we release new AD which was allocated and updated for copy from to actual AD*/ - LIST_FOR_EACH(p_Pos, h_FmPcdNewPointersLst) + switch (p_CcNodeParam->extractCcParams.type) { - p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); - ASSERT_COND(p_CcNodeInformation->h_CcNode); - FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode); + case (e_FM_PCD_EXTRACT_BY_HDR): + switch (p_CcNodeParam->extractCcParams.extractByHdr.type) + { + case (e_FM_PCD_EXTRACT_FULL_FIELD): + p_CcNode->parseCode = + GetFullFieldParseCode( + p_CcNodeParam->extractCcParams.extractByHdr.hdr, + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField); + GetSizeHeaderField( + p_CcNodeParam->extractCcParams.extractByHdr.hdr, + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, + &p_CcNode->sizeOfExtraction); + fullField = TRUE; + if ((p_CcNode->parseCode != CC_PC_FF_TCI1) + && (p_CcNode->parseCode != CC_PC_FF_TCI2) + && (p_CcNode->parseCode != CC_PC_FF_MPLS1) + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) + && (p_CcNode->parseCode + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) + && (p_CcNode->parseCode + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) + && glblMask) + { + glblMask = FALSE; + p_CcNode->glblMaskSize = 4; + p_CcNode->lclMask = TRUE; + } + break; - } + case (e_FM_PCD_EXTRACT_FROM_HDR): + p_CcNode->sizeOfExtraction = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size; + p_CcNode->offset = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; + p_CcNode->userOffset = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; + p_CcNode->parseCode = + GetPrParseCode( + p_CcNodeParam->extractCcParams.extractByHdr.hdr, + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, + p_CcNode->offset, glblMask, + &p_CcNode->prsArrayOffset); + break; - /*free Old data structure if it has to be freed - new data structure was allocated*/ - if(p_CcNewModifyAdditionalParams->p_AdTableOld) - FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_AdTableOld); - if(p_CcNewModifyAdditionalParams->p_KeysMatchTableOld) - FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_KeysMatchTableOld); + case (e_FM_PCD_EXTRACT_FROM_FIELD): + p_CcNode->offset = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; + p_CcNode->userOffset = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; + p_CcNode->sizeOfExtraction = + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size; + p_CcNode->parseCode = + GetFieldParseCode( + p_CcNodeParam->extractCcParams.extractByHdr.hdr, + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field, + p_CcNode->offset, + &p_CcNode->prsArrayOffset, + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex); + break; - /*update current modified node with changed fields if it's required*/ - if(!p_CcNewModifyAdditionalParams->tree) + default: + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); + } + break; + + case (e_FM_PCD_EXTRACT_NON_HDR): + /* get the field code for the generic extract */ + p_CcNode->sizeOfExtraction = + p_CcNodeParam->extractCcParams.extractNonHdr.size; + p_CcNode->offset = + p_CcNodeParam->extractCcParams.extractNonHdr.offset; + p_CcNode->userOffset = + p_CcNodeParam->extractCcParams.extractNonHdr.offset; + p_CcNode->parseCode = GetGenParseCode( + p_CcNodeParam->extractCcParams.extractNonHdr.src, + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset, + fromIc, icCode); + + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) + { + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8) + { + DeleteNode(p_CcNode); + RETURN_ERROR( + MAJOR, + E_INVALID_SELECTION, + ("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)")); + } + } + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK) + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) + { + p_CcNode->offset += p_CcNode->prsArrayOffset; + p_CcNode->prsArrayOffset = 0; + } + break; + + default: + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); + } + + if (p_CcNode->parseCode == CC_PC_ILLEGAL) { - if(p_CcNewModifyAdditionalParams->p_AdTableNew) - ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable = p_CcNewModifyAdditionalParams->p_AdTableNew; - if(p_CcNewModifyAdditionalParams->numOfKeys) - ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfKeys = p_CcNewModifyAdditionalParams->numOfKeys; - if(p_CcNewModifyAdditionalParams->p_KeysMatchTableNew) - ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_KeysMatchTable = p_CcNewModifyAdditionalParams->p_KeysMatchTableNew; - memcpy(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (FM_PCD_MAX_NUM_OF_KEYS)); + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); + } + + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) + || !p_CcNode->sizeOfExtraction) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("sizeOfExatrction can not be greater than 56 and not 0")); + } + + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("keySize has to be equal to sizeOfExtraction")); + } + + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction; + + if (!glblMask) + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode); + if (err != E_OK) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("keySize has to be equal to sizeOfExtraction")); + } + + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */ + GetCcExtractKeySize(p_CcNode->sizeOfExtraction, + &p_CcNode->ccKeySizeAccExtraction); + + /* If local mask is used, it is stored next to each key in the keys match table */ + if (p_CcNode->lclMask) + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); + else + keySize = p_CcNode->ccKeySizeAccExtraction; + + /* Update CC shadow with maximal size required by this node */ + if (p_CcNode->maxNumOfKeys) + { + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize, + &adTableSize); + if (err != E_OK) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + p_CcNode->keysMatchTableMaxSize = matchTableSize; + + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE) + { + err = AllocStatsObjs(p_CcNode); + if (err != E_OK) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + /* If manipulation will be initialized before this node, it will use the table + descriptor in the AD table of previous node and this node will need an extra + AD as his table descriptor. */ + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem( + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_CcNode->h_TmpAd) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC action descriptor")); + } } else - memcpy(&((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfEntries)); + { + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t) + * (p_CcNode->numOfKeys + 1)); + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE + * (p_CcNode->numOfKeys + 1)); + } - ReleaseLst(h_FmPcdOldPointersLst); - ReleaseLst(h_FmPcdNewPointersLst); - XX_Free(p_CcNewModifyAdditionalParams); +#if (DPAA_VERSION >= 11) + switch (p_CcNode->statisticsMode) + { + + case e_FM_PCD_CC_STATS_MODE_RMON: + /* If RMON statistics or RMON conditional statistics modes are requested, + allocate frame length ranges array */ + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem( + h_FmMuram, + (uint32_t)(p_CcNode->numOfStatsFLRs) + * FM_PCD_CC_STATS_FLR_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + + if (!p_CcNode->h_StatsFLRs) + { + DeleteNode(p_CcNode); + RETURN_ERROR( + MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC frame length ranges array")); + } + + /* Initialize using value received from the user */ + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++) + { + uint16_t flr = + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]); + + h_StatsFLRs = + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE); + + MemCpy8(h_StatsFLRs, + &flr, + FM_PCD_CC_STATS_FLR_SIZE); + } + break; + + default: + break; + } +#endif /* (DPAA_VERSION >= 11) */ + + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL + identification, IPv6 hop count identification, etc. */ + if (isKeyTblAlloc) + { + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem( + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); + if (!p_CcNode->h_KeysMatchTable) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC node key match table")); + } + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize); + } + + /* Allocate action descriptors table */ + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_CcNode->h_AdTable) + { + DeleteNode(p_CcNode); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC node action descriptors table")); + } + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize); + + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable; + p_AdTableTmp = p_CcNode->h_AdTable; + + /* For each key, create the key and the next step AD */ + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) + { + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; + + if (p_KeysMatchTblTmp) + { + /* Copy the key */ + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, + p_CcNode->sizeOfExtraction); + + /* Copy the key mask or initialize it to 0xFF..F */ + if (p_CcNode->lclMask && p_KeyParams->p_Mask) + { + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp, + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ + } + else + if (p_CcNode->lclMask) + { + MemSet8(PTR_MOVE(p_KeysMatchTblTmp, + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ + } + + p_KeysMatchTblTmp = + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t)); + } + + /* Create the next action descriptor in the match table */ + if (p_KeyParams->ccNextEngineParams.statisticsEn) + { + p_StatsObj = GetStatsObj(p_CcNode); + ASSERT_COND(p_StatsObj); + + statsParams.h_StatsAd = p_StatsObj->h_StatsAd; + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; +#if (DPAA_VERSION >= 11) + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; + +#endif /* (DPAA_VERSION >= 11) */ + NextStepAd(p_AdTableTmp, &statsParams, + &p_KeyParams->ccNextEngineParams, p_FmPcd); + + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; + } + else + { + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams, + p_FmPcd); + + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; + } + + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); + } + + /* Update next engine for the 'miss' entry */ + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn) + { + p_StatsObj = GetStatsObj(p_CcNode); + ASSERT_COND(p_StatsObj); + + /* All 'bucket' nodes of a hash table should share the same statistics counters, + allocated by the hash table. So, if this node is a bucket of a hash table, + we'll replace the locally allocated counters with the shared counters. */ + if (p_CcNode->isHashBucket) + { + ASSERT_COND(p_CcNode->h_MissStatsCounters); + + /* Store original counters pointer and replace it with mutual preallocated pointer */ + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters; + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters; + } + + statsParams.h_StatsAd = p_StatsObj->h_StatsAd; + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; +#if (DPAA_VERSION >= 11) + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; + +#endif /* (DPAA_VERSION >= 11) */ + + NextStepAd(p_AdTableTmp, &statsParams, + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + p_FmPcd); + + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; + } + else + { + NextStepAd(p_AdTableTmp, NULL, + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, + p_FmPcd); + + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; + } + + /* This parameter will be used to initialize the "key length" field in the action descriptor + that points to this node and it should be 0 for full field extraction */ + if (fullField == TRUE) + p_CcNode->sizeOfExtraction = 0; + + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) + { + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine + == e_FM_PCD_CC) + { + p_FmPcdCcNextNode = + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode; + p_CcInformation = FindNodeInfoInReleventLst( + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode, + p_FmPcdCcNextNode->h_Spinlock); + if (!p_CcInformation) + { + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; + ccNodeInfo.index = 1; + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, + &ccNodeInfo, + p_FmPcdCcNextNode->h_Spinlock); + } + else + p_CcInformation->index++; + + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) + { + h_Manip = + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip; + p_CcInformation = FindNodeInfoInReleventLst( + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip)); + if (!p_CcInformation) + { + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; + ccNodeInfo.index = 1; + EnqueueNodeInfoToRelevantLst( + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip)); + } + else + p_CcInformation->index++; + } + } + } + + p_AdTableTmp = p_CcNode->h_AdTable; + + if (!FmPcdLockTryLockAll(h_FmPcd)) + { + FM_PCD_MatchTableDelete((t_Handle)p_CcNode); + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + /* Required action for each next engine */ + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) + { + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction) + { + err = SetRequiredAction( + h_FmPcd, + p_CcNode->keyAndNextEngineParams[tmp].requiredAction, + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1, + NULL); + if (err) + { + FmPcdLockUnlockAll(h_FmPcd); + FM_PCD_MatchTableDelete((t_Handle)p_CcNode); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); + } + } + + FmPcdLockUnlockAll(h_FmPcd); + + return E_OK; +} +/************************** End of static functions **************************/ + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, + t_Handle h_Spinlock) +{ + t_CcNodeInformation *p_CcInformation; + t_List *p_Pos; + uint32_t intFlags; + + intFlags = XX_LockIntrSpinlock(h_Spinlock); + + for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); + p_Pos = NCSW_LIST_NEXT(p_Pos)) + { + p_CcInformation = CC_NODE_F_OBJECT(p_Pos); + + ASSERT_COND(p_CcInformation->h_CcNode); + + if (p_CcInformation->h_CcNode == h_Info) + { + XX_UnlockIntrSpinlock(h_Spinlock, intFlags); + return p_CcInformation; + } + } + + XX_UnlockIntrSpinlock(h_Spinlock, intFlags); + + return NULL; +} + +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, + t_Handle h_Spinlock) +{ + t_CcNodeInformation *p_CcInformation; + uint32_t intFlags = 0; + + p_CcInformation = (t_CcNodeInformation *)XX_Malloc( + sizeof(t_CcNodeInformation)); + + if (p_CcInformation) + { + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation)); + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation)); + INIT_LIST(&p_CcInformation->node); + + if (h_Spinlock) + intFlags = XX_LockIntrSpinlock(h_Spinlock); + + NCSW_LIST_AddToTail(&p_CcInformation->node, p_List); + + if (h_Spinlock) + XX_UnlockIntrSpinlock(h_Spinlock, intFlags); + } + else + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information")); +} + +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, + t_Handle h_Spinlock) +{ + t_CcNodeInformation *p_CcInformation = NULL; + uint32_t intFlags = 0; + t_List *p_Pos; + + if (h_Spinlock) + intFlags = XX_LockIntrSpinlock(h_Spinlock); + + if (NCSW_LIST_IsEmpty(p_List)) + { + XX_RestoreAllIntr(intFlags); + return; + } + + for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); + p_Pos = NCSW_LIST_NEXT(p_Pos)) + { + p_CcInformation = CC_NODE_F_OBJECT(p_Pos); + ASSERT_COND(p_CcInformation); + ASSERT_COND(p_CcInformation->h_CcNode); + if (p_CcInformation->h_CcNode == h_Info) + break; + } + + if (p_CcInformation) + { + NCSW_LIST_DelAndInit(&p_CcInformation->node); + XX_Free(p_CcInformation); + } + + if (h_Spinlock) + XX_UnlockIntrSpinlock(h_Spinlock, intFlags); +} + +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, + t_FmPcd *p_FmPcd) +{ + switch (p_FmPcdCcNextEngineParams->nextEngine) + { + case (e_FM_PCD_KG): + case (e_FM_PCD_PLCR): + case (e_FM_PCD_DONE): + /* if NIA is not CC, create a "result" type AD */ + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd, + p_FmPcdCcNextEngineParams); + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_FR): + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) + { + FillAdOfTypeContLookup( + h_Ad, p_FmPcdCcStatsParams, p_FmPcd, + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, + p_FmPcdCcNextEngineParams->h_Manip, + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); + FrmReplicGroupUpdateOwner( + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic, + TRUE/* add */); + } + break; +#endif /* (DPAA_VERSION >= 11) */ + + case (e_FM_PCD_CC): + /* if NIA is not CC, create a TD to continue the CC lookup */ + FillAdOfTypeContLookup( + h_Ad, p_FmPcdCcStatsParams, p_FmPcd, + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, + p_FmPcdCcNextEngineParams->h_Manip, NULL); + + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, + TRUE); + break; + + default: + return; + } +} + +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip, + bool createSchemes) +{ + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + t_FmPcdCcNextEngineParams nextEngineParams; + t_NetEnvParams netEnvParams; + t_Handle h_Ad; + bool isIpv6Present; + uint8_t ipv4GroupId, ipv6GroupId; + t_Error err; + + ASSERT_COND(p_FmPcdCcTree); + + /* this routine must be protected by the calling routine! */ + + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); + memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); + + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); + + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip); + + if (isIpv6Present + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); + + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); + + nextEngineParams.nextEngine = e_FM_PCD_DONE; + nextEngineParams.h_Manip = h_IpReassemblyManip; + + /* Lock tree */ + err = CcRootTryLock(p_FmPcdCcTree); + if (err) + return ERROR_CODE(E_BUSY); + + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip) + { + CcRootReleaseLock(p_FmPcdCcTree); + return E_OK; + } + + if ((p_FmPcdCcTree->h_IpReassemblyManip) + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip)) + { + CcRootReleaseLock(p_FmPcdCcTree); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("This tree was previously updated with different IPR")); + } + + /* Initialize IPR for the first time for this tree */ + if (isIpv6Present) + { + ipv6GroupId = p_FmPcdCcTree->numOfGrps++; + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry = + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2); + + if (createSchemes) + { + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, + p_FmPcdCcTree, + h_IpReassemblyManip, FALSE, + ipv6GroupId); + if (err) + { + p_FmPcdCcTree->numOfGrps--; + CcRootReleaseLock(p_FmPcdCcTree); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + NextStepAd( + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE), + NULL, &nextEngineParams, h_FmPcd); + } + + ipv4GroupId = p_FmPcdCcTree->numOfGrps++; + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0; + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry = + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); + + if (createSchemes) + { + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree, + h_IpReassemblyManip, TRUE, + ipv4GroupId); + if (err) + { + p_FmPcdCcTree->numOfGrps--; + if (isIpv6Present) + { + p_FmPcdCcTree->numOfGrps--; + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip); + } + CcRootReleaseLock(p_FmPcdCcTree); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + NextStepAd( + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), + NULL, &nextEngineParams, h_FmPcd); + + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip; + + CcRootReleaseLock(p_FmPcdCcTree); return E_OK; } -uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer) +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, + t_Handle h_NetEnv, t_Handle h_ReassemblyManip, + bool createSchemes) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_CcNodeInformation *p_CcNodeInfo; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + t_FmPcdCcNextEngineParams nextEngineParams; + t_NetEnvParams netEnvParams; + t_Handle h_Ad; + uint8_t groupId; + t_Error err; - SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, (uint32_t)ILLEGAL_BASE); + ASSERT_COND(p_FmPcdCcTree); - p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer); - return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) - p_FmPcd->physicalMuramBase); + /* this routine must be protected by the calling routine! */ + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); + memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); + + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); + + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR")); + + nextEngineParams.nextEngine = e_FM_PCD_DONE; + nextEngineParams.h_Manip = h_ReassemblyManip; + + /* Lock tree */ + err = CcRootTryLock(p_FmPcdCcTree); + if (err) + return ERROR_CODE(E_BUSY); + + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip) + { + CcRootReleaseLock(p_FmPcdCcTree); + return E_OK; + } + + if ((p_FmPcdCcTree->h_CapwapReassemblyManip) + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip)) + { + CcRootReleaseLock(p_FmPcdCcTree); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("This tree was previously updated with different CPR")); + } + + groupId = p_FmPcdCcTree->numOfGrps++; + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry = + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); + + if (createSchemes) + { + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv, + p_FmPcdCcTree, + h_ReassemblyManip, groupId); + if (err) + { + p_FmPcdCcTree->numOfGrps--; + CcRootReleaseLock(p_FmPcdCcTree); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + NextStepAd( + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), + NULL, &nextEngineParams, h_FmPcd); + + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip; + + CcRootReleaseLock(p_FmPcdCcTree); + + return E_OK; } -t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase) +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree) { - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *) h_FmPcdCcTree; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + + ASSERT_COND(p_FmPcdCcTree); + + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams; +} + +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, + t_Handle h_SavedManipParams) +{ + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; + + ASSERT_COND(p_FmPcdCcTree); + + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams; +} + +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + + ASSERT_COND(p_CcNode); + + return p_CcNode->parseCode; +} + +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + + ASSERT_COND(p_CcNode); + + return p_CcNode->offset; +} + +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + + ASSERT_COND(p_CcNode); + + return p_CcNode->numOfKeys; +} + +t_Error FmPcdCcModifyNextEngineParamTree( + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; + t_FmPcd *p_FmPcd; + t_List h_OldPointersLst, h_NewPointersLst; + uint16_t keyIndex; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE); + + if (grpId >= p_FmPcdCcTree->numOfGrps) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, + ("grpId you asked > numOfGroup of relevant tree")); + + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup")); + + p_FmPcd = (t_FmPcd *)h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry + + index); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex, + e_MODIFY_STATE_CHANGE, FALSE, + FALSE, TRUE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + p_ModifyKeyParams->tree = TRUE; + + if (p_FmPcd->p_CcShadow + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex, + p_FmPcdCcNextEngineParams, + &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams); + if (err) + { + XX_Free(p_ModifyKeyParams); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, FALSE); + + if (p_FmPcd->p_CcShadow) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; + +} + +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + uint16_t keyIndex) +{ + + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + t_List h_OldPointersLst, h_NewPointersLst; + bool useShadowStructs = FALSE; + t_Error err = E_OK; + + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("impossible to remove key when numOfKeys <= keyIndex")); + + if (p_CcNode->h_FmPcd != h_FmPcd) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("handler to FmPcd is different from the handle provided at node initialization time")); + + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_REMOVE, TRUE, TRUE, + FALSE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_CcNode->maxNumOfKeys) + { + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + useShadowStructs = TRUE; + } + + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams); + if (err) + { + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, + &h_OldPointersLst, + &h_NewPointersLst); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, useShadowStructs); + + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; +} + +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, + uint8_t *p_Mask) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_List h_OldPointersLst, h_NewPointersLst; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + uint16_t tmpKeyIndex; + bool useShadowStructs = FALSE; + t_Error err = E_OK; + + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("keyIndex > previously cleared last index + 1")); + + if (keySize != p_CcNode->userSizeOfExtraction) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("size for ModifyKey has to be the same as defined in SetNode")); + + if (p_CcNode->h_FmPcd != h_FmPcd) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("handler to FmPcd is different from the handle provided at node initialization time")); + + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex); + if (GET_ERROR_TYPE(err) != E_NOT_FOUND) + RETURN_ERROR( + MINOR, + E_ALREADY_EXISTS, + ("The received key and mask pair was already found in the match table of the provided node")); + + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_CHANGE, TRUE, TRUE, + FALSE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_CcNode->maxNumOfKeys) + { + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + useShadowStructs = TRUE; + } + + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask, + p_ModifyKeyParams); + if (err) + { + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, + &h_OldPointersLst, + &h_NewPointersLst); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, useShadowStructs); + + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; +} + +t_Error FmPcdCcModifyMissNextEngineParamNode( + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_List h_OldPointersLst, h_NewPointersLst; + uint16_t keyIndex; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE); + + keyIndex = p_CcNode->numOfKeys; + + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_CHANGE, FALSE, TRUE, + FALSE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_CcNode->maxNumOfKeys + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcNextEngineParams, + &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams); + if (err) + { + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, FALSE); + + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; +} + +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + uint16_t keyIndex, uint8_t keySize, + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + t_List h_OldPointersLst, h_NewPointersLst; + bool useShadowStructs = FALSE; + uint16_t tmpKeyIndex; + t_Error err = E_OK; + + if (keyIndex > p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, + ("keyIndex > previously cleared last index + 1")); + + if (keySize != p_CcNode->userSizeOfExtraction) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("keySize has to be defined as it was defined in initialization step")); + + if (p_CcNode->h_FmPcd != h_FmPcd) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("handler to FmPcd is different from the handle provided at node initialization time")); + + if (p_CcNode->maxNumOfKeys) + { + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys) + RETURN_ERROR( + MAJOR, + E_FULL, + ("number of keys exceeds the maximal number of keys provided at node initialization time")); + } + else + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS)); + + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); + if (GET_ERROR_TYPE(err) != E_NOT_FOUND) + RETURN_ERROR( + MAJOR, + E_ALREADY_EXISTS, + ("The received key and mask pair was already found in the match table of the provided node")); + + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_ADD, TRUE, TRUE, + FALSE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_CcNode->maxNumOfKeys) + { + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + useShadowStructs = TRUE; + } + + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcKeyParams, + p_ModifyKeyParams, TRUE); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, + &h_OldPointersLst, + &h_NewPointersLst); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, useShadowStructs); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; +} + +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + uint16_t keyIndex, uint8_t keySize, + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_FmPcd *p_FmPcd; + t_List h_OldPointersLst, h_NewPointersLst; + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; + uint16_t tmpKeyIndex; + bool useShadowStructs = FALSE; + t_Error err = E_OK; + + if (keyIndex > p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("keyIndex > previously cleared last index + 1")); + + if (keySize != p_CcNode->userSizeOfExtraction) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("keySize has to be defined as it was defined in initialization step")); + + if (p_CcNode->h_FmPcd != h_FmPcd) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("handler to FmPcd is different from the handle provided at node initialization time")); + + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); + if (GET_ERROR_TYPE(err) != E_NOT_FOUND) + RETURN_ERROR( + MINOR, + E_ALREADY_EXISTS, + ("The received key and mask pair was already found in the match table of the provided node")); + + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + + INIT_LIST(&h_OldPointersLst); + INIT_LIST(&h_NewPointersLst); + + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, + e_MODIFY_STATE_CHANGE, TRUE, TRUE, + FALSE); + if (!p_ModifyKeyParams) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_CcNode->maxNumOfKeys) + { + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + { + XX_Free(p_ModifyKeyParams); + return ERROR_CODE(E_BUSY); + } + + useShadowStructs = TRUE; + } + + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcKeyParams, + p_ModifyKeyParams, FALSE); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, + &h_OldPointersLst, + &h_NewPointersLst); + if (err) + { + ReleaseNewNodeCommonPart(p_ModifyKeyParams); + XX_Free(p_ModifyKeyParams); + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, + p_ModifyKeyParams, useShadowStructs); + + if (p_CcNode->maxNumOfKeys) + RELEASE_LOCK(p_FmPcd->shadowLock); + + return err; +} + +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, + t_Handle h_Pointer) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_CcNodeInformation *p_CcNodeInfo; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, + (uint32_t)ILLEGAL_BASE); + + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer); + + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) + - p_FmPcd->physicalMuramBase); +} + +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, + uint32_t *p_GrpBits, uint8_t *p_GrpBase) +{ + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); - if(grpId >= p_FmPcdCcTree->numOfGrps) - RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree")); + if (grpId >= p_FmPcdCcTree->numOfGrps) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, + ("grpId you asked > numOfGroup of relevant tree")); + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask; *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry; + return E_OK; } -t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint32_t *p_Offset, t_Handle h_FmPort) +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPcdCcTree, uint32_t *p_Offset, + t_Handle h_FmPort) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; - t_Error err = E_OK; + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; + t_Error err = E_OK; - SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); - FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, TRUE); + /* this routine must be protected by the calling routine by locking all PCD modules! */ - *p_Offset = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) - - p_FmPcd->physicalMuramBase); + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE); - err = CcUpdateParams(h_FmPcd, h_FmPort, h_FmPcdCcTree, TRUE); + if (err == E_OK) + UpdateCcRootOwner(p_FmPcdCcTree, TRUE); + + *p_Offset = (uint32_t)(XX_VirtToPhys( + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) + - p_FmPcd->physicalMuramBase); return err; } -t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree) +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree) { - t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; + + /* this routine must be protected by the calling routine by locking all PCD modules! */ UNUSED(h_FmPcd); - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); - FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, FALSE); + UpdateCcRootOwner(p_FmPcdCcTree, FALSE); return E_OK; } -t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree) +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, + t_List *p_List) { - if (TRY_LOCK(NULL, &((t_FmPcdCcTree *)h_FmPcdCcTree)->lock)) - return E_OK; - return ERROR_CODE(E_BUSY); -} + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; + t_List *p_Pos, *p_Tmp; + t_CcNodeInformation *p_CcNodeInfo, nodeInfo; + uint32_t intFlags; + t_Error err = E_OK; -t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; - t_List *p_Pos; - t_CcNodeInformation *p_CcNodeInfo, nodeInfo; - t_Error err = E_OK; + intFlags = FmPcdLock(h_FmPcd); - UNUSED(h_FmPcd); - - if(LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst)) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("asked for more nodes in CC than MAX")) ; - LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst) + NCSW_LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) { p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); ASSERT_COND(p_CcNodeInfo->h_CcNode); - err = FmPcdCcTreeTryLock(p_CcNodeInfo->h_CcNode); - if(err == E_OK) + + err = CcRootTryLock(p_CcNodeInfo->h_CcNode); + + if (err) { - memset(&nodeInfo, 0, sizeof(t_CcNodeInformation)); - nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode; - EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo); + NCSW_LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst) + { + if (p_Tmp == p_Pos) + break; + + CcRootReleaseLock(p_CcNodeInfo->h_CcNode); + } + break; } - else - FmPcdCcNodeTreeReleaseLock(p_List); + + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation)); + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode; + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL); } + FmPcdUnlock(h_FmPcd, intFlags); + CORE_MemoryBarrier(); + return err; } -t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsParam) +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_Error err = E_OK; - int i = 0, j = 0, k = 0; - t_FmPcdCcTree *p_FmPcdCcTree; - uint8_t numOfEntries; - t_Handle p_CcTreeTmp; - t_FmPcdCcGrpParams *p_FmPcdCcGroupParams; - t_FmPcdCcNextEngineAndRequiredActionParams params[16]; - t_NetEnvParams netEnvParams; - uint8_t lastOne = 0; - uint32_t requiredAction = 0; - t_FmPcdCcNode *p_FmPcdCcNextNode; - t_CcNodeInformation ccNodeInfo, *p_CcInformation; + t_List *p_Pos; + t_CcNodeInformation *p_CcNodeInfo; + t_Handle h_FmPcdCcTree; + uint32_t intFlags; - SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam,E_INVALID_HANDLE, NULL); + intFlags = FmPcdLock(h_FmPcd); + + NCSW_LIST_FOR_EACH(p_Pos, p_List) + { + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode; + CcRootReleaseLock(h_FmPcdCcTree); + } + + ReleaseLst(p_List); + + FmPcdUnlock(h_FmPcd, intFlags); + CORE_MemoryBarrier(); +} + +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align) +{ + uint32_t intFlags; + uint32_t newSize = 0, newAlign = 0; + bool allocFail = FALSE; + + ASSERT_COND(p_FmPcd); + + if (!size) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0")); + + if (!POWER_OF_2(align)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2")); + + newSize = p_FmPcd->ccShadowSize; + newAlign = p_FmPcd->ccShadowAlign; + + /* Check if current shadow is large enough to hold the requested size */ + if (size > p_FmPcd->ccShadowSize) + newSize = size; + + /* Check if current shadow matches the requested alignment */ + if (align > p_FmPcd->ccShadowAlign) + newAlign = align; + + /* If a bigger shadow size or bigger shadow alignment are required, + a new shadow will be allocated */ + if ((newSize != p_FmPcd->ccShadowSize) + || (newAlign != p_FmPcd->ccShadowAlign)) + { + intFlags = FmPcdLock(p_FmPcd); + + if (p_FmPcd->p_CcShadow) + { + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow); + p_FmPcd->ccShadowSize = 0; + p_FmPcd->ccShadowAlign = 0; + } + + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), + newSize, newAlign); + if (!p_FmPcd->p_CcShadow) + { + allocFail = TRUE; + + /* If new shadow size allocation failed, + re-allocate with previous parameters */ + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem( + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize, + p_FmPcd->ccShadowAlign); + } + + FmPcdUnlock(p_FmPcd, intFlags); + + if (allocFail) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for CC Shadow memory")); + + p_FmPcd->ccShadowSize = newSize; + p_FmPcd->ccShadowAlign = newAlign; + } + + return E_OK; +} + +#if (DPAA_VERSION >= 11) +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, + t_Handle h_ReplicGroup, + t_List *p_AdTables, + uint32_t *p_NumOfAdTables) +{ + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node; + int i = 0; + void * p_AdTable; + t_CcNodeInformation ccNodeInfo; + + ASSERT_COND(h_Node); + *p_NumOfAdTables = 0; + + /* search in the current node which exact index points on this current replicator group for getting AD */ + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++) + { + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic + == (t_Handle)h_ReplicGroup))) + { + /* save the current ad table in the list */ + /* this entry uses the input replicator group */ + p_AdTable = + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = p_AdTable; + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL); + (*p_NumOfAdTables)++; + } + } + + ASSERT_COND(i != p_CurrentNode->numOfKeys); +} +#endif /* (DPAA_VERSION >= 11) */ +/*********************** End of inter-module routines ************************/ + +/****************************************/ +/* API Init unit functions */ +/****************************************/ + +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd, + t_FmPcdCcTreeParams *p_PcdGroupsParam) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_Error err = E_OK; + int i = 0, j = 0, k = 0; + t_FmPcdCcTree *p_FmPcdCcTree; + uint8_t numOfEntries; + t_Handle p_CcTreeTmp; + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams; + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams; + t_NetEnvParams netEnvParams; + uint8_t lastOne = 0; + uint32_t requiredAction = 0; + t_FmPcdCcNode *p_FmPcdCcNextNode; + t_CcNodeInformation ccNodeInfo, *p_CcInformation; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL); if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS) { @@ -2788,44 +6018,77 @@ t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsPa } p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree)); - if(!p_FmPcdCcTree) + if (!p_FmPcdCcTree) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure")); return NULL; } - memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)) ; - memset(params, 0, 16 * sizeof(t_FmPcdCcNextEngineParams)); + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)); + p_FmPcdCcTree->h_FmPcd = h_FmPcd; + + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc( + FM_PCD_MAX_NUM_OF_CC_GROUPS + * sizeof(t_FmPcdCcKeyAndNextEngineParams)); + memset(p_Params, + 0, + FM_PCD_MAX_NUM_OF_CC_GROUPS + * sizeof(t_FmPcdCcKeyAndNextEngineParams)); INIT_LIST(&p_FmPcdCcTree->fmPortsLst); +#ifdef FM_CAPWAP_SUPPORT + if ((p_PcdGroupsParam->numOfGrps == 1) && + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) && + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) && + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode && + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode)) + { + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild(); + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip) + { + DeleteTree(p_FmPcdCcTree,p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + return NULL; + } + } +#endif /* FM_CAPWAP_SUPPORT */ + numOfEntries = 0; - p_FmPcdCcTree->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdGroupsParam->h_NetEnv)-1); - for(i = 0; i < p_PcdGroupsParam->numOfGrps; i++) + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv); + + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++) { p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i]; - if (p_FmPcdCcGroupParams->numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_CC_UNITS) + if (p_FmPcdCcGroupParams->numOfDistinctionUnits + > FM_PCD_MAX_NUM_OF_CC_UNITS) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS)); + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS)); return NULL; } p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries; - p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup =(uint8_t)( 0x01 << p_FmPcdCcGroupParams->numOfDistinctionUnits); + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01 + << p_FmPcdCcGroupParams->numOfDistinctionUnits); numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; - if(numOfEntries > 16) + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than 16")); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); return NULL; } - if(lastOne) + + if (lastOne) { - if(p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order")); return NULL; } @@ -2834,112 +6097,160 @@ t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsPa lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId; - netEnvParams.numOfDistinctionUnits = p_FmPcdCcGroupParams->numOfDistinctionUnits; - memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits); + netEnvParams.numOfDistinctionUnits = + p_FmPcdCcGroupParams->numOfDistinctionUnits; + + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits); + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); - if(err) + if (err) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); REPORT_ERROR(MAJOR, err, NO_MSG); return NULL; } p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector; - for(j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; j++) + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; + j++) { - err = ValidateNextEngineParams(h_FmPcd,&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j]); - if(err) + err = ValidateNextEngineParams( + h_FmPcd, + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], + e_FM_PCD_CC_STATS_MODE_NONE); + if (err) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); REPORT_ERROR(MAJOR, err, (NO_MSG)); return NULL; } -#ifdef FM_PCD_CC_MANIP - if(p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) { - err = FmPcdManipCheckParamsForCcNextEgine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction); - if(err) + err = FmPcdManipCheckParamsForCcNextEngine( + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], + &requiredAction); + if (err) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); return NULL; } - } -#endif /* FM_PCD_CC_MANIP */ + } + p_KeyAndNextEngineParams = p_Params + k; - memcpy(¶ms[k].nextEngineParams, &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], sizeof(t_FmPcdCcNextEngineParams)); - requiredAction |= UPDATE_CC_WITH_TREE; - params[k].requiredAction = requiredAction; - k++; + memcpy(&p_KeyAndNextEngineParams->nextEngineParams, + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], + sizeof(t_FmPcdCcNextEngineParams)); + + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine + == e_FM_PCD_CC) + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip) + { + err = + AllocAndFillAdForContLookupManip( + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode); + if (err) + { + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); + return NULL; + } + } + + requiredAction |= UPDATE_CC_WITH_TREE; + p_KeyAndNextEngineParams->requiredAction = requiredAction; + + k++; } } p_FmPcdCcTree->numOfEntries = (uint8_t)k; p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps; - p_FmPcdCcTree->ccTreeBaseAddr = - PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), - (uint32_t)( k * FM_PCD_CC_AD_ENTRY_SIZE), - FM_PCD_CC_AD_TABLE_ALIGN)); - if(!p_FmPcdCcTree->ccTreeBaseAddr) + p_FmPcdCcTree->ccTreeBaseAddr = + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE), + FM_PCD_CC_TREE_ADDR_ALIGN)); + if (!p_FmPcdCcTree->ccTreeBaseAddr) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); + DeleteTree(p_FmPcdCcTree, p_FmPcd); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); return NULL; } - IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(k * FM_PCD_CC_AD_ENTRY_SIZE)); + MemSet8( + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE)); p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); - j = 0; - for(i = 0; i < numOfEntries; i++) + for (i = 0; i < numOfEntries; i++) { - NextStepAd(p_CcTreeTmp,¶ms[i].nextEngineParams,p_FmPcd); + p_KeyAndNextEngineParams = p_Params + i; + + NextStepAd(p_CcTreeTmp, NULL, + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd); + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); - memcpy(&p_FmPcdCcTree->nextEngineAndRequiredAction[i], ¶ms[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams)); - if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine== e_FM_PCD_CC) + + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i], + p_KeyAndNextEngineParams, + sizeof(t_FmPcdCcKeyAndNextEngineParams)); + + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode; - if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode)) + p_FmPcdCcNextNode = + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + p_CcInformation = FindNodeInfoInReleventLst( + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree, + p_FmPcdCcNextNode->h_Spinlock); + + if (!p_CcInformation) { memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree; ccNodeInfo.index = 1; - EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, &ccNodeInfo); - UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE); + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, + &ccNodeInfo, + p_FmPcdCcNextNode->h_Spinlock); } else - { - p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst,(t_Handle)p_FmPcdCcTree); - ASSERT_COND(p_CcInformation); p_CcInformation->index++; - } } } FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId); p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); - for(i = 0; i < p_FmPcdCcTree->numOfEntries ; i++) + if (!FmPcdLockTryLockAll(p_FmPcd)) { - if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode; - - if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode)) - UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE); - } + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return NULL; } - for(i = 0; i < numOfEntries; i++) + for (i = 0; i < numOfEntries; i++) { - if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction) + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction) { - err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction, &p_FmPcdCcTree->nextEngineAndRequiredAction[i], p_CcTreeTmp,1, p_FmPcdCcTree); - if(err) + err = SetRequiredAction( + h_FmPcd, + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction, + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1, + p_FmPcdCcTree); + if (err) { - DeleteTree(p_FmPcdCcTree,p_FmPcd); + FmPcdLockUnlockAll(p_FmPcd); + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); return NULL; } @@ -2947,521 +6258,1294 @@ t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsPa } } + FmPcdLockUnlockAll(p_FmPcd); + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd); + if (!p_FmPcdCcTree->p_Lock) + { + FM_PCD_CcRootDelete(p_FmPcdCcTree); + XX_Free(p_Params); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock")); + return NULL; + } + + XX_Free(p_Params); + return p_FmPcdCcTree; } -t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree) +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; - int i= 0; + t_FmPcd *p_FmPcd; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; + int i = 0; + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE); - FmPcdDecNetEnvOwners(h_FmPcd, p_CcTree->netEnvId); + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId); - if(p_CcTree->owners) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree")); + if (p_CcTree->owners) + RETURN_ERROR( + MAJOR, + E_INVALID_SELECTION, + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree")); - for(i = 0; i numOfEntries; i++) + /* Delete ip-reassembly schemes if exist */ + if (p_CcTree->h_IpReassemblyManip) { - if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - UpdateNodeOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE); + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); } -#ifdef FM_PCD_CC_MANIP - for(i = 0; i < p_CcTree->numOfEntries; i++) + /* Delete capwap-reassembly schemes if exist */ + if (p_CcTree->h_CapwapReassemblyManip) { - if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip) - FmPcdManipUpdateOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE); + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip); + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE); } -#endif /* FM_PCD_CC_MANIP */ + + for (i = 0; i < p_CcTree->numOfEntries; i++) + { + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) + UpdateNodeOwner( + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, + FALSE); + + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip) + FmPcdManipUpdateOwner( + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip, + FALSE); + +#ifdef FM_CAPWAP_SUPPORT + if ((p_CcTree->numOfGrps == 1) && + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) && + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) && + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode && + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode)) + { + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK) + return E_INVALID_STATE; + } +#endif /* FM_CAPWAP_SUPPORT */ + +#if (DPAA_VERSION >= 11) + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) + FrmReplicGroupUpdateOwner( + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, + FALSE); +#endif /* (DPAA_VERSION >= 11) */ + } + + if (p_CcTree->p_Lock) + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock); DeleteTree(p_CcTree, p_FmPcd); + return E_OK; } -t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam) +t_Error FM_PCD_CcRootModifyNextEngine( + t_Handle h_CcTree, uint8_t grpId, uint8_t index, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) { - t_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd; - t_FmPcdCcNode *p_FmPcdCcNode, *p_FmPcdCcNextNode; - t_Error err = E_OK; - int tmp, size; - bool glblMask = FALSE; - t_FmPcdCcKeyParams *p_KeyParams; - t_Handle p_KeysMatchTblTmp; - t_Handle p_AdTableTmp; - bool fullField = FALSE; - ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE; - bool isKeyTblAlloc, fromIc = FALSE; - t_CcNodeInformation ccNodeInfo, *p_CcInformation; + t_FmPcd *p_FmPcd; + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; + t_Error err = E_OK; - SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - /* - if (!p_CcNodeParam->keysParams.keySize || - !p_CcNodeParam->keysParams.numOfKeys) + if (!FmPcdLockTryLockAll(p_FmPcd)) { - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("At least one key of keySize > 0 must be defined.")); - return NULL; + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); } - */ - p_FmPcdCcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); - if(!p_FmPcdCcNode) + + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index, + p_FmPcdCcNextEngineParams); + FmPcdLockUnlockAll(p_FmPcd); + + if (err) + { + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + return E_OK; +} + +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, + t_FmPcdCcNodeParams *p_CcNodeParam) +{ + t_FmPcdCcNode *p_CcNode; + t_Error err; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL); + + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); + if (!p_CcNode) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); return NULL; } - memset(p_FmPcdCcNode, 0, sizeof(t_FmPcdCcNode)); + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); - p_FmPcdCcNode->p_GlblMask = (t_Handle)XX_Malloc(CC_GLBL_MASK_SIZE * sizeof(uint8_t)); - memset(p_FmPcdCcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam); - p_FmPcdCcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys; + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + break; - p_FmPcdCcNode->h_FmPcd = h_FmPcd; + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return NULL; - INIT_LIST(&p_FmPcdCcNode->ccPrevNodesLst); - INIT_LIST(&p_FmPcdCcNode->ccTreeIdLst); - INIT_LIST(&p_FmPcdCcNode->ccTreesLst); - - if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) && - ((p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv4) || - (p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv6)) && - (p_CcNodeParam->extractCcParams.extractByHdr.type == e_FM_PCD_EXTRACT_FULL_FIELD) && - ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 == NET_HEADER_FIELD_IPv6_HOP_LIMIT) || - (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 == NET_HEADER_FIELD_IPv4_TTL))) - { - err = Ipv4TtlOrIpv6HopLimiCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc); - glblMask = FALSE; - - } - else if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) && - ((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_KEY) || - (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_HASH) || - (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID))) - { - if((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID) && - (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0)) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0")); - return NULL; - } - - icCode = IcDefineCode(p_CcNodeParam); - fromIc = TRUE; - if(icCode == CC_PRIVATE_INFO_NONE) - { - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way")); - return NULL; - } - - if((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP)) - { - err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc); - - glblMask = TRUE; - } - else - { - err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc); - if(p_FmPcdCcNode->glblMaskSize) - glblMask = TRUE; - } - } - else - { - err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc); - if(p_FmPcdCcNode->glblMaskSize) - glblMask = TRUE; - } - - if(err) - { - DeleteNode(p_FmPcdCcNode); + default: REPORT_ERROR(MAJOR, err, NO_MSG); return NULL; } - switch(p_CcNodeParam->extractCcParams.type) - { - case(e_FM_PCD_EXTRACT_BY_HDR): - switch(p_CcNodeParam->extractCcParams.extractByHdr.type) - { - case(e_FM_PCD_EXTRACT_FULL_FIELD): - p_FmPcdCcNode->parseCode = GetFullFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, - p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField); - GetSizeHeaderField(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, &p_FmPcdCcNode->sizeOfExtraction); - fullField = TRUE; - if((p_FmPcdCcNode->parseCode != CC_PC_FF_TCI1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_TCI2) && - (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) && - (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) && - (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) && - glblMask) - { - glblMask = FALSE; - p_FmPcdCcNode->glblMaskSize = 4; - p_FmPcdCcNode->lclMask = TRUE; - } - break; - case(e_FM_PCD_EXTRACT_FROM_HDR): - p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size; - p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; - p_FmPcdCcNode->parseCode = GetPrParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, - p_FmPcdCcNode->offset,glblMask, &p_FmPcdCcNode->prsArrayOffset); - break; - case(e_FM_PCD_EXTRACT_FROM_FIELD): - p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; - p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size; - p_FmPcdCcNode->parseCode = GetFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field, - p_FmPcdCcNode->offset,&p_FmPcdCcNode->prsArrayOffset, - p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex); - break; - default: - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); - return NULL; - } - break; - case(e_FM_PCD_EXTRACT_NON_HDR): - /* get the field code for the generic extract */ - p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractNonHdr.size; - p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractNonHdr.offset; - p_FmPcdCcNode->parseCode = GetGenParseCode(p_CcNodeParam->extractCcParams.extractNonHdr.src, p_FmPcdCcNode->offset, glblMask, &p_FmPcdCcNode->prsArrayOffset, fromIc,icCode); - - if(p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) - { - if((p_FmPcdCcNode->offset + p_FmPcdCcNode->sizeOfExtraction) > 64) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_SELECTION,("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)")); - return NULL; - } - } - if((p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_GMASK) || (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) - { - p_FmPcdCcNode->offset += p_FmPcdCcNode->prsArrayOffset; - p_FmPcdCcNode->prsArrayOffset = 0; - } - break; - - default: - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); - return NULL; - } - - if(p_FmPcdCcNode->parseCode == CC_PC_ILLEGAL) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illeagl extraction type")); - return NULL; - } - - if((p_FmPcdCcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || !p_FmPcdCcNode->sizeOfExtraction) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0")); - return NULL; - } - - if(p_CcNodeParam->keysParams.keySize != p_FmPcdCcNode->sizeOfExtraction) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); - return NULL; - } - - - p_FmPcdCcNode->userSizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction; - - if(!glblMask) - memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); - -#ifdef FM_PCD_CC_MANIP - err = CheckAndSetManipParamsWithCcNodeParams(p_FmPcdCcNode); - if(err != E_OK) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction")); - return NULL; - } -#endif /* FM_PCD_CC_MANIP */ - - GetCcExtractKeySize(p_FmPcdCcNode->sizeOfExtraction, &p_FmPcdCcNode->ccKeySizeAccExtraction); - - if(p_FmPcdCcNode->lclMask) - size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction; - else - size = p_FmPcdCcNode->ccKeySizeAccExtraction; - - if(isKeyTblAlloc) - { - p_FmPcdCcNode->h_KeysMatchTable =(t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), - (uint32_t)(size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1)), - FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); - if(!p_FmPcdCcNode->h_KeysMatchTable) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table")); - return NULL; - } - IOMemSet32((uint8_t *)p_FmPcdCcNode->h_KeysMatchTable, 0, size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1)); - } - - p_FmPcdCcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), - (uint32_t)( (p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE), - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_FmPcdCcNode->h_AdTable) - { - DeleteNode(p_FmPcdCcNode); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table ")); - return NULL; - } - IOMemSet32((uint8_t *)p_FmPcdCcNode->h_AdTable, 0, (uint32_t)((p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE)); - - p_KeysMatchTblTmp = p_FmPcdCcNode->h_KeysMatchTable; - p_AdTableTmp = p_FmPcdCcNode->h_AdTable; - for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++) - { - p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; - - if(p_KeysMatchTblTmp) - { - Mem2IOCpy32((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, p_FmPcdCcNode->sizeOfExtraction); - - if(p_FmPcdCcNode->lclMask && p_KeyParams->p_Mask) - Mem2IOCpy32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->sizeOfExtraction); - else if(p_FmPcdCcNode->lclMask) - IOMemSet32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->sizeOfExtraction); - p_KeysMatchTblTmp = PTR_MOVE(p_KeysMatchTblTmp, size * sizeof(uint8_t)); - } - NextStepAd(p_AdTableTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd); - - p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); - - } - NextStepAd(p_AdTableTmp,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, p_FmPcd); - - if(fullField == TRUE) - p_FmPcdCcNode->sizeOfExtraction = 0; - - - for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++) - { - if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC) - { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode; - - if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode)) - { - memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); - ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcNode; - ccNodeInfo.index = 1; - EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, &ccNodeInfo); - UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE); - } - else - { - p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccPrevNodesLst,(t_Handle)p_FmPcdCcNode); - ASSERT_COND(p_CcInformation); - p_CcInformation->index++; - } - } - - } - - for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++) - { - if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC) - { - p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode; - - if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode)) - UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE); - } - } - - p_AdTableTmp = p_FmPcdCcNode->h_AdTable; - for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys; tmp++) - { - if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction) - { - - err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL); - if(err) - { - FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; - } - p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); - } - } - if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction) - { - err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL); - if(err) - { - FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; - } - - } - - - return p_FmPcdCcNode; + return p_CcNode; } -t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode) +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode) { - t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; int i = 0; - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE); - UNUSED(h_FmPcd); - if(!p_CcNode) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID is not initialized")); + if (p_CcNode->owners) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("This node cannot be removed because it is occupied; first unbind this node")); - if(p_CcNode->owners) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID can not be removed because this node is occupied, first - unbind this node")); + for (i = 0; i < p_CcNode->numOfKeys; i++) + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) + UpdateNodeOwner( + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, + FALSE); - for(i = 0; i < p_CcNode->numOfKeys; i++) - { - if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE); + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) + UpdateNodeOwner( + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, + FALSE); - } - if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC) - UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE); - -#ifdef FM_PCD_CC_MANIP - for(i = 0; i < p_CcNode->numOfKeys; i++) + /* Handle also Miss entry */ + for (i = 0; i < p_CcNode->numOfKeys + 1; i++) { - if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip) - FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE); - } - if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip) - FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE); -#endif /* FM_PCD_CC_MANIP */ + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) + FmPcdManipUpdateOwner( + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, + FALSE); - DeleteNode(p_CcNode); +#if (DPAA_VERSION >= 11) + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_FR) + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) + { + FrmReplicGroupUpdateOwner( + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, + FALSE); + } +#endif /* (DPAA_VERSION >= 11) */ + } + + DeleteNode(p_CcNode); return E_OK; } -t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams) +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex, + uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - return FmHcPcdCcAddKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams); -} + if (keyIndex == FM_PCD_LAST_KEY_INDEX) + keyIndex = p_CcNode->numOfKeys; -t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcRemoveKey(p_FmPcd->h_Hc, h_CcNode, keyIndex); -} - -t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcModifyKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_Key, p_Mask); -} - -t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcModifyNodeNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams); -} - -t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcModifyNodeMissNextEngine(p_FmPcd->h_Hc, h_CcNode, p_FmPcdCcNextEngineParams); -} - -t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcModifyTreeNextEngine(p_FmPcd->h_Hc, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams); -} - -t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - - return FmHcPcdCcModifyKeyAndNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams); -} - -uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex) -{ - t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode; - t_AdOfTypeResult *p_AdResult = NULL; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_VALUE(h_CcNode, E_INVALID_HANDLE, 0); -#ifdef DISABLE_SANITY_CHECKS -UNUSED(h_FmPcd); -#endif /* DISABLE_SANITY_CHECKS */ - - if (keyIndex >= p_FmPcdCcNode->numOfKeys) + if (!FmPcdLockTryLockAll(p_FmPcd)) { - REPORT_ERROR(MINOR, E_INVALID_STATE, - ("keyIndex > numOfKeys defined for this node")); + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + return E_OK; +} + +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex, + uint8_t keySize, uint8_t *p_Key, + uint8_t *p_Mask) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableModifyNextEngine( + t_Handle h_CcNode, uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcNextEngineParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableModifyMissNextEngine( + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode, + p_FmPcdCcNextEngineParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, + uint16_t keyIndex, + uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize, + p_KeyParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize, + uint8_t *p_Key, uint8_t *p_Mask) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint16_t keyIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + FmPcdLockUnlockAll(p_FmPcd); + RETURN_ERROR( + MAJOR, + err, + ("The received key and mask pair was not found in the match table of the provided node")); + } + + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableFindNModifyNextEngine( + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint16_t keyIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + FmPcdLockUnlockAll(p_FmPcd); + RETURN_ERROR( + MAJOR, + err, + ("The received key and mask pair was not found in the match table of the provided node")); + } + + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, + p_FmPcdCcNextEngineParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine( + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, + t_FmPcdCcKeyParams *p_KeyParams) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint16_t keyIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + FmPcdLockUnlockAll(p_FmPcd); + RETURN_ERROR( + MAJOR, + err, + ("The received key and mask pair was not found in the match table of the provided node")); + } + + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize, + p_KeyParams); + + FmPcdLockUnlockAll(p_FmPcd); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize, + uint8_t *p_Key, uint8_t *p_Mask, + uint8_t *p_NewKey, uint8_t *p_NewMask) +{ + t_FmPcd *p_FmPcd; + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + t_List h_List; + uint16_t keyIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + INIT_LIST(&h_List); + + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List); + if (err) + { + DBG(TRACE, ("Node's trees lock failed")); + return ERROR_CODE(E_BUSY); + } + + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); + RETURN_ERROR(MAJOR, err, + ("The received key and mask pair was not found in the " + "match table of the provided node")); + } + + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey, + p_NewMask); + + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); + + switch(GET_ERROR_TYPE(err) +) { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +t_Error FM_PCD_MatchTableGetNextEngine( + t_Handle h_CcNode, uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("keyIndex exceeds current number of keys")); + + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1))); + + memcpy(p_FmPcdCcNextEngineParams, + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams, + sizeof(t_FmPcdCcNextEngineParams)); + + return E_OK; +} + + +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t *p_StatsCounters, frameCount; + uint32_t intFlags; + + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0); + + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table")); return 0; } - p_AdResult = PTR_MOVE(p_FmPcdCcNode->h_AdTable, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE); - ASSERT_COND(p_AdResult); - - if (p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC) + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME) + && (p_CcNode->statisticsMode + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) { - REPORT_ERROR(MINOR, E_INVALID_STATE, - ("statistics updated only for entries where next engine not CC")); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table")); return 0; } - if(((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_DONE) && - !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.enqueueParams.statisticsEn) || - ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_KG) && - !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.kgParams.statisticsEn) || - ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_PLCR) && - !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.plcrParams.statisticsEn)) + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + if (keyIndex >= p_CcNode->numOfKeys) { - REPORT_ERROR(MINOR, E_INVALID_STATE, - ("statistics wasn't enable")); + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table")); return 0; } - return GET_UINT32(p_AdResult->res); + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) + { + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key")); + return 0; + } + + p_StatsCounters = + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; + ASSERT_COND(p_StatsCounters); + + /* The first counter is byte counter, so we need to advance to the next counter */ + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters, + FM_PCD_CC_STATS_COUNTER_SIZE))); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + return frameCount; +} + +t_Error FM_PCD_MatchTableGetKeyStatistics( + t_Handle h_CcNode, uint16_t keyIndex, + t_FmPcdCcKeyStatistics *p_KeyStatistics) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t intFlags; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); + + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + if (keyIndex >= p_CcNode->numOfKeys) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("The provided keyIndex exceeds the number of keys in this match table")); + + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FM_PCD_MatchTableGetMissStatistics( + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint32_t intFlags; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); + + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys, + p_MissStatistics); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FM_PCD_MatchTableFindNGetKeyStatistics( + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, + t_FmPcdCcKeyStatistics *p_KeyStatistics) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint16_t keyIndex; + uint32_t intFlags; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); + + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); + + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); + if (GET_ERROR_TYPE(err) != E_OK) + { + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, err, + ("The received key and mask pair was not found in the " + "match table of the provided node")); + } + + ASSERT_COND(keyIndex < p_CcNode->numOfKeys); + + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); + + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); + + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode, + uint8_t keySize, uint8_t *p_Key, + uint8_t hashShift, + t_Handle *p_CcNodeBucketHandle, + uint8_t *p_BucketIndex, + uint16_t *p_LastIndex) +{ + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; + uint16_t glblMask; + uint64_t crc64 = 0; + + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR( + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED, + E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER); + + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2); + glblMask = be16toh(glblMask); + + crc64 = crc64_init(); + crc64 = crc64_compute(p_Key, keySize, crc64); + crc64 >>= hashShift; + + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset))) + & glblMask) >> 4); + if (*p_BucketIndex >= p_CcNode->numOfKeys) + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!")); + + *p_CcNodeBucketHandle = + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode; + if (!*p_CcNodeBucketHandle) + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!")); + + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys; + + return E_OK; +} + +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) +{ + t_FmPcdCcNode *p_CcNodeHashTbl; + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam; + t_FmPcdCcNode *p_CcNode; + t_Handle h_MissStatsCounters = NULL; + t_FmPcdCcKeyParams *p_HashKeyParams; + int i; + uint16_t numOfSets, numOfWays, countMask, onesCount = 0; + bool statsEnForMiss = FALSE; + t_Error err; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL); + + if (p_Param->maxNumOfKeys == 0) + { + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0")); + return NULL; + } + + if (p_Param->hashResMask == 0) + { + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0")); + return NULL; + } + + /*Fix: QorIQ SDK / QSDK-2131*/ + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Next PCD Engine for on-miss entry is invalid. On-miss entry is always required. You can use e_FM_PCD_DONE.")); + return NULL; + } + +#if (DPAA_VERSION >= 11) + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, + ("RMON statistics mode is not supported for hash table")); + return NULL; + } +#endif /* (DPAA_VERSION >= 11) */ + + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( + sizeof(t_FmPcdCcNodeParams)); + if (!p_ExactMatchCcNodeParam) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam")); + return NULL; + } + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); + + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( + sizeof(t_FmPcdCcNodeParams)); + if (!p_IndxHashCcNodeParam) + { + XX_Free(p_ExactMatchCcNodeParam); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam")); + return NULL; + } + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); + + /* Calculate number of sets and number of ways of the hash table */ + countMask = (uint16_t)(p_Param->hashResMask >> 4); + while (countMask) + { + onesCount++; + countMask = (uint16_t)(countMask >> 1); + } + + numOfSets = (uint16_t)(1 << onesCount); + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets); + + if (p_Param->maxNumOfKeys % numOfSets) + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up")); + + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME) + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) + { + /* Allocating a statistics counters table that will be used by all + 'miss' entries of the hash table */ + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem( + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!h_MissStatsCounters) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss")); + XX_Free(p_IndxHashCcNodeParam); + XX_Free(p_ExactMatchCcNodeParam); + return NULL; + } + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + + /* Always enable statistics for 'miss', so that a statistics AD will be + initialized from the start. We'll store the requested 'statistics enable' + value and it will be used when statistics are read by the user. */ + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn; + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE; + } + + /* Building exact-match node params, will be used to create the hash buckets */ + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; + + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src = + e_FM_PCD_EXTRACT_FROM_KEY; + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action = + e_FM_PCD_ACTION_EXACT_MATCH; + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0; + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size = + p_Param->matchKeySize; + + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays; + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE; + p_ExactMatchCcNodeParam->keysParams.statisticsMode = + p_Param->statisticsMode; + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0; + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize; + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss = + p_Param->ccNextEngineParamsForMiss; + + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams; + + for (i = 0; i < numOfSets; i++) + { + /* Each exact-match node will be marked as a 'bucket' and provided with + a pointer to statistics counters, to be used for 'miss' entry + statistics */ + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode)); + if (!p_CcNode) + break; + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); + + p_CcNode->isHashBucket = TRUE; + p_CcNode->h_MissStatsCounters = h_MissStatsCounters; + + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam); + if (err) + break; + + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC; + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE; + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = + p_CcNode; + } + + if (i < numOfSets) + { + for (i = i - 1; i >= 0; i--) + FM_PCD_MatchTableDelete( + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode); + + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); + + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); + XX_Free(p_IndxHashCcNodeParam); + XX_Free(p_ExactMatchCcNodeParam); + return NULL; + } + + /* Creating indexed-hash CC node */ + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src = + e_FM_PCD_EXTRACT_FROM_HASH; + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action = + e_FM_PCD_ACTION_INDEXED_LOOKUP; + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask = + p_Param->hashResMask; + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset = + p_Param->hashShift; + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2; + + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets; + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE; + p_IndxHashCcNodeParam->keysParams.statisticsMode = + e_FM_PCD_CC_STATS_MODE_NONE; + /* Number of keys of this node is number of sets of the hash */ + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets; + p_IndxHashCcNodeParam->keysParams.keySize = 2; + + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam); + + if (p_CcNodeHashTbl) + { + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift; + + /* Storing the allocated counters for buckets 'miss' in the hash table + and if statistics for miss were enabled. */ + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters; + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss; + } + + XX_Free(p_IndxHashCcNodeParam); + XX_Free(p_ExactMatchCcNodeParam); + + return p_CcNodeHashTbl; +} + +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_FmPcd; + t_Handle *p_HashBuckets, h_MissStatsCounters; + uint16_t i, numOfBuckets; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + + /* Store all hash buckets before the hash is freed */ + numOfBuckets = p_HashTbl->numOfKeys; + + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle)); + if (!p_HashBuckets) + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); + + for (i = 0; i < numOfBuckets; i++) + p_HashBuckets[i] = + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + + h_FmPcd = p_HashTbl->h_FmPcd; + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters; + + /* Free the hash */ + err = FM_PCD_MatchTableDelete(p_HashTbl); + + /* Free each hash bucket */ + for (i = 0; i < numOfBuckets; i++) + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]); + + XX_Free(p_HashBuckets); + + /* Free statistics counters for 'miss', if these were allocated */ + if (h_MissStatsCounters) + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); + + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} + +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + uint8_t bucketIndex; + uint16_t lastIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER); + + if (p_KeyParams->p_Mask) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("Keys masks not supported for hash table")); + + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, + p_KeyParams->p_Key, + p_HashTbl->kgHashShift, + &h_HashBucket, &bucketIndex, + &lastIndex); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize, + p_KeyParams); +} + +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize, + uint8_t *p_Key) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + uint8_t bucketIndex; + uint16_t lastIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, + p_HashTbl->kgHashShift, + &h_HashBucket, &bucketIndex, + &lastIndex); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL); +} + +t_Error FM_PCD_HashTableModifyNextEngine( + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + uint8_t bucketIndex; + uint16_t lastIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, + p_HashTbl->kgHashShift, + &h_HashBucket, &bucketIndex, + &lastIndex); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key, + NULL, + p_FmPcdCcNextEngineParams); +} + +t_Error FM_PCD_HashTableModifyMissNextEngine( + t_Handle h_HashTbl, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + uint8_t i; + bool nullifyMissStats = FALSE; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); + + if ((!p_HashTbl->h_MissStatsCounters) + && (p_FmPcdCcNextEngineParams->statisticsEn)) + RETURN_ERROR( + MAJOR, + E_CONFLICT, + ("Statistics are requested for a key, but statistics mode was set" + "to 'NONE' upon initialization")); + + if (p_HashTbl->h_MissStatsCounters) + { + if ((!p_HashTbl->statsEnForMiss) + && (p_FmPcdCcNextEngineParams->statisticsEn)) + nullifyMissStats = TRUE; + + if ((p_HashTbl->statsEnForMiss) + && (!p_FmPcdCcNextEngineParams->statisticsEn)) + { + p_HashTbl->statsEnForMiss = FALSE; + p_FmPcdCcNextEngineParams->statisticsEn = TRUE; + } + } + + for (i = 0; i < p_HashTbl->numOfKeys; i++) + { + h_HashBucket = + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; + + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket, + p_FmPcdCcNextEngineParams); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if (nullifyMissStats) + { + memset(p_HashTbl->h_MissStatsCounters, 0, + (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + memset(p_HashTbl->h_MissStatsCounters, 0, + (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); + p_HashTbl->statsEnForMiss = TRUE; + } + + return E_OK; +} + + +t_Error FM_PCD_HashTableGetMissNextEngine( + t_Handle h_HashTbl, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_FmPcdCcNode *p_HashBucket; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + + /* Miss next engine of each bucket was initialized with the next engine of the hash table */ + p_HashBucket = + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; + + memcpy(p_FmPcdCcNextEngineParams, + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams, + sizeof(t_FmPcdCcNextEngineParams)); + + return E_OK; +} + +t_Error FM_PCD_HashTableFindNGetKeyStatistics( + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, + t_FmPcdCcKeyStatistics *p_KeyStatistics) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + uint8_t bucketIndex; + uint16_t lastIndex; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); + + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, + p_HashTbl->kgHashShift, + &h_HashBucket, &bucketIndex, + &lastIndex); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key, + NULL, p_KeyStatistics); +} + +t_Error FM_PCD_HashTableGetMissStatistics( + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics) +{ + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; + t_Handle h_HashBucket; + + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); + + if (!p_HashTbl->statsEnForMiss) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Statistics were not enabled for miss")); + + h_HashBucket = + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; + + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics); } diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h index a96142bf2b30..3456bb565fd7 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_cc.h @@ -49,6 +50,8 @@ /* Coarse classification defines */ /***********************************************************************/ +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1) + #define CC_PC_FF_MACDST 0x00 #define CC_PC_FF_MACSRC 0x01 #define CC_PC_FF_ETYPE 0x02 @@ -81,6 +84,9 @@ #define CC_PC_FF_IPV6SRC1 0x10 #define CC_PC_FF_IPV6SRC2 0x1e #define CC_PC_FF_IPV6HOP_LIMIT 0x2a +#define CC_PC_FF_IPPID 0x24 +#define CC_PC_FF_IPDSCP 0x76 + #define CC_PC_FF_GREPTYPE 0x11 #define CC_PC_FF_MINENCAP_PTYPE 0x12 @@ -101,6 +107,7 @@ #define CC_PC_GENERIC_WITH_MASK 0x28 #define CC_PC_GENERIC_IC_GMASK 0x2B #define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D #define CC_PR_OFFSET 0x25 #define CC_PR_WITHOUT_OFFSET 0x26 @@ -126,9 +133,10 @@ #define CC_SIZE_ILLEGAL 0 #define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16 -#define FM_PCD_CC_AD_TABLE_ALIGN 256 +#define FM_PCD_CC_AD_TABLE_ALIGN 16 #define FM_PCD_CC_AD_ENTRY_SIZE 16 #define FM_PCD_CC_NUM_OF_KEYS 255 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256 #define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000 #define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000 @@ -137,17 +145,37 @@ #define FM_PCD_AD_RESULT_NADEN 0x20000000 #define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000 - #define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000 #define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000 +#define FM_PCD_AD_STATS_TYPE 0x40000000 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000 +#define FM_PCD_AD_STATS_COND_EN 0x00002000 + + + +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000 + #define FM_PCD_AD_TYPE_MASK 0xc0000000 #define FM_PCD_AD_OPCODE_MASK 0x0000000f #define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16 +#if (DPAA_VERSION >= 11) +#define FM_PCD_AD_RESULT_VSP_SHIFT 24 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000 +#endif /* (DPAA_VERSION >= 11) */ #define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000 #define CC_GLBL_MASK_SIZE 4 +#define CC_AGING_MASK_SIZE 4 typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */ @@ -157,156 +185,215 @@ typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */ #define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000 #define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys))) /***********************************************************************/ /* Memory map */ /***********************************************************************/ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START -typedef _Packed struct { +typedef struct +{ volatile uint32_t fqid; volatile uint32_t plcrProfile; volatile uint32_t nia; - volatile uint32_t res; -} _PackedType t_AdOfTypeResult; + volatile uint32_t res; +} t_AdOfTypeResult; -typedef _Packed struct { +typedef struct +{ volatile uint32_t ccAdBase; volatile uint32_t matchTblPtr; volatile uint32_t pcAndOffsets; volatile uint32_t gmask; -} _PackedType t_AdOfTypeContLookup; +} t_AdOfTypeContLookup; -typedef _Packed union { +typedef struct +{ + volatile uint32_t profileTableAddr; + volatile uint32_t reserved; + volatile uint32_t nextActionIndx; + volatile uint32_t statsTableAddr; +} t_AdOfTypeStats; + +typedef union +{ volatile t_AdOfTypeResult adResult; volatile t_AdOfTypeContLookup adContLookup; -} _PackedType t_Ad; +} t_Ad; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ /***********************************************************************/ -/* Driver's internal structures */ +/* Driver's internal structures */ /***********************************************************************/ -typedef enum e_ModifyState { - e_MODIFY_STATE_ADD = 0, - e_MODIFY_STATE_REMOVE, - e_MODIFY_STATE_CHANGE -} e_ModifyState; +typedef struct t_FmPcdStatsObj +{ + t_Handle h_StatsAd; + t_Handle h_StatsCounters; + t_List node; +} t_FmPcdStatsObj; + +typedef struct +{ + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY]; + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY]; -typedef struct { t_FmPcdCcNextEngineParams nextEngineParams; uint32_t requiredAction; uint32_t shadowAction; -} t_FmPcdCcNextEngineAndRequiredActionParams; -typedef struct { - t_Handle p_Ad; - e_FmPcdEngine fmPcdEngine; - bool adAllocated; - bool isTree; + t_FmPcdStatsObj *p_StatsObj; - uint32_t myInfo; - t_List *h_CcNextNodesLst; - t_Handle h_AdditionalInfo; - t_Handle h_Node; +} t_FmPcdCcKeyAndNextEngineParams; + +typedef struct +{ + t_Handle p_Ad; + e_FmPcdEngine fmPcdEngine; + bool adAllocated; + bool isTree; + + uint32_t myInfo; + t_List *h_CcNextNodesLst; + t_Handle h_AdditionalInfo; + t_Handle h_Node; } t_FmPcdModifyCcAdditionalParams; -typedef struct { - t_Handle p_AdTableNew; - t_Handle p_KeysMatchTableNew; - t_Handle p_AdTableOld; - t_Handle p_KeysMatchTableOld; - uint16_t numOfKeys; - t_Handle h_CurrentNode; - uint16_t keyIndex; - t_Handle h_NodeForAdd; - t_Handle h_NodeForRmv; - t_Handle h_ManipForRmv; - bool tree; +typedef struct +{ + t_Handle p_AdTableNew; + t_Handle p_KeysMatchTableNew; + t_Handle p_AdTableOld; + t_Handle p_KeysMatchTableOld; + uint16_t numOfKeys; + t_Handle h_CurrentNode; + uint16_t savedKeyIndex; + t_Handle h_NodeForAdd; + t_Handle h_NodeForRmv; + t_Handle h_ManipForRmv; + t_Handle h_ManipForAdd; + t_FmPcdStatsObj *p_StatsObjForRmv; +#if (DPAA_VERSION >= 11) + t_Handle h_FrmReplicForAdd; + t_Handle h_FrmReplicForRmv; +#endif /* (DPAA_VERSION >= 11) */ + bool tree; - t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[256]; + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; } t_FmPcdModifyCcKeyAdditionalParams; -typedef struct { - t_Handle h_Manip; - t_Handle h_CcNode; +typedef struct +{ + t_Handle h_Manip; + t_Handle h_CcNode; } t_CcNextEngineInfo; -typedef struct { - uint16_t numOfKeys; - bool glblMaskUpdated; - t_Handle p_GlblMask; - bool lclMask; - uint8_t parseCode; - uint8_t offset; - uint8_t prsArrayOffset; - bool ctrlFlow; - uint8_t owners; +typedef struct +{ + uint16_t numOfKeys; + uint16_t maxNumOfKeys; - uint8_t ccKeySizeAccExtraction; - uint8_t sizeOfExtraction; - uint8_t glblMaskSize; + bool maskSupport; + uint32_t keysMatchTableMaxSize; - t_Handle h_KeysMatchTable; - t_Handle h_AdTable; + e_FmPcdCcStatsMode statisticsMode; + uint32_t numOfStatsFLRs; + uint32_t countersArraySize; - t_List ccPrevNodesLst; + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */ + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket; + Holds the statistics counters allocated by the hash table and + are shared by all hash table buckets; */ + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only; + Holds the statistics counters that were allocated for this node + and replaced by the shared counters (allocated by the hash table); */ + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently + enabled for hash 'miss', FALSE otherwise; This parameter effects the + returned statistics count to user, statistics AD always present for 'miss' + for all hash buckets; */ + bool glblMaskUpdated; + t_Handle p_GlblMask; + bool lclMask; + uint8_t parseCode; + uint8_t offset; + uint8_t prsArrayOffset; + bool ctrlFlow; + uint16_t owners; - t_List ccTreeIdLst; - t_List ccTreesLst; + uint8_t ccKeySizeAccExtraction; + uint8_t sizeOfExtraction; + uint8_t glblMaskSize; - t_Handle h_FmPcd; - uint32_t shadowAction; - bool modifiedState; - uint8_t userSizeOfExtraction; + t_Handle h_KeysMatchTable; + t_Handle h_AdTable; + t_Handle h_StatsAds; + t_Handle h_TmpAd; + t_Handle h_Ad; + t_Handle h_StatsFLRs; - t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[256]; + t_List availableStatsLst; + + t_List ccPrevNodesLst; + + t_List ccTreeIdLst; + t_List ccTreesLst; + + t_Handle h_FmPcd; + uint32_t shadowAction; + uint8_t userSizeOfExtraction; + uint8_t userOffset; + uint8_t kgHashShift; /* used in hash-table */ + + t_Handle h_Spinlock; + + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; } t_FmPcdCcNode; -typedef struct { +typedef struct +{ t_FmPcdCcNode *p_FmPcdCcNode; bool occupied; - uint8_t owners; + uint16_t owners; volatile bool lock; } t_FmPcdCcNodeArray; -typedef struct { +typedef struct +{ uint8_t numOfEntriesInGroup; uint32_t totalBitsMask; uint8_t baseGroupEntry; } t_FmPcdCcGroupParam; -typedef struct { +typedef struct +{ + t_Handle h_FmPcd; uint8_t netEnvId; uintptr_t ccTreeBaseAddr; uint8_t numOfGrps; t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS]; t_List fmPortsLst; - volatile bool lock; + t_FmPcdLock *p_Lock; uint8_t numOfEntries; - uint8_t owners; - t_Handle *fmPcdCcSavedManipParams[256]; + uint16_t owners; + t_Handle h_FmPcdCcSavedManipParams; bool modifiedState; uint32_t requiredAction; - t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[FM_PCD_MAX_NUM_OF_KEYS]; + t_Handle h_IpReassemblyManip; + t_Handle h_CapwapReassemblyManip; + + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; } t_FmPcdCcTree; -typedef struct { - t_FmPcdCcTree *p_FmPcdCcTree; - bool occupied; - uint8_t owners; - volatile bool lock; -} t_FmPcdCcTreeArray; - -bool FmPcdManipIsManipNode(t_Handle h_Ad); +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List); +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List); +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align); #endif /* __FM_CC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c index ca93ec513cab..f183d2f9ee05 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_kg.c @@ -45,17 +46,59 @@ #include "fm_common.h" #include "fm_pcd.h" #include "fm_hc.h" - #include "fm_pcd_ipc.h" +#include "fm_kg.h" +#include "fsl_fman_kg.h" -static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t kgar) +/****************************************/ +/* static functions */ +/****************************************/ + +static uint32_t KgHwLock(t_Handle h_FmPcdKg) { - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar, kgar); - /* Wait for GO to be idle and read error */ - while ((kgar = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar)) & FM_PCD_KG_KGAR_GO) ; - if (kgar & FM_PCD_KG_KGAR_ERR) + ASSERT_COND(h_FmPcdKg); + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock); +} + +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags) +{ + ASSERT_COND(h_FmPcdKg); + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags); +} + +static uint32_t KgSchemeLock(t_Handle h_Scheme) +{ + ASSERT_COND(h_Scheme); + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); +} + +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags) +{ + ASSERT_COND(h_Scheme); + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags); +} + +static bool KgSchemeFlagTryLock(t_Handle h_Scheme) +{ + ASSERT_COND(h_Scheme); + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); +} + +static void KgSchemeFlagUnlock(t_Handle h_Scheme) +{ + ASSERT_COND(h_Scheme); + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); +} + +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar) +{ + + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + + if (fman_kg_write_ar_wait(regs, fmkg_ar)) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation")); + return E_OK; } @@ -63,81 +106,84 @@ static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDef { int i; - switch(code) + switch (code) { - case( KG_SCH_GEN_PARSE_RESULT_N_FQID): - case( KG_SCH_GEN_DEFAULT): - case( KG_SCH_GEN_NEXTHDR): - for(i=0 ; ifmRevInfo.majorRev < 6) + return KG_SCH_KN_PTYPE2; +#endif /* FM_KG_NO_IPPID_SUPPORT */ + return KG_SCH_KN_IPPID; REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return 0; - case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): - if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1); - if(index == e_FM_PCD_HDR_INDEX_2) + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2); REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); return 0; + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC): + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + return KG_SCH_KN_IPTOS_TC1; + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) + return KG_SCH_KN_IPTOS_TC2; + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); + return 0; + case (NET_HEADER_FIELD_IPv6_FL): + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) + return KG_SCH_KN_IPV6FL1; + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) + return KG_SCH_KN_IPV6FL2; + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); + return 0; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_GRE): - switch(field.gre) + case (HEADER_TYPE_GRE): + switch (field.gre) { - case(NET_HEADER_FIELD_GRE_TYPE): + case (NET_HEADER_FIELD_GRE_TYPE): return KG_SCH_KN_GREPTYPE; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; - } - case(HEADER_TYPE_MINENCAP): - switch(field.minencap) + } + case (HEADER_TYPE_MINENCAP): + switch (field.minencap) { - case(NET_HEADER_FIELD_MINENCAP_SRC_IP): + case (NET_HEADER_FIELD_MINENCAP_SRC_IP): return KG_SCH_KN_IPSRC2; - case(NET_HEADER_FIELD_MINENCAP_DST_IP): + case (NET_HEADER_FIELD_MINENCAP_DST_IP): return KG_SCH_KN_IPDST2; - case(NET_HEADER_FIELD_MINENCAP_TYPE): + case (NET_HEADER_FIELD_MINENCAP_TYPE): return KG_SCH_KN_PTYPE2; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; - } - case(HEADER_TYPE_TCP): - switch(field.tcp) + } + case (HEADER_TYPE_TCP): + switch (field.tcp) { - case(NET_HEADER_FIELD_TCP_PORT_SRC): + case (NET_HEADER_FIELD_TCP_PORT_SRC): return KG_SCH_KN_L4PSRC; - case(NET_HEADER_FIELD_TCP_PORT_DST): + case (NET_HEADER_FIELD_TCP_PORT_DST): return KG_SCH_KN_L4PDST; - case(NET_HEADER_FIELD_TCP_FLAGS): + case (NET_HEADER_FIELD_TCP_FLAGS): return KG_SCH_KN_TFLG; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_UDP): - switch(field.udp) + case (HEADER_TYPE_UDP): + switch (field.udp) { - case(NET_HEADER_FIELD_UDP_PORT_SRC): + case (NET_HEADER_FIELD_UDP_PORT_SRC): return KG_SCH_KN_L4PSRC; - case(NET_HEADER_FIELD_UDP_PORT_DST): + case (NET_HEADER_FIELD_UDP_PORT_DST): return KG_SCH_KN_L4PDST; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_IPSEC_AH): - switch(field.ipsecAh) + case (HEADER_TYPE_IPSEC_AH): + switch (field.ipsecAh) { - case(NET_HEADER_FIELD_IPSEC_AH_SPI): + case (NET_HEADER_FIELD_IPSEC_AH_SPI): return KG_SCH_KN_IPSEC_SPI; - case(NET_HEADER_FIELD_IPSEC_AH_NH): + case (NET_HEADER_FIELD_IPSEC_AH_NH): return KG_SCH_KN_IPSEC_NH; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_IPSEC_ESP): - switch(field.ipsecEsp) + case (HEADER_TYPE_IPSEC_ESP): + switch (field.ipsecEsp) { - case(NET_HEADER_FIELD_IPSEC_ESP_SPI): + case (NET_HEADER_FIELD_IPSEC_ESP_SPI): return KG_SCH_KN_IPSEC_SPI; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_SCTP): - switch(field.sctp) + case (HEADER_TYPE_SCTP): + switch (field.sctp) { - case(NET_HEADER_FIELD_SCTP_PORT_SRC): + case (NET_HEADER_FIELD_SCTP_PORT_SRC): return KG_SCH_KN_L4PSRC; - case(NET_HEADER_FIELD_SCTP_PORT_DST): + case (NET_HEADER_FIELD_SCTP_PORT_DST): return KG_SCH_KN_L4PDST; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_DCCP): - switch(field.dccp) + case (HEADER_TYPE_DCCP): + switch (field.dccp) { - case(NET_HEADER_FIELD_DCCP_PORT_SRC): + case (NET_HEADER_FIELD_DCCP_PORT_SRC): return KG_SCH_KN_L4PSRC; - case(NET_HEADER_FIELD_DCCP_PORT_DST): + case (NET_HEADER_FIELD_DCCP_PORT_DST): return KG_SCH_KN_L4PDST; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } - case(HEADER_TYPE_PPPoE): - switch(field.pppoe) + case (HEADER_TYPE_PPPoE): + switch (field.pppoe) { - case(NET_HEADER_FIELD_PPPoE_PID): + case (NET_HEADER_FIELD_PPPoE_PID): return KG_SCH_KN_PPPID; - case(NET_HEADER_FIELD_PPPoE_SID): + case (NET_HEADER_FIELD_PPPoE_SID): return KG_SCH_KN_PPPSID; default: REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); return 0; } default: - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); - return 0; + break; + } + + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); + return 0; } @@ -604,7 +686,7 @@ static uint8_t GetKnownFieldId(uint32_t bitMask) uint8_t cnt = 0; while (bitMask) - if(bitMask & 0x80000000) + if (bitMask & 0x80000000) break; else { @@ -620,716 +702,211 @@ static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid) uint8_t i, mask, numOfOnesToClear, walking1Mask = 1; /* bitOffset 1-7 --> mask 0x1-0x7F */ - if(bitOffset<8) + if (bitOffset<8) { mask = 0; - for(i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1) + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1) mask |= walking1Mask; } else { mask = 0xFF; numOfOnesToClear = 0; - if(fqid && bitOffset>24) + if (fqid && bitOffset>24) /* bitOffset 25-31 --> mask 0xFE-0x80 */ numOfOnesToClear = (uint8_t)(bitOffset-24); else /* bitOffset 9-15 --> mask 0xFE-0x80 */ - if(!fqid && bitOffset>8) + if (!fqid && bitOffset>8) numOfOnesToClear = (uint8_t)(bitOffset-8); - for(i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1) + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1) mask &= ~walking1Mask; /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/ } return mask; } - -t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet) +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; - t_FmPcdIpcKgClsPlanParams kgAlloc; - t_Error err = E_OK; - uint32_t oredVectors = 0; - uint32_t intFlags; - int i, j; + t_FmPcdKg *p_FmPcdKg; + t_FmPcdKgScheme *p_Scheme; + uint32_t intFlags; + uint8_t relativeSchemeId; + int i; - if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected.")); + p_FmPcdKg = p_FmPcd->p_FmPcdKg; - intFlags = FmPcdLock(p_FmPcd); - - /* find a new clsPlan group */ - for(i = 0;ip_FmPcdKg->clsPlanGrps[i].used) - break; - if(i== FM_MAX_NUM_OF_PORTS) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available.")); - } - p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE; - p_Grp->clsPlanGrpId = (uint8_t)i; - - if(p_Grp->numOfOptions == 0) - p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i; - - if (!TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock)) - { - FmPcdUnlock(p_FmPcd, intFlags); - return ERROR_CODE(E_BUSY); - } - FmPcdUnlock(p_FmPcd, intFlags); - - p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i]; - p_ClsPlanGrp->netEnvId = p_Grp->netEnvId; - p_ClsPlanGrp->owners = 0; - FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId); - FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId); - - p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1<numOfOptions); - /* a minimal group of 8 is required */ - if(p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP) - p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP; - if(p_FmPcd->guestId == NCSW_MASTER_ID) - { - err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry); - - if(err) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); - RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - } - - } - else - { - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; - - /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - memset(&kgAlloc, 0, sizeof(kgAlloc)); - kgAlloc.guestId = p_FmPcd->guestId; - kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; - msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN; - memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); - replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(kgAlloc), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry))) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - } - if ((t_Error)reply.error != E_OK) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); - RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG); - } - - p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody); - } - - /* build classification plan entries parameters */ - p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry; - p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; - - oredVectors = 0; - for(i = 0; inumOfOptions; i++) - { - oredVectors |= p_Grp->optVectors[i]; - /* save an array of used options - the indexes represent the power of 2 index */ - p_ClsPlanGrp->optArray[i] = p_Grp->options[i]; - } - /* set the classification plan relevant entries so that all bits - * relevant to the list of options is cleared - */ - for(j = 0; jsizeOfGrp; j++) - p_ClsPlanSet->vectors[j] = ~oredVectors; - - for(i = 0; inumOfOptions; i++) - { - /* option i got the place 2^i in the clsPlan array. all entries that - * have bit i set, should have the vector bit cleared. So each option - * has one location that it is exclusive (1,2,4,8...) and represent the - * presence of that option only, and other locations that represent a - * combination of options. - * e.g: - * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2 - * now represents a frame with ethernet-BC header - so the bit - * representing ethernet-BC should be set and all other option bits - * should be cleared. - * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit - * vector[1] set, but they also have other bits set: - * 3=1+2, options 0 and 1 - * 6=2+4, options 1 and 2 - * 7=1+2+4, options 0,1,and 2 - * 10=2+8, options 1 and 3 - * etc. - * */ - - /* now for each option (i), we set their bits in all entries (j) - * that contain bit 2^i. - */ - for(j = 0; jsizeOfGrp; j++) - { - if(j & (1<vectors[j] |= p_Grp->optVectors[i]; - } - } - - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); - - return E_OK; -} - -void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdIpcKgClsPlanParams kgAlloc; - t_Error err; - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; - - /* check that no port is bound to this clsPlan */ - if(p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to")); - return; - } - - FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId); - - /* free blocks */ - if(p_FmPcd->guestId == NCSW_MASTER_ID) - { - KgFreeClsPlanEntries(h_FmPcd, - p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp, - p_FmPcd->guestId, - p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry); - } - else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ - { - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - kgAlloc.guestId = p_FmPcd->guestId; - kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp; - kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry; - msg.msgId = FM_PCD_FREE_KG_CLSPLAN; - memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(kgAlloc), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - { - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - if (replyLength != sizeof(uint32_t)) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return; - } - if((t_Error)reply.error != E_OK) - { - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed")); - return; - } - } - - if(grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) - p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; - /* clear clsPlan driver structure */ - memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp)); -} - -t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t j, schemesPerPortVector = 0; - t_FmPcdKgScheme *p_Scheme; - uint8_t i, relativeSchemeId; - uint32_t tmp, walking1Mask; - uint8_t swPortIndex = 0; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - /* for each scheme */ - for(i = 0; inumOfSchemes; i++) + /* for each scheme - update owners counters */ + for (i = 0; i < p_BindPort->numOfSchemes; i++) { relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); - if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) - RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); - if(add) - { - if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); - - p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; - /* check netEnvId of the port against the scheme netEnvId */ - if((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId")); - - /* if next engine is private port policer profile, we need to check that it is valid */ - HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId); - if(p_Scheme->nextRelativePlcrProfile) - { - for(j = 0;jnumOfProfiles;j++) - { - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort); - if(p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range")); - if(!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j))) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid.")); - } - } - if(!p_BindPort->useClsPlan) - { - /* if this port does not use clsPlan, it may not be bound to schemes with units that contain - cls plan options. Schemes that are used only directly, should not be checked. - it also may not be bound to schemes that go to CC with units that are options - so we OR - the match vector and the grpBits (= ccUnits) */ - if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits) - { - walking1Mask = 0x80000000; - tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector; - tmp |= p_Scheme->ccUnits; - while (tmp) - { - if(tmp & walking1Mask) - { - tmp &= ~walking1Mask; - if(!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, p_Scheme->netEnvId, walking1Mask)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options")); - } - walking1Mask >>= 1; - } - } - } - } - /* build vector */ - schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]); - } - - *p_SpReg = schemesPerPortVector; - - return E_OK; -} - -void FmPcdKgIncSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - int i; - t_FmPcdKgScheme *p_Scheme; - - /* for each scheme - update owners counters */ - for(i = 0; inumOfSchemes; i++) - { - p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]]; + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; /* increment owners number */ + intFlags = KgSchemeLock(p_Scheme); p_Scheme->owners++; + KgSchemeUnlock(p_Scheme, intFlags); } } -void FmPcdKgDecSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - int i; - t_FmPcdKgScheme *p_Scheme; + t_FmPcdKg *p_FmPcdKg; + t_FmPcdKgScheme *p_Scheme; + uint32_t intFlags; + uint8_t relativeSchemeId; + int i; + + p_FmPcdKg = p_FmPcd->p_FmPcdKg; /* for each scheme - update owners counters */ - for(i = 0; inumOfSchemes; i++) + for (i = 0; i < p_BindPort->numOfSchemes; i++) { - p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]]; + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); + + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; /* increment owners number */ ASSERT_COND(p_Scheme->owners); + intFlags = KgSchemeLock(p_Scheme); p_Scheme->owners--; + KgSchemeUnlock(p_Scheme, intFlags); + } +} + +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set) +{ + /* this routine is locked by the calling routine */ + ASSERT_COND(p_Scheme); + ASSERT_COND(p_Scheme->valid); + + if (set) + p_Scheme->requiredActionFlag = TRUE; + else + { + p_Scheme->requiredAction = 0; + p_Scheme->requiredActionFlag = FALSE; } } static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add) { - t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs; - uint32_t tmpKgarReg = 0, tmpKgpeSp, intFlags; + struct fman_kg_regs *p_KgRegs; + + uint32_t tmpKgarReg = 0, intFlags; t_Error err = E_OK; + /* The calling routine had locked the port, so for each port only one core can access + * (so we don't need a lock here) */ + if (p_FmPcd->h_Hc) return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add); - p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs; + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); - intFlags = FmPcdLock(p_FmPcd); + /* lock a common KG reg */ + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); err = WriteKgarWait(p_FmPcd, tmpKgarReg); - if(err) + if (err) { - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); RETURN_ERROR(MINOR, err, NO_MSG); } - tmpKgpeSp = GET_UINT32(p_FmPcdKgPortRegs->kgoe_sp); - - if(add) - tmpKgpeSp |= spReg; - else /* clear */ - tmpKgpeSp &= ~spReg; - - WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_sp, tmpKgpeSp); + fman_kg_write_sp(p_KgRegs, spReg, add); tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId); err = WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); return err; } static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg) { - t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs; + struct fman_kg_regs *p_KgRegs; uint32_t tmpKgarReg, intFlags; t_Error err; + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + if (p_FmPcd->h_Hc) - return FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg); - - p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs; - intFlags = FmPcdLock(p_FmPcd); - WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_cpp, cppReg); + { + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg); + return err; + } + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + fman_kg_write_cpp(p_KgRegs, cppReg); tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); err = WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); return err; } -static void FmPcdKgUnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId) +{ + uint32_t tmpKgpeCpp; + + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8); + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT); + + return tmpKgpeCpp; +} + +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) +{ + uint32_t tmpKgpeCpp = 0; + + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId); + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp); +} + +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) { KgWriteCpp(p_FmPcd, hardwarePortId, 0); } -static t_Error KgBindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId) { - uint32_t tmpKgpeCpp = 0; + return (uint32_t)(FM_KG_KGAR_GO | + FM_KG_KGAR_READ | + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | + DUMMY_PORT_ID | + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | + FM_PCD_KG_KGAR_WSEL_MASK); - tmpKgpeCpp = FmPcdKgBuildCppReg(p_FmPcd, clsPlanGrpId); - return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp); -} - -t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t spReg; - t_Error err = E_OK; - - err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - FmPcdKgIncSchemeOwners(h_FmPcd, p_SchemeBind); - - return E_OK; -} - -t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t spReg; - t_Error err = E_OK; - - err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, FALSE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - FmPcdKgDecSchemeOwners(h_FmPcd, p_SchemeBind); - - return E_OK; -} - -bool FmPcdKgIsSchemeValidSw(t_Handle h_FmPcd, uint8_t schemeId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - return p_FmPcd->p_FmPcdKg->schemes[schemeId].valid; -} - -bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - if(p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT) - return TRUE; - else - return FALSE; -} - -t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t intFlags; - uint8_t i,j; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - - intFlags = FmPcdLock(p_FmPcd); - for(j=0,i=0;ip_FmPcdKg->schemesMng[i].allocated) - { - p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE; - p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId; - p_SchemesIds[j] = i; - j++; - } - } - - if (j != numOfSchemes) - { - /* roll back */ - for(j--; j; j--) - { - p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE; - p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0; - p_SchemesIds[j] = 0; - } - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found")); - } - FmPcdUnlock(p_FmPcd, intFlags); - - return E_OK; -} - -t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t intFlags; - uint8_t i; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - - intFlags = FmPcdLock(p_FmPcd); - - for(i=0;ip_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated")); - } - if(p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. ")); - } - p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE; - p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0; - } - - FmPcdUnlock(p_FmPcd, intFlags); - return E_OK; -} - -t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t intFlags; - uint8_t numOfBlocks, blocksFound=0, first=0; - uint8_t i, j; - - intFlags = FmPcdLock(p_FmPcd); - - if(!numOfClsPlanEntries) - { - FmPcdUnlock(p_FmPcd, intFlags); - return E_OK; - } - - if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries))) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8")); - } - - numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); - - /* try to find consequent blocks */ - first = 0; - for(i=0;ip_FmPcdKg->clsPlanBlocksMng[i].allocated) - { - blocksFound++; - i++; - if(blocksFound == numOfBlocks) - break; - } - else - { - blocksFound = 0; - /* advance i to the next aligned address */ - first = i = (uint8_t)(first + numOfBlocks); - } - } - - if(blocksFound == numOfBlocks) - { - *p_First = (uint8_t)(first*CLS_PLAN_NUM_PER_GRP); - for(j = first; jp_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE; - p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId; - } - FmPcdUnlock(p_FmPcd, intFlags); - - return E_OK; - } - else - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MINOR, E_FULL, ("No recources for clsPlan")); - } -} - -void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t intFlags; - uint8_t numOfBlocks; - uint8_t i, baseBlock; - - UNUSED( guestId); - - intFlags = FmPcdLock(p_FmPcd); - - numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); - ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP)); - - baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP); - for(i=baseBlock;ip_FmPcdKg->clsPlanBlocksMng[i].allocated); - ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId); - p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE; - p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0; - } - FmPcdUnlock(p_FmPcd, intFlags); -} - -void KgEnable(t_FmPcd *p_FmPcd) -{ - t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) | FM_PCD_KG_KGGCR_EN); -} - -void KgDisable(t_FmPcd *p_FmPcd) -{ - t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) & ~FM_PCD_KG_KGGCR_EN); -} - -void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdKgClsPlanRegs *p_FmPcdKgPortRegs; - uint32_t tmpKgarReg=0, intFlags; - uint16_t i, j; - - SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs; - - intFlags = FmPcdLock(p_FmPcd); - for(i=p_Set->baseEntry;ibaseEntry+p_Set->numOfClsPlanEntries;i+=8) - { - tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); - - for (j = i; j < i+8; j++) - { - ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); - WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]); - } - - if(WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) - { - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED")); - return; - } - } - FmPcdUnlock(p_FmPcd, intFlags); + /* if we ever want to write 1 by 1, use: + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); + */ } +#endif /* (defined(DEBUG_ERRORS) && ... */ static void PcdKgErrorException(t_Handle h_FmPcd) { t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t event, force, schemeIndexes = 0,index = 0, mask = 0; + uint32_t event,schemeIndexes = 0, index = 0; + struct fman_kg_regs *p_KgRegs; ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - event = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer); - mask = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer); + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes); - schemeIndexes = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer); - schemeIndexes &= GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseeer); - - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer); - if(force & event) - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, force & ~event); - - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer, event); - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer, schemeIndexes); - - if(event & FM_PCD_KG_DOUBLE_ECC) + if (event & FM_EX_KG_DOUBLE_ECC) p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC); - if(event & FM_PCD_KG_KEYSIZE_OVERFLOW) + if (event & FM_EX_KG_KEYSIZE_OVERFLOW) { - if(schemeIndexes) + if (schemeIndexes) { - while(schemeIndexes) + while (schemeIndexes) { - if(schemeIndexes & 0x1) + if (schemeIndexes & 0x1) p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index)); schemeIndexes >>= 1; index+=1; @@ -1367,7 +944,7 @@ static t_Error KgInitGuest(t_FmPcd *p_FmPcd) NULL, NULL)) != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); - if(replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t))) + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t))) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)); @@ -1377,438 +954,63 @@ static t_Error KgInitGuest(t_FmPcd *p_FmPcd) static t_Error KgInitMaster(t_FmPcd *p_FmPcd) { t_Error err = E_OK; - t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; - int i; - uint8_t hardwarePortId = 0; - uint32_t tmpReg; + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - /**********************KGEER******************/ - WRITE_UINT32(p_Regs->kgeer, (FM_PCD_KG_DOUBLE_ECC | FM_PCD_KG_KEYSIZE_OVERFLOW)); - /**********************KGEER******************/ - - /**********************KGEEER******************/ - tmpReg = 0; - if(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC) - { + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC) FmEnableRamsEcc(p_FmPcd->h_Fm); - tmpReg |= FM_PCD_KG_DOUBLE_ECC; - } - if(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW) - tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW; - WRITE_UINT32(p_Regs->kgeeer,tmpReg); - /**********************KGEEER******************/ - /**********************KGFDOR******************/ - WRITE_UINT32(p_Regs->kgfdor,0); - /**********************KGFDOR******************/ - - /**********************KGGDV0R******************/ - WRITE_UINT32(p_Regs->kggdv0r,0); - /**********************KGGDV0R******************/ - - /**********************KGGDV1R******************/ - WRITE_UINT32(p_Regs->kggdv1r,0); - /**********************KGGDV1R******************/ - - /**********************KGGCR******************/ - WRITE_UINT32(p_Regs->kggcr, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); - /**********************KGGCR******************/ + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd)); /* register even if no interrupts enabled, to allow future enablement */ - FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR, PcdKgErrorException, p_FmPcd); + FmRegisterIntr(p_FmPcd->h_Fm, + e_FM_MOD_KG, + 0, + e_FM_INTR_TYPE_ERR, + PcdKgErrorException, + p_FmPcd); - /* clear binding between ports to schemes so that all ports are not bound to any schemes */ - for (i=0;ikgseer, 0xFFFFFFFF); - WRITE_UINT32(p_Regs->kgseeer, 0xFFFFFFFF); - - if(p_FmPcd->p_FmPcdKg->numOfSchemes) + if (p_FmPcd->p_FmPcdKg->numOfSchemes) { err = FmPcdKgAllocSchemes(p_FmPcd, p_FmPcd->p_FmPcdKg->numOfSchemes, p_FmPcd->guestId, p_FmPcd->p_FmPcdKg->schemesIds); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); - } - - return E_OK; -} - - -/****************************************/ -/* API routines */ -/****************************************/ -t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdKgRegs *p_Regs; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); - - p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; - if(!FmIsMaster(p_FmPcd->h_Fm)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!")); - -/* not needed - if(payloadOffset > 256) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("data exatraction offset from parseing end can not be more than 256")); -*/ - - WRITE_UINT32(p_Regs->kgfdor,payloadOffset); - - return E_OK; -} - -t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdKgRegs *p_Regs; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); - - p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; - - if(!FmIsMaster(p_FmPcd->h_Fm)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!")); - - if(valueId == 0) - WRITE_UINT32(p_Regs->kggdv0r,value); - else - WRITE_UINT32(p_Regs->kggdv1r,value); - return E_OK; -} - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - int i = 0, j = 0; - uint8_t hardwarePortId = 0; - uint32_t tmpKgarReg, intFlags; - t_Error err = E_OK; - t_FmPcdIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_KG_DUMP_REGS; - return XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL); - } - DUMP_SUBTITLE(("\n")); - DUMP_TITLE(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, ("FmPcdKgRegs Regs")); - - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggcr); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeeer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseeer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggsr); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgtpc); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgserc); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfdor); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv0r); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv1r); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfeer); - DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgar); - - DUMP_SUBTITLE(("\n")); - intFlags = FmPcdLock(p_FmPcd); - for(j = 0;jp_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs, ("FmPcdKgIndirectAccessSchemeRegs Scheme %d Regs", j)); - - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mode); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekfc); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekdv); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmch); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmcl); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_fqb); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_hc); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ppc); - - DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec, ("kgse_gec")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PCD_KG_NUM_OF_GENERIC_REGS) - { - DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec[i], sizeof(uint32_t)); - } - - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_spc); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv0); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv1); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ccbs); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mv); - } - DUMP_SUBTITLE(("\n")); - - for (i=0;ip_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, ("FmPcdKgIndirectAccessPortRegs PCD Port %d regs", hardwarePortId)); - - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_sp); - DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_cpp); - } - - DUMP_SUBTITLE(("\n")); - for(j=0;jp_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs, ("FmPcdKgIndirectAccessClsPlanRegs Regs group %d", j)); - DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe, ("kgcpe")); - - tmpKgarReg = FmPcdKgBuildReadClsPlanBlockActionReg((uint8_t)j); - err = WriteKgarWait(p_FmPcd, tmpKgarReg); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); - DUMP_SUBSTRUCT_ARRAY(i, 8) - DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe[i], sizeof(uint32_t)); - } - FmPcdUnlock(p_FmPcd, intFlags); - - return E_OK; -} -#endif /* (defined(DEBUG_ERRORS) && ... */ - -t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) -{ - t_FmPcdKg *p_FmPcdKg; - - UNUSED(p_FmPcd); - - if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES)); - return NULL; - } - - p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg)); - if (!p_FmPcdKg) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED")); - return NULL; - } - memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg)); - - if(FmIsMaster(p_FmPcd->h_Fm)) - { - p_FmPcdKg->p_FmPcdKgRegs = (t_FmPcdKgRegs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm)); - p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions; - } - - p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes; - if((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes) - { - p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; - DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES")); - } - - p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; - - return p_FmPcdKg; -} - -t_Error KgInit(t_FmPcd *p_FmPcd) -{ - if (p_FmPcd->guestId == NCSW_MASTER_ID) - return KgInitMaster(p_FmPcd); - else - return KgInitGuest(p_FmPcd); -} - -t_Error KgFree(t_FmPcd *p_FmPcd) -{ - t_FmPcdIpcKgSchemesParams kgAlloc; - t_Error err = E_OK; - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; - - FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR); - - if(p_FmPcd->guestId == NCSW_MASTER_ID) - return FmPcdKgFreeSchemes(p_FmPcd, - p_FmPcd->p_FmPcdKg->numOfSchemes, - p_FmPcd->guestId, - p_FmPcd->p_FmPcdKg->schemesIds); - - /* guest */ - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; - kgAlloc.guestId = p_FmPcd->guestId; - ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES); - memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds , (sizeof(uint8_t))*kgAlloc.numOfSchemes); - msg.msgId = FM_PCD_FREE_KG_SCHEMES; - memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(kgAlloc), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - return (t_Error)reply.error; -} - -t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams; - t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; - t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; - t_Error err; - - memset(&grpParams, 0, sizeof(grpParams)); - grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN; - p_GrpParams = &grpParams; - - p_GrpParams->netEnvId = netEnvId; - err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams); - if(err) - RETURN_ERROR(MINOR,err,NO_MSG); - if(p_GrpParams->grpExists) - *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; - else - { - p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); - if (!p_ClsPlanSet) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet")); - memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); - err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet); if (err) - { - XX_Free(p_ClsPlanSet); - RETURN_ERROR(MINOR,err,NO_MSG); - } - *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; - - if (p_FmPcd->h_Hc) - { - /* write clsPlan entries to memory */ - err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet); - if (err) - { - XX_Free(p_ClsPlanSet); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - } - else - /* write clsPlan entries to memory */ - KgSetClsPlan(p_FmPcd, p_ClsPlanSet); - - XX_Free(p_ClsPlanSet); + RETURN_ERROR(MINOR, err, NO_MSG); } - /* mark if this is an empty classification group */ - if(*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) - *p_IsEmptyClsPlanGrp = TRUE; - else - *p_IsEmptyClsPlanGrp = FALSE; - - p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId]; - - /* increment owners number */ - p_ClsPlanGrp->owners++; - - /* copy options array for port */ - memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t)); - - /* bind port to the new or existing group */ - err = KgBindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; } -t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId]; - t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; + ASSERT_COND(!p_Scheme->valid); + if (p_Scheme->netEnvId != ILLEGAL_NETENV) + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); + p_Scheme->valid = TRUE; +} - FmPcdKgUnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId); +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme) +{ + if (p_Scheme->owners) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to")); - /* decrement owners number */ - ASSERT_COND(p_ClsPlanGrp->owners); - p_ClsPlanGrp->owners--; + if (p_Scheme->netEnvId != ILLEGAL_NETENV) + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); + p_Scheme->valid = FALSE; - if(!p_ClsPlanGrp->owners) - { - if (p_FmPcd->h_Hc) - return FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId); - else - { - /* clear clsPlan entries in memory */ - p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); - if (!p_ClsPlanSet) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet")); - memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); - p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry; - p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp; - KgSetClsPlan(p_FmPcd, p_ClsPlanSet); - XX_Free(p_ClsPlanSet); - FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId); - } - } return E_OK; } -t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t_FmPcdKgInterModuleSchemeRegs *p_SchemeRegs) +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme, + t_FmPcdKgSchemeParams *p_SchemeParams, + struct fman_kg_scheme_regs *p_SchemeRegs) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd); uint32_t grpBits = 0; uint8_t grpBase; bool direct=TRUE, absolute=FALSE; @@ -1828,184 +1030,169 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t t_FmPcdKgSchemesExtracts *p_LocalExtractsArray; uint8_t numOfSwDefaults = 0; t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS]; - uint8_t currGenId = 0, relativeSchemeId; + uint8_t currGenId = 0; - if(!p_Scheme->modify) - relativeSchemeId = p_Scheme->id.relativeSchemeId; - else - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1)); - - memset(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId], 0, sizeof(t_FmPcdKgScheme)); memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt)); - memset(p_SchemeRegs, 0, sizeof(t_FmPcdKgInterModuleSchemeRegs)); + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs)); - if (p_Scheme->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)); /* by netEnv parameters, get match vector */ - if(!p_Scheme->alwaysDirect) + if (!p_SchemeParams->alwaysDirect) { - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId = - (uint8_t)(PTR_TO_UINT(p_Scheme->netEnvParams.h_NetEnv)-1); - netEnvParams.netEnvId = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId; - netEnvParams.numOfDistinctionUnits = p_Scheme->netEnvParams.numOfDistinctionUnits; - memcpy(netEnvParams.unitIds, p_Scheme->netEnvParams.unitIds, (sizeof(uint8_t))*p_Scheme->netEnvParams.numOfDistinctionUnits); + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv); + netEnvParams.netEnvId = p_Scheme->netEnvId; + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits; + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits); err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); - if(err) + if (err) RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = netEnvParams.vector; + p_Scheme->matchVector = netEnvParams.vector; } else { - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = SCHEME_ALWAYS_DIRECT; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId = ILLEGAL_NETENV; + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT; + p_Scheme->netEnvId = ILLEGAL_NETENV; } - if(p_Scheme->nextEngine == e_FM_PCD_INVALID) + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid")); - if(p_Scheme->bypassFqidGeneration) + if (p_SchemeParams->bypassFqidGeneration) { #ifdef FM_KG_NO_BYPASS_FQID_GEN - { - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPcd->h_Fm, &revInfo); - if (revInfo.majorRev != 4) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration.")); - } + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration.")); #endif /* FM_KG_NO_BYPASS_FQID_GEN */ - if(p_Scheme->baseFqid) + if (p_SchemeParams->baseFqid) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID")); } else - if(!p_Scheme->baseFqid) + if (!p_SchemeParams->baseFqid) DBG(WARNING, ("baseFqid is 0.")); - if(p_Scheme->nextEngine == e_FM_PCD_PLCR) + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR) { - direct = p_Scheme->kgNextEngineParams.plcrProfile.direct; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr = direct; - absolute = (bool)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE); - if(!direct && absolute) + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct; + p_Scheme->directPlcr = direct; + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE); + if (!direct && absolute) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared.")); - if(direct) + if (direct) { - profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId; + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId; numOfProfiles = 1; } else { - profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; - shift = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; - numOfProfiles = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles; + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles; } } - if(p_Scheme->nextEngine == e_FM_PCD_CC) + if (p_SchemeParams->nextEngine == e_FM_PCD_CC) { #ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN - if((p_Scheme->kgNextEngineParams.cc.plcrNext) && (p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) { - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPcd->h_Fm, &revInfo); - if (revInfo.majorRev != 4) + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration.")); } #endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */ - err = FmPcdCcGetGrpParams(p_Scheme->kgNextEngineParams.cc.h_CcTree, - p_Scheme->kgNextEngineParams.cc.grpId, + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree, + p_SchemeParams->kgNextEngineParams.cc.grpId, &grpBits, &grpBase); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].ccUnits = grpBits; + p_Scheme->ccUnits = grpBits; - if((p_Scheme->kgNextEngineParams.cc.plcrNext) && - (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) { - if(p_Scheme->kgNextEngineParams.cc.plcrProfile.sharedProfile) + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification.")); absolute = FALSE; - direct = p_Scheme->kgNextEngineParams.cc.plcrProfile.direct; - if(direct) + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct; + if (direct) { - profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId; + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId; numOfProfiles = 1; } else { - profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; - shift = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; - numOfProfiles = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles; + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles; } } } /* if policer is used directly after KG, or after CC */ - if((p_Scheme->nextEngine == e_FM_PCD_PLCR) || - ((p_Scheme->nextEngine == e_FM_PCD_CC) && - (p_Scheme->kgNextEngineParams.cc.plcrNext) && - (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration))) + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) || + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) && + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) && + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))) { /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ - if(absolute) + if (absolute) { /* for absolute direct policy only, */ relativeProfileId = profileId; - err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId); - if(err) + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId); + if (err) RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset")); - if(!FmPcdPlcrIsProfileValid(p_FmPcd, profileId)) + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId)) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid.")); - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId; + p_Scheme->relativeProfileId = profileId; } else { /* save relative profile id's for later check */ - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile = TRUE; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].numOfProfiles = numOfProfiles; + p_Scheme->nextRelativePlcrProfile = TRUE; + p_Scheme->relativeProfileId = profileId; + p_Scheme->numOfProfiles = numOfProfiles; } } else { /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */ - if(p_Scheme->bypassFqidGeneration && p_Scheme->numOfUsedExtractedOrs) + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID")); - if(p_Scheme->bypassFqidGeneration && - p_Scheme->useHash && - p_Scheme->keyExtractAndHashParams.hashDistributionNumOfFqids) + if (p_SchemeParams->bypassFqidGeneration && + p_SchemeParams->useHash && + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID")); } /* configure all 21 scheme registers */ tmpReg = KG_SCH_MODE_EN; - switch(p_Scheme->nextEngine) + switch (p_SchemeParams->nextEngine) { - case(e_FM_PCD_PLCR): + case (e_FM_PCD_PLCR): /* add to mode register - NIA */ tmpReg |= KG_SCH_MODE_NIA_PLCR; tmpReg |= NIA_ENG_PLCR; - tmpReg |= (uint32_t)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0); + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0); /* initialize policer profile command - */ /* configure kgse_ppc */ - if(direct) + if (direct) /* use profileId as base, other fields are 0 */ p_SchemeRegs->kgse_ppc = (uint32_t)profileId; else { - if(shift > MAX_PP_SHIFT) + if (shift > MAX_PP_SHIFT) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); - if(!numOfProfiles || !POWER_OF_2(numOfProfiles)) + if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; @@ -2016,30 +1203,30 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t p_SchemeRegs->kgse_ppc = ppcTmp; } break; - case(e_FM_PCD_CC): + case (e_FM_PCD_CC): /* mode reg - define NIA */ tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); p_SchemeRegs->kgse_ccbs = grpBits; tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT); - if(p_Scheme->kgNextEngineParams.cc.plcrNext) + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext) { - if(!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration) + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration) { /* find out if absolute or relative */ - if(absolute) + if (absolute) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow")); - if(direct) + if (direct) { /* mask = 0, base = directProfileId */ p_SchemeRegs->kgse_ppc = (uint32_t)profileId; } else { - if(shift > MAX_PP_SHIFT) + if (shift > MAX_PP_SHIFT) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); - if(!numOfProfiles || !POWER_OF_2(numOfProfiles)) + if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; @@ -2050,26 +1237,61 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t p_SchemeRegs->kgse_ppc = ppcTmp; } } - else - ppcTmp = KG_SCH_PP_NO_GEN; } break; - case(e_FM_PCD_DONE): - if(p_Scheme->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME) - tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD); + case (e_FM_PCD_DONE): + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME) + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); else - tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); break; default: RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported")); } p_SchemeRegs->kgse_mode = tmpReg; - p_SchemeRegs->kgse_mv = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector; + p_SchemeRegs->kgse_mv = p_Scheme->matchVector; - if(p_Scheme->useHash) +#if (DPAA_VERSION >= 11) + if (p_SchemeParams->overrideStorageProfile) { - p_KeyAndHash = &p_Scheme->keyExtractAndHashParams; + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE; + + if (p_SchemeParams->storageProfile.direct) + { + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId; + shift = 0; + numOfProfiles = 1; + } + else + { + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift; + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles; + } + if (shift > MAX_SP_SHIFT) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT)); + + if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); + + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT; + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT); + tmpReg |= (uint32_t)profileId; + + + p_SchemeRegs->kgse_vsp = tmpReg; + + p_Scheme->vspe = TRUE; + + } + else + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN; +#endif /* (DPAA_VERSION >= 11) */ + + if (p_SchemeParams->useHash) + { + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams; if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range")); @@ -2080,70 +1302,70 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t /* configure kgse_dv1 */ p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1; - if(!p_Scheme->bypassFqidGeneration) + if (!p_SchemeParams->bypassFqidGeneration) { - if(!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids)) + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2")); - if((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_Scheme->baseFqid) + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid) DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues.")); } /* configure kgse_ekdv */ tmpReg = 0; - for( i=0 ;inumOfUsedDflts ; i++) + for ( i=0 ;inumOfUsedDflts ; i++) { - switch(p_KeyAndHash->dflts[i].type) + switch (p_KeyAndHash->dflts[i].type) { - case(e_FM_PCD_KG_MAC_ADDR): + case (e_FM_PCD_KG_MAC_ADDR): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT); break; - case(e_FM_PCD_KG_TCI): + case (e_FM_PCD_KG_TCI): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT); break; - case(e_FM_PCD_KG_ENET_TYPE): + case (e_FM_PCD_KG_ENET_TYPE): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT); break; - case(e_FM_PCD_KG_PPP_SESSION_ID): + case (e_FM_PCD_KG_PPP_SESSION_ID): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT); break; - case(e_FM_PCD_KG_PPP_PROTOCOL_ID): + case (e_FM_PCD_KG_PPP_PROTOCOL_ID): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT); break; - case(e_FM_PCD_KG_MPLS_LABEL): + case (e_FM_PCD_KG_MPLS_LABEL): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT); break; - case(e_FM_PCD_KG_IP_ADDR): + case (e_FM_PCD_KG_IP_ADDR): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT); break; - case(e_FM_PCD_KG_PROTOCOL_TYPE): + case (e_FM_PCD_KG_PROTOCOL_TYPE): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT); break; - case(e_FM_PCD_KG_IP_TOS_TC): + case (e_FM_PCD_KG_IP_TOS_TC): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT); break; - case(e_FM_PCD_KG_IPV6_FLOW_LABEL): + case (e_FM_PCD_KG_IPV6_FLOW_LABEL): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); break; - case(e_FM_PCD_KG_IPSEC_SPI): + case (e_FM_PCD_KG_IPSEC_SPI): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT); break; - case(e_FM_PCD_KG_L4_PORT): + case (e_FM_PCD_KG_L4_PORT): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); break; - case(e_FM_PCD_KG_TCP_FLAG): + case (e_FM_PCD_KG_TCP_FLAG): tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT); break; - case(e_FM_PCD_KG_GENERIC_FROM_DATA): + case (e_FM_PCD_KG_GENERIC_FROM_DATA): swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA; swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; numOfSwDefaults ++; break; - case(e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V): + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V): swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V; swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; numOfSwDefaults ++; break; - case(e_FM_PCD_KG_GENERIC_NOT_FROM_DATA): + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA): swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; numOfSwDefaults ++; @@ -2155,33 +1377,38 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t p_SchemeRegs->kgse_ekdv = tmpReg; p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts)); - if(!p_LocalExtractsArray) + if (!p_LocalExtractsArray) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); /* configure kgse_ekfc and kgse_gec */ knownTmp = 0; - for( i=0 ;inumOfUsedExtracts ; i++) + for ( i=0 ;inumOfUsedExtracts ; i++) { p_Extract = &p_KeyAndHash->extractArray[i]; - switch(p_Extract->type) + switch (p_Extract->type) { - case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): knownTmp |= KG_SCH_KN_PORT_ID; /* save in driver structure */ p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID); p_LocalExtractsArray->extractsArray[i].known = TRUE; break; - case(e_FM_PCD_EXTRACT_BY_HDR): - switch(p_Extract->extractByHdr.hdr) + case (e_FM_PCD_EXTRACT_BY_HDR): + switch (p_Extract->extractByHdr.hdr) { - case(HEADER_TYPE_UDP_ENCAP_ESP): - switch(p_Extract->extractByHdr.type) +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + case (HEADER_TYPE_UDP_LITE): + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; + break; +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + case (HEADER_TYPE_UDP_ENCAP_ESP): + switch (p_Extract->extractByHdr.type) { - case(e_FM_PCD_EXTRACT_FROM_HDR): + case (e_FM_PCD_EXTRACT_FROM_HDR): /* case where extraction from ESP only */ if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE) { - p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE; p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; } @@ -2191,50 +1418,48 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t p_Extract->extractByHdr.ignoreProtocolValidation = FALSE; } break; - case(e_FM_PCD_EXTRACT_FROM_FIELD): - switch(p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp) + case (e_FM_PCD_EXTRACT_FROM_FIELD): + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp) { - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; break; - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; - p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); - p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; break; - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; - p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); - p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET; p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; break; } break; - case(e_FM_PCD_EXTRACT_FULL_FIELD): - switch(p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp) + case (e_FM_PCD_EXTRACT_FULL_FIELD): + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp) { - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; break; - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; - p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE; p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET; p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; break; - case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; - p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE; p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET; p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; @@ -2246,9 +1471,9 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t default: break; } - switch(p_Extract->extractByHdr.type) + switch (p_Extract->extractByHdr.type) { - case(e_FM_PCD_EXTRACT_FROM_HDR): + case (e_FM_PCD_EXTRACT_FROM_HDR): generic = TRUE; /* get the header code for the generic extract */ code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation); @@ -2256,7 +1481,7 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset; size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size; break; - case(e_FM_PCD_EXTRACT_FROM_FIELD): + case (e_FM_PCD_EXTRACT_FROM_FIELD): generic = TRUE; /* get the field code for the generic extract */ code = GetGenFieldCode(p_Extract->extractByHdr.hdr, @@ -2264,13 +1489,13 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset; size = p_Extract->extractByHdr.extractByHdrType.fromField.size; break; - case(e_FM_PCD_EXTRACT_FULL_FIELD): - if(!p_Extract->extractByHdr.ignoreProtocolValidation) + case (e_FM_PCD_EXTRACT_FULL_FIELD): + if (!p_Extract->extractByHdr.ignoreProtocolValidation) { /* if we have a known field for it - use it, otherwise use generic */ - bitMask = GetKnownProtMask(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.extractByHdrType.fullField); - if(bitMask) + if (bitMask) { knownTmp |= bitMask; /* save in driver structure */ @@ -2279,21 +1504,22 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t } else generic = TRUE; - } else generic = TRUE; - if(generic) + if (generic) { /* tmp - till we cover more headers under generic */ + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported")); } break; default: + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } break; - case(e_FM_PCD_EXTRACT_NON_HDR): + case (e_FM_PCD_EXTRACT_NON_HDR): /* use generic */ generic = TRUE; offset = 0; @@ -2306,25 +1532,35 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } - if(generic) + if (generic) { /* set generic register fields */ - if(currGenId >= FM_PCD_KG_NUM_OF_GENERIC_REGS) + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS) + { + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); - if(!code) + } + if (!code) + { + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); + } genTmp = KG_SCH_GEN_VALID; genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); genTmp |= offset; - if((size > MAX_KG_SCH_SIZE) || (size < 1)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)")); + if ((size > MAX_KG_SCH_SIZE) || (size < 1)) + { + XX_Free(p_LocalExtractsArray); + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)")); + } genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT); swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code); - if(swDefault == e_FM_PCD_KG_DFLT_ILLEGAL) + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL) DBG(WARNING, ("No sw default configured")); + else + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT; - genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT; genTmp |= KG_SCH_GEN_MASK; p_SchemeRegs->kgse_gec[currGenId] = genTmp; /* save in driver structure */ @@ -2339,9 +1575,12 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t maskTmp = 0xFFFFFFFF; /* configure kgse_bmch, kgse_bmcl and kgse_fqb */ - if(p_KeyAndHash->numOfUsedMasks >= FM_PCD_KG_NUM_OF_EXTRACT_MASKS) + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS) + { + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS)); - for( i=0 ;inumOfUsedMasks ; i++) + } + for ( i=0 ;inumOfUsedMasks ; i++) { /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */ id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id; @@ -2374,23 +1613,32 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t /* kgse_fqb will be written t the end of the routine */ /* configure kgse_hc */ - if(p_KeyAndHash->hashShift > MAX_HASH_SHIFT) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); - if(p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT)); + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT) + { + XX_Free(p_LocalExtractsArray); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); + } + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) + { + XX_Free(p_LocalExtractsArray); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT)); + } tmpReg = 0; tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift); tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT; - if(p_KeyAndHash->symmetricHash) + if (p_KeyAndHash->symmetricHash) { - if((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) || + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) || (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) || (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) || (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST))) + { + XX_Free(p_LocalExtractsArray); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing")); + } tmpReg |= KG_SCH_HASH_CONFIG_SYM; } p_SchemeRegs->kgse_hc = tmpReg; @@ -2409,7 +1657,7 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t curr = 0; for (i=0;inumOfUsedExtracts ; i++) { - if(p_LocalExtractsArray->extractsArray[i].known) + if (p_LocalExtractsArray->extractsArray[i].known) { ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId)); j = curr; @@ -2417,14 +1665,14 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t index in the user's extractions array */ /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1] location */ - while((j > 0) && (p_LocalExtractsArray->extractsArray[i].id < - p_LocalExtractsArray->extractsArray[p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1]].id)) + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id < + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id)) { - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] = - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1]; + p_Scheme->orderedArray[j] = + p_Scheme->orderedArray[j-1]; j--; } - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] = (uint8_t)i; + p_Scheme->orderedArray[j] = (uint8_t)i; curr++; } else @@ -2432,12 +1680,10 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t /* index is first_generic_index + generic index (id) */ idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id); ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY); - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[idx]= (uint8_t)i; + p_Scheme->orderedArray[idx]= (uint8_t)i; } } XX_Free(p_LocalExtractsArray); - p_LocalExtractsArray = NULL; - } else { @@ -2451,38 +1697,38 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t p_SchemeRegs->kgse_dv1 = 0; } - if(p_Scheme->bypassFqidGeneration) + if (p_SchemeParams->bypassFqidGeneration) p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID; /* configure kgse_spc */ - if( p_Scheme->schemeCounter.update) - p_SchemeRegs->kgse_spc = p_Scheme->schemeCounter.value; + if ( p_SchemeParams->schemeCounter.update) + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value; /* check that are enough generic registers */ - if(p_Scheme->numOfUsedExtractedOrs + currGenId > FM_PCD_KG_NUM_OF_GENERIC_REGS) + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS) RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); /* extracted OR mask on Qid */ - for( i=0 ;inumOfUsedExtractedOrs ; i++) + for ( i=0 ;inumOfUsedExtractedOrs ; i++) { - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs = TRUE; + p_Scheme->extractedOrs = TRUE; /* configure kgse_gec[i] */ - p_ExtractOr = &p_Scheme->extractedOrs[i]; - switch(p_ExtractOr->type) + p_ExtractOr = &p_SchemeParams->extractedOrs[i]; + switch (p_ExtractOr->type) { - case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): code = KG_SCH_GEN_PARSE_RESULT_N_FQID; offset = 0; break; - case(e_FM_PCD_EXTRACT_BY_HDR): + case (e_FM_PCD_EXTRACT_BY_HDR): /* get the header code for the generic extract */ code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation); /* set generic register fields */ offset = p_ExtractOr->extractionOffset; break; - case(e_FM_PCD_EXTRACT_NON_HDR): + case (e_FM_PCD_EXTRACT_NON_HDR): /* get the field code for the generic extract */ offset = 0; code = GetGenCode(p_ExtractOr->src, &offset); @@ -2493,12 +1739,12 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t } /* set generic register fields */ - if(!code) + if (!code) RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID; genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); genTmp |= offset; - if(!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile) + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile) RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile")); /************************************************************************************ @@ -2542,11 +1788,11 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t ************************************************************************************/ - if(p_ExtractOr->bitOffsetInFqid) + if (p_ExtractOr->bitOffsetInFqid) { - if(p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET ) + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET ) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)")); - if(p_ExtractOr->bitOffsetInFqid<8) + if (p_ExtractOr->bitOffsetInFqid<8) genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT); else genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT); @@ -2554,9 +1800,9 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t } else /* effect policer profile */ { - if(p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET ) + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET ) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)")); - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile; + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile; genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT); p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE); } @@ -2570,41 +1816,788 @@ t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t } /* clear all unused GEC registers */ - for( i=currGenId ;ikgse_gec[i] = 0; /* add base Qid for this scheme */ /* add configuration for kgse_fqb */ - if(p_Scheme->baseFqid & ~0x00FFFFFF) + if (p_SchemeParams->baseFqid & ~0x00FFFFFF) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1")); - fqbTmp |= p_Scheme->baseFqid; + fqbTmp |= p_SchemeParams->baseFqid; p_SchemeRegs->kgse_fqb = fqbTmp; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine = p_Scheme->nextEngine; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction = p_Scheme->kgNextEngineParams.doneAction; + p_Scheme->nextEngine = p_SchemeParams->nextEngine; + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction; + return E_OK; } -void FmPcdKgValidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; + t_FmPcdIpcKgClsPlanParams kgAlloc; + t_Error err = E_OK; + uint32_t oredVectors = 0; + int i, j; - ASSERT_COND(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); + /* this routine is protected by the calling routine ! */ + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected.")); - if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV) - FmPcdIncNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId); - p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = TRUE; + /* find a new clsPlan group */ + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used) + break; + if (i == FM_MAX_NUM_OF_PORTS) + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available.")); + + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE; + + p_Grp->clsPlanGrpId = (uint8_t)i; + + if (p_Grp->numOfOptions == 0) + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i; + + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i]; + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId; + p_ClsPlanGrp->owners = 0; + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId); + if (p_Grp->numOfOptions != 0) + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId); + + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions); + /* a minimal group of 8 is required */ + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP) + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP; + if (p_FmPcd->guestId == NCSW_MASTER_ID) + { + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry); + + if (err) + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); + } + else + { + t_FmPcdIpcMsg msg; + uint32_t replyLength; + t_FmPcdIpcReply reply; + + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ + memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); + memset(&kgAlloc, 0, sizeof(kgAlloc)); + kgAlloc.guestId = p_FmPcd->guestId; + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN; + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)); + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(kgAlloc), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + if ((t_Error)reply.error != E_OK) + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG); + + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody); + } + + /* build classification plan entries parameters */ + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry; + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; + + oredVectors = 0; + for (i = 0; inumOfOptions; i++) + { + oredVectors |= p_Grp->optVectors[i]; + /* save an array of used options - the indexes represent the power of 2 index */ + p_ClsPlanGrp->optArray[i] = p_Grp->options[i]; + } + /* set the classification plan relevant entries so that all bits + * relevant to the list of options is cleared + */ + for (j = 0; jsizeOfGrp; j++) + p_ClsPlanSet->vectors[j] = ~oredVectors; + + for (i = 0; inumOfOptions; i++) + { + /* option i got the place 2^i in the clsPlan array. all entries that + * have bit i set, should have the vector bit cleared. So each option + * has one location that it is exclusive (1,2,4,8...) and represent the + * presence of that option only, and other locations that represent a + * combination of options. + * e.g: + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2 + * now represents a frame with ethernet-BC header - so the bit + * representing ethernet-BC should be set and all other option bits + * should be cleared. + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit + * vector[1] set, but they also have other bits set: + * 3=1+2, options 0 and 1 + * 6=2+4, options 1 and 2 + * 7=1+2+4, options 0,1,and 2 + * 10=2+8, options 1 and 3 + * etc. + * */ + + /* now for each option (i), we set their bits in all entries (j) + * that contain bit 2^i. + */ + for (j = 0; jsizeOfGrp; j++) + { + if (j & (1<vectors[j] |= p_Grp->optVectors[i]; + } + } + + return E_OK; } -void FmPcdKgInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId) { + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdIpcKgClsPlanParams kgAlloc; + t_Error err; + t_FmPcdIpcMsg msg; + uint32_t replyLength; + t_FmPcdIpcReply reply; + /* check that no port is bound to this clsPlan */ + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners) + { + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to")); + return; + } + + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN); + + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; + else + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId); + + /* free blocks */ + if (p_FmPcd->guestId == NCSW_MASTER_ID) + KgFreeClsPlanEntries(h_FmPcd, + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp, + p_FmPcd->guestId, + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry); + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ + { + memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); + kgAlloc.guestId = p_FmPcd->guestId; + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp; + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry; + msg.msgId = FM_PCD_FREE_KG_CLSPLAN; + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); + replyLength = sizeof(uint32_t); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(kgAlloc), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + { + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + if (replyLength != sizeof(uint32_t)) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return; + } + if ((t_Error)reply.error != E_OK) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed")); + return; + } + } + + /* clear clsPlan driver structure */ + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp)); +} + +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t j, schemesPerPortVector = 0; + t_FmPcdKgScheme *p_Scheme; + uint8_t i, relativeSchemeId; + uint32_t tmp, walking1Mask; + uint8_t swPortIndex = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); + + /* for each scheme */ + for (i = 0; inumOfSchemes; i++) + { + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); + + if (add) + { + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; + if (!FmPcdKgIsSchemeValidSw(p_Scheme)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); + /* check netEnvId of the port against the scheme netEnvId */ + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId")); + + /* if next engine is private port policer profile, we need to check that it is valid */ + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId); + if (p_Scheme->nextRelativePlcrProfile) + { + for (j = 0;jnumOfProfiles;j++) + { + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort); + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range")); + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j))) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid.")); + } + } + if (!p_BindPort->useClsPlan) + { + /* This check may be redundant as port is a assigned to the whole NetEnv */ + + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain + cls plan options. Schemes that are used only directly, should not be checked. + it also may not be bound to schemes that go to CC with units that are options - so we OR + the match vector and the grpBits (= ccUnits) */ + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits) + { + uint8_t netEnvId; + walking1Mask = 0x80000000; + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId; + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector; + tmp |= p_Scheme->ccUnits; + while (tmp) + { + if (tmp & walking1Mask) + { + tmp &= ~walking1Mask; + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options")); + } + walking1Mask >>= 1; + } + } + } + } + /* build vector */ + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]); + } + + *p_SpReg = schemesPerPortVector; + + return E_OK; +} + +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t spReg; + t_Error err = E_OK; + + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + IncSchemeOwners(p_FmPcd, p_SchemeBind); + + return E_OK; +} + +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t spReg; + t_Error err = E_OK; + + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + DecSchemeOwners(p_FmPcd, p_SchemeBind); + + return E_OK; +} + +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme) +{ + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; + + return p_Scheme->valid; +} + +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId) +{ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV) - FmPcdDecNetEnvOwners(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId); - p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = FALSE; + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT) + return TRUE; + else + return FALSE; +} + +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint8_t i, j; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); + + /* This routine is issued only on master core of master partition - + either directly or through IPC, so no need for lock */ + + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++) + { + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated) + { + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE; + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId; + p_SchemesIds[j] = i; + j++; + } + } + + if (j != numOfSchemes) + { + /* roll back */ + for (j--; j; j--) + { + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE; + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0; + p_SchemesIds[j] = 0; + } + + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found")); + } + + return E_OK; +} + +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint8_t i; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); + + /* This routine is issued only on master core of master partition - + either directly or through IPC */ + + for (i = 0; i < numOfSchemes; i++) + { + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated) + { + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated")); + } + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId) + { + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. ")); + } + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE; + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0; + } + + return E_OK; +} + +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint8_t numOfBlocks, blocksFound=0, first=0; + uint8_t i, j; + + /* This routine is issued only on master core of master partition - + either directly or through IPC, so no need for lock */ + + if (!numOfClsPlanEntries) + return E_OK; + + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8")); + + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); + + /* try to find consequent blocks */ + first = 0; + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;) + { + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated) + { + blocksFound++; + i++; + if (blocksFound == numOfBlocks) + break; + } + else + { + blocksFound = 0; + /* advance i to the next aligned address */ + first = i = (uint8_t)(first + numOfBlocks); + } + } + + if (blocksFound == numOfBlocks) + { + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP); + for (j = first; j < (first + numOfBlocks); j++) + { + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE; + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId; + } + return E_OK; + } + else + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan")); +} + +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint8_t numOfBlocks; + uint8_t i, baseBlock; + +#ifdef DISABLE_ASSERTIONS +UNUSED(guestId); +#endif /* DISABLE_ASSERTIONS */ + + /* This routine is issued only on master core of master partition - + either directly or through IPC, so no need for lock */ + + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP)); + + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP); + for (i=baseBlock;ip_FmPcdKg->clsPlanBlocksMng[i].allocated); + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId); + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE; + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0; + } +} + +void KgEnable(t_FmPcd *p_FmPcd) +{ + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); + fman_kg_enable(p_Regs); +} + +void KgDisable(t_FmPcd *p_FmPcd) +{ + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); + fman_kg_disable(p_Regs); +} + +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + struct fman_kg_cp_regs *p_FmPcdKgPortRegs; + uint32_t tmpKgarReg = 0, intFlags; + uint16_t i, j; + + /* This routine is protected by the calling routine ! */ + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs; + + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + for (i=p_Set->baseEntry;ibaseEntry+p_Set->numOfClsPlanEntries;i+=8) + { + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); + + for (j = i; j < i+8; j++) + { + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]); + } + + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED")); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); + return; + } + } + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); +} + +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) +{ + t_FmPcdKg *p_FmPcdKg; + + UNUSED(p_FmPcd); + + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES)); + return NULL; + } + + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg)); + if (!p_FmPcdKg) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED")); + return NULL; + } + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg)); + + + if (FmIsMaster(p_FmPcd->h_Fm)) + { + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm)); + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions; + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0]; + } + + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes; + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes) + { + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES")); + } + + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; + + return p_FmPcdKg; +} + +t_Error KgInit(t_FmPcd *p_FmPcd) +{ + t_Error err = E_OK; + + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock(); + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock")); + + if (p_FmPcd->guestId == NCSW_MASTER_ID) + err = KgInitMaster(p_FmPcd); + else + err = KgInitGuest(p_FmPcd); + + if (err != E_OK) + { + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); + } + + return err; +} + +t_Error KgFree(t_FmPcd *p_FmPcd) +{ + t_FmPcdIpcKgSchemesParams kgAlloc; + t_Error err = E_OK; + t_FmPcdIpcMsg msg; + uint32_t replyLength; + t_FmPcdIpcReply reply; + + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR); + + if (p_FmPcd->guestId == NCSW_MASTER_ID) + { + err = FmPcdKgFreeSchemes(p_FmPcd, + p_FmPcd->p_FmPcdKg->numOfSchemes, + p_FmPcd->guestId, + p_FmPcd->p_FmPcdKg->schemesIds); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); + + return E_OK; + } + + /* guest */ + memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; + kgAlloc.guestId = p_FmPcd->guestId; + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES); + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes); + msg.msgId = FM_PCD_FREE_KG_SCHEMES; + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(kgAlloc), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); + + return (t_Error)reply.error; +} + +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams; + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; + t_Error err; + + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules, + so no need for lock here */ + + memset(&grpParams, 0, sizeof(grpParams)); + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN; + p_GrpParams = &grpParams; + + p_GrpParams->netEnvId = netEnvId; + + /* Get from the NetEnv the information of the clsPlan (can be already created, + * or needs to build) */ + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams); + if (err) + RETURN_ERROR(MINOR,err,NO_MSG); + + if (p_GrpParams->grpExists) + { + /* this group was already updated (at least) in SW */ + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; + } + else + { + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); + if (!p_ClsPlanSet) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */ + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet); + if (err) + { + XX_Free(p_ClsPlanSet); + RETURN_ERROR(MINOR, err, NO_MSG); + } + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; + + if (p_FmPcd->h_Hc) + { + /* write clsPlan entries to memory */ + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet); + if (err) + { + XX_Free(p_ClsPlanSet); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + else + /* write clsPlan entries to memory */ + KgSetClsPlan(p_FmPcd, p_ClsPlanSet); + + XX_Free(p_ClsPlanSet); + } + + /* Set caller parameters */ + + /* mark if this is an empty classification group */ + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) + *p_IsEmptyClsPlanGrp = TRUE; + else + *p_IsEmptyClsPlanGrp = FALSE; + + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId]; + + /* increment owners number */ + p_ClsPlanGrp->owners++; + + /* copy options array for port */ + memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t)); + + /* bind port to the new or existing group */ + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId); + if (err) + RETURN_ERROR(MINOR, err, NO_MSG); + + return E_OK; +} + +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId]; + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; + t_Error err; + + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules, + so no need for lock here */ + + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId); + + /* decrement owners number */ + ASSERT_COND(p_ClsPlanGrp->owners); + p_ClsPlanGrp->owners--; + + if (!p_ClsPlanGrp->owners) + { + if (p_FmPcd->h_Hc) + { + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId); + return err; + } + else + { + /* clear clsPlan entries in memory */ + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); + if (!p_ClsPlanSet) + { + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); + } + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); + + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry; + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp; + KgSetClsPlan(p_FmPcd, p_ClsPlanSet); + XX_Free(p_ClsPlanSet); + + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId); + } + } + return E_OK; } uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId) @@ -2615,13 +2608,13 @@ uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId) return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction; } -uint32_t FmPcdKgGetPointedOwners(t_Handle h_FmPcd, uint8_t schemeId) +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); - return p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners; + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag; } bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId) @@ -2643,14 +2636,13 @@ uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId) return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId; } - bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); - if((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs && + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs && p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) || p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile) return TRUE; @@ -2658,25 +2650,14 @@ bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId) return FALSE; } -void FmPcdKgUpatePointedOwner(t_Handle h_FmPcd, uint8_t schemeId, bool add) + +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid); - if(add) - p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners++; - else - p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners--; -} - -e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); - - return p_FmPcd->p_FmPcdKg->schemes[schemeId].nextEngine; + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine; } e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId) @@ -2688,127 +2669,85 @@ e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId) return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction; } -void FmPcdKgUpdateRequiredAction(t_Handle h_FmPcd, uint8_t schemeId, uint32_t requiredAction) +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; - ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); + /* this routine is protected by calling routine */ - p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction = requiredAction; + ASSERT_COND(p_Scheme->valid); + + p_Scheme->requiredAction |= requiredAction; } -t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - if(schemeId >= FM_PCD_KG_NUM_OF_SCHEMES) - REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - - /* check that no port is bound to this scheme */ - if(p_FmPcd->p_FmPcdKg->schemes[schemeId].owners) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to")); - if(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete an invalid scheme")); - return E_OK; + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN); } -uint32_t FmPcdKgBuildCppReg(t_Handle h_FmPcd, uint8_t clsPlanGrpId) +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t tmpKgpeCpp; - - tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8); - tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_PCD_KG_PE_CPP_MASK_SHIFT); - return tmpKgpeCpp; + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | + FM_KG_KGAR_GO | + FM_KG_KGAR_WRITE | + FM_KG_KGAR_SEL_SCHEME_ENTRY | + DUMMY_PORT_ID | + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0)); } -bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg) +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId) { - - if(schemeModeReg & KG_SCH_MODE_EN) - return TRUE; - else - return FALSE; -} - -uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter) -{ - return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)| - FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_WRITE | - FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY | - DUMMY_PORT_ID | - (updateCounter ? FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT:0)); + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | + FM_KG_KGAR_GO | + FM_KG_KGAR_READ | + FM_KG_KGAR_SEL_SCHEME_ENTRY | + DUMMY_PORT_ID | + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT); } -uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId) +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId) { - return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)| - FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_READ | - FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY | - DUMMY_PORT_ID | - FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT); + return (uint32_t)(FM_KG_KGAR_GO | + FM_KG_KGAR_WRITE | + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | + DUMMY_PORT_ID | + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | + FM_PCD_KG_KGAR_WSEL_MASK); + /* if we ever want to write 1 by 1, use: + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); + */ } - -uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId) +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId) { - return (uint32_t)(FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_WRITE | - FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | - DUMMY_PORT_ID | - ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | - FM_PCD_KG_KGAR_WSEL_MASK); - - /* if we ever want to write 1 by 1, use: - sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/ + return (uint32_t)(FM_KG_KGAR_GO | + FM_KG_KGAR_WRITE | + FM_PCD_KG_KGAR_SEL_PORT_ENTRY | + hardwarePortId | + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); } -uint32_t FmPcdKgBuildReadClsPlanBlockActionReg(uint8_t grpId) +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId) { - return (uint32_t)(FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_READ | - FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | - DUMMY_PORT_ID | - ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | - FM_PCD_KG_KGAR_WSEL_MASK); - - /* if we ever want to write 1 by 1, use: - sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/ + return (uint32_t)(FM_KG_KGAR_GO | + FM_KG_KGAR_READ | + FM_PCD_KG_KGAR_SEL_PORT_ENTRY | + hardwarePortId | + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); } -uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId) +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId) { - return (uint32_t)(FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_WRITE | - FM_PCD_KG_KGAR_SEL_PORT_ENTRY | - hardwarePortId | - FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); -} - -uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId) -{ - - return (uint32_t)(FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_READ | - FM_PCD_KG_KGAR_SEL_PORT_ENTRY | - hardwarePortId | - FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); -} -uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId) -{ - - return (uint32_t)(FM_PCD_KG_KGAR_GO | - FM_PCD_KG_KGAR_WRITE | - FM_PCD_KG_KGAR_SEL_PORT_ENTRY | - hardwarePortId | - FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); + return (uint32_t)(FM_KG_KGAR_GO | + FM_KG_KGAR_WRITE | + FM_PCD_KG_KGAR_SEL_PORT_ENTRY | + hardwarePortId | + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); } uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp) @@ -2825,106 +2764,125 @@ uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp) return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp; } -uint8_t FmPcdKgGetSchemeSwId(t_Handle h_FmPcd, uint8_t schemeHwId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint8_t i; - for(i=0;ip_FmPcdKg->numOfSchemes;i++) - if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeHwId) - return i; - ASSERT_COND(i!=p_FmPcd->p_FmPcdKg->numOfSchemes); - return FM_PCD_KG_NUM_OF_SCHEMES; +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme) +{ + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId; + } -uint8_t FmPcdKgGetNumOfPartitionSchemes(t_Handle h_FmPcd) +#if (DPAA_VERSION >= 11) +bool FmPcdKgGetVspe(t_Handle h_Scheme) { - return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->numOfSchemes; -} + return ((t_FmPcdKgScheme*)h_Scheme)->vspe; -uint8_t FmPcdKgGetPhysicalSchemeId(t_Handle h_FmPcd, uint8_t relativeSchemeId) -{ - return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemesIds[relativeSchemeId]; } +#endif /* (DPAA_VERSION >= 11) */ uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; uint8_t i; - for(i = 0;ip_FmPcdKg->numOfSchemes;i++) - if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId) + for (i = 0;ip_FmPcdKg->numOfSchemes;i++) + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId) return i; - if(i == p_FmPcd->p_FmPcdKg->numOfSchemes) + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes) REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range")); return FM_PCD_KG_NUM_OF_SCHEMES; } -t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction) +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + ASSERT_COND(p_FmPcd); + + /* check that schemeId is in range */ + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) + { + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); + return NULL; + } + + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId])) + return NULL; + + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; +} + +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme) +{ + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE; +} + +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; uint8_t relativeSchemeId, physicalSchemeId; uint32_t tmpKgarReg, tmpReg32 = 0, intFlags; t_Error err; + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); - if (p_FmPcd->h_Hc) - return FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction); + /* Calling function locked all PCD modules, so no need to lock here */ - physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + if (!FmPcdKgIsSchemeValidSw(h_Scheme)) + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); + + if (p_FmPcd->h_Hc) + { + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value); + + UpdateRequiredActionFlag(h_Scheme,TRUE); + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction); + return err; + } + + physicalSchemeId = p_Scheme->schemeId; relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); - if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Lock of the scheme FAILED")); - - if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners || - !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction)) + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag || + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction)) { - if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) { - switch(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine) + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine) { - case(e_FM_PCD_DONE): - if(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME) + case (e_FM_PCD_DONE): + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME) { tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - intFlags = FmPcdLock(p_FmPcd); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); WriteKgarWait(p_FmPcd, tmpKgarReg); - if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); - RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); - } - tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode); + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA); /* call indirect command for scheme write */ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); } break; - case(e_FM_PCD_PLCR): - if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr || + case (e_FM_PCD_PLCR): + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr || (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs && p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) || p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile) { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); } err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction); - if(err) + if (err) { - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); RETURN_ERROR(MAJOR, err, NO_MSG); } break; @@ -2932,258 +2890,353 @@ t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t req RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME")); } } + if (requiredAction & UPDATE_KG_NIA_CC_WA) + { + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC) + { + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + WriteKgarWait(p_FmPcd, tmpKgarReg); + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); + tmpReg32 &= ~NIA_FM_CTL_AC_CC; + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC); + /* call indirect command for scheme write */ + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); + WriteKgarWait(p_FmPcd, tmpKgarReg); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); + } + } + if (requiredAction & UPDATE_KG_OPT_MODE) + { + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + WriteKgarWait(p_FmPcd, tmpKgarReg); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value); + /* call indirect command for scheme write */ + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); + WriteKgarWait(p_FmPcd, tmpKgarReg); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); + } + if (requiredAction & UPDATE_KG_NIA) + { + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + WriteKgarWait(p_FmPcd, tmpKgarReg); + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK); + tmpReg32 |= value; + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32); + /* call indirect command for scheme write */ + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); + WriteKgarWait(p_FmPcd, tmpKgarReg); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); + } } - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners += 1; - p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction |= requiredAction; - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); + UpdateRequiredActionFlag(h_Scheme, TRUE); + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction); + return E_OK; } +/*********************** End of inter-module routines ************************/ -t_Error FmPcdKgSchemeTryLock(t_Handle h_FmPcd, uint8_t schemeId, bool intr) + +/****************************************/ +/* API routines */ +/****************************************/ + +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - bool ans; - - if (intr) - ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock); - else - ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock); - if (ans) - return E_OK; - return ERROR_CODE(E_BUSY); -} - -void FmPcdKgReleaseSchemeLock(t_Handle h_FmPcd, uint8_t schemeId) -{ - RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemes[schemeId].lock); -} - -t_Handle FM_PCD_KgSetScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t tmpReg; - t_FmPcdKgInterModuleSchemeRegs schemeRegs; - t_FmPcdKgInterModuleSchemeRegs *p_MemRegs; + t_FmPcd *p_FmPcd; + struct fman_kg_scheme_regs schemeRegs; + struct fman_kg_scheme_regs *p_MemRegs; uint8_t i; t_Error err = E_OK; uint32_t tmpKgarReg; uint32_t intFlags; - uint8_t physicalSchemeId, relativeSchemeId; + uint8_t physicalSchemeId, relativeSchemeId = 0; + t_FmPcdKgScheme *p_Scheme; - SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); - - if (p_FmPcd->h_Hc) - return FmHcPcdKgSetScheme(p_FmPcd->h_Hc, p_Scheme); - - /* if not called for modification, check first that this scheme is unused */ - if(!p_Scheme->modify) + if (p_SchemeParams->modify) { - /* check that schemeId is in range */ - if(p_Scheme->id.relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) - { - REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of range")); - return NULL; - } - relativeSchemeId = p_Scheme->id.relativeSchemeId; + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme; + p_FmPcd = p_Scheme->h_FmPcd; - if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) - return NULL; + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); - physicalSchemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId]; - - /* read specified scheme into scheme registers */ - tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - intFlags = FmPcdLock(p_FmPcd); - WriteKgarWait(p_FmPcd, tmpKgarReg); - tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode); - FmPcdUnlock(p_FmPcd, intFlags); - - if (tmpReg & KG_SCH_MODE_EN) + if (!FmPcdKgIsSchemeValidSw(p_Scheme)) { REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, - ("Scheme %d(phys %d) is already used", relativeSchemeId, physicalSchemeId)); - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); + ("Scheme is invalid")); + return NULL; + } + + if (!KgSchemeFlagTryLock(p_Scheme)) + { + DBG(TRACE, ("Scheme Try Lock - BUSY")); + /* Signal to caller BUSY condition */ + p_SchemeParams->id.h_Scheme = NULL; return NULL; } } else { - SANITY_CHECK_RETURN_VALUE(p_Scheme->id.h_Scheme, E_INVALID_HANDLE, NULL); + p_FmPcd = (t_FmPcd*)h_FmPcd; - intFlags = FmPcdLock(p_FmPcd); - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1); - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); + relativeSchemeId = p_SchemeParams->id.relativeSchemeId; /* check that schemeId is in range */ - if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) { - REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - FmPcdUnlock(p_FmPcd, intFlags); + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); return NULL; } - err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, TRUE); - FmPcdUnlock(p_FmPcd, intFlags); - if (err) + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; + if (FmPcdKgIsSchemeValidSw(p_Scheme)) + { + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, + ("Scheme id (%d)!", relativeSchemeId)); return NULL; + } + /* Clear all fields, scheme may have beed previously used */ + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme)); + + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId]; + p_Scheme->h_FmPcd = p_FmPcd; + + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd); + if (!p_Scheme->p_Lock) + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!")); } - err = FmPcdKgBuildScheme(h_FmPcd, p_Scheme, &schemeRegs); - if(err) + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs); + if (err) { REPORT_ERROR(MAJOR, err, NO_MSG); - FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId); - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); + if (p_SchemeParams->modify) + KgSchemeFlagUnlock(p_Scheme); + if (!p_SchemeParams->modify && + p_Scheme->p_Lock) + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); return NULL; } + if (p_FmPcd->h_Hc) + { + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc, + (t_Handle)p_Scheme, + &schemeRegs, + p_SchemeParams->schemeCounter.update); + if (p_SchemeParams->modify) + KgSchemeFlagUnlock(p_Scheme); + if (err) + { + if (!p_SchemeParams->modify && + p_Scheme->p_Lock) + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); + return NULL; + } + if (!p_SchemeParams->modify) + ValidateSchemeSw(p_Scheme); + return (t_Handle)p_Scheme; + } + + physicalSchemeId = p_Scheme->schemeId; + /* configure all 21 scheme registers */ - p_MemRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs; - intFlags = FmPcdLock(p_FmPcd); - WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc); - WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs); - WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode); - WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv); - WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0); - WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1); - WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv); - WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc); - WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch); - WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl); - WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc); - WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc); - WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb); - for(i=0 ; ip_FmPcdKg->p_IndirectAccessRegs->schemeRegs; + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc); + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs); + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode); + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv); + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0); + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1); + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv); + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc); + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch); + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl); + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc); + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc); + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb); + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om); + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp); + for (i=0 ; ikgse_gec[i], schemeRegs.kgse_gec[i]); /* call indirect command for scheme write */ - tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_Scheme->schemeCounter.update); + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update); WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); - FmPcdKgValidateSchemeSw(h_FmPcd, relativeSchemeId); + if (!p_SchemeParams->modify) + ValidateSchemeSw(p_Scheme); + else + KgSchemeFlagUnlock(p_Scheme); - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); - - return UINT_TO_PTR((uint64_t)physicalSchemeId+1); + return (t_Handle)p_Scheme; } -t_Error FM_PCD_KgDeleteScheme(t_Handle h_FmPcd, t_Handle h_Scheme) +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcd *p_FmPcd; uint8_t physicalSchemeId; uint32_t tmpKgarReg, intFlags; t_Error err = E_OK; - uint8_t relativeSchemeId; + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE); - if (p_FmPcd->h_Hc) - return FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme); + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd); - physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); - - if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) - RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - - if ((err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); + UpdateRequiredActionFlag(h_Scheme, FALSE); /* check that no port is bound to this scheme */ - err = FmPcdKgCheckInvalidateSchemeSw(h_FmPcd, relativeSchemeId); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + err = InvalidateSchemeSw(h_Scheme); + if (err) + RETURN_ERROR(MINOR, err, NO_MSG); - intFlags = FmPcdLock(p_FmPcd); + if (p_FmPcd->h_Hc) + { + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme); + if (p_Scheme->p_Lock) + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); + return err; + } + + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; + + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); /* clear mode register, including enable bit */ - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, 0); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0); /* call indirect command for scheme write */ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); - FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId); - - RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); + if (p_Scheme->p_Lock) + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); return E_OK; } -uint32_t FM_PCD_KgGetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme) +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcd *p_FmPcd; uint32_t tmpKgarReg, spc, intFlags; uint8_t physicalSchemeId; - SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); if (p_FmPcd->h_Hc) return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme); - physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; - if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - intFlags = FmPcdLock(p_FmPcd); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); WriteKgarWait(p_FmPcd, tmpKgarReg); - if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); - spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc); - FmPcdUnlock(p_FmPcd, intFlags); + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); return spc; } -t_Error FM_PCD_KgSetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t value) +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcd *p_FmPcd; uint32_t tmpKgarReg, intFlags; uint8_t physicalSchemeId; - SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); + + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); + + if (!FmPcdKgIsSchemeValidSw(h_Scheme)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); if (p_FmPcd->h_Hc) return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value); - physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; /* check that schemeId is in range */ - if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); /* read specified scheme into scheme registers */ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); - intFlags = FmPcdLock(p_FmPcd); + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); WriteKgarWait(p_FmPcd, tmpKgarReg); - if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) { - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); } /* change counter value */ - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc, value); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value); /* call indirect command for scheme write */ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); WriteKgarWait(p_FmPcd, tmpKgarReg); - FmPcdUnlock(p_FmPcd, intFlags); + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); return E_OK; } +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + struct fman_kg_regs *p_Regs; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); + + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + if (!FmIsMaster(p_FmPcd->h_Fm)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!")); + + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset); + + return E_OK; +} + +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + struct fman_kg_regs *p_Regs; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); + + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; + + if (!FmIsMaster(p_FmPcd->h_Fm)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!")); + + if (valueId == 0) + WRITE_UINT32(p_Regs->fmkg_gdv0r,value); + else + WRITE_UINT32(p_Regs->fmkg_gdv1r,value); + return E_OK; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.h new file mode 100644 index 000000000000..cb7521a11397 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.h @@ -0,0 +1,206 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_kg.h + + @Description FM KG private header +*//***************************************************************************/ +#ifndef __FM_KG_H +#define __FM_KG_H + +#include "std_ext.h" + +/***********************************************************************/ +/* Keygen defines */ +/***********************************************************************/ +/* maskes */ +#if (DPAA_VERSION >= 11) +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000 +#define KG_SCH_OM_VSPE 0x00000001 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000 + +#define MAX_SP_SHIFT 23 +#define KG_SCH_VSP_MASK_SHIFT 12 +#define KG_SCH_VSP_SHIFT 24 +#endif /* (DPAA_VERSION >= 11) */ + +typedef uint32_t t_KnownFieldsMasks; +#define KG_SCH_KN_PORT_ID 0x80000000 +#define KG_SCH_KN_MACDST 0x40000000 +#define KG_SCH_KN_MACSRC 0x20000000 +#define KG_SCH_KN_TCI1 0x10000000 +#define KG_SCH_KN_TCI2 0x08000000 +#define KG_SCH_KN_ETYPE 0x04000000 +#define KG_SCH_KN_PPPSID 0x02000000 +#define KG_SCH_KN_PPPID 0x01000000 +#define KG_SCH_KN_MPLS1 0x00800000 +#define KG_SCH_KN_MPLS2 0x00400000 +#define KG_SCH_KN_MPLS_LAST 0x00200000 +#define KG_SCH_KN_IPSRC1 0x00100000 +#define KG_SCH_KN_IPDST1 0x00080000 +#define KG_SCH_KN_PTYPE1 0x00040000 +#define KG_SCH_KN_IPTOS_TC1 0x00020000 +#define KG_SCH_KN_IPV6FL1 0x00010000 +#define KG_SCH_KN_IPSRC2 0x00008000 +#define KG_SCH_KN_IPDST2 0x00004000 +#define KG_SCH_KN_PTYPE2 0x00002000 +#define KG_SCH_KN_IPTOS_TC2 0x00001000 +#define KG_SCH_KN_IPV6FL2 0x00000800 +#define KG_SCH_KN_GREPTYPE 0x00000400 +#define KG_SCH_KN_IPSEC_SPI 0x00000200 +#define KG_SCH_KN_IPSEC_NH 0x00000100 +#define KG_SCH_KN_IPPID 0x00000080 +#define KG_SCH_KN_L4PSRC 0x00000004 +#define KG_SCH_KN_L4PDST 0x00000002 +#define KG_SCH_KN_TFLG 0x00000001 + +typedef uint8_t t_GenericCodes; +#define KG_SCH_GEN_SHIM1 0x70 +#define KG_SCH_GEN_DEFAULT 0x10 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20 +#define KG_SCH_GEN_START_OF_FRM 0x40 +#define KG_SCH_GEN_SHIM2 0x71 +#define KG_SCH_GEN_IP_PID_NO_V 0x72 +#define KG_SCH_GEN_ETH 0x03 +#define KG_SCH_GEN_ETH_NO_V 0x73 +#define KG_SCH_GEN_SNAP 0x04 +#define KG_SCH_GEN_SNAP_NO_V 0x74 +#define KG_SCH_GEN_VLAN1 0x05 +#define KG_SCH_GEN_VLAN1_NO_V 0x75 +#define KG_SCH_GEN_VLAN2 0x06 +#define KG_SCH_GEN_VLAN2_NO_V 0x76 +#define KG_SCH_GEN_ETH_TYPE 0x07 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77 +#define KG_SCH_GEN_PPP 0x08 +#define KG_SCH_GEN_PPP_NO_V 0x78 +#define KG_SCH_GEN_MPLS1 0x09 +#define KG_SCH_GEN_MPLS2 0x19 +#define KG_SCH_GEN_MPLS3 0x29 +#define KG_SCH_GEN_MPLS1_NO_V 0x79 +#define KG_SCH_GEN_MPLS_LAST 0x0a +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a +#define KG_SCH_GEN_IPV4 0x0b +#define KG_SCH_GEN_IPV6 0x1b +#define KG_SCH_GEN_L3_NO_V 0x7b +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c +#define KG_SCH_GEN_MIN_ENCAP 0x2c +#define KG_SCH_GEN_IP2_NO_V 0x7c +#define KG_SCH_GEN_GRE 0x0d +#define KG_SCH_GEN_GRE_NO_V 0x7d +#define KG_SCH_GEN_TCP 0x0e +#define KG_SCH_GEN_UDP 0x1e +#define KG_SCH_GEN_IPSEC_AH 0x2e +#define KG_SCH_GEN_SCTP 0x3e +#define KG_SCH_GEN_DCCP 0x4e +#define KG_SCH_GEN_IPSEC_ESP 0x6e +#define KG_SCH_GEN_L4_NO_V 0x7e +#define KG_SCH_GEN_NEXTHDR 0x7f +/* shifts */ +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12 +#define KG_SCH_PP_MASK_SHIFT 16 +#define KG_SCH_MODE_CCOBASE_SHIFT 24 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30 +#define KG_SCH_DEF_TCI_SHIFT 28 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10 +#define KG_SCH_DEF_L4_PORT_SHIFT 8 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24 +#define KG_SCH_GEN_MASK_SHIFT 16 +#define KG_SCH_GEN_HT_SHIFT 8 +#define KG_SCH_GEN_SIZE_SHIFT 24 +#define KG_SCH_GEN_DEF_SHIFT 29 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16 + +/* others */ +#define NUM_OF_SW_DEFAULTS 3 +#define MAX_PP_SHIFT 23 +#define MAX_KG_SCH_SIZE 16 +#define MASK_FOR_GENERIC_BASE_ID 0x20 +#define MAX_HASH_SHIFT 40 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31 +#define MAX_KG_SCH_PP_BIT_OFFSET 15 +#define MAX_DIST_FQID_SHIFT 23 + +#define GET_MASK_SEL_SHIFT(shift,i) \ +switch (i) { \ + case (0):shift = 26;break; \ + case (1):shift = 20;break; \ + case (2):shift = 10;break; \ + case (3):shift = 4;break; \ + default: \ + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ +} + +#define GET_MASK_OFFSET_SHIFT(shift,i) \ +switch (i) { \ + case (0):shift = 16;break; \ + case (1):shift = 0;break; \ + case (2):shift = 28;break; \ + case (3):shift = 24;break; \ + default: \ + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ +} + +#define GET_MASK_SHIFT(shift,i) \ +switch (i) { \ + case (0):shift = 24;break; \ + case (1):shift = 16;break; \ + case (2):shift = 8;break; \ + case (3):shift = 0;break; \ + default: \ + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ +} + +/***********************************************************************/ +/* Keygen defines */ +/***********************************************************************/ + +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100 +#define NO_VALIDATION 0x70 +#define KG_ACTION_REG_TO 1024 +#define KG_MAX_PROFILE 255 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF + + +#endif /* __FM_KG_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c index 0d176e88b48b..33e7ae807347 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,18 +30,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_manip.c @Description FM PCD manip ... -*//***************************************************************************/ -#ifdef CONFIG_FMAN_P1023 -#ifdef FM_CAPWAP_SUPPORT + *//***************************************************************************/ #include "std_ext.h" #include "error_ext.h" #include "string_ext.h" #include "debug_ext.h" #include "fm_pcd_ext.h" +#include "fm_port_ext.h" #include "fm_muram_ext.h" #include "memcpy_ext.h" @@ -49,1472 +49,2971 @@ #include "fm_hc.h" #include "fm_manip.h" - -#ifdef CORE_8BIT_ACCESS_ERRATA -#undef WRITE_UINT16 -#undef GET_UINT16 -#undef WRITE_UINT8 -#undef GET_UINT8 - -#define WRITE_UINT16(addr, val) \ - do{ \ - if((int)&(addr) % 4) \ - WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L), \ - ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val)); \ - else \ - WRITE_UINT32(*(uint32_t*)&addr, \ - ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16)); \ - }while(0); -#define GET_UINT16(addr) (((uint32_t)&addr%4) ? \ - ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))): \ - ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16))) - -#define WRITE_UINT8(addr,val) WRITE_UINT8_ERRATA(&addr,val) -#define GET_UINT8(addr) GET_UINT8_ERRATA(&addr) -#endif /* CORE_8BIT_ACCESS_ERRATA */ - - -static void WRITE_UINT8_ERRATA(uint8_t *addr, uint8_t val) +/****************************************/ +/* static functions */ +/****************************************/ +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo) { - uint32_t newAddr, newVal; - newAddr = (uint32_t)addr & ~0x3L; - switch ((uint32_t)addr%4) + t_FmPcdManip *p_CurManip = p_Manip; + + if (!MANIP_IS_UNIFIED(p_Manip)) + p_CurManip = p_Manip; + else { - case (0): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x00ffffff) | (((uint32_t)val)<<24); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (1): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xff00ffff) | (((uint32_t)val)<<16); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (2): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xffff00ff) | (((uint32_t)val)<<8); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (3): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xffffff00) | val; - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; + /* go to first unified */ + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) + p_CurManip = p_CurManip->h_PrevManip; + } + + switch (manipInfo) + { + case (e_MANIP_HMCT): + return p_CurManip->p_Hmct; + case (e_MANIP_HMTD): + return p_CurManip->h_Ad; + case (e_MANIP_HANDLER_TABLE_OWNER): + return (t_Handle)p_CurManip; + default: + return NULL; } } -static uint8_t GET_UINT8_ERRATA(uint8_t *addr) +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip) { - uint32_t newAddr, newVal=0; - newAddr = (uint32_t)addr & ~0x3L; - switch ((uint32_t)addr%4) - { - case (0): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xff000000)>>24; - break; - case (1): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x00ff0000)>>16; - break; - case (2): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x0000ff00)>>8; - break; - case (3): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x000000ff); - break; - } + uint16_t size = 0; + t_FmPcdManip *p_CurManip = p_Manip; - return (uint8_t)newVal; + if (!MANIP_IS_UNIFIED(p_Manip)) + return p_Manip->tableSize; + + /* accumulate sizes, starting with the first node */ + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) + p_CurManip = p_CurManip->h_PrevManip; + + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) + { + size += p_CurManip->tableSize; + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; + } + size += p_CurManip->tableSize; /* add last size */ + + return (size); } -static t_Error GetPrOffsetByNonHeader(uint8_t *parseArrayOffset) +static uint16_t GetDataSize(t_FmPcdManip *p_Manip) { - /*For now - the only field in the Parse Array from the NON_BY_TYPE can be e_FM_PCD_KG_EXTRACT_FROM_CURR_END_OF_PARSE*/ - /*Maybe extended in the future*/ + uint16_t size = 0; + t_FmPcdManip *p_CurManip = p_Manip; - *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; + if (!MANIP_IS_UNIFIED(p_Manip)) + return p_Manip->dataSize; + + /* accumulate sizes, starting with the first node */ + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) + p_CurManip = p_CurManip->h_PrevManip; + + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) + { + size += p_CurManip->dataSize; + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; + } + size += p_CurManip->dataSize; /* add last size */ + + return (size); +} + +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams, + uint16_t *p_TableSize, uint8_t *p_DataSize) +{ + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0; + + if (p_FmPcdManipParams->u.hdr.rmv) + { + switch (p_FmPcdManipParams->u.hdr.rmvParams.type) + { + case (e_FM_PCD_MANIP_RMV_GENERIC): + tableSize += HMCD_BASIC_SIZE; + break; + case (e_FM_PCD_MANIP_RMV_BY_HDR): + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): +#endif /* (DPAA_VERSION >= 11) */ + tableSize += HMCD_BASIC_SIZE; + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown byHdr.type")); + } + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown rmvParams.type")); + } + } + + if (p_FmPcdManipParams->u.hdr.insrt) + { + switch (p_FmPcdManipParams->u.hdr.insrtParams.type) + { + case (e_FM_PCD_MANIP_INSRT_GENERIC): + remain = + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size + % 4); + if (remain) + localDataSize = + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size + + 4 - remain); + else + localDataSize = + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize); + break; + case (e_FM_PCD_MANIP_INSRT_BY_HDR): + { + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) + { + + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE; + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) + { + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): + dataSize += + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; + break; + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); + } + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): + tableSize += + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE + + HMCD_PARAM_SIZE + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); + dataSize += 2; + break; + + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE); + + break; + + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): + tableSize += + (HMCD_BASIC_SIZE + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown byHdr.type")); + } + } + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown insrtParams.type")); + } + } + + if (p_FmPcdManipParams->u.hdr.fieldUpdate) + { + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) + { + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): + tableSize += HMCD_BASIC_SIZE; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) + { + tableSize += HMCD_PTR_SIZE; + dataSize += DSCP_TO_VLAN_TABLE_SIZE; + } + break; + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): + tableSize += HMCD_BASIC_SIZE; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_ID) + { + tableSize += HMCD_PARAM_SIZE; + dataSize += 2; + } + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_SRC) + tableSize += HMCD_IPV4_ADDR_SIZE; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_DST) + tableSize += HMCD_IPV4_ADDR_SIZE; + break; + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): + tableSize += HMCD_BASIC_SIZE; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV6_SRC) + tableSize += HMCD_IPV6_ADDR_SIZE; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV6_DST) + tableSize += HMCD_IPV6_ADDR_SIZE; + break; + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + == HDR_MANIP_TCP_UDP_CHECKSUM) + /* we implement this case with the update-checksum descriptor */ + tableSize += HMCD_BASIC_SIZE; + else + /* we implement this case with the TCP/UDP-update descriptor */ + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown fieldUpdateParams.type")); + } + } + + if (p_FmPcdManipParams->u.hdr.custom) + { + switch (p_FmPcdManipParams->u.hdr.customParams.type) + { + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): + { + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE; + dataSize += + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) + dataSize += 2; + } + break; + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown customParams.type")); + } + } + + *p_TableSize = tableSize; + *p_DataSize = dataSize; return E_OK; } +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo, + uint8_t *parseArrayOffset) +{ + e_NetHeaderType hdr = p_HdrInfo->hdr; + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex; + bool byField = p_HdrInfo->byField; + t_FmPcdFields field; + + if (byField) + field = p_HdrInfo->fullField; + + if (byField) + { + switch (hdr) + { + case (HEADER_TYPE_ETH): + switch (field.eth) + { + case (NET_HEADER_FIELD_ETH_TYPE): + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; + break; + default: + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("Header manipulation of the type Ethernet with this field not supported")); + } + break; + case (HEADER_TYPE_VLAN): + switch (field.vlan) + { + case (NET_HEADER_FIELD_VLAN_TCI): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; + break; + default: + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("Header manipulation of the type VLAN with this field not supported")); + } + break; + default: + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("Header manipulation of this header by field not supported")); + } + } + else + { + switch (hdr) + { + case (HEADER_TYPE_ETH): + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; + break; + case (HEADER_TYPE_USER_DEFINED_SHIM1): + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; + break; + case (HEADER_TYPE_USER_DEFINED_SHIM2): + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; + break; + case (HEADER_TYPE_LLC_SNAP): + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; + break; + case (HEADER_TYPE_PPPoE): + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; + break; + case (HEADER_TYPE_MPLS): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; + break; + case (HEADER_TYPE_IPv4): + case (HEADER_TYPE_IPv6): + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) + || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) + *parseArrayOffset = CC_PC_PR_IP1_OFFSET; + else + if (hdrIndex == e_FM_PCD_HDR_INDEX_2) + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; + break; + case (HEADER_TYPE_MINENCAP): + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; + break; + case (HEADER_TYPE_GRE): + *parseArrayOffset = CC_PC_PR_GRE_OFFSET; + break; + case (HEADER_TYPE_TCP): + case (HEADER_TYPE_UDP): + case (HEADER_TYPE_IPSEC_AH): + case (HEADER_TYPE_IPSEC_ESP): + case (HEADER_TYPE_DCCP): + case (HEADER_TYPE_SCTP): + *parseArrayOffset = CC_PC_PR_L4_OFFSET; + break; + case (HEADER_TYPE_CAPWAP): + case (HEADER_TYPE_CAPWAP_DTLS): + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; + break; + default: + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("Header manipulation of this header is not supported")); + } + } + return E_OK; +} + +static t_Error BuildHmct(t_FmPcdManip *p_Manip, + t_FmPcdManipParams *p_FmPcdManipParams, + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new) +{ + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData; + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr; + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData = + p_DestData; + t_Handle h_FmPcd = p_Manip->h_FmPcd; + uint8_t j = 0; + + if (p_FmPcdManipParams->u.hdr.rmv) + { + if (p_FmPcdManipParams->u.hdr.rmvParams.type + == e_FM_PCD_MANIP_RMV_GENERIC) + { + /* initialize HMCD */ + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT; + /* tmp, should be conditional */ + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset + << HMCD_RMV_OFFSET_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size + << HMCD_RMV_SIZE_SHIFT; + } + else + if (p_FmPcdManipParams->u.hdr.rmvParams.type + == e_FM_PCD_MANIP_RMV_BY_HDR) + { + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): + { + uint8_t hmcdOpt; + + /* initialize HMCD */ + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT; + + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2) + { + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET): + hmcdOpt = HMCD_RMV_L2_ETHERNET; + break; + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS): + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS; + break; + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS): + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS; + break; + case (e_FM_PCD_MANIP_HDR_RMV_MPLS): + hmcdOpt = HMCD_RMV_L2_MPLS; + break; + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE): + hmcdOpt = HMCD_RMV_L2_PPPOE; + break; + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); + } + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; + break; + } +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV) + << HMCD_OC_SHIFT; + break; + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): + { + uint8_t prsArrayOffset; + t_Error err = E_OK; + + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL) + << HMCD_OC_SHIFT; + + err = + GetPrOffsetByHeaderOrField( + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, + &prsArrayOffset); + ASSERT_COND(!err); + /* was previously checked */ + + tmpReg |= ((uint32_t)prsArrayOffset << 16); + } + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("manip header remove by hdr type!")); + } + } + + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + /* advance to next command */ + p_TmpHmct += HMCD_BASIC_SIZE / 4; + } + + if (p_FmPcdManipParams->u.hdr.insrt) + { + if (p_FmPcdManipParams->u.hdr.insrtParams.type + == e_FM_PCD_MANIP_INSRT_GENERIC) + { + /* initialize HMCD */ + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace) + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE) + << HMCD_OC_SHIFT; + else + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT; + + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset + << HMCD_INSRT_OFFSET_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size + << HMCD_INSRT_SIZE_SHIFT; + + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data; + + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + /* initialize data to be inserted */ + /* if size is not a multiple of 4, padd with 0's */ + origSize = size; + remain = (uint8_t)(size % 4); + if (remain) + { + size += (uint8_t)(4 - remain); + p_LocalData = (uint32_t *)XX_Malloc(size); + memset((uint8_t *)p_LocalData, 0, size); + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize); + } + else + p_LocalData = (uint32_t*)p_UsrData; + + /* initialize data and advance pointer to next command */ + MemCpy8(p_TmpHmct, p_LocalData, size); + p_TmpHmct += size / sizeof(uint32_t); + + if (remain) + XX_Free(p_LocalData); + } + + else + if (p_FmPcdManipParams->u.hdr.insrtParams.type + == e_FM_PCD_MANIP_INSRT_BY_HDR) + { + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): + { + uint8_t hmcdOpt; + + /* initialize HMCD */ + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT) + << HMCD_OC_SHIFT; + + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) + { + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update) + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS; + else + hmcdOpt = HMCD_INSRT_L2_MPLS; + break; + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): + hmcdOpt = HMCD_INSRT_L2_PPPOE; + break; + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); + } + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; + + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + /* set size and pointer of user's data */ + size = + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; + + ASSERT_COND(p_TmpData); + MemCpy8( + p_TmpData, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data, + size); + tmpReg = + (size << HMCD_INSRT_L2_SIZE_SHIFT) + | (uint32_t)(XX_VirtToPhys(p_TmpData) + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); + WRITE_UINT32(*p_TmpHmct, tmpReg); + p_TmpHmct += HMCD_PTR_SIZE / 4; + p_TmpData += size; + } + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT) + << HMCD_OC_SHIFT; + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum) + tmpReg |= HMCD_IP_L4_CS_CALC; + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS) + tmpReg |= HMCD_IP_OR_QOS; + tmpReg |= + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset + & HMCD_IP_LAST_PID_MASK; + tmpReg |= + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size + << HMCD_IP_SIZE_SHIFT) + & HMCD_IP_SIZE_MASK); + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite) + tmpReg |= HMCD_IP_DF_MODE; + + WRITE_UINT32(*p_TmpHmct, tmpReg); + + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + /* set IP id */ + ASSERT_COND(p_TmpData); + WRITE_UINT16( + *(uint16_t*)p_TmpData, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id); + WRITE_UINT32( + *p_TmpHmct, + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); + p_TmpData += 2; + p_TmpHmct += HMCD_PTR_SIZE / 4; + + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset); + p_TmpHmct += HMCD_PARAM_SIZE / 4; + + MemCpy8( + p_TmpHmct, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); + p_TmpHmct += + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size + / 4; + break; + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): + tmpReg = HMCD_INSRT_UDP_LITE; + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT) + << HMCD_OC_SHIFT; + + WRITE_UINT32(*p_TmpHmct, tmpReg); + + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + MemCpy8( + p_TmpHmct, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); + p_TmpHmct += + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size + / 4; + break; + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT) + << HMCD_OC_SHIFT; + tmpReg |= HMCD_CAPWAP_INSRT; + + WRITE_UINT32(*p_TmpHmct, tmpReg); + + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + MemCpy8( + p_TmpHmct, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); + p_TmpHmct += + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size + / 4; + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("manip header insert by header type!")); + + } + } + } + + if (p_FmPcdManipParams->u.hdr.fieldUpdate) + { + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) + { + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE) + << HMCD_OC_SHIFT; + + /* set mode & table pointer */ + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) + { + /* set Mode */ + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI) + << HMCD_VLAN_PRI_REP_MODE_SHIFT; + /* set VPRI default */ + tmpReg |= + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal; + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + /* write the table pointer into the Manip descriptor */ + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + tmpReg = 0; + ASSERT_COND(p_TmpData); + for (i = 0; i < HMCD_DSCP_VALUES; i++) + { + /* first we build from each 8 values a 32bit register */ + tmpReg |= + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]) + << (32 - 4 * (j + 1)); + j++; + /* Than we write this register to the next table word + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */ + if ((i % 8) == 7) + { + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1), + tmpReg); + tmpReg = 0; + j = 0; + } + } + + WRITE_UINT32( + *p_TmpHmct, + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); + p_TmpHmct += HMCD_PTR_SIZE / 4; + + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE; + } + else + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) + { + /* set Mode */ + /* line commented out as it has no-side-effect ('0' value). */ + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/; + /* set VPRI parameter */ + tmpReg |= + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri; + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + p_TmpHmct += HMCD_BASIC_SIZE / 4; + } + break; + + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_TTL) + tmpReg |= HMCD_IPV4_UPDATE_TTL; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_TOS) + { + tmpReg |= HMCD_IPV4_UPDATE_TOS; + tmpReg |= + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos + << HMCD_IPV4_UPDATE_TOS_SHIFT; + } + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_ID) + tmpReg |= HMCD_IPV4_UPDATE_ID; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_SRC) + tmpReg |= HMCD_IPV4_UPDATE_SRC; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_DST) + tmpReg |= HMCD_IPV4_UPDATE_DST; + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_ID) + { + ASSERT_COND(p_TmpData); + WRITE_UINT16( + *(uint16_t*)p_TmpData, + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id); + WRITE_UINT32( + *p_TmpHmct, + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); + p_TmpData += 2; + p_TmpHmct += HMCD_PTR_SIZE / 4; + } + + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_SRC) + { + WRITE_UINT32( + *p_TmpHmct, + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src); + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; + } + + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates + & HDR_MANIP_IPV4_DST) + { + WRITE_UINT32( + *p_TmpHmct, + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst); + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; + } + break; + + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_HL) + tmpReg |= HMCD_IPV6_UPDATE_HL; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_TC) + { + tmpReg |= HMCD_IPV6_UPDATE_TC; + tmpReg |= + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass + << HMCD_IPV6_UPDATE_TC_SHIFT; + } + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_SRC) + tmpReg |= HMCD_IPV6_UPDATE_SRC; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_DST) + tmpReg |= HMCD_IPV6_UPDATE_DST; + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_SRC) + { + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) + { + memcpy(&tmp_ipv6_addr, + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i], + sizeof(uint32_t)); + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); + p_TmpHmct += HMCD_PTR_SIZE / 4; + } + } + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates + & HDR_MANIP_IPV6_DST) + { + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) + { + memcpy(&tmp_ipv6_addr, + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i], + sizeof(uint32_t)); + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); + p_TmpHmct += HMCD_PTR_SIZE / 4; + } + } + break; + + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + == HDR_MANIP_TCP_UDP_CHECKSUM) + { + /* we implement this case with the update-checksum descriptor */ + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM) + << HMCD_OC_SHIFT; + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + } + else + { + /* we implement this case with the TCP/UDP update descriptor */ + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE) + << HMCD_OC_SHIFT; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + & HDR_MANIP_TCP_UDP_DST) + tmpReg |= HMCD_TCP_UDP_UPDATE_DST; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + & HDR_MANIP_TCP_UDP_SRC) + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC; + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + tmpReg = 0; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + & HDR_MANIP_TCP_UDP_SRC) + tmpReg |= + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src) + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT; + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates + & HDR_MANIP_TCP_UDP_DST) + tmpReg |= + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst); + WRITE_UINT32(*p_TmpHmct, tmpReg); + p_TmpHmct += HMCD_PTR_SIZE / 4; + } + break; + + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown fieldUpdateParams.type")); + } + } + + if (p_FmPcdManipParams->u.hdr.custom) + { + switch (p_FmPcdManipParams->u.hdr.customParams.type) + { + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT; + + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl) + tmpReg |= HMCD_IP_REPLACE_TTL_HL; + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6) + /* line commented out as it has no-side-effect ('0' value). */ + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/; + else + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) + { + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6; + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id) + tmpReg |= HMCD_IP_REPLACE_ID; + } + else + RETURN_ERROR( + MINOR, + E_NOT_SUPPORTED, + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set.")); + + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE / 4; + + size = + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; + ASSERT_COND(p_TmpData); + MemCpy8( + p_TmpData, + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr, + size); + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT); + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData) + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); + WRITE_UINT32(*p_TmpHmct, tmpReg); + p_TmpHmct += HMCD_PTR_SIZE / 4; + p_TmpData += size; + + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) + { + WRITE_UINT16( + *(uint16_t*)p_TmpData, + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id); + WRITE_UINT32( + *p_TmpHmct, + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); + p_TmpData += 2; + } + p_TmpHmct += HMCD_PTR_SIZE / 4; + break; + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): + /* set opcode */ + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT; + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) + tmpReg |= HMCD_GEN_FIELD_MASK_EN; + + /* write the first 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + /* save a pointer to the "last" indication word */ + p_Last = p_TmpHmct; + + p_TmpHmct += HMCD_BASIC_SIZE/4; + + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) + { + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT; + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT; + /* write the next 4 bytes of the descriptor */ + WRITE_UINT32(*p_TmpHmct, tmpReg); + } + p_TmpHmct += HMCD_PARAM_SIZE/4; + break; + default: + RETURN_ERROR(MINOR, E_INVALID_SELECTION, + ("Unknown customParams.type")); + } + } + + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table + the old table and should be freed */ + if (p_FmPcdManipParams->h_NextManip + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) + && (MANIP_DONT_REPARSE(p_Manip))) + { + if (new) + { + /* If this is the first time this manip is created we need to free unused memory. If it + * is a dynamic changes case, the memory used is either the CC shadow or the existing + * table - no allocation, no free */ + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip); + + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST; + } + } + else + { + ASSERT_COND(p_Last); + /* set the "last" indication on the last command of the current table */ + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST); + } + + return E_OK; +} + +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip, + t_FmPcdManipParams *p_FmPcdManipParams) +{ + t_FmPcdManip *p_CurManip; + t_Error err; + uint32_t nextSize = 0, totalSize; + uint16_t tmpReg; + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr; + + /* set Manip structure */ + + p_Manip->dontParseAfterManip = + p_FmPcdManipParams->u.hdr.dontParseAfterManip; + + if (p_FmPcdManipParams->h_NextManip) + { /* Next Header manipulation exists */ + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip); + + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip) + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip) + + GetDataSize(p_FmPcdManipParams->h_NextManip)); + else /* either parsing is required or next manip is Frag; no table merging. */ + p_Manip->cascaded = TRUE; + /* pass up the "cascaded" attribute. The whole chain is cascaded + * if something is cascaded along the way. */ + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip)) + p_Manip->cascaded = TRUE; + } + + /* Allocate new table */ + /* calculate table size according to manip parameters */ + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize, + &p_Manip->dataSize); + if (err) + RETURN_ERROR(MINOR, err, NO_MSG); + + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize); + + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem( + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4); + if (!p_Manip->p_Hmct) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed")); + + if (p_Manip->dataSize) + p_Manip->p_Data = + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize)); + + /* update shadow size to allow runtime replacement of Header manipulation */ + /* The allocated shadow is divided as follows: + 0 . . . 16 . . . + -------------------------------- + | Shadow | Shadow HMTD | + | HMTD | Match Table | + | (16 bytes) | (maximal size) | + -------------------------------- + */ + + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16), + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN); + if (err != E_OK) + { + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM allocation for HdrManip node shadow")); + } + + if (p_FmPcdManipParams->h_NextManip + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) + && (MANIP_DONT_REPARSE(p_Manip))) + { + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip, + e_MANIP_HMCT); + p_CurManip = p_FmPcdManipParams->h_NextManip; + /* Run till the last Manip (which is the first to configure) */ + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) + p_CurManip = p_CurManip->h_NextManip; + + while (p_CurManip) + { + /* If this is a unified table, point to the part of the table + * which is the relative offset in HMCT. + */ + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, + (p_Manip->tableSize + + (PTR_TO_UINT(p_CurManip->p_Hmct) - + PTR_TO_UINT(p_OldHmct)))); + if (p_CurManip->p_Data) + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, + (p_Manip->tableSize + + (PTR_TO_UINT(p_CurManip->p_Data) - + PTR_TO_UINT(p_OldHmct)))); + else + p_TmpDataPtr = NULL; + + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, + p_TmpDataPtr, FALSE); + /* update old manip table pointer */ + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr); + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr); + + p_CurManip = p_CurManip->h_PrevManip; + } + /* We copied the HMCT to create a new large HMCT so we can free the old one */ + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip), + p_OldHmct); + } + + /* Fill table */ + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, + p_Manip->p_Data, TRUE); + if (err) + { + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); + RETURN_ERROR(MINOR, err, NO_MSG); + } + + /* Build HMTD (table descriptor) */ + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */ + + /* add parseAfterManip */ + if (!p_Manip->dontParseAfterManip) + tmpReg |= HMTD_CFG_PRS_AFTER_HM; + + /* create cascade */ + /*if (p_FmPcdManipParams->h_NextManip + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/ + if (p_Manip->cascaded) + { + uint16_t nextAd; + /* indicate that there's another HM table descriptor */ + tmpReg |= HMTD_CFG_NEXT_AD_EN; + /* get address of next HMTD (table descriptor; h_Ad). + * If the next HMTD was removed due to table unifing, get the address + * of the "next next" as written in the h_Ad of the next h_Manip node. + */ + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST) + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); + else + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx; + + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd); + } + + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg); + WRITE_UINT32( + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr, + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); + + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC); + + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST) + { + /* The HMTD of the next Manip is never going to be used */ + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate) + FM_MURAM_FreeMem( + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram, + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); + else + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL; + } + + return E_OK; +} + +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip, + t_FmPcdManipParams *p_FmPcdManipParams) +{ + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL; + uint16_t newSize; + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + t_Error err; + t_FmPcdManip *p_CurManip = p_Manip; + + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize); + if (err) + RETURN_ERROR(MINOR, err, NO_MSG); + + /* check coherency of new table parameters */ + if (newSize > p_Manip->tableSize) + RETURN_ERROR( + MINOR, + E_INVALID_VALUE, + ("New Hdr Manip configuration requires larger size than current one (command table).")); + if (newDataSize > p_Manip->dataSize) + RETURN_ERROR( + MINOR, + E_INVALID_VALUE, + ("New Hdr Manip configuration requires larger size than current one (data).")); + if (p_FmPcdManipParams->h_NextManip) + RETURN_ERROR( + MINOR, E_INVALID_VALUE, + ("New Hdr Manip configuration can not contain h_NextManip.")); + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize)) + RETURN_ERROR( + MINOR, + E_INVALID_VALUE, + ("New Hdr Manip configuration in a chained manipulation requires different size than current one.")); + if (p_Manip->dontParseAfterManip + != p_FmPcdManipParams->u.hdr.dontParseAfterManip) + RETURN_ERROR( + MINOR, + E_INVALID_VALUE, + ("New Hdr Manip configuration differs in dontParseAfterManip value.")); + + p_Manip->tableSize = newSize; + p_Manip->dataSize = newDataSize; + + /* Build the new table in the shadow */ + if (!MANIP_IS_UNIFIED(p_Manip)) + { + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); + if (p_Manip->p_Data) + p_TmpDataPtr = + (uint8_t*)PTR_MOVE(p_TmpHmctPtr, + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct))); + + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data, + FALSE); + } + else + { + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); + ASSERT_COND(p_WholeHmct); + + /* Run till the last Manip (which is the first to configure) */ + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) + p_CurManip = p_CurManip->h_NextManip; + + while (p_CurManip) + { + /* If this is a non-head node in a unified table, point to the part of the shadow + * which is the relative offset in HMCT. + * else, point to the beginning of the + * shadow table (we save 16 for the HMTD. + */ + p_TmpHmctPtr = + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct))); + if (p_CurManip->p_Data) + p_TmpDataPtr = + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct))); + + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, + p_TmpDataPtr, FALSE); + p_CurManip = p_CurManip->h_PrevManip; + } + } + + return E_OK; +} + +static t_Error CreateManipActionBackToOrig( + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams) +{ + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr; + t_FmPcdManip *p_CurManip = p_Manip; + + /* Build the new table in the shadow */ + if (!MANIP_IS_UNIFIED(p_Manip)) + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data, + FALSE); + else + { + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); + ASSERT_COND(p_WholeHmct); + + /* Run till the last Manip (which is the first to configure) */ + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) + p_CurManip = p_CurManip->h_NextManip; + + while (p_CurManip) + { + /* If this is a unified table, point to the part of the table + * which is the relative offset in HMCT. + */ + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/ + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/ + + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, + p_TmpDataPtr, FALSE); + + p_CurManip = p_CurManip->h_PrevManip; + } + } + + return E_OK; +} + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset) { t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; - t_Handle p_Ad; - uint32_t tmpReg32 = 0; - SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE); + t_Handle p_Ad; + uint32_t tmpReg32 = 0; + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); - switch(p_Manip->type) + switch (p_Manip->opcode) { - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) + { + tmpReg32 = + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets; + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = + tmpReg32; + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; + p_Manip->icOffset = icOffset; + } + else + { + if (p_Manip->icOffset != icOffset) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("this manipulation was updated previously by different value");); + } + break; + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + if (p_Manip->h_Frag) + { + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) { - tmpReg32 = *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets; - tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); - *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = tmpReg32; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets); + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32); p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; p_Manip->icOffset = icOffset; } else { - if(p_Manip->icOffset != icOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value");); + if (p_Manip->icOffset != icOffset) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value");); } - break; -#ifdef FM_CAPWAP_SUPPORT - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - if(p_Manip->h_Frag) - { - if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) - { - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets); - tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32); - p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; - p_Manip->icOffset = icOffset; - } - else - { - if(p_Manip->icOffset != icOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value");); - } - } - break; -#endif /* FM_CAPWAP_SUPPORT */ + } + break; } return E_OK; } -static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate) +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix( + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate) { - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; - t_FmPortGetSetCcParams fmPortGetSetCcParams; - t_Error err; - uint32_t tmpReg32; + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + t_Error err; + uint32_t tmpReg32; memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((p_Manip->type & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR( + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), + E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE); - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if((!(p_Manip->updateParams & OFFSET_OF_PR)) || - (p_Manip->shadowUpdateParams & OFFSET_OF_PR)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); + if ((!(p_Manip->updateParams & OFFSET_OF_PR)) + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("in this stage parameters from Port has not be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; fmPortGetSetCcParams.setCcParams.psoSize = 16; err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely")); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("Parser result offset wasn't configured previousely")); #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16)); #endif } - else if (validate) + else + if (validate) { - if((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) || - (p_Manip->updateParams & OFFSET_OF_PR)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) + || (p_Manip->updateParams & OFFSET_OF_PR)) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("in this stage parameters from Port has be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; fmPortGetSetCcParams.setCcParams.psoSize = 16; err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely")); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("Parser result offset wasn't configured previousely")); } - if(p_Manip->updateParams & OFFSET_OF_PR) - { + ASSERT_COND(p_Ad); + + if (p_Manip->updateParams & OFFSET_OF_PR) + { tmpReg32 = 0; tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset; - WRITE_UINT32(p_Ad->matchTblPtr, (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32)); + WRITE_UINT32(p_Ad->matchTblPtr, + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32)); p_Manip->updateParams &= ~OFFSET_OF_PR; p_Manip->shadowUpdateParams |= OFFSET_OF_PR; - } - else if (validate) - { + } + else + if (validate) + { tmpReg32 = GET_UINT32(p_Ad->matchTblPtr); - if((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value");); - } + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("this manipulation was updated previousely by different value");); + } return E_OK; } -#ifdef FM_CAPWAP_SUPPORT static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree) { - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; - t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL; - uint32_t tmpReg32 = 0; + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL; + uint32_t tmpReg32 = 0; SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if((!(p_Manip->updateParams & OFFSET_OF_DATA) && - !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) || - ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); - p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX); - if(!p_SavedManipParams) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); - p_Manip->fragParams.poolId = p_SavedManipParams->capwapParams.poolId; - p_Manip->fragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset; + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); + if (!p_SavedManipParams) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset; tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); - tmpReg32 |= ((uint32_t)p_Manip->fragParams.poolId << 8); - tmpReg32 |= ((uint32_t)p_Manip->fragParams.dataOffset<< 16); + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16); WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); p_Manip->updateParams &= ~OFFSET_OF_DATA; - p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP; - p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP); + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; } - else if (validate) - { + else if (validate) + { - p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX); - if(!p_SavedManipParams) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); - if((p_Manip->fragParams.poolId != p_SavedManipParams->capwapParams.poolId) || - (p_Manip->fragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); - } + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); + if (!p_SavedManipParams) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); + } return E_OK; } -static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate, t_Handle h_FmTree) +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, + t_FmPcdManip *p_Manip, + t_Handle h_Ad, + bool validate, + t_Handle h_FmTree) { - t_AdOfTypeContLookup *p_Ad; - t_FmPortGetSetCcParams fmPortGetSetCcParams; - t_Error err; - uint32_t tmpReg32 = 0; - t_FmPcdCcSavedManipParams *p_SavedManipParams; + t_AdOfTypeContLookup *p_Ad; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + t_Error err; + uint32_t tmpReg32 = 0; + t_FmPcdCcSavedManipParams *p_SavedManipParams; UNUSED(h_Ad); SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if((!(p_Manip->updateParams & OFFSET_OF_DATA) && - !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) || - ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; - err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */ + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1; - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely")); + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams)); p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; - p_SavedManipParams->capwapParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip; #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16)); -#endif +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ - FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams, e_FM_MANIP_CAPWAP_INDX); + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams); } else if (validate) { - if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && - !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) || - ((p_Manip->updateParams & OFFSET_OF_DATA) || - (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) || + ((p_Manip->updateParams & OFFSET_OF_DATA))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely")); + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); } - if(p_Manip->updateParams) + if (p_Manip->updateParams) { tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); - tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.poolIdForManip << 8); tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16); WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); p_Manip->updateParams &= ~OFFSET_OF_DATA; - p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP; - p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP); - p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip; - p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; } else if (validate) { - if((p_Manip->fragParams.poolId != fmPortGetSetCcParams.getCcParams.poolIdForManip) || - (p_Manip->fragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); } return E_OK; } -static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd, - t_Handle h_FmPort, - t_FmPcdManip *p_Manip, - t_Handle h_Ad, - bool validate) +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd, + t_Handle h_FmPort, + t_FmPcdManip *p_Manip, + t_Handle h_Ad, + bool validate) { - t_CapwapReasmPram *p_ReassmTbl; - t_Error err; - t_FmPortGetSetCcParams fmPortGetSetCcParams; - uint8_t i = 0; - uint16_t size; - uint32_t tmpReg32; - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_CapwapReasmPram *p_ReassmTbl; + t_Error err; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + uint8_t i = 0; + uint16_t size; + uint32_t tmpReg32; + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams; SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); - if(p_Manip->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value")); + if (p_Manip->h_FmPcd != h_FmPcd) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("handler of PCD previously was initiated by different value")); UNUSED(h_Ad); memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); - p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag; + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag; - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if((!(p_Manip->updateParams & NUM_OF_TASKS) && !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) && - !(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) && - !(p_Manip->updateParams & HW_PORT_ID)) || - ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) || - (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) - ||(p_Manip->shadowUpdateParams & HW_PORT_ID))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); + if ((!(p_Manip->updateParams & NUM_OF_TASKS) && + !(p_Manip->updateParams & OFFSET_OF_DATA) && + !(p_Manip->updateParams & OFFSET_OF_PR) && + !(p_Manip->updateParams & HW_PORT_ID)) || + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) || + (p_Manip->shadowUpdateParams & HW_PORT_ID))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("buffser pool id wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely")); + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0); -#endif +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ } else if (validate) { - if((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && (!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) && - (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) && - (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) && - ((p_Manip->updateParams & NUM_OF_TASKS) || - (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) || - (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)|| - (p_Manip->updateParams & HW_PORT_ID))) + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) && + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) && + ((p_Manip->updateParams & NUM_OF_TASKS) || + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) || + (p_Manip->updateParams & HW_PORT_ID))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool for header manipulation wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously")); + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously")); + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); } - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if(p_Manip->updateParams & NUM_OF_TASKS) + if (p_Manip->updateParams & NUM_OF_TASKS) { - size = (uint16_t)(p_Manip->fragParams.maxNumFramesInProcess + fmPortGetSetCcParams.getCcParams.numOfTasks); - if(size > 255) - RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256")); + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */ + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks); + if (size > 255) + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256")); - p_Manip->fragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks; + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks; /*p_ReassmFrmDescrIndxPoolTbl*/ - p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)(size + 1), - 4); - if(!p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl = + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)(size + 1), + 4); + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table")); - IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1)); + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1)); - for( i = 0; i < size; i++) - WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); + for ( i = 0; i < size; i++) + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32); /*p_ReassmFrmDescrPoolTbl*/ - p_Manip->fragParams.p_ReassmFrmDescrPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE), - 4); + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl = + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE), + 4); - if(!p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table")); - IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE)); + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE)); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase); + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase); WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32); /*p_TimeOutTbl*/ - p_Manip->fragParams.p_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE), - 4); + p_Manip->capwapFragParams.p_TimeOutTbl = + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE), + 4); - if(!p_Manip->fragParams.p_TimeOutTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + if (!p_Manip->capwapFragParams.p_TimeOutTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table")); - IOMemSet32(p_Manip->fragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE)); + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE)); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase); + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase); WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32); - p_Manip->updateParams &= ~NUM_OF_TASKS; p_Manip->shadowUpdateParams |= NUM_OF_TASKS; - } + } - if(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) - { - - p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip; - - tmpReg32 = GET_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes); - tmpReg32 |= (uint32_t)p_Manip->fragParams.poolId << 16; - WRITE_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes, tmpReg32); - - p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP; - p_Manip->shadowUpdateParams |= BUFFER_POOL_ID_FOR_MANIP; - } - - if(p_Manip->updateParams & OFFSET_OF_DATA) + if (p_Manip->updateParams & OFFSET_OF_DATA) { - p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; tmpReg32 = GET_UINT32(p_ReassmTbl->mode); - tmpReg32|= p_Manip->fragParams.dataOffset; + tmpReg32|= p_Manip->capwapFragParams.dataOffset; WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); p_Manip->updateParams &= ~OFFSET_OF_DATA; p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; } - if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) + + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) { - p_Manip->fragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset; + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset; tmpReg32 = GET_UINT32(p_ReassmTbl->mode); tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY; WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr); - tmpReg32 |= (uint32_t)p_Manip->fragParams.prOffset << 24; + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24; WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32); - p_Manip->updateParams &= ~OFFSET_OF_PR; - p_Manip->shadowUpdateParams |= OFFSET_OF_PR; - } - else - { - p_Manip->fragParams.prOffset = 0xff; - p_Manip->updateParams &= ~OFFSET_OF_PR; - p_Manip->shadowUpdateParams |= OFFSET_OF_PR; + p_Manip->updateParams &= ~OFFSET_OF_PR; + p_Manip->shadowUpdateParams |= OFFSET_OF_PR; + } + else + { + p_Manip->capwapFragParams.prOffset = 0xff; + p_Manip->updateParams &= ~OFFSET_OF_PR; + p_Manip->shadowUpdateParams |= OFFSET_OF_PR; + } - } - - p_Manip->fragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId; + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId; p_Manip->updateParams &= ~HW_PORT_ID; p_Manip->shadowUpdateParams |= HW_PORT_ID; /*timeout hc */ - ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->fragParams.fqidForTimeOutFrames; - ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->fragParams.hwPortId << 24; - ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase)); - ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<fragParams.bitFor1Micro) * p_Manip->fragParams.timeoutRoutineRequestTime)/2; - return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams); - + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames; + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24; + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase)); + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2; + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams); } - else if(validate) + + else if (validate) { - if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); - if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value ")); + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value ")); - if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value ")); - - if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) { - if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); } else { - if(p_Manip->fragParams.prOffset != 0xff) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); + if (p_Manip->capwapFragParams.prOffset != 0xff) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); } - if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value ")); + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value ")); } return E_OK; } -#endif /* FM_CAPWAP_SUPPORT */ +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) -static t_Error UpdateInitIPSec(t_Handle h_FmPort, t_FmPcdManip *p_Manip) +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) { - SANITY_CHECK_RETURN_ERROR(h_FmPort,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IPSEC, E_INVALID_STATE); + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 }; + t_Error err = E_OK; + uint8_t result; + uint32_t bitFor1Micro, tsbs, log2num; - /* - if(p_Manip->cnia) - { - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + ASSERT_COND(p_FmPcd); + ASSERT_COND(h_ReasmCommonPramTbl); - WRITE_UINT32(p_Ad->ccAdBase, GET_UINT32(p_Ad->ccAdBase) | FM_PCD_MANIP_IPSEC_CNIA); - } -*/ - return E_OK; -} -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/ + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); + if (bitFor1Micro == 0) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY -static t_Error UpdateInitIpFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip) -{ - t_FmPortGetSetCcParams fmPortGetSetCcParams; - t_Error err; - uint32_t tmpReg32 = 0; + bitFor1Micro = 32 - bitFor1Micro; + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num); + tsbs = bitFor1Micro - log2num; - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IP_FRAGMENTATION, E_INVALID_STATE); - - fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; - err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys( + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs; + ccReassmTimeoutParams.activate = TRUE; + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, + &result)) != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); + switch (result) + { + case (0): + return E_OK; + case (1): + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM")); + case (2): + RETURN_ERROR( + MAJOR, E_NO_MEMORY, + ("failed to allocate internal buffer from the HC-Port")); + case (3): + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("'Disable Timeout Task' with invalid IPRCPT")); + case (4): + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks")); + case (5): + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command")); + default: + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); + } return E_OK; } -static t_Error CreateIpReassCommonParamTable(t_FmPcdManip *p_Manip, - t_FmPcd *p_FmPcd , - t_IpReasmCommonTbl *p_IpReasmCommonPramTbl) +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip) { - uint32_t tmpReg32 = 0, i; - uint64_t tmpReg64, size; + uint32_t tmpReg32 = 0, i, bitFor1Micro; + uint64_t tmpReg64, size; + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + t_Error err = E_OK; - p_Manip->ipReassmParams.h_IpReassCommonParamsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE, - FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN); + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); + if (bitFor1Micro == 0) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); - if(!p_Manip->ipReassmParams.h_IpReassCommonParamsTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + /* Allocation of the Reassembly Common Parameters table. This table is located in the + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */ + p_Manip->reassmParams.p_ReassCommonTbl = + (t_ReassCommonTbl *)FM_MURAM_AllocMem( + p_FmPcd->h_FmMuram, + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE, + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN); - p_IpReasmCommonPramTbl = (t_IpReasmCommonTbl *)(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl); + if (!p_Manip->reassmParams.p_ReassCommonTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM alloc for Reassembly common parameters table")); - IOMemSet32(p_IpReasmCommonPramTbl, 0, FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE); + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0, + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE); + /* Setting the TimeOut Mode.*/ tmpReg32 = 0; - if(p_Manip->ipReassmParams.timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) - tmpReg32 |= FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES; + if (p_Manip->reassmParams.timeOutMode + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES; - tmpReg32 |= p_Manip->ipReassmParams.fqidForTimeOutFrames; - WRITE_UINT32(p_IpReasmCommonPramTbl->timeoutModeAndFqid, tmpReg32); + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID. + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/ + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames; + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid, + tmpReg32); + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/ + size = p_Manip->reassmParams.maxNumFramesInProcess + 129; - size = p_Manip->ipReassmParams.maxNumFramesInProcess + 129; + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */ + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr = + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)(size * 2), + 256)); + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) + RETURN_ERROR( + MAJOR, E_NO_MEMORY, + ("MURAM alloc for Reassembly frame descriptor indexes pool")); - /*p_ReassmFrmDescrIndxPoolTbl */ - p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)(size * 2), - 256); - if(!p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), + 0, (uint32_t)(size * 2)); - IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size * 2)); + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to + the maximum number of frames that are allowed to be reassembled simultaneously + 128. + The last entry in this pool must contain the index zero*/ + for (i = 0; i < (size - 1); i++) + WRITE_UINT16( + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)), + (uint16_t)(i+1)); - for( i = 0; i < size - 1; i++) - WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */ + tmpReg32 = (uint32_t)(XX_VirtToPhys( + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)) + - p_FmPcd->physicalMuramBase); + WRITE_UINT32( + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr, + tmpReg32); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory. + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/ + p_Manip->reassmParams.reassFrmDescrPoolTblAddr = + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64)); - WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescIndexPoolTblPtr, tmpReg32); - - /*p_ReassmFrmDescrPoolTbl*/ - p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl = (t_Handle)XX_MallocSmart((uint32_t)(size * 32), p_Manip->ipReassmParams.dataMemId, 32); - - if(!p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl) + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); - IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl, 0, (uint32_t)(size * 32)); + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0, + (uint32_t)(size * 64)); - tmpReg64 = (uint64_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl)); - tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); - tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); - WRITE_UINT32(p_IpReasmCommonPramTbl->liodnAndReassFrmDescPoolPtrHi, (uint32_t)(tmpReg64 >> 32)); - WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescPoolPtrLow, (uint32_t)tmpReg64); + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/ + tmpReg64 = (uint64_t)(XX_VirtToPhys( + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr))); + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_LIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_ELIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); + WRITE_UINT32( + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi, + (uint32_t)(tmpReg64 >> 32)); + WRITE_UINT32( + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow, + (uint32_t)tmpReg64); - /*p_TimeOutTbl*/ - p_Manip->ipReassmParams.h_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)(size * 8),8); + /*Allocation of the TimeOut table - This table resides in the MURAM. + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/ + p_Manip->reassmParams.timeOutTblAddr = + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8)); - if(!p_Manip->ipReassmParams.h_TimeOutTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + if (!p_Manip->reassmParams.timeOutTblAddr) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM alloc for Reassembly timeout table")); - IOMemSet32(p_Manip->ipReassmParams.h_TimeOutTbl, 0, (uint16_t)(size * 8)); + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0, + (uint16_t)(size * 8)); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_TimeOutTbl) - p_FmPcd->physicalMuramBase); - WRITE_UINT32(p_IpReasmCommonPramTbl->timeOutTblPtr, tmpReg32); + /* Sets the TimeOut table offset from MURAM */ + tmpReg32 = (uint32_t)(XX_VirtToPhys( + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)) + - p_FmPcd->physicalMuramBase); + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr, + tmpReg32); - /* Expiration Delay */ + /* Sets the Expiration Delay */ tmpReg32 = 0; - tmpReg32 |= p_Manip->ipReassmParams.timeoutThresholdForReassmProcess; - WRITE_UINT32(p_IpReasmCommonPramTbl->expirationDelay, tmpReg32); + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro)) + * p_Manip->reassmParams.timeoutThresholdForReassmProcess); + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay, + tmpReg32); - /* Counts the number of TimeOut occurrences - Must be initialized to zero.*/ - WRITE_UINT32(p_IpReasmCommonPramTbl->totalTimeOutCounter, 0); - /* Counts the number of failed attempts to allocate a Reassembly Frame Descriptor - Must be initialized to zero.*/ - WRITE_UINT32(p_IpReasmCommonPramTbl->totalRfdPoolBusyCounter, 0); - /* Counts the number of times an internal buffer busy occured.*/ - WRITE_UINT32(p_IpReasmCommonPramTbl->totalInternalBufferBusy, 0); - /* Counts the number of times external buffer busy occured. */ - WRITE_UINT32(p_IpReasmCommonPramTbl->totalExternalBufferBusy, 0); + err = FmPcdRegisterReassmPort(p_FmPcd, + p_Manip->reassmParams.p_ReassCommonTbl); + if (err != E_OK) + { + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->reassmParams.p_ReassCommonTbl); + RETURN_ERROR(MAJOR, err, ("port registration")); + } - return E_OK; + return err; } -static t_Error CreateIpReassParamTable(t_FmPcdManip *p_Manip, t_Handle h_IpReassParamsTblPtr, bool ipv4) +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) { - t_IpReasmPram *p_Table; - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - t_FmPcd *p_FmPcd = p_Manip->h_FmPcd; - uint32_t tmpReg32, autoLearnHashTblSize; - uint32_t numOfWays, setSize, setSizeCode, tmpSetSize; - uint32_t waySize, numOfSets, tmpNumOfSets, numOfEntries; - uint64_t tmpReg64; - t_Handle h_AutoLearnHashTbl, h_AutoLearnSetLockTblPtr; + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd; + uint32_t tmpReg32, autoLearnHashTblSize; + uint32_t numOfWays, setSize, setSizeCode, keySize; + uint32_t waySize, numOfSets, numOfEntries; + uint64_t tmpReg64; + uint16_t minFragSize; + uint16_t maxReassemSize; + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr; + t_ReassTbl **p_ReassTbl; - /*Pointer to fragment ID*/ - h_IpReassParamsTblPtr = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_MANIP_IP_REASM_TABLE_SIZE, - FM_PCD_MANIP_IP_REASM_TABLE_ALIGN); + switch (hdr) + { + case HEADER_TYPE_IPv4: + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl; + p_AutoLearnHashTblAddr = + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr; + p_AutoLearnSetLockTblAddr = + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr; + minFragSize = p_Manip->reassmParams.ip.minFragSize[0]; + maxReassemSize = 0; + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0]; + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */ + break; + case HEADER_TYPE_IPv6: + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl; + p_AutoLearnHashTblAddr = + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr; + p_AutoLearnSetLockTblAddr = + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr; + minFragSize = p_Manip->reassmParams.ip.minFragSize[1]; + maxReassemSize = 0; + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1]; + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */ + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways")); + break; + case HEADER_TYPE_CAPWAP: + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl; + p_AutoLearnHashTblAddr = + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr; + p_AutoLearnSetLockTblAddr = + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr; + minFragSize = 0; + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize; + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry; + keySize = 4; + break; + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); + } + keySize += 2; /* 2 bytes reserved for RFDIndex */ +#if (DPAA_VERSION >= 11) + keySize += 2; /* 2 bytes reserved */ +#endif /* (DPAA_VERSION >= 11) */ + waySize = ROUND_UP(keySize, 8); - if(!h_IpReassParamsTblPtr) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/ + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem( + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE, + FM_PCD_MANIP_REASM_TABLE_ALIGN); + if (!*p_ReassTbl) + RETURN_ERROR( MAJOR, E_NO_MEMORY, + ("MURAM alloc for Reassembly specific parameters table")); + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl)); - IOMemSet32(h_IpReassParamsTblPtr, 0, FM_PCD_MANIP_IP_REASM_TABLE_SIZE); + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/ + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl) + - p_FmPcd->physicalMuramBase); + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32); - p_Table = (t_IpReasmPram *)h_IpReassParamsTblPtr; + /* Calculate set size (set size is rounded-up to next power of 2) */ + NEXT_POWER_OF_2(numOfWays * waySize, setSize); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl) - p_FmPcd->physicalMuramBase); - WRITE_UINT32(((t_IpReasmPram *)h_IpReassParamsTblPtr)->ipReassCommonPrmTblPtr, tmpReg32); + /* Get set size code */ + LOG2(setSize, setSizeCode); - /* waysNumAndSetSize calculation */ - numOfWays = p_Manip->ipReassmParams.numOfFramesPerHashEntry; + /* Sets ways number and set size code */ + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize, + (uint16_t)((numOfWays << 8) | setSizeCode)); - /*It is recommended that the total number of entries in this table - (number of sets * number of ways) will be twice the number of frames that + /* It is recommended that the total number of entries in this table + (number of sets * number of ways) will be twice the number of frames that are expected to be reassembled simultaneously.*/ - numOfEntries = (uint32_t)(p_Manip->ipReassmParams.maxNumFramesInProcess * 2); + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2); /* sets number calculation - number of entries = number of sets * number of ways */ numOfSets = numOfEntries / numOfWays; - /*TODO - Handle way size*/ - switch(p_Manip->ipReassmParams.hdr) - { - case(HEADER_TYPE_IPv6): - /* WaySize is rounded-up to next multiple of 8 */ - waySize = ROUND_UP(((16 + 16 + 4 + 2) /* * numOfWays*/),8); - break; - case(HEADER_TYPE_IPv4): - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly")); - } - /* Set size is rounded-up to next power of 2 */ - LOG2(numOfWays * waySize, tmpSetSize); - setSize = (uint32_t)(1 << (tmpSetSize + (POWER_OF_2(numOfWays * waySize) ? 0 : 1))); + /* Sets AutoLearnHashKeyMask*/ + NEXT_POWER_OF_2(numOfSets, numOfSets); - LOG2(setSize, setSizeCode); - WRITE_UINT16(((t_IpReasmPram *)p_Table)->waysNumAndSetSize, (uint16_t)((numOfWays << 8) | setSizeCode)); + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask, + (uint16_t)(numOfSets - 1)); - LOG2(numOfSets, tmpNumOfSets); - numOfSets = (uint32_t)(1 << (tmpNumOfSets + (POWER_OF_2(numOfSets) ? 0 : 1))); - - WRITE_UINT16(((t_IpReasmPram *)p_Table)->autoLearnHashKeyMask, (uint16_t)(numOfSets - 1)); - - /*autoLearnHashTbl allocation - Table size = set size * number of sets - This table’s base address should be aligned to SetSize.*/ + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory. + The size of this table is determined by the number of sets and the set size. + Table size = set size * number of sets + This table base address should be aligned to SetSize.*/ autoLearnHashTblSize = numOfSets * setSize; - if (ipv4) - h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl; - else - h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl; - - h_AutoLearnHashTbl = (t_Handle)XX_MallocSmart(autoLearnHashTblSize, p_Manip->ipReassmParams.dataMemId, setSizeCode); - - if(!h_AutoLearnHashTbl) + *p_AutoLearnHashTblAddr = + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize)); + if (!*p_AutoLearnHashTblAddr) + { + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); + *p_ReassTbl = NULL; RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); + } + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize); - IOMemSet32(h_AutoLearnHashTbl, 0, autoLearnHashTblSize); + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */ + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_LIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_ELIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi, + (uint32_t)(tmpReg64 >> 32)); + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64); - tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); - tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); - tmpReg64 |= XX_VirtToPhys(h_AutoLearnHashTbl); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnAlAndAutoLearnHashTblPtrHi, (uint32_t)(tmpReg64 >> 32)); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64); - - /* AutoLearnSetLockTbl allocation - The size of this table is (number of sets in the IP - Reassembly Automatic Learning Hash table)*4 bytes. This table resides in external memory - and its base address should be 4-byte aligned */ - if (ipv4) - h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr; - else - h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr; - - h_AutoLearnSetLockTblPtr = (t_Handle)XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->ipReassmParams.dataMemId, 4); - - if(!h_AutoLearnSetLockTblPtr) + /* Allocation of the Set Lock table - This table resides in external memory + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes. + This table resides in external memory and its base address should be 4-byte aligned */ + *p_AutoLearnSetLockTblAddr = + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4)); + if (!*p_AutoLearnSetLockTblAddr) + { + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); + *p_ReassTbl = NULL; + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); + *p_AutoLearnHashTblAddr = 0; RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); + } + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4)); - IOMemSet32(h_AutoLearnSetLockTblPtr, 0, (numOfSets * 4)); + /* sets Set Lock table pointer and liodn offset*/ + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_LIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset + & FM_PCD_MANIP_REASM_ELIODN_MASK) + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr)); + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi, + (uint32_t)(tmpReg64 >> 32)); + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64); - tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT); - tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT); - tmpReg64 |= XX_VirtToPhys(h_AutoLearnSetLockTblPtr); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnSlAndAutoLearnSetLockTblPtrHi, (uint32_t)(tmpReg64 >> 32)); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64); + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */ + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize); - /* Setting the First/Middle fragment minimum size in Bytes */ - WRITE_UINT32(((t_IpReasmPram *)p_Table)->minFragSize, p_Manip->ipReassmParams.minFragSize); - - /* Zeroes all counters */ - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSuccessfullyReasmFramesCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalValidFragmentCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalProcessedFragCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMalformdFragCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSetBusyCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalDiscardedFragsCounter, 0); - WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMoreThan16FramesCounter, 0); + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize); return E_OK; } -static t_Error UpdateInitIpReasm(t_Handle h_FmPcd, - t_Handle h_FmPort, - t_FmPcdManip *p_Manip, - t_Handle h_Ad, - bool validate) +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_FmPcdManip *p_Manip, + t_Handle h_Ad, bool validate) { - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - t_IpReasmCommonTbl *p_ReassmCommonTbl = NULL; - t_FmPortGetSetCcParams fmPortGetSetCcParams; - uint8_t i = 0; - uint32_t tmpReg32; - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_Error err; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + uint32_t tmpReg32; + t_Error err; + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams; +#if (DPAA_VERSION >= 11) + t_FmPcdCtrlParamsPage *p_ParamsPage; +#endif /* (DPAA_VERSION >= 11) */ - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_IP_REASSEMBLY), E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR( + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY), + E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams, + E_INVALID_HANDLE); UNUSED(h_Ad); - if(p_Manip->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value")); + if (!p_Manip->updateParams) + return E_OK; - memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); + if (p_Manip->h_FmPcd != h_FmPcd) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("handler of PCD previously was initiated by different value")); - - if(p_Manip->updateParams) + if (p_Manip->updateParams) { - if((!(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) && - !(p_Manip->updateParams & HW_PORT_ID)) || - ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) || - (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) - ||(p_Manip->shadowUpdateParams & HW_PORT_ID))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); + if ((!(p_Manip->updateParams + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))) + || ((p_Manip->shadowUpdateParams + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("in this stage parameters from Port has not be updated")); - fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; - fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; - fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK; - err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); - - } - else if (validate) - { - if((!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) && - (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) && - (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) && - ((p_Manip->updateParams & NUM_OF_TASKS) || - (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)|| - (p_Manip->updateParams & HW_PORT_ID))) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); - - fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; - fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx; - fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL; - fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE; - fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK; - err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); - if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); - } - - if(p_Manip->updateParams) - { - if(p_Manip->updateParams & OFFSET_OF_DATA) + fmPortGetSetCcParams.setCcParams.type = 0; + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) { - p_Manip->ipReassmParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; - tmpReg32 = GET_UINT32(p_Ad->matchTblPtr); - tmpReg32 |= p_Manip->ipReassmParams.dataOffset; - WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE; + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF; + } + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV; + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) + != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (fmPortGetSetCcParams.getCcParams.type + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("offset of the data wasn't configured previously")); + if (p_Manip->updateParams + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)) + { + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint8_t *p_Ptr, i, totalNumOfTnums; - p_Manip->updateParams &= ~OFFSET_OF_DATA; - p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; + totalNumOfTnums = + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks); + + p_Manip->reassmParams.internalBufferPoolAddr = + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS), + BMI_FIFO_UNITS)); + if (!p_Manip->reassmParams.internalBufferPoolAddr) + RETURN_ERROR( + MAJOR, E_NO_MEMORY, + ("MURAM alloc for Reassembly internal buffers pool")); + MemSet8( + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr), + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS)); + + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr = + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)(5 + totalNumOfTnums), + 4)); + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) + RETURN_ERROR( + MAJOR, + E_NO_MEMORY, + ("MURAM alloc for Reassembly internal buffers management")); + + p_Ptr = + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr); + WRITE_UINT32( + *(uint32_t*)p_Ptr, + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase)); + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++) + WRITE_UINT8(*p_Ptr, i); + WRITE_UINT8(*p_Ptr, 0xFF); + + tmpReg32 = + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT) + | ((uint32_t)(XX_VirtToPhys( + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)) + - p_FmPcd->physicalMuramBase)); + WRITE_UINT32( + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement, + tmpReg32); + + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS + | DISCARD_MASK); + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS + | DISCARD_MASK); + } + } + + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) + { + if (p_Manip->reassmParams.capwap.h_Scheme) + { + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = + p_Manip->reassmParams.capwap.h_Scheme; + p_PcdParams->p_KgParams->numOfSchemes++; } - p_Manip->updateParams &= ~HW_PORT_ID; - p_Manip->shadowUpdateParams |= HW_PORT_ID; } else { - if(validate) + if (p_Manip->reassmParams.ip.h_Ipv4Scheme) { - /* TODO - Handle validate..*/ - /*if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); - if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value ")); - - if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value ")); - - if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) - { - if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); - } - else - { - if(p_Manip->fragParams.prOffset != 0xff) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); - } - if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));*/ - + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = + p_Manip->reassmParams.ip.h_Ipv4Scheme; + p_PcdParams->p_KgParams->numOfSchemes++; } + if (p_Manip->reassmParams.ip.h_Ipv6Scheme) + { + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = + p_Manip->reassmParams.ip.h_Ipv6Scheme; + p_PcdParams->p_KgParams->numOfSchemes++; + } +#if (DPAA_VERSION >= 11) + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6) + { + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE, + (void**)&p_ParamsPage)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + tmpReg32 = NIA_ENG_KG; + if (p_Manip->reassmParams.ip.h_Ipv4Scheme) + { + tmpReg32 |= NIA_KG_DIRECT; + tmpReg32 |= NIA_KG_CC_EN; + tmpReg32 |= FmPcdKgGetSchemeId( + p_Manip->reassmParams.ip.h_Ipv4Scheme); + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32); + } + if (p_Manip->reassmParams.ip.h_Ipv6Scheme) + { + tmpReg32 &= ~NIA_AC_MASK; + tmpReg32 |= NIA_KG_DIRECT; + tmpReg32 |= NIA_KG_CC_EN; + tmpReg32 |= FmPcdKgGetSchemeId( + p_Manip->reassmParams.ip.h_Ipv6Scheme); + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32); + } + } +#else + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6) + { + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask, + fmPortGetSetCcParams.getCcParams.discardMask); + } +#endif /* (DPAA_VERSION >= 11) */ } + return E_OK; +} + +#if (DPAA_VERSION == 10) +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); + + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS; + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed," + "Failed to release %d buffers to the BM (missing FBPRs)", + fmPcdCcFragScratchPoolCmdParams.numOfBuffers)); return E_OK; } -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ + +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); + + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + return E_OK; +} +#endif /* (DPAA_VERSION == 10) */ static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) { - if(p_Manip->h_Ad) + if (p_Manip->h_Ad) { - if(p_Manip->muramAllocate) + if (p_Manip->muramAllocate) FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad); else XX_Free(p_Manip->h_Ad); p_Manip->h_Ad = NULL; } - if(p_Manip->p_Template) + if (p_Manip->p_Template) { FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template); p_Manip->p_Template = NULL; } - if(p_Manip->h_Frag) +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + if (p_Manip->h_Frag) { - if(p_Manip->fragParams.p_AutoLearnHashTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_AutoLearnHashTbl); - if(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrPoolTbl); - if(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl); - if(p_Manip->fragParams.p_TimeOutTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_TimeOutTbl); + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->capwapFragParams.p_AutoLearnHashTbl); + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl); + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl); + if (p_Manip->capwapFragParams.p_TimeOutTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->capwapFragParams.p_TimeOutTbl); FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag); } -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - if (p_Manip->ipFragParams.h_Frag) +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + if (p_Manip->frag) { - if(p_Manip->ipFragParams.h_FragId) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_FragId); - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_Frag); + if (p_Manip->fragParams.p_Frag) + { +#if (DPAA_VERSION == 10) + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid); +#endif /* (DPAA_VERSION == 10) */ + + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); + } } - if (p_Manip->reassm) - { - if(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl) - XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl); - if(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl) - XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl); - if(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr) - XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr); - if(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr) - XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr); - if(p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr); - if(p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr); - if(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_IpReassCommonParamsTbl); - if(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl) - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl); - if(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl) - XX_Free(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl); - } -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ - if(p_Manip->p_StatsTbl) + else + if (p_Manip->reassm) + { + FmPcdUnregisterReassmPort(p_FmPcd, + p_Manip->reassmParams.p_ReassCommonTbl); + + if (p_Manip->reassmParams.timeOutTblAddr) + FM_MURAM_FreeMem( + p_FmPcd->h_FmMuram, + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)); + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr) + XX_FreeSmart( + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)); + if (p_Manip->reassmParams.p_ReassCommonTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->reassmParams.p_ReassCommonTbl); + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) + FM_MURAM_FreeMem( + p_FmPcd->h_FmMuram, + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)); + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) + FM_MURAM_FreeMem( + p_FmPcd->h_FmMuram, + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)); + if (p_Manip->reassmParams.internalBufferPoolAddr) + FM_MURAM_FreeMem( + p_FmPcd->h_FmMuram, + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)); + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP) + { + + } + else + { + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr) + XX_FreeSmart( + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)); + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr) + XX_FreeSmart( + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)); + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr) + XX_FreeSmart( + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)); + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr) + XX_FreeSmart( + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)); + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->reassmParams.ip.p_Ipv4ReassTbl); + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, + p_Manip->reassmParams.ip.p_Ipv6ReassTbl); + if (p_Manip->reassmParams.ip.h_Ipv6Ad) + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad); + if (p_Manip->reassmParams.ip.h_Ipv4Ad) + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad); + } + } + + if (p_Manip->p_StatsTbl) FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl); } -static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams) +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams) { - - if(p_ManipParams->rmv) + if (p_ManipParams->u.hdr.rmv) { - switch(p_ManipParams->rmvParams.type) + switch (p_ManipParams->u.hdr.rmvParams.type) { - case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION): - switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.type) + case (e_FM_PCD_MANIP_RMV_BY_HDR): + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) : + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include) { - case(e_FM_PCD_MANIP_LOC_BY_HDR) : - switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.manipByHdr.hdr) + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) + { + case (HEADER_TYPE_CAPWAP_DTLS) : + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; + p_Manip->muramAllocate = TRUE; + if (p_ManipParams->u.hdr.insrt) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after")); + if (p_ManipParams->fragOrReasm) { - case(HEADER_TYPE_CAPWAP_DTLS) : - - p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; - p_Manip->muramAllocate = TRUE; - - if(p_ManipParams->insrt) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after")); - - if(p_ManipParams->fragOrReasm) + if (!p_ManipParams->fragOrReasmParams.frag) + { + switch (p_ManipParams->fragOrReasmParams.hdr) { - if(!p_ManipParams->fragOrReasmParams.frag) - { - switch(p_ManipParams->fragOrReasmParams.hdr) - { - case(HEADER_TYPE_CAPWAP): - p_Manip->type = HMAN_OC_CAPWAP_REASSEMBLY; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly")); - } - } - else - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE")); + case (HEADER_TYPE_CAPWAP): + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly")); } - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location")); - + } + else + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE")); } break; default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid type of remove location")); - - } - break; - case(e_FM_PCD_MANIP_RMV_INT_FRAME_HDR) : - if(p_ManipParams->insrt || p_ManipParams->fragOrReasm) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For the type of remove e_FM_PCD_MANIP_RMV_INT_FRAME_HDR the only valid option rmv = TRUE, insrt = FALSE, fragOrReasm = FALSE")); - p_Manip->type = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; - p_Manip->muramAllocate = FALSE; - break; - case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION) : - if (p_ManipParams->fragOrReasm || - ((p_ManipParams->insrt) && p_ManipParams->insrtParams.type != e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION the only allowed insertion type is e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR")); - p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; - p_Manip->muramAllocate = TRUE; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); - } - } - else if(p_ManipParams->insrt) - { - switch(p_ManipParams->insrtParams.type) - { - case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE) : - - p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; - p_Manip->muramAllocate = FALSE; - - if(p_ManipParams->fragOrReasm) - { - if(p_ManipParams->fragOrReasmParams.frag) - { - switch(p_ManipParams->fragOrReasmParams.hdr) - { - case(HEADER_TYPE_CAPWAP): - p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION; - break; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation")); - } + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location")); } - else - RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point")); } - break; - case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR) : - if(p_ManipParams->fragOrReasm) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of insert can not be fragOrReasm = TRUE")); - p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; - p_Manip->muramAllocate = TRUE; + else + { + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) + { + case (HEADER_TYPE_CAPWAP_DTLS) : + case (HEADER_TYPE_CAPWAP) : + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE")); + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; + p_Manip->muramAllocate = TRUE; + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header + break; + default : + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); + } + } + break; + default : + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); + } break; default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type")); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); } } - else if(p_ManipParams->fragOrReasm) + else if (p_ManipParams->u.hdr.insrt) { - if(p_ManipParams->fragOrReasmParams.frag) + switch (p_ManipParams->u.hdr.insrtParams.type) { - switch(p_ManipParams->fragOrReasmParams.hdr) - { - case(HEADER_TYPE_CAPWAP): - p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION; - p_Manip->muramAllocate = FALSE; - break; -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - case(HEADER_TYPE_IPv4): - p_Manip->type = HMAN_OC_IP_FRAGMENTATION; - p_Manip->muramAllocate = TRUE; - break; -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation")); - } + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) : + + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; + p_Manip->muramAllocate = FALSE; + if (p_ManipParams->fragOrReasm) + { + if (p_ManipParams->fragOrReasmParams.frag) + { + switch (p_ManipParams->fragOrReasmParams.hdr) + { + case (HEADER_TYPE_CAPWAP): + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation")); + } + } + else + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point")); + } + break; + + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type")); + } + } + else if (p_ManipParams->fragOrReasm) + { + if (p_ManipParams->fragOrReasmParams.frag) + { + switch (p_ManipParams->fragOrReasmParams.hdr) + { + case (HEADER_TYPE_CAPWAP): + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; + p_Manip->muramAllocate = FALSE; + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation")); + } } else { switch (p_ManipParams->fragOrReasmParams.hdr) { - case(HEADER_TYPE_CAPWAP): - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS")); -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - case(HEADER_TYPE_IPv4): - p_Manip->type = HMAN_OC_IP_REASSEMBLY; - p_Manip->muramAllocate = TRUE; - p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv4; - break; - case(HEADER_TYPE_IPv6): - p_Manip->type = HMAN_OC_IP_REASSEMBLY; - p_Manip->muramAllocate = TRUE; - p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv6; - break; -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ + case (HEADER_TYPE_CAPWAP): + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS")); default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly")); - + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly")); } } } else - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation")); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation")); - p_Manip->insrt = p_ManipParams->insrt; - p_Manip->rmv = p_ManipParams->rmv; + p_Manip->insrt = p_ManipParams->u.hdr.insrt; + p_Manip->rmv = p_ManipParams->u.hdr.rmv; return E_OK; } -static t_Error UpdateIndxStats( t_Handle h_FmPcd, - t_Handle h_FmPort, - t_FmPcdManip *p_Manip) + +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, + t_FmPcdManipParams *p_ManipParams) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t tmpReg32 = 0; - t_AdOfTypeContLookup *p_Ad; - t_FmPortGetSetCcParams fmPortGetSetCcParams; - t_Error err; + switch (p_ManipParams->type) + { + case e_FM_PCD_MANIP_HDR: + /* Check that next-manip is not already used */ + if (p_ManipParams->h_NextManip) + { + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip)) + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("h_NextManip is already a part of another chain")); + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip) + != e_FM_PCD_MANIP_HDR) && + (MANIP_GET_TYPE(p_ManipParams->h_NextManip) + != e_FM_PCD_MANIP_FRAG)) + RETURN_ERROR( + MAJOR, + E_NOT_SUPPORTED, + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation.")); + } + + if (p_ManipParams->u.hdr.rmv) + { + switch (p_ManipParams->u.hdr.rmvParams.type) + { + case (e_FM_PCD_MANIP_RMV_BY_HDR): + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): + break; + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): + { + t_Error err; + uint8_t prsArrayOffset; + + err = + GetPrOffsetByHeaderOrField( + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, + &prsArrayOffset); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + break; + } +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("invalid type of remove manipulation")); + } + break; + case (e_FM_PCD_MANIP_RMV_GENERIC): + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("invalid type of remove manipulation")); + } + p_Manip->opcode = HMAN_OC; + p_Manip->muramAllocate = TRUE; + p_Manip->rmv = TRUE; + } + else + if (p_ManipParams->u.hdr.insrt) + { + switch (p_ManipParams->u.hdr.insrtParams.type) + { + case (e_FM_PCD_MANIP_INSRT_BY_HDR): + { + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type) + { + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): + /* nothing to check */ + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size + % 4) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("IP inserted header must be of size which is a multiple of four bytes")); + break; + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size + % 4) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("CAPWAP inserted header must be of size which is a multiple of four bytes")); + break; + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size + != 8) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Inserted header must be of size 8")); + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("unsupported insert by header type")); + } + } + case (e_FM_PCD_MANIP_INSRT_GENERIC): + break; + default: + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("for only insert manipulation unsupported type")); + } + p_Manip->opcode = HMAN_OC; + p_Manip->muramAllocate = TRUE; + p_Manip->insrt = TRUE; + } + else + if (p_ManipParams->u.hdr.fieldUpdate) + { + /* Check parameters */ + if (p_ManipParams->u.hdr.fieldUpdateParams.type + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN) + { + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri + > 7)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("vpri should get values of 0-7 ")); + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) + { + int i; + + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal + > 7) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("vpriDefVal should get values of 0-7 ")); + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS; + i++) + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i] + & 0xf0) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("dscpToVpriTabl value out of range (0-15)")); + } + + } + + p_Manip->opcode = HMAN_OC; + p_Manip->muramAllocate = TRUE; + p_Manip->fieldUpdate = TRUE; + } + else + if (p_ManipParams->u.hdr.custom) + { + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE) + { + + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) || + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("size should get values of 1-8 ")); + + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("srcOffset should be <= 7")); + + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset + + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("(srcOffset + size) should be <= 8")); + + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset + + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("(dstOffset + size) should be <= 256")); + + } + + p_Manip->opcode = HMAN_OC; + p_Manip->muramAllocate = TRUE; + p_Manip->custom = TRUE; + } + break; + case e_FM_PCD_MANIP_REASSEM: + if (p_ManipParams->h_NextManip) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("next manip with reassembly")); + switch (p_ManipParams->u.reassem.hdr) + { + case (HEADER_TYPE_IPv4): + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4; + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; + break; + case (HEADER_TYPE_IPv6): + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6; + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; + break; +#if (DPAA_VERSION >= 11) + case (HEADER_TYPE_CAPWAP): + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP; + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("header for reassembly")); + } + break; + case e_FM_PCD_MANIP_FRAG: + if (p_ManipParams->h_NextManip) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("next manip with fragmentation")); + switch (p_ManipParams->u.frag.hdr) + { + case (HEADER_TYPE_IPv4): + case (HEADER_TYPE_IPv6): + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION; + break; +#if (DPAA_VERSION >= 11) + case (HEADER_TYPE_CAPWAP): + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("header for fragmentation")); + } + p_Manip->muramAllocate = TRUE; + break; + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD: + switch (p_ManipParams->u.specialOffload.type) + { + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC): + p_Manip->opcode = HMAN_OC_IPSEC_MANIP; + p_Manip->muramAllocate = TRUE; + break; +#if (DPAA_VERSION >= 11) + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP): + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP; + p_Manip->muramAllocate = TRUE; + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("special offload type")); + } + break; + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type")); + } + + return E_OK; +} +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + +static t_Error UpdateIndxStats(t_Handle h_FmPcd, + t_Handle h_FmPort, + t_FmPcdManip *p_Manip) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t tmpReg32 = 0; + t_AdOfTypeContLookup *p_Ad; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - if(p_Manip->h_FmPcd != h_FmPcd) - RETURN_ERROR(MAJOR, E_INVALID_STATE, - ("handler of PCD previously was initiated by different value")); + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + if (p_Manip->h_FmPcd != h_FmPcd) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("handler of PCD previously was initiated by different value")); memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); - if(!p_Manip->p_StatsTbl) + if (!p_Manip->p_StatsTbl) { fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); tmpReg32 = GET_UINT32(p_Ad->ccAdBase); - p_Manip->p_StatsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE, - 4); - if(!p_Manip->p_StatsTbl) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + p_Manip->p_StatsTbl = + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE, + 4); + if (!p_Manip->p_StatsTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table")); - IOMemSet32(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4)); + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4)); tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase); - if(p_Manip->cnia) - tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA; + if (p_Manip->cnia) + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA; - tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD; + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD; WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); - } else { fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); } + return E_OK; } -static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree) +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip) { - t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; - t_Error err = E_OK; - - SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE); - UNUSED(h_FmPcd); - UNUSED(h_FmTree); - - switch(p_Manip->type) - { - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - if(level != 1) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree")); - err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, p_Manip, h_Ad, validate); - break; -#ifdef FM_CAPWAP_SUPPORT - case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): - if(!p_Manip->h_Frag) - break; - case(HMAN_OC_CAPWAP_FRAGMENTATION): - if(level != 2) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree")); - err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree); - break; - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - if(p_Manip->h_Frag) - { - if(level != 2) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree")); - err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate); - } - break; -#endif /* FM_CAPWAP_SUPPORT */ -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) - case(HMAN_OC_IPSEC): - err = UpdateInitIPSec(h_FmPort, p_Manip); - if (err != E_OK) - RETURN_ERROR(MAJOR, err, ("UpdateInitIPSec failed")); - if(!p_Manip->h_Frag) - break; -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - case(HMAN_OC_IP_FRAGMENTATION): - err = UpdateInitIpFragmentation(h_FmPort, p_Manip); - break; - case(HMAN_OC_IP_REASSEMBLY): - err = UpdateInitIpReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate); - break; -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/ - case(HMAN_OC_CAPWAP_INDEXED_STATS): - if(level != 2) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For index statistics the manipulation has to be in the first level of the tree")); - err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip); - break; - default: - return E_OK; - } - return err; -} - -static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree) -{ - - t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; - t_Error err = E_OK; - - switch(p_Manip->type) - { - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation is not suppported")); - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - - if(p_Manip->h_Frag) - { - if(!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) && - !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation requires manipulation be updated previousely in SetPcd function")); - if(level != 2) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree")); - } - break; -#ifdef FM_CAPWAP_SUPPORT - case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): - if(p_Manip->h_Frag) - { - if(level != 2) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree")); - err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree); - } - break; -#endif /* FM_CAPWAP_SUPPORT */ - default: - return E_OK; - - } - return err; - -} - -static t_Error GetPrOffsetByHeaderOrField(t_FmPcdManipLocationParams *p_ManipParams, uint8_t *parseArrayOffset) -{ - e_NetHeaderType hdr = p_ManipParams->manipByHdr.hdr; - e_FmPcdHdrIndex hdrIndex = p_ManipParams->manipByHdr.hdrIndex; - bool byField = p_ManipParams->manipByHdr.byField; - t_FmPcdFields field; - - if(byField) - field = p_ManipParams->manipByHdr.fullField; - - if(byField) - { - switch(hdr) - { - case(HEADER_TYPE_ETH): - switch(field.eth) - { - case(NET_HEADER_FIELD_ETH_TYPE): - *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; - break; - default: - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type Ethernet with this field not supported")); - } - break; - case(HEADER_TYPE_VLAN): - switch(field.vlan) - { - case(NET_HEADER_FIELD_VLAN_TCI) : - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) - *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; - break; - default: - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type VLAN with this field not supported")); - } - break; - default: - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header by field not supported")); - } - } - else - { - switch(hdr){ - case(HEADER_TYPE_ETH): - *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; - break; - case(HEADER_TYPE_USER_DEFINED_SHIM1): - *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; - break; - case(HEADER_TYPE_USER_DEFINED_SHIM2): - *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; - break; - /* TODO - to take care about SHIM3 - case(HEADER_TYPE_USER_DEFINED_SHIM3): - *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM3_OFFSET; - break; - */ - case(HEADER_TYPE_LLC_SNAP): - *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; - break; - case(HEADER_TYPE_PPPoE): - *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; - break; - case(HEADER_TYPE_MPLS): - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) - *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; - break; - case(HEADER_TYPE_IPv4): - case(HEADER_TYPE_IPv6): - if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - *parseArrayOffset = CC_PC_PR_IP1_OFFSET; - else if(hdrIndex == e_FM_PCD_HDR_INDEX_2) - *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; - break; - case(HEADER_TYPE_MINENCAP): - *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; - break; - case(HEADER_TYPE_GRE): - *parseArrayOffset = CC_PC_PR_GRE_OFFSET; - break; - case(HEADER_TYPE_TCP): - case(HEADER_TYPE_UDP): - case(HEADER_TYPE_IPSEC_AH): - case(HEADER_TYPE_IPSEC_ESP): - case(HEADER_TYPE_DCCP): - case(HEADER_TYPE_SCTP): - *parseArrayOffset = CC_PC_PR_L4_OFFSET; - break; - default: - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header is not supported")); - } - } - return E_OK; -} - -static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipRmvParams *p_ManipParams, t_FmPcdManip *p_Manip) -{ - t_AdOfTypeContLookup *p_Ad; - uint32_t tmpReg32 = 0; - uint8_t prsArrayOffset = 0; - t_Error err; + t_AdOfTypeContLookup *p_Ad; + uint32_t tmpReg32 = 0; + uint8_t prsArrayOffset = 0; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - if(p_Manip->rmv) + if (p_Manip->rmv) { - switch(p_ManipParams->rmvSpecificLocationParams.type) - { - case(e_FM_PCD_MANIP_LOC_BY_HDR) : - err = GetPrOffsetByHeaderOrField(&p_ManipParams->rmvSpecificLocationParams, &prsArrayOffset); - break; - case(e_FM_PCD_MANIP_LOC_NON_HDR) : - err = GetPrOffsetByNonHeader(&prsArrayOffset); - break; - default : - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid type of location header manipulation of type Remove")); - } - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); tmpReg32 |= (uint32_t)prsArrayOffset << 24; tmpReg32 |= HMAN_RMV_HDR; } - if(p_Manip->insrt) - tmpReg32 |= HMAN_INSRT_INT_FRM_HDR; + if (p_Manip->insrt) + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR; tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; @@ -1527,12 +3026,13 @@ static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipRmvParams *p_Mani return E_OK; } -static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, bool caamUsed) +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, + bool caamUsed) { - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - uint32_t tmpReg32 = 0; + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + uint32_t tmpReg32 = 0; - SANITY_CHECK_RETURN_ERROR(p_Ad,E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE); p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET; @@ -1540,32 +3040,26 @@ static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, bo tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; *(uint32_t *)&p_Ad->ccAdBase = tmpReg32; - /*TODO - update offsetInBufferPrefixForIntFrameHdr when port connected to tree - tmpReg32 = 0; - tmpReg32 |= offsetInBufferPrefixForIntFrameHdr; - *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;*/ - tmpReg32 = 0; tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; tmpReg32 |= (uint32_t)0x16 << 16; *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; if (caamUsed) - *(uint32_t *)&p_Ad->gmask = 0xf0000000; + *(uint32_t *)&p_Ad->gmask = 0xf0000000; return E_OK; } -#ifdef FM_CAPWAP_SUPPORT static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip) { - t_AdOfTypeContLookup *p_Ad; - uint32_t tmpReg32 = 0; - t_Error err = E_OK; + t_AdOfTypeContLookup *p_Ad; + uint32_t tmpReg32 = 0; + t_Error err = E_OK; SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; tmpReg32 = 0; tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; @@ -1575,7 +3069,7 @@ static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip) tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; - if(p_Manip->h_Frag) + if (p_Manip->h_Frag) { p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET; tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); @@ -1586,74 +3080,85 @@ static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip) return err; } -static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex) +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams, + t_FmPcdManip *p_Manip, + t_FmPcd *p_FmPcd, + uint8_t poolId) { - t_Handle p_Table; - uint32_t tmpReg32 = 0; - int i = 0; - uint8_t log2Num; - uint8_t numOfSets; - uint32_t j = 0; + t_Handle p_Table; + uint32_t tmpReg32 = 0; + int i = 0; + uint8_t log2Num; + uint8_t numOfSets; + uint32_t j = 0; + uint32_t bitFor1Micro; - SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); - if(!p_FmPcd->h_Hc) + if (!p_FmPcd->h_Hc) RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode")); if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2")); - if(!POWER_OF_2(p_ManipParams->maxNumFramesInProcess)) + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess)) RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2")); - if(!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess) + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess) DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly")); - if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH) + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH) { - if((p_ManipParams->maxNumFramesInProcess < 4) || - (p_ManipParams->maxNumFramesInProcess > 512)) - RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512")); + if ((p_ManipParams->maxNumFramesInProcess < 4) || + (p_ManipParams->maxNumFramesInProcess > 512)) + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512")); } else { - if((p_ManipParams->maxNumFramesInProcess < 8) || - (p_ManipParams->maxNumFramesInProcess > 2048)) - RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048")); + if ((p_ManipParams->maxNumFramesInProcess < 8) || + (p_ManipParams->maxNumFramesInProcess > 2048)) + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048")); } - p_Manip->updateParams |= (NUM_OF_TASKS | BUFFER_POOL_ID_FOR_MANIP | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID); + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); + if (bitFor1Micro == 0) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); + + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID); p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE, - FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); - if(!p_Manip->h_Frag) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE, + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); + if (!p_Manip->h_Frag) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table")); - IOMemSet32(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE); + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE); - p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag; + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag; - p_Manip->fragParams.p_AutoLearnHashTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), - FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); + p_Manip->capwapFragParams.p_AutoLearnHashTbl = + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); - IOMemSet32(p_Manip->fragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE)); + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl) + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table")); + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE)); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase); + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase); WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32); tmpReg32 = 0; - if(p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES; - if(p_ManipParams->haltOnDuplicationFrag) - tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG; - if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH) + if (p_ManipParams->haltOnDuplicationFrag) + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG; + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH) { i = 8; - tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS; + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS; } else - i = 4; + i = 4; numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i); LOG2(numOfSets, log2Num); @@ -1661,305 +3166,88 @@ static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,t_FmPcdM WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32); - for(j = 0; j < p_ManipParams->maxNumFramesInProcess * 2; j++) - { - if(((j / i) % 2)== 0) - { - WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->fragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000); - } - } + for (j=0; jmaxNumFramesInProcess*2; j++) + if (((j / i) % 2)== 0) + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000); - WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, 0x00008000); + tmpReg32 = 0x00008000; + tmpReg32 |= (uint32_t)poolId << 16; + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32); WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000); WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000); - p_Manip->fragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess; + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess; - p_Manip->fragParams.poolIndx = poolIndex; + p_Manip->capwapFragParams.sgBpid = poolId; - p_Manip->fragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames; - p_Manip->fragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime; - /*TODO - to take care about this function FmGetTimeStampScale - it return t_Error - now we have problems with all calls to this fucntion*/ - p_Manip->fragParams.bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames; + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime; + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro; tmpReg32 = 0; - tmpReg32 |= (((uint32_t)1<fragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess); + tmpReg32 |= (((uint32_t)1<capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess); WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32); return E_OK; - } -static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex) +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams, + t_FmPcdManip *p_Manip, + t_FmPcd *p_FmPcd, + uint8_t poolId) { - t_AdOfTypeContLookup *p_Ad; - uint32_t tmpReg32 = 0; + t_AdOfTypeContLookup *p_Ad; + uint32_t tmpReg32 = 0; SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - p_Manip->updateParams |= OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP; + p_Manip->updateParams |= OFFSET_OF_DATA; p_Manip->frag = TRUE; p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Manip->h_Frag) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->h_Frag) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor")); - IOMemSet32(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; tmpReg32 = 0; tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; - if(p_ManipParams->headerOptionsCompr) - tmpReg32 = FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN; + if (p_ManipParams->headerOptionsCompr) + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN; + tmpReg32 |= ((uint32_t)poolId << 8); WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); tmpReg32 = 0; tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); - p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; - p_Manip->fragParams.poolIndx = poolIndex; + p_Manip->capwapFragParams.sgBpid = poolId; return E_OK; } -#endif /* FM_CAPWAP_SUPPORT */ - -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY -static t_Error IpFragmentation(t_IpFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd, uint8_t poolIndex) -{ - t_AdOfTypeContLookup *p_Ad; - uint32_t tmpReg32 = 0; - - SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - - p_Manip->ipFragParams.h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - - if( !p_Manip->ipFragParams.h_Frag) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - - IOMemSet32( p_Manip->ipFragParams.h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); - - p_Ad = (t_AdOfTypeContLookup *)p_Manip->ipFragParams.h_Frag; - - tmpReg32 = 0; - tmpReg32 |= (uint32_t)HMAN_OC_IP_FRAGMENTATION; - WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); - - tmpReg32 = 0; - tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; - tmpReg32 |= (p_ManipParams->dontFragAction << 30); - WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); - - p_Manip->frag = TRUE; - - p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; - p_Manip->ipFragParams.poolIndx = poolIndex; - - /*Pointer to fragment ID*/ - p_Manip->ipFragParams.h_FragId= (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,4, 4); - - if(!p_Manip->ipFragParams.h_FragId) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - - IOMemSet32(p_Manip->ipFragParams.h_FragId, 0, 4); - - tmpReg32 = 0; - tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->ipFragParams.h_FragId) - (p_FmPcd->physicalMuramBase)); - tmpReg32 |= p_ManipParams->scratchBpid << 24; - WRITE_UINT32(p_Ad->gmask, tmpReg32); - - return E_OK; -} - -static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool ipv4) -{ - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; - t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; - uint32_t tmpReg32; - t_Error err; - t_Handle h_IpReassParamsTblPtr; - - /* First Ad register */ - tmpReg32 = 0; - tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; - - if (ipv4) - h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr; - else - h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr; - - err = CreateIpReassParamTable(p_Manip, h_IpReassParamsTblPtr, ipv4); - - if (err == E_OK) - tmpReg32 |= (uint32_t)(XX_VirtToPhys(h_IpReassParamsTblPtr) - (p_FmPcd->physicalMuramBase)); - else - return err; - - WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); - - /* Second Ad register */ - tmpReg32 = (uint32_t)(p_Manip->ipReassmParams.bpid << 8); - WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); - - p_Manip->updateParams = OFFSET_OF_DATA; - - /* Third Ad register */ - tmpReg32 = 0; - tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY; - tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT; - tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT; - WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); - - p_Manip->reassm = TRUE; - - return E_OK; -} - -static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; - - if(p_Manip->muramAllocate) - { - p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Manip->ipReassmParams.h_Ipv4Ad) - { - ReleaseManipHandler(p_Manip, p_FmPcd); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - } - - IOMemSet32(p_Manip->ipReassmParams.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - } - else - { - p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0); - if(!p_Manip->ipReassmParams.h_Ipv4Ad) - { - ReleaseManipHandler(p_Manip, p_FmPcd); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - } - - memset(p_Manip->ipReassmParams.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); - } - - FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, TRUE); - - return E_OK; -} - -static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; - - if(p_Manip->muramAllocate) - { - p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Manip->ipReassmParams.h_Ipv6Ad) - { - ReleaseManipHandler(p_Manip, p_FmPcd); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - } - - IOMemSet32(p_Manip->ipReassmParams.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - } - else - { - p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0); - if(!p_Manip->ipReassmParams.h_Ipv6Ad) - { - ReleaseManipHandler(p_Manip, p_FmPcd); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - } - - memset(p_Manip->ipReassmParams.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); - } - - FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, FALSE); - - return E_OK; -} - - -static t_Error IpReassembly(t_FmPcdManipFragOrReasmParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) -{ - uint32_t tmpReg32 = 0, maxSetNumber = 10000; - t_IpReasmCommonTbl *p_IpReasmCommonPramTbl = NULL; - t_IpReassemblyParams reassmManipParams = p_ManipParams->ipReasmParams; - t_Error err; - - SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); - - if (!p_FmPcd->h_Hc) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode")); - if (!POWER_OF_2(reassmManipParams.maxNumFramesInProcess)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2")); - - if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) && (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("timeoutThresholdForReassmProcess should be 1msec - 8sec")); - - /*It is recommended that the total number of entries in this table (number of sets * number of ways) - will be twice the number of frames that are expected to be reassembled simultaneously.*/ - if (reassmManipParams.maxNumFramesInProcess > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); - - p_Manip->ipReassmParams.maxNumFramesInProcess = reassmManipParams.maxNumFramesInProcess; - p_Manip->ipReassmParams.timeOutMode = reassmManipParams.timeOutMode; - p_Manip->ipReassmParams.fqidForTimeOutFrames = reassmManipParams.fqidForTimeOutFrames; - p_Manip->ipReassmParams.numOfFramesPerHashEntry = reassmManipParams.numOfFramesPerHashEntry; - p_Manip->ipReassmParams.timeoutThresholdForReassmProcess = reassmManipParams.timeoutThresholdForReassmProcess; - p_Manip->ipReassmParams.liodnOffset = reassmManipParams.liodnOffset; - p_Manip->ipReassmParams.minFragSize = reassmManipParams.minFragSize; - p_Manip->ipReassmParams.dataMemId = reassmManipParams.dataMemId; - p_Manip->ipReassmParams.bpid = p_ManipParams->extBufPoolIndx; - - CreateIpReassCommonParamTable(p_Manip, p_FmPcd, p_IpReasmCommonPramTbl); - - if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4)) - return SetIpv4ReassmManip(p_Manip); - - if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv6)) - return SetIpv6ReassmManip(p_Manip); - - err = FM_PCD_RegisterReassmPort(p_FmPcd, p_IpReasmCommonPramTbl); - if (err != E_OK) - { - FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_IpReasmCommonPramTbl); - RETURN_ERROR(MAJOR, err, ("port registration")); - } - - return E_OK; -} -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd) { - t_AdOfTypeContLookup *p_Ad; - uint32_t tmpReg32 = 0; + t_AdOfTypeContLookup *p_Ad; + uint32_t tmpReg32 = 0; SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); UNUSED(p_FmPcd); - p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; tmpReg32 = 0; tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS; - if(p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID) - tmpReg32 |= (uint32_t)0x16 << 16; + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID) + tmpReg32 |= (uint32_t)0x16 << 16; WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); tmpReg32 = 0; @@ -1969,17 +3257,17 @@ static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip return E_OK; } -static t_Error InsrtHdrByTempl(t_FmPcdManipInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) { - t_FmPcdManipInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->insrtByTemplateParams; - uint8_t tmpReg8 = 0xff; - t_AdOfTypeContLookup *p_Ad; - bool ipModify = FALSE; - uint32_t tmpReg32 = 0, tmpRegNia = 0; - uint16_t tmpReg16 = 0; - t_Error err = E_OK; - uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0; - uint8_t *p_Template = NULL; + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate; + uint8_t tmpReg8 = 0xff; + t_AdOfTypeContLookup *p_Ad; + bool ipModify = FALSE; + uint32_t tmpReg32 = 0, tmpRegNia = 0; + uint16_t tmpReg16 = 0; + t_Error err = E_OK; + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0; + uint8_t *p_Template = NULL; SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); @@ -1987,155 +3275,178 @@ static t_Error InsrtHdrByTempl(t_FmPcdManipInsrtParams *p_ManipParams, t_FmPcdM SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER); p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - if(p_Manip->insrt) + if (p_Manip->insrt) { - if((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) || - (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)")); + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) || + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)")); - if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset")); + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset")); - if(p_InsrtByTemplate->size > 128) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128")); + if (p_InsrtByTemplate->size > 128) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128")); - if(p_InsrtByTemplate->size) - { - p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - p_InsrtByTemplate->size, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Manip->p_Template) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); + if (p_InsrtByTemplate->size) + { + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, + p_InsrtByTemplate->size, + FM_PCD_CC_AD_TABLE_ALIGN); + if(!p_Manip->p_Template) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase)); - tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24; - *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32; - } + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase)); + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24; + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32; + } - tmpReg32 = 0; + tmpReg32 = 0; p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t)); - if(!p_Template) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED")); + if (!p_Template) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED")); memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t)); + if (p_InsrtByTemplate->modifyOuterIp) + { + ipModify = TRUE; - if(p_InsrtByTemplate->modifyOuterIp) - { - ipModify = TRUE; + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset]; - tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset]; + if((tmpReg8 & 0xf0) == 0x40) + tmpReg8 = 4; + else if((tmpReg8 & 0xf0) == 0x60) + tmpReg8 = 6; + else + tmpReg8 = 0xff; - if((tmpReg8 & 0xf0) == 0x40) - tmpReg8 = 4; - else if((tmpReg8 & 0xf0) == 0x60) - tmpReg8 = 6; - else - tmpReg8 = 0xff; + if (tmpReg8 != 0xff) + { + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte")); + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength) + { - if(tmpReg8 == 4) - { - if((IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size")); - - if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte")); - - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn; - - if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength) - { - - if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes")); - extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize); - blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize; - extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize; - /*IP header template - IP totalLength - + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes")); + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize); + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize; + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize; + /*IP header template - IP totalLength - (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage , in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13) second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/ - } - if(blockSize) - { - if (!POWER_OF_2(blockSize)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2")); - blockSize -= 1; - } + } + if (blockSize) + { + if (!POWER_OF_2(blockSize)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2")); + } - if((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255")); + } + if (tmpReg8 == 4) + { + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size")); - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes); + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP] = 0x00; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; + if (blockSize) + blockSize -= 1; + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255")); - /*IP header template - relevant only for ipv4 CheckSum = 0*/ - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; - /*UDP checksum has to be 0*/ - if(p_InsrtByTemplate->modifyOuterIpParams.udpPresent) - { - if((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_UDPCHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); + /*IP header template - relevant only for ipv4 CheckSum = 0*/ + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00; - p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; + /*UDP checksum has to be 0*/ + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) + { + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); - } + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; - if(p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field")); + } - tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24; - } - else - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4")); - } + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field")); - tmpReg32 = tmpReg16 = tmpReg8 = 0; - /*TODO - check it*/ - if(p_InsrtByTemplate->modifyOuterVlan) - { - if(p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07) - RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits")); + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24; + } + else if (tmpReg8 == 6) + { + /*TODO - add check for maximum value of blockSize;*/ + if (blockSize) + LOG2(blockSize, log2Num); + tmpRegNia |= (uint32_t)log2Num << 24; - memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t))); - if((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100)) - RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN ")); + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40); + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) + { + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite")); + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00; + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; + } + } + else + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4")); + } - memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t))); - tmpReg8 &= 0x1f; - tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5); + tmpReg32 = tmpReg16 = tmpReg8 = 0; + /*TODO - check it*/ + if (p_InsrtByTemplate->modifyOuterVlan) + { + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07) + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits")); - p_Template[14] = tmpReg8; - } + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t))); + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100)) + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN ")); - Mem2IOCpy32(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size); + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t))); + tmpReg8 &= 0x1f; + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5); + + p_Template[14] = tmpReg8; + } + + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size); XX_Free(p_Template); } tmpReg32 = 0; - if(p_Manip->h_Frag) + if (p_Manip->h_Frag) { tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16; } else - tmpReg32 = 0xffff0000; + tmpReg32 = 0xffff0000; - if(ipModify) - tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8; + if (ipModify) + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8; else - tmpReg32 |= (uint32_t)0x0000ff00; + tmpReg32 |= (uint32_t)0x0000ff00; tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; @@ -2146,492 +3457,2115 @@ static t_Error InsrtHdrByTempl(t_FmPcdManipInsrtParams *p_ManipParams, t_FmPcdM return err; } -#if defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC) -static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams) { - t_Error err = E_OK; - t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; - uint32_t tmpReg32 = 0, tmpRegNia = 0; - - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE); - - if(p_Manip->frag == TRUE) + switch (p_StatsParams->type) { - tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); - tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16; - } - else - tmpReg32 = 0xffff0000; - - tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; - tmpReg32 |= HMAN_OC_IPSEC; - - WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); - WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); - WRITE_UINT32(p_Ad->gmask, 0); /* Total frame counter - MUST be initialized to zero.*/ - -/* - TODO - Fill the following: - - Over write OuterTos - - SaveInnerTos - - support in CNIA -*/ - - return err; -} -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */ - -static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams) -{ - - switch(p_StatsParams->type) - { - case(e_FM_PCD_STATS_PER_FLOWID): - p_Manip->type = HMAN_OC_CAPWAP_INDEXED_STATS; - p_Manip->muramAllocate = TRUE; + case (e_FM_PCD_STATS_PER_FLOWID): + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS; + p_Manip->muramAllocate = TRUE; break; default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type")); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type")); + } + + return E_OK; +} +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) +{ + t_AdOfTypeContLookup *p_Ad; + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + uint32_t tmpReg32; + t_Error err = E_OK; + + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then + two separate IP Reassembly Parameter tables are required.*/ + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/ + tmpReg32 = 0; + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; + + /* Gets the required Action descriptor table pointer */ + switch (hdr) + { + case HEADER_TYPE_IPv4: + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad; + tmpReg32 |= (uint32_t)(XX_VirtToPhys( + p_Manip->reassmParams.ip.p_Ipv4ReassTbl) + - (p_FmPcd->physicalMuramBase)); + break; + case HEADER_TYPE_IPv6: + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad; + tmpReg32 |= (uint32_t)(XX_VirtToPhys( + p_Manip->reassmParams.ip.p_Ipv6ReassTbl) + - (p_FmPcd->physicalMuramBase)); + break; + case HEADER_TYPE_CAPWAP: + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad; + tmpReg32 |= (uint32_t)(XX_VirtToPhys( + p_Manip->reassmParams.capwap.p_ReassTbl) + - (p_FmPcd->physicalMuramBase)); + break; + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); + } + + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); + + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/ + /* mark the Scatter/Gather table offset to be set later on when the port will be known */ + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK); + + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4)) + { +#if (DPAA_VERSION == 10) + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8); + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); +#endif /* (DPAA_VERSION == 10) */ +#if (DPAA_VERSION >= 11) + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0) + { + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid); + WRITE_UINT32(p_Ad->gmask, tmpReg32); + } +#endif /* (DPAA_VERSION >= 11) */ + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/ + tmpReg32 = 0; + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY; + } +#if (DPAA_VERSION >= 11) + else + if (hdr == HEADER_TYPE_CAPWAP) + { + tmpReg32 = 0; + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY; + } +#endif /* (DPAA_VERSION >= 11) */ + + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); + + p_Manip->reassm = TRUE; + + return E_OK; +} + +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + + /* Allocation if IPv4 Action descriptor */ + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart( + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->reassmParams.ip.h_Ipv4Ad) + { + ReleaseManipHandler(p_Manip, p_FmPcd); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("Allocation of IPv4 table descriptor")); + } + + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4); +} + +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + + /* Allocation if IPv6 Action descriptor */ + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart( + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->reassmParams.ip.h_Ipv6Ad) + { + ReleaseManipHandler(p_Manip, p_FmPcd); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("Allocation of IPv6 table descriptor")); + } + + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6); +} + +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, + t_FmPcdManip *p_Manip) +{ + uint32_t maxSetNumber = 10000; + t_FmPcdManipReassemIpParams reassmManipParams = + p_ManipReassmParams->u.ipReassem; + t_Error res; + + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, + E_INVALID_HANDLE); + + /* Check validation of user's parameter.*/ + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); + /* It is recommended that the total number of entries in this table (number of sets * number of ways) + will be twice the number of frames that are expected to be reassembled simultaneously.*/ + if (reassmManipParams.maxNumFramesInProcess + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); + + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6) + && (reassmManipParams.minFragSize[1] < 256)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256")); + + /* Saves user's reassembly manipulation parameters */ + p_Manip->reassmParams.ip.relativeSchemeId[0] = + reassmManipParams.relativeSchemeId[0]; + p_Manip->reassmParams.ip.relativeSchemeId[1] = + reassmManipParams.relativeSchemeId[1]; + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] = + reassmManipParams.numOfFramesPerHashEntry[0]; + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] = + reassmManipParams.numOfFramesPerHashEntry[1]; + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0]; + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1]; + p_Manip->reassmParams.maxNumFramesInProcess = + reassmManipParams.maxNumFramesInProcess; + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; + p_Manip->reassmParams.fqidForTimeOutFrames = + reassmManipParams.fqidForTimeOutFrames; + p_Manip->reassmParams.timeoutThresholdForReassmProcess = + reassmManipParams.timeoutThresholdForReassmProcess; + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; +#if (DPAA_VERSION == 10) + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid; +#endif /* (DPAA_VERSION == 10) */ +#if (DPAA_VERSION >= 11) + if (reassmManipParams.nonConsistentSpFqid != 0) + { + p_Manip->reassmParams.ip.nonConsistentSpFqid = + reassmManipParams.nonConsistentSpFqid; + } +#endif /* (DPAA_VERSION >= 11) */ + + /* Creates and initializes the IP Reassembly common parameter table */ + CreateReassCommonTable(p_Manip); + + /* Creation of IPv4 reassembly manipulation */ + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4)) + { + res = SetIpv4ReassmManip(p_Manip); + if (res != E_OK) + return res; + } + + /* Creation of IPv6 reassembly manipulation */ + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) + { + res = SetIpv6ReassmManip(p_Manip); + if (res != E_OK) + return res; } return E_OK; } -static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, bool stats) +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd, + t_FmPcdKgSchemeParams *p_Scheme, + t_Handle h_CcTree, bool ipv4, + uint8_t groupId) { - t_FmPcdManip *p_Manip; - t_Error err; - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t j; + uint8_t res; + + /* Configures scheme's network environment parameters */ + p_Scheme->netEnvParams.numOfDistinctionUnits = 2; + if (ipv4) + res = FmPcdNetEnvGetUnitId( + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), + HEADER_TYPE_IPv4, FALSE, 0); + else + res = FmPcdNetEnvGetUnitId( + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), + HEADER_TYPE_IPv6, FALSE, 0); + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); + p_Scheme->netEnvParams.unitIds[0] = res; + + res = FmPcdNetEnvGetUnitId( + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); + p_Scheme->netEnvParams.unitIds[1] = res; + + /* Configures scheme's next engine parameters*/ + p_Scheme->nextEngine = e_FM_PCD_CC; + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; + p_Scheme->kgNextEngineParams.cc.grpId = groupId; + p_Scheme->useHash = TRUE; + + /* Configures scheme's key*/ + if (ipv4 == TRUE) + { + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4; + p_Scheme->keyExtractAndHashParams.extractArray[0].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = + e_FM_PCD_EXTRACT_FULL_FIELD; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = + HEADER_TYPE_IPv4; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 = + NET_HEADER_FIELD_IPv4_DST_IP; + p_Scheme->keyExtractAndHashParams.extractArray[1].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = + e_FM_PCD_EXTRACT_FULL_FIELD; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = + HEADER_TYPE_IPv4; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 = + NET_HEADER_FIELD_IPv4_SRC_IP; + p_Scheme->keyExtractAndHashParams.extractArray[2].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = + e_FM_PCD_EXTRACT_FULL_FIELD; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = + HEADER_TYPE_IPv4; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 = + NET_HEADER_FIELD_IPv4_PROTO; + p_Scheme->keyExtractAndHashParams.extractArray[3].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr = + HEADER_TYPE_IPv4; + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type = + e_FM_PCD_EXTRACT_FROM_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation = + FALSE; + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size = + 2; + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset = + 4; + } + else /* IPv6 */ + { + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3; + p_Scheme->keyExtractAndHashParams.extractArray[0].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = + e_FM_PCD_EXTRACT_FULL_FIELD; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = + HEADER_TYPE_IPv6; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 = + NET_HEADER_FIELD_IPv6_DST_IP; + p_Scheme->keyExtractAndHashParams.extractArray[1].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = + e_FM_PCD_EXTRACT_FULL_FIELD; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = + HEADER_TYPE_IPv6; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 = + NET_HEADER_FIELD_IPv6_SRC_IP; + p_Scheme->keyExtractAndHashParams.extractArray[2].type = + e_FM_PCD_EXTRACT_BY_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = + HEADER_TYPE_USER_DEFINED_SHIM2; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = + e_FM_PCD_EXTRACT_FROM_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size = + 4; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset = + 4; + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation = + TRUE; + } + + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304; + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314; + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++) + { + p_Scheme->keyExtractAndHashParams.dflts[j].type = + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */ + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect = + e_FM_PCD_KG_DFLT_GBL_0; + } +} + +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip, + t_FmPcdManipReassemIpStats *p_Stats) +{ + ASSERT_COND(p_Manip); + ASSERT_COND(p_Stats); + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); + + p_Stats->timeout = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); + p_Stats->rfdPoolBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); + p_Stats->internalBufferBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); + p_Stats->externalBufferBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); + p_Stats->sgFragments = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); + p_Stats->dmaSemaphoreDepletion = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); +#if (DPAA_VERSION >= 11) + p_Stats->nonConsistentSp = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); +#endif /* (DPAA_VERSION >= 11) */ + + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) + { + p_Stats->specificHdrStatistics[0].successfullyReassembled = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter); + p_Stats->specificHdrStatistics[0].validFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter); + p_Stats->specificHdrStatistics[0].processedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter); + p_Stats->specificHdrStatistics[0].malformedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter); + p_Stats->specificHdrStatistics[0].autoLearnBusy = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter); + p_Stats->specificHdrStatistics[0].discardedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter); + p_Stats->specificHdrStatistics[0].moreThan16Fragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter); + } + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) + { + p_Stats->specificHdrStatistics[1].successfullyReassembled = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter); + p_Stats->specificHdrStatistics[1].validFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter); + p_Stats->specificHdrStatistics[1].processedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter); + p_Stats->specificHdrStatistics[1].malformedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter); + p_Stats->specificHdrStatistics[1].autoLearnBusy = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter); + p_Stats->specificHdrStatistics[1].discardedFragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter); + p_Stats->specificHdrStatistics[1].moreThan16Fragments = + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter); + } + return E_OK; +} + +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip, + t_FmPcdManipFragIpStats *p_Stats) +{ + t_AdOfTypeContLookup *p_Ad; + + ASSERT_COND(p_Manip); + ASSERT_COND(p_Stats); + ASSERT_COND(p_Manip->h_Ad); + ASSERT_COND(p_Manip->fragParams.p_Frag); + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase) + & 0x00ffffff; + p_Stats->generatedFragments = + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr); + + return E_OK; +} + +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams, + t_FmPcdManip *p_Manip) +{ + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; + t_FmPcd *p_FmPcd; +#if (DPAA_VERSION == 10) + t_Error err = E_OK; +#endif /* (DPAA_VERSION == 10) */ + + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, + E_INVALID_VALUE); + + p_FmPcd = p_Manip->h_FmPcd; + /* Allocation of fragmentation Action Descriptor */ + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->fragParams.p_Frag) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM alloc for Fragmentation table descriptor")); + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION; + + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; + ccAdBaseReg |= (p_ManipParams->dontFragAction + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT); + + + /* Set Scatter/Gather BPid */ + if (p_ManipParams->sgBpidEn) + { + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN; + pcAndOffsetsReg |= ((p_ManipParams->sgBpid + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT) + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK); + } + + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)) + - p_FmPcd->physicalMuramBase); +#if (DPAA_VERSION == 10) + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; +#else + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; +#endif /* (DPAA_VERSION == 10) */ + + /* Set all Ad registers */ + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); + + /* Saves user's fragmentation manipulation parameters */ + p_Manip->frag = TRUE; + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; + +#if (DPAA_VERSION == 10) + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid; + + /* scratch buffer pool initialization */ + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK) + { + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); + p_Manip->fragParams.p_Frag = NULL; + RETURN_ERROR(MAJOR, err, NO_MSG); + } +#endif /* (DPAA_VERSION == 10) */ + + return E_OK; +} + +static t_Error IPManip(t_FmPcdManip *p_Manip) +{ + t_Error err = E_OK; + t_FmPcd *p_FmPcd; + t_AdOfTypeContLookup *p_Ad; + uint32_t tmpReg32 = 0, tmpRegNia = 0; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + p_FmPcd = p_Manip->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION; + if (p_Manip->frag == TRUE) + { + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) + - (p_FmPcd->physicalMuramBase)); + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation + << FM_PCD_MANIP_IP_MTU_SHIFT; + } + + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; + tmpReg32 |= HMAN_OC_IP_MANIP; + +#if (DPAA_VERSION >= 11) + tmpRegNia |= FM_PCD_MANIP_IP_CNIA; +#endif /* (DPAA_VERSION >= 11) */ + + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); + WRITE_UINT32(p_Ad->gmask, 0); + /* Total frame counter - MUST be initialized to zero.*/ + + return err; +} + +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_FmPcdManip *p_Manip, + t_Handle h_Ad, bool validate) +{ + t_FmPortGetSetCcParams fmPortGetSetCcParams; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION), + E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + + UNUSED(h_FmPcd); + UNUSED(h_Ad); + UNUSED(h_PcdParams); + UNUSED(validate); + UNUSED(p_Manip); + + fmPortGetSetCcParams.setCcParams.type = 0; + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) + DBG(WARNING, ("manipExtraSpace must be larger than '0'")); + + return E_OK; +} + +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, + t_FmPcdManip *p_Manip) +{ + t_AdOfTypeContLookup *p_Ad; + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams; + t_Error err = E_OK; + uint32_t tmpReg32 = 0; + uint32_t power; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); + + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec; + + SANITY_CHECK_RETURN_ERROR( + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption, + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR( + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption, + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR( + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen, + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR( + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr, + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR( + !p_IPSecParams->arwSize || p_IPSecParams->decryption, + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE); + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0; + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0; + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0; + tmpReg32 |= + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0; + tmpReg32 |= + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0; + if (p_IPSecParams->arwSize) + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM) + & (FM_MURAM_SIZE-1)); + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); + + tmpReg32 = 0; + if (p_IPSecParams->arwSize) { + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power); + LOG2(power, power); + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT; + } + + if (p_ManipParams->h_NextManip) + tmpReg32 |= + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4; + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); + + tmpReg32 = HMAN_OC_IPSEC_MANIP; + tmpReg32 |= p_IPSecParams->outerIPHdrLen + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT; + if (p_ManipParams->h_NextManip) + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN; + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); + + return err; +} + +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; + + /* Allocation if CAPWAP Action descriptor */ + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart( + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->reassmParams.capwap.h_Ad) + { + ReleaseManipHandler(p_Manip, p_FmPcd); + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("Allocation of CAPWAP table descriptor")); + } + + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */ + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP); +} + +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd, + t_FmPcdKgSchemeParams *p_Scheme, + t_Handle h_CcTree, uint8_t groupId) +{ + uint8_t res; + + /* Configures scheme's network environment parameters */ + p_Scheme->netEnvParams.numOfDistinctionUnits = 1; + res = FmPcdNetEnvGetUnitId( + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); + p_Scheme->netEnvParams.unitIds[0] = res; + + /* Configures scheme's next engine parameters*/ + p_Scheme->nextEngine = e_FM_PCD_CC; + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; + p_Scheme->kgNextEngineParams.cc.grpId = groupId; + p_Scheme->useHash = TRUE; + + /* Configures scheme's key*/ + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2; + p_Scheme->keyExtractAndHashParams.extractArray[0].type = + e_FM_PCD_EXTRACT_NON_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src = + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action = + e_FM_PCD_ACTION_NONE; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20; + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4; + p_Scheme->keyExtractAndHashParams.extractArray[1].type = + e_FM_PCD_EXTRACT_NON_HDR; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src = + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action = + e_FM_PCD_ACTION_NONE; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0; + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1; + + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0; + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0; + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1; + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0; +} + +#if (DPAA_VERSION >= 11) +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip, + t_FmPcdManipReassemCapwapStats *p_Stats) +{ + ASSERT_COND(p_Manip); + ASSERT_COND(p_Stats); + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); + + p_Stats->timeout = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); + p_Stats->rfdPoolBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); + p_Stats->internalBufferBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); + p_Stats->externalBufferBusy = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); + p_Stats->sgFragments = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); + p_Stats->dmaSemaphoreDepletion = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); + p_Stats->exceedMaxReassemblyFrameLen = + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); + + p_Stats->successfullyReassembled = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter); + p_Stats->validFragments = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter); + p_Stats->processedFragments = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter); + p_Stats->malformedFragments = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter); + p_Stats->autoLearnBusy = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter); + p_Stats->discardedFragments = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter); + p_Stats->moreThan16Fragments = + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter); + + return E_OK; +} + +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip, + t_FmPcdManipFragCapwapStats *p_Stats) +{ + t_AdOfTypeContLookup *p_Ad; + + ASSERT_COND(p_Manip); + ASSERT_COND(p_Stats); + ASSERT_COND(p_Manip->h_Ad); + ASSERT_COND(p_Manip->fragParams.p_Frag); + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); + + return E_OK; +} + +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, + t_FmPcdManip *p_Manip) +{ + uint32_t maxSetNumber = 10000; + t_FmPcdManipReassemCapwapParams reassmManipParams = + p_ManipReassmParams->u.capwapReassem; + t_Error res; + + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, + E_INVALID_HANDLE); + + /* Check validation of user's parameter.*/ + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); + /* It is recommended that the total number of entries in this table (number of sets * number of ways) + will be twice the number of frames that are expected to be reassembled simultaneously.*/ + if (reassmManipParams.maxNumFramesInProcess + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); + + /* Saves user's reassembly manipulation parameters */ + p_Manip->reassmParams.capwap.relativeSchemeId = + reassmManipParams.relativeSchemeId; + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry = + reassmManipParams.numOfFramesPerHashEntry; + p_Manip->reassmParams.capwap.maxRessembledsSize = + reassmManipParams.maxReassembledFrameLength; + p_Manip->reassmParams.maxNumFramesInProcess = + reassmManipParams.maxNumFramesInProcess; + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; + p_Manip->reassmParams.fqidForTimeOutFrames = + reassmManipParams.fqidForTimeOutFrames; + p_Manip->reassmParams.timeoutThresholdForReassmProcess = + reassmManipParams.timeoutThresholdForReassmProcess; + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; + + /* Creates and initializes the Reassembly common parameter table */ + CreateReassCommonTable(p_Manip); + + res = SetCapwapReassmManip(p_Manip); + if (res != E_OK) + return res; + + return E_OK; +} + +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams, + t_FmPcdManip *p_Manip) +{ + t_FmPcd *p_FmPcd; + t_AdOfTypeContLookup *p_Ad; + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; + uint32_t tmpReg32 = 0, tmpRegNia = 0; + + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, + E_INVALID_VALUE); + p_FmPcd = p_Manip->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + /* Allocation of fragmentation Action Descriptor */ + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->fragParams.p_Frag) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("MURAM alloc for Fragmentation table descriptor")); + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; + + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; + ccAdBaseReg |= + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN : + 0; + + /* Set Scatter/Gather BPid */ + if (p_ManipParams->sgBpidEn) + { + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN; + pcAndOffsetsReg |= ((p_ManipParams->sgBpid + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT) + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK); + } + + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)) + - p_FmPcd->physicalMuramBase); + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; + + /* Set all Ad registers */ + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); + + /* Saves user's fragmentation manipulation parameters */ + p_Manip->frag = TRUE; + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) + - (p_FmPcd->physicalMuramBase)); + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT; + + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK; + + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA; + + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); + WRITE_UINT32(p_Ad->gmask, 0); + /* Total frame counter - MUST be initialized to zero.*/ + + return E_OK; +} + +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_FmPcdManip *p_Manip, + t_Handle h_Ad, bool validate) +{ + t_FmPortGetSetCcParams fmPortGetSetCcParams; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION), + E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + + UNUSED(h_FmPcd); + UNUSED(h_Ad); + UNUSED(h_PcdParams); + UNUSED(validate); + UNUSED(p_Manip); + + fmPortGetSetCcParams.setCcParams.type = 0; + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) + DBG(WARNING, ("manipExtraSpace must be larger than '0'")); + + return E_OK; +} + +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams, + t_FmPcdManip *p_Manip) +{ + t_AdOfTypeContLookup *p_Ad; + t_FmPcdManipSpecialOffloadCapwapParams *p_Params; + t_Error err = E_OK; + uint32_t tmpReg32 = 0; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); + + p_Params = &p_ManipParams->u.specialOffload.u.capwap; + + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0; + /* TODO - add 'qosSrc' */ + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); + + tmpReg32 = HMAN_OC_CAPWAP_MANIP; + if (p_ManipParams->h_NextManip) + { + WRITE_UINT32( + p_Ad->matchTblPtr, + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); + + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN; + } + + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); + + return err; +} +#endif /* (DPAA_VERSION >= 11) */ + +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, + bool stats) +{ + t_FmPcdManip *p_Manip; + t_Error err; + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); - if(!p_Manip) + if (!p_Manip) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); return NULL; } memset(p_Manip, 0, sizeof(t_FmPcdManip)); - if(!stats) - { - err = CheckManipParamsAndSetType(p_Manip, (t_FmPcdManipParams *)p_Params); - } + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type; + memcpy((uint8_t*)&p_Manip->manipParams, p_Params, + sizeof(p_Manip->manipParams)); + + if (!stats) + err = CheckManipParamsAndSetType(p_Manip, + (t_FmPcdManipParams *)p_Params); +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + else + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params); +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ else { - err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params); + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!")); + XX_Free(p_Manip); + return NULL; } - - if(err) +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + if (err) { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("INVALID HEADER MANIPULATION TYPE")); - ReleaseManipHandler(p_Manip, p_FmPcd); + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type")); XX_Free(p_Manip); return NULL; } -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - if(p_Manip->type != HMAN_OC_IP_REASSEMBLY) + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY)) { -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ - if(p_Manip->muramAllocate) - { - p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, - FM_PCD_CC_AD_ENTRY_SIZE, - FM_PCD_CC_AD_TABLE_ALIGN); - if(!p_Manip->h_Ad) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } + /* In Case of reassembly manipulation the reassembly action descriptor will + be defines later on */ + if (p_Manip->muramAllocate) + { + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem( + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_Manip->h_Ad) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + } - IOMemSet32(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); - } - else - { - p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); - if(!p_Manip->h_Ad) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + } + else + { + p_Manip->h_Ad = (t_Handle)XX_Malloc( + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); + if (!p_Manip->h_Ad) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + } - memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); + } } -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - } -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ + p_Manip->h_FmPcd = h_FmPcd; return p_Manip; } +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst) +{ + t_CcNodeInformation *p_CcNodeInformation; + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL; + t_List *p_Pos; + int i = 0; + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; + t_CcNodeInformation ccNodeInfo; -t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify) + NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst) + { + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); + p_NodePtrOnCurrentMdfManip = + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; + + ASSERT_COND(p_NodePtrOnCurrentMdfManip); + + /* Search in the previous node which exact index points on this current modified node for getting AD */ + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++) + { + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine + == e_FM_PCD_CC) + { + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip + == (t_Handle)p_CrntMdfManip) + { + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj) + p_AdTablePtOnCrntCurrentMdfNode = + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; + else + p_AdTablePtOnCrntCurrentMdfNode = + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); + + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL); + } + } + } + + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys); + } +} + +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd, + t_FmPcd *p_FmPcd) { t_Error err; - if(!modify) + /* Copy the HMTD */ + MemCpy8(p_Dest, (uint8_t*)p_Src, 16); + /* Replace the HMCT table pointer */ + WRITE_UINT32( + ((t_Hmtd *)p_Dest)->hmcdBasePtr, + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase)); + /* Call Host Command to replace HMTD by a new HMTD */ + err = FmHcPcdCcDoDynamicChange( + p_FmPcd->h_Hc, + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase), + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase)); + if (err) + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners.")); +} + +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_Handle h_Manip, + t_Handle h_Ad, bool validate, int level, + t_Handle h_FmTree) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); + + UNUSED(level); + UNUSED(h_FmTree); + + switch (p_Manip->opcode) { - err = FmPcdManipInitUpdate(h_FmPcd, h_FmPort, h_Manip, h_Ad, validate, level, h_FmTree); - } - else - { - err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree); +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, + p_Manip, + h_Ad, + validate); + break; + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): + if (!p_Manip->h_Frag) + break; + case (HMAN_OC_CAPWAP_FRAGMENTATION): + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree); + break; + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + if (p_Manip->h_Frag) + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate); + break; + case (HMAN_OC_CAPWAP_INDEXED_STATS): + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip); + break; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + case (HMAN_OC_IP_REASSEMBLY): + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, + validate); + break; + case (HMAN_OC_IP_FRAGMENTATION): + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, + h_Ad, validate); + break; +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_FRAGMENTATION): + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, + h_Ad, validate); + break; + case (HMAN_OC_CAPWAP_REASSEMBLY): + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, + validate); + break; +#endif /* (DPAA_VERSION >= 11) */ + default: + return E_OK; } + return err; } -uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip) +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, + bool validate, int level, + t_Handle h_FmTree) { + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_Error err = E_OK; - ASSERT_COND(h_Manip); + UNUSED(level); - switch(p_Manip->type) + switch (p_Manip->opcode) { - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - return UPDATE_NIA_ENQ_WITHOUT_DMA; +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("modify node with this type of manipulation is not suppported")); + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + + if (p_Manip->h_Frag) + { + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function")); + } + break; + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): + if (p_Manip->h_Frag) + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree); + break; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ default: - return 0; + return E_OK; } + + return err; +} + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, + bool validate, int level, t_Handle h_FmTree, + bool modify) +{ + t_Error err; + + if (!modify) + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip, + h_Ad, validate, level, h_FmTree); + else + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree); + + return err; } void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add) { - if(add) + uint32_t intFlags; + + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock); + if (add) ((t_FmPcdManip *)h_Manip)->owner++; else { ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner); ((t_FmPcdManip *)h_Manip)->owner--; } + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags); } -t_Error FmPcdManipCheckParamsForCcNextEgine(t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, uint32_t *requiredAction) +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip) { - t_FmPcdManip *p_Manip; - t_Error err; + ASSERT_COND(h_Manip); + return &((t_FmPcdManip *)h_Manip)->nodesLst; +} +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip) +{ + ASSERT_COND(h_Manip); + return ((t_FmPcdManip *)h_Manip)->h_Spinlock; +} + +t_Error FmPcdManipCheckParamsForCcNextEngine( + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, + uint32_t *requiredAction) +{ + t_FmPcdManip *p_Manip; +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + t_Error err = E_OK; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/ + bool pointFromCc = TRUE; SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); - SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, + E_NULL_POINTER); p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip); *requiredAction = 0; - switch(p_Manip->type) - { - case(HMAN_OC_CAPWAP_INDEXED_STATS): - if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); - if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) - p_Manip->cnia = TRUE; - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; - case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): - p_Manip->ownerTmp++; - break; - case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): - if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE")); - p_Manip->ownerTmp++; - break; - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC) && - (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) != CC_PC_GENERIC_IC_HASH_INDEXED)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP")); - err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; - break; -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) - case(HMAN_OC_IPSEC): - if((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_DONE) && - !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) - p_Manip->cnia = FALSE; - else - p_Manip->cnia = TRUE; - if(!p_Manip->h_Frag) - { + while (p_Manip) + { + switch (p_Manip->opcode) + { +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_CAPWAP_INDEXED_STATS): + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) + p_Manip->cnia = TRUE; + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): p_Manip->ownerTmp++; break; - } -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - case(HMAN_OC_IP_FRAGMENTATION): - if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); - p_Manip->ownerTmp++; - break; -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ - break; -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */ - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE,("invalid type of header manipulation for this state")); + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE")); + p_Manip->ownerTmp++; + break; + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC) + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) + != CC_PC_GENERIC_IC_HASH_INDEXED)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP")); + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; + break; + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + case (HMAN_OC_IP_FRAGMENTATION): + case (HMAN_OC_IP_REASSEMBLY): +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_REASSEMBLY): + case (HMAN_OC_CAPWAP_FRAGMENTATION): +#endif /* (DPAA_VERSION >= 11) */ + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); + p_Manip->ownerTmp++; + break; + case (HMAN_OC_IPSEC_MANIP): +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_MANIP): +#endif /* (DPAA_VERSION >= 11) */ + p_Manip->ownerTmp++; + break; + case (HMAN_OC): + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) + && MANIP_IS_CASCADED(p_Manip)) + RETURN_ERROR( + MINOR, + E_INVALID_STATE, + ("Can't have a cascaded manipulation when and Next Engine is CC")); + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)")); + break; + default: + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("invalid type of header manipulation for this state")); + } + p_Manip = p_Manip->h_NextManip; + pointFromCc = FALSE; } - return E_OK; } -t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode) + +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, + t_Handle h_FmPcdCcNode) { t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; - t_Error err = E_OK; + t_Error err = E_OK; SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE); - switch(p_Manip->type) + switch (p_Manip->opcode) { - case(HMAN_OC_CAPWAP_INDEXED_STATS): - if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys")); +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_CAPWAP_INDEXED_STATS): + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys")); break; - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - if(p_Manip->h_Frag) - { - if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys")); - err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode)); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - } - break; + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + if (p_Manip->h_Frag) + { + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys")); + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode)); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + break; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ default: break; } + return err; } -void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew) +void FmPcdManipUpdateAdResultForCc( + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams, + t_Handle p_Ad, t_Handle *p_AdNewPtr) { - t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + + /* This routine creates a Manip AD and can return in "p_AdNewPtr" + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ ASSERT_COND(p_Manip); + ASSERT_COND(p_CcNextEngineParams); + ASSERT_COND(p_Ad); + ASSERT_COND(p_AdNewPtr); FmPcdManipUpdateOwner(h_Manip, TRUE); - switch(p_Manip->type) + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */ + switch (p_Manip->opcode) { - case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): - case(HMAN_OC_CAPWAP_INDEXED_STATS): -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) - case(HMAN_OC_IP_FRAGMENTATION): - case(HMAN_OC_IP_REASSEMBLY): -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */ - *p_AdNew = p_Manip->h_Ad; +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + case (HMAN_OC_CAPWAP_INDEXED_STATS): + *p_AdNewPtr = p_Manip->h_Ad; + break; + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): + case (HMAN_OC_CAPWAP_FRAGMENTATION): + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid); + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile); + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia); + *p_AdNewPtr = NULL; + break; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + case (HMAN_OC_IPSEC_MANIP): +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_MANIP): +#endif /* (DPAA_VERSION >= 11) */ + *p_AdNewPtr = p_Manip->h_Ad; break; - case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): - case(HMAN_OC_CAPWAP_FRAGMENTATION): - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid); - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile); - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia); - *p_AdNew = NULL; - break; -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) - case(HMAN_OC_IPSEC): - if (p_Manip->cnia) - *p_AdNew = p_Manip->h_Ad; - else + case (HMAN_OC_IP_FRAGMENTATION): +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_FRAGMENTATION): +#endif /* (DPAA_VERSION >= 11) */ + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE) + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid)) { - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid); - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile); - WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia); - *p_AdNew = NULL; + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad, + sizeof(t_AdOfTypeContLookup)); +#if (DPAA_VERSION >= 11) + WRITE_UINT32( + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA); +#endif /* (DPAA_VERSION >= 11) */ + *p_AdNewPtr = NULL; } + else + *p_AdNewPtr = p_Manip->h_Ad; + break; + case (HMAN_OC_IP_REASSEMBLY): + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip)) + { + if (!p_Manip->reassmParams.ip.ipv6Assigned) + { + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad; + p_Manip->reassmParams.ip.ipv6Assigned = TRUE; + FmPcdManipUpdateOwner(h_Manip, FALSE); + } + else + { + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; + p_Manip->reassmParams.ip.ipv6Assigned = FALSE; + } + } + else + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, + sizeof(t_AdOfTypeContLookup)); + *p_AdNewPtr = NULL; + break; +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_REASSEMBLY): + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad; + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, + sizeof(t_AdOfTypeContLookup)); + *p_AdNewPtr = NULL; + break; +#endif /* (DPAA_VERSION >= 11) */ + case (HMAN_OC): + /* Allocate and initialize HMTD */ + *p_AdNewPtr = p_Manip->h_Ad; break; -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */ default: break; } } -void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset) +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, + t_Handle *p_AdNewPtr, + uint32_t adTableOffset) { - t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + /* This routine creates a Manip AD and can return in "p_AdNewPtr" + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ ASSERT_COND(p_Manip); FmPcdManipUpdateOwner(h_Manip, TRUE); - switch(p_Manip->type) + switch (p_Manip->opcode) { - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase); - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr); - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets); - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask); - WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset)); - *p_AdNew = NULL; +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase); + WRITE_UINT32( + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr, + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr); + WRITE_UINT32( + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets); + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask, + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask); + WRITE_UINT32( + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset)); + *p_AdNewPtr = NULL; + break; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + case (HMAN_OC): + /* Initialize HMTD within the match table*/ + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); + /* copy the existing HMTD *//* ask Alla - memcpy??? */ + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd)); + /* update NADEN to be "1"*/ + WRITE_UINT16( + ((t_Hmtd *)p_Ad)->cfg, + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN)); + /* update next action descriptor */ + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx, + (uint16_t)(adTableOffset >> 4)); + /* mark that Manip's HMTD is not used */ + *p_AdNewPtr = NULL; break; + default: break; } } -t_Handle FM_PCD_ManipSetNode(t_Handle h_FmPcd, t_FmPcdManipParams *p_ManipParams) +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, + t_Handle h_CcTree, t_Handle h_Manip, + bool isIpv4, uint8_t groupId) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdManip *p_Manip; - t_Error err; + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_FmPcdKgSchemeParams *p_SchemeParams = NULL; + t_Handle h_Scheme; - SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); - SANITY_CHECK_RETURN_VALUE(p_ManipParams,E_INVALID_HANDLE,NULL); + ASSERT_COND(p_FmPcd); + ASSERT_COND(h_NetEnv); + ASSERT_COND(p_Manip); + /* scheme was already build, no need to check for IPv6 */ + if (p_Manip->reassmParams.ip.h_Ipv4Scheme) + return E_OK; - p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE); - if(!p_Manip) + if (isIpv4) { + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]); + if (h_Scheme) { + /* scheme was found */ + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme; + return E_OK; + } + } else { + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]); + if (h_Scheme) { + /* scheme was found */ + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme; + return E_OK; + } + } + + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); + if (!p_SchemeParams) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("Memory allocation failed for scheme")); + + /* Configures the IPv4 or IPv6 scheme*/ + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; + p_SchemeParams->id.relativeSchemeId = (uint8_t)( + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] : + p_Manip->reassmParams.ip.relativeSchemeId[1]); + p_SchemeParams->schemeCounter.update = TRUE; +#if (DPAA_VERSION >= 11) + p_SchemeParams->alwaysDirect = TRUE; + p_SchemeParams->bypassFqidGeneration = TRUE; +#else + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1; + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/ +#endif /* (DPAA_VERSION >= 11) */ + + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId); + + /* Sets the new scheme */ + if (isIpv4) + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet( + p_FmPcd, p_SchemeParams); + else + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet( + p_FmPcd, p_SchemeParams); + + XX_Free(p_SchemeParams); + + return E_OK; +} + +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + + ASSERT_COND(p_Manip); + + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) && + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme)) + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme); + + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) && + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme)) + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme); + + return E_OK; +} + +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + + ASSERT_COND(p_Manip); + + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6); +} + +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, + t_Handle h_CcTree, t_Handle h_Manip, + uint8_t groupId) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + t_FmPcdKgSchemeParams *p_SchemeParams = NULL; + + ASSERT_COND(p_FmPcd); + ASSERT_COND(h_NetEnv); + ASSERT_COND(p_Manip); + + /* scheme was already build, no need to check for IPv6 */ + if (p_Manip->reassmParams.capwap.h_Scheme) + return E_OK; + + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); + if (!p_SchemeParams) + RETURN_ERROR(MAJOR, E_NO_MEMORY, + ("Memory allocation failed for scheme")); + + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; + p_SchemeParams->id.relativeSchemeId = + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId; + p_SchemeParams->schemeCounter.update = TRUE; + p_SchemeParams->bypassFqidGeneration = TRUE; + + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId); + + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd, + p_SchemeParams); + + XX_Free(p_SchemeParams); + + return E_OK; +} + +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + + ASSERT_COND(p_Manip); + + if (p_Manip->reassmParams.capwap.h_Scheme) + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme); + + return E_OK; +} + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) +t_Handle FmPcdManipApplSpecificBuild(void) +{ + t_FmPcdManip *p_Manip; + + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); + if (!p_Manip) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); + return NULL; + } + memset(p_Manip, 0, sizeof(t_FmPcdManip)); + + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; + p_Manip->muramAllocate = FALSE; + + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); + if (!p_Manip->h_Ad) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); + XX_Free(p_Manip); + return NULL; + } + + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); + + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/ + /*Application specific = type of flowId index, move internal frame header from data to IC, + SEC errors check*/ + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK) + { + XX_Free(p_Manip->h_Ad); + XX_Free(p_Manip); + return NULL; + } + return p_Manip; +} + +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; + ASSERT_COND(h_Manip); + + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE); +} +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ +/*********************** End of inter-module routines ************************/ + +/****************************************/ +/* API Init unit functions */ +/****************************************/ + +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, + t_FmPcdManipParams *p_ManipParams) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdManip *p_Manip; + t_Error err; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL); + + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE); + if (!p_Manip) return NULL; - switch(p_Manip->type) + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION) + || (p_Manip->opcode == HMAN_OC) + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP) +#if (DPAA_VERSION >= 11) + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP) + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) +#endif /* (DPAA_VERSION >= 11) */ + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd))) { - case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): - /* HmanType1 */ - err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->rmvParams, p_Manip); - break; -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - case(HMAN_OC_IP_REASSEMBLY): + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled")); + XX_Free(p_Manip); + return NULL; + } + p_Manip->h_Spinlock = XX_InitSpinlock(); + if (!p_Manip->h_Spinlock) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + }INIT_LIST(&p_Manip->nodesLst); + + switch (p_Manip->opcode) + { + case (HMAN_OC_IP_REASSEMBLY): /* IpReassembly */ - err = IpReassembly(&p_ManipParams->fragOrReasmParams, p_Manip, p_FmPcd); - if(err) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip); break; - case(HMAN_OC_IP_FRAGMENTATION): + case (HMAN_OC_IP_FRAGMENTATION): /* IpFragmentation */ - err = IpFragmentation(&p_ManipParams->fragOrReasmParams.ipFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx); - if(err) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ -#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)) - case(HMAN_OC_IPSEC) : - err = IPSecManip(p_ManipParams, p_Manip, p_FmPcd); + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip); + if (err) + break; + err = IPManip(p_Manip); break; -#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */ -#ifdef FM_CAPWAP_SUPPORT - case(HMAN_OC_CAPWAP_FRAGMENTATION): + case (HMAN_OC_IPSEC_MANIP): + err = IPSecManip(p_ManipParams, p_Manip); + break; +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_REASSEMBLY): + /* CapwapReassembly */ + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip); + break; + case (HMAN_OC_CAPWAP_FRAGMENTATION): /* CapwapFragmentation */ - err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.capwapFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx); - if(err) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } - if(p_Manip->insrt) - p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; - case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): - /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */ - err = InsrtHdrByTempl(&p_ManipParams->insrtParams, p_Manip, p_FmPcd); + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag, + p_Manip); break; - case(HMAN_OC_CAPWAP_REASSEMBLY) : - /*CAPWAP Reassembly*/ - err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.capwapReasmParams,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx); - if(err) + case (HMAN_OC_CAPWAP_MANIP): + err = CapwapManip(p_ManipParams, p_Manip); + break; +#endif /* (DPAA_VERSION >= 11) */ +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): + /* HmanType1 */ + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip); + break; + case (HMAN_OC_CAPWAP_FRAGMENTATION): + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams, + p_Manip, + p_FmPcd, + p_ManipParams->fragOrReasmParams.sgBpid); + if (err) { REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); ReleaseManipHandler(p_Manip, p_FmPcd); XX_Free(p_Manip); return NULL; } - if(p_Manip->rmv) - p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; - case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): + if (p_Manip->insrt) + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */ + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd); + break; + case (HMAN_OC_CAPWAP_REASSEMBLY): + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams, + p_Manip, + p_FmPcd, + p_ManipParams->fragOrReasmParams.sgBpid); + if (err) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + } + if (p_Manip->rmv) + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/ err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip); break; -#endif /* FM_CAPWAP_SUPPORT */ - case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): /*Application Specific type 1*/ - err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, (bool)(p_ManipParams->treatFdStatusFieldsAsErrors ? TRUE : FALSE)); + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE); break; - default: - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + case (HMAN_OC): + /* New Manip */ + err = CreateManipActionNew(p_Manip, p_ManipParams); + break; + default: + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; } - if(err) - { - REPORT_ERROR(MAJOR, err, NO_MSG); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } - return p_Manip; + + if (err) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + } + + if (p_ManipParams->h_NextManip) + { + /* in the check routine we've verified that h_NextManip has no owners + * and that only supported types are allowed. */ + p_Manip->h_NextManip = p_ManipParams->h_NextManip; + /* save a "prev" pointer in h_NextManip */ + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip); + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE); + } + + return p_Manip; } -t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_ManipNode) +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip, + t_FmPcdManipParams *p_ManipParams) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip; + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd); + t_Error err; + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL; + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos; + t_CcNodeInformation *p_CcNodeInfo; + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip); - if(p_Manip->owner) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("This manipulation node not be removed because this node is occupied, first - unbind this node ")); + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR) + || (p_Manip->type != e_FM_PCD_MANIP_HDR)) + RETURN_ERROR( + MINOR, + E_NOT_SUPPORTED, + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation.")); - ReleaseManipHandler(p_Manip,p_FmPcd); + ASSERT_COND(p_Manip->opcode == HMAN_OC); + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip); + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams, + sizeof(p_Manip->manipParams)); + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip; + + /* The replacement of the HdrManip depends on the node type.*/ + /* + * (1) If this is an independent node, all its owners should be updated. + * + * (2) If it is the head of a cascaded chain (it does not have a "prev" but + * it has a "next" and it has a "cascaded" indication), the next + * node remains unchanged, and the behavior is as in (1). + * + * (3) If it is not the head, but a part of a cascaded chain, in can be + * also replaced as a regular node with just one owner. + * + * (4) If it is a part of a chain implemented as a unified table, the + * whole table is replaced and the owners of the head node must be updated. + * + */ + /* lock shadow */ + if (!p_FmPcd->p_CcShadow) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); + + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + return ERROR_CODE(E_BUSY); + + /* this routine creates a new manip action in the CC Shadow. */ + err = CreateManipActionShadow(p_Manip, p_ManipParams); + if (err) + RETURN_ERROR(MINOR, err, NO_MSG); + + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC) + * replace only HMTD and no lcok is required. Otherwise + * lock the whole PCD + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */ + if (!FmPcdLockTryLockAll(p_FmPcd)) + { + DBG(TRACE, ("FmPcdLockTryLockAll failed")); + return ERROR_CODE(E_BUSY); + } + + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); + + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip, + e_MANIP_HANDLER_TABLE_OWNER); + ASSERT_COND(p_FirstManip); + + if (!NCSW_LIST_IsEmpty(&p_FirstManip->nodesLst)) + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip); + + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); + ASSERT_COND(p_Hmtd); + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct, + ((t_FmPcd*)(p_Manip->h_FmPcd))); + + NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) + { + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); + } + + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); + ASSERT_COND(p_WholeHmct); + + /* re-build the HMCT n the original location */ + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams); + if (err) + { + RELEASE_LOCK(p_FmPcd->shadowLock); + RETURN_ERROR(MINOR, err, NO_MSG); + } + + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); + ASSERT_COND(p_Hmtd); + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct, + ((t_FmPcd*)p_Manip->h_FmPcd)); + + /* If NCSW_LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list. + * For each p_Hmct (from list+fixed): + * call Host Command to replace HMTD by a new one */NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) + { + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); + } + + + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip); + + FmPcdLockUnlockAll(p_FmPcd); + + /* unlock shadow */ + RELEASE_LOCK(p_FmPcd->shadowLock); + + return E_OK; +} + +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + + if (p_Manip->owner) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("This manipulation node not be removed because this node is occupied, first - unbind this node ")); + + if (p_Manip->h_NextManip) + { + MANIP_SET_PREV(p_Manip->h_NextManip, NULL); + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE); + } + + if (p_Manip->p_Hmct + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip))) + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, + p_Manip->p_Hmct); + + if (p_Manip->h_Spinlock) + { + XX_FreeSpinlock(p_Manip->h_Spinlock); + p_Manip->h_Spinlock = NULL; + } + + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd); XX_Free(h_ManipNode); return E_OK; } +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, + t_FmPcdManipStats *p_FmPcdManipStats) +{ + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; + + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER); + + switch (p_Manip->opcode) + { + case (HMAN_OC_IP_REASSEMBLY): + return IpReassemblyStats(p_Manip, + &p_FmPcdManipStats->u.reassem.u.ipReassem); + case (HMAN_OC_IP_FRAGMENTATION): + return IpFragmentationStats(p_Manip, + &p_FmPcdManipStats->u.frag.u.ipFrag); +#if (DPAA_VERSION >= 11) + case (HMAN_OC_CAPWAP_REASSEMBLY): + return CapwapReassemblyStats( + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem); + case (HMAN_OC_CAPWAP_FRAGMENTATION): + return CapwapFragmentationStats( + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag); +#endif /* (DPAA_VERSION >= 11) */ + default: + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("no statistics to this type of manip")); + } + + return E_OK; +} + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdManip *p_Manip; - t_Error err; + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdManip *p_Manip; + t_Error err; SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL); - p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE); - if(!p_Manip) - return NULL; + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE); + if (!p_Manip) + return NULL; - switch(p_Manip->type) + switch (p_Manip->opcode) { - case(HMAN_OC_CAPWAP_INDEXED_STATS): - /* Indexed statistics */ - err = IndxStats(p_StatsParams, p_Manip, p_FmPcd); - break; - default: - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type")); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - + case (HMAN_OC_CAPWAP_INDEXED_STATS): + /* Indexed statistics */ + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd); + break; + default: + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type")); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; } - if(err) - { - REPORT_ERROR(MAJOR, err, NO_MSG); - ReleaseManipHandler(p_Manip, p_FmPcd); - XX_Free(p_Manip); - return NULL; - } - return p_Manip; -} -#endif /* FM_CAPWAP_SUPPORT */ -#endif /* CONFIG_FMAN_P1023 */ + if (err) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + ReleaseManipHandler(p_Manip, p_FmPcd); + XX_Free(p_Manip); + return NULL; + } + + return p_Manip; +} +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h index dbe9c1d4da0a..853bb834dedf 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_manip.h @@ -49,30 +50,46 @@ /* Header manipulations defines */ /***********************************************************************/ +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/ + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) #define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e #define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31 -#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33 -#define HMAN_OC_IPSEC 0x34 -#define HMAN_OC_IP_FRAGMENTATION 0x74 -#define HMAN_OC_IP_REASSEMBLY 0xB4 #define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f #define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30 #define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */ #define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */ +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33 +#else +#define HMAN_OC_CAPWAP_MANIP 0x2F +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ +#define HMAN_OC_IP_MANIP 0x34 +#define HMAN_OC_IP_FRAGMENTATION 0x74 +#define HMAN_OC_IP_REASSEMBLY 0xB4 +#define HMAN_OC_IPSEC_MANIP 0xF4 +#define HMAN_OC 0x35 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) #define HMAN_RMV_HDR 0x80000000 #define HMAN_INSRT_INT_FRM_HDR 0x40000000 -#define UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP 6 -#define UDP_UDPCHECKSUM_FIELD_SIZE 2 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6 +#define UDP_CHECKSUM_FIELD_SIZE 2 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4 -#define IP_DSCECN_FIELD_OFFSET_FROM_IP 1 -#define IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2 -#define IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10 #define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12 -#define IP_ID_FIELD_OFFSET_FROM_IP 4 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4 -#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 80 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6 + +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80 #define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8 #define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32 #define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4 @@ -89,28 +106,219 @@ #define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4 #define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000 #define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -#define FM_PCD_MANIP_IPSEC_CALC_UDP_LENGTH 0x01000000 -#define FM_PCD_MANIP_IPSEC_CNIA 0x20000000 +#if (DPAA_VERSION >= 11) +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000 -#define e_FM_MANIP_CAPWAP_INDX 0 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000 -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY -#define FM_PCD_MANIP_IP_REASM_TABLE_SIZE 0x40 -#define FM_PCD_MANIP_IP_REASM_TABLE_ALIGN 8 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24 +#endif /* (DPAA_VERSION >= 11) */ + +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8 + +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024 + +#define FM_PCD_MANIP_IP_MTU_SHIFT 16 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000 +#define FM_PCD_MANIP_IP_CNIA 0x20000000 + +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24 + +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000 + +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16 + +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16 -#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE 64 -#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN 8 -#define FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000 #define e_FM_MANIP_IP_INDX 1 -#define FM_PCD_MANIP_IP_REASM_LIODN_MASK 0x000003F0 -#define FM_PCD_MANIP_IP_REASM_LIODN_SHIFT 56 -#define FM_PCD_MANIP_IP_REASM_ELIODN_MASK 0x0000000F -#define FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT 44 -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ +#define HMCD_OPCODE_GENERIC_RMV 0x01 +#define HMCD_OPCODE_GENERIC_INSRT 0x02 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05 +#define HMCD_OPCODE_L2_RMV 0x08 +#define HMCD_OPCODE_L2_INSRT 0x09 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B +#define HMCD_OPCODE_IPV4_UPDATE 0x0C +#define HMCD_OPCODE_IPV6_UPDATE 0x10 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14 +#define HMCD_OPCODE_REPLACE_IP 0x12 +#define HMCD_OPCODE_RMV_TILL 0x15 +#define HMCD_OPCODE_UDP_INSRT 0x16 +#define HMCD_OPCODE_IP_INSRT 0x17 +#define HMCD_OPCODE_CAPWAP_RMV 0x18 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19 + +#define HMCD_LAST 0x00800000 + +#define HMCD_DSCP_VALUES 64 + +#define HMCD_BASIC_SIZE 4 +#define HMCD_PTR_SIZE 4 +#define HMCD_PARAM_SIZE 4 +#define HMCD_IPV4_ADDR_SIZE 4 +#define HMCD_IPV6_ADDR_SIZE 0x10 +#define HMCD_L4_HDR_SIZE 8 + +#define HMCD_CAPWAP_INSRT 0x00010000 +#define HMCD_INSRT_UDP_LITE 0x00010000 +#define HMCD_IP_ID_MASK 0x0000FFFF +#define HMCD_IP_SIZE_MASK 0x0000FF00 +#define HMCD_IP_SIZE_SHIFT 8 +#define HMCD_IP_LAST_PID_MASK 0x000000FF +#define HMCD_IP_OR_QOS 0x00010000 +#define HMCD_IP_L4_CS_CALC 0x00040000 +#define HMCD_IP_DF_MODE 0x00400000 +#define HMCD_OC_SHIFT 24 + +#define HMCD_RMV_OFFSET_SHIFT 0 +#define HMCD_RMV_SIZE_SHIFT 8 + +#define HMCD_INSRT_OFFSET_SHIFT 0 +#define HMCD_INSRT_SIZE_SHIFT 8 + +#define HMTD_CFG_TYPE 0x4000 +#define HMTD_CFG_EXT_HMCT 0x0080 +#define HMTD_CFG_PRS_AFTER_HM 0x0040 +#define HMTD_CFG_NEXT_AD_EN 0x0020 + +#define HMCD_RMV_L2_ETHERNET 0 +#define HMCD_RMV_L2_STACKED_QTAGS 1 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2 +#define HMCD_RMV_L2_MPLS 3 +#define HMCD_RMV_L2_PPPOE 4 + +#define HMCD_INSRT_L2_MPLS 0 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1 +#define HMCD_INSRT_L2_PPPOE 2 +#define HMCD_INSRT_L2_SIZE_SHIFT 24 + +#define HMCD_L2_MODE_SHIFT 16 + +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16 +#define HMCD_VLAN_PRI_UPDATE 0 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1 + +#define HMCD_IPV4_UPDATE_TTL 0x00000001 +#define HMCD_IPV4_UPDATE_TOS 0x00000002 +#define HMCD_IPV4_UPDATE_DST 0x00000020 +#define HMCD_IPV4_UPDATE_SRC 0x00000040 +#define HMCD_IPV4_UPDATE_ID 0x00000080 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8 + +#define HMCD_IPV6_UPDATE_HL 0x00000001 +#define HMCD_IPV6_UPDATE_TC 0x00000002 +#define HMCD_IPV6_UPDATE_DST 0x00000040 +#define HMCD_IPV6_UPDATE_SRC 0x00000080 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8 + +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16 + +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000 +#define HMCD_IP_REPLACE_ID 0x00400000 + +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24 + +#define HMCD_GEN_FIELD_SIZE_SHIFT 16 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000 + +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16 +#define HMCD_GEN_FIELD_MASK_SHIFT 24 + +#define DSCP_TO_VLAN_TABLE_SIZE 32 + +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize) +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize) + +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct) +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data) + +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr) +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr) + +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad) +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip) +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev) +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner) +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type) +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE) +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram) +#define MANIP_FREE_HMTD(h_Manip) \ + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \ + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\ + else \ + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \ + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \ + } +/* position regarding Manip SW structure */ +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip)) +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded) +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)) +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \ + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)) +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\ + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID)) +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST) + +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \ + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \ + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID) + +typedef enum e_ManipUnifiedPosition { + e_MANIP_UNIFIED_NONE = 0, + e_MANIP_UNIFIED_FIRST, + e_MANIP_UNIFIED_MID, + e_MANIP_UNIFIED_LAST +} e_ManipUnifiedPosition; + +typedef enum e_ManipInfo { + e_MANIP_HMTD, + e_MANIP_HMCT, + e_MANIP_HANDLER_TABLE_OWNER +}e_ManipInfo; /***********************************************************************/ /* Memory map */ /***********************************************************************/ @@ -118,7 +326,8 @@ #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -typedef _Packed struct { +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) +typedef struct t_CapwapReasmPram { volatile uint32_t mode; volatile uint32_t autoLearnHashTblPtr; volatile uint32_t intStatsTblPtr; @@ -141,20 +350,20 @@ typedef _Packed struct { volatile uint32_t totalMoreThan16FramesCounter; volatile uint32_t internalBufferBusy; volatile uint32_t externalBufferBusy; - volatile uint8_t res[16]; -} _PackedType t_CapwapReasmPram; + volatile uint32_t reserved1[4]; +} t_CapwapReasmPram; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY -typedef _Packed struct t_IpReasmPram{ +typedef _Packed struct t_ReassTbl { volatile uint16_t waysNumAndSetSize; volatile uint16_t autoLearnHashKeyMask; - volatile uint32_t ipReassCommonPrmTblPtr; + volatile uint32_t reassCommonPrmTblPtr; volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi; volatile uint32_t autoLearnHashTblPtrLow; volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi; volatile uint32_t autoLearnSetLockTblPtrLow; - volatile uint16_t minFragSize; - volatile uint16_t reserved1; + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/ + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/ volatile uint32_t totalSuccessfullyReasmFramesCounter; volatile uint32_t totalValidFragmentCounter; volatile uint32_t totalProcessedFragCounter; @@ -163,27 +372,38 @@ typedef _Packed struct t_IpReasmPram{ volatile uint32_t totalDiscardedFragsCounter; volatile uint32_t totalMoreThan16FramesCounter; volatile uint32_t reserved2[2]; -} _PackedType t_IpReasmPram; +} _PackedType t_ReassTbl; -typedef _Packed struct t_IpReasmCommonTbl{ +typedef struct t_ReassCommonTbl { volatile uint32_t timeoutModeAndFqid; volatile uint32_t reassFrmDescIndexPoolTblPtr; volatile uint32_t liodnAndReassFrmDescPoolPtrHi; volatile uint32_t reassFrmDescPoolPtrLow; volatile uint32_t timeOutTblPtr; volatile uint32_t expirationDelay; - volatile uint32_t reseervd1; - volatile uint32_t reseervd2; + volatile uint32_t internalBufferManagement; + volatile uint32_t reserved2; volatile uint32_t totalTimeOutCounter; volatile uint32_t totalRfdPoolBusyCounter; volatile uint32_t totalInternalBufferBusy; volatile uint32_t totalExternalBufferBusy; - volatile uint32_t reserved3[4]; -} _PackedType t_IpReasmCommonTbl; + volatile uint32_t totalSgFragmentCounter; + volatile uint32_t totalDmaSemaphoreDepletionCounter; + volatile uint32_t totalNCSPCounter; + volatile uint32_t discardMask; +} t_ReassCommonTbl; -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ +typedef _Packed struct t_Hmtd { + volatile uint16_t cfg; + volatile uint8_t eliodnOffset; + volatile uint8_t extHmcdBasePtrHi; + volatile uint32_t hmcdBasePtr; + volatile uint16_t nextAdIdx; + volatile uint8_t res1; + volatile uint8_t opCode; + volatile uint32_t res2; +} _PackedType t_Hmtd; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -192,98 +412,125 @@ typedef _Packed struct t_IpReasmCommonTbl{ /***********************************************************************/ /* Driver's internal structures */ /***********************************************************************/ - +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) typedef struct { t_Handle p_AutoLearnHashTbl; t_Handle p_ReassmFrmDescrPoolTbl; t_Handle p_ReassmFrmDescrIndxPoolTbl; t_Handle p_TimeOutTbl; - uint8_t maxNumFramesInProcess; + uint16_t maxNumFramesInProcess; uint8_t numOfTasks; - uint8_t poolId; + //uint8_t poolId; uint8_t prOffset; uint16_t dataOffset; - uint8_t poolIndx; + uint8_t sgBpid; uint8_t hwPortId; uint32_t fqidForTimeOutFrames; uint32_t timeoutRoutineRequestTime; uint32_t bitFor1Micro; -} t_FragParams; +} t_CapwapFragParams; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY typedef struct { - t_Handle h_Frag; - t_Handle h_FragId; - uint8_t poolId; - uint16_t dataOffset; - uint8_t poolIndx; -}t_IpFragParams; + t_AdOfTypeContLookup *p_Frag; +#if (DPAA_VERSION == 10) + uint8_t scratchBpid; +#endif /* (DPAA_VERSION == 10) */ +} t_FragParams; -typedef struct t_IpReassmParams +typedef struct t_ReassmParams { - t_Handle h_Ipv4Ad; - t_Handle h_Ipv6Ad; - e_NetHeaderType hdr; /**< Header selection */ - uint32_t fqidForTimeOutFrames; - uint16_t dataOffset; - t_Handle h_IpReassCommonParamsTbl; - t_Handle h_Ipv4ReassParamsTblPtr; - t_Handle h_Ipv6ReassParamsTblPtr; - t_Handle h_Ipv4AutoLearnHashTbl; - t_Handle h_Ipv6AutoLearnHashTbl; - t_Handle h_Ipv4AutoLearnSetLockTblPtr; - t_Handle h_Ipv6AutoLearnSetLockTblPtr; - t_Handle h_ReassmFrmDescrIndxPoolTbl; - t_Handle h_ReassmFrmDescrPoolTbl; - t_Handle h_TimeOutTbl; - uint32_t maxNumFramesInProcess; - uint32_t liodnOffset; - uint32_t minFragSize; - uint8_t dataMemId; /**< Memory partition ID for data buffers */ - uint32_t bpid; + e_NetHeaderType hdr; /* Header selection */ + t_ReassCommonTbl *p_ReassCommonTbl; + uintptr_t reassFrmDescrIndxPoolTblAddr; + uintptr_t reassFrmDescrPoolTblAddr; + uintptr_t timeOutTblAddr; + uintptr_t internalBufferPoolManagementIndexAddr; + uintptr_t internalBufferPoolAddr; + uint32_t maxNumFramesInProcess; + uint8_t sgBpid; + uint8_t dataMemId; + uint16_t dataLiodnOffset; + uint32_t fqidForTimeOutFrames; e_FmPcdManipReassemTimeOutMode timeOutMode; - e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry; uint32_t timeoutThresholdForReassmProcess; - -}t_IpReassmParams; - -typedef struct t_IpCommonReassmParams -{ - uint8_t numOfTasks; - uint32_t bitFor1Micro; - t_Handle h_ReassmFrmDescrPoolTbl; - t_Handle h_ReassmFrmDescrIndxPoolTbl; - t_Handle h_TimeOutTbl; -}t_IpCommonReassmParams; - -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ + union { + struct { + t_Handle h_Ipv4Ad; + t_Handle h_Ipv6Ad; + bool ipv6Assigned; + t_ReassTbl *p_Ipv4ReassTbl; + t_ReassTbl *p_Ipv6ReassTbl; + uintptr_t ipv4AutoLearnHashTblAddr; + uintptr_t ipv6AutoLearnHashTblAddr; + uintptr_t ipv4AutoLearnSetLockTblAddr; + uintptr_t ipv6AutoLearnSetLockTblAddr; + uint16_t minFragSize[2]; + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2]; + uint8_t relativeSchemeId[2]; + t_Handle h_Ipv4Scheme; + t_Handle h_Ipv6Scheme; + uint32_t nonConsistentSpFqid; + } ip; + struct { + t_Handle h_Ad; + t_ReassTbl *p_ReassTbl; + uintptr_t autoLearnHashTblAddr; + uintptr_t autoLearnSetLockTblAddr; + uint16_t maxRessembledsSize; + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry; + uint8_t relativeSchemeId; + t_Handle h_Scheme; + } capwap; + }; +} t_ReassmParams; typedef struct{ - bool muramAllocate; - t_Handle h_Ad; - uint32_t type; - bool rmv; - bool insrt; - uint8_t *p_Template; - t_Handle h_Frag; - bool frag; - bool reassm; - uint16_t sizeForFragmentation; - uint8_t owner; - uint32_t updateParams; - uint32_t shadowUpdateParams; - t_FragParams fragParams; -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY - t_IpReassmParams ipReassmParams; - t_IpFragParams ipFragParams; -#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */ - uint8_t icOffset; - uint16_t ownerTmp; - bool cnia; - t_Handle p_StatsTbl; - t_Handle h_FmPcd; + e_FmPcdManipType type; + t_FmPcdManipParams manipParams; + bool muramAllocate; + t_Handle h_Ad; + uint32_t opcode; + bool rmv; + bool insrt; + t_Handle h_NextManip; + t_Handle h_PrevManip; + e_FmPcdManipType nextManipType; + /* HdrManip parameters*/ + uint8_t *p_Hmct; + uint8_t *p_Data; + bool dontParseAfterManip; + bool fieldUpdate; + bool custom; + uint16_t tableSize; + uint8_t dataSize; + bool cascaded; + e_ManipUnifiedPosition unifiedPosition; + /* end HdrManip */ + uint8_t *p_Template; + uint16_t owner; + uint32_t updateParams; + uint32_t shadowUpdateParams; + bool frag; + bool reassm; + uint16_t sizeForFragmentation; +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + t_Handle h_Frag; + t_CapwapFragParams capwapFragParams; +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ + union { + t_ReassmParams reassmParams; + t_FragParams fragParams; + }; + uint8_t icOffset; + uint16_t ownerTmp; + bool cnia; + t_Handle p_StatsTbl; + t_Handle h_FmPcd; + t_List nodesLst; + t_Handle h_Spinlock; } t_FmPcdManip; typedef struct t_FmPcdCcSavedManipParams @@ -293,15 +540,13 @@ typedef struct t_FmPcdCcSavedManipParams struct { uint16_t dataOffset; - uint8_t poolId; + //uint8_t poolId; }capwapParams; -#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY struct { uint16_t dataOffset; uint8_t poolId; }ipParams; -#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/ }; } t_FmPcdCcSavedManipParams; diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c index e3af876627c2..48d650d0607f 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_pcd.c @@ -49,28 +50,33 @@ #include "fm_pcd.h" #include "fm_pcd_ipc.h" #include "fm_hc.h" +#include "fm_muram_ext.h" +/****************************************/ +/* static functions */ +/****************************************/ + static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd) { - if(!p_FmPcd->h_Fm) + if (!p_FmPcd->h_Fm) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized")); - if(p_FmPcd->guestId == NCSW_MASTER_ID) + if (p_FmPcd->guestId == NCSW_MASTER_ID) { - if(p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs) + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); - if(p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs) + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); - if(!p_FmPcd->f_Exception) + if (!p_FmPcd->f_Exception) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized")); - if((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg)) + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized")); - if(p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT) + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191")); } @@ -78,21 +84,21 @@ static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd) } static volatile bool blockingFlag = FALSE; -static void FmPcdIpcMsgCompletionCB(t_Handle h_FmPcd, - uint8_t *p_Msg, - uint8_t *p_Reply, - uint32_t replyLength, - t_Error status) +static void IpcMsgCompletionCB(t_Handle h_FmPcd, + uint8_t *p_Msg, + uint8_t *p_Reply, + uint32_t replyLength, + t_Error status) { UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); blockingFlag = FALSE; } -static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, - uint8_t *p_Msg, - uint32_t msgLength, - uint8_t *p_Reply, - uint32_t *p_ReplyLength) +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd, + uint8_t *p_Msg, + uint32_t msgLength, + uint8_t *p_Reply, + uint32_t *p_ReplyLength) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; t_Error err = E_OK; @@ -111,7 +117,7 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE)); *p_ReplyLength = 0; - switch(p_IpcMsg->msgId) + switch (p_IpcMsg->msgId) { case (FM_PCD_MASTER_IS_ALIVE): *(uint8_t*)(p_IpcReply->replyBody) = 1; @@ -120,14 +126,14 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, break; case (FM_PCD_MASTER_IS_ENABLED): /* count partitions registrations */ - if(p_FmPcd->enabled) + if (p_FmPcd->enabled) p_FmPcd->numOfEnabledGuestPartitionsPcds++; *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled; p_IpcReply->error = E_OK; *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); break; case (FM_PCD_GUEST_DISABLE): - if(p_FmPcd->numOfEnabledGuestPartitionsPcds) + if (p_FmPcd->numOfEnabledGuestPartitionsPcds) { p_FmPcd->numOfEnabledGuestPartitionsPcds--; p_IpcReply->error = E_OK; @@ -139,7 +145,7 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, } *p_ReplyLength = sizeof(uint32_t); break; - case(FM_PCD_GET_COUNTER): + case (FM_PCD_GET_COUNTER): { e_FmPcdCounters inCounter; uint32_t outCounter; @@ -196,91 +202,54 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams)); KgFreeClsPlanEntries(h_FmPcd, - ipcKgClsPlanParams.numOfClsPlanEntries, - ipcKgClsPlanParams.guestId, - ipcKgClsPlanParams.clsPlanBase); + ipcKgClsPlanParams.numOfClsPlanEntries, + ipcKgClsPlanParams.guestId, + ipcKgClsPlanParams.clsPlanBase); *p_ReplyLength = sizeof(uint32_t); break; } case (FM_PCD_ALLOC_PROFILES): { - t_FmPcdIpcPlcrAllocParams ipcPlcrAllocParams; - uint16_t profilesBase; - - memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams)); - err = PlcrAllocProfiles(h_FmPcd, - ipcPlcrAllocParams.hardwarePortId, - ipcPlcrAllocParams.num, - &profilesBase); - memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesBase, sizeof(uint16_t)); - p_IpcReply->error = err; + t_FmIpcResourceAllocParams ipcAllocParams; + uint16_t base; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + base = PlcrAllocProfilesForPartition(h_FmPcd, + ipcAllocParams.base, + ipcAllocParams.num, + ipcAllocParams.guestId); + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t)); *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t); break; } case (FM_PCD_FREE_PROFILES): { - t_FmPcdIpcPlcrAllocParams ipcPlcrAllocParams; - - memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams)); - err = PlcrFreeProfiles(h_FmPcd, - ipcPlcrAllocParams.hardwarePortId, - ipcPlcrAllocParams.num, - ipcPlcrAllocParams.plcrProfilesBase); - p_IpcReply->error = err; - *p_ReplyLength = sizeof(uint32_t); + t_FmIpcResourceAllocParams ipcAllocParams; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + PlcrFreeProfilesForPartition(h_FmPcd, + ipcAllocParams.base, + ipcAllocParams.num, + ipcAllocParams.guestId); break; } - case (FM_PCD_ALLOC_SHARED_PROFILES): + case (FM_PCD_SET_PORT_PROFILES): { - uint16_t numOfProfiles; - uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES]; - uint32_t profilesMask[FM_PCD_PLCR_NUM_ENTRIES/32]; - int i; - - memset(profilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t)); - memcpy((uint8_t*)&numOfProfiles, p_IpcMsg->msgBody, sizeof(uint16_t)); - err = PlcrAllocSharedProfiles(h_FmPcd, - numOfProfiles, - profilesIds); - p_IpcReply->error = err; - - /* translate the allocated profile id's to a 32bit * 8regs mask */ - for(i = 0;i> (profilesIds[i] % 32)); - - memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesMask, sizeof(profilesMask)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(profilesMask); /* num-of-shared-profiles */ + t_FmIpcResourceAllocParams ipcAllocParams; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + PlcrSetPortProfiles(h_FmPcd, + ipcAllocParams.guestId, + ipcAllocParams.num, + ipcAllocParams.base); break; } - case (FM_PCD_FREE_SHARED_PROFILES): + case (FM_PCD_CLEAR_PORT_PROFILES): { - t_FmPcdIpcSharedPlcrAllocParams ipcSharedPlcrAllocParams; - uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES]; - int i,j, index = 0; - uint32_t walking1Mask = 0x80000000; - - memset(profilesIds, 0, FM_PCD_PLCR_NUM_ENTRIES*sizeof(uint16_t)); - memcpy((uint8_t*)&ipcSharedPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSharedPlcrAllocParams)); - for(i = 0; i>= 1; - } - walking1Mask = 0x80000000; - } - } - - PlcrFreeSharedProfiles(h_FmPcd, - ipcSharedPlcrAllocParams.num, - profilesIds); + t_FmIpcResourceAllocParams ipcAllocParams; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + PlcrClearPortProfiles(h_FmPcd, + ipcAllocParams.guestId); break; } - case(FM_PCD_GET_SW_PRS_OFFSET): + case (FM_PCD_GET_SW_PRS_OFFSET): { t_FmPcdIpcSwPrsLable ipcSwPrsLable; uint32_t swPrsOffset; @@ -294,7 +263,7 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); break; } - case(FM_PCD_PRS_INC_PORT_STATS): + case (FM_PCD_PRS_INC_PORT_STATS): { t_FmPcdIpcPrsIncludePort ipcPrsIncludePort; @@ -304,33 +273,6 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, ipcPrsIncludePort.include); break; } -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) - case(FM_PCD_DUMP_REGS): - if((err = FM_PCD_DumpRegs(h_FmPcd)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - case(FM_PCD_KG_DUMP_REGS): - if((err = FM_PCD_KgDumpRegs(h_FmPcd)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - case(FM_PCD_PLCR_DUMP_REGS): - if((err = FM_PCD_PlcrDumpRegs(h_FmPcd)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - case(FM_PCD_PLCR_PROFILE_DUMP_REGS): - { - t_Handle h_Profile; - memcpy((uint8_t*)&h_Profile, p_IpcMsg->msgBody, sizeof(t_Handle)); - if((err = FM_PCD_PlcrProfileDumpRegs(h_FmPcd, h_Profile)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - - } - case(FM_PCD_PRS_DUMP_REGS): - if((err = FM_PCD_PrsDumpRegs(h_FmPcd)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; -#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ default: *p_ReplyLength = 0; RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); @@ -338,8 +280,99 @@ static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd, return E_OK; } +static uint32_t NetEnvLock(t_Handle h_NetEnv) +{ + ASSERT_COND(h_NetEnv); + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock); +} + +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags) +{ + ASSERT_COND(h_NetEnv); + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags); +} + +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) +{ + uint32_t intFlags; + + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); + NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst); + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); +} + +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd) +{ + t_FmPcdLock *p_Lock = NULL; + uint32_t intFlags; + + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); + if (!NCSW_LIST_IsEmpty(&p_FmPcd->freeLocksLst)) + { + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next); + NCSW_LIST_DelAndInit(&p_Lock->node); + } + if (p_FmPcd->h_Spinlock) + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); + + return p_Lock; +} + +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) +{ + uint32_t intFlags; + + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); + NCSW_LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst); + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); +} + +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd) +{ + t_FmPcdLock *p_Lock; + int i; + + for (i=0; i<10; i++) + { + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock)); + if (!p_Lock) + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!")); + memset(p_Lock, 0, sizeof(t_FmPcdLock)); + INIT_LIST(&p_Lock->node); + p_Lock->h_Spinlock = XX_InitSpinlock(); + if (!p_Lock->h_Spinlock) + { + XX_Free(p_Lock); + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!")); + } + EnqueueLockToFreeLst(p_FmPcd, p_Lock); + } + + return E_OK; +} + +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd) +{ + t_FmPcdLock *p_Lock; + + p_Lock = DequeueLockFromFreeLst(p_FmPcd); + while (p_Lock) + { + XX_FreeSpinlock(p_Lock->h_Spinlock); + XX_Free(p_Lock); + p_Lock = DequeueLockFromFreeLst(p_FmPcd); + } +} + + + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId) { + ASSERT_COND(p_FmPcd); p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId; } @@ -348,7 +381,8 @@ t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpP uint8_t netEnvId = p_GrpParams->netEnvId; int i, k, j; - if(p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN) + ASSERT_COND(p_FmPcd); + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN) { p_GrpParams->grpExists = TRUE; p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId; @@ -362,16 +396,16 @@ t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpP (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) { /* if an option exists, add it to the opts list */ - if(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) { /* check if this option already exists, add if it doesn't */ - for(j = 0;jnumOfOptions;j++) + for (j = 0;jnumOfOptions;j++) { - if(p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) break; } p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i]; - if(j == p_GrpParams->numOfOptions) + if (j == p_GrpParams->numOfOptions) { p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt; p_GrpParams->numOfOptions++; @@ -380,9 +414,9 @@ t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpP } } - if(p_GrpParams->numOfOptions == 0) + if (p_GrpParams->numOfOptions == 0) { - if(p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN) + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN) { p_GrpParams->grpExists = TRUE; p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId; @@ -399,6 +433,7 @@ t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt *p_Vector = 0; + ASSERT_COND(p_FmPcd); for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++) { @@ -420,10 +455,13 @@ t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params) { int i; + ASSERT_COND(p_FmPcd); + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS); + p_Params->vector = 0; - for(i=0; inumOfDistinctionUnits ;i++) + for (i=0; inumOfDistinctionUnits ;i++) { - if(p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE) + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module")); ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]); p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]; @@ -435,6 +473,8 @@ t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params) bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector) { int i=0, k; + + ASSERT_COND(p_FmPcd); /* check whether a given unit may be used by non-clsPlan users. */ /* first, recognize the unit by its vector */ while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE) @@ -446,7 +486,7 @@ bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t uni (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) /* check that no option exists */ - if((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) return FALSE; break; } @@ -472,7 +512,7 @@ bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) return TRUE; } - for (i=0; ((i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) && + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++) { if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) @@ -482,13 +522,87 @@ bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType return FALSE; } +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt) +{ + uint8_t i, k; + + ASSERT_COND(p_FmPcd); + + if (interchangeable) + { + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) + { + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) + { + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt)) + + return i; + } + } + } + else + { + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) && + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE)) + return i; + + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) && + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt)) + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr; + } + + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS; +} + +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0}; + uint8_t result; + t_Error err = E_OK; + + ASSERT_COND(p_FmPcd); + ASSERT_COND(h_ReasmCommonPramTbl); + + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/ + + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + switch (result) + { + case (0): + return E_OK; + case (1): + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); + case (2): + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); + case (3): + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT")); + default: + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); + } + + return E_OK; +} + e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr) { int i; ASSERT_COND(p_FmPcd); + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS); - for (i=0; (i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) { if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) @@ -503,8 +617,8 @@ void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePo t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; uint16_t swPortIndex = 0; + ASSERT_COND(h_FmPcd); HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); - p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort; } @@ -512,6 +626,7 @@ uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + ASSERT_COND(h_FmPcd); return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum]; } @@ -519,40 +634,154 @@ uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + ASSERT_COND(h_FmPcd); return p_FmPcd->netEnvs[netEnvId].macsecVector; } +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv) +{ + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId; +} + void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) { + uint32_t intFlags; + + ASSERT_COND(h_FmPcd); + + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++; + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); } void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) { + uint32_t intFlags; + + ASSERT_COND(h_FmPcd); ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners); + + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--; + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); } uint32_t FmPcdLock(t_Handle h_FmPcd) { + ASSERT_COND(h_FmPcd); return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock); } void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags) { + ASSERT_COND(h_FmPcd); XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags); } +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd) +{ + t_FmPcdLock *p_Lock; + ASSERT_COND(h_FmPcd); + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); + if (!p_Lock) + { + FillFreeLocksLst(h_FmPcd); + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); + } + + if (p_Lock) + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock); + return p_Lock; +} + +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock) +{ + uint32_t intFlags; + ASSERT_COND(h_FmPcd); + intFlags = FmPcdLock(h_FmPcd); + NCSW_LIST_DelAndInit(&p_Lock->node); + FmPcdUnlock(h_FmPcd, intFlags); + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock); +} + +bool FmPcdLockTryLockAll(t_Handle h_FmPcd) +{ + uint32_t intFlags; + t_List *p_Pos, *p_SavedPos=NULL; + + ASSERT_COND(h_FmPcd); + intFlags = FmPcdLock(h_FmPcd); + NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) + { + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); + if (!FmPcdLockTryLock(p_Lock)) + { + p_SavedPos = p_Pos; + break; + } + } + if (p_SavedPos) + { + NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) + { + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); + if (p_Pos == p_SavedPos) + break; + FmPcdLockUnlock(p_Lock); + } + } + FmPcdUnlock(h_FmPcd, intFlags); + + CORE_MemoryBarrier(); + + if (p_SavedPos) + return FALSE; + + return TRUE; +} + +void FmPcdLockUnlockAll(t_Handle h_FmPcd) +{ + uint32_t intFlags; + t_List *p_Pos; + + ASSERT_COND(h_FmPcd); + intFlags = FmPcdLock(h_FmPcd); + NCSW_LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) + { + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); + p_Lock->flag = FALSE; + } + FmPcdUnlock(h_FmPcd, intFlags); + + CORE_MemoryBarrier(); +} + +t_Error FmPcdHcSync(t_Handle h_FmPcd) +{ + ASSERT_COND(h_FmPcd); + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc); + + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc); +} + t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd) { ASSERT_COND(h_FmPcd); - SANITY_CHECK_RETURN_VALUE(((t_FmPcd*)h_FmPcd)->h_Hc, E_INVALID_HANDLE, NULL); return ((t_FmPcd*)h_FmPcd)->h_Hc; } -/**********************************************************************************************************/ -/* API */ -/**********************************************************************************************************/ +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd) +{ + ASSERT_COND(h_FmPcd); + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport; +} +/*********************** End of inter-module routines ************************/ + + +/****************************************/ +/* API Init unit functions */ +/****************************************/ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) { @@ -565,7 +794,7 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd)); if (!p_FmPcd) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD")); return NULL; } memset(p_FmPcd, 0, sizeof(t_FmPcd)); @@ -574,7 +803,7 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) if (!p_FmPcd->p_FmPcdDriverParam) { XX_Free(p_FmPcd); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Driver Param")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param")); return NULL; } memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam)); @@ -582,10 +811,13 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) p_FmPcd->h_Fm = p_FmPcdParams->h_Fm; p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm); p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm); - FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase); - p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32)); + if (p_FmPcd->h_FmMuram) + { + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase); + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32)); + } - for(i = 0; inetEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN; if (p_FmPcdParams->useHostCommand) @@ -599,42 +831,42 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams); if (!p_FmPcd->h_Hc) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd HC")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC")); FM_PCD_Free(p_FmPcd); return NULL; } } - else if(p_FmPcd->guestId != NCSW_MASTER_ID) + else if (p_FmPcd->guestId != NCSW_MASTER_ID) REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition.")); - if(p_FmPcdParams->kgSupport) + if (p_FmPcdParams->kgSupport) { p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams); - if(!p_FmPcd->p_FmPcdKg) + if (!p_FmPcd->p_FmPcdKg) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Keygen")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen")); FM_PCD_Free(p_FmPcd); return NULL; } } - if(p_FmPcdParams->plcrSupport) + if (p_FmPcdParams->plcrSupport) { p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams); - if(!p_FmPcd->p_FmPcdPlcr) + if (!p_FmPcd->p_FmPcdPlcr) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Policer")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer")); FM_PCD_Free(p_FmPcd); return NULL; } } - if(p_FmPcdParams->prsSupport) + if (p_FmPcdParams->prsSupport) { p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams); - if(!p_FmPcd->p_FmPcdPrs) + if (!p_FmPcd->p_FmPcdPrs) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Parser")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser")); FM_PCD_Free(p_FmPcd); return NULL; } @@ -643,10 +875,12 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) p_FmPcd->h_Spinlock = XX_InitSpinlock(); if (!p_FmPcd->h_Spinlock) { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd spinlock")); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock")); FM_PCD_Free(p_FmPcd); return NULL; } + INIT_LIST(&p_FmPcd->freeLocksLst); + INIT_LIST(&p_FmPcd->acquiredLocksLst); p_FmPcd->numOfEnabledGuestPartitionsPcds = 0; @@ -654,6 +888,18 @@ t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId; p_FmPcd->h_App = p_FmPcdParams->h_App; + p_FmPcd->p_CcShadow = NULL; + p_FmPcd->ccShadowSize = 0; + p_FmPcd->ccShadowAlign = 0; + + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock(); + if (!p_FmPcd->h_ShadowSpinlock) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock")); + FM_PCD_Free(p_FmPcd); + return NULL; + } + return p_FmPcd; } @@ -666,81 +912,101 @@ t_Error FM_PCD_Init(t_Handle h_FmPcd) SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - uint8_t isMasterAlive = 0; - t_FmPcdIpcReply reply; - uint32_t replyLength; + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo); + if (p_FmPcd->guestId != NCSW_MASTER_ID) + { memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10) + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11)) + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11)) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName); - if (p_FmPcd->h_IpcSession == NULL) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM PCD Guest %d IPC session", p_FmPcd->guestId)); - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_PCD_MASTER_IS_ALIVE; - msg.msgBody[0] = p_FmPcd->guestId; - blockingFlag = TRUE; - - do + if (p_FmPcd->h_IpcSession) { - replyLength = sizeof(uint32_t) + sizeof(isMasterAlive); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(p_FmPcd->guestId), - (uint8_t*)&reply, - &replyLength, - FmPcdIpcMsgCompletionCB, - h_FmPcd)) != E_OK) - REPORT_ERROR(MAJOR, err, NO_MSG); - while(blockingFlag) ; - if(replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive))) - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - isMasterAlive = *(uint8_t*)(reply.replyBody); - } while (!isMasterAlive); + t_FmPcdIpcReply reply; + uint32_t replyLength; + uint8_t isMasterAlive = 0; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_PCD_MASTER_IS_ALIVE; + msg.msgBody[0] = p_FmPcd->guestId; + blockingFlag = TRUE; + + do + { + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive); + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId), + (uint8_t*)&reply, + &replyLength, + IpcMsgCompletionCB, + h_FmPcd)) != E_OK) + REPORT_ERROR(MAJOR, err, NO_MSG); + while (blockingFlag) ; + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive))) + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + isMasterAlive = *(uint8_t*)(reply.replyBody); + } while (!isMasterAlive); + } } CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters); - if(p_FmPcd->p_FmPcdKg) + if (p_FmPcd->p_FmPcdKg) { err = KgInit(p_FmPcd); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); } - if(p_FmPcd->p_FmPcdPlcr) + if (p_FmPcd->p_FmPcdPlcr) { err = PlcrInit(p_FmPcd); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); } - if(p_FmPcd->p_FmPcdPrs) + if (p_FmPcd->p_FmPcdPrs) { err = PrsInit(p_FmPcd); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); } - if(p_FmPcd->guestId == NCSW_MASTER_ID) + if (p_FmPcd->guestId == NCSW_MASTER_ID) { /* register to inter-core messaging mechanism */ memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10) + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); - err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, FmPcdHandleIpcMsgCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE); - if(err) + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); } + /* IPv6 Frame-Id used for fragmentation */ + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4)); + if (!p_FmPcd->ipv6FrameIdAddr) + { + FM_PCD_Free(p_FmPcd); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id")); + } + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4); + + /* CAPWAP Frame-Id used for fragmentation */ + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4)); + if (!p_FmPcd->capwapFrameIdAddr) + { + FM_PCD_Free(p_FmPcd); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id")); + } + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2); + XX_Free(p_FmPcd->p_FmPcdDriverParam); p_FmPcd->p_FmPcdDriverParam = NULL; @@ -754,36 +1020,39 @@ t_Error FM_PCD_Free(t_Handle h_FmPcd) t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd; t_Error err = E_OK; - if(p_FmPcd->enabled) + if (p_FmPcd->ipv6FrameIdAddr) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)); + + if (p_FmPcd->capwapFrameIdAddr) + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)); + + if (p_FmPcd->enabled) FM_PCD_Disable(p_FmPcd); - if (p_FmPcd->h_Spinlock) - XX_FreeSpinlock(p_FmPcd->h_Spinlock); - - if(p_FmPcd->p_FmPcdDriverParam) + if (p_FmPcd->p_FmPcdDriverParam) { XX_Free(p_FmPcd->p_FmPcdDriverParam); p_FmPcd->p_FmPcdDriverParam = NULL; } - if(p_FmPcd->p_FmPcdKg) + + if (p_FmPcd->p_FmPcdKg) { - if((err = KgFree(p_FmPcd)) != E_OK) + if ((err = KgFree(p_FmPcd)) != E_OK) RETURN_ERROR(MINOR, err, NO_MSG); XX_Free(p_FmPcd->p_FmPcdKg); p_FmPcd->p_FmPcdKg = NULL; } - if(p_FmPcd->p_FmPcdPlcr) + if (p_FmPcd->p_FmPcdPlcr) { - if((err = PlcrFree(p_FmPcd)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); + PlcrFree(p_FmPcd); XX_Free(p_FmPcd->p_FmPcdPlcr); p_FmPcd->p_FmPcdPlcr = NULL; } - if(p_FmPcd->p_FmPcdPrs) + if (p_FmPcd->p_FmPcdPrs) { - if(p_FmPcd->guestId == NCSW_MASTER_ID) + if (p_FmPcd->guestId == NCSW_MASTER_ID) PrsFree(p_FmPcd); XX_Free(p_FmPcd->p_FmPcdPrs); p_FmPcd->p_FmPcdPrs = NULL; @@ -799,10 +1068,53 @@ t_Error FM_PCD_Free(t_Handle h_FmPcd) FmUnregisterPcd(p_FmPcd->h_Fm); + ReleaseFreeLocksLst(p_FmPcd); + + if (p_FmPcd->h_Spinlock) + XX_FreeSpinlock(p_FmPcd->h_Spinlock); + + if (p_FmPcd->h_ShadowSpinlock) + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock); + XX_Free(p_FmPcd); + return E_OK; } +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!")); + + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_FmPcd->exceptions |= bitMask; + else + p_FmPcd->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); + + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId); +} + t_Error FM_PCD_Enable(t_Handle h_FmPcd) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; @@ -810,28 +1122,19 @@ t_Error FM_PCD_Enable(t_Handle h_FmPcd) SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - if(p_FmPcd->guestId == NCSW_MASTER_ID) - { - if(p_FmPcd->p_FmPcdKg) - KgEnable(p_FmPcd); + if (p_FmPcd->enabled) + return E_OK; - if(p_FmPcd->p_FmPcdPlcr) - PlcrEnable(p_FmPcd); - - if(p_FmPcd->p_FmPcdPrs) - PrsEnable(p_FmPcd); - - p_FmPcd->enabled = TRUE; - } - else + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + p_FmPcd->h_IpcSession) { uint8_t enabled; t_FmPcdIpcMsg msg; t_FmPcdIpcReply reply; uint32_t replyLength; - memset(&msg, 0, sizeof(msg)); memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); msg.msgId = FM_PCD_MASTER_IS_ENABLED; replyLength = sizeof(uint32_t) + sizeof(enabled); if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, @@ -847,7 +1150,23 @@ t_Error FM_PCD_Enable(t_Handle h_FmPcd) p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody)); if (!p_FmPcd->enabled) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!")); + + return E_OK; } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + + if (p_FmPcd->p_FmPcdKg) + KgEnable(p_FmPcd); + + if (p_FmPcd->p_FmPcdPlcr) + PlcrEnable(p_FmPcd); + + if (p_FmPcd->p_FmPcdPrs) + PrsEnable(p_FmPcd); + + p_FmPcd->enabled = TRUE; return E_OK; } @@ -856,50 +1175,62 @@ t_Error FM_PCD_Disable(t_Handle h_FmPcd) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; t_Error err = E_OK; - t_FmPcdIpcMsg msg; - t_FmPcdIpcReply reply; - uint32_t replyLength; SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - if(p_FmPcd->guestId == NCSW_MASTER_ID) - { - if(p_FmPcd->numOfEnabledGuestPartitionsPcds != 0) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to disable a master partition PCD while guest partitions are still enabled.")); - - if(p_FmPcd->p_FmPcdKg) - KgDisable(p_FmPcd); - - if(p_FmPcd->p_FmPcdPlcr) - PlcrDisable(p_FmPcd); - - if(p_FmPcd->p_FmPcdPrs) - PrsDisable(p_FmPcd); - - p_FmPcd->enabled = FALSE; - + if (!p_FmPcd->enabled) return E_OK; + + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + p_FmPcd->h_IpcSession) + { + t_FmPcdIpcMsg msg; + t_FmPcdIpcReply reply; + uint32_t replyLength; + + memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_PCD_GUEST_DISABLE; + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + if (reply.error == E_OK) + p_FmPcd->enabled = FALSE; + + return (t_Error)(reply.error); } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_GUEST_DISABLE; - memset(&reply, 0, sizeof(reply)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Trying to disable a master partition PCD while" + "guest partitions are still enabled!")); - return (t_Error)(reply.error); + if (p_FmPcd->p_FmPcdKg) + KgDisable(p_FmPcd); + + if (p_FmPcd->p_FmPcdPlcr) + PlcrDisable(p_FmPcd); + + if (p_FmPcd->p_FmPcdPrs) + PrsDisable(p_FmPcd); + + p_FmPcd->enabled = FALSE; + + return E_OK; } -t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams) +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; uint32_t intFlags, specialUnits = 0; @@ -909,18 +1240,20 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0; bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE; uint8_t hdrNum; + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams; SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL); SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL); intFlags = FmPcdLock(p_FmPcd); /* find a new netEnv */ - for(i = 0;inetEnvs[i].used) + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) + if (!p_FmPcd->netEnvs[i].used) break; - if(i== FM_MAX_NUM_OF_PORTS) + if (i== FM_MAX_NUM_OF_PORTS) { REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS)); FmPcdUnlock(p_FmPcd, intFlags); @@ -928,63 +1261,78 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams } p_FmPcd->netEnvs[i].used = TRUE; + FmPcdUnlock(p_FmPcd, intFlags); - if (!TRY_LOCK(NULL, &p_FmPcd->netEnvs[i].lock)) + /* As anyone doesn't have handle of this netEnv yet, no need + to protect it with spinlocks */ + + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams)); + if (!p_ModifiedNetEnvParams) { - FmPcdUnlock(p_FmPcd, intFlags); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams")); return NULL; } - FmPcdUnlock(p_FmPcd, intFlags); + + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams)); + p_NetEnvParams = p_ModifiedNetEnvParams; netEnvCurrId = (uint8_t)i; /* clear from previous use */ memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit)); - memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_PRIVATE_HDRS * sizeof(t_FmPcdNetEnvAliases)); + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases)); memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit)); + + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId; + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd; + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN; /* check that header with opt is not interchanged with the same header */ - for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) { - for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) { /* if an option exists, check that other headers are not the same header without option */ - if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt) + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt) { - for (j=0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++) - if((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) && + { + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) && !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt) { - REPORT_ERROR(MINOR, E_FULL, ("Illegal unit - header with opt may not be interchangeable with the same header without opt")); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); + REPORT_ERROR(MINOR, E_FULL, + ("Illegal unit - header with opt may not be interchangeable with the same header without opt")); + XX_Free(p_ModifiedNetEnvParams); return NULL; } + } } } } - /* IPSEC_AH and IPSEC_SPI can't be 2 units, */ - /* check that header with opt is not interchanged with the same header */ - for(i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + /* Specific headers checking */ + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) { - for(k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) { /* Some headers pairs may not be defined on different units as the parser doesn't distinguish */ - if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH) + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */ + /* check that header with opt is not interchanged with the same header */ + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH) { if (ipsecEspExists && (ipsecEspUnit != i)) { REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); - return NULL; + XX_Free(p_ModifiedNetEnvParams); + return NULL; } else { @@ -992,12 +1340,12 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams ipsecAhExists = TRUE; } } - if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP) + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP) { if (ipsecAhExists && (ipsecAhUnit != i)) { REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); + XX_Free(p_ModifiedNetEnvParams); return NULL; } else @@ -1006,46 +1354,111 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams ipsecEspExists = TRUE; } } - if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP) + /* ENCAP_ESP */ + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP) { - /* TODO - general coding. choose the free shim header */ + /* IPSec UDP encapsulation is currently set to use SHIM1 */ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP; p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1; p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1; p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; } +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + /* UDP_LITE */ + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE) + { + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; + } +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + + /* IP FRAG */ + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) && + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1)) + { + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if + * IPv4 exists. If so we don't need to set an extra unit + * We consider as "having IPv4" any IPv4 without interchangable headers + * but including any options. */ + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; + + /* check if IPv4 header exists by itself */ + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + { + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4; + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; + } + } + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) && + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1)) + { + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if + * IPv4 exists. If so we don't need to set an extra unit + * We consider as "having IPv6" any IPv6 without interchangable headers + * but including any options. */ + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; + + /* check if IPv6 header exists by itself */ + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + { + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6; + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; + } + } +#if (DPAA_VERSION >= 11) + /* CAPWAP FRAG */ + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) && + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1)) + { + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1; + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; + } +#endif /* (DPAA_VERSION >= 11) */ } } /* if private header (shim), check that no other headers specified */ - for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) { - if(IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) - if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE) + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE) { REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers")); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); + XX_Free(p_ModifiedNetEnvParams); return NULL; } } - for(i=0; inumOfDistinctionUnits;i++) + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++) { if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) - switch(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr) + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr) { - case(HEADER_TYPE_USER_DEFINED_SHIM1): + case (HEADER_TYPE_USER_DEFINED_SHIM1): if (shim1Selected) { REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP")); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); + XX_Free(p_ModifiedNetEnvParams); return NULL; } shim1Selected = TRUE; p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001; - break; - case(HEADER_TYPE_USER_DEFINED_SHIM2): + break; + case (HEADER_TYPE_USER_DEFINED_SHIM2): p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002; break; default: @@ -1055,7 +1468,7 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams { p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++); - if(IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; } } @@ -1063,57 +1476,67 @@ t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams /* define a set of hardware parser LCV's according to the defined netenv */ /* set an array of LCV's for each header in the netEnv */ - for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) { /* private headers have no LCV in the hard parser */ if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) { - for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) { - GET_PRS_HDR_NUM(hdrNum, p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr); + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr); if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) { REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); + XX_Free(p_ModifiedNetEnvParams); return NULL; } p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; } } } + XX_Free(p_ModifiedNetEnvParams); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock); - - return UINT_TO_PTR((uint64_t)netEnvCurrId+1); + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock(); + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock")); + return NULL; + } + return &p_FmPcd->netEnvs[netEnvCurrId]; } -t_Error FM_PCD_DeleteNetEnvCharacteristics(t_Handle h_FmPcd, t_Handle h_NetEnv) +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint8_t netEnvId = (uint8_t)(PTR_TO_UINT(h_NetEnv)-1); + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv; + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd; + uint32_t intFlags; + uint8_t netEnvId = p_NetEnv->netEnvId; - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - if (!TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->netEnvs[netEnvId].lock)) - return ERROR_CODE(E_BUSY); /* check that no port is bound to this netEnv */ - if(p_FmPcd->netEnvs[netEnvId].owners) + if (p_FmPcd->netEnvs[netEnvId].owners) { - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock); - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to")); + RETURN_ERROR(MINOR, E_INVALID_STATE, + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to")); } - p_FmPcd->netEnvs[netEnvId].used= FALSE; + + intFlags = FmPcdLock(p_FmPcd); + + p_FmPcd->netEnvs[netEnvId].used = FALSE; p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN; memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS); - RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock); + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock) + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock); + FmPcdUnlock(p_FmPcd, intFlags); return E_OK; } @@ -1126,19 +1549,133 @@ void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd) FmHcTxConf(p_FmPcd->h_Hc, p_Fd); } +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmCtrlCodeRevisionInfo revInfo; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE); + + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK) + { + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision.")); + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER; + } + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); + + if (!p_FmPcd->h_Hc) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode")); + + p_FmPcd->advancedOffloadSupport = TRUE; + + return E_OK; +} + uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t replyLength, outCounter = 0; - t_FmPcdIpcMsg msg; + uint32_t outCounter = 0; t_Error err; - t_FmPcdIpcReply reply; SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); - if(p_FmPcd->guestId != NCSW_MASTER_ID) + switch (counter) { + case (e_FM_PCD_KG_COUNTERS_TOTAL): + if (!p_FmPcd->p_FmPcdKg) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated")); + return 0; + } + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs && + !p_FmPcd->h_IpcSession) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); + return 0; + } + break; + + case (e_FM_PCD_PLCR_COUNTERS_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_TOTAL): + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): + if (!p_FmPcd->p_FmPcdPlcr) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated")); + return 0; + } + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && + !p_FmPcd->h_IpcSession) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in \"guest-mode\" without neither IPC nor mapped register!")); + return 0; + } + + /* check that counters are enabled */ + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) + { + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); + return 0; + } + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs || + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession)); + break; + + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): + if (!p_FmPcd->p_FmPcdPrs) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated")); + return 0; + } + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs && + !p_FmPcd->h_IpcSession) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); + return 0; + } + break; + default: + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter")); + return 0; + } + + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + p_FmPcd->h_IpcSession) + { + t_FmPcdIpcMsg msg; + t_FmPcdIpcReply reply; + uint32_t replyLength; + memset(&msg, 0, sizeof(msg)); memset(&reply, 0, sizeof(reply)); msg.msgId = FM_PCD_GET_COUNTER; @@ -1159,188 +1696,61 @@ uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter) return outCounter; } - switch(counter) + switch (counter) { - case(e_FM_PCD_KG_COUNTERS_TOTAL): - if(!p_FmPcd->p_FmPcdKg) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters")); - return 0; - } - break; - case(e_FM_PCD_PLCR_COUNTERS_YELLOW): - case(e_FM_PCD_PLCR_COUNTERS_RED): - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): - case(e_FM_PCD_PLCR_COUNTERS_TOTAL): - case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): - if(!p_FmPcd->p_FmPcdPlcr) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters")); - return 0; - } - /* check that counters are enabled */ - if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); - return 0; - } - break; - case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): - if(!p_FmPcd->p_FmPcdPrs) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters")); - return 0; - } - break; - default: - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); - return 0; - } - switch(counter) - { - case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds); - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs); - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs); - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs); - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs); - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres); - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres); - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres); - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres); - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs); - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs); - case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs); - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs); - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs); - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs); - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs); - case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): - return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs); - case(e_FM_PCD_KG_COUNTERS_TOTAL): - return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc); + /* Parser statistics */ + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds); + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs); + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs); + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs); + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs); + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres); + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres); + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres); + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres); + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs); + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs); + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs); + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs); + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs); + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs); + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs); + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs); + case (e_FM_PCD_KG_COUNTERS_TOTAL): + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc); - /*Policer statictics*/ - case(e_FM_PCD_PLCR_COUNTERS_YELLOW): + /* Policer statistics */ + case (e_FM_PCD_PLCR_COUNTERS_YELLOW): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt); - case(e_FM_PCD_PLCR_COUNTERS_RED): + case (e_FM_PCD_PLCR_COUNTERS_RED): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt); - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt); - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt); - case(e_FM_PCD_PLCR_COUNTERS_TOTAL): + case (e_FM_PCD_PLCR_COUNTERS_TOTAL): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt); - case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt); - - default: - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); - return 0; } -} - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_DUMP_REGS; - return XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL); - } - if (p_FmPcd->p_FmPcdKg) - return FM_PCD_KgDumpRegs(h_FmPcd); - if (p_FmPcd->p_FmPcdPlcr) - return FM_PCD_PlcrDumpRegs(h_FmPcd); - if (p_FmPcd->p_FmPcdPrs) - return FM_PCD_PrsDumpRegs(h_FmPcd); - return E_OK; -} - -t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_STATE); - - return FmHcDumpRegs(p_FmPcd->h_Hc); -} - -#endif /* (defined(DEBUG_ERRORS) && ... */ - -t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t bitMask = 0; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!")); - - GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) - { - if (enable) - p_FmPcd->exceptions |= bitMask; - else - p_FmPcd->exceptions &= ~bitMask; - } - else - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - - return E_OK; + return 0; } t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) @@ -1351,126 +1761,119 @@ t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - if(p_FmPcd->guestId != NCSW_MASTER_ID) + if (p_FmPcd->guestId != NCSW_MASTER_ID) RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!")); GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) + if (bitMask) { if (enable) p_FmPcd->exceptions |= bitMask; else p_FmPcd->exceptions &= ~bitMask; - switch(exception) + switch (exception) { - case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): - if(!p_FmPcd->p_FmPcdKg) + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): + if (!p_FmPcd->p_FmPcdKg) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); break; - case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): - case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): - case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): - if(!p_FmPcd->p_FmPcdPlcr) + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): + if (!p_FmPcd->p_FmPcdPlcr) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); - break; - case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): - if(!p_FmPcd->p_FmPcdPrs) + break; + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): + if (!p_FmPcd->p_FmPcdPrs) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working")); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception")); - + break; } - switch(exception) + switch (exception) { - case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): - tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer); - if(enable) - tmpReg |= FM_PCD_KG_DOUBLE_ECC; + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); + if (enable) + tmpReg |= FM_EX_KG_DOUBLE_ECC; else - tmpReg &= ~FM_PCD_KG_DOUBLE_ECC; - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg); + tmpReg &= ~FM_EX_KG_DOUBLE_ECC; + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); break; - case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): - tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer); - if(enable) - tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW; + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); + if (enable) + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW; else - tmpReg &= ~FM_PCD_KG_KEYSIZE_OVERFLOW; - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg); + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW; + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); break; - case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): - tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer); - if(enable) + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer); + if (enable) tmpReg |= FM_PCD_PRS_DOUBLE_ECC; else tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC; - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer, tmpReg); + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg); break; - case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): - tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever); - if(enable) + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever); + if (enable) tmpReg |= FM_PCD_PRS_SINGLE_ECC; else tmpReg &= ~FM_PCD_PRS_SINGLE_ECC; - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever, tmpReg); + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg); break; - case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); - if(enable) + if (enable) tmpReg |= FM_PCD_PLCR_DOUBLE_ECC; else tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC; WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); break; - case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); - if(enable) + if (enable) tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR; else tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR; WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); break; - case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); - if(enable) + if (enable) tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; else tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); break; - case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); - if(enable) + if (enable) tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; else tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception")); } /* for ECC exceptions driver automatically enables ECC mechanism, if disabled. Driver may disable them automatically, depending on driver's status */ - if(enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) FmEnableRamsEcc(p_FmPcd->h_Fm); - if(!enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) FmDisableRamsEcc(p_FmPcd->h_Fm); } - else - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); return E_OK; } @@ -1482,53 +1885,50 @@ t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception) SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - if(p_FmPcd->guestId != NCSW_MASTER_ID) + if (p_FmPcd->guestId != NCSW_MASTER_ID) RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!")); - switch(exception) + switch (exception) { - case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): - if(!p_FmPcd->p_FmPcdKg) + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): + if (!p_FmPcd->p_FmPcdKg) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); break; - case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): - case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): - case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): - if(!p_FmPcd->p_FmPcdPlcr) + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): + if (!p_FmPcd->p_FmPcdPlcr) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); break; - case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): - case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): - if(!p_FmPcd->p_FmPcdPrs) + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): + if (!p_FmPcd->p_FmPcdPrs) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working")); break; default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid interrupt requested")); - + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested")); } - switch(exception) + switch (exception) { case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, FM_PCD_PRS_DOUBLE_ECC); break; case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, FM_PCD_PRS_SINGLE_ECC); break; case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: - if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC)) + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_DOUBLE_ECC); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC); break; case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: - if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW)) + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_KEYSIZE_OVERFLOW); + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW); break; case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)) @@ -1550,8 +1950,6 @@ t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception) RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE); break; - default: - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); } return E_OK; @@ -1565,129 +1963,133 @@ t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - if(p_FmPcd->guestId != NCSW_MASTER_ID) + if (p_FmPcd->guestId != NCSW_MASTER_ID) RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!")); - switch(counter) + switch (counter) { - case(e_FM_PCD_KG_COUNTERS_TOTAL): - if(!p_FmPcd->p_FmPcdKg) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - keygen is not working")); + case (e_FM_PCD_KG_COUNTERS_TOTAL): + if (!p_FmPcd->p_FmPcdKg) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working")); break; - case(e_FM_PCD_PLCR_COUNTERS_YELLOW): - case(e_FM_PCD_PLCR_COUNTERS_RED): - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): - case(e_FM_PCD_PLCR_COUNTERS_TOTAL): - case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): - if(!p_FmPcd->p_FmPcdPlcr) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - Policer is not working")); - if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) + case (e_FM_PCD_PLCR_COUNTERS_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_TOTAL): + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): + if (!p_FmPcd->p_FmPcdPlcr) + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working")); + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); break; - case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): - case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): - if(!p_FmPcd->p_FmPcdPrs) + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): + if (!p_FmPcd->p_FmPcdPrs) RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); break; default: RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); } - switch(counter) + switch (counter) { - case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds, value); + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value); break; - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs, value); + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value); break; - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs, value); + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value); break; - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs, value); + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value); break; - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs, value); + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value); break; - case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres, value); + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value); break; - case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres, value); + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value); break; - case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres, value); + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value); break; - case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres, value); + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value); break; - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs, value); + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value); break; - case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs, value); + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value); break; - case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs, value); + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value); break; - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs, value); + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value); break; - case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs, value); + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value); break; - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs, value); + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value); break; - case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs, value); + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value); break; - case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs, value); + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value); break; - case(e_FM_PCD_KG_COUNTERS_TOTAL): - WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc,value); + case (e_FM_PCD_KG_COUNTERS_TOTAL): + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value); break; /*Policer counters*/ - case(e_FM_PCD_PLCR_COUNTERS_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_YELLOW): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value); break; - case(e_FM_PCD_PLCR_COUNTERS_RED): + case (e_FM_PCD_PLCR_COUNTERS_RED): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value); break; - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value); break; - case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value); break; - case(e_FM_PCD_PLCR_COUNTERS_TOTAL): + case (e_FM_PCD_PLCR_COUNTERS_TOTAL): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value); break; - case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value); break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter")); } -return E_OK; + return E_OK; +} + +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + return FmHcGetPort(p_FmPcd->h_Hc); } diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h index 55ae47ac3f88..27ec9c5bf672 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_pcd.h @@ -42,15 +43,25 @@ #include "error_ext.h" #include "list_ext.h" #include "fm_pcd_ext.h" - +#include "fm_common.h" +#include "fsl_fman_prs.h" +#include "fsl_fman_kg.h" #define __ERR_MODULE__ MODULE_FM_PCD -/**************************************************************************//** - @Group FM_PCD_Runtime_grp FM PCD Runtime Unit - @{ -*//***************************************************************************/ +/****************************/ +/* Defaults */ +/****************************/ +#define DEFAULT_plcrAutoRefresh FALSE +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW) +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) +#define DEFAULT_fmPcdPlcrExceptions 0 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC) + +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC +#define DEFAULT_numOfUsedProfilesPerWindow 16 +#define DEFAULT_numOfSharedPlcrProfiles 4 /****************************/ /* Network defines */ @@ -67,28 +78,26 @@ /****************************/ #define ILLEGAL_CLS_PLAN 0xff #define ILLEGAL_NETENV 0xff + +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3 + /****************************/ /* Error defines */ /****************************/ -#define FM_PCD_EX_KG_DOUBLE_ECC 0x80000000 -#define FM_PCD_EX_KG_KEYSIZE_OVERFLOW 0x40000000 #define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000 #define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000 #define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000 #define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000 -#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000 -#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000 - #define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \ -switch(exception){ \ +switch (exception){ \ case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \ - bitMask = FM_PCD_EX_KG_DOUBLE_ECC; break; \ + bitMask = FM_EX_KG_DOUBLE_ECC; break; \ case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \ bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \ case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \ - bitMask = FM_PCD_EX_KG_KEYSIZE_OVERFLOW; break; \ + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \ case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \ bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \ case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \ @@ -101,290 +110,24 @@ switch(exception){ \ bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \ default: bitMask = 0;break;} -/***********************************************************************/ -/* SW parser L4 shells patch */ -/***********************************************************************/ -#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb -#define SW_PRS_L4_PATCH \ -{ 0x31,0x92,0x02,0x1f,0x00,0x32,0x00,0x78, \ - 0x00,0x34,0x32,0xf0,0x00,0x50,0x00,0x0c, \ - 0x28,0x5e,0x83,0x8e,0x29,0x32,0xaf,0x8e, \ - 0x31,0xb2,0x9f,0xff,0x00,0x06,0xaf,0xbf, \ - 0x00,0x06,0x29,0x36,0x00,0x01,0x1b,0xff, \ - 0x32,0xf0,0x00,0x50,0x00,0x08,0x28,0x5e, \ - 0x08,0x99,0x00,0x00,0x9f,0x8e,0x31,0xb2, \ - 0x9f,0xff,0x00,0x06,0x29,0x36,0x00,0x01, \ - 0x1b,0xff,0x32,0xf0,0x00,0x50,0x00,0x04, \ - 0x28,0x5e,0x8f,0x9e,0x29,0x32,0x31,0xb2, \ - 0x8f,0xbf,0x00,0x06,0x29,0x36,0x00,0x01, \ - 0x1b,0xff,0x32,0xf0,0x00,0x50,0x00,0x04, \ - 0x28,0x5e,0x8f,0x9e,0x29,0x32,0x31,0xb2, \ - 0x8f,0xbf,0x00,0x06,0x29,0x36,0x00,0x01, \ - 0x1b,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; - -#define SW_PRS_L4_PATCH_SIZE 120 -#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */ - -/****************************/ -/* Parser defines */ -/****************************/ -/* masks */ -#define PRS_ERR_CAP 0x80000000 -#define PRS_ERR_TYPE_DOUBLE 0x40000000 -#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000 -#define PRS_ERR_ADDR_MASK 0x000001FF -#define FM_PCD_PRS_RPIMAC_EN 0x00000001 -#define FM_PCD_PRS_SINGLE_ECC 0x00004000 -#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000 -#define FM_PCD_PRS_DOUBLE_ECC 0x00004000 -#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000 - -/* others */ -#define PRS_MAX_CYCLE_LIMIT 8191 -#define PRS_SW_DATA 0x00000800 -#define PRS_REGS_OFFSET 0x00000840 - -#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \ - prsPortId = (uint8_t)(hardwarePortId & 0x0f) - -#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \ - bitMask = 0x80000000>>prsPortId - -/***********************************************************************/ -/* Keygen defines */ -/***********************************************************************/ -/* Masks */ -#define FM_PCD_KG_KGGCR_EN 0x80000000 -#define KG_SCH_GEN_VALID 0x80000000 -#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 -#define KG_ERR_CAP 0x80000000 -#define KG_ERR_TYPE_DOUBLE 0x40000000 -#define KG_ERR_ADDR_MASK 0x00000FFF -#define FM_PCD_KG_DOUBLE_ECC 0x80000000 -#define FM_PCD_KG_KEYSIZE_OVERFLOW 0x40000000 -#define KG_SCH_MODE_EN 0x80000000 - -/* shifts */ -#define FM_PCD_KG_PE_CPP_MASK_SHIFT 16 -#define FM_PCD_KG_KGAR_WSEL_SHIFT 8 - -/* others */ -#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100 -#define NO_VALIDATION 0x70 -#define KG_ACTION_REG_TO 1024 -#define KG_MAX_PROFILE 255 -#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF - -typedef struct { - bool known; - uint8_t id; -} t_FmPcdKgSchemesExtractsEntry; - -typedef struct { - t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; -} t_FmPcdKgSchemesExtracts; - /***********************************************************************/ /* Policer defines */ /***********************************************************************/ - -/* masks */ -#define FM_PCD_PLCR_PEMODE_PI 0x80000000 -#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000 -#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000 -#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000 -#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000 -#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000 -#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000 -#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000 -#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000 -#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000 -#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000 -#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000 -#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000 -#define FM_PCD_PLCR_PEMODE_PKT 0x00800000 -#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000 -#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16 -#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000 -#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000 -#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000 -#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000 -#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000 -#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800 -#define FM_PCD_PLCR_PEMODE_TRA 0x00000004 -#define FM_PCD_PLCR_PEMODE_TRB 0x00000002 -#define FM_PCD_PLCR_PEMODE_TRC 0x00000001 +#define FM_PCD_PLCR_GCR_STEN 0x40000000 #define FM_PCD_PLCR_DOUBLE_ECC 0x80000000 #define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000 #define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000 #define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000 -#define FM_PCD_PLCR_NIA_VALID 0x80000000 - -#define FM_PCD_PLCR_GCR_EN 0x80000000 -#define FM_PCD_PLCR_GCR_STEN 0x40000000 -#define FM_PCD_PLCR_GCR_DAR 0x20000000 -#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF -#define FM_PCD_PLCR_NIA_ABS 0x00000100 - -#define FM_PCD_PLCR_GSR_BSY 0x80000000 -#define FM_PCD_PLCR_GSR_DQS 0x60000000 -#define FM_PCD_PLCR_GSR_RPB 0x20000000 -#define FM_PCD_PLCR_GSR_FQS 0x0C000000 -#define FM_PCD_PLCR_GSR_LPALG 0x0000C000 -#define FM_PCD_PLCR_GSR_LPCA 0x00003000 -#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF - -#define FM_PCD_PLCR_EVR_PSIC 0x80000000 -#define FM_PCD_PLCR_EVR_AAC 0x40000000 - -#define FM_PCD_PLCR_PAR_PSI 0x20000000 -#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000 -/* PWSEL Selctive select options */ -#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */ -#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */ -#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */ -#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */ -#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */ -#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */ -#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */ -#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */ -#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */ -#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */ - -#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1] - 1-> 2^N specific locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}. - 2-> 2^(N-1) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}. - 4-> 2^(N-2) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}. - 8->2^(N-3) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}. - 16-> 2^(N-4) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}. - 32-> 2^(N-5) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}. - 64-> 2^(N-6) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}. - 128-> 2^(N-7) base locations. */ -#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}. - When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */ - -#define FM_PCD_PLCR_PMR_V 0x80000000 -#define PLCR_ERR_ECC_CAP 0x80000000 -#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000 -#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0 -#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F - -#define PLCR_ERR_UNINIT_CAP 0x80000000 -#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF -#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000 -#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000 - -/* shifts */ -#define PLCR_ERR_ECC_PNUM_SHIFT 4 -#define PLCR_ERR_UNINIT_PID_SHIFT 16 - -#define FM_PCD_PLCR_PMR_BRN_SHIFT 16 - -/* others */ -#define WAIT_FOR_PLCR_EVR_AAC \ -{\ - uint32_t count = 0; \ - uint32_t tmpReg32; \ - while (count < FM_PCD_PLCR_POLL) \ - { \ - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->fmpl_evr);\ - if (!( tmpReg32 & FM_PCD_PLCR_EVR_AAC)) break;\ - count++;\ - }\ -} - -#define WAIT_FOR_PLCR_PAR_GO \ -{\ - uint32_t count = 0; \ - uint32_t tmpReg32; \ - while (count < FM_PCD_PLCR_POLL) \ - { \ - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->fmpl_par);\ - if (!( tmpReg32 & FM_PCD_PLCR_PAR_GO)) break;\ - count++; \ - }\ -} - -#define PLCR_PORT_WINDOW_SIZE(hardwarePortId) - -/****************************/ -/* Defaults */ -/****************************/ -#define DEFAULT_plcrAutoRefresh FALSE -#define DEFAULT_prsMaxParseCycleLimit 0 -#define DEFAULT_fmPcdKgErrorExceptions (FM_PCD_EX_KG_DOUBLE_ECC | FM_PCD_EX_KG_KEYSIZE_OVERFLOW) -#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) -#define DEFAULT_fmPcdPlcrExceptions 0 -#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC) - -#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC -#define DEFAULT_numOfUsedProfilesPerWindow 16 -#define DEFAULT_numOfSharedPlcrProfiles 4 - /***********************************************************************/ /* Memory map */ /***********************************************************************/ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START -typedef _Packed struct { - volatile uint32_t kgoe_sp; - volatile uint32_t kgoe_cpp; -} _PackedType t_FmPcdKgPortConfigRegs; -typedef _Packed struct { - volatile uint32_t kgcpe[8]; -} _PackedType t_FmPcdKgClsPlanRegs; - -typedef _Packed union { - t_FmPcdKgInterModuleSchemeRegs schemeRegs; - t_FmPcdKgPortConfigRegs portRegs; - t_FmPcdKgClsPlanRegs clsPlanRegs; -} _PackedType u_FmPcdKgIndirectAccessRegs; - -typedef _Packed struct { - volatile uint32_t kggcr; - volatile uint32_t res0; - volatile uint32_t res1; - volatile uint32_t kgeer; - volatile uint32_t kgeeer; - volatile uint32_t res2; - volatile uint32_t res3; - volatile uint32_t kgseer; - volatile uint32_t kgseeer; - volatile uint32_t kggsr; - volatile uint32_t kgtpc; - volatile uint32_t kgserc; - volatile uint32_t res4[4]; - volatile uint32_t kgfdor; - volatile uint32_t kggdv0r; - volatile uint32_t kggdv1r; - volatile uint32_t res5[5]; - volatile uint32_t kgfer; - volatile uint32_t kgfeer; - volatile uint32_t res6[38]; - u_FmPcdKgIndirectAccessRegs indirectAccessRegs; - volatile uint32_t res[42]; /*(0xfc-sizeof(u_FmPcdKgIndirectAccessRegs))/4 */ - volatile uint32_t kgar; -} _PackedType t_FmPcdKgRegs; - -typedef _Packed struct { +typedef struct { /* General Configuration and Status Registers */ volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */ volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */ @@ -404,7 +147,7 @@ typedef _Packed struct { volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */ /* Profile RAM Access Registers */ volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/ - t_FmPcdPlcrInterModuleProfileRegs profileRegs; + t_FmPcdPlcrProfileRegs profileRegs; /* Error Capture Registers */ volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */ volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */ @@ -415,42 +158,8 @@ typedef _Packed struct { volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */ volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers. (for port-ID 1-11, only for supported Port-ID registers) */ -} _PackedType t_FmPcdPlcrRegs; +} t_FmPcdPlcrRegs; -typedef _Packed struct { - volatile uint32_t rpclim; - volatile uint32_t rpimac; - volatile uint32_t pmeec; - volatile uint32_t res1[5]; - volatile uint32_t pevr; - volatile uint32_t pever; - volatile uint32_t pevfr; - volatile uint32_t perr; - volatile uint32_t perer; - volatile uint32_t perfr; - volatile uint32_t res2[0xA]; - volatile uint32_t ppsc; - volatile uint32_t res3; - volatile uint32_t pds; - volatile uint32_t l2rrs; - volatile uint32_t l3rrs; - volatile uint32_t l4rrs; - volatile uint32_t srrs; - volatile uint32_t l2rres; - volatile uint32_t l3rres; - volatile uint32_t l4rres; - volatile uint32_t srres; - volatile uint32_t spcs; - volatile uint32_t spscs; - volatile uint32_t hxscs; - volatile uint32_t mrcs; - volatile uint32_t mwcs; - volatile uint32_t mrscs; - volatile uint32_t mwscs; - volatile uint32_t fcscs; -} _PackedType t_FmPcdPrsRegs; - -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -460,6 +169,15 @@ typedef _Packed struct { /* Driver's internal structures */ /***********************************************************************/ +typedef struct { + bool known; + uint8_t id; +} t_FmPcdKgSchemesExtractsEntry; + +typedef struct { + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; +} t_FmPcdKgSchemesExtracts; + typedef struct { t_Handle h_Manip; bool keepRes; @@ -472,12 +190,18 @@ typedef struct { between the port and PCD regarding the KG scheme. *//***************************************************************************/ typedef struct { - uint8_t netEnvId; /* in */ - uint8_t numOfDistinctionUnits; /* in */ - uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */ - uint32_t vector; /* out */ + uint8_t netEnvId; /* in */ + uint8_t numOfDistinctionUnits; /* in */ + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */ + uint32_t vector; /* out */ } t_NetEnvParams; +typedef struct { + bool allocated; + uint8_t ownerId; /* guestId for KG in multi-partition only. + portId for PLCR in any environment */ +} t_FmPcdAllocMng; + typedef struct { volatile bool lock; bool used; @@ -490,7 +214,9 @@ typedef struct { } t_FmPcdKgClsPlanGrp; typedef struct { - volatile bool lock; + t_Handle h_FmPcd; + uint8_t schemeId; + t_FmPcdLock *p_Lock; bool valid; uint8_t netEnvId; uint8_t owners; @@ -502,29 +228,34 @@ typedef struct { t_FmPcdKgKeyOrder orderedArray; e_FmPcdEngine nextEngine; e_FmPcdDoneAction doneAction; - uint8_t pointedOwners; + bool requiredActionFlag; uint32_t requiredAction; bool extractedOrs; uint8_t bitOffsetInPlcrProfile; bool directPlcr; +#if (DPAA_VERSION >= 11) + bool vspe; +#endif } t_FmPcdKgScheme; -typedef struct { - bool allocated; - uint8_t ownerId; /* guestId for KG in multi-partition only, - portId for PLCR in any environment */ -} t_FmPcdAllocMng; +typedef union { + struct fman_kg_scheme_regs schemeRegs; + struct fman_kg_pe_regs portRegs; + struct fman_kg_cp_regs clsPlanRegs; +} u_FmPcdKgIndirectAccessRegs; typedef struct { - t_FmPcdKgRegs *p_FmPcdKgRegs; - uint32_t schemeExceptionsBitMask; - uint8_t numOfSchemes; - uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; - t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES]; - t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS]; - uint8_t emptyClsPlanGrpId; - t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */ - t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP]; + struct fman_kg_regs *p_FmPcdKgRegs; + uint32_t schemeExceptionsBitMask; + uint8_t numOfSchemes; + t_Handle h_HwSpinlock; + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES]; + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS]; + uint8_t emptyClsPlanGrpId; + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */ + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP]; + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs; } t_FmPcdKg; typedef struct { @@ -534,11 +265,13 @@ typedef struct { } t_FmPcdPlcrMapParam; typedef struct { - bool valid; - volatile bool lock; - t_FmPcdAllocMng profilesMng; - uint8_t pointedOwners; - uint32_t requiredAction; + uint16_t absoluteProfileId; + t_Handle h_FmPcd; + bool valid; + t_FmPcdLock *p_Lock; + t_FmPcdAllocMng profilesMng; + bool requiredActionFlag; + uint32_t requiredAction; e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */ u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */ @@ -551,17 +284,21 @@ typedef struct { typedef struct { t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; + uint16_t partPlcrProfilesBase; + uint16_t partNumOfPlcrProfiles; t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES]; uint16_t numOfSharedProfiles; uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES]; t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS]; + t_Handle h_HwSpinlock; + t_Handle h_SwSpinlock; } t_FmPcdPlcr; typedef struct { uint32_t *p_SwPrsCode; uint32_t *p_CurrSwPrs; uint8_t currLabel; - t_FmPcdPrsRegs *p_FmPcdPrsRegs; + struct fman_prs_regs *p_FmPcdPrsRegs; t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS]; uint32_t fmPcdPrsPortIdStatistics; } t_FmPcdPrs; @@ -575,11 +312,14 @@ typedef struct { typedef struct { e_NetHeaderType hdr; + protocolOpt_t opt; /* only one option !! */ e_NetHeaderType aliasHdr; } t_FmPcdNetEnvAliases; typedef struct { - volatile bool lock; + uint8_t netEnvId; + t_Handle h_FmPcd; + t_Handle h_Spinlock; bool used; uint8_t owners; uint8_t clsPlanGrpId; @@ -587,21 +327,26 @@ typedef struct { uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS]; uint32_t macsecVector; - t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_PRIVATE_HDRS]; + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS]; } t_FmPcdNetEnv; typedef struct { + struct fman_prs_cfg dfltCfg; bool plcrAutoRefresh; - uint16_t prsMaxParseCycleLimit; } t_FmPcdDriverParam; typedef struct { t_Handle h_Fm; t_Handle h_FmMuram; + t_FmRevisionInfo fmRevInfo; + uint64_t physicalMuramBase; - volatile bool lock; + t_Handle h_Spinlock; + t_List freeLocksLst; + t_List acquiredLocksLst; + t_Handle h_IpcSession; /* relevant for guest only */ bool enabled; uint8_t guestId; /**< Guest Partition Id */ @@ -613,42 +358,48 @@ typedef struct { t_FmPcdPlcr *p_FmPcdPlcr; t_FmPcdPrs *p_FmPcdPrs; + void *p_CcShadow; /**< CC MURAM shadow */ + uint32_t ccShadowSize; + uint32_t ccShadowAlign; + volatile bool shadowLock; + t_Handle h_ShadowSpinlock; + t_Handle h_Hc; uint32_t exceptions; t_FmPcdExceptionCallback *f_Exception; t_FmPcdIdExceptionCallback *f_FmPcdIndexedException; t_Handle h_App; + uintptr_t ipv6FrameIdAddr; + uintptr_t capwapFrameIdAddr; + bool advancedOffloadSupport; t_FmPcdDriverParam *p_FmPcdDriverParam; } t_FmPcd; - +#if (DPAA_VERSION >= 11) +typedef uint8_t t_FmPcdFrmReplicUpdateType; +#define FRM_REPLIC_UPDATE_COUNTER 0x01 +#define FRM_REPLIC_UPDATE_INFO 0x02 +#endif /* (DPAA_VERSION >= 11) */ /***********************************************************************/ /* PCD internal routines */ /***********************************************************************/ -/**************************************************************************//** - - @Group FM_PCD_InterModule_grp FM PCD Inter-Module Unit - - @Description FM PCD Inter Module functions - - These are not User API routines but routines that may be called - from other modules. This will be the case in a single core environment, - where instead of useing the XX messeging mechanism, the routines may be - called from other modules. In a multicore environment, the other modules may - be run by other cores and therefor these routines may not be called directly. - - @{ -*//***************************************************************************/ - t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector); t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params); bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector); t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams); void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId); e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); -uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt); + +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId); +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip); +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId); +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip); +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip); t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams); t_Error KgInit(t_FmPcd *p_FmPcd); @@ -666,15 +417,21 @@ t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t g /* only for SINGLE partittion */ t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg); +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd); +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock); + t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams); t_Error PlcrInit(t_FmPcd *p_FmPcd); t_Error PlcrFree(t_FmPcd *p_FmPcd); void PlcrEnable(t_FmPcd *p_FmPcd); void PlcrDisable(t_FmPcd *p_FmPcd); -t_Error PlcrFreeProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t num, uint16_t base); -t_Error PlcrAllocProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t *p_Base); -t_Error PlcrAllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds); -void PlcrFreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds); +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId); +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId); +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd, + uint8_t hardwarePortId, + uint16_t numOfProfiles, + uint16_t base); +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId); t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams); t_Error PrsInit(t_FmPcd *p_FmPcd); @@ -683,19 +440,56 @@ void PrsDisable(t_FmPcd *p_FmPcd); void PrsFree(t_FmPcd *p_FmPcd ); t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include); -t_Handle FmPcdCcConfig(t_Handle h_FmPcd, t_FmPcdParams *p_FmPcdParams); t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase); uint8_t FmPcdCcGetOffset(t_Handle h_CcNode); uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode); uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode); +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode); void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add); -t_Error FmPcdManipCheckParamsForCcNextEgine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction); -void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew); +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction); +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, + t_Handle p_Ad, + t_Handle *p_AdNewPtr); void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset); -uint32_t FmPcdManipCheckNia(t_Handle h_FmPcd, t_Handle h_Ad); void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add); t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode); +#ifdef FM_CAPWAP_SUPPORT +t_Handle FmPcdManipApplSpecificBuild(void); +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip); +#endif /* FM_CAPWAP_SUPPORT */ +#if (DPAA_VERSION >= 11) +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup); +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add); +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew); + +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, + t_Handle h_ReplicGroup, + t_List *p_AdTables, + uint32_t *p_NumOfAdTables); +#endif /* (DPAA_VERSION >= 11) */ + +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock); +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock); +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock); +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip); +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip); + +typedef struct +{ + t_Handle h_StatsAd; + t_Handle h_StatsCounters; +#if (DPAA_VERSION >= 11) + t_Handle h_StatsFLRs; +#endif /* (DPAA_VERSION >= 11) */ +} t_FmPcdCcStatsParams; + +void NextStepAd(t_Handle h_Ad, + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, + t_FmPcd *p_FmPcd); +void ReleaseLst(t_List *p_List); static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd) { @@ -711,5 +505,39 @@ static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd) return p_FmPcd->physicalMuramBase; } +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock) +{ + ASSERT_COND(p_Lock); + return XX_LockIntrSpinlock(p_Lock->h_Spinlock); +} + +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags) +{ + ASSERT_COND(p_Lock); + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags); +} + +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock) +{ + uint32_t intFlags; + + ASSERT_COND(p_Lock); + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock); + if (p_Lock->flag) + { + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags); + return FALSE; + } + p_Lock->flag = TRUE; + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags); + return TRUE; +} + +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock) +{ + ASSERT_COND(p_Lock); + p_Lock->flag = FALSE; +} + #endif /* __FM_PCD_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h index 800a72b2ba7c..325d3e335f02 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_pcd_ipc.h @@ -53,7 +54,6 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START /**************************************************************************//** @Description Structure for getting a sw parser address according to a label @@ -63,7 +63,7 @@ *//***************************************************************************/ typedef _Packed struct t_FmPcdIpcSwPrsLable { - uint32_t enumHdr; /**< IN. The existance of this header will envoke + uint32_t enumHdr; /**< IN. The existence of this header will invoke the sw parser code. */ uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser attachments for the same header, use this @@ -79,38 +79,25 @@ typedef _Packed struct t_FmPcdIpcSwPrsLable Some fields are optional (depending on configuration) and will be analized by the port and FM modules accordingly. *//***************************************************************************/ + typedef struct t_FmPcdIpcKgSchemesParams { - uint8_t guestId; /**< IN */ - uint8_t numOfSchemes; /**< IN */ - uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; /**< OUT */ + uint8_t guestId; + uint8_t numOfSchemes; + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; } _PackedType t_FmPcdIpcKgSchemesParams; typedef struct t_FmPcdIpcKgClsPlanParams { - uint8_t guestId; /**< IN */ - uint16_t numOfClsPlanEntries; /**< IN */ - uint8_t clsPlanBase; /**< IN in alloc only */ + uint8_t guestId; + uint16_t numOfClsPlanEntries; + uint8_t clsPlanBase; } _PackedType t_FmPcdIpcKgClsPlanParams; -typedef _Packed struct t_FmPcdIpcPlcrAllocParams -{ - uint16_t num; - uint8_t hardwarePortId; - uint16_t plcrProfilesBase; -} _PackedType t_FmPcdIpcPlcrAllocParams; - -typedef _Packed struct t_FmPcdIpcSharedPlcrAllocParams -{ - uint16_t num; /**< IN */ - //uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES]; /**< OUT */ - uint32_t sharedProfilesMask[8]; -} _PackedType t_FmPcdIpcSharedPlcrAllocParams; - typedef _Packed struct t_FmPcdIpcPrsIncludePort { - uint8_t hardwarePortId; /* IN */ - bool include; /* IN */ + uint8_t hardwarePortId; + bool include; } _PackedType t_FmPcdIpcPrsIncludePort; @@ -118,19 +105,22 @@ typedef _Packed struct t_FmPcdIpcPrsIncludePort #define FM_PCD_MAX_MSG_SIZE 36 #define FM_PCD_MAX_REPLY_BODY_SIZE 36 -typedef _Packed struct -{ +typedef _Packed struct { uint32_t msgId; uint8_t msgBody[FM_PCD_MAX_MSG_SIZE]; } _PackedType t_FmPcdIpcMsg; -typedef _Packed struct t_FmPcdIpcReply -{ +typedef _Packed struct t_FmPcdIpcReply { uint32_t error; uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE]; } _PackedType t_FmPcdIpcReply; -#define MEM_MAP_END +typedef _Packed struct t_FmIpcResourceAllocParams { + uint8_t guestId; + uint16_t base; + uint16_t num; +}_PackedType t_FmIpcResourceAllocParams; + #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -160,7 +150,7 @@ typedef _Packed struct t_FmPcdIpcReply @Description Used by FM PCD front-end in order to allocate Policer profiles - @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer + @Param[in/out] t_FmIpcResourceAllocParams Pointer *//***************************************************************************/ #define FM_PCD_ALLOC_PROFILES 5 @@ -169,10 +159,30 @@ typedef _Packed struct t_FmPcdIpcReply @Description Used by FM PCD front-end in order to Free Policer profiles - @Param[in/out] t_FmPcdIpcPlcrAllocParams Pointer + @Param[in/out] t_FmIpcResourceAllocParams Pointer *//***************************************************************************/ #define FM_PCD_FREE_PROFILES 6 +/**************************************************************************//** + @Function FM_PCD_SET_PORT_PROFILES + + @Description Used by FM PCD front-end in order to allocate Policer profiles + for specific port + + @Param[in/out] t_FmIpcResourceAllocParams Pointer +*//***************************************************************************/ +#define FM_PCD_SET_PORT_PROFILES 7 + +/**************************************************************************//** + @Function FM_PCD_CLEAR_PORT_PROFILES + + @Description Used by FM PCD front-end in order to allocate Policer profiles + for specific port + + @Param[in/out] t_FmIpcResourceAllocParams Pointer +*//***************************************************************************/ +#define FM_PCD_CLEAR_PORT_PROFILES 8 + /**************************************************************************//** @Function FM_PCD_GET_PHYS_MURAM_BASE @@ -180,7 +190,7 @@ typedef _Packed struct t_FmPcdIpcReply @Param[in/out] t_FmPcdIcPhysAddr Pointer *//***************************************************************************/ -#define FM_PCD_GET_PHYS_MURAM_BASE 7 +#define FM_PCD_GET_PHYS_MURAM_BASE 9 /**************************************************************************//** @Function FM_PCD_GET_SW_PRS_OFFSET @@ -190,25 +200,7 @@ typedef _Packed struct t_FmPcdIpcReply @Param[in/out] t_FmPcdIpcSwPrsLable Pointer *//***************************************************************************/ -#define FM_PCD_GET_SW_PRS_OFFSET 8 - -/**************************************************************************//** - @Function FM_PCD_ALLOC_SHARED_PROFILES - - @Description Used by FM PCD front-end in order to allocate shared profiles - - @Param[in/out] t_FmPcdIpcSharedPlcrAllocParams Pointer -*//***************************************************************************/ -#define FM_PCD_ALLOC_SHARED_PROFILES 9 - -/**************************************************************************//** - @Function FM_PCD_FREE_SHARED_PROFILES - - @Description Used by FM PCD front-end in order to free shared profiles - - @Param[in/out] t_FmPcdIpcSharedPlcrAllocParams Pointer -*//***************************************************************************/ -#define FM_PCD_FREE_SHARED_PROFILES 10 +#define FM_PCD_GET_SW_PRS_OFFSET 10 /**************************************************************************//** @Function FM_PCD_MASTER_IS_ENABLED @@ -230,51 +222,6 @@ typedef _Packed struct t_FmPcdIpcReply *//***************************************************************************/ #define FM_PCD_GUEST_DISABLE 16 -/**************************************************************************//** - @Function FM_PCD_DUMP_REGS - - @Description Used by FM front-end to dump all PCD registers - - @Param[in] None -*//***************************************************************************/ -#define FM_PCD_DUMP_REGS 17 - -/**************************************************************************//** - @Function FM_PCD_KG_DUMP_REGS - - @Description Used by FM front-end to dump KG registers - - @Param[in] None -*//***************************************************************************/ -#define FM_PCD_KG_DUMP_REGS 18 - -/**************************************************************************//** - @Function FM_PCD_PLCR_DUMP_REGS - - @Description Used by FM front-end to dump PLCR registers - - @Param[in] None -*//***************************************************************************/ -#define FM_PCD_PLCR_DUMP_REGS 19 - -/**************************************************************************//** - @Function FM_PCD_PLCR_PROFILE_DUMP_REGS - - @Description Used by FM front-end to dump PLCR specified profile registers - - @Param[in] t_Handle Pointer -*//***************************************************************************/ -#define FM_PCD_PLCR_PROFILE_DUMP_REGS 20 - -/**************************************************************************//** - @Function FM_PCD_PRS_DUMP_REGS - - @Description Used by FM front-end to dump PRS registers - - @Param[in] None -*//***************************************************************************/ -#define FM_PCD_PRS_DUMP_REGS 21 - /**************************************************************************//** @Function FM_PCD_FREE_KG_CLSPLAN @@ -282,7 +229,7 @@ typedef _Packed struct t_FmPcdIpcReply @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer *//***************************************************************************/ -#define FM_PCD_FREE_KG_CLSPLAN 22 +#define FM_PCD_FREE_KG_CLSPLAN 22 /**************************************************************************//** @Function FM_PCD_ALLOC_KG_CLSPLAN @@ -291,7 +238,7 @@ typedef _Packed struct t_FmPcdIpcReply @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer *//***************************************************************************/ -#define FM_PCD_ALLOC_KG_CLSPLAN 23 +#define FM_PCD_ALLOC_KG_CLSPLAN 23 /**************************************************************************//** @Function FM_PCD_MASTER_IS_ALIVE @@ -319,6 +266,13 @@ typedef _Packed struct t_FmPcdIpcReply @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer *//***************************************************************************/ #define FM_PCD_PRS_INC_PORT_STATS 26 + +#if (DPAA_VERSION >= 11) +/* TODO - doc */ +#define FM_PCD_ALLOC_SP 27 +#endif /* (DPAA_VERSION >= 11) */ + + /** @} */ /* end of FM_PCD_IPC_grp group */ /** @} */ /* end of FM_grp group */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c index b9f5128d43d3..f23d8b8168b2 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,11 +30,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_plcr.c @Description FM PCD POLICER... *//***************************************************************************/ +#include #include "std_ext.h" #include "error_ext.h" #include "string_ext.h" @@ -46,17 +48,70 @@ #include "fm_pcd.h" #include "fm_hc.h" #include "fm_pcd_ipc.h" +#include "fm_plcr.h" -static bool FmPcdPlcrIsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId) +/****************************************/ +/* static functions */ +/****************************************/ + +static uint32_t PlcrProfileLock(t_Handle h_Profile) +{ + ASSERT_COND(h_Profile); + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); +} + +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags) +{ + ASSERT_COND(h_Profile); + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags); +} + +static bool PlcrProfileFlagTryLock(t_Handle h_Profile) +{ + ASSERT_COND(h_Profile); + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); +} + +static void PlcrProfileFlagUnlock(t_Handle h_Profile) +{ + ASSERT_COND(h_Profile); + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); +} + +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr) +{ + ASSERT_COND(h_FmPcdPlcr); + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock); +} + +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags) +{ + ASSERT_COND(h_FmPcdPlcr); + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags); +} + +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr) +{ + ASSERT_COND(h_FmPcdPlcr); + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock); +} + +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags) +{ + ASSERT_COND(h_FmPcdPlcr); + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags); +} + +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; uint16_t i; SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE); - for(i=0;ip_FmPcdPlcr->numOfSharedProfiles;i++) - if(p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId) + for (i=0;ip_FmPcdPlcr->numOfSharedProfiles;i++) + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId) return TRUE; return FALSE; } @@ -64,8 +119,8 @@ static bool FmPcdPlcrIsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileI static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction) { uint32_t nia; - uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_NextEngineParams->h_Profile)-1); - uint8_t relativeSchemeId, physicatSchemeId; + uint16_t absoluteProfileId; + uint8_t relativeSchemeId, physicalSchemeId; nia = FM_PCD_PLCR_NIA_VALID; @@ -75,31 +130,32 @@ static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcd switch (p_NextEngineParams->action) { case e_FM_PCD_DROP_FRAME : - nia |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD); + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); break; case e_FM_PCD_ENQ_FRAME: - nia |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); break; default: RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } break; case e_FM_PCD_KG: - physicatSchemeId = (uint8_t)(PTR_TO_UINT(p_NextEngineParams->h_DirectScheme)-1); - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicatSchemeId); - if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme); + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); - if (!FmPcdKgIsSchemeValidSw(p_FmPcd, relativeSchemeId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme.")); - if(!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId)) + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme.")); + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId)) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct.")); - nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicatSchemeId; + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId; break; case e_FM_PCD_PLCR: - if(!FmPcdPlcrIsProfileShared(p_FmPcd, absoluteProfileId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile")); - if(!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile ")); + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId; + if (!IsProfileShared(p_FmPcd, absoluteProfileId)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile")); + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile ")); nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId; break; default: @@ -111,24 +167,24 @@ static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcd return E_OK; } -static uint32_t FPP_Function(uint32_t fpp) +static uint32_t CalcFPP(uint32_t fpp) { - if(fpp > 15) + if (fpp > 15) return 15 - (0x1f - fpp); else return 16 + fpp; } -static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode, - uint32_t rate, - uint64_t tsuInTenthNano, - uint32_t fppShift, - uint64_t *p_Integer, - uint64_t *p_Fraction) +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode, + uint32_t rate, + uint64_t tsuInTenthNano, + uint32_t fppShift, + uint64_t *p_Integer, + uint64_t *p_Fraction) { uint64_t tmp, div; - if(rateMode == e_FM_PCD_PLCR_BYTE_MODE) + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE) { /* now we calculate the initial integer for the bigger rate */ /* from Kbps to Bytes/TSU */ @@ -150,46 +206,66 @@ static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode, div = 1000000000; /* nano */ div *= 10; /* 10 nano */ } - *p_Integer = (tmp<h_Fm); /* TimeStamp per nano seconds units */ /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */ - tsuInTenthNanos = (uint32_t)(1000*10/(1<comittedInfoRate > p_NonPassthroughAlgParam->peakOrAccessiveInfoRate) - GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, 0, &integer, &fraction); + /* The meaning of this step: + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count. + * In this configuration we calculate the integer and fraction that represent the higher infoRate + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at + * high rate, as many bits as possible for fraction at low rate. + */ + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate) + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction); else - GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, 0, &integer, &fraction); - + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction); /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and * the LSB bits are for the fraction */ temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF); /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll - * take max fpp=31. + * take max FP = 31. * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is * limited by the 10G physical port. */ - if(temp != 0) + if (temp != 0) { + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits. + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s + * in the integer part of the cir/pir register, than these bits are wasted. So we want + * to use these bits for the fraction. in this way we will have for fraction - the number + * of "0" bits and the rest - for integer. + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS + * one bit to the left - preserving the relationship and achieving more bits + * for integer in the TS. + */ + /* count zeroes left of the higher used bit (in order to shift the value such that * unused bits may be used for fraction). */ @@ -198,7 +274,7 @@ static void calcRates(t_Handle h_FmPcd, t_FmPcdPlcrNonPassthroughAlgParams *p_No temp = temp << 1; fppShift++; } - if(fppShift > 15) + if (fppShift > 15) { REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small")); return; @@ -207,12 +283,12 @@ static void calcRates(t_Handle h_FmPcd, t_FmPcdPlcrNonPassthroughAlgParams *p_No else { temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */ - if(!temp) - /* integer and fraction are 0, we set fpp to its max val */ + if (!temp) + /* integer and fraction are 0, we set FP to its max val */ fppShift = 31; else { - /* integer was 0 but fraction is not. fpp is 16 for the integer, + /* integer was 0 but fraction is not. FP is 16 for the fraction, * + all left zeroes of the fraction. */ fppShift=16; /* count zeroes left of the higher used bit (in order to shift the value such that @@ -227,20 +303,22 @@ static void calcRates(t_Handle h_FmPcd, t_FmPcdPlcrNonPassthroughAlgParams *p_No } /* - * This means that the FM TS register will now be used so that 'count' bits are for + * This means that the FM TS register will now be used so that 'fppShift' bits are for * fraction and the rest for integer */ - /* now we re-calculate cir */ - GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); + /* now we re-calculate cir and pir_eir with the calculated FP */ + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); - GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); - *cbs = p_NonPassthroughAlgParam->comittedBurstSize; - *pbs_ebs = p_NonPassthroughAlgParam->peakOrAccessiveBurstSize; - - /* get fpp as it should be written to reg.*/ - *fpp = FPP_Function(fppShift); + *cbs = p_NonPassthroughAlgParam->committedBurstSize; + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize; + /* convert FP as it should be written to reg. + * 0-15 --> 16-31 + * 16-31 --> 0-15 + */ + *fpp = CalcFPP(fppShift); } static void WritePar(t_FmPcd *p_FmPcd, uint32_t par) @@ -250,443 +328,37 @@ static void WritePar(t_FmPcd *p_FmPcd, uint32_t par) ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par); - while(GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ; - + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ; } -/*********************************************/ -/*............Policer Exception..............*/ -/*********************************************/ -static void PcdPlcrException(t_Handle h_FmPcd) +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd, + t_FmPcdPlcrProfileParams *p_ProfileParams, + t_FmPcdPlcrProfileRegs *p_PlcrRegs) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t event, mask, force; + t_Error err = E_OK; + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro; - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr); - mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); + ASSERT_COND(p_FmPcd); - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr); - if(force & event) - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event); - - - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event); - - if(event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE) - p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE); - if(event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE) - p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE); - -} - -/* ..... */ - -static void PcdPlcrErrorException(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t event, force, captureReg, mask; - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr); - mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); - - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr); - if(force & event) - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event); - - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event); - - if(event & FM_PCD_PLCR_DOUBLE_ECC) - p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC); - if(event & FM_PCD_PLCR_INIT_ENTRY_ERROR) - { - captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr); - /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP); - p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK); - p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ; - p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/ - p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK)); - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP); - } -} - -void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); - - if(add) - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners++; - else - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners--; -} - -uint32_t FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); - - return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners; -} -uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); - - return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction; -} - -t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdIpcPlcrAllocParams ipcPlcrParams; - t_Error err = E_OK; - uint16_t base; - uint16_t swPortIndex = 0; - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - if(!numOfProfiles) - return E_OK; - - memset(&ipcPlcrParams, 0, sizeof(ipcPlcrParams)); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - /* Alloc resources using IPC messaging */ - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - ipcPlcrParams.num = numOfProfiles; - ipcPlcrParams.hardwarePortId = hardwarePortId; - msg.msgId = FM_PCD_ALLOC_PROFILES; - memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams)); - replyLength = sizeof(uint32_t) + sizeof(uint16_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(ipcPlcrParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err,NO_MSG); - if (replyLength != sizeof(uint32_t) + sizeof(uint16_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - if((t_Error)reply.error != E_OK) - RETURN_ERROR(MAJOR, (t_Error)reply.error, ("PLCR profiles allocation failed")); - - memcpy((uint8_t*)&base, reply.replyBody, sizeof(uint16_t)); - } - else /* master */ - { - err = PlcrAllocProfiles(p_FmPcd, hardwarePortId, numOfProfiles, &base); - if(err) - RETURN_ERROR(MAJOR, err,NO_MSG); - } - HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); - - p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles; - p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = base; - - return E_OK; -} - -t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdIpcPlcrAllocParams ipcPlcrParams; - t_Error err = E_OK; - uint16_t swPortIndex = 0; - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - /* Alloc resources using IPC messaging */ - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - ipcPlcrParams.num = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles; - ipcPlcrParams.hardwarePortId = hardwarePortId; - ipcPlcrParams.plcrProfilesBase = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; - msg.msgId = FM_PCD_FREE_PROFILES; - memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(ipcPlcrParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err,NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - if ((t_Error)reply.error != E_OK) - RETURN_ERROR(MINOR, (t_Error)reply.error, ("PLCR Free Profiles failed")); - } - else /* master */ - { - err = PlcrFreeProfiles(p_FmPcd, hardwarePortId, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase); - if(err) - RETURN_ERROR(MAJOR, err,NO_MSG); - } - p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0; - p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0; - - return E_OK; -} - -bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; - - return p_FmPcdPlcr->profiles[absoluteProfileId].valid; -} - -t_Error PlcrAllocProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t *p_Base) -{ - t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; - uint32_t profilesFound, log2Num, tmpReg32; - uint32_t intFlags; - uint16_t first, i; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - if(!numOfProfiles) - return E_OK; - - ASSERT_COND(hardwarePortId); - - if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) - RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); - - if (!POWER_OF_2(numOfProfiles)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); - - intFlags = FmPcdLock(p_FmPcd); - - if(GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The requesting port has already an allocated profiles window.")); - } - - first = 0; - profilesFound = 0; - for(i=0;ip_FmPcdPlcr->profiles[i].profilesMng.allocated) - { - profilesFound++; - i++; - if(profilesFound == numOfProfiles) - break; - } - else - { - profilesFound = 0; - /* advance i to the next aligned address */ - first = i = (uint8_t)(first + numOfProfiles); - } - } - if(profilesFound == numOfProfiles) - { - for(i = first; ip_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE; - p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId; - } - } - else - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); - } - - /**********************FMPL_PMRx******************/ - LOG2((uint64_t)numOfProfiles, log2Num); - tmpReg32 = first; - tmpReg32 |= log2Num << 16; - tmpReg32 |= FM_PCD_PLCR_PMR_V; - WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32); - - *p_Base = first; - - FmPcdUnlock(p_FmPcd, intFlags); - - return E_OK; -} - -t_Error PlcrAllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) -{ - uint32_t profilesFound; - uint16_t i, k=0; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - if(!numOfProfiles) - return E_OK; - - if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) - RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); - - profilesFound = 0; - for(i=0;ip_FmPcdPlcr->profiles[i].profilesMng.allocated) - { - profilesFound++; - profilesIds[k] = i; - k++; - if(profilesFound == numOfProfiles) - break; - } - } - if(profilesFound != numOfProfiles) - RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG); - for(i = 0;ip_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE; - p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0; - } - - return E_OK; -} - -t_Error PlcrFreeProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t base) -{ - t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; - uint16_t i; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0); - - for(i = base; ip_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId); - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated); - - p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE; - p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = 0; - } - - return E_OK; -} - -void PlcrFreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) -{ - uint16_t i; - - SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); - - ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); - for(i=0;ip_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated); - p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE; - } -} - -void PlcrEnable(t_FmPcd *p_FmPcd) -{ - t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; - - WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN); -} - -void PlcrDisable(t_FmPcd *p_FmPcd) -{ - t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; - - WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN); -} - -t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t tmpReg32; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - - if(!FmIsMaster(p_FmPcd->h_Fm)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!")); - - tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr); - if(enable) - tmpReg32 |= FM_PCD_PLCR_GCR_STEN; - else - tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN; - - WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32); - return E_OK; -} - -t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - - if(!FmIsMaster(p_FmPcd->h_Fm)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!")); - - p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable; - - return E_OK; -} - - -t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile, t_FmPcdPlcrInterModuleProfileRegs *p_PlcrRegs) -{ - - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_Error err = E_OK; - uint32_t pemode, gnia, ynia, rnia; + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); + if (bitFor1Micro == 0) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); /* Set G, Y, R Nia */ - err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnGreen, &(p_Profile->paramsOnGreen), &gnia); - if(err) + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnYellow, &(p_Profile->paramsOnYellow), &ynia); - if(err) + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnRed, &(p_Profile->paramsOnRed), &rnia); - if(err) + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia); + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); - /* Mode fmpl_pemode */ pemode = FM_PCD_PLCR_PEMODE_PI; - switch (p_Profile->algSelection) + switch (p_ProfileParams->algSelection) { case e_FM_PCD_PLCR_PASS_THROUGH: p_PlcrRegs->fmpl_pecir = 0; @@ -697,11 +369,11 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof p_PlcrRegs->fmpl_pects = 0; p_PlcrRegs->fmpl_pepts_ets = 0; pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK; - switch (p_Profile->colorMode) + switch (p_ProfileParams->colorMode) { case e_FM_PCD_PLCR_COLOR_BLIND: pemode |= FM_PCD_PLCR_PEMODE_CBLND; - switch (p_Profile->color.dfltColor) + switch (p_ProfileParams->color.dfltColor) { case e_FM_PCD_PLCR_GREEN: pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK; @@ -731,15 +403,15 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof case e_FM_PCD_PLCR_RFC_2698: /* Select algorithm MODE[ALG] = "01" */ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698; - if (p_Profile->nonPassthroughAlgParams.comittedInfoRate > p_Profile->nonPassthroughAlgParams.peakOrAccessiveInfoRate) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than comittedInfoRate.")); + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate.")); goto cont_rfc; case e_FM_PCD_PLCR_RFC_4115: /* Select algorithm MODE[ALG] = "10" */ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115; cont_rfc: /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */ - switch (p_Profile->colorMode) + switch (p_ProfileParams->colorMode) { case e_FM_PCD_PLCR_COLOR_BLIND: pemode |= FM_PCD_PLCR_PEMODE_CBLND; @@ -747,7 +419,7 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof case e_FM_PCD_PLCR_COLOR_AWARE: pemode &= ~FM_PCD_PLCR_PEMODE_CBLND; /*In color aware more select override color interpretation (MODE[OVCLR]) */ - switch (p_Profile->color.override) + switch (p_ProfileParams->color.override) { case e_FM_PCD_PLCR_GREEN: pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK; @@ -769,11 +441,11 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */ - switch (p_Profile->nonPassthroughAlgParams.rateMode) + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode) { case e_FM_PCD_PLCR_BYTE_MODE : pemode &= ~FM_PCD_PLCR_PEMODE_PKT; - switch (p_Profile->nonPassthroughAlgParams.byteModeParams.frameLengthSelection) + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection) { case e_FM_PCD_PLCR_L2_FRM_LEN: pemode |= FM_PCD_PLCR_PEMODE_FLS_L2; @@ -790,7 +462,7 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof default: RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } - switch (p_Profile->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection) + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection) { case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN: pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS; @@ -816,7 +488,7 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof { uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0; - calcRates(h_FmPcd, &p_Profile->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp); + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp); /* Set Committed Information Rate (CIR) */ p_PlcrRegs->fmpl_pecir = cir; @@ -857,26 +529,153 @@ t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Prof return E_OK; } -void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t profilesFound; + uint16_t i, k=0; + uint32_t intFlags; - ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + if (!numOfProfiles) + return E_OK; + + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); + + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); + /* Find numOfProfiles free profiles (may be spread) */ + profilesFound = 0; + for (i=0;ip_FmPcdPlcr->profiles[i].profilesMng.allocated) + { + profilesFound++; + profilesIds[k] = i; + k++; + if (profilesFound == numOfProfiles) + break; + } + + if (profilesFound != numOfProfiles) + { + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG); + } + + for (i = 0;ip_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE; + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0; + } + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + + return E_OK; } -void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) +{ + uint16_t i; + + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); + + ASSERT_COND(numOfProfiles); + + for (i=0; i < numOfProfiles; i++) + { + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated); + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE; + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId; + } +} + +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + /* this routine is protected by calling routine */ + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE; + + if (set) + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE; + else + { + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0; + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE; + } } +/*********************************************/ +/*............Policer Exception..............*/ +/*********************************************/ +static void EventsCB(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t event, mask, force; + + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr); + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); + + event &= mask; + + /* clear the forced events */ + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr); + if (force & event) + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event); + + + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event); + + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE) + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE); + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE) + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE); +} + +/* ..... */ + +static void ErrorExceptionsCB(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t event, force, captureReg, mask; + + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr); + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); + + event &= mask; + + /* clear the forced events */ + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr); + if (force & event) + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event); + + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event); + + if (event & FM_PCD_PLCR_DOUBLE_ECC) + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC); + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR) + { + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr); + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP); + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK); + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ; + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/ + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK)); + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP); + } +} + + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) { t_FmPcdPlcr *p_FmPcdPlcr; - /*uint8_t i=0;*/ + uint16_t i=0; UNUSED(p_FmPcd); UNUSED(p_FmPcdParams); @@ -888,14 +687,24 @@ t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) return NULL; } memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr)); - if(p_FmPcd->guestId == NCSW_MASTER_ID) + if (p_FmPcd->guestId == NCSW_MASTER_ID) { p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm)); p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh; p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions); } - p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles; + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles; + + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase; + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles; + /* for backward compatabilty. if no policer profile, will set automatically to the max */ + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0)) + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES; + + for (i=0; iprofiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; return p_FmPcdPlcr; } @@ -904,68 +713,47 @@ t_Error PlcrInit(t_FmPcd *p_FmPcd) { t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; - uint32_t tmpReg32 = 0; - t_Error err = E_OK; t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; - t_FmPcdIpcMsg msg; - uint32_t replyLength; - t_FmPcdIpcReply reply; + t_Error err = E_OK; + uint32_t tmpReg32 = 0; + uint16_t base; - if ((p_FmPcd->guestId != NCSW_MASTER_ID) && - (p_FmPcdPlcr->numOfSharedProfiles)) + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!")); + + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock(); + if (!p_FmPcdPlcr->h_HwSpinlock) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock")); + + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock(); + if (!p_FmPcdPlcr->h_SwSpinlock) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock")); + + base = PlcrAllocProfilesForPartition(p_FmPcd, + p_FmPcdPlcr->partPlcrProfilesBase, + p_FmPcdPlcr->partNumOfPlcrProfiles, + p_FmPcd->guestId); + if (base == (uint16_t)ILLEGAL_BASE) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); + + if (p_FmPcdPlcr->numOfSharedProfiles) { - int i, j, index = 0; - uint32_t walking1Mask = 0x80000000; - uint32_t sharedProfilesMask[FM_PCD_PLCR_NUM_ENTRIES/32]; - - memset(sharedProfilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t)); - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_ALLOC_SHARED_PROFILES; - memcpy(msg.msgBody, (uint8_t *)&p_FmPcdPlcr->numOfSharedProfiles, sizeof(uint16_t)); - replyLength = sizeof(uint32_t) + sizeof(sharedProfilesMask); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId)+ sizeof(p_FmPcdPlcr->numOfSharedProfiles), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err,NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(sharedProfilesMask))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - memcpy(sharedProfilesMask, reply.replyBody, sizeof(sharedProfilesMask)); - /* translate 8 regs of 32 bits masks into an array of up to 256 indexes. */ - for(i = 0; ip_FmPcdPlcr->sharedProfilesIds[index++] = (uint16_t)(i*32+j); - walking1Mask >>= 1; - } - walking1Mask = 0x80000000; - } - } - return (t_Error)reply.error; - } - - if(p_FmPcdPlcr->numOfSharedProfiles) - { - err = PlcrAllocSharedProfiles(p_FmPcd, p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds); - if(err) + err = AllocSharedProfiles(p_FmPcd, + p_FmPcdPlcr->numOfSharedProfiles, + p_FmPcdPlcr->sharedProfilesIds); + if (err) RETURN_ERROR(MAJOR, err,NO_MSG); } + if (p_FmPcd->guestId != NCSW_MASTER_ID) + return E_OK; + /**********************FMPL_GCR******************/ tmpReg32 = 0; tmpReg32 |= FM_PCD_PLCR_GCR_STEN; - if(p_Param->plcrAutoRefresh) + if (p_Param->plcrAutoRefresh) tmpReg32 |= FM_PCD_PLCR_GCR_DAR; - tmpReg32 |= NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME; + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32); /**********************FMPL_GCR******************/ @@ -975,12 +763,12 @@ t_Error PlcrInit(t_FmPcd *p_FmPcd) /**********************FMPL_EEVR******************/ /**********************FMPL_EIER******************/ tmpReg32 = 0; - if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC) + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC) { FmEnableRamsEcc(p_FmPcd->h_Fm); tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC; } - if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR; WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32); /**********************FMPL_EIER******************/ @@ -990,16 +778,26 @@ t_Error PlcrInit(t_FmPcd *p_FmPcd) /**********************FMPL_EVR******************/ /**********************FMPL_IER******************/ tmpReg32 = 0; - if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE) + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE) tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; - if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE ) + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE) tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32); /**********************FMPL_IER******************/ /* register even if no interrupts enabled, to allow future enablement */ - FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR, PcdPlcrErrorException, p_FmPcd); - FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL, PcdPlcrException, p_FmPcd); + FmRegisterIntr(p_FmPcd->h_Fm, + e_FM_MOD_PLCR, + 0, + e_FM_INTR_TYPE_ERR, + ErrorExceptionsCB, + p_FmPcd); + FmRegisterIntr(p_FmPcd->h_Fm, + e_FM_MOD_PLCR, + 0, + e_FM_INTR_TYPE_NORMAL, + EventsCB, + p_FmPcd); /* driver initializes one DFLT profile at the last entry*/ /**********************FMPL_DPMR******************/ @@ -1012,49 +810,542 @@ t_Error PlcrInit(t_FmPcd *p_FmPcd) t_Error PlcrFree(t_FmPcd *p_FmPcd) { - t_Error err; - t_FmPcdIpcSharedPlcrAllocParams ipcSharedPlcrParams; - t_FmPcdIpcMsg msg; - FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR); FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL); - if(p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles) - { - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - int i; - memset(ipcSharedPlcrParams.sharedProfilesMask, 0, sizeof(ipcSharedPlcrParams.sharedProfilesMask)); - /* Free resources using IPC messaging */ - ipcSharedPlcrParams.num = p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles; + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles) + FreeSharedProfiles(p_FmPcd, + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles, + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds); - /* translate the allocated profile id's to a 32bit * 8regs mask */ - for(i = 0;ip_FmPcdPlcr->numOfSharedProfiles;i++) - ipcSharedPlcrParams.sharedProfilesMask[p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i]/32] |= (0x80000000 >> (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] % 32)); + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles) + PlcrFreeProfilesForPartition(p_FmPcd, + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles, + p_FmPcd->guestId); + + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock) + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock); + + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock) + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock); - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_FREE_SHARED_PROFILES; - memcpy(msg.msgBody, &ipcSharedPlcrParams, sizeof(ipcSharedPlcrParams)); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(ipcSharedPlcrParams), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err,NO_MSG); - } - /* else - PlcrFreeSharedProfiles(p_FmPcd, p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);*/ - } return E_OK; } -t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd, - e_FmPcdProfileTypeSelection profileType, - t_Handle h_FmPort, - uint16_t relativeProfile, - uint16_t *p_AbsoluteId) +void PlcrEnable(t_FmPcd *p_FmPcd) +{ + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; + + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN); +} + +void PlcrDisable(t_FmPcd *p_FmPcd) +{ + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; + + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN); +} + +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId) +{ + uint32_t intFlags; + uint16_t profilesFound = 0; + int i = 0; + + ASSERT_COND(p_FmPcd); + ASSERT_COND(p_FmPcd->p_FmPcdPlcr); + + if (!numOfProfiles) + return 0; + + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) || + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES)) + return (uint16_t)ILLEGAL_BASE; + + if (p_FmPcd->h_IpcSession) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmPcdIpcMsg msg; + t_FmPcdIpcReply reply; + t_Error err; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = p_FmPcd->guestId; + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles; + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase; + msg.msgId = FM_PCD_ALLOC_PROFILES; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + replyLength = sizeof(uint32_t) + sizeof(uint16_t); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if ((err != E_OK) || + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t)))) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + return (uint16_t)ILLEGAL_BASE; + } + else + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t)); + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + return (uint16_t)ILLEGAL_BASE; + } + } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + { + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!")); + return (uint16_t)ILLEGAL_BASE; + } + + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); + for (i=base; i<(base+numOfProfiles); i++) + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE) + profilesFound++; + else + break; + + if (profilesFound == numOfProfiles) + for (i=base; i<(base+numOfProfiles); i++) + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId; + else + { + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); + return (uint16_t)ILLEGAL_BASE; + } + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); + + return base; +} + +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId) +{ + int i = 0; + + ASSERT_COND(p_FmPcd); + ASSERT_COND(p_FmPcd->p_FmPcdPlcr); + + if (p_FmPcd->h_IpcSession) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmPcdIpcMsg msg; + t_Error err; + + memset(&msg, 0, sizeof(msg)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = p_FmPcd->guestId; + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles; + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase; + msg.msgId = FM_PCD_FREE_PROFILES; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MAJOR, err, NO_MSG); + return; + } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + { + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!")); + return; + } + + for (i=base; i<(base+numOfProfiles); i++) + { + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId) + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; + else + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition")); + } +} + +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd, + uint8_t hardwarePortId, + uint16_t numOfProfiles, + uint16_t base) +{ + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; + uint32_t log2Num, tmpReg32; + + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + !p_Regs && + p_FmPcd->h_IpcSession) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmPcdIpcMsg msg; + t_Error err; + + memset(&msg, 0, sizeof(msg)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = hardwarePortId; + ipcAllocParams.num = numOfProfiles; + ipcAllocParams.base = base; + msg.msgId = FM_PCD_SET_PORT_PROFILES; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + return E_OK; + } + else if (!p_Regs) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("The requesting port has already an allocated profiles window.")); + + /**********************FMPL_PMRx******************/ + LOG2((uint64_t)numOfProfiles, log2Num); + tmpReg32 = base; + tmpReg32 |= log2Num << 16; + tmpReg32 |= FM_PCD_PLCR_PMR_V; + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32); + + return E_OK; +} + +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) +{ + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; + + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + !p_Regs && + p_FmPcd->h_IpcSession) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmPcdIpcMsg msg; + t_Error err; + + memset(&msg, 0, sizeof(msg)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = hardwarePortId; + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + return E_OK; + } + else if (!p_Regs) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0); + + return E_OK; +} + +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_Error err = E_OK; + uint32_t profilesFound; + uint32_t intFlags; + uint16_t i, first, swPortIndex = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + + if (!numOfProfiles) + return E_OK; + + ASSERT_COND(hardwarePortId); + + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); + + if (!POWER_OF_2(numOfProfiles)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); + + first = 0; + profilesFound = 0; + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); + + for (i=0; ip_FmPcdPlcr->profiles[i].profilesMng.allocated) + { + profilesFound++; + i++; + if (profilesFound == numOfProfiles) + break; + } + else + { + profilesFound = 0; + /* advance i to the next aligned address */ + i = first = (uint16_t)(first + numOfProfiles); + } + } + + if (profilesFound == numOfProfiles) + { + for (i=first; ip_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE; + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId; + } + } + else + { + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); + } + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first); + if (err) + { + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles; + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first; + + return E_OK; +} + +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_Error err = E_OK; + uint32_t intFlags; + uint16_t i, swPortIndex = 0; + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); + + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId); + if (err) + RETURN_ERROR(MAJOR, err,NO_MSG); + + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles); + i++) + { + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId); + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated); + + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE; + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId; + } + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0; + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0; + + return E_OK; +} + +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs; + uint32_t tmpReg32, intFlags; + t_Error err; + + /* Calling function locked all PCD modules, so no need to lock here */ + + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range")); + + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid")); + + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/ + + if (p_FmPcd->h_Hc) + { + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction); + + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE); + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction); + + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + return err; + } + + /* lock the HW because once we read the registers we don't want them to be changed + * by another access. (We can copy to a tmp location and release the lock!) */ + + intFlags = PlcrHwLock(p_FmPcdPlcr); + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); + + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag || + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction)) + { + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) + { + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) || + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) || + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE)) + { + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE")); + } + + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME) + { + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia); + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) + { + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); + } + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32); + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; + WritePar(p_FmPcd, tmpReg32); + } + + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME) + { + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia); + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) + { + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); + } + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32); + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; + WritePar(p_FmPcd, tmpReg32); + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + } + + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME) + { + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia); + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) + { + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); + } + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32); + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; + WritePar(p_FmPcd, tmpReg32); + + } + } + } + PlcrHwUnlock(p_FmPcdPlcr, intFlags); + + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE); + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction); + + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ + + return E_OK; +} + +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag; +} + +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction; +} + +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; + + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES); + + return p_FmPcdPlcr->profiles[absoluteProfileId].valid; +} + +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t intFlags; + + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]); + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE; + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags); +} + +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t intFlags; + + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]); + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE; + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags); +} + +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile) +{ + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId; +} + +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd, + e_FmPcdProfileTypeSelection profileType, + t_Handle h_FmPort, + uint16_t relativeProfile, + uint16_t *p_AbsoluteId) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; @@ -1064,26 +1355,27 @@ t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd, { case e_FM_PCD_PLCR_PORT_PRIVATE: /* get port PCD id from port handle */ - for(i=0;ip_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort) + for (i=0;ip_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort) break; if (i == FM_MAX_NUM_OF_PORTS) RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle.")); - if(!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles")); - if(relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile); break; case e_FM_PCD_PLCR_SHARED: - if(relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles) + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles) RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]); break; default: RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type")); } + return E_OK; } @@ -1123,7 +1415,7 @@ uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId) bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg) { - if(profileModeReg & FM_PCD_PLCR_PEMODE_PI) + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI) return TRUE; else return FALSE; @@ -1139,17 +1431,17 @@ uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId) uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter) { - switch(counter) + switch (counter) { - case(e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER): + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER): return FM_PCD_PLCR_PAR_PWSEL_PEGPC; - case(e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER): + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER): return FM_PCD_PLCR_PAR_PWSEL_PEYPC; - case(e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) : + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) : return FM_PCD_PLCR_PAR_PWSEL_PERPC; - case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) : + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) : return FM_PCD_PLCR_PAR_PWSEL_PERYPC; - case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) : + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) : return FM_PCD_PLCR_PAR_PWSEL_PERRPC; default: REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); @@ -1162,11 +1454,11 @@ uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red) uint32_t tmpReg32 = 0; - if(green) + if (green) tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; - if(yellow) + if (yellow) tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; - if(red) + if (red) tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; return tmpReg32; @@ -1176,127 +1468,199 @@ void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + /* this routine is protected by calling routine */ - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = requiredAction; + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); + + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction; } -t_Error FmPcdPlcrProfileTryLock(t_Handle h_FmPcd, uint16_t profileId, bool intr) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - bool ans; - if (intr) - ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock); - else - ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock); - if (ans) - return E_OK; - return ERROR_CODE(E_BUSY); -} +/*********************** End of inter-module routines ************************/ -void FmPcdPlcrReleaseProfileLock(t_Handle h_FmPcd, uint16_t profileId) -{ - RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdPlcr->profiles[profileId].lock); -} /**************************************************/ /*............Policer API.........................*/ /**************************************************/ -t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd, - t_FmPcdPlcrProfileParams *p_Profile) +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); + + if (!FmIsMaster(p_FmPcd->h_Fm)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!")); + + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable; + + return E_OK; +} + +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); + + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles; + + return E_OK; +} + +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable) +{ + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + uint32_t tmpReg32; + + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); + + if (!FmIsMaster(p_FmPcd->h_Fm)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!")); + + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr); + if (enable) + tmpReg32 |= FM_PCD_PLCR_GCR_STEN; + else + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN; + + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32); + return E_OK; +} + +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd, + t_FmPcdPlcrProfileParams *p_ProfileParams) +{ + t_FmPcd *p_FmPcd; t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; - t_FmPcdPlcrInterModuleProfileRegs plcrProfileReg; + t_FmPcdPlcrProfileRegs plcrProfileReg; uint32_t intFlags; uint16_t absoluteProfileId; t_Error err = E_OK; uint32_t tmpReg32; + t_FmPcdPlcrProfile *p_Profile; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + + if (p_ProfileParams->modify) + { + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile; + p_FmPcd = p_Profile->h_FmPcd; + absoluteProfileId = p_Profile->absoluteProfileId; + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); + return NULL; + } + + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); + + /* Try lock profile using flag */ + if (!PlcrProfileFlagTryLock(p_Profile)) + { + DBG(TRACE, ("Profile Try Lock - BUSY")); + /* Signal to caller BUSY condition */ + p_ProfileParams->id.h_Profile = NULL; + return NULL; + } + } + else + { + p_FmPcd = (t_FmPcd*)h_FmPcd; + + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); + + /* SMP: needs to be protected only if another core now changes the windows */ + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd, + p_ProfileParams->id.newParams.profileType, + p_ProfileParams->id.newParams.h_FmPort, + p_ProfileParams->id.newParams.relativeProfileId, + &absoluteProfileId); + if (err) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + return NULL; + } + + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); + return NULL; + } + + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) + { + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used")); + return NULL; + } + + /* initialize profile struct */ + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]; + + p_Profile->h_FmPcd = p_FmPcd; + p_Profile->absoluteProfileId = absoluteProfileId; + + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd); + if (!p_Profile->p_Lock) + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!")); + } - SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); - SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); + + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen; + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams)); + + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow; + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams)); + + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed; + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams)); + + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs)); + + /* build the policer profile registers */ + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg); + if (err) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + if (p_ProfileParams->modify) + /* unlock */ + PlcrProfileFlagUnlock(p_Profile); + if (!p_ProfileParams->modify && + p_Profile->p_Lock) + /* release allocated Profile lock */ + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); + return NULL; + } if (p_FmPcd->h_Hc) - return FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, p_Profile); + { + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg); + if (p_ProfileParams->modify) + PlcrProfileFlagUnlock(p_Profile); + if (err) + { + /* release the allocated scheme lock */ + if (!p_ProfileParams->modify && + p_Profile->p_Lock) + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); + + return NULL; + } + if (!p_ProfileParams->modify) + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId); + return (t_Handle)p_Profile; + } p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL); - if (p_Profile->modify) - { - absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_Profile->id.h_Profile)-1); - if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); - return NULL; - } - if (FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, FALSE)) - return NULL; - } - else - { - intFlags = FmPcdLock(p_FmPcd); - err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, - p_Profile->id.newParams.profileType, - p_Profile->id.newParams.h_FmPort, - p_Profile->id.newParams.relativeProfileId, - &absoluteProfileId); - if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); - return NULL; - } - if(err) - { - FmPcdUnlock(p_FmPcd, intFlags); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; - } - err = FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, TRUE); - FmPcdUnlock(p_FmPcd, intFlags); - if (err) - return NULL; - } - - /* if no override, check first that this profile is unused */ - if(!p_Profile->modify) - { - /* read specified profile into profile registers */ - tmpReg32 = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); - intFlags = FmPcdLock(p_FmPcd); - WritePar(p_FmPcd, tmpReg32); - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode); - FmPcdUnlock(p_FmPcd, intFlags); - if (tmpReg32 & FM_PCD_PLCR_PEMODE_PI) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used")); - return NULL; - } - } - - memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs)); - - err = FmPcdPlcrBuildProfile(h_FmPcd, p_Profile, &plcrProfileReg); - if(err) - { - RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); - REPORT_ERROR(MAJOR, err, NO_MSG); - return NULL; - } - - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnGreen = p_Profile->nextEngineOnGreen; - memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnGreen, &(p_Profile->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams)); - - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnYellow = p_Profile->nextEngineOnYellow; - memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnYellow, &(p_Profile->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams)); - - p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnRed = p_Profile->nextEngineOnRed; - memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnRed, &(p_Profile->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams)); - - intFlags = FmPcdLock(p_FmPcd); + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode); WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia); WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia); @@ -1317,55 +1681,75 @@ t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd, tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId); WritePar(p_FmPcd, tmpReg32); - FmPcdUnlock(p_FmPcd, intFlags); + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); - if (!p_Profile->modify) + if (!p_ProfileParams->modify) FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId); + else + PlcrProfileFlagUnlock(p_Profile); - RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock); - - return UINT_TO_PTR((uint64_t)absoluteProfileId+1); + return (t_Handle)p_Profile; } -t_Error FM_PCD_PlcrDeleteProfile(t_Handle h_FmPcd, t_Handle h_Profile) +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); - uint32_t tmpReg32, intFlags; + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; + t_FmPcd *p_FmPcd; + uint16_t profileIndx; + uint32_t tmpReg32, intFlags; + t_Error err; + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); + p_FmPcd = p_Profile->h_FmPcd; SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((profileIndx < FM_PCD_PLCR_NUM_ENTRIES), E_INVALID_SELECTION); - if (p_FmPcd->h_Hc) - return FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile); + profileIndx = p_Profile->absoluteProfileId; + + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE); FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx); - intFlags = FmPcdLock(p_FmPcd); + if (p_FmPcd->h_Hc) + { + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile); + if (p_Profile->p_Lock) + /* release allocated Profile lock */ + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); + + return err; + } + + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI); tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx); WritePar(p_FmPcd, tmpReg32); - FmPcdUnlock(p_FmPcd, intFlags); + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); + + if (p_Profile->p_Lock) + /* release allocated Profile lock */ + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); + + /* we do not memset profile as all its fields are being re-initialized at "set", + * plus its allocation information is still valid. */ return E_OK; } -/* ......... */ /***************************************************/ /*............Policer Profile Counter..............*/ /***************************************************/ -uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) { - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); - t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; - uint32_t intFlags, counterVal = 0; + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; + t_FmPcd *p_FmPcd; + uint16_t profileIndx; + uint32_t intFlags, counterVal = 0; + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; - SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); - SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); + p_FmPcd = p_Profile->h_FmPcd; + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); if (p_FmPcd->h_Hc) return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter); @@ -1373,21 +1757,16 @@ uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_Fm p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0); + profileIndx = p_Profile->absoluteProfileId; + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) { REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); return 0; } - intFlags = FmPcdLock(p_FmPcd); + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); - if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode))) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized profile")); - FmPcdUnlock(p_FmPcd, intFlags); - return 0; - } - switch (counter) { case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: @@ -1409,119 +1788,23 @@ uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_Fm REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); break; } - FmPcdUnlock(p_FmPcd, intFlags); + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); return counterVal; } - -t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction) +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value) { - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; - t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs; - uint32_t tmpReg32, intFlags; + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; + t_FmPcd *p_FmPcd; + uint16_t profileIndx; + uint32_t tmpReg32, intFlags; + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; - if (p_FmPcd->h_Hc) - return FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction); + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); - if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range")); - - if (FmPcdPlcrProfileTryLock(p_FmPcd, profileIndx, FALSE)) - RETURN_ERROR(MAJOR, E_INVALID_STATE,("Lock on PP FAILED")); - - intFlags = FmPcdLock(p_FmPcd); - WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); - - if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode))) - { - FmPcdUnlock(p_FmPcd, intFlags); - RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock); - RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid")); - } - - ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].valid); - - if(!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners || - !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction)) - { - if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) - { - if((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) || - (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) || - (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE)) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE")); - } - - if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME) - { - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia); - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); - } - tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; - WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32); - tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); - tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; - WritePar(p_FmPcd, tmpReg32); - } - - if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME) - { - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia); - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); - } - tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; - WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32); - tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); - tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; - WritePar(p_FmPcd, tmpReg32); - } - - if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME) - { - tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia); - if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) - { - FmPcdUnlock(p_FmPcd, intFlags); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); - } - tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; - WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32); - tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); - tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; - WritePar(p_FmPcd, tmpReg32); - } - } - } - FmPcdUnlock(p_FmPcd, intFlags); - - p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners += 1; - p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction |= requiredAction; - - RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock); - - return E_OK; -} - -t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); - t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; - uint32_t tmpReg32, intFlags; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); + p_FmPcd = p_Profile->h_FmPcd; + profileIndx = p_Profile->absoluteProfileId; if (p_FmPcd->h_Hc) return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value); @@ -1529,7 +1812,7 @@ t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmP p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE); - intFlags = FmPcdLock(p_FmPcd); + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); switch (counter) { case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: @@ -1548,6 +1831,7 @@ t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmP WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value); break; default: + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); } @@ -1557,146 +1841,7 @@ t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmP tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter); WritePar(p_FmPcd, tmpReg32); - FmPcdUnlock(p_FmPcd, intFlags); + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); return E_OK; } - -t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - - p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles; - - return E_OK; -} - - -/* ... */ - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - int i = 0; - t_FmPcdIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_PLCR_DUMP_REGS; - return XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL); - } - else - { - DUMP_SUBTITLE(("\n")); - DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Regs")); - - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gcr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gsr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_evr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ier); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ifr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eevr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eier); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eifr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rpcnt); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ypcnt); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rrpcnt); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rypcnt); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_tpcnt); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_flmcnt); - - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_serc); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_upcr); - DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_dpmr); - - - DUMP_TITLE(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr, ("fmpl_pmr")); - DUMP_SUBSTRUCT_ARRAY(i, 63) - { - DUMP_MEMORY(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i], sizeof(uint32_t)); - } - - return E_OK; - } -} - -t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_FmPcd, t_Handle h_Profile) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdPlcrInterModuleProfileRegs *p_ProfilesRegs; - uint32_t tmpReg, intFlags; - uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1); - t_FmPcdIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_PLCR_PROFILE_DUMP_REGS; - memcpy(msg.msgBody, (uint8_t *)&h_Profile, sizeof(uint32_t)); - return XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(uint32_t), - NULL, - NULL, - NULL, - NULL); - } - else - { - DUMP_SUBTITLE(("\n")); - DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Profile Regs")); - - p_ProfilesRegs = &p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs; - - tmpReg = FmPcdPlcrBuildReadPlcrActionReg((uint16_t)profileIndx); - intFlags = FmPcdLock(p_FmPcd); - WritePar(p_FmPcd, tmpReg); - - DUMP_TITLE(p_ProfilesRegs, ("Profile %d regs", profileIndx)); - - DUMP_VAR(p_ProfilesRegs, fmpl_pemode); - DUMP_VAR(p_ProfilesRegs, fmpl_pegnia); - DUMP_VAR(p_ProfilesRegs, fmpl_peynia); - DUMP_VAR(p_ProfilesRegs, fmpl_pernia); - DUMP_VAR(p_ProfilesRegs, fmpl_pecir); - DUMP_VAR(p_ProfilesRegs, fmpl_pecbs); - DUMP_VAR(p_ProfilesRegs, fmpl_pepepir_eir); - DUMP_VAR(p_ProfilesRegs, fmpl_pepbs_ebs); - DUMP_VAR(p_ProfilesRegs, fmpl_pelts); - DUMP_VAR(p_ProfilesRegs, fmpl_pects); - DUMP_VAR(p_ProfilesRegs, fmpl_pepts_ets); - DUMP_VAR(p_ProfilesRegs, fmpl_pegpc); - DUMP_VAR(p_ProfilesRegs, fmpl_peypc); - DUMP_VAR(p_ProfilesRegs, fmpl_perpc); - DUMP_VAR(p_ProfilesRegs, fmpl_perypc); - DUMP_VAR(p_ProfilesRegs, fmpl_perrpc); - FmPcdUnlock(p_FmPcd, intFlags); - - return E_OK; - } -} -#endif /* (defined(DEBUG_ERRORS) && ... */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.h new file mode 100644 index 000000000000..2bb8b969956c --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.h @@ -0,0 +1,165 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_plcr.h + + @Description FM Policer private header +*//***************************************************************************/ +#ifndef __FM_PLCR_H +#define __FM_PLCR_H + +#include "std_ext.h" + + +/***********************************************************************/ +/* Policer defines */ +/***********************************************************************/ + +#define FM_PCD_PLCR_PAR_GO 0x80000000 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF +#define FM_PCD_PLCR_PAR_R 0x40000000 + +/* shifts */ +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16 + +/* masks */ +#define FM_PCD_PLCR_PEMODE_PI 0x80000000 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000 + +#define FM_PCD_PLCR_NIA_VALID 0x80000000 + +#define FM_PCD_PLCR_GCR_EN 0x80000000 +#define FM_PCD_PLCR_GCR_STEN 0x40000000 +#define FM_PCD_PLCR_GCR_DAR 0x20000000 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF +#define FM_PCD_PLCR_NIA_ABS 0x00000100 + +#define FM_PCD_PLCR_GSR_BSY 0x80000000 +#define FM_PCD_PLCR_GSR_DQS 0x60000000 +#define FM_PCD_PLCR_GSR_RPB 0x20000000 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF + +#define FM_PCD_PLCR_EVR_PSIC 0x80000000 +#define FM_PCD_PLCR_EVR_AAC 0x40000000 + +#define FM_PCD_PLCR_PAR_PSI 0x20000000 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000 +/* PWSEL Selctive select options */ +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */ +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */ +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */ +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */ +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */ +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */ +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */ +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */ +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */ +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */ + +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1] + 1-> 2^N specific locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}. + 2-> 2^(N-1) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}. + 4-> 2^(N-2) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}. + 8->2^(N-3) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}. + 16-> 2^(N-4) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}. + 32-> 2^(N-5) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}. + 64-> 2^(N-6) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}. + 128-> 2^(N-7) base locations. */ +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}. + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */ + +#define FM_PCD_PLCR_PMR_V 0x80000000 +#define PLCR_ERR_ECC_CAP 0x80000000 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F + +#define PLCR_ERR_UNINIT_CAP 0x80000000 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000 + +/* shifts */ +#define PLCR_ERR_ECC_PNUM_SHIFT 4 +#define PLCR_ERR_UNINIT_PID_SHIFT 16 + +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16 + +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId) + + +#endif /* __FM_PLCR_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c index 2191c12d2837..ff4f0a2f23cb 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,11 +30,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_pcd.c @Description FM PCD ... *//***************************************************************************/ +#include #include "std_ext.h" #include "error_ext.h" #include "string_ext.h" @@ -44,8 +46,48 @@ #include "fm_common.h" #include "fm_pcd.h" #include "fm_pcd_ipc.h" +#include "fm_prs.h" +#include "fsl_fman_prs.h" +static void PcdPrsErrorException(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t event, ev_mask; + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + ev_mask = fman_prs_get_err_ev_mask(PrsRegs); + + event = fman_prs_get_err_event(PrsRegs, ev_mask); + + fman_prs_ack_err_event(PrsRegs, event); + + DBG(TRACE, ("parser error - 0x%08x\n",event)); + + if(event & FM_PCD_PRS_DOUBLE_ECC) + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC); +} + +static void PcdPrsException(t_Handle h_FmPcd) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + uint32_t event, ev_mask; + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs); + event = fman_prs_get_expt_event(PrsRegs, ev_mask); + + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC); + + DBG(TRACE, ("parser event - 0x%08x\n",event)); + + fman_prs_ack_expt_event(PrsRegs, event); + + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC); +} + t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams) { t_FmPcdPrs *p_FmPcdPrs; @@ -61,81 +103,216 @@ t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams) return NULL; } memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs)); + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg); if (p_FmPcd->guestId == NCSW_MASTER_ID) { baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm); p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr); - p_FmPcdPrs->p_FmPcdPrsRegs = (t_FmPcdPrsRegs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET); + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET); } - p_FmPcdPrs->fmPcdPrsPortIdStatistics = 0; - p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = DEFAULT_prsMaxParseCycleLimit; - p_FmPcd->exceptions |= (DEFAULT_fmPcdPrsErrorExceptions | DEFAULT_fmPcdPrsExceptions); + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat; + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim; + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions; return p_FmPcdPrs; } -static void PcdPrsErrorException(t_Handle h_FmPcd) +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH; +#else + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH; +#endif /* FM_CAPWAP_SUPPORT */ + +t_Error PrsInit(t_FmPcd *p_FmPcd) +{ + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; + uint32_t *p_TmpCode; + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode, + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE); + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + uint32_t i; + + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE)); + + /* nothing to do in guest-partition */ + if (p_FmPcd->guestId != NCSW_MASTER_ID) + return E_OK; + + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t)); + if (!p_TmpCode) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED")); + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4)); + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch)); + + fman_prs_init(PrsRegs, &p_Param->dfltCfg); + + /* register even if no interrupts enabled, to allow future enablement */ + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd); + + /* register even if no interrupts enabled, to allow future enablement */ + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd); + + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC) + FmEnableRamsEcc(p_FmPcd->h_Fm); + + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC) + FmEnableRamsEcc(p_FmPcd->h_Fm); + + /* load sw parser Ip-Frag patch */ + for (i=0; iguestId == NCSW_MASTER_ID); + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR); + /* register even if no interrupts enabled, to allow future enablement */ + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL); +} + +void PrsEnable(t_FmPcd *p_FmPcd) +{ + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + fman_prs_enable(PrsRegs); +} + +void PrsDisable(t_FmPcd *p_FmPcd) +{ + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + fman_prs_disable(PrsRegs); +} + +int PrsIsEnabled(t_FmPcd *p_FmPcd) +{ + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + return fman_prs_is_enabled(PrsRegs); +} + +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include) +{ + struct fman_prs_regs *PrsRegs; + uint32_t bitMask = 0; + uint8_t prsPortId; + + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); + + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId); + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId); + + if (include) + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask; + else + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask; + + fman_prs_set_stst_port_msk(PrsRegs, + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics); + + return E_OK; +} + +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include) +{ + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; + t_Error err; + + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); + + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + p_FmPcd->h_IpcSession) + { + t_FmPcdIpcPrsIncludePort prsIncludePortParams; + t_FmPcdIpcMsg msg; + + prsIncludePortParams.hardwarePortId = hardwarePortId; + prsIncludePortParams.include = include; + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_PCD_PRS_INC_PORT_STATS; + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams)); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) +sizeof(prsIncludePortParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + return E_OK; + } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include); +} + +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr) { t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t event, mask, force; - - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr); - mask = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer); - - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr); - if(force & event) - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, force & ~event); - - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr, event); - - DBG(TRACE, ("parser error - 0x%08x\n",event)); - - if(event & FM_PCD_PRS_DOUBLE_ECC) - p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC); -} - -static void PcdPrsException(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - uint32_t event, force; - - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr); - event &= GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever); - - ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC); - - DBG(TRACE, ("parser event - 0x%08x\n",event)); - - /* clear the forced events */ - force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr); - if(force & event) - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, force & ~event); - - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr, event); - - p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC); -} - -static uint32_t GetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - int i; t_FmPcdPrsLabelParams *p_Label; + int i; SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0); - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); + if ((p_FmPcd->guestId != NCSW_MASTER_ID) && + p_FmPcd->h_IpcSession) + { + t_Error err = E_OK; + t_FmPcdIpcSwPrsLable labelParams; + t_FmPcdIpcMsg msg; + uint32_t prsOffset = 0; + t_FmPcdIpcReply reply; + uint32_t replyLength; + + memset(&reply, 0, sizeof(reply)); + memset(&msg, 0, sizeof(msg)); + labelParams.enumHdr = (uint32_t)hdr; + labelParams.indexPerHdr = indexPerHdr; + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET; + memcpy(msg.msgBody, &labelParams, sizeof(labelParams)); + replyLength = sizeof(uint32_t) + sizeof(uint32_t); + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, + (uint8_t*)&msg, + sizeof(msg.msgId) +sizeof(labelParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t)); + return prsOffset; + } + else if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS); - for (i=0; i < p_FmPcd->p_FmPcdPrs->currLabel; i++) + for (i=0; ip_FmPcdPrs->currLabel; i++) { p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i]; @@ -147,248 +324,32 @@ static uint32_t GetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t return (uint32_t)ILLEGAL_BASE; } -t_Error PrsInit(t_FmPcd *p_FmPcd) -{ - t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; - t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; - uint32_t tmpReg; - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - return E_OK; - - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - -#ifdef FM_PRS_MEM_ERRATA_FMAN_SW003 - { - uint32_t i; - uint32_t regsToGlobalOffset = 0x840; - uint32_t firstPortToGlobalOffset = 0x45800; - uint64_t globalAddr = PTR_TO_UINT(p_Regs) - regsToGlobalOffset; - uint32_t firstPortAddr = (uint32_t)(globalAddr - (uint64_t)firstPortToGlobalOffset); - uint32_t portSize = 0x1000; - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPcd->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - /* clear all parser memory */ - IOMemSet32(UINT_TO_PTR(globalAddr), 0x00000000, 0x800); - for(i = 0;i<16;i++) - IOMemSet32(UINT_TO_PTR(firstPortAddr+i*portSize), (uint8_t)0x00000000, (uint32_t)0x80); - } - } -#endif /* FM_PRS_MEM_ERRATA_FMAN_SW003 */ - - /**********************RPCLIM******************/ - WRITE_UINT32(p_Regs->rpclim, (uint32_t)p_Param->prsMaxParseCycleLimit); - /**********************FMPL_RPCLIM******************/ - - /* register even if no interrupts enabled, to allow future enablement */ - FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd); - - /* register even if no interrupts enabled, to allow future enablement */ - FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd); - - /**********************PEVR******************/ - WRITE_UINT32(p_Regs->pevr, (FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS) ); - /**********************PEVR******************/ - - /**********************PEVER******************/ - if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC) - { - FmEnableRamsEcc(p_FmPcd->h_Fm); - WRITE_UINT32(p_Regs->pever, FM_PCD_PRS_SINGLE_ECC); - } - else - WRITE_UINT32(p_Regs->pever, 0); - /**********************PEVER******************/ - - /**********************PERR******************/ - WRITE_UINT32(p_Regs->perr, FM_PCD_PRS_DOUBLE_ECC); - - /**********************PERR******************/ - - /**********************PERER******************/ - tmpReg = 0; - if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC) - { - FmEnableRamsEcc(p_FmPcd->h_Fm); - tmpReg |= FM_PCD_PRS_DOUBLE_ECC; - } - WRITE_UINT32(p_Regs->perer, tmpReg); - /**********************PERER******************/ - - /**********************PPCS******************/ - WRITE_UINT32(p_Regs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics); - /**********************PPCS******************/ - -#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb - { - uint32_t i, j; - t_FmRevisionInfo revInfo; - uint8_t swPrsL4Patch[] = SW_PRS_L4_PATCH; - - FM_GetRevision(p_FmPcd->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - /* load sw parser L4 patch */ - for(i=0;ip_FmPcdPrs->p_SwPrsCode+ FM_PCD_PRS_SW_OFFSET/4 + i), tmpReg); - } - p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = FM_PCD_PRS_SW_OFFSET/4 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode+sizeof(swPrsL4Patch)/4; - } - } -#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */ - - return E_OK; -} - -void PrsFree(t_FmPcd *p_FmPcd ) -{ - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR); - /* register even if no interrupts enabled, to allow future enablement */ - FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL); -} - -void PrsEnable(t_FmPcd *p_FmPcd ) -{ - t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; - - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) | FM_PCD_PRS_RPIMAC_EN); -} - -void PrsDisable(t_FmPcd *p_FmPcd ) -{ - t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; - - ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); - WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) & ~FM_PCD_PRS_RPIMAC_EN); -} - -t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include) -{ - uint32_t bitMask = 0; - uint8_t prsPortId; - - SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); - - GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId); - GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId); - - if(include) - p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask; - else - p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask; - - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics); - - return E_OK; -} - -t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_FmPcdIpcPrsIncludePort prsIncludePortParams; - t_FmPcdIpcMsg msg; - t_Error err; - - SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - prsIncludePortParams.hardwarePortId = hardwarePortId; - prsIncludePortParams.include = include; - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_PRS_INC_PORT_STATS; - memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams)); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(prsIncludePortParams), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - return E_OK; - } - return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include); -} - -uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr) -{ - t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; - t_Error err = E_OK; - t_FmPcdIpcSwPrsLable labelParams; - t_FmPcdIpcMsg msg; - uint32_t prsOffset = 0; - t_FmPcdIpcReply reply; - uint32_t replyLength; - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&reply, 0, sizeof(reply)); - memset(&msg, 0, sizeof(msg)); - labelParams.enumHdr = (uint32_t)hdr; - labelParams.indexPerHdr = indexPerHdr; - msg.msgId = FM_PCD_GET_SW_PRS_OFFSET; - memcpy(msg.msgBody, &labelParams, sizeof(labelParams)); - replyLength = sizeof(uint32_t) + sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(labelParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(replyLength != sizeof(uint32_t) + sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t)); - return prsOffset; - } - - return GetSwPrsOffset(h_FmPcd, hdr, indexPerHdr); -} - void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; + struct fman_prs_regs *PrsRegs; SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; + + if(p_FmPcd->guestId != NCSW_MASTER_ID) { REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!")); return; } - if(enable) - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, FM_PCD_PRS_PPSC_ALL_PORTS); - else - WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, 0); + fman_prs_set_stst(PrsRegs, enable); } t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs) { t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - uint32_t *p_LoadTarget, tmpReg; - int i, j; + uint32_t *p_LoadTarget; + uint32_t *p_TmpCode; + int i; SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); @@ -396,48 +357,53 @@ t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs) SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE); - if(p_FmPcd->guestId != NCSW_MASTER_ID) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_PrsLoadSw - guest mode!")); + if (p_FmPcd->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!")); - if(!p_SwPrs->override) + if (!p_SwPrs->override) { if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code")); } - if(p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2) + else + p_FmPcd->p_FmPcdPrs->currLabel = 0; + + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE")); - if(p_SwPrs->size % 4) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size must be divisible by 4")); + + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed ")); + + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t)); + if (!p_TmpCode) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED")); + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4)); + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size); /* save sw parser labels */ - if(p_SwPrs->override) - p_FmPcd->p_FmPcdPrs->currLabel = 0; - if(p_FmPcd->p_FmPcdPrs->currLabel+ p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed ")); - memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], p_SwPrs->labelsTable, p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams)); + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], + p_SwPrs->labelsTable, + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams)); p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels; + /* load sw parser code */ p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4; - for(i=0;isize/4;i++) - { - tmpReg = 0; - for(j =0;j<4;j++) - { - tmpReg <<= 8; - tmpReg |= *(p_SwPrs->p_Code+i*4+j); - } - WRITE_UINT32(*(p_LoadTarget + i), tmpReg); - } - p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + p_SwPrs->size/4; + + for(i=0; isize, 4); i++) + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i])); + + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4); /* copy data parameters */ - for(i=0;ip_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]); - /* Clear last 4 bytes */ WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0); + XX_FreeSmart(p_TmpCode); + return E_OK; } @@ -455,63 +421,3 @@ t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value) return E_OK; } - - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd) -{ - t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; - t_FmPcdIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); - - if(p_FmPcd->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_PCD_PRS_DUMP_REGS; - return XX_IpcSendMessage(p_FmPcd->h_IpcSession, - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL); - } - DUMP_SUBTITLE(("\n")); - DUMP_TITLE(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs, ("FmPcdPrsRegs Regs")); - - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpclim); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpimac); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pmeec); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevr); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pever); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevfr); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perr); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perer); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perfr); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,ppsc); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pds); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rrs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rrs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rrs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srrs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rres); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rres); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rres); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srres); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spcs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spscs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,hxscs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrcs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwcs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrscs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwscs); - DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fcscs); - - return E_OK; -} -#endif /* (defined(DEBUG_ERRORS) && ... */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.h new file mode 100644 index 000000000000..056f225ef221 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.h @@ -0,0 +1,316 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_prs.h + + @Description FM Parser private header + *//***************************************************************************/ +#ifndef __FM_PRS_H +#define __FM_PRS_H + +#include "std_ext.h" + +/***********************************************************************/ +/* SW parser IP_FRAG patch */ +/***********************************************************************/ + +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) +#define SW_PRS_UDP_LITE_PATCH \ +{\ + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \ + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \ + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \ + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \ + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \ + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \ + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \ + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \ + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \ + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \ + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \ + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \ + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \ + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \ + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \ + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \ + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \ + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \ + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \ + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \ + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \ + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \ + 0x00,0x01,0x1B,0xFF \ +} +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + +#if (DPAA_VERSION == 10) +/* Version: 106.1.9 */ +#define SW_PRS_OFFLOAD_PATCH \ +{ \ + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \ + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \ + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \ + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \ + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \ + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \ + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \ + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \ + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \ + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \ + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \ + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \ + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \ + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \ + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \ + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \ + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \ + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \ + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \ + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \ + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \ + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \ + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \ + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \ + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \ + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \ + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \ + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \ + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \ + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \ + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \ + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \ + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \ +} + +#else +#define SW_PRS_OFFLOAD_PATCH \ +{ \ + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \ + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \ + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \ + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \ + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \ + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \ + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \ + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \ + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \ + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \ + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \ + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \ + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \ + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \ + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \ + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \ + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \ + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \ + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \ + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \ + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \ + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \ + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \ + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \ + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \ + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \ + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \ + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \ + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \ + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \ + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \ + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \ + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \ + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \ + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \ + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \ + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \ + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \ + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \ + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \ + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \ + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \ + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \ + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \ + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \ + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \ + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \ + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \ + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \ + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \ + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \ + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \ + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \ + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \ + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \ + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \ + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \ + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \ + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \ + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \ + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \ + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \ + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \ + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \ + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \ + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \ + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \ + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \ + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \ + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \ + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \ + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \ + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \ + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \ + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \ + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \ + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \ + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \ + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \ + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \ + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \ + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \ + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \ + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \ + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \ + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \ + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \ + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \ + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \ + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \ + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \ + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \ + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \ + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \ + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \ + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \ + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \ + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \ + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \ + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \ + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \ + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \ + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \ + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \ + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \ + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \ + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \ + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \ + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \ + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \ + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \ + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \ + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \ + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \ + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \ + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \ + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \ + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \ + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \ + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \ + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \ + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \ + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \ + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \ + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \ + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \ +} +#endif /* (DPAA_VERSION == 10) */ + +/****************************/ +/* Parser defines */ +/****************************/ +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at + the end of the SW parser area */ + +/* masks */ +#define PRS_ERR_CAP 0x80000000 +#define PRS_ERR_TYPE_DOUBLE 0x40000000 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000 +#define PRS_ERR_ADDR_MASK 0x000001FF + +/* others */ +#define PRS_MAX_CYCLE_LIMIT 8191 +#define PRS_SW_DATA 0x00000800 +#define PRS_REGS_OFFSET 0x00000840 + +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \ + prsPortId = (uint8_t)(hardwarePortId & 0x0f) + +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \ + bitMask = 0x80000000>>prsPortId + +#endif /* __FM_PRS_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.c new file mode 100644 index 000000000000..ee82f73014b6 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.c @@ -0,0 +1,984 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_replic.c + + @Description FM frame replicator +*//***************************************************************************/ +#include "std_ext.h" +#include "error_ext.h" +#include "string_ext.h" +#include "debug_ext.h" +#include "fm_pcd_ext.h" +#include "fm_muram_ext.h" +#include "fm_common.h" +#include "fm_hc.h" +#include "fm_replic.h" +#include "fm_cc.h" +#include "list_ext.h" + + +/****************************************/ +/* static functions */ +/****************************************/ +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup, + uint32_t memberIndex, + bool isAddOperation) +{ + uint8_t memberPosition; + uint32_t lastMemberIndex; + + ASSERT_COND(p_ReplicGroup); + + /* the last member index is different between add and remove operation - + in case of remove - this is exactly the last member index + in case of add - this is the last member index + 1 - e.g. + if we have 4 members, the index of the actual last member is 3(because the + index starts from 0) therefore in order to add a new member as the last + member we shall use memberIndex = 4 and not 3 + */ + if (isAddOperation) + lastMemberIndex = p_ReplicGroup->numOfEntries; + else + lastMemberIndex = p_ReplicGroup->numOfEntries-1; + + /* last */ + if (memberIndex == lastMemberIndex) + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX; + else + { + /* first */ + if (memberIndex == 0) + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX; + else + { + /* middle */ + ASSERT_COND(memberIndex < lastMemberIndex); + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX; + } + } + return memberPosition; +} + +static t_Error MemberCheckParams(t_Handle h_FmPcd, + t_FmPcdCcNextEngineParams *p_MemberParams) +{ + t_Error err; + + + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) && + (p_MemberParams->nextEngine != e_FM_PCD_KG) && + (p_MemberParams->nextEngine != e_FM_PCD_PLCR)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer")); + + /* check the regular parameters of the next engine */ + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE); + if (err) + RETURN_ERROR(MAJOR, err, ("member next engine parameters")); + + return E_OK; +} + +static t_Error CheckParams(t_Handle h_FmPcd, + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam) +{ + int i; + t_Error err; + + /* check that max num of entries is at least 2 */ + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("maxNumOfEntries in the frame replicator parameters should be 2-%d",FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)); + + /* check that number of entries is greater than zero */ + if (!p_ReplicGroupParam->numOfEntries) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero")); + + /* check that max num of entries is equal or greater than number of entries */ + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries")); + + for (i=0; inumOfEntries; i++) + { + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]); + if (err) + RETURN_ERROR(MAJOR, err, ("member check parameters")); + } + return E_OK; +} + +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup) +{ + t_FmPcdFrmReplicMember *p_ReplicMember = NULL; + t_List *p_Next; + + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList)) + { + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList); + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node); + ASSERT_COND(p_ReplicMember); + LIST_DelAndInit(p_Next); + } + return p_ReplicMember; +} + +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_ReplicMember) +{ + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList); +} + +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_CurrentMember, + t_List *p_ListHead) +{ + LIST_Add(&p_CurrentMember->node, p_ListHead); + + p_ReplicGroup->numOfEntries++; +} + +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_CurrentMember) +{ + ASSERT_COND(p_ReplicGroup->numOfEntries); + LIST_DelAndInit(&p_CurrentMember->node); + p_ReplicGroup->numOfEntries--; +} + +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_AdOfTypeContLookup *p_SourceTd, + t_FmPcdFrmReplicMember *p_ReplicMember) +{ + t_FmPcd *p_FmPcd; + + ASSERT_COND(p_SourceTd); + ASSERT_COND(p_ReplicMember); + ASSERT_COND(p_ReplicGroup); + ASSERT_COND(p_ReplicGroup->h_FmPcd); + + /* Link the first member in the group to the source TD */ + p_FmPcd = p_ReplicGroup->h_FmPcd; + + WRITE_UINT32(p_SourceTd->matchTblPtr, + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) - + p_FmPcd->physicalMuramBase)); +} + +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_CurrentMember, + t_FmPcdFrmReplicMember *p_NextMember) +{ + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd; + t_AdOfTypeResult *p_NextReplicAd = NULL; + t_FmPcd *p_FmPcd; + uint32_t offset = 0; + + /* Check if the next member exists or it's NULL (- means that this is the last member) */ + if (p_NextMember) + { + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd; + p_FmPcd = p_ReplicGroup->h_FmPcd; + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase)); + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT); + } + + /* link the current AD to point to the AD of the next member */ + WRITE_UINT32(p_CurrReplicAd->res, offset); +} + +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup, + void *p_OldDescriptor, + void *p_NewDescriptor) +{ + t_Handle h_Hc; + t_Error err; + t_FmPcd *p_FmPcd; + + ASSERT_COND(p_ReplicGroup); + ASSERT_COND(p_ReplicGroup->h_FmPcd); + ASSERT_COND(p_OldDescriptor); + ASSERT_COND(p_NewDescriptor); + + p_FmPcd = p_ReplicGroup->h_FmPcd; + h_Hc = FmPcdGetHcHandle(p_FmPcd); + if (!h_Hc) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command")); + + err = FmHcPcdCcDoDynamicChange(h_Hc, + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase), + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase)); + if (err) + RETURN_ERROR(MAJOR, err, ("Dynamic change host command")); + + return E_OK; +} + +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last) +{ + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd; + uint32_t tmp; + + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile); + if (last) + /* clear the NL bit in case it's the last member in the group*/ + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT)); + else + /* set the NL bit in case it's not the last member in the group */ + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT)); + + /* set FR bit in the action descriptor */ + tmp = GET_UINT32(p_CurrReplicAd->nia); + WRITE_UINT32(p_CurrReplicAd->nia, + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE )); +} + +static void BuildSourceTd(void *p_Ad) +{ + t_AdOfTypeContLookup *p_SourceTd; + + ASSERT_COND(p_Ad); + + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad; + + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* initialize the source table descriptor */ + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE); + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE); +} + +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_NextMember, + t_FmPcdFrmReplicMember *p_CurrentMember, + bool sourceDescriptor, + bool last) +{ + t_FmPcd *p_FmPcd; + t_FmPcdFrmReplicMember shadowMember; + t_Error err; + + ASSERT_COND(p_ReplicGroup); + ASSERT_COND(p_ReplicGroup->h_FmPcd); + + p_FmPcd = p_ReplicGroup->h_FmPcd; + ASSERT_COND(p_FmPcd->p_CcShadow); + + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) + return ERROR_CODE(E_BUSY); + + if (sourceDescriptor) + { + BuildSourceTd(p_FmPcd->p_CcShadow); + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember); + + /* Modify the source table descriptor according to the prepared shadow descriptor */ + err = ModifyDescriptor(p_ReplicGroup, + p_ReplicGroup->p_SourceTd, + p_FmPcd->p_CcShadow/* new prepared source td */); + + RELEASE_LOCK(p_FmPcd->shadowLock); + if (err) + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor")); + + } + else + { + IO2IOCpy32(p_FmPcd->p_CcShadow, + p_CurrentMember->p_MemberAd, + FM_PCD_CC_AD_ENTRY_SIZE); + + /* update the last bit in the shadow ad */ + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last); + + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow; + + /* update the next FR member index */ + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember); + + /* Modify the next member according to the prepared shadow descriptor */ + err = ModifyDescriptor(p_ReplicGroup, + p_CurrentMember->p_MemberAd, + p_FmPcd->p_CcShadow); + + RELEASE_LOCK(p_FmPcd->shadowLock); + if (err) + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor")); + } + + + return E_OK; +} + +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup, + uint16_t memberIndex) +{ + int i=0; + t_List *p_Pos; + t_FmPcdFrmReplicMember *p_Member = NULL; + + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList) + { + if (i == memberIndex) + { + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node); + return p_Member; + } + i++; + } + return p_Member; +} + +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup) +{ + t_FmPcdFrmReplicMember *p_CurrentMember; + t_Handle h_Muram; + + ASSERT_COND(p_ReplicGroup); + + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); + ASSERT_COND(h_Muram); + + /* Initialize an internal structure of a member to add to the available members list */ + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember)); + if (!p_CurrentMember) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member")); + + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember)); + + /* Allocate the member AD */ + p_CurrentMember->p_MemberAd = + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram, + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_CurrentMember->p_MemberAd) + { + XX_Free(p_CurrentMember); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table")); + } + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + /* Add the new member to the available members list */ + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList)); + + return E_OK; +} + +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdCcNextEngineParams *p_MemberParams, + bool last) +{ + t_FmPcdFrmReplicMember *p_CurrentMember = NULL; + + ASSERT_COND(p_ReplicGroup); + + /* Get an available member from the internal members list */ + p_CurrentMember = GetAvailableMember(p_ReplicGroup); + if (!p_CurrentMember) + { + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member")); + return NULL; + } + p_CurrentMember->h_Manip = NULL; + + /* clear the Ad of the new member */ + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + INIT_LIST(&p_CurrentMember->node); + + /* Initialize the Ad of the member */ + NextStepAd(p_CurrentMember->p_MemberAd, + NULL, + p_MemberParams, + p_ReplicGroup->h_FmPcd); + + /* save Manip handle (for free needs) */ + if (p_MemberParams->h_Manip) + p_CurrentMember->h_Manip = p_MemberParams->h_Manip; + + /* Initialize the relevant frame replicator fields in the AD */ + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last); + + return p_CurrentMember; +} + +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + t_FmPcdFrmReplicMember *p_Member) +{ + /* Note: Can't free the member AD just returns the member to the available + member list - therefore only memset the AD */ + + /* zero the AD */ + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); + + + /* return the member to the available members list */ + PutAvailableMember(p_ReplicGroup, p_Member); +} + +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, + uint16_t memberIndex) +{ + t_FmPcd *p_FmPcd = NULL; + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL; + t_Error err; + uint8_t memberPosition; + + p_FmPcd = p_ReplicGroup->h_FmPcd; + ASSERT_COND(p_FmPcd); + UNUSED(p_FmPcd); + + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); + ASSERT_COND(p_CurrentMember); + + /* determine the member position in the group */ + memberPosition = GetMemberPosition(p_ReplicGroup, + memberIndex, + FALSE/*remove operation*/); + + switch (memberPosition) + { + case FRM_REPLIC_FIRST_MEMBER_INDEX: + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1)); + ASSERT_COND(p_NextMember); + + /* update the source td itself by using a host command */ + err = BuildShadowAndModifyDescriptor(p_ReplicGroup, + p_NextMember, + NULL, + TRUE/*sourceDescriptor*/, + FALSE/*last*/); + break; + + case FRM_REPLIC_MIDDLE_MEMBER_INDEX: + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); + ASSERT_COND(p_PreviousMember); + + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1)); + ASSERT_COND(p_NextMember); + + err = BuildShadowAndModifyDescriptor(p_ReplicGroup, + p_NextMember, + p_PreviousMember, + FALSE/*sourceDescriptor*/, + FALSE/*last*/); + + break; + + case FRM_REPLIC_LAST_MEMBER_INDEX: + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); + ASSERT_COND(p_PreviousMember); + + err = BuildShadowAndModifyDescriptor(p_ReplicGroup, + NULL, + p_PreviousMember, + FALSE/*sourceDescriptor*/, + TRUE/*last*/); + break; + + default: + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member")); + } + + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (p_CurrentMember->h_Manip) + { + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE); + p_CurrentMember->h_Manip = NULL; + } + + /* remove the member from the driver internal members list */ + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember); + + /* return the member to the available members list */ + FreeMember(p_ReplicGroup, p_CurrentMember); + + return E_OK; +} + +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup) +{ + int i, j; + t_Handle h_Muram; + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember; + + if (p_ReplicGroup) + { + ASSERT_COND(p_ReplicGroup->h_FmPcd); + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); + ASSERT_COND(h_Muram); + + /* free the source table descriptor */ + if (p_ReplicGroup->p_SourceTd) + { + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd); + p_ReplicGroup->p_SourceTd = NULL; + } + + /* Remove all members from the members linked list (hw and sw) and + return the members to the available members list */ + if (p_ReplicGroup->numOfEntries) + { + j = p_ReplicGroup->numOfEntries-1; + + /* manually removal of the member because there are no owners of + this group */ + for (i=j; i>=0; i--) + { + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/); + ASSERT_COND(p_CurrentMember); + + if (p_CurrentMember->h_Manip) + { + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE); + p_CurrentMember->h_Manip = NULL; + } + + /* remove the member from the internal driver members list */ + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember); + + /* return the member to the available members list */ + FreeMember(p_ReplicGroup, p_CurrentMember); + } + } + + /* Free members AD */ + for (i=0; imaxNumOfEntries; i++) + { + p_Member = GetAvailableMember(p_ReplicGroup); + ASSERT_COND(p_Member); + if (p_Member->p_MemberAd) + { + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd); + p_Member->p_MemberAd = NULL; + } + XX_Free(p_Member); + } + + /* release the group lock */ + if (p_ReplicGroup->p_Lock) + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock); + + /* free the replicator group */ + XX_Free(p_ReplicGroup); + } +} + + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ + +/* NOTE: the inter-module routines are locked by cc in case of using them */ +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + ASSERT_COND(p_ReplicGroup); + + return (p_ReplicGroup->p_SourceTd); +} + +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, + void *p_Ad, + t_Handle *h_AdNew) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad; + t_FmPcd *p_FmPcd; + + ASSERT_COND(p_ReplicGroup); + p_FmPcd = p_ReplicGroup->h_FmPcd; + + /* build a bypass ad */ + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE | + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase)); + + *h_AdNew = NULL; +} + +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, + bool add) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + ASSERT_COND(p_ReplicGroup); + + /* update the group owner counter */ + if (add) + p_ReplicGroup->owners++; + else + { + ASSERT_COND(p_ReplicGroup->owners); + p_ReplicGroup->owners--; + } +} + +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + + ASSERT_COND(h_ReplicGroup); + + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock)) + return E_OK; + + return ERROR_CODE(E_BUSY); +} + +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + + ASSERT_COND(h_ReplicGroup); + + FmPcdLockUnlock(p_ReplicGroup->p_Lock); +} +/*********************** End of inter-module routines ************************/ + + +/****************************************/ +/* API Init unit functions */ +/****************************************/ +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup; + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL; + int i; + t_Error err; + bool last = FALSE; + t_Handle h_Muram; + + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL); + + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd)) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled")); + return NULL; + } + + err = CheckParams(h_FmPcd, p_ReplicGroupParam); + if (err) + { + REPORT_ERROR(MAJOR, err, (NO_MSG)); + return NULL; + } + + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup)); + if (!p_ReplicGroup) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); + return NULL; + } + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup)); + + /* initialize lists for internal driver use */ + INIT_LIST(&p_ReplicGroup->availableMembersList); + INIT_LIST(&p_ReplicGroup->membersList); + + p_ReplicGroup->h_FmPcd = h_FmPcd; + + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); + ASSERT_COND(h_Muram); + + /* initialize the group lock */ + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd); + if (!p_ReplicGroup->p_Lock) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock")); + DeleteGroup(p_ReplicGroup); + return NULL; + } + + /* Allocate the frame replicator source table descriptor */ + p_ReplicGroup->p_SourceTd = + (t_Handle)FM_MURAM_AllocMem(h_Muram, + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (!p_ReplicGroup->p_SourceTd) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor")); + DeleteGroup(p_ReplicGroup); + return NULL; + } + + /* update the shadow size - required for the host commands */ + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd, + FM_PCD_CC_AD_ENTRY_SIZE, + FM_PCD_CC_AD_TABLE_ALIGN); + if (err) + { + REPORT_ERROR(MAJOR, err, ("Update CC shadow")); + DeleteGroup(p_ReplicGroup); + return NULL; + } + + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries; + + /* Allocate the maximal number of members ADs and Statistics AD for the group + It prevents allocation of Muram in run-time */ + for (i=0; imaxNumOfEntries; i++) + { + err = AllocMember(p_ReplicGroup); + if (err) + { + REPORT_ERROR(MAJOR, err, ("allocate a new member")); + DeleteGroup(p_ReplicGroup); + return NULL; + } + } + + /* Initialize the members linked lists: + (hw - the one that is used by the FMan controller and + sw - the one that is managed by the driver internally) */ + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--) + { + /* check if this is the last member in the group */ + if (i == (p_ReplicGroupParam->numOfEntries-1)) + last = TRUE; + else + last = FALSE; + + /* Initialize a new member */ + p_CurrentMember = InitMember(p_ReplicGroup, + &(p_ReplicGroupParam->nextEngineParams[i]), + last); + if (!p_CurrentMember) + { + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member")); + DeleteGroup(p_ReplicGroup); + return NULL; + } + + /* Build the members group - link two consecutive members in the hw linked list */ + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember); + + /* update the driver internal members list to be compatible to the hw members linked list */ + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList); + + p_NextMember = p_CurrentMember; + } + + /* initialize the source table descriptor */ + BuildSourceTd(p_ReplicGroup->p_SourceTd); + + /* link the source table descriptor to point to the first member in the group */ + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember); + + return p_ReplicGroup; +} + +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; + + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); + + if (p_ReplicGroup->owners) + RETURN_ERROR(MAJOR, + E_INVALID_STATE, + ("the group has owners and can't be deleted")); + + DeleteGroup(p_ReplicGroup); + + return E_OK; +} + + +/*****************************************************************************/ +/* API Run-time Frame replicator Control unit functions */ +/*****************************************************************************/ +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup, + uint16_t memberIndex, + t_FmPcdCcNextEngineParams *p_MemberParams) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup; + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL; + t_Error err; + uint8_t memberPosition; + + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE); + + /* group lock */ + err = FrmReplicGroupTryLock(p_ReplicGroup); + if (GET_ERROR_TYPE(err) == E_BUSY) + return ERROR_CODE(E_BUSY); + + if (memberIndex > p_ReplicGroup->numOfEntries) + { + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("memberIndex is greater than the members in the list")); + } + + if (memberIndex >= p_ReplicGroup->maxNumOfEntries) + { + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group")); + } + + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES) + { + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("numOfEntries with new entry can not be larger than %d\n", + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)); + } + + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams); + if (err) + { + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation")); + } + /* determine the member position in the group */ + memberPosition = GetMemberPosition(p_ReplicGroup, + memberIndex, + TRUE/* add operation */); + + /* Initialize a new member */ + p_NewMember = InitMember(p_ReplicGroup, + p_MemberParams, + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE)); + if (!p_NewMember) + { + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member")); + } + + switch (memberPosition) + { + case FRM_REPLIC_FIRST_MEMBER_INDEX: + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); + ASSERT_COND(p_CurrentMember); + + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember); + + /* update the internal group source TD */ + LinkSourceToMember(p_ReplicGroup, + p_ReplicGroup->p_SourceTd, + p_NewMember); + + /* add member to the internal sw member list */ + AddMemberToList(p_ReplicGroup, + p_NewMember, + &p_ReplicGroup->membersList); + break; + + case FRM_REPLIC_MIDDLE_MEMBER_INDEX: + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); + ASSERT_COND(p_CurrentMember); + + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); + ASSERT_COND(p_PreviousMember); + + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember); + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember); + + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node); + break; + + case FRM_REPLIC_LAST_MEMBER_INDEX: + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); + ASSERT_COND(p_PreviousMember); + + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember); + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/); + + /* add the new member to the internal sw member list */ + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node); + break; + + default: + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member")); + + } + + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + + return E_OK; +} + +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup, + uint16_t memberIndex) +{ + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); + + /* lock */ + err = FrmReplicGroupTryLock(p_ReplicGroup); + if (GET_ERROR_TYPE(err) == E_BUSY) + return ERROR_CODE(E_BUSY); + + if (memberIndex >= p_ReplicGroup->numOfEntries) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove")); + + /* Design decision: group must contain at least one member + No possibility to remove the last member from the group */ + if (p_ReplicGroup->numOfEntries == 1) + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group.")); + + err = RemoveMember(p_ReplicGroup, memberIndex); + + /* unlock */ + FrmReplicGroupUnlock(p_ReplicGroup); + + switch (GET_ERROR_TYPE(err)) + { + case E_OK: + return E_OK; + + case E_BUSY: + DBG(TRACE, ("E_BUSY error")); + return ERROR_CODE(E_BUSY); + + default: + RETURN_ERROR(MAJOR, err, NO_MSG); + } +} + +/*********************** End of API routines ************************/ + + diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.h new file mode 100644 index 000000000000..0e8e8bc00cb2 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_replic.h @@ -0,0 +1,101 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_replic.h + + @Description FM frame replicator +*//***************************************************************************/ +#ifndef __FM_REPLIC_H +#define __FM_REPLIC_H + +#include "std_ext.h" +#include "error_ext.h" + + +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16 +#define FRM_REPLIC_FR_BIT 0x08000000 +#define FRM_REPLIC_NL_BIT 0x10000000 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0 + +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2 + +#define SOURCE_TD_ITSELF_OPTION 0x01 +#define SOURCE_TD_COPY_OPTION 0x02 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION +#define SOURCE_TD_NONE 0x04 + +/*typedef enum e_SourceTdOption +{ + e_SOURCE_TD_NONE = 0, + e_SOURCE_TD_ITSELF_OPTION = 1, + e_SOURCE_TD_COPY_OPTION = 2, + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION +} e_SourceTdOption; +*/ + +typedef struct +{ + volatile uint32_t type; + volatile uint32_t frGroupPointer; + volatile uint32_t operationCode; + volatile uint32_t reserved; +} t_FrmReplicGroupSourceAd; + +typedef struct t_FmPcdFrmReplicMember +{ + void *p_MemberAd; /**< pointer to the member AD */ + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */ + t_Handle h_Manip; /**< manip handle - need for free routines */ + t_List node; +} t_FmPcdFrmReplicMember; + +typedef struct t_FmPcdFrmReplicGroup +{ + t_Handle h_FmPcd; + + uint8_t maxNumOfEntries;/**< maximal number of members in the group */ + uint8_t numOfEntries; /**< actual number of members in the group */ + uint16_t owners; /**< how many keys share this frame replicator group */ + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */ + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/ + t_List availableMembersList;/**< list of all the available members in the group */ + t_FmPcdLock *p_Lock; +} t_FmPcdFrmReplicGroup; + + +#endif /* __FM_REPLIC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_kg.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_kg.c new file mode 100644 index 000000000000..49b86e8e4696 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_kg.c @@ -0,0 +1,888 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_kg.h" + +/****************************************/ +/* static functions */ +/****************************************/ + + +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write) +{ + uint32_t rw; + + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ; + + return (uint32_t)(FM_KG_KGAR_GO | + rw | + FM_PCD_KG_KGAR_SEL_PORT_ENTRY | + hwport_id | + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); +} + +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id) +{ + uint32_t ar; + + fman_kg_write_sp(regs, 0xffffffff, 0); + + ar = build_ar_bind_scheme(hwport_id, TRUE); + fman_kg_write_ar_wait(regs, ar); +} + +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write) +{ + uint32_t rw; + + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ; + + return (uint32_t)(FM_KG_KGAR_GO | + rw | + FM_PCD_KG_KGAR_SEL_PORT_ENTRY | + hwport_id | + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); +} + +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id) +{ + uint32_t ar; + + fman_kg_write_cpp(regs, 0); + + ar = build_ar_bind_cls_plan(hwport_id, TRUE); + fman_kg_write_ar_wait(regs, ar); +} + +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src, + bool no_validation, + uint8_t *offset) +{ + int code; + + switch (src) { + case E_FMAN_KG_GEN_EXTRACT_ETH: + code = no_validation ? 0x73 : 0x3; + break; + + case E_FMAN_KG_GEN_EXTRACT_ETYPE: + code = no_validation ? 0x77 : 0x7; + break; + + case E_FMAN_KG_GEN_EXTRACT_SNAP: + code = no_validation ? 0x74 : 0x4; + break; + + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1: + code = no_validation ? 0x75 : 0x5; + break; + + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N: + code = no_validation ? 0x76 : 0x6; + break; + + case E_FMAN_KG_GEN_EXTRACT_PPPoE: + code = no_validation ? 0x78 : 0x8; + break; + + case E_FMAN_KG_GEN_EXTRACT_MPLS_1: + code = no_validation ? 0x79 : 0x9; + break; + + case E_FMAN_KG_GEN_EXTRACT_MPLS_2: + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19; + break; + + case E_FMAN_KG_GEN_EXTRACT_MPLS_3: + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29; + break; + + case E_FMAN_KG_GEN_EXTRACT_MPLS_N: + code = no_validation ? 0x7a : 0xa; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPv4_1: + code = no_validation ? 0x7b : 0xb; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPv6_1: + code = no_validation ? 0x7b : 0x1b; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPv4_2: + code = no_validation ? 0x7c : 0xc; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPv6_2: + code = no_validation ? 0x7c : 0x1c; + break; + + case E_FMAN_KG_GEN_EXTRACT_MINENCAP: + code = no_validation ? 0x7c : 0x2c; + break; + + case E_FMAN_KG_GEN_EXTRACT_IP_PID: + code = no_validation ? 0x72 : 0x2; + break; + + case E_FMAN_KG_GEN_EXTRACT_GRE: + code = no_validation ? 0x7d : 0xd; + break; + + case E_FMAN_KG_GEN_EXTRACT_TCP: + code = no_validation ? 0x7e : 0xe; + break; + + case E_FMAN_KG_GEN_EXTRACT_UDP: + code = no_validation ? 0x7e : 0x1e; + break; + + case E_FMAN_KG_GEN_EXTRACT_SCTP: + code = no_validation ? 0x7e : 0x3e; + break; + + case E_FMAN_KG_GEN_EXTRACT_DCCP: + code = no_validation ? 0x7e : 0x4e; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH: + code = no_validation ? 0x7e : 0x2e; + break; + + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP: + code = no_validation ? 0x7e : 0x6e; + break; + + case E_FMAN_KG_GEN_EXTRACT_SHIM_1: + code = 0x70; + break; + + case E_FMAN_KG_GEN_EXTRACT_SHIM_2: + code = 0x71; + break; + + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT: + code = 0x10; + break; + + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START: + code = 0x40; + break; + + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT: + code = 0x20; + break; + + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE: + code = 0x7f; + break; + + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID: + code = 0x20; + *offset += 0x20; + break; + + default: + code = FM_KG_SCH_GEN_HT_INVALID; + } + + return (uint8_t)code; +} + +static uint32_t build_ar_scheme(uint8_t scheme, + uint8_t hwport_id, + bool update_counter, + bool write) +{ + uint32_t rw; + + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ); + + return (uint32_t)(FM_KG_KGAR_GO | + rw | + FM_KG_KGAR_SEL_SCHEME_ENTRY | + hwport_id | + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) | + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0)); +} + +static uint32_t build_ar_cls_plan(uint8_t grp, + uint8_t entries_mask, + uint8_t hwport_id, + bool write) +{ + uint32_t rw; + + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ); + + return (uint32_t)(FM_KG_KGAR_GO | + rw | + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | + hwport_id | + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) | + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT)); +} + +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar) +{ + iowrite32be(fmkg_ar, ®s->fmkg_ar); + /* Wait for GO to be idle and read error */ + while ((fmkg_ar = ioread32be(®s->fmkg_ar)) & FM_KG_KGAR_GO) ; + if (fmkg_ar & FM_PCD_KG_KGAR_ERR) + return -EINVAL; + return 0; +} + +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add) +{ + + struct fman_kg_pe_regs *kgpe_regs; + uint32_t tmp; + + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp); + + if (add) + tmp |= sp; + else /* clear */ + tmp &= ~sp; + + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp); + +} + +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp) +{ + struct fman_kg_pe_regs *kgpe_regs; + + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); + + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp); +} + +void fman_kg_get_event(struct fman_kg_regs *regs, + uint32_t *event, + uint32_t *scheme_idx) +{ + uint32_t mask, force; + + *event = ioread32be(®s->fmkg_eer); + mask = ioread32be(®s->fmkg_eeer); + *scheme_idx = ioread32be(®s->fmkg_seer); + *scheme_idx &= ioread32be(®s->fmkg_seeer); + + *event &= mask; + + /* clear the forced events */ + force = ioread32be(®s->fmkg_feer); + if (force & *event) + iowrite32be(force & ~*event ,®s->fmkg_feer); + + iowrite32be(*event, ®s->fmkg_eer); + iowrite32be(*scheme_idx, ®s->fmkg_seer); +} + + +void fman_kg_init(struct fman_kg_regs *regs, + uint32_t exceptions, + uint32_t dflt_nia) +{ + uint32_t tmp; + int i; + + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW, + ®s->fmkg_eer); + + tmp = 0; + if (exceptions & FM_EX_KG_DOUBLE_ECC) + tmp |= FM_EX_KG_DOUBLE_ECC; + + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW) + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW; + + iowrite32be(tmp, ®s->fmkg_eeer); + iowrite32be(0, ®s->fmkg_fdor); + iowrite32be(0, ®s->fmkg_gdv0r); + iowrite32be(0, ®s->fmkg_gdv1r); + iowrite32be(dflt_nia, ®s->fmkg_gcr); + + /* Clear binding between ports to schemes and classification plans + * so that all ports are not bound to any scheme/classification plan */ + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) { + clear_pe_all_scheme(regs, (uint8_t)i); + clear_pe_all_cls_plan(regs, (uint8_t)i); + } +} + +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs) +{ + /* enable and enable all scheme interrupts */ + iowrite32be(0xFFFFFFFF, ®s->fmkg_seer); + iowrite32be(0xFFFFFFFF, ®s->fmkg_seeer); +} + +void fman_kg_enable(struct fman_kg_regs *regs) +{ + iowrite32be(ioread32be(®s->fmkg_gcr) | FM_KG_KGGCR_EN, + ®s->fmkg_gcr); +} + +void fman_kg_disable(struct fman_kg_regs *regs) +{ + iowrite32be(ioread32be(®s->fmkg_gcr) & ~FM_KG_KGGCR_EN, + ®s->fmkg_gcr); +} + +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset) +{ + iowrite32be(offset, ®s->fmkg_fdor); +} + +void fman_kg_set_dflt_val(struct fman_kg_regs *regs, + uint8_t def_id, + uint32_t val) +{ + if(def_id == 0) + iowrite32be(val, ®s->fmkg_gdv0r); + else + iowrite32be(val, ®s->fmkg_gdv1r); +} + + +void fman_kg_set_exception(struct fman_kg_regs *regs, + uint32_t exception, + bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(®s->fmkg_eeer); + + if (enable) { + tmp |= exception; + } else { + tmp &= ~exception; + } + + iowrite32be(tmp, ®s->fmkg_eeer); +} + +void fman_kg_get_exception(struct fman_kg_regs *regs, + uint32_t *events, + uint32_t *scheme_ids, + bool clear) +{ + uint32_t mask; + + *events = ioread32be(®s->fmkg_eer); + mask = ioread32be(®s->fmkg_eeer); + *events &= mask; + + *scheme_ids = 0; + + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) { + *scheme_ids = ioread32be(®s->fmkg_seer); + mask = ioread32be(®s->fmkg_seeer); + *scheme_ids &= mask; + } + + if (clear) { + iowrite32be(*scheme_ids, ®s->fmkg_seer); + iowrite32be(*events, ®s->fmkg_eer); + } +} + +void fman_kg_get_capture(struct fman_kg_regs *regs, + struct fman_kg_ex_ecc_attr *ecc_attr, + bool clear) +{ + uint32_t tmp; + + tmp = ioread32be(®s->fmkg_serc); + + if (tmp & KG_FMKG_SERC_CAP) { + /* Captured data is valid */ + ecc_attr->valid = TRUE; + ecc_attr->double_ecc = + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE); + ecc_attr->single_ecc_count = + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >> + KG_FMKG_SERC_CNT_SHIFT); + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK); + + if (clear) + iowrite32be(KG_FMKG_SERC_CAP, ®s->fmkg_serc); + } else { + /* No ECC error is captured */ + ecc_attr->valid = FALSE; + } +} + +int fman_kg_build_scheme(struct fman_kg_scheme_params *params, + struct fman_kg_scheme_regs *scheme_regs) +{ + struct fman_kg_extract_params *extract_params; + struct fman_kg_gen_extract_params *gen_params; + uint32_t tmp_reg, i, select, mask, fqb; + uint8_t offset, shift, ht; + + /* Zero out all registers so no need to care about unused ones */ + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs)); + + /* Mode register */ + tmp_reg = fm_kg_build_nia(params->next_engine, + params->next_engine_action); + if (tmp_reg == KG_NIA_INVALID) { + return -EINVAL; + } + + if (params->next_engine == E_FMAN_PCD_PLCR) { + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR; + } + else if (params->next_engine == E_FMAN_PCD_CC) { + tmp_reg |= (uint32_t)params->cc_params.base_offset << + FMAN_KG_SCH_MODE_CCOBASE_SHIFT; + } + + tmp_reg |= FMAN_KG_SCH_MODE_EN; + scheme_regs->kgse_mode = tmp_reg; + + /* Match vector */ + scheme_regs->kgse_mv = params->match_vector; + + extract_params = ¶ms->extract_params; + + /* Scheme default values registers */ + scheme_regs->kgse_dv0 = extract_params->def_scheme_0; + scheme_regs->kgse_dv1 = extract_params->def_scheme_1; + + /* Extract Known Fields Command register */ + scheme_regs->kgse_ekfc = extract_params->known_fields; + + /* Entry Extract Known Default Value register */ + tmp_reg = 0; + tmp_reg |= extract_params->known_fields_def.mac_addr << + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT; + tmp_reg |= extract_params->known_fields_def.vlan_tci << + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT; + tmp_reg |= extract_params->known_fields_def.etype << + FMAN_KG_SCH_DEF_ETYPE_SHIFT; + tmp_reg |= extract_params->known_fields_def.ppp_sid << + FMAN_KG_SCH_DEF_PPP_SID_SHIFT; + tmp_reg |= extract_params->known_fields_def.ppp_pid << + FMAN_KG_SCH_DEF_PPP_PID_SHIFT; + tmp_reg |= extract_params->known_fields_def.mpls << + FMAN_KG_SCH_DEF_MPLS_SHIFT; + tmp_reg |= extract_params->known_fields_def.ip_addr << + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT; + tmp_reg |= extract_params->known_fields_def.ptype << + FMAN_KG_SCH_DEF_PTYPE_SHIFT; + tmp_reg |= extract_params->known_fields_def.ip_tos_tc << + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT; + tmp_reg |= extract_params->known_fields_def.ipv6_fl << + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT; + tmp_reg |= extract_params->known_fields_def.ipsec_spi << + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT; + tmp_reg |= extract_params->known_fields_def.l4_port << + FMAN_KG_SCH_DEF_L4_PORT_SHIFT; + tmp_reg |= extract_params->known_fields_def.tcp_flg << + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT; + + scheme_regs->kgse_ekdv = tmp_reg; + + /* Generic extract registers */ + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) { + return -EINVAL; + } + + for (i = 0; i < extract_params->gen_extract_num; i++) { + gen_params = extract_params->gen_extract + i; + + tmp_reg = FMAN_KG_SCH_GEN_VALID; + tmp_reg |= (uint32_t)gen_params->def_val << + FMAN_KG_SCH_GEN_DEF_SHIFT; + + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) { + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) || + (gen_params->extract == 0)) { + return -EINVAL; + } + } else { + tmp_reg |= FMAN_KG_SCH_GEN_OR; + } + + tmp_reg |= (uint32_t)gen_params->extract << + FMAN_KG_SCH_GEN_SIZE_SHIFT; + tmp_reg |= (uint32_t)gen_params->mask << + FMAN_KG_SCH_GEN_MASK_SHIFT; + + offset = gen_params->offset; + ht = get_gen_ht_code(gen_params->src, + gen_params->no_validation, + &offset); + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT; + tmp_reg |= offset; + + scheme_regs->kgse_gec[i] = tmp_reg; + } + + /* Masks registers */ + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) { + return -EINVAL; + } + + select = 0; + mask = 0; + fqb = 0; + for (i = 0; i < extract_params->masks_num; i++) { + /* MCSx fields */ + KG_GET_MASK_SEL_SHIFT(shift, i); + if (extract_params->masks[i].is_known) { + /* Mask known field */ + select |= extract_params->masks[i].field_or_gen_idx << + shift; + } else { + /* Mask generic extract */ + select |= (extract_params->masks[i].field_or_gen_idx + + FM_KG_MASK_SEL_GEN_BASE) << shift; + } + + /* MOx fields - spread between se_bmch and se_fqb registers */ + KG_GET_MASK_OFFSET_SHIFT(shift, i); + if (i < 2) { + select |= (uint32_t)extract_params->masks[i].offset << + shift; + } else { + fqb |= (uint32_t)extract_params->masks[i].offset << + shift; + } + + /* BMx fields */ + KG_GET_MASK_SHIFT(shift, i); + mask |= (uint32_t)extract_params->masks[i].mask << shift; + } + + /* Finish with rest of BMx fileds - + * don't mask bits for unused masks by setting + * corresponding BMx field = 0xFF */ + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) { + KG_GET_MASK_SHIFT(shift, i); + mask |= 0xFF << shift; + } + + scheme_regs->kgse_bmch = select; + scheme_regs->kgse_bmcl = mask; + + /* Finish with FQB register initialization. + * Check fqid is 24-bit value. */ + if (params->base_fqid & ~0x00FFFFFF) { + return -EINVAL; + } + + fqb |= params->base_fqid; + scheme_regs->kgse_fqb = fqb; + + /* Hash Configuration register */ + tmp_reg = 0; + if (params->hash_params.use_hash) { + /* Check hash mask is 24-bit value */ + if (params->hash_params.mask & ~0x00FFFFFF) { + return -EINVAL; + } + + /* Hash function produces 64-bit value, 24 bits of that + * are used to generate fq_id and policer profile. + * Thus, maximal shift is 40 bits to allow 24 bits out of 64. + */ + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) { + return -EINVAL; + } + + tmp_reg |= params->hash_params.mask; + tmp_reg |= (uint32_t)params->hash_params.shift_r << + FMAN_KG_SCH_HASH_HSHIFT_SHIFT; + + if (params->hash_params.sym) { + tmp_reg |= FMAN_KG_SCH_HASH_SYM; + } + + } + + if (params->bypass_fqid_gen) { + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN; + } + + scheme_regs->kgse_hc = tmp_reg; + + /* Policer Profile register */ + if (params->policer_params.bypass_pp_gen) { + tmp_reg = 0; + } else { + /* Lower 8 bits of 24-bits extracted from hash result + * are used for policer profile generation. + * That leaves maximum shift value = 23. */ + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) { + return -EINVAL; + } + + tmp_reg = params->policer_params.base; + tmp_reg |= ((uint32_t)params->policer_params.shift << + FMAN_KG_SCH_PP_SH_SHIFT) & + FMAN_KG_SCH_PP_SH_MASK; + tmp_reg |= ((uint32_t)params->policer_params.shift << + FMAN_KG_SCH_PP_SL_SHIFT) & + FMAN_KG_SCH_PP_SL_MASK; + tmp_reg |= (uint32_t)params->policer_params.mask << + FMAN_KG_SCH_PP_MASK_SHIFT; + } + + scheme_regs->kgse_ppc = tmp_reg; + + /* Coarse Classification Bit Select register */ + if (params->next_engine == E_FMAN_PCD_CC) { + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel; + } + + /* Packets Counter register */ + if (params->update_counter) { + scheme_regs->kgse_spc = params->counter_value; + } + + return 0; +} + +int fman_kg_write_scheme(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + struct fman_kg_scheme_regs *scheme_regs, + bool update_counter) +{ + struct fman_kg_scheme_regs *kgse_regs; + uint32_t tmp_reg; + int err, i; + + /* Write indirect scheme registers */ + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); + + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode); + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc); + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv); + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch); + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl); + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb); + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc); + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc); + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc); + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0); + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1); + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs); + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv); + + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++) + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]); + + /* Write AR (Action register) */ + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + return err; +} + +int fman_kg_delete_scheme(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id) +{ + struct fman_kg_scheme_regs *kgse_regs; + uint32_t tmp_reg; + int err, i; + + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); + + /* Clear all registers including enable bit in mode register */ + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) { + iowrite32be(0, ((uint32_t *)kgse_regs + i)); + } + + /* Write AR (Action register) */ + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + return err; +} + +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + uint32_t *counter) +{ + struct fman_kg_scheme_regs *kgse_regs; + uint32_t tmp_reg; + int err; + + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); + + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + + if (err != 0) + return err; + + *counter = ioread32be(&kgse_regs->kgse_spc); + + return 0; +} + +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + uint32_t counter) +{ + struct fman_kg_scheme_regs *kgse_regs; + uint32_t tmp_reg; + int err; + + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); + + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE); + + err = fman_kg_write_ar_wait(regs, tmp_reg); + if (err != 0) + return err; + + /* Keygen indirect access memory contains all scheme_id registers + * by now. Change only counter value. */ + iowrite32be(counter, &kgse_regs->kgse_spc); + + /* Write back scheme registers */ + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + + return err; +} + +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs) +{ + return ioread32be(®s->fmkg_tpc); +} + +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params, + struct fman_kg_cp_regs *cls_plan_regs) +{ + uint8_t entries_set, entry_bit; + int i; + + /* Zero out all group's register */ + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs)); + + /* Go over all classification entries in params->entries_mask and + * configure the corresponding cpe register */ + entries_set = params->entries_mask; + for (i = 0; entries_set; i++) { + entry_bit = (uint8_t)(0x80 >> i); + if ((entry_bit & entries_set) == 0) + continue; + entries_set ^= entry_bit; + cls_plan_regs->kgcpe[i] = params->mask_vector[i]; + } + + return 0; +} + +int fman_kg_write_cls_plan(struct fman_kg_regs *regs, + uint8_t grp_id, + uint8_t entries_mask, + uint8_t hwport_id, + struct fman_kg_cp_regs *cls_plan_regs) +{ + struct fman_kg_cp_regs *kgcpe_regs; + uint32_t tmp_reg; + int i, err; + + /* Check group index is valid and the group isn't empty */ + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM) + return -EINVAL; + + /* Write indirect classification plan registers */ + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]); + + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) { + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]); + } + + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + return err; +} + +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs, + uint8_t hwport_id, + uint32_t schemes) +{ + struct fman_kg_pe_regs *kg_pe_regs; + uint32_t tmp_reg; + int err; + + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); + + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp); + + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + return err; +} + +int fman_kg_build_bind_cls_plans(uint8_t grp_base, + uint8_t grp_mask, + uint32_t *bind_cls_plans) +{ + /* Check grp_base and grp_mask are 5-bits values */ + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F)) + return -EINVAL; + + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base); + return 0; +} + + +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs, + uint8_t hwport_id, + uint32_t bind_cls_plans) +{ + struct fman_kg_pe_regs *kg_pe_regs; + uint32_t tmp_reg; + int err; + + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); + + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp); + + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE); + err = fman_kg_write_ar_wait(regs, tmp_reg); + return err; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_prs.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_prs.c new file mode 100644 index 000000000000..108779dbaf40 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fman_prs.c @@ -0,0 +1,129 @@ +/* + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_prs.h" + +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->fmpr_perr) & ev_mask; +} + +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs) +{ + return ioread32be(®s->fmpr_perer); +} + +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event) +{ + iowrite32be(event, ®s->fmpr_perr); +} + +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->fmpr_pevr) & ev_mask; +} + +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs) +{ + return ioread32be(®s->fmpr_pever); +} + +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event) +{ + iowrite32be(event, ®s->fmpr_pevr); +} + +void fman_prs_defconfig(struct fman_prs_cfg *cfg) +{ + cfg->port_id_stat = 0; + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM; + cfg->prs_exceptions = 0x03000000; +} + +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg) +{ + uint32_t tmp; + + iowrite32be(cfg->max_prs_cyc_lim, ®s->fmpr_rpclim); + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS), + ®s->fmpr_pevr); + + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC) + iowrite32be(FM_PCD_PRS_SINGLE_ECC, ®s->fmpr_pever); + else + iowrite32be(0, ®s->fmpr_pever); + + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, ®s->fmpr_perr); + + tmp = 0; + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC) + tmp |= FM_PCD_PRS_DOUBLE_ECC; + iowrite32be(tmp, ®s->fmpr_perer); + + iowrite32be(cfg->port_id_stat, ®s->fmpr_ppsc); + + return 0; +} + +void fman_prs_enable(struct fman_prs_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN; + iowrite32be(tmp, ®s->fmpr_rpimac); +} + +void fman_prs_disable(struct fman_prs_regs *regs) +{ + uint32_t tmp; + + tmp = ioread32be(®s->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN; + iowrite32be(tmp, ®s->fmpr_rpimac); +} + +int fman_prs_is_enabled(struct fman_prs_regs *regs) +{ + return ioread32be(®s->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN; +} + +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk) +{ + iowrite32be(pid_msk, ®s->fmpr_ppsc); +} + +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable) +{ + if (enable) + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, ®s->fmpr_ppsc); + else + iowrite32be(0, ®s->fmpr_ppsc); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c index 127435873bba..79419eab453f 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,36 +30,46 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_port.c @Description FM driver routines implementation. -*//***************************************************************************/ + *//***************************************************************************/ #include "error_ext.h" #include "std_ext.h" #include "string_ext.h" #include "sprint_ext.h" #include "debug_ext.h" -#include "fm_pcd_ext.h" +#include "fm_muram_ext.h" +#include "fman_common.h" #include "fm_port.h" - +#include "fm_port_dsar.h" +#include "common/general.h" /****************************************/ /* static functions */ /****************************************/ +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort); static t_Error CheckInitParameters(t_FmPort *p_FmPort) { t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; - t_Error ans = E_OK; - uint32_t unusedMask; - uint8_t i; - uint8_t j; - bool found; + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg; + t_Error ans = E_OK; + uint32_t unusedMask; if (p_FmPort->imEn) { + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + > 2) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2")); + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK) return ERROR_CODE(ans); } @@ -68,67 +78,41 @@ static t_Error CheckInitParameters(t_FmPort *p_FmPort) /****************************************/ /* Rx only */ /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { /* external buffer pools */ - if(!p_Params->extBufPools.numOfPoolsUsed) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); + if (!p_Params->extBufPools.numOfPoolsUsed) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); - if(p_Params->extBufPools.numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS)); + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools, + p_Params->p_BackupBmPools, + &p_Params->bufPoolDepletion) != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); - for(i=0;iextBufPools.numOfPoolsUsed;i++) - { - if(p_Params->extBufPools.extBufPool[i].id >= BM_MAX_NUM_OF_POOLS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS)); - if(!p_Params->extBufPools.extBufPool[i].size) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i)); - } - - /* backup BM pools indication is valid only for some chip deriviatives - (limited by the config routine) */ - if(p_Params->p_BackupBmPools) - { - if(p_Params->p_BackupBmPools->numOfBackupPools >= p_Params->extBufPools.numOfPoolsUsed) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed")); - found = FALSE; - for(i = 0;ip_BackupBmPools->numOfBackupPools;i++) - for(j=0;jextBufPools.numOfPoolsUsed;j++) - if(p_Params->p_BackupBmPools->poolIds[i] == p_Params->extBufPools.extBufPool[j].id) - found = TRUE; - if (!found) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id")); - } - - /* up to extBufPools.numOfPoolsUsed pools may be defined */ - if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable) - { - if((p_Params->bufPoolDepletion.numOfPools > p_Params->extBufPools.numOfPoolsUsed)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS)); - - if(!p_Params->bufPoolDepletion.numOfPools) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE")); - } /* Check that part of IC that needs copying is small enough to enter start margin */ - if(p_Params->intContext.size + p_Params->intContext.extBufOffset > p_Params->bufMargins.startMargins) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size is larger than start margins")); + if (p_Params->intContext.size + && (p_Params->intContext.size + + p_Params->intContext.extBufOffset + > p_Params->bufMargins.startMargins)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("intContext.size is larger than start margins")); - if(p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); -#ifdef FM_PARTITION_ARRAY - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - if(p_Params->liodnOffset >= MAX_LIODN_OFFSET) - { - p_Params->liodnOffset = (uint16_t)(p_Params->liodnOffset & (MAX_LIODN_OFFSET-1)); - DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard.")); - } - } - } -#endif /* FM_PARTITION_ARRAY */ + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE) + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); + +#ifdef FM_NO_BACKUP_POOLS + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6)) + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools")); +#endif /* FM_NO_BACKUP_POOLS */ } /****************************************/ @@ -136,25 +120,51 @@ static t_Error CheckInitParameters(t_FmPort *p_FmPort) /****************************************/ else { - if(p_Params->deqSubPortal >= MAX_QMI_DEQ_SUBPORTAL) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" deqSubPortal has to be in the range of 0 - %d", MAX_QMI_DEQ_SUBPORTAL)); + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS)); /* to protect HW internal-context from overwrite */ - if((p_Params->intContext.size) && (p_Params->intContext.intContextOffset < MIN_TX_INT_OFFSET)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); + if ((p_Params->intContext.size) + && (p_Params->intContext.intContextOffset + < MIN_TX_INT_OFFSET)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); + + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */ + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + != DEFAULT_notSupported)) + { + /* Check that not larger than 8 */ + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth) + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + > MAX_FIFO_PIPELINE_DEPTH)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); + } } /****************************************/ /* Rx Or Offline Parsing */ /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) { - - if(!p_Params->dfltFqid) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1")); + if (!p_Params->dfltFqid) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("dfltFqid must be between 1 and 2^24-1")); #if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004) - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); #endif /* defined(FM_CAPWAP_SUPPORT) && ... */ } @@ -163,170 +173,365 @@ static t_Error CheckInitParameters(t_FmPort *p_FmPort) /****************************************/ /* common BMI registers values */ /* Check that Queue Id is not larger than 2^24, and is not 0 */ - if((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("errFqid must be between 1 and 2^24-1")); - if(p_Params->dfltFqid & ~0x00FFFFFF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1")); + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("errFqid must be between 1 and 2^24-1")); + if (p_Params->dfltFqid & ~0x00FFFFFF) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("dfltFqid must be between 1 and 2^24-1")); } /****************************************/ /* Rx only */ /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { - /* Check that divisible by 256 and not larger than 256 */ - if(p_Params->rxFifoPriElevationLevel % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); - if(!p_Params->rxFifoPriElevationLevel || (p_Params->rxFifoPriElevationLevel > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); - if(p_Params->rxFifoThreshold % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); - if(!p_Params->rxFifoThreshold ||(p_Params->rxFifoThreshold > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS) + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS) + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); /* Check that not larger than 16 */ - if(p_Params->cutBytesFromEnd > FRAME_END_DATA_SIZE) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); - /* Check the margin definition */ - if(p_Params->bufMargins.startMargins > MAX_EXT_BUFFER_OFFSET) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); - if(p_Params->bufMargins.endMargins > MAX_EXT_BUFFER_OFFSET) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); /* extra FIFO size (allowed only to Rx ports) */ - if(p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); + if (p_Params->setSizeOfFifo + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); - if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable && - !p_Params->bufPoolDepletion.numOfPools) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE")); + if (p_Params->bufPoolDepletion.poolsGrpModeEnable + && !p_Params->bufPoolDepletion.numOfPools) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE")); #ifdef FM_CSI_CFED_LIMIT + if (p_FmPort->fmRevInfo.majorRev == 4) { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - - if (revInfo.majorRev == 4) - { - /* Check that not larger than 16 */ - if(p_Params->cutBytesFromEnd + p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); - } + /* Check that not larger than 16 */ + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); } #endif /* FM_CSI_CFED_LIMIT */ - } /****************************************/ /* Non Rx ports */ /****************************************/ + /* extra FIFO size (allowed only to Rx ports) */ else - /* extra FIFO size (allowed only to Rx ports) */ - if(p_FmPort->fifoBufs.extra) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No fifoBufs.extra for non Rx ports")); - - /****************************************/ - /* Rx & Tx */ - /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || - (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) - { - /* Check that not larger than 16 */ - if(p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); - } + if (p_FmPort->fifoBufs.extra) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + (" No fifoBufs.extra for non Rx ports")); /****************************************/ /* Tx only */ /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) { - /* Check that divisible by 256 and not larger than 256 */ - if(p_Params->txFifoMinFillLevel % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); - if(p_Params->txFifoMinFillLevel > (BMI_MAX_FIFO_SIZE - 256)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be in the range of 0 - %d", BMI_MAX_FIFO_SIZE)); - if(p_Params->txFifoLowComfLevel % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); - if(!p_Params->txFifoLowComfLevel || (p_Params->txFifoLowComfLevel > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256))); + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS) + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); - /* Check that not larger than 8 */ - if((!p_FmPort->txFifoDeqPipelineDepth) ||( p_FmPort->txFifoDeqPipelineDepth > MAX_FIFO_PIPELINE_DEPTH)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); - if(p_FmPort->portType == e_FM_PORT_TYPE_TX) - if(p_FmPort->txFifoDeqPipelineDepth > 2) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth for !G can't be larger than 2")); + if (p_FmPort->portType == e_FM_PORT_TYPE_TX) + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + > 2) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("fifoDeqPipelineDepth for 1G can't be larger than 2")); } - else + /****************************************/ /* Non Tx Ports */ /****************************************/ - { - /* If discard override was selected , no frames may be discarded. */ - if(p_Params->frmDiscardOverride && p_Params->errorsToDiscard) - RETURN_ERROR(MAJOR, E_CONFLICT, ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); - } + /* If discard override was selected , no frames may be discarded. */ + else + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard) + RETURN_ERROR( + MAJOR, + E_CONFLICT, + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); /****************************************/ /* Rx and Offline parsing */ /****************************************/ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) - || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) { - if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) unusedMask = BMI_STATUS_OP_MASK_UNUSED; else unusedMask = BMI_STATUS_RX_MASK_UNUSED; /* Check that no common bits with BMI_STATUS_MASK_UNUSED */ - if(p_Params->errorsToDiscard & unusedMask) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("errorsToDiscard contains undefined bits")); + if (p_Params->errorsToDiscard & unusedMask) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("errorsToDiscard contains undefined bits")); + } + + /****************************************/ + /* Offline Ports */ + /****************************************/ +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT + if ((p_FmPort->fmRevInfo.majorRev >= 6) + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + && p_Params->setNumOfOpenDmas + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS)); +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */ + + /****************************************/ + /* Offline & HC Ports */ + /****************************************/ + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) + { +#ifndef FM_FRAME_END_PARAMS_FOR_OP + if ((p_FmPort->fmRevInfo.majorRev < 6) && + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported)) + /* this is an indication that user called config for this mode which is not supported in this integration */ + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only")); +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */ + +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP + if ((!((p_FmPort->fmRevInfo.majorRev == 4) || + (p_FmPort->fmRevInfo.majorRev >= 6))) && + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported)) + /* this is an indication that user called config for this mode which is not supported in this integration */ + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only")); +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ } /****************************************/ /* All ports */ /****************************************/ + /* Check that not larger than 16 */ + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported))) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); - /* Check that divisible by 16 and not larger than 240 */ - if(p_Params->intContext.intContextOffset >MAX_INT_OFFSET) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET)); - if(p_Params->intContext.intContextOffset % OFFSET_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS)); - - /* check that ic size+ic internal offset, does not exceed ic block size */ - if(p_Params->intContext.size + p_Params->intContext.intContextOffset > MAX_IC_SIZE) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE)); - /* Check that divisible by 16 and not larger than 256 */ - if(p_Params->intContext.size % OFFSET_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS)); - - /* Check that divisible by 16 and not larger than 4K */ - if(p_Params->intContext.extBufOffset > MAX_EXT_OFFSET) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET)); - if(p_Params->intContext.extBufOffset % OFFSET_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS)); + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); /* common BMI registers values */ - if((!p_FmPort->tasks.num) || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); - if(p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); - if((!p_FmPort->openDmas.num) || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); - if(p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); - if(!p_FmPort->fifoBufs.num || (p_FmPort->fifoBufs.num > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); - if(p_FmPort->fifoBufs.num % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); + if (p_Params->setNumOfTasks + && ((!p_FmPort->tasks.num) + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); + if (p_Params->setNumOfTasks + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); + if (p_Params->setNumOfOpenDmas + && ((!p_FmPort->openDmas.num) + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); + if (p_Params->setNumOfOpenDmas + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); + if (p_Params->setSizeOfFifo + && (!p_FmPort->fifoBufs.num + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE))) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); + +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + if (p_FmPort->fmRevInfo.majorRev == 4) + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported) + /* this is an indication that user called config for this mode which is not supported in this integration */ + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption")); +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + + return E_OK; +} + +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort) +{ + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0; + + /*************************/ + /* TX PORTS */ + /*************************/ + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) + { + minFifoSizeRequired = + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) + + (3 * BMI_FIFO_UNITS)); + if (!p_FmPort->imEn) + minFifoSizeRequired += + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + * BMI_FIFO_UNITS; + + optFifoSizeForB2B = minFifoSizeRequired; + + /* Add some margin for back-to-back capability to improve performance, + allows the hardware to pipeline new frame dma while the previous + frame not yet transmitted. */ + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; + else + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS; + } + + /*************************/ + /* RX IM PORTS */ + /*************************/ + else + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + && p_FmPort->imEn) + { + optFifoSizeForB2B = + minFifoSizeRequired = + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) + + (4 * BMI_FIFO_UNITS)); + } + + /*************************/ + /* RX non-IM PORTS */ + /*************************/ + else + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + && !p_FmPort->imEn) + { + if (p_FmPort->fmRevInfo.majorRev == 4) + { + if (p_FmPort->rxPoolsParams.numOfPools == 1) + minFifoSizeRequired = 8 * BMI_FIFO_UNITS; + else + minFifoSizeRequired = + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS) + + (7 * BMI_FIFO_UNITS)); + } + else + { +#if (DPAA_VERSION >= 11) + minFifoSizeRequired = + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) + + (5 * BMI_FIFO_UNITS)); + /* 4 according to spec + 1 for FOF>0 */ +#else + minFifoSizeRequired = (uint32_t) + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS) + + (7*BMI_FIFO_UNITS)); +#endif /* (DPAA_VERSION >= 11) */ + } + + optFifoSizeForB2B = minFifoSizeRequired; + + /* Add some margin for back-to-back capability to improve performance, + allows the hardware to pipeline new frame dma while the previous + frame not yet transmitted. */ + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS; + else + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; + } + + /* For O/H ports, check fifo size and update if necessary */ + else + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) + { +#if (DPAA_VERSION >= 11) + optFifoSizeForB2B = + minFifoSizeRequired = + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth + + 5) * BMI_FIFO_UNITS)); + /* 4 according to spec + 1 for FOF>0 */ +#else + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS); +#endif /* (DPAA_VERSION >= 11) */ + } + + ASSERT_COND(minFifoSizeRequired > 0); + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired); + + /* Verify the size */ + if (p_FmPort->fifoBufs.num < minFifoSizeRequired) + DBG(INFO, + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired)); + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B) + DBG(INFO, + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B)); return E_OK; } static void FmPortDriverParamFree(t_FmPort *p_FmPort) { - if(p_FmPort->p_FmPortDriverParam) + if (p_FmPort->p_FmPortDriverParam) { XX_Free(p_FmPort->p_FmPortDriverParam); p_FmPort->p_FmPortDriverParam = NULL; @@ -335,997 +540,505 @@ static void FmPortDriverParamFree(t_FmPort *p_FmPort) static t_Error SetExtBufferPools(t_FmPort *p_FmPort) { - t_FmPortExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; - t_FmPortBufPoolDepletion *p_BufPoolDepletion = &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; - volatile uint32_t *p_ExtBufRegs; - volatile uint32_t *p_BufPoolDepletionReg; - bool rxPort; - bool found; - uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; - uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; - uint8_t count = 0; - uint8_t numOfPools; - uint16_t bufSize = 0, largestBufSize = 0; - int i=0, j=0, k=0; - uint32_t tmpReg, vector, minFifoSizeRequired=0; + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; + t_FmBufPoolDepletion *p_BufPoolDepletion = + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; + int i = 0, j = 0, err; + struct fman_port_bpools bpools; memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); - memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmPortExtPools)); + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools)); - switch(p_FmPort->portType) + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray, + sizesArray); + + /* Prepare flibs bpools structure */ + memset(&bpools, 0, sizeof(struct fman_port_bpools)); + bpools.count = p_ExtBufPools->numOfPoolsUsed; + bpools.counters_enable = TRUE; + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi; - p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_mpd; - rxPort = TRUE; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi; - p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ompd; - rxPort = FALSE; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for port type")); - } - - /* First we copy the external buffers pools information to an ordered local array */ - for(i=0;inumOfPoolsUsed;i++) - { - /* get pool size */ - bufSize = p_ExtBufPools->extBufPool[i].size; - - /* keep sizes in an array according to poolId for direct access */ - sizesArray[p_ExtBufPools->extBufPool[i].id] = bufSize; - - /* save poolId in an ordered array according to size */ - for (j=0;j<=i;j++) - { - /* this is the next free place in the array */ - if (j==i) - orderedArray[i] = p_ExtBufPools->extBufPool[i].id; - else - { - /* find the right place for this poolId */ - if(bufSize < sizesArray[orderedArray[j]]) + bpools.bpool[i].bpid = orderedArray[i]; + bpools.bpool[i].size = sizesArray[orderedArray[i]]; + /* functionality available only for some derivatives (limited by config) */ + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) + for (j = 0; + j + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools; + j++) + if (orderedArray[i] + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) { - /* move the poolIds one place ahead to make room for this poolId */ - for(k=i;k>j;k--) - orderedArray[k] = orderedArray[k-1]; - - /* now k==j, this is the place for the new size */ - orderedArray[k] = p_ExtBufPools->extBufPool[i].id; + bpools.bpool[i].is_backup = TRUE; break; } - } - } } - /* build the register value */ + /* save pools parameters for later use */ + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; + p_FmPort->rxPoolsParams.largestBufSize = + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]]; + p_FmPort->rxPoolsParams.secondLargestBufSize = + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]]; - for(i=0;inumOfPoolsUsed;i++) + /* FMBM_RMPD reg. - pool depletion */ + if (p_BufPoolDepletion->poolsGrpModeEnable) { - tmpReg = BMI_EXT_BUF_POOL_VALID | BMI_EXT_BUF_POOL_EN_COUNTER; - tmpReg |= ((uint32_t)orderedArray[i] << BMI_EXT_BUF_POOL_ID_SHIFT); - tmpReg |= sizesArray[orderedArray[i]]; - /* functionality available only for some deriviatives (limited by config) */ - if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools) - for(j=0;jp_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;j++) - if(orderedArray[i] == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) - { - tmpReg |= BMI_EXT_BUF_POOL_BACKUP; - break; - } - WRITE_UINT32(*(p_ExtBufRegs+i), tmpReg); - } - - if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools) - XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); - - numOfPools = (uint8_t)(rxPort ? FM_PORT_MAX_NUM_OF_EXT_POOLS:FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS); - - /* clear unused pools */ - for(i=p_ExtBufPools->numOfPoolsUsed;irxPoolsParams.largestBufSize = largestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-1]]; - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) - { -#ifdef FM_FIFO_ALLOCATION_OLD_ALG - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - - if(revInfo.majorRev != 4) + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools; + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) { - minFifoSizeRequired = (uint32_t)(((largestBufSize % BMI_FIFO_UNITS) ? - ((largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : - largestBufSize) + - (7*BMI_FIFO_UNITS)); - } - else -#endif /* FM_FIFO_ALLOCATION_OLD_ALG */ - { - p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; - if(p_ExtBufPools->numOfPoolsUsed == 1) - minFifoSizeRequired = 8*BMI_FIFO_UNITS; - else + if (p_BufPoolDepletion->poolsToConsider[i]) { - uint16_t secondLargestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-2]]; - p_FmPort->rxPoolsParams.secondLargestBufSize = secondLargestBufSize; - minFifoSizeRequired = (uint32_t)(((secondLargestBufSize % BMI_FIFO_UNITS) ? - ((secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : - secondLargestBufSize) + - (7*BMI_FIFO_UNITS)); - } - } - if(p_FmPort->fifoBufs.num < minFifoSizeRequired) - { - p_FmPort->fifoBufs.num = minFifoSizeRequired; - DBG(INFO, ("FIFO size for Rx port enlarged to %d",minFifoSizeRequired)); - } - } - - /* check if pool size is not too big */ - /* This is a definition problem in which if the fifo for the RX port - is lower than the largest pool size the hardware will allocate scatter gather - buffers even though the frame size can fit in a single buffer. */ - if (largestBufSize > p_FmPort->fifoBufs.num) - DBG(WARNING, ("Frame larger than port Fifo size (%u) will be split to more than a single buffer (S/G) even if shorter than largest buffer size (%u)", - p_FmPort->fifoBufs.num, largestBufSize)); - - /* pool depletion */ - tmpReg = 0; - if(p_BufPoolDepletion->numberOfPoolsModeEnable) - { - /* calculate vector for number of pools depletion */ - found = FALSE; - vector = 0; - count = 0; - for(i=0;ipoolsToConsider[i]) - { - for(j=0;jnumOfPoolsUsed;j++) + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) { if (i == orderedArray[j]) { - vector |= 0x80000000 >> j; - found = TRUE; - count++; + bpools.bpool[j].grp_bp_depleted = TRUE; break; } } - if (!found) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); - else - found = FALSE; } } - if (count < p_BufPoolDepletion->numOfPools) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined.")); - - /* configure num of pools and vector for number of pools mode */ - tmpReg |= (((uint32_t)p_BufPoolDepletion->numOfPools - 1) << BMI_POOL_DEP_NUM_OF_POOLS_SHIFT); - tmpReg |= vector; } - if(p_BufPoolDepletion->singlePoolModeEnable) + if (p_BufPoolDepletion->singlePoolModeEnable) { - /* calculate vector for number of pools depletion */ - found = FALSE; - vector = 0; - count = 0; - for(i=0;ipoolsToConsiderForSingleMode[i]) + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i]) { - for(j=0;jnumOfPoolsUsed;j++) + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) { if (i == orderedArray[j]) - { - vector |= 0x00000080 >> j; - found = TRUE; - count++; + { + bpools.bpool[j].single_bp_depleted = TRUE; break; } } - if (!found) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); - else - found = FALSE; } } - if (!count) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion.")); - - /* configure num of pools and vector for number of pools mode */ - tmpReg |= vector; } - WRITE_UINT32(*p_BufPoolDepletionReg, tmpReg); +#if (DPAA_VERSION >= 11) + /* fill QbbPEV */ + if (p_BufPoolDepletion->poolsGrpModeEnable + || p_BufPoolDepletion->singlePoolModeEnable) + { + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++) + { + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE) + { + bpools.bpool[i].pfc_priorities_en = TRUE; + } + } + } +#endif /* (DPAA_VERSION >= 11) */ + + /* Issue flibs function */ + err = fman_port_set_bpools(&p_FmPort->port, &bpools); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools")); + + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); return E_OK; } static t_Error ClearPerfCnts(t_FmPort *p_FmPort) { + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0); - FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0); FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0); return E_OK; } -static t_Error BmiRxPortInit(t_FmPort *p_FmPort) +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort) { - t_FmPortRxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; - uint32_t tmpReg; - t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; - uint32_t errorsToEnq = 0; - t_FmPortPerformanceCnt performanceContersParams; - t_Error err; + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam; + struct fman_port_params portParams; + uint32_t tmpVal; + t_Error err; - /* check that port is not busy */ - if (GET_UINT32(p_Regs->fmbm_rcfg) & BMI_PORT_CFG_EN) - RETURN_ERROR(MAJOR, E_INVALID_STATE, - ("Port(%d,%d) is already enabled",p_FmPort->portType, p_FmPort->portId)); - - /* Set Config register */ - tmpReg = 0; - if (p_FmPort->imEn) - tmpReg |= BMI_PORT_CFG_IM; - /* No discard - all error frames go to error queue */ - else if (p_Params->frmDiscardOverride) - tmpReg |= BMI_PORT_CFG_FDOVR; - - WRITE_UINT32(p_Regs->fmbm_rcfg, tmpReg); - - /* Configure dma attributes */ - tmpReg = 0; - tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; - if(p_Params->dmaWriteOptimize) - tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; - - WRITE_UINT32(p_Regs->fmbm_rda, tmpReg); - - /* Configure Rx Fifo params */ - tmpReg = 0; - tmpReg |= ((p_Params->rxFifoPriElevationLevel/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_PRI_ELEVATION_SHIFT); - tmpReg |= ((p_Params->rxFifoThreshold/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_THRESHOLD_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_rfp, tmpReg); + /* Set up flibs parameters and issue init function */ + memset(&portParams, 0, sizeof(struct fman_port_params)); + portParams.discard_mask = p_DriverParams->errorsToDiscard; + portParams.dflt_fqid = p_DriverParams->dfltFqid; + portParams.err_fqid = p_DriverParams->errFqid; + portParams.deq_sp = p_DriverParams->deqSubPortal; + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf; + switch (p_FmPort->portType) { -#ifdef FM_NO_THRESHOLD_REG - t_FmRevisionInfo revInfo; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask); + if (!p_FmPort->imEn) + { + if (p_DriverParams->forwardReuseIntContext) + p_DriverParams->dfltCfg.rx_fd_bits = + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24); + } + break; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev > 1) -#endif /* FM_NO_THRESHOLD_REG */ - /* always allow access to the extra resources */ - WRITE_UINT32(p_Regs->fmbm_reth, BMI_RX_FIFO_THRESHOLD_BC); + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask); + break; + break; + + default: + break; } - /* frame end parameters */ - tmpReg = 0; - tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_RX_FRAME_END_CS_IGNORE_SHIFT); - tmpReg |= ((uint32_t)p_Params->cutBytesFromEnd<< BMI_RX_FRAME_END_CUT_SHIFT); + tmpVal = + (uint32_t)( + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset + / OFFSET_UNITS + 1) : + (p_FmPort->internalBufferOffset / OFFSET_UNITS)); + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS); + p_DriverParams->dfltCfg.int_buf_start_margin = + p_FmPort->internalBufferOffset; - WRITE_UINT32(p_Regs->fmbm_rfed, tmpReg); + p_DriverParams->dfltCfg.ext_buf_start_margin = + p_DriverParams->bufMargins.startMargins; + p_DriverParams->dfltCfg.ext_buf_end_margin = + p_DriverParams->bufMargins.endMargins; - /* IC parameters */ - tmpReg = 0; - tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); + p_DriverParams->dfltCfg.ic_ext_offset = + p_DriverParams->intContext.extBufOffset; + p_DriverParams->dfltCfg.ic_int_offset = + p_DriverParams->intContext.intContextOffset; + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size; - WRITE_UINT32(p_Regs->fmbm_ricp, tmpReg); + p_DriverParams->dfltCfg.stats_counters_enable = TRUE; + p_DriverParams->dfltCfg.perf_counters_enable = TRUE; + p_DriverParams->dfltCfg.queue_counters_enable = TRUE; - if (!p_FmPort->imEn) - { - /* check if the largest external buffer pool is large enough */ - if(p_Params->bufMargins.startMargins + MIN_EXT_BUF_SIZE + p_Params->bufMargins.endMargins > p_FmPort->rxPoolsParams.largestBufSize) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", - p_Params->bufMargins.startMargins, p_Params->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize)); - - /* buffer margins */ - tmpReg = 0; - tmpReg |= (((uint32_t)p_Params->bufMargins.startMargins) << BMI_EXT_BUF_MARG_START_SHIFT); - tmpReg |= (((uint32_t)p_Params->bufMargins.endMargins) << BMI_EXT_BUF_MARG_END_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_rebm, tmpReg); - } - - - if(p_FmPort->internalBufferOffset) - { - tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ? - (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1): - (p_FmPort->internalBufferOffset/OFFSET_UNITS)); - p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); - WRITE_UINT32(p_Regs->fmbm_rim, tmpReg << BMI_IM_FOF_SHIFT); - } - - /* NIA */ - if (p_FmPort->imEn) - WRITE_UINT32(p_Regs->fmbm_rfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX); + p_DriverParams->dfltCfg.perf_cnt_params.task_val = + (uint8_t)p_FmPort->tasks.num; + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0; else - { - tmpReg = 0; - if (p_Params->forwardReuseIntContext) - tmpReg |= BMI_PORT_RFNE_FRWD_RPD; - /* L3/L4 checksum verify is enabled by default. */ - /*tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C;*/ - WRITE_UINT32(p_Regs->fmbm_rfne, tmpReg | NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); - } - WRITE_UINT32(p_Regs->fmbm_rfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1; + p_DriverParams->dfltCfg.perf_cnt_params.dma_val = + (uint8_t)p_FmPort->openDmas.num; + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num; - /* command attribute */ - tmpReg = BMI_CMD_RX_MR_DEF; - if (!p_FmPort->imEn) - { - tmpReg |= BMI_CMD_ATTR_ORDER; - if(p_Params->syncReq) - tmpReg |= BMI_CMD_ATTR_SYNC; - tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); - } + if (0 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg, + &portParams)) + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init")); - WRITE_UINT32(p_Regs->fmbm_rfca, tmpReg); - - /* default queues */ - if (!p_FmPort->imEn) - { - WRITE_UINT32(p_Regs->fmbm_rfqid, p_Params->dfltFqid); - WRITE_UINT32(p_Regs->fmbm_refqid, p_Params->errFqid); - } - - /* set counters */ - WRITE_UINT32(p_Regs->fmbm_rstc, BMI_COUNTERS_EN); - - performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; - performanceContersParams.queueCompVal = 1; - performanceContersParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num; - performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; - if((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams)) != E_OK) + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) RETURN_ERROR(MAJOR, err, NO_MSG); - - WRITE_UINT32(p_Regs->fmbm_rpc, BMI_COUNTERS_EN); - - /* error/status mask - check that if discard OV is set, no - discard is required for specific errors.*/ - WRITE_UINT32(p_Regs->fmbm_rfsdm, p_Params->errorsToDiscard); - - errorsToEnq = (RX_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); - WRITE_UINT32(p_Regs->fmbm_rfsem, errorsToEnq); - -#ifdef FM_BMI_TO_RISC_ENQ_ERRATA_FMANc - if((GET_UINT32(p_Regs->fmbm_rfene) && NIA_ENG_MASK)== NIA_ENG_FM_CTL) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("NIA not supported at this stage")); -#endif /* FM_BMI_TO_RISC_ENQ_ERRATA_FMANc */ - - return E_OK; -} - -static t_Error BmiTxPortInit(t_FmPort *p_FmPort) -{ - t_FmPortTxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; - uint32_t tmpReg; - t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; - /*uint32_t rateCountUnit;*/ - t_FmPortPerformanceCnt performanceContersParams; - - /* check that port is not busy */ - if (GET_UINT32(p_Regs->fmbm_tcfg) & BMI_PORT_CFG_EN) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); - - tmpReg = 0; - if (p_FmPort->imEn) - tmpReg |= BMI_PORT_CFG_IM; - - WRITE_UINT32(p_Regs->fmbm_tcfg, tmpReg); - - /* Configure dma attributes */ - tmpReg = 0; - tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; - - WRITE_UINT32(p_Regs->fmbm_tda, tmpReg); - - /* Configure Tx Fifo params */ - tmpReg = 0; - tmpReg |= ((p_Params->txFifoMinFillLevel/BMI_FIFO_UNITS) << BMI_TX_FIFO_MIN_FILL_SHIFT); - tmpReg |= (((uint32_t)p_FmPort->txFifoDeqPipelineDepth - 1) << BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT); - tmpReg |= ((p_Params->txFifoLowComfLevel/BMI_FIFO_UNITS - 1) << BMI_TX_LOW_COMF_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_tfp, tmpReg); - - /* frame end parameters */ - tmpReg = 0; - tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_TX_FRAME_END_CS_IGNORE_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_tfed, tmpReg); - - if (!p_FmPort->imEn) - { - /* IC parameters */ - tmpReg = 0; - tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_ticp, tmpReg); - } - - /* NIA */ - if (p_FmPort->imEn) - { - WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); - WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); - } else { - WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_QMI_DEQ); - WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); - /* The line bellow is a trick so the FM will not release the buffer - to BM nor will try to enq the frame to QM */ - if(!p_Params->dfltFqid && p_Params->dontReleaseBuf) + // from QMIInit + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + { + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH) + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, + FALSE); + else + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, + TRUE); + } + } + /* The code bellow is a trick so the FM will not release the buffer + to BM nor will try to enqueue the frame to QM */ + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn)) + { + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf) { /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to - * act acording to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release * buffers to BM regardless of fmbm_tfene */ - WRITE_UINT32(p_Regs->fmbm_tcfqid, 0xFFFFFF); - WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF); + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene, + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); } } - /* command attribute */ - tmpReg = BMI_CMD_TX_MR_DEF; - if (p_FmPort->imEn) - tmpReg |= BMI_CMD_MR_DEAS; - else - { - tmpReg |= BMI_CMD_ATTR_ORDER; - /* if we set syncReq, we may get stuck when HC command is running */ - /*if(p_Params->syncReq) - tmpReg |= BMI_CMD_ATTR_SYNC;*/ - tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); - } - - WRITE_UINT32(p_Regs->fmbm_tfca, tmpReg); - - /* default queues */ - if (!p_FmPort->imEn) - { - if(p_Params->dfltFqid || !p_Params->dontReleaseBuf) - WRITE_UINT32(p_Regs->fmbm_tcfqid, p_Params->dfltFqid); - WRITE_UINT32(p_Regs->fmbm_tfeqid, p_Params->errFqid); - } - - /* statistics & performance counters */ - WRITE_UINT32(p_Regs->fmbm_tstc, BMI_COUNTERS_EN); - - performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; - performanceContersParams.queueCompVal = 1; - performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; - performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; - FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); - - WRITE_UINT32(p_Regs->fmbm_tpc, BMI_COUNTERS_EN); - return E_OK; } -static t_Error BmiOhPortInit(t_FmPort *p_FmPort) +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) { - t_FmPortOhBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; - uint32_t tmpReg, errorsToEnq = 0; - t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; - t_FmPortPerformanceCnt performanceContersParams; - t_Error err; + UNUSED(p_FmPort); - /* check that port is not busy */ - if (GET_UINT32(p_Regs->fmbm_ocfg) & BMI_PORT_CFG_EN) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); - - /* Configure dma attributes */ - tmpReg = 0; - tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; - tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; - if(p_Params->dmaWriteOptimize) - tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; - - WRITE_UINT32(p_Regs->fmbm_oda, tmpReg); - - /* IC parameters */ - tmpReg = 0; - tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); - tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); - - WRITE_UINT32(p_Regs->fmbm_oicp, tmpReg); - - /* NIA */ - WRITE_UINT32(p_Regs->fmbm_ofdne, NIA_ENG_QMI_DEQ); - - if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) - WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ); - else - WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); - - /* command attribute */ - if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) - tmpReg = BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; - else - tmpReg = BMI_CMD_ATTR_ORDER | BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; - - if(p_Params->syncReq) - tmpReg |= BMI_CMD_ATTR_SYNC; - tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); - WRITE_UINT32(p_Regs->fmbm_ofca, tmpReg); - - /* No discard - all error frames go to error queue */ - if (p_Params->frmDiscardOverride) - tmpReg = BMI_PORT_CFG_FDOVR; - else - tmpReg = 0; - WRITE_UINT32(p_Regs->fmbm_ocfg, tmpReg); - - if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + switch (counter) { - WRITE_UINT32(p_Regs->fmbm_ofsdm, p_Params->errorsToDiscard); - - errorsToEnq = (OP_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); - WRITE_UINT32(p_Regs->fmbm_ofsem, errorsToEnq); - - /* NIA */ - WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); - { -#ifdef FM_NO_OP_OBSERVED_POOLS - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 4) && (p_Params->enBufPoolDepletion)) -#endif /* FM_NO_OP_OBSERVED_POOLS */ - { - /* define external buffer pools */ - err = SetExtBufferPools(p_FmPort); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - } - } + case (e_FM_PORT_COUNTERS_CYCLE): + case (e_FM_PORT_COUNTERS_TASK_UTIL): + case (e_FM_PORT_COUNTERS_QUEUE_UTIL): + case (e_FM_PORT_COUNTERS_DMA_UTIL): + case (e_FM_PORT_COUNTERS_FIFO_UTIL): + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): + case (e_FM_PORT_COUNTERS_FRAME): + case (e_FM_PORT_COUNTERS_DISCARD_FRAME): + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): + case (e_FM_PORT_COUNTERS_DEALLOC_BUF): + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): + return TRUE; + default: + return FALSE; } - else - /* NIA */ - WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC); - - /* default queues */ - WRITE_UINT32(p_Regs->fmbm_ofqid, p_Params->dfltFqid); - WRITE_UINT32(p_Regs->fmbm_oefqid, p_Params->errFqid); - - if(p_FmPort->internalBufferOffset) - { - tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ? - (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1): - (p_FmPort->internalBufferOffset/OFFSET_UNITS)); - p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); - WRITE_UINT32(p_Regs->fmbm_oim, tmpReg << BMI_IM_FOF_SHIFT); - } - /* statistics & performance counters */ - WRITE_UINT32(p_Regs->fmbm_ostc, BMI_COUNTERS_EN); - - performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; - performanceContersParams.queueCompVal = 0; - performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; - performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; - FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); - - WRITE_UINT32(p_Regs->fmbm_opc, BMI_COUNTERS_EN); - - return E_OK; } -static t_Error QmiInit(t_FmPort *p_FmPort) +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) { - t_FmPortDriverParam *p_Params = NULL; - uint32_t tmpReg; + UNUSED(p_FmPort); - p_Params = p_FmPort->p_FmPortDriverParam; - - /* check that port is not busy */ - if(((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX)) && - (GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); - - /* enable & clear counters */ - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, QMI_PORT_CFG_EN_COUNTERS); - - /* The following is done for non-Rx ports only */ - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + switch (counter) { - if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || - (p_FmPort->portType == e_FM_PORT_TYPE_TX)) - { - /* define dequeue NIA */ - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); - /* define enqueue NIA */ - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); - } - else /* for HC & OP */ - { - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); - /* define enqueue NIA */ - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); - } - - /* configure dequeue */ - tmpReg = 0; - if(p_Params->deqHighPriority) - tmpReg |= QMI_DEQ_CFG_PRI; - - switch(p_Params->deqType) - { - case(e_FM_PORT_DEQ_TYPE1): - tmpReg |= QMI_DEQ_CFG_TYPE1; - break; - case(e_FM_PORT_DEQ_TYPE2): - tmpReg |= QMI_DEQ_CFG_TYPE2; - break; - case(e_FM_PORT_DEQ_TYPE3): - tmpReg |= QMI_DEQ_CFG_TYPE3; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue type")); - } - -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - switch(p_Params->deqPrefetchOption) - { - case(e_FM_PORT_DEQ_NO_PREFETCH): - /* Do nothing - QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_1_FRAME = 0 */ - break; - case(e_FM_PORT_DEQ_PARTIAL_PREFETCH): - tmpReg |= QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; - break; - case(e_FM_PORT_DEQ_FULL_PREFETCH): - tmpReg |= QMI_DEQ_CFG_PREFETCH_NO_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue prefetch option")); - } -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - - tmpReg |= p_Params->deqByteCnt; - tmpReg |= (uint32_t)p_Params->deqSubPortal << QMI_DEQ_CFG_SUBPORTAL_SHIFT; - - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndc, tmpReg); + case (e_FM_PORT_COUNTERS_CYCLE): + case (e_FM_PORT_COUNTERS_TASK_UTIL): + case (e_FM_PORT_COUNTERS_QUEUE_UTIL): + case (e_FM_PORT_COUNTERS_DMA_UTIL): + case (e_FM_PORT_COUNTERS_FIFO_UTIL): + case (e_FM_PORT_COUNTERS_FRAME): + case (e_FM_PORT_COUNTERS_DISCARD_FRAME): + case (e_FM_PORT_COUNTERS_LENGTH_ERR): + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): + case (e_FM_PORT_COUNTERS_DEALLOC_BUF): + return TRUE; + default: + return FALSE; } - else /* rx port */ - /* define enqueue NIA */ - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); - - return E_OK; } -static t_Error BmiRxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) { - t_FmPortRxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; - - /* check that counters are enabled */ - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_CYCLE): - case(e_FM_PORT_COUNTERS_TASK_UTIL): - case(e_FM_PORT_COUNTERS_QUEUE_UTIL): - case(e_FM_PORT_COUNTERS_DMA_UTIL): - case(e_FM_PORT_COUNTERS_FIFO_UTIL): - case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): - /* performance counters - may be read when disabled */ - break; - case(e_FM_PORT_COUNTERS_FRAME): - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - case(e_FM_PORT_COUNTERS_RX_BAD_FRAME): - case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME): - case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): - case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): - case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - if(!(GET_UINT32(p_BmiRegs->fmbm_rstc) & BMI_COUNTERS_EN)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); + case (e_FM_PORT_COUNTERS_CYCLE): + case (e_FM_PORT_COUNTERS_TASK_UTIL): + case (e_FM_PORT_COUNTERS_DMA_UTIL): + case (e_FM_PORT_COUNTERS_FIFO_UTIL): + case (e_FM_PORT_COUNTERS_FRAME): + case (e_FM_PORT_COUNTERS_DISCARD_FRAME): + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): + case (e_FM_PORT_COUNTERS_WRED_DISCARD): + case (e_FM_PORT_COUNTERS_LENGTH_ERR): + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): + case (e_FM_PORT_COUNTERS_DEALLOC_BUF): + return TRUE; + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) + return FALSE; + else + return TRUE; + default: + return FALSE; } +} - /* Set counter */ - switch(counter) +static t_Error BmiPortCheckAndGetCounterType( + t_FmPort *p_FmPort, e_FmPortCounters counter, + enum fman_port_stats_counters *p_StatsType, + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats) +{ + volatile uint32_t *p_Reg; + bool isValid; + + switch (p_FmPort->portType) { - case(e_FM_PORT_COUNTERS_CYCLE): - *p_Ptr = &p_BmiRegs->fmbm_rccn; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc; + isValid = CheckRxBmiCounter(p_FmPort, counter); break; - case(e_FM_PORT_COUNTERS_TASK_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_rtuc; + case (e_FM_PORT_TYPE_TX_10G): + case (e_FM_PORT_TYPE_TX): + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc; + isValid = CheckTxBmiCounter(p_FmPort, counter); break; - case(e_FM_PORT_COUNTERS_QUEUE_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_rrquc; - break; - case(e_FM_PORT_COUNTERS_DMA_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_rduc; - break; - case(e_FM_PORT_COUNTERS_FIFO_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_rfuc; - break; - case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): - *p_Ptr = &p_BmiRegs->fmbm_rpac; - break; - case(e_FM_PORT_COUNTERS_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_rfrc; - break; - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_rfcd; - break; - case(e_FM_PORT_COUNTERS_RX_BAD_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_rfbc; - break; - case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_rlfc; - break; - case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_rffc; - break; - case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -#ifdef FM_PORT_COUNTERS_ERRATA_FMANg - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1")); - } -#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */ - *p_Ptr = &p_BmiRegs->fmbm_rfldec; - break; - case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): - *p_Ptr = &p_BmiRegs->fmbm_rodc; - break; - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - *p_Ptr = &p_BmiRegs->fmbm_rbdc; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + case (e_FM_PORT_TYPE_OH_HOST_COMMAND): + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc; + isValid = CheckOhBmiCounter(p_FmPort, counter); break; default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); } - return E_OK; -} - -static t_Error BmiTxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) -{ - t_FmPortTxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; - - /* check that counters are enabled */ - switch(counter) - { - case(e_FM_PORT_COUNTERS_CYCLE): - case(e_FM_PORT_COUNTERS_TASK_UTIL): - case(e_FM_PORT_COUNTERS_QUEUE_UTIL): - case(e_FM_PORT_COUNTERS_DMA_UTIL): - case(e_FM_PORT_COUNTERS_FIFO_UTIL): - /* performance counters - may be read when disabled */ - break; - case(e_FM_PORT_COUNTERS_FRAME): - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - case(e_FM_PORT_COUNTERS_LENGTH_ERR): - case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - if(!(GET_UINT32(p_BmiRegs->fmbm_tstc) & BMI_COUNTERS_EN)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); - } - - /* Set counter */ - switch(counter) - { - case(e_FM_PORT_COUNTERS_CYCLE): - *p_Ptr = &p_BmiRegs->fmbm_tccn; - break; - case(e_FM_PORT_COUNTERS_TASK_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_ttuc; - break; - case(e_FM_PORT_COUNTERS_QUEUE_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_ttcquc; - break; - case(e_FM_PORT_COUNTERS_DMA_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_tduc; - break; - case(e_FM_PORT_COUNTERS_FIFO_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_tfuc; - break; - case(e_FM_PORT_COUNTERS_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_tfrc; - break; - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_tfdc; - break; - case(e_FM_PORT_COUNTERS_LENGTH_ERR): - *p_Ptr = &p_BmiRegs->fmbm_tfledc; - break; - case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): - *p_Ptr = &p_BmiRegs->fmbm_tfufdc; - break; - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - *p_Ptr = &p_BmiRegs->fmbm_tbdc; - break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); - } - - return E_OK; -} - -static t_Error BmiOhPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) -{ - t_FmPortOhBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; + if (!isValid) + RETURN_ERROR(MINOR, E_INVALID_STATE, + ("Requested counter is not available for this port type")); /* check that counters are enabled */ - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_CYCLE): - case(e_FM_PORT_COUNTERS_TASK_UTIL): - case(e_FM_PORT_COUNTERS_DMA_UTIL): - case(e_FM_PORT_COUNTERS_FIFO_UTIL): + case (e_FM_PORT_COUNTERS_CYCLE): + case (e_FM_PORT_COUNTERS_TASK_UTIL): + case (e_FM_PORT_COUNTERS_QUEUE_UTIL): + case (e_FM_PORT_COUNTERS_DMA_UTIL): + case (e_FM_PORT_COUNTERS_FIFO_UTIL): + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): /* performance counters - may be read when disabled */ + *p_IsStats = FALSE; break; - case(e_FM_PORT_COUNTERS_FRAME): - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): - case(e_FM_PORT_COUNTERS_WRED_DISCARD): - case(e_FM_PORT_COUNTERS_LENGTH_ERR): - case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); - break; - case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): /* only valid for offline parsing */ - if(p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Host Command ports")); - if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); + case (e_FM_PORT_COUNTERS_FRAME): + case (e_FM_PORT_COUNTERS_DISCARD_FRAME): + case (e_FM_PORT_COUNTERS_DEALLOC_BUF): + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): + case (e_FM_PORT_COUNTERS_LENGTH_ERR): + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): + case (e_FM_PORT_COUNTERS_WRED_DISCARD): + *p_IsStats = TRUE; + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN)) + RETURN_ERROR(MINOR, E_INVALID_STATE, + ("Requested counter was not enabled")); break; default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports")); + break; } /* Set counter */ - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_CYCLE): - *p_Ptr = &p_BmiRegs->fmbm_occn; + case (e_FM_PORT_COUNTERS_CYCLE): + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE; break; - case(e_FM_PORT_COUNTERS_TASK_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_otuc; + case (e_FM_PORT_COUNTERS_TASK_UTIL): + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL; break; - case(e_FM_PORT_COUNTERS_DMA_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_oduc; + case (e_FM_PORT_COUNTERS_QUEUE_UTIL): + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL; break; - case(e_FM_PORT_COUNTERS_FIFO_UTIL): - *p_Ptr = &p_BmiRegs->fmbm_ofuc; + case (e_FM_PORT_COUNTERS_DMA_UTIL): + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL; break; - case(e_FM_PORT_COUNTERS_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_ofrc; + case (e_FM_PORT_COUNTERS_FIFO_UTIL): + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL; break; - case(e_FM_PORT_COUNTERS_DISCARD_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_ofdc; + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE; break; - case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): - *p_Ptr = &p_BmiRegs->fmbm_offc; + case (e_FM_PORT_COUNTERS_FRAME): + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME; break; - case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -#ifdef FM_PORT_COUNTERS_ERRATA_FMANg - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1")); - } -#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */ - *p_Ptr = &p_BmiRegs->fmbm_ofldec; + case (e_FM_PORT_COUNTERS_DISCARD_FRAME): + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD; break; - case(e_FM_PORT_COUNTERS_WRED_DISCARD): - *p_Ptr = &p_BmiRegs->fmbm_ofwdc; + case (e_FM_PORT_COUNTERS_DEALLOC_BUF): + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF; break; - case(e_FM_PORT_COUNTERS_LENGTH_ERR): - *p_Ptr = &p_BmiRegs->fmbm_ofledc; + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME; break; - case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): - *p_Ptr = &p_BmiRegs->fmbm_ofufdc; + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME; break; - case(e_FM_PORT_COUNTERS_DEALLOC_BUF): - *p_Ptr = &p_BmiRegs->fmbm_obdc; + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF; + break; + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME; + break; + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR; + break; + case (e_FM_PORT_COUNTERS_WRED_DISCARD): + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD; + break; + case (e_FM_PORT_COUNTERS_LENGTH_ERR): + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR; + break; + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT; break; default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports")); + break; } return E_OK; } -static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, t_FmPcdPrsAdditionalHdrParams *p_HdrParams, uint32_t *p_SoftSeqAttachReg) +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, + t_FmPcdPrsAdditionalHdrParams *p_HdrParams, + uint32_t *p_SoftSeqAttachReg) { - uint8_t hdrNum, Ipv4HdrNum; - u_FmPcdHdrPrsOpts *p_prsOpts; - uint32_t tmpReg = 0, tmpPrsOffset; + uint8_t hdrNum, Ipv4HdrNum; + u_FmPcdHdrPrsOpts *p_prsOpts; + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset; - if(IS_PRIVATE_HEADER(p_HdrParams->hdr) || IS_SPECIAL_HEADER(p_HdrParams->hdr)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("No additional parameters for private or special headers.")); + if (IS_PRIVATE_HEADER(p_HdrParams->hdr) + || IS_SPECIAL_HEADER(p_HdrParams->hdr)) + RETURN_ERROR( + MAJOR, E_NOT_SUPPORTED, + ("No additional parameters for private or special headers.")); - if(p_HdrParams->errDisable) + if (p_HdrParams->errDisable) tmpReg |= PRS_HDR_ERROR_DIS; /* Set parser options */ - if(p_HdrParams->usePrsOpts) + if (p_HdrParams->usePrsOpts) { p_prsOpts = &p_HdrParams->prsOpts; - switch(p_HdrParams->hdr) + switch (p_HdrParams->hdr) { - case(HEADER_TYPE_MPLS): - if(p_prsOpts->mplsPrsOptions.labelInterpretationEnable) + case (HEADER_TYPE_MPLS): + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable) tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN; - GET_PRS_HDR_NUM(hdrNum, p_prsOpts->mplsPrsOptions.nextParse); - if(hdrNum == ILLEGAL_HDR_NUM) + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse); + if (hdrNum == ILLEGAL_HDR_NUM) RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); - GET_PRS_HDR_NUM(Ipv4HdrNum, HEADER_TYPE_IPv4); - if(hdrNum < Ipv4HdrNum) + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + if (hdrNum < Ipv4HdrNum) RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("Header must be equal or higher than IPv4")); - tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) << PRS_HDR_MPLS_NEXT_HDR_SHIFT; + ("Header must be equal or higher than IPv4")); + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) + << PRS_HDR_MPLS_NEXT_HDR_SHIFT; break; - case(HEADER_TYPE_PPPoE): - if(p_prsOpts->pppoePrsOptions.enableMTUCheck) - { -#ifdef FM_PPPOE_NO_MTU_CHECK - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Invalid parser option")); - else -#endif /* FM_PPPOE_NO_MTU_CHECK */ - tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; - } + case (HEADER_TYPE_PPPoE): + if (p_prsOpts->pppoePrsOptions.enableMTUCheck) + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; break; - case(HEADER_TYPE_IPv6): - if(p_prsOpts->ipv6PrsOptions.routingHdrDisable) - tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_DIS; + case (HEADER_TYPE_IPv6): + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable) + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN; break; - case(HEADER_TYPE_TCP): - if(p_prsOpts->tcpPrsOptions.padIgnoreChecksum) - tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; + case (HEADER_TYPE_TCP): + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum) + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; + else + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL; break; - case(HEADER_TYPE_UDP): - if(p_prsOpts->udpPrsOptions.padIgnoreChecksum) - tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; + case (HEADER_TYPE_UDP): + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum) + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL; + else + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL; break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header")); } } - /* set software parsing (address is devided in 2 since parser uses 2 byte access. */ - if(p_HdrParams->swPrsEnable) + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */ + if (p_HdrParams->swPrsEnable) { - tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, p_HdrParams->indexPerHdr); - if(tmpPrsOffset == ILLEGAL_BASE) - RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, + p_HdrParams->indexPerHdr); + if (tmpPrsOffset == ILLEGAL_BASE) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset); } *p_SoftSeqAttachReg = tmpReg; @@ -1333,24 +1046,25 @@ static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, t_FmPcdPrsAdditionalHdrP return E_OK; } -static uint32_t GetPortSchemeBindParams(t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) +static uint32_t GetPortSchemeBindParams( + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t walking1Mask = 0x80000000, tmp; - uint8_t idx = 0; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint32_t walking1Mask = 0x80000000, tmp; + uint8_t idx = 0; p_SchemeBind->netEnvId = p_FmPort->netEnvId; p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId; p_SchemeBind->useClsPlan = p_FmPort->useClsPlan; p_SchemeBind->numOfSchemes = 0; tmp = p_FmPort->schemesPerPortVector; - if(tmp) + if (tmp) { while (tmp) { - if(tmp & walking1Mask) + if (tmp & walking1Mask) { - p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = FmPcdKgGetSchemeSwId(p_FmPort->h_FmPcd, idx); + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx; p_SchemeBind->numOfSchemes++; tmp &= ~walking1Mask; } @@ -1362,400 +1076,357 @@ static uint32_t GetPortSchemeBindParams(t_Handle h_FmPort, t_FmPcdKgInterModuleB return tmp; } -static t_Error BuildBufferStructure(t_FmPort *p_FmPort) +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort) { - uint32_t tmp; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + volatile uint32_t *p_BmiCfgReg = NULL; + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; + uint32_t lcv, walking1Mask = 0x80000000; + uint8_t cnt = 0; ASSERT_COND(p_FmPort); + ASSERT_COND(p_FmPort->h_FmPcd); + ASSERT_COND(!p_FmPort->p_FmPortDriverParam); - /* Align start of internal context data to 16 byte */ - p_FmPort->p_FmPortDriverParam->intContext.extBufOffset = - (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize & (OFFSET_UNITS-1)) ? - ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) : - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + return; - /* Translate margin and intContext params to FM parameters */ -#ifdef FM_INCORRECT_CS_ERRATA_FMAN18 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg; + /* get LCV for MACSEC */ + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId)) + != 0) { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) + while (!(lcv & walking1Mask)) { - uint8_t mod = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign % 256; - if(mod) - { - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign += (256-mod); - DBG(WARNING,("dataAlign modified to next 256 to conform with FMAN18 errata\n")); - } + cnt++; + walking1Mask >>= 1; } + + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); } -#endif /* FM_INCORRECT_CS_ERRATA_FMAN18 */ - - /* Initialize with illegal value. Later we'll set legal values. */ - p_FmPort->bufferOffsets.prsResultOffset = (uint32_t)ILLEGAL_BASE; - p_FmPort->bufferOffsets.timeStampOffset = (uint32_t)ILLEGAL_BASE; - p_FmPort->bufferOffsets.hashResultOffset= (uint32_t)ILLEGAL_BASE; - p_FmPort->bufferOffsets.pcdInfoOffset = (uint32_t)ILLEGAL_BASE; -#ifdef DEBUG - p_FmPort->bufferOffsets.debugOffset = (uint32_t)ILLEGAL_BASE; -#endif /* DEBUG */ - - /* Internally the driver supports 4 options - 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll - relate to it as 1). - 2. All IC context (from AD) except debug. - 3. Debug information only. - 4. All IC context (from AD) including debug. - Note, that if user asks for prsResult/timestamp/hashResult and Debug, we give them (4) */ - - /* This 'if' covers options 2 & 4. We copy from beginning of context with or without debug. */ - /* If passAllOtherPCDInfo explicitly requested, or passDebugInfo+prs/ts --> we also take passAllOtherPCDInfo */ - if ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo) -#ifdef DEBUG - || (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo && - (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult || - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult)) -#endif /* DEBUG */ - ) - { -#ifdef DEBUG - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo) - { - p_FmPort->p_FmPortDriverParam->intContext.size = 240; - p_FmPort->bufferOffsets.debugOffset = - (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 128); - } - else -#endif /* DEBUG */ - p_FmPort->p_FmPortDriverParam->intContext.size = 128; /* must be aligned to 16 */ - /* Start copying data after 16 bytes (FD) from the beginning of the internal context */ - p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 16; - - if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo) - p_FmPort->bufferOffsets.pcdInfoOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; - if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult) - p_FmPort->bufferOffsets.prsResultOffset = - (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 16); - if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp) - p_FmPort->bufferOffsets.timeStampOffset = - (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 48); - if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) - p_FmPort->bufferOffsets.hashResultOffset = - (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 56); - } - else - { -#ifdef DEBUG - if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo) - { - /* This case covers option 3 */ - p_FmPort->p_FmPortDriverParam->intContext.size = 112; - p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 144; - p_FmPort->bufferOffsets.debugOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; - } - else -#endif /* DEBUG */ - { - /* This case covers the options under 1 */ - /* Copy size must be in 16-byte granularity. */ - p_FmPort->p_FmPortDriverParam->intContext.size = - (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 : 0) + - ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 16 : 0)); - - /* Align start of internal context data to 16 byte */ - p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = - (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 : - ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 64 : 0)); - - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult) - p_FmPort->bufferOffsets.prsResultOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp) - p_FmPort->bufferOffsets.timeStampOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? - (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult)) : - p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) - /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */ - p_FmPort->bufferOffsets.hashResultOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? - (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult) + 8) : - p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 8; - } - } - - p_FmPort->p_FmPortDriverParam->bufMargins.startMargins = - (uint16_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + - p_FmPort->p_FmPortDriverParam->intContext.size); -#ifdef FM_CAPWAP_SUPPORT - /* save extra space for manip in both external and internal buffers */ - if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace) - { - if((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE) >= 256) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + 32 can not be equal or larger to 256")); - p_FmPort->bufferOffsets.manipOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins; - p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE); - p_FmPort->p_FmPortDriverParam->internalBufferOffset = - (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE); - } -#endif /* FM_CAPWAP_SUPPORT */ - - /* align data start */ - tmp = (uint32_t)(p_FmPort->p_FmPortDriverParam->bufMargins.startMargins % - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign); - if (tmp) - p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign-tmp); - p_FmPort->bufferOffsets.dataOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins; - p_FmPort->internalBufferOffset = p_FmPort->p_FmPortDriverParam->internalBufferOffset; - - return E_OK; } -static t_Error SetPcd(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; - uint32_t tmpReg; - volatile uint32_t *p_BmiNia=NULL; - volatile uint32_t *p_BmiPrsNia=NULL; - volatile uint32_t *p_BmiPrsStartOffset=NULL; - volatile uint32_t *p_BmiInitPrsResult=NULL; - volatile uint32_t *p_BmiCcBase=NULL; - uint8_t hdrNum, L3HdrNum, greHdrNum; - int i; - bool isEmptyClsPlanGrp; - uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; - uint16_t absoluteProfileId; - uint8_t physicalSchemeId; - uint32_t ccTreePhysOffset; - SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + t_Error err = E_OK; + uint32_t tmpReg; + volatile uint32_t *p_BmiNia = NULL; + volatile uint32_t *p_BmiPrsNia = NULL; + volatile uint32_t *p_BmiPrsStartOffset = NULL; + volatile uint32_t *p_BmiInitPrsResult = NULL; + volatile uint32_t *p_BmiCcBase = NULL; + uint16_t hdrNum, L3HdrNum, greHdrNum; + int i; + bool isEmptyClsPlanGrp; + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; + uint16_t absoluteProfileId; + uint8_t physicalSchemeId; + uint32_t ccTreePhysOffset; + t_FmPcdKgInterModuleBindPortToSchemes schemeBind; + uint32_t initialSwPrs = 0; + + ASSERT_COND(p_FmPort); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independant mode ports only")); - if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); - p_FmPort->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdParams->h_NetEnv)-1); + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv); p_FmPort->pcdEngines = 0; /* initialize p_FmPort->pcdEngines field in port's structure */ - switch(p_PcdParams->pcdSupport) + switch (p_PcdParams->pcdSupport) { - case(e_FM_PORT_PCD_SUPPORT_NONE): - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); - case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY): + case (e_FM_PORT_PCD_SUPPORT_NONE): + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): p_FmPort->pcdEngines |= FM_PCD_PRS; break; - case(e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): - if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): p_FmPort->pcdEngines |= FM_PCD_PLCR; break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): p_FmPort->pcdEngines |= FM_PCD_PRS; p_FmPort->pcdEngines |= FM_PCD_PLCR; break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): p_FmPort->pcdEngines |= FM_PCD_PRS; p_FmPort->pcdEngines |= FM_PCD_KG; break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): p_FmPort->pcdEngines |= FM_PCD_PRS; p_FmPort->pcdEngines |= FM_PCD_CC; p_FmPort->pcdEngines |= FM_PCD_KG; break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): p_FmPort->pcdEngines |= FM_PCD_PRS; p_FmPort->pcdEngines |= FM_PCD_KG; p_FmPort->pcdEngines |= FM_PCD_CC; p_FmPort->pcdEngines |= FM_PCD_PLCR; break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): + p_FmPort->pcdEngines |= FM_PCD_PRS; + p_FmPort->pcdEngines |= FM_PCD_CC; + break; + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): + p_FmPort->pcdEngines |= FM_PCD_PRS; + p_FmPort->pcdEngines |= FM_PCD_CC; + p_FmPort->pcdEngines |= FM_PCD_PLCR; + break; + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): p_FmPort->pcdEngines |= FM_PCD_PRS; p_FmPort->pcdEngines |= FM_PCD_KG; p_FmPort->pcdEngines |= FM_PCD_PLCR; break; - + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY): + p_FmPort->pcdEngines |= FM_PCD_CC; + break; #ifdef FM_CAPWAP_SUPPORT - case(e_FM_PORT_PCD_SUPPORT_CC_ONLY): - if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); - p_FmPort->pcdEngines |= FM_PCD_CC; - break; - case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG): - if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG): p_FmPort->pcdEngines |= FM_PCD_CC; p_FmPort->pcdEngines |= FM_PCD_KG; break; - case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): - if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): p_FmPort->pcdEngines |= FM_PCD_CC; p_FmPort->pcdEngines |= FM_PCD_KG; p_FmPort->pcdEngines |= FM_PCD_PLCR; break; #endif /* FM_CAPWAP_SUPPORT */ + default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport")); } - if((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams > FM_PCD_PRS_NUM_OF_HDRS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); + if ((p_FmPort->pcdEngines & FM_PCD_PRS) + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams + > FM_PCD_PRS_NUM_OF_HDRS)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); /* check that parameters exist for each and only each defined engine */ - if((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) || - (!!(p_FmPort->pcdEngines & FM_PCD_KG) != !!p_PcdParams->p_KgParams) || - (!!(p_FmPort->pcdEngines & FM_PCD_CC) != !!p_PcdParams->p_CcParams)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("PCD initialization structure is not consistant with pcdSupport")); + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) + || (!!(p_FmPort->pcdEngines & FM_PCD_KG) + != !!p_PcdParams->p_KgParams) + || (!!(p_FmPort->pcdEngines & FM_PCD_CC) + != !!p_PcdParams->p_CcParams)) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("PCD initialization structure is not consistent with pcdSupport")); /* get PCD registers pointers */ - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; - p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; - p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[0]; - p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0]; + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; - p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; - p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[0]; - p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0]; + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); } - if(p_FmPort->pcdEngines & FM_PCD_KG) - { - - if(p_PcdParams->p_KgParams->numOfSchemes == 0) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For ports using Keygen, at lease one scheme must be bound. ")); - /* for each scheme */ - for(i = 0; ip_KgParams->numOfSchemes; i++) - { - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_Schemes[i])-1); - /* build vector */ - p_FmPort->schemesPerPortVector |= 1 << (31 - (uint32_t)physicalSchemeId); - } - - err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, - p_FmPort->hardwarePortId, - p_FmPort->netEnvId, - p_FmPort->optArray, - &p_FmPort->clsPlanGrpId, - &isEmptyClsPlanGrp); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); - - p_FmPort->useClsPlan = !isEmptyClsPlanGrp; - } - /* set PCD port parameter */ - if(p_FmPort->pcdEngines & FM_PCD_CC) + if (p_FmPort->pcdEngines & FM_PCD_CC) { - err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams->p_CcParams->h_CcTree, &ccTreePhysOffset, h_FmPort); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams, + p_PcdParams->p_CcParams->h_CcTree, + &ccTreePhysOffset, p_FmPort); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree; } + if (p_FmPort->pcdEngines & FM_PCD_KG) + { + if (p_PcdParams->p_KgParams->numOfSchemes == 0) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("For ports using Keygen, at least one scheme must be bound. ")); + + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, + p_FmPort->hardwarePortId, + p_FmPort->netEnvId, + p_FmPort->optArray, + &p_FmPort->clsPlanGrpId, + &isEmptyClsPlanGrp); + if (err) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); + + p_FmPort->useClsPlan = !isEmptyClsPlanGrp; + + schemeBind.netEnvId = p_FmPort->netEnvId; + schemeBind.hardwarePortId = p_FmPort->hardwarePortId; + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; + schemeBind.useClsPlan = p_FmPort->useClsPlan; + + /* for each scheme */ + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) + { + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]); + physicalSchemeId = FmPcdKgGetSchemeId( + p_PcdParams->p_KgParams->h_Schemes[i]); + schemeBind.schemesIds[i] = physicalSchemeId; + /* build vector */ + p_FmPort->schemesPerPortVector |= 1 + << (31 - (uint32_t)physicalSchemeId); +#if (DPAA_VERSION >= 11) + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement + if !VSPE - in port, for relevant scheme VSPE can not be set*/ + if (!p_FmPort->vspe + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i]))) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("VSPE is not at port level")); +#endif /* (DPAA_VERSION >= 11) */ + } + + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + /***************************/ /* configure NIA after BMI */ /***************************/ - if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - /* rfne may contain FDCS bits, so first we read them. */ - p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; + /* rfne may contain FDCS bits, so first we read them. */ + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; /* If policer is used directly after BMI or PRS */ - if((p_FmPort->pcdEngines & FM_PCD_PLCR) && - ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) || - (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) + if ((p_FmPort->pcdEngines & FM_PCD_PLCR) + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) + || (p_PcdParams->pcdSupport + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) { - absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_PcdParams->p_PlcrParams->h_Profile)-1); + if (!p_PcdParams->p_PlcrParams->h_Profile) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Profile should be initialized")); - if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Private port profile not valid.")); + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId( + p_PcdParams->p_PlcrParams->h_Profile); + + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Private port profile not valid.")); tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE); - if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ - { + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ /* update BMI HPNIA */ WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg)); - } - else /* e_FM_PCD_SUPPORT_PLCR_ONLY */ + else + /* e_FM_PCD_SUPPORT_PLCR_ONLY */ /* update BMI NIA */ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR); } -#ifdef FM_CAPWAP_SUPPORT /* if CC is used directly after BMI */ - if((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) || - (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) || - (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)) + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) +#ifdef FM_CAPWAP_SUPPORT + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR) +#endif /* FM_CAPWAP_SUPPORT */ + ) { if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); + RETURN_ERROR( + MAJOR, + E_INVALID_OPERATION, + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); - /* check that prs start offset == RIM[FOF] */ + /* check that prs start offset == RIM[FOF] */ } -#endif /* FM_CAPWAP_SUPPORT */ if (p_FmPort->pcdEngines & FM_PCD_PRS) { ASSERT_COND(p_PcdParams->p_PrsParams); - /* if PRS is used it is always first */ - GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->firstPrsHdr); - if (hdrNum == ILLEGAL_HDR_NUM) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); - if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) - p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); +#if (DPAA_VERSION >= 11) + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP) + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL; + else + { +#endif /* (DPAA_VERSION >= 11) */ + /* if PRS is used it is always first */ + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr); + if (hdrNum == ILLEGAL_HDR_NUM) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); +#if (DPAA_VERSION >= 11) + } +#endif /* (DPAA_VERSION >= 11) */ + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); /* set after parser NIA */ tmpReg = 0; - switch(p_PcdParams->pcdSupport) + switch (p_PcdParams->pcdSupport) { - case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY): - WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): + WRITE_UINT32(*p_BmiPrsNia, + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)); break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): tmpReg = NIA_KG_CC_EN; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): - if(p_PcdParams->p_KgParams->directScheme) + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): + if (p_PcdParams->p_KgParams->directScheme) { - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_DirectScheme)-1); + physicalSchemeId = FmPcdKgGetSchemeId( + p_PcdParams->p_KgParams->h_DirectScheme); /* check that this scheme was bound to this port */ - for(i=0 ; ip_KgParams->numOfSchemes; i++) - if(p_PcdParams->p_KgParams->h_DirectScheme == p_PcdParams->p_KgParams->h_Schemes[i]) + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) + if (p_PcdParams->p_KgParams->h_DirectScheme + == p_PcdParams->p_KgParams->h_Schemes[i]) break; - if(i == p_PcdParams->p_KgParams->numOfSchemes) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Direct scheme is not one of the port selected schemes.")); + if (i == p_PcdParams->p_KgParams->numOfSchemes) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("Direct scheme is not one of the port selected schemes.")); tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId); } WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg); break; - case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): + WRITE_UINT32(*p_BmiPrsNia, + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); + break; + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support")); } /* set start parsing offset */ - /* WRITE_UINT32(*p_BmiPrsStartOffset, p_PcdParams->p_PrsParams->parsingOffset); */ + WRITE_UINT32(*p_BmiPrsStartOffset, + p_PcdParams->p_PrsParams->parsingOffset); /************************************/ /* Parser port parameters */ @@ -1763,227 +1434,322 @@ static t_Error SetPcd(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) /* stop before configuring */ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); /* wait for parser to be in idle state */ - while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ; + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) + ; /* set soft seq attachment register */ - memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t)); + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t)); /* set protocol options */ - for(i=0;p_FmPort->optArray[i];i++) - switch(p_FmPort->optArray[i]) + for (i = 0; p_FmPort->optArray[i]; i++) + switch (p_FmPort->optArray[i]) { - case(ETH_BROADCAST): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_BC_SHIFT; + case (ETH_BROADCAST): + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT; break; - case(ETH_MULTICAST): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_MC_SHIFT; + case (ETH_MULTICAST): + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT; break; - case(VLAN_STACKED): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_VLAN) - tmpHxs[hdrNum] |= (i+1)<< PRS_HDR_VLAN_STACKED_SHIFT; + case (VLAN_STACKED): + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT; break; - case(MPLS_STACKED): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_MPLS_STACKED_SHIFT; + case (MPLS_STACKED): + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT; break; - case(IPV4_BROADCAST_1): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_BC_SHIFT; + case (IPV4_BROADCAST_1): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT; break; - case(IPV4_MULTICAST_1): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_MC_SHIFT; + case (IPV4_MULTICAST_1): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT; break; - case(IPV4_UNICAST_2): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_UC_SHIFT; + case (IPV4_UNICAST_2): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT; break; - case(IPV4_MULTICAST_BROADCAST_2): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; + case (IPV4_MULTICAST_BROADCAST_2): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; break; - case(IPV6_MULTICAST_1): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_1_MC_SHIFT; + case (IPV6_MULTICAST_1): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT; break; - case(IPV6_UNICAST_2): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_UC_SHIFT; + case (IPV6_UNICAST_2): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT; break; - case(IPV6_MULTICAST_2): - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) - tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_MC_SHIFT; + case (IPV6_MULTICAST_2): + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT; break; } - if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP)) + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, + HEADER_TYPE_UDP_ENCAP_ESP)) { - p_PcdParams->p_PrsParams->additionalParams - [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = HEADER_TYPE_UDP; - p_PcdParams->p_PrsParams->additionalParams - [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = TRUE; + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS) + RETURN_ERROR( + MINOR, E_INVALID_VALUE, + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1")); + + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = + HEADER_TYPE_UDP; + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = + TRUE; p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++; } /* set MPLS default next header - HW reset workaround */ - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; - GET_PRS_HDR_NUM(L3HdrNum, HEADER_TYPE_USER_DEFINED_L3); - tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3); + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; /* for GRE, disable errors */ - GET_PRS_HDR_NUM(greHdrNum, HEADER_TYPE_GRE); + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE); tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; + /* For UDP remove PAD from L4 checksum calculation */ + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP); + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL; + /* For TCP remove PAD from L4 checksum calculation */ + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP); + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL; + /* config additional params for specific headers */ - for(i=0 ; ip_PrsParams->numOfHdrsWithAdditionalParams ; i++) + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams; + i++) { - GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->additionalParams[i].hdr); - if(hdrNum== ILLEGAL_HDR_NUM) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); - if(hdrNum==NO_HDR_NUM) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Private headers may not use additional parameters")); - - err = AdditionalPrsParams(p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], &tmpReg); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); - - tmpHxs[hdrNum] |= tmpReg; - } -#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) + /* case for using sw parser as the initial NIA address, before + * HW parsing + */ + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) && + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable) { - /* link to sw parser code for L4 shells - only if no other code is applied. */ - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_SCTP) - if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) - tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | SCTP_SW_PATCH_START); - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_DCCP) - if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) - tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | DCCP_SW_PATCH_START); - GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPSEC_AH) - if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) - tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IPSEC_SW_PATCH_START); - } - } -#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */ + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE, + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr); + if (initialSwPrs == ILLEGAL_BASE) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); - for(i=0 ; isavedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */ + /* rewrite with soft parser start */ + p_FmPort->savedBmiNia |= initialSwPrs; + continue; + } + + hdrNum = + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr); + if (hdrNum == ILLEGAL_HDR_NUM) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); + if (hdrNum == NO_HDR_NUM) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("Private headers may not use additional parameters")); + + err = AdditionalPrsParams( + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], + &tmpHxs[hdrNum]); + if (err) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); + } + + /* Check if ip-reassembly port - need to link sw-parser code */ + if (p_FmPort->h_IpReassemblyManip) + { + /* link to sw parser code for IP Frag - only if no other code is applied. */ + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL); + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL); + } else { + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE)) + { + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))) + { + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); + } + } + +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, + HEADER_TYPE_UDP_LITE)) + { + /* link to sw parser code for udp lite - only if no other code is applied. */ + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL); + } +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++) { /* For all header set LCV as taken from netEnv*/ - WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); + WRITE_UINT32( + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); /* set HXS register according to default+Additional params+protocol options */ - WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, tmpHxs[i]); + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, + tmpHxs[i]); } /* set tpid. */ tmpReg = PRS_TPID_DFLT; - if(p_PcdParams->p_PrsParams->setVlanTpid1) + if (p_PcdParams->p_PrsParams->setVlanTpid1) { tmpReg &= PRS_TPID2_MASK; - tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 << PRS_PCTPID_SHIFT; + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 + << PRS_PCTPID_SHIFT; } - if(p_PcdParams->p_PrsParams->setVlanTpid2) + if (p_PcdParams->p_PrsParams->setVlanTpid2) { tmpReg &= PRS_TPID1_MASK; tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2; - } - WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); /* enable parser */ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0); - if(p_PcdParams->p_PrsParams->prsResultPrivateInfo) - p_FmPort->privateInfo = p_PcdParams->p_PrsParams->prsResultPrivateInfo; + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo) + p_FmPort->privateInfo = + p_PcdParams->p_PrsParams->prsResultPrivateInfo; } /* end parser */ - else - p_FmPort->privateInfo = 0; + else { + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + { + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach, + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL)); + } - WRITE_UINT32(*p_BmiPrsStartOffset, GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); + WRITE_UINT32(*p_BmiPrsStartOffset, 0); + + p_FmPort->privateInfo = 0; + } + + FmPortCheckNApplyMacsec(p_FmPort); + + WRITE_UINT32( + *p_BmiPrsStartOffset, + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); /* set initial parser result - used for all engines */ - for (i=0;iprivateInfo << BMI_PR_PORTID_SHIFT) - | BMI_PRS_RESULT_HIGH)); + WRITE_UINT32( + *(p_BmiInitPrsResult), + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH)); else - if (i< FM_PORT_PRS_RESULT_NUM_OF_WORDS/2) + { + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2) WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH); else WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW); + } } return E_OK; } -static t_Error DeletePcd(t_Handle h_FmPort) +static t_Error DeletePcd(t_FmPort *p_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; - volatile uint32_t *p_BmiNia=NULL; + t_Error err = E_OK; + volatile uint32_t *p_BmiNia = NULL; + volatile uint32_t *p_BmiPrsStartOffset = NULL; - SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + ASSERT_COND(p_FmPort); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independant mode ports only")); - if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); - if(!p_FmPort->pcdEngines) + if (!p_FmPort->pcdEngines) RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port")); /* get PCD registers pointers */ - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); } - if((GET_UINT32(*p_BmiNia) & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("port has to be detached previousely")); + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("port has to be detached previousely")); + + WRITE_UINT32(*p_BmiPrsStartOffset, 0); /* "cut" PCD out of the port's flow - go to BMI */ /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */ - if(p_FmPort->pcdEngines | FM_PCD_PRS) + if (p_FmPort->pcdEngines & FM_PCD_PRS) { /* stop parser */ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); /* wait for parser to be in idle state */ - while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ; + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) + ; } - if(p_FmPort->pcdEngines & FM_PCD_KG) + if (p_FmPort->pcdEngines & FM_PCD_KG) { - err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, p_FmPort->clsPlanGrpId); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + t_FmPcdKgInterModuleBindPortToSchemes schemeBind; + + /* unbind all schemes */ + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, + &schemeBind); + + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, + p_FmPort->hardwarePortId, + p_FmPort->clsPlanGrpId); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); p_FmPort->useClsPlan = FALSE; } - if(p_FmPort->pcdEngines & FM_PCD_CC) + if (p_FmPort->pcdEngines & FM_PCD_CC) { /* unbind - we need to get the treeId too */ - err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); } p_FmPort->pcdEngines = 0; @@ -1991,62 +1757,155 @@ static t_Error DeletePcd(t_Handle h_FmPort) return E_OK; } - -/********************************************/ -/* Inter-module API */ -/********************************************/ -void FmPortSetMacsecLcv(t_Handle h_FmPort) +static t_Error AttachPCD(t_FmPort *p_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiCfgReg = NULL; - uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; - uint32_t lcv, walking1Mask = 0x80000000; - uint8_t cnt = 0; + volatile uint32_t *p_BmiNia = NULL; - SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); + ASSERT_COND(p_FmPort); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + /* get PCD registers pointers */ + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; + else + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; + + /* check that current NIA is BMI to BMI */ + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("may be called only for ports in BMI-to-BMI state.")); + + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1, + p_FmPort->orFmanCtrl) != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE) { - REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Rx ports only")); - return; + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne, + p_FmPort->savedBmiCmne); + else + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne, + p_FmPort->savedBmiCmne); } - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; - /* get LCV for MACSEC */ - if ((p_FmPort->h_FmPcd) && ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))!= 0)) + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, + p_FmPort->savedQmiPnen); + + if (p_FmPort->requiredAction & UPDATE_NIA_FENE) { - while(!(lcv & walking1Mask)) - { - cnt++; - walking1Mask >>= 1; - } + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, + p_FmPort->savedBmiFene); + else + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, + p_FmPort->savedBmiFene); + } - macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; - } + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE) + { + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne, + p_FmPort->savedBmiFpne); + else + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne, + p_FmPort->savedBmiFpne); + } - WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE) + { + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING); + + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp, + p_FmPort->savedBmiOfp); + } + + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); + + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) + { + p_FmPort->origNonRxQmiRegsPndn = + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn); + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, + p_FmPort->savedNonRxQmiRegsPndn); + } + + return E_OK; } +static t_Error DetachPCD(t_FmPort *p_FmPort) +{ + volatile uint32_t *p_BmiNia = NULL; + + ASSERT_COND(p_FmPort); + + /* get PCD registers pointers */ + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, + p_FmPort->origNonRxQmiRegsPndn); + + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; + else + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; + + WRITE_UINT32( + *p_BmiNia, + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()); + + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd)) + FmPcdHcSync(p_FmPort->h_FmPcd); + + if (p_FmPort->requiredAction & UPDATE_NIA_FENE) + { + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); + else + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); + } + + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen, + NIA_ENG_BMI | NIA_BMI_AC_RELEASE); + + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2, + p_FmPort->orFmanCtrl) != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + + p_FmPort->requiredAction = 0; + + return E_OK; +} + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiCfgReg = NULL; - uint32_t tmpReg; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + volatile uint32_t *p_BmiCfgReg = NULL; + uint32_t tmpReg; SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) { REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only")); return; } - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfca; + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca; tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK; tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED; - tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) & BMI_CMD_ATTR_MACCMD_SC_MASK); + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) + & BMI_CMD_ATTR_MACCMD_SC_MASK); WRITE_UINT32(*p_BmiCfgReg, tmpReg); } @@ -2066,156 +1925,297 @@ uint32_t FmPortGetPcdEngines(t_Handle h_FmPort) return ((t_FmPort*)h_FmPort)->pcdEngines; } -t_Error FmPortAttachPCD(t_Handle h_FmPort) +#if (DPAA_VERSION >= 11) +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, + void **p_Value) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiNia=NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint32_t muramPageOffset; -/*TODO - to take care about the chnges that were made in the port because of the previously assigned tree. -pndn, pnen ... maybe were changed because of the Tree requirement*/ + ASSERT_COND(p_FmPort); + ASSERT_COND(p_Value); - /* get PCD registers pointers */ - switch(p_FmPort->portType) + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + if (p_FmPort->gprFunc != gprFunc) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("gpr was assigned with different func")); + } + else + { + switch (gprFunc) + { + case (e_FM_PORT_GPR_MURAM_PAGE): + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, + 256, 8); + if (!p_FmPort->p_ParamsPage) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page")); + + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256); + muramPageOffset = + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage) + - p_FmPort->fmMuramPhysBaseAddr); + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + WRITE_UINT32( + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr, + muramPageOffset); + break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + WRITE_UINT32( + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr, + muramPageOffset); + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Invalid port type")); + } + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); + } + p_FmPort->gprFunc = gprFunc; } - if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) - if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1)!= E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - - /* check that current NIA is BMI to BMI */ - if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); - - WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); - - if(p_FmPort->requiredAction & UPDATE_NIA_PNEN) - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, p_FmPort->savedQmiPnen); - - if(p_FmPort->requiredAction & UPDATE_NIA_PNDN) - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, p_FmPort->savedNonRxQmiRegsPndn); - + switch (p_FmPort->gprFunc) + { + case (e_FM_PORT_GPR_MURAM_PAGE): + *p_Value = p_FmPort->p_ParamsPage; + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); + } return E_OK; } +#endif /* (DPAA_VERSION >= 11) */ -t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_CcParams) +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, + t_FmPortGetSetCcParams *p_CcParams) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - int tmpInt; - volatile uint32_t *p_BmiPrsStartOffset = NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint32_t tmpInt; + volatile uint32_t *p_BmiPrsStartOffset = NULL; /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ - if((p_CcParams->getCcParams.type & OFFSET_OF_PR) && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR) + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) { - p_CcParams->getCcParams.prOffset = (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; + p_CcParams->getCcParams.prOffset = + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; p_CcParams->getCcParams.type &= ~OFFSET_OF_PR; } - if(p_CcParams->getCcParams.type & HW_PORT_ID) + if (p_CcParams->getCcParams.type & HW_PORT_ID) { - p_CcParams->getCcParams.hardwarePortId = (uint8_t)p_FmPort->hardwarePortId; + p_CcParams->getCcParams.hardwarePortId = + (uint8_t)p_FmPort->hardwarePortId; p_CcParams->getCcParams.type &= ~HW_PORT_ID; } - if((p_CcParams->getCcParams.type & OFFSET_OF_DATA) && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA) + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) { - p_CcParams->getCcParams.dataOffset = (uint16_t)p_FmPort->bufferOffsets.dataOffset; + p_CcParams->getCcParams.dataOffset = + (uint16_t)p_FmPort->bufferOffsets.dataOffset; p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA; } - if(p_CcParams->getCcParams.type & NUM_OF_TASKS) + if (p_CcParams->getCcParams.type & NUM_OF_TASKS) { - p_CcParams->getCcParams.numOfTasks = p_FmPort->numOfTasks; + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; p_CcParams->getCcParams.type &= ~NUM_OF_TASKS; } - if(p_CcParams->getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS) { - if(p_CcParams->getCcParams.poolIndex < p_FmPort->extBufPools.numOfPoolsUsed) - { - p_CcParams->getCcParams.poolIdForManip = p_FmPort->extBufPools.extBufPool[p_CcParams->getCcParams.poolIndex].id; - p_CcParams->getCcParams.type &= ~BUFFER_POOL_ID_FOR_MANIP; - } + p_CcParams->getCcParams.numOfExtraTasks = + (uint8_t)p_FmPort->tasks.extra; + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS; + } + if (p_CcParams->getCcParams.type & FM_REV) + { + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev; + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev; + p_CcParams->getCcParams.type &= ~FM_REV; + } + if (p_CcParams->getCcParams.type & DISCARD_MASK) + { + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + p_CcParams->getCcParams.discardMask = + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm); + else + p_CcParams->getCcParams.discardMask = + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm); + p_CcParams->getCcParams.type &= ~DISCARD_MASK; + } + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE) + { + p_CcParams->getCcParams.internalBufferOffset = + p_FmPort->internalBufferOffset; + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE; + } + if (p_CcParams->getCcParams.type & GET_NIA_FPNE) + { + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + p_CcParams->getCcParams.nia = + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne); + else + p_CcParams->getCcParams.nia = + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne); + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE; + } + if (p_CcParams->getCcParams.type & GET_NIA_PNDN) + { + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + p_CcParams->getCcParams.nia = + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn); + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN; } - if((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)) + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)) { p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl; } - if((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN)) + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN)) { p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia; p_FmPort->requiredAction |= UPDATE_NIA_PNEN; } - else if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) - { - if(p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pnen was defined previously different")); - } + else + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) + { + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("PNEN was defined previously different")); + } - if((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN)) + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN)) { p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia; p_FmPort->requiredAction |= UPDATE_NIA_PNDN; } - else if(p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) + else + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) + { + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("PNDN was defined previously different")); + } + + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE) + && (p_CcParams->setCcParams.overwrite + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE))) { - if(p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pndn was defined previously different")); + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia; + p_FmPort->requiredAction |= UPDATE_NIA_FENE; } + else + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE) + { + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia) + RETURN_ERROR( MAJOR, E_INVALID_STATE, + ("xFENE was defined previously different")); + } + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE)) + { + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia; + p_FmPort->requiredAction |= UPDATE_NIA_FPNE; + } + else + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) + { + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia) + RETURN_ERROR( MAJOR, E_INVALID_STATE, + ("xFPNE was defined previously different")); + } - if((p_CcParams->setCcParams.type & UPDATE_PSO) && !(p_FmPort->requiredAction & UPDATE_PSO)) + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE)) + { + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia; + p_FmPort->requiredAction |= UPDATE_NIA_CMNE; + } + else + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) + { + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia) + RETURN_ERROR( MAJOR, E_INVALID_STATE, + ("xCMNE was defined previously different")); + } + + if ((p_CcParams->setCcParams.type & UPDATE_PSO) + && !(p_FmPort->requiredAction & UPDATE_PSO)) { /* get PCD registers pointers */ - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; + break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + } + /* set start parsing offset */ - tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)+ p_CcParams->setCcParams.psoSize; - if(tmpInt>0) + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset) + + p_CcParams->setCcParams.psoSize; + if (tmpInt > 0) WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt); p_FmPort->requiredAction |= UPDATE_PSO; p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize; + } + else + if (p_CcParams->setCcParams.type & UPDATE_PSO) + { + if (p_FmPort->savedPrsStartOffset + != p_CcParams->setCcParams.psoSize) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("parser start offset was defoned previousley different")); + } - } - else if (p_CcParams->setCcParams.type & UPDATE_PSO) + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE) + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE)) { - if(p_FmPort->savedPrsStartOffset != p_CcParams->setCcParams.psoSize) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser start offset was defoned previousley different")); + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp); + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK; + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde + << BMI_FIFO_PIPELINE_DEPTH_SHIFT; + p_FmPort->requiredAction |= UPDATE_OFP_DPTE; } + return E_OK; } -/********************************** End of inter-module routines ********************************/ +/*********************** End of inter-module routines ************************/ /****************************************/ /* API Init unit functions */ /****************************************/ + t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) { - t_FmPort *p_FmPort; - uintptr_t baseAddr = p_FmPortParams->baseAddr; + t_FmPort *p_FmPort; + uintptr_t baseAddr = p_FmPortParams->baseAddr; + uint32_t tmpReg; /* Allocate FM structure */ - p_FmPort = (t_FmPort *) XX_Malloc(sizeof(t_FmPort)); + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort)); if (!p_FmPort) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure")); @@ -2224,7 +2224,8 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) memset(p_FmPort, 0, sizeof(t_FmPort)); /* Allocate the FM driver's parameters structure */ - p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(sizeof(t_FmPortDriverParam)); + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc( + sizeof(t_FmPortDriverParam)); if (!p_FmPort->p_FmPortDriverParam) { XX_Free(p_FmPort); @@ -2234,197 +2235,310 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam)); /* Initialize FM port parameters which will be kept by the driver */ - p_FmPort->portType = p_FmPortParams->portType; - p_FmPort->portId = p_FmPortParams->portId; - p_FmPort->pcdEngines = FM_PCD_NONE; - p_FmPort->f_Exception = p_FmPortParams->f_Exception; - p_FmPort->h_App = p_FmPortParams->h_App; - p_FmPort->h_Fm = p_FmPortParams->h_Fm; + p_FmPort->portType = p_FmPortParams->portType; + p_FmPort->portId = p_FmPortParams->portId; + p_FmPort->pcdEngines = FM_PCD_NONE; + p_FmPort->f_Exception = p_FmPortParams->f_Exception; + p_FmPort->h_App = p_FmPortParams->h_App; + p_FmPort->h_Fm = p_FmPortParams->h_Fm; + + /* get FM revision */ + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo); /* calculate global portId number */ - SW_PORT_ID_TO_HW_PORT_ID(p_FmPort->hardwarePortId, p_FmPort->portType, p_FmPortParams->portId); + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType, + p_FmPortParams->portId, + p_FmPort->fmRevInfo.majorRev, + p_FmPort->fmRevInfo.minorRev); - /* Initialize FM port parameters for initialization phase only */ - p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr; - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = DEFAULT_PORT_bufferPrefixContent_privDataSize; - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult= DEFAULT_PORT_bufferPrefixContent_passPrsResult; - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp= DEFAULT_PORT_bufferPrefixContent_passTimeStamp; - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo - = DEFAULT_PORT_bufferPrefixContent_passTimeStamp; -#ifdef DEBUG - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo= DEFAULT_PORT_bufferPrefixContent_debugInfo; -#endif /* DEBUG */ - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign; - p_FmPort->p_FmPortDriverParam->dmaSwapData = DEFAULT_PORT_dmaSwapData; - p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = DEFAULT_PORT_dmaIntContextCacheAttr; - p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = DEFAULT_PORT_dmaHeaderCacheAttr; - p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = DEFAULT_PORT_dmaScatterGatherCacheAttr; - p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize; - p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase; - - /* resource distribution. */ - p_FmPort->fifoBufs.num = DEFAULT_PORT_sizeOfFifo(p_FmPort->portType); - p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraSizeOfFifo(p_FmPort->portType); - p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType); - p_FmPort->openDmas.extra = DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType); - p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType); - p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType); - p_FmPort->numOfTasks = (uint8_t)p_FmPort->tasks.num; -#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 + if (p_FmPort->fmRevInfo.majorRev >= 6) { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - p_FmPort->fifoBufs.extra = 0; - p_FmPort->openDmas.extra = 0; - p_FmPort->tasks.extra = 0; - } - } -#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) + && (p_FmPortParams->portId != FM_OH_PORT_ID)) + DBG(WARNING, + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.", + FM_OH_PORT_ID)); - p_FmPort->p_FmPortDriverParam->color = DEFAULT_PORT_color; -#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && - (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - p_FmPort->p_FmPortDriverParam->color = e_FM_PORT_COLOR_OVERRIDE; + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + && (p_FmPortParams->portId == FM_OH_PORT_ID)) + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0.")); } -#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */ - if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReqForHc; + /* Set up FM port parameters for initialization phase only */ + + /* First, fill in flibs struct */ + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg, + (enum fman_port_type)p_FmPort->portType); + /* Overwrite some integration specific parameters */ + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = + DEFAULT_PORT_rxFifoPriElevationLevel; + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = + DEFAULT_PORT_rxFifoThreshold; + +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006) + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE; +#else + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE; +#endif + if ((p_FmPort->fmRevInfo.majorRev == 6) + && (p_FmPort->fmRevInfo.minorRev == 0)) + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE; else - p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReq; + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE; -#ifdef FM_PORT_SYNC_ERRATA_FMAN6 + /* Excessive Threshold register - exists for pre-FMv3 chips only */ + if (p_FmPort->fmRevInfo.majorRev < 6) { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - p_FmPort->p_FmPortDriverParam->syncReq = FALSE; +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = + TRUE; +#endif + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE; + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE; } -#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */ + else + { + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = + FALSE; + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE; + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE; + } + if (p_FmPort->fmRevInfo.majorRev == 4) + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE; + else + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE; + + /* Continue with other parameters */ + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr; + /* set memory map pointers */ + p_FmPort->p_FmPortQmiRegs = + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET); + p_FmPort->p_FmPortBmiRegs = + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET); + p_FmPort->p_FmPortPrsRegs = + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET); + + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = + DEFAULT_PORT_bufferPrefixContent_privDataSize; + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult = + DEFAULT_PORT_bufferPrefixContent_passPrsResult; + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp = + DEFAULT_PORT_bufferPrefixContent_passTimeStamp; + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo = + DEFAULT_PORT_bufferPrefixContent_passTimeStamp; + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = + DEFAULT_PORT_bufferPrefixContent_dataAlign; + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData; + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr; + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr; + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr; + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize; + */ + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase; + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = + DEFAULT_PORT_cheksumLastBytesIgnore; + + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength; + /* resource distribution. */ + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType) + * BMI_FIFO_UNITS; + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs + * BMI_FIFO_UNITS; + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType); + p_FmPort->openDmas.extra = + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType); + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType); + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType); + + +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 + if ((p_FmPort->fmRevInfo.majorRev == 6) + && (p_FmPort->fmRevInfo.minorRev == 0) + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))) + { + p_FmPort->openDmas.num = 16; + p_FmPort->openDmas.extra = 0; + } +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */ /* Port type specific initialization: */ - if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) && - (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) - p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride; - - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX): - case(e_FM_PORT_TYPE_RX_10G): - /* Initialize FM port parameters for initialization phase only */ - p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = DEFAULT_PORT_cutBytesFromEnd; - p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE; - p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride; - p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = DEFAULT_PORT_rxFifoPriElevationLevel; - p_FmPort->p_FmPortDriverParam->rxFifoThreshold = DEFAULT_PORT_rxFifoThreshold; - p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = DEFAULT_PORT_BufMargins_endMargins; - p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard; - p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore; - p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = DEFAULT_PORT_forwardIntContextReuse; - break; - - case(e_FM_PORT_TYPE_TX): - p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_1G; - p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE; - case(e_FM_PORT_TYPE_TX_10G): - if(p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) - p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_10G; - p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore; - p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = DEFAULT_PORT_txFifoMinFillLevel; - p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = DEFAULT_PORT_txFifoLowComfLevel; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_FmPort->p_FmPortDriverParam->deqHighPriority = DEFAULT_PORT_deqHighPriority; - p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - p_FmPort->p_FmPortDriverParam->deqByteCnt = DEFAULT_PORT_deqByteCnt; - - if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) - p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard; - break; - - default: - XX_Free(p_FmPort->p_FmPortDriverParam); - XX_Free(p_FmPort); - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - return NULL; - } -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption_HC; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - - if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || - (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - p_FmPort->txFifoDeqPipelineDepth = OH_PIPELINE_DEPTH; - - p_FmPort->imEn = p_FmPortParams->independentModeEnable; - - if (p_FmPort->imEn) - { - if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) || - (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) - p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_IM; - FmPortConfigIM(p_FmPort, p_FmPortParams); - } - else - { - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX): - case(e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + case (e_FM_PORT_TYPE_RX_10G): /* Initialize FM port parameters for initialization phase only */ - memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, - &p_FmPortParams->specificParams.rxParams.extBufPools, - sizeof(t_FmPortExtPools)); - p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.rxParams.errFqid; - p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.rxParams.dfltFqid; - p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.rxParams.liodnOffset; + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = + DEFAULT_PORT_cutBytesFromEnd; + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE; + p_FmPort->p_FmPortDriverParam->frmDiscardOverride = + DEFAULT_PORT_frmDiscardOverride; + + tmpReg = + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp); + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK) + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1) + * BMI_FIFO_UNITS; + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg + & BMI_RX_FIFO_THRESHOLD_MASK) + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS; + + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = + DEFAULT_PORT_BufMargins_endMargins; + p_FmPort->p_FmPortDriverParam->errorsToDiscard = + DEFAULT_PORT_errorsToDiscard; + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = + DEFAULT_PORT_forwardIntContextReuse; +#if (DPAA_VERSION >= 11) + p_FmPort->p_FmPortDriverParam->noScatherGather = + DEFAULT_PORT_noScatherGather; +#endif /* (DPAA_VERSION >= 11) */ break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -#ifdef FM_OP_PARTITION_ERRATA_FMANx8 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.nonRxParams.opLiodnOffset; - } -#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */ - case(e_FM_PORT_TYPE_TX): - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.nonRxParams.errFqid; - p_FmPort->p_FmPortDriverParam->deqSubPortal = - (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel & QMI_DEQ_CFG_SUBPORTAL_MASK); - p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.nonRxParams.dfltFqid; + + case (e_FM_PORT_TYPE_TX): + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE; +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 + tmpReg = 0x00001013; + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp, + tmpReg); +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */ + case (e_FM_PORT_TYPE_TX_10G): + tmpReg = + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp); + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg + & BMI_TX_FIFO_MIN_FILL_MASK) + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS; + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1) + * BMI_FIFO_UNITS; + + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = + DEFAULT_PORT_deqPrefetchOption; + p_FmPort->p_FmPortDriverParam->deqHighPriority = + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G : + DEFAULT_PORT_deqHighPriority_10G); + p_FmPort->p_FmPortDriverParam->deqByteCnt = + (uint16_t)( + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G : + DEFAULT_PORT_deqByteCnt_10G); break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_FmPort->p_FmPortDriverParam->errorsToDiscard = + DEFAULT_PORT_errorsToDiscard; +#if (DPAA_VERSION >= 11) + p_FmPort->p_FmPortDriverParam->noScatherGather = + DEFAULT_PORT_noScatherGather; +#endif /* (DPAA_VERSION >= 11) */ + case (e_FM_PORT_TYPE_OH_HOST_COMMAND): + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = + DEFAULT_PORT_deqPrefetchOption_HC; + p_FmPort->p_FmPortDriverParam->deqHighPriority = + DEFAULT_PORT_deqHighPriority_1G; + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; + p_FmPort->p_FmPortDriverParam->deqByteCnt = + DEFAULT_PORT_deqByteCnt_1G; + + tmpReg = + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp); + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) + && (p_FmPortParams->portId != FM_OH_PORT_ID)) + { + /* Overwrite HC defaults */ + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = + DEFAULT_PORT_fifoDeqPipelineDepth_OH; + } + +#ifndef FM_FRAME_END_PARAMS_FOR_OP + if (p_FmPort->fmRevInfo.majorRev < 6) + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported; +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */ + +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP + if (!((p_FmPort->fmRevInfo.majorRev == 4) || + (p_FmPort->fmRevInfo.majorRev >= 6))) + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported; +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ + break; + default: XX_Free(p_FmPort->p_FmPortDriverParam); XX_Free(p_FmPort); REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); return NULL; + } +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + if (p_FmPort->fmRevInfo.majorRev == 4) + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported; +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + + p_FmPort->imEn = p_FmPortParams->independentModeEnable; + + if (p_FmPort->imEn) + { + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = + DEFAULT_PORT_fifoDeqPipelineDepth_IM; + FmPortConfigIM(p_FmPort, p_FmPortParams); + } + else + { + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX): + case (e_FM_PORT_TYPE_RX_10G): + /* Initialize FM port parameters for initialization phase only */ + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, + &p_FmPortParams->specificParams.rxParams.extBufPools, + sizeof(t_FmExtPools)); + p_FmPort->p_FmPortDriverParam->errFqid = + p_FmPortParams->specificParams.rxParams.errFqid; + p_FmPort->p_FmPortDriverParam->dfltFqid = + p_FmPortParams->specificParams.rxParams.dfltFqid; + p_FmPort->p_FmPortDriverParam->liodnOffset = + p_FmPortParams->specificParams.rxParams.liodnOffset; + break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + case (e_FM_PORT_TYPE_TX): + case (e_FM_PORT_TYPE_TX_10G): + case (e_FM_PORT_TYPE_OH_HOST_COMMAND): + p_FmPort->p_FmPortDriverParam->errFqid = + p_FmPortParams->specificParams.nonRxParams.errFqid; + p_FmPort->p_FmPortDriverParam->deqSubPortal = + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel + & QMI_DEQ_CFG_SUBPORTAL_MASK); + p_FmPort->p_FmPortDriverParam->dfltFqid = + p_FmPortParams->specificParams.nonRxParams.dfltFqid; + break; + default: + XX_Free(p_FmPort->p_FmPortDriverParam); + XX_Free(p_FmPort); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + return NULL; } } memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_FmPort->name, "FM-%d-port-%s-%d", - FmGetId(p_FmPort->h_Fm), - ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || - (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? - "OH" : (p_FmPort->portType == e_FM_PORT_TYPE_RX ? - "1g-RX" : (p_FmPort->portType == e_FM_PORT_TYPE_TX ? - "1g-TX" : (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G ? - "10g-RX" : "10g-TX")))), - p_FmPort->portId) == 0) + if (Sprint( + p_FmPort->name, + "FM-%d-port-%s-%d", + FmGetId(p_FmPort->h_Fm), + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" : + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" : + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" : + (p_FmPort->portType + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" : + "10g-TX")))), + p_FmPort->portId) == 0) { XX_Free(p_FmPort->p_FmPortDriverParam); XX_Free(p_FmPort); @@ -2444,6 +2558,9 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) return p_FmPort; } +t_FmPort *rx_port = 0; +t_FmPort *tx_port = 0; + /**************************************************************************//** @Function FM_PORT_Init @@ -2452,137 +2569,183 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) @Param[in] h_FmPort - FM module descriptor @Return E_OK on success; Error code otherwise. -*//***************************************************************************/ + *//***************************************************************************/ t_Error FM_PORT_Init(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPortDriverParam *p_Params; - t_Error err = E_OK; - t_FmInterModulePortInitParams fmParams; - uint32_t minFifoSizeRequired = 0; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPortDriverParam *p_DriverParams; + t_Error errCode; + t_FmInterModulePortInitParams fmParams; + t_FmRevisionInfo revInfo; SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if ((err = BuildBufferStructure(p_FmPort)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); + errCode = FmSpBuildBufferStructure( + &p_FmPort->p_FmPortDriverParam->intContext, + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent, + &p_FmPort->p_FmPortDriverParam->bufMargins, + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset); + if (errCode != E_OK) + RETURN_ERROR(MAJOR, errCode, NO_MSG); +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) && + (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + { + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL; + if (!p_FmPort->fifoBufs.num) + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS; + p_FmPort->fifoBufs.num += 4*KILOBYTE; + } +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters); - p_Params = p_FmPort->p_FmPortDriverParam; + p_DriverParams = p_FmPort->p_FmPortDriverParam; - /* set memory map pointers */ - p_FmPort->p_FmPortQmiRegs = (t_FmPortQmiRegs *)UINT_TO_PTR(p_Params->baseAddr + QMI_PORT_REGS_OFFSET); - p_FmPort->p_FmPortBmiRegs = (u_FmPortBmiRegs *)UINT_TO_PTR(p_Params->baseAddr + BMI_PORT_REGS_OFFSET); - p_FmPort->p_FmPortPrsRegs = (t_FmPortPrsRegs *)UINT_TO_PTR(p_Params->baseAddr + PRS_PORT_REGS_OFFSET); + /* Set up flibs port structure */ + memset(&p_FmPort->port, 0, sizeof(struct fman_port)); + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType; + FM_GetRevision(p_FmPort->h_Fm, &revInfo); + p_FmPort->port.fm_rev_maj = revInfo.majorRev; + p_FmPort->port.fm_rev_min = revInfo.minorRev; + p_FmPort->port.bmi_regs = + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET); + p_FmPort->port.qmi_regs = + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET); + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8); + p_FmPort->port.im_en = p_FmPort->imEn; + p_FmPort->p_FmPortPrsRegs = + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET); - /* For O/H ports, check fifo size and update if necessary */ - if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - { - minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS); - if (p_FmPort->fifoBufs.num < minFifoSizeRequired) - { - p_FmPort->fifoBufs.num = minFifoSizeRequired; - DBG(WARNING, ("FIFO size enlarged to %d due to txFifoDeqPipelineDepth size", minFifoSizeRequired)); - } - } - - /* For Rx Ports, call the external Buffer routine which also checks fifo - size and updates it if necessary */ - if(((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) - && !p_FmPort->imEn) + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn) { + /* Call the external Buffer routine which also checks fifo + size and updates it if necessary */ /* define external buffer pools and pool depletion*/ - err = SetExtBufferPools(p_FmPort); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); + errCode = SetExtBufferPools(p_FmPort); + if (errCode) + RETURN_ERROR(MAJOR, errCode, NO_MSG); + /* check if the largest external buffer pool is large enough */ + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE + + p_DriverParams->bufMargins.endMargins + > p_FmPort->rxPoolsParams.largestBufSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize)); + } + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + { + { +#ifdef FM_NO_OP_OBSERVED_POOLS + t_FmRevisionInfo revInfo; + + FM_GetRevision(p_FmPort->h_Fm, &revInfo); + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion)) +#endif /* FM_NO_OP_OBSERVED_POOLS */ + { + /* define external buffer pools */ + errCode = SetExtBufferPools(p_FmPort); + if (errCode) + RETURN_ERROR(MAJOR, errCode, NO_MSG); + } + } } /************************************************************/ /* Call FM module routine for communicating parameters */ /************************************************************/ memset(&fmParams, 0, sizeof(fmParams)); - fmParams.hardwarePortId = p_FmPort->hardwarePortId; - fmParams.portType = (e_FmPortType)p_FmPort->portType; - fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; - fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra; - fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num; + fmParams.hardwarePortId = p_FmPort->hardwarePortId; + fmParams.portType = (e_FmPortType)p_FmPort->portType; + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra; + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num; fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra; - fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; - fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; - fmParams.independentMode = p_FmPort->imEn; - fmParams.liodnOffset = p_Params->liodnOffset; - fmParams.liodnBase = p_Params->liodnBase; - switch(p_FmPort->portType) + if (p_FmPort->fifoBufs.num) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + errCode = VerifySizeOfFifo(p_FmPort); + if (errCode != E_OK) + RETURN_ERROR(MAJOR, errCode, NO_MSG); } + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; + fmParams.independentMode = p_FmPort->imEn; + fmParams.liodnOffset = p_DriverParams->liodnOffset; + fmParams.liodnBase = p_DriverParams->liodnBase; + fmParams.deqPipelineDepth = + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; + fmParams.maxFrameLength = p_FmPort->maxFrameLength; +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) + { + if (!((p_FmPort->fmRevInfo.majorRev == 4) || + (p_FmPort->fmRevInfo.majorRev >= 6))) + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only + * for deq threshold calculation. + */ + fmParams.deqPipelineDepth = 2; + } +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ - err = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - p_FmPort->tasks.num = fmParams.numOfTasks; - p_FmPort->tasks.extra = fmParams.numOfExtraTasks; - p_FmPort->openDmas.num = fmParams.numOfOpenDmas; - p_FmPort->openDmas.extra = fmParams.numOfExtraOpenDmas; - p_FmPort->fifoBufs.num = fmParams.sizeOfFifo; - p_FmPort->fifoBufs.extra = fmParams.extraSizeOfFifo; + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); + if (errCode) + RETURN_ERROR(MAJOR, errCode, NO_MSG); /* get params for use in init */ - p_Params->fmMuramPhysBaseAddr = - (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) | - ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32)); + p_FmPort->fmMuramPhysBaseAddr = + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32)); + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm); - /**********************/ - /* Init BMI Registers */ - /**********************/ - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - err = BmiRxPortInit(p_FmPort); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - err = BmiTxPortInit(p_FmPort); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - err = BmiOhPortInit(p_FmPort); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - } - - /**********************/ - /* Init QMI Registers */ - /**********************/ - if (!p_FmPort->imEn && ((err = QmiInit(p_FmPort)) != E_OK)) - RETURN_ERROR(MAJOR, err, NO_MSG); - - if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) - RETURN_ERROR(MAJOR, err, NO_MSG); + errCode = InitLowLevelDriver(p_FmPort); + if (errCode != E_OK) + RETURN_ERROR(MAJOR, errCode, NO_MSG); FmPortDriverParamFree(p_FmPort); +#if (DPAA_VERSION >= 11) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + { + t_FmPcdCtrlParamsPage *p_ParamsPage; + + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, + (void**)&p_ParamsPage); + ASSERT_COND(p_ParamsPage); + + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON); +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + { + WRITE_UINT32( + p_ParamsPage->misc, + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN)); + WRITE_UINT32( + p_ParamsPage->discardMask, + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); + } +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */ +#ifdef FM_ERROR_VSP_NO_MATCH_SW006 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32( + p_ParamsPage->errorsDiscardMask, + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem))); + else + WRITE_UINT32( + p_ParamsPage->errorsDiscardMask, + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem))); +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ + } +#endif /* (DPAA_VERSION >= 11) */ + + if (p_FmPort->deepSleepVars.autoResMaxSizes) + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort); return E_OK; } @@ -2591,21 +2754,24 @@ t_Error FM_PORT_Init(t_Handle h_FmPort) @Description Frees all resources that were assigned to FM module. - Calling this routine invalidates the descriptor. + Calling this routine invalidates the descriptor. @Param[in] h_FmPort - FM module descriptor @Return E_OK on success; Error code otherwise. -*//***************************************************************************/ + *//***************************************************************************/ t_Error FM_PORT_Free(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmInterModulePortFreeParams fmParams; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmInterModulePortFreeParams fmParams; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - if(p_FmPort->pcdEngines) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first.")); + if (p_FmPort->pcdEngines) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first.")); if (p_FmPort->enabled) { @@ -2613,19 +2779,28 @@ t_Error FM_PORT_Free(t_Handle h_FmPort) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED")); } - FmPortDriverParamFree(p_FmPort); - if (p_FmPort->imEn) FmPortImFree(p_FmPort); + FmPortDriverParamFree(p_FmPort); + + memset(&fmParams, 0, sizeof(fmParams)); fmParams.hardwarePortId = p_FmPort->hardwarePortId; fmParams.portType = (e_FmPortType)p_FmPort->portType; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ + fmParams.deqPipelineDepth = + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; FmFreePortParams(p_FmPort->h_Fm, &fmParams); - + +#if (DPAA_VERSION >= 11) + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId) + != E_OK) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED")); + + if (p_FmPort->p_ParamsPage) + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage); +#endif /* (DPAA_VERSION >= 11) */ + if (p_FmPort->h_Spinlock) XX_FreeSpinlock(p_FmPort->h_Spinlock); @@ -2634,21 +2809,59 @@ t_Error FM_PORT_Free(t_Handle h_FmPort) return E_OK; } - /*************************************************/ /* API Advanced Init unit functions */ /*************************************************/ +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE; + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc)); + + return E_OK; +} + +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE; + return E_OK; +} + +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE; + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); + + return E_OK; +} + t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports")); - p_FmPort->p_FmPortDriverParam->deqHighPriority = highPri; + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri; return E_OK; } @@ -2659,50 +2872,52 @@ t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("not available for Rx ports")); - p_FmPort->p_FmPortDriverParam->deqType = deqType; + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type = + (enum fman_port_deq_type)deqType; return E_OK; } -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT -t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption) +t_Error FM_PORT_ConfigDeqPrefetchOption( + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); - p_FmPort->p_FmPortDriverParam->deqPrefetchOption = deqPrefetchOption; + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("not available for Rx ports")); + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt = + (enum fman_port_deq_prefetch)deqPrefetchOption; + return E_OK; } -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ -t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmPortBackupBmPools *p_BackupBmPools) +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, + t_FmBackupBmPools *p_BackupBmPools) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -#ifdef FM_NO_BACKUP_POOLS - t_FmRevisionInfo revInfo; -#endif /* FM_NO_BACKUP_POOLS */ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); -#ifdef FM_NO_BACKUP_POOLS - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev != 4) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigBackupPools")); -#endif /* FM_NO_BACKUP_POOLS */ - - p_FmPort->p_FmPortDriverParam->p_BackupBmPools = (t_FmPortBackupBmPools *)XX_Malloc(sizeof(t_FmPortBackupBmPools)); - if(!p_FmPort->p_FmPortDriverParam->p_BackupBmPools) + p_FmPort->p_FmPortDriverParam->p_BackupBmPools = + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); - memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmPortBackupBmPools)); + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, + sizeof(t_FmBackupBmPools)); return E_OK; } @@ -2713,171 +2928,120 @@ t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("not available for Rx ports")); - p_FmPort->p_FmPortDriverParam->deqByteCnt = deqByteCnt; + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt; return E_OK; } -t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, t_FmPortBufferPrefixContent *p_FmPortBufferPrefixContent) +t_Error FM_PORT_ConfigBufferPrefixContent( + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, p_FmPortBufferPrefixContent, sizeof(t_FmPortBufferPrefixContent)); - /* if dataAlign was not initialized by user, we return to driver's deafult */ + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent)); + /* if dataAlign was not initialized by user, we return to driver's default */ if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign) - p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign; + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = + DEFAULT_PORT_bufferPrefixContent_dataAlign; return E_OK; } -t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore) +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, + uint8_t checksumLastBytesIgnore) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx & Tx ports only")); - p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = cheksumLastBytesIgnore; + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore = + checksumLastBytesIgnore; return E_OK; } -t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd) +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, + uint8_t cutBytesFromEnd) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); - p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = cutBytesFromEnd; + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd; return E_OK; } -t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion *p_BufPoolDepletion) +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, + t_FmBufPoolDepletion *p_BufPoolDepletion) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; - memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmPortBufPoolDepletion)); + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, + sizeof(t_FmBufPoolDepletion)); return E_OK; } -t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion) +t_Error FM_PORT_ConfigObservedPoolDepletion( + t_Handle h_FmPort, + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only")); + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for OP ports only")); p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; - memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, &p_FmPortObservedBufPoolDepletion->poolDepletionParams, sizeof(t_FmPortBufPoolDepletion)); - memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, &p_FmPortObservedBufPoolDepletion->poolsParams, sizeof(t_FmPortExtPools)); + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, + &p_FmPortObservedBufPoolDepletion->poolDepletionParams, + sizeof(t_FmBufPoolDepletion)); + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, + &p_FmPortObservedBufPoolDepletion->poolsParams, + sizeof(t_FmExtPools)); return E_OK; } -t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortExtPools) +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only")); - memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmPortExtPools, sizeof(t_FmPortExtPools)); + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for OP ports only")); - return E_OK; -} - -t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); - - p_FmPort->p_FmPortDriverParam->rxFifoThreshold = fifoThreshold; - - return E_OK; -} - -t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); - - p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = priElevationLevel; - - return E_OK; -} - -t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); - - p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = minFillLevel; - - return E_OK; -} - -t_Error FM_PORT_ConfigTxFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); - if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for IM ports!")); - - p_FmPort->txFifoDeqPipelineDepth = deqPipelineDepth; - - return E_OK; -} - -t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); - - p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = fifoLowComfLevel; + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools, + sizeof(t_FmExtPools)); return E_OK; } @@ -2888,8 +3052,10 @@ t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Tx ports only")); p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE; @@ -2902,15 +3068,7 @@ t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDfltColor!")); - } -#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */ - p_FmPort->p_FmPortDriverParam->color = color; + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color; return E_OK; } @@ -2921,94 +3079,102 @@ t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -#ifdef FM_PORT_SYNC_ERRATA_FMAN6 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("port-sync!")); - } -#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */ - p_FmPort->p_FmPortDriverParam->syncReq = syncReq; + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("Not available for Tx ports")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq; return E_OK; } - t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType == e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Tx ports")); + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("Not available for Tx ports")); - p_FmPort->p_FmPortDriverParam->frmDiscardOverride = override; + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override; return E_OK; } -t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, + fmPortFrameErrSelect_t errs) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs; return E_OK; } -t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData) +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - p_FmPort->p_FmPortDriverParam->dmaSwapData = swapData; + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data = + (enum fman_port_dma_swap)swapData; return E_OK; } -t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intContextCacheAttr) +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, + e_FmDmaCacheOption intContextCacheAttr) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = intContextCacheAttr; + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on = + (bool)(intContextCacheAttr == e_FM_DMA_STASH); return E_OK; } -t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCacheAttr) +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, + e_FmDmaCacheOption headerCacheAttr) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = headerCacheAttr; + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on = + (bool)(headerCacheAttr == e_FM_DMA_STASH); return E_OK; } -t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache scatterGatherCacheAttr) +t_Error FM_PORT_ConfigDmaScatterGatherAttr( + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = scatterGatherCacheAttr; + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on = + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH); return E_OK; } @@ -3020,63 +3186,197 @@ t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize) SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for Tx ports")); + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("Not available for Tx ports")); - p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = optimize; + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize; return E_OK; } -t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool forwardReuse) +#if (DPAA_VERSION >= 11) +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + UNUSED(noScatherGather); + UNUSED(p_FmPort); + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather; + + return E_OK; +} +#endif /* (DPAA_VERSION >= 11) */ + +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, + bool forwardReuse) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse; return E_OK; } +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + p_FmPort->maxFrameLength = length; + + return E_OK; +} + +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE; + + return E_OK; +} +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ /****************************************************/ -/* PCD Advaced config API */ +/* Hidden-DEBUG Only API */ /****************************************************/ +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, + uint32_t minFillLevel) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Tx ports only")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel; + + return E_OK; +} + +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, + uint8_t deqPipelineDepth) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("Not available for Rx ports")); + + if (p_FmPort->imEn) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("Not available for IM ports!")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = + deqPipelineDepth; + + return E_OK; +} + +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, + uint32_t fifoLowComfLevel) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Tx ports only")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level = + fifoLowComfLevel; + + return E_OK; +} + +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold; + + return E_OK; +} + +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, + uint32_t priElevationLevel) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); + + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel; + + return E_OK; +} /****************************************************/ /* API Run-time Control unit functions */ /****************************************************/ -t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas) +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, + t_FmPortRsrc *p_NumOfOpenDmas) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && - (p_NumOfOpenDmas->extra)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); - } -#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ - - if((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS)); - if(p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); - err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfOpenDmas->num, (uint8_t)p_NumOfOpenDmas->extra, FALSE); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS)) + RETURN_ERROR( MAJOR, E_INVALID_VALUE, + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS)); + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, + (uint8_t*)&p_NumOfOpenDmas->num, + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc)); @@ -3085,33 +3385,30 @@ t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDma t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for host command port where number is always 1")); + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */ + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND); -#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && - (p_NumOfTasks->extra)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); - } -#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS)); + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); - if((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS)); - if(p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); - - err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfTasks->num, (uint8_t)p_NumOfTasks->extra, FALSE); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, + (uint8_t*)&p_NumOfTasks->num, + (uint8_t*)&p_NumOfTasks->extra, FALSE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); /* update driver's struct */ memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); @@ -3120,112 +3417,85 @@ t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err; - t_FmInterModulePortRxPoolsParams rxPoolsParams; - uint32_t minFifoSizeRequired; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && - (p_SizeOfFifo->extra)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); - } -#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ - if(!p_SizeOfFifo->num || (p_SizeOfFifo->num > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); - if(p_SizeOfFifo->num % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS)); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); + if (p_SizeOfFifo->num % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS)); + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { /* extra FIFO size (allowed only to Rx ports) */ - if(p_SizeOfFifo->extra % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS)); + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS)); } else - if(p_SizeOfFifo->extra) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No SizeOfFifo-extra for non Rx ports")); + if (p_SizeOfFifo->extra) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + (" No SizeOfFifo-extra for non Rx ports")); - /* For O/H ports, check fifo size and update if necessary */ - if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - { - minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS); - if (p_FmPort->fifoBufs.num < minFifoSizeRequired) - { - p_FmPort->fifoBufs.num = minFifoSizeRequired; - DBG(INFO, ("FIFO size enlarged to %d", minFifoSizeRequired)); - } - } - memcpy(&rxPoolsParams, &p_FmPort->rxPoolsParams, sizeof(rxPoolsParams)); - err = FmSetSizeOfFifo(p_FmPort->h_Fm, - p_FmPort->hardwarePortId, - p_FmPort->portType, - p_FmPort->imEn, - &p_SizeOfFifo->num, - p_SizeOfFifo->extra, - p_FmPort->txFifoDeqPipelineDepth, - &rxPoolsParams, - FALSE); - if(err) - RETURN_ERROR(MINOR, err, NO_MSG); - - /* update driver's structure AFTER the FM routine, as it may change by the FM. */ memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); + /* we do not change user's parameter */ + err = VerifySizeOfFifo(p_FmPort); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId, + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + return E_OK; } uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + 0); return p_FmPort->bufferOffsets.dataOffset; } uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + NULL); - if(p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) return NULL; return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset); } -#ifdef DEBUG -uint8_t * FM_PORT_GetBufferDebugInfo(t_Handle h_FmPort, char *p_Data) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - - SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); - - if(p_FmPort->bufferOffsets.debugOffset == ILLEGAL_BASE) - return NULL; - - return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.debugOffset); -} -#endif /* DEBUG */ - t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + NULL); - if(p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE) + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE) return NULL; return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset); @@ -3233,12 +3503,13 @@ t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data) uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + NULL); - if(p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE) + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE) return NULL; return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset); @@ -3246,12 +3517,13 @@ uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data) uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + NULL); - if(p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE) + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE) return NULL; return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset); @@ -3259,466 +3531,364 @@ uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data) t_Error FM_PORT_Disable(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiCfgReg = NULL; - volatile uint32_t *p_BmiStatusReg = NULL; - bool rxPort = FALSE; - int tries; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; - p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rst; - rxPort = TRUE; - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; - p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tst; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; - p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ost; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } - /* check if port is already disabled */ - if(!(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN)) - { - if (!rxPort && !p_FmPort->imEn) - { - if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN)) - /* port is disabled */ - return E_OK; - else - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's QMI is enabled but BMI disabled")); - } - /* port is disabled */ - return E_OK; - } - - /* Disable QMI */ - if (!rxPort && !p_FmPort->imEn) - { - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, - GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & ~QMI_PORT_CFG_EN); - /* wait for QMI to finish Handling dequeue tnums */ - tries=1000; - while ((GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pns) & QMI_PORT_STATUS_DEQ_FD_BSY) && - --tries) - XX_UDelay(1); - if (!tries) - RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name)); - } - - /* Disable BMI */ - WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) & ~BMI_PORT_CFG_EN); - if (p_FmPort->imEn) FmPortImDisable(p_FmPort); - tries=5000; - while ((GET_UINT32(*p_BmiStatusReg) & BMI_PORT_STATUS_BSY) && - --tries) - XX_UDelay(1); + err = fman_port_disable(&p_FmPort->port); + if (err == -EBUSY) + { + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down", + p_FmPort->name)); + } + else + if (err != 0) + { + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable")); + } - if (!tries) - RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name)); - - p_FmPort->enabled = 0; + p_FmPort->enabled = FALSE; return E_OK; } t_Error FM_PORT_Enable(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiCfgReg = NULL; - bool rxPort = FALSE; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; - rxPort = TRUE; - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } - - /* check if port is already enabled */ - if(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN) - { - if (!rxPort && !p_FmPort->imEn) - { - if(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN) - /* port is enabled */ - return E_OK; - else - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's BMI is enabled but QMI disabled")); - } - /* port is enabled */ - return E_OK; - } + /* Used by FM_PORT_Free routine as indication + if to disable port. Thus set it to TRUE prior + to enabling itself. This way if part of enable + process fails there will be still things + to disable during Free. For example, if BMI + enable succeeded but QMI failed, still BMI + needs to be disabled by Free. */ + p_FmPort->enabled = TRUE; if (p_FmPort->imEn) FmPortImEnable(p_FmPort); - /* Enable QMI */ - if (!rxPort && !p_FmPort->imEn) - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, - GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN); - - /* Enable BMI */ - WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | BMI_PORT_CFG_EN); - - p_FmPort->enabled = 1; + err = fman_port_enable(&p_FmPort->port); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable")); return E_OK; } t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpRateLimit, tmpRateLimitScale; - volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; - uint8_t factor, countUnitBit; - uint16_t baseGran; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint8_t factor, countUnitBit; + uint16_t baseGran; + struct fman_port_rate_limiter params; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || - (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only")); - - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; - p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; - baseGran = 16000; + case (e_FM_PORT_TYPE_TX_10G): + case (e_FM_PORT_TYPE_TX): + baseGran = BMI_RATE_LIMIT_GRAN_TX; + break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + baseGran = BMI_RATE_LIMIT_GRAN_OP; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; - p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; - baseGran = 10000; - break; default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Tx and Offline parsing ports only")); } - countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */ + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */ /* normally, we use 1 usec as the reference count */ factor = 1; /* if ratelimit is too small for a 1usec factor, multiply the factor */ - while (p_RateLimit->rateLimit < baseGran/factor) + while (p_RateLimit->rateLimit < baseGran / factor) { - if (countUnitBit==31) + if (countUnitBit == 31) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small")); countUnitBit++; factor <<= 1; } /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/ - if (p_RateLimit->rateLimit > ((uint32_t)baseGran * (1<<10) * (uint32_t)factor)) + if (p_RateLimit->rateLimit + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large")); - tmpRateLimit = (uint32_t)(p_RateLimit->rateLimit*factor/baseGran - 1); + if (!p_RateLimit->maxBurstSize + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE)); - if(!p_RateLimit->maxBurstSize || (p_RateLimit->maxBurstSize > MAX_BURST_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxBurstSize must be between 1K and %dk", MAX_BURST_SIZE)); + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); + params.high_burst_size_gran = FALSE; + params.burst_size = p_RateLimit->maxBurstSize; + params.rate = p_RateLimit->rateLimit; + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE; - tmpRateLimitScale = ((31 - (uint32_t)countUnitBit) << BMI_COUNT_RATE_UNIT_SHIFT) | BMI_RATE_LIMIT_EN; - - if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) - tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; - else + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) { #ifndef FM_NO_ADVANCED_RATE_LIMITER - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev == 4) + if ((p_FmPort->fmRevInfo.majorRev == 4) + || (p_FmPort->fmRevInfo.majorRev >= 6)) { - switch(p_RateLimit->rateLimitDivider) - { - case(e_FM_PORT_DUAL_RATE_LIMITER_NONE): - break; - case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2): - tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_2; - break; - case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4): - tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_4; - break; - case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8): - tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_8; - break; - default: - break; - } - tmpRateLimit |= BMI_RATE_LIMIT_BURST_SIZE_GRAN; + params.high_burst_size_gran = TRUE; } else #endif /* ! FM_NO_ADVANCED_RATE_LIMITER */ { - if(p_RateLimit->rateLimitDivider != e_FM_PORT_DUAL_RATE_LIMITER_NONE) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDualRateLimitScaleDown")); + if (p_RateLimit->rateLimitDivider + != e_FM_PORT_DUAL_RATE_LIMITER_NONE) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("FM_PORT_ConfigDualRateLimitScaleDown")); - if(p_RateLimit->maxBurstSize % 1000) + if (p_RateLimit->maxBurstSize % 1000) { - p_RateLimit->maxBurstSize = (uint16_t)((p_RateLimit->maxBurstSize/1000)+1); + p_RateLimit->maxBurstSize = + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1); DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000)); } else - p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize/1000); + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize + / 1000); } - tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; - + params.rate_factor = + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider; + params.burst_size = p_RateLimit->maxBurstSize; } - WRITE_UINT32(*p_RateLimitScaleReg, tmpRateLimitScale); - WRITE_UINT32(*p_RateLimitReg, tmpRateLimit); + + err = fman_port_set_rate_limiter(&p_FmPort->port, ¶ms); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); return E_OK; } t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || - (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only")); - - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; - p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; - p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } - - WRITE_UINT32(*p_RateLimitScaleReg, 0); - WRITE_UINT32(*p_RateLimitReg, 0); + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Tx and Offline parsing ports only")); + err = fman_port_delete_rate_limiter(&p_FmPort->port); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); return E_OK; } - -t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, + uint8_t wq) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpReg; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint32_t tmpReg; + uint32_t wqTmpReg; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - tmpReg = GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc); - if(enable) - tmpReg |= QMI_PORT_CFG_EN_COUNTERS ; - else - tmpReg &= ~QMI_PORT_CFG_EN_COUNTERS; + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("PFC mapping is available for Tx ports only")); - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, tmpReg); + if (prio > 7) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, + ("PFC priority (%d) is out of range (0-7)", prio)); + if (wq > 7) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, + ("WQ (%d) is out of range (0-7)", wq)); + + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]); + tmpReg &= ~(0xf << ((7 - prio) * 4)); + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4)); + tmpReg |= wqTmpReg; + + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0], + tmpReg); + + return E_OK; +} + +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); + + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable); return E_OK; } t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiPcReg = NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpc; - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpc; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opc; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } - - if(enable) - WRITE_UINT32(*p_BmiPcReg, BMI_COUNTERS_EN); - else - WRITE_UINT32(*p_BmiPcReg, 0); - + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode")); return E_OK; } -t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) +t_Error FM_PORT_SetPerformanceCountersParams( + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpReg; - volatile uint32_t *p_BmiPcpReg = NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + struct fman_port_perf_cnt_params params; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpcp; - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpcp; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opcp; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); - } - /* check parameters */ - if (!p_FmPortPerformanceCnt->taskCompVal || - (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.taskCompVal has to be in the range of 1 - %d (current value)!", - p_FmPort->tasks.num)); - if (!p_FmPortPerformanceCnt->dmaCompVal || - (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.dmaCompVal has to be in the range of 1 - %d (current value)!", - p_FmPort->openDmas.num)); - if (!p_FmPortPerformanceCnt->fifoCompVal || - (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.fifoCompVal has to be in the range of 256 - %d (current value)!", - p_FmPort->fifoBufs.num)); + if (!p_FmPortPerformanceCnt->taskCompVal + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num)); + if (!p_FmPortPerformanceCnt->dmaCompVal + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num)); + if (!p_FmPortPerformanceCnt->fifoCompVal + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num)); if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.fifoCompVal has to be divisible by %d", - BMI_FIFO_UNITS)); - switch(p_FmPort->portType) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS)); + + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - if (!p_FmPortPerformanceCnt->queueCompVal || - (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_RX_QUEUE_COMP)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", - MAX_PERFORMANCE_RX_QUEUE_COMP)); + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + if (!p_FmPortPerformanceCnt->queueCompVal + || (p_FmPortPerformanceCnt->queueCompVal + > MAX_PERFORMANCE_RX_QUEUE_COMP)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP)); break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - if (!p_FmPortPerformanceCnt->queueCompVal || - (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_TX_QUEUE_COMP)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", - MAX_PERFORMANCE_TX_QUEUE_COMP)); + case (e_FM_PORT_TYPE_TX_10G): + case (e_FM_PORT_TYPE_TX): + if (!p_FmPortPerformanceCnt->queueCompVal + || (p_FmPortPerformanceCnt->queueCompVal + > MAX_PERFORMANCE_TX_QUEUE_COMP)) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP)); break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + case (e_FM_PORT_TYPE_OH_HOST_COMMAND): if (p_FmPortPerformanceCnt->queueCompVal) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("performanceCnt.queueCompVal is not relevant for H/O ports.")); + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("performanceCnt.queueCompVal is not relevant for H/O ports.")); break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); } - tmpReg = 0; - tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->queueCompVal - 1) << BMI_PERFORMANCE_PORT_COMP_SHIFT); - tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->dmaCompVal- 1) << BMI_PERFORMANCE_DMA_COMP_SHIFT); - tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->fifoCompVal/BMI_FIFO_UNITS - 1) << BMI_PERFORMANCE_FIFO_COMP_SHIFT); - if ((p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && (p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND)) - tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->taskCompVal - 1) << BMI_PERFORMANCE_TASK_COMP_SHIFT); + params.task_val = p_FmPortPerformanceCnt->taskCompVal; + params.queue_val = p_FmPortPerformanceCnt->queueCompVal; + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal; + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal; - WRITE_UINT32(*p_BmiPcpReg, tmpReg); + err = fman_port_set_perf_cnt_params(&p_FmPort->port, ¶ms); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params")); return E_OK; } t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPortPerformanceCnt currParams, savedParams; - t_Error err; - bool underTest, failed = FALSE; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPortPerformanceCnt currParams, savedParams; + t_Error err; + bool underTest, failed = FALSE; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n", p_FmPort->portType, p_FmPort->portId); - currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; - if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || - (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) - currParams.queueCompVal = 0; + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) + currParams.queueCompVal = 0; else - currParams.queueCompVal = 1; - currParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num; - currParams.fifoCompVal = p_FmPort->fifoBufs.num; + currParams.queueCompVal = 1; + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; + currParams.fifoCompVal = p_FmPort->fifoBufs.num; FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); ClearPerfCnts(p_FmPort); - if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK) + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) + != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); XX_UDelay(1000000); FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) { - XX_Print ("Max num of defined port tasks (%d) utilized - Please enlarge\n",p_FmPort->tasks.num); + XX_Print( + "Max num of defined port tasks (%d) utilized - Please enlarge\n", + p_FmPort->tasks.num); failed = TRUE; } if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) { - XX_Print ("Max num of defined port openDmas (%d) utilized - Please enlarge\n",p_FmPort->openDmas.num); + XX_Print( + "Max num of defined port openDmas (%d) utilized - Please enlarge\n", + p_FmPort->openDmas.num); failed = TRUE; } if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) { - XX_Print ("Max size of defined port fifo (%d) utilized - Please enlarge\n",p_FmPort->fifoBufs.num*BMI_FIFO_UNITS); + XX_Print( + "Max size of defined port fifo (%d) utilized - Please enlarge\n", + p_FmPort->fifoBufs.num); failed = TRUE; } if (failed) - RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); memset(&savedParams, 0, sizeof(savedParams)); while (TRUE) @@ -3734,7 +3904,8 @@ t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) currParams.dmaCompVal--; underTest = TRUE; } - if ((currParams.fifoCompVal != BMI_FIFO_UNITS) && !savedParams.fifoCompVal) + if ((currParams.fifoCompVal != BMI_FIFO_UNITS) + && !savedParams.fifoCompVal) { currParams.fifoCompVal -= BMI_FIFO_UNITS; underTest = TRUE; @@ -3743,146 +3914,278 @@ t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) break; ClearPerfCnts(p_FmPort); - if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK) + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) + != E_OK) RETURN_ERROR(MAJOR, err, NO_MSG); FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); XX_UDelay(1000000); FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); - if (!savedParams.taskCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) - savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal+2); - if (!savedParams.dmaCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) - savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal+2); - if (!savedParams.fifoCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) - savedParams.fifoCompVal = currParams.fifoCompVal+2; + if (!savedParams.taskCompVal + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2); + if (!savedParams.dmaCompVal + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2); + if (!savedParams.fifoCompVal + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) + savedParams.fifoCompVal = currParams.fifoCompVal + + (2 * BMI_FIFO_UNITS); } XX_Print("best vals: tasks %d, dmas %d, fifos %d\n", - savedParams.taskCompVal, savedParams.dmaCompVal, savedParams.fifoCompVal); + savedParams.taskCompVal, savedParams.dmaCompVal, + savedParams.fifoCompVal); return E_OK; } t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpReg; - volatile uint32_t *p_BmiStcReg = NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(p_FmPort->portType) + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode")); + return E_OK; +} + +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + volatile uint32_t *p_ErrDiscard = NULL; + int err; + + UNUSED(p_ErrDiscard); + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask")); + +#ifdef FM_ERROR_VSP_NO_MATCH_SW006 + if (p_FmPort->fmRevInfo.majorRev >= 6) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rstc; - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tstc; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ostc; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); + t_FmPcdCtrlParamsPage *p_ParamsPage; + + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, + (void**)&p_ParamsPage); + ASSERT_COND(p_ParamsPage); + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_ErrDiscard = + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; + break; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_ErrDiscard = + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm; + break; + default: + RETURN_ERROR( + MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); + } + WRITE_UINT32(p_ParamsPage->errorsDiscardMask, + GET_UINT32(*p_ErrDiscard) | errs); } - - tmpReg = GET_UINT32(*p_BmiStcReg); - - if(enable) - tmpReg |= BMI_COUNTERS_EN; - else - tmpReg &= ~BMI_COUNTERS_EN; - - WRITE_UINT32(*p_BmiStcReg, tmpReg); +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ return E_OK; } -t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, + bool enable) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_ErrQReg, *p_ErrDiscard; - - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem; - p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem; - p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); - } - - if (GET_UINT32(*p_ErrDiscard) & errs) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Selectd Errors that were configured to cause frame discard.")); - - WRITE_UINT32(*p_ErrQReg, errs); - - return E_OK; -} - -t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpReg; - int i; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(poolIdp_FmPortDriverParam, E_INVALID_STATE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); - for(i=0 ; i< FM_PORT_MAX_NUM_OF_EXT_POOLS ; i++) - { - tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); - if ((uint8_t)((tmpReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT) == poolId) - { - if(enable) - tmpReg |= BMI_EXT_BUF_POOL_EN_COUNTER; - else - tmpReg &= ~BMI_EXT_BUF_POOL_EN_COUNTER; - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], tmpReg); - break; - } + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode")); + return E_OK; +} + +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){ + p_BmiStats->cntCycle = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); + /* fmbm_rccn */ + p_BmiStats->cntTaskUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); + /* fmbm_rtuc */ + p_BmiStats->cntQueueUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); + /* fmbm_rrquc */ + p_BmiStats->cntDmaUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); + /* fmbm_rduc */ + p_BmiStats->cntFifoUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); + /* fmbm_rfuc */ + p_BmiStats->cntRxPauseActivation = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION); + /* fmbm_rpac */ + p_BmiStats->cntFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); + /* fmbm_rfrc */ + p_BmiStats->cntDiscardFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); + /* fmbm_rfdc */ + p_BmiStats->cntDeallocBuf = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); + /* fmbm_rbdc */ + p_BmiStats->cntRxBadFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME); + /* fmbm_rfbc */ + p_BmiStats->cntRxLargeFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME); + /* fmbm_rlfc */ + p_BmiStats->cntRxFilterFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); + /* fmbm_rffc */ + p_BmiStats->cntRxListDmaErr = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); + /* fmbm_rfldec */ + p_BmiStats->cntRxOutOfBuffersDiscard = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); + /* fmbm_rodc */ + p_BmiStats->cntWredDiscard = 0; + p_BmiStats->cntLengthErr = 0; + p_BmiStats->cntUnsupportedFormat = 0; + } + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){ + p_BmiStats->cntCycle = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); + /* fmbm_tccn */ + p_BmiStats->cntTaskUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); + /* fmbm_ttuc */ + p_BmiStats->cntQueueUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); + /* fmbm_ttcquc */ + p_BmiStats->cntDmaUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); + /* fmbm_tduc */ + p_BmiStats->cntFifoUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); + /* fmbm_tfuc */ + p_BmiStats->cntRxPauseActivation = 0; + p_BmiStats->cntFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); + /* fmbm_tfrc */ + p_BmiStats->cntDiscardFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); + /* fmbm_tfdc */ + p_BmiStats->cntDeallocBuf = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); + /* fmbm_tbdc */ + p_BmiStats->cntRxBadFrame = 0; + p_BmiStats->cntRxLargeFrame = 0; + p_BmiStats->cntRxFilterFrame = 0; + p_BmiStats->cntRxListDmaErr = 0; + p_BmiStats->cntRxOutOfBuffersDiscard = 0; + p_BmiStats->cntWredDiscard = 0; + p_BmiStats->cntLengthErr = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); + /* fmbm_tfledc */ + p_BmiStats->cntUnsupportedFormat = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); + /* fmbm_tfufdc */ + } + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) { + p_BmiStats->cntCycle = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); + /* fmbm_occn */ + p_BmiStats->cntTaskUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); + /* fmbm_otuc */ + p_BmiStats->cntQueueUtil = 0; + p_BmiStats->cntDmaUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); + /* fmbm_oduc */ + p_BmiStats->cntFifoUtil = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); + /* fmbm_ofuc*/ + p_BmiStats->cntRxPauseActivation = 0; + p_BmiStats->cntFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); + /* fmbm_ofrc */ + p_BmiStats->cntDiscardFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); + /* fmbm_ofdc */ + p_BmiStats->cntDeallocBuf = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); + /* fmbm_obdc*/ + p_BmiStats->cntRxBadFrame = 0; + p_BmiStats->cntRxLargeFrame = 0; + p_BmiStats->cntRxFilterFrame = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); + /* fmbm_offc */ + p_BmiStats->cntRxListDmaErr = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); + /* fmbm_ofldec */ + p_BmiStats->cntRxOutOfBuffersDiscard = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); + /* fmbm_rodc */ + p_BmiStats->cntWredDiscard = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD); + /* fmbm_ofwdc */ + p_BmiStats->cntLengthErr = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); + /* fmbm_ofledc */ + p_BmiStats->cntUnsupportedFormat = + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); + /* fmbm_ofufdc */ } - if (i == FM_PORT_MAX_NUM_OF_EXT_POOLS) - RETURN_ERROR(MINOR, E_INVALID_VALUE,("poolId %d is not included in this ports pools", poolId)); - return E_OK; } uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - bool bmiCounter = FALSE; - volatile uint32_t *p_Reg; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + bool bmiCounter = FALSE; + enum fman_port_stats_counters statsType; + enum fman_port_perf_counters perfType; + enum fman_port_qmi_counters queueType; + bool isStats; + t_Error errCode; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_DEQ_TOTAL): - case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): - case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ): + case (e_FM_PORT_COUNTERS_DEQ_TOTAL): + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): /* check that counter is available for the port type */ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); + REPORT_ERROR(MINOR, E_INVALID_STATE, + ("Requested counter is not available for Rx ports")); return 0; } bmiCounter = FALSE; - case(e_FM_PORT_COUNTERS_ENQ_TOTAL): + break; + case (e_FM_PORT_COUNTERS_ENQ_TOTAL): bmiCounter = FALSE; break; default: /* BMI counters (or error - will be checked in BMI routine )*/ @@ -3890,88 +4193,83 @@ uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter) break; } - if(bmiCounter) + if (bmiCounter) { - switch(p_FmPort->portType) + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, + &perfType, &isStats); + if (errCode != E_OK) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - return 0; - } - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - return 0; - } - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - { - REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - return 0; - } - break; - default: - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); - return 0; + REPORT_ERROR(MINOR, errCode, NO_MSG); + return 0; } - return GET_UINT32(*p_Reg); + if (isStats) + return fman_port_get_stats_counter(&p_FmPort->port, statsType); + else + return fman_port_get_perf_counter(&p_FmPort->port, perfType); } else /* QMI counter */ { - /* check that counters are enabled */ - if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS)) + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) + & QMI_PORT_CFG_EN_COUNTERS)) + { REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); return 0; } /* Set counter */ - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_ENQ_TOTAL): - return GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc); - case(e_FM_PORT_COUNTERS_DEQ_TOTAL): - return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc); - case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): - return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc); - case(e_FM_PORT_COUNTERS_DEQ_CONFIRM): - return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc); + case (e_FM_PORT_COUNTERS_ENQ_TOTAL): + queueType = E_FMAN_PORT_ENQ_TOTAL; + break; + case (e_FM_PORT_COUNTERS_DEQ_TOTAL): + queueType = E_FMAN_PORT_DEQ_TOTAL; + break; + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): + queueType = E_FMAN_PORT_DEQ_FROM_DFLT; + break; + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): + queueType = E_FMAN_PORT_DEQ_CONFIRM; + break; default: REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); return 0; } + + return fman_port_get_qmi_counter(&p_FmPort->port, queueType); } return 0; } -t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, uint32_t value) +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, + uint32_t value) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - bool bmiCounter = FALSE; - volatile uint32_t *p_Reg; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + bool bmiCounter = FALSE; + enum fman_port_stats_counters statsType; + enum fman_port_perf_counters perfType; + enum fman_port_qmi_counters queueType; + bool isStats; + t_Error errCode; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_DEQ_TOTAL): - case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): - case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ): + case (e_FM_PORT_COUNTERS_DEQ_TOTAL): + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): /* check that counter is available for the port type */ - if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); - case(e_FM_PORT_COUNTERS_ENQ_TOTAL): + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + RETURN_ERROR( + MINOR, E_INVALID_STATE, + ("Requested counter is not available for Rx ports")); + case (e_FM_PORT_COUNTERS_ENQ_TOTAL): bmiCounter = FALSE; break; default: /* BMI counters (or error - will be checked in BMI routine )*/ @@ -3979,55 +4277,50 @@ t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, uint3 break; } - if(bmiCounter) + if (bmiCounter) { - switch(p_FmPort->portType) + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, + &perfType, &isStats); + if (errCode != E_OK) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - break; - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) - RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); + RETURN_ERROR(MINOR, errCode, NO_MSG); } - WRITE_UINT32(*p_Reg, value); + if (isStats) + fman_port_set_stats_counter(&p_FmPort->port, statsType, value); + else + fman_port_set_perf_counter(&p_FmPort->port, perfType, value); } else /* QMI counter */ { - /* check that counters are enabled */ - if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) + & QMI_PORT_CFG_EN_COUNTERS)) + { + RETURN_ERROR(MINOR, E_INVALID_STATE, + ("Requested counter was not enabled")); + } /* Set counter */ - switch(counter) + switch (counter) { - case(e_FM_PORT_COUNTERS_ENQ_TOTAL): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc, value); + case (e_FM_PORT_COUNTERS_ENQ_TOTAL): + queueType = E_FMAN_PORT_ENQ_TOTAL; break; - case(e_FM_PORT_COUNTERS_DEQ_TOTAL): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc, value); + case (e_FM_PORT_COUNTERS_DEQ_TOTAL): + queueType = E_FMAN_PORT_DEQ_TOTAL; break; - case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc, value); + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): + queueType = E_FMAN_PORT_DEQ_FROM_DFLT; break; - case(e_FM_PORT_COUNTERS_DEQ_CONFIRM): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc, value); + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): + queueType = E_FMAN_PORT_DEQ_CONFIRM; break; default: - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Requested counter is not available")); } + + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value); } return E_OK; @@ -4035,90 +4328,50 @@ t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, uint3 uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t extPoolReg; - uint8_t tmpPool; - uint8_t i; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); return 0; } - - for(i=0;ip_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); - if (extPoolReg & BMI_EXT_BUF_POOL_VALID) - { - tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); - if(tmpPool == poolId) - { - if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) - return GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i]); - else - { - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); - return 0; - } - } - } - } - REPORT_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); - return 0; + return fman_port_get_bpool_counter(&p_FmPort->port, poolId); } -t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value) +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, + uint32_t value) { - t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; - uint32_t extPoolReg; - uint8_t tmpPool; - uint8_t i; + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) + RETURN_ERROR( MINOR, E_INVALID_STATE, + ("Requested counter is not available for non-Rx ports")); - - for(i=0;ip_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); - if (extPoolReg & BMI_EXT_BUF_POOL_VALID) - { - tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); - if(tmpPool == poolId) - { - if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) - { - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], value); - return E_OK; - } - else - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); - } - } - } - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value); + return E_OK; } - bool FM_PORT_IsStalled(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err; - bool isStalled; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err; + bool isStalled; SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE); - SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, FALSE); + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, + FALSE); err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled); - if(err != E_OK) + if (err != E_OK) { - REPORT_ERROR(MINOR, err, NO_MSG); + REPORT_ERROR(MAJOR, err, NO_MSG); return TRUE; } return isStalled; @@ -4126,7 +4379,7 @@ bool FM_PORT_IsStalled(t_Handle h_FmPort) t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); @@ -4137,164 +4390,313 @@ t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort) t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - uint32_t tmpReg; + int err; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for Rx ports only")); - tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); if (l4Checksum) - tmpReg &= ~BMI_PORT_RFNE_FRWD_DCL4C; + err = fman_port_modify_rx_fd_bits( + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), + TRUE); else - tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C; - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, tmpReg); + err = fman_port_modify_rx_fd_bits( + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), + FALSE); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits")); return E_OK; } +/*****************************************************************************/ +/* API Run-time PCD Control unit functions */ +/*****************************************************************************/ -/* API Run-time PCD Control unit functions */ +#if (DPAA_VERSION >= 11) +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL; + uint32_t tmpReg = 0, tmp = 0; + uint16_t hwStoragePrflId; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE); + /*for numOfProfiles = 0 don't call this function*/ + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE); + /*dfltRelativeId should be in the range of numOfProfiles*/ + SANITY_CHECK_RETURN_ERROR( + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles, + E_INVALID_VALUE); + /*p_FmPort should be from Rx type or OP*/ + SANITY_CHECK_RETURN_ERROR( + ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), + E_INVALID_VALUE); + /*port should be disabled*/ + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE); + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/ + SANITY_CHECK_RETURN_ERROR( + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), + E_INVALID_VALUE); + /*should be called before SetPCD - this port should be without PCD*/ + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE); + + /*alloc window of VSPs for this port*/ + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType, + p_FmPort->portId, p_VSPParams->numOfProfiles); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + /*get absolute VSP ID for dfltRelative*/ + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType, + p_FmPort->portId, + p_VSPParams->dfltRelativeId, + &hwStoragePrflId); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/ + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiStorageProfileId = + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid); + p_BmiVspe = + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne); + + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); + + tmpReg = GET_UINT32(*p_BmiVspe); + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN); + + p_BmiStorageProfileId = + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid; + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp; + hwStoragePrflId = p_VSPParams->dfltRelativeId; + break; + + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME; + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, + tmpReg); + + p_BmiStorageProfileId = + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid; + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp; + tmp |= BMI_EBD_EN; + break; + + default: + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); + } + + p_FmPort->vspe = TRUE; + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId; + + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); + + tmpReg = GET_UINT32(*p_BmiVspe); + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp); + return E_OK; +} +#endif /* (DPAA_VERSION >= 11) */ t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); ASSERT_COND(p_FmPort->h_FmPcd); - if(numOfProfiles) + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) { - err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, numOfProfiles); - if(err) - RETURN_ERROR(MAJOR, err,NO_MSG); + DBG(TRACE, ("FM Port Try Lock - BUSY")); + return ERROR_CODE(E_BUSY); } + + if (numOfProfiles) + { + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, + p_FmPort->hardwarePortId, numOfProfiles); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + /* set the port handle within the PCD policer, even if no profiles defined */ FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId); + RELEASE_LOCK(p_FmPort->lock); + return E_OK; } t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; + + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); + return ERROR_CODE(E_BUSY); + } err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId); - if(err) - RETURN_ERROR(MAJOR, err,NO_MSG); + + RELEASE_LOCK(p_FmPort->lock); + + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + return E_OK; } -t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme) +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort, + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiHpnia = NULL; - uint32_t tmpReg; - uint8_t relativeSchemeId; - uint8_t physicalSchemeId; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + volatile uint32_t *p_BmiHpnia = NULL; + uint32_t tmpReg; + uint8_t relativeSchemeId; + uint8_t physicalSchemeId; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, + E_INVALID_STATE); - tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC)? NIA_KG_CC_EN:0); - switch(p_FmPort->portType) + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0); + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; break; default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); } if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) - return ERROR_CODE(E_BUSY); - /* if we want to change to direct scheme, we need to check that this scheme is valid */ - if(p_FmPcdKgScheme->direct) { - physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_FmPcdKgScheme->h_DirectScheme)-1); - /* check that this scheme is bound to this port */ - if(!(p_FmPort->schemesPerPortVector & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId)))) - { - RELEASE_LOCK(p_FmPort->lock); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with a scheme that is not bound to this port")); - } - - relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, physicalSchemeId); - if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) - { - RELEASE_LOCK(p_FmPort->lock); - RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("called with invalid Scheme ")); - } - - if(!FmPcdKgIsSchemeValidSw(p_FmPort->h_FmPcd, relativeSchemeId)) - { - RELEASE_LOCK(p_FmPort->lock); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with uninitialized Scheme ")); - } - - WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId); + DBG(TRACE, ("FM Port Try Lock - BUSY")); + return ERROR_CODE(E_BUSY); } - else /* change to indirect scheme */ + + /* if we want to change to direct scheme, we need to check that this scheme is valid */ + if (p_FmPcdKgScheme->direct) + { + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme); + /* check that this scheme is bound to this port */ + if (!(p_FmPort->schemesPerPortVector + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId)))) + { + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR( + MAJOR, E_INVALID_STATE, + ("called with a scheme that is not bound to this port")); + } + + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, + physicalSchemeId); + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) + { + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, + ("called with invalid Scheme ")); + } + + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme)) + { + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("called with uninitialized Scheme ")); + } + + WRITE_UINT32( + *p_BmiHpnia, + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId); + } + else + /* change to indirect scheme */ WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg); RELEASE_LOCK(p_FmPort->lock); return E_OK; } -t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile) +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort, + t_Handle h_Profile) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiNia; - volatile uint32_t *p_BmiHpnia; - uint32_t tmpReg; - uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1); + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + volatile uint32_t *p_BmiNia; + volatile uint32_t *p_BmiHpnia; + uint32_t tmpReg; + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR , E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR, + E_INVALID_STATE); - /* check relevancy of this routine - only when policer is used - directly after BMI or Parser */ - if((p_FmPort->pcdEngines & FM_PCD_KG) || (p_FmPort->pcdEngines & FM_PCD_CC)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR")); + /* check relevance of this routine - only when policer is used + directly after BMI or Parser */ + if ((p_FmPort->pcdEngines & FM_PCD_KG) + || (p_FmPort->pcdEngines & FM_PCD_CC)) + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR")); - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; - p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; - p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; tmpReg = 0; break; default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); } if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); - if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) + } + + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) { RELEASE_LOCK(p_FmPort->lock); RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile")); } - tmpReg = (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId); + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId); - if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ { /* update BMI HPNIA */ WRITE_UINT32(*p_BmiHpnia, tmpReg); @@ -4305,107 +4707,133 @@ t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_P tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK); /* update BMI NIA */ WRITE_UINT32(*p_BmiNia, tmpReg); - } - RELEASE_LOCK(p_FmPort->lock); + }RELEASE_LOCK(p_FmPort->lock); return E_OK; } - -t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree) +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; - volatile uint32_t *p_BmiCcBase=NULL; - volatile uint32_t *p_BmiNia=NULL; - uint32_t ccTreePhysOffset; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; + volatile uint32_t *p_BmiCcBase = NULL; + volatile uint32_t *p_BmiNia = NULL; + uint32_t ccTreePhysOffset; - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independent mode ports only")); /* get PCD registers pointers */ - switch(p_FmPort->portType) + switch (p_FmPort->portType) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; break; default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); } /* check that current NIA is BMI to BMI */ - if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("may be called only for ports in BMI-to-BMI state.")); -/*TODO - to take care of changes due to previous tree. Maybe in the previous tree where chnged pndn, pnen ... - it has to be returned to the default state - initially*/ - - p_FmPort->requiredAction = 0; - - if(p_FmPort->pcdEngines & FM_PCD_CC) + if (p_FmPort->pcdEngines & FM_PCD_CC) { - switch(p_FmPort->portType) + if (p_FmPort->h_IpReassemblyManip) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL, + p_FmPort->h_IpReassemblyManip, FALSE); + if (err != E_OK) + { + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + else + if (p_FmPort->h_CapwapReassemblyManip) + { + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL, + p_FmPort->h_CapwapReassemblyManip, + FALSE); + if (err != E_OK) + { + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + switch (p_FmPort->portType) + { + case (e_FM_PORT_TYPE_RX_10G): + case (e_FM_PORT_TYPE_RX): + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb; + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; break; default: RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); } if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); - err = FmPcdCcBindTree(p_FmPort->h_FmPcd, h_CcTree, &ccTreePhysOffset, h_FmPort); - if(err) + } + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree, + &ccTreePhysOffset, h_FmPort); + if (err) { RELEASE_LOCK(p_FmPort->lock); - RETURN_ERROR(MINOR, err, NO_MSG); - } - WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); + RETURN_ERROR(MAJOR, err, NO_MSG); + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); p_FmPort->ccTreeId = h_CcTree; RELEASE_LOCK(p_FmPort->lock); } else - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Coarse CLassification not defined for this port.")); + RETURN_ERROR( MAJOR, E_INVALID_STATE, + ("Coarse Classification not defined for this port.")); return E_OK; } t_Error FM_PORT_AttachPCD(t_Handle h_FmPort) { - - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independent mode ports only")); - /* TODO - may add here checks for: - SP (or in sw: schemes) - CPP (or in sw clsPlan) - Parser enabled and configured(?) - Tree(?) - Profile - only if direct. - Scheme - only if direct - */ + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); - err = FmPortAttachPCD(h_FmPort); + } + + if (p_FmPort->h_ReassemblyTree) + p_FmPort->pcdEngines |= FM_PCD_CC; + + err = AttachPCD(h_FmPort); RELEASE_LOCK(p_FmPort->lock); return err; @@ -4413,124 +4841,436 @@ t_Error FM_PORT_AttachPCD(t_Handle h_FmPort) t_Error FM_PORT_DetachPCD(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiNia=NULL; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independent mode ports only")); - /* get PCD registers pointers */ - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); - } - - WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); - -/*TODO - not atomic - it seems that port has to be disabled*/ - if(p_FmPort->requiredAction & UPDATE_NIA_PNEN) - { - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); - break; - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - case(e_FM_PORT_TYPE_RX): - case(e_FM_PORT_TYPE_RX_10G): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); - } - } - - if(p_FmPort->requiredAction & UPDATE_NIA_PNDN) - { - switch(p_FmPort->portType) - { - case(e_FM_PORT_TYPE_TX_10G): - case(e_FM_PORT_TYPE_TX): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); - break; - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); - } - } - - - if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) - if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2)!= E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - return E_OK; -} - -t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) -{ - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPcdKgInterModuleBindPortToSchemes schemeBind; - t_Error err = E_OK; - uint8_t i; - - SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - - if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independent mode ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); - p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); - ASSERT_COND(p_FmPort->h_FmPcd); + } - err = SetPcd( h_FmPort, p_PcdParams); - if(err) + err = DetachPCD(h_FmPort); + if (err != E_OK) { RELEASE_LOCK(p_FmPort->lock); RETURN_ERROR(MAJOR, err, NO_MSG); } - if(p_FmPort->pcdEngines & FM_PCD_KG) - { - schemeBind.netEnvId = p_FmPort->netEnvId; - schemeBind.hardwarePortId = p_FmPort->hardwarePortId; - schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; - schemeBind.useClsPlan = p_FmPort->useClsPlan; - for(i = 0;ip_KgParams->h_Schemes[i])-1); + if (p_FmPort->h_ReassemblyTree) + p_FmPort->pcdEngines &= ~FM_PCD_CC; + RELEASE_LOCK(p_FmPort->lock); - err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); - if(err) + return E_OK; +} + +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams; + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams; + t_FmPortPcdCcParams fmPortPcdCcParams; + t_FmPortGetSetCcParams fmPortGetSetCcParams; + + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER); + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); + + if (p_FmPort->imEn) + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independent mode ports only")); + + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); + + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); + return ERROR_CODE(E_BUSY); + } + + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); + ASSERT_COND(p_FmPort->h_FmPcd); + + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree) + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, + ("Tree handle must be given if CC is required")); + + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams)); + p_PcdParams = &modifiedPcdParams; + if ((p_PcdParams->h_IpReassemblyManip) +#if (DPAA_VERSION >= 11) + || (p_PcdParams->h_CapwapReassemblyManip) +#endif /* (DPAA_VERSION >= 11) */ + ) + { + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) + && (p_PcdParams->pcdSupport + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC) + && (p_PcdParams->pcdSupport + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR) + && (p_PcdParams->pcdSupport + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)) { - DeletePcd(p_FmPort); RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR( MAJOR, E_INVALID_STATE, + ("pcdSupport must have KG for supporting Reassembly")); + } + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip; +#if (DPAA_VERSION >= 11) + if ((p_PcdParams->h_IpReassemblyManip) + && (p_PcdParams->h_CapwapReassemblyManip)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("Either IP-R or CAPWAP-R is allowed")); + if ((p_PcdParams->h_CapwapReassemblyManip) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("CAPWAP-R is allowed only on offline-port")); + if (p_PcdParams->h_CapwapReassemblyManip) + p_FmPort->h_CapwapReassemblyManip = + p_PcdParams->h_CapwapReassemblyManip; +#endif /* (DPAA_VERSION >= 11) */ + + if (!p_PcdParams->p_CcParams) + { + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) + || (p_PcdParams->pcdSupport + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))) + { + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR( + MAJOR, + E_INVALID_STATE, + ("PCD initialization structure is not consistent with pcdSupport")); + } + + /* No user-tree, need to build internal tree */ + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc( + sizeof(t_FmPcdCcTreeParams)); + if (!p_FmPcdCcTreeParams) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams")); + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams)); + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv; + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild( + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams); + + if (!p_FmPort->h_ReassemblyTree) + { + RELEASE_LOCK(p_FmPort->lock); + XX_Free(p_FmPcdCcTreeParams); + RETURN_ERROR( MAJOR, E_INVALID_HANDLE, + ("FM_PCD_CcBuildTree for Reassembly failed")); + } + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) + p_PcdParams->pcdSupport = + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC; + else + p_PcdParams->pcdSupport = + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR; + + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams)); + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree; + p_PcdParams->p_CcParams = &fmPortPcdCcParams; + XX_Free(p_FmPcdCcTreeParams); + } + + if (p_FmPort->h_IpReassemblyManip) + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, + p_PcdParams->p_CcParams->h_CcTree, + p_PcdParams->h_NetEnv, + p_FmPort->h_IpReassemblyManip, TRUE); +#if (DPAA_VERSION >= 11) + else + if (p_FmPort->h_CapwapReassemblyManip) + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, + p_PcdParams->p_CcParams->h_CcTree, + p_PcdParams->h_NetEnv, + p_FmPort->h_CapwapReassemblyManip, + TRUE); +#endif /* (DPAA_VERSION >= 11) */ + + if (err != E_OK) + { + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); RETURN_ERROR(MAJOR, err, NO_MSG); } } - if ((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->includeInPrsStatistics)) - FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, TRUE); + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) + { + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + DBG(TRACE, ("Try LockAll - BUSY")); + return ERROR_CODE(E_BUSY); + } + + err = SetPcd(h_FmPort, p_PcdParams); + if (err) + { + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + } + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if ((p_FmPort->pcdEngines & FM_PCD_PRS) + && (p_PcdParams->p_PrsParams->includeInPrsStatistics)) + { + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, + p_FmPort->hardwarePortId, TRUE); + if (err) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + } + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + p_FmPort->includeInPrsStatistics = TRUE; + } FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); - err = FmPortAttachPCD(h_FmPort); + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) + { + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); + + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + { +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 + if ((p_FmPort->fmRevInfo.majorRev < 6) && + (p_FmPort->pcdEngines & FM_PCD_KG)) + { + int i; + for (i = 0; ip_KgParams->numOfSchemes; i++) + /* The following function must be locked */ + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, + p_PcdParams->p_KgParams->h_Schemes[i], + UPDATE_KG_NIA_CC_WA, + 0); + } +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ + +#if (DPAA_VERSION >= 11) + { + t_FmPcdCtrlParamsPage *p_ParamsPage; + + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, + (void**)&p_ParamsPage); + ASSERT_COND(p_ParamsPage); + WRITE_UINT32(p_ParamsPage->postBmiFetchNia, + p_FmPort->savedBmiNia); + } +#endif /* (DPAA_VERSION >= 11) */ + + /* Set post-bmi-fetch nia */ + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK; + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH + | NIA_ENG_FM_CTL); + + /* Set pre-bmi-fetch nia */ + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; +#if (DPAA_VERSION >= 11) + fmPortGetSetCcParams.setCcParams.nia = + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL); +#else + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL); +#endif /* (DPAA_VERSION >= 11) */ + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams)) + != E_OK) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + } + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + + /* Set pop-to-next-step nia */ +#if (DPAA_VERSION == 10) + if (p_FmPort->fmRevInfo.majorRev < 6) + { + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; + } + else + { +#endif /* (DPAA_VERSION == 10) */ + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE; +#if (DPAA_VERSION == 10) + } +#endif /* (DPAA_VERSION == 10) */ + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) + != E_OK) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /* Set post-bmi-prepare-to-enq nia */ + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ + | NIA_ENG_FM_CTL); + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) + != E_OK) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if ((p_FmPort->h_IpReassemblyManip) + || (p_FmPort->h_CapwapReassemblyManip)) + { +#if (DPAA_VERSION == 10) + if (p_FmPort->fmRevInfo.majorRev < 6) + { + /* Overwrite post-bmi-prepare-to-enq nia */ + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR); + fmPortGetSetCcParams.setCcParams.overwrite = TRUE; + } + else + { +#endif /* (DPAA_VERSION == 10) */ + /* Set the ORR bit (for order-restoration) */ + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE; + fmPortGetSetCcParams.setCcParams.nia = + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR; +#if (DPAA_VERSION == 10) + } +#endif /* (DPAA_VERSION == 10) */ + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) + != E_OK) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + } + } + else + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + +#if (DPAA_VERSION >= 11) + { + t_FmPcdCtrlParamsPage *p_ParamsPage; + + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); + + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE; + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP + | NIA_ENG_FM_CTL; + else + fmPortGetSetCcParams.setCcParams.nia = + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL; + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) + != E_OK) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, + (void**)&p_ParamsPage); + ASSERT_COND(p_ParamsPage); + + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) + WRITE_UINT32( + p_ParamsPage->misc, + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN); + + if ((p_FmPort->h_IpReassemblyManip) + || (p_FmPort->h_CapwapReassemblyManip)) + { + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) + WRITE_UINT32( + p_ParamsPage->discardMask, + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); + else + WRITE_UINT32( + p_ParamsPage->discardMask, + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm)); + } +#ifdef FM_ERROR_VSP_NO_MATCH_SW006 + if (p_FmPort->vspe) + WRITE_UINT32( + p_ParamsPage->misc, + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK)); +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ + } +#endif /* (DPAA_VERSION >= 11) */ + + err = AttachPCD(h_FmPort); + if (err) + { + DeletePcd(p_FmPort); + if (p_FmPort->h_ReassemblyTree) + { + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + RELEASE_LOCK(p_FmPort->lock); return err; @@ -4538,21 +5278,30 @@ t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) t_Error FM_PORT_DeletePCD(t_Handle h_FmPort) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPcdKgInterModuleBindPortToSchemes schemeBind; - t_Error err = E_OK; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_Error err = E_OK; SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); if (p_FmPort->imEn) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, + ("available for non-independant mode ports only")); + + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR( MAJOR, E_INVALID_OPERATION, + ("available for Rx and offline parsing ports only")); if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); + } - err = FM_PORT_DetachPCD(h_FmPort); - if(err) + err = DetachPCD(h_FmPort); + if (err) { RELEASE_LOCK(p_FmPort->lock); RETURN_ERROR(MAJOR, err, NO_MSG); @@ -4561,86 +5310,124 @@ t_Error FM_PORT_DeletePCD(t_Handle h_FmPort) FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); /* we do it anyway, instead of checking if included */ - if (FmIsMaster(p_FmPort->h_Fm) && - (p_FmPort->pcdEngines & FM_PCD_PRS)) - FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, FALSE); - - if(p_FmPort->pcdEngines & FM_PCD_KG) + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics) { - /* unbind all schemes */ - p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, &schemeBind); + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, + p_FmPort->hardwarePortId, FALSE); + p_FmPort->includeInPrsStatistics = FALSE; + } - err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); - if(err) + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) + { + RELEASE_LOCK(p_FmPort->lock); + DBG(TRACE, ("Try LockAll - BUSY")); + return ERROR_CODE(E_BUSY); + } + + err = DeletePcd(h_FmPort); + FmPcdLockUnlockAll(p_FmPort->h_FmPcd); + if (err) + { + RELEASE_LOCK(p_FmPort->lock); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + if (p_FmPort->h_ReassemblyTree) + { + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); + if (err) { RELEASE_LOCK(p_FmPort->lock); RETURN_ERROR(MAJOR, err, NO_MSG); } - } - - err = DeletePcd(h_FmPort); - RELEASE_LOCK(p_FmPort->lock); + p_FmPort->h_ReassemblyTree = NULL; + }RELEASE_LOCK(p_FmPort->lock); return err; } -t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme) +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort, + t_FmPcdPortSchemesParams *p_PortScheme) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPcdKgInterModuleBindPortToSchemes schemeBind; - t_Error err = E_OK; - uint32_t tmpScmVec=0; - int i; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPcdKgInterModuleBindPortToSchemes schemeBind; + t_Error err = E_OK; + uint32_t tmpScmVec = 0; + int i; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, + E_INVALID_STATE); schemeBind.netEnvId = p_FmPort->netEnvId; schemeBind.hardwarePortId = p_FmPort->hardwarePortId; schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; schemeBind.useClsPlan = p_FmPort->useClsPlan; - for (i=0; ih_Schemes[i])-1); + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( + p_PortScheme->h_Schemes[i]); /* build vector */ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); } if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); + } + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); if (err == E_OK) p_FmPort->schemesPerPortVector |= tmpScmVec; + +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) && + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && + (p_FmPort->fmRevInfo.majorRev < 6)) + { + for (i=0; inumOfSchemes; i++) + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0); + } +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ + RELEASE_LOCK(p_FmPort->lock); return err; } -t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme) +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort, + t_FmPcdPortSchemesParams *p_PortScheme) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_FmPcdKgInterModuleBindPortToSchemes schemeBind; - t_Error err = E_OK; - uint32_t tmpScmVec=0; - int i; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + t_FmPcdKgInterModuleBindPortToSchemes schemeBind; + t_Error err = E_OK; + uint32_t tmpScmVec = 0; + int i; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, + E_INVALID_STATE); schemeBind.netEnvId = p_FmPort->netEnvId; schemeBind.hardwarePortId = p_FmPort->hardwarePortId; schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; - for (i=0; ih_Schemes[i])-1); + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( + p_PortScheme->h_Schemes[i]); /* build vector */ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); } if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) + { + DBG(TRACE, ("FM Port Try Lock - BUSY")); return ERROR_CODE(E_BUSY); + } + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); if (err == E_OK) p_FmPort->schemesPerPortVector &= ~tmpScmVec; @@ -4649,412 +5436,1003 @@ t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams return err; } -t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart) +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, + t_FmPortCongestionGrps *p_CongestionGrps) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - volatile uint32_t *p_BmiPrsStartOffset = NULL; - volatile uint32_t *p_BmiNia = NULL; - uint32_t tmpReg; - uint8_t hdrNum; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS]; + uint8_t mod, index; + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; + int err; +#if (DPAA_VERSION >= 11) + int j; +#endif /* (DPAA_VERSION >= 11) */ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PRS , E_INVALID_STATE); - switch(p_FmPort->portType) + /* un-necessary check of the indexes; probably will be needed in the future when there + will be more CGs available .... + for (i=0; inumOfCongestionGrpsToConsider; i++) + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!")); + */ + +#ifdef FM_NO_OP_OBSERVED_CGS + if ((p_FmPort->fmRevInfo.majorRev != 4) && + (p_FmPort->fmRevInfo.majorRev < 6)) { - case(e_FM_PORT_TYPE_RX_10G): - case(e_FM_PORT_TYPE_RX): - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; - tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; - break; - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; - p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; - tmpReg = 0; - break; - default: - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && + (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); + } + else +#endif /* FM_NO_OP_OBSERVED_CGS */ + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("Available for Rx & OP ports only")); + + /* Prepare groups map array */ + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) + { + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); + if (p_FmPort->fmRevInfo.majorRev != 4) + grpsMap[7 - index] |= (uint32_t)(1 << mod); + else + grpsMap[0] |= (uint32_t)(1 << mod); } - /* check that current NIA is BMI to BMI */ - if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) - RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); + memset(&priorityTmpArray, 0, + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t)); - if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) - return ERROR_CODE(E_BUSY); - /* set the first header */ - GET_PRS_HDR_NUM(hdrNum, p_FmPcdPrsStart->firstPrsHdr); - if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) { - RELEASE_LOCK(p_FmPort->lock); - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); +#if (DPAA_VERSION >= 11) + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++) + if (p_CongestionGrps->pfcPrioritiesEn[i][j]) + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |= + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1)); +#endif /* (DPAA_VERSION >= 11) */ } - WRITE_UINT32(*p_BmiNia, (uint32_t)(NIA_ENG_PRS | (uint32_t)hdrNum | tmpReg)); - /* set start parsing offset */ - WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)(p_FmPcdPrsStart->parsingOffset + p_FmPort->internalBufferOffset)); - RELEASE_LOCK(p_FmPort->lock); +#if (DPAA_VERSION >= 11) + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++) + { + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i, + priorityTmpArray[i]); + if (err) + return err; + } +#endif /* (DPAA_VERSION >= 11) */ + + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps")); return E_OK; } -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_PORT_DumpRegs(t_Handle h_FmPort) +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, + t_FmPortCongestionGrps *p_CongestionGrps) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - t_Error err = E_OK; - char arr[30]; - uint8_t flag; - int i=0; + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + uint8_t mod, index; + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; + int err; - DECLARE_DUMP; + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortQmiRegs, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortBmiRegs, E_INVALID_HANDLE); - - switch (p_FmPort->portType) { - case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): - strcpy(arr, "PORT_TYPE_OFFLINE_PARSING"); - flag = 0; - break; - case (e_FM_PORT_TYPE_OH_HOST_COMMAND): - strcpy(arr, "PORT_TYPE_HOST_COMMAND"); - flag = 0; - break; - case (e_FM_PORT_TYPE_RX): - strcpy(arr, "PORT_TYPE_RX"); - flag = 1; - break; - case (e_FM_PORT_TYPE_RX_10G): - strcpy(arr, "PORT_TYPE_RX_10G"); - flag = 1; - break; - case (e_FM_PORT_TYPE_TX): - strcpy(arr, "PORT_TYPE_TX"); - flag = 2; - break; - case (e_FM_PORT_TYPE_TX_10G): - strcpy(arr, "PORT_TYPE_TX_10G"); - flag = 2; - break; - default: - return ERROR_CODE(E_INVALID_VALUE); +#ifdef FM_NO_OP_OBSERVED_CGS + t_FmRevisionInfo revInfo; + + FM_GetRevision(p_FmPort->h_Fm, &revInfo); + if (revInfo.majorRev != 4) + { + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && + (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); + } + else +#endif /* FM_NO_OP_OBSERVED_CGS */ + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) + && (p_FmPort->portType != e_FM_PORT_TYPE_RX) + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("Available for Rx & OP ports only")); } - DUMP_TITLE(UINT_TO_PTR(p_FmPort->hardwarePortId), ("PortId for %s %d", arr, p_FmPort->portId )); - DUMP_TITLE(p_FmPort->p_FmPortBmiRegs, ("Bmi Port Regs")); - - err = FmDumpPortRegs(p_FmPort->h_Fm, p_FmPort->hardwarePortId); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - switch(flag) + /* Prepare groups map array */ + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) { - case(0): + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); + if (p_FmPort->fmRevInfo.majorRev != 4) + grpsMap[7 - index] |= (uint32_t)(1 << mod); + else + grpsMap[0] |= (uint32_t)(1 << mod); + } - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocfg); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ost); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oda); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofca); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofpne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opso); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occb); +#if (DPAA_VERSION >= 11) + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) + { + t_Error err = FmSetCongestionGroupPFCpriority( + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i], + 0); + if (err) + return err; + } +#endif /* (DPAA_VERSION >= 11) */ - DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai), ("fmbm_oprai")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap); + if (err != 0) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("fman_port_remove_congestion_grps")); + return E_OK; +} + +#if (DPAA_VERSION >= 11) +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, + uint32_t *p_Ipv4OptionsCount) +{ + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; + + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR( + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING), + E_INVALID_VALUE); + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER); + + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter); + + return E_OK; +} +#endif /* (DPAA_VERSION >= 11) */ + +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, + t_FmPortDsarTablesSizes *params) +{ + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc( + sizeof(struct t_FmPortDsarTablesSizes)); + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params, + sizeof(struct t_FmPortDsarTablesSizes)); + return E_OK; +} + +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort) +{ + uint32_t *param_page; + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes; + t_ArCommonDesc *ArCommonDescPtr; + uint32_t size = sizeof(t_ArCommonDesc); + // ARP + // should put here if (params->max_num_of_arp_entries)? + size = ROUND_UP(size,4); + size += sizeof(t_DsarArpDescriptor); + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries; + size += sizeof(t_DsarArpStatistics); + //ICMPV4 + size = ROUND_UP(size,4); + size += sizeof(t_DsarIcmpV4Descriptor); + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries; + size += sizeof(t_DsarIcmpV4Statistics); + //ICMPV6 + size = ROUND_UP(size,4); + size += sizeof(t_DsarIcmpV6Descriptor); + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries; + size += sizeof(t_DsarIcmpV6Statistics); + //ND + size = ROUND_UP(size,4); + size += sizeof(t_DsarNdDescriptor); + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries; + size += sizeof(t_DsarIcmpV6Statistics); + //SNMP + size = ROUND_UP(size,4); + size += sizeof(t_DsarSnmpDescriptor); + size += sizeof(t_DsarSnmpIpv4AddrTblEntry) + * params->maxNumOfSnmpIPV4Entries; + size += sizeof(t_DsarSnmpIpv6AddrTblEntry) + * params->maxNumOfSnmpIPV6Entries; + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries; + size += params->maxNumOfSnmpOidChar; + size += sizeof(t_DsarIcmpV6Statistics); + //filters + size = ROUND_UP(size,4); + size += params->maxNumOfIpProtFiltering; + size = ROUND_UP(size,4); + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry); + size = ROUND_UP(size,4); + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry); + + // add here for more protocols + + // statistics + size = ROUND_UP(size,4); + size += sizeof(t_ArStatistics); + + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10); + + param_page = + XX_PhysToVirt( + p_FmPort->fmMuramPhysBaseAddr + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); + WRITE_UINT32( + *param_page, + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr)); + return E_OK; +} + +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx) +{ + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; + return p_FmPort->deepSleepVars.autoResMaxSizes; +} + +struct arOffsets +{ + uint32_t arp; + uint32_t nd; + uint32_t icmpv4; + uint32_t icmpv6; + uint32_t snmp; + uint32_t stats; + uint32_t filtIp; + uint32_t filtUdp; + uint32_t filtTcp; +}; + +static uint32_t AR_ComputeOffsets(struct arOffsets* of, + struct t_FmPortDsarParams *params, + t_FmPort *p_FmPort) +{ + uint32_t size = sizeof(t_ArCommonDesc); + // ARP + if (params->p_AutoResArpInfo) + { + size = ROUND_UP(size,4); + of->arp = size; + size += sizeof(t_DsarArpDescriptor); + size += sizeof(t_DsarArpBindingEntry) + * params->p_AutoResArpInfo->tableSize; + size += sizeof(t_DsarArpStatistics); + } + // ICMPV4 + if (params->p_AutoResEchoIpv4Info) + { + size = ROUND_UP(size,4); + of->icmpv4 = size; + size += sizeof(t_DsarIcmpV4Descriptor); + size += sizeof(t_DsarIcmpV4BindingEntry) + * params->p_AutoResEchoIpv4Info->tableSize; + size += sizeof(t_DsarIcmpV4Statistics); + } + // ICMPV6 + if (params->p_AutoResEchoIpv6Info) + { + size = ROUND_UP(size,4); + of->icmpv6 = size; + size += sizeof(t_DsarIcmpV6Descriptor); + size += sizeof(t_DsarIcmpV6BindingEntry) + * params->p_AutoResEchoIpv6Info->tableSize; + size += sizeof(t_DsarIcmpV6Statistics); + } + // ND + if (params->p_AutoResNdpInfo) + { + size = ROUND_UP(size,4); + of->nd = size; + size += sizeof(t_DsarNdDescriptor); + size += sizeof(t_DsarIcmpV6BindingEntry) + * (params->p_AutoResNdpInfo->tableSizeAssigned + + params->p_AutoResNdpInfo->tableSizeTmp); + size += sizeof(t_DsarIcmpV6Statistics); + } + // SNMP + if (params->p_AutoResSnmpInfo) + { + size = ROUND_UP(size,4); + of->snmp = size; + size += sizeof(t_DsarSnmpDescriptor); + size += sizeof(t_DsarSnmpIpv4AddrTblEntry) + * params->p_AutoResSnmpInfo->numOfIpv4Addresses; + size += sizeof(t_DsarSnmpIpv6AddrTblEntry) + * params->p_AutoResSnmpInfo->numOfIpv6Addresses; + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize; + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar; + size += sizeof(t_DsarIcmpV6Statistics); + } + //filters + size = ROUND_UP(size,4); + if (params->p_AutoResFilteringInfo) + { + of->filtIp = size; + size += params->p_AutoResFilteringInfo->ipProtTableSize; + size = ROUND_UP(size,4); + of->filtUdp = size; + size += params->p_AutoResFilteringInfo->udpPortsTableSize + * sizeof(t_PortTblEntry); + size = ROUND_UP(size,4); + of->filtTcp = size; + size += params->p_AutoResFilteringInfo->tcpPortsTableSize + * sizeof(t_PortTblEntry); + } + // add here for more protocols + // statistics + size = ROUND_UP(size,4); + of->stats = size; + size += sizeof(t_ArStatistics); + return size; +} + +uint32_t* ARDesc; +void PrsEnable(t_Handle p_FmPcd); +void PrsDisable(t_Handle p_FmPcd); +int PrsIsEnabled(t_Handle p_FmPcd); +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd); + +static t_Error DsarCheckParams(t_FmPortDsarParams *params, + t_FmPortDsarTablesSizes *sizes) +{ + bool macInit = FALSE; + uint8_t mac[6]; + int i = 0; + + // check table sizes + if (params->p_AutoResArpInfo + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Arp table size exceeds the configured maximum size.")); + if (params->p_AutoResEchoIpv4Info + && sizes->maxNumOfEchoIpv4Entries + < params->p_AutoResEchoIpv4Info->tableSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: EchoIpv4 table size exceeds the configured maximum size.")); + if (params->p_AutoResNdpInfo + && sizes->maxNumOfNdpEntries + < params->p_AutoResNdpInfo->tableSizeAssigned + + params->p_AutoResNdpInfo->tableSizeTmp) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: NDP table size exceeds the configured maximum size.")); + if (params->p_AutoResEchoIpv6Info + && sizes->maxNumOfEchoIpv6Entries + < params->p_AutoResEchoIpv6Info->tableSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: EchoIpv6 table size exceeds the configured maximum size.")); + if (params->p_AutoResSnmpInfo + && sizes->maxNumOfSnmpOidEntries + < params->p_AutoResSnmpInfo->oidsTblSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: Snmp Oid table size exceeds the configured maximum size.")); + if (params->p_AutoResSnmpInfo + && sizes->maxNumOfSnmpIPV4Entries + < params->p_AutoResSnmpInfo->numOfIpv4Addresses) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size.")); + if (params->p_AutoResSnmpInfo + && sizes->maxNumOfSnmpIPV6Entries + < params->p_AutoResSnmpInfo->numOfIpv6Addresses) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size.")); + if (params->p_AutoResFilteringInfo) + { + if (sizes->maxNumOfIpProtFiltering + < params->p_AutoResFilteringInfo->ipProtTableSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: ip filter table size exceeds the configured maximum size.")); + if (sizes->maxNumOfTcpPortFiltering + < params->p_AutoResFilteringInfo->udpPortsTableSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: udp filter table size exceeds the configured maximum size.")); + if (sizes->maxNumOfUdpPortFiltering + < params->p_AutoResFilteringInfo->tcpPortsTableSize) + RETURN_ERROR( + MAJOR, + E_INVALID_VALUE, + ("DSAR: tcp filter table size exceeds the configured maximum size.")); + } + /* check only 1 MAC address is configured (this is what ucode currently supports) */ + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize) + { + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6); + i = 1; + macInit = TRUE; + + for (; i < params->p_AutoResArpInfo->tableSize; i++) + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Only 1 mac address is currently supported.")); + } + if (params->p_AutoResEchoIpv4Info + && params->p_AutoResEchoIpv4Info->tableSize) + { + i = 0; + if (!macInit) { - DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[i]), sizeof(uint32_t)); + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac, + 6); + i = 1; + macInit = TRUE; } - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofqid ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oefqid); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsdm ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsem ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofene ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmts); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmt); - + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++) + if (memcmp(mac, + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Only 1 mac address is currently supported.")); + } + if (params->p_AutoResEchoIpv6Info + && params->p_AutoResEchoIpv6Info->tableSize) + { + i = 0; + if (!macInit) { -#ifndef FM_NO_OP_OBSERVED_POOLS - t_FmRevisionInfo revInfo; + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac, + 6); + i = 1; + macInit = TRUE; + } + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++) + if (memcmp(mac, + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Only 1 mac address is currently supported.")); + } + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned) + { + i = 0; + if (!macInit) + { + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac, + 6); + i = 1; + macInit = TRUE; + } + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) + if (memcmp(mac, + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac, + 6)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Only 1 mac address is currently supported.")); + } + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp) + { + i = 0; + if (!macInit) + { + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6); + i = 1; + } + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac, + 6)) + RETURN_ERROR( + MAJOR, E_INVALID_VALUE, + ("DSAR: Only 1 mac address is currently supported.")); + } + return E_OK; +} - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev == 4) -#endif /* !FM_NO_OP_OBSERVED_POOLS */ +static int GetBERLen(uint8_t* buf) +{ + if (*buf & 0x80) + { + if ((*buf & 0x7F) == 1) + return buf[1]; + else + return *(uint16_t*)&buf[1]; // assuming max len is 2 + } + else + return buf[0]; +} +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3 + +#ifdef TODO_SOC_SUSPEND // XXX +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000 +static int fm_soc_suspend(void) +{ + uint32_t *fmclk, tmp32; + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); + tmp32 = GET_UINT32(*fmclk); + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL); + tmp32 = GET_UINT32(*fmclk); + iounmap(fmclk); + return 0; +} + +void fm_clk_down(void) +{ + uint32_t *fmclk, tmp32; + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); + tmp32 = GET_UINT32(*fmclk); + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000); + tmp32 = GET_UINT32(*fmclk); + iounmap(fmclk); +} +#endif + +#if 0 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) +{ + int i, j; + t_Error err; + uint32_t nia; + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx; + t_DsarArpDescriptor *ArpDescriptor; + t_DsarIcmpV4Descriptor* ICMPV4Descriptor; + t_DsarIcmpV6Descriptor* ICMPV6Descriptor; + t_DsarNdDescriptor* NDDescriptor; + + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr)); + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); + struct arOffsets* of; + uint8_t tmp = 0; + t_FmGetSetParams fmGetSetParams; + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; + fmGetSetParams.setParams.sleep = 1; + + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes); + if (err != E_OK) + return err; + + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets)); + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets; + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort)); + + // common + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId); + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne)); + else + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia); + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161); + + // ARP + if (params->p_AutoResArpInfo) + { + t_DsarArpBindingEntry* arp_bindings; + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr); + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor)); + if (params->p_AutoResArpInfo->enableConflictDetection) + WRITE_UINT16(ArpDescriptor->control, 1); + else + WRITE_UINT16(ArpDescriptor->control, 0); + if (params->p_AutoResArpInfo->tableSize) + { + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable; + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize); + + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++) { - DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi, ("fmbm_oebmpi")); - - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS) - { - DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi[i], sizeof(uint32_t)); - } - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocgm); + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress); + if (arp_entry[i].isVlan) + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); } + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr); } - - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ostc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofrc ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdc ); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofledc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofufdc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_offc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofwdc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofldec); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opcp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occn); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_otuc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oduc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofuc); - break; - case(1): - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rcfg); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rst); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rda); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_reth); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfed); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_ricp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rebm); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfca); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfpne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpso); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpp); - - DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai), ("fmbm_rprai")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) - { - DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[i]), sizeof(uint32_t)); - } - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfqid); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_refqid); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsdm); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsem); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfene); - DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi, ("fmbm_ebmpi")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) - { - DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], sizeof(uint32_t)); - } - DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt, ("fmbm_acnt")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) - { - DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], sizeof(uint32_t)); - } - DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm, ("fmbm_cgm")); - DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_NUM_OF_CONGESTION_GRPS/32) - { - DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[i], sizeof(uint32_t)); - } - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_mpd); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rstc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfrc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfbc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rlfc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rffc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfcd); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfldec); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rodc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpcp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rccn); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rtuc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rrquc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rduc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfuc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpac); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rdbg); - break; - case(2): - - DUMP_SUBTITLE(("\n")); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfg); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tst); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tda); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfed); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ticp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfne); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfca); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfqid); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfeqid); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfene); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmts); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmt); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tstc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfrc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfdc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfledc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfufdc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpcp); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tccn); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttuc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttcquc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tduc); - DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfuc); - break; - - default: - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid flag")); + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) + + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr); } - DUMP_TITLE(p_FmPort->p_FmPortQmiRegs, ("Qmi Port Regs")); - - DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnc); - DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pns); - DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnts); - DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnen); - DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnetfc); - - if(flag !=1) + // ICMPV4 + if (params->p_AutoResEchoIpv4Info) { - DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndn); - DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndc); - DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndtfc); - DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndfdc); - DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndcc); + t_DsarIcmpV4BindingEntry* icmpv4_bindings; + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr); + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor)); + WRITE_UINT16(ICMPV4Descriptor->control, 0); + if (params->p_AutoResEchoIpv4Info->tableSize) + { + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable; + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize); + + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++) + { + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress); + if (arp_entry[i].isVlan) + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); + } + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr); + } + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) + + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr); } + // ICMPV6 + if (params->p_AutoResEchoIpv6Info) + { + t_DsarIcmpV6BindingEntry* icmpv6_bindings; + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr); + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor)); + WRITE_UINT16(ICMPV6Descriptor->control, 0); + if (params->p_AutoResEchoIpv6Info->tableSize) + { + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable; + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize); + + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++) + { + for (j = 0; j < 4; j++) + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); + if (ndp_entry[i].isVlan) + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan + } + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); + } + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr); + } + + // ND + if (params->p_AutoResNdpInfo) + { + t_DsarIcmpV6BindingEntry* icmpv6_bindings; + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr); + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor)); + if (params->p_AutoResNdpInfo->enableConflictDetection) + WRITE_UINT16(NDDescriptor->control, 1); + else + WRITE_UINT16(NDDescriptor->control, 0); + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) + { + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned; + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned + + params->p_AutoResNdpInfo->tableSizeTmp); + + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) + { + for (j = 0; j < 4; j++) + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); + if (ndp_entry[i].isVlan) + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan + } + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp; + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) + { + for (j = 0; j < 4; j++) + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]); + if (ndp_entry[i].isVlan) + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan + } + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); + } + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry) + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) + - fmMuramVirtBaseAddr); + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF); + } + + // SNMP + if (params->p_AutoResSnmpInfo) + { + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo; + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr; + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr; + t_OidsTblEntry* snmpOid; + uint8_t *charPointer; + int len; + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr); + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control); + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength); + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor)); + if (snmpSrc->numOfIpv4Addresses) + { + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl; + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses); + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++) + { + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr); + if (snmpIpv4AddrSrc[i].isVlan) + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF); + } + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr); + } + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr) + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses); + if (snmpSrc->numOfIpv6Addresses) + { + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl; + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses); + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++) + { + for (j = 0; j < 4; j++) + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]); + if (snmpIpv6AddrSrc[i].isVlan) + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF); + } + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr); + } + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr) + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses); + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid) + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize); + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1])); + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len); + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); + charPointer += len; + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1])); + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len); + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); + charPointer += len; + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize); + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr); + for (i = 0; i < snmpSrc->oidsTblSize; i++) + { + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize); + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize); + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize); + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); + charPointer += snmpSrc->p_OidsTbl[i].oidSize; + if (snmpSrc->p_OidsTbl[i].resSize <= 4) + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal); + else + { + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize); + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); + charPointer += snmpSrc->p_OidsTbl[i].resSize; + } + snmpOid++; + } + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4)); + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); + } + + // filtering + if (params->p_AutoResFilteringInfo) + { + if (params->p_AutoResFilteringInfo->ipProtPassOnHit) + tmp |= IP_PROT_TBL_PASS_MASK; + if (params->p_AutoResFilteringInfo->udpPortPassOnHit) + tmp |= UDP_PORT_TBL_PASS_MASK; + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit) + tmp |= TCP_PORT_TBL_PASS_MASK; + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp); + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask); + + // ip filtering + if (params->p_AutoResFilteringInfo->ipProtTableSize) + { + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp); + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize); + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++) + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]); + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr); + } + + // udp filtering + if (params->p_AutoResFilteringInfo->udpPortsTableSize) + { + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp); + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize); + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++) + { + WRITE_UINT32(udp_tbl[i].Ports, + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) + + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort); + WRITE_UINT32(udp_tbl[i].PortsMask, + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) + + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask); + } + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr); + } + + // tcp filtering + if (params->p_AutoResFilteringInfo->tcpPortsTableSize) + { + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp); + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize); + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++) + { + WRITE_UINT32(tcp_tbl[i].Ports, + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) + + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort); + WRITE_UINT32(tcp_tbl[i].PortsMask, + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) + + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask); + } + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr); + } + } + // common stats + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr); + + // get into Deep Sleep sequence: + + // Ensures that FMan do not enter the idle state. This is done by programing + // FMDPSLPCR[FM_STOP] to one. + fm_soc_suspend(); + + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr)); + return E_OK; + +} + +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId); +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort) +{ + t_FmGetSetParams fmGetSetParams; + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort; + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort; + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FM_CLD; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + + /* Issue graceful stop to HC port */ + FM_PORT_Disable(p_FmPortHc); + + // config tx port + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg); + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN); + // ???? + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne); + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE); + // Stage 7:echo + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne); + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E); + if (!PrsIsEnabled(h_FmPcd)) + { + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE; + PrsEnable(h_FmPcd); + } + else + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE; + + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000); + + // save rcfg for restoring: accumulate mode is changed by ucode + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg); + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM); + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; + fmGetSetParams.setParams.sleep = 1; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + +// ***** issue external request sync command + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + // get + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMFP_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + if (fmGetSetParams.getParams.fmfp_extc != 0) + { + // clear + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); +} + + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI; + do + { + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0); + if (fmGetSetParams.getParams.fm_npi != 0) + XX_Print("FM: Sync did not finish\n"); + + // check that all stoped + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000) + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0) + XX_Print("FM: Sleeping\n"); +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId); + return E_OK; } -#endif /* (defined(DEBUG_ERRORS) && ... */ -t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) +void FM_PORT_Dsar_DumpRegs() { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; - int i; - uint8_t mod; - uint32_t tmpReg = 0; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - - { -#ifdef FM_NO_OP_OBSERVED_CGS - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev != 4) - { - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); - } - else -#endif /* FM_NO_OP_OBSERVED_CGS */ - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only")); - } - - opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); - - /* to minimize memory access (groups may belong to the same regsiter, and may - be out of order), we first collect all information into a 256 booleans array, - representing each possible group. */ - - memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); - for(i=0;inumOfCongestionGrpsToConsider;i++) - tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; - - for(i=0;ip_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): - GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]); - - /* set in the register, the bit representing the relevant congestion group. */ - if(tmpArray[i]) - tmpReg |= (0x00000001 << (uint32_t)mod); - - if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ - { - if(opPort) - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); - else - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg); - } - } - - return E_OK; + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc)); + DUMP_MEMORY(hh, 0x220); } -t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx) { - t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; - int i; - uint8_t mod; - uint32_t tmpReg = 0; - - SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); - + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx; + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); + t_FmGetSetParams fmGetSetParams; + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; + fmGetSetParams.setParams.sleep = 0; + if (p_FmPort->deepSleepVars.autoResOffsets) { -#ifdef FM_NO_OP_OBSERVED_CGS - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if (revInfo.majorRev != 4) - { - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); - } - else -#endif /* FM_NO_OP_OBSERVED_CGS */ - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && - (p_FmPort->portType != e_FM_PORT_TYPE_RX) && - (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only")); + XX_Free(p_FmPort->deepSleepVars.autoResOffsets); + p_FmPort->deepSleepVars.autoResOffsets = 0; } - opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); - - /* to minimize memory access (groups may belong to the same regsiter, and may - be out of order), we first collect all information into a 256 booleans array, - representing each possible group. */ - memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); - for(i=0;inumOfCongestionGrpsToConsider;i++) - tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; - - for(i=0;ip_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): - GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]); - - /* set in the register, the bit representing the relevant congestion group. */ - if(tmpArray[i]) - tmpReg &= ~(0x00000001 << (uint32_t)mod); - - if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ - { - if(opPort) - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); - else - WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg); - } - } - - return E_OK; + if (p_FmPort->deepSleepVars.dsarEnabledParser) + PrsDisable(FmGetPcd(p_FmPort->h_Fm)); + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne); + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne); + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg); + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne); + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg); + FM_PORT_Enable(p_FmPortHc); } +bool FM_PORT_IsInDsar(t_Handle h_FmPort) +{ + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets); +} + +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats) +{ + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets; + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr); + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr); + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr); + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr); + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); + stats->arpArCnt = arp_stats->arCnt; + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt; + stats->ndpArCnt = nd_stats->arCnt; + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt; + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt; + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt; + return E_OK; +} +#endif diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h index 2e8a99735e26..85986f553c3f 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_port.h @@ -43,7 +44,10 @@ #include "fm_port_ext.h" #include "fm_common.h" - +#include "fm_sp_common.h" +#include "fsl_fman_sp.h" +#include "fm_port_ext.h" +#include "fsl_fman_port.h" #define __ERR_MODULE__ MODULE_FM_PORT @@ -51,6 +55,7 @@ #define MIN_EXT_BUF_SIZE 64 #define DATA_ALIGNMENT 64 #define MAX_LIODN_OFFSET 64 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS) /**************************************************************************//** @Description Memory Map defines @@ -62,36 +67,31 @@ /**************************************************************************//** @Description defaults *//***************************************************************************/ -#define DEFAULT_PORT_deqHighPriority TRUE +#define DEFAULT_PORT_deqHighPriority_1G FALSE +#define DEFAULT_PORT_deqHighPriority_10G TRUE #define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1 -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT #define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH #define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ -#define DEFAULT_PORT_deqByteCnt 2000 -#define DEFAULT_PORT_bufferPrefixContent_privDataSize 0 -#define DEFAULT_PORT_bufferPrefixContent_passPrsResult FALSE -#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp FALSE -#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo FALSE -#ifdef DEBUG -#define DEFAULT_PORT_bufferPrefixContent_debugInfo FALSE -#endif /* DEBUG */ -#define DEFAULT_PORT_bufferPrefixContent_dataAlign DATA_ALIGNMENT +#define DEFAULT_PORT_deqByteCnt_10G 0x1400 +#define DEFAULT_PORT_deqByteCnt_1G 0x400 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign #define DEFAULT_PORT_cheksumLastBytesIgnore 0 #define DEFAULT_PORT_cutBytesFromEnd 4 -#define DEFAULT_PORT_txFifoMinFillLevel 0 -#define DEFAULT_PORT_txFifoDeqPipelineDepth_IM 2 -#define DEFAULT_PORT_txFifoDeqPipelineDepth_1G 2 -#define DEFAULT_PORT_txFifoDeqPipelineDepth_10G 8 -#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE) -#define DEFAULT_PORT_rxFifoPriElevationLevel BMI_MAX_FIFO_SIZE -#define DEFAULT_PORT_rxFifoThreshold (BMI_MAX_FIFO_SIZE*3/4) +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2 + #define DEFAULT_PORT_frmDiscardOverride FALSE -#define DEFAULT_PORT_dmaSwapData e_FM_PORT_DMA_NO_SWP -#define DEFAULT_PORT_dmaIntContextCacheAttr e_FM_PORT_DMA_NO_STASH -#define DEFAULT_PORT_dmaHeaderCacheAttr e_FM_PORT_DMA_NO_STASH -#define DEFAULT_PORT_dmaScatterGatherCacheAttr e_FM_PORT_DMA_NO_STASH -#define DEFAULT_PORT_dmaWriteOptimize TRUE + +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE + +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER #define DEFAULT_PORT_forwardIntContextReuse FALSE #define DEFAULT_PORT_BufMargins_startMargins 32 #define DEFAULT_PORT_BufMargins_endMargins 0 @@ -99,9 +99,23 @@ #define DEFAULT_PORT_syncReqForHc FALSE #define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN #define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD -#define DEFAULT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE -#define DEFAULT_rateLimitBurstSizeHighGranularity FALSE -#define DEFAULT_exception IM_EV_BSY +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */ +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */ +#define DEFAULT_PORT_exception IM_EV_BSY +#define DEFAULT_PORT_maxFrameLength 9600 + +#define DEFAULT_notSupported 0xff + +#if (DPAA_VERSION < 11) +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4) + +#define DEFAULT_PORT_txFifoMinFillLevel 0 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE) +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4 + +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2 /* Host command port MUST NOT be changed to more than 1 !!! */ #define DEFAULT_PORT_numOfTasks(type) \ @@ -112,46 +126,116 @@ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1)) #define DEFAULT_PORT_extraNumOfTasks(type) \ - (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ - ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \ - ((((type) == e_FM_PORT_TYPE_RX) || \ - ((type) == e_FM_PORT_TYPE_TX) || \ - ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 2 : 0)) + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0)) -#define DEFAULT_PORT_numOfOpenDmas(type) \ - (uint32_t)(((type) == e_FM_PORT_TYPE_TX_10G) ? 8 : \ - (((type) == e_FM_PORT_TYPE_RX_10G) ? 4 : 1)) +#define DEFAULT_PORT_numOfOpenDmas(type) \ + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \ + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 ) #define DEFAULT_PORT_extraNumOfOpenDmas(type) \ + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0)) + +#define DEFAULT_PORT_numOfFifoBufs(type) \ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ - ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \ - ((((type) == e_FM_PORT_TYPE_RX) || \ - ((type) == e_FM_PORT_TYPE_TX) || \ - ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 1 : 0)) + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \ + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \ + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8) -#if defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM) -/* Let LLD to set minimum fifosize, otherwise fifosize settings will not work */ -#define DEFAULT_PORT_sizeOfFifo(type) \ - (uint32_t)(KILOBYTE) -#else -#define DEFAULT_PORT_sizeOfFifo(type) \ - (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ - ((type) == e_FM_PORT_TYPE_TX_10G)) ? (16*KILOBYTE) : \ - ((((type) == e_FM_PORT_TYPE_RX) || \ - ((type) == e_FM_PORT_TYPE_TX) || \ - ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? (4*KILOBYTE) : (1536))) -#endif +#define DEFAULT_PORT_extraNumOfFifoBufs 0 -#define DEFAULT_PORT_extraSizeOfFifo(type) \ - (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? (8*KILOBYTE) : \ - (((type) == e_FM_PORT_TYPE_RX) ? (4*KILOBYTE) : (0))) +#else /* (DPAA_VERSION < 11) */ +/* Defaults are registers' reset values */ +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE + +#define DEFAULT_PORT_txFifoMinFillLevel 0 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE) +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4 + +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2 + +#define DEFAULT_PORT_numOfTasks(type) \ + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \ + (((type) == e_FM_PORT_TYPE_RX) || \ + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \ + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1) + +#define DEFAULT_PORT_extraNumOfTasks(type) 0 + +#define DEFAULT_PORT_numOfOpenDmas(type) \ + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \ + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \ + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \ + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4) + +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0 + +#define DEFAULT_PORT_numOfFifoBufs(type) \ + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \ + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \ + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50) + +#define DEFAULT_PORT_extraNumOfFifoBufs 0 + +#endif /* (DPAA_VERSION < 11) */ #define DEFAULT_PORT_txBdRingLength 16 #define DEFAULT_PORT_rxBdRingLength 128 #define DEFAULT_PORT_ImfwExtStructsMemId 0 #define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE -#define OH_PIPELINE_DEPTH 2 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32) + +/**************************************************************************//** + @Collection PCD Engines +*//***************************************************************************/ +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */ + +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */ +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */ +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */ +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */ +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */ +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */ +/* @} */ + +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32) + +#define FM_OH_PORT_ID 0 + +/***********************************************************************/ +/* SW parser OFFLOAD labels (offsets) */ +/***********************************************************************/ +#if (DPAA_VERSION == 10) +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325 +#else +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100 +/* Will be used for: + * 1. identify fragments + * 2. udp-lite + */ +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146 +/* Will be used for: + * 1. will identify the fragmentable area + * 2. udp-lite + */ +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d +#endif /* (DPAA_VERSION == 10) */ + +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) +#define UDP_LITE_SW_PATCH_LABEL 0x2E0 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + /**************************************************************************//** @Description Memory Mapped Registers @@ -160,12 +244,8 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START -#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8 -#define FM_PORT_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256 - -typedef _Packed struct +typedef struct { volatile uint32_t fmbm_rcfg; /**< Rx Configuration */ volatile uint32_t fmbm_rst; /**< Rx Status */ @@ -182,7 +262,7 @@ typedef _Packed struct volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */ volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */ volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */ - volatile uint32_t reserved1[1]; /**< (0x03C 0x03F) */ + volatile uint32_t reserved1[0x01];/**< (0x03C) */ volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS]; /**< Rx Parse Results Array Initialization*/ volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/ @@ -190,17 +270,19 @@ typedef _Packed struct volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/ volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/ volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */ - volatile uint32_t reserved2[0x23];/**< (0x074 0x0FF) */ + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */ + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */ + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */ volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS]; /**< Buffer Manager pool Information-*/ volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS]; /**< Allocate Counter-*/ - volatile uint32_t reserved3[8]; + volatile uint32_t reserved4[0x08]; /**< 0x130/0x140 - 0x15F reserved -*/ - volatile uint32_t fmbm_cgm[FM_PORT_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32]; + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32]; /**< Congestion Group Map*/ - volatile uint32_t fmbm_mpd; /**< BM Pool Depletion */ - volatile uint32_t reserved4[0x1F];/**< (0x184 0x1FF) */ + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */ + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */ volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/ volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/ volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/ @@ -210,7 +292,8 @@ typedef _Packed struct volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/ volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/ volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/ - volatile uint32_t reserved5[0x17];/**< (0x224 0x27F) */ + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/ + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */ volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/ volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/ volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/ @@ -219,11 +302,13 @@ typedef _Packed struct volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/ volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/ volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/ - volatile uint32_t reserved6[0x18];/**< (0x2A0 0x2FF) */ - volatile uint32_t fmbm_rdbg; /**< Rx Debug-*/ -} _PackedType t_FmPortRxBmiRegs; + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */ + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/ + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */ + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */ +} t_FmPortRxBmiRegs; -typedef _Packed struct +typedef struct { volatile uint32_t fmbm_tcfg; /**< Tx Configuration */ volatile uint32_t fmbm_tst; /**< Tx Status */ @@ -231,21 +316,26 @@ typedef _Packed struct volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */ volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */ volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */ - volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine. */ + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */ volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */ volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */ volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */ volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */ volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */ volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */ - volatile uint32_t reserved0[0x73];/**< (0x038-0x200) */ + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */ + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */ + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */ + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */ + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */ + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */ volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */ volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */ volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */ volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */ volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */ volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */ - volatile uint32_t reserved1[0x1A];/**< (0x218-0x280) */ + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */ volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/ volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/ volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/ @@ -253,9 +343,13 @@ typedef _Packed struct volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/ volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/ volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/ -} _PackedType t_FmPortTxBmiRegs; + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */ + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/ + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */ + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */ +} t_FmPortTxBmiRegs; -typedef _Packed struct +typedef struct { volatile uint32_t fmbm_ocfg; /**< O/H Configuration */ volatile uint32_t fmbm_ost; /**< O/H Status */ @@ -269,7 +363,9 @@ typedef _Packed struct volatile uint32_t fmbm_opp; /**< O/H Policer Profile */ volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */ volatile uint32_t fmbm_oim; /**< O/H Internal margins*/ - volatile uint32_t reserved0[4]; /**< (0x030 - 0x03F) */ + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/ + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/ + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */ volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS]; /**< O/H Parse Results Array Initialization */ volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */ @@ -279,19 +375,14 @@ typedef _Packed struct volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */ volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */ volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */ - volatile uint32_t reserved0a[0x21]; - /**< 0x07C - 0x0FF Reserved */ - union - { - volatile uint32_t fmbm_oebmpi[FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS]; - /**< Buffer Manager Observed Pool Information */ - volatile uint32_t reserved0b[0x18]; - }; /**< 0x100 - 0x15F Reserved */ + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */ + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */ + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */ + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */ volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */ - volatile uint32_t reserved0c[0x7];/**< 0x164 - 0x17F Reserved */ + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */ volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */ - volatile uint32_t reserved0d[0x1F]; - /**< 0x184 - 0x1FF Reserved */ + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */ volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */ volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */ volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */ @@ -301,23 +392,29 @@ typedef _Packed struct volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */ volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */ volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */ - volatile uint32_t reserved2[0x17];/**< (0x218 - 0x27F) */ + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */ + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */ + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */ volatile uint32_t fmbm_opc; /**< O/H Performance Counters */ volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */ volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */ volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */ volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */ volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */ -} _PackedType t_FmPortOhBmiRegs; + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */ + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */ + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */ + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */ +} t_FmPortOhBmiRegs; -typedef _Packed union +typedef union { t_FmPortRxBmiRegs rxPortBmiRegs; t_FmPortTxBmiRegs txPortBmiRegs; t_FmPortOhBmiRegs ohPortBmiRegs; -} _PackedType u_FmPortBmiRegs; +} u_FmPortBmiRegs; -typedef _Packed struct +typedef struct { volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */ volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */ @@ -325,9 +422,9 @@ typedef _Packed struct volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */ volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */ volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */ -} _PackedType t_FmPortNonRxQmiRegs; +} t_FmPortNonRxQmiRegs; -typedef _Packed struct +typedef struct { volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */ volatile uint32_t fmqm_pns; /**< PortID n Status Register */ @@ -335,20 +432,20 @@ typedef _Packed struct volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */ volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */ volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */ - t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */ -} _PackedType t_FmPortQmiRegs; + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */ +} t_FmPortQmiRegs; -typedef _Packed struct +typedef struct { - _Packed struct + struct { volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */ volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */ - } _PackedType hdrs[FM_PCD_PRS_NUM_OF_HDRS]; - volatile uint8_t reserved0[0x378]; + } hdrs[FM_PCD_PRS_NUM_OF_HDRS]; + volatile uint32_t reserved0[0xde]; volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */ volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */ -} _PackedType t_FmPortPrsRegs; +} t_FmPortPrsRegs; /**************************************************************************//* @Description Basic buffer descriptor (BD) structure @@ -386,7 +483,6 @@ typedef _Packed struct volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */ } _PackedType t_FmPortImPram; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -399,36 +495,41 @@ typedef _Packed struct /**************************************************************************//** @Description BMI defines *//***************************************************************************/ +#if (DPAA_VERSION >= 11) +#define BMI_SP_ID_MASK 0xff000000 +#define BMI_SP_ID_SHIFT 24 +#define BMI_SP_EN 0x01000000 +#endif /* (DPAA_VERSION >= 11) */ + #define BMI_PORT_CFG_EN 0x80000000 #define BMI_PORT_CFG_EN_MACSEC 0x00800000 #define BMI_PORT_CFG_FDOVR 0x02000000 #define BMI_PORT_CFG_IM 0x01000000 +#define BMI_PORT_CFG_AM 0x00000040 #define BMI_PORT_STATUS_BSY 0x80000000 #define BMI_COUNTERS_EN 0x80000000 -#define BMI_DMA_ATTR_WRITE_OPTIMIZE 0x00100000 + #define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000 #define BMI_PORT_RFNE_FRWD_RPD 0x40000000 #define BMI_RFNE_FDCS_MASK 0xFF000000 +#define BMI_RFNE_HXS_MASK 0x000000FF #define BMI_CMD_MR_LEAC 0x00200000 #define BMI_CMD_MR_SLEAC 0x00100000 #define BMI_CMD_MR_MA 0x00080000 #define BMI_CMD_MR_DEAS 0x00040000 -#define BMI_CMD_TX_MR_DEF (0) #define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \ BMI_CMD_MR_SLEAC | \ BMI_CMD_MR_MA | \ BMI_CMD_MR_DEAS) #define BMI_CMD_ATTR_ORDER 0x80000000 #define BMI_CMD_ATTR_SYNC 0x02000000 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000 #define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00 #define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000 #define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000 #define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00 -#define BMI_EXT_BUF_POOL_VALID 0x80000000 -#define BMI_EXT_BUF_POOL_EN_COUNTER 0x40000000 -#define BMI_EXT_BUF_POOL_BACKUP 0x20000000 #define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000 #define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \ FM_PORT_FRM_ERR_PHYSICAL | \ @@ -444,11 +545,13 @@ typedef _Packed struct FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \ FM_PORT_FRM_ERR_PRS_HDR_ERR | \ - FM_PORT_FRM_ERR_PROCESS_TIMEOUT | \ + FM_PORT_FRM_ERR_IPRE | \ + FM_PORT_FRM_ERR_IPR_NCSP | \ FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW)) #define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \ ~(FM_PORT_FRM_ERR_LENGTH | \ + FM_PORT_FRM_ERR_NON_FM | \ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)) #define BMI_RATE_LIMIT_EN 0x80000000 @@ -462,6 +565,7 @@ typedef _Packed struct #define BMI_PRS_RESULT_HIGH 0x00000000 #define BMI_PRS_RESULT_LOW 0xFFFFFFFF + #define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \ FM_PORT_FRM_ERR_PHYSICAL | \ FM_PORT_FRM_ERR_SIZE | \ @@ -473,27 +577,26 @@ typedef _Packed struct FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \ FM_PORT_FRM_ERR_PRS_HDR_ERR | \ - FM_PORT_FRM_ERR_PROCESS_TIMEOUT | \ - FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW) + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \ + FM_PORT_FRM_ERR_IPRE) -#ifdef FM_CAPWAP_SUPPORT #define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \ FM_PORT_FRM_ERR_LENGTH | \ FM_PORT_FRM_ERR_NON_FM | \ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT) -#else -#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \ - FM_PORT_FRM_ERR_LENGTH | \ - FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT) -#endif /* FM_CAPWAP_SUPPORT */ + +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000 +#define BMI_TX_LOW_COMF_MASK 0x000003FF /* shifts */ #define BMI_PORT_CFG_MS_SEL_SHIFT 16 -#define BMI_DMA_ATTR_SWP_SHIFT 30 -#define BMI_DMA_ATTR_IC_CACHE_SHIFT 28 -#define BMI_DMA_ATTR_HDR_CACHE_SHIFT 26 -#define BMI_DMA_ATTR_SG_CACHE_SHIFT 24 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT #define BMI_IM_FOF_SHIFT 28 #define BMI_PR_PORTID_SHIFT 24 @@ -504,14 +607,11 @@ typedef _Packed struct #define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24 #define BMI_RX_FRAME_END_CUT_SHIFT 16 -#define BMI_IC_TO_EXT_SHIFT 16 -#define BMI_IC_FROM_INT_SHIFT 8 -#define BMI_IC_SIZE_SHIFT 0 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT #define BMI_INT_BUF_MARG_SHIFT 28 -#define BMI_EXT_BUF_MARG_START_SHIFT 16 -#define BMI_EXT_BUF_MARG_END_SHIFT 0 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT #define BMI_CMD_ATTR_COLOR_SHIFT 26 #define BMI_CMD_ATTR_COM_MODE_SHIFT 16 @@ -520,17 +620,11 @@ typedef _Packed struct #define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12 #define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8 -#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16 #define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24 -#define BMI_EXT_BUF_POOL_ID_SHIFT 16 - #define BMI_TX_FIFO_MIN_FILL_SHIFT 16 -#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12 #define BMI_TX_LOW_COMF_SHIFT 0 -#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24 - #define BMI_PERFORMANCE_TASK_COMP_SHIFT 24 #define BMI_PERFORMANCE_PORT_COMP_SHIFT 16 #define BMI_PERFORMANCE_DMA_COMP_SHIFT 12 @@ -541,13 +635,8 @@ typedef _Packed struct /* sizes */ #define FRAME_END_DATA_SIZE 16 -#define OFFSET_UNITS 16 #define FRAME_OFFSET_UNITS 16 -#define MAX_EXT_OFFSET 496 -#define MAX_EXT_BUFFER_OFFSET 511 -#define MAX_INT_OFFSET 240 #define MIN_TX_INT_OFFSET 16 -#define MAX_IC_SIZE 256 #define MAX_FRAME_OFFSET 64 #define MAX_FIFO_PIPELINE_DEPTH 8 #define MAX_PERFORMANCE_TASK_COMP 64 @@ -559,7 +648,8 @@ typedef _Packed struct #define MAX_NUM_OF_DMAS 16 #define MAX_NUM_OF_EXTRA_DMAS 8 #define MAX_BURST_SIZE 1024 -#define FRAG_EXTRA_SPACE 32 +#define MIN_NUM_OF_OP_DMAS 2 + /**************************************************************************//** @Description QMI defines @@ -595,7 +685,7 @@ typedef _Packed struct #define PRS_TPID_DFLT 0x91009100 #define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000 -#define PRS_HDR_IPV6_ROUTE_HDR_DIS 0x00008000 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000 #define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000 #define PRS_HDR_UDP_PAD_REMOVAL 0x80000000 #define PRS_HDR_TCP_PAD_REMOVAL 0x80000000 @@ -637,10 +727,6 @@ typedef _Packed struct #define SCTP_SW_PATCH_START 0x4D #define DCCP_SW_PATCH_START 0x41 -#define IP_FRAG_SW_PATCH_IPv4 0x300 -#define IP_FRAG_SW_PATCH_IPv6_0 0x320 -#define IP_FRAG_SW_PATCH_IPv6_1 0x372 - /**************************************************************************//** @Description IM defines *//***************************************************************************/ @@ -653,7 +739,6 @@ typedef _Packed struct #define BD_RX_OV 0x00010000 #define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV) -#define BD_ERROR_PASS_FRAME BD_RX_ERRORS #define FM_IM_SIZEOF_BD sizeof(t_FmImBd) @@ -686,6 +771,11 @@ typedef _Packed struct #define IM_EV_BSY 0x40000000 #define IM_EV_RX 0x80000000 + +/**************************************************************************//** + @Description Additional defines +*//***************************************************************************/ + typedef struct { t_Handle h_FmMuram; t_FmPortImPram *p_FmPortImPram; @@ -710,41 +800,9 @@ typedef struct { t_FmPortImTxConfCallback *f_TxConf; } t_FmMacIm; -/**************************************************************************//** - @Description structure for defining internal context copying -*//***************************************************************************/ -typedef struct -{ - uint16_t extBufOffset; /**< Offset in External buffer to which internal - context is copied to (Rx) or taken from (Tx, Op). */ - uint8_t intContextOffset; /**< Offset within internal context to copy from - (Rx) or to copy to (Tx, Op). */ - uint16_t size; /**< Internal offset size to be copied */ -} t_FmPortIntContextDataCopy; - -/**************************************************************************//** - @Description struct for defining external buffer margins -*//***************************************************************************/ -typedef struct { - uint16_t startMargins; /**< Number of bytes to be left at the beginning - of the external buffer (must be divisible by 16) */ - uint16_t endMargins; /**< number of bytes to be left at the end - of the external buffer(must be divisible by 16) */ -} t_FmPortBufMargins; - -typedef struct { - uint32_t dataOffset; - uint32_t prsResultOffset; - uint32_t timeStampOffset; - uint32_t hashResultOffset; - uint32_t pcdInfoOffset; - uint32_t manipOffset; -#ifdef DEBUG - uint32_t debugOffset; -#endif /* DEBUG */ -} t_FmPortBufferOffsets; typedef struct { + struct fman_port_cfg dfltCfg; uint32_t dfltFqid; uint32_t confFqid; uint32_t errFqid; @@ -752,13 +810,11 @@ typedef struct { uint8_t deqSubPortal; bool deqHighPriority; e_FmPortDeqType deqType; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT e_FmPortDeqPrefetchOption deqPrefetchOption; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ uint16_t deqByteCnt; uint8_t cheksumLastBytesIgnore; uint8_t cutBytesFromEnd; - t_FmPortBufPoolDepletion bufPoolDepletion; + t_FmBufPoolDepletion bufPoolDepletion; uint8_t pipelineDepth; uint16_t fifoLowComfLevel; bool frmDiscardOverride; @@ -768,34 +824,63 @@ typedef struct { bool enBufPoolDepletion; uint16_t liodnOffset; uint16_t liodnBase; - t_FmPortExtPools extBufPools; - e_FmPortDmaSwap dmaSwapData; - e_FmPortDmaCache dmaIntContextCacheAttr; - e_FmPortDmaCache dmaHeaderCacheAttr; - e_FmPortDmaCache dmaScatterGatherCacheAttr; + t_FmExtPools extBufPools; + e_FmDmaSwapOption dmaSwapData; + e_FmDmaCacheOption dmaIntContextCacheAttr; + e_FmDmaCacheOption dmaHeaderCacheAttr; + e_FmDmaCacheOption dmaScatterGatherCacheAttr; bool dmaReadOptimize; bool dmaWriteOptimize; uint32_t txFifoMinFillLevel; uint32_t txFifoLowComfLevel; uint32_t rxFifoPriElevationLevel; uint32_t rxFifoThreshold; - t_FmPortBufMargins bufMargins; - t_FmPortIntContextDataCopy intContext; + t_FmSpBufMargins bufMargins; + t_FmSpIntContextDataCopy intContext; bool syncReq; e_FmPortColor color; fmPortFrameErrSelect_t errorsToDiscard; fmPortFrameErrSelect_t errorsToEnq; - uint64_t fmMuramPhysBaseAddr; bool forwardReuseIntContext; - t_FmPortBufferPrefixContent bufferPrefixContent; - uint8_t internalBufferOffset; - t_FmPortBackupBmPools *p_BackupBmPools; + t_FmBufferPrefixContent bufferPrefixContent; + t_FmBackupBmPools *p_BackupBmPools; bool dontReleaseBuf; + bool setNumOfTasks; + bool setNumOfOpenDmas; + bool setSizeOfFifo; +#if (DPAA_VERSION >= 11) + bool noScatherGather; +#endif /* (DPAA_VERSION >= 11) */ + +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 + bool bcbWorkaround; +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ } t_FmPortDriverParam; + +typedef struct t_FmPortRxPoolsParams +{ + uint8_t numOfPools; + uint16_t secondLargestBufSize; + uint16_t largestBufSize; +} t_FmPortRxPoolsParams; + +typedef struct t_FmPortDsarVars { + t_Handle *autoResOffsets; + t_FmPortDsarTablesSizes *autoResMaxSizes; + uint32_t fmbm_tcfg; + uint32_t fmbm_tcmne; + uint32_t fmbm_rfne; + uint32_t fmbm_rfpne; + uint32_t fmbm_rcfg; + bool dsarEnabledParser; +} t_FmPortDsarVars; typedef struct { + struct fman_port port; t_Handle h_Fm; t_Handle h_FmPcd; + t_Handle h_FmMuram; + t_FmRevisionInfo fmRevInfo; uint8_t portId; e_FmPortType portType; int enabled; @@ -817,11 +902,10 @@ typedef struct { t_Handle ccTreeId; t_Handle completeArg; void (*f_Complete)(t_Handle arg); - t_FmPortBufferOffsets bufferOffsets; + t_FmSpBufferOffsets bufferOffsets; /* Independent-Mode parameters support */ bool imEn; t_FmMacIm im; - uint8_t txFifoDeqPipelineDepth; volatile bool lock; t_Handle h_Spinlock; t_FmPortExceptionCallback *f_Exception; @@ -830,23 +914,38 @@ typedef struct { uint8_t fmanCtrlEventId; uint32_t exceptions; bool polling; - uint8_t numOfTasks; - t_FmPortExtPools extBufPools; + t_FmExtPools extBufPools; uint32_t requiredAction; uint32_t savedQmiPnen; + uint32_t savedBmiFene; + uint32_t savedBmiFpne; + uint32_t savedBmiCmne; + uint32_t savedBmiOfp; uint32_t savedNonRxQmiRegsPndn; + uint32_t origNonRxQmiRegsPndn; int savedPrsStartOffset; + bool includeInPrsStatistics; + uint16_t maxFrameLength; + t_FmFmanCtrl orFmanCtrl; t_FmPortRsrc openDmas; t_FmPortRsrc tasks; t_FmPortRsrc fifoBufs; - t_FmInterModulePortRxPoolsParams rxPoolsParams; + t_FmPortRxPoolsParams rxPoolsParams; +// bool explicitUserSizeOfFifo; + t_Handle h_IpReassemblyManip; + t_Handle h_CapwapReassemblyManip; + t_Handle h_ReassemblyTree; + uint64_t fmMuramPhysBaseAddr; +#if (DPAA_VERSION >= 11) + bool vspe; + uint8_t dfltRelativeId; + e_FmPortGprFuncType gprFunc; + t_FmPcdCtrlParamsPage *p_ParamsPage; +#endif /* (DPAA_VERSION >= 11) */ + t_FmPortDsarVars deepSleepVars; t_FmPortDriverParam *p_FmPortDriverParam; } t_FmPort; -#define CHECK_FM_CTL_AC_POST_FETCH_PCD(savedBmiNia) \ - ((((savedBmiNia) & NIA_ENG_MASK) == NIA_ENG_FM_CTL) && \ - ((((savedBmiNia) & NIA_FM_CTL_AC_MASK) == NIA_FM_CTL_AC_POST_FETCH_PCD) || \ - (((savedBmiNia) & NIA_FM_CTL_AC_MASK) == NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN))) void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams); t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort); @@ -862,6 +961,10 @@ void FmPortSetMacsecLcv(t_Handle h_FmPort); void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci); +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas); +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks); +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); + static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd) { uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32); @@ -890,5 +993,7 @@ static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id) return 0; } +void FM_PORT_Dsar_DumpRegs(void); + #endif /* __FM_PORT_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_dsar.h b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_dsar.h new file mode 100755 index 000000000000..95619eff0bee --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_dsar.h @@ -0,0 +1,494 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/**************************************************************************//** + @File fm_port_dsar.h + + @Description Deep Sleep Auto Response project - common module header file. + + Author - Eyal Harari + + @Cautions See the FMan Controller spec and design document for more information. +*//***************************************************************************/ + +#ifndef __FM_PORT_DSAR_H_ +#define __FM_PORT_DSAR_H_ + +#define DSAR_GETSER_MASK 0xFF0000FF + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(push,1) +#endif /* defined(__MWERKS__) && ... */ + +/**************************************************************************//** + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ + uint16_t reserved; +} _PackedType t_DsarArpBindingEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor + Refer to the FMan Controller spec for more details. + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter + 0x04 ECHO_CNT Echo counter + 0x08 CD_CNT Conflict Detection counter + 0x0C AR_CNT Auto-Response counter + 0x10 RATM_CNT Replies Addressed To Me counter + 0x14 UKOP_CNT Unknown Operation counter + 0x18 NMTP_CNT Not my TPA counter + 0x1C NMVLAN_CNT Not My VLAN counter +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */ + uint32_t echoCnt; /**< Echo counter. */ + uint32_t cdCnt; /**< Conflict Detection counter. */ + uint32_t arCnt; /**< Auto-Response counter. */ + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */ + uint32_t ukopCnt; /**< Unknown Operation counter. */ + uint32_t nmtpCnt; /**< Not my TPA counter. */ + uint32_t nmVlanCnt; /**< Not My VLAN counter */ +} _PackedType t_DsarArpStatistics; + + +/**************************************************************************//** + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN. + 0x2 0-15 NumOfBindings Number of entries in the binding list. + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list. + 0x6 0-15 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure. + 0xA 0-15 + 0xC 0-15 Reserved Reserved. Must be cleared. + 0xE 015 + +*//***************************************************************************/ +typedef _Packed struct +{ + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */ + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */ + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ + uint32_t reserved1; /**< Reserved. */ +} _PackedType t_DsarArpDescriptor; + + +/**************************************************************************//** + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ + uint16_t reserved; +} _PackedType t_DsarIcmpV4BindingEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor + Refer to the FMan Controller spec for more details. + 0x00 INVAL_CNT Invalid ICMPv4 header counter + 0x04 NMVLAN_CNT Not My VLAN counter + 0x08 NMIP_CNT Not My IP counter + 0x0C AR_CNT Auto-Response counter + 0x10 CSERR_CNT Checksum Error counter + 0x14 Reserved Reserved + 0x18 Reserved Reserved + 0x1C Reserved Reserved + +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ + uint32_t nmVlanCnt; /**< Not My VLAN counter */ + uint32_t nmIpCnt; /**< Not My IP counter */ + uint32_t arCnt; /**< Auto-Response counter */ + uint32_t cserrCnt; /**< Checksum Error counter */ + uint32_t reserved0; /**< Reserved */ + uint32_t reserved1; /**< Reserved */ + uint32_t reserved2; /**< Reserved */ +} _PackedType t_DsarIcmpV4Statistics; + + + +/**************************************************************************//** + @Description Deep Sleep Auto Response ICMPv4 Descriptor + 0x0 0-15 Control bits [0-15] + 0x2 0-15 NumOfBindings Number of entries in the binding list. + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. + 0x6 0-15 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. + 0xA 0-15 + 0xC 0-15 Reserved Reserved. Must be cleared. + 0xE 015 + +*//***************************************************************************/ +typedef _Packed struct +{ + uint16_t control; /** Control bits [0-15]. */ + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */ + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ + uint32_t reserved1; /**< Reserved. */ +} _PackedType t_DsarIcmpV4Descriptor; + +/**************************************************************************//** + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) + The 4 left-most bits (15:12) of the VlanId parameter are control flags. + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared. + Flags[0] (VlanId[12]): Temporary address. + • 0 - Assigned IP address. + • 1- Temporary (tentative) IP address. + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */ + uint16_t resFlags:4; /*!< reserved flags. should be cleared */ + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */ + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */ + uint16_t reserved; +} _PackedType t_DsarIcmpV6BindingEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor + Refer to the FMan Controller spec for more details. + 0x00 INVAL_CNT Invalid ICMPv4 header counter + 0x04 NMVLAN_CNT Not My VLAN counter + 0x08 NMIP_CNT Not My IP counter + 0x0C AR_CNT Auto-Response counter + 0x10 CSERR_CNT Checksum Error counter + 0x14 MCAST_CNT Multicast counter + 0x18 Reserved Reserved + 0x1C Reserved Reserved + +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ + uint32_t nmVlanCnt; /**< Not My VLAN counter */ + uint32_t nmIpCnt; /**< Not My IP counter */ + uint32_t arCnt; /**< Auto-Response counter */ + uint32_t reserved1; /**< Reserved */ + uint32_t reserved2; /**< Reserved */ + uint32_t reserved3; /**< Reserved */ + uint32_t reserved4; /**< Reserved */ +} _PackedType t_DsarIcmpV6Statistics; + +/**************************************************************************//** + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter + 0x04 NMVLAN_CNT Not My VLAN counter + 0x08 NMIP_CNT Not My IP counter + 0x0C AR_CNT Auto-Response counter + 0x10 CSERR_CNT Checksum Error counter + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter + 0x18 NMMCAST_CNT Not My Multicast group counter + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target + Address of a packet that its source IP address is a unicast address, but the ICMPv6 + Source Link-layer Address option is omitted +*//***************************************************************************/ +typedef _Packed struct +{ + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ + uint32_t nmVlanCnt; /**< Not My VLAN counter */ + uint32_t nmIpCnt; /**< Not My IP counter */ + uint32_t arCnt; /**< Auto-Response counter */ + uint32_t reserved1; /**< Reserved */ + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */ + uint32_t nmmcastCnt; /**< Not My Multicast group counter */ + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */ +} _PackedType t_NdStatistics; + +/**************************************************************************//** + @Description Deep Sleep Auto Response ICMPv6 Descriptor + 0x0 0-15 Control bits [0-15] + 0x2 0-15 NumOfBindings Number of entries in the binding list. + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. + 0x6 0-15 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. + 0xA 0-15 + 0xC 0-15 Reserved Reserved. Must be cleared. + 0xE 015 + +*//***************************************************************************/ +typedef _Packed struct +{ + uint16_t control; /** Control bits [0-15]. */ + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */ + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ + uint32_t reserved1; /**< Reserved. */ +} _PackedType t_DsarIcmpV6Descriptor; + + +/**************************************************************************//** + @Description Internet Control Message Protocol (ICMPv6) Echo message header + The fields names are taken from RFC 4443. +*//***************************************************************************/ +/* 0 1 2 3 */ +/* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | Type | Code | Checksum | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | Identifier | Sequence Number | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | Data ... */ +/* +-+-+-+-+- */ +typedef _Packed struct +{ + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t identifier; + uint16_t sequenceNumber; +} _PackedType t_IcmpV6EchoHdr; + +/**************************************************************************//** + @Description Internet Control Message Protocol (ICMPv6) + Neighbor Solicitation/Advertisement header + The fields names are taken from RFC 4861. + The R/S/O fields are valid for Neighbor Advertisement only +*//***************************************************************************/ +/* 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Code | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |R|S|O| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | | + * + Target Address + + * | | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Options ... + * +-+-+-+-+-+-+-+-+-+-+-+- + * + * Options Format: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Link-Layer Address ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Link-Layer Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +typedef _Packed struct +{ + uint8_t type; + uint8_t code; + uint16_t checksum; + uint32_t router:1; + uint32_t solicited:1; + uint32_t override:1; + uint32_t reserved:29; + uint32_t targetAddr[4]; + uint8_t optionType; + uint8_t optionLength; + uint8_t linkLayerAddr[6]; +} _PackedType t_IcmpV6NdHdr; + +/**************************************************************************//** + @Description Deep Sleep Auto Response ICMPv6 Descriptor + 0x0 0-15 Control bits [0-15] + 0x2 0-15 NumOfBindings Number of entries in the binding list. + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. + 0x6 0-15 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. + 0xA 0-15 + 0xC 0-15 Reserved Reserved. Must be cleared. + 0xE 015 + +*//***************************************************************************/ +typedef _Packed struct +{ + uint16_t control; /** Control bits [0-15]. */ + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */ + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */ +} _PackedType t_DsarNdDescriptor; + +/**************************************************************************//** +@Description Deep Sleep Auto Response SNMP OIDs table entry + +*//***************************************************************************/ +typedef struct { + uint16_t oidSize; /**< Size in octets of the OID. */ + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */ + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */ + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */ + uint32_t reserved; +} t_OidsTblEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef struct +{ + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ + uint16_t reserved; +} t_DsarSnmpIpv4AddrTblEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +#pragma pack(push,1) +typedef struct +{ + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */ + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ + uint16_t reserved; +} t_DsarSnmpIpv6AddrTblEntry; +#pragma pack(pop) + +/**************************************************************************//** +@Description Deep Sleep Auto Response SNMP statistics table + +*//***************************************************************************/ +typedef struct { + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */ + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */ + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */ + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */ + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */ +} t_DsarSnmpStatistics; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP Descriptor + +*//***************************************************************************/ +typedef struct +{ + uint16_t control; /**< Control bits [0-15]. */ + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */ + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */ + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */ + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */ + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */ + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */ + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */ + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */ + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */ + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */ +} t_DsarSnmpDescriptor; + +/**************************************************************************//** +@Description Deep Sleep Auto Response (Common) Statistics + +*//***************************************************************************/ +typedef _Packed struct { + uint32_t dsarDiscarded; + uint32_t dsarErrDiscarded; + uint32_t dsarFragDiscarded; + uint32_t dsarTunnelDiscarded; + uint32_t dsarArpDiscarded; + uint32_t dsarIpDiscarded; + uint32_t dsarTcpDiscarded; + uint32_t dsarUdpDiscarded; + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */ + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */ + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */ +} _PackedType t_ArStatistics; + + +/**************************************************************************//** +@Description Deep Sleep Auto Response TCP/UDP port filter table entry + +*//***************************************************************************/ +typedef _Packed struct { + uint32_t Ports; + uint32_t PortsMask; +} _PackedType t_PortTblEntry; + + + +/**************************************************************************//** +@Description Deep Sleep Auto Response Common Parameters Descriptor + +*//***************************************************************************/ +typedef _Packed struct { + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */ + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */ + uint16_t res1; /* 0x00 16-31 Reserved */ + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */ + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */ + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */ + uint8_t res2; /* 0x10 0-7 Reserved */ + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */ + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */ + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */ + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */ + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */ + uint8_t res3; /* 0x14 24-31 Reserved */ + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */ + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */ + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */ + uint32_t res4; /* 0x24 Reserved */ + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */ + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */ + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */ + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */ + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */ + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */ +} _PackedType t_ArCommonDesc; + +#if defined(__MWERKS__) && !defined(__GNUC__) +#pragma pack(pop) +#endif /* defined(__MWERKS__) && ... */ + +/* t_ArCommonDesc.filterControl bits */ +#define IP_PROT_TBL_PASS_MASK 0x08 +#define UDP_PORT_TBL_PASS_MASK 0x04 +#define TCP_PORT_TBL_PASS_MASK 0x02 + +/* Offset of TCF flags within TCP packet */ +#define TCP_FLAGS_OFFSET 12 + + +#endif /* __FM_PORT_DSAR_H_ */ diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c index e79a61bb2d7f..8de8f5fd9ddb 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_port_im.c @@ -38,6 +39,7 @@ #include "std_ext.h" #include "string_ext.h" #include "error_ext.h" +#include "memcpy_ext.h" #include "fm_muram_ext.h" #include "fm_port.h" @@ -45,25 +47,6 @@ #define TX_CONF_STATUS_UNSENT 0x1 -#ifdef CORE_8BIT_ACCESS_ERRATA -#undef WRITE_UINT16 -#undef GET_UINT16 - -#define WRITE_UINT16(addr, val) \ - do{ \ - if((int)&(addr) % 4) \ - WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L), \ - ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val)); \ - else \ - WRITE_UINT32(*(uint32_t*)&addr, \ - ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16)); \ - }while(0); - -#define GET_UINT16(addr) (((uint32_t)&addr%4) ? \ - ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))): \ - ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16))) -#endif /* CORE_8BIT_ACCESS_ERRATA */ - typedef enum e_TxConfType { @@ -77,7 +60,7 @@ static void ImException(t_Handle h_FmPort, uint32_t event) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - ASSERT_COND(((event & IM_EV_RX) && FmIsMaster(p_FmPort->h_Fm)) || + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) || !FmIsMaster(p_FmPort->h_Fm)); if (event & IM_EV_RX) @@ -158,7 +141,7 @@ t_Error FmPortImRx(t_FmPort *p_FmPort) uint32_t bdStatus; volatile uint8_t buffPos; uint16_t length; - uint16_t errors/*, reportErrors*/; + uint16_t errors; uint8_t *p_CurData, *p_Data; uint32_t flags; @@ -186,7 +169,6 @@ t_Error FmPortImRx(t_FmPort *p_FmPort) if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID) p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId; - errors = 0; p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId)); h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]; length = (uint16_t)((bdStatus & BD_L) ? @@ -217,9 +199,8 @@ t_Error FmPortImRx(t_FmPort *p_FmPort) WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4)); /* Pass the buffer if one of the conditions is true: - There are no errors - - This is a part of a larger frame ( the application has already received some buffers ) - - There is an error, but it was defined to be passed anyway. */ - if ((buffPos != SINGLE_BUF) || !errors || (errors & (uint16_t)(BD_ERROR_PASS_FRAME>>16))) + - This is a part of a larger frame ( the application has already received some buffers ) */ + if ((buffPos != SINGLE_BUF) || !errors) { if (p_FmPort->im.f_RxStore(p_FmPort->h_App, p_CurData, @@ -282,7 +263,7 @@ void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams) if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize) DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr)); p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength; - p_FmPort->exceptions = DEFAULT_exception; + p_FmPort->exceptions = DEFAULT_PORT_exception; if (FmIsMaster(p_FmPort->h_Fm)) p_FmPort->polling = FALSE; else @@ -312,28 +293,8 @@ t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!")); if (p_FmPort->im.mrblr < 256) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!")); - if(p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK) + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); -#ifdef FM_PARTITION_ARRAY - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_FmPort->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - if(p_FmPort->p_FmPortDriverParam->liodnOffset >= MAX_LIODN_OFFSET) - { - p_FmPort->p_FmPortDriverParam->liodnOffset = - (uint16_t)(p_FmPort->p_FmPortDriverParam->liodnOffset & (MAX_LIODN_OFFSET-1)); - DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard.")); - } - } - } -#endif /* FM_PARTITION_ARRAY */ -/* TODO - add checks */ - } - else - { -/* TODO - add checks */ } return E_OK; @@ -362,7 +323,10 @@ t_Error FmPortImInit(t_FmPort *p_FmPort) if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) { - p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4); + p_FmPort->im.p_BdRing = + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), + p_FmPort->im.fwExtStructsMemId, + 4); if (!p_FmPort->im.p_BdRing) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!")); IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); @@ -392,7 +356,7 @@ t_Error FmPortImInit(t_FmPort *p_FmPort) WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr, (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - - p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x20)); + p_FmPort->fmMuramPhysBaseAddr + 0x20)); LOG2((uint64_t)p_FmPort->im.mrblr, log2Num); WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num); @@ -405,24 +369,24 @@ t_Error FmPortImInit(t_FmPort *p_FmPort) /* Update the IM PRAM address in the BMI */ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid, (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - - p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr)); + p_FmPort->fmMuramPhysBaseAddr)); if (!p_FmPort->polling || p_FmPort->exceptions) { /* Allocate, configure and register interrupts */ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK); tmpReg32 = 0; - if(p_FmPort->exceptions & IM_EV_BSY) + if (p_FmPort->exceptions & IM_EV_BSY) { tmpReg16 |= IM_RXQD_BSYINTM; tmpReg32 |= IM_EV_BSY; } - if(!p_FmPort->polling) + if (!p_FmPort->polling) { tmpReg16 |= IM_RXQD_RXFINTM; tmpReg32 |= IM_EV_RX; @@ -457,7 +421,7 @@ t_Error FmPortImInit(t_FmPort *p_FmPort) WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr, (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - - p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x40)); + p_FmPort->fmMuramPhysBaseAddr + 0x40)); /* Initialize Tx QD */ tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing)); @@ -467,7 +431,7 @@ t_Error FmPortImInit(t_FmPort *p_FmPort) /* Update the IM PRAM address in the BMI */ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid, (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - - p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr)); + p_FmPort->fmMuramPhysBaseAddr)); } @@ -593,7 +557,7 @@ t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort) SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only")); if (!FmIsMaster(p_FmPort->h_Fm)) @@ -616,16 +580,16 @@ t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); - if(exception == e_FM_PORT_EXCEPTION_IM_BUSY) + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY) { - if(enable) + if (enable) { p_FmPort->exceptions |= IM_EV_BSY; - if(p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ) + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ) { /* Allocate, configure and register interrupts */ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); - if(err) + if (err) RETURN_ERROR(MAJOR, err, NO_MSG); ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fman_port.c b/sys/contrib/ncsw/Peripherals/FM/Port/fman_port.c new file mode 100755 index 000000000000..df86ec3dc378 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fman_port.c @@ -0,0 +1,1568 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "common/general.h" + +#include "fman_common.h" +#include "fsl_fman_port.h" + + +/* problem Eyal: the following should not be here*/ +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028 + +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg) +{ + if (cfg->errata_A006675) + return NIA_ENG_FM_CTL | + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME; + else + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME; +} + +static int init_bmi_rx(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params) +{ + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; + uint32_t tmp; + + /* Rx Configuration register */ + tmp = 0; + if (port->im_en) + tmp |= BMI_PORT_CFG_IM; + else if (cfg->discard_override) + tmp |= BMI_PORT_CFG_FDOVR; + iowrite32be(tmp, ®s->fmbm_rcfg); + + /* DMA attributes */ + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; + if (cfg->dma_ic_stash_on) + tmp |= BMI_DMA_ATTR_IC_STASH_ON; + if (cfg->dma_header_stash_on) + tmp |= BMI_DMA_ATTR_HDR_STASH_ON; + if (cfg->dma_sg_stash_on) + tmp |= BMI_DMA_ATTR_SG_STASH_ON; + if (cfg->dma_write_optimize) + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE; + iowrite32be(tmp, ®s->fmbm_rda); + + /* Rx FIFO parameters */ + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) << + BMI_RX_FIFO_PRI_ELEVATION_SHIFT; + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1; + iowrite32be(tmp, ®s->fmbm_rfp); + + if (cfg->excessive_threshold_register) + /* always allow access to the extra resources */ + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, ®s->fmbm_reth); + + /* Frame end data */ + tmp = (uint32_t)cfg->checksum_bytes_ignore << + BMI_RX_FRAME_END_CS_IGNORE_SHIFT; + tmp |= (uint32_t)cfg->rx_cut_end_bytes << + BMI_RX_FRAME_END_CUT_SHIFT; + if (cfg->errata_A006320) + tmp &= 0xffe0ffff; + iowrite32be(tmp, ®s->fmbm_rfed); + + /* Internal context parameters */ + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_TO_EXT_SHIFT; + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_FROM_INT_SHIFT; + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; + iowrite32be(tmp, ®s->fmbm_ricp); + + /* Internal buffer offset */ + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS) + << BMI_INT_BUF_MARG_SHIFT; + iowrite32be(tmp, ®s->fmbm_rim); + + /* External buffer margins */ + if (!port->im_en) + { + tmp = (uint32_t)cfg->ext_buf_start_margin << + BMI_EXT_BUF_MARG_START_SHIFT; + tmp |= (uint32_t)cfg->ext_buf_end_margin; + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather) + tmp |= BMI_SG_DISABLE; + iowrite32be(tmp, ®s->fmbm_rebm); + } + + /* Frame attributes */ + tmp = BMI_CMD_RX_MR_DEF; + if (!port->im_en) + { + tmp |= BMI_CMD_ATTR_ORDER; + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; + if (cfg->sync_req) + tmp |= BMI_CMD_ATTR_SYNC; + } + iowrite32be(tmp, ®s->fmbm_rfca); + + /* NIA */ + if (port->im_en) + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX; + else + { + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT; + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg); + } + iowrite32be(tmp, ®s->fmbm_rfne); + + /* Enqueue NIA */ + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_rfene); + + /* Default/error queues */ + if (!port->im_en) + { + iowrite32be((params->dflt_fqid & 0x00FFFFFF), ®s->fmbm_rfqid); + iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_refqid); + } + + /* Discard/error masks */ + iowrite32be(params->discard_mask, ®s->fmbm_rfsdm); + iowrite32be(params->err_mask, ®s->fmbm_rfsem); + + /* Statistics counters */ + tmp = 0; + if (cfg->stats_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_rstc); + + /* Performance counters */ + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); + tmp = 0; + if (cfg->perf_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_rpc); + + return 0; +} + +static int init_bmi_tx(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params) +{ + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; + uint32_t tmp; + + /* Tx Configuration register */ + tmp = 0; + if (port->im_en) + tmp |= BMI_PORT_CFG_IM; + iowrite32be(tmp, ®s->fmbm_tcfg); + + /* DMA attributes */ + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; + if (cfg->dma_ic_stash_on) + tmp |= BMI_DMA_ATTR_IC_STASH_ON; + if (cfg->dma_header_stash_on) + tmp |= BMI_DMA_ATTR_HDR_STASH_ON; + if (cfg->dma_sg_stash_on) + tmp |= BMI_DMA_ATTR_SG_STASH_ON; + iowrite32be(tmp, ®s->fmbm_tda); + + /* Tx FIFO parameters */ + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) << + BMI_TX_FIFO_MIN_FILL_SHIFT; + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) << + BMI_FIFO_PIPELINE_DEPTH_SHIFT; + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level / + FMAN_PORT_BMI_FIFO_UNITS - 1); + iowrite32be(tmp, ®s->fmbm_tfp); + + /* Frame end data */ + tmp = (uint32_t)cfg->checksum_bytes_ignore << + BMI_FRAME_END_CS_IGNORE_SHIFT; + iowrite32be(tmp, ®s->fmbm_tfed); + + /* Internal context parameters */ + if (!port->im_en) + { + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_TO_EXT_SHIFT; + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_FROM_INT_SHIFT; + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; + iowrite32be(tmp, ®s->fmbm_ticp); + } + /* Frame attributes */ + tmp = BMI_CMD_TX_MR_DEF; + if (port->im_en) + tmp |= BMI_CMD_MR_DEAS; + else + { + tmp |= BMI_CMD_ATTR_ORDER; + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; + } + iowrite32be(tmp, ®s->fmbm_tfca); + + /* Dequeue NIA + enqueue NIA */ + if (port->im_en) + { + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, ®s->fmbm_tfdne); + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, ®s->fmbm_tfene); + } + else + { + iowrite32be(NIA_ENG_QMI_DEQ, ®s->fmbm_tfdne); + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_tfene); + if (cfg->fmbm_tfne_has_features) + iowrite32be(!params->dflt_fqid ? + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME : + NIA_BMI_AC_FETCH_ALL_FRAME, ®s->fmbm_tfne); + if (!params->dflt_fqid && params->dont_release_buf) + { + iowrite32be(0x00FFFFFF, ®s->fmbm_tcfqid); + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, ®s->fmbm_tfene); + if (cfg->fmbm_tfne_has_features) + iowrite32be(ioread32be(®s->fmbm_tfne) & ~BMI_EBD_EN, ®s->fmbm_tfne); + } + } + + /* Confirmation/error queues */ + if (!port->im_en) + { + if (params->dflt_fqid || !params->dont_release_buf) + iowrite32be(params->dflt_fqid & 0x00FFFFFF, ®s->fmbm_tcfqid); + iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_tefqid); + } + /* Statistics counters */ + tmp = 0; + if (cfg->stats_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_tstc); + + /* Performance counters */ + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); + tmp = 0; + if (cfg->perf_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_tpc); + + return 0; +} + +static int init_bmi_oh(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params) +{ + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; + uint32_t tmp; + + /* OP Configuration register */ + tmp = 0; + if (cfg->discard_override) + tmp |= BMI_PORT_CFG_FDOVR; + iowrite32be(tmp, ®s->fmbm_ocfg); + + /* DMA attributes */ + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; + if (cfg->dma_ic_stash_on) + tmp |= BMI_DMA_ATTR_IC_STASH_ON; + if (cfg->dma_header_stash_on) + tmp |= BMI_DMA_ATTR_HDR_STASH_ON; + if (cfg->dma_sg_stash_on) + tmp |= BMI_DMA_ATTR_SG_STASH_ON; + if (cfg->dma_write_optimize) + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE; + iowrite32be(tmp, ®s->fmbm_oda); + + /* Tx FIFO parameters */ + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) << + BMI_FIFO_PIPELINE_DEPTH_SHIFT; + iowrite32be(tmp, ®s->fmbm_ofp); + + /* Internal context parameters */ + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_TO_EXT_SHIFT; + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << + BMI_IC_FROM_INT_SHIFT; + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; + iowrite32be(tmp, ®s->fmbm_oicp); + + /* Frame attributes */ + tmp = BMI_CMD_OP_MR_DEF; + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; + if (cfg->sync_req) + tmp |= BMI_CMD_ATTR_SYNC; + if (port->type == E_FMAN_PORT_TYPE_OP) + tmp |= BMI_CMD_ATTR_ORDER; + iowrite32be(tmp, ®s->fmbm_ofca); + + /* Internal buffer offset */ + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS) + << BMI_INT_BUF_MARG_SHIFT; + iowrite32be(tmp, ®s->fmbm_oim); + + /* Dequeue NIA */ + iowrite32be(NIA_ENG_QMI_DEQ, ®s->fmbm_ofdne); + + /* NIA and Enqueue NIA */ + if (port->type == E_FMAN_PORT_TYPE_HC) { + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC, + ®s->fmbm_ofne); + iowrite32be(NIA_ENG_QMI_ENQ, ®s->fmbm_ofene); + } else { + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg), + ®s->fmbm_ofne); + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, + ®s->fmbm_ofene); + } + + /* Default/error queues */ + iowrite32be((params->dflt_fqid & 0x00FFFFFF), ®s->fmbm_ofqid); + iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_oefqid); + + /* Discard/error masks */ + if (port->type == E_FMAN_PORT_TYPE_OP) { + iowrite32be(params->discard_mask, ®s->fmbm_ofsdm); + iowrite32be(params->err_mask, ®s->fmbm_ofsem); + } + + /* Statistics counters */ + tmp = 0; + if (cfg->stats_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_ostc); + + /* Performance counters */ + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); + tmp = 0; + if (cfg->perf_counters_enable) + tmp = BMI_COUNTERS_EN; + iowrite32be(tmp, ®s->fmbm_opc); + + return 0; +} + +static int init_qmi(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params) +{ + struct fman_port_qmi_regs *regs = port->qmi_regs; + uint32_t tmp; + + tmp = 0; + if (cfg->queue_counters_enable) + tmp |= QMI_PORT_CFG_EN_COUNTERS; + iowrite32be(tmp, ®s->fmqm_pnc); + + /* Rx port configuration */ + if ((port->type == E_FMAN_PORT_TYPE_RX) || + (port->type == E_FMAN_PORT_TYPE_RX_10G)) { + /* Enqueue NIA */ + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, ®s->fmqm_pnen); + return 0; + } + + /* Continue with Tx and O/H port configuration */ + if ((port->type == E_FMAN_PORT_TYPE_TX) || + (port->type == E_FMAN_PORT_TYPE_TX_10G)) { + /* Enqueue NIA */ + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, + ®s->fmqm_pnen); + /* Dequeue NIA */ + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, ®s->fmqm_pndn); + } else { + /* Enqueue NIA */ + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, ®s->fmqm_pnen); + /* Dequeue NIA */ + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, ®s->fmqm_pndn); + } + + /* Dequeue Configuration register */ + tmp = 0; + if (cfg->deq_high_pri) + tmp |= QMI_DEQ_CFG_PRI; + + switch (cfg->deq_type) { + case E_FMAN_PORT_DEQ_BY_PRI: + tmp |= QMI_DEQ_CFG_TYPE1; + break; + case E_FMAN_PORT_DEQ_ACTIVE_FQ: + tmp |= QMI_DEQ_CFG_TYPE2; + break; + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS: + tmp |= QMI_DEQ_CFG_TYPE3; + break; + default: + return -EINVAL; + } + + if (cfg->qmi_deq_options_support) { + if ((port->type == E_FMAN_PORT_TYPE_HC) && + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH)) + return -EINVAL; + + switch (cfg->deq_prefetch_opt) { + case E_FMAN_PORT_DEQ_NO_PREFETCH: + break; + case E_FMAN_PORT_DEQ_PART_PREFETCH: + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL; + break; + case E_FMAN_PORT_DEQ_FULL_PREFETCH: + tmp |= QMI_DEQ_CFG_PREFETCH_FULL; + break; + default: + return -EINVAL; + } + } + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) << + QMI_DEQ_CFG_SP_SHIFT; + tmp |= cfg->deq_byte_cnt; + iowrite32be(tmp, ®s->fmqm_pndc); + + return 0; +} + +static void get_rx_stats_reg(struct fman_port *port, + enum fman_port_stats_counters counter, + uint32_t **stats_reg) +{ + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; + + switch (counter) { + case E_FMAN_PORT_STATS_CNT_FRAME: + *stats_reg = ®s->fmbm_rfrc; + break; + case E_FMAN_PORT_STATS_CNT_DISCARD: + *stats_reg = ®s->fmbm_rfdc; + break; + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: + *stats_reg = ®s->fmbm_rbdc; + break; + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME: + *stats_reg = ®s->fmbm_rfbc; + break; + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME: + *stats_reg = ®s->fmbm_rlfc; + break; + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF: + *stats_reg = ®s->fmbm_rodc; + break; + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME: + *stats_reg = ®s->fmbm_rffc; + break; + case E_FMAN_PORT_STATS_CNT_DMA_ERR: + *stats_reg = ®s->fmbm_rfldec; + break; + default: + *stats_reg = NULL; + } +} + +static void get_tx_stats_reg(struct fman_port *port, + enum fman_port_stats_counters counter, + uint32_t **stats_reg) +{ + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; + + switch (counter) { + case E_FMAN_PORT_STATS_CNT_FRAME: + *stats_reg = ®s->fmbm_tfrc; + break; + case E_FMAN_PORT_STATS_CNT_DISCARD: + *stats_reg = ®s->fmbm_tfdc; + break; + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: + *stats_reg = ®s->fmbm_tbdc; + break; + case E_FMAN_PORT_STATS_CNT_LEN_ERR: + *stats_reg = ®s->fmbm_tfledc; + break; + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT: + *stats_reg = ®s->fmbm_tfufdc; + break; + default: + *stats_reg = NULL; + } +} + +static void get_oh_stats_reg(struct fman_port *port, + enum fman_port_stats_counters counter, + uint32_t **stats_reg) +{ + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; + + switch (counter) { + case E_FMAN_PORT_STATS_CNT_FRAME: + *stats_reg = ®s->fmbm_ofrc; + break; + case E_FMAN_PORT_STATS_CNT_DISCARD: + *stats_reg = ®s->fmbm_ofdc; + break; + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: + *stats_reg = ®s->fmbm_obdc; + break; + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME: + *stats_reg = ®s->fmbm_offc; + break; + case E_FMAN_PORT_STATS_CNT_DMA_ERR: + *stats_reg = ®s->fmbm_ofldec; + break; + case E_FMAN_PORT_STATS_CNT_LEN_ERR: + *stats_reg = ®s->fmbm_ofledc; + break; + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT: + *stats_reg = ®s->fmbm_ofufdc; + break; + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD: + *stats_reg = ®s->fmbm_ofwdc; + break; + default: + *stats_reg = NULL; + } +} + +static void get_rx_perf_reg(struct fman_port *port, + enum fman_port_perf_counters counter, + uint32_t **perf_reg) +{ + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; + + switch (counter) { + case E_FMAN_PORT_PERF_CNT_CYCLE: + *perf_reg = ®s->fmbm_rccn; + break; + case E_FMAN_PORT_PERF_CNT_TASK_UTIL: + *perf_reg = ®s->fmbm_rtuc; + break; + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL: + *perf_reg = ®s->fmbm_rrquc; + break; + case E_FMAN_PORT_PERF_CNT_DMA_UTIL: + *perf_reg = ®s->fmbm_rduc; + break; + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: + *perf_reg = ®s->fmbm_rfuc; + break; + case E_FMAN_PORT_PERF_CNT_RX_PAUSE: + *perf_reg = ®s->fmbm_rpac; + break; + default: + *perf_reg = NULL; + } +} + +static void get_tx_perf_reg(struct fman_port *port, + enum fman_port_perf_counters counter, + uint32_t **perf_reg) +{ + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; + + switch (counter) { + case E_FMAN_PORT_PERF_CNT_CYCLE: + *perf_reg = ®s->fmbm_tccn; + break; + case E_FMAN_PORT_PERF_CNT_TASK_UTIL: + *perf_reg = ®s->fmbm_ttuc; + break; + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL: + *perf_reg = ®s->fmbm_ttcquc; + break; + case E_FMAN_PORT_PERF_CNT_DMA_UTIL: + *perf_reg = ®s->fmbm_tduc; + break; + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: + *perf_reg = ®s->fmbm_tfuc; + break; + default: + *perf_reg = NULL; + } +} + +static void get_oh_perf_reg(struct fman_port *port, + enum fman_port_perf_counters counter, + uint32_t **perf_reg) +{ + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; + + switch (counter) { + case E_FMAN_PORT_PERF_CNT_CYCLE: + *perf_reg = ®s->fmbm_occn; + break; + case E_FMAN_PORT_PERF_CNT_TASK_UTIL: + *perf_reg = ®s->fmbm_otuc; + break; + case E_FMAN_PORT_PERF_CNT_DMA_UTIL: + *perf_reg = ®s->fmbm_oduc; + break; + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: + *perf_reg = ®s->fmbm_ofuc; + break; + default: + *perf_reg = NULL; + } +} + +static void get_qmi_counter_reg(struct fman_port *port, + enum fman_port_qmi_counters counter, + uint32_t **queue_reg) +{ + struct fman_port_qmi_regs *regs = port->qmi_regs; + + switch (counter) { + case E_FMAN_PORT_ENQ_TOTAL: + *queue_reg = ®s->fmqm_pnetfc; + break; + case E_FMAN_PORT_DEQ_TOTAL: + if ((port->type == E_FMAN_PORT_TYPE_RX) || + (port->type == E_FMAN_PORT_TYPE_RX_10G)) + /* Counter not available for Rx ports */ + *queue_reg = NULL; + else + *queue_reg = ®s->fmqm_pndtfc; + break; + case E_FMAN_PORT_DEQ_FROM_DFLT: + if ((port->type == E_FMAN_PORT_TYPE_RX) || + (port->type == E_FMAN_PORT_TYPE_RX_10G)) + /* Counter not available for Rx ports */ + *queue_reg = NULL; + else + *queue_reg = ®s->fmqm_pndfdc; + break; + case E_FMAN_PORT_DEQ_CONFIRM: + if ((port->type == E_FMAN_PORT_TYPE_RX) || + (port->type == E_FMAN_PORT_TYPE_RX_10G)) + /* Counter not available for Rx ports */ + *queue_reg = NULL; + else + *queue_reg = ®s->fmqm_pndcc; + break; + default: + *queue_reg = NULL; + } +} + +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type) +{ + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP; + cfg->dma_ic_stash_on = FALSE; + cfg->dma_header_stash_on = FALSE; + cfg->dma_sg_stash_on = FALSE; + cfg->dma_write_optimize = TRUE; + cfg->color = E_FMAN_PORT_COLOR_GREEN; + cfg->discard_override = FALSE; + cfg->checksum_bytes_ignore = 0; + cfg->rx_cut_end_bytes = 4; + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS); + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS); + cfg->rx_fd_bits = 0; + cfg->ic_ext_offset = 0; + cfg->ic_int_offset = 0; + cfg->ic_size = 0; + cfg->int_buf_start_margin = 0; + cfg->ext_buf_start_margin = 0; + cfg->ext_buf_end_margin = 0; + cfg->tx_fifo_min_level = 0; + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE); + cfg->stats_counters_enable = TRUE; + cfg->perf_counters_enable = TRUE; + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI; + + if (type == E_FMAN_PORT_TYPE_HC) { + cfg->sync_req = FALSE; + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH; + } else { + cfg->sync_req = TRUE; + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH; + } + + if (type == E_FMAN_PORT_TYPE_TX_10G) { + cfg->tx_fifo_deq_pipeline_depth = 4; + cfg->deq_high_pri = TRUE; + cfg->deq_byte_cnt = 0x1400; + } else { + if ((type == E_FMAN_PORT_TYPE_HC) || + (type == E_FMAN_PORT_TYPE_OP)) + cfg->tx_fifo_deq_pipeline_depth = 2; + else + cfg->tx_fifo_deq_pipeline_depth = 1; + + cfg->deq_high_pri = FALSE; + cfg->deq_byte_cnt = 0x400; + } + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER; +} + +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid) +{ + uint32_t *bp_reg, tmp; + uint8_t i, id; + + /* Find the pool */ + bp_reg = port->bmi_regs->rx.fmbm_ebmpi; + for (i = 0; + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM)); + i++) { + tmp = ioread32be(&bp_reg[i]); + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >> + BMI_EXT_BUF_POOL_ID_SHIFT); + + if (id == bpid) + break; + } + + return i; +} + +int fman_port_init(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params) +{ + int err; + + /* Init BMI registers */ + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + err = init_bmi_rx(port, cfg, params); + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + err = init_bmi_tx(port, cfg, params); + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + err = init_bmi_oh(port, cfg, params); + break; + default: + return -EINVAL; + } + + if (err) + return err; + + /* Init QMI registers */ + if (!port->im_en) + { + err = init_qmi(port, cfg, params); + return err; + } + return 0; +} + +int fman_port_enable(struct fman_port *port) +{ + uint32_t *bmi_cfg_reg, tmp; + bool rx_port; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg; + rx_port = TRUE; + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg; + rx_port = FALSE; + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg; + rx_port = FALSE; + break; + default: + return -EINVAL; + } + + /* Enable QMI */ + if (!rx_port) { + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN; + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); + } + + /* Enable BMI */ + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN; + iowrite32be(tmp, bmi_cfg_reg); + + return 0; +} + +int fman_port_disable(const struct fman_port *port) +{ + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp; + bool rx_port, failure = FALSE; + int count; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg; + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst; + rx_port = TRUE; + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg; + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst; + rx_port = FALSE; + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg; + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost; + rx_port = FALSE; + break; + default: + return -EINVAL; + } + + /* Disable QMI */ + if (!rx_port) { + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN; + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); + + /* Wait for QMI to finish FD handling */ + count = 100; + do { + DELAY(10); + tmp = ioread32be(&port->qmi_regs->fmqm_pns); + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count); + + if (count == 0) + { + /* Timeout */ + failure = TRUE; + } + } + + /* Disable BMI */ + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN; + iowrite32be(tmp, bmi_cfg_reg); + + /* Wait for graceful stop end */ + count = 500; + do { + DELAY(10); + tmp = ioread32be(bmi_status_reg); + } while ((tmp & BMI_PORT_STATUS_BSY) && --count); + + if (count == 0) + { + /* Timeout */ + failure = TRUE; + } + + if (failure) + return -EBUSY; + + return 0; +} + +int fman_port_set_bpools(const struct fman_port *port, + const struct fman_port_bpools *bp) +{ + uint32_t tmp, *bp_reg, *bp_depl_reg; + uint8_t i, max_bp_num; + bool grp_depl_used = FALSE, rx_port; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + max_bp_num = port->ext_pools_num; + rx_port = TRUE; + bp_reg = port->bmi_regs->rx.fmbm_ebmpi; + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd; + break; + case E_FMAN_PORT_TYPE_OP: + if (port->fm_rev_maj != 4) + return -EINVAL; + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM; + rx_port = FALSE; + bp_reg = port->bmi_regs->oh.fmbm_oebmpi; + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd; + break; + default: + return -EINVAL; + } + + if (rx_port) { + /* Check buffers are provided in ascending order */ + for (i = 0; + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1)); + i++) { + if (bp->bpool[i].size > bp->bpool[i+1].size) + return -EINVAL; + } + } + + /* Set up external buffers pools */ + for (i = 0; i < bp->count; i++) { + tmp = BMI_EXT_BUF_POOL_VALID; + tmp |= ((uint32_t)bp->bpool[i].bpid << + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK; + + if (rx_port) { + if (bp->counters_enable) + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER; + + if (bp->bpool[i].is_backup) + tmp |= BMI_EXT_BUF_POOL_BACKUP; + + tmp |= (uint32_t)bp->bpool[i].size; + } + + iowrite32be(tmp, &bp_reg[i]); + } + + /* Clear unused pools */ + for (i = bp->count; i < max_bp_num; i++) + iowrite32be(0, &bp_reg[i]); + + /* Pools depletion */ + tmp = 0; + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) { + if (bp->bpool[i].grp_bp_depleted) { + grp_depl_used = TRUE; + tmp |= 0x80000000 >> i; + } + + if (bp->bpool[i].single_bp_depleted) + tmp |= 0x80 >> i; + + if (bp->bpool[i].pfc_priorities_en) + tmp |= 0x0100 << i; + } + + if (grp_depl_used) + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) << + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT; + + iowrite32be(tmp, bp_depl_reg); + return 0; +} + +int fman_port_set_rate_limiter(struct fman_port *port, + struct fman_port_rate_limiter *rate_limiter) +{ + uint32_t *rate_limit_reg, *rate_limit_scale_reg; + uint32_t granularity, tmp; + uint8_t usec_bit, factor; + + switch (port->type) { + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt; + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts; + granularity = BMI_RATE_LIMIT_GRAN_TX; + break; + case E_FMAN_PORT_TYPE_OP: + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt; + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts; + granularity = BMI_RATE_LIMIT_GRAN_OP; + break; + default: + return -EINVAL; + } + + /* Factor is per 1 usec count */ + factor = 1; + usec_bit = rate_limiter->count_1micro_bit; + + /* If rate limit is too small for an 1usec factor, adjust timestamp + * scale and multiply the factor */ + while (rate_limiter->rate < (granularity / factor)) { + if (usec_bit == 31) + /* Can't configure rate limiter - rate is too small */ + return -EINVAL; + + usec_bit++; + factor <<= 1; + } + + /* Figure out register value. The "while" above quarantees that + * (rate_limiter->rate * factor / granularity) >= 1 */ + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1); + + /* Check rate limit isn't too large */ + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS) + return -EINVAL; + + /* Check burst size is in allowed range */ + if ((rate_limiter->burst_size == 0) || + (rate_limiter->burst_size > + BMI_RATE_LIMIT_MAX_BURST_SIZE)) + return -EINVAL; + + tmp |= (uint32_t)(rate_limiter->burst_size - 1) << + BMI_RATE_LIMIT_MAX_BURST_SHIFT; + + if ((port->type == E_FMAN_PORT_TYPE_OP) && + (port->fm_rev_maj == 4)) { + if (rate_limiter->high_burst_size_gran) + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN; + } + + iowrite32be(tmp, rate_limit_reg); + + /* Set up rate limiter scale register */ + tmp = BMI_RATE_LIMIT_SCALE_EN; + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT; + + if ((port->type == E_FMAN_PORT_TYPE_OP) && + (port->fm_rev_maj == 4)) + tmp |= rate_limiter->rate_factor; + + iowrite32be(tmp, rate_limit_scale_reg); + + return 0; +} + +int fman_port_delete_rate_limiter(struct fman_port *port) +{ + uint32_t *rate_limit_scale_reg; + + switch (port->type) { + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts; + break; + case E_FMAN_PORT_TYPE_OP: + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts; + break; + default: + return -EINVAL; + } + + iowrite32be(0, rate_limit_scale_reg); + return 0; +} + +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask) +{ + uint32_t *err_mask_reg; + + /* Obtain register address */ + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem; + break; + case E_FMAN_PORT_TYPE_OP: + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem; + break; + default: + return -EINVAL; + } + + iowrite32be(err_mask, err_mask_reg); + return 0; +} + +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask) +{ + uint32_t *discard_mask_reg; + + /* Obtain register address */ + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm; + break; + case E_FMAN_PORT_TYPE_OP: + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm; + break; + default: + return -EINVAL; + } + + iowrite32be(discard_mask, discard_mask_reg); + return 0; +} + +int fman_port_modify_rx_fd_bits(struct fman_port *port, + uint8_t rx_fd_bits, + bool add) +{ + uint32_t tmp; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + break; + default: + return -EINVAL; + } + + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne); + + if (add) + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT; + else + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT); + + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne); + return 0; +} + +int fman_port_set_perf_cnt_params(struct fman_port *port, + struct fman_port_perf_cnt_params *params) +{ + uint32_t *pcp_reg, tmp; + + /* Obtain register address and check parameters are in range */ + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp; + if ((params->queue_val == 0) || + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP)) + return -EINVAL; + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp; + if ((params->queue_val == 0) || + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP)) + return -EINVAL; + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + pcp_reg = &port->bmi_regs->oh.fmbm_opcp; + if (params->queue_val != 0) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if ((params->task_val == 0) || + (params->task_val > MAX_PERFORMANCE_TASK_COMP)) + return -EINVAL; + if ((params->dma_val == 0) || + (params->dma_val > MAX_PERFORMANCE_DMA_COMP)) + return -EINVAL; + if ((params->fifo_val == 0) || + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) > + MAX_PERFORMANCE_FIFO_COMP)) + return -EINVAL; + tmp = (uint32_t)(params->task_val - 1) << + BMI_PERFORMANCE_TASK_COMP_SHIFT; + tmp |= (uint32_t)(params->dma_val - 1) << + BMI_PERFORMANCE_DMA_COMP_SHIFT; + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1); + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + tmp |= (uint32_t)(params->queue_val - 1) << + BMI_PERFORMANCE_QUEUE_COMP_SHIFT; + break; + default: + break; + } + + + iowrite32be(tmp, pcp_reg); + return 0; +} + +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable) +{ + uint32_t *stats_reg, tmp; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + stats_reg = &port->bmi_regs->rx.fmbm_rstc; + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + stats_reg = &port->bmi_regs->tx.fmbm_tstc; + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + stats_reg = &port->bmi_regs->oh.fmbm_ostc; + break; + default: + return -EINVAL; + } + + tmp = ioread32be(stats_reg); + + if (enable) + tmp |= BMI_COUNTERS_EN; + else + tmp &= ~BMI_COUNTERS_EN; + + iowrite32be(tmp, stats_reg); + return 0; +} + +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable) +{ + uint32_t *stats_reg, tmp; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + stats_reg = &port->bmi_regs->rx.fmbm_rpc; + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + stats_reg = &port->bmi_regs->tx.fmbm_tpc; + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + stats_reg = &port->bmi_regs->oh.fmbm_opc; + break; + default: + return -EINVAL; + } + + tmp = ioread32be(stats_reg); + + if (enable) + tmp |= BMI_COUNTERS_EN; + else + tmp &= ~BMI_COUNTERS_EN; + + iowrite32be(tmp, stats_reg); + return 0; +} + +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable) +{ + uint32_t tmp; + + tmp = ioread32be(&port->qmi_regs->fmqm_pnc); + + if (enable) + tmp |= QMI_PORT_CFG_EN_COUNTERS; + else + tmp &= ~QMI_PORT_CFG_EN_COUNTERS; + + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); + return 0; +} + +int fman_port_set_bpool_cnt_mode(struct fman_port *port, + uint8_t bpid, + bool enable) +{ + uint8_t index; + uint32_t tmp; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + break; + default: + return -EINVAL; + } + + /* Find the pool */ + index = fman_port_find_bpool(port, bpid); + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) + /* Not found */ + return -EINVAL; + + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]); + + if (enable) + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER; + else + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER; + + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]); + return 0; +} + +uint32_t fman_port_get_stats_counter(struct fman_port *port, + enum fman_port_stats_counters counter) +{ + uint32_t *stats_reg, ret_val; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + get_rx_stats_reg(port, counter, &stats_reg); + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + get_tx_stats_reg(port, counter, &stats_reg); + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + get_oh_stats_reg(port, counter, &stats_reg); + break; + default: + stats_reg = NULL; + } + + if (stats_reg == NULL) + return 0; + + ret_val = ioread32be(stats_reg); + return ret_val; +} + +void fman_port_set_stats_counter(struct fman_port *port, + enum fman_port_stats_counters counter, + uint32_t value) +{ + uint32_t *stats_reg; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + get_rx_stats_reg(port, counter, &stats_reg); + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + get_tx_stats_reg(port, counter, &stats_reg); + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + get_oh_stats_reg(port, counter, &stats_reg); + break; + default: + stats_reg = NULL; + } + + if (stats_reg == NULL) + return; + + iowrite32be(value, stats_reg); +} + +uint32_t fman_port_get_perf_counter(struct fman_port *port, + enum fman_port_perf_counters counter) +{ + uint32_t *perf_reg, ret_val; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + get_rx_perf_reg(port, counter, &perf_reg); + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + get_tx_perf_reg(port, counter, &perf_reg); + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + get_oh_perf_reg(port, counter, &perf_reg); + break; + default: + perf_reg = NULL; + } + + if (perf_reg == NULL) + return 0; + + ret_val = ioread32be(perf_reg); + return ret_val; +} + +void fman_port_set_perf_counter(struct fman_port *port, + enum fman_port_perf_counters counter, + uint32_t value) +{ + uint32_t *perf_reg; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + get_rx_perf_reg(port, counter, &perf_reg); + break; + case E_FMAN_PORT_TYPE_TX: + case E_FMAN_PORT_TYPE_TX_10G: + get_tx_perf_reg(port, counter, &perf_reg); + break; + case E_FMAN_PORT_TYPE_OP: + case E_FMAN_PORT_TYPE_HC: + get_oh_perf_reg(port, counter, &perf_reg); + break; + default: + perf_reg = NULL; + } + + if (perf_reg == NULL) + return; + + iowrite32be(value, perf_reg); +} + +uint32_t fman_port_get_qmi_counter(struct fman_port *port, + enum fman_port_qmi_counters counter) +{ + uint32_t *queue_reg, ret_val; + + get_qmi_counter_reg(port, counter, &queue_reg); + + if (queue_reg == NULL) + return 0; + + ret_val = ioread32be(queue_reg); + return ret_val; +} + +void fman_port_set_qmi_counter(struct fman_port *port, + enum fman_port_qmi_counters counter, + uint32_t value) +{ + uint32_t *queue_reg; + + get_qmi_counter_reg(port, counter, &queue_reg); + + if (queue_reg == NULL) + return; + + iowrite32be(value, queue_reg); +} + +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid) +{ + uint8_t index; + uint32_t ret_val; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + break; + default: + return 0; + } + + /* Find the pool */ + index = fman_port_find_bpool(port, bpid); + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) + /* Not found */ + return 0; + + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]); + return ret_val; +} + +void fman_port_set_bpool_counter(struct fman_port *port, + uint8_t bpid, + uint32_t value) +{ + uint8_t index; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + break; + default: + return; + } + + /* Find the pool */ + index = fman_port_find_bpool(port, bpid); + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) + /* Not found */ + return; + + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]); +} + +int fman_port_add_congestion_grps(struct fman_port *port, + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]) +{ + int i; + uint32_t tmp, *grp_map_reg; + uint8_t max_grp_map_num; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + if (port->fm_rev_maj == 4) + max_grp_map_num = 1; + else + max_grp_map_num = FMAN_PORT_CG_MAP_NUM; + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm; + break; + case E_FMAN_PORT_TYPE_OP: + max_grp_map_num = 1; + if (port->fm_rev_maj != 4) + return -EINVAL; + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm; + break; + default: + return -EINVAL; + } + + for (i = (max_grp_map_num - 1); i >= 0; i--) { + if (grps_map[i] == 0) + continue; + tmp = ioread32be(&grp_map_reg[i]); + tmp |= grps_map[i]; + iowrite32be(tmp, &grp_map_reg[i]); + } + + return 0; +} + +int fman_port_remove_congestion_grps(struct fman_port *port, + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]) +{ + int i; + uint32_t tmp, *grp_map_reg; + uint8_t max_grp_map_num; + + switch (port->type) { + case E_FMAN_PORT_TYPE_RX: + case E_FMAN_PORT_TYPE_RX_10G: + if (port->fm_rev_maj == 4) + max_grp_map_num = 1; + else + max_grp_map_num = FMAN_PORT_CG_MAP_NUM; + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm; + break; + case E_FMAN_PORT_TYPE_OP: + max_grp_map_num = 1; + if (port->fm_rev_maj != 4) + return -EINVAL; + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm; + break; + default: + return -EINVAL; + } + + for (i = (max_grp_map_num - 1); i >= 0; i--) { + if (grps_map[i] == 0) + continue; + tmp = ioread32be(&grp_map_reg[i]); + tmp &= ~grps_map[i]; + iowrite32be(tmp, &grp_map_reg[i]); + } + return 0; +} diff --git a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c index 13ac04793929..99de427b3ae8 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c +++ b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_rtc.c @@ -37,7 +38,7 @@ @Cautions None *//***************************************************************************/ - +#include #include "error_ext.h" #include "debug_ext.h" #include "string_ext.h" @@ -49,38 +50,16 @@ #include "fm_common.h" -/*****************************************************************************/ -static void SetDefaultParam(t_FmRtc *p_Rtc) -{ - t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; - int i; - - p_Rtc->outputClockDivisor = DEFAULT_outputClockDivisor; - p_Rtc->p_RtcDriverParam->bypass = DEFAULT_bypass; - p_RtcDriverParam->srcClk = DEFAULT_srcClock; - p_RtcDriverParam->invertInputClkPhase = DEFAULT_invertInputClkPhase; - p_RtcDriverParam->invertOutputClkPhase = DEFAULT_invertOutputClkPhase; - p_RtcDriverParam->pulseRealign = DEFAULT_pulseRealign; - for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) - { - p_RtcDriverParam->alarmPolarity[i] = DEFAULT_alarmPolarity; - } - for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) - { - p_RtcDriverParam->triggerPolarity[i] = DEFAULT_triggerPolarity; - } - p_Rtc->clockPeriodNanoSec = DEFAULT_clockPeriod; /* 1 usec */ -} /*****************************************************************************/ static t_Error CheckInitParameters(t_FmRtc *p_Rtc) { - t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; int i; - if ((p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_EXTERNAL) && - (p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) && - (p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_OSCILATOR)) + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) && + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) && + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR)) RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined")); if (p_Rtc->outputClockDivisor == 0) @@ -91,31 +70,21 @@ static t_Error CheckInitParameters(t_FmRtc *p_Rtc) for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) { - if ((p_RtcDriverParam->alarmPolarity[i] != e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW) && - (p_RtcDriverParam->alarmPolarity[i] != e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH)) + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) && + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH)) { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i)); } } for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) { - if ((p_RtcDriverParam->triggerPolarity[i] != e_FM_RTC_TRIGGER_ON_FALLING_EDGE) && - (p_RtcDriverParam->triggerPolarity[i] != e_FM_RTC_TRIGGER_ON_RISING_EDGE)) + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) && + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE)) { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i)); } } -#ifdef FM_1588_SRC_CLK_ERRATA_FMAN1 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Rtc->h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)&& - ((p_RtcDriverParam->srcClk==e_FM_RTC_SOURCE_CLOCK_SYSTEM) && p_RtcDriverParam->invertInputClkPhase)) - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Can not use invertInputClkPhase when source clock is e_FM_RTC_SOURCE_CLOCK_SYSTEM")); - } -#endif /* FM_1588_SRC_CLK_ERRATA_FMAN1 */ - return E_OK; } @@ -123,55 +92,49 @@ static t_Error CheckInitParameters(t_FmRtc *p_Rtc) static void RtcExceptions(t_Handle h_FmRtc) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - t_FmRtcMemMap *p_MemMap; + struct rtc_regs *p_MemMap; register uint32_t events; ASSERT_COND(p_Rtc); p_MemMap = p_Rtc->p_MemMap; - /* Get valid events */ - events = GET_UINT32(p_MemMap->tmr_tevent); - events &= GET_UINT32(p_MemMap->tmr_temask); - - /* Clear event bits */ - WRITE_UINT32(p_MemMap->tmr_tevent, events); - - if (events & TMR_TEVENT_ALM1) + events = fman_rtc_check_and_clear_event(p_MemMap); + if (events & FMAN_RTC_TMR_TEVENT_ALM1) { - if(p_Rtc->alarmParams[0].clearOnExpiration) + if (p_Rtc->alarmParams[0].clearOnExpiration) { - WRITE_UINT32(p_MemMap->tmr_alarm[0].tmr_alarm_l, 0); - WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM1); + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0); + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1); } ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback); p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0); } - if (events & TMR_TEVENT_ALM2) + if (events & FMAN_RTC_TMR_TEVENT_ALM2) { - if(p_Rtc->alarmParams[1].clearOnExpiration) + if (p_Rtc->alarmParams[1].clearOnExpiration) { - WRITE_UINT32(p_MemMap->tmr_alarm[1].tmr_alarm_l, 0); - WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM2); + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0); + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2); } ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback); p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1); } - if (events & TMR_TEVENT_PP1) + if (events & FMAN_RTC_TMR_TEVENT_PP1) { ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback); p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0); } - if (events & TMR_TEVENT_PP2) + if (events & FMAN_RTC_TMR_TEVENT_PP2) { ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback); p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1); } - if (events & TMR_TEVENT_ETS1) + if (events & FMAN_RTC_TMR_TEVENT_ETS1) { ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback); p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0); } - if (events & TMR_TEVENT_ETS2) + if (events & FMAN_RTC_TMR_TEVENT_ETS2) { ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback); p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1); @@ -197,7 +160,7 @@ t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam) memset(p_Rtc, 0, sizeof(t_FmRtc)); /* Allocate memory for the FM RTC driver parameters */ - p_Rtc->p_RtcDriverParam = (t_FmRtcDriverParam *)XX_Malloc(sizeof(t_FmRtcDriverParam)); + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg)); if (!p_Rtc->p_RtcDriverParam) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters")); @@ -205,16 +168,21 @@ t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam) return NULL; } - memset(p_Rtc->p_RtcDriverParam, 0, sizeof(t_FmRtcDriverParam)); + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg)); /* Store RTC configuration parameters */ p_Rtc->h_Fm = p_FmRtcParam->h_Fm; /* Set default RTC configuration parameters */ - SetDefaultParam(p_Rtc); + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam); + + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR; + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS; + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */ + /* Store RTC parameters in the RTC control structure */ - p_Rtc->p_MemMap = (t_FmRtcMemMap *)UINT_TO_PTR(p_FmRtcParam->baseAddress); + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress); p_Rtc->h_App = p_FmRtcParam->h_App; return p_Rtc; @@ -224,119 +192,57 @@ t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam) t_Error FM_RTC_Init(t_Handle h_FmRtc) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - t_FmRtcDriverParam *p_RtcDriverParam; - t_FmRtcMemMap *p_MemMap; - uint32_t freqCompensation; - uint32_t tmrCtrl; - int i; + struct rtc_cfg *p_RtcDriverParam; + struct rtc_regs *p_MemMap; + uint32_t freqCompensation = 0; uint64_t tmpDouble; + bool init_freq_comp = FALSE; p_RtcDriverParam = p_Rtc->p_RtcDriverParam; p_MemMap = p_Rtc->p_MemMap; - if(CheckInitParameters(p_Rtc)!=E_OK) + if (CheckInitParameters(p_Rtc)!=E_OK) RETURN_ERROR(MAJOR, E_CONFLICT, ("Init Parameters are not Valid")); - /* TODO A check must be added here, that no timestamping MAC's - * are working in this stage. */ - WRITE_UINT32(p_MemMap->tmr_ctrl, TMR_CTRL_TMSR); - XX_UDelay(10); - WRITE_UINT32(p_MemMap->tmr_ctrl, 0); - - /* Set the source clock */ - switch (p_RtcDriverParam->srcClk) - { - case e_FM_RTC_SOURCE_CLOCK_SYSTEM: - tmrCtrl = TMR_CTRL_CKSEL_MAC_CLK; - break; - case e_FM_RTC_SOURCE_CLOCK_OSCILATOR: - tmrCtrl = TMR_CTRL_CKSEL_OSC_CLK; - break; - default: - /* Use a clock from the External TMR reference clock.*/ - tmrCtrl = TMR_CTRL_CKSEL_EXT_CLK; - break; - } - - /* whatever period the user picked, the timestamp will advance in '1' every time - * the period passed. */ - tmrCtrl |= ((1 << TMR_CTRL_TCLK_PERIOD_SHIFT) & TMR_CTRL_TCLK_PERIOD_MASK); - - if (p_RtcDriverParam->invertInputClkPhase) - tmrCtrl |= TMR_CTRL_CIPH; - if (p_RtcDriverParam->invertOutputClkPhase) - tmrCtrl |= TMR_CTRL_COPH; - - for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) - { - if (p_RtcDriverParam->alarmPolarity[i] == e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW) - tmrCtrl |= (TMR_CTRL_ALMP1 >> i); - } - - for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) - if (p_RtcDriverParam->triggerPolarity[i] == e_FM_RTC_TRIGGER_ON_FALLING_EDGE) - tmrCtrl |= (TMR_CTRL_ETEP1 << i); - - if (!p_RtcDriverParam->timerSlaveMode && p_Rtc->p_RtcDriverParam->bypass) - tmrCtrl |= TMR_CTRL_BYP; - - WRITE_UINT32(p_MemMap->tmr_ctrl, tmrCtrl); - - for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) - { - /* Clear TMR_ALARM registers */ - WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_l, 0xFFFFFFFF); - WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_h, 0xFFFFFFFF); - } - - /* Clear TMR_TEVENT */ - WRITE_UINT32(p_MemMap->tmr_tevent, TMR_TEVENT_ALL); - - /* Initialize TMR_TEMASK */ - WRITE_UINT32(p_MemMap->tmr_temask, 0); - + /* TODO check that no timestamping MACs are working in this stage. */ /* find source clock frequency in Mhz */ - if (p_Rtc->p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) - p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->extSrcClkFreq; + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq; else - p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetClockFreq(p_Rtc->h_Fm)/2); + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm)); /* if timer in Master mode Initialize TMR_CTRL */ /* We want the counter (TMR_CNT) to count in nano-seconds */ - if (!p_RtcDriverParam->timerSlaveMode && p_Rtc->p_RtcDriverParam->bypass) - { + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass) p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz); - } else { /* Initialize TMR_ADD with the initial frequency compensation value: freqCompensation = (2^32 / frequency ratio) */ /* frequency ratio = sorce clock/rtc clock = * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */ + init_freq_comp = TRUE; freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000, - p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz); - WRITE_UINT32(p_MemMap->tmr_add, freqCompensation); + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz); } + /* check the legality of the relation between source and destination clocks */ /* should be larger than 1.0001 */ tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz; - if((tmpDouble) <= 10001) + if ((tmpDouble) <= 10001) RETURN_ERROR(MAJOR, E_CONFLICT, ("Invalid relation between source and destination clocks. Should be larger than 1.0001")); - - for (i=0; i < 2; i++) - /* Clear TMR_FIPER registers */ - WRITE_UINT32(p_MemMap->tmr_fiper[i], 0xFFFFFFFF); - - /* Initialize TMR_PRSC */ - WRITE_UINT32(p_MemMap->tmr_prsc, p_Rtc->outputClockDivisor); - - /* Clear TMR_OFF */ - WRITE_UINT32(p_MemMap->tmr_off_l, 0); - WRITE_UINT32(p_MemMap->tmr_off_h, 0); + fman_rtc_init(p_RtcDriverParam, + p_MemMap, + FM_RTC_NUM_OF_ALARMS, + FM_RTC_NUM_OF_PERIODIC_PULSES, + FM_RTC_NUM_OF_EXT_TRIGGERS, + init_freq_comp, + freqCompensation, + p_Rtc->outputClockDivisor); /* Register the FM RTC interrupt */ FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc); @@ -381,9 +287,9 @@ t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc, SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_Rtc->p_RtcDriverParam->srcClk = srcClk; - if(srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) - p_Rtc->p_RtcDriverParam->extSrcClkFreq = freqInMhz; + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk; + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz; return E_OK; } @@ -422,7 +328,7 @@ t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_Rtc->p_RtcDriverParam->invertInputClkPhase = inverted; + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted; return E_OK; } @@ -435,7 +341,7 @@ t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_Rtc->p_RtcDriverParam->invertOutputClkPhase = inverted; + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted; return E_OK; } @@ -461,7 +367,7 @@ t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_Rtc->p_RtcDriverParam->pulseRealign = enable; + p_Rtc->p_RtcDriverParam->pulse_realign = enable; return E_OK; } @@ -477,11 +383,10 @@ t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc, SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); if (alarmId >= FM_RTC_NUM_OF_ALARMS) - { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID")); - } - p_Rtc->p_RtcDriverParam->alarmPolarity[alarmId] = alarmPolarity; + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] = + (enum fman_rtc_alarm_polarity)alarmPolarity; return E_OK; } @@ -501,7 +406,8 @@ t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc, RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID")); } - p_Rtc->p_RtcDriverParam->triggerPolarity[triggerId] = triggerPolarity; + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] = + (enum fman_rtc_trigger_polarity)triggerPolarity; return E_OK; } @@ -510,27 +416,11 @@ t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc, t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint32_t tmrCtrl; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl); - - /* TODO A check must be added here, that no timestamping MAC's - * are working in this stage. */ - if (resetClock) - { - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TMSR)); - - XX_UDelay(10); - /* Clear TMR_OFF */ - WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, 0); - WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, 0); - } - - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TE)); - + fman_rtc_enable(p_Rtc->p_MemMap, resetClock); return E_OK; } @@ -538,15 +428,13 @@ t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock) t_Error FM_RTC_Disable(t_Handle h_FmRtc) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint32_t tmrCtrl; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); /* TODO A check must be added here, that no timestamping MAC's * are working in this stage. */ - tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl); - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl & ~(TMR_CTRL_TE))); + fman_rtc_disable(p_Rtc->p_MemMap); return E_OK; } @@ -559,10 +447,7 @@ t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - /* TMR_OFF_L must be written first */ - WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, (uint32_t)offset); - WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, (uint32_t)(offset >> 32)); - + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset); return E_OK; } @@ -570,43 +455,36 @@ t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset) t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - t_FmRtcMemMap *p_MemMap; - uint32_t tmpReg; uint64_t tmpAlarm; + bool enable = FALSE; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_MemMap = p_Rtc->p_MemMap; - if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS) { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID")); } - if(p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm time must be equal or larger than RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); - if(p_FmRtcAlarmParams->alarmTime % (uint64_t)p_Rtc->clockPeriodNanoSec) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm time must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); - tmpAlarm = p_FmRtcAlarmParams->alarmTime/(uint64_t)p_Rtc->clockPeriodNanoSec; - - /* TMR_ALARM_L must be written first */ - WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_l, (uint32_t)tmpAlarm); - WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_h, - (uint32_t)(tmpAlarm >> 32)); + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("Alarm time must be equal or larger than RTC period - %d nanoseconds", + p_Rtc->clockPeriodNanoSec)); + tmpAlarm = p_FmRtcAlarmParams->alarmTime; + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec)) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("Alarm time must be a multiple of RTC period - %d nanoseconds", + p_Rtc->clockPeriodNanoSec)); if (p_FmRtcAlarmParams->f_AlarmCallback) { p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback; p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration; - - if(p_FmRtcAlarmParams->alarmId == 0) - tmpReg = TMR_TEVENT_ALM1; - else - tmpReg = TMR_TEVENT_ALM2; - WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg); + enable = TRUE; } + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable); + return E_OK; } @@ -614,43 +492,39 @@ t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - t_FmRtcMemMap *p_MemMap; - uint32_t tmpReg; + bool enable = FALSE; uint64_t tmpFiper; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - p_MemMap = p_Rtc->p_MemMap; - if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES) { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID")); } - if(GET_UINT32(p_MemMap->tmr_ctrl) & TMR_CTRL_TE) + if (fman_rtc_is_enabled(p_Rtc->p_MemMap)) RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled.")); - if(p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); - if(p_FmRtcPeriodicPulseParams->periodicPulsePeriod % (uint64_t)p_Rtc->clockPeriodNanoSec) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec)); - tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod/(uint64_t)p_Rtc->clockPeriodNanoSec; - if(tmpFiper & 0xffffffff00000000LL) - RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse/RTC Period must be smaller than 4294967296", p_Rtc->clockPeriodNanoSec)); - - WRITE_UINT32(p_MemMap->tmr_fiper[p_FmRtcPeriodicPulseParams->periodicPulseId], (uint32_t)tmpFiper); + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds", + p_Rtc->clockPeriodNanoSec)); + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod; + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec)) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds", + p_Rtc->clockPeriodNanoSec)); + if (tmpFiper & 0xffffffff00000000LL) + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, + ("Periodic pulse/RTC Period must be smaller than 4294967296", + p_Rtc->clockPeriodNanoSec)); if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback) { p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback = - p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback; - - if(p_FmRtcPeriodicPulseParams->periodicPulseId == 0) - tmpReg = TMR_TEVENT_PP1; - else - tmpReg = TMR_TEVENT_PP2; - WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg); + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback; + enable = TRUE; } - + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable); return E_OK; } @@ -658,7 +532,6 @@ t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_ t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint32_t tmpReg; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); @@ -669,17 +542,7 @@ t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId) } p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL; - - if(periodicPulseId == 0) - tmpReg = TMR_TEVENT_PP1; - else - tmpReg = TMR_TEVENT_PP2; - WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg); - - if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & TMR_CTRL_FS) - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~TMR_CTRL_FS); - - WRITE_UINT32(p_Rtc->p_MemMap->tmr_fiper[periodicPulseId], 0xFFFFFFFF); + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId); return E_OK; } @@ -688,7 +551,7 @@ t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId) t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint32_t tmpReg; + bool enable = FALSE; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); @@ -701,22 +564,10 @@ t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback) { p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback; - if(p_FmRtcExternalTriggerParams->externalTriggerId == 0) - tmpReg = TMR_TEVENT_ETS1; - else - tmpReg = TMR_TEVENT_ETS2; - WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) | tmpReg); - } - - if(p_FmRtcExternalTriggerParams->usePulseAsInput) - { - if(p_FmRtcExternalTriggerParams->externalTriggerId == 0) - tmpReg = TMR_CTRL_PP1L; - else - tmpReg = TMR_CTRL_PP2L; - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) | tmpReg); + enable = TRUE; } + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput); return E_OK; } @@ -724,7 +575,6 @@ t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint32_t tmpReg; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); @@ -734,19 +584,7 @@ t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId) p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL; - if(externalTriggerId == 0) - tmpReg = TMR_TEVENT_ETS1; - else - tmpReg = TMR_TEVENT_ETS2; - WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg); - - if(externalTriggerId == 0) - tmpReg = TMR_CTRL_PP1L; - else - tmpReg = TMR_CTRL_PP2L; - - if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & tmpReg) - WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~tmpReg); + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId); return E_OK; } @@ -757,21 +595,14 @@ t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc, uint64_t *p_TimeStamp) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint64_t timeStamp; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS) - { RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID")); - } - timeStamp = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_l); - timeStamp |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_h) << 32); - - timeStamp = timeStamp*p_Rtc->clockPeriodNanoSec; - *p_TimeStamp = timeStamp; + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec; return E_OK; } @@ -780,18 +611,11 @@ t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc, t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts) { t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - uint64_t time; SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - /* TMR_CNT_L must be read first to get an accurate value */ - time = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_l); - time |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_h) << 32); - - time = time*p_Rtc->clockPeriodNanoSec; - - *p_Ts = time; + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec; return E_OK; } @@ -804,10 +628,8 @@ t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - ts = ts/p_Rtc->clockPeriodNanoSec; - /* TMR_CNT_L must be written first to get an accurate value */ - WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_l, (uint32_t)ts); - WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_h, (uint32_t)(ts >> 32)); + do_div(ts, p_Rtc->clockPeriodNanoSec); + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts); return E_OK; } @@ -820,9 +642,7 @@ t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation) SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - *p_Compensation = (uint32_t) - DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000, - p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz); + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap); return E_OK; } @@ -836,56 +656,37 @@ t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation) SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); /* set the new freqCompensation */ - WRITE_UINT32(p_Rtc->p_MemMap->tmr_add, freqCompensation); + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation); return E_OK; } +#ifdef CONFIG_PTP_1588_CLOCK_DPAA +/*****************************************************************************/ +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events) +{ + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; + + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); + + /* enable interrupt */ + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events); + + return E_OK; +} + /*****************************************************************************/ -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc) +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events) { - t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - t_FmRtcMemMap *p_MemMap = p_Rtc->p_MemMap; - int i = 0; + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; - DECLARE_DUMP; + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); - if (p_MemMap) - { + /* disable interrupt */ + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events); - DUMP_TITLE(p_MemMap, ("RTC:")); - DUMP_VAR(p_MemMap, tmr_id); - DUMP_VAR(p_MemMap, tmr_id2); - DUMP_VAR(p_MemMap, tmr_ctrl); - DUMP_VAR(p_MemMap, tmr_tevent); - DUMP_VAR(p_MemMap, tmr_temask); - DUMP_VAR(p_MemMap, tmr_cnt_h); - DUMP_VAR(p_MemMap, tmr_cnt_l); - DUMP_VAR(p_MemMap, tmr_ctrl); - DUMP_VAR(p_MemMap, tmr_add); - DUMP_VAR(p_MemMap, tmr_acc); - DUMP_VAR(p_MemMap, tmr_prsc); - DUMP_VAR(p_MemMap, tmr_off_h); - DUMP_VAR(p_MemMap, tmr_off_l); - - DUMP_SUBSTRUCT_ARRAY(i, 2) - { - DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_h); - DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_l); - } - DUMP_SUBSTRUCT_ARRAY(i, 2) - { - DUMP_VAR(p_MemMap, tmr_fiper[i]); - DUMP_VAR(p_MemMap, tmr_fiper[i]); - } - DUMP_SUBSTRUCT_ARRAY(i, 2) - { - DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l); - DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l); - } - } - - return E_OK; + return E_OK; } -#endif /* (defined(DEBUG_ERRORS) && ... */ +#endif diff --git a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h index f11222529b36..843ca008ff8b 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h +++ b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_rtc.h @@ -49,134 +50,12 @@ /* General definitions */ -#define NANOSEC_PER_ONE_HZ_TICK 1000000000 -#define MIN_RTC_CLK_FREQ_HZ 1000 -#define MHz 1000000 - #define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32)) - -/* RTC default values */ -#define DEFAULT_srcClock e_FM_RTC_SOURCE_CLOCK_SYSTEM -#define DEFAULT_bypass FALSE -#define DEFAULT_invertInputClkPhase FALSE -#define DEFAULT_invertOutputClkPhase FALSE -#define DEFAULT_outputClockDivisor 0x00000002 -#define DEFAULT_alarmPolarity e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH -#define DEFAULT_triggerPolarity e_FM_RTC_TRIGGER_ON_FALLING_EDGE -#define DEFAULT_pulseRealign FALSE -#define DEFAULT_clockPeriod 1000 - -/* FM RTC Registers definitions */ -#define TMR_CTRL_ALMP1 0x80000000 -#define TMR_CTRL_ALMP2 0x40000000 -#define TMR_CTRL_FS 0x10000000 -#define TMR_CTRL_PP1L 0x08000000 -#define TMR_CTRL_PP2L 0x04000000 -#define TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000 -#define TMR_CTRL_FRD 0x00004000 -#define TMR_CTRL_SLV 0x00002000 -#define TMR_CTRL_ETEP1 0x00000100 -#define TMR_CTRL_COPH 0x00000080 -#define TMR_CTRL_CIPH 0x00000040 -#define TMR_CTRL_TMSR 0x00000020 -#define TMR_CTRL_DBG 0x00000010 -#define TMR_CTRL_BYP 0x00000008 -#define TMR_CTRL_TE 0x00000004 -#define TMR_CTRL_CKSEL_OSC_CLK 0x00000003 -#define TMR_CTRL_CKSEL_MAC_CLK 0x00000001 -#define TMR_CTRL_CKSEL_EXT_CLK 0x00000000 -#define TMR_CTRL_TCLK_PERIOD_SHIFT 16 - -#define TMR_TEVENT_ETS2 0x02000000 -#define TMR_TEVENT_ETS1 0x01000000 -#define TMR_TEVENT_ALM2 0x00020000 -#define TMR_TEVENT_ALM1 0x00010000 -#define TMR_TEVENT_PP1 0x00000080 -#define TMR_TEVENT_PP2 0x00000040 -#define TMR_TEVENT_PP3 0x00000020 -#define TMR_TEVENT_ALL (TMR_TEVENT_ETS2 | TMR_TEVENT_ETS1 | \ - TMR_TEVENT_ALM2 | TMR_TEVENT_ALM1 | \ - TMR_TEVENT_PP1 | TMR_TEVENT_PP2 | TMR_TEVENT_PP3) - -#define TMR_PRSC_OCK_MASK 0x0000FFFF +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002 +#define DEFAULT_BYPASS FALSE +#define DEFAULT_CLOCK_PERIOD 1000 -/**************************************************************************//** - @Description Memory Mapped Registers -*//***************************************************************************/ - -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(push,1) -#endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START - -/**************************************************************************//** - @Description FM RTC timer alarm -*//***************************************************************************/ -typedef _Packed struct t_TmrAlaram -{ - volatile uint32_t tmr_alarm_h; /**< */ - volatile uint32_t tmr_alarm_l; /**< */ -} _PackedType t_TmrAlaram; - -/**************************************************************************//** - @Description FM RTC timer Ex trigger -*//***************************************************************************/ -typedef _Packed struct t_TmrExtTrigger -{ - volatile uint32_t tmr_etts_h; /**< */ - volatile uint32_t tmr_etts_l; /**< */ -} _PackedType t_TmrExtTrigger; - -typedef _Packed struct -{ - volatile uint32_t tmr_id; /* Module ID and version register */ - volatile uint32_t tmr_id2; /* Module ID and configuration register */ - volatile uint32_t PTP_RESERVED1[30]; - volatile uint32_t tmr_ctrl; /* timer control register */ - volatile uint32_t tmr_tevent; /* timer event register */ - volatile uint32_t tmr_temask; /* timer event mask register */ - volatile uint32_t PTP_RESERVED2[3]; - volatile uint32_t tmr_cnt_h; /* timer counter high register */ - volatile uint32_t tmr_cnt_l; /* timer counter low register */ - volatile uint32_t tmr_add; /* timer drift compensation addend register */ - volatile uint32_t tmr_acc; /* timer accumulator register */ - volatile uint32_t tmr_prsc; /* timer prescale */ - volatile uint32_t PTP_RESERVED3; - volatile uint32_t tmr_off_h; /* timer offset high */ - volatile uint32_t tmr_off_l; /* timer offset low */ - volatile t_TmrAlaram tmr_alarm[FM_RTC_NUM_OF_ALARMS]; /* timer alarm */ - volatile uint32_t PTP_RESERVED4[2]; - volatile uint32_t tmr_fiper[FM_RTC_NUM_OF_PERIODIC_PULSES]; /* timer fixed period interval */ - volatile uint32_t PTP_RESERVED5[2]; - volatile t_TmrExtTrigger tmr_etts[FM_RTC_NUM_OF_EXT_TRIGGERS]; /*time stamp general purpose external */ - volatile uint32_t PTP_RESERVED6[3]; -} _PackedType t_FmRtcMemMap; - -#define MEM_MAP_END -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(pop) -#endif /* defined(__MWERKS__) && ... */ - - -/**************************************************************************//** - @Description RTC FM driver parameters structure. -*//***************************************************************************/ -typedef struct t_FmRtcDriverParam -{ - t_Handle h_Fm; /**< */ - e_FmSrcClk srcClk; /**< */ - uint32_t extSrcClkFreq; /**< */ - uint32_t rtcFreqHz; /**< */ - bool timerSlaveMode; /*Slave/Master Mode*/ - bool invertInputClkPhase; - bool invertOutputClkPhase; - uint32_t eventsMask; - bool bypass; /**< Indicates if frequency compensation is bypassed */ - bool pulseRealign; - e_FmRtcAlarmPolarity alarmPolarity[FM_RTC_NUM_OF_ALARMS]; - e_FmRtcTriggerPolarity triggerPolarity[FM_RTC_NUM_OF_EXT_TRIGGERS]; -} t_FmRtcDriverParam; typedef struct t_FmRtcAlarm { @@ -203,14 +82,14 @@ typedef struct t_FmRtc t_Part *p_Part; /**< Pointer to the integration device */ t_Handle h_Fm; t_Handle h_App; /**< Application handle */ - t_FmRtcMemMap *p_MemMap; /**< Pointer to RTC memory map */ + struct rtc_regs *p_MemMap; uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */ uint32_t srcClkFreqMhz; uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */ t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS]; t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES]; t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS]; - t_FmRtcDriverParam *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */ + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */ } t_FmRtc; diff --git a/sys/contrib/ncsw/Peripherals/FM/Rtc/fman_rtc.c b/sys/contrib/ncsw/Peripherals/FM/Rtc/fman_rtc.c new file mode 100755 index 000000000000..f3a02b15abcc --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/Rtc/fman_rtc.c @@ -0,0 +1,334 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_rtc.h" + +void fman_rtc_defconfig(struct rtc_cfg *cfg) +{ + int i; + cfg->src_clk = DEFAULT_SRC_CLOCK; + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE; + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE; + cfg->pulse_realign = DEFAULT_PULSE_REALIGN; + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++) + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY; + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++) + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY; +} + +uint32_t fman_rtc_get_events(struct rtc_regs *regs) +{ + return ioread32be(®s->tmr_tevent); +} + +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask) +{ + return ioread32be(®s->tmr_tevent) & ev_mask; +} + +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs) +{ + return ioread32be(®s->tmr_temask); +} + +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask) +{ + iowrite32be(mask, ®s->tmr_temask); +} + +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events) +{ + iowrite32be(events, ®s->tmr_tevent); +} + +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs) +{ + uint32_t event; + + event = ioread32be(®s->tmr_tevent); + event &= ioread32be(®s->tmr_temask); + + if (event) + iowrite32be(event, ®s->tmr_tevent); + return event; +} + +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs) +{ + return ioread32be(®s->tmr_add); +} + +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val) +{ + iowrite32be(val, ®s->tmr_add); +} + +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events) +{ + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events); +} + +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events) +{ + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events); +} + +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val) +{ + iowrite32be(val, ®s->tmr_alarm[index].tmr_alarm_l); +} + +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val) +{ + iowrite32be(val, ®s->tmr_fiper[index]); +} + +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val) +{ + iowrite32be((uint32_t)val, ®s->tmr_alarm[index].tmr_alarm_l); + iowrite32be((uint32_t)(val >> 32), ®s->tmr_alarm[index].tmr_alarm_h); +} + +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val) +{ + iowrite32be((uint32_t)val, ®s->tmr_off_l); + iowrite32be((uint32_t)(val >> 32), ®s->tmr_off_h); +} + +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id) +{ + uint64_t time; + /* TMR_CNT_L must be read first to get an accurate value */ + time = (uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_l); + time |= ((uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_h) + << 32); + + return time; +} + +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs) +{ + return ioread32be(®s->tmr_ctrl); +} + +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val) +{ + iowrite32be(val, ®s->tmr_ctrl); +} + +void fman_rtc_timers_soft_reset(struct rtc_regs *regs) +{ + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR); + DELAY(10); + fman_rtc_set_timer_ctrl(regs, 0); +} + +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms, + int num_fipers, int num_ext_triggers, bool init_freq_comp, + uint32_t freq_compensation, uint32_t output_clock_divisor) +{ + uint32_t tmr_ctrl; + int i; + + fman_rtc_timers_soft_reset(regs); + + /* Set the source clock */ + switch (cfg->src_clk) { + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM: + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK; + break; + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR: + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK; + break; + default: + /* Use a clock from the External TMR reference clock.*/ + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK; + break; + } + + /* whatever period the user picked, the timestamp will advance in '1' + * every time the period passed. */ + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) & + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK); + + if (cfg->invert_input_clk_phase) + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH; + if (cfg->invert_output_clk_phase) + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH; + + for (i = 0; i < num_alarms; i++) { + if (cfg->alarm_polarity[i] == + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i); + } + + for (i = 0; i < num_ext_triggers; i++) + if (cfg->trigger_polarity[i] == + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i); + + if (!cfg->timer_slave_mode && cfg->bypass) + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP; + + fman_rtc_set_timer_ctrl(regs, tmr_ctrl); + if (init_freq_comp) + fman_rtc_set_frequency_compensation(regs, freq_compensation); + + /* Clear TMR_ALARM registers */ + for (i = 0; i < num_alarms; i++) + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL); + + /* Clear TMR_TEVENT */ + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL); + + /* Initialize TMR_TEMASK */ + fman_rtc_set_interrupt_mask(regs, 0); + + /* Clear TMR_FIPER registers */ + for (i = 0; i < num_fipers; i++) + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF); + + /* Initialize TMR_PRSC */ + iowrite32be(output_clock_divisor, ®s->tmr_prsc); + + /* Clear TMR_OFF */ + fman_rtc_set_timer_offset(regs, 0); +} + +bool fman_rtc_is_enabled(struct rtc_regs *regs) +{ + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE); +} + +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock) +{ + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs); + + /* TODO check that no timestamping MACs are working in this stage. */ + if (reset_clock) { + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR)); + + DELAY(10); + /* Clear TMR_OFF */ + fman_rtc_set_timer_offset(regs, 0); + } + + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE)); +} + +void fman_rtc_disable(struct rtc_regs *regs) +{ + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs) + & ~(FMAN_RTC_TMR_CTRL_TE))); +} + +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id) +{ + uint32_t tmp_reg; + if (id == 0) + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1; + else + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2; + fman_rtc_disable_interupt(regs, tmp_reg); + + tmp_reg = fman_rtc_get_timer_ctrl(regs); + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS) + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS); + + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF); +} + +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id) +{ + uint32_t tmpReg, tmp_ctrl; + + if (id == 0) + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1; + else + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2; + fman_rtc_disable_interupt(regs, tmpReg); + + if (id == 0) + tmpReg = FMAN_RTC_TMR_CTRL_PP1L; + else + tmpReg = FMAN_RTC_TMR_CTRL_PP2L; + tmp_ctrl = fman_rtc_get_timer_ctrl(regs); + if (tmp_ctrl & tmpReg) + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg); +} + +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable) +{ + uint32_t tmpReg; + fman_rtc_set_timer_alarm(regs, id, val); + if (enable) { + if (id == 0) + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1; + else + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2; + fman_rtc_enable_interupt(regs, tmpReg); + } +} + +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val, + bool enable) +{ + uint32_t tmpReg; + fman_rtc_set_timer_fiper(regs, id, val); + if (enable) { + if (id == 0) + tmpReg = FMAN_RTC_TMR_TEVENT_PP1; + else + tmpReg = FMAN_RTC_TMR_TEVENT_PP2; + fman_rtc_enable_interupt(regs, tmpReg); + } +} + +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable, + bool use_pulse_as_input) +{ + uint32_t tmpReg; + if (enable) { + if (id == 0) + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1; + else + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2; + fman_rtc_enable_interupt(regs, tmpReg); + } + if (use_pulse_as_input) { + if (id == 0) + tmpReg = FMAN_RTC_TMR_CTRL_PP1L; + else + tmpReg = FMAN_RTC_TMR_CTRL_PP2L; + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg); + } +} diff --git a/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.c b/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.c new file mode 100644 index 000000000000..0994f34d392d --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.c @@ -0,0 +1,757 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_sp.c + + @Description FM PCD Storage profile ... +*//***************************************************************************/ + +#include "std_ext.h" +#include "error_ext.h" +#include "string_ext.h" +#include "debug_ext.h" +#include "net_ext.h" + +#include "fm_vsp_ext.h" +#include "fm_sp.h" +#include "fm_common.h" +#include "fsl_fman_sp.h" + + +#if (DPAA_VERSION >= 11) +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry) +{ + t_Error err = E_OK; + + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + return err; + +} + +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry) +{ + t_Error err = E_OK; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE); + + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK) + + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); + + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm, + p_FmVspEntry->portType, + p_FmVspEntry->portId, + p_FmVspEntry->relativeProfileId); + + return err; +} +#endif /* (DPAA_VERSION >= 11) */ + + +/*****************************************************************************/ +/* Inter-module API routines */ +/*****************************************************************************/ +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, + uint8_t *orderedArray, + uint16_t *sizesArray) +{ + uint16_t bufSize = 0; + int i=0, j=0, k=0; + + /* First we copy the external buffers pools information to an ordered local array */ + for (i=0;inumOfPoolsUsed;i++) + { + /* get pool size */ + bufSize = p_FmExtPools->extBufPool[i].size; + + /* keep sizes in an array according to poolId for direct access */ + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize; + + /* save poolId in an ordered array according to size */ + for (j=0;j<=i;j++) + { + /* this is the next free place in the array */ + if (j==i) + orderedArray[i] = p_FmExtPools->extBufPool[i].id; + else + { + /* find the right place for this poolId */ + if (bufSize < sizesArray[orderedArray[j]]) + { + /* move the poolIds one place ahead to make room for this poolId */ + for (k=i;k>j;k--) + orderedArray[k] = orderedArray[k-1]; + + /* now k==j, this is the place for the new size */ + orderedArray[k] = p_FmExtPools->extBufPool[i].id; + break; + } + } + } + } +} + +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools, + t_FmBackupBmPools *p_FmBackupBmPools, + t_FmBufPoolDepletion *p_FmBufPoolDepletion) +{ + + int i = 0, j = 0; + bool found; + uint8_t count = 0; + + if (p_FmExtPools) + { + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS)); + + for (i=0;inumOfPoolsUsed;i++) + { + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS)); + if (!p_FmExtPools->extBufPool[i].size) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i)); + } + } + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools")); + + /* backup BM pools indication is valid only for some chip derivatives + (limited by the config routine) */ + if (p_FmBackupBmPools) + { + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed")); + found = FALSE; + for (i = 0;inumOfBackupPools;i++) + { + + for (j=0;jnumOfPoolsUsed;j++) + { + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id) + { + found = TRUE; + break; + } + } + if (!found) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id")); + else + found = FALSE; + } + } + + /* up to extBufPools.numOfPoolsUsed pools may be defined */ + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable) + { + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS)); + + if (!p_FmBufPoolDepletion->numOfPools) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE")); + + found = FALSE; + count = 0; + /* for each pool that is in poolsToConsider, check if it is defined + in extBufPool */ + for (i=0;ipoolsToConsider[i]) + { + for (j=0;jnumOfPoolsUsed;j++) + { + if (i == p_FmExtPools->extBufPool[j].id) + { + found = TRUE; + count++; + break; + } + } + if (!found) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); + else + found = FALSE; + } + } + /* check that the number of pools that we have checked is equal to the number announced by the user */ + if (count != p_FmBufPoolDepletion->numOfPools) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined.")); + } + + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable) + { + /* calculate vector for number of pools depletion */ + found = FALSE; + count = 0; + for (i=0;ipoolsToConsiderForSingleMode[i]) + { + for (j=0;jnumOfPoolsUsed;j++) + { + if (i == p_FmExtPools->extBufPool[j].id) + { + found = TRUE; + count++; + break; + } + } + if (!found) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); + else + found = FALSE; + } + } + if (!count) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion.")); + } + + return E_OK; +} + +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy) +{ + /* Check that divisible by 16 and not larger than 240 */ + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET)); + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS)); + + /* check that ic size+ic internal offset, does not exceed ic block size */ + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE)); + /* Check that divisible by 16 and not larger than 256 */ + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS)); + + /* Check that divisible by 16 and not larger than 4K */ + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET)); + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS)); + + return E_OK; +} + +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins) +{ + /* Check the margin definition */ + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); + + return E_OK; +} + +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy, + t_FmBufferPrefixContent *p_BufferPrefixContent, + t_FmSpBufMargins *p_FmSpBufMargins, + t_FmSpBufferOffsets *p_FmSpBufferOffsets, + uint8_t *internalBufferOffset) +{ + uint32_t tmp; + + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE); + ASSERT_COND(p_FmSpIntContextDataCopy); + ASSERT_COND(p_BufferPrefixContent); + ASSERT_COND(p_FmSpBufMargins); + ASSERT_COND(p_FmSpBufferOffsets); + + /* Align start of internal context data to 16 byte */ + p_FmSpIntContextDataCopy->extBufOffset = + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ? + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) : + p_BufferPrefixContent->privDataSize); + + /* Translate margin and intContext params to FM parameters */ + /* Initialize with illegal value. Later we'll set legal values. */ + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE; + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE; + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE; + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE; + + /* Internally the driver supports 4 options + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll + relate to it as 1). + 2. All IC context (from AD) not including debug.*/ + + /* This 'if' covers option 2. We copy from beginning of context. */ + if (p_BufferPrefixContent->passAllOtherPCDInfo) + { + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */ + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */ + p_FmSpIntContextDataCopy->intContextOffset = 16; + + if (p_BufferPrefixContent->passAllOtherPCDInfo) + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset; + if (p_BufferPrefixContent->passPrsResult) + p_FmSpBufferOffsets->prsResultOffset = + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16); + if (p_BufferPrefixContent->passTimeStamp) + p_FmSpBufferOffsets->timeStampOffset = + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48); + if (p_BufferPrefixContent->passHashResult) + p_FmSpBufferOffsets->hashResultOffset = + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56); + } + else + { + /* This case covers the options under 1 */ + /* Copy size must be in 16-byte granularity. */ + p_FmSpIntContextDataCopy->size = + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) + + ((p_BufferPrefixContent->passTimeStamp || + p_BufferPrefixContent->passHashResult) ? 16 : 0)); + + /* Align start of internal context data to 16 byte */ + p_FmSpIntContextDataCopy->intContextOffset = + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 : + ((p_BufferPrefixContent->passTimeStamp || + p_BufferPrefixContent->passHashResult) ? 64 : 0)); + + if (p_BufferPrefixContent->passPrsResult) + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset; + if (p_BufferPrefixContent->passTimeStamp) + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ? + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) : + p_FmSpIntContextDataCopy->extBufOffset; + if (p_BufferPrefixContent->passHashResult) + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */ + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ? + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) : + p_FmSpIntContextDataCopy->extBufOffset + 8; + } + + if (p_FmSpIntContextDataCopy->size) + p_FmSpBufMargins->startMargins = + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset + + p_FmSpIntContextDataCopy->size); + else + /* No Internal Context passing, STartMargin is immediately after privateInfo */ + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize; + + /* save extra space for manip in both external and internal buffers */ + if (p_BufferPrefixContent->manipExtraSpace) + { + uint8_t extraSpace; +#ifdef FM_CAPWAP_SUPPORT + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("p_BufferPrefixContent->manipExtraSpace should be less than %d", + 256-CAPWAP_FRAG_EXTRA_SPACE)); + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE); +#else + extraSpace = p_BufferPrefixContent->manipExtraSpace; +#endif /* FM_CAPWAP_SUPPORT */ + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins; + p_FmSpBufMargins->startMargins += extraSpace; + *internalBufferOffset = extraSpace; + } + + /* align data start */ + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign); + if (tmp) + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp); + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins; + + return E_OK; +} +/*********************** End of inter-module routines ************************/ + + +#if (DPAA_VERSION >= 11) +/*****************************************************************************/ +/* API routines */ +/*****************************************************************************/ +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams) +{ + t_FmVspEntry *p_FmVspEntry = NULL; + struct fm_storage_profile_params fm_vsp_params; + + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry)); + if (!p_FmVspEntry) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); + return NULL; + } + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry)); + + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams)); + if (!p_FmVspEntry->p_FmVspEntryDriverParams) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); + XX_Free(p_FmVspEntry); + return NULL; + } + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams)); + fman_vsp_defconfig(&fm_vsp_params); + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr; + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr; + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr; + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data; + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize; + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather; + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize; + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult; + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign; + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset; + + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools)); + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm; + p_FmVspEntry->portType = p_FmVspParams->portParams.portType; + p_FmVspEntry->portId = p_FmVspParams->portParams.portId; + + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId; + + return p_FmVspEntry; +} + +t_Error FM_VSP_Init(t_Handle h_FmVsp) +{ + + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp; + struct fm_storage_profile_params fm_vsp_params; + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; + t_Error err; + uint16_t absoluteProfileId = 0; + int i = 0; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE); + + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams); + + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); + + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext, + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, + &p_FmVspEntry->bufMargins, + &p_FmVspEntry->bufferOffsets, + &p_FmVspEntry->internalBufferOffset); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + + err = CheckParamsGeneratedInternally(p_FmVspEntry); + if (err != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + + p_FmVspEntry->p_FmSpRegsBase = + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm); + if (!p_FmVspEntry->p_FmSpRegsBase) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase")); + + /* order external buffer pools in ascending order of buffer pools sizes */ + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools, + orderedArray, + sizesArray); + + p_FmVspEntry->extBufPools.numOfPoolsUsed = + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed; + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++) + { + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i]; + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]]; + } + + /* on user responsibility to fill it according requirement */ + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params)); + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData; + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr; + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr; + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr; + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize; + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset; + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather; + + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion) + { + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE; + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable; + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools; + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider; + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable; + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode; + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE; + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn; + } + else + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE; + + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools) + { + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools; + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds; + } + else + fm_vsp_params.backup_pools.num_backup_pools = 0; + + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed; + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool; + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins; + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext; + + /* no check on err - it was checked earlier */ + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm, + p_FmVspEntry->portType, + p_FmVspEntry->portId, + p_FmVspEntry->relativeProfileId, + &absoluteProfileId); + + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase); + ASSERT_COND(fm_vsp_params.int_context); + ASSERT_COND(fm_vsp_params.buf_margins); + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES)); + + /* Set all registers related to VSP */ + fman_vsp_init(p_FmVspEntry->p_FmSpRegsBase, absoluteProfileId, &fm_vsp_params,FM_PORT_MAX_NUM_OF_EXT_POOLS, BM_MAX_NUM_OF_POOLS, FM_MAX_NUM_OF_PFC_PRIORITIES); + + p_FmVspEntry->absoluteSpId = absoluteProfileId; + + if (p_FmVspEntry->p_FmVspEntryDriverParams) + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams); + p_FmVspEntry->p_FmVspEntryDriverParams = NULL; + + return E_OK; +} + +t_Error FM_VSP_Free(t_Handle h_FmVsp) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp; + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); + XX_Free(p_FmVspEntry); + return E_OK; +} + +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent)); + /* if dataAlign was not initialized by user, we return to driver's default */ + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign) + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign; + + return E_OK; +} + +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData; + + return E_OK; +} + +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr; + + return E_OK; +} + +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr; + + return E_OK; +} + +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr; + + return E_OK; +} + +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize; + + return E_OK; +} + +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + + + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather; + + return E_OK; +} + +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion)); + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed")); + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion)); + + return E_OK; +} + +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE); + + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools)); + + return E_OK; +} + +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0); + + return p_FmVspEntry->bufferOffsets.dataOffset; +} + +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); + + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) + return NULL; + + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset); +} + +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); + + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE) + return NULL; + + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset); +} + +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); + + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE) + return NULL; + + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset); +} + +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data) +{ + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; + + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); + + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE) + return NULL; + + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset); +} + +#endif /* (DPAA_VERSION >= 11) */ diff --git a/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.h b/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.h new file mode 100644 index 000000000000..9c171d85a5bb --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.h @@ -0,0 +1,85 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_sp.h + + @Description FM SP ... +*//***************************************************************************/ +#ifndef __FM_SP_H +#define __FM_SP_H + +#include "std_ext.h" +#include "error_ext.h" +#include "list_ext.h" + +#include "fm_sp_common.h" +#include "fm_common.h" + + +#define __ERR_MODULE__ MODULE_FM_SP + +typedef struct { + t_FmBufferPrefixContent bufferPrefixContent; + e_FmDmaSwapOption dmaSwapData; + e_FmDmaCacheOption dmaIntContextCacheAttr; + e_FmDmaCacheOption dmaHeaderCacheAttr; + e_FmDmaCacheOption dmaScatterGatherCacheAttr; + bool dmaWriteOptimize; + uint16_t liodnOffset; + bool noScatherGather; + t_FmBufPoolDepletion *p_BufPoolDepletion; + t_FmBackupBmPools *p_BackupBmPools; + t_FmExtPools extBufPools; +} t_FmVspEntryDriverParams; + +typedef struct { + bool valid; + volatile bool lock; + uint8_t pointedOwners; + uint16_t absoluteSpId; + uint8_t internalBufferOffset; + t_FmSpBufMargins bufMargins; + t_FmSpIntContextDataCopy intContext; + t_FmSpBufferOffsets bufferOffsets; + t_Handle h_Fm; + e_FmPortType portType; /**< Port type */ + uint8_t portId; /**< Port Id - relative to type */ + uint8_t relativeProfileId; + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase; + t_FmExtPools extBufPools; + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams; +} t_FmVspEntry; + + +#endif /* __FM_SP_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/SP/fman_sp.c b/sys/contrib/ncsw/Peripherals/FM/SP/fman_sp.c new file mode 100755 index 000000000000..0f772e919792 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/SP/fman_sp.c @@ -0,0 +1,197 @@ +/* + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 "fsl_fman_sp.h" + + +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs, + uint16_t index) +{ + struct fm_pcd_storage_profile_regs *sp_regs; + sp_regs = ®s[index]; + return ioread32be(&sp_regs->fm_sp_acnt); +} + +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs, + uint16_t index, uint32_t value) +{ + struct fm_pcd_storage_profile_regs *sp_regs; + sp_regs = ®s[index]; + iowrite32be(value, &sp_regs->fm_sp_acnt); +} + +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg) +{ + cfg->dma_swap_data = + DEFAULT_FMAN_SP_DMA_SWAP_DATA; + cfg->int_context_cache_attr = + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR; + cfg->header_cache_attr = + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR; + cfg->scatter_gather_cache_attr = + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR; + cfg->dma_write_optimize = + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE; + cfg->no_scather_gather = + DEFAULT_FMAN_SP_NO_SCATTER_GATHER; +} + +static inline uint32_t calc_vec_dep(int max_pools, bool *pools, + struct fman_ext_pools *ext_buf_pools, uint32_t mask) +{ + int i, j; + uint32_t vector = 0; + for (i = 0; i < max_pools; i++) + if (pools[i]) + for (j = 0; j < ext_buf_pools->num_pools_used; j++) + if (i == ext_buf_pools->ext_buf_pool[j].id) { + vector |= mask >> j; + break; + } + return vector; +} + +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs, + uint16_t index, struct fm_storage_profile_params *fm_vsp_params, + int port_max_num_of_ext_pools, int bm_max_num_of_pools, + int max_num_of_pfc_priorities) +{ + int i = 0, j = 0; + struct fm_pcd_storage_profile_regs *sp_regs; + uint32_t tmp_reg, vector; + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools; + struct fman_buf_pool_depletion *buf_pool_depletion = + &fm_vsp_params->buf_pool_depletion; + struct fman_backup_bm_pools *backup_pools = + &fm_vsp_params->backup_pools; + struct fman_sp_int_context_data_copy *int_context_data_copy = + fm_vsp_params->int_context; + struct fman_sp_buf_margins *external_buffer_margins = + fm_vsp_params->buf_margins; + bool no_scather_gather = fm_vsp_params->no_scather_gather; + uint16_t liodn_offset = fm_vsp_params->liodn_offset; + + sp_regs = ®s[index]; + + /* fill external buffers manager pool information register*/ + for (i = 0; i < ext_buf_pools->num_pools_used; i++) { + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID | + FMAN_SP_EXT_BUF_POOL_EN_COUNTER; + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id << + FMAN_SP_EXT_BUF_POOL_ID_SHIFT); + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size; + /* functionality available only for some deriviatives + (limited by config) */ + for (j = 0; j < backup_pools->num_backup_pools; j++) + if (ext_buf_pools->ext_buf_pool[i].id == + backup_pools->pool_ids[j]) { + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP; + break; + } + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]); + } + + /* clear unused pools */ + for (i = ext_buf_pools->num_pools_used; + i < port_max_num_of_ext_pools; i++) + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]); + + /* fill pool depletion register*/ + tmp_reg = 0; + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) { + /* calculate vector for number of pools depletion */ + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion-> + pools_to_consider, ext_buf_pools, 0x80000000); + + /* configure num of pools and vector for number of pools mode */ + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) << + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT); + tmp_reg |= vector; + } + + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) { + /* calculate vector for number of pools depletion */ + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion-> + pools_to_consider_for_single_mode, + ext_buf_pools, 0x00000080); + + /* configure num of pools and vector for number of pools mode */ + tmp_reg |= vector; + } + + /* fill QbbPEV */ + if (buf_pool_depletion->buf_pool_depletion_enabled) { + vector = 0; + for (i = 0; i < max_num_of_pfc_priorities; i++) + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE) + vector |= 0x00000100 << i; + tmp_reg |= vector; + } + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd); + + /* fill dma attributes register */ + tmp_reg = 0; + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data << + FMAN_SP_DMA_ATTR_SWP_SHIFT; + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr << + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT; + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr << + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT; + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr << + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT; + if (fm_vsp_params->dma_write_optimize) + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE; + iowrite32be(tmp_reg, &sp_regs->fm_sp_da); + + /* IC parameters - fill internal context parameters register */ + tmp_reg = 0; + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/ + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT); + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/ + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT); + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) << + FMAN_SP_IC_SIZE_SHIFT); + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp); + + /* buffer margins - fill external buffer margins register */ + tmp_reg = 0; + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) << + FMAN_SP_EXT_BUF_MARG_START_SHIFT); + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) << + FMAN_SP_EXT_BUF_MARG_END_SHIFT); + if (no_scather_gather) + tmp_reg |= FMAN_SP_SG_DISABLE; + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm); + + /* buffer margins - fill spliodn register */ + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/fm.c b/sys/contrib/ncsw/Peripherals/FM/fm.c deleted file mode 100644 index a0f225167d9a..000000000000 --- a/sys/contrib/ncsw/Peripherals/FM/fm.c +++ /dev/null @@ -1,4605 +0,0 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. - */ - -/****************************************************************************** - @File fm.c - - @Description FM driver routines implementation. -*//***************************************************************************/ -#include "std_ext.h" -#include "error_ext.h" -#include "xx_ext.h" -#include "string_ext.h" -#include "sprint_ext.h" -#include "debug_ext.h" -#include "fm_muram_ext.h" - -#include "fm_common.h" -#include "fm_ipc.h" -#include "fm.h" - - -/****************************************/ -/* static functions */ -/****************************************/ - -static volatile bool blockingFlag = FALSE; -static void IpcMsgCompletionCB(t_Handle h_Fm, - uint8_t *p_Msg, - uint8_t *p_Reply, - uint32_t replyLength, - t_Error status) -{ - UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); - blockingFlag = FALSE; -} - -static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm) -{ - t_FMIramRegs *p_Iram; - - ASSERT_COND(p_Fm); - p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); - - return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY); -} - -static t_Error CheckFmParameters(t_Fm *p_Fm) -{ - if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->p_FmDriverParam->resetOnInit) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!")); - if(!p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats || (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)); - if(p_Fm->p_FmDriverParam->dmaCamNumOfEntries % DMA_CAM_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be divisble by %d", DMA_CAM_UNITS)); - if(!p_Fm->p_FmDriverParam->dmaCamNumOfEntries || (p_Fm->p_FmDriverParam->dmaCamNumOfEntries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)); - if(p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency > DMA_THRESH_MAX_COMMQ) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ)); - if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency > DMA_THRESH_MAX_COMMQ) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ)); - if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency must be smaller than dmaCommQThresholds.assertEmergency")); - if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); - if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); - if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency must be smaller than dmaReadBufThresholds.assertEmergency")); - if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); - if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF)); - if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency must be smaller than dmaWriteBufThresholds.assertEmergency")); - - if(!p_Fm->p_FmStateStruct->fmClkFreq) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set.")); - if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, - ("dmaWatchdog depends on FM clock. dmaWatchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG)); - -#ifdef FM_PARTITION_ARRAY - { - t_FmRevisionInfo revInfo; - uint8_t i; - - FM_GetRevision(p_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - for (i=0; ip_FmDriverParam->liodnBasePerPort[i] & ~FM_LIODN_BASE_MASK) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodn number is out of range")); - } -#endif /* FM_PARTITION_ARRAY */ - - if(p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS)); - if(!p_Fm->p_FmStateStruct->totalFifoSize || (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be in the range 256 - %d", BMI_MAX_FIFO_SIZE)); - if(!p_Fm->p_FmStateStruct->totalNumOfTasks || (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS)); - if(!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS)); - - if(p_Fm->p_FmDriverParam->thresholds.dispLimit > FPM_MAX_DISP_LIMIT) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("thresholds.dispLimit can't be greater than %d", FPM_MAX_DISP_LIMIT)); - - if(!p_Fm->f_Exception) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); - if(!p_Fm->f_BusError) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); - - return E_OK; -} - -static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg) -{ - t_Error err; - t_FmIpcIsr fmIpcIsr; - t_FmIpcMsg msg; - - ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID); - ASSERT_COND(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]); - if (p_Fm->intrMng[macEvent].guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_GUEST_ISR; - fmIpcIsr.pendingReg = pendingReg; - fmIpcIsr.boolErr = FALSE; - memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(fmIpcIsr), - NULL, - NULL, - NULL, - NULL)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - else - p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle); -} - -static void BmiErrEvent(t_Fm *p_Fm) -{ - uint32_t event, mask, force; - - event = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr); - mask = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr); - if(force & event) - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, force & ~event); - - - /* clear the acknowledged events */ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, event); - - if(event & BMI_ERR_INTR_EN_PIPELINE_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_PIPELINE_ECC); - if(event & BMI_ERR_INTR_EN_LIST_RAM_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC); - if(event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC); - if(event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC); -} - -static void QmiErrEvent(t_Fm *p_Fm) -{ - uint32_t event, mask, force; - - event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie); - mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); - - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif); - if(force & event) - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, force & ~event); - - /* clear the acknowledged events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, event); - - if(event & QMI_ERR_INTR_EN_DOUBLE_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC); - if(event & QMI_ERR_INTR_EN_DEQ_FROM_DEF) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID); -} - -static void DmaErrEvent(t_Fm *p_Fm) -{ - uint64_t addr=0; - uint32_t status, mask, tmpReg=0; - uint8_t tnum; - uint8_t hardwarePortId; - uint8_t relativePortId; - uint16_t liodn; - - status = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr); - mask = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); - - /* get bus error regs befor clearing BER */ - if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER)) - { - addr = (uint64_t)GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtal); - addr |= ((uint64_t)(GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtah)) << 32); - - /* get information about the owner of that bus error */ - tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtcid); - } - - /* clear set events */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, status); - - if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER)) - { - hardwarePortId = (uint8_t)(((tmpReg & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT)); - HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); - tnum = (uint8_t)((tmpReg & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT); - liodn = (uint16_t)(tmpReg & DMA_TRANSFER_LIODN_MASK); - ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY); - p_Fm->f_BusError(p_Fm->h_App, p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], relativePortId, addr, tnum, liodn); - } - if(mask & DMA_MODE_ECC) - { - if (status & DMA_STATUS_READ_ECC) - p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC); - if (status & DMA_STATUS_SYSTEM_WRITE_ECC) - p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC); - if (status & DMA_STATUS_FM_WRITE_ECC) - p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC); - } -} - -static void FpmErrEvent(t_Fm *p_Fm) -{ - uint32_t event; - - event = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem); - - /* clear the all occurred events */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, event); - - if((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN)) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC); - if((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN)) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS); - if((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN)) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC); -} - -static void MuramErrIntr(t_Fm *p_Fm) -{ - uint32_t event, mask; - - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr); - mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie); - - /* clear MURAM event bit */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_IRAM_ECC); - - ASSERT_COND(event & FPM_RAM_CTL_MURAM_ECC); - ASSERT_COND(event & FPM_RAM_CTL_RAMS_ECC_EN); - - if ((mask & FPM_MURAM_ECC_ERR_EX_EN)) - p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC); -} - -static void IramErrIntr(t_Fm *p_Fm) -{ - uint32_t event, mask; - - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr) ; - mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie); - /* clear the acknowledged events (do not clear IRAM event) */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_MURAM_ECC); - - ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC); - ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC_EN); - - if ((mask & FPM_IRAM_ECC_ERR_EX_EN)) - p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC); -} - -static void QmiEvent(t_Fm *p_Fm) -{ - uint32_t event, mask, force; - - event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie); - mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien); - - event &= mask; - - /* clear the forced events */ - force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_if); - if(force & event) - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, force & ~event); - - /* clear the acknowledged events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, event); - - if(event & QMI_INTR_EN_SINGLE_ECC) - p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC); -} - -static void UnimplementedIsr(t_Handle h_Arg) -{ - UNUSED(h_Arg); - - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!")); -} - -static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event) -{ - UNUSED(h_Arg); UNUSED(event); - - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl Isr!")); -} - -static void FmEnableTimeStamp(t_Fm *p_Fm) -{ - uint32_t tmpReg; - uint64_t fraction; - uint32_t integer; - uint8_t count1MicroBit = 8; - uint32_t tsFrequency = (uint32_t)(1<p_FmStateStruct->fmClkFreq; - /* we multiply by 2^16 to keep the fraction of the division */ - /* we do not divid back, since we write this value as fraction - see spec */ - fraction = ((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq)/p_Fm->p_FmStateStruct->fmClkFreq; - /* we check remainder of the division in order to round up if not integer */ - if(((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq) % p_Fm->p_FmStateStruct->fmClkFreq) - fraction++; - - tmpReg = (integer << FPM_TS_INT_SHIFT) | (uint16_t)fraction; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc2, tmpReg); - - /* enable timestamp with original clock */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc1, FPM_TS_CTL_EN); - - p_Fm->p_FmStateStruct->count1MicroBit = count1MicroBit; - p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE; -} - -static void FreeInitResources(t_Fm *p_Fm) -{ - if (p_Fm->camBaseAddr) - FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr)); - if (p_Fm->fifoBaseAddr) - FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr)); - if (p_Fm->resAddr) - FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr)); -} - -static t_Error ClearIRam(t_Fm *p_Fm) -{ - t_FMIramRegs *p_Iram; - int i; - - ASSERT_COND(p_Fm); - p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); - - /* Enable the auto-increment */ - WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); - while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; - - for (i=0; i < (FM_IRAM_SIZE/4); i++) - WRITE_UINT32(p_Iram->idata, 0xffffffff); - - WRITE_UINT32(p_Iram->iadd, FM_IRAM_SIZE - 4); - CORE_MemoryBarrier(); - while (GET_UINT32(p_Iram->idata) != 0xffffffff) ; - - return E_OK; -} - -static t_Error LoadFmanCtrlCode(t_Fm *p_Fm) -{ - t_FMIramRegs *p_Iram; - int i; - uint32_t tmp; - uint8_t compTo16; - - ASSERT_COND(p_Fm); - p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); - - /* Enable the auto-increment */ - WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); - while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; - - for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++) - WRITE_UINT32(p_Iram->idata, p_Fm->p_FmDriverParam->firmware.p_Code[i]); - - compTo16 = (uint8_t)(p_Fm->p_FmDriverParam->firmware.size % 16); - if(compTo16) - for (i=0; i < ((16-compTo16) / 4); i++) - WRITE_UINT32(p_Iram->idata, 0xffffffff); - - WRITE_UINT32(p_Iram->iadd,p_Fm->p_FmDriverParam->firmware.size-4); - while(GET_UINT32(p_Iram->iadd) != (p_Fm->p_FmDriverParam->firmware.size-4)) ; - - /* verify that writing has completed */ - while (GET_UINT32(p_Iram->idata) != p_Fm->p_FmDriverParam->firmware.p_Code[(p_Fm->p_FmDriverParam->firmware.size / 4)-1]) ; - - if (p_Fm->p_FmDriverParam->fwVerify) - { - WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); - while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; - for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++) - if ((tmp=GET_UINT32(p_Iram->idata)) != p_Fm->p_FmDriverParam->firmware.p_Code[i]) - RETURN_ERROR(MAJOR, E_WRITE_FAILED, - ("UCode write error : write 0x%x, read 0x%x", - p_Fm->p_FmDriverParam->firmware.p_Code[i],tmp)); - WRITE_UINT32(p_Iram->iadd, 0x0); - } - - /* Enable patch from IRAM */ - WRITE_UINT32(p_Iram->iready, IRAM_READY); - XX_UDelay(1000); - - DBG(INFO, ("FMan-Controller code (ver %d.%d) loaded to IRAM.", - ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[5], - ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[7])); - - return E_OK; -} - -static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending) -{ -#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \ -do { \ - p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ -} while (0) -#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \ -do { \ - p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\ -} while (0) - - /* error interrupts */ - if (pending & ERR_INTR_EN_1G_MAC0) - FM_G_CALL_1G_MAC_ERR_ISR(0); - if (pending & ERR_INTR_EN_1G_MAC1) - FM_G_CALL_1G_MAC_ERR_ISR(1); - if (pending & ERR_INTR_EN_1G_MAC2) - FM_G_CALL_1G_MAC_ERR_ISR(2); - if (pending & ERR_INTR_EN_1G_MAC3) - FM_G_CALL_1G_MAC_ERR_ISR(3); - if (pending & ERR_INTR_EN_1G_MAC4) - FM_G_CALL_1G_MAC_ERR_ISR(4); - if (pending & ERR_INTR_EN_10G_MAC0) - FM_G_CALL_10G_MAC_ERR_ISR(0); -} - -static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending) -{ -#define FM_G_CALL_1G_MAC_TMR_ISR(_id) \ -do { \ - p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\ -} while (0) - - if (pending & INTR_EN_1G_MAC0_TMR) - FM_G_CALL_1G_MAC_TMR_ISR(0); - if (pending & INTR_EN_1G_MAC1_TMR) - FM_G_CALL_1G_MAC_TMR_ISR(1); - if (pending & INTR_EN_1G_MAC2_TMR) - FM_G_CALL_1G_MAC_TMR_ISR(2); - if (pending & INTR_EN_1G_MAC3_TMR) - FM_G_CALL_1G_MAC_TMR_ISR(3); - if (pending & INTR_EN_1G_MAC4_TMR) - FM_G_CALL_1G_MAC_TMR_ISR(4); - if(pending & INTR_EN_TMR) - p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); -} - - -/****************************************/ -/* Inter-Module functions */ -/****************************************/ -static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm, - uint8_t *p_Msg, - uint32_t msgLength, - uint8_t *p_Reply, - uint32_t *p_ReplyLength) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; - - UNUSED(p_Reply); - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE); - -#ifdef DISABLE_SANITY_CHECKS - UNUSED(msgLength); -#endif /* DISABLE_SANITY_CHECKS */ - - ASSERT_COND(p_Msg); - - *p_ReplyLength = 0; - - switch(p_IpcMsg->msgId) - { - case (FM_GUEST_ISR): - { - t_FmIpcIsr ipcIsr; - - memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr)); - if(ipcIsr.boolErr) - GuestErrorIsr(p_Fm, ipcIsr.pendingReg); - else - GuestEventIsr(p_Fm, ipcIsr.pendingReg); - break; - } - default: - *p_ReplyLength = 0; - RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); - } - return E_OK; -} - -static t_Error FmHandleIpcMsgCB(t_Handle h_Fm, - uint8_t *p_Msg, - uint32_t msgLength, - uint8_t *p_Reply, - uint32_t *p_ReplyLength) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; - t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); - -#ifdef DISABLE_SANITY_CHECKS - UNUSED(msgLength); -#endif /* DISABLE_SANITY_CHECKS */ - - ASSERT_COND(p_IpcMsg); - - memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE)); - *p_ReplyLength = 0; - - switch(p_IpcMsg->msgId) - { - case (FM_GET_SET_PORT_PARAMS): - { - t_FmIpcPortInInitParams ipcInitParams; - t_FmInterModulePortInitParams initParams; - t_FmIpcPhysAddr ipcPhysAddr; - - memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams)); - initParams.hardwarePortId = ipcInitParams.hardwarePortId; - initParams.portType = (e_FmPortType)ipcInitParams.enumPortType; - initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode); - initParams.liodnOffset = ipcInitParams.liodnOffset; - initParams.numOfTasks = ipcInitParams.numOfTasks; - initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks; - initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas; - initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas; - initParams.sizeOfFifo = ipcInitParams.sizeOfFifo; - initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo; - initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth; - initParams.liodnBase = ipcInitParams.liodnBase; - - p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams); - ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high; - ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low; - memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr); - break; - } - case (FM_SET_SIZE_OF_FIFO): - { - t_FmIpcPortFifoParams ipcPortFifoParams; - t_FmInterModulePortRxPoolsParams rxPoolsParams; - - memcpy((uint8_t*)&ipcPortFifoParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFifoParams)); - rxPoolsParams.numOfPools = ipcPortFifoParams.numOfPools; - rxPoolsParams.secondLargestBufSize = ipcPortFifoParams.secondLargestBufSize; - rxPoolsParams.largestBufSize = ipcPortFifoParams.largestBufSize; - - p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, ipcPortFifoParams.rsrcParams.hardwarePortId, - (e_FmPortType)ipcPortFifoParams.enumPortType, - (bool)ipcPortFifoParams.boolIndependentMode, - &ipcPortFifoParams.rsrcParams.val, - ipcPortFifoParams.rsrcParams.extra, - ipcPortFifoParams.deqPipelineDepth, - &rxPoolsParams, - (bool)ipcPortFifoParams.boolInitialConfig); - memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPortFifoParams.rsrcParams.val, sizeof(uint32_t)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); - break; - } - case (FM_SET_NUM_OF_TASKS): - { - t_FmIpcPortRsrcParams ipcPortRsrcParams; - - memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); - p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId, - (uint8_t)ipcPortRsrcParams.val, - (uint8_t)ipcPortRsrcParams.extra, - (bool)ipcPortRsrcParams.boolInitialConfig); - *p_ReplyLength = sizeof(uint32_t); - break; - } - case (FM_SET_NUM_OF_OPEN_DMAS): - { - t_FmIpcPortRsrcParams ipcPortRsrcParams; - - memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); - p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId, - (uint8_t)ipcPortRsrcParams.val, - (uint8_t)ipcPortRsrcParams.extra, - (bool)ipcPortRsrcParams.boolInitialConfig); - *p_ReplyLength = sizeof(uint32_t); - break; - } - case (FM_RESUME_STALLED_PORT): - *p_ReplyLength = sizeof(uint32_t); - p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]); - break; - case (FM_MASTER_IS_ALIVE): - { - uint8_t guestId = p_IpcMsg->msgBody[0]; - /* build the FM master partition IPC address */ - memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); - p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName); - if (p_Fm->h_IpcSessions[guestId] == NULL) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId)); - *(uint8_t*)(p_IpcReply->replyBody) = 1; - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); - break; - } - case (FM_IS_PORT_STALLED): - { - bool tmp; - - p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp); - *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp; - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); - break; - } - case (FM_RESET_MAC): - { - t_FmIpcMacParams ipcMacParams; - - memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams)); - p_IpcReply->error = (uint32_t)FmResetMac(p_Fm, - (e_FmMacType)(ipcMacParams.enumType), - ipcMacParams.id); - *p_ReplyLength = sizeof(uint32_t); - break; - } - case (FM_SET_MAC_MAX_FRAME): - { - t_Error err; - t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams; - - memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams)); - if ((err = FmSetMacMaxFrame(p_Fm, - (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType), - ipcMacMaxFrameParams.macParams.id, - ipcMacMaxFrameParams.maxFrameLength)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } - case (FM_GET_CLK_FREQ): - memcpy(p_IpcReply->replyBody, (uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, sizeof(uint16_t)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t); - break; - case (FM_FREE_PORT): - { - t_FmInterModulePortFreeParams portParams; - t_FmIpcPortFreeParams ipcPortParams; - - memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams)); - portParams.hardwarePortId = ipcPortParams.hardwarePortId; - portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType); -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - FmFreePortParams(h_Fm, &portParams); - break; - } - case (FM_REGISTER_INTR): - { - t_FmIpcRegisterIntr ipcRegIntr; - - memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr)); - p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId; - break; - } -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) - case (FM_DUMP_REGS): - { - t_Error err; - if ((err = FM_DumpRegs(h_Fm)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } - case (FM_DUMP_PORT_REGS): - { - t_Error err; - - if ((err = FmDumpPortRegs(h_Fm, p_IpcMsg->msgBody[0])) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } -#endif /* (defined(DEBUG_ERRORS) && ... */ - case (FM_GET_REV): - { - t_FmRevisionInfo revInfo; - t_FmIpcRevisionInfo ipcRevInfo; - - p_IpcReply->error = (uint32_t)FM_GetRevision(h_Fm, &revInfo); - ipcRevInfo.majorRev = revInfo.majorRev; - ipcRevInfo.minorRev = revInfo.minorRev; - memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcRevisionInfo)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcRevisionInfo); - break; - } - case (FM_DMA_STAT): - { - t_FmDmaStatus dmaStatus; - t_FmIpcDmaStatus ipcDmaStatus; - - FM_GetDmaStatus(h_Fm, &dmaStatus); - ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty; - ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError; - ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError; - ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError; - ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError; - memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); - break; - } - case (FM_ALLOC_FMAN_CTRL_EVENT_REG): - p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); - break; - case (FM_FREE_FMAN_CTRL_EVENT_REG): - FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]); - break; - case (FM_GET_TIMESTAMP_SCALE): - { - uint32_t timeStamp = FmGetTimeStampScale(h_Fm); - - memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); - break; - } - case (FM_GET_COUNTER): - { - e_FmCounters inCounter; - uint32_t outCounter; - - memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t)); - outCounter = FM_GetCounter(h_Fm, inCounter); - memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); - break; - } - case (FM_SET_FMAN_CTRL_EVENTS_ENABLE): - { - t_FmIpcFmanEvents ipcFmanEvents; - - memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents)); - FmSetFmanCtrlIntr(h_Fm, - ipcFmanEvents.eventRegId, - ipcFmanEvents.enableEvents); - break; - } - case (FM_GET_FMAN_CTRL_EVENTS_ENABLE): - { - uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]); - - memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); - break; - } - case (FM_GET_PHYS_MURAM_BASE): - { - t_FmPhysAddr physAddr; - t_FmIpcPhysAddr ipcPhysAddr; - - FmGetPhysicalMuramBase(h_Fm, &physAddr); - ipcPhysAddr.high = physAddr.high; - ipcPhysAddr.low = physAddr.low; - memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr)); - *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr); - break; - } - case (FM_ENABLE_RAM_ECC): - { - t_Error err; - - if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) || - ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) || - ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK)) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } - case (FM_DISABLE_RAM_ECC): - { - t_Error err; - - if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) || - ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) || - ((err = FM_DisableRamsEcc(h_Fm)) != E_OK)) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } - case (FM_SET_NUM_OF_FMAN_CTRL): - { - t_Error err; - t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls; - - memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls)); - if ((err = FmSetNumOfRiscsPerPort(h_Fm, - ipcPortNumOfFmanCtrls.hardwarePortId, - ipcPortNumOfFmanCtrls.numOfFmanCtrls)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - break; - } -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 - case (FM_10G_TX_ECC_WA): - p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]); - *p_ReplyLength = sizeof(uint32_t); - break; -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ - default: - *p_ReplyLength = 0; - RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); - } - return E_OK; -} - -static void ErrorIsrCB(t_Handle h_Fm) -{ -#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \ - { \ - if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \ - SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \ - else \ - p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ - } - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t pending; - - SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE); - - /* error interrupts */ - pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmepi); - if (!pending) - return; - - if(pending & ERR_INTR_EN_BMI) - BmiErrEvent(p_Fm); - if(pending & ERR_INTR_EN_QMI) - QmiErrEvent(p_Fm); - if(pending & ERR_INTR_EN_FPM) - FpmErrEvent(p_Fm); - if(pending & ERR_INTR_EN_DMA) - DmaErrEvent(p_Fm); - if(pending & ERR_INTR_EN_IRAM) - IramErrIntr(p_Fm); - if(pending & ERR_INTR_EN_MURAM) - MuramErrIntr(p_Fm); - if(pending & ERR_INTR_EN_PRS) - p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle); - if(pending & ERR_INTR_EN_PLCR) - p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle); - if(pending & ERR_INTR_EN_KG) - p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle); - - /* MAC events may belong to different partitions */ - if(pending & ERR_INTR_EN_1G_MAC0) - FM_M_CALL_1G_MAC_ERR_ISR(0); - if(pending & ERR_INTR_EN_1G_MAC1) - FM_M_CALL_1G_MAC_ERR_ISR(1); - if(pending & ERR_INTR_EN_1G_MAC2) - FM_M_CALL_1G_MAC_ERR_ISR(2); - if(pending & ERR_INTR_EN_1G_MAC3) - FM_M_CALL_1G_MAC_ERR_ISR(3); - if(pending & ERR_INTR_EN_1G_MAC4) - FM_M_CALL_1G_MAC_ERR_ISR(4); - if(pending & ERR_INTR_EN_10G_MAC0) - { - if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].guestId) - SendIpcIsr(p_Fm, e_FM_EV_ERR_10G_MAC0, pending); - else - p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].h_SrcHandle); - } -} - - -#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - int timeout = 1000; - t_Error err = E_OK; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - uint8_t rxHardwarePortId, txHardwarePortId; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_10G_TX_ECC_WA; - msg.msgBody[0] = macId; - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(macId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return (t_Error)(reply.error); - } - - SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED); - SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE); - - SW_PORT_ID_TO_HW_PORT_ID(rxHardwarePortId, e_FM_PORT_TYPE_RX_10G, macId); - SW_PORT_ID_TO_HW_PORT_ID(txHardwarePortId, e_FM_PORT_TYPE_TX_10G, macId); - if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) || - (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, - ("MAC should be initialized prior to rx and tx ports!")); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmextc, 0x40000000); - CORE_MemoryBarrier(); - while ((GET_UINT32(p_Fm->p_FmFpmRegs->fpmextc) & 0x40000000) && - --timeout) ; - if (!timeout) - return ERROR_CODE(E_TIMEOUT); - return E_OK; -} -#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ - -uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); - - if(p_Fm->guestId != NCSW_MASTER_ID) - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset")); - - return (p_Fm->baseAddr + FM_MM_PRS); -} - -uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); - - if(p_Fm->guestId != NCSW_MASTER_ID) - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset")); - - return (p_Fm->baseAddr + FM_MM_KG); -} - -uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); - - if(p_Fm->guestId != NCSW_MASTER_ID) - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset")); - - return (p_Fm->baseAddr + FM_MM_PLCR); -} - -t_Handle FmGetMuramHandle(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL); - - return (p_Fm->h_FmMuram); -} - -void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - t_FmIpcPhysAddr ipcPhysAddr; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_PHYS_MURAM_BASE; - replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - { - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr))) - { - REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch")); - return; - } - memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr)); - p_FmPhysAddr->high = ipcPhysAddr.high; - p_FmPhysAddr->low = ipcPhysAddr.low; - return ; - } - - /* General FM driver initialization */ - p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr; - p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32); -} - -t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint8_t i; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG; - replyLength = sizeof(uint32_t) + sizeof(uint8_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - *p_EventId = *(uint8_t*)(reply.replyBody); - - return (t_Error)(reply.error); - } - - for(i=0;iusedEventRegs[i]) - { - p_Fm->usedEventRegs[i] = TRUE; - *p_EventId = i; - break; - } - - if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS) - RETURN_ERROR(MAJOR, E_BUSY, ("No resource - Fman controller event register.")); - - return E_OK; -} - -void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_Error err; - t_FmIpcMsg msg; - - if(((t_Fm *)h_Fm)->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG; - msg.msgBody[0] = eventId; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(eventId), - NULL, - NULL, - NULL, - NULL)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - - ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE; -} - -void FmRegisterIntr(t_Handle h_Fm, - e_FmEventModules module, - uint8_t modId, - e_FmIntrType intrType, - void (*f_Isr) (t_Handle h_Arg), - t_Handle h_Arg) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint8_t event= 0; - t_FmIpcRegisterIntr fmIpcRegisterIntr; - t_Error err; - t_FmIpcMsg msg; - - ASSERT_COND(h_Fm); - - GET_FM_MODULE_EVENT(module, modId,intrType, event); - - /* register in local FM structure */ - ASSERT_COND(event != e_FM_EV_DUMMY_LAST); - p_Fm->intrMng[event].f_Isr = f_Isr; - p_Fm->intrMng[event].h_SrcHandle = h_Arg; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - if(p_Fm->h_IpcSessions[0]) - { - /* register in Master FM structure */ - fmIpcRegisterIntr.event = event; - fmIpcRegisterIntr.guestId = p_Fm->guestId; - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_REGISTER_INTR; - memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr), - NULL, - NULL, - NULL, - NULL)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - } - else - DBG(WARNING,("'Register interrupt' - unavailable - No IPC")); - } - -} - -void FmUnregisterIntr(t_Handle h_Fm, - e_FmEventModules module, - uint8_t modId, - e_FmIntrType intrType) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint8_t event= 0; - - ASSERT_COND(h_Fm); - - GET_FM_MODULE_EVENT(module, modId,intrType, event); - - ASSERT_COND(event != e_FM_EV_DUMMY_LAST); - p_Fm->intrMng[event].f_Isr = UnimplementedIsr; - p_Fm->intrMng[event].h_SrcHandle = NULL; -} - -void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_FmIpcFmanEvents fmanCtrl; - t_Error err; - t_FmIpcMsg msg; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - fmanCtrl.eventRegId = eventRegId; - fmanCtrl.enableEvents = enableEvents; - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE; - memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(fmanCtrl), - NULL, - NULL, - NULL, - NULL)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - - ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId], enableEvents); -} - -uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength, ctrlIntr; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE; - msg.msgBody[0] = eventRegId; - replyLength = sizeof(uint32_t) + sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(eventRegId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - { - REPORT_ERROR(MINOR, err, NO_MSG); - return 0; - } - if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) - { - REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return 0; - } - memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t)); - return ctrlIntr; - } - - return GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId]); -} - -void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) - { - ASSERT_COND(0); - /* TODO */ - } - - p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr; - p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg; -} - -void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) - { - ASSERT_COND(0); - /* TODO */ - } - - p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr; - p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL; -} - -void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - if(p_Fm->h_Pcd) - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set")); - - p_Fm->h_Pcd = h_FmPcd; - -} - -void FmUnregisterPcd(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - if(!p_Fm->h_Pcd) - REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("No PCD")); - - p_Fm->h_Pcd = NULL; - -} - -t_Handle FmGetPcdHandle(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - return p_Fm->h_Pcd; -} - -uint8_t FmGetId(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff); - - return p_Fm->p_FmStateStruct->fmId; -} - -t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls) -{ - - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg = 0; - t_Error err; - t_FmIpcPortNumOfFmanCtrls params; - t_FmIpcMsg msg; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - params.hardwarePortId = hardwarePortId; - params.numOfFmanCtrls = numOfFmanCtrls; - msg.msgId = FM_SET_NUM_OF_FMAN_CTRL; - memcpy(msg.msgBody, ¶ms, sizeof(params)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(params), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - - return E_OK; - } - - XX_LockSpinlock(p_Fm->h_Spinlock); - - tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT); - - /*TODO - maybe to put CTL# according to another criteria*/ - - if(numOfFmanCtrls == 2) - tmpReg = FPM_PORT_FM_CTL2 | FPM_PORT_FM_CTL1; - - /* order restoration */ - if(hardwarePortId%2) - tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL1; - else - tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL2; - - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg); - XX_UnlockSpinlock(p_Fm->h_Spinlock); - - return E_OK; -} - -t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - uint8_t hardwarePortId = p_PortParams->hardwarePortId; - t_FmIpcPortInInitParams portInParams; - t_FmIpcPhysAddr ipcPhysAddr; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - portInParams.hardwarePortId = p_PortParams->hardwarePortId; - portInParams.enumPortType = (uint32_t)p_PortParams->portType; - portInParams.boolIndependentMode = (uint8_t)p_PortParams->independentMode; - portInParams.liodnOffset = p_PortParams->liodnOffset; - portInParams.numOfTasks = p_PortParams->numOfTasks; - portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks; - portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas; - portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas; - portInParams.sizeOfFifo = p_PortParams->sizeOfFifo; - portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo; - portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; - portInParams.liodnBase = p_PortParams->liodnBase; - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_SET_PORT_PARAMS; - memcpy(msg.msgBody, &portInParams, sizeof(portInParams)); - replyLength = (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(portInParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr)); - p_PortParams->fmMuramPhysBaseAddr.high = ipcPhysAddr.high; - p_PortParams->fmMuramPhysBaseAddr.low = ipcPhysAddr.low; - - return (t_Error)(reply.error); - } - - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - XX_LockSpinlock(p_Fm->h_Spinlock); - - if(p_PortParams->independentMode) - { - /* set port parameters */ - p_Fm->independentMode = p_PortParams->independentMode; - /* disable dispatch limit */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, 0); - } - - if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - { - if(p_Fm->hcPortInitialized) - { - XX_UnlockSpinlock(p_Fm->h_Spinlock); - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed.")); - } - else - p_Fm->hcPortInitialized = TRUE; - } - p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType; - - err = FmSetNumOfTasks(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfTasks, p_PortParams->numOfExtraTasks, TRUE); - if(err) - { - XX_UnlockSpinlock(p_Fm->h_Spinlock); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) - /* for transmit & O/H ports */ - { - uint8_t enqTh; - uint8_t deqTh; - bool update = FALSE; - - /* update qmi ENQ/DEQ threshold */ - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth; - tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc); - enqTh = (uint8_t)(tmpReg>>8); - /* if enqTh is too big, we reduce it to the max value that is still OK */ - if(enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums)) - { - enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); - tmpReg &= ~QMI_CFG_ENQ_MASK; - tmpReg |= ((uint32_t)enqTh << 8); - update = TRUE; - } - - deqTh = (uint8_t)tmpReg; - /* if deqTh is too small, we enlarge it to the min value that is still OK. - deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */ - if((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1)) - { - deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); - tmpReg &= ~QMI_CFG_DEQ_MASK; - tmpReg |= (uint32_t)deqTh; - update = TRUE; - } - if(update) - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg); - } -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - -#ifdef FM_LOW_END_RESTRICTION - if((hardwarePortId==0x1) || (hardwarePortId==0x29)) - { - if(p_Fm->p_FmStateStruct->lowEndRestriction) - { - XX_UnlockSpinlock(p_Fm->h_Spinlock); - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1.")); - } - else - p_Fm->p_FmStateStruct->lowEndRestriction = TRUE; - } -#endif /* FM_LOW_END_RESTRICTION */ - - err = FmSetSizeOfFifo(p_Fm, - p_PortParams->hardwarePortId, - p_PortParams->portType, - p_PortParams->independentMode, - &p_PortParams->sizeOfFifo, - p_PortParams->extraSizeOfFifo, - p_PortParams->deqPipelineDepth, - NULL, - TRUE); - if(err) - { - XX_UnlockSpinlock(p_Fm->h_Spinlock); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - err = FmSetNumOfOpenDmas(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfOpenDmas, p_PortParams->numOfExtraOpenDmas, TRUE); - if(err) - { - XX_UnlockSpinlock(p_Fm->h_Spinlock); - RETURN_ERROR(MAJOR, err, NO_MSG); - } - - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], (uint32_t)p_PortParams->liodnOffset); - - tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT); - if(p_PortParams->independentMode) - { - if((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)) - tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL1; - else - tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL2; - } - else - { - tmpReg |= (FPM_PORT_FM_CTL2|FPM_PORT_FM_CTL1); - - /* order restoration */ - if(hardwarePortId%2) - tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT); - else - tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT); - } - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg); - - { -#ifdef FM_PARTITION_ARRAY - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_Fm, &revInfo); - if (revInfo.majorRev >= 2) -#endif /* FM_PARTITION_ARRAY */ - { - /* set LIODN base for this port */ - tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2]); - if(hardwarePortId%2) - { - tmpReg &= ~FM_LIODN_BASE_MASK; - tmpReg |= (uint32_t)p_PortParams->liodnBase; - } - else - { - tmpReg &= ~(FM_LIODN_BASE_MASK<< DMA_LIODN_SHIFT); - tmpReg |= (uint32_t)p_PortParams->liodnBase << DMA_LIODN_SHIFT; - } - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], tmpReg); - } - } - - FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr); - XX_UnlockSpinlock(p_Fm->h_Spinlock); - - return E_OK; -} - -void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - uint8_t hardwarePortId = p_PortParams->hardwarePortId; - uint8_t numOfTasks; - t_Error err; - t_FmIpcPortFreeParams portParams; - t_FmIpcMsg msg; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - portParams.hardwarePortId = p_PortParams->hardwarePortId; - portParams.enumPortType = (uint32_t)p_PortParams->portType; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_FREE_PORT; - memcpy(msg.msgBody, &portParams, sizeof(portParams)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(portParams), - NULL, - NULL, - NULL, - NULL)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - XX_LockSpinlock(p_Fm->h_Spinlock); - - - if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) - { - ASSERT_COND(p_Fm->hcPortInitialized); - p_Fm->hcPortInitialized = FALSE; - } - - p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY; - - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); - /* free numOfTasks */ - numOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks); - p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks; - - /* free numOfOpenDmas */ - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= ((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); - p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= (((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); - - /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */ - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; - tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); - - /* free sizeOfFifo */ - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= - (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS)); - p_Fm->p_FmStateStruct->accumulatedFifoSize -= - (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS); - - /* clear registers */ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], 0); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], 0); - /* WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], 0); */ - -#ifdef FM_PORT_DISABLED_ERRATA_FMANx9 - /* this errata means that when a port is taken down, other port may not use its - * resources for a while as it may still be using it (in case of reject). - */ - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - XX_UDelay(100000); - } -#endif /* FM_PORT_DISABLED_ERRATA_FMANx9 */ - -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) - /* for transmit & O/H ports */ - { - uint8_t enqTh; - uint8_t deqTh; - - tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc); - /* update qmi ENQ/DEQ threshold */ - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth; - - /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, - so we can enlarge enqTh */ - enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); - tmpReg &= ~QMI_CFG_ENQ_MASK; - tmpReg |= ((uint32_t)enqTh << QMI_CFG_ENQ_SHIFT); - - /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, - so we can reduce deqTh */ - deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); - tmpReg &= ~QMI_CFG_DEQ_MASK; - tmpReg |= (uint32_t)deqTh; - - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg); - } -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - -#ifdef FM_LOW_END_RESTRICTION - if((hardwarePortId==0x1) || (hardwarePortId==0x29)) - p_Fm->p_FmStateStruct->lowEndRestriction = FALSE; -#endif /* FM_LOW_END_RESTRICTION */ - XX_UnlockSpinlock(p_Fm->h_Spinlock); -} - -t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_IS_PORT_STALLED; - msg.msgBody[0] = hardwarePortId; - replyLength = sizeof(uint32_t) + sizeof(uint8_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(hardwarePortId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody)); - - return (t_Error)(reply.error); - } - - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]); - *p_IsStalled = (bool)!!(tmpReg & FPM_PS_STALLED); - - return E_OK; -} - -t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - t_Error err; - bool isStalled; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_RESUME_STALLED_PORT; - msg.msgBody[0] = hardwarePortId; - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(hardwarePortId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return (t_Error)(reply.error); - } - - /* Get port status */ - err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled); - if(err) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status")); - if (!isStalled) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is not stalled")); - - tmpReg = (uint32_t)((hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT) | FPM_PRC_REALSE_STALLED); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg); - - return E_OK; -} - -t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t bitMask, timeout = 1000; - t_FmIpcMacParams macParams; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - if(p_Fm->h_IpcSessions[0]) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - macParams.id = macId; - macParams.enumType = (uint32_t)type; - msg.msgId = FM_RESET_MAC; - memcpy(msg.msgBody, &macParams, sizeof(macParams)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(macParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return (t_Error)(reply.error); - } - else - if(!p_Fm->p_FmFpmRegs) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("No IPC and no registers address")); - } - - /* Get the relevant bit mask */ - if (type == e_FM_MAC_10G) - { - switch(macId) - { - case(0): - bitMask = FPM_RSTC_10G0_RESET; - break; - default: - RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id")); - } - } - else - { - switch(macId) - { - case(0): - bitMask = FPM_RSTC_1G0_RESET; - break; - case(1): - bitMask = FPM_RSTC_1G1_RESET; - break; - case(2): - bitMask = FPM_RSTC_1G2_RESET; - break; - case(3): - bitMask = FPM_RSTC_1G3_RESET; - break; - case(4): - bitMask = FPM_RSTC_1G4_RESET; - break; - default: - RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id")); - } - } - - /* reset */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, bitMask); - while ((GET_UINT32(p_Fm->p_FmFpmRegs->fmrstc) & bitMask) && - --timeout) ; - if (!timeout) - return ERROR_CODE(E_TIMEOUT); - return E_OK; -} - -t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_FmIpcMacMaxFrameParams macMaxFrameLengthParams; - t_Error err; - t_FmIpcMsg msg; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - macMaxFrameLengthParams.macParams.id = macId; - macMaxFrameLengthParams.macParams.enumType = (uint32_t)type; - macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu; - msg.msgId = FM_SET_MAC_MAX_FRAME; - memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams)); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; - } - -#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)) - if (type == e_FM_MAC_10G) - p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu; - else -#else - UNUSED(type); -#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */ - p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu; - - return E_OK; -} - -uint16_t FmGetClockFreq(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - /* for MC environment: this depends on the - * fact that fmClkFreq was properly initialized at "init". */ - return p_Fm->p_FmStateStruct->fmClkFreq; -} - -uint32_t FmGetTimeStampScale(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength, timeStamp; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_TIMESTAMP_SCALE; - replyLength = sizeof(uint32_t) + sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - - memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t)); - return timeStamp; - } - - if(!p_Fm->p_FmStateStruct->enabledTimeStamp) - FmEnableTimeStamp(p_Fm); - - return p_Fm->p_FmStateStruct->count1MicroBit; -} - -bool FmRamsEccIsExternalCtl(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr); - if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL) - return TRUE; - else - return FALSE; -} - -t_Error FmEnableRamsEcc(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - p_Fm->p_FmStateStruct->ramsEccOwners++; - p_Fm->p_FmStateStruct->internalCall = TRUE; - - return FM_EnableRamsEcc(p_Fm); -} - -t_Error FmDisableRamsEcc(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners); - p_Fm->p_FmStateStruct->ramsEccOwners--; - - if(p_Fm->p_FmStateStruct->ramsEccOwners==0) - { - p_Fm->p_FmStateStruct->internalCall = TRUE; - return FM_DisableRamsEcc(p_Fm); - } - return E_OK; -} - -uint8_t FmGetGuestId(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - return p_Fm->guestId; -} - -bool FmIsMaster(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - return (p_Fm->guestId == NCSW_MASTER_ID); -} - -t_Error FmSetSizeOfFifo(t_Handle h_Fm, - uint8_t hardwarePortId, - e_FmPortType portType, - bool independentMode, - uint32_t *p_SizeOfFifo, - uint32_t extraSizeOfFifo, - uint8_t deqPipelineDepth, - t_FmInterModulePortRxPoolsParams *p_RxPoolsParams, - bool initialConfig) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint8_t relativePortId; - uint16_t macMaxFrameLength = 0, oldVal; - uint32_t minFifoSizeRequired = 0, sizeOfFifo, tmpReg = 0; - t_FmIpcPortFifoParams fifoParams; - t_Error err; - - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - ASSERT_COND(initialConfig || p_RxPoolsParams); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - ASSERT_COND(p_RxPoolsParams); - - memset(&fifoParams, 0, sizeof(fifoParams)); - fifoParams.rsrcParams.hardwarePortId = hardwarePortId; - fifoParams.rsrcParams.val = *p_SizeOfFifo; - fifoParams.rsrcParams.extra = extraSizeOfFifo; - fifoParams.enumPortType = (uint32_t)portType; - fifoParams.boolIndependentMode = (uint8_t)independentMode; - fifoParams.deqPipelineDepth = deqPipelineDepth; - fifoParams.numOfPools = p_RxPoolsParams->numOfPools; - fifoParams.secondLargestBufSize = p_RxPoolsParams->secondLargestBufSize; - fifoParams.largestBufSize = p_RxPoolsParams->largestBufSize; - fifoParams.boolInitialConfig = (uint8_t)initialConfig; - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_SET_SIZE_OF_FIFO; - memcpy(msg.msgBody, &fifoParams, sizeof(fifoParams)); - replyLength = sizeof(uint32_t) + sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(fifoParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - memcpy((uint8_t*)p_SizeOfFifo, reply.replyBody, sizeof(uint32_t)); - - return (t_Error)(reply.error); - } - sizeOfFifo = *p_SizeOfFifo; - /* if neseccary (cases where frame length is relevant), update sizeOfFifo field. */ - if((portType == e_FM_PORT_TYPE_TX) || ((portType == e_FM_PORT_TYPE_RX) && independentMode)) - { - HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); - ASSERT_COND(relativePortId < FM_MAX_NUM_OF_1G_MACS); - macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths1G[relativePortId]; - } - -#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)) - if((portType == e_FM_PORT_TYPE_TX_10G) || ((portType == e_FM_PORT_TYPE_RX_10G) && independentMode)) - { - HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); - ASSERT_COND(relativePortId < FM_MAX_NUM_OF_10G_MACS); - macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths10G[relativePortId]; - } -#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */ - - /*************************/ - /* TX PORTS */ - /*************************/ - if((portType == e_FM_PORT_TYPE_TX) || (portType == e_FM_PORT_TYPE_TX_10G)) - { - if(independentMode) - minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ? - (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS : - macMaxFrameLength) + - (3*BMI_FIFO_UNITS)); - else - minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ? - (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS : - macMaxFrameLength) + - (deqPipelineDepth+3)*BMI_FIFO_UNITS); - } - /*************************/ - /* RX IM PORTS */ - /*************************/ - else if(((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && independentMode) - minFifoSizeRequired = (uint32_t)(((macMaxFrameLength % BMI_FIFO_UNITS) ? - ((macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : - macMaxFrameLength) + - (4*BMI_FIFO_UNITS)); - - /* for Rx (non-Im) ports or OP, buffer pools are relevant for fifo size. - If this routine is called as part of the "GetSet" routine, initialConfig is TRUE - and these checks where done in the port routine. - If it is called by an explicit user request ("SetSizeOfFifo"), than these parameters - should be checked/updated */ - if(!initialConfig && - ((portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || - (((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && !independentMode))) - { - if((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) - { - /*************************/ - /* RX non-IM PORTS */ - /*************************/ -#ifdef FM_FIFO_ALLOCATION_OLD_ALG - t_FmRevisionInfo revInfo; - - FM_GetRevision(p_Fm, &revInfo); - if(revInfo.majorRev != 4) - minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->largestBufSize % BMI_FIFO_UNITS) ? - ((p_RxPoolsParams->largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : - p_RxPoolsParams->largestBufSize) + - (7*BMI_FIFO_UNITS)); - else -#endif /* FM_FIFO_ALLOCATION_OLD_ALG */ - { - if(p_RxPoolsParams->numOfPools == 1) - minFifoSizeRequired = 8*BMI_FIFO_UNITS; - else - { - minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->secondLargestBufSize % BMI_FIFO_UNITS) ? - ((p_RxPoolsParams->secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : - p_RxPoolsParams->secondLargestBufSize) + - (7*BMI_FIFO_UNITS)); - if((sizeOfFifo < minFifoSizeRequired)) - { - DBG(WARNING, ("User set FIFO size for Rx port is not optimized. (not modified by driver)")); - minFifoSizeRequired = 8*BMI_FIFO_UNITS; - } - } - } - } - else - { - /*************************/ - /* OP PORTS */ - /*************************/ - /* check if pool size is not too big */ - if(p_RxPoolsParams->largestBufSize > sizeOfFifo ) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Largest pool size is bigger than ports committed fifo size")); - } - } - - - if (minFifoSizeRequired && (sizeOfFifo < minFifoSizeRequired)) - { - sizeOfFifo = minFifoSizeRequired; - DBG(WARNING, ("FIFO size enlarged to %d for port %#x", minFifoSizeRequired, hardwarePortId)); - } - - if(initialConfig) - oldVal = 0; - else - { - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]); - /* read into oldVal the current extra fifo size */ - oldVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT); - } - - if(extraSizeOfFifo > oldVal) - p_Fm->p_FmStateStruct->extraFifoPoolSize = NCSW_MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo); - - if(!initialConfig) - /* read into oldVal the current num of tasks */ - oldVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS); - - /* check that there are enough uncommitted fifo size */ - if((p_Fm->p_FmStateStruct->accumulatedFifoSize - oldVal + sizeOfFifo) > - (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size.")); - else - { - /* update acummulated */ - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= oldVal); - p_Fm->p_FmStateStruct->accumulatedFifoSize -= oldVal; - p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo; - /* calculate reg */ - tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) | - ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT)); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg); - } - *p_SizeOfFifo = sizeOfFifo; - - return E_OK; -} - -t_Error FmSetNumOfTasks(t_Handle h_Fm, - uint8_t hardwarePortId, - uint8_t numOfTasks, - uint8_t numOfExtraTasks, - bool initialConfig) -{ - t_Fm *p_Fm = (t_Fm *)h_Fm; - uint8_t oldVal; - uint32_t tmpReg = 0; - t_FmIpcPortRsrcParams rsrcParams; - t_Error err; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - rsrcParams.hardwarePortId = hardwarePortId; - rsrcParams.val = numOfTasks; - rsrcParams.extra = numOfExtraTasks; - rsrcParams.boolInitialConfig = (uint8_t)initialConfig; - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_SET_NUM_OF_TASKS; - memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(rsrcParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return (t_Error)(reply.error); - } - - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - - if(initialConfig) - oldVal = 0; - else - { - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); - /* read into oldVal the current extra tasks */ - oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT); - } - - if(numOfExtraTasks > oldVal) - p_Fm->p_FmStateStruct->extraTasksPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks); - - if(!initialConfig) - /* read into oldVal the current num of tasks */ - oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1); - - /* check that there are enough uncommitted tasks */ - if((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - oldVal + numOfTasks) > - (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize)) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, - ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.", - p_Fm->p_FmStateStruct->fmId)); - else - { - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= oldVal); - /* update acummulated */ - p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= oldVal; - p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks; - /* calculate reg */ - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); - tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) | - (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg); - } - - return E_OK; -} - -t_Error FmSetNumOfOpenDmas(t_Handle h_Fm, - uint8_t hardwarePortId, - uint8_t numOfOpenDmas, - uint8_t numOfExtraOpenDmas, - bool initialConfig) - -{ - t_Fm *p_Fm = (t_Fm *)h_Fm; - uint8_t oldVal; - uint32_t tmpReg = 0; - t_FmIpcPortRsrcParams rsrcParams; - t_Error err; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - rsrcParams.hardwarePortId = hardwarePortId; - rsrcParams.val = numOfOpenDmas; - rsrcParams.extra = numOfExtraOpenDmas; - rsrcParams.boolInitialConfig = (uint8_t)initialConfig; - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_SET_NUM_OF_OPEN_DMAS; - memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); - replyLength = sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) + sizeof(rsrcParams), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != sizeof(uint32_t)) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return (t_Error)(reply.error); - } - - ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); - - if(initialConfig) - oldVal = 0; - else - { - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]); - /* read into oldVal the current extra tasks */ - oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT); - } - - if(numOfExtraOpenDmas > oldVal) - p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas); - - if(!initialConfig) - /* read into oldVal the current num of tasks */ - oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1); - - /* check that there are enough uncommitted open DMA's */ - ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= oldVal); - if((p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + numOfOpenDmas) > - p_Fm->p_FmStateStruct->maxNumOfOpenDmas) - RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, - ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.", - p_Fm->p_FmStateStruct->fmId)); - else - { - /* update acummulated */ - p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= oldVal; - p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas; - /* calculate reg */ - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); - tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) | - (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg); - - /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */ - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; - tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); - } - - return E_OK; -} - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FmDumpPortRegs (t_Handle h_Fm,uint8_t hardwarePortId) -{ - t_Fm *p_Fm = (t_Fm *)h_Fm; - t_FmIpcMsg msg; - t_Error err; - - DECLARE_DUMP; - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_DUMP_PORT_REGS; - msg.msgBody[0] = hardwarePortId; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(hardwarePortId), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; - } - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId))); - DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t)); - - DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId ))); - DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t)); - - DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], ("bm_ppid for port %u", (hardwarePortId))); - DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], sizeof(uint32_t)); - - return E_OK; -} -#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ - - -/*****************************************************************************/ -/* API Init unit functions */ -/*****************************************************************************/ -t_Handle FM_Config(t_FmParams *p_FmParam) -{ - t_Fm *p_Fm; - uint8_t i; - uintptr_t baseAddr; - - SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL); - SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) || - (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)), - E_INVALID_VALUE, NULL); - - baseAddr = p_FmParam->baseAddr; - - /* Allocate FM structure */ - p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm)); - if (!p_Fm) - { - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure")); - return NULL; - } - memset(p_Fm, 0, sizeof(t_Fm)); - - p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct)); - if (!p_Fm->p_FmStateStruct) - { - XX_Free(p_Fm); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure")); - return NULL; - } - memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct)); - - /* Initialize FM parameters which will be kept by the driver */ - p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; - p_Fm->guestId = p_FmParam->guestId; - - for(i=0; ip_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY; - - /* Allocate the FM driver's parameters structure */ - p_Fm->p_FmDriverParam = (t_FmDriverParam *)XX_Malloc(sizeof(t_FmDriverParam)); - if (!p_Fm->p_FmDriverParam) - { - XX_Free(p_Fm->p_FmStateStruct); - XX_Free(p_Fm); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters")); - return NULL; - } - memset(p_Fm->p_FmDriverParam, 0, sizeof(t_FmDriverParam)); - - /* Initialize FM parameters which will be kept by the driver */ - p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; - p_Fm->h_FmMuram = p_FmParam->h_FmMuram; - p_Fm->h_App = p_FmParam->h_App; - p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq; - p_Fm->f_Exception = p_FmParam->f_Exception; - p_Fm->f_BusError = p_FmParam->f_BusError; - p_Fm->p_FmFpmRegs = (t_FmFpmRegs *)UINT_TO_PTR(baseAddr + FM_MM_FPM); - p_Fm->p_FmBmiRegs = (t_FmBmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); - p_Fm->p_FmQmiRegs = (t_FmQmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_QMI); - p_Fm->p_FmDmaRegs = (t_FmDmaRegs *)UINT_TO_PTR(baseAddr + FM_MM_DMA); - p_Fm->baseAddr = baseAddr; - p_Fm->p_FmStateStruct->irq = p_FmParam->irq; - p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq; - p_Fm->hcPortInitialized = FALSE; - p_Fm->independentMode = FALSE; - p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; - p_Fm->p_FmStateStruct->totalNumOfTasks = DEFAULT_totalNumOfTasks; - p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize; - p_Fm->p_FmStateStruct->maxNumOfOpenDmas = DEFAULT_maxNumOfOpenDmas; - p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS; - p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions; - for(i = 0;ip_FmStateStruct->macMaxFrameLengths1G[i] = DEFAULT_mtu; -#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) - for(i = 0;ip_FmStateStruct->macMaxFrameLengths10G[i] = DEFAULT_mtu; -#endif /*defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)*/ - - p_Fm->h_Spinlock = XX_InitSpinlock(); - if (!p_Fm->h_Spinlock) - { - XX_Free(p_Fm->p_FmDriverParam); - XX_Free(p_Fm->p_FmStateStruct); - XX_Free(p_Fm); - REPORT_ERROR(MAJOR, E_INVALID_STATE, ("cant allocate spinlock!")); - return NULL; - } - -#ifdef FM_PARTITION_ARRAY - /* Initialize FM driver parameters parameters (for initialization phase only) */ - memcpy(p_Fm->p_FmDriverParam->liodnBasePerPort, p_FmParam->liodnBasePerPort, FM_SIZE_OF_LIODN_TABLE*sizeof(uint16_t)); -#endif /* FM_PARTITION_ARRAY */ - - /*p_Fm->p_FmDriverParam->numOfPartitions = p_FmParam->numOfPartitions; */ - p_Fm->p_FmDriverParam->enCounters = FALSE; - - p_Fm->p_FmDriverParam->resetOnInit = DEFAULT_resetOnInit; - - p_Fm->p_FmDriverParam->thresholds.dispLimit = DEFAULT_dispLimit; - p_Fm->p_FmDriverParam->thresholds.prsDispTh = DEFAULT_prsDispTh; - p_Fm->p_FmDriverParam->thresholds.plcrDispTh = DEFAULT_plcrDispTh; - p_Fm->p_FmDriverParam->thresholds.kgDispTh = DEFAULT_kgDispTh; - p_Fm->p_FmDriverParam->thresholds.bmiDispTh = DEFAULT_bmiDispTh; - p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh = DEFAULT_qmiEnqDispTh; - p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh = DEFAULT_qmiDeqDispTh; - p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh = DEFAULT_fmCtl1DispTh; - p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh = DEFAULT_fmCtl2DispTh; - - p_Fm->p_FmDriverParam->dmaStopOnBusError = DEFAULT_dmaStopOnBusError; - - p_Fm->p_FmDriverParam->dmaCacheOverride = DEFAULT_cacheOverride; - p_Fm->p_FmDriverParam->dmaAidMode = DEFAULT_aidMode; - p_Fm->p_FmDriverParam->dmaAidOverride = DEFAULT_aidOverride; - p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = DEFAULT_axiDbgNumOfBeats; - p_Fm->p_FmDriverParam->dmaCamNumOfEntries = DEFAULT_dmaCamNumOfEntries; - p_Fm->p_FmDriverParam->dmaWatchdog = DEFAULT_dmaWatchdog; - - p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency = DEFAULT_dmaCommQLow; - p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency = DEFAULT_dmaCommQHigh; - p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency = DEFAULT_dmaReadIntBufLow; - p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency = DEFAULT_dmaReadIntBufHigh; - p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency = DEFAULT_dmaWriteIntBufLow; - p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency = DEFAULT_dmaWriteIntBufHigh; - p_Fm->p_FmDriverParam->dmaSosEmergency = DEFAULT_dmaSosEmergency; - - p_Fm->p_FmDriverParam->dmaDbgCntMode = DEFAULT_dmaDbgCntMode; - - p_Fm->p_FmDriverParam->dmaEnEmergency = FALSE; - p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = FALSE; - p_Fm->p_FmDriverParam->catastrophicErr = DEFAULT_catastrophicErr; - p_Fm->p_FmDriverParam->dmaErr = DEFAULT_dmaErr; - p_Fm->p_FmDriverParam->haltOnExternalActivation = DEFAULT_haltOnExternalActivation; - p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = DEFAULT_haltOnUnrecoverableEccError; - p_Fm->p_FmDriverParam->enIramTestMode = FALSE; - p_Fm->p_FmDriverParam->enMuramTestMode = FALSE; - p_Fm->p_FmDriverParam->externalEccRamsEnable = DEFAULT_externalEccRamsEnable; - - p_Fm->p_FmDriverParam->fwVerify = DEFAULT_VerifyUcode; - p_Fm->p_FmDriverParam->firmware.size = p_FmParam->firmware.size; - if (p_Fm->p_FmDriverParam->firmware.size) - { - p_Fm->p_FmDriverParam->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->p_FmDriverParam->firmware.size); - if (!p_Fm->p_FmDriverParam->firmware.p_Code) - { - XX_FreeSpinlock(p_Fm->h_Spinlock); - XX_Free(p_Fm->p_FmStateStruct); - XX_Free(p_Fm->p_FmDriverParam); - XX_Free(p_Fm); - REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code")); - return NULL; - } - memcpy(p_Fm->p_FmDriverParam->firmware.p_Code, p_FmParam->firmware.p_Code, p_Fm->p_FmDriverParam->firmware.size); - } - - return p_Fm; -} - -/**************************************************************************//** - @Function FM_Init - - @Description Initializes the FM module - - @Param[in] h_Fm - FM module descriptor - - @Return E_OK on success; Error code otherwise. -*//***************************************************************************/ -t_Error FM_Init(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_FmDriverParam *p_FmDriverParam = NULL; - t_Error err = E_OK; - uint32_t tmpReg, cfgReg = 0; - int i; - uint16_t periodInFmClocks; - uint8_t remainder; - t_FmRevisionInfo revInfo; - - SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - uint8_t isMasterAlive; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - - /* build the FM guest partition IPC address */ - if(Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); - - /* build the FM master partition IPC address */ - memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); - if(Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); - - for(i=0;iintrMng[i].f_Isr = UnimplementedIsr; - - p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName); - if (p_Fm->h_IpcSessions[0]) - { - err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_MASTER_IS_ALIVE; - msg.msgBody[0] = p_Fm->guestId; - replyLength = sizeof(uint32_t) + sizeof(uint8_t); - do - { - blockingFlag = TRUE; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId)+sizeof(p_Fm->guestId), - (uint8_t*)&reply, - &replyLength, - IpcMsgCompletionCB, - h_Fm)) != E_OK) - REPORT_ERROR(MINOR, err, NO_MSG); - while(blockingFlag) ; - if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - isMasterAlive = *(uint8_t*)(reply.replyBody); - } while (!isMasterAlive); - - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_CLK_FREQ; - replyLength = sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(replyLength != (sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - memcpy((uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, reply.replyBody, sizeof(uint16_t)); - } - else - { - DBG(WARNING, ("FM Guest mode - without IPC")); - if(!p_Fm->p_FmStateStruct->fmClkFreq ) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC")); - if(!p_Fm->baseAddr) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No baseAddr configured for guest without IPC")); - } - - XX_Free(p_Fm->p_FmDriverParam); - p_Fm->p_FmDriverParam = NULL; - - if ((p_Fm->guestId == NCSW_MASTER_ID) || - (p_Fm->h_IpcSessions[0])) - { - FM_DisableRamsEcc(p_Fm); - FmMuramClear(p_Fm->h_FmMuram); - FM_EnableRamsEcc(p_Fm); - } - - return E_OK; - } - - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - FM_GetRevision(p_Fm, &revInfo); - -#ifdef FM_NO_DISPATCH_RAM_ECC - if (revInfo.majorRev != 4) - p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC; -#endif /* FM_NO_DISPATCH_RAM_ECC */ - -#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_LIST_RAM_ECC; -#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */ - -#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_PIPELINE_ECC; -#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */ - -#ifdef FM_QMI_NO_ECC_EXCEPTIONS - if (revInfo.majorRev == 4) - p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC); -#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ - - CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters); - - p_FmDriverParam = p_Fm->p_FmDriverParam; - - FmMuramClear(p_Fm->h_FmMuram); - -#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 - if (p_FmDriverParam->resetOnInit) - { - t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); - uint32_t debug_reg; - - /* write to IRAM first location the debug instruction */ - WRITE_UINT32(p_Iram->iadd, 0); - while (GET_UINT32(p_Iram->iadd) != 0) ; - WRITE_UINT32(p_Iram->idata, FM_UCODE_DEBUG_INSTRUCTION); - - WRITE_UINT32(p_Iram->iadd, 0); - while (GET_UINT32(p_Iram->iadd) != 0) ; - while (GET_UINT32(p_Iram->idata) != FM_UCODE_DEBUG_INSTRUCTION) ; - - /* Enable patch from IRAM */ - WRITE_UINT32(p_Iram->iready, IRAM_READY); - XX_UDelay(100); - - /* reset FMAN */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET); - XX_UDelay(100); - - /* verify breakpoint debug status register */ - debug_reg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET)); -#ifndef NCSW_LINUX - if(!debug_reg) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid debug status register value = 0")); -#else - if(!debug_reg) - DBG(INFO,("Invalid debug status register value = 0")); -#endif - /*************************************/ - /* Load FMan-Controller code to Iram */ - /*************************************/ - if (ClearIRam(p_Fm) != E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - if (p_Fm->p_FmDriverParam->firmware.p_Code && - (LoadFmanCtrlCode(p_Fm) != E_OK)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - XX_UDelay(100); - - /* reset FMAN again to start the microcode */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET); - XX_UDelay(1000); - } - else - { -#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ - if(p_FmDriverParam->resetOnInit) - { - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET); - XX_UDelay(100); - } - - /*************************************/ - /* Load FMan-Controller code to Iram */ - /*************************************/ - if (ClearIRam(p_Fm) != E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); - if (p_Fm->p_FmDriverParam->firmware.p_Code && - (LoadFmanCtrlCode(p_Fm) != E_OK)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 - } -#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ - -#ifdef FM_CAPWAP_SUPPORT - /* save first 256 byte in MURAM */ - p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0)); - if (!p_Fm->resAddr) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed")); - - WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256); -#endif /* FM_CAPWAP_SUPPORT */ - - /* General FM driver initialization */ - p_Fm->fmMuramPhysBaseAddr = (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM))); - for(i=0;iintrMng[i].f_Isr = UnimplementedIsr; - for(i=0;ifmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr; - - /**********************/ - /* Init DMA Registers */ - /**********************/ - /* clear status reg events */ - tmpReg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC); - /*tmpReg |= (DMA_STATUS_SYSTEM_DPEXT_ECC | DMA_STATUS_FM_DPEXT_ECC | DMA_STATUS_SYSTEM_DPDAT_ECC | DMA_STATUS_FM_DPDAT_ECC | DMA_STATUS_FM_SPDAT_ECC);*/ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr) | tmpReg); - - /* configure mode register */ - tmpReg = 0; - tmpReg |= p_FmDriverParam->dmaCacheOverride << DMA_MODE_CACHE_OR_SHIFT; - if(p_FmDriverParam->dmaAidOverride) - tmpReg |= DMA_MODE_AID_OR; - if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_BUS_ERROR) - tmpReg |= DMA_MODE_BER; - if ((p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_SYSTEM_WRITE_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_READ_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_FM_WRITE_ECC)) - tmpReg |= DMA_MODE_ECC; - if(p_FmDriverParam->dmaStopOnBusError) - tmpReg |= DMA_MODE_SBER; - tmpReg |= (uint32_t)(p_FmDriverParam->dmaAxiDbgNumOfBeats - 1) << DMA_MODE_AXI_DBG_SHIFT; - if (p_FmDriverParam->dmaEnEmergency) - { - tmpReg |= p_FmDriverParam->dmaEmergency.emergencyBusSelect; - tmpReg |= p_FmDriverParam->dmaEmergency.emergencyLevel << DMA_MODE_EMERGENCY_LEVEL_SHIFT; - if(p_FmDriverParam->dmaEnEmergencySmoother) - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr, p_FmDriverParam->dmaEmergencySwitchCounter); - } - tmpReg |= ((p_FmDriverParam->dmaCamNumOfEntries/DMA_CAM_UNITS) - 1) << DMA_MODE_CEN_SHIFT; - - tmpReg |= DMA_MODE_SECURE_PROT; - tmpReg |= p_FmDriverParam->dmaDbgCntMode << DMA_MODE_DBG_SHIFT; - tmpReg |= p_FmDriverParam->dmaAidMode << DMA_MODE_AID_MODE_SHIFT; - -#ifdef FM_PEDANTIC_DMA - tmpReg |= DMA_MODE_EMERGENCY_READ; -#endif /* FM_PEDANTIC_DMA */ - - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); - - /* configure thresholds register */ - tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.assertEmergency << DMA_THRESH_COMMQ_SHIFT) | - ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.assertEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) | - ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.assertEmergency); - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmtr, tmpReg); - - /* configure hysteresis register */ - tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.clearEmergency << DMA_THRESH_COMMQ_SHIFT) | - ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.clearEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) | - ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.clearEmergency); - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmhy, tmpReg); - - /* configure emergency threshold */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr, p_FmDriverParam->dmaSosEmergency); - - /* configure Watchdog */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr, USEC_TO_CLK(p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq)); - - /* Allocate MURAM for CAM */ - p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, - (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY), - DMA_CAM_ALIGN)); - if (!p_Fm->camBaseAddr ) - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed")); - - WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), 0, (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY)); - - /* VirtToPhys */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmebcr, - (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr)); - -#ifdef FM_PARTITION_ARRAY - { - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - /* liodn-partitions */ - for (i=0 ; iliodnBasePerPort[i] << DMA_LIODN_SHIFT) | - (uint32_t)p_FmDriverParam->liodnBasePerPort[i+1]); - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[i/2], tmpReg); - } - } -#endif /* FM_PARTITION_ARRAY */ - - /**********************/ - /* Init FPM Registers */ - /**********************/ - tmpReg = (uint32_t)(p_FmDriverParam->thresholds.dispLimit << FPM_DISP_LIMIT_SHIFT); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, tmpReg); - - tmpReg = (((uint32_t)p_FmDriverParam->thresholds.prsDispTh << FPM_THR1_PRS_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.kgDispTh << FPM_THR1_KG_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.plcrDispTh << FPM_THR1_PLCR_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.bmiDispTh << FPM_THR1_BMI_SHIFT)); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis1, tmpReg); - - tmpReg = (((uint32_t)p_FmDriverParam->thresholds.qmiEnqDispTh << FPM_THR2_QMI_ENQ_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.qmiDeqDispTh << FPM_THR2_QMI_DEQ_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.fmCtl1DispTh << FPM_THR2_FM_CTL1_SHIFT) | - ((uint32_t)p_FmDriverParam->thresholds.fmCtl2DispTh << FPM_THR2_FM_CTL2_SHIFT)); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis2, tmpReg); - - /* define exceptions and error behavior */ - tmpReg = 0; - /* Clear events */ - tmpReg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_SINGLE_ECC); - /* enable interrupts */ - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_STALL_ON_TASKS) - tmpReg |= FPM_EV_MASK_STALL_EN; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_SINGLE_ECC) - tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_DOUBLE_ECC) - tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN; - tmpReg |= (p_Fm->p_FmDriverParam->catastrophicErr << FPM_EV_MASK_CAT_ERR_SHIFT); - tmpReg |= (p_Fm->p_FmDriverParam->dmaErr << FPM_EV_MASK_DMA_ERR_SHIFT); - if(!p_Fm->p_FmDriverParam->haltOnExternalActivation) - tmpReg |= FPM_EV_MASK_EXTERNAL_HALT; - if(!p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError) - tmpReg |= FPM_EV_MASK_ECC_ERR_HALT; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg); - - /* clear all fmCtls event registers */ - for(i=0;ip_FmFpmRegs->fpmcev[i], 0xFFFFFFFF); - - /* RAM ECC - enable and clear events*/ - /* first we need to clear all parser memory, as it is uninitialized and - may cause ECC errors */ - tmpReg = 0; - /* event bits */ - tmpReg = (FPM_RAM_CTL_MURAM_ECC | FPM_RAM_CTL_IRAM_ECC); - /* Rams enable is not effected by the RCR bit, but by a COP configuration */ - if(p_Fm->p_FmDriverParam->externalEccRamsEnable) - tmpReg |= FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL; - - /* enable test mode */ - if(p_FmDriverParam->enMuramTestMode) - tmpReg |= FPM_RAM_CTL_MURAM_TEST_ECC; - if(p_FmDriverParam->enIramTestMode) - tmpReg |= FPM_RAM_CTL_IRAM_TEST_ECC; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg); - - tmpReg = 0; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_IRAM_ECC) - { - tmpReg |= FPM_IRAM_ECC_ERR_EX_EN; - FmEnableRamsEcc(p_Fm); - } - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_NURAM_ECC) - { - tmpReg |= FPM_MURAM_ECC_ERR_EX_EN; - FmEnableRamsEcc(p_Fm); - } - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg); - - /**********************/ - /* Init BMI Registers */ - /**********************/ - - /* define common resources */ - /* allocate MURAM for FIFO according to total size */ - p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, - p_Fm->p_FmStateStruct->totalFifoSize, - BMI_FIFO_ALIGN)); - if (!p_Fm->fifoBaseAddr) - { - FreeInitResources(p_Fm); - RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for FIFO failed")); - } - - tmpReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); - tmpReg = tmpReg / BMI_FIFO_ALIGN; - - tmpReg |= ((p_Fm->p_FmStateStruct->totalFifoSize/BMI_FIFO_UNITS - 1) << BMI_CFG1_FIFO_SIZE_SHIFT); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, tmpReg); - - tmpReg = ((uint32_t)(p_Fm->p_FmStateStruct->totalNumOfTasks - 1) << BMI_CFG2_TASKS_SHIFT ); - /* num of DMA's will be dynamically updated when each port is set */ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg); - - /* define unmaskable exceptions, enable and clear events */ - tmpReg = 0; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, (BMI_ERR_INTR_EN_LIST_RAM_ECC | - BMI_ERR_INTR_EN_PIPELINE_ECC | - BMI_ERR_INTR_EN_STATISTICS_RAM_ECC | - BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)); - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC) - tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC) - tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC) - tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC) - tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); - - /**********************/ - /* Init QMI Registers */ - /**********************/ - /* Clear error interrupt events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, (QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF)); - tmpReg = 0; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID) - tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC) - tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC; - /* enable events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); - - if(p_Fm->p_FmDriverParam->tnumAgingPeriod) - { - /* tnumAgingPeriod is in units of microseconds, p_FmClockFreq is in Mhz */ - periodInFmClocks = (uint16_t)(p_Fm->p_FmDriverParam->tnumAgingPeriod*p_Fm->p_FmStateStruct->fmClkFreq); - /* periodInFmClocks must be a 64 multiply */ - remainder = (uint8_t)(periodInFmClocks % 64); - if (remainder > 64) - tmpReg = (uint32_t)((periodInFmClocks/64) + 1); - else - { - tmpReg = (uint32_t)(periodInFmClocks/64); - if(!tmpReg) - tmpReg = 1; - } - tmpReg <<= QMI_TAPC_TAP; - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_tapc, tmpReg); - - } - tmpReg = 0; - /* Clear interrupt events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, QMI_INTR_EN_SINGLE_ECC); - if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC) - tmpReg |= QMI_INTR_EN_SINGLE_ECC; - /* enable events */ - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg); - - /* clear & enable global counters - calculate reg and save for later, - because it's the same reg for QMI enable */ - if(p_Fm->p_FmDriverParam->enCounters) - cfgReg = QMI_CFG_EN_COUNTERS; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT - cfgReg |= (uint32_t)(((QMI_DEF_TNUMS_THRESH) << 8) | (uint32_t)QMI_DEF_TNUMS_THRESH); -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - - if (p_Fm->p_FmStateStruct->irq != NO_IRQ) - { - XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm); - XX_EnableIntr(p_Fm->p_FmStateStruct->irq); - } - - if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) - { - XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, ErrorIsrCB, p_Fm); - XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq); - } - - /* build the FM master partition IPC address */ - if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); - - err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); - if(err) - RETURN_ERROR(MAJOR, err, NO_MSG); - - /**********************/ - /* Enable all modules */ - /**********************/ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, BMI_INIT_START); - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, cfgReg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN); - - if (p_Fm->p_FmDriverParam->firmware.p_Code) - { - XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code); - p_Fm->p_FmDriverParam->firmware.p_Code = NULL; - } - - XX_Free(p_Fm->p_FmDriverParam); - p_Fm->p_FmDriverParam = NULL; - - return E_OK; -} - -/**************************************************************************//** - @Function FM_Free - - @Description Frees all resources that were assigned to FM module. - - Calling this routine invalidates the descriptor. - - @Param[in] h_Fm - FM module descriptor - - @Return E_OK on success; Error code otherwise. -*//***************************************************************************/ -t_Error FM_Free(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - if (p_Fm->guestId != NCSW_MASTER_ID) - { - XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); - - if(!p_Fm->recoveryMode) - XX_Free(p_Fm->p_FmStateStruct); - - XX_Free(p_Fm); - - return E_OK; - } - - /* disable BMI and QMI */ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, 0); - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, 0); - - /* release BMI resources */ - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, 0); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, 0); - - /* disable ECC */ - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, 0); - - if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0)) - XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); - - if (p_Fm->p_FmStateStruct) - { - if (p_Fm->p_FmStateStruct->irq != NO_IRQ) - { - XX_DisableIntr(p_Fm->p_FmStateStruct->irq); - XX_FreeIntr(p_Fm->p_FmStateStruct->irq); - } - if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) - { - XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq); - XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq); - } - } - - if (p_Fm->h_Spinlock) - XX_FreeSpinlock(p_Fm->h_Spinlock); - - if (p_Fm->p_FmDriverParam) - { - if (p_Fm->p_FmDriverParam->firmware.p_Code) - XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code); - XX_Free(p_Fm->p_FmDriverParam); - p_Fm->p_FmDriverParam = NULL; - } - - FreeInitResources(p_Fm); - - if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct) - XX_Free(p_Fm->p_FmStateStruct); - - XX_Free(p_Fm); - - return E_OK; -} - -/*************************************************/ -/* API Advanced Init unit functions */ -/*************************************************/ - -t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable) -{ - - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->resetOnInit = enable; - - return E_OK; -} - - -t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmStateStruct->totalNumOfTasks = totalNumOfTasks; - - return E_OK; -} - -t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize; - - return E_OK; -} - -t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmStateStruct->maxNumOfOpenDmas = maxNumOfOpenDmas; - - return E_OK; -} - -t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - memcpy(&p_Fm->p_FmDriverParam->thresholds, p_FmThresholds, sizeof(t_FmThresholds)); - - return E_OK; -} - -t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaCacheOverride = cacheOverride; - - return E_OK; -} - -t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaAidOverride = aidOverride; - - return E_OK; -} - -t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaAidMode = aidMode; - - return E_OK; -} - -t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = axiDbgNumOfBeats; - - return E_OK; -} - -t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaCamNumOfEntries = numOfEntries; - - return E_OK; -} - -t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - -#ifdef FM_NO_WATCHDOG - { - t_FmRevisionInfo revInfo; - FM_GetRevision(h_Fm, &revInfo); - if (revInfo.majorRev != 4) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("watchdog!")); - } -#endif /* FM_NO_WATCHDOG */ - - p_Fm->p_FmDriverParam->dmaWatchdog = watchdogValue; - - return E_OK; -} - -t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) - -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - memcpy(&p_Fm->p_FmDriverParam->dmaWriteBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); - - return E_OK; -} - -t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - memcpy(&p_Fm->p_FmDriverParam->dmaCommQThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); - - return E_OK; -} - -t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - memcpy(&p_Fm->p_FmDriverParam->dmaReadBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds)); - - return E_OK; -} - -t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaEnEmergency = TRUE; - memcpy(&p_Fm->p_FmDriverParam->dmaEmergency, p_Emergency, sizeof(t_FmDmaEmergency)); - - return E_OK; -} - -t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - if(!p_Fm->p_FmDriverParam->dmaEnEmergency) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM_ConfigEnDmaEmergencySmoother may be called only after FM_ConfigEnDmaEmergency")); - - p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = TRUE; - p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = emergencyCnt; - - return E_OK; -} - -t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaDbgCntMode = fmDmaDbgCntMode; - - return E_OK; -} - -t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaStopOnBusError = stop; - - return E_OK; -} - -t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaSosEmergency = dmaSosEmergency; - - return E_OK; -} - -t_Error FM_ConfigEnableCounters(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->enCounters = TRUE; - - return E_OK; -} - -t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->dmaErr = dmaErr; - - return E_OK; -} - -t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->catastrophicErr = catastrophicErr; - - return E_OK; -} - -t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->enMuramTestMode = TRUE; - - return E_OK; -} - -t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->enIramTestMode = TRUE; - - return E_OK; -} - -t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - -#ifdef FM_HALT_SIG_ERRATA_GEN12 - { - t_FmRevisionInfo revInfo; - FM_GetRevision(h_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnExternalActivation!")); - } -#endif /* FM_HALT_SIG_ERRATA_GEN12 */ - - p_Fm->p_FmDriverParam->haltOnExternalActivation = enable; - - return E_OK; -} - -t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - -#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnEccError!")); -#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */ - - p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = enable; - - return E_OK; -} - -t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t bitMask = 0; - t_FmRevisionInfo revInfo; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - FM_GetRevision(p_Fm, &revInfo); -#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 - if((exception == e_FM_EX_BMI_PIPELINE_ECC) && (enable)) - { - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECC!")); - return E_OK; - } - } -#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */ -#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 - if((exception == e_FM_EX_BMI_LIST_RAM_ECC) && (enable)) - { - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC!")); - return E_OK; - } - } -#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */ -#ifdef FM_QMI_NO_ECC_EXCEPTIONS - if(((exception == e_FM_EX_QMI_SINGLE_ECC) || (exception == e_FM_EX_QMI_DOUBLE_ECC)) && - enable) - { - if (revInfo.majorRev == 4) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("QMI ECC exception!")); - return E_OK; - } - } -#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ -#ifdef FM_NO_DISPATCH_RAM_ECC - if((exception == e_FM_EX_BMI_DISPATCH_RAM_ECC) && (enable)) - { - if (revInfo.majorRev != 4) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC!")); - return E_OK; - } - } -#endif /* FM_NO_DISPATCH_RAM_ECC */ - - GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) - { - if (enable) - p_Fm->p_FmStateStruct->exceptions |= bitMask; - else - p_Fm->p_FmStateStruct->exceptions &= ~bitMask; - } - else - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - - return E_OK; -} - -t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - p_Fm->p_FmDriverParam->externalEccRamsEnable = enable; - - return E_OK; -} - -t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; -#ifdef FM_NO_TNUM_AGING - t_FmRevisionInfo revInfo; -#endif /* FM_NO_TNUM_AGING */ - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - -#ifdef FM_NO_TNUM_AGING - FM_GetRevision(h_Fm, &revInfo); - if (revInfo.majorRev != 4) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_ConfigTnumAgingPeriod!")); -#endif /* FM_NO_TNUM_AGING */ - - p_Fm->p_FmDriverParam->tnumAgingPeriod = tnumAgingPeriod; - - return E_OK; - -} - -/****************************************************/ -/* API Run-time Control uint functions */ -/****************************************************/ -t_Handle FM_GetPcdHandle(t_Handle h_Fm) -{ - SANITY_CHECK_RETURN_VALUE(h_Fm, E_INVALID_HANDLE, NULL); - SANITY_CHECK_RETURN_VALUE(!((t_Fm*)h_Fm)->p_FmDriverParam, E_INVALID_STATE, NULL); - - return ((t_Fm*)h_Fm)->h_Pcd; -} - -void FM_EventIsr(t_Handle h_Fm) -{ -#define FM_M_CALL_1G_MAC_TMR_ISR(_id) \ - { \ - if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].guestId) \ - SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id), pending); \ - else \ - p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\ - } - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t pending, event; - - SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE); - - /* normal interrupts */ - pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmnpi); - ASSERT_COND(pending); - if (pending & INTR_EN_BMI) - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("BMI Event - undefined!")); - if (pending & INTR_EN_QMI) - QmiEvent(p_Fm); - if (pending & INTR_EN_PRS) - p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle); - if (pending & INTR_EN_PLCR) - p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle); - if (pending & INTR_EN_KG) - p_Fm->intrMng[e_FM_EV_KG].f_Isr(p_Fm->intrMng[e_FM_EV_KG].h_SrcHandle); - if (pending & INTR_EN_TMR) - p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); - - /* MAC events may belong to different partitions */ - if (pending & INTR_EN_1G_MAC0_TMR) - FM_M_CALL_1G_MAC_TMR_ISR(0); - if (pending & INTR_EN_1G_MAC1_TMR) - FM_M_CALL_1G_MAC_TMR_ISR(1); - if (pending & INTR_EN_1G_MAC2_TMR) - FM_M_CALL_1G_MAC_TMR_ISR(2); - if (pending & INTR_EN_1G_MAC3_TMR) - FM_M_CALL_1G_MAC_TMR_ISR(3); - if (pending & INTR_EN_1G_MAC4_TMR) - FM_M_CALL_1G_MAC_TMR_ISR(4); - - /* IM port events may belong to different partitions */ - if (pending & INTR_EN_REV0) - { - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[0]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[0]); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[0], event); - if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId) - /*TODO IPC ISR For Fman Ctrl */ - ASSERT_COND(0); - /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */ - else - p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event); - - } - if (pending & INTR_EN_REV1) - { - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[1]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[1]); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[1], event); - if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId) - /*TODO IPC ISR For Fman Ctrl */ - ASSERT_COND(0); - /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */ - else - p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event); - - } - if (pending & INTR_EN_REV2) - { - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[2]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[2]); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[2], event); - if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId) - /*TODO IPC ISR For Fman Ctrl */ - ASSERT_COND(0); - /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */ - else - p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event); - } - if (pending & INTR_EN_REV3) - { - event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[3]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[3]); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[3], event); - if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId) - /*TODO IPC ISR For Fman Ctrl */ - ASSERT_COND(0); - /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */ - else - p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event); - } -} - -t_Error FM_ErrorIsr(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE); - - /* error interrupts */ - if (GET_UINT32(p_Fm->p_FmFpmRegs->fmepi) == 0) - return ERROR_CODE(E_EMPTY); - - ErrorIsrCB(p_Fm); - return E_OK; -} - -t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - int i; - uint8_t sum; - uint8_t hardwarePortId; - uint32_t tmpRegs[8] = {0,0,0,0,0,0,0,0}; - uint8_t relativePortId, shift, weight, maxPercent = 0; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - /* check that all ports add up to 100% */ - sum = 0; - for (i=0;inumOfPorts;i++) - sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth; - if (sum != 100) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%")); - - /* find highest precent */ - for (i=0;inumOfPorts;i++) - { - if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent) - maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth; - } - - /* calculate weight for each port */ - for (i=0;inumOfPorts;i++) - { - weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT )/maxPercent); - /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exect division - is not reached, we round up so that: - 0 until maxPercent/PORT_MAX_WEIGHT get "1" - maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2" - ... - maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */ - if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent)) - weight++; - - /* find the location of this port within the register */ - SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId, - p_PortsBandwidth->portsBandwidths[i].type, - p_PortsBandwidth->portsBandwidths[i].relativePortId); - relativePortId = (uint8_t)(hardwarePortId % 8); - shift = (uint8_t)(32-4*(relativePortId+1)); - - - if(weight > 1) - /* Add this port to tmpReg */ - /* (each 8 ports result in one register)*/ - tmpRegs[hardwarePortId/8] |= ((weight-1) << shift); - } - - for(i=0;i<8;i++) - if(tmpRegs[i]) - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_arb[i], tmpRegs[i]); - - return E_OK; -} - -t_Error FM_EnableRamsEcc(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - t_FmIpcMsg msg; - t_Error err; - - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_ENABLE_RAM_ECC; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; - } - - if(!p_Fm->p_FmStateStruct->internalCall) - p_Fm->p_FmStateStruct->explicitEnable = TRUE; - p_Fm->p_FmStateStruct->internalCall = FALSE; - - if(p_Fm->p_FmStateStruct->ramsEccEnable) - return E_OK; - else - { - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr); - if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL) - { - DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG")); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | FPM_RAM_CTL_IRAM_ECC_EN); - } - else - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | (FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN)); - p_Fm->p_FmStateStruct->ramsEccEnable = TRUE; - } - - return E_OK; -} - -t_Error FM_DisableRamsEcc(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - bool explicitDisable = FALSE; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - t_Error err; - t_FmIpcMsg msg; - - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_DISABLE_RAM_ECC; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; - } - - if(!p_Fm->p_FmStateStruct->internalCall) - explicitDisable = TRUE; - p_Fm->p_FmStateStruct->internalCall = FALSE; - - /* if rams are already disabled, or if rams were explicitly enabled and are - currently called indirectly (not explicitly), ignore this call. */ - if(!p_Fm->p_FmStateStruct->ramsEccEnable || (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable)) - return E_OK; - else - { - if(p_Fm->p_FmStateStruct->explicitEnable) - /* This is the case were both explicit are TRUE. - Turn off this flag for cases were following ramsEnable - routines are called */ - p_Fm->p_FmStateStruct->explicitEnable = FALSE; - - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr); - if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL) - { - DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG")); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~FPM_RAM_CTL_IRAM_ECC_EN); - } - else - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~(FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN)); - p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; - } - - return E_OK; -} - -t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t bitMask = 0; - uint32_t tmpReg; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - GET_EXCEPTION_FLAG(bitMask, exception); - if(bitMask) - { - if (enable) - p_Fm->p_FmStateStruct->exceptions |= bitMask; - else - p_Fm->p_FmStateStruct->exceptions &= ~bitMask; - - switch(exception) - { - case(e_FM_EX_DMA_BUS_ERROR): - tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); - if(enable) - tmpReg |= DMA_MODE_BER; - else - tmpReg &= ~DMA_MODE_BER; - /* disable bus error */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); - break; - case(e_FM_EX_DMA_READ_ECC): - case(e_FM_EX_DMA_SYSTEM_WRITE_ECC): - case(e_FM_EX_DMA_FM_WRITE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr); - if(enable) - tmpReg |= DMA_MODE_ECC; - else - tmpReg &= ~DMA_MODE_ECC; - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg); - break; - case(e_FM_EX_FPM_STALL_ON_TASKS): - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem); - if(enable) - tmpReg |= FPM_EV_MASK_STALL_EN; - else - tmpReg &= ~FPM_EV_MASK_STALL_EN; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg); - break; - case(e_FM_EX_FPM_SINGLE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem); - if(enable) - tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN; - else - tmpReg &= ~FPM_EV_MASK_SINGLE_ECC_EN; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg); - break; - case( e_FM_EX_FPM_DOUBLE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem); - if(enable) - tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN; - else - tmpReg &= ~FPM_EV_MASK_DOUBLE_ECC_EN; - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg); - break; - case( e_FM_EX_QMI_SINGLE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien); - if(enable) - { -#ifdef FM_QMI_NO_ECC_EXCEPTIONS - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if (revInfo.majorRev == 4) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC")); - return E_OK; - } -#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ - tmpReg |= QMI_INTR_EN_SINGLE_ECC; - } - else - tmpReg &= ~QMI_INTR_EN_SINGLE_ECC; - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg); - break; - case(e_FM_EX_QMI_DOUBLE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); - if(enable) - { -#ifdef FM_QMI_NO_ECC_EXCEPTIONS - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if (revInfo.majorRev == 4) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_DOUBLE_ECC")); - return E_OK; - } -#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ - tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC; - } - else - tmpReg &= ~QMI_ERR_INTR_EN_DOUBLE_ECC; - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); - break; - case(e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID): - tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien); - if(enable) - tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; - else - tmpReg &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF; - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg); - break; - case(e_FM_EX_BMI_LIST_RAM_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); - if(enable) - { -#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC")); - return E_OK; - } -#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */ - tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; - } - else - tmpReg &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); - break; - case(e_FM_EX_BMI_PIPELINE_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); - if(enable) - { -#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECCBMI_LIST_RAM_ECC")); - return E_OK; - } -#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */ - tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC; - } - else - tmpReg &= ~BMI_ERR_INTR_EN_PIPELINE_ECC; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); - break; - case(e_FM_EX_BMI_STATISTICS_RAM_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); - if(enable) - tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; - else - tmpReg &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); - break; - case(e_FM_EX_BMI_DISPATCH_RAM_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier); - if(enable) - { -#ifdef FM_NO_DISPATCH_RAM_ECC - t_FmRevisionInfo revInfo; - FM_GetRevision(p_Fm, &revInfo); - if (revInfo.majorRev != 4) - { - REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC")); - return E_OK; - } -#endif /* FM_NO_DISPATCH_RAM_ECC */ - tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; - } - else - tmpReg &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg); - break; - case(e_FM_EX_IRAM_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie); - if(enable) - { - /* enable ECC if not enabled */ - FmEnableRamsEcc(p_Fm); - /* enable ECC interrupts */ - tmpReg |= FPM_IRAM_ECC_ERR_EX_EN; - } - else - { - /* ECC mechanism may be disabled, depending on driver status */ - FmDisableRamsEcc(p_Fm); - tmpReg &= ~FPM_IRAM_ECC_ERR_EX_EN; - } - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg); - break; - - case(e_FM_EX_MURAM_ECC): - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie); - if(enable) - { - /* enable ECC if not enabled */ - FmEnableRamsEcc(p_Fm); - /* enable ECC interrupts */ - tmpReg |= FPM_MURAM_ECC_ERR_EX_EN; - } - else - { - /* ECC mechanism may be disabled, depending on driver status */ - FmDisableRamsEcc(p_Fm); - tmpReg &= ~FPM_MURAM_ECC_ERR_EX_EN; - } - - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg); - break; - default: - RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); - } - } - else - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); - - return E_OK; -} - -t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - t_FmIpcRevisionInfo ipcRevInfo; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - - if (p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_REV; - replyLength = sizeof(uint32_t) + sizeof(t_FmRevisionInfo); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - if (replyLength != (sizeof(uint32_t) + sizeof(t_FmRevisionInfo))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmRevisionInfo)); - p_FmRevisionInfo->majorRev = ipcRevInfo.majorRev; - p_FmRevisionInfo->minorRev = ipcRevInfo.minorRev; - return (t_Error)(reply.error); - } - - /* read revision register 1 */ - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1); - p_FmRevisionInfo->majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); - p_FmRevisionInfo->minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); - - return E_OK; -} - -uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - t_Error err; - uint32_t counterValue; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength, outCounter; - - SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); - SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0); - - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_GET_COUNTER; - memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t)); - replyLength = sizeof(uint32_t) + sizeof(uint32_t); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId) +sizeof(counterValue), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MAJOR, err, NO_MSG); - if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) - RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t)); - - return outCounter; - } - - switch(counter) - { - case(e_FM_COUNTERS_ENQ_TOTAL_FRAME): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc); - case(e_FM_COUNTERS_DEQ_TOTAL_FRAME): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc); - case(e_FM_COUNTERS_DEQ_0): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0); - case(e_FM_COUNTERS_DEQ_1): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1); - case(e_FM_COUNTERS_DEQ_2): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2); - case(e_FM_COUNTERS_DEQ_3): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3); - case(e_FM_COUNTERS_DEQ_FROM_DEFAULT): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc); - case(e_FM_COUNTERS_DEQ_FROM_CONTEXT): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc); - case(e_FM_COUNTERS_DEQ_FROM_FD): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc); - case(e_FM_COUNTERS_DEQ_CONFIRM): - return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc); - case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT): - return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc); - case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT): - return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc); - case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT): - return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc); - default: - break; - } - /* should never get here */ - ASSERT_COND(FALSE); - - return 0; -} - -t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - /* When applicable (when there is an 'enable counters' bit, - check that counters are enabled */ - switch(counter) - { - case(e_FM_COUNTERS_ENQ_TOTAL_FRAME): - case(e_FM_COUNTERS_DEQ_TOTAL_FRAME): - case(e_FM_COUNTERS_DEQ_0): - case(e_FM_COUNTERS_DEQ_1): - case(e_FM_COUNTERS_DEQ_2): - case(e_FM_COUNTERS_DEQ_3): - case(e_FM_COUNTERS_DEQ_FROM_DEFAULT): - case(e_FM_COUNTERS_DEQ_FROM_CONTEXT): - case(e_FM_COUNTERS_DEQ_FROM_FD): - case(e_FM_COUNTERS_DEQ_CONFIRM): - if(!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS)) - RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); - break; - default: - break; - } - - /* Set counter */ - switch(counter) - { - case(e_FM_COUNTERS_ENQ_TOTAL_FRAME): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc, val); - break; - case(e_FM_COUNTERS_DEQ_TOTAL_FRAME): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc, val); - break; - case(e_FM_COUNTERS_DEQ_0): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0, val); - break; - case(e_FM_COUNTERS_DEQ_1): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1, val); - break; - case(e_FM_COUNTERS_DEQ_2): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2, val); - break; - case(e_FM_COUNTERS_DEQ_3): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3, val); - break; - case(e_FM_COUNTERS_DEQ_FROM_DEFAULT): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc, val); - break; - case(e_FM_COUNTERS_DEQ_FROM_CONTEXT): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc, val); - break; - case(e_FM_COUNTERS_DEQ_FROM_FD): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc, val); - break; - case(e_FM_COUNTERS_DEQ_CONFIRM): - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc, val); - break; - case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT): - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc, val); - break; - case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT): - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc, val); - break; - case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT): - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc, val); - break; - default: - break; - } - - return E_OK; -} - -void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t bitMask; - - SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - bitMask = (uint32_t)((muramPort==e_FM_DMA_MURAM_PORT_WRITE) ? DMA_MODE_EMERGENCY_WRITE : DMA_MODE_EMERGENCY_READ); - - if(enable) - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | bitMask); - else /* disable */ - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) & ~bitMask); - - return; -} - -void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | ((uint32_t)pri << DMA_MODE_BUS_PRI_SHIFT) ); - - return; -} - -void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - t_Error err; - t_FmIpcMsg msg; - t_FmIpcReply reply; - uint32_t replyLength; - t_FmIpcDmaStatus ipcDmaStatus; - - SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - memset(&reply, 0, sizeof(reply)); - msg.msgId = FM_DMA_STAT; - replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - (uint8_t*)&reply, - &replyLength, - NULL, - NULL)) != E_OK) - { - REPORT_ERROR(MINOR, err, NO_MSG); - return; - } - if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus))) - { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); - return; - } - memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus)); - - p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */ - p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */ - p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */ - p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */ - p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */ - return; - } - - tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr); - - p_FmDmaStatus->cmqNotEmpty = (bool)(tmpReg & DMA_STATUS_CMD_QUEUE_NOT_EMPTY); - p_FmDmaStatus->busError = (bool)(tmpReg & DMA_STATUS_BUS_ERR); - p_FmDmaStatus->readBufEccError = (bool)(tmpReg & DMA_STATUS_READ_ECC); - p_FmDmaStatus->writeBufEccSysError = (bool)(tmpReg & DMA_STATUS_SYSTEM_WRITE_ECC); - p_FmDmaStatus->writeBufEccFmError = (bool)(tmpReg & DMA_STATUS_FM_WRITE_ECC); - return; -} - -t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - switch(exception) - { - case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DEQ_FROM_DEF); - break; - case e_FM_EX_QMI_SINGLE_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, QMI_INTR_EN_SINGLE_ECC); - break; - case e_FM_EX_QMI_DOUBLE_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DOUBLE_ECC); - break; - case e_FM_EX_BMI_LIST_RAM_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_LIST_RAM_ECC); - break; - case e_FM_EX_BMI_PIPELINE_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_PIPELINE_ECC); - break; - case e_FM_EX_BMI_STATISTICS_RAM_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STATISTICS_RAM_ECC); - break; - case e_FM_EX_BMI_DISPATCH_RAM_ECC: - if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)) - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); - WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_DISPATCH_RAM_ECC); - break; - default: - RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); - } - - return E_OK; -} - -void FM_Resume(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm*)h_Fm; - uint32_t tmpReg; - - SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - if (p_Fm->guestId == NCSW_MASTER_ID) - { - tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem); - /* clear tmpReg event bits in order not to clear standing events */ - tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC); - WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg | FPM_EV_MASK_RELEASE_FM); - } - else - ASSERT_COND(0); /* TODO */ -} - -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -t_Error FM_DumpRegs(t_Handle h_Fm) -{ - t_Fm *p_Fm = (t_Fm *)h_Fm; - uint8_t i = 0; - t_Error err; - t_FmIpcMsg msg; - - DECLARE_DUMP; - - SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); - SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); - - - if(p_Fm->guestId != NCSW_MASTER_ID) - { - memset(&msg, 0, sizeof(msg)); - msg.msgId = FM_DUMP_REGS; - if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], - (uint8_t*)&msg, - sizeof(msg.msgId), - NULL, - NULL, - NULL, - NULL)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); - return E_OK; - } - - - DUMP_SUBTITLE(("\n")); - - DUMP_TITLE(p_Fm->p_FmFpmRegs, ("FmFpmRegs Regs")); - - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtnc); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmpr); - DUMP_VAR(p_Fm->p_FmFpmRegs,brkc); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmflc); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis1); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis2); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmepi); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmrie); - - DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcev, ("fmfpfcev")); - DUMP_SUBSTRUCT_ARRAY(i, 4) - { - DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcev[i], sizeof(uint32_t)); - } - - DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcee, ("fmfpfcee")); - DUMP_SUBSTRUCT_ARRAY(i, 4) - { - DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcee[i], sizeof(uint32_t)); - } - - DUMP_SUBTITLE(("\n")); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc1); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc2); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsp); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsf); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmrcr); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmextc); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext1); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext2); - - DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmdrd, ("fpmdrd")); - DUMP_SUBSTRUCT_ARRAY(i, 16) - { - DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmdrd[i], sizeof(uint32_t)); - } - - DUMP_SUBTITLE(("\n")); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdra); - DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_1); - DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_2); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmrstc); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmcld); - DUMP_VAR(p_Fm->p_FmFpmRegs,fmnpi); - DUMP_VAR(p_Fm->p_FmFpmRegs,fpmem); - - DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmcev, ("fpmcev")); - DUMP_SUBSTRUCT_ARRAY(i, 4) - { - DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmcev[i], sizeof(uint32_t)); - } - - DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps, ("fmfp_ps")); - DUMP_SUBSTRUCT_ARRAY(i, 64) - { - DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[i], sizeof(uint32_t)); - } - - - DUMP_TITLE(p_Fm->p_FmDmaRegs, ("p_FmDmaRegs Regs")); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmmr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmhy); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsetr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtah); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtal); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtcid); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmra); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmrd); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmwcr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmebcr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqdr); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr1); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr2); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr3); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr4); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr5); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsefrc); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsqfrc); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmssrc); - DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmdcr); - - DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr, ("fmdmplr")); - - DUMP_SUBSTRUCT_ARRAY(i, FM_SIZE_OF_LIODN_TABLE/2) - { - DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[i], sizeof(uint32_t)); - } - - DUMP_TITLE(p_Fm->p_FmBmiRegs, ("p_FmBmiRegs COMMON Regs")); - DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_init); - DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg1); - DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg2); - DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ievr); - DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ier); - - DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_arb, ("fmbm_arb")); - DUMP_SUBSTRUCT_ARRAY(i, 8) - { - DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_arb[i], sizeof(uint32_t)); - } - - - DUMP_TITLE(p_Fm->p_FmQmiRegs, ("p_FmQmiRegs COMMON Regs")); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gc); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eie); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eien); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eif); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ie); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ien); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_if); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gs); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ts); - DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_etfc); - - return E_OK; -} -#endif /* (defined(DEBUG_ERRORS) && ... */ - diff --git a/sys/contrib/ncsw/Peripherals/FM/fm.h b/sys/contrib/ncsw/Peripherals/FM/fm.h index cd61d9661701..d0f96d66851d 100644 --- a/sys/contrib/ncsw/Peripherals/FM/fm.h +++ b/sys/contrib/ncsw/Peripherals/FM/fm.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm.h @@ -43,6 +44,7 @@ #include "fm_ext.h" #include "fm_ipc.h" +#include "fsl_fman.h" #define __ERR_MODULE__ MODULE_FM @@ -63,80 +65,221 @@ #define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */ #define FM_EX_QMI_DOUBLE_ECC 0x00400000 #define FM_EX_BMI_LIST_RAM_ECC 0x00200000 -#define FM_EX_BMI_PIPELINE_ECC 0x00100000 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000 #define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000 #define FM_EX_IRAM_ECC 0x00040000 -#define FM_EX_NURAM_ECC 0x00020000 +#define FM_EX_MURAM_ECC 0x00020000 #define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000 -#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \ - case e_FM_EX_DMA_BUS_ERROR: \ - bitMask = FM_EX_DMA_BUS_ERROR; break; \ - case e_FM_EX_DMA_READ_ECC: \ - bitMask = FM_EX_DMA_READ_ECC; break; \ - case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \ - bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \ - case e_FM_EX_DMA_FM_WRITE_ECC: \ - bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \ - case e_FM_EX_FPM_STALL_ON_TASKS: \ - bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \ - case e_FM_EX_FPM_SINGLE_ECC: \ - bitMask = FM_EX_FPM_SINGLE_ECC; break; \ - case e_FM_EX_FPM_DOUBLE_ECC: \ - bitMask = FM_EX_FPM_DOUBLE_ECC; break; \ - case e_FM_EX_QMI_SINGLE_ECC: \ - bitMask = FM_EX_QMI_SINGLE_ECC; break; \ - case e_FM_EX_QMI_DOUBLE_ECC: \ - bitMask = FM_EX_QMI_DOUBLE_ECC; break; \ - case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \ - bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \ - case e_FM_EX_BMI_LIST_RAM_ECC: \ - bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \ - case e_FM_EX_BMI_PIPELINE_ECC: \ - bitMask = FM_EX_BMI_PIPELINE_ECC; break; \ - case e_FM_EX_BMI_STATISTICS_RAM_ECC: \ - bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \ - case e_FM_EX_BMI_DISPATCH_RAM_ECC: \ - bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \ - case e_FM_EX_IRAM_ECC: \ - bitMask = FM_EX_IRAM_ECC; break; \ - case e_FM_EX_MURAM_ECC: \ - bitMask = FM_EX_NURAM_ECC; break; \ - default: bitMask = 0;break;} +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF + +#define DMA_THRESH_COMMQ_MASK 0xFF000000 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F + +#define GET_EXCEPTION_FLAG(bitMask, exception) \ +switch (exception){ \ + case e_FM_EX_DMA_BUS_ERROR: \ + bitMask = FM_EX_DMA_BUS_ERROR; break; \ + case e_FM_EX_DMA_SINGLE_PORT_ECC: \ + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \ + case e_FM_EX_DMA_READ_ECC: \ + bitMask = FM_EX_DMA_READ_ECC; break; \ + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \ + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \ + case e_FM_EX_DMA_FM_WRITE_ECC: \ + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \ + case e_FM_EX_FPM_STALL_ON_TASKS: \ + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \ + case e_FM_EX_FPM_SINGLE_ECC: \ + bitMask = FM_EX_FPM_SINGLE_ECC; break; \ + case e_FM_EX_FPM_DOUBLE_ECC: \ + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \ + case e_FM_EX_QMI_SINGLE_ECC: \ + bitMask = FM_EX_QMI_SINGLE_ECC; break; \ + case e_FM_EX_QMI_DOUBLE_ECC: \ + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \ + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \ + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \ + case e_FM_EX_BMI_LIST_RAM_ECC: \ + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \ + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \ + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \ + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \ + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \ + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \ + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \ + case e_FM_EX_IRAM_ECC: \ + bitMask = FM_EX_IRAM_ECC; break; \ + case e_FM_EX_MURAM_ECC: \ + bitMask = FM_EX_MURAM_ECC; break; \ + default: bitMask = 0;break; \ +} + +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \ + switch (_mod) { \ + case e_FM_MOD_PRS: \ + if (_id) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \ + break; \ + case e_FM_MOD_KG: \ + if (_id) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \ + break; \ + case e_FM_MOD_PLCR: \ + if (_id) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \ + break; \ + case e_FM_MOD_TMR: \ + if (_id) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \ + break; \ + case e_FM_MOD_10G_MAC: \ + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \ + break; \ + case e_FM_MOD_1G_MAC: \ + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \ + break; \ + case e_FM_MOD_MACSEC: \ + switch (_id){ \ + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \ + break; \ + } \ + break; \ + case e_FM_MOD_FMAN_CTRL: \ + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \ + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \ + break; \ + default: _event = e_FM_EV_DUMMY_LAST; \ + break; \ + } + +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \ + switch (_cache_override){ \ + case e_FM_DMA_NO_CACHE_OR: \ + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \ + case e_FM_DMA_NO_STASH_DATA: \ + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \ + case e_FM_DMA_MAY_STASH_DATA: \ + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \ + case e_FM_DMA_STASH_DATA: \ + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \ + default: \ + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \ + } + +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \ + switch (_aid_mode){ \ + case e_FM_DMA_AID_OUT_PORT_ID: \ + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \ + case e_FM_DMA_AID_OUT_TNUM: \ + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \ + default: \ + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \ + } + +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \ + switch (_dma_dbg_cnt){ \ + case e_FM_DMA_DBG_NO_CNT: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \ + case e_FM_DMA_DBG_CNT_DONE: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \ + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \ + case e_FM_DMA_DBG_CNT_INT_READ_EM: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \ + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \ + case e_FM_DMA_DBG_CNT_FPM_WAIT: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \ + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \ + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \ + default: \ + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \ + } + +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \ + switch (_dma_emer){ \ + case e_FM_DMA_EM_EBS: \ + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \ + case e_FM_DMA_EM_SOS: \ + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \ + default: \ + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \ + } + +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \ + switch (_dma_err){ \ + case e_FM_DMA_ERR_CATASTROPHIC: \ + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \ + case e_FM_DMA_ERR_REPORT: \ + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \ + default: \ + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \ + } + +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \ + switch (_catastrophic_err){ \ + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \ + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \ + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \ + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \ + default: \ + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \ + } + +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \ + switch (_counters){ \ + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \ + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \ + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \ + case e_FM_COUNTERS_DEQ_0: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \ + case e_FM_COUNTERS_DEQ_1: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \ + case e_FM_COUNTERS_DEQ_2: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \ + case e_FM_COUNTERS_DEQ_3: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \ + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \ + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \ + case e_FM_COUNTERS_DEQ_FROM_FD: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \ + case e_FM_COUNTERS_DEQ_CONFIRM: \ + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \ + default: \ + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \ + } /**************************************************************************//** @Description defaults *//***************************************************************************/ -#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\ +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\ FM_EX_DMA_READ_ECC |\ FM_EX_DMA_SYSTEM_WRITE_ECC |\ FM_EX_DMA_FM_WRITE_ECC |\ FM_EX_FPM_STALL_ON_TASKS |\ FM_EX_FPM_SINGLE_ECC |\ FM_EX_FPM_DOUBLE_ECC |\ - FM_EX_QMI_SINGLE_ECC |\ FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\ - FM_EX_QMI_DOUBLE_ECC |\ FM_EX_BMI_LIST_RAM_ECC |\ - FM_EX_BMI_PIPELINE_ECC |\ + FM_EX_BMI_STORAGE_PROFILE_ECC |\ FM_EX_BMI_STATISTICS_RAM_ECC |\ - FM_EX_BMI_DISPATCH_RAM_ECC |\ FM_EX_IRAM_ECC |\ - FM_EX_NURAM_ECC ) -#define DEFAULT_totalNumOfTasks (BMI_MAX_NUM_OF_TASKS*3/4) -#define DEFAULT_totalFifoSize (BMI_MAX_FIFO_SIZE*3/4) -#define DEFAULT_maxNumOfOpenDmas (BMI_MAX_NUM_OF_DMAS*3/4) + FM_EX_MURAM_ECC |\ + FM_EX_BMI_DISPATCH_RAM_ECC |\ + FM_EX_QMI_DOUBLE_ECC |\ + FM_EX_QMI_SINGLE_ECC) + #define DEFAULT_eccEnable FALSE -#define DEFAULT_dispLimit 0 -#define DEFAULT_prsDispTh 16 -#define DEFAULT_plcrDispTh 16 -#define DEFAULT_kgDispTh 16 -#define DEFAULT_bmiDispTh 16 -#define DEFAULT_qmiEnqDispTh 16 -#define DEFAULT_qmiDeqDispTh 16 -#define DEFAULT_fmCtl1DispTh 16 -#define DEFAULT_fmCtl2DispTh 16 -#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR #ifdef FM_PEDANTIC_DMA #define DEFAULT_aidOverride TRUE #else @@ -146,42 +289,129 @@ #define DEFAULT_dmaStopOnBusError FALSE #define DEFAULT_stopAtBusError FALSE #define DEFAULT_axiDbgNumOfBeats 1 -#define DEFAULT_dmaCamNumOfEntries 32 -#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2) -#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4) #define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2) #define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4) #define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2) #define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4) -#define DEFAULT_dmaSosEmergency 0 -#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT #define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT #define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC #define DEFAULT_resetOnInit FALSE +#define DEFAULT_resetOnInitOverrideCallback NULL #define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */ #define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */ #define DEFAULT_externalEccRamsEnable FALSE #define DEFAULT_VerifyUcode FALSE -#define DEFAULT_tnumAgingPeriod 0 + +#if (DPAA_VERSION < 11) +#define DEFAULT_totalFifoSize(major, minor) \ + (((major == 2) || (major == 5)) ? \ + (100*KILOBYTE) : ((major == 4) ? \ + (49*KILOBYTE) : (122*KILOBYTE))) +#define DEFAULT_totalNumOfTasks(major, minor) \ + BMI_MAX_NUM_OF_TASKS + +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2) +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4) +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR +#define DEFAULT_dmaCamNumOfEntries 32 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT +#define DEFAULT_dmaEnEmergency FALSE +#define DEFAULT_dmaSosEmergency 0 #define DEFAULT_dmaWatchdog 0 /* disabled */ -#define DEFAULT_mtu 9600 +#define DEFAULT_dmaEnEmergencySmoother FALSE +#define DEFAULT_dmaEmergencySwitchCounter 0 + +#define DEFAULT_dispLimit 0 +#define DEFAULT_prsDispTh 16 +#define DEFAULT_plcrDispTh 16 +#define DEFAULT_kgDispTh 16 +#define DEFAULT_bmiDispTh 16 +#define DEFAULT_qmiEnqDispTh 16 +#define DEFAULT_qmiDeqDispTh 16 +#define DEFAULT_fmCtl1DispTh 16 +#define DEFAULT_fmCtl2DispTh 16 + +#else /* (DPAA_VERSION < 11) */ +/* Defaults are registers' reset values */ +#define DEFAULT_totalFifoSize(major, minor) \ + (((major == 6) && ((minor == 1) || (minor == 4))) ? \ + (156*KILOBYTE) : (295*KILOBYTE)) + +/* According to the default value of FMBM_CFG2[TNTSKS] */ +#define DEFAULT_totalNumOfTasks(major, minor) \ + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124) + +#define DEFAULT_dmaCommQLow 0x2A +#define DEFAULT_dmaCommQHigh 0x3F +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR +#define DEFAULT_dmaCamNumOfEntries 64 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT +#define DEFAULT_dmaEnEmergency FALSE +#define DEFAULT_dmaSosEmergency 0 +#define DEFAULT_dmaWatchdog 0 /* disabled */ +#define DEFAULT_dmaEnEmergencySmoother FALSE +#define DEFAULT_dmaEmergencySwitchCounter 0 + +#define DEFAULT_dispLimit 0 +#define DEFAULT_prsDispTh 16 +#define DEFAULT_plcrDispTh 16 +#define DEFAULT_kgDispTh 16 +#define DEFAULT_bmiDispTh 16 +#define DEFAULT_qmiEnqDispTh 16 +#define DEFAULT_qmiDeqDispTh 16 +#define DEFAULT_fmCtl1DispTh 16 +#define DEFAULT_fmCtl2DispTh 16 +#endif /* (DPAA_VERSION < 11) */ + +#define FM_TIMESTAMP_1_USEC_BIT 8 /**************************************************************************//** - @Description Modules registers offsets + @Collection Defines used for enabling/disabling FM interrupts + @{ *//***************************************************************************/ -#define FM_MM_MURAM 0x00000000 -#define FM_MM_BMI 0x00080000 -#define FM_MM_QMI 0x00080400 -#define FM_MM_PRS 0x000c7000 -#define FM_MM_KG 0x000C1000 -#define FM_MM_DMA 0x000C2000 -#define FM_MM_FPM 0x000C3000 -#define FM_MM_PLCR 0x000C0000 -#define FM_MM_IMEM 0x000C4000 +#define ERR_INTR_EN_DMA 0x00010000 +#define ERR_INTR_EN_FPM 0x80000000 +#define ERR_INTR_EN_BMI 0x00800000 +#define ERR_INTR_EN_QMI 0x00400000 +#define ERR_INTR_EN_PRS 0x00200000 +#define ERR_INTR_EN_KG 0x00100000 +#define ERR_INTR_EN_PLCR 0x00080000 +#define ERR_INTR_EN_MURAM 0x00040000 +#define ERR_INTR_EN_IRAM 0x00020000 +#define ERR_INTR_EN_10G_MAC0 0x00008000 +#define ERR_INTR_EN_10G_MAC1 0x00000040 +#define ERR_INTR_EN_1G_MAC0 0x00004000 +#define ERR_INTR_EN_1G_MAC1 0x00002000 +#define ERR_INTR_EN_1G_MAC2 0x00001000 +#define ERR_INTR_EN_1G_MAC3 0x00000800 +#define ERR_INTR_EN_1G_MAC4 0x00000400 +#define ERR_INTR_EN_1G_MAC5 0x00000200 +#define ERR_INTR_EN_1G_MAC6 0x00000100 +#define ERR_INTR_EN_1G_MAC7 0x00000080 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001 -/**************************************************************************//** - @Description Interrupt Enable/Mask -*//***************************************************************************/ +#define INTR_EN_QMI 0x40000000 +#define INTR_EN_PRS 0x20000000 +#define INTR_EN_WAKEUP 0x10000000 +#define INTR_EN_PLCR 0x08000000 +#define INTR_EN_1G_MAC0 0x00080000 +#define INTR_EN_1G_MAC1 0x00040000 +#define INTR_EN_1G_MAC2 0x00020000 +#define INTR_EN_1G_MAC3 0x00010000 +#define INTR_EN_1G_MAC4 0x00000040 +#define INTR_EN_1G_MAC5 0x00000020 +#define INTR_EN_1G_MAC6 0x00000008 +#define INTR_EN_1G_MAC7 0x00000002 +#define INTR_EN_10G_MAC0 0x00200000 +#define INTR_EN_10G_MAC1 0x00100000 +#define INTR_EN_REV0 0x00008000 +#define INTR_EN_REV1 0x00004000 +#define INTR_EN_REV2 0x00002000 +#define INTR_EN_REV3 0x00001000 +#define INTR_EN_BRK 0x00000080 +#define INTR_EN_TMR 0x01000000 +#define INTR_EN_MACSEC_MAC0 0x00000001 +/* @} */ /**************************************************************************//** @Description Memory Mapped Registers @@ -190,375 +420,80 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START -typedef _Packed struct +typedef struct { - volatile uint32_t fpmtnc; /**< FPM TNUM Control */ - volatile uint32_t fpmpr; /**< FPM Port_ID FmCtl Association */ - volatile uint32_t brkc; /**< FPM Breakpoint Control */ - volatile uint32_t fpmflc; /**< FPM Flush Control */ - volatile uint32_t fpmdis1; /**< FPM Dispatch Thresholds1 */ - volatile uint32_t fpmdis2; /**< FPM Dispatch Thresholds2 */ - volatile uint32_t fmepi; /**< FM Error Pending Interrupts */ - volatile uint32_t fmrie; /**< FM Error Interrupt Enable */ - volatile uint32_t fmfpfcev[4]; /**< FPM FMan-Controller Event 1-4 */ - volatile uint8_t res1[16]; /**< reserved */ - volatile uint32_t fmfpfcee[4]; /**< PM FMan-Controller Event 1-4 */ - volatile uint8_t res2[16]; /**< reserved */ - volatile uint32_t fpmtsc1; /**< FPM TimeStamp Control1 */ - volatile uint32_t fpmtsc2; /**< FPM TimeStamp Control2 */ - volatile uint32_t fpmtsp; /**< FPM Time Stamp */ - volatile uint32_t fpmtsf; /**< FPM Time Stamp Fraction */ - volatile uint32_t fmrcr; /**< FM Rams Control */ - volatile uint32_t fpmextc; /**< FPM External Requests Control */ - volatile uint32_t fpmext1; /**< FPM External Requests Config1 */ - volatile uint32_t fpmext2; /**< FPM External Requests Config2 */ - volatile uint32_t fpmdrd[16]; /**< FPM Data_Ram Data 0-15 */ - volatile uint32_t fpmdra; /**< FPM Data Ram Access */ - volatile uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 */ - volatile uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 */ - volatile uint32_t fmrstc; /**< FM Reset Command */ - volatile uint32_t fmcld; /**< FM Classifier Debug */ - volatile uint32_t fmnpi; /**< FM Normal Pending Interrupts */ - volatile uint32_t fmfp_exte; /**< FPM External Requests Enable */ - volatile uint32_t fpmem; /**< FPM Event & Mask */ - volatile uint32_t fpmcev[4]; /**< FPM CPU Event 1-4 */ - volatile uint8_t res4[16]; /**< reserved */ - volatile uint32_t fmfp_ps[0x40]; /**< FPM Port Status */ - volatile uint8_t reserved1[0x260]; - volatile uint32_t fpmts[128]; /**< 0x400: FPM Task Status */ -} _PackedType t_FmFpmRegs; + volatile uint32_t iadd; /**< FM IRAM instruction address register */ + volatile uint32_t idata; /**< FM IRAM instruction data register */ + volatile uint32_t itcfg; /**< FM IRAM timing config register */ + volatile uint32_t iready; /**< FM IRAM ready register */ + volatile uint32_t res[0x1FFFC]; +} t_FMIramRegs; -#define NUM_OF_DBG_TRAPS 3 - -typedef _Packed struct +/* Trace buffer registers - + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */ +typedef struct t_FmTrbRegs { - volatile uint32_t fmbm_init; /**< BMI Initialization */ - volatile uint32_t fmbm_cfg1; /**< BMI Configuration 1 */ - volatile uint32_t fmbm_cfg2; /**< BMI Configuration 2 */ - volatile uint32_t reserved[5]; - volatile uint32_t fmbm_ievr; /**< Interrupt Event Register */ - volatile uint32_t fmbm_ier; /**< Interrupt Enable Register */ - volatile uint32_t fmbm_ifr; /**< Interrupt Force Register */ - volatile uint32_t reserved1[5]; - volatile uint32_t fmbm_arb[8]; /**< BMI Arbitration */ - volatile uint32_t reserved2[12]; - volatile uint32_t fmbm_dtc[NUM_OF_DBG_TRAPS]; /**< BMI Debug Trap Counter */ - volatile uint32_t reserved3; - volatile uint32_t fmbm_dcv[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Value */ - volatile uint32_t fmbm_dcm[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Mask */ - volatile uint32_t fmbm_gde; /**< BMI Global Debug Enable */ - volatile uint32_t fmbm_pp[63]; /**< BMI Port Parameters */ - volatile uint32_t reserved4; - volatile uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size */ - volatile uint32_t reserved5; - volatile uint32_t fmbm_ppid[63]; /**< Port Partition ID */ -} _PackedType t_FmBmiRegs; + volatile uint32_t tcrh; + volatile uint32_t tcrl; + volatile uint32_t tesr; + volatile uint32_t tecr0h; + volatile uint32_t tecr0l; + volatile uint32_t terf0h; + volatile uint32_t terf0l; + volatile uint32_t tecr1h; + volatile uint32_t tecr1l; + volatile uint32_t terf1h; + volatile uint32_t terf1l; + volatile uint32_t tpcch; + volatile uint32_t tpccl; + volatile uint32_t tpc1h; + volatile uint32_t tpc1l; + volatile uint32_t tpc2h; + volatile uint32_t tpc2l; + volatile uint32_t twdimr; + volatile uint32_t twicvr; + volatile uint32_t tar; + volatile uint32_t tdr; + volatile uint32_t tsnum1; + volatile uint32_t tsnum2; + volatile uint32_t tsnum3; + volatile uint32_t tsnum4; +} t_FmTrbRegs; -typedef _Packed struct -{ - volatile uint32_t fmqm_gc; /**< General Configuration Register */ - volatile uint32_t Reserved0; - volatile uint32_t fmqm_eie; /**< Error Interrupt Event Register */ - volatile uint32_t fmqm_eien; /**< Error Interrupt Enable Register */ - volatile uint32_t fmqm_eif; /**< Error Interrupt Force Register */ - volatile uint32_t fmqm_ie; /**< Interrupt Event Register */ - volatile uint32_t fmqm_ien; /**< Interrupt Enable Register */ - volatile uint32_t fmqm_if; /**< Interrupt Force Register */ - volatile uint32_t fmqm_gs; /**< Global Status Register */ - volatile uint32_t fmqm_ts; /**< Task Status Register */ - volatile uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter */ - volatile uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter */ - volatile uint32_t fmqm_dc0; /**< Dequeue Counter 0 */ - volatile uint32_t fmqm_dc1; /**< Dequeue Counter 1 */ - volatile uint32_t fmqm_dc2; /**< Dequeue Counter 2 */ - volatile uint32_t fmqm_dc3; /**< Dequeue Counter 3 */ - volatile uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter */ - volatile uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter */ - volatile uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter */ - volatile uint32_t fmqm_dcc; /**< Dequeue Confirm Counter */ - volatile uint32_t Reserved1a[7]; - volatile uint32_t fmqm_tapc; /**< Tnum Aging Period Control */ - volatile uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter */ - volatile uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter */ - volatile uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter */ - volatile uint32_t Reserved1b; - volatile uint32_t fmqm_dtc; /**< 0x0080 Debug Trap Counter */ - volatile uint32_t fmqm_efddd; /**< 0x0084 Enqueue Frame Descriptor Dynamic Debug */ - volatile uint32_t Reserved3[2]; - _Packed struct { - volatile uint32_t fmqm_dtcfg1; /**< 0x0090 Debug Trap Configuration 1 Register */ - volatile uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register */ - volatile uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register */ - volatile uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register */ - volatile uint32_t fmqm_dtcfg2; /**< Debug Trap Configuration 2 Register */ - volatile uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register */ - volatile uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register */ - volatile uint32_t Reserved1; - } _PackedType dbgTraps[NUM_OF_DBG_TRAPS]; -} _PackedType t_FmQmiRegs; - -typedef _Packed struct -{ - volatile uint32_t fmdmsr; /**< FM DMA status register 0x04 */ - volatile uint32_t fmdmmr; /**< FM DMA mode register 0x08 */ - volatile uint32_t fmdmtr; /**< FM DMA bus threshold register 0x0c */ - volatile uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x10 */ - volatile uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x14 */ - volatile uint32_t fmdmtah; /**< FM DMA transfer bus address high register 0x18 */ - volatile uint32_t fmdmtal; /**< FM DMA transfer bus address low register 0x1C */ - volatile uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID register 0x20 */ - volatile uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x24 */ - volatile uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x28 */ - volatile uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x2C */ - volatile uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x30 */ - volatile uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug register 0x34 */ - volatile uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value register #1 0x38 */ - volatile uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value register #2 0x3C */ - volatile uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x40 */ - volatile uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x44 */ - volatile uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x48 */ - volatile uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Counter 0x50 */ - volatile uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Counter 0x54 */ - volatile uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x54 */ - volatile uint32_t fmdmdcr; /**< FM DMA Debug Counter */ - volatile uint32_t fmdmemsr; /**< FM DMA Emrgency Smoother Register */ - volatile uint32_t reserved; - volatile uint32_t fmdmplr[FM_SIZE_OF_LIODN_TABLE/2]; - /**< FM DMA PID-LIODN # register */ -} _PackedType t_FmDmaRegs; - -typedef _Packed struct -{ - volatile uint32_t iadd; /**< FM IRAM instruction address register */ - volatile uint32_t idata; /**< FM IRAM instruction data register */ - volatile uint32_t itcfg; /**< FM IRAM timing config register */ - volatile uint32_t iready; /**< FM IRAM ready register */ - volatile uint8_t res[0x80000-0x10]; -} _PackedType t_FMIramRegs; - -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ - /**************************************************************************//** @Description General defines *//***************************************************************************/ - #define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL -#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL - - -/**************************************************************************//** - @Description DMA definitions -*//***************************************************************************/ - -/* masks */ -#define DMA_MODE_AID_OR 0x20000000 -#define DMA_MODE_SBER 0x10000000 -#define DMA_MODE_BER 0x00200000 -#define DMA_MODE_ECC 0x00000020 -#define DMA_MODE_PRIVILEGE_PROT 0x00001000 -#define DMA_MODE_SECURE_PROT 0x00000800 -#define DMA_MODE_EMERGENCY_READ 0x00080000 -#define DMA_MODE_EMERGENCY_WRITE 0x00040000 - -#define DMA_TRANSFER_PORTID_MASK 0xFF000000 -#define DMA_TRANSFER_TNUM_MASK 0x00FF0000 -#define DMA_TRANSFER_LIODN_MASK 0x00000FFF - -#define DMA_HIGH_LIODN_MASK 0x0FFF0000 -#define DMA_LOW_LIODN_MASK 0x00000FFF - -#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000 -#define DMA_STATUS_BUS_ERR 0x08000000 -#define DMA_STATUS_READ_ECC 0x04000000 -#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000 -#define DMA_STATUS_FM_WRITE_ECC 0x01000000 -#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000 -#define DMA_STATUS_FM_DPEXT_ECC 0x00400000 -#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000 -#define DMA_STATUS_FM_DPDAT_ECC 0x00100000 -#define DMA_STATUS_FM_SPDAT_ECC 0x00080000 - -#define FM_LIODN_BASE_MASK 0x00000FFF - -/* shifts */ -#define DMA_MODE_CACHE_OR_SHIFT 30 -#define DMA_MODE_BUS_PRI_SHIFT 16 -#define DMA_MODE_AXI_DBG_SHIFT 24 -#define DMA_MODE_CEN_SHIFT 13 -#define DMA_MODE_BUS_PROT_SHIFT 10 -#define DMA_MODE_DBG_SHIFT 7 -#define DMA_MODE_EMERGENCY_LEVEL_SHIFT 6 -#define DMA_MODE_AID_MODE_SHIFT 4 -#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16 -#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32 - -#define DMA_THRESH_COMMQ_SHIFT 24 -#define DMA_THRESH_READ_INT_BUF_SHIFT 16 - -#define DMA_LIODN_SHIFT 16 - -#define DMA_TRANSFER_PORTID_SHIFT 24 -#define DMA_TRANSFER_TNUM_SHIFT 16 - -/* sizes */ -#define DMA_MAX_WATCHDOG 0xffffffff - -/* others */ -#define DMA_CAM_SIZEOF_ENTRY 0x40 -#define DMA_CAM_ALIGN 0x1000 -#define DMA_CAM_UNITS 8 - +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL /**************************************************************************//** @Description FPM defines *//***************************************************************************/ - /* masks */ -#define FPM_EV_MASK_DOUBLE_ECC 0x80000000 -#define FPM_EV_MASK_STALL 0x40000000 -#define FPM_EV_MASK_SINGLE_ECC 0x20000000 -#define FPM_EV_MASK_RELEASE_FM 0x00010000 -#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000 -#define FPM_EV_MASK_STALL_EN 0x00004000 -#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000 -#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008 -#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004 - -#define FPM_RAM_CTL_RAMS_ECC_EN 0x80000000 -#define FPM_RAM_CTL_IRAM_ECC_EN 0x40000000 -#define FPM_RAM_CTL_MURAM_ECC 0x00008000 -#define FPM_RAM_CTL_IRAM_ECC 0x00004000 -#define FPM_RAM_CTL_MURAM_TEST_ECC 0x20000000 -#define FPM_RAM_CTL_IRAM_TEST_ECC 0x10000000 -#define FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL 0x08000000 - -#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000 -#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000 - -#define FPM_REV1_MAJOR_MASK 0x0000FF00 -#define FPM_REV1_MINOR_MASK 0x000000FF - -#define FPM_REV2_INTEG_MASK 0x00FF0000 -#define FPM_REV2_ERR_MASK 0x0000FF00 -#define FPM_REV2_CFG_MASK 0x000000FF - -#define FPM_TS_FRACTION_MASK 0x0000FFFF -#define FPM_TS_CTL_EN 0x80000000 - -#define FPM_PORT_FM_CTL1 0x00000001 -#define FPM_PORT_FM_CTL2 0x00000002 -#define FPM_PRC_REALSE_STALLED 0x00800000 - -#define FPM_PS_STALLED 0x00800000 -#define FPM_PS_FM_CTL1_SEL 0x80000000 -#define FPM_PS_FM_CTL2_SEL 0x40000000 -#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL) - -#define FPM_RSTC_FM_RESET 0x80000000 -#define FPM_RSTC_10G0_RESET 0x04000000 -#define FPM_RSTC_1G0_RESET 0x40000000 -#define FPM_RSTC_1G1_RESET 0x20000000 -#define FPM_RSTC_1G2_RESET 0x10000000 -#define FPM_RSTC_1G3_RESET 0x08000000 -#define FPM_RSTC_1G4_RESET 0x02000000 - - -/* shifts */ -#define FPM_DISP_LIMIT_SHIFT 24 - -#define FPM_THR1_PRS_SHIFT 24 -#define FPM_THR1_KG_SHIFT 16 -#define FPM_THR1_PLCR_SHIFT 8 -#define FPM_THR1_BMI_SHIFT 0 - -#define FPM_THR2_QMI_ENQ_SHIFT 24 -#define FPM_THR2_QMI_DEQ_SHIFT 0 -#define FPM_THR2_FM_CTL1_SHIFT 16 -#define FPM_THR2_FM_CTL2_SHIFT 8 - -#define FPM_EV_MASK_CAT_ERR_SHIFT 1 -#define FPM_EV_MASK_DMA_ERR_SHIFT 0 - -#define FPM_REV1_MAJOR_SHIFT 8 -#define FPM_REV1_MINOR_SHIFT 0 - -#define FPM_REV2_INTEG_SHIFT 16 -#define FPM_REV2_ERR_SHIFT 8 -#define FPM_REV2_CFG_SHIFT 0 - -#define FPM_TS_INT_SHIFT 16 - -#define FPM_PORT_FM_CTL_PORTID_SHIFT 24 - -#define FPM_PS_FM_CTL_SEL_SHIFT 30 -#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16 - -/* Interrupts defines */ -#define FPM_EVENT_FM_CTL_0 0x00008000 -#define FPM_EVENT_FM_CTL 0x0000FF00 -#define FPM_EVENT_FM_CTL_BRK 0x00000080 - -/* others */ -#define FPM_MAX_DISP_LIMIT 31 - +#define FPM_BRKC_RDBG 0x00000200 +#define FPM_BRKC_SLP 0x00000800 /**************************************************************************//** @Description BMI defines *//***************************************************************************/ /* masks */ #define BMI_INIT_START 0x80000000 -#define BMI_ERR_INTR_EN_PIPELINE_ECC 0x80000000 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000 #define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000 #define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000 #define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000 -#define BMI_NUM_OF_TASKS_MASK 0x3F000000 -#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000 -#define BMI_NUM_OF_DMAS_MASK 0x00000F00 -#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F -#define BMI_FIFO_SIZE_MASK 0x000003FF -#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000 -#define BMI_CFG2_DMAS_MASK 0x0000003F - -/* shifts */ -#define BMI_CFG2_TASKS_SHIFT 16 -#define BMI_CFG2_DMAS_SHIFT 0 -#define BMI_CFG1_FIFO_SIZE_SHIFT 16 -#define BMI_FIFO_SIZE_SHIFT 0 -#define BMI_EXTRA_FIFO_SIZE_SHIFT 16 -#define BMI_NUM_OF_TASKS_SHIFT 24 -#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16 -#define BMI_NUM_OF_DMAS_SHIFT 8 -#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0 - -/* others */ -#define BMI_FIFO_ALIGN 0x100 - - /**************************************************************************//** @Description QMI defines *//***************************************************************************/ /* masks */ -#define QMI_CFG_ENQ_EN 0x80000000 -#define QMI_CFG_DEQ_EN 0x40000000 -#define QMI_CFG_EN_COUNTERS 0x10000000 -#define QMI_CFG_SOFT_RESET 0x01000000 -#define QMI_CFG_DEQ_MASK 0x0000003F -#define QMI_CFG_ENQ_MASK 0x00003F00 - #define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000 #define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000 #define QMI_INTR_EN_SINGLE_ECC 0x80000000 -/* shifts */ -#define QMI_CFG_ENQ_SHIFT 8 -#define QMI_TAPC_TAP 22 - - /**************************************************************************//** @Description IRAM defines *//***************************************************************************/ @@ -566,49 +501,21 @@ typedef _Packed struct #define IRAM_IADD_AIE 0x80000000 #define IRAM_READY 0x80000000 +/**************************************************************************//** + @Description TRB defines +*//***************************************************************************/ +/* masks */ +#define TRB_TCRH_RESET 0x04000000 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000 +#define TRB_TCRL_RESET 0x20000000 +#define TRB_TCRL_UTIL 0x00000460 typedef struct { void (*f_Isr) (t_Handle h_Arg, uint32_t event); t_Handle h_SrcHandle; } t_FmanCtrlIntrSrc; -typedef struct -{ - /* uint8_t numOfPartitions; */ - bool resetOnInit; -#ifdef FM_PARTITION_ARRAY - uint16_t liodnBasePerPort[FM_SIZE_OF_LIODN_TABLE]; -#endif - bool enCounters; - t_FmThresholds thresholds; - e_FmDmaCacheOverride dmaCacheOverride; - e_FmDmaAidMode dmaAidMode; - bool dmaAidOverride; - uint8_t dmaAxiDbgNumOfBeats; - uint8_t dmaCamNumOfEntries; - uint32_t dmaWatchdog; - t_FmDmaThresholds dmaCommQThresholds; - t_FmDmaThresholds dmaWriteBufThresholds; - t_FmDmaThresholds dmaReadBufThresholds; - uint32_t dmaSosEmergency; - e_FmDmaDbgCntMode dmaDbgCntMode; - bool dmaStopOnBusError; - bool dmaEnEmergency; - t_FmDmaEmergency dmaEmergency; - bool dmaEnEmergencySmoother; - uint32_t dmaEmergencySwitchCounter; - bool haltOnExternalActivation; - bool haltOnUnrecoverableEccError; - e_FmCatastrophicErr catastrophicErr; - e_FmDmaErr dmaErr; - bool enMuramTestMode; - bool enIramTestMode; - bool externalEccRamsEnable; - uint16_t tnumAgingPeriod; - t_FmPcdFirmwareParams firmware; - bool fwVerify; -} t_FmDriverParam; - typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event); typedef struct @@ -619,6 +526,8 @@ typedef struct uint8_t fmId; e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS]; uint16_t fmClkFreq; + uint16_t fmMacClkFreq; + t_FmRevisionInfo revInfo; /**************************/ /* Master Only parameters */ /**************************/ @@ -630,15 +539,13 @@ typedef struct uint8_t accumulatedNumOfTasks; uint32_t accumulatedFifoSize; uint8_t accumulatedNumOfOpenDmas; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT uint8_t accumulatedNumOfDeqTnums; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ #ifdef FM_LOW_END_RESTRICTION bool lowEndRestriction; #endif /* FM_LOW_END_RESTRICTION */ uint32_t exceptions; - int irq; - int errIrq; + uintptr_t irq; + uintptr_t errIrq; bool ramsEccEnable; bool explicitEnable; bool internalCall; @@ -647,12 +554,39 @@ typedef struct uint8_t extraTasksPoolSize; uint8_t extraOpenDmasPoolSize; #if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS]; uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS]; -#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) */ +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS]; uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS]; } t_FmStateStruct; -typedef struct +#if (DPAA_VERSION >= 11) +typedef struct t_FmMapParam { + uint16_t profilesBase; + uint16_t numOfProfiles; + t_Handle h_FmPort; +} t_FmMapParam; + +typedef struct t_FmAllocMng { + bool allocated; + uint8_t ownerId; /* guestId for KG in multi-partition only, + portId for PLCR in any environment */ +} t_FmAllocMng; + +typedef struct t_FmPcdSpEntry { + bool valid; + t_FmAllocMng profilesMng; +} t_FmPcdSpEntry; + +typedef struct t_FmSp { + void *p_FmPcdStoragePrflRegs; + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES]; + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS]; +} t_FmSp; +#endif /* (DPAA_VERSION >= 11) */ + +typedef struct t_Fm { /***************************/ /* Master/Guest parameters */ @@ -671,19 +605,29 @@ typedef struct /* Master Only parameters */ /**************************/ /* locals for recovery */ - t_FmFpmRegs *p_FmFpmRegs; - t_FmBmiRegs *p_FmBmiRegs; - t_FmQmiRegs *p_FmQmiRegs; - t_FmDmaRegs *p_FmDmaRegs; + struct fman_fpm_regs *p_FmFpmRegs; + struct fman_bmi_regs *p_FmBmiRegs; + struct fman_qmi_regs *p_FmQmiRegs; + struct fman_dma_regs *p_FmDmaRegs; + struct fman_regs *p_FmRegs; t_FmExceptionsCallback *f_Exception; t_FmBusErrorCallback *f_BusError; t_Handle h_App; /* Application handle */ t_Handle h_Spinlock; bool recoveryMode; t_FmStateStruct *p_FmStateStruct; + uint16_t tnumAgingPeriod; +#if (DPAA_VERSION >= 11) + t_FmSp *p_FmSp; + uint8_t partNumOfVSPs; + uint8_t partVSPBase; + uintptr_t vspBaseAddr; +#endif /* (DPAA_VERSION >= 11) */ + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */ + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */ /* un-needed for recovery */ - t_FmDriverParam *p_FmDriverParam; + struct fman_cfg *p_FmDriverParam; t_Handle h_FmMuram; uint64_t fmMuramPhysBaseAddr; bool independentMode; @@ -693,6 +637,11 @@ typedef struct uintptr_t fifoBaseAddr; /* save for freeing */ t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */ bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; + t_FmFirmwareParams firmware; + bool fwVerify; + bool resetOnInit; + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride; + uint32_t userSetExceptions; } t_Fm; diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h b/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h index 7bb2e48c7fba..7ce36a767e25 100644 --- a/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h +++ b/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_ipc.h @@ -61,7 +62,6 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START /**************************************************************************//** @Description enum for defining MAC types @@ -94,6 +94,17 @@ typedef _Packed struct t_FmIpcPhysAddr volatile uint32_t low; } _PackedType t_FmIpcPhysAddr; + +typedef _Packed struct t_FmIpcPortOutInitParams { + uint8_t numOfTasks; /**< OUT */ + uint8_t numOfExtraTasks; /**< OUT */ + uint8_t numOfOpenDmas; /**< OUT */ + uint8_t numOfExtraOpenDmas; /**< OUT */ + uint32_t sizeOfFifo; /**< OUT */ + uint32_t extraSizeOfFifo; /**< OUT */ + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */ +} _PackedType t_FmIpcPortOutInitParams; + /**************************************************************************//** @Description Structure for IPC communication during FM_PORT_Init. *//***************************************************************************/ @@ -109,6 +120,7 @@ typedef _Packed struct t_FmIpcPortInInitParams { uint32_t sizeOfFifo; /**< IN. Port's requested resource */ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ + uint16_t maxFrameLength; /**< IN. Port's max frame length. */ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1. LIODN base for this port, to be used together with LIODN offset. */ @@ -148,9 +160,7 @@ typedef _Packed struct t_FmIpcPortFifoParams { typedef _Packed struct t_FmIpcPortFreeParams { uint8_t hardwarePortId; /**< IN. port Id */ uint32_t enumPortType; /**< IN. Port type */ -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ } _PackedType t_FmIpcPortFreeParams; /**************************************************************************//** @@ -162,6 +172,7 @@ typedef _Packed struct t_FmIpcDmaStatus { uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */ uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */ uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */ + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */ } _PackedType t_FmIpcDmaStatus; typedef _Packed struct t_FmIpcRegisterIntr @@ -177,12 +188,24 @@ typedef _Packed struct t_FmIpcIsr } _PackedType t_FmIpcIsr; /**************************************************************************//** - @Description structure for returning revision information + @Description structure for returning FM parameters *//***************************************************************************/ -typedef _Packed struct t_FmIpcRevisionInfo { +typedef _Packed struct t_FmIpcParams { + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */ + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */ + uint8_t majorRev; /**< OUT: FM Major revision */ + uint8_t minorRev; /**< OUT: FM Minor revision */ +} _PackedType t_FmIpcParams; + + +/**************************************************************************//** + @Description structure for returning Fman Ctrl Code revision information +*//***************************************************************************/ +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo { + uint16_t packageRev; /**< OUT: Package revision */ uint8_t majorRev; /**< OUT: Major revision */ uint8_t minorRev; /**< OUT: Minor revision */ -} _PackedType t_FmIpcRevisionInfo; +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo; /**************************************************************************//** @Description Structure for defining Fm number of Fman controlers @@ -190,19 +213,38 @@ typedef _Packed struct t_FmIpcRevisionInfo { typedef _Packed struct t_FmIpcPortNumOfFmanCtrls { uint8_t hardwarePortId; /**< IN. port Id */ uint8_t numOfFmanCtrls; /**< IN. Port type */ + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/ } t_FmIpcPortNumOfFmanCtrls; /**************************************************************************//** @Description structure for setting Fman contriller events *//***************************************************************************/ typedef _Packed struct t_FmIpcFmanEvents { - uint8_t eventRegId; /**< IN: Fman controller event register id */ - uint32_t enableEvents; /**< IN/OUT: required enabled events mask */ + uint8_t eventRegId; /**< IN: Fman controller event register id */ + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */ } _PackedType t_FmIpcFmanEvents; -#define FM_IPC_MAX_REPLY_BODY_SIZE 16 +typedef _Packed struct t_FmIpcResourceAllocParams { + uint8_t guestId; + uint16_t base; + uint16_t num; +}_PackedType t_FmIpcResourceAllocParams; + +typedef _Packed struct t_FmIpcVspSetPortWindow { + uint8_t hardwarePortId; + uint8_t baseStorageProfile; + uint8_t log2NumOfProfiles; +}_PackedType t_FmIpcVspSetPortWindow; + +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority { + uint32_t congestionGroupId; + uint8_t priorityBitMap; +}_PackedType t_FmIpcSetCongestionGroupPfcPriority; + +#define FM_IPC_MAX_REPLY_BODY_SIZE 20 #define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t)) #define FM_IPC_MAX_MSG_SIZE 30 + typedef _Packed struct t_FmIpcMsg { uint32_t msgId; @@ -215,7 +257,6 @@ typedef _Packed struct t_FmIpcReply uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE]; } _PackedType t_FmIpcReply; -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -243,16 +284,6 @@ typedef _Packed struct t_FmIpcReply *//***************************************************************************/ #define FM_GET_COUNTER 2 -/**************************************************************************//** - @Function FM_DUMP_REGS - - @Description Used by FM front-end for the PORT module in order to set and get - parameters in/from master FM module on FM PORT initialization time. - - @Param None -*//***************************************************************************/ -#define FM_DUMP_REGS 3 - /**************************************************************************//** @Function FM_GET_SET_PORT_PARAMS @@ -303,24 +334,14 @@ typedef _Packed struct t_FmIpcReply #define FM_IS_PORT_STALLED 8 /**************************************************************************//** - @Function FM_DUMP_PORT_REGS + @Function FM_GET_PARAMS @Description Used by FM front-end for the PORT module in order to dump - all port registers. + return FM parameters. @Param[in] uint8_t Pointer *//***************************************************************************/ -#define FM_DUMP_PORT_REGS 9 - -/**************************************************************************//** - @Function FM_GET_REV - - @Description Used by FM front-end for the PORT module in order to dump - all port registers. - - @Param[in] uint8_t Pointer -*//***************************************************************************/ -#define FM_GET_REV 10 +#define FM_GET_PARAMS 10 /**************************************************************************//** @Function FM_REGISTER_INTR @@ -332,15 +353,6 @@ typedef _Packed struct t_FmIpcReply *//***************************************************************************/ #define FM_REGISTER_INTR 11 -/**************************************************************************//** - @Function FM_GET_CLK_FREQ - - @Description Used by FM Front-end to read the FM clock frequency. - - @Param[out] uint32_t Pointer -*//***************************************************************************/ -#define FM_GET_CLK_FREQ 12 - /**************************************************************************//** @Function FM_DMA_STAT @@ -422,7 +434,11 @@ typedef _Packed struct t_FmIpcReply #define FM_SET_SIZE_OF_FIFO 24 #define FM_SET_NUM_OF_TASKS 25 #define FM_SET_NUM_OF_OPEN_DMAS 26 - +#define FM_VSP_ALLOC 27 +#define FM_VSP_FREE 28 +#define FM_VSP_SET_PORT_WINDOW 29 +#define FM_GET_FMAN_CTRL_CODE_REV 30 +#define FM_SET_CONG_GRP_PFC_PRIO 31 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 #define FM_10G_TX_ECC_WA 100 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_muram.c b/sys/contrib/ncsw/Peripherals/FM/fm_muram.c index e52f233993ec..0bc67cb74b99 100644 --- a/sys/contrib/ncsw/Peripherals/FM/fm_muram.c +++ b/sys/contrib/ncsw/Peripherals/FM/fm_muram.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File FM_muram.c @@ -43,7 +44,6 @@ #include "fm_muram_ext.h" #include "fm_common.h" - #define __ERR_MODULE__ MODULE_FM_MURAM @@ -158,7 +158,17 @@ t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr) SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE); if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0) - RETURN_ERROR(MINOR, E_INVALID_HANDLE, ("memory pointer!!!")); + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!")); return E_OK; } + +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram) +{ + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; + + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0); + + return MM_GetFreeMemSize(p_FmMuram->h_Mem); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_ncsw.c b/sys/contrib/ncsw/Peripherals/FM/fm_ncsw.c new file mode 100644 index 000000000000..884bc45edd3b --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/fm_ncsw.c @@ -0,0 +1,5213 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm.c + + @Description FM driver routines implementation. +*//***************************************************************************/ +#include "std_ext.h" +#include "error_ext.h" +#include "xx_ext.h" +#include "string_ext.h" +#include "sprint_ext.h" +#include "debug_ext.h" +#include "fm_muram_ext.h" +#include + +#include "fm_common.h" +#include "fm_ipc.h" +#include "fm.h" +#include "fsl_fman.h" + + +/****************************************/ +/* static functions */ +/****************************************/ + +static volatile bool blockingFlag = FALSE; +static void IpcMsgCompletionCB(t_Handle h_Fm, + uint8_t *p_Msg, + uint8_t *p_Reply, + uint32_t replyLength, + t_Error status) +{ + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); + blockingFlag = FALSE; +} + +static void FreeInitResources(t_Fm *p_Fm) +{ + if (p_Fm->camBaseAddr) + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr)); + if (p_Fm->fifoBaseAddr) + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr)); + if (p_Fm->resAddr) + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr)); +} + +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm) +{ + t_FMIramRegs *p_Iram; + + ASSERT_COND(p_Fm); + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY); +} + +static t_Error CheckFmParameters(t_Fm *p_Fm) +{ + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!")); +#if (DPAA_VERSION < 11) + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats || + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)); +#endif /* (DPAA_VERSION < 11) */ + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS)); +// if (!p_Fm->p_FmDriverParam->dma_cam_num_of_entries || (p_Fm->p_FmDriverParam->dma_cam_num_of_entries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)) +// RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)); + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ)); + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ)); + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer")); +#if (DPAA_VERSION < 11) + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer")); + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer")); +#else /* (DPAA_VERSION >= 11) */ + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)|| + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) || + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration.")); + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)|| + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration.")); + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration.")); +#ifdef FM_AID_MODE_NO_TNUM_SW005 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration.")); +#endif /* FM_AID_MODE_NO_TNUM_SW005 */ + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration.")); +#endif /* (DPAA_VERSION < 11) */ + + if (!p_Fm->p_FmStateStruct->fmClkFreq) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set.")); + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG)); + +#if (DPAA_VERSION >= 11) + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!")); +#endif /* (DPAA_VERSION >= 11) */ + + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS)); + if (!p_Fm->p_FmStateStruct->totalFifoSize || + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d", + p_Fm->p_FmStateStruct->totalFifoSize, + BMI_MAX_FIFO_SIZE)); + if (!p_Fm->p_FmStateStruct->totalNumOfTasks || + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS)); + +#ifdef FM_HAS_TOTAL_DMAS + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS)); +#endif /* FM_HAS_TOTAL_DMAS */ + + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT)); + + if (!p_Fm->f_Exception) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); + if (!p_Fm->f_BusError) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); + +#ifdef FM_NO_WATCHDOG + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) && + (p_Fm->p_FmDriverParam->dma_watchdog)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!")); +#endif /* FM_NO_WATCHDOG */ + +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) && + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!")); +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */ + +#ifdef FM_NO_TNUM_AGING + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)) + if (p_Fm->p_FmDriverParam->tnum_aging_period) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!")); +#endif /* FM_NO_TNUM_AGING */ + + /* check that user did not set revision-dependent exceptions */ +#ifdef FM_NO_DISPATCH_RAM_ECC + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)) + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!")); +#endif /* FM_NO_DISPATCH_RAM_ECC */ + +#ifdef FM_QMI_NO_ECC_EXCEPTIONS + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4) + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC)) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!")); +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ + +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!")); +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */ + + return E_OK; +} + + +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg) +{ + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID); + + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID) + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle); + + /* If the MAC is running on guest-partition and we have IPC session with it, + we inform him about the event through IPC; otherwise, we ignore the event. */ + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]) + { + t_Error err; + t_FmIpcIsr fmIpcIsr; + t_FmIpcMsg msg; + + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_GUEST_ISR; + fmIpcIsr.pendingReg = pendingReg; + fmIpcIsr.boolErr = FALSE; + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(fmIpcIsr), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + } + else + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!")); +} + +static void BmiErrEvent(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; + + + event = fman_get_bmi_err_event(bmi_rg); + + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC); + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC); + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC); + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC); +} + +static void QmiErrEvent(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; + + event = fman_get_qmi_err_event(qmi_rg); + + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC); + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID); +} + +static void DmaErrEvent(t_Fm *p_Fm) +{ + uint32_t status, com_id; + uint8_t tnum; + uint8_t hardwarePortId; + uint8_t relativePortId; + uint16_t liodn; + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs; + + status = fman_get_dma_err_event(dma_rg); + + if (status & DMA_STATUS_BUS_ERR) + { + com_id = fman_get_dma_com_id(dma_rg); + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT)); + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT); + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK); + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY); + p_Fm->f_BusError(p_Fm->h_App, + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], + relativePortId, + fman_get_dma_addr(dma_rg), + tnum, + liodn); + } + if (status & DMA_STATUS_FM_SPDAT_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC); + if (status & DMA_STATUS_READ_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC); + if (status & DMA_STATUS_SYSTEM_WRITE_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC); + if (status & DMA_STATUS_FM_WRITE_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC); + } + +static void FpmErrEvent(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + event = fman_get_fpm_err_event(fpm_rg); + + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN)) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC); + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN)) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS); + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN)) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC); +} + +static void MuramErrIntr(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + event = fman_get_muram_err_event(fpm_rg); + + if (event & FPM_RAM_MURAM_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC); +} + +static void IramErrIntr(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + event = fman_get_iram_err_event(fpm_rg); + + if (event & FPM_RAM_IRAM_ECC) + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC); +} + +static void QmiEvent(t_Fm *p_Fm) +{ + uint32_t event; + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; + + event = fman_get_qmi_event(qmi_rg); + + if (event & QMI_INTR_EN_SINGLE_ECC) + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC); +} + +static void UnimplementedIsr(t_Handle h_Arg) +{ + UNUSED(h_Arg); + + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!")); +} + +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event) +{ + UNUSED(h_Arg); UNUSED(event); + + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!")); +} + +static void EnableTimeStamp(t_Fm *p_Fm) +{ + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + ASSERT_COND(p_Fm->p_FmStateStruct); + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit); + + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq); + + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE; +} + +static t_Error ClearIRam(t_Fm *p_Fm) +{ + t_FMIramRegs *p_Iram; + int i; + int iram_size; + + ASSERT_COND(p_Fm); + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev); + + /* Enable the auto-increment */ + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; + + for (i=0; i < (iram_size/4); i++) + WRITE_UINT32(p_Iram->idata, 0xffffffff); + + WRITE_UINT32(p_Iram->iadd, iram_size - 4); + CORE_MemoryBarrier(); + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ; + + return E_OK; +} + +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm) +{ + t_FMIramRegs *p_Iram; + int i; + uint32_t tmp; + uint8_t compTo16; + + ASSERT_COND(p_Fm); + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + + /* Enable the auto-increment */ + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; + + for (i=0; i < (p_Fm->firmware.size / 4); i++) + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]); + + compTo16 = (uint8_t)(p_Fm->firmware.size % 16); + if (compTo16) + for (i=0; i < ((16-compTo16) / 4); i++) + WRITE_UINT32(p_Iram->idata, 0xffffffff); + + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4); + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ; + + /* verify that writing has completed */ + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ; + + if (p_Fm->fwVerify) + { + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; + for (i=0; i < (p_Fm->firmware.size / 4); i++) + { + tmp = GET_UINT32(p_Iram->idata); + if (tmp != p_Fm->firmware.p_Code[i]) + RETURN_ERROR(MAJOR, E_WRITE_FAILED, + ("UCode write error : write 0x%x, read 0x%x", + p_Fm->firmware.p_Code[i],tmp)); + } + WRITE_UINT32(p_Iram->iadd, 0x0); + } + + /* Enable patch from IRAM */ + WRITE_UINT32(p_Iram->iready, IRAM_READY); + XX_UDelay(1000); + + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.", + ((uint16_t *)p_Fm->firmware.p_Code)[2], + ((uint8_t *)p_Fm->firmware.p_Code)[6], + ((uint8_t *)p_Fm->firmware.p_Code)[7])); + + return E_OK; +} + +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm) +{ + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + uint32_t tmpReg; + uint32_t savedSpliodn[63]; + + /* write to IRAM first location the debug instruction */ + WRITE_UINT32(p_Iram->iadd, 0); + while (GET_UINT32(p_Iram->iadd) != 0) ; + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION); + + WRITE_UINT32(p_Iram->iadd, 0); + while (GET_UINT32(p_Iram->iadd) != 0) ; + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ; + + /* Enable patch from IRAM */ + WRITE_UINT32(p_Iram->iready, IRAM_READY); + CORE_MemoryBarrier(); + XX_UDelay(100); + IO2MemCpy32((uint8_t *)savedSpliodn, + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn, + 63*sizeof(uint32_t)); + + /* reset FMAN */ + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); + CORE_MemoryBarrier(); + XX_UDelay(100); + + /* verify breakpoint debug status register */ + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET)); + if (!tmpReg) + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'")); + + /*************************************/ + /* Load FMan-Controller code to IRAM */ + /*************************************/ + ClearIRam(p_Fm); + if (p_Fm->firmware.p_Code && + (LoadFmanCtrlCode(p_Fm) != E_OK)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); + XX_UDelay(100); + + /* reset FMAN again to start the microcode */ + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); + CORE_MemoryBarrier(); + XX_UDelay(100); + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn, + (uint8_t *)savedSpliodn, + 63*sizeof(uint32_t)); + + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs)) + { + fman_resume(p_Fm->p_FmFpmRegs); + CORE_MemoryBarrier(); + XX_UDelay(100); + } + + return E_OK; +} +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ + +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending) +{ +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \ +do { \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ +} while (0) +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \ +do { \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\ +} while (0) + + /* error interrupts */ + if (pending & ERR_INTR_EN_1G_MAC0) + FM_G_CALL_1G_MAC_ERR_ISR(0); + if (pending & ERR_INTR_EN_1G_MAC1) + FM_G_CALL_1G_MAC_ERR_ISR(1); + if (pending & ERR_INTR_EN_1G_MAC2) + FM_G_CALL_1G_MAC_ERR_ISR(2); + if (pending & ERR_INTR_EN_1G_MAC3) + FM_G_CALL_1G_MAC_ERR_ISR(3); + if (pending & ERR_INTR_EN_1G_MAC4) + FM_G_CALL_1G_MAC_ERR_ISR(4); + if (pending & ERR_INTR_EN_1G_MAC5) + FM_G_CALL_1G_MAC_ERR_ISR(5); + if (pending & ERR_INTR_EN_1G_MAC6) + FM_G_CALL_1G_MAC_ERR_ISR(6); + if (pending & ERR_INTR_EN_1G_MAC7) + FM_G_CALL_1G_MAC_ERR_ISR(7); + if (pending & ERR_INTR_EN_10G_MAC0) + FM_G_CALL_10G_MAC_ERR_ISR(0); + if (pending & ERR_INTR_EN_10G_MAC1) + FM_G_CALL_10G_MAC_ERR_ISR(1); +} + +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending) +{ +#define FM_G_CALL_1G_MAC_ISR(_id) \ +do { \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\ +} while (0) +#define FM_G_CALL_10G_MAC_ISR(_id) \ +do { \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\ +} while (0) + + if (pending & INTR_EN_1G_MAC0) + FM_G_CALL_1G_MAC_ISR(0); + if (pending & INTR_EN_1G_MAC1) + FM_G_CALL_1G_MAC_ISR(1); + if (pending & INTR_EN_1G_MAC2) + FM_G_CALL_1G_MAC_ISR(2); + if (pending & INTR_EN_1G_MAC3) + FM_G_CALL_1G_MAC_ISR(3); + if (pending & INTR_EN_1G_MAC4) + FM_G_CALL_1G_MAC_ISR(4); + if (pending & INTR_EN_1G_MAC5) + FM_G_CALL_1G_MAC_ISR(5); + if (pending & INTR_EN_1G_MAC6) + FM_G_CALL_1G_MAC_ISR(6); + if (pending & INTR_EN_1G_MAC7) + FM_G_CALL_1G_MAC_ISR(7); + if (pending & INTR_EN_10G_MAC0) + FM_G_CALL_10G_MAC_ISR(0); + if (pending & INTR_EN_10G_MAC1) + FM_G_CALL_10G_MAC_ISR(1); + if (pending & INTR_EN_TMR) + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); +} + +#if (DPAA_VERSION >= 11) +static t_Error SetVSPWindow(t_Handle h_Fm, + uint8_t hardwarePortId, + uint8_t baseStorageProfile, + uint8_t log2NumOfProfiles) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + + ASSERT_COND(h_Fm); + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->p_FmBmiRegs && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow; + t_FmIpcMsg msg; + t_Error err = E_OK; + + memset(&msg, 0, sizeof(msg)); + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow)); + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId; + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile; + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles; + msg.msgId = FM_VSP_SET_PORT_WINDOW; + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow)); + + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return E_OK; + } + else if (!p_Fm->p_FmBmiRegs) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + fman_set_vsp_window(p_Fm->p_FmBmiRegs, + hardwarePortId, + baseStorageProfile, + log2NumOfProfiles); + + return E_OK; +} + +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + uint8_t profilesFound = 0; + int i = 0; + uint32_t intFlags; + + if (!numOfProfiles) + return E_OK; + + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) || + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES)) + return (uint8_t)ILLEGAL_BASE; + + if (p_Fm->h_IpcSessions[0]) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + t_Error err; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = p_Fm->guestId; + ipcAllocParams.num = p_Fm->partNumOfVSPs; + ipcAllocParams.base = p_Fm->partVSPBase; + msg.msgId = FM_VSP_ALLOC; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + replyLength = sizeof(uint32_t) + sizeof(uint8_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if ((err != E_OK) || + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))) + RETURN_ERROR(MAJOR, err, NO_MSG); + else + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t)); + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) + RETURN_ERROR(MAJOR, err, NO_MSG); + } + if (p_Fm->guestId != NCSW_MASTER_ID) + { + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!")); + return (uint8_t)ILLEGAL_BASE; + } + + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); + for (i = base; i < base + numOfProfiles; i++) + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE) + profilesFound++; + else + break; + + if (profilesFound == numOfProfiles) + for (i = base; ip_FmSp->profiles[i].profilesMng.ownerId = guestId; + else + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + return (uint8_t)ILLEGAL_BASE; + } + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + + return base; +} + +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + int i = 0; + + ASSERT_COND(p_Fm); + + if (p_Fm->h_IpcSessions[0]) + { + t_FmIpcResourceAllocParams ipcAllocParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + t_Error err; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); + ipcAllocParams.guestId = p_Fm->guestId; + ipcAllocParams.num = p_Fm->partNumOfVSPs; + ipcAllocParams.base = p_Fm->partVSPBase; + msg.msgId = FM_VSP_FREE; + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); + replyLength = sizeof(uint32_t) + sizeof(uint8_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MAJOR, err, NO_MSG); + return; + } + if (p_Fm->guestId != NCSW_MASTER_ID) + { + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!")); + return; + } + + ASSERT_COND(p_Fm->p_FmSp); + + for (i=base; ip_FmSp->profiles[i].profilesMng.ownerId == guestId) + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; + else + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition")); + } +} +#endif /* (DPAA_VERSION >= 11) */ + +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm, + uint8_t *p_Msg, + uint32_t msgLength, + uint8_t *p_Reply, + uint32_t *p_ReplyLength) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; + + UNUSED(p_Reply); + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE); + +#ifdef DISABLE_SANITY_CHECKS + UNUSED(msgLength); +#endif /* DISABLE_SANITY_CHECKS */ + + ASSERT_COND(p_Msg); + + *p_ReplyLength = 0; + + switch (p_IpcMsg->msgId) + { + case (FM_GUEST_ISR): + { + t_FmIpcIsr ipcIsr; + + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr)); + if (ipcIsr.boolErr) + GuestErrorIsr(p_Fm, ipcIsr.pendingReg); + else + GuestEventIsr(p_Fm, ipcIsr.pendingReg); + break; + } + default: + *p_ReplyLength = 0; + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); + } + return E_OK; +} + +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm, + uint8_t *p_Msg, + uint32_t msgLength, + uint8_t *p_Reply, + uint32_t *p_ReplyLength) +{ + t_Error err; + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); + +#ifdef DISABLE_SANITY_CHECKS + UNUSED(msgLength); +#endif /* DISABLE_SANITY_CHECKS */ + + ASSERT_COND(p_IpcMsg); + + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE)); + *p_ReplyLength = 0; + + switch (p_IpcMsg->msgId) + { + case (FM_GET_SET_PORT_PARAMS): + { + t_FmIpcPortInInitParams ipcInitParams; + t_FmInterModulePortInitParams initParams; + t_FmIpcPortOutInitParams ipcOutInitParams; + + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams)); + initParams.hardwarePortId = ipcInitParams.hardwarePortId; + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType; + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode); + initParams.liodnOffset = ipcInitParams.liodnOffset; + initParams.numOfTasks = ipcInitParams.numOfTasks; + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks; + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas; + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas; + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo; + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo; + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth; + initParams.maxFrameLength = ipcInitParams.maxFrameLength; + initParams.liodnBase = ipcInitParams.liodnBase; + + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams); + + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high; + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low; + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo; + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo; + ipcOutInitParams.numOfTasks = initParams.numOfTasks; + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks; + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas; + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas; + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams); + break; + } + case (FM_SET_SIZE_OF_FIFO): + { + t_FmIpcPortRsrcParams ipcPortRsrcParams; + + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, + ipcPortRsrcParams.hardwarePortId, + &ipcPortRsrcParams.val, + &ipcPortRsrcParams.extra, + (bool)ipcPortRsrcParams.boolInitialConfig); + *p_ReplyLength = sizeof(uint32_t); + break; + } + case (FM_SET_NUM_OF_TASKS): + { + t_FmIpcPortRsrcParams ipcPortRsrcParams; + + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId, + (uint8_t*)&ipcPortRsrcParams.val, + (uint8_t*)&ipcPortRsrcParams.extra, + (bool)ipcPortRsrcParams.boolInitialConfig); + *p_ReplyLength = sizeof(uint32_t); + break; + } + case (FM_SET_NUM_OF_OPEN_DMAS): + { + t_FmIpcPortRsrcParams ipcPortRsrcParams; + + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId, + (uint8_t*)&ipcPortRsrcParams.val, + (uint8_t*)&ipcPortRsrcParams.extra, + (bool)ipcPortRsrcParams.boolInitialConfig); + *p_ReplyLength = sizeof(uint32_t); + break; + } + case (FM_RESUME_STALLED_PORT): + *p_ReplyLength = sizeof(uint32_t); + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]); + break; + case (FM_MASTER_IS_ALIVE): + { + uint8_t guestId = p_IpcMsg->msgBody[0]; + /* build the FM master partition IPC address */ + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE); + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName); + if (p_Fm->h_IpcSessions[guestId] == NULL) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId)); + *(uint8_t*)(p_IpcReply->replyBody) = 1; + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); + break; + } + case (FM_IS_PORT_STALLED): + { + bool tmp; + + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp); + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp; + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); + break; + } + case (FM_RESET_MAC): + { + t_FmIpcMacParams ipcMacParams; + + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams)); + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm, + (e_FmMacType)(ipcMacParams.enumType), + ipcMacParams.id); + *p_ReplyLength = sizeof(uint32_t); + break; + } + case (FM_SET_MAC_MAX_FRAME): + { + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams; + + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams)); + err = FmSetMacMaxFrame(p_Fm, + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType), + ipcMacMaxFrameParams.macParams.id, + ipcMacMaxFrameParams.maxFrameLength); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + break; + } +#if (DPAA_VERSION >= 11) + case (FM_VSP_ALLOC) : + { + t_FmIpcResourceAllocParams ipcAllocParams; + uint8_t vspBase; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId); + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); + break; + } + case (FM_VSP_FREE) : + { + t_FmIpcResourceAllocParams ipcAllocParams; + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId); + break; + } + case (FM_VSP_SET_PORT_WINDOW) : + { + t_FmIpcVspSetPortWindow ipcVspSetPortWindow; + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow)); + err = SetVSPWindow(h_Fm, + ipcVspSetPortWindow.hardwarePortId, + ipcVspSetPortWindow.baseStorageProfile, + ipcVspSetPortWindow.log2NumOfProfiles); + return err; + } + case (FM_SET_CONG_GRP_PFC_PRIO) : + { + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority; + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); + err = FmSetCongestionGroupPFCpriority(h_Fm, + fmIpcSetCongestionGroupPfcPriority.congestionGroupId, + fmIpcSetCongestionGroupPfcPriority.priorityBitMap); + return err; + } +#endif /* (DPAA_VERSION >= 11) */ + + case (FM_FREE_PORT): + { + t_FmInterModulePortFreeParams portParams; + t_FmIpcPortFreeParams ipcPortParams; + + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams)); + portParams.hardwarePortId = ipcPortParams.hardwarePortId; + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType); + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth; + FmFreePortParams(h_Fm, &portParams); + break; + } + case (FM_REGISTER_INTR): + { + t_FmIpcRegisterIntr ipcRegIntr; + + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr)); + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId; + break; + } + case (FM_GET_PARAMS): + { + t_FmIpcParams ipcParams; + + /* Get clock frequency */ + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq; + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq; + + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev); + + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams); + break; + } + case (FM_GET_FMAN_CTRL_CODE_REV): + { + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo; + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo; + + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo); + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev; + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev; + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev; + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo); + break; + } + + case (FM_DMA_STAT): + { + t_FmDmaStatus dmaStatus; + t_FmIpcDmaStatus ipcDmaStatus; + + FM_GetDmaStatus(h_Fm, &dmaStatus); + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty; + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError; + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError; + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError; + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError; + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError; + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); + break; + } + case (FM_ALLOC_FMAN_CTRL_EVENT_REG): + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody); + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); + break; + case (FM_FREE_FMAN_CTRL_EVENT_REG): + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]); + break; + case (FM_GET_TIMESTAMP_SCALE): + { + uint32_t timeStamp = FmGetTimeStampScale(h_Fm); + + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); + break; + } + case (FM_GET_COUNTER): + { + e_FmCounters inCounter; + uint32_t outCounter; + + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t)); + outCounter = FM_GetCounter(h_Fm, inCounter); + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); + break; + } + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE): + { + t_FmIpcFmanEvents ipcFmanEvents; + + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents)); + FmSetFmanCtrlIntr(h_Fm, + ipcFmanEvents.eventRegId, + ipcFmanEvents.enableEvents); + break; + } + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE): + { + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]); + + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); + break; + } + case (FM_GET_PHYS_MURAM_BASE): + { + t_FmPhysAddr physAddr; + t_FmIpcPhysAddr ipcPhysAddr; + + FmGetPhysicalMuramBase(h_Fm, &physAddr); + ipcPhysAddr.high = physAddr.high; + ipcPhysAddr.low = physAddr.low; + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr)); + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr); + break; + } + case (FM_ENABLE_RAM_ECC): + { + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) || + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) || + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK)) +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) + UNUSED(err); +#else + REPORT_ERROR(MINOR, err, NO_MSG); +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */ + break; + } + case (FM_DISABLE_RAM_ECC): + { + + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) || + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) || + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK)) +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) + UNUSED(err); +#else + REPORT_ERROR(MINOR, err, NO_MSG); +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */ + break; + } + case (FM_SET_NUM_OF_FMAN_CTRL): + { + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls; + + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls)); + err = FmSetNumOfRiscsPerPort(h_Fm, + ipcPortNumOfFmanCtrls.hardwarePortId, + ipcPortNumOfFmanCtrls.numOfFmanCtrls, + ipcPortNumOfFmanCtrls.orFmanCtrl); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + break; + } +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 + case (FM_10G_TX_ECC_WA): + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]); + *p_ReplyLength = sizeof(uint32_t); + break; +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ + default: + *p_ReplyLength = 0; + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); + } + return E_OK; +} + + +/****************************************/ +/* Inter-Module functions */ +/****************************************/ +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err = E_OK; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + uint8_t rxHardwarePortId, txHardwarePortId; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_10G_TX_ECC_WA; + msg.msgBody[0] = macId; + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(macId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } + + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED); + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE); + + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G, + macId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G, + macId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) || + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, + ("MAC should be initialized prior to Rx and Tx ports!")); + + return fman_set_erratum_10gmac_a004_wa(fpm_rg); +} +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ + +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0); + + return p_Fm->tnumAgingPeriod; +} + +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, + uint8_t portNum, + bool preFetchConfigured) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + p_Fm->portsPreFetchConfigured[portNum] = TRUE; + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured; + + return E_OK; +} + +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, + uint8_t portNum, + bool *p_PortConfigured, + bool *p_PreFetchConfigured) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + /* If the prefetch wasn't configured yet (not enable or disabled) + we return the value TRUE as it was already configured */ + if (!p_Fm->portsPreFetchConfigured[portNum]) + { + *p_PortConfigured = FALSE; + *p_PreFetchConfigured = FALSE; + } + else + { + *p_PortConfigured = TRUE; + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]); + } + + return E_OK; +} + +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm, + uint32_t congestionGroupId, + uint8_t priorityBitMap) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + uint32_t regNum; + + ASSERT_COND(h_Fm); + + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("Congestion group ID bigger than %d", + FM_PORT_NUM_OF_CONGESTION_GRPS)); + + if (p_Fm->guestId == NCSW_MASTER_ID) + { + ASSERT_COND(p_Fm->baseAddr); + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4; + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)), + congestionGroupId, + priorityBitMap, + regNum); + } + else if (p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority; + + memset(&msg, 0, sizeof(msg)); + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId; + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap; + + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO; + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); + + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + } + else + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!")); + + return E_OK; +} + +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + + if (!p_Fm->baseAddr) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, + ("No base-addr; probably Guest with IPC!")); + return 0; + } + + return (p_Fm->baseAddr + FM_MM_PRS); +} + +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + + if (!p_Fm->baseAddr) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, + ("No base-addr; probably Guest with IPC!")); + return 0; + } + + return (p_Fm->baseAddr + FM_MM_KG); +} + +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + + if (!p_Fm->baseAddr) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, + ("No base-addr; probably Guest with IPC!")); + return 0; + } + + return (p_Fm->baseAddr + FM_MM_PLCR); +} + +#if (DPAA_VERSION >= 11) +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + + return p_Fm->vspBaseAddr; +} +#endif /* (DPAA_VERSION >= 11) */ + +t_Handle FmGetMuramHandle(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL); + + return (p_Fm->h_FmMuram); +} + +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + if (p_Fm->fmMuramPhysBaseAddr) + { + /* General FM driver initialization */ + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr; + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32); + return; + } + + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID); + + if (p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + t_FmIpcPhysAddr ipcPhysAddr; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_PHYS_MURAM_BASE; + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + { + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr))) + { + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch")); + return; + } + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr)); + p_FmPhysAddr->high = ipcPhysAddr.high; + p_FmPhysAddr->low = ipcPhysAddr.low; + } + else + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); +} + +#if (DPAA_VERSION >= 11) +t_Error FmVSPAllocForPort (t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint8_t numOfVSPs) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_Error err = E_OK; + uint32_t profilesFound, intFlags; + uint8_t first, i; + uint8_t log2Num; + uint8_t swPortIndex=0, hardwarePortId; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + if (!numOfVSPs) + return E_OK; + + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES) + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES)); + + if (!POWER_OF_2(numOfVSPs)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); + + LOG2((uint64_t)numOfVSPs, log2Num); + + if ((log2Num == 0) || (p_Fm->partVSPBase == 0)) + first = 0; + else + first = 1< (p_Fm->partVSPBase + p_Fm->partNumOfVSPs)) + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window")); + + if (first < p_Fm->partVSPBase) + while (first < p_Fm->partVSPBase) + first = first + numOfVSPs; + + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs)) + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window")); + + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); + profilesFound = 0; + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; ) + { + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated) + { + profilesFound++; + i++; + if (profilesFound == numOfVSPs) + break; + } + else + { + profilesFound = 0; + /* advance i to the next aligned address */ + first = i = (uint8_t)(first + numOfVSPs); + } + } + if (profilesFound == numOfVSPs) + for (i = first; ip_FmSp->profiles[i].profilesMng.allocated = TRUE; + else + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); + } + + hardwarePortId = SwPortIdToHwPortId(portType, + portId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs; + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first; + + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK) + for (i = first; i < first + numOfVSPs; i++) + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE; + + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + + return err; +} + +t_Error FmVSPFreeForPort(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i; + uint32_t intFlags; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + hardwarePortId = SwPortIdToHwPortId(portType, + portId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles; + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase; + + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); + for (i = first; i < first + numOfVSPs; i++) + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE; + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0; + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0; + + return E_OK; +} +#endif /* (DPAA_VERSION >= 11) */ + +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint8_t i; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG; + replyLength = sizeof(uint32_t) + sizeof(uint8_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + + *p_EventId = *(uint8_t*)(reply.replyBody); + + return (t_Error)(reply.error); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + + for (i=0;iusedEventRegs[i]) + { + p_Fm->usedEventRegs[i] = TRUE; + *p_EventId = i; + break; + } + + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS) + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register.")); + + return E_OK; +} + +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG; + msg.msgBody[0] = eventId; + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(eventId), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + return; + } + + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE; +} + +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->p_FmFpmRegs && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcFmanEvents fmanCtrl; + t_Error err; + t_FmIpcMsg msg; + + fmanCtrl.eventRegId = eventRegId; + fmanCtrl.enableEvents = enableEvents; + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE; + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(fmanCtrl), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + else if (!p_Fm->p_FmFpmRegs) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + return; + } + + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS); + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents); +} + +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->p_FmFpmRegs && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength, ctrlIntr; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE; + msg.msgBody[0] = eventRegId; + replyLength = sizeof(uint32_t) + sizeof(uint32_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(eventRegId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + { + REPORT_ERROR(MINOR, err, NO_MSG); + return 0; + } + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) + { + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return 0; + } + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t)); + return ctrlIntr; + } + else if (!p_Fm->p_FmFpmRegs) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + return 0; + } + + return fman_get_ctrl_intr(fpm_rg, eventRegId); +} + +void FmRegisterIntr(t_Handle h_Fm, + e_FmEventModules module, + uint8_t modId, + e_FmIntrType intrType, + void (*f_Isr) (t_Handle h_Arg), + t_Handle h_Arg) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + int event = 0; + + ASSERT_COND(h_Fm); + + GET_FM_MODULE_EVENT(module, modId, intrType, event); + ASSERT_COND(event < e_FM_EV_DUMMY_LAST); + + /* register in local FM structure */ + p_Fm->intrMng[event].f_Isr = f_Isr; + p_Fm->intrMng[event].h_SrcHandle = h_Arg; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcRegisterIntr fmIpcRegisterIntr; + t_Error err; + t_FmIpcMsg msg; + + /* register in Master FM structure */ + fmIpcRegisterIntr.event = (uint32_t)event; + fmIpcRegisterIntr.guestId = p_Fm->guestId; + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_REGISTER_INTR; + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); +} + +void FmUnregisterIntr(t_Handle h_Fm, + e_FmEventModules module, + uint8_t modId, + e_FmIntrType intrType) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + int event = 0; + + ASSERT_COND(h_Fm); + + GET_FM_MODULE_EVENT(module, modId,intrType, event); + ASSERT_COND(event < e_FM_EV_DUMMY_LAST); + + p_Fm->intrMng[event].f_Isr = UnimplementedIsr; + p_Fm->intrMng[event].h_SrcHandle = NULL; +} + +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) + { + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode")); + return; + } + + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr; + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg; +} + +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) + { + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode")); + return; + } + + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr; + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL; +} + +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + if (p_Fm->h_Pcd) + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set")); + + p_Fm->h_Pcd = h_FmPcd; +} + +void FmUnregisterPcd(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + if (!p_Fm->h_Pcd) + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!")); + + p_Fm->h_Pcd = NULL; +} + +t_Handle FmGetPcdHandle(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + return p_Fm->h_Pcd; +} + +uint8_t FmGetId(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff); + + return p_Fm->p_FmStateStruct->fmId; +} + +t_Error FmReset(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); + CORE_MemoryBarrier(); + XX_UDelay(100); + + return E_OK; +} + +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, + uint8_t hardwarePortId, + uint8_t numOfFmanCtrls, + t_FmFmanCtrl orFmanCtrl) +{ + + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE); + + fpm_rg = p_Fm->p_FmFpmRegs; + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->p_FmFpmRegs && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcPortNumOfFmanCtrls params; + t_FmIpcMsg msg; + + memset(&msg, 0, sizeof(msg)); + params.hardwarePortId = hardwarePortId; + params.numOfFmanCtrls = numOfFmanCtrls; + params.orFmanCtrl = orFmanCtrl; + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL; + memcpy(msg.msgBody, ¶ms, sizeof(params)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) +sizeof(params), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return E_OK; + } + else if (!p_Fm->p_FmFpmRegs) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl); + + return E_OK; +} + +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err; + uint32_t intFlags; + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId; + struct fman_rg fman_rg; + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { + t_FmIpcPortInInitParams portInParams; + t_FmIpcPortOutInitParams portOutParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + portInParams.hardwarePortId = p_PortParams->hardwarePortId; + portInParams.enumPortType = (uint32_t)p_PortParams->portType; + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode; + portInParams.liodnOffset = p_PortParams->liodnOffset; + portInParams.numOfTasks = p_PortParams->numOfTasks; + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks; + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas; + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas; + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo; + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo; + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; + portInParams.maxFrameLength = p_PortParams->maxFrameLength; + portInParams.liodnBase = p_PortParams->liodnBase; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_SET_PORT_PARAMS; + memcpy(msg.msgBody, &portInParams, sizeof(portInParams)); + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) +sizeof(portInParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams)); + + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high; + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low; + p_PortParams->numOfTasks = portOutParams.numOfTasks; + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks; + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas; + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas; + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo; + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo; + + return (t_Error)(reply.error); + } + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); + if (p_PortParams->independentMode) + { + /* set port parameters */ + p_Fm->independentMode = p_PortParams->independentMode; + /* disable dispatch limit */ + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg); + } + + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) + { + if (p_Fm->hcPortInitialized) + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed.")); + } + else + p_Fm->hcPortInitialized = TRUE; + } + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType; + + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE); + if (err) + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) && + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) + /* for transmit & O/H ports */ + { + uint8_t enqTh; + uint8_t deqTh; + + /* update qmi ENQ/DEQ threshold */ + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth; + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg); + /* if enqTh is too big, we reduce it to the max value that is still OK */ + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums)) + { + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh); + } + + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg); + /* if deqTh is too small, we enlarge it to the min value that is still OK. + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */ + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1)) + { + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh); + } + } + +#ifdef FM_LOW_END_RESTRICTION + if ((hardwarePortId==0x1) || (hardwarePortId==0x29)) + { + if (p_Fm->p_FmStateStruct->lowEndRestriction) + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1.")); + } + else + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE; + } +#endif /* FM_LOW_END_RESTRICTION */ + + err = FmSetSizeOfFifo(p_Fm, + hardwarePortId, + &p_PortParams->sizeOfFifo, + &p_PortParams->extraSizeOfFifo, + TRUE); + if (err) + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + err = FmSetNumOfOpenDmas(p_Fm, + hardwarePortId, + &p_PortParams->numOfOpenDmas, + &p_PortParams->numOfExtraOpenDmas, + TRUE); + if (err) + { + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + fman_set_liodn_per_port(&fman_rg, + hardwarePortId, + p_PortParams->liodnBase, + p_PortParams->liodnOffset); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) + fman_set_order_restoration_per_port(fman_rg.fpm_rg, + hardwarePortId, + p_PortParams->independentMode, + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G))); + + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); + +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) || + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G)) + { + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS); + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId]) + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength; + else + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU")); + } + else +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) || + (p_PortParams->portType == e_FM_PORT_TYPE_RX)) + { + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS); + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId]) + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength; + else + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU")); + } + + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr); + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); + + return E_OK; +} + +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t intFlags; + uint8_t hardwarePortId = p_PortParams->hardwarePortId; + uint8_t numOfTasks, numOfDmas, macId; + uint16_t sizeOfFifo; + t_Error err; + t_FmIpcPortFreeParams portParams; + t_FmIpcMsg msg; + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { + portParams.hardwarePortId = p_PortParams->hardwarePortId; + portParams.enumPortType = (uint32_t)p_PortParams->portType; + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_FREE_PORT; + memcpy(msg.msgBody, &portParams, sizeof(portParams)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(portParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); + + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) + { + ASSERT_COND(p_Fm->hcPortInitialized); + p_Fm->hcPortInitialized = FALSE; + } + + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY; + + /* free numOfTasks */ + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId); + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks); + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks; + + /* free numOfOpenDmas */ + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId); + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas); + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas; + +#ifdef FM_HAS_TOTAL_DMAS + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) + { + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */ + fman_set_num_of_open_dmas(bmi_rg, + hardwarePortId, + 1, + 0, + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize)); + } +#endif /* FM_HAS_TOTAL_DMAS */ + + /* free sizeOfFifo */ + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId); + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS)); + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS); + +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) && + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) + /* for transmit & O/H ports */ + { + uint8_t enqTh; + uint8_t deqTh; + + /* update qmi ENQ/DEQ threshold */ + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth; + + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, + so we can enlarge enqTh */ + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); + + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, + so we can reduce deqTh */ + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); + + fman_set_qmi_enq_th(qmi_rg, enqTh); + fman_set_qmi_deq_th(qmi_rg, deqTh); + } + + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); + +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) || + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G)) + { + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS); + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0; + } + else +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) || + (p_PortParams->portType == e_FM_PORT_TYPE_RX)) + { + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS); + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0; + } + +#ifdef FM_LOW_END_RESTRICTION + if ((hardwarePortId==0x1) || (hardwarePortId==0x29)) + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE; +#endif /* FM_LOW_END_RESTRICTION */ + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); +} + +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_IS_PORT_STALLED; + msg.msgBody[0] = hardwarePortId; + replyLength = sizeof(uint32_t) + sizeof(uint8_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(hardwarePortId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody)); + + return (t_Error)(reply.error); + } + else if (!p_Fm->baseAddr) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId); + + return E_OK; +} + +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err; + bool isStalled; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_RESUME_STALLED_PORT; + msg.msgBody[0] = hardwarePortId; + replyLength = sizeof(uint32_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(hardwarePortId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } + else if (!p_Fm->baseAddr) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!")); + + /* Get port status */ + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled); + if (err) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status")); + if (!isStalled) + return E_OK; + + fman_resume_stalled_port(fpm_rg, hardwarePortId); + + return E_OK; +} + +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err; + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; + +#if (DPAA_VERSION >= 11) + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("FMan MAC reset!")); +#endif /*(DPAA_VERSION >= 11)*/ + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcMacParams macParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + macParams.id = macId; + macParams.enumType = (uint32_t)type; + msg.msgId = FM_RESET_MAC; + memcpy(msg.msgBody, &macParams, sizeof(macParams)); + replyLength = sizeof(uint32_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(macParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } + else if (!p_Fm->baseAddr) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G)); + + if (err == -EBUSY) + return ERROR_CODE(E_TIMEOUT); + else if (err) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID")); + + return E_OK; +} + +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams; + t_Error err; + t_FmIpcMsg msg; + + memset(&msg, 0, sizeof(msg)); + macMaxFrameLengthParams.macParams.id = macId; + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type; + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu; + msg.msgId = FM_SET_MAC_MAX_FRAME; + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams)); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return E_OK; + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + + /* if port is already initialized, check that MaxFrameLength is smaller + * or equal to the port's max */ +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)) + if (type == e_FM_MAC_10G) + { + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId]) + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] && + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId]))) + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu; + else + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength")); + + } + else +#else + UNUSED(type); +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */ + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId]) + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] && + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId]))) + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu; + else + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength")); + + return E_OK; +} + +uint16_t FmGetClockFreq(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + /* for multicore environment: this depends on the + * fact that fmClkFreq was properly initialized at "init". */ + return p_Fm->p_FmStateStruct->fmClkFreq; +} + +uint16_t FmGetMacClockFreq(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + return p_Fm->p_FmStateStruct->fmMacClkFreq; +} + +uint32_t FmGetTimeStampScale(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength, timeStamp; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_TIMESTAMP_SCALE; + replyLength = sizeof(uint32_t) + sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + return 0; + } + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return 0; + } + + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t)); + return timeStamp; + } + else if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->baseAddr) + { + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN)) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!")); + return 0; + } + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled.")); + + return p_Fm->p_FmStateStruct->count1MicroBit; +} + +t_Error FmEnableRamsEcc(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + p_Fm->p_FmStateStruct->ramsEccOwners++; + p_Fm->p_FmStateStruct->internalCall = TRUE; + + return FM_EnableRamsEcc(p_Fm); +} + +t_Error FmDisableRamsEcc(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners); + p_Fm->p_FmStateStruct->ramsEccOwners--; + + if (p_Fm->p_FmStateStruct->ramsEccOwners==0) + { + p_Fm->p_FmStateStruct->internalCall = TRUE; + return FM_DisableRamsEcc(p_Fm); + } + + return E_OK; +} + +uint8_t FmGetGuestId(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + return p_Fm->guestId; +} + +bool FmIsMaster(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + return (p_Fm->guestId == NCSW_MASTER_ID); +} + +t_Error FmSetSizeOfFifo(t_Handle h_Fm, + uint8_t hardwarePortId, + uint32_t *p_SizeOfFifo, + uint32_t *p_ExtraSizeOfFifo, + bool initialConfig) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_FmIpcPortRsrcParams rsrcParams; + t_Error err; + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo; + uint16_t currentVal = 0, currentExtraVal = 0; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + rsrcParams.hardwarePortId = hardwarePortId; + rsrcParams.val = sizeOfFifo; + rsrcParams.extra = extraSizeOfFifo; + rsrcParams.boolInitialConfig = (uint8_t)initialConfig; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_SET_SIZE_OF_FIFO; + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(rsrcParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } + else if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->baseAddr) + { + DBG(WARNING, ("No IPC - can't validate FM total-fifo size.")); + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); + + if (!initialConfig) + { + /* !initialConfig - runtime change of existing value. + * - read the current FIFO and extra FIFO size */ + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId); + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId); + } + + if (extraSizeOfFifo > currentExtraVal) + { + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize) + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize + * must be initialized to 1 buffer per port + */ + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS; + + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo); + } + + /* check that there are enough uncommitted fifo size */ + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) > + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){ + REPORT_ERROR(MAJOR, E_INVALID_VALUE, + ("Port request fifo size + accumulated size > total FIFO size:")); + RETURN_ERROR(MAJOR, E_INVALID_VALUE, + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d", + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize, + p_Fm->p_FmStateStruct->accumulatedFifoSize, + p_Fm->p_FmStateStruct->totalFifoSize)); + } + else + { + /* update accumulated */ + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal); + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal; + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo; + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo); + } + + return E_OK; +} + +t_Error FmSetNumOfTasks(t_Handle h_Fm, + uint8_t hardwarePortId, + uint8_t *p_NumOfTasks, + uint8_t *p_NumOfExtraTasks, + bool initialConfig) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_Error err; + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks; + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcPortRsrcParams rsrcParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + rsrcParams.hardwarePortId = hardwarePortId; + rsrcParams.val = numOfTasks; + rsrcParams.extra = numOfExtraTasks; + rsrcParams.boolInitialConfig = (uint8_t)initialConfig; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_SET_NUM_OF_TASKS; + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(rsrcParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } + else if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->baseAddr) + { + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks.")); + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); + + if (!initialConfig) + { + /* !initialConfig - runtime change of existing value. + * - read the current number of tasks */ + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId); + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId); + } + + if (numOfExtraTasks > currentExtraVal) + p_Fm->p_FmStateStruct->extraTasksPoolSize = + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks); + + /* check that there are enough uncommitted tasks */ + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) > + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize)) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.", + p_Fm->p_FmStateStruct->fmId)); + else + { + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal); + /* update accumulated */ + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal; + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks; + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks); + } + + return E_OK; +} + +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm, + uint8_t hardwarePortId, + uint8_t *p_NumOfOpenDmas, + uint8_t *p_NumOfExtraOpenDmas, + bool initialConfig) + +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_Error err; + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas; + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0; + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcPortRsrcParams rsrcParams; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + rsrcParams.hardwarePortId = hardwarePortId; + rsrcParams.val = numOfOpenDmas; + rsrcParams.extra = numOfExtraOpenDmas; + rsrcParams.boolInitialConfig = (uint8_t)initialConfig; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS; + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); + replyLength = sizeof(uint32_t); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) + sizeof(rsrcParams), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != sizeof(uint32_t)) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return (t_Error)(reply.error); + } +#ifdef FM_HAS_TOTAL_DMAS + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!")); +#else + else if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->baseAddr && + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) + { + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/ + + if (!numOfOpenDmas) + { + /* first config without explic it value: Do Nothing - reset value shouldn't be + changed, read register for port save */ + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId); + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); + } + else + /* whether it is the first time with explicit value, or runtime "set" - write register */ + fman_set_num_of_open_dmas(bmi_rg, + hardwarePortId, + numOfOpenDmas, + numOfExtraOpenDmas, + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, + ("running in guest-mode without neither IPC nor mapped register!")); +#endif /* FM_HAS_TOTAL_DMAS */ + + if (!initialConfig) + { + /* !initialConfig - runtime change of existing value. + * - read the current number of open Dma's */ + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId); + } + +#ifdef FM_NO_GUARANTEED_RESET_VALUES + /* it's illegal to be in a state where this is not the first set and no value is specified */ + ASSERT_COND(initialConfig || numOfOpenDmas); + if (!numOfOpenDmas) + { + /* !numOfOpenDmas - first configuration according to values in regs. + * - read the current number of open Dma's */ + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId); + /* This is the first configuration and user did not specify value (!numOfOpenDmas), + * reset values will be used and we just save these values for resource management */ + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal); + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal; + *p_NumOfOpenDmas = currentVal; + *p_NumOfExtraOpenDmas = currentExtraVal; + return E_OK; + } +#endif /* FM_NO_GUARANTEED_RESET_VALUES */ + + if (numOfExtraOpenDmas > currentExtraVal) + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas); + +#ifdef FM_HAS_TOTAL_DMAS + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) && + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > + p_Fm->p_FmStateStruct->maxNumOfOpenDmas)) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.", + p_Fm->p_FmStateStruct->fmId)); +#else + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) && +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) && + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) && +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */ + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1)) + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)", + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1)); +#endif /* FM_HAS_TOTAL_DMAS */ + else + { + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal); + /* update acummulated */ + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal; + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas; + +#ifdef FM_HAS_TOTAL_DMAS + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize); +#endif /* FM_HAS_TOTAL_DMAS */ + fman_set_num_of_open_dmas(bmi_rg, + hardwarePortId, + numOfOpenDmas, + numOfExtraOpenDmas, + totalNumDmas); + } + + return E_OK; +} + +#if (DPAA_VERSION >= 11) +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint16_t relativeProfile) +{ + t_Fm *p_Fm; + t_FmSp *p_FmPcdSp; + uint8_t swPortIndex=0, hardwarePortId; + + ASSERT_COND(h_Fm); + p_Fm = (t_Fm*)h_Fm; + + hardwarePortId = SwPortIdToHwPortId(portType, + portId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + ASSERT_COND(hardwarePortId); + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + p_FmPcdSp = p_Fm->p_FmSp; + ASSERT_COND(p_FmPcdSp); + + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles) + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles")); + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles) + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range")); + + return E_OK; +} + +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint16_t relativeProfile, + uint16_t *p_AbsoluteId) +{ + t_Fm *p_Fm; + t_FmSp *p_FmPcdSp; + uint8_t swPortIndex=0, hardwarePortId; + t_Error err; + + ASSERT_COND(h_Fm); + p_Fm = (t_Fm*)h_Fm; + + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile); + if (err != E_OK) + return err; + + hardwarePortId = SwPortIdToHwPortId(portType, + portId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + ASSERT_COND(hardwarePortId); + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); + + p_FmPcdSp = p_Fm->p_FmSp; + ASSERT_COND(p_FmPcdSp); + + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile); + + return E_OK; +} +#endif /* (DPAA_VERSION >= 11) */ + +static t_Error InitFmDma(t_Fm *p_Fm) +{ + t_Error err; + + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam); + if (err != E_OK) + return err; + + /* Allocate MURAM for CAM */ + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY), + DMA_CAM_ALIGN)); + if (!p_Fm->camBaseAddr) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed")); + + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), + 0, + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY)); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2) + { + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr)); + + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128), + 64)); + if (!p_Fm->camBaseAddr) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed")); + + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), + 0, + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128)); + + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries) + { + case (8): + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000); + break; + case (16): + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000); + break; + case (24): + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00); + break; + case (32): + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff); + break; + default: + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries")); + } + } + + p_Fm->p_FmDriverParam->cam_base_addr = + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); + + return E_OK; +} + +static t_Error InitFmFpm(t_Fm *p_Fm) +{ + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam); +} + +static t_Error InitFmBmi(t_Fm *p_Fm) +{ + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam); +} + +static t_Error InitFmQmi(t_Fm *p_Fm) +{ + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam); +} + +static t_Error InitGuestMode(t_Fm *p_Fm) +{ + t_Error err = E_OK; + int i; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + + ASSERT_COND(p_Fm); + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID); + + /* build the FM guest partition IPC address */ + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); + + /* build the FM master partition IPC address */ + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); + + for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; + + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName); + if (p_Fm->h_IpcSessions[0]) + { + uint8_t isMasterAlive; + t_FmIpcParams ipcParams; + + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); + if (err) + RETURN_ERROR(MAJOR, err, NO_MSG); + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_MASTER_IS_ALIVE; + msg.msgBody[0] = p_Fm->guestId; + replyLength = sizeof(uint32_t) + sizeof(uint8_t); + do + { + blockingFlag = TRUE; + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId)+sizeof(p_Fm->guestId), + (uint8_t*)&reply, + &replyLength, + IpcMsgCompletionCB, + p_Fm)) != E_OK) + REPORT_ERROR(MINOR, err, NO_MSG); + while (blockingFlag) ; + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + isMasterAlive = *(uint8_t*)(reply.replyBody); + } while (!isMasterAlive); + + /* read FM parameters and save */ + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_PARAMS; + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams)); + + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq; + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq; + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev; + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev; + } + else + { + DBG(WARNING, ("FM Guest mode - without IPC")); + if (!p_Fm->p_FmStateStruct->fmClkFreq) + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC")); + if (p_Fm->baseAddr) + { + fman_get_revision(p_Fm->p_FmFpmRegs, + &p_Fm->p_FmStateStruct->revInfo.majorRev, + &p_Fm->p_FmStateStruct->revInfo.minorRev); + + } + } + +#if (DPAA_VERSION >= 11) + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) + DBG(WARNING, ("partition VSPs allocation is FAILED")); +#endif /* (DPAA_VERSION >= 11) */ + + /* General FM driver initialization */ + if (p_Fm->baseAddr) + p_Fm->fmMuramPhysBaseAddr = + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM))); + + XX_Free(p_Fm->p_FmDriverParam); + p_Fm->p_FmDriverParam = NULL; + + if ((p_Fm->guestId == NCSW_MASTER_ID) || + (p_Fm->h_IpcSessions[0])) + { + FM_DisableRamsEcc(p_Fm); + FmMuramClear(p_Fm->h_FmMuram); + FM_EnableRamsEcc(p_Fm); + } + + return E_OK; +} + +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception) +{ + switch (exception) { + case e_FM_EX_DMA_BUS_ERROR: + return E_FMAN_EX_DMA_BUS_ERROR; + case e_FM_EX_DMA_READ_ECC: + return E_FMAN_EX_DMA_READ_ECC; + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC; + case e_FM_EX_DMA_FM_WRITE_ECC: + return E_FMAN_EX_DMA_FM_WRITE_ECC; + case e_FM_EX_FPM_STALL_ON_TASKS: + return E_FMAN_EX_FPM_STALL_ON_TASKS; + case e_FM_EX_FPM_SINGLE_ECC: + return E_FMAN_EX_FPM_SINGLE_ECC; + case e_FM_EX_FPM_DOUBLE_ECC: + return E_FMAN_EX_FPM_DOUBLE_ECC; + case e_FM_EX_QMI_SINGLE_ECC: + return E_FMAN_EX_QMI_SINGLE_ECC; + case e_FM_EX_QMI_DOUBLE_ECC: + return E_FMAN_EX_QMI_DOUBLE_ECC; + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; + case e_FM_EX_BMI_LIST_RAM_ECC: + return E_FMAN_EX_BMI_LIST_RAM_ECC; + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC; + case e_FM_EX_BMI_STATISTICS_RAM_ECC: + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC; + case e_FM_EX_BMI_DISPATCH_RAM_ECC: + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC; + case e_FM_EX_IRAM_ECC: + return E_FMAN_EX_IRAM_ECC; + case e_FM_EX_MURAM_ECC: + return E_FMAN_EX_MURAM_ECC; + default: + return E_FMAN_EX_DMA_BUS_ERROR; + } +} + +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev) +{ + switch (type) + { + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): + case (e_FM_PORT_TYPE_OH_HOST_COMMAND): + CHECK_PORT_ID_OH_PORTS(relativePortId); + return (uint8_t)(BASE_OH_PORTID + (relativePortId)); + case (e_FM_PORT_TYPE_RX): + CHECK_PORT_ID_1G_RX_PORTS(relativePortId); + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId)); + case (e_FM_PORT_TYPE_RX_10G): + /* The 10G port in T1024 (FMan Version 6.4) is the first port. + * This is the reason why the 1G port offset is used. + */ + if (majorRev == 6 && minorRev == 4) + { + CHECK_PORT_ID_1G_RX_PORTS(relativePortId); + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId)); + } + else + { + CHECK_PORT_ID_10G_RX_PORTS(relativePortId); + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId)); + } + case (e_FM_PORT_TYPE_TX): + CHECK_PORT_ID_1G_TX_PORTS(relativePortId); + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId)); + case (e_FM_PORT_TYPE_TX_10G): + /* The 10G port in T1024 (FMan Version 6.4) is the first port. + * This is the reason why the 1G port offset is used. + */ + if (majorRev == 6 && minorRev == 4) + { + CHECK_PORT_ID_1G_TX_PORTS(relativePortId); + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId)); + } + else + { + CHECK_PORT_ID_10G_TX_PORTS(relativePortId); + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId)); + } + default: + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); + return 0; + } +} + +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + + DECLARE_DUMP; + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) || + p_Fm->baseAddr), E_INVALID_OPERATION); + + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId))); + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t)); + + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId ))); + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t)); + + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId))); + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t)); + + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId))); + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t)); + + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId))); + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t)); + + return E_OK; +} +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ + + +/*****************************************************************************/ +/* API Init unit functions */ +/*****************************************************************************/ +t_Handle FM_Config(t_FmParams *p_FmParam) +{ + t_Fm *p_Fm; + uint8_t i; + uintptr_t baseAddr; + + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL); + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) || + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)), + E_INVALID_VALUE, NULL); + + baseAddr = p_FmParam->baseAddr; + + /* Allocate FM structure */ + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm)); + if (!p_Fm) + { + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure")); + return NULL; + } + memset(p_Fm, 0, sizeof(t_Fm)); + + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct)); + if (!p_Fm->p_FmStateStruct) + { + XX_Free(p_Fm); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure")); + return NULL; + } + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct)); + + /* Initialize FM parameters which will be kept by the driver */ + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; + p_Fm->guestId = p_FmParam->guestId; + + for (i=0; ip_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY; + + /* Allocate the FM driver's parameters structure */ + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg)); + if (!p_Fm->p_FmDriverParam) + { + XX_Free(p_Fm->p_FmStateStruct); + XX_Free(p_Fm); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters")); + return NULL; + } + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg)); + +#if (DPAA_VERSION >= 11) + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp)); + if (!p_Fm->p_FmSp) + { + XX_Free(p_Fm->p_FmDriverParam); + XX_Free(p_Fm->p_FmStateStruct); + XX_Free(p_Fm); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed")); + return NULL; + } + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp)); + + for (i=0; ip_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; +#endif /* (DPAA_VERSION >= 11) */ + + /* Initialize FM parameters which will be kept by the driver */ + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; + p_Fm->h_FmMuram = p_FmParam->h_FmMuram; + p_Fm->h_App = p_FmParam->h_App; + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq; + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio); + p_Fm->f_Exception = p_FmParam->f_Exception; + p_Fm->f_BusError = p_FmParam->f_BusError; + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM); + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI); + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA); + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); + p_Fm->baseAddr = baseAddr; + p_Fm->p_FmStateStruct->irq = p_FmParam->irq; + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq; + p_Fm->hcPortInitialized = FALSE; + p_Fm->independentMode = FALSE; + + p_Fm->h_Spinlock = XX_InitSpinlock(); + if (!p_Fm->h_Spinlock) + { + XX_Free(p_Fm->p_FmDriverParam); + XX_Free(p_Fm->p_FmStateStruct); + XX_Free(p_Fm); + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!")); + return NULL; + } + +#if (DPAA_VERSION >= 11) + p_Fm->partVSPBase = p_FmParam->partVSPBase; + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs; + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr; +#endif /* (DPAA_VERSION >= 11) */ + + fman_defconfig(p_Fm->p_FmDriverParam, + !!(p_Fm->guestId == NCSW_MASTER_ID)); +/* overide macros dependent parameters */ +#ifdef FM_PEDANTIC_DMA + p_Fm->p_FmDriverParam->pedantic_dma = TRUE; + p_Fm->p_FmDriverParam->dma_aid_override = TRUE; +#endif /* FM_PEDANTIC_DMA */ +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE; +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0; + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions; + p_Fm->resetOnInit = DEFAULT_resetOnInit; + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback; + p_Fm->fwVerify = DEFAULT_VerifyUcode; + p_Fm->firmware.size = p_FmParam->firmware.size; + if (p_Fm->firmware.size) + { + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size); + if (!p_Fm->firmware.p_Code) + { + XX_FreeSpinlock(p_Fm->h_Spinlock); + XX_Free(p_Fm->p_FmStateStruct); + XX_Free(p_Fm->p_FmDriverParam); + XX_Free(p_Fm); + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code")); + return NULL; + } + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size); + } + + if (p_Fm->guestId != NCSW_MASTER_ID) + return p_Fm; + + /* read revision */ + /* Chip dependent, will be configured in Init */ + fman_get_revision(p_Fm->p_FmFpmRegs, + &p_Fm->p_FmStateStruct->revInfo.majorRev, + &p_Fm->p_FmStateStruct->revInfo.minorRev); + +#ifdef FM_AID_MODE_NO_TNUM_SW005 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID; +#endif /* FM_AID_MODE_NO_TNUM_SW005 */ +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH; +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ + + p_Fm->p_FmStateStruct->totalFifoSize = 0; + p_Fm->p_FmStateStruct->totalNumOfTasks = + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + +#ifdef FM_HAS_TOTAL_DMAS + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS; +#endif /* FM_HAS_TOTAL_DMAS */ +#if (DPAA_VERSION < 11) + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow; + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh; + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries; + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow; + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh; + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow; + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh; + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats; +#endif /* (DPAA_VERSION < 11) */ +#ifdef FM_NO_TNUM_AGING + p_Fm->p_FmDriverParam->tnum_aging_period = 0; +#endif + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period; + + return p_Fm; +} + +/**************************************************************************//** + @Function FM_Init + + @Description Initializes the FM module + + @Param[in] h_Fm - FM module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_Init(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_cfg *p_FmDriverParam = NULL; + t_Error err = E_OK; + int i; + t_FmRevisionInfo revInfo; + struct fman_rg fman_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT; + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS; + + if (p_Fm->guestId != NCSW_MASTER_ID) + return InitGuestMode(p_Fm); + + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default + * according to chip. otherwise, we use user's configuration. + */ + if (p_Fm->p_FmStateStruct->totalFifoSize == 0) + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters); + + p_FmDriverParam = p_Fm->p_FmDriverParam; + + FM_GetRevision(p_Fm, &revInfo); + + /* clear revision-dependent non existing exception */ +#ifdef FM_NO_DISPATCH_RAM_ECC + if ((revInfo.majorRev != 4) && + (revInfo.majorRev < 6)) + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC; +#endif /* FM_NO_DISPATCH_RAM_ECC */ + +#ifdef FM_QMI_NO_ECC_EXCEPTIONS + if (revInfo.majorRev == 4) + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC); +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ + +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION + if (revInfo.majorRev >= 6) + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC; +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */ + + FmMuramClear(p_Fm->h_FmMuram); + + /* clear CPG */ + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS); + + /* add to the default exceptions the user's definitions */ + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions; + + /* Reset the FM if required */ + if (p_Fm->resetOnInit) + { +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK) + RETURN_ERROR(MAJOR, err, NO_MSG); +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ + + if (p_Fm->f_ResetOnInitOverride) + { + /* Perform user specific FMan reset */ + p_Fm->f_ResetOnInitOverride(h_Fm); + } + else + { + /* Perform FMan reset */ + FmReset(h_Fm); + } + + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs)) + { + fman_resume(p_Fm->p_FmFpmRegs); + XX_UDelay(100); + } +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ + } + +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */ + { +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ + /* Load FMan-Controller code to IRAM */ + + ClearIRam(p_Fm); + + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK)) + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 + } +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ + +#ifdef FM_CAPWAP_SUPPORT + /* save first 256 byte in MURAM */ + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0)); + if (!p_Fm->resAddr) + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed")); + + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256); +#endif /* FM_CAPWAP_SUPPORT */ + +#if (DPAA_VERSION >= 11) + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) + DBG(WARNING, ("partition VSPs allocation is FAILED")); +#endif /* (DPAA_VERSION >= 11) */ + + /* General FM driver initialization */ + p_Fm->fmMuramPhysBaseAddr = + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM))); + + for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; + for (i=0;ifmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr; + + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions; + + /**********************/ + /* Init DMA Registers */ + /**********************/ + err = InitFmDma(p_Fm); + if (err != E_OK) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /**********************/ + /* Init FPM Registers */ + /**********************/ + err = InitFmFpm(p_Fm); + if (err != E_OK) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /* define common resources */ + /* allocate MURAM for FIFO according to total size */ + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, + p_Fm->p_FmStateStruct->totalFifoSize, + BMI_FIFO_ALIGN)); + if (!p_Fm->fifoBaseAddr) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed")); + } + + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize; + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks; + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq; + + /**********************/ + /* Init BMI Registers */ + /**********************/ + err = InitFmBmi(p_Fm); + if (err != E_OK) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /**********************/ + /* Init QMI Registers */ + /**********************/ + err = InitFmQmi(p_Fm); + if (err != E_OK) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /* build the FM master partition IPC address */ + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); + } + + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); + if (err) + { + FreeInitResources(p_Fm); + RETURN_ERROR(MAJOR, err, NO_MSG); + } + + /* Register the FM interrupts handlers */ + if (p_Fm->p_FmStateStruct->irq != NO_IRQ) + { + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm); + XX_EnableIntr(p_Fm->p_FmStateStruct->irq); + } + + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) + { + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm); + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq); + } + + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam); + if (err != E_OK) + return err; /* FIXME */ + + EnableTimeStamp(p_Fm); + + if (p_Fm->firmware.p_Code) + { + XX_Free(p_Fm->firmware.p_Code); + p_Fm->firmware.p_Code = NULL; + } + + XX_Free(p_Fm->p_FmDriverParam); + p_Fm->p_FmDriverParam = NULL; + + return E_OK; +} + +/**************************************************************************//** + @Function FM_Free + + @Description Frees all resources that were assigned to FM module. + + Calling this routine invalidates the descriptor. + + @Param[in] h_Fm - FM module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_Free(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_rg fman_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { +#if (DPAA_VERSION >= 11) + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); + + if (p_Fm->p_FmSp) + { + XX_Free(p_Fm->p_FmSp); + p_Fm->p_FmSp = NULL; + } +#endif /* (DPAA_VERSION >= 11) */ + + if (p_Fm->fmModuleName[0] != 0) + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); + + if (!p_Fm->recoveryMode) + XX_Free(p_Fm->p_FmStateStruct); + + XX_Free(p_Fm); + + return E_OK; + } + + fman_free_resources(&fman_rg); + + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0)) + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); + + if (p_Fm->p_FmStateStruct) + { + if (p_Fm->p_FmStateStruct->irq != NO_IRQ) + { + XX_DisableIntr(p_Fm->p_FmStateStruct->irq); + XX_FreeIntr(p_Fm->p_FmStateStruct->irq); + } + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) + { + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq); + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq); + } + } + +#if (DPAA_VERSION >= 11) + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); + + if (p_Fm->p_FmSp) + { + XX_Free(p_Fm->p_FmSp); + p_Fm->p_FmSp = NULL; + } +#endif /* (DPAA_VERSION >= 11) */ + + if (p_Fm->h_Spinlock) + XX_FreeSpinlock(p_Fm->h_Spinlock); + + if (p_Fm->p_FmDriverParam) + { + if (p_Fm->firmware.p_Code) + XX_Free(p_Fm->firmware.p_Code); + XX_Free(p_Fm->p_FmDriverParam); + p_Fm->p_FmDriverParam = NULL; + } + + FreeInitResources(p_Fm); + + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct) + XX_Free(p_Fm->p_FmStateStruct); + + XX_Free(p_Fm); + + return E_OK; +} + +/*************************************************/ +/* API Advanced Init unit functions */ +/*************************************************/ + +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->resetOnInit = enable; + + return E_OK; +} + +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride; + + return E_OK; +} + +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize; + + return E_OK; +} + +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_dma_cache_override fsl_cache_override; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride) + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override; + + return E_OK; +} + +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride; + + return E_OK; +} + +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_dma_aid_mode fsl_aid_mode; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode); + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode; + + return E_OK; +} + +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + +#if (DPAA_VERSION >= 11) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); +#else + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats; + + return E_OK; +#endif /* (DPAA_VERSION >= 11) */ +} + +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries; + + return E_OK; +} + +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode); + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt; + + return E_OK; +} + +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop; + + return E_OK; +} + +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_dma_emergency_level fsl_dma_emer; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel); + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE; + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect; + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer; + + return E_OK; +} + +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE; + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt; + + return E_OK; +} + +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_dma_err fsl_dma_err; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr); + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err; + + return E_OK; +} + +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_catastrophic_err fsl_catastrophic_err; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr); + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err; + + return E_OK; +} + +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); + + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE; + + return E_OK; +} + +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE ); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); + + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE; + + return E_OK; +} + +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->halt_on_external_activ = enable; + + return E_OK; +} + +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); + + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable; + + return E_OK; +} + +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t bitMask = 0; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + GET_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_Fm->userSetExceptions |= bitMask; + else + p_Fm->p_FmStateStruct->exceptions &= ~bitMask; + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable; + + return E_OK; +} + +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod; + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period; + + return E_OK; +} + +/****************************************************/ +/* Hidden-DEBUG Only API */ +/****************************************************/ + +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit; + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh; + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh; + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh; + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh; + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh; + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh; + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh; + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh; + + return E_OK; +} + +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency; + + return E_OK; +} + +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) + +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + +#if (DPAA_VERSION >= 11) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); +#else + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency; + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency; + + return E_OK; +#endif +} + +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency; + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency; + + return E_OK; +} + +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + +#if (DPAA_VERSION >= 11) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); +#else + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency; + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency; + + return E_OK; +#endif +} + +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue; + + return E_OK; +} + +t_Error FM_ConfigEnableCounters(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); +UNUSED(p_Fm); + + return E_OK; +} + +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params) +{ + t_Fm* p_Fm = (t_Fm*)h_Fm; + if (p_Params->setParams.type & UPDATE_FM_CLD) + { + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32( + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800); + } + if (p_Params->setParams.type & CLEAR_IRAM_READY) + { + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY); + } + if (p_Params->setParams.type & UPDATE_FPM_EXTC) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000); + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000); + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP) + { + if (p_Params->setParams.sleep) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP); + else + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP); + } + if (p_Params->getParams.type & GET_FM_CLD) + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld); + if (p_Params->getParams.type & GET_FMQM_GS) + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs); + if (p_Params->getParams.type & GET_FM_NPI) + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi); + if (p_Params->getParams.type & GET_FMFP_EXTC) + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc); + return E_OK; +} + + +/****************************************************/ +/* API Run-time Control uint functions */ +/****************************************************/ +void FM_EventIsr(t_Handle h_Fm) +{ +#define FM_M_CALL_1G_MAC_ISR(_id) \ + { \ + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \ + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \ + else \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\ + } +#define FM_M_CALL_10G_MAC_ISR(_id) \ + { \ + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \ + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \ + else \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\ + } + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t pending, event; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + fpm_rg = p_Fm->p_FmFpmRegs; + + /* normal interrupts */ + pending = fman_get_normal_pending(fpm_rg); + if (!pending) + return; + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt + { + t_FmGetSetParams fmGetSetParams; + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; + fmGetSetParams.setParams.sleep = 0; + FmGetSetParams(h_Fm, &fmGetSetParams); + } + if (pending & INTR_EN_QMI) + QmiEvent(p_Fm); + if (pending & INTR_EN_PRS) + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle); + if (pending & INTR_EN_PLCR) + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle); + if (pending & INTR_EN_TMR) + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); + + /* MAC events may belong to different partitions */ + if (pending & INTR_EN_1G_MAC0) + FM_M_CALL_1G_MAC_ISR(0); + if (pending & INTR_EN_1G_MAC1) + FM_M_CALL_1G_MAC_ISR(1); + if (pending & INTR_EN_1G_MAC2) + FM_M_CALL_1G_MAC_ISR(2); + if (pending & INTR_EN_1G_MAC3) + FM_M_CALL_1G_MAC_ISR(3); + if (pending & INTR_EN_1G_MAC4) + FM_M_CALL_1G_MAC_ISR(4); + if (pending & INTR_EN_1G_MAC5) + FM_M_CALL_1G_MAC_ISR(5); + if (pending & INTR_EN_1G_MAC6) + FM_M_CALL_1G_MAC_ISR(6); + if (pending & INTR_EN_1G_MAC7) + FM_M_CALL_1G_MAC_ISR(7); + if (pending & INTR_EN_10G_MAC0) + FM_M_CALL_10G_MAC_ISR(0); + if (pending & INTR_EN_10G_MAC1) + FM_M_CALL_10G_MAC_ISR(1); + + /* IM port events may belong to different partitions */ + if (pending & INTR_EN_REV0) + { + event = fman_get_controller_event(fpm_rg, 0); + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId) + /*TODO IPC ISR For Fman Ctrl */ + ASSERT_COND(0); + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */ + else + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event); + + } + if (pending & INTR_EN_REV1) + { + event = fman_get_controller_event(fpm_rg, 1); + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId) + /*TODO IPC ISR For Fman Ctrl */ + ASSERT_COND(0); + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */ + else + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event); + } + if (pending & INTR_EN_REV2) + { + event = fman_get_controller_event(fpm_rg, 2); + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId) + /*TODO IPC ISR For Fman Ctrl */ + ASSERT_COND(0); + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */ + else + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event); + } + if (pending & INTR_EN_REV3) + { + event = fman_get_controller_event(fpm_rg, 3); + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId) + /*TODO IPC ISR For Fman Ctrl */ + ASSERT_COND(0); + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */ + else + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event); + } +#ifdef FM_MACSEC_SUPPORT + if (pending & INTR_EN_MACSEC_MAC0) + { + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId) + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending); + else + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle); + } +#endif /* FM_MACSEC_SUPPORT */ +} + +t_Error FM_ErrorIsr(t_Handle h_Fm) +{ +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \ + { \ + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \ + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \ + else \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ + } +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \ + { \ + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \ + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \ + else \ + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\ + } + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t pending; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + fpm_rg = p_Fm->p_FmFpmRegs; + + /* error interrupts */ + pending = fman_get_fpm_error_interrupts(fpm_rg); + if (!pending) + return ERROR_CODE(E_EMPTY); + + if (pending & ERR_INTR_EN_BMI) + BmiErrEvent(p_Fm); + if (pending & ERR_INTR_EN_QMI) + QmiErrEvent(p_Fm); + if (pending & ERR_INTR_EN_FPM) + FpmErrEvent(p_Fm); + if (pending & ERR_INTR_EN_DMA) + DmaErrEvent(p_Fm); + if (pending & ERR_INTR_EN_IRAM) + IramErrIntr(p_Fm); + if (pending & ERR_INTR_EN_MURAM) + MuramErrIntr(p_Fm); + if (pending & ERR_INTR_EN_PRS) + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle); + if (pending & ERR_INTR_EN_PLCR) + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle); + if (pending & ERR_INTR_EN_KG) + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle); + + /* MAC events may belong to different partitions */ + if (pending & ERR_INTR_EN_1G_MAC0) + FM_M_CALL_1G_MAC_ERR_ISR(0); + if (pending & ERR_INTR_EN_1G_MAC1) + FM_M_CALL_1G_MAC_ERR_ISR(1); + if (pending & ERR_INTR_EN_1G_MAC2) + FM_M_CALL_1G_MAC_ERR_ISR(2); + if (pending & ERR_INTR_EN_1G_MAC3) + FM_M_CALL_1G_MAC_ERR_ISR(3); + if (pending & ERR_INTR_EN_1G_MAC4) + FM_M_CALL_1G_MAC_ERR_ISR(4); + if (pending & ERR_INTR_EN_1G_MAC5) + FM_M_CALL_1G_MAC_ERR_ISR(5); + if (pending & ERR_INTR_EN_1G_MAC6) + FM_M_CALL_1G_MAC_ERR_ISR(6); + if (pending & ERR_INTR_EN_1G_MAC7) + FM_M_CALL_1G_MAC_ERR_ISR(7); + if (pending & ERR_INTR_EN_10G_MAC0) + FM_M_CALL_10G_MAC_ERR_ISR(0); + if (pending & ERR_INTR_EN_10G_MAC1) + FM_M_CALL_10G_MAC_ERR_ISR(1); + +#ifdef FM_MACSEC_SUPPORT + if (pending & ERR_INTR_EN_MACSEC_MAC0) + { + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId) + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending); + else + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle); + } +#endif /* FM_MACSEC_SUPPORT */ + + return E_OK; +} + +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + int i; + uint8_t sum; + uint8_t hardwarePortId; + uint8_t weights[64]; + uint8_t weight, maxPercent = 0; + struct fman_bmi_regs *bmi_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + bmi_rg = p_Fm->p_FmBmiRegs; + + memset(weights, 0, (sizeof(uint8_t) * 64)); + + /* check that all ports add up to 100% */ + sum = 0; + for (i=0; i < p_PortsBandwidth->numOfPorts; i++) + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth; + if (sum != 100) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%")); + + /* find highest percent */ + for (i=0; i < p_PortsBandwidth->numOfPorts; i++) + { + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent) + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth; + } + + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */ + + /* calculate weight for each port */ + for (i=0; i < p_PortsBandwidth->numOfPorts; i++) + { + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent); + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division + is not reached, we round up so that: + 0 until maxPercent/PORT_MAX_WEIGHT get "1" + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2" + ... + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */ + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent)) + weight++; + + /* find the location of this port within the register */ + hardwarePortId = + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type, + p_PortsBandwidth->portsBandwidths[i].relativePortId, + p_Fm->p_FmStateStruct->revInfo.majorRev, + p_Fm->p_FmStateStruct->revInfo.minorRev); + + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); + weights[hardwarePortId] = weight; + } + + fman_set_ports_bandwidth(bmi_rg, weights); + + return E_OK; +} + +t_Error FM_EnableRamsEcc(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + + fpm_rg = p_Fm->p_FmFpmRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { + t_FmIpcMsg msg; + t_Error err; + + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_ENABLE_RAM_ECC; + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + NULL, + NULL, + NULL, + NULL); + if (err != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return E_OK; + } + + if (!p_Fm->p_FmStateStruct->internalCall) + p_Fm->p_FmStateStruct->explicitEnable = TRUE; + p_Fm->p_FmStateStruct->internalCall = FALSE; + + if (p_Fm->p_FmStateStruct->ramsEccEnable) + return E_OK; + else + { + fman_enable_rams_ecc(fpm_rg); + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE; + } + + return E_OK; +} + +t_Error FM_DisableRamsEcc(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + bool explicitDisable = FALSE; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE); + + fpm_rg = p_Fm->p_FmFpmRegs; + + if (p_Fm->guestId != NCSW_MASTER_ID) + { + t_Error err; + t_FmIpcMsg msg; + + memset(&msg, 0, sizeof(msg)); + msg.msgId = FM_DISABLE_RAM_ECC; + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + NULL, + NULL, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + return E_OK; + } + + if (!p_Fm->p_FmStateStruct->internalCall) + explicitDisable = TRUE; + p_Fm->p_FmStateStruct->internalCall = FALSE; + + /* if rams are already disabled, or if rams were explicitly enabled and are + currently called indirectly (not explicitly), ignore this call. */ + if (!p_Fm->p_FmStateStruct->ramsEccEnable || + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable)) + return E_OK; + else + { + if (p_Fm->p_FmStateStruct->explicitEnable) + /* This is the case were both explicit are TRUE. + Turn off this flag for cases were following ramsEnable + routines are called */ + p_Fm->p_FmStateStruct->explicitEnable = FALSE; + + fman_enable_rams_ecc(fpm_rg); + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; + } + + return E_OK; +} + +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t bitMask = 0; + enum fman_exceptions fslException; + struct fman_rg fman_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + GET_EXCEPTION_FLAG(bitMask, exception); + if (bitMask) + { + if (enable) + p_Fm->p_FmStateStruct->exceptions |= bitMask; + else + p_Fm->p_FmStateStruct->exceptions &= ~bitMask; + + fslException = FmanExceptionTrans(exception); + + return (t_Error)fman_set_exception(&fman_rg, + fslException, + enable); + } + else + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); + + return E_OK; +} + +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev; + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev; + + return E_OK; +} + +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_FMIramRegs *p_Iram; + uint32_t revInfo; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER); + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + p_Fm->h_IpcSessions[0]) + { + t_Error err; + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength; + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV; + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo); + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL)) != E_OK) + RETURN_ERROR(MINOR, err, NO_MSG); + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo))) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo)); + p_RevisionInfo->packageRev = ipcRevInfo.packageRev; + p_RevisionInfo->majorRev = ipcRevInfo.majorRev; + p_RevisionInfo->minorRev = ipcRevInfo.minorRev; + return (t_Error)(reply.error); + } + else if (p_Fm->guestId != NCSW_MASTER_ID) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, + ("running in guest-mode without IPC!")); + + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); + WRITE_UINT32(p_Iram->iadd, 0x4); + while (GET_UINT32(p_Iram->iadd) != 0x4) ; + revInfo = GET_UINT32(p_Iram->idata); + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16); + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8); + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF); + + return E_OK; +} + +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_Error err; + uint32_t counterValue; + struct fman_rg fman_rg; + enum fman_counters fsl_counter; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcMsg msg; + t_FmIpcReply reply; + uint32_t replyLength, outCounter; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_GET_COUNTER; + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t)); + replyLength = sizeof(uint32_t) + sizeof(uint32_t); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId) +sizeof(counterValue), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + { + REPORT_ERROR(MAJOR, err, NO_MSG); + return 0; + } + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return 0; + } + + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t)); + return outCounter; + } + else if (!p_Fm->baseAddr) + { + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!")); + return 0; + } + + /* When applicable (when there is an 'enable counters' bit, + check that counters are enabled */ + switch (counter) + { + case (e_FM_COUNTERS_DEQ_1): + case (e_FM_COUNTERS_DEQ_2): + case (e_FM_COUNTERS_DEQ_3): + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) || + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) + { + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported")); + return 0; + } + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): + case (e_FM_COUNTERS_DEQ_0): + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): + case (e_FM_COUNTERS_DEQ_FROM_FD): + case (e_FM_COUNTERS_DEQ_CONFIRM): + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS)) + { + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled")); + return 0; + } + break; + default: + break; + } + + FMAN_COUNTERS_TRANS(fsl_counter, counter); + return fman_get_counter(&fman_rg, fsl_counter); +} + +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_rg fman_rg; + enum fman_counters fsl_counter; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + FMAN_COUNTERS_TRANS(fsl_counter, counter); + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val); +} + +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_dma_regs *dma_rg; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + dma_rg = p_Fm->p_FmDmaRegs; + + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable); +} + +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_dma_regs *dma_rg; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + dma_rg = p_Fm->p_FmDmaRegs; + + fman_set_dma_ext_bus_pri(dma_rg, pri); +} + +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + uint32_t dmaStatus; + struct fman_dma_regs *dma_rg; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + dma_rg = p_Fm->p_FmDmaRegs; + + if ((p_Fm->guestId != NCSW_MASTER_ID) && + !p_Fm->baseAddr && + p_Fm->h_IpcSessions[0]) + { + t_FmIpcDmaStatus ipcDmaStatus; + t_FmIpcMsg msg; + t_FmIpcReply reply; + t_Error err; + uint32_t replyLength; + + memset(&msg, 0, sizeof(msg)); + memset(&reply, 0, sizeof(reply)); + msg.msgId = FM_DMA_STAT; + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], + (uint8_t*)&msg, + sizeof(msg.msgId), + (uint8_t*)&reply, + &replyLength, + NULL, + NULL); + if (err != E_OK) + { + REPORT_ERROR(MINOR, err, NO_MSG); + return; + } + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus))) + { + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); + return; + } + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus)); + + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */ + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */ + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */ + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */ + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */ + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */ + return; + } + else if (!p_Fm->baseAddr) + { + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, + ("Either IPC or 'baseAddress' is required!")); + return; + } + + dmaStatus = fman_get_dma_status(dma_rg); + + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY); + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR); + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC); + else + { + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC); + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC); + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC); + } +} + +void FM_Resume(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + struct fman_fpm_regs *fpm_rg; + + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + fpm_rg = p_Fm->p_FmFpmRegs; + + fman_resume(fpm_rg); +} + +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm, + fmSpecialOperations_t spOper, + uint8_t *p_SpOperCoding) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + t_FmCtrlCodeRevisionInfo revInfo; + t_Error err; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER); + + if (!spOper) + { + *p_SpOperCoding = 0; + return E_OK; + } + + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK) + { + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision.")); + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER; + } + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); + + switch (spOper) + { + case (FM_SP_OP_CAPWAP_DTLS_DEC): + *p_SpOperCoding = 9; + break; + case (FM_SP_OP_CAPWAP_DTLS_ENC): + *p_SpOperCoding = 10; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP): + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD): + *p_SpOperCoding = 5; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP): + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD): + *p_SpOperCoding = 6; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD): + *p_SpOperCoding = 3; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN): + *p_SpOperCoding = 1; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR): + *p_SpOperCoding = 12; + break; + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD): + *p_SpOperCoding = 4; + break; + case (FM_SP_OP_IPSEC): + *p_SpOperCoding = 2; + break; + case (FM_SP_OP_DCL4C): + *p_SpOperCoding = 7; + break; + case (FM_SP_OP_CLEAR_RPD): + *p_SpOperCoding = 8; + break; + default: + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); + } + + return E_OK; +} + +t_Error FM_CtrlMonStart(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_FmTrbRegs *p_MonRegs; + uint8_t i; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG); + + for (i = 0; i < FM_NUM_OF_CTRL; i++) + { + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i)); + + /* Reset control registers */ + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET); + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET); + + /* Configure: counter #1 counts all stalls in risc - ldsched stall + counter #2 counts all stalls in risc - other stall*/ + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL); + + /* Enable monitoring */ + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS); + } + + return E_OK; +} + +t_Error FM_CtrlMonStop(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_FmTrbRegs *p_MonRegs; + uint8_t i; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + + for (i = 0; i < FM_NUM_OF_CTRL; i++) + { + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i)); + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS); + } + + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG); + + return E_OK; +} + +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon) +{ + t_Fm *p_Fm = (t_Fm *)h_Fm; + t_FmTrbRegs *p_MonRegs; + uint64_t clkCnt, utilValue, effValue; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER); + + if (fmCtrlIndex >= FM_NUM_OF_CTRL) + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index")); + + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex)); + + clkCnt = (uint64_t) + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl)); + + utilValue = (uint64_t) + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l)); + + effValue = (uint64_t) + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l)); + + p_Mon->percentCnt[0] = (uint8_t)(((clkCnt - utilValue) * 100) / clkCnt); + if (clkCnt != utilValue) + p_Mon->percentCnt[1] = (uint8_t)((((clkCnt - utilValue) - effValue) * 100) / (clkCnt - utilValue)); + else + p_Mon->percentCnt[1] = 0; + + return E_OK; +} + +t_Handle FM_GetMuramHandle(t_Handle h_Fm) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL); + + return (p_Fm->h_FmMuram); +} + +/****************************************************/ +/* Hidden-DEBUG Only API */ +/****************************************************/ +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception) +{ + t_Fm *p_Fm = (t_Fm*)h_Fm; + enum fman_exceptions fslException; + struct fman_rg fman_rg; + + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); + + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; + fman_rg.dma_rg = p_Fm->p_FmDmaRegs; + + switch (exception) + { + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_QMI_SINGLE_ECC: + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration.")); + + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_QMI_DOUBLE_ECC: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_BMI_LIST_RAM_ECC: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_BMI_STATISTICS_RAM_ECC: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + case e_FM_EX_BMI_DISPATCH_RAM_ECC: + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)) + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); + break; + default: + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); + } + + fslException = FmanExceptionTrans(exception); + fman_force_intr (&fman_rg, fslException); + + return E_OK; +} + +t_Handle FmGetPcd(t_Handle h_Fm) +{ + return ((t_Fm*)h_Fm)->h_Pcd; +} +#if (DPAA_VERSION >= 11) +extern void *g_MemacRegs; +void fm_clk_down(void); +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask); +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId) +{ + int macId; + uint32_t event, rcr; + t_Fm *p_Fm = (t_Fm*)h_Fm; + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); + rcr |= 0x04000000; + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr); + + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); + do + { + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF); + } while ((event & 0x00000020) == 0); + fm_clk_down(); + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); + rcr &= ~0x04000000; + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr); +} +#endif diff --git a/sys/contrib/ncsw/Peripherals/FM/fman_ncsw.c b/sys/contrib/ncsw/Peripherals/FM/fman_ncsw.c new file mode 100755 index 000000000000..2c8002e8562c --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/fman_ncsw.c @@ -0,0 +1,1398 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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 +#include "fsl_fman.h" +#include "dpaa_integration_ext.h" + +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg) +{ + uint32_t event, mask, force; + + event = ioread32be(&bmi_rg->fmbm_ievr); + mask = ioread32be(&bmi_rg->fmbm_ier); + event &= mask; + /* clear the forced events */ + force = ioread32be(&bmi_rg->fmbm_ifr); + if (force & event) + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr); + /* clear the acknowledged events */ + iowrite32be(event, &bmi_rg->fmbm_ievr); + return event; +} + +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg) +{ + uint32_t event, mask, force; + + event = ioread32be(&qmi_rg->fmqm_eie); + mask = ioread32be(&qmi_rg->fmqm_eien); + event &= mask; + + /* clear the forced events */ + force = ioread32be(&qmi_rg->fmqm_eif); + if (force & event) + iowrite32be(force & ~event, &qmi_rg->fmqm_eif); + /* clear the acknowledged events */ + iowrite32be(event, &qmi_rg->fmqm_eie); + return event; +} + +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg) +{ + return ioread32be(&dma_rg->fmdmtcid); +} + +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg) +{ + uint64_t addr; + + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal); + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32); + + return addr; +} + +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg) +{ + uint32_t status, mask; + + status = ioread32be(&dma_rg->fmdmsr); + mask = ioread32be(&dma_rg->fmdmmr); + + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */ + if ((mask & DMA_MODE_BER) != DMA_MODE_BER) + status &= ~DMA_STATUS_BUS_ERR; + + /* clear relevant bits if mask has no DMA_MODE_ECC */ + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC) + status &= ~(DMA_STATUS_FM_SPDAT_ECC | + DMA_STATUS_READ_ECC | + DMA_STATUS_SYSTEM_WRITE_ECC | + DMA_STATUS_FM_WRITE_ECC); + + /* clear set events */ + iowrite32be(status, &dma_rg->fmdmsr); + + return status; +} + +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg) +{ + uint32_t event; + + event = ioread32be(&fpm_rg->fmfp_ee); + /* clear the all occurred events */ + iowrite32be(event, &fpm_rg->fmfp_ee); + return event; +} + +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg) +{ + uint32_t event, mask; + + event = ioread32be(&fpm_rg->fm_rcr); + mask = ioread32be(&fpm_rg->fm_rie); + + /* clear MURAM event bit (do not clear IRAM event) */ + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr); + + if ((mask & FPM_MURAM_ECC_ERR_EX_EN)) + return event; + else + return 0; +} + +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg) +{ + uint32_t event, mask; + + event = ioread32be(&fpm_rg->fm_rcr) ; + mask = ioread32be(&fpm_rg->fm_rie); + /* clear IRAM event bit (do not clear MURAM event) */ + iowrite32be(event & ~FPM_RAM_MURAM_ECC, + &fpm_rg->fm_rcr); + + if ((mask & FPM_IRAM_ECC_ERR_EX_EN)) + return event; + else + return 0; +} + +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg) +{ + uint32_t event, mask, force; + + event = ioread32be(&qmi_rg->fmqm_ie); + mask = ioread32be(&qmi_rg->fmqm_ien); + event &= mask; + /* clear the forced events */ + force = ioread32be(&qmi_rg->fmqm_if); + if (force & event) + iowrite32be(force & ~event, &qmi_rg->fmqm_if); + /* clear the acknowledged events */ + iowrite32be(event, &qmi_rg->fmqm_ie); + return event; +} + +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg, + uint8_t count1ubit, + uint16_t fm_clk_freq) +{ + uint32_t tmp; + uint64_t frac; + uint32_t intgr; + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */ + + /* configure timestamp so that bit 8 will count 1 microsecond + * Find effective count rate at TIMESTAMP least significant bits: + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz + * Find frequency ratio between effective count rate and the clock: + * Effective_Count_Rate / CLK e.g. for 600 MHz clock: + * 256/600 = 0.4266666... */ + + intgr = ts_freq / fm_clk_freq; + /* we multiply by 2^16 to keep the fraction of the division + * we do not div back, since we write this value as a fraction + * see spec */ + + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq; + /* we check remainder of the division in order to round up if not int */ + if (do_div(frac, fm_clk_freq)) + frac++; + + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac; + iowrite32be(tmp, &fpm_rg->fmfp_tsc2); + + /* enable timestamp with original clock */ + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1); +} + +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg) +{ + return ioread32be(&fpm_rg->fm_epi); +} + + +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg) +{ + int timeout = 100; + + iowrite32be(0x40000000, &fpm_rg->fmfp_extc); + + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout) + DELAY(10); + + if (!timeout) + return -EBUSY; + return 0; +} + +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, + uint8_t event_reg_id, + uint32_t enable_events) +{ + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]); +} + +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id) +{ + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]); +} + +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg, + uint8_t port_id, + uint8_t num_fman_ctrls, + uint32_t or_fman_ctrl) +{ + uint32_t tmp = 0; + + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT); + /*TODO - maybe to put CTL# according to another criteria*/ + if (num_fman_ctrls == 2) + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1; + /* order restoration */ + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl; + + iowrite32be(tmp, &fpm_rg->fmfp_prc); +} + +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg, + uint8_t port_id, + bool independent_mode, + bool is_rx_port) +{ + uint32_t tmp = 0; + + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT); + if (independent_mode) { + if (is_rx_port) + tmp |= (FPM_PRT_FM_CTL1 << + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1; + else + tmp |= (FPM_PRT_FM_CTL2 << + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2; + } else { + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1); + + /* order restoration */ + if (port_id % 2) + tmp |= (FPM_PRT_FM_CTL1 << + FPM_PRC_ORA_FM_CTL_SEL_SHIFT); + else + tmp |= (FPM_PRT_FM_CTL2 << + FPM_PRC_ORA_FM_CTL_SEL_SHIFT); + } + iowrite32be(tmp, &fpm_rg->fmfp_prc); +} + +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg) +{ + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc); +} + +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg) +{ + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8); +} + +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val) +{ + uint32_t tmp_reg; + + tmp_reg = ioread32be(&qmi_rg->fmqm_gc); + tmp_reg &= ~QMI_CFG_ENQ_MASK; + tmp_reg |= ((uint32_t)val << 8); + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc); +} + +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val) +{ + uint32_t tmp_reg; + + tmp_reg = ioread32be(&qmi_rg->fmqm_gc); + tmp_reg &= ~QMI_CFG_DEQ_MASK; + tmp_reg |= (uint32_t)val; + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc); +} + +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg) +{ + iowrite32be(0, &fpm_rg->fmfp_mxd); +} + +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id, + uint16_t liodn_base, + uint16_t liodn_ofst) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return; + + /* set LIODN base for this port */ + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]); + if (port_id % 2) { + tmp &= ~FM_LIODN_BASE_MASK; + tmp |= (uint32_t)liodn_base; + } else { + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT); + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT; + } + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]); + iowrite32be((uint32_t)liodn_ofst, + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]); +} + +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id) +{ + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED); +} + +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id) +{ + uint32_t tmp; + + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) | + FPM_PRC_REALSE_STALLED); + iowrite32be(tmp, &fpm_rg->fmfp_prc); +} + +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g) +{ + uint32_t msk, timeout = 100; + + /* Get the relevant bit mask */ + if (is_10g) { + switch (mac_id) { + case(0): + msk = FPM_RSTC_10G0_RESET; + break; + case(1): + msk = FPM_RSTC_10G1_RESET; + break; + default: + return -EINVAL; + } + } else { + switch (mac_id) { + case(0): + msk = FPM_RSTC_1G0_RESET; + break; + case(1): + msk = FPM_RSTC_1G1_RESET; + break; + case(2): + msk = FPM_RSTC_1G2_RESET; + break; + case(3): + msk = FPM_RSTC_1G3_RESET; + break; + case(4): + msk = FPM_RSTC_1G4_RESET; + break; + case (5): + msk = FPM_RSTC_1G5_RESET; + break; + case (6): + msk = FPM_RSTC_1G6_RESET; + break; + case (7): + msk = FPM_RSTC_1G7_RESET; + break; + default: + return -EINVAL; + } + } + /* reset */ + iowrite32be(msk, &fpm_rg->fm_rstc); + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout) + DELAY(10); + + if (!timeout) + return -EBUSY; + return 0; +} + +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id) +{ + uint32_t tmp_reg; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]); + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1); +} + +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg) +{ + uint32_t reg, res; + + reg = ioread32be(&bmi_rg->fmbm_cfg1); + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff; + return res * FMAN_BMI_FIFO_UNITS; +} + +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg, + uint8_t port_id) +{ + uint32_t tmp_reg; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]); + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >> + BMI_EXTRA_FIFO_SIZE_SHIFT); +} + +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint32_t sz_fifo, + uint32_t extra_sz_fifo) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return; + + /* calculate reg */ + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) | + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) << + BMI_EXTRA_FIFO_SIZE_SHIFT)); + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]); +} + +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >> + BMI_NUM_OF_TASKS_SHIFT) + 1); +} + +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >> + BMI_EXTRA_NUM_OF_TASKS_SHIFT); +} + +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t num_tasks, + uint8_t num_extra_tasks) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return; + + /* calculate reg */ + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) & + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) | + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]); +} + +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >> + BMI_NUM_OF_DMAS_SHIFT) + 1); +} + +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id) +{ + uint32_t tmp; + + if ((port_id > 63) || (port_id < 1)) + return 0; + + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >> + BMI_EXTRA_NUM_OF_DMAS_SHIFT); +} + +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t num_open_dmas, + uint8_t num_extra_open_dmas, + uint8_t total_num_dmas) +{ + uint32_t tmp = 0; + + if ((port_id > 63) || (port_id < 1)) + return; + + /* calculate reg */ + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) & + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) | + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]); + + /* update total num of DMA's with committed number of open DMAS, + * and max uncommitted pool. */ + if (total_num_dmas) + { + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT; + iowrite32be(tmp, &bmi_rg->fmbm_cfg2); + } +} + +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t base_storage_profile, + uint8_t log2_num_of_profiles) +{ + uint32_t tmp = 0; + if ((port_id > 63) || (port_id < 1)) + return; + + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]); + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16; + tmp |= (uint32_t)log2_num_of_profiles << 28; + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]); +} + +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg, + uint32_t congestion_group_id, + uint8_t priority_bit_map, + uint32_t reg_num) +{ + uint32_t offset, tmp = 0; + + offset = (congestion_group_id%4)*8; + + tmp = ioread32be(&cpg_rg[reg_num]); + tmp &= ~(0xFF<catastrophic_err = DEFAULT_CATASTROPHIC_ERR; + cfg->dma_err = DEFAULT_DMA_ERR; + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION; + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR; + cfg->en_iram_test_mode = FALSE; + cfg->en_muram_test_mode = FALSE; + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE; + + if (!is_master) + return; + + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE; + cfg->dma_aid_mode = DEFAULT_AID_MODE; + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW; + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH; + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE; + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES; + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE; + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY; + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY; + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG; + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER; + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER; + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT; + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH; + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH; + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH; + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH; + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH; + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH; + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH; + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH; + + cfg->pedantic_dma = FALSE; + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD; + cfg->dma_stop_on_bus_error = FALSE; + cfg->qmi_deq_option_support = FALSE; +} + +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg) +{ + uint32_t tmp_reg; + + /* read the values from the registers as they are initialized by the HW with + * the required values. + */ + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1); + cfg->total_fifo_size = + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS; + + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2); + cfg->total_num_of_tasks = + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1); + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr); + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT); + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy); + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT); + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr); + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT); + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS); + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE); + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT); + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE); + + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd); + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT); + + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1); + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT); + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT); + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT); + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT); + + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2); + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT); + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT); + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT); + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT); + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr); + cfg->dma_sos_emergency = tmp_reg; + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr); + cfg->dma_watchdog = tmp_reg/cfg->clk_freq; + + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr); + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE); + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK); +} + +void fman_reset(struct fman_fpm_regs *fpm_rg) +{ + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc); +} + +/**************************************************************************//** + @Function FM_Init + + @Description Initializes the FM module + + @Param[in] h_Fm - FM module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg) +{ + uint32_t tmp_reg; + + /**********************/ + /* Init DMA Registers */ + /**********************/ + /* clear status reg events */ + /* oren - check!!! */ + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC); + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg, + &dma_rg->fmdmsr); + + /* configure mode register */ + tmp_reg = 0; + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT; + if (cfg->dma_aid_override) + tmp_reg |= DMA_MODE_AID_OR; + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR) + tmp_reg |= DMA_MODE_BER; + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) | + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) | + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC)) + tmp_reg |= DMA_MODE_ECC; + if (cfg->dma_stop_on_bus_error) + tmp_reg |= DMA_MODE_SBER; + if(cfg->dma_axi_dbg_num_of_beats) + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK & + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT)); + + if (cfg->dma_en_emergency) { + tmp_reg |= cfg->dma_emergency_bus_select; + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT; + if (cfg->dma_en_emergency_smoother) + iowrite32be(cfg->dma_emergency_switch_counter, + &dma_rg->fmdmemsr); + } + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) << + DMA_MODE_CEN_SHIFT; + tmp_reg |= DMA_MODE_SECURE_PROT; + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT; + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT; + + if (cfg->pedantic_dma) + tmp_reg |= DMA_MODE_EMER_READ; + + iowrite32be(tmp_reg, &dma_rg->fmdmmr); + + /* configure thresholds register */ + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer << + DMA_THRESH_COMMQ_SHIFT) | + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer << + DMA_THRESH_READ_INT_BUF_SHIFT) | + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer); + + iowrite32be(tmp_reg, &dma_rg->fmdmtr); + + /* configure hysteresis register */ + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer << + DMA_THRESH_COMMQ_SHIFT) | + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer << + DMA_THRESH_READ_INT_BUF_SHIFT) | + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer); + + iowrite32be(tmp_reg, &dma_rg->fmdmhy); + + /* configure emergency threshold */ + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr); + + /* configure Watchdog */ + iowrite32be((cfg->dma_watchdog * cfg->clk_freq), + &dma_rg->fmdmwcr); + + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr); + + return 0; +} + +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg) +{ + uint32_t tmp_reg; + int i; + + /**********************/ + /* Init FPM Registers */ + /**********************/ + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT); + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd); + + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) | + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) | + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) | + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT)); + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1); + + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) | + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) | + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) | + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT)); + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2); + + /* define exceptions and error behavior */ + tmp_reg = 0; + /* Clear events */ + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | + FPM_EV_MASK_SINGLE_ECC); + /* enable interrupts */ + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS) + tmp_reg |= FPM_EV_MASK_STALL_EN; + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC) + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN; + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC) + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN; + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT); + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT); + if (!cfg->halt_on_external_activ) + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT; + if (!cfg->halt_on_unrecov_ecc_err) + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT; + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee); + + /* clear all fmCtls event registers */ + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++) + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]); + + /* RAM ECC - enable and clear events*/ + /* first we need to clear all parser memory, + * as it is uninitialized and may cause ECC errors */ + /* event bits */ + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC); + /* Rams enable not effected by RCR bit, but by a COP configuration */ + if (cfg->external_ecc_rams_enable) + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL; + + /* enable test mode */ + if (cfg->en_muram_test_mode) + tmp_reg |= FPM_RAM_MURAM_TEST_ECC; + if (cfg->en_iram_test_mode) + tmp_reg |= FPM_RAM_IRAM_TEST_ECC; + iowrite32be(tmp_reg, &fpm_rg->fm_rcr); + + tmp_reg = 0; + if (cfg->exceptions & FMAN_EX_IRAM_ECC) { + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN; + fman_enable_rams_ecc(fpm_rg); + } + if (cfg->exceptions & FMAN_EX_NURAM_ECC) { + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN; + fman_enable_rams_ecc(fpm_rg); + } + iowrite32be(tmp_reg, &fpm_rg->fm_rie); + + return 0; +} + +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg) +{ + uint32_t tmp_reg; + + /**********************/ + /* Init BMI Registers */ + /**********************/ + + /* define common resources */ + tmp_reg = cfg->fifo_base_addr; + tmp_reg = tmp_reg / BMI_FIFO_ALIGN; + + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) << + BMI_CFG1_FIFO_SIZE_SHIFT); + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1); + + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) << + BMI_CFG2_TASKS_SHIFT); + /* num of DMA's will be dynamically updated when each port is set */ + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2); + + /* define unmaskable exceptions, enable and clear events */ + tmp_reg = 0; + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC | + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC | + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC | + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC, + &bmi_rg->fmbm_ievr); + + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC) + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC) + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC) + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC) + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier); + + return 0; +} + +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg) +{ + uint32_t tmp_reg; + uint16_t period_in_fm_clocks; + uint8_t remainder; + /**********************/ + /* Init QMI Registers */ + /**********************/ + /* Clear error interrupt events */ + + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF, + &qmi_rg->fmqm_eie); + tmp_reg = 0; + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID) + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC) + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC; + /* enable events */ + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien); + + if (cfg->tnum_aging_period) { + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */ + period_in_fm_clocks = (uint16_t) + (cfg->tnum_aging_period * cfg->clk_freq); + /* period_in_fm_clocks must be a 64 multiply */ + remainder = (uint8_t)(period_in_fm_clocks % 64); + if (remainder) + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1); + else{ + tmp_reg = (uint32_t)(period_in_fm_clocks / 64); + if (!tmp_reg) + tmp_reg = 1; + } + tmp_reg <<= QMI_TAPC_TAP; + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc); + } + tmp_reg = 0; + /* Clear interrupt events */ + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie); + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC) + tmp_reg |= QMI_INTR_EN_SINGLE_ECC; + /* enable events */ + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien); + + return 0; +} + +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg) +{ + uint32_t cfg_reg = 0; + + /**********************/ + /* Enable all modules */ + /**********************/ + /* clear & enable global counters - calculate reg and save for later, + because it's the same reg for QMI enable */ + cfg_reg = QMI_CFG_EN_COUNTERS; + if (cfg->qmi_deq_option_support) + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) | + (uint32_t)cfg->qmi_def_tnums_thresh); + + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init); + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN, + &fman_rg->qmi_rg->fmqm_gc); + + return 0; +} + +void fman_free_resources(struct fman_rg *fman_rg) +{ + /* disable BMI and QMI */ + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init); + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc); + + /* release BMI resources */ + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2); + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1); + + /* disable ECC */ + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr); +} + +/****************************************************/ +/* API Run-time Control uint functions */ +/****************************************************/ +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg) +{ + return ioread32be(&fpm_rg->fm_npi); +} + +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id) +{ + uint32_t event; + + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) & + ioread32be(&fpm_rg->fmfp_cee[reg_id]); + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]); + + return event; +} + +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg) +{ + return ioread32be(&fpm_rg->fm_epi); +} + +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights) +{ + int i; + uint8_t shift; + uint32_t tmp = 0; + + for (i = 0; i < 64; i++) { + if (weights[i] > 1) { /* no need to write 1 since it is 0 */ + /* Add this port to tmp_reg */ + /* (each 8 ports result in one register)*/ + shift = (uint8_t)(32 - 4 * ((i % 8) + 1)); + tmp |= ((weights[i] - 1) << shift); + } + if (i % 8 == 7) { /* last in this set */ + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]); + tmp = 0; + } + } +} + +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg) +{ + uint32_t tmp; + + tmp = ioread32be(&fpm_rg->fm_rcr); + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL) + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN, + &fpm_rg->fm_rcr); + else + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN | + FPM_RAM_IRAM_ECC_EN, + &fpm_rg->fm_rcr); +} + +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg) +{ + uint32_t tmp; + + tmp = ioread32be(&fpm_rg->fm_rcr); + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL) + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN, + &fpm_rg->fm_rcr); + else + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN), + &fpm_rg->fm_rcr); +} + +int fman_set_exception(struct fman_rg *fman_rg, + enum fman_exceptions exception, + bool enable) +{ + uint32_t tmp; + + switch (exception) { + case(E_FMAN_EX_DMA_BUS_ERROR): + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr); + if (enable) + tmp |= DMA_MODE_BER; + else + tmp &= ~DMA_MODE_BER; + /* disable bus error */ + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr); + break; + case(E_FMAN_EX_DMA_READ_ECC): + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC): + case(E_FMAN_EX_DMA_FM_WRITE_ECC): + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr); + if (enable) + tmp |= DMA_MODE_ECC; + else + tmp &= ~DMA_MODE_ECC; + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr); + break; + case(E_FMAN_EX_FPM_STALL_ON_TASKS): + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); + if (enable) + tmp |= FPM_EV_MASK_STALL_EN; + else + tmp &= ~FPM_EV_MASK_STALL_EN; + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); + break; + case(E_FMAN_EX_FPM_SINGLE_ECC): + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); + if (enable) + tmp |= FPM_EV_MASK_SINGLE_ECC_EN; + else + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN; + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); + break; + case(E_FMAN_EX_FPM_DOUBLE_ECC): + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); + if (enable) + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN; + else + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN; + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); + break; + case(E_FMAN_EX_QMI_SINGLE_ECC): + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien); + if (enable) + tmp |= QMI_INTR_EN_SINGLE_ECC; + else + tmp &= ~QMI_INTR_EN_SINGLE_ECC; + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien); + break; + case(E_FMAN_EX_QMI_DOUBLE_ECC): + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien); + if (enable) + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC; + else + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC; + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien); + break; + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID): + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien); + if (enable) + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; + else + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF; + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien); + break; + case(E_FMAN_EX_BMI_LIST_RAM_ECC): + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); + if (enable) + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC; + else + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC; + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); + break; + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC): + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); + if (enable) + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; + else + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); + break; + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC): + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); + if (enable) + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; + else + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); + break; + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC): + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); + if (enable) + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; + else + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); + break; + case(E_FMAN_EX_IRAM_ECC): + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie); + if (enable) { + /* enable ECC if not enabled */ + fman_enable_rams_ecc(fman_rg->fpm_rg); + /* enable ECC interrupts */ + tmp |= FPM_IRAM_ECC_ERR_EX_EN; + } else { + /* ECC mechanism may be disabled, + * depending on driver status */ + fman_disable_rams_ecc(fman_rg->fpm_rg); + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN; + } + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie); + break; + case(E_FMAN_EX_MURAM_ECC): + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie); + if (enable) { + /* enable ECC if not enabled */ + fman_enable_rams_ecc(fman_rg->fpm_rg); + /* enable ECC interrupts */ + tmp |= FPM_MURAM_ECC_ERR_EX_EN; + } else { + /* ECC mechanism may be disabled, + * depending on driver status */ + fman_disable_rams_ecc(fman_rg->fpm_rg); + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN; + } + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie); + break; + default: + return -EINVAL; + } + return 0; +} + +void fman_get_revision(struct fman_fpm_regs *fpm_rg, + uint8_t *major, + uint8_t *minor) +{ + uint32_t tmp; + + tmp = ioread32be(&fpm_rg->fm_ip_rev_1); + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); + +} + +uint32_t fman_get_counter(struct fman_rg *fman_rg, + enum fman_counters reg_name) +{ + uint32_t ret_val; + + switch (reg_name) { + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc); + break; + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc); + break; + case(E_FMAN_COUNTERS_DEQ_0): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0); + break; + case(E_FMAN_COUNTERS_DEQ_1): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1); + break; + case(E_FMAN_COUNTERS_DEQ_2): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2); + break; + case(E_FMAN_COUNTERS_DEQ_3): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_FD): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc); + break; + case(E_FMAN_COUNTERS_DEQ_CONFIRM): + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc); + break; + default: + ret_val = 0; + } + return ret_val; +} + +int fman_modify_counter(struct fman_rg *fman_rg, + enum fman_counters reg_name, + uint32_t val) +{ + /* When applicable (when there is an 'enable counters' bit, + * check that counters are enabled */ + switch (reg_name) { + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): + case(E_FMAN_COUNTERS_DEQ_0): + case(E_FMAN_COUNTERS_DEQ_1): + case(E_FMAN_COUNTERS_DEQ_2): + case(E_FMAN_COUNTERS_DEQ_3): + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): + case(E_FMAN_COUNTERS_DEQ_FROM_FD): + case(E_FMAN_COUNTERS_DEQ_CONFIRM): + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) & + QMI_CFG_EN_COUNTERS)) + return -EINVAL; + break; + default: + break; + } + /* Set counter */ + switch (reg_name) { + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc); + break; + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc); + break; + case(E_FMAN_COUNTERS_DEQ_0): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0); + break; + case(E_FMAN_COUNTERS_DEQ_1): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1); + break; + case(E_FMAN_COUNTERS_DEQ_2): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2); + break; + case(E_FMAN_COUNTERS_DEQ_3): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc); + break; + case(E_FMAN_COUNTERS_DEQ_FROM_FD): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc); + break; + case(E_FMAN_COUNTERS_DEQ_CONFIRM): + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc); + break; + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT): + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc); + break; + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT): + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc); + break; + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT): + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc); + break; + default: + break; + } + return 0; +} + +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, + bool is_write, + bool enable) +{ + uint32_t msk; + + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ); + + if (enable) + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk, + &dma_rg->fmdmmr); + else /* disable */ + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk, + &dma_rg->fmdmmr); +} + +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri) +{ + uint32_t tmp; + + tmp = ioread32be(&dma_rg->fmdmmr) | + (pri << DMA_MODE_BUS_PRI_SHIFT); + + iowrite32be(tmp, &dma_rg->fmdmmr); +} + +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg) +{ + return ioread32be(&dma_rg->fmdmsr); +} + +void fman_force_intr(struct fman_rg *fman_rg, + enum fman_exceptions exception) +{ + switch (exception) { + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF, + &fman_rg->qmi_rg->fmqm_eif); + break; + case E_FMAN_EX_QMI_SINGLE_ECC: + iowrite32be(QMI_INTR_EN_SINGLE_ECC, + &fman_rg->qmi_rg->fmqm_if); + break; + case E_FMAN_EX_QMI_DOUBLE_ECC: + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC, + &fman_rg->qmi_rg->fmqm_eif); + break; + case E_FMAN_EX_BMI_LIST_RAM_ECC: + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC, + &fman_rg->bmi_rg->fmbm_ifr); + break; + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC: + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC, + &fman_rg->bmi_rg->fmbm_ifr); + break; + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC: + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC, + &fman_rg->bmi_rg->fmbm_ifr); + break; + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC: + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC, + &fman_rg->bmi_rg->fmbm_ifr); + break; + default: + break; + } +} + +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg) +{ + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY); +} +void fman_resume(struct fman_fpm_regs *fpm_rg) +{ + uint32_t tmp; + + tmp = ioread32be(&fpm_rg->fmfp_ee); + /* clear tmp_reg event bits in order not to clear standing events */ + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC | + FPM_EV_MASK_STALL | + FPM_EV_MASK_SINGLE_ECC); + tmp |= FPM_EV_MASK_RELEASE_FM; + + iowrite32be(tmp, &fpm_rg->fmfp_ee); +} diff --git a/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h b/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h index d1aaa3d83fea..81a25e976b62 100644 --- a/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h +++ b/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /****************************************************************************** @File fm_common.h @@ -41,20 +42,112 @@ #include "error_ext.h" #include "std_ext.h" #include "fm_pcd_ext.h" +#include "fm_ext.h" #include "fm_port_ext.h" + +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY + #define CLS_PLAN_NUM_PER_GRP 8 +#define IP_OFFLOAD_PACKAGE_NUMBER 106 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER)) + + + +/**************************************************************************//** + @Description Modules registers offsets +*//***************************************************************************/ +#define FM_MM_MURAM 0x00000000 +#define FM_MM_BMI 0x00080000 +#define FM_MM_QMI 0x00080400 +#define FM_MM_PRS 0x000c7000 +#define FM_MM_KG 0x000C1000 +#define FM_MM_DMA 0x000C2000 +#define FM_MM_FPM 0x000C3000 +#define FM_MM_PLCR 0x000C0000 +#define FM_MM_IMEM 0x000C4000 +#define FM_MM_CGP 0x000DB000 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i)) +#if (DPAA_VERSION >= 11) +#define FM_MM_SP 0x000dc000 +#endif /* (DPAA_VERSION >= 11) */ + + +/**************************************************************************//** + @Description Enum for inter-module interrupts registration +*//***************************************************************************/ +typedef enum e_FmEventModules{ + e_FM_MOD_PRS, /**< Parser event */ + e_FM_MOD_KG, /**< Keygen event */ + e_FM_MOD_PLCR, /**< Policer event */ + e_FM_MOD_10G_MAC, /**< 10G MAC event */ + e_FM_MOD_1G_MAC, /**< 1G MAC event */ + e_FM_MOD_TMR, /**< Timer event */ + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */ + e_FM_MOD_MACSEC, + e_FM_MOD_DUMMY_LAST +} e_FmEventModules; + +/**************************************************************************//** + @Description Enum for interrupts types +*//***************************************************************************/ +typedef enum e_FmIntrType { + e_FM_INTR_TYPE_ERR, + e_FM_INTR_TYPE_NORMAL +} e_FmIntrType; + +/**************************************************************************//** + @Description Enum for inter-module interrupts registration +*//***************************************************************************/ +typedef enum e_FmInterModuleEvent +{ + e_FM_EV_PRS = 0, /**< Parser event */ + e_FM_EV_ERR_PRS, /**< Parser error event */ + e_FM_EV_KG, /**< Keygen event */ + e_FM_EV_ERR_KG, /**< Keygen error event */ + e_FM_EV_PLCR, /**< Policer event */ + e_FM_EV_ERR_PLCR, /**< Policer error event */ + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */ + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */ + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */ + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */ + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */ + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */ + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */ + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */ + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */ + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */ + e_FM_EV_ERR_MACSEC_MAC0, + e_FM_EV_TMR, /**< Timer event */ + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/ + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/ + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/ + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/ + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/ + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/ + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/ + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/ + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/ + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/ + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */ + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */ + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */ + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */ + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */ + e_FM_EV_DUMMY_LAST +} e_FmInterModuleEvent; + #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START /**************************************************************************//** @Description PCD KG scheme registers *//***************************************************************************/ -typedef _Packed struct t_FmPcdPlcrInterModuleProfileRegs { +typedef _Packed struct t_FmPcdPlcrProfileRegs { volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/ volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/ volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/ @@ -72,28 +165,8 @@ typedef _Packed struct t_FmPcdPlcrInterModuleProfileRegs { volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/ volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/ volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */ -} _PackedType t_FmPcdPlcrInterModuleProfileRegs; +} _PackedType t_FmPcdPlcrProfileRegs; -/**************************************************************************//** - @Description PCD KG scheme registers -*//***************************************************************************/ -typedef _Packed struct t_FmPcdKgInterModuleSchemeRegs { - volatile uint32_t kgse_mode; /**< MODE */ - volatile uint32_t kgse_ekfc; /**< Extract Known Fields Command */ - volatile uint32_t kgse_ekdv; /**< Extract Known Default Value */ - volatile uint32_t kgse_bmch; /**< Bit Mask Command High */ - volatile uint32_t kgse_bmcl; /**< Bit Mask Command Low */ - volatile uint32_t kgse_fqb; /**< Frame Queue Base */ - volatile uint32_t kgse_hc; /**< Hash Command */ - volatile uint32_t kgse_ppc; /**< Policer Profile Command */ - volatile uint32_t kgse_gec[FM_PCD_KG_NUM_OF_GENERIC_REGS]; - /**< Generic Extract Command */ - volatile uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */ - volatile uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */ - volatile uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */ - volatile uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/ - volatile uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */ -} _PackedType t_FmPcdKgInterModuleSchemeRegs; typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams { volatile uint32_t portIdAndCapwapReassmTbl; @@ -101,14 +174,50 @@ typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams { volatile uint32_t timeoutRequestTime; }_PackedType t_FmPcdCcCapwapReassmTimeoutParams; +/**************************************************************************//** + @Description PCD CTRL Parameters Page +*//***************************************************************************/ +typedef _Packed struct t_FmPcdCtrlParamsPage { + volatile uint8_t reserved0[16]; + volatile uint32_t iprIpv4Nia; + volatile uint32_t iprIpv6Nia; + volatile uint8_t reserved1[24]; + volatile uint32_t ipfOptionsCounter; + volatile uint8_t reserved2[12]; + volatile uint32_t misc; + volatile uint32_t errorsDiscardMask; + volatile uint32_t discardMask; + volatile uint8_t reserved3[4]; + volatile uint32_t postBmiFetchNia; + volatile uint8_t reserved4[172]; +} _PackedType t_FmPcdCtrlParamsPage; + -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/ +typedef uint32_t t_FmFmanCtrl; + +#define FPM_PORT_FM_CTL1 0x00000001 +#define FPM_PORT_FM_CTL2 0x00000002 + + + +typedef struct t_FmPcdCcFragScratchPoolCmdParams { + uint32_t numOfBuffers; + uint8_t bufferPoolId; +} t_FmPcdCcFragScratchPoolCmdParams; + +typedef struct t_FmPcdCcReassmTimeoutParams { + bool activate; + uint8_t tsbs; + uint32_t iprcpt; +} t_FmPcdCcReassmTimeoutParams; + typedef struct { uint8_t baseEntry; uint16_t numOfClsPlanEntries; @@ -137,34 +246,42 @@ typedef struct uint16_t index; t_List node; }t_CcNodeInformation; -#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node) +#define CC_NODE_F_OBJECT(ptr) NCSW_LIST_OBJECT(ptr, t_CcNodeInformation, node) + +typedef enum e_ModifyState +{ + e_MODIFY_STATE_ADD = 0, + e_MODIFY_STATE_REMOVE, + e_MODIFY_STATE_CHANGE +} e_ModifyState; typedef struct { t_Handle h_Manip; t_List node; }t_ManipInfo; -#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node) +#define CC_NEXT_NODE_F_OBJECT(ptr) NCSW_LIST_OBJECT(ptr, t_CcNodeInfo, node) typedef struct { - uint32_t type; - uint8_t prOffset; - - uint16_t dataOffset; - uint8_t poolIndex; - - uint8_t poolIdForManip; - uint8_t numOfTasks; - - uint8_t hardwarePortId; - + uint32_t type; + uint8_t prOffset; + uint16_t dataOffset; + uint8_t internalBufferOffset; + uint8_t numOfTasks; + uint8_t numOfExtraTasks; + uint8_t hardwarePortId; + t_FmRevisionInfo revInfo; + uint32_t nia; + uint32_t discardMask; } t_GetCcParams; typedef struct { - uint32_t type; - int psoSize; - uint32_t nia; - + uint32_t type; + int psoSize; + uint32_t nia; + t_FmFmanCtrl orFmanCtrl; + bool overwrite; + uint8_t ofpDpde; } t_SetCcParams; typedef struct { @@ -172,6 +289,25 @@ typedef struct { t_SetCcParams setCcParams; } t_FmPortGetSetCcParams; +typedef struct { + uint32_t type; + bool sleep; +} t_FmSetParams; + +typedef struct { + uint32_t type; + uint32_t fmqm_gs; + uint32_t fm_npi; + uint32_t fm_cld; + uint32_t fmfp_extc; +} t_FmGetParams; + +typedef struct { + t_FmSetParams setParams; + t_FmGetParams getParams; +} t_FmGetSetParams; + +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params); static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) { @@ -180,6 +316,7 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) intFlags = XX_LockIntrSpinlock(h_Spinlock); else intFlags = XX_DisableAllIntr(); + if (*p_Flag) { if (h_Spinlock) @@ -189,10 +326,12 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) return FALSE; } *p_Flag = TRUE; + if (h_Spinlock) XX_UnlockIntrSpinlock(h_Spinlock, intFlags); else XX_RestoreAllIntr(intFlags); + return TRUE; } @@ -204,16 +343,24 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) *//***************************************************************************/ #define INTERNAL_CONTEXT_OFFSET 0x80000000 #define OFFSET_OF_PR 0x40000000 -#define BUFFER_POOL_ID_FOR_MANIP 0x20000000 +#define MANIP_EXTRA_SPACE 0x20000000 #define NUM_OF_TASKS 0x10000000 #define OFFSET_OF_DATA 0x08000000 #define HW_PORT_ID 0x04000000 - +#define FM_REV 0x02000000 +#define GET_NIA_FPNE 0x01000000 +#define GET_NIA_PNDN 0x00800000 +#define NUM_OF_EXTRA_TASKS 0x00400000 +#define DISCARD_MASK 0x00200000 #define UPDATE_NIA_PNEN 0x80000000 #define UPDATE_PSO 0x40000000 #define UPDATE_NIA_PNDN 0x20000000 #define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000 +#define UPDATE_OFP_DPTE 0x08000000 +#define UPDATE_NIA_FENE 0x04000000 +#define UPDATE_NIA_CMNE 0x02000000 +#define UPDATE_NIA_FPNE 0x01000000 /* @} */ /**************************************************************************//** @@ -223,53 +370,21 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) #define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000 #define UPDATE_CC_WITH_TREE 0x40000000 #define UPDATE_CC_WITH_DELETE_TREE 0x20000000 +#define UPDATE_KG_NIA_CC_WA 0x10000000 +#define UPDATE_KG_OPT_MODE 0x08000000 +#define UPDATE_KG_NIA 0x04000000 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000 /* @} */ -/**************************************************************************//** - @Collection Defines used for enabling/disabling FM interrupts - @{ -*//***************************************************************************/ -typedef uint32_t t_FmBlockErrIntrEnable; - -#define ERR_INTR_EN_DMA 0x00010000 -#define ERR_INTR_EN_FPM 0x80000000 -#define ERR_INTR_EN_BMI 0x00800000 -#define ERR_INTR_EN_QMI 0x00400000 -#define ERR_INTR_EN_PRS 0x00200000 -#define ERR_INTR_EN_KG 0x00100000 -#define ERR_INTR_EN_PLCR 0x00080000 -#define ERR_INTR_EN_MURAM 0x00040000 -#define ERR_INTR_EN_IRAM 0x00020000 -#define ERR_INTR_EN_10G_MAC0 0x00008000 -#define ERR_INTR_EN_1G_MAC0 0x00004000 -#define ERR_INTR_EN_1G_MAC1 0x00002000 -#define ERR_INTR_EN_1G_MAC2 0x00001000 -#define ERR_INTR_EN_1G_MAC3 0x00000800 -#define ERR_INTR_EN_1G_MAC4 0x00000400 -#define ERR_INTR_EN_MACSEC_MAC0 0x00000200 - - -typedef uint32_t t_FmBlockIntrEnable; - -#define INTR_EN_BMI 0x80000000 -#define INTR_EN_QMI 0x40000000 -#define INTR_EN_PRS 0x20000000 -#define INTR_EN_KG 0x10000000 -#define INTR_EN_PLCR 0x08000000 -#define INTR_EN_1G_MAC0_TMR 0x00080000 -#define INTR_EN_1G_MAC1_TMR 0x00040000 -#define INTR_EN_1G_MAC2_TMR 0x00020000 -#define INTR_EN_1G_MAC3_TMR 0x00010000 -#define INTR_EN_1G_MAC4_TMR 0x00000040 -#define INTR_EN_REV0 0x00008000 -#define INTR_EN_REV1 0x00004000 -#define INTR_EN_REV2 0x00002000 -#define INTR_EN_REV3 0x00001000 -#define INTR_EN_BRK 0x00000080 -#define INTR_EN_TMR 0x01000000 -#define INTR_EN_MACSEC_MAC0 0x00000001 -/* @} */ - +#define UPDATE_FPM_BRKC_SLP 0x80000000 +#define UPDATE_FPM_EXTC 0x40000000 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000 +#define GET_FMQM_GS 0x10000000 +#define GET_FM_NPI 0x08000000 +#define GET_FMFP_EXTC 0x04000000 +#define CLEAR_IRAM_READY 0x02000000 +#define UPDATE_FM_CLD 0x01000000 +#define GET_FM_CLD 0x00800000 #define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ FM_MAX_NUM_OF_1G_RX_PORTS + \ FM_MAX_NUM_OF_10G_RX_PORTS + \ @@ -284,6 +399,9 @@ typedef uint32_t t_FmBlockIntrEnable; /**************************************************************************//** @Description NIA Description *//***************************************************************************/ +#define NIA_ENG_MASK 0x007C0000 +#define NIA_AC_MASK 0x0003ffff + #define NIA_ORDER_RESTOR 0x00800000 #define NIA_ENG_FM_CTL 0x00000000 #define NIA_ENG_PRS 0x00440000 @@ -292,19 +410,25 @@ typedef uint32_t t_FmBlockIntrEnable; #define NIA_ENG_BMI 0x00500000 #define NIA_ENG_QMI_ENQ 0x00540000 #define NIA_ENG_QMI_DEQ 0x00580000 -#define NIA_ENG_MASK 0x007C0000 #define NIA_FM_CTL_AC_CC 0x00000006 #define NIA_FM_CTL_AC_HC 0x0000000C #define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008 #define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A -#define NIA_FM_CTL_AC_FRAG 0x0000000e -#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010 -#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012 -#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018 -#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012 -#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014 -#define NIA_FM_CTL_AC_MASK 0x0000001f +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020 +#define NIA_FM_CTL_AC_POST_TX 0x00000024 +/* V3 only */ +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C #define NIA_BMI_AC_ENQ_FRAME 0x00000002 #define NIA_BMI_AC_TX_RELEASE 0x000002C0 @@ -320,10 +444,47 @@ typedef uint32_t t_FmBlockIntrEnable; #define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006) +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \ + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)) +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \ + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME)) +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME) +#else +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \ + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \ + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \ + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \ + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD)) +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \ + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME) +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */ + +/**************************************************************************//** + @Description CTRL Parameters Page defines +*//***************************************************************************/ +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100 + +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f + /**************************************************************************//** @Description Port Id defines *//***************************************************************************/ +#if (DPAA_VERSION == 10) #define BASE_OH_PORTID 1 +#else +#define BASE_OH_PORTID 2 +#endif /* (DPAA_VERSION == 10) */ #define BASE_1G_RX_PORTID 8 #define BASE_10G_RX_PORTID 0x10 #define BASE_1G_TX_PORTID 0x28 @@ -344,67 +505,39 @@ typedef uint32_t t_FmBlockIntrEnable; REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id")) #endif #if (FM_MAX_NUM_OF_1G_RX_PORTS > 0) -#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ - if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \ +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id")) #else -#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id")) #endif #if (FM_MAX_NUM_OF_10G_RX_PORTS > 0) -#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ - if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \ +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id")) #else -#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id")) #endif #if (FM_MAX_NUM_OF_1G_TX_PORTS > 0) -#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ - if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \ +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id")) #else -#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id")) #endif #if (FM_MAX_NUM_OF_10G_TX_PORTS > 0) -#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ - if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \ +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id")) #else -#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id")) #endif - -#define SW_PORT_ID_TO_HW_PORT_ID(_port, _type, _relativePortId) \ -switch(_type) { \ - case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): \ - case(e_FM_PORT_TYPE_OH_HOST_COMMAND): \ - CHECK_PORT_ID_OH_PORTS(_relativePortId); \ - _port = (uint8_t)(BASE_OH_PORTID + (_relativePortId)); \ - break; \ - case(e_FM_PORT_TYPE_RX): \ - CHECK_PORT_ID_1G_RX_PORTS(_relativePortId); \ - _port = (uint8_t)(BASE_1G_RX_PORTID + (_relativePortId)); \ - break; \ - case(e_FM_PORT_TYPE_RX_10G): \ - CHECK_PORT_ID_10G_RX_PORTS(_relativePortId); \ - _port = (uint8_t)(BASE_10G_RX_PORTID + (_relativePortId)); \ - break; \ - case(e_FM_PORT_TYPE_TX): \ - CHECK_PORT_ID_1G_TX_PORTS(_relativePortId); \ - _port = (uint8_t)(BASE_1G_TX_PORTID + (_relativePortId)); \ - break; \ - case(e_FM_PORT_TYPE_TX_10G): \ - CHECK_PORT_ID_10G_TX_PORTS(_relativePortId); \ - _port = (uint8_t)(BASE_10G_TX_PORTID + (_relativePortId)); \ - break; \ - default: \ - REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); \ - _port = 0; \ - break; \ -} +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev); #define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \ { if (((hardwarePortId) >= BASE_OH_PORTID) && \ @@ -462,6 +595,7 @@ do { else ASSERT_COND(FALSE); \ } while (0) +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) #define BMI_FIFO_UNITS 0x100 typedef struct { @@ -477,220 +611,37 @@ typedef struct { ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2)) #define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC) -#define GET_PRS_HDR_NUM(num, hdr) \ -switch(hdr) \ -{ case(HEADER_TYPE_ETH): num = 0; break; \ - case(HEADER_TYPE_LLC_SNAP): num = 1; break; \ - case(HEADER_TYPE_VLAN): num = 2; break; \ - case(HEADER_TYPE_PPPoE): num = 3; break; \ - case(HEADER_TYPE_MPLS): num = 4; break; \ - case(HEADER_TYPE_IPv4): num = 5; break; \ - case(HEADER_TYPE_IPv6): num = 6; break; \ - case(HEADER_TYPE_GRE): num = 7; break; \ - case(HEADER_TYPE_MINENCAP): num = 8; break; \ - case(HEADER_TYPE_USER_DEFINED_L3): num = 9; break; \ - case(HEADER_TYPE_TCP): num = 10; break; \ - case(HEADER_TYPE_UDP): num = 11; break; \ - case(HEADER_TYPE_IPSEC_AH): \ - case(HEADER_TYPE_IPSEC_ESP): num = 12; break; \ - case(HEADER_TYPE_SCTP): num = 13; break; \ - case(HEADER_TYPE_DCCP): num = 14; break; \ - case(HEADER_TYPE_USER_DEFINED_L4): num = 15; break; \ - case(HEADER_TYPE_USER_DEFINED_SHIM1): \ - case(HEADER_TYPE_USER_DEFINED_SHIM2): \ - case(HEADER_TYPE_MACSEC): \ - num = NO_HDR_NUM; break; \ - default: \ - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header for parser"));\ - num = ILLEGAL_HDR_NUM; break; \ -} - -/***********************************************************************/ -/* Policer defines */ -/***********************************************************************/ -#define FM_PCD_PLCR_PAR_GO 0x80000000 -#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF -#define FM_PCD_PLCR_PAR_R 0x40000000 - -/* shifts */ -#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16 - - -/***********************************************************************/ -/* Keygen defines */ -/***********************************************************************/ -/* maskes */ -#define KG_SCH_PP_SHIFT_HIGH 0x80000000 -#define KG_SCH_PP_NO_GEN 0x10000000 -#define KG_SCH_PP_SHIFT_LOW 0x0000F000 -#define KG_SCH_MODE_NIA_PLCR 0x40000000 -#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 -#define KG_SCH_BITMASK_MASK 0x000000FF -#define KG_SCH_GEN_VALID 0x80000000 -#define KG_SCH_GEN_MASK 0x00FF0000 -#define FM_PCD_KG_KGAR_ERR 0x20000000 -#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000 -#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000 -#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000 -#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000 -#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00 -#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000 -#define KG_SCH_HASH_CONFIG_SYM 0x40000000 - -#define FM_PCD_KG_KGAR_GO 0x80000000 -#define FM_PCD_KG_KGAR_READ 0x40000000 -#define FM_PCD_KG_KGAR_WRITE 0x00000000 -#define FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000 -#define FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT 0x00008000 - - -typedef uint32_t t_KnownFieldsMasks; - -#define KG_SCH_KN_PORT_ID 0x80000000 -#define KG_SCH_KN_MACDST 0x40000000 -#define KG_SCH_KN_MACSRC 0x20000000 -#define KG_SCH_KN_TCI1 0x10000000 -#define KG_SCH_KN_TCI2 0x08000000 -#define KG_SCH_KN_ETYPE 0x04000000 -#define KG_SCH_KN_PPPSID 0x02000000 -#define KG_SCH_KN_PPPID 0x01000000 -#define KG_SCH_KN_MPLS1 0x00800000 -#define KG_SCH_KN_MPLS2 0x00400000 -#define KG_SCH_KN_MPLS_LAST 0x00200000 -#define KG_SCH_KN_IPSRC1 0x00100000 -#define KG_SCH_KN_IPDST1 0x00080000 -#define KG_SCH_KN_PTYPE1 0x00040000 -#define KG_SCH_KN_IPTOS_TC1 0x00020000 -#define KG_SCH_KN_IPV6FL1 0x00010000 -#define KG_SCH_KN_IPSRC2 0x00008000 -#define KG_SCH_KN_IPDST2 0x00004000 -#define KG_SCH_KN_PTYPE2 0x00002000 -#define KG_SCH_KN_IPTOS_TC2 0x00001000 -#define KG_SCH_KN_IPV6FL2 0x00000800 -#define KG_SCH_KN_GREPTYPE 0x00000400 -#define KG_SCH_KN_IPSEC_SPI 0x00000200 -#define KG_SCH_KN_IPSEC_NH 0x00000100 -#define KG_SCH_KN_L4PSRC 0x00000004 -#define KG_SCH_KN_L4PDST 0x00000002 -#define KG_SCH_KN_TFLG 0x00000001 - -typedef uint8_t t_GenericCodes; - -#define KG_SCH_GEN_SHIM1 0x70 -#define KG_SCH_GEN_DEFAULT 0x10 -#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20 -#define KG_SCH_GEN_START_OF_FRM 0x40 -#define KG_SCH_GEN_SHIM2 0x71 -#define KG_SCH_GEN_IP_PID_NO_V 0x72 -#define KG_SCH_GEN_ETH 0x03 -#define KG_SCH_GEN_ETH_NO_V 0x73 -#define KG_SCH_GEN_SNAP 0x04 -#define KG_SCH_GEN_SNAP_NO_V 0x74 -#define KG_SCH_GEN_VLAN1 0x05 -#define KG_SCH_GEN_VLAN1_NO_V 0x75 -#define KG_SCH_GEN_VLAN2 0x06 -#define KG_SCH_GEN_VLAN2_NO_V 0x76 -#define KG_SCH_GEN_ETH_TYPE 0x07 -#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77 -#define KG_SCH_GEN_PPP 0x08 -#define KG_SCH_GEN_PPP_NO_V 0x78 -#define KG_SCH_GEN_MPLS1 0x09 -#define KG_SCH_GEN_MPLS2 0x19 -#define KG_SCH_GEN_MPLS3 0x29 -#define KG_SCH_GEN_MPLS1_NO_V 0x79 -#define KG_SCH_GEN_MPLS_LAST 0x0a -#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a -#define KG_SCH_GEN_IPV4 0x0b -#define KG_SCH_GEN_IPV6 0x1b -#define KG_SCH_GEN_L3_NO_V 0x7b -#define KG_SCH_GEN_IPV4_TUNNELED 0x0c -#define KG_SCH_GEN_IPV6_TUNNELED 0x1c -#define KG_SCH_GEN_MIN_ENCAP 0x2c -#define KG_SCH_GEN_IP2_NO_V 0x7c -#define KG_SCH_GEN_GRE 0x0d -#define KG_SCH_GEN_GRE_NO_V 0x7d -#define KG_SCH_GEN_TCP 0x0e -#define KG_SCH_GEN_UDP 0x1e -#define KG_SCH_GEN_IPSEC_AH 0x2e -#define KG_SCH_GEN_SCTP 0x3e -#define KG_SCH_GEN_DCCP 0x4e -#define KG_SCH_GEN_IPSEC_ESP 0x6e -#define KG_SCH_GEN_L4_NO_V 0x7e -#define KG_SCH_GEN_NEXTHDR 0x7f - -/* shifts */ -#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27 -#define KG_SCH_PP_SHIFT_LOW_SHIFT 12 -#define KG_SCH_PP_MASK_SHIFT 16 -#define KG_SCH_MODE_CCOBASE_SHIFT 24 -#define KG_SCH_DEF_MAC_ADDR_SHIFT 30 -#define KG_SCH_DEF_TCI_SHIFT 28 -#define KG_SCH_DEF_ENET_TYPE_SHIFT 26 -#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24 -#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22 -#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20 -#define KG_SCH_DEF_IP_ADDR_SHIFT 18 -#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16 -#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14 -#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12 -#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10 -#define KG_SCH_DEF_L4_PORT_SHIFT 8 -#define KG_SCH_DEF_TCP_FLAG_SHIFT 6 -#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24 -#define KG_SCH_GEN_MASK_SHIFT 16 -#define KG_SCH_GEN_HT_SHIFT 8 -#define KG_SCH_GEN_SIZE_SHIFT 24 -#define KG_SCH_GEN_DEF_SHIFT 29 -#define FM_PCD_KG_KGAR_NUM_SHIFT 16 - - -/* others */ -#define NUM_OF_SW_DEFAULTS 3 -#define MAX_PP_SHIFT 15 -#define MAX_KG_SCH_SIZE 16 -#define MASK_FOR_GENERIC_BASE_ID 0x20 -#define MAX_HASH_SHIFT 40 -#define MAX_KG_SCH_FQID_BIT_OFFSET 31 -#define MAX_KG_SCH_PP_BIT_OFFSET 15 -#define MAX_DIST_FQID_SHIFT 23 - -#define GET_MASK_SEL_SHIFT(shift,i) \ -switch(i) { \ - case(0):shift = 26;break; \ - case(1):shift = 20;break; \ - case(2):shift = 10;break; \ - case(3):shift = 4;break; \ - default: \ - RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\ -} - -#define GET_MASK_OFFSET_SHIFT(shift,i) \ -switch(i) { \ - case(0):shift = 16;break; \ - case(1):shift = 0;break; \ - case(2):shift = 28;break; \ - case(3):shift = 24;break; \ - default: \ - RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\ -} - -#define GET_MASK_SHIFT(shift,i) \ -switch(i) { \ - case(0):shift = 24;break; \ - case(1):shift = 16;break; \ - case(2):shift = 8;break; \ - case(3):shift = 0;break; \ - default: \ - RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\ +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr) +{ + switch (hdr) + { case (HEADER_TYPE_ETH): return 0; + case (HEADER_TYPE_LLC_SNAP): return 1; + case (HEADER_TYPE_VLAN): return 2; + case (HEADER_TYPE_PPPoE): return 3; + case (HEADER_TYPE_PPP): return 3; + case (HEADER_TYPE_MPLS): return 4; + case (HEADER_TYPE_IPv4): return 5; + case (HEADER_TYPE_IPv6): return 6; + case (HEADER_TYPE_GRE): return 7; + case (HEADER_TYPE_MINENCAP): return 8; + case (HEADER_TYPE_USER_DEFINED_L3): return 9; + case (HEADER_TYPE_TCP): return 10; + case (HEADER_TYPE_UDP): return 11; + case (HEADER_TYPE_IPSEC_AH): + case (HEADER_TYPE_IPSEC_ESP): return 12; + case (HEADER_TYPE_SCTP): return 13; + case (HEADER_TYPE_DCCP): return 14; + case (HEADER_TYPE_USER_DEFINED_L4): return 15; + case (HEADER_TYPE_USER_DEFINED_SHIM1): + case (HEADER_TYPE_USER_DEFINED_SHIM2): + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM; + default: + return ILLEGAL_HDR_NUM; + } } #define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0)))) -typedef struct { - uint16_t num; - uint8_t hardwarePortId; - uint16_t plcrProfilesBase; -} t_FmPortPcdInterModulePlcrParams; /**************************************************************************//** @Description A structure for initializing a keygen classification plan group @@ -707,93 +658,88 @@ typedef struct t_FmPcdKgInterModuleClsPlanGrpParams { /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/ } t_FmPcdKgInterModuleClsPlanGrpParams; -typedef struct t_FmInterModulePortRxPoolsParams -{ - uint8_t numOfPools; - uint16_t secondLargestBufSize; - uint16_t largestBufSize; -} t_FmInterModulePortRxPoolsParams; +typedef struct t_FmPcdLock { + t_Handle h_Spinlock; + volatile bool flag; + t_List node; +} t_FmPcdLock; +#define FM_PCD_LOCK_OBJ(ptr) NCSW_LIST_OBJECT(ptr, t_FmPcdLock, node) typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams); +/***********************************************************************/ +/* Common API for FM-PCD module */ +/***********************************************************************/ t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd); uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr); uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum); uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId); void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId); void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId); +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv); void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId); uint32_t FmPcdLock(t_Handle h_FmPcd); void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags); bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); -bool FmPcdIsIpFrag(t_Handle h_FmPcd, uint8_t netEnvId); - -t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params); -uint32_t FmPcdCcGetNodeAddrOffset(t_Handle h_FmPcd, t_Handle h_Pointer); -t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams); -t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_Params); -t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams); -t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams); -t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams); -t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams); -t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams); -uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer); -t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree); -t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List); -void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree); -void FmPcdCcNodeTreeReleaseLock(t_List *p_List); -t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx); -void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t manipIndx); - -bool FmPcdKgIsSchemeValidSw(t_Handle h_FmPcd, uint8_t schemeId); +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid); +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl); +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl); +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd); +bool FmPcdLockTryLockAll(t_Handle h_FmPcd); +void FmPcdLockUnlockAll(t_Handle h_FmPcd); +t_Error FmPcdHcSync(t_Handle h_FmPcd); +t_Handle FmGetPcd(t_Handle h_Fm); +/***********************************************************************/ +/* Common API for FM-PCD KG module */ +/***********************************************************************/ uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp); uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp); - -t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t_FmPcdKgInterModuleSchemeRegs *p_SchemeRegs); t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet); -uint8_t FmPcdKgGetNumOfPartitionSchemes(t_Handle h_FmPcd); -uint8_t FmPcdKgGetPhysicalSchemeId(t_Handle h_FmPcd, uint8_t schemeId); + +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme); +#if (DPAA_VERSION >= 11) +bool FmPcdKgGetVspe(t_Handle h_Scheme); +#endif /* (DPAA_VERSION >= 11) */ uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId); void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId); -void FmPcdKgValidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId); -void FmPcdKgInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId); -t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId); +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme); t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add); -void FmPcdKgIncSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort); -void FmPcdKgDecSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort); -bool FmPcdKgIsDriverClsPlan(t_Handle h_FmPcd); bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg); -uint32_t FmPcdKgBuildCppReg(t_Handle h_FmPcd, uint8_t clsPlanGrpId); uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter); uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId); uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId); -uint32_t FmPcdKgBuildReadClsPlanBlockActionReg(uint8_t grpId); uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId); uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId); uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId); -uint8_t FmPcdKgGetSchemeSwId(t_Handle h_FmPcd, uint8_t schemeHwId); -t_Error FmPcdKgSchemeTryLock(t_Handle h_FmPcd, uint8_t schemeId, bool intr); -void FmPcdKgReleaseSchemeLock(t_Handle h_FmPcd, uint8_t schemeId); -void FmPcdKgUpatePointedOwner(t_Handle h_FmPcd, uint8_t schemeId, bool add); +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme); t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind); t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind); uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId); -uint32_t FmPcdKgGetPointedOwners(t_Handle h_FmPcd, uint8_t schemeId); +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId); e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId); e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId); -void FmPcdKgUpdateRequiredAction(t_Handle h_FmPcd, uint8_t schemeId, uint32_t requiredAction); +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction); bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId); bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId); uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId); +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId); +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme); +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value); +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp); +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId); -/* FM-PCD parser API routines */ +/***********************************************************************/ +/* Common API for FM-PCD parser module */ +/***********************************************************************/ t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include); -/* FM-PCD policer API routines */ +/***********************************************************************/ +/* Common API for FM-PCD policer module */ +/***********************************************************************/ t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles); t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId); bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId); @@ -803,8 +749,8 @@ uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId); uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter); uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId); uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId); -t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile, t_FmPcdPlcrInterModuleProfileRegs *p_PlcrRegs); -t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd, +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile); +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd, e_FmPcdProfileTypeSelection profileType, t_Handle h_FmPort, uint16_t relativeProfile, @@ -812,36 +758,60 @@ t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd, void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg); -t_Error FmPcdPlcrProfileTryLock(t_Handle h_FmPcd, uint16_t profileId, bool intr); -void FmPcdPlcrReleaseProfileLock(t_Handle h_FmPcd, uint16_t profileId); uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId); -uint32_t FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId); -void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add); +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId); uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red); void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction); +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction); -/* FM-PCD Coarse-Classification API routines */ +/***********************************************************************/ +/* Common API for FM-PCD CC module */ +/***********************************************************************/ uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode); uint8_t FmPcdCcGetOffset(t_Handle h_CcNode); - -t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify); -t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams); -uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip); -t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort); +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex); +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams); +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask); +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams); +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer); +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree); +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams); +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes); +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes); +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort); t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree); -t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction); -t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction); +/***********************************************************************/ +/* Common API for FM-PCD Manip module */ +/***********************************************************************/ +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify); +/***********************************************************************/ +/* Common API for FM-Port module */ +/***********************************************************************/ +#if (DPAA_VERSION >= 11) +typedef enum e_FmPortGprFuncType +{ + e_FM_PORT_GPR_EMPTY = 0, + e_FM_PORT_GPR_MURAM_PAGE +} e_FmPortGprFuncType; + +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value); +#endif /* DPAA_VERSION >= 11) */ +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams); +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams); uint8_t FmPortGetNetEnvId(t_Handle h_FmPort); uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort); uint32_t FmPortGetPcdEngines(t_Handle h_FmPort); void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort); -t_Error FmPortAttachPCD(t_Handle h_FmPort); -t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp); -t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId); +#if (DPAA_VERSION >= 11) +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic); +#endif /* (DPAA_VERSION >= 11) */ + /**************************************************************************//** @Function FmRegisterIntr @@ -857,7 +827,7 @@ t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hard @Return None. *//***************************************************************************/ -void FmRegisterIntr(t_Handle h_Fm, +void FmRegisterIntr(t_Handle h_Fm, e_FmEventModules mod, uint8_t modId, e_FmIntrType intrType, @@ -926,6 +896,7 @@ typedef struct t_FmInterModulePortInitParams { uint32_t sizeOfFifo; /**< IN. Port's requested resource */ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ + uint16_t maxFrameLength; /**< IN. Port's max frame length. */ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1. LIODN base for this port, to be used together with LIODN offset. */ @@ -938,9 +909,7 @@ typedef struct t_FmInterModulePortInitParams { typedef struct t_FmInterModulePortFreeParams { uint8_t hardwarePortId; /**< IN. port Id */ e_FmPortType portType; /**< IN. Port type */ -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ } t_FmInterModulePortFreeParams; /**************************************************************************//** @@ -1005,13 +974,17 @@ void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr); @Description Used internally by other modules in order to get the timeStamp period as requested by the application. + This function returns bit number that is incremented every 1 usec. + To calculate timestamp period in nsec, use + 1000 / (1 << FmGetTimeStampScale()). + @Param[in] h_Fm A handle to an FM Module. - @Return TimeStamp period in nanoseconds. + @Return Bit that counts 1 usec. @Cautions Allowed only following FM_Init(). *//***************************************************************************/ -uint32_t FmGetTimeStampScale(t_Handle h_Fm); +uint32_t FmGetTimeStampScale(t_Handle h_Fm); /**************************************************************************//** @Function FmResumeStalledPort @@ -1070,6 +1043,19 @@ t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId); *//***************************************************************************/ uint16_t FmGetClockFreq(t_Handle h_Fm); +/**************************************************************************//** + @Function FmGetMacClockFreq + + @Description Used by MAC driver to get the MAC clock frequency + + @Param[in] h_Fm A handle to an FM Module. + + @Return clock-freq on success; 0 otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +uint16_t FmGetMacClockFreq(t_Handle h_Fm); + /**************************************************************************//** @Function FmGetId @@ -1083,6 +1069,17 @@ uint16_t FmGetClockFreq(t_Handle h_Fm); *//***************************************************************************/ uint8_t FmGetId(t_Handle h_Fm); +/**************************************************************************//** + @Function FmReset + + @Description Used to reset the FM + + @Param[in] h_Fm A handle to an FM Module. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FmReset(t_Handle h_Fm); + /**************************************************************************//** @Function FmGetSetPortParams @@ -1113,25 +1110,41 @@ t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortPa void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams); /**************************************************************************//** - @Function FmSetPortToWorkWithOneRiscOnly + @Function FmSetNumOfRiscsPerPort @Description Used by FM-PORT driver to pass parameter between PORT and FM modules for working with number of RISC.. @Param[in] h_Fm A handle to an FM Module. - @Param[in,out] p_PortParams A structure of FM Port parameters. + @Param[in] hardwarePortId hardware port Id. + @Param[in] numOfFmanCtrls number of Fman Controllers. + @Param[in] orFmanCtrl Fman Controller for order restoration. @Return None. @Cautions Allowed only following FM_Init(). *//***************************************************************************/ -t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls); +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl); +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) +/**************************************************************************//* + @Function FmDumpPortRegs + + @Description Dumps FM port registers which are part of FM common registers + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] hardwarePortId HW port id. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only FM_Init(). +*//***************************************************************************/ +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId); +#endif /* (defined(DEBUG_ERRORS) && ... */ void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd); void FmUnregisterPcd(t_Handle h_Fm); t_Handle FmGetPcdHandle(t_Handle h_Fm); -bool FmRamsEccIsExternalCtl(t_Handle h_Fm); t_Error FmEnableRamsEcc(t_Handle h_Fm); t_Error FmDisableRamsEcc(t_Handle h_Fm); void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo); @@ -1144,30 +1157,58 @@ void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId); t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu); bool FmIsMaster(t_Handle h_Fm); uint8_t FmGetGuestId(t_Handle h_Fm); +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm); +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured); +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured); + + #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId); #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ void FmMuramClear(t_Handle h_FmMuram); t_Error FmSetNumOfOpenDmas(t_Handle h_Fm, - uint8_t hardwarePortId, - uint8_t numOfOpenDmas, - uint8_t numOfExtraOpenDmas, - bool initialConfig); + uint8_t hardwarePortId, + uint8_t *p_NumOfOpenDmas, + uint8_t *p_NumOfExtraOpenDmas, + bool initialConfig); t_Error FmSetNumOfTasks(t_Handle h_Fm, - uint8_t hardwarePortId, - uint8_t numOfTasks, - uint8_t numOfExtraTasks, - bool initialConfig); -t_Error FmSetSizeOfFifo(t_Handle h_Fm, - uint8_t hardwarePortId, - e_FmPortType portType, - bool independentMode, - uint32_t *p_SizeOfFifo, - uint32_t extraSizeOfFifo, - uint8_t deqPipelineDepth, - t_FmInterModulePortRxPoolsParams *p_RxPoolsParams, - bool initialConfig); + uint8_t hardwarePortId, + uint8_t *p_NumOfTasks, + uint8_t *p_NumOfExtraTasks, + bool initialConfig); +t_Error FmSetSizeOfFifo(t_Handle h_Fm, + uint8_t hardwarePortId, + uint32_t *p_SizeOfFifo, + uint32_t *p_ExtraSizeOfFifo, + bool initialConfig); + +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm, + uint32_t congestionGroupId, + uint8_t priorityBitMap); + +#if (DPAA_VERSION >= 11) +t_Error FmVSPAllocForPort(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint8_t numOfStorageProfiles); + +t_Error FmVSPFreeForPort(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId); + +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint16_t relativeProfile, + uint16_t *p_AbsoluteId); +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm, + e_FmPortType portType, + uint8_t portId, + uint16_t relativeProfile); + +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm); +#endif /* (DPAA_VERSION >= 11) */ #endif /* __FM_COMMON_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h b/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h index bbcc83c6e46a..492aa8a3aa78 100644 --- a/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h +++ b/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,12 +30,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __FM_HC_H #define __FM_HC_H #include "std_ext.h" #include "error_ext.h" - +#include "fsl_fman_kg.h" #define __ERR_MODULE__ MODULE_FM_PCD @@ -49,28 +50,29 @@ typedef struct t_FmHcParams { t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams); void FmHcFree(t_Handle h_FmHc); +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc, + uint8_t memId); t_Error FmHcDumpRegs(t_Handle h_FmHc); void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd); -t_Handle FmHcPcdKgSetScheme(t_Handle h_FmHc, t_FmPcdKgSchemeParams *p_Scheme); +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc, + t_Handle h_Scheme, + struct fman_kg_scheme_regs *p_SchemeRegs, + bool updateCounter); t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme); t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams ); +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams); +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result); t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set); t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId); t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value); uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme); -t_Error FmHcPcdCcModifyTreeNextEngine(t_Handle h_FmHc, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -t_Error FmHcPcdCcModifyNodeNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -t_Error FmHcPcdCcModifyNodeMissNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -t_Error FmHcPcdCcRemoveKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex); -t_Error FmHcPcdCcAddKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams); -t_Error FmHcPcdCcModifyKeyAndNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams); -t_Error FmHcPcdCcModifyKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask); +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset); -t_Handle FmHcPcdPlcrSetProfile(t_Handle h_FmHc,t_FmPcdPlcrProfileParams *p_Profile); +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs); t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile); t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value); @@ -79,8 +81,13 @@ uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_ t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add); t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg); -t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction); +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value); t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction); +t_Error FmHcPcdSync(t_Handle h_FmHc); +t_Handle FmHcGetPort(t_Handle h_FmHc); + + + #endif /* __FM_HC_H */ diff --git a/sys/contrib/ncsw/Peripherals/FM/inc/fm_sp_common.h b/sys/contrib/ncsw/Peripherals/FM/inc/fm_sp_common.h new file mode 100644 index 000000000000..f9dd384bb685 --- /dev/null +++ b/sys/contrib/ncsw/Peripherals/FM/inc/fm_sp_common.h @@ -0,0 +1,117 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/****************************************************************************** + @File fm_sp_common.h + + @Description FM SP ... +*//***************************************************************************/ +#ifndef __FM_SP_COMMON_H +#define __FM_SP_COMMON_H + +#include "std_ext.h" +#include "error_ext.h" +#include "list_ext.h" + +#include "fm_ext.h" +#include "fm_pcd_ext.h" +#include "fsl_fman.h" + +/**************************************************************************//** + @Description defaults +*//***************************************************************************/ +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64 + +/**************************************************************************//** + @Description structure for defining internal context copying +*//***************************************************************************/ +typedef struct +{ + uint16_t extBufOffset; /**< Offset in External buffer to which internal + context is copied to (Rx) or taken from (Tx, Op). */ + uint8_t intContextOffset; /**< Offset within internal context to copy from + (Rx) or to copy to (Tx, Op). */ + uint16_t size; /**< Internal offset size to be copied */ +} t_FmSpIntContextDataCopy; + +/**************************************************************************//** + @Description struct for defining external buffer margins +*//***************************************************************************/ +typedef struct { + uint16_t startMargins; /**< Number of bytes to be left at the beginning + of the external buffer (must be divisible by 16) */ + uint16_t endMargins; /**< number of bytes to be left at the end + of the external buffer(must be divisible by 16) */ +} t_FmSpBufMargins; + +typedef struct { + uint32_t dataOffset; + uint32_t prsResultOffset; + uint32_t timeStampOffset; + uint32_t hashResultOffset; + uint32_t pcdInfoOffset; + uint32_t manipOffset; +} t_FmSpBufferOffsets; + + +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy, + t_FmBufferPrefixContent *p_BufferPrefixContent, + t_FmSpBufMargins *p_FmPortBufMargins, + t_FmSpBufferOffsets *p_FmPortBufferOffsets, + uint8_t *internalBufferOffset); + +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy); +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools, + t_FmBackupBmPools *p_FmBackupBmPools, + t_FmBufPoolDepletion *p_FmBufPoolDepletion); +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins); +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray); + +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd, + uint8_t hardwarePortId, + uint16_t numOfStorageProfiles, + uint16_t *base, + uint8_t *log2Num); +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd, + t_Handle h_FmPort, + uint16_t relativeProfile, + uint16_t *p_AbsoluteId); +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); + + +#endif /* __FM_SP_COMMON_H */ diff --git a/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h b/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h index 42573f6964a2..bcb2c243a258 100644 --- a/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h +++ b/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h @@ -117,7 +117,7 @@ struct qm_portal_config { * affinity configured. */ int cpu; /* portal interrupt line */ - int irq; + uintptr_t irq; /* The portal's dedicated channel id, use this value for initializing * frame queues to target this portal when scheduled. */ e_QmFQChannel channel; diff --git a/sys/contrib/ncsw/Peripherals/QM/qm.c b/sys/contrib/ncsw/Peripherals/QM/qm.c index d1d7032f882b..50b74712e266 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qm.c +++ b/sys/contrib/ncsw/Peripherals/QM/qm.c @@ -38,6 +38,10 @@ @Description QM & Portal implementation *//***************************************************************************/ + +#include +#include +#include #include "error_ext.h" #include "std_ext.h" #include "string_ext.h" @@ -209,7 +213,7 @@ static t_Error QmInitPfdr(t_Qm *p_Qm, uint32_t pfdr_start, uint32_t num) WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 16)); WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 1)); - CORE_MemoryBarrier(); + mb(); WRITE_UINT32(p_Qm->p_QmRegs->mcr, MCR_INIT_PFDR); /* Poll for the result */ @@ -556,6 +560,7 @@ uint32_t QmFqidGet(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, ui "QM FQID MEM"); XX_UnlockIntrSpinlock(p_Qm->lock, intFlags); + KASSERT(ans < UINT32_MAX, ("Oops, %lx > UINT32_MAX!\n", ans)); return (uint32_t)ans; } @@ -784,10 +789,10 @@ t_Error QM_Init(t_Handle h_Qm) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQD obj!!!")); } memset(p_Qm->p_FqdBase, 0, dsSize); - CORE_MemoryBarrier(); + mb(); for (i=0; ip_FqdBase, i)); - CORE_MemoryBarrier(); + mb(); phyAddr = XX_VirtToPhys(p_Qm->p_FqdBase); WRITE_UINT32(p_Qm->p_QmRegs->fqd_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff)); diff --git a/sys/contrib/ncsw/Peripherals/QM/qm.h b/sys/contrib/ncsw/Peripherals/QM/qm.h index 68af1855b96a..a004dc55a67d 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qm.h +++ b/sys/contrib/ncsw/Peripherals/QM/qm.h @@ -482,7 +482,7 @@ typedef struct { uint32_t exceptions; t_QmExceptionsCallback *f_Exception; t_Handle h_App; - int errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */ + uintptr_t errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */ uint32_t numOfPfdr; uint16_t partNumOfCgs; uint16_t partCgsBase; diff --git a/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c index f1c23ac74671..605d09aeb1aa 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c +++ b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c @@ -38,6 +38,10 @@ @Description QM & Portal implementation *//***************************************************************************/ +#include +#include +#include + #include "error_ext.h" #include "std_ext.h" #include "string_ext.h" @@ -45,6 +49,7 @@ #include "qm.h" #include "qman_low.h" +#include /****************************************/ /* static functions */ @@ -53,6 +58,40 @@ #define SLOW_POLL_IDLE 1000 #define SLOW_POLL_BUSY 10 +/* + * Context entries are 32-bit. The qman driver uses the pointer to the queue as + * its context, and the pointer is 64-byte aligned, per the XX_MallocSmart() + * call. Take advantage of this fact to shove a 64-bit kernel pointer into a + * 32-bit context integer, and back. + * + * XXX: This depends on the fact that VM_MAX_KERNEL_ADDRESS is less than 38-bit + * count from VM_MIN_KERNEL_ADDRESS. If this ever changes, this needs to be + * updated. + */ +CTASSERT((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) < (1ULL << 35)); +static inline uint32_t +aligned_int_from_ptr(const void *p) +{ + uintptr_t ctx; + + ctx = (uintptr_t)p; + KASSERT(ctx >= VM_MIN_KERNEL_ADDRESS, ("%p is too low!\n", p)); + ctx -= VM_MIN_KERNEL_ADDRESS; + KASSERT((ctx & 0x07) == 0, ("Pointer %p is not 8-byte aligned!\n", p)); + + return (ctx >> 3); +} + +static inline void * +ptr_from_aligned_int(uint32_t ctx) +{ + uintptr_t p; + + p = ctx; + p = VM_MIN_KERNEL_ADDRESS + (p << 3); + + return ((void *)p); +} static t_Error qman_volatile_dequeue(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq, @@ -259,7 +298,7 @@ static t_Error qman_retire_fq(t_QmPortal *p_QmPortal, p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal); p_Mcc->alterfq.fqid = p_Fq->fqid; if (drain) - p_Mcc->alterfq.context_b = (uint32_t)PTR_TO_UINT(p_Fq); + p_Mcc->alterfq.context_b = aligned_int_from_ptr(p_Fq); qm_mc_commit(p_QmPortal->p_LowQmPortal, (uint8_t)((drain)?QM_MCC_VERB_ALTER_RETIRE_CTXB:QM_MCC_VERB_ALTER_RETIRE)); while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ; @@ -568,8 +607,8 @@ static uint32_t LoopMessageRing(t_QmPortal *p_QmPortal, uint32_t is) qmPortalMrPvbUpdate(p_QmPortal->p_LowQmPortal); p_Msg = qm_mr_current(p_QmPortal->p_LowQmPortal); if (p_Msg) { - struct qman_fq *p_FqFqs = UINT_TO_PTR(p_Msg->fq.contextB); - struct qman_fq *p_FqErn = UINT_TO_PTR(p_Msg->ern.tag); + struct qman_fq *p_FqFqs = ptr_from_aligned_int(p_Msg->fq.contextB); + struct qman_fq *p_FqErn = ptr_from_aligned_int(p_Msg->ern.tag); uint8_t verb =(uint8_t)(p_Msg->verb & QM_MR_VERB_TYPE_MASK); t_QmRejectedFrameInfo rejectedFrameInfo; @@ -646,7 +685,7 @@ static void LoopDequeueRing(t_Handle h_QmPortal) p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal); if (!p_Dq) break; - p_Fq = UINT_TO_PTR(p_Dq->contextB); + p_Fq = ptr_from_aligned_int(p_Dq->contextB); if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) { /* We only set QMAN_FQ_STATE_NE when retiring, so we only need * to check for clearing it when doing volatile dequeues. It's @@ -728,7 +767,7 @@ static void LoopDequeueRingDcaOptimized(t_Handle h_QmPortal) p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal); if (!p_Dq) break; - p_Fq = UINT_TO_PTR(p_Dq->contextB); + p_Fq = ptr_from_aligned_int(p_Dq->contextB); if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) { /* We only set QMAN_FQ_STATE_NE when retiring, so we only need * to check for clearing it when doing volatile dequeues. It's @@ -802,7 +841,7 @@ static void LoopDequeueRingOptimized(t_Handle h_QmPortal) p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal); if (!p_Dq) break; - p_Fq = UINT_TO_PTR(p_Dq->contextB); + p_Fq = ptr_from_aligned_int(p_Dq->contextB); if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) { /* We only set QMAN_FQ_STATE_NE when retiring, so we only need * to check for clearing it when doing volatile dequeues. It's @@ -1023,13 +1062,8 @@ static t_Error qm_new_fq(t_QmPortal *p_QmPortal, /* If this FQ will not be used for tx, we can use contextB field */ if (fq_opts.fqd.dest.channel < e_QM_FQ_CHANNEL_FMAN0_SP0) { - if (sizeof(p_Fqs[0]) <= sizeof(fq_opts.fqd.context_b)) - { fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTB; - fq_opts.fqd.context_b = (uint32_t)PTR_TO_UINT(p_Fqs[0]); - } - else - RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("64 bit pointer (virtual) not supported yet!!!")); + fq_opts.fqd.context_b = aligned_int_from_ptr(p_Fqs[0]); } else if (p_ContextB) /* Tx-Queue */ { @@ -1102,7 +1136,7 @@ static t_Error qm_free_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq) { uint32_t flags=0; - if (qman_retire_fq(p_QmPortal, p_Fq, &flags, FALSE) != E_OK) + if (qman_retire_fq(p_QmPortal, p_Fq, &flags, false) != E_OK) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!")); if (flags & QMAN_FQ_STATE_CHANGING) @@ -1471,7 +1505,7 @@ static t_Error QmPortalPullFrame(t_Handle h_QmPortal, uint32_t pdqcr, t_DpaaFD * NCSW_PLOCK(p_QmPortal); qm_dqrr_pdqcr_set(p_QmPortal->p_LowQmPortal, pdqcr); - CORE_MemoryBarrier(); + mb(); while (qm_dqrr_pdqcr_get(p_QmPortal->p_LowQmPortal)) ; prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH); @@ -1483,7 +1517,7 @@ static t_Error QmPortalPullFrame(t_Handle h_QmPortal, uint32_t pdqcr, t_DpaaFD * p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal); if (!p_Dq) continue; - p_Fq = UINT_TO_PTR(p_Dq->contextB); + p_Fq = ptr_from_aligned_int(p_Dq->contextB); ASSERT_COND(p_Dq->fqid); p_Dst = (uint32_t *)p_Frame; p_Src = (uint32_t *)&p_Dq->fd; @@ -1495,7 +1529,7 @@ static t_Error QmPortalPullFrame(t_Handle h_QmPortal, uint32_t pdqcr, t_DpaaFD * { qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal, p_Dq, - FALSE); + false); qm_dqrr_next(p_QmPortal->p_LowQmPortal); } else @@ -1811,7 +1845,7 @@ t_Error QM_PORTAL_PollFrame(t_Handle h_QmPortal, t_QmPortalFrameInfo *p_frameInf PUNLOCK(p_QmPortal); return ERROR_CODE(E_EMPTY); } - p_Fq = UINT_TO_PTR(p_Dq->contextB); + p_Fq = ptr_from_aligned_int(p_Dq->contextB); ASSERT_COND(p_Dq->fqid); if (p_Fq) { @@ -1830,7 +1864,7 @@ t_Error QM_PORTAL_PollFrame(t_Handle h_QmPortal, t_QmPortalFrameInfo *p_frameInf if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA) { qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal, p_Dq, - FALSE); + false); qm_dqrr_next(p_QmPortal->p_LowQmPortal); } else { qm_dqrr_next(p_QmPortal->p_LowQmPortal); @@ -2064,7 +2098,7 @@ t_Error QM_FQR_FreeWDrain(t_Handle h_QmFqr, for (i=0;inumOfFqids;i++) { - if (qman_retire_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i], 0, TRUE) != E_OK) + if (qman_retire_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i], 0, true) != E_OK) RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!")); if (p_QmFqr->p_Fqs[i]->flags & QMAN_FQ_STATE_CHANGING) @@ -2141,7 +2175,7 @@ t_Error QM_FQR_Enqueue(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffse } p_Eq->fqid = p_Fq->fqid; - p_Eq->tag = (uintptr_t)p_Fq; + p_Eq->tag = aligned_int_from_ptr(p_Fq); /* gcc does a dreadful job of the following; * eq->fd = *fd; * It causes the entire function to save/restore a wider range of diff --git a/sys/contrib/ncsw/Peripherals/QM/qman_low.h b/sys/contrib/ncsw/Peripherals/QM/qman_low.h index 612f4cac8848..1becfc15554a 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qman_low.h +++ b/sys/contrib/ncsw/Peripherals/QM/qman_low.h @@ -96,7 +96,7 @@ static __inline__ void *ptr_ADD(void *a, uintptr_t b) /* Bitwise-OR two pointers */ static __inline__ void *ptr_OR(void *a, uintptr_t b) { - return (void *)((uintptr_t)a + b); + return (void *)((uintptr_t)a | b); } /* Cache-inhibited register access */ @@ -323,7 +323,7 @@ static __inline__ void qmPortalEqcrPciCommit(struct qm_portal *portal, uint8_t m EQCR_INC(eqcr); eqcr->available--; dcbf_64(eqcr->cursor); - hwsync(); + mb(); qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor)); #ifdef QM_CHECKING eqcr->busy = 0; @@ -351,7 +351,7 @@ static __inline__ void qmPortalEqcrPceCommit(struct qm_portal *portal, uint8_t m EQCR_INC(eqcr); eqcr->available--; dcbf_64(eqcr->cursor); - lwsync(); + wmb(); qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor)); #ifdef QM_CHECKING eqcr->busy = 0; @@ -366,7 +366,7 @@ static __inline__ void qmPortalEqcrPvbCommit(struct qm_portal *portal, uint8_t m EQCR_COMMIT_CHECKS(eqcr); ASSERT_COND(eqcr->pmode == e_QmPortalPVB); #endif /* QM_CHECKING */ - lwsync(); + rmb(); eqcursor = eqcr->cursor; eqcursor->__dont_write_directly__verb = (uint8_t)(myverb | eqcr->vbit); dcbf_64(eqcursor); @@ -1086,7 +1086,7 @@ static __inline__ void qm_mc_commit(struct qm_portal *portal, uint8_t myverb) #ifdef QM_CHECKING ASSERT_COND(mc->state == mc_user); #endif /* QM_CHECKING */ - lwsync(); + rmb(); mc->cr->__dont_write_directly__verb = (uint8_t)(myverb | mc->vbit); dcbf_64(mc->cr); dcbit_ro(mc->rr + mc->rridx); diff --git a/sys/contrib/ncsw/Peripherals/QM/qman_private.h b/sys/contrib/ncsw/Peripherals/QM/qman_private.h index 5bab41802f89..0b172879099a 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qman_private.h +++ b/sys/contrib/ncsw/Peripherals/QM/qman_private.h @@ -55,76 +55,13 @@ * and that dcbzl(), dcbfl(), and dcbi() won't fall victim to compiler or * execution reordering with respect to other code/instructions that manipulate * the same cacheline. */ -#ifdef CORE_E500MC - -#if defined(_DIAB_TOOL) -#define hwsync() \ -do { \ -__asm__ __volatile__ ("sync"); \ -} while(0) - -#define lwsync() \ -do { \ -__asm__ __volatile__ ("lwsync"); \ -} while(0) - -__asm__ __volatile__ void dcbf (volatile void * addr) -{ -%reg addr - dcbf r0, addr -} - -__asm__ __volatile__ void dcbt_ro (volatile void * addr) -{ -%reg addr - dcbt r0, addr -} - -__asm__ __volatile__ void dcbt_rw (volatile void * addr) -{ -%reg addr - dcbtst r0, addr -} - -__asm__ __volatile__ void dcbzl (volatile void * addr) -{ -%reg addr - dcbzl r0, addr -} - -#define dcbz_64(p) \ - do { \ - dcbzl(p); \ - } while (0) - -#define dcbf_64(p) \ - do { \ - dcbf(p); \ - } while (0) - -/* Commonly used combo */ -#define dcbit_ro(p) \ - do { \ - dcbi(p); \ - dcbt_ro(p); \ - } while (0) - -#else /* GNU C */ -#define hwsync() \ - do { \ - __asm__ __volatile__ ("sync" : : : "memory"); \ - } while(0) - -#define lwsync() \ - do { \ - __asm__ __volatile__ ("lwsync" : : : "memory"); \ - } while(0) #define dcbf(addr) \ do { \ __asm__ __volatile__ ("dcbf 0, %0" : : "r" (addr)); \ } while(0) +#ifdef CORE_E500MC #define dcbt_ro(addr) \ do { \ __asm__ __volatile__ ("dcbt 0, %0" : : "r" (addr)); \ @@ -157,16 +94,8 @@ __asm__ __volatile__ void dcbzl (volatile void * addr) dcbt_ro(p); \ } while (0) -#endif /* _DIAB_TOOL */ - #else -#define hwsync CORE_MemoryBarrier -#define lwsync hwsync -#define dcbf(p) \ - do { \ - __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p)); \ - } while(0) #define dcbt_ro(p) \ do { \ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)); \ @@ -182,21 +111,21 @@ __asm__ __volatile__ void dcbzl (volatile void * addr) } while (0) #define dcbz_64(p) \ do { \ - dcbz((uint32_t)p + 32); \ + dcbz((char *)p + 32); \ dcbz(p); \ } while (0) #define dcbf_64(p) \ do { \ - dcbf((uint32_t)p + 32); \ + dcbf((char *)p + 32); \ dcbf(p); \ } while (0) /* Commonly used combo */ #define dcbit_ro(p) \ do { \ dcbi(p); \ - dcbi((uint32_t)p + 32); \ + dcbi((char *)p + 32); \ dcbt_ro(p); \ - dcbt_ro((uint32_t)p + 32); \ + dcbt_ro((char *)p + 32); \ } while (0) #endif /* CORE_E500MC */ diff --git a/sys/contrib/ncsw/etc/error.c b/sys/contrib/ncsw/etc/error.c index 896722fe8b5e..fead7f50f2ba 100644 --- a/sys/contrib/ncsw/etc/error.c +++ b/sys/contrib/ncsw/etc/error.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,14 +30,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* @File error.c @Description General errors and events reporting utilities. *//***************************************************************************/ - #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) +#include "error_ext.h" + const char *dbgLevelStrings[] = { @@ -49,70 +51,45 @@ const char *dbgLevelStrings[] = ,"TRACE" }; -const char *errTypeStrings[] = + +char * ErrTypeStrings (e_ErrorType err) { - "Invalid State" /* E_INVALID_STATE */ - ,"Invalid Operation" /* E_INVALID_OPERATION */ - ,"Unsupported Operation" /* E_NOT_SUPPORTED */ - ,"No Device" /* E_NO_DEVICE */ - ,"Invalid Handle" /* E_INVALID_HANDLE */ - ,"Invalid ID" /* E_INVALID_ID */ - ,"Unexpected NULL Pointer" /* E_NULL_POINTER */ - ,"Invalid Value" /* E_INVALID_VALUE */ - ,"Invalid Selection" /* E_INVALID_SELECTION */ - ,"Invalid Communication Mode" /* E_INVALID_COMM_MODE */ - ,"Invalid Byte Order" /* E_INVALID_BYTE_ORDER */ - ,"Invalid Memory Type" /* E_INVALID_MEMORY_TYPE */ - ,"Invalid Interrupt Queue" /* E_INVALID_INTR_QUEUE */ - ,"Invalid Priority" /* E_INVALID_PRIORITY */ - ,"Invalid Clock" /* E_INVALID_CLOCK */ - ,"Invalid Rate" /* E_INVALID_RATE */ - ,"Invalid Address" /* E_INVALID_ADDRESS */ - ,"Invalid Bus" /* E_INVALID_BUS */ - ,"Conflict In Bus Selection" /* E_BUS_CONFLICT */ - ,"Conflict In Settings" /* E_CONFLICT */ - ,"Incorrect Alignment" /* E_NOT_ALIGNED */ - ,"Value Out Of Range" /* E_NOT_IN_RANGE */ - ,"Invalid Frame" /* E_INVALID_FRAME */ - ,"Frame Is Empty" /* E_EMPTY_FRAME */ - ,"Buffer Is Empty" /* E_EMPTY_BUFFER */ - ,"Memory Allocation Failed" /* E_NO_MEMORY */ - ,"Resource Not Found" /* E_NOT_FOUND */ - ,"Resource Is Unavailable" /* E_NOT_AVAILABLE */ - ,"Resource Already Exists" /* E_ALREADY_EXISTS */ - ,"Resource Is Full" /* E_FULL */ - ,"Resource Is Empty" /* E_EMPTY */ - ,"Resource Is Busy" /* E_BUSY */ - ,"Resource Already Free" /* E_ALREADY_FREE */ - ,"Read Access Failed" /* E_READ_FAILED */ - ,"Write Access Failed" /* E_WRITE_FAILED */ - ,"Send Operation Failed" /* E_SEND_FAILED */ - ,"Receive Operation Failed" /* E_RECEIVE_FAILED */ - ,"Operation Timed Out" /* E_TIMEOUT */ -}; - - -#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) - -const char *eventStrings[] = -{ - "Rx Discard" /* EV_RX_DISCARD */ - ,"Rx Error" /* EV_RX_ERROR */ - ,"Tx Error" /* EV_TX_ERROR */ - ,"No Buffer Objects" /* EV_NO_BUFFERS */ - ,"No MB-Frame Objects" /* EV_NO_MB_FRAMES */ - ,"No SB-Frame Objects" /* EV_NO_SB_FRAMES */ - ,"Tx Queue Is Full" /* EV_TX_QUEUE_FULL */ - ,"Rx Queue Is Full" /* EV_RX_QUEUE_FULL */ - ,"Interrupts Queue Is Full" /* EV_INTR_QUEUE_FULL */ - ,"Data Buffer Is Unavailable" /* EV_NO_DATA_BUFFER */ - ,"Objects Pool Is Empty" /* EV_OBJ_POOL_EMPTY */ - ,"Illegal bus access" /* EV_BUS_ERROR */ - ,"PTP Tx Timestamps Queue Is Full" /* EV_PTP_TXTS_QUEUE_FULL */ - ,"PTP Rx Timestamps Queue Is Full" /* EV_PTP_RXTS_QUEUE_FULL */ -}; - -#endif /* (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) */ - + switch (err) + { + case (E_OK): return "OK"; + case (E_WRITE_FAILED): return "Write Access Failed"; + case (E_NO_DEVICE): return "No Device"; + case (E_NOT_AVAILABLE): return "Resource Is Unavailable"; + case (E_NO_MEMORY): return "Memory Allocation Failed"; + case (E_INVALID_ADDRESS): return "Invalid Address"; + case (E_BUSY): return "Resource Is Busy"; + case (E_ALREADY_EXISTS): return "Resource Already Exists"; + case (E_INVALID_OPERATION): return "Invalid Operation"; + case (E_INVALID_VALUE): return "Invalid Value"; + case (E_NOT_IN_RANGE): return "Value Out Of Range"; + case (E_NOT_SUPPORTED): return "Unsupported Operation"; + case (E_INVALID_STATE): return "Invalid State"; + case (E_INVALID_HANDLE): return "Invalid Handle"; + case (E_INVALID_ID): return "Invalid ID"; + case (E_NULL_POINTER): return "Unexpected NULL Pointer"; + case (E_INVALID_SELECTION): return "Invalid Selection"; + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode"; + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type"; + case (E_INVALID_CLOCK): return "Invalid Clock"; + case (E_CONFLICT): return "Conflict In Settings"; + case (E_NOT_ALIGNED): return "Incorrect Alignment"; + case (E_NOT_FOUND): return "Resource Not Found"; + case (E_FULL): return "Resource Is Full"; + case (E_EMPTY): return "Resource Is Empty"; + case (E_ALREADY_FREE): return "Resource Already Free"; + case (E_READ_FAILED): return "Read Access Failed"; + case (E_INVALID_FRAME): return "Invalid Frame"; + case (E_SEND_FAILED): return "Send Operation Failed"; + case (E_RECEIVE_FAILED): return "Receive Operation Failed"; + case (E_TIMEOUT): return "Operation Timed Out"; + default: + break; + } + return NULL; +} #endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ - diff --git a/sys/contrib/ncsw/etc/memcpy.c b/sys/contrib/ncsw/etc/memcpy.c index 1ed8daeafd52..8494440bd1c3 100644 --- a/sys/contrib/ncsw/etc/memcpy.c +++ b/sys/contrib/ncsw/etc/memcpy.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,76 +31,31 @@ */ + #include "std_ext.h" #include "xx_ext.h" #include "memcpy_ext.h" - -#ifdef CORE_8BIT_ACCESS_ERRATA -static void MY_MY_WRITE_UINT8(uint8_t *addr, uint8_t val) +void * MemCpy8(void* pDst, void* pSrc, uint32_t size) { - uint32_t newAddr, newVal; - newAddr = (uint32_t)addr & ~0x3L; - switch ((uint32_t)addr%4) - { - case (0): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x00ffffff) | (((uint32_t)val)<<24); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (1): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xff00ffff) | (((uint32_t)val)<<16); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (2): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xffff00ff) | (((uint32_t)val)<<8); - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - case (3): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xffffff00) | val; - WRITE_UINT32(*(uint32_t*)newAddr, newVal); - break; - } + uint32_t i; + + for(i = 0; i < size; ++i) + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i); + + return pDst; } -static uint8_t MY_MY_GET_UINT8(uint8_t *addr) +void * MemSet8(void* pDst, int c, uint32_t size) { - uint32_t newAddr, newVal=0; - newAddr = (uint32_t)addr & ~0x3L; - switch ((uint32_t)addr%4) - { - case (0): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0xff000000)>>24; - break; - case (1): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x00ff0000)>>16; - break; - case (2): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x0000ff00)>>8; - break; - case (3): - newVal = GET_UINT32(*(uint32_t*)newAddr); - newVal = (newVal & 0x000000ff); - break; - } + uint32_t i; - return (uint8_t)newVal; + for(i = 0; i < size; ++i) + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c); + + return pDst; } -#define MY_WRITE_UINT8(addr,val) MY_MY_WRITE_UINT8(&addr,val) -#define MY_GET_UINT8(addr) MY_MY_GET_UINT8(&addr) -#else -#define MY_WRITE_UINT8 WRITE_UINT8 -#define MY_GET_UINT8 GET_UINT8 -#endif /* CORE_8BIT_ACCESS_ERRATA */ - - void * MemCpy32(void* pDst,void* pSrc, uint32_t size) { uint32_t leftAlign; @@ -194,7 +149,7 @@ void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size) */ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ { - MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8)); + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); p_Dst8++;p_Src8++; size--; } @@ -202,7 +157,7 @@ void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size) /* align destination (possibly disaligning source)*/ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ { - MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8)); + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); p_Dst8++;p_Src8++; size--; } @@ -247,7 +202,7 @@ void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size) /* complete the left overs */ while (size--) { - MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8)); + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); p_Dst8++;p_Src8++; } @@ -273,7 +228,7 @@ void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size) */ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ { - MY_WRITE_UINT8(*p_Dst8, *p_Src8); + WRITE_UINT8(*p_Dst8, *p_Src8); p_Dst8++;p_Src8++; size--; } @@ -281,7 +236,7 @@ void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size) /* align destination (possibly disaligning source)*/ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ { - MY_WRITE_UINT8(*p_Dst8, *p_Src8); + WRITE_UINT8(*p_Dst8, *p_Src8); p_Dst8++;p_Src8++; size--; } @@ -325,7 +280,7 @@ void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size) /* complete the left overs */ while (size--) { - MY_WRITE_UINT8(*p_Dst8, *p_Src8); + WRITE_UINT8(*p_Dst8, *p_Src8); p_Dst8++;p_Src8++; } @@ -351,7 +306,7 @@ void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size) */ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ { - *p_Dst8 = MY_GET_UINT8(*p_Src8); + *p_Dst8 = GET_UINT8(*p_Src8); p_Dst8++;p_Src8++; size--; } @@ -359,7 +314,7 @@ void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size) /* align destination (possibly disaligning source)*/ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ { - *p_Dst8 = MY_GET_UINT8(*p_Src8); + *p_Dst8 = GET_UINT8(*p_Src8); p_Dst8++;p_Src8++; size--; } @@ -404,7 +359,7 @@ void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size) /* complete the left overs */ while (size--) { - *p_Dst8 = MY_GET_UINT8(*p_Src8); + *p_Dst8 = GET_UINT8(*p_Src8); p_Dst8++;p_Src8++; } @@ -537,7 +492,7 @@ void * IOMemSet32(void* pDst, uint8_t val, uint32_t size) /* align destination to 32 */ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ { - MY_WRITE_UINT8(*p_Dst8, val); + WRITE_UINT8(*p_Dst8, val); p_Dst8++; size--; } @@ -555,7 +510,7 @@ void * IOMemSet32(void* pDst, uint8_t val, uint32_t size) p_Dst8 = (uint8_t*)(p_Dst32); while (size--) { - MY_WRITE_UINT8(*p_Dst8, val); + WRITE_UINT8(*p_Dst8, val); p_Dst8++; } diff --git a/sys/contrib/ncsw/etc/mm.c b/sys/contrib/ncsw/etc/mm.c index 2a8e338cb52e..9fcc46e0b26b 100644 --- a/sys/contrib/ncsw/etc/mm.c +++ b/sys/contrib/ncsw/etc/mm.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,10 +30,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "string_ext.h" #include "error_ext.h" #include "std_ext.h" -#include "sprint_ext.h" #include "part_ext.h" #include "xx_ext.h" @@ -246,6 +246,7 @@ static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end) else p_MM->freeBlocks[i] = p_CurrB->p_Next; XX_Free(p_CurrB); + p_CurrB = NULL; } break; } @@ -575,7 +576,10 @@ static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignm /* calls Update routine to update a lists of free blocks */ if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK ) + { + XX_Free(p_NewBusyB); return (uint64_t)(ILLEGAL_BASE); + } /* insert the new busy block into the list of busy blocks */ AddBusy ( p_MM, p_NewBusyB ); @@ -614,21 +618,30 @@ t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!")); } - /* initializes a new memory block */ - if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) - RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); + /* Initializes counter of free memory to total size */ + p_MM->freeMemSize = size; /* A busy list is empty */ p_MM->busyBlocks = 0; - /*Initializes a new free block for each free list*/ + /* Initializes a new memory block */ + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) + { + MM_Free(p_MM); + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); + } + + /* Initializes a new free block for each free list*/ for (i=0; i <= MM_MAX_ALIGNMENT; i++) { newBase = MAKE_ALIGNED( base, (0x1 << i) ); newSize = size - (newBase - base); if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL) + { + MM_Free(p_MM); RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); + } } *h_MM = p_MM; @@ -751,9 +764,13 @@ uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name) if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK ) { XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); + XX_Free(p_NewBusyB); return (uint64_t)(ILLEGAL_BASE); } + /* Decreasing the allocated memory size from free memory size */ + p_MM->freeMemSize -= size; + /* insert the new busy block into the list of busy blocks */ AddBusy ( p_MM, p_NewBusyB ); XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); @@ -804,9 +821,13 @@ uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name) if ( CutFree ( p_MM, base, base+size ) != E_OK ) { XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); + XX_Free(p_NewBusyB); return (uint64_t)(ILLEGAL_BASE); } + /* Decreasing the allocated memory size from free memory size */ + p_MM->freeMemSize -= size; + /* insert the new busy block into the list of busy blocks */ AddBusy ( p_MM, p_NewBusyB ); XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); @@ -889,9 +910,13 @@ uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64 if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK ) { XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); + XX_Free(p_NewBusyB); return (uint64_t)(ILLEGAL_BASE); } + /* Decreasing the allocated memory size from free memory size */ + p_MM->freeMemSize -= size; + /* insert the new busy block into the list of busy blocks */ AddBusy( p_MM, p_NewBusyB ); XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); @@ -942,6 +967,9 @@ uint64_t MM_Put(t_Handle h_MM, uint64_t base) size = p_BusyB->end - p_BusyB->base; + /* Adding the deallocated memory size to free memory size */ + p_MM->freeMemSize += size; + XX_Free(p_BusyB); XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); @@ -958,6 +986,7 @@ uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size) ASSERT_COND(p_MM); intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); + if ( CutBusy( p_MM, base, end ) != E_OK ) { XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); @@ -969,6 +998,10 @@ uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size) XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); return (uint64_t)(0); } + + /* Adding the deallocated memory size to free memory size */ + p_MM->freeMemSize += size; + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); return (size); @@ -988,6 +1021,7 @@ t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size) * memory block */ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); + p_MemB = p_MM->memBlocks; while ( p_MemB->p_Next ) { @@ -1024,6 +1058,10 @@ t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size) XX_Free(p_NewMemB); return ((t_Error)errCode); } + + /* Adding the new block size to free memory size */ + p_MM->freeMemSize += size; + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); return (E_OK); @@ -1077,7 +1115,17 @@ bool MM_InRange(t_Handle h_MM, uint64_t addr) } /*****************************************************************************/ -void MM_Dump(t_Handle h_MM, void *buff) +uint64_t MM_GetFreeMemSize(t_Handle h_MM) +{ + t_MM *p_MM = (t_MM*)h_MM; + + ASSERT_COND(p_MM); + + return p_MM->freeMemSize; +} + +/*****************************************************************************/ +void MM_Dump(t_Handle h_MM) { t_MM *p_MM = (t_MM *)h_MM; t_FreeBlock *p_FreeB; @@ -1085,25 +1133,23 @@ void MM_Dump(t_Handle h_MM, void *buff) int i; p_BusyB = p_MM->busyBlocks; - Sprint(buff, "List of busy blocks:\n"); + XX_Print("List of busy blocks:\n"); while (p_BusyB) { - Sprint(buff, "\t0x%p: (%s: b=0x%lx, e=0x%lx)\n", - p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end ); + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end ); p_BusyB = p_BusyB->p_Next; } - Sprint(buff, "\nLists of free blocks according to alignment:\n"); + XX_Print("\nLists of free blocks according to alignment:\n"); for (i=0; i <= MM_MAX_ALIGNMENT; i++) { - Sprint(buff, "%d alignment:\n", (0x1 << i)); + XX_Print("%d alignment:\n", (0x1 << i)); p_FreeB = p_MM->freeBlocks[i]; while (p_FreeB) { - Sprint(buff, "\t0x%p: (b=0x%lx, e=0x%lx)\n", - p_FreeB, p_FreeB->base, p_FreeB->end); + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end); p_FreeB = p_FreeB->p_Next; } - Sprint(buff, "\n"); + XX_Print("\n"); } } diff --git a/sys/contrib/ncsw/etc/mm.h b/sys/contrib/ncsw/etc/mm.h index 509f6141ab08..43b2298fce5d 100644 --- a/sys/contrib/ncsw/etc/mm.h +++ b/sys/contrib/ncsw/etc/mm.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************** * * File: mm.h @@ -55,7 +56,7 @@ (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1))) -/* t_MemBlock data stucutre defines parameters of the Memory Block */ +/* t_MemBlock data structure defines parameters of the Memory Block */ typedef struct t_MemBlock { struct t_MemBlock *p_Next; /* Pointer to the next memory block */ @@ -65,7 +66,7 @@ typedef struct t_MemBlock } t_MemBlock; -/* t_FreeBlock data stucutre defines parameters of the Free Block */ +/* t_FreeBlock data structure defines parameters of the Free Block */ typedef struct t_FreeBlock { struct t_FreeBlock *p_Next; /* Pointer to the next free block */ @@ -75,7 +76,7 @@ typedef struct t_FreeBlock } t_FreeBlock; -/* t_BusyBlock data stucutre defines parameters of the Busy Block */ +/* t_BusyBlock data structure defines parameters of the Busy Block */ typedef struct t_BusyBlock { struct t_BusyBlock *p_Next; /* Pointer to the next free block */ @@ -90,11 +91,14 @@ typedef struct t_BusyBlock /* t_MM data structure defines parameters of the MM object */ typedef struct t_MM { + t_Handle h_Spinlock; + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */ t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */ t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1]; /* Alignment lists of free blocks (Free lists) */ - t_Handle h_Spinlock; + + uint64_t freeMemSize; /* Total size of free memory (in bytes) */ } t_MM; diff --git a/sys/contrib/ncsw/etc/list.c b/sys/contrib/ncsw/etc/ncsw_list.c similarity index 90% rename from sys/contrib/ncsw/etc/list.c rename to sys/contrib/ncsw/etc/ncsw_list.c index 62a5fcdf5895..efe0d6727141 100644 --- a/sys/contrib/ncsw/etc/list.c +++ b/sys/contrib/ncsw/etc/ncsw_list.c @@ -40,30 +40,30 @@ #include "list_ext.h" -void LIST_Append(t_List *p_NewList, t_List *p_Head) +void NCSW_LIST_Append(t_List *p_NewList, t_List *p_Head) { t_List *p_First = NCSW_LIST_FIRST(p_NewList); if (p_First != p_NewList) { - t_List *p_Last = LIST_LAST(p_NewList); + t_List *p_Last = NCSW_LIST_LAST(p_NewList); t_List *p_Cur = NCSW_LIST_NEXT(p_Head); NCSW_LIST_PREV(p_First) = p_Head; NCSW_LIST_FIRST(p_Head) = p_First; NCSW_LIST_NEXT(p_Last) = p_Cur; - LIST_LAST(p_Cur) = p_Last; + NCSW_LIST_LAST(p_Cur) = p_Last; } } -int LIST_NumOfObjs(t_List *p_List) +int NCSW_LIST_NumOfObjs(t_List *p_List) { t_List *p_Tmp; int numOfObjs = 0; - if (!LIST_IsEmpty(p_List)) - LIST_FOR_EACH(p_Tmp, p_List) + if (!NCSW_LIST_IsEmpty(p_List)) + NCSW_LIST_FOR_EACH(p_Tmp, p_List) numOfObjs++; return numOfObjs; diff --git a/sys/contrib/ncsw/etc/ncsw_mem.c b/sys/contrib/ncsw/etc/ncsw_mem.c index f82f0f4af2bc..bc21390a3288 100644 --- a/sys/contrib/ncsw/etc/ncsw_mem.c +++ b/sys/contrib/ncsw/etc/ncsw_mem.c @@ -42,6 +42,7 @@ #include "xx_ext.h" +#if 0 #define PAD_ALIGNMENT(align, x) (((x)%(align)) ? ((align)-((x)%(align))) : 0) #define ALIGN_BLOCK(p_Block, prefixSize, alignment) \ @@ -761,3 +762,4 @@ void MEM_CheckLeaks(t_Handle h_Mem) #endif /* DEBUG_MEM_LEAKS */ +#endif diff --git a/sys/contrib/ncsw/etc/sprint.c b/sys/contrib/ncsw/etc/sprint.c index 6f9bdf94ffe5..46d2956a2629 100644 --- a/sys/contrib/ncsw/etc/sprint.c +++ b/sys/contrib/ncsw/etc/sprint.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /*------------------------------------------------------*/ /* File: sprint.c */ /* */ @@ -38,7 +39,6 @@ /*------------------------------------------------------*/ #include "string_ext.h" #include "stdlib_ext.h" -#include "ctype_ext.h" #include "stdarg_ext.h" #include "sprint_ext.h" #include "std_ext.h" diff --git a/sys/contrib/ncsw/inc/Peripherals/bm_ext.h b/sys/contrib/ncsw/inc/Peripherals/bm_ext.h index 140cf58831d3..952e95f62e47 100644 --- a/sys/contrib/ncsw/inc/Peripherals/bm_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/bm_ext.h @@ -322,7 +322,7 @@ typedef struct { uintptr_t ciBaseAddress; /**< Cache-inhibited base address (virtual) */ t_Handle h_Bm; /**< Bm Handle */ e_DpaaSwPortal swPortalId; /**< Portal id */ - int irq; /**< portal interrupt line; NO_IRQ if interrupts not used */ + uintptr_t irq; /**< portal interrupt line; NO_IRQ if interrupts not used */ } t_BmPortalParam; @@ -593,30 +593,6 @@ uint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool); *//***************************************************************************/ t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff); -/**************************************************************************//** - @Function BM_POOL_PhysToVirt - - @Description Translates a physical address to the matching virtual address. - - @Param[in] h_BmPool - A handle to a BM-pool - @Param[in] addr - The physical address to translate - - @Return Virtual address. -*//***************************************************************************/ -void * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr); - -/**************************************************************************//** - @Function BM_POOL_VirtToPhys - - @Description Translates a virtual address to the matching physical address. - - @Param[in] h_BmPool - A handle to a BM-pool - @Param[in] addr - The virtual address to translate - - @Return Physical address. -*//***************************************************************************/ -physAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *addr); - /**************************************************************************//** @Function BM_POOL_GetCounter diff --git a/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h b/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h index 5990f7195a63..a84d563116c6 100644 --- a/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /*------------------------------------------------------*/ /* */ /* File: crc_mac_addr_ext.h */ diff --git a/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h b/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h index 282f41591169..ec0a03a877a0 100644 --- a/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/****************************************************************************** + +/**************************************************************************//** @File dpaa_ext.h @Description DPAA Application Programming Interface. @@ -53,14 +54,29 @@ #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START + +#include + +#define __BYTE_ORDER__ BYTE_ORDER +#define __ORDER_BIG_ENDIAN__ BIG_ENDIAN /**************************************************************************//** @Description Frame descriptor *//***************************************************************************/ typedef _Packed struct t_DpaaFD { - volatile uint32_t id; /**< FD id */ - volatile uint32_t addrl; /**< Data Address */ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + volatile uint8_t liodn; + volatile uint8_t bpid; + volatile uint8_t elion; + volatile uint8_t addrh; + volatile uint32_t addrl; +#else + volatile uint32_t addrl; + volatile uint8_t addrh; + volatile uint8_t elion; + volatile uint8_t bpid; + volatile uint8_t liodn; + #endif volatile uint32_t length; /**< Frame length */ volatile uint32_t status; /**< FD status */ } _PackedType t_DpaaFD; @@ -95,25 +111,17 @@ typedef enum e_DpaaFDFormatType { #define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */ #define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */ -#define DPAA_FD_GET_DD(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_DD_MASK) >> (31-1)) /**< Macro to get FD DD field */ -#define DPAA_FD_GET_PID(fd) (((((t_DpaaFD *)fd)->id & DPAA_FD_PID_MASK) >> (31-7)) | \ - ((((t_DpaaFD *)fd)->id & DPAA_FD_ELIODN_MASK) >> (31-19-6))) /**< Macro to get FD PID field */ -#define DPAA_FD_GET_BPID(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_BPID_MASK) >> (31-15)) /**< Macro to get FD BPID field */ -#define DPAA_FD_GET_ADDRH(fd) (((t_DpaaFD *)fd)->id & DPAA_FD_ADDRH_MASK) /**< Macro to get FD ADDRH field */ +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */ #define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */ #define DPAA_FD_GET_PHYS_ADDR(fd) ((physAddress_t)(((uint64_t)DPAA_FD_GET_ADDRH(fd) << 32) | (uint64_t)DPAA_FD_GET_ADDRL(fd))) /**< Macro to get FD ADDR field */ #define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */ #define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */ #define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */ #define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */ -#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */ -#define DPAA_FD_SET_DD(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_DD_MASK) | (((val) << (31-1)) & DPAA_FD_DD_MASK ))) /**< Macro to set FD DD field */ - /**< Macro to set FD PID field or LIODN offset*/ -#define DPAA_FD_SET_PID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~(DPAA_FD_PID_MASK|DPAA_FD_ELIODN_MASK)) | ((((val) << (31-7)) & DPAA_FD_PID_MASK) | ((((val)>>6) << (31-19)) & DPAA_FD_ELIODN_MASK)))) -#define DPAA_FD_SET_BPID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_BPID_MASK) | (((val) << (31-15)) & DPAA_FD_BPID_MASK))) /**< Macro to set FD BPID field */ -#define DPAA_FD_SET_ADDRH(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_ADDRH_MASK) | ((val) & DPAA_FD_ADDRH_MASK))) /**< Macro to set FD ADDRH field */ -#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */ +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */ +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */ #define DPAA_FD_SET_ADDR(fd,val) \ do { \ uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \ @@ -123,7 +131,7 @@ do { \ #define DPAA_FD_SET_FORMAT(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_FORMAT_MASK) | (((val) << (31-2))& DPAA_FD_FORMAT_MASK))) /**< Macro to set FD FORMAT field */ #define DPAA_FD_SET_OFFSET(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_OFFSET_MASK) | (((val) << (31-11))& DPAA_FD_OFFSET_MASK) )) /**< Macro to set FD OFFSET field */ #define DPAA_FD_SET_LENGTH(fd,val) (((t_DpaaFD *)fd)->length = (((t_DpaaFD *)fd)->length & ~DPAA_FD_LENGTH_MASK) | ((val) & DPAA_FD_LENGTH_MASK)) /**< Macro to set FD LENGTH field */ -#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */ +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */ /* @} */ /**************************************************************************//** @@ -143,7 +151,7 @@ typedef _Packed struct t_DpaaSGTE { *//***************************************************************************/ typedef _Packed struct t_DpaaSGT { t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY]; - /**< structure that hold the information about + /**< Structure that holds information about a single S/G entry. */ } _PackedType t_DpaaSGT; @@ -151,10 +159,10 @@ typedef _Packed struct t_DpaaSGT { @Description Compound Frame Table *//***************************************************************************/ typedef _Packed struct t_DpaaCompTbl { - t_DpaaSGTE outputBuffInfo; /**< structure that holds the information about + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about the compound-frame output buffer; NOTE: this may point to a S/G table */ - t_DpaaSGTE inputBuffInfo; /**< structure that holds the information about + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about the compound-frame input buffer; NOTE: this may point to a S/G table */ } _PackedType t_DpaaCompTbl; @@ -195,11 +203,12 @@ do { \ #define DPAA_SGTE_SET_OFFSET(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_OFFSET_MASK) | (((val) << (31-31))& DPAA_SGTE_OFFSET_MASK) )) /**< Macro to set SGTE OFFSET field */ /* @} */ -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ +#define DPAA_LIODN_DONT_OVERRIDE (-1) + /** @} */ /* end of DPAA_grp group */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_ext.h index a3f56f885bc1..c3633592694c 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_ext.h @@ -41,7 +42,7 @@ #include "error_ext.h" #include "std_ext.h" #include "dpaa_ext.h" - +#include "fsl_fman_sp.h" /**************************************************************************//** @Group FM_grp Frame Manager API @@ -54,31 +55,29 @@ /**************************************************************************//** @Group FM_lib_grp FM library - @Description FM API functions, definitions and enums + @Description FM API functions, definitions and enums. + The FM module is the main driver module and is a mandatory module - for FM driver users. Before any further module initialization, - this module must be initialized. - The FM is a "singletone" module. It is responsible of the common - HW modules: FPM, DMA, common QMI, common BMI initializations and + for FM driver users. This module must be initialized first prior + to any other drivers modules. + The FM is a "singleton" module. It is responsible of the common + HW modules: FPM, DMA, common QMI and common BMI initializations and run-time control routines. This module must be initialized always when working with any of the FM modules. - NOTE - We assumes that the FML will be initialize only by core No. 0! + NOTE - We assume that the FM library will be initialized only by core No. 0! @{ *//***************************************************************************/ /**************************************************************************//** - @Description enum for defining port types + @Description Enum for defining port types *//***************************************************************************/ typedef enum e_FmPortType { - e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port (id's: 0-6, share id's with - host command, so must have exclusive id) */ - e_FM_PORT_TYPE_OH_HOST_COMMAND, /**< Host command port (id's: 0-6, share id's with - offline parsing ports, so must have exclusive id) */ - e_FM_PORT_TYPE_RX, /**< 1G Rx port (id's: 0-3) */ - e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port (id's: 0) */ - e_FM_PORT_TYPE_TX, /**< 1G Tx port (id's: 0-3) */ - e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port (id's: 0) */ + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */ + e_FM_PORT_TYPE_RX, /**< 1G Rx port */ + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */ + e_FM_PORT_TYPE_TX, /**< 1G Tx port */ + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */ e_FM_PORT_TYPE_DUMMY } e_FmPortType; @@ -93,7 +92,6 @@ typedef enum e_FmPortType { #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(push,1) #endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START /**************************************************************************//** @Description FM physical Address @@ -114,9 +112,12 @@ typedef _Packed struct t_FmPrsResult { volatile uint8_t l4r; /**< Layer 4 result */ volatile uint8_t cplan; /**< Classification plan id */ volatile uint16_t nxthdr; /**< Next Header */ - volatile uint16_t cksum; /**< Checksum */ - volatile uint32_t lcv; /**< LCV */ - volatile uint8_t shim_off[3]; /**< Shim offset */ + volatile uint16_t cksum; /**< Running-sum */ + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */ + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */ + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */ + volatile uint8_t shim_off[2]; /**< Shim offset */ + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */ volatile uint8_t eth_off; /**< ETH offset */ volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */ volatile uint8_t vlan_off[2]; /**< VLAN offset */ @@ -143,15 +144,71 @@ typedef _Packed struct t_FmPrsResult { /**************************************************************************//** @Collection FM Frame descriptor macros *//***************************************************************************/ -#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */ -#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */ -#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */ -#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */ -#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */ -#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */ +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */ +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */ +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */ +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */ +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */ +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */ -#define FM_FD_TX_STATUS_ERR_MASK 0x07000000 /**< TX Error FD bits */ -#define FM_FD_RX_STATUS_ERR_MASK 0x070ee3f8 /**< RX Error FD bits */ +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */ +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */ +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */ + +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */ + +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */ +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */ +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */ + +#ifdef FM_CAPWAP_SUPPORT +#define FM_FD_ERR_CRE 0x00200000 +#define FM_FD_ERR_CHE 0x00100000 +#endif /* FM_CAPWAP_SUPPORT */ + +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity + error (SGMII and TBI modes), FIFO parity error. PHY + Sequence error, PHY error control character detected. */ +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */ +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */ +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */ +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */ +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */ +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */ +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */ +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */ +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */ +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */ +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */ +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */ +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */ + +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \ + FM_FD_ERR_LENGTH | \ + FM_FD_ERR_DMA) /**< TX Error FD bits */ + +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \ + FM_FD_ERR_LENGTH | \ + FM_FD_ERR_DMA | \ + FM_FD_ERR_IPR | \ + FM_FD_ERR_IPR_TO | \ + FM_FD_ERR_IPR_NCSP | \ + FM_FD_ERR_PHYSICAL | \ + FM_FD_ERR_SIZE | \ + FM_FD_ERR_CLS_DISCARD | \ + FM_FD_ERR_COLOR_RED | \ + FM_FD_ERR_COLOR_YELLOW | \ + FM_FD_ERR_ILL_PLCR | \ + FM_FD_ERR_PLCR_FRAME_LEN | \ + FM_FD_ERR_EXTRACTION | \ + FM_FD_ERR_NO_SCHEME | \ + FM_FD_ERR_KEYSIZE_OVERFLOW | \ + FM_FD_ERR_PRS_TIMEOUT | \ + FM_FD_ERR_PRS_ILL_INSTRUCT | \ + FM_FD_ERR_PRS_HDR_ERR | \ + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */ + +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */ /* @} */ /**************************************************************************//** @@ -167,6 +224,23 @@ typedef _Packed struct t_FmContextA { *//***************************************************************************/ typedef uint32_t t_FmContextB; +/**************************************************************************//** + @Collection Special Operation options +*//***************************************************************************/ +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */ + +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */ +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */ +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */ +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */ +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */ +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */ +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */ +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */ +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */ +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */ +/* @} */ + /**************************************************************************//** @Collection Context A macros *//***************************************************************************/ @@ -207,7 +281,6 @@ typedef uint32_t t_FmContextB; #define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK))) /* @} */ -#define MEM_MAP_END #if defined(__MWERKS__) && !defined(__GNUC__) #pragma pack(pop) #endif /* defined(__MWERKS__) && ... */ @@ -217,24 +290,45 @@ typedef uint32_t t_FmContextB; @Description FM Exceptions *//***************************************************************************/ typedef enum e_FmExceptions { - e_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */ - e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error */ - e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side */ - e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */ + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */ + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/ + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/ + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/ + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/ e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ - e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeu from unknown port id */ + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */ e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ - e_FM_EX_BMI_PIPELINE_ECC, /**< Pipeline Table ECC Error */ + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */ e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */ e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ } e_FmExceptions; +/**************************************************************************//** + @Description Enum for defining port DMA swap mode +*//***************************************************************************/ +typedef enum e_FmDmaSwapOption { + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/ + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped + in PowerPc Little Endian mode. */ + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped + in Big Endian mode */ +} e_FmDmaSwapOption; + +/**************************************************************************//** + @Description Enum for defining port DMA cache attributes +*//***************************************************************************/ +typedef enum e_FmDmaCacheOption { + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */ + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */ +} e_FmDmaCacheOption; + + /**************************************************************************//** @Group FM_init_grp FM Initialization Unit @@ -243,9 +337,9 @@ typedef enum e_FmExceptions { Initialization Flow Initialization of the FM Module will be carried out by the application according to the following sequence: - a. Calling the configuration routine with basic parameters. - b. Calling the advance initialization routines to change driver's defaults. - c. Calling the initialization routine. + - Calling the configuration routine with basic parameters. + - Calling the advance initialization routines to change driver's defaults. + - Calling the initialization routine. @{ *//***************************************************************************/ @@ -259,8 +353,9 @@ typedef enum e_FmExceptions { @Param[in] h_App - User's application descriptor. @Param[in] exception - The exception. *//***************************************************************************/ -typedef void (t_FmExceptionsCallback) (t_Handle h_App, - e_FmExceptions exception); +typedef void (t_FmExceptionsCallback)(t_Handle h_App, + e_FmExceptions exception); + /**************************************************************************//** @Function t_FmBusErrorCallback @@ -283,76 +378,162 @@ typedef void (t_FmBusErrorCallback) (t_Handle h_App, uint16_t liodn); /**************************************************************************//** - @Description structure for defining Ucode patch for loading. + @Description A structure for defining buffer prefix area content. *//***************************************************************************/ -typedef struct t_FmPcdFirmwareParams { - uint32_t size; /**< Size of uCode */ - uint32_t *p_Code; /**< A pointer to the uCode */ -} t_FmPcdFirmwareParams; +typedef struct t_FmBufferPrefixContent { + uint16_t privDataSize; /**< Number of bytes to be left at the beginning + of the external buffer; Note that the private-area will + start from the base of the buffer address. */ + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM; + User may use FM_PORT_GetBufferPrsResult() in order to + get the parser-result from a buffer. */ + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM + User may use FM_PORT_GetBufferTimeStamp() in order to + get the parser-result from a buffer. */ + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM + User may use FM_PORT_GetBufferHashResult() in order to + get the parser-result from a buffer. */ + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information: + AD, hash-result, key, etc. */ + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign], + other value for selecting a data alignment (must be a power of 2); + if write optimization is used, must be >= 16. */ + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size); + Note that this field impacts the size of the buffer-prefix + (i.e. it pushes the data offset); + This field is irrelevant if DPAA_VERSION==10 */ +} t_FmBufferPrefixContent; /**************************************************************************//** - @Description structure representing FM initialization parameters + @Description A structure of information about each of the external + buffer pools used by a port or storage-profile. +*//***************************************************************************/ +typedef struct t_FmExtPoolParams { + uint8_t id; /**< External buffer pool id */ + uint16_t size; /**< External buffer pool buffer size */ +} t_FmExtPoolParams; + +/**************************************************************************//** + @Description A structure for informing the driver about the external + buffer pools allocated in the BM and used by a port or a + storage-profile. +*//***************************************************************************/ +typedef struct t_FmExtPools { + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */ + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS]; + /**< Parameters for each port */ +} t_FmExtPools; + +/**************************************************************************//** + @Description A structure for defining backup BM Pools. +*//***************************************************************************/ +typedef struct t_FmBackupBmPools { + uint8_t numOfBackupPools; /**< Number of BM backup pools - + must be smaller than the total number of + pools defined for the specified port.*/ + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS]; + /**< numOfBackupPools pool id's, specifying which + pools should be used only as backup. Pool + id's specified here must be a subset of the + pools used by the specified port.*/ +} t_FmBackupBmPools; + +/**************************************************************************//** + @Description A structure for defining BM pool depletion criteria +*//***************************************************************************/ +typedef struct t_FmBufPoolDepletion { + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after + a number of pools (all together!) are depleted */ + uint8_t numOfPools; /**< the number of depleted pools that will invoke + pause frames transmission. */ + bool poolsToConsider[BM_MAX_NUM_OF_POOLS]; + /**< For each pool, TRUE if it should be considered for + depletion (Note - this pool must be used by this port!). */ + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after + a single-pool is depleted; */ + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS]; + /**< For each pool, TRUE if it should be considered for + depletion (Note - this pool must be used by this port!) */ +#if (DPAA_VERSION >= 11) + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES]; + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */ +#endif /* (DPAA_VERSION >= 11) */ +} t_FmBufPoolDepletion; + +/**************************************************************************//** + @Description A Structure for defining Ucode patch for loading. +*//***************************************************************************/ +typedef struct t_FmFirmwareParams { + uint32_t size; /**< Size of uCode */ + uint32_t *p_Code; /**< A pointer to the uCode */ +} t_FmFirmwareParams; + +/**************************************************************************//** + @Description A Structure for defining FM initialization parameters *//***************************************************************************/ -#define FM_SIZE_OF_LIODN_TABLE 64 typedef struct t_FmParams { uint8_t fmId; /**< Index of the FM */ - uint8_t guestId; /**< FM Partition Id */ + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual); + this field is optional when the FM runs in "guest-mode" + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will + use the memory-map instead of calling the IPC where possible; + NOTE that this should include ALL common registers of the FM including + the PCD registers area (i.e. until the VSP pages - 880KB). */ + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object, + to be used by the FM. */ + uint16_t fmClkFreq; /**< In Mhz; + Relevant when FM not runs in "guest-mode". */ + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability: + when fmMacClkRatio = 0, ratio is 2:1 + when fmMacClkRatio = 1, ratio is 1:1 */ + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions; + Relevant when FM not runs in "guest-mode". */ + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions; + Relevant when FM not runs in "guest-mode". */ + t_Handle h_App; /**< A handle to an application layer object; This handle will + be passed by the driver upon calling the above callbacks; + Relevant when FM not runs in "guest-mode". */ + uintptr_t irq; /**< FM interrupt source for normal events; + Relevant when FM not runs in "guest-mode". */ + uintptr_t errIrq; /**< FM interrupt source for errors; + Relevant when FM not runs in "guest-mode". */ + t_FmFirmwareParams firmware; /**< The firmware parameters structure; + Relevant when FM not runs in "guest-mode". */ - uintptr_t baseAddr; /**< Relevant when guestId = NCSW_MASSTER_ID only. - A pointer to base of memory mapped FM registers (virtual); - NOTE that this should include ALL common regs of the FM including - the PCD regs area. */ - t_Handle h_FmMuram; /**< Relevant when guestId = NCSW_MASSTER_ID only. - A handle of an initialized MURAM object, - to be used by the FM */ - uint16_t fmClkFreq; /**< Relevant when guestId = NCSW_MASSTER_ID only. - In Mhz */ -#ifdef FM_PARTITION_ARRAY - uint16_t liodnBasePerPort[FM_SIZE_OF_LIODN_TABLE]; - /**< Relevant when guestId = NCSW_MASSTER_ID only. - For each partition, LIODN should be configured here. */ -#endif /* FM_PARTITION_ARRAY */ - t_FmExceptionsCallback *f_Exception; /**< Relevant when guestId = NCSW_MASSTER_ID only. - An application callback routine to - handle exceptions.*/ - t_FmBusErrorCallback *f_BusError; /**< Relevant when guestId = NCSW_MASSTER_ID only. - An application callback routine to - handle exceptions.*/ - t_Handle h_App; /**< Relevant when guestId = NCSW_MASSTER_ID only. - A handle to an application layer object; This handle will - be passed by the driver upon calling the above callbacks */ - uintptr_t irq; /**< Relevant when guestId = NCSW_MASSTER_ID only. - FM interrupt source for normal events */ - uintptr_t errIrq; /**< Relevant when guestId = NCSW_MASSTER_ID only. - FM interrupt source for errors */ - t_FmPcdFirmwareParams firmware; /**< Relevant when guestId = NCSW_MASSTER_ID only. - Ucode */ +#if (DPAA_VERSION >= 11) + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual); + i.e. up to 24KB, depending on the specific chip. */ + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition. + NOTE: this parameter relevant only when working with multiple partitions. */ + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition. + NOTE: this parameter relevant only when working with multiple partitions. */ +#endif /* (DPAA_VERSION >= 11) */ } t_FmParams; /**************************************************************************//** @Function FM_Config - @Description Creates descriptor for the FM module. - - The routine returns a handle (descriptor) to the FM object. + @Description Creates the FM module and returns its handle (descriptor). This descriptor must be passed as first parameter to all other FM function calls. No actual initialization or configuration of FM hardware is - done by this routine. + done by this routine. All FM parameters get default values that + may be changed by calling one or more of the advance config routines. - @Param[in] p_FmParams - A pointer to data structure of parameters + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters - @Return Handle to FM object, or NULL for Failure. + @Return A handle to the FM object, or NULL for Failure. *//***************************************************************************/ t_Handle FM_Config(t_FmParams *p_FmParams); /**************************************************************************//** @Function FM_Init - @Description Initializes the FM module + @Description Initializes the FM module by defining the software structure + and configuring the hardware registers. @Param[in] h_Fm - FM module descriptor @@ -377,13 +558,15 @@ t_Error FM_Free(t_Handle h_Fm); /**************************************************************************//** @Group FM_advanced_init_grp FM Advanced Configuration Unit - @Description Configuration functions used to change default values; - Note: Advanced init routines are not available for guest partition. + @Description Advanced configuration routines are optional routines that may + be called in order to change the default driver settings. + + Note: Advanced configuration routines are not available for guest partition. @{ *//***************************************************************************/ /**************************************************************************//** - @Description DMA debug mode + @Description Enum for selecting DMA debug mode *//***************************************************************************/ typedef enum e_FmDmaDbgCntMode { e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */ @@ -397,7 +580,7 @@ typedef enum e_FmDmaDbgCntMode { } e_FmDmaDbgCntMode; /**************************************************************************//** - @Description DMA Cache Override + @Description Enum for selecting DMA Cache Override *//***************************************************************************/ typedef enum e_FmDmaCacheOverride { e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */ @@ -407,7 +590,7 @@ typedef enum e_FmDmaCacheOverride { } e_FmDmaCacheOverride; /**************************************************************************//** - @Description DMA External Bus Priority + @Description Enum for selecting DMA External Bus Priority *//***************************************************************************/ typedef enum e_FmDmaExtBusPri { e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */ @@ -417,7 +600,7 @@ typedef enum e_FmDmaExtBusPri { } e_FmDmaExtBusPri; /**************************************************************************//** - @Description enum for choosing the field that will be output on AID + @Description Enum for choosing the field that will be output on AID *//***************************************************************************/ typedef enum e_FmDmaAidMode { e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */ @@ -425,23 +608,24 @@ typedef enum e_FmDmaAidMode { } e_FmDmaAidMode; /**************************************************************************//** - @Description FPM Catasrophic error behaviour + @Description Enum for selecting FPM Catastrophic error behavior *//***************************************************************************/ typedef enum e_FmCatastrophicErr { e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */ - e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only errornous task is stalled */ + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */ } e_FmCatastrophicErr; /**************************************************************************//** - @Description FPM DMA error behaviour + @Description Enum for selecting FPM DMA Error behavior *//***************************************************************************/ typedef enum e_FmDmaErr { - e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic error */ + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic + error (e_FmCatastrophicErr)*/ e_FM_DMA_ERR_REPORT /**< Dma error is just reported */ } e_FmDmaErr; /**************************************************************************//** - @Description DMA Emergency level by BMI emergency signal + @Description Enum for selecting DMA Emergency level by BMI emergency signal *//***************************************************************************/ typedef enum e_FmDmaEmergencyLevel { e_FM_DMA_EM_EBS = 0, /**< EBS emergency */ @@ -449,7 +633,7 @@ typedef enum e_FmDmaEmergencyLevel { } e_FmDmaEmergencyLevel; /**************************************************************************//** - @Collection DMA emergency options + @Collection Enum for selecting DMA Emergency options *//***************************************************************************/ typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */ @@ -467,7 +651,7 @@ typedef struct t_FmDmaEmergency { e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */ } t_FmDmaEmergency; -/**************************************************************************//** +/**************************************************************************//* @Description structure for defining FM threshold *//***************************************************************************/ typedef struct t_FmThresholds { @@ -492,8 +676,7 @@ typedef struct t_FmThresholds { queued in fmCtl2 dispatch queue*/ } t_FmThresholds; - -/**************************************************************************//** +/**************************************************************************//* @Description structure for defining DMA thresholds *//***************************************************************************/ typedef struct t_FmDmaThresholds { @@ -503,12 +686,21 @@ typedef struct t_FmDmaThresholds { until this value is reached (Hystheresis) */ } t_FmDmaThresholds; +/**************************************************************************//** + @Function t_FmResetOnInitOverrideCallback + + @Description FMan specific reset on init user callback routine, + will be used to override the standard FMan reset on init procedure + + @Param[in] h_Fm - FMan handler +*//***************************************************************************/ +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm); /**************************************************************************//** @Function FM_ConfigResetOnInit - @Description Tell the driver whether to reset the FM before initialization or - not. It changes the default configuration [FALSE]. + @Description Define whether to reset the FM before initialization. + Change the default configuration [DEFAULT_resetOnInit]. @Param[in] h_Fm A handle to an FM Module. @Param[in] enable When TRUE, FM will be reset before any initialization. @@ -516,29 +708,34 @@ typedef struct t_FmDmaThresholds { @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable); /**************************************************************************//** - @Function FM_ConfigTotalNumOfTasks + @Function FM_ConfigResetOnInitOverrideCallback - @Description Change the total number of tasks from its default - configuration [BMI_MAX_NUM_OF_TASKS] + @Description Define a special reset of FM before initialization. + Change the default configuration [DEFAULT_resetOnInitOverrideCallback]. - @Param[in] h_Fm A handle to an FM Module. - @Param[in] totalNumOfTasks The selected new value. + @Param[in] h_Fm A handle to an FM Module. + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ -t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks); +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride); /**************************************************************************//** @Function FM_ConfigTotalFifoSize - @Description Change the total Fifo size from its default - configuration [BMI_MAX_FIFO_SIZE] + @Description Define Total FIFO size for the whole FM. + Calling this routine changes the total Fifo size in the internal driver + data base from its default configuration [DEFAULT_totalFifoSize] @Param[in] h_Fm A handle to an FM Module. @Param[in] totalFifoSize The selected new value. @@ -546,53 +743,17 @@ t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize); -/**************************************************************************//** - @Function FM_ConfigMaxNumOfOpenDmas - - @Description Change the maximum allowed open DMA's for this FM from its default - configuration [BMI_MAX_NUM_OF_DMAS] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] maxNumOfOpenDmas The selected new value. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas); - -/**************************************************************************//** - @Function FM_ConfigThresholds - - @Description Calling this routine changes the internal driver data base - from its default FM threshold configuration: - dispLimit: [0] - prsDispTh: [16] - plcrDispTh: [16] - kgDispTh: [16] - bmiDispTh: [16] - qmiEnqDispTh: [16] - qmiDeqDispTh: [16] - fmCtl1DispTh: [16] - fmCtl2DispTh: [16] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] p_FmThresholds A structure of threshold parameters. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds); - /**************************************************************************//** @Function FM_ConfigDmaCacheOverride - @Description Calling this routine changes the internal driver data base - from its default configuration of cache override mode [e_FM_DMA_NO_CACHE_OR] + @Description Define cache override mode. + Calling this routine changes the cache override mode + in the internal driver data base from its default configuration [DEFAULT_cacheOverride] @Param[in] h_Fm A handle to an FM Module. @Param[in] cacheOverride The selected new value. @@ -600,14 +761,17 @@ t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride); /**************************************************************************//** @Function FM_ConfigDmaAidOverride - @Description Calling this routine changes the internal driver data base - from its default configuration of aid override mode [TRUE] + @Description Define DMA AID override mode. + Calling this routine changes the AID override mode + in the internal driver data base from its default configuration [DEFAULT_aidOverride] @Param[in] h_Fm A handle to an FM Module. @Param[in] aidOverride The selected new value. @@ -615,14 +779,17 @@ t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverr @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride); /**************************************************************************//** @Function FM_ConfigDmaAidMode - @Description Calling this routine changes the internal driver data base - from its default configuration of aid mode [e_FM_DMA_AID_OUT_TNUM] + @Description Define DMA AID mode. + Calling this routine changes the AID mode in the internal + driver data base from its default configuration [DEFAULT_aidMode] @Param[in] h_Fm A handle to an FM Module. @Param[in] aidMode The selected new value. @@ -630,14 +797,17 @@ t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode); /**************************************************************************//** @Function FM_ConfigDmaAxiDbgNumOfBeats - @Description Calling this routine changes the internal driver data base - from its default configuration of axi debug [1] + @Description Define DMA AXI number of beats. + Calling this routine changes the AXI number of beats in the internal + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats] @Param[in] h_Fm A handle to an FM Module. @Param[in] axiDbgNumOfBeats The selected new value. @@ -645,14 +815,17 @@ t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats); /**************************************************************************//** @Function FM_ConfigDmaCamNumOfEntries - @Description Calling this routine changes the internal driver data base - from its default configuration of number of CAM entries [32] + @Description Define number of CAM entries. + Calling this routine changes the number of CAM entries in the internal + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries]. @Param[in] h_Fm A handle to an FM Module. @Param[in] numOfEntries The selected new value. @@ -660,116 +833,28 @@ t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries); -/**************************************************************************//** - @Function FM_ConfigDmaWatchdog - - @Description Calling this routine changes the internal driver data base - from its default watchdog configuration, which is disabled - [0]. - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] watchDogValue The selected new value - in microseconds. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue); - -/**************************************************************************//** - @Function FM_ConfigDmaWriteBufThresholds - - @Description Calling this routine changes the internal driver data base - from its default configuration of DMA write buffer threshold - assertEmergency: [DMA_THRESH_MAX_BUF] - clearEmergency: [DMA_THRESH_MAX_BUF] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - - When 'assertEmergency' value is reached, emergency is asserted, - then it is held until 'clearEmergency' value is reached. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); - - /**************************************************************************//** - @Function FM_ConfigDmaCommQThresholds - - @Description Calling this routine changes the internal driver data base - from its default configuration of DMA command queue threshold - assertEmergency: [DMA_THRESH_MAX_COMMQ] - clearEmergency: [DMA_THRESH_MAX_COMMQ] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - - When 'assertEmergency' value is reached, emergency is asserted, - then it is held until 'clearEmergency' value is reached.. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); - -/**************************************************************************//** - @Function FM_ConfigDmaReadBufThresholds - - @Description Calling this routine changes the internal driver data base - from its default configuration of DMA read buffer threshold - assertEmergency: [DMA_THRESH_MAX_BUF] - clearEmergency: [DMA_THRESH_MAX_BUF] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - - When 'assertEmergency' value is reached, emergency is asserted, - then it is held until 'clearEmergency' value is reached.. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); - -/**************************************************************************//** - @Function FM_ConfigDmaSosEmergencyThreshold - - @Description Calling this routine changes the internal driver data base - from its default dma SOS emergency configuration [0] - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] dmaSosEmergency The selected new value. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency); - /**************************************************************************//** @Function FM_ConfigEnableCounters - @Description Calling this routine changes the internal driver data base - from its default counters configuration where counters are disabled. + @Description Obsolete, always return E_OK. @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). *//***************************************************************************/ t_Error FM_ConfigEnableCounters(t_Handle h_Fm); /**************************************************************************//** @Function FM_ConfigDmaDbgCounter - @Description Calling this routine changes the internal driver data base - from its default DMA debug counters configuration [e_FM_DMA_DBG_NO_CNT] + @Description Define DMA debug counter. + Calling this routine changes the number of the DMA debug counter in the internal + driver data base from its default configuration [DEFAULT_dmaDbgCntMode]. @Param[in] h_Fm A handle to an FM Module. @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode. @@ -777,15 +862,18 @@ t_Error FM_ConfigEnableCounters(t_Handle h_Fm); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode); /**************************************************************************//** @Function FM_ConfigDmaStopOnBusErr - @Description Calling this routine changes the internal driver data base - from its default selection of bus error behavior [FALSE] - + @Description Define bus error behavior. + Calling this routine changes the bus error behavior definition + in the internal driver data base from its default + configuration [DEFAULT_dmaStopOnBusError]. @Param[in] h_Fm A handle to an FM Module. @Param[in] stop TRUE to stop on bus error, FALSE to continue. @@ -794,14 +882,18 @@ t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode) @Cautions Allowed only following FM_Config() and before FM_Init(). Only if bus error is enabled. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop); /**************************************************************************//** @Function FM_ConfigDmaEmergency - @Description Calling this routine changes the internal driver data base - from its default selection of DMA emergency where's it's disabled. + @Description Define DMA emergency. + Calling this routine changes the DMA emergency definition + in the internal driver data base from its default + configuration where's it's disabled. @Param[in] h_Fm A handle to an FM Module. @Param[in] p_Emergency An OR mask of all required options. @@ -809,30 +901,18 @@ t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency); -/**************************************************************************//** - @Function FM_ConfigDmaEmergencySmoother - - @Description sets the minimum amount of DATA beats transferred on the AXI - READ and WRITE ports before lowering the emergency level. - By default smother is disabled. - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] emergencyCnt emergency switching counter. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Config() and before FM_Init(). -*//***************************************************************************/ -t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt); - /**************************************************************************//** @Function FM_ConfigDmaErr - @Description Calling this routine changes the internal driver data base - from its default DMA error treatment [e_FM_DMA_ERR_CATASTROPHIC] + @Description DMA error treatment. + Calling this routine changes the DMA error treatment + in the internal driver data base from its default + configuration [DEFAULT_dmaErr]. @Param[in] h_Fm A handle to an FM Module. @Param[in] dmaErr The selected new choice. @@ -840,14 +920,18 @@ t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr); /**************************************************************************//** @Function FM_ConfigCatastrophicErr - @Description Calling this routine changes the internal driver data base - from its default behavior on catastrophic error [e_FM_CATASTROPHIC_ERR_STALL_PORT] + @Description Define FM behavior on catastrophic error. + Calling this routine changes the FM behavior on catastrophic + error in the internal driver data base from its default + [DEFAULT_catastrophicErr]. @Param[in] h_Fm A handle to an FM Module. @Param[in] catastrophicErr The selected new choice. @@ -855,43 +939,54 @@ t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr); /**************************************************************************//** @Function FM_ConfigEnableMuramTestMode - @Description Calling this routine changes the internal driver data base + @Description Enable MURAM test mode. + Calling this routine changes the internal driver data base from its default selection of test mode where it's disabled. + This routine is only avaiable on old FM revisions (FMan v2). @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm); /**************************************************************************//** @Function FM_ConfigEnableIramTestMode - @Description Calling this routine changes the internal driver data base + @Description Enable IRAM test mode. + Calling this routine changes the internal driver data base from its default selection of test mode where it's disabled. + This routine is only avaiable on old FM revisions (FMan v2). @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm); /**************************************************************************//** @Function FM_ConfigHaltOnExternalActivation - @Description Calling this routine changes the internal driver data base - from its default selection of FM behaviour on external halt - activation [FALSE]. + @Description Define FM behavior on external halt activation. + Calling this routine changes the FM behavior on external halt + activation in the internal driver data base from its default + [DEFAULT_haltOnExternalActivation]. @Param[in] h_Fm A handle to an FM Module. @Param[in] enable TRUE to enable halt on external halt @@ -900,15 +995,19 @@ t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable); /**************************************************************************//** @Function FM_ConfigHaltOnUnrecoverableEccError - @Description Calling this routine changes the internal driver data base - from its default selection of FM behaviour on unrecoverable - Ecc error [FALSE]. + @Description Define FM behavior on external halt activation. + Calling this routine changes the FM behavior on unrecoverable + ECC error in the internal driver data base from its default + [DEFAULT_haltOnUnrecoverableEccError]. + This routine is only avaiable on old FM revisions (FMan v2). @Param[in] h_Fm A handle to an FM Module. @Param[in] enable TRUE to enable halt on unrecoverable Ecc error @@ -916,15 +1015,17 @@ t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable); /**************************************************************************//** @Function FM_ConfigException - @Description Calling this routine changes the internal driver data base - from its default selection of exceptions enablement. - By default all exceptions are enabled. + @Description Define FM exceptions. + Calling this routine changes the exceptions defaults in the + internal driver data base where all exceptions are enabled. @Param[in] h_Fm A handle to an FM Module. @Param[in] exception The exception to be selected. @@ -933,16 +1034,19 @@ t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable); /**************************************************************************//** @Function FM_ConfigExternalEccRamsEnable - @Description Calling this routine changes the internal driver data base - from its default [FALSE]. - When this option is enabled Rams ECC enable is not effected - by the FPM RCR bit, but by a JTAG. + @Description Select external ECC enabling. + Calling this routine changes the ECC enabling control in the internal + driver data base from its default [DEFAULT_externalEccRamsEnable]. + When this option is enabled Rams ECC enabling is not effected + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG. @Param[in] h_Fm A handle to an FM Module. @Param[in] enable TRUE to enable this option. @@ -950,16 +1054,18 @@ t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable) @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable); /**************************************************************************//** @Function FM_ConfigTnumAgingPeriod - @Description Calling this routine changes the internal driver data base - from its default configuration for aging of dequeue TNUM's - in the QMI.[0] - Note that this functionality is not available in all chips. + @Description Define Tnum aging period. + Calling this routine changes the Tnum aging of dequeue TNUMs + in the QMI in the internal driver data base from its default + [DEFAULT_tnumAgingPeriod]. @Param[in] h_Fm A handle to an FM Module. @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds. @@ -970,9 +1076,160 @@ t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) + NOTE that if some MAC is configured for PFC, '0' value is NOT + allowed. *//***************************************************************************/ t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod); +/**************************************************************************//* + @Function FM_ConfigDmaEmergencySmoother + + @Description Define DMA emergency smoother. + Calling this routine changes the definition of the minimum + amount of DATA beats transferred on the AXI READ and WRITE + ports before lowering the emergency level. + By default smoother is disabled. + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] emergencyCnt emergency switching counter. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt); + +/**************************************************************************//* + @Function FM_ConfigThresholds + + @Description Calling this routine changes the internal driver data base + from its default FM threshold configuration: + dispLimit: [DEFAULT_dispLimit] + prsDispTh: [DEFAULT_prsDispTh] + plcrDispTh: [DEFAULT_plcrDispTh] + kgDispTh: [DEFAULT_kgDispTh] + bmiDispTh: [DEFAULT_bmiDispTh] + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh] + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh] + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh] + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh] + + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] p_FmThresholds A structure of threshold parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds); + +/**************************************************************************//* + @Function FM_ConfigDmaSosEmergencyThreshold + + @Description Calling this routine changes the internal driver data base + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency] + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] dmaSosEmergency The selected new value. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency); + +/**************************************************************************//* + @Function FM_ConfigDmaWriteBufThresholds + + @Description Calling this routine changes the internal driver data base + from its default configuration of DMA write buffer threshold + assertEmergency: [DEFAULT_dmaWriteIntBufLow] + clearEmergency: [DEFAULT_dmaWriteIntBufHigh] + This routine is only avaiable on old FM revisions (FMan v2). + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - + When 'assertEmergency' value is reached, emergency is asserted, + then it is held until 'clearEmergency' value is reached. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); + + /**************************************************************************//* + @Function FM_ConfigDmaCommQThresholds + + @Description Calling this routine changes the internal driver data base + from its default configuration of DMA command queue threshold + assertEmergency: [DEFAULT_dmaCommQLow] + clearEmergency: [DEFAULT_dmaCommQHigh] + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - + When 'assertEmergency' value is reached, emergency is asserted, + then it is held until 'clearEmergency' value is reached.. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); + +/**************************************************************************//* + @Function FM_ConfigDmaReadBufThresholds + + @Description Calling this routine changes the internal driver data base + from its default configuration of DMA read buffer threshold + assertEmergency: [DEFAULT_dmaReadIntBufLow] + clearEmergency: [DEFAULT_dmaReadIntBufHigh] + This routine is only avaiable on old FM revisions (FMan v2). + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - + When 'assertEmergency' value is reached, emergency is asserted, + then it is held until 'clearEmergency' value is reached.. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); + +/**************************************************************************//* + @Function FM_ConfigDmaWatchdog + + @Description Calling this routine changes the internal driver data base + from its default watchdog configuration, which is disabled + [DEFAULT_dmaWatchdog]. + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] watchDogValue The selected new value - in microseconds. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue); + /** @} */ /* end of FM_advanced_init_grp group */ /** @} */ /* end of FM_init_grp group */ @@ -981,7 +1238,7 @@ t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod); @Group FM_runtime_control_grp FM Runtime Control Unit @Description FM Runtime control unit API functions, definitions and enums. - The FM driver provides a set of control routines for each module. + The FM driver provides a set of control routines. These routines may only be called after the module was fully initialized (both configuration and initialization routines were called). They are typically used to get information from hardware @@ -998,11 +1255,11 @@ t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod); FM_MAX_NUM_OF_1G_RX_PORTS + \ FM_MAX_NUM_OF_10G_RX_PORTS + \ FM_MAX_NUM_OF_1G_TX_PORTS + \ - FM_MAX_NUM_OF_10G_TX_PORTS) + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */ /* @} */ -/**************************************************************************//** - @Description Structure for Port bandwidth requirement. Port is identified +/**************************************************************************//* + @Description A Structure for Port bandwidth requirement. Port is identified by type and relative id. *//***************************************************************************/ typedef struct t_FmPortBandwidth { @@ -1011,14 +1268,15 @@ typedef struct t_FmPortBandwidth { uint8_t bandwidth; /**< bandwidth - (in term of percents) */ } t_FmPortBandwidth; -/**************************************************************************//** +/**************************************************************************//* @Description A Structure containing an array of Port bandwidth requirements. The user should state the ports requiring bandwidth in terms of percentage - i.e. all port's bandwidths in the array must add up to 100. *//***************************************************************************/ typedef struct t_FmPortsBandwidthParams { - uint8_t numOfPorts; /**< num of ports listed in the array below */ + uint8_t numOfPorts; /**< The number of relevant ports, which is the + number of valid entries in the array below */ t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS]; /**< for each port, it's bandwidth (all port's bandwidths must add up to 100.*/ @@ -1033,7 +1291,7 @@ typedef enum e_FmDmaMuramPort { } e_FmDmaMuramPort; /**************************************************************************//** - @Description enum for defining FM counters + @Description Enum for defining FM counters *//***************************************************************************/ typedef enum e_FmCounters { e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */ @@ -1045,14 +1303,11 @@ typedef enum e_FmCounters { e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */ e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */ e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */ - e_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */ - e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA semaphor reject due to full entry counter */ - e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA semaphor reject due to full CAM queue counter */ - e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA semaphor reject due to sync counter */ + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */ } e_FmCounters; /**************************************************************************//** - @Description structure for returning revision information + @Description A Structure for returning FM revision information *//***************************************************************************/ typedef struct t_FmRevisionInfo { uint8_t majorRev; /**< Major revision */ @@ -1060,16 +1315,33 @@ typedef struct t_FmRevisionInfo { } t_FmRevisionInfo; /**************************************************************************//** - @Description struct for defining DMA status + @Description A Structure for returning FM ctrl code revision information +*//***************************************************************************/ +typedef struct t_FmCtrlCodeRevisionInfo { + uint16_t packageRev; /**< Package revision */ + uint8_t majorRev; /**< Major revision */ + uint8_t minorRev; /**< Minor revision */ +} t_FmCtrlCodeRevisionInfo; + +/**************************************************************************//** + @Description A Structure for defining DMA status *//***************************************************************************/ typedef struct t_FmDmaStatus { bool cmqNotEmpty; /**< Command queue is not empty */ bool busError; /**< Bus error occurred */ - bool readBufEccError; /**< Double ECC error on buffer Read */ - bool writeBufEccSysError; /**< Double ECC error on buffer write from system side */ - bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side */ + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/ + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/ + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */ + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/ } t_FmDmaStatus; +/**************************************************************************//** + @Description A Structure for obtaining FM controller monitor values +*//***************************************************************************/ +typedef struct t_FmCtrlMon { + uint8_t percentCnt[2]; /**< Percentage value */ +} t_FmCtrlMon; + #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) /**************************************************************************//** @@ -1081,7 +1353,7 @@ typedef struct t_FmDmaStatus { @Return E_OK on success; - @Cautions Allowed only FM_Init(). + @Cautions Allowed only following FM_Init(). *//***************************************************************************/ t_Error FM_DumpRegs(t_Handle h_Fm); #endif /* (defined(DEBUG_ERRORS) && ... */ @@ -1090,7 +1362,6 @@ t_Error FM_DumpRegs(t_Handle h_Fm); @Function FM_SetException @Description Calling this routine enables/disables the specified exception. - Note: Not available for guest partition. @Param[in] h_Fm A handle to an FM Module. @Param[in] exception The exception to be selected. @@ -1099,25 +1370,11 @@ t_Error FM_DumpRegs(t_Handle h_Fm); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable); -/**************************************************************************//** - @Function FM_SetPortsBandwidth - - @Description Sets relative weights between ports when accessing common resources. - Note: Not available for guest partition. - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e. - total must equal 100. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_Init(). -*//***************************************************************************/ -t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth); - /**************************************************************************//** @Function FM_EnableRamsEcc @@ -1128,13 +1385,14 @@ t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBan setting of ECC, this routine effects IRAM ECC only. This routine is also called by the driver if an ECC exception is enabled. - Note: Not available for guest partition. @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_EnableRamsEcc(t_Handle h_Fm); @@ -1148,14 +1406,14 @@ t_Error FM_EnableRamsEcc(t_Handle h_Fm); setting of ECC, this routine effects IRAM ECC only. In opposed to FM_EnableRamsEcc, this routine must be called explicitly to disable all Rams ECC. - Note: Not available for guest partition. - @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Config() and before FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_DisableRamsEcc(t_Handle h_Fm); @@ -1173,6 +1431,20 @@ t_Error FM_DisableRamsEcc(t_Handle h_Fm); *//***************************************************************************/ t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo); +/**************************************************************************//** + @Function FM_GetFmanCtrlCodeRevision + + @Description Returns the Fman controller code revision + + @Param[in] h_Fm A handle to an FM Module. + @Param[out] p_RevisionInfo A structure of revision information parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo); + /**************************************************************************//** @Function FM_GetCounter @@ -1194,7 +1466,6 @@ uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter); @Function FM_ModifyCounter @Description Sets a value to an enabled counter. Use "0" to reset the counter. - Note: Not available for guest partition. @Param[in] h_Fm A handle to an FM Module. @Param[in] counter The requested counter. @@ -1203,6 +1474,8 @@ uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val); @@ -1210,11 +1483,14 @@ t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val); @Function FM_Resume @Description Release FM after halt FM command or after unrecoverable ECC error. - Note: Not available for guest partition. @Param[in] h_Fm A handle to an FM Module. @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ void FM_Resume(t_Handle h_Fm); @@ -1222,7 +1498,6 @@ void FM_Resume(t_Handle h_Fm); @Function FM_SetDmaEmergency @Description Manual emergency set - Note: Not available for guest partition. @Param[in] h_Fm A handle to an FM Module. @Param[in] muramPort MURAM direction select. @@ -1231,14 +1506,15 @@ void FM_Resume(t_Handle h_Fm); @Return None. @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable); /**************************************************************************//** @Function FM_SetDmaExtBusPri - @Description Manual emergency set - Note: Not available for guest partition. + @Description Set the DMA external bus priority @Param[in] h_Fm A handle to an FM Module. @Param[in] pri External bus priority select @@ -1246,55 +1522,25 @@ void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable); @Return None. @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri); -/**************************************************************************//** - @Function FM_ForceIntr - - @Description Causes an interrupt event on the requested source. - Note: Not available for guest partition. - - @Param[in] h_Fm A handle to an FM Module. - @Param[in] exception An exception to be forced. - - @Return E_OK on success; Error code if the exception is not enabled, - or is not able to create interrupt. - - @Cautions Allowed only following FM_Init(). -*//***************************************************************************/ -t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception); - /**************************************************************************//** @Function FM_GetDmaStatus @Description Reads the DMA current status - @Param[in] h_Fm A handle to an FM Module. - @Param[out] p_FmDmaStatus A structure of DMA status parameters. - - @Return None + @Param[in] h_Fm A handle to an FM Module. + @Param[out] p_FmDmaStatus A structure of DMA status parameters. @Cautions Allowed only following FM_Init(). *//***************************************************************************/ void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus); -/**************************************************************************//** - @Function FM_GetPcdHandle - - @Description Used by FMC in order to get PCD handle - - @Param[in] h_Fm A handle to an FM Module. - - @Return A handle to the PCD module, NULL if uninitialized. - - @Cautions Allowed only following FM_Init(). -*//***************************************************************************/ -t_Handle FM_GetPcdHandle(t_Handle h_Fm); - /**************************************************************************//** @Function FM_ErrorIsr - Note: Not available for guest partition. @Description FM interrupt-service-routine for errors. @@ -1311,7 +1557,6 @@ t_Error FM_ErrorIsr(t_Handle h_Fm); /**************************************************************************//** @Function FM_EventIsr - Note: Not available for guest partition. @Description FM interrupt-service-routine for normal events. @@ -1323,25 +1568,164 @@ t_Error FM_ErrorIsr(t_Handle h_Fm); *//***************************************************************************/ void FM_EventIsr(t_Handle h_Fm); -#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) /**************************************************************************//** - @Function FmDumpPortRegs + @Function FM_GetSpecialOperationCoding - @Description Dumps FM port registers which are part of FM common registers + @Description Return a specific coding according to the input mask. @Param[in] h_Fm A handle to an FM Module. - @Param[in] hardwarePortId HW port id. + @Param[in] spOper special operation mask. + @Param[out] p_SpOperCoding special operation code. @Return E_OK on success; Error code otherwise. - @Cautions Allowed only FM_Init(). + @Cautions Allowed only following FM_Init(). *//***************************************************************************/ -t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId); -#endif /* (defined(DEBUG_ERRORS) && ... */ +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm, + fmSpecialOperations_t spOper, + uint8_t *p_SpOperCoding); +/**************************************************************************//** + @Function FM_CtrlMonStart + + @Description Start monitoring utilization of all available FM controllers. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Param[in] h_Fm A handle to an FM Module. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID). +*//***************************************************************************/ +t_Error FM_CtrlMonStart(t_Handle h_Fm); + +/**************************************************************************//** + @Function FM_CtrlMonStop + + @Description Stop monitoring utilization of all available FM controllers. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Param[in] h_Fm A handle to an FM Module. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID). +*//***************************************************************************/ +t_Error FM_CtrlMonStop(t_Handle h_Fm); + +/**************************************************************************//** + @Function FM_CtrlMonGetCounters + + @Description Obtain FM controller utilization parameters. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] fmCtrlIndex FM Controller index for that utilization results + are requested. + @Param[in] p_Mon Pointer to utilization results structure. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID). +*//***************************************************************************/ +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon); + + +/**************************************************************************//* + @Function FM_ForceIntr + + @Description Causes an interrupt event on the requested source. + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] exception An exception to be forced. + + @Return E_OK on success; Error code if the exception is not enabled, + or is not able to create interrupt. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception); + +/**************************************************************************//* + @Function FM_SetPortsBandwidth + + @Description Sets relative weights between ports when accessing common resources. + + @Param[in] h_Fm A handle to an FM Module. + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e. + total must equal 100. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth); + +/**************************************************************************//* + @Function FM_GetMuramHandle + + @Description Gets the corresponding MURAM handle + + @Param[in] h_Fm A handle to an FM Module. + + @Return MURAM handle; NULL otherwise. + + @Cautions Allowed only following FM_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Handle FM_GetMuramHandle(t_Handle h_Fm); /** @} */ /* end of FM_runtime_control_grp group */ /** @} */ /* end of FM_lib_grp group */ /** @} */ /* end of FM_grp group */ + +#ifdef NCSW_BACKWARD_COMPATIBLE_API +typedef t_FmFirmwareParams t_FmPcdFirmwareParams; +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent; +typedef t_FmExtPoolParams t_FmPortExtPoolParams; +typedef t_FmExtPools t_FmPortExtPools; +typedef t_FmBackupBmPools t_FmPortBackupBmPools; +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion; +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption; +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption; + +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE + +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH +#endif /* NCSW_BACKWARD_COMPATIBLE_API */ + + #endif /* __FM_EXT */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h index 5abb60089cfe..da7e0463480a 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_mac_ext.h @@ -59,45 +60,51 @@ @{ *//***************************************************************************/ +#define FM_MAC_NO_PFC 0xff + /**************************************************************************//** @Description FM MAC Exceptions *//***************************************************************************/ typedef enum e_FmMacExceptions { - e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 - ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL - ,e_FM_MAC_EX_10G_REM_FAULT - ,e_FM_MAC_EX_10G_LOC_FAULT - ,e_FM_MAC_EX_10G_1TX_ECC_ER - ,e_FM_MAC_EX_10G_TX_FIFO_UNFL - ,e_FM_MAC_EX_10G_TX_FIFO_OVFL - ,e_FM_MAC_EX_10G_TX_ER - ,e_FM_MAC_EX_10G_RX_FIFO_OVFL - ,e_FM_MAC_EX_10G_RX_ECC_ER - ,e_FM_MAC_EX_10G_RX_JAB_FRM - ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM - ,e_FM_MAC_EX_10G_RX_RUNT_FRM - ,e_FM_MAC_EX_10G_RX_FRAG_FRM - ,e_FM_MAC_EX_10G_RX_LEN_ER - ,e_FM_MAC_EX_10G_RX_CRC_ER - ,e_FM_MAC_EX_10G_RX_ALIGN_ER - ,e_FM_MAC_EX_1G_BAB_RX - ,e_FM_MAC_EX_1G_RX_CTL - ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET - ,e_FM_MAC_EX_1G_BAB_TX - ,e_FM_MAC_EX_1G_TX_CTL - ,e_FM_MAC_EX_1G_TX_ERR - ,e_FM_MAC_EX_1G_LATE_COL - ,e_FM_MAC_EX_1G_COL_RET_LMT - ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN - ,e_FM_MAC_EX_1G_MAG_PCKT - ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET - ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET - ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET - ,e_FM_MAC_EX_1G_TX_DATA_ERR - ,e_FM_MAC_EX_1G_RX_DATA_ERR - ,e_FM_MAC_EX_1G_1588_TS_RX_ERR - ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */ + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */ + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */ + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */ + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */ + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */ + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */ + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */ + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */ + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */ + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */ + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */ + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */ + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */ + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */ + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */ + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */ + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */ + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */ + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */ + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */ + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */ + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */ + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */ + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */ + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */ + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */ + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */ + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */ + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */ + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */ + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */ + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */ + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */ + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt; + not supported on T4240/B4860 rev1 chips */ + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT + /**< mEMAC Magic Packet Indication Interrupt */ } e_FmMacExceptions; /**************************************************************************//** @@ -105,11 +112,26 @@ typedef enum e_FmMacExceptions { *//***************************************************************************/ typedef enum e_FmMacStatisticsLevel { e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */ - e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available. Optimized for performance */ - e_FM_MAC_FULL_STATISTICS /**< All counters available. Not optimized for performance */ + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */ + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */ } e_FmMacStatisticsLevel; +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Priority Flow Control Parameters +*//***************************************************************************/ +typedef struct t_FmMacPfcParams { + bool pfcEnable; /**< Enable/Disable PFC */ + + uint16_t pauseQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES]; /**< Pause Quanta per priority to be sent in a pause frame. Each quanta represents a 512 bit-times*/ + + uint16_t pauseThresholdQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES];/**< Pause threshold per priority, when timer passes this threshold time a PFC frames is sent again if the port is still congested or BM pool in depletion*/ + + +} t_FmMacPfcParams; +#endif /* (DPAA_VERSION >= 11) */ + /**************************************************************************//** @Function t_FmMacExceptionCallback @@ -119,7 +141,6 @@ typedef enum e_FmMacStatisticsLevel { @Param[in] exceptions - The exception that occurred - @Return void. *//***************************************************************************/ typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions); @@ -140,17 +161,20 @@ typedef struct t_FmMacStatistics { /* */ uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */ - uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client. */ + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */ uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/ - uint64_t eStatUndersizePkts; /**< Total number of packets that were less than 64 octets long with a good CRC.*/ - uint64_t eStatOversizePkts; /**< T,B.D*/ + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed; + This count does not include range length errors */ + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains + a valid FCS and otherwise well formed */ /* Pause */ uint64_t teStatPause; /**< Pause MAC Control received */ uint64_t reStatPause; /**< Pause MAC Control sent */ - /* MIB II */ uint64_t ifInOctets; /**< Total number of byte received. */ uint64_t ifInPkts; /**< Total number of packets received.*/ + uint64_t ifInUcastPkts; /**< Total number of unicast frame received; + NOTE: this counter is not supported on dTSEC MAC */ uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/ uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */ uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */ @@ -162,6 +186,8 @@ typedef struct t_FmMacStatistics { - The dedicated Error Code (0xfe, not a code error) was received */ uint64_t ifOutOctets; /**< Total number of byte sent. */ uint64_t ifOutPkts; /**< Total number of packets sent .*/ + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent; + NOTE: this counter is not supported on dTSEC MAC */ uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */ uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */ uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ @@ -173,7 +199,7 @@ typedef struct t_FmMacStatistics { /**************************************************************************//** - @Group FM_mac_init_grp Initialization Unit + @Group FM_mac_init_grp FM MAC Initialization Unit @Description FM MAC Initialization Unit @@ -186,8 +212,24 @@ typedef struct t_FmMacStatistics { typedef struct t_FmMacParams { uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */ t_EnetAddr addr; /**< MAC address of device; First octet is sent first */ - uint8_t macId; /**< MAC ID <10G 0> */ - e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed) */ + uint8_t macId; /**< MAC ID; + numbering of dTSEC and 1G-mEMAC: + 0 - FM_MAX_NUM_OF_1G_MACS; + numbering of 10G-MAC (TGEC) and 10G-mEMAC: + 0 - FM_MAX_NUM_OF_10G_MACS */ + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed); + Note that the speed should indicate the maximum rate that + this MAC should support rather than the actual speed; + i.e. user should use the FM_MAC_AdjustLink() routine to + provide accurate speed; + In case of mEMAC RGMII mode, the MAC is configured to RGMII + automatic mode, where actual speed/duplex mode information + is provided by PHY automatically in-band; FM_MAC_AdjustLink() + function should be used to switch to manual RGMII speed/duplex mode + configuration if RGMII PHY doesn't support in-band status signaling; + In addition, in mEMAC, in case where user is using the higher MACs + (i.e. the MACs that should support 10G), user should pass here + speed=10000 even if the interface is not allowing that (e.g. SGMII). */ t_Handle h_Fm; /**< A handle to the FM object this port related to */ int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all MACs; MUST be set to 'NO_IRQ' for MACs that don't have @@ -215,7 +257,7 @@ typedef struct t_FmMacParams { @Retval Handle to FM MAC object, or NULL for Failure. *//***************************************************************************/ -t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam); +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam); /**************************************************************************//** @Function FM_MAC_Init @@ -226,7 +268,7 @@ t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam); @Return E_OK on success; Error code otherwise. *//***************************************************************************/ -t_Error FM_MAC_Init (t_Handle h_FmMac); +t_Error FM_MAC_Init(t_Handle h_FmMac); /**************************************************************************//** @Function FM_Free @@ -239,11 +281,11 @@ t_Error FM_MAC_Init (t_Handle h_FmMac); @Return E_OK on success; Error code otherwise. *//***************************************************************************/ -t_Error FM_MAC_Free (t_Handle h_FmMac); +t_Error FM_MAC_Free(t_Handle h_FmMac); /**************************************************************************//** - @Group FM_mac_advanced_init_grp Advanced Configuration Unit + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit @Description Configuration functions used to change default values. @@ -254,7 +296,7 @@ t_Error FM_MAC_Free (t_Handle h_FmMac); @Function FM_MAC_ConfigResetOnInit @Description Tell the driver whether to reset the FM MAC before initialization or - not. It changes the default configuration [FALSE]. + not. It changes the default configuration [DEFAULT_resetOnInit]. @Param[in] h_FmMac A handle to a FM MAC Module. @Param[in] enable When TRUE, FM will be reset before any initialization. @@ -263,7 +305,7 @@ t_Error FM_MAC_Free (t_Handle h_FmMac); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_ConfigLoopback @@ -277,12 +319,12 @@ t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_ConfigMaxFrameLength - @Description Setup maximum Frame Length + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx) @Param[in] h_FmMac A handle to a FM MAC Module. @Param[in] newVal MAX Frame length @@ -291,12 +333,12 @@ t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool enable); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal); +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal); /**************************************************************************//** @Function FM_MAC_ConfigWan - @Description ENABLE WAN mode in 10G MAC + @Description ENABLE WAN mode in 10G-MAC @Param[in] h_FmMac A handle to a FM MAC Module. @Param[in] enable TRUE to enable or FALSE to disable. @@ -305,7 +347,7 @@ t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_ConfigPadAndCrc @@ -318,8 +360,11 @@ t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool enable); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is + added automatically by HW). *//***************************************************************************/ -t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_ConfigHalfDuplex @@ -333,12 +378,26 @@ t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool enable); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable); + +/**************************************************************************//** + @Function FM_MAC_ConfigTbiPhyAddr + + @Description Configures the address of internal TBI PHY. + + @Param[in] h_FmMac A handle to a FM MAC Module. + @Param[in] newVal TBI PHY address (1-31). + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). +*//***************************************************************************/ +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal); /**************************************************************************//** @Function FM_MAC_ConfigLengthCheck - @Description Configure thef frame length checking. + @Description Configure the frame length checking. @Param[in] h_FmMac A handle to a FM MAC Module. @Param[in] enable TRUE to enable or FALSE to disable. @@ -347,7 +406,7 @@ t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool enable); @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_ConfigException @@ -358,7 +417,6 @@ t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool enable); @Param[in] ex Type of the desired exceptions @Param[in] enable TRUE to enable the specified exception, FALSE to disable it. - @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). @@ -373,7 +431,7 @@ t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac); /**************************************************************************//** - @Group FM_mac_runtime_control_grp Runtime Control Unit + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit @Description FM MAC Runtime control unit API functions, definitions and enums. @@ -392,7 +450,7 @@ t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac); @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode); +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode); /**************************************************************************//** @Function FM_MAC_Disable @@ -406,7 +464,20 @@ t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode); @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode); +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode); + +/**************************************************************************//** + @Function FM_MAC_Resume + + @Description Re-init the MAC after suspend + + @Param[in] h_FmMac A handle to a FM MAC Module. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). +*//***************************************************************************/ +t_Error FM_MAC_Resume(t_Handle h_FmMac); /**************************************************************************//** @Function FM_MAC_Enable1588TimeStamp @@ -437,56 +508,108 @@ t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm); /**************************************************************************//** @Function FM_MAC_SetTxAutoPauseFrames - @Description Enable/Disable transmition of Pause-Frames. + @Description Enable/Disable transmission of Pause-Frames. + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME]. - @Param[in] h_FmMac A handle to a FM MAC Module. - @Param[in] pauseTime Pause quanta value used with transmitted pause frames. - Each quanta represents a 512 bit-times; Note that '0' - as an input here will be used as disabling the - transmission of the pause-frames. + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames. + Each quanta represents a 512 bit-times; Note that '0' + as an input here will be used as disabling the + transmission of the pause-frames. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_SetTxAutoPauseFrames (t_Handle h_FmMac, uint16_t pauseTime); +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac, + uint16_t pauseTime); + + /**************************************************************************//** + @Function FM_MAC_SetTxPauseFrames + + @Description Enable/Disable transmission of Pause-Frames. + The routine changes the default configuration: + pause-time - [DEFAULT_TX_PAUSE_TIME] + threshold-time - [0] + + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC' + to indicate legacy pause support (i.e. no PFC). + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames. + Each quanta represents a 512 bit-times; + Note that '0' as an input here will be used as disabling the + transmission of the pause-frames. + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame. + if the situation causing a pause frame to be sent didn't finish when the timer + reached the threshold quanta, the MAC will retransmit the pause frame. + Each quanta represents a 512 bit-times. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). + In order for PFC to work properly the user must configure + TNUM-aging in the tx-port it is recommended that pre-fetch and + rate limit in the tx port should be disabled; + PFC is supported only on new mEMAC; i.e. in MACs that don't have + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC' + in the 'priority' field. +*//***************************************************************************/ +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac, + uint8_t priority, + uint16_t pauseTime, + uint16_t threshTime); /**************************************************************************//** @Function FM_MAC_SetRxIgnorePauseFrames @Description Enable/Disable ignoring of Pause-Frames. - @Param[in] h_FmMac A handle to a FM MAC Module. - @Param[in] en boolean indicates whether to ignore the incoming pause - frames or not. + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] en - boolean indicates whether to ignore the incoming pause + frames or not. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en); +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en); + +/**************************************************************************//** + @Function FM_MAC_SetWakeOnLan + + @Description Enable/Disable Wake On Lan support + + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] en - boolean indicates whether to enable Wake On Lan + support or not. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). +*//***************************************************************************/ +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en); /**************************************************************************//** @Function FM_MAC_ResetCounters @Description reset all statistics counters - @Param[in] h_FmMac A handle to a FM MAC Module. + @Param[in] h_FmMac - A handle to a FM MAC Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ResetCounters (t_Handle h_FmMac); +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac); /**************************************************************************//** @Function FM_MAC_SetException @Description Enable/Disable a specific Exception - @Param[in] h_FmMac A handle to a FM MAC Module. - @Param[in] ex Type of the desired exceptions - @Param[in] enable TRUE to enable the specified exception, FALSE to disable it. + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] ex - Type of the desired exceptions + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it. @Return E_OK on success; Error code otherwise. @@ -499,35 +622,36 @@ t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) @Function FM_MAC_SetStatistics @Description Define Statistics level. - Where applicable, the routine also enables the MIB counters - overflow interrupt in order to keep counters accurate - and account for overflows. + Where applicable, the routine also enables the MIB counters + overflow interrupt in order to keep counters accurate + and account for overflows. + This routine is relevant only for dTSEC. - @Param[in] h_FmMac A handle to a FM MAC Module. - @Param[in] statisticsLevel Full statistics level provides all standard counters but may - reduce performance. Partial statistics provides only special - event counters (errors etc.). If selected, regular counters (such as - byte/packet) will be invalid and will return -1. + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may + reduce performance. Partial statistics provides only special + event counters (errors etc.). If selected, regular counters (such as + byte/packet) will be invalid and will return -1. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel); +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel); /**************************************************************************//** @Function FM_MAC_GetStatistics @Description get all statistics counters - @Param[in] h_FmMac A handle to a FM MAC Module. - @Param[in] p_Statistics Staructure with statistics + @Param[in] h_FmMac - A handle to a FM MAC Module. + @Param[in] p_Statistics - Structure with statistics @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_Init(). *//***************************************************************************/ -t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); /**************************************************************************//** @Function FM_MAC_ModifyMacAddr @@ -541,7 +665,7 @@ t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics) @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); /**************************************************************************//** @Function FM_MAC_AddHashMacAddr @@ -556,7 +680,7 @@ t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); @Cautions Allowed only following FM_MAC_Init(). It is a filter only address. @Cautions Some address need to be filterd out in upper FM blocks. *//***************************************************************************/ -t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); /**************************************************************************//** @Function FM_MAC_RemoveHashMacAddr @@ -570,7 +694,7 @@ t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); @Cautions Allowed only following FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); /**************************************************************************//** @Function FM_MAC_AddExactMatchMacAddr @@ -585,7 +709,7 @@ t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); /**************************************************************************//** @Function FM_MAC_RemovelExactMatchMacAddr @@ -599,7 +723,7 @@ t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); /**************************************************************************//** @Function FM_MAC_SetPromiscuous @@ -613,22 +737,45 @@ t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAdd @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool enable); +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable); /**************************************************************************//** @Function FM_MAC_AdjustLink @Description Adjusts the Ethernet link with new speed/duplex setup. + This routine is relevant for dTSEC and mEMAC. + In case of mEMAC, this routine is also used for manual + re-configuration of RGMII speed and duplex mode for + RGMII PHYs not supporting in-band status information + to MAC. @Param[in] h_FmMac - A handle to a FM Module. @Param[in] speed - Ethernet speed. - @Param[in] fullDuplex - TRUE for Full-Duplex mode; - FALSE for Half-Duplex mode. + @Param[in] fullDuplex - TRUE for full-duplex mode; + FALSE for half-duplex mode. @Return E_OK on success; Error code otherwise. *//***************************************************************************/ t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex); +/**************************************************************************//** + @Function FM_MAC_RestartAutoneg + + @Description Restarts the auto-negotiation process. + When auto-negotiation process is invoked under traffic the + auto-negotiation process between the internal SGMII PHY and the + external PHY does not always complete successfully. Calling this + function will restart the auto-negotiation process that will end + successfully. It is recommended to call this function after issuing + auto-negotiation restart command to the Eth Phy. + This routine is relevant only for dTSEC. + + @Param[in] h_FmMac - A handle to a FM Module. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac); + /**************************************************************************//** @Function FM_MAC_GetId @@ -641,7 +788,7 @@ t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex); @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *p_MacId); +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId); /**************************************************************************//** @Function FM_MAC_GetVesrion @@ -655,7 +802,7 @@ t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *p_MacId); @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *p_MacVresion); +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion); /**************************************************************************//** @Function FM_MAC_MII_WritePhyReg @@ -671,7 +818,7 @@ t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *p_MacVresion); @Cautions Allowed only after FM_MAC_Init(). *//***************************************************************************/ -t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data); +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data); /**************************************************************************//** @Function FM_MAC_MII_ReadPhyReg @@ -709,5 +856,4 @@ t_Error FM_MAC_DumpRegs(t_Handle h_FmMac); /** @} */ /* end of FM_grp group */ - #endif /* __FM_MAC_EXT_H */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_macsec_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_macsec_ext.h new file mode 100644 index 000000000000..57925f1040b9 --- /dev/null +++ b/sys/contrib/ncsw/inc/Peripherals/fm_macsec_ext.h @@ -0,0 +1,1271 @@ +/* + * Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/**************************************************************************//** + @File fm_macsec_ext.h + + @Description FM MACSEC ... +*//***************************************************************************/ +#ifndef __FM_MACSEC_EXT_H +#define __FM_MACSEC_EXT_H + +#include "std_ext.h" + + +/**************************************************************************//** + @Group FM_grp Frame Manager API + + @Description FM API functions, definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Group FM_MACSEC_grp FM MACSEC + + @Description FM MACSEC API functions, definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description MACSEC Exceptions +*//***************************************************************************/ +typedef enum e_FmMacsecExceptions { + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */ + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */ +} e_FmMacsecExceptions; + + +/**************************************************************************//** + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit + + @Description FM MACSEC Initialization Unit + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function t_FmMacsecExceptionsCallback + + @Description Exceptions user callback routine, will be called upon an + exception passing the exception identification. + + @Param[in] h_App A handle to an application layer object; This handle + will be passed by the driver upon calling this callback. + @Param[in] exception The exception. +*//***************************************************************************/ +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App, + e_FmMacsecExceptions exception); + + +/**************************************************************************//** + @Description FM MACSEC config input +*//***************************************************************************/ +typedef struct t_FmMacsecParams { + t_Handle h_Fm; /**< A handle to the FM object related to */ + bool guestMode; /**< Partition-id */ + union { + struct { + uint8_t fmMacId; /**< FM MAC id */ + } guestParams; + + struct { + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */ + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */ + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */ + t_Handle h_App; /**< A handle to an application layer object; This handle will + be passed by the driver upon calling the above callbacks */ + } nonGuestParams; + }; +} t_FmMacsecParams; + +/**************************************************************************//** + @Function FM_MACSEC_Config + + @Description Creates descriptor for the FM MACSEC module; + + The routine returns a handle (descriptor) to the FM MACSEC object; + This descriptor must be passed as first parameter to all other + FM MACSEC function calls; + + No actual initialization or configuration of FM MACSEC hardware is + done by this routine. + + @Param[in] p_FmMacsecParam Pointer to data structure of parameters. + + @Retval Handle to FM MACSEC object, or NULL for Failure. +*//***************************************************************************/ +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam); + +/**************************************************************************//** + @Function FM_MACSEC_Init + + @Description Initializes the FM MACSEC module. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec); + +/**************************************************************************//** + @Function FM_MACSEC_Free + + @Description Frees all resources that were assigned to FM MACSEC module; + + Calling this routine invalidates the descriptor. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec); + + +/**************************************************************************//** + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit + + @Description Configuration functions used to change default values. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description enum for unknown sci frame treatment +*//***************************************************************************/ +typedef enum e_FmMacsecUnknownSciFrameTreatment { + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */ + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard + Controlled port - Check or Disable mode */ + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */ + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED /**< If C bit set deliver on uncontrolled port and discard on controlled port, + else discard on uncontrolled port and deliver on controlled port + Controlled port - Check or Disable mode */ +} e_FmMacsecUnknownSciFrameTreatment; + +/**************************************************************************//** + @Description enum for untag frame treatment +*//***************************************************************************/ +typedef enum e_FmMacsecUntagFrameTreatment { + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */ + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */ + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */ +} e_FmMacsecUntagFrameTreatment; + +/**************************************************************************//** + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment + + @Description Change the treatment for received frames with unknown sci from its default + configuration [DEFAULT_unknownSciFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] treatMode The selected mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment + + @Description Change the treatment for received frames with invalid tags or + a zero value PN or an invalid ICV from its default configuration + [DEFAULT_invalidTagsFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; + In both cases discard on the controlled port; + this provide Strict, Check or Disable mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment + + @Description Change the treatment for received frames with the Encryption bit + set and the Changed Text bit clear from its default configuration + [DEFAULT_encryptWithNoChangedTextFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver; + In both cases discard on the controlled port; + this provide Strict, Check or Disable mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment + + @Description Change the treatment for received frames with the Encryption bit + clear and the Changed Text bit set from its default configuration + [DEFAULT_changedTextWithNoEncryptFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; + In both cases discard on the controlled port; + this provide Strict, Check or Disable mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigUntagFrameTreatment + + @Description Change the treatment for received frames without the MAC security tag (SecTAG) + from its default configuration [DEFAULT_untagFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] treatMode The selected mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment + + @Description Change the treatment for received frames with only SCB bit set + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment]. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; + In both cases discard on the controlled port; + this provide Strict, Check or Disable mode. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigPnExhaustionThreshold + + @Description It's provide the ability to configure a PN exhaustion threshold; + When the NextPn crosses this value an interrupt event + is asserted to warn that the active SA should re-key. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] pnExhThr If the threshold is reached, an interrupt event + is asserted to re-key. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigKeysUnreadable + + @Description Turn on privacy mode; All the keys and their hash values can't be read any more; + Can not be cleared unless hard reset. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigSectagWithoutSCI + + @Description Promise that all generated Sectag will be without SCI included. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec); + +/**************************************************************************//** + @Function FM_MACSEC_ConfigException + + @Description Calling this routine changes the internal driver data base + from its default selection of exceptions enablement; + By default all exceptions are enabled. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] exception The exception to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); + +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */ +/** @} */ /* end of FM_MACSEC_init_grp group */ + + +/**************************************************************************//** + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit + + @Description FM MACSEC runtime control data unit API functions, definitions and enums. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function FM_MACSEC_GetRevision + + @Description Return MACSEC HW chip revision + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only after FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision); + +/**************************************************************************//** + @Function FM_MACSEC_Enable + + @Description This routine should be called after MACSEC is initialized for enabling all + MACSEC engines according to their existing configuration. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled. +*//***************************************************************************/ +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec); + +/**************************************************************************//** + @Function FM_MACSEC_Disable + + @Description This routine may be called when MACSEC is enabled in order to + disable all MACSEC engines; The MACSEC is working in bypass mode. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled. +*//***************************************************************************/ +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec); + +/**************************************************************************//** + @Function FM_MACSEC_SetException + + @Description Calling this routine enables/disables the specified exception. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[in] exception The exception to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); + +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) +/**************************************************************************//** + @Function FM_MACSEC_DumpRegs + + @Description Dump internal registers. + + @Param[in] h_FmMacsec - FM MACSEC module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only after FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec); +#endif /* (defined(DEBUG_ERRORS) && ... */ + +#ifdef VERIFICATION_SUPPORT +/********************* VERIFICATION ONLY ********************************/ +/**************************************************************************//** + @Function FM_MACSEC_BackdoorSet + + @Description Set register of the MACSEC memory map + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[out] offset Register offset. + @Param[out] value Value to write. + + + @Return None + + @Cautions Allowed only following FM_MACSEC_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value); + +/**************************************************************************//** + @Function FM_MACSEC_BackdoorGet + + @Description Read from register of the MACSEC memory map. + + @Param[in] h_FmMacsec FM MACSEC module descriptor. + @Param[out] offset Register offset. + + @Return Value read + + @Cautions Allowed only following FM_MACSEC_Init(). +*//***************************************************************************/ +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset); +#endif /* VERIFICATION_SUPPORT */ + +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */ + + +/**************************************************************************//** + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY + + @Description FM-MACSEC SecY API functions, definitions and enums + + @{ +*//***************************************************************************/ + +typedef uint8_t macsecSAKey_t[32]; +typedef uint64_t macsecSCI_t; +typedef uint8_t macsecAN_t; + +/**************************************************************************//** +@Description MACSEC SECY Cipher Suite +*//***************************************************************************/ +typedef enum e_FmMacsecSecYCipherSuite { + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */ +#if (DPAA_VERSION >= 11) + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */ +#endif /* (DPAA_VERSION >= 11) */ +} e_FmMacsecSecYCipherSuite; + +/**************************************************************************//** + @Description MACSEC SECY Exceptions +*//***************************************************************************/ +typedef enum e_FmMacsecSecYExceptions { + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */ +} e_FmMacsecSecYExceptions; + +/**************************************************************************//** + @Description MACSEC SECY Events +*//***************************************************************************/ +typedef enum e_FmMacsecSecYEvents { + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */ +} e_FmMacsecSecYEvents; + +/**************************************************************************//** + @Collection MACSEC SECY Frame Discarded Descriptor error +*//***************************************************************************/ +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */ + +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */ +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */ +/* @} */ + +/**************************************************************************//** + @Function t_FmMacsecSecYExceptionsCallback + + @Description Exceptions user callback routine, will be called upon an + exception passing the exception identification. + + @Param[in] h_App A handle to an application layer object; This handle + will be passed by the driver upon calling this callback. + @Param[in] exception The exception. +*//***************************************************************************/ +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App, + e_FmMacsecSecYExceptions exception); + +/**************************************************************************//** + @Function t_FmMacsecSecYEventsCallback + + @Description Events user callback routine, will be called upon an + event passing the event identification. + + @Param[in] h_App A handle to an application layer object; This handle + will be passed by the driver upon calling this callback. + @Param[in] event The event. +*//***************************************************************************/ +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App, + e_FmMacsecSecYEvents event); + +/**************************************************************************//** + @Description RFC2863 MIB +*//***************************************************************************/ +typedef struct t_MIBStatistics { + uint64_t ifInOctets; /**< Total number of byte received */ + uint64_t ifInPkts; /**< Total number of packets received */ + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */ + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */ + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX : + - InPktsNoTag, + - InPktsLate, + - InPktsOverrun */ + uint64_t ifInErrors; /**< Number of frames received with error: + - InPktsBadTag, + - InPktsNoSCI, + - InPktsNotUsingSA + - InPktsNotValid */ + uint64_t ifOutOctets; /**< Total number of byte sent */ + uint64_t ifOutPkts; /**< Total number of packets sent */ + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */ + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */ + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */ + uint64_t ifOutErrors; /**< Number of frames transmitted with error: + - FIFO Overflow Error + - FIFO Underflow Error + - Other */ +} t_MIBStatistics; + +/**************************************************************************//** + @Description MACSEC SecY Rx SA Statistics +*//***************************************************************************/ +typedef struct t_FmMacsecSecYRxSaStatistics { + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all + frame validation frame validation with the validateFrame not set to disable */ + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame + validation with the validateFrame set to check */ + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port, + that have failed frame validation with the validateFrame set to strict or the c bit is set */ + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or + not provisioned SA with validateFrame in the strict mode or the C bit is set */ + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA + with validateFrame not in the strict mode and the C bit is cleared */ +} t_FmMacsecSecYRxSaStatistics; + +/**************************************************************************//** + @Description MACSEC SecY Tx SA Statistics +*//***************************************************************************/ +typedef struct t_FmMacsecSecYTxSaStatistics { + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to + be transmitted, which were integrity protected */ + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to + be transmitted, which were confidentiality protected */ +} t_FmMacsecSecYTxSaStatistics; + +/**************************************************************************//** + @Description MACSEC SecY Rx SC Statistics +*//***************************************************************************/ +typedef struct t_FmMacsecSecYRxScStatistics { + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port, + that are not validated with the validateFrame set to disable */ + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port, + that have their PN smaller than the lowest_PN with the validateFrame set to + disable or replayProtect disabled */ + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port, + that have their PN smaller than the lowest_PN with the validateFrame set to + Check or Strict and replayProtect enabled */ + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all + frame validation frame validation with the validateFrame not set to disable */ + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame + validation with the validateFrame set to check */ + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port, + that have failed frame validation with the validateFrame set to strict or the c bit is set */ + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or + not provisioned SA with validateFrame in the strict mode or the C bit is set */ + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA + with validateFrame not in the strict mode and the C bit is cleared */ +} t_FmMacsecSecYRxScStatistics; + +/**************************************************************************//** + @Description MACSEC SecY Tx SC Statistics +*//***************************************************************************/ +typedef struct t_FmMacsecSecYTxScStatistics { + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to + be transmitted, which were integrity protected */ + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to + be transmitted, which were confidentiality protected */ +} t_FmMacsecSecYTxScStatistics; + +/**************************************************************************//** + @Description MACSEC SecY Statistics +*//***************************************************************************/ +typedef struct t_FmMacsecSecYStatistics { + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */ + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */ +/* Frame verification statistics */ + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag + (SecTAG) with validateFrames which is not in the strict mode */ + uint64_t inPktsNoTag; /**< The number of received packets discarded without the + MAC security tag (SecTAG) with validateFrames which is in the strict mode */ + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid + SecTAG or a zero value PN or an invalid ICV */ + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the + condition : validateFrames is not in the strict mode and the + C bit in the SecTAG is not set */ + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI + information with the condition : validateFrames is in the strict mode + or the C bit in the SecTAG is set */ + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of + received packets exceeded the cryptographic performance capabilities */ +/* Frame validation statistics */ + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with + resolved SCI that were integrity protected but not encrypted */ + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with + resolved SCI that were integrity protected and encrypted */ +/* Frame generation statistics */ + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to + be transmitted, with protectFrame false */ + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */ +/* Frame protection statistics */ + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were + integrity protected but not encrypted */ + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were + both integrity protected and encrypted */ +} t_FmMacsecSecYStatistics; + + +/**************************************************************************//** + @Description MACSEC SecY SC Params +*//***************************************************************************/ +typedef struct t_FmMacsecSecYSCParams { + macsecSCI_t sci; /**< The secure channel identification of the SC */ + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */ +} t_FmMacsecSecYSCParams; + +/**************************************************************************//** + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit + + @Description FM-MACSEC SecY Initialization Unit + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description enum for validate frames +*//***************************************************************************/ +typedef enum e_FmMacsecValidFrameBehavior { + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */ + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking + without filtering out invalid frames */ + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter + out those invalid frames */ +} e_FmMacsecValidFrameBehavior; + +/**************************************************************************//** + @Description enum for sci insertion +*//***************************************************************************/ +typedef enum e_FmMacsecSciInsertionMode { + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */ + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/ + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */ +} e_FmMacsecSciInsertionMode; + +/**************************************************************************//** + @Description FM MACSEC SecY config input +*//***************************************************************************/ +typedef struct t_FmMacsecSecYParams { + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */ + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */ + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */ + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */ + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */ + t_Handle h_App; /**< A handle to an application layer object; This handle will + be passed by the driver upon calling the above callbacks */ +} t_FmMacsecSecYParams; + +/**************************************************************************//** + @Function FM_MACSEC_SECY_Config + + @Description Creates descriptor for the FM MACSEC SECY module; + + The routine returns a handle (descriptor) to the FM MACSEC SECY object; + This descriptor must be passed as first parameter to all other + FM MACSEC SECY function calls; + No actual initialization or configuration of FM MACSEC SecY hardware is + done by this routine. + + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters. + + @Return Handle to FM MACSEC SECY object, or NULL for Failure. +*//***************************************************************************/ +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_Init + + @Description Initializes the FM MACSEC SECY module. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_Free + + @Description Frees all resources that were assigned to FM MACSEC SECY module. + + Calling this routine invalidates the descriptor. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY); + +/**************************************************************************//** + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit + + @Description Configuration functions used to change default values. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigSciInsertionMode + + @Description Calling this routine changes the SCI-insertion-mode in the + internal driver data base from its default configuration + [DEFAULT_sciInsertionMode] + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] sciInsertionMode Sci insertion mode + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigProtectFrames + + @Description Calling this routine changes the protect-frame mode in the + internal driver data base from its default configuration + [DEFAULT_protectFrames] + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] protectFrames If FALSE, frames are transmitted without modification + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigReplayWindow + + @Description Calling this routine changes the replay-window settings in the + internal driver data base from its default configuration + [DEFAULT_replayEnable], [DEFAULT_replayWindow] + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] replayProtect; Replay protection function mode + @Param[in] replayWindow; The size of the replay window + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigValidationMode + + @Description Calling this routine changes the frame-validation-behavior mode + in the internal driver data base from its default configuration + [DEFAULT_validateFrames] + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] validateFrames Validation function mode + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigConfidentiality + + @Description Calling this routine changes the confidentiality settings in the + internal driver data base from its default configuration + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset] + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection + FALSE - no confidentiality protection, only integrity protection + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection + common values are 0, 30, and 50 + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigPointToPoint + + @Description configure this SecY to work in point-to-point mode, means that + it will have only one rx sc; + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); + Can be called only once in a system; only the first secY that will call this + routine will be able to operate in Point-To-Point mode. +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigException + + @Description Calling this routine changes the internal driver data base + from its default selection of exceptions enablement; + By default all exceptions are enabled. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] exception The exception to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_ConfigEvent + + @Description Calling this routine changes the internal driver data base + from its default selection of events enablement; + By default all events are enabled. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] event The event to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable); + +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */ +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */ + + +/**************************************************************************//** + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit + + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function FM_MACSEC_SECY_CreateRxSc + + @Description Create a receive secure channel. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] scParams secure channel params. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_DeleteRxSc + + @Description Deleting an initialized secure channel. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_CreateRxSa + + @Description Create a receive secure association for the secure channel; + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + @Param[in] lowestPn the lowest acceptable PN value for a received frame. + @Param[in] key the desired key for this SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_DeleteRxSa + + @Description Deleting an initialized secure association. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaEnableReceive + + @Description Enabling the SA to receive frames. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaDisableReceive + + @Description Disabling the SA from receive frames. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaUpdateNextPn + + @Description Update the next packet number expected on RX; + The value of nextPN shall be set to the greater of its existing value and the + supplied of updtNextPN (802.1AE-2006 10.7.15). + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + @Param[in] updtNextPN the next PN value for a received frame. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn + + @Description Update the lowest packet number expected on RX; + The value of lowestPN shall be set to the greater of its existing value and the + supplied of updtLowestPN (802.1AE-2006 10.7.15). + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaModifyKey + + @Description Modify the current key of the SA with a new one. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[in] an association number represent the SA. + @Param[in] key new key to replace the current key. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_CreateTxSa + + @Description Create a transmit secure association for the secure channel; + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called; + Only one SA can be active at a time. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] an association number represent the SA. + @Param[in] key the desired key for this SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_DeleteTxSa + + @Description Deleting an initialized secure association. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] an association number represent the SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_TxSaModifyKey + + @Description Modify the key of the inactive SA with a new one. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] nextActiveAn association number represent the next SA to be activated. + @Param[in] key new key to replace the current key. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_TxSaSetActive + + @Description Set this SA to the active SA to be used on TX for SC; + only one SA can be active at a time. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] an association number represent the SA. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_TxSaGetActive + + @Description Get the active SA that being used for TX. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[out] p_An the active an. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_GetStatistics + + @Description get all statistics counters. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] p_Statistics Structure with statistics. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxScGetStatistics + + @Description get all statistics counters. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc Rx Sc handle. + @Param[in] p_Statistics Structure with statistics. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_RxSaGetStatistics + + @Description get all statistics counters + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc Rx Sc handle. + @Param[in] an association number represent the SA. + @Param[in] p_Statistics Structure with statistics. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_TxScGetStatistics + + @Description get all statistics counters. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] p_Statistics Structure with statistics. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_TxSaGetStatistics + + @Description get all statistics counters. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] an association number represent the SA. + @Param[in] p_Statistics Structure with statistics. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_SetException + + @Description Calling this routine enables/disables the specified exception. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] exception The exception to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_SetEvent + + @Description Calling this routine enables/disables the specified event. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] event The event to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_GetRxScPhysId + + @Description return the physical id of the Secure Channel. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. + @Param[out] p_ScPhysId the SC physical id. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId); + +/**************************************************************************//** + @Function FM_MACSEC_SECY_GetTxScPhysId + + @Description return the physical id of the Secure Channel. + + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. + @Param[out] p_ScPhysId the SC physical id. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MACSEC_SECY_Init(). +*//***************************************************************************/ +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId); + +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */ +/** @} */ /* end of FM_MACSEC_SECY_grp group */ +/** @} */ /* end of FM_MACSEC_grp group */ +/** @} */ /* end of FM_grp group */ + + +#endif /* __FM_MACSEC_EXT_H */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h index 0c99ef3f4480..ef62c8ef28d5 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_muram_ext.h @@ -60,7 +61,7 @@ *//***************************************************************************/ /**************************************************************************//** - @Group FM_muram_init_grp FM MURAM Initialization + @Group FM_muram_init_grp FM MURAM Initialization Unit @Description FM MURAM initialization API functions, definitions and enums @@ -103,7 +104,7 @@ t_Error FM_MURAM_Free(t_Handle h_FmMuram); /**************************************************************************//** - @Group FM_muram_ctrl_grp FM MURAM Control + @Group FM_muram_ctrl_grp FM MURAM Control Unit @Description FM MURAM control API functions, definitions and enums @@ -149,6 +150,17 @@ void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size) *//***************************************************************************/ t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr); +/**************************************************************************//** + @Function FM_MURAM_GetFreeMemSize + + @Description Returns the size (in bytes) of free MURAM memory. + + @Param[in] h_FmMuram - FM-MURAM module descriptor. + + @Return Free MURAM memory size in bytes. +*//***************************************************************************/ +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram); + /** @} */ /* end of FM_muram_ctrl_grp group */ /** @} */ /* end of FM_muram_grp group */ /** @} */ /* end of FM_grp group */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h index 6de21e736960..8d1c3d889451 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,10 +30,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_pcd_ext.h - @Description FM PCD ... + @Description FM PCD API definitions *//***************************************************************************/ #ifndef __FM_PCD_EXT #define __FM_PCD_EXT @@ -42,13 +43,13 @@ #include "net_ext.h" #include "list_ext.h" #include "fm_ext.h" +#include "fsl_fman_kg.h" /**************************************************************************//** - @Group FM_grp Frame Manager API - @Description FM API functions, definitions and enums + @Description Frame Manager Application Programming Interface @{ *//***************************************************************************/ @@ -56,18 +57,18 @@ /**************************************************************************//** @Group FM_PCD_grp FM PCD - @Description FM PCD API functions, definitions and enums + @Description Frame Manager PCD (Parse-Classify-Distribute) API. The FM PCD module is responsible for the initialization of all global classifying FM modules. This includes the parser general and common registers, the key generator global and common registers, - and the Policer global and common registers. + and the policer global and common registers. In addition, the FM PCD SW module will initialize all required - key generator schemes, coarse classification flows, and Policer - profiles. When An FM module is configured to work with one of these + key generator schemes, coarse classification flows, and policer + profiles. When FM module is configured to work with one of these entities, it will register to it using the FM PORT API. The PCD module will manage the PCD resources - i.e. resource management of - Keygen schemes, etc. + KeyGen schemes, etc. @{ *//***************************************************************************/ @@ -75,52 +76,41 @@ /**************************************************************************//** @Collection General PCD defines *//***************************************************************************/ -typedef uint32_t fmPcdEngines_t; /**< options as defined below: */ - -#define FM_PCD_NONE 0 /**< No PCD Engine indicated */ -#define FM_PCD_PRS 0x80000000 /**< Parser indicated */ -#define FM_PCD_KG 0x40000000 /**< Keygen indicated */ -#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */ -#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */ -#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */ - #define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */ #define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */ #define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) - /**< number of distinction units is limited by - register size (32), - reserved bits for - private headers. */ - -#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers in a distinction unit */ -#define FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KG registers */ -#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration. - For reason of HW implementation, in most - cases less than this will be allowed. The - driver will return error in initialization - time if resource is overused. */ -#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KG extractions. */ + /**< Number of distinction units is limited by + register size (32 bits) minus reserved bits + for private headers. */ +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers + in a distinction unit */ +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */ +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration; + For HW implementation reasons, in most + cases less than this will be allowed; The + driver will return an initialization error + if resource is unavailable. */ +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */ #define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */ -#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Max number of SW parser label */ -#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of sw parser area */ -#define FM_PCD_PRS_SW_OFFSET 0x00000040 /**< Size of illegal addresses at the beginning - of the SW parser area */ -#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */ -#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at - the end of the SW parser area */ -#define FM_SW_PRS_MAX_IMAGE_SIZE (FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_OFFSET-FM_PCD_PRS_SW_TAIL_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE) - /**< Max possible size of SW parser code */ +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */ +#define FM_SW_PRS_MAX_IMAGE_SIZE (FM_PCD_SW_PRS_SIZE /*- FM_PCD_PRS_SW_OFFSET -FM_PCD_PRS_SW_TAIL_SIZE*/-FM_PCD_PRS_SW_PATCHES_SIZE) + /**< Maximum size of SW parser code */ -#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Max possible size of insertion template for - insert manipulation*/ +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for + insert manipulation */ + +#if (DPAA_VERSION >= 11) +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */ +#endif /* (DPAA_VERSION >= 11) */ /* @} */ /**************************************************************************//** @Group FM_PCD_init_grp FM PCD Initialization Unit - @Description FM PCD Initialization Unit + @Description Frame Manager PCD Initialization Unit API @{ *//***************************************************************************/ @@ -129,44 +119,46 @@ typedef uint32_t fmPcdEngines_t; /**< options as defined below: */ @Description PCD counters *//***************************************************************************/ typedef enum e_FmPcdCounters { - e_FM_PCD_KG_COUNTERS_TOTAL, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter */ - e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter */ - e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter */ - e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter */ - e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter */ - e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter */ - e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter */ - e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter */ + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */ + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */ + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */ + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer; + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */ + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer; + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */ + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */ + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */ + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */ + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */ + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */ + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */ + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */ + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */ + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */ + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */ + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */ + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */ + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */ + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */ + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */ + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */ + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */ + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */ + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */ } e_FmPcdCounters; /**************************************************************************//** @Description PCD interrupts *//***************************************************************************/ typedef enum e_FmPcdExceptions { - e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< Keygen ECC error */ - e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Read Buffer ECC error */ - e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< Write Buffer ECC error on system side */ - e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Write Buffer ECC error on FM side */ - e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Self init complete */ - e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Atomic action complete */ - e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser ECC error */ - e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single ECC */ + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */ + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */ + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */ + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */ + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */ + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */ + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */ + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */ } e_FmPcdExceptions; @@ -194,7 +186,7 @@ typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App, /**************************************************************************//** @Description A callback for enqueuing frame onto a QM queue. - @Param[in] h_App - User's application descriptor. + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue. @Param[in] p_Fd - Frame descriptor for the frame. @Return E_OK on success; Error code otherwise. @@ -202,54 +194,60 @@ typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App, typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd); /**************************************************************************//** - @Description A structure for Host-Command + @Description Host-Command parameters structure. + When using Host command for PCD functionalities, a dedicated port must be used. If this routine is called for a PCD in a single partition - environment, or it is the Master partition in a Multi partition + environment, or it is the Master partition in a Multi-partition environment, The port will be initialized by the PCD driver initialization routine. *//***************************************************************************/ typedef struct t_FmPcdHcParams { - uintptr_t portBaseAddr; /**< Host-Command Port Virtual Address of - memory mapped registers.*/ - uint8_t portId; /**< Host-Command Port Id (0-6 relative - to Host-Command/Offline parsing ports) */ - uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be - used together with LIODN offset. */ - uint32_t errFqid; /**< Host-Command Port Error Queue Id. */ - uint32_t confFqid; /**< Host-Command Port Confirmation queue Id. */ - uint32_t qmChannel; /**< Host-Command port - QM-channel dedicated to - this port will be used by the FM for dequeue. */ - t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Call back routine for enqueuing a frame to the QM */ - t_Handle h_QmArg; /**< A handle of the QM module */ + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/ + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports); + NOTE: When configuring Host Command port for + FMANv3 devices (DPAA_VERSION 11 and higher), + portId=0 MUST be used. */ + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset + (irrelevant for P4080 revision 1.0) */ + uint32_t errFqid; /**< Host-Command Port error queue Id. */ + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */ + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port; + will be used by the FM for dequeue. */ + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */ + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */ } t_FmPcdHcParams; /**************************************************************************//** @Description The main structure for PCD initialization *//***************************************************************************/ typedef struct t_FmPcdParams { - bool prsSupport; /**< TRUE if Parser will be used for any - of the FM ports */ + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */ bool ccSupport; /**< TRUE if Coarse Classification will be used for any - of the FM ports */ - bool kgSupport; /**< TRUE if Keygen will be used for any - of the FM ports */ - bool plcrSupport; /**< TRUE if Policer will be used for any - of the FM ports */ - t_Handle h_Fm; /**< A handle to the FM module */ - uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition. */ + of the FM ports. */ + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */ + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */ + t_Handle h_Fm; /**< A handle to the FM module. */ + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition. + this parameter is relevant if 'kgSupport'=TRUE. */ bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */ - t_FmPcdHcParams hc; /**< Relevant only if useHostCommand=TRUE. - Host Command parameters. */ + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE; + Relevant when FM not runs in "guest-mode". */ - t_FmPcdExceptionCallback *f_Exception; /**< Relevant for master (or single) partition only: Callback routine - to be called of PCD exception */ - t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Relevant for master (or single) partition only: Callback routine - to be used for a single scheme and - profile exceptions */ - t_Handle h_App; /**< Relevant for master (or single) partition only: A handle to an - application layer object; This handle will - be passed by the driver upon calling the above callbacks */ + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions; + Relevant when FM not runs in "guest-mode". */ + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or + Policer profile exceptions; + Relevant when FM not runs in "guest-mode". */ + t_Handle h_App; /**< A handle to an application layer object; This handle will + be passed by the driver upon calling the above callbacks; + Relevant when FM not runs in "guest-mode". */ + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition. + this parameter is relevant if 'plcrSupport'=TRUE. + NOTE: this parameter relevant only when working with multiple partitions. */ + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition. + this parameter is relevant if 'plcrSupport'=TRUE. + NOTE: this parameter relevant only when working with multiple partitions. */ } t_FmPcdParams; @@ -290,19 +288,54 @@ t_Error FM_PCD_Init(t_Handle h_FmPcd); t_Error FM_PCD_Free(t_Handle h_FmPcd); /**************************************************************************//** - @Group FM_PCD_advanced_init_grp FM PCD Advanced Configuration Unit + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit - @Description Configuration functions used to change default values. + @Description Frame Manager PCD Advanced Configuration API. @{ *//***************************************************************************/ +/**************************************************************************//** + @Function FM_PCD_ConfigException + + @Description Calling this routine changes the internal driver data base + from its default selection of exceptions enabling. + [DEFAULT_numOfSharedPlcrProfiles]. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] exception The exception to be selected. + @Param[in] enable TRUE to enable interrupt, FALSE to mask it. + + @Return E_OK on success; Error code otherwise. + + @Cautions This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable); + +/**************************************************************************//** + @Function FM_PCD_ConfigHcFramesDataMemory + + @Description Configures memory-partition-id for FMan-Controller Host-Command + frames. Calling this routine changes the internal driver data + base from its default configuration [0]. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] memId Memory partition ID. + + @Return E_OK on success; Error code otherwise. + + @Cautions This routine may be called only if 'useHostCommand' was TRUE + when FM_PCD_Config() routine was called. +*//***************************************************************************/ +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId); + /**************************************************************************//** @Function FM_PCD_ConfigPlcrNumOfSharedProfiles @Description Calling this routine changes the internal driver data base from its default selection of exceptions enablement. - [4]. + [DEFAULT_numOfSharedPlcrProfiles]. @Param[in] h_FmPcd FM PCD module descriptor. @Param[in] numOfSharedPlcrProfiles Number of profiles to @@ -312,36 +345,20 @@ t_Error FM_PCD_Free(t_Handle h_FmPcd); *//***************************************************************************/ t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles); -/**************************************************************************//** - @Function FM_PCD_ConfigException - - @Description Calling this routine changes the internal driver data base - from its default selection of exceptions enablement. - By default all exceptions are enabled. - - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] exception The exception to be selected. - @Param[in] enable TRUE to enable interrupt, FALSE to mask it. - - @Return E_OK on success; Error code otherwise. - - @Cautions Not available for guest partition. -*//***************************************************************************/ -t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable); - /**************************************************************************//** @Function FM_PCD_ConfigPlcrAutoRefreshMode @Description Calling this routine changes the internal driver data base from its default selection of exceptions enablement. - By default autorefresh is enabled. + By default auto-refresh is [DEFAULT_plcrAutoRefresh]. @Param[in] h_FmPcd FM PCD module descriptor. @Param[in] enable TRUE to enable, FALSE to disable @Return E_OK on success; Error code otherwise. - @Cautions Not available for guest partition. + @Cautions This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable); @@ -350,7 +367,7 @@ t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable); @Description Calling this routine changes the internal data structure for the maximum parsing time from its default value - [0]. + [DEFAULT_MAX_PRS_CYC_LIM]. @Param[in] h_FmPcd FM PCD module descriptor. @Param[in] value 0 to disable the mechanism, or new @@ -358,46 +375,46 @@ t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable); @Return E_OK on success; Error code otherwise. - @Cautions Not available for guest partition. + @Cautions This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value); -/** @} */ /* end of FM_PCD_advanced_init_grp group */ +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */ /** @} */ /* end of FM_PCD_init_grp group */ /**************************************************************************//** @Group FM_PCD_Runtime_grp FM PCD Runtime Unit - @Description FM PCD Runtime Unit + @Description Frame Manager PCD Runtime Unit API The runtime control allows creation of PCD infrastructure modules such as Network Environment Characteristics, Classification Plan Groups and Coarse Classification Trees. It also allows on-the-fly initialization, modification and removal - of PCD modules such as Keygen schemes, coarse classification nodes + of PCD modules such as KeyGen schemes, coarse classification nodes and Policer profiles. - In order to explain the programming model of the PCD driver interface a few terms should be explained, and will be used below. - * Distinction Header - One of the 16 protocols supported by the FM parser, - or one of the shim headers (1 or 2). May be a header with a special + - Distinction Header - One of the 16 protocols supported by the FM parser, + or one of the SHIM headers (1 or 2). May be a header with a special option (see below). - * Interchangeable Headers Group- This is a group of Headers recognized + - Interchangeable Headers Group - This is a group of Headers recognized by either one of them. For example, if in a specific context the user chooses to treat IPv4 and IPV6 in the same way, they may create an interchangeable Headers Unit consisting of these 2 headers. - * A Distinction Unit - a Distinction Header or an Interchangeable Headers + - A Distinction Unit - a Distinction Header or an Interchangeable Headers Group. - * Header with special option - applies to ethernet, mpls, vlan, ipv4 and - ipv6, includes multicast, broadcast and other protocol specific options. + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and + IPv6, includes multicast, broadcast and other protocol specific options. In terms of hardware it relates to the options available in the classification plan. - * Network Environment Characteristics - a set of Distinction Units that define + - Network Environment Characteristics - a set of Distinction Units that define the total recognizable header selection for a certain environment. This is NOT the list of all headers that will ever appear in a flow, but rather - everything that needs distinction in a flow, where distinction is made by keygen + everything that needs distinction in a flow, where distinction is made by KeyGen schemes and coarse classification action descriptors. The PCD runtime modules initialization is done in stages. The first stage after @@ -410,20 +427,23 @@ t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value); *//***************************************************************************/ /**************************************************************************//** - @Description A structure for sw parser labels + @Description A structure for SW parser labels *//***************************************************************************/ typedef struct t_FmPcdPrsLabelParams { uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes resolution), relative to Parser RAM. */ - e_NetHeaderType hdr; /**< The existance of this header will envoke - the sw parser code. */ - uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser + e_NetHeaderType hdr; /**< The existence of this header will invoke + the SW parser code; Use HEADER_TYPE_NONE + to indicate that sw parser is to run + independent of the existence of any protocol + (run before HW parser). */ + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser attachments for the same header, use this index to distinguish between them. */ } t_FmPcdPrsLabelParams; /**************************************************************************//** - @Description A structure for sw parser + @Description A structure for SW parser *//***************************************************************************/ typedef struct t_FmPcdPrsSwParams { bool override; /**< FALSE to invoke a check that nothing else @@ -472,7 +492,6 @@ t_Error FM_PCD_Enable(t_Handle h_FmPcd); *//***************************************************************************/ t_Error FM_PCD_Disable(t_Handle h_FmPcd); - /**************************************************************************//** @Function FM_PCD_GetCounter @@ -491,28 +510,45 @@ t_Error FM_PCD_Disable(t_Handle h_FmPcd); uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter); /**************************************************************************//** -@Function FM_PCD_PrsLoadSw +@Function FM_PCD_PrsLoadSw -@Description This routine may be called in order to load software parsing code. +@Description This routine may be called in order to load software parsing code. -@Param[in] h_FmPcd FM PCD module descriptor. -@Param[in] p_SwPrs A pointer to a structure of software +@Param[in] h_FmPcd FM PCD module descriptor. +@Param[in] p_SwPrs A pointer to a structure of software parser parameters, including the software parser image. +@Return E_OK on success; Error code otherwise. + +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs); + +/**************************************************************************//** +@Function FM_PCD_SetAdvancedOffloadSupport + +@Description This routine must be called in order to support the following features: + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator. + +@Param[in] h_FmPcd FM PCD module descriptor. + @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ -t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs); +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd); /**************************************************************************//** @Function FM_PCD_KgSetDfltValue @Description Calling this routine sets a global default value to be used - by the keygen when parser does not recognize a required + by the KeyGen when parser does not recognize a required field/header. By default default values are 0. @@ -523,14 +559,15 @@ t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value); /**************************************************************************//** @Function FM_PCD_KgSetAdditionalDataAfterParsing - @Description Calling this routine allows the keygen to access data past + @Description Calling this routine allows the KeyGen to access data past the parser finishing point. @Param[in] h_FmPcd FM PCD module descriptor. @@ -539,7 +576,8 @@ t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset); @@ -555,7 +593,8 @@ t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payload @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable); @@ -571,7 +610,8 @@ t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value); @@ -587,7 +627,8 @@ t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable); @@ -602,26 +643,11 @@ t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable); @Return None @Cautions Allowed only following FM_PCD_Init(). - Not available for guest partition. + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable); -/**************************************************************************//** - @Function FM_PCD_ForceIntr - - @Description Causes an interrupt event on the requested source. - - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] exception An exception to be forced. - - @Return E_OK on success; Error code if the exception is not enabled, - or is not able to create interrupt. - - @Cautions Allowed only following FM_PCD_Init(). - Not available for guest partition. -*//***************************************************************************/ -t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception); - /**************************************************************************//** @Function FM_PCD_HcTxConf @@ -636,6 +662,23 @@ t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception); *//***************************************************************************/ void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd); +/**************************************************************************//* + @Function FM_PCD_ForceIntr + + @Description Causes an interrupt event on the requested source. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] exception An exception to be forced. + + @Return E_OK on success; Error code if the exception is not enabled, + or is not able to create interrupt. + + @Cautions Allowed only following FM_PCD_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) +*//***************************************************************************/ +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception); + #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) /**************************************************************************//** @Function FM_PCD_DumpRegs @@ -647,6 +690,9 @@ void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers + are mapped. *//***************************************************************************/ t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd); @@ -660,46 +706,57 @@ t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers + are mapped. *//***************************************************************************/ t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd); /**************************************************************************//** @Function FM_PCD_PlcrDumpRegs - @Description Dumps all PCD Plcr registers + @Description Dumps all PCD Policer registers @Param[in] h_FmPcd A handle to an FM PCD Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers + are mapped. *//***************************************************************************/ t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd); /**************************************************************************//** @Function FM_PCD_PlcrProfileDumpRegs - @Description Dumps all PCD Plcr registers + @Description Dumps all PCD Policer profile registers - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_Profile A handle to a profile. + @Param[in] h_Profile A handle to a Policer profile. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers + are mapped. *//***************************************************************************/ -t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_FmPcd, t_Handle h_Profile); +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile); /**************************************************************************//** @Function FM_PCD_PrsDumpRegs - @Description Dumps all PCD Prs registers + @Description Dumps all PCD Parser registers @Param[in] h_FmPcd A handle to an FM PCD Module. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers + are mapped. *//***************************************************************************/ t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd); @@ -713,6 +770,8 @@ t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). + NOTE: this routine may be called only for FM in master mode + (i.e. 'guestId'=NCSW_MASTER_ID). *//***************************************************************************/ t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd); #endif /* (defined(DEBUG_ERRORS) && ... */ @@ -720,9 +779,9 @@ t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd); /**************************************************************************//** - @Group FM_PCD_Runtime_tree_buildgrp FM PCD Tree building Unit + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit - @Description FM PCD Runtime Unit + @Description Frame Manager PCD Runtime Building API This group contains routines for setting, deleting and modifying PCD resources, for defining the total PCD tree. @@ -731,16 +790,19 @@ t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd); /**************************************************************************//** @Collection Definitions of coarse classification - parameters as required by keygen (when coarse classification + parameters as required by KeyGen (when coarse classification is the next engine after this scheme). *//***************************************************************************/ -#define FM_PCD_MAX_NUM_OF_CC_NODES 255 -#define FM_PCD_MAX_NUM_OF_CC_TREES 8 -#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16 -#define FM_PCD_MAX_NUM_OF_CC_UNITS 4 -#define FM_PCD_MAX_NUM_OF_KEYS 256 -#define FM_PCD_MAX_SIZE_OF_KEY 56 -#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4 +#define FM_PCD_MAX_NUM_OF_KEYS 256 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE) +#define FM_PCD_MAX_SIZE_OF_KEY 56 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16 +#define FM_PCD_LAST_KEY_INDEX 0xffff + +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */ /* @} */ /**************************************************************************//** @@ -753,11 +815,11 @@ typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. #define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */ #define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */ -typedef protocolOpt_t vlanProtocolOpt_t; /**< Vlan protocol options. */ -#define VLAN_STACKED 0x20000000 /**< Vlan Stacked. */ +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */ +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */ typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */ -#define MPLS_STACKED 0x10000000 /**< MPLS Stacked. */ +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */ typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */ #define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */ @@ -765,10 +827,70 @@ typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */ #define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */ #define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */ +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option. + IPV4 Reassembly manipulation requires network + environment with IPV4 header and IPV4_FRAG_1 option */ + typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */ #define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */ #define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */ #define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */ + +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option. + IPV6 Reassembly manipulation requires network + environment with IPV6 header and IPV6_FRAG_1 option; + in case where fragment found, the fragment-extension offset + may be found at 'shim2' (in parser-result). */ +#if (DPAA_VERSION >= 11) +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */ +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option. + CAPWAP Reassembly manipulation requires network + environment with CAPWAP header and CAPWAP_FRAG_1 option; + in case where fragment found, the fragment-extension offset + may be found at 'shim2' (in parser-result). */ +#endif /* (DPAA_VERSION >= 11) */ + + +/* @} */ + +#define FM_PCD_MANIP_MAX_HDR_SIZE 256 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64 + +/**************************************************************************//** + @Collection A set of definitions to support Header Manipulation selection. +*//***************************************************************************/ +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */ + +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */ + +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field + of t_FmPcdManipHdrFieldUpdateIpv4) */ +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field + of t_FmPcdManipHdrFieldUpdateIpv4) */ +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */ +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */ +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */ + +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */ + +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */ +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */ +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */ +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */ + +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */ + +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */ +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */ +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */ + /* @} */ /**************************************************************************//** @@ -784,16 +906,20 @@ typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; @Description All PCD engines *//***************************************************************************/ typedef enum e_FmPcdEngine { - e_FM_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/ + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */ e_FM_PCD_DONE, /**< No PCD Engine indicated */ - e_FM_PCD_KG, /**< Keygen indicated */ - e_FM_PCD_CC, /**< Coarse classification indicated */ - e_FM_PCD_PLCR, /**< Policer indicated */ - e_FM_PCD_PRS /**< Parser indicated */ + e_FM_PCD_KG, /**< KeyGen */ + e_FM_PCD_CC, /**< Coarse classifier */ + e_FM_PCD_PLCR, /**< Policer */ + e_FM_PCD_PRS, /**< Parser */ +#if (DPAA_VERSION >= 11) + e_FM_PCD_FR, /**< Frame-Replicator */ +#endif /* (DPAA_VERSION >= 11) */ + e_FM_PCD_HASH /**< Hash table */ } e_FmPcdEngine; /**************************************************************************//** - @Description An enum for selecting extraction by header types + @Description Enumeration type for selecting extraction by header types *//***************************************************************************/ typedef enum e_FmPcdExtractByHdrType { e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */ @@ -802,22 +928,22 @@ typedef enum e_FmPcdExtractByHdrType { } e_FmPcdExtractByHdrType; /**************************************************************************//** - @Description An enum for selecting extraction source + @Description Enumeration type for selecting extraction source (when it is not the header) *//***************************************************************************/ typedef enum e_FmPcdExtractFrom { e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */ e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */ - e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */ + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */ e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */ e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */ - e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */ + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */ e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */ e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */ } e_FmPcdExtractFrom; /**************************************************************************//** - @Description An enum for selecting extraction type + @Description Enumeration type for selecting extraction type *//***************************************************************************/ typedef enum e_FmPcdExtractType { e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */ @@ -826,7 +952,7 @@ typedef enum e_FmPcdExtractType { } e_FmPcdExtractType; /**************************************************************************//** - @Description An enum for selecting a default + @Description Enumeration type for selecting default extraction value *//***************************************************************************/ typedef enum e_FmPcdKgExtractDfltSelect { e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */ @@ -837,9 +963,8 @@ typedef enum e_FmPcdKgExtractDfltSelect { } e_FmPcdKgExtractDfltSelect; /**************************************************************************//** - @Description An enum defining all default groups - - each group shares a default value, one of 4 user - initialized values. + @Description Enumeration type defining all default groups - each group shares + a default value, one of four user-initialized values. *//***************************************************************************/ typedef enum e_FmPcdKgKnownFieldsDfltTypes { e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */ @@ -848,25 +973,26 @@ typedef enum e_FmPcdKgKnownFieldsDfltTypes { e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */ e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */ e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */ - e_FM_PCD_KG_IP_ADDR, /**< IP addr */ + e_FM_PCD_KG_IP_ADDR, /**< IP address */ e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */ e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */ e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */ e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */ e_FM_PCD_KG_L4_PORT, /**< L4 Port */ e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */ - e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by sw, + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW, any data extraction that is not the full field described above */ - e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by sw, + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW, any data extraction without validation */ - e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by sw, + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW, extraction from parser result or direct use of default value */ } e_FmPcdKgKnownFieldsDfltTypes; /**************************************************************************//** - @Description enum for defining header index when headers may repeat + @Description Enumeration type for defining header index for scenarios with + multiple (tunneled) headers *//***************************************************************************/ typedef enum e_FmPcdHdrIndex { e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also @@ -878,7 +1004,7 @@ typedef enum e_FmPcdHdrIndex { } e_FmPcdHdrIndex; /**************************************************************************//** - @Description A structure for selcting the policer profile functional type + @Description Enumeration type for selecting the policer profile functional type *//***************************************************************************/ typedef enum e_FmPcdProfileTypeSelection { e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */ @@ -886,16 +1012,16 @@ typedef enum e_FmPcdProfileTypeSelection { } e_FmPcdProfileTypeSelection; /**************************************************************************//** - @Description A structure for selcting the policer profile algorithem + @Description Enumeration type for selecting the policer profile algorithm *//***************************************************************************/ typedef enum e_FmPcdPlcrAlgorithmSelection { e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */ - e_FM_PCD_PLCR_RFC_2698, /**< Policer algorythm RFC 2698 */ - e_FM_PCD_PLCR_RFC_4115 /**< Policer algorythm RFC 4115 */ + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */ + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */ } e_FmPcdPlcrAlgorithmSelection; /**************************************************************************//** - @Description A structure for selcting the policer profile color mode + @Description Enumeration type for selecting a policer profile color mode *//***************************************************************************/ typedef enum e_FmPcdPlcrColorMode { e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */ @@ -903,17 +1029,17 @@ typedef enum e_FmPcdPlcrColorMode { } e_FmPcdPlcrColorMode; /**************************************************************************//** - @Description A structure for selcting the policer profile color functional mode + @Description Enumeration type for selecting a policer profile color *//***************************************************************************/ typedef enum e_FmPcdPlcrColor { - e_FM_PCD_PLCR_GREEN, /**< Green */ - e_FM_PCD_PLCR_YELLOW, /**< Yellow */ - e_FM_PCD_PLCR_RED, /**< Red */ - e_FM_PCD_PLCR_OVERRIDE /**< Color override */ + e_FM_PCD_PLCR_GREEN, /**< Green color code */ + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */ + e_FM_PCD_PLCR_RED, /**< Red color code */ + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */ } e_FmPcdPlcrColor; /**************************************************************************//** - @Description A structure for selcting the policer profile packet frame length selector + @Description Enumeration type for selecting the policer profile packet frame length selector *//***************************************************************************/ typedef enum e_FmPcdPlcrFrameLengthSelect { e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */ @@ -923,15 +1049,15 @@ typedef enum e_FmPcdPlcrFrameLengthSelect { } e_FmPcdPlcrFrameLengthSelect; /**************************************************************************//** - @Description An enum for selecting rollback frame + @Description Enumeration type for selecting roll-back frame *//***************************************************************************/ typedef enum e_FmPcdPlcrRollBackFrameSelect { - e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */ - e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */ + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */ + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */ } e_FmPcdPlcrRollBackFrameSelect; /**************************************************************************//** - @Description A structure for selcting the policer profile packet or byte mode + @Description Enumeration type for selecting the policer profile packet or byte mode *//***************************************************************************/ typedef enum e_FmPcdPlcrRateMode { e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */ @@ -939,15 +1065,17 @@ typedef enum e_FmPcdPlcrRateMode { } e_FmPcdPlcrRateMode; /**************************************************************************//** - @Description An enum for defining action of frame + @Description Enumeration type for defining action of frame *//***************************************************************************/ typedef enum e_FmPcdDoneAction { e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */ - e_FM_PCD_DROP_FRAME /**< Drop frame */ + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD' + flag will be set for this frame. */ } e_FmPcdDoneAction; /**************************************************************************//** - @Description A structure for selecting the policer counter + @Description Enumeration type for selecting the policer counter *//***************************************************************************/ typedef enum e_FmPcdPlcrProfileCounters { e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */ @@ -958,72 +1086,216 @@ typedef enum e_FmPcdPlcrProfileCounters { } e_FmPcdPlcrProfileCounters; /**************************************************************************//** - @Description A structure for selecting action + @Description Enumeration type for selecting the PCD action after extraction *//***************************************************************************/ typedef enum e_FmPcdAction { e_FM_PCD_ACTION_NONE, /**< NONE */ - e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/ - e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/ + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */ + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */ } e_FmPcdAction; -#if defined(FM_CAPWAP_SUPPORT) /**************************************************************************//** - @Description An enum for selecting type of insert manipulation + @Description Enumeration type for selecting type of insert manipulation *//***************************************************************************/ -typedef enum e_FmPcdManipInsrtType { - e_FM_PCD_MANIP_INSRT_NONE = 0, /**< No insertion */ - e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR, /**< Insert internal frame header to start of frame */ - e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE /**< Insert template to start of frame*/ -} e_FmPcdManipInsrtType; +typedef enum e_FmPcdManipHdrInsrtType { + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */ + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */ +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */ +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ +} e_FmPcdManipHdrInsrtType; /**************************************************************************//** - @Description An enum for selecting type of remove manipulation + @Description Enumeration type for selecting type of remove manipulation *//***************************************************************************/ -typedef enum e_FmPcdManipRmvParamsType { - e_FM_PCD_MANIP_RMV_NONE = 0, /**< No remove */ - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION, /**< Remove from start of frame till (excluding) specified indication */ - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION, /**< Remove from start of frame till (including) specified indication */ - e_FM_PCD_MANIP_RMV_INT_FRAME_HDR /**< Remove internal frame header to start of frame */ -} e_FmPcdManipRmvParamsType; +typedef enum e_FmPcdManipHdrRmvType { + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */ + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */ +} e_FmPcdManipHdrRmvType; /**************************************************************************//** - @Description An enum for selecting type of location + @Description Enumeration type for selecting specific L2 fields removal *//***************************************************************************/ -typedef enum e_FmPcdManipLocateType { - e_FM_PCD_MANIP_LOC_BY_HDR = 0, /**< Locate according to header */ - e_FM_PCD_MANIP_LOC_NON_HDR /**< Locate from data that is not the header */ -} e_FmPcdManipLocateType; +typedef enum e_FmPcdManipHdrRmvSpecificL2 { + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */ + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */ + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until + the header which follows the MPLS header */ + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */ + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */ +} e_FmPcdManipHdrRmvSpecificL2; /**************************************************************************//** - @Description An enum for selecting type of Timeout mode + @Description Enumeration type for selecting specific fields updates +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrFieldUpdateType { + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */ + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */ + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */ + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */ +} e_FmPcdManipHdrFieldUpdateType; + +/**************************************************************************//** + @Description Enumeration type for selecting VLAN updates +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrFieldUpdateVlan { + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */ + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */ +} e_FmPcdManipHdrFieldUpdateVlan; + +/**************************************************************************//** + @Description Enumeration type for selecting specific L2 header insertion +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrInsrtSpecificL2 { + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */ + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */ +} e_FmPcdManipHdrInsrtSpecificL2; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Enumeration type for selecting QoS mapping mode + + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE' + User should instruct the port to read the hash-result +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrQosMappingMode { + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */ + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */ +} e_FmPcdManipHdrQosMappingMode; + +/**************************************************************************//** + @Description Enumeration type for selecting QoS source + + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE' + User should left room for the hash-result on input/output buffer + and instruct the port to read/write the hash-result to the buffer (RPD should be set) +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrQosSrc { + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */ + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */ +} e_FmPcdManipHdrQosSrc; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Enumeration type for selecting type of header insertion +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrInsrtByHdrType { + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */ +#if (DPAA_VERSION >= 11) + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */ + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */ + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */ + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */ +#endif /* (DPAA_VERSION >= 11) */ +} e_FmPcdManipHdrInsrtByHdrType; + +/**************************************************************************//** + @Description Enumeration type for selecting specific customCommand +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrCustomType { + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */ + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */ +} e_FmPcdManipHdrCustomType; + +/**************************************************************************//** + @Description Enumeration type for selecting specific customCommand +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrCustomIpReplace { + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */ + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */ +} e_FmPcdManipHdrCustomIpReplace; + +/**************************************************************************//** + @Description Enumeration type for selecting type of header removal +*//***************************************************************************/ +typedef enum e_FmPcdManipHdrRmvByHdrType { + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */ +#if (DPAA_VERSION >= 11) + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */ +#endif /* (DPAA_VERSION >= 11) */ +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ +} e_FmPcdManipHdrRmvByHdrType; + +/**************************************************************************//** + @Description Enumeration type for selecting type of timeout mode *//***************************************************************************/ typedef enum e_FmPcdManipReassemTimeOutMode { - e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< limits the time of the reassm process from the first frag to the last */ - e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< limits the time of receiving the fragment */ + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process + from the first fragment to the last */ + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */ } e_FmPcdManipReassemTimeOutMode; /**************************************************************************//** - @Description An enum for selecting type of WaysNumber mode + @Description Enumeration type for selecting type of WaysNumber mode *//***************************************************************************/ typedef enum e_FmPcdManipReassemWaysNumber { - e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< -------------- */ - e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< -------------- */ - e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< -------------- */ - e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< four ways hash */ - e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< -------------- */ - e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< -------------- */ - e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< -------------- */ - e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< eight ways hash*/ + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */ + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */ + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */ + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */ + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */ + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */ + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */ + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */ } e_FmPcdManipReassemWaysNumber; +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) /**************************************************************************//** - @Description An enum for selecting type of statistics mode + @Description Enumeration type for selecting type of statistics mode *//***************************************************************************/ typedef enum e_FmPcdStatsType { - e_FM_PCD_STATS_PER_FLOWID = 0 /**< type where flowId used as index for getting statistics */ + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */ } e_FmPcdStatsType; +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -#endif /* FM_CAPWAP_SUPPORT */ +/**************************************************************************//** + @Description Enumeration type for selecting manipulation type +*//***************************************************************************/ +typedef enum e_FmPcdManipType { + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */ + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */ + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */ + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */ +} e_FmPcdManipType; + +/**************************************************************************//** + @Description Enumeration type for selecting type of statistics mode +*//***************************************************************************/ +typedef enum e_FmPcdCcStatsMode { + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */ + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */ + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */ +#if (DPAA_VERSION >= 11) + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics; + This mode is supported only on B4860 device */ +#endif /* (DPAA_VERSION >= 11) */ +} e_FmPcdCcStatsMode; + +/**************************************************************************//** + @Description Enumeration type for determining the action in case an IP packet + is larger than MTU but its DF (Don't Fragment) bit is set. +*//***************************************************************************/ +typedef enum e_FmPcdManipDontFragAction { + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */ + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET, + /**< Obsolete, cannot enqueue to error queue; + In practice, selects to discard packets; + Will be removed in the future */ + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */ + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */ +} e_FmPcdManipDontFragAction; + +/**************************************************************************//** + @Description Enumeration type for selecting type of special offload manipulation +*//***************************************************************************/ +typedef enum e_FmPcdManipSpecialOffloadType { + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */ +#if (DPAA_VERSION >= 11) + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */ +#endif /* (DPAA_VERSION >= 11) */ +} e_FmPcdManipSpecialOffloadType; /**************************************************************************//** @@ -1031,36 +1303,158 @@ typedef enum e_FmPcdStatsType { *//***************************************************************************/ typedef union u_FmPcdHdrProtocolOpt { ethProtocolOpt_t ethOpt; /**< Ethernet options */ - vlanProtocolOpt_t vlanOpt; /**< Vlan options */ + vlanProtocolOpt_t vlanOpt; /**< VLAN options */ mplsProtocolOpt_t mplsOpt; /**< MPLS options */ ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */ ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */ +#if (DPAA_VERSION >= 11) + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */ +#endif /* (DPAA_VERSION >= 11) */ } u_FmPcdHdrProtocolOpt; /**************************************************************************//** - @Description A union holding all known protocol fields + @Description A union holding protocol fields + + + Fields supported as "full fields": + HEADER_TYPE_ETH: + NET_HEADER_FIELD_ETH_DA + NET_HEADER_FIELD_ETH_SA + NET_HEADER_FIELD_ETH_TYPE + + HEADER_TYPE_LLC_SNAP: + NET_HEADER_FIELD_LLC_SNAP_TYPE + + HEADER_TYPE_VLAN: + NET_HEADER_FIELD_VLAN_TCI + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_LAST) + + HEADER_TYPE_MPLS: + NET_HEADER_FIELD_MPLS_LABEL_STACK + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_2, + e_FM_PCD_HDR_INDEX_LAST) + + HEADER_TYPE_IPv4: + NET_HEADER_FIELD_IPv4_SRC_IP + NET_HEADER_FIELD_IPv4_DST_IP + NET_HEADER_FIELD_IPv4_PROTO + NET_HEADER_FIELD_IPv4_TOS + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) + + HEADER_TYPE_IPv6: + NET_HEADER_FIELD_IPv6_SRC_IP + NET_HEADER_FIELD_IPv6_DST_IP + NET_HEADER_FIELD_IPv6_NEXT_HDR + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!) + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) + + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to + the last next header indication, meaning the next L4, which may be + present at the Ipv6 last extension. On earlier revisions this field + applies to the Next-Header field of the main IPv6 header) + + HEADER_TYPE_IP: + NET_HEADER_FIELD_IP_PROTO + (index may apply: + e_FM_PCD_HDR_INDEX_LAST) + NET_HEADER_FIELD_IP_DSCP + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1) + HEADER_TYPE_GRE: + NET_HEADER_FIELD_GRE_TYPE + + HEADER_TYPE_MINENCAP + NET_HEADER_FIELD_MINENCAP_SRC_IP + NET_HEADER_FIELD_MINENCAP_DST_IP + NET_HEADER_FIELD_MINENCAP_TYPE + + HEADER_TYPE_TCP: + NET_HEADER_FIELD_TCP_PORT_SRC + NET_HEADER_FIELD_TCP_PORT_DST + NET_HEADER_FIELD_TCP_FLAGS + + HEADER_TYPE_UDP: + NET_HEADER_FIELD_UDP_PORT_SRC + NET_HEADER_FIELD_UDP_PORT_DST + + HEADER_TYPE_UDP_LITE: + NET_HEADER_FIELD_UDP_LITE_PORT_SRC + NET_HEADER_FIELD_UDP_LITE_PORT_DST + + HEADER_TYPE_IPSEC_AH: + NET_HEADER_FIELD_IPSEC_AH_SPI + NET_HEADER_FIELD_IPSEC_AH_NH + + HEADER_TYPE_IPSEC_ESP: + NET_HEADER_FIELD_IPSEC_ESP_SPI + + HEADER_TYPE_SCTP: + NET_HEADER_FIELD_SCTP_PORT_SRC + NET_HEADER_FIELD_SCTP_PORT_DST + + HEADER_TYPE_DCCP: + NET_HEADER_FIELD_DCCP_PORT_SRC + NET_HEADER_FIELD_DCCP_PORT_DST + + HEADER_TYPE_PPPoE: + NET_HEADER_FIELD_PPPoE_PID + NET_HEADER_FIELD_PPPoE_SID + + ***************************************************************** + Fields supported as "from fields": + HEADER_TYPE_ETH (with or without validation): + NET_HEADER_FIELD_ETH_TYPE + + HEADER_TYPE_VLAN (with or without validation): + NET_HEADER_FIELD_VLAN_TCI + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_LAST) + + HEADER_TYPE_IPv4 (without validation): + NET_HEADER_FIELD_IPv4_PROTO + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) + + HEADER_TYPE_IPv6 (without validation): + NET_HEADER_FIELD_IPv6_NEXT_HDR + (index may apply: + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) + *//***************************************************************************/ typedef union t_FmPcdFields { - headerFieldEth_t eth; /**< eth */ - headerFieldVlan_t vlan; /**< vlan */ - headerFieldLlcSnap_t llcSnap; /**< llcSnap */ - headerFieldPppoe_t pppoe; /**< pppoe */ - headerFieldMpls_t mpls; /**< mpls */ - headerFieldIpv4_t ipv4; /**< ipv4 */ - headerFieldIpv6_t ipv6; /**< ipv6 */ - headerFieldUdp_t udp; /**< udp */ - headerFieldTcp_t tcp; /**< tcp */ - headerFieldSctp_t sctp; /**< sctp */ - headerFieldDccp_t dccp; /**< dccp */ - headerFieldGre_t gre; /**< gre */ - headerFieldMinencap_t minencap; /**< minencap */ - headerFieldIpsecAh_t ipsecAh; /**< ipsecAh */ - headerFieldIpsecEsp_t ipsecEsp; /**< ipsecEsp */ - headerFieldUdpEncapEsp_t udpEncapEsp; /**< udpEncapEsp */ + headerFieldEth_t eth; /**< Ethernet */ + headerFieldVlan_t vlan; /**< VLAN */ + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */ + headerFieldPppoe_t pppoe; /**< PPPoE */ + headerFieldMpls_t mpls; /**< MPLS */ + headerFieldIp_t ip; /**< IP */ + headerFieldIpv4_t ipv4; /**< IPv4 */ + headerFieldIpv6_t ipv6; /**< IPv6 */ + headerFieldUdp_t udp; /**< UDP */ + headerFieldUdpLite_t udpLite; /**< UDP Lite */ + headerFieldTcp_t tcp; /**< TCP */ + headerFieldSctp_t sctp; /**< SCTP */ + headerFieldDccp_t dccp; /**< DCCP */ + headerFieldGre_t gre; /**< GRE */ + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */ + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */ + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */ + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */ } t_FmPcdFields; /**************************************************************************//** - @Description structure for defining header extraction for key generation + @Description Parameters for defining header extraction for key generation *//***************************************************************************/ typedef struct t_FmPcdFromHdr { uint8_t size; /**< Size in byte */ @@ -1068,7 +1462,7 @@ typedef struct t_FmPcdFromHdr { } t_FmPcdFromHdr; /**************************************************************************//** - @Description structure for defining field extraction for key generation + @Description Parameters for defining field extraction for key generation *//***************************************************************************/ typedef struct t_FmPcdFromField { t_FmPcdFields field; /**< Field selection */ @@ -1077,24 +1471,25 @@ typedef struct t_FmPcdFromField { } t_FmPcdFromField; /**************************************************************************//** - @Description A structure of parameters used to define a single network - environment unit. - A unit should be defined if it will later be used by one or - more PCD engines to distinguich between flows. + @Description Parameters for defining a single network environment unit + + A distinction unit should be defined if it will later be used + by one or more PCD engines to distinguish between flows. *//***************************************************************************/ typedef struct t_FmPcdDistinctionUnit { struct { e_NetHeaderType hdr; /**< One of the headers supported by the FM */ - u_FmPcdHdrProtocolOpt opt; /**< only one option !! */ + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */ } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS]; } t_FmPcdDistinctionUnit; /**************************************************************************//** - @Description A structure of parameters used to define the different - units supported by a specific PCD Network Environment - Characteristics module. Each unit represent - a protocol or a group of protocols that may be used later - by the different PCD engined to distinguich between flows. + @Description Parameters for defining all different distinction units supported + by a specific PCD Network Environment Characteristics module. + + Each unit represent a protocol or a group of protocols that may + be used later by the different PCD engines to distinguish + between flows. *//***************************************************************************/ typedef struct t_FmPcdNetEnvParams { uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */ @@ -1103,8 +1498,8 @@ typedef struct t_FmPcdNetEnvParams { } t_FmPcdNetEnvParams; /**************************************************************************//** - @Description structure for defining a single extraction action - when creating a key + @Description Parameters for defining a single extraction action when + creating a key *//***************************************************************************/ typedef struct t_FmPcdExtractEntry { e_FmPcdExtractType type; /**< Extraction type select */ @@ -1114,19 +1509,22 @@ typedef struct t_FmPcdExtractEntry { bool ignoreProtocolValidation; /**< Ignore protocol validation */ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled - IP. Otherwise should be cleared.*/ + IP. Otherwise should be cleared. */ e_FmPcdExtractByHdrType type; /**< Header extraction type select */ union { t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */ - t_FmPcdFromField fromField; /**< Extract bytes from field parameters*/ - t_FmPcdFields fullField; /**< Extract full filed parameters*/ + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */ + t_FmPcdFields fullField; /**< Extract full filed parameters */ } extractByHdrType; } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */ struct { e_FmPcdExtractFrom src; /**< Non-header extraction source */ e_FmPcdAction action; /**< Relevant for CC Only */ - uint16_t icIndxMask; /**< Relevant only for CC where - action=e_FM_PCD_ACTION_INDEXED_LOOKUP */ + uint16_t icIndxMask; /**< Relevant only for CC when + action = e_FM_PCD_ACTION_INDEXED_LOOKUP; + Note that the number of bits that are set within + this mask must be log2 of the CC-node 'numOfKeys'. + Note that the mask cannot be set on the lower bits. */ uint8_t offset; /**< Byte offset */ uint8_t size; /**< Size in byte */ } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */ @@ -1134,27 +1532,24 @@ typedef struct t_FmPcdExtractEntry { } t_FmPcdExtractEntry; /**************************************************************************//** - @Description A structure for defining masks for each extracted - field in the key. + @Description Parameters for defining masks for each extracted field in the key. *//***************************************************************************/ typedef struct t_FmPcdKgExtractMask { - uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */ - uint8_t offset; /**< Byte offset */ - uint8_t mask; /**< A byte mask (selected bits will be used) */ + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */ + uint8_t offset; /**< Byte offset */ + uint8_t mask; /**< A byte mask (selected bits will be used) */ } t_FmPcdKgExtractMask; /**************************************************************************//** - @Description A structure for defining default selection per groups - of fields + @Description Parameters for defining default selection per groups of fields *//***************************************************************************/ typedef struct t_FmPcdKgExtractDflt { - e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select*/ + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */ e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */ } t_FmPcdKgExtractDflt; /**************************************************************************//** - @Description A structure for defining all parameters needed for - generation a key and using a hash function + @Description Parameters for defining key extraction and hashing *//***************************************************************************/ typedef struct t_FmPcdKgKeyExtractAndHashParams { uint32_t privateDflt0; /**< Scheme default register 0 */ @@ -1181,8 +1576,7 @@ typedef struct t_FmPcdKgKeyExtractAndHashParams { } t_FmPcdKgKeyExtractAndHashParams; /**************************************************************************//** - @Description A structure of parameters for defining a single - Fqid mask (extracted OR). + @Description Parameters for defining a single FQID mask (extracted OR). *//***************************************************************************/ typedef struct t_FmPcdKgExtractedOrParams { e_FmPcdExtractType type; /**< Extraction type select */ @@ -1193,7 +1587,7 @@ typedef struct t_FmPcdKgExtractedOrParams { IP. Otherwise should be cleared.*/ bool ignoreProtocolValidation; /**< continue extraction even if protocol is not recognized */ - } extractByHdr; + } extractByHdr; /**< Header to extract by */ e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */ }; uint8_t extractionOffset; /**< Offset for extraction (in bytes). */ @@ -1226,7 +1620,7 @@ typedef struct t_FmPcdKgExtractedOrParams { } t_FmPcdKgExtractedOrParams; /**************************************************************************//** - @Description A structure for configuring scheme counter + @Description Parameters for configuring a scheme counter *//***************************************************************************/ typedef struct t_FmPcdKgSchemeCounter { bool update; /**< FALSE to keep the current counter state @@ -1237,54 +1631,85 @@ typedef struct t_FmPcdKgSchemeCounter { } t_FmPcdKgSchemeCounter; /**************************************************************************//** - @Description A structure for defining policer profile - parameters as required by keygen (when policer - is the next engine after this scheme). + @Description Parameters for configuring a policer profile for a KeyGen scheme + (when policer is the next engine after this scheme). *//***************************************************************************/ typedef struct t_FmPcdKgPlcrProfile { bool sharedProfile; /**< TRUE if this profile is shared between ports - (i.e. managed by master partition) May not be TRUE + (managed by master partition); Must not be TRUE if profile is after Coarse Classification*/ bool direct; /**< if TRUE, directRelativeProfileId only selects the profile id, if FALSE fqidOffsetRelativeProfileIdBase is used together with fqidOffsetShift and numOfProfiles parameters, to define a range of profiles from - which the keygen result will determine the + which the KeyGen result will determine the destination policer profile. */ union { uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile. - This parameter should - indicate the policer profile offset within the port's - policer profiles or SHARED window. */ + should indicate the policer profile offset within the + port's policer profiles or shared window. */ struct { - uint8_t fqidOffsetShift; /**< shift of KG results without the qid base */ + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the + final FQID - without the FQID base). */ uint8_t fqidOffsetRelativeProfileIdBase; - /**< OR of KG results without the qid base - This parameter should indicate the policer profile - offset within the port's policer profiles window or - SHARED window depends on sharedProfile */ + /**< The base of the FMan Port's relative Storage-Profile ID; + this value will be "OR'ed" with the KeyGen create FQID + offset (i.e. not the final FQID - without the FQID base); + the final result should indicate the Storage-Profile offset + within the FMan Port's relative Storage-Profiles window/ + (or the SHARED window depends on 'sharedProfile'). */ uint8_t numOfProfiles; /**< Range of profiles starting at base */ - } indirectProfile; - } profileSelect; + } indirectProfile; /**< Indirect profile parameters */ + } profileSelect; /**< Direct/indirect profile selection and parameters */ } t_FmPcdKgPlcrProfile; +#if (DPAA_VERSION >= 11) /**************************************************************************//** - @Description A structure for CC parameters if CC is the next engine after KG + @Description Parameters for configuring a storage profile for a KeyGen scheme. +*//***************************************************************************/ +typedef struct t_FmPcdKgStorageProfile { + bool direct; /**< If TRUE, directRelativeProfileId only selects the + profile id; + If FALSE, fqidOffsetRelativeProfileIdBase is used + together with fqidOffsetShift and numOfProfiles + parameters to define a range of profiles from which + the KeyGen result will determine the destination + storage profile. */ + union { + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile; + should indicate the storage profile offset within the + port's storage profiles window. */ + struct { + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the + final FQID - without the FQID base). */ + uint8_t fqidOffsetRelativeProfileIdBase; + /**< The base of the FMan Port's relative Storage-Profile ID; + this value will be "OR'ed" with the KeyGen create FQID + offset (i.e. not the final FQID - without the FQID base); + the final result should indicate the Storage-Profile offset + within the FMan Port's relative Storage-Profiles window. */ + uint8_t numOfProfiles; /**< Range of profiles starting at base. */ + } indirectProfile; /**< Indirect profile parameters. */ + } profileSelect; /**< Direct/indirect profile selection and parameters. */ +} t_FmPcdKgStorageProfile; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Parameters for defining CC as the next engine after KeyGen *//***************************************************************************/ typedef struct t_FmPcdKgCc { - t_Handle h_CcTree; /**< A handle to a CC Tree */ - uint8_t grpId; /**< CC group id within the CC tree */ - bool plcrNext; /**< TRUE if after CC, in case of data frame, - policing is required. */ - bool bypassPlcrProfileGeneration; - /**< TRUE to bypass keygen policer profile - generation (profile selected is the one selected at - port initialization). */ - t_FmPcdKgPlcrProfile plcrProfile; /**< only if plcrNext=TRUE and bypassPlcrProfileGeneration=FALSE */ + t_Handle h_CcTree; /**< A handle to a CC Tree */ + uint8_t grpId; /**< CC group id within the CC tree */ + bool plcrNext; /**< TRUE if after CC, in case of data frame, + policing is required. */ + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation; + selected profile is the one set at port initialization. */ + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and + bypassPlcrProfileGeneration = FALSE */ } t_FmPcdKgCc; /**************************************************************************//** - @Description A structure for initializing a keygen single scheme + @Description Parameters for defining initializing a KeyGen scheme *//***************************************************************************/ typedef struct t_FmPcdKgSchemeParams { bool modify; /**< TRUE to change an existing scheme */ @@ -1292,35 +1717,41 @@ typedef struct t_FmPcdKgSchemeParams { { uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */ t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */ - }id; - bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need for match vector. Keygen will ignore - it when matching */ + } id; + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need + for match vector; KeyGen will ignore it when matching */ struct { /**< HL Relevant only if alwaysDirect = FALSE */ t_Handle h_NetEnv; /**< A handle to the Network environment as returned - by FM_PCD_SetNetEnvCharacteristics() */ - uint8_t numOfDistinctionUnits; /**< Number of netenv units listed in unitIds array */ + by FM_PCD_NetEnvCharacteristicsSet() */ + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */ uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< Indexes as passed to SetNetEnvCharacteristics array*/ } netEnvParams; - bool useHash; /**< use the KG Hash functionality */ + bool useHash; /**< use the KeyGen Hash functionality */ t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams; /**< used only if useHash = TRUE */ bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC; - In such a case FQID after KG will be the default FQID + In such a case FQID after KeyGen will be the default FQID defined for the relevant port, or the FQID defined by CC in cases where CC was the previous engine. */ uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE; If hash is used and an even distribution is expected according to hashDistributionNumOfFqids, baseFqid must be aligned to - hashDistributionNumOfFqids. */ - uint8_t numOfUsedExtractedOrs; /**< Number of Fqid masks listed in extractedOrs array*/ + hashDistributionNumOfFqids. */ + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */ t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS]; - /**< IN: FM_PCD_KG_NUM_OF_GENERIC_REGS + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS registers are shared between qidMasks functionality and some of the extraction actions; Normally only some will be used for qidMask. Driver will return error if resource is full at initialization time. */ + +#if (DPAA_VERSION >= 11) + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */ + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */ +#endif /* (DPAA_VERSION >= 11) */ + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */ union { /**< depends on nextEngine */ e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */ @@ -1332,23 +1763,40 @@ typedef struct t_FmPcdKgSchemeParams { } t_FmPcdKgSchemeParams; /**************************************************************************//** - @Description A structure for defining CC params when CC is the - next engine after a CC node. + @Collection Definitions for CC statistics +*//***************************************************************************/ +#if (DPAA_VERSION >= 11) +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */ +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */ +#endif /* (DPAA_VERSION >= 11) */ +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */ +/* @} */ + +/**************************************************************************//** + @Description Parameters for defining CC as the next engine after a CC node. *//***************************************************************************/ typedef struct t_FmPcdCcNextCcParams { t_Handle h_CcNode; /**< A handle of the next CC node */ } t_FmPcdCcNextCcParams; +#if (DPAA_VERSION >= 11) /**************************************************************************//** - @Description A structure for defining PLCR params when PLCR is the - next engine after a CC node. + @Description Parameters for defining Frame replicator as the next engine after a CC node. +*//***************************************************************************/ +typedef struct t_FmPcdCcNextFrParams { + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */ +} t_FmPcdCcNextFrParams; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Parameters for defining Policer as the next engine after a CC node. *//***************************************************************************/ typedef struct t_FmPcdCcNextPlcrParams { bool overrideParams; /**< TRUE if CC override previously decided parameters*/ bool sharedProfile; /**< Relevant only if overrideParams=TRUE: TRUE if this profile is shared between ports */ uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE: - (otherwise profile id is taken from keygen); + (otherwise profile id is taken from KeyGen); This parameter should indicate the policer profile offset within the port's policer profiles or from SHARED window.*/ @@ -1357,107 +1805,200 @@ typedef struct t_FmPcdCcNextPlcrParams { In earlier chips if policer next engine is KEYGEN, this parameter can be 0, because the KEYGEN always decides the enqueue FQID.*/ - bool statisticsEn; /**< In the case of TRUE Statistic counter is - incremented for each received frame passed through - this Coarse Classification entry.*/ +#if (DPAA_VERSION >= 11) + uint8_t newRelativeStorageProfileId; + /**< Indicates the relative storage profile offset within + the port's storage profiles window; + Relevant only if the port was configured with VSP. */ +#endif /* (DPAA_VERSION >= 11) */ } t_FmPcdCcNextPlcrParams; /**************************************************************************//** - @Description A structure for defining enqueue params when BMI is the - next engine after a CC node. + @Description Parameters for defining enqueue as the next action after a CC node. *//***************************************************************************/ typedef struct t_FmPcdCcNextEnqueueParams { - e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */ - bool overrideFqid; /**< TRUE if CC override previously decided Fqid(by Keygen), + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid, relevant if action = e_FM_PCD_ENQ_FRAME */ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame - (otherwise FQID is taken from keygen), - relevant if action = e_FM_PCD_ENQ_FRAME*/ - bool statisticsEn; /**< In the case of TRUE Statistic counter is - incremented for each received frame passed through - this Coarse Classification entry.*/ + (otherwise FQID is taken from KeyGen), + relevant if action = e_FM_PCD_ENQ_FRAME */ +#if (DPAA_VERSION >= 11) + uint8_t newRelativeStorageProfileId; + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual + storage profile offset within the port's storage profiles + window; Relevant only if the port was configured with VSP. */ +#endif /* (DPAA_VERSION >= 11) */ } t_FmPcdCcNextEnqueueParams; /**************************************************************************//** - @Description A structure for defining KG params when KG is the - next engine after a CC node. + @Description Parameters for defining KeyGen as the next engine after a CC node. *//***************************************************************************/ typedef struct t_FmPcdCcNextKgParams { - bool overrideFqid; /**< TRUE if CC override previously decided Fqid (by keygen), - Note - this parameters irrelevant for earlier chips*/ + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid, + Note - this parameters irrelevant for earlier chips */ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame - (otherwise FQID is taken from keygen), - Note - this parameters irrelevant for earlier chips*/ + (otherwise FQID is taken from KeyGen), + Note - this parameters irrelevant for earlier chips */ +#if (DPAA_VERSION >= 11) + uint8_t newRelativeStorageProfileId; + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual + storage profile offset within the port's storage profiles + window; Relevant only if the port was configured with VSP. */ +#endif /* (DPAA_VERSION >= 11) */ + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */ - bool statisticsEn; /**< In the case of TRUE Statistic counter is - incremented for each received frame passed through - this Coarse Classification entry.*/ } t_FmPcdCcNextKgParams; /**************************************************************************//** - @Description A structure for defining next engine params after a CC node. + @Description Parameters for defining the next engine after a CC node. *//***************************************************************************/ typedef struct t_FmPcdCcNextEngineParams { - e_FmPcdEngine nextEngine; /**< User has to initialize parameters - according to nextEngine definition */ + e_FmPcdEngine nextEngine; /**< User has to initialize parameters + according to nextEngine definition */ union { - t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */ - t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */ - t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */ - t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */ - } params; -#if defined(FM_CAPWAP_SUPPORT) - t_Handle h_Manip; /**< Handler to headerManip. - Relevant if next engine of the type result - (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */ -#endif /* defined(FM_CAPWAP_SUPPORT) || ... */ + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */ + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */ + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */ + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */ +#if (DPAA_VERSION >= 11) + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */ +#endif /* (DPAA_VERSION >= 11) */ + } params; /**< union used for all the next-engine parameters options */ + + t_Handle h_Manip; /**< Handle to Manipulation object. + Relevant if next engine is of type result + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */ + + bool statisticsEn; /**< If TRUE, statistics counters are incremented + for each frame passing through this + Coarse Classification entry. */ } t_FmPcdCcNextEngineParams; /**************************************************************************//** - @Description A structure for defining a single CC Key parameters + @Description Parameters for defining a single CC key *//***************************************************************************/ typedef struct t_FmPcdCcKeyParams { - uint8_t *p_Key; /**< pointer to the key of the size defined in keySize*/ - uint8_t *p_Mask; /**< pointer to the Mask per key of the size defined + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH; + pointer to the key of the size defined in keySize */ + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH; + pointer to the Mask per key of the size defined in keySize. p_Key and p_Mask (if defined) has to be - of the same size defined in the keySize */ + of the same size defined in the keySize; + NOTE that if this value is equal for all entries whithin + this table, the driver will automatically use global-mask + (i.e. one common mask for all entries) instead of private + one; that is done in order to spare some memory and for + better performance. */ t_FmPcdCcNextEngineParams ccNextEngineParams; /**< parameters for the next for the defined Key in the p_Key */ } t_FmPcdCcKeyParams; /**************************************************************************//** - @Description A structure for defining CC Keys parameters + @Description Parameters for defining CC keys parameters + The driver supports two methods for CC node allocation: dynamic and static. + Static mode was created in order to prevent runtime alloc/free + of FMan memory (MURAM), which may cause fragmentation; in this mode, + the driver automatically allocates the memory according to + 'maxNumOfKeys' parameter. The driver calculates the maximal memory + size that may be used for this CC-Node taking into consideration + 'maskSupport' and 'statisticsMode' parameters. + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'. + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization, + all required structures are allocated according to 'numOfKeys' + parameter. During runtime modification, these structures are + re-allocated according to the updated number of keys. + + Please note that 'action' and 'icIndxMask' mentioned in the + specific parameter explanations are passed in the extraction + parameters of the node (fields of extractCcParams.extractNonHdr). *//***************************************************************************/ typedef struct t_KeysParams { - uint8_t numOfKeys; /**< Number Of relevant Keys */ - uint8_t keySize; /**< size of the key - in the case of the extraction of - the type FULL_FIELD keySize has to be as standard size of the relevant - key. In the another type of extraction keySize has to be as size of extraction. - In the case of action = e_FM_PCD_ACTION_INDEXED_LOOKUP the size of keySize has to be 2*/ + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node; + A value of zero may be used for dynamic memory allocation. */ + bool maskSupport; /**< This parameter is relevant only if a node is initialized with + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0; + Should be TRUE to reserve table memory for key masks, even if + initial keys do not contain masks, or if the node was initialized + as 'empty' (without keys); this will allow user to add keys with + masks at runtime. + NOTE that if user want to use only global-masks (i.e. one common mask + for all the entries within this table, this parameter should set to 'FALSE'. */ + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys. + To enable statistics gathering, statistics should be enabled per + every key, using 'statisticsEn' in next engine parameters structure + of that key; + If 'maxNumOfKeys' is set, all required structures will be + preallocated for all keys. */ +#if (DPAA_VERSION >= 11) + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; + /**< Relevant only for 'RMON' statistics mode + (this feature is supported only on B4860 device); + Holds a list of programmable thresholds - for each received frame, + its length in bytes is examined against these range thresholds and + the appropriate counter is incremented by 1 - for example, to belong + to range i, the following should hold: + range i-1 threshold < frame length <= range i threshold + Each range threshold must be larger then its preceding range + threshold, and last range threshold must be 0xFFFF. */ +#endif /* (DPAA_VERSION >= 11) */ + uint16_t numOfKeys; /**< Number of initial keys; + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP, + this field should be power-of-2 of the number of bits that are + set in 'icIndxMask'. */ + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has + to be the standard size of the selected key; For other extraction + types, 'keySize' has to be as size of extraction; When 'action' = + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */ t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS]; - /**< it's array with numOfKeys entries each entry in - the array of the type t_FmPcdCcKeyParams */ + /**< An array with 'numOfKeys' entries, each entry specifies the + corresponding key parameters; + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved + for the 'miss' entry. */ t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; - /**< parameters for the next step of - unfound (or undefined) key . Not relevant in the case - of action = e_FM_PCD_ACTION_INDEXED_LOOKUP*/ + /**< Parameters for defining the next engine when a key is not matched; + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */ } t_KeysParams; + /**************************************************************************//** - @Description A structure for defining the CC node params + @Description Parameters for defining a CC node *//***************************************************************************/ typedef struct t_FmPcdCcNodeParams { - t_FmPcdExtractEntry extractCcParams; /**< params which defines extraction parameters */ - t_KeysParams keysParams; /**< params which defines Keys parameters of the - extraction defined in extractCcParams */ + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */ + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */ } t_FmPcdCcNodeParams; /**************************************************************************//** - @Description A structure for defining each CC tree group in term of - NetEnv units and the action to be taken in each case. - the unitIds list must be in order from lower to higher indexes. + @Description Parameters for defining a hash table +*//***************************************************************************/ +typedef struct t_FmPcdHashTableParams { + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the + requested statistics mode will be allocated according to maxNumOfKeys. */ + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme + that leads to this hash-table. */ + uint16_t hashResMask; /**< Mask that will be used on the hash-result; + The number-of-sets for this hash will be calculated + as (2^(number of bits set in 'hashResMask')); + The 4 lower bits must be cleared. */ + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the + 2-bytes to be used as hash index. */ + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */ + + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */ + +} t_FmPcdHashTableParams; + +/**************************************************************************//** + @Description Parameters for defining a CC tree group. + + This structure defines a CC group in terms of NetEnv units + and the action to be taken in each case. The unitIds list must + be given in order from low to high indices. t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits structures where each defines the next action to be taken for @@ -1474,26 +2015,46 @@ typedef struct t_FmPcdCcNodeParams { unit 1 - found; unit 3 - found; *//***************************************************************************/ typedef struct t_FmPcdCcGrpParams { - uint8_t numOfDistinctionUnits; /**< up to 4 */ + uint8_t numOfDistinctionUnits; /**< Up to 4 */ uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS]; - /**< Indexes of the units as defined in - FM_PCD_SetNetEnvCharacteristics() */ + /**< Indices of the units as defined in + FM_PCD_NetEnvCharacteristicsSet() */ t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP]; - /**< Max size is 16 - if only one group used */ + /**< Maximum entries per group is 16 */ } t_FmPcdCcGrpParams; /**************************************************************************//** - @Description A structure for defining the CC tree groups + @Description Parameters for defining CC tree groups *//***************************************************************************/ typedef struct t_FmPcdCcTreeParams { - t_Handle h_NetEnv; /**< A handle to the Network environment as returned - by FM_PCD_SetNetEnvCharacteristics() */ - uint8_t numOfGrps; /**< Number of CC groups within the CC tree */ - t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; /**< Parameters for each group. */ + t_Handle h_NetEnv; /**< A handle to the Network environment as returned + by FM_PCD_NetEnvCharacteristicsSet() */ + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */ + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; + /**< Parameters for each group. */ } t_FmPcdCcTreeParams; + /**************************************************************************//** - @Description A structure for defining parameters for byte rate + @Description CC key statistics structure +*//***************************************************************************/ +typedef struct t_FmPcdCcKeyStatistics { + uint32_t byteCount; /**< This counter reflects byte count of frames that + were matched by this key. */ + uint32_t frameCount; /**< This counter reflects count of frames that + were matched by this key. */ +#if (DPAA_VERSION >= 11) + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; + /**< These counters reflect how many frames matched + this key in 'RMON' statistics mode: + Each counter holds the number of frames of a + specific frames length range, according to the + ranges provided at initialization. */ +#endif /* (DPAA_VERSION >= 11) */ +} t_FmPcdCcKeyStatistics; + +/**************************************************************************//** + @Description Parameters for defining policer byte rate *//***************************************************************************/ typedef struct t_FmPcdPlcrByteRateModeParams { e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */ @@ -1502,30 +2063,30 @@ typedef struct t_FmPcdPlcrByteRateModeParams { } t_FmPcdPlcrByteRateModeParams; /**************************************************************************//** - @Description A structure for selcting the policer profile RFC-2698 or - RFC-4115 parameters + @Description Parameters for defining the policer profile (based on + RFC-2698 or RFC-4115 attributes). *//***************************************************************************/ typedef struct t_FmPcdPlcrNonPassthroughAlgParams { - e_FmPcdPlcrRateMode rateMode; /**< Byte / Packet */ + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */ t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */ - uint32_t comittedInfoRate; /**< KBits/Sec or Packets/Sec */ - uint32_t comittedBurstSize; /**< Bytes/Packets */ - uint32_t peakOrAccessiveInfoRate; /**< KBits/Sec or Packets/Sec */ - uint32_t peakOrAccessiveBurstSize; /**< Bytes/Packets */ + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */ + uint32_t committedBurstSize; /**< Bytes/Packets */ + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */ + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */ } t_FmPcdPlcrNonPassthroughAlgParams; /**************************************************************************//** - @Description A union for defining Policer next engine parameters + @Description Parameters for defining the next engine after policer *//***************************************************************************/ typedef union u_FmPcdPlcrNextEngineParams { - e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */ - t_Handle h_Profile; /**< Policer profile handle - used when next engine - is PLCR, must be a SHARED profile */ - t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is Keygen */ + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */ + t_Handle h_Profile; /**< Policer profile handle - used when next engine + is Policer, must be a SHARED profile */ + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */ } u_FmPcdPlcrNextEngineParams; /**************************************************************************//** - @Description A structure for selecting the policer profile entry parameters + @Description Parameters for defining the policer profile entry *//***************************************************************************/ typedef struct t_FmPcdPlcrProfileParams { bool modify; /**< TRUE to change an existing profile */ @@ -1534,87 +2095,80 @@ typedef struct t_FmPcdPlcrProfileParams { e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */ t_Handle h_FmPort; /**< Relevant for per-port profiles only */ uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */ - } newParams; /**< use it when modify=FALSE */ + } newParams; /**< use it when modify = FALSE */ t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */ } id; e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */ e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */ union { - e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode. the policer will re-color + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color any incoming packet with the default value. */ - e_FmPcdPlcrColor override; /**< For Color-Aware modes. The profile response to a + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a pre-color value of 2'b11. */ } color; - t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 params */ + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */ - e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */ - u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */ + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */ + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */ - e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */ - u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */ + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */ + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */ - e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */ - u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */ + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */ + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */ - bool trapProfileOnFlowA; /**< Trap on flow A */ - bool trapProfileOnFlowB; /**< Trap on flow B */ - bool trapProfileOnFlowC; /**< Trap on flow C */ + bool trapProfileOnFlowA; /**< Obsolete - do not use */ + bool trapProfileOnFlowB; /**< Obsolete - do not use */ + bool trapProfileOnFlowC; /**< Obsolete - do not use */ } t_FmPcdPlcrProfileParams; -#if defined(FM_CAPWAP_SUPPORT) /**************************************************************************//** - @Description A structure for selecting the location of manipulation + @Description Parameters for selecting a location for requested manipulation *//***************************************************************************/ -typedef struct t_FmPcdManipLocationParams { - e_FmPcdManipLocateType type; /**< location of manipulation type select */ - struct { /**< used when type = e_FM_PCD_MANIP_BY_HDR */ - e_NetHeaderType hdr; /**< Header selection */ - e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled - IP. Otherwise should be cleared. */ - bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/ - t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */ - } manipByHdr; -} t_FmPcdManipLocationParams; +typedef struct t_FmManipHdrInfo { + e_NetHeaderType hdr; /**< Header selection */ + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */ + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/ + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */ +} t_FmManipHdrInfo; +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) /**************************************************************************//** - @Description structure for defining insert manipulation - of the type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE + @Description Parameters for defining an insertion manipulation + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE *//***************************************************************************/ -typedef struct t_FmPcdManipInsrtByTemplateParams { - uint8_t size; /**< size of insert template to the start of the frame. */ +typedef struct t_FmPcdManipHdrInsrtByTemplateParams { + uint8_t size; /**< Size of insert template to the start of the frame. */ uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE]; - /**< array of the insertion template. */ + /**< Array of the insertion template. */ bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */ struct { - uint16_t ipOuterOffset; /**< offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/ + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/ uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE. in IPV4 dscpEcn only byte - it has to be adjusted to the right*/ bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/ - uint8_t udpOffset; /**< offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/ + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/ uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/ bool recalculateLength; /**< TRUE if recalculate length has to be performed due to the engines in the path which can change the frame later, relevant if modifyOuterIp = TRUE.*/ struct { - uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP-total-len field.*/ - uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP-total-len field and UDP length*/ - uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP-total-len field and UDP length.*/ - } recalculateLengthParams; /**< recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */ + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/ + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/ + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/ + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */ } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */ - bool modifyOuterVlan; /**< TRUE if user wants to modify vpri field in the outer VLAN header*/ + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/ struct { - uint8_t vpri; /**< value of vpri, relevant if modifyOuterVlan = TRUE - vpri only 3 bits, it has to be adjusted to the right*/ + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE + VPri only 3 bits, it has to be adjusted to the right*/ } modifyOuterVlanParams; -} t_FmPcdManipInsrtByTemplateParams; -#endif /* defined(FM_CAPWAP_SUPPORT) || ... */ +} t_FmPcdManipHdrInsrtByTemplateParams; - -#ifdef FM_CAPWAP_SUPPORT /**************************************************************************//** - @Description structure for defining CAPWAP fragmentation + @Description Parameters for defining CAPWAP fragmentation *//***************************************************************************/ typedef struct t_CapwapFragmentationParams { uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/ @@ -1624,120 +2178,758 @@ typedef struct t_CapwapFragmentationParams { } t_CapwapFragmentationParams; /**************************************************************************//** - @Description structure for defining CAPWAP Re-assembly + @Description Parameters for defining CAPWAP reassembly *//***************************************************************************/ typedef struct t_CapwapReassemblyParams { - uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time. - It has to be power of 2. - In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2. + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, maxNumFramesInProcess has to be in the range of 4 - 512, - In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, maxNumFramesInProcess has to be in the range of 8 - 2048 */ - bool haltOnDuplicationFrag; /**< In the case of TRUE, Reassembly process halted due to duplicated fragment, - and all processed fragments passed for enqueue with error indication. - In the case of FALSE, only duplicated fragment passed for enqueue with error indication */ + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment, + and all processed fragments will be enqueued with error indication; + If FALSE, only duplicated fragments will be enqueued with error indication. */ - e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */ - uint32_t fqidForTimeOutFrames; /**< Fqid in which time out frames will enqueue during Time Out Process */ + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */ + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */ uint32_t timeoutRoutineRequestTime; /**< Represents the time interval in microseconds between consecutive timeout routine requests It has to be power of 2. */ uint32_t timeoutThresholdForReassmProcess; - /**< Represents the time interval in microseconds which defines - if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ + /**< Time interval (microseconds) for marking frames in process as too old; + Frames in process are those for which at least one fragment was received + but not all fragments. */ - e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry needed for reassembly process */ + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */ } t_CapwapReassemblyParams; -#endif /* FM_CAPWAP_SUPPORT */ - -#if defined(FM_CAPWAP_SUPPORT) /**************************************************************************//** - @Description structure for defining fragmentation/reassembly + @Description Parameters for defining fragmentation/reassembly manipulation *//***************************************************************************/ typedef struct t_FmPcdManipFragOrReasmParams { bool frag; /**< TRUE if using the structure for fragmentation, otherwise this structure is used for reassembly */ - uint8_t extBufPoolIndx; /**< Index of the buffer pool ID which was configured for port - and can be used for manipulation; - NOTE: This field is relevant only for CAPWAP fragmentation - and reassembly */ + uint8_t sgBpid; /**< Scatter/Gather buffer pool id; + Same LIODN number is used for these buffers as for + the received frames buffers, so buffers of this pool + need to be allocated in the same memory area as the + received buffers. If the received buffers arrive + from different sources, the Scatter/Gather BP id + should be mutual to all these sources. */ e_NetHeaderType hdr; /**< Header selection */ union { -#ifdef FM_CAPWAP_SUPPORT - t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation, relevant if frag = TRUE, hdr = HEADER_TYPE_CAPWAP */ - t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly, relevant if frag = FALSE, hdr = HEADER_TYPE_CAPWAP */ -#endif /* FM_CAPWAP_SUPPORT */ - }; + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation, + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */ + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly, + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */ + } u; } t_FmPcdManipFragOrReasmParams; +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + /**************************************************************************//** - @Description structure for defining insert manipulation + @Description Parameters for defining header removal by header type *//***************************************************************************/ -typedef struct t_FmPcdManipInsrtParams { - e_FmPcdManipInsrtType type; /**< Type of insert manipulation */ +typedef struct t_FmPcdManipHdrRmvByHdrParams { + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */ union { - t_FmPcdManipInsrtByTemplateParams insrtByTemplateParams; - /**< parameters for insert manipulation, relevant if - type = e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE */ - }; -} t_FmPcdManipInsrtParams; +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + struct { + bool include; /**< If FALSE, remove until the specified header (not including the header); + If TRUE, remove also the specified header. */ + t_FmManipHdrInfo hdrInfo; + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ +#endif /* (DPAA_VERSION >= 11) || ... */ +#if (DPAA_VERSION >= 11) + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ +#endif /* (DPAA_VERSION >= 11) */ + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2; + Defines which L2 headers to remove. */ + } u; +} t_FmPcdManipHdrRmvByHdrParams; /**************************************************************************//** - @Description structure for defining remove manipulation + @Description Parameters for configuring IP fragmentation manipulation + + Restrictions: + - IP Fragmentation output fragments must not be forwarded to application directly. + - Maximum number of fragments per frame is 16. + - Fragmentation of IP fragments is not supported. + - IPv4 packets containing header Option fields are fragmented by copying all option + fields to each fragment, regardless of the copy bit value. + - Transmit confirmation is not supported. + - Fragmentation after SEC can't handle S/G frames. + - Fragmentation nodes must be set as the last PCD action (i.e. the + corresponding CC node key must have next engine set to e_FM_PCD_DONE). + - Only BMan buffers shall be used for frames to be fragmented. + - IPF does not support VSP. Therefore, on the same port where we have IPF + we cannot support VSP. + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF + does not support VSP. Therefore, on the same port where we have IPF we + cannot support VSP. *//***************************************************************************/ -typedef struct t_FmPcdManipRmvParams { - e_FmPcdManipRmvParamsType type; /**< Type of remove manipulation */ - t_FmPcdManipLocationParams rmvSpecificLocationParams; - /**< Specified location of remove manipulation; - This params should be initialized in cases: - - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION - - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION */ -} t_FmPcdManipRmvParams; +typedef struct t_FmPcdManipFragIpParams { + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value, + IP fragmentation will be executed.*/ +#if (DPAA_VERSION == 10) + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/ +#endif /* (DPAA_VERSION == 10) */ + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the + received frame's buffer. */ + uint8_t sgBpid; /**< Scatter/Gather buffer pool id; + This parameters is relevant when 'sgBpidEn=TRUE'; + Same LIODN number is used for these buffers as for the received frames buffers, so buffers + of this pool need to be allocated in the same memory area as the received buffers. + If the received buffers arrive from different sources, the Scatter/Gather BP id should be + mutual to all these sources. */ + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger + than MTU and its DF bit is set, then this field will + determine the action to be taken.*/ +} t_FmPcdManipFragIpParams; /**************************************************************************//** - @Description structure for defining manipulation + @Description Parameters for configuring IP reassembly manipulation. + + This is a common structure for both IPv4 and IPv6 reassembly + manipulation. For reassembly of both IPv4 and IPv6, make sure to + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6. + + Restrictions: + - Application must define at least one scheme to catch the reassembled frames. + - Maximum number of fragments per frame is 16. + - Reassembly of IPv4 fragments containing Option fields is supported. + +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemIpParams { + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id: + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation; + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation; + NOTE: The following comment is relevant only for FMAN v2 devices: + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than + the user schemes id to ensure that the reassembly schemes will be first match; + Rest schemes, if defined, should have higher relative scheme ID. */ +#if (DPAA_VERSION >= 11) + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage + profile than the opening fragment (Non-Consistent-SP state) + then one of two possible scenarios occurs: + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/ +#else + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */ +#endif /* (DPAA_VERSION >= 11) */ + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */ + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */ + uint16_t minFragSize[2]; /**< Minimum fragment size: + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */ + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2]; + /**< Number of frames per hash entry needed for reassembly process: + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH); + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */ + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time; + Must be power of 2; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 4 - 512; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 8 - 2048. */ + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */ + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process; + Recommended value for this field is 0; in this way timed-out frames will be discarded */ + uint32_t timeoutThresholdForReassmProcess; + /**< Represents the time interval in microseconds which defines + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ +} t_FmPcdManipReassemIpParams; + +/**************************************************************************//** + @Description structure for defining IPSEC manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipSpecialOffloadIPSecParams { + bool decryption; /**< TRUE if being used in decryption direction; + FALSE if being used in encryption direction. */ + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner + (direction depends on the 'decryption' field). */ + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner + (direction depends on the 'decryption' field). */ + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */ + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */ + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value; + It is specifies the length of the outer IP header that was configured in the + corresponding SA. */ + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA; + The value must be a multiplication of 16 */ + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value; + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to; + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */ +} t_FmPcdManipSpecialOffloadIPSecParams; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Parameters for configuring CAPWAP fragmentation manipulation + + Restrictions: + - Maximum number of fragments per frame is 16. + - Transmit confirmation is not supported. + - Fragmentation nodes must be set as the last PCD action (i.e. the + corresponding CC node key must have next engine set to e_FM_PCD_DONE). + - Only BMan buffers shall be used for frames to be fragmented. + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF + does not support VSP. Therefore, on the same port where we have IPF we + cannot support VSP. +*//***************************************************************************/ +typedef struct t_FmPcdManipFragCapwapParams { + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value, + CAPWAP fragmentation will be executed.*/ + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the + received frame's buffer. */ + uint8_t sgBpid; /**< Scatter/Gather buffer pool id; + This parameters is relevant when 'sgBpidEn=TRUE'; + Same LIODN number is used for these buffers as for the received frames buffers, so buffers + of this pool need to be allocated in the same memory area as the received buffers. + If the received buffers arrive from different sources, the Scatter/Gather BP id should be + mutual to all these sources. */ + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode; + When this mode is enabled then only the first fragment include the CAPWAP header options + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP + options field (CAPWAP header is updated accordingly).*/ +} t_FmPcdManipFragCapwapParams; + +/**************************************************************************//** + @Description Parameters for configuring CAPWAP reassembly manipulation. + + Restrictions: + - Application must define one scheme to catch the reassembled frames. + - Maximum number of fragments per frame is 16. + +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemCapwapParams { + uint8_t relativeSchemeId; /**< Partition relative scheme id; + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match; + Rest schemes, if defined, should have higher relative scheme ID. */ + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */ + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */ + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes; + If maxReassembledFrameLength == 0, any successful reassembled frame length is + considered as a valid length; + if maxReassembledFrameLength > 0, a successful reassembled frame which its length + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */ + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry; + /**< Number of frames per hash entry needed for reassembly process */ + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time; + Must be power of 2; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 4 - 512; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 8 - 2048. */ + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */ + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process; + Recommended value for this field is 0; in this way timed-out frames will be discarded */ + uint32_t timeoutThresholdForReassmProcess; + /**< Represents the time interval in microseconds which defines + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ +} t_FmPcdManipReassemCapwapParams; + +/**************************************************************************//** + @Description structure for defining CAPWAP manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipSpecialOffloadCapwapParams { + bool dtls; /**< TRUE if continue to SEC DTLS encryption */ + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */ +} t_FmPcdManipSpecialOffloadCapwapParams; + +#endif /* (DPAA_VERSION >= 11) */ + + +/**************************************************************************//** + @Description Parameters for defining special offload manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipSpecialOffloadParams { + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */ + union + { + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */ +#if (DPAA_VERSION >= 11) + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} t_FmPcdManipSpecialOffloadParams; + +/**************************************************************************//** + @Description Parameters for defining insertion manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrt { + uint8_t size; /**< size of inserted section */ + uint8_t *p_Data; /**< data to be inserted */ +} t_FmPcdManipHdrInsrt; + + +/**************************************************************************//** + @Description Parameters for defining generic removal manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrRmvGenericParams { + uint8_t offset; /**< Offset from beginning of header to the start + location of the removal */ + uint8_t size; /**< Size of removed section */ +} t_FmPcdManipHdrRmvGenericParams; + +/**************************************************************************//** + @Description Parameters for defining generic insertion manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrtGenericParams { + uint8_t offset; /**< Offset from beginning of header to the start + location of the insertion */ + uint8_t size; /**< Size of inserted section */ + bool replace; /**< TRUE to override (replace) existing data at + 'offset', FALSE to insert */ + uint8_t *p_Data; /**< Pointer to data to be inserted */ +} t_FmPcdManipHdrInsrtGenericParams; + +/**************************************************************************//** + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri { + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS]; + /**< A table of VPri values for each DSCP value; + The index is the DSCP value (0-0x3F) and the + value is the corresponding VPRI (0-15). */ + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType = + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN, + this field is the Q Tag default value if the + IP header is not found. */ +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri; + +/**************************************************************************//** + @Description Parameters for defining header manipulation VLAN fields updates +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateVlan { + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */ + union { + uint8_t vpri; /**< 0-7, Relevant only if If updateType = + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this + is the new VLAN pri. */ + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */ + } u; +} t_FmPcdManipHdrFieldUpdateVlan; + +/**************************************************************************//** + @Description Parameters for defining header manipulation IPV4 fields updates +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 { + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains + HDR_MANIP_IPV4_TOS */ + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates + contains HDR_MANIP_IPV4_ID */ + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates + contains HDR_MANIP_IPV4_SRC */ + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates + contains HDR_MANIP_IPV4_DST */ +} t_FmPcdManipHdrFieldUpdateIpv4; + +/**************************************************************************//** + @Description Parameters for defining header manipulation IPV6 fields updates +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 { + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains + HDR_MANIP_IPV6_TC */ + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE]; + /**< 16 byte new IP SRC; Relevant only if validUpdates + contains HDR_MANIP_IPV6_SRC */ + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE]; + /**< 16 byte new IP DST; Relevant only if validUpdates + contains HDR_MANIP_IPV6_DST */ +} t_FmPcdManipHdrFieldUpdateIpv6; + +/**************************************************************************//** + @Description Parameters for defining header manipulation TCP/UDP fields updates +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp { + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates + contains HDR_MANIP_TCP_UDP_SRC */ + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates + contains HDR_MANIP_TCP_UDP_DST */ +} t_FmPcdManipHdrFieldUpdateTcpUdp; + +/**************************************************************************//** + @Description Parameters for defining header manipulation fields updates +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrFieldUpdateParams { + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */ + union { + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */ + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */ + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */ + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */ + } u; +} t_FmPcdManipHdrFieldUpdateParams; + + + +/**************************************************************************//** + @Description Parameters for defining custom header manipulation for generic field replacement +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrCustomGenFieldReplace { + uint8_t srcOffset; /**< Location of new data - Offset from + Parse Result (>= 16, srcOffset+size <= 32, ) */ + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from + start of frame (dstOffset + size <= 256). */ + uint8_t size; /**< The number of bytes (<=16) to be replaced */ + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for + replacement (1 - bit will be replaced); + Clear to use field as is. */ + uint8_t maskOffset; /**< Relevant if mask != 0; + Mask offset within the replaces "size" */ +} t_FmPcdManipHdrCustomGenFieldReplace; + +/**************************************************************************//** + @Description Parameters for defining custom header manipulation for IP replacement +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrCustomIpHdrReplace { + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */ + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */ + bool updateIpv4Id; /**< Relevant when replaceType = + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */ + uint16_t id; /**< 16 bit New IP ID; Relevant only if + updateIpv4Id = TRUE */ + uint8_t hdrSize; /**< The size of the new IP header */ + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE]; + /**< The new IP header */ +} t_FmPcdManipHdrCustomIpHdrReplace; + +/**************************************************************************//** + @Description Parameters for defining custom header manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrCustomParams { + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */ + union { + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */ + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */ + } u; +} t_FmPcdManipHdrCustomParams; + +/**************************************************************************//** + @Description Parameters for defining specific L2 insertion manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params { + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */ + bool update; /**< TRUE to update MPLS header */ + uint8_t size; /**< size of inserted section */ + uint8_t *p_Data; /**< data to be inserted */ +} t_FmPcdManipHdrInsrtSpecificL2Params; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Parameters for defining IP insertion manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrtIpParams { + bool calcL4Checksum; /**< Calculate L4 checksum. */ + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */ + uint8_t lastPidOffset; /**< the offset of the last Protocol within + the inserted header */ + uint16_t id; /**< 16 bit New IP ID */ + bool dontFragOverwrite; + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte. + * This byte is configured to be overwritten when RPD is set. */ + uint8_t lastDstOffset; + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address + * in order to calculate UDP checksum pseudo header; + * Otherwise set it to '0'. */ + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */ +} t_FmPcdManipHdrInsrtIpParams; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Parameters for defining header insertion manipulation by header type +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrtByHdrParams { + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */ + union { + + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params; + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2: + Selects which L2 headers to insert */ +#if (DPAA_VERSION >= 11) + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */ + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} t_FmPcdManipHdrInsrtByHdrParams; + +/**************************************************************************//** + @Description Parameters for defining header insertion manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrInsrtParams { + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */ + union { + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type, + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */ + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation, + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */ +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template, + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */ +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ + } u; +} t_FmPcdManipHdrInsrtParams; + +/**************************************************************************//** + @Description Parameters for defining header removal manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrRmvParams { + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */ + union { + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type, + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */ + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation, + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */ + } u; +} t_FmPcdManipHdrRmvParams; + +/**************************************************************************//** + @Description Parameters for defining header manipulation node +*//***************************************************************************/ +typedef struct t_FmPcdManipHdrParams { + bool rmv; /**< TRUE, to define removal manipulation */ + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */ + + bool insrt; /**< TRUE, to define insertion manipulation */ + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */ + + bool fieldUpdate; /**< TRUE, to define field update manipulation */ + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */ + + bool custom; /**< TRUE, to define custom manipulation */ + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */ + + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node. + Restrictions: + 1. MUST be set if the next engine after the CC is not another CC node + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and + also never pointed as h_NextManip of other manipulation nodes) + 2. MUST be set if the next engine after the CC is another CC node, and + this is NOT the last manipulation node (i.e. it has h_NextManip).*/ +} t_FmPcdManipHdrParams; + +/**************************************************************************//** + @Description Parameters for defining fragmentation manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipFragParams { + e_NetHeaderType hdr; /**< Header selection */ + union { +#if (DPAA_VERSION >= 11) + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation, + relevant if 'hdr' = HEADER_TYPE_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation, + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ + } u; +} t_FmPcdManipFragParams; + +/**************************************************************************//** + @Description Parameters for defining reassembly manipulation +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemParams { + e_NetHeaderType hdr; /**< Header selection */ + union { +#if (DPAA_VERSION >= 11) + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly, + relevant if 'hdr' = HEADER_TYPE_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly, + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ + } u; +} t_FmPcdManipReassemParams; + +/**************************************************************************//** + @Description Parameters for defining a manipulation node *//***************************************************************************/ typedef struct t_FmPcdManipParams { - bool rmv; /**< TRUE, if defined remove manipulation */ - t_FmPcdManipRmvParams rmvParams; /**< Parameters for remove manipulation, relevant if rmv = TRUE */ + e_FmPcdManipType type; /**< Selects type of manipulation node */ + union{ + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */ + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */ + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */ + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */ + } u; - bool insrt; /**< TRUE, if defined insert manipulation */ - t_FmPcdManipInsrtParams insrtParams; /**< Parameters for insert manipulation, relevant if insrt = TRUE */ - - bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */ - t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation, relevant if fragOrReasm = TRUE */ - - /**< General parameters */ - bool treatFdStatusFieldsAsErrors; - /**< Set to TRUE when the port that is using this manip is chained - to SEC (i.e. the traffic was forwarded from SEC) */ + t_Handle h_NextManip; /**< Supported for Header Manipulation only; + Handle to another (previously defined) manipulation node; + Allows concatenation of manipulation actions; + This parameter is optional and may be NULL. */ +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */ + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation, + relevant if fragOrReasm = TRUE */ +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ } t_FmPcdManipParams; +/**************************************************************************//** + @Description Structure for retrieving IP reassembly statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemIpStats { + /* common counters for both IPv4 and IPv6 */ + uint32_t timeout; /**< Counts the number of timeout occurrences */ + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate + a Reassembly Frame Descriptor */ + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */ + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */ + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */ + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ +#if (DPAA_VERSION >= 11) + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for + successfully reassembled frames */ +#endif /* (DPAA_VERSION >= 11) */ + struct { + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */ + uint32_t validFragments; /**< Counts the total number of valid fragments that + have been processed for all frames */ + uint32_t processedFragments; /**< Counts the number of processed fragments + (valid and error fragments) for all frames */ + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */ + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */ + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting + to access an IP-Reassembly Automatic Learning Hash set */ + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame + exceeds 16 */ + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */ +} t_FmPcdManipReassemIpStats; + +/**************************************************************************//** + @Description Structure for retrieving IP fragmentation statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipFragIpStats { + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */ + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */ + uint32_t generatedFragments; /**< Number of fragments that were generated */ +} t_FmPcdManipFragIpStats; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Structure for retrieving CAPWAP reassembly statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemCapwapStats { + uint32_t timeout; /**< Counts the number of timeout occurrences */ + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate + a Reassembly Frame Descriptor */ + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */ + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */ + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */ + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */ + uint32_t validFragments; /**< Counts the total number of valid fragments that + have been processed for all frames */ + uint32_t processedFragments; /**< Counts the number of processed fragments + (valid and error fragments) for all frames */ + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */ + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting + to access an Reassembly Automatic Learning Hash set */ + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */ + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame + exceeds 16 */ + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame + length exceeds MaxReassembledFrameLength value */ +} t_FmPcdManipReassemCapwapStats; + +/**************************************************************************//** + @Description Structure for retrieving CAPWAP fragmentation statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipFragCapwapStats { + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */ + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */ + uint32_t generatedFragments; /**< Number of fragments that were generated */ +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */ +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ +} t_FmPcdManipFragCapwapStats; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Structure for retrieving reassembly statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipReassemStats { + union { + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */ +#if (DPAA_VERSION >= 11) + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} t_FmPcdManipReassemStats; + +/**************************************************************************//** + @Description Structure for retrieving fragmentation statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipFragStats { + union { + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */ +#if (DPAA_VERSION >= 11) + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} t_FmPcdManipFragStats; + +/**************************************************************************//** + @Description Structure for selecting manipulation statistics +*//***************************************************************************/ +typedef struct t_FmPcdManipStats { + union { + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */ + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */ + } u; +} t_FmPcdManipStats; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Parameters for defining frame replicator group and its members +*//***************************************************************************/ +typedef struct t_FmPcdFrmReplicGroupParams { + uint8_t maxNumOfEntries; /**< Maximal number of members in the group; + Must be at least 2. */ + uint8_t numOfEntries; /**< Number of members in the group; + Must be at least 1. */ + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES]; + /**< Array of members' parameters */ +} t_FmPcdFrmReplicGroupParams; +#endif /* (DPAA_VERSION >= 11) */ + +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) /**************************************************************************//** @Description structure for defining statistics node *//***************************************************************************/ typedef struct t_FmPcdStatsParams { - e_FmPcdStatsType type; /**< type of statistics node */ + e_FmPcdStatsType type; /**< type of statistics node */ } t_FmPcdStatsParams; -#endif /* defined(FM_CAPWAP_SUPPORT) || ... */ - +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ /**************************************************************************//** - @Function FM_PCD_SetNetEnvCharacteristics + @Function FM_PCD_NetEnvCharacteristicsSet @Description Define a set of Network Environment Characteristics. + When setting an environment it is important to understand its application. It is not meant to describe the flows that will run on the ports using this environment, but what the user means TO DO with the PCD mechanisms in order to parse-classify-distribute those frames. By specifying a distinction unit, the user means it would use that option - for distinction between frames at either a keygen scheme keygen or a coarse + for distinction between frames at either a KeyGen scheme or a coarse classification action descriptor. Using interchangeable headers to define a unit means that the user is indifferent to which of the interchangeable - headers is present in the frame, and they want the distinction to be based + headers is present in the frame, and wants the distinction to be based on the presence of either one of them. + Depending on context, there are limitations to the use of environments. A port using the PCD functionality is bound to an environment. Some or even all ports may share an environment but also an environment per port is @@ -1746,6 +2938,7 @@ typedef struct t_FmPcdStatsParams { stated and related to. When a port is bound to a scheme, a classification plan group, or a coarse classification tree, it MUST be bound to the same environment. + The different PCD modules, may relate (for flows definition) ONLY on distinction units as defined by their environment. When initializing a scheme for example, it may not choose to select IPV4 as a match for @@ -1753,6 +2946,7 @@ typedef struct t_FmPcdStatsParams { fact, to guide the user through the configuration of the PCD, each module's characterization in terms of flows is not done using protocol names, but using environment indexes. + In terms of HW implementation, the list of distinction units sets the LCV vectors and later used for match vector, classification plan vectors and coarse classification indexing. @@ -1765,280 +2959,86 @@ typedef struct t_FmPcdStatsParams { @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams); +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams); /**************************************************************************//** - @Function FM_PCD_DeleteNetEnvCharacteristics + @Function FM_PCD_NetEnvCharacteristicsDelete @Description Deletes a set of Network Environment Characteristics. - @Param[in] h_FmPcd FM PCD module descriptor. @Param[in] h_NetEnv A handle to the Network environment. @Return E_OK on success; Error code otherwise. *//***************************************************************************/ -t_Error FM_PCD_DeleteNetEnvCharacteristics(t_Handle h_FmPcd, t_Handle h_NetEnv); +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv); /**************************************************************************//** - @Function FM_PCD_KgSetScheme + @Function FM_PCD_KgSchemeSet - @Description Initializing or modifying and enabling a scheme for the keygen. + @Description Initializing or modifying and enabling a scheme for the KeyGen. This routine should be called for adding or modifying a scheme. When a scheme needs modifying, the API requires that it will be rewritten. In such a case 'modify' should be TRUE. If the routine is called for a valid scheme and 'modify' is FALSE, it will return error. - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in,out] p_Scheme A structure of parameters for defining the scheme + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module. + Otherwise NULL (ignored by driver). + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme @Return A handle to the initialized scheme on success; NULL code otherwise. + When used as "modify" (rather than for setting a new scheme), + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme + BUSY state. @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Handle FM_PCD_KgSetScheme (t_Handle h_FmPcd, - t_FmPcdKgSchemeParams *p_Scheme); +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, + t_FmPcdKgSchemeParams *p_SchemeParams); /**************************************************************************//** - @Function FM_PCD_KgDeleteScheme + @Function FM_PCD_KgSchemeDelete @Description Deleting an initialized scheme. - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet() @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PCD_Init(). + + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). *//***************************************************************************/ -t_Error FM_PCD_KgDeleteScheme(t_Handle h_FmPcd, t_Handle h_Scheme); +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme); /**************************************************************************//** - @Function FM_PCD_KgGetSchemeCounter + @Function FM_PCD_KgSchemeGetCounter @Description Reads scheme packet counter. - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme. + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet(). @Return Counter's current value. - @Cautions Allowed only following FM_PCD_Init(). + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). *//***************************************************************************/ -uint32_t FM_PCD_KgGetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme); +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme); /**************************************************************************//** - @Function FM_PCD_KgSetSchemeCounter + @Function FM_PCD_KgSchemeSetCounter @Description Writes scheme packet counter. - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme. + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet(). @Param[in] value New scheme counter value - typically '0' for resetting the counter. - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_Init(). -*//***************************************************************************/ -t_Error FM_PCD_KgSetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t value); - -/**************************************************************************//** - @Function FM_PCD_CcBuildTree - - @Description This routine must be called to define a complete coarse - classification tree. This is the way to define coarse - classification to a certain flow - the keygen schemes - may point only to trees defined in this way. - - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] p_FmPcdCcTreeParams A structure of parameters to define the tree. - - @Return A handle to the initialized object on success; NULL code otherwise. - - @Cautions Allowed only following FM_PCD_Init(). -*//***************************************************************************/ -t_Handle FM_PCD_CcBuildTree (t_Handle h_FmPcd, - t_FmPcdCcTreeParams *p_FmPcdCcTreeParams); - -/**************************************************************************//** - @Function FM_PCD_CcDeleteTree - - @Description Deleting an built tree. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcTree A handle to a CC tree. - - @Cautions Allowed only following FM_PCD_Init(). -*//***************************************************************************/ -t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree); - -/**************************************************************************//** - @Function FM_PCD_CcSetNode - - @Description This routine should be called for each CC (coarse classification) - node. The whole CC tree should be built bottom up so that each - node points to already defined nodes. - - @Param[in] h_FmPcd FM PCD module descriptor. - @Param[in] p_CcNodeParam A structure of parameters defining the CC node - - @Return A handle to the initialized object on success; NULL code otherwise. - - @Cautions Allowed only following FM_PCD_Init(). -*//***************************************************************************/ -t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd, - t_FmPcdCcNodeParams *p_CcNodeParam); - -/**************************************************************************//** - @Function FM_PCD_CcDeleteNode - - @Description Deleting an built node. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to a CC node. - - @Cautions Allowed only following FM_PCD_Init(). -*//***************************************************************************/ -t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode); - -/**************************************************************************//** - @Function FM_PCD_CcTreeModifyNextEngine - - @Description Modify the Next Engine Parameters in the entry of the tree. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcTree A handle to the tree - @Param[in] grpId A Group index in the tree - @Param[in] index Entry index in the group defined by grpId - @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PCD_CcBuildTree(). + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). *//***************************************************************************/ -t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value); /**************************************************************************//** - @Function FM_PCD_CcNodeModifyNextEngine - - @Description Modify the Next Engine Parameters in the relevant key entry of the node. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for Next Engine Params modifications - @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode(). -*//***************************************************************************/ -t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); - -/**************************************************************************//** - @Function FM_PCD_CcNodeModifyMissNextEngine - - @Description Modify the Next Engine Parameters of the Miss key case of the node. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode(). -*//***************************************************************************/ -t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); - -/**************************************************************************//** - @Function FM_PCD_CcNodeRemoveKey - - @Description Remove the key (include Next Engine Parameters of this key) defined by the index of the relevant node . - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for removing - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also - the node that points to this node -*//***************************************************************************/ -t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex); - -/**************************************************************************//** - @Function FM_PCD_CcNodeAddKey - - @Description Add the key(include Next Engine Parameters of this key)in the index defined by the keyIndex . - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for adding - @Param[in] keySize Key size of added key - @Param[in] p_KeyParams A pointer to the parameters includes new key with Next Engine Parameters - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also - the node that points to this node -*//***************************************************************************/ -t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams); - -/**************************************************************************//** - @Function FM_PCD_CcNodeModifyKeyAndNextEngine - - @Description Modify the key and Next Engine Parameters of this key in the index defined by the keyIndex . - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for adding - @Param[in] keySize Key size of added key - @Param[in] p_KeyParams A pointer to the parameters includes modified key and modified Next Engine Parameters - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also - the node that points to this node -*//***************************************************************************/ -t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams); - -/**************************************************************************//** - @Function FM_PCD_CcNodeModifyKey - - @Description Modify the key in the index defined by the keyIndex . - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for adding - @Param[in] keySize Key size of added key - @Param[in] p_Key A pointer to the new key - @Param[in] p_Mask A pointer to the new mask if relevant, otherwise pointer to NULL - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also - the node that points to this node -*//***************************************************************************/ -t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask); - -/**************************************************************************//** - @Function FM_PCD_CcNodeGetKeyCounter - - @Description This routine may be used to get a counter of specific key in a CC - Node; This counter reflects how many frames passed that were matched - this key. - - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_CcNode A handle to the node - @Param[in] keyIndex Key index for adding - - @Return The specific key counter. - - @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also - the node that points to this node -*//***************************************************************************/ -uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex); - -/**************************************************************************//** - @Function FM_PCD_PlcrSetProfile + @Function FM_PCD_PlcrProfileSet @Description Sets a profile entry in the policer profile table. The routine overrides any existing value. @@ -2048,50 +3048,50 @@ uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t policer profile entry. @Return A handle to the initialized object on success; NULL code otherwise. - + When used as "modify" (rather than for setting a new profile), + p_Profile->id.h_Profile will return NULL if action fails due to profile + BUSY state. @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd, +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile); /**************************************************************************//** - @Function FM_PCD_PlcrDeleteProfile + @Function FM_PCD_PlcrProfileDelete @Description Delete a profile entry in the policer profile table. The routine set entry to invalid. - @Param[in] h_FmPcd A handle to an FM PCD Module. @Param[in] h_Profile A handle to the profile. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Error FM_PCD_PlcrDeleteProfile(t_Handle h_FmPcd, t_Handle h_Profile); +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile); /**************************************************************************//** - @Function FM_PCD_PlcrGetProfileCounter + @Function FM_PCD_PlcrProfileGetCounter @Description Sets an entry in the classification plan. The routine overrides any existing value. - @Param[in] h_FmPcd A handle to an FM PCD Module. @Param[in] h_Profile A handle to the profile. - @Param[in] counter Counter selector. + @Param[in] counter Counter selector. @Return specific counter value. @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter); +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, + e_FmPcdPlcrProfileCounters counter); /**************************************************************************//** - @Function FM_PCD_PlcrSetProfileCounter + @Function FM_PCD_PlcrProfileSetCounter @Description Sets an entry in the classification plan. The routine overrides any existing value. - @Param[in] h_FmPcd A handle to an FM PCD Module. @Param[in] h_Profile A handle to the profile. @Param[in] counter Counter selector. @Param[in] value value to set counter with. @@ -2100,11 +3100,672 @@ uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_Fm @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value); +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, + e_FmPcdPlcrProfileCounters counter, + uint32_t value); -#if defined(FM_CAPWAP_SUPPORT) /**************************************************************************//** - @Function FM_PCD_ManipSetNode + @Function FM_PCD_CcRootBuild + + @Description This routine must be called to define a complete coarse + classification tree. This is the way to define coarse + classification to a certain flow - the KeyGen schemes + may point only to trees defined in this way. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] p_Params A structure of parameters to define the tree. + + @Return A handle to the initialized object on success; NULL code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd, + t_FmPcdCcTreeParams *p_Params); + +/**************************************************************************//** + @Function FM_PCD_CcRootDelete + + @Description Deleting an built tree. + + @Param[in] h_CcTree A handle to a CC tree. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree); + +/**************************************************************************//** + @Function FM_PCD_CcRootModifyNextEngine + + @Description Modify the Next Engine Parameters in the entry of the tree. + + @Param[in] h_CcTree A handle to the tree + @Param[in] grpId A Group index in the tree + @Param[in] index Entry index in the group defined by grpId + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_CcBuildTree(). +*//***************************************************************************/ +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree, + uint8_t grpId, + uint8_t index, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableSet + + @Description This routine should be called for each CC (coarse classification) + node. The whole CC tree should be built bottom up so that each + node points to already defined nodes. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] p_Param A structure of parameters defining the CC node + + @Return A handle to the initialized object on success; NULL code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param); + +/**************************************************************************//** + @Function FM_PCD_MatchTableDelete + + @Description Deleting an built node. + + @Param[in] h_CcNode A handle to a CC node. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode); + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyMissNextEngine + + @Description Modify the Next Engine Parameters of the Miss key case of the node. + + @Param[in] h_CcNode A handle to the node + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(); + Not relevant in the case the node is of type 'INDEXED_LOOKUP'. + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. + +*//***************************************************************************/ +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableRemoveKey + + @Description Remove the key (including next engine parameters of this key) + defined by the index of the relevant node. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for removing + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex); + +/**************************************************************************//** + @Function FM_PCD_MatchTableAddKey + + @Description Add the key (including next engine parameters of this key in the + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX' + may be used by user that don't care about the position of the + key in the table - in that case, the key will be automatically + added by the driver in the last available entry. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for adding. + @Param[in] keySize Key size of added key + @Param[in] p_KeyParams A pointer to the parameters includes + new key with Next Engine Parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, + uint16_t keyIndex, + uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyNextEngine + + @Description Modify the Next Engine Parameters in the relevant key entry of the node. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for Next Engine modifications + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. + +*//***************************************************************************/ +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode, + uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyKeyAndNextEngine + + @Description Modify the key and Next Engine Parameters of this key in the + index defined by the keyIndex. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for adding + @Param[in] keySize Key size of added key + @Param[in] p_KeyParams A pointer to the parameters includes + modified key and modified Next Engine Parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, + uint16_t keyIndex, + uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyKey + + @Description Modify the key in the index defined by the keyIndex. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for adding + @Param[in] keySize Key size of added key + @Param[in] p_Key A pointer to the new key + @Param[in] p_Mask A pointer to the new mask if relevant, + otherwise pointer to NULL + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, + uint16_t keyIndex, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask); + +/**************************************************************************//** + @Function FM_PCD_MatchTableFindNRemoveKey + + @Description Remove the key (including next engine parameters of this key) + defined by the key and mask. Note that this routine will search + the node to locate the index of the required key (& mask) to remove. + + @Param[in] h_CcNode A handle to the node + @Param[in] keySize Key size of the one to remove. + @Param[in] p_Key A pointer to the requested key to remove. + @Param[in] p_Mask A pointer to the mask if relevant, + otherwise pointer to NULL + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask); + +/**************************************************************************//** + @Function FM_PCD_MatchTableFindNModifyNextEngine + + @Description Modify the Next Engine Parameters in the relevant key entry of + the node. Note that this routine will search the node to locate + the index of the required key (& mask) to modify. + + @Param[in] h_CcNode A handle to the node + @Param[in] keySize Key size of the one to modify. + @Param[in] p_Key A pointer to the requested key to modify. + @Param[in] p_Mask A pointer to the mask if relevant, + otherwise pointer to NULL + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine + + @Description Modify the key and Next Engine Parameters of this key in the + index defined by the keyIndex. Note that this routine will search + the node to locate the index of the required key (& mask) to modify. + + @Param[in] h_CcNode A handle to the node + @Param[in] keySize Key size of the one to modify. + @Param[in] p_Key A pointer to the requested key to modify. + @Param[in] p_Mask A pointer to the mask if relevant, + otherwise pointer to NULL + @Param[in] p_KeyParams A pointer to the parameters includes + modified key and modified Next Engine Parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask, + t_FmPcdCcKeyParams *p_KeyParams); + +/**************************************************************************//** + @Function FM_PCD_MatchTableFindNModifyKey + + @Description Modify the key in the index defined by the keyIndex. Note that + this routine will search the node to locate the index of the + required key (& mask) to modify. + + @Param[in] h_CcNode A handle to the node + @Param[in] keySize Key size of the one to modify. + @Param[in] p_Key A pointer to the requested key to modify. + @Param[in] p_Mask A pointer to the mask if relevant, + otherwise pointer to NULL + @Param[in] p_NewKey A pointer to the new key + @Param[in] p_NewMask A pointer to the new mask if relevant, + otherwise pointer to NULL + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this + node and the nodes that lead to it. +*//***************************************************************************/ +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask, + uint8_t *p_NewKey, + uint8_t *p_NewMask); + +/**************************************************************************//** + @Function FM_PCD_MatchTableGetKeyCounter + + @Description This routine may be used to get a counter of specific key in a CC + Node; This counter reflects how many frames passed that were matched + this key. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for adding + + @Return The specific key counter. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex); + +/**************************************************************************//** + @Function FM_PCD_MatchTableGetKeyStatistics + + @Description This routine may be used to get statistics counters of specific key + in a CC Node. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames passed that were matched + this key; The total frames count will be returned in the counter + of the first range (as only one frame length range was defined). + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total + frame count will be separated to frame length counters, based on + provided frame length ranges. + + @Param[in] h_CcNode A handle to the node + @Param[in] keyIndex Key index for adding + @Param[out] p_KeyStatistics Key statistics counters + + @Return The specific key statistics. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode, + uint16_t keyIndex, + t_FmPcdCcKeyStatistics *p_KeyStatistics); + +/**************************************************************************//** + @Function FM_PCD_MatchTableGetMissStatistics + + @Description This routine may be used to get statistics counters of miss entry + in a CC Node. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; The + total frames count will be returned in the counter of the + first range (as only one frame length range was defined). + + @Param[in] h_CcNode A handle to the node + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return The statistics for 'miss'. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode, + t_FmPcdCcKeyStatistics *p_MissStatistics); + +/**************************************************************************//** + @Function FM_PCD_MatchTableFindNGetKeyStatistics + + @Description This routine may be used to get statistics counters of specific key + in a CC Node. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames passed that were matched + this key; The total frames count will be returned in the counter + of the first range (as only one frame length range was defined). + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total + frame count will be separated to frame length counters, based on + provided frame length ranges. + Note that this routine will search the node to locate the index + of the required key based on received key parameters. + + @Param[in] h_CcNode A handle to the node + @Param[in] keySize Size of the requested key + @Param[in] p_Key A pointer to the requested key + @Param[in] p_Mask A pointer to the mask if relevant, + otherwise pointer to NULL + @Param[out] p_KeyStatistics Key statistics counters + + @Return The specific key statistics. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode, + uint8_t keySize, + uint8_t *p_Key, + uint8_t *p_Mask, + t_FmPcdCcKeyStatistics *p_KeyStatistics); + +/**************************************************************************//* + @Function FM_PCD_MatchTableGetNextEngine + + @Description Gets NextEngine of the relevant keyIndex. + + @Param[in] h_CcNode A handle to the node. + @Param[in] keyIndex keyIndex in the relevant node. + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for + the relevant keyIndex of the CC Node + received as parameter to this function + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode, + uint16_t keyIndex, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//* + @Function FM_PCD_MatchTableGetIndexedHashBucket + + @Description This routine simulates KeyGen operation on the provided key and + calculates to which hash bucket it will be mapped. + + @Param[in] h_CcNode A handle to the node. + @Param[in] kgKeySize Key size as it was configured in the KG + scheme that leads to this hash. + @Param[in] p_KgKey Pointer to the key; must be like the key + that the KG is generated, i.e. the same + extraction and with mask if exist. + @Param[in] kgHashShift Hash-shift as it was configured in the KG + scheme that leads to this hash. + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key. + @Param[out] p_BucketIndex Index to the bucket of the provided key + @Param[out] p_LastIndex Pointer to last index in the bucket of the + provided key. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet() +*//***************************************************************************/ +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode, + uint8_t kgKeySize, + uint8_t *p_KgKey, + uint8_t kgHashShift, + t_Handle *p_CcNodeBucketHandle, + uint8_t *p_BucketIndex, + uint16_t *p_LastIndex); + +/**************************************************************************//** + @Function FM_PCD_HashTableSet + + @Description This routine initializes a hash table structure. + KeyGen hash result determines the hash bucket. + Next, KeyGen key is compared against all keys of this + bucket (exact match). + Number of sets (number of buckets) of the hash equals to the + number of 1-s in 'hashResMask' in the provided parameters. + Number of hash table ways is then calculated by dividing + 'maxNumOfKeys' equally between the hash sets. This is the maximal + number of keys that a hash bucket may hold. + The hash table is initialized empty and keys may be + added to it following the initialization. Keys masks are not + supported in current hash table implementation. + The initialized hash table can be integrated as a node in a + CC tree. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] p_Param A structure of parameters defining the hash table + + @Return A handle to the initialized object on success; NULL code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param); + +/**************************************************************************//** + @Function FM_PCD_HashTableDelete + + @Description This routine deletes the provided hash table and released all + its allocated resources. + + @Param[in] h_HashTbl A handle to a hash table + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl); + +/**************************************************************************//** + @Function FM_PCD_HashTableAddKey + + @Description This routine adds the provided key (including next engine + parameters of this key) to the hash table. + The key is added as the last key of the bucket that it is + mapped to. + + @Param[in] h_HashTbl A handle to a hash table + @Param[in] keySize Key size of added key + @Param[in] p_KeyParams A pointer to the parameters includes + new key with next engine parameters; The pointer + to the key mask must be NULL, as masks are not + supported in hash table implementation. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, + uint8_t keySize, + t_FmPcdCcKeyParams *p_KeyParams); + +/**************************************************************************//** + @Function FM_PCD_HashTableRemoveKey + + @Description This routine removes the requested key (including next engine + parameters of this key) from the hash table. + + @Param[in] h_HashTbl A handle to a hash table + @Param[in] keySize Key size of the one to remove. + @Param[in] p_Key A pointer to the requested key to remove. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, + uint8_t keySize, + uint8_t *p_Key); + +/**************************************************************************//** + @Function FM_PCD_HashTableModifyNextEngine + + @Description This routine modifies the next engine for the provided key. The + key should be previously added to the hash table. + + @Param[in] h_HashTbl A handle to a hash table + @Param[in] keySize Key size of the key to modify. + @Param[in] p_Key A pointer to the requested key to modify. + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine + parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. +*//***************************************************************************/ +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl, + uint8_t keySize, + uint8_t *p_Key, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_HashTableModifyMissNextEngine + + @Description This routine modifies the next engine on key match miss. + + @Param[in] h_HashTbl A handle to a hash table + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine + parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). + When configuring nextEngine = e_FM_PCD_CC, note that + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different + from the currently changed table. +*//***************************************************************************/ +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//* + @Function FM_PCD_HashTableGetMissNextEngine + + @Description Gets NextEngine in case of key match miss. + + @Param[in] h_HashTbl A handle to a hash table + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified + hash table. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl, + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); + +/**************************************************************************//** + @Function FM_PCD_HashTableFindNGetKeyStatistics + + @Description This routine may be used to get statistics counters of specific key + in a hash table. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames passed that were matched + this key; The total frames count will be returned in the counter + of the first range (as only one frame length range was defined). + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total + frame count will be separated to frame length counters, based on + provided frame length ranges. + Note that this routine will identify the bucket of this key in + the hash table and will search the bucket to locate the index + of the required key based on received key parameters. + + @Param[in] h_HashTbl A handle to a hash table + @Param[in] keySize Size of the requested key + @Param[in] p_Key A pointer to the requested key + @Param[out] p_KeyStatistics Key statistics counters + + @Return The specific key statistics. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl, + uint8_t keySize, + uint8_t *p_Key, + t_FmPcdCcKeyStatistics *p_KeyStatistics); + +/**************************************************************************//** + @Function FM_PCD_HashTableGetMissStatistics + + @Description This routine may be used to get statistics counters of 'miss' + entry of the a hash table. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; + + @Param[in] h_HashTbl A handle to a hash table + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return The statistics for 'miss'. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl, + t_FmPcdCcKeyStatistics *p_MissStatistics); + +/**************************************************************************//** + @Function FM_PCD_ManipNodeSet @Description This routine should be called for defining a manipulation node. A manipulation node must be defined before the CC node @@ -2117,28 +3778,116 @@ t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmP @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Handle FM_PCD_ManipSetNode(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams); +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams); /**************************************************************************//** - @Function FM_PCD_ManipDeleteNode + @Function FM_PCD_ManipNodeDelete - @Description Delete an existing manip node. + @Description Delete an existing manipulation node. - @Param[in] h_FmPcd A handle to an FM PCD Module. - @Param[in] h_HdrManipNode A handle to a Manip node. + @Param[in] h_ManipNode A handle to a manipulation node. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_ManipNodeSet(). +*//***************************************************************************/ +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode); + +/**************************************************************************//** + @Function FM_PCD_ManipGetStatistics + + @Description Retrieve the manipulation statistics. + + @Param[in] h_ManipNode A handle to a manipulation node. + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_ManipNodeSet(). +*//***************************************************************************/ +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats); + +/**************************************************************************//** + @Function FM_PCD_ManipNodeReplace + + @Description Change existing manipulation node to be according to new requirement. + + @Param[in] h_ManipNode A handle to a manipulation node. + @Param[out] p_ManipParams A structure of parameters defining the change requirement + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_ManipNodeSet(). +*//***************************************************************************/ +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams); + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Function FM_PCD_FrmReplicSetGroup + + @Description Initialize a Frame Replicator group. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of + the frame replicator group. + + @Return A handle to the initialized object on success; NULL code otherwise. @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ -t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_HdrManipNode); -#endif /* defined(FM_CAPWAP_SUPPORT) || ... */ +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam); +/**************************************************************************//** + @Function FM_PCD_FrmReplicDeleteGroup -#ifdef FM_CAPWAP_SUPPORT + @Description Delete a Frame Replicator group. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup(). +*//***************************************************************************/ +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup); + +/**************************************************************************//** + @Function FM_PCD_FrmReplicAddMember + + @Description Add the member in the index defined by the memberIndex. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + @Param[in] memberIndex member index for adding. + @Param[in] p_MemberParams A pointer to the new member parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. +*//***************************************************************************/ +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup, + uint16_t memberIndex, + t_FmPcdCcNextEngineParams *p_MemberParams); + +/**************************************************************************//** + @Function FM_PCD_FrmReplicRemoveMember + + @Description Remove the member defined by the index from the relevant group. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + @Param[in] memberIndex member index for removing. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. +*//***************************************************************************/ +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup, + uint16_t memberIndex); +#endif /* (DPAA_VERSION >= 11) */ + +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) /**************************************************************************//** @Function FM_PCD_StatisticsSetNode - @Description This routine should be called for defining a statistics - node. + @Description This routine should be called for defining a statistics node. @Param[in] h_FmPcd FM PCD module descriptor. @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics @@ -2148,13 +3897,78 @@ t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_HdrManipNode); @Cautions Allowed only following FM_PCD_Init(). *//***************************************************************************/ t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams); -#endif /* FM_CAPWAP_SUPPORT */ +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -/** @} */ /* end of FM_PCD_Runtime_tree_buildgrp group */ +/** @} */ /* end of FM_PCD_Runtime_build_grp group */ /** @} */ /* end of FM_PCD_Runtime_grp group */ /** @} */ /* end of FM_PCD_grp group */ /** @} */ /* end of FM_grp group */ +#ifdef NCSW_BACKWARD_COMPATIBLE_API +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH + +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */ + +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \ + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params) +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params) +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params) +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params) +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params) +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params) + +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \ + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__) +#define FM_PCD_KgDeleteScheme(_pcd, ...) \ + FM_PCD_KgSchemeDelete(__VA_ARGS__) +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \ + FM_PCD_KgSchemeGetCounter(__VA_ARGS__) +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \ + FM_PCD_KgSchemeSetCounter(__VA_ARGS__) +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \ + FM_PCD_PlcrProfileDelete(__VA_ARGS__) +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \ + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__) +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \ + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__) +#define FM_PCD_CcDeleteTree(_pcd, ...) \ + FM_PCD_CcRootDelete(__VA_ARGS__) +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \ + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__) +#define FM_PCD_CcDeleteNode(_pcd, ...) \ + FM_PCD_MatchTableDelete(__VA_ARGS__) +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \ + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \ + FM_PCD_MatchTableRemoveKey(__VA_ARGS__) +#define FM_PCD_CcNodeAddKey(_pcd, ...) \ + FM_PCD_MatchTableAddKey(__VA_ARGS__) +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \ + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \ + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \ + FM_PCD_MatchTableModifyKey(__VA_ARGS__) +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \ + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__) +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \ + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \ + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \ + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__) +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \ + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__) +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \ + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__) +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \ + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__) +#define FM_PCD_ManipDeleteNode(_pcd, ...) \ + FM_PCD_ManipNodeDelete(__VA_ARGS__) +#endif /* NCSW_BACKWARD_COMPATIBLE_API */ + #endif /* __FM_PCD_EXT */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h index d1df4ea2dfc6..08a5aa59ab9d 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_port_ext.h @@ -60,21 +61,18 @@ @Description FM Port API The FM uses a general module called "port" to represent a Tx port - (MAC), an Rx port (MAC), offline parsing flow or host command - flow. There may be up to 17 (may change) ports in an FM - 5 Tx - ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7 - Host command/Offline parsing ports. The SW driver manages these - ports as sub-modules of the FM, i.e. after an FM is initialized, - its ports may be initialized and operated upon. + (MAC), an Rx port (MAC) or Offline Parsing port. + The number of ports in an FM varies between SOCs. + The SW driver manages these ports as sub-modules of the FM, i.e. + after an FM is initialized, its ports may be initialized and + operated upon. The port is initialized aware of its type, but other functions on a port may be indifferent to its type. When necessary, the driver - verifies coherency and returns error if applicable. + verifies coherence and returns error if applicable. On initialization, user specifies the port type and it's index - (relative to the port's type). Host command and Offline parsing - ports share the same id range, I.e user may not initialized host - command port 0 and offline parsing port 0. + (relative to the port's type) - always starting at 0. @{ *//***************************************************************************/ @@ -85,22 +83,28 @@ all engines have to be used, but all have to be enabled. The real flow of a specific frame depends on the PCD configuration and the frame headers and payload. + Note: the first engine and the first engine after the parser (if + exists) should be in order, the order is important as it will + define the flow of the port. However, as for the rest engines + (the ones that follows), the order is not important anymore as + it is defined by the PCD graph itself. *//***************************************************************************/ typedef enum e_FmPortPcdSupport { - e_FM_PORT_PCD_SUPPORT_NONE = 0, /**< BMI to BMI, PCD is not used */ - e_FM_PORT_PCD_SUPPORT_PRS_ONLY, /**< Use only Parser */ - e_FM_PORT_PCD_SUPPORT_PLCR_ONLY, /**< Use only Policer */ - e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR, /**< Use Parser and Policer */ - e_FM_PORT_PCD_SUPPORT_PRS_AND_KG, /**< Use Parser and Keygen */ - e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC, /**< Use Parser, Keygen and Coarse Classification */ - e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR, - /**< Use all PCD engines */ - e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */ + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */ + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */ + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR + /**< Use all PCD engines */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */ + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */ + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ #ifdef FM_CAPWAP_SUPPORT - , - e_FM_PORT_PCD_SUPPORT_CC_ONLY, /**< Use only Coarse Classification */ - e_FM_PORT_PCD_SUPPORT_CC_AND_KG, /**< Use Coarse Classification,and Keygen */ - e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */ + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */ + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */ #endif /* FM_CAPWAP_SUPPORT */ } e_FmPortPcdSupport; @@ -123,30 +127,39 @@ typedef enum e_FmPortExceptions { *//***************************************************************************/ typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */ -#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Offline parsing only! Unsupported Format */ -#define FM_PORT_FRM_ERR_LENGTH 0x02000000 /**< Offline parsing only! Length Error */ -#define FM_PORT_FRM_ERR_DMA 0x01000000 /**< DMA Data error */ +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */ +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */ +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */ +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that + was chained to FM */ + +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */ +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */ + +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */ + #ifdef FM_CAPWAP_SUPPORT -#define FM_PORT_FRM_ERR_NON_FM 0x00400000 /**< non Frame-Manager error; probably come from SEC that - was chained to FM */ +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE #endif /* FM_CAPWAP_SUPPORT */ -#define FM_PORT_FRM_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity - error (SGMII and TBI modes), FIFO parity error. PHY - Sequence error, PHY error control character detected. */ -#define FM_PORT_FRM_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */ -#define FM_PORT_FRM_ERR_CLS_DISCARD 0x00020000 /**< classification discard */ -#define FM_PORT_FRM_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */ -#define FM_PORT_FRM_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */ -#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */ -#define FM_PORT_FRM_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */ -#define FM_PORT_FRM_ERR_COLOR_RED 0x00000800 /**< Frame color is red */ -#define FM_PORT_FRM_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */ -#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */ -#define FM_PORT_FRM_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */ -#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */ -#define FM_PORT_FRM_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */ -#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */ -#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */ + +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity + error (SGMII and TBI modes), FIFO parity error. PHY + Sequence error, PHY error control character detected. */ +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */ +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */ +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */ +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */ +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */ +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */ +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */ +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */ +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */ +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */ +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */ +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */ +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */ +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */ /* @} */ @@ -210,52 +223,30 @@ typedef void (t_FmPortImTxConfCallback) (t_Handle h_App, t_Handle h_BufContext); /**************************************************************************//** - @Description A structure of information about each of the external - buffer pools used by the port, -*//***************************************************************************/ -typedef struct t_FmPortExtPoolParams { - uint8_t id; /**< External buffer pool id */ - uint16_t size; /**< External buffer pool buffer size */ -} t_FmPortExtPoolParams; - -/**************************************************************************//** - @Description A structure for informing the driver about the external - buffer pools allocated in the BM and used by this port. -*//***************************************************************************/ -typedef struct t_FmPortExtPools { - uint8_t numOfPoolsUsed; /**< Number of pools use by this port */ - t_FmPortExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS]; - /**< Parameters for each port */ -} t_FmPortExtPools; - -/**************************************************************************//** - @Description structure for additional Rx port parameters + @Description A structure for additional Rx port parameters *//***************************************************************************/ typedef struct t_FmPortRxParams { uint32_t errFqid; /**< Error Queue Id. */ uint32_t dfltFqid; /**< Default Queue Id. */ uint16_t liodnOffset; /**< Port's LIODN offset. */ - t_FmPortExtPools extBufPools; /**< Which external buffer pools are used + t_FmExtPools extBufPools; /**< Which external buffer pools are used (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */ } t_FmPortRxParams; /**************************************************************************//** - @Description structure for additional non-Rx port parameters + @Description A structure for additional non-Rx port parameters *//***************************************************************************/ typedef struct t_FmPortNonRxParams { uint32_t errFqid; /**< Error Queue Id. */ - uint32_t dfltFqid; /**< For Tx and HC - Default Confirmation queue, + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue, 0 means no Tx confirmation for processed - frames. For OP - default Rx queue. */ + frames. For OP port - default Rx queue. */ uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used by the FM for dequeue. */ -#ifdef FM_OP_PARTITION_ERRATA_FMANx8 - uint16_t opLiodnOffset; /**< For Offline Parsing ports only. Port's LIODN offset. */ -#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */ } t_FmPortNonRxParams; /**************************************************************************//** - @Description structure for additional Rx port parameters + @Description A structure for additional Rx port parameters *//***************************************************************************/ typedef struct t_FmPortImRxTxParams { t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */ @@ -268,7 +259,7 @@ typedef struct t_FmPortImRxTxParams { } t_FmPortImRxTxParams; /**************************************************************************//** - @Description Union for additional parameters depending on port type + @Description A union for additional parameters depending on port type *//***************************************************************************/ typedef union u_FmPortSpecificParams { t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */ @@ -277,13 +268,17 @@ typedef union u_FmPortSpecificParams { } u_FmPortSpecificParams; /**************************************************************************//** - @Description structure representing FM initialization parameters + @Description A structure representing FM initialization parameters *//***************************************************************************/ typedef struct t_FmPortParams { uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/ t_Handle h_Fm; /**< A handle to the FM object this port related to */ e_FmPortType portType; /**< Port type */ - uint8_t portId; /**< Port Id - relative to type */ + uint8_t portId; /**< Port Id - relative to type; + NOTE: When configuring Offline Parsing port for + FMANv3 devices (DPAA_VERSION 11 and higher), + it is highly recommended NOT to use portId=0 due to lack + of HW resources on portId=0. */ bool independentModeEnable; /**< This port is Independent-Mode - Used for Rx/Tx ports only! */ uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be @@ -291,7 +286,7 @@ typedef struct t_FmPortParams { u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port type. */ - t_FmPortExceptionCallback *f_Exception; /**< Callback routine to be called of PCD exception */ + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */ t_Handle h_App; /**< A handle to an application layer object; This handle will be passed by the driver upon calling the above callbacks */ } t_FmPortParams; @@ -300,7 +295,7 @@ typedef struct t_FmPortParams { /**************************************************************************//** @Function FM_PORT_Config - @Description Creates descriptor for the FM PORT module. + @Description Creates a descriptor for the FM PORT module. The routine returns a handle (descriptor) to the FM PORT object. This descriptor must be passed as first parameter to all other @@ -318,7 +313,8 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams); /**************************************************************************//** @Function FM_PORT_Init - @Description Initializes the FM PORT module + @Description Initializes the FM PORT module by defining the software structure + and configuring the hardware registers. @Param[in] h_FmPort - FM PORT module descriptor @@ -360,7 +356,6 @@ typedef enum e_FmPortDeqType { and override Intra-Class Scheduling */ } e_FmPortDeqType; -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT /**************************************************************************//** @Description enum for defining QM frame dequeue *//***************************************************************************/ @@ -373,26 +368,6 @@ typedef enum e_FmPortDeqPrefetchOption { no dedicated portId tnums are waiting. */ } e_FmPortDeqPrefetchOption; -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ - -/**************************************************************************//** - @Description enum for defining port DMA swap mode -*//***************************************************************************/ -typedef enum e_FmPortDmaSwap { - e_FM_PORT_DMA_NO_SWP, /**< No swap, transfer data as is.*/ - e_FM_PORT_DMA_SWP_PPC_LE, /**< The transferred data should be swapped - in PowerPc Little Endian mode. */ - e_FM_PORT_DMA_SWP_BE /**< The transferred data should be swapped - in Big Endian mode */ -} e_FmPortDmaSwap; - -/**************************************************************************//** - @Description enum for defining port DMA cache attributes -*//***************************************************************************/ -typedef enum e_FmPortDmaCache { - e_FM_PORT_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */ - e_FM_PORT_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */ -} e_FmPortDmaCache; /**************************************************************************//** @Description enum for defining port default color @@ -405,7 +380,7 @@ typedef enum e_FmPortColor { } e_FmPortColor; /**************************************************************************//** - @Description struct for defining Dual Tx rate limiting scale + @Description A structure for defining Dual Tx rate limiting scale *//***************************************************************************/ typedef enum e_FmPortDualRateLimiterScaleDown { e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */ @@ -416,7 +391,7 @@ typedef enum e_FmPortDualRateLimiterScaleDown { /**************************************************************************//** - @Description struct for defining FM port resources + @Description A structure for defining FM port resources *//***************************************************************************/ typedef struct t_FmPortRsrc { uint32_t num; /**< Committed required resource */ @@ -424,50 +399,32 @@ typedef struct t_FmPortRsrc { } t_FmPortRsrc; /**************************************************************************//** - @Description struct for defining pool depletion criteria -*//***************************************************************************/ -typedef struct t_FmPortBufPoolDepletion { - bool numberOfPoolsModeEnable; /**< select mode in which pause frames will be sent after - a number of pools are depleted */ - uint8_t numOfPools; /**< the minimum number of depleted pools that will - invoke pause frames transmission. */ - bool poolsToConsider[BM_MAX_NUM_OF_POOLS]; - /**< For each pool, TRUE if it should be considered for - depletion (Note - this pool must be used by this port!) */ - bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after - a single of pools are depleted */ - bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS]; - /**< For each pool, TRUE if it should be considered for - depletion (Note - this pool must be used by this port!) */ -} t_FmPortBufPoolDepletion; - -/**************************************************************************//** - @Description struct for defining observed pool depletion + @Description A structure for defining observed pool depletion *//***************************************************************************/ typedef struct t_FmPortObservedBufPoolDepletion { - t_FmPortBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */ - t_FmPortExtPools poolsParams; /**< Which external buffer pools are observed - (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS), - and their sizes. */ + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */ + t_FmExtPools poolsParams; /**< Which external buffer pools are observed + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS), + and their sizes. */ } t_FmPortObservedBufPoolDepletion; /**************************************************************************//** - @Description struct for defining Tx rate limiting + @Description A structure for defining Tx rate limiting *//***************************************************************************/ typedef struct t_FmPortRateLimit { - uint16_t maxBurstSize; /**< in kBytes for Tx ports, in frames - for offline parsing ports. (note that + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames + for OP ports. (note that for early chips burst size is rounded up to a multiply of 1000 frames).*/ uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for - offline parsing ports. Rate limit refers to + OP ports. Rate limit refers to data rate (rather than line rate). */ - e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For offline parsing ports only. Not-valid + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid for some earlier chip revisions */ } t_FmPortRateLimit; /**************************************************************************//** - @Description struct for defining define the parameters of + @Description A structure for defining the parameters of the Rx port performance counters *//***************************************************************************/ typedef struct t_FmPortPerformanceCnt { @@ -478,49 +435,116 @@ typedef struct t_FmPortPerformanceCnt { uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */ } t_FmPortPerformanceCnt; -/**************************************************************************//** - @Description struct for defining buffer content. -*//***************************************************************************/ -typedef struct t_FmPortBufferPrefixContent { - uint16_t privDataSize; /**< Number of bytes to be left at the beginning - of the external buffer */ - bool passPrsResult; /**< TRUE to pass the parse result to/from the FM */ - bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM */ - bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM */ - bool passAllOtherPCDInfo;/**< Add all other Internal-Context information: - AD, hash-result, key, etc. */ - uint16_t dataAlign; /**< 0 to use driver's default alignment, other value - for selecting a data alignment (must be a - power of 2) */ -#ifdef DEBUG - bool passDebugInfo; /**< Debug-information */ -#endif /* DEBUG */ -#ifdef FM_CAPWAP_SUPPORT - uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size) */ -#endif /* FM_CAPWAP_SUPPORT */ -} t_FmPortBufferPrefixContent; /**************************************************************************//** - @Description struct for defining backup Bm Pools. + @Description A structure for defining the sizes of the Deep Sleep + the Auto Response tables *//***************************************************************************/ -typedef struct t_FmPortBackupBmPools { - uint8_t numOfBackupPools; /**< Number of BM backup pools - - must be smaller than the total number of - pools defined for the specified port.*/ - uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS]; - /**< numOfBackupPools pool id's, specifying which - pools should be used only as backup. Pool - id's specified here must be a subset of the - pools used by the specified port.*/ -} t_FmPortBackupBmPools; +typedef struct t_FmPortDsarTablesSizes +{ + uint16_t maxNumOfArpEntries; + uint16_t maxNumOfEchoIpv4Entries; + uint16_t maxNumOfNdpEntries; + uint16_t maxNumOfEchoIpv6Entries; + uint16_t maxNumOfSnmpIPV4Entries; + uint16_t maxNumOfSnmpIPV6Entries; + uint16_t maxNumOfSnmpOidEntries; + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */ + uint16_t maxNumOfIpProtFiltering; + uint16_t maxNumOfTcpPortFiltering; + uint16_t maxNumOfUdpPortFiltering; +} t_FmPortDsarTablesSizes; + + +/**************************************************************************//** + @Function FM_PORT_ConfigDsarSupport + + @Description This function will allocate the amount of MURAM needed for + this max number of entries for Deep Sleep Auto Response. + it will calculate all needed MURAM for autoresponse including + necesary common stuff. + + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] params A pointer to a structure containing the maximum + sizes of the auto response tables + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params); + +/**************************************************************************//** + @Function FM_PORT_ConfigNumOfOpenDmas + + @Description Calling this routine changes the max number of open DMA's + available for this port. It changes this parameter in the + internal driver data base from its default configuration + [OP: 1] + [1G-RX, 1G-TX: 1 (+1)] + [10G-RX, 10G-TX: 8 (+8)] + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_OpenDmas A pointer to a structure of parameters defining + the open DMA allocation. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas); + +/**************************************************************************//** + @Function FM_PORT_ConfigNumOfTasks + + @Description Calling this routine changes the max number of tasks + available for this port. It changes this parameter in the + internal driver data base from its default configuration + [OP: 1] + [1G-RX, 1G-TX: 3 (+2)] + [10G-RX, 10G-TX: 16 (+8)] + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining + the tasks allocation. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks); + +/**************************************************************************//** + @Function FM_PORT_ConfigSizeOfFifo + + @Description Calling this routine changes the max FIFO size configured for this port. + + This function changes the internal driver data base from its + default configuration. Please refer to the driver's User Guide for + information on default FIFO sizes in the various devices. + [OP: 2KB] + [1G-RX, 1G-TX: 11KB] + [10G-RX, 10G-TX: 12KB] + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining + the FIFO allocation. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); /**************************************************************************//** @Function FM_PORT_ConfigDeqHighPriority @Description Calling this routine changes the dequeue priority in the internal driver data base from its default configuration - [TRUE] + 1G: [DEFAULT_PORT_deqHighPriority_1G] + 10G: [DEFAULT_PORT_deqHighPriority_10G] May be used for Non-Rx ports only @@ -538,7 +562,7 @@ t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri); @Description Calling this routine changes the dequeue type parameter in the internal driver data base from its default configuration - [e_FM_PORT_DEQ_TYPE1]. + [DEFAULT_PORT_deqType]. May be used for Non-Rx ports only @@ -551,13 +575,12 @@ t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri); *//***************************************************************************/ t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType); -#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT /**************************************************************************//** @Function FM_PORT_ConfigDeqPrefetchOption @Description Calling this routine changes the dequeue prefetch option parameter in the internal driver data base from its default configuration - [e_FM_PORT_DEQ_FULL_PREFETCH] + [DEFAULT_PORT_deqPrefetchOption] Note: Available for some chips only May be used for Non-Rx ports only @@ -570,13 +593,14 @@ t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType); @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption); -#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ /**************************************************************************//** @Function FM_PORT_ConfigDeqByteCnt @Description Calling this routine changes the dequeue byte count parameter in - the internal driver data base from its default configuration [2000]. + the internal driver data base from its default configuration + 1G:[DEFAULT_PORT_deqByteCnt_1G]. + 10G:[DEFAULT_PORT_deqByteCnt_10G]. May be used for Non-Rx ports only @@ -589,109 +613,6 @@ t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOp *//***************************************************************************/ t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt); -/**************************************************************************//** - @Function FM_PORT_ConfigTxFifoMinFillLevel - - @Description Calling this routine changes the fifo minimum - fill level parameter in the internal driver data base - from its default configuration [0] - - May be used for Tx ports only - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] minFillLevel New value - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel); - -/**************************************************************************//** - @Function FM_PORT_ConfigTxFifoDeqPipelineDepth - - @Description Calling this routine changes the fifo dequeue - pipeline depth parameter in the internal driver data base - - from its default configuration: 1G ports: [2], - 10G port: [8] - - May be used for Tx ports only - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] deqPipelineDepth New value - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_ConfigTxFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth); - -/**************************************************************************//** - @Function FM_PORT_ConfigTxFifoLowComfLevel - - @Description Calling this routine changes the fifo low comfort level - parameter in internal driver data base - from its default configuration [5] - - May be used for Tx ports only - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] fifoLowComfLevel New value - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel); - -/**************************************************************************//** - @Function FM_PORT_ConfigRxFifoThreshold - - @Description Calling this routine changes the threshold of the FIFO - fill level parameter in the internal driver data base - from its default configuration [BMI_MAX_FIFO_SIZE] - - If the total number of buffers which are - currently in use and associated with the - specific RX port exceed this threshold, the - BMI will signal the MAC to send a pause frame - over the link. - - May be used for Rx ports only - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] fifoThreshold New value - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold); - -/**************************************************************************//** - @Function FM_PORT_ConfigRxFifoPriElevationLevel - - @Description Calling this routine changes the priority elevation level - parameter in the internal driver data base from its default - configuration [BMI_MAX_FIFO_SIZE] - - If the total number of buffers which are currently in use and - associated with the specific RX port exceed the amount specified - in priElevationLevel, BMI will signal the main FM's DMA to - elevate the FM priority on the system bus. - - May be used for Rx ports only - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] priElevationLevel New value - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel); - /**************************************************************************//** @Function FM_PORT_ConfigBufferPrefixContent @@ -705,14 +626,14 @@ t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priEle application buffer, and to offset. Calling this routine changes the buffer margins definitions in the internal driver data base from its default - configuration: Data size: [0] - Pass Parser result: [FALSE]. - Pass timestamp: [FALSE]. + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize] + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult]. + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp]. May be used for all ports @Param[in] h_FmPort A handle to a FM Port module. - @Param[in,out] p_FmPortBufferPrefixContent A structure of parameters describing the + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the structure of the buffer. Out parameter: Start margin - offset of data from start of external buffer. @@ -721,20 +642,20 @@ t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priEle @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, t_FmPortBufferPrefixContent *p_FmPortBufferPrefixContent); - +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, + t_FmBufferPrefixContent *p_FmBufferPrefixContent); /**************************************************************************//** @Function FM_PORT_ConfigCheksumLastBytesIgnore @Description Calling this routine changes the number of checksum bytes to ignore parameter in the internal driver data base from its default configuration - [0] + [DEFAULT_PORT_cheksumLastBytesIgnore] May be used by Tx & Rx ports only @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] cheksumLastBytesIgnore New value + @Param[in] cheksumLastBytesIgnore New value @Return E_OK on success; Error code otherwise. @@ -747,7 +668,7 @@ t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumL @Description Calling this routine changes the number of bytes to cut from a frame's end parameter in the internal driver data base - from its default configuration [4] + from its default configuration [DEFAULT_PORT_cutBytesFromEnd] Note that if the result of (frame length before chop - cutBytesFromEnd) is less than 14 bytes, the chop operation is not executed. @@ -778,7 +699,7 @@ t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion *p_BufPoolDepletion); +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion); /**************************************************************************//** @Function FM_PORT_ConfigObservedPoolDepletion @@ -790,39 +711,38 @@ t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion Note: Available for some chips only - May be used for Offline Parsing ports only + May be used for OP ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion. - @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion); +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion); /**************************************************************************//** @Function FM_PORT_ConfigExtBufPools - @Description This routine should be called for offline parsing ports + @Description This routine should be called for OP ports that internally use BM buffer pools. In such cases, e.g. for fragmentation and re-assembly, the FM needs new BM buffers. By calling this routine the user specifies the BM buffer pools that should be used. Note: Available for some chips only - May be used for Offline Parsing ports only + May be used for OP ports only @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_FmPortExtPools A structure of parameters for the external pools. - + @Param[in] p_FmExtPools A structure of parameters for the external pools. @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortExtPools); +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools); /**************************************************************************//** @Function FM_PORT_ConfigBackupPools @@ -842,19 +762,19 @@ t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortE @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmPortBackupBmPools *p_FmPortBackupBmPools); +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools); /**************************************************************************//** @Function FM_PORT_ConfigFrmDiscardOverride @Description Calling this routine changes the error frames destination parameter in the internal driver data base from its default configuration: - override = [FALSE] + override = [DEFAULT_PORT_frmDiscardOverride] - May be used for Rx and offline parsing ports only + May be used for Rx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] override TRUE to override dicarding of error frames and + @Param[in] override TRUE to override discarding of error frames and enqueueing them to error queue. @Return E_OK on success; Error code otherwise. @@ -868,14 +788,13 @@ t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override); @Description Calling this routine changes the behaviour on error parameter in the internal driver data base from its default configuration: - [FM_PORT_FRM_ERR_CLS_DISCARD]. + [DEFAULT_PORT_errorsToDiscard]. If a requested error was previously defined as "ErrorsToEnqueue" it's definition will change and the frame will be discarded. Errors that were not defined either as "ErrorsToEnqueue" nor as "ErrorsToDiscard", will be forwarded to CPU. - - May be used for Rx and offline parsing ports only + May be used for Rx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] errs A list of errors to discard @@ -891,7 +810,7 @@ t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t @Description Calling this routine changes the DMA swap data aparameter in the internal driver data base from its default - configuration [e_FM_PORT_DMA_NO_SWP] + configuration [DEFAULT_PORT_dmaSwapData] May be used for all port types @@ -902,14 +821,14 @@ t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData); +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData); /**************************************************************************//** @Function FM_PORT_ConfigDmaIcCacheAttr @Description Calling this routine changes the internal context cache attribute parameter in the internal driver data base - from its default configuration [e_FM_PORT_DMA_NO_STASH] + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr] May be used for all port types @@ -920,14 +839,14 @@ t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData); @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intContextCacheAttr); +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr); /**************************************************************************//** @Function FM_PORT_ConfigDmaHdrAttr @Description Calling this routine changes the header cache attribute parameter in the internal driver data base - from its default configuration [e_FM_PORT_DMA_NO_STASH] + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr] May be used for all port types @@ -938,14 +857,14 @@ t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intCont @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCacheAttr); +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr); /**************************************************************************//** @Function FM_PORT_ConfigDmaScatterGatherAttr @Description Calling this routine changes the scatter gather cache attribute parameter in the internal driver data base - from its default configuration [e_FM_PORT_DMA_NO_STASH] + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr] May be used for all port types @@ -956,16 +875,23 @@ t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCache @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). *//***************************************************************************/ -t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache scatterGatherCacheAttr); +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr); /**************************************************************************//** @Function FM_PORT_ConfigDmaWriteOptimize @Description Calling this routine changes the write optimization parameter in the internal driver data base - from its default configuration: optimize = [TRUE] + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize]. + Note: - May be used for non-Tx port types + 1. For head optimization, data alignment must be >= 16 (supported by default). + + 3. For tail optimization, note that the optimization is performed by extending the write transaction + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write + is extended to be on 16/64 bytes aligned block (chip dependent). + + Relevant for non-Tx port types @Param[in] h_FmPort A handle to a FM Port module. @Param[in] optimize TRUE to enable optimization, FALSE for normal operation @@ -976,12 +902,28 @@ t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache s *//***************************************************************************/ t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize); +/**************************************************************************//** + @Function FM_PORT_ConfigNoScatherGather + + @Description Calling this routine changes the noScatherGather parameter in internal driver data base + from its default configuration. + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer, + FALSE - frame can be stored in scatter gather (S/G) format). + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather); + /**************************************************************************//** @Function FM_PORT_ConfigDfltColor @Description Calling this routine changes the internal default color parameter in the internal driver data base - from its default configuration [e_FM_PORT_COLOR_GREEN] + from its default configuration [DEFAULT_PORT_color] May be used for all port types @@ -999,7 +941,7 @@ t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color); @Description Calling this routine changes the synchronization attribute parameter in the internal driver data base from its default configuration: - syncReq = [TRUE] + syncReq = [DEFAULT_PORT_syncReq] May be used for all port types @@ -1015,16 +957,16 @@ t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq); /**************************************************************************//** @Function FM_PORT_ConfigForwardReuseIntContext - @Description This routine is relevant for Rx ports that are routed to offline - parsing. It changes the internal context reuse option - in the internal driver data base from its default configuration: - reuse = [FALSE] + @Description This routine is relevant for Rx ports that are routed to OP port. + It changes the internal context reuse option in the internal + driver data base from its default configuration: + reuse = [DEFAULT_PORT_forwardIntContextReuse] May be used for Rx ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] reuse TRUE to reuse internal context on frames - forwarded to offline parsing. + forwarded to OP port. @Return E_OK on success; Error code otherwise. @@ -1084,7 +1026,7 @@ t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal); @Function FM_PORT_ConfigIMRxBdRingLength @Description Changes the receive BD ring length from its default - configuration:[128] + configuration:[DEFAULT_PORT_rxBdRingLength] @Param[in] h_FmPort A handle to a FM Port module. @Param[in] newVal The desired BD ring length. @@ -1100,7 +1042,7 @@ t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal); @Function FM_PORT_ConfigIMTxBdRingLength @Description Changes the transmit BD ring length from its default - configuration:[16] + configuration:[DEFAULT_PORT_txBdRingLength] @Param[in] h_FmPort A handle to a FM Port module. @Param[in] newVal The desired BD ring length. @@ -1119,7 +1061,7 @@ t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal); data structures (e.g. BD rings). Calling this routine changes the internal driver data base from its default configuration - [0 , MEMORY_ATTR_CACHEABLE]. + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr]. @Param[in] h_FmPort A handle to a FM Port module. @Param[in] memId Memory partition ID. @@ -1145,6 +1087,173 @@ t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort, *//***************************************************************************/ t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort); +/**************************************************************************//** + @Function FM_PORT_ConfigMaxFrameLength + + @Description Changes the definition of the max size of frame that should be + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength]. + This parameter is used for confirmation of the minimum Fifo + size calculations and only for Tx ports or ports working in + independent mode. This should be larger than the maximum possible + MTU that will be used for this port (i.e. its MAC). + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] length Max size of frame + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). + This routine is to be used only if Independent-Mode is enabled. +*//***************************************************************************/ +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length); + +/**************************************************************************//* + @Function FM_PORT_ConfigTxFifoMinFillLevel + + @Description Calling this routine changes the fifo minimum + fill level parameter in the internal driver data base + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel] + + May be used for Tx ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] minFillLevel New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel); + +/**************************************************************************//* + @Function FM_PORT_ConfigFifoDeqPipelineDepth + + @Description Calling this routine changes the fifo dequeue + pipeline depth parameter in the internal driver data base + + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G], + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G], + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH] + + May be used for Tx/OP ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] deqPipelineDepth New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth); + +/**************************************************************************//* + @Function FM_PORT_ConfigTxFifoLowComfLevel + + @Description Calling this routine changes the fifo low comfort level + parameter in internal driver data base + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel] + + May be used for Tx ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] fifoLowComfLevel New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel); + +/**************************************************************************//* + @Function FM_PORT_ConfigRxFifoThreshold + + @Description Calling this routine changes the threshold of the FIFO + fill level parameter in the internal driver data base + from its default configuration [DEFAULT_PORT_rxFifoThreshold] + + If the total number of buffers which are + currently in use and associated with the + specific RX port exceed this threshold, the + BMI will signal the MAC to send a pause frame + over the link. + + May be used for Rx ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] fifoThreshold New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold); + +/**************************************************************************//* + @Function FM_PORT_ConfigRxFifoPriElevationLevel + + @Description Calling this routine changes the priority elevation level + parameter in the internal driver data base from its default + configuration [DEFAULT_PORT_rxFifoPriElevationLevel] + + If the total number of buffers which are currently in use and + associated with the specific RX port exceed the amount specified + in priElevationLevel, BMI will signal the main FM's DMA to + elevate the FM priority on the system bus. + + May be used for Rx ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] priElevationLevel New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel); + +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 +/**************************************************************************//* + @Function FM_PORT_ConfigBCBWorkaround + + @Description Configures BCB errata workaround. + + When BCB errata is applicable, the workaround is always + performed by FM Controller. Thus, this functions doesn't + actually enable errata workaround but rather allows driver + to perform adjustments required due to errata workaround + execution in FM controller. + + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be + set by FM_PORT_SetErrorsRoute() function. + + @Param[in] h_FmPort A handle to a FM Port module. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort); +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ + +#if (DPAA_VERSION >= 11) +/**************************************************************************//* + @Function FM_PORT_ConfigInternalBuffOffset + + @Description Configures internal buffer offset. + + May be used for Rx and OP ports only + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] val New value + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val); +#endif /* (DPAA_VERSION >= 11) */ + /** @} */ /* end of FM_PORT_advanced_init_grp group */ /** @} */ /* end of FM_PORT_init_grp group */ @@ -1172,18 +1281,39 @@ typedef enum e_FmPortCounters { e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */ e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */ e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */ - e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx only statistics counter */ e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */ e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */ + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */ + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */ e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */ e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */ e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */ - e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI counter */ - e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI counter */ + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */ + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */ e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */ e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */ } e_FmPortCounters; +typedef struct t_FmPortBmiStats { + uint32_t cntCycle; + uint32_t cntTaskUtil; + uint32_t cntQueueUtil; + uint32_t cntDmaUtil; + uint32_t cntFifoUtil; + uint32_t cntRxPauseActivation; + uint32_t cntFrame; + uint32_t cntDiscardFrame; + uint32_t cntDeallocBuf; + uint32_t cntRxBadFrame; + uint32_t cntRxLargeFrame; + uint32_t cntRxFilterFrame; + uint32_t cntRxListDmaErr; + uint32_t cntRxOutOfBuffersDiscard; + uint32_t cntWredDiscard; + uint32_t cntLengthErr; + uint32_t cntUnsupportedFormat; +} t_FmPortBmiStats; + /**************************************************************************//** @Description Structure for Port id parameters. Fields commented 'IN' are passed by the port module to be used @@ -1191,14 +1321,284 @@ typedef enum e_FmPortCounters { Fields commented 'OUT' will be filled by FM before returning to port. *//***************************************************************************/ typedef struct t_FmPortCongestionGrps { - uint16_t numOfCongestionGrpsToConsider; /**< The number of required congestion groups + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs to define the size of the following array */ uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS]; - /**< An array of 'numOfCongestionGrpsToConsider' - describing the groups */ + /**< An array of CG indexes; + Note that the size of the array should be + 'numOfCongestionGrpsToConsider'. */ +#if (DPAA_VERSION >= 11) + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES]; + /**< a matrix that represents the map between the CG ids + defined in 'congestionGrpsToConsider' to the priorties + mapping array. */ +#endif /* (DPAA_VERSION >= 11) */ } t_FmPortCongestionGrps; +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response ARP Entry +*//***************************************************************************/ +typedef struct t_FmPortDsarArpEntry +{ + uint32_t ipAddress; + uint8_t mac[6]; + bool isVlan; + uint16_t vid; +} t_FmPortDsarArpEntry; +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response ARP info +*//***************************************************************************/ +typedef struct t_FmPortDsarArpInfo +{ + uint8_t tableSize; + t_FmPortDsarArpEntry *p_AutoResTable; + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */ +} t_FmPortDsarArpInfo; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response NDP Entry +*//***************************************************************************/ +typedef struct t_FmPortDsarNdpEntry +{ + uint32_t ipAddress[4]; + uint8_t mac[6]; + bool isVlan; + uint16_t vid; +} t_FmPortDsarNdpEntry; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response NDP info +*//***************************************************************************/ +typedef struct t_FmPortDsarNdpInfo +{ + uint32_t multicastGroup; + + uint8_t tableSizeAssigned; + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses. + Note that all IP adresses must be from the same multicast group. + This will be checked and if not operation will fail. */ + uint8_t tableSizeTmp; + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses. + Note that all temp IP adresses must be from the same multicast group. + This will be checked and if not operation will fail. */ + + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */ + +} t_FmPortDsarNdpInfo; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response ICMPV4 info +*//***************************************************************************/ +typedef struct t_FmPortDsarEchoIpv4Info +{ + uint8_t tableSize; + t_FmPortDsarArpEntry *p_AutoResTable; +} t_FmPortDsarEchoIpv4Info; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response ICMPV6 info +*//***************************************************************************/ +typedef struct t_FmPortDsarEchoIpv6Info +{ + uint8_t tableSize; + t_FmPortDsarNdpEntry *p_AutoResTable; +} t_FmPortDsarEchoIpv6Info; + +/**************************************************************************//** +@Description Deep Sleep Auto Response SNMP OIDs table entry + +*//***************************************************************************/ +typedef struct { + uint16_t oidSize; + uint8_t *oidVal; /* only the oid string */ + uint16_t resSize; + uint8_t *resVal; /* resVal will be the entire reply, + i.e. "Type|Length|Value" */ +} t_FmPortDsarOidsEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef struct +{ + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ + bool isVlan; + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ +} t_FmPortDsarSnmpIpv4AddrTblEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry + Refer to the FMan Controller spec for more details. +*//***************************************************************************/ +typedef struct +{ + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */ + bool isVlan; + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ +} t_FmPortDsarSnmpIpv6AddrTblEntry; + +/**************************************************************************//** + @Description Deep Sleep Auto Response SNMP Descriptor + +*//***************************************************************************/ +typedef struct +{ + uint16_t control; /**< Control bits [0-15]. */ + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */ + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */ + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */ + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */ + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */ + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */ + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */ + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */ + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */ +} t_FmPortDsarSnmpInfo; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response filtering Entry +*//***************************************************************************/ +typedef struct t_FmPortDsarFilteringEntry +{ + uint16_t srcPort; + uint16_t dstPort; + uint16_t srcPortMask; + uint16_t dstPortMask; +} t_FmPortDsarFilteringEntry; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response filtering info +*//***************************************************************************/ +typedef struct t_FmPortDsarFilteringInfo +{ + /* IP protocol filtering parameters */ + uint8_t ipProtTableSize; + uint8_t *p_IpProtTablePtr; + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, + hit will pass the packet to UDP/TCP filters if needed and if not + to the classification tree. If the classification tree will pass + the packet to a queue it will cause a wake interupt. + When FALSE it the other way around. */ + /* UDP port filtering parameters */ + uint8_t udpPortsTableSize; + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr; + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, + hit will pass the packet to classification tree. + If the classification tree will pass the packet to a queue it + will cause a wake interupt. + When FALSE it the other way around. */ + /* TCP port filtering parameters */ + uint16_t tcpFlagsMask; + uint8_t tcpPortsTableSize; + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr; + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, + hit will pass the packet to classification tree. + If the classification tree will pass the packet to a queue it + will cause a wake interupt. + When FALSE it the other way around. */ +} t_FmPortDsarFilteringInfo; + +/**************************************************************************//** + @Description Structure for Deep Sleep Auto Response parameters +*//***************************************************************************/ +typedef struct t_FmPortDsarParams +{ + t_Handle h_FmPortTx; + t_FmPortDsarArpInfo *p_AutoResArpInfo; + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info; + t_FmPortDsarNdpInfo *p_AutoResNdpInfo; + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info; + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo; + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo; +} t_FmPortDsarParams; + +/**************************************************************************//** + @Function FM_PORT_EnterDsar + + @Description Enter Deep Sleep Auto Response mode. + This function write the apropriate values to in the relevant + tables in the MURAM. + + @Param[in] h_FmPortRx - FM PORT module descriptor + @Param[in] params - Auto Response parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params); + +/**************************************************************************//** + @Function FM_PORT_EnterDsarFinal + + @Description Enter Deep Sleep Auto Response mode. + This function sets the Tx port in independent mode as needed + and redirect the receive flow to go through the + Dsar Fman-ctrl code + + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort); + +/**************************************************************************//** + @Function FM_PORT_ExitDsar + + @Description Exit Deep Sleep Auto Response mode. + This function reverse the AR mode and put the ports back into + their original wake mode + + @Param[in] h_FmPortRx - FM PORT Rx module descriptor + @Param[in] h_FmPortTx - FM PORT Tx module descriptor + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_EnterDsar(). +*//***************************************************************************/ +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx); + +/**************************************************************************//** + @Function FM_PORT_IsInDsar + + @Description This function returns TRUE if the port was set as Auto Response + and FALSE if not. Once Exit AR mode it will return FALSE as well + until re-enabled once more. + + @Param[in] h_FmPort - FM PORT module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +bool FM_PORT_IsInDsar(t_Handle h_FmPort); + +typedef struct t_FmPortDsarStats +{ + uint32_t arpArCnt; + uint32_t echoIcmpv4ArCnt; + uint32_t ndpArCnt; + uint32_t echoIcmpv6ArCnt; + uint32_t snmpGetCnt; + uint32_t snmpGetNextCnt; +} t_FmPortDsarStats; + +/**************************************************************************//** + @Function FM_PORT_GetDsarStats + + @Description Return statistics for Deep Sleep Auto Response + + @Param[in] h_FmPortRx - FM PORT module descriptor + @Param[out] stats - structure containing the statistics counters + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats); #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) /**************************************************************************//** @@ -1237,7 +1637,7 @@ uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort); @Description Returns the Internal Context offset from the beginning of the data buffer @Param[in] h_FmPort - FM PORT module descriptor - @Param[in] p_Data - A pointer to the data buffer. + @Param[in] p_Data - A pointer to the data buffer. @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not configured for this port. @@ -1246,23 +1646,6 @@ uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort); *//***************************************************************************/ uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data); -#ifdef DEBUG -/**************************************************************************//** - @Function FM_PORT_GetBufferDebugInfo - - @Description Returns the debug info offset from the beginning of the data buffer - - @Param[in] h_FmPort - FM PORT module descriptor - @Param[in] p_Data - A pointer to the data buffer. - - @Return Debug info pointer on success, NULL if 'passDebugInfo' was not - configured for this port. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -uint8_t * FM_PORT_GetBufferDebugInfo(t_Handle h_FmPort, char *p_Data); -#endif /* DEBUG */ - /**************************************************************************//** @Function FM_PORT_GetBufferPrsResult @@ -1358,7 +1741,7 @@ t_Error FM_PORT_Enable(t_Handle h_FmPort); The selected rate limit specified here would be rounded DOWN to the nearest 16M. - May be used for Tx and offline parsing ports only + May be used for Tx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] p_RateLimit A structure of rate limit parameters @@ -1366,6 +1749,8 @@ t_Error FM_PORT_Enable(t_Handle h_FmPort); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PORT_Init(). + If rate limit is set on a port that need to send PFC frames, + it might violate the stop transmit timing. *//***************************************************************************/ t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit); @@ -1375,7 +1760,7 @@ t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit); @Description Calling this routine disables and clears rate limit initialization. - May be used for Tx and offline parsing ports only + May be used for Tx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. @@ -1385,6 +1770,24 @@ t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit); *//***************************************************************************/ t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort); +/**************************************************************************//** + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ + + @Description Calling this routine maps each PFC received priority to the transmit WQ. + This WQ will be blocked upon receiving a PFC frame with this priority. + + May be used for Tx ports only. + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] prio PFC priority (0-7). + @Param[in] wq Work Queue (0-7). + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq); + /**************************************************************************//** @Function FM_PORT_SetStatisticsCounters @@ -1419,47 +1822,12 @@ t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable); *//***************************************************************************/ t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable); -/**************************************************************************//** - @Function FM_PORT_SetPerformanceCounters - - @Description Calling this routine enables/disables port's performance counters. - By default, counters are enabled. - - May be used for all port types - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] enable TRUE to enable, FALSE to disable. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable); - -/**************************************************************************//** - @Function FM_PORT_SetPerformanceCounters - - @Description Calling this routine defines port's performance - counters parameters. - - May be used for all port types - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance - counters parameters. - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt); - /**************************************************************************//** @Function FM_PORT_AnalyzePerformanceParams @Description User may call this routine to so the driver will analyze if the basic performance parameters are correct and also the driver may - suggest of improvments; The basic parameters are FIFO sizes, number + suggest of improvements; The basic parameters are FIFO sizes, number of DMAs and number of TNUMs for the port. May be used for all port types @@ -1472,58 +1840,6 @@ t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerforma *//***************************************************************************/ t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort); -/**************************************************************************//** - @Function FM_PORT_SetNumOfOpenDmas - - @Description Calling this routine updates the number of open DMA requested for - this port. - - - May be used for all port types. - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_NumOfOpenDmas A structure of resource requested parameters - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas); - -/**************************************************************************//** - @Function FM_PORT_SetNumOfTasks - - @Description Calling this routine updates the number of tasks requested for - this port. - - May be used for all port types. - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_NumOfTasks A structure of resource requested parameters - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks); - -/**************************************************************************//** - @Function FM_PORT_SetSizeOfFifo - - @Description Calling this routine updates the Fifo size resource requested for - this port. - - May be used for all port types - note that only Rx has 'extra' - fifo size. For other ports 'extra' field must be disabled. - - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_SizeOfFifo A structure of resource requested parameters - - @Return E_OK on success; Error code otherwise. - - @Cautions Allowed only following FM_PORT_Init(). -*//***************************************************************************/ -t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); /**************************************************************************//** @Function FM_PORT_SetAllocBufCounter @@ -1544,6 +1860,21 @@ t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); *//***************************************************************************/ t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable); +/**************************************************************************//** + @Function FM_PORT_GetBmiCounters + + @Description Read port's BMI stat counters and place them into + a designated structure of counters. + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[out] p_BmiStats counters structure + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats); + /**************************************************************************//** @Function FM_PORT_GetCounter @@ -1618,7 +1949,7 @@ t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32 Each call to this routine may add one or more congestion groups to be considered relevant to this port. - May be used for Rx, or RX+OP ports only (depending on chip) + May be used for Rx, or RX+OP ports only (depending on chip) @Param[in] h_FmPort A handle to a FM Port module. @Param[in] p_CongestionGrps A pointer to an array of congestion groups @@ -1670,6 +2001,8 @@ bool FM_PORT_IsStalled(t_Handle h_FmPort); @Description This routine may be called in case the port was stalled and may now be released. + Note that this routine is available only on older FMan revisions + (FMan v2, DPAA v1.0 only). @Param[in] h_FmPort A handle to a FM Port module. @@ -1707,7 +2040,7 @@ t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum); Errors that were configured to be discarded (at initialization) may not be selected here. - May be used for Rx and offline parsing ports only + May be used for Rx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] errs A list of errors to enqueue to error queue @@ -1722,7 +2055,6 @@ t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs); @Function FM_PORT_SetIMExceptions @Description Calling this routine enables/disables FM PORT interrupts. - Note: Not available for guest partition. @Param[in] h_FmPort FM PORT module descriptor. @Param[in] exception The exception to be selected. @@ -1731,10 +2063,45 @@ t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs); @Return E_OK on success; Error code otherwise. @Cautions Allowed only following FM_PORT_Init(). + This routine should NOT be called from guest-partition + (i.e. guestId != NCSW_MASTER_ID) *//***************************************************************************/ t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable); +/**************************************************************************//* + @Function FM_PORT_SetPerformanceCounters + @Description Calling this routine enables/disables port's performance counters. + By default, counters are enabled. + + May be used for all port types + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] enable TRUE to enable, FALSE to disable. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable); + +/**************************************************************************//* + @Function FM_PORT_SetPerformanceCountersParams + + @Description Calling this routine defines port's performance + counters parameters. + + May be used for all port types + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance + counters parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(). +*//***************************************************************************/ +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt); /**************************************************************************//** @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit @@ -1752,9 +2119,9 @@ t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, *//***************************************************************************/ typedef struct t_FmPcdKgSchemeSelect { - bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV.*/ - t_Handle h_DirectScheme; /**< Relevant for 'direct'=TRUE only. - 'h_DirectScheme' selects the scheme after parser. */ + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */ + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser; + Relevant only when 'direct' is TRUE. */ } t_FmPcdKgSchemeSelect; /**************************************************************************//** @@ -1791,7 +2158,7 @@ typedef union u_FmPcdHdrPrsOpts { /* IPV6 */ struct{ - bool routingHdrDisable; /**< Disable routing header */ + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */ } ipv6PrsOptions; /* UDP */ @@ -1809,7 +2176,12 @@ typedef union u_FmPcdHdrPrsOpts { @Description A structure for defining each header for the parser *//***************************************************************************/ typedef struct t_FmPcdPrsAdditionalHdrParams { - e_NetHeaderType hdr; /**< Selected header */ + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE + to indicate that sw parser is to run first + (before HW parser, and independent of the + existence of any protocol), in this case, + swPrsEnable must be set, and all other + parameters are irrelevant. */ bool errDisable; /**< TRUE to disable error indication */ bool swPrsEnable; /**< Enable jump to SW parser when this header is recognized by the HW parser. */ @@ -1835,7 +2207,8 @@ typedef struct t_FmPortPcdPrsParams { uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */ e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */ bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics; - NOTE: this field is not valid when the FN is in "guest" mode. */ + NOTE: this field is not valid when the FM is in "guest" mode + and IPC is not available. */ uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get special parameters */ t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS]; @@ -1877,13 +2250,7 @@ typedef struct t_FmPortPcdKgParams { @Description struct for defining policer parameters *//***************************************************************************/ typedef struct t_FmPortPcdPlcrParams { - t_Handle h_Profile; /**< Selected profile handle; Relevant for one of - following cases: - e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or - e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected, - or if any flow uses a KG scheme were policer - profile is not generated - (bypassPlcrProfileGeneration selected) */ + t_Handle h_Profile; /**< Selected profile handle */ } t_FmPortPcdPlcrParams; /**************************************************************************//** @@ -1896,7 +2263,17 @@ typedef struct t_FmPortPcdParams { t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */ t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */ t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */ - t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port */ + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of + following cases: + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected, + or if any flow uses a KG scheme were policer + profile is not generated + ('bypassPlcrProfileGeneration selected'). */ + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */ +#if (DPAA_VERSION >= 11) + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */ +#endif /* (DPAA_VERSION >= 11) */ } t_FmPortPcdParams; /**************************************************************************//** @@ -1909,6 +2286,19 @@ typedef struct t_FmPcdPrsStart { 'parsingOffset' */ } t_FmPcdPrsStart; +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description struct for defining external buffer margins +*//***************************************************************************/ +typedef struct t_FmPortVSPAllocParams { + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */ + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port + The same default Virtual-Storage-Profile-id will be for coupled Tx port + if relevant function called for Rx port */ + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */ +} t_FmPortVSPAllocParams; +#endif /* (DPAA_VERSION >= 11) */ + /**************************************************************************//** @Function FM_PORT_SetPCD @@ -1918,7 +2308,7 @@ typedef struct t_FmPcdPrsStart { disabled (BMI to BMI) and configures it according to the passed parameters. - May be used for Rx and offline parsing ports only + May be used for Rx and OP ports only @Param[in] h_FmPort A handle to a FM Port module. @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD @@ -1937,7 +2327,7 @@ t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd); The port returns to its default configuration which is PCD disabled (BMI to BMI) and all PCD configuration is removed. - May be used for Rx and offline parsing ports which are + May be used for Rx and OP ports which are in PCD mode only @Param[in] h_FmPort A handle to a FM Port module. @@ -1956,7 +2346,7 @@ t_Error FM_PORT_DeletePCD(t_Handle h_FmPort); The couple of routines are used to allow PCD configuration changes that demand that PCD will not be used while changes take place. - May be used for Rx and offline parsing ports which are + May be used for Rx and OP ports which are in PCD mode only @Param[in] h_FmPort A handle to a FM Port module. @@ -1973,7 +2363,7 @@ t_Error FM_PORT_AttachPCD(t_Handle h_FmPort); @Description Calling this routine detaches the port from its PCD functionality. The port returns to its default flow which is BMI to BMI. - May be used for Rx and offline parsing ports which are + May be used for Rx and OP ports which are in PCD mode only @Param[in] h_FmPort A handle to a FM Port module. @@ -1995,7 +2385,8 @@ t_Error FM_PORT_DetachPCD(t_Handle h_FmPort); @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), and before FM_PORT_SetPCD(). + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), + and before FM_PORT_SetPCD(). *//***************************************************************************/ t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles); @@ -2008,10 +2399,30 @@ t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles); @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), and before FM_PORT_SetPCD(). + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), + and before FM_PORT_SetPCD(). *//***************************************************************************/ t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort); +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Function FM_PORT_VSPAlloc + + @Description This routine allocated VSPs per port and forces the port to work + in VSP mode. Note that the port is initialized by default with the + physical-storage-profile only. + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_Params A structure of parameters for allocation VSP's per port + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD() + and also before FM_PORT_Enable(); i.e. the port should be disabled. +*//***************************************************************************/ +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params); +#endif /* (DPAA_VERSION >= 11) */ + /**************************************************************************//** @Function FM_PORT_PcdKgModifyInitialScheme @@ -2099,21 +2510,18 @@ t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme); /**************************************************************************//** - @Function FM_PORT_PcdPrsModifyStartOffset + @Function FM_PORT_GetIPv4OptionsCount - @Description Runtime change of the parser start offset within the header. - The routine may not be called while port - receives packets using the PCD functionalities, therefore port must be first detached - from the PCD, only than the routine may be called, and than port be attached to PCD again. - @Param[in] h_FmPort A handle to a FM Port module. - @Param[in] p_FmPcdPrsStart A structure of parameters for defining the - start point for the parser. + @Description TODO + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[out] p_Ipv4OptionsCount will hold the counter value @Return E_OK on success; Error code otherwise. - @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetatchPCD(). + @Cautions Allowed only following FM_PORT_Init() *//***************************************************************************/ -t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart); +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount); /** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */ /** @} */ /* end of FM_PORT_runtime_control_grp group */ @@ -2192,5 +2600,9 @@ t_Error FM_PORT_ImRx(t_Handle h_FmPort); +#ifdef NCSW_BACKWARD_COMPATIBLE_API +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth +#endif /* NCSW_BACKWARD_COMPATIBLE_API */ + #endif /* __FM_PORT_EXT */ diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h index 8827d2aa476d..72078ac42c10 100644 --- a/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File fm_rtc_ext.h @@ -44,7 +45,7 @@ #include "error_ext.h" #include "std_ext.h" - +#include "fsl_fman_rtc.h" /**************************************************************************//** @@ -76,8 +77,8 @@ *//***************************************************************************/ typedef enum e_FmRtcAlarmPolarity { - e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */ - e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */ + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */ + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */ } e_FmRtcAlarmPolarity; /**************************************************************************//** @@ -85,8 +86,8 @@ typedef enum e_FmRtcAlarmPolarity *//***************************************************************************/ typedef enum e_FmRtcTriggerPolarity { - e_FM_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */ - e_FM_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */ + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */ + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */ } e_FmRtcTriggerPolarity; /**************************************************************************//** @@ -94,9 +95,9 @@ typedef enum e_FmRtcTriggerPolarity *//***************************************************************************/ typedef enum e_FmSrcClock { - e_FM_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */ - e_FM_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ - e_FM_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */ + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */ + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */ }e_FmSrcClk; /**************************************************************************//** @@ -169,7 +170,7 @@ t_Error FM_RTC_Free(t_Handle h_FmRtc); @Function FM_RTC_ConfigPeriod @Description Configures the period of the timestamp if different than - default [1000]. + default [DEFAULT_clockPeriod]. @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] period - Period in nano-seconds. @@ -201,7 +202,7 @@ t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc, @Function FM_RTC_ConfigPulseRealignment @Description Configures the RTC to automatic FIPER pulse realignment in - response to timer adjustments [FALSE] + response to timer adjustments [DEFAULT_pulseRealign] In this mode, the RTC clock is identical to the source clock. This feature can be useful when the system contains an external @@ -220,7 +221,7 @@ t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable); @Function FM_RTC_ConfigFrequencyBypass @Description Configures the RTC to bypass the frequency compensation - mechanism. [FALSE] + mechanism. [DEFAULT_bypass] In this mode, the RTC clock is identical to the source clock. This feature can be useful when the system contains an external @@ -240,7 +241,7 @@ t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled); @Function FM_RTC_ConfigInvertedInputClockPhase @Description Configures the RTC to invert the source clock phase on input. - [FALSE] + [DEFAULT_invertInputClkPhase] @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] inverted - TRUE to invert the source clock phase on input. @@ -256,7 +257,7 @@ t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted); @Function FM_RTC_ConfigInvertedOutputClockPhase @Description Configures the RTC to invert the output clock phase. - [FALSE] + [DEFAULT_invertOutputClkPhase] @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] inverted - TRUE to invert the output clock phase. @@ -272,7 +273,7 @@ t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted); @Function FM_RTC_ConfigOutputClockDivisor @Description Configures the divisor for generating the output clock from - the RTC clock. [0x00000002] + the RTC clock. [DEFAULT_outputClockDivisor] @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] divisor - Divisor for generation of the output clock. @@ -287,7 +288,7 @@ t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor); @Function FM_RTC_ConfigAlarmPolarity @Description Configures the polarity (active-high/active-low) of a specific - alarm signal. [e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH] + alarm signal. [DEFAULT_alarmPolarity] @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] alarmId - Alarm ID. @@ -305,7 +306,7 @@ t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc, @Function FM_RTC_ConfigExternalTriggerPolarity @Description Configures the polarity (rising/falling edge) of a specific - external trigger signal. [e_FM_RTC_TRIGGER_ON_FALLING_EDGE] + external trigger signal. [DEFAULT_triggerPolarity] @Param[in] h_FmRtc - Handle to FM RTC object. @Param[in] triggerId - Trigger ID. @@ -540,11 +541,11 @@ t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts); @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). *//***************************************************************************/ t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts); - + /**************************************************************************//** @Function FM_RTC_GetFreqCompensation - @Description TODO + @Description Retrieves the frequency compensation value @Param[in] h_FmRtc - Handle to FM RTC object. @Param[out] p_Compensation - A pointer to the returned value of compensation. @@ -558,10 +559,10 @@ t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation); /**************************************************************************//** @Function FM_RTC_SetFreqCompensation - @Description TODO + @Description Sets a new frequency compensation value. @Param[in] h_FmRtc - Handle to FM RTC object. - @Param[in] freqCompensation - the new desired compensation value to be set. + @Param[in] freqCompensation - The new frequency compensation value to set. @Return E_OK on success; Error code otherwise. @@ -569,6 +570,32 @@ t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation); *//***************************************************************************/ t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation); +#ifdef CONFIG_PTP_1588_CLOCK_DPAA +/**************************************************************************//** +*@Function FM_RTC_EnableInterrupt +* +*@Description Enable interrupt of FM RTC. +* +*@Param[in] h_FmRtc - Handle to FM RTC object. +*@Param[in] events - Interrupt events. +* +*@Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events); + +/**************************************************************************//** +*@Function FM_RTC_DisableInterrupt +* +*@Description Disable interrupt of FM RTC. +* +*@Param[in] h_FmRtc - Handle to FM RTC object. +*@Param[in] events - Interrupt events. +* +*@Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events); +#endif + #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) /**************************************************************************//** @Function FM_RTC_DumpRegs diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_vsp_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_vsp_ext.h new file mode 100644 index 000000000000..f9aed0363d7c --- /dev/null +++ b/sys/contrib/ncsw/inc/Peripherals/fm_vsp_ext.h @@ -0,0 +1,411 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/**************************************************************************//** + @File fm_vsp_ext.h + + @Description FM Virtual Storage-Profile ... +*//***************************************************************************/ +#ifndef __FM_VSP_EXT_H +#define __FM_VSP_EXT_H + +#include "std_ext.h" +#include "error_ext.h" +#include "string_ext.h" +#include "debug_ext.h" + +#include "fm_ext.h" + + +/**************************************************************************//** + + @Group FM_grp Frame Manager API + + @Description FM API functions, definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Group FM_VSP_grp FM Virtual-Storage-Profile + + @Description FM Virtual-Storage-Profile API + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Group FM_VSP_init_grp FM VSP Initialization Unit + + @Description FM VSP initialization API. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description Virtual Storage Profile +*//***************************************************************************/ +typedef struct t_FmVspParams { + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */ + t_FmExtPools extBufPools; /**< Which external buffer pools are used + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. + parameter associated with Rx / OP port */ + uint16_t liodnOffset; /**< VSP's LIODN offset */ + struct { + e_FmPortType portType; /**< Port type */ + uint8_t portId; /**< Port Id - relative to type */ + } portParams; + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range + defined in relevant FM object */ +} t_FmVspParams; + + +/**************************************************************************//** + @Function FM_VSP_Config + + @Description Creates descriptor for the FM VSP module. + + The routine returns a handle (descriptor) to the FM VSP object. + This descriptor must be passed as first parameter to all other + FM VSP function calls. + + No actual initialization or configuration of FM hardware is + done by this routine. + +@Param[in] p_FmVspParams Pointer to data structure of parameters + + @Retval Handle to FM VSP object, or NULL for Failure. +*//***************************************************************************/ +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams); + +/**************************************************************************//** + @Function FM_VSP_Init + + @Description Initializes the FM VSP module + + @Param[in] h_FmVsp - FM VSP module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_VSP_Init(t_Handle h_FmVsp); + +/**************************************************************************//** + @Function FM_VSP_Free + + @Description Frees all resources that were assigned to FM VSP module. + + Calling this routine invalidates the descriptor. + + @Param[in] h_FmVsp - FM VSP module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +t_Error FM_VSP_Free(t_Handle h_FmVsp); + + +/**************************************************************************//** + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit + + @Description FM VSP advanced configuration functions. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function FM_VSP_ConfigBufferPrefixContent + + @Description Defines the structure, size and content of the application buffer. + + The prefix will + In VSPs defined for Tx ports, if 'passPrsResult', the application + should set a value to their offsets in the prefix of + the FM will save the first 'privDataSize', than, + depending on 'passPrsResult' and 'passTimeStamp', copy parse result + and timeStamp, and the packet itself (in this order), to the + application buffer, and to offset. + + Calling this routine changes the buffer margins definitions + in the internal driver data base from its default + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the + structure of the buffer. + Out parameter: Start margin - offset + of data from start of external buffer. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, + t_FmBufferPrefixContent *p_FmBufferPrefixContent); + +/**************************************************************************//** + @Function FM_VSP_ConfigDmaSwapData + + @Description Calling this routine changes the DMA swap data parameter + in the internal driver data base from its default + configuration [DEFAULT_FM_SP_dmaSwapData] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] swapData New selection + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData); + +/**************************************************************************//** + @Function FM_VSP_ConfigDmaIcCacheAttr + + @Description Calling this routine changes the internal context cache + attribute parameter in the internal driver data base + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] intContextCacheAttr New selection + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, + e_FmDmaCacheOption intContextCacheAttr); + +/**************************************************************************//** + @Function FM_VSP_ConfigDmaHdrAttr + + @Description Calling this routine changes the header cache + attribute parameter in the internal driver data base + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] headerCacheAttr New selection + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr); + +/**************************************************************************//** + @Function FM_VSP_ConfigDmaScatterGatherAttr + + @Description Calling this routine changes the scatter gather cache + attribute parameter in the internal driver data base + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] scatterGatherCacheAttr New selection + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, + e_FmDmaCacheOption scatterGatherCacheAttr); + +/**************************************************************************//** + @Function FM_VSP_ConfigDmaWriteOptimize + + @Description Calling this routine changes the write optimization + parameter in the internal driver data base + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize); + +/**************************************************************************//** + @Function FM_VSP_ConfigNoScatherGather + + @Description Calling this routine changes the possibility to receive S/G frame + in the internal driver data base + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather] + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] noScatherGather TRUE to operate without scatter/gather capability. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather); + +/**************************************************************************//** + @Function FM_VSP_ConfigPoolDepletion + + @Description Calling this routine enables pause frame generation depending on the + depletion status of BM pools. It also defines the conditions to activate + this functionality. By default, this functionality is disabled. + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion); + +/**************************************************************************//** + @Function FM_VSP_ConfigBackupPools + + @Description Calling this routine allows the configuration of some of the BM pools + defined for this port as backup pools. + A pool configured to be a backup pool will be used only if all other + enabled non-backup pools are depleted. + + @Param[in] h_FmVsp A handle to a FM VSP module. + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will + be defined as backup pools. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools); + +/** @} */ /* end of FM_VSP_adv_config_grp group */ +/** @} */ /* end of FM_VSP_init_grp group */ + + +/**************************************************************************//** + @Group FM_VSP_control_grp FM VSP Control Unit + + @Description FM VSP runtime control API. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Function FM_VSP_GetBufferDataOffset + + @Description Relevant for Rx ports. + Returns the data offset from the beginning of the data buffer + + @Param[in] h_FmVsp - FM PORT module descriptor + + @Return data offset. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp); + +/**************************************************************************//** + @Function FM_VSP_GetBufferICInfo + + @Description Returns the Internal Context offset from the beginning of the data buffer + + @Param[in] h_FmVsp - FM PORT module descriptor + @Param[in] p_Data - A pointer to the data buffer. + + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not + configured for this port. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data); + +/**************************************************************************//** + @Function FM_VSP_GetBufferPrsResult + + @Description Returns the pointer to the parse result in the data buffer. + In Rx ports this is relevant after reception, if parse + result is configured to be part of the data passed to the + application. For non Rx ports it may be used to get the pointer + of the area in the buffer where parse result should be + initialized - if so configured. + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix + configuration. + + @Param[in] h_FmVsp - FM PORT module descriptor + @Param[in] p_Data - A pointer to the data buffer. + + @Return Parse result pointer on success, NULL if parse result was not + configured for this port. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data); + +/**************************************************************************//** + @Function FM_VSP_GetBufferTimeStamp + + @Description Returns the time stamp in the data buffer. + Relevant for Rx ports for getting the buffer time stamp. + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix + configuration. + + @Param[in] h_FmVsp - FM PORT module descriptor + @Param[in] p_Data - A pointer to the data buffer. + + @Return A pointer to the hash result on success, NULL otherwise. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data); + +/**************************************************************************//** + @Function FM_VSP_GetBufferHashResult + + @Description Given a data buffer, on the condition that hash result was defined + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent) + this routine will return the pointer to the hash result location in the + buffer prefix. + + @Param[in] h_FmVsp - FM PORT module descriptor + @Param[in] p_Data - A pointer to the data buffer. + + @Return A pointer to the hash result on success, NULL otherwise. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data); + + +/** @} */ /* end of FM_VSP_control_grp group */ +/** @} */ /* end of FM_VSP_grp group */ +/** @} */ /* end of FM_grp group */ + + +#endif /* __FM_VSP_EXT_H */ diff --git a/sys/contrib/ncsw/inc/Peripherals/mii_acc_ext.h b/sys/contrib/ncsw/inc/Peripherals/mii_acc_ext.h new file mode 100644 index 000000000000..f635d3c24de0 --- /dev/null +++ b/sys/contrib/ncsw/inc/Peripherals/mii_acc_ext.h @@ -0,0 +1,76 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + + +#ifndef __MII_ACC_EXT_H +#define __MII_ACC_EXT_H + + +/**************************************************************************//** + @Function MII_ReadPhyReg + + @Description This routine is called to read a specified PHY + register value. + + @Param[in] h_MiiAccess - Handle to MII configuration access registers + @Param[in] phyAddr - PHY address (0-31). + @Param[in] reg - PHY register to read + @Param[out] p_Data - Gets the register value. + + @Return Always zero (success). +*//***************************************************************************/ +int MII_ReadPhyReg(t_Handle h_MiiAccess, + uint8_t phyAddr, + uint8_t reg, + uint16_t *p_Data); + +/**************************************************************************//** + @Function MII_WritePhyReg + + @Description This routine is called to write data to a specified PHY + register. + + @Param[in] h_MiiAccess - Handle to MII configuration access registers + @Param[in] phyAddr - PHY address (0-31). + @Param[in] reg - PHY register to write + @Param[in] data - Data to write in register. + + @Return Always zero (success). +*//***************************************************************************/ +int MII_WritePhyReg(t_Handle h_MiiAccess, + uint8_t phyAddr, + uint8_t reg, + uint16_t data); + + +#endif /* __MII_ACC_EXT_H */ diff --git a/sys/contrib/ncsw/inc/Peripherals/qm_ext.h b/sys/contrib/ncsw/inc/Peripherals/qm_ext.h index 98f4b37892d7..6a4bc9fcfe6f 100644 --- a/sys/contrib/ncsw/inc/Peripherals/qm_ext.h +++ b/sys/contrib/ncsw/inc/Peripherals/qm_ext.h @@ -627,7 +627,7 @@ typedef struct { uintptr_t ciBaseAddress; /**< Cache-inhibited base address (virtual) */ t_Handle h_Qm; /**< Qm Handle */ e_DpaaSwPortal swPortalId; /**< Portal id */ - int irq; /**< portal interrupt line; used only if useIrq set to TRUE */ + uintptr_t irq; /**< portal interrupt line; used only if useIrq set to TRUE */ uint16_t fdLiodnOffset; /**< liodn to be used for all frames enqueued via this software portal */ t_QmReceivedFrameCallback *f_DfltFrame; /**< this callback will be called unless specific callback assigned to the FQ*/ t_QmRejectedFrameCallback *f_RejectedFrame; /**< this callback will be called for rejected frames. */ diff --git a/sys/contrib/ncsw/inc/core_ext.h b/sys/contrib/ncsw/inc/core_ext.h index 022de2b30e5c..ec89a6dde4cd 100644 --- a/sys/contrib/ncsw/inc/core_ext.h +++ b/sys/contrib/ncsw/inc/core_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File core_ext.h @@ -42,7 +43,10 @@ #ifndef __CORE_EXT_H #define __CORE_EXT_H - +#ifdef CONFIG_FMAN_ARM +#include "arm_ext.h" +#include +#else #ifdef NCSW_PPC_CORE #include "ppc_ext.h" #elif defined(NCSW_VXWORKS) @@ -55,6 +59,12 @@ #error "Must define core as little-endian or big-endian!" #endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */ +#ifndef CORE_CACHELINE_SIZE +#error "Must define the core cache-line size!" +#endif /* !CORE_CACHELINE_SIZE */ + +#endif /* CONFIG_FMAN_ARM */ + /**************************************************************************//** @Function CORE_GetId @@ -75,7 +85,6 @@ uint32_t CORE_GetId(void); @Return None. *//***************************************************************************/ void CORE_MemoryBarrier(void); - +#define fsl_mem_core_barrier() CORE_MemoryBarrier() #endif /* __CORE_EXT_H */ - diff --git a/sys/contrib/ncsw/inc/cores/arm_ext.h b/sys/contrib/ncsw/inc/cores/arm_ext.h new file mode 100644 index 000000000000..e63444a7d676 --- /dev/null +++ b/sys/contrib/ncsw/inc/cores/arm_ext.h @@ -0,0 +1,55 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/**************************************************************************//** + @File arm_ext.h + + @Description Core API for ARM cores + + These routines must be implemented by each specific PowerPC + core driver. +*//***************************************************************************/ +#ifndef __ARM_EXT_H +#define __ARM_EXT_H + +#include "part_ext.h" + + +#define CORE_IS_LITTLE_ENDIAN + +static __inline__ void CORE_MemoryBarrier(void) +{ + mb(); +} + +#endif /* __PPC_EXT_H */ diff --git a/sys/contrib/ncsw/inc/cores/e500v2_ext.h b/sys/contrib/ncsw/inc/cores/e500v2_ext.h index df545ff4b2de..e79b1ddff121 100644 --- a/sys/contrib/ncsw/inc/cores/e500v2_ext.h +++ b/sys/contrib/ncsw/inc/cores/e500v2_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File e500v2_ext.h @@ -58,6 +59,8 @@ void L1DCache_Disable(void); void L1ICache_Disable(void); void L1DCache_Flush(void); void L1ICache_Flush(void); +uint32_t L1ICache_IsEnabled(void); +uint32_t L1DCache_IsEnabled(void); /* * */ @@ -193,6 +196,7 @@ typedef enum e_E500mcL2CacheMode e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */ } e_E500mcL2CacheMode; +#if defined(CORE_E500MC) || defined(CORE_E5500) /**************************************************************************//** @Function E500_L2CacheEnable @@ -237,6 +241,65 @@ void E500_L2CacheFlush(void); @Return None. *//***************************************************************************/ void E500_L2SetStashId(uint8_t stashId); +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */ + +#ifdef CORE_E6500 +/**************************************************************************//** + @Function E6500_L2CacheEnable + + @Description Enables the cache for memory pages that are not cache inhibited. + + @param[in] mode - L2 cache mode: support data & instruction only. + + @Return None. + + @Cautions This routine must be call only ONCE for both caches. I.e. it is + not possible to call this routine for i-cache and than to call + again for d-cache; The second call will override the first one. +*//***************************************************************************/ +void E6500_L2CacheEnable(uintptr_t clusterBase); + +/**************************************************************************//** + @Function E6500_L2CacheDisable + + @Description Disables the cache (data instruction or both). + + @Return None. + +*//***************************************************************************/ +void E6500_L2CacheDisable(uintptr_t clusterBase); + +/**************************************************************************//** + @Function E6500_L2CacheFlush + + @Description Flushes the cache. + + @Return None. +*//***************************************************************************/ +void E6500_L2CacheFlush(uintptr_t clusterBase); + +/**************************************************************************//** + @Function E6500_L2SetStashId + + @Description Set Stash Id + + @Param[in] stashId the stash id to be set. + + @Return None. +*//***************************************************************************/ +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId); + +/**************************************************************************//** + @Function E6500_GetCcsrBase + + @Description Obtain SoC CCSR base address + + @Param[in] None. + + @Return Physical CCSR base address. +*//***************************************************************************/ +physAddress_t E6500_GetCcsrBase(void); +#endif /* CORE_E6500 */ /**************************************************************************//** @Function E500_AddressBusStreamingEnable @@ -374,9 +437,9 @@ int E500_TestAndSet(volatile int *p); *//***************************************************************************/ static __inline__ void E500_MemoryBarrier(void) { -#ifdef CORE_E500MC +#ifndef CORE_E500V2 __asm__ ("mbar 1"); -#else +#else /* CORE_E500V2 */ /**** ERRATA WORK AROUND START ****/ /* ERRATA num: CPU1 */ /* Description: "mbar MO = 1" instruction fails to order caching-inhibited @@ -387,7 +450,7 @@ static __inline__ void E500_MemoryBarrier(void) __asm__ ("msync"); /**** ERRATA WORK AROUND END ****/ -#endif +#endif /* CORE_E500V2 */ } /**************************************************************************//** diff --git a/sys/contrib/ncsw/inc/cores/ppc_ext.h b/sys/contrib/ncsw/inc/cores/ppc_ext.h index e045c3173bc9..6639affd4e71 100644 --- a/sys/contrib/ncsw/inc/cores/ppc_ext.h +++ b/sys/contrib/ncsw/inc/cores/ppc_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File ppc_ext.h @@ -46,6 +47,14 @@ #define CORE_IS_BIG_ENDIAN +#if defined(CORE_E300) || defined(CORE_E500V2) +#define CORE_CACHELINE_SIZE 32 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500) +#define CORE_CACHELINE_SIZE 64 +#else +#error "Core not defined!" +#endif /* defined(CORE_E300) || ... */ + /**************************************************************************//** @Function CORE_TestAndSet @@ -117,14 +126,6 @@ void CORE_ICacheDisable(void); - -#if defined(CORE_E300) -#include "e300_ext.h" -#elif defined(CORE_E500V2) || defined(CORE_E500MC) #include "e500v2_ext.h" -#else -#error "Core not defined!" -#endif - #endif /* __PPC_EXT_H */ diff --git a/sys/contrib/ncsw/inc/ddr_std_ext.h b/sys/contrib/ncsw/inc/ddr_std_ext.h index c4d9ed66f433..8bb343fc2852 100644 --- a/sys/contrib/ncsw/inc/ddr_std_ext.h +++ b/sys/contrib/ncsw/inc/ddr_std_ext.h @@ -1,38 +1,34 @@ -/****************************************************************************** - - © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc. - All rights reserved. - - This is proprietary source code of Freescale Semiconductor Inc., - and its use is subject to the NetComm Device Drivers EULA. - The copyright notice above does not evidence any actual or intended - publication of such source code. - - ALTERNATIVELY, redistribution and use in source and binary forms, with - or without modification, are permitted provided that the following - conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of Freescale Semiconductor nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * - - **************************************************************************/ + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ #ifndef __DDR_SDT_EXT_H #define __DDR_SDT_EXT_H @@ -60,7 +56,8 @@ typedef enum e_DdrType e_DDR_DDR1, e_DDR_DDR2, e_DDR_DDR3, - e_DDR_DDR3L + e_DDR_DDR3L, + e_DDR_DDR4 } e_DdrType; /**************************************************************************//** diff --git a/sys/contrib/ncsw/inc/debug_ext.h b/sys/contrib/ncsw/inc/debug_ext.h index 37f5b83af5e2..57db0a1486cd 100644 --- a/sys/contrib/ncsw/inc/debug_ext.h +++ b/sys/contrib/ncsw/inc/debug_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File debug_ext.h @@ -54,24 +55,26 @@ #define DUMP_Print XX_Print #define DUMP_MAX_LEVELS 6 +#define DUMP_IDX_LEN 6 #define DUMP_MAX_STR 64 #define _CREATE_DUMP_SUBSTR(phrase) \ dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \ - sprintf(dumpTmpStr, "%s", #phrase); \ + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \ p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \ - while (p_DumpToken != NULL) \ + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \ { \ - strcat(dumpSubStr, p_DumpToken); \ + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \ if (dumpIsArr[dumpTmpLevel]) \ { \ - strcat(dumpSubStr, dumpIdxStr[dumpTmpLevel]); \ + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \ p_DumpToken = strtok(NULL, "."); \ } \ - if ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != 0) \ - strcat(dumpSubStr, "."); \ - }\ + if ((p_DumpToken != NULL) && \ + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \ + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \ + } /**************************************************************************//** @@ -98,11 +101,11 @@ starts. *//***************************************************************************/ #define DECLARE_DUMP \ - char dumpIdxStr[DUMP_MAX_LEVELS + 1][6] = { "", }; \ + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \ char dumpSubStr[DUMP_MAX_STR] = ""; \ char dumpTmpStr[DUMP_MAX_STR] = ""; \ char *p_DumpToken = NULL; \ - int dumpArrIdx = 0, dumpArrSize = 0, dumpVarSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \ + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \ uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \ /* Prevent warnings if not all used */ \ UNUSED(dumpIdxStr[0][0]); \ @@ -111,7 +114,6 @@ UNUSED(p_DumpToken); \ UNUSED(dumpArrIdx); \ UNUSED(dumpArrSize); \ - UNUSED(dumpVarSize); \ UNUSED(dumpLevel); \ UNUSED(dumpTmpLevel); \ UNUSED(dumpIsArr[0]); @@ -123,11 +125,11 @@ The inputs for this macro are the structure/memory title and its base addresses. *//***************************************************************************/ -#define DUMP_TITLE(addr, msg) \ +#define DUMP_TITLE(addr, msg) \ DUMP_Print("\r\n"); DUMP_Print msg; \ - DUMP_Print(" (0x%p)\r\n" \ - "---------------------------------------------------------\r\n", \ - (addr)) + if (addr) \ + DUMP_Print(" (%p)", (addr)); \ + DUMP_Print("\r\n---------------------------------------------------------\r\n"); /**************************************************************************//** @Description Prints a subtitle for a subsequent dumped sub-structure (optional). @@ -163,8 +165,8 @@ *//***************************************************************************/ #define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \ for (idx=0, dumpIsArr[dumpLevel++] = 1; \ - (idx < cnt) && sprintf(dumpIdxStr[dumpLevel-1], "[%d]", idx); \ - idx++, ((idx < cnt) || ((dumpIsArr[--dumpLevel] = 0) == 0))) + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \ + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0))) /**************************************************************************//** @@ -185,21 +187,11 @@ *//***************************************************************************/ #define DUMP_VAR(st, phrase) \ do { \ - void *addr = (void *)&((st)->phrase); \ + void *addr = (void *)&((st)->phrase); \ + physAddress_t physAddr = XX_VirtToPhys(addr); \ _CREATE_DUMP_SUBSTR(phrase); \ - dumpVarSize = sizeof((st)->phrase); \ - switch (dumpVarSize) \ - { \ - case 1: DUMP_Print("0x%08X: 0x%02x%14s\t%s\r\n", \ - addr, GET_UINT8(*(uint8_t*)addr), "", dumpSubStr); break; \ - case 2: DUMP_Print("0x%08X: 0x%04x%12s\t%s\r\n", \ - addr, GET_UINT16(*(uint16_t*)addr), "", dumpSubStr); break; \ - case 4: DUMP_Print("0x%08X: 0x%08x%8s\t%s\r\n", \ - addr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); break; \ - case 8: DUMP_Print("0x%08X: 0x%016llx\t%s\r\n", \ - addr, GET_UINT64(*(uint64_t*)addr), dumpSubStr); break; \ - default: DUMP_Print("Bad size %d (" #st "->" #phrase ")\r\n", dumpVarSize); \ - } \ + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \ + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \ } while (0) @@ -218,36 +210,18 @@ *//***************************************************************************/ #define DUMP_ARR(st, phrase) \ do { \ + physAddress_t physAddr; \ _CREATE_DUMP_SUBSTR(phrase); \ dumpArrSize = ARRAY_SIZE((st)->phrase); \ - dumpVarSize = sizeof((st)->phrase[0]); \ - switch (dumpVarSize) \ - { \ - case 1: \ - for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ - DUMP_Print("0x%08X: 0x%02x%14s\t%s[%d]\r\n", \ - &((st)->phrase[dumpArrIdx]), GET_UINT8((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ - } break; \ - case 2: \ - for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ - DUMP_Print("0x%08X: 0x%04x%12s\t%s[%d]\r\n", \ - &((st)->phrase[dumpArrIdx]), GET_UINT16((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ - } break; \ - case 4: \ - for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ - DUMP_Print("0x%08X: 0x%08x%8s\t%s[%d]\r\n", \ - &((st)->phrase[dumpArrIdx]), GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ - } break; \ - case 8: \ - for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ - DUMP_Print("0x%08X: 0x%016llx\t%s[%d]\r\n", \ - &((st)->phrase[dumpArrIdx]), GET_UINT64((st)->phrase[dumpArrIdx]), dumpSubStr, dumpArrIdx); \ - } break; \ - default: DUMP_Print("Bad size %d (" #st "->" #phrase "[0])\r\n", dumpVarSize); \ + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \ + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \ + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ } \ } while (0) + #endif /* DEBUG_ERRORS > 0 */ diff --git a/sys/contrib/ncsw/inc/endian_ext.h b/sys/contrib/ncsw/inc/endian_ext.h index 7084e8285a0d..5cdec668aedf 100644 --- a/sys/contrib/ncsw/inc/endian_ext.h +++ b/sys/contrib/ncsw/inc/endian_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File endian_ext.h diff --git a/sys/contrib/ncsw/inc/enet_ext.h b/sys/contrib/ncsw/inc/enet_ext.h index 14f7760b72bc..ef3bee55e897 100644 --- a/sys/contrib/ncsw/inc/enet_ext.h +++ b/sys/contrib/ncsw/inc/enet_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File enet_ext.h @@ -39,6 +40,7 @@ #ifndef __ENET_EXT_H #define __ENET_EXT_H +#include "fsl_enet.h" #define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */ #define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */ @@ -59,24 +61,32 @@ typedef enum e_EnetAddrType e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */ } e_EnetAddrType; - /**************************************************************************//** @Description Ethernet MAC-PHY Interface *//***************************************************************************/ typedef enum e_EnetInterface { - e_ENET_IF_MII = 0x00010000, /**< MII interface */ - e_ENET_IF_RMII = 0x00020000, /**< RMII interface */ - e_ENET_IF_SMII = 0x00030000, /**< SMII interface */ - e_ENET_IF_GMII = 0x00040000, /**< GMII interface */ - e_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */ - e_ENET_IF_TBI = 0x00060000, /**< TBI interface */ - e_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */ - e_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */ - e_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */ - e_ENET_IF_QSGMII= 0x000a0000 /**< QSGMII interface */ + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */ + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */ + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */ + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */ + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */ + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */ + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */ + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */ + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */ + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */ + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */ } e_EnetInterface; +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX + auto-negotiation between MAC and phy + or backplane; + Note: 1000BaseX auto-negotiation relates + only to interface between MAC and phy/backplane, + SGMII phy can still synchronize with far-end phy + at 10Mbps, 100Mbps or 1000Mbps */ + /**************************************************************************//** @Description Ethernet Duplex Mode *//***************************************************************************/ @@ -91,10 +101,11 @@ typedef enum e_EnetDuplexMode *//***************************************************************************/ typedef enum e_EnetSpeed { - e_ENET_SPEED_10 = 10, /**< 10 Mbps */ - e_ENET_SPEED_100 = 100, /**< 100 Mbps */ - e_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */ - e_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */ + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */ + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */ + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */ + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */ + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */ } e_EnetSpeed; /**************************************************************************//** @@ -102,24 +113,46 @@ typedef enum e_EnetSpeed *//***************************************************************************/ typedef enum e_EnetMode { - e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */ - e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */ - e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */ - e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */ - e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */ - e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */ - e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */ - e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */ - e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */ - e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */ - e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */ - e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */ - e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */ - e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10), /**< 10 Mbps SGMII */ - e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100), /**< 100 Mbps SGMII */ - e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000), /**< 1000 Mbps SGMII */ - e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */ - e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000) /**< 1000 Mbps QSGMII */ + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */ + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */ + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */ + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */ + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */ + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */ + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */ + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */ + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */ + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */ + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */ + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */ + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */ + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10), + /**< 10 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100), + /**< 100 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000), + /**< 1000 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500), + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10), + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100), + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000), + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000), + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and + QSGMII phy according to Cisco QSGMII specification */ + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000), + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between + MAC and QSGMII phy or backplane */ + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */ + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */ } e_EnetMode; @@ -139,16 +172,34 @@ typedef enum e_EnetMode ((mode) == e_ENET_MODE_SGMII_10 ) || \ ((mode) == e_ENET_MODE_SGMII_100 ) || \ ((mode) == e_ENET_MODE_SGMII_1000 ) || \ + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \ + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \ + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \ ((mode) == e_ENET_MODE_XGMII_10000) || \ - ((mode) == e_ENET_MODE_QSGMII_1000)) + ((mode) == e_ENET_MODE_QSGMII_1000) || \ + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \ + ((mode) == e_ENET_MODE_XFI_10000)) #define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed)) -#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0xFFFF0000) +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000) #define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF) +#define ENET_ADDR_TO_UINT64(_enetAddr) \ + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \ + ((uint64_t)(_enetAddr)[1] << 32) | \ + ((uint64_t)(_enetAddr)[2] << 24) | \ + ((uint64_t)(_enetAddr)[3] << 16) | \ + ((uint64_t)(_enetAddr)[4] << 8) | \ + ((uint64_t)(_enetAddr)[5])) + +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \ + do { \ + int i; \ + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \ + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \ + } while (0) #endif /* __ENET_EXT_H */ - diff --git a/sys/contrib/ncsw/inc/error_ext.h b/sys/contrib/ncsw/inc/error_ext.h index 3963b843e309..7afafe9fbc2b 100644 --- a/sys/contrib/ncsw/inc/error_ext.h +++ b/sys/contrib/ncsw/inc/error_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** + +/**************************************************************************//** @File error_ext.h @Description Error definitions. @@ -39,10 +40,19 @@ #ifndef __ERROR_EXT_H #define __ERROR_EXT_H +#if defined(NCSW_FREEBSD) +#include +#include +#include +#endif + #include "std_ext.h" #include "xx_ext.h" #include "core_ext.h" + + + /**************************************************************************//** @Group gen_id General Drivers Utilities @@ -85,18 +95,45 @@ The scheme below provides the bits description for error codes: typedef enum e_ErrorType /* Comments / Associated Message Strings */ { /* ------------------------------------------------------------ */ E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */ - - /* Invalid Function Calls */ + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */ + /* String: none, or device name. */ + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */ + /* String: none. */ + ,E_NOT_AVAILABLE = EAGAIN + /**< Resource is unavailable. */ + /* String: none, unless the operation is not the main goal + of the function (in this case add resource description). */ + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */ + /* String: description of item for which allocation failed. */ + ,E_INVALID_ADDRESS = EFAULT + /**< Invalid address. */ + /* String: description of the specific violation. */ + ,E_BUSY = EBUSY /**< Resource or module is busy. */ + /* String: none, unless the operation is not the main goal + of the function (in this case add resource description). */ + ,E_ALREADY_EXISTS = EEXIST + /**< Requested resource or item already exists. */ + /* Use when resource duplication or sharing are not allowed. + String: none, unless the operation is not the main goal + of the function (in this case add item description). */ + ,E_INVALID_OPERATION = ENODEV + /**< The operation/command is invalid (unrecognized). */ + /* String: none. */ + ,E_INVALID_VALUE = EDOM /**< Invalid value. */ + /* Use for non-enumeration parameters, and + only when other error types are not suitable. + String: parameter description + "(should be )", + e.g: "Maximum Rx buffer length (should be divisible by 8)", + "Channel number (should be even)". */ + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */ + /* Don't use this error for enumeration parameters. + String: parameter description + "(should be %d-%d)", + e.g: "Number of pad characters (should be 0-15)". */ + ,E_NOT_SUPPORTED = ENOSYS + /**< The function is not supported or not implemented. */ + /* String: none. */ ,E_INVALID_STATE /**< The operation is not allowed in current module state. */ /* String: none. */ - ,E_INVALID_OPERATION /**< The operation/command is invalid (unrecognized). */ - /* String: none. */ - ,E_NOT_SUPPORTED /**< The function is not supported or not implemented. */ - /* String: none. */ - ,E_NO_DEVICE /**< The associated device is not initialized. */ - /* String: none. */ - - /* Invalid Parameters */ ,E_INVALID_HANDLE /**< Invalid handle of module or object. */ /* String: none, unless the function takes in more than one handle (in this case add the handle description) */ @@ -105,12 +142,6 @@ typedef enum e_ErrorType /* Comments / Associated Message Strings ID (in this case add the ID description) */ ,E_NULL_POINTER /**< Unexpected NULL pointer. */ /* String: pointer description. */ - ,E_INVALID_VALUE /**< Invalid value. */ - /* Use for non-enumeration parameters, and - only when other error types are not suitable. - String: parameter description + "(should be )", - e.g: "Maximum Rx buffer length (should be divisible by 8)", - "Channel number (should be even)". */ ,E_INVALID_SELECTION /**< Invalid selection or mode. */ /* Use for enumeration values, only when other error types are not suitable. @@ -119,101 +150,47 @@ typedef enum e_ErrorType /* Comments / Associated Message Strings /* String: none, unless the function takes in more than one communication mode indications (in this case add parameter description). */ - ,E_INVALID_BYTE_ORDER /**< Invalid byte order. */ - /* String: none, unless the function takes in more than one - byte order indications (in this case add parameter - description). */ ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */ /* String: none, unless the function takes in more than one memory types (in this case add memory description, e.g: "Data memory", "Buffer descriptors memory"). */ - ,E_INVALID_INTR_QUEUE /**< Invalid interrupt queue. */ - /* String: none, unless the function takes in more than one - interrupt queues (in this case add queue description, - e.g: "Rx interrupt queue", "Tx interrupt queue"). */ - ,E_INVALID_PRIORITY /**< Invalid priority. */ - /* String: none, unless the function takes in more than one - priority (in this case add priority description). */ ,E_INVALID_CLOCK /**< Invalid clock. */ /* String: none, unless the function takes in more than one clocks (in this case add clock description, e.g: "Rx clock", "Tx clock"). */ - ,E_INVALID_RATE /**< Invalid rate value. */ - /* String: none, unless the function takes in more than one - rate values (in this case add rate description). */ - ,E_INVALID_ADDRESS /**< Invalid address. */ - /* String: description of the specific violation. */ - ,E_INVALID_BUS /**< Invalid bus type. */ - /* String: none, unless the function takes in more than one - bus parameters (in this case add bus description). */ - ,E_BUS_CONFLICT /**< Bus (or memory) type conflicts with another setting. */ - /* String: description of the conflicting buses/memories. */ ,E_CONFLICT /**< Some setting conflicts with another setting. */ /* String: description of the conflicting settings. */ ,E_NOT_ALIGNED /**< Non-aligned address. */ /* String: parameter description + "(should be %d-bytes aligned)", e.g: "Rx data buffer (should be 32-bytes aligned)". */ - ,E_NOT_IN_RANGE /**< Parameter value is out of range. */ - /* Don't use this error for enumeration parameters. - String: parameter description + "(should be %d-%d)", - e.g: "Number of pad characters (should be 0-15)". */ - - /* Frame/Buffer Errors */ - ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */ - /* String: none. */ - ,E_EMPTY_FRAME /**< Frame object is empty (has no buffers). */ - /* String: none. */ - ,E_EMPTY_BUFFER /**< Buffer object is empty (no data, or zero data length). */ - /* String: none. */ - - /* Resource Errors */ - ,E_NO_MEMORY /**< External memory allocation failed. */ - /* String: description of item for which allocation failed. */ ,E_NOT_FOUND /**< Requested resource or item was not found. */ /* Use only when the resource/item is uniquely identified. String: none, unless the operation is not the main goal of the function (in this case add item description). */ - ,E_NOT_AVAILABLE /**< Resource is unavailable. */ - /* String: none, unless the operation is not the main goal - of the function (in this case add resource description). */ - ,E_ALREADY_EXISTS /**< Requested resource or item already exists. */ - /* Use when resource duplication or sharing are not allowed. - String: none, unless the operation is not the main goal - of the function (in this case add item description). */ ,E_FULL /**< Resource is full. */ /* String: none, unless the operation is not the main goal of the function (in this case add resource description). */ ,E_EMPTY /**< Resource is empty. */ /* String: none, unless the operation is not the main goal of the function (in this case add resource description). */ - ,E_BUSY /**< Resource or module is busy. */ - /* String: none, unless the operation is not the main goal - of the function (in this case add resource description). */ ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */ /* String: none, unless the operation is not the main goal of the function (in this case add item description). */ - - /* Read/Write Access Errors */ ,E_READ_FAILED /**< Read access failed on memory/device. */ /* String: none, or device name. */ - ,E_WRITE_FAILED /**< Write access failed on memory/device. */ - /* String: none, or device name. */ - - /* Send/Receive Failures */ + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */ + /* String: none. */ ,E_SEND_FAILED /**< Send operation failed on device. */ /* String: none, or device name. */ ,E_RECEIVE_FAILED /**< Receive operation failed on device. */ /* String: none, or device name. */ - - /* Operation time-out */ - ,E_TIMEOUT /**< The operation timed out. */ + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */ /* String: none. */ ,E_DUMMY_LAST /* NEVER USED */ } e_ErrorType; - /**************************************************************************//** @Description Event Type Enumeration *//***************************************************************************/ @@ -352,9 +329,7 @@ int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL; #endif /* !ERROR_DYNAMIC_LEVEL */ #define PRINT_FORMAT "[CPU%02d, %s:%d %s]" -#define PRINT_FMT_PARAMS CORE_GetId(), __FILE__, __LINE__, __FUNCTION__ -#define _ERR_STRING(err) #err -#define ERR_STRING(err) _ERR_STRING(err) +#define PRINT_FMT_PARAMS PCPU_GET(cpuid), __FILE__, __LINE__, __FUNCTION__ #if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) /* No debug/error/event messages at all */ @@ -384,12 +359,12 @@ int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL; #else /* DEBUG_ERRORS > 0 */ extern const char *dbgLevelStrings[]; -extern const char *errTypeStrings[]; -extern const char *moduleStrings[]; #if (REPORT_EVENTS > 0) extern const char *eventStrings[]; #endif /* (REPORT_EVENTS > 0) */ +char * ErrTypeStrings (e_ErrorType err); + #if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING)) /* No need for DBG macro - debug level is higher anyway */ @@ -400,7 +375,7 @@ extern const char *eventStrings[]; if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \ XX_Print("> %s (%s) " PRINT_FORMAT ": ", \ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \ - ERR_STRING(__ERR_MODULE__), \ + __STRING(__ERR_MODULE__), \ PRINT_FMT_PARAMS); \ XX_Print _vmsg; \ XX_Print("\r\n"); \ @@ -414,9 +389,9 @@ extern const char *eventStrings[]; if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \ XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \ - ERR_STRING(__ERR_MODULE__), \ + __STRING(__ERR_MODULE__), \ PRINT_FMT_PARAMS, \ - errTypeStrings[(GET_ERROR_TYPE(_err) - E_OK - 1)]); \ + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \ XX_Print _vmsg; \ XX_Print("\r\n"); \ } \ @@ -437,7 +412,7 @@ extern const char *eventStrings[]; if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \ XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \ dbgLevelStrings[_ev##_LEVEL - 1], \ - ERR_STRING(__ERR_MODULE__), \ + __STRING(__ERR_MODULE__), \ PRINT_FMT_PARAMS, \ eventStrings[((_ev) - EV_NO_EVENT - 1)], \ (uint16_t)(_flg)); \ diff --git a/sys/contrib/ncsw/inc/etc/list_ext.h b/sys/contrib/ncsw/inc/etc/list_ext.h index d6f3a662fa5f..743b2785b9e9 100644 --- a/sys/contrib/ncsw/inc/etc/list_ext.h +++ b/sys/contrib/ncsw/inc/etc/list_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File list_ext.h @@ -71,16 +72,16 @@ typedef struct List /**************************************************************************//** - @Function NCSW_LIST_FIRST/LIST_LAST/NCSW_LIST_NEXT/NCSW_LIST_PREV + @Function NCSW_LIST_FIRST/NCSW_LIST_LAST/NCSW_LIST_NEXT/NCSW_LIST_PREV @Description Macro to get first/last/next/previous entry in a list. @Param[in] p_List - A pointer to a list. *//***************************************************************************/ #define NCSW_LIST_FIRST(p_List) (p_List)->p_Next -#define LIST_LAST(p_List) (p_List)->p_Prev +#define NCSW_LIST_LAST(p_List) (p_List)->p_Prev #define NCSW_LIST_NEXT NCSW_LIST_FIRST -#define NCSW_LIST_PREV LIST_LAST +#define NCSW_LIST_PREV NCSW_LIST_LAST /**************************************************************************//** @@ -94,13 +95,13 @@ typedef struct List /**************************************************************************//** - @Function LIST + @Function NCSW_LIST @Description Macro to declare of a list. @Param[in] listName - The list object name. *//***************************************************************************/ -#define LIST(listName) t_List listName = NCSW_LIST_INIT(listName) +#define NCSW_LIST(listName) t_List listName = NCSW_LIST_INIT(listName) /**************************************************************************//** @@ -110,11 +111,11 @@ typedef struct List @Param[in] p_List - The list pointer. *//***************************************************************************/ -#define INIT_LIST(p_List) NCSW_LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List) +#define INIT_LIST(p_List) NCSW_LIST_FIRST(p_List) = NCSW_LIST_LAST(p_List) = (p_List) /**************************************************************************//** - @Function LIST_OBJECT + @Function NCSW_LIST_OBJECT @Description Macro to get the struct (object) for this entry. @@ -124,12 +125,12 @@ typedef struct List @Return The structure pointer for this entry. *//***************************************************************************/ #define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member)) -#define LIST_OBJECT(p_List, type, member) \ +#define NCSW_LIST_OBJECT(p_List, type, member) \ ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member))) /**************************************************************************//** - @Function LIST_FOR_EACH + @Function NCSW_LIST_FOR_EACH @Description Macro to iterate over a list. @@ -137,14 +138,14 @@ typedef struct List @Param[in] p_Head - A pointer to the head for your list pointer. @Cautions You can't delete items with this routine. - For deletion use LIST_FOR_EACH_SAFE(). + For deletion use NCSW_LIST_FOR_EACH_SAFE(). *//***************************************************************************/ -#define LIST_FOR_EACH(p_Pos, p_Head) \ +#define NCSW_LIST_FOR_EACH(p_Pos, p_Head) \ for (p_Pos = NCSW_LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = NCSW_LIST_NEXT(p_Pos)) /**************************************************************************//** - @Function LIST_FOR_EACH_SAFE + @Function NCSW_LIST_FOR_EACH_SAFE @Description Macro to iterate over a list safe against removal of list entry. @@ -152,14 +153,14 @@ typedef struct List @Param[in] p_Tmp - Another pointer to a list to use as temporary storage. @Param[in] p_Head - A pointer to the head for your list pointer. *//***************************************************************************/ -#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \ +#define NCSW_LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \ for (p_Pos = NCSW_LIST_FIRST(p_Head), p_Tmp = NCSW_LIST_FIRST(p_Pos); \ p_Pos != (p_Head); \ p_Pos = p_Tmp, p_Tmp = NCSW_LIST_NEXT(p_Pos)) /**************************************************************************//** - @Function LIST_FOR_EACH_OBJECT_SAFE + @Function NCSW_LIST_FOR_EACH_OBJECT_SAFE @Description Macro to iterate over list of given type safely. @@ -170,17 +171,17 @@ typedef struct List @Param[in] member - The name of the list_struct within the struct. @Cautions You can't delete items with this routine. - For deletion use LIST_FOR_EACH_SAFE(). + For deletion use NCSW_LIST_FOR_EACH_SAFE(). *//***************************************************************************/ -#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \ - for (p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member), \ - p_Tmp = LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member); \ +#define NCSW_LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \ + for (p_Pos = NCSW_LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member), \ + p_Tmp = NCSW_LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member); \ &p_Pos->member != (p_Head); \ p_Pos = p_Tmp, \ - p_Tmp = LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member)) + p_Tmp = NCSW_LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member)) /**************************************************************************//** - @Function LIST_FOR_EACH_OBJECT + @Function NCSW_LIST_FOR_EACH_OBJECT @Description Macro to iterate over list of given type. @@ -190,16 +191,16 @@ typedef struct List @Param[in] member - The name of the list_struct within the struct. @Cautions You can't delete items with this routine. - For deletion use LIST_FOR_EACH_SAFE(). + For deletion use NCSW_LIST_FOR_EACH_SAFE(). *//***************************************************************************/ -#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \ - for (p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member); \ +#define NCSW_LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \ + for (p_Pos = NCSW_LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member); \ &p_Pos->member != (p_Head); \ - p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(&(p_Pos->member)), type, member)) + p_Pos = NCSW_LIST_OBJECT(NCSW_LIST_FIRST(&(p_Pos->member)), type, member)) /**************************************************************************//** - @Function LIST_Add + @Function NCSW_LIST_Add @Description Add a new entry to a list. @@ -211,7 +212,7 @@ typedef struct List @Return none. *//***************************************************************************/ -static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head) +static __inline__ void NCSW_LIST_Add(t_List *p_New, t_List *p_Head) { NCSW_LIST_PREV(NCSW_LIST_NEXT(p_Head)) = p_New; NCSW_LIST_NEXT(p_New) = NCSW_LIST_NEXT(p_Head); @@ -221,7 +222,7 @@ static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head) /**************************************************************************//** - @Function LIST_AddToTail + @Function NCSW_LIST_AddToTail @Description Add a new entry to a list. @@ -229,11 +230,11 @@ static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head) This is useful for implementing queues. @Param[in] p_New - A pointer to a new list entry to be added. - @Param[in] p_Head - A pointer to a list head to add it after. + @Param[in] p_Head - A pointer to a list head to add it before. @Return none. *//***************************************************************************/ -static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head) +static __inline__ void NCSW_LIST_AddToTail(t_List *p_New, t_List *p_Head) { NCSW_LIST_NEXT(NCSW_LIST_PREV(p_Head)) = p_New; NCSW_LIST_PREV(p_New) = NCSW_LIST_PREV(p_Head); @@ -243,7 +244,7 @@ static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head) /**************************************************************************//** - @Function LIST_Del + @Function NCSW_LIST_Del @Description Deletes entry from a list. @@ -251,10 +252,10 @@ static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head) @Return none. - @Cautions LIST_IsEmpty() on entry does not return true after this, + @Cautions NCSW_LIST_IsEmpty() on entry does not return true after this, the entry is in an undefined state. *//***************************************************************************/ -static __inline__ void LIST_Del(t_List *p_Entry) +static __inline__ void NCSW_LIST_Del(t_List *p_Entry) { NCSW_LIST_PREV(NCSW_LIST_NEXT(p_Entry)) = NCSW_LIST_PREV(p_Entry); NCSW_LIST_NEXT(NCSW_LIST_PREV(p_Entry)) = NCSW_LIST_NEXT(p_Entry); @@ -262,7 +263,7 @@ static __inline__ void LIST_Del(t_List *p_Entry) /**************************************************************************//** - @Function LIST_DelAndInit + @Function NCSW_LIST_DelAndInit @Description Deletes entry from list and reinitialize it. @@ -270,15 +271,15 @@ static __inline__ void LIST_Del(t_List *p_Entry) @Return none. *//***************************************************************************/ -static __inline__ void LIST_DelAndInit(t_List *p_Entry) +static __inline__ void NCSW_LIST_DelAndInit(t_List *p_Entry) { - LIST_Del(p_Entry); + NCSW_LIST_Del(p_Entry); INIT_LIST(p_Entry); } /**************************************************************************//** - @Function LIST_Move + @Function NCSW_LIST_Move @Description Delete from one list and add as another's head. @@ -287,15 +288,15 @@ static __inline__ void LIST_DelAndInit(t_List *p_Entry) @Return none. *//***************************************************************************/ -static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head) +static __inline__ void NCSW_LIST_Move(t_List *p_Entry, t_List *p_Head) { - LIST_Del(p_Entry); - LIST_Add(p_Entry, p_Head); + NCSW_LIST_Del(p_Entry); + NCSW_LIST_Add(p_Entry, p_Head); } /**************************************************************************//** - @Function LIST_MoveToTail + @Function NCSW_LIST_MoveToTail @Description Delete from one list and add as another's tail. @@ -304,15 +305,15 @@ static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head) @Return none. *//***************************************************************************/ -static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head) +static __inline__ void NCSW_LIST_MoveToTail(t_List *p_Entry, t_List *p_Head) { - LIST_Del(p_Entry); - LIST_AddToTail(p_Entry, p_Head); + NCSW_LIST_Del(p_Entry); + NCSW_LIST_AddToTail(p_Entry, p_Head); } /**************************************************************************//** - @Function LIST_IsEmpty + @Function NCSW_LIST_IsEmpty @Description Tests whether a list is empty. @@ -320,14 +321,14 @@ static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head) @Return 1 if the list is empty, 0 otherwise. *//***************************************************************************/ -static __inline__ int LIST_IsEmpty(t_List *p_List) +static __inline__ int NCSW_LIST_IsEmpty(t_List *p_List) { return (NCSW_LIST_FIRST(p_List) == p_List); } /**************************************************************************//** - @Function LIST_Append + @Function NCSW_LIST_Append @Description Join two lists. @@ -336,11 +337,11 @@ static __inline__ int LIST_IsEmpty(t_List *p_List) @Return none. *//***************************************************************************/ -void LIST_Append(t_List *p_NewList, t_List *p_Head); +void NCSW_LIST_Append(t_List *p_NewList, t_List *p_Head); /**************************************************************************//** - @Function LIST_NumOfObjs + @Function NCSW_LIST_NumOfObjs @Description Counts number of objects in the list @@ -348,7 +349,7 @@ void LIST_Append(t_List *p_NewList, t_List *p_Head); @Return Number of objects in the list. *//***************************************************************************/ -int LIST_NumOfObjs(t_List *p_List); +int NCSW_LIST_NumOfObjs(t_List *p_List); /** @} */ /* end of list_id group */ /** @} */ /* end of etc_id group */ diff --git a/sys/contrib/ncsw/inc/etc/mem_ext.h b/sys/contrib/ncsw/inc/etc/mem_ext.h index 16592d5ddadb..d0565d410ca4 100644 --- a/sys/contrib/ncsw/inc/etc/mem_ext.h +++ b/sys/contrib/ncsw/inc/etc/mem_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File mem_ext.h @@ -258,7 +259,7 @@ uint32_t MEM_ComputePartitionSize(uint32_t num, uint16_t alignment); #ifdef DEBUG_MEM_LEAKS -#if !(defined(__MWERKS__) && (__dest_os == __ppc_eabi)) +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi)) #error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior" #endif /* !(defined(__MWERKS__) && ... */ diff --git a/sys/contrib/ncsw/inc/etc/memcpy_ext.h b/sys/contrib/ncsw/inc/etc/memcpy_ext.h index e50c8a9f8e17..1b3a2fac5fad 100644 --- a/sys/contrib/ncsw/inc/etc/memcpy_ext.h +++ b/sys/contrib/ncsw/inc/etc/memcpy_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File memcpy_ext.h @@ -166,6 +167,40 @@ void * MemSet64(void* pDst, uint8_t val, uint32_t size); *//***************************************************************************/ void MemDisp(uint8_t *addr, int size); +/**************************************************************************//** + @Function MemCpy8 + + @Description Trivial copy one memory buffer into another byte by byte + + @Param[in] pDst - The address of the destination buffer. + @Param[in] pSrc - The address of the source buffer. + @Param[in] size - The number of bytes that will be copied from pSrc to pDst. + + @Return pDst (the address of the destination buffer). + + @Cautions There is no parameter or boundary checking! It is up to the user + to supply non-null parameters as source & destination and size + that actually fits into the destination buffer. +*//***************************************************************************/ +void * MemCpy8(void* pDst,void* pSrc, uint32_t size); + +/**************************************************************************//** + @Function MemSet8 + + @Description Sets all bytes of a memory buffer to a specific value byte by byte. + + @Param[in] pDst - The address of the destination buffer. + @Param[in] c - Value to set destination bytes to. + @Param[in] size - The number of bytes that will be set to val. + + @Return pDst (the address of the destination buffer). + + @Cautions There is no parameter or boundary checking! It is up to the user + to supply non null parameter as destination and size + that actually fits into the destination buffer. +*//***************************************************************************/ +void * MemSet8(void* pDst, int c, uint32_t size); + /** @} */ /* end of mem_cpy group */ /** @} */ /* end of etc_id group */ diff --git a/sys/contrib/ncsw/inc/etc/mm_ext.h b/sys/contrib/ncsw/inc/etc/mm_ext.h index 030f8775e1e2..fa7c85e3b2b8 100644 --- a/sys/contrib/ncsw/inc/etc/mm_ext.h +++ b/sys/contrib/ncsw/inc/etc/mm_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /**************************************************************************//** +/**************************************************************************//** @File mm_ext.h @Description Memory Manager Application Programming Interface @@ -245,12 +245,11 @@ t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size); /**************************************************************************//** @Function MM_Dump - @Description Prints results of free and busy lists into the file. + @Description Prints results of free and busy lists. @Param[in] h_MM - Handle to the MM object. - @Param[in] buff - A pointer to a buffer *//***************************************************************************/ -void MM_Dump(t_Handle h_MM, void *buff); +void MM_Dump(t_Handle h_MM); /**************************************************************************//** @Function MM_Free @@ -293,6 +292,17 @@ uint64_t MM_GetMemBlock(t_Handle h_MM, int index); *//***************************************************************************/ bool MM_InRange(t_Handle h_MM, uint64_t addr); +/**************************************************************************//** + @Function MM_GetFreeMemSize + + @Description Returns the size (in bytes) of free memory. + + @Param[in] h_MM - Handle to the MM object. + + @Return Free memory size in bytes. +*//***************************************************************************/ +uint64_t MM_GetFreeMemSize(t_Handle h_MM); + /** @} */ /* end of mm_grp group */ /** @} */ /* end of etc_id group */ diff --git a/sys/contrib/ncsw/inc/etc/sprint_ext.h b/sys/contrib/ncsw/inc/etc/sprint_ext.h index e94fac00b74d..0a53b7ce02a0 100644 --- a/sys/contrib/ncsw/inc/etc/sprint_ext.h +++ b/sys/contrib/ncsw/inc/etc/sprint_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/****************************************************************************** +/**************************************************************************//** @File sprint_ext.h @Description Debug routines (externals). @@ -45,13 +45,6 @@ #if defined(NCSW_LINUX) && defined(__KERNEL__) #include -#elif defined(NCSW_LINUX_USD) -#include -#include "stdarg_ext.h" -#include "std_ext.h" - -extern int vsscanf(const char *, const char *, va_list); - #elif defined(NCSW_VXWORKS) #include "private/stdioP.h" diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_guest.c b/sys/contrib/ncsw/inc/flib/common/arch/ppc_access.h similarity index 92% rename from sys/contrib/ncsw/Peripherals/FM/fm_guest.c rename to sys/contrib/ncsw/inc/flib/common/arch/ppc_access.h index 886f6a07d891..c7b9b46f269b 100644 --- a/sys/contrib/ncsw/Peripherals/FM/fm_guest.c +++ b/sys/contrib/ncsw/inc/flib/common/arch/ppc_access.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef FL_E500_MACROS_H +#define FL_E500_MACROS_H - +#endif /* FL_E500_MACROS_H */ diff --git a/sys/contrib/ncsw/inc/flib/common/general.h b/sys/contrib/ncsw/inc/flib/common/general.h new file mode 100644 index 000000000000..1b2ce7242805 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/common/general.h @@ -0,0 +1,52 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __GENERAL_H +#define __GENERAL_H + +#include "std_ext.h" +#if !defined(NCSW_LINUX) && !defined(NCSW_FREEBSD) +#include "errno.h" +#endif + + +extern uint32_t get_mac_addr_crc(uint64_t _addr); + +#ifndef CONFIG_FMAN_ARM +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val) +#define ioread32be(addr) GET_UINT32(*addr) +#endif + +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16) + + +#endif /* __GENERAL_H */ diff --git a/sys/contrib/ncsw/inc/flib/fman_common.h b/sys/contrib/ncsw/inc/flib/fman_common.h new file mode 100755 index 000000000000..8b194e995561 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fman_common.h @@ -0,0 +1,78 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +#ifndef __FMAN_COMMON_H +#define __FMAN_COMMON_H + +/**************************************************************************//** + @Description NIA Description +*//***************************************************************************/ +#define NIA_ORDER_RESTOR 0x00800000 +#define NIA_ENG_FM_CTL 0x00000000 +#define NIA_ENG_PRS 0x00440000 +#define NIA_ENG_KG 0x00480000 +#define NIA_ENG_PLCR 0x004C0000 +#define NIA_ENG_BMI 0x00500000 +#define NIA_ENG_QMI_ENQ 0x00540000 +#define NIA_ENG_QMI_DEQ 0x00580000 +#define NIA_ENG_MASK 0x007C0000 + +#define NIA_FM_CTL_AC_CC 0x00000006 +#define NIA_FM_CTL_AC_HC 0x0000000C +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A +#define NIA_FM_CTL_AC_FRAG 0x0000000e +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020 + + +#define NIA_BMI_AC_ENQ_FRAME 0x00000002 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0 +#define NIA_BMI_AC_RELEASE 0x000000C0 +#define NIA_BMI_AC_DISCARD 0x000000C1 +#define NIA_BMI_AC_TX 0x00000274 +#define NIA_BMI_AC_FETCH 0x00000208 +#define NIA_BMI_AC_MASK 0x000003FF + +#define NIA_KG_DIRECT 0x00000100 +#define NIA_KG_CC_EN 0x00000200 +#define NIA_PLCR_ABSOLUTE 0x00008000 + +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c + +#endif /* __FMAN_COMMON_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_enet.h b/sys/contrib/ncsw/inc/flib/fsl_enet.h new file mode 100644 index 000000000000..caa87fc6b21d --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_enet.h @@ -0,0 +1,273 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_ENET_H +#define __FSL_ENET_H + +/** + @Description Ethernet MAC-PHY Interface +*/ + +enum enet_interface { + E_ENET_IF_MII = 0x00010000, /**< MII interface */ + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */ + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */ + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */ + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */ + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */ + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */ + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */ + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */ + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */ + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */ +}; + +/** + @Description Ethernet Speed (nominal data rate) +*/ +enum enet_speed { + E_ENET_SPEED_10 = 10, /**< 10 Mbps */ + E_ENET_SPEED_100 = 100, /**< 100 Mbps */ + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */ + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */ + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */ +}; + +enum mac_type { + E_MAC_DTSEC, + E_MAC_TGEC, + E_MAC_MEMAC +}; + +/**************************************************************************//** + @Description Enum for inter-module interrupts registration +*//***************************************************************************/ +enum fman_event_modules { + E_FMAN_MOD_PRS, /**< Parser event */ + E_FMAN_MOD_KG, /**< Keygen event */ + E_FMAN_MOD_PLCR, /**< Policer event */ + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */ + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */ + E_FMAN_MOD_TMR, /**< Timer event */ + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */ + E_FMAN_MOD_MACSEC, + E_FMAN_MOD_DUMMY_LAST +}; + +/**************************************************************************//** + @Description Enum for interrupts types +*//***************************************************************************/ +enum fman_intr_type { + E_FMAN_INTR_TYPE_ERR, + E_FMAN_INTR_TYPE_NORMAL +}; + +/**************************************************************************//** + @Description enum for defining MAC types +*//***************************************************************************/ +enum fman_mac_type { + E_FMAN_MAC_10G = 0, /**< 10G MAC */ + E_FMAN_MAC_1G /**< 1G MAC */ +}; + +enum fman_mac_exceptions { + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0, + /**< 10GEC MDIO scan event interrupt */ + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL, + /**< 10GEC MDIO command completion interrupt */ + E_FMAN_MAC_EX_10G_REM_FAULT, + /**< 10GEC, mEMAC Remote fault interrupt */ + E_FMAN_MAC_EX_10G_LOC_FAULT, + /**< 10GEC, mEMAC Local fault interrupt */ + E_FMAN_MAC_EX_10G_1TX_ECC_ER, + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */ + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL, + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */ + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL, + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */ + E_FMAN_MAC_EX_10G_TX_ER, + /**< 10GEC Transmit frame error interrupt */ + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL, + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */ + E_FMAN_MAC_EX_10G_RX_ECC_ER, + /**< 10GEC, mEMAC Receive frame ECC error interrupt */ + E_FMAN_MAC_EX_10G_RX_JAB_FRM, + /**< 10GEC Receive jabber frame interrupt */ + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM, + /**< 10GEC Receive oversized frame interrupt */ + E_FMAN_MAC_EX_10G_RX_RUNT_FRM, + /**< 10GEC Receive runt frame interrupt */ + E_FMAN_MAC_EX_10G_RX_FRAG_FRM, + /**< 10GEC Receive fragment frame interrupt */ + E_FMAN_MAC_EX_10G_RX_LEN_ER, + /**< 10GEC Receive payload length error interrupt */ + E_FMAN_MAC_EX_10G_RX_CRC_ER, + /**< 10GEC Receive CRC error interrupt */ + E_FMAN_MAC_EX_10G_RX_ALIGN_ER, + /**< 10GEC Receive alignment error interrupt */ + E_FMAN_MAC_EX_1G_BAB_RX, + /**< dTSEC Babbling receive error */ + E_FMAN_MAC_EX_1G_RX_CTL, + /**< dTSEC Receive control (pause frame) interrupt */ + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET, + /**< dTSEC Graceful transmit stop complete */ + E_FMAN_MAC_EX_1G_BAB_TX, + /**< dTSEC Babbling transmit error */ + E_FMAN_MAC_EX_1G_TX_CTL, + /**< dTSEC Transmit control (pause frame) interrupt */ + E_FMAN_MAC_EX_1G_TX_ERR, + /**< dTSEC Transmit error */ + E_FMAN_MAC_EX_1G_LATE_COL, + /**< dTSEC Late collision */ + E_FMAN_MAC_EX_1G_COL_RET_LMT, + /**< dTSEC Collision retry limit */ + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN, + /**< dTSEC Transmit FIFO underrun */ + E_FMAN_MAC_EX_1G_MAG_PCKT, + /**< dTSEC Magic Packet detection */ + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET, + /**< dTSEC MII management read completion */ + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET, + /**< dTSEC MII management write completion */ + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET, + /**< dTSEC Graceful receive stop complete */ + E_FMAN_MAC_EX_1G_TX_DATA_ERR, + /**< dTSEC Internal data error on transmit */ + E_FMAN_MAC_EX_1G_RX_DATA_ERR, + /**< dTSEC Internal data error on receive */ + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR, + /**< dTSEC Time-Stamp Receive Error */ + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL, + /**< dTSEC MIB counter overflow */ + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR, + /**< mEMAC Time-stamp FIFO ECC error interrupt; + not supported on T4240/B4860 rev1 chips */ +}; + +#define ENET_IF_SGMII_BASEX 0x80000000 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC + and phy or backplane; + Note: 1000BaseX auto-negotiation relates only to interface between MAC + and phy/backplane, SGMII phy can still synchronize with far-end phy at + 10Mbps, 100Mbps or 1000Mbps */ + +enum enet_mode { + E_ENET_MODE_INVALID = 0, + /**< Invalid Ethernet mode */ + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10), + /**< 10 Mbps MII */ + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100), + /**< 100 Mbps MII */ + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10), + /**< 10 Mbps RMII */ + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100), + /**< 100 Mbps RMII */ + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10), + /**< 10 Mbps SMII */ + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100), + /**< 100 Mbps SMII */ + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000), + /**< 1000 Mbps GMII */ + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10), + /**< 10 Mbps RGMII */ + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100), + /**< 100 Mbps RGMII */ + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000), + /**< 1000 Mbps RGMII */ + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000), + /**< 1000 Mbps TBI */ + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000), + /**< 1000 Mbps RTBI */ + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10), + /**< 10 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100), + /**< 100 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000), + /**< 1000 Mbps SGMII with auto-negotiation between MAC and + SGMII phy according to Cisco SGMII specification */ + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII + | E_ENET_SPEED_10), + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII + | E_ENET_SPEED_100), + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII + | E_ENET_SPEED_1000), + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between + MAC and SGMII phy or backplane */ + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000), + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and + QSGMII phy according to Cisco QSGMII specification */ + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII + | E_ENET_SPEED_1000), + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between + MAC and QSGMII phy or backplane */ + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000), + /**< 10000 Mbps XGMII */ + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000) + /**< 10000 Mbps XFI */ +}; + +enum fmam_mac_statistics_level { + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */ + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; + Optimized for performance */ + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not + optimized for performance */ +}; + +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \ + | (_speed)) + +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \ + ((mode) & 0x0FFF0000) +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF) +#define _ENET_ADDR_TO_UINT64(_enet_addr) \ + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \ + ((uint64_t)(_enet_addr)[1] << 32) | \ + ((uint64_t)(_enet_addr)[2] << 24) | \ + ((uint64_t)(_enet_addr)[3] << 16) | \ + ((uint64_t)(_enet_addr)[4] << 8) | \ + ((uint64_t)(_enet_addr)[5])) + +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \ + do { \ + int i; \ + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \ + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\ + } while (0) + +#endif /* __FSL_ENET_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman.h b/sys/contrib/ncsw/inc/flib/fsl_fman.h new file mode 100755 index 000000000000..96a63fa7f283 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman.h @@ -0,0 +1,825 @@ +/* + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_H +#define __FSL_FMAN_H + +#include "common/general.h" + +struct fman_ext_pool_params { + uint8_t id; /**< External buffer pool id */ + uint16_t size; /**< External buffer pool buffer size */ +}; + +struct fman_ext_pools { + uint8_t num_pools_used; /**< Number of pools use by this port */ + struct fman_ext_pool_params *ext_buf_pool; + /**< Parameters for each port */ +}; + +struct fman_backup_bm_pools { + uint8_t num_backup_pools; /**< Number of BM backup pools - + must be smaller than the total number + of pools defined for the specified + port.*/ + uint8_t *pool_ids; /**< numOfBackupPools pool id's, + specifying which pools should be used + only as backup. Pool id's specified + here must be a subset of the pools + used by the specified port.*/ +}; + +/**************************************************************************//** + @Description A structure for defining BM pool depletion criteria +*//***************************************************************************/ +struct fman_buf_pool_depletion { + bool buf_pool_depletion_enabled; + bool pools_grp_mode_enable; /**< select mode in which pause frames + will be sent after a number of pools + (all together!) are depleted */ + uint8_t num_pools; /**< the number of depleted pools that + will invoke pause frames transmission. + */ + bool *pools_to_consider; /**< For each pool, TRUE if it should be + considered for depletion (Note - this + pool must be used by this port!). */ + bool single_pool_mode_enable; /**< select mode in which pause frames + will be sent after a single-pool + is depleted; */ + bool *pools_to_consider_for_single_mode; + /**< For each pool, TRUE if it should be + considered for depletion (Note - this + pool must be used by this port!) */ + bool has_pfc_priorities; + bool *pfc_priorities_en; /**< This field is used by the MAC as + the Priority Enable Vector in the PFC + frame which is transmitted */ +}; + +/**************************************************************************//** + @Description Enum for defining port DMA swap mode +*//***************************************************************************/ +enum fman_dma_swap_option { + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/ + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped + in PowerPc Little Endian mode. */ + FMAN_DMA_SWP_BE /**< The transferred data should be swapped + in Big Endian mode */ +}; + +/**************************************************************************//** + @Description Enum for defining port DMA cache attributes +*//***************************************************************************/ +enum fman_dma_cache_option { + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */ + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */ +}; + +typedef struct t_FmPrsResult fm_prs_result_t; +typedef enum e_EnetMode enet_mode_t; +typedef t_Handle handle_t; + +struct fman_revision_info { + uint8_t majorRev; /**< Major revision */ + uint8_t minorRev; /**< Minor revision */ +}; + +/* sizes */ +#define CAPWAP_FRAG_EXTRA_SPACE 32 +#define OFFSET_UNITS 16 +#define MAX_INT_OFFSET 240 +#define MAX_IC_SIZE 256 +#define MAX_EXT_OFFSET 496 +#define MAX_EXT_BUFFER_OFFSET 511 + +/************************************************************************** + @Description Memory Mapped Registers +***************************************************************************/ +#define FMAN_LIODN_TBL 64 /* size of LIODN table */ + +struct fman_fpm_regs { + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */ + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */ + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */ + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */ + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */ + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */ + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */ + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */ + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */ + uint32_t res0030[4]; /**< res 0x30 - 0x3f */ + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */ + uint32_t res0050[4]; /**< res 0x50-0x5f */ + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */ + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */ + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */ + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */ + uint32_t fm_rcr; /**< FM Rams Control 0x70 */ + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */ + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */ + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */ + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */ + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */ + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */ + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */ + uint32_t fm_rstc; /**< FM Reset Command 0xcc */ + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */ + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */ + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */ + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */ + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */ + uint32_t res00f0[4]; /**< res 0xf0-0xff */ + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */ + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */ + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */ + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */ + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */ + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */ + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */ + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */ + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */ + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */ + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */ + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */ + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */ + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */ + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */ + uint32_t res0600[0x400 - 384]; +}; + +struct fman_bmi_regs { + uint32_t fmbm_init; /**< BMI Initialization 0x00 */ + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */ + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */ + uint32_t res000c[5]; /**< 0x0c - 0x1f */ + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */ + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */ + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */ + uint32_t res002c[5]; /**< 0x2c - 0x3f */ + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */ + uint32_t res0060[12]; /**<0x60 - 0x8f */ + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */ + uint32_t res009c; /**< 0x9c */ + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */ + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */ + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */ + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */ + uint32_t res0200; /**< 0x200 */ + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */ + uint32_t res0300; /**< 0x300 */ + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */ +}; + +struct fman_qmi_regs { + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */ + uint32_t res0004; /**< 0x04 */ + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */ + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */ + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */ + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */ + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */ + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */ + uint32_t fmqm_gs; /**< Global Status Register 0x20 */ + uint32_t fmqm_ts; /**< Task Status Register 0x24 */ + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */ + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */ + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */ + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */ + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */ + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */ + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */ + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */ + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */ + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */ + uint32_t res0050[7]; /**< 0x50 - 0x6b */ + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */ + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */ + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */ + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */ + uint32_t res007c; /**< 0x7c */ + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */ + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */ + uint32_t res0088[2]; /**< 0x88 - 0x8f */ + struct { + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */ + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */ + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */ + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */ + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */ + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */ + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */ + uint32_t res001c; /**< 0x1c */ + } dbg_traps[3]; /**< 0x90 - 0xef */ + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */ +}; + +struct fman_dma_regs { + uint32_t fmdmsr; /**< FM DMA status register 0x00 */ + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */ + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */ + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */ + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */ + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */ + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */ + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */ + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */ + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */ + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */ + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */ + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */ + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */ + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */ + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */ + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */ + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */ + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */ + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */ + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */ + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */ + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */ + uint32_t res005c; /**< 0x5c */ + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */ + uint32_t res00e0[0x400 - 56]; +}; + +struct fman_rg { + struct fman_fpm_regs *fpm_rg; + struct fman_dma_regs *dma_rg; + struct fman_bmi_regs *bmi_rg; + struct fman_qmi_regs *qmi_rg; +}; + +enum fman_dma_cache_override { + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */ + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */ + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */ + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */ +}; + +enum fman_dma_aid_mode { + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */ + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */ +}; + +enum fman_dma_dbg_cnt_mode { + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */ + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */ + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */ + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */ + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */ + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */ + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */ + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */ +}; + +enum fman_dma_emergency_level { + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */ + E_FMAN_DMA_EM_SOS /**< SOS emergency */ +}; + +enum fman_catastrophic_err { + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */ + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */ +}; + +enum fman_dma_err { + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */ + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */ +}; + +struct fman_cfg { + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */ + bool en_counters; + uint8_t disp_limit_tsh; + uint8_t prs_disp_tsh; + uint8_t plcr_disp_tsh; + uint8_t kg_disp_tsh; + uint8_t bmi_disp_tsh; + uint8_t qmi_enq_disp_tsh; + uint8_t qmi_deq_disp_tsh; + uint8_t fm_ctl1_disp_tsh; + uint8_t fm_ctl2_disp_tsh; + enum fman_dma_cache_override dma_cache_override; + enum fman_dma_aid_mode dma_aid_mode; + bool dma_aid_override; + uint8_t dma_axi_dbg_num_of_beats; + uint8_t dma_cam_num_of_entries; + uint32_t dma_watchdog; + uint8_t dma_comm_qtsh_asrt_emer; + uint8_t dma_write_buf_tsh_asrt_emer; + uint8_t dma_read_buf_tsh_asrt_emer; + uint8_t dma_comm_qtsh_clr_emer; + uint8_t dma_write_buf_tsh_clr_emer; + uint8_t dma_read_buf_tsh_clr_emer; + uint32_t dma_sos_emergency; + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode; + bool dma_stop_on_bus_error; + bool dma_en_emergency; + uint32_t dma_emergency_bus_select; + enum fman_dma_emergency_level dma_emergency_level; + bool dma_en_emergency_smoother; + uint32_t dma_emergency_switch_counter; + bool halt_on_external_activ; + bool halt_on_unrecov_ecc_err; + enum fman_catastrophic_err catastrophic_err; + enum fman_dma_err dma_err; + bool en_muram_test_mode; + bool en_iram_test_mode; + bool external_ecc_rams_enable; + uint16_t tnum_aging_period; + uint32_t exceptions; + uint16_t clk_freq; + bool pedantic_dma; + uint32_t cam_base_addr; + uint32_t fifo_base_addr; + uint32_t total_fifo_size; + uint8_t total_num_of_tasks; + bool qmi_deq_option_support; + uint32_t qmi_def_tnums_thresh; + bool fman_partition_array; + uint8_t num_of_fman_ctrl_evnt_regs; +}; + +/**************************************************************************//** + @Description Exceptions +*//***************************************************************************/ +#define FMAN_EX_DMA_BUS_ERROR 0x80000000 +#define FMAN_EX_DMA_READ_ECC 0x40000000 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000 +#define FMAN_EX_IRAM_ECC 0x00040000 +#define FMAN_EX_NURAM_ECC 0x00020000 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000 + +enum fman_exceptions { + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */ + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */ + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */ + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */ + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */ + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */ + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */ + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ +}; + +enum fman_counters { + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */ + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */ + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */ + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */ + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */ + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */ + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */ + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */ + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */ + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */ + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */ + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */ + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */ +}; + +#define FPM_PRT_FM_CTL1 0x00000001 +#define FPM_PRT_FM_CTL2 0x00000002 + +/**************************************************************************//** + @Description DMA definitions +*//***************************************************************************/ + +/* masks */ +#define DMA_MODE_AID_OR 0x20000000 +#define DMA_MODE_SBER 0x10000000 +#define DMA_MODE_BER 0x00200000 +#define DMA_MODE_EB 0x00100000 +#define DMA_MODE_ECC 0x00000020 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000 +#define DMA_MODE_SECURE_PROT 0x00000800 +#define DMA_MODE_EMER_READ 0x00080000 +#define DMA_MODE_EMER_WRITE 0x00040000 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000 +#define DMA_MODE_CEN_MASK 0x0000E000 +#define DMA_MODE_DBG_MASK 0x00000380 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000 + +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF + +#define DMA_TRANSFER_PORTID_MASK 0xFF000000 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF + +#define DMA_HIGH_LIODN_MASK 0x0FFF0000 +#define DMA_LOW_LIODN_MASK 0x00000FFF + +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000 +#define DMA_STATUS_BUS_ERR 0x08000000 +#define DMA_STATUS_READ_ECC 0x04000000 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000 + +#define FM_LIODN_BASE_MASK 0x00000FFF + +/* shifts */ +#define DMA_MODE_CACHE_OR_SHIFT 30 +#define DMA_MODE_BUS_PRI_SHIFT 16 +#define DMA_MODE_AXI_DBG_SHIFT 24 +#define DMA_MODE_CEN_SHIFT 13 +#define DMA_MODE_BUS_PROT_SHIFT 10 +#define DMA_MODE_DBG_SHIFT 7 +#define DMA_MODE_EMER_LVL_SHIFT 6 +#define DMA_MODE_AID_MODE_SHIFT 4 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32 + +#define DMA_THRESH_COMMQ_SHIFT 24 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16 + +#define DMA_LIODN_SHIFT 16 + +#define DMA_TRANSFER_PORTID_SHIFT 24 +#define DMA_TRANSFER_TNUM_SHIFT 16 + +/* sizes */ +#define DMA_MAX_WATCHDOG 0xffffffff + +/* others */ +#define DMA_CAM_SIZEOF_ENTRY 0x40 +#define DMA_CAM_ALIGN 0x1000 +#define DMA_CAM_UNITS 8 + +/**************************************************************************//** + @Description General defines +*//***************************************************************************/ + +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL + +/**************************************************************************//** + @Description FPM defines +*//***************************************************************************/ + +/* masks */ +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000 +#define FPM_EV_MASK_STALL 0x40000000 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000 +#define FPM_EV_MASK_RELEASE_FM 0x00010000 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000 +#define FPM_EV_MASK_STALL_EN 0x00004000 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004 + +#define FPM_RAM_RAMS_ECC_EN 0x80000000 +#define FPM_RAM_IRAM_ECC_EN 0x40000000 +#define FPM_RAM_MURAM_ECC 0x00008000 +#define FPM_RAM_IRAM_ECC 0x00004000 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000 + +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000 + +#define FPM_REV1_MAJOR_MASK 0x0000FF00 +#define FPM_REV1_MINOR_MASK 0x000000FF + +#define FPM_REV2_INTEG_MASK 0x00FF0000 +#define FPM_REV2_ERR_MASK 0x0000FF00 +#define FPM_REV2_CFG_MASK 0x000000FF + +#define FPM_TS_FRACTION_MASK 0x0000FFFF +#define FPM_TS_CTL_EN 0x80000000 + +#define FPM_PRC_REALSE_STALLED 0x00800000 + +#define FPM_PS_STALLED 0x00800000 +#define FPM_PS_FM_CTL1_SEL 0x80000000 +#define FPM_PS_FM_CTL2_SEL 0x40000000 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL) + +#define FPM_RSTC_FM_RESET 0x80000000 +#define FPM_RSTC_10G0_RESET 0x04000000 +#define FPM_RSTC_1G0_RESET 0x40000000 +#define FPM_RSTC_1G1_RESET 0x20000000 +#define FPM_RSTC_1G2_RESET 0x10000000 +#define FPM_RSTC_1G3_RESET 0x08000000 +#define FPM_RSTC_1G4_RESET 0x02000000 + + +#define FPM_DISP_LIMIT_MASK 0x1F000000 +#define FPM_THR1_PRS_MASK 0xFF000000 +#define FPM_THR1_KG_MASK 0x00FF0000 +#define FPM_THR1_PLCR_MASK 0x0000FF00 +#define FPM_THR1_BMI_MASK 0x000000FF + +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00 + +/* shifts */ +#define FPM_DISP_LIMIT_SHIFT 24 + +#define FPM_THR1_PRS_SHIFT 24 +#define FPM_THR1_KG_SHIFT 16 +#define FPM_THR1_PLCR_SHIFT 8 +#define FPM_THR1_BMI_SHIFT 0 + +#define FPM_THR2_QMI_ENQ_SHIFT 24 +#define FPM_THR2_QMI_DEQ_SHIFT 0 +#define FPM_THR2_FM_CTL1_SHIFT 16 +#define FPM_THR2_FM_CTL2_SHIFT 8 + +#define FPM_EV_MASK_CAT_ERR_SHIFT 1 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0 + +#define FPM_REV1_MAJOR_SHIFT 8 +#define FPM_REV1_MINOR_SHIFT 0 + +#define FPM_REV2_INTEG_SHIFT 16 +#define FPM_REV2_ERR_SHIFT 8 +#define FPM_REV2_CFG_SHIFT 0 + +#define FPM_TS_INT_SHIFT 16 + +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24 + +#define FPM_PS_FM_CTL_SEL_SHIFT 30 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16 + +#define FPM_DISP_LIMIT_SHIFT 24 + +/* Interrupts defines */ +#define FPM_EVENT_FM_CTL_0 0x00008000 +#define FPM_EVENT_FM_CTL 0x0000FF00 +#define FPM_EVENT_FM_CTL_BRK 0x00000080 + +/* others */ +#define FPM_MAX_DISP_LIMIT 31 +#define FPM_RSTC_FM_RESET 0x80000000 +#define FPM_RSTC_1G0_RESET 0x40000000 +#define FPM_RSTC_1G1_RESET 0x20000000 +#define FPM_RSTC_1G2_RESET 0x10000000 +#define FPM_RSTC_1G3_RESET 0x08000000 +#define FPM_RSTC_10G0_RESET 0x04000000 +#define FPM_RSTC_1G4_RESET 0x02000000 +#define FPM_RSTC_1G5_RESET 0x01000000 +#define FPM_RSTC_1G6_RESET 0x00800000 +#define FPM_RSTC_1G7_RESET 0x00400000 +#define FPM_RSTC_10G1_RESET 0x00200000 +/**************************************************************************//** + @Description BMI defines +*//***************************************************************************/ +/* masks */ +#define BMI_INIT_START 0x80000000 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F +#define BMI_FIFO_SIZE_MASK 0x000003FF +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000 +#define BMI_CFG2_DMAS_MASK 0x0000003F +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000 + +/* shifts */ +#define BMI_CFG2_TASKS_SHIFT 16 +#define BMI_CFG2_DMAS_SHIFT 0 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16 +#define BMI_FIFO_SIZE_SHIFT 0 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16 +#define BMI_NUM_OF_TASKS_SHIFT 24 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16 +#define BMI_NUM_OF_DMAS_SHIFT 8 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0 + +/* others */ +#define BMI_FIFO_ALIGN 0x100 +#define FMAN_BMI_FIFO_UNITS 0x100 + + +/**************************************************************************//** + @Description QMI defines +*//***************************************************************************/ +/* masks */ +#define QMI_CFG_ENQ_EN 0x80000000 +#define QMI_CFG_DEQ_EN 0x40000000 +#define QMI_CFG_EN_COUNTERS 0x10000000 +#define QMI_CFG_SOFT_RESET 0x01000000 +#define QMI_CFG_DEQ_MASK 0x0000003F +#define QMI_CFG_ENQ_MASK 0x00003F00 + +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000 + +/* shifts */ +#define QMI_CFG_ENQ_SHIFT 8 +#define QMI_TAPC_TAP 22 + +#define QMI_GS_HALT_NOT_BUSY 0x00000002 + +/**************************************************************************//** + @Description IRAM defines +*//***************************************************************************/ +/* masks */ +#define IRAM_IADD_AIE 0x80000000 +#define IRAM_READY 0x80000000 + +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg); +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg); +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg); +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg); +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg); +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg); +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg); +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg); +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg); +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg); +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, + uint8_t event_reg_id); +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg); +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg); +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id); +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg); +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg, + uint8_t port_id); +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id); +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, + uint8_t port_id); +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id); +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, + uint8_t port_id); +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg); +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, + uint8_t reg_id); +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg); +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major, + uint8_t *minor); +uint32_t fman_get_counter(struct fman_rg *fman_rg, + enum fman_counters reg_name); +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg); + + +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg); +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id, + uint32_t enable_events); +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg, + uint8_t port_id, + uint8_t num_fman_ctrls, + uint32_t or_fman_ctrl); +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg, + uint8_t port_id, + bool independent_mode, + bool is_rx_port); +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val); +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val); +void fman_set_liodn_per_port(struct fman_rg *fman_rg, + uint8_t port_id, + uint16_t liodn_base, + uint16_t liodn_offset); +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint32_t size_of_fifo, + uint32_t extra_size_of_fifo); +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t num_of_tasks, + uint8_t num_of_extra_tasks); +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t num_of_open_dmas, + uint8_t num_of_extra_open_dmas, + uint8_t total_num_of_dmas); +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights); +int fman_set_exception(struct fman_rg *fman_rg, + enum fman_exceptions exception, + bool enable); +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write, + bool enable); +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri); +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg, + uint32_t congestion_group_id, + uint8_t piority_bit_map, + uint32_t reg_num); + + +void fman_defconfig(struct fman_cfg *cfg, bool is_master); +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg); +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg); +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg); +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg); +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg); +void fman_free_resources(struct fman_rg *fman_rg); +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg); +void fman_reset(struct fman_fpm_regs *fpm_rg); +void fman_resume(struct fman_fpm_regs *fpm_rg); + + +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg, + uint8_t count1ubit, + uint16_t fm_clk_freq); +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg); +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg); +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg); +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id); +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g); +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id); +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg); +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg); +int fman_modify_counter(struct fman_rg *fman_rg, + enum fman_counters reg_name, + uint32_t val); +void fman_force_intr(struct fman_rg *fman_rg, + enum fman_exceptions exception); +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg, + uint8_t port_id, + uint8_t base_storage_profile, + uint8_t log2_num_of_profiles); + +/**************************************************************************//** + @Description default values +*//***************************************************************************/ +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */ +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */ +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE +#define DEFAULT_AID_OVERRIDE FALSE +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM +#define DEFAULT_DMA_COMM_Q_LOW 0x2A +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT +#define DEFAULT_DMA_EN_EMERGENCY FALSE +#define DEFAULT_DMA_SOS_EMERGENCY 0 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */ +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0 +#define DEFAULT_DISP_LIMIT 0 +#define DEFAULT_PRS_DISP_TH 16 +#define DEFAULT_PLCR_DISP_TH 16 +#define DEFAULT_KG_DISP_TH 16 +#define DEFAULT_BMI_DISP_TH 16 +#define DEFAULT_QMI_ENQ_DISP_TH 16 +#define DEFAULT_QMI_DEQ_DISP_TH 16 +#define DEFAULT_FM_CTL1_DISP_TH 16 +#define DEFAULT_FM_CTL2_DISP_TH 16 +#define DEFAULT_TNUM_AGING_PERIOD 4 + + +#endif /* __FSL_FMAN_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec.h b/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec.h new file mode 100644 index 000000000000..6004e478081a --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec.h @@ -0,0 +1,1096 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_DTSEC_H +#define __FSL_FMAN_DTSEC_H + +#include "common/general.h" +#include "fsl_enet.h" + +/** + * DOC: dTSEC Init sequence + * + * To prepare dTSEC block for transfer use the following call sequence: + * + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its + * use is to obtain the default dTSEC configuration parameters. + * + * - Change dtsec configuration in &dtsec_cfg. This structure will be used + * to customize the dTSEC behavior. + * + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that + * dTSEC is initialized while both Tx and Rx are disabled. + * + * - fman_dtsec_set_mac_address() - Set the station address (mac address). + * This is used by dTSEC to match against received packets. + * + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters + * after the PHY establishes the link. + * + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and + * reception. + */ + +/** + * DOC: dTSEC Graceful stop + * + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop + * but return before this stop is complete. To query for graceful stop + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to + * enable graceful stop interrupts. + * + * To resume operation after graceful stop use fman_dtsec_start_tx() and + * fman_dtsec_start_rx(). + */ + +/** + * DOC: dTSEC interrupt handling + * + * This code does not provide an interrupt handler for dTSEC. Instead this + * handler should be implemented and registered to the operating system by the + * caller. Some primitives for accessing the event status and mask registers + * are provided. + * + * See "dTSEC Events" section for a list of events that dTSEC can generate. + */ + +/** + * DOC: dTSEC Events + * + * Interrupt events cause dTSEC event bits to be set. Software may poll the + * event register at any time to check for pending interrupts. If an event + * occurs and its corresponding enable bit is set in the interrupt mask + * register, the event also causes a hardware interrupt at the PIC. + * + * To poll for event status use the fman_dtsec_get_event() function. + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and + * fman_dtsec_disable_interrupt() functions. + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the + * serviced event bit. + * + * The following events may be signaled by dTSEC hardware: + * + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that + * a frame was received with length in excess of the MAC's maximum frame length + * register. + * + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause + * control frame was received while Rx pause frame handling is enabled. + * Also see fman_dtsec_handle_rx_pause(). + * + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB + * counters has exceeded the size of its register. + * + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now + * complete. The transmitter is in a stopped state, in which only pause frames + * can be transmitted. + * Also see fman_dtsec_stop_tx(). + * + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length + * has exceeded the value in the MAC's Maximum Frame Length register. + * + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit + * indicates that a control frame was transmitted. + * + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error + * occurred on the transmitted channel. This bit is set whenever any transmit + * error occurs which causes the dTSEC to discard all or part of a frame + * (LC, CRL, XFUN). + * + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision + * occurred beyond the collision window (slot time) in half-duplex mode. + * The frame is truncated with a bad CRC and the remainder of the frame + * is discarded. + * + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number + * of successive transmission collisions has exceeded the MAC's half-duplex + * register's retransmission maximum count. The frame is discarded without + * being transmitted and transmission of the next frame commences. This only + * occurs while in half-duplex mode. + * The number of retransmit attempts can be set in + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init(). + * + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the + * transmit FIFO became empty before the complete frame was transmitted. + * The frame is truncated with a bad CRC and the remainder of the frame is + * discarded. + * + * %DTSEC_IEVENT_MAG - TBD + * + * %DTSEC_IEVENT_MMRD - MII management read completion. + * + * %DTSEC_IEVENT_MMWR - MII management write completion. + * + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to + * know if the system has completed the stop and it is safe to write to receive + * registers (status, control or configuration registers) that are used by the + * system during normal operation. + * + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates + * that the dTSEC has detected a parity error on its stored transmit data, which + * is likely to compromise the validity of recently transferred frames. + * + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that + * the dTSEC has detected a parity error on its stored receive data, which is + * likely to compromise the validity of recently transferred frames. + */ +/* Interrupt Mask Register (IMASK) */ +#define DTSEC_IMASK_BREN 0x80000000 +#define DTSEC_IMASK_RXCEN 0x40000000 +#define DTSEC_IMASK_MSROEN 0x04000000 +#define DTSEC_IMASK_GTSCEN 0x02000000 +#define DTSEC_IMASK_BTEN 0x01000000 +#define DTSEC_IMASK_TXCEN 0x00800000 +#define DTSEC_IMASK_TXEEN 0x00400000 +#define DTSEC_IMASK_LCEN 0x00040000 +#define DTSEC_IMASK_CRLEN 0x00020000 +#define DTSEC_IMASK_XFUNEN 0x00010000 +#define DTSEC_IMASK_ABRTEN 0x00008000 +#define DTSEC_IMASK_IFERREN 0x00004000 +#define DTSEC_IMASK_MAGEN 0x00000800 +#define DTSEC_IMASK_MMRDEN 0x00000400 +#define DTSEC_IMASK_MMWREN 0x00000200 +#define DTSEC_IMASK_GRSCEN 0x00000100 +#define DTSEC_IMASK_TDPEEN 0x00000002 +#define DTSEC_IMASK_RDPEEN 0x00000001 + +#define DTSEC_EVENTS_MASK \ + ((uint32_t)(DTSEC_IMASK_BREN | \ + DTSEC_IMASK_RXCEN | \ + DTSEC_IMASK_BTEN | \ + DTSEC_IMASK_TXCEN | \ + DTSEC_IMASK_TXEEN | \ + DTSEC_IMASK_ABRTEN | \ + DTSEC_IMASK_LCEN | \ + DTSEC_IMASK_CRLEN | \ + DTSEC_IMASK_XFUNEN | \ + DTSEC_IMASK_IFERREN | \ + DTSEC_IMASK_MAGEN | \ + DTSEC_IMASK_TDPEEN | \ + DTSEC_IMASK_RDPEEN)) + +/* dtsec timestamp event bits */ +#define TMR_PEMASK_TSREEN 0x00010000 +#define TMR_PEVENT_TSRE 0x00010000 + +/* Group address bit indication */ +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL +/* size in bytes of L2 address */ +#define MAC_ADDRLEN 6 + +#define DEFAULT_HALFDUP_ON FALSE +#define DEFAULT_HALFDUP_RETRANSMIT 0xf +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE +#define DEFAULT_RX_DROP_BCAST FALSE +#define DEFAULT_RX_SHORT_FRM TRUE +#define DEFAULT_RX_LEN_CHECK FALSE +#define DEFAULT_TX_PAD_CRC TRUE +#define DEFAULT_TX_CRC FALSE +#define DEFAULT_RX_CTRL_ACC FALSE +#define DEFAULT_TX_PAUSE_TIME 0xf000 +#define DEFAULT_TBIPA 5 +#define DEFAULT_RX_PREPEND 0 +#define DEFAULT_PTP_TSU_EN TRUE +#define DEFAULT_PTP_EXCEPTION_EN TRUE +#define DEFAULT_PREAMBLE_LEN 7 +#define DEFAULT_RX_PREAMBLE FALSE +#define DEFAULT_TX_PREAMBLE FALSE +#define DEFAULT_LOOPBACK FALSE +#define DEFAULT_RX_TIME_STAMP_EN FALSE +#define DEFAULT_TX_TIME_STAMP_EN FALSE +#define DEFAULT_RX_FLOW TRUE +#define DEFAULT_TX_FLOW TRUE +#define DEFAULT_RX_GROUP_HASH_EXD FALSE +#define DEFAULT_TX_PAUSE_TIME_EXTD 0 +#define DEFAULT_RX_PROMISC FALSE +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50 +#define DEFAULT_BACK_TO_BACK_IPG 0x60 +#define DEFAULT_MAXIMUM_FRAME 0x600 +#define DEFAULT_TBI_PHY_ADDR 5 +#define DEFAULT_WAKE_ON_LAN FALSE + +/* register related defines (bits, field offsets..) */ +#define DTSEC_ID1_ID 0xffff0000 +#define DTSEC_ID1_REV_MJ 0x0000FF00 +#define DTSEC_ID1_REV_MN 0x000000ff + +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000 + +#define DTSEC_ECNTRL_CLRCNT 0x00004000 +#define DTSEC_ECNTRL_AUTOZ 0x00002000 +#define DTSEC_ECNTRL_STEN 0x00001000 +#define DTSEC_ECNTRL_CFG_RO 0x80000000 +#define DTSEC_ECNTRL_GMIIM 0x00000040 +#define DTSEC_ECNTRL_TBIM 0x00000020 +#define DTSEC_ECNTRL_SGMIIM 0x00000002 +#define DTSEC_ECNTRL_RPM 0x00000010 +#define DTSEC_ECNTRL_R100M 0x00000008 +#define DTSEC_ECNTRL_RMM 0x00000004 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001 + +#define DTSEC_TCTRL_THDF 0x00000800 +#define DTSEC_TCTRL_TTSE 0x00000040 +#define DTSEC_TCTRL_GTS 0x00000020 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010 + +/* PTV offsets */ +#define PTV_PTE_OFST 16 + +#define RCTRL_CFA 0x00008000 +#define RCTRL_GHTX 0x00000400 +#define RCTRL_RTSE 0x00000040 +#define RCTRL_GRS 0x00000020 +#define RCTRL_BC_REJ 0x00000010 +#define RCTRL_MPROM 0x00000008 +#define RCTRL_RSF 0x00000004 +#define RCTRL_UPROM 0x00000001 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM) + +#define TMR_CTL_ESFDP 0x00000800 +#define TMR_CTL_ESFDE 0x00000400 + +#define MACCFG1_SOFT_RESET 0x80000000 +#define MACCFG1_LOOPBACK 0x00000100 +#define MACCFG1_RX_FLOW 0x00000020 +#define MACCFG1_TX_FLOW 0x00000010 +#define MACCFG1_TX_EN 0x00000001 +#define MACCFG1_RX_EN 0x00000004 +#define MACCFG1_RESET_RxMC 0x00080000 +#define MACCFG1_RESET_TxMC 0x00040000 +#define MACCFG1_RESET_RxFUN 0x00020000 +#define MACCFG1_RESET_TxFUN 0x00010000 + +#define MACCFG2_NIBBLE_MODE 0x00000100 +#define MACCFG2_BYTE_MODE 0x00000200 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040 +#define MACCFG2_LENGTH_CHECK 0x00000010 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008 +#define MACCFG2_PAD_CRC_EN 0x00000004 +#define MACCFG2_CRC_EN 0x00000002 +#define MACCFG2_FULL_DUPLEX 0x00000001 + +#define PREAMBLE_LENGTH_SHIFT 12 + +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8 + +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F + +#define HAFDUP_ALT_BEB 0x00080000 +#define HAFDUP_BP_NO_BACKOFF 0x00040000 +#define HAFDUP_NO_BACKOFF 0x00020000 +#define HAFDUP_EXCESS_DEFER 0x00010000 +#define HAFDUP_COLLISION_WINDOW 0x000003ff + +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000 + +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */ + +/* CAR1/2 bits */ +#define DTSEC_CAR1_TR64 0x80000000 +#define DTSEC_CAR1_TR127 0x40000000 +#define DTSEC_CAR1_TR255 0x20000000 +#define DTSEC_CAR1_TR511 0x10000000 +#define DTSEC_CAR1_TRK1 0x08000000 +#define DTSEC_CAR1_TRMAX 0x04000000 +#define DTSEC_CAR1_TRMGV 0x02000000 + +#define DTSEC_CAR1_RBYT 0x00010000 +#define DTSEC_CAR1_RPKT 0x00008000 +#define DTSEC_CAR1_RFCS 0x00004000 +#define DTSEC_CAR1_RMCA 0x00002000 +#define DTSEC_CAR1_RBCA 0x00001000 +#define DTSEC_CAR1_RXCF 0x00000800 +#define DTSEC_CAR1_RXPF 0x00000400 +#define DTSEC_CAR1_RXUO 0x00000200 +#define DTSEC_CAR1_RALN 0x00000100 +#define DTSEC_CAR1_RFLR 0x00000080 +#define DTSEC_CAR1_RCDE 0x00000040 +#define DTSEC_CAR1_RCSE 0x00000020 +#define DTSEC_CAR1_RUND 0x00000010 +#define DTSEC_CAR1_ROVR 0x00000008 +#define DTSEC_CAR1_RFRG 0x00000004 +#define DTSEC_CAR1_RJBR 0x00000002 +#define DTSEC_CAR1_RDRP 0x00000001 + +#define DTSEC_CAR2_TJBR 0x00080000 +#define DTSEC_CAR2_TFCS 0x00040000 +#define DTSEC_CAR2_TXCF 0x00020000 +#define DTSEC_CAR2_TOVR 0x00010000 +#define DTSEC_CAR2_TUND 0x00008000 +#define DTSEC_CAR2_TFRG 0x00004000 +#define DTSEC_CAR2_TBYT 0x00002000 +#define DTSEC_CAR2_TPKT 0x00001000 +#define DTSEC_CAR2_TMCA 0x00000800 +#define DTSEC_CAR2_TBCA 0x00000400 +#define DTSEC_CAR2_TXPF 0x00000200 +#define DTSEC_CAR2_TDFR 0x00000100 +#define DTSEC_CAR2_TEDF 0x00000080 +#define DTSEC_CAR2_TSCL 0x00000040 +#define DTSEC_CAR2_TMCL 0x00000020 +#define DTSEC_CAR2_TLCL 0x00000010 +#define DTSEC_CAR2_TXCL 0x00000008 +#define DTSEC_CAR2_TNCL 0x00000004 +#define DTSEC_CAR2_TDRP 0x00000001 + +#define CAM1_ERRORS_ONLY \ + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \ + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \ + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \ + | DTSEC_CAR1_RDRP) + +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP) + +/* + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1 + * (or Ethernet) statistics. + */ +#define CAM1_MIB_GRP_1 \ + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\ + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\ + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \ + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \ + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX) + +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP) + +/* memory map */ + +struct dtsec_regs { + /* dTSEC General Control and Status Registers */ + uint32_t tsec_id; /* 0x000 ETSEC_ID register */ + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */ + uint32_t ievent; /* 0x008 Interrupt event register */ + uint32_t imask; /* 0x00C Interrupt mask register */ + uint32_t reserved0010[1]; + uint32_t ecntrl; /* 0x014 E control register */ + uint32_t ptv; /* 0x018 Pause time value register */ + uint32_t tbipa; /* 0x01C TBI PHY address register */ + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */ + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */ + uint32_t tmr_pemask; /* 0x028 Timer event mask register */ + uint32_t reserved002c[5]; + uint32_t tctrl; /* 0x040 Transmit control register */ + uint32_t reserved0044[3]; + uint32_t rctrl; /* 0x050 Receive control register */ + uint32_t reserved0054[11]; + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */ + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */ + uint32_t reserved00c0[16]; + uint32_t maccfg1; /* 0x100 MAC configuration #1 */ + uint32_t maccfg2; /* 0x104 MAC configuration #2 */ + uint32_t ipgifg; /* 0x108 IPG/IFG */ + uint32_t hafdup; /* 0x10C Half-duplex */ + uint32_t maxfrm; /* 0x110 Maximum frame */ + uint32_t reserved0114[10]; + uint32_t ifstat; /* 0x13C Interface status */ + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */ + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */ + struct { + uint32_t exact_match1; /* octets 1-4 */ + uint32_t exact_match2; /* octets 5-6 */ + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */ + uint32_t reserved01c0[16]; + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */ + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame + * counter */ + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame + * counter */ + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame + * counter */ + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame + * counter */ + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame + * counter */ + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good + * VLAN frame count */ + uint32_t rbyt; /* 0x21C receive byte counter */ + uint32_t rpkt; /* 0x220 receive packet counter */ + uint32_t rfcs; /* 0x224 receive FCS error counter */ + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */ + uint32_t rbca; /* 0x22C receive broadcast packet counter */ + uint32_t rxcf; /* 0x230 receive control frame packet counter */ + uint32_t rxpf; /* 0x234 receive pause frame packet counter */ + uint32_t rxuo; /* 0x238 receive unknown OP code counter */ + uint32_t raln; /* 0x23C receive alignment error counter */ + uint32_t rflr; /* 0x240 receive frame length error counter */ + uint32_t rcde; /* 0x244 receive code error counter */ + uint32_t rcse; /* 0x248 receive carrier sense error counter */ + uint32_t rund; /* 0x24C receive undersize packet counter */ + uint32_t rovr; /* 0x250 receive oversize packet counter */ + uint32_t rfrg; /* 0x254 receive fragments counter */ + uint32_t rjbr; /* 0x258 receive jabber counter */ + uint32_t rdrp; /* 0x25C receive drop */ + uint32_t tbyt; /* 0x260 transmit byte counter */ + uint32_t tpkt; /* 0x264 transmit packet counter */ + uint32_t tmca; /* 0x268 transmit multicast packet counter */ + uint32_t tbca; /* 0x26C transmit broadcast packet counter */ + uint32_t txpf; /* 0x270 transmit pause control frame counter */ + uint32_t tdfr; /* 0x274 transmit deferral packet counter */ + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */ + uint32_t tscl; /* 0x27C transmit single collision packet counter */ + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */ + uint32_t tlcl; /* 0x284 transmit late collision packet counter */ + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */ + uint32_t tncl; /* 0x28C transmit total collision counter */ + uint32_t reserved0290[1]; + uint32_t tdrp; /* 0x294 transmit drop frame counter */ + uint32_t tjbr; /* 0x298 transmit jabber frame counter */ + uint32_t tfcs; /* 0x29C transmit FCS error counter */ + uint32_t txcf; /* 0x2A0 transmit control frame counter */ + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */ + uint32_t tund; /* 0x2A8 transmit undersize frame counter */ + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */ + uint32_t car1; /* 0x2B0 carry register one register* */ + uint32_t car2; /* 0x2B4 carry register two register* */ + uint32_t cam1; /* 0x2B8 carry register one mask register */ + uint32_t cam2; /* 0x2BC carry register two mask register */ + uint32_t reserved02c0[848]; +}; + +/** + * struct dtsec_mib_grp_1_counters - MIB counter overflows + * + * @tr64: Transmit and Receive 64 byte frame count. Increment for each + * good or bad frame, of any type, transmitted or received, which + * is 64 bytes in length. + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for + * each good or bad frame of any type, transmitted or received, + * which is 65-127 bytes in length. + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments + * for each good or bad frame, of any type, transmitted or + * received, which is 128-255 bytes in length. + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments + * for each good or bad frame, of any type, transmitted or + * received, which is 256-511 bytes in length. + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments + * for each good or bad frame, of any type, transmitted or + * received, which is 512-1023 bytes in length. + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments + * for each good or bad frame, of any type, transmitted or + * received, which is 1024-1518 bytes in length. + * @rfrg: Receive fragments count. Increments for each received frame + * which is less than 64 bytes in length and contains an invalid + * FCS. This includes integral and non-integral lengths. + * @rjbr: Receive jabber count. Increments for received frames which + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an + * invalid FCS. This includes alignment errors. + * @rdrp: Receive dropped packets count. Increments for received frames + * which are streamed to system but are later dropped due to lack + * of system resources. Does not increment for frames rejected due + * to address filtering. + * @raln: Receive alignment error count. Increments for each received + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains + * an invalid FCS and is not an integral number of bytes. + * @rund: Receive undersize packet count. Increments each time a frame is + * received which is less than 64 bytes in length and contains a + * valid FCS and is otherwise well formed. This count does not + * include range length errors. + * @rovr: Receive oversize packet count. Increments each time a frame is + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and + * contains a valid FCS and is otherwise well formed. + * @rbyt: Receive byte count. Increments by the byte count of frames + * received, including those in bad packets, excluding preamble and + * SFD but including FCS bytes. + * @rpkt: Receive packet count. Increments for each received frame + * (including bad packets, all unicast, broadcast, and multicast + * packets). + * @rmca: Receive multicast packet count. Increments for each multicast + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or + * 1522 (VLAN), excluding broadcast frames. This count does not + * include range/length errors. + * @rbca: Receive broadcast packet count. Increments for each broadcast + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or + * 1522 (VLAN), excluding multicast frames. Does not include + * range/length errors. + * @tdrp: Transmit drop frame count. Increments each time a memory error + * or an underrun has occurred. + * @tncl: Transmit total collision counter. Increments by the number of + * collisions experienced during the transmission of a frame. Does + * not increment for aborted frames. + * + * The structure contains a group of dTSEC HW specific counters relating to the + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure + * is counting only the carry events of the corresponding HW counters. + * + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble + * and SFD but including FCS bytes. + */ +struct dtsec_mib_grp_1_counters { + uint64_t rdrp; + uint64_t tdrp; + uint64_t rbyt; + uint64_t rpkt; + uint64_t rbca; + uint64_t rmca; + uint64_t raln; + uint64_t rund; + uint64_t rovr; + uint64_t rfrg; + uint64_t rjbr; + uint64_t tncl; + uint64_t tr64; + uint64_t tr127; + uint64_t tr255; + uint64_t tr511; + uint64_t tr1k; + uint64_t trmax; +}; + +enum dtsec_stat_counters { + E_DTSEC_STAT_TR64, + E_DTSEC_STAT_TR127, + E_DTSEC_STAT_TR255, + E_DTSEC_STAT_TR511, + E_DTSEC_STAT_TR1K, + E_DTSEC_STAT_TRMAX, + E_DTSEC_STAT_TRMGV, + E_DTSEC_STAT_RBYT, + E_DTSEC_STAT_RPKT, + E_DTSEC_STAT_RMCA, + E_DTSEC_STAT_RBCA, + E_DTSEC_STAT_RXPF, + E_DTSEC_STAT_RALN, + E_DTSEC_STAT_RFLR, + E_DTSEC_STAT_RCDE, + E_DTSEC_STAT_RCSE, + E_DTSEC_STAT_RUND, + E_DTSEC_STAT_ROVR, + E_DTSEC_STAT_RFRG, + E_DTSEC_STAT_RJBR, + E_DTSEC_STAT_RDRP, + E_DTSEC_STAT_TFCS, + E_DTSEC_STAT_TBYT, + E_DTSEC_STAT_TPKT, + E_DTSEC_STAT_TMCA, + E_DTSEC_STAT_TBCA, + E_DTSEC_STAT_TXPF, + E_DTSEC_STAT_TNCL, + E_DTSEC_STAT_TDRP +}; + +enum dtsec_stat_level { + /* No statistics */ + E_MAC_STAT_NONE = 0, + /* Only RMON MIB group 1 (ether stats). Optimized for performance */ + E_MAC_STAT_MIB_GRP1, + /* Only error counters are available. Optimized for performance */ + E_MAC_STAT_PARTIAL, + /* All counters available. Not optimized for performance */ + E_MAC_STAT_FULL +}; + + +/** + * struct dtsec_cfg - dTSEC configuration + * + * @halfdup_on: Transmit half-duplex flow control, under software + * control for 10/100-Mbps half-duplex media. If set, + * back pressure is applied to media by raising carrier. + * @halfdup_retransmit: Number of retransmission attempts following a collision. + * If this is exceeded dTSEC aborts transmission due to + * excessive collisions. The standard specifies the + * attempt limit to be 15. + * @halfdup_coll_window:The number of bytes of the frame during which + * collisions may occur. The default value of 55 + * corresponds to the frame byte at the end of the + * standard 512-bit slot time window. If collisions are + * detected after this byte, the late collision event is + * asserted and transmission of current frame is aborted. + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames + * will be discarded by dTSEC. + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames + * of length 14..63 bytes. + * @rx_len_check: Length check for received frames. If set, the MAC + * checks the frame's length field on receive to ensure it + * matches the actual data field length. This only works + * for received frames with length field less than 1500. + * No check is performed for larger frames. + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all + * transmitted short frames and appends a CRC to every + * frame regardless of padding requirement. + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC + * to all frames. If frames presented to the MAC have a + * valid length and contain a valid CRC, @tx_crc should be + * reset. + * This field is ignored if @tx_pad_crc is set. + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3 + * standard control frame behavior, and all Ethernet frames + * that have an ethertype of 0x8808 are treated as normal + * Ethernet frames and passed up to the packet interface on + * a DA match. Received pause control frames are passed to + * the packet interface only if Rx flow control is also + * disabled. See fman_dtsec_handle_rx_pause() function. + * @tx_pause_time: Transmit pause time value. This pause value is used as + * part of the pause frame to be sent when a transmit pause + * frame is initiated. If set to 0 this disables + * transmission of pause frames. + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the + * received Ethernet 7-byte preamble and passes it to the + * packet interface at the start of each received frame. + * This field should be reset for internal MAC loop-back + * mode. + * @tx_preamble: User defined preamble enable for transmitted frames. + * If set, a user-defined preamble must passed to the MAC + * and it is transmitted instead of the standard preamble. + * @preamble_len: Length, in bytes, of the preamble field preceding each + * Ethernet start-of-frame delimiter byte. The default + * value of 0x7 should be used in order to guarantee + * reliable operation with IEEE 802.3 compliant hardware. + * @rx_prepend: Packet alignment padding length. The specified number + * of bytes (1-31) of zero padding are inserted before the + * start of each received frame. For Ethernet, where + * optional preamble extraction is enabled, the padding + * appears before the preamble, otherwise the padding + * precedes the layer 2 header. + * + * This structure contains basic dTSEC configuration and must be passed to + * fman_dtsec_init() function. A default set of configuration values can be + * obtained by calling fman_dtsec_defconfig(). + */ +struct dtsec_cfg { + bool halfdup_on; + bool halfdup_alt_backoff_en; + bool halfdup_excess_defer; + bool halfdup_no_backoff; + bool halfdup_bp_no_backoff; + uint8_t halfdup_alt_backoff_val; + uint16_t halfdup_retransmit; + uint16_t halfdup_coll_window; + bool rx_drop_bcast; + bool rx_short_frm; + bool rx_len_check; + bool tx_pad_crc; + bool tx_crc; + bool rx_ctrl_acc; + unsigned short tx_pause_time; + unsigned short tbipa; + bool ptp_tsu_en; + bool ptp_exception_en; + bool rx_preamble; + bool tx_preamble; + unsigned char preamble_len; + unsigned char rx_prepend; + bool loopback; + bool rx_time_stamp_en; + bool tx_time_stamp_en; + bool rx_flow; + bool tx_flow; + bool rx_group_hash_exd; + bool rx_promisc; + uint8_t tbi_phy_addr; + uint16_t tx_pause_time_extd; + uint16_t maximum_frame; + uint32_t non_back_to_back_ipg1; + uint32_t non_back_to_back_ipg2; + uint32_t min_ifg_enforcement; + uint32_t back_to_back_ipg; + bool wake_on_lan; +}; + + +/** + * fman_dtsec_defconfig() - Get default dTSEC configuration + * @cfg: pointer to configuration structure. + * + * Call this function to obtain a default set of configuration values for + * initializing dTSEC. The user can overwrite any of the values before calling + * fman_dtsec_init(), if specific configuration needs to be applied. + */ +void fman_dtsec_defconfig(struct dtsec_cfg *cfg); + +/** + * fman_dtsec_init() - Init dTSEC hardware block + * @regs: Pointer to dTSEC register block + * @cfg: dTSEC configuration data + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface. + * @iface_speed: 1G or 10G + * @macaddr: MAC station address to be assigned to the device + * @fm_rev_maj: major rev number + * @fm_rev_min: minor rev number + * @exceptions_mask: initial exceptions mask + * + * This function initializes dTSEC and applies basic configuration. + * + * dTSEC initialization sequence: + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address, + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception. + * + * Returns: 0 if successful, an error code otherwise. + */ +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg, + enum enet_interface iface_mode, + enum enet_speed iface_speed, + uint8_t *macaddr, uint8_t fm_rev_maj, + uint8_t fm_rev_min, + uint32_t exception_mask); + +/** + * fman_dtsec_enable() - Enable dTSEC Tx and Tx + * @regs: Pointer to dTSEC register block + * @apply_rx: enable rx side + * @apply_tx: enable tx side + * + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx. + */ +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); + +/** + * fman_dtsec_disable() - Disable dTSEC Tx and Rx + * @regs: Pointer to dTSEC register block + * @apply_rx: disable rx side + * @apply_tx: disable tx side + * + * This function disables Tx and Rx in dTSEC. + */ +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); + +/** + * fman_dtsec_get_revision() - Get dTSEC hardware revision + * @regs: Pointer to dTSEC register block + * + * Returns dtsec_id content + * + * Call this function to obtain the dTSEC hardware version. + */ +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs); + +/** + * fman_dtsec_set_mac_address() - Set MAC station address + * @regs: Pointer to dTSEC register block + * @macaddr: MAC address array + * + * This function sets MAC station address. To enable unicast reception call + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will + * match the destination address of received unicast frames against this + * address. + */ +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); + +/** + * fman_dtsec_get_mac_address() - Query MAC station address + * @regs: Pointer to dTSEC register block + * @macaddr: MAC address array + */ +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); + +/** + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode + * @regs: Pointer to dTSEC register block + * @enable: Enable unicast promiscuous mode + * + * Use this function to enable/disable dTSEC L2 address filtering. If the + * address filtering is disabled all unicast packets are accepted. + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and + * multicast addresses. + */ +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable); + +/** + * fman_dtsec_set_wol() - Enable/Disable wake on lan + * (magic packet support) + * @regs: Pointer to dTSEC register block + * @en: Enable Wake On Lan support in dTSEC + * + */ +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en); + +/** + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings + * @regs: Pointer to dTSEC register block + * @iface_mode: dTSEC interface mode + * @speed: Link speed + * @full_dx: True for full-duplex, false for half-duplex. + * + * This function configures the MAC to function and the desired rates. Use it + * to configure dTSEC after fman_dtsec_init() and whenever the link speed + * changes (for instance following PHY auto-negociation). + * + * Returns: 0 if successful, an error code otherwise. + */ +int fman_dtsec_adjust_link(struct dtsec_regs *regs, + enum enet_interface iface_mode, + enum enet_speed speed, bool full_dx); + +/** + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field + * @regs: Pointer to dTSEC register block + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved. + * + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address + * so that the associated TBI PHY (i.e. the link) may be initialized. + * + * Returns: 0 if successful, an error code otherwise. + */ +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs, + uint8_t addr); + +/** + * fman_dtsec_set_max_frame_len() - Set max frame length + * @regs: Pointer to dTSEC register block + * @length: Max frame length. + * + * Sets maximum frame length for received and transmitted frames. Frames that + * exceeds this length are truncated. + */ +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length); + +/** + * fman_dtsec_get_max_frame_len() - Query max frame length + * @regs: Pointer to dTSEC register block + * + * Returns: the current value of the maximum frame length. + */ +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs); + +/** + * fman_dtsec_handle_rx_pause() - Configure pause frame handling + * @regs: Pointer to dTSEC register block + * @en: Enable pause frame handling in dTSEC + * + * If enabled, dTSEC will handle pause frames internally. This must be disabled + * if dTSEC is set in half-duplex mode. + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause + * frames will be transferred to the packet interface just like regular Ethernet + * frames. + */ +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en); + +/** + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time + * @regs: Pointer to dTSEC register block + * @time: Time value included in pause frames + * + * Call this function to set the time value used in transmitted pause frames. + * If time is 0, transmission of pause frames is disabled + */ +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time); + +/** + * fman_dtsec_ack_event() - Acknowledge handled events + * @regs: Pointer to dTSEC register block + * @ev_mask: Events to acknowledge + * + * After handling events signaled by dTSEC in either polling or interrupt mode, + * call this function to reset the associated status bits in dTSEC event + * register. + */ +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask); + +/** + * fman_dtsec_get_event() - Returns currently asserted events + * @regs: Pointer to dTSEC register block + * @ev_mask: Mask of relevant events + * + * Call this function to obtain a bit-mask of events that are currently asserted + * in dTSEC, taken from IEVENT register. + * + * Returns: a bit-mask of events asserted in dTSEC. + */ +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask); + +/** + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts + * @regs: Pointer to dTSEC register block + * + * Call this function to obtain a bit-mask of enabled interrupts + * in dTSEC, taken from IMASK register. + * + * Returns: a bit-mask of enabled interrupts in dTSEC. + */ +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs); + +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, + uint8_t paddr_num); + +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs, + uint64_t addr, + uint8_t paddr_num); + +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs); + +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs); + +/** + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events + * @regs: Pointer to dTSEC register block + * @ev_mask: Mask of relevant events + * + * Call this function to disable interrupts in dTSEC for the specified events. + * To enable interrupts use fman_dtsec_enable_interrupt(). + */ +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); + +/** + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events + * @regs: Pointer to dTSEC register block + * @ev_mask: Mask of relevant events + * + * Call this function to enable interrupts in dTSEC for the specified events. + * To disable interrupts use fman_dtsec_disable_interrupt(). + */ +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); + +/** + * fman_dtsec_set_ts() - Enables dTSEC timestamps + * @regs: Pointer to dTSEC register block + * @en: true to enable timestamps, false to disable them + * + * Call this function to enable/disable dTSEC timestamps. This affects both + * Tx and Rx. + */ +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en); + +/** + * fman_dtsec_set_bucket() - Enables/disables a filter bucket + * @regs: Pointer to dTSEC register block + * @bucket: Bucket index + * @enable: true/false to enable/disable this bucket + * + * This function enables or disables the specified bucket. Enabling a bucket + * associated with an address configures dTSEC to accept received packets + * with that destination address. + * Multiple addresses may be associated with the same bucket. Disabling a + * bucket will affect all addresses associated with that bucket. A bucket that + * is enabled requires further filtering and verification in the upper layers + * + */ +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable); + +/** + * dtsec_set_hash_table() - insert a crc code into thr filter table + * @regs: Pointer to dTSEC register block + * @crc: crc to insert + * @mcast: true is this is a multicast address + * @ghtx: true if we are in ghtx mode + * + * This function inserts a crc code into the filter table. + */ +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, + bool mcast, bool ghtx); + +/** + * fman_dtsec_reset_filter_table() - Resets the address filtering table + * @regs: Pointer to dTSEC register block + * @mcast: Reset multicast entries + * @ucast: Reset unicast entries + * + * Resets all entries in L2 address filter table. After calling this function + * all buckets enabled using fman_dtsec_set_bucket() will be disabled. + * If dtsec_init_filter_table() was called with @unicast_hash set to false, + * @ucast argument is ignored. + * This does not affect the primary nor the 15 additional addresses configured + * using dtsec_set_address() or dtsec_set_match_address(). + */ +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, + bool ucast); + +/** + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode + * @regs: Pointer to dTSEC register block + * @enable: Enable multicast promiscuous mode + * + * Call this to enable/disable L2 address filtering for multicast packets. + */ +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable); + +/* statistics APIs */ + +/** + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters + * @regs: Pointer to dTSEC register block + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_, + * to specify all the existing counters. + * If set to _none_, it disables all the counters. + * + * Enables the MIB statistics hw counters and sets up the carry interrupt + * masks for the counters corresponding to the @level input parameter. + * + * Returns: error if invalid @level value given. + */ +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, + enum dtsec_stat_level level); + +/** + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters + * @regs: Pointer to dTSEC register block + */ +void fman_dtsec_reset_stat(struct dtsec_regs *regs); + +/** + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers) + * @regs: Pointer to dTSEC register block + * @car1: car1 register value + * @car2: car2 register value + * + * When set, the carry bits signal that an overflow occurred on the + * corresponding counters. + * Note that the carry bits (CAR1-2 registers) will assert the + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs). + * + * Returns: true if overflow occurred, otherwise - false + */ +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs, + uint32_t *car1, uint32_t *car2); + +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs); + +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs, + enum dtsec_stat_counters reg_name); + +void fman_dtsec_start_tx(struct dtsec_regs *regs); +void fman_dtsec_start_rx(struct dtsec_regs *regs); +void fman_dtsec_stop_tx(struct dtsec_regs *regs); +void fman_dtsec_stop_rx(struct dtsec_regs *regs); +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs); + + +#endif /* __FSL_FMAN_DTSEC_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec_mii_acc.h b/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec_mii_acc.h new file mode 100644 index 000000000000..0dda09c3c388 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_dtsec_mii_acc.h @@ -0,0 +1,107 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H +#define __FSL_FMAN_DTSEC_MII_ACC_H + +#include "common/general.h" + + +/* MII Management Configuration Register */ +#define MIIMCFG_RESET_MGMT 0x80000000 +#define MIIMCFG_MGNTCLK_MASK 0x00000007 +#define MIIMCFG_MGNTCLK_SHIFT 0 + +/* MII Management Command Register */ +#define MIIMCOM_SCAN_CYCLE 0x00000002 +#define MIIMCOM_READ_CYCLE 0x00000001 + +/* MII Management Address Register */ +#define MIIMADD_PHY_ADDR_SHIFT 8 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00 + +#define MIIMADD_REG_ADDR_SHIFT 0 +#define MIIMADD_REG_ADDR_MASK 0x0000001f + +/* MII Management Indicator Register */ +#define MIIMIND_BUSY 0x00000001 + + +/* PHY Control Register */ +#define PHY_CR_PHY_RESET 0x8000 +#define PHY_CR_LOOPBACK 0x4000 +#define PHY_CR_SPEED0 0x2000 +#define PHY_CR_ANE 0x1000 +#define PHY_CR_RESET_AN 0x0200 +#define PHY_CR_FULLDUPLEX 0x0100 +#define PHY_CR_SPEED1 0x0040 + +#define PHY_TBICON_SRESET 0x8000 +#define PHY_TBICON_SPEED2 0x0020 +#define PHY_TBICON_CLK_SEL 0x0020 +#define PHY_TBIANA_SGMII 0x4001 +#define PHY_TBIANA_1000X 0x01a0 +/* register map */ + +/* MII Configuration Control Memory Map Registers */ +struct dtsec_mii_reg { + uint32_t reserved1[72]; + uint32_t miimcfg; /* MII Mgmt:configuration */ + uint32_t miimcom; /* MII Mgmt:command */ + uint32_t miimadd; /* MII Mgmt:address */ + uint32_t miimcon; /* MII Mgmt:control 3 */ + uint32_t miimstat; /* MII Mgmt:status */ + uint32_t miimind; /* MII Mgmt:indicators */ +}; + +/* dTSEC MII API */ + +/* functions to access the mii registers for phy configuration. + * this functionality may not be available for all dtsecs in the system. + * consult the reference manual for details */ +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs); +/* frequency is in MHz. + * note that dtsec clock is 1/2 of fman clock */ +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq); +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, + uint8_t addr, + uint8_t reg, + uint16_t data, + uint16_t dtsec_freq); + +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, + uint8_t addr, + uint8_t reg, + uint16_t *data, + uint16_t dtsec_freq); + +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_kg.h b/sys/contrib/ncsw/inc/flib/fsl_fman_kg.h new file mode 100644 index 000000000000..010e4b709d63 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_kg.h @@ -0,0 +1,514 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_KG_H +#define __FSL_FMAN_KG_H + +#include "common/general.h" + +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */ +#define FMAN_MAX_NUM_OF_HW_PORTS 64 +/**< Total num of masks allowed on KG extractions */ +#define FM_KG_EXTRACT_MASKS_NUM 4 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */ +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */ + +struct fman_kg_regs { + uint32_t fmkg_gcr; + uint32_t res004; + uint32_t res008; + uint32_t fmkg_eer; + uint32_t fmkg_eeer; + uint32_t res014; + uint32_t res018; + uint32_t fmkg_seer; + uint32_t fmkg_seeer; + uint32_t fmkg_gsr; + uint32_t fmkg_tpc; + uint32_t fmkg_serc; + uint32_t res030[4]; + uint32_t fmkg_fdor; + uint32_t fmkg_gdv0r; + uint32_t fmkg_gdv1r; + uint32_t res04c[6]; + uint32_t fmkg_feer; + uint32_t res068[38]; + uint32_t fmkg_indirect[63]; + uint32_t fmkg_ar; +}; + +struct fman_kg_scheme_regs { + uint32_t kgse_mode; /**< MODE */ + uint32_t kgse_ekfc; /**< Extract Known Fields Command */ + uint32_t kgse_ekdv; /**< Extract Known Default Value */ + uint32_t kgse_bmch; /**< Bit Mask Command High */ + uint32_t kgse_bmcl; /**< Bit Mask Command Low */ + uint32_t kgse_fqb; /**< Frame Queue Base */ + uint32_t kgse_hc; /**< Hash Command */ + uint32_t kgse_ppc; /**< Policer Profile Command */ + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS]; + /**< Generic Extract Command */ + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */ + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */ + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */ + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/ + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */ + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */ + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */ +}; + +struct fman_kg_pe_regs{ + uint32_t fmkg_pe_sp; + uint32_t fmkg_pe_cpp; +}; + +struct fman_kg_cp_regs { + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR]; +}; + + +#define FM_KG_KGAR_GO 0x80000000 +#define FM_KG_KGAR_READ 0x40000000 +#define FM_KG_KGAR_WRITE 0x00000000 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000 + +#define KG_SCH_PP_SHIFT_HIGH 0x80000000 +#define KG_SCH_PP_NO_GEN 0x10000000 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000 +#define KG_SCH_MODE_NIA_PLCR 0x40000000 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 +#define KG_SCH_BITMASK_MASK 0x000000FF +#define KG_SCH_GEN_VALID 0x80000000 +#define KG_SCH_GEN_MASK 0x00FF0000 +#define FM_PCD_KG_KGAR_ERR 0x20000000 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000 + +#define FM_EX_KG_DOUBLE_ECC 0x80000000 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000 + +/* ECC capture register */ +#define KG_FMKG_SERC_CAP 0x80000000 +#define KG_FMKG_SERC_CET 0x40000000 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000 +#define KG_FMKG_SERC_CNT_SHIFT 16 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF + +/* Masks */ +#define FM_KG_KGGCR_EN 0x80000000 +#define KG_SCH_GEN_VALID 0x80000000 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 +#define KG_ERR_TYPE_DOUBLE 0x40000000 +#define KG_ERR_ADDR_MASK 0x00000FFF +#define KG_SCH_MODE_EN 0x80000000 + +/* shifts */ +#define FM_KG_KGAR_NUM_SHIFT 16 +#define FM_KG_PE_CPP_MASK_SHIFT 16 +#define FM_KG_KGAR_WSEL_SHIFT 8 + +#define FM_KG_SCH_GEN_HT_INVALID 0 + +#define FM_KG_MASK_SEL_GEN_BASE 0x20 + +#define KG_GET_MASK_SEL_SHIFT(shift, i) \ +switch (i) \ +{ \ + case 0: (shift) = 26; break; \ + case 1: (shift) = 20; break; \ + case 2: (shift) = 10; break; \ + case 3: (shift) = 4; break; \ + default: (shift) = 0; \ +} + +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \ +switch (i) \ +{ \ + case 0: (shift) = 16; break; \ + case 1: (shift) = 0; break; \ + case 2: (shift) = 28; break; \ + case 3: (shift) = 24; break; \ + default: (shift) = 0; \ +} + +#define KG_GET_MASK_SHIFT(shift, i) \ +switch (i) \ +{ \ + case 0: shift = 24; break; \ + case 1: shift = 16; break; \ + case 2: shift = 8; break; \ + case 3: shift = 0; break; \ + default: shift = 0; \ +} + +/* Port entry CPP register */ +#define FMAN_KG_PE_CPP_MASK_SHIFT 16 + +/* Scheme registers */ +#define FMAN_KG_SCH_MODE_EN 0x80000000 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24 + +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6 + +#define FMAN_KG_SCH_GEN_VALID 0x80000000 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16 +#define FMAN_KG_SCH_GEN_OR 0x00008000 + +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8 + +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28 +#define FMAN_KG_SCH_HASH_SYM 0x40000000 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000 + +#define FMAN_KG_SCH_PP_SH_SHIFT 27 +#define FMAN_KG_SCH_PP_SL_SHIFT 12 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000 + +enum fman_kg_gen_extract_src { + E_FMAN_KG_GEN_EXTRACT_ETH, + E_FMAN_KG_GEN_EXTRACT_ETYPE, + E_FMAN_KG_GEN_EXTRACT_SNAP, + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1, + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N, + E_FMAN_KG_GEN_EXTRACT_PPPoE, + E_FMAN_KG_GEN_EXTRACT_MPLS_1, + E_FMAN_KG_GEN_EXTRACT_MPLS_2, + E_FMAN_KG_GEN_EXTRACT_MPLS_3, + E_FMAN_KG_GEN_EXTRACT_MPLS_N, + E_FMAN_KG_GEN_EXTRACT_IPv4_1, + E_FMAN_KG_GEN_EXTRACT_IPv6_1, + E_FMAN_KG_GEN_EXTRACT_IPv4_2, + E_FMAN_KG_GEN_EXTRACT_IPv6_2, + E_FMAN_KG_GEN_EXTRACT_MINENCAP, + E_FMAN_KG_GEN_EXTRACT_IP_PID, + E_FMAN_KG_GEN_EXTRACT_GRE, + E_FMAN_KG_GEN_EXTRACT_TCP, + E_FMAN_KG_GEN_EXTRACT_UDP, + E_FMAN_KG_GEN_EXTRACT_SCTP, + E_FMAN_KG_GEN_EXTRACT_DCCP, + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH, + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP, + E_FMAN_KG_GEN_EXTRACT_SHIM_1, + E_FMAN_KG_GEN_EXTRACT_SHIM_2, + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT, + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START, + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT, + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE, + E_FMAN_KG_GEN_EXTRACT_FROM_FQID +}; + +struct fman_kg_ex_ecc_attr +{ + bool valid; + bool double_ecc; + uint16_t addr; + uint8_t single_ecc_count; +}; + +enum fman_kg_def_select +{ + E_FMAN_KG_DEF_GLOBAL_0, + E_FMAN_KG_DEF_GLOBAL_1, + E_FMAN_KG_DEF_SCHEME_0, + E_FMAN_KG_DEF_SCHEME_1 +}; + +struct fman_kg_extract_def +{ + enum fman_kg_def_select mac_addr; + enum fman_kg_def_select vlan_tci; + enum fman_kg_def_select etype; + enum fman_kg_def_select ppp_sid; + enum fman_kg_def_select ppp_pid; + enum fman_kg_def_select mpls; + enum fman_kg_def_select ip_addr; + enum fman_kg_def_select ptype; + enum fman_kg_def_select ip_tos_tc; + enum fman_kg_def_select ipv6_fl; + enum fman_kg_def_select ipsec_spi; + enum fman_kg_def_select l4_port; + enum fman_kg_def_select tcp_flg; +}; + +enum fman_kg_gen_extract_type +{ + E_FMAN_KG_HASH_EXTRACT, + E_FMAN_KG_OR_EXTRACT +}; + +struct fman_kg_gen_extract_params +{ + /* Hash or Or-ed extract */ + enum fman_kg_gen_extract_type type; + enum fman_kg_gen_extract_src src; + bool no_validation; + /* Extraction offset from the header location specified above */ + uint8_t offset; + /* Size of extraction for FMAN_KG_HASH_EXTRACT, + * hash result shift for FMAN_KG_OR_EXTRACT */ + uint8_t extract; + uint8_t mask; + /* Default value to use when header specified + * by fman_kg_gen_extract_src doesn't present */ + enum fman_kg_def_select def_val; +}; + +struct fman_kg_extract_mask +{ + /**< Indication if mask is on known field extraction or + * on general extraction; TRUE for known field */ + bool is_known; + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and + * generic register index for generic extracts mask */ + uint32_t field_or_gen_idx; + /**< Byte offset from start of the extracted data specified + * by field_or_gen_idx */ + uint8_t offset; + /**< Byte mask (selected bits will be used) */ + uint8_t mask; +}; + +struct fman_kg_extract_params +{ + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */ + uint32_t known_fields; + struct fman_kg_extract_def known_fields_def; + /* Number of entries in gen_extract */ + uint8_t gen_extract_num; + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS]; + /* Number of entries in masks */ + uint8_t masks_num; + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM]; + uint32_t def_scheme_0; + uint32_t def_scheme_1; +}; + +struct fman_kg_hash_params +{ + bool use_hash; + uint8_t shift_r; + uint32_t mask; /**< 24-bit mask */ + bool sym; /**< Symmetric hash for src and dest pairs */ +}; + +struct fman_kg_pp_params +{ + uint8_t base; + uint8_t shift; + uint8_t mask; + bool bypass_pp_gen; +}; + +struct fman_kg_cc_params +{ + uint8_t base_offset; + uint32_t qlcv_bits_sel; +}; + +enum fman_pcd_engine +{ + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/ + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */ + E_FMAN_PCD_KG, /**< Keygen indicated */ + E_FMAN_PCD_CC, /**< Coarse classification indicated */ + E_FMAN_PCD_PLCR, /**< Policer indicated */ + E_FMAN_PCD_PRS /**< Parser indicated */ +}; + +struct fman_kg_cls_plan_params +{ + uint8_t entries_mask; + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR]; +}; + +struct fman_kg_scheme_params +{ + uint32_t match_vector; + struct fman_kg_extract_params extract_params; + struct fman_kg_hash_params hash_params; + uint32_t base_fqid; + /* What we do w/features supported per FM version ?? */ + bool bypass_fqid_gen; + struct fman_kg_pp_params policer_params; + struct fman_kg_cc_params cc_params; + bool update_counter; + /**< counter_value: Set scheme counter to the specified value; + * relevant only when update_counter = TRUE. */ + uint32_t counter_value; + enum fman_pcd_engine next_engine; + /**< Next engine action code */ + uint32_t next_engine_action; +}; + + + +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar); +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add); +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp); +void fman_kg_get_event(struct fman_kg_regs *regs, + uint32_t *event, + uint32_t *scheme_idx); +void fman_kg_init(struct fman_kg_regs *regs, + uint32_t exceptions, + uint32_t dflt_nia); +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs); +void fman_kg_enable(struct fman_kg_regs *regs); +void fman_kg_disable(struct fman_kg_regs *regs); +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs, + uint8_t hwport_id, + uint32_t bind_cls_plans); +int fman_kg_build_bind_cls_plans(uint8_t grp_base, + uint8_t grp_mask, + uint32_t *bind_cls_plans); +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs, + uint8_t hwport_id, + uint32_t schemes); +int fman_kg_write_cls_plan(struct fman_kg_regs *regs, + uint8_t grp_id, + uint8_t entries_mask, + uint8_t hwport_id, + struct fman_kg_cp_regs *cls_plan_regs); +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params, + struct fman_kg_cp_regs *cls_plan_regs); +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs); +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + uint32_t counter); +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + uint32_t *counter); +int fman_kg_delete_scheme(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id); +int fman_kg_write_scheme(struct fman_kg_regs *regs, + uint8_t scheme_id, + uint8_t hwport_id, + struct fman_kg_scheme_regs *scheme_regs, + bool update_counter); +int fman_kg_build_scheme(struct fman_kg_scheme_params *params, + struct fman_kg_scheme_regs *scheme_regs); +void fman_kg_get_capture(struct fman_kg_regs *regs, + struct fman_kg_ex_ecc_attr *ecc_attr, + bool clear); +void fman_kg_get_exception(struct fman_kg_regs *regs, + uint32_t *events, + uint32_t *scheme_ids, + bool clear); +void fman_kg_set_exception(struct fman_kg_regs *regs, + uint32_t exception, + bool enable); +void fman_kg_set_dflt_val(struct fman_kg_regs *regs, + uint8_t def_id, + uint32_t val); +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset); + + + +/**************************************************************************//** + @Description NIA Description +*//***************************************************************************/ +#define KG_NIA_ORDER_RESTOR 0x00800000 +#define KG_NIA_ENG_FM_CTL 0x00000000 +#define KG_NIA_ENG_PRS 0x00440000 +#define KG_NIA_ENG_KG 0x00480000 +#define KG_NIA_ENG_PLCR 0x004C0000 +#define KG_NIA_ENG_BMI 0x00500000 +#define KG_NIA_ENG_QMI_ENQ 0x00540000 +#define KG_NIA_ENG_QMI_DEQ 0x00580000 +#define KG_NIA_ENG_MASK 0x007C0000 + +#define KG_NIA_AC_MASK 0x0003FFFF + +#define KG_NIA_INVALID 0xFFFFFFFF + +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine, + uint32_t next_engine_action) +{ + uint32_t nia; + + if (next_engine_action & ~KG_NIA_AC_MASK) + return KG_NIA_INVALID; + + switch (next_engine) { + case E_FMAN_PCD_DONE: + nia = KG_NIA_ENG_BMI | next_engine_action; + break; + + case E_FMAN_PCD_KG: + nia = KG_NIA_ENG_KG | next_engine_action; + break; + + case E_FMAN_PCD_CC: + nia = KG_NIA_ENG_FM_CTL | next_engine_action; + break; + + case E_FMAN_PCD_PLCR: + nia = KG_NIA_ENG_PLCR | next_engine_action; + break; + + default: + nia = KG_NIA_INVALID; + } + + return nia; +} + +#endif /* __FSL_FMAN_KG_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_memac.h b/sys/contrib/ncsw/inc/flib/fsl_fman_memac.h new file mode 100644 index 000000000000..0dd8286bda93 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_memac.h @@ -0,0 +1,427 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +#ifndef __FSL_FMAN_MEMAC_H +#define __FSL_FMAN_MEMAC_H + +#include "common/general.h" +#include "fsl_enet.h" + + +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */ + +/* Control and Configuration Register (COMMAND_CONFIG) */ +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */ +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */ +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */ +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */ +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */ +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */ +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */ +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */ +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */ +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */ +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */ +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */ +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */ +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */ +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */ +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */ +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */ +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */ +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */ +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */ + +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */ +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060 + +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \ +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \ + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G)); + +#define GET_TX_EMPTY_PFC_VALUE(_val) \ +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \ + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G)); + +/* Interface Mode Register (IF_MODE) */ +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */ +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */ +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */ +#define IF_MODE_RGMII 0x00000004 +#define IF_MODE_RGMII_AUTO 0x00008000 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */ +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */ +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */ +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */ +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */ +#define IF_MODE_HD 0x00000040 /* Half duplex operation */ + +/* Hash table Control Register (HASHTABLE_CTRL) */ +#define HASH_CTRL_MCAST_SHIFT 26 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */ +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */ + +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */ +#define HASH_TABLE_SIZE 64 /* Hash tbl size */ + +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F + +/* Statistics Configuration Register (STATN_CONFIG) */ +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */ +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */ +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */ + +/* Interrupt Mask Register (IMASK) */ +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */ +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */ +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */ +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */ + +#define MEMAC_ALL_ERRS_IMASK \ + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \ + MEMAC_IMASK_TECC_ER | \ + MEMAC_IMASK_RECC_ER | \ + MEMAC_IMASK_MGI)) + +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */ +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */ +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */ +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */ +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */ +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */ +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */ +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */ +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */ +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */ +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */ +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */ +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */ +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */ +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */ +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */ +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */ + +enum memac_counters { + E_MEMAC_COUNTER_R64, + E_MEMAC_COUNTER_R127, + E_MEMAC_COUNTER_R255, + E_MEMAC_COUNTER_R511, + E_MEMAC_COUNTER_R1023, + E_MEMAC_COUNTER_R1518, + E_MEMAC_COUNTER_R1519X, + E_MEMAC_COUNTER_RFRG, + E_MEMAC_COUNTER_RJBR, + E_MEMAC_COUNTER_RDRP, + E_MEMAC_COUNTER_RALN, + E_MEMAC_COUNTER_TUND, + E_MEMAC_COUNTER_ROVR, + E_MEMAC_COUNTER_RXPF, + E_MEMAC_COUNTER_TXPF, + E_MEMAC_COUNTER_ROCT, + E_MEMAC_COUNTER_RMCA, + E_MEMAC_COUNTER_RBCA, + E_MEMAC_COUNTER_RPKT, + E_MEMAC_COUNTER_RUCA, + E_MEMAC_COUNTER_RERR, + E_MEMAC_COUNTER_TOCT, + E_MEMAC_COUNTER_TMCA, + E_MEMAC_COUNTER_TBCA, + E_MEMAC_COUNTER_TUCA, + E_MEMAC_COUNTER_TERR +}; + +#define DEFAULT_PAUSE_QUANTA 0xf000 +#define DEFAULT_FRAME_LENGTH 0x600 +#define DEFAULT_TX_IPG_LENGTH 12 + +/* + * memory map + */ + +struct mac_addr { + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */ + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */ +}; + +struct memac_regs { + /* General Control and Status */ + uint32_t res0000[2]; + uint32_t command_config; /* 0x008 Ctrl and cfg */ + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */ + uint32_t maxfrm; /* 0x014 Max frame length */ + uint32_t res0018[1]; + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */ + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */ + uint32_t res0024[2]; + uint32_t hashtable_ctrl; /* 0x02C Hash table control */ + uint32_t res0030[4]; + uint32_t ievent; /* 0x040 Interrupt event */ + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */ + uint32_t res0048; + uint32_t imask; /* 0x04C Interrupt mask */ + uint32_t res0050; + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */ + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */ + uint32_t rx_pause_status; /* 0x074 Receive pause status */ + uint32_t res0078[2]; + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */ + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */ + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */ + uint32_t res00c0[8]; + uint32_t statn_config; /* 0x0E0 Statistics configuration */ + uint32_t res00e4[7]; + /* Rx Statistics Counter */ + uint32_t reoct_l; + uint32_t reoct_u; + uint32_t roct_l; + uint32_t roct_u; + uint32_t raln_l; + uint32_t raln_u; + uint32_t rxpf_l; + uint32_t rxpf_u; + uint32_t rfrm_l; + uint32_t rfrm_u; + uint32_t rfcs_l; + uint32_t rfcs_u; + uint32_t rvlan_l; + uint32_t rvlan_u; + uint32_t rerr_l; + uint32_t rerr_u; + uint32_t ruca_l; + uint32_t ruca_u; + uint32_t rmca_l; + uint32_t rmca_u; + uint32_t rbca_l; + uint32_t rbca_u; + uint32_t rdrp_l; + uint32_t rdrp_u; + uint32_t rpkt_l; + uint32_t rpkt_u; + uint32_t rund_l; + uint32_t rund_u; + uint32_t r64_l; + uint32_t r64_u; + uint32_t r127_l; + uint32_t r127_u; + uint32_t r255_l; + uint32_t r255_u; + uint32_t r511_l; + uint32_t r511_u; + uint32_t r1023_l; + uint32_t r1023_u; + uint32_t r1518_l; + uint32_t r1518_u; + uint32_t r1519x_l; + uint32_t r1519x_u; + uint32_t rovr_l; + uint32_t rovr_u; + uint32_t rjbr_l; + uint32_t rjbr_u; + uint32_t rfrg_l; + uint32_t rfrg_u; + uint32_t rcnp_l; + uint32_t rcnp_u; + uint32_t rdrntp_l; + uint32_t rdrntp_u; + uint32_t res01d0[12]; + /* Tx Statistics Counter */ + uint32_t teoct_l; + uint32_t teoct_u; + uint32_t toct_l; + uint32_t toct_u; + uint32_t res0210[2]; + uint32_t txpf_l; + uint32_t txpf_u; + uint32_t tfrm_l; + uint32_t tfrm_u; + uint32_t tfcs_l; + uint32_t tfcs_u; + uint32_t tvlan_l; + uint32_t tvlan_u; + uint32_t terr_l; + uint32_t terr_u; + uint32_t tuca_l; + uint32_t tuca_u; + uint32_t tmca_l; + uint32_t tmca_u; + uint32_t tbca_l; + uint32_t tbca_u; + uint32_t res0258[2]; + uint32_t tpkt_l; + uint32_t tpkt_u; + uint32_t tund_l; + uint32_t tund_u; + uint32_t t64_l; + uint32_t t64_u; + uint32_t t127_l; + uint32_t t127_u; + uint32_t t255_l; + uint32_t t255_u; + uint32_t t511_l; + uint32_t t511_u; + uint32_t t1023_l; + uint32_t t1023_u; + uint32_t t1518_l; + uint32_t t1518_u; + uint32_t t1519x_l; + uint32_t t1519x_u; + uint32_t res02a8[6]; + uint32_t tcnp_l; + uint32_t tcnp_u; + uint32_t res02c8[14]; + /* Line Interface Control */ + uint32_t if_mode; /* 0x300 Interface Mode Control */ + uint32_t if_status; /* 0x304 Interface Status */ + uint32_t res0308[14]; + /* HiGig/2 */ + uint32_t hg_config; /* 0x340 Control and cfg */ + uint32_t res0344[3]; + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */ + uint32_t res0354[3]; + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */ + uint32_t res0364[3]; + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */ + uint32_t hg_fifos_status; /* 0x374 fifos status */ + uint32_t rhm; /* 0x378 rx messages counter */ + uint32_t thm; /* 0x37C tx messages counter */ +}; + +struct memac_cfg { + bool reset_on_init; + bool rx_error_discard; + bool pause_ignore; + bool pause_forward_enable; + bool no_length_check_enable; + bool cmd_frame_enable; + bool send_idle_enable; + bool wan_mode_enable; + bool promiscuous_mode_enable; + bool tx_addr_ins_enable; + bool loopback_enable; + bool lgth_check_nostdr; + bool time_stamp_enable; + bool pad_enable; + bool phy_tx_ena_on; + bool rx_sfd_any; + bool rx_pbl_fwd; + bool tx_pbl_fwd; + bool debug_mode; + bool wake_on_lan; + uint16_t max_frame_length; + uint16_t pause_quanta; + uint32_t tx_ipg_length; +}; + + +/** + * fman_memac_defconfig() - Get default MEMAC configuration + * @cfg: pointer to configuration structure. + * + * Call this function to obtain a default set of configuration values for + * initializing MEMAC. The user can overwrite any of the values before calling + * fman_memac_init(), if specific configuration needs to be applied. + */ +void fman_memac_defconfig(struct memac_cfg *cfg); + +int fman_memac_init(struct memac_regs *regs, + struct memac_cfg *cfg, + enum enet_interface enet_interface, + enum enet_speed enet_speed, + bool slow_10g_if, + uint32_t exceptions); + +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx); + +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx); + +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val); + +void fman_memac_add_addr_in_paddr(struct memac_regs *regs, + uint8_t *adr, + uint8_t paddr_num); + +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs, + uint8_t paddr_num); + +uint64_t fman_memac_get_counter(struct memac_regs *regs, + enum memac_counters reg_name); + +void fman_memac_set_tx_pause_frames(struct memac_regs *regs, + uint8_t priority, uint16_t pauseTime, uint16_t threshTime); + +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs); + +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, + bool enable); + +void fman_memac_reset_stat(struct memac_regs *regs); + +void fman_memac_reset(struct memac_regs *regs); + +void fman_memac_reset_filter_table(struct memac_regs *regs); + +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc); + +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val); + +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs, + bool enable); + +void fman_memac_set_wol(struct memac_regs *regs, bool enable); + +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask); + +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask); + +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs); + +void fman_memac_adjust_link(struct memac_regs *regs, + enum enet_interface iface_mode, + enum enet_speed speed, bool full_dx); + + + +#endif /*__FSL_FMAN_MEMAC_H*/ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_memac_mii_acc.h b/sys/contrib/ncsw/inc/flib/fsl_fman_memac_mii_acc.h new file mode 100755 index 000000000000..b43044501b80 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_memac_mii_acc.h @@ -0,0 +1,78 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H +#define __FSL_FMAN_MEMAC_MII_ACC_H + +#include "common/general.h" +#include "fsl_enet.h" +/* MII Management Registers */ +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80 +#define MDIO_CFG_CLK_DIV_SHIFT 7 +#define MDIO_CFG_HOLD_MASK 0x0000001c +#define MDIO_CFG_ENC45 0x00000040 +#define MDIO_CFG_READ_ERR 0x00000002 +#define MDIO_CFG_BSY 0x00000001 + +#define MDIO_CTL_PHY_ADDR_SHIFT 5 +#define MDIO_CTL_READ 0x00008000 + +#define MDIO_DATA_BSY 0x80000000 + +/*MEMAC Internal PHY Registers - SGMII */ +#define PHY_SGMII_CR_PHY_RESET 0x8000 +#define PHY_SGMII_CR_RESET_AN 0x0200 +#define PHY_SGMII_CR_DEF_VAL 0x1140 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0 +#define PHY_SGMII_IF_MODE_AN 0x0002 +#define PHY_SGMII_IF_MODE_SGMII 0x0001 +#define PHY_SGMII_IF_MODE_1000X 0x0000 + +/*----------------------------------------------------*/ +/* MII Configuration Control Memory Map Registers */ +/*----------------------------------------------------*/ +struct memac_mii_access_mem_map { + uint32_t mdio_cfg; /* 0x030 */ + uint32_t mdio_ctrl; /* 0x034 */ + uint32_t mdio_data; /* 0x038 */ + uint32_t mdio_addr; /* 0x03c */ +}; + +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t *data, + enum enet_speed enet_speed); +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs, + uint8_t phy_addr, uint8_t reg, uint16_t data, + enum enet_speed enet_speed); + +#endif /* __MAC_API_MEMAC_MII_ACC_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_port.h b/sys/contrib/ncsw/inc/flib/fsl_fman_port.h new file mode 100755 index 000000000000..080a23e963b9 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_port.h @@ -0,0 +1,593 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_PORT_H +#define __FSL_FMAN_PORT_H + +#include "fsl_fman_sp.h" + +/** @Collection Registers bit fields */ + +/** @Description BMI defines */ +#define BMI_EBD_EN 0x80000000 + +#define BMI_PORT_CFG_EN 0x80000000 +#define BMI_PORT_CFG_FDOVR 0x02000000 +#define BMI_PORT_CFG_IM 0x01000000 + +#define BMI_PORT_STATUS_BSY 0x80000000 + +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE + +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000 + +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24 +#define BMI_RX_FRAME_END_CUT_SHIFT 16 + +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT + +#define BMI_INT_BUF_MARG_SHIFT 28 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT + +#define BMI_CMD_MR_LEAC 0x00200000 +#define BMI_CMD_MR_SLEAC 0x00100000 +#define BMI_CMD_MR_MA 0x00080000 +#define BMI_CMD_MR_DEAS 0x00040000 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \ + BMI_CMD_MR_SLEAC | \ + BMI_CMD_MR_MA | \ + BMI_CMD_MR_DEAS) +#define BMI_CMD_TX_MR_DEF 0 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \ + BMI_CMD_MR_MA) + +#define BMI_CMD_ATTR_ORDER 0x80000000 +#define BMI_CMD_ATTR_SYNC 0x02000000 +#define BMI_CMD_ATTR_COLOR_SHIFT 26 + +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24 + +#define BMI_COUNTERS_EN 0x80000000 + +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP +#define BMI_EXT_BUF_POOL_ID_SHIFT 16 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16 + +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12 + +#define MAX_PERFORMANCE_TASK_COMP 64 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8 +#define MAX_PERFORMANCE_DMA_COMP 16 +#define MAX_PERFORMANCE_FIFO_COMP 1024 + +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12 + +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */ +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */ +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */ +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE + +/** @Description QMI defines */ +#define QMI_PORT_CFG_EN 0x80000000 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000 + +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000 + +#define QMI_DEQ_CFG_PRI 0x80000000 +#define QMI_DEQ_CFG_TYPE1 0x10000000 +#define QMI_DEQ_CFG_TYPE2 0x20000000 +#define QMI_DEQ_CFG_TYPE3 0x30000000 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000 +#define QMI_DEQ_CFG_SP_MASK 0xf +#define QMI_DEQ_CFG_SP_SHIFT 20 + + +/** @Description General port defines */ +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \ + (((fm_rev_maj) == 4) ? 4 : 8) +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2 +#define FMAN_PORT_CG_MAP_NUM 8 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10 + + +/** @Collection FM Port Register Map */ + +/** @Description BMI Rx port register map */ +struct fman_port_rx_bmi_regs { + uint32_t fmbm_rcfg; /**< Rx Configuration */ + uint32_t fmbm_rst; /**< Rx Status */ + uint32_t fmbm_rda; /**< Rx DMA attributes*/ + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/ + uint32_t fmbm_rfed; /**< Rx Frame End Data*/ + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/ + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/ + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/ + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/ + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/ + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/ + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/ + uint32_t fmbm_rpp; /**< Rx Policer Profile */ + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */ + uint32_t fmbm_reth; /**< Rx Excessive Threshold */ + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */ + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM]; + /**< Rx Parse Results Array Init*/ + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/ + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/ + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/ + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/ + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */ + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */ + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */ + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */ + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM]; + /**< Buffer Manager pool Information-*/ + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM]; + /**< Allocate Counter-*/ + uint32_t reserved0130[8]; + /**< 0x130/0x140 - 0x15F reserved -*/ + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM]; + /**< Congestion Group Map*/ + uint32_t fmbm_mpd; /**< BM Pool Depletion */ + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */ + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/ + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/ + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/ + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/ + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/ + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/ + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/ + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/ + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/ + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */ + uint32_t fmbm_rpc; /**< Rx Performance Counters*/ + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/ + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/ + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/ + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/ + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/ + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/ + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/ + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */ + uint32_t fmbm_rdbg; /**< Rx Debug-*/ +}; + +/** @Description BMI Tx port register map */ +struct fman_port_tx_bmi_regs { + uint32_t fmbm_tcfg; /**< Tx Configuration */ + uint32_t fmbm_tst; /**< Tx Status */ + uint32_t fmbm_tda; /**< Tx DMA attributes */ + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */ + uint32_t fmbm_tfed; /**< Tx Frame End Data */ + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */ + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */ + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */ + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */ + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */ + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */ + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */ + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */ + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */ + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */ + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */ + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */ + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */ + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */ + uint32_t fmbm_tstc; /**< Tx Statistics Counters */ + uint32_t fmbm_tfrc; /**< Tx Frame Counter */ + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */ + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */ + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/ + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */ + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */ + uint32_t fmbm_tpc; /**< Tx Performance Counters*/ + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/ + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/ + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/ + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/ + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/ + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/ +}; + +/** @Description BMI O/H port register map */ +struct fman_port_oh_bmi_regs { + uint32_t fmbm_ocfg; /**< O/H Configuration */ + uint32_t fmbm_ost; /**< O/H Status */ + uint32_t fmbm_oda; /**< O/H DMA attributes */ + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */ + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */ + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */ + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */ + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */ + uint32_t fmbm_opso; /**< O/H Parse Start Offset */ + uint32_t fmbm_opp; /**< O/H Policer Profile */ + uint32_t fmbm_occb; /**< O/H Coarse Classification base */ + uint32_t fmbm_oim; /**< O/H Internal margins*/ + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/ + uint32_t fmbm_ofed; /**< O/H Frame End Data*/ + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */ + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM]; + /**< O/H Parse Results Array Initialization */ + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */ + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */ + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */ + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */ + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */ + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */ + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */ + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */ + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */ + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */ + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */ + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */ + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */ + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */ + uint32_t fmbm_ostc; /**< O/H Statistics Counters */ + uint32_t fmbm_ofrc; /**< O/H Frame Counter */ + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */ + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */ + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */ + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */ + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */ + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */ + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */ + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */ + uint32_t fmbm_opc; /**< O/H Performance Counters */ + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */ + uint32_t fmbm_occn; /**< O/H Cycle Counter */ + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */ + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */ + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */ +}; + +/** @Description BMI port register map */ +union fman_port_bmi_regs { + struct fman_port_rx_bmi_regs rx; + struct fman_port_tx_bmi_regs tx; + struct fman_port_oh_bmi_regs oh; +}; + +/** @Description QMI port register map */ +struct fman_port_qmi_regs { + uint32_t fmqm_pnc; /**< PortID n Configuration Register */ + uint32_t fmqm_pns; /**< PortID n Status Register */ + uint32_t fmqm_pnts; /**< PortID n Task Status Register */ + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */ + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */ + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */ + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */ + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */ + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */ + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */ + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */ + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */ +}; + + +enum fman_port_dma_swap { + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */ + E_FMAN_PORT_DMA_SWAP_LE, + /**< The transferred data should be swapped in PPC Little Endian mode */ + E_FMAN_PORT_DMA_SWAP_BE + /**< The transferred data should be swapped in Big Endian mode */ +}; + +/* Default port color */ +enum fman_port_color { + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */ + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */ + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */ + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */ +}; + +/* QMI dequeue from the SP channel - types */ +enum fman_port_deq_type { + E_FMAN_PORT_DEQ_BY_PRI, + /**< Priority precedence and Intra-Class scheduling */ + E_FMAN_PORT_DEQ_ACTIVE_FQ, + /**< Active FQ precedence and Intra-Class scheduling */ + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS + /**< Active FQ precedence and override Intra-Class scheduling */ +}; + +/* QMI dequeue prefetch modes */ +enum fman_port_deq_prefetch { + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */ + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */ + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */ +}; + +/* Parameters for defining performance counters behavior */ +struct fman_port_perf_cnt_params { + uint8_t task_val; /**< Task compare value */ + uint8_t queue_val; + /**< Rx or Tx conf queue compare value (unused for O/H ports) */ + uint8_t dma_val; /**< Dma compare value */ + uint32_t fifo_val; /**< Fifo compare value (in bytes) */ +}; + +/** @Description FM Port configuration structure, used at init */ +struct fman_port_cfg { + struct fman_port_perf_cnt_params perf_cnt_params; + /* BMI parameters */ + enum fman_port_dma_swap dma_swap_data; + bool dma_ic_stash_on; + bool dma_header_stash_on; + bool dma_sg_stash_on; + bool dma_write_optimize; + uint16_t ic_ext_offset; + uint8_t ic_int_offset; + uint16_t ic_size; + enum fman_port_color color; + bool sync_req; + bool discard_override; + uint8_t checksum_bytes_ignore; + uint8_t rx_cut_end_bytes; + uint32_t rx_pri_elevation; + uint32_t rx_fifo_thr; + uint8_t rx_fd_bits; + uint8_t int_buf_start_margin; + uint16_t ext_buf_start_margin; + uint16_t ext_buf_end_margin; + uint32_t tx_fifo_min_level; + uint32_t tx_fifo_low_comf_level; + uint8_t tx_fifo_deq_pipeline_depth; + bool stats_counters_enable; + bool perf_counters_enable; + /* QMI parameters */ + bool deq_high_pri; + enum fman_port_deq_type deq_type; + enum fman_port_deq_prefetch deq_prefetch_opt; + uint16_t deq_byte_cnt; + bool queue_counters_enable; + bool no_scatter_gather; + int errata_A006675; + int errata_A006320; + int excessive_threshold_register; + int fmbm_rebm_has_sgd; + int fmbm_tfne_has_features; + int qmi_deq_options_support; +}; + +enum fman_port_type { + E_FMAN_PORT_TYPE_OP = 0, + /**< Offline parsing port, shares id-s with + * host command, so must have exclusive id-s */ + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */ + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */ + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */ + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */ + E_FMAN_PORT_TYPE_DUMMY, + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY + /**< Host command port, shares id-s with + * offline parsing ports, so must have exclusive id-s */ +}; + +struct fman_port_params { + uint32_t discard_mask; + uint32_t err_mask; + uint32_t dflt_fqid; + uint32_t err_fqid; + uint8_t deq_sp; + bool dont_release_buf; +}; + +/* Port context - used by most API functions */ +struct fman_port { + enum fman_port_type type; + uint8_t fm_rev_maj; + uint8_t fm_rev_min; + union fman_port_bmi_regs *bmi_regs; + struct fman_port_qmi_regs *qmi_regs; + bool im_en; + uint8_t ext_pools_num; +}; + +/** @Description External buffer pools configuration */ +struct fman_port_bpools { + uint8_t count; /**< Num of pools to set up */ + bool counters_enable; /**< Enable allocate counters */ + uint8_t grp_bp_depleted_num; + /**< Number of depleted pools - if reached the BMI indicates + * the MAC to send a pause frame */ + struct { + uint8_t bpid; /**< BM pool ID */ + uint16_t size; + /**< Pool's size - must be in ascending order */ + bool is_backup; + /**< If this is a backup pool */ + bool grp_bp_depleted; + /**< Consider this buffer in multiple pools depletion criteria*/ + bool single_bp_depleted; + /**< Consider this buffer in single pool depletion criteria */ + bool pfc_priorities_en; + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM]; +}; + +enum fman_port_rate_limiter_scale_down { + E_FMAN_PORT_RATE_DOWN_NONE, + E_FMAN_PORT_RATE_DOWN_BY_2, + E_FMAN_PORT_RATE_DOWN_BY_4, + E_FMAN_PORT_RATE_DOWN_BY_8 +}; + +/* Rate limiter configuration */ +struct fman_port_rate_limiter { + uint8_t count_1micro_bit; + bool high_burst_size_gran; + /**< Defines burst_size granularity for OP ports; when TRUE, + * burst_size below counts in frames, otherwise in 10^3 frames */ + uint16_t burst_size; + /**< Max burst size, in KBytes for Tx port, according to + * high_burst_size_gran definition for OP port */ + uint32_t rate; + /**< In Kbps for Tx port, in frames/sec for OP port */ + enum fman_port_rate_limiter_scale_down rate_factor; +}; + +/* BMI statistics counters */ +enum fman_port_stats_counters { + E_FMAN_PORT_STATS_CNT_FRAME, + /**< Number of processed frames; valid for all ports */ + E_FMAN_PORT_STATS_CNT_DISCARD, + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports - + * frames discarded due to DMA error; valid for all ports */ + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF, + /**< Number of buffer deallocate operations; valid for all ports */ + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME, + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc; + * valid for Rx ports only */ + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME, + /**< Number of Rx oversized frames, that is frames exceeding max frame + * size configured for the corresponding ETH controller; + * valid for Rx ports only */ + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF, + /**< Frames discarded due to lack of external buffers; valid for + * Rx ports only */ + E_FMAN_PORT_STATS_CNT_LEN_ERR, + /**< Frames discarded due to frame length error; valid for Tx and + * O/H ports only */ + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT, + /**< Frames discarded due to unsupported FD format; valid for Tx + * and O/H ports only */ + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME, + /**< Number of frames filtered out by PCD module; valid for + * Rx and OP ports only */ + E_FMAN_PORT_STATS_CNT_DMA_ERR, + /**< Frames rejected by QMAN that were not able to release their + * buffers due to DMA error; valid for Rx and O/H ports only */ + E_FMAN_PORT_STATS_CNT_WRED_DISCARD + /**< Frames going through O/H port that were not able to to enter the + * return queue due to WRED algorithm; valid for O/H ports only */ +}; + +/* BMI performance counters */ +enum fman_port_perf_counters { + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */ + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */ + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL, + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue + * utilization; not valid for O/H ports */ + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */ + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */ + E_FMAN_PORT_PERF_CNT_RX_PAUSE + /**< Number of cycles in which Rx pause activation control is on; + * valid for Rx ports only */ +}; + +/* QMI counters */ +enum fman_port_qmi_counters { + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */ + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */ + E_FMAN_PORT_DEQ_FROM_DFLT, + /**< Dequeue from default FQID counter not valid for Rx ports */ + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */ +}; + + +/** @Collection FM Port API */ +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type); +int fman_port_init(struct fman_port *port, + struct fman_port_cfg *cfg, + struct fman_port_params *params); +int fman_port_enable(struct fman_port *port); +int fman_port_disable(const struct fman_port *port); +int fman_port_set_bpools(const struct fman_port *port, + const struct fman_port_bpools *bp); +int fman_port_set_rate_limiter(struct fman_port *port, + struct fman_port_rate_limiter *rate_limiter); +int fman_port_delete_rate_limiter(struct fman_port *port); +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask); +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask); +int fman_port_modify_rx_fd_bits(struct fman_port *port, + uint8_t rx_fd_bits, + bool add); +int fman_port_set_perf_cnt_params(struct fman_port *port, + struct fman_port_perf_cnt_params *params); +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable); +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable); +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable); +int fman_port_set_bpool_cnt_mode(struct fman_port *port, + uint8_t bpid, + bool enable); +uint32_t fman_port_get_stats_counter(struct fman_port *port, + enum fman_port_stats_counters counter); +void fman_port_set_stats_counter(struct fman_port *port, + enum fman_port_stats_counters counter, + uint32_t value); +uint32_t fman_port_get_perf_counter(struct fman_port *port, + enum fman_port_perf_counters counter); +void fman_port_set_perf_counter(struct fman_port *port, + enum fman_port_perf_counters counter, + uint32_t value); +uint32_t fman_port_get_qmi_counter(struct fman_port *port, + enum fman_port_qmi_counters counter); +void fman_port_set_qmi_counter(struct fman_port *port, + enum fman_port_qmi_counters counter, + uint32_t value); +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid); +void fman_port_set_bpool_counter(struct fman_port *port, + uint8_t bpid, + uint32_t value); +int fman_port_add_congestion_grps(struct fman_port *port, + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]); +int fman_port_remove_congestion_grps(struct fman_port *port, + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]); + + +#endif /* __FSL_FMAN_PORT_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_prs.h b/sys/contrib/ncsw/inc/flib/fsl_fman_prs.h new file mode 100644 index 000000000000..b18997dc0b8a --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_prs.h @@ -0,0 +1,102 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_PRS_H +#define __FSL_FMAN_PRS_H + +#include "common/general.h" + +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000 + +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000 +#define PRS_MAX_CYCLE_LIMIT 8191 + +#define DEFAULT_MAX_PRS_CYC_LIM 0 + +struct fman_prs_regs { + uint32_t fmpr_rpclim; + uint32_t fmpr_rpimac; + uint32_t pmeec; + uint32_t res00c[5]; + uint32_t fmpr_pevr; + uint32_t fmpr_pever; + uint32_t res028; + uint32_t fmpr_perr; + uint32_t fmpr_perer; + uint32_t res034; + uint32_t res038[10]; + uint32_t fmpr_ppsc; + uint32_t res064; + uint32_t fmpr_pds; + uint32_t fmpr_l2rrs; + uint32_t fmpr_l3rrs; + uint32_t fmpr_l4rrs; + uint32_t fmpr_srrs; + uint32_t fmpr_l2rres; + uint32_t fmpr_l3rres; + uint32_t fmpr_l4rres; + uint32_t fmpr_srres; + uint32_t fmpr_spcs; + uint32_t fmpr_spscs; + uint32_t fmpr_hxscs; + uint32_t fmpr_mrcs; + uint32_t fmpr_mwcs; + uint32_t fmpr_mrscs; + uint32_t fmpr_mwscs; + uint32_t fmpr_fcscs; +}; + +struct fman_prs_cfg { + uint32_t port_id_stat; + uint16_t max_prs_cyc_lim; + uint32_t prs_exceptions; +}; + +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask); +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs); +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event); +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask); +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs); +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event); +void fman_prs_defconfig(struct fman_prs_cfg *cfg); +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg); +void fman_prs_enable(struct fman_prs_regs *regs); +void fman_prs_disable(struct fman_prs_regs *regs); +int fman_prs_is_enabled(struct fman_prs_regs *regs); +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk); +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable); +#endif /* __FSL_FMAN_PRS_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_rtc.h b/sys/contrib/ncsw/inc/flib/fsl_fman_rtc.h new file mode 100755 index 000000000000..f6b69a1fbb05 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_rtc.h @@ -0,0 +1,449 @@ +/* + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_RTC_H +#define __FSL_FMAN_RTC_H + +#include "common/general.h" + +/* FM RTC Registers definitions */ +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16 + +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\ + FMAN_RTC_TMR_TEVENT_ETS1 |\ + FMAN_RTC_TMR_TEVENT_ALM2 |\ + FMAN_RTC_TMR_TEVENT_ALM1 |\ + FMAN_RTC_TMR_TEVENT_PP1 |\ + FMAN_RTC_TMR_TEVENT_PP2 |\ + FMAN_RTC_TMR_TEVENT_PP3) + +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF + +/**************************************************************************//** + @Description FM RTC Alarm Polarity Options. +*//***************************************************************************/ +enum fman_rtc_alarm_polarity { + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */ + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */ +}; + +/**************************************************************************//** + @Description FM RTC Trigger Polarity Options. +*//***************************************************************************/ +enum fman_rtc_trigger_polarity { + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */ + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */ +}; + +/**************************************************************************//** + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources. +*//***************************************************************************/ +enum fman_src_clock { + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer + reference clock */ + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */ +}; + +/* RTC default values */ +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE +#define DEFAULT_PULSE_REALIGN FALSE + +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3 + +/**************************************************************************//** + @Description FM RTC timer alarm +*//***************************************************************************/ +struct t_tmr_alarm{ + uint32_t tmr_alarm_h; /**< */ + uint32_t tmr_alarm_l; /**< */ +}; + +/**************************************************************************//** + @Description FM RTC timer Ex trigger +*//***************************************************************************/ +struct t_tmr_ext_trigger{ + uint32_t tmr_etts_h; /**< */ + uint32_t tmr_etts_l; /**< */ +}; + +struct rtc_regs { + uint32_t tmr_id; /* 0x000 Module ID register */ + uint32_t tmr_id2; /* 0x004 Controller ID register */ + uint32_t reserved0008[30]; + uint32_t tmr_ctrl; /* 0x0080 timer control register */ + uint32_t tmr_tevent; /* 0x0084 timer event register */ + uint32_t tmr_temask; /* 0x0088 timer event mask register */ + uint32_t reserved008c[3]; + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */ + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */ + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */ + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */ + uint32_t tmr_prsc; /* 0x00a8 timer prescale */ + uint32_t reserved00ac; + uint32_t tmr_off_h; /* 0x00b0 timer offset high */ + uint32_t tmr_off_l; /* 0x00b4 timer offset low */ + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer + alarm */ + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer + fixed period interval */ + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; + /* 0x00e0 time stamp general purpose external */ + uint32_t reserved00f0[4]; +}; + +struct rtc_cfg { + enum fman_src_clock src_clk; + uint32_t ext_src_clk_freq; + uint32_t rtc_freq_hz; + bool timer_slave_mode; + bool invert_input_clk_phase; + bool invert_output_clk_phase; + uint32_t events_mask; + bool bypass; /**< Indicates if frequency compensation + is bypassed */ + bool pulse_realign; + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS]; + enum fman_rtc_trigger_polarity trigger_polarity + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; +}; + +/** + * fman_rtc_defconfig() - Get default RTC configuration + * @cfg: pointer to configuration structure. + * + * Call this function to obtain a default set of configuration values for + * initializing RTC. The user can overwrite any of the values before calling + * fman_rtc_init(), if specific configuration needs to be applied. + */ +void fman_rtc_defconfig(struct rtc_cfg *cfg); + +/** + * fman_rtc_get_events() - Get the events + * @regs: Pointer to RTC register block + * + * Returns: The events + */ +uint32_t fman_rtc_get_events(struct rtc_regs *regs); + +/** + * fman_rtc_get_interrupt_mask() - Get the events mask + * @regs: Pointer to RTC register block + * + * Returns: The events mask + */ +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs); + + +/** + * fman_rtc_set_interrupt_mask() - Set the events mask + * @regs: Pointer to RTC register block + * @mask: The mask to set + */ +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask); + +/** + * fman_rtc_get_event() - Check if specific events occurred + * @regs: Pointer to RTC register block + * @ev_mask: a mask of the events to check + * + * Returns: 0 if the events did not occur. Non zero if one of the events occurred + */ +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask); + +/** + * fman_rtc_check_and_clear_event() - Clear events which are on + * @regs: Pointer to RTC register block + * + * Returns: A mask of the events which were cleared + */ +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs); + +/** + * fman_rtc_ack_event() - Clear events + * @regs: Pointer to RTC register block + * @events: The events to disable + */ +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events); + +/** + * fman_rtc_enable_interupt() - Enable events interrupts + * @regs: Pointer to RTC register block + * @mask: The events to disable + */ +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask); + +/** + * fman_rtc_disable_interupt() - Disable events interrupts + * @regs: Pointer to RTC register block + * @mask: The events to disable + */ +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask); + +/** + * fman_rtc_get_timer_ctrl() - Get the control register + * @regs: Pointer to RTC register block + * + * Returns: The control register value + */ +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs); + +/** + * fman_rtc_set_timer_ctrl() - Set timer control register + * @regs: Pointer to RTC register block + * @val: The value to set + */ +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val); + +/** + * fman_rtc_get_frequency_compensation() - Get the frequency compensation + * @regs: Pointer to RTC register block + * + * Returns: The timer counter + */ +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs); + +/** + * fman_rtc_set_frequency_compensation() - Set frequency compensation + * @regs: Pointer to RTC register block + * @val: The value to set + */ +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val); + +/** + * fman_rtc_get_trigger_stamp() - Get a trigger stamp + * @regs: Pointer to RTC register block + * @id: The id of the trigger stamp + * + * Returns: The time stamp + */ +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id); + +/** + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register + * @regs: Pointer to RTC register block + * @index: The index of alarm to set + * @val: The value to set + */ +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, + uint32_t val); + +/** + * fman_rtc_set_timer_alarm() - Set timer alarm + * @regs: Pointer to RTC register block + * @index: The index of alarm to set + * @val: The value to set + */ +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val); + +/** + * fman_rtc_set_timer_fiper() - Set timer fiper + * @regs: Pointer to RTC register block + * @index: The index of fiper to set + * @val: The value to set + */ +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val); + +/** + * fman_rtc_set_timer_offset() - Set timer offset + * @regs: Pointer to RTC register block + * @val: The value to set + */ +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val); + +/** + * fman_rtc_get_timer() - Get the timer counter + * @regs: Pointer to RTC register block + * + * Returns: The timer counter + */ +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs) +{ + uint64_t time; + /* TMR_CNT_L must be read first to get an accurate value */ + time = (uint64_t)ioread32be(®s->tmr_cnt_l); + time |= ((uint64_t)ioread32be(®s->tmr_cnt_h) << 32); + + return time; +} + +/** + * fman_rtc_set_timer() - Set timer counter + * @regs: Pointer to RTC register block + * @val: The value to set + */ +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val) +{ + iowrite32be((uint32_t)val, ®s->tmr_cnt_l); + iowrite32be((uint32_t)(val >> 32), ®s->tmr_cnt_h); +} + +/** + * fman_rtc_timers_soft_reset() - Soft reset + * @regs: Pointer to RTC register block + * + * Resets all the timer registers and state machines for the 1588 IP and + * the attached client 1588 + */ +void fman_rtc_timers_soft_reset(struct rtc_regs *regs); + +/** + * fman_rtc_clear_external_trigger() - Clear an external trigger + * @regs: Pointer to RTC register block + * @id: The id of the trigger to clear + */ +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id); + +/** + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse + * @regs: Pointer to RTC register block + * @id: The id of the fiper to clear + */ +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id); + +/** + * fman_rtc_enable() - Enable RTC hardware block + * @regs: Pointer to RTC register block + */ +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock); + +/** + * fman_rtc_is_enabled() - Is RTC hardware block enabled + * @regs: Pointer to RTC register block + * + * Return: TRUE if enabled + */ +bool fman_rtc_is_enabled(struct rtc_regs *regs); + +/** + * fman_rtc_disable() - Disable RTC hardware block + * @regs: Pointer to RTC register block + */ +void fman_rtc_disable(struct rtc_regs *regs); + +/** + * fman_rtc_init() - Init RTC hardware block + * @cfg: RTC configuration data + * @regs: Pointer to RTC register block + * @num_alarms: Number of alarms in RTC + * @num_fipers: Number of fipers in RTC + * @num_ext_triggers: Number of external triggers in RTC + * @freq_compensation: Frequency compensation + * @output_clock_divisor: Output clock divisor + * + * This function initializes RTC and applies basic configuration. + */ +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms, + int num_fipers, int num_ext_triggers, bool init_freq_comp, + uint32_t freq_compensation, uint32_t output_clock_divisor); + +/** + * fman_rtc_set_alarm() - Set an alarm + * @regs: Pointer to RTC register block + * @id: id of alarm + * @val: value to write + * @enable: should interrupt be enabled + */ +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable); + +/** + * fman_rtc_set_periodic_pulse() - Set an alarm + * @regs: Pointer to RTC register block + * @id: id of fiper + * @val: value to write + * @enable: should interrupt be enabled + */ +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val, + bool enable); + +/** + * fman_rtc_set_ext_trigger() - Set an external trigger + * @regs: Pointer to RTC register block + * @id: id of trigger + * @enable: should interrupt be enabled + * @use_pulse_as_input: use the pulse as input + */ +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable, + bool use_pulse_as_input); + +struct fm_rtc_alarm_params { + uint8_t alarm_id; /**< 0 or 1 */ + uint64_t alarm_time; /**< In nanoseconds, the time when the + alarm should go off - must be a + multiple of the RTC period */ + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will + be called when RTC reaches alarmTime */ + bool clear_on_expiration; /**< TRUE to turn off the alarm once + expired.*/ +}; + +struct fm_rtc_periodic_pulse_params { + uint8_t periodic_pulse_id; /**< 0 or 1 */ + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple + of the RTC period */ + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This + routine will be called every + periodicPulsePeriod. */ +}; + +#endif /* __FSL_FMAN_RTC_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_sp.h b/sys/contrib/ncsw/inc/flib/fsl_fman_sp.h new file mode 100755 index 000000000000..f8ef7d569e10 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_sp.h @@ -0,0 +1,138 @@ +/* + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_SP_H +#define __FSL_FMAN_SP_H + +#include "common/general.h" +#include "fsl_fman.h" + + +struct fm_pcd_storage_profile_regs{ + uint32_t fm_sp_ebmpi[8]; + /*offset 0 - 0xc*/ + /**< Buffer Manager pool Information */ + + uint32_t fm_sp_acnt; /*offset 0x20*/ + uint32_t fm_sp_ebm; /*offset 0x24*/ + uint32_t fm_sp_da; /*offset 0x28*/ + uint32_t fm_sp_icp; /*offset 0x2c*/ + uint32_t fm_sp_mpd; /*offset 0x30*/ + uint32_t res1[2]; /*offset 0x34 - 0x38*/ + uint32_t fm_sp_spliodn; /*offset 0x3c*/ +}; + +/**************************************************************************//** + @Description structure for defining internal context copying +*//***************************************************************************/ +struct fman_sp_int_context_data_copy{ + uint16_t ext_buf_offset; /**< Offset in External buffer to which + internal context is copied to (Rx) + or taken from (Tx, Op). */ + uint8_t int_context_offset; /**< Offset within internal context to copy + from (Rx) or to copy to (Tx, Op).*/ + uint16_t size; /**< Internal offset size to be copied */ +}; + +/**************************************************************************//** + @Description struct for defining external buffer margins +*//***************************************************************************/ +struct fman_sp_buf_margins{ + uint16_t start_margins; /**< Number of bytes to be left at the + beginning of the external buffer (must be + divisible by 16) */ + uint16_t end_margins; /**< number of bytes to be left at the end of + the external buffer(must be divisible by 16)*/ +}; + +struct fm_storage_profile_params { + struct fman_ext_pools fm_ext_pools; + struct fman_backup_bm_pools backup_pools; + struct fman_sp_int_context_data_copy *int_context; + struct fman_sp_buf_margins *buf_margins; + enum fman_dma_swap_option dma_swap_data; + enum fman_dma_cache_option int_context_cache_attr; + enum fman_dma_cache_option header_cache_attr; + enum fman_dma_cache_option scatter_gather_cache_attr; + bool dma_write_optimize; + uint16_t liodn_offset; + bool no_scather_gather; + struct fman_buf_pool_depletion buf_pool_depletion; +}; + +/**************************************************************************//** + @Description Registers bit fields +*//***************************************************************************/ +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000 +#define FMAN_SP_SG_DISABLE 0x80000000 + +/* shifts */ +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24 +#define FMAN_SP_IC_TO_EXT_SHIFT 16 +#define FMAN_SP_IC_FROM_INT_SHIFT 8 +#define FMAN_SP_IC_SIZE_SHIFT 0 + +/**************************************************************************//** + @Description defaults +*//***************************************************************************/ +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE + +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg); + +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs, + uint16_t index, struct fm_storage_profile_params *fm_vsp_params, + int port_max_num_of_ext_pools, int bm_max_num_of_pools, + int max_num_of_pfc_priorities); + +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs, + uint16_t index); + +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs, + uint16_t index, uint32_t value); + + +#endif /* __FSL_FMAN_SP_H */ diff --git a/sys/contrib/ncsw/inc/flib/fsl_fman_tgec.h b/sys/contrib/ncsw/inc/flib/fsl_fman_tgec.h new file mode 100644 index 000000000000..a0373141ac68 --- /dev/null +++ b/sys/contrib/ncsw/inc/flib/fsl_fman_tgec.h @@ -0,0 +1,479 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef __FSL_FMAN_TGEC_H +#define __FSL_FMAN_TGEC_H + +#include "common/general.h" +#include "fsl_enet.h" + + +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff + +enum tgec_counters { + E_TGEC_COUNTER_R64, + E_TGEC_COUNTER_R127, + E_TGEC_COUNTER_R255, + E_TGEC_COUNTER_R511, + E_TGEC_COUNTER_R1023, + E_TGEC_COUNTER_R1518, + E_TGEC_COUNTER_R1519X, + E_TGEC_COUNTER_TRFRG, + E_TGEC_COUNTER_TRJBR, + E_TGEC_COUNTER_RDRP, + E_TGEC_COUNTER_RALN, + E_TGEC_COUNTER_TRUND, + E_TGEC_COUNTER_TROVR, + E_TGEC_COUNTER_RXPF, + E_TGEC_COUNTER_TXPF, + E_TGEC_COUNTER_ROCT, + E_TGEC_COUNTER_RMCA, + E_TGEC_COUNTER_RBCA, + E_TGEC_COUNTER_RPKT, + E_TGEC_COUNTER_RUCA, + E_TGEC_COUNTER_RERR, + E_TGEC_COUNTER_TOCT, + E_TGEC_COUNTER_TMCA, + E_TGEC_COUNTER_TBCA, + E_TGEC_COUNTER_TUCA, + E_TGEC_COUNTER_TERR +}; + +/* Command and Configuration Register (COMMAND_CONFIG) */ +#define CMD_CFG_EN_TIMESTAMP 0x00100000 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000 +#define CMD_CFG_NO_LEN_CHK 0x00020000 +#define CMD_CFG_SEND_IDLE 0x00010000 +#define CMD_CFG_RX_ER_DISC 0x00004000 +#define CMD_CFG_CMD_FRM_EN 0x00002000 +#define CMD_CFG_STAT_CLR 0x00001000 +#define CMD_CFG_LOOPBACK_EN 0x00000400 +#define CMD_CFG_TX_ADDR_INS 0x00000200 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 +#define CMD_CFG_PAUSE_FWD 0x00000080 +#define CMD_CFG_PROMIS_EN 0x00000010 +#define CMD_CFG_WAN_MODE 0x00000008 +#define CMD_CFG_RX_EN 0x00000002 +#define CMD_CFG_TX_EN 0x00000001 + +/* Interrupt Mask Register (IMASK) */ +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000 +#define TGEC_IMASK_REM_FAULT 0x00004000 +#define TGEC_IMASK_LOC_FAULT 0x00002000 +#define TGEC_IMASK_TX_ECC_ER 0x00001000 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400 +#define TGEC_IMASK_TX_ER 0x00000200 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100 +#define TGEC_IMASK_RX_ECC_ER 0x00000080 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008 +#define TGEC_IMASK_RX_LEN_ER 0x00000004 +#define TGEC_IMASK_RX_CRC_ER 0x00000002 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001 + +#define TGEC_EVENTS_MASK \ + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \ + TGEC_IMASK_MDIO_CMD_CMPL | \ + TGEC_IMASK_REM_FAULT | \ + TGEC_IMASK_LOC_FAULT | \ + TGEC_IMASK_TX_ECC_ER | \ + TGEC_IMASK_TX_FIFO_UNFL | \ + TGEC_IMASK_TX_FIFO_OVFL | \ + TGEC_IMASK_TX_ER | \ + TGEC_IMASK_RX_FIFO_OVFL | \ + TGEC_IMASK_RX_ECC_ER | \ + TGEC_IMASK_RX_JAB_FRM | \ + TGEC_IMASK_RX_OVRSZ_FRM | \ + TGEC_IMASK_RX_RUNT_FRM | \ + TGEC_IMASK_RX_FRAG_FRM | \ + TGEC_IMASK_RX_LEN_ER | \ + TGEC_IMASK_RX_CRC_ER | \ + TGEC_IMASK_RX_ALIGN_ER)) + +/* Hashtable Control Register (HASHTABLE_CTRL) */ +#define TGEC_HASH_MCAST_SHIFT 23 +#define TGEC_HASH_MCAST_EN 0x00000200 +#define TGEC_HASH_ADR_MSK 0x000001ff + +#define DEFAULT_WAN_MODE_ENABLE FALSE +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE +#define DEFAULT_PAUSE_IGNORE FALSE +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE +#define DEFAULT_LOOPBACK_ENABLE FALSE +#define DEFAULT_CMD_FRAME_ENABLE FALSE +#define DEFAULT_RX_ERROR_DISCARD FALSE +#define DEFAULT_SEND_IDLE_ENABLE FALSE +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE +#define DEFAULT_TIME_STAMP_ENABLE FALSE +#define DEFAULT_TX_IPG_LENGTH 12 +#define DEFAULT_MAX_FRAME_LENGTH 0x600 +#define DEFAULT_PAUSE_QUANT 0xf000 + +/* + * 10G memory map + */ +struct tgec_regs { + uint32_t tgec_id; /* 0x000 Controller ID */ + uint32_t reserved001[1]; /* 0x004 */ + uint32_t command_config; /* 0x008 Control and configuration */ + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */ + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */ + uint32_t maxfrm; /* 0x014 Maximum frame length */ + uint32_t pause_quant; /* 0x018 Pause quanta */ + uint32_t rx_fifo_sections; /* 0x01c */ + uint32_t tx_fifo_sections; /* 0x020 */ + uint32_t rx_fifo_almost_f_e; /* 0x024 */ + uint32_t tx_fifo_almost_f_e; /* 0x028 */ + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/ + uint32_t mdio_cfg_status; /* 0x030 */ + uint32_t mdio_command; /* 0x034 */ + uint32_t mdio_data; /* 0x038 */ + uint32_t mdio_regaddr; /* 0x03c */ + uint32_t status; /* 0x040 */ + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */ + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */ + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */ + uint32_t rx_fifo_ptr_rd; /* 0x050 */ + uint32_t rx_fifo_ptr_wr; /* 0x054 */ + uint32_t tx_fifo_ptr_rd; /* 0x058 */ + uint32_t tx_fifo_ptr_wr; /* 0x05c */ + uint32_t imask; /* 0x060 Interrupt mask */ + uint32_t ievent; /* 0x064 Interrupt event */ + uint32_t udp_port; /* 0x068 Defines a UDP Port number */ + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */ + uint32_t reserved070[4]; /* 0x070 */ + /*10Ge Statistics Counter */ + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */ + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */ + uint32_t rfrm_u; /* 88 aFramesReceivedOK */ + uint32_t rfrm_l; /* 8c aFramesReceivedOK */ + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */ + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */ + uint32_t raln_u; /* 98 aAlignmentErrors */ + uint32_t raln_l; /* 9c aAlignmentErrors */ + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */ + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */ + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */ + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */ + uint32_t rlong_u; /* B0 aFrameTooLongErrors */ + uint32_t rlong_l; /* B4 aFrameTooLongErrors */ + uint32_t rflr_u; /* B8 aInRangeLengthErrors */ + uint32_t rflr_l; /* Bc aInRangeLengthErrors */ + uint32_t tvlan_u; /* C0 VLANTransmittedOK */ + uint32_t tvlan_l; /* C4 VLANTransmittedOK */ + uint32_t rvlan_u; /* C8 VLANReceivedOK */ + uint32_t rvlan_l; /* Cc VLANReceivedOK */ + uint32_t toct_u; /* D0 ifOutOctets */ + uint32_t toct_l; /* D4 ifOutOctets */ + uint32_t roct_u; /* D8 ifInOctets */ + uint32_t roct_l; /* Dc ifInOctets */ + uint32_t ruca_u; /* E0 ifInUcastPkts */ + uint32_t ruca_l; /* E4 ifInUcastPkts */ + uint32_t rmca_u; /* E8 ifInMulticastPkts */ + uint32_t rmca_l; /* Ec ifInMulticastPkts */ + uint32_t rbca_u; /* F0 ifInBroadcastPkts */ + uint32_t rbca_l; /* F4 ifInBroadcastPkts */ + uint32_t terr_u; /* F8 ifOutErrors */ + uint32_t terr_l; /* Fc ifOutErrors */ + uint32_t reserved100[2]; /* 100-108*/ + uint32_t tuca_u; /* 108 ifOutUcastPkts */ + uint32_t tuca_l; /* 10c ifOutUcastPkts */ + uint32_t tmca_u; /* 110 ifOutMulticastPkts */ + uint32_t tmca_l; /* 114 ifOutMulticastPkts */ + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */ + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */ + uint32_t rdrp_u; /* 120 etherStatsDropEvents */ + uint32_t rdrp_l; /* 124 etherStatsDropEvents */ + uint32_t reoct_u; /* 128 etherStatsOctets */ + uint32_t reoct_l; /* 12c etherStatsOctets */ + uint32_t rpkt_u; /* 130 etherStatsPkts */ + uint32_t rpkt_l; /* 134 etherStatsPkts */ + uint32_t trund_u; /* 138 etherStatsUndersizePkts */ + uint32_t trund_l; /* 13c etherStatsUndersizePkts */ + uint32_t r64_u; /* 140 etherStatsPkts64Octets */ + uint32_t r64_l; /* 144 etherStatsPkts64Octets */ + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */ + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */ + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */ + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */ + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */ + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */ + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */ + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */ + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */ + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */ + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */ + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */ + uint32_t trovr_u; /* 178 etherStatsOversizePkts */ + uint32_t trovr_l; /* 17c etherStatsOversizePkts */ + uint32_t trjbr_u; /* 180 etherStatsJabbers */ + uint32_t trjbr_l; /* 184 etherStatsJabbers */ + uint32_t trfrg_u; /* 188 etherStatsFragments */ + uint32_t trfrg_l; /* 18C etherStatsFragments */ + uint32_t rerr_u; /* 190 ifInErrors */ + uint32_t rerr_l; /* 194 ifInErrors */ +}; + +/** + * struct tgec_cfg - TGEC configuration + * + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1 + * any frame received with an error is discarded in the + * Core and not forwarded to the Client interface. + * When set to 0 (Reset value), erroneous Frames are + * forwarded to the Client interface with ff_rx_err + * asserted. + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause + * frames are ignored by the MAC. When set to 0 + * (Reset value) the transmit process is stopped for the + * amount of time specified in the pause quanta received + * within a pause frame. + * @pause_forward_enable: + * Terminate / Forward Pause Frames. If set to 1 pause + * frames are forwarded to the user application. When set + * to 0 (Reset value) pause frames are terminated and + * discarded within the MAC. + * @no_length_check_enable: + * Payload Length Check Disable. When set to 0 + * (Reset value), the Core checks the frame's payload + * length with the Frame Length/Type field, when set to 1 + * the payload length check is disabled. + * @cmd_frame_enable: Enables reception of all command frames. When set to 1 + * all Command Frames are accepted, when set to 0 + * (Reset Value) only Pause Frames are accepted and all + * other Command Frames are rejected. + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC + * permanently sends XGMII Idle sequences even when faults + * are received. + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode + * (0, default) of operation. + * @promiscuous_mode_enable: + * Enables MAC promiscuous operation. When set to 1, all + * frames are received without any MAC address filtering, + * when set to 0 (Reset value) Unicast Frames with a + * destination address not matching the Core MAC Address + * (MAC Address programmed in Registers MAC_ADDR_0 and + * MAC_ADDR_1 or the MAC address programmed in Registers + * MAC_ADDR_2 and MAC_ADDR_3) are rejected. + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the + * MAC overwrites the source MAC address received from the + * Client Interface with one of the MAC addresses. If set + * to 0 (Reset value), the source MAC address from the + * Client Interface is transmitted unmodified to the line. + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal + * loop_ena is set to '1', when set to 0 (Reset value) + * the signal loop_ena is set to 0. + * @lgth_check_nostdr: The Core interprets the Length/Type field differently + * depending on the value of this Bit + * @time_stamp_enable: This bit selects between enabling and disabling the + * IEEE 1588 functionality. 1: IEEE 1588 is enabled + * 0: IEEE 1588 is disabled + * @max_frame_length: Maximum supported received frame length. + * The 10GEC MAC supports reception of any frame size up + * to 16,352 bytes (0x3FE0). Typical settings are + * 0x05EE (1,518 bytes) for standard frames. + * Default setting is 0x0600 (1,536 bytes). + * Received frames that exceed this stated maximum + * are truncated. + * @pause_quant: Pause quanta value used with transmitted pause frames. + * Each quanta represents a 512 bit-times. + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value: + * Depending on LAN or WAN mode of operation the value has + * the following meaning: - LAN Mode: Number of octets in + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is + * fully supported (see 10.6.1 page 49) for any setting. A + * default of 12 (reset value) must be set to conform to + * IEEE802.3ae. Warning: When set to 8, PCS layers may not + * be able to perform clock rate compensation. - WAN Mode: + * Stretch factor. Valid values are 4..15. The stretch + * factor is calculated as (value+1)*8. A default of 12 + * (reset value) must be set to conform to IEEE 802.3ae + * (i.e. 13*8=104). A larger value shrinks the IPG + * (increasing bandwidth). + * + * This structure contains basic TGEC configuration and must be passed to + * fman_tgec_init() function. A default set of configuration values can be + * obtained by calling fman_tgec_defconfig(). + */ +struct tgec_cfg { + bool rx_error_discard; + bool pause_ignore; + bool pause_forward_enable; + bool no_length_check_enable; + bool cmd_frame_enable; + bool send_idle_enable; + bool wan_mode_enable; + bool promiscuous_mode_enable; + bool tx_addr_ins_enable; + bool loopback_enable; + bool lgth_check_nostdr; + bool time_stamp_enable; + uint16_t max_frame_length; + uint16_t pause_quant; + uint32_t tx_ipg_length; + bool skip_fman11_workaround; +}; + + +void fman_tgec_defconfig(struct tgec_cfg *cfg); + +/** + * fman_tgec_init() - Init tgec hardware block + * @regs: Pointer to tgec register block + * @cfg: tgec configuration data + * @exceptions_mask: initial exceptions mask + * + * This function initializes the tgec controller and applies its + * basic configuration. + * + * Returns: 0 if successful, an error code otherwise. + */ + +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg, + uint32_t exception_mask); + +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); + +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); + +uint32_t fman_tgec_get_revision(struct tgec_regs *regs); + +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr); + +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val); + +/** + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters + * @regs: Pointer to TGEC register block + */ +void fman_tgec_reset_stat(struct tgec_regs *regs); + +/** + * fman_tgec_get_counter() - Reads TGEC HW counters + * @regs: Pointer to TGEC register block + * @reg_name: Counter name according to the appropriate enum + * + * Returns: Required counter value + */ +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, + enum tgec_counters reg_name); + +/** + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register + * @regs: Pointer to TGEC register block + * @value: Value to be written in Hashtable Control Register + */ +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value); + +/** + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register + * @regs: Pointer to TGEC register block + * @pause_time: Pause quanta value used with transmitted pause frames. + * Each quanta represents a 512 bit-times + */ +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time); + +/** + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames + * @regs: Pointer to TGEC register block + * @en: Ignore/Respond to pause frame quanta + * + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register + * 0 - MAC stops transmit process for the duration specified + * in the Pause frame quanta of a received Pause frame. + * 1 - MAC ignores received Pause frames. + */ +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en); + +/** + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality + * @regs: Pointer to TGEC register block + * @en: enable/disable timestamp functionality + * + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register + * IEEE 1588 timestamp functionality control: + * 0 disabled, 1 enabled + */ + +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en); + +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask); + +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask); + +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs); + +/** + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address + * @regs: Pointer to TGEC register block + * @addr_ptr: Pointer to 6-byte array containing the MAC address + * + * Sets the additional station MAC address + */ +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr); + +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs); + +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); + +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); + +void fman_tgec_reset_filter_table(struct tgec_regs *regs); + +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc); + + +/** + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value + * @regs: Pointer to TGEC register block + */ +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs); + +/** + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the + * main tgec configuration parameters + * @regs: Pointer to TGEC register block + * + * TODO + */ +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs + *regs); + + +#endif /* __FSL_FMAN_TGEC_H */ diff --git a/sys/contrib/ncsw/inc/integrations/dpaa_integration_ext.h b/sys/contrib/ncsw/inc/integrations/dpaa_integration_ext.h index 88443fa86316..27bb5d402378 100644 --- a/sys/contrib/ncsw/inc/integrations/dpaa_integration_ext.h +++ b/sys/contrib/ncsw/inc/integrations/dpaa_integration_ext.h @@ -177,7 +177,7 @@ typedef enum /* RAMs defines */ #define FM_MURAM_SIZE (160 * KILOBYTE) -#define FM_IRAM_SIZE ( 64 * KILOBYTE) +#define FM_IRAM_SIZE(a,b) ( 64 * KILOBYTE) /* PCD defines */ #define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */ @@ -208,113 +208,6 @@ typedef enum #define PORT_MAX_WEIGHT 16 -/**************************************************************************//** - @Description Enum for inter-module interrupts registration -*//***************************************************************************/ -typedef enum e_FmEventModules -{ - e_FM_MOD_PRS, /**< Parser event */ - e_FM_MOD_KG, /**< Keygen event */ - e_FM_MOD_PLCR, /**< Policer event */ - e_FM_MOD_10G_MAC, /**< 10G MAC error event */ - e_FM_MOD_1G_MAC, /**< 1G MAC error event */ - e_FM_MOD_TMR, /**< Timer event */ - e_FM_MOD_1G_MAC_TMR, /**< 1G MAC timer event */ - e_FM_MOD_FMAN_CTRL, /**< FMAN Controller timer event */ - e_FM_MOD_DUMMY_LAST -} e_FmEventModules; - -/**************************************************************************//** - @Description Enum for interrupts types -*//***************************************************************************/ -typedef enum e_FmIntrType -{ - e_FM_INTR_TYPE_ERR, - e_FM_INTR_TYPE_NORMAL -} e_FmIntrType; - -/**************************************************************************//** - @Description Enum for inter-module interrupts registration -*//***************************************************************************/ -typedef enum e_FmInterModuleEvent -{ - e_FM_EV_PRS, /**< Parser event */ - e_FM_EV_ERR_PRS, /**< Parser error event */ - e_FM_EV_KG, /**< Keygen event */ - e_FM_EV_ERR_KG, /**< Keygen error event */ - e_FM_EV_PLCR, /**< Policer event */ - e_FM_EV_ERR_PLCR, /**< Policer error event */ - e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */ - e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */ - e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */ - e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */ - e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */ - e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */ - e_FM_EV_TMR, /**< Timer event */ - e_FM_EV_1G_MAC0_TMR, /**< 1G MAC 0 timer event */ - e_FM_EV_1G_MAC1_TMR, /**< 1G MAC 1 timer event */ - e_FM_EV_1G_MAC2_TMR, /**< 1G MAC 2 timer event */ - e_FM_EV_1G_MAC3_TMR, /**< 1G MAC 3 timer event */ - e_FM_EV_1G_MAC4_TMR, /**< 1G MAC 4 timer event */ - e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */ - e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */ - e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */ - e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */ - e_FM_EV_DUMMY_LAST -} e_FmInterModuleEvent; - -#define GET_FM_MODULE_EVENT(mod, id, intrType, event) \ - switch(mod){ \ - case e_FM_MOD_PRS: \ - if (id) event = e_FM_EV_DUMMY_LAST; \ - else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \ - break; \ - case e_FM_MOD_KG: \ - if (id) event = e_FM_EV_DUMMY_LAST; \ - else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \ - break; \ - case e_FM_MOD_PLCR: \ - if (id) event = e_FM_EV_DUMMY_LAST; \ - else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \ - break; \ - case e_FM_MOD_10G_MAC: \ - if (id) event = e_FM_EV_DUMMY_LAST; \ - else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_10G_MAC0 : e_FM_EV_DUMMY_LAST; \ - break; \ - case e_FM_MOD_1G_MAC: \ - switch(id){ \ - case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC0 : e_FM_EV_DUMMY_LAST; break; \ - case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC1 : e_FM_EV_DUMMY_LAST; break; \ - case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC2 : e_FM_EV_DUMMY_LAST; break; \ - case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC3 : e_FM_EV_DUMMY_LAST; break; \ - case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC4 : e_FM_EV_DUMMY_LAST; break; \ - } \ - break; \ - case e_FM_MOD_TMR: \ - if (id) event = e_FM_EV_DUMMY_LAST; \ - else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \ - break; \ - case e_FM_MOD_1G_MAC_TMR: \ - switch(id){ \ - case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC0_TMR; break; \ - case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC1_TMR; break; \ - case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC2_TMR; break; \ - case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC3_TMR; break; \ - case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC4_TMR; break; \ - } \ - break; \ - case e_FM_MOD_FMAN_CTRL: \ - if (intrType == e_FM_INTR_TYPE_ERR) event = e_FM_EV_DUMMY_LAST; \ - else switch(id){ \ - case(0): event = e_FM_EV_FMAN_CTRL_0; break; \ - case(1): event = e_FM_EV_FMAN_CTRL_1; break; \ - case(2): event = e_FM_EV_FMAN_CTRL_2; break; \ - case(3): event = e_FM_EV_FMAN_CTRL_3; break; \ - } \ - break; \ - default: event = e_FM_EV_DUMMY_LAST; \ - break;} - #define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE /* P5020 unique features */ @@ -374,5 +267,9 @@ typedef enum e_FmInterModuleEvent #define FM_PRS_MEM_ERRATA_FMAN_SW003 #define FM_LEN_CHECK_ERRATA_FMAN_SW002 +#define DPAA_VERSION 10 +#define FM_PCD_SW_PRS_SIZE 0x00000800 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 +#define FM_NUM_OF_CTRL 2 #endif /* __DPAA_INTEGRATION_EXT_H */ diff --git a/sys/contrib/ncsw/inc/integrations/part_ext.h b/sys/contrib/ncsw/inc/integrations/part_ext.h index 8052c43129a5..0fa702993892 100644 --- a/sys/contrib/ncsw/inc/integrations/part_ext.h +++ b/sys/contrib/ncsw/inc/integrations/part_ext.h @@ -44,21 +44,8 @@ #include "enet_ext.h" #include "dpaa_integration_ext.h" -#define CORE_E500MC - -/***************************************************************************** - INTEGRATION-SPECIFIC MODULE CODES -******************************************************************************/ -#define MODULE_MEM 0x00010000 -#define MODULE_MM 0x00020000 -#define MODULE_QM 0x000d0000 -#define MODULE_BM 0x000e0000 -#define MODULE_FM 0x00130000 -#define MODULE_FM_MURAM 0x00140000 -#define MODULE_FM_PCD 0x00150000 -#define MODULE_FM_RTC 0x00160000 -#define MODULE_FM_MAC 0x00170000 -#define MODULE_FM_PORT 0x00180000 +#define CORE_E500MC +#define INTG_MAX_NUM_OF_CORES 24 /**************************************************************************//* @Description Part data structure - must be contained in any integration diff --git a/sys/contrib/ncsw/inc/math_ext.h b/sys/contrib/ncsw/inc/math_ext.h deleted file mode 100644 index 95b9560d8d60..000000000000 --- a/sys/contrib/ncsw/inc/math_ext.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. - */ - -#ifndef __MATH_EXT_H -#define __MATH_EXT_H - - -#if defined(NCSW_LINUX) && defined(__KERNEL__) -#include - -#elif defined(__MWERKS__) -#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x)) -#define HIGH(x) (*(int32_t*)&x) -#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x)) -#define UHIGH(x) (*(uint32_t*)&x) - -static const double big = 1.0e300; - -/* Macro for checking if a number is a power of 2 */ -static __inline__ double ceil(double x) -{ - int32_t i0,i1,j0; /*- cc 020130 -*/ - uint32_t i,j; /*- cc 020130 -*/ - i0 = HIGH(x); - i1 = LOW(x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { /* raise inexact if x != 0 */ - if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */ - if(i0<0) {i0=0x80000000;i1=0;} - else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} - } - } else { - i = (uint32_t)(0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(big+x>0.0) { /* raise inexact flag */ - if(i0>0) i0 += (0x00100000)>>j0; - i0 &= (~i); i1=0; - } - } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/ - if((i1&i)==0) return x; /* x is integral */ - if(big+x>0.0) { /* raise inexact flag */ - if(i0>0) { - if(j0==20) i0+=1; - else { - j = (uint32_t)(i1 + (1<<(52-j0))); - if(j -#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ - - -#endif /* __MATH_EXT_H */ diff --git a/sys/contrib/ncsw/inc/ncsw_ext.h b/sys/contrib/ncsw/inc/ncsw_ext.h index e9f059dff496..ec7aca01fda4 100644 --- a/sys/contrib/ncsw/inc/ncsw_ext.h +++ b/sys/contrib/ncsw/inc/ncsw_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /**************************************************************************//** + +/**************************************************************************//** @File ncsw_ext.h @Description General NetCommSw Standard Definitions @@ -39,11 +40,11 @@ #ifndef __NCSW_EXT_H #define __NCSW_EXT_H + #include "memcpy_ext.h" - -#define WRITE_BLOCK IOMemSet32 -#define COPY_BLOCK Mem2IOCpy32 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */ +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */ #define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr)) #define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val)) @@ -51,8 +52,10 @@ #define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset)) -#define WRITE_UINT8_UINT24(arg, data08, data24) WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF)) -#define WRITE_UINT24_UINT8(arg, data24, data08) WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF)) +#define WRITE_UINT8_UINT24(arg, data08, data24) \ + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF)) +#define WRITE_UINT24_UINT8(arg, data24, data08) \ + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF)) /* Little-Endian access macros */ @@ -93,14 +96,16 @@ /* Miscellaneous macros */ /*----------------------*/ -#define UNUSED(X) (X=X) +#define UNUSED(_x) ((void)(_x)) #define KILOBYTE 0x400UL /* 1024 */ #define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */ -#define GIGABYTE (KILOBYTE * MEGABYTE) /* 1024*1024*1024 */ +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */ +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */ -#undef NO_IRQ -#define NO_IRQ (-1) +#ifndef NO_IRQ +#define NO_IRQ (0) +#endif #define NCSW_MASTER_ID (0) /* Macro for checking if a number is a power of 2 */ @@ -137,7 +142,7 @@ do \ } while (0) /* Ceiling division - not the fastest way, but safer in terms of overflow */ -#define DIV_CEIL(x,y) (((x)/(y)) + ((((((x)/(y)))*(y)) == (x)) ? 0 : 1)) +#define DIV_CEIL(x,y) (((x)/(y)) + (((((x)/(y))*(y)) == (x)) ? 0 : 1)) /* Round up a number to be a multiple of a second number */ #define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y)) @@ -157,8 +162,6 @@ do \ #define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk)) /* Min, Max macros */ -#define NCSW_MIN(a,b) ((a) < (b) ? (a) : (b)) -#define NCSW_MAX(a,b) ((a) > (b) ? (a) : (b)) #define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max)) #define ABS(a) ((a<0)?(a*-1):a) diff --git a/sys/contrib/ncsw/inc/net_ext.h b/sys/contrib/ncsw/inc/net_ext.h index c41b7c940f3b..8f3bc369247e 100644 --- a/sys/contrib/ncsw/inc/net_ext.h +++ b/sys/contrib/ncsw/inc/net_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File net_ext.h @@ -82,6 +83,16 @@ typedef uint8_t headerFieldEth_t; #define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5) #define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1) +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6 + +typedef uint16_t headerFieldIp_t; + +#define NET_HEADER_FIELD_IP_VER (1) +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2) +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3) +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4) + +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1 typedef uint16_t headerFieldIpv4_t; @@ -102,6 +113,9 @@ typedef uint16_t headerFieldIpv4_t; #define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14) #define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1) +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1 + typedef uint8_t headerFieldIpv6_t; @@ -114,6 +128,9 @@ typedef uint8_t headerFieldIpv6_t; #define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6) #define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1) +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1 + #define NET_HEADER_FIELD_ICMP_TYPE (1) #define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1) #define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2) @@ -121,6 +138,9 @@ typedef uint8_t headerFieldIpv6_t; #define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4) #define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1) +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1 + #define NET_HEADER_FIELD_IGMP_VERSION (1) #define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1) #define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2) @@ -143,6 +163,8 @@ typedef uint16_t headerFieldTcp_t; #define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10) #define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1) +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2 + typedef uint8_t headerFieldSctp_t; @@ -152,6 +174,7 @@ typedef uint8_t headerFieldSctp_t; #define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3) #define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1) +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2 typedef uint8_t headerFieldDccp_t; @@ -159,6 +182,8 @@ typedef uint8_t headerFieldDccp_t; #define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1) #define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1) +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2 + typedef uint8_t headerFieldUdp_t; @@ -168,6 +193,16 @@ typedef uint8_t headerFieldUdp_t; #define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3) #define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1) +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2 + +typedef uint8_t headerFieldUdpLite_t; + +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1) +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1) +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1) + +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2 + typedef uint8_t headerFieldUdpEncapEsp_t; #define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1) @@ -178,6 +213,9 @@ typedef uint8_t headerFieldUdpEncapEsp_t; #define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5) #define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1) +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4 + #define NET_HEADER_FIELD_IPHC_CID (1) #define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1) #define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2) @@ -326,6 +364,8 @@ typedef uint8_t headerFieldIpsecEsp_t; #define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1) #define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1) +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4 + typedef uint8_t headerFieldMpls_t; @@ -346,8 +386,10 @@ typedef enum { HEADER_TYPE_VLAN, HEADER_TYPE_IPv4, HEADER_TYPE_IPv6, + HEADER_TYPE_IP, HEADER_TYPE_TCP, HEADER_TYPE_UDP, + HEADER_TYPE_UDP_LITE, HEADER_TYPE_IPHC, HEADER_TYPE_SCTP, HEADER_TYPE_SCTP_CHUNK_DATA, diff --git a/sys/contrib/ncsw/inc/std_ext.h b/sys/contrib/ncsw/inc/std_ext.h index 4d2ba4434b51..d91e6fddf507 100644 --- a/sys/contrib/ncsw/inc/std_ext.h +++ b/sys/contrib/ncsw/inc/std_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /**************************************************************************//** +/**************************************************************************//** @File std_ext.h @Description General Standard Definitions diff --git a/sys/contrib/ncsw/inc/stdarg_ext.h b/sys/contrib/ncsw/inc/stdarg_ext.h index 39e46ef276a9..7379a4e5ed52 100644 --- a/sys/contrib/ncsw/inc/stdarg_ext.h +++ b/sys/contrib/ncsw/inc/stdarg_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/sys/contrib/ncsw/inc/stdlib_ext.h b/sys/contrib/ncsw/inc/stdlib_ext.h index 16f2a2a715ac..bc89030f13ec 100644 --- a/sys/contrib/ncsw/inc/stdlib_ext.h +++ b/sys/contrib/ncsw/inc/stdlib_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/sys/contrib/ncsw/inc/string_ext.h b/sys/contrib/ncsw/inc/string_ext.h index 32c64572ce57..e2d413067277 100644 --- a/sys/contrib/ncsw/inc/string_ext.h +++ b/sys/contrib/ncsw/inc/string_ext.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. - * All rights reserved. +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/sys/contrib/ncsw/inc/types_ext.h b/sys/contrib/ncsw/inc/types_ext.h index 03b6db4b7799..da524cc882be 100644 --- a/sys/contrib/ncsw/inc/types_ext.h +++ b/sys/contrib/ncsw/inc/types_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /**************************************************************************//** + +/**************************************************************************//** @File types_ext.h @Description General types Standard Definitions @@ -39,76 +40,26 @@ #ifndef __TYPES_EXT_H #define __TYPES_EXT_H - #if defined(NCSW_LINUX) #include "types_linux.h" -#elif defined(NCSW_LINUX_USD) -#include "types_linux_usd.h" - #elif defined(NCSW_VXWORKS) #include "types_vxworks.h" -#elif defined(__MWERKS__) && defined(__GNUC__) && defined(__cplusplus) +#elif defined(__GNUC__) && defined(__cplusplus) #include "types_bb_gpp.h" -#elif defined(__MWERKS__) && defined(__GNUC__) +#elif defined(__FreeBSD__) +#include "types_freebsd.h" + +#elif defined(__GNUC__) #include "types_bb_gcc.h" #elif defined(__ghs__) #include "types_ghs.h" -#elif defined(NCSW_FREEBSD) -#include "types_freebsd.h" - #else #include "types_dflt.h" #endif /* defined (__ROCOO__) */ - -static __inline__ void TypesChecker(void) -{ -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(push,1) -#endif /* defined(__MWERKS__) && ... */ -#define MEM_MAP_START - _Packed struct strct { - __volatile__ int vi; - } _PackedType; -#define MEM_MAP_END -#if defined(__MWERKS__) && !defined(__GNUC__) -#pragma pack(pop) -#endif /* defined(__MWERKS__) && ... */ - size_t size = 0; - bool tr = TRUE, fls = FALSE; - struct strct *p_Strct = NULL; - physAddress_t addr = 0x100; - - tr = fls; - p_Strct = p_Strct; - size++; - if (tr) size++; - - WRITE_UINT8(*((uint8_t*)((size_t)(addr))), - GET_UINT8(*((uint8_t*)((size_t)(addr))))); - - WRITE_UINT8(*((uint8_t*)((size_t)(UINT8_MAX))), - GET_UINT8(*((uint8_t*)((size_t)(UINT8_MAX))))); - WRITE_UINT16(*((uint16_t*)((size_t)(UINT16_MAX))), - GET_UINT16(*((uint16_t*)((size_t)(UINT16_MAX))))); - WRITE_UINT32(*((uint32_t*)((size_t)(UINT32_MAX))), - GET_UINT32(*((uint32_t*)((size_t)(UINT32_MAX))))); - WRITE_UINT64(*((uint64_t*)((size_t)(UINT64_MAX))), - GET_UINT64(*((uint64_t*)((size_t)(UINT64_MAX))))); - WRITE_UINT8(*((uint8_t*)((size_t)(INT8_MAX))), - GET_UINT8(*((uint8_t*)((size_t)(INT8_MIN))))); - WRITE_UINT16(*((uint16_t*)((size_t)(INT16_MAX))), - GET_UINT16(*((uint16_t*)((size_t)(INT16_MIN))))); - WRITE_UINT32(*((uint32_t*)((size_t)(INT32_MAX))), - GET_UINT32(*((uint32_t*)((size_t)(INT32_MIN))))); - WRITE_UINT64(*((uint64_t*)((size_t)(INT64_MAX))), - GET_UINT64(*((uint64_t*)((size_t)(INT64_MIN))))); -} - - #endif /* __TYPES_EXT_H */ diff --git a/sys/contrib/ncsw/inc/xx_common.h b/sys/contrib/ncsw/inc/xx_common.h new file mode 100644 index 000000000000..8247b9921678 --- /dev/null +++ b/sys/contrib/ncsw/inc/xx_common.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + + +/**************************************************************************//** + @File debug_ext.h + + @Description Debug mode definitions. +*//***************************************************************************/ + +#ifndef __XX_COMMON_H +#define __XX_COMMON_H + +/***************************************************************************** + * UNIFIED MODULE CODES + *****************************************************************************/ +#define MODULE_UNKNOWN 0x00000000 +#define MODULE_FM 0x00010000 +#define MODULE_FM_MURAM 0x00020000 +#define MODULE_FM_PCD 0x00030000 +#define MODULE_FM_RTC 0x00040000 +#define MODULE_FM_MAC 0x00050000 +#define MODULE_FM_PORT 0x00060000 +#define MODULE_MM 0x00070000 +#define MODULE_FM_SP 0x00080000 +#define MODULE_FM_MACSEC 0x00090000 +#define MODULE_QM 0x000a0000 +#define MODULE_BM 0x000b0000 +#endif /* __XX_COMMON_H */ diff --git a/sys/contrib/ncsw/inc/xx_ext.h b/sys/contrib/ncsw/inc/xx_ext.h index f011b58b65a2..32e0c39d3634 100644 --- a/sys/contrib/ncsw/inc/xx_ext.h +++ b/sys/contrib/ncsw/inc/xx_ext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /**************************************************************************//** @File xx_ext.h @@ -41,11 +42,9 @@ #define __XX_EXT_H #include "std_ext.h" +#include "xx_common.h" #include "part_ext.h" -#if defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED) -#include "xx_integration_ext.h" -#endif /* defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED) */ /**************************************************************************//** @@ -57,26 +56,6 @@ @{ *//***************************************************************************/ -#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) -/**************************************************************************//** - @Function XX_EventById - - @Description Event reporting routine - executed only when REPORT_EVENTS=1. - - @Param[in] event - Event code (e_Event). - @Param[in] appId - Application identifier. - @Param[in] flags - Event flags. - @Param[in] msg - Event message. - - @Return None -*//***************************************************************************/ -void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg); - -#else /* not REPORT_EVENTS */ -#define XX_EventById(event, appId, flags, msg) -#endif /* REPORT_EVENTS */ - - #ifdef DEBUG_XX_MALLOC void * XX_MallocDebug(uint32_t size, char *fname, int line); @@ -104,15 +83,6 @@ void * XX_MallocSmartDebug(uint32_t size, *//***************************************************************************/ void * XX_Malloc(uint32_t size); -/**************************************************************************//** - @Function XX_MallocSmartInit - - @Description Initializes SmartMalloc allocator. - - @Return E_OK on success, error code otherwise. -*//***************************************************************************/ -int XX_MallocSmartInit(void); - /**************************************************************************//** @Function XX_MallocSmart @@ -127,6 +97,8 @@ int XX_MallocSmartInit(void); @Return The address of the newly allocated block on success, NULL on failure. *//***************************************************************************/ void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment); + +int XX_MallocSmartInit(void); #endif /* not DEBUG_XX_MALLOC */ /**************************************************************************//** @@ -152,21 +124,6 @@ void XX_FreeSmart(void *p_Memory); *//***************************************************************************/ void XX_Free(void *p_Memory); -#ifndef NCSW_LINUX -/**************************************************************************//** - @Function XX_GetMemPartitionBase - - @Description This routine gets the address of a memory segment according to - the memory type. - - @Param[in] memPartitionId - Memory partition ID; The value zero must - be mapped to the default heap partition. - - @Return The address of the required memory type. -*//***************************************************************************/ -void * XX_GetMemPartitionBase(int memPartitionId); -#endif - /**************************************************************************//** @Function XX_Print @@ -176,39 +133,7 @@ void * XX_GetMemPartitionBase(int memPartitionId); @Return None. *//***************************************************************************/ -void XX_Print(char *str, ...); - -/**************************************************************************//** - @Function XX_GetChar - - @Description Get character from console. - - @Return Character is returned on success. Zero is returned otherwise. -*//***************************************************************************/ -char XX_GetChar(void); - -/**************************************************************************//** - @Function XX_PreallocAndBindIntr - - @Description Preallocate and optionally bind it to given CPU. - - @Param[in] irq - Interrupt ID (system-specific number). - @Param[in] cpu - CPU to bind to or -1 if iRQ should be unbound. - - @Return E_OK on success; error code otherwise.. -*//***************************************************************************/ -t_Error XX_PreallocAndBindIntr(uintptr_t irq, unsigned int cpu); - -/**************************************************************************//** - @Function XX_DeallocIntr - - @Description Deallocate preallocated interupt. - - @Param[in] irq - Interrupt ID (system-specific number). - - @Return E_OK on success; error code otherwise.. -*//***************************************************************************/ -t_Error XX_DeallocIntr(uintptr_t irq); +void XX_Print(char *str, ...); /**************************************************************************//** @Function XX_SetIntr @@ -256,7 +181,6 @@ t_Error XX_EnableIntr(uintptr_t irq); *//***************************************************************************/ t_Error XX_DisableIntr(uintptr_t irq); -#if !(defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED)) /**************************************************************************//** @Function XX_DisableAllIntr @@ -279,29 +203,10 @@ uint32_t XX_DisableAllIntr(void); @Return None. *//***************************************************************************/ void XX_RestoreAllIntr(uint32_t flags); -#endif /* !(defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED)) */ -/**************************************************************************//** - @Function XX_Call - @Description Call a service in another task. - - Activate the routine "f" via the queue identified by "IntrManagerId". The - parameter to "f" is Id - the handle of the destination object - - @Param[in] intrManagerId - Queue ID. - @Param[in] f - routine pointer. - @Param[in] Id - the parameter to be passed to f(). - @Param[in] h_App - Application handle. - @Param[in] flags - Unused, - - @Return E_OK is returned on success. E_FAIL is returned otherwise (usually an operating system level failure). -*//***************************************************************************/ -t_Error XX_Call( uint32_t intrManagerId, - t_Error (* f)(t_Handle), - t_Handle Id, - t_Handle h_App, - uint16_t flags ); +t_Error XX_PreallocAndBindIntr(uintptr_t irq, unsigned int cpu); +t_Error XX_DeallocIntr(uintptr_t irq); /**************************************************************************//** @Function XX_Exit @@ -312,6 +217,7 @@ t_Error XX_Call( uint32_t intrManagerId, *//***************************************************************************/ void XX_Exit(int status); + /*****************************************************************************/ /* Tasklet Service Routines */ /*****************************************************************************/ @@ -552,18 +458,6 @@ void XX_StartTimer(t_Handle h_Timer, *//***************************************************************************/ void XX_StopTimer(t_Handle h_Timer); -/**************************************************************************//** - @Function XX_GetExpirationTime - - @Description Returns the time (in milliseconds) remaining until the - expiration of a timer. - - @Param[in] h_Timer - A handle to a timer. - - @Return The time left until the timer expires. -*//***************************************************************************/ -uint32_t XX_GetExpirationTime(t_Handle h_Timer); - /**************************************************************************//** @Function XX_ModTimer @@ -580,17 +474,6 @@ uint32_t XX_GetExpirationTime(t_Handle h_Timer); *//***************************************************************************/ void XX_ModTimer(t_Handle h_Timer, uint32_t msecs); -/**************************************************************************//** - @Function XX_TimerIsActive - - @Description Checks whether a timer is active (pending) or not. - - @Param[in] h_Timer - A handle to a timer. - - @Return 0 - the timer is inactive; Non-zero value - the timer is active; -*//***************************************************************************/ -int XX_TimerIsActive(t_Handle h_Timer); - /**************************************************************************//** @Function XX_Sleep @@ -598,7 +481,8 @@ int XX_TimerIsActive(t_Handle h_Timer); @Param[in] msecs - The requested sleep time (in milliseconds). - @Return None. + @Return Zero if the requested time has elapsed; Otherwise, the value + returned will be the unslept amount) in milliseconds. @Cautions This routine enables interrupts during its wait time. *//***************************************************************************/ @@ -647,28 +531,6 @@ void * XX_PhysToVirt(physAddress_t addr); *//***************************************************************************/ physAddress_t XX_VirtToPhys(void *addr); -/**************************************************************************//** - @Function XX_PortalSetInfo - - @Description Save physical and virtual adresses of the portals. - - @Param[in] dev - Portals device - either bman or qman. - - @Return Physical, virtual addresses and size. -*//***************************************************************************/ -void XX_PortalSetInfo(device_t dev); - -/**************************************************************************//** - @Function XX_FmanSetIntrInfo - - @Description Workaround for FMan interrupt, which must be binded to one CPU - only. - - @Param[in] irq - Interrupt number. - - @Return None. -*//***************************************************************************/ -void XX_FmanFixIntr(int irq); /**************************************************************************//** @Group xx_ipc XX Inter-Partition-Communication API @@ -930,4 +792,7 @@ t_Error XX_IpcSendMessage(t_Handle h_Session, /** @} */ /* end of xx_ipc group */ /** @} */ /* end of xx_id group */ + +void XX_PortalSetInfo(device_t dev); +void XX_FmanFixIntr(int irq); #endif /* __XX_EXT_H */ diff --git a/sys/contrib/ncsw/user/env/xx.c b/sys/contrib/ncsw/user/env/xx.c index c153c69dcef2..d422942d1daa 100644 --- a/sys/contrib/ncsw/user/env/xx.c +++ b/sys/contrib/ncsw/user/env/xx.c @@ -120,7 +120,7 @@ struct XX_PortalInfo { uint32_t portal_ci_size[2][MAXCPU]; vm_offset_t portal_ce_va[2]; vm_offset_t portal_ci_va[2]; - uint32_t portal_intr[2][MAXCPU]; + uintptr_t portal_intr[2][MAXCPU]; }; static struct XX_PortalInfo XX_PInfo; @@ -283,16 +283,8 @@ XX_RestoreAllIntr(uint32_t flags) intr_restore(flags); } -t_Error -XX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags ) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); - return (E_OK); -} - static bool -XX_IsPortalIntr(int irq) +XX_IsPortalIntr(uintptr_t irq) { int cpu, type; /* Check interrupt numbers of all available portals */ @@ -599,71 +591,6 @@ XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) XX_UnlockSpinlock(h_Spinlock); } -uint32_t -XX_CurrentTime(void) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); - return (0); -} - - -t_Handle -XX_CreateTimer(void) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); - return (NULL); -} - -void -XX_FreeTimer(t_Handle h_Timer) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); -} - -void -XX_StartTimer(t_Handle h_Timer, - uint32_t msecs, - bool periodic, - void (*f_TimerExpired)(t_Handle), - t_Handle h_Arg) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); -} - -uint32_t -XX_GetExpirationTime(t_Handle h_Timer) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); - return (0); -} - -void -XX_StopTimer(t_Handle h_Timer) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); -} - -void -XX_ModTimer(t_Handle h_Timer, uint32_t msecs) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); -} - -int -XX_TimerIsActive(t_Handle h_Timer) -{ - /* Not referenced */ - printf("NetCommSW: Unimplemented function %s() called!\n", __func__); - return (0); -} - uint32_t XX_Sleep(uint32_t msecs) { diff --git a/sys/contrib/octeon-sdk/cvmx-l2c.c b/sys/contrib/octeon-sdk/cvmx-l2c.c index 8a39f9ea95e0..26644e8fd90b 100644 --- a/sys/contrib/octeon-sdk/cvmx-l2c.c +++ b/sys/contrib/octeon-sdk/cvmx-l2c.c @@ -339,7 +339,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) static void fault_in(uint64_t addr, int len) { volatile char *ptr; - volatile char dummy; + volatile char dummy = 0; /* * Adjust addr and length so we get all cache lines even for * small ranges spanning two cache lines. diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c index ea5e0bf9f71c..86e63d58aabe 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c @@ -378,8 +378,7 @@ static void pagelist_page_free(vm_page_t pp) { vm_page_lock(pp); - vm_page_unwire(pp, PQ_INACTIVE); - if (pp->wire_count == 0 && pp->object == NULL) + if (vm_page_unwire(pp, PQ_INACTIVE) && pp->object == NULL) vm_page_free(pp); vm_page_unlock(pp); } diff --git a/sys/crypto/aesni/aesni.c b/sys/crypto/aesni/aesni.c index bfea2f0ab1bc..8b45f282a7ea 100644 --- a/sys/crypto/aesni/aesni.c +++ b/sys/crypto/aesni/aesni.c @@ -2,6 +2,7 @@ * Copyright (c) 2005-2008 Pawel Jakub Dawidek * Copyright (c) 2010 Konstantin Belousov * Copyright (c) 2014 The FreeBSD Foundation + * Copyright (c) 2017 Conrad Meyer * All rights reserved. * * Portions of this software were developed by John-Mark Gurney @@ -46,9 +47,23 @@ __FBSDID("$FreeBSD$"); #include #include #include + #include -#include +#include +#include +#include + +#include #include +#include + +#include +#include +#if defined(__i386__) +#include +#elif defined(__amd64__) +#include +#endif static struct mtx_padalign *ctx_mtx; static struct fpu_kern_ctx **ctx_fpu; @@ -57,11 +72,13 @@ struct aesni_softc { int dieing; int32_t cid; uint32_t sid; + bool has_aes; + bool has_sha; TAILQ_HEAD(aesni_sessions_head, aesni_session) sessions; struct rwlock lock; }; -#define AQUIRE_CTX(i, ctx) \ +#define ACQUIRE_CTX(i, ctx) \ do { \ (i) = PCPU_GET(cpuid); \ mtx_lock(&ctx_mtx[(i)]); \ @@ -79,9 +96,13 @@ static int aesni_freesession(device_t, uint64_t tid); static void aesni_freesession_locked(struct aesni_softc *sc, struct aesni_session *ses); static int aesni_cipher_setup(struct aesni_session *ses, - struct cryptoini *encini); + struct cryptoini *encini, struct cryptoini *authini); static int aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, struct cryptodesc *authcrd, struct cryptop *crp); +static int aesni_cipher_crypt(struct aesni_session *ses, + struct cryptodesc *enccrd, struct cryptodesc *authcrd, struct cryptop *crp); +static int aesni_cipher_mac(struct aesni_session *ses, struct cryptodesc *crd, + struct cryptop *crp); MALLOC_DEFINE(M_AESNI, "aesni_data", "AESNI Data"); @@ -95,26 +116,38 @@ aesni_identify(driver_t *drv, device_t parent) panic("aesni: could not attach"); } +static void +detect_cpu_features(bool *has_aes, bool *has_sha) +{ + + *has_aes = ((cpu_feature2 & CPUID2_AESNI) != 0 && + (cpu_feature2 & CPUID2_SSE41) != 0); + *has_sha = ((cpu_stdext_feature & CPUID_STDEXT_SHA) != 0 && + (cpu_feature2 & CPUID2_SSSE3) != 0); +} + static int aesni_probe(device_t dev) { + bool has_aes, has_sha; - if ((cpu_feature2 & CPUID2_AESNI) == 0) { - device_printf(dev, "No AESNI support.\n"); + detect_cpu_features(&has_aes, &has_sha); + if (!has_aes && !has_sha) { + device_printf(dev, "No AES or SHA support.\n"); return (EINVAL); - } + } else if (has_aes && has_sha) + device_set_desc(dev, + "AES-CBC,AES-XTS,AES-GCM,AES-ICM,SHA1,SHA256"); + else if (has_aes) + device_set_desc(dev, "AES-CBC,AES-XTS,AES-GCM,AES-ICM"); + else + device_set_desc(dev, "SHA1,SHA256"); - if ((cpu_feature2 & CPUID2_SSE41) == 0) { - device_printf(dev, "No SSE4.1 support.\n"); - return (EINVAL); - } - - device_set_desc_copy(dev, "AES-CBC,AES-XTS,AES-GCM,AES-ICM"); return (0); } static void -aensi_cleanctx(void) +aesni_cleanctx(void) { int i; @@ -161,13 +194,22 @@ aesni_attach(device_t dev) } rw_init(&sc->lock, "aesni_lock"); - crypto_register(sc->cid, CRYPTO_AES_CBC, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_ICM, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_NIST_GCM_16, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_128_NIST_GMAC, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_192_NIST_GMAC, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_256_NIST_GMAC, 0, 0); - crypto_register(sc->cid, CRYPTO_AES_XTS, 0, 0); + + detect_cpu_features(&sc->has_aes, &sc->has_sha); + if (sc->has_aes) { + crypto_register(sc->cid, CRYPTO_AES_CBC, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_ICM, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_NIST_GCM_16, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_128_NIST_GMAC, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_192_NIST_GMAC, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_256_NIST_GMAC, 0, 0); + crypto_register(sc->cid, CRYPTO_AES_XTS, 0, 0); + } + if (sc->has_sha) { + crypto_register(sc->cid, CRYPTO_SHA1, 0, 0); + crypto_register(sc->cid, CRYPTO_SHA1_HMAC, 0, 0); + crypto_register(sc->cid, CRYPTO_SHA2_256_HMAC, 0, 0); + } return (0); } @@ -198,7 +240,7 @@ aesni_detach(device_t dev) rw_destroy(&sc->lock); - aensi_cleanctx(); + aesni_cleanctx(); return (0); } @@ -208,7 +250,8 @@ aesni_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) { struct aesni_softc *sc; struct aesni_session *ses; - struct cryptoini *encini; + struct cryptoini *encini, *authini; + bool gcm_hash, gcm; int error; if (sidp == NULL || cri == NULL) { @@ -221,13 +264,20 @@ aesni_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) return (EINVAL); ses = NULL; + authini = NULL; encini = NULL; + gcm = false; + gcm_hash = false; for (; cri != NULL; cri = cri->cri_next) { switch (cri->cri_alg) { + case CRYPTO_AES_NIST_GCM_16: + gcm = true; + /* FALLTHROUGH */ case CRYPTO_AES_CBC: case CRYPTO_AES_ICM: case CRYPTO_AES_XTS: - case CRYPTO_AES_NIST_GCM_16: + if (!sc->has_aes) + goto unhandled; if (encini != NULL) { CRYPTDEB("encini already set"); return (EINVAL); @@ -241,16 +291,35 @@ aesni_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) * nothing to do here, maybe in the future cache some * values for GHASH */ + gcm_hash = true; + break; + case CRYPTO_SHA1: + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: + if (!sc->has_sha) + goto unhandled; + if (authini != NULL) { + CRYPTDEB("authini already set"); + return (EINVAL); + } + authini = cri; break; default: +unhandled: CRYPTDEB("unhandled algorithm"); return (EINVAL); } } - if (encini == NULL) { + if (encini == NULL && authini == NULL) { CRYPTDEB("no cipher"); return (EINVAL); } + /* + * GMAC algorithms are only supported with simultaneous GCM. Likewise + * GCM is not supported without GMAC. + */ + if (gcm_hash != gcm) + return (EINVAL); rw_wlock(&sc->lock); if (sc->dieing) { @@ -275,9 +344,13 @@ aesni_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) ses->used = 1; TAILQ_INSERT_TAIL(&sc->sessions, ses, next); rw_wunlock(&sc->lock); - ses->algo = encini->cri_alg; - error = aesni_cipher_setup(ses, encini); + if (encini != NULL) + ses->algo = encini->cri_alg; + if (authini != NULL) + ses->auth_algo = authini->cri_alg; + + error = aesni_cipher_setup(ses, encini, authini); if (error != 0) { CRYPTDEB("setup failed"); rw_wlock(&sc->lock); @@ -299,7 +372,7 @@ aesni_freesession_locked(struct aesni_softc *sc, struct aesni_session *ses) sid = ses->id; TAILQ_REMOVE(&sc->sessions, ses, next); - *ses = (struct aesni_session){}; + explicit_bzero(ses, sizeof(*ses)); ses->id = sid; TAILQ_INSERT_HEAD(&sc->sessions, ses, next); } @@ -351,6 +424,9 @@ aesni_process(device_t dev, struct cryptop *crp, int hint __unused) for (crd = crp->crp_desc; crd != NULL; crd = crd->crd_next) { switch (crd->crd_alg) { + case CRYPTO_AES_NIST_GCM_16: + needauth = 1; + /* FALLTHROUGH */ case CRYPTO_AES_CBC: case CRYPTO_AES_ICM: case CRYPTO_AES_XTS: @@ -361,24 +437,17 @@ aesni_process(device_t dev, struct cryptop *crp, int hint __unused) enccrd = crd; break; - case CRYPTO_AES_NIST_GCM_16: - if (enccrd != NULL) { - error = EINVAL; - goto out; - } - enccrd = crd; - needauth = 1; - break; - case CRYPTO_AES_128_NIST_GMAC: case CRYPTO_AES_192_NIST_GMAC: case CRYPTO_AES_256_NIST_GMAC: + case CRYPTO_SHA1: + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: if (authcrd != NULL) { error = EINVAL; goto out; } authcrd = crd; - needauth = 1; break; default: @@ -387,14 +456,16 @@ aesni_process(device_t dev, struct cryptop *crp, int hint __unused) } } - if (enccrd == NULL || (needauth && authcrd == NULL)) { + if ((enccrd == NULL && authcrd == NULL) || + (needauth && authcrd == NULL)) { error = EINVAL; goto out; } /* CBC & XTS can only handle full blocks for now */ - if ((enccrd->crd_alg == CRYPTO_AES_CBC || enccrd->crd_alg == - CRYPTO_AES_XTS) && (enccrd->crd_len % AES_BLOCK_LEN) != 0) { + if (enccrd != NULL && (enccrd->crd_alg == CRYPTO_AES_CBC || + enccrd->crd_alg == CRYPTO_AES_XTS) && + (enccrd->crd_len % AES_BLOCK_LEN) != 0) { error = EINVAL; goto out; } @@ -420,9 +491,9 @@ aesni_process(device_t dev, struct cryptop *crp, int hint __unused) return (error); } -uint8_t * +static uint8_t * aesni_cipher_alloc(struct cryptodesc *enccrd, struct cryptop *crp, - int *allocated) + bool *allocated) { struct mbuf *m; struct uio *uio; @@ -442,18 +513,18 @@ aesni_cipher_alloc(struct cryptodesc *enccrd, struct cryptop *crp, addr = (uint8_t *)iov->iov_base; } else addr = (uint8_t *)crp->crp_buf; - *allocated = 0; + *allocated = false; addr += enccrd->crd_skip; return (addr); alloc: addr = malloc(enccrd->crd_len, M_AESNI, M_NOWAIT); if (addr != NULL) { - *allocated = 1; + *allocated = true; crypto_copydata(crp->crp_flags, crp->crp_buf, enccrd->crd_skip, enccrd->crd_len, addr); } else - *allocated = 0; + *allocated = false; return (addr); } @@ -482,23 +553,40 @@ MODULE_VERSION(aesni, 1); MODULE_DEPEND(aesni, crypto, 1, 1, 1); static int -aesni_cipher_setup(struct aesni_session *ses, struct cryptoini *encini) +aesni_cipher_setup(struct aesni_session *ses, struct cryptoini *encini, + struct cryptoini *authini) { struct fpu_kern_ctx *ctx; - int error; - int kt, ctxidx; + int kt, ctxidx, keylen, error; - kt = is_fpu_kern_thread(0); + switch (ses->auth_algo) { + case CRYPTO_SHA1: + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: + if (authini->cri_klen % 8 != 0) + return (EINVAL); + keylen = authini->cri_klen / 8; + if (keylen > sizeof(ses->hmac_key)) + return (EINVAL); + if (ses->auth_algo == CRYPTO_SHA1 && keylen > 0) + return (EINVAL); + memcpy(ses->hmac_key, authini->cri_key, keylen); + ses->mlen = authini->cri_mlen; + } + + kt = is_fpu_kern_thread(0) || (encini == NULL); if (!kt) { - AQUIRE_CTX(ctxidx, ctx); + ACQUIRE_CTX(ctxidx, ctx); error = fpu_kern_enter(curthread, ctx, FPU_KERN_NORMAL | FPU_KERN_KTHR); if (error != 0) goto out; } - error = aesni_cipher_setup_common(ses, encini->cri_key, - encini->cri_klen); + error = 0; + if (encini != NULL) + error = aesni_cipher_setup_common(ses, encini->cri_key, + encini->cri_klen); if (!kt) { fpu_kern_leave(curthread, ctx); @@ -508,52 +596,201 @@ aesni_cipher_setup(struct aesni_session *ses, struct cryptoini *encini) return (error); } +static int +intel_sha1_update(void *vctx, const void *vdata, u_int datalen) +{ + struct sha1_ctxt *ctx = vctx; + const char *data = vdata; + size_t gaplen; + size_t gapstart; + size_t off; + size_t copysiz; + u_int blocks; + + off = 0; + /* Do any aligned blocks without redundant copying. */ + if (datalen >= 64 && ctx->count % 64 == 0) { + blocks = datalen / 64; + ctx->c.b64[0] += blocks * 64 * 8; + intel_sha1_step(ctx->h.b32, data + off, blocks); + off += blocks * 64; + } + + while (off < datalen) { + gapstart = ctx->count % 64; + gaplen = 64 - gapstart; + + copysiz = (gaplen < datalen - off) ? gaplen : datalen - off; + bcopy(&data[off], &ctx->m.b8[gapstart], copysiz); + ctx->count += copysiz; + ctx->count %= 64; + ctx->c.b64[0] += copysiz * 8; + if (ctx->count % 64 == 0) + intel_sha1_step(ctx->h.b32, (void *)ctx->m.b8, 1); + off += copysiz; + } + return (0); +} + +static void +SHA1_Finalize_fn(void *digest, void *ctx) +{ + sha1_result(ctx, digest); +} + +static int +intel_sha256_update(void *vctx, const void *vdata, u_int len) +{ + SHA256_CTX *ctx = vctx; + uint64_t bitlen; + uint32_t r; + u_int blocks; + const unsigned char *src = vdata; + + /* Number of bytes left in the buffer from previous updates */ + r = (ctx->count >> 3) & 0x3f; + + /* Convert the length into a number of bits */ + bitlen = len << 3; + + /* Update number of bits */ + ctx->count += bitlen; + + /* Handle the case where we don't need to perform any transforms */ + if (len < 64 - r) { + memcpy(&ctx->buf[r], src, len); + return (0); + } + + /* Finish the current block */ + memcpy(&ctx->buf[r], src, 64 - r); + intel_sha256_step(ctx->state, ctx->buf, 1); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks */ + if (len >= 64) { + blocks = len / 64; + intel_sha256_step(ctx->state, src, blocks); + src += blocks * 64; + len -= blocks * 64; + } + + /* Copy left over data into buffer */ + memcpy(ctx->buf, src, len); + return (0); +} + +static void +SHA256_Finalize_fn(void *digest, void *ctx) +{ + SHA256_Final(digest, ctx); +} + /* - * authcrd contains the associated date. + * Compute the HASH( (key ^ xorbyte) || buf ) */ +static void +hmac_internal(void *ctx, uint32_t *res, + int (*update)(void *, const void *, u_int), + void (*finalize)(void *, void *), uint8_t *key, uint8_t xorbyte, + const void *buf, size_t off, size_t buflen, int crpflags) +{ + size_t i; + + for (i = 0; i < 64; i++) + key[i] ^= xorbyte; + update(ctx, key, 64); + for (i = 0; i < 64; i++) + key[i] ^= xorbyte; + + crypto_apply(crpflags, __DECONST(void *, buf), off, buflen, + __DECONST(int (*)(void *, void *, u_int), update), ctx); + finalize(res, ctx); +} + static int aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, struct cryptodesc *authcrd, struct cryptop *crp) { struct fpu_kern_ctx *ctx; - uint8_t iv[AES_BLOCK_LEN]; - uint8_t tag[GMAC_DIGEST_LEN]; - uint8_t *buf, *authbuf; - int error, allocated, authallocated; - int ivlen, encflag; - int kt, ctxidx; + int error, ctxidx; + bool kt; - encflag = (enccrd->crd_flags & CRD_F_ENCRYPT) == CRD_F_ENCRYPT; + if (enccrd != NULL) { + if ((enccrd->crd_alg == CRYPTO_AES_ICM || + enccrd->crd_alg == CRYPTO_AES_NIST_GCM_16) && + (enccrd->crd_flags & CRD_F_IV_EXPLICIT) == 0) + return (EINVAL); + } - if ((enccrd->crd_alg == CRYPTO_AES_ICM || - enccrd->crd_alg == CRYPTO_AES_NIST_GCM_16) && - (enccrd->crd_flags & CRD_F_IV_EXPLICIT) == 0) - return (EINVAL); + error = 0; + kt = is_fpu_kern_thread(0); + if (!kt) { + ACQUIRE_CTX(ctxidx, ctx); + error = fpu_kern_enter(curthread, ctx, + FPU_KERN_NORMAL | FPU_KERN_KTHR); + if (error != 0) + goto out2; + } + + /* Do work */ + if (enccrd != NULL && authcrd != NULL) { + /* Perform the first operation */ + if (crp->crp_desc == enccrd) + error = aesni_cipher_crypt(ses, enccrd, authcrd, crp); + else + error = aesni_cipher_mac(ses, authcrd, crp); + if (error != 0) + goto out; + /* Perform the second operation */ + if (crp->crp_desc == enccrd) + error = aesni_cipher_mac(ses, authcrd, crp); + else + error = aesni_cipher_crypt(ses, enccrd, authcrd, crp); + } else if (enccrd != NULL) + error = aesni_cipher_crypt(ses, enccrd, authcrd, crp); + else + error = aesni_cipher_mac(ses, authcrd, crp); + + if (error != 0) + goto out; + +out: + if (!kt) { + fpu_kern_leave(curthread, ctx); +out2: + RELEASE_CTX(ctxidx, ctx); + } + return (error); +} + +static int +aesni_cipher_crypt(struct aesni_session *ses, struct cryptodesc *enccrd, + struct cryptodesc *authcrd, struct cryptop *crp) +{ + uint8_t iv[AES_BLOCK_LEN], tag[GMAC_DIGEST_LEN], *buf, *authbuf; + int error, ivlen; + bool encflag, allocated, authallocated; + + KASSERT(ses->algo != CRYPTO_AES_NIST_GCM_16 || authcrd != NULL, + ("AES_NIST_GCM_16 must include MAC descriptor")); buf = aesni_cipher_alloc(enccrd, crp, &allocated); if (buf == NULL) return (ENOMEM); - error = 0; - authbuf = NULL; - authallocated = 0; - if (authcrd != NULL) { + authallocated = false; + if (ses->algo == CRYPTO_AES_NIST_GCM_16) { authbuf = aesni_cipher_alloc(authcrd, crp, &authallocated); if (authbuf == NULL) { error = ENOMEM; - goto out1; + goto out; } } - kt = is_fpu_kern_thread(0); - if (!kt) { - AQUIRE_CTX(ctxidx, ctx); - error = fpu_kern_enter(curthread, ctx, - FPU_KERN_NORMAL|FPU_KERN_KTHR); - if (error != 0) - goto out2; - } - + error = 0; + encflag = (enccrd->crd_flags & CRD_F_ENCRYPT) == CRD_F_ENCRYPT; if ((enccrd->crd_flags & CRD_F_KEY_EXPLICIT) != 0) { error = aesni_cipher_setup_common(ses, enccrd->crd_key, enccrd->crd_klen); @@ -561,7 +798,6 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, goto out; } - /* XXX - validate that enccrd and authcrd have/use same key? */ switch (enccrd->crd_alg) { case CRYPTO_AES_CBC: case CRYPTO_AES_ICM: @@ -593,13 +829,6 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, enccrd->crd_inject, ivlen, iv); } - if (authcrd != NULL && !encflag) - crypto_copydata(crp->crp_flags, crp->crp_buf, - authcrd->crd_inject, GMAC_DIGEST_LEN, tag); - else - bzero(tag, sizeof tag); - - /* Do work */ switch (ses->algo) { case CRYPTO_AES_CBC: if (encflag) @@ -625,11 +854,21 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, iv); break; case CRYPTO_AES_NIST_GCM_16: - if (encflag) + if (!encflag) + crypto_copydata(crp->crp_flags, crp->crp_buf, + authcrd->crd_inject, GMAC_DIGEST_LEN, tag); + else + bzero(tag, sizeof tag); + + if (encflag) { AES_GCM_encrypt(buf, buf, authbuf, iv, tag, enccrd->crd_len, authcrd->crd_len, ivlen, ses->enc_schedule, ses->rounds); - else { + + if (authcrd != NULL) + crypto_copyback(crp->crp_flags, crp->crp_buf, + authcrd->crd_inject, GMAC_DIGEST_LEN, tag); + } else { if (!AES_GCM_decrypt(buf, buf, authbuf, iv, tag, enccrd->crd_len, authcrd->crd_len, ivlen, ses->enc_schedule, ses->rounds)) @@ -638,28 +877,78 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptodesc *enccrd, break; } - if (allocated) - crypto_copyback(crp->crp_flags, crp->crp_buf, enccrd->crd_skip, - enccrd->crd_len, buf); - - if (!error && authcrd != NULL) { - crypto_copyback(crp->crp_flags, crp->crp_buf, - authcrd->crd_inject, GMAC_DIGEST_LEN, tag); - } - out: - if (!kt) { - fpu_kern_leave(curthread, ctx); -out2: - RELEASE_CTX(ctxidx, ctx); - } - -out1: if (allocated) { - bzero(buf, enccrd->crd_len); + explicit_bzero(buf, enccrd->crd_len); free(buf, M_AESNI); } - if (authallocated) + if (authallocated) { + explicit_bzero(authbuf, authcrd->crd_len); free(authbuf, M_AESNI); + } return (error); } + +static int +aesni_cipher_mac(struct aesni_session *ses, struct cryptodesc *crd, + struct cryptop *crp) +{ + union { + struct SHA256Context sha2 __aligned(16); + struct sha1_ctxt sha1 __aligned(16); + } sctx; + uint32_t res[SHA2_256_HASH_LEN / sizeof(uint32_t)]; + int hashlen; + + if (crd->crd_flags != 0) + return (EINVAL); + + switch (ses->auth_algo) { + case CRYPTO_SHA1_HMAC: + hashlen = SHA1_HASH_LEN; + /* Inner hash: (K ^ IPAD) || data */ + sha1_init(&sctx.sha1); + hmac_internal(&sctx.sha1, res, intel_sha1_update, + SHA1_Finalize_fn, ses->hmac_key, 0x36, crp->crp_buf, + crd->crd_skip, crd->crd_len, crp->crp_flags); + /* Outer hash: (K ^ OPAD) || inner hash */ + sha1_init(&sctx.sha1); + hmac_internal(&sctx.sha1, res, intel_sha1_update, + SHA1_Finalize_fn, ses->hmac_key, 0x5C, res, 0, hashlen, 0); + break; + case CRYPTO_SHA1: + hashlen = SHA1_HASH_LEN; + sha1_init(&sctx.sha1); + crypto_apply(crp->crp_flags, crp->crp_buf, crd->crd_skip, + crd->crd_len, __DECONST(int (*)(void *, void *, u_int), + intel_sha1_update), &sctx.sha1); + sha1_result(&sctx.sha1, (void *)res); + break; + case CRYPTO_SHA2_256_HMAC: + hashlen = SHA2_256_HASH_LEN; + /* Inner hash: (K ^ IPAD) || data */ + SHA256_Init(&sctx.sha2); + hmac_internal(&sctx.sha2, res, intel_sha256_update, + SHA256_Finalize_fn, ses->hmac_key, 0x36, crp->crp_buf, + crd->crd_skip, crd->crd_len, crp->crp_flags); + /* Outer hash: (K ^ OPAD) || inner hash */ + SHA256_Init(&sctx.sha2); + hmac_internal(&sctx.sha2, res, intel_sha256_update, + SHA256_Finalize_fn, ses->hmac_key, 0x5C, res, 0, hashlen, + 0); + break; + default: + /* + * AES-GMAC authentication is verified while processing the + * enccrd + */ + return (0); + } + + if (ses->mlen != 0 && ses->mlen < hashlen) + hashlen = ses->mlen; + + crypto_copyback(crp->crp_flags, crp->crp_buf, crd->crd_inject, hashlen, + (void *)res); + return (0); +} diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h index 8b40e1ab0fec..0231d572fc78 100644 --- a/sys/crypto/aesni/aesni.h +++ b/sys/crypto/aesni/aesni.h @@ -56,12 +56,16 @@ struct aesni_session { uint8_t enc_schedule[AES_SCHED_LEN] __aligned(16); uint8_t dec_schedule[AES_SCHED_LEN] __aligned(16); uint8_t xts_schedule[AES_SCHED_LEN] __aligned(16); + /* Same as the SHA256 Blocksize. */ + uint8_t hmac_key[SHA1_HMAC_BLOCK_LEN] __aligned(16); int algo; int rounds; /* uint8_t *ses_ictx; */ /* uint8_t *ses_octx; */ /* int ses_mlen; */ int used; + int auth_algo; + int mlen; uint32_t id; TAILQ_ENTRY(aesni_session) next; }; @@ -111,7 +115,5 @@ int AES_GCM_decrypt(const unsigned char *in, unsigned char *out, int aesni_cipher_setup_common(struct aesni_session *ses, const uint8_t *key, int keylen); -uint8_t *aesni_cipher_alloc(struct cryptodesc *enccrd, struct cryptop *crp, - int *allocated); #endif /* _AESNI_H_ */ diff --git a/sys/crypto/aesni/intel_sha1.c b/sys/crypto/aesni/intel_sha1.c new file mode 100644 index 000000000000..e9e1836f8871 --- /dev/null +++ b/sys/crypto/aesni/intel_sha1.c @@ -0,0 +1,262 @@ +/******************************************************************************* +* Copyright (c) 2013, Intel Corporation +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * 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. +* +* * Neither the name of the Intel Corporation nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* +* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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. +******************************************************************************** +* +* Intel SHA Extensions optimized implementation of a SHA-1 update function +* +* The function takes a pointer to the current hash values, a pointer to the +* input data, and a number of 64 byte blocks to process. Once all blocks have +* been processed, the digest pointer is updated with the resulting hash value. +* The function only processes complete blocks, there is no functionality to +* store partial blocks. All message padding and hash value initialization must +* be done outside the update function. +* +* The indented lines in the loop are instructions related to rounds processing. +* The non-indented lines are instructions related to the message schedule. +* +* Author: Sean Gulley +* Date: July 2013 +* +******************************************************************************** +* +* Example complier command line: +* icc intel_sha_extensions_sha1_intrinsic.c +* gcc -msha -msse4 intel_sha_extensions_sha1_intrinsic.c +* +*******************************************************************************/ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +void intel_sha1_step(uint32_t *digest, const char *data, uint32_t num_blks) { + __m128i abcd, e0, e1; + __m128i abcd_save, e_save; + __m128i msg0, msg1, msg2, msg3; + __m128i shuf_mask, e_mask; + +#if 0 + e_mask = _mm_set_epi64x(0xFFFFFFFF00000000ull, 0x0000000000000000ull); +#else + (void)e_mask; + e0 = _mm_set_epi64x(0, 0); +#endif + shuf_mask = _mm_set_epi64x(0x0001020304050607ull, 0x08090a0b0c0d0e0full); + + // Load initial hash values + abcd = _mm_loadu_si128((__m128i*) digest); + e0 = _mm_insert_epi32(e0, *(digest+4), 3); + abcd = _mm_shuffle_epi32(abcd, 0x1B); +#if 0 + e0 = _mm_and_si128(e0, e_mask); +#endif + + while (num_blks > 0) { + // Save hash values for addition after rounds + abcd_save = abcd; + e_save = e0; + + // Rounds 0-3 + msg0 = _mm_loadu_si128((const __m128i*) data); + msg0 = _mm_shuffle_epi8(msg0, shuf_mask); + e0 = _mm_add_epi32(e0, msg0); + e1 = abcd; + abcd = _mm_sha1rnds4_epu32(abcd, e0, 0); + + // Rounds 4-7 + msg1 = _mm_loadu_si128((const __m128i*) (data+16)); + msg1 = _mm_shuffle_epi8(msg1, shuf_mask); + e1 = _mm_sha1nexte_epu32(e1, msg1); + e0 = abcd; + abcd = _mm_sha1rnds4_epu32(abcd, e1, 0); + msg0 = _mm_sha1msg1_epu32(msg0, msg1); + + // Rounds 8-11 + msg2 = _mm_loadu_si128((const __m128i*) (data+32)); + msg2 = _mm_shuffle_epi8(msg2, shuf_mask); + e0 = _mm_sha1nexte_epu32(e0, msg2); + e1 = abcd; + abcd = _mm_sha1rnds4_epu32(abcd, e0, 0); + msg1 = _mm_sha1msg1_epu32(msg1, msg2); + msg0 = _mm_xor_si128(msg0, msg2); + + // Rounds 12-15 + msg3 = _mm_loadu_si128((const __m128i*) (data+48)); + msg3 = _mm_shuffle_epi8(msg3, shuf_mask); + e1 = _mm_sha1nexte_epu32(e1, msg3); + e0 = abcd; + msg0 = _mm_sha1msg2_epu32(msg0, msg3); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 0); + msg2 = _mm_sha1msg1_epu32(msg2, msg3); + msg1 = _mm_xor_si128(msg1, msg3); + + // Rounds 16-19 + e0 = _mm_sha1nexte_epu32(e0, msg0); + e1 = abcd; + msg1 = _mm_sha1msg2_epu32(msg1, msg0); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 0); + msg3 = _mm_sha1msg1_epu32(msg3, msg0); + msg2 = _mm_xor_si128(msg2, msg0); + + // Rounds 20-23 + e1 = _mm_sha1nexte_epu32(e1, msg1); + e0 = abcd; + msg2 = _mm_sha1msg2_epu32(msg2, msg1); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 1); + msg0 = _mm_sha1msg1_epu32(msg0, msg1); + msg3 = _mm_xor_si128(msg3, msg1); + + // Rounds 24-27 + e0 = _mm_sha1nexte_epu32(e0, msg2); + e1 = abcd; + msg3 = _mm_sha1msg2_epu32(msg3, msg2); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 1); + msg1 = _mm_sha1msg1_epu32(msg1, msg2); + msg0 = _mm_xor_si128(msg0, msg2); + + // Rounds 28-31 + e1 = _mm_sha1nexte_epu32(e1, msg3); + e0 = abcd; + msg0 = _mm_sha1msg2_epu32(msg0, msg3); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 1); + msg2 = _mm_sha1msg1_epu32(msg2, msg3); + msg1 = _mm_xor_si128(msg1, msg3); + + // Rounds 32-35 + e0 = _mm_sha1nexte_epu32(e0, msg0); + e1 = abcd; + msg1 = _mm_sha1msg2_epu32(msg1, msg0); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 1); + msg3 = _mm_sha1msg1_epu32(msg3, msg0); + msg2 = _mm_xor_si128(msg2, msg0); + + // Rounds 36-39 + e1 = _mm_sha1nexte_epu32(e1, msg1); + e0 = abcd; + msg2 = _mm_sha1msg2_epu32(msg2, msg1); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 1); + msg0 = _mm_sha1msg1_epu32(msg0, msg1); + msg3 = _mm_xor_si128(msg3, msg1); + + // Rounds 40-43 + e0 = _mm_sha1nexte_epu32(e0, msg2); + e1 = abcd; + msg3 = _mm_sha1msg2_epu32(msg3, msg2); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 2); + msg1 = _mm_sha1msg1_epu32(msg1, msg2); + msg0 = _mm_xor_si128(msg0, msg2); + + // Rounds 44-47 + e1 = _mm_sha1nexte_epu32(e1, msg3); + e0 = abcd; + msg0 = _mm_sha1msg2_epu32(msg0, msg3); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 2); + msg2 = _mm_sha1msg1_epu32(msg2, msg3); + msg1 = _mm_xor_si128(msg1, msg3); + + // Rounds 48-51 + e0 = _mm_sha1nexte_epu32(e0, msg0); + e1 = abcd; + msg1 = _mm_sha1msg2_epu32(msg1, msg0); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 2); + msg3 = _mm_sha1msg1_epu32(msg3, msg0); + msg2 = _mm_xor_si128(msg2, msg0); + + // Rounds 52-55 + e1 = _mm_sha1nexte_epu32(e1, msg1); + e0 = abcd; + msg2 = _mm_sha1msg2_epu32(msg2, msg1); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 2); + msg0 = _mm_sha1msg1_epu32(msg0, msg1); + msg3 = _mm_xor_si128(msg3, msg1); + + // Rounds 56-59 + e0 = _mm_sha1nexte_epu32(e0, msg2); + e1 = abcd; + msg3 = _mm_sha1msg2_epu32(msg3, msg2); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 2); + msg1 = _mm_sha1msg1_epu32(msg1, msg2); + msg0 = _mm_xor_si128(msg0, msg2); + + // Rounds 60-63 + e1 = _mm_sha1nexte_epu32(e1, msg3); + e0 = abcd; + msg0 = _mm_sha1msg2_epu32(msg0, msg3); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 3); + msg2 = _mm_sha1msg1_epu32(msg2, msg3); + msg1 = _mm_xor_si128(msg1, msg3); + + // Rounds 64-67 + e0 = _mm_sha1nexte_epu32(e0, msg0); + e1 = abcd; + msg1 = _mm_sha1msg2_epu32(msg1, msg0); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 3); + msg3 = _mm_sha1msg1_epu32(msg3, msg0); + msg2 = _mm_xor_si128(msg2, msg0); + + // Rounds 68-71 + e1 = _mm_sha1nexte_epu32(e1, msg1); + e0 = abcd; + msg2 = _mm_sha1msg2_epu32(msg2, msg1); + abcd = _mm_sha1rnds4_epu32(abcd, e1, 3); + msg3 = _mm_xor_si128(msg3, msg1); + + // Rounds 72-75 + e0 = _mm_sha1nexte_epu32(e0, msg2); + e1 = abcd; + msg3 = _mm_sha1msg2_epu32(msg3, msg2); + abcd = _mm_sha1rnds4_epu32(abcd, e0, 3); + + // Rounds 76-79 + e1 = _mm_sha1nexte_epu32(e1, msg3); + e0 = abcd; + abcd = _mm_sha1rnds4_epu32(abcd, e1, 3); + + // Add current hash values with previously saved + e0 = _mm_sha1nexte_epu32(e0, e_save); + abcd = _mm_add_epi32(abcd, abcd_save); + + data += 64; + num_blks--; + } + + abcd = _mm_shuffle_epi32(abcd, 0x1B); + _mm_store_si128((__m128i*) digest, abcd); + *(digest+4) = _mm_extract_epi32(e0, 3); +} + diff --git a/sys/crypto/aesni/intel_sha256.c b/sys/crypto/aesni/intel_sha256.c new file mode 100644 index 000000000000..06636ccd4986 --- /dev/null +++ b/sys/crypto/aesni/intel_sha256.c @@ -0,0 +1,278 @@ +/******************************************************************************* +* Copyright (c) 2013, Intel Corporation +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * 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. +* +* * Neither the name of the Intel Corporation nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* +* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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. +******************************************************************************** +* +* Intel SHA Extensions optimized implementation of a SHA-256 update function +* +* The function takes a pointer to the current hash values, a pointer to the +* input data, and a number of 64 byte blocks to process. Once all blocks have +* been processed, the digest pointer is updated with the resulting hash value. +* The function only processes complete blocks, there is no functionality to +* store partial blocks. All message padding and hash value initialization must +* be done outside the update function. +* +* The indented lines in the loop are instructions related to rounds processing. +* The non-indented lines are instructions related to the message schedule. +* +* Author: Sean Gulley +* Date: July 2013 +* +******************************************************************************** +* +* Example complier command line: +* icc intel_sha_extensions_sha256_intrinsic.c +* gcc -msha -msse4 intel_sha_extensions_sha256_intrinsic.c +* +*******************************************************************************/ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +void intel_sha256_step(uint32_t *digest, const char *data, uint32_t num_blks) { + __m128i state0, state1; + __m128i msg; + __m128i msgtmp0, msgtmp1, msgtmp2, msgtmp3; + __m128i tmp; + __m128i shuf_mask; + __m128i abef_save, cdgh_save; + + // Load initial hash values + // Need to reorder these appropriately + // DCBA, HGFE -> ABEF, CDGH + tmp = _mm_loadu_si128((__m128i*) digest); + state1 = _mm_loadu_si128((__m128i*) (digest+4)); + + tmp = _mm_shuffle_epi32(tmp, 0xB1); // CDAB + state1 = _mm_shuffle_epi32(state1, 0x1B); // EFGH + state0 = _mm_alignr_epi8(tmp, state1, 8); // ABEF + state1 = _mm_blend_epi16(state1, tmp, 0xF0); // CDGH + + shuf_mask = _mm_set_epi64x(0x0c0d0e0f08090a0bull, 0x0405060700010203ull); + + while (num_blks > 0) { + // Save hash values for addition after rounds + abef_save = state0; + cdgh_save = state1; + + // Rounds 0-3 + msg = _mm_loadu_si128((const __m128i*) data); + msgtmp0 = _mm_shuffle_epi8(msg, shuf_mask); + msg = _mm_add_epi32(msgtmp0, + _mm_set_epi64x(0xE9B5DBA5B5C0FBCFull, 0x71374491428A2F98ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + + // Rounds 4-7 + msgtmp1 = _mm_loadu_si128((const __m128i*) (data+16)); + msgtmp1 = _mm_shuffle_epi8(msgtmp1, shuf_mask); + msg = _mm_add_epi32(msgtmp1, + _mm_set_epi64x(0xAB1C5ED5923F82A4ull, 0x59F111F13956C25Bull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp0 = _mm_sha256msg1_epu32(msgtmp0, msgtmp1); + + // Rounds 8-11 + msgtmp2 = _mm_loadu_si128((const __m128i*) (data+32)); + msgtmp2 = _mm_shuffle_epi8(msgtmp2, shuf_mask); + msg = _mm_add_epi32(msgtmp2, + _mm_set_epi64x(0x550C7DC3243185BEull, 0x12835B01D807AA98ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp1 = _mm_sha256msg1_epu32(msgtmp1, msgtmp2); + + // Rounds 12-15 + msgtmp3 = _mm_loadu_si128((const __m128i*) (data+48)); + msgtmp3 = _mm_shuffle_epi8(msgtmp3, shuf_mask); + msg = _mm_add_epi32(msgtmp3, + _mm_set_epi64x(0xC19BF1749BDC06A7ull, 0x80DEB1FE72BE5D74ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp3, msgtmp2, 4); + msgtmp0 = _mm_add_epi32(msgtmp0, tmp); + msgtmp0 = _mm_sha256msg2_epu32(msgtmp0, msgtmp3); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp2 = _mm_sha256msg1_epu32(msgtmp2, msgtmp3); + + // Rounds 16-19 + msg = _mm_add_epi32(msgtmp0, + _mm_set_epi64x(0x240CA1CC0FC19DC6ull, 0xEFBE4786E49B69C1ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp0, msgtmp3, 4); + msgtmp1 = _mm_add_epi32(msgtmp1, tmp); + msgtmp1 = _mm_sha256msg2_epu32(msgtmp1, msgtmp0); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp3 = _mm_sha256msg1_epu32(msgtmp3, msgtmp0); + + // Rounds 20-23 + msg = _mm_add_epi32(msgtmp1, + _mm_set_epi64x(0x76F988DA5CB0A9DCull, 0x4A7484AA2DE92C6Full)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp1, msgtmp0, 4); + msgtmp2 = _mm_add_epi32(msgtmp2, tmp); + msgtmp2 = _mm_sha256msg2_epu32(msgtmp2, msgtmp1); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp0 = _mm_sha256msg1_epu32(msgtmp0, msgtmp1); + + // Rounds 24-27 + msg = _mm_add_epi32(msgtmp2, + _mm_set_epi64x(0xBF597FC7B00327C8ull, 0xA831C66D983E5152ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp2, msgtmp1, 4); + msgtmp3 = _mm_add_epi32(msgtmp3, tmp); + msgtmp3 = _mm_sha256msg2_epu32(msgtmp3, msgtmp2); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp1 = _mm_sha256msg1_epu32(msgtmp1, msgtmp2); + + // Rounds 28-31 + msg = _mm_add_epi32(msgtmp3, + _mm_set_epi64x(0x1429296706CA6351ull, 0xD5A79147C6E00BF3ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp3, msgtmp2, 4); + msgtmp0 = _mm_add_epi32(msgtmp0, tmp); + msgtmp0 = _mm_sha256msg2_epu32(msgtmp0, msgtmp3); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp2 = _mm_sha256msg1_epu32(msgtmp2, msgtmp3); + + // Rounds 32-35 + msg = _mm_add_epi32(msgtmp0, + _mm_set_epi64x(0x53380D134D2C6DFCull, 0x2E1B213827B70A85ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp0, msgtmp3, 4); + msgtmp1 = _mm_add_epi32(msgtmp1, tmp); + msgtmp1 = _mm_sha256msg2_epu32(msgtmp1, msgtmp0); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp3 = _mm_sha256msg1_epu32(msgtmp3, msgtmp0); + + // Rounds 36-39 + msg = _mm_add_epi32(msgtmp1, + _mm_set_epi64x(0x92722C8581C2C92Eull, 0x766A0ABB650A7354ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp1, msgtmp0, 4); + msgtmp2 = _mm_add_epi32(msgtmp2, tmp); + msgtmp2 = _mm_sha256msg2_epu32(msgtmp2, msgtmp1); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp0 = _mm_sha256msg1_epu32(msgtmp0, msgtmp1); + + // Rounds 40-43 + msg = _mm_add_epi32(msgtmp2, + _mm_set_epi64x(0xC76C51A3C24B8B70ull, 0xA81A664BA2BFE8A1ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp2, msgtmp1, 4); + msgtmp3 = _mm_add_epi32(msgtmp3, tmp); + msgtmp3 = _mm_sha256msg2_epu32(msgtmp3, msgtmp2); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp1 = _mm_sha256msg1_epu32(msgtmp1, msgtmp2); + + // Rounds 44-47 + msg = _mm_add_epi32(msgtmp3, + _mm_set_epi64x(0x106AA070F40E3585ull, 0xD6990624D192E819ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp3, msgtmp2, 4); + msgtmp0 = _mm_add_epi32(msgtmp0, tmp); + msgtmp0 = _mm_sha256msg2_epu32(msgtmp0, msgtmp3); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp2 = _mm_sha256msg1_epu32(msgtmp2, msgtmp3); + + // Rounds 48-51 + msg = _mm_add_epi32(msgtmp0, + _mm_set_epi64x(0x34B0BCB52748774Cull, 0x1E376C0819A4C116ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp0, msgtmp3, 4); + msgtmp1 = _mm_add_epi32(msgtmp1, tmp); + msgtmp1 = _mm_sha256msg2_epu32(msgtmp1, msgtmp0); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + msgtmp3 = _mm_sha256msg1_epu32(msgtmp3, msgtmp0); + + // Rounds 52-55 + msg = _mm_add_epi32(msgtmp1, + _mm_set_epi64x(0x682E6FF35B9CCA4Full, 0x4ED8AA4A391C0CB3ull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp1, msgtmp0, 4); + msgtmp2 = _mm_add_epi32(msgtmp2, tmp); + msgtmp2 = _mm_sha256msg2_epu32(msgtmp2, msgtmp1); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + + // Rounds 56-59 + msg = _mm_add_epi32(msgtmp2, + _mm_set_epi64x(0x8CC7020884C87814ull, 0x78A5636F748F82EEull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + tmp = _mm_alignr_epi8(msgtmp2, msgtmp1, 4); + msgtmp3 = _mm_add_epi32(msgtmp3, tmp); + msgtmp3 = _mm_sha256msg2_epu32(msgtmp3, msgtmp2); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + + // Rounds 60-63 + msg = _mm_add_epi32(msgtmp3, + _mm_set_epi64x(0xC67178F2BEF9A3F7ull, 0xA4506CEB90BEFFFAull)); + state1 = _mm_sha256rnds2_epu32(state1, state0, msg); + msg = _mm_shuffle_epi32(msg, 0x0E); + state0 = _mm_sha256rnds2_epu32(state0, state1, msg); + + // Add current hash values with previously saved + state0 = _mm_add_epi32(state0, abef_save); + state1 = _mm_add_epi32(state1, cdgh_save); + + data += 64; + num_blks--; + } + + // Write hash values back in the correct order + tmp = _mm_shuffle_epi32(state0, 0x1B); // FEBA + state1 = _mm_shuffle_epi32(state1, 0xB1); // DCHG + state0 = _mm_blend_epi16(tmp, state1, 0xF0); // DCBA + state1 = _mm_alignr_epi8(state1, tmp, 8); // ABEF + + _mm_store_si128((__m128i*) digest, state0); + _mm_store_si128((__m128i*) (digest+4), state1); +} + diff --git a/bin/rcp/extern.h b/sys/crypto/aesni/sha_sse.h similarity index 61% rename from bin/rcp/extern.h rename to sys/crypto/aesni/sha_sse.h index 075764899d3b..1d41f0b1a810 100644 --- a/bin/rcp/extern.h +++ b/sys/crypto/aesni/sha_sse.h @@ -1,6 +1,6 @@ /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2017 Conrad Meyer + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,14 +10,11 @@ * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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) @@ -26,22 +23,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)extern.h 8.1 (Berkeley) 5/31/93 * $FreeBSD$ */ -typedef struct { - size_t cnt; - char *buf; -} BUF; +#ifndef _CRYPTO__SHA_SSE_H_ +#define _CRYPTO__SHA_SSE_H_ -extern int iamremote; +/* + * Internal functions, implemented in intrinsics. + */ +void intel_sha1_step(uint32_t *digest, const char *data, uint32_t num_blks); +void intel_sha256_step(uint32_t *digest, const char *data, uint32_t num_blks); -BUF *allocbuf(BUF *, int, int); -char *colon(char *); -void lostconn(int); -void nospace(void); -int okname(char *); -void run_err(const char *, ...) __printflike(1, 2); -int susystem(char *, int); -void verifydir(char *); +#endif /* _CRYPTO__SHA_SSE_H_ */ diff --git a/sys/crypto/via/padlock_hash.c b/sys/crypto/via/padlock_hash.c index 658043b4946a..ebc88787a934 100644 --- a/sys/crypto/via/padlock_hash.c +++ b/sys/crypto/via/padlock_hash.c @@ -81,19 +81,27 @@ static void padlock_sha1_final(uint8_t *hash, struct padlock_sha_ctx *ctx); static void padlock_sha256_final(uint8_t *hash, struct padlock_sha_ctx *ctx); static struct auth_hash padlock_hmac_sha1 = { - CRYPTO_SHA1_HMAC, "HMAC-SHA1", - 20, SHA1_HASH_LEN, SHA1_HMAC_BLOCK_LEN, sizeof(struct padlock_sha_ctx), - (void (*)(void *))padlock_sha_init, NULL, NULL, - (int (*)(void *, const uint8_t *, uint16_t))padlock_sha_update, - (void (*)(uint8_t *, void *))padlock_sha1_final + .type = CRYPTO_SHA1_HMAC, + .name = "HMAC-SHA1", + .keysize = SHA1_HMAC_BLOCK_LEN, + .hashsize = SHA1_HASH_LEN, + .ctxsize = sizeof(struct padlock_sha_ctx), + .blocksize = SHA1_HMAC_BLOCK_LEN, + .Init = (void (*)(void *))padlock_sha_init, + .Update = (int (*)(void *, const uint8_t *, uint16_t))padlock_sha_update, + .Final = (void (*)(uint8_t *, void *))padlock_sha1_final, }; static struct auth_hash padlock_hmac_sha256 = { - CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256", - 32, SHA2_256_HASH_LEN, SHA2_256_HMAC_BLOCK_LEN, sizeof(struct padlock_sha_ctx), - (void (*)(void *))padlock_sha_init, NULL, NULL, - (int (*)(void *, const uint8_t *, uint16_t))padlock_sha_update, - (void (*)(uint8_t *, void *))padlock_sha256_final + .type = CRYPTO_SHA2_256_HMAC, + .name = "HMAC-SHA2-256", + .keysize = SHA2_256_HMAC_BLOCK_LEN, + .hashsize = SHA2_256_HASH_LEN, + .ctxsize = sizeof(struct padlock_sha_ctx), + .blocksize = SHA2_256_HMAC_BLOCK_LEN, + .Init = (void (*)(void *))padlock_sha_init, + .Update = (int (*)(void *, const uint8_t *, uint16_t))padlock_sha_update, + .Final = (void (*)(uint8_t *, void *))padlock_sha256_final, }; MALLOC_DECLARE(M_PADLOCK); diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c index 8e3810279114..8330c373f5b5 100644 --- a/sys/dev/acpica/Osd/OsdSchedule.c +++ b/sys/dev/acpica/Osd/OsdSchedule.c @@ -274,9 +274,6 @@ AcpiOsGetTimer(void) struct bintime bt; UINT64 t; - /* XXX During early boot there is no (decent) timer available yet. */ - KASSERT(cold == 0, ("acpi: timer op not yet supported during boot")); - binuptime(&bt); t = (uint64_t)bt.sec * 10000000; t += ((uint64_t)10000000 * (uint32_t)(bt.frac >> 32)) >> 32; diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index daeaf67ea954..855e57b45d2b 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -1197,7 +1197,7 @@ acpi_cpu_idle(sbintime_t sbt) AcpiGetTimer(&end_time); if (cx_next->type == ACPI_STATE_C3) { AcpiGetTimer(&end_time); - end_time = acpi_TimerDelta(end_time, start_time); + AcpiGetTimerDuration(start_time, end_time, &end_time); } else end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate(); diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 7633fbafe9dc..35893bf6ce88 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -2747,5 +2747,8 @@ ahcipoll(struct cam_sim *sim) ahci_reset_to(ch); } } + +devclass_t ahci_devclass; + MODULE_VERSION(ahci, 1); MODULE_DEPEND(ahci, cam, 1, 1, 1); diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index 6b2a3cb70f0e..456fda51e142 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -649,3 +649,6 @@ bus_dma_tag_t ahci_get_dma_tag(device_t dev, device_t child); int ahci_ctlr_reset(device_t dev); int ahci_ctlr_setup(device_t dev); void ahci_free_mem(device_t dev); + +extern devclass_t ahci_devclass; + diff --git a/sys/dev/ahci/ahci_mv_fdt.c b/sys/dev/ahci/ahci_mv_fdt.c index cf5b85362b62..b5bc92339ba0 100644 --- a/sys/dev/ahci/ahci_mv_fdt.c +++ b/sys/dev/ahci/ahci_mv_fdt.c @@ -145,7 +145,6 @@ static device_method_t ahci_methods[] = { DEVMETHOD_END }; -static devclass_t ahci_devclass; static driver_t ahci_driver = { "ahci", ahci_methods, diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c index 0cd3dda947cc..4db10522c459 100644 --- a/sys/dev/ahci/ahci_pci.c +++ b/sys/dev/ahci/ahci_pci.c @@ -636,7 +636,6 @@ ahci_pci_resume(device_t dev) return (bus_generic_resume(dev)); } -devclass_t ahci_devclass; static device_method_t ahci_methods[] = { DEVMETHOD(device_probe, ahci_probe), DEVMETHOD(device_attach, ahci_pci_attach), diff --git a/sys/dev/amdsmn/amdsmn.c b/sys/dev/amdsmn/amdsmn.c index bc2ed7cb34e3..fb2c8b17328c 100644 --- a/sys/dev/amdsmn/amdsmn.c +++ b/sys/dev/amdsmn/amdsmn.c @@ -89,6 +89,8 @@ static driver_t amdsmn_driver = { static devclass_t amdsmn_devclass; DRIVER_MODULE(amdsmn, hostb, amdsmn_driver, amdsmn_devclass, NULL, NULL); MODULE_VERSION(amdsmn, 1); +MODULE_PNP_INFO("W32:vendor/device", pci, amdsmn, amdsmn_ids, + sizeof(amdsmn_ids[0]), nitems(amdsmn_ids)); static bool amdsmn_match(device_t parent) diff --git a/sys/dev/amdtemp/amdtemp.c b/sys/dev/amdtemp/amdtemp.c index 2080c92b8f2c..38086982211d 100644 --- a/sys/dev/amdtemp/amdtemp.c +++ b/sys/dev/amdtemp/amdtemp.c @@ -100,7 +100,6 @@ static struct amdtemp_product { { VENDORID_AMD, DEVICEID_AMD_MISC16_M30H }, { VENDORID_AMD, DEVICEID_AMD_MISC17 }, { VENDORID_AMD, DEVICEID_AMD_HOSTB17H }, - { 0, 0 } }; /* @@ -165,6 +164,8 @@ static devclass_t amdtemp_devclass; DRIVER_MODULE(amdtemp, hostb, amdtemp_driver, amdtemp_devclass, NULL, NULL); MODULE_VERSION(amdtemp, 1); MODULE_DEPEND(amdtemp, amdsmn, 1, 1, 1); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, amdtemp, amdtemp_products, + sizeof(amdtemp_products[0]), nitems(amdtemp_products)); static int amdtemp_match(device_t dev) @@ -175,7 +176,7 @@ amdtemp_match(device_t dev) vendor = pci_get_vendor(dev); devid = pci_get_device(dev); - for (i = 0; amdtemp_products[i].amdtemp_vendorid != 0; i++) { + for (i = 0; i < nitems(amdtemp_products); i++) { if (vendor == amdtemp_products[i].amdtemp_vendorid && devid == amdtemp_products[i].amdtemp_deviceid) return (1); diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 87e97109db76..1b0f47f71390 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -4049,10 +4049,14 @@ ath_txq_update(struct ath_softc *sc, int ac) #define ATH_EXPONENT_TO_VALUE(v) ((1<sc_ic; struct ath_txq *txq = sc->sc_ac2q[ac]; - struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; + struct chanAccParams chp; + struct wmeParams *wmep; struct ath_hal *ah = sc->sc_ah; HAL_TXQ_INFO qi; + ieee80211_wme_ic_getparams(ic, &chp); + wmep = &chp.cap_wmeParams[ac]; + ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi); #ifdef IEEE80211_SUPPORT_TDMA if (sc->sc_tdma) { diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index c077a68190e9..608e4c58f0f0 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -6094,8 +6094,10 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) if (get_mouse_status(kbdc, status, 0, 3) != 3) return (FALSE); - synhw.infoXupmm = status[0]; - synhw.infoYupmm = status[2]; + if (status[0] != 0 && (status[1] & 0x80) && status[2] != 0) { + synhw.infoXupmm = status[0]; + synhw.infoYupmm = status[2]; + } if (verbose >= 2) { printf(" Extended capabilities:\n"); diff --git a/sys/dev/bhnd/bcma/bcma.c b/sys/dev/bhnd/bcma/bcma.c index 7b4be6cb61b2..1915d173dcce 100644 --- a/sys/dev/bhnd/bcma/bcma.c +++ b/sys/dev/bhnd/bcma/bcma.c @@ -686,6 +686,7 @@ bcma_add_children(device_t bus) { bhnd_erom_t *erom; struct bcma_erom *bcma_erom; + struct bhnd_erom_io *eio; const struct bhnd_chipid *cid; struct bcma_corecfg *corecfg; struct bcma_devinfo *dinfo; @@ -696,9 +697,12 @@ bcma_add_children(device_t bus) corecfg = NULL; /* Allocate our EROM parser */ - erom = bhnd_erom_alloc(&bcma_erom_parser, cid, bus, BCMA_EROM_RID); - if (erom == NULL) + eio = bhnd_erom_iores_new(bus, BCMA_EROM_RID); + erom = bhnd_erom_alloc(&bcma_erom_parser, cid, eio); + if (erom == NULL) { + bhnd_erom_io_fini(eio); return (ENODEV); + } /* Add all cores. */ bcma_erom = (struct bcma_erom *)erom; diff --git a/sys/dev/bhnd/bcma/bcma_erom.c b/sys/dev/bhnd/bcma/bcma_erom.c index 87422535603c..88bd1a899a82 100644 --- a/sys/dev/bhnd/bcma/bcma_erom.c +++ b/sys/dev/bhnd/bcma/bcma_erom.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2017 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -58,13 +62,8 @@ __FBSDID("$FreeBSD$"); * marker. */ -struct bcma_erom_io; - static const char *bcma_erom_entry_type_name (uint8_t entry); -static uint32_t bcma_eio_read4(struct bcma_erom_io *io, - bus_size_t offset); - static int bcma_erom_read32(struct bcma_erom *erom, uint32_t *entry); static int bcma_erom_skip32(struct bcma_erom *erom); @@ -104,38 +103,19 @@ static void bcma_erom_to_core_info(const struct bcma_erom_core *core, u_int core_idx, int core_unit, struct bhnd_core_info *info); -/** - * BCMA EROM generic I/O context - */ -struct bcma_erom_io { - struct bhnd_resource *res; /**< memory resource, or NULL if initialized - with bus space tag and handle */ - int rid; /**< memory resource id, or -1 */ - - bus_space_tag_t bst; /**< bus space tag, if any */ - bus_space_handle_t bsh; /**< bus space handle, if any */ - - bus_size_t start; /**< base read offset */ -}; - /** * BCMA EROM per-instance state. */ struct bcma_erom { - struct bhnd_erom obj; - device_t dev; /**< parent device, or NULL if none. */ - struct bcma_erom_io io; /**< I/O context */ - bus_size_t offset; /**< current read offset */ + struct bhnd_erom obj; + device_t dev; /**< parent device, or NULL if none. */ + struct bhnd_erom_io *eio; /**< bus I/O callbacks */ + bhnd_size_t offset; /**< current read offset */ }; -#define EROM_LOG(erom, fmt, ...) do { \ - if (erom->dev != NULL) { \ - device_printf(erom->dev, "erom[0x%llx]: " fmt, \ - (unsigned long long) (erom->offset), ##__VA_ARGS__);\ - } else { \ - printf("erom[0x%llx]: " fmt, \ - (unsigned long long) (erom->offset), ##__VA_ARGS__);\ - } \ +#define EROM_LOG(erom, fmt, ...) do { \ + printf("%s erom[0x%llx]: " fmt, __FUNCTION__, \ + (unsigned long long)(erom->offset), ##__VA_ARGS__); \ } while(0) /** Return the type name for an EROM entry */ @@ -154,106 +134,52 @@ bcma_erom_entry_type_name (uint8_t entry) } } - -/** - * Read a 32-bit value from an EROM I/O context. - * - * @param io EROM I/O context. - * @param offset Read offset. - */ -static uint32_t -bcma_eio_read4(struct bcma_erom_io *io, bus_size_t offset) -{ - bus_size_t read_off; - - read_off = io->start + offset; - if (io->res != NULL) - return (bhnd_bus_read_4(io->res, read_off)); - else - return (bus_space_read_4(io->bst, io->bsh, read_off)); -} - -/* Initialize bcma_erom resource I/O context */ -static void -bcma_eio_init(struct bcma_erom_io *io, struct bhnd_resource *res, int rid, - bus_size_t offset) -{ - io->res = res; - io->rid = rid; - io->start = offset; -} - -/* Initialize bcma_erom bus space I/O context */ -static void -bcma_eio_init_static(struct bcma_erom_io *io, bus_space_tag_t bst, - bus_space_handle_t bsh, bus_size_t offset) -{ - io->res = NULL; - io->rid = -1; - io->bst = bst; - io->bsh = bsh; - io->start = offset; -} - /* BCMA implementation of BHND_EROM_INIT() */ static int bcma_erom_init(bhnd_erom_t *erom, const struct bhnd_chipid *cid, - device_t parent, int rid) + struct bhnd_erom_io *eio) { struct bcma_erom *sc; - struct bhnd_resource *res; + bhnd_addr_t table_addr; + int error; sc = (struct bcma_erom *)erom; - sc->dev = parent; + sc->eio = eio; sc->offset = 0; - res = bhnd_alloc_resource(parent, SYS_RES_MEMORY, &rid, cid->enum_addr, - cid->enum_addr + BCMA_EROM_TABLE_SIZE - 1, BCMA_EROM_TABLE_SIZE, - RF_ACTIVE|RF_SHAREABLE); + /* Determine erom table address */ + if (BHND_ADDR_MAX - BCMA_EROM_TABLE_START < cid->enum_addr) + return (ENXIO); /* would overflow */ - if (res == NULL) - return (ENOMEM); + table_addr = cid->enum_addr + BCMA_EROM_TABLE_START; - bcma_eio_init(&sc->io, res, rid, BCMA_EROM_TABLE_START); + /* Try to map the erom table */ + error = bhnd_erom_io_map(sc->eio, table_addr, BCMA_EROM_TABLE_SIZE); + if (error) + return (error); return (0); } -/* BCMA implementation of BHND_EROM_INIT_STATIC() */ +/* BCMA implementation of BHND_EROM_PROBE() */ static int -bcma_erom_init_static(bhnd_erom_t *erom, const struct bhnd_chipid *cid, - bus_space_tag_t bst, bus_space_handle_t bsh) +bcma_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio, + const struct bhnd_chipid *hint, struct bhnd_chipid *cid) { - struct bcma_erom *sc; - - sc = (struct bcma_erom *)erom; - sc->dev = NULL; - sc->offset = 0; - - bcma_eio_init_static(&sc->io, bst, bsh, BCMA_EROM_TABLE_START); - - return (0); -} - -/* Common implementation of BHND_EROM_PROBE/BHND_EROM_PROBE_STATIC */ -static int -bcma_erom_probe_common(struct bcma_erom_io *io, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) -{ - uint32_t idreg, eromptr; + uint32_t idreg, eromptr; /* Hints aren't supported; all BCMA devices have a ChipCommon * core */ if (hint != NULL) return (EINVAL); - /* Confirm CHIPC_EROMPTR availability */ - idreg = bcma_eio_read4(io, CHIPC_ID); + /* Confirm CHIPC_EROMPTR availability */ + idreg = bhnd_erom_io_read(eio, CHIPC_ID, 4); if (!BHND_CHIPTYPE_HAS_EROM(CHIPC_GET_BITS(idreg, CHIPC_ID_BUS))) return (ENXIO); /* Fetch EROM address */ - eromptr = bcma_eio_read4(io, CHIPC_EROMPTR); + eromptr = bhnd_erom_io_read(eio, CHIPC_EROMPTR, 4); /* Parse chip identifier */ *cid = bhnd_parse_chipid(idreg, eromptr); @@ -272,42 +198,12 @@ bcma_erom_probe_common(struct bcma_erom_io *io, const struct bhnd_chipid *hint, } } -static int -bcma_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res, - bus_size_t offset, const struct bhnd_chipid *hint, struct bhnd_chipid *cid) -{ - struct bcma_erom_io io; - - bcma_eio_init(&io, res, rman_get_rid(res->res), - offset + BCMA_EROM_TABLE_START); - - return (bcma_erom_probe_common(&io, hint, cid)); -} - -static int -bcma_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst, - bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) -{ - struct bcma_erom_io io; - - bcma_eio_init_static(&io, bst, bsh, BCMA_EROM_TABLE_START); - return (bcma_erom_probe_common(&io, hint, cid)); -} - - static void bcma_erom_fini(bhnd_erom_t *erom) { struct bcma_erom *sc = (struct bcma_erom *)erom; - if (sc->io.res != NULL) { - bhnd_release_resource(sc->dev, SYS_RES_MEMORY, sc->io.rid, - sc->io.res); - - sc->io.res = NULL; - sc->io.rid = -1; - } + bhnd_erom_io_fini(sc->eio); } static int @@ -591,8 +487,8 @@ bcma_erom_peek32(struct bcma_erom *erom, uint32_t *entry) EROM_LOG(erom, "BCMA EROM table missing terminating EOF\n"); return (EINVAL); } - - *entry = bcma_eio_read4(&erom->io, erom->offset); + + *entry = bhnd_erom_io_read(erom->eio, erom->offset, 4); return (0); } @@ -1520,9 +1416,7 @@ bcma_erom_dump(bhnd_erom_t *erom) static kobj_method_t bcma_erom_methods[] = { KOBJMETHOD(bhnd_erom_probe, bcma_erom_probe), - KOBJMETHOD(bhnd_erom_probe_static, bcma_erom_probe_static), KOBJMETHOD(bhnd_erom_init, bcma_erom_init), - KOBJMETHOD(bhnd_erom_init_static, bcma_erom_init_static), KOBJMETHOD(bhnd_erom_fini, bcma_erom_fini), KOBJMETHOD(bhnd_erom_get_core_table, bcma_erom_get_core_table), KOBJMETHOD(bhnd_erom_free_core_table, bcma_erom_free_core_table), diff --git a/sys/dev/bhnd/bhnd.c b/sys/dev/bhnd/bhnd.c index 104ca8ecb44a..f4c1ea29cf81 100644 --- a/sys/dev/bhnd/bhnd.c +++ b/sys/dev/bhnd/bhnd.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -69,11 +73,9 @@ __FBSDID("$FreeBSD$"); #include "bhnd.h" #include "bhndvar.h" -MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); +#include "bhnd_private.h" -/* Bus pass at which all bus-required children must be available, and - * attachment may be finalized. */ -#define BHND_FINISH_ATTACH_PASS BUS_PASS_DEFAULT +MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); /** * bhnd_generic_probe_nomatch() reporting configuration. @@ -92,23 +94,8 @@ static const struct bhnd_nomatch { { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } }; - static int bhnd_delete_children(struct bhnd_softc *sc); -static int bhnd_finish_attach(struct bhnd_softc *sc); - -static device_t bhnd_find_chipc(struct bhnd_softc *sc); -static struct chipc_caps *bhnd_find_chipc_caps(struct bhnd_softc *sc); -static device_t bhnd_find_platform_dev(struct bhnd_softc *sc, - const char *classname); -static device_t bhnd_find_pmu(struct bhnd_softc *sc); -static device_t bhnd_find_nvram(struct bhnd_softc *sc); - -static int compare_ascending_probe_order(const void *lhs, - const void *rhs); -static int compare_descending_probe_order(const void *lhs, - const void *rhs); - /** * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). * @@ -119,8 +106,6 @@ int bhnd_generic_attach(device_t dev) { struct bhnd_softc *sc; - device_t *devs; - int ndevs; int error; if (device_is_attached(dev)) @@ -129,29 +114,13 @@ bhnd_generic_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; - if ((error = device_get_children(dev, &devs, &ndevs))) - return (error); - /* Probe and attach all children */ - qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); - for (int i = 0; i < ndevs; i++) { - device_t child = devs[i]; - device_probe_and_attach(child); - } - - /* Try to finalize attachment */ - if (bus_current_pass >= BHND_FINISH_ATTACH_PASS) { - if ((error = bhnd_finish_attach(sc))) - goto cleanup; - } - -cleanup: - free(devs, M_TEMP); - - if (error) + if ((error = bhnd_bus_probe_children(dev))) { bhnd_delete_children(sc); + return (error); + } - return (error); + return (0); } /** @@ -164,11 +133,13 @@ bhnd_delete_children(struct bhnd_softc *sc) int ndevs; int error; - if ((error = device_get_children(sc->dev, &devs, &ndevs))) + /* Fetch children in detach order */ + error = bhnd_bus_get_children(sc->dev, &devs, &ndevs, + BHND_DEVICE_ORDER_DETACH); + if (error) return (error); - /* Detach in the reverse of attach order */ - qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); + /* Perform detach */ for (int i = 0; i < ndevs; i++) { device_t child = devs[i]; @@ -178,7 +149,7 @@ bhnd_delete_children(struct bhnd_softc *sc) } cleanup: - free(devs, M_TEMP); + bhnd_bus_free_children(devs); return (error); } @@ -193,12 +164,17 @@ int bhnd_generic_detach(device_t dev) { struct bhnd_softc *sc; + int error; if (!device_is_attached(dev)) return (EBUSY); sc = device_get_softc(dev); - return (bhnd_delete_children(sc)); + + if ((error = bhnd_delete_children(sc))) + return (error); + + return (0); } /** @@ -218,11 +194,13 @@ bhnd_generic_shutdown(device_t dev) if (!device_is_attached(dev)) return (EBUSY); - if ((error = device_get_children(dev, &devs, &ndevs))) + /* Fetch children in detach order */ + error = bhnd_bus_get_children(dev, &devs, &ndevs, + BHND_DEVICE_ORDER_DETACH); + if (error) return (error); - /* Shutdown in the reverse of attach order */ - qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); + /* Perform shutdown */ for (int i = 0; i < ndevs; i++) { device_t child = devs[i]; @@ -232,7 +210,7 @@ bhnd_generic_shutdown(device_t dev) } cleanup: - free(devs, M_TEMP); + bhnd_bus_free_children(devs); return (error); } @@ -253,10 +231,13 @@ bhnd_generic_resume(device_t dev) if (!device_is_attached(dev)) return (EBUSY); - if ((error = device_get_children(dev, &devs, &ndevs))) + /* Fetch children in attach order */ + error = bhnd_bus_get_children(dev, &devs, &ndevs, + BHND_DEVICE_ORDER_ATTACH); + if (error) return (error); - qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); + /* Perform resume */ for (int i = 0; i < ndevs; i++) { device_t child = devs[i]; @@ -266,7 +247,7 @@ bhnd_generic_resume(device_t dev) } cleanup: - free(devs, M_TEMP); + bhnd_bus_free_children(devs); return (error); } @@ -289,11 +270,13 @@ bhnd_generic_suspend(device_t dev) if (!device_is_attached(dev)) return (EBUSY); - if ((error = device_get_children(dev, &devs, &ndevs))) + /* Fetch children in detach order */ + error = bhnd_bus_get_children(dev, &devs, &ndevs, + BHND_DEVICE_ORDER_DETACH); + if (error) return (error); - /* Suspend in the reverse of attach order */ - qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); + /* Perform suspend */ for (int i = 0; i < ndevs; i++) { device_t child = devs[i]; error = BUS_SUSPEND_CHILD(device_get_parent(child), child); @@ -310,259 +293,10 @@ bhnd_generic_suspend(device_t dev) } cleanup: - free(devs, M_TEMP); + bhnd_bus_free_children(devs); return (error); } -static void -bhnd_new_pass(device_t dev) -{ - struct bhnd_softc *sc; - int error; - - sc = device_get_softc(dev); - - /* Attach any permissible children */ - bus_generic_new_pass(dev); - - /* Finalize attachment */ - if (!sc->attach_done && bus_current_pass >= BHND_FINISH_ATTACH_PASS) { - if ((error = bhnd_finish_attach(sc))) { - panic("bhnd_finish_attach() failed: %d", error); - } - } -} - -/* - * Finish any pending bus attachment operations. - * - * When attached as a SoC bus (as opposed to a bridged WiFi device), our - * platform devices may not be attached until later bus passes, necessitating - * delayed initialization on our part. - */ -static int -bhnd_finish_attach(struct bhnd_softc *sc) -{ - struct chipc_caps *ccaps; - - GIANT_REQUIRED; /* for newbus */ - - KASSERT(bus_current_pass >= BHND_FINISH_ATTACH_PASS, - ("bhnd_finish_attach() called in pass %d", bus_current_pass)); - - KASSERT(!sc->attach_done, ("duplicate call to bhnd_finish_attach()")); - - /* Locate chipc device */ - if ((sc->chipc_dev = bhnd_find_chipc(sc)) == NULL) { - device_printf(sc->dev, "error: ChipCommon device not found\n"); - return (ENXIO); - } - - ccaps = BHND_CHIPC_GET_CAPS(sc->chipc_dev); - - /* Look for NVRAM device */ - if (ccaps->nvram_src != BHND_NVRAM_SRC_UNKNOWN) { - if ((sc->nvram_dev = bhnd_find_nvram(sc)) == NULL) { - device_printf(sc->dev, - "warning: NVRAM %s device not found\n", - bhnd_nvram_src_name(ccaps->nvram_src)); - } - } - - /* Look for a PMU */ - if (ccaps->pmu || ccaps->pwr_ctrl) { - if ((sc->pmu_dev = bhnd_find_pmu(sc)) == NULL) { - device_printf(sc->dev, - "attach failed: supported PMU not found\n"); - return (ENXIO); - } - } - - /* Mark attach as completed */ - sc->attach_done = true; - - return (0); -} - -/* Locate the ChipCommon core. */ -static device_t -bhnd_find_chipc(struct bhnd_softc *sc) -{ - device_t chipc; - - /* Make sure we're holding Giant for newbus */ - GIANT_REQUIRED; - - /* chipc_dev is initialized during attachment */ - if (sc->attach_done) { - if ((chipc = sc->chipc_dev) == NULL) - return (NULL); - - goto found; - } - - /* Locate chipc core with a core unit of 0 */ - chipc = bhnd_find_child(sc->dev, BHND_DEVCLASS_CC, 0); - if (chipc == NULL) - return (NULL); - -found: - if (device_get_state(chipc) < DS_ATTACHING) { - device_printf(sc->dev, "chipc found, but did not attach\n"); - return (NULL); - } - - return (chipc); -} - -/* Locate the ChipCommon core and return the device capabilities */ -static struct chipc_caps * -bhnd_find_chipc_caps(struct bhnd_softc *sc) -{ - device_t chipc; - - if ((chipc = bhnd_find_chipc(sc)) == NULL) { - device_printf(sc->dev, - "chipc unavailable; cannot fetch capabilities\n"); - return (NULL); - } - - return (BHND_CHIPC_GET_CAPS(chipc)); -} - -/** - * Find an attached platform device on @p dev, searching first for cores - * matching @p classname, and if not found, searching the children of the first - * bhnd_chipc device on the bus. - * - * @param sc Driver state. - * @param chipc Attached ChipCommon device. - * @param classname Device class to search for. - * - * @retval device_t A matching device. - * @retval NULL If no matching device is found. - */ -static device_t -bhnd_find_platform_dev(struct bhnd_softc *sc, const char *classname) -{ - device_t chipc, child; - - /* Make sure we're holding Giant for newbus */ - GIANT_REQUIRED; - - /* Look for a directly-attached child */ - child = device_find_child(sc->dev, classname, -1); - if (child != NULL) - goto found; - - /* Look for the first matching ChipCommon child */ - if ((chipc = bhnd_find_chipc(sc)) == NULL) { - device_printf(sc->dev, - "chipc unavailable; cannot locate %s\n", classname); - return (NULL); - } - - child = device_find_child(chipc, classname, -1); - if (child != NULL) - goto found; - - /* Look for a parent-attached device (e.g. nexus0 -> bhnd_nvram) */ - child = device_find_child(device_get_parent(sc->dev), classname, -1); - if (child == NULL) - return (NULL); - -found: - if (device_get_state(child) < DS_ATTACHING) - return (NULL); - - return (child); -} - -/* Locate the PMU device, if any */ -static device_t -bhnd_find_pmu(struct bhnd_softc *sc) -{ - /* Make sure we're holding Giant for newbus */ - GIANT_REQUIRED; - - /* pmu_dev is initialized during attachment */ - if (sc->attach_done) { - if (sc->pmu_dev == NULL) - return (NULL); - - if (device_get_state(sc->pmu_dev) < DS_ATTACHING) - return (NULL); - - return (sc->pmu_dev); - } - - - return (bhnd_find_platform_dev(sc, "bhnd_pmu")); -} - -/* Locate the NVRAM device, if any */ -static device_t -bhnd_find_nvram(struct bhnd_softc *sc) -{ - struct chipc_caps *ccaps; - - /* Make sure we're holding Giant for newbus */ - GIANT_REQUIRED; - - - /* nvram_dev is initialized during attachment */ - if (sc->attach_done) { - if (sc->nvram_dev == NULL) - return (NULL); - - if (device_get_state(sc->nvram_dev) < DS_ATTACHING) - return (NULL); - - return (sc->nvram_dev); - } - - if ((ccaps = bhnd_find_chipc_caps(sc)) == NULL) - return (NULL); - - if (ccaps->nvram_src == BHND_NVRAM_SRC_UNKNOWN) - return (NULL); - - return (bhnd_find_platform_dev(sc, "bhnd_nvram")); -} - -/* - * Ascending comparison of bhnd device's probe order. - */ -static int -compare_ascending_probe_order(const void *lhs, const void *rhs) -{ - device_t ldev, rdev; - int lorder, rorder; - - ldev = (*(const device_t *) lhs); - rdev = (*(const device_t *) rhs); - - lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); - rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); - - if (lorder < rorder) { - return (-1); - } else if (lorder > rorder) { - return (1); - } else { - return (0); - } -} - -/* - * Descending comparison of bhnd device's probe order. - */ -static int -compare_descending_probe_order(const void *lhs, const void *rhs) -{ - return (compare_ascending_probe_order(rhs, lhs)); -} - /** * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). * @@ -613,7 +347,7 @@ bhnd_generic_get_probe_order(device_t dev, device_t child) case BHND_DEVCLASS_EROM: case BHND_DEVCLASS_OTHER: case BHND_DEVCLASS_INVALID: - if (bhnd_find_hostb_device(dev) == child) + if (bhnd_bus_find_hostb_device(dev) == child) return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); return (BHND_PROBE_DEFAULT); @@ -630,7 +364,6 @@ bhnd_generic_alloc_pmu(device_t dev, device_t child) { struct bhnd_softc *sc; struct bhnd_resource *br; - struct chipc_caps *ccaps; struct bhnd_core_pmu_info *pm; struct resource_list *rl; struct resource_list_entry *rle; @@ -646,18 +379,6 @@ bhnd_generic_alloc_pmu(device_t dev, device_t child) pm = bhnd_get_pmu_info(child); pmu_regs = BHND_CLK_CTL_ST; - if ((ccaps = bhnd_find_chipc_caps(sc)) == NULL) { - device_printf(sc->dev, "alloc_pmu failed: chipc " - "capabilities unavailable\n"); - return (ENXIO); - } - - if ((pmu_dev = bhnd_find_pmu(sc)) == NULL) { - device_printf(sc->dev, - "pmu unavailable; cannot allocate request state\n"); - return (ENXIO); - } - /* already allocated? */ if (pm != NULL) { panic("duplicate PMU allocation for %s", @@ -719,23 +440,34 @@ bhnd_generic_alloc_pmu(device_t dev, device_t child) else pmu_regs -= r_addr - rman_get_start(rle->res); + /* Retain PMU reference on behalf of our caller */ + pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU); + if (pmu_dev == NULL) { + device_printf(sc->dev, + "pmu unavailable; cannot allocate request state\n"); + return (ENXIO); + } + /* Allocate and initialize PMU info */ br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); - if (br == NULL) + if (br == NULL) { + bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); return (ENOMEM); + } br->res = rle->res; br->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0); pm = malloc(sizeof(*pm), M_BHND, M_NOWAIT); if (pm == NULL) { + bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); free(br, M_BHND); return (ENOMEM); } pm->pm_dev = child; - pm->pm_pmu = pmu_dev; pm->pm_res = br; pm->pm_regs = pmu_regs; + pm->pm_pmu = pmu_dev; bhnd_set_pmu_info(child, pm); return (0); @@ -749,29 +481,24 @@ bhnd_generic_release_pmu(device_t dev, device_t child) { struct bhnd_softc *sc; struct bhnd_core_pmu_info *pm; - device_t pmu; int error; GIANT_REQUIRED; /* for newbus */ sc = device_get_softc(dev); - if ((pmu = bhnd_find_pmu(sc)) == NULL) { - device_printf(sc->dev, - "pmu unavailable; cannot release request state\n"); - return (ENXIO); - } - /* dispatch release request */ pm = bhnd_get_pmu_info(child); if (pm == NULL) panic("pmu over-release for %s", device_get_nameunit(child)); - if ((error = BHND_PMU_CORE_RELEASE(pmu, pm))) + if ((error = BHND_PMU_CORE_RELEASE(pm->pm_pmu, pm))) return (error); /* free PMU info */ bhnd_set_pmu_info(child, NULL); + + bhnd_release_provider(pm->pm_dev, pm->pm_pmu, BHND_SERVICE_PMU); free(pm->pm_res, M_BHND); free(pm, M_BHND); @@ -875,9 +602,9 @@ bhnd_generic_is_region_valid(device_t dev, device_t child, /** * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). * - * This implementation searches @p dev for a usable NVRAM child device. + * This implementation searches @p dev for a registered NVRAM child device. * - * If no usable child device is found on @p dev, the request is delegated to + * If no NVRAM device is registered with @p dev, the request is delegated to * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. */ int @@ -886,12 +613,17 @@ bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, { struct bhnd_softc *sc; device_t nvram, parent; + int error; sc = device_get_softc(dev); /* If a NVRAM device is available, consult it first */ - if ((nvram = bhnd_find_nvram(sc)) != NULL) - return BHND_NVRAM_GETVAR(nvram, name, buf, size, type); + nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM); + if (nvram != NULL) { + error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type); + bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM); + return (error); + } /* Otherwise, try to delegate to parent */ if ((parent = device_get_parent(dev)) == NULL) @@ -1046,15 +778,6 @@ bhnd_generic_child_deleted(device_t dev, device_t child) panic("%s leaked device pmu state\n", device_get_nameunit(child)); } - - /* Clean up platform device references */ - if (sc->chipc_dev == child) { - sc->chipc_dev = NULL; - } else if (sc->nvram_dev == child) { - sc->nvram_dev = NULL; - } else if (sc->pmu_dev == child) { - sc->pmu_dev = NULL; - } } /** @@ -1176,7 +899,6 @@ static device_method_t bhnd_methods[] = { DEVMETHOD(device_resume, bhnd_generic_resume), /* Bus interface */ - DEVMETHOD(bus_new_pass, bhnd_new_pass), DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), DEVMETHOD(bus_print_child, bhnd_generic_print_child), diff --git a/sys/dev/bhnd/bhnd.h b/sys/dev/bhnd/bhnd.h index 2532c9d07092..33e34344968a 100644 --- a/sys/dev/bhnd/bhnd.h +++ b/sys/dev/bhnd/bhnd.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,8 +36,10 @@ #ifndef _BHND_BHND_H_ #define _BHND_BHND_H_ -#include +#include #include +#include +#include #include @@ -289,6 +295,35 @@ struct bhnd_device { #define BHND_DEVICE_IS_END(_d) \ (BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL) +/** + * bhnd device sort order. + */ +typedef enum { + BHND_DEVICE_ORDER_ATTACH, /**< sort by bhnd(4) device attach order; + child devices should be probed/attached + in this order */ + BHND_DEVICE_ORDER_DETACH, /**< sort by bhnd(4) device detach order; + child devices should be detached, suspended, + and shutdown in this order */ +} bhnd_device_order; + +/** + * A registry of bhnd service providers. + */ +struct bhnd_service_registry { + STAILQ_HEAD(,bhnd_service_entry) entries; /**< registered services */ + struct mtx lock; /**< state lock */ +}; + +/** + * bhnd service provider flags. + */ +enum { + BHND_SPF_INHERITED = (1<<0), /**< service provider reference was inherited from + a parent bus, and should be deregistered when the + last active reference is released */ +}; + const char *bhnd_vendor_name(uint16_t vendor); const char *bhnd_port_type_name(bhnd_port_type port_type); const char *bhnd_nvram_src_name(bhnd_nvram_src nvram_src); @@ -304,12 +339,23 @@ bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci); int bhnd_format_chip_id(char *buffer, size_t size, uint16_t chip_id); -device_t bhnd_match_child(device_t dev, +device_t bhnd_bus_match_child(device_t bus, const struct bhnd_core_match *desc); -device_t bhnd_find_child(device_t dev, +device_t bhnd_bus_find_child(device_t bus, bhnd_devclass_t class, int unit); +int bhnd_bus_get_children(device_t bus, + device_t **devlistp, int *devcountp, + bhnd_device_order order); + +void bhnd_bus_free_children(device_t *devlist); + +int bhnd_bus_probe_children(device_t bus); + +int bhnd_sort_devices(device_t *devlist, + size_t devcount, bhnd_device_order order); + device_t bhnd_find_bridge_root(device_t dev, devclass_t bus_class); @@ -410,6 +456,51 @@ int bhnd_nvram_getvar_array(device_t dev, const char *name, void *buf, size_t count, bhnd_nvram_type type); +int bhnd_service_registry_init( + struct bhnd_service_registry *bsr); +int bhnd_service_registry_fini( + struct bhnd_service_registry *bsr); +int bhnd_service_registry_add( + struct bhnd_service_registry *bsr, + device_t provider, + bhnd_service_t service, + uint32_t flags); +int bhnd_service_registry_remove( + struct bhnd_service_registry *bsr, + device_t provider, + bhnd_service_t service); +device_t bhnd_service_registry_retain( + struct bhnd_service_registry *bsr, + bhnd_service_t service); +bool bhnd_service_registry_release( + struct bhnd_service_registry *bsr, + device_t provider, + bhnd_service_t service); + +int bhnd_bus_generic_register_provider( + device_t dev, device_t child, + device_t provider, bhnd_service_t service); +int bhnd_bus_generic_deregister_provider( + device_t dev, device_t child, + device_t provider, bhnd_service_t service); +device_t bhnd_bus_generic_retain_provider(device_t dev, + device_t child, bhnd_service_t service); +void bhnd_bus_generic_release_provider(device_t dev, + device_t child, device_t provider, + bhnd_service_t service); + +int bhnd_bus_generic_sr_register_provider( + device_t dev, device_t child, + device_t provider, bhnd_service_t service); +int bhnd_bus_generic_sr_deregister_provider( + device_t dev, device_t child, + device_t provider, bhnd_service_t service); +device_t bhnd_bus_generic_sr_retain_provider(device_t dev, + device_t child, bhnd_service_t service); +void bhnd_bus_generic_sr_release_provider(device_t dev, + device_t child, device_t provider, + bhnd_service_t service); + bool bhnd_bus_generic_is_hw_disabled(device_t dev, device_t child); bool bhnd_bus_generic_is_region_valid(device_t dev, @@ -458,10 +549,84 @@ bhnd_driver_get_erom_class(driver_t *driver) * @param dev A bhnd bus device. */ static inline device_t -bhnd_find_hostb_device(device_t dev) { +bhnd_bus_find_hostb_device(device_t dev) { return (BHND_BUS_FIND_HOSTB_DEVICE(dev)); } +/** + * Register a provider for a given @p service. + * + * @param dev The device to register as a service provider + * with its parent bus. + * @param service The service for which @p dev will be registered. + * + * @retval 0 success + * @retval EEXIST if an entry for @p service already exists. + * @retval non-zero if registering @p dev otherwise fails, a regular + * unix error code will be returned. + */ +static inline int +bhnd_register_provider(device_t dev, bhnd_service_t service) +{ + return (BHND_BUS_REGISTER_PROVIDER(device_get_parent(dev), dev, dev, + service)); +} + + /** + * Attempt to remove a service provider registration for @p dev. + * + * @param dev The device to be deregistered as a service provider. + * @param service The service for which @p dev will be deregistered, or + * BHND_SERVICE_INVALID to remove all service registrations + * for @p dev. + * + * @retval 0 success + * @retval EBUSY if active references to @p dev exist; @see + * bhnd_retain_provider() and bhnd_release_provider(). + */ +static inline int +bhnd_deregister_provider(device_t dev, bhnd_service_t service) +{ + return (BHND_BUS_DEREGISTER_PROVIDER(device_get_parent(dev), dev, dev, + service)); +} + +/** + * Retain and return a reference to the registered @p service provider, if any. + * + * @param dev The requesting device. + * @param service The service for which a provider should be returned. + * + * On success, the caller assumes ownership the returned provider, and + * is responsible for releasing this reference via + * BHND_BUS_RELEASE_PROVIDER(). + * + * @retval device_t success + * @retval NULL if no provider is registered for @p service. + */ +static inline device_t +bhnd_retain_provider(device_t dev, bhnd_service_t service) +{ + return (BHND_BUS_RETAIN_PROVIDER(device_get_parent(dev), dev, + service)); +} + +/** + * Release a reference to a provider device previously returned by + * bhnd_retain_provider(). + * + * @param dev The requesting device. + * @param provider The provider to be released. + * @param service The service for which @p provider was previously retained. + */ +static inline void +bhnd_release_provider(device_t dev, device_t provider, + bhnd_service_t service) +{ + return (BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev, + provider, service)); +} + /** * Return true if the hardware components required by @p dev are known to be * unpopulated or otherwise unusable. diff --git a/sys/dev/bhnd/bhnd_bus_if.m b/sys/dev/bhnd/bhnd_bus_if.m index 1b2bff6d4159..28b513959e6e 100644 --- a/sys/dev/bhnd/bhnd_bus_if.m +++ b/sys/dev/bhnd/bhnd_bus_if.m @@ -1,7 +1,11 @@ #- # Copyright (c) 2015-2016 Landon Fuller +# Copyright (c) 2017 The FreeBSD Foundation # All rights reserved. # +# Portions of this software were developed by Landon Fuller +# under sponsorship from the FreeBSD Foundation. +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: @@ -221,6 +225,12 @@ CODE { return (NULL); } + static struct bhnd_service_registry * + bhnd_bus_null_get_service_registry(device_t dev) + { + panic("bhnd_bus_get_service_registry unimplemented"); + } + static bool bhnd_bus_null_is_hw_disabled(device_t dev, device_t child) { @@ -273,6 +283,100 @@ STATICMETHOD bhnd_erom_class_t * get_erom_class { driver_t *driver; } DEFAULT bhnd_bus_null_get_erom_class; +/** + * Register a shared bus @p provider for a given @p service. + * + * @param dev The parent of @p child. + * @param child The requesting child device. + * @param provider The service provider to register. + * @param service The service for which @p provider will be registered. + * + * @retval 0 success + * @retval EEXIST if an entry for @p service already exists. + * @retval non-zero if registering @p provider otherwise fails, a regular + * unix error code will be returned. + */ +METHOD int register_provider { + device_t dev; + device_t child; + device_t provider; + bhnd_service_t service; +} DEFAULT bhnd_bus_generic_register_provider; + + /** + * Attempt to remove the @p service provider registration for @p provider. + * + * @param dev The parent of @p child. + * @param child The requesting child device. + * @param provider The service provider to be deregistered. + * @param service The service for which @p provider will be deregistered, + * or BHND_SERVICE_INVALID to remove all service + * registrations for @p provider. + * + * @retval 0 success + * @retval EBUSY if active references to @p provider exist; @see + * BHND_BUS_RETAIN_PROVIDER() and + * BHND_BUS_RELEASE_PROVIDER(). + */ +METHOD int deregister_provider { + device_t dev; + device_t child; + device_t provider; + bhnd_service_t service; +} DEFAULT bhnd_bus_generic_deregister_provider; + +/** + * Retain and return a reference to the registered @p service provider, if any. + * + * @param dev The parent of @p child. + * @param child The requesting child device. + * @param service The service for which a provider should be returned. + * + * On success, the caller assumes ownership the returned provider, and + * is responsible for releasing this reference via + * BHND_BUS_RELEASE_PROVIDER(). + * + * @retval device_t success + * @retval NULL if no provider is registered for @p service. + */ +METHOD device_t retain_provider { + device_t dev; + device_t child; + bhnd_service_t service; +} DEFAULT bhnd_bus_generic_retain_provider; + + /** + * Release a reference to a service provider previously returned by + * BHND_BUS_RETAIN_PROVIDER(). + * + * @param dev The parent of @p child. + * @param child The requesting child device. + * @param provider The provider to be released. + * @param service The service for which @p provider was previously + * retained. + */ +METHOD void release_provider { + device_t dev; + device_t child; + device_t provider; + bhnd_service_t service; +} DEFAULT bhnd_bus_generic_release_provider; + +/** + * Return a struct bhnd_service_registry. + * + * Used by drivers which use bhnd_bus_generic_sr_register_provider() etc. + * to implement service provider registration. It should return a service + * registry that may be used to resolve provider requests from @p child. + * + * @param dev The parent of @p child. + * @param child The requesting child device. + */ +METHOD struct bhnd_service_registry * get_service_registry { + device_t dev; + device_t child; +} DEFAULT bhnd_bus_null_get_service_registry; + /** * Return the active host bridge core for the bhnd bus, if any. * diff --git a/sys/dev/bhnd/bhnd_erom.c b/sys/dev/bhnd/bhnd_erom.c index 1330c11bb71b..727e47cd7707 100644 --- a/sys/dev/bhnd/bhnd_erom.c +++ b/sys/dev/bhnd/bhnd_erom.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -31,20 +35,124 @@ __FBSDID("$FreeBSD$"); #include +#include #include + +#include +#include +#include #include #include +#include + +static int bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, + bhnd_size_t size); +static uint32_t bhnd_erom_iores_read(struct bhnd_erom_io *eio, + bhnd_size_t offset, u_int width); +static void bhnd_erom_iores_fini(struct bhnd_erom_io *eio); + +static int bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, + bhnd_size_t size); +static uint32_t bhnd_erom_iobus_read(struct bhnd_erom_io *eio, + bhnd_size_t offset, u_int width); + +/** + * An implementation of bhnd_erom_io that manages mappings via + * bhnd_alloc_resource() and bhnd_release_resource(). + */ +struct bhnd_erom_iores { + struct bhnd_erom_io eio; + device_t owner; /**< device from which we'll allocate resources */ + int owner_rid; /**< rid to use when allocating new mappings */ + struct bhnd_resource *mapped; /**< current mapping, or NULL */ + int mapped_rid; /**< resource ID of current mapping, or -1 */ +}; + +/** + * Fetch the device enumeration parser class from all bhnd(4)-compatible drivers + * registered for @p bus_devclass, probe @p eio for supporting parser classes, + * and return the best available supporting enumeration parser class. + * + * @param bus_devclass The bus device class to be queried for + * bhnd(4)-compatible drivers. + * @param eio An erom bus I/O instance, configured with a + * mapping of the first bus core. + * @param hint Identification hint used to identify the device. + * If the chipset supports standard chip + * identification registers within the first core, + * this parameter should be NULL. + * @param[out] cid On success, the probed chip identifier. + * + * @retval non-NULL on success, the best available EROM class. + * @retval NULL if no erom class returned a successful probe result for + * @p eio. + */ +bhnd_erom_class_t * +bhnd_erom_probe_driver_classes(devclass_t bus_devclass, + struct bhnd_erom_io *eio, const struct bhnd_chipid *hint, + struct bhnd_chipid *cid) +{ + driver_t **drivers; + int drv_count; + bhnd_erom_class_t *erom_cls; + int error, prio, result; + + erom_cls = NULL; + prio = 0; + + /* Fetch all available drivers */ + error = devclass_get_drivers(bus_devclass, &drivers, &drv_count); + if (error) { + printf("error fetching bhnd(4) drivers for %s: %d\n", + devclass_get_name(bus_devclass), error); + return (NULL); + } + + /* Enumerate the drivers looking for the best available EROM class */ + for (int i = 0; i < drv_count; i++) { + struct bhnd_chipid pcid; + bhnd_erom_class_t *cls; + + /* The default implementation of BHND_BUS_GET_EROM_CLASS() + * returns NULL if unimplemented; this should always be safe + * to call on arbitrary drivers */ + cls = bhnd_driver_get_erom_class(drivers[i]); + if (cls == NULL) + continue; + + kobj_class_compile(cls); + + /* Probe the bus */ + result = bhnd_erom_probe(cls, eio, hint, &pcid); + + /* The parser did not match if an error was returned */ + if (result > 0) + continue; + + /* Check for a new highest priority match */ + if (erom_cls == NULL || result > prio) { + prio = result; + + *cid = pcid; + erom_cls = cls; + } + + /* Terminate immediately on BUS_PROBE_SPECIFIC */ + if (result == BUS_PROBE_SPECIFIC) + break; + } + + return (erom_cls); +} /** * Allocate and return a new device enumeration table parser. * * @param cls The parser class for which an instance will be * allocated. - * @param parent The parent device from which EROM resources should - * be allocated. - * @param rid The resource ID to be used when allocating EROM - * resources. + * @param eio The bus I/O callbacks to use when reading the device + * enumeration table. * @param cid The device's chip identifier. * * @retval non-NULL success @@ -53,7 +161,7 @@ __FBSDID("$FreeBSD$"); */ bhnd_erom_t * bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid, - device_t parent, int rid) + struct bhnd_erom_io *eio) { bhnd_erom_t *erom; int error; @@ -61,10 +169,9 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid, erom = (bhnd_erom_t *)kobj_create((kobj_class_t)cls, M_BHND, M_WAITOK|M_ZERO); - if ((error = BHND_EROM_INIT(erom, cid, parent, rid))) { - printf("error initializing %s parser at %#jx with " - "rid %d: %d\n", cls->name, (uintmax_t)cid->enum_addr, rid, - error); + if ((error = BHND_EROM_INIT(erom, cid, eio))) { + printf("error initializing %s parser at %#jx: %d\n", cls->name, + (uintmax_t)cid->enum_addr, error); kobj_delete((kobj_t)erom, M_BHND); return (NULL); @@ -74,8 +181,7 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid, } /** - * Perform static initialization of aa device enumeration table parser using - * the provided bus space tag and handle. + * Perform static initialization of a device enumeration table parser. * * This may be used to initialize a caller-allocated erom instance state * during early boot, prior to malloc availability. @@ -87,9 +193,8 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid, * @p erom. If this is less than is required by @p cls, * ENOMEM will be returned. * @param cid The device's chip identifier. - * @param bst Bus space tag. - * @param bsh Bus space handle mapping the device enumeration - * space. + * @param eio The bus I/O callbacks to use when reading the device + * enumeration table. * * @retval 0 success * @retval ENOMEM if @p esize is smaller than required by @p cls. @@ -98,7 +203,7 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid, */ int bhnd_erom_init_static(bhnd_erom_class_t *cls, bhnd_erom_t *erom, size_t esize, - const struct bhnd_chipid *cid, bus_space_tag_t bst, bus_space_handle_t bsh) + const struct bhnd_chipid *cid, struct bhnd_erom_io *eio) { kobj_class_t kcls; @@ -110,7 +215,7 @@ bhnd_erom_init_static(bhnd_erom_class_t *cls, bhnd_erom_t *erom, size_t esize, /* Perform instance initialization */ kobj_init_static((kobj_t)erom, kcls); - return (BHND_EROM_INIT_STATIC(erom, cid, bst, bsh)); + return (BHND_EROM_INIT(erom, cid, eio)); } /** @@ -139,3 +244,243 @@ bhnd_erom_free(bhnd_erom_t *erom) BHND_EROM_FINI(erom); kobj_delete((kobj_t)erom, M_BHND); } + + +/** + * Attempt to map @p size bytes at @p addr, replacing any existing + * @p eio mapping. + * + * @param eio I/O instance state. + * @param addr The address to be mapped. + * @param size The number of bytes to be mapped at @p addr. + * + * @retval 0 success + * @retval non-zero if mapping @p addr otherwise fails, a regular + * unix error code should be returned. + */ +int +bhnd_erom_io_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, bhnd_size_t size) +{ + return (eio->map(eio, addr, size)); +} + +/** + * Read a 1, 2, or 4 byte data item from @p eio, at the given @p offset + * relative to @p eio's current mapping. + * + * @param eio erom I/O callbacks + * @param offset read offset. + * @param width item width (1, 2, or 4 bytes). + */ +uint32_t +bhnd_erom_io_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width) +{ + return (eio->read(eio, offset, width)); +} + +/** + * Free all resources held by @p eio. + */ +void +bhnd_erom_io_fini(struct bhnd_erom_io *eio) +{ + if (eio->fini != NULL) + return (eio->fini(eio)); +} + +/** + * Allocate, initialize, and return a new I/O instance that will perform + * mapping by allocating SYS_RES_MEMORY resources from @p dev using @p rid. + * + * @param dev The device to pass to bhnd_alloc_resource() and + * bhnd_release_resource() functions. + * @param rid The resource ID to be used when allocating memory resources. + */ +struct bhnd_erom_io * +bhnd_erom_iores_new(device_t dev, int rid) +{ + struct bhnd_erom_iores *iores; + + iores = malloc(sizeof(*iores), M_BHND, M_WAITOK | M_ZERO); + iores->eio.map = bhnd_erom_iores_map; + iores->eio.read = bhnd_erom_iores_read; + iores->eio.fini = bhnd_erom_iores_fini; + + iores->owner = dev; + iores->owner_rid = rid; + iores->mapped = NULL; + iores->mapped_rid = -1; + + return (&iores->eio); +} + +static int +bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, + bhnd_size_t size) +{ + struct bhnd_erom_iores *iores; + + iores = (struct bhnd_erom_iores *)eio; + + /* Sanity check the addr/size */ + if (size == 0) + return (EINVAL); + + if (BHND_ADDR_MAX - size < addr) + return (EINVAL); /* would overflow */ + + /* Check for an existing mapping */ + if (iores->mapped) { + /* If already mapped, nothing else to do */ + if (rman_get_start(iores->mapped->res) == addr && + rman_get_size(iores->mapped->res) == size) + { + return (0); + } + + /* Otherwise, we need to drop the existing mapping */ + bhnd_release_resource(iores->owner, SYS_RES_MEMORY, + iores->mapped_rid, iores->mapped); + iores->mapped = NULL; + iores->mapped_rid = -1; + } + + /* Try to allocate the new mapping */ + iores->mapped_rid = iores->owner_rid; + iores->mapped = bhnd_alloc_resource(iores->owner, SYS_RES_MEMORY, + &iores->mapped_rid, addr, addr+size-1, size, + RF_ACTIVE|RF_SHAREABLE); + if (iores->mapped == NULL) { + iores->mapped_rid = -1; + return (ENXIO); + } + + return (0); +} + +static uint32_t +bhnd_erom_iores_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width) +{ + struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio; + + if (iores->mapped == NULL) + panic("read with invalid mapping"); + + switch (width) { + case 1: + return (bhnd_bus_read_1(iores->mapped, offset)); + case 2: + return (bhnd_bus_read_2(iores->mapped, offset)); + case 4: + return (bhnd_bus_read_4(iores->mapped, offset)); + default: + panic("invalid width %u", width); + } +} + +static void +bhnd_erom_iores_fini(struct bhnd_erom_io *eio) +{ + struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio; + + /* Release any mapping */ + if (iores->mapped) { + bhnd_release_resource(iores->owner, SYS_RES_MEMORY, + iores->mapped_rid, iores->mapped); + iores->mapped = NULL; + iores->mapped_rid = -1; + } + + free(eio, M_BHND); +} + +/** + * Initialize an I/O instance that will perform mapping directly from the + * given bus space tag and handle. + * + * @param addr The base address mapped by @p bsh. + * @param size The total size mapped by @p bsh. + * @param bst Bus space tag for @p bsh. + * @param bsh Bus space handle mapping the full bus enumeration space. + * + * @retval 0 success + * @retval non-zero if initializing @p iobus otherwise fails, a regular + * unix error code will be returned. + */ +int +bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus, bhnd_addr_t addr, + bhnd_size_t size, bus_space_tag_t bst, bus_space_handle_t bsh) +{ + iobus->eio.map = bhnd_erom_iobus_map; + iobus->eio.read = bhnd_erom_iobus_read; + iobus->eio.fini = NULL; + + iobus->addr = addr; + iobus->size = size; + iobus->bst = bst; + iobus->bsh = bsh; + iobus->mapped = false; + + return (0); +} + +static int +bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, + bhnd_size_t size) +{ + struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio; + + /* Sanity check the addr/size */ + if (size == 0) + return (EINVAL); + + /* addr+size must not overflow */ + if (BHND_ADDR_MAX - size < addr) + return (EINVAL); + + /* addr/size must fit within our bus tag's mapping */ + if (addr < iobus->addr || size > iobus->size) + return (ENXIO); + + if (iobus->size - (addr - iobus->addr) < size) + return (ENXIO); + + /* The new addr offset and size must be representible as a bus_size_t */ + if ((addr - iobus->addr) > BUS_SPACE_MAXSIZE) + return (ENXIO); + + if (size > BUS_SPACE_MAXSIZE) + return (ENXIO); + + iobus->offset = addr - iobus->addr; + iobus->limit = size; + iobus->mapped = true; + + return (0); +} + +static uint32_t +bhnd_erom_iobus_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width) +{ + struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio; + + if (!iobus->mapped) + panic("no active mapping"); + + if (iobus->limit < width || iobus->limit - width < offset) + panic("invalid offset %#jx", offset); + + switch (width) { + case 1: + return (bus_space_read_1(iobus->bst, iobus->bsh, + iobus->offset + offset)); + case 2: + return (bus_space_read_2(iobus->bst, iobus->bsh, + iobus->offset + offset)); + case 4: + return (bus_space_read_4(iobus->bst, iobus->bsh, + iobus->offset + offset)); + default: + panic("invalid width %u", width); + } +} diff --git a/sys/dev/bhnd/bhnd_erom.h b/sys/dev/bhnd/bhnd_erom.h index b9c33c0445c8..28268d2d08ee 100644 --- a/sys/dev/bhnd/bhnd_erom.h +++ b/sys/dev/bhnd/bhnd_erom.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2015-2017 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,19 +45,38 @@ #include "bhnd_erom_if.h" -bhnd_erom_t *bhnd_erom_alloc(bhnd_erom_class_t *cls, - const struct bhnd_chipid *cid, - device_t parent, int rid); +/* forward declarations */ +struct bhnd_erom_io; +struct bhnd_erom_iobus; -int bhnd_erom_init_static(bhnd_erom_class_t *cls, - bhnd_erom_t *erom, size_t esize, - const struct bhnd_chipid *cid, - bus_space_tag_t bst, - bus_space_handle_t bsh); +bhnd_erom_class_t *bhnd_erom_probe_driver_classes(devclass_t bus_devclass, + struct bhnd_erom_io *eio, + const struct bhnd_chipid *hint, + struct bhnd_chipid *cid); -void bhnd_erom_fini_static(bhnd_erom_t *erom); +bhnd_erom_t *bhnd_erom_alloc(bhnd_erom_class_t *cls, + const struct bhnd_chipid *cid, + struct bhnd_erom_io *eio); -void bhnd_erom_free(bhnd_erom_t *erom); +int bhnd_erom_init_static(bhnd_erom_class_t *cls, + bhnd_erom_t *erom, size_t esize, + const struct bhnd_chipid *cid, + struct bhnd_erom_io *eio); + +void bhnd_erom_fini_static(bhnd_erom_t *erom); + +void bhnd_erom_free(bhnd_erom_t *erom); + +struct bhnd_erom_io *bhnd_erom_iores_new(device_t dev, int rid); +int bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus, + bhnd_addr_t addr, bhnd_size_t size, + bus_space_tag_t bst, bus_space_handle_t bsh); + +int bhnd_erom_io_map(struct bhnd_erom_io *eio, + bhnd_addr_t addr, bhnd_size_t size); +uint32_t bhnd_erom_io_read(struct bhnd_erom_io *eio, + bhnd_size_t offset, u_int width); +void bhnd_erom_io_fini(struct bhnd_erom_io *eio); /** * Abstract bhnd_erom instance state. Must be first member of all subclass @@ -92,19 +115,18 @@ SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t); #define BHND_EROM_CLASS_DEF(classvar) DATA_SET(bhnd_erom_class_set, classvar) - /** * Probe to see if this device enumeration class supports the bhnd bus - * mapped by the given resource, returning a standard newbus device probe - * result (see BUS_PROBE_*) and the probed chip identification. + * mapped by @p eio, returning a standard newbus device probe result + * (see BUS_PROBE_*) and the probed chip identification. * * @param cls The erom class to probe. - * @param res A resource mapping the first bus core (EXTIF or - * ChipCommon) - * @param offset Offset to the first bus core within @p res. - * @param hint Identification hint used to identify the device. If - * chipset supports standard chip identification registers - * within the first core, this parameter should be NULL. + * @param eio A bus I/O instance, configured with a mapping of the + * first bus core. + * @param hint Identification hint used to identify the device. + * If chipset supports standard chip identification + * registers within the first core, this parameter should + * be NULL. * @param[out] cid On success, the probed chip identifier. * * @retval 0 if this is the only possible device enumeration @@ -117,43 +139,10 @@ SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t); * code should be returned. */ static inline int -bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res, - bus_size_t offset, const struct bhnd_chipid *hint, struct bhnd_chipid *cid) +bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio, + const struct bhnd_chipid *hint, struct bhnd_chipid *cid) { - return (BHND_EROM_PROBE(cls, res, offset, hint, cid)); -} - -/** - * Probe to see if this device enumeration class supports the bhnd bus - * mapped at the given bus space tag and handle, returning a standard - * newbus device probe result (see BUS_PROBE_*) and the probed - * chip identification. - * - * @param cls The erom class to probe. - * @param bst Bus space tag. - * @param bsh Bus space handle mapping the EXTIF or ChipCommon core. - * @param paddr The physical address of the core mapped by @p bst and - * @p bsh. - * @param hint Identification hint used to identify the device. If - * chipset supports standard chip identification registers - * within the first core, this parameter should be NULL. - * @param[out] cid On success, the probed chip identifier. - * - * @retval 0 if this is the only possible device enumeration - * parser for the probed bus. - * @retval negative if the probe succeeds, a negative value should be - * returned; the parser returning the lowest value will - * be selected to handle device enumeration. - * @retval ENXIO If the bhnd bus type is not handled by this parser. - * @retval positive if an error occurs during probing, a regular unix error - * code should be returned. - */ -static inline int -bhnd_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst, - bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) -{ - return (BHND_EROM_PROBE_STATIC(cls, bst, bsh, paddr, hint, cid)); + return (BHND_EROM_PROBE(cls, eio, hint, cid)); } /** diff --git a/sys/dev/bhnd/bhnd_erom_if.m b/sys/dev/bhnd/bhnd_erom_if.m index cee0551b0dbc..a00699770c27 100644 --- a/sys/dev/bhnd/bhnd_erom_if.m +++ b/sys/dev/bhnd/bhnd_erom_if.m @@ -1,7 +1,11 @@ #- -# Copyright (c) 2016 Landon Fuller +# Copyright (c) 2016-2017 Landon Fuller +# Copyright (c) 2017 The FreeBSD Foundation # All rights reserved. # +# Portions of this software were developed by Landon Fuller +# under sponsorship from the FreeBSD Foundation. +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: @@ -43,18 +47,25 @@ INTERFACE bhnd_erom; # tables used by bhnd(4) buses. # +HEADER { + /* forward declarations */ + struct bhnd_erom_io; +}; + /** - * Probe to see if this device enumeration class supports the bhnd bus - * mapped by the given resource, returning a standard newbus device probe - * result (see BUS_PROBE_*) and the probed chip identification. + * Probe to see if this device enumeration class supports the bhnd bus at + * @p addr, returning a standard newbus device probe result (see BUS_PROBE_*) + * and the probed chip identification. * - * @param cls The erom class to probe. - * @param res A resource mapping the first bus core. - * @param offset Offset to the first bus core within @p res. - * @param hint Hint used to identify the device. If chipset supports - * standard chip identification registers within the first - * core, this parameter should be NULL. - * @param[out] cid On success, the probed chip identifier. + * @param cls The erom class to probe. + * @param eio A bus I/O instance, configured with a mapping of + * the first bus core. + * @param base_addr Address of the first bus core. + * @param hint Hint used to identify the device. If chipset + * supports standard chip identification registers + * within the first core, this parameter should be + * NULL. + * @param[out] cid On success, the probed chip identifier. * * @retval 0 if this is the only possible device enumeration * parser for the probed bus. @@ -67,42 +78,7 @@ INTERFACE bhnd_erom; */ STATICMETHOD int probe { bhnd_erom_class_t *cls; - struct bhnd_resource *res; - bus_size_t offset; - const struct bhnd_chipid *hint; - struct bhnd_chipid *cid; -}; - -/** - * Probe to see if this device enumeration class supports the bhnd bus - * mapped at the given bus space tag and handle, returning a standard - * newbus device probe result (see BUS_PROBE_*) and the probed - * chip identification. - * - * @param cls The erom class to probe. - * @param bst Bus space tag. - * @param bsh Bus space handle mapping the first bus core. - * @param paddr The physical address of the core mapped by @p bst and - * @p bsh. - * @param hint Hint used to identify the device. If chipset supports - * standard chip identification registers within the first - * core, this parameter should be NULL. - * @param[out] cid On success, the probed chip identifier. - * - * @retval 0 if this is the only possible device enumeration - * parser for the probed bus. - * @retval negative if the probe succeeds, a negative value should be - * returned; the parser returning the highest negative - * value will be selected to handle device enumeration. - * @retval ENXIO If the bhnd bus type is not handled by this parser. - * @retval positive if an error occurs during probing, a regular unix error - * code should be returned. - */ -STATICMETHOD int probe_static { - bhnd_erom_class_t *cls; - bus_space_tag_t bst; - bus_space_handle_t bsh; - bus_addr_t paddr; + struct bhnd_erom_io *eio; const struct bhnd_chipid *hint; struct bhnd_chipid *cid; }; @@ -112,11 +88,9 @@ STATICMETHOD int probe_static { * * @param erom The erom parser to initialize. * @param cid The device's chip identifier. - * @param parent The parent device from which EROM resources should - * be allocated. - * @param rid The resource id to be used when allocating the - * enumeration table. - * + * @param eio The bus I/O instance to use when reading the device + * enumeration table. On success, the erom parser assumes + * ownership of this instance. * @retval 0 success * @retval non-zero if an error occurs initializing the EROM parser, * a regular unix error code will be returned. @@ -124,29 +98,7 @@ STATICMETHOD int probe_static { METHOD int init { bhnd_erom_t *erom; const struct bhnd_chipid *cid; - device_t parent; - int rid; -}; - -/** - * Initialize an device enumeration table parser using the provided bus space - * tag and handle. - * - * @param erom The erom parser to initialize. - * @param cid The device's chip identifier. - * @param bst Bus space tag. - * @param bsh Bus space handle mapping the full bus enumeration - * space. - * - * @retval 0 success - * @retval non-zero if an error occurs initializing the EROM parser, - * a regular unix error code will be returned. - */ -METHOD int init_static { - bhnd_erom_t *erom; - const struct bhnd_chipid *cid; - bus_space_tag_t bst; - bus_space_handle_t bsh; + struct bhnd_erom_io *eio; }; /** diff --git a/sys/dev/bhnd/bhnd_eromvar.h b/sys/dev/bhnd/bhnd_eromvar.h new file mode 100644 index 000000000000..25fae616aa85 --- /dev/null +++ b/sys/dev/bhnd/bhnd_eromvar.h @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Landon Fuller under sponsorship from + * the FreeBSD Foundation. + * + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * 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 NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + * $FreeBSD$ + */ + +#ifndef _BHND_EROM_BHND_EROMVAR_H_ +#define _BHND_EROM_BHND_EROMVAR_H_ + +#include + +#include "bhnd_erom.h" + +/* forward declarations */ +struct bhnd_erom_io; +struct bhnd_erom_iobus; + +/** @see bhnd_erom_io_map() */ +typedef int (bhnd_erom_io_map_t)(struct bhnd_erom_io *eio, + bhnd_addr_t addr, bhnd_size_t size); + +/** @see bhnd_erom_io_read() */ +typedef uint32_t (bhnd_erom_io_read_t)(struct bhnd_erom_io *eio, + bhnd_size_t offset, u_int width); + +/** @see bhnd_erom_io_fini() */ +typedef void (bhnd_erom_io_fini_t)(struct bhnd_erom_io *eio); + +/** + * Abstract EROM bus I/O support. + */ +struct bhnd_erom_io { + bhnd_erom_io_map_t *map; /**< @see bhnd_erom_io_map() */ + bhnd_erom_io_read_t *read; /**< @see bhnd_erom_io_read() */ + bhnd_erom_io_fini_t *fini; /**< @see bhnd_erom_io_fini(). May be NULL */ +}; + +/** + * EROM bus handle/tag I/O instance state. + */ +struct bhnd_erom_iobus { + struct bhnd_erom_io eio; + bhnd_addr_t addr; /**< the address of @p bsh */ + bhnd_size_t size; /**< the size of @p bsh */ + bus_space_tag_t bst; /**< bus space tag */ + bus_space_handle_t bsh; /**< bus space handle mapping the full enumeration space */ + bool mapped; /**< if a mapping is active */ + bus_size_t offset; /**< the current mapped offset within bsh */ + bus_size_t limit; /**< the current mapped size relative to offset */ +}; + +#endif /* _BHND_EROM_BHND_EROMVAR_H_ */ diff --git a/sys/dev/bhnd/bhnd_private.h b/sys/dev/bhnd/bhnd_private.h new file mode 100644 index 000000000000..9c2ed900fa15 --- /dev/null +++ b/sys/dev/bhnd/bhnd_private.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Landon Fuller under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _BHND_BHND_PRIVATE_H_ +#define _BHND_BHND_PRIVATE_H_ + +#include +#include + +#include "bhnd_types.h" + +/* + * Private bhnd(4) driver definitions. + */ + +/** + * A bhnd(4) service registry entry. + */ +struct bhnd_service_entry { + device_t provider; /**< service provider */ + bhnd_service_t service; /**< service implemented */ + uint32_t flags; /**< entry flags (see BHND_SPF_*) */ + volatile u_int refs; /**< reference count; updated atomically + with only a shared lock held */ + + STAILQ_ENTRY(bhnd_service_entry) link; +}; + +#endif /* _BHND_BHND_PRIVATE_H_ */ diff --git a/sys/dev/bhnd/bhnd_subr.c b/sys/dev/bhnd/bhnd_subr.c index 716a8721ecec..992b887288fa 100644 --- a/sys/dev/bhnd/bhnd_subr.c +++ b/sys/dev/bhnd/bhnd_subr.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -51,6 +56,14 @@ __FBSDID("$FreeBSD$"); #include "bhndreg.h" #include "bhndvar.h" +#include "bhnd_private.h" + +static void bhnd_service_registry_free_entry( + struct bhnd_service_entry *entry); + +static int compare_ascending_probe_order(const void *lhs, const void *rhs); +static int compare_descending_probe_order(const void *lhs, + const void *rhs); /* BHND core device description table. */ static const struct bhnd_core_desc { @@ -331,9 +344,9 @@ bhnd_get_core_info(device_t dev) { } /** - * Find a @p class child device with @p unit on @p dev. + * Find a @p class child device with @p unit on @p bus. * - * @param parent The bhnd-compatible bus to be searched. + * @param bus The bhnd-compatible bus to be searched. * @param class The device class to match on. * @param unit The core unit number; specify -1 to return the first match * regardless of unit number. @@ -342,7 +355,7 @@ bhnd_get_core_info(device_t dev) { * @retval NULL if no matching child device is found. */ device_t -bhnd_find_child(device_t dev, bhnd_devclass_t class, int unit) +bhnd_bus_find_child(device_t bus, bhnd_devclass_t class, int unit) { struct bhnd_core_match md = { BHND_MATCH_CORE_CLASS(class), @@ -352,27 +365,27 @@ bhnd_find_child(device_t dev, bhnd_devclass_t class, int unit) if (unit == -1) md.m.match.core_unit = 0; - return bhnd_match_child(dev, &md); + return bhnd_bus_match_child(bus, &md); } /** - * Find the first child device on @p dev that matches @p desc. + * Find the first child device on @p bus that matches @p desc. * - * @param parent The bhnd-compatible bus to be searched. + * @param bus The bhnd-compatible bus to be searched. * @param desc A match descriptor. * * @retval device_t if a matching child device is found. * @retval NULL if no matching child device is found. */ device_t -bhnd_match_child(device_t dev, const struct bhnd_core_match *desc) +bhnd_bus_match_child(device_t bus, const struct bhnd_core_match *desc) { device_t *devlistp; device_t match; int devcnt; int error; - error = device_get_children(dev, &devlistp, &devcnt); + error = device_get_children(bus, &devlistp, &devcnt); if (error != 0) return (NULL); @@ -391,6 +404,146 @@ bhnd_match_child(device_t dev, const struct bhnd_core_match *desc) return match; } +/** + * Retrieve an ordered list of all device instances currently connected to + * @p bus, returning a pointer to the array in @p devlistp and the count + * in @p ndevs. + * + * The memory allocated for the table must be freed via + * bhnd_bus_free_children(). + * + * @param bus The bhnd-compatible bus to be queried. + * @param[out] devlist The array of devices. + * @param[out] devcount The number of devices in @p devlistp + * @param order The order in which devices will be returned + * in @p devlist. + * + * @retval 0 success + * @retval non-zero if an error occurs, a regular unix error code will + * be returned. + */ +int +bhnd_bus_get_children(device_t bus, device_t **devlist, int *devcount, + bhnd_device_order order) +{ + int error; + + /* Fetch device array */ + if ((error = device_get_children(bus, devlist, devcount))) + return (error); + + /* Perform requested sorting */ + if ((error = bhnd_sort_devices(*devlist, *devcount, order))) { + bhnd_bus_free_children(*devlist); + return (error); + } + + return (0); +} + +/** + * Free any memory allocated in a previous call to bhnd_bus_get_children(). + * + * @param devlist The device array returned by bhnd_bus_get_children(). + */ +void +bhnd_bus_free_children(device_t *devlist) +{ + free(devlist, M_TEMP); +} + +/** + * Perform in-place sorting of an array of bhnd device instances. + * + * @param devlist An array of bhnd devices. + * @param devcount The number of devices in @p devs. + * @param order The sort order to be used. + */ +int +bhnd_sort_devices(device_t *devlist, size_t devcount, bhnd_device_order order) +{ + int (*compare)(const void *, const void *); + + switch (order) { + case BHND_DEVICE_ORDER_ATTACH: + compare = compare_ascending_probe_order; + break; + case BHND_DEVICE_ORDER_DETACH: + compare = compare_descending_probe_order; + break; + default: + printf("unknown sort order: %d\n", order); + return (EINVAL); + } + + qsort(devlist, devcount, sizeof(*devlist), compare); + return (0); +} + +/* + * Ascending comparison of bhnd device's probe order. + */ +static int +compare_ascending_probe_order(const void *lhs, const void *rhs) +{ + device_t ldev, rdev; + int lorder, rorder; + + ldev = (*(const device_t *) lhs); + rdev = (*(const device_t *) rhs); + + lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); + rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); + + if (lorder < rorder) { + return (-1); + } else if (lorder > rorder) { + return (1); + } else { + return (0); + } +} + +/* + * Descending comparison of bhnd device's probe order. + */ +static int +compare_descending_probe_order(const void *lhs, const void *rhs) +{ + return (compare_ascending_probe_order(rhs, lhs)); +} + +/** + * Call device_probe_and_attach() for each of the bhnd bus device's + * children, in bhnd attach order. + * + * @param bus The bhnd-compatible bus for which all children should be probed + * and attached. + */ +int +bhnd_bus_probe_children(device_t bus) +{ + device_t *devs; + int ndevs; + int error; + + /* Fetch children in attach order */ + error = bhnd_bus_get_children(bus, &devs, &ndevs, + BHND_DEVICE_ORDER_ATTACH); + if (error) + return (error); + + /* Probe and attach all children */ + for (int i = 0; i < ndevs; i++) { + device_t child = devs[i]; + device_probe_and_attach(child); + } + + bhnd_bus_free_children(devs); + + return (0); +} + /** * Walk up the bhnd device hierarchy to locate the root device * to which the bhndb bridge is attached. @@ -727,7 +880,7 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table, uint32_t dflags; parent = device_get_parent(dev); - hostb = bhnd_find_hostb_device(parent); + hostb = bhnd_bus_find_hostb_device(parent); attach_type = bhnd_get_attach_type(dev); for (entry = table; !BHND_DEVICE_IS_END(entry); entry = @@ -1344,6 +1497,277 @@ bhnd_nvram_getvar_array(device_t dev, const char *name, void *buf, size_t size, return (0); } +/** + * Initialize a service provider registry. + * + * @param bsr The service registry to initialize. + * + * @retval 0 success + * @retval non-zero if an error occurs initializing the service registry, + * a regular unix error code will be returned. + + */ +int +bhnd_service_registry_init(struct bhnd_service_registry *bsr) +{ + STAILQ_INIT(&bsr->entries); + mtx_init(&bsr->lock, "bhnd_service_registry lock", NULL, MTX_DEF); + + return (0); +} + +/** + * Release all resources held by @p bsr. + * + * @param bsr A service registry instance previously successfully + * initialized via bhnd_service_registry_init(). + * + * @retval 0 success + * @retval EBUSY if active references to service providers registered + * with @p bsr exist. + */ +int +bhnd_service_registry_fini(struct bhnd_service_registry *bsr) +{ + struct bhnd_service_entry *entry, *enext; + + /* Remove everthing we can */ + mtx_lock(&bsr->lock); + STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { + if (entry->refs > 0) + continue; + + STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); + free(entry, M_BHND); + } + + if (!STAILQ_EMPTY(&bsr->entries)) { + mtx_unlock(&bsr->lock); + return (EBUSY); + } + mtx_unlock(&bsr->lock); + + mtx_destroy(&bsr->lock); + return (0); +} + +/** + * Register a @p provider for the given @p service. + * + * @param bsr Service registry to be modified. + * @param provider Service provider to register. + * @param service Service for which @p provider will be registered. + * @param flags Service provider flags (see BHND_SPF_*). + * + * @retval 0 success + * @retval EEXIST if an entry for @p service already exists. + * @retval EINVAL if @p service is BHND_SERVICE_ANY. + * @retval non-zero if registering @p provider otherwise fails, a regular + * unix error code will be returned. + */ +int +bhnd_service_registry_add(struct bhnd_service_registry *bsr, device_t provider, + bhnd_service_t service, uint32_t flags) +{ + struct bhnd_service_entry *entry; + + if (service == BHND_SERVICE_ANY) + return (EINVAL); + + mtx_lock(&bsr->lock); + + /* Is a service provider already registered? */ + STAILQ_FOREACH(entry, &bsr->entries, link) { + if (entry->service == service) { + mtx_unlock(&bsr->lock); + return (EEXIST); + } + } + + /* Initialize and insert our new entry */ + entry = malloc(sizeof(*entry), M_BHND, M_NOWAIT); + if (entry == NULL) { + mtx_unlock(&bsr->lock); + return (ENOMEM); + } + + entry->provider = provider; + entry->service = service; + entry->flags = flags; + refcount_init(&entry->refs, 0); + + STAILQ_INSERT_HEAD(&bsr->entries, entry, link); + + mtx_unlock(&bsr->lock); + return (0); +} + +/** + * Free an unreferenced registry entry. + * + * @param entry The entry to be deallocated. + */ +static void +bhnd_service_registry_free_entry(struct bhnd_service_entry *entry) +{ + KASSERT(entry->refs == 0, ("provider has active references")); + free(entry, M_BHND); +} + +/** + * Attempt to remove the @p service provider registration for @p provider. + * + * @param bsr The service registry to be modified. + * @param provider The service provider to be deregistered. + * @param service The service for which @p provider will be deregistered, + * or BHND_SERVICE_ANY to remove all service + * registrations for @p provider. + * + * @retval 0 success + * @retval EBUSY if active references to @p provider exist; @see + * bhnd_service_registry_retain() and + * bhnd_service_registry_release(). + */ +int +bhnd_service_registry_remove(struct bhnd_service_registry *bsr, + device_t provider, bhnd_service_t service) +{ + struct bhnd_service_entry *entry, *enext; + + mtx_lock(&bsr->lock); + +#define BHND_PROV_MATCH(_e) \ + ((_e)->provider == provider && \ + (service == BHND_SERVICE_ANY || (_e)->service == service)) + + /* Validate matching provider entries before making any + * modifications */ + STAILQ_FOREACH(entry, &bsr->entries, link) { + /* Skip non-matching entries */ + if (!BHND_PROV_MATCH(entry)) + continue; + + /* Entry is in use? */ + if (entry->refs > 0) { + mtx_unlock(&bsr->lock); + return (EBUSY); + } + } + + /* We can now safely remove matching entries */ + STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { + /* Skip non-matching entries */ + if (!BHND_PROV_MATCH(entry)) + continue; + + /* Remove from list */ + STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); + + /* Free provider entry */ + bhnd_service_registry_free_entry(entry); + } +#undef BHND_PROV_MATCH + + mtx_unlock(&bsr->lock); + return (0); +} + +/** + * Retain and return a reference to a registered @p service provider, if any. + * + * @param bsr The service registry to be queried. + * @param service The service for which a provider should be returned. + * + * On success, the caller assumes ownership the returned provider, and + * is responsible for releasing this reference via + * bhnd_service_registry_release(). + * + * @retval device_t success + * @retval NULL if no provider is registered for @p service. + */ +device_t +bhnd_service_registry_retain(struct bhnd_service_registry *bsr, + bhnd_service_t service) +{ + struct bhnd_service_entry *entry; + + mtx_lock(&bsr->lock); + STAILQ_FOREACH(entry, &bsr->entries, link) { + if (entry->service != service) + continue; + + /* With a live refcount, entry is gauranteed to remain alive + * after we release our lock */ + refcount_acquire(&entry->refs); + + mtx_unlock(&bsr->lock); + return (entry->provider); + } + mtx_unlock(&bsr->lock); + + /* Not found */ + return (NULL); +} + +/** + * Release a reference to a service provider previously returned by + * bhnd_service_registry_retain(). + * + * If this is the last reference to an inherited service provider registration + * (@see BHND_SPF_INHERITED), the registration will also be removed, and + * true will be returned. + * + * @param bsr The service registry from which @p provider + * was returned. + * @param provider The provider to be released. + * @param service The service for which @p provider was previously + * retained. + * @retval true The inherited service provider registration was removed; + * the caller should release its own reference to the + * provider. + * @retval false The service provider was not inherited, or active + * references to the provider remain. + */ +bool +bhnd_service_registry_release(struct bhnd_service_registry *bsr, + device_t provider, bhnd_service_t service) +{ + struct bhnd_service_entry *entry; + + /* Exclusive lock, as we need to prevent any new references to the + * entry from being taken if it's to be removed */ + mtx_lock(&bsr->lock); + STAILQ_FOREACH(entry, &bsr->entries, link) { + bool removed; + + if (entry->provider != provider) + continue; + + if (entry->service != service) + continue; + + if (refcount_release(&entry->refs) && + (entry->flags & BHND_SPF_INHERITED)) + { + /* If an inherited entry is no longer actively + * referenced, remove the local registration and inform + * the caller. */ + STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, + link); + bhnd_service_registry_free_entry(entry); + removed = true; + } else { + removed = false; + } + + mtx_unlock(&bsr->lock); + return (removed); + } + + /* Caller owns a reference, but no such provider is registered? */ + panic("invalid service provider reference"); +} + /** * Using the bhnd(4) bus-level core information and a custom core name, * populate @p dev's device description. @@ -1427,6 +1851,222 @@ bhnd_set_default_bus_desc(device_t dev, const struct bhnd_chipid *chip_id) } +/** + * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). + * + * This implementation delegates the request to the BHND_BUS_REGISTER_PROVIDER() + * method on the parent of @p dev. If no parent exists, the implementation + * will return an error. + */ +int +bhnd_bus_generic_register_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + device_t parent = device_get_parent(dev); + + if (parent != NULL) { + return (BHND_BUS_REGISTER_PROVIDER(parent, child, + provider, service)); + } + + return (ENXIO); +} + +/** + * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). + * + * This implementation delegates the request to the + * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent + * exists, the implementation will panic. + */ +int +bhnd_bus_generic_deregister_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + device_t parent = device_get_parent(dev); + + if (parent != NULL) { + return (BHND_BUS_DEREGISTER_PROVIDER(parent, child, + provider, service)); + } + + panic("missing BHND_BUS_DEREGISTER_PROVIDER()"); +} + +/** + * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). + * + * This implementation delegates the request to the + * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent + * exists, the implementation will return NULL. + */ +device_t +bhnd_bus_generic_retain_provider(device_t dev, device_t child, + bhnd_service_t service) +{ + device_t parent = device_get_parent(dev); + + if (parent != NULL) { + return (BHND_BUS_RETAIN_PROVIDER(parent, child, + service)); + } + + return (NULL); +} + +/** + * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). + * + * This implementation delegates the request to the + * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent + * exists, the implementation will panic. + */ +void +bhnd_bus_generic_release_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + device_t parent = device_get_parent(dev); + + if (parent != NULL) { + return (BHND_BUS_RELEASE_PROVIDER(parent, child, + provider, service)); + } + + panic("missing BHND_BUS_RELEASE_PROVIDER()"); +} + +/** + * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). + * + * This implementation uses the bhnd_service_registry_add() function to + * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find + * a suitable service registry to edit. + */ +int +bhnd_bus_generic_sr_register_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + struct bhnd_service_registry *bsr; + + bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); + + KASSERT(bsr != NULL, ("NULL service registry")); + + return (bhnd_service_registry_add(bsr, provider, service, 0)); +} + +/** + * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). + * + * This implementation uses the bhnd_service_registry_remove() function to + * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find + * a suitable service registry to edit. + */ +int +bhnd_bus_generic_sr_deregister_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + struct bhnd_service_registry *bsr; + + bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); + + KASSERT(bsr != NULL, ("NULL service registry")); + + return (bhnd_service_registry_remove(bsr, provider, service)); +} + +/** + * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). + * + * This implementation uses the bhnd_service_registry_retain() function to + * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find + * a suitable service registry. + * + * If a local provider for the service is not available, and a parent device is + * available, this implementation will attempt to fetch and locally register + * a service provider reference from the parent of @p dev. + */ +device_t +bhnd_bus_generic_sr_retain_provider(device_t dev, device_t child, + bhnd_service_t service) +{ + struct bhnd_service_registry *bsr; + device_t parent, provider; + int error; + + bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); + KASSERT(bsr != NULL, ("NULL service registry")); + + /* + * Attempt to fetch a service provider reference from either the local + * service registry, or if not found, from our parent. + * + * If we fetch a provider from our parent, we register the provider + * with the local service registry to prevent conflicting local + * registrations from being added. + */ + while (1) { + /* Check the local service registry first */ + provider = bhnd_service_registry_retain(bsr, service); + if (provider != NULL) + return (provider); + + /* Otherwise, try to delegate to our parent (if any) */ + if ((parent = device_get_parent(dev)) == NULL) + return (NULL); + + provider = BHND_BUS_RETAIN_PROVIDER(parent, dev, service); + if (provider == NULL) + return (NULL); + + /* Register the inherited service registration with the local + * registry */ + error = bhnd_service_registry_add(bsr, provider, service, + BHND_SPF_INHERITED); + if (error) { + BHND_BUS_RELEASE_PROVIDER(parent, dev, provider, + service); + if (error == EEXIST) { + /* A valid service provider was registered + * concurrently; retry fetching from the local + * registry */ + continue; + } + + device_printf(dev, "failed to register service " + "provider: %d\n", error); + return (NULL); + } + } +} + +/** + * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). + * + * This implementation uses the bhnd_service_registry_release() function to + * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find + * a suitable service registry. + */ +void +bhnd_bus_generic_sr_release_provider(device_t dev, device_t child, + device_t provider, bhnd_service_t service) +{ + struct bhnd_service_registry *bsr; + + bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); + KASSERT(bsr != NULL, ("NULL service registry")); + + /* Release the provider reference; if the refcount hits zero on an + * inherited reference, true will be returned, and we need to drop + * our own bus reference to the provider */ + if (!bhnd_service_registry_release(bsr, provider, service)) + return; + + /* Drop our reference to the borrowed provider */ + BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev, provider, + service); +} + /** * Helper function for implementing BHND_BUS_IS_HW_DISABLED(). * diff --git a/sys/dev/bhnd/bhnd_types.h b/sys/dev/bhnd/bhnd_types.h index ffdbf1a47489..d819afedbecb 100644 --- a/sys/dev/bhnd/bhnd_types.h +++ b/sys/dev/bhnd/bhnd_types.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -65,6 +69,14 @@ typedef enum { BHND_DEVCLASS_INVALID /**< no/invalid class */ } bhnd_devclass_t; +/** bhnd(4) platform services. */ +typedef enum { + BHND_SERVICE_CHIPC, /**< chipcommon service; implements the bhnd_chipc interface */ + BHND_SERVICE_PMU, /**< pmu service; implements the bhnd_pmu interface */ + BHND_SERVICE_NVRAM, /**< nvram service; implements the bhnd_nvram interface */ + + BHND_SERVICE_ANY = 1000, /**< match on any service type */ +} bhnd_service_t; /** * bhnd(4) port types. diff --git a/sys/dev/bhnd/bhndb/bhnd_bhndb.c b/sys/dev/bhnd/bhndb/bhnd_bhndb.c index 12efb04c33a4..fdd45ef39819 100644 --- a/sys/dev/bhnd/bhndb/bhnd_bhndb.c +++ b/sys/dev/bhnd/bhndb/bhnd_bhndb.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -90,7 +94,7 @@ bhnd_bhndb_find_hostb_device(device_t dev) /* Find the corresponding bus device */ md = bhnd_core_get_match_desc(&core); - return (bhnd_match_child(dev, &md)); + return (bhnd_bus_match_child(dev, &md)); } static int diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c index c5b08276caf1..92de9f174bed 100644 --- a/sys/dev/bhnd/bhndb/bhndb.c +++ b/sys/dev/bhnd/bhndb/bhndb.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -73,18 +77,6 @@ enum { #define BHNDB_DEBUG(_type) (BHNDB_DEBUG_ ## _type & bhndb_debug) -static int bhndb_find_hostb_core(struct bhndb_softc *sc, - bhnd_erom_t *erom, - struct bhnd_core_info *core); - -static bhnd_erom_class_t *bhndb_probe_erom_class(struct bhndb_softc *sc, - struct bhnd_chipid *cid); - -static int bhndb_init_full_config(struct bhndb_softc *sc, - bhnd_erom_class_t *eromcls); - -static struct bhnd_core_info *bhndb_get_bridge_core(struct bhndb_softc *sc); - static bool bhndb_hw_matches(struct bhndb_softc *sc, struct bhnd_core_info *cores, u_int ncores, const struct bhndb_hw *hw); @@ -196,21 +188,6 @@ bhndb_child_location_str(device_t dev, device_t child, char *buf, return (0); } -/** - * Return the bridge core info. Will panic if the bridge core info has not yet - * been populated during full bridge configuration. - * - * @param sc BHNDB device state. - */ -static struct bhnd_core_info * -bhndb_get_bridge_core(struct bhndb_softc *sc) -{ - if (!sc->have_br_core) - panic("bridge not yet fully configured; no bridge core!"); - - return (&sc->bridge_core); -} - /** * Return true if @p cores matches the @p hw specification. * @@ -503,49 +480,66 @@ bhndb_find_hwspec(struct bhndb_softc *sc, struct bhnd_core_info *cores, * priority bands to add additional devices that will be attached in * their preferred order relative to the bridged bhnd(4) bus. * - * @param dev The bridge device to attach. - * @param bridge_devclass The device class of the bridging core. This is used - * to automatically detect the bridge core, and to disable additional bridge - * cores (e.g. PCMCIA on a PCIe device). + * @param dev The bridge device to attach. + * @param cid The bridged device's chip identification. + * @param cores The bridged device's core table. + * @param ncores The number of cores in @p cores. + * @param bridge_core Core info for the bhnd(4) core serving as the host + * bridge. + * @param erom_class An erom parser class that may be used to parse + * the bridged device's device enumeration table. */ int -bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass) +bhndb_attach(device_t dev, struct bhnd_chipid *cid, + struct bhnd_core_info *cores, u_int ncores, + struct bhnd_core_info *bridge_core, bhnd_erom_class_t *erom_class) { struct bhndb_devinfo *dinfo; struct bhndb_softc *sc; - const struct bhndb_hwcfg *cfg; - bhnd_erom_class_t *eromcls; + const struct bhndb_hw *hw; + const struct bhndb_hwcfg *hwcfg; + const struct bhndb_hw_priority *hwprio; + struct bhnd_erom_io *eio; + bhnd_erom_t *erom; int error; sc = device_get_softc(dev); sc->dev = dev; sc->parent_dev = device_get_parent(dev); - sc->bridge_class = bridge_devclass; + sc->bridge_core = *bridge_core; + sc->chipid = *cid; + + if ((error = bhnd_service_registry_init(&sc->services))) + return (error); BHNDB_LOCK_INIT(sc); - - /* Populate generic resource allocation state. */ - cfg = BHNDB_BUS_GET_GENERIC_HWCFG(sc->parent_dev, sc->dev); - sc->bus_res = bhndb_alloc_resources(dev, sc->parent_dev, cfg); + + erom = NULL; + + /* Find a matching bridge hardware configuration */ + if ((error = bhndb_find_hwspec(sc, cores, ncores, &hw))) { + device_printf(sc->dev, "unable to identify device, " + " using generic bridge resource definitions\n"); + + hwcfg = BHNDB_BUS_GET_GENERIC_HWCFG(sc->parent_dev, dev); + hw = NULL; + } else { + hwcfg = hw->cfg; + } + + if (hw != NULL && (bootverbose || BHNDB_DEBUG(PRIO))) { + device_printf(sc->dev, "%s resource configuration\n", hw->name); + } + + /* Allocate bridge resource state using the discovered hardware + * configuration */ + sc->bus_res = bhndb_alloc_resources(sc->dev, sc->parent_dev, hwcfg); if (sc->bus_res == NULL) { - return (ENXIO); - } - - /* Allocate our host resources */ - if ((error = bhndb_alloc_host_resources(sc->bus_res))) + device_printf(sc->dev, "failed to allocate bridge resource " + "state\n"); + error = ENOMEM; goto failed; - - /* Probe for a usable EROM class for our bridged bhnd(4) bus and - * populate our chip identifier. */ - BHNDB_LOCK(sc); - if ((eromcls = bhndb_probe_erom_class(sc, &sc->chipid)) == NULL) { - BHNDB_UNLOCK(sc); - - device_printf(sc->dev, "device enumeration unsupported; no " - "compatible driver found\n"); - return (ENXIO); } - BHNDB_UNLOCK(sc); /* Add our bridged bus device */ sc->bus_dev = BUS_ADD_CHILD(dev, BHND_PROBE_BUS, "bhnd", -1); @@ -557,14 +551,29 @@ bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass) dinfo = device_get_ivars(sc->bus_dev); dinfo->addrspace = BHNDB_ADDRSPACE_BRIDGED; - /* Enumerate the bridged device and fully initialize our bridged - * resource configuration */ - if ((error = bhndb_init_full_config(sc, eromcls))) { - device_printf(sc->dev, "initializing full bridge " - "configuration failed: %d\n", error); + /* We can now use bhndb to perform bridging of SYS_RES_MEMORY resources; + * we use this to instantiate an erom parser instance */ + eio = bhnd_erom_iores_new(sc->bus_dev, 0); + if ((erom = bhnd_erom_alloc(erom_class, cid, eio)) == NULL) { + bhnd_erom_io_fini(eio); + error = ENXIO; goto failed; } + /* Populate our resource priority configuration */ + hwprio = BHNDB_BUS_GET_HARDWARE_PRIO(sc->parent_dev, sc->dev); + error = bhndb_init_region_cfg(sc, erom, sc->bus_res, cores, ncores, + hwprio); + if (error) { + device_printf(sc->dev, "failed to initialize resource " + "priority configuration: %d\n", error); + goto failed; + } + + /* Free our erom instance */ + bhnd_erom_free(erom); + erom = NULL; + return (0); failed: @@ -573,327 +582,10 @@ bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass) if (sc->bus_res != NULL) bhndb_free_resources(sc->bus_res); - return (error); -} - - -/** - * Return a borrowed reference to the host resource mapping at least - * BHND_DEFAULT_CORE_SIZE bytes at the first bus core, for use with - * bhnd_erom_probe(). - * - * This may return a borrowed reference to a bhndb_dw_alloc-managed - * resource; any additional resource mapping requests may invalidate this - * borrowed reference. - * - * @param sc BHNDB driver state. - * @param[out] offset On success, the offset within the returned resource - * at which the first bus core can be found. - * - * @retval non-NULL success. - * @retval NULL If no usable mapping could be found. - */ -static struct resource * -bhndb_erom_chipc_resource(struct bhndb_softc *sc, bus_size_t *offset) -{ - const struct bhndb_hwcfg *cfg; - struct bhndb_dw_alloc *dwa; - struct resource *res; - const struct bhndb_regwin *win; - - BHNDB_LOCK_ASSERT(sc, MA_OWNED); - - cfg = sc->bus_res->cfg; - - /* Find a static register window mapping ChipCommon. */ - win = bhndb_regwin_find_core(cfg->register_windows, BHND_DEVCLASS_CC, - 0, BHND_PORT_DEVICE, 0, 0); - if (win != NULL) { - if (win->win_size < BHND_DEFAULT_CORE_SIZE) { - device_printf(sc->dev, - "chipcommon register window too small\n"); - return (NULL); - } - - res = bhndb_find_regwin_resource(sc->bus_res, win); - if (res == NULL) { - device_printf(sc->dev, - "chipcommon register window not allocated\n"); - return (NULL); - } - - *offset = win->win_offset; - return (res); - } - - /* We'll need to fetch and configure a dynamic window. We can assume a - * device without a static ChipCommon mapping uses the default siba(4) - * base address. */ - dwa = bhndb_io_resource(sc, BHND_DEFAULT_CHIPC_ADDR, - BHND_DEFAULT_CORE_SIZE, offset); - if (dwa != NULL) - return (dwa->parent_res); - - device_printf(sc->dev, "unable to map chipcommon registers; no usable " - "register window found\n"); - return (NULL); -} - -/** - * Probe all supported EROM classes, returning the best matching class - * (or NULL if not found), writing the probed chip identifier to @p cid. - * - * @param sc BHNDB driver state. - * @param cid On success, the bridged chipset's chip identifier. - */ -static bhnd_erom_class_t * -bhndb_probe_erom_class(struct bhndb_softc *sc, struct bhnd_chipid *cid) -{ - devclass_t bhndb_devclass; - const struct bhnd_chipid *hint; - struct resource *res; - bus_size_t res_offset; - driver_t **drivers; - int drv_count; - bhnd_erom_class_t *erom_cls; - int prio, result; - - BHNDB_LOCK_ASSERT(sc, MA_OWNED); - - erom_cls = NULL; - prio = 0; - - /* Let our parent device provide a chipid hint */ - hint = BHNDB_BUS_GET_CHIPID(sc->parent_dev, sc->dev); - - /* Fetch a borrowed reference to the resource mapping ChipCommon. */ - res = bhndb_erom_chipc_resource(sc, &res_offset); - if (res == NULL) - return (NULL); - - /* Fetch all available drivers */ - bhndb_devclass = device_get_devclass(sc->dev); - if (devclass_get_drivers(bhndb_devclass, &drivers, &drv_count) != 0) - return (NULL); - - /* Enumerate the drivers looking for the best available EROM class */ - for (int i = 0; i < drv_count; i++) { - struct bhnd_chipid pcid; - bhnd_erom_class_t *cls; - - cls = bhnd_driver_get_erom_class(drivers[i]); - if (cls == NULL) - continue; - - kobj_class_compile(cls); - - /* Probe the bus */ - result = bhnd_erom_probe(cls, &BHND_DIRECT_RESOURCE(res), - res_offset, hint, &pcid); - - /* The parser did not match if an error was returned */ - if (result > 0) - continue; - - /* Check for a new highest priority match */ - if (erom_cls == NULL || result > prio) { - prio = result; - - *cid = pcid; - erom_cls = cls; - } - - /* Terminate immediately on BUS_PROBE_SPECIFIC */ - if (result == BUS_PROBE_SPECIFIC) - break; - } - - return (erom_cls); -} - -/* ascending core index comparison used by bhndb_find_hostb_core() */ -static int -compare_core_index(const void *lhs, const void *rhs) -{ - u_int left = ((const struct bhnd_core_info *)lhs)->core_idx; - u_int right = ((const struct bhnd_core_info *)rhs)->core_idx; - - if (left < right) - return (-1); - else if (left > right) - return (1); - else - return (0); -} - -/** - * Search @p erom for the core serving as the bhnd host bridge. - * - * This function uses a heuristic valid on all known PCI/PCIe/PCMCIA-bridged - * bhnd(4) devices to determine the hostb core: - * - * - The core must have a Broadcom vendor ID. - * - The core devclass must match the bridge type. - * - The core must be the first device on the bus with the bridged device - * class. - * - * @param sc BHNDB device state. - * @param erom The device enumeration table parser to be used to fetch - * core info. - * @param[out] core If found, the matching core info. - * - * @retval 0 success - * @retval ENOENT not found - * @retval non-zero if an error occured fetching core info. - */ -static int -bhndb_find_hostb_core(struct bhndb_softc *sc, bhnd_erom_t *erom, - struct bhnd_core_info *core) -{ - struct bhnd_core_match md; - struct bhnd_core_info *cores; - u_int ncores; - int error; - - if ((error = bhnd_erom_get_core_table(erom, &cores, &ncores))) - return (error); - - /* Set up a match descriptor for the required device class. */ - md = (struct bhnd_core_match) { - BHND_MATCH_CORE_CLASS(sc->bridge_class), - BHND_MATCH_CORE_UNIT(0) - }; - - /* Ensure the table is sorted by core index value, ascending; - * the host bridge must be the absolute first matching device on the - * bus. */ - qsort(cores, ncores, sizeof(*cores), compare_core_index); - - /* Find the hostb core */ - error = ENOENT; - for (u_int i = 0; i < ncores; i++) { - if (bhnd_core_matches(&cores[i], &md)) { - /* Found! */ - *core = cores[i]; - error = 0; - break; - } - } - - /* Clean up */ - bhnd_erom_free_core_table(erom, cores); - - return (error); -} - -/** - * Identify the bridged device and perform final bridge resource configuration - * based on capabilities of the enumerated device. - * - * Any bridged resources allocated using the generic brige hardware - * configuration must be released prior to calling this function. - */ -static int -bhndb_init_full_config(struct bhndb_softc *sc, bhnd_erom_class_t *eromcls) -{ - struct bhnd_core_info *cores; - struct bhndb_resources *br; - const struct bhndb_hw_priority *hwprio; - bhnd_erom_t *erom; - const struct bhndb_hw *hw; - u_int ncores; - int error; - - erom = NULL; - cores = NULL; - br = NULL; - - /* Allocate EROM parser instance */ - erom = bhnd_erom_alloc(eromcls, &sc->chipid, sc->bus_dev, 0); - if (erom == NULL) { - device_printf(sc->dev, "failed to allocate device enumeration " - "table parser\n"); - return (ENXIO); - } - - /* Look for our host bridge core */ - if ((error = bhndb_find_hostb_core(sc, erom, &sc->bridge_core))) { - device_printf(sc->dev, "no host bridge core found\n"); - goto cleanup; - } else { - sc->have_br_core = true; - } - - /* Fetch the bridged device's core table */ - if ((error = bhnd_erom_get_core_table(erom, &cores, &ncores))) { - device_printf(sc->dev, "error fetching core table: %d\n", - error); - goto cleanup; - } - - /* Find our full register window configuration */ - if ((error = bhndb_find_hwspec(sc, cores, ncores, &hw))) { - device_printf(sc->dev, "unable to identify device, " - " using generic bridge resource definitions\n"); - error = 0; - goto cleanup; - } - - if (bootverbose || BHNDB_DEBUG(PRIO)) - device_printf(sc->dev, "%s resource configuration\n", hw->name); - - /* Allocate new bridge resource state using the discovered hardware - * configuration */ - br = bhndb_alloc_resources(sc->dev, sc->parent_dev, hw->cfg); - if (br == NULL) { - device_printf(sc->dev, - "failed to allocate new resource state\n"); - error = ENOMEM; - goto cleanup; - } - - /* Populate our resource priority configuration */ - hwprio = BHNDB_BUS_GET_HARDWARE_PRIO(sc->parent_dev, sc->dev); - error = bhndb_init_region_cfg(sc, erom, br, cores, ncores, hwprio); - if (error) { - device_printf(sc->dev, "failed to initialize resource " - "priority configuration: %d\n", error); - goto cleanup; - } - - /* The EROM parser holds a reference to the resource state we're - * about to invalidate */ - bhnd_erom_free_core_table(erom, cores); - bhnd_erom_free(erom); - - cores = NULL; - erom = NULL; - - /* Replace existing resource state */ - bhndb_free_resources(sc->bus_res); - sc->bus_res = br; - - /* Pointer is now owned by sc->bus_res */ - br = NULL; - - /* Re-allocate host resources */ - if ((error = bhndb_alloc_host_resources(sc->bus_res))) { - device_printf(sc->dev, "failed to reallocate bridge host " - "resources: %d\n", error); - goto cleanup; - } - - return (0); - -cleanup: - if (cores != NULL) - bhnd_erom_free_core_table(erom, cores); - if (erom != NULL) bhnd_erom_free(erom); - if (br != NULL) - bhndb_free_resources(br); + bhnd_service_registry_fini(&sc->services); return (error); } @@ -911,11 +603,15 @@ bhndb_generic_detach(device_t dev) int error; sc = device_get_softc(dev); - + /* Detach children */ if ((error = bus_generic_detach(dev))) return (error); + /* Clean up our service registry */ + if ((error = bhnd_service_registry_fini(&sc->services))) + return (error); + /* Clean up our driver state. */ bhndb_free_resources(sc->bus_res); @@ -1178,7 +874,6 @@ bhndb_is_core_disabled(device_t dev, device_t child, struct bhnd_core_info *core) { struct bhndb_softc *sc; - struct bhnd_core_info *bridge_core; sc = device_get_softc(dev); @@ -1188,9 +883,8 @@ bhndb_is_core_disabled(device_t dev, device_t child, /* Otherwise, we treat bridge-capable cores as unpopulated if they're * not the configured host bridge */ - bridge_core = bhndb_get_bridge_core(sc); if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(core))) - return (!bhnd_cores_equal(core, bridge_core)); + return (!bhnd_cores_equal(core, &sc->bridge_core)); /* Assume the core is populated */ return (false); @@ -1207,10 +901,21 @@ bhndb_get_hostb_core(device_t dev, device_t child, struct bhnd_core_info *core) { struct bhndb_softc *sc = device_get_softc(dev); - *core = *bhndb_get_bridge_core(sc); + *core = sc->bridge_core; return (0); } +/** + * Default bhndb(4) implementation of BHND_BUS_GET_SERVICE_REGISTRY(). + */ +static struct bhnd_service_registry * +bhndb_get_service_registry(device_t dev, device_t child) +{ + struct bhndb_softc *sc = device_get_softc(dev); + + return (&sc->services); +} + /** * Default bhndb(4) implementation of BUS_ALLOC_RESOURCE(). */ @@ -1475,7 +1180,7 @@ bhndb_activate_static_region(struct bhndb_softc *sc, r_size = rman_get_size(r); /* Find the corresponding bridge resource */ - bridge_res = bhndb_find_regwin_resource(sc->bus_res, win); + bridge_res = bhndb_host_resource_for_regwin(sc->bus_res->res, win); if (bridge_res == NULL) return (ENXIO); @@ -1595,8 +1300,8 @@ bhndb_try_activate_resource(struct bhndb_softc *sc, device_t child, int type, struct resource *parent; /* Find the bridge resource referenced by the child */ - parent = bhndb_find_resource_range(sc->bus_res, r_start, - r_size); + parent = bhndb_host_resource_for_range(sc->bus_res->res, + type, r_start, r_size); if (parent == NULL) { device_printf(sc->dev, "host resource not found " "for 0x%llx-0x%llx\n", @@ -2146,6 +1851,13 @@ static device_method_t bhndb_methods[] = { DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource), DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource), DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var), + + DEVMETHOD(bhnd_bus_get_service_registry,bhndb_get_service_registry), + DEVMETHOD(bhnd_bus_register_provider, bhnd_bus_generic_sr_register_provider), + DEVMETHOD(bhnd_bus_deregister_provider, bhnd_bus_generic_sr_deregister_provider), + DEVMETHOD(bhnd_bus_retain_provider, bhnd_bus_generic_sr_retain_provider), + DEVMETHOD(bhnd_bus_release_provider, bhnd_bus_generic_sr_release_provider), + DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1), DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2), DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4), diff --git a/sys/dev/bhnd/bhndb/bhndb_pci.c b/sys/dev/bhnd/bhndb/bhndb_pci.c index 60da43b914e2..3fe38628e3c4 100644 --- a/sys/dev/bhnd/bhndb/bhndb_pci.c +++ b/sys/dev/bhnd/bhndb/bhndb_pci.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -55,6 +59,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#include +#include #include @@ -62,15 +70,24 @@ __FBSDID("$FreeBSD$"); #include "bhndb_pcivar.h" #include "bhndb_private.h" +struct bhndb_pci_eio; + static int bhndb_pci_init_msi(struct bhndb_pci_softc *sc); +static int bhndb_pci_read_core_table(device_t dev, + struct bhnd_chipid *chipid, + struct bhnd_core_info **cores, u_int *ncores, + bhnd_erom_class_t **eromcls); static int bhndb_pci_add_children(struct bhndb_pci_softc *sc); -static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc); -static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc); +static bool bhndb_is_pcie_attached(device_t dev); -static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *, - const struct bhndb_regwin *, bhnd_addr_t); -static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *, +static int bhndb_enable_pci_clocks(device_t dev); +static int bhndb_disable_pci_clocks(device_t dev); + +static int bhndb_pci_compat_setregwin(device_t dev, + device_t pci_dev, const struct bhndb_regwin *, + bhnd_addr_t); +static int bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev, const struct bhndb_regwin *, bhnd_addr_t); static void bhndb_init_sromless_pci_config( @@ -79,8 +96,30 @@ static void bhndb_init_sromless_pci_config( static bus_addr_t bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc); static bus_size_t bhndb_pci_sprom_size(struct bhndb_pci_softc *sc); +static int bhndb_pci_eio_init(struct bhndb_pci_eio *pio, + device_t dev, device_t pci_dev, + struct bhndb_host_resources *hr); +static int bhndb_pci_eio_map(struct bhnd_erom_io *eio, + bhnd_addr_t addr, bhnd_size_t size); +static uint32_t bhndb_pci_eio_read(struct bhnd_erom_io *eio, + bhnd_size_t offset, u_int width); + #define BHNDB_PCI_MSI_COUNT 1 +/* bhndb_pci erom I/O implementation */ +struct bhndb_pci_eio { + struct bhnd_erom_io eio; + device_t dev; /**< bridge device */ + device_t pci_dev; /**< parent PCI device */ + struct bhndb_host_resources *hr; /**< borrowed reference to host resources */ + const struct bhndb_regwin *win; /**< mapped register window, or NULL */ + struct resource *res; /**< resource containing the register window, or NULL if no window mapped */ + bhnd_addr_t res_target; /**< current target address (if mapped) */ + bool mapped; /**< true if a valid mapping exists, false otherwise */ + bhnd_addr_t addr; /**< mapped address */ + bhnd_size_t size; /**< mapped size */ +}; + /** * Default bhndb_pci implementation of device_probe(). * @@ -137,17 +176,23 @@ static int bhndb_pci_attach(device_t dev) { struct bhndb_pci_softc *sc; + struct bhnd_chipid cid; + struct bhnd_core_info *cores, hostb_core; + bhnd_erom_class_t *erom_class; + u_int ncores; int error, reg; sc = device_get_softc(dev); sc->dev = dev; sc->parent = device_get_parent(dev); - sc->set_regwin = bhndb_pci_compat_setregwin; + sc->set_regwin = NULL; + + cores = NULL; /* Enable PCI bus mastering */ pci_enable_busmaster(sc->parent); - /* Set up interrupt handling */ + /* Set up PCI interrupt handling */ if (bhndb_pci_init_msi(sc) == 0) { device_printf(dev, "Using MSI interrupts on %s\n", device_get_nameunit(sc->parent)); @@ -165,22 +210,32 @@ bhndb_pci_attach(device_t dev) sc->pci_devclass = BHND_DEVCLASS_PCI; /* Enable clocks (if required by this hardware) */ - if ((error = bhndb_enable_pci_clocks(sc))) + if ((error = bhndb_enable_pci_clocks(sc->dev))) goto cleanup; - /* Perform bridge attach, fully initializing the bridge - * configuration. */ - if ((error = bhndb_attach(dev, sc->pci_devclass))) + /* Identify the chip and enumerate the bridged cores */ + error = bhndb_pci_read_core_table(dev, &cid, &cores, &ncores, + &erom_class); + if (error) goto cleanup; - /* If supported, switch to faster regwin handling */ - if (sc->bhndb.chipid.chip_type != BHND_CHIPTYPE_SIBA) { - atomic_store_rel_ptr((volatile void *) &sc->set_regwin, - (uintptr_t) &bhndb_pci_fast_setregwin); + /* Select the appropriate register window handler */ + if (cid.chip_type == BHND_CHIPTYPE_SIBA) { + sc->set_regwin = bhndb_pci_compat_setregwin; + } else { + sc->set_regwin = bhndb_pci_fast_setregwin; } - /* Enable PCI bus mastering */ - pci_enable_busmaster(sc->parent); + /* Determine our host bridge core */ + error = bhndb_find_hostb_core(cores, ncores, sc->pci_devclass, + &hostb_core); + if (error) + goto cleanup; + + /* Perform bridge attach */ + error = bhndb_attach(dev, &cid, cores, ncores, &hostb_core, erom_class); + if (error) + goto cleanup; /* Fix-up power on defaults for SROM-less devices. */ bhndb_init_sromless_pci_config(sc); @@ -193,14 +248,20 @@ bhndb_pci_attach(device_t dev) if ((error = bus_generic_attach(dev))) goto cleanup; + free(cores, M_BHND); + return (0); cleanup: device_delete_children(dev); - bhndb_disable_pci_clocks(sc); + bhndb_disable_pci_clocks(sc->dev); + if (sc->intr.msi_count > 0) pci_release_msi(dev); + if (cores != NULL) + free(cores, M_BHND); + pci_disable_busmaster(sc->parent); return (error); @@ -223,7 +284,7 @@ bhndb_pci_detach(device_t dev) return (error); /* Disable clocks (if required by this hardware) */ - if ((error = bhndb_disable_pci_clocks(sc))) + if ((error = bhndb_disable_pci_clocks(sc->dev))) return (error); /* Release MSI interrupts */ @@ -236,6 +297,124 @@ bhndb_pci_detach(device_t dev) return (0); } +/** + * Use the generic PCI bridge hardware configuration to enumerate the bridged + * bhnd(4) bus' core table. + * + * @note This function may be safely called prior to device attach, (e.g. + * from DEVICE_PROBE). + * @note This function requires exclusive ownership over allocating and + * configuring host bridge resources, and should only be called prior to + * completion of device attach and full configuration of the bridge. + * + * @param dev The bhndb_pci bridge device. + * @param[out] chipid On success, the parsed chip identification. + * @param[out] cores On success, the enumerated core table. The + * caller is responsible for freeing this table via + * bhndb_pci_free_core_table(). + * @param[out] ncores On success, the number of cores found in + * @p cores. + * @param[out] eromcls On success, a pointer to the erom class used to + * parse the device enumeration table. This + * argument may be NULL if the class is not + * desired. + * + * @retval 0 success + * @retval non-zero if enumerating the bridged bhnd(4) bus fails, a regular + * unix error code will be returned. + */ +static int +bhndb_pci_read_core_table(device_t dev, struct bhnd_chipid *chipid, + struct bhnd_core_info **cores, u_int *ncores, + bhnd_erom_class_t **eromcls) +{ + const struct bhndb_hwcfg *cfg; + struct bhndb_host_resources *hr; + struct bhndb_pci_eio pio; + struct bhnd_core_info *erom_cores; + const struct bhnd_chipid *hint; + struct bhnd_chipid cid; + bhnd_erom_class_t *erom_class; + bhnd_erom_t *erom; + device_t parent_dev; + u_int erom_ncores; + int error; + + parent_dev = device_get_parent(dev); + erom = NULL; + erom_cores = NULL; + + /* Fetch our chipid hint (if any) and generic hardware configuration */ + cfg = BHNDB_BUS_GET_GENERIC_HWCFG(parent_dev, dev); + hint = BHNDB_BUS_GET_CHIPID(parent_dev, dev); + + /* Allocate our host resources */ + if ((error = bhndb_alloc_host_resources(parent_dev, cfg, &hr))) + return (error); + + /* Initialize our erom I/O state */ + if ((error = bhndb_pci_eio_init(&pio, dev, parent_dev, hr))) + goto failed; + + /* Map the first bus core from our bridged bhnd(4) bus */ + error = bhndb_pci_eio_map(&pio.eio, BHND_DEFAULT_CHIPC_ADDR, + BHND_DEFAULT_CORE_SIZE); + if (error) + goto failed; + + /* Probe for a usable EROM class, and read the chip identifier */ + erom_class = bhnd_erom_probe_driver_classes(device_get_devclass(dev), + &pio.eio, hint, &cid); + if (erom_class == NULL) { + device_printf(dev, "device enumeration unsupported; no " + "compatible driver found\n"); + + error = ENXIO; + goto failed; + } + + /* Allocate EROM parser */ + if ((erom = bhnd_erom_alloc(erom_class, &cid, &pio.eio)) == NULL) { + device_printf(dev, "failed to allocate device enumeration " + "table parser\n"); + error = ENXIO; + goto failed; + } + + /* Read the full core table */ + error = bhnd_erom_get_core_table(erom, &erom_cores, &erom_ncores); + if (error) { + device_printf(dev, "error fetching core table: %d\n", error); + goto failed; + } + + /* Provide the results to our caller */ + *cores = malloc(sizeof(erom_cores[0]) * erom_ncores, M_BHND, M_WAITOK); + memcpy(*cores, erom_cores, sizeof(erom_cores[0]) * erom_ncores); + *ncores = erom_ncores; + + *chipid = cid; + if (eromcls != NULL) + *eromcls = erom_class; + + /* Clean up */ + bhnd_erom_free_core_table(erom, erom_cores); + bhnd_erom_free(erom); + bhndb_release_host_resources(hr); + + return (0); + +failed: + if (erom_cores != NULL) + bhnd_erom_free_core_table(erom, erom_cores); + + if (erom != NULL) + bhnd_erom_free(erom); + + bhndb_release_host_resources(hr); + return (error); +} + static int bhndb_pci_add_children(struct bhndb_pci_softc *sc) { @@ -309,7 +488,7 @@ bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc) KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+")); /* Fetch the associated resource */ - r = bhndb_find_regwin_resource(sc->bhndb.bus_res, sprom_win); + r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, sprom_win); KASSERT(r != NULL, ("missing resource for sprom window\n")); return (rman_get_start(r) + sprom_win->win_offset); @@ -419,7 +598,7 @@ bhndb_init_sromless_pci_config(struct bhndb_pci_softc *sc) } /* Fetch the resource containing the register window */ - core_regs = bhndb_find_regwin_resource(bres, win); + core_regs = bhndb_host_resource_for_regwin(bres->res, win); if (core_regs == NULL) { device_printf(sc->dev, "missing PCI core register resource\n"); return; @@ -449,7 +628,7 @@ bhndb_pci_resume(device_t dev) sc = device_get_softc(dev); /* Enable clocks (if supported by this hardware) */ - if ((error = bhndb_enable_pci_clocks(sc))) + if ((error = bhndb_enable_pci_clocks(sc->dev))) return (error); /* Perform resume */ @@ -465,7 +644,7 @@ bhndb_pci_suspend(device_t dev) sc = device_get_softc(dev); /* Disable clocks (if supported by this hardware) */ - if ((error = bhndb_disable_pci_clocks(sc))) + if ((error = bhndb_disable_pci_clocks(sc->dev))) return (error); /* Perform suspend */ @@ -477,7 +656,7 @@ bhndb_pci_set_window_addr(device_t dev, const struct bhndb_regwin *rw, bhnd_addr_t addr) { struct bhndb_pci_softc *sc = device_get_softc(dev); - return (sc->set_regwin(sc, rw, addr)); + return (sc->set_regwin(sc->dev, sc->parent, rw, addr)); } /** @@ -491,7 +670,7 @@ bhndb_pci_set_window_addr(device_t dev, const struct bhndb_regwin *rw, * validating the register, there's no harm in performing the verification. */ static int -bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc, +bhndb_pci_compat_setregwin(device_t dev, device_t pci_dev, const struct bhndb_regwin *rw, bhnd_addr_t addr) { int error; @@ -502,10 +681,10 @@ bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc, reg = rw->d.dyn.cfg_offset; for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) { - if ((error = bhndb_pci_fast_setregwin(sc, rw, addr))) + if ((error = bhndb_pci_fast_setregwin(dev, pci_dev, rw, addr))) return (error); - if (pci_read_config(sc->parent, reg, 4) == addr) + if (pci_read_config(pci_dev, reg, 4) == addr) return (0); DELAY(10); @@ -519,7 +698,7 @@ bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc, * A bcma(4)-only bhndb_set_window_addr implementation. */ static int -bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc, +bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev, const struct bhndb_regwin *rw, bhnd_addr_t addr) { /* The PCI bridge core only supports 32-bit addressing, regardless @@ -533,7 +712,7 @@ bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc, if (addr % rw->win_size != 0) return (EINVAL); - pci_write_config(sc->parent, rw->d.dyn.cfg_offset, addr, 4); + pci_write_config(pci_dev, rw->d.dyn.cfg_offset, addr, 4); break; default: return (ENODEV); @@ -590,6 +769,23 @@ bhndb_pci_populate_board_info(device_t dev, device_t child, return (0); } +/** + * Return true if the bridge device @p bhndb is attached via PCIe, + * false otherwise. + * + * @param dev The bhndb bridge device + */ +static bool +bhndb_is_pcie_attached(device_t dev) +{ + int reg; + + if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, ®) == 0) + return (true); + + return (false); +} + /** * Enable externally managed clocks, if required. * @@ -598,77 +794,89 @@ bhndb_pci_populate_board_info(device_t dev, device_t child, * attach/resume by directly adjusting GPIO registers exposed in the * PCI config space, and correspondingly, explicitly shutdown at * detach/suspend. - * - * @param sc Bridge driver state. + * + * @note This function may be safely called prior to device attach, (e.g. + * from DEVICE_PROBE). + * + * @param dev The bhndb bridge device */ static int -bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc) +bhndb_enable_pci_clocks(device_t dev) { + device_t pci_dev; uint32_t gpio_in, gpio_out, gpio_en; uint32_t gpio_flags; uint16_t pci_status; + pci_dev = device_get_parent(dev); + /* Only supported and required on PCI devices */ - if (sc->pci_devclass != BHND_DEVCLASS_PCI) + if (!bhndb_is_pcie_attached(dev)) return (0); /* Read state of XTAL pin */ - gpio_in = pci_read_config(sc->parent, BHNDB_PCI_GPIO_IN, 4); + gpio_in = pci_read_config(pci_dev, BHNDB_PCI_GPIO_IN, 4); if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON) return (0); /* already enabled */ /* Fetch current config */ - gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4); - gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4); + gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4); + gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4); /* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */ gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON); gpio_out |= gpio_flags; gpio_en |= gpio_flags; - pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4); - pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4); + pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4); + pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4); DELAY(1000); /* Reset PLL_OFF */ gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF; - pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4); + pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4); DELAY(5000); /* Clear any PCI 'sent target-abort' flag. */ - pci_status = pci_read_config(sc->parent, PCIR_STATUS, 2); + pci_status = pci_read_config(pci_dev, PCIR_STATUS, 2); pci_status &= ~PCIM_STATUS_STABORT; - pci_write_config(sc->parent, PCIR_STATUS, pci_status, 2); + pci_write_config(pci_dev, PCIR_STATUS, pci_status, 2); return (0); } /** * Disable externally managed clocks, if required. - * - * @param sc Bridge driver state. + * + * This function may be safely called prior to device attach, (e.g. + * from DEVICE_PROBE). + * + * @param dev The bhndb bridge device */ static int -bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc) +bhndb_disable_pci_clocks(device_t dev) { + device_t pci_dev; uint32_t gpio_out, gpio_en; + pci_dev = device_get_parent(dev); + /* Only supported and required on PCI devices */ - if (sc->pci_devclass != BHND_DEVCLASS_PCI) + if (bhndb_is_pcie_attached(dev)) return (0); /* Fetch current config */ - gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4); - gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4); + gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4); + gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4); /* Set PLL_OFF to HIGH, XTAL_ON to LOW. */ gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON; gpio_out |= BHNDB_PCI_GPIO_PLL_OFF; - pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4); + pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4); /* Enable both output pins */ gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON); - pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4); + pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4); return (0); } @@ -683,7 +891,7 @@ bhndb_pci_pwrctl_get_clksrc(device_t dev, device_t child, sc = device_get_softc(dev); /* Only supported on PCI devices */ - if (sc->pci_devclass != BHND_DEVCLASS_PCI) + if (bhndb_is_pcie_attached(sc->dev)) return (ENODEV); /* Only ILP is supported */ @@ -704,14 +912,14 @@ bhndb_pci_pwrctl_gate_clock(device_t dev, device_t child, struct bhndb_pci_softc *sc = device_get_softc(dev); /* Only supported on PCI devices */ - if (sc->pci_devclass != BHND_DEVCLASS_PCI) + if (bhndb_is_pcie_attached(sc->dev)) return (ENODEV); /* Only HT is supported */ if (clock != BHND_CLOCK_HT) return (ENXIO); - return (bhndb_disable_pci_clocks(sc)); + return (bhndb_disable_pci_clocks(sc->dev)); } static int @@ -721,14 +929,14 @@ bhndb_pci_pwrctl_ungate_clock(device_t dev, device_t child, struct bhndb_pci_softc *sc = device_get_softc(dev); /* Only supported on PCI devices */ - if (sc->pci_devclass != BHND_DEVCLASS_PCI) + if (bhndb_is_pcie_attached(sc->dev)) return (ENODEV); /* Only HT is supported */ if (clock != BHND_CLOCK_HT) return (ENXIO); - return (bhndb_enable_pci_clocks(sc)); + return (bhndb_enable_pci_clocks(sc->dev)); } static int @@ -754,6 +962,191 @@ bhndb_pci_assign_intr(device_t dev, device_t child, int rid) return (bus_set_resource(child, SYS_RES_IRQ, rid, start, count)); } +/** + * Initialize a new bhndb PCI bridge EROM I/O instance. This EROM I/O + * implementation supports mapping of the device enumeration table via the + * @p hr host resources. + * + * @param pio The instance to be initialized. + * @param dev The bridge device. + * @param pci_dev The bridge's parent PCI device. + * @param hr The host resources to be used to map the device + * enumeration table. + */ +static int +bhndb_pci_eio_init(struct bhndb_pci_eio *pio, device_t dev, device_t pci_dev, + struct bhndb_host_resources *hr) +{ + memset(&pio->eio, sizeof(pio->eio), 0); + pio->eio.map = bhndb_pci_eio_map; + pio->eio.read = bhndb_pci_eio_read; + pio->eio.fini = NULL; + + pio->dev = dev; + pio->pci_dev = pci_dev; + pio->hr = hr; + pio->win = NULL; + pio->res = NULL; + + return (0); +} + +/** + * Attempt to adjust the dynamic register window backing @p pio to permit + * reading @p size bytes at @p addr. + * + * If @p addr or @p size fall outside the existing mapped range, or if + * @p pio is not backed by a dynamic register window, ENXIO will be returned. + * + * @param pio The bhndb PCI erom I/O state to be modified. + * @param addr The address to be include + */ +static int +bhndb_pci_eio_adjust_mapping(struct bhndb_pci_eio *pio, bhnd_addr_t addr, + bhnd_size_t size) +{ + bhnd_addr_t target; + bhnd_size_t offset; + int error; + + + KASSERT(pio->win != NULL, ("missing register window")); + KASSERT(pio->res != NULL, ("missing regwin resource")); + KASSERT(pio->win->win_type == BHNDB_REGWIN_T_DYN, + ("unexpected window type %d", pio->win->win_type)); + + /* The requested subrange must fall within the total mapped range */ + if (addr < pio->addr || (addr - pio->addr) > pio->size || + size > pio->size || (addr - pio->addr) - pio->size < size) + { + return (ENXIO); + } + + /* Do we already have a useable mapping? */ + if (addr >= pio->res_target && + addr <= pio->res_target + pio->win->win_size && + (pio->res_target + pio->win->win_size) - addr >= size) + { + return (0); + } + + /* Page-align the target address */ + offset = addr % pio->win->win_size; + target = addr - offset; + + /* Configure the register window */ + error = bhndb_pci_compat_setregwin(pio->dev, pio->pci_dev, pio->win, + target); + if (error) { + device_printf(pio->dev, "failed to configure dynamic register " + "window: %d\n", error); + return (error); + } + + pio->res_target = target; + return (0); +} + +/* bhnd_erom_io_map() implementation */ +static int +bhndb_pci_eio_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, + bhnd_size_t size) +{ + struct bhndb_pci_eio *pio; + const struct bhndb_regwin *regwin; + struct resource *r; + bhnd_addr_t target; + bhnd_size_t offset; + int error; + + pio = (struct bhndb_pci_eio *)eio; + + /* Locate a useable dynamic register window */ + regwin = bhndb_regwin_find_type(pio->hr->cfg->register_windows, + BHNDB_REGWIN_T_DYN, MIN(size, BHND_DEFAULT_CORE_SIZE)); + if (regwin == NULL) { + device_printf(pio->dev, "unable to map %#jx+%#jx; no " + "usable dynamic register window found\n", addr, size); + return (ENXIO); + } + + /* Locate the host resource mapping our register window */ + if ((r = bhndb_host_resource_for_regwin(pio->hr, regwin)) == NULL) { + device_printf(pio->dev, "unable to map %#jx+%#jx; no " + "usable register resource found\n", addr, size); + return (ENXIO); + } + + /* Page-align the target address */ + offset = addr % regwin->win_size; + target = addr - offset; + + /* Configure the register window */ + error = bhndb_pci_compat_setregwin(pio->dev, pio->pci_dev, regwin, + target); + if (error) { + device_printf(pio->dev, "failed to configure dynamic register " + "window: %d\n", error); + return (error); + } + + /* Update our mapping state */ + pio->win = regwin; + pio->res = r; + pio->addr = addr; + pio->size = size; + pio->res_target = target; + + return (0); +} + +/* bhnd_erom_io_read() implementation */ +static uint32_t +bhndb_pci_eio_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width) +{ + struct bhndb_pci_eio *pio; + bhnd_addr_t addr; + bus_size_t res_offset; + int error; + + pio = (struct bhndb_pci_eio *)eio; + + /* Calculate absolute address */ + if (BHND_SIZE_MAX - offset < pio->addr) { + device_printf(pio->dev, "invalid offset %#jx+%#jx\n", pio->addr, + offset); + return (UINT32_MAX); + } + + addr = pio->addr + offset; + + /* Adjust the mapping for our read */ + if ((error = bhndb_pci_eio_adjust_mapping(pio, addr, width))) { + device_printf(pio->dev, "failed to adjust register mapping: " + "%d\n", error); + return (UINT32_MAX); + } + + KASSERT(pio->res_target <= addr, ("invalid mapping (%#jx vs. %#jx)", + pio->res_target, addr)); + + /* Determine the actual read offset within our register window + * resource */ + res_offset = (addr - pio->res_target) + pio->win->win_offset; + + /* Perform our read */ + switch (width) { + case 1: + return (bus_read_1(pio->res, res_offset)); + case 2: + return (bus_read_2(pio->res, res_offset)); + case 4: + return (bus_read_4(pio->res, res_offset)); + default: + panic("unsupported width: %u", width); + } +} + static device_method_t bhndb_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, bhndb_pci_probe), diff --git a/sys/dev/bhnd/bhndb/bhndb_pcivar.h b/sys/dev/bhnd/bhndb/bhndb_pcivar.h index 344812ea050a..c00ac326c798 100644 --- a/sys/dev/bhnd/bhndb/bhndb_pcivar.h +++ b/sys/dev/bhnd/bhndb/bhndb_pcivar.h @@ -45,7 +45,7 @@ struct bhndb_pci_softc; /* * An interconnect-specific function implementing BHNDB_SET_WINDOW_ADDR */ -typedef int (*bhndb_pci_set_regwin_t)(struct bhndb_pci_softc *sc, +typedef int (*bhndb_pci_set_regwin_t)(device_t dev, device_t pci_dev, const struct bhndb_regwin *rw, bhnd_addr_t addr); /* bhndb_pci interrupt state */ diff --git a/sys/dev/bhnd/bhndb/bhndb_private.h b/sys/dev/bhnd/bhndb/bhndb_private.h index be92b7b36672..bb4f31a76708 100644 --- a/sys/dev/bhnd/bhndb/bhndb_private.h +++ b/sys/dev/bhnd/bhndb/bhndb_private.h @@ -1,7 +1,10 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -51,21 +54,10 @@ struct bhndb_dw_alloc; struct bhndb_region; struct bhndb_resources; -struct resource *bhndb_find_resource_range( - struct bhndb_resources *br, - rman_res_t start, rman_res_t count); - -struct resource *bhndb_find_regwin_resource( - struct bhndb_resources *br, - const struct bhndb_regwin *win); - struct bhndb_resources *bhndb_alloc_resources(device_t dev, device_t parent_dev, const struct bhndb_hwcfg *cfg); -int bhndb_alloc_host_resources( - struct bhndb_resources *br); - void bhndb_free_resources( struct bhndb_resources *br); @@ -107,32 +99,6 @@ int bhndb_dw_set_addr(device_t dev, struct bhndb_dw_alloc *dwa, bus_addr_t addr, bus_size_t size); -size_t bhndb_regwin_count( - const struct bhndb_regwin *table, - bhndb_regwin_type_t type); - -const struct bhndb_regwin *bhndb_regwin_find_type( - const struct bhndb_regwin *table, - bhndb_regwin_type_t type, - bus_size_t min_size); - -const struct bhndb_regwin *bhndb_regwin_find_core( - const struct bhndb_regwin *table, - bhnd_devclass_t class, int unit, - bhnd_port_type port_type, u_int port, - u_int region); - - -const struct bhndb_regwin *bhndb_regwin_find_best( - const struct bhndb_regwin *table, - bhnd_devclass_t class, int unit, - bhnd_port_type port_type, u_int port, - u_int region, bus_size_t min_size); - -bool bhndb_regwin_match_core( - const struct bhndb_regwin *regw, - struct bhnd_core_info *core); - const struct bhndb_hw_priority *bhndb_hw_priority_find_core( const struct bhndb_hw_priority *table, struct bhnd_core_info *core); @@ -177,10 +143,7 @@ struct bhndb_resources { device_t dev; /**< bridge device */ const struct bhndb_hwcfg *cfg; /**< hardware configuration */ - device_t parent_dev; /**< parent device */ - struct resource_spec *res_spec; /**< parent bus resource specs, or NULL if not allocated */ - struct resource **res; /**< parent bus resources, or NULL if not allocated */ - bool res_avail; /**< if parent bus resources have been allocated */ + struct bhndb_host_resources *res; /**< host resources, or NULL if not allocated */ struct rman ht_mem_rman; /**< host memory manager */ struct rman br_mem_rman; /**< bridged memory manager */ diff --git a/sys/dev/bhnd/bhndb/bhndb_subr.c b/sys/dev/bhnd/bhndb/bhndb_subr.c index 4cd8963a3e83..55ca48e51082 100644 --- a/sys/dev/bhnd/bhndb/bhndb_subr.c +++ b/sys/dev/bhnd/bhndb/bhndb_subr.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -183,9 +187,10 @@ bhnd_generic_br_resume_child(device_t dev, device_t child) } /** - * Find a SYS_RES_MEMORY resource containing the given address range. + * Find a host resource of @p type that maps the given range. * - * @param br The bhndb resource state to search. + * @param hr The resource state to search. + * @param type The resource type to search for (see SYS_RES_*). * @param start The start address of the range to search for. * @param count The size of the range to search for. * @@ -193,15 +198,13 @@ bhnd_generic_br_resume_child(device_t dev, device_t child) * @retval NULL if no resource containing the requested range can be found. */ struct resource * -bhndb_find_resource_range(struct bhndb_resources *br, rman_res_t start, - rman_res_t count) +bhndb_host_resource_for_range(struct bhndb_host_resources *hr, int type, + rman_res_t start, rman_res_t count) { - KASSERT(br->res_avail, ("no host resources allocated")); + for (u_int i = 0; hr->resource_specs[i].type != -1; i++) { + struct resource *r = hr->resources[i]; - for (u_int i = 0; br->res_spec[i].type != -1; i++) { - struct resource *r = br->res[i]; - - if (br->res_spec->type != SYS_RES_MEMORY) + if (hr->resource_specs[i].type != type) continue; /* Verify range */ @@ -218,23 +221,21 @@ bhndb_find_resource_range(struct bhndb_resources *br, rman_res_t start, } /** - * Find the resource containing @p win. + * Find a host resource of that matches the given register window definition. * - * @param br The bhndb resource state to search. - * @param win A register window. + * @param hr The resource state to search. + * @param win A register window definition. * - * @retval resource the resource containing @p win. - * @retval NULL if no resource containing @p win can be found. + * @retval resource the host resource corresponding to @p win. + * @retval NULL if no resource corresponding to @p win can be found. */ struct resource * -bhndb_find_regwin_resource(struct bhndb_resources *br, +bhndb_host_resource_for_regwin(struct bhndb_host_resources *hr, const struct bhndb_regwin *win) { const struct resource_spec *rspecs; - KASSERT(br->res_avail, ("no host resources allocated")); - - rspecs = br->cfg->resource_specs; + rspecs = hr->resource_specs; for (u_int i = 0; rspecs[i].type != -1; i++) { if (win->res.type != rspecs[i].type) continue; @@ -243,12 +244,11 @@ bhndb_find_regwin_resource(struct bhndb_resources *br, continue; /* Found declared resource */ - return (br->res[i]); + return (hr->resources[i]); } - device_printf(br->dev, - "missing regwin resource spec (type=%d, rid=%d)\n", - win->res.type, win->res.rid); + device_printf(hr->owner, "missing regwin resource spec " + "(type=%d, rid=%d)\n", win->res.type, win->res.rid); return (NULL); } @@ -281,8 +281,8 @@ bhndb_alloc_resources(device_t dev, device_t parent_dev, /* Basic initialization */ r->dev = dev; - r->parent_dev = parent_dev; r->cfg = cfg; + r->res = NULL; r->min_prio = BHNDB_PRIORITY_NONE; STAILQ_INIT(&r->bus_regions); @@ -380,6 +380,72 @@ bhndb_alloc_resources(device_t dev, device_t parent_dev, rnid++; } + /* Allocate host resources */ + error = bhndb_alloc_host_resources(parent_dev, r->cfg, &r->res); + if (error) { + device_printf(r->dev, + "could not allocate host resources on %s: %d\n", + device_get_nameunit(parent_dev), error); + goto failed; + } + + /* Populate (and validate) parent resource references for all + * dynamic windows */ + for (size_t i = 0; i < r->dwa_count; i++) { + struct bhndb_dw_alloc *dwa; + const struct bhndb_regwin *win; + + dwa = &r->dw_alloc[i]; + win = dwa->win; + + /* Find and validate corresponding resource. */ + dwa->parent_res = bhndb_host_resource_for_regwin(r->res, win); + if (dwa->parent_res == NULL) { + device_printf(r->dev, "no host resource found for %u " + "register window with offset %#jx and " + "size %#jx\n", + win->win_type, + (uintmax_t)win->win_offset, + (uintmax_t)win->win_size); + + error = ENXIO; + goto failed; + } + + if (rman_get_size(dwa->parent_res) < win->win_offset + + win->win_size) + { + device_printf(r->dev, "resource %d too small for " + "register window with offset %llx and size %llx\n", + rman_get_rid(dwa->parent_res), + (unsigned long long) win->win_offset, + (unsigned long long) win->win_size); + + error = EINVAL; + goto failed; + } + } + + /* Add allocated memory resources to our host memory resource manager */ + for (u_int i = 0; r->res->resource_specs[i].type != -1; i++) { + struct resource *res; + + /* skip non-memory resources */ + if (r->res->resource_specs[i].type != SYS_RES_MEMORY) + continue; + + /* add host resource to set of managed regions */ + res = r->res->resources[i]; + error = rman_manage_region(&r->ht_mem_rman, + rman_get_start(res), rman_get_end(res)); + if (error) { + device_printf(r->dev, + "could not register host memory region with " + "ht_mem_rman: %d\n", error); + goto failed; + } + } + return (r); failed: @@ -395,136 +461,14 @@ bhndb_alloc_resources(device_t dev, device_t parent_dev, if (r->dwa_freelist != NULL) free(r->dwa_freelist, M_BHND); + if (r->res != NULL) + bhndb_release_host_resources(r->res); + free(r, M_BHND); return (NULL); } -/** - * Allocate host resources required by @p br, and initialize - * internal BHNDB_ADDRSPACE_NATIVE resource manager state. - * - * @param br Resource state. - */ -int -bhndb_alloc_host_resources(struct bhndb_resources *br) -{ - size_t res_num; - int error; - - KASSERT(!br->res_avail, ("host resources already allocated")); - - /* Determine our bridge resource count from the hardware config. */ - res_num = 0; - for (size_t i = 0; br->cfg->resource_specs[i].type != -1; i++) - res_num++; - - /* Allocate space for a non-const copy of our resource_spec - * table; this will be updated with the RIDs assigned by - * bus_alloc_resources. */ - br->res_spec = malloc(sizeof(br->res_spec[0]) * (res_num + 1), M_BHND, - M_NOWAIT); - if (br->res_spec == NULL) { - error = ENOMEM; - goto failed; - } - - /* Initialize and terminate the table */ - for (size_t i = 0; i < res_num; i++) - br->res_spec[i] = br->cfg->resource_specs[i]; - - br->res_spec[res_num].type = -1; - - /* Allocate space for our resource references */ - br->res = malloc(sizeof(br->res[0]) * res_num, M_BHND, M_NOWAIT); - if (br->res == NULL) { - error = ENOMEM; - goto failed; - } - - /* Allocate host resources */ - error = bus_alloc_resources(br->parent_dev, br->res_spec, br->res); - if (error) { - device_printf(br->dev, - "could not allocate bridge resources on %s: %d\n", - device_get_nameunit(br->parent_dev), error); - goto failed; - } else { - br->res_avail = true; - } - - /* Populate (and validate) parent resource references for all - * dynamic windows */ - for (size_t i = 0; i < br->dwa_count; i++) { - struct bhndb_dw_alloc *dwa; - const struct bhndb_regwin *win; - - dwa = &br->dw_alloc[i]; - win = dwa->win; - - /* Find and validate corresponding resource. */ - dwa->parent_res = bhndb_find_regwin_resource(br, win); - if (dwa->parent_res == NULL) { - device_printf(br->dev, "no host resource found for %u " - "register window with offset %#jx and " - "size %#jx\n", - win->win_type, - (uintmax_t)win->win_offset, - (uintmax_t)win->win_size); - - error = ENXIO; - goto failed; - } - - if (rman_get_size(dwa->parent_res) < win->win_offset + - win->win_size) - { - device_printf(br->dev, "resource %d too small for " - "register window with offset %llx and size %llx\n", - rman_get_rid(dwa->parent_res), - (unsigned long long) win->win_offset, - (unsigned long long) win->win_size); - - error = EINVAL; - goto failed; - } - } - - /* Add allocated memory resources to our host memory resource manager */ - for (u_int i = 0; br->res_spec[i].type != -1; i++) { - struct resource *res; - - /* skip non-memory resources */ - if (br->res_spec[i].type != SYS_RES_MEMORY) - continue; - - /* add host resource to set of managed regions */ - res = br->res[i]; - error = rman_manage_region(&br->ht_mem_rman, - rman_get_start(res), rman_get_end(res)); - if (error) { - device_printf(br->dev, - "could not register host memory region with " - "ht_mem_rman: %d\n", error); - goto failed; - } - } - - return (0); - -failed: - if (br->res_avail) - bus_release_resources(br->parent_dev, br->res_spec, br->res); - - if (br->res != NULL) - free(br->res, M_BHND); - - if (br->res_spec != NULL) - free(br->res_spec, M_BHND); - - return (error); -} - /** * Deallocate the given bridge resource structure and any associated resources. * @@ -551,9 +495,9 @@ bhndb_free_resources(struct bhndb_resources *br) } } - /* Release resources allocated through our parent. */ - if (br->res_avail) - bus_release_resources(br->parent_dev, br->res_spec, br->res); + /* Release host resources allocated through our parent. */ + if (br->res != NULL) + bhndb_release_host_resources(br->res); /* Clean up resource reservations */ for (size_t i = 0; i < br->dwa_count; i++) { @@ -575,17 +519,153 @@ bhndb_free_resources(struct bhndb_resources *br) rman_fini(&br->ht_mem_rman); rman_fini(&br->br_mem_rman); - /* Free backing resource state structures */ - if (br->res != NULL) - free(br->res, M_BHND); - - if (br->res_spec != NULL) - free(br->res_spec, M_BHND); - free(br->dw_alloc, M_BHND); free(br->dwa_freelist, M_BHND); } +/** + * Allocate host bus resources defined by @p hwcfg. + * + * On success, the caller assumes ownership of the allocated host resources, + * which must be freed via bhndb_release_host_resources(). + * + * @param dev The device to be used when allocating resources + * (e.g. via bus_alloc_resources()). + * @param hwcfg The hardware configuration defining the host + * resources to be allocated + * @param[out] resources On success, the allocated host resources. + */ +int +bhndb_alloc_host_resources(device_t dev, const struct bhndb_hwcfg *hwcfg, + struct bhndb_host_resources **resources) +{ + struct bhndb_host_resources *hr; + size_t nres; + int error; + + hr = malloc(sizeof(*hr), M_BHND, M_WAITOK); + hr->owner = dev; + hr->cfg = hwcfg; + hr->resource_specs = NULL; + hr->resources = NULL; + + /* Determine our bridge resource count from the hardware config. */ + nres = 0; + for (size_t i = 0; hwcfg->resource_specs[i].type != -1; i++) + nres++; + + /* Allocate space for a non-const copy of our resource_spec + * table; this will be updated with the RIDs assigned by + * bus_alloc_resources. */ + hr->resource_specs = malloc(sizeof(hr->resource_specs[0]) * (nres + 1), + M_BHND, M_WAITOK); + + /* Initialize and terminate the table */ + for (size_t i = 0; i < nres; i++) + hr->resource_specs[i] = hwcfg->resource_specs[i]; + + hr->resource_specs[nres].type = -1; + + /* Allocate space for our resource references */ + hr->resources = malloc(sizeof(hr->resources[0]) * nres, M_BHND, + M_WAITOK); + + /* Allocate host resources */ + error = bus_alloc_resources(hr->owner, hr->resource_specs, + hr->resources); + if (error) { + device_printf(dev, "could not allocate bridge resources via " + "%s: %d\n", device_get_nameunit(dev), error); + goto failed; + } + + *resources = hr; + return (0); + +failed: + if (hr->resource_specs != NULL) + free(hr->resource_specs, M_BHND); + + if (hr->resources != NULL) + free(hr->resources, M_BHND); + + free(hr, M_BHND); + + return (error); +} + +/** + * Deallocate a set of bridge host resources. + * + * @param hr The resources to be freed. + */ +void +bhndb_release_host_resources(struct bhndb_host_resources *hr) +{ + bus_release_resources(hr->owner, hr->resource_specs, hr->resources); + + free(hr->resources, M_BHND); + free(hr->resource_specs, M_BHND); + free(hr, M_BHND); +} + + +/** + * Search @p cores for the core serving as the bhnd host bridge. + * + * This function uses a heuristic valid on all known PCI/PCIe/PCMCIA-bridged + * bhnd(4) devices to determine the hostb core: + * + * - The core must have a Broadcom vendor ID. + * - The core devclass must match the bridge type. + * - The core must be the first device on the bus with the bridged device + * class. + * + * @param cores The core table to search. + * @param ncores The number of cores in @p cores. + * @param bridge_devclass The expected device class of the bridge core. + * @param[out] core If found, the matching host bridge core info. + * + * @retval 0 success + * @retval ENOENT not found + */ +int +bhndb_find_hostb_core(struct bhnd_core_info *cores, u_int ncores, + bhnd_devclass_t bridge_devclass, struct bhnd_core_info *core) +{ + struct bhnd_core_match md; + struct bhnd_core_info *match; + u_int match_core_idx; + + /* Set up a match descriptor for the required device class. */ + md = (struct bhnd_core_match) { + BHND_MATCH_CORE_CLASS(bridge_devclass), + BHND_MATCH_CORE_UNIT(0) + }; + + /* Find the matching core with the lowest core index */ + match = NULL; + match_core_idx = UINT_MAX; + + for (u_int i = 0; i < ncores; i++) { + if (!bhnd_core_matches(&cores[i], &md)) + continue; + + /* Lower core indices take precedence */ + if (match != NULL && match_core_idx < match->core_idx) + continue; + + match = &cores[i]; + match_core_idx = match->core_idx; + } + + if (match == NULL) + return (ENOENT); + + *core = *match; + return (0); +} + /** * Add a bus region entry to @p r for the given base @p addr and @p size. * diff --git a/sys/dev/bhnd/bhndb/bhndbvar.h b/sys/dev/bhnd/bhndb/bhndbvar.h index 2ce502d14342..b0a6a4be16d1 100644 --- a/sys/dev/bhnd/bhndb/bhndbvar.h +++ b/sys/dev/bhnd/bhndb/bhndbvar.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -52,18 +56,69 @@ DECLARE_CLASS(bhndb_driver); struct bhndb_resources; +struct bhndb_host_resources; -int bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass); +int bhndb_attach(device_t dev, + struct bhnd_chipid *cid, + struct bhnd_core_info *cores, u_int ncores, + struct bhnd_core_info *bridge_core, + bhnd_erom_class_t *erom_class); -int bhndb_generic_probe(device_t dev); -int bhndb_generic_detach(device_t dev); -int bhndb_generic_suspend(device_t dev); -int bhndb_generic_resume(device_t dev); -int bhndb_generic_init_full_config(device_t dev, device_t child, - const struct bhndb_hw_priority *hw_prio_table); +int bhndb_generic_probe(device_t dev); +int bhndb_generic_detach(device_t dev); +int bhndb_generic_suspend(device_t dev); +int bhndb_generic_resume(device_t dev); +int bhndb_generic_init_full_config(device_t dev, + device_t child, + const struct bhndb_hw_priority *hw_prio_table); -int bhnd_generic_br_suspend_child(device_t dev, device_t child); -int bhnd_generic_br_resume_child(device_t dev, device_t child); +int bhnd_generic_br_suspend_child(device_t dev, + device_t child); +int bhnd_generic_br_resume_child(device_t dev, + device_t child); + +int bhndb_find_hostb_core( + struct bhnd_core_info *cores, u_int ncores, + bhnd_devclass_t bridge_devclass, + struct bhnd_core_info *core); + +int bhndb_alloc_host_resources(device_t dev, + const struct bhndb_hwcfg *hwcfg, + struct bhndb_host_resources **resources); +void bhndb_release_host_resources( + struct bhndb_host_resources *resources); +struct resource *bhndb_host_resource_for_range( + struct bhndb_host_resources *resources, + int type, rman_res_t start, + rman_res_t count); +struct resource *bhndb_host_resource_for_regwin( + struct bhndb_host_resources *resources, + const struct bhndb_regwin *win); + +size_t bhndb_regwin_count( + const struct bhndb_regwin *table, + bhndb_regwin_type_t type); + +const struct bhndb_regwin *bhndb_regwin_find_type( + const struct bhndb_regwin *table, + bhndb_regwin_type_t type, + bus_size_t min_size); + +const struct bhndb_regwin *bhndb_regwin_find_core( + const struct bhndb_regwin *table, + bhnd_devclass_t class, int unit, + bhnd_port_type port_type, u_int port, + u_int region); + +const struct bhndb_regwin *bhndb_regwin_find_best( + const struct bhndb_regwin *table, + bhnd_devclass_t class, int unit, + bhnd_port_type port_type, u_int port, + u_int region, bus_size_t min_size); + +bool bhndb_regwin_match_core( + const struct bhndb_regwin *regw, + struct bhnd_core_info *core); /** * bhndb child address space. Children either operate in the bridged @@ -81,6 +136,16 @@ struct bhndb_devinfo { struct resource_list resources; /**< child resources. */ }; +/** + * Host resources allocated for a bridge hardware configuration. + */ +struct bhndb_host_resources { + device_t owner; /**< device owning the allocated resources */ + const struct bhndb_hwcfg *cfg; /**< bridge hardware configuration */ + struct resource_spec *resource_specs; /**< resource specification table */ + struct resource **resources; /**< allocated resource table */ +}; + /** * bhndb driver instance state. Must be first member of all subclass * softc structures. @@ -88,14 +153,13 @@ struct bhndb_devinfo { struct bhndb_softc { device_t dev; /**< bridge device */ struct bhnd_chipid chipid; /**< chip identification */ - bhnd_devclass_t bridge_class; /**< bridge core type */ - struct bhnd_core_info bridge_core; /**< bridge core. not populated until - * full bridge config is initialized */ - bool have_br_core; /**< false if not yet available */ + struct bhnd_core_info bridge_core; /**< bridge core info */ device_t parent_dev; /**< parent device */ device_t bus_dev; /**< child bhnd(4) bus */ + struct bhnd_service_registry services; /**< local service registry */ + struct mtx sc_mtx; /**< resource lock. */ struct bhndb_resources *bus_res; /**< bus resource state */ }; diff --git a/sys/dev/bhnd/bhndreg.h b/sys/dev/bhnd/bhndreg.h index 6463d1b5f5a2..1fbcccae7416 100644 --- a/sys/dev/bhnd/bhndreg.h +++ b/sys/dev/bhnd/bhndreg.h @@ -34,9 +34,9 @@ /** * The default address at which the ChipCommon core is mapped on all siba(4) - * devices, and most bcma(4) devices. + * devices, and most (all?) bcma(4) devices. */ -#define BHND_DEFAULT_CHIPC_ADDR 0x18000000 +#define BHND_DEFAULT_CHIPC_ADDR 0x18000000 /** * The standard size of a primary BHND_PORT_DEVICE or BHND_PORT_AGENT @@ -44,5 +44,9 @@ */ #define BHND_DEFAULT_CORE_SIZE 0x1000 +/** + * The standard size of the siba(4) and bcma(4) enumeration space. + */ +#define BHND_DEFAULT_ENUM_SIZE 0x00100000 #endif /* _BHND_BHNDREG_H_ */ \ No newline at end of file diff --git a/sys/dev/bhnd/bhndvar.h b/sys/dev/bhnd/bhndvar.h index 2602302a1861..6bbbb796ebba 100644 --- a/sys/dev/bhnd/bhndvar.h +++ b/sys/dev/bhnd/bhndvar.h @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -34,7 +38,10 @@ #include #include +#include #include +#include +#include #include "bhnd.h" @@ -45,57 +52,51 @@ MALLOC_DECLARE(M_BHND); DECLARE_CLASS(bhnd_driver); -int bhnd_generic_attach(device_t dev); -int bhnd_generic_detach(device_t dev); -int bhnd_generic_shutdown(device_t dev); -int bhnd_generic_resume(device_t dev); -int bhnd_generic_suspend(device_t dev); +int bhnd_generic_attach(device_t dev); +int bhnd_generic_detach(device_t dev); +int bhnd_generic_shutdown(device_t dev); +int bhnd_generic_resume(device_t dev); +int bhnd_generic_suspend(device_t dev); -int bhnd_generic_get_probe_order(device_t dev, - device_t child); +int bhnd_generic_get_probe_order(device_t dev, + device_t child); -int bhnd_generic_alloc_pmu(device_t dev, - device_t child); -int bhnd_generic_release_pmu(device_t dev, - device_t child); -int bhnd_generic_request_clock(device_t dev, - device_t child, bhnd_clock clock); -int bhnd_generic_enable_clocks(device_t dev, - device_t child, uint32_t clocks); -int bhnd_generic_request_ext_rsrc(device_t dev, - device_t child, u_int rsrc); -int bhnd_generic_release_ext_rsrc(device_t dev, - device_t child, u_int rsrc); +int bhnd_generic_alloc_pmu(device_t dev, + device_t child); +int bhnd_generic_release_pmu(device_t dev, + device_t child); +int bhnd_generic_request_clock(device_t dev, + device_t child, bhnd_clock clock); +int bhnd_generic_enable_clocks(device_t dev, + device_t child, uint32_t clocks); +int bhnd_generic_request_ext_rsrc(device_t dev, + device_t child, u_int rsrc); +int bhnd_generic_release_ext_rsrc(device_t dev, + device_t child, u_int rsrc); -int bhnd_generic_print_child(device_t dev, - device_t child); -void bhnd_generic_probe_nomatch(device_t dev, - device_t child); +int bhnd_generic_print_child(device_t dev, + device_t child); +void bhnd_generic_probe_nomatch(device_t dev, + device_t child); -void bhnd_generic_child_deleted(device_t dev, - device_t child); -int bhnd_generic_suspend_child(device_t dev, - device_t child); -int bhnd_generic_resume_child(device_t dev, - device_t child); +void bhnd_generic_child_deleted(device_t dev, + device_t child); +int bhnd_generic_suspend_child(device_t dev, + device_t child); +int bhnd_generic_resume_child(device_t dev, + device_t child); -int bhnd_generic_get_nvram_var(device_t dev, - device_t child, const char *name, void *buf, - size_t *size, bhnd_nvram_type type); +int bhnd_generic_get_nvram_var(device_t dev, + device_t child, const char *name, + void *buf, size_t *size, + bhnd_nvram_type type); /** * bhnd driver instance state. Must be first member of all subclass * softc structures. */ struct bhnd_softc { - device_t dev; /**< bus device */ - - bool attach_done; /**< true if initialization of - * all platform devices has - * been completed */ - device_t chipc_dev; /**< bhnd_chipc device */ - device_t nvram_dev; /**< bhnd_nvram device, if any */ - device_t pmu_dev; /**< bhnd_pmu device, if any */ + device_t dev; /**< bus device */ }; #endif /* _BHND_BHNDVAR_H_ */ diff --git a/sys/dev/bhnd/cores/chipc/chipc.c b/sys/dev/bhnd/cores/chipc/chipc.c index 0d1f893a8a6a..31a5a2d3780c 100644 --- a/sys/dev/bhnd/cores/chipc/chipc.c +++ b/sys/dev/bhnd/cores/chipc/chipc.c @@ -1,8 +1,12 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * Copyright (c) 2016 Michael Zhilin + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * This software was developed by Landon Fuller under sponsorship from + * the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -211,6 +215,10 @@ chipc_attach(device_t dev) if ((error = bus_generic_attach(dev))) goto failed; + /* Register ourselves with the bus */ + if ((error = bhnd_register_provider(dev, BHND_SERVICE_CHIPC))) + goto failed; + return (0); failed: @@ -234,6 +242,9 @@ chipc_detach(device_t dev) sc = device_get_softc(dev); + if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY))) + return (error); + if ((error = bus_generic_detach(dev))) return (error); @@ -1087,7 +1098,7 @@ chipc_should_enable_muxed_sprom(struct chipc_softc *sc) mtx_lock(&Giant); /* for newbus */ parent = device_get_parent(sc->dev); - hostb = bhnd_find_hostb_device(parent); + hostb = bhnd_bus_find_hostb_device(parent); if ((error = device_get_children(parent, &devs, &devcount))) { mtx_unlock(&Giant); diff --git a/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c b/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c index d2bf54c8ce35..90155418ed7f 100644 --- a/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c +++ b/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Landon Fuller - * Copyright (c) 2010, Broadcom Corporation. + * Copyright (c) 2010 Broadcom Corporation. + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. + * + * This software was developed by Landon Fuller under sponsorship from + * the FreeBSD Foundation. * * This file is derived from the siutils.c source distributed with the * Asus RT-N16 firmware source code release. @@ -116,6 +120,7 @@ bhnd_pwrctl_attach(device_t dev) struct chipc_softc *chipc_sc; bhnd_devclass_t hostb_class; device_t hostb_dev; + device_t bus; int error; sc = device_get_softc(dev); @@ -128,10 +133,12 @@ bhnd_pwrctl_attach(device_t dev) sc->quirks = bhnd_device_quirks(sc->chipc_dev, pwrctl_devices, sizeof(pwrctl_devices[0])); + bus = device_get_parent(sc->chipc_dev); + /* On devices that lack a slow clock source, HT must always be * enabled. */ hostb_class = BHND_DEVCLASS_INVALID; - hostb_dev = bhnd_find_hostb_device(device_get_parent(sc->chipc_dev)); + hostb_dev = bhnd_bus_find_hostb_device(device_get_parent(sc->chipc_dev)); if (hostb_dev != NULL) hostb_class = bhnd_get_class(hostb_dev); @@ -177,6 +184,13 @@ bhnd_pwrctl_attach(device_t dev) PWRCTL_UNLOCK(sc); + /* Register as the bus PMU provider */ + if ((error = bhnd_register_provider(dev, BHND_SERVICE_PMU))) { + device_printf(sc->dev, "failed to register PMU with bus : %d\n", + error); + goto cleanup; + } + return (0); cleanup: @@ -193,9 +207,16 @@ bhnd_pwrctl_detach(device_t dev) sc = device_get_softc(dev); + if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY))) + return (error); + + PWRCTL_LOCK(sc); + if ((error = bhnd_pwrctl_setclk(sc, BHND_CLOCK_DYN))) return (error); + PWRCTL_UNLOCK(sc); + STAILQ_FOREACH_SAFE(clkres, &sc->clkres_list, cr_link, crnext) free(clkres, M_DEVBUF); diff --git a/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c b/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c index ec2b5b2b9e9a..5d5657a1cf26 100644 --- a/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c +++ b/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -561,7 +565,7 @@ bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc, bhnd_pci_war_state state) bus_size_t reg; bhnd = device_get_parent(sc->dev); - chipc = bhnd_find_child(bhnd, BHND_DEVCLASS_CC, 0); + chipc = bhnd_bus_find_child(bhnd, BHND_DEVCLASS_CC, 0); KASSERT(chipc != NULL, ("missing chipcommon device")); /* Write SerDes PLL disable flag to the ChipCommon core */ diff --git a/sys/dev/bhnd/cores/pmu/bhnd_pmu.c b/sys/dev/bhnd/cores/pmu/bhnd_pmu.c index 6d7e907da4cb..254fa309dd39 100644 --- a/sys/dev/bhnd/cores/pmu/bhnd_pmu.c +++ b/sys/dev/bhnd/cores/pmu/bhnd_pmu.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -128,7 +132,7 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *res) /* Fetch capability flags */ sc->caps = bhnd_bus_read_4(sc->res, BHND_PMU_CAP); - /* Find the bus-attached core */ + /* Find the bus and bus-attached core */ bhnd_class = devclass_find("bhnd"); core = sc->dev; while ((bus = device_get_parent(core)) != NULL) { @@ -153,7 +157,7 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *res) } /* Locate ChipCommon device */ - sc->chipc_dev = bhnd_find_child(bus, BHND_DEVCLASS_CC, 0); + sc->chipc_dev = bhnd_bus_find_child(bus, BHND_DEVCLASS_CC, 0); if (sc->chipc_dev == NULL) { device_printf(sc->dev, "chipcommon device not found\n"); return (ENXIO); @@ -186,6 +190,13 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *res) goto failed; } + /* Register ourselves with the bus */ + if ((error = bhnd_register_provider(dev, BHND_SERVICE_PMU))) { + device_printf(sc->dev, "failed to register PMU with bus : %d\n", + error); + goto failed; + } + /* Set up sysctl nodes */ ctx = device_get_sysctl_ctx(dev); tree = device_get_sysctl_tree(dev); @@ -217,9 +228,13 @@ int bhnd_pmu_detach(device_t dev) { struct bhnd_pmu_softc *sc; + int error; sc = device_get_softc(dev); + if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY))) + return (error); + BPMU_LOCK_DESTROY(sc); bhnd_pmu_query_fini(&sc->query); diff --git a/sys/dev/bhnd/nvram/bhnd_sprom.c b/sys/dev/bhnd/nvram/bhnd_sprom.c index d830af9785d1..0eb17b4b1e88 100644 --- a/sys/dev/bhnd/nvram/bhnd_sprom.c +++ b/sys/dev/bhnd/nvram/bhnd_sprom.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -99,8 +103,10 @@ bhnd_sprom_attach(device_t dev, bus_size_t offset) sc = device_get_softc(dev); sc->dev = dev; + sc->store = NULL; io = NULL; + r = NULL; /* Allocate SPROM resource */ rid = 0; @@ -138,6 +144,16 @@ bhnd_sprom_attach(device_t dev, bus_size_t offset) bhnd_nvram_io_free(io); bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); + io = NULL; + r = NULL; + + /* Register ourselves with the bus */ + if ((error = bhnd_register_provider(dev, BHND_SERVICE_NVRAM))) { + device_printf(dev, "failed to register NVRAM provider: %d\n", + error); + goto failed; + } + return (0); failed: @@ -145,7 +161,11 @@ bhnd_sprom_attach(device_t dev, bus_size_t offset) if (io != NULL) bhnd_nvram_io_free(io); - bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); + if (r != NULL) + bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); + + if (sc->store != NULL) + bhnd_nvram_store_free(sc->store); return (error); } @@ -175,9 +195,13 @@ int bhnd_sprom_detach(device_t dev) { struct bhnd_sprom_softc *sc; + int error; sc = device_get_softc(dev); + if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY))) + return (error); + bhnd_nvram_store_free(sc->store); return (0); diff --git a/sys/dev/bhnd/siba/siba.c b/sys/dev/bhnd/siba/siba.c index 7f85a1d8ec89..d7be266b4680 100644 --- a/sys/dev/bhnd/siba/siba.c +++ b/sys/dev/bhnd/siba/siba.c @@ -820,30 +820,34 @@ int siba_add_children(device_t dev) { const struct bhnd_chipid *chipid; - struct bhnd_core_info *cores; - struct siba_devinfo *dinfo; + struct siba_core_id *cores; struct bhnd_resource *r; + device_t *children; int rid; int error; - dinfo = NULL; cores = NULL; r = NULL; chipid = BHND_BUS_GET_CHIPID(dev, dev); - /* Allocate our temporary core table and enumerate all cores */ - cores = malloc(sizeof(*cores) * chipid->ncores, M_BHND, M_NOWAIT); - if (cores == NULL) - return (ENOMEM); + /* Allocate our temporary core and device table */ + cores = malloc(sizeof(*cores) * chipid->ncores, M_BHND, M_WAITOK); + children = malloc(sizeof(*children) * chipid->ncores, M_BHND, + M_WAITOK | M_ZERO); - /* Add all cores. */ + /* + * Add child devices for all discovered cores. + * + * On bridged devices, we'll exhaust our available register windows if + * we map config blocks on unpopulated/disabled cores. To avoid this, we + * defer mapping of the per-core siba(4) config blocks until all cores + * have been enumerated and otherwise configured. + */ for (u_int i = 0; i < chipid->ncores; i++) { - struct siba_core_id cid; - device_t child; + struct siba_devinfo *dinfo; uint32_t idhigh, idlow; rman_res_t r_count, r_end, r_start; - int nintr; /* Map the core's register block */ rid = 0; @@ -854,51 +858,73 @@ siba_add_children(device_t dev) r_end, r_count, RF_ACTIVE); if (r == NULL) { error = ENXIO; - goto cleanup; + goto failed; } - /* Add the child device */ - child = BUS_ADD_CHILD(dev, 0, NULL, -1); - if (child == NULL) { - error = ENXIO; - goto cleanup; - } - /* Read the core info */ idhigh = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); idlow = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW)); - cid = siba_parse_core_id(idhigh, idlow, i, 0); - cores[i] = cid.core_info; + cores[i] = siba_parse_core_id(idhigh, idlow, i, 0); - /* Determine unit number */ + /* Determine and set unit number */ for (u_int j = 0; j < i; j++) { - if (cores[j].vendor == cores[i].vendor && - cores[j].device == cores[i].device) - cores[i].unit++; + struct bhnd_core_info *cur = &cores[i].core_info; + struct bhnd_core_info *prev = &cores[j].core_info; + + if (prev->vendor == cur->vendor && + prev->device == cur->device) + cur->unit++; + } + + /* Add the child device */ + children[i] = BUS_ADD_CHILD(dev, 0, NULL, -1); + if (children[i] == NULL) { + error = ENXIO; + goto failed; } /* Initialize per-device bus info */ - if ((dinfo = device_get_ivars(child)) == NULL) { + if ((dinfo = device_get_ivars(children[i])) == NULL) { error = ENXIO; - goto cleanup; + goto failed; } - if ((error = siba_init_dinfo(dev, dinfo, &cid))) - goto cleanup; + if ((error = siba_init_dinfo(dev, dinfo, &cores[i]))) + goto failed; /* Register the core's address space(s). */ if ((error = siba_register_addrspaces(dev, dinfo, r))) - goto cleanup; + goto failed; - /* Release our resource covering the register blocks - * we're about to map */ + /* Unmap the core's register block */ bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); r = NULL; + /* If pins are floating or the hardware is otherwise + * unpopulated, the device shouldn't be used. */ + if (bhnd_is_hw_disabled(children[i])) + device_disable(children[i]); + } + + /* Map all valid core's config register blocks and perform interrupt + * assignment */ + for (u_int i = 0; i < chipid->ncores; i++) { + struct siba_devinfo *dinfo; + device_t child; + int nintr; + + child = children[i]; + + /* Skip if core is disabled */ + if (bhnd_is_hw_disabled(child)) + continue; + + dinfo = device_get_ivars(child); + /* Map the core's config blocks */ if ((error = siba_map_cfg_resources(dev, dinfo))) - goto cleanup; + goto failed; /* Assign interrupts */ nintr = bhnd_get_intr_count(child); @@ -910,18 +936,25 @@ siba_add_children(device_t dev) } } - /* If pins are floating or the hardware is otherwise - * unpopulated, the device shouldn't be used. */ - if (bhnd_is_hw_disabled(child)) - device_disable(child); - /* Issue bus callback for fully initialized child. */ BHND_BUS_CHILD_ADDED(dev, child); } - -cleanup: - if (cores != NULL) - free(cores, M_BHND); + + free(cores, M_BHND); + free(children, M_BHND); + + return (0); + +failed: + for (u_int i = 0; i < chipid->ncores; i++) { + if (children[i] == NULL) + continue; + + device_delete_child(dev, children[i]); + } + + free(cores, M_BHND); + free(children, M_BHND); if (r != NULL) bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); diff --git a/sys/dev/bhnd/siba/siba_bhndb.c b/sys/dev/bhnd/siba/siba_bhndb.c index cfc1180ad930..13082edc2347 100644 --- a/sys/dev/bhnd/siba/siba_bhndb.c +++ b/sys/dev/bhnd/siba/siba_bhndb.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2015 Landon Fuller + * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -222,14 +226,14 @@ siba_bhndb_wars_pcie_clear_d11_timeout(struct siba_softc *sc) uint32_t imcfg; /* Only applies when bridged by PCIe */ - if ((hostb_dev = bhnd_find_hostb_device(sc->dev)) == NULL) + if ((hostb_dev = bhnd_bus_find_hostb_device(sc->dev)) == NULL) return (ENXIO); if (bhnd_get_class(hostb_dev) != BHND_DEVCLASS_PCIE) return (0); /* Only applies if there's a D11 core */ - d11 = bhnd_match_child(sc->dev, &(struct bhnd_core_match) { + d11 = bhnd_bus_match_child(sc->dev, &(struct bhnd_core_match) { BHND_MATCH_CORE(BHND_MFGID_BCM, BHND_COREID_D11), BHND_MATCH_CORE_UNIT(0) }); @@ -259,7 +263,7 @@ siba_bhndb_wars_hwup(struct siba_softc *sc) uint32_t quirks; int error; - if ((hostb_dev = bhnd_find_hostb_device(sc->dev)) == NULL) + if ((hostb_dev = bhnd_bus_find_hostb_device(sc->dev)) == NULL) return (ENXIO); quirks = bhnd_device_quirks(hostb_dev, bridge_devs, diff --git a/sys/dev/bhnd/siba/siba_erom.c b/sys/dev/bhnd/siba/siba_erom.c index 58ab3d37f00b..1d7c0af62612 100644 --- a/sys/dev/bhnd/siba/siba_erom.c +++ b/sys/dev/bhnd/siba/siba_erom.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -50,12 +54,7 @@ struct siba_erom_io; static int siba_eio_init(struct siba_erom_io *io, - device_t parent, struct bhnd_resource *res, - int rid, bus_size_t offset, u_int ncores); - -static int siba_eio_init_static(struct siba_erom_io *io, - bus_space_tag_t bst, bus_space_handle_t bsh, - bus_size_t offset, u_int ncores); + struct bhnd_erom_io *eio, u_int ncores); static uint32_t siba_eio_read_4(struct siba_erom_io *io, u_int core_idx, bus_size_t offset); @@ -71,18 +70,9 @@ static int siba_eio_read_chipid(struct siba_erom_io *io, * SIBA EROM generic I/O context */ struct siba_erom_io { + struct bhnd_erom_io *eio; /**< erom I/O callbacks */ + bhnd_addr_t base_addr; /**< address of first core */ u_int ncores; /**< core count */ - bus_size_t offset; /**< base read offset */ - - /* resource state */ - device_t dev; /**< parent dev to use for resource allocations, - or NULL if unavailable. */ - struct bhnd_resource *res; /**< memory resource, or NULL */ - int rid; /**< memory resource ID */ - - /* bus tag state */ - bus_space_tag_t bst; /**< bus space tag */ - bus_space_handle_t bsh; /**< bus space handle */ }; /** @@ -93,22 +83,23 @@ struct siba_erom { struct siba_erom_io io; /**< i/o context */ }; -#define EROM_LOG(io, fmt, ...) do { \ - if (io->dev != NULL) { \ - device_printf(io->dev, "%s: " fmt, __FUNCTION__, \ - ##__VA_ARGS__); \ - } else { \ - printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ - } \ +#define EROM_LOG(io, fmt, ...) do { \ + printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ } while(0) +/* SIBA implementation of BHND_EROM_PROBE() */ static int -siba_erom_probe_common(struct siba_erom_io *io, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) +siba_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio, + const struct bhnd_chipid *hint, struct bhnd_chipid *cid) { + struct siba_erom_io io; uint32_t idreg; int error; + /* Initialize I/O context, assuming at least the first core is mapped */ + if ((error = siba_eio_init(&io, eio, 1))) + return (error); + /* Try using the provided hint. */ if (hint != NULL) { struct siba_core_id sid; @@ -127,7 +118,7 @@ siba_erom_probe_common(struct siba_erom_io *io, const struct bhnd_chipid *hint, * BCM4710, it's a SDRAM core (0x803). */ - sid = siba_eio_read_core_id(io, 0, 0); + sid = siba_eio_read_core_id(&io, 0, 0); if (sid.core_info.vendor != BHND_MFGID_BCM) return (ENXIO); @@ -138,12 +129,12 @@ siba_erom_probe_common(struct siba_erom_io *io, const struct bhnd_chipid *hint, *cid = *hint; } else { /* Validate bus type */ - idreg = siba_eio_read_4(io, 0, CHIPC_ID); + idreg = siba_eio_read_4(&io, 0, CHIPC_ID); if (CHIPC_GET_BITS(idreg, CHIPC_ID_BUS) != BHND_CHIPTYPE_SIBA) return (ENXIO); /* Identify the chipset */ - if ((error = siba_eio_read_chipid(io, SIBA_ENUM_ADDR, cid))) + if ((error = siba_eio_read_chipid(&io, SIBA_ENUM_ADDR, cid))) return (error); /* Verify the chip type */ @@ -164,77 +155,27 @@ siba_erom_probe_common(struct siba_erom_io *io, const struct bhnd_chipid *hint, return (0); } -/* SIBA implementation of BHND_EROM_PROBE() */ -static int -siba_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res, - bus_size_t offset, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) -{ - struct siba_erom_io io; - int error, rid; - - rid = rman_get_rid(res->res); - - /* Initialize I/O context, assuming at least 1 core exists. */ - if ((error = siba_eio_init(&io, NULL, res, rid, offset, 1))) - return (error); - - return (siba_erom_probe_common(&io, hint, cid)); -} - -/* SIBA implementation of BHND_EROM_PROBE_STATIC() */ -static int -siba_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst, - bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint, - struct bhnd_chipid *cid) -{ - struct siba_erom_io io; - int error; - - /* Initialize I/O context, assuming at least 1 core exists. */ - if ((error = siba_eio_init_static(&io, bst, bsh, 0, 1))) - return (error); - - return (siba_erom_probe_common(&io, hint, cid)); -} - /* SIBA implementation of BHND_EROM_INIT() */ static int siba_erom_init(bhnd_erom_t *erom, const struct bhnd_chipid *cid, - device_t parent, int rid) + struct bhnd_erom_io *eio) { struct siba_erom *sc; - struct bhnd_resource *res; int error; - + sc = (struct siba_erom *)erom; - /* Allocate backing resource */ - res = bhnd_alloc_resource(parent, SYS_RES_MEMORY, &rid, - cid->enum_addr, cid->enum_addr + SIBA_ENUM_SIZE -1, SIBA_ENUM_SIZE, - RF_ACTIVE|RF_SHAREABLE); - if (res == NULL) - return (ENOMEM); + /* Attempt to map the full core enumeration space */ + error = bhnd_erom_io_map(eio, cid->enum_addr, + cid->ncores * SIBA_CORE_SIZE); + if (error) { + printf("%s: failed to map %u cores: %d\n", __FUNCTION__, + cid->ncores, error); + return (error); + } /* Initialize I/O context */ - error = siba_eio_init(&sc->io, parent, res, rid, 0x0, cid->ncores); - if (error) - bhnd_release_resource(parent, SYS_RES_MEMORY, rid, res); - - return (error); -} - -/* SIBA implementation of BHND_EROM_INIT_STATIC() */ -static int -siba_erom_init_static(bhnd_erom_t *erom, const struct bhnd_chipid *cid, - bus_space_tag_t bst, bus_space_handle_t bsh) -{ - struct siba_erom *sc; - - sc = (struct siba_erom *)erom; - - /* Initialize I/O context */ - return (siba_eio_init_static(&sc->io, bst, bsh, 0x0, cid->ncores)); + return (siba_eio_init(&sc->io, eio, cid->ncores)); } /* SIBA implementation of BHND_EROM_FINI() */ @@ -243,41 +184,15 @@ siba_erom_fini(bhnd_erom_t *erom) { struct siba_erom *sc = (struct siba_erom *)erom; - if (sc->io.res != NULL) { - bhnd_release_resource(sc->io.dev, SYS_RES_MEMORY, sc->io.rid, - sc->io.res); - - sc->io.res = NULL; - sc->io.rid = -1; - } + bhnd_erom_io_fini(sc->io.eio); } /* Initialize siba_erom resource I/O context */ static int -siba_eio_init(struct siba_erom_io *io, device_t parent, - struct bhnd_resource *res, int rid, bus_size_t offset, u_int ncores) +siba_eio_init(struct siba_erom_io *io, struct bhnd_erom_io *eio, u_int ncores) { - io->dev = parent; - io->res = res; - io->rid = rid; - io->offset = offset; + io->eio = eio; io->ncores = ncores; - - return (0); -} - -/* Initialize siba_erom bus space I/O context */ -static int -siba_eio_init_static(struct siba_erom_io *io, bus_space_tag_t bst, - bus_space_handle_t bsh, bus_size_t offset, u_int ncores) -{ - io->res = NULL; - io->rid = -1; - io->bst = bst; - io->bsh = bsh; - io->offset = offset; - io->ncores = ncores; - return (0); } @@ -292,8 +207,6 @@ siba_eio_init_static(struct siba_erom_io *io, bus_space_tag_t bst, static uint32_t siba_eio_read_4(struct siba_erom_io *io, u_int core_idx, bus_size_t offset) { - bus_size_t core_offset; - /* Sanity check core index and offset */ if (core_idx >= io->ncores) panic("core index %u out of range (ncores=%u)", core_idx, @@ -303,11 +216,8 @@ siba_eio_read_4(struct siba_erom_io *io, u_int core_idx, bus_size_t offset) panic("invalid core offset %#jx", (uintmax_t)offset); /* Perform read */ - core_offset = io->offset + SIBA_CORE_OFFSET(core_idx) + offset; - if (io->res != NULL) - return (bhnd_bus_read_4(io->res, core_offset)); - else - return (bus_space_read_4(io->bst, io->bsh, core_offset)); + return (bhnd_erom_io_read(io->eio, SIBA_CORE_OFFSET(core_idx) + offset, + 4)); } /** @@ -393,7 +303,7 @@ siba_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc, /* Re-scan preceding cores to determine the unit number. */ for (u_int j = 0; j < i; j++) { - sid = siba_eio_read_core_id(&sc->io, i, 0); + sid = siba_eio_read_core_id(&sc->io, j, 0); /* Bump the unit number? */ if (sid.core_info.vendor == ci.vendor && @@ -580,9 +490,7 @@ siba_erom_dump(bhnd_erom_t *erom) static kobj_method_t siba_erom_methods[] = { KOBJMETHOD(bhnd_erom_probe, siba_erom_probe), - KOBJMETHOD(bhnd_erom_probe_static, siba_erom_probe_static), KOBJMETHOD(bhnd_erom_init, siba_erom_init), - KOBJMETHOD(bhnd_erom_init_static, siba_erom_init_static), KOBJMETHOD(bhnd_erom_fini, siba_erom_fini), KOBJMETHOD(bhnd_erom_get_core_table, siba_erom_get_core_table), KOBJMETHOD(bhnd_erom_free_core_table, siba_erom_free_core_table), diff --git a/sys/dev/bnxt/bnxt.h b/sys/dev/bnxt/bnxt.h index 81cb2e512e31..834ab82279c4 100644 --- a/sys/dev/bnxt/bnxt.h +++ b/sys/dev/bnxt/bnxt.h @@ -102,7 +102,8 @@ __FBSDID("$FreeBSD$"); #define BNXT_GET_RSS_PROFILE_ID(rss_hash_type) ((rss_hash_type >> 1) & 0x1F) #define BNXT_NO_MORE_WOL_FILTERS 0xFFFF -#define bnxt_wol_supported(softc) ((softc)->flags & BNXT_FLAG_WOL_CAP) +#define bnxt_wol_supported(softc) (!((softc)->flags & BNXT_FLAG_VF) && \ + ((softc)->flags & BNXT_FLAG_WOL_CAP )) /* Completion related defines */ #define CMP_VALID(cmp, v_bit) \ @@ -210,6 +211,10 @@ __FBSDID("$FreeBSD$"); #define BNXT_HWRM_LOCK_DESTROY(_softc) mtx_destroy(&(_softc)->hwrm_lock) #define BNXT_HWRM_LOCK_ASSERT(_softc) mtx_assert(&(_softc)->hwrm_lock, \ MA_OWNED) +#define BNXT_IS_FLOW_CTRL_CHANGED(link_info) \ + ((link_info->last_flow_ctrl.tx != link_info->flow_ctrl.tx) || \ + (link_info->last_flow_ctrl.rx != link_info->flow_ctrl.rx) || \ + (link_info->last_flow_ctrl.autoneg != link_info->flow_ctrl.autoneg)) /* Chip info */ #define BNXT_TSO_SIZE UINT16_MAX @@ -226,6 +231,11 @@ __FBSDID("$FreeBSD$"); #define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max) +#define BNXT_IFMEDIA_ADD(supported, fw_speed, ifm_speed) do { \ + if ((supported) & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_ ## fw_speed) \ + ifmedia_add(softc->media, IFM_ETHER | (ifm_speed), 0, NULL); \ +} while(0) + /* NVRAM access */ enum bnxt_nvm_directory_type { BNX_DIR_TYPE_UNUSED = 0, @@ -287,6 +297,12 @@ struct bnxt_bar_info { int rid; }; +struct bnxt_flow_ctrl { + bool rx; + bool tx; + bool autoneg; +}; + struct bnxt_link_info { uint8_t media_type; uint8_t transceiver; @@ -298,10 +314,8 @@ struct bnxt_link_info { uint8_t last_link_up; uint8_t duplex; uint8_t last_duplex; - uint8_t pause; - uint8_t last_pause; - uint8_t auto_pause; - uint8_t force_pause; + struct bnxt_flow_ctrl flow_ctrl; + struct bnxt_flow_ctrl last_flow_ctrl; uint8_t duplex_setting; uint8_t auto_mode; #define PHY_VER_LEN 3 @@ -319,7 +333,6 @@ struct bnxt_link_info { #define BNXT_AUTONEG_SPEED 1 #define BNXT_AUTONEG_FLOW_CTRL 2 uint8_t req_duplex; - uint8_t req_flow_ctrl; uint16_t req_link_speed; }; @@ -393,7 +406,6 @@ struct bnxt_vf_info { bus_addr_t hwrm_cmd_req_dma_addr; }; -#define BNXT_FLAG_VF (1<<1) #define BNXT_PF(softc) (!((softc)->flags & BNXT_FLAG_VF)) #define BNXT_VF(softc) ((softc)->flags & BNXT_FLAG_VF) @@ -526,6 +538,14 @@ struct bnxt_func_qcfg { uint16_t alloc_vnics; }; +struct bnxt_hw_lro { + uint16_t enable; + uint16_t is_mode_gro; + uint16_t max_agg_segs; + uint16_t max_aggs; + uint32_t min_agg_len; +}; + struct bnxt_softc { device_t dev; if_ctx_t ctx; @@ -536,8 +556,9 @@ struct bnxt_softc { struct bnxt_bar_info hwrm_bar; struct bnxt_bar_info doorbell_bar; struct bnxt_link_info link_info; -#define BNXT_FLAG_NPAR 0x1 -#define BNXT_FLAG_WOL_CAP 0x2 +#define BNXT_FLAG_VF 0x0001 +#define BNXT_FLAG_NPAR 0x0002 +#define BNXT_FLAG_WOL_CAP 0x0004 uint32_t flags; uint32_t total_msix; @@ -585,10 +606,15 @@ struct bnxt_softc { struct sysctl_ctx_list hw_stats; struct sysctl_oid *hw_stats_oid; + struct sysctl_ctx_list hw_lro_ctx; + struct sysctl_oid *hw_lro_oid; + struct sysctl_ctx_list flow_ctrl_ctx; + struct sysctl_oid *flow_ctrl_oid; struct bnxt_ver_info *ver_info; struct bnxt_nvram_info *nvm_info; bool wol; + struct bnxt_hw_lro hw_lro; uint8_t wol_filter_id; uint16_t rx_coal_usecs; uint16_t rx_coal_usecs_irq; diff --git a/sys/dev/bnxt/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_hwrm.c index fa1f17877428..e25d2cb02130 100644 --- a/sys/dev/bnxt/bnxt_hwrm.c +++ b/sys/dev/bnxt/bnxt_hwrm.c @@ -503,33 +503,28 @@ static void bnxt_hwrm_set_pause_common(struct bnxt_softc *softc, struct hwrm_port_phy_cfg_input *req) { - if (softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL) { + struct bnxt_link_info *link_info = &softc->link_info; + + if (link_info->flow_ctrl.autoneg) { req->auto_pause = HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE; - if (softc->link_info.req_flow_ctrl & - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) + if (link_info->flow_ctrl.rx) req->auto_pause |= HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; - if (softc->link_info.req_flow_ctrl & - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) + if (link_info->flow_ctrl.tx) req->auto_pause |= - HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; + HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; req->enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE); } else { - if (softc->link_info.req_flow_ctrl & - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) + if (link_info->flow_ctrl.rx) req->force_pause |= HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; - if (softc->link_info.req_flow_ctrl & - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) + if (link_info->flow_ctrl.tx) req->force_pause |= HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; req->enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE); - req->auto_pause = req->force_pause; - req->enables |= htole32( - HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE); } } @@ -563,26 +558,7 @@ bnxt_hwrm_set_eee(struct bnxt_softc *softc, struct hwrm_port_phy_cfg_input *req) int bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause, - bool set_eee) -{ - struct hwrm_port_phy_cfg_input req = {0}; - - if (softc->flags & BNXT_FLAG_NPAR) - return ENOTSUP; - - bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG); - if (set_pause) - bnxt_hwrm_set_pause_common(softc, &req); - - bnxt_hwrm_set_link_common(softc, &req); - if (set_eee) - bnxt_hwrm_set_eee(softc, &req); - return hwrm_send_message(softc, &req, sizeof(req)); -} - - -int -bnxt_hwrm_set_pause(struct bnxt_softc *softc) + bool set_eee, bool set_link) { struct hwrm_port_phy_cfg_input req = {0}; int rc; @@ -591,21 +567,32 @@ bnxt_hwrm_set_pause(struct bnxt_softc *softc) return ENOTSUP; bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG); - bnxt_hwrm_set_pause_common(softc, &req); + + if (set_pause) { + bnxt_hwrm_set_pause_common(softc, &req); - if (softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL) + if (softc->link_info.flow_ctrl.autoneg) + set_link = true; + } + + if (set_link) bnxt_hwrm_set_link_common(softc, &req); - + + if (set_eee) + bnxt_hwrm_set_eee(softc, &req); + BNXT_HWRM_LOCK(softc); rc = _hwrm_send_message(softc, &req, sizeof(req)); - if (!rc && !(softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL)) { - /* since changing of pause setting doesn't trigger any link - * change event, the driver needs to update the current pause - * result upon successfully return of the phy_cfg command */ - softc->link_info.pause = - softc->link_info.force_pause = softc->link_info.req_flow_ctrl; - softc->link_info.auto_pause = 0; - bnxt_report_link(softc); + + if (!rc) { + if (set_pause) { + /* since changing of 'force pause' setting doesn't + * trigger any link change event, the driver needs to + * update the current pause result upon successfully i + * return of the phy_cfg command */ + if (!softc->link_info.flow_ctrl.autoneg) + bnxt_report_link(softc); + } } BNXT_HWRM_UNLOCK(softc); return rc; @@ -949,43 +936,81 @@ bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic, } int -bnxt_hwrm_func_cfg(struct bnxt_softc *softc) +bnxt_cfg_async_cr(struct bnxt_softc *softc) { - struct hwrm_func_cfg_input req = {0}; + int rc = 0; + + if (BNXT_PF(softc)) { + struct hwrm_func_cfg_input req = {0}; - bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG); + bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG); - req.fid = 0xffff; - req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR); + req.fid = 0xffff; + req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR); + req.async_event_cr = softc->def_cp_ring.ring.phys_id; - req.async_event_cr = softc->def_cp_ring.ring.phys_id; + rc = hwrm_send_message(softc, &req, sizeof(req)); + } + else { + struct hwrm_func_vf_cfg_input req = {0}; - return hwrm_send_message(softc, &req, sizeof(req)); + bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_VF_CFG); + + req.enables = htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR); + req.async_event_cr = softc->def_cp_ring.ring.phys_id; + + rc = hwrm_send_message(softc, &req, sizeof(req)); + } + return rc; +} + +void +bnxt_validate_hw_lro_settings(struct bnxt_softc *softc) +{ + softc->hw_lro.enable = min(softc->hw_lro.enable, 1); + + softc->hw_lro.is_mode_gro = min(softc->hw_lro.is_mode_gro, 1); + + softc->hw_lro.max_agg_segs = min(softc->hw_lro.max_agg_segs, + HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX); + + softc->hw_lro.max_aggs = min(softc->hw_lro.max_aggs, + HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX); + + softc->hw_lro.min_agg_len = min(softc->hw_lro.min_agg_len, BNXT_MAX_MTU); } int -bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic, - uint32_t flags) +bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc) { struct hwrm_vnic_tpa_cfg_input req = {0}; + uint32_t flags; bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_TPA_CFG); - req.flags = htole32(flags); - req.vnic_id = htole16(vnic->id); - req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS | - HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS | - /* HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER | */ - HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN); - /* TODO: Calculate this based on ring size? */ - req.max_agg_segs = htole16(3); - /* Base this in the allocated TPA start size... */ - req.max_aggs = htole16(7); - /* - * TODO: max_agg_timer? - * req.mag_agg_timer = htole32(XXX); - */ - req.min_agg_len = htole32(0); + if (softc->hw_lro.enable) { + flags = HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA | + HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA | + HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN | + HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ; + + if (softc->hw_lro.is_mode_gro) + flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO; + else + flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE; + + req.flags = htole32(flags); + + req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS | + HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS | + HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN); + + req.max_agg_segs = htole16(softc->hw_lro.max_agg_segs); + req.max_aggs = htole16(softc->hw_lro.max_aggs); + req.min_agg_len = htole32(softc->hw_lro.min_agg_len); + } + + req.vnic_id = htole16(softc->vnic_info.id); return hwrm_send_message(softc, &req, sizeof(req)); } @@ -1498,10 +1523,43 @@ bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc) link_info->phy_link_status = resp->link; link_info->duplex = resp->duplex_cfg; - link_info->pause = resp->pause; link_info->auto_mode = resp->auto_mode; - link_info->auto_pause = resp->auto_pause; - link_info->force_pause = resp->force_pause; + + /* + * When AUTO_PAUSE_AUTONEG_PAUSE bit is set to 1, + * the advertisement of pause is enabled. + * 1. When the auto_mode is not set to none and this flag is set to 1, + * then the auto_pause bits on this port are being advertised and + * autoneg pause results are being interpreted. + * 2. When the auto_mode is not set to none and this flag is set to 0, + * the pause is forced as indicated in force_pause, and also + * advertised as auto_pause bits, but the autoneg results are not + * interpreted since the pause configuration is being forced. + * 3. When the auto_mode is set to none and this flag is set to 1, + * auto_pause bits should be ignored and should be set to 0. + */ + + link_info->flow_ctrl.autoneg = false; + link_info->flow_ctrl.tx = false; + link_info->flow_ctrl.rx = false; + + if ((resp->auto_mode) && + (resp->auto_pause & BNXT_AUTO_PAUSE_AUTONEG_PAUSE)) { + link_info->flow_ctrl.autoneg = true; + } + + if (link_info->flow_ctrl.autoneg) { + if (resp->auto_pause & BNXT_PAUSE_TX) + link_info->flow_ctrl.tx = true; + if (resp->auto_pause & BNXT_PAUSE_RX) + link_info->flow_ctrl.rx = true; + } else { + if (resp->force_pause & BNXT_PAUSE_TX) + link_info->flow_ctrl.tx = true; + if (resp->force_pause & BNXT_PAUSE_RX) + link_info->flow_ctrl.rx = true; + } + link_info->duplex_setting = resp->duplex_cfg; if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) link_info->link_speed = le16toh(resp->link_speed); @@ -1719,4 +1777,3 @@ int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bm return hwrm_send_message(softc, &req, sizeof(req)); } - diff --git a/sys/dev/bnxt/bnxt_hwrm.h b/sys/dev/bnxt/bnxt_hwrm.h index f1c56c44f636..28f3c08f6083 100644 --- a/sys/dev/bnxt/bnxt_hwrm.h +++ b/sys/dev/bnxt/bnxt_hwrm.h @@ -32,6 +32,11 @@ __FBSDID("$FreeBSD$"); #ifndef _BNXT_HWRM_H #define _BNXT_HWRM_H +#define BNXT_PAUSE_TX (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) +#define BNXT_PAUSE_RX (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) +#define BNXT_AUTO_PAUSE_AUTONEG_PAUSE \ + (HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE) + /* HWRM Function Prototypes */ int bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc); void bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc); @@ -45,8 +50,8 @@ int bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool shutdown); int bnxt_hwrm_func_qcaps(struct bnxt_softc *softc); int bnxt_hwrm_func_qcfg(struct bnxt_softc *softc); int bnxt_hwrm_func_reset(struct bnxt_softc *softc); -int bnxt_hwrm_set_link_setting(struct bnxt_softc *, bool set_pause, - bool set_eee); +int bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause, + bool set_eee, bool set_link); int bnxt_hwrm_set_pause(struct bnxt_softc *softc); int bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id); int bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic); @@ -61,9 +66,9 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc, int bnxt_hwrm_set_filter(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic); int bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic, uint32_t hash_type); -int bnxt_hwrm_func_cfg(struct bnxt_softc *softc); -int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc, - struct bnxt_vnic_info *vnic, uint32_t flags); +int bnxt_cfg_async_cr(struct bnxt_softc *softc); +int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc); +void bnxt_validate_hw_lro_settings(struct bnxt_softc *softc); int bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type, uint16_t *ordinal, uint16_t ext, uint16_t *index, bool use_index, uint8_t search_opt, uint32_t *data_length, uint32_t *item_length, diff --git a/sys/dev/bnxt/bnxt_sysctl.c b/sys/dev/bnxt/bnxt_sysctl.c index fa423c5b31ea..39d184e68aa8 100644 --- a/sys/dev/bnxt/bnxt_sysctl.c +++ b/sys/dev/bnxt/bnxt_sysctl.c @@ -84,6 +84,26 @@ bnxt_init_sysctl_ctx(struct bnxt_softc *softc) return ENOMEM; } + sysctl_ctx_init(&softc->hw_lro_ctx); + ctx = device_get_sysctl_ctx(softc->dev); + softc->hw_lro_oid = SYSCTL_ADD_NODE(ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO, + "hw_lro", CTLFLAG_RD, 0, "hardware lro"); + if (!softc->hw_lro_oid) { + sysctl_ctx_free(&softc->hw_lro_ctx); + return ENOMEM; + } + + sysctl_ctx_init(&softc->flow_ctrl_ctx); + ctx = device_get_sysctl_ctx(softc->dev); + softc->flow_ctrl_oid = SYSCTL_ADD_NODE(ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO, + "fc", CTLFLAG_RD, 0, "flow ctrl"); + if (!softc->flow_ctrl_oid) { + sysctl_ctx_free(&softc->flow_ctrl_ctx); + return ENOMEM; + } + return 0; } @@ -114,6 +134,21 @@ bnxt_free_sysctl_ctx(struct bnxt_softc *softc) else softc->nvm_info->nvm_oid = NULL; } + if (softc->hw_lro_oid != NULL) { + orc = sysctl_ctx_free(&softc->hw_lro_ctx); + if (orc) + rc = orc; + else + softc->hw_lro_oid = NULL; + } + + if (softc->flow_ctrl_oid != NULL) { + orc = sysctl_ctx_free(&softc->flow_ctrl_ctx); + if (orc) + rc = orc; + else + softc->flow_ctrl_oid = NULL; + } return rc; } @@ -1210,6 +1245,130 @@ bnxt_create_config_sysctls_pre(struct bnxt_softc *softc) return 0; } +#define BNXT_HW_LRO_FN(fn_name, arg) \ +static int \ +fn_name(SYSCTL_HANDLER_ARGS) { \ + struct bnxt_softc *softc = arg1; \ + int rc; \ + int val; \ + \ + if (softc == NULL) \ + return EBUSY; \ + \ + val = softc->hw_lro.arg; \ + rc = sysctl_handle_int(oidp, &val, 0, req); \ + if (rc || !req->newptr) \ + return rc; \ + \ + if ((if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)) \ + return EBUSY; \ + \ + softc->hw_lro.arg = val; \ + bnxt_validate_hw_lro_settings(softc); \ + rc = bnxt_hwrm_vnic_tpa_cfg(softc); \ + \ + return rc; \ +} + +BNXT_HW_LRO_FN(bnxt_hw_lro_enable_disable, enable) +BNXT_HW_LRO_FN(bnxt_hw_lro_set_mode, is_mode_gro) +BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_agg_segs, max_agg_segs) +BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_aggs, max_aggs) +BNXT_HW_LRO_FN(bnxt_hw_lro_set_min_agg_len, min_agg_len) + +#define BNXT_FLOW_CTRL_FN(fn_name, arg) \ +static int \ +fn_name(SYSCTL_HANDLER_ARGS) { \ + struct bnxt_softc *softc = arg1; \ + int rc; \ + int val; \ + \ + if (softc == NULL) \ + return EBUSY; \ + \ + val = softc->link_info.flow_ctrl.arg; \ + rc = sysctl_handle_int(oidp, &val, 0, req); \ + if (rc || !req->newptr) \ + return rc; \ + \ + if (val) \ + val = 1; \ + \ + if (softc->link_info.flow_ctrl.arg != val) { \ + softc->link_info.flow_ctrl.arg = val; \ + rc = bnxt_hwrm_set_link_setting(softc, true, false, false);\ + rc = bnxt_hwrm_port_phy_qcfg(softc); \ + } \ + \ + return rc; \ +} + +BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_tx, tx) +BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_rx, rx) +BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_autoneg, autoneg) +int +bnxt_create_pause_fc_sysctls(struct bnxt_softc *softc) +{ + struct sysctl_oid *oid = softc->flow_ctrl_oid; + + if (!oid) + return ENOMEM; + + SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "tx", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_flow_ctrl_tx, "A", + "Enable or Disable Tx Flow Ctrl: 0 / 1"); + + SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "rx", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_flow_ctrl_rx, "A", + "Enable or Disable Tx Flow Ctrl: 0 / 1"); + + SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "autoneg", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_flow_ctrl_autoneg, "A", + "Enable or Disable Autoneg Flow Ctrl: 0 / 1"); + + return 0; +} + +int +bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc) +{ + struct sysctl_oid *oid = softc->hw_lro_oid; + + if (!oid) + return ENOMEM; + + SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "enable", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_hw_lro_enable_disable, "A", + "Enable or Disable HW LRO: 0 / 1"); + + SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "gro_mode", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_hw_lro_set_mode, "A", + "Set mode: 1 = GRO mode, 0 = RSC mode"); + + SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "max_agg_segs", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_hw_lro_set_max_agg_segs, "A", + "Set Max Agg Seg Value (unit is Log2): " + "0 (= 1 seg) / 1 (= 2 segs) / ... / 31 (= 2^31 segs)"); + + SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "max_aggs", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_hw_lro_set_max_aggs, "A", + "Set Max Aggs Value (unit is Log2): " + "0 (= 1 agg) / 1 (= 2 aggs) / ... / 7 (= 2^7 segs)"); + + SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "min_agg_len", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, + bnxt_hw_lro_set_min_agg_len, "A", + "Min Agg Len: 1 to 9000"); + + return 0; +} static int bnxt_vlan_only_sysctl(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; diff --git a/sys/dev/bnxt/bnxt_sysctl.h b/sys/dev/bnxt/bnxt_sysctl.h index 31985d93b7c3..ac0dcae1fd29 100644 --- a/sys/dev/bnxt/bnxt_sysctl.h +++ b/sys/dev/bnxt/bnxt_sysctl.h @@ -40,3 +40,5 @@ int bnxt_create_ver_sysctls(struct bnxt_softc *softc); int bnxt_create_nvram_sysctls(struct bnxt_nvram_info *ni); int bnxt_create_config_sysctls_pre(struct bnxt_softc *softc); int bnxt_create_config_sysctls_post(struct bnxt_softc *softc); +int bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc); +int bnxt_create_pause_fc_sysctls(struct bnxt_softc *softc); diff --git a/sys/dev/bnxt/if_bnxt.c b/sys/dev/bnxt/if_bnxt.c index aaf18b04a120..c97e94e0a2d5 100644 --- a/sys/dev/bnxt/if_bnxt.c +++ b/sys/dev/bnxt/if_bnxt.c @@ -243,6 +243,8 @@ MODULE_DEPEND(bnxt, pci, 1, 1, 1); MODULE_DEPEND(bnxt, ether, 1, 1, 1); MODULE_DEPEND(bnxt, iflib, 1, 1, 1); +IFLIB_PNP_INFO(pci, bnxt, bnxt_vendor_info_array); + static device_method_t bnxt_iflib_methods[] = { DEVMETHOD(ifdi_tx_queues_alloc, bnxt_tx_queues_alloc), DEVMETHOD(ifdi_rx_queues_alloc, bnxt_rx_queues_alloc), @@ -657,7 +659,7 @@ bnxt_attach_pre(if_ctx_t ctx) scctx = softc->scctx; /* TODO: Better way of detecting NPAR/VF is needed */ - switch (softc->sctx->isc_vendor_info->pvi_device_id) { + switch (pci_get_device(softc->dev)) { case BCM57402_NPAR: case BCM57404_NPAR: case BCM57406_NPAR: @@ -826,6 +828,17 @@ bnxt_attach_pre(if_ctx_t ctx) /* iflib will map and release this bar */ scctx->isc_msix_bar = pci_msix_table_bar(softc->dev); + /* + * Default settings for HW LRO (TPA): + * Disable HW LRO by default + * Can be enabled after taking care of 'packet forwarding' + */ + softc->hw_lro.enable = 0; + softc->hw_lro.is_mode_gro = 0; + softc->hw_lro.max_agg_segs = 5; /* 2^5 = 32 segs */ + softc->hw_lro.max_aggs = HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX; + softc->hw_lro.min_agg_len = 512; + /* Allocate the default completion ring */ softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE; softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE; @@ -861,6 +874,14 @@ bnxt_attach_pre(if_ctx_t ctx) if (rc) goto failed; + rc = bnxt_create_hw_lro_sysctls(softc); + if (rc) + goto failed; + + rc = bnxt_create_pause_fc_sysctls(softc); + if (rc) + goto failed; + /* Initialize the vlan list */ SLIST_INIT(&softc->vnic_info.vlan_tags); softc->vnic_info.vlan_tag_list.idi_vaddr = NULL; @@ -980,7 +1001,7 @@ bnxt_init(if_ctx_t ctx) goto fail; /* And now set the default CP ring as the async CP ring */ - rc = bnxt_hwrm_func_cfg(softc); + rc = bnxt_cfg_async_cr(softc); if (rc) goto fail; @@ -1071,15 +1092,7 @@ bnxt_init(if_ctx_t ctx) if (rc) goto fail; - /* - * Enable LRO/TPA/GRO - * TBD: - * Enable / Disable HW_LRO based on - * ifconfig lro / ifconfig -lro setting - */ - rc = bnxt_hwrm_vnic_tpa_cfg(softc, &softc->vnic_info, - (if_getcapenable(iflib_get_ifp(ctx)) & IFCAP_LRO) ? - HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA : 0); + rc = bnxt_hwrm_vnic_tpa_cfg(softc); if (rc) goto fail; @@ -1116,6 +1129,7 @@ bnxt_init(if_ctx_t ctx) bnxt_do_enable_intr(&softc->def_cp_ring); bnxt_media_status(softc->ctx, &ifmr); + bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info); return; fail: @@ -1184,7 +1198,10 @@ bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr) { struct bnxt_softc *softc = iflib_get_softc(ctx); struct bnxt_link_info *link_info = &softc->link_info; - uint8_t phy_type = get_phy_type(softc); + struct ifmedia_entry *next; + uint64_t target_baudrate = bnxt_get_baudrate(link_info); + int active_media = IFM_UNKNOWN; + bnxt_update_link(softc, true); @@ -1201,179 +1218,22 @@ bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr) else ifmr->ifm_active |= IFM_HDX; - switch (link_info->link_speed) { - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB: - ifmr->ifm_active |= IFM_100_T; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: - ifmr->ifm_active |= IFM_1000_KX; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: - ifmr->ifm_active |= IFM_1000_T; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY: - ifmr->ifm_active |= IFM_1000_SGMII; - break; - default: - /* - * Workaround: - * Don't return IFM_UNKNOWN until - * Stratus return proper media_type - */ - ifmr->ifm_active |= IFM_1000_KX; + /* + * Go through the list of supported media which got prepared + * as part of bnxt_add_media_types() using api ifmedia_add(). + */ + LIST_FOREACH(next, &(iflib_get_media(ctx)->ifm_list), ifm_list) { + if (ifmedia_baudrate(next->ifm_media) == target_baudrate) { + active_media = next->ifm_media; break; } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: - ifmr->ifm_active |= IFM_2500_KX; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: - ifmr->ifm_active |= IFM_2500_T; - break; - default: - ifmr->ifm_active |= IFM_UNKNOWN; - break; - } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - ifmr->ifm_active |= IFM_10G_CR1; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - ifmr->ifm_active |= IFM_10G_KR; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: - ifmr->ifm_active |= IFM_10G_LR; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: - ifmr->ifm_active |= IFM_10G_SR; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: - ifmr->ifm_active |= IFM_10G_KX4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: - ifmr->ifm_active |= IFM_10G_T; - break; - default: - /* - * Workaround: - * Don't return IFM_UNKNOWN until - * Stratus return proper media_type - */ - ifmr->ifm_active |= IFM_10G_CR1; - break; - } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB: - ifmr->ifm_active |= IFM_20G_KR2; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - ifmr->ifm_active |= IFM_25G_CR; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - ifmr->ifm_active |= IFM_25G_KR; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: - ifmr->ifm_active |= IFM_25G_SR; - break; - default: - /* - * Workaround: - * Don't return IFM_UNKNOWN until - * Stratus return proper media_type - */ - ifmr->ifm_active |= IFM_25G_CR; - break; - } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - ifmr->ifm_active |= IFM_40G_CR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - ifmr->ifm_active |= IFM_40G_KR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: - ifmr->ifm_active |= IFM_40G_LR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: - ifmr->ifm_active |= IFM_40G_SR4; - break; - default: - ifmr->ifm_active |= IFM_UNKNOWN; - break; - } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - ifmr->ifm_active |= IFM_50G_CR2; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - ifmr->ifm_active |= IFM_50G_KR2; - break; - default: - /* - * Workaround: - * Don't return IFM_UNKNOWN until - * Stratus return proper media_type - */ - ifmr->ifm_active |= IFM_50G_CR2; - break; - } - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB: - switch (phy_type) { - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - ifmr->ifm_active |= IFM_100G_CR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - ifmr->ifm_active |= IFM_100G_KR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: - ifmr->ifm_active |= IFM_100G_LR4; - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: - ifmr->ifm_active |= IFM_100G_SR4; - break; - default: - /* - * Workaround: - * Don't return IFM_UNKNOWN until - * Stratus return proper media_type - */ - ifmr->ifm_active |= IFM_100G_CR4; - break; - } - default: - return; } + ifmr->ifm_active |= active_media; - if (link_info->pause == (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) - ifmr->ifm_active |= (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE); - else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) - ifmr->ifm_active |= IFM_ETH_TXPAUSE; - else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) + if (link_info->flow_ctrl.rx) ifmr->ifm_active |= IFM_ETH_RXPAUSE; + if (link_info->flow_ctrl.tx) + ifmr->ifm_active |= IFM_ETH_TXPAUSE; bnxt_report_link(softc); return; @@ -1461,7 +1321,7 @@ bnxt_media_change(if_ctx_t ctx) softc->link_info.autoneg |= BNXT_AUTONEG_SPEED; break; } - rc = bnxt_hwrm_set_link_setting(softc, true, true); + rc = bnxt_hwrm_set_link_setting(softc, true, true, true); bnxt_media_status(softc->ctx, &ifmr); return rc; } @@ -1640,9 +1500,7 @@ bnxt_msix_intr_assign(if_ctx_t ctx, int msix) } for (i=0; iscctx->isc_ntxqsets; i++) - /* TODO: Benchmark and see if tying to the RX irqs helps */ - iflib_softirq_alloc_generic(ctx, -1, IFLIB_INTR_TX, NULL, i, - "tx_cp"); + iflib_softirq_alloc_generic(ctx, NULL, IFLIB_INTR_TX, NULL, i, "tx_cp"); return rc; @@ -2088,18 +1946,6 @@ bnxt_probe_phy(struct bnxt_softc *softc) if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE) link_info->autoneg |= BNXT_AUTONEG_SPEED; - if (link_info->auto_pause & (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) { - if (link_info->auto_pause == ( - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) - link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; - link_info->req_flow_ctrl = link_info->auto_pause; - } else if (link_info->force_pause & ( - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) { - link_info->req_flow_ctrl = link_info->force_pause; - } link_info->req_duplex = link_info->duplex_setting; if (link_info->autoneg & BNXT_AUTONEG_SPEED) link_info->req_link_speed = link_info->auto_link_speed; @@ -2124,129 +1970,89 @@ bnxt_add_media_types(struct bnxt_softc *softc) return; switch (phy_type) { + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N: case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_100G_CR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_50G_CR2, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_40G_CR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_25G_CR, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_CR1, 0, - NULL); + BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_CR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_CR2); + BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_CR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_CR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_CR1); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_T); break; + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: + BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_LR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_LR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_LR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_LR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_LX); + break; + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR: + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASESX: + BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_SR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_SR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_SR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_SR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_SX); + break; + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_100G_KR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_50G_KR2, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_40G_KR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_25G_KR, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_20G_KR2, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_KR, 0, - NULL); + BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_KR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_KR2); + BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_KR4); + BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_KR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_20GB, IFM_20G_KR2); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_KR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_KX); break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_100G_LR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_40G_LR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_LR, 0, - NULL); + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE: + BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_ACC); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_AOC); break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_100G_SR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_40G_SR4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_25G_SR, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_SR, 0, - NULL); - break; - case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_KX4, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_2500_KX, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_1000_KX, 0, - NULL); + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASECX: + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GBHD, IFM_1000_CX); break; + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET: case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10_T, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB) - ifmedia_add(softc->media, IFM_ETHER | IFM_100_T, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_1000_T, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_2500_T, 0, - NULL); - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_T, 0, - NULL); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_T); + BNXT_IFMEDIA_ADD(supported, SPEEDS_2_5GB, IFM_2500_T); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_T); + BNXT_IFMEDIA_ADD(supported, SPEEDS_100MB, IFM_100_T); + BNXT_IFMEDIA_ADD(supported, SPEEDS_10MB, IFM_10_T); break; + + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: + BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_KR); + BNXT_IFMEDIA_ADD(supported, SPEEDS_2_5GB, IFM_2500_KX); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_KX); + break; + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY: - if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) - ifmedia_add(softc->media, IFM_ETHER | IFM_1000_SGMII, 0, - NULL); + BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_SGMII); break; + case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN: default: - /* - * Workaround for Cumulus & Stratus - * For Stratus: - * media_type is being returned as 0x0 - * Return support speeds as 10G, 25G, 50G & 100G - * - * For Cumulus: - * phy_type is being returned as 0x14 (PHY_TYPE_40G_BASECR4) - * Return support speeds as 1G, 10G, 25G & 50G - */ - if (pci_get_device(softc->dev) == BCM57454) { - /* For Stratus: 10G, 25G, 50G & 100G */ - ifmedia_add(softc->media, IFM_ETHER | IFM_100G_CR4, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_50G_CR2, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_25G_CR, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_CR1, 0, NULL); - } else if (pci_get_device(softc->dev) == BCM57414) { - /* For Cumulus: 1G, 10G, 25G & 50G */ - ifmedia_add(softc->media, IFM_ETHER | IFM_50G_CR2, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_25G_CR, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_10G_CR1, 0, NULL); - ifmedia_add(softc->media, IFM_ETHER | IFM_1000_T, 0, NULL); - } + /* Only Autoneg is supported for TYPE_UNKNOWN */ break; } @@ -2344,47 +2150,46 @@ bnxt_update_link(struct bnxt_softc *softc, bool chng_link_state) void bnxt_report_link(struct bnxt_softc *softc) { + struct bnxt_link_info *link_info = &softc->link_info; const char *duplex = NULL, *flow_ctrl = NULL; - if (softc->link_info.link_up == softc->link_info.last_link_up) { - if (!softc->link_info.link_up) + if (link_info->link_up == link_info->last_link_up) { + if (!link_info->link_up) return; - if (softc->link_info.pause == softc->link_info.last_pause && - softc->link_info.duplex == softc->link_info.last_duplex) + if ((link_info->duplex == link_info->last_duplex) && + (!(BNXT_IS_FLOW_CTRL_CHANGED(link_info)))) return; } - if (softc->link_info.link_up) { - if (softc->link_info.duplex == + if (link_info->link_up) { + if (link_info->duplex == HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL) duplex = "full duplex"; else duplex = "half duplex"; - if (softc->link_info.pause == ( - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) + if (link_info->flow_ctrl.tx & link_info->flow_ctrl.rx) flow_ctrl = "FC - receive & transmit"; - else if (softc->link_info.pause == - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) + else if (link_info->flow_ctrl.tx) flow_ctrl = "FC - transmit"; - else if (softc->link_info.pause == - HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) + else if (link_info->flow_ctrl.rx) flow_ctrl = "FC - receive"; else flow_ctrl = "FC - none"; iflib_link_state_change(softc->ctx, LINK_STATE_UP, IF_Gbps(100)); device_printf(softc->dev, "Link is UP %s, %s - %d Mbps \n", duplex, - flow_ctrl, (softc->link_info.link_speed * 100)); + flow_ctrl, (link_info->link_speed * 100)); } else { iflib_link_state_change(softc->ctx, LINK_STATE_DOWN, bnxt_get_baudrate(&softc->link_info)); device_printf(softc->dev, "Link is Down\n"); } - softc->link_info.last_link_up = softc->link_info.link_up; - softc->link_info.last_pause = softc->link_info.pause; - softc->link_info.last_duplex = softc->link_info.duplex; + link_info->last_link_up = link_info->link_up; + link_info->last_duplex = link_info->duplex; + link_info->last_flow_ctrl.tx = link_info->flow_ctrl.tx; + link_info->last_flow_ctrl.rx = link_info->flow_ctrl.rx; + link_info->last_flow_ctrl.autoneg = link_info->flow_ctrl.autoneg; } static int diff --git a/sys/dev/cas/if_cas.c b/sys/dev/cas/if_cas.c index 554b245260f5..8b5d9659063d 100644 --- a/sys/dev/cas/if_cas.c +++ b/sys/dev/cas/if_cas.c @@ -133,7 +133,7 @@ static void cas_detach(struct cas_softc *sc); static int cas_disable_rx(struct cas_softc *sc); static int cas_disable_tx(struct cas_softc *sc); static void cas_eint(struct cas_softc *sc, u_int status); -static void cas_free(struct mbuf *m, void *arg1, void* arg2); +static void cas_free(struct mbuf *m); static void cas_init(void *xsc); static void cas_init_locked(struct cas_softc *sc); static void cas_init_regs(struct cas_softc *sc); @@ -1732,16 +1732,10 @@ cas_rint(struct cas_softc *sc) refcount_acquire(&rxds->rxds_refcount); bus_dmamap_sync(sc->sc_rdmatag, rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD); -#if __FreeBSD_version < 800016 - MEXTADD(m, (caddr_t)rxds->rxds_buf + - off * 256 + ETHER_ALIGN, len, cas_free, - rxds, M_RDONLY, EXT_NET_DRV); -#else - MEXTADD(m, (caddr_t)rxds->rxds_buf + + m_extadd(m, (char *)rxds->rxds_buf + off * 256 + ETHER_ALIGN, len, cas_free, sc, (void *)(uintptr_t)idx, M_RDONLY, EXT_NET_DRV); -#endif if ((m->m_flags & M_EXT) == 0) { m_freem(m); m = NULL; @@ -1779,16 +1773,10 @@ cas_rint(struct cas_softc *sc) m->m_len = min(CAS_PAGE_SIZE - off, len); bus_dmamap_sync(sc->sc_rdmatag, rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD); -#if __FreeBSD_version < 800016 - MEXTADD(m, (caddr_t)rxds->rxds_buf + off, - m->m_len, cas_free, rxds, M_RDONLY, - EXT_NET_DRV); -#else - MEXTADD(m, (caddr_t)rxds->rxds_buf + off, + m_extadd(m, (char *)rxds->rxds_buf + off, m->m_len, cas_free, sc, (void *)(uintptr_t)idx, M_RDONLY, EXT_NET_DRV); -#endif if ((m->m_flags & M_EXT) == 0) { m_freem(m); m = NULL; @@ -1818,19 +1806,11 @@ cas_rint(struct cas_softc *sc) sc->sc_rdmatag, rxds2->rxds_dmamap, BUS_DMASYNC_POSTREAD); -#if __FreeBSD_version < 800016 - MEXTADD(m2, - (caddr_t)rxds2->rxds_buf, - m2->m_len, cas_free, - rxds2, M_RDONLY, - EXT_NET_DRV); -#else - MEXTADD(m2, - (caddr_t)rxds2->rxds_buf, + m_extadd(m2, + (char *)rxds2->rxds_buf, m2->m_len, cas_free, sc, (void *)(uintptr_t)idx2, M_RDONLY, EXT_NET_DRV); -#endif if ((m2->m_flags & M_EXT) == 0) { m_freem(m2); @@ -1889,21 +1869,15 @@ cas_rint(struct cas_softc *sc) } static void -cas_free(struct mbuf *m, void *arg1, void *arg2) +cas_free(struct mbuf *m) { struct cas_rxdsoft *rxds; struct cas_softc *sc; u_int idx, locked; -#if __FreeBSD_version < 800016 - rxds = arg2; - sc = rxds->rxds_sc; - idx = rxds->rxds_idx; -#else - sc = arg1; - idx = (uintptr_t)arg2; + sc = m->m_ext.ext_arg1; + idx = (uintptr_t)m->m_ext.ext_arg2; rxds = &sc->sc_rxdsoft[idx]; -#endif if (refcount_release(&rxds->rxds_refcount) == 0) return; diff --git a/sys/dev/cas/if_casvar.h b/sys/dev/cas/if_casvar.h index 653572c8b201..e92f277003e8 100644 --- a/sys/dev/cas/if_casvar.h +++ b/sys/dev/cas/if_casvar.h @@ -119,10 +119,6 @@ struct cas_rxdsoft { void *rxds_buf; /* receive buffer */ bus_dmamap_t rxds_dmamap; /* our DMA map */ bus_addr_t rxds_paddr; /* physical address of the segment */ -#if __FreeBSD_version < 800016 - struct cas_softc *rxds_sc; /* softc pointer */ - u_int rxds_idx; /* our index */ -#endif u_int rxds_refcount; /* hardware + mbuf references */ }; @@ -239,18 +235,7 @@ do { \ __CAS_UPDATE_RXDESC(&(sc)->sc_rxdescs[(d)], \ &(sc)->sc_rxdsoft[(s)], (s)) -#if __FreeBSD_version < 800016 -#define CAS_INIT_RXDESC(sc, d, s) \ -do { \ - struct cas_rxdsoft *__rxds = &(sc)->sc_rxdsoft[(s)]; \ - \ - __rxds->rxds_sc = (sc); \ - __rxds->rxds_idx = (s); \ - __CAS_UPDATE_RXDESC(&(sc)->sc_rxdescs[(d)], __rxds, (s)); \ -} while (0) -#else #define CAS_INIT_RXDESC(sc, d, s) CAS_UPDATE_RXDESC(sc, d, s) -#endif #define CAS_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->sc_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index cff4c6d61faf..e4a14a339ff2 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -219,7 +219,9 @@ struct vi_info { int nnmrxq; int first_nm_rxq; int tmr_idx; + int ofld_tmr_idx; int pktc_idx; + int ofld_pktc_idx; int qsize_rxq; int qsize_txq; @@ -285,7 +287,8 @@ struct port_info { uint8_t mod_type; uint8_t port_id; uint8_t tx_chan; - uint8_t rx_chan_map; /* rx MPS channel bitmap */ + uint8_t mps_bg_map; /* rx MPS buffer group bitmap */ + uint8_t rx_e_chan_map; /* rx TP e-channel bitmap */ struct link_config link_cfg; struct link_config old_link_cfg; @@ -794,7 +797,7 @@ struct adapter { struct taskqueue *tq[MAX_NCHAN]; /* General purpose taskqueues */ struct port_info *port[MAX_NPORTS]; - uint8_t chan_map[MAX_NCHAN]; + uint8_t chan_map[MAX_NCHAN]; /* channel -> port */ void *tom_softc; /* (struct tom_data *) */ struct tom_tunables tt; diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index c4a3ef249e46..c34f57ad9c18 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -369,6 +369,8 @@ struct adapter_params { unsigned int max_ordird_qp; unsigned int max_ird_adapter; + + uint32_t mps_bg_map; /* rx buffer group map for all ports (upto 4) */ }; #define CHELSIO_T4 0x4 diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 8ae7e5bbfa84..bb7491af4c91 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -5894,6 +5894,24 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) * port. */ static unsigned int t4_get_mps_bg_map(struct adapter *adap, int idx) +{ + u32 n; + + if (adap->params.mps_bg_map) + return ((adap->params.mps_bg_map >> (idx << 3)) & 0xff); + + n = G_NUMPORTS(t4_read_reg(adap, A_MPS_CMN_CTL)); + if (n == 0) + return idx == 0 ? 0xf : 0; + if (n == 1 && chip_id(adap) <= CHELSIO_T5) + return idx < 2 ? (3 << (2 * idx)) : 0; + return 1 << idx; +} + +/* + * TP RX e-channels associated with the port. + */ +static unsigned int t4_get_rx_e_chan_map(struct adapter *adap, int idx) { u32 n = G_NUMPORTS(t4_read_reg(adap, A_MPS_CMN_CTL)); @@ -5972,7 +5990,7 @@ void t4_get_port_stats_offset(struct adapter *adap, int idx, */ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) { - u32 bgmap = t4_get_mps_bg_map(adap, idx); + u32 bgmap = adap2pinfo(adap, idx)->mps_bg_map; u32 stat_ctl = t4_read_reg(adap, A_MPS_STAT_CTL); #define GET_STAT(name) \ @@ -6074,7 +6092,7 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) */ void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p) { - u32 bgmap = t4_get_mps_bg_map(adap, idx); + u32 bgmap = adap2pinfo(adap, idx)->mps_bg_map; #define GET_STAT(name) \ t4_read_reg64(adap, \ @@ -8379,7 +8397,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) else p->vi[0].smt_idx = (ret & 0x7f); p->tx_chan = j; - p->rx_chan_map = t4_get_mps_bg_map(adap, j); + p->mps_bg_map = t4_get_mps_bg_map(adap, j); + p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); p->lport = j; p->vi[0].rss_size = rss_size; t4_os_set_hw_addr(p, addr); @@ -9374,7 +9393,7 @@ int t4_set_filter_mode(struct adapter *adap, unsigned int mode_map, void t4_clr_port_stats(struct adapter *adap, int idx) { unsigned int i; - u32 bgmap = t4_get_mps_bg_map(adap, idx); + u32 bgmap = adap2pinfo(adap, idx)->mps_bg_map; u32 port_base_addr; if (is_t4(adap)) diff --git a/sys/dev/cxgbe/crypto/t4_crypto.c b/sys/dev/cxgbe/crypto/t4_crypto.c index eb341f9720e2..0a1041111ded 100644 --- a/sys/dev/cxgbe/crypto/t4_crypto.c +++ b/sys/dev/cxgbe/crypto/t4_crypto.c @@ -1483,11 +1483,12 @@ ccr_sysctls(struct ccr_softc *sc) SYSCTL_ADD_U64(ctx, children, OID_AUTO, "pad_error", CTLFLAG_RD, &sc->stats_pad_error, 0, "Padding errors"); SYSCTL_ADD_U64(ctx, children, OID_AUTO, "bad_session", CTLFLAG_RD, - &sc->stats_pad_error, 0, "Requests with invalid session ID"); + &sc->stats_bad_session, 0, "Requests with invalid session ID"); SYSCTL_ADD_U64(ctx, children, OID_AUTO, "sglist_error", CTLFLAG_RD, - &sc->stats_pad_error, 0, "Requests for which DMA mapping failed"); + &sc->stats_sglist_error, 0, + "Requests for which DMA mapping failed"); SYSCTL_ADD_U64(ctx, children, OID_AUTO, "process_error", CTLFLAG_RD, - &sc->stats_pad_error, 0, "Requests failed during queueing"); + &sc->stats_process_error, 0, "Requests failed during queueing"); } static int diff --git a/sys/dev/cxgbe/firmware/t4fw-1.16.59.0.bin.uu b/sys/dev/cxgbe/firmware/t4fw-1.16.59.0.bin.uu deleted file mode 100644 index 63b3f4a15f99..000000000000 --- a/sys/dev/cxgbe/firmware/t4fw-1.16.59.0.bin.uu +++ /dev/null @@ -1,9540 +0,0 @@ -/*- - * Copyright (c) 2017 Chelsio Communications, Inc. - * All rights reserved. - * - * 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 AUTHOR 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 AUTHOR 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. - */ -begin-base64 644 t4fw -AAAEIwEQOwAAAQkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAABAYEFQQdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IFNhdCBBdWcgMTIgMDQ6 -Mzc6MDQgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j -dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDR4eCAwMS4xMC4zYi4wMAAAAAAAAAAAAAAAANacJeNg -AMgA4QB78AAQAADhADC4eP///x/84UCAAAAB4QB7cAAAEAAf//4A4QGUcCAAAADhAZwE4QB5AAAC -AEDhAHmAAAYAQAACAAoABgAK4QB5BAAMAACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA -AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//jiAAAAAA -H/+OJAAAAAAf/44oAAAAAB//jiwf/8AAAAAAAAAAAADAABL/zRP/zZMgEv/NE//NhCAEMwGTIBH/ -zBL/zJIQEf/MEv/MkhAR/8wB9DER/8siCv+SEADkMQAFMQECABL/yALnMQIWABH/x4EQAQFfwCEC -EQHJERH/xBL/xJIQEf/EEv/EkhBgAA8R/78S/8OSEBH/vxL/wpIQgRAR/8HAIJIREv/AkhLAIJIT -Ev+/khCCEALyUGUv9xH/vccvkhAR/7ySEBL/vBP/vJMgwDKTIRP/u5MigiIS/7oT/7qTICMiIRT/ -uQQzAck4E/+4gzADgxQIMxEU/7akM5MhE/+qkyJgAAjCMJMhE/+nkyIS/7GQIJAhkCKQI5AkkCWQ -JpAnkCiQKZAqkCuQLJAtkC6QLyAmECAmEYIiEv+kwDAtNzAtNzQtNzgtNzwjPQFyM+0AAgAS/6HA -MC83AC83EC83IC83MCM9AXIz7QACABL/l8AwKDcwKDc0KDc4KDc8Iz0BcjPtEv+VwDAnNwAnNxAn -NyAnNzAjPQFyM+0S/5AV/5AW/5HAMNcgBWYBYAAZAAAAAAAAAAQ2BQACANMP0w8FMwxuOxQHRxQH -BEN2MeYENgUFMwxvO+0AAgAS/4MV/4EjCgACJwIHBEMEPgUFMwwHRxRvO/ADAgAS/33JLoMghCGF -IrwidDsOhlC0VZYwtDN0M/Rj/+YAZT/iZV/fEv9xwDIDLgUDAgAS/2jAMCg3QCg3RCg3SCg3TCM9 -AXIz7QACABL/ay0nAMARAUkxAEgxAQIAwAAU/2gE0jEV/2eUUBT/ZwTTMRX/ZpRQFP9mBNQxFf9m -lFAU/2UE1TEV/2WUUBD/ZQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA -H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/4AAH/+FsOMACfgf/4WwH/+FsOMAD6gf -/4WwH/+FsOMAD6gf/4WwH/+HWOMAD6gf/4dYH/+OFOMAEVAf/44gH/+v8OMAGBgf/6/wH/+v8OMA -Oegf/8AAH//+7eMAOeggAAAAIAABauMAeNggAAF4IAABfOMAekQgAAF8IAABheMAekggAAGYIAAB -nOMAelQgAAGcIAABpeMAelggAAG4IAABvOMAemQgAAG8IAABxeMAemggAAHYIAAB2OMAenQgAAHc -IAAB4uMAenQgAAH4IAAB+OMAenwgAAH8IAAB/OMAenwgAAIYIAACGOMAenwgAAIcIAACHOMAenwg -AAI4IAACOOMAenwgAAI8IAACPOMAenwgAAJYIAACWOMAenwgAAJcIAACYuMAenwgAAJ4IAACeOMA -eoQgAAJ8IAACguMAeoQgAAKYIAH7VeMAeowgAwAAIAMXMOMCc0wgAxcwIAMXMOMCinwgAxcwIAb4 -lOMCinwgBvigIAb8EOMGa+wgCAAAIAgS4OMGb1wgCBLgIAko2uMGgjwgCSjgIAkprOMHmDwgCwAA -IAsAAOMHmQggCwAAIAsAAOMHmQggCwAAIAtymOMHmQgAAAAAAAAAAAAAAAAgABQWIAAUCCAAF/Ig -ABQIIAAXbSAAFAggABS6IAAXBSAAFoogABQIIAAWOSAAFfIgABWFIAAT9SAAFS8gABQIIAAUCCAA -FAggABTaAAAAAP///////w/8///w////APwgALk2IAC6qiAAutogALqgIAC6YSAAulcgALomIAC6 -HCAAuhAgALm/IAC62CAAubUgALmFIAC62iAAuXsgALlpARAYAQAEAAAAAAAAAAAAAAACAgUFCAgL -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 -H/+AsB//rGBnRSMB782riZi63P4QMlR2H/+AAAAAPyggAxBcz////yALBfAQAAAAP////wIAAABA -AAAAAAAQAAgAAAAA////9////yALB1AAQAAAIAA87BoAAAAf/OB0IKAAAB//p3ggACA4IAAh1IAA -AAAAAIAA//7//yAAJTwgAAAAIAAloCALCMD//3////v//w/2gAAgCwjwIAsJIAABAAAABAAAH/+n -6CALUTAgCwmwIAA3ACAAOFAgADU0IAsLUCALChAgCwqgIAAzfCALCvBTAAAAUgAAAFEAAAAgAes8 -H/+l8AAA//8gBAmMH/+pmCAAPFAf/6nAIAsLcB//mNQf/6lkIAsNYBQAAACAAAACfFAAAIAAABCA -AAAGgACwAAAACgAA/zSS///wD4AAsQDhAZoAAAIAACALDSAf/5ZIAAB+QB//qZQA/8AAAQAAACgA -AADgAAAAJgAAAB//jzAGAAAABYAAAB//pUgrAAAAIABX4CALU1Af/6cUA4AAAAf///8EAQAINQAA -AAMAAAAAP///gEAAAAgP//8f////AADAAB//qXg9AAAAH/+UwAcAAACBBAEAgQQAAB//qVAAADqY -wwAAAAAAD/8AQwAAH/+m2AAACAAEAAAAIAtTsB//ryQf/61wH/+UIAAGAADhAHoAH/+UkB//qYQf -/5jkH/+Y0CALU+AAAweAIAtUUB//lrAAIAAAAAAJAAAAMAL//Ph/wAAAAKP/uwCj/7oADQAAAOAD -AACD/7YAD////w//+AD/AAAAIAtUkCALDqAgCw7QIAtVIAAPAAAACgAA//8ADwP/wACD/8AAIAtV -oCALVhAf/6poH/+t4P9g8AAf/63AH/+OMASAAAgf/4BQAEQAAP8f//8AwAAAAYDCAAACAgDhAAAA -4QDgAAAAgQDwAAAAgYAAAP9///8f/6Qk/7//////AAAAgAAAAACG3R//miwf/OIAH/+PIO4AAAAA -AAnMH/ziDA8AAAAgCw8QH/+qCAAACMwf/6sUH/+aqB//lLwf/4BgIAb6QAAAMAAAACcQH//c6CAL -XPAgC1zAH/+qdB//lLQAAP/+H/+YxN6tvu8gAwggNAAAAD8AAAAf/6tEAACJBgCZAAAf/6zoEAAH -AgHAgACZAAAAH/+rsACIAAiCgAABH/+tOP//8AADFQAAAxEAAAAPA/8gAPJkIAD2UCkAAAAAAIkU -IAD7JCADC0QAAEAAIAMOcAwAAAAgAQYIH/+uAAAAH5AgAwtUH/+q8B//rAgf/6mc/wD/APDw8PCq -qqqqzMzMzB//pZgAA///AAAn/yADC5ggC11AIAEWYAAPQkAgA10wH/+qOAAJAAAAAEgAggAAACAB -KsAf/6nsOwAACA4AAADQAAAAH/+AoAAAIHoAAAhQAAAfQB//qaQgCx5QIAsecCALHpAACQAIH/+t -NDAAAAB/AAAAIAshsAAAD/4gCyDgIAshQCALIYAAAOAA///3/yALIkAgA2N8AACD/yAHAEgVoAAA -IAcBQB//rPgAAAgGAACIzB//lmAABAP/CgAAACAG/NggBv54IAb9IB//mXCD/7cAg/+2ICALInAz -AAAAH/+tAB//rfQD/+AAf///AAA/9pAAACCIA//wACALSAAgC0fAIAtIIB//rwAf/6z8AA///x// -qwAf/6mgIAtg4B//mQQgAHUwIAb5yCAABYgf/6RwH/+V3B//lFwf/6jUIAsi8MAEAAAf/6eQH/+n -hB//p5wf/62wH/+tJCAD41AgCyMwIAMPIB//pZwgAHYQ4AEAAB//mjAgC2IQIAsjcCAAtYAf/5oo -IACygCALYZAgC2HgH/+WgCALJYDg//4AIAtKoB//mjQgCzBQH/+O9B//kKwf/6mQH/+tpCALPMAg -CzzwSAAAACABvigf/6ckIAHALB//lRAf/6X8H/+k9B//p+Qf/6S8AAAYQAAAFkwf/6f0IAb8VB// -pUQf/5SU4QAuAB//qADhAF4A4QIOAP//v//hAA4A4QGOAP//vv8f/5jMH/+lzCABxTggAdFs4AUA -AAP/AAAf/6UEIAMOeB/8v/88AAAAAAX//4MAAAAf/6T8DzwAACALR4AgAfG0IAH0sB//qoQgAfho -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYAAAAAAAAD/////////////////////H//86B// -/Ogf//ywH//8sB///LAf//ywH//2MB//+Vgf//e0H//3tB//97QgBtBgAAAAAAAAAAAAAAAAAAAA -ACAG06ggBtOoAAAAAAAAAAAAAAAAAAAAACAG0GAgBtBgH//6UB//+lAf//pQH//6UB//+lAf//pQ -AAAAACABxlAAAAAAAAAAAAAAAAAAAAAAAgEAAAAAAAAAAAAAAAAAAAQAAAAAAAAAgYAAAAAAABAF -AAAAAAAABAAAAAAAAAAAAAAAAAAAAACBAAAAAAAAGAUAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -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 -ExcOiwAA/GPgFeAKBQD//vQNpN0dAMCgwIoI6DT54QYVr/66AAAAAAAAAABsEAQoIAbojP8pUASA -APhAxh2gCxUAW3+fwCDRDwAAAAEQGAEAAQAAAAAAAAAAAAAgA1Y7IANWnSADViggA1adIANWKCAD -Vp0gA1Y/IANWPyADVoUgA1ZtIANWVgAAAAAgA19iIANfYiADXXMgA19iIANdcyADXz8gA18XIANd -cyADXkkgA11zIANdcyADXkAgA11zIANfYiADXXMgA11zIANfYiADXXwDAQACAAAAACAEzIsgBM2W -IATONSAEzIsgBM4tIATODyAEzIsgBMyLIATMiyAEzfEgBMyLIATMiyAEzIsgBMyLIATMiyAEzIsg -BM3hIATN1CAEzIsgBMyLIATMiyAEzIsgBMyLIATMiyAEzIsgBMyLIATMiyAEzIsgBMyLIATMiyAE -zIsgBMyLIATM8CAEzIsgBMzqIATM6iAEzIsgBMzqIATM6iAEza4gBMzqAAAAAAAAAAAAAAAAIATv -XiAE714gBO4SIATvXiAE6s0gBO9UIATvMCAE6s0gBOrNIATqzSAE6s0gBOrNIATt9iAE714gBOrN -IATt9iAE714AAAAAAAAAAAAAAAAgBP6zIAT9NCAFASMgBQDjIAUAqyAFAG0gBQBLIAT9iCAFACcg -BP/rIAT/kyAE/z0gBP7zIAT+ywAAAAAAAAAAARAYAQACAAABEBgBAAIAACAFrE8gBafkIAWsIyAF -q/cgBavKIAWrtSAFqAsgBagiIAWrnCAFqFcgBahDIAWoCyAFqFcgBagLIAWoCyAFqAsgBaxPAAAA -AAAAAAAAAAAAAAAAACAF+CwgBfFIIAXw8CAF7oAgBeqwAAAAAAAAAAAgBfEwIAXxKiAF8SogBfEq -IAXxMCAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxKiAF8Sog -BfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF -8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXx -KiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEw -IAXxKiAF8SogBfEqIAXxMCAF8SogBfEqIAXxKiAF8TAgBfEqIAXxKiAF8SogBfEwIAXxKiAF8Sog -BfEqIAXxMCAF8SogBfEqIAXxKiAF8TAgBfEqIAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxMCAF -8SogBfEqIAXxKiAF8TAgBfEqIAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxMCAF8SogBfEqIAXx -KiAF8TAgBfEqIAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxMCAF8SogBfEqIAXxKiAF8TAgBfEq -IAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8Sog -BfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8TAgBfEqIAXxKiAF8SogBfEqIAXxKiAF -8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8TAgBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXx -KiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEq -IAXxKiAF8TAgBfEqIAXxKiAF8SogBfEwIAXxKiAF8SogBfEqIAXxMCAF8SogBfEqIAXxKiAF8Sog -BfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF -8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXx -KiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEq -IAXxKiAF8SogBfEqIAXxKiAF8SogBfEqIAXxKiAF8SogBfEwAAAAAAAAAAAAAAAAIAXxfSAF8dcg -BfTsIAX03iAF9MkgBfS7IAX0oCAF9JIgBfR3IAX0aiAF9FcgBfRKIAX0NyAF9CogBfQXIAXxeSAF -9AMgBfP2IAXz4yAF89UgBfPAIAXztiAF86UgBfO2IAXzpSAF85cgBfOCIAXxeSAF8XkgBfF5IAXx -eSAF83UgBfGWIAXxeSAF8XkgBfF5IAXzWCAF8z8gBfM1IAXzJCAF8XkgBfMRIAXy9yAF8uQgBfLK -IAXytyAF8p8gBfKMIAXyeSAF8hggBfF5IAXxeSAF8XkgBfF5IAXxeSAF8XkgBfHlIAXxzSAF8bUA -AAAAIAX4dyAF+IEgBfp6IAX6VCAF+k0gBfpGIAX6PyAF+jggBfoxIAX6KiAF+iMgBfoZIAX6DyAF -+fQgBfnNIAX5pSAF+ZwgBfl+IAX5dCAF+WcgBflXIAX5UCAF+TogBfkzIAX4aCAF+QwgBfkCIAX4 -+CAF+PEgBfjqIAX42iAF+KIgBfibIAX4lAAAAAAAAAAAAAAABQAAAAUAAAAKAAAACgAAAAoAAAAK -AAAACgAAAAoAAAAKAAAACgAAAAoAAAAAIAafSCAGnJwgBpswIAaYzCAGlmggBokQIAaLsCAGlMgg -BoesIAaXOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUoAw8IEqWog46TkgAAAABSVgAAEAAAAGNv -bmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZm91bmQgYWRkaXRpb25hbCBjb25maWd1cmF0aW9uIGFm -dGVyIFtmaW5pXQoAADAAAABmY29lAAAAAHZuaWNfaWQAdmxhbgAAAAB0b3MAZXRoZXJ0eXBlAAAA -bWFjbWF0Y2gAAAAAbXBzaGl0dHlwZQAAZnJhZ21lbnRhdGlvbgAAAHBmX3ZmAAAAb3V0ZXJfdmxh -bgAAYmFzaWN2aXJ0dWFsAAAAAGdsYl9rZXkAZ2xidmZfa2V5AAAAcGZ2Zl9rZXkAAAAAaWR4dmZf -a2V5AAAAc3lubWFwZW4AAAAAc3luNHR1cGVuaXB2NgAAAHN5bjJ0dXBlbmlwdjYAAABzeW40dHVw -ZW5pcHY0AAAAc3luMnR1cGVuaXB2NAAAAG9mZG1hcGVuAAAAAHRubG1hcGVuAAAAAHRubGFsbGxr -cAAAAGhhc2h0b2VwbGl0egAAAABsYW4Ad2FuAGNsdXN0ZXIAbWFudWFsAAB0cF9waW8AAHRwX3Rt -X3BpbwAAAG5pY192bQAAbmljX3VtAABuaWNfdW1faXNnbABuaWNfaGFzaGZpbHRlcgAAb2ZsZAAA -AAByZGRwAAAAAHJkbWFjAAAAaXNjc2lfaW5pdGlhdG9yX3BkdQBpc2NzaV90YXJnZXRfcGR1AAAA -AGlzY3NpX2luaXRpYXRvcl9mb2ZsZAAAAGlzY3NpX3RhcmdldF9mb2ZsZAAAZmNvZV9pbml0aWF0 -b3IAAGZjb2VfdGFyZ2V0AHBvZmNvZV9pbml0aWF0b3IAAAAAcG9mY29lX3RhcmdldAAAAGlzY3Np -X3QxMGRpZgAAAABpc2NzaV9pbml0aWF0b3JfY21kb2ZsZABpc2NzaV90YXJnZXRfY21kb2ZsZAAA -AAB0bHNrZXlzAGNyeXB0b19sb29rYXNpZGUAAAAAcHBwAGRjYngAAAAAYjJiAHNvY2tldG51bQAA -AGNlZQBpZWVlAAAAAGF1dG8AAAAAYW5fZGlzAABwZGxpdGVfZGlzAAAgAxbQAAQAAAAABAAABAAA -AAAAAAAAAAAAAAAAIAaHcAAAAAAgBobIIAaEWCAGgzAgBmOgIAX/SCAF6gggBejwAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAIARe7CAEa+ggBGvoIARr6CAEe+AgBJOYIASj2CAErWQgBFvYIARZSCAE -T2QgBMtoIARNFCAESdggBejEIAXnnCAF4OAgBGvoIAXgCCAF3pwgBd3QIAbW2CADuuwgBBosIAap -nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIANUVCADPWwgA028IANLMCADSbQAAAAA -IANHXCADU4gAAAAAIARBEAAAAAAAAAAAAAAAAAAAAAAAAAAAIAbEHCAGwywgBt7sIAbDHCAGw1gg -BsI4IAbEBCAGwdAgBt7cIAbDCP8YMGBgAAAAAAECAwAAAAAAAAAAAAAAACAGn/AgBF04IABwjAAA -AAAAAACBAAAAAAAAAAAAAAAAAAECAwICAwMAAgMFAwMFBSAENQQgBDaIIAQ2KCAENpwgBDUgAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAENbQAAAAAAAAAAAAAAAAAAAAMAAAADQAAAA4AAAAP -AAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAAAAAAAQA -AAAEAAAACAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEA -AAACAAAABAAAAAgAAAD////////wAP///////+AA////////wAD///////+AAP///////wAA//// -///+AAD///////wAAP//////+AAA///////wAAD//////+AAAP//////wAAA//////+AAAD///// -/wAAAP/////+AAAA//////wAAAD/////+AAAADAxMjM0NTY3ODlhYmNkZWZBQkNERUYAAAAAAAAA -AAAAQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx -MjM0NTY3ODkrLwAAAAAAAAAAAAAAAAAAAAAgACPUAAEAACAAI7QABQABIAAjmAADAAUgACN4AAcA -AGOCU2MAAAAA////////AAAAJhoLCggrMkECREADLQAAAAAACAAAAAUAAAAHAAAAAAAAAIgAAACF -AAAAhwAAAAAAAABAAAABAAAAAoAAAAAAAAQECAAEBAgABAQIAAAAAAAAAAAAAACAAAACAAAAAoAA -B0MAAAAAAAAAAAAAAAAA/////////////////////wAhAAkAgQBBACEACQAhAAkAgQBBAIEAQQCB -AEEAgQBBACEACQCBAEEAIQAJACEAEQCBAEEAgQBBACEACQCBAEEAIQAJACEACQEBAEEAgQAhAIEA -IQAQEGEBAQCBAQEAgQMCAQAEAAAAAAAAAAAAAAAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAAAAA -AAAAACADCHAAAAAAIAMQiAAAAAAgAwh0AAAAASADEPQAAAACIAMIfAAAAAQgAwiEAAAACCADCIwA -AAAQIAMQ/AAAACAgAwiQAAAAQCADCJwAAACAIAMIqAAAAQAgAwi0AAACAAAAAAUAAAADAAAAAQAA -AAIgBqNUIAajDCAGofwgBqC4IAageCAGoFAgBqCgAAAAAAAAAgAAAAQAAAAIAFllcwAwMTIzNDU2 -Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoAAAAAbm9uZQAAAABhbGwAKgAAAGRpc2FibGVk -AAAAAGVuYWJsZWQAMHgAAE5BAABWMAAAVjEAAFYyAABWMwAAVjQAAFY1AABWNgAAVjcAAFY4AABW -OQAAVkEAAFZCAABWQwAAVkQAAFZFAABWRgAAcG9ydAAAAABwcm90b2NvbAAAAABnbG9iYWwAAGZ1 -bmN0aW9uAAAAAGZpbmkAAAAAcmVnAGZpbHRlck1vZGUAAGZpbHRlck1hc2sAAHZuaWNNb2RlAAAA -AHJzc19nbGJfY29uZmlnX21vZGUAcnNzX2tleW1vZGUAcnNzX2dsYl9jb25maWdfb3B0aW9ucwAA -c2dlX3RpbWVyX3ZhbHVlAHRwX3BtcngAdHBfcG1yeF9wYWdlc2l6ZQAAAAB0cF9wbXJ4X2ZsYWdz -AAAAdHBfbnJ4Y2gAAAAAdHBfcG10eAB0cF9wbXR4X3BhZ2VzaXplAAAAAHRwX250eGNoAAAAAHRw -X210dXMAdHBfdGNwdHVuaW5nAAAAAHRwX3RpbWVycmVzAHRwX3RpbWVydmFscwAAAAB0cF9iYWNr -b2ZmdmFscwAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHkAbnZmAHd4X2NhcHMAcl9jYXBzAABuaXFm -bGludAAAAABuZXEAbmV0aGN0cmwAAAAAbnZpAHJzc252aQAAcnNzbnNlY3JldAAAbmV4YWN0ZgBu -cmF3ZgAAAGNtYXNrAAAAcG1hc2sAAABuZXRob2ZsZAAAAABucm91dGUAAG5jbGlwAAAAbmZpbHRl -cgBuc2VydmVyAG5oYXNoAAAAdHBfbDJ0AAB0cF9kZHAAAHRwX2RkcF9pc2NzaQAAAAB0cF9zdGFn -AHRwX3BibAAAdHBfcnEAAABpc2NzaV9udGFzawBpc2NzaV9uc2VzcwBpc2NzaV9uY29ubl9wZXJf -c2Vzc2lvbgBpc2NzaV9uaW5pdGlhdG9yX2luc3RhbmNlAAAAaXNjc2lfbWF4X3NnZQAAAHBwbV9t -YXhfem9uZXMAAABwcG1fem9uZV9yYW5nZTAAcHBtX3pvbmVfcmFuZ2UxAHBwbV96b25lX3Jhbmdl -MgBwcG1fem9uZV9yYW5nZTMAZmNvZV9uZmNmAAAAZmNvZV9udm5wAAAAZmNvZV9uc3NuAAAAZmNv -ZV9uZmNiAAAAZGNiAGRjYl9hcHBfdGx2AGRjYl9kY2J4X3Byb3RvY29sAAAAYmdfbWVtAABscGJr -X21lbQAAAABod20AbHdtAGR3bQBkZWJvdW5jZXRpbWUAAAAAYW5fYWVjX3RpbWUAYWVjX3JldHJ5 -X2NudAAAAHZlcnNpb24AY2hlY2tzdW0AAAAAU2Vzc2lvblR5cGUAT0ZNYXJrZXIAAAAASUZNYXJr -ZXIAAAAARGF0YURpZ2VzdAAASGVhZGVyRGlnZXN0AAAAAEVycm9yUmVjb3ZlcnlMZXZlbAAASW1t -ZWRpYXRlRGF0YQAAAERhdGFQRFVJbk9yZGVyAABEYXRhU2VxdWVuY2VJbk9yZGVyAEluaXRpYWxS -MlQAAE1heENvbm5lY3Rpb25zAABNYXhSZWN2RGF0YVNlZ21lbnRMZW5ndGgAAAAASW5pdGlhdG9y -TmFtZQAAAEluaXRpYXRvckFsaWFzAABEZWZhdWx0VGltZTJXYWl0AAAAAERlZmF1bHRUaW1lMlJl -dGFpbgAATWF4QnVyc3RMZW5ndGgAAEZpcnN0QnVyc3RMZW5ndGgAAAAATWF4T3V0c3RhbmRpbmdS -MlQAAABUYXJnZXROYW1lAABUYXJnZXRBbGlhcwBUYXJnZXRBZGRyZXNzAAAAVGFyZ2V0UG9ydGFs -R3JvdXBUYWcAAAAAQXV0aE1ldGhvZAAAU2VuZFRhcmdldHM9QWxsAENIQVBfQQAAQ0hBUF9JAABD -SEFQX0MAAENIQVBfTgAAQ0hBUF9SAABEaXNjb3ZlcnkAAABOb3JtYWwAAE5vbmUAAAAAQ1JDMzJD -AABDUkMzMkMsTm9uZQBOb25lLENSQzMyQwBDSEFQAAAAAENIQVAsTm9uZQAAAE5vbmUsQ0hBUAAA -AE5vdFVuZGVyc3Rvb2QAAABJcnJlbGV2YW50AABSZWplY3QAAE5vAAA1AAAAQ0hOZXQgMS4wMAAA -AAAADAAAAAABAAF8AAwBAAAAABAAAAAUIAbz8AAAAxUOQAAAH/wAAB/8AAAf/6/wH/+v8CAG/BAg -BwGAIAkpsCAJKbAgCgAAIAqAACAKgAAgCuaAH/+pwCALAAAgCwAwH/+tBB//jnAAD///H/+n1B/8 -3gAf/6xQBAAACIEAAAAaAAAAH/+szCALAIAgBvxgg/+3AIAAAAAAAP//g/+2ICALSGAf/6o4H/+s -6B//qHAf/6mkH/+sYDAAABAgC0igIAtJAB//rmQf/6f4H/+QxOEBlgAgBwFAIAb/RCADCCAXkAAA -FLAAAAAAYAAgBwBggAAABCAHAUoAACB6AACD/xWgAAAgAwAAFqAAAAhQAQAgoAAAP/AAACOgAAAD -/wAfAMAABB//rmggBtHwKgAAACADQxQgC0kwIAtJcCAG0bTerb7/GsAAACAHAEgAAP/qIAcBUAAA -CBQAAIgAAACAAB//qZAf/6oYAAAnEAAehIAAAEAAIANdMB//qxQAEAAAH/+n2B//qyggAwAQIAtK -MCALSgABAAAAKAAAAOEAAAA4AAAA/z///zAAAHQf/4CwIAMAQCALANAwAAAIMAAADDQAAAjQAAAA -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 -IAsUQCALFNAgCxUg7gAAAAHAgAAQAAUNCQAAAB//q7AgAwFAAACDACALFkAAAIIAIAsVYCALFbAg -CxXwEAAHAh//qDAgCxagAAAMvAAAiQYgCxbAIAtJsCIiIiIADAAAIAtScCALUjAgAwGQIAsXICAL -FvAgCxoQIAsZ0CALGZAgCxlQIAsZECALGNAgCxiAIAsYQCALF/AgCxegIAsXYCALXXAgC12gIAtd -0CALXhAgC15QIAtegCALG0AgCxrwIAsaUCALGpAAAIDCAAAbISALG3AgC16wIAte8CALG5AgBvxA -AP/AABIAAAAgBRxQIAscACALHQAgCxzAIAscQCALHUAgAw4gIAUkzCALXxAAAB9AAAAQNv//7/8f -/65sH/+s+AAACFAgCx2gIAsd8CALHdAA///8MgAAAB//ruogAwHQM5AAACAG/0ggC19wIAtf0CAL -X7AgC2AQIAseECADblQgAwHYIAsewAAAgAUAAIAHIAse8IGAAADerb7vIAsfMB//qZQAAIP9MAAA -HDAAAAQwAAAU//7//x//raQA//AAACgAACALH2AAAAhAIAMJ5CALH5AA///6IAsf4DAAAAAwAAA0 -AACAASADAeAAAIACIAV7yCALYKAQAAUQmQAAADQAAAAgC2BQIAsgIAAZAAAgCyBwIAMPEAAAEg8g -CyCgH/+lNB//rTQDFQAAg/8AGyALIrDhAZGsAAGRrAsAAAAgBK9IIAMKlB//mAgAATiA4AAGAAAC -JxAgC2Egf///Dx//qQD8AP//4QCWAOEAmgAAAAn/AACwAB//qiwgAwIwIAsjwOEADgADAAAA4QAS -ABMAAAARAAAAH/wAAB//qXwgCyQAIAtiQAABlI8AAZTPIAMCUB//pVQf/5jsIAMGICALJEC///// -IAskgCAG+KAgCySwH/+PJB//p2AgAwcQH/+mDB//l/Qf/5aAH/+QtCALKqAgCyrwIAsrUB//qXAg -CywgAD///x//pRQf/5acH/+nzAAA/5cAAP7V//+rkx//qYjCAAAOBdwBAAP/AADAAAABIAsskCAL -LNAgCy0gIAstYCALLbAgCy3wIAMHoB//pfgf///wIAsusCALLxAf/6qEAgAAEB//jpAf/5hwH/+Q -6AAC//8AAJxAIAtSsCALL2AgCy/QIAswkP/f////v////v///yALW+AAAP4AIAtn0AAFAAIbAAAA -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 -ANEPZE5+LmAN6WESJxoZgACwn/5gJhXgAgUA0Q9kTmQoYA1kgzryYCYVoAIFANEPZE5RKsLWKcLV -qpmwmZkx0Q9kTkArwtWbMdEPZEIlLWBcLGBdCN0RDcwC/GAmFaACBQDRD2ROHS5gUAuLR/9gDOOi -AJ0Ax//+YCYV4AIFANEPZE4AiGeIjoiPmDHRD2RN84lniZ4qkhIpkhGqmbCZmTHRD2RN3opniq4q -ohGaMdEPZE3QLPKAK/J/rLuwu5sx0Q9kTb8t8n+dMdEPZE21jmeO7i/iFC7iE6/usO6eMdEPZE2g -j2eP/i/yE58x0Q9kTZKIZ4iOiY6IjamIsIiYMdEPZE1/iWeJnomdmTHRD2RNcopniq4rohCKr6uq -sKqaMdEPZE1ei2eLvoy8i7usu7C7mzHRD2RNS4xnjM6My5wx0Q9kTT6NZ43ejtiN167dsN2dMdEP -ZE0rjmeO7o7nnjHRD2RNHo9nj/6I9o/1qP+w/58x0Q9kTQuIZ4iOiIWYMdEPZEz+iWeJnivhdSqR -MSmRMAuqNqqZsJmZMdEPZEzjimeKriqhMJox0Q9kTNWLZ4u+LeFzLLEvK7EuDcw2rLuwu5sx0Q9k -TLqMZ4zOLMEunDHRD2RMrI1njd4u0S0t0Syu3bDdnTHRD2RMl45nju4u4SyeMdEPZEyJj2eP/ijx -Ky/xKqj/sP+fMdEPZFD42mBYHmMoYAwIiBH5RgAMMIkFAAmIAvhgJhWgAgUA0Q8qYAwpsIAAoAQJ -CRsJCUD4YCYV4AIFANEPZFC8izH6xAYd6LsdAPrEJh3gAgUA0Q+MMWTBFgqdAvzCxhXgAgUA0Q8A -AGRQkY4x/sumHajuHQD+y4YdoAIFANEPAGSQ/C7S4otgDrsMC1gUDogRCMgMKI0F/xjIFeS7AQAA -sQQAqRoJ/wL/GMYV4AIFANEPZFBHijH1QAcoEgCdAOpkeCtQBIAAWu94wCDRDwAAL+GKZPzRKeF3 -KOF2qYiwiPhgJhWgAgUA0Q8q4YpkrM8r4Xb6YCYV4AIFANEPxy/RD4xnjM6Nw4zCrcywzPxgJhWg -AgUA0Q8AjWeN3o3S/GAmFeACBQDRD45sqe6w7v5gJhWgAgUA0Q+PbP5gJhXgAgUA0Q8oYROpiLCI -+GAmFaACBQDRDylhE/hgJhXgAgUA0Q8AAAAAAAD/7PQNr/n1ABpK/wqaAfrCxhWgAgUA0Q8uYAws -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 -AAAAAAAAAAAAAAAABAACAAEAAIAAQAAgABAACCBAgAAAAAAAAAAAAAAAAAAgCKmrIAipqyAIqWsg -CKkzIAipBCAIqMYgCKjGIAiquCAIqrggCKjGIAiquCAIqrggCKjGIAioxiAIqH4gCKq4IAiquCAI -qrggCKq4IAiquCAIqrggCKq4IAiquCAIqrggCKq4IAiquCAIqrggCKq4IAiquCAIqrggCKq4IAio -pyADCyQAAAABIAMLLAAAAAIgAxCIAAAA/yADCHAAAAD/IAMLEAAAAAIgAwsUAAAAAyADCxwAAAAH -AAAAAAAAAAAgAwr0AAAAASADCvgAAAACIAMLAAAAAAQgAxCIAAAA/yADCHAAAAD/AAAAAAAAAAAg -AwhwAAAAACADEIgAAAAAIAMJwAAAAAEgAwnIAAAABCADCdAAAAAIIAMJ3AAAACAgAwnsAAAAQCAD -CfQAAACAIAMJ/AAAAQAgAwoEAAACACADChgAAAQAIAMKLAAACAAgAwpEAAAQACADClgAACAAIAMK -aAAAQAAgAwp0AACAACADCogAAQAAIAMKmAACAAAgAwqoABAAACADCsAAIAAAIAMK2ABAAAAgAwrg -AIAAACADCawAAAAQIAMJtAAAABEgAwmUAAAAACADCZgAAAABIAMJnAAAAAIgAwmkAAAAAwAAAAAA -AP//AAAAAAAA//8gAwkUAAABACADCSAAAACAIAMJMAAAAEAgAwlAAAAAICADCVAAAAAQIAMJYAAA -AAggAwlsAAAABCADCXgAAAACIAMJhAAAAAEAAAAAAAAAACADCMQAAAAAIAMIzAAAAAEAAAABAAAA -AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB -AAAABwAAAAcAAAAGAAAABgAMNQAAEEaqABRYVQAYagAAACtoAAAjgwAAGGoAAA0GAAALKgAAAAAA -AAAAAAAAAAAAaCsAAGgrAABsggAAb5wAAEpoAABKaAAATSkAAEpoAABO6gAATJgAAFI9AABPuAAB -hqAAAYagAAII1gACCNYAAgjVAAII1QACiwsAAosLAAII1QACtnIAArZyAAMNQAAEBgcAAAAAAAAA -AAAAAADy1RKY8tUSmPLVEpjy1RKY8tUSmPLVEpjy1RKY8tUSmPLVEpjy1RKY8tUSmAOFGxgDhRuY -8tUSmPLVEpjy1RKY8tUSmPLVEpjy1RKY8tUSmPLVEpgAAAAAAAAAAAAAAAD//wAFAAYABwAIAAkA -CgALAAwADQAOAA8AEP///////wAAADIAAAPoAAAAKAAATiAAAAAAAAPQkACYloAAD0JAAJiWgAAA -HCAAAABLAD0JAAAD0JAAmJaAAQEAAAMDAgIFBQQEBwcGBgAAADIAAAPoAAAAZAAAw1AAAAAAAAPQ -kAPQkAAATEtAA9CQAAAAHCAAAABLAD0JAAAPQkAjw0YAAwIBAAcGBQQLCgkIDw4NDAAAADIAAAPo -AAAACgAAAfQAAAAAAAAD6ACYloAAD0JAAJiWgAAAHCAAAABLAD0JAAAD0JAAmJaAAwIBAAcGBQQJ -CQgICwsKCgAAAAAAAAAAAAoAFACMAIIAZABaAKAAlgB4AG4AUABGADwAMgAoAB4ACgTOBJIJzgmS -ArIEVgTiBKYDtgQaB7IJVgZeAnYJ4gmmB04COgi2CRoIFgYiAsYEagCWA3oBcgd2AL4D3gT2BLoE -QgOiAmIHOgYOAIIDygQuAG4AWgMqATYB6gM+B8YJagFKBxIFlgh6BsIB/gZyAooDUgXmBb4I3gGa -B9oJ9gm6CX4HnglCCKIJBgFeB2ICTgcmAxYBIgWCCGYFqgjKCS4IjgEOBW4FWgVGBtYIKgY2AhIB -wgbqCD4A5gaGAtoEfgKeBAYGSgImCAIDZgCqA44F+gBGAdYG/gauBdIBhgeKCPIDAghSAPoFMgGu -ANID8gfuADIGmgLuBR4AHgUKAAAJxAmIBNgEnAeoCUwJ2AmcCKwJEAK8BGABaAdsBOwEsAJYBzAD -wAQkAyABLAe8CWAFjAhwBmgCgAW0CNQJ7AmwCTgImAdYAkQBGAV4CMAJJAVkBVAIIAYsBuAINALQ -BHQGQAIcAKADhAHMBvQBfAeACEgA8ADIA+gGkALkBQAExASIAqgETAOsBBAGVAJsB0QCMAgMBhgA -jANwALQD1AQ4A5gGBAB4AGQAUAHgAzQBQAcIBrgB9ANIBdwBkAfQCXQHlAj8AVQHHAMMCFwFoAiE -AQQFPAbMAggBuADcBnwClAP8B/gDXAXwADwGpAXICOgC+AUoAaQH5AAoBRQAFAAABMkEjQnJCY0C -rQRRBN0EoQOxBBUHrQlRBlkCcQndCaEHSQI1CLEJFQgRBh0CwQRlAJEDdQFtB3EAuQPZBPEEtQQ9 -A50CXQc1BgkAfQPFBCkAaQBVAyUBMQHlAzkHwQllAUUHDQWRCHUGvQH5Bm0ChQNNBeEFuQjZAZUH -1QnxCbUJeQeZCT0InQkBAVkHXQJJByEDEQEdBX0IYQWlCMUJKQiJAQkFaQVVBUEG0QglBjECDQG9 -BuUIOQDhBoEC1QR5ApkEAQZFAiEH/QNhAKUDiQX1AEEB0Qb5BqkFzQGBB4UI7QL9CE0A9QUtAakA -zQPtB+kALQaVAukFGQAZBQUAAAm/CYME0wSXB6MJRwnTCZcIpwkLArcEWwFjB2cE5wSrAlMHKwO7 -BB8DGwEnB7cJWwWHCGsGYwJ7Ba8IzwnnCasJMwiTB1MCPwETBXMIuwkfBV8FSwgbBicG2wgvAssE -bwY7AhcAmwN/AccG7wF3B3sIQwDrAMMD4waLAt8E+wS/BIMCowRHA6cECwZPAmcHPwIrCAcGEwCH -A2sArwPPBDMDkwX/AHMAXwBLAdsDLwE7BwMGswHvA0MF1wGLB8sJbwePCPcBTwcXAwcIVwWbCH8A -/wU3BscCAwGzANcGdwKPA/cH8wNXBesANwafBcMI4wLzBSMBnwffACMFDwAAAAoAjABuAJYAeAA8 -AFAAoACCAGQAMgBGAFoAKAAeABQAAACHAGkAkQBzADcASwCbAH0AXwAtAEEAVQAjABkAAAAAMAQA -ADAQAABZCAAAWaQAAZQwAAAQJAAAEDAAABA8AAAQ3AAAeywAAHs0AAHijAAB5owAAeqMAAHujAAB -8owAAfaMAAH6jAAB/owAAI3MAAB+dAAAj9wAAZFYAACP/AAAdRwAAHUYAAB1EAAAd+AAAHfkAAB3 -9AABnDwAARB0AAEQhAAAlAgAAJhcAACWDAAAlhQAAJYgAACWLAAA0CgAAJAIAAIQ3AACMNwAAlDc -AAJw3AABkFQAAGAcAAGg2AABkJAAAHfgAAB35AAAd/QAAHl4AAB5+AABlAQAAePAAAHnwAAB68AA -Ae/AAAHzwAAB98AAAfvAAAH/wAABlAwAADAAP///wAAAMAg////AAABZEKyAAAAAAFmsfiUAAAAB -lBAf////AAGUNAAAABEAAZQIH////wABlDgAAAARAAAQKH////8AABAsf////wAAEDR/////AAAQ -OH////8AABBAD0QAAAAAeygAH//iAAB7MD//7v8AAHs4AAAAAQAAe0A//+7/AAB8JAAf/+IAAeKI -AAgAAAAB5ogACAAAAAHqiAAIAAAAAe6IAAgAAAAB8ogACAAAAAH2iAAIAAAAAfqIAAgAAAAB/ogA -CAAAAACNyP////8AAI3Q/////wAAfnB/v///AAB+eH+///8AAH4AAsAAAAABkVQB////AAGRnAH/ -//8AAI/YAH///QAAj/j////9AAB1FAAAAAcAAHUMAAAACwAAd9wAAAADAAB38P////8AAZw4AAGA -QAABnPgAAAADAACQBAAAAD4AARB4AP///wABEHwA////AAEQiAAAAAAAAJQEAAD//wAAlBAAAP// -AACYVAAAAf8AAJhYAAAB/wAAlggAAAAAAACWEAAf//8AAJYYAB///wAAlhwAD///AACWJAAP//8A -AJYoAP///wAAljAA////AADQIAAAAAcAANAkAAAABwACENgAAAADAAIw2AAAAAMAAlDYAAAAAwAC -cNgAAAADAAGQUAAAAC8AAaDUAAABgwABkIwAOAAAAAGQmAA4AAAAAHl0AAAALwAAeXAAAAAFAAB5 -9AAAAC8AAHnwAAAABSADESQgCNUsIAMRKCAI5iggAxE0IAjlUCADEUAgCOScIAMRTCAI5EwgAxFg -IAjjaCADEWwgCOK4IAMRhCAI4VAgAxGUIAjgOCADEZwgCOAQIAMRsCAI3+ggAxHAIAjfuCADEcwg -CN6cIAMR1CAI3nQgAxHoIAjeQCADEfQgCNzUIAMR/CAI3CwgAxIMIAjbKCADEhggCNoYIAMSKCAI -2RAgAxI4IAjX5AAAAAAAAAAAIAMSUCAI1PQgAxJUIAjUeCADElwgCNRAIAMSZCAI1AggAxJwIAjT -0CADEnQgCNOYIAMSgCAI02AgAxKEIAjUsCADEowgCNMoIAMSmCAI0vAgAxKgIAjSuCADEqggCNKA -IAMSsCAIz7AgAxK4IAjSMCADEsQgCNIoIAMSzCAI0fAgAxLUIAjRuCADEtwgCNGAIAMS5CAI0Ugg -AxD8IAjN1CADEuwgCM2cIAMS9CAIzWQgAxL8IAjNLCADEwwgCMz0IAMTFCAIzLwgAxMcIAjMhCAD -EyQgCMxcIAMTMCAIzDQgAxM8IAjMBCADE1QgCMvcIAMTcCAIy7QgAxOAIAjLjCADE5AgCMtkIAMT -oCAIyzwgAxOwIAjLFCADE8AgCMrsIAMT0CAIysQgAxPcIAjKnCADE+ggCMp0IAMT9CAIyjggAxQA -IAjJHCADFAQgCMdMIAMUECAIxmggAxQkIAjGOCADFCwgCMYIIAMUOCAIxdggAxQ8IAjFqCADFEAg -CMV4IAMURCAIxUwgAxRUIAjE9CADFGAgCMO4IAMRuCAIxAQgAxRwIAjDkCADFHggCMNoIAMRCCAI -6RggAxEQIAjoSCADEPQgCOeYIAMRHCAI5vAAABAhIEIwY0CEUKVgxnDngQiRKaFKsWvBjNGt4c7x -7xIxAhAycyJSUrVClHL3YtaTOYMYs3ujWtO9w5zz/+PeJGI0QwQgFAFk5nTHRKRUhaVqtUuFKJUJ -5e71z8Ws1Y02UyZyFhEGMHbXZvZWlUa0t1unepcZhzj33+f+153HvEjEWOVohninCEAYYSgCOCPJ -zNnt6Y75r4lImWmpCrkrWvVK1Hq3apYacQpQOjMqEtv9y9z7v+uem3mLWLs7qxpspnyHTORcxSwi -PAMMYBxB7a79j83s3c2tKr0LjWidSX6XbrZe1U70PhMuMh5RDnD/n+++393P/L8brzqfWY94kYiB -qbHKoevRDMEt8U7hbxCAAKEwwiDjUARAJXBGYGeDuZOYo/uz2sM90xzjf/NeArESkCLzMtJCNVIU -YndyVrXqpcuVqIWJ9W7lT9UsxQ004iTDFKAEgXRmZEdUJEQFp9u3+oeZl7jnX/d+xx3XPCbTNvIG -kRawZld2dkYVVjTZTMlt+Q7pL5nIiem5iqmrWERIZXgGaCcYwAjhOIIoo8t921zrP/sei/mb2Ku7 -u5pKdVpUajd6FgrxGtAqszqS/S7tD91szU29qq2LneiNyXwmbAdcZExFPKIsgxzgDMHvH/8+z13f -fK+bv7qP2Z/4bhd+Nk5VXnQukz6yDtEe8CALARAf/6ZEH/+QsAAAE4gf/488AAALuAAAQA0gCwGg -IAsBMCALAYAgCwHAH/+QrAAAQR4AAPADAABBDgAAQEAAAKAAAACgIAAAQYgAAH//AABBhgAAgAAA -AEGBAACoGQAAqBoAAMMAAACoGwAAqBwAAKgXAAD//wAAEAQAAOWfAAAfEQAA7gkAAP/+AADq/yAL -AfAAAP8AIAsCMOEAXgAADwAPIFAAAAAAMNQAAP/p4QIOAAAAQAAACAAIAADkAAAAxDAAAMQxIAsD -oAAJiWgAAMRQIAsD0CALA/AgCwQQAAAgAAAAxFEAAMABAADEUiBP/4AgCA/kIAtL8CALTFAgC0ug -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 -zC5CHixG96y7LUIdK0b4q6osQigqRvmqmStCKSlG+qmIKkIqKEb7qP8pQisvRvyv7ihCLC5G/a7d -L0ItLUb+rcwuQi4sRv+suy1CLytWgquqLEIwKlaDqpkrQjIpVoSpiCpCMyhWhaj/L1aGKUI2r+4u -VocoQjeu3S1WiK3MLFaJrLsrVoqrqipWi6qZKVaMJEI4qYgoVo2oRCRWj1uToJofW5OfKVKmJFKn -LVKj+S/gFe+OBQDumQECAGmAAC9SpA/dDA1NNihSociOCagRqJh40wf4tMYVoAAaAMCQ6RYQJJap -gAAsEhBkwzce4jYsVpMv4s8q4sXo4sYnI/MAAC1C7+7ixy1WQoAA6skIDEZCgADoyAgP/kKAAK/P -nxmYGOgSEi92QoAA7s4IDu5CgAD+IUYVpK0dAG2pBQgAhgkCYfoiSBWmvR0AW3MyLULw0w/pEggu -7kKAAPgiaBWkrR0AbakFCACGCQJh+iJoFaa9HQBbcygtQvHpEgou7kKAAPgiiBWkrR0AbakFCACG -CQJh+iKIFaa9HQBbcx4tQvbTD+kSCS7uQoAA+GBoHaStHQBtqQUIAIYJAmH6YGgdpr0dAFtzFCNS -oypSp5ob6jMMCyAEgAAE5BYBAgDbMFuaUwTkFioKAVtzByMWABTiYC8SC/3EvAWgC4UA+iImFaAN -FQDk/wgNcASAAP4hhhXgClUAW5eQ2WAqEhGLHA8CAKKiKyaBIyaCJiaDCeQWKRYNAQIAKCKDBOow -KxoCW3LtCOowLCKI7BYOJgCpgAAE6jD6IigVoQslAFty5gjqMI0dDeQWBIoMW3Lb2KD+IcgVoApV -AP3EgAWgC4UA7yKIKadCgAAIRCz0IAYVoA0VAFuXcSZWpxniNCpSoytSpCmSFCZWpAuqDOpWoySK -YYAAK1HfwKN7oAzCYPAAPA2gBCUAAAAA9gACHaAEZQCDFh3iKoofixed0O3WASbj0QAAnMCcwVv7 -LxriICqiFKRr66ooCdgEgABb+rQm+sDmoKFtEASAAFv6MStSq2SwQCpSsixSsyRSqh7iGStSsR3i -GS9Sra67DbsBK1asK1awC/8MBLQM9YAARjAOFQDsVrMn+P0AAPfgBAewDQUAW3KAL3JmZPCUwIAp -UqHMl/AA9A2gCAUAACpSqCRSpSNSpitSoqhEpDPsUqkhmP0AAAYzAfpvAA/wDQUA41ajJ/j9AAD3 -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 -AFt0fuI2RCF9EYAA2iBb/QPnr4RtEASAAGP/LMCi/XuUBaALBQBbcb9j/3FsEAQTu4nyaGgVoAoF -AFtuQv1AaB2giQUA6iQADkAEgADTD9MPbZoP6YIAJEARAADppgAlUBEAAPuAaB2iCwUAW3Rj4jZD -IQBJgADAINEPAP17aAWgCgUA+gACHe/9tQBbcaXHK9EPAGwQBhi7nhm9rR67GB29rZ2a/yFmFaAL -BQD7IwQd4ApFACqUMhy9qMfwD8wBLIa2HL2mKIKuKZL1mRD4ICYVoI8FAFtxk8Ag0Q8AAABsEAQc -vZ8avZ8XvZ8twoEtpuX9kEgVoA1FAC2mJy2mJi2mKi2mNC2mNS2mMP1cxhWgCwUA+0wGFeAIFQAo -pjL5RaYVoBmFAPlDJhXgA4UAI3SAF7tfErtgHrsVI3B9IiKBH7wz93hmBaQJBQD+QeAL0EMBACJK -AAQuOS71ftEPFbsLCDoC+u+mHaCqAQAKlTklZX7RDwAAAAAAAABsEAQbvXsavXsYvXvAwOq2fyVR -AwAA+w/mFaCLhQBbbJMduy0cvXbs1kMmYAsAACzWRNEPbBAEGru467x1EQ1ZAABoIm3kkINkkAUA -APxCgBFQBBUAYAA5AAAAaWQDpaiXgHJLLOo0AApYBIAAW3B96GEUYiAFAADlqQgLF3wAAPcgBB3v -/3oApav3YAYd7/9SANEPLKLFKbKGo8wJzBHsmQgDDd0AAGhidmlk5KWdl9DRDxm7vqk5KZB9aEA2 -5JBmYhAFAAByQ5tj/8UsosUpsoajzOnMEQIgBQAA7JkIAwxtAABoYh1oZCXyn/u7ogCdAGP/nGWf -TGP/lqWY9wAGHe//pgClmvdABB3v/34AAKWb92AGFe//UgClnCfEANEPpZ0n1QDRD9EPAAAAAAAA -IAMQsAzAAAYgBtfsIAMQtAjAAAwgBtfsIAMQuCDAABAgBtd0IAMQvAbAADggBtlQIAMQwAjAADwg -BtfsIAMQxALAAEAgBtm4IAMQyAjAAEQgBtfsIAMQzAiAAEggBth8IAMQ0BiAAFwgBth8IAMQ1BiA -AHAgBth8IAMQ2BiAAIQgBth8IAMQ3BiAAJggBth8IAMQ4BiAAPwgBth8IAMQ5BiAAQwgBth8IAMQ -6BiAARwgBth8IAMQ7BiAASwgBth8IAMQ8AiAAXwgBth8RkNvRSBERFAgZmFpbGVkIDogb3hfaWQg -MHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBERFAgZmFpbGVkIDogRGRwUmVwb3J0IDB4JXgg -RGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBmYWlsZWQ6IGF2YWlsICVkCgBGQ09FIEZyZWU6 -IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXgg -CgAAAAAAAAAAAAAAAFBSTEkgUnNwIHRpbWVkb3V0IDogZmxvd2NfaWQgMHgleCBveF9pZCAweCV4 -IHJ4X2lkIDB4JXggCgAAAAAAAABod19iY204NDM0X2NoZWNrcmFtOiBTdGFydAoAAAAAAFBIWSBw -cm9jZXNzb3Igbm90IHJ1bm5pbmcsIHN0aWxsIGluIHJlc2V0IGZvciA1bXMsIHBvcnRfYml0X21h -cD0ldSAKAAAAAAAAAAAAAAAAUEhZIEZXIGhhcyBiYWQgQ1JDLCBva19jcmM9JXUKAABQSFkgZmly -bXdhcmUgbG9hZCBzdWNjZXNzZnVsIQoAAGh3X2JjbTg0ODM0X2xvYWRzZXF1ZW5jZTogU3RhcnRl -ZAoAAAAAAAAAAAAAAAAAAGh3X2JjbTg0ODM0X2xvYWRzZXF1ZW5jZTogVXBsb2FkIGltYWdlIHRv -IFBIWSBvbi1jaGlwIG1lbW9yCgAAAABod19iY204NDgzNF9sb2Fkc2VxdWVuY2U6IGRvbmUgbG9h -ZGluZyBpbWFnZSAoaSA9ICV1KQoAAAAAAAAAAAAAaHdfYmNtODQzNF9sb3dwb3dlclsldV06IGVu -YWJsZT0lZAoAAAAAAAAAAAAAAAAAaHdfYmNtODQzNF9sb3dwb3dlclsldV0sIGZhaWxlZCB0byBz -ZXQgMzAuMHg0MDFBYml0IDcgc2luY2UgMzAuMHg0MDBFIGJpdD0xIGFmdGVyIDVtcywJcmVnPSV4 -CgAAaHdfY2w0NV9pbml0WyV1XSBhY2FwcyAlI3gKAAAAAABod19jbDQ1X3VwZF9zcGRfYWR2ICUj -eAoAAAAAAAAAAGh3X2FxMTIwMl9saW5rX3VwWyV1XSB1cAoAAAAAAAAAcFsldV0gUEhZIE9WRVJI -RUFURUQgLSBmb3JjZWQgcG93ZXIgZG93biAodGVtcD0lZCkKAAAAAAAAAAAAAAAAAEZMQVNIIG5v -dCByZWFkeTogaSAldSBudnJSZWcgJSN4CgAAAAAAAAAAAAAAAAAAAEFRX0ZMQVNIX1JlYWR5IC0g -VGltZW91dCAoMSkKAAAAQVFfRkxBU0hfUmVhZHkgLSBUaW1lb3V0ICgyKQoAAAAJQVFfUmV0dXJu -Q29udHJvbE9mRkxBU0gKAAAAAAAAAHNldF9kaWdlc3Q6IEJQIGFscmVhZHkgZmMgMHgleCBmbGFn -cyAweCV4CgAAAAAAAHNldF9kaWdlc3Q6IGNzayAweCV4IGNvbm4gMHgleCBzdGF0ZQoAAAAAAAAA -AAAAAHNldF9kaWdlc3Q6IHVwbHN1Ym1vZGU6JXgsIHBnaWR4OjB4JXgsIHZhbDoweCV4IGJ1ZmZl -cmVkIDB4JXgKAABzZXRfZGlnZXN0OiBidWZfbGxfZmx1c2ggZmMgMHgleCBuZXh0X3dyIDB4JXgK -AABpcHY2X2FkZHJbMF0gMHgleCBpcHY2X2FkZHJbMV0gMHgleAoAAAAAAAAAAAAAAABhZGRyICVz -IHBvcnQgJXMgdGFnICVzCgAAAAAAAAAAAHJlZGlyZWN0IElQdjYgMHgleC0weCV4LCBwb3J0ICV4 -CgAAAAAAAAAAAAAAAAAAAHJlZGlyZWN0IElQdjQgMHgleCwgcG9ydCAleAoAAAAAYXV0aGVudGlj -YXRlX3RhcmdldDogSW5jb3JyZWN0IHBhc3N3b3JkCgAAAAAAAAAAQ0hBUF9DOiBkaWdlc3QgZXhw -YW5zaW9uIGVycm9yCgBDSEFQX046IFRhcmdldCB1c2VyaWQgbWlzbWF0Y2gKAENIQVBfUjogZGln -ZXN0IGV4cGFuc2lvbiBlcnJvcgoAcmN2ZF9wYXJhbXM6IGVycm9yLCBsZW4gJWQKAAAAAABMb2dv -dXQgZnJvbSBzZXNzaW9uIFsweCV4XQoAAAAAAGlTQ1NJIFNlYy1wYXJhbXMgcmVjZWl2ZWQgaGF2 -ZSBlcnJvcnMhIQoAAAAAAAAAAFRhcmdldCBtb3ZlZCB0ZW1wLiBjb25uICV4LCBzZXNzICV4CgAA -AAAAAAAAAAAAAExvZ2luIEZhaWxlZCEhLiBjb25uX2ZjIFsweCV4XSwgc2Vzc19mYyBbMHgleF0s -IHN0YXR1c19jbGFzcyBbMHgleF0KAAAAAAAAAAAAAAAAUHJvdG9jb2wgRXJyb3IgY2JpdCAlZCB0 -Yml0ICVkIGNzZyAlZCBuc2cgJWQKAAAAb2ZsZF9yeF9kYXRhOiBpbnZhbGlkIG9wY29kZSByZWNl -aXZlZCwgYWJvcnRpbmcgY29ubmVjdGlvbiAleAoAAGNobmV0X2wyZGV2X3VwX21iX2NiOiByYyBb -JWRdLCBwb3J0IFsldV0sIHN0YXRlIFsldV0sIGNvb2tpZSBbMHgleF0KAAAAAAAAAAAAAAAAbG9n -aW5fdGltZWRvdXQ6IEJyZWFraW5nIHBhdGggcyBbMHgleF0gYyBbMHgleF0gY3NrIFsweCV4XQoA -AAAAAHJlY292ZXJ5X3RpbWVvdXQ6IHNlc3MgaWQgWzB4JXhdIGluIGxvZ291dAoAAAAAAGZvaXNj -c2k6IFJlY292ZXJ5IHRpbWVkIG91dCBhZnRlciBbJXVdIHJldHJ5LCBiYWlsaW5nIG91dAoAAAAA -AABUQ1AgY29ubiBlc3RhYmxpc2htZW50IGZhaWxlZCAlZAoAAAAAAAAAAAAAAAAAAABJbnZhbGlk -IG9wY29kZSAweCV4IGluIGN0cmwgcGF0aAoAAAAAAAAAAAAAAAAAAABERFAgZXJyb3IgWzB4JXhd -LCBhYm9ydGluZyBjb25ubiBbMHgleF0KAAAAAAAAAAByeF9kYXRhX2RkcDogUmVzcG9uY2UgcmVj -aWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9uIHN0 -YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3MgWzB4 -JXhdCgBmb2lzY3NpX3Rhc2sgTlVMTCwgb3A6MHgleCBjc2tfZmNpZDoweCV4IGNza19zdGF0ZTow -eCV4IHRjYl9mY2lkOjB4JXgsIHRjYl9zdGF0ZToweCV4IAoAAAAAAAAAAABpaGRyOiBSZXNwb25j -ZSByZWNpZXZlZCBmb3IgdGFzayBbMHgleF0gd2hpbGUgaW52YWxpZCB0YXNrIG9yIGNvbm5lY3Rp -b24gc3RhdGUuIHRhc2sgc3RhdGUgWzB4JXhdLCBjb25uIHN0YXRlIFsweCV4XSwgY29ubiBmbGFn -cyBbMHgleF0KAAAAAAAAAABpaGRyOiBJbnZhbGlkIHRhc2sgc3RhdGUgMHgleCBmb3IgdGFzayAw -eCV4LCBpdHQgWzB4JXhdLCBvcGMgWzB4JXhdCgAAAAAAAAAAAAAAAGlzY3NpX2hkcl9yeDogYWJv -cnQgY29ubjogZmxhZ3MgPj4gNyBbMHgleF0sIGhkc2dsZW4gWzB4JXhdIGRzcl9kdGwgWzB4JXhd -LCBtYXhfYnVyc3QgWzB4JXhdCgAAAE1heCBkYXRhIGxlbiBleGNlZWRlZCAlZCA+ICVkCgAAcHJv -Y2Vzc190eF9xdWV1ZTogdHhfcXVldWUgZm9yIGNvbm46MHgleCBzdG9wcGVkLCBhYm9ydGluZyB0 -YXNrLgoAAAAAAAAAAAAAAAAAAABXQVRDSERPR19kaXNwYXRjaCBjYXNlIHRvIGF2b2lkOiBDb3Vu -dGVyX3dhdGNoZG9nICV1IENvdW50ZXJfc2NoZWQgJXUgCgAAAAAAAAAAAHhnbWFjWyV1XSBzZXR0 -aW5nL3Vuc2V0dGluZyBoc3MgcmVzeW5jIGJpdAoAAAAAAFdBVENIRE9HOiBkZXZpY2Ugc2h1dGRv -d24KAAAAAAAAV0FUQ0hET0c6IHBvcnRbJXVdIHBhdXNlIHdhdGNoZG9nIHRpbWVvdXQKAAAAAAAA -V0FUQ0hET0c6IGJ5cGFzcyB0aW1lb3V0CgAAAAAAAABXQVRDSERPRzogRkxSIC0gbm90IGltcGxl -bWVudGVkIHlldAoAAAAAAAAAAAAAAABXQVRDSERPRzogdGVtcGVyYXR1cmUgb2YgJWRDIGV4Y2Vl -ZHMgdGhyZXNob2xkIG9mICVkQwoAAAAAAAAAAAAAZmlsdGVyOiBwb3JncmFtbWluZyB0aWQgJXUg -KGxlIHRjYW0gaW5kZXggJXUpLi4uCgAAAAAAAAAAAAAAAAAAAGZpbHRlcjogcmVxdWVzdGluZyBj -b21wbGV0aW9uLi4uCgAAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSB3cml0ZSBvbmx5 -IHBlcm1pdHRlZCBvbiBsb2NhbCBjb25mCgAAAAAAAAAAAABkY2J4X2llZWVfY21kaFsldV0gY2Fu -bm90IHdyaXRlICV1IGFwcHMgKE1BWDogJXUpCgAAAAAAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhb -JXVdIHJlcXVlc3RpbmcgRENCX0lFRUVfQ01ECgAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIHVua25v -d24gZmVhdHVyZSB3cml0ZTogJXUKAAAAZGNieF9pZWVlX2NtZGhbJXVdIHVua25vd24gZmVhdHVy -ZSByZWFkOiAldQoAAAAAY2Fubm90IGFsbG9jYXRlIG9mZmxvYWRlZCBmaWx0ZXIgY29ubmVjdGlv -bgoAAAAAY2Fubm90IGFsbG9jYXRlIG9mZmxvYWRlZCBmaWx0ZXIgSVB2NiBjb25uZWN0aW9uCgAA -AAAAAAAAAAAAAAAAAGRpc3BhdGNoX2RlZmVycmVkX2NsYXNzX2NsYXNzX3NoYXBpbmdbJXU6JXVd -OiBsaXN0X2VtcHR5CgAAAAAAAABsb29wYmFjayBidWZmZXIgZ3JvdXBbJXVdIGlzIGRpc2FibGVk -CgAAAAAAAAAAAABpbnZhbGlkIGJ1ZmZlciBncm91cFsldV0gY29uZmlndXJhdGlvbjogbXR1ICV1 -IGx3bSAldSBod20gJXUgZHdtICV1CgAAAAAAAAAAAAAAAGZjICV1IHZmICV1IGdvdCBpdmY9MHgl -eCxyYW5nZTogJSN4LSUjeCAoJXUvJXUgdXNlZCkKAAAAAAAAAAAAAABWSSAldSBjYW5ub3QgZ2V0 -IFJTUyBzbGljZTogTm8gbW9yZSBzbGljZXMgYXZhaWxhYmxlICh1c2VkICV1LyV1KQoAAAAAAAAA -AAAAAAAAAHBmbiAldSB2Zm4gJXUgd2l0aCBwb3J0IG1hc2sgMHgleCBjYW5ub3QgYWNjZXNzIHBv -cnQgJXUsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxs -b2NhdGUgdmlpZCwgcmV0ICVkCgAAcGZuICV1IHZmbiAldSBjb3VsZCBtYXAgdmlpZCAgMHgleCB0 -byBmbG93YywgcmV0ICVkCgAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9j -YXRlIHV3aXJlIGZ1bmMgJWQgbWFjIGFkZHIsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAcGYgJWQs -IHZmICVkLCBFUlJPUiBleGNlZWRlZCBtYXggbWFjIGxpbWl0ICVkLyVkCgAAAAAAAAAAAAAAAAAA -AG1paV9mb3JjZV9zcGVlZFsldV06IHJjYXBzIDB4JXgKAAAAAAAAAAAAAAAAAAAAAG1paV9wZG93 -blsldV06IHBvd2VyZG93biBlbiAldQoAcG9ydF9jbWRfaGFuZGxlcjogdW5rbm93biB1LmRjYi50 -eXBlIDB4JXgKAAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIGludmFsaWQgcmVx -dWVzdCwgcGNhcHMgMHgleCBhY2FwcyAweCV4IG1jYXBzIDB4JXgsIHJjYXBzIDB4JXgKAAAAcG9y -dFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIHBjYXBzICUjeCBhY2FwcyAlI3ggcmNhcHMgJSN4 -IG1jYXBzICUjeAoAAAAAAAAAAABwb3J0WyV1XTogbDFjZmcsIHVuc3VwcG9ydGVkIEZFQywgcmNh -cHMgJSN4CgAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgbWRpIGlzc3VlIHBjYXBz -IDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06 -IGwxY2ZnLCBjYW5ub3QgZm9yY2Ugbm8vbXVsdGlwbGUgc3BlZWQocyksIHBjYXBzIDB4JXggYWNh -cHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1 -bmtub3duIGFjdGlvbiAweCV4CgAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1bmtub3duIHJl -YWQgYWN0aW9uIDB4JXgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBjcGwg -MHglMDh4JTA4eAoAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBjcGwgMHglMDh4JTA4 -eCAweCUwOHglMDh4CgAAAAAAAAAAAAAAAAAAAGNwbF9lcnJfbm90aWZ5OiB0aWQgJXUgbGVuICV1 -CgAARkNPRSBGcmVlOiBzdGlsbCB5aWVsZGVkIHdoZW4gZnJlZWluZy4uLmZsb3djX2lkICV4IGZs -b3djX2ZsYWdzICV4IAoAAAAAAAAAAAAAAABGQ09FIEJQIFdSIEVSUjogV1Igd2l0aCBjb29raWUg -JXgleCBlcnJvcmVkIGJhY2sgCgAAAAAAAAAAAAAAAAAAYWJvcnQvY2xvc2UgV1Igd2l0aCBjb29r -aWUgMHglbHggd2FzIGlzc3VlZCBvbiBzc24gMHgleCBpbiB3cm9uZyBzdGF0ZSAweCV4CgAAAABh -Ym9ydCBXUiBvbiBzc24gMHgleCBkaWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUgMHgleCV4CgAA -AAAAAAAAY2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggb24gc3NuIDB4JXg7ZGlkIG5vdCBmaW5k -IFdSIHdpdGggY29va2llIDB4JWx4CgAAAAAAAABhYm9ydCBXUiBvbiBzc24gMHgleCB3YXMgaXNz -dWVkIG9uIHhjaGcgMHgleCB3aXRoIHJ4X2lkIDB4JXggaW4gd3Jvbmcgc3RhdGUgMHgleAoAAAAA -AAAAAAAAAAAAAAB0YXNrX2FsbG9jOiBPdXQgb2YgdGFza3MuCgAAAAAAAGRjYnhfYXBwbHlfYXBw -X2NmZ1sldV1ORVcgQVBQIFRMViAKAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVh -dHVyZVsldV0gRkVBVFVSRV9MSU5LVVAKAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0g -U0VUX0xPQ0FMX1BBUkFNRVRFUlMKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1 -cmVbJXVdIEZFQVRVUkVfTk9fQURWRVJUSVNFCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1 -XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAA -AAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9OT1RfQURW -RVJUSVNFX0ZFQVRVUkUKAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsl -dV0gRkVBVFVSRV9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZl -YXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAA -AGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9HRVRfUEVFUl9DRkcKAAAA -AAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfQ0ZHX05PVF9D -T01QQVRJQkxFCgAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VT -RV9MT0NBTF9DRkcKAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVB -VFVSRV9VU0VfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVb -JXVdIEZFQVRVUkVfRkVBVFVSRV9ESVNBQkxFRAoAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBG -ZWF0dXJlWyV1XSBGRUFUVVJFX0VSUk9SX0NIQU5HRQoAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9j -ZXNzWyV1XSByZWNlaXZlZCBCV3MgZG8gbm90IGFkZCB1cCB0byAxMDAhCgAAAAAAAABXQVJOSU5H -OiByZWNlaXZlZCBBcHAgVExWIGNvbnRhaW5zIG1vcmUgdGhhbkZXIGNhbiBoYW5kbGUgKG1heDog -JXU7IHRsdiBjb250YWluczogJXUKAAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vzc1sldV0gc3Vi -dHlwZSAlI3ggcmVtX2Z0X2NoYW5nZWQgJXUgc21fY2hhbmdlICV1CgAAAAAAAAAAAAAAAAAAAGRj -YnhfaWVlZV9wcm9jZXNzWyV1XSBzdWJ0eXBlIHVua25vd24KAAAAAAAAAAAAAGRjYnhfcGFyc2Vf -cGt0WyV1XSBlcnJvciAlZAoAAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJkZXZfZmMgWzB4JXhdLCBs -MmRldl9mYy0+Zmxvd2NfaWQgWyV1XSBsMmRldl9mYy0+Zmxvd2NfZmxhZ3MgWzB4JXhdLCBpbnRm -IFsweCV4XQoAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGU6IGluIGRlbGF5ZWRfcHJvY2Vzc2lu -ZywgbDJ0ZW50IFslMDh4XQoAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBsMnQgaXA0 -IGVudHJ5IG5vdCBmb3VuZAoAAAAAAAAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTog -bDJ0IGlwNiBlbnRyeSBub3QgZm91bmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGVf -Y2FjaGU6IGJvdGggaXA0IGFuZCBpcDYgYWRkciBjYW5ub3QgYmUgbnVsbAoAAABjaG5ldF9sMnRf -dXBkYXRlX2NhY2hlOiBsMnQgZW50cnkgaWR4ICV1LCBzdGF0ZSAweCV4CgAAAAAAAAAAAAAAY2hu -ZXRfbDJ0X3VwZGF0ZTogbDJ0X3VwZGF0ZSByZXF1ZXN0IHNlbnQgbDJ0ZW50IFslMDh4XSwgbDJ0 -ZW50LT5pZHggWyVkXSwgbDJ0ZW50LT52bGFuIFslZF0KAAAAQ291bGQgbm8gYWxsb2NhdGUgcGNi -ISEgRnJlZWluZyBmY2YgISEhCgAAAAAAAAAAdm5fcGFyc2UgdW5rbm93biBzdWJjb2RlICV1CgAA -AAB2bl9wYXJzZSB1bmtub3duIGR0eXBlICV1CgAAAAAAAGlnbm9yaW5nIGZpcCByZWN2IGZvciBw -Y2IgZmxvdzoleCBpbiBvZmZsaW5lIHN0YXRlCgAAAAAAAAAAAAAAAABmaXBfdm4ydm5fcmVjdl9l -cnIgCgAAAAAAAAAAAAAAAENvdWxkIG5vdCBhbGxvY2F0ZSBmbG93YyEhISEKAAAAQ291bGQgbm90 -IGFsbG9jYXRlIFNDQiBmbG93YyEhISEKAAAAAAAAAAAAAAAAAAAAQ291bGQgbm90IGZpbmQgcmln -aHQgc2NiIGZvciBsb2dvCgAAAAAAAAAAAAAAAAAAaWdub3JpbmcgZmlwIHJlY3YgZm9yIGZjZiBm -bG93OiV4IGluIG9mZmxpbmUgc3RhdGUKAAAAAAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0 -IHNjYiBmb3IgZmxvZ2kKAAAAAAAAAAAAAAAAAHBvcnQgMHgleCwgc3RhdGUgMHgleCwgcmV0cnkg -bm90IHN1cHBvcnRlZAoAAAAAAEZsb2dpIHJlc3AgcmN2IHdpdGggdW5rbm93biB4Y2hnIG94X2lk -JXggc2lkICUyeCUyeCUyeCBkaWQgJTJ4JTJ4JTJ4CgAAAAAAAAAAAAAATl9QT1JUIDB4JXgleCV4 -IHJlamVjdGVkIFBMT0dJIHdpdGggcmVhc29uIGNvZGUgJXgKAAAAAAAAAAAAAAAAAEFCVFMgd2hp -bGUgYXdhaXRpbmcgUFJMSSBSc3A6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4 -IAoAAAAAAAAAAAAAAAAAQUJUUyBmYWtlIFJzcDogbG9jIDB4JXggb3hfaWQgMHgleCByeF9pZCAw -eCV4CgAAbGxkcF9yeF9wa3RfaGFuZGxlclsldV0gZHJvcCBwcmUtaW5pdCAoY291bnQgPSAldSkK -AAAAAAAAAAAAAAAAAGFycF9yZWN2OiBpcGlkIFsweCV4XSwgaW5fYWRkci5hZGRyIFsweCV4XSwg -c2lwIFsweCV4XSwgcmlwIFsweCV4XSwgYXJwX29wIFsweCV4XQoAAAAAAAAAAAAAAAAAAGFycF9y -ZWN2OiBpbl9hdHRyLmlwdjQuYWRkcjoweCV4LCBhaGRyLnNpcDoweCV4CgAAAAAAAAAAAAAAAAAA -AABjaG5ldF9hcnBfcmVjdjogaXAgY29uZmxpY3QgZGV0ZWN0ZWQKAAAAAAAAAAAAAABjaG5ldF9h -cnBfcmVjdjogcGlkIFsldV0sIHZsYW4gWzB4JXhdLCBhcnAgb3AgWzB4JXhdLCBzaXAgWzB4JXhd -LCByaXAgWzB4JXhdIGwyZGV2X2ZjLT5mbG93Y19pZCAleCBsMmRjLT5pbjRfZGV2LmluX2FkZHIu -YWRkciAleAoAAAAAAAAAAAAAAAAAAAAleCV4JXggUmVjaWV2ZWQgTE9HTyBmcm9tICV4JXgleCAK -AAAAAAAAAAAAAAAAAABjYW5ub3QgYWxsb2NhdGUgUE9GQ09FIGZpbHRlciBjb25uZWN0aW9uIGZv -ciB4X2lkICV4IAoAAAAAAAAAAAAARmFpbGVkIHRvIHBvc3QgeGNoZyBlcnI6IHNzbmkgMHgleCBj -b29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAG9mbGRfYWJvcnRfcmVxX25lZ2FkdlsldV06IHdy -IDB4JTA4eCBjcGxfYWJvcnRfcmVxIERFTElWRVJFRAoAAABob3N0X3dyWyV1XTogd3IgMHglMDh4 -IGNwbF9hYm9ydF9yZXEgc3RhdHVzIDB4JXgKAAAAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfcmxb -JXU6JXVdOiBtb2RlIHwgdW5pdCB8IHJhdGUgMHglMDZ4IG1pbiAldSBtYXggJXUgcGt0c2l6ZSAl -dQoAAAAAAABwYXJhbV9jaG5ldFsweCV4OjB4JXhdOiBjaG5ldCAweCV4IHJlYWQgJXUgcGYgJXUg -cmV0ICVkCgAAAAAAAAAAcGFyYW1fZG1hcVsweCV4OjB4JXhdOiBkbWFxIDB4JXggcmVhZCAldSBw -ZiAldSByZXQgJWQKAAAAAAAAAAAAAFJTU1NFQ1JFVEtFWTogcnNzc2VjcmV0IHRibCBiYXNlICVk -LCByc3Nuc2VjcmV0ICVkCgAAAAAAAAAAAAAAAABNQ1sldV0gaW5pdF9zdGF0ZV9tYWNoaW5lIDB4 -JTAyeAoAAAAAAAAAAAAAAAAAAABNQyBpbml0aWFsaXphdGlvbiBub3QgY29tcGxldGluZywgTUMg -Y3VycmVudCBpbml0IHN0YXRlIGlzIDB4JTAyeAoAAAAAAAAAAAAAAAAAAE1DWyV1XSBfaHdfbWNf -aW5pdF9tYwoAAAAAAAAAAAAAX2h3X21jX2luaXRfbWM6IGVycm9yLCByZXQgJWQKAABwaHk6IGZh -aWxlZCB0byBhbGxvY2F0ZWQgbWVtb3J5IGZvciBwaHkgZncgZmlsZSwgcmV0ICVkCgAAAAAAAAAA -aHdfbGVfZmlsdGVyX2N0dXBsZTogdHVwbGUgJXUgbm90IHNwZWNpZmllZCBidXQgcmVxdWlyZWQg -Zm9yIG1hc2sgMHgleAoAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogdGltZXJfcnMgJXV1 -cyB0aW1lc3RhbXBfcmVzICV1dXMgZGVsYXllZGFja19yZXMgJXV1cwoAAAAAAGh3X3RwX3RjcF9z -ZXR0aW5nc193OiBkYWNrX3RpbWVyICV1dXMgbXNsICV1dXMgcnh0X21pbixtYXggJXUsJXV1cyBw -ZXJzX21pbixtYXggJXUsJXV1cwoAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBrZWVwX2lk -bGUsaW50dmwgJXUsJXVzIG1heHJ0dCAldXVzIGluaXRzcnR0ICV1dXMgZmlud2FpdDJfdGltZXIg -JXV1cwoAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGRhY2tfdGltZXIgZnJvbSAl -dSB0byAldQAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBtc2wgZnJvbSAl -dSB0byAldQBod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWluIGZyb20gJXUgdG8g -JXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcnh0X21heCBmcm9t -ICV1IHRvICV1AAAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHBlcnNf -bWluIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGlu -ZyBwZXJzX21heCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6 -IGNhcHBpbmcga2VlcF9pZGxlIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0 -aW5nc193OiBjYXBwaW5nIGtlZXBfaW50dmwgZnJvbSAldSB0byAldQAAAAAAAAAAAABod190cF90 -Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRfbWF4cnR0IGZyb20gJXUgdG8gJXUAAAAA -aHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgaW5pdF9zcnR0X2luaXRzcnR0IGZyb20gJXUg -dG8gJXUAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGZpbndhaXQyX3RpbWVyIGZyb20g -JXUgdG8gJXUAAAAAAABmaWx0ZXJNb2RlPSUjeCBpbGxlZ2FsOiBzZWxlY3RzICVkIGJpdHMgKG1h -eCAlZCkKAAAAAAAAAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogbmVudHJpZXMgJXUgcm91dGUg -JXUgY2xpcCAldSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAA -AAAAbGUgY29uZmlndXJhdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIg -JXUgc2VydmVyICV1IGFjdGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAA -AGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBlZ3Jlc3MgcXVl -dWVzLCAldQoAAAAAAAAAAAAAAAAAAAAAaHdfc2dlX3F1ZXVlX2Jhc2VfbWFwWyV1XTogZXhjZWVk -ZWQgbnVtYmVyIG9mIGluZ3Jlc3MgcXVldWVzIHdpdGggZnJlZWxpc3QgYW5kIGludGVycnVwdCwg -JXUKAAAAaHdfc2dlX3F1ZXVlX2Jhc2VfbWFwWyV1XTogZXhjZWVkZWQgbnVtYmVyIG9mIGluZ3Jl -c3MgcXVldWVzLCAldQoAAAAAAAAAAAAAAAAAAABFcnJvciwgVG90YWwgUlNTIFNlY3JldCB0YWJs -ZSBhbGxvY2F0aW9uICVkID4gMTYKAAAAAAAAAAAAAAAAAAAAY2ZfcGFyc2U6IGZpbGUgbWVtdHlw -ZSAweCV4IG1lbWFkZHIgMHgleCBtYXBwZWQgQCAlcDoKAAAAAAAAAAAAAGNvbmZpZ3VyZWQgd2l0 -aCBjYXBzIG5ibXxsaW5rIDB4JTA4eCBzd2l0Y2h8bmljIDB4JTA4eCB0b2V8cmRtYSAweCUwOHgg -aXNjc2l8Y3J5cHRvIDB4JTA4eCBmY29lOjB4JXgKAAAAAAAAAAAAAABuZXQgVkkgYWxsb2NhdGlv -biBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAbmV0IFZJIG1h -YyBhZGRyZXNzIHByb2dyYW1taW5nIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoA -AAAAAAAAAAAAAAAAAABuZXQgVkkgcnhtb2RlIHByb2dyYW1taW5nIGZhaWxlZCBmb3IgZmNfaWQg -JXUgd2l0aCBlcnJvciAlZAoAAAAAbmV0IFZJIHJzcyBpbmRpcmVjdGlvbiB0YWJsZSBwcm9ncmFt -bWluZyBmb3IgZmNfaWQgJXUgZmFpbGVkIHdpdGggZXJyb3IgJWQKAAAAAABuZXQgVkkgcnNzIGNv -bmZpZyBjb21tYW5kIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAbmV0IFZJ -IGNvbW1hbmQgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAAAA -AGZvaXNjc2lfaW5pdDogaW5pdF9kb25lOiV1LCBmb2lzY3NpX250YXNrczoldSwgZm9pc2NzaV9u -c2VzczoldSwgbmNzb2NrOiV1LCBuc3BvcnRzOiV1LCBmb2lzY3NpX25pbml0OiV1LCByYzolZAoA -AAAAAAAAAAAAAAAAAAAARkNvRSBERFAgaW5pdDogZmNvZSBsbGltaXQgMHgleCwgZmNvZSB1bGlt -aXQgMHgleCBnYmwgbGxpbWl0IDB4JXggZ2JsIHVsaW1pdCAweCV4IHBjYnN6ICV4CgAAAAAARkNv -RSBERFAgaW5pdDogZmNvZSBwcG9kIG9mZiAweCV4LCBmY29lIHN0IHBwb2QgYWRkciAweCV4IGZj -b2UgbnVtIHBwb2RzIDB4JXgKAABjaF9jbF9yYXRlWyV1LyV1XTogY2FwcGVkIGNsYXNzIHJhdGUg -ZnJvbSByZXF1ZXN0ZWQgJXUgdG8gY29uZmlndXJlZCAoZWZmZWN0aXZlKSBjaGFubmVsIHJhdGUg -JXUKAAAAAAAAAAAAAAAAAAAAY2hfY2xfcmF0ZVsldS8ldV06IGluY3JlYXNlZCBkZWZpY2l0X2lu -Y3IgZnJvbSByZXF1ZXN0ZWQgJXUgdG8gcmVxdWlyZWQgbWluIG9mICV1OyByYXRlICV1IChlZmYg -JXUpIGRlZmljaXRfbWF4ICV1CgAAAAAAAAAAAAAAAABwa3RzY2hlZCBjaGFubmVsICV1IHNldHMg -c3BlZWQgKGZyb20gJXUpIHRvICV1IGticHMKAAAAAAAAAAAAAAAAbmV0X2wyZGV2X25vdGlmeTog -cGdpZCBbMHgleF0sIHByaW8gWzB4JXhdLCBjaCBbMHgleF0KAAAAAAAAAAAAAFsldV0gdW5hYmxl -IHRvIGV4ZWN1dGUgaW50ZXJuYWwgRENCX0lFRUVfQ01ECgAAAHBvcnRbJXVdIGxpbmsgZG93biAo -JXUpIChsc3RhdHVzICUjeCkKAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVzZWQgYnkgbW9kdWxlIHVu -cGx1ZwoAAAAAAAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5kICVwIGZvciBwb3J0ICV1 -LCB3YW50IHRvIHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gdXBkYXRl -IChmbG93Y2lkICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRfbG9vcGJhY2sgcG9ydCAl -I3ggY3VycmVudCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHNwZWVkIHVw -ZGF0ZTogJSN4CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNlCgAAAABwb3J0X2xpbmtf -c3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgZG93bgoAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFu -ZGxlclsldV0gcG93ZXJpbmcgdXAKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0g -dW5rbm93biBzdGF0ZSAoc3RhdGUgPSAlI3gpCgAAAAAAAAAAcG9ydF9saW5rX3N0YXRlX2hhbmRs -ZXI6IFNvbWV0aGluZyB3ZW50IHRlcnJpYmx5IHdyb25nLiByZXQgPSAlZAoAAAAAAAAAAAAAAAAA -AABDYWxjdWxhdGlvbiBvdXQgb2YgYm91bmRzIGZ1cmluZyBpbml0OiAlI3ggJSN4ICUjeAoAAAAA -AAAAAAAAAAAAbGUgaW5pdGlhbGl6YXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUg -ZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAbGUgaW5pdGlh -bGl6YXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAl -dSBhY3RpdmUgJXUgaGFzaCAldSBuc2VydmVyc3JhbSAldQoAAAAAAAAAAAAAAGh3X3RwX2luaXQ6 -IHRjYiByZWdpb24gKHN0YXJ0IDB4JTA4cyBzaXplICV1KSBtdXN0IGJlIGluIGZpcnN0IDI1Nk1C -IG9mIE1BIG1lbW9yeQoAAAAAAAAAAAAAAAAAAGh3X3RwX2luaXQ6IHBnbW5ndCByZWdpb24gKHN0 -YXJ0IDB4JTA4cyBzaXplICV1KSBtdXN0IGJlIGluIGZpcnN0IDI1Nk1CIG9mIE1BIG1lbW9yeQoA -AAAAAAAAAAAAAGh3X3RwX2luaXQ6IFRQIHBnbW5ndCBpbml0aWFsaXphdGlvbiBkaWQgbm90IGNv -bXBsZXRlCgAAAAAAAAAAAABidWZtX2luaXQ6IG4gJXUgYnVmbGw2NGludF9zaXplIDB4JXgKAAAA -AAAAAAAAAABidWZtX2luaXQ6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIGludGVybmFs -IGJ1ZmxsNjQgYnVmZmVycwoAAAAAAAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1v -cnkgdG8gYWxsb2NhdGUgYnVmbGw2NCBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9idWY6IG5vdCBl -bm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIGZsb3cgYnVmZmVycwoAAAAAAAAAbWVtX2luaXRfYnVm -OiBub3QgZW5vdWdoIG1lbW9yeSB0byBhbGxvY2F0ZSB0Y2JfY2FjaGUgKG9mZmVyZWQgJXUgdHJ5 -aW5nIHRvIHVzZSAldSBhdmFpbGFibGUgJXUpCgAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fb3Ro -ZXJzOiBzdGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KSwgaG1hICV1CgAAAABtcGFydGl0 -aW9uX290aGVyczogc3RhcnQgMHglMDh4IHNpemUgJXUgKHVudXNlZCAldSkKAAAAAAAAAAAAAAAA -bWVtX2luaXQ6IEVEQyBvdmVyY29tbWl0dGVkIGJ5ICVkIGJ5dGVzCgAAAAAAAAAAbWVtX2luaXQ6 -IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIGZsb3cgdGFibGUKAAAAAAAAAAAAAAAAAGN4 -Y25pY19kZXZpY2VfaW5pdDogY3hjbmljIFsweCUweF0sIGN4Y25pYy0+ZmlsdGVyIFslMHhdCgAA -AAAAAABwb2Zjb2UgaW5pdCBkb25lCgAAAAAAAAAAAAAAAAAAAHBvcnRfaW5pdFsldV0gcHR5cGUg -MHgleAoAAAAAAAAAUG9ydFsldV06IFVua25vd24gU0dNSUkgc3ViLXR5cGUgJSN4CgAAAAAAAAAA -AAAAUG9ydFsldV06IFVua25vd24gQlRfWEZJIHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAUG9ydFsl -dV06IFVua25vd24gQlRfWEFVSSBzdWItdHlwZSAlI3gKAAAAAAAAAAAAcG9ydF9pbml0WyV1XTog -cG9ydCB0eXBlIDB4JXggaXMgbm90IHN1cHBvcnRlZAoAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBw -bXJ4X3N0YXJ0IGZyb20gMHglMDh4IHRvIDB4JTA4eCB0byBtYWtlIHJvb20gZm9yIExFIEhBU0gg -YW5kL29yIFRQIFRDQnMKAAAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25faW5pdDogbW92ZWQgcG1y -eF9zdGFydCBmcm9tIDB4JTA4eCB0byAweCUwOHggKEVEUkFNKQoAAAAAAAAAAAAAAAAAAAAARVEg -cGZuICV1IHZmbiAldTogZGVzdHJveWluZyBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVt -X2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgKAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiBtYiBbMHgl -eF0sIGRlZmVycmVkLCBzdGF0ZSBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAGwyZGV2X3ZpX2ZzbTog -dmlpZCBbMHgleF0gcG9ydCBbMHgleF0sIG1hYy1pZCBbJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4 -OiUwMnhdLiAKAAAAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogc2dlX2VxaWQgWzB4JXhdLCBz -Z2VfaXFpZCBbMHgleF0sIHNnZV9lcWNyIFsweCV4XSwgcnNzX3N6IFsweCV4XQoAbDJkZXZfdmlf -ZnNtOiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X210dSBbJXVdLCBtYl9zY3JhdGNoIFsweCV4 -XSwgcG9ydCBbMHgleF0KAAAAAAAAAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiB2aWlkIFslZF0sIHZp -X2ZjLT5mbG93Y192aV9mbGFncyBbMHgleF0KAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogcGZuIFsw -eCV4XSwgdmZuIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbHBvcnQgWzB4JXhd -LCB2aWlkIFsweCV4XSwgZmxhZ3MgWzB4JXhdCgAAAAAAAABsMmRldl92aV9mc206IEVycm9yIGZy -ZWVpbmcgVkksIHJjIFsweCV4XQoAAAAAAABsMmRldl92aV9mc206IHBpZCBbMHgleF0sIHZpaWQg -WzB4JXhdLCBtYl9sb2MgWzB4JXhdLCBtYl9vcmlnWzB4JXhdLCBsMmRldl9mbGFncyBbMHgleF0s -IHJjIFsweCV4XQoAAAAAAAAAAAAAAAAAQWggaGEuLi5kb3VibGUgZnJlZSBveF9pZCAweCV4LCBy -eF9pZCAweCV4CgAAAAAASG9zdCBQUkxJIFJlc3BvbnNlIHRpbWVkb3V0OiBveF9pZCAweCV4IHJ4 -X2lkIDB4JXgKAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgdmlhIGNvbW1hbmQKAAAAAAAAaHdf -aTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYg -JXUKAGh3X2kyY190cmFuc2FjdGlvbjogbmRhdGEgJXUgYWRkcl9vcCAweCV4IHJlZyAweCV4IGRp -ZmYgJXUgY29udCAldSBmYWlsZWQgd2l0aCBlcnIgJWQKAAAAAAAAAAAAAGh3X2kyY190cmFuc2Fj -dGlvbjogbmRhdGEgJXUgYWRkcl9vcCAweCV4IGRhdGFbMF0gMHgleCBkaWZmICV1IGRwb3MgJXUg -Y29udCAldSBmYWlsZWQgd2l0aCBlcnIgJWQKAAAAAAAAAAAAAAAAAABpMmMgdHJhbnNhY3Rpb24g -ZmFpbGVkIHRvIGNvbXBsZXRlCgAAAAAAAAAAAAAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2Vy -OiBhZWNfcmV0cnlfY250IHZhbHVlICVkIGlzIG5vdCB3aXRoaW4gdGhlIGFsbG93ZWQgbGltaXQg -b2YgMSB0byAyNTQuRGlzYWJsaW5nIGl0LgoAAAAAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNlcjog -YW5fYWVjX3RpbWUgdmFsdWUgJWQgaXMgYmlnZ2VyIHRoYW4gYWxsb3dlZCBsaW1pdC5DaGFuZ2lu -ZyBpdCB0byAxMDAwMCBtcy4KAAAAAAAAAAAAAERlcHJlY2F0ZWQgY29uZmlnIG9wdGlvbiBmb3Vu -ZCBpbiBjb25maWcgZmlsZS4gSWdub3JpbmcuLgoAAAAAAABzY2hlZF9pb3F0eF9icF9wcmlvcml0 -eTogaGFzICV1IGVudHJpZXMgb25seSwgcmVxdWlyZXMgJXUgZW50cmllcwoAAAAAAAAAAAAAAAAA -AHRwX2JhY2tvZmY6IHBhcnNlZCAlZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMKAAAAAHRwX3RpbWVy -dmFsczogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50cmllcwoAAHRwX3RpbWVycmVzOiBwYXJz -ZWQgJWQgaW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAAHRwX210dXMgaGFzICV1IGVudHJpZXMgb25s -eSwgcmVxdWlyZXMgJXUgZW50cmllcwoAAAAAAAAAAAAAAAAAAAB0cF9tdHVzWyV1XSBpcyAldSBi -eXRlcyB3aGljaCBpcyBub3Qgc3VwcG9ydGVkCgBjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBz -Z2UgdGltZXIgdmFsdWVbJWRdIGlzIHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJvbSAldSB0byAldXVz -ZWNzCgAAAAAAAABmaWx0ZXJtYXNrIDB4JXggaXMgbm90IGVxdWFsL3N1YnNldCB0by9vZiBmaWx0 -ZXJtb2RlCgAAAAAAAAAAAAAAaHdfbGVfY2xpcF9oYW5kbGVyOiByZW1vdmVkIHBvcz0ldSAoPWlk -eCAldSkKAAAAaHdfbGVfY2xpcF9oYW5kbGVyOiBhZGRpbmcgdG8gcG9zPSV1ICg9aWR4ICV1KQoA -bW9kdWxlWyV1XTogcG9ydCBtb2R1bGUgaW5zZXJ0ZWQgYW5kIHJlYWR5CgAAAAAAbW9kdWxlWyV1 -XTogcG9ydCBtb2R1bGUgcmVtb3ZlZAoAAAAAAAAAAAAAAAAAAAAAbW9kdWxlWyV1XTogdW5rbm93 -biBtb2R1bGUgaWRlbnRpZmllciAweCUwMngKAAAAbW9kdWxlWyV1XTogZ3BpbyAldSB2ZW5kb3Ig -aWQgJTA2eCwgaWRlbnRpZmllciAweCUwMngsIFNGUDI4KGJ5dGUgMzYvMTkyKSAweCUwMngsIFNG -UChieXRlIDMvMTMxKSAweCUwMngsIDFHIChieXRlIDYpIDB4JTAyeAoAAABvcHRpY2FsIGxlbmd0 -aChieXRlIDE1LzE0MikgJXUsIGNvcHBlciBjYWJsZShieXRlIDgvMTQ3KSAweCUwMngsIGxlbmd0 -aChieXRlIDE4LzE0NikgJXUsIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAAbW9kdWxlWyV1XTogZ3Bp -byAldSB2ZW5kb3IgaWQgJTA2eCwgaWRlbnRpZmllciAweCUwMngsIFNGUDI4KGJ5dGUgMzYvMTky -KSAweCUwMngsIFNGUChieXRlIDMvMTMxKSAweCUwMngsIDFHIChieXRlIDYpIDB4JTAyeAoAAABv -cHRpY2FsIGxlbmd0aChieXRlIDE1LzE0MikgJXUsIGNvcHBlciBjYWJsZShieXRlIDgvMTQ3KSAw -eCUwMngsIGxlbmd0aChieXRlIDE4LzE0NikgJXUsIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAAcGZu -ICV1IHZmbiAldSBGU00gc3RhcnQKAAAAAAAAAABwZm4gJXUgdmZuICV1IEZTTSBjb21wbGV0ZQoA -AAAAAGZscl9wZnZmX2ZzbVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAAAGh3IHBm -IGJpdG1hcCAweCUwMnggdmZpZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAA -AABhZnRlciB2ZmlkIGZpeHVwLCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUw -OHgKAAAAAAAAdGltZXIgcXVldWUgJXUgbG9zdCBhIHRpY2shIG5leHQgJXAgbGFzdCAlcCBudW1l -ICV1CgAAAAAAAAAAAAAAAGZscl90aW1lcl9zdGFydDogZmxvd2NfaWQgJXUgJXAgYnVmICVwCgAA -AAAAAAAAAHBjaWU6IG5wZiAldSAocGZiaXRtYXAgMHglMDJ4KSBudmYgJXUgKHBmIDAuLjcgMHgl -MDh4JTA4eCkgdmZzdHJpZGUgJXUKAAAAAAAAAAAAaHdfZ3Bpb19wcmVwOiBlcnJvciwgcmV0ICVk -CgAAAABmYWlsZWQgdG8gZmluZCB0aGUgJWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAABmYWls -ZWQgdG8gcGFyc2UgdGhlICVjJWMgVlBEIHBhcmFtZXRlcgoAAAAAAAAAAABtZW1fcHJlcDogZXJy -b3IsIHJldCAlZAoAAAAAAAAAAGZhaWxlZCB0byBzdWNjZXNzZnVsbHkgZmluZCBDaGVsc2lvIFZQ -RAoAAAAAAAAAAHZwZF9wcmVwOiBlcnJvciwgcmV0ICVkCgAAAAAAAAAAc2VyY2ZnX3ByZXA6IGVy -cm9yLCByZXQgJWQKAAAAAABsb2cgaW5pdGlhbGl6ZWQgQCAweCUwOHggc2l6ZSAldSAoJXUgZW50 -cmllcykgZndyZXYgMHglMDh4IHBjaWVfZncgMHglMDh4CgAAAAAAAGdhdGhlcl90YXNrc19mb3Jf -dG1mOiBJbnZhbGlkIHR5cGUgWzB4JXhdLCBiYWlsaW5nIG91dC4KAAAAAAAAAABmY19zZW5kX2Fs -bG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNv -ZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8g -c2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAAAARkNvRSBGQ0IgbGlua2Rvd246IGlv -X3JlcSAweCV4JXggaXFpZCAweCV4IGZsb3dpZCAweCV4IG9wIDB4JXgKAGZjb2Ugbm90aWZ5IDog -VXBkYXRlIG5ldyBEQ0JYIHZhbHVlcyBWSSBzdGF0ZSAweCV4IHByaSAweCV4IHNjaGVkY2wgMHgl -eCBkY2J4X2RvbmUgMHgleAoAAAAAAAAAAGZjb2Ugbm90aWZ5IDogRkNGIGZsb3dpZCAweCV4LCB1 -bHBjaCAweCV4IAoAAAAAAGZjb2Ugbm90aWZ5IDogRkNvRSBMSU5LVVA6IHBvcnQgMHgleCwgZXZl -bnQgMHgleAoAAAAAAAAAAAAAAAAAAABmY29lIG5vdGlmeSA6IEZDb0UgTElOS0RPV046IHBvcnQg -MHgleCwgZXZlbnQgMHgleAoAAAAAAAAAAAAAAAAAZmNvZSBub3RpZnkgOiBEQ0JYIDogcG9ydCAw -eCV4LCBwcmlvcml0eSAweCV4IHVscHR4Y2ggMHgleCBjbGFzcyAweCV4CgAAAAAAAAAAAABSREVW -IG1zZyBmbG93YzoleCBzdGF0ZSAweCV4IGV2ZW50IDB4JXgKAAAAAAAAAABjYW5jZWwgZmNiOiV4 -IHNjYjoleCBzdGF0ZToleAoAAEZDb0UgRkNGIHRpbWVyOiBmbG93YyBzdGF0ZSAweCV4LCBwb3J0 -IDB4JXggLGZjZiAweCV4LCBmbG93Y19pZCAweCV4CgAAAAAAAAAAAAAAaHcgcmVnaXN0ZXIgb3Bl -cmF0aW9uIG5vdCBjb21wbGV0aW5nLCByZWcgMHglMDh4IG1hc2sgMHglMDh4IHZhbHVlIDB4JTA4 -eCAocmVnIDB4JTA4eCkKAAAAAAAAAAAATURJTyBDTDQ1OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBh -ZGRyCgAAAAAAAAAAAAAATURJTzogZmFpbGVkIHRvIHdyaXRlCgAAAAAAAAAAAABNRElPIENMNDU6 -IGZhaWxlZCB0byBzZXQgdXAgTU1EIGFkZHIKAAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gcmVh -ZAoAAAAAAAAAAAAAAAlBUV9UYWtlQ29udHJvbE9mRkxBU0g6IDFlLmMwMDE9JSN4IDFlLmM0NTA9 -JSN4IDFlLmM0NTE9JSN4IDFlLjEwMD0lI3gKAAAAAAAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5 -Rmxhc2hJbWFnZSAtIEltYWdlIGludGVncml0eSBjaGVjayBmYWlsZWQgKGNhbGMgJSN4IHZhbCAl -I3gpCgAAAAAAAAAAAAAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIEltYWdl -IGludGVncml0eSBjaGVjayBwYXNzZWQKAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2Ug -LSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFjZSAoJXUpCgAAAAAAQVFfQVBJX1dy -aXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIFRpbWVvdXQgd2FpdGluZyBmb3IgZmxhc2ggaW50ZXJm -YWNlICgldSkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gVGltZW91dCB3 -YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KQoAAAAAAEFRX0FQSV9Xcml0ZUFuZFZlcmlm -eUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFjZSAoJXUpIChw -cCAlI3ggYXAgJSN4KQoAAAAAAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1l -b3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFjZSAoJXUpCgAAAAAAQVFfQVBJX1dyaXRlQW5k -VmVyaWZ5Rmxhc2hJbWFnZSAtIFRpbWVvdXQgd2FpdGluZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgl -dSkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gRXJyb3Igb24gYnVybmlu -ZyBGTEFTSCAoY3JjMTYgbWlzbWF0Y2gpCgAAAAAAACUwOHg6ICUwOHggJTA4eCAlMDh4ICUwOHgK -AAAAAAAAZm9pc2NzaV92YWxpZGF0ZV9sb2dpbl9zdGFnZTogLSAxCgAAAAAAAAAAAAAAAAAAY3Bs -X3R4X3BrdDogdmxhbmlkIFsweCV4XQoAAAAAAABjaG5ldCBbJWQvJWRdIGZyZWUgbDJ0IGVudHJ5 -OiBpZHggJXUsIHJlZmNudCAldQoAAAAAAAAAAAAAAAAAAAAAY2huZXQgWyVkLyVkXSBwdXQgbDJ0 -IGVudHJ5OiBpZHggJXUsIHJlZmNudCAldQoAY2huZXQgWyVkLyVkXSBnZXQgbDJ0IGVudHJ5OiBp -ZHggJXUsIHJlZmNudCAldQoAY2huZXQgWyVkLyVkXSBsMnQgYWxsb2MgbDJ0ZW50IDB4JXgsIGlk -eCAldSwgcmVmY250ICV1CgAAAAAAAAAAAGNobmV0X2ZpbmRfbDJ0X2VudHJ5OiBkYWRkciBbJTA4 -eF0sIFsweCUwOHhdLCBsb2NhbCBuZXR3b3JrIFslZF0KAAAAAAAAAAAAAAAAAAAAY2huZXQgZmlu -ZCBsMnRlbnQgbm90IHZhbGlkLCAweCV4LCBpZHggJXUsIHN0YXRlIDB4JXgsIHJldHJ5IGNvdW50 -ICV1CgAAAAAAAAAAAABjaG5ldCBsMnRlbnQgMHgleCwgaWR4ICV1LCByZWZjbnQgJXUKAAAAAAAA -AAAAAABjaG5ldCBsMnRlbnQgZmluZCBlcnIKAAAAAAAAAAAAAG91dCBvZiBhdGlkczogbWF4IGF0 -aWRzOiAlZAoAAAAAZm9pc2NzaV9maW5kX3Rhc2s6IHRhc2sgbm90IGZvdW5kIHRjYl9mYyBpZCAw -eCV4IGl0dCAweCV4CgAAAAAAAFdBVENIRE9HOiBObyB0ZW1wZXJhdHVyZSBzZW5zb3IgYXZhaWxh -YmxlLgoAAAAAAFdBVENIRE9HOiBBY3RpdmF0aW5nCgAAAAAAAAAAAAAAV0FUQ0hET0cgLSBFbmFi -bGUgYWN0aW9uICV1IHRpbWUgJXUKAAAAAAAAAAAAAAAAV0FUQ0hET0cgLSBEaXNhYmxlIGFjdGlv -biAldQoAAABXQVRDSERPRzogRGUtYWN0aXZhdGluZwoAAAAAAAAAAHBvcnRbJXVdIHNldCBQQVVT -RSBQQVJBTVM6IHBwcGVuICV1IHR4cGUgJSN4IHJ4cGUgJSN4CgAAAAAAAAAAAABtcHNfbGlua191 -cFsldV0gYWNhcHMgJSN4ICg4MDIuMyAlI3gpICsgbHBhY2FwcyAlI3ggPT4gJSN4CgAAAAAAY2hf -Y2xfcmF0ZVsldS8ldV06IGNhcHBlZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1aXJlZCAldSB0byAl -dTsgcmF0ZSAldSAoZWZmICV1KSBkZWZpY2l0X21heCAldQoARENCWDogc3VtIG9mIHJhdGVzIG9u -IGFsbCBjbGFzc2VzIG11c3QgYmUgMTAwIChhY3R1YWw6ICV1KQoAAAAAAHdvcmthcm91bmQxMzcy -MzogZGV0ZWN0ZWQgV1IgQCAweCUwOHggb2Ygc2l6ZSAldSBieXRlcywgZHJpYmJsaW5nIGl0IGlu -ICV1IGJ5dGVzIGF0IGEgdGltZQoAAAAAAHJpX3dyX2luaXRbJXVdOiBtc3MgJXUgaXMgbm90IDgt -Ynl0ZSBhbGlnbmVkCgAAAGNvcmVfcHJvZ3JhbV90Y2I6IHRpZCAlI3ggdF9zdGF0ZSAlI3ggcmN2 -X2FkdiAweCUwOHggcmN2X3NjYWxlICUjeCB0eF9tYXggJSN4IHJjdl9ueHQgJSN4IGF0aWQgJSN4 -CgAAAAAAAAAAAAAAAAAJb3B0MCAlI3gleCBvcHQyICUjeCBpcHY2ICUjeCBmbGFnc190aW1lciAw -eCUwOHgKAAAAAAAAAAAAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGgg -NS10dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBpcCAweCUwOHglMDh4 -IGZpbHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAAAAAAAAAAAAb2ZsZF9j -b25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUwNHggZnAgMHglMDR4 -IGxpcCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBAIExFIGluZGV4ICV1 -CgAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4 -JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmlsdGVyIDB4JTA4 -eAoAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUw -NHggZnAgMHglMDR4IGxpcCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHglMDh4CgAAAAAAAAAA -AAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogaXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAA -AAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgbm90IGFsbG9jYXRlZAoA -AABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMGlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAA -AAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSBub3QgYWxsb2NhdGVkCgAA -SVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAAAAAA -AAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgbm90IGFsbG9jYXRlZAoAAElR -RkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgaXMgdmFsaWQgYnV0IG5vdCBmbDBpZCAldQoA -AAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBoZWFkZXIg -c3BsaXQgZmVhdHVyZSBpcyBub3QgZW5hYmxlZAoAAAAAAAAAAAAAAAAAAABod191bHB0eF93b3Jr -YXJvdW5kX3ByMTY5NDlfZW5hYmxlZF92ZmlkOiB2ZmlkICV1IGVuYWJsZWQgJXUKAAAARVEgcGZu -ICV1IHZmbiAldTogY3JlYXRpbmcgRVRIIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1f -Ynl0ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAARVEgcGZuICV1IHZmbiAldTogY3JlYXRp -bmcgQ1RSTCBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFn -cyAweCUwOHgKAAAAAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSB0b28gbGFyZ2UgKG1heCAl -dSkKAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAAAAAAAAaHdf -Y2ltX3RwX3dvcmthcm91bmQxMzcyM19lbmFibGU6IHBvcnQgJXUgcHJvdG9jb2wgMHgleCBlbiAl -dSBjdXJyZW50IDB4JXggd29ya2Fyb3VuZF9wcjEzNzIzIDB4JXggbmV4dCAweCV4CgAAAGRjYnhf -cG9wdWxhdGVfY3RybCBjb2RlIGluY29tcGxldGUKAAAAAAAAAAAAAAAAAHZpX3RjYW1fcmF3IGlk -eCAldSBtYWMgMHglMDR4ICUwOHgKAAAAAAAAAAAAAAAAAHBvcnRfYmxpbmtfbGVkX3Jlc3RvcmUK -AAAAAAAAAAAAcG9ydF9ibGluazogYmxpbmtkdXI9MHgleCBibGlua19yZWZjbnQKAAAAAAAAAAAA -cG9ydF9ibGluazogCWJsaW5rX3JlZmNudD0weCV4CgBwb3J0X2JsaW5rOiAJYmxpbmtfcmVmY250 -PTB4JXgKAG1paV9hZHZfZmNbJXVdOiByY2FwcyAweCV4CgAAAAAAbWlpX2Fkdl9zcGVlZFsldV06 -IHJjYXBzIDB4JXgKAABtaWlfaW5pdFsldV06IGFjYXBzIDB4JXgKAAAAAAAAAHBvcnRbJXVdOiBn -YXZlIHVwIGZpeGluZyBlcnJvcnMhISEKAAAAAAAAAAAAAAAAAG1paV9hbnJlc3RhcnRbJXVdOiBh -Y2FwcyAweCV4CgAAbWlzc2luZyBwb3J0IGNhcHMzMiB0byBjYXBzMTYgdHJhbnNsYXRpb24gZm9y -ICUjbHgKAAAAAAAAAAAAAAAAAGh3X3hnbV9wb3J0X2xwYmsgcG9ydCAldSBwdHlwZSAlI3ggYWN0 -aW9uICUjeAoAAHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24gdS5kY2IudHlwZSAweCV4CgAAAAAA -AG1pc3NpbmcgcG9ydCBjYXBzMTYgdG8gY2FwczMyIHRyYW5zbGF0aW9uIGZvciAlI3gKAAAAAAAA -AAAAAAAAAABiYWQgRmxvd0MgJWQgb24gZXN0YWJsaXNoZWQgY29ubmVjdGlvbgoAAAAAAAAAAABl -dGhfZmxvd2NfaGFuZGxlclsweCV4XTogZmxhZ3MgMHglMDh4IG51bV9ieXRlcyAldSBzY2hlZGNs -IDB4JXggLT4gMHgleAoAAAAAAAAAAHNjc2lfcmVhZDogcHBvZCBhbGxvYyBmYWlsZWQsIG5wcG9k -ICV1CgAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9MSU5LVVAKAAAAAAAAAAAA -AAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9VUERBVEVfRENCWF9UTFYKAAAAAGRjYnhf -Y29udHJvbF9zbVsldV0gQ09OVFJPTF9QRUVSX05PVF9BRFZFUlRJU0VfRENCWAoAAAAAAAAAAAAA -AABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfVVBEQVRFX09QRVJfVkVSU0lPTgoAAAAAAAAA -AAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1BST0NFU1NfUEVFUl9UTFYKAAAA -ZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX0FDS19QRUVSCgAAAAAAAAAAAAAAZGNieF9pZWVl -X3ZhbGlkYXRlWyV1XSBlcnJvciAob3VpICUjeCBzdWJ0eXBlICUjeCBsZW4gJSN4KQoAAAAAAGRj -YnhfY2VlX3ZhbGlkYXRlWyV1XSBlcnJvcgoAAAAAdm4ydm46IHBvcnQgMHgleCBkaWQ6MHgleCV4 -JXggVVAKAAAAAAAAAAAAAAAAAAAAdm4ydm46IHBvcnQgMHgleCBkaWQ6MHgleCV4JXggRE9XTgoA -AAAAAAAAAAAAAAAAZmNfc2VuZF9hbGxvY19jcGw6IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1 -cGxlCgAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0ZV9jdHVwbGUgMHgleDoleAoAAAAAY29tcHV0 -ZV9jdHVwbGUoKTogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAA -AGZjb2VfY29tcHV0ZV9jdHVwbGUgdmxhbiAleCB2aWlkICV4IHBvcnQgJXggbXBzX2lkeCAleAoA -AAAAAAAAAABBQlRTIEFDQyBhd2FpdGluZyBQUkxJIFJzcDogZmxvd2NfaWQgMHgleCBveF9pZCAw -eCV4IHJ4X2lkIDB4JXggaXFpZCAweCV4CgAAAAAAAHBvcnQgMHgleCwgc3RhdGUgMHgleCwgY29t -bWFuZCBmYWlsZWQgcmV0cmllcyAweCV4CgAAAAAAAAAAAAAAAABHb3QgQ09OTl9FWElTVCBmb3Ig -eGlkOjB4JXgsIHRhZzoweCV4LCByZXRyeWluZy4KAAAAAAAAAAAAAAAAAAAAY2hfcmF0ZVsldV06 -IGNhcHBlZCB0aWNrIGZyb20gcmVxdWlyZWQgJXUgdG8gc3VwcG9ydGVkICV1OyByYXRlICV1IChl -ZmYgJXUpIGRlZmljaXRfaW5jciAldSB0aWNrICV1CgAAAAAAAAAAAAAAAHBrdHNjaGVkX2NoX3Js -WyV1XTogY2hhbm5lbCBybCBub3QgYXZhaWxhYmxlIGluIGNvbmp1bmN0aW9uIHdpdGggZmxvdyBz -aGFwaW5nCgAAcGt0c2NoZWRfY2hfcmxbJXVdOiByYXRlICV1IG1heCAldQoAAAAAAAAAAAAAAAAA -cGt0c2NoZWRfY2xfd3JyWyV1OiV1XTogd2VpZ2h0ICV1CgAAAAAAAAAAAAAAAAAAZXFfcGFyYW1z -WzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1IHBmICV1IGVxaWRfYXBpICV1IHJldCAlZAoA -AAAAAAAAAAAAAAAAAABod19tYV9hZGRyX3RvX21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUw -OHggaXMgbm90IG1hcHBlZAoAAAAAaHdfbWFfYWRkcl90b19tZW1fdHlwZV9vZmY6IE1BIGFkZHJl -c3MgMHglMDh4IG1hcHMgdG8gdHlwZSAldSBvZmZzZXQgMHgleAoAAAAAAABtZW1fbWFsbG9jX3Rl -bXA6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAbWVtX21h -bGxvYzogZmFpbGVkIHRvIGFsbG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAAAAAAAA -AGxlIGNvbmZpZ3VyYXRpb246IGhhc2ggbW9kZSByZXF1aXJlcyBhdCBsZWFzdCAxNiBlbnRyaWVz -LCBuaGFzaCAldQoAAAAAAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBtb2RlIHJlcXVp -cmVzIGF0IGVudHJpZXMgdG8gYmUgYSBwb3dlciBvZiAyLCBuaGFzaCAldQoAAABsZSBjb25maWd1 -cmF0aW9uOiByZXF1ZXN0ZWQgJXUgdGNhbSBlbnRyaWVzIGJ1dCBvbmx5ICV1IGF2YWlsYWJsZSAo -bnJvdXRlICV1IG5jbGlwICV1IG5maWx0ZXIgJXUgbnNlcnZlciAldQoAAAAAbGUgY29uZmlndXJh -dGlvbjogdGNhbSByZWdpb25zIG11c3QgaGF2ZSBtdWx0aXBsZSBvZiAzMiBlbnRyaWVzLCBucm91 -dGUgJXUgbmNsaXAgJXUgbmZpbHRlciAldSBuc2VydmVyICV1CgAAAAAAAGh3X3RwX3RjcF90dW5p -bmdzOiB0dW5pbmcgZm9yIGNsdXN0ZXIgZW52aXJvbm1lbnQKAAAAAAAAAAAAAAAAAABod190cF90 -Y3BfdHVuaW5nczogdHVuaW5nIGZvciBMQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5n -czogdHVuaW5nIGZvciBXQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczogbWFudWFs -IHR1bmluZwoAAAAAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBzdGFy -dAoAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogZHN0IDB4JTA4IG9mZnNldCAweCUw -OHggc2l6ZSAldSwgd2lkdGggb2YgJXUgaXMgbm90IHN1cHBvcnRlZAoAAAAAAAAAAAAAAABfaHdf -Y2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBlbmQKAAAAAAAAAAAAAAAAAABjb25maWd1cmF0aW9u -IGZpbGUgcGFyc2VyIGVuY291bnRlcmVkIGVycm9yIEAgbGluZSAldToKAAAAAAAAAAAAZmNvZSB4 -Y2hnIG1nciBpbml0OiBOdW1iZXIgb2YgZXhjaGFuZ2VzIGZvciBGQ29FIGlzICV4CgAAAAAAAAAA -AGZjb2VfbDJ0X2luaXQ6IE5vIHVscHR4IGNyZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2VfbDJ0 -X2luaXQ6IGNoOlsldV0gbDJ0X2lkeCBbJXVdCgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVzIGNv -bmZpZ3VyZWQ7IGZvcmNpbmcgJXUgZW50cmllcywgc3RhcnRpbmcgYXQgJXUKAABkY2J4X2llZWVf -Y29uc3RydWN0WyV1XSBldHMgJXUgcGZjICV1IGFwcCAldQoAAABkY2J4X3RpbWVvdXRbJXVdCgAA -AAAAAAAAAAAAAAAAAGRjYnhfcnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9J -RUVFCgAAAAAAAAAAAAAAAAAAAABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFU -RV9SVU5fQ0VFCgBkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fTk9O -RQoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gbGluayB1cCAoJXUpIChzcGVlZCAlI3ggYWNhcHMg -JSN4IGxwY2FwcyAlI3gpCgAAAAAAAAAAAHBvcnRfaHNzX3NpZ2RldFsldV06IGhzc19zaWdkZXQg -Y2hhbmdlZCB0byAweCV4CgAAAAAAAAAAAAAAAAAAAABRU0ZQIG1vZHVsZSB1bnBsdWcgLSByZWlu -aXRpYWxpemluZyByeF9sb3MgIHRvIDB4ZmYKAAAAAAAAAAAAAAAAZ3Bpb19xc2ZwX21vZHVsZV91 -cGRhdGU6IGNoYW5nZWQgcnhfbG9zIGZyb20gMHgleCB0byAweCV4CgAAAAAAAGdwaW9fcXNmcF9t -b2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHR4X2RpcyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABod19z -Z2VfbWFtZW1faW5pdDogZW5jb3VudGVyZWQgZXJyb3IgJWQKAAAAAAAAAABfaHdfdHBfcGdtbmd0 -OiB0eF9wYWdlX21heCAldSByeF9wYWdlX21heCAldSBwc3RydWN0cyAldSBzaXplICV1CgAAAAAA -AAAAAAAAAAAAAG1wYXJ0aXRpb25fb3RoZXJzX3RvdGFsOiBtZW0gJXUsIGRkcCAldSBkZHBfaXNj -c2kgJXUgc3RhZyAldSBwYmwgJXUgcnEgJXUgcnF1ZHAgJXUgLT4gJXUKAAAAAAAAAF9tcGFydGl0 -aW9uX2JhbmtzX21jWDogbmJhbmtzX3BtdHggJXUgKCV1TUIpIG5iYW5rc19wbXJ4ICV1ICgldU1C -KSBuYmFua3Nfb3RoZXJzICV1ICgldU1CKSBuYmFua3NfZncgJXUgKCV1TUIpCgBfbXBhcnRpdGlv -bl9iYW5rc19tYzE6IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1C -KSBuYmFua3NfZncgJXUgKCV1TUIpCgAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tYzA6IG5iYW5r -c19wbXJ4ICV1ICgldU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1CKQoAAAAAAAAAAAAAAG1lbV9t -YWxsb2NfaW50ZXJuYWw6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJuaW5nIE5V -TEwKAAAAAAAAAAAAAAAAAAAAaHdfZWRjX2Jpc3RbJXVdOiBiaXN0X2NtZFsweCUwOHhdIGFkZHIg -MHgleCBsZW4gMHgleAoAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1XTogZG9uZSwgZW5jb3VudGVy -ZWQgJXUgZXJyb3JzIG9uIGZpcnN0IGFuZCAldSBlcnJvcnMgb24gc2Vjb25kIGF0dGVtcHQgKCV1 -Z2JwcykKAG1lbV9pbml0X2NhY2hlczogY2FjaGVfc2l6ZSAldSBmbG93Y19idWZfdGNiX2NhY2hl -X3NpemUgJXUgYnVmbGw2NF9jYWNoZV9zaXplICV1CgAAAAAAAAAAAAAAAAAAAHF1ZXVlc19wZXJf -cGFnZTogcGYgJXUgaGFzIGEgYmFyc2l6ZSBvZiAldS1ieXRlcywgb2NxX3NpemUgJXUKAABzZ2Ug -cmVxdWlyZSBuZXEgJXUgbmlxICV1IHJvdW5kaW5nIHRvICV1ICV1CgAAAABtcGFydGl0aW9uX3Bt -dHg6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX3Btcng6IG0gMHgl -MDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX2VkYyAobm8gZXh0bWVtKTogbSAw -eCUwOHggc2l6ZSAldQoAAABtcGFydGl0aW9uX2VkY19lc3RpbWF0ZTogaHcgbW9kdWxlcyByZXF1 -aXJlICVkIGJ5dGVzIGluIEVEQwoAAAAAZm9pc2NzaV9jb3JlX2J5ZTogYWN0aXZlIHNlc3NfY250 -ICVkCgAAAAAAAAAAAAAAcG9ydFsldV0gcmVzZXR0aW5nIEtSCgAAAAAAAAAAAABjeDRfY3JfbW9k -dWxlX3J4X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgBwZm4gJXUgdmZuICV1IGhhcyBw -bmR0eG5zICV1IGFmdGVyIDEwMG1zCgAAAAAAAABwZm4gJXUgdmZuICV1IGNvbXBsZXRlIGltbWVk -aWF0ZQoAAAAAAAAAAAAAAAAAAABiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBv -cGNvZGUgMHgleCA+IExBU1RDMkUgMHgleAoAbWFpbGJveCBjbWQgbm90IHlldCBzdXBwb3J0ZWQ6 -IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHgleAoAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4 -JXggdmZuIDB4JXg7IG9wY29kZSAweCV4IGlzIHZhbGlkIHBvc3QgZGV2aWNlIGluaXQgb25seQoA -YmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JTAyeCByYW1hc2sg -MHgleCBjbWQgcmFtYXNrIDB4JXgKAABiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4 -OyBvcGNvZGUgMHglMDJ4IGxlbjE2IDB4JXggdmVyc3VzIGV4cGVjdGVkIGxlbjE2IDB4JXgKAAAA -AAAAAABpbnN1ZmZpY2llbnQgY2FwcyB0byBwcm9jZXNzIG1haWxib3ggY21kOiBwZm4gMHgleCB2 -Zm4gMHgleDsgcl9jYXBzIDB4JXggd3hfY2FwcyAweCV4IHJlcXVpcmVkIHJfY2FwcyAweCV4IHdf -Y2FwcyAweCV4CgAAAAAAAAAAAGluc3VmZmljaWVudCBjYXBzIHRvIHByb2Nlc3MgbWFpbGJveCBj -bWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2NhcHMgMHgleCB3eF9jYXBzIDB4JXggcmVxdWlyZWQg -cl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAAAAAAAAAAZG93bmxvYWRfc3JhbTogZXJyb3IsIHJl -dCAlZAoAAABkb3dubG9hZF90Y2FtOiBlcnJvciwgcmV0ICVkCgAAAFZQRCByZWdpb24gaXMgdG9v -IHNtYWxsIChTRVJDRkdfU1JfUEZOVlBEU0laRSAweCV4KQoAAAAAAAAAAAAAAABjZl9wcmVwOiBl -cnJvciwgcmV0ICVkCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC -AAABIAAAAAAAAACCAAABAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG -gIAAAAAAAAAAAAAAAACAAAAAAAAAAAACgAAAAAAAAAAAAAIAAwAAAAABYAgAAAAAAwAAAAAAAAAA -AAAAAwAAAAAAAAAAAAAAAgAAAAAAAAAAACAAAAAAAAAAAAAAAAEAA4AAAAAAAAAAAAAAAgAAAAAA -AAAAACADgAAAAAAAAAAAABACgACAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAoAA -AAAAAAAAAAAAAgAAAAAAAAAAAAAAAoAAAAAAAAAAAAEAAwAAAAAAAAAAAAACgwAAAAAAAAAAABAC -gAAAAAAAAAAAADAAAwAAAAAAAAgAADAAAwAAAAAAAAAAADAFgwAAAAAAAAgAADAFgwAAAAAAAAAA -ADAEgwAAAAAAAAgAADAEgwAAAAAAAAAAADADAwAAAAAAAAgAADADAwAAAAAAAAAAADgDAwAAAAAA -AAAAADgFgwAAAAAAAAAAADgEgwAAAAAAAAAAADgAAwAAAAAAAAAAADQGggAAAAAAAAAAADwDggAA -AAAAAAAAADwAAwAAAAAAAAgAADwAAwAAAAAAAAAAADwEgwAAAAAAAAAAADwFAwAAAAAAAAAAAD0E -AwAAAAAAAAAAADwDgwAAAAAAAAAAACwAAgAAAAAAAAAAACwFggAAAAAAAAAAACwFAgAAAAAAAAAA -ABAGgAAAAAAAAAAAABAGgsAAAAAAAAAAABAGgoAAAAAAAAAAAAAOggAAAAAAAAAAABAHgoAAAAAg -AAAAAAAHggAAAAAgAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAAAAAHAgAA -AAAgAAAAABAXgwAAAAAAAAgAABAXgwAAAAAAAAgAABAAAAAAAAAAAAAAABAGA4AAAAAAAAAAAAAO -AwAAAAAAAAAAABAGA0AAAAAAAAAAABAGAwAAAAAAAAAAABAGAAAAAAAAAAAAAAAGA4AAAAAAAAAA -AAAGAwAAAAAAAAAAAAAOAgAAAAAAAAAAAAAOAgAAAAAAAAAAABAGAgAAAAAAAAAAABAGAgAAAAAA -AAAAABAGAoAAAAAAAAAAABAGAoAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAIAAAAAAAAAAAAQAwAAAAAAAAgAAAAAAAAAAAAAAAAAAP////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////wAAACAAAAAA -wAAAAAAAACAAAAAA4AAAAAAAAAACAAAAAAAAAEAAAAAAAAAAAAAAAAAAASEAAAAAAAAAAAABASAA -AAAAAAAAAAAAAgAAAAQABAAAAAAFAAAABAAAAAAAAAAAAKAAAAAAgAAAAACAAEAAAAAAAAIAAACA -ACAAAAAAAAIAAAEAQAAAAAAAAAAAAAEAQgAAAAAAAAAAAAAAIAAAAAAAAAAAAAIQIAAAAAAAAAAA -AAIMAgAAAAAAAAAAAACFAgAAAAQAAAAAAACAQgAAAAAAAAAAAAIAIgAAAAAAAAAAAACAQQAAAAAA -AAAAAACAQYAAAAAAAAAAAAIAIQAAAAAAAAAAAAAQIIAAAAAAAAAAAAIlAIAAAAAAAAAAAAAFAAAA -AAAAAAAAAAiIBIAAAAAAAAAAAAiIBIAAAAAAAAAAAAiiAIAAAAAAAAAAAAiiAIAAAAAAAAAAAAij -AIAAAAAAAAAAAAijAIAAAAAAAAAAAAikgIAAAAAAAAAAAAikgIAAAAAAAAAAAASkgMAAAAAAAAAA -AASiAMAAAAAAAAAAAASjAMAAAAAAAAAAAASIBMAAAAAAAAAAAAAJAYAAAAAAAAAAAAIMAIAAAAAA -AAAAAACIBMAAAAAAAAAAAACIBIAAAAAAAAAAAAILAIAAAAAAAAAAAACKgIAAAAAAAAAAAAALgIAA -AAAAAAAAAACMAIAAAAAAAAAAAAIgEIAAAAAAAAAAAAIKAIAAAAAAAAAAAAIKgIAAAAAAAAAAAAAJ -AoAAAAAAAAAAAAABAQAAAAAAAAAAAAABAUAAAAAAAAAAAAABAIAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAIAAAAAAAAAAAAAAgRAAAAAAAAAAAAAAgQgAAAAAAAAAAAAAgQQAAAAAAAAAAAAAgYAAAAAA -AAAAAACAAMAAAAAAAAAAAACAAKAAAAAAAAAAAAAACAAAAAAAAAAAAACBgAAAAAAAAAAAAACBgIAA -AAAAAAAAAACJgIAAAAAAAAAAAACJgMAAAAAAAAAAAAABggAAAAAAAAAAAAIBgAAAAAAAAAAAAAIB -gIAAAAAAAAAAAABBgYAAAAAAAAAAAAIBgYAAAAAAAAAAAABJgYAAAAAAAAAAAAIJgYAAAAAAAAAA -AAIBgQAAAAAAAAAAAABBgQAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAIBAAAAAAAAABAAAAIAAAAA -AAAAABAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////wAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAACACSAAAAAAAAAANmACAAQAAAAAAIAJIAAAAAAAAAA3IBJQRAAAAAAAAAAAAA -AAAAAAADlgAgAEAAAAAACAAAAAIAiAOHAABWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAAA -AAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAA -AAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABA -AAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YA -IABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAIA -A5YAJgRAAAAAAAhHIAEEAAACsgAC0gUgJEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAARyABBgyh -grBAAZIEICRAAAAAAABHIAEEDKBCs4ACEgUgJEAAAAAACAAAAAIAiAOFAACWASAAQAAAAAAIAAAA -AgCIA4UAAJYBIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAN -xRK6ArCA0xRUi+JKRiRAAAAAAAXFEroCt4DTFFSLYkmmJEAAAAAABcUSogawgNMUVIviSkYkQAAA -AAANxRKiBreA0xRUi2JJpiRAAAAAAAXFEqIGsIDTFFSL4kpGJEAAAAAADcUSoga3gNMUVItiSaYk -QAAAAAAFxRKiBrCA0xRUi+JKRiRAAAAAAA3FEqIGt4DTFFSLYkmmJEAAAAAACcQQoAIAgJAAAIti -acYkQAAAAAABxBCgBrCAkwZUi2JpxiRAAAAAAAHEEKAGsICTBlSLYmnGJEAAAAAAAcUQuAawgJMW -VItiSMYkQAAAAAAIoRCIAgCBWBIAC1IApiRAAAAAAAnAEJACsIADFlSKkgHGJEAAAAAACcAQuAaw -gAMQlIviAkYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAAAAnAELgCtIADEJSLYgGmJEAAAAAACcAQ -uAK0gAMQlItiAaYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAAAAGgEJAGtIADEJSLYgGmJEAAAAAA -AcAQgAKwgAMUVIpSAMYkQAAAAAABwBCAArCAAxRUilIAxiRAAAAAAAHAEIACsIADFFSKUgDGJEAA -AAAACEcgAQQAAAKyAALSBSAkQAAAAAAAgQAAAgCFWAdAC1IApiRAAAAAAACBAAACAIVYB0ALUgCm -JEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAAAAAABgChgABAAVYAIABAAAAAAAAAAAAEAKBAAYAB -1gAgAEAAAAAACIEAAAIAhVmABAtSAKYkQAAAAAAJYUAAAAAAGAAAA0IBJqRAAAAAAAAAAAAAAAAA -AAADlgAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIAAAAAgCIA4cAA9YAJgRAAAAAAAgAAAAC -AIgDhwAD1gAmBEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAAA -AAAEAKBAAYAB1gAgAEAAAAAACcAQuAK0gAMQlItiAaYkQAAAAAAAAAAAAAAAAAIAA5YAJgRAAAAA -AAAAAAAAAAAAAAADlgAgAEAAAAAACAAAAAIAiAOFAACWASAAQAAAAAAAAAAABACgQAGAAdYAIABA -AAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIoRCIAgCBWBAACRIB -piRAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAYAoYAAQAFWACAAQAAAAAAIAAAAAgCIA4VA -CNICRiRAAAAAAAnFEqIClIjSEICLIkimJEAAAAAAAcAQgAakiAEFVItSAMYkQAAAAAAJwBCAAqSI -AIVUi1IAxiRAAAAAAAnAEIAGtIgDARSLUgGmJEAAAAAADcAAAAKwgMMWVIviA0YkQAAAAAAAAAAA -AAAAAAAAA5YAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAgAMAAEAAAAAgAAAgAmJEAAAAAAAEcwAAYDIAK3AAgCAcAkQAAAAAAIAwAAAgagCrUA -CAIAxiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAAACBQAAQAAAACAAACACYkQAAAAAAIYCAAhAAA -AAAAAAYAIABAAAAAAAhgIACEAAAAAgEwAgAmJUAAAAAACGAAAAQAhAGABAQCAcYkwAAAAAABwAAA -AkOAAwIMiAIBpiRAAAAAAAgAYAAEAAAAAgAAAgAmJEAAAAAACABgAAQAAAAAAAAEASAAQAAAAAAA -AAAAAAAAAAAAAAQBIABAAAAAAAQIFIAGCgAABwFMAiCmJkAAAAAACIAAAAYAhAGABAgCAaYmQAAA -AAAAQAAAAgCgAAJACAIBpiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAABAAAAAKEAAMCiggCBKYk -QAAAAAAAAAAAAAAAAAIAAAYBIEhAAAAAAAAgUAAEAAAAAgAAAgAmJEAAAAAACGAgAIQAAAACAAAG -ACYEQAAAAAAIYCAAhAAAAAIAAAIBJiVAAAAAAAhgAAAEAIQBgAQEAgHGJMAAAAAACABgAAQAAAAA -AAAEASAAQAAAAAAAAAAAAAAAAAAAAAIAJkxwAAAAAAAAAAAAAAAAAAAABgEgAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAABwAAACLSQBAkWBAIExiRAAAAAAAHAAAAItJAECRYEAgTGJEAA -AAAABAh0gEwJAABQAFwCYeYkQAAAAAAMCHSARAAAAFIAQAJhJiRAAAAAAAgCEKAEAAAAAAEAAgAm -JEAAAAAACAIQoAQAAAAAAQACACYkQAAAAAAECHQAQgEAAAcAiAJgxiRAAAAAAA3IFAACCQAABECc -AmDmJEAAAAAACcgQgAa0kAQClIgCZcYkQAAAAAANyHQASLSQAwCUiAJgpiTAAAAAAA3IdABItJAD -AJSIAmCmJMAAAAAACEcAAAQAAAAAAAACASAkQAAAAAAIRwAABAAAAAIAAAIFICRAAAAAAABHIAEM -ByHCtwAIAgHAJEAAAAAAAEcgAQwHIcK3AAgCAcAkQAAAAAAARyABDAchwrcACAIBwCRAAAAAAAAA -IAEIAIQABUCIAgHGJMAAAAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAAACABCACEAAVAiAIBxiTAAAAA -AAAAIAGGggABAsCIAgPGJMAAAAAAAAAgAYKCAAACwIgCA8YkwAAAAAAJwCABgqSAAQVAiAIBxiTA -AAAAAAgAAAAMAIQABUCIAgHGJMAAAAAAAAAgAYaCAAECwIgCA8YkwAAAAAAAACABgoIAAADAiAIC -piTAAAAAAAnAIAGCpIABBUCIAgHGJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAIAAAABAAEJBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFtnbG9iYWxdCnJzc19nbGJfY29u -ZmlnX21vZGU9YmFzaWN2aXJ0dWFsCnJzc19nbGJfY29uZmlnX29wdGlvbnM9dG5sbWFwZW4saGFz -aHRvZXBsaXR6LHRubGFsbGxrcApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVnWzB4MTAw -Y109MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQwOTYKcmVn -WzB4MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJlZ1sweDEw -NTRdPTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2MF09ODE5 -MgpyZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEwMDBhMDAwLzB4ZjAwMGYwMDAKcmVn -WzB4MTBhOF09MHgyMDAwLzB4MjAwMApzZ2VfdGltZXJfdmFsdWU9NSwxMCwyMCw1MCwxMDAsMjAw -CnJlZ1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZDZjXT0weDAwMDAwMDAw -LzB4MDAwMDcwMDAKcmVnWzB4N2RjMF09MHgwZTJmODg0OQpmaWx0ZXJNb2RlPWZyYWdtZW50YXRp -b24sbXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBvcnQsZmNvZQpmaWx0ZXJNYXNrPXByb3RvY29s -LGZjb2UKdHBfcG1yeD0zNAp0cF9wbXJ4X3BhZ2VzaXplPTY0Swp0cF9ucnhjaD0wCnRwX3BtdHg9 -MzIKdHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4Y2g9MAp0cF9tdHVzPTg4LDI1Niw1MTIsNTc2 -LDgwOCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIsMjA0OCw0MDk2LDQzNTIsODE5Miw5MDAwLDk2 -MDAKcmVnWzB4MTkxNjhdPTB4MDQwMjAxMDAKW2Z1bmN0aW9uIjAiXQpudmY9MTYKd3hfY2Fwcz1h -bGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9 -OApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIxIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJf -Y2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21h -c2s9YWxsCnBtYXNrPTB4MgpbZnVuY3Rpb24iMiJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9 -YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFs -bApwbWFzaz0weDQKW2Z1bmN0aW9uIjMiXQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApu -dmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1h -c2s9MHg4CltmdW5jdGlvbiI0Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MjgKbmlxZmxp -bnQ9MTcwCm5ldGhjdHJsPTEwMApuZXE9MjU2Cm5leGFjdGY9NDAKY21hc2s9YWxsCnBtYXNrPWFs -bApuZXRob2ZsZD0xMDI0Cm5yb3V0ZT0zMgpuY2xpcD0zMgpuZmlsdGVyPTQ5Ngpuc2VydmVyPTQ5 -NgpuaGFzaD0xMjI4OApwcm90b2NvbD1uaWNfdm0sb2ZsZCxyZGRwLHJkbWFjLGlzY3NpX2luaXRp -YXRvcl9wZHUsaXNjc2lfdGFyZ2V0X3BkdQp0cF9sMnQ9MzA3Mgp0cF9kZHA9Mwp0cF9kZHBfaXNj -c2k9Mgp0cF9zdGFnPTMKdHBfcGJsPTEwCnRwX3JxPTEzCltmdW5jdGlvbiI1Il0Kd3hfY2Fwcz1h -bGwKcl9jYXBzPWFsbApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjQKbmV4YWN0 -Zj00CmNtYXNrPWFsbApwbWFzaz1hbGwKbnNlcnZlcj0xNgpuaGFzaD0yMDQ4CnRwX2wydD0xMDIw -CnByb3RvY29sPWlzY3NpX2luaXRpYXRvcl9mb2ZsZAp0cF9kZHBfaXNjc2k9Mgppc2NzaV9udGFz -az0yMDQ4CmlzY3NpX25zZXNzPTIwNDgKaXNjc2lfbmNvbm5fcGVyX3Nlc3Npb249MQppc2NzaV9u -aW5pdGlhdG9yX2luc3RhbmNlPTY0CltmdW5jdGlvbiI2Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFs -bApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjYKbmV4YWN0Zj0zMgpjbWFzaz1h -bGwKcG1hc2s9YWxsCm5oYXNoPTIwNDgKdHBfbDJ0PTQKcHJvdG9jb2w9ZmNvZV9pbml0aWF0b3IK -dHBfZGRwPTEKZmNvZV9uZmNmPTE2CmZjb2VfbnZucD0zMgpmY29lX25zc249MTAyNApbZnVuY3Rp -b24iMTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNrPWFs -bApuZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fw -cz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9 -YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52 -aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNr -PTB4MgpbZnVuY3Rpb24iMi8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52aT0xCm5pcWZs -aW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPTB4NApbZnVu -Y3Rpb24iMy8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0 -aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPTB4OApbcG9ydCIwIl0KZGNi -PXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2Jf -YXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVy -dHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMSJdCmRjYj1wcHAs -ZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90 -bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUs -MwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0IjIiXQpkY2I9cHBwLGRjYngK -YmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBd -PTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNi -X2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIzIl0KZGNiPXBwcCxkY2J4CmJnX21l -bT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5 -MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBf -dGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNpb249MHgxNDI1MDAxYwpjaGVja3N1 -bT0weDVjZWFiNDFlCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbZ2xvYmFsXQpyc3NfZ2xiX2NvbmZpZ19tb2Rl -PWJhc2ljdmlydHVhbApyc3NfZ2xiX2NvbmZpZ19vcHRpb25zPXRubG1hcGVuLGhhc2h0b2VwbGl0 -eix0bmxhbGxsa3AKcmVnWzB4MTAwOF09MHg0MDgxMC8weDIxYzcwCnJlZ1sweDEwMGNdPTB4MjIy -MjIyMjIKcmVnWzB4MTBhMF09MHgwMTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sweDEwNDhd -PTY1NTM2CnJlZ1sweDEwNGNdPTE1MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0XT05MjE2 -CnJlZ1sweDEwNThdPTIwNDgKcmVnWzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIKcmVnWzB4 -MTA2NF09MTYzODQKcmVnWzB4MTBhNF09MHhhMDAwYTAwMC8weGYwMDBmMDAwCnJlZ1sweDEwYThd -PTB4MjAwMC8weDIwMDAKc2dlX3RpbWVyX3ZhbHVlPTUsMTAsMjAsNTAsMTAwLDIwMApyZWdbMHg3 -ZDA0XT0weDAwMDEwMDAwLzB4MDAwMTAwMDAKcmVnWzB4N2Q2Y109MHgwMDAwMDAwMC8weDAwMDA3 -MDAwCnJlZ1sweDdkYzBdPTB4MGUyZjg4NDkKZmlsdGVyTW9kZT1mcmFnbWVudGF0aW9uLG1wc2hp -dHR5cGUscHJvdG9jb2wsdmxhbixwb3J0LGZjb2UKZmlsdGVyTWFzaz1wcm90b2NvbCxmY29lCnRw -X3Btcng9MzAKdHBfcG1yeF9wYWdlc2l6ZT02NEsKdHBfbnJ4Y2g9MAp0cF9wbXR4PTUwCnRwX3Bt -dHhfcGFnZXNpemU9NjRLCnRwX250eGNoPTAKdHBfbXR1cz04OCwyNTYsNTEyLDU3Niw4MDgsMTAy -NCwxMjgwLDE0ODgsMTUwMCwyMDAyLDIwNDgsNDA5Niw0MzUyLDgxOTIsOTAwMCw5NjAwCnJlZ1sw -eDE5MTY4XT0weDA0MDIwMTAwCltmdW5jdGlvbiIwIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApu -dmk9MjgKbmlxZmxpbnQ9MTcwCm5ldGhjdHJsPTk2Cm5lcT0yNTIKbmV4YWN0Zj00MApjbWFzaz1h -bGwKcG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbnJvdXRlPTMyCm5jbGlwPTMyCm5maWx0ZXI9NDgK -bnNlcnZlcj0zMgpuaGFzaD0wCnByb3RvY29sPW5pY192bSxvZmxkLHJkZHAscmRtYWMsaXNjc2lf -aW5pdGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1CnRwX2wydD0zMDcyCnRwX2RkcD0yCnRwX2Rk -cF9pc2NzaT0yCnRwX3N0YWc9Mgp0cF9wYmw9NQp0cF9ycT03CltmdW5jdGlvbiIxIl0Kd3hfY2Fw -cz1hbGwKcl9jYXBzPWFsbApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjYKbmV4 -YWN0Zj0zMgpjbWFzaz1hbGwKcG1hc2s9YWxsCm5oYXNoPTAKcHJvdG9jb2w9ZmNvZV9pbml0aWF0 -b3IKdHBfZGRwPTIKZmNvZV9uZmNmPTE2CmZjb2VfbnZucD0zMgpmY29lX25zc249MTAyNApbZnVu -Y3Rpb24iMTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNr -PWFsbApuZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJf -Y2Fwcz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21h -c2s9YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2 -Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBt -YXNrPTB4MgpbcG9ydCIwIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209 -MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2Fw -cF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVt -LDUKW3BvcnQiMSJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3 -bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2 -WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltw -b3J0IjIiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUK -ZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0w -eDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIz -Il0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0z -MApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0 -LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNp -b249MHgxNDI1MDAxYwpjaGVja3N1bT0weGFkNGMxNzRmCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -==== diff --git a/sys/dev/cxgbe/firmware/t4fw-1.16.63.0.bin.uu b/sys/dev/cxgbe/firmware/t4fw-1.16.63.0.bin.uu new file mode 100644 index 000000000000..8908a057fe58 --- /dev/null +++ b/sys/dev/cxgbe/firmware/t4fw-1.16.63.0.bin.uu @@ -0,0 +1,9567 @@ +/*- + * Copyright (c) 2017 Chelsio Communications, Inc. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + */ +begin-base64 644 t4fw +AAAEJgEQPwAAAQkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAABAkEGAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IEZyaSBTZXAgIDggMTA6 +MTg6MzMgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j +dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDR4eCAwMS4xMC4zZi4wMAAAAAAAAAAAAAAAABRhxKxg +AMgA4QB78AAQAADhADC4eP///x/84UCAAAAB4QB7cAAAEAAf//4A4QGUcCAAAADhAZwE4QB5AAAC +AEDhAHmAAAYAQAACAAoABgAK4QB5BAAMAACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA +AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//jhAAAAAA +H/+OFAAAAAAf/44YAAAAAB//jhwf/8AAAAAAAAAAAADAABL/zRP/zZMgEv/NE//NhCAEMwGTIBH/ +zBL/zJIQEf/MEv/MkhAR/8wB9DER/8siCv+SEADkMQAFMQECABL/yALnMQIWABH/x4EQAQFfwCEC +EQHJERH/xBL/xJIQEf/EEv/EkhBgAA8R/78S/8OSEBH/vxL/wpIQgRAR/8HAIJIREv/AkhLAIJIT +Ev+/khCCEALyUGUv9xH/vccvkhAR/7ySEBL/vBP/vJMgwDKTIRP/u5MigiIS/7oT/7qTICMiIRT/ +uQQzAck4E/+4gzADgxQIMxEU/7akM5MhE/+qkyJgAAjCMJMhE/+nkyIS/7GQIJAhkCKQI5AkkCWQ +JpAnkCiQKZAqkCuQLJAtkC6QLyAmECAmEYIiEv+kwDAtNzAtNzQtNzgtNzwjPQFyM+0AAgAS/6HA +MC83AC83EC83IC83MCM9AXIz7QACABL/l8AwKDcwKDc0KDc4KDc8Iz0BcjPtEv+VwDAnNwAnNxAn +NyAnNzAjPQFyM+0S/5AV/5AW/5HAMNcgBWYBYAAZAAAAAAAAAAQ2BQACANMP0w8FMwxuOxQHRxQH +BEN2MeYENgUFMwxvO+0AAgAS/4MV/4EjCgACJwIHBEMEPgUFMwwHRxRvO/ADAgAS/33JLoMghCGF +IrwidDsOhlC0VZYwtDN0M/Rj/+YAZT/iZV/fEv9xwDIDLgUDAgAS/2jAMCg3QCg3RCg3SCg3TCM9 +AXIz7QACABL/ay0nAMARAUkxAEgxAQIAwAAU/2gE0jEV/2eUUBT/ZwTTMRX/ZpRQFP9mBNQxFf9m +lFAU/2UE1TEV/2WUUBD/ZQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA +H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/4AAH/+FsOMACfgf/4WwH/+FsOMAD6gf +/4WwH/+FsOMAD6gf/4WwH/+HWOMAD6gf/4dYH/+OEOMAEVAf/44QH/+v4OMAGAgf/6/gH/+v4OMA +Odgf/8AAH//+7eMAOdggAAAAIAABauMAeMggAAF4IAABfOMAejQgAAF8IAABheMAejggAAGYIAAB +nOMAekQgAAGcIAABpeMAekggAAG4IAABvOMAelQgAAG8IAABxeMAelggAAHYIAAB2OMAemQgAAHc +IAAB4uMAemQgAAH4IAAB+OMAemwgAAH8IAAB/OMAemwgAAIYIAACGOMAemwgAAIcIAACHOMAemwg +AAI4IAACOOMAemwgAAI8IAACPOMAemwgAAJYIAACWOMAemwgAAJcIAACYuMAemwgAAJ4IAACeOMA +enQgAAJ8IAACguMAenQgAAKYIAH5KeMAenwgAwAAIAMXMOMCcRAgAxcwIAMXMOMCiEAgAxcwIAb7 +tOMCiEAgBvvAIAb/MOMGbNAgCAAAIAgS0OMGcEAgCBLQIAksJuMGgxAgCSwwIAks/OMHnHAgCwAA +IAsAAOMHnTwgCwAAIAsAAOMHnTwgCwAAIAt0COMHnTwAAAAAAAAAAAAAAAAgABQWIAAUCCAAF/Ig +ABQIIAAXbSAAFAggABS6IAAXBSAAFoogABQIIAAWOSAAFfIgABWFIAAT9SAAFS8gABQIIAAUCCAA +FAggABTaAAAAAP///////w/8///w////APwgALbmIAC4WiAAuIogALhQIAC4ESAAuAcgALfWIAC3 +zCAAt8AgALdvIAC4iCAAt2UgALc1IAC4iiAAtysgALcZARAYAQAEAAAAAAAAAAAAAAACAgUFCAgL +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 +H/+AsB//rFBnRSMB782riZi63P4QMlR2H/+AAAAAPyggAxBcz////yALBfAQAAAAP////wIAAABA +AAAAGgAAAB/84HQgoAAAH/+naCAAHeAgAB98gAAAAAAAgAD//v//AAAQAABAAAAgADqUIAAi5CAA +AAAgACNIIAsIwP//f///+///D/aAACALCPAgCwkgAAEAAAAEAAAf/6fYIAtRYCALCbAgADSoIAA1 ++CAAMtwgCwtQIAsKECALCqAgADEkIAsK8FMAAAAA////UgAAAFEAAAAgAek0H/+l4AAA//8gBAv4 +H/+piCAAOfgf/6mwIAsLcB//mMQf/6lUIAsNkBQAAACAAAACfFAAAIAAABCAAAAGgACwAAAACgAA +/zSS///wD4AAsQDhAZoAAAIAACALDSAf/5Y4AAB+QCALDWAf/6mEAP/AAAEAAAAoAAAA4AAAACYA +AAAf/48gBgAAAAWAAAAf/6U4KwAAACAAVZggC1OwH/+nBAOAAAAH////BAEACDUAAAADAAAAAD// +/4BAAAAID///H////wAAwAAf/6loPQAAAB//lLAHAAAAgQQBAIEEAAAf/6lAAAA6mMMAAAAAAA// +AEMAAB//psgAAAgABAAAACALVBAf/68UH/+tYB//lBAABgAA4QB6AB//lIAf/6l0H/+Y1B//mMAg +C1RAAAMHgCALVLAIAAAAH/+WoAAgAAAAAAkAAAAwAv/8+H/AAAAAo/+7AKP/ugANAAAA4AMAAIP/ +tgAP////D//4AP8AAAAgC1TwIAsO0CALDwAgC1WAAA8AAAAKAAD//wAPA//AAIP/wAAgC1YAIAtW +cB//qlgf/63Q/2DwAB//rbAf/44gBIAACB//gFAARAAA/x///wDAAAABgMIAAAICAOEAAADhAOAA +AACBAPAAAACBgAAA/3///x//pBT/v/////8AAACAAAAAAIbdH/+aHB/84gAf/48Q7gAAAAAACcwf +/OIMDwAAACALD0Af/6n4AAAIzB//qwQf/5qYH/+UrB//gGAgBv1gAAAwAAAAJxAf/9zwIAtdICAL +XPAf/6pkH/+UpAAA//4f/5i03q2+7yADCCA0AAAAPwAAAB//qzQAAIkGAJkAAB//rNgQAAcCAcCA +AJkAAAAf/6ugAIgACIKAAAEf/60o///wAAMVAAADEQAAAA8D/yAA8BQgAPQAKQAAAAAAiRQgAPjU +IAMLRAAAQAAgAw5wDAAAACABA7gf/63wAAAfkCADC1Qf/6rgH/+r+B//qYz/AP8A8PDw8KqqqqrM +zMzMH/+liAAD//8AACf/IAMLmCALXXAgARQQAA9CQCADXVAf/6ooAAkAAAAASACCAAAAIAEocB// +qdw7AAAIDgAAANAAAAAf/4CgAAAgegAACFAAAB9AH/+plCALHoAgCx6gIAsewAAJAAgf/60kMAAA +AH8AAAAgCyHgAAAP/iALIRAgCyFwIAshsAAA4AD///f/IAsicCADY5wAAIP/IAcDaBWgAAAgBwRg +H/+s6AAACAYAAIjMH/+WUAAEA/8KAAAAIAb/+CAHAZggBwBAH/+ZYIP/twCD/7YgIAsioDMAAAAf +/6zwH/+t5AP/4AB///8AAD/2kAAAIIgD//AAIAtIMCALR/AgC0hQH/+u8B//rOwAD///H/+q8B// +qZAgC2EQH/+Y9CAAcuggBvzoIAAFiB//pGAf/5XMH/+UTB//qMQgCyMgwAQAAB//p4Af/6d0H/+n +jB//raAf/60UIAPlMCALI2AgAw8gH/+ljCAAc8jgAQAAH/+aICALYkAgCyOgH/+aGCAAszAgALAw +IAthwCALYhAf/5ZwIAslsOD//gAgC0rQH/+aJCALMIAf/47kH/+QnB//qYAf/62UIAs88CALPSBI +AAAAIAG8CB//pxQgAb4MH/+VAB//pewf/6TkH/+n1B//pKwAABhAAAAWTB//p+QgBv90H/+lNB// +lIThAC4AH/+n8OEAXgDhAg4A//+//+EADgDhAY4A//++/x//mLwf/6W8IAHDOCABz2DgBQAAA/8A +AB//pPQgAw54H/y//zwAAAAABf//gwAAAB//pOwPPAAAIAtHsCAB76wgAfKoH/+qdCAB9mAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAACBgAAAAAAAAP////////////////////8f//zoH//86B///LAf//ywH//8sB// +/LAf//Y4H//5YB//97wf//e8H//3vCAG03gAAAAAAAAAAAAAAAAAAAAAIAbWwCAG1sAAAAAAAAAA +AAAAAAAAAAAAIAbTeCAG03gf//pUH//6VB//+lQf//pUH//6VB//+lQAAAAAIAHEUAAAAAAAAAAA +AAAAAAAAAAACAQAAAAAAAAAAAAAAAAAABAAAAAAAAACBgAAAAAAAEAUAAAAAAAAEAAAAAAAAAAAA +AAAAAAAAAIEAAAAAAAAYBQAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +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 +oBHIgQAA6bYAIVDhAACaOJs5mS/4YWYVoAIFANEPAAAAAAAA6iQAAlhhAAD8ACIdoA1FAFv/YGP/ +rwAA//twDaALBQDAoFk7phxj4orI+V/7OJIAnQD//igNoAsFAMCwwNoNrTT9gQYV7/3uAAAAAGwQ +BGQg1mQw02RQ0Ioix43oqAEFeDiAAPhARhWgAGIAAADIrlk+BNug+kBoHa/89QBb+vb4x5QF52QB +AOdjyxMlkQAADGgRp4gqgp7pawoB6H0AAPt36BXk3R0A/UAEo+IAnQAqgp3TDwuqAWSgcRxjzR5j +0+wABQ1ABIAAbdkCCAJhGGPMmKCPIJ1Qk6PupgIv/gKAAA/fAu+mASUQQQAA0Q8AH2Owjvhq4U8M +aBGniCqCnulrCgHofQAA+3foFeTdHQB9o1Yqgp0LqgHkoE9nY/0AAJz4Za+UYAADwCDRD9og+oMA +FeAMBQBb/xfAINEPAAD//dANoAoFAMCgWTtcH2OYjvjpY5UXDosAAPxj4BXgCgUA//70DaTdHQDA +oMCKCOg0+eEGFa/+ugAAAAABEBgBAAEAAAAAAAAAAAAAIANWWyADVr0gA1ZIIANWvSADVkggA1a9 +IANWXyADVl8gA1alIANWjSADVnYAAAAAIANfgiADX4IgA12VIANfgiADXZUgA19fIANfNyADXZUg +A15pIANdlSADXZUgA15gIANdlSADX4IgA12VIANdlSADX4IgA12eAwEAAgAAAAAgBNArIATRHSAE +0b0gBNArIATRtSAE0ZYgBNArIATQKyAE0CsgBNF4IATQKyAE0CsgBNArIATQKyAE0CsgBNArIATR +aCAE0VsgBNArIATQKyAE0CsgBNArIATQKyAE0CsgBNArIATQKyAE0CsgBNArIATQKyAE0CsgBNAr +IATQKyAE0FIgBNArIATQTCAE0EwgBNArIATQTCAE0EwgBNE1IATQTAAAAAAAAAAAAAAAACAE8lYg +BPJWIATxCiAE8lYgBO3FIATyTCAE8iggBO3FIATtxSAE7cUgBO3FIATtxSAE8O4gBPJWIATtxSAE +8O4gBPJWAAAAAAAAAAAAAAAAIAUBoyAFABwgBQQTIAUD0yAFA5sgBQNdIAUDOyAFAHAgBQMXIAUC +2yAFAoMgBQItIAUB4yAFAbsBEBgBAAIAAAEQGAEAAgAAAAAAAAAAAAAgBa+3IAWrTCAFr4sgBa9f +IAWvMiAFrx0gBatzIAWriiAFrwQgBau/IAWrqyAFq3MgBau/IAWrcyAFq3MgBatzIAWvtwAAAAAA +AAAAAAAAAAAAAAAgBfuMIAX0qCAF9FQgBfHoIAXuGAAAAAAAAAAAIAX0kSAF9I0gBfSNIAX0jSAF +9JEgBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0 +jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSN +IAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0g +BfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0kSAF +9I0gBfSNIAX0jSAF9JEgBfSNIAX0jSAF9I0gBfSRIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0 +jSAF9JEgBfSNIAX0jSAF9I0gBfSRIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9JEgBfSN +IAX0jSAF9I0gBfSRIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9JEgBfSNIAX0jSAF9I0g +BfSRIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9JEgBfSNIAX0jSAF9I0gBfSRIAX0jSAF +9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0 +jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSRIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSN +IAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSRIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0g +BfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF +9I0gBfSRIAX0jSAF9I0gBfSNIAX0kSAF9I0gBfSNIAX0jSAF9JEgBfSNIAX0jSAF9I0gBfSNIAX0 +jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSN +IAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0g +BfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF +9I0gBfSNIAX0jSAF9I0gBfSNIAX0jSAF9I0gBfSNIAX0kQAAAAAAAAAAAAAAACAF9N0gBfU3IAX4 +TCAF+D4gBfgpIAX4GyAF+AAgBffyIAX31yAF98ogBfe3IAX3qiAF95cgBfeKIAX3dyAF9NkgBfdj +IAX3ViAF90MgBfc1IAX3ICAF9xYgBfcFIAX3FiAF9wUgBfb3IAX24iAF9NkgBfTZIAX02SAF9Nkg +BfbVIAX09iAF9NkgBfTZIAX02SAF9rggBfafIAX2lSAF9oQgBfTZIAX2cSAF9lcgBfZEIAX2KiAF +9hcgBfX/IAX17CAF9dkgBfV4IAX02SAF9NkgBfTZIAX02SAF9NkgBfTZIAX1RSAF9S0gBfUVAAAA +ACAF+9cgBfvhIAX92iAF/bQgBf2tIAX9piAF/Z8gBf2YIAX9kSAF/YogBf2DIAX9eSAF/W8gBf1U +IAX9LSAF/QUgBfz8IAX83iAF/NQgBfzHIAX8tyAF/LAgBfyaIAX8kyAF+8ggBfxsIAX8YiAF/Fgg +BfxRIAX8SiAF/DogBfwCIAX7+yAF+/QAAAAAAAAAAAAAAAUAAAAFAAAACgAAAAoAAAAKAAAACgAA +AAoAAAAKAAAACgAAAAoAAAAKAAAAACAGolAgBp+kIAaeOCAGm9QgBplwIAaMaCAGjwggBpfQIAaL +BCAGmjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlKAMPCBKlqIOOk5IAAAAAUlYAABAAAABjb25m +aWd1cmF0aW9uIGZpbGUgcGFyc2VyIGZvdW5kIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiBhZnRl +ciBbZmluaV0KAAAwAAAAZmNvZQAAAAB2bmljX2lkAHZsYW4AAAAAdG9zAGV0aGVydHlwZQAAAG1h +Y21hdGNoAAAAAG1wc2hpdHR5cGUAAGZyYWdtZW50YXRpb24AAABwZl92ZgAAAG91dGVyX3ZsYW4A +AGJhc2ljdmlydHVhbAAAAABnbGJfa2V5AGdsYnZmX2tleQAAAHBmdmZfa2V5AAAAAGlkeHZmX2tl +eQAAAHN5bm1hcGVuAAAAAHN5bjR0dXBlbmlwdjYAAABzeW4ydHVwZW5pcHY2AAAAc3luNHR1cGVu +aXB2NAAAAHN5bjJ0dXBlbmlwdjQAAABvZmRtYXBlbgAAAAB0bmxtYXBlbgAAAAB0bmxhbGxsa3AA +AABoYXNodG9lcGxpdHoAAAAAbGFuAHdhbgBjbHVzdGVyAG1hbnVhbAAAdHBfcGlvAAB0cF90bV9w +aW8AAABuaWNfdm0AAG5pY191bQAAbmljX3VtX2lzZ2wAbmljX2hhc2hmaWx0ZXIAAG9mbGQAAAAA +cmRkcAAAAAByZG1hYwAAAGlzY3NpX2luaXRpYXRvcl9wZHUAaXNjc2lfdGFyZ2V0X3BkdQAAAABp +c2NzaV9pbml0aWF0b3JfZm9mbGQAAABpc2NzaV90YXJnZXRfZm9mbGQAAGZjb2VfaW5pdGlhdG9y +AABmY29lX3RhcmdldABwb2Zjb2VfaW5pdGlhdG9yAAAAAHBvZmNvZV90YXJnZXQAAABpc2NzaV90 +MTBkaWYAAAAAaXNjc2lfaW5pdGlhdG9yX2NtZG9mbGQAaXNjc2lfdGFyZ2V0X2NtZG9mbGQAAAAA +dGxza2V5cwBjcnlwdG9fbG9va2FzaWRlAAAAAHBwcABkY2J4AAAAAGIyYgBzb2NrZXRudW0AAABj +ZWUAaWVlZQAAAABhdXRvAAAAAGFuX2RpcwAAcGRsaXRlX2RpcwAAIAMW0AAEAAAAAAQAAAQAAAAA +AAAAAAAAAAAAACAGisgAAAAAIAaKICAGh7AgBoaIIAZmwCAGArAgBe1wIAXsWAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAACAEYYwgBG6IIARuiCAEboggBH6AIASWOCAEpnggBLAEIAReeCAEW+ggBFIE +IATPACAET7QgBEx8IAXsLCAF6wQgBeRIIARuiCAF43AgBeIEIAXhOCAG2fAgA7zMIAQcoCAGrKwA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACADVHQgAz2EIANN3CADS1AgA0nUAAAAACAD +R3wgA1OoAAAAACAEQ4AAAAAAAAAAAAAAAAAAAAAAAAAAACAGxzQgBsZEIAbiCCAGxjQgBsZwIAbF +UCAGxxwgBsTgIAbh+CAGxiD/GDBgYAAAAAABAgMAAAAAAAAAAAAAAAAgBqL4IARf2CAAbkQAAAAA +AAAAgQAAAAAAAAAAAAAAAAABAgMCAgMDAAIDBQMDBQUgBDd8IAQ5ACAEOKAgBDkUIAQ3mAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBDgsAAAAAAAAAAAAAAAAAAAADAAAAA0AAAAOAAAADwAA +ABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAAAAAAAAEAAAA +BAAAAAgAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAA +AgAAAAQAAAAIAAAA////////8AD////////gAP///////8AA////////gAD///////8AAP////// +/gAA///////8AAD///////gAAP//////8AAA///////gAAD//////8AAAP//////gAAA//////8A +AAD//////gAAAP/////8AAAA//////gAAAAwMTIzNDU2Nzg5YWJjZGVmQUJDREVGAAAAAAAAAAAA +AEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIz +NDU2Nzg5Ky8AAAAAAAAAAAAAAAAAAAAAIAAhfAABAAAgACFcAAUAASAAIUAAAwAFIAAhIAAHAABj +glNjAAAAAP///////wAAACYaCwoIKzJBAkRAAy0AAAAAAAgAAAAFAAAABwAAAAAAAACIAAAAhQAA +AIcAAAAAAAAAQAAAAQAAAAKAAAAAAAAEBAgABAQIAAQECAAAAAAAAAAAAAAAgAAAAgAAAAKAAAdD +AAAAAAAAAAAAAAAAAP////////////////////8AIQAJAIEAQQAhAAkAIQAJAIEAQQCBAEEAgQBB +AIEAQQAhAAkAgQBBACEACQAhABEAgQBBAIEAQQAhAAkAgQBBACEACQAhAAkBAQBBAIEAIQCBACEA +EBBhAQEAgQEBAIEDAgEABAAAAAAAAAAAAAAAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAAAAAA +AAAgAwhwAAAAACADEIgAAAAAIAMIdAAAAAEgAxD0AAAAAiADCHwAAAAEIAMIhAAAAAggAwiMAAAA +ECADEPwAAAAgIAMIkAAAAEAgAwicAAAAgCADCKgAAAEAIAMItAAAAgAAAAAFAAAAAwAAAAEAAAAC +IAamYCAGphQgBqUEIAajwCAGo4AgBqNYIAajqAAAAAAAAAIAAAAEAAAACABZZXMAMDEyMzQ1Njc4 +OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6AAAAAG5vbmUAAAAAYWxsACoAAABkaXNhYmxlZAAA +AABlbmFibGVkADB4AABOQQAAVjAAAFYxAABWMgAAVjMAAFY0AABWNQAAVjYAAFY3AABWOAAAVjkA +AFZBAABWQgAAVkMAAFZEAABWRQAAVkYAAHBvcnQAAAAAcHJvdG9jb2wAAAAAZ2xvYmFsAABmdW5j +dGlvbgAAAABmaW5pAAAAAHJlZwBmaWx0ZXJNb2RlAABmaWx0ZXJNYXNrAAB2bmljTW9kZQAAAABy +c3NfZ2xiX2NvbmZpZ19tb2RlAHJzc19rZXltb2RlAHJzc19nbGJfY29uZmlnX29wdGlvbnMAAHNn +ZV90aW1lcl92YWx1ZQB0cF9wbXJ4AHRwX3BtcnhfcGFnZXNpemUAAAAAdHBfcG1yeF9mbGFncwAA +AHRwX25yeGNoAAAAAHRwX3BtdHgAdHBfcG10eF9wYWdlc2l6ZQAAAAB0cF9udHhjaAAAAAB0cF9t +dHVzAHRwX3RjcHR1bmluZwAAAAB0cF90aW1lcnJlcwB0cF90aW1lcnZhbHMAAAAAdHBfYmFja29m +ZnZhbHMAAHNjaGVkX2lvcXR4X2JwX3ByaW9yaXR5AG52ZgB3eF9jYXBzAHJfY2FwcwAAbmlxZmxp +bnQAAAAAbmVxAG5ldGhjdHJsAAAAAG52aQByc3NudmkAAHJzc25zZWNyZXQAAG5leGFjdGYAbnJh +d2YAAABjbWFzawAAAHBtYXNrAAAAbmV0aG9mbGQAAAAAbnJvdXRlAABuY2xpcAAAAG5maWx0ZXIA +bnNlcnZlcgBuaGFzaAAAAHRwX2wydAAAdHBfZGRwAAB0cF9kZHBfaXNjc2kAAAAAdHBfc3RhZwB0 +cF9wYmwAAHRwX3JxAAAAaXNjc2lfbnRhc2sAaXNjc2lfbnNlc3MAaXNjc2lfbmNvbm5fcGVyX3Nl +c3Npb24AaXNjc2lfbmluaXRpYXRvcl9pbnN0YW5jZQAAAGlzY3NpX21heF9zZ2UAAABwcG1fbWF4 +X3pvbmVzAAAAcHBtX3pvbmVfcmFuZ2UwAHBwbV96b25lX3JhbmdlMQBwcG1fem9uZV9yYW5nZTIA +cHBtX3pvbmVfcmFuZ2UzAGZjb2VfbmZjZgAAAGZjb2VfbnZucAAAAGZjb2VfbnNzbgAAAGZjb2Vf +bmZjYgAAAGRjYgBkY2JfYXBwX3RsdgBkY2JfZGNieF9wcm90b2NvbAAAAGJnX21lbQAAbHBia19t +ZW0AAAAAaHdtAGx3bQBkd20AZGVib3VuY2V0aW1lAAAAAGFuX2FlY190aW1lAGFlY19yZXRyeV9j +bnQAAAB2ZXJzaW9uAGNoZWNrc3VtAAAAAFNlc3Npb25UeXBlAE9GTWFya2VyAAAAAElGTWFya2Vy +AAAAAERhdGFEaWdlc3QAAEhlYWRlckRpZ2VzdAAAAABFcnJvclJlY292ZXJ5TGV2ZWwAAEltbWVk +aWF0ZURhdGEAAABEYXRhUERVSW5PcmRlcgAARGF0YVNlcXVlbmNlSW5PcmRlcgBJbml0aWFsUjJU +AABNYXhDb25uZWN0aW9ucwAATWF4UmVjdkRhdGFTZWdtZW50TGVuZ3RoAAAAAEluaXRpYXRvck5h +bWUAAABJbml0aWF0b3JBbGlhcwAARGVmYXVsdFRpbWUyV2FpdAAAAABEZWZhdWx0VGltZTJSZXRh +aW4AAE1heEJ1cnN0TGVuZ3RoAABGaXJzdEJ1cnN0TGVuZ3RoAAAAAE1heE91dHN0YW5kaW5nUjJU +AAAAVGFyZ2V0TmFtZQAAVGFyZ2V0QWxpYXMAVGFyZ2V0QWRkcmVzcwAAAFRhcmdldFBvcnRhbEdy +b3VwVGFnAAAAAEF1dGhNZXRob2QAAFNlbmRUYXJnZXRzPUFsbABDSEFQX0EAAENIQVBfSQAAQ0hB +UF9DAABDSEFQX04AAENIQVBfUgAARGlzY292ZXJ5AAAATm9ybWFsAABOb25lAAAAAENSQzMyQwAA +Q1JDMzJDLE5vbmUATm9uZSxDUkMzMkMAQ0hBUAAAAABDSEFQLE5vbmUAAABOb25lLENIQVAAAABO +b3RVbmRlcnN0b29kAAAASXJyZWxldmFudAAAUmVqZWN0AABObwAANQAAAENITmV0IDEuMDAAAAAA +AAwAAAAAAQABfAAMAQAAAAAQAAAAFCAG9xAAAAMVDkAAAB/8AAAf/AAAH/+v4B//r+AgBv8wIAcE +oCAJLQAgCS0AIAoAACAKgAAgCoAAIArmgB//qbAgCwAAIAsAMB//rPQf/45gAA///x//p8Qf/N4A +H/+sQAQAAAiBAAAAGgAAAB//rLwgCwCAIAb/gIP/twCAAAAAAAD//4P/tiAgC0iQH/+qKB//rNgf +/6hgH/+plB//rFAwAAAQIAtI0CALSTAf/65UH/+n6B//kLThAZYAIAcEYCAHAmQgAwggF5AAABSw +AAAAAGAAIAcDgIAAAAQgBwRqAAAgegAAg/8VoAAAIAMAABagAAAIUAEAIKAAAD/wAAAjoAAAA/8A +HwDAAAQf/65YIAbVCCoAAAAgA0M0IAtJYCALSaAgBtTM3q2+/xrAAAAgBwNoAAD/6iAHBHAAAAgU +AACIAAAAgAAf/6mAH/+qCAAAJxAAHoSAAABAACADXVAf/6sEABAAAB//p8gf/6sYIAMAECALSmAg +C0owAQAAACgAAADhAAAAOAAAAP8///8wAAB0H/+AsCADAEAgCwDQMAAACDAAAAw0AAAI0AAAAA4A +AAAAAIkUOwAACCAHAng0kAAAIAMKJCAHAYAFXUqAIANjnAAYAAD/B///ADgAAAAwAAAgC0qAAAQA +AAAIAAAAAwAAAAAIAOEBjgAAAZEMIAtLgCALSzAgC0uw///z/yALS2AgCwJwAABADgAAQBogCwKg +AAAQAAAA/+kAAP/gAABQAAAA//gAAEAN///wAAAA//cAAA//AAAPQgAA//UAEwAHAAAgQAAAIAAA +AMQQAADAAQAAyCAgCwMAIAsDIAAAxAAAAMgAAADEMAAAxDEAAhAI4P/+ACALA0D///f/AADoACAL +A2AAAMgQAADERQAAEAEAACB8AAAyAAAAzAAAAknvAAJJ8OEAXgDhAC4AAAIAAABAAAAAgAAAAAEA +AAgAAAAf/OB0AgAAAP/3//8ATEtAIAPjrCADx6T//f//H/+qZB//qYwPPAAAIAA2bA8AAAAgBA6o +IAsFACALBTAgCwWAIAsFUB//gnAf/4NgIAsFoCADDjAgAw2wIAMNkAAPQkAgACGoIAQL+CALBjAg +BAh4AP///yALBlAgBAZAIAtPICALBnAgCwbQIAsHICAD3DwgCwagIAPhcPf///8gCwdQH/+n2B// +juQgBv1gAA/8AB//lfQf/5Ss//8H/wAAMABVAAAAEAAAACALT1AgAw6oAAAIBgAAD/4gA77AIAPC +rB//qdggA6+4IAO4pOAAAABAAAAAAADwAB//qewf/5CcAMAAAB//p9AgBwMw7/////9///8gCweQ +/f///yADxSQgAw6gIAb/4CAHABAf/6mIH/+C0B//g9AgAxBgH/+CsD/////P////H/+DjH///6v/ +/y5cAADRpP//0E0AAJxOH/+CzAwAAAAAAEgAIAMOdB//gsgf/4MwIAsH4B//qeAgACNIIAQCVCAL +TwAgBvJ0IAHvRCAB8qggADqUIAAJ+B//qGwgC1BQIAtQoCALUSAgA+UwIAtQ8CAD63QgA69wIAtR +QB//lXQD/9AACUAAABBQB/8AUAf/IAtP4CALUBAgC0+wIAtPcCAD/HT//0AAIAsIUCALCCAf/6mQ +IAPkSCALCJAEAQAIACAAAAOAAAAEAAAAIAQGjCAD/yQAABdwIAMK5CALUkAgC1HwIAtR0CAEHpwg +C1GgIAtSICADClQf/6l8IAMKxCALC8DhAhYA4QIaAP//yP///xf///8f/wACGRwAAhl8AAIZnAAC +Gfwf/6mc///x/wACGQDAAAAAAAIaJAACGqQAAhooAAIaqAACGjQAAhq0AAIaMAACGrDhAg4AAAAT +hyADDNQgAwzEBAAAAeECEgAAACHBIAsMEAACEOD//7//AAIcIOEAegAgCwxAH/+n8CALDGAgCwyQ +IAsMsB//puwgCwzgH/+lpOEAfgAFAAAAgAAAHYAAAAqAAAAMgAAAG4AAAB8gAwwwH/+oAB//qZgA +APP/FAAAACAEQSwf/5Bo4AAJJACcAAAgCw3AIAsOoCALDnAgC1NwIAsOQB//mYAgCw4AAAIEwOEC +AgDhAI4AAACWgAAAlkAgBv8wAACWoAAAlmDhAgAs//8AAAAB4ADhAZIAAAHjAAYAAAAgBFPc+AAA +AAH//+cAAcAAIAAAgB//kKwEABAAH/+ltOEBmgDhAZpA4QGaPOEBmjjhAZo04QGaMB//qoAgAwpc +IAMKbCADCmQgAwp0gAAAA4AAAAL//P//4QEOAH////8f/5BMH/+QzCAEYYwgC1bgIAtXICALV1Ag +C1eQIAtXwCALWAAgC1gwIAtYcA////D/8AAAIAtY0B//lcgf/61AH/+ktCAEboggC1nQIAtaACAL +WXAgC1kQH/+XjAAA/4Af/47gIAsPgCALD7D/+///4QHiwB//pjThAf4AkAAA8Pz/gMACAAAg/v+A +wCALEAAgCxBAAAD4AAACAQgAAgEMj////x//p/ThAZgAIAsQkCALEOAgCxEQIAsRUOEA3gAAAgMI +AAICAOEA7gD//3//AAD8AB//qbgAAOAAAAAMACALEaAAAgMEH/+poAABERwAAREYIAtaoAAQCACA +AAgAH/+U9P//wAAAAgEEAAD//gAAJYAAAgMAH/+n7OD/4sAgC1owH/+mmB//mYQgC1rwIAtbICAL +W0AAAP/9IAta0CADAIgAAP/zIAtbYCALW4AAACowIAtboAAA/48AAFK1AABICgAAj4IAAI+GAAA4 +AAAAj4oAAOM/AACDrgAA//EAcwADIAsR4P//z78AABBAIAtbwCALW/AAABIAIAsSECADDwAAAhkE +IAsSMP5s/4AgCxLAAAIWCH8/////7/////P///+f//8gCxJgIAsTECALE0AgCxOQAAD/+yADAJAg +C1yAIAsUMCALFAAAAP/vAAD/3wAA/78AAP9/AAD+/wAA/f8AAPv/AAD3/wAA7/8AAL//IAtcsCAL +FOAgCxSgIAsUcCALFQAgCxVQ7gAAAAHAgAAQAAUNCQAAAB//q6AgAwFAAACDACALFnAAAIIAIAsV +kCALFeAgCxYgEAAHAh//qCAgCxbQAAAMvAAAiQYgCxbwIAtJ4CIiIiIADAAAIAtSoCALUmAgAwGQ +IAsXUCALFyAgCxpAIAsaACALGcAgCxmAIAsZQCALGQAgCxiwIAsYcCALGCAgCxfQIAsXkCALXaAg +C13QIAteACALXkAgC16AIAtesCALG3AgCxsgIAsagCALGsAAAIDCAAAbISALG6AgC17gIAtfICAL +G8AgBv9gAP/AABIAAAAgBR+AIAscMCALHTAgCxzwIAsccCALHXAgAw4gIAUoPCALX0AAAB9AAAAQ +Nv//7/8f/65cH/+s6AAACFAgCx3QIAseICALHgAA///8MgAAAB//rtogAwHIM5AAACAHAmggC1+g +IAtgACALX+AgC2BAIAseQCADbnQgAwHQIAse8AAAgAUAAIAHIAsfIIGAAADerb7vIAsfYB//qYQA +AIP9MAAAHDAAAAQwAAAU//7//x//rZQA//AAACgAACALH5AAAAhAIAMJ5CALH8AA///6IAsgEDAA +AAAwAAA0AACAASADAeAAAIACIAV/OCALYNAQAAUQmQAAADQAAAAgC2CAIAsgUAAZAAAgCyCgIAMP +EAAAEg8gCyDQH/+lJB//rSQDFQAAg/8AGyALIuDhAZGsAAGRrAsAAAAgBLHoIAMKlB//l/gAATiA +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 +LtIcnjHRD2RPno9nj/4v8SqfMdEP6mAMKVgEgABYPfpkT4UuoDstoDrsS0UfRAKAAPmmAAwwGyUA ++GAmFaAKRQBYPsHAINEP+pQ2BeAKFQDpYA0iGuGAAGSS+C7S4o1gDt0MDVQUDkQRBMQMJE0I9IDI +FaSdAQAAkQTsSg0dQAqAAAhEAeSkOQlYBIAA/oBoHaAKVQBYPqz0YCYVoAIFANEPAAAAAAAAAGRO +/C9gDWTzfvJgJhWgAgUA0Q9kTukoYA1kg4LyYCYVoAIFANEPZE7WKWANZJMn8mAmFaACBQDRDwAA +AAAAZE6+KmANZKMp8mAmFaACBQDRD2ROqytgDeliCyWaoYAAsJz8YCYVoAIFANEPZE6RLWANZNNK +8mAmFaACBQDRD2ROfi5gDelhEicaGYAAsJ/+YCYV4AIFANEPZE5kKGANZIM68mAmFaACBQDRD2RO +USrC1inC1aqZsJmZMdEPZE5AK8LVmzHRD2RCJS1gXCxgXQjdEQ3MAvxgJhWgAgUA0Q9kTh0uYFAL +i0f/YAzjogCdAMf//mAmFeACBQDRD2ROAIhniI6Ij5gx0Q9kTfOJZ4meKpISKZIRqpmwmZkx0Q9k +Td6KZ4quKqIRmjHRD2RN0CzygCvyf6y7sLubMdEPZE2/LfJ/nTHRD2RNtY5nju4v4hQu4hOv7rDu +njHRD2RNoI9nj/4v8hOfMdEPZE2SiGeIjomOiI2piLCImDHRD2RNf4lniZ6JnZkx0Q9kTXKKZ4qu +K6IQiq+rqrCqmjHRD2RNXotni76MvIu7rLuwu5sx0Q9kTUuMZ4zOjMucMdEPZE0+jWeN3o7Yjdeu +3bDdnTHRD2RNK45nju6O554x0Q9kTR6PZ4/+iPaP9aj/sP+fMdEPZE0LiGeIjoiFmDHRD2RM/oln +iZ4r4XUqkTEpkTALqjaqmbCZmTHRD2RM44pniq4qoTCaMdEPZEzVi2eLvi3hcyyxLyuxLg3MNqy7 +sLubMdEPZEy6jGeMzizBLpwx0Q9kTKyNZ43eLtEtLdEsrt2w3Z0x0Q9kTJeOZ47uLuEsnjHRD2RM +iY9nj/4o8Ssv8Sqo/7D/nzHRD2RQ+NpgWB5UKGAMCIgR+UYADDCJBQAJiAL4YCYVoAIFANEPKmAM +KbCAAKAECQkbCQlA+GAmFeACBQDRD2RQvIsx+sQGHei7HQD6xCYd4AIFANEPjDFkwRYKnQL8wsYV +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 +AC0APABQAGQAyAEsAZAB9AAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAgACAAMAAwADAAMABAAEAAQA +BAAEAAUABQAFAAUABQAFAAYABgAHAAcAAAACAAAABgAAAAoAAAAOAAAAFAAAABwAAAAoAAAAOAAA +AFAAAABwAAAAoAAAAOAAAAFAAAABwAAAAoAAAAOAAAAFAQAABwAAAAoAAAAOAAAAFAAAABwAAAAo +AAAAOAAAAFAAAABwAAAAoAAAAOAAAAFAAAABwAAAAoAAAAOAAP8AAQICAAAAECBAAAAAAAAEAAIA +AQAAgABAACAAEAAIIECAAAAAAAAAAAAAAAAAACAIqdMgCKnTIAipkyAIqVsgCKksIAio7iAIqO4g +CKrgIAiq4CAIqO4gCKrgIAiq4CAIqO4gCKjuIAiopiAIquAgCKrgIAiq4CAIquAgCKrgIAiq4CAI +quAgCKrgIAiq4CAIquAgCKrgIAiq4CAIquAgCKrgIAiq4CAIquAgCKjPIAMLJAAAAAEgAwssAAAA +AiADEIgAAAD/IAMIcAAAAP8gAwsQAAAAAiADCxQAAAADIAMLHAAAAAcAAAAAAAAAACADCvQAAAAB +IAMK+AAAAAIgAwsAAAAABCADEIgAAAD/IAMIcAAAAP8AAAAAAAAAACADCHAAAAAAIAMQiAAAAAAg +AwnAAAAAASADCcgAAAAEIAMJ0AAAAAggAwncAAAAICADCewAAABAIAMJ9AAAAIAgAwn8AAABACAD +CgQAAAIAIAMKGAAABAAgAwosAAAIACADCkQAABAAIAMKWAAAIAAgAwpoAABAACADCnQAAIAAIAMK +iAABAAAgAwqYAAIAACADCqgAEAAAIAMKwAAgAAAgAwrYAEAAACADCuAAgAAAIAMJrAAAABAgAwm0 +AAAAESADCZQAAAAAIAMJmAAAAAEgAwmcAAAAAiADCaQAAAADAAAAAAAA//8AAAAAAAD//yADCRQA +AAEAIAMJIAAAAIAgAwkwAAAAQCADCUAAAAAgIAMJUAAAABAgAwlgAAAACCADCWwAAAAEIAMJeAAA +AAIgAwmEAAAAAQAAAAAAAAAAIAMIxAAAAAAgAwjMAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA +AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAHAAAABwAAAAYAAAAG +AAw1AAAQRqoAFFhVABhqAAAAK2gAACODAAAYagAADQYAAAsqAAAAAAAAAAAAAAAAAABoKwAAaCsA +AGyCAABvnAAASmgAAEpoAABNKQAASmgAAE7qAABMmAAAUj0AAE+4AAGGoAABhqAAAgjWAAII1gAC +CNUAAgjVAAKLCwACiwsAAgjVAAK2cgACtnIAAw1AAAQGBwAAAAAAAAAAAAAAAPLVEpjy1RKY8tUS +mPLVEpjy1RKY8tUSmPLVEpjy1RKY8tUSmPLVEpjy1RKYA4UbGAOFG5jy1RKY8tUSmPLVEpjy1RKY +8tUSmPLVEpjy1RKY8tUSmAAAAAAAAAAAAAAAAP//AAUABgAHAAgACQAKAAsADAANAA4ADwAQ//// +////AAAAMgAAA+gAAAAoAABOIAAAAAAAA9CQAJiWgAAPQkAAmJaAAAAcIAAAAEsAPQkAAAPQkACY +loABAQAAAwMCAgUFBAQHBwYGAAAAMgAAA+gAAABkAADDUAAAAAAAA9CQA9CQAABMS0AD0JAAAAAc +IAAAAEsAPQkAAA9CQCPDRgADAgEABwYFBAsKCQgPDg0MAAAAMgAAA+gAAAAKAAAB9AAAAAAAAAPo +AJiWgAAPQkAAmJaAAAAcIAAAAEsAPQkAAAPQkACYloADAgEABwYFBAkJCAgLCwoKAAAAAAAAAAAA +CgAUAIwAggBkAFoAoACWAHgAbgBQAEYAPAAyACgAHgAKBM4EkgnOCZICsgRWBOIEpgO2BBoHsglW +Bl4CdgniCaYHTgI6CLYJGggWBiICxgRqAJYDegFyB3YAvgPeBPYEugRCA6ICYgc6Bg4AggPKBC4A +bgBaAyoBNgHqAz4HxglqAUoHEgWWCHoGwgH+BnICigNSBeYFvgjeAZoH2gn2CboJfgeeCUIIogkG +AV4HYgJOByYDFgEiBYIIZgWqCMoJLgiOAQ4FbgVaBUYG1ggqBjYCEgHCBuoIPgDmBoYC2gR+Ap4E +BgZKAiYIAgNmAKoDjgX6AEYB1gb+Bq4F0gGGB4oI8gMCCFIA+gUyAa4A0gPyB+4AMgaaAu4FHgAe +BQoAAAnECYgE2AScB6gJTAnYCZwIrAkQArwEYAFoB2wE7ASwAlgHMAPABCQDIAEsB7wJYAWMCHAG +aAKABbQI1AnsCbAJOAiYB1gCRAEYBXgIwAkkBWQFUAggBiwG4Ag0AtAEdAZAAhwAoAOEAcwG9AF8 +B4AISADwAMgD6AaQAuQFAATEBIgCqARMA6wEEAZUAmwHRAIwCAwGGACMA3AAtAPUBDgDmAYEAHgA +ZABQAeADNAFABwgGuAH0A0gF3AGQB9AJdAeUCPwBVAccAwwIXAWgCIQBBAU8BswCCAG4ANwGfAKU +A/wH+ANcBfAAPAakBcgI6AL4BSgBpAfkACgFFAAUAAAEyQSNCckJjQKtBFEE3QShA7EEFQetCVEG +WQJxCd0JoQdJAjUIsQkVCBEGHQLBBGUAkQN1AW0HcQC5A9kE8QS1BD0DnQJdBzUGCQB9A8UEKQBp +AFUDJQExAeUDOQfBCWUBRQcNBZEIdQa9AfkGbQKFA00F4QW5CNkBlQfVCfEJtQl5B5kJPQidCQEB +WQddAkkHIQMRAR0FfQhhBaUIxQkpCIkBCQVpBVUFQQbRCCUGMQINAb0G5Qg5AOEGgQLVBHkCmQQB +BkUCIQf9A2EApQOJBfUAQQHRBvkGqQXNAYEHhQjtAv0ITQD1BS0BqQDNA+0H6QAtBpUC6QUZABkF +BQAACb8JgwTTBJcHowlHCdMJlwinCQsCtwRbAWMHZwTnBKsCUwcrA7sEHwMbAScHtwlbBYcIawZj +AnsFrwjPCecJqwkzCJMHUwI/ARMFcwi7CR8FXwVLCBsGJwbbCC8CywRvBjsCFwCbA38BxwbvAXcH +ewhDAOsAwwPjBosC3wT7BL8EgwKjBEcDpwQLBk8CZwc/AisIBwYTAIcDawCvA88EMwOTBf8AcwBf +AEsB2wMvATsHAwazAe8DQwXXAYsHywlvB48I9wFPBxcDBwhXBZsIfwD/BTcGxwIDAbMA1wZ3Ao8D +9wfzA1cF6wA3Bp8FwwjjAvMFIwGfB98AIwUPAAAACgCMAG4AlgB4ADwAUACgAIIAZAAyAEYAWgAo +AB4AFAAAAIcAaQCRAHMANwBLAJsAfQBfAC0AQQBVACMAGQAAAAAwBAAAMBAAAFkIAABZpAABlDAA +ABAkAAAQMAAAEDwAABDcAAB7LAAAezQAAeKMAAHmjAAB6owAAe6MAAHyjAAB9owAAfqMAAH+jAAA +jcwAAH50AACP3AABkVgAAI/8AAB1HAAAdRgAAHUQAAB34AAAd+QAAHf0AAGcPAABEHQAARCEAACU +CAAAmFwAAJYMAACWFAAAliAAAJYsAADQKAAAkAgAAhDcAAIw3AACUNwAAnDcAAGQVAAAYBwAAaDY +AAGQkAAAd+AAAHfkAAB39AAAeXgAAHn4AAGUBAAB48AAAefAAAHrwAAB78AAAfPAAAH3wAAB+8AA +Af/AAAGUDAAAMAA////AAAAwCD///8AAAFkQrIAAAAAAWax+JQAAAAGUEB////8AAZQ0AAAAEQAB +lAgf////AAGUOAAAABEAABAof////wAAECx/////AAAQNH////8AABA4f////wAAEEAPRAAAAAB7 +KAAf/+IAAHswP//u/wAAezgAAAABAAB7QD//7v8AAHwkAB//4gAB4ogACAAAAAHmiAAIAAAAAeqI +AAgAAAAB7ogACAAAAAHyiAAIAAAAAfaIAAgAAAAB+ogACAAAAAH+iAAIAAAAAI3I/////wAAjdD/ +////AAB+cH+///8AAH54f7///wAAfgACwAAAAAGRVAH///8AAZGcAf///wAAj9gAf//9AACP+P// +//0AAHUUAAAABwAAdQwAAAALAAB33AAAAAMAAHfw/////wABnDgAAYBAAAGc+AAAAAMAAJAEAAAA +PgABEHgA////AAEQfAD///8AARCIAAAAAAAAlAQAAP//AACUEAAA//8AAJhUAAAB/wAAmFgAAAH/ +AACWCAAAAAAAAJYQAB///wAAlhgAH///AACWHAAP//8AAJYkAA///wAAligA////AACWMAD///8A +ANAgAAAABwAA0CQAAAAHAAIQ2AAAAAMAAjDYAAAAAwACUNgAAAADAAJw2AAAAAMAAZBQAAAALwAB +oNQAAAGDAAGQjAA4AAAAAZCYADgAAAAAeXQAAAAvAAB5cAAAAAUAAHn0AAAALwAAefAAAAAFIAMR +JCAI2GwgAxEoIAjpaCADETQgCOiQIAMRQCAI59wgAxFMIAjnjCADEWAgCOaoIAMRbCAI5fggAxGE +IAjkkCADEZQgCON4IAMRnCAI41AgAxGwIAjjKCADEcAgCOL4IAMRzCAI4dwgAxHUIAjhtCADEegg +COGAIAMR9CAI4BQgAxH8IAjfbCADEgwgCN5oIAMSGCAI3VggAxIoIAjcUCADEjggCNskAAAAAAAA +AAAgAxJQIAjYNCADElQgCNe4IAMSXCAI14AgAxJkIAjXSCADEnAgCNcQIAMSdCAI1tggAxKAIAjW +oCADEoQgCNfwIAMSjCAI1mggAxKYIAjWMCADEqAgCNX4IAMSqCAI1cAgAxKwIAjS8CADErggCNVw +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 +//MAKXKZyZrAoVt0iaKpK5KAZ7ALbQgFLJKAZ8ACY//zKXKZJlavL3JmHOKqG+KqK1aq+rWGFeAK +JQAqVrIsVrOp/y9Wq/vgAERwDQUA+LWmFa/EBQDoVrEn+P0AAPXgBAewDhUAW3Q6iRQb4ov87MgV +78QFACmcPwSZAelWpCahaYAALrLjL7LmCe4MD+4Mse0O7Tse4uYNHRIO3TRm1HEvCmQP3yz/4AEH +8ApVAOzi4R/3AoAA7hYHL/+CgAD+IMYV4AsFAFuY5Ft0WxTi2iZG8ilCGypCGitCGSxCGC1CFy9C +FShCFC5CFihG86j/KEIfL0b0r+4uRvWu3S9CHC1G9q3MLkIeLEb3rLstQh0rRvirqixCKCpG+aqZ +K0IpKUb6qYgqQiooRvuo/ylCKy9G/K/uKEIsLkb9rt0vQi0tRv6tzC5CLixG/6y7LUIvK1aCq6os +QjAqVoOqmStCMilWhKmIKkIzKFaFqP8vVoYpQjav7i5WhyhCN67dLVaIrcwsVomsuytWiquqKlaL +qpkpVowkQjipiChWjahEJFaPW5Remh9blF0pUqYkUqctUqP5L+AV744FAO6ZAQIAaYAAL1KkD90M +DU02KFKhyI4JqBGomHjTB/i0xhWgABoAwJDpFhAklqmAACwSEGTDNx7iKixWky/izyrixejixicj +8wAALULv7uLHLVZCgADqyQgMRkKAAOjICA/+QoAAr8+fGZgY6BISL3ZCgADuzggO7kKAAP4hRhWk +rR0AbakFCACGCQJh+iJIFaa9HQBbc/ItQvDTD+kSCC7uQoAA+CJoFaStHQBtqQUIAIYJAmH6ImgV +pr0dAFtz6C1C8ekSCi7uQoAA+CKIFaStHQBtqQUIAIYJAmH6IogVpr0dAFtz3i1C9tMP6RIJLu5C +gAD4YGgdpK0dAG2pBQgAhgkCYfpgaB2mvR0AW3PUI1KjKlKnmhvqMwwLIASAAATkFgECANswW5sT +BOQWKgoBW3PHIxYAFOJTLxIL/cSiBaALhQD6IiYVoA0VAOT/CA1wBIAA/iGGFeAKVQBbmFDZYCoS +EYscDwIAoqIrJoEjJoImJoMJ5BYpFg0BAgAoIoME6jArGgJbc60I6jAsIojsFg4mAKmAAATqMPoi +KBWhCyUAW3OmCOowjR0N5BYEigxbc5vYoP4hyBWgClUA/cRmBaALhQDvIogpp0KAAAhELPQgBhWg +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 +AsAAQCAG3NAgAxDICMAARCAG2wQgAxDMCIAASCAG25QgAxDQGIAAXCAG25QgAxDUGIAAcCAG25Qg +AxDYGIAAhCAG25QgAxDcGIAAmCAG25QgAxDgGIAA/CAG25QgAxDkGIABDCAG25QgAxDoGIABHCAG +25QgAxDsGIABLCAG25QgAxDwCIABfCAG25RGQ29FIEREUCBmYWlsZWQgOiBveF9pZCAweCV4IHJ4 +X2lkIDB4JXgKAAAAAAAAAABGQ29FIEREUCBmYWlsZWQgOiBEZHBSZXBvcnQgMHgleCBEZHBWYWxp +ZCAweCV4CgBGQyB4Y2hnIGFsbG9jIGZhaWxlZDogYXZhaWwgJWQKAEZDT0UgRnJlZTogc3RpbGwg +eWllbGRlZCB3aGVuIGZyZWVpbmcuLi5mbG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAAAAAA +AAAAAAAAUFJMSSBSc3AgdGltZWRvdXQgOiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQg +MHgleCAKAAAAAAAAAGh3X2JjbTg0MzRfY2hlY2tyYW06IFN0YXJ0CgAAAAAAUEhZIHByb2Nlc3Nv +ciBub3QgcnVubmluZywgc3RpbGwgaW4gcmVzZXQgZm9yIDVtcywgcG9ydF9iaXRfbWFwPSV1IAoA +AAAAAAAAAAAAAABQSFkgRlcgaGFzIGJhZCBDUkMsIG9rX2NyYz0ldQoAAFBIWSBmaXJtd2FyZSBs +b2FkIHN1Y2Nlc3NmdWwhCgAAaHdfYmNtODQ4MzRfbG9hZHNlcXVlbmNlOiBTdGFydGVkCgAAAAAA +AAAAAAAAAAAAaHdfYmNtODQ4MzRfbG9hZHNlcXVlbmNlOiBVcGxvYWQgaW1hZ2UgdG8gUEhZIG9u +LWNoaXAgbWVtb3IKAAAAAGh3X2JjbTg0ODM0X2xvYWRzZXF1ZW5jZTogZG9uZSBsb2FkaW5nIGlt +YWdlIChpID0gJXUpCgAAAAAAAAAAAABod19iY204NDM0X2xvd3Bvd2VyWyV1XTogZW5hYmxlPSVk +CgAAAAAAAAAAAAAAAABod19iY204NDM0X2xvd3Bvd2VyWyV1XSwgZmFpbGVkIHRvIHNldCAzMC4w +eDQwMUFiaXQgNyBzaW5jZSAzMC4weDQwMEUgYml0PTEgYWZ0ZXIgNW1zLAlyZWc9JXgKAABod19j +bDQ1X2luaXRbJXVdIGFjYXBzICUjeAoAAAAAAGh3X2NsNDVfdXBkX3NwZF9hZHYgJSN4CgAAAAAA +AAAAaHdfYXExMjAyX2xpbmtfdXBbJXVdIHVwCgAAAAAAAABwWyV1XSBQSFkgT1ZFUkhFQVRFRCAt +IGZvcmNlZCBwb3dlciBkb3duICh0ZW1wPSVkKQoAAAAAAAAAAAAAAAAARkxBU0ggbm90IHJlYWR5 +OiBpICV1IG52clJlZyAlI3gKAAAAAAAAAAAAAAAAAAAAQVFfRkxBU0hfUmVhZHkgLSBUaW1lb3V0 +ICgxKQoAAABBUV9GTEFTSF9SZWFkeSAtIFRpbWVvdXQgKDIpCgAAAAlBUV9SZXR1cm5Db250cm9s +T2ZGTEFTSAoAAAAAAAAAc2V0X2RpZ2VzdDogQlAgYWxyZWFkeSBmYyAweCV4IGZsYWdzIDB4JXgK +AAAAAAAAc2V0X2RpZ2VzdDogY3NrIDB4JXggY29ubiAweCV4IHN0YXRlCgAAAAAAAAAAAAAAc2V0 +X2RpZ2VzdDogdXBsc3VibW9kZToleCwgcGdpZHg6MHgleCwgdmFsOjB4JXggYnVmZmVyZWQgMHgl +eAoAAHNldF9kaWdlc3Q6IGJ1Zl9sbF9mbHVzaCBmYyAweCV4IG5leHRfd3IgMHgleAoAAGlwdjZf +YWRkclswXSAweCV4IGlwdjZfYWRkclsxXSAweCV4CgAAAAAAAAAAAAAAAGFkZHIgJXMgcG9ydCAl +cyB0YWcgJXMKAAAAAAAAAAAAcmVkaXJlY3QgSVB2NiAweCV4LTB4JXgsIHBvcnQgJXgKAAAAAAAA +AAAAAAAAAAAAcmVkaXJlY3QgSVB2NCAweCV4LCBwb3J0ICV4CgAAAABhdXRoZW50aWNhdGVfdGFy +Z2V0OiBJbmNvcnJlY3QgcGFzc3dvcmQKAAAAAAAAAABDSEFQX0M6IGRpZ2VzdCBleHBhbnNpb24g +ZXJyb3IKAENIQVBfTjogVGFyZ2V0IHVzZXJpZCBtaXNtYXRjaAoAQ0hBUF9SOiBkaWdlc3QgZXhw +YW5zaW9uIGVycm9yCgByY3ZkX3BhcmFtczogZXJyb3IsIGxlbiAlZAoAAAAAAExvZ291dCBmcm9t +IHNlc3Npb24gWzB4JXhdCgAAAAAAaVNDU0kgU2VjLXBhcmFtcyByZWNlaXZlZCBoYXZlIGVycm9y +cyEhCgAAAAAAAAAAVGFyZ2V0IG1vdmVkIHRlbXAuIGNvbm4gJXgsIHNlc3MgJXgKAAAAAAAAAAAA +AAAATG9naW4gRmFpbGVkISEuIGNvbm5fZmMgWzB4JXhdLCBzZXNzX2ZjIFsweCV4XSwgc3RhdHVz +X2NsYXNzIFsweCV4XQoAAAAAAAAAAAAAAABQcm90b2NvbCBFcnJvciBjYml0ICVkIHRiaXQgJWQg +Y3NnICVkIG5zZyAlZAoAAABvZmxkX3J4X2RhdGE6IG1lbV9zaXplOiAweCV4LCBkbGVuIFsweCV4 +XSwgYWJvcnRpbmcgY29ubiAweCV4CgAAY2huZXRfbDJkZXZfdXBfbWJfY2I6IHJjIFslZF0sIHBv +cnQgWyV1XSwgc3RhdGUgWyV1XSwgY29va2llIFsweCV4XQoAAAAAAAAAAAAAAABsb2dpbl90aW1l +ZG91dDogQnJlYWtpbmcgcGF0aCBzIFsweCV4XSBjIFsweCV4XSBjc2sgWzB4JXhdCgAAAAAAcmVj +b3ZlcnlfdGltZW91dDogc2VzcyBpZCBbMHgleF0gaW4gbG9nb3V0CgAAAAAAZm9pc2NzaTogUmVj +b3ZlcnkgdGltZWQgb3V0IGFmdGVyIFsldV0gcmV0cnksIGJhaWxpbmcgb3V0CgAAAAAAAFRDUCBj +b25uIGVzdGFibGlzaG1lbnQgZmFpbGVkICVkCgAAAAAAAAAAAAAAAAAAAEludmFsaWQgb3Bjb2Rl +IDB4JXggaW4gY3RybCBwYXRoCgAAAAAAAAAAAAAAAAAAAEREUCBlcnJvciBbMHgleF0sIGFib3J0 +aW5nIGNvbm5uIFsweCV4XQoAAAAAAAAAAHJ4X2RhdGFfZGRwOiBSZXNwb25jZSByZWNpZXZlZCBm +b3IgdGFzayBbMHgleF0gd2hpbGUgaW52YWxpZCB0YXNrIG9yIGNvbm5lY3Rpb24gc3RhdGUuIHRh +c2sgc3RhdGUgWzB4JXhdLCBjb25uIHN0YXRlIFsweCV4XSwgY29ubiBmbGFncyBbMHgleF0KAGZv +aXNjc2lfdGFzayBOVUxMLCBvcDoweCV4IGNza19mY2lkOjB4JXggY3NrX3N0YXRlOjB4JXggdGNi +X2ZjaWQ6MHgleCwgdGNiX3N0YXRlOjB4JXggCgAAAAAAAAAAAGloZHI6IFJlc3BvbmNlIHJlY2ll +dmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3IgY29ubmVjdGlvbiBzdGF0 +ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBjb25uIGZsYWdzIFsweCV4 +XQoAAAAAAAAAAGloZHI6IEludmFsaWQgdGFzayBzdGF0ZSAweCV4IGZvciB0YXNrIDB4JXgsIGl0 +dCBbMHgleF0sIG9wYyBbMHgleF0KAAAAAAAAAAAAAAAAaXNjc2lfaGRyX3J4OiBhYm9ydCBjb25u +OiBmbGFncyA+PiA3IFsweCV4XSwgaGRzZ2xlbiBbMHgleF0gZHNyX2R0bCBbMHgleF0sIG1heF9i +dXJzdCBbMHgleF0KAAAATWF4IGRhdGEgbGVuIGV4Y2VlZGVkICVkID4gJWQKAABwcm9jZXNzX3R4 +X3F1ZXVlOiB0eF9xdWV1ZSBmb3IgY29ubjoweCV4IHN0b3BwZWQsIGFib3J0aW5nIHRhc2suCgAA +AAAAAAAAAAAAAAAAAFdBVENIRE9HX2Rpc3BhdGNoIGNhc2UgdG8gYXZvaWQ6IENvdW50ZXJfd2F0 +Y2hkb2cgJXUgQ291bnRlcl9zY2hlZCAldSAKAAAAAAAAAAAAeGdtYWNbJXVdIHNldHRpbmcvdW5z +ZXR0aW5nIGhzcyByZXN5bmMgYml0CgAAAAAAV0FUQ0hET0c6IGRldmljZSBzaHV0ZG93bgoAAAAA +AABXQVRDSERPRzogcG9ydFsldV0gcGF1c2Ugd2F0Y2hkb2cgdGltZW91dAoAAAAAAABXQVRDSERP +RzogYnlwYXNzIHRpbWVvdXQKAAAAAAAAAFdBVENIRE9HOiBGTFIgLSBub3QgaW1wbGVtZW50ZWQg +eWV0CgAAAAAAAAAAAAAAAFdBVENIRE9HOiB0ZW1wZXJhdHVyZSBvZiAlZEMgZXhjZWVkcyB0aHJl +c2hvbGQgb2YgJWRDCgAAAAAAAAAAAABmaWx0ZXI6IHBvcmdyYW1taW5nIHRpZCAldSAobGUgdGNh +bSBpbmRleCAldSkuLi4KAAAAAAAAAAAAAAAAAAAAd3JoX2ZpbHRlcjogaXggJWQgbm90IG11bHRp +cGxlIG9mICVkCgAAAAAAAAAAAAAAZmlsdGVyOiByZXF1ZXN0aW5nIGNvbXBsZXRpb24uLi4KAAAA +AAAAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIHdyaXRlIG9ubHkgcGVybWl0dGVkIG9uIGxv +Y2FsIGNvbmYKAAAAAAAAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSBjYW5ub3Qgd3JpdGUgJXUgYXBw +cyAoTUFYOiAldSkKAAAAAAAAAAAAAAAAAABkY2J4X2llZWVfY21kaFsldV0gcmVxdWVzdGluZyBE +Q0JfSUVFRV9DTUQKAAAAAABkY2J4X2llZWVfY21kaFsldV0gdW5rbm93biBmZWF0dXJlIHdyaXRl +OiAldQoAAABkY2J4X2llZWVfY21kaFsldV0gdW5rbm93biBmZWF0dXJlIHJlYWQ6ICV1CgAAAABj +YW5ub3QgYWxsb2NhdGUgb2ZmbG9hZGVkIGZpbHRlciBjb25uZWN0aW9uCgAAAABjYW5ub3QgYWxs +b2NhdGUgb2ZmbG9hZGVkIGZpbHRlciBJUHY2IGNvbm5lY3Rpb24KAAAAAAAAAAAAAAAAAAAAZGlz +cGF0Y2hfZGVmZXJyZWRfY2xhc3NfY2xhc3Nfc2hhcGluZ1sldToldV06IGxpc3RfZW1wdHkKAAAA +AAAAAGxvb3BiYWNrIGJ1ZmZlciBncm91cFsldV0gaXMgZGlzYWJsZWQKAAAAAAAAAAAAAGludmFs +aWQgYnVmZmVyIGdyb3VwWyV1XSBjb25maWd1cmF0aW9uOiBtdHUgJXUgbHdtICV1IGh3bSAldSBk +d20gJXUKAAAAAAAAAAAAAAAAZmMgJXUgdmYgJXUgZ290IGl2Zj0weCV4LHJhbmdlOiAlI3gtJSN4 +ICgldS8ldSB1c2VkKQoAAAAAAAAAAAAAAFZJICV1IGNhbm5vdCBnZXQgUlNTIHNsaWNlOiBObyBt +b3JlIHNsaWNlcyBhdmFpbGFibGUgKHVzZWQgJXUvJXUpCgAAAAAAAAAAAAAAAAAAcGZuICV1IHZm +biAldSB3aXRoIHBvcnQgbWFzayAweCV4IGNhbm5vdCBhY2Nlc3MgcG9ydCAldSwgcmV0ICVkCgAA +AAAAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvdWxkIG5vdCBhbGxvY2F0ZSB2aWlkLCByZXQg +JWQKAABwZm4gJXUgdmZuICV1IGNvdWxkIG1hcCB2aWlkICAweCV4IHRvIGZsb3djLCByZXQgJWQK +AAAAAAAAAAAAAAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxsb2NhdGUgdXdpcmUgZnVuYyAl +ZCBtYWMgYWRkciwgcmV0ICVkCgAAAAAAAAAAAAAAAAAAAABwZiAlZCwgdmYgJWQsIEVSUk9SIGV4 +Y2VlZGVkIG1heCBtYWMgbGltaXQgJWQvJWQKAAAAAAAAAAAAAAAAAAAAbWlpX2ZvcmNlX3NwZWVk +WyV1XTogcmNhcHMgMHgleAoAAAAAAAAAAAAAAAAAAAAAbWlpX3Bkb3duWyV1XTogcG93ZXJkb3du +IGVuICV1CgBwb3J0X2NtZF9oYW5kbGVyOiB1bmtub3duIHUuZGNiLnR5cGUgMHgleAoAAAAAAABw +b3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgaW52YWxpZCByZXF1ZXN0LCBwY2FwcyAweCV4 +IGFjYXBzIDB4JXggbWNhcHMgMHgleCwgcmNhcHMgMHgleAoAAABwb3J0WyV1OjB4JTAyeDoweCUw +MnhdOiBsMWNmZywgcGNhcHMgJSN4IGFjYXBzICUjeCByY2FwcyAlI3ggbWNhcHMgJSN4CgAAAAAA +AAAAAHBvcnRbJXVdOiBsMWNmZywgdW5zdXBwb3J0ZWQgRkVDLCByY2FwcyAlI3gKAAAAAHBvcnRb +JXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBtZGkgaXNzdWUgcGNhcHMgMHgleCBhY2FwcyAweCV4 +IHJjYXBzIDB4JXgKAAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIGNhbm5vdCBm +b3JjZSBuby9tdWx0aXBsZSBzcGVlZChzKSwgcGNhcHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4 +JXgKAAAAAAAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVua25vd24gYWN0aW9uIDB4 +JXgKAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVua25vd24gcmVhZCBhY3Rpb24gMHgleAoA +AAAAAAAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4CgAAAAAA +AAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4IDB4JTA4eCUwOHgKAAAA +AAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBsZW4gJXUKAABGQ09FIEZyZWU6IHN0 +aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAA +AAAAAAAAAAAAAEZDT0UgQlAgV1IgRVJSOiBXUiB3aXRoIGNvb2tpZSAleCV4IGVycm9yZWQgYmFj +ayAKAAAAAAAAAAAAAAAAAABhYm9ydC9jbG9zZSBXUiB3aXRoIGNvb2tpZSAweCVseCB3YXMgaXNz +dWVkIG9uIHNzbiAweCV4IGluIHdyb25nIHN0YXRlIDB4JXgKAAAAAGFib3J0IFdSIG9uIHNzbiAw +eCV4IGRpZCBub3QgZmluZCBXUiB3aXRoIGNvb2tpZSAweCV4JXgKAAAAAAAAAABjbG9zZSBXUiB3 +aXRoIGNvb2tpZSAweCVseCBvbiBzc24gMHgleDtkaWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUg +MHglbHgKAAAAAAAAAGFib3J0IFdSIG9uIHNzbiAweCV4IHdhcyBpc3N1ZWQgb24geGNoZyAweCV4 +IHdpdGggcnhfaWQgMHgleCBpbiB3cm9uZyBzdGF0ZSAweCV4CgAAAAAAAAAAAAAAAAAAAHRhc2tf +YWxsb2M6IE91dCBvZiB0YXNrcy4KAAAAAAAAZGNieF9hcHBseV9hcHBfY2ZnWyV1XU5FVyBBUFAg +VExWIAoAAAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJF +X0xJTktVUAoAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBTRVRfTE9DQUxfUEFSQU1F +VEVSUwoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9O +T19BRFZFUlRJU0UKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZF +QVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0RDQlgKAAAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2Zl +YV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9QRUVSX05PVF9BRFZFUlRJU0VfRkVBVFVSRQoA +AAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VQREFU +RV9PUEVSX1ZFUlNJT04KAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVS +RV9QRUVSX1VQREFURV9PUEVSX1ZFUlNJT04KAAAAAAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3Nt +WyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0dFVF9QRUVSX0NGRwoAAAAAAAAAAAAAAGRjYnhfY2Vl +X2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9DRkdfTk9UX0NPTVBBVElCTEUKAAAAAABk +Y2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfVVNFX0xPQ0FMX0NGRwoAAAAA +AAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9QRUVSX0NG +RwoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9GRUFU +VVJFX0RJU0FCTEVECgAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRV +UkVfRVJST1JfQ0hBTkdFCgAAAAAAAAAAAAAAZGNieF9pZWVlX3Byb2Nlc3NbJXVdIHJlY2VpdmVk +IEJXcyBkbyBub3QgYWRkIHVwIHRvIDEwMCEKAAAAAAAAAFdBUk5JTkc6IHJlY2VpdmVkIEFwcCBU +TFYgY29udGFpbnMgbW9yZSB0aGFuRlcgY2FuIGhhbmRsZSAobWF4OiAldTsgdGx2IGNvbnRhaW5z +OiAldQoAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9jZXNzWyV1XSBzdWJ0eXBlICUjeCByZW1fZnRf +Y2hhbmdlZCAldSBzbV9jaGFuZ2UgJXUKAAAAAAAAAAAAAAAAAAAAZGNieF9pZWVlX3Byb2Nlc3Nb +JXVdIHN1YnR5cGUgdW5rbm93bgoAAAAAAAAAAAAAZGNieF9wYXJzZV9wa3RbJXVdIGVycm9yICVk +CgAAAABjaG5ldF9sMnRfdXBkYXRlOiBsMmRldl9mYyBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19p +ZCBbJXVdIGwyZGV2X2ZjLT5mbG93Y19mbGFncyBbMHgleF0sIGludGYgWzB4JXhdCgAAAAAAAAAA +AAAAY2huZXRfbDJ0X3VwZGF0ZTogaW4gZGVsYXllZF9wcm9jZXNzaW5nLCBsMnRlbnQgWyUwOHhd +CgAAAAAAAAAAAGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGwydCBpcDQgZW50cnkgbm90IGZvdW5k +CgAAAAAAAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBsMnQgaXA2IGVudHJ5IG5v +dCBmb3VuZAoAAAAAAAAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTogYm90aCBpcDQg +YW5kIGlwNiBhZGRyIGNhbm5vdCBiZSBudWxsCgAAAGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGwy +dCBlbnRyeSBpZHggJXUsIHN0YXRlIDB4JXgKAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlOiBs +MnRfdXBkYXRlIHJlcXVlc3Qgc2VudCBsMnRlbnQgWyUwOHhdLCBsMnRlbnQtPmlkeCBbJWRdLCBs +MnRlbnQtPnZsYW4gWyVkXQoAAABDb3VsZCBubyBhbGxvY2F0ZSBwY2IhISBGcmVlaW5nIGZjZiAh +ISEKAAAAAAAAAAB2bl9wYXJzZSB1bmtub3duIHN1YmNvZGUgJXUKAAAAAHZuX3BhcnNlIHVua25v +d24gZHR5cGUgJXUKAAAAAAAAaWdub3JpbmcgZmlwIHJlY3YgZm9yIHBjYiBmbG93OiV4IGluIG9m +ZmxpbmUgc3RhdGUKAAAAAAAAAAAAAAAAAGZpcF92bjJ2bl9yZWN2X2VyciAKAAAAAAAAAAAAAAAA +Q291bGQgbm90IGFsbG9jYXRlIGZsb3djISEhIQoAAABDb3VsZCBub3QgYWxsb2NhdGUgU0NCIGZs +b3djISEhIQoAAAAAAAAAAAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGxvZ28K +AAAAAAAAAAAAAAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgZmNmIGZsb3c6JXggaW4gb2ZmbGlu +ZSBzdGF0ZQoAAAAAAAAAAAAAAAAAQ291bGQgbm90IGZpbmQgcmlnaHQgc2NiIGZvciBmbG9naQoA +AAAAAAAAAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4LCByZXRyeSBub3Qgc3VwcG9ydGVkCgAA +AAAARmxvZ2kgcmVzcCByY3Ygd2l0aCB1bmtub3duIHhjaGcgb3hfaWQleCBzaWQgJTJ4JTJ4JTJ4 +IGRpZCAlMnglMnglMngKAAAAAAAAAAAAAABOX1BPUlQgMHgleCV4JXggcmVqZWN0ZWQgUExPR0kg +d2l0aCByZWFzb24gY29kZSAleAoAAAAAAAAAAAAAAAAAQUJUUyB3aGlsZSBhd2FpdGluZyBQUkxJ +IFJzcDogZmxvd2NfaWQgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXggCgAAAAAAAAAAAAAAAABB +QlRTIGZha2UgUnNwOiBsb2MgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXgKAABsbGRwX3J4X3Br +dF9oYW5kbGVyWyV1XSBkcm9wIHByZS1pbml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAAAAAAYXJw +X3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9hZGRyLmFkZHIgWzB4JXhdLCBzaXAgWzB4JXhdLCByaXAg +WzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGluX2F0dHIuaXB2 +NC5hZGRyOjB4JXgsIGFoZHIuc2lwOjB4JXgKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2FycF9yZWN2 +OiBpcCBjb25mbGljdCBkZXRlY3RlZAoAAAAAAAAAAAAAAGNobmV0X2FycF9yZWN2OiBwaWQgWyV1 +XSwgdmxhbiBbMHgleF0sIGFycCBvcCBbMHgleF0sIHNpcCBbMHgleF0sIHJpcCBbMHgleF0gbDJk +ZXZfZmMtPmZsb3djX2lkICV4IGwyZGMtPmluNF9kZXYuaW5fYWRkci5hZGRyICV4CgAAAAAAAAAA +AAAAAAAAACV4JXgleCBSZWNpZXZlZCBMT0dPIGZyb20gJXgleCV4IAoAAAAAAAAAAAAAAAAAAGNh +bm5vdCBhbGxvY2F0ZSBQT0ZDT0UgZmlsdGVyIGNvbm5lY3Rpb24gZm9yIHhfaWQgJXggCgAAAAAA +AAAAAABGYWlsZWQgdG8gcG9zdCB4Y2hnIGVycjogc3NuaSAweCV4IGNvb2tpZSAweCVseCBydmFs +ICV4IAoAAAAAAAAAb2ZsZF9hYm9ydF9yZXFfbmVnYWR2WyV1XTogd3IgMHglMDh4IGNwbF9hYm9y +dF9yZXEgREVMSVZFUkVECgAAAGhvc3Rfd3JbJXVdOiB3ciAweCUwOHggY3BsX2Fib3J0X3JlcSBz +dGF0dXMgMHgleAoAAAAAAAAAAAAAAAAAAABwa3RzY2hlZF9jbF9ybFsldToldV06IG1vZGUgfCB1 +bml0IHwgcmF0ZSAweCUwNnggbWluICV1IG1heCAldSBwa3RzaXplICV1CgAAAAAAAHBhcmFtX2No +bmV0WzB4JXg6MHgleF06IGNobmV0IDB4JXggcmVhZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAABw +YXJhbV9kbWFxWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAA +AAAAAAAAUlNTU0VDUkVUS0VZOiByc3NzZWNyZXQgdGJsIGJhc2UgJWQsIHJzc25zZWNyZXQgJWQK +AAAAAAAAAAAAAAAAAE1DWyV1XSBpbml0X3N0YXRlX21hY2hpbmUgMHglMDJ4CgAAAAAAAAAAAAAA +AAAAAE1DIGluaXRpYWxpemF0aW9uIG5vdCBjb21wbGV0aW5nLCBNQyBjdXJyZW50IGluaXQgc3Rh +dGUgaXMgMHglMDJ4CgAAAAAAAAAAAAAAAAAATUNbJXVdIF9od19tY19pbml0X21jCgAAAAAAAAAA +AABfaHdfbWNfaW5pdF9tYzogZXJyb3IsIHJldCAlZAoAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRl +ZCBtZW1vcnkgZm9yIHBoeSBmdyBmaWxlLCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1 +cGxlOiB0dXBsZSAldSBub3Qgc3BlY2lmaWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAA +AAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiB0aW1lcl9ycyAldXVzIHRpbWVzdGFtcF9yZXMg +JXV1cyBkZWxheWVkYWNrX3JlcyAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGRhY2tf +dGltZXIgJXV1cyBtc2wgJXV1cyByeHRfbWluLG1heCAldSwldXVzIHBlcnNfbWluLG1heCAldSwl +dXVzCgAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGtlZXBfaWRsZSxpbnR2bCAldSwldXMg +bWF4cnR0ICV1dXMgaW5pdHNydHQgJXV1cyBmaW53YWl0Ml90aW1lciAldXVzCgAAAAAAaHdfdHBf +dGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZGFja190aW1lciBmcm9tICV1IHRvICV1AAAAAAAAAAAA +AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIG1zbCBmcm9tICV1IHRvICV1AGh3X3RwX3Rj +cF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4dF9taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAABo +d190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAA +AAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVyc19taW4gZnJvbSAldSB0byAl +dQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHBlcnNfbWF4IGZyb20g +JXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBrZWVwX2lk +bGUgZnJvbSAldSB0byAldQAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcg +a2VlcF9pbnR2bCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBj +YXBwaW5nIGluaXRfc3J0dF9tYXhydHQgZnJvbSAldSB0byAldQAAAABod190cF90Y3Bfc2V0dGlu +Z3NfdzogY2FwcGluZyBpbml0X3NydHRfaW5pdHNydHQgZnJvbSAldSB0byAldQAAaHdfdHBfdGNw +X3NldHRpbmdzX3c6IGNhcHBpbmcgZmlud2FpdDJfdGltZXIgZnJvbSAldSB0byAldQAAAAAAAGZp +bHRlck1vZGU9JSN4IGlsbGVnYWw6IHNlbGVjdHMgJWQgYml0cyAobWF4ICVkKQoAAAAAAAAAAAAA +AAAAAABsZSBjb25maWd1cmF0aW9uOiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRl +ciAldSBhY3RpdmUgJXUgc2VydmVyICV1IGhhc2ggJXUKAAAAAAAAAAAAAABsZSBjb25maWd1cmF0 +aW9uOiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRlciAldSBzZXJ2ZXIgJXUgYWN0 +aXZlICV1IGhhc2ggJXUgbnNlcnZlcnNyYW0gJXUKAAAAAAAAAAAAAAAAaHdfc2dlX3F1ZXVlX2Jh +c2VfbWFwWyV1XTogZXhjZWVkZWQgbnVtYmVyIG9mIGVncmVzcyBxdWV1ZXMsICV1CgAAAAAAAAAA +AAAAAAAAAABod19zZ2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5n +cmVzcyBxdWV1ZXMgd2l0aCBmcmVlbGlzdCBhbmQgaW50ZXJydXB0LCAldQoAAABod19zZ2VfcXVl +dWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5ncmVzcyBxdWV1ZXMsICV1CgAA +AAAAAAAAAAAAAAAAAEVycm9yLCBUb3RhbCBSU1MgU2VjcmV0IHRhYmxlIGFsbG9jYXRpb24gJWQg +PiAxNgoAAAAAAAAAAAAAAAAAAABjZl9wYXJzZTogZmlsZSBtZW10eXBlIDB4JXggbWVtYWRkciAw +eCV4IG1hcHBlZCBAICVwOgoAAAAAAAAAAAAAY29uZmlndXJlZCB3aXRoIGNhcHMgbmJtfGxpbmsg +MHglMDh4IHN3aXRjaHxuaWMgMHglMDh4IHRvZXxyZG1hIDB4JTA4eCBpc2NzaXxjcnlwdG8gMHgl +MDh4IGZjb2U6MHgleAoAAAAAAAAAAAAAAG5ldCBWSSBhbGxvY2F0aW9uIGZhaWxlZCBmb3IgZmNf +aWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAABuZXQgVkkgbWFjIGFkZHJlc3MgcHJvZ3Jh +bW1pbmcgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAAAAAG5l +dCBWSSByeG1vZGUgcHJvZ3JhbW1pbmcgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVk +CgAAAABuZXQgVkkgcnNzIGluZGlyZWN0aW9uIHRhYmxlIHByb2dyYW1taW5nIGZvciBmY19pZCAl +dSBmYWlsZWQgd2l0aCBlcnJvciAlZAoAAAAAAG5ldCBWSSByc3MgY29uZmlnIGNvbW1hbmQgZmFp +bGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAABuZXQgVkkgY29tbWFuZCBmYWlsZWQg +Zm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAAZm9pc2NzaV9pbml0OiBp +bml0X2RvbmU6JXUsIGZvaXNjc2lfbnRhc2tzOiV1LCBmb2lzY3NpX25zZXNzOiV1LCBuY3NvY2s6 +JXUsIG5zcG9ydHM6JXUsIGZvaXNjc2lfbmluaXQ6JXUsIHJjOiVkCgAAAAAAAAAAAAAAAAAAAABG +Q29FIEREUCBpbml0OiBmY29lIGxsaW1pdCAweCV4LCBmY29lIHVsaW1pdCAweCV4IGdibCBsbGlt +aXQgMHgleCBnYmwgdWxpbWl0IDB4JXggcGNic3ogJXgKAAAAAABGQ29FIEREUCBpbml0OiBmY29l +IHBwb2Qgb2ZmIDB4JXgsIGZjb2Ugc3QgcHBvZCBhZGRyIDB4JXggZmNvZSBudW0gcHBvZHMgMHgl +eAoAAGNoX2NsX3JhdGVbJXUvJXVdOiBjYXBwZWQgY2xhc3MgcmF0ZSBmcm9tIHJlcXVlc3RlZCAl +dSB0byBjb25maWd1cmVkIChlZmZlY3RpdmUpIGNoYW5uZWwgcmF0ZSAldQoAAAAAAAAAAAAAAAAA +AABjaF9jbF9yYXRlWyV1LyV1XTogaW5jcmVhc2VkIGRlZmljaXRfaW5jciBmcm9tIHJlcXVlc3Rl +ZCAldSB0byByZXF1aXJlZCBtaW4gb2YgJXU7IHJhdGUgJXUgKGVmZiAldSkgZGVmaWNpdF9tYXgg +JXUKAAAAAAAAAAAAAAAAAHBrdHNjaGVkIGNoYW5uZWwgJXUgc2V0cyBzcGVlZCAoZnJvbSAldSkg +dG8gJXUga2JwcwoAAAAAAAAAAAAAAABuZXRfbDJkZXZfbm90aWZ5OiBwZ2lkIFsweCV4XSwgcHJp +byBbMHgleF0sIGNoIFsweCV4XQoAAAAAAAAAAAAAWyV1XSB1bmFibGUgdG8gZXhlY3V0ZSBpbnRl +cm5hbCBEQ0JfSUVFRV9DTUQKAAAAcG9ydFsldV0gbGluayBkb3duICgldSkgKGxzdGF0dXMgJSN4 +KQoAAAAAAAAAAAAAaTJjIGVycm9yIGNhdXNlZCBieSBtb2R1bGUgdW5wbHVnCgAAAAAAAAAAAAAA +AAAAc2VuZHRvIHBlbmRpbmc6IHdyX3BlbmQgJXAgZm9yIHBvcnQgJXUsIHdhbnQgdG8gc2VuZCB0 +byBwb3J0ICV1CgAAAAAAAAAAAAAAAAAAAABwb3J0WyV1XSB1cGRhdGUgKGZsb3djaWQgJXUgcmMg +JXUpCgAAAAAAAAAAAAAAAABwb3J0X3NldF9sb29wYmFjayBwb3J0ICUjeCBjdXJyZW50ICUjeCBt +b2RlICUjeAoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gc3BlZWQgdXBkYXRlOiAlI3gKAAAAAABw +b3J0WyV1XSBiZWdpbm5pbmcgZGVib3VuY2UKAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1 +XSBwb3dlcmluZyBkb3duCgAAAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1XSBwb3dlcmlu +ZyB1cAoAAAAAAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1XSB1bmtub3duIHN0YXRlIChz +dGF0ZSA9ICUjeCkKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlcjogU29tZXRoaW5nIHdl +bnQgdGVycmlibHkgd3JvbmcuIHJldCA9ICVkCgAAAAAAAAAAAAAAAAAAAENhbGN1bGF0aW9uIG91 +dCBvZiBib3VuZHMgZnVyaW5nIGluaXQ6ICUjeCAlI3ggJSN4CgAAAAAAAAAAAAAAAABsZSBpbml0 +aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgYWN0aXZl +ICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJp +ZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2VydmVyICV1IGFjdGl2ZSAldSBoYXNo +ICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogdGNiIHJlZ2lvbiAoc3Rh +cnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVtb3J5CgAA +AAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUg +JXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVtb3J5CgAAAAAAAAAAAAAAaHdfdHBf +aW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBub3QgY29tcGxldGUKAAAAAAAAAAAA +AGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgleAoAAAAAAAAAAAAAAGJ1Zm1faW5p +dDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50ZXJuYWwgYnVmbGw2NCBidWZmZXJz +CgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdoIG1lbW9yeSB0byBhbGxvY2F0ZSBi +dWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjogbm90IGVub3VnaCBtZW1vcnkgdG8g +YWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9idWY6IG5vdCBlbm91Z2ggbWVt +b3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAldSB0cnlpbmcgdG8gdXNlICV1IGF2 +YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9vdGhlcnM6IHN0YXJ0IDB4JTA4 +eCBzaXplICV1ICh1bnVzZWQgJXUpLCBobWEgJXUKAAAAAG1wYXJ0aXRpb25fb3RoZXJzOiBzdGFy +dCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAAAAAAAABtZW1faW5pdDogRURDIG92 +ZXJjb21taXR0ZWQgYnkgJWQgYnl0ZXMKAAAAAAAAAABtZW1faW5pdDogbm90IGVub3VnaCBtZW1v +cnkgdG8gYWxsb2NhdGUgZmxvdyB0YWJsZQoAAAAAAAAAAAAAAAAAY3hjbmljX2RldmljZV9pbml0 +OiBjeGNuaWMgWzB4JTB4XSwgY3hjbmljLT5maWx0ZXIgWyUweF0KAAAAAAAAAHBvZmNvZSBpbml0 +IGRvbmUKAAAAAAAAAAAAAAAAAAAAcG9ydF9pbml0WyV1XSBwdHlwZSAweCV4CgAAAAAAAABQb3J0 +WyV1XTogVW5rbm93biBTR01JSSBzdWItdHlwZSAlI3gKAAAAAAAAAAAAAABQb3J0WyV1XTogVW5r +bm93biBCVF9YRkkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAABQb3J0WyV1XTogVW5rbm93biBCVF9Y +QVVJIHN1Yi10eXBlICUjeAoAAAAAAAAAAABwb3J0X2luaXRbJXVdOiBwb3J0IHR5cGUgMHgleCBp +cyBub3Qgc3VwcG9ydGVkCgBtcGFydGl0aW9uX2luaXQ6IG1vdmVkIHBtcnhfc3RhcnQgZnJvbSAw +eCUwOHggdG8gMHglMDh4IHRvIG1ha2Ugcm9vbSBmb3IgTEUgSEFTSCBhbmQvb3IgVFAgVENCcwoA +AAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHgl +MDh4IHRvIDB4JTA4eCAoRURSQU0pCgAAAAAAAAAAAAAAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBk +ZXN0cm95aW5nIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMgJXUgYW5kIGZs +YWdzIDB4JTA4eAoAAAAAAAAAAABsMmRldl92aV9mc206IG1iIFsweCV4XSwgZGVmZXJyZWQsIHN0 +YXRlIFsweCV4XSwgcG9ydCBbMHgleF0KAAAAbDJkZXZfdmlfZnNtOiB2aWlkIFsweCV4XSBwb3J0 +IFsweCV4XSwgbWFjLWlkIFslMDJ4OiUwMng6JTAyeDolMDJ4OiUwMng6JTAyeF0uIAoAAAAAAAAA +AAAAAAAAAAAAbDJkZXZfdmlfZnNtOiBzZ2VfZXFpZCBbMHgleF0sIHNnZV9pcWlkIFsweCV4XSwg +c2dlX2VxY3IgWzB4JXhdLCByc3Nfc3ogWzB4JXhdCgBsMmRldl92aV9mc206IGwyZGV2X2ZjLT5m +bG93Y19uZXRfbDJkZXZfbXR1IFsldV0sIG1iX3NjcmF0Y2ggWzB4JXhdLCBwb3J0IFsweCV4XQoA +AAAAAAAAAAAAAAAAAABsMmRldl92aV9mc206IHZpaWQgWyVkXSwgdmlfZmMtPmZsb3djX3ZpX2Zs +YWdzIFsweCV4XQoAAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiBwZm4gWzB4JXhdLCB2Zm4gWzB4JXhd +LCBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBscG9ydCBbMHgleF0sIHZpaWQgWzB4JXhdLCBm +bGFncyBbMHgleF0KAAAAAAAAAGwyZGV2X3ZpX2ZzbTogRXJyb3IgZnJlZWluZyBWSSwgcmMgWzB4 +JXhdCgAAAAAAAGwyZGV2X3ZpX2ZzbTogcGlkIFsweCV4XSwgdmlpZCBbMHgleF0sIG1iX2xvYyBb +MHgleF0sIG1iX29yaWdbMHgleF0sIGwyZGV2X2ZsYWdzIFsweCV4XSwgcmMgWzB4JXhdCgAAAAAA +AAAAAAAAAABBaCBoYS4uLmRvdWJsZSBmcmVlIG94X2lkIDB4JXgsIHJ4X2lkIDB4JXgKAAAAAABI +b3N0IFBSTEkgUmVzcG9uc2UgdGltZWRvdXQ6IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAAAAAAAA +AAAAAAAAcGZuICV1IHZmbiAldSB2aWEgY29tbWFuZAoAAAAAAABod19pMmNfdHJhbnNhY3Rpb246 +IG5kYXRhICV1IGFkZHJfb3AgMHgleCByZWcgMHgleCBkaWZmICV1IGNvbnQgJXUgZmFpbGVkIHdp +dGggZXJyICVkCgAAAAAAAAAAAABod19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJfb3Ag +MHgleCBkYXRhWzBdIDB4JXggZGlmZiAldSBkcG9zICV1IGNvbnQgJXUgZmFpbGVkIHdpdGggZXJy +ICVkCgAAAAAAAAAAAAAAAAAAaTJjIHRyYW5zYWN0aW9uIGZhaWxlZCB0byBjb21wbGV0ZQoAAAAA +AAAAAAAAAAAAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNlcjogYWVjX3JldHJ5X2NudCB2YWx1ZSAl +ZCBpcyBub3Qgd2l0aGluIHRoZSBhbGxvd2VkIGxpbWl0IG9mIDEgdG8gMjU0LkRpc2FibGluZyBp +dC4KAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXI6IGFuX2FlY190aW1lIHZhbHVlICVkIGlz +IGJpZ2dlciB0aGFuIGFsbG93ZWQgbGltaXQuQ2hhbmdpbmcgaXQgdG8gMTAwMDAgbXMuCgAAAAAA +AAAAAABEZXByZWNhdGVkIGNvbmZpZyBvcHRpb24gZm91bmQgaW4gY29uZmlnIGZpbGUuIElnbm9y +aW5nLi4KAAAAAAAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHk6IGhhcyAldSBlbnRyaWVzIG9ubHks +IHJlcXVpcmVzICV1IGVudHJpZXMKAAAAAAAAAAAAAAAAAAB0cF9iYWNrb2ZmOiBwYXJzZWQgJWQg +aW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAAAB0cF90aW1lcnZhbHM6IHBhcnNlZCAlZCBpbnN0ZWFk +IG9mICV1IGVudHJpZXMKAAB0cF90aW1lcnJlczogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50 +cmllcwoAAAB0cF9tdHVzIGhhcyAldSBlbnRyaWVzIG9ubHksIHJlcXVpcmVzICV1IGVudHJpZXMK +AAAAAAAAAAAAAAAAAAAAdHBfbXR1c1sldV0gaXMgJXUgYnl0ZXMgd2hpY2ggaXMgbm90IHN1cHBv +cnRlZAoAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNlcjogc2dlIHRpbWVyIHZhbHVlWyVkXSBpcyB0 +b28gbGFyZ2UsIGNoYW5naW5nIGZyb20gJXUgdG8gJXV1c2VjcwoAAAAAAAAAZmlsdGVybWFzayAw +eCV4IGlzIG5vdCBlcXVhbC9zdWJzZXQgdG8vb2YgZmlsdGVybW9kZQoAAAAAAAAAAAAAAGh3X2xl +X2NsaXBfaGFuZGxlcjogcmVtb3ZlZCBwb3M9JXUgKD1pZHggJXUpCgAAAGh3X2xlX2NsaXBfaGFu +ZGxlcjogYWRkaW5nIHRvIHBvcz0ldSAoPWlkeCAldSkKAG1vZHVsZVsldV06IHBvcnQgbW9kdWxl +IGluc2VydGVkIGFuZCByZWFkeQoAAAAAAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIHJlbW92ZWQK +AAAAAAAAAAAAAAAAAAAAAG1vZHVsZVsldV06IHVua25vd24gbW9kdWxlIGlkZW50aWZpZXIgMHgl +MDJ4CgAAAG1vZHVsZVsldV06IGdwaW8gJXUgdmVuZG9yIGlkICUwNngsIGlkZW50aWZpZXIgMHgl +MDJ4LCBTRlAyOChieXRlIDM2LzE5MikgMHglMDJ4LCBTRlAoYnl0ZSAzLzEzMSkgMHglMDJ4LCAx +RyAoYnl0ZSA2KSAweCUwMngKAAAAb3B0aWNhbCBsZW5ndGgoYnl0ZSAxNS8xNDIpICV1LCBjb3Bw +ZXIgY2FibGUoYnl0ZSA4LzE0NykgMHglMDJ4LCBsZW5ndGgoYnl0ZSAxOC8xNDYpICV1LCBtb2R1 +bGVfdHlwZSAweCUwMngKAAAAAG1vZHVsZVsldV06IGdwaW8gJXUgdmVuZG9yIGlkICUwNngsIGlk +ZW50aWZpZXIgMHglMDJ4LCBTRlAyOChieXRlIDM2LzE5MikgMHglMDJ4LCBTRlAoYnl0ZSAzLzEz +MSkgMHglMDJ4LCAxRyAoYnl0ZSA2KSAweCUwMngKAAAAb3B0aWNhbCBsZW5ndGgoYnl0ZSAxNS8x +NDIpICV1LCBjb3BwZXIgY2FibGUoYnl0ZSA4LzE0NykgMHglMDJ4LCBsZW5ndGgoYnl0ZSAxOC8x +NDYpICV1LCBtb2R1bGVfdHlwZSAweCUwMngKAAAAAHBmbiAldSB2Zm4gJXUgRlNNIHN0YXJ0CgAA +AAAAAAAAcGZuICV1IHZmbiAldSBGU00gY29tcGxldGUKAAAAAABmbHJfcGZ2Zl9mc21bJXU6JXVd +OiB1bmtub3duIHN0YXRlICV1CgAAAAAAAAAAAABodyBwZiBiaXRtYXAgMHglMDJ4IHZmaWQgYml0 +bWFwIDB4JTA4eDoweCUwOHg6MHglMDh4OjB4JTA4eAoAAAAAYWZ0ZXIgdmZpZCBmaXh1cCwgdmZp +ZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAAAAAAAHRpbWVyIHF1ZXVlICV1 +IGxvc3QgYSB0aWNrISBuZXh0ICVwIGxhc3QgJXAgbnVtZSAldQoAAAAAAAAAAAAAAABmbHJfdGlt +ZXJfc3RhcnQ6IGZsb3djX2lkICV1ICVwIGJ1ZiAlcAoAAAAAAAAAAABTZXJpYWwgQ29uZmlndXJh +dGlvbiB2ZXJzaW9uOiAweCV4IFZQRCB2ZXJzaW9uOiAweCV4CgAAAAAAAAAAAAAAcGNpZTogbnBm +ICV1IChwZmJpdG1hcCAweCUwMngpIG52ZiAldSAocGYgMC4uNyAweCUwOHglMDh4KSB2ZnN0cmlk +ZSAldQoAAAAAAAAAAABod19ncGlvX3ByZXA6IGVycm9yLCByZXQgJWQKAAAAAGZhaWxlZCB0byBm +aW5kIHRoZSAlYyVjIFZQRCBwYXJhbWV0ZXIKAAAAAAAAAAAAAGZhaWxlZCB0byBwYXJzZSB0aGUg +JWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAG1lbV9wcmVwOiBlcnJvciwgcmV0ICVkCgAAAAAA +AAAAZmFpbGVkIHRvIHN1Y2Nlc3NmdWxseSBmaW5kIENoZWxzaW8gVlBECgAAAAAAAAAAdnBkX3By +ZXA6IGVycm9yLCByZXQgJWQKAAAAAAAAAABzZXJjZmdfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAA +AGxvZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgldSBlbnRyaWVzKSBmd3JldiAweCUw +OHggcGNpZV9mdyAweCUwOHgKAAAAAAAAZ2F0aGVyX3Rhc2tzX2Zvcl90bWY6IEludmFsaWQgdHlw +ZSBbMHgleF0sIGJhaWxpbmcgb3V0LgoAAAAAAAAAAGZjX3NlbmRfYWxsb2NfY3BsOiBmYWlsZWQg +dG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAABmY29lX2NvbXB1dGVfY3R1cGxl +IDB4JXg6JXgKAAAAAGNvbXB1dGVfY3R1cGxlKCk6IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1 +cGxlCgAAAAAAAAAAAAAAAAAAAABGQ29FIEZDQiBsaW5rZG93bjogaW9fcmVxIDB4JXgleCBpcWlk +IDB4JXggZmxvd2lkIDB4JXggb3AgMHgleAoAZmNvZSBub3RpZnkgOiBVcGRhdGUgbmV3IERDQlgg +dmFsdWVzIFZJIHN0YXRlIDB4JXggcHJpIDB4JXggc2NoZWRjbCAweCV4IGRjYnhfZG9uZSAweCV4 +CgAAAAAAAAAAZmNvZSBub3RpZnkgOiBGQ0YgZmxvd2lkIDB4JXgsIHVscGNoIDB4JXggCgAAAAAA +ZmNvZSBub3RpZnkgOiBGQ29FIExJTktVUDogcG9ydCAweCV4LCBldmVudCAweCV4CgAAAAAAAAAA +AAAAAAAAAGZjb2Ugbm90aWZ5IDogRkNvRSBMSU5LRE9XTjogcG9ydCAweCV4LCBldmVudCAweCV4 +CgAAAAAAAAAAAAAAAABmY29lIG5vdGlmeSA6IERDQlggOiBwb3J0IDB4JXgsIHByaW9yaXR5IDB4 +JXggdWxwdHhjaCAweCV4IGNsYXNzIDB4JXgKAAAAAAAAAAAAAFJERVYgbXNnIGZsb3djOiV4IHN0 +YXRlIDB4JXggZXZlbnQgMHgleAoAAAAAAAAAAGNhbmNlbCBmY2I6JXggc2NiOiV4IHN0YXRlOiV4 +CgAARkNvRSBGQ0YgdGltZXI6IGZsb3djIHN0YXRlIDB4JXgsIHBvcnQgMHgleCAsZmNmIDB4JXgs +IGZsb3djX2lkIDB4JXgKAAAAAAAAAAAAAABodyByZWdpc3RlciBvcGVyYXRpb24gbm90IGNvbXBs +ZXRpbmcsIHJlZyAweCUwOHggbWFzayAweCUwOHggdmFsdWUgMHglMDh4IChyZWcgMHglMDh4KQoA +AAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAgTU1EIGFkZHIKAAAAAAAAAAAAAABN +RElPOiBmYWlsZWQgdG8gd3JpdGUKAAAAAAAAAAAAAE1ESU8gQ0w0NTogZmFpbGVkIHRvIHNldCB1 +cCBNTUQgYWRkcgoAAAAAAAAAAAAAAE1ESU86IGZhaWxlZCB0byByZWFkCgAAAAAAAAAAAAAACUFR +X1Rha2VDb250cm9sT2ZGTEFTSDogMWUuYzAwMT0lI3ggMWUuYzQ1MD0lI3ggMWUuYzQ1MT0lI3gg +MWUuMTAwPSUjeAoAAAAAAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gSW1h +Z2UgaW50ZWdyaXR5IGNoZWNrIGZhaWxlZCAoY2FsYyAlI3ggdmFsICUjeCkKAAAAAAAAAAAAAAAA +AABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gSW1hZ2UgaW50ZWdyaXR5IGNoZWNr +IHBhc3NlZAoAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIFRpbWVvdXQgd2FpdGlu +ZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgldSkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFz +aEltYWdlIC0gVGltZW91dCB3YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KQoAAAAAAEFR +X0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZsYXNo +IGludGVyZmFjZSAoJXUpCgAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIFRp +bWVvdXQgd2FpdGluZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgldSkgKHBwICUjeCBhcCAlI3gpCgAA +AAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIFRpbWVvdXQgd2FpdGluZyBmb3Ig +Zmxhc2ggaW50ZXJmYWNlICgldSkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdl +IC0gVGltZW91dCB3YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KQoAAAAAAEFRX0FQSV9X +cml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBFcnJvciBvbiBidXJuaW5nIEZMQVNIIChjcmMxNiBt +aXNtYXRjaCkKAAAAAAAAJTA4eDogJTA4eCAlMDh4ICUwOHggJTA4eAoAAAAAAABmb2lzY3NpX3Zh +bGlkYXRlX2xvZ2luX3N0YWdlOiAtIDEKAAAAAAAAAAAAAAAAAABjcGxfdHhfcGt0OiB2bGFuaWQg +WzB4JXhdCgAAAAAAAGNobmV0IFslZC8lZF0gZnJlZSBsMnQgZW50cnk6IGlkeCAldSwgcmVmY250 +ICV1CgAAAAAAAAAAAAAAAAAAAABjaG5ldCBbJWQvJWRdIHB1dCBsMnQgZW50cnk6IGlkeCAldSwg +cmVmY250ICV1CgBjaG5ldCBbJWQvJWRdIGdldCBsMnQgZW50cnk6IGlkeCAldSwgcmVmY250ICV1 +CgBjaG5ldCBbJWQvJWRdIGwydCBhbGxvYyBsMnRlbnQgMHgleCwgaWR4ICV1LCByZWZjbnQgJXUK +AAAAAAAAAAAAY2huZXRfZmluZF9sMnRfZW50cnk6IGRhZGRyIFslMDh4XSwgWzB4JTA4eF0sIGxv +Y2FsIG5ldHdvcmsgWyVkXQoAAAAAAAAAAAAAAAAAAABjaG5ldCBmaW5kIGwydGVudCBub3QgdmFs +aWQsIDB4JXgsIGlkeCAldSwgc3RhdGUgMHgleCwgcmV0cnkgY291bnQgJXUKAAAAAAAAAAAAAGNo +bmV0IGwydGVudCAweCV4LCBpZHggJXUsIHJlZmNudCAldQoAAAAAAAAAAAAAAGNobmV0IGwydGVu +dCBmaW5kIGVycgoAAAAAAAAAAAAAb3V0IG9mIGF0aWRzOiBtYXggYXRpZHM6ICVkCgAAAABmb2lz +Y3NpX2ZpbmRfdGFzazogdGFzayBub3QgZm91bmQgdGNiX2ZjIGlkIDB4JXggaXR0IDB4JXgKAAAA +AAAAV0FUQ0hET0c6IE5vIHRlbXBlcmF0dXJlIHNlbnNvciBhdmFpbGFibGUuCgAAAAAAV0FUQ0hE +T0c6IEFjdGl2YXRpbmcKAAAAAAAAAAAAAABXQVRDSERPRyAtIEVuYWJsZSBhY3Rpb24gJXUgdGlt +ZSAldQoAAAAAAAAAAAAAAABXQVRDSERPRyAtIERpc2FibGUgYWN0aW9uICV1CgAAAFdBVENIRE9H +OiBEZS1hY3RpdmF0aW5nCgAAAAAAAAAAcG9ydFsldV0gc2V0IFBBVVNFIFBBUkFNUzogcHBwZW4g +JXUgdHhwZSAlI3ggcnhwZSAlI3gKAAAAAAAAAAAAAG1wc19saW5rX3VwWyV1XSBhY2FwcyAlI3gg +KDgwMi4zICUjeCkgKyBscGFjYXBzICUjeCA9PiAlI3gKAAAAAABkY2J4X3BvcHVsYXRlX2N0cmwg +Y29kZSBpbmNvbXBsZXRlCgAAAAAAAAAAAAAAAABjaF9jbF9yYXRlWyV1LyV1XTogY2FwcGVkIGRl +ZmljaXRfaW5jciBmcm9tIHJlcXVpcmVkICV1IHRvICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmlj +aXRfbWF4ICV1CgBEQ0JYOiBzdW0gb2YgcmF0ZXMgb24gYWxsIGNsYXNzZXMgbXVzdCBiZSAxMDAg +KGFjdHVhbDogJXUpCgAAAAAAd29ya2Fyb3VuZDEzNzIzOiBkZXRlY3RlZCBXUiBAIDB4JTA4eCBv +ZiBzaXplICV1IGJ5dGVzLCBkcmliYmxpbmcgaXQgaW4gJXUgYnl0ZXMgYXQgYSB0aW1lCgAAAAAA +cmlfd3JfaW5pdFsldV06IG1zcyAldSBpcyBub3QgOC1ieXRlIGFsaWduZWQKAAAAY29yZV9wcm9n +cmFtX3RjYjogdGlkICUjeCB0X3N0YXRlICUjeCByY3ZfYWR2IDB4JTA4eCByY3Zfc2NhbGUgJSN4 +IHR4X21heCAlI3ggcmN2X254dCAlI3ggYXRpZCAlI3gKAAAAAAAAAAAAAAAAAAlvcHQwICUjeCV4 +IG9wdDIgJSN4IGlwdjYgJSN4IGZsYWdzX3RpbWVyIDB4JTA4eAoAAAAAAAAAAAAAAAAAAABvZmxk +X2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUw +NHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmlsdGVyIDB4JTA4eCBleGlzdHMgQCBM +RSBpbmRleCAldQoAAAAAAAAAAAAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24g +d2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCBwaXAgMHglMDh4IGZp +bHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93 +cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4 +JTA4eCBwaXAgMHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4CgAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6 +IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCBw +aXAgMHglMDh4IGZpbHRlciAweCUwOHgKAAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1 +OiBpcWlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAAAAAAAAAAAAAAAElRRkxJTlQgcGZuICV1 +IHZmbiAldTogaXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAElRRkxJTlQgcGZuICV1IHZmbiAldTog +ZmwwaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2 +Zm4gJXU6IGZsMGlkICV1IG5vdCBhbGxvY2F0ZWQKAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZs +MWlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZu +ICV1OiBmbDFpZCAldSBub3QgYWxsb2NhdGVkCgAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFp +ZCAldSBpcyB2YWxpZCBidXQgbm90IGZsMGlkICV1CgAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAl +dTogZmwxaWQgJXUgaXMgdmFsaWQgYnV0IGhlYWRlciBzcGxpdCBmZWF0dXJlIGlzIG5vdCBlbmFi +bGVkCgAAAAAAAAAAAAAAAAAAAGh3X3VscHR4X3dvcmthcm91bmRfcHIxNjk0OV9lbmFibGVkX3Zm +aWQ6IHZmaWQgJXUgZW5hYmxlZCAldQoAAABFUSBwZm4gJXUgdmZuICV1OiBjcmVhdGluZyBFVEgg +ZXFpZCAldSB3aXRoIHBlbmRpbmcgV1IocykgKG51bV9ieXRlcyAldSBhbmQgZmxhZ3MgMHglMDh4 +CgAAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBjcmVhdGluZyBDVFJMIGVxaWQgJXUgd2l0aCBwZW5k +aW5nIFdSKHMpIChudW1fYnl0ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAABFUSBwZm4gJXUg +dmZuICV1OiBlcWlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAABFUSBwZm4gJXUgdmZuICV1OiBl +cWlkICV1IG5vdCBhbGxvY2F0ZWQKAAAAAAAAAABod19jaW1fdHBfd29ya2Fyb3VuZDEzNzIzX2Vu +YWJsZTogcG9ydCAldSBwcm90b2NvbCAweCV4IGVuICV1IGN1cnJlbnQgMHgleCB3b3JrYXJvdW5k +X3ByMTM3MjMgMHgleCBuZXh0IDB4JXgKAAAAdmlfdGNhbV9yYXcgaWR4ICV1IG1hYyAweCUwNHgg +JTA4eAoAAAAAAAAAAAAAAAAAcG9ydF9ibGlua19sZWRfcmVzdG9yZQoAAAAAAAAAAABwb3J0X2Js +aW5rOiBibGlua2R1cj0weCV4IGJsaW5rX3JlZmNudAoAAAAAAAAAAABwb3J0X2JsaW5rOiAJYmxp +bmtfcmVmY250PTB4JXgKAHBvcnRfYmxpbms6IAlibGlua19yZWZjbnQ9MHgleAoAbWlpX2Fkdl9m +Y1sldV06IHJjYXBzIDB4JXgKAAAAAABtaWlfYWR2X3NwZWVkWyV1XTogcmNhcHMgMHgleAoAAG1p +aV9pbml0WyV1XTogYWNhcHMgMHgleAoAAAAAAAAAcG9ydFsldV06IGdhdmUgdXAgZml4aW5nIGVy +cm9ycyEhIQoAAAAAAAAAAAAAAAAAbWlpX2FucmVzdGFydFsldV06IGFjYXBzIDB4JXgKAABtaXNz +aW5nIHBvcnQgY2FwczMyIHRvIGNhcHMxNiB0cmFuc2xhdGlvbiBmb3IgJSNseAoAAAAAAAAAAAAA +AAAAaHdfeGdtX3BvcnRfbHBiayBwb3J0ICV1IHB0eXBlICUjeCBhY3Rpb24gJSN4CgAAcG9ydF9j +bWRfaGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAbWlzc2luZyBwb3J0IGNh +cHMxNiB0byBjYXBzMzIgdHJhbnNsYXRpb24gZm9yICUjeAoAAAAAAAAAAAAAAAAAAGJhZCBGbG93 +QyAlZCBvbiBlc3RhYmxpc2hlZCBjb25uZWN0aW9uCgAAAAAAAAAAAGV0aF9mbG93Y19oYW5kbGVy +WzB4JXhdOiBmbGFncyAweCUwOHggbnVtX2J5dGVzICV1IHNjaGVkY2wgMHgleCAtPiAweCV4CgAA +AAAAAAAAc2NzaV9yZWFkOiBwcG9kIGFsbG9jIGZhaWxlZCwgbnBwb2QgJXUKAAAAAAAAAAAAZGNi +eF9jb250cm9sX3NtWyV1XSBDT05UUk9MX0xJTktVUAoAAAAAAAAAAAAAAAAAZGNieF9jb250cm9s +X3NtWyV1XSBDT05UUk9MX1VQREFURV9EQ0JYX1RMVgoAAAAAZGNieF9jb250cm9sX3NtWyV1XSBD +T05UUk9MX1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9z +bVsldV0gQ09OVFJPTF9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAABkY2J4X2Nv +bnRyb2xfc21bJXVdIENPTlRST0xfUFJPQ0VTU19QRUVSX1RMVgoAAABkY2J4X2NvbnRyb2xfc21b +JXVdIENPTlRST0xfQUNLX1BFRVIKAAAAAAAAAAAAAABkY2J4X2llZWVfdmFsaWRhdGVbJXVdIGVy +cm9yIChvdWkgJSN4IHN1YnR5cGUgJSN4IGxlbiAlI3gpCgAAAAAAZGNieF9jZWVfdmFsaWRhdGVb +JXVdIGVycm9yCgAAAAB2bjJ2bjogcG9ydCAweCV4IGRpZDoweCV4JXgleCBVUAoAAAAAAAAAAAAA +AAAAAAB2bjJ2bjogcG9ydCAweCV4IGRpZDoweCV4JXgleCBET1dOCgAAAAAAAAAAAAAAAABmY19z +ZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAA +AAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWls +ZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0 +dXBsZSB2bGFuICV4IHZpaWQgJXggcG9ydCAleCBtcHNfaWR4ICV4CgAAAAAAAAAAAEFCVFMgQUND +IGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCBp +cWlkIDB4JXgKAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4LCBjb21tYW5kIGZhaWxlZCByZXRy +aWVzIDB4JXgKAAAAAAAAAAAAAAAAAEdvdCBDT05OX0VYSVNUIGZvciB4aWQ6MHgleCwgdGFnOjB4 +JXgsIHJldHJ5aW5nLgoAAAAAAAAAAAAAAAAAAABjaF9yYXRlWyV1XTogY2FwcGVkIHRpY2sgZnJv +bSByZXF1aXJlZCAldSB0byBzdXBwb3J0ZWQgJXU7IHJhdGUgJXUgKGVmZiAldSkgZGVmaWNpdF9p +bmNyICV1IHRpY2sgJXUKAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2hfcmxbJXVdOiBjaGFubmVsIHJs +IG5vdCBhdmFpbGFibGUgaW4gY29uanVuY3Rpb24gd2l0aCBmbG93IHNoYXBpbmcKAABwa3RzY2hl +ZF9jaF9ybFsldV06IHJhdGUgJXUgbWF4ICV1CgAAAAAAAAAAAAAAAABwa3RzY2hlZF9jbF93cnJb +JXU6JXVdOiB3ZWlnaHQgJXUKAAAAAAAAAAAAAAAAAABlcV9wYXJhbXNbMHgleDoweCV4XTogZG1h +cSAweCV4IHJlYWQgJXUgcGYgJXUgZXFpZF9hcGkgJXUgcmV0ICVkCgAAAAAAAAAAAAAAAAAAAGh3 +X21hX2FkZHJfdG9fbWVtX3R5cGVfb2ZmOiBNQSBhZGRyZXNzIDB4JTA4eCBpcyBub3QgbWFwcGVk +CgAAAABod19tYV9hZGRyX3RvX21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUwOHggbWFwcyB0 +byB0eXBlICV1IG9mZnNldCAweCV4CgAAAAAAAG1lbV9tYWxsb2NfdGVtcDogZmFpbGVkIHRvIGFs +bG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAABtZW1fbWFsbG9jOiBmYWlsZWQgdG8g +YWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAbGUgY29uZmlndXJhdGlv +bjogaGFzaCBtb2RlIHJlcXVpcmVzIGF0IGxlYXN0IDE2IGVudHJpZXMsIG5oYXNoICV1CgAAAAAA +AAAAAAAAAABsZSBjb25maWd1cmF0aW9uOiBoYXNoIG1vZGUgcmVxdWlyZXMgYXQgZW50cmllcyB0 +byBiZSBhIHBvd2VyIG9mIDIsIG5oYXNoICV1CgAAAGxlIGNvbmZpZ3VyYXRpb246IHJlcXVlc3Rl +ZCAldSB0Y2FtIGVudHJpZXMgYnV0IG9ubHkgJXUgYXZhaWxhYmxlIChucm91dGUgJXUgbmNsaXAg +JXUgbmZpbHRlciAldSBuc2VydmVyICV1CgAAAABsZSBjb25maWd1cmF0aW9uOiB0Y2FtIHJlZ2lv +bnMgbXVzdCBoYXZlIG11bHRpcGxlIG9mIDMyIGVudHJpZXMsIG5yb3V0ZSAldSBuY2xpcCAldSBu +ZmlsdGVyICV1IG5zZXJ2ZXIgJXUKAAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3Ig +Y2x1c3RlciBlbnZpcm9ubWVudAoAAAAAAAAAAAAAAAAAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5p +bmcgZm9yIExBTiBlbnZpcm9ubWVudAoAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIFdB +TiBlbnZpcm9ubWVudAoAAGh3X3RwX3RjcF90dW5pbmdzOiBtYW51YWwgdHVuaW5nCgAAAAAAAAAA +AAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5OiBtZW1jcHlYIHN0YXJ0CgAAAAAAAAAAAAAAAF9o +d19jaW1fZmxhc2hfbWVtY3B5OiBkc3QgMHglMDggb2Zmc2V0IDB4JTA4eCBzaXplICV1LCB3aWR0 +aCBvZiAldSBpcyBub3Qgc3VwcG9ydGVkCgAAAAAAAAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5 +OiBtZW1jcHlYIGVuZAoAAAAAAAAAAAAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZW5j +b3VudGVyZWQgZXJyb3IgQCBsaW5lICV1OgoAAAAAAAAAAABmY29lIHhjaGcgbWdyIGluaXQ6IE51 +bWJlciBvZiBleGNoYW5nZXMgZm9yIEZDb0UgaXMgJXgKAAAAAAAAAAAAZmNvZV9sMnRfaW5pdDog +Tm8gdWxwdHggY3JlZGl0IGNoOlsldV0KAAAAAAAAAAAAZmNvZV9sMnRfaW5pdDogY2g6WyV1XSBs +MnRfaWR4IFsldV0KAAAAAAAAAAAAAAAAbm8gbDJ0IGVudHJpZXMgY29uZmlndXJlZDsgZm9yY2lu +ZyAldSBlbnRyaWVzLCBzdGFydGluZyBhdCAldQoAAGRjYnhfaWVlZV9jb25zdHJ1Y3RbJXVdIGV0 +cyAldSBwZmMgJXUgYXBwICV1CgAAAGRjYnhfdGltZW91dFsldV0KAAAAAAAAAAAAAAAAAAAAZGNi +eF9ydW5fdmVyc2lvbl9zbVsldV0gRENCWF9WRVJfU1RBVEVfUlVOX0lFRUUKAAAAAAAAAAAAAAAA +AAAAAGRjYnhfcnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9DRUUKAGRjYnhf +cnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9OT05FCgAAAAAAAAAAAAAAAAAA +AABwb3J0WyV1XSBsaW5rIHVwICgldSkgKHNwZWVkICUjeCBhY2FwcyAlI3ggbHBjYXBzICUjeCkK +AAAAAAAAAAAAcG9ydF9oc3Nfc2lnZGV0WyV1XTogaHNzX3NpZ2RldCBjaGFuZ2VkIHRvIDB4JXgK +AAAAAAAAAAAAAAAAAAAAAFFTRlAgbW9kdWxlIHVucGx1ZyAtIHJlaW5pdGlhbGl6aW5nIHJ4X2xv +cyAgdG8gMHhmZgoAAAAAAAAAAAAAAABncGlvX3FzZnBfbW9kdWxlX3VwZGF0ZTogY2hhbmdlZCBy +eF9sb3MgZnJvbSAweCV4IHRvIDB4JXgKAAAAAAAAZ3Bpb19xc2ZwX21vZHVsZV91cGRhdGU6IGNo +YW5nZWQgdHhfZGlzIGZyb20gMHgleCB0byAweCV4CgAAAAAAAGh3X3NnZV9tYW1lbV9pbml0OiBl +bmNvdW50ZXJlZCBlcnJvciAlZAoAAAAAAAAAAF9od190cF9wZ21uZ3Q6IHR4X3BhZ2VfbWF4ICV1 +IHJ4X3BhZ2VfbWF4ICV1IHBzdHJ1Y3RzICV1IHNpemUgJXUKAAAAAAAAAAAAAAAAAAAATm8gc3Bh +Y2UgbGVmdCBmb3IgcGdtbmd0LCBOZWVkICV1QiwgYXZhaWxhYmxlICV1QiwgTm8gb2ZmbG9hZAoA +AG1wYXJ0aXRpb25fb3RoZXJzX3RvdGFsOiBtZW0gJXUsIGRkcCAldSBkZHBfaXNjc2kgJXUgc3Rh +ZyAldSBwYmwgJXUgcnEgJXUgcnF1ZHAgJXUgLT4gJXUKAAAAAAAAAE5vIHNwYWNlIGxlZnQgZm9y +IHBtdHggcGFnZXMsIE5lZWQgJXVCLCBhdmFpbGFibGUgJXVCLCBObyBvZmZsb2FkCgAAAAAAAAAA +AAAAAAAATm8gc3BhY2UgbGVmdCBmb3IgcG1yeCBwYWdlcywgTmVlZCAldUIsIGF2YWlsYWJsZSAl +dUIsIE5vIG9mZmxvYWQKAAAAAAAAAAAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tY1g6IG5iYW5r +c19wbXR4ICV1ICgldU1CKSBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAo +JXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAX21wYXJ0aXRpb25fYmFua3NfbWMxOiBuYmFua3Nf +cG10eCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1C +KQoAAAAAAAAAX21wYXJ0aXRpb25fYmFua3NfbWMwOiBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJh +bmtzX290aGVycyAldSAoJXVNQikKAAAAAAAAAAAAAABtZW1fbWFsbG9jX2ludGVybmFsOiBmYWls +ZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAAAAAAAAAAGh3 +X2VkY19iaXN0WyV1XTogYmlzdF9jbWRbMHglMDh4XSBhZGRyIDB4JXggbGVuIDB4JXgKAAAAAAAA +AAAAAABod19lZGNfYmlzdFsldV06IGRvbmUsIGVuY291bnRlcmVkICV1IGVycm9ycyBvbiBmaXJz +dCBhbmQgJXUgZXJyb3JzIG9uIHNlY29uZCBhdHRlbXB0ICgldWdicHMpCgBtZW1faW5pdF9jYWNo +ZXM6IGNhY2hlX3NpemUgJXUgZmxvd2NfYnVmX3RjYl9jYWNoZV9zaXplICV1IGJ1ZmxsNjRfY2Fj +aGVfc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABxdWV1ZXNfcGVyX3BhZ2U6IHBmICV1IGhhcyBhIGJh +cnNpemUgb2YgJXUtYnl0ZXMsIG9jcV9zaXplICV1CgAAc2dlIHJlcXVpcmUgbmVxICV1IG5pcSAl +dSByb3VuZGluZyB0byAldSAldQoAAAAAbXBhcnRpdGlvbl9wbXR4OiBtIDB4JTA4eCBzaXplICV1 +CgAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9wbXJ4OiBtIDB4JTA4eCBzaXplICV1CgAAAAAAAAAA +AAAAAAAAbXBhcnRpdGlvbl9lZGMgKG5vIGV4dG1lbSk6IG0gMHglMDh4IHNpemUgJXUKAAAAZWRj +IG92ZXJjb21taXRlZCBieSAlZEIsIDB4JXgvMHgleAoAAAAAAAAAAAAAAAAAZWRjIG92ZXJjb21t +aXRlZCBieSAlZEIsIDB4JXgvMHgleC8lZAoAAAAAAAAAAAAAbXBhcnRpdGlvbl9lZGNfZXN0aW1h +dGU6IGh3IG1vZHVsZXMgcmVxdWlyZSAlZCBieXRlcyBpbiBFREMKAAAAAGZvaXNjc2lfY29yZV9i +eWU6IGFjdGl2ZSBzZXNzX2NudCAlZAoAAAAAAAAAAAAAAHBvcnRbJXVdIHJlc2V0dGluZyBLUgoA +AAAAAAAAAAAAY3g0X2NyX21vZHVsZV9yeF9sb3NbJXVdOiByeF9sb3MgY2hhbmdlZCB0byAldQoA +cGZuICV1IHZmbiAldSBoYXMgcG5kdHhucyAldSBhZnRlciAxMDBtcwoAAAAAAAAAcGZuICV1IHZm +biAldSBjb21wbGV0ZSBpbW1lZGlhdGUKAAAAAAAAAAAAAAAAAAAAYmFkIG1haWxib3ggY21kOiBw +Zm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXggPiBMQVNUQzJFIDB4JXgKAG1haWxib3ggY21k +IG5vdCB5ZXQgc3VwcG9ydGVkOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXgKAABiYWQg +bWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHgleCBpcyB2YWxpZCBwb3N0 +IGRldmljZSBpbml0IG9ubHkKAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9w +Y29kZSAweCUwMnggcmFtYXNrIDB4JXggY21kIHJhbWFzayAweCV4CgAAYmFkIG1haWxib3ggY21k +OiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JTAyeCBsZW4xNiAweCV4IHZlcnN1cyBleHBl +Y3RlZCBsZW4xNiAweCV4CgAAAAAAAAAAaW5zdWZmaWNpZW50IGNhcHMgdG8gcHJvY2VzcyBtYWls +Ym94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IHJfY2FwcyAweCV4IHd4X2NhcHMgMHgleCByZXF1 +aXJlZCByX2NhcHMgMHgleCB3X2NhcHMgMHgleAoAAAAAAAAAAABpbnN1ZmZpY2llbnQgY2FwcyB0 +byBwcm9jZXNzIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgcl9jYXBzIDB4JXggd3hf +Y2FwcyAweCV4IHJlcXVpcmVkIHJfY2FwcyAweCV4IHdfY2FwcyAweCV4CgAAAAAAAAAAAGRvd25s +b2FkX3NyYW06IGVycm9yLCByZXQgJWQKAAAAZG93bmxvYWRfdGNhbTogZXJyb3IsIHJldCAlZAoA +AABWUEQgcmVnaW9uIGlzIHRvbyBzbWFsbCAoU0VSQ0ZHX1NSX1BGTlZQRFNJWkUgMHgleCkKAAAA +AAAAAAAAAAAAY2ZfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCAAAB +IAAAAAAAAACCAAABAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgIAA +AAAAAAAAAAAAAACAAAAAAAAAAAACgAAAAAAAAAAAAAIAAwAAAAABYAgAAAAAAwAAAAAAAAAAAAAA +AwAAAAAAAAAAAAAAAgAAAAAAAAAAACAAAAAAAAAAAAAAAAEAA4AAAAAAAAAAAAAAAgAAAAAAAAAA +ACADgAAAAAAAAAAAABACgACAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAoAAAAAA +AAAAAAAAAgAAAAAAAAAAAAAAAoAAAAAAAAAAAAEAAwAAAAAAAAAAAAACgwAAAAAAAAAAABACgAAA +AAAAAAAAADAAAwAAAAAAAAgAADAAAwAAAAAAAAAAADAFgwAAAAAAAAgAADAFgwAAAAAAAAAAADAE +gwAAAAAAAAgAADAEgwAAAAAAAAAAADADAwAAAAAAAAgAADADAwAAAAAAAAAAADgDAwAAAAAAAAAA +ADgFgwAAAAAAAAAAADgEgwAAAAAAAAAAADgAAwAAAAAAAAAAADQGggAAAAAAAAAAADwDggAAAAAA +AAAAADwAAwAAAAAAAAgAADwAAwAAAAAAAAAAADwEgwAAAAAAAAAAADwFAwAAAAAAAAAAAD0EAwAA +AAAAAAAAADwDgwAAAAAAAAAAACwAAgAAAAAAAAAAACwFggAAAAAAAAAAACwFAgAAAAAAAAAAABAG +gAAAAAAAAAAAABAGgsAAAAAAAAAAABAGgoAAAAAAAAAAAAAOggAAAAAAAAAAABAHgoAAAAAgAAAA +AAAHggAAAAAgAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAAAAAHAgAAAAAg +AAAAABAXgwAAAAAAAAgAABAXgwAAAAAAAAgAABAAAAAAAAAAAAAAABAGA4AAAAAAAAAAAAAOAwAA +AAAAAAAAABAGA0AAAAAAAAAAABAGAwAAAAAAAAAAABAGAAAAAAAAAAAAAAAGA4AAAAAAAAAAAAAG +AwAAAAAAAAAAAAAOAgAAAAAAAAAAAAAOAgAAAAAAAAAAABAGAgAAAAAAAAAAABAGAgAAAAAAAAAA +ABAGAoAAAAAAAAAAABAGAoAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAIAAAAAAAAAAAAQAwAAAAAAAAgAAAAAAAAAAAAAAAAAAP////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////wAAACAAAAAAwAAA +AAAAACAAAAAA4AAAAAAAAAACAAAAAAAAAEAAAAAAAAAAAAAAAAAAASEAAAAAAAAAAAABASAAAAAA +AAAAAAAAAgAAAAQABAAAAAAFAAAABAAAAAAAAAAAAKAAAAAAgAAAAACAAEAAAAAAAAIAAACAACAA +AAAAAAIAAAEAQAAAAAAAAAAAAAEAQgAAAAAAAAAAAAAAIAAAAAAAAAAAAAIQIAAAAAAAAAAAAAIM +AgAAAAAAAAAAAACFAgAAAAQAAAAAAACAQgAAAAAAAAAAAAIAIgAAAAAAAAAAAACAQQAAAAAAAAAA +AACAQYAAAAAAAAAAAAIAIQAAAAAAAAAAAAAQIIAAAAAAAAAAAAIlAIAAAAAAAAAAAAAFAAAAAAAA +AAAAAAiIBIAAAAAAAAAAAAiIBIAAAAAAAAAAAAiiAIAAAAAAAAAAAAiiAIAAAAAAAAAAAAijAIAA +AAAAAAAAAAijAIAAAAAAAAAAAAikgIAAAAAAAAAAAAikgIAAAAAAAAAAAASkgMAAAAAAAAAAAASi +AMAAAAAAAAAAAASjAMAAAAAAAAAAAASIBMAAAAAAAAAAAAAJAYAAAAAAAAAAAAIMAIAAAAAAAAAA +AACIBMAAAAAAAAAAAACIBIAAAAAAAAAAAAILAIAAAAAAAAAAAACKgIAAAAAAAAAAAAALgIAAAAAA +AAAAAACMAIAAAAAAAAAAAAIgEIAAAAAAAAAAAAIKAIAAAAAAAAAAAAIKgIAAAAAAAAAAAAAJAoAA +AAAAAAAAAAABAQAAAAAAAAAAAAABAUAAAAAAAAAAAAABAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AIAAAAAAAAAAAAAAgRAAAAAAAAAAAAAAgQgAAAAAAAAAAAAAgQQAAAAAAAAAAAAAgYAAAAAAAAAA +AACAAMAAAAAAAAAAAACAAKAAAAAAAAAAAAAACAAAAAAAAAAAAACBgAAAAAAAAAAAAACBgIAAAAAA +AAAAAACJgIAAAAAAAAAAAACJgMAAAAAAAAAAAAABggAAAAAAAAAAAAIBgAAAAAAAAAAAAAIBgIAA +AAAAAAAAAABBgYAAAAAAAAAAAAIBgYAAAAAAAAAAAABJgYAAAAAAAAAAAAIJgYAAAAAAAAAAAAIB +gQAAAAAAAAAAAABBgQAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAIBAAAAAAAAABAAAAIAAAAAAAAA +ABAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////wAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAACACSAAAAAAAAAANmACAAQAAAAAAIAJIAAAAAAAAAA3IBJQRAAAAAAAAAAAAAAAAA +AAADlgAgAEAAAAAACAAAAAIAiAOHAABWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAAAAAAA +AAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAgA +AAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAA +AAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABA +AAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAIAA5YA +JgRAAAAAAAhHIAEEAAACsgAC0gUgJEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAARyABBgyhgrBA +AZIEICRAAAAAAABHIAEEDKBCs4ACEgUgJEAAAAAACAAAAAIAiAOFAACWASAAQAAAAAAIAAAAAgCI +A4UAAJYBIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAANxRK6 +ArCA0xRUi+JKRiRAAAAAAAXFEroCt4DTFFSLYkmmJEAAAAAABcUSogawgNMUVIviSkYkQAAAAAAN +xRKiBreA0xRUi2JJpiRAAAAAAAXFEqIGsIDTFFSL4kpGJEAAAAAADcUSoga3gNMUVItiSaYkQAAA +AAAFxRKiBrCA0xRUi+JKRiRAAAAAAA3FEqIGt4DTFFSLYkmmJEAAAAAACcQQoAIAgJAAAItiacYk +QAAAAAABxBCgBrCAkwZUi2JpxiRAAAAAAAHEEKAGsICTBlSLYmnGJEAAAAAAAcUQuAawgJMWVIti +SMYkQAAAAAAIoRCIAgCBWBIAC1IApiRAAAAAAAnAEJACsIADFlSKkgHGJEAAAAAACcAQuAawgAMQ +lIviAkYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAAAAnAELgCtIADEJSLYgGmJEAAAAAACcAQuAK0 +gAMQlItiAaYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAAAAGgEJAGtIADEJSLYgGmJEAAAAAAAcAQ +gAKwgAMUVIpSAMYkQAAAAAABwBCAArCAAxRUilIAxiRAAAAAAAHAEIACsIADFFSKUgDGJEAAAAAA +CEcgAQQAAAKyAALSBSAkQAAAAAAAgQAAAgCFWAdAC1IApiRAAAAAAACBAAACAIVYB0ALUgCmJEAA +AAAAAAAAAAQAoEABgAHWACAAQAAAAAAAAAAABgChgABAAVYAIABAAAAAAAAAAAAEAKBAAYAB1gAg +AEAAAAAACIEAAAIAhVmABAtSAKYkQAAAAAAJYUAAAAAAGAAAA0IBJqRAAAAAAAAAAAAAAAAAAAAD +lgAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIAAAAAgCIA4cAA9YAJgRAAAAAAAgAAAACAIgD +hwAD1gAmBEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAAAAAAE +AKBAAYAB1gAgAEAAAAAACcAQuAK0gAMQlItiAaYkQAAAAAAAAAAAAAAAAAIAA5YAJgRAAAAAAAAA +AAAAAAAAAAADlgAgAEAAAAAACAAAAAIAiAOFAACWASAAQAAAAAAAAAAABACgQAGAAdYAIABAAAAA +AAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIoRCIAgCBWBAACRIBpiRA +AAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAYAoYAAQAFWACAAQAAAAAAIAAAAAgCIA4VACNIC +RiRAAAAAAAnFEqIClIjSEICLIkimJEAAAAAAAcAQgAakiAEFVItSAMYkQAAAAAAJwBCAAqSIAIVU +i1IAxiRAAAAAAAnAEIAGtIgDARSLUgGmJEAAAAAADcAAAAKwgMMWVIviA0YkQAAAAAAAAAAAAAAA +AAAAA5YAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAgAMAAEAAAAAgAAAgAmJEAAAAAAAEcwAAYDIAK3AAgCAcAkQAAAAAAIAwAAAgagCrUACAIA +xiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAAACBQAAQAAAACAAACACYkQAAAAAAIYCAAhAAAAAAA +AAYAIABAAAAAAAhgIACEAAAAAgEwAgAmJUAAAAAACGAAAAQAhAGABAQCAcYkwAAAAAABwAAAAkOA +AwIMiAIBpiRAAAAAAAgAYAAEAAAAAgAAAgAmJEAAAAAACABgAAQAAAAAAAAEASAAQAAAAAAAAAAA +AAAAAAAAAAQBIABAAAAAAAQIFIAGCgAABwFMAiCmJkAAAAAACIAAAAYAhAGABAgCAaYmQAAAAAAA +QAAAAgCgAAJACAIBpiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAABAAAAAKEAAMCiggCBKYkQAAA +AAAAAAAAAAAAAAIAAAYBIEhAAAAAAAAgUAAEAAAAAgAAAgAmJEAAAAAACGAgAIQAAAACAAAGACYE +QAAAAAAIYCAAhAAAAAIAAAIBJiVAAAAAAAhgAAAEAIQBgAQEAgHGJMAAAAAACABgAAQAAAAAAAAE +ASAAQAAAAAAAAAAAAAAAAAAAAAIAJkxwAAAAAAAAAAAAAAAAAAAABgEgAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAABwAAACLSQBAkWBAIExiRAAAAAAAHAAAAItJAECRYEAgTGJEAAAAAA +BAh0gEwJAABQAFwCYeYkQAAAAAAMCHSARAAAAFIAQAJhJiRAAAAAAAgCEKAEAAAAAAEAAgAmJEAA +AAAACAIQoAQAAAAAAQACACYkQAAAAAAECHQAQgEAAAcAiAJgxiRAAAAAAA3IFAACCQAABECcAmDm +JEAAAAAACcgQgAa0kAQClIgCZcYkQAAAAAANyHQASLSQAwCUiAJgpiTAAAAAAA3IdABItJADAJSI +AmCmJMAAAAAACEcAAAQAAAAAAAACASAkQAAAAAAIRwAABAAAAAIAAAIFICRAAAAAAABHIAEMByHC +twAIAgHAJEAAAAAAAEcgAQwHIcK3AAgCAcAkQAAAAAAARyABDAchwrcACAIBwCRAAAAAAAAAIAEI +AIQABUCIAgHGJMAAAAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAAACABCACEAAVAiAIBxiTAAAAAAAAA +IAGGggABAsCIAgPGJMAAAAAAAAAgAYKCAAACwIgCA8YkwAAAAAAJwCABgqSAAQVAiAIBxiTAAAAA +AAgAAAAMAIQABUCIAgHGJMAAAAAAAAAgAYaCAAECwIgCA8YkwAAAAAAAACABgoIAAADAiAICpiTA +AAAAAAnAIAGCpIABBUCIAgHGJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA +AAABAAEJBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFtnbG9iYWxdCnJzc19nbGJfY29uZmln +X21vZGU9YmFzaWN2aXJ0dWFsCnJzc19nbGJfY29uZmlnX29wdGlvbnM9dG5sbWFwZW4saGFzaHRv +ZXBsaXR6LHRubGFsbGxrcApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVnWzB4MTAwY109 +MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQwOTYKcmVnWzB4 +MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJlZ1sweDEwNTRd +PTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2MF09ODE5Mgpy +ZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEwMDBhMDAwLzB4ZjAwMGYwMDAKcmVnWzB4 +MTBhOF09MHgyMDAwLzB4MjAwMApzZ2VfdGltZXJfdmFsdWU9NSwxMCwyMCw1MCwxMDAsMjAwCnJl +Z1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZDZjXT0weDAwMDAwMDAwLzB4 +MDAwMDcwMDAKcmVnWzB4N2RjMF09MHgwZTJmODg0OQpmaWx0ZXJNb2RlPWZyYWdtZW50YXRpb24s +bXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBvcnQsZmNvZQpmaWx0ZXJNYXNrPXByb3RvY29sLGZj +b2UKdHBfcG1yeD0zNAp0cF9wbXJ4X3BhZ2VzaXplPTY0Swp0cF9ucnhjaD0wCnRwX3BtdHg9MzIK +dHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4Y2g9MAp0cF9tdHVzPTg4LDI1Niw1MTIsNTc2LDgw +OCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIsMjA0OCw0MDk2LDQzNTIsODE5Miw5MDAwLDk2MDAK +cmVnWzB4MTkxNjhdPTB4MDQwMjAxMDAKW2Z1bmN0aW9uIjAiXQpudmY9MTYKd3hfY2Fwcz1hbGwK +cl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApj +bWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIxIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fw +cz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9 +YWxsCnBtYXNrPTB4MgpbZnVuY3Rpb24iMiJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxs +Cm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApw +bWFzaz0weDQKW2Z1bmN0aW9uIjMiXQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9 +MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9 +MHg4CltmdW5jdGlvbiI0Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MjgKbmlxZmxpbnQ9 +MTcwCm5ldGhjdHJsPTEwMApuZXE9MjU2Cm5leGFjdGY9NDAKY21hc2s9YWxsCnBtYXNrPWFsbApu +ZXRob2ZsZD0xMDI0Cm5yb3V0ZT0zMgpuY2xpcD0zMgpuZmlsdGVyPTQ5Ngpuc2VydmVyPTQ5Ngpu +aGFzaD0xMjI4OApwcm90b2NvbD1uaWNfdm0sb2ZsZCxyZGRwLHJkbWFjLGlzY3NpX2luaXRpYXRv +cl9wZHUsaXNjc2lfdGFyZ2V0X3BkdQp0cF9sMnQ9MzA3Mgp0cF9kZHA9Mwp0cF9kZHBfaXNjc2k9 +Mgp0cF9zdGFnPTMKdHBfcGJsPTEwCnRwX3JxPTEzCltmdW5jdGlvbiI1Il0Kd3hfY2Fwcz1hbGwK +cl9jYXBzPWFsbApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjQKbmV4YWN0Zj00 +CmNtYXNrPWFsbApwbWFzaz1hbGwKbnNlcnZlcj0xNgpuaGFzaD0yMDQ4CnRwX2wydD0xMDIwCnBy +b3RvY29sPWlzY3NpX2luaXRpYXRvcl9mb2ZsZAp0cF9kZHBfaXNjc2k9Mgppc2NzaV9udGFzaz0y +MDQ4CmlzY3NpX25zZXNzPTIwNDgKaXNjc2lfbmNvbm5fcGVyX3Nlc3Npb249MQppc2NzaV9uaW5p +dGlhdG9yX2luc3RhbmNlPTY0CltmdW5jdGlvbiI2Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApu +dmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjYKbmV4YWN0Zj0zMgpjbWFzaz1hbGwK +cG1hc2s9YWxsCm5oYXNoPTIwNDgKdHBfbDJ0PTQKcHJvdG9jb2w9ZmNvZV9pbml0aWF0b3IKdHBf +ZGRwPTEKZmNvZV9uZmNmPTE2CmZjb2VfbnZucD0zMgpmY29lX25zc249MTAyNApbZnVuY3Rpb24i +MTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNrPWFsbApu +ZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0w +eDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxs +CnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52aT0x +Cm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPTB4 +MgpbZnVuY3Rpb24iMi8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52aT0xCm5pcWZsaW50 +PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPTB4NApbZnVuY3Rp +b24iMy8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0 +cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPTB4OApbcG9ydCIwIl0KZGNiPXBw +cCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBw +X3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlw +ZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMSJdCmRjYj1wcHAsZGNi +eApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZb +MF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpk +Y2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0IjIiXQpkY2I9cHBwLGRjYngKYmdf +bWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4 +ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2Fw +cF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIzIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0y +NQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYs +ZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2 +WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNpb249MHgxNDI1MDAxYwpjaGVja3N1bT0w +eDVjZWFiNDFlCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbZ2xvYmFsXQpyc3NfZ2xiX2NvbmZpZ19tb2RlPWJh +c2ljdmlydHVhbApyc3NfZ2xiX2NvbmZpZ19vcHRpb25zPXRubG1hcGVuLGhhc2h0b2VwbGl0eix0 +bmxhbGxsa3AKcmVnWzB4MTAwOF09MHg0MDgxMC8weDIxYzcwCnJlZ1sweDEwMGNdPTB4MjIyMjIy +MjIKcmVnWzB4MTBhMF09MHgwMTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sweDEwNDhdPTY1 +NTM2CnJlZ1sweDEwNGNdPTE1MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0XT05MjE2CnJl +Z1sweDEwNThdPTIwNDgKcmVnWzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIKcmVnWzB4MTA2 +NF09MTYzODQKcmVnWzB4MTBhNF09MHhhMDAwYTAwMC8weGYwMDBmMDAwCnJlZ1sweDEwYThdPTB4 +MjAwMC8weDIwMDAKc2dlX3RpbWVyX3ZhbHVlPTUsMTAsMjAsNTAsMTAwLDIwMApyZWdbMHg3ZDA0 +XT0weDAwMDEwMDAwLzB4MDAwMTAwMDAKcmVnWzB4N2Q2Y109MHgwMDAwMDAwMC8weDAwMDA3MDAw +CnJlZ1sweDdkYzBdPTB4MGUyZjg4NDkKZmlsdGVyTW9kZT1mcmFnbWVudGF0aW9uLG1wc2hpdHR5 +cGUscHJvdG9jb2wsdmxhbixwb3J0LGZjb2UKZmlsdGVyTWFzaz1wcm90b2NvbCxmY29lCnRwX3Bt +cng9MzAKdHBfcG1yeF9wYWdlc2l6ZT02NEsKdHBfbnJ4Y2g9MAp0cF9wbXR4PTUwCnRwX3BtdHhf +cGFnZXNpemU9NjRLCnRwX250eGNoPTAKdHBfbXR1cz04OCwyNTYsNTEyLDU3Niw4MDgsMTAyNCwx +MjgwLDE0ODgsMTUwMCwyMDAyLDIwNDgsNDA5Niw0MzUyLDgxOTIsOTAwMCw5NjAwCnJlZ1sweDE5 +MTY4XT0weDA0MDIwMTAwCltmdW5jdGlvbiIwIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9 +MjgKbmlxZmxpbnQ9MTcwCm5ldGhjdHJsPTk2Cm5lcT0yNTIKbmV4YWN0Zj00MApjbWFzaz1hbGwK +cG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbnJvdXRlPTMyCm5jbGlwPTMyCm5maWx0ZXI9NDgKbnNl +cnZlcj0zMgpuaGFzaD0wCnByb3RvY29sPW5pY192bSxvZmxkLHJkZHAscmRtYWMsaXNjc2lfaW5p +dGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1CnRwX2wydD0zMDcyCnRwX2RkcD0yCnRwX2RkcF9p +c2NzaT0yCnRwX3N0YWc9Mgp0cF9wYmw9NQp0cF9ycT03CltmdW5jdGlvbiIxIl0Kd3hfY2Fwcz1h +bGwKcl9jYXBzPWFsbApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjYKbmV4YWN0 +Zj0zMgpjbWFzaz1hbGwKcG1hc2s9YWxsCm5oYXNoPTAKcHJvdG9jb2w9ZmNvZV9pbml0aWF0b3IK +dHBfZGRwPTIKZmNvZV9uZmNmPTE2CmZjb2VfbnZucD0zMgpmY29lX25zc249MTAyNApbZnVuY3Rp +b24iMTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNrPWFs +bApuZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fw +cz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9 +YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52 +aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNr +PTB4MgpbcG9ydCIwIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAK +bHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90 +bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUK +W3BvcnQiMSJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0x +NQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFd +PTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0 +IjIiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdt +PTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5 +MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIzIl0K +ZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApk +Y2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0 +aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNpb249 +MHgxNDI1MDAxYwpjaGVja3N1bT0weGFkNGMxNzRmCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAA +==== diff --git a/sys/dev/cxgbe/firmware/t4fw_interface.h b/sys/dev/cxgbe/firmware/t4fw_interface.h index 85f6b2ca269b..7895206276ff 100644 --- a/sys/dev/cxgbe/firmware/t4fw_interface.h +++ b/sys/dev/cxgbe/firmware/t4fw_interface.h @@ -73,6 +73,7 @@ enum fw_retval { FW_SCSI_OVER_FLOW_ERR = 140, /* */ FW_SCSI_DDP_ERR = 141, /* DDP error*/ FW_SCSI_TASK_ERR = 142, /* No SCSI tasks available */ + FW_SCSI_IO_BLOCK = 143, /* IO is going to be blocked due to resource failure */ }; /****************************************************************************** @@ -140,9 +141,10 @@ enum fw_wr_opcodes { FW_PTP_TX_PKT_WR = 0x46, FW_TLSTX_DATA_WR = 0x68, FW_CRYPTO_LOOKASIDE_WR = 0x6d, - FW_COiSCSI_TGT_WR = 0x70, - FW_COiSCSI_TGT_CONN_WR = 0x71, - FW_COiSCSI_TGT_XMIT_WR = 0x72, + FW_COISCSI_TGT_WR = 0x70, + FW_COISCSI_TGT_CONN_WR = 0x71, + FW_COISCSI_TGT_XMIT_WR = 0x72, + FW_COISCSI_STATS_WR = 0x73, FW_ISNS_WR = 0x75, FW_ISNS_XMIT_WR = 0x76, FW_FILTER2_WR = 0x77, @@ -2093,6 +2095,8 @@ struct fw_ri_wr { #define FW_FOISCSI_NAME_MAX_LEN 224 #define FW_FOISCSI_ALIAS_MAX_LEN 224 +#define FW_FOISCSI_KEY_MAX_LEN 64 +#define FW_FOISCSI_VAL_MAX_LEN 256 #define FW_FOISCSI_CHAP_SEC_MAX_LEN 128 #define FW_FOISCSI_INIT_NODE_MAX 8 @@ -2124,19 +2128,36 @@ enum fw_chnet_ifconf_wr_subop { FW_CHNET_IFCONF_WR_SUBOP_RA_BASED_ADDR_SET, FW_CHNET_IFCONF_WR_SUBOP_ADDR_EXPIRED, + FW_CHNET_IFCONF_WR_SUBOP_ICMP_PING4, + FW_CHNET_IFCONF_WR_SUBOP_ICMP_PING6, + FW_CHNET_IFCONF_WR_SUBOP_MAX, }; struct fw_chnet_ifconf_wr { __be32 op_compl; __be32 flowid_len16; - __be64 cookie; + __u64 cookie; __be32 if_flowid; __u8 idx; __u8 subop; __u8 retval; __u8 r2; - __be64 r3; + union { + __be64 r3; + struct fw_chnet_ifconf_ping { + __be16 ping_time; + __u8 ping_rsptype; + __u8 ping_param_rspcode_to_fin_bit; + __u8 ping_pktsize; + __u8 ping_ttl; + __be16 ping_seq; + } ping; + struct fw_chnet_ifconf_mac { + __u8 peer_mac[6]; + __u8 smac_idx; + } mac; + } u; struct fw_chnet_ifconf_params { __be32 r0; __be16 vlanid; @@ -2163,6 +2184,23 @@ struct fw_chnet_ifconf_wr { } param; }; +#define S_FW_CHNET_IFCONF_WR_PING_MACBIT 1 +#define M_FW_CHNET_IFCONF_WR_PING_MACBIT 0x1 +#define V_FW_CHNET_IFCONF_WR_PING_MACBIT(x) \ + ((x) << S_FW_CHNET_IFCONF_WR_PING_MACBIT) +#define G_FW_CHNET_IFCONF_WR_PING_MACBIT(x) \ + (((x) >> S_FW_CHNET_IFCONF_WR_PING_MACBIT) & \ + M_FW_CHNET_IFCONF_WR_PING_MACBIT) +#define F_FW_CHNET_IFCONF_WR_PING_MACBIT \ + V_FW_CHNET_IFCONF_WR_PING_MACBIT(1U) + +#define S_FW_CHNET_IFCONF_WR_FIN_BIT 0 +#define M_FW_CHNET_IFCONF_WR_FIN_BIT 0x1 +#define V_FW_CHNET_IFCONF_WR_FIN_BIT(x) ((x) << S_FW_CHNET_IFCONF_WR_FIN_BIT) +#define G_FW_CHNET_IFCONF_WR_FIN_BIT(x) \ + (((x) >> S_FW_CHNET_IFCONF_WR_FIN_BIT) & M_FW_CHNET_IFCONF_WR_FIN_BIT) +#define F_FW_CHNET_IFCONF_WR_FIN_BIT V_FW_CHNET_IFCONF_WR_FIN_BIT(1U) + enum fw_foiscsi_node_type { FW_FOISCSI_NODE_TYPE_INITIATOR = 0, FW_FOISCSI_NODE_TYPE_TARGET, @@ -2198,6 +2236,13 @@ enum fw_foiscsi_wr_subop { FW_FOISCSI_WR_SUBOP_MOD = 4, }; +enum fw_coiscsi_stats_wr_subop { + FW_COISCSI_WR_SUBOP_TOT = 1, + FW_COISCSI_WR_SUBOP_MAX = 2, + FW_COISCSI_WR_SUBOP_CUR = 3, + FW_COISCSI_WR_SUBOP_CLR = 4, +}; + enum fw_foiscsi_ctrl_state { FW_FOISCSI_CTRL_STATE_FREE = 0, FW_FOISCSI_CTRL_STATE_ONLINE = 1, @@ -2487,7 +2532,7 @@ struct fw_rdev_wr { struct fw_foiscsi_node_wr { __be32 op_to_immdlen; - __be32 flowid_len16; + __be32 no_sess_recv_to_len16; __u64 cookie; __u8 subop; __u8 status; @@ -2500,6 +2545,7 @@ struct fw_foiscsi_node_wr { __be16 r3; __u8 iqn[224]; __u8 alias[224]; + __be32 isid_tval_to_isid_cval; }; #define S_FW_FOISCSI_NODE_WR_IMMDLEN 0 @@ -2508,8 +2554,46 @@ struct fw_foiscsi_node_wr { #define G_FW_FOISCSI_NODE_WR_IMMDLEN(x) \ (((x) >> S_FW_FOISCSI_NODE_WR_IMMDLEN) & M_FW_FOISCSI_NODE_WR_IMMDLEN) +#define S_FW_FOISCSI_NODE_WR_NO_SESS_RECV 28 +#define M_FW_FOISCSI_NODE_WR_NO_SESS_RECV 0x1 +#define V_FW_FOISCSI_NODE_WR_NO_SESS_RECV(x) \ + ((x) << S_FW_FOISCSI_NODE_WR_NO_SESS_RECV) +#define G_FW_FOISCSI_NODE_WR_NO_SESS_RECV(x) \ + (((x) >> S_FW_FOISCSI_NODE_WR_NO_SESS_RECV) & \ + M_FW_FOISCSI_NODE_WR_NO_SESS_RECV) +#define F_FW_FOISCSI_NODE_WR_NO_SESS_RECV \ + V_FW_FOISCSI_NODE_WR_NO_SESS_RECV(1U) + +#define S_FW_FOISCSI_NODE_WR_ISID_TVAL 30 +#define M_FW_FOISCSI_NODE_WR_ISID_TVAL 0x3 +#define V_FW_FOISCSI_NODE_WR_ISID_TVAL(x) \ + ((x) << S_FW_FOISCSI_NODE_WR_ISID_TVAL) +#define G_FW_FOISCSI_NODE_WR_ISID_TVAL(x) \ + (((x) >> S_FW_FOISCSI_NODE_WR_ISID_TVAL) & M_FW_FOISCSI_NODE_WR_ISID_TVAL) + +#define S_FW_FOISCSI_NODE_WR_ISID_AVAL 24 +#define M_FW_FOISCSI_NODE_WR_ISID_AVAL 0x3f +#define V_FW_FOISCSI_NODE_WR_ISID_AVAL(x) \ + ((x) << S_FW_FOISCSI_NODE_WR_ISID_AVAL) +#define G_FW_FOISCSI_NODE_WR_ISID_AVAL(x) \ + (((x) >> S_FW_FOISCSI_NODE_WR_ISID_AVAL) & M_FW_FOISCSI_NODE_WR_ISID_AVAL) + +#define S_FW_FOISCSI_NODE_WR_ISID_BVAL 8 +#define M_FW_FOISCSI_NODE_WR_ISID_BVAL 0xffff +#define V_FW_FOISCSI_NODE_WR_ISID_BVAL(x) \ + ((x) << S_FW_FOISCSI_NODE_WR_ISID_BVAL) +#define G_FW_FOISCSI_NODE_WR_ISID_BVAL(x) \ + (((x) >> S_FW_FOISCSI_NODE_WR_ISID_BVAL) & M_FW_FOISCSI_NODE_WR_ISID_BVAL) + +#define S_FW_FOISCSI_NODE_WR_ISID_CVAL 0 +#define M_FW_FOISCSI_NODE_WR_ISID_CVAL 0xff +#define V_FW_FOISCSI_NODE_WR_ISID_CVAL(x) \ + ((x) << S_FW_FOISCSI_NODE_WR_ISID_CVAL) +#define G_FW_FOISCSI_NODE_WR_ISID_CVAL(x) \ + (((x) >> S_FW_FOISCSI_NODE_WR_ISID_CVAL) & M_FW_FOISCSI_NODE_WR_ISID_CVAL) + struct fw_foiscsi_ctrl_wr { - __be32 op_compl; + __be32 op_to_no_fin; __be32 flowid_len16; __u64 cookie; __u8 subop; @@ -2530,7 +2614,7 @@ struct fw_foiscsi_ctrl_wr { __be32 r1; } sess_attr; struct fw_foiscsi_conn_attr { - __be32 hdigest_to_ddp_pgsz; + __be32 hdigest_to_tcp_ws_en; __be32 max_rcv_dsl; __be32 ping_tmo; __be16 dst_port; @@ -2551,6 +2635,13 @@ struct fw_foiscsi_ctrl_wr { __u8 tgt_name[FW_FOISCSI_NAME_MAX_LEN]; }; +#define S_FW_FOISCSI_CTRL_WR_NO_FIN 0 +#define M_FW_FOISCSI_CTRL_WR_NO_FIN 0x1 +#define V_FW_FOISCSI_CTRL_WR_NO_FIN(x) ((x) << S_FW_FOISCSI_CTRL_WR_NO_FIN) +#define G_FW_FOISCSI_CTRL_WR_NO_FIN(x) \ + (((x) >> S_FW_FOISCSI_CTRL_WR_NO_FIN) & M_FW_FOISCSI_CTRL_WR_NO_FIN) +#define F_FW_FOISCSI_CTRL_WR_NO_FIN V_FW_FOISCSI_CTRL_WR_NO_FIN(1U) + #define S_FW_FOISCSI_CTRL_WR_SESS_TYPE 30 #define M_FW_FOISCSI_CTRL_WR_SESS_TYPE 0x3 #define V_FW_FOISCSI_CTRL_WR_SESS_TYPE(x) \ @@ -2646,20 +2737,64 @@ struct fw_foiscsi_ctrl_wr { (((x) >> S_FW_FOISCSI_CTRL_WR_IPV6) & M_FW_FOISCSI_CTRL_WR_IPV6) #define F_FW_FOISCSI_CTRL_WR_IPV6 V_FW_FOISCSI_CTRL_WR_IPV6(1U) +#define S_FW_FOISCSI_CTRL_WR_DDP_PGIDX 16 +#define M_FW_FOISCSI_CTRL_WR_DDP_PGIDX 0xf +#define V_FW_FOISCSI_CTRL_WR_DDP_PGIDX(x) \ + ((x) << S_FW_FOISCSI_CTRL_WR_DDP_PGIDX) +#define G_FW_FOISCSI_CTRL_WR_DDP_PGIDX(x) \ + (((x) >> S_FW_FOISCSI_CTRL_WR_DDP_PGIDX) & M_FW_FOISCSI_CTRL_WR_DDP_PGIDX) + +#define S_FW_FOISCSI_CTRL_WR_TCP_WS 12 +#define M_FW_FOISCSI_CTRL_WR_TCP_WS 0xf +#define V_FW_FOISCSI_CTRL_WR_TCP_WS(x) ((x) << S_FW_FOISCSI_CTRL_WR_TCP_WS) +#define G_FW_FOISCSI_CTRL_WR_TCP_WS(x) \ + (((x) >> S_FW_FOISCSI_CTRL_WR_TCP_WS) & M_FW_FOISCSI_CTRL_WR_TCP_WS) + +#define S_FW_FOISCSI_CTRL_WR_TCP_WS_EN 11 +#define M_FW_FOISCSI_CTRL_WR_TCP_WS_EN 0x1 +#define V_FW_FOISCSI_CTRL_WR_TCP_WS_EN(x) \ + ((x) << S_FW_FOISCSI_CTRL_WR_TCP_WS_EN) +#define G_FW_FOISCSI_CTRL_WR_TCP_WS_EN(x) \ + (((x) >> S_FW_FOISCSI_CTRL_WR_TCP_WS_EN) & M_FW_FOISCSI_CTRL_WR_TCP_WS_EN) +#define F_FW_FOISCSI_CTRL_WR_TCP_WS_EN V_FW_FOISCSI_CTRL_WR_TCP_WS_EN(1U) + struct fw_foiscsi_chap_wr { - __be32 op_compl; + __be32 op_to_kv_flag; __be32 flowid_len16; __u64 cookie; __u8 status; - __u8 id_len; - __u8 sec_len; + union fw_foiscsi_len { + struct fw_foiscsi_chap_lens { + __u8 id_len; + __u8 sec_len; + } chapl; + struct fw_foiscsi_vend_kv_lens { + __u8 key_len; + __u8 val_len; + } vend_kvl; + } lenu; __u8 node_type; __be16 node_id; __u8 r3[2]; - __u8 chap_id[FW_FOISCSI_NAME_MAX_LEN]; - __u8 chap_sec[FW_FOISCSI_CHAP_SEC_MAX_LEN]; + union fw_foiscsi_chap_vend { + struct fw_foiscsi_chap { + __u8 chap_id[224]; + __u8 chap_sec[128]; + } chap; + struct fw_foiscsi_vend_kv { + __u8 vend_key[64]; + __u8 vend_val[256]; + } vend_kv; + } u; }; +#define S_FW_FOISCSI_CHAP_WR_KV_FLAG 20 +#define M_FW_FOISCSI_CHAP_WR_KV_FLAG 0x1 +#define V_FW_FOISCSI_CHAP_WR_KV_FLAG(x) ((x) << S_FW_FOISCSI_CHAP_WR_KV_FLAG) +#define G_FW_FOISCSI_CHAP_WR_KV_FLAG(x) \ + (((x) >> S_FW_FOISCSI_CHAP_WR_KV_FLAG) & M_FW_FOISCSI_CHAP_WR_KV_FLAG) +#define F_FW_FOISCSI_CHAP_WR_KV_FLAG V_FW_FOISCSI_CHAP_WR_KV_FLAG(1U) + /****************************************************************************** * C O i S C S I W O R K R E Q U E S T S ********************************************/ @@ -2711,22 +2846,31 @@ struct fw_coiscsi_tgt_conn_wr { __be16 iq_id; __be32 in_stid; __be32 io_id; - __be32 flags; - struct fw_coiscsi_tgt_conn_tcp { - __be16 in_sport; - __be16 in_dport; - __be32 r4; - union fw_coiscsi_tgt_conn_tcp_addr { - struct fw_coiscsi_tgt_conn_tcp_in_addr { - __be32 saddr; - __be32 daddr; - } in_addr; - struct fw_coiscsi_tgt_conn_tcp_in_addr6 { - __be64 saddr[2]; - __be64 daddr[2]; - } in_addr6; - } u; - } conn_tcp; + __be32 flags_fin; + union { + struct fw_coiscsi_tgt_conn_tcp { + __be16 in_sport; + __be16 in_dport; + __u8 wscale_wsen; + __u8 r4[3]; + union fw_coiscsi_tgt_conn_tcp_addr { + struct fw_coiscsi_tgt_conn_tcp_in_addr { + __be32 saddr; + __be32 daddr; + } in_addr; + struct fw_coiscsi_tgt_conn_tcp_in_addr6 { + __be64 saddr[2]; + __be64 daddr[2]; + } in_addr6; + } u; + } conn_tcp; + struct fw_coiscsi_tgt_conn_stats { + __be32 ddp_reqs; + __be32 ddp_cmpls; + __be16 ddp_aborts; + __be16 ddp_bps; + } stats; + } u; struct fw_coiscsi_tgt_conn_iscsi { __be32 hdigest_to_ddp_pgsz; __be32 tgt_id; @@ -2735,79 +2879,148 @@ struct fw_coiscsi_tgt_conn_wr { __be32 max_burst; __be32 max_rdsl; __be32 max_tdsl; - __be32 nxt_sn; + __be32 cur_sn; __be32 r6; } conn_iscsi; }; +#define S_FW_COISCSI_TGT_CONN_WR_FIN 0 +#define M_FW_COISCSI_TGT_CONN_WR_FIN 0x1 +#define V_FW_COISCSI_TGT_CONN_WR_FIN(x) ((x) << S_FW_COISCSI_TGT_CONN_WR_FIN) +#define G_FW_COISCSI_TGT_CONN_WR_FIN(x) \ + (((x) >> S_FW_COISCSI_TGT_CONN_WR_FIN) & M_FW_COISCSI_TGT_CONN_WR_FIN) +#define F_FW_COISCSI_TGT_CONN_WR_FIN V_FW_COISCSI_TGT_CONN_WR_FIN(1U) + +#define S_FW_COISCSI_TGT_CONN_WR_WSCALE 1 +#define M_FW_COISCSI_TGT_CONN_WR_WSCALE 0xf +#define V_FW_COISCSI_TGT_CONN_WR_WSCALE(x) \ + ((x) << S_FW_COISCSI_TGT_CONN_WR_WSCALE) +#define G_FW_COISCSI_TGT_CONN_WR_WSCALE(x) \ + (((x) >> S_FW_COISCSI_TGT_CONN_WR_WSCALE) & \ + M_FW_COISCSI_TGT_CONN_WR_WSCALE) + +#define S_FW_COISCSI_TGT_CONN_WR_WSEN 0 +#define M_FW_COISCSI_TGT_CONN_WR_WSEN 0x1 +#define V_FW_COISCSI_TGT_CONN_WR_WSEN(x) \ + ((x) << S_FW_COISCSI_TGT_CONN_WR_WSEN) +#define G_FW_COISCSI_TGT_CONN_WR_WSEN(x) \ + (((x) >> S_FW_COISCSI_TGT_CONN_WR_WSEN) & M_FW_COISCSI_TGT_CONN_WR_WSEN) +#define F_FW_COISCSI_TGT_CONN_WR_WSEN V_FW_COISCSI_TGT_CONN_WR_WSEN(1U) + struct fw_coiscsi_tgt_xmit_wr { __be32 op_to_immdlen; - __be32 flowid_len16; - __be64 cookie; + union { + struct cmpl_stat { + __be32 cmpl_status_pkd; + } cs; + struct flowid_len { + __be32 flowid_len16; + } fllen; + } u; + __u64 cookie; __be16 iq_id; - __be16 r4; - __be32 datasn; + __be16 r3; + __be32 pz_off; __be32 t_xfer_len; - __be32 flags; - __be32 tag; - __be32 tidx; - __be32 r5[2]; + union { + __be32 tag; + __be32 datasn; + __be32 ddp_status; + } cu; }; -#define S_FW_COiSCSI_TGT_XMIT_WR_DDGST 23 -#define M_FW_COiSCSI_TGT_XMIT_WR_DDGST 0x1 -#define V_FW_COiSCSI_TGT_XMIT_WR_DDGST(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_DDGST) -#define G_FW_COiSCSI_TGT_XMIT_WR_DDGST(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_DDGST) & M_FW_COiSCSI_TGT_XMIT_WR_DDGST) -#define F_FW_COiSCSI_TGT_XMIT_WR_DDGST V_FW_COiSCSI_TGT_XMIT_WR_DDGST(1U) +#define S_FW_COISCSI_TGT_XMIT_WR_DDGST 23 +#define M_FW_COISCSI_TGT_XMIT_WR_DDGST 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_DDGST(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_DDGST) +#define G_FW_COISCSI_TGT_XMIT_WR_DDGST(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_DDGST) & M_FW_COISCSI_TGT_XMIT_WR_DDGST) +#define F_FW_COISCSI_TGT_XMIT_WR_DDGST V_FW_COISCSI_TGT_XMIT_WR_DDGST(1U) -#define S_FW_COiSCSI_TGT_XMIT_WR_HDGST 22 -#define M_FW_COiSCSI_TGT_XMIT_WR_HDGST 0x1 -#define V_FW_COiSCSI_TGT_XMIT_WR_HDGST(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_HDGST) -#define G_FW_COiSCSI_TGT_XMIT_WR_HDGST(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_HDGST) & M_FW_COiSCSI_TGT_XMIT_WR_HDGST) -#define F_FW_COiSCSI_TGT_XMIT_WR_HDGST V_FW_COiSCSI_TGT_XMIT_WR_HDGST(1U) +#define S_FW_COISCSI_TGT_XMIT_WR_HDGST 22 +#define M_FW_COISCSI_TGT_XMIT_WR_HDGST 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_HDGST(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_HDGST) +#define G_FW_COISCSI_TGT_XMIT_WR_HDGST(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_HDGST) & M_FW_COISCSI_TGT_XMIT_WR_HDGST) +#define F_FW_COISCSI_TGT_XMIT_WR_HDGST V_FW_COISCSI_TGT_XMIT_WR_HDGST(1U) -#define S_FW_COiSCSI_TGT_XMIT_WR_DDP 20 -#define M_FW_COiSCSI_TGT_XMIT_WR_DDP 0x1 -#define V_FW_COiSCSI_TGT_XMIT_WR_DDP(x) ((x) << S_FW_COiSCSI_TGT_XMIT_WR_DDP) -#define G_FW_COiSCSI_TGT_XMIT_WR_DDP(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_DDP) & M_FW_COiSCSI_TGT_XMIT_WR_DDP) -#define F_FW_COiSCSI_TGT_XMIT_WR_DDP V_FW_COiSCSI_TGT_XMIT_WR_DDP(1U) +#define S_FW_COISCSI_TGT_XMIT_WR_DDP 20 +#define M_FW_COISCSI_TGT_XMIT_WR_DDP 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_DDP(x) ((x) << S_FW_COISCSI_TGT_XMIT_WR_DDP) +#define G_FW_COISCSI_TGT_XMIT_WR_DDP(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_DDP) & M_FW_COISCSI_TGT_XMIT_WR_DDP) +#define F_FW_COISCSI_TGT_XMIT_WR_DDP V_FW_COISCSI_TGT_XMIT_WR_DDP(1U) -#define S_FW_COiSCSI_TGT_XMIT_WR_ABORT 19 -#define M_FW_COiSCSI_TGT_XMIT_WR_ABORT 0x1 -#define V_FW_COiSCSI_TGT_XMIT_WR_ABORT(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_ABORT) -#define G_FW_COiSCSI_TGT_XMIT_WR_ABORT(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_ABORT) & M_FW_COiSCSI_TGT_XMIT_WR_ABORT) -#define F_FW_COiSCSI_TGT_XMIT_WR_ABORT V_FW_COiSCSI_TGT_XMIT_WR_ABORT(1U) +#define S_FW_COISCSI_TGT_XMIT_WR_ABORT 19 +#define M_FW_COISCSI_TGT_XMIT_WR_ABORT 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_ABORT(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_ABORT) +#define G_FW_COISCSI_TGT_XMIT_WR_ABORT(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_ABORT) & M_FW_COISCSI_TGT_XMIT_WR_ABORT) +#define F_FW_COISCSI_TGT_XMIT_WR_ABORT V_FW_COISCSI_TGT_XMIT_WR_ABORT(1U) -#define S_FW_COiSCSI_TGT_XMIT_WR_FINAL 18 -#define M_FW_COiSCSI_TGT_XMIT_WR_FINAL 0x1 -#define V_FW_COiSCSI_TGT_XMIT_WR_FINAL(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_FINAL) -#define G_FW_COiSCSI_TGT_XMIT_WR_FINAL(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_FINAL) & M_FW_COiSCSI_TGT_XMIT_WR_FINAL) -#define F_FW_COiSCSI_TGT_XMIT_WR_FINAL V_FW_COiSCSI_TGT_XMIT_WR_FINAL(1U) +#define S_FW_COISCSI_TGT_XMIT_WR_FINAL 18 +#define M_FW_COISCSI_TGT_XMIT_WR_FINAL 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_FINAL(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_FINAL) +#define G_FW_COISCSI_TGT_XMIT_WR_FINAL(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_FINAL) & M_FW_COISCSI_TGT_XMIT_WR_FINAL) +#define F_FW_COISCSI_TGT_XMIT_WR_FINAL V_FW_COISCSI_TGT_XMIT_WR_FINAL(1U) -#define S_FW_COiSCSI_TGT_XMIT_WR_PADLEN 16 -#define M_FW_COiSCSI_TGT_XMIT_WR_PADLEN 0x3 -#define V_FW_COiSCSI_TGT_XMIT_WR_PADLEN(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_PADLEN) -#define G_FW_COiSCSI_TGT_XMIT_WR_PADLEN(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_PADLEN) & \ - M_FW_COiSCSI_TGT_XMIT_WR_PADLEN) +#define S_FW_COISCSI_TGT_XMIT_WR_PADLEN 16 +#define M_FW_COISCSI_TGT_XMIT_WR_PADLEN 0x3 +#define V_FW_COISCSI_TGT_XMIT_WR_PADLEN(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_PADLEN) +#define G_FW_COISCSI_TGT_XMIT_WR_PADLEN(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_PADLEN) & \ + M_FW_COISCSI_TGT_XMIT_WR_PADLEN) -#define S_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN 0 -#define M_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN 0xff -#define V_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN(x) \ - ((x) << S_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN) -#define G_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN(x) \ - (((x) >> S_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN) & \ - M_FW_COiSCSI_TGT_XMIT_WR_IMMDLEN) +#define S_FW_COISCSI_TGT_XMIT_WR_INCSTATSN 15 +#define M_FW_COISCSI_TGT_XMIT_WR_INCSTATSN 0x1 +#define V_FW_COISCSI_TGT_XMIT_WR_INCSTATSN(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_INCSTATSN) +#define G_FW_COISCSI_TGT_XMIT_WR_INCSTATSN(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_INCSTATSN) & \ + M_FW_COISCSI_TGT_XMIT_WR_INCSTATSN) +#define F_FW_COISCSI_TGT_XMIT_WR_INCSTATSN \ + V_FW_COISCSI_TGT_XMIT_WR_INCSTATSN(1U) + +#define S_FW_COISCSI_TGT_XMIT_WR_IMMDLEN 0 +#define M_FW_COISCSI_TGT_XMIT_WR_IMMDLEN 0xff +#define V_FW_COISCSI_TGT_XMIT_WR_IMMDLEN(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_IMMDLEN) +#define G_FW_COISCSI_TGT_XMIT_WR_IMMDLEN(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_IMMDLEN) & \ + M_FW_COISCSI_TGT_XMIT_WR_IMMDLEN) + +#define S_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS 8 +#define M_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS 0xff +#define V_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS(x) \ + ((x) << S_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS) +#define G_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS(x) \ + (((x) >> S_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS) & \ + M_FW_COISCSI_TGT_XMIT_WR_CMPL_STATUS) + +struct fw_coiscsi_stats_wr { + __be32 op_compl; + __be32 flowid_len16; + __u64 cookie; + __u8 subop; + __u8 status; + union fw_coiscsi_stats { + struct fw_coiscsi_resource { + __u8 num_ipv4_tgt; + __u8 num_ipv6_tgt; + __be16 num_l2t_entries; + __be16 num_csocks; + __be16 num_tasks; + __be16 num_ppods_zone[11]; + __be32 num_bufll64; + __u8 r2[12]; + } rsrc; + } u; +}; struct fw_isns_wr { __be32 op_compl; @@ -2816,7 +3029,8 @@ struct fw_isns_wr { __u8 subop; __u8 status; __be16 iq_id; - __be32 r4; + __be16 vlanid; + __be16 r4; struct fw_tcp_conn_attr { __be32 in_tid; __be16 in_port; @@ -2838,7 +3052,7 @@ struct fw_isns_wr { struct fw_isns_xmit_wr { __be32 op_to_immdlen; __be32 flowid_len16; - __be64 cookie; + __u64 cookie; __be16 iq_id; __be16 r4; __be32 xfer_len; @@ -8289,7 +8503,7 @@ enum fw_devlog_facility { FW_DEVLOG_FACILITY_FOISCSI = 0x30, FW_DEVLOG_FACILITY_FOFCOE = 0x32, FW_DEVLOG_FACILITY_CHNET = 0x34, - FW_DEVLOG_FACILITY_COiSCSI = 0x36, + FW_DEVLOG_FACILITY_COISCSI = 0x36, FW_DEVLOG_FACILITY_MAX = 0x38, }; @@ -8830,7 +9044,8 @@ struct fw_dcb_ieee_cmd { } dcbx_app_stats; struct fw_dcbx_control { __be32 multi_peer_invalidated; - __be32 r5_lo; + __u8 version; + __u8 r6[3]; } dcbx_control; } u; }; @@ -9383,17 +9598,17 @@ enum fw_hdr_chip { enum { T4FW_VERSION_MAJOR = 0x01, T4FW_VERSION_MINOR = 0x10, - T4FW_VERSION_MICRO = 0x3b, + T4FW_VERSION_MICRO = 0x3f, T4FW_VERSION_BUILD = 0x00, T5FW_VERSION_MAJOR = 0x01, T5FW_VERSION_MINOR = 0x10, - T5FW_VERSION_MICRO = 0x3b, + T5FW_VERSION_MICRO = 0x3f, T5FW_VERSION_BUILD = 0x00, T6FW_VERSION_MAJOR = 0x01, T6FW_VERSION_MINOR = 0x10, - T6FW_VERSION_MICRO = 0x3b, + T6FW_VERSION_MICRO = 0x3f, T6FW_VERSION_BUILD = 0x00, }; @@ -9460,5 +9675,16 @@ struct fw_ephy_hdr { enum { FW_EPHY_HDR_MAGIC = 0x65706879, }; + +struct fw_ifconf_dhcp_info { + __be32 addr; + __be32 mask; + __be16 vlanid; + __be16 mtu; + __be32 gw; + __u8 op; + __u8 len; + __u8 data[270]; +}; #endif /* _T4FW_INTERFACE_H_ */ diff --git a/sys/dev/cxgbe/firmware/t5fw-1.16.59.0.bin.uu b/sys/dev/cxgbe/firmware/t5fw-1.16.59.0.bin.uu deleted file mode 100644 index d69c84336820..000000000000 --- a/sys/dev/cxgbe/firmware/t5fw-1.16.59.0.bin.uu +++ /dev/null @@ -1,11247 +0,0 @@ -/*- - * Copyright (c) 2017 Chelsio Communications, Inc. - * All rights reserved. - * - * 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 AUTHOR 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 AUTHOR 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. - */ -begin-base64 644 t5fw -AAEE4QEQOwAAAQQJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAABMIE0QTaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IFNhdCBBdWcgMTIgMDU6 -MDA6MTAgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j -dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDV4eCAwMS4xMC4zYi4wMAAAAAAAAAAAAAAAAIzU6cNg -AMgAH/zhSOEAe/AAEAAA4QAwuHj///8f/OFAgAAAAeEAe3AAABAAH//+kCAAAADhAZwE4QUAAAAC -AEDhBQgAAAYAQAACAAwABgAM4QUABAAMgACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA -AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//j+AAAAAA -H/+P5AAAAAAf/4/oAAAAAB//j+wf/8AAAAAAAAAAAADAABH/zSIKh5IQghAS/8wT/8yTIBL/zBP/ -zIQgBDMBkyAR/8oS/8uSEBH/yhL/y5IQEf/KAfQxAOQxAAUxAQIAEv/IAucxAhYAEf/GgRABAV/A -IQIRAckTEf/EEv/EkhAR/8QS/8SSEGAAEQAAEf++Ev/CkhAR/74S/8GSEIEQEf/AwCCSERL/v5IS -wCCSExL/vpIQghAC8lBlL/cR/7zHL5IQEf+7khAS/7sT/7uTIMAykyET/7qTIoIiEv+5E/+5kyAj -IiEU/7gEMwHJOBP/t4MwA4MUCDMRFP+1pDOTIRP/qZMiYAAIwjCTIRP/ppMiEv+wkCCQIZAikCOQ -JJAlkCaQJ5AokCmQKpArkCyQLZAukC8gJhAgJhGCIhL/o8AwLTcwLTc0LTc4LTc8Iz0BcjPtAAIA -Ev+gIwoALzcALzcQLzcgLzcwIz0BcjPtAAIAEv+VwDAoNzAoNzQoNzgoNzwjPQFyM+0S/5TAMCc3 -ACc3ECc3ICc3MCM9AXIz7RL/jxX/jxb/j8Aw1yAFZgFgABQAAAQ2BQACANMP0w8FMwxuOxQHRxQH -BEN2MeYENgUFMwxvO+0AAgAS/4MV/4EjCgACJwIHBEMEPgUFMwwHRxRvO/ADAgAS/33JLoMghCGF -IrwidDsOhlC0VZYwtDN0M/Rj/+YAZT/iZV/fEv9xwDIDLgUDAgAS/2jAMCg3QCg3RCg3SCg3TCM9 -AXIz7QACABL/ay0nAMARAUkxAEgxAQIAwAAU/2gE0jEV/2eUUBT/ZwTTMRX/ZpRQFP9mBNQxFf9m -lFAU/2UE1TEV/2WUUBD/ZQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA -H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/4AAH/+FsOMACfgf/4WwH/+FsOMAD6gf -/4WwH/+FsOMAD6gf/4WwH/+HnOMAD6gf/4ecH/+P2OMAEZQf/4/gH/+xcOMAGdgf/7FwH/+xcOMA -O2gf/8AAH///feMAO2ggAAAAIAABauMAeuggAAF4IAABfOMAfFQgAAF8IAABheMAfFggAAGYIAAB -nOMAfGQgAAGcIAABpeMAfGggAAG4IAABvOMAfHQgAAG8IAABxeMAfHggAAHYIAAB2OMAfIQgAAHc -IAAB4uMAfIQgAAH4IAAB+OMAfIwgAAH8IAAB/OMAfIwgAAIYIAACGOMAfIwgAAIcIAACHOMAfIwg -AAI4IAACOOMAfIwgAAI8IAACPOMAfIwgAAJYIAACWOMAfIwgAAJcIAACYuMAfIwgAAJ4IAACeOMA -fJQgAAJ8IAACguMAfJQgAAKYIAJu0uMAfJwgAwAAIAMbLOMC6NggAxssIAMbLOMDBAQgAxswIAev -FOMDBAggB68gIAey4OMHl/ggCAAAIAgbAOMHm7ggCBsAIAlRauMHtrggCVFwIAlS8OMI7SggCwAA -IAsAAOMI7qggCwAAIAsAAOMI7qggCwAAIAuTqOMI7qgAAAAAAAAAAAAAAAAgAHH2IABx6CAAddIg -AHHoIAB1TSAAceggAHKaIAB05SAAdGogAHHoIAB0GSAAc9IgAHNlIABx1SAAcw8gAHHoIABx6CAA -ceggAHK6AAAAAP///////w/8///w////APwgASF2IAEixSABIvYgASK9IAEigyABInwgASJKIAEi -QiABIjkgASHvIAEi9CABIecgASG+IAEi9iABIbcgASGnARAYAQAEAAAAAAAAAAAAAAACAgUFCAgL -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 -IAMRAAwAAAAf/5ZQH/+WQB//m+z//7//v////wQBAAjDAAAAH/+u0B//qmQf/65MH/+nBCALAGAf -/6yoH/+spB//rQgf/63QIAsFcAAPQkAgAwyoIAAg6CALBOAgABbQIAsFoCALBLAgCwUQIAsFQCAD -mGggAwy4AABgAABgAABgAAAAAACG3SALBdAgACnEKgAAACAAfhggAwyIIAOhPCALBfAgABtkIAMM -yB//lcAAAgAAAABAAIIAAAAgAxEkIAAukCAAAAAf/6pUGgAAACBgAAAf/6j4gAAAACAAM2AAAP// -IAsHECALCCAgCwigIAsHkCALB9AgCwhwIAsHYB//qbAAD///AAAP/gAAEAAAQAAAIACw9B//qjAg -AD9cIAA9uCAAPhwgAInsABAAACALZgAgAD58H/+rHAAAIAAgAw90AABIACAAP8Qf/6loIAtmICAD -DvggAw60IAMOdCAARoAf/6pEIABKkCALCMAPPAAAIABRoCAHszAgB7YgIAClKA8AAAAgBFeoIAsJ -MCALCWAFAAAAg/8AACALCaAgAFvcIAsJAB//q0AgCwowAgAAAB//q0ggA8DYH/+nlB//qwAgAGUY -IACjXCADDzgf/4TwH/+AsGdFIwHvzauJmLrc/hAyVHYf/4AAAAA/KCADE0zP////IAsLYBAAAAA/ -////QAAAAAgAAAAA////9////yALDMAAAIAAIAPnYCAHtyAgB7cmIAe2uAAACAAgB7dCIACEfCAD -5KAf/6yUH/+r9P/+//8gAIgEIAQx3ABMS0AgBDmoH/+rJOEAAAAgCw/w//9//yAEWVD/+///D/6A -AP//8AAgCxAgIAsQcA/2gAAgCxCgIAsQ0AAEAAAAAQAAIAtpwCALEaAgCxFgIAChLCAAouggAJ8E -IAsTQCALEgAgCxKQIACc3CALEuBTAAAAUgAAAFEAAAAgAlk8IAsT8CALFDAgCxNgIAsT0CALFID/ -9///IABZVB//p3Af/6sY//3//wQAAAAgBE6wAAgAACAAsFQgCxTQH/+aVB//quQgCxaQFAAAAIAA -AAJ8UAAAgAAAEIAAAAaAAAAFAAAKAIAAsAAA/zSS///wD4AAsQDhAZoAIAsWUB//l8gAAH5AH/+r -FAD/wAABAAAAKAAAAOAAAAAmAAAABYAAAAYAAAAf/6bIKwAAACAAx/Qf/N4AH/+olAOAAAAH//// -NQAAAANAAAAAP///gEAAAAgP//8f////wgAAAAAAwAAf/6r4PQAAAB//qZQHAAAAgQQBAIEEAAAf -/6rQAAA6mAAAD/8AQwAAH/+oWCALa+Af/67wH/+wpOEAegAf/6sEH/+aXB//mlAgC2wQAAMHgCAL -bIAf/5gwACAAAAAACQAAADAA//z4f8AAAACj/7sAo/+6AA0AAADgAwAAg/+2AA////8P//gA/wAA -AA///gEgC2zAIAsX0CALGAAgC21QAA8AAAAKAAD//wAPH/+aZAP/wACD/8AAIAtt0CALbkAf/6vo -H/+vYB//r0D/YPAAH/+AUB//j/AEgAAIAEQAAP8f//8AwAAAAYDCAAADAgDhAOAAAACBAP+///// -/wAAAIAAAB//kOAAAAnMH/ziDO4AAAAgCxhAH/+riAAACMwf/5pMH/+cSB//ljwf/4BgIAexAAAA -JxAf/9zQIAtz8CALc8Af/5Y0H/+aRN6tvu8gAwlANAAAAD8AAAAf/6zEH/+uaACZAAAAAIkGEAAH -AgHAgACZAAAAH/+tMACIAAiCgAABH/+uuB//rMgADwP/AxEAAAMVAAAgAVPgIAFY+CkAAAAAAIkU -IAFfKCADDPQgAxEoIAFsLB//r4AAAB9QIAMNBB//rHAf/62IqqqqqszMzMz/AP8A8PDw8B//p1gA -A///AAAn/yADDUggC3RAIAF8TCADX3gf/6oAH/+ruAAJAAAgAZMsH/+rbCAAK/wAABwgIAt3UCAL -d4AgACeEIAsm8CALJ0AgC3YQIAt2MCALJ3AgCyfAIAt20CALdvAgCycgIAt3ICALdmAgC3aQIAsn -8H8AAADwAAAAIAt3sCAAhNA7AAAIDgAAANAAAAAf/4CgAAAgOh/84uQAAAhQAAAfQCALKRAgCykw -IAspUAAJAAgf/660MAAAAB//qVQgCyxwIAsroCALLAAgCyxAAADgAP//9/8gCy0AIANlPAAAg/8g -B7eYIAe4kBWgAAAgAwtIH/+ueAAACAYAAIjMIAstMB//l+AABAP/CgAAACAHtcgzAAAAH/+vdAP/ -4AB///8AAAD//gA/9pAf/66AAAAgSAP/8AAgC2AwIAtf8CALYFAf/7CAH/+ufB//rIAf/6sgIAt5 -oCAHsJwf/6UwIAstoMAEAAAf/6kQH/+pBB//qRwf/68wH/+umCAEOsAgCy3gH/+osOABAAAf/5vw -IAt60CALLiAgAR2wH/+b6CABGqAgC3pQIAt6oB//mAAgCzCgH/+b9CALPRDg//4AIAti0B//pxwf -/5IsH/+rEB//ryQgC0ggIAtIUEgAAAAgAjFAH/+opCACM0Af/6a0H/+WsB//qaQf/6Z8AAAWTB// -qXQgB7MkH/+m5OEAXgAf/6h8AE01oAAASLkf/5ZU4QAuAB//qYDhAwYA4QAOAOAFAAAD/wAAH/+m -hCADETAf/L//PAAAAAAH//+DAAAAH/+mvCALX7AgAl9kIAJhjCACZWgf/6wEIAJq2OAGAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAIGAAAAAAAAA/////////////////////x///aQf//2kH//9aB// -/Wgf//1oH//9aB//9bAf//ogH//4SB//+Egf//hIIAd6yAAAAAAAAAAAAAAAAAAAAAAgB304IAd9 -OAAAAAAAAAAAAAAAAAAAAAAgB3rIIAd6yB//+xwf//scH//7HB//+xwf//scH//7HAAAAAAgAjms -AAAAAAAAAAAAAAAAAAAAAAIBAAAAAAAAAAAAAAAAAAAEAAAAAAAAAIGAAAAAAAAQAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAKABHxaxPxa9MP -A+YxAQIAFvFpF/Fqd2sGkGC0Zndj+FQPbxTxZwdAAA8UAGP/+WwQCIoiKCAHiTD7Cv8oIAFAMPWh -YmkAAUwwKiAWmRP4FgQgMgRasPS1GgIAAFCwWFS5iBT0omhg/xBYMBrxVhnxViyiSvmSfyFXADcg -JqJJCWYB+WwAAVEANaAd8VAt0IAMhxH/8U8WACBV8PxyOiBuAmtwDU0UpN3/jwoABgJrcP/ylyoA -he8QLnI5/+YBDgCAf5AoIBaZEvoK7SAuBFowKTAQ+zELJgDOVlC8uwIqAlhUuiggFCwgBKSI+AlH -AgCAAyD5JBQsAJgSYB7xNighB40TGfE2/PE0GUABQDD8iBEAHgJ7cP9PFAgJAEow+GYAKuABKDD7 -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 -BD5g9WEidAAgSTAMVxEHRAwABIsIWGDwBIAPlAC5YCIhBQkiEaJS0Q8oJQXz/9tgABAoMGwQBMBR -AyQsAyIuAlI5pCLRDwAAARAYAQABAAAAAAAAAAAAACADWIIgA1jlIANYbyADWOUgA1hvIANY5SAD -WIYgA1iGIANYzSADWLUgA1idAAAAACADYa8gA2GvIANfwCADYa8gA1/AIANhjCADYWUgA1/AIANg -lSADX8AgA1/AIANgjCADX8AgA2GvIANfwCADX8AgA2GvIANfywAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAACADpvkgA6bRIAOm6CADpuggA6boIAOm6CADpuggA6boIAOonyADqGMgA6boIAOm6CADpugg -A6boIAOm6CADpuggA6gVIAOnrCADp1IgA6c9IAOnKCADpxYDAQACAAAAACAE/eMgBP7oIAT/fSAE -/eMgBP91IAT/WCAE/eMgBP3jIAT94yAE/z0gBP3jIAT94yAE/eMgBP3jIAT94yAE/eMgBP8wIAT/ -IyAE/eMgBP3jIAT94yAE/eMgBP3jIAT94yAE/eMgBP3jIAT94yAE/eMgBP3jIAT94yAE/eMgBP3j -IAT+SCAE/eMgBP5CIAT+QiAE/eMgBP5CIAT+QiAE/wAgBP5CAAAAAAAAAAAAAAAAIAUdCCAFHQgg -BRxqIAUdCCAFGW0gBR0AIAUc4CAFGW0gBRltIAUZbSAFGW0gBRltIAUcTiAFHQggBRltIAUcTiAF -HQgAAAAAAAAAAAAAAAAgBSpjIAUo0yAFLPMgBSyrIAUsayAFLDEgBSwLIAUpKyAFK+MgBSujIAUr -RCAFKu0gBSqjIAUqfQEQGAEAAgAAARAYAQACAAAAAAAAAAAAACAF7L8gBehBIAXskyAF7GcgBew6 -IAXsJSAF6GMgBeh6IAXsDCAF6K8gBeibIAXoYyAF6K8gBehjIAXoYyAF6GMgBey/AAAAAAAAAAAA -AAAAAAAAACAGOCQgBi/QIAYveCAGLGQgBifwAAAAAAAAAAAgBi+4IAYvsiAGL7IgBi+yIAYvuCAG -L7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYv -siAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+y -IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7Ig -Bi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+4IAYvsiAG -L7IgBi+yIAYvuCAGL7IgBi+yIAYvsiAGL7ggBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYv -uCAGL7IgBi+yIAYvsiAGL7ggBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvuCAGL7IgBi+y -IAYvsiAGL7ggBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvuCAGL7IgBi+yIAYvsiAGL7gg -Bi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvuCAGL7IgBi+yIAYvsiAGL7ggBi+yIAYvsiAG -L7IgBi+4IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYv -siAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7ggBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+y -IAYvsiAGL7IgBi+yIAYvsiAGL7ggBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7Ig -Bi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAG -L7ggBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvuCAGL7IgBi+yIAYvsiAGL7IgBi+yIAYv -siAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+y -IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7Ig -Bi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAG -L7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+4IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYv -siAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+y -IAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7Ig -Bi+yIAYvsiAGL7IgBi+yIAYvsiAGL7IgBi+yIAYvsiAGL7gAAAAAAAAAAAAAAAAgBjANIAY0cSAG -NFYgBjRCIAY0JyAGNBMgBjPyIAYz3iAGM70gBjOqIAYzkSAGM34gBjNlIAYzUiAGMzkgBjAJIAYz -HyAGMwwgBjLzIAYy3yAGMsQgBjKDIAYyQyAGMoMgBjJDIAYyLyAGMhQgBjAJIAYwCSAGMAkgBjAJ -IAYyASAGMCYgBjAJIAYwCSAGMAkgBjHkIAYxyyAGMbsgBjGkIAYwCSAGMZEgBjF3IAYxZCAGMUog -BjE3IAYxHyAGMQwgBjD5IAYwnSAGMAkgBjAJIAYwCSAGMAkgBjAJIAYwCSAGMGsgBjBbIAYwQwAA -AAAgBjhvIAY4eSAGOoIgBjpWIAY6TyAGOkggBjpBIAY6OiAGOjMgBjosIAY6JSAGOhsgBjoRIAY5 -+SAGOc4gBjmlIAY5nCAGOYEgBjl3IAY5aSAGOVkgBjlSIAY5PCAGOTUgBjhgIAY5DCAGOQIgBjj4 -IAY48SAGOOogBjjaIAY4oiAGOJsgBjiUIAY4hgAAAAAAAAAFAAAABQAAAAoAAAAKAAAACgAAAAoA -AAAKAAAACgAAAAoAAAAKAAAACgAAAAAgBurAIAboHCAG5rAgBuRgIAbiCCAG1ZAgBtaIIAbgQCAG -1QQgBuLMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJSgDDwgSpaiDjpOSAAAAAFJWAAAQAAAAY29u -ZmlndXJhdGlvbiBmaWxlIHBhcnNlciBmb3VuZCBhZGRpdGlvbmFsIGNvbmZpZ3VyYXRpb24gYWZ0 -ZXIgW2ZpbmldCgAAMAAAAGZjb2UAAAAAdm5pY19pZAB2bGFuAAAAAHRvcwBldGhlcnR5cGUAAABt -YWNtYXRjaAAAAABtcHNoaXR0eXBlAABmcmFnbWVudGF0aW9uAAAAc3J2cnNyYW0AAAAAZmNvZW1h -c2sAAAAAY29tcGFjdABwZl92ZgAAAG91dGVyX3ZsYW4AAGJhc2ljdmlydHVhbAAAAABnbGJfa2V5 -AGdsYnZmX2tleQAAAHBmdmZfa2V5AAAAAGlkeHZmX2tleQAAAHN5bm1hcGVuAAAAAHN5bjR0dXBl -bmlwdjYAAABzeW4ydHVwZW5pcHY2AAAAc3luNHR1cGVuaXB2NAAAAHN5bjJ0dXBlbmlwdjQAAABv -ZmRtYXBlbgAAAAB0bmxtYXBlbgAAAAB0bmxhbGxsa3AAAABoYXNodG9lcGxpdHoAAAAAbGFuAHdh -bgBjbHVzdGVyAG1hbnVhbAAAdHBfcGlvAAB0cF90bV9waW8AAABuaWNfdm0AAG5pY191bQAAbmlj -X3VtX2lzZ2wAbmljX2hhc2hmaWx0ZXIAAG9mbGQAAAAAcmRkcAAAAAByZG1hYwAAAGlzY3NpX2lu -aXRpYXRvcl9wZHUAaXNjc2lfdGFyZ2V0X3BkdQAAAABpc2NzaV9pbml0aWF0b3JfZm9mbGQAAABp -c2NzaV90YXJnZXRfZm9mbGQAAGZjb2VfaW5pdGlhdG9yAABmY29lX3RhcmdldABwb2Zjb2VfaW5p -dGlhdG9yAAAAAHBvZmNvZV90YXJnZXQAAABpc2NzaV90MTBkaWYAAAAAaXNjc2lfaW5pdGlhdG9y -X2NtZG9mbGQAaXNjc2lfdGFyZ2V0X2NtZG9mbGQAAAAAdGxza2V5cwBjcnlwdG9fbG9va2FzaWRl -AAAAAHBwcABkY2J4AAAAAGIyYgBzb2NrZXRudW0AAABjZWUAaWVlZQAAAABhdXRvAAAAAGFuX2Rp -cwAAcGRsaXRlX2RpcwAAIAMauAAEAAAAAAQAAAQAAP8CAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8CAAAAAAAAAAAAAAABAAL/AgAAAAAAAAAAAAAAAAAC/wIA -AAAAAAAAAAAAAAAAFgAAAAAAAAAAAAAAACAG1MgAAAAAIAbUGCAG0aggBtCAIAavKCAGQZwgBidI -IAYmKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAEj2QgBJwwIAScMCAEnDAgBKv4IATIICAE1hgg -BN90IASMXCAEidAgBH+0IAT8xCAEfWAgBHpQIAYl/CAGJMwgBh4YIAScMCAGHUQgBht0IAYaqCAH -gFAgBAikIARg/CAG9ZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACADVvggAz/EIANQ -dCADTfQgA0x8AAAAACADShggA1YwAAAAACAEcXQAAAAAAAAAAAAAAAAgA6aMAAAAAAAD//8AAAP/ -AAAAPwAAAA8gBzrAIAc5+CAHkbQgBznoIAc6JCAHOTwgBzqoIAc5DCAHkaAgBznU/xgwYGAAAAAA -AQIDAAAAAAAAAAAAAAAAIAbrbCAEjbQgAN8gAAAAAAAAAIEAAAAAAAAAAAAAAAAAAQIDAgIDAwAC -AwUDAwUFIARkHCAEZaggBGVEIARlvCAEZDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIARk -zAAAAAAAAAAAAAAAAAAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAW -AAAAFwAAABgAAAAZAAAAGgAAABsAAAAAAAAABAAAAAQAAAAIAAAQAAAAIAAAAEAAAACAAAABAAAA -AgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAAP////////AA//////// -4AD////////AAP///////4AA////////AAD///////4AAP///////AAA///////4AAD///////AA -AP//////4AAA///////AAAD//////4AAAP//////AAAA//////4AAAD//////AAAAP/////4AAAA -MDEyMzQ1Njc4OWFiY2RlZkFCQ0RFRgAAAAAAAAAAAABBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ -WmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvAAAAAAAAAAAAAAAAAAAAACAA -howAAQAAIACGbAAFAAEgAIZQAAMABSAAhjAABwAAY4JTYwAAAAD///////8AAAAmGgsKCCsyQQJE -QAMtAAAAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAY -AAAAGQAAABoAAAAbAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAA -gAAAAQAAAAIAAAAEAAAACAAAAP////////AA////////4AD////////AAP///////4AA//////// -AAD///////4AAP///////AAA///////4AAD///////AAAP//////4AAA///////AAAD//////4AA -AP//////AAAA//////4AAAD//////AAAAP/////4AAAAAAAAAAAAAAQAAAAEAAAACAAEBAgAAAAA -AAAAAAAAAAD//wED/wL///8AAAAAAAAAAAQECAAEBAgABAQIAAQECAAEBAgAB0MAAAAAAAAAAAAA -IQAJAIEAQQAhAAkAIQAJAIEAQQCBAEEAgQBBAIEAQQAhAAkAgQBBACEACQAhABEAgQBBAIEAQQAh -AAkAgQBBACEACQAhAAkBAQBBAIEAIQCBACEAEBBhAQEAgQEBAIEDAgEABAAAABAgQAAAAAAABAAC -AAEAAIAAQAAgABAACCBAgAAAAAAAAAAAAAAAAAAgAwmQAAAAACADE3gAAAAAIAMJlAAAAAEgAxQg -AAAAAiADCZwAAAAEIAMJpAAAAAggAwmsAAAAECADFCgAAAAgIAMJsAAAAEAgAwm8AAAAgCADCcgA -AAEAIAMJ1AAAAgAgAwnkAAAgACADCfAAAEAAIAMJ/AAAgAAAAAAAAAAAAAAAKhwAACo8AAAqXAAA -KnwIBwQDCgkCAAAAAAAAAAAAAEAAQAAQABAACAAIAAQAAgAAAAAAAAAAAAAAAAAAAAAAAAIEAAAA -RAAAAAQAAABAIAbvECAG7sggBu2YIAbsPCAG6/ggBuvMIAbsJAAAAAAAAAIAAAAEAAAACABZZXMA -MDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6AAAAAG5vbmUAAAAAYWxsACoAAABk -aXNhYmxlZAAAAABlbmFibGVkADB4AABOQQAAVjAAAFYxAABWMgAAVjMAAFY0AABWNQAAVjYAAFY3 -AABWOAAAVjkAAFZBAABWQgAAVkMAAFZEAABWRQAAVkYAAFZHAABWSAAAVkkAAFZKAABWSwAAVkwA -AFZNAABWTgAAVk8AAFZQAABWUQAAVlIAAFZTAABWVAAAVlUAAHBvcnQAAAAAcHJvdG9jb2wAAAAA -Z2xvYmFsAABmdW5jdGlvbgAAAABmaW5pAAAAAHJlZwBmaWx0ZXJNb2RlAABmaWx0ZXJNYXNrAAB2 -bmljTW9kZQAAAAByc3NfZ2xiX2NvbmZpZ19tb2RlAHJzc19rZXltb2RlAHJzc19nbGJfY29uZmln -X29wdGlvbnMAAHNnZV90aW1lcl92YWx1ZQB0cF9wbXJ4AHRwX3BtcnhfcGFnZXNpemUAAAAAdHBf -cG1yeF9mbGFncwAAAHRwX25yeGNoAAAAAHRwX3BtdHgAdHBfcG10eF9wYWdlc2l6ZQAAAAB0cF9u -dHhjaAAAAAB0cF9tdHVzAHRwX3RjcHR1bmluZwAAAAB0cF90aW1lcnJlcwB0cF90aW1lcnZhbHMA -AAAAdHBfYmFja29mZnZhbHMAAHNjaGVkX2lvcXR4X2JwX3ByaW9yaXR5AHBjaWVfbWFfcnNwX3Rp -bWVydmFsdWUAAHBsX3RpbWVvdXRfdmFsdWUAAAAAbWVtZnJlZV9jb25maWcAAGJhc2VfbWFjX3Bm -AGJhcjJ0aHJvdHRsZWNvdW50AAAAY3BsdHhkYXRhX21lbWFsaWduAABtY19wZAAAAG9mbGRfZmxh -Z3MAAG1jX21vZGVfYnJjAG1jAABudmYAd3hfY2FwcwByX2NhcHMAAG5pcWZsaW50AAAAAG5lcQBu -cXBjcQAAAG5ldGhjdHJsAAAAAG52aQByc3NudmkAAHJzc25zZWNyZXQAAG5leGFjdGYAbnJhd2YA -AABjbWFzawAAAHBtYXNrAAAAbmV0aG9mbGQAAAAAbnJvdXRlAABuY2xpcAAAAG5maWx0ZXIAbnNl -cnZlcgBuaGFzaAAAAHRwX2wydAAAdHBfZGRwAAB0cF9kZHBfaXNjc2kAAAAAdHBfc3RhZwB0cF9w -YmwAAHRwX3JxAAAAaXNjc2lfbnRhc2sAaXNjc2lfbnNlc3MAaXNjc2lfbmNvbm5fcGVyX3Nlc3Np -b24AaXNjc2lfbmluaXRpYXRvcl9pbnN0YW5jZQAAAGlzY3NpX21heF9zZ2UAAABwcG1fbWF4X3pv -bmVzAAAAcHBtX3pvbmVfcmFuZ2UwAHBwbV96b25lX3JhbmdlMQBwcG1fem9uZV9yYW5nZTIAcHBt -X3pvbmVfcmFuZ2UzAGNvaXNjc2lfbnRhcmdldABjb2lzY3NpX250YXNrAAAAZmNvZV9uZmNmAAAA -ZmNvZV9udm5wAAAAZmNvZV9uc3NuAAAAZmNvZV9uZmNiAAAAZGNiAGRjYl9hcHBfdGx2AGRjYl9k -Y2J4X3Byb3RvY29sAAAAYmdfbWVtAABscGJrX21lbQAAAABod20AbHdtAGR3bQBkZWJvdW5jZXRp -bWUAAAAAYW5fYWVjX3RpbWUAYWVjX3JldHJ5X2NudAAAAHZlcnNpb24AY2hlY2tzdW0AAAAAU2Vz -c2lvblR5cGUAT0ZNYXJrZXIAAAAASUZNYXJrZXIAAAAARGF0YURpZ2VzdAAASGVhZGVyRGlnZXN0 -AAAAAEVycm9yUmVjb3ZlcnlMZXZlbAAASW1tZWRpYXRlRGF0YQAAAERhdGFQRFVJbk9yZGVyAABE -YXRhU2VxdWVuY2VJbk9yZGVyAEluaXRpYWxSMlQAAE1heENvbm5lY3Rpb25zAABNYXhSZWN2RGF0 -YVNlZ21lbnRMZW5ndGgAAAAASW5pdGlhdG9yTmFtZQAAAEluaXRpYXRvckFsaWFzAABEZWZhdWx0 -VGltZTJXYWl0AAAAAERlZmF1bHRUaW1lMlJldGFpbgAATWF4QnVyc3RMZW5ndGgAAEZpcnN0QnVy -c3RMZW5ndGgAAAAATWF4T3V0c3RhbmRpbmdSMlQAAABUYXJnZXROYW1lAABUYXJnZXRBbGlhcwBU -YXJnZXRBZGRyZXNzAAAAVGFyZ2V0UG9ydGFsR3JvdXBUYWcAAAAAQXV0aE1ldGhvZAAAU2VuZFRh -cmdldHM9QWxsAENIQVBfQQAAQ0hBUF9JAABDSEFQX0MAAENIQVBfTgAAQ0hBUF9SAABEaXNjb3Zl -cnkAAABOb3JtYWwAAE5vbmUAAAAAQ1JDMzJDAABDUkMzMkMsTm9uZQBOb25lLENSQzMyQwBDSEFQ -AAAAAENIQVAsTm9uZQAAAE5vbmUsQ0hBUAAAAE5vdFVuZGVyc3Rvb2QAAABJcnJlbGV2YW50AABS -ZWplY3QAAE5vAAA1AAAAQ0hOZXQgMS4wMAAAAAAADAAAAAABAAF8AAwBAAAAABAAAAAUIAeneAAA -AwUOQAAAAAAAEAAAACggB6qAAAADGA5QAAAf/AAAH/wAAB//sXAf/7FwIAey4CAHuNAgCVLwIAlS -8CAKAAAgCoAAIAqAACAK5oAAAAAAH/+rQCALAAAgCwAwH/+QMB//roQAD///H/ziAB//qfQf/63Q -GgAAAIEAAAAEAAAIIAsAgCALYJAf/6u4H/+uaB//qjAf/6skH/+t4DAAABAgC2DQIAthMB//r+Qf -/5HcIAe4kBeQAAAgB7aUIAMLUBSwAAAgAwtgAABgAIAAAAQgB7iaAAAgOgAAg/8VoAAAIAMAABag -AAAIUAEAIKAAAD/wAAAjoAAAA/8AHwDAAAQf/6/oAAD//yAHe4AqAAAAIANFqCALYWAgC2GgIAd7 -RN6tvv8awAAAIAe3mCADC1wAAP/qIAe4oAAACBQAAIgAAACAAB//qxAgB7MwH/+rmAAAJxAAHoSA -AABAACADX3gf/6yUABAAAB//qVgf/6yoIAMAECALYmAgC2IwAQAAACgAAADhAAAAOAAAAP8///8w -AAB0H/+AsCADAEAgCwDQMAAACDAAAAw0AAAI0AAAAA4AAAAAAIkUOwAACCAHtqggAwvENJAAACAH -tTAFXUqAIANlPAAYAAD/B///ADgAAAAwAAAgC2KA4QAuAAAAYajhAY4AAABADwABkQyAAAAAIAtj -MCALY2AABAAAAAgAAAADAAAAAAgAIAtjsP//8/8gC2PgAACoLAAAqC8AAKgrAACoKgAAqOwAAIEA -AACoNQAAqDcgCwOw4QBeACALA/AAAEAOAABAGiALBCAAABAAAAD/6QAA/+AAAFAAAAD/+AAAqDv/ -/8kkAABADf//8AAAAP/3AAAP/wAAD0IAAP/1ABMAByALBIAAAIAHAACABCALZAAgC2QgAAC47gAA -NAAAALTuAAC0/wAAtAAAALgAAHMAAx//q1ggAwyIAACD/SADCuggA6LYAAFBSgABAW4gAwtIAMAA -ARAAAAAgC2RAIAMMmCjAAABAAAACIAMLlCigAACAAAACawAAACADCxAgA5zIIAtkYCADpFggC2Sw -A2AAAO4AAAAgAwzYA+AAAB//qtAgAwCQ4QMGAP/f///f////AAEACgLmAukgAAAA4QL+ACADAKAA -AgAA//3//wD/AAAAD0JAAJiWgAAAJw8f/6s0AACvAEAAAADhAQ4AAACI9wAgAAABPwFAH/+pVCAL -ZVAf/6msIAtloABAAAAAgAAAAAEAAAgAAAAf/OLkAgAAAB//qxwgCwYgIAsGcCAD59AgCwbwIAsG -wCALZXAgBDrAH/+rbCALZeAf/5dEAFAMAAlAAACD/9AAA//QACAD5FggA7C4IACJ7CALCdAgADNg -IAO3+AAQAjAAQQAAAFEEACALCgAf/6v0H/+nTB//q7AJAAAAAABD/yADvDgAAIbdAEAP/SADvRAf -/6moH/+poB//q0j/8///AAwAAB//q0QAAA/+AP///yAAZLRxAAAAH/+paCAHsQAgAwlAAA/8AB// -ljwf/5ekAAA+AAAAIABVAAAAH/+plCALZnAgA8Hc//f//wBMS0AgBDkMIAQctCALCnAgCwqgIAsK -8CALCsAf/4JwH/+DYCALCxAgAw/gIAMPYCADD0AgAIa8IAsLoCAEU4wgCwvAIARSzCALZvAgCwvg -IAsMQCALDJAgBDHcIAsMECAENuz//wf/AAAwACALDQAgCw1gH/+rgCALDZAgCw3Q4AAAACADnfgg -Cw4QIAsOMCADEFgAAAgGIAPkoCAD52Af/6swAADwACAEEZAgBBZEIAsOUCAEBFQgCw6AH/+SLADA -AAAf/6lgIAe24O//////f///IAsOwCAHtqogBApQIAtosBSQAABAAAAEIAtpICALaVAgC2cgIAe2 -oCALZ2AgC2fAAACP/iALaBAjKBUAA/8AACALaHAgBBi0/f///yADEFAgB7OQIAezwB//qxgf/4LQ -H/+D0CADE1Af/4KwP////8////8f/4OMf///q///LlwAANGk///QTQAAnE4f/4LMIAMRLAAAaAAM -AAAAH/+CyCADE1Af/4MwIAsPEB//q3AgBE6wH/+rICALZSAgC2TgIARF0P//QAAgCw+AIAsPUCAL -D8AEAQAIIAejqCACX2QgAmVoIACw9CAAW9wDgAAAIARTGCAESwwAABdwIAMMlCALaqAgC2pQIAtq -MCAEYuwgC2oAIAtqgCADDAQf/6sMIAMMdCALFSAgCxVwH/+pgCALFZAgCxXAIAsV4B//qHwgB68g -IAsWEB//pzThAH4ABAAAAAUAAACAAAAdgAAACoAAAAyAAAAbgAAAHyADDeAf/6mQH/+rKAAA8/8U -AAAAIARujB//q/AgACDoH/+SGACcAADgAAkkH/+rLCALFsAgCxegIAsXcCALa6AgCxdAH/+aVCAL -FwAAAwTA4QMCAOD//gDhAI4AAACWgAAAlkAgB7LgAACWoAAAlmDhAwAsH/zeAOEAegAf/6sUAAHg -AOEBkgAAAeMABgAAACAEgbD4AAAAAf//5wABwAAgAACABAAQAB//p0ThAZoA4QGaQOEBmjzhAZo4 -4QGaNOEBmjAf/6wQIAMMDCADDBwgAwwUIAMMJIAAAAP//P//f////x//klwgBI9kIAtusCALbvAg -C28gIAtvYCALb5AgC2/QIAtwACALcED//wAAD///8P/wAAAgC3CgH/+XWB//rtAf/6aEIAScMCAL -caAgC3HQIAtxQCALcOAf/5ckH/+YYB//mrAAAP+AIAsYgCALGLD/+///4QHiwJAAAPD8/4DAAgAA -IP7/gMAgCxkAIAsZQAAA+AAAAwEIAAMBDI////8gCxmQIAsZ4CALGhAgCxpQH/+XgOEA5gAf/6mE -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 -IAuO0P/v///hAFbgf+///yALWUBAAAAAH/+piOEBkgAgC46gAAAxRAAANYQf/5F0AAAxhAAALUQg -C1mAHQAAAB//gLAf/6vsIAd7gCAHe0QgAwlAIAexFAAwAAAgAxEkIAuPwCALkHAgC47wIAuPMCAL -kPAgC5AQIAuPcCAHsDQf/6skIAMMDCADDBQgAwwcH/+ocOAAAAAf/6uQIAtbAAAAJxAAAIAAIAd0 -QB//rJQf/5AwH/+s0B//sSgf/7FAAA9CQB//sVgf/66QH/+xLB//sUQf/7FcH/+pfOEDBgDt//// -AAJiWgAaQAAf/6fE/8AAAAATHBwAAaoA//wAAAADCQQgC1sw4QM6AH////8f/5GgAADw/wAAUA0f -/5hwH/+YeOEAXgAgB7Cc//z4fwAAE4ggB7Mw4AAKAOAADYQgC1tQP////wACAADiAAAAIAqAAB// -kPAAABzg3//+AOEAWgDf////AAEAAB//pogf/6iYIAtd8CALk5ADAAAAv//w/yADDCQf/6vwAABA -AB//q/Qf/5LYH/ziAB//qmThAA4A4QASABAAAAAf/63QAAAgAAIAAAAf/5Hc/w///wAA//8f/61E -H/+SLAAA/v8gC14gH/+p9CALXvAgC16AIAtfYB//pzAgB7MoH/+mMAQBAAgwAAAAgQAAACAHs5Ag -B7PAIAe2ICAHo6gEAAAIIAMP4CAAAAAKAAAAH/zi5CALjQDhAy4AAAMNECALTmD7///OBAAAAQBA -AAAAgAAA/j4ADwAAIAz//98w4QMOAAAAP+AAGAADAAC5k+EDEgD//+//8//n/wAAEgAAEAAAABAA -QB//qywAEAAgABAAEAAQAAgAEAAEABAAAgAEk+AgAwkgIAtO4CALTrAgC08Q/+//6SALT0AgC0/A -IAtQMCALULAAAYag//tsIAAehID/4XuAABMABgATABDhAzIAIAuIcCALiKDhAv4AIAMS0CALiCAg -C4jQAAMINCALieAgC4lQIAuJAAADKhwAAyo8AAMqXAADKnwgC4oAIAuJkB//q4gBgAAAIAuLkAAD -CAAf/6X4AAMiPAADIhgAAyIcIAMS4CALiyAgC4twIAuKYP7////hAyIA//9D////P//hAx4A//+/ -/wADIgAgC4qQIAuLsCALi9AAB6EgAIlUQACYloAgC4rAAAMiBCALivD//9//IAuL8AAA/+8gC1Eg -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 -IAk3SiAJN5AgCTeGIAk3SiAJN0ogCTdKIAk3SiAJN0ogCTeQIAk3SiAJN0ogCTdKIAk3SiAJN0og -CTeQIAk3kCAJN5AgCTeQIAk3kCAJN5AgCTeQIAk3kCAJN0ogCTdKIAk3SiAJN0ogCTdKIAk3SiAJ -N0ogCTdKIAk3SiAJN0ogCTdKIAk3SiAJN0ogCTdKIAk3SiAJN0ogCUXtIAlF7SAJRdcgCUXJIAlF -8CAJRcMgCUXDIAlFwyAJRfAgCUXDIAlFvSAJRfAgCUXDIAlFwyAJRcMgCUW9IAlF8CAJRfAgCUXw -IAlF8CAJRfAgCUXwIAlF8CAJRfAgCUXwIAlF8CAJRfAgCUXwIAlF8CAJRfAgCUXwIAlF8AAGIXoA -AAAFAAAABAAAAAEAAABSAAAAEwAAABsAAAAWAAAAEAAAAAAAAAAAAAAAUgAAAFsACBsyAAAABgAA -AAwAAAACAAAAZwAAAAAAAAAdAAAAFAAAABAAAAAAAAAAAAAAAFcAAABjAAmJaAAAAAcAAAACAAAA -AgAAAP0AAAADAAAAHgAAABoAAAAQAAAAAwAAAAAAAABbAAAAaAAKIf8AAAAHAAAAAgAAAAIAAABn -AAAAHAAAAB4AAAAeAAAAUAAAAAAAAAACAAAAXAAAAGwACrqVAAAACAAAAAoAAAADAAAA9QAAAAEA -AAAeAAAAGgAAABAAAAABAAAAAAAAAF0AAABtAAsgTwAAAAgAAAAKAAAAAwAAAGoAAAACAAAAHgAA -ABoAAAAQAAAAAgAAAAAAAABeAAAAbgALp/EAAAAIAAAACgAAAAMAAAApAAAAAgAAAB8AAAAcAAAA -EAAAAAIAAAACAAAAXwAAAHEADDUAAAAACAAAAAoAAAADAAAAUgAAABMAAAAbAAAAGwAAAFAAAAAA -AAAAAAAAAGEAAABzAAxC8wAAAAgAAAAKAAAAAwAAAPUAAAABAAAAGwAAABsAAAAQAAAAAQAAAAIA -AABhAAAAcwAMtzYAAAAJAAAABgAAAAMAAAD9AAAAAwAAABwAAAAcAAAAEAAAAAMAAAAAAAAAZAAA -AHAADRzvAAAACQAAAAYAAAADAAAAKQAAAAEAAAAcAAAAHAAAAFAAAAABAAAAAgAAAGQAAABxAA49 -1QAAAAkAAAAGAAAAAwAAACoAAAAfAAAAHwAAAB8AAAAQAAAAAAAAAAIAAABmAAAAcgAO1b4AAAAK -AAAACQAAAAQAAABqAAAAAgAAABwAAAAcAAAAEAAAAAIAAAAAAAAAZgAAAHcAD0JAAAAACgAAAAkA -AAAEAAAA/QAAAAIAAAAdAAAAHQAAAFAAAAACAAAAAgAAAGYAAAB3AA+8UgAAAAoAAAAJAAAABAAA -ACkAAAABAAAAHQAAAB0AAABQAAAAAQAAAAIAAABrAAAAeAAQRgQAAAAKAAAACQAAAAQAAABnAAAA -GQAAAB4AAAAeAAAAUAAAAAIAAAACAAAAawAAAHkHADsAAgA4AAQDOwEAAAAAATYBbAGWAPABIAFT -AOEBMQFhALwA5AELAPUBIgFJAMYA6wEPAMIA6gETAJ0AvwDeAMsA7QENAKoAyQDkAKMAxADgAIEA -ogC9AK8AzADjAJQAsADGAIsAqAC/AAAAgQCdAJoAswDHAIEAmwCvAG4AjwClAAAAAAAAAIkAnwCx -AG0AiACbAAAAYQByAAAAAAAAAHoAjwCfAAAAcgCHAAAAAAAAAAAAAAAAAAAAAAAAAAAA+wEmAWoA -2QD/ATYA7gEuAYwAqwDTARMA1gD5ASoAuQDaAQoAtwDiATAAjACtAOEAugDZAQYAogC+AOcAlgC3 -AOoAZQCMALoApAC/AOYAjgCoAM0AegCYAMMAAAAAAJQAkQCqAM0AewCVALcAAAB6AKMAAAAAAAAA -gACYALgAZACBAKMAAAAAAH0AAAAAAAAAbQCGAKUAAABmAI4AAAAAAAAAAAAAAAAAAAAAAAAAAAEA -ASkBVQDOAPMBFQDHAO4BFgChAMMA4ADNAO0BDACrAMoA4wCiAMEA3QB9AJ4AtwCtAMkA3wCTAK0A -wQCGAKIAuQAAAAAAiwCXAK4AwAB9AJYAqQBMAIEAmQAAAAAAAACFAJoAqwBiAH8AkwAAAAAAAAAA -AAAAAAB2AIkAmQAAAFYAeQAAAAAAAAAAAAAAAABmAHoAiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAN8BAwExAL8A3wEQALwA5AEsAI8ArwDiAL0A3AEHAKQAvwDnAJYAtgDmAFcAhgC0AKQAvwDk -AI4ApgDKAHYAkwC8AAAAAAAAAI8ApwDIAHgAkQCyAAAAbQCZAAAAAAAAAHwAlACyAFoAegCYAAAA -AAAAAAAAAAAAAGcAgACeAAAAAACBAAAAAAAAAAAAAAAAAAAAagCKAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAA2wEAARsAtwDXAPAAsADPAOgAkACuAMYAswDOAOQAmQCyAMYAjQCnALwAAAAAAI0A -mQCvAMAAgACXAKkAAAB8AJQAAAAAAAAAhQCZAKgAWgB7AI8AAAAAAAAAAAAAAAAAdACHAJUAAAAA -AAAAAAAAAAAAAAAAAAAAYQB1AIMAAAAAAAAAAAAAAAAAAAAAAAAAAABgAHEAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAADMAOsBGACyAM8A9gCpAMwBAACCAKEAygCtAMgA7QCYALEA1QCDAKAAxwAA -AAAAlgCVAK0AzgCAAJgAuQAAAHUAnQAAAAAAAAB/AJYAtABVAH0AnwAAAAAAAAAAAAAAAABmAIAA -nQAAAAAAfQAAAAAAAAAAAAAAAAAAAGIAhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAD/8P/w/8AP8P+AnbD/APpQ/gCZkPwACZD4AAAA8AAAAP/A/8D/gF -/A/wD7QP4AW0D8AAtA+AAAAPAAAADAAAAA/AAAAOwAAAD4AAAA6AAAAPAAAADgAAAAwAAAABAAAA -AAE4gAAAaCoAAE4gAAGGoAABhqAAAgjVAAII1QAAACgAAAAyAAEEagAAaCoAAEpnAAGGoAABhqAA -AgjVAAII1QAAACgAAAAyAAFbAQAAaCoAAFAgAAII1QABhqAAAgjVAAK2cQAAACYAAAAyAAEpbgAA -aCoAAE0pAAII1QABhqAAAgjVAAK2cQAAACYAAAAyAAEEQQAAaCoAAEpnAAII1QABhqAAAgjVAAK2 -cQAAACYAAAAyAAF0BgAAbIEAAFQBAAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAFFhQAAbIEAAFFh -AAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAEhWgAAbIEAAE7qAAKLCgACCNUAAosKAAK2cQAAAB4A -AAAtAAEEagAAbIEAAEyXAAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAGGoAAAb5sAAFbOAAKLCgAC -CNUAAosKAAMNQAAAAB4AAAAoAAFbOAAAb5sAAFR1AAKLCgACCNUAAosKAAMNQAAAAB4AAAAoAAE4 -gAAAb5sAAFI8AAKLCgACCNUAAosKAAMNQAAAAB4AAAAoAAEcGAAAb5wAAFAhAAKLCgACCNYAAosK -AAMNQAAAAB4AAAAoAAFsdAAAcuMAAFdjAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAFLUgAAcuMA -AFVYAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAEvtgAAcuMAAFNlAAMNQAACiwoAAosKAAMNQAAA -ABsAAAAjAAEYWQAAcuMAAFGIAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAF6ugAAdl8AAFo+AAMN -QAACiwoAAosKAAMNQAAAABkAAAAjAAFbKwAAdl8AAFhWAAMNQAACiwoAAosKAAMNQAAAABkAAAAj -AAFBXgAAdl8AAFaBAAMNQAACiwoAAosKAAMNQAAAABkAAAAjAAEpkwAAdmAAAFTBAAMNQQACiwsA -AosLAAMNQQAAABkAAAAjAAERKgAAb5sAAE/dAAII1QACCNUAAosKAAMNQAAAAB4AAAAoAAEXBAAA -bIEAAE4gAAKLCgACiwoAAosKAAMNQAAAABsAAAAjAAAAACtoI4MYag0GCyoAAAAAAAAAAAAyAAAD -6AAAACgAAE4gAAAAAAAD0JAAmJaAAA9CQACYloAAABwgAAAASwA9CQAAA9CQAJiWgAEBAAADAwIC -BQUEBAcHBgYAAAAyAAAD6AAAAGQAAMNQAAAAAAAD0JAD0JAAAExLQAPQkAAAABwgAAAASwA9CQAA -D0JAI8NGAAMCAQAHBgUECwoJCA8ODQwAAAAyAAAD6AAAAAoAAAH0AAAAAAAAA+gAmJaAAA9CQACY -loAAABwgAAAASwA9CQAAA9CQAJiWgAMCAQAHBgUECQkICAsLCgoAAAAAAAAAAAABABAAEQAeAA0A -EgAHAB8ADgALABMAFQAbAAgAFwAgAA8AHQAMAAYACgAUABoAFgAcAAUACQAZAAQAGAADAAIAAQB7 -AHUA+wD1AEUAbwB9AHcAXwBpAMUA7wCjAD8A/QD3ALsAOQDfAOkAzwCdAEcAcQAPAFkAJQC/ABMA -YwB/AHkAbQBdAD0AuQCbAA0AYQBrAAsACQBRAB8AMQBTAMcA8QAhALUAjwDZAK0AMwClAEEAVQCX -AJMA4wApAMkA/wD5APMAwwDtAN0A5wAjAL0AOwC3AE8AHQCNANcAkQDhAOsA2wAbAIsAiQCHAK8A -0QCfADUALQCxANMAFwCnAEkAcwBDAGcAoQA3AM0AVwARAFsAmQAHAC8AswCrAJUAJwDBAOUATQDV -ABkAhQArABUAZQDLAAUAqQBLAIMAAwCBAAAA+gD0AHwAdgDEAO4A/AD2AN4A6ABGAHAAJAC+AH4A -eAA8ALgAYABqAFAAHgDGAPAAjgDYAKQAQACSAOIA/gD4AOwA3AC8ADoAHACMAOAA6gCKAIgA0ACe -ALAA0gBIAHIAoAA2ABAAWgAuALIAJgDAANQAGAAUAGQAqABKAIAAegB0AEQAbgBeAGgAogA+ALoA -OADOAJwADgBYABIAYgBsAFwAmgAMAAoACAAwAFIAIAC0AKwAMgBUAJYAKADIAPIAwgDmACIAtgBO -ANYAkADaABoAhgCuADQALAAWAKYAQgBmAMwAVgCYAAYAqgCUAOQATACEACoAygAEAIIAAgABAAMA -AgAEAAAAAAAAAAAAAQACABwAGwAWABUAHgAdABgAFwAMAAsAEAAPACAAHwAaABkAFAATAAoACQAO -AA0AEgARAAgABwAGAAUABAADAAEAAAACAAQAAAAAAAAAAAAAMAQAADAQAABZ3AAAWoAAAFqEAABa -iAAAWowAAFqQAAGUMAAAECQAABAwAAAQPAAAENwAABEMAAB7LAAAezQAAeKMAAHmjAAB6owAAe6M -AAHyjAAB9owAAfqMAAH+jAAAjcwAAI6AAAB+dAAAj9wAAZFYAAGScAAAj/wABBMcAAQTGAAEExAA -BJMcAASTGAAEkxAAAHfgAAB35AAAd/QAAHgEAAGcPAABEHQAARCEAACUCAAAmFwAAJYMAACWFAAA -liAAAJYsAACWxAAA0CgAAJAIAAMI3AADSNwAA4jcAAPI3AADCOQAA0jkAAOI5AADyOQAAZBUAABg -HAABoNgAAZCQAAB34AAAd+QAAHf0AAB4BAAAeNgAAHjgAAB49AAFAHgABQh4AAUTCAABlAQAAePA -AAHnwAAB68AAAe/AAAHzwAAB98AAAfvAAAH/wAABlAwAAAAAAAAAAAAAAAAAADAAv///QAAAMAi/ -//9AAAGUEJ////8AAZQ0AAAAEAABlAif/+P/AAGUOAAAABAAABAo4f///wAAECzh////AAAQNAH/ -//8AABA4Af///wAAEEAABAAAAAAREAD///8AABEUAP///wAAeygAff/iAAB7MD//7v8AAHs4AAAA -AQAAe0A//+7/AAB8JAB9/+IAAeKIAAgAAAAB5ogACAAAAAHqiAAIAAAAAe6IAAgAAAAB8ogACAAA -AAH2iAAIAAAAAfqIAAgAAAAB/ogACAAAAACNyP////AAAI3Q////8AAAjnwAAADwAACOhAAAAPAA -AH5wf7//fwAAfnh/v/9/AAB+AALAAAAAAZFUAf///wABkZwB////AACP2AN///8AAI/4/////wAE -ExQAAAAHAAQTDAAAAAsABJMUAAAABwAEkwwAAAALAAB33AAAAAMAAHf0/////wAAeAQAAAADAAGc -OAABwEAAAZz4AAHAQAAAkAQAAAA+AAEQeAD///8AARB8AP///wABEIgAAAAAAACUBAAA//8AAJQQ -AAD//wAAmFQAAAH/AACYWAAAAf8AAJYIAAAAAAAAlhwA////AACWJAD///8AAJYoAP///wAAljAA -////AADQIAAAAAcAANAkAAAABwADCNgAAAADAANI2AAAAAMAA4jYAAAAAwADyNgAAAADAAMI5AAA -AAMAA0jkAAAAAwADiOQAAAADAAPI5AAAAAMAAZBQAAAA7wABoNQAAAGDAAGQjAA4AAAAAZCYADgA -AAAFAHQAAAAHAAUAcAAAAAUABQh0AAAABwAFCHAAAAAFAAUTBAAAAAEgAxRQIAjl5CADFFQgCPbo -IAMUYCAI9fggAxRsIAj1RCADFHggCPT0IAMUjCAI9BAgAxSYIAjzZCADFLAgCPH4IAMUwCAI8OAg -AxTIIAjwuCADFNwgCPCQIAMU7CAI8GAgAxT4IAjvRCADFQAgCO8cIAMVFCAI7uggAxUgIAjthCAD -FSggCOzcIAMVOCAI69ggAxVEIAjqyCADFVQgCOnAIAMVZCAI6JQgAxV8IAjlZCADFZQgCOUYIAMV -qCAI5NggAxW4IAjksCADFcQgCOQcIAMV2CAI4/QgAxXsIAji9CADFfQgCOLMIAMWACAI4dwgAxYM -IAjg3AAAAAAAAAAAIAMWECAI4JwgAxYUIAjgICADFhwgCN/oIAMWJCAI37AgAxYwIAjfeCADFjQg -CN9AIAMWPCAI3wggAxZIIAje0CADFkwgCOBYIAMWVCAI3pggAxZgIAjeYCADFmggCN4oIAMWcCAI -3fAgAxZ4IAjbECADFoAgCN2gIAMWjCAI3ZggAxaUIAjdYCADFpwgCN0oIAMWpCAI3PAgAxasIAjc -uCADFCggCNiwIAMWtCAI2HggAxa8IAjYQCADFsQgCNgIIAMW1CAI19AgAxbcIAjXmCADFuQgCNdg -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 -ABoAAAD6xogAIAAA8AAAAB//qXwf/6dw4QMCAOEDBgAgB6/IIAewcAAA/98AAP/3IAtGUCAIAhB/ -//////P///5///8gC0agIAtGcCALRtAf/5pUH/+YLAAA+AAAPDw8H/+u0B//ktgf/5agH/+rJAoU -KFAgCBOkIAewwB//kOggAxIoH/+SXP//x/8AAv/AH/+X0CALhLAgC4RQIAuG4CALR3AgC4aAIAuG -UCALRwAgC4awIAuD4B//mGwf/5hkH/+mmB//ppQgC0nwH/+n0CAIApAAACcQIAtKYB//plgf/5jA -H/+YvB//mLQf/5iwIAgCsB//p8ggAwmwIAMMRCAIAtAf/6uoIAtK0B//p1wf/6dgH/+nZB//p+wf -/6fkH/+nmB//p5Qf/6eQH/+njB//p4gf/6eAH/+ndCAIAwAf/6bkAABAAx//kXQf/5joH/+mhIf/ -//8f/5lIH/+tRB//mZgAD//wIAtLECAIA7AgC0twIAgDwB//q8QgC0uwH/+ZXCALTAAf/5kwIAtM -MCALTGAgCAPQH/+YpAAAJYAgC0yQIAtM0B//mEgf/5Y0IAgD8B//mEQf/5bcIAgD+P//AAAD5/wY -IAtNACAIBAAf/6iIIAMKKB//qITz////IAMKMCADCjwgAwpIIAMKGA////8gCARQH/+YoCADElAg -C01gIAgY1P//6tAgCBh0///rMCAIFxQgCBhs///skCAIFhQgCBcM///tkB//mMwD///gAARyDAAE -chQABHIcAARwFAAEcCgABHAgAARwLAAAhYA////gAARAJAAEQEwABEokAAQA4AAEAAQgC1GwIAtR -4B//mIgABALEAAQCwCALjbAgC43gAARwZCALjhAABEHAAARBxAAEQcgABEB4AARA3AAEQUAABEFE -IAtSsCALUvAgC1MgIAtSECALUlAgC1KAAARwWAAAECgABEFgIAtTcAAAd3cAADMzIAtUsCALU7Ag -C1QwIAtUcCALU/AgC1NAAAAgKAAEdBgABErAAARAwAAEQMQABEHwAARB9AAEdBQgC41wIAtV0CAL -VZAgC1VQIAtVECALVNAABAJwAAAI8AAEAnQABAJ8AAQCkAAAvygABHBcAAR0AAAA8AYABEvwAARy -KAABmy8AAWMdAAQBMAAEAOwABAEIAAR2AAAEAQQABHYEAAD/+AAEAQAABADkAAR2CAAA/8EABHIA -AABVVQAEcgQABAD4AAQA3AAEANgABHJIAAQBOAAEARgABHJMAAQA9AAEclAABHQIAARyCAAEQEgA -BErcIAtWECALVlAgC1aQAARBLAAEQTwABEDgIAtW0AAEQQAgC1cAAARwSAAEcGAABHIgAAR2DAAE -eASAEAAAIAuOUCADExCAEgADAAQA6IAQAAMABADAAABOIAAEAMwABADEAAQAyAAEATQgCAt0IAgP -tAACACEABACAAA//KQAEAEQgC1cwAAQCRAAEAkwABAJIBgYAAAAEAYAAAB54AAEwsAAEANAABADU -AAQA8AAEAPwAAgjVAAEEagAEAQwABAEQAACiwgAEARQABAEcAAQBJAAEASgABAEsAAQBQAAEAUQA -BAJQAAQBIAAEAmAABAJkAAQCVAABACF3NZQAAARB/AAES/wAAIAgAAAICAAEcDAgCAhgAARgwAAE -YMQAAIgAAARB1AAES9QABEHYAARL2AAEQdwABEvcAARwOAAEcAAgC1dgAARwBCALV6AABGDIAACA -JAAEQBwABEocAAAXLCALV+AgC1gQO5rKAAAEYOQABGDQIAtYQAAEQAAABEAEAARADAAEQAggAwv0 -AARKBAAEcDQABHAIAARQAAAEVAAABGDMAAB/AAAEQdAABEvQAARwUAAEUGgABFBAAARUaCAIDJAA -BFBQAARUUAAEUiQAAEBAAARSKAAEUiwABEAQAARIEAAEQBQABEgUIAgMsAAEQeAABEvgIAgM1AAE -QegABEvoAARB5AAES+QABEHsAARL7AAEQBgABEoYAADu8AAEUGAABFRgAAARAAAAETAAABAwIAgI -iCAIB9wgCAnoIAgJPCAIC0ggCAqcAAQTBAAEEyQA////AIECIB//kaAAAPD/AABQDQCAAADhAeJA -4QASAP/ADAAf/6koH/+Q5CALW+AgC1uQAf///wPf0kACFg7A4QNGACALXDAf/5dYAARUsAAA4+8A -BFCwAARg4AAAwfMf/6nwIAgEYP48f/8gC1xQgAAFAAAAfuiAAAcAIAuRkIAABACAAAYAIAuRcIAA -AQCAAAIA/58AAEAIAAD4wAAAAABgLP9///8gC1xwIAlRcCALXLAf/5EAIAlS8CADCUAgC1zgH/+r -OAAP//8gB7C4H/+qoB//qXAf/6xQH/+scB//kXMf/6mYAFOAACAMgAAADIAAH/+pMCALXRAgCAUg -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 -Amtw+TYmLABAP3D9NiUiAAA6cC8w9/QyFy4AIC/wL/CABPkorX75FhIgBnUqYPk2KC4AICOw9AgG -Af4Cc7D/FiMuAEBDsP42JyIAAGpwKjD2BNksKDIY/xIjJAAgLrAlUIAIeCz5NhkkACBKMPg2GiQA -ICkw/pwABAAgd3D0ChguACAn8ASKLASbLP+7CAIAAGow+6oIAH4CKXAE9Cz6RAgEAEA1cPpEEQAG -EFgw9BYAIAUQUDBbuNwrMuclNin0NiosACAtMPoyJCoAIG7w/PqAIP4CWvD9NuYqAEBm8Ps2IyoA -IFqwW3lY0Q8AAAAA/jKsIATLqeD57AAABMeroCgw9SkWNAc+FP4WOyFlALYgKDGB+woAIAAQeDD8 -iBAAABBQMPACBGoDAEKwp6n3DAYB/gJKcAnJAXWbbSsyQn+/Zx/X8y0w9wpeDP/YLh4DAHuwr90t -0IAOXgz/MiguACBx8PfdKAH+AnOw+hYRLgBAczD+NicqBZnr0K5+sO79NiguAEBzMC42Jy9ACcCk -+woGICAQQDD82JIeCQBH8P9ECSIAAGlwW7ig0Q8AAAAA9ewAB/cAN6AF+zcLOxT7Fi8iAABS8Fpr -zCsw/Sww/C4w+C8w+f0w+yIAABKw+TD/IAUQUDD5FgMoACBz8PsWAigAIGow/RYAKAAgYjD8FgEo -ACBaMPzYExgAIEow+BYqIAAQaDD4FgQgBhBYMFu4gikw9SUw9AJ7DP28AAAFTapgKhIq+RYnIgAA -cvD8CgAsACBNcPwWKSwAIG6w/RYoJngAtqD/nAAAARBIMPkWMiAAEEAw+BYrL/8QSDApFixgBo0r -MP0uMPgvMPktMPssMPz6MP8oACB38P0WACgAIG5w+hYDIAAQaDD7FgIoACBmcPwWASgAIF5w/Nfq -GAAgVnD5FjAgBhBYMPkWBCAFEFAwW7hZKhIwzKouEjvwADZgABB4MADAsfsWMiAIEFgwW7s8LhIw -LTD1/t0IAAAQYDBbua8oEjL4CAYOAQBG8P4SOy4AQEfwLUAJ/DGBIAgQWDAPuwz76igAQBBAMPzM -EAwJAEdw/UQJKgMAYrAc2CoqFj3/6CgCAABq8PpOWwAGEFgw+BY8KXQBQDD4FgAgBRBQMFu4NSkS -PdMP0w//EjwmYAA2YBrXbCk2KNMP+jYnKAAgVnAuEjT916AQCgA34Ck2Ky82LCvSfSrSfguqDCoW -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 -LrYw/bbmIAAQYDD8tmAgARBIMCm2Mvm2LSAYEFAw+rYZIAgQGDAjhIAYsv8Ssxkfs8YjgMEiIoH2 -s8QUABAgMPk8AgQAARww9U85ABgAvLASs/kvJX7RDxez9/wLQAQAEFAw/ITBJgUAWrAmdX7RD2wQ -BBy2Ghq2Ghi2FyrGf/qtQCCIEFgw+oZ/IAAQYDBbjRUesuUdthMt5jMt3QIt5jTRDwAAAAAAbBAE -GrOB+7Q7EKIAPKBoImj0kH5gAgIScP8iE2ABECAwYAA0aWQFBagIJ4YAckso+jwAAgAAWTBbkyn4 -YRJgAgIhMPli3WgAIC6wJ5UAY//bpasntABj/9PRDyyitSmyhqPMCcwR+GFvaAAgZnBoYm5pZOSl -nZfQ0Q8Zs5ipOSmQ3WhANvSQX2ACAhEwckOfY//FLKK1KbKGo8z5zBEAAgIhMPhhG2gAIGZwaGIb -aGQg/wIAC/+9lRBj/5xln1Fj/5almCeEAGP/5qWaJ6UAY//epZuXsGP/16WcJ8QA0Q+lnSfVANEP -ANEPAAAAAAAAIAMToAzAAAYgB4KMIAMTpAjAAAwgB4KMIAMTqDzAABAgB4HcIAMTrAbAADggB4Pw -IAMTsAjAADwgB4KMIAMTtALAAEAgB4RYIAMTuAjAAEQgB4KMIAMTvAhAAEwgB4McIAMTwAhAAFAg -B4McIAMTxAhAAFQgB4McIAMTyAhAAFggB4McIAMTzCBAAFwgB4McIAMT0CBAAHAgB4McIAMT1CBA -AIQgB4McIAMT2CBAAJggB4McIAMT3CBAAKwgB4McIAMT4CBAAMAgB4McIAMT5CBAANQgB4McIAMT -6CBAAOggB4McIAMT7AxAAPwgB4DsIAMT8AxAAQwgB4DsIAMT9AxAARwgB4DsIAMT+AxAASwgB4Ds -IAMT/AxAATwgB4DsIAMUAAxAAUwgB4DsIAMUBAxAAVwgB4DsIAMUCAxAAWwgB4DsIAMUDAhAAXwg -B4McIAMUEAhAAYAgB4McIAMUFAhAAYQgB4McIAMUGBBAAYggB4McIAMUHBBAAZAgB4McRkNvRSBE -RFAgZmFpbGVkIDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBERFAgZmFpbGVk -IDogRGRwUmVwb3J0IDB4JXggRGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBmYWlsZWQ6IGF2 -YWlsICVkCgBGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQg -JXggZmxvd2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAFBSTEkgUnNwIHRpbWVkb3V0IDogZmxvd2Nf -aWQgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXggCgAAAAAAAABod19iY204NDg1Nl9jaGVjayBl -bnRyeQoAAAAAAAAAAGh3X2JjbTg0ODU2X2NoZWNrIGxvb3AgJXUgKGNoZWNrICUjeCkKAAAAAAAA -AAAAAFsldSBQb3J0IGNhcmRdaHdfYmNtODQ4NTZfY2hlY2sgdXBfcnVubmluZyAocG9ydD0ldSA6 -bG9vcF9jbnQ9JXUgKQoAAAAAAAAAAAAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgZmFpbGVkIChiYWQg -Q1JDKQoAAAAAAAAAAAAAAAAAUEhZIGZpcm13YXJlIGxvYWQgc3VjY2Vzc2Z1bCAocG9ydCV1KSB3 -b3cuLi4hISEhIAoAAAAAAAAAAAAAAAAAAGJjbTg0ODU2X2xvYWRzZXF1ZW5jZTogU3RhcnRlZAoA -QnJvYWRjYXN0IG1vZGUgdHVybmVkIE9OIAoAAAAAAABiY204NDg1Nl9sb2Fkc2VxdWVuY2U6IFVw -bG9hZCBpbWFnZSB0byBQSFkgb24tY2hpcCBtZW1vcnkKAAAAAAAAYmNtODQ4NTZfbG9hZHNlcXVl -bmNlOiBkb25lIGxvYWRpbmcgaW1hZ2UgKDB4JXgpCgAAAAAAAAAAAAAAAAAAAFdhaXRfU1BJX0xP -T1A6IHBpZCA9ICV1IAoAAAAAAAAAYmNtODQ4NTZfbG9hZHNlcXVlbmNlOkRPV05MT0FEIEZBSUxF -RCAobG8gPSAlI3gsIGhpPSUjeCwgY250PSV1KQoAAAAAAAAAAAAAAAAAAABbJXUgUG9ydCBjYXJk -XSBiY204NDg1Nl9sb2Fkc2VxdWVuY2UgOkRvd25sb2FkIGNvbXBsZXRlZCBhZnRlciAldSBsb29w -cyBmb3IgcG9ydCAldQoAAAAAAAAAAAAAAABod19jbDQ1X2luaXRbJXVdIGFjYXBzICUjeAoAAAAA -AGJjbTg0ODU2X2luaXRbJXVdCgAAAAAAAAAAAAAAAAAAaHdfYmNtODQ4NTZfbG93cG93ZXJbJXVd -OiBlbmFibGU9JWQKAAAAAAAAAAAAAAAAaHdfYmNtODQ4NTZfbG93cG93ZXJbJXVdLCBmYWlsZWQg -dG8gc2V0IDMwLjB4NDAwQSBiaXQgNzsgMzAuMHg0MDBFIGJpdD0xIGFmdGVyIDVtcywgcmVnPSV4 -CgAAAAAAaHdfYmNtNTQ4Ml9jZmdtZGlbJXVdIHNldHRpbmcgdHlwZSAldQoAAAAAAAAAAAAAZGhj -cDZfdGltZXJfY2I6IHJlc2VuZGluZyBESENQNlNPTElDSVQgYWdhaW4KAAAAZGhjcDZfdGltZXJf -Y2I6IHNlbmRpbmcgREhDUDZSRVFVRVNUCgAAAAAAAAAAAAAAZGhjcDZfdGltZXJfY2I6IHNlbmRp -bmcgREhDUDZSRU5FVyByZXF1ZXN0CgAAAAAAZGhjcDZfdGltZXJfY2I6IHNlbmRpbmcgREhDUDZS -RUJJTkQgcmVxdWVzdAoAAAAAZGhjcDZfdGltZXJfY2I6IERIQ1A2UkVQTFkgcmN2ZCwgc3RhdGUg -JXUKAAAAAAAAZmFpbGVkIHRvIHJlbmV3L3JlYmluZCBkaGNwdjYgYWRkcmVzcwoAAAAAAAAAAAAA -dHlwZSAleCwgeGlkICV4LCB0eXBlX3hpZCAleAoAAABpcHY2IHByZWZlcnJlZCBhZGRyIFslMDR4 -ICUwNHggJTA0eCAlMDR4XQoAAAAAAABjaG5ldF9maW5kX2wydF9lbnRyeTogZGFkZHIgWyUwOHhd -LCBbMHglMDh4XSwgbG9jYWwgbmV0d29yayBbJWRdCgAAAAAAAAAAAAAAAAAAAGNobmV0IGZpbmQg -bDJ0ZW50IG5vdCB2YWxpZCwgMHgleCwgaWR4ICV1LCBzdGF0ZSAweCV4LCByZXRyeSBjb3VudCAl -dQoAAAAAAAAAAAAAY2huZXQgbDJ0ZW50IDB4JXgsIGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAA -AAAAY2huZXQgbDJ0ZW50IGZpbmQgZXJyCgAAAAAAAAAAAABjaG5ldF9maW5kX2lwNl9sMnRfZW50 -cnk6IGZpbmQgcHJlZml4IG1hdGNoIFslMDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAAAAAAAAAAAA -AE5vIHJvdXRlciBjb25maWd1cmVkLCBsMmRldl9mYy0+Zmxvd2NfaWQgMHgleAoAAApSb3V0ZXIg -bGlmZSAldSBleHBpcmVkLiBkZWxldGluZyByb3V0ZXIgWyUwNHggJTA0eCAlMDR4ICUwNHhdCgBV -c2luZyByb3V0ZXIgWyUwNHggJTA0eCAlMDR4ICUwNHhdIHRvIHJlYWNoIFslMDR4ICUwNHggJTA0 -eCAlMDR4XQoAAAAAAAAAAAAAAAAAAGNobmV0IGZpbmQgaXA2IGwydGVudCBub3QgdmFsaWQsIDB4 -JXgsIGlkeCAldSwgc3RhdGUgMHgleCwgcmV0cnkgY291bnQgJXUKAAAAAAAAY2huZXQgbDJ0ZW50 -ICUweCwgaWR4ICV1LCByZWZjbnQgJXUKAAAAAAAAAAAAAAAAY2huZXQgaXA2IGwydGVudCBmaW5k -IGVycgoAAAAAAABzZXR1cF9kZHA6IGlzdGFzazoweCV4LCBucHBvZCAldSwgYWxsb2MgZmFpbGVk -ICVkCgAAAAAAAAAAAAAAAAAAc2V0X2RpZ2VzdDogQlAgYWxyZWFkeSBmYyAweCV4IGZsYWdzIDB4 -JXgKAAAAAAAAc2V0X2RpZ2VzdDogY3NrIDB4JXggY29ubiAweCV4IHN0YXRlCgAAAAAAAAAAAAAA -c2V0X2RpZ2VzdDogdXBsc3VibW9kZToleCwgcGdpZHg6MHgleCwgdmFsOjB4JXggYnVmZmVyZWQg -MHgleAoAAHNldF9kaWdlc3Q6IGJ1Zl9sbF9mbHVzaCBmYyAweCV4IG5leHRfd3IgMHgleAoAAG5v -IHZhbGlkIGwydCBlbnRyeSBmb3IgcmVqZWN0IGNza19mYyAlcAoAAAAAAAAAAG5vIHZhbGlkIGwy -dCBlbnRyeSBmb3IgYWNjZXB0IGNza19mYyAlcAoAAAAAAAAAAHRndF9jb25uX3dyOiBmbG93LWlk -OjB4JXggdHlwZToweCV4IGlzIHdyb25nIGZvciBzdWJvcDoweCV4CgAAAABpcHY2X2FkZHJbMF0g -MHgleCBpcHY2X2FkZHJbMV0gMHgleAoAAAAAAAAAAAAAAABhZGRyICVzIHBvcnQgJXMgdGFnICVz -CgAAAAAAAAAAAHJlZGlyZWN0IElQdjYgMHgleC0weCV4LCBwb3J0ICV4CgAAAAAAAAAAAAAAAAAA -AHJlZGlyZWN0IElQdjQgMHgleCwgcG9ydCAleAoAAAAAYXV0aGVudGljYXRlX3RhcmdldDogSW5j -b3JyZWN0IHBhc3N3b3JkCgAAAAAAAAAAQ0hBUF9DOiBkaWdlc3QgZXhwYW5zaW9uIGVycm9yCgBD -SEFQX046IFRhcmdldCB1c2VyaWQgbWlzbWF0Y2gKAENIQVBfUjogZGlnZXN0IGV4cGFuc2lvbiBl -cnJvcgoAcmN2ZF9wYXJhbXM6IGVycm9yLCBsZW4gJWQKAAAAAABMb2dvdXQgZnJvbSBzZXNzaW9u -IFsweCV4XQoAAAAAAGlTQ1NJIFNlYy1wYXJhbXMgcmVjZWl2ZWQgaGF2ZSBlcnJvcnMhIQoAAAAA -AAAAAFRhcmdldCBtb3ZlZCB0ZW1wLiBjb25uICV4LCBzZXNzICV4CgAAAAAAAAAAAAAAAExvZ2lu -IEZhaWxlZCEhLiBjb25uX2ZjIFsweCV4XSwgc2Vzc19mYyBbMHgleF0sIHN0YXR1c19jbGFzcyBb -MHgleF0KAAAAAAAAAAAAAAAAUHJvdG9jb2wgRXJyb3IgY2JpdCAlZCB0Yml0ICVkIGNzZyAlZCBu -c2cgJWQKAAAAb2ZsZF9yeF9kYXRhOiBpbnZhbGlkIG9wY29kZSByZWNlaXZlZCwgYWJvcnRpbmcg -Y29ubmVjdGlvbiAleAoAAG5ldGlmX3BpbmdfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBb -MHgleF0sIGluZGV2Y3R4dCAweCV4IHN0YXRlIFslZF0gcmV0cnlfY250IFslZF0KAAAAAAAAAG5l -dGlmX3BpbmdfdGltZXJfY2I6IGwydF9pZHggJWQsIGRlbF9sMnQgJWQKAAAAAG5ldGlmX3Bpbmdf -dGltZXJfY2I6IHRpbWUgMHgleCB0eXBlICVkIGNvZGUgJWQgcmV0dmFsICVkCgAAAAAAAABuZXRp -Zl9waW5nX3RpbWVyX2NiOiBwaW5nX3RzIDB4JXgleCByc3BfdGltZSAweCV4JXgKAAAAAAAAAAAA -AAAAaWNtcF9sMnRfY2I6IHN1Ym9wICVkCgAAAAAAAAAAAABpY21wX2wydF9jYjogSW52YWxpZCBz -dWJvcCAlZAoAAGwzaW42X2Rldl9jb25maWc6IGxpbmsgbG9jYWwgSVAgbm90IGFzc2lnbmVkCgAA -AGwyZGV2X2ZjIFsweCV4IF0gRmFpbGVkIHRvIHN0YXJ0IHRpbWVyIGZvciBpcHY0IGRhZAoAAAAA -AAAAAAAAAABjaG5ldF9sMmRldl91cF9tYl9jYjogcmMgWyVkXSwgcG9ydCBbJXVdLCBzdGF0ZSBb -JXVdLCBjb29raWUgWzB4JXhdCgAAAAAAAAAAAAAAAGxvZ2luX3RpbWVkb3V0OiBCcmVha2luZyBw -YXRoIHMgWzB4JXhdIGMgWzB4JXhdIGNzayBbMHgleF0KAAAAAAByZWNvdmVyeV90aW1lb3V0OiBz -ZXNzIGlkIFsweCV4XSBpbiBsb2dvdXQKAAAAAABmb2lzY3NpOiBSZWNvdmVyeSB0aW1lZCBvdXQg -YWZ0ZXIgWyV1XSByZXRyeSwgYmFpbGluZyBvdXQKAAAAAAAAVENQIGNvbm4gZXN0YWJsaXNobWVu -dCBmYWlsZWQgJWQKAAAAAAAAAAAAAAAAAAAASW52YWxpZCBvcGNvZGUgMHgleCBpbiBjdHJsIHBh -dGgKAAAAAAAAAAAAAAAAAAAAZGF0YV9kZHA6IGl0YXNrLWlkOjB4JXgsIGZsYWdzOjB4JXgsIGR4 -ZmVyX2xlbjolZCwgZHNlbnRfbGVuOiVkCgAAAAAAAAAAAAAAAAAAAABkYXRhX2RkcDogdGlkIFsw -eCV4XSBlcnJvciBbMHgleF0KAAAAAAAAAAAAAAAAAABERFAgZXJyb3IgWzB4JXhdLCBhYm9ydGlu -ZyBjb25ubiBbMHgleF0KAAAAAAAAAAByeF9kYXRhX2RkcDogUmVzcG9uY2UgcmVjaWV2ZWQgZm9y -IHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9uIHN0YXRlLiB0YXNr -IHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3MgWzB4JXhdCgA9PT4g -cmVjZWl2ZWQgZGF0YSBmYyBpZCAweCV4IGZsb3djX2ljb25uX2ZsYWdzIDB4JXggbGVuIDB4JXgK -AAAAZm9pc2NzaV90YXNrIE5VTEwsIG9wOjB4JXggY3NrX2ZjaWQ6MHgleCBjc2tfc3RhdGU6MHgl -eCB0Y2JfZmNpZDoweCV4LCB0Y2Jfc3RhdGU6MHgleCAKAAAAAAAAAAAAaWhkcjogUmVzcG9uY2Ug -cmVjaWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9u -IHN0YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3Mg -WzB4JXhdCgAAAAAAAAAAaWhkcjogSW52YWxpZCB0YXNrIHN0YXRlIDB4JXggZm9yIHRhc2sgMHgl -eCwgaXR0IFsweCV4XSwgb3BjIFsweCV4XQoAAAAAAAAAAAAAAABpc2NzaV9oZHJfcng6IGFib3J0 -IGNvbm46IGZsYWdzID4+IDcgWzB4JXhdLCBoZHNnbGVuIFsweCV4XSBkc3JfZHRsIFsweCV4XSwg -bWF4X2J1cnN0IFsweCV4XQoAAABNYXggZGF0YSBsZW4gZXhjZWVkZWQgJWQgPiAlZAoAAHJldHVy -bl9wZW5kaW5nX3Rhc2s6IG5vIFdSIGl0YXNrOiBpZDoweCV4LCBzdGF0ZToweCV4LCBjb25uOjB4 -JXgsIGZsYWdzOjB4JXgsIGNvbm4taWQ6MHgleCwgZGRwOiVkCgAAAAAAAAAAAAAAAABoYW5kbGVy -ICV4LCBxdWV1ZWQgJXgKAAAAAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IERvbmUgc2VuZGlu -ZyB0YXNrIGVycm9yIHRvIGhvc3QKAAAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBkZXF1 -ZXVlIHRhc2sgWzB4JXhdLCBzdGF0ZSBbMHgleF0gZnJvbSB0eF9saXN0CgAAAAAAAAAAAAAAAHJl -dHVybl9wZW5kaW5nX3Rhc2s6IGFsbCB0YXNrcyByZXR1cm5lZCwgcmVjb3Zlcnkgc3RhdGUgdHJh -bnMgdG8gWzB4JXhdCgAAAAAAAAAAcHJvY2Vzc190eF9xdWV1ZTogdHhfcXVldWUgZm9yIGNvbm46 -MHgleCBzdG9wcGVkLCBhYm9ydGluZyB0YXNrLgoAAAAAAAAAAAAAAAAAAABXQVRDSERPR19kaXNw -YXRjaCBjYXNlIHRvIGF2b2lkOiBDb3VudGVyX3dhdGNoZG9nICV1IENvdW50ZXJfc2NoZWQgJXUg -CgAAAAAAAAAAAFdBVENIRE9HOiBkZXZpY2Ugc2h1dGRvd24KAAAAAAAAV0FUQ0hET0c6IHBvcnRb -JXVdIHBhdXNlIHdhdGNoZG9nIHRpbWVvdXQKAAAAAAAAV0FUQ0hET0c6IGJ5cGFzcyB0aW1lb3V0 -CgAAAAAAAABXQVRDSERPRzogRkxSIC0gbm90IGltcGxlbWVudGVkIHlldAoAAAAAAAAAAAAAAABX -QVRDSERPRzogdGVtcGVyYXR1cmUgb2YgJWRDIGV4Y2VlZHMgdGhyZXNob2xkIG9mICVkQwoAAAAA -AAAAAAAAZmlsdGVyOiBwb3JncmFtbWluZyB0aWQgJXUgKGxlIHRjYW0gaW5kZXggJXUpLi4uCgAA -AAAAAAAAAAAAAAAAAGZpbHRlcjogcmVxdWVzdGluZyBjb21wbGV0aW9uLi4uCgAAAAAAAAAAAAAA -AAAAAGRjYnhfaWVlZV9jbWRoWyV1XSB3cml0ZSBvbmx5IHBlcm1pdHRlZCBvbiBsb2NhbCBjb25m -CgAAAAAAAAAAAABkY2J4X2llZWVfY21kaFsldV0gY2Fubm90IHdyaXRlICV1IGFwcHMgKE1BWDog -JXUpCgAAAAAAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIHJlcXVlc3RpbmcgRENCX0lFRUVf -Q01ECgAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIHVua25vd24gZmVhdHVyZSB3cml0ZTogJXUKAAAA -ZGNieF9pZWVlX2NtZGhbJXVdIHVua25vd24gZmVhdHVyZSByZWFkOiAldQoAAAAAY2Fubm90IGFs -bG9jYXRlIG9mZmxvYWRlZCBmaWx0ZXIgY29ubmVjdGlvbgoAAAAAY2Fubm90IGFsbG9jYXRlIG9m -ZmxvYWRlZCBmaWx0ZXIgSVB2NiBjb25uZWN0aW9uCgAAAAAAAAAAAAAAAAAAAGRpc3BhdGNoX2Rl -ZmVycmVkX2NsYXNzX2NsYXNzX3NoYXBpbmdbJXU6JXVdOiBsaXN0X2VtcHR5CgAAAAAAAABsb29w -YmFjayBidWZmZXIgZ3JvdXBbJXVdIGlzIGRpc2FibGVkCgAAAAAAAAAAAABpbnZhbGlkIGJ1ZmZl -ciBncm91cFsldV0gY29uZmlndXJhdGlvbjogbXR1ICV1IGx3bSAldSBod20gJXUgZHdtICV1CgAA -AAAAAAAAAAAAAGZjICV1IHZmICV1IGdvdCBpdmY9MHgleCxyYW5nZTogJSN4LSUjeCAoJXUvJXUg -dXNlZCkKAAAAAAAAAAAAAABWSSAldSBjYW5ub3QgZ2V0IFJTUyBzbGljZTogTm8gbW9yZSBzbGlj -ZXMgYXZhaWxhYmxlICh1c2VkICV1LyV1KQoAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgd2l0 -aCBwb3J0IG1hc2sgMHgleCBjYW5ub3QgYWNjZXNzIHBvcnQgJXUsIHJldCAlZAoAAAAAAAAAAAAA -AAAAAAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxsb2NhdGUgdmlpZCwgcmV0ICVkCgAAcGZu -ICV1IHZmbiAldSBjb3VsZCBtYXAgdmlpZCAgMHgleCB0byBmbG93YywgcmV0ICVkCgAAAAAAAAAA -AAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHV3aXJlIGZ1bmMgJWQgbWFjIGFk -ZHIsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAcGYgJWQsIHZmICVkLCBFUlJPUiBleGNlZWRlZCBt -YXggbWFjIGxpbWl0ICVkLyVkCgAAAAAAAAAAAAAAAAAAAG1paV9pbml0WyV1XTogYWNhcHMgMHgl -eAoAAAAAAAAAbWlpX2ZvcmNlX3NwZWVkWyV1XTogcmNhcHMgMHgleAoAAAAAAAAAAAAAAAAAAAAA -bWlpX3Bkb3duWyV1XTogcG93ZXJkb3duIGVuICV1CgBwb3J0X2NtZF9oYW5kbGVyOiB1bmtub3du -IHUuZGNiLnR5cGUgMHgleAoAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgaW52 -YWxpZCByZXF1ZXN0LCBwY2FwcyAweCV4IGFjYXBzIDB4JXggbWNhcHMgMHgleCwgcmNhcHMgMHgl -eAoAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgcGNhcHMgJSN4IGFjYXBzICUjeCBy -Y2FwcyAlI3ggbWNhcHMgJSN4CgAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2Zn -LCBtZGkgaXNzdWUgcGNhcHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgKAAAAAAAAcG9ydFsl -dToweCUwMng6MHglMDJ4XTogbDFjZmcsIGNhbm5vdCBmb3JjZSBuby9tdWx0aXBsZSBzcGVlZChz -KSwgcGNhcHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgKAAAAAAAAAAAAAAAAAHBvcnRbJXU6 -MHglMDJ4OjB4JTAyeF06IHVua25vd24gYWN0aW9uIDB4JXgKAAAAAHBvcnRbJXU6MHglMDJ4OjB4 -JTAyeF06IHVua25vd24gcmVhZCBhY3Rpb24gMHgleAoAAAAAAAAAAAAAAAAAAABjcGxfZXJyX25v -dGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4CgAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlk -ICV1IGNwbCAweCUwOHglMDh4IDB4JTA4eCUwOHgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3Rp -Znk6IHRpZCAldSBsZW4gJXUKAABGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5n -Li4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAEZDT0UgQlAgV1IgRVJS -OiBXUiB3aXRoIGNvb2tpZSAleCV4IGVycm9yZWQgYmFjayAKAAAAAAAAAAAAAAAAAABhYm9ydC9j -bG9zZSBXUiB3aXRoIGNvb2tpZSAweCVseCB3YXMgaXNzdWVkIG9uIHNzbiAweCV4IGluIHdyb25n -IHN0YXRlIDB4JXgKAAAAAGFib3J0IFdSIG9uIHNzbiAweCV4IGRpZCBub3QgZmluZCBXUiB3aXRo -IGNvb2tpZSAweCV4JXgKAAAAAAAAAABjbG9zZSBXUiB3aXRoIGNvb2tpZSAweCVseCBvbiBzc24g -MHgleDtkaWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUgMHglbHgKAAAAAAAAAGFib3J0IFdSIG9u -IHNzbiAweCV4IHdhcyBpc3N1ZWQgb24geGNoZyAweCV4IHdpdGggcnhfaWQgMHgleCBpbiB3cm9u -ZyBzdGF0ZSAweCV4CgAAAAAAAAAAAAAAAAAAAGRjYnhfYXBwbHlfYXBwX2NmZ1sldV1ORVcgQVBQ -IFRMViAKAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVS -RV9MSU5LVVAKAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gU0VUX0xPQ0FMX1BBUkFN -RVRFUlMKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVf -Tk9fQURWRVJUSVNFCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBG -RUFUVVJFX1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NlZV9m -ZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0ZFQVRVUkUK -AAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VUERB -VEVfT1BFUl9WRVJTSU9OCgAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRV -UkVfUEVFUl9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9z -bVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9HRVRfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2Nl -ZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfQ0ZHX05PVF9DT01QQVRJQkxFCgAAAAAA -ZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9MT0NBTF9DRkcKAAAA -AAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0VfUEVFUl9D -RkcKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfRkVB -VFVSRV9ESVNBQkxFRAoAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFU -VVJFX0VSUk9SX0NIQU5HRQoAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9jZXNzWyV1XSByZWNlaXZl -ZCBCV3MgZG8gbm90IGFkZCB1cCB0byAxMDAhCgAAAAAAAABXQVJOSU5HOiByZWNlaXZlZCBBcHAg -VExWIGNvbnRhaW5zIG1vcmUgdGhhbkZXIGNhbiBoYW5kbGUgKG1heDogJXU7IHRsdiBjb250YWlu -czogJXUKAAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vzc1sldV0gc3VidHlwZSAlI3ggcmVtX2Z0 -X2NoYW5nZWQgJXUgc21fY2hhbmdlICV1CgAAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9jZXNz -WyV1XSBzdWJ0eXBlIHVua25vd24KAAAAAAAAAAAAAGRjYnhfcGFyc2VfcGt0WyV1XSBlcnJvciAl -ZAoAAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJkZXZfZmMgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2Nf -aWQgWyV1XSBsMmRldl9mYy0+Zmxvd2NfZmxhZ3MgWzB4JXhdLCBpbnRmIFsweCV4XQoAAAAAAAAA -AAAAAGNobmV0X2wydF91cGRhdGU6IGluIGRlbGF5ZWRfcHJvY2Vzc2luZywgbDJ0ZW50IFslMDh4 -XQoAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBsMnQgaXA0IGVudHJ5IG5vdCBmb3Vu -ZAoAAAAAAAAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTogbDJ0IGlwNiBlbnRyeSBu -b3QgZm91bmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGJvdGggaXA0 -IGFuZCBpcDYgYWRkciBjYW5ub3QgYmUgbnVsbAoAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBs -MnQgZW50cnkgaWR4ICV1LCBzdGF0ZSAweCV4CgAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZTog -bDJ0X3VwZGF0ZSByZXF1ZXN0IHNlbnQgbDJ0ZW50IFslMDh4XSwgbDJ0ZW50LT5pZHggWyVkXSwg -bDJ0ZW50LT52bGFuIFslZF0KAAAAaWNtcCBjaGVja3N1bToweCV4CgAAAAAAAAAAAAAAAABpcHY2 -IHRjcCByZWN2LCBpbml0IHR4cSB3ciBmYWlsZWQKAAAAAAAAAAAAAAAAAABESENQdjYgcGFja2V0 -IHR5cGUgJXUsIG9wdHNsZW4gJXUgcmVjZWl2ZWQKAAAAAABJbnZhbGlkIGRoY3Agc3RhdGUgJWQK -AAAAAAAAAAAAAElnbm9yZSBESENQdjYgbXNnIHhpZCAleCwgIGRoNmN0eHQtPnhpZCAleAoAAAAA -AEVycm9yIGluIERIQ1B2NiBvcHRpb25zIHBhcnNpbmcuIElnbm9yaW5nIG1zZywgaSAlZCwgb3B0 -c2xlbiAlZAoAAAAAAAAAAAAAAAAAAAAAREhDUCBmYWlsZWQsIHN0YXR1c2NvZGUgJWQuIElnbm9y -aW5nIGFkdmVydGlzZQoAaWNtcDYgY2hlY2tzdW0gdmFsaWRhdGlvbiBmYWlsZWQsIG9yIGVyciBy -Y3ZkaWdub3JpbmcgaWNtcDYgbXNnICV1LCBkbGVuICV1CgAAAAB0Y3AgcmVjdiwgaW5pdCB0eHEg -d3IgZmFpbGVkCgAAAENvdWxkIG5vIGFsbG9jYXRlIHBjYiEhIEZyZWVpbmcgZmNmICEhIQoAAAAA -AAAAAHZuX3BhcnNlIHVua25vd24gc3ViY29kZSAldQoAAAAAdm5fcGFyc2UgdW5rbm93biBkdHlw -ZSAldQoAAAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgcGNiIGZsb3c6JXggaW4gb2ZmbGluZSBz -dGF0ZQoAAAAAAAAAAAAAAAAAZmlwX3ZuMnZuX3JlY3ZfZXJyIAoAAAAAAAAAAAAAAABDb3VsZCBu -b3QgYWxsb2NhdGUgZmxvd2MhISEhCgAAAENvdWxkIG5vdCBhbGxvY2F0ZSBTQ0IgZmxvd2MhISEh -CgAAAAAAAAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgbG9nbwoAAAAAAAAA -AAAAAAAAAGlnbm9yaW5nIGZpcCByZWN2IGZvciBmY2YgZmxvdzoleCBpbiBvZmZsaW5lIHN0YXRl -CgAAAAAAAAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGZsb2dpCgAAAAAAAAAA -AAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIHJldHJ5IG5vdCBzdXBwb3J0ZWQKAAAAAABGbG9n -aSByZXNwIHJjdiB3aXRoIHVua25vd24geGNoZyBveF9pZCV4IHNpZCAlMnglMnglMnggZGlkICUy -eCUyeCUyeAoAAAAAAAAAAAAAAE5fUE9SVCAweCV4JXgleCByZWplY3RlZCBQTE9HSSB3aXRoIHJl -YXNvbiBjb2RlICV4CgAAAAAAAAAAAAAAAABBQlRTIHdoaWxlIGF3YWl0aW5nIFBSTEkgUnNwOiBm -bG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAAAAAAAAAAAAAAAEFCVFMgZmFr -ZSBSc3A6IGxvYyAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAGxsZHBfcnhfcGt0X2hhbmRs -ZXJbJXVdIGRyb3AgcHJlLWluaXQgKGNvdW50ID0gJXUpCgAAAAAAAAAAAAAAAABhcnBfcmVjdjog -aXBpZCBbMHgleF0sIGluX2FkZHIuYWRkciBbMHgleF0sIHNpcCBbMHgleF0sIHJpcCBbMHgleF0s -IGFycF9vcCBbMHgleF0KAAAAAAAAAAAAAAAAAABhcnBfcmVjdjogaW5fYXR0ci5pcHY0LmFkZHI6 -MHgleCwgYWhkci5zaXA6MHgleAoAAAAAAAAAAAAAAAAAAAAAY2huZXRfYXJwX3JlY3Y6IGlwIGNv -bmZsaWN0IGRldGVjdGVkCgAAAAAAAAAAAAAAY2huZXRfYXJwX3JlY3Y6IHBpZCBbJXVdLCB2bGFu -IFsweCV4XSwgYXJwIG9wIFsweCV4XSwgc2lwIFsweCV4XSwgcmlwIFsweCV4XSBsMmRldl9mYy0+ -Zmxvd2NfaWQgJXggbDJkYy0+aW40X2Rldi5pbl9hZGRyLmFkZHIgJXgKAAAAAAAAAAAAAAAAAAAA -JXgleCV4IFJlY2lldmVkIExPR08gZnJvbSAleCV4JXggCgAAAAAAAAAAAAAAAAAAQ1BMX1JYX1BL -VDogSWdub3JpbmcgTU9QIG9yIEVPUCBmcmFtZXMKAAAAAAAAAAAARmFpbGVkIHRvIHBvc3QgeGNo -ZyBlcnI6IHNzbmkgMHgleCBjb29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAG9mbGRfYWJvcnRf -cmVxX25lZ2FkdlsldV06IHdyIDB4JTA4eCBjcGxfYWJvcnRfcmVxIERFTElWRVJFRAoAAABob3N0 -X3dyWyV1XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgc3RhdHVzIDB4JXgKAAAAAAAAAAAAAAAA -AAAAcGt0c2NoZWRfY2xfcmxbJXU6JXVdOiBtb2RlIHwgdW5pdCB8IHJhdGUgMHglMDZ4IG1pbiAl -dSBtYXggJXUgcGt0c2l6ZSAldQoAAAAAAABwZiAlZCwgdmYgJWQgc2VjcmV0IGtleV9pbmRleCAl -ZCwgVkYgc2VjcmV0IDB4JXgKAAAAAAAAAAAAAAAAAAAAcGFyYW1fY2huZXRbMHgleDoweCV4XTog -Y2huZXQgMHgleCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAHBhcmFtX2RtYXFbMHgleDow -eCV4XTogZG1hcSAweCV4IHJlYWQgJXUgcGYgJXUgcmV0ICVkCgAAAAAAAAAAAABSU1NTRUNSRVRL -RVk6IHJzc3NlY3JldCB0YmwgYmFzZSAlZCwgcnNzbnNlY3JldCAlZAoAAAAAAAAAAAAAAAAATUNb -JXVdIGluaXRfc3RhdGVfbWFjaGluZSAweCUwMngKAAAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6 -YXRpb24gbm90IGNvbXBsZXRpbmcsIE1DIGN1cnJlbnQgaW5pdCBzdGF0ZSBpcyAweCUwMngKAAAA -AAAAAAAAAAAAAABNQ1sldV0gX2h3X21jX2luaXRfbWMKAAAAAAAAAAAAAF9od19tY19pbml0X21j -OiBlcnJvciwgcmV0ICVkCgAAX2h3X21jX2luaXRfbWNfZnBnYVsldV06IGVycm9yICVkCgAAAAAA -AAAAAAAAAAAAcGh5OiBmYWlsZWQgdG8gYWxsb2NhdGVkIG1lbW9yeSBmb3IgcGh5IGZ3IGZpbGUs -IHJldCAlZAoAAAAAAAAAAGh3X2xlX2ZpbHRlcl9jdHVwbGU6IHR1cGxlICV1IG5vdCBzcGVjaWZp -ZWQgYnV0IHJlcXVpcmVkIGZvciBtYXNrIDB4JXgKAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjog -aGFzaCByZWdpb24gdG9vIGxhcmdlIHRvIGVuYWJsZSBzZXJ2ZXIgc3JhbQoAAGxlIGNvbmZpZ3Vy -YXRpb246IGNhbm5vdCBlbmFibGUgc2VydmVyIHNyYW0gd2hlbiBoYXNoIHJlZ2lvbiBpcyBkaXNh -YmxlZAoAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IHRpbWVyX3JzICV1dXMgdGltZXN0YW1w -X3JlcyAldXVzIGRlbGF5ZWRhY2tfcmVzICV1dXMKAAAAAABod190cF90Y3Bfc2V0dGluZ3Nfdzog -ZGFja190aW1lciAldXVzIG1zbCAldXVzIHJ4dF9taW4sbWF4ICV1LCV1dXMgcGVyc19taW4sbWF4 -ICV1LCV1dXMKAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3Nfdzoga2VlcF9pZGxlLGludHZsICV1 -LCV1cyBtYXhydHQgJXV1cyBpbml0c3J0dCAldXVzIGZpbndhaXQyX3RpbWVyICV1dXMKAAAAAABo -d190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBkYWNrX3RpbWVyIGZyb20gJXUgdG8gJXUAAAAA -AAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgbXNsIGZyb20gJXUgdG8gJXUAaHdf -dHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcnh0X21pbiBmcm9tICV1IHRvICV1AAAAAAAAAAAA -AAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4dF9tYXggZnJvbSAldSB0byAldQAA -AAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBwZXJzX21pbiBmcm9tICV1 -IHRvICV1AAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVyc19tYXgg -ZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGtl -ZXBfaWRsZSBmcm9tICV1IHRvICV1AAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2Fw -cGluZyBrZWVwX2ludHZsIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdz -X3c6IGNhcHBpbmcgaW5pdF9zcnR0X21heHJ0dCBmcm9tICV1IHRvICV1AAAAAGh3X3RwX3RjcF9z -ZXR0aW5nc193OiBjYXBwaW5nIGluaXRfc3J0dF9pbml0c3J0dCBmcm9tICV1IHRvICV1AABod190 -cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBmaW53YWl0Ml90aW1lciBmcm9tICV1IHRvICV1AAAA -AAAAZmlsdGVyTW9kZT0lI3ggaWxsZWdhbDogc2VsZWN0cyAlZCBiaXRzIChtYXggJWQpCgAAAAAA -AAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUg -ZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAAGxlIGNvbmZp -Z3VyYXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAl -dSBhY3RpdmUgJXUgaGFzaCAldSBuc2VydmVyc3JhbSAldQoAAAAAAAAAAAAAAABod19zZ2VfcXVl -dWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgZWdyZXNzIHF1ZXVlcywgJXUKAAAA -AAAAAAAAAAAAAAAAAGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBv -ZiBpbmdyZXNzIHF1ZXVlcyB3aXRoIGZyZWVsaXN0IGFuZCBpbnRlcnJ1cHQsICV1CgAAAGh3X3Nn -ZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1ZXVlcywg -JXUKAAAAAAAAAAAAAAAAAAAARXJyb3IsIFRvdGFsIFJTUyBTZWNyZXQgdGFibGUgYWxsb2NhdGlv -biAlZCA+IDE2CgAAAAAAAAAAAAAAAAAAAHNrdSgweCV4KTogY3VzdG9tIHNrdSA0MEdfU08gZG9l -cyBub3Qgc3VwcG9ydCBleHRtZW0KAAAAAAAAAAAAAABza3UoMHgleCk6IGN1c3RvbSBza3UgMTBH -IGRvZXMgbm90IHN1cHBvcnQgNDBHIHBvcnRzCgAAAAAAAAAAAAAAc2t1KDB4JXgpOiBjdXN0b20g -c2t1IDEwR19TTyBkb2VzIG5vdCBzdXBwb3J0IDQwRyBwb3J0cygldSkgb3IgZXh0bWVtKCV1KQoA -AAAAAABza3U6IGN1c3RvbSBza3UoMHgleCkgNDBHIHBvcnRzKCV1KSBleHRtZW0oJXUpIHN1cHBv -cnRlZAoAAAAAAAAAY2ZfcGFyc2U6IGZpbGUgbWVtdHlwZSAweCV4IG1lbWFkZHIgMHgleCBtYXBw -ZWQgQCAlcDoKAAAAAAAAAAAAAGNvbmZpZ3VyZWQgd2l0aCBjYXBzIG5ibXxsaW5rIDB4JTA4eCBz -d2l0Y2h8bmljIDB4JTA4eCB0b2V8cmRtYSAweCUwOHggaXNjc2l8Y3J5cHRvIDB4JTA4eCBmY29l -OjB4JXgKAAAAAAAAAAAAAABuZXQgVkkgYWxsb2NhdGlvbiBmYWlsZWQgZm9yIGZjX2lkICV1IHdp -dGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAbmV0IFZJIG1hYyBhZGRyZXNzIHByb2dyYW1taW5nIGZh -aWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAAAAAABuZXQgVkkgcnht -b2RlIHByb2dyYW1taW5nIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAbmV0 -IFZJIHJzcyBpbmRpcmVjdGlvbiB0YWJsZSBwcm9ncmFtbWluZyBmb3IgZmNfaWQgJXUgZmFpbGVk -IHdpdGggZXJyb3IgJWQKAAAAAABuZXQgVkkgcnNzIGNvbmZpZyBjb21tYW5kIGZhaWxlZCBmb3Ig -ZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAbmV0IFZJIGNvbW1hbmQgZmFpbGVkIGZvciBmY19p -ZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAAAAAGZvaXNjc2lfaW5pdDogaW5pdF9kb25l -OiV1LCBmb2lzY3NpX250YXNrczoldSwgZm9pc2NzaV9uc2VzczoldSwgbmNzb2NrOiV1LCBuc3Bv -cnRzOiV1LCBmb2lzY3NpX25pbml0OiV1LCByYzolZAoAAAAAAAAAAAAAAAAAAAAARkNvRSBERFAg -aW5pdDogZmNvZSBsbGltaXQgMHgleCwgZmNvZSB1bGltaXQgMHgleCBnYmwgbGxpbWl0IDB4JXgg -Z2JsIHVsaW1pdCAweCV4IHBjYnN6ICV4CgAAAAAARkNvRSBERFAgaW5pdDogZmNvZSBwcG9kIG9m -ZiAweCV4LCBmY29lIHN0IHBwb2QgYWRkciAweCV4IGZjb2UgbnVtIHBwb2RzIDB4JXgKAABjaF9j -bF9yYXRlWyV1LyV1XTogY2FwcGVkIGNsYXNzIHJhdGUgZnJvbSByZXF1ZXN0ZWQgJXUgdG8gY29u -ZmlndXJlZCAoZWZmZWN0aXZlKSBjaGFubmVsIHJhdGUgJXUKAAAAAAAAAAAAAAAAAAAAY2hfY2xf -cmF0ZVsldS8ldV06IGluY3JlYXNlZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1ZXN0ZWQgJXUgdG8g -cmVxdWlyZWQgbWluIG9mICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfbWF4ICV1CgAAAAAA -AAAAAAAAAABwa3RzY2hlZCBjaGFubmVsICV1IHNldHMgc3BlZWQgKGZyb20gJXUpIHRvICV1IGti -cHMKAAAAAAAAAAAAAAAAbmV0X2wyZGV2X25vdGlmeTogcGdpZCBbMHgleF0sIHByaW8gWzB4JXhd -LCBjaCBbMHgleF0KAAAAAAAAAAAAAFsldV0gdW5hYmxlIHRvIGV4ZWN1dGUgaW50ZXJuYWwgRENC -X0lFRUVfQ01ECgAAAHBvcnRbJXVdIHB0eXBlICV1IGxhbmUgJXU6IHJ4Y2ZnID0gJSN4CgAAAAAA -AAAAAHBvcnRbJXVdIHB0eXBlICV1IGxhbmUgJXU6IHR4Y2ZnID0gJSN4CgAAAAAAAAAAAHBvcnRb -JXVdIGxpbmsgZG93biAoJXUpIChsc3RhdHVzICUjeCkKAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVz -ZWQgYnkgbW9kdWxlIHVucGx1ZwoAAAAAAAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5k -ICVwIGZvciBwb3J0ICV1LCB3YW50IHRvIHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAA -cG9ydFsldV0gdXBkYXRlIChmbG93Y2lkICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRf -bG9vcGJhY2sgcG9ydCAlI3ggY3VycmVudCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBv -cnRbJXVdIHNwZWVkIHVwZGF0ZTogJSN4CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNl -CgAAAABRU0ZQIG1vZHVsZSB1bnBsdWcgLSByZWluaXRpYWxpemluZyByeF9sb3MgIHRvIDB4ZmYK -AAAAAAAAAAAAAAAAZ3Bpb19xc2ZwX21vZHVsZV91cGRhdGU6IGNoYW5nZWQgcnhfbG9zIGZyb20g -MHgleCB0byAweCV4CgAAAAAAAGdwaW9fcXNmcF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHR4X2Rp -cyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABkaXNhYmxpbmcgdHggJSN4IHJ4ICUjeAoAAAAAAAAA -AHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1XSBwb3dlcmluZyBkb3duCgAAAAAAAHBvcnRfbGlu -a19zdGF0ZV9oYW5kbGVyWyV1XSBwb3dlcmluZyB1cAoAAAAAAAAAAHBvcnRfbGlua19zdGF0ZV9o -YW5kbGVyWyV1XSB1bmtub3duIHN0YXRlIChzdGF0ZSA9ICUjeCkKAAAAAAAAAABwb3J0X2xpbmtf -c3RhdGVfaGFuZGxlcjogU29tZXRoaW5nIHdlbnQgdGVycmlibHkgd3JvbmcuIHJldCA9ICVkCgAA -AAAAAAAAAAAAAAAAAENhbGN1bGF0aW9uIG91dCBvZiBib3VuZHMgZnVyaW5nIGluaXQ6ICUjeCAl -I3ggJSN4CgAAAAAAAAAAAAAAAABod19zZ2VfbWFtZW1faW5pdDogZW5jb3VudGVyZWQgZXJyb3Ig -JWQKAAAAAAAAAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAl -dSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBpbml0 -aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2VydmVy -ICV1IGFjdGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBfaW5p -dDogdGNiIHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2 -TUIgb2YgTUEgbWVtb3J5CgAAAAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lvbiAo -c3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVtb3J5 -CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBub3Qg -Y29tcGxldGUKAAAAAAAAAAAAAGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgleAoA -AAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50ZXJu -YWwgYnVmbGw2NCBidWZmZXJzCgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdoIG1l -bW9yeSB0byBhbGxvY2F0ZSBidWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjogbm90 -IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9i -dWY6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAldSB0 -cnlpbmcgdG8gdXNlICV1IGF2YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9v -dGhlcnM6IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpLCBobWEgJXUKAAAAAG1wYXJ0 -aXRpb25fb3RoZXJzOiBzdGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAAAAAA -AABtZW1faW5pdDogRURDIG92ZXJjb21taXR0ZWQgYnkgJWQgYnl0ZXMKAAAAAAAAAABtZW1faW5p -dDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyB0YWJsZQoAAAAAAAAAAAAAAAAA -Y3hjbmljX2RldmljZV9pbml0OiBjeGNuaWMgWzB4JTB4XSwgY3hjbmljLT5maWx0ZXIgWyUweF0K -AAAAAAAAAHBvZmNvZSBpbml0IGRvbmUKAAAAAAAAAAAAAAAAAAAAcG9ydF9pbml0WyV1XSBwdHlw -ZSAweCV4CgAAAAAAAABQb3J0WyV1XTogVW5rbm93biBTR01JSSBzdWItdHlwZSAlI3gKAAAAAAAA -AAAAAABQb3J0WyV1XTogVW5rbm93biBCVF9YRkkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAABwb3J0 -X2luaXRbJXVdOiBwb3J0IHR5cGUgMHgleCBpcyBub3Qgc3VwcG9ydGVkCgBtcGFydGl0aW9uX2lu -aXQ6IG1vdmVkIHBtcnhfc3RhcnQgZnJvbSAweCUwOHggdG8gMHglMDh4IHRvIG1ha2Ugcm9vbSBm -b3IgTEUgSEFTSCBhbmQvb3IgVFAgVENCcwoAAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9pbml0 -OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHglMDh4IHRvIDB4JTA4eCAoRURSQU0pCgAAAAAAAAAA -AAAAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBkZXN0cm95aW5nIGVxaWQgJXUgd2l0aCBwZW5kaW5n -IFdSKHMpIChudW1fYnl0ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAAAABBaCBoYS4uLmRv -dWJsZSBmcmVlIG94X2lkIDB4JXgsIHJ4X2lkIDB4JXgKAAAAAABIb3N0IFBSTEkgUmVzcG9uc2Ug -dGltZWRvdXQ6IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAAAAAAAAAAAAAAAAcGZuICV1IHZmbiAl -dSB2aWEgY29tbWFuZAoAAAAAAABod19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJfb3Ag -MHgleCBkYXRhWzBdIDB4JXggZGlmZiAldQoAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBh -ZGRyX29wIDB4JXggcmVnIDB4JXggZGlmZiAldSBjb250ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoA -AAAAAAAAAAAAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRyX29wIDB4JXggZGF0YVsw -XSAweCV4IGRpZmYgJXUgZHBvcyAldSBjb250ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoAAAAAAAAA -AAAAAAAAAGkyYyB0cmFuc2FjdGlvbiBmYWlsZWQgdG8gY29tcGxldGUKAAAAAAAAAAAAAAAAAGNv -bmZpZ3VyYXRpb24gZmlsZSBwYXJzZXI6IGFlY19yZXRyeV9jbnQgdmFsdWUgJWQgaXMgbm90IHdp -dGhpbiB0aGUgYWxsb3dlZCBsaW1pdCBvZiAxIHRvIDI1NC5EaXNhYmxpbmcgaXQuCgAAAABjb25m -aWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBhbl9hZWNfdGltZSB2YWx1ZSAlZCBpcyBiaWdnZXIgdGhh -biBhbGxvd2VkIGxpbWl0LkNoYW5naW5nIGl0IHRvIDEwMDAwIG1zLgoAAAAAAAAAAAAARGVwcmVj -YXRlZCBjb25maWcgb3B0aW9uIGZvdW5kIGluIGNvbmZpZyBmaWxlLiBJZ25vcmluZy4uCgAAAAAA -AGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXI6IHBsIHRpbWVvdXQgdmFsdWUgaXMgdG9vIGxhcmdl -LCBjaGFuZ2luZyBmcm9tICV1IHRvICV1dXNlY3MKAAAAAAAAAAAAAFBMX1BDSUVfTElOSy5zcGVl -ZCBvZiAldSBpcyBub3Qgc3VwcG9ydGVkCmZpbGUsIHJldCBGV19FSU8KAAAAAABzY2hlZF9pb3F0 -eF9icF9wcmlvcml0eTogaGFzICV1IGVudHJpZXMgb25seSwgcmVxdWlyZXMgJXUgZW50cmllcwoA -AAAAAAAAAAAAAAAAAHRwX2JhY2tvZmY6IHBhcnNlZCAlZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMK -AAAAAHRwX3RpbWVydmFsczogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50cmllcwoAAHRwX3Rp -bWVycmVzOiBwYXJzZWQgJWQgaW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAAHRwX210dXMgaGFzICV1 -IGVudHJpZXMgb25seSwgcmVxdWlyZXMgJXUgZW50cmllcwoAAAAAAAAAAAAAAAAAAAB0cF9tdHVz -WyV1XSBpcyAldSBieXRlcyB3aGljaCBpcyBub3Qgc3VwcG9ydGVkCgBjb25maWd1cmF0aW9uIGZp -bGUgcGFyc2VyOiBzZ2UgdGltZXIgdmFsdWVbJWRdIGlzIHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJv -bSAldSB0byAldXVzZWNzCgAAAAAAAABmaWx0ZXJtYXNrIDB4JXggaXMgbm90IGVxdWFsL3N1YnNl -dCB0by9vZiBmaWx0ZXJtb2RlCgAAAAAAAAAAAAAAaHdfbGVfY2xpcF9oYW5kbGVyOiByZW1vdmVk -IHBvcz0ldSAoPWlkeCAldSkKAAAAaHdfbGVfY2xpcF9oYW5kbGVyOiBhZGRpbmcgdG8gcG9zPSV1 -ICg9aWR4ICV1KQoAcGh5X2luaXQ6IHBvcnQgJXUgd2l0aCB0aGUgdHlwZSAldSAgaGF2ZSByZXQg -JWQKAAAAAAAAAAAAAAAAAAAAAGJlYW4vYWVjIGNvbXBsZXRlICV1CgAAAAAAAAAAAAAAaHdfbWFj -X2luaXRfcG9ydFsldV0sIHB0eXBlIDB4JXgsIHNwZWVkIDB4JXgsIGxhbmVzIDB4JXgsIGZlYyAw -eCV4CgAAAAAAAAAAAAAAAABtb2R1bGVbJXVdOiBwb3J0IG1vZHVsZSBpbnNlcnRlZCBhbmQgcmVh -ZHkKAAAAAABtb2R1bGVbJXVdOiBwb3J0IG1vZHVsZSByZW1vdmVkCgAAAAAAAAAAAAAAAAAAAABt -b2R1bGVbJXVdOiB1bmtub3duIG1vZHVsZSBpZGVudGlmaWVyIDB4JTAyeAoAAABtb2R1bGVbJXVd -OiBncGlvICV1IHZlbmRvciBpZCAlMDZ4LCBpZGVudGlmaWVyIDB4JTAyeCwgU0ZQMjgoYnl0ZSAz -Ni8xOTIpIDB4JTAyeCwgU0ZQKGJ5dGUgMy8xMzEpIDB4JTAyeCwgMUcgKGJ5dGUgNikgMHglMDJ4 -CgAAAG9wdGljYWwgbGVuZ3RoKGJ5dGUgMTUvMTQyKSAldSwgY29wcGVyIGNhYmxlKGJ5dGUgOC8x -NDcpIDB4JTAyeCwgbGVuZ3RoKGJ5dGUgMTgvMTQ2KSAldSwgbW9kdWxlX3R5cGUgMHglMDJ4CgAA -AABtb2R1bGVbJXVdOiBncGlvICV1IHZlbmRvciBpZCAlMDZ4LCBpZGVudGlmaWVyIDB4JTAyeCwg -U0ZQMjgoYnl0ZSAzNi8xOTIpIDB4JTAyeCwgU0ZQKGJ5dGUgMy8xMzEpIDB4JTAyeCwgMUcgKGJ5 -dGUgNikgMHglMDJ4CgAAAG9wdGljYWwgbGVuZ3RoKGJ5dGUgMTUvMTQyKSAldSwgY29wcGVyIGNh -YmxlKGJ5dGUgOC8xNDcpIDB4JTAyeCwgbGVuZ3RoKGJ5dGUgMTgvMTQ2KSAldSwgbW9kdWxlX3R5 -cGUgMHglMDJ4CgAAAABjeDRfY3JfbW9kdWxlX3J4X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRv -ICV1CgBNQzogZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNoIHRvIENGRy4AAAAAAAAAAAAAAABNQzog -ZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNoIHRvIEFjY2Vzcy4AAAAAAAAAAABNQzogZXhwZWN0ZWQg -c3RhdGUgdG8gc3dpdGNoIHRvIENGRy4AAAAAAAAAAAAAAABNQzogZXhwZWN0ZWQgc3RhdGUgdG8g -c3dpdGNoIHRvIEFjY2Vzcy4AAAAAAAAAAABJSS4xLmJ4IGRwMThbJXVdIHFbJXVdICUjeCAlI3gg -JSN4ICUjeCBtaW4gJSN4IG1heCAlI3gKAAAAAAAAAAAASUkuMS5jLWQuICUjeCAlI3ggJSN4ICUj -eCBhbGwgICUjeAoAAAAAAAAAAAAAAAAASUkuMi5iICglI3ggLSAlI3ggKyAlI3gpICUgMTI4ID0g -JSN4CgAAAAAAAAAAAAAASUkuMyBpbmV3XzFlIGFmdGVyIGxpbWl0IGNvbXB1dGUgaXRlbXBfMWUg -JXgsIGluZXdfMWUgJXgKAAAAAAAAAElJLjMuIGl0ZW1wXzFlICUjeCBpbmV3XzFlICUjeCBpbmV3 -XzFlICVkCgAAAAAAAElJLjQuIHNldF8xZSAlI3gKAAAAAAAAAAAAAAAAAAAATUM6IGNhbGlicmF0 -aW9uIGZhaWxlZCBmb3IgZXJyYXRhMjkgZHAxOCAldQoAAAAASVYuMS4gZHAxOFsldV0gcGhhc2Vf -c2VsIGJlZm9yZSAlI3ggYWZ0ZXIgJSN4LCBnYXRlX2RlbGF5ICUjeAoAAE1DIGVycmF0YTI5IGlz -c3VlOiBkcDE4ICV1IHF1YWQgJXUgY2Fubm90IGJlIGRlY3JlYXNlZAoAAAAAAAAAAABNQyBlcnJh -dGEyOSBpc3N1ZTogZHAxOCAldSBxdWFkICV1IGNhbm5vdCBiZSBkZWNyZWFzZWQKAAAAAAAAAAAA -TUMgZXJyYXRhMjkgaXNzdWU6IGRwMTggJXUgcXVhZCAldSBjYW5ub3QgYmUgZGVjcmVhc2VkCgAA -AAAAAAAAAE1DIGVycmF0YTI5IGlzc3VlOiBkcDE4ICV1IHF1YWQgJXUgY2Fubm90IGJlIGRlY3Jl -YXNlZAoAAAAAAAAAAAB0ZW1wMl8xZSsweDEwID0gJSN4CgAAAAAAAAAAAAAAAE1DOiBjYWxpYnJh -dGlvbiBmYWlsZWQgZm9yIGVycmF0YTIxIGl0ZXJhdGlvbiAldQoAAAAAAAAAAAAAAAAAAABNQyBl -cnJhdGEgMjE6IGRwMThbJXVdIHByMCBuMDIgZmFpbGVkIHRvIGdldCBhdmVyYWdlCgAAAAAAAAAA -AAAATUMgZXJyYXRhIDIxOiBkcDE4WyV1XSBwcjAgbjEzIGZhaWxlZCB0byBnZXQgYXZlcmFnZQoA -AAAAAAAAAAAAAE1DIGVycmF0YSAyMTogZHAxOFsldV0gcHIxIG4wMiBmYWlsZWQgdG8gZ2V0IGF2 -ZXJhZ2UKAAAAAAAAAAAAAABNQyBlcnJhdGEgMjE6IGRwMThbJXVdIHByMSBuMTMgZmFpbGVkIHRv -IGdldCBhdmVyYWdlCgAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVkOiBERkkgaW5p -dCBub3QgZ29pbmcgdG8gMAoAAAAAAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIGZhaWxlZDog -REZJIGluaXQgbm90IGNvbXBsZXRpbmcKAAAAAAAAAAAAAAAAAABNQyBpbml0aWFsaXphdGlvbiBm -YWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21wbGV0ZS4KAAAAAAAAAAAARFAxOCAldSwgYnl0 -ZV9sYW5lICV1LCBiaXRfc2VsZWN0ICV1CgAAAAAAAAAAAAAARFAxOCAldSwgYnl0ZV9sYW5lICV1 -LCBiaXRfc2VsZWN0ICV1CgAAAAAAAAAAAAAATUMgZmFpbGVkIHRvIGdldCBVUENUTCBwb3dlciB1 -cCBkb25lCgAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVkOiBEaWRuJ3QgZ2V0IGFs -bCBEUDE4cyBsb2NrZWQKAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIGZhaWxlZDogRGlkbid0 -IGdldCBib3RoIEFEUnMgbG9ja2VkCgAAAAAAAAAAAABDdXJyZW50IFNsZXcgdHhfcm93ICVkOiB0 -eF9jb2wgJWQsIHZhbCAlZAoAAAAAAABDdXJyZW50IFNsZXcgYWRkcl9yb3cgJWQ6IGFkZHJfY29s -ICVkLCB2YWwgJWQKAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IFNMRVdfRE9ORV9TVEFUVVMg -bmV2ZXIgdG9nZ2xlZAAAAAAAAAAAcGZuICV1IHZmbiAldSBGU00gc3RhcnQKAAAAAAAAAABwZm4g -JXUgdmZuICV1IEZTTSBjb21wbGV0ZQoAAAAAAGZscl9wZnZmX2ZzbVsldToldV06IHVua25vd24g -c3RhdGUgJXUKAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgaW4gZDNob3QsIGlnbm9yaW5nLCBkM2hv -dCAweCUwOHggUENJRV9TVEFUIDB4JTA4eAoAAAAAAAAAAAAAAAAAAAAAaHcgcGYgYml0bWFwIDB4 -JTAyeCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUwOHgKAAAAAGFmdGVyIHZm -aWQgZml4dXAsIHZmaWQgYml0bWFwIDB4JTA4eDoweCUwOHg6MHglMDh4OjB4JTA4eAoAAAAAAABN -Q1sldV06IGZhaWxlZCB0byBzd2l0Y2ggY29udHJvbGxlciB0byBDRkcgc3RhdGUKAAAAAAAAAAAA -AAAAAAAATUNbJXVdOiBmYWlsZWQgdG8gc3dpdGNoIGNvbnRyb2xsZXIgdG8gSU5JVF9NRU0gc3Rh -dGUKAAAAAAAAAAAAAE1DWyV1XTogZmFpbGVkIHRvIHN3aXRjaCBjb250cm9sbGVyIHRvIENGRyBz -dGF0ZQoAAAAAAAAAAAAAAAAAAABNQ1sldV06IHBlcmlvZGljIGNhbGlicmF0aW9uIGZhaWxlZCB3 -aXRoIGVycm9yICV1CgAAAAAAAAAAAAAAAAAAdGltZXIgcXVldWUgJXUgbG9zdCBhIHRpY2shIG5l -eHQgJXAgbGFzdCAlcCBudW1lICV1CgAAAAAAAAAAAAAAAGZscl90aW1lcl9zdGFydDogZmxvd2Nf -aWQgJXUgJXAgYnVmICVwCgAAAAAAAAAAAE1BQzogUExMcyBkaWRuJ3QgbG9jawoAAAAAAAAAAAAA -cGNpZTogcmVhZCBmcm9tIHNlcmNmZyBwY2llX2lwX3VyX21heGZ1bmMgMHgleCBwZmJpdG1hcCAw -eCV4CgAAAHBjaWU6IFNlcmlhbCBDb25maWd1cmF0aW9uIFNQQVJFMyBoYXMgQ29va2llIEdlbmVy -YXRpb24gZW5hYmxlZC4KAAAAAAAAAAAAAAAAAAAAcGNpZTogbnBmICV1IChwZmJpdG1hcCAweCUw -MngpIG52ZiAldSAocGYgMC4uNyAweCUwOHglMDh4KSB2ZnN0cmlkZSAldQoAAAAAAAAAAABod19t -YWNfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAGh3X2dwaW9fcHJlcDogZXJyb3IsIHJldCAlZAoA -AAAATUMgQ0xLIHNldHRpbmcgZmFpbGVkOiBQTExfTV9MT0NLIG5ldmVyIHRvZ2dsZWQKAAAAAAAA -AAAAAAAAAAAAAGZhaWxlZCB0byBmaW5kIHRoZSAlYyVjIFZQRCBwYXJhbWV0ZXIKAAAAAAAAAAAA -AGZhaWxlZCB0byBwYXJzZSB0aGUgJWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAG1lbV9wcmVw -OiBlcnJvciwgcmV0ICVkCgAAAAAAAAAAZmFpbGVkIHRvIHN1Y2Nlc3NmdWxseSBmaW5kIENoZWxz -aW8gVlBECgAAAAAAAAAAdnBkX3ByZXA6IGVycm9yLCByZXQgJWQKAAAAAAAAAABzZXJjZmdfcHJl -cDogZXJyb3IsIHJldCAlZAoAAAAAAGxvZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgl -dSBlbnRyaWVzKSBmd3JldiAweCUwOHggcGNpZV9mdyAweCUwOHgKAAAAAAAAYm9vdHN0cmFwIGZp -cm13YXJlIHRvb2sgJXUgbXNlY3MgdG8gcnVuCgAAAAAAAAAAUEkgZXJyb3IgZmxvd2lkX2xlbjE2 -IDB4JXgsIGFwcF90YWcgMHgleCwgcmVmX3RhZyAweCV4LCBwaXNjICUwNHggJTA0eCAlMDR4ICUw -NHgKAAAAAAAAAAAAAAAAAAAAZmxvd2MgJXUgKFNHRSBlcWlkICV1KSAoRVRIQ1RSTCBxdWV1ZSkg -ZXhwZXJpZW5jZWQgYSBQQ0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1 -ZXVlICV1KQoAAAAAAAAAAGZsb3djICV1IChTR0UgZXFpZCAldSkgZXhwZXJpZW5jZWQgYW4gdW5l -eHBlY3RlZCBQQ0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1 -KQoAAAAAAAAAAAAAAABmbG93YyAldSBleHBlcmllbmNlZCBhbiB1bmV4cGVjdGVkIFBDSSBETUEg -UkVBRCBlcnJvciAoaW5ib3VuZCBxdWV1ZSAldSkKAAAAAAAAAGdhdGhlcl90YXNrc19mb3JfdG1m -OiBJbnZhbGlkIHR5cGUgWzB4JXhdLCBiYWlsaW5nIG91dC4KAAAAAAAAAABmY19zZW5kX2FsbG9j -X2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9j -b21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0 -dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAAAARkNvRSBGQ0IgbGlua2Rvd246IGlvX3Jl -cSAweCV4JXggaXFpZCAweCV4IGZsb3dpZCAweCV4IG9wIDB4JXgKAGZjb2Ugbm90aWZ5IDogVXBk -YXRlIG5ldyBEQ0JYIHZhbHVlcyBWSSBzdGF0ZSAweCV4IHByaSAweCV4IHNjaGVkY2wgMHgleCBk -Y2J4X2RvbmUgMHgleAoAAAAAAAAAAGZjb2Ugbm90aWZ5IDogRkNGIGZsb3dpZCAweCV4LCB1bHBj -aCAweCV4IAoAAAAAAGZjb2Ugbm90aWZ5IDogRkNvRSBMSU5LVVA6IHBvcnQgMHgleCwgZXZlbnQg -MHgleAoAAAAAAAAAAAAAAAAAAABmY29lIG5vdGlmeSA6IEZDb0UgTElOS0RPV046IHBvcnQgMHgl -eCwgZXZlbnQgMHgleAoAAAAAAAAAAAAAAAAAZmNvZSBub3RpZnkgOiBEQ0JYIDogcG9ydCAweCV4 -LCBwcmlvcml0eSAweCV4IHVscHR4Y2ggMHgleCBjbGFzcyAweCV4CgAAAAAAAAAAAABSREVWIG1z -ZyBmbG93YzoleCBzdGF0ZSAweCV4IGV2ZW50IDB4JXgKAAAAAAAAAABjYW5jZWwgZmNiOiV4IHNj -YjoleCBzdGF0ZToleAoAAEZDb0UgRkNGIHRpbWVyOiBmbG93YyBzdGF0ZSAweCV4LCBwb3J0IDB4 -JXggLGZjZiAweCV4LCBmbG93Y19pZCAweCV4CgAAAAAAAAAAAAAAaHcgcmVnaXN0ZXIgb3BlcmF0 -aW9uIG5vdCBjb21wbGV0aW5nLCByZWcgMHglMDh4IG1hc2sgMHglMDh4IHZhbHVlIDB4JTA4eCAo -cmVnIDB4JTA4eCkKAAAAAAAAAAAATURJTyBDTDQ1OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRy -CgAAAAAAAAAAAAAATURJTzogZmFpbGVkIHRvIHJlYWQKAAAAAAAAAAAAAABXcml0ZV9hbGxfcG9y -dHM6IHBpZCA9ICV1IHJlZyA9IDB4JXggCgAAAAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBz -ZXQgdXAgTU1EIGFkZHIKAAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gd3JpdGUKAAAAAAAAAAAA -AG1paV9hZHZfZmNbJXVdOiByY2FwcyAweCV4CgAAAAAAbWlpX2Fkdl9zcGVlZFsldV06IHJjYXBz -IDB4JXgKAABjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGZsb3djX2lkIFsldV0gbDJk -ZXZfZmMgWzB4JXhdIGFscmVhZHkgcmVjZWl2ZWQgUkEsIG5vdCBzZW5kaW5nIFJTCgAAAAAAAAAA -AAAAAAAAZmxvd2NpZCBbJXVdIGwyZGV2X2ZjIFsweCV4XSBObyBJUHY2IHJvdXRlcgoAAAAAY2hu -ZXQgWyVkLyVkXSBmcmVlIGwydCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKAAAAAAAAAAAAAAAA -AAAAAGNobmV0IFslZC8lZF0gcHV0IGwydCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKACUwOHg6 -ICUwOHggJTA4eCAlMDh4ICUwOHgKAAAAAAAAY2huZXQgWyVkLyVkXSBnZXQgbDJ0IGVudHJ5OiBp -ZHggJXUsIHJlZmNudCAldQoAY2huZXQgWyVkLyVkXSBsMnQgYWxsb2MgbDJ0ZW50IDB4JXgsIGlk -eCAldSwgcmVmY250ICV1CgAAAAAAAAAAAG91dCBvZiBhdGlkczogbWF4IGF0aWRzOiAlZAoAAAAA -dGFza19hbGxvYzogT3V0IG9mIHRhc2tzLgoAAAAAAABjb2lzY3NpX2ZpbmRfdGFzazogdGFzayBu -b3QgZm91bmQgdGNiX2ZjIGlkIDB4JXggaXR0IDB4JXggdHR0IDB4JXgKAAAAAAAAAAAAAAAAAHBl -bmRpbmdfY3NvY2tzOiBjc29jazogJXAgdGd0X2ZjOiAlcCBpZHggJXUgc3RhdGUgMHgleAoAAAAA -AAAAAABmbG93X2lkIFsweCV4XSBoaXN0b3J5IDB4JTJ4IDB4JTJ4IDB4JTJ4IDB4JTJ4IDB4JTJ4 -CgAAAAAAAAAAAAAAZm9pc2NzaV92YWxpZGF0ZV9sb2dpbl9zdGFnZTogLSAxCgAAAAAAAAAAAAAA -AAAAbDJkZXZfdmlfZnNtOiBtYiBbMHgleF0sIGRlZmVycmVkLCBzdGF0ZSBbMHgleF0sIHBvcnQg -WzB4JXhdCgAAAGwyZGV2X3ZpX2ZzbTogdmlpZCBbMHgleF0gcG9ydCBbMHgleF0sIG1hYy1pZCBb -JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMnhdLiAKAAAAAAAAAAAAAAAAAAAAAGwyZGV2X3Zp -X2ZzbTogc2dlX2VxaWQgWzB4JXhdLCBzZ2VfaXFpZCBbMHgleF0sIHNnZV9lcWNyIFsweCV4XSwg -cnNzX3N6IFsweCV4XQoAbDJkZXZfdmlfZnNtOiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X210 -dSBbJXVdLCBtYl9zY3JhdGNoIFsweCV4XSwgcG9ydCBbMHgleF0KAAAAAAAAAAAAAAAAAAAAbDJk -ZXZfdmlfZnNtOiB2aWlkIFslZF0sIHZpX2ZjLT5mbG93Y192aV9mbGFncyBbMHgleF0KAAAAAAAA -AAAAAGwyZGV2X3ZpX2ZzbTogcGZuIFsweCV4XSwgdmZuIFsweCV4XSwgbDJkZXZfZmMtPmZsb3dj -X2lkIFsweCV4XSwgbHBvcnQgWzB4JXhdLCB2aWlkIFsweCV4XSwgZmxhZ3MgWzB4JXhdCgAAAAAA -AABsMmRldl92aV9mc206IEVycm9yIGZyZWVpbmcgVkksIHJjIFsweCV4XQoAAAAAAABsMmRldl92 -aV9mc206IHBpZCBbMHgleF0sIHZpaWQgWzB4JXhdLCBtYl9sb2MgWzB4JXhdLCBtYl9vcmlnWzB4 -JXhdLCBsMmRldl9mbGFncyBbMHgleF0sIHJjIFsweCV4XQoAAAAAAAAAAAAAAAAAZm9pc2NzaV9m -aW5kX3Rhc2s6IHRhc2sgbm90IGZvdW5kIHRjYl9mYyBpZCAweCV4IGl0dCAweCV4CgAAAAAAAFdB -VENIRE9HOiBObyB0ZW1wZXJhdHVyZSBzZW5zb3IgYXZhaWxhYmxlLgoAAAAAAFdBVENIRE9HOiBB -Y3RpdmF0aW5nCgAAAAAAAAAAAAAAV0FUQ0hET0cgLSBFbmFibGUgYWN0aW9uICV1IHRpbWUgJXUK -AAAAAAAAAAAAAAAAV0FUQ0hET0cgLSBEaXNhYmxlIGFjdGlvbiAldQoAAABXQVRDSERPRzogRGUt -YWN0aXZhdGluZwoAAAAAAAAAAHBvcnRbJXVdIHNldCBQQVVTRSBQQVJBTVM6IHBwcGVuICV1IHR4 -cGUgJSN4IHJ4cGUgJSN4CgAAAAAAAAAAAABtcHNfbGlua191cFsldV0gYWNhcHMgJSN4ICg4MDIu -MyAlI3gpICsgbHBhY2FwcyAlI3ggPT4gJSN4CgAAAAAAY2hfY2xfcmF0ZVsldS8ldV06IGNhcHBl -ZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1aXJlZCAldSB0byAldTsgcmF0ZSAldSAoZWZmICV1KSBk -ZWZpY2l0X21heCAldQoARENCWDogc3VtIG9mIHJhdGVzIG9uIGFsbCBjbGFzc2VzIG11c3QgYmUg -MTAwIChhY3R1YWw6ICV1KQoAAAAAAHJpX3dyX2luaXRbJXVdOiBtc3MgJXUgaXMgbm90IDgtYnl0 -ZSBhbGlnbmVkCgAAAGNvcmVfcHJvZ3JhbV90Y2I6IHRpZCAlI3ggdF9zdGF0ZSAlI3ggcmN2X2Fk -diAweCUwOHggcmN2X3NjYWxlICUjeCB0eF9tYXggJSN4IHJjdl9ueHQgJSN4IGF0aWQgJSN4CgAA -AAAAAAAAAAAAAAAJb3B0MCAlI3gleCBvcHQyICUjeCBpcHY2ICUjeCBmbGFnc190aW1lciAweCUw -OHgKAAAAAAAAAAAAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10 -dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBpcCAweCUwOHglMDh4IGZp -bHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAAAAAAAAAAAAb2ZsZF9jb25u -ZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxp -cCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBAIExFIGluZGV4ICV1CgAA -AAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0 -eCBmcCAweCUwNHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmlsdGVyIDB4JTA4eAoA -AAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUwNHgg -ZnAgMHglMDR4IGxpcCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHglMDh4CgAAAAAAAAAAAAAA -AElRRkxJTlQgcGZuICV1IHZmbiAldTogaXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAAAAAA -AAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgbm90IGFsbG9jYXRlZAoAAABJ -UUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMGlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAAAAAA -AAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSBub3QgYWxsb2NhdGVkCgAASVFG -TElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAAAAAAAAAA -AAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgbm90IGFsbG9jYXRlZAoAAElRRkxJ -TlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgaXMgdmFsaWQgYnV0IG5vdCBmbDBpZCAldQoAAAAA -AABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBoZWFkZXIgc3Bs -aXQgZmVhdHVyZSBpcyBub3QgZW5hYmxlZAoAAAAAAAAAAAAAAAAAAABod191bHB0eF93b3JrYXJv -dW5kX3ByMTY5NDlfZW5hYmxlZF92ZmlkOiB2ZmlkICV1IGVuYWJsZWQgJXUKAAAARVEgcGZuICV1 -IHZmbiAldTogY3JlYXRpbmcgRVRIIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0 -ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAARVEgcGZuICV1IHZmbiAldTogY3JlYXRpbmcg -Q1RSTCBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAw -eCUwOHgKAAAAAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkK -AAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAAAAAAAAZGNieF9w -b3B1bGF0ZV9jdHJsIGNvZGUgaW5jb21wbGV0ZQoAAAAAAAAAAAAAAAAAdmlfdGNhbV9yYXcgaWR4 -ICV1IG1hYyAweCUwNHggJTA4eAoAAAAAAAAAAAAAAAAAcG9ydF9ibGlua19sZWRfcmVzdG9yZQoA -AAAAAAAAAABwb3J0X2JsaW5rOiBibGlua2R1cj0weCV4IGJsaW5rX3JlZmNudAoAAAAAAAAAAABw -b3J0X2JsaW5rOiAJYmxpbmtfcmVmY250PTB4JXgKAHBvcnRfYmxpbms6IAlibGlua19yZWZjbnQ9 -MHgleAoAbWlpX2FucmVzdGFydFsldV06IGFjYXBzIDB4JXgKAABtaXNzaW5nIHBvcnQgY2FwczMy -IHRvIGNhcHMxNiB0cmFuc2xhdGlvbiBmb3IgJSNseAoAAAAAAAAAAAAAAAAAcG9ydF9jbWRfaGFu -ZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAbWlzc2luZyBwb3J0IGNhcHMxNiB0 -byBjYXBzMzIgdHJhbnNsYXRpb24gZm9yICUjeAoAAAAAAAAAAAAAAAAAAGJhZCBGbG93QyAlZCBv -biBlc3RhYmxpc2hlZCBjb25uZWN0aW9uCgAAAAAAAAAAAGV0aF9mbG93Y19oYW5kbGVyWzB4JXhd -OiBmbGFncyAweCUwOHggbnVtX2J5dGVzICV1IHNjaGVkY2wgMHgleCAtPiAweCV4CgAAAAAAAAAA -c2NzaV9yZWFkOiBwcG9kIGFsbG9jIGZhaWxlZCwgbnBwb2QgJXUKAAAAAAAAAAAAZGNieF9jb250 -cm9sX3NtWyV1XSBDT05UUk9MX0xJTktVUAoAAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1 -XSBDT05UUk9MX1VQREFURV9EQ0JYX1RMVgoAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9M -X1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0g -Q09OVFJPTF9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xf -c21bJXVdIENPTlRST0xfUFJPQ0VTU19QRUVSX1RMVgoAAABkY2J4X2NvbnRyb2xfc21bJXVdIENP -TlRST0xfQUNLX1BFRVIKAAAAAAAAAAAAAABkY2J4X2llZWVfdmFsaWRhdGVbJXVdIGVycm9yIChv -dWkgJSN4IHN1YnR5cGUgJSN4IGxlbiAlI3gpCgAAAAAAZGNieF9jZWVfdmFsaWRhdGVbJXVdIGVy -cm9yCgAAAABESENQdjYgUkVQTFkgcmVjZWl2ZWQgc3RhdGUgJXUKAGRoY3AgcmVwbHkgcmVjZWl2 -ZWQgaW4gd3Jvbmcgc3RhdGUgJWQKAAAAAAAAAAAAAHVua25vd24gc2VydmVyaWQuIElnbm9yaW5n -IGRoY3AgcmVwbHkKAAAAAAAAAAAAAHJlY2VpdmVkIHJlcGx5IHdpdGggZGlmZmVyZW50IGFkZHJl -c3MuIGlnbm9yaW5nIGRoY3AgcmVwbHkKAAAAAABESENQdjYgQURWRVJUSVNFIHJlY2VpdmVkCgAA -AAAAAGRoY3AgYWR2ZXJ0aXNlIHJlY2VpdmVkIGluIHdyb25nIHN0YXRlICVkCgAAAAAAAGlnbm9y -aW5nIHJjdmQgYWR2ZXJ0aXNlIHByZWZlcmVuY2UgJXUKAAAAAAAAAAAAAFN0YXJ0IERIQ1B2NiB0 -byBnZXQgdGhlIGlwIGFkZHJlc3MKAAAAAAAAAAAAAAAAAE5vIGRoY3AsIGRoY3Agc3RhdGUgJWQs -IGFkZHIgc3RhdGUgJWQKAAAAAAAAAAAAACUwMnggJTAyeCAlMDJ4ICUwMnggJTAyeCAlMDJ4CgAA -dm4ydm46IHBvcnQgMHgleCBkaWQ6MHgleCV4JXggVVAKAAAAAAAAAAAAAAAAAAAAdm4ydm46IHBv -cnQgMHgleCBkaWQ6MHgleCV4JXggRE9XTgoAAAAAAAAAAAAAAAAAZmNfc2VuZF9hbGxvY19jcGw6 -IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0 -ZV9jdHVwbGUgMHgleDoleAoAAAAAY29tcHV0ZV9jdHVwbGUoKTogZmFpbGVkIHRvIHNldHVwIGZp -bHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0ZV9jdHVwbGUgdmxhbiAleCB2 -aWlkICV4IHBvcnQgJXggbXBzX2lkeCAleAoAAAAAAAAAAABBQlRTIEFDQyBhd2FpdGluZyBQUkxJ -IFJzcDogZmxvd2NfaWQgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXggaXFpZCAweCV4CgAAAAAA -AHBvcnQgMHgleCwgc3RhdGUgMHgleCwgY29tbWFuZCBmYWlsZWQgcmV0cmllcyAweCV4CgAAAAAA -AAAAAAAAAABHb3QgQ09OTl9FWElTVCBmb3IgeGlkOjB4JXgsIHRhZzoweCV4LCByZXRyeWluZy4K -AAAAAAAAAAAAAAAAAAAAY2hfcmF0ZVsldV06IGNhcHBlZCB0aWNrIGZyb20gcmVxdWlyZWQgJXUg -dG8gc3VwcG9ydGVkICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfaW5jciAldSB0aWNrICV1 -CgAAAAAAAAAAAAAAAHBrdHNjaGVkX2NoX3JsWyV1XTogY2hhbm5lbCBybCBub3QgYXZhaWxhYmxl -IGluIGNvbmp1bmN0aW9uIHdpdGggZmxvdyBzaGFwaW5nCgAAcGt0c2NoZWRfY2hfcmxbJXVdOiBy -YXRlICV1IG1heCAldQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfd3JyWyV1OiV1XTogd2VpZ2h0 -ICV1CgAAAAAAAAAAAAAAAAAAZXFfcGFyYW1zWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1 -IHBmICV1IGVxaWRfYXBpICV1IHJldCAlZAoAAAAAAAAAAAAAAAAAAAB3YWl0X2Zvcl9jYWxpYl9k -b25lOiByZXQgJWQgaW4gJXUgYXR0ZW1wdHMKAAAAAABod19tYV9hZGRyX3RvX21lbV90eXBlX29m -ZjogTUEgYWRkcmVzcyAweCUwOHggaXMgbm90IG1hcHBlZAoAAAAAaHdfbWFfYWRkcl90b19tZW1f -dHlwZV9vZmY6IE1BIGFkZHJlc3MgMHglMDh4IG1hcHMgdG8gdHlwZSAldSBvZmZzZXQgMHgleAoA -AAAAAABtZW1fbWFsbG9jX3RlbXA6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJu -aW5nIE5VTEwKAAAAcmluZyBiYWNrYm9uZSwgZW5hYmxlICVkLCBtcHMuZmxhZ3MgMHgleAoAAAAA -AAAAcmluZyBiYWNrYm9uZSBubyBjaGFuZ2UgaW4gY29uZmlndXJhdGlvbgoAAAAAAAAAcmluZyBi -YWNrYm9uZSBjb25maWd1cmF0aW9uIGVycm9yLCBUQ0FNIG5vdCBlbXB0eS4gYXZhaWxhYmxlICVk -LCBzaXplICVkCgAAAAAAAABtZW1fbWFsbG9jOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMs -IHJldHVybmluZyBOVUxMCgAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBtb2RlIHJlcXVp -cmVzIGF0IGxlYXN0IDE2IGVudHJpZXMsIG5oYXNoICV1CgAAAAAAAAAAAAAAAABsZSBjb25maWd1 -cmF0aW9uOiBoYXNoIG1vZGUgcmVxdWlyZXMgYXQgZW50cmllcyB0byBiZSBhIHBvd2VyIG9mIDIs -IG5oYXNoICV1CgAAAGxlIGNvbmZpZ3VyYXRpb246IHJlcXVlc3RlZCAldSB0Y2FtIGVudHJpZXMg -YnV0IG9ubHkgJXUgYXZhaWxhYmxlIChucm91dGUgJXUgbmNsaXAgJXUgbmZpbHRlciAldSBuc2Vy -dmVyICV1CgAAAABsZSBjb25maWd1cmF0aW9uOiB0Y2FtIHJlZ2lvbnMgbXVzdCBoYXZlIG11bHRp -cGxlIG9mIDMyIGVudHJpZXMsIG5yb3V0ZSAldSBuY2xpcCAldSBuZmlsdGVyICV1IG5zZXJ2ZXIg -JXUKAAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgY2x1c3RlciBlbnZpcm9ubWVu -dAoAAAAAAAAAAAAAAAAAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIExBTiBlbnZpcm9u -bWVudAoAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIFdBTiBlbnZpcm9ubWVudAoAAGh3 -X3RwX3RjcF90dW5pbmdzOiBtYW51YWwgdHVuaW5nCgAAAAAAAAAAAAAAAAAAAF9od19jaW1fZmxh -c2hfbWVtY3B5OiBtZW1jcHlYIHN0YXJ0CgAAAAAAAAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5 -OiBkc3QgMHglMDggb2Zmc2V0IDB4JTA4eCBzaXplICV1LCB3aWR0aCBvZiAldSBpcyBub3Qgc3Vw -cG9ydGVkCgAAAAAAAAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5OiBtZW1jcHlYIGVuZAoAAAAA -AAAAAAAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZW5jb3VudGVyZWQgZXJyb3IgQCBs -aW5lICV1OgoAAAAAAAAAAABmY29lIHhjaGcgbWdyIGluaXQ6IE51bWJlciBvZiBleGNoYW5nZXMg -Zm9yIEZDb0UgaXMgJXgKAAAAAAAAAAAAZmNvZV9sMnRfaW5pdDogTm8gdWxwdHggY3JlZGl0IGNo -OlsldV0KAAAAAAAAAAAAZmNvZV9sMnRfaW5pdDogY2g6WyV1XSBsMnRfaWR4IFsldV0KAAAAAAAA -AAAAAAAAbm8gbDJ0IGVudHJpZXMgY29uZmlndXJlZDsgZm9yY2luZyAldSBlbnRyaWVzLCBzdGFy -dGluZyBhdCAldQoAAGRjYnhfaWVlZV9jb25zdHJ1Y3RbJXVdIGV0cyAldSBwZmMgJXUgYXBwICV1 -CgAAAGRjYnhfdGltZW91dFsldV0KAAAAAAAAAAAAAAAAAAAAZGNieF9ydW5fdmVyc2lvbl9zbVsl -dV0gRENCWF9WRVJfU1RBVEVfUlVOX0lFRUUKAAAAAAAAAAAAAAAAAAAAAGRjYnhfcnVuX3ZlcnNp -b25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9DRUUKAGRjYnhfcnVuX3ZlcnNpb25fc21bJXVd -IERDQlhfVkVSX1NUQVRFX1JVTl9OT05FCgAAAAAAAAAAAAAAAAAAAABNQUMgZmFpbGVkIHRvIHJl -c3luYyB0eAoAAAAAAAAAAHBvcnRbJXVdIGxpbmsgdXAgKCV1KSAoc3BlZWQgJSN4IGFjYXBzICUj -eCBscGNhcHMgJSN4KQoAAAAAAAAAAABwb3J0X2hzc19zaWdkZXRbJXVdOiBoc3Nfc2lnZGV0IGNo -YW5nZWQgdG8gMHgleAoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gaW5pdGlhbGl6aW5nIEtSCgAA -AAAAAABfaHdfdHBfcGdtbmd0OiB0eF9wYWdlX21heCAldSByeF9wYWdlX21heCAldSBwc3RydWN0 -cyAldSBzaXplICV1CgAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fb3RoZXJzX3RvdGFsOiBtZW0g -JXUsIGRkcCAldSBkZHBfaXNjc2kgJXUgc3RhZyAldSBwYmwgJXUgcnEgJXUgcnF1ZHAgJXUgLT4g -JXUKAAAAAAAAAF9tcGFydGl0aW9uX2JhbmtzX21jWDogbmJhbmtzX3BtdHggJXUgKCV1TUIpIG5i -YW5rc19wbXJ4ICV1ICgldU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1CKSBuYmFua3NfZncgJXUg -KCV1TUIpCgBfbXBhcnRpdGlvbl9iYW5rc19tYzE6IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFu -a3Nfb3RoZXJzICV1ICgldU1CKSBuYmFua3NfZncgJXUgKCV1TUIpCgAAAAAAAABfbXBhcnRpdGlv -bl9iYW5rc19tYzA6IG5iYW5rc19wbXJ4ICV1ICgldU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1C -KQoAAAAAAAAAAAAAAG1lbV9tYWxsb2NfaW50ZXJuYWw6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBi -eXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAAAAAAAAAAAAAAAAAaHdfZWRjX2Jpc3RbJXVdOiBiaXN0 -X2NtZFsweCUwOHhdIGFkZHIgMHgleCBsZW4gMHgleAoAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1 -XTogZG9uZSwgZW5jb3VudGVyZWQgJXUgZXJyb3JzIG9uIGZpcnN0IGFuZCAldSBlcnJvcnMgb24g -c2Vjb25kIGF0dGVtcHQgKCV1Z2JwcykKAG1lbV9pbml0X2NhY2hlczogY2FjaGVfc2l6ZSAldSBm -bG93Y19idWZfdGNiX2NhY2hlX3NpemUgJXUgYnVmbGw2NF9jYWNoZV9zaXplICV1CgAAAAAAAAAA -AAAAAAAAAG1wYXJ0aXRpb25fcG10eDogbSAweCUwOHggc2l6ZSAldQoAAAAAAAAAAAAAAAAAAG1w -YXJ0aXRpb25fcG1yeDogbSAweCUwOHggc2l6ZSAldQoAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25f -ZWRjIChubyBleHRtZW0pOiBtIDB4JTA4eCBzaXplICV1CgAAAG1wYXJ0aXRpb25fZWRjX2VzdGlt -YXRlOiBodyBtb2R1bGVzIHJlcXVpcmUgJWQgYnl0ZXMgaW4gRURDCgAAAABUZW1wZXJhdHVyZS9W -b2x0YWdlIFNlbnNvcjogQ29yZSBjbG9jayAldSA+ICV1OyBjYXBwaW5nIHRvIHN0YXkgaW4gY29t -cGxpYW5jZSB3aXRoIGhhcmR3YXJlLgoAAABzZXR0aW5nIHVwIHJpbmcgYmFja2JvbmUKAAAAAAAA -AHJpbmcgYmFja2JvbmUgY29uZmlnIGVycm9yLCBUQ0FNIG5vdCBlbXB0eS4gYXZhaWxhYmxlICVk -LCBzaXplICVkCgAAAAAAAAAAAAAAAAAAZm9pc2NzaV9jb3JlX2J5ZTogYWN0aXZlIHNlc3NfY250 -ICVkCgAAAAAAAAAAAAAAaHdfbWFjX2FlY19jb21wbGV0ZVsldV0gb24gbGFuZXMgJSN4IChzaWdk -ZXQgJSN4KSwgdHhfbGFuZXMgJSN4CgAAAAAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHN0YXRl -IFNUQVJUIChzaWdkZXQgJSN4KQoAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHRyYW5zaXRpb25pbmcg -dG8gVFJBSU5JTkcKAAAAAAAAAABhZWNfZnNtWyV1XSA6IFRSQUlOSU5HX0NPTVBMRVRFCgAAAAAA -AAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IExvY2FsIGZhdWx0IHdoaWxlIHdhaXRpbmcgZm9yIGxp -bmsgc3RhdHVzIDB4JXggOiAweCV4CgAAAAAAAAAAAAAAAGFlY19mc21bJXVdIDogUmVtb3RlIGZh -dWx0IHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4JXgKAABhZWNfZnNtWyV1XSA6IFJl -bW90ZSBmYXVsdCBjbGVhcmVkIHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4JXgKAAAA -AAAAAAAAAGFlY19mc21bJXVdIDogRE9ORQoAAAAAAAAAAAAAAAAAYWVjX2ZzbVsldV0gdGltZWQg -b3V0IHRyYWluaW5nIEZTTV9TVEFURV8wIDB4JXgsIF8xIDB4JXggXzIgMHgleCBfMyAweCV4LCBM -aW5rIFN0YXR1cyAweCV4CgAAAAAAYmVhbl9mc21bJXVdIDogc3RhdGUgU1RBUlQgKGNvdW50ID0g -JXUpCgAAAAAAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9TSUdERVQKAAAA -AAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgQkFTRVBfSEFORExFCgAAAAAAYmVhbl9m -c21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9DT01QTEVURQoAAAAAYmVhbl9mc21bJXVdIDog -REwgNDBHIE5lZ290aWF0aW9uIEVycm9yIC0gQXR0ZW1wdGluZyB0byBjb250aW51ZQoAAAAAAAAA -AAAAAAAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBET05FCgAAAAAAAGJlYW5fZnNtWyV1XSA6IHN0 -YXRlIFJFU1RBUlQxCgAAYmVhbl9mc21bJXVdIDogc3RhdGUgUkVTVEFSVDIKAABiZWFuX2ZzbVsl -dV0gOiBzdGF0ZSBSRVNUQVJUMwoAAGJlYW5fZnNtWyV1XSBUSU1FT1VUOyBzdGF0ZSAldSBldGhf -c3RhdHVzICUjeCBiZWFuX3N0YXR1cyAlI3ggaHNzIHNpZ2RldCAlI3ggcmV0cnlfY250ICV1CgAA -AAAAAGh3X21hY19saW5rX3N0YXR1c1sldV0gaW50X2NhdXNlIDB4JXgsIGxpbmtfc3RhdHVzIDB4 -JXgKAAAAAAAAAABwb3J0ICV1IGNoYW5naW5nIHNwZWVkIHRvIDFHCgAAAHBvcnQgJXUgbmVnb3Rp -YXRlZCB1bnN1cHBvcnRlZCBzcGVlZCAlI3gKAAAAAAAAAGJlYW4vYWVjIGNvbXBsZXRlIChyZXRy -eTogJXUpCgAAcG9ydFsldV0gcmVzZXR0aW5nIEtSCgAAAAAAAAAAAABwb3J0ICV1IG5lZ290aWF0 -ZWQgdW5zdXBwb3J0ZWQgc3BlZWQgJSN4CgAAAAAAAABiZWFuL2FlYyBjb21wbGV0ZSAocmV0cnk6 -ICV1KQoAAFJhbmdlIGNhbGM6IEF2ZXJhZ2VkICUjeCBidXQgaWdub3JlZCB2YWx1ZSAlI3ggKGl0 -ZXJhdGlvbiAldSkKAABNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBnb2luZyB0 -byAwCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBjb21wbGV0aW5nCgBNQyBj -YWxpYnJhdGlvbiBmYWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21wbGV0ZS4KAAAAAAAAAAAA -AAAATUMgY29tbWFuZCBmYWlsZWQgdG8gY29tcGxldGUob3Bjb2RlICUjeCBjYWRkciAlI3ggYmFk -ZHIgJSN4IGRlbGF5ICVkKQoAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvbXBsZXRlIGltbWVkaWF0 -ZQoAAAAAAAAAAAAAAAAAAABwZm5fYml0bWFwIDB4JXgKAAAAAAAAAAAAAAAAAAAAAGJhZCBtYWls -Ym94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4ID4gTEFTVEMyRSAweCV4CgBt -YWlsYm94IGNtZCBub3QgeWV0IHN1cHBvcnRlZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAw -eCV4CgAAYmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXggaXMg -dmFsaWQgcG9zdCBkZXZpY2UgaW5pdCBvbmx5CgBiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZm -biAweCV4OyBvcGNvZGUgMHglMDJ4IHJhbWFzayAweCV4IGNtZCByYW1hc2sgMHgleAoAAGJhZCBt -YWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCUwMnggbGVuMTYgMHgleCB2 -ZXJzdXMgZXhwZWN0ZWQgbGVuMTYgMHgleAoAAAAAAAAAAGluc3VmZmljaWVudCBjYXBzIHRvIHBy -b2Nlc3MgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2NhcHMgMHgleCB3eF9jYXBz -IDB4JXggcmVxdWlyZWQgcl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAAAAAAAAAAaW5zdWZmaWNp -ZW50IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IHJfY2Fw -cyAweCV4IHd4X2NhcHMgMHgleCByZXF1aXJlZCByX2NhcHMgMHgleCB3X2NhcHMgMHgleAoAAAAA -AAAAAABkb3dubG9hZF9zcmFtOiBlcnJvciwgcmV0ICVkCgAAAGRvd25sb2FkX3RjYW06IGVycm9y -LCByZXQgJWQKAAAAaHdfcG93ZXJfcHJlcDogVkREPU5PTkUgYnV0IFZDUz0lZAoAAAAAAAAAAAAA -AAAAaHdfcG93ZXJfcHJlcDogdW5zdXBwb3J0ZWQgZXh0ZXJuYWwgYWRqdXN0YWJsZSBwb3dlciBy -ZWd1bGF0b3JzIFZERD0lZCwgVkNTPSVkCgBod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWREQ9 -JWQKAAAAAAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWQ1M9JWQKAAAAAAAA -AAAAAAAAAABod19wb3dlcl9wcmVwOiBpMmMgd3JpdGUgZXJyb3IsIFZERD0lZCxyZXQ9JWQKAABo -d19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWREQ9JWQKAAAAAAAAAAAAAAAAAABod19wb3dlcl9w -cmVwOiBpMmMgd3JpdGUgZXJyb3IsIFZDUz0lZCxyZXQ9JWQKAABod19wb3dlcl9wcmVwOiB1bnN1 -cHBvcnRlZCBWQ1M9JWQKAAAAAAAAAAAAAAAAAABWUEQgcmVnaW9uIGlzIHRvbyBzbWFsbCAoU0VS -Q0ZHX1NSX1BGTlZQRFNJWkUgMHgleCkKAAAAAAAAAAAAAAAAY2ZfcHJlcDogZXJyb3IsIHJldCAl -ZAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAggAAASAAAAAAAAAAggAAAQAA -AAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoCAAAAAAAAAAAAAAAAAgAAA -AAAAAAAABwAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAACAEAMA -AAAAAAAIAAAAAAIAAAAAAAAAAAAgAAAAAAAAAAAAAAABAAOAAAAAAAAAAAAAAAIAAAAAAAAAAAAg -A4AAAAAAAAAAAAAQAoAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAA -AAAgAAAAAAAAAAAAAACAAAKAAAAAAAAAAAAAAAKAAAAAAAAAAACAAAIAAAAAAAAAAAAAAAIAAAAA -AAAAAAAAAAKAAAAAAAAAAAABAAMAAAAAAAAAAAAAAoMAAAAAAAAAAAAQAoAAAAAAAAAAAAAwAAMA -AAAAAAAIAAAwAAMAAAAAAAAAAAAwBYMAAAAAAAAIAAAwBYMAAAAAAAAAAAAwBIMAAAAAAAAIAAAw -BIMAAAAAAAAAAAAwAwMAAAAAAAAIAAAwAwMAAAAAAAAAAAA4AwMAAAAAAAAAAAA4BYMAAAAAAAAA -AAA4BIMAAAAAAAAAAAA4AAMAAAAAAAAAAAA0BoIAAAAAAAAAAAA8A4IAAAAAAAAAAAA8AAMAAAAA -AAAIAAA8AAMAAAAAAAAAAAA8BIMAAAAAAAAAAAA8BQMAAAAAAAAAAAA9BAMAAAAAAAAAAAA8A4MA -AAAAAAAAAAAsAAIAAAAAAAAAAAAsBYIAAAAAAAAAAAAsBQIAAAAAAAAAAAAQBoAAAAAAAAAAAAAQ -BoKAAAAAAAAAAAAADoIAAAAAAAAAAAAQB4KAAAAAIAAAAAAAB4IAAAAAIAAAAAAQBwKAAAAAAAAA -AAAQBwKAAAAAAAAAAAAQBwKAAAAAAAAAAAAABwIAAAAAIAAAAAAQF4MAAAAAAAAIAAAQF4MAAAAA -AAAIAAAQAAAAAAAAAAAAAAAQBgOAAAAAAAAAAAAADgMAAAAAAAAAAAAQBgNAAAAAAAAAAAAQBgMA -AAAAAAAAAAAQBgAAAAAAAAAAAAAABgOAAAAAAAAAAAAABgMAAAAAAAAAAAAADgIAAAAAAAAAAAAA -DgIAAAAAAAAAAAAQBgIAAAAAAAAAAAAQBgIAAAAAAAAAAAAQBgKAAAAAAAAAAAAQBgKAAAAAAAAA -AAAAAAIAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAEAMAAAAA -AAAIAAAAAAAAAAAAAAAAAAD///////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////8AAAAgAAAAAMAAAAAAAAAgAAAAAOAAAAAA -AAAAAgAAAAAAAABAAAAAAAAAAAAAAAAAAAEhAAAAAAAAAAAAAQEgAAAAAAAAAAAAAAIAAAAEAAQA -AAAAAIFAAAAAAAAAAAAABoAAAAQAAAAAAAAAgABAAAAAAAACAAAAgAAgAAAAAAACAAAIgAAAAAAA -QAAAAAIBAEAAAAAAAAAAAAABAEIAAAAAAAAAAAAAACAAAAAAAAAAAAACECAAAAAAAAAAAAACDAIA -AAAAAAAAAAAAhQIAAAAEAAAAAAAAgEIAAAAAAAAAAACAgEIAQAAAAAAAAACAgEIAAAAAAAAAAAAC -ACIAAAAAAAAAAAAAgEEAAAAAAAAAAACAgEEAAAAAAAAAAAAAgEGAAAAAAAAAAACAgEGAAAAAAAAA -AAACACEAAAAAAAAAAAAAECCAAAAAAAAAAAACJQCAAAAAAAAAAAAABQAAAAAAAAAAAAAIiASAAAAA -AAAAAAAIiASAAAAAAAAAAAAIogCAAAAAAAAAAAAIogCAAAAAAAAAAAAIowCAAAAAAAAAAAAIowCA -AAAAAAAAAAAIpICAAAAAAAAAAAAIpICAAAAAAAAAAAAEpIDAAAAAAAAAAAAEogDAAAAAAAAAAAAE -owDAAAAAAAAAAAAEiATAAAAAAAAAAAAACQGAAAAAAAAAAAACDACAAAAAAAAAAAAAiATAAAAAAAAA -AAAAiASAAAAAAAAAAAACCwCAAAAAAAAAAAAAioCAAAAAAAAAAAAAC4CAAAAAAAAAAAAAjACAAAAA -AAAAAAACIBCAAAAAAAAAAAACCgCAAAAAAAAAAAACCoCAAAAAAAAAAAAACQKAAAAAAAAAAAAAAQEA -AAAAAAAAAAAAAQCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAIEQAAAAAAAAAAAA -AIEIAAAAAAAAAAAAAIEEAAAAAAAAAAAAAIGAAAAAAAAAAAAAgADAAAAAAAAAAAAAgACgAAAAAAAA -AAAAAAgAAAAAAAAAAAAAgYAAAAAAAAAAAAAAgYCAAAAAAAAAAAAAiYCAAAAAAAAAAAAAiYDAAAAA -AAAAAAAAAYIAAAAAAAAAAAACAYAAAAAAAAAAAAACAYCAAAAAAAAAAAAAQYGAAAAAAAAAAAACAYGA -AAAAAAAAAAAASYGAAAAAAAAAAAACCYGAAAAAAAAAAAACAYEAAAAAAAAAAAAAQYEAAAAAAAAAAAAg -AAAAAAAAAAAAAAAQAAACAQAAAAAAAAAQAAACAAAAAAAAAAAQAAAAAAAAAAAAAAAAgADAAAAAAAAA -AAAAAAAAAAAAAAAAAAD///////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAkgAA -AAAAAAADZgAgAEAAAAAACACSAAAAAAAAAANyASUEQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAgA -AAACAIgDhwAAVgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAA -AAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABA -AAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAIAAAAAgCIA4UAAJYB -IABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAA -A5YAIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAA -AAIAA5YAJgRAAAAAAAhHIAEEAAACsAAC0gVAJEQAAAAACEcgAQQAAAKyAALSBUYkQAAAAAAIAAAA -AgCIA4cAAJYBJgRAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAEcgAQYMoYKyQAGSBEAkRAAAAAAI -AAAAAgCIA4cAAJYBJgRAAAAAAABHIAEEDKBCsYACEgVAJEQAAAAACAAAAAIAiAOHAACWASYEQAAA -AAAIAAAAAgCIA4UAAJYBIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAACAAAAAIAiAOFAACWASAA -QAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAA3FEroCsIDTFFSL4kpGJEAAAAAABcUSugK3gNMUVIti -SaYkQAAAAAAFxRKiBrCA0xRUi+JKRiRAAAAAAA3FEqIGt4DTFFSLYkmmJEAAAAAABcUSogawgNMU -VIviSkYkQAAAAAANxRKiBreA0xRUi2JJpiRAAAAAAAXFEqIGsIDTFFSL4kpGJEAAAAAADcUSoga3 -gNMUVItiSaYkQAAAAAAJxBCgAgCAkAAAi2JpxiRAAAAAAAHEEKAGsICTBlSLYmnGJEAAAAAAAcQQ -oAawgJMGVItiacYkQAAAAAABxRC4BrCAkxZUi2JIxiRAAAAAAAihEIgCAIFYEgALUgCmJEAAAAAA -CcAQkAKwgAMWVIqSAcYkQAAAAAAJwBC4BrCAAxCUi+ICRiRAAAAAAAnAELgCtIADEJSLYgGmJEAA -AAAACcAQuAK0gAMQlItiAaYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAAAAnAELgCtIADEJSLYgGm -JEAAAAAAAaAQkAa0gAMQlItiAaYkQAAAAAABwBCAArCAAxRUilIAxiRAAAAAAAHAEIACsIADFFSK -UgDGJEAAAAAAAcAQgAKwgAMUVIpSAMYkQAAAAAAIRyABBAAAArAAAtIEQCRAAAAAAACBAAACAIVY -B0ALUgCmJEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAAAAAABgChgABAAVYAIABAAAAAAAAAAAAE -AKBAAYAB1gAgAEAAAAAACIEAAAIAhVmABAtSAKYkQAAAAAAKAUAAAAAAGAIAA0IBJqRCAAAAAAAA -AAAAAAAAAAADlgAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIAAAAAgCIA4UAA9YAIABAAAAA -AAgAAAACAIgDhQAD1gAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABA -AAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAACcAQuAK0gAMQlItiAaYkQAAAAAAAAAAAAAAAAAIAA5YA -JgRAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAACAAAAAIAiAOFAACWASAAQAAAAAAAAAAABACgQAGA -AdYAIABAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAQAoEABgAHWACAAQAAAAAAIoRCIAgCB -WBAACRIBpiRAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAYAoYAAQAFWACAAQAAAAAAIAAAA -AgCIA4dACNICRiRCAAAAAAnFEqIClIjSEoCLIknGJEAAAAAAAcAQgAakiAEFVItSAMYkQAAAAAAJ -wBCAAqSIAIVUi1IAxiRAAAAAAAnAEIAGtIgDARSLUgGmJEAAAAAADcAAAAKwgMMWVIviA0YkQAAA -AAAAAAAAAAAAAAAAA5YAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIADAABAAAAAIA -AAIAJiRAAAAAAABHMAAGAyACtwAIAgHAJEAAAAAACAMAAAIGoAq3AAgCAcYkRgAAAAAAAAAAAAAA -AAIAAAIAJiRAAAAAAAAgUAAEAAAAAAAAAgEmJEYAAAAACGAgAIQAAAAAAAAGACAAQAAAAAAIYCAA -hAAAAAIBMAIAJiVAAAAAAAhgAAAEAIQBggQEAgHGJMIAAAAAAcAAAAJDgAMCDIgCAaYkQAAAAAAI -AGAABAAAAAIAAAIAJiRAAAAAAAgAYAAEAAAAAAAABAEgAEAAAAAAAAAAAAAAAAAAAAAEASAAQAAA -AAAECBSABgoAAAcBTAIgpiZAAAAAAAiAAAAGAIQBgAQIAgGmJMAAAAAAAEAAAAIAoAAAQAgCAKYk -RgAAAAAAAAAAAAAAAAIAAAIAJiRAAAAAAAQAAAAChAADAooIAgTAJEAAAAAAAAAAAAAAAAACAAAG -ASBIQAAAAAAAIFAABAAAAAIAAAIAJiRAAAAAAAhgIACEAAAAAgAABgAmBEAAAAAACGAgAIQAAAAC -AAACASYlQAAAAAAIYAAABACEAYAEBAIBxiTAAAAAAAgAYAAEAAAAAAAABAEgAEAAAAAAAACAACAA -AAAAAAACACZMcAAAAAAAAIAAIAAAAAAAAAYBIAAAAAAAAAAAgAAgAAAAAAAAAgAmTHAAAAAAAACA -ACAAAAAAAAAGASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAACcAAAAi0jAQJFgQCBMYkQAAAAAAJwAAADDSABAkWBAIExiRAAAAAAAQIdIBMCQAAUABcAmHm -JEAAAAAADAh0gEQAAABSAEACYSYkQAAAAAAIAhCgBAAAAAABAAIAJiRAAAAAAAgCEKAEAAAAAAEA -AgAmJEAAAAAABAh0AEIBAAAHAIgCYMYkQAAAAAANyBQAAgkAAARAnAJg5iRAAAAAAAnIEIACtIAE -ApSIAmXGJEAAAAAADch0AEy0gAMAlIgCYKYkwAAAAAAFyHQASDSQAwCUiAJgpiTAAAAAAAhHAAAE -AAAAAAAAAgEgJEAAAAAACEcAAAQAAAAAAAACBEAkQAAAAAAARyABDAchwrcACAIAwCREAAAAAABH -IAEMByHCtwAIAgDAJEQAAAAAAEcgAQwHIcK3AAgCAMAkRAAAAAAAACABCACEAAVAiAIBxiTAAAAA -AAAAIAEIAIQABUCIAgHGJMAAAAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAAACABhoIAAQLAiAIDxiTA -AAAAAAAAIAGCggAAAsCIAgPGJMAAAAAACcAgAYKkgAEFQIgCAcYkwAAAAAAIAAAADACEAAVAiAIB -xiTAAAAAAAAAIAGGggABAsCIAgPGJMAAAAAAAAAgAYKCAAAAwIgCAqYkwAAAAAAJwCABgqSAAQVA -iAIBxiTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAQABBAkAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAABbZ2xvYmFsXQpyc3NfZ2xiX2NvbmZpZ19tb2RlPWJhc2ljdmly -dHVhbApyc3NfZ2xiX2NvbmZpZ19vcHRpb25zPXRubG1hcGVuLGhhc2h0b2VwbGl0eix0bmxhbGxs -a3AKcGxfdGltZW91dF92YWx1ZT0xMDAwMApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVn -WzB4MTAwY109MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQw -OTYKcmVnWzB4MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJl -Z1sweDEwNTRdPTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2 -MF09ODE5MgpyZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weDAwMjgwMDAwLzB4M2ZmYzAw -MDAKcmVnWzB4MTExOF09MHgwMDAwMjgwMC8weDAwMDAzYzAwCnJlZ1sweDEwYThdPTB4NDAyMDAw -LzB4NDAyMDAwCmJhcjJ0aHJvdHRsZWNvdW50PTUwMApzZ2VfdGltZXJfdmFsdWU9NSwxMCwyMCw1 -MCwxMDAsMjAwCnJlZ1sweDExMjRdPTB4MDAwMDA0MDAvMHgwMDAwMDQwMApyZWdbMHgxMTMwXT0w -eDAwZDVmZmViCnJlZ1sweDExM2NdPTB4MDAwMmZmYzAKcmVnWzB4N2QwNF09MHgwMDAxMDAwMC8w -eDAwMDEwMDAwCnJlZ1sweDdkNmNdPTB4MDAwMDAwMDAvMHgwMDAwNzAwMApyZWdbMHg3ZDc4XT0w -eDAwMDAwNDAwLzB4MDAwMDAwMDAKcmVnWzB4N2RjMF09MHgwZTJmODg0OQpmaWx0ZXJNb2RlPWZj -b2VtYXNrLHNydnJzcmFtLGZyYWdtZW50YXRpb24sbXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBv -cnQsZmNvZQpmaWx0ZXJNYXNrPXByb3RvY29sLGZjb2UKdHBfcG1yeD0zMAp0cF9wbXJ4X3BhZ2Vz -aXplPTY0Swp0cF9ucnhjaD0wCnRwX3BtdHg9NTAKdHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4 -Y2g9MAp0cF9tdHVzPTg4LDI1Niw1MTIsNTc2LDgwOCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIs -MjA0OCw0MDk2LDQzNTIsODE5Miw5MDAwLDk2MDAKcmVnWzB4N2QwOF09MHgwMDAwMDgwMC8weDAw -MDAwODAwCnJlZ1sweDdkNDhdPTB4MDAwMDAwMDAvMHgwMDAwMDQwMApyZWdbMHg3ZDYwXT0weDA2 -MDAwMDAwLzB4MDcwMDAwMDAKcmVnWzB4MTkxNjhdPTB4MDQwMjAxMDAKcmVnWzB4MTljMDRdPTB4 -MDA0MDAwMDAvMHgwMDQwMDAwMAptY19tb2RlX2JyY1swXT0xCm1jX21vZGVfYnJjWzFdPTEKcmVn -WzB4OGRjMF09MHgwMDAwMDAwNC8weDAwMDAwMDA0CltmdW5jdGlvbiIwIl0KbnZmPTE2Cnd4X2Nh -cHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0xNgpuZXhh -Y3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMSJdCm52Zj0xNgp3eF9jYXBzPWFs -bApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04 -CmNtYXNrPWFsbApwbWFzaz0weDIKW2Z1bmN0aW9uIjIiXQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9j -YXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApjbWFz -az1hbGwKcG1hc2s9MHg0CltmdW5jdGlvbiIzIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fwcz1h -bGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9YWxs -CnBtYXNrPTB4OApbZnVuY3Rpb24iNCJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTI4Cm5p -cWZsaW50PTE3MApuZXRoY3RybD0xMDAKbmVxPTI1NgpucXBjcT0xMjI4OApuZXhhY3RmPTQwCmNt -YXNrPWFsbApwbWFzaz1hbGwKbmV0aG9mbGQ9MTAyNApucm91dGU9MzIKbmNsaXA9MzIKbmZpbHRl -cj00OTYKbnNlcnZlcj00OTYKbmhhc2g9MTIyODgKcHJvdG9jb2w9bmljX3ZtLG9mbGQscmRkcCxy -ZG1hYyxpc2NzaV9pbml0aWF0b3JfcGR1LGlzY3NpX3RhcmdldF9wZHUsaXNjc2lfdDEwZGlmCnRw -X2wydD0zMDcyCnRwX2RkcD0yCnRwX2RkcF9pc2NzaT0yCnRwX3N0YWc9Mgp0cF9wYmw9NQp0cF9y -cT03CltmdW5jdGlvbiI1Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9NApuaXFmbGludD0z -NApuZXRoY3RybD0zMgpuZXE9NjQKbmV4YWN0Zj0xNgpjbWFzaz1hbGwKcG1hc2s9YWxsCm5zZXJ2 -ZXI9MTYKbmhhc2g9MjA0OAp0cF9sMnQ9MTAyMApwcm90b2NvbD1pc2NzaV9pbml0aWF0b3JfZm9m -bGQKdHBfZGRwX2lzY3NpPTIKaXNjc2lfbnRhc2s9MjA0OAppc2NzaV9uc2Vzcz0yMDQ4CmlzY3Np -X25jb25uX3Blcl9zZXNzaW9uPTEKaXNjc2lfbmluaXRpYXRvcl9pbnN0YW5jZT02NApbZnVuY3Rp -b24iNiJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxpbnQ9MzQKbmV0aGN0cmw9 -MzIKbmVxPTY2Cm5leGFjdGY9MzIKY21hc2s9YWxsCnBtYXNrPWFsbApuaGFzaD0yMDQ4CnRwX2wy -dD00CnByb3RvY29sPWZjb2VfaW5pdGlhdG9yCnRwX2RkcD0yCmZjb2VfbmZjZj0xNgpmY29lX252 -bnA9MzIKZmNvZV9uc3NuPTEwMjQKW2Z1bmN0aW9uIjEwMjMiXQp3eF9jYXBzPWFsbApyX2NhcHM9 -YWxsCm52aT00CmNtYXNrPWFsbApwbWFzaz1hbGwKbmV4YWN0Zj04Cm5maWx0ZXI9MTYKW2Z1bmN0 -aW9uIjAvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhj -dHJsPTQKbmVxPTgKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEvKiJd -Cnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhjdHJsPTQKbmVx -PTgKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDIKW2Z1bmN0aW9uIjIvKiJdCnd4X2NhcHM9 -MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhjdHJsPTQKbmVxPTgKbmV4YWN0 -Zj00CmNtYXNrPWFsbApwbWFzaz0weDQKW2Z1bmN0aW9uIjMvKiJdCnd4X2NhcHM9MHg4MgpyX2Nh -cHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhjdHJsPTQKbmVxPTgKbmV4YWN0Zj00CmNtYXNr -PWFsbApwbWFzaz0weDgKW3BvcnQiMCJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09 -MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwz -CmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNv -Y2tldG51bSw1Cltwb3J0IjEiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3 -bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2Jf -YXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRu -dW0sNQpbcG9ydCIyIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAK -bHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90 -bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUK -W3BvcnQiMyJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0x -NQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFd -PTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1CltmaW5p -XQp2ZXJzaW9uPTB4MTQyNTAwMWMKY2hlY2tzdW09MHgzNjIyOGM3YgoAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAABbZ2xvYmFsXQpyc3NfZ2xiX2NvbmZpZ19tb2RlPWJhc2ljdmlydHVhbApyc3Nf -Z2xiX2NvbmZpZ19vcHRpb25zPXRubG1hcGVuLGhhc2h0b2VwbGl0eix0bmxhbGxsa3AKcGxfdGlt -ZW91dF92YWx1ZT0xMDAwMApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVnWzB4MTAwY109 -MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQwOTYKcmVnWzB4 -MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJlZ1sweDEwNTRd -PTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2MF09ODE5Mgpy -ZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEwMDBhMDAwLzB4ZjAwMGYwMDAKcmVnWzB4 -MTBhOF09MHg0MDIwMDAvMHg0MDIwMDAKYmFyMnRocm90dGxlY291bnQ9NTAwCnNnZV90aW1lcl92 -YWx1ZT01LDEwLDIwLDUwLDEwMCwyMDAKcmVnWzB4MTEyNF09MHgwMDAwMDQwMC8weDAwMDAwNDAw -CnJlZ1sweDExMzBdPTB4MDBkNWZmZWIKcmVnWzB4MTEzY109MHgwMDAyZmZjMApyZWdbMHg3ZDA0 -XT0weDAwMDEwMDAwLzB4MDAwMTAwMDAKcmVnWzB4N2Q2Y109MHgwMDAwMDAwMC8weDAwMDA3MDAw -CnJlZ1sweDdkYzBdPTB4MGUyZjg4NDkKZmlsdGVyTW9kZT1mY29lbWFzayxzcnZyc3JhbSxmcmFn -bWVudGF0aW9uLG1wc2hpdHR5cGUscHJvdG9jb2wsdmxhbixwb3J0LGZjb2UKZmlsdGVyTWFzaz1w -cm90b2NvbCxmY29lCnRwX3Btcng9MzAKdHBfcG1yeF9wYWdlc2l6ZT02NEsKdHBfbnJ4Y2g9MAp0 -cF9wbXR4PTUwCnRwX3BtdHhfcGFnZXNpemU9NjRLCnRwX250eGNoPTAKdHBfbXR1cz04OCwyNTYs -NTEyLDU3Niw4MDgsMTAyNCwxMjgwLDE0ODgsMTUwMCwyMDAyLDIwNDgsNDA5Niw0MzUyLDgxOTIs -OTAwMCw5NjAwCnJlZ1sweDdkMDhdPTB4MDAwMDA4MDAvMHgwMDAwMDgwMApyZWdbMHg3ZDQ4XT0w -eDAwMDAwMDAwLzB4MDAwMDA0MDAKcmVnWzB4N2Q2MF09MHgwNjAwMDAwMC8weDA3MDAwMDAwCnJl -Z1sweDE5MTY4XT0weDA0MDIwMTAwCnJlZ1sweDE5YzA0XT0weDAwNDAwMDAwLzB4MDA0MDAwMDAK -bWNfbW9kZV9icmNbMF09MQptY19tb2RlX2JyY1sxXT0xCltmdW5jdGlvbiIwIl0Kd3hfY2Fwcz1h -bGwKcl9jYXBzPWFsbApudmk9MjgKbmlxZmxpbnQ9MTcwCm5ldGhjdHJsPTk2Cm5lcT0yNTIKbnFw -Y3E9MjA0OApuZXhhY3RmPTQwCmNtYXNrPWFsbApwbWFzaz1hbGwKbmV0aG9mbGQ9MTAyNApucm91 -dGU9MzIKbmNsaXA9MzIKbmZpbHRlcj00OApuc2VydmVyPTMyCm5oYXNoPTIwNDgKcHJvdG9jb2w9 -bmljX3ZtLG9mbGQscmRkcCxyZG1hYyxpc2NzaV9pbml0aWF0b3JfcGR1LGlzY3NpX3RhcmdldF9w -ZHUsaXNjc2lfdDEwZGlmCnRwX2wydD00MDkyCnRwX2RkcD0yCnRwX2RkcF9pc2NzaT0yCnRwX3N0 -YWc9Mgp0cF9wYmw9NQp0cF9ycT03CltmdW5jdGlvbiIxIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFs -bApudmk9NApuaXFmbGludD0zNApuZXRoY3RybD0zMgpuZXE9NjYKbmV4YWN0Zj0zMgpjbWFzaz1h -bGwKcG1hc2s9YWxsCm5oYXNoPTIwNDgKcHJvdG9jb2w9ZmNvZV9pbml0aWF0b3IKdHBfbDJ0PTQK -dHBfZGRwPTIKZmNvZV9uZmNmPTE2CmZjb2VfbnZucD0zMgpmY29lX25zc249MTAyNApbZnVuY3Rp -b24iMTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNrPWFs -bApuZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fw -cz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9 -YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52 -aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNr -PTB4MgpbcG9ydCIwIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAK -bHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90 -bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUK -W3BvcnQiMSJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0x -NQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFd -PTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0 -IjIiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdt -PTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5 -MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIzIl0K -ZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApk -Y2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0 -aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNpb249 -MHgxNDI1MDAxZApjaGVja3N1bT0weDdkYzRkY2QKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAA= -==== diff --git a/sys/dev/cxgbe/firmware/t5fw-1.16.63.0.bin.uu b/sys/dev/cxgbe/firmware/t5fw-1.16.63.0.bin.uu new file mode 100644 index 000000000000..c84bd017eded --- /dev/null +++ b/sys/dev/cxgbe/firmware/t5fw-1.16.63.0.bin.uu @@ -0,0 +1,11265 @@ +/*- + * Copyright (c) 2017 Chelsio Communications, Inc. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + */ +begin-base64 644 t5fw +AAEE4wEQPwAAAQQJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAABMQE0wTcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IEZyaSBTZXAgIDggMTA6 +NDE6NDEgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j +dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDV4eCAwMS4xMC4zZi4wMAAAAAAAAAAAAAAAABU64zpg +AMgAH/zhSOEAe/AAEAAA4QAwuHj///8f/OFAgAAAAeEAe3AAABAAH//+oCAAAADhAZwE4QUAAAAC +AEDhBQgAAAYAQAACAAwABgAM4QUABAAMgACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA +AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//j+AAAAAA +H/+P5AAAAAAf/4/oAAAAAB//j+wf/8AAAAAAAAAAAADAABH/zSIKh5IQghAS/8wT/8yTIBL/zBP/ +zIQgBDMBkyAR/8oS/8uSEBH/yhL/y5IQEf/KAfQxAOQxAAUxAQIAEv/IAucxAhYAEf/GgRABAV/A +IQIRAckTEf/EEv/EkhAR/8QS/8SSEGAAEQAAEf++Ev/CkhAR/74S/8GSEIEQEf/AwCCSERL/v5IS +wCCSExL/vpIQghAC8lBlL/cR/7zHL5IQEf+7khAS/7sT/7uTIMAykyET/7qTIoIiEv+5E/+5kyAj +IiEU/7gEMwHJOBP/t4MwA4MUCDMRFP+1pDOTIRP/qZMiYAAIwjCTIRP/ppMiEv+wkCCQIZAikCOQ +JJAlkCaQJ5AokCmQKpArkCyQLZAukC8gJhAgJhGCIhL/o8AwLTcwLTc0LTc4LTc8Iz0BcjPtAAIA +Ev+gIwoALzcALzcQLzcgLzcwIz0BcjPtAAIAEv+VwDAoNzAoNzQoNzgoNzwjPQFyM+0S/5TAMCc3 +ACc3ECc3ICc3MCM9AXIz7RL/jxX/jxb/j8Aw1yAFZgFgABQAAAQ2BQACANMP0w8FMwxuOxQHRxQH +BEN2MeYENgUFMwxvO+0AAgAS/4MV/4EjCgACJwIHBEMEPgUFMwwHRxRvO/ADAgAS/33JLoMghCGF +IrwidDsOhlC0VZYwtDN0M/Rj/+YAZT/iZV/fEv9xwDIDLgUDAgAS/2jAMCg3QCg3RCg3SCg3TCM9 +AXIz7QACABL/ay0nAMARAUkxAEgxAQIAwAAU/2gE0jEV/2eUUBT/ZwTTMRX/ZpRQFP9mBNQxFf9m +lFAU/2UE1TEV/2WUUBD/ZQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA +H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/4AAH/+FsOMACfgf/4WwH/+FsOMAD6gf +/4WwH/+FsOMAD6gf/4WwH/+HnOMAD6gf/4ecH/+P1OMAEZQf/4/gH/+xcOMAGdgf/7FwH/+xcOMA +O2gf/8AAH///jeMAO2ggAAAAIAABauMAevggAAF4IAABfOMAfGQgAAF8IAABheMAfGggAAGYIAAB +nOMAfHQgAAGcIAABpeMAfHggAAG4IAABvOMAfIQgAAG8IAABxeMAfIggAAHYIAAB2OMAfJQgAAHc +IAAB4uMAfJQgAAH4IAAB+OMAfJwgAAH8IAAB/OMAfJwgAAIYIAACGOMAfJwgAAIcIAACHOMAfJwg +AAI4IAACOOMAfJwgAAI8IAACPOMAfJwgAAJYIAACWOMAfJwgAAJcIAACYuMAfJwgAAJ4IAACeOMA +fKQgAAJ8IAACguMAfKQgAAKYIAJtCuMAfKwgAwAAIAMbLOMC5yAgAxssIAMbLOMDAkwgAxswIAex +nOMDAlAgB7GgIAe1YOMHmMAgCAAAIAgbAOMHnIAgCBsAIAlUuuMHt4AgCVTAIAlWQOMI8UAgCwAA +IAsAAOMI8sAgCwAAIAsAAOMI8sAgCwAAIAuUuOMI8sAAAAAAAAAAAAAAAAAgAHHmIABx2CAAdcIg +AHHYIAB1PSAAcdggAHKKIAB01SAAdFogAHHYIAB0CSAAc8IgAHNVIABxxSAAcv8gAHHYIABx2CAA +cdggAHKqAAAAAP///////w/8///w////APwgAR8mIAEgdSABIKYgASBtIAEgMyABICwgAR/6IAEf +8iABH+kgAR+fIAEgpCABH5cgAR9uIAEgpiABH2cgAR9XARAYAQAEAAAAAAAAAAAAAAACAgUFCAgL +Cw4OEREUFBcXGhodHSAgIyMmJikpLCwvLzIyNTU4ODs7AAAAAAAAAAEDEREICBAJAwEAAAAAAAAg +BQgEIAIhBCAAsXAgAf50IAIdlCACGSggAegwIARv1B//wDAf/+rUIAEhWB//3awgAN1QIADPyAAA +AAAAAAAAIAIAGCAA+9AAAAAAAAAAAB//1Sgf/8doH//E/B//wxAgAMq0IADAQCAAvsAgARbgH//l +nCAHe2gAAAAAAAAAACAAwtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAIm+CACEJggASos +IAEpUB//8SAf/9AYH//MwCAA+aAgBZnIIAGXcCABfswgAWFoIAFWYCABSLAgAT7gIAEsSCAFCmgg +AytoIAGLyCADWFggAk5UIADdDAAAAAAgASqMIAYODCABHpAgAgccIAAReCABEjAgAAyoIAOk9B// +9FAgASpIIAMuAAAAAAAAAAAAIAPjkCAAkYQgA+HQIACNiAAAAAAgAJ7UIACcrCAAmoQAAAAAIACx +FCABj3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAKdYIAUHnCAAkYQAAAAA +IAPJiCADx0QgA8TQIAPKJAAAAAAAAAAAIACvaCAEA3QgAKhAAAAAAAAAAAAAAAAAIABjkCAAXpAg +AFgYIABgdAAAAAAgADloIAAukCAAsXAgAQ74IAHsZCAAzPgAAAAAAAAAAAAAAAAAAAAAIAUH/AsA +AAAgAxhsCAAAACADGHgIAAAAIAMYhAoAAAAgAxiQDAAAACADGJwSAAAAIAMYrA0AAAAgAxjADgAA +ACADGNATAAAAIAMY4AoAAAAgAxj0DgAAACADGQAYAAAAIAMZEA0AAAAgAxksDgAAACADGTwQAAAA +IAMZTBIAAAAgAxlgDgAAACADGXQQAAAAIAMZhBEAAAAgAxmYCgAAACADGawLAAAAIAMZuA0AAAAg +AxnEFAAAACADGdQKAAAAIAMZ7A8AAAAgAxn4BgAAACADGggGAAAAIAMaEAYAAAAgAxoYBgAAACAD +GiAGAAAAIAMaKAkAAAAgAxowBgAAACADGjwEAAAAIAMaRAYAAAAgAxpMCwAAACADGlQLAAAAIAMa +YAQAAAAgAxpEBAAAACADGmwJAAAAIAMadAkAAAAgAxqAAAAAAAAAAAANAAAAIAMajAoAAAAgAxqc +BgAAACADGqgCAAAAIAMasAMAAAAgAxNMAQAAACADGrQAAAAAAAAAANdqpHjox7dWJCBw28G9zu71 +fA+vR4fGKqgwRhP9RpUBaYCY2ItE96///1uxiVzXvmuQESL9mHGTpnlDjkm0CCH2HiViwECzQCZe +WlHptseq1i8QXQJEFFPYoeaB59P7yCHhzebDNwfW9NUNh0VaFO2p4+kF/O+j+GdvAtmNKkyK//o5 +Qodx9oFtnWEi/eU4DKS+6kRL3s+p9rtLYL6/vHAom37G6qEn+tTvMIUEiB0F2dTQOebbmeUfonz4 +xKxWZfQpIkRDKv+Xq5Qjp/yToDllW1nDjwzMkv/v9H2FhF3Rb6h+T/4s5uCjAUMUTggRofdTfoK9 +OvI1KtfSu+uG05EHDBEWBwwRFgcMERYHDBEWBQkOFAUJDhQFCQ4UBQkOFAQLEBcECxAXBAsQFwQL +EBcGCg8VBgoPFQYKDxUGCg8VH//AAAAEACAgB7VgIAe7UCAHsOgf/OIAH/+qZB//rtAf/6n0gYAA +AIEAAAAEAAAID////x//reADgAAAH/+t0AD/+AABAAAAABAAAIEEAQCBBAAAAQQAAAEEAQAAB/// +gAAAACoAAAAf/4CwBgAAAB//z6AgBIPYAgAAAIAQAACAAAAFQUAAAEFAAQCDAAABAUAAAIFAAAAf +/5XAIAMRMAwAAAD//7//v////x//kDD//wAA//8A//AAAAD/f///H/zi5ABAAAAf/6XEAAEAAAAA +//8f/5Dg///QdP//0zAf/2OsH/zg6CAHszz//8EwH/9jYB//ZAQf/N4AH/+rHB//m/QAAAjI4P/+ +AOEBkgAf/5ZUAP///x//q0Af/5pMBEEACAQBAAjAAAAAwAQAAKUAAAAwAAAAH/+Y0OED/gDhBG4A +AACFhAAAhYAgC1lQIAtaECALWZAgC1nQH/+r0AAAHYAAAP+AIAe1sCAHsyAgC1pQ4QAuAB//q8Qf +/6a0H/+sUB//p+AAABewH/+rYOAAAKDhADC44AAAAAAAgADhAGAQAABAAOEDCADhA0gA4QOIAOED +yADhABAIH/zhQOEAe3Af/7EwH/+xKB/84Agf/7EsH/+xSB//sUAf/7FEH/+xYB//sVgf/7FcH/zi +AB//qfQf/6dMIAI2xB//rJwAAP+AAAAeYB//kDAf/63gIAMRkCADESCBgAAABAAACIKAAACBAAAA +IAMRAAwAAAAf/5ZQH/+WQB//m+z//7//v////wQBAAjDAAAAH/+u0B//qmQf/65MH/+nBCALAGAf +/6yoH/+spB//rQgf/63QIAsFcAAPQkAgAwyoIAAg6CALBOAgABbQIAsFoCALBLAgCwUQIAsFQCAD +mGggAwy4AABgAABgAABgAAAAAACG3SALBdAgACnEKgAAACAAe7QgAwyIIAOhPCALBfAgABtkIAMM +yB//lcAAAgAAAABAAIIAAAAgAxEkIAAukCAAAAAf/6pUGgAAACBgAAAf/6j4gAAAACAAM2AAAP// +IAsHECALCCAgCwigIAsHkCALB9AgCwhwIAsHYB//qbAAD///AAAP/gAAEAAAQAAAIACunB//qjAg +AD9cIAA9uCAAPhwgAIeMABAAACALZdAgAD58H/+rHAAAIAAgAw90AABIACAAP8Qf/6loIAtl8CAD +DvggAw60IAMOdCAARoAf/6pEIABKkCALCMAPPAAAIABRkCAHtbAgB7igIACi0A8AAAAgBFmoIAsJ +MCALCWAFAAAAg/8AACALCaAgAFvMIAsJAB//q0AgCwowAgAAAB//q0ggA8EgH/+nlB//qwAgAGUI +IAChBCADDzgf/4TwH/+AsGdFIwHvzauJmLrc/hAyVHYf/4AAAAA/KCADE0zP////IAsLYBAAAAA/ +////QAAAAAAAgAAgA+loIAe5oCAHuaYgB7k4AAAIACAHucIgAIIcIAPmqB//rJQf/6v0//7//yAA +haQgBDOUAExLQCAEO2Af/6sk4QAAACALD/D//3//IARbUP/7//8P/oAA///wACALECAgCxBwD/aA +ACALEKAgCxDQAAQAAAABAAAgC2mQIAsRoAD///8gCxFgIACe1CAAoJAgAJysIAsTQCALEgAgCxKQ +IACahCALEuBTAAAAUgAAAFEAAAAgAld0IAsT8CALFDAgCxNgIAsT0CALFID/9///IABZRB//p3Af +/6sY//3//wQAAAAIAAAAIARQsAAIAAAgAK38IAsU0B//mlQf/6rkIAsWwBQAAACAAAACfFAAAIAA +ABCAAAAGgAAABQAACgCAALAAAP80kv//8A+AALEA4QGaACALFlAf/5fIAAB+QCALFpAf/6sUAP/A +AAEAAAAoAAAA4AAAACYAAAAFgAAABgAAAB//psgrAAAAIADFpB/83gAf/6iUA4AAAAf///81AAAA +A0AAAAA///+AQAAACA///x/////CAAAAAADAAB//qvg9AAAAH/+plAcAAACBBAEAgQQAAB//qtAA +ADqYAAAP/wBDAAAf/6hYIAtr4B//rvAf/7Ck4QB6AB//qwQf/5pcH/+aUCALbBAAAweAIAtsgB// +mDAAIAAAAAAJAAAAMAD//Ph/wAAAAKP/uwCj/7oADQAAAOADAACD/7YAD////w//+AD/AAAAD//+ +ASALbMAgCxgAIAsYMCALbVAADwAAAAoAAP//AA8f/5pkA//AAIP/wAAgC23QIAtuQB//q+gf/69g +H/+vQP9g8AAf/4BQH/+P8ASAAAgARAAA/x///wDAAAABgMIAAAMCAOEA4AAAAIEA/7//////AAAA +gAAAH/+Q4AAACcwf/OIM7gAAACALGHAf/6uIAAAIzB//mkwf/5xIH/+WPB//gGAgB7OAAAAnEB// +3OAgC3PAIAtzkB//ljQf/5pE3q2+7yADCUA0AAAAPwAAAB//rMQf/65oAJkAAAAAiQYQAAcCAcCA +AJkAAAAf/60wAIgACIKAAAEf/664H/+syAAPA/8DEQAAAxUAACABUZAgAVaoKQAAAAAAiRQgAVzY +IAMM9CADESggAWncH/+vgAAAH1AgAw0EH/+scB//rYiqqqqqzMzMzP8A/wDw8PDwH/+nWAAD//8A +ACf/IAMNSCALdBAgAXn8IANfeB//qgAf/6u4AAkAACABkNwf/6tsIAAr/AAAHCAgC3cgIAt3UCAA +J4QgCycgIAsncCALdeAgC3YAIAsnoCALJ/AgC3agIAt2wCALJ1AgC3bwIAt2MCALdmAgCyggfwAA +APAAAAAgC3eAIACCcDsAAAgOAAAA0AAAAB//gKAAACA6H/zi5AAACFAAAB9AIAspQCALKWAgCymA +AAkACB//rrQwAAAAH/+pVCALLKAgCyvQIAssMCALLHAAAOAA///3/yALLTAgA2U8AACD/yAHuhgg +B7sQFaAAACADC0gf/654AAAIBgAAiMwgCy1gH/+X4AAEA/8KAAAAIAe4SDMAAAAf/690A//gAH// +/wAAAP/+AD/2kB//roAAACBIA//wACALYAAgC1/AIAtgIB//sIAf/658H/+sgB//qyAgC3lwIAez +HB//pTAgCy3QwAQAAB//qRAf/6kEH/+pHB//rzAf/66YIAQ8eCALLhAf/6iw4AEAAB//m/AgC3qg +IAsuUB//m+ggARtgIAEYUCALeiAgC3pwH/+YACALMNAf/5v0IAs9QOD//gAgC2KgH/+nHB//kiwf +/6sQH/+vJCALR/AgC0ggSAAAACACL3gf/6ikIAIxeB//prQf/5awH/+ppB//pnwAABZMH/+pdCAH +taQf/6bk4QBeAB//qHwATTWgAABIuR//llThAC4AH/+pgOEDBgDhAA4A4AUAAAP/AAAf/6aEIAMR +MB/8v/88AAAAAAf//4MAAAAf/6a8IAtfgCACXZwgAl/EIAJjoB//rAQgAmkQ4AYAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAIGAAAAAAAAA/////////////////////x///bQf//20H//9eB// +/Xgf//14H//9eB//9cAf//owH//4WB//+Fgf//hYIAd9UAAAAAAAAAAAAAAAAAAAAAAgB3/AIAd/ +wAAAAAAAAAAAAAAAAAAAAAAgB31QIAd9UB//+ywf//ssH//7LB//+ywf//ssH//7LAAAAAAgAjfk +AAAAAAAAAAAAAAAAAAAAAAIBAAAAAAAAAAAAAAAAAAAEAAAAAAAAAIGAAAAAAAAQAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAKABHxaxPxa9MP +A+YxAQIAFvFpF/Fqd2sGkGC0Zndj+FQPcxTxZwdAAA8UAGP/+WwQCIoiKCAHiTD7Cv8oIAFAMPWh +YmkAAUwwKiAWmRP4FgQgMgRasPS1GgIAAFCwWFQliBT0omhg/xBYMBrxVhnxViyiSvmSfyFXADcg +JqJJCWYB+WwAAVEANaAd8VAt0IAMhxH/8U8WACBV8PxyOiBuAmtwDU0UpN3/jwoABgJrcP/ylyoA +he8QLnI5/+YBDgCAf5AoIBaZEvoK7SAuBFowKTAQ+zELJgDOVlC8uwIqAlhUJiggFCwgBKSI+AlH +AgCAAyD5JBQsAJgSYB7xNighB40TGfE2/PE0GUABQDD8iBEAHgJ7cP9PFAgJAEow+GYAKuABKDD7 +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 +4gMCA0cMMxGoMysyIBniFIqxKLAA+YgKCgAIOCACCj4oghADAj79CgIiAABgsAuAACI2INEPAABs +EARZ5h8S4iwT4hgMAgApIoIIqY4DqAqIhAuAAGP/6xLiTAPoMATuMAWxMJMglCGVIhLiSBPh+oQg +BDMCkyAS4kbAOoQgBDMCkyAS4kTAMCg3QCg3RCg3SCg3TCM9AXIz7RLiP8AwkyDHLxPiPgMjAxLi +PYQgBDQBlCAS4jyEIAQ0AZQgEuI6hCAENAGUIBLiOYQgBDQBlCDHL8AxAyMDEuI2hCAENAGUIGP/ +/AAAABLiM4MgAxMUDzMRkyAS4jDAMCMmAFf/1hDiL5EAkgGTApQDEeItghAB6jCiEQHwMcBABOQW +AAIAEeIpghAjGgADIgKSEBHiJsAhkhAE5DGEA4MCggGBAADSMAEjAAAAABDiIZEAkgGTApQDEeIf +ghAB6jCiEQHxMcBABOQWAAIAEeIXghAjKgADIgKSEBHiF8AhkhAE5DGEA4MCggGBAADTMAEzAAAA +ABDiEpEAkgGTApQDEeIQghAB6jCiEQHyMcBABOQWAAIAEeIFghAjSgADIgKSEBHiCMAhkhAE5DGE +A4MCggGBAADUMAFDAAAAAABclAFdlAJelANflABDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXJABXZACXpADX5AAUwAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyUAB2QAZ2UAp6UA5+UBAiUBQmUBgqUBwuU +AEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACckAGdkAKekAcdkAOfkAR4kAV5 +kAZ6kAd7kABTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3JQAHZAB3ZQC3pQD +35QEBJQFBZQGBpQHB5QICJQJCZQKCpQLC5QAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyQAd2Q +At6QCx2QA9+QBLSQBbWQBraQB7eQCLiQCbmQCrqQC7uQAFMAAAAf//64ANIxEP/+CgAAAAAAH/// +AADTMRD//goAAAAAAB///0gA1DEQ//4KAAAAAAAA9DAKAAAAAAD0MAoAAAAAAPQwCgAAAABsEAaJ +IoUz9ZFCZPgBLDD44T0UAIqRYAxUEfrhOxQAIEEwKEI6CloK+qKXJgCWQiApQjke4Tb6mwEOAI9W +UCzif4og/wIACgBI5pDA8P3t8y//EGAw/dF+IAAQcDD8FgAgARBgMPoWAiAAEFAw+hYBJAAgL3D9 +CgQiAABRcFiQBvwKACAEEGgw/goAIAAQQDD4FgAgABB4MPgWASIAAFqw+BYCIgAAUXBYj/vAlhrh +GC0gBosi+UY5IAEQYDD6NgIgAgJrcP0kBioJAGbw+yYCIAAQEDDRDwD8CgAgABBIMPkWACAEEGgw ++RYBIAAQcDD5FgIgABB4MFiP58CTGuEELSAGiyL5RjkgARBgMPo2AiACAmtw/SQGKgkAZvD7JgIg +ABAQMNEPACogBv7g+RABEEAw/jYCLgkARnD/JgIgAgJSsPokBiAAEBAw0Q/AINEPAAAAAAAAAPtc +GCIAAFCw/AoBIAYQaDBYmPfAINEPAGwQBIUjgyAU4Of4IQQkIAEsMPrg5RWwBD1g9DAXZAAgIXD4 +eUYIAEBSMAmIAiglBCJCf9EPFuDdH+DeKyEEI0J+HeDZ/kJ/LMcBWDDyNgAuACA38PMmAS4AIH1w +/yYAIAICK7D1Rn8qAEBu8PJGfioJAGbw+yUEIgAAEXDRDwAAbBAEgiMCAkHRDwAAbBAaIhYnJhYb ++DIDIBAQSDD4FhMgARBwMPwSJyAgEDAw+BYZKggBRDD7FiIiAAAQ8PrABywJAUQw/RYWIgAAG3D9 +CgAiBQBvsPzCByIAAHtw9iIALgUAHbD/FhwqIAFQMPoWEioFAF+w+nwQIEACYzD8FiUiAABjcPoW +JCwFAF5w8t4IAgAAUXD+Fhom4AEwMP7+CAQAIBWw/2kMACACKXD9mQwAIAJzsP4WHSACEHAw+RYj +LAUAG7D8TQwOACA/8PvdDAAgAjPw83wIIf4Ca3D9Fh4gAlPeEP58ICAgAkiw8wkWAAAQMDAAQ4oA +CYjyEx4AMAJJ8CMSIyZ0ES0gGf4WJCAeAhjw80MUAEACM/DzFiYh/gJDcPOcAATgADdgmRAvIBP9 +3gkIAAFAMP8WFCH6AnOw/h4UAgABfDDzFiEoACByMPPzCAAEAkIw+B4UCAABRDDzdAsoACB2cCkW +GAeJC/OcGCAwAH4wH+BvAA+NAAOKLyAT/SAZIEACGnCFUPYhCC/QBDvgnh0uEiH5IgMoAQEwMPZG +QgTgASww/VUMARsAN6AiFigkFin+4GAQIAJocPiICQYAIGmw+OBdFgAgQbAk4gEi4Agi1Agk1gH+ +4gAh/gIhcPVSCQQAASAw/tYAIfoCELDyEhQCAABpcPZgACQAIBEw8hImIAQCITD0HhQEAAEgMPBm +MgQAIHEw9CIIAAEQcDD0EiksBQAvsP0WFywmAUww/RIbKAAgajAogIAiFh7yEiggIAIY8PjdDAAB +94Wg/fYLAfoCcbAObTh2ly8vEhop8BUu8gcv8QsJ7gz+/goAARBIMP7/EQGeAnOwD+4t/pkMAGAC +ejAJ/ygP3Qj/AgAKAIgE4BjgKvk9/yAIEHAwLpY9KJY8GeAiAAmNKRIhJRYf/RYVIfACQPBtmQIA +CIpgAOMAAAAiFigjFiv+4BoQIAJocPiICQYAIGmw+OAXFgAgQbCD4SLgCCLUCJPR/uIAIf4CGXD1 +UgkCAAEcMP7WACH6AhCw8hIUAgAAaXD2YAAiACAU8PISJiAEAhjw8x4UAgABHDDwZjICACB08PMi +CAABEHAw8xIrLAUAL7D9FhcsJgFMMP0SGygAIGowKICAIhYeIhIo+N0MAAGbhaAiFij98gsB+gJx +sA4tOCISKHaXLS8SGinwFY73L/ELCe4M/v4KAAEQSDD+/xEBngJzsA/uLf6ZDABgAnowCf8or90l +Fh8tFhUmEhwlEhS4Pf0WJCYAIBmw9mwIJdAEPWAtEjQoEib8vggAIAJJsP4WICJxADagsev/TAAC +vwC2IGTwQy8WEf0WDiIEADVgLRIVKhIlLBId9d0MAgAAWnBb9lQqEiWLEPwSHSIAAGlwW/ZQLRIR +KhIl/AoAIgAAW3BYi5WNHprQZNGULhIfZOGiKRIhLxIfKxIYKhIgD/gJ+Iz9If4Ce/D4GBQOAAF8 +MPgSHi4AIEfwq6r937YYACBWcP/8AigAIEow//chcAQCQjAMjBH8fAgAABBIMPANFwHwAmMwsZny +HB4B9AI+YC4SJyrhBy8SIvnfqhtAAVAw/P8QC8AEOqAK/wIJ/wKfcI7gKhIc+d+lH4AEO6D/Ehcu +CQByMJ5x/hIiIBEANWAd354rIBmMEA27ApvAKxIjLRImDk4M9e4MCgAgWrD7EicgAgJrcP7dDAAB +EGAw/RIbLgUAbzD+EhYgIAJSsPzfkR6QBD/g+jYBLgkAT/D/NgAgJwA3oCkSGvoSJCAgAkpwCgmI +AUqKCAmIAQqKBgmIAMqKBAmIAIqKKRIZEt+BL7Ea+7IALiYBSDD5ZgMuACATsP7ggC6ABD/g/2YC +KgkAZvCbYA7dDP1mASIAABIw0Q8AAAAAAAAA+QoAIB4CanD5FhUgABBAMPgWFyAAEHgw/xYYIAAQ +cDAuFiENTRT9FiYgABBoMC0WH/P+BWAAECgwKhISKxITW/TILhIf+hYZLmEAt6ArEhgqEiApEiEo +Eh6rqqqZqYjz/qVgBAJCMAAtEh7ckPoSJSwAIF9wWIsejR6a0GP+IQDA0P0WFSAAEEgw+RYXIAAQ +QDD4FhggABBwMP50CyAAEHgw/xYhIAAQcDAuFh/z/YlgABAoMI8dD90MY/wXKRYQmR+dHioSEisS +E1v0pSgSJose+hYZIAAQSDD5tgAhDAC2IC0SHiwSJv8CAAf+3G8QZVEdKRIPDNoM+BIdK/AEOqBt +qQUACIgACYpj/ZaOHQ7dDGP81S4SJQy6EZob/OkELgAgXjD44gEvwAQ/4J8aD8wM+uEFKAAgUjD4 +5gEvwBB4MPjMMg4AQH+w+hYIKgAgerD/FgkggAJSsPzlBCoAa9IQjxuOGg/uDP4WDCA2ADegroz/ +AgAKAGXmkC4SJm3pBQAIhgBJYSgSJYkciIGpiP8CAAYAetYQKRIlmJEsEiUsyQTKxCwSHSkSIyoS +JpjQC08M+v8MDAAgYnD8Fh0gABBYMPP8k2gAIE2wjhkvEiXAgPj1BCCAAnOwnvGe8PP/w2AAEEAw +AAAAAC8SHW2JCyoSEAIPhgBKYyoWECwSHSsSI6y8/BYdKgAgXbCbH2P+0IsfLRIVKhIlLBIdBd0M +W/VrKhIlixD8Eh0iAABpcFv1Z2P8bo8YD4gMmOFj/yIAAAAIqgz6TxQCAABicG35BQQIhgBMZSgS +Jg+IDI8ZCmkI+ZwQIIACe/BtiQUGD4YASWeJHIgZCpkM+RIlKAAgSjAojECYkWP/E4gZKhIlKIxA +mKFj/wYAAGwQDCogBwC1jpMVJSAF8zIDIgAAMPD4IgIgExBoMPsWCyogAVAw84NACBgAOWD/AgAO +AeRpUBvesGWDD/oWBingBD6g+N6sGAAgXnD5FggoACAdMPkWCSfABD6g+AoAJgAgRfCYGv0SCyAO +ADTgjBUswBMMDECcGmTQzI8ajRkucjqJGK/dtN35kpcqAWTvkChyOSsaAPmPAQ4BXc4QJSEbimIF +pTYFrAz4IgoqAANm0NWgjCkrICIMiAz5ICMqADKqEAuZDP3enBNbADZgKyAHCwtBDbsJKLHeCY02 +DYgMKLXeLiAiGN6ViysO7Yf+JCIgfgA3oCiCf/CBBAH+Akuw8JkaAAEQQDAAiBr4jP8qACBO8Ai7 +ApsqDLkM/wIACgGOLlArGgD9Cv8qAAaq0CwgFg8CAH3JQf8WDCoA2FFQYADMAAAAAAD+EgUvLwA0 +4C7gGWTvJNog+xIFIgAAYTBb8+DA8Z8b8/8QYgAAMrAAnCrz/6NiAABbMCsgBxrecP06ICogAVww +Db0cqtoooq7wwQQAARBwMADuGn6IJB3eVQy8Ea3MjMAtoq/87AEAARBAMPyMOQgAHOuQ8ABEYgAA +UzAZ3lMMyAn52QgJwAQ6IKmIKI0KKIzYKYHeLoHdKIHhCe4B+OsacAEQUDBgAsUtorHAsf3tAQAA +EFAwDbo4CsoBZKKvimL/FgwqAHBRUBveTYljjhsLmQH5FgcgUgA3oPkWByDgAAZwLSEaDQ5C/CIJ +IGQAt6AMC0JksFkP2BF1i1MZ3kGIY/kSBygAQEowCd5Q+9UMDyAEO6D4ZgMoCQB2cJkXYAAuAAAA +AAAAAP8WDCIAAFCw+xIFIgAAYTBb85grEgf/EgwiAAAysPqiAiEwAIbwjCmOF/WtDAIAAFmw+iwA +DAAgKzD9ZgIiAABpcPwmCSIAAGEwWI1cLhoA+nY5KgAGq5ArIBYvCv9/uQjAgZgbY/2NAAAqIAf6 +CkECAABhcFiRcGP/5QCNG4kp+iwAAgAAWbDzEgwiAABhMPWZCAIAAHFw+SYJICACQHD4FgAiAAB4 +8Fv9NCkgFKSZKSQUjGD6zj9yAABasPt2OSEAEFAw/Ar/KgAHqpArIBb/AgAOAGfi0IIU0Q+NG2TR +U8Ag0Q+LFtog+7wYIAEQYDBYlfVj/+QAJCAHHd3wGN33/K8RBgIBIDD6ZhAOACB88PghCCYJAEGw +9vYAIAMQYDD7IgAgIBBwMP32AiQgASAw/vYDJQAEOSD0iAIHgAQ64Pzd5xYJAGGw9vYBJIAEOmD+ +IgsgARAwMP0iCSQJADEw9PYHKAkAYjD49gQqCQBm8Jv2nvn99gggABBwMJ71LiQU8/83YAYCWrBl +vDj/AgAB/hqdYCkgIP8CAAH+FXpQY/89KiAH+gpBAgAAYXBYkSKCFNEPKyAF/wIAAf+QBuCMIsDS +DcwCnCJj/w8qIAcf3b4N6wz7JCIqIAFQMA+vCS7x3q3uLvXeLiAizOaMKZwqYAAoABndtSmSf40r +8JEEAf4CQ7DwiBoAARB4MAD/Gv/8/ywAIEdwD90CnSr7rB8gARBgMP0KACIAAFCwWJWmihtlrqva +IPsSBSIAAGEwW/MNwCDRD4sW+iwAAAEQYDD7vBIgABBoMFiVm2P+fQAAbBAGKiAHiCL93Z8aIAFQ +MPWAvGfABDqgGN2DLdCA/N2CFgAgQbD7YjogbgJrcA1NFKTd/KwKAAQCa3D8wpcqAGDu0CtiOQy7 +AfsWASC9ADbgL4JKGt2NZPCNKqJ/KYJJ+psBDgBCVlAsIBQMxIf8JBQsAHiTIPkSASzgASww+DwQ +IgB1G2D4QRBgABAoMCpM/22pBQAIhgBJYYsRhzInJhz4MgEh/gJhMAzMEay7+xYAINwAhjD2gIlg +ABAYMKNNsN39ZjkiAAARcNEPAAAAAPosAAIAAFjw/EwAAgAAaXBYjhXSoNEPAPosAAAcEFgw/AoB +IAEQaDBYlVtj/9EAAPP/RWAAEFgwAAArrBj8CgEiAABQsFiVVGP/tAAAAAAA+iwAAgAAYfBb+O+L +ECgyASoWAvOsAA3ABDqg949/agAgZvDaIP18AAAAEGAwW/jA8lwADAAgHrCtTbDdLWY50Q8AANog +W/dyY/8KAIkniJn9mRQvwBAoMPeRFSBAAlpw/EoRBABALvD63QwAIAJCMPiWCSwAICnw+N0yAIAC +YzD9lRQqAEziEGirMainJ3zwd8M1/xIBIDYAPSCwSW2ZBQAIhgBPYYexp6f9uQQh4AI58Hxxb/e2 +ASIAAEHwZNBJ8/62YgAAKjAACM0MjBENTxRt+QUCCIYATGOMEf9PDACAAkFw+PEPbAAgazCw/m3p +BQQIhgBMZS+5BA2oDKhYKIww+LYBL7oAt+ApXECZsfm2ACAAEEAwKLUEY/+iB4gMmJlj/2IoXECY +sWP/jwAAAGwQBBjdDimCfyowBy2RAi6RBCyRBfuSACEbADdg/9z/If4Cc7D8zBEPwAQ7oP+VAioA +IHbw/LsMDxAQEDDwACxgABB4MCuRBS2RBLG7+wtPAf4Cc3D7lQUmAGhu0IyQDO4R/swIC8AEPuAL +ywwAC4sP32DwC4APnAC7YB7c8SmRBSvifwmZEanZ/eJ9ILgANuCM0YvQm8CL0Jyxn9Cf0Svif7C7 +K+Z/+QtPCABbA2Ci0vz6wCAwAkNw/NIJKABAYjArJjr/1RAlQBBIMPnVESCAAiIwJNYH9NYGJcAE +PqD7TAAGAEqnEP+NBigAIEFw/IxAIQACe/D11RAqAERn0Mky+UwAABAANqBtqQUAA4YASWErIkKr +WP8CAAYAVv4Q+CZCIfACE3DRDy+VBfP/LWAAEFgwwKX83MMQMhBYMFnj3MAg0Q8t4oCM0YvQm8CL +0Jyxn9Cf0SvigrC7K+aCY/9FwMD6gn8gARBoMFiH/cAg0Q8AAAAAAAD/1gkh8AITcNEPAMo/+zwA +AFwQYDD8rDYCAABxMG3JBQILhgBOY8Xk/qESegAgTPAvrKzTD235BQQLhgBEZSmN+/kmQiHwAhNw +0Q8AAAAAAPQmQiHwAhNw0Q8AAGwQBIogZaBVHdybCz4Rrt0t0n/6IgMgARBgMAxMNw3ILPjdKAog +AVAw9yUFKgkAMrD9zAwAAgJaMPv6/CgFAGLw+6oBCZAEPiD5WQIKCQAasPomAygJAEowKCUE0Q+P +Ixvchg8PQQv+EavrLbJ//LJ+IDYIE3DYwPKJG3AAEGAwwMAstn8stn6KIGAADNnA8pFWcAAQYDBy +0RqOIZrgjyAtsn2e8Zwg/CYBIf4Ca3Attn1j/1IZ3FgY3FmpiKjoeKEZ+rZ/IB4At+DNpiqyfWqi +ES2yey22f2AACAD8tn8v7AA34IogY/+wHNxLGdxMiCGsmanp+YkMAAAQYDAJyDgotn5j/5AAAGwQ +BPXcXBABEDAw9CwAAAMQEDDwAAdmAQAxMACwIihSf/Vc4Cv/+8WQ0Q8AbBASgyeDPlngg1ngeSgy +kvWsAAIAADLw9AoAI04ANiApMpL3CgMiAcKCYCoykv8CAAQBdIKgKzKS/wIAAgFvBuAsMpL/AgAG +AcwHIC0ykv8CAAgB5YNgLjKS/wIABABFB6AvMpL7CmQm/gA74MFUKDKTsYj4NpMqAW2uECkykvVK +8CYB7YZgKjKS/wIACAF0AqAkNpMkNpIsPQIuwr0rwAXH9//uAQANEGgw/sa9IBIEavDAINEPANog +8szwKgAgLPD8LAAAbhBwMFlN3RjcHwAIiwBCYQBCYQBCYQBCYQBCYWP/zQAAAPzcGhAFEFAw/TKS +IDAQWDBZ4ysuMpInMt75Mt8gARBQMPkWGSH0AnOwDko4+hYYIDgAOmD93A4SAABZsPpcAAAAEGAw +WeSAKRIZq5koMt4PAgAPAgD5FhkgPgA6IPtsAAIAAFFw/dwBEAAQYDBZ5Hb5EhkmACBd8C4SGCU9 +AidWxylWxiQ2k/Q2kiL9ADegJBQSJBQTJBQUJBQVJBQWJBQXJBQYJBQZJBQaKj0Fhif+MtsgARBI +MClWwi5Wvy0y2oZuLVa+LDLdLFbBKzLcK1bA+aUKIEAQQDAopQsa2+UpFBslbQKNoYygj6OOop4S +nxOcEJ0R/W0FIcACUrCMoPiiASADEFgwK1bCL9AHLtAGLhQeLxQfLdAF/RQdIGACWHCYsfy2ACD/ +EEAwKBQcjKIoFBCKo5yy+rYDIAIQYDD8FBEgIAJ4cPnyAiBAAkBwmYKK8ZqBi/ArhgAv8gP/hgMi +AABQsFjh+yNtBSsWESoWEC0WE/wWEiCAAmhwjNGK0vnSAyCgAlhwmbOaspyxjdCdsCg5Ei4KAP8K +ASIAAFCw+IwBIAAQaDD4/TgAYAJgcFgBZy45Ev8CAAAA4wOgKDkT+xxQIgAAULD/CgEgQAJgcPiM +ASAAEGgw+P04AAAQcDBYAVspORP/AgAAAMKCYPosAAIAAFhw/W0FIEACYHD93PggARBwMFjzwC5S +w/zbmRIAAFCw/uwBIGQQWDD+VsMgARBoMFlPn/pWxCAAEBAw0Q8AwKX825AQMBBYMFnioC8ykygK +ZPj/KAIAAFCw/zaWIAMQWDBYYmj3NpIgFBAoMPP9ImBkEFgwAADaIPzbgxAAEGgwWU+L+jaUIAAQ +EDDRD8ef+TaUIAAQEDDRD8Cl/Nt8EDAQWDBZ4on6LAAAABBgMPU2CAAREGgw+2wAAG4QcDBZTSn6 +LAACAABZsFlOh2P85cCl/NtvEDAQWDBZ4nwsMpMtCmQNzCj8zGQiAABQsPw2liABEFgwWGJDwVTz +/JRgZBBYMADApfzbYxAwEFgwWeJvKDLYKTKTJTLZ2iD5mQoABRBYMPhVDAnwBD5g+TaWIAoQQDAI +VSxYYjPz/FVj6BBYMMCl/NtVEDAQWDBZ4l8oMtkpMpMlMt/aIPmZCgAGEFgw+FUMCfAEPmD5NpYg +ChBAMAhVLFhiI2P/vgAqNRNj/njaIFgCv8Ag0Q8AKjUSY/43AAArMtjaIPzbQBBkEGgw/bsoAAEQ +aDBZT0H6VsggABAQMNEPAABsEAyFJ/zbOBAAEHgwnxn/FgsgCxBwMP4WCCAoEGgwnRqGw4nChV76 +wgEgIAJAcJqBKYYCJoYDLMIA/IYAIgAAWPD2QQAgQAJocPxBASIAAFCwWQBvKBAfKRAeLRAd/hAc +IDMQeDAvFDAvFDEuFDL9FDMgYAJYcPkUNCAGEGAw+BQ1IgAAGrBZ2dG2OvwKBiB0AliwWdnNK10F +GNsWGtsWHtsTH9sTLzQQ/jQPIGAQaDD9NA4gEBBgMPo0DSCGEEgw+TQMICwCUPD4NBEgOhBIMPk0 +FC//EEAw+DQVIXACWvBZ2boqPCb8ChAgIAJYcFnZtyoKQPo0FSAREEgwKTQU/1KVIiIQcDD+NDcg +AhBoMP00NiACEFgw+zQ4IiMQYDD8NDkogAQ5oPza9R4JAEfwD4gULzRBKDRACIgUKDQ/+IgUAAUQ +UDD4ND4gMBBYMP5SlSIAAGmwWeHv2mBY3b33rz1yAAAisMRi9yqAIJ4A+TB9T2r/AgACAF5xEHlP +f/8CAAIASMUQK2zKKzQ7KzQTC4sUKzQ6+zQSIAAQEDDRDytSlg8CAA8CAPo8QivgAVwwWN2b8/+x +YIQCMrD8XQMqACAw8PtdAiEAAmMw/MBcILgCWvBY3YX9R5l2ACAysKY6+10DLAAgOXD8wN0hugJa +8FjdcfP/fGYAIDKwAAAApjpY3Sj/AgAGACAysP8CAAH/u8UQpjpY3RqmrS3cyi00Oy00Ew2NFC00 +Ov00EiAAEBAw0Q8uXQMvUt79UtkiAABQsPxS2CoAIDTw+VLfICAQQDD5FgAoAEBBMPgWASDQAnOw +WN0f8/8TZgAgMrAAAABsEASIMIon/DIBIM0ANiDA2C6pFISoLKEVLu0B+6ILIUACc7D4+sAqAFZ3 +EC+sIAj/Aa/M/MxAJgBqJtArTQErvKD+pRQqAGlfEP8CAAYAbebQm6gZ2n0c2o4Y2o7wCQcCAABJ +MABJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYZhAiiD/2oQQChBYMP9GAiCcAnNw/kYFK4AE +OqD8RgQqCQBasPpGASApADUg2zD63D4gEBBgMPpGCSCFEEgw+UUQIFACUTBZ2SSLIsqywCDRD8As +0Q9lzzONMmXfLo4zZe8p8/8oYAAQaDAAAAAAAAAA+iwAAgAAWTD8CgogAxBoMFgXNsAg0Q8AwPCf +q/P/QGIAACLwBMgMCPgMKI0BKIzgmKhj/yop/ECZqGP/IgAAAGwQEiMWGIknJhYXiCuJnvosAA// +EHAw/hUAIgAAYLDxhg1yAAAScCrCESKiByIiDioWFikWFSYtBfstAyAzEHgwLxQJLxQILUAMLRQK +J0ANJxQL/UAOIAAQGDD9FAwg+AJa8PhADyH4AjGw+BQNL/8QODApsn9ocHlkkHu4Hv1sAAAGEEAw +bYoPKuAAL9CAsd3+7AEuAJ36kNcw/BYUIBoANWAqEhX7TAACAABgcFjcTPwSFCCsAD6gH9orivOL +8v7yASAgAmhwntGb0prTL/IA/9YAIBAQSDBtmg8v0AAuQACxRP75cHACAmtwIhkA0Q8AAGWfhdcw +9mwMIAICGPD7vAwl/7ec4GP/j2hwqgd9CQLdCiXdAyVcfClSf8iXsZ4uVn9j/5EA+t0FIBACWHD6 +rHwgBhBgMFnYuyoSFvwKACAQAlhwWNvSLBIUKVJ/Y//MAAAAAAAA/vMGf/8QaDDA0WTfhiQSFdMP +JE0CK0Lv/BYUIBwAOuDawFlOFcePKEbvKhIV+woEIAAQYDD+CgIgQAJocFjf5PsSGCIAAGqw+hIU +IEACYHBY38EpEhdknzoqEhQc2e79CgAh9BBYMFlN5SpG7yIZANEPAAAAAAAA+vMGf/8QaDDA0WXf +GmP+uGwQHhXZ4YMniFOKUotRgz78UgAgIAJIcJyQm5EqlgIolgNZ3fZZ3ez6ShECAAA6sKo2JW0C +LlKyC7kC/AoBIAAQaDD/Cv8iAW2DoP8CAAIA/p+gK1Kz+RYxIgD8xuAc2cwtUq4uUq8vUrD4UrEg +ABBIMPlWsyAEEFAw+BYAIDQQWDBZ4MPAxPttBS//EFAw+la0IgAAULD8VrIhcAJa8PsWMiAAEGAw +WN2bKxIy+jwAD/8QaDD8bQQv/xBwMPzBayABEHgwWGGs+QoAJEkANSAuUrbTD9MP+RYwIIAAO6D7 +EjEiAABR8P3ZlRAAEGAwWeIKL1KtKlK2+6oMAA4Ac/AqMtjdQPzZlhBkEFgw+6soAgAAULBZTZcq +VrjaIFjfwSoWFCsWFSwWFv0WFyCgAmBw/cIBIAIQIDD/wgMgABA4MPnCAiDAAkBw+YYCIAEQcDD/ +hgMiAABQsP2GASIAAFow/MIAIAAQaDD8hgAgIAJgcFv/KyQUcScUcicUcycUdCcUdScUdicUdycU +eCcUeScUevttBSABEGAw/BR7IP8QaDAtFHD9FHwhAAJa8CmwRyqwRioUfikUfyuwRfsUfSDgAmhw +/tIBIP4CQHD/0gMgAgJCMJ+D/oYBIgAAYjD50gIiAABQsPmGAiDAAlhw/dIAIAEQcDD9hgAgABBo +MFv/CC49Ay7gxfpKsCQBb4egL1KtKz0C/PcPcA0QSDAosAX/AgAGAUvOEC4SMMDP+msIABAQaDD+ +zTkCAABQsPwKACAAEHAwWUr4wCDRD9LQ0Q8AAAAV2TwvFDwvFDAtFDotFDktFDgtFDctFDYtFDUt +FDQtFDMtFDLzIgcgAhBAMCgUMfjZLxABEHAwLhQ7gz6JgvyCASBAAlhwnLGZso2AnbCIg/i2AyIA +IB6wLT0F8z0CIAMQSDD5NrIhAAJjcC/ARijARygUPy8UPizARfwUPSBgAnhwivCI8vnyASCAAmBw +mcGYwprA//IDIXACa3D/xgMiAABQsFjxOCkys/sKZCIAAFCw+ZwBIgAAYXD5NrMiAABpMFlNF/o2 +tCAAEBAw0Q8vFDAvFDwtFDItFDMtFDQtFDUtFDYtFDctFDgtFDktFDoW2P8sFDuFJ4lii2GFXv5i +ACBAAkBwnoCbgZmCG9kKhmP2hgMkACAusCNdAiZdBfqyACADEEAw+DayIQACMbApYEcoYEYoFD75 +FD8g/gJwcPZgRSAiAnOwmuAmFD2KsZrhirKa4vuyAyACEFAwKhQx++YDIGACUHCMov2iASCAAlhw +nbGcso6gLrYAiqPTD/q2AyIAAFCwWN8SKhYoLBYq/RYrIP4CYHD7FikgQgJrMI7ShtD/0gEgYgJb +MJ+xlrCesiZdA/hp8iABEDgw/dIDIgAAULD9tgMgIgJjMPiMASAAEGgw+H04AAAQcDBb/nsoafL/ +AgAAAH8CIPhp8yIAAFCw/goAIIACYHD/CgEgABBoMPiMASD+Alhw+P04AGICWvBb/m4pafP/AgAA +AGgCYBbYtPscICIAAFCw/V0FIIACYHD93LggARBwMFjw0i4ys/sKZCIAAFCw/uwBIgAAYbD+NrMi +AABpMFlMsfo2tCAAEBAw0Q8AwND+CgAiAABQsPttBSHgAhLw/CwAAWACWvBZSlTaIPsKACBQEGAw +WddkwCDRDwAvPQTy/LAiAABQsPwKACIAAFiwWU/u2iD7CgAgUBBgMFnXWsAg0Q8AAAAAKT0CKJKn +x6z6iAECAABZMPiWpyIAAFCwWN1g8/ucYAEQSDAqZfJj/v8AACpl82P/LQAAbBAEgyeDPigykmSB +AigykmiHBMAg0Q8AwJj5NpIgBhAgMCs9Avu88CIAAFEwWNokLCIHLskUK8II/cEVIAAQKDD+7QEv +wBBAMPbCCyFAAnOw/8wgKgBN91D47AAOAEBH8P69ASwAIH9w/dxAJgBg3ZAu7KD4xRQqAGB3UP8C +AAYAZO+QLsYIGdhZHthwGNhr8AkHAgAASvAASWEASWEASWEASWEASWEASWEASWEASWEASWEASWEZ +2GAptgAtIgAsCgr4tgIgIAJ6sP62BC2ABD9g/7YFLAkAZ3D9tgEgEgA24C0iAiS1EPq1ESA0ADdg +/NhFEgAAULD9CgAj6BBYMFlMSio2lPU2kyAAEBAw0Q/A5y42kvP/CWAFECAwAAAA+iwAAAMQaDBY +FRZj/8GVy/P/U2IAAFmwC9gMCPgMKI0BKIzgmMhj/z0p/ECZyGP/NQAAAGwQCPxBASIAAFjw8yIH +IDYQSDD5FgIgABAwMPYWAyA4EEAw+BYBIAEQUDD6FgAiAABocPMyDiIAAFCwWP1tCqUC/AoGIFgC +WTBZ1tgrLDr8CgYgDAJRcFnW1RLYHh7YGx/YHBnYHSlUDf9UECAsAlFw/lQPIGAQaDD9VA4ghhBA +MPhUDCAQAlkw8lQRL/8QYDD8VBUgOhAQMPJUFCAQEGAwWdbCKlwm/AoQIDACWTBZ1r8vPQQv8iov +VBUuQQAuVDYmVDctQDYuQDcPAgAI3REO3QItVDsNjRQtVDosQDgtQDkPAgAIzBENzAIsVD0MjBQs +VDwqQQD7CoEgARBAMPlcAAYAlN6QwKZtqkL4lD4gAgJSMPuMAiAGAmIw+pQ/IAgCUjD7lEAgCgJa +MPyUQSAMAmIw+pRCIA4CUjD7lEMgEAJKcPyUPCAQAkIwKpQ9h0r2jxQAKAIYcCY0Ay80AidUEw+P +FC80AQeOFA+PFC5UEixBDS5BCyhBCSlBBSpBBytBDy1BES80ACIUFyJBECNBDi9BBv1BBCIAIGiw ++0EIIgAgXPD6QQouACBX8PlBDCwAIE9w+LsIDAAgf3D+qggKACBu8PuqCAgAIGZw+EESKAAgVnD5 +QRMiACBM8PMRCiIAIBiw+BELIgAgQLD3Ck8H8AE8MPp3CAIAIEiw9yIIAgAgRPCjIvIDTwfwARQw +o3PzA18CACA4sKMiIlQ5AoIU8lQ4IAAQEDDRDwCMSipcPvtMOiHwAmMwWdZcY/8PAGwQCvzXrhA2 +EHAw/hYGIAEQODD3FgQgABAoMPUWByA4EGgwnRWKwYjDicKZEigWA5oR/MIAIgAAWPD8FgAgIAJo +cPxBAyIAAFCwWPzZKBAOLBAMLxAP+RANIDMQaDAtFCAtFCEpFCP/FCUgQAJYcPwUIiIAABqw+BQk +IAYQYDBZ1jvyLDogDAJQ8PwKBiIAAFiwWdY2G9eAFtd9GNd9Gdd9+TQRIGAQeDD/NA4v/xBwMC40 +Ffg0ECCGEFAw+jQMIBAQYDD2NA8gLAJQ8Ps0DSA6EDAw9jQUIBACWTBZ1iMqPCb7HAAAEBBgMFnW +ICU0NyU0PQWPFP80PC+FEHAwLjQ2D48ULzQ7D48ULzQ6jEL4QgMgABBoMP00EiAIEEgw+TQTIBMA +tyDMi4pE+0IFIAcAtqBksBcnND73ND8iAABYsPwKBiCAAlDwWdYIwZD1jRQAWAJwcPXkAyAAEGAw +LDQS/eQCIBAQWDArNBMNjRQiQQUvQQcrQQksQQgt5AEoQQoNjRQt5AD9QQsr4AFIMPYULy/wAUgw ++kEGLgAgU7D9QQQoACBqMPsRBywAIFsw/xEDKgAgerDyEQEsACAXcPoRACwAIFdw/REFLAAgazD8 +EQQoACBiMPIRAioAIBKw+BEGKgAgQrD9ERYsACBrMP8RFyIAIHiw+iIICAAgWjD47ggMACATMP/d +CAwAIHMwrcz8DU8P8AFgMK3t/Q1fDAAgczCtzCw0OQyMFPw0OCAAEBAw0Q8AAABsEAj7PAACAABQ +sPxBAyA2EDAw9hYCIDgQKDD1FgEgARAwMPYWACAAECgw9RYDIgAAaHBY/FEKowL8CgYggAJZMFnV +vPIsOiAMAlDw/AoGIgAAWLBZ1bcZ1wId1v4e1v4f1v8vNBH+NBAgLAJQ8P00DyBgEGAw/DQOICAC +WTD5NA0ghhBAMPg0DC//EEgw+TQVIDoQQDD4NBQgEBBgMFnVpSo8JvwKECBAAlkwWdWh9TQ3L4gQ +cDAuNDYtQgItND0NjRQtNDwNjRT9NDsgfAJQ8P2NFABgAlkw/TQ6IBAQYDBZ1ZSKQ8Dw/zQSIBgQ +SDD5NBMgJAA2oCY0T/o0TiIAAFiw+jxQIAYQYDBZ1YrAqPAABmAgEEgwwKD1iBQAKAJYcPW0AyAw +AjqwJzQTKLQCB4cUCIgUKLQBJzQSLUENLkEJIkETJkEVJ0EUL0ELCIgULEEKKLQAKEESK0EP/0EO +LAAgezD2QQgmACA18PJBDCgAIBIw+0EWLgAgX/D+QRAmACBxsPxmCAIAIGiw9kERIgAgMLD9QRcg +OhBgMCwUF/L/CA4AIDOw/BELLgAge7D5Dk8IACByMPgRCiYAIEXw+QtfBgAgXfD+uwgGACBt8PyI +CAYAIF3wqHf3CE8L8AE8MKi4+AhfBgAgXfCodyc0OQeHFPc0OCAAEBAw0Q8AAGwQBCxAAS1AAC00 +ACw0ASpAAytAAis0Aio0AyhABflABCAGEGAw+TQEIHQCWLD4NAUgDAJQ8FnVPx/WiRzWhxnWhR3W +hi00Efk0DyBgEEAw+DQOIgAAWXD8NBAgLAJQ8P80DSCGEHAw/jQMIDoQeDD/NBQv/xBwMP40FSAQ +EGAwWdUs22D8ChAgTAJQ8FnVKb4y0Q9sEAgoIhjTDyiABSkKc/UKRw4CM0oQ/wIAAgJHmqD6LAAA +AhBYMFhYMvWsAARjADagiqfbMPqsICIAAGEwWIVQjVD43REABBBYMPyhCCwJAG0w/aYBIgAAGrD8 +VQgiAABRcFk9fY4iLCAHGtYo+AoJIlwAt6AMDEEMyxH+1iUaACBW8C+yOg7OCv7ilyoBxcfQLbI5 +H9Y+/tQBDgG+91DwDwcCAABJMABJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYSciF4Y1iSmIKpsV ++YgMBgMAObD3bAAKAO62EC4gFi8gB/3WHRD/EFAw8OEEAMgEU7D6OiAuIAF8MAr6HPoWAioAIGqw +KKKuwNEA3Rr/AgAIAY9qEBjV/Qz+EajujuAooq/+3gEAARBIMP6eOQgAB0NQ8AAZYgAAa7AAACii +scDx+NgBAAAQSDAI+TgJ7QFk0wzA8C9UQioyCflMMCBgAnDw9KF1YFACQPD/VEMqAwBRsCpGCfEI +FgBQAjkwAAeKLTIJCmcMCt0M/TYJIcoAN2AuMgv9MgouACBysP42CyoAA9OQLdwB/TYKIAAQaDAo +IQcN3gn51eEf4AQ7oP7sPylAAUAw/k4UCcAEOiD51gkYCQBKMJhA+iIAIBAQODCXQxfV1fdGAieA +BD6g+ckKBgkAP7CXQRfWACmSl/fV/xgAQD5wKCEa99X+GAkAPnAIiBD4RgYgAgJDcPfV+hgJADow ++UYHKCYBTDD31cgYACA+cCmQgPhGCCoJADqwmkQJaQyZRSgiFYcppoj4JhUmACA18JcpLrY5KyAW +Kgr/erEPKiAH+gpBAgAAYbBYiRTA8IlYjTD7UgkgEAA2YJ9bmbCMWJvBn1ifWXrWFvosAAIAAFlw +/AoCIAMQaDBYjfjAINEPLvqX/lQFIgAAUXBYjU7AINEPnBT6LAACAABZsFiJS4sV/BIELhQANqD7 +1c4SAABRcFiOaNKg0Q8qUEMDqgqKrGSgcApqNppJJ1BDDncLuHfzBxYAUAJpMABNiihQQw6ICoeA +CncMl4AtUEOdEw7dCo3Q+mcMACMAN2CIEw6OC4fjp6f94gIqAANR0LHdl+Od4vP+d2AAEGgwihMP +AgBkoMUtUEL/VEMgAgJrcP1UQiCQAnDw/QoALlQANeAqUEMOqgqKoPIWBigAAWgw+YIKCgMAUfCa +ICJQQw4iC7giBAKICYIL+BYBIBACELAAgoooUEMOiAqCgAoiDJKAKFBDmBMOiAqIgPp3DAACAmtw +8hIGIDMAtiCIE8qBKlBC/1RDIAICUrD6VEIgMAJzsIoRKJwY9X+GaAUAVjBj/c7AgShUQ2P/54cT +Dn4LieP34gIoACBOsPkWACoAA1JQsXeX4ogQmONj/aTAoSpUQ2P/RAAAAAAA+8wYIgAAULD9Cgkg +ARBgMFiNSWP+ngAAGtU+iRIO6AkPAgD6mQgJwAQ6IAmICCiNCimByi+BySiBzQ8CAAn/Af0KASv+ +ekPQ+8wSIgAAULD9CgAgARBgMFiNN2P+VgAAaKISiTcqmRT1PAAAPAA2oIOZYAACAMBQ2iD7XAAC +AABg8P4KAiCOEGgwWItRwCDRD4k3K5kU9TwAABYANuCDmWP7qQAAAAAA8//MYAAQGDDz+5lgABAY +MGwQBiMiGBnVTSgyEQmIAvg2ESIAAFCwWN6GJiAHiiLAcvQh1mYgATAw/qcOf/0QQDAIqAGYImAA +EwAAyK5Z3CXboPz6/yIAAFCwWIelGNT7DGQR+tU7FAAgQTApQjoKagr6on8iAMHCYClCORvVFPqc +AQ4AutZQ8AsHAgAASzAASWEASWEZ1PmZwIsgLfrw+NT5EAgQeDD4xgIvgAQ64P/GAy4JADuw/sYB +JgCobxAd1SX9vQICAABQ8P3GBCAaEFgwWd0tLDIO0w/3RjkgDwA3IPsyECIAAFCwC8AAiicPAgAP +AgD0oA9gYAJ6sC6iDP8CAA4AcXuQ9AoAIGQANqD8+sAgQAJasPiiDCoAQGbw9KUUIIACWvD7pgkg +YAJKsPumCC4AU8oQHdUI/NTfH/8QcDD+pgAgEAJasPQmByoAbNdQLcJ9GdUBm9GZoyjCfZiiL8J/ ++8Z9IAICe/Avxn+ULpQvJCYQJCYRJCYSJCYTJCYUJCYVJCYWJCYXJCYYJCYZJCYaJCYcJCYdJCYe +JCYfJCQEJCQFlCIkJCAkJCEkJCIkJCOUKZQqlCuULCQlGiQlG/o8AAAAEFgw/AoAIAIQaDBZBKvA +INEPANogWQjSiidj/1IA2iBZCM/aIFjl84onY/8SAAAA+iwAADACWbD8CgAgAhBoMFiMoRjU1S8y +EY4iCP8C/zYRIC4AN6AFCUdokj/AINEPKMKAL80Cm4Gfoy7CgJ6iLcKC+8aAIAICa3AtxoJj/ycr +IAfaIPsLQQAAEGAw+7wYIAAQaDBYjIxj/7oAH9StnxCOINog+xwAAAEQYDD91LsfgAQ7oP0WAi4J +AGOw/hYBIgAAaXBYiy/AINEPbBASJBYUKDANKTAOKjAPKhQvKRQu+BQtIAAQMDAmFComFCkmFCgm +FCcmFCYmFCUmFCT2FCMg/xAoMCUULIQpJRQgJBYVhEf2FCIgAhAoMPUUISIAADiw9EIOIAEQMDD2 +FCsgQAIQcIghhiL5IgAgYAIocJlQllKYUSZNAiIiA5JT8mLSIgAAKPBZ2J0iFhNZ2JMd1JAscTkq +FhcrFhb9wRdwABAQMAzKAllIpC6gJ/njBmIAABKw0Q8c1IclFhKNMI4xjzL4MgMgBRBQMPgWACA0 +EFgwWdtvJWLxWdiJWdh/JBYRKhYaKxYZKU0G9hYQIYgCSnD5FhgmAGGuUCQWESYWEIRS+EAzYgAA +MXArEhkd1Ez6EhogABBgMFncwHtLGvVSACIAAFFwWUdUKxIQKrLwsKoqtvBgABMAACpsGPxiBCIA +AFjwWUfGzKmFYCsSGHW5rmAAZGRgYSwSEmTASGQhiC8gJ/4hECIAswfg/NRbEAUQUDD9chsgNBBY +MP0WACIAAGiwWdtDLiAnaeEZL3Ibb/MTKhIVKxIULRIS/goAIGACYHBY7E3ApfzUTRA0EFgwWds4 +wCDRDwAAKBITZIGlaIBeKxIWHdQe+hIXIAAQYDBZ3JIqEhN7q0coEhAc1EEvgs8ugs4pgtD5FgAg +NBBYMPiC0SIAAGqw+BYBIAUQUDBZ2yQqEhH6rQUgABBYMPqsMCAgEGAwWdLXY/86AAAAAAD5EhEg +ABBgMCwUKiwUKSwUKCwUJywUJiwUJSwUJCwUI/wUIiD/EFgwKxQs+xQgIAIQUDD6FCEgARBAMCgU +KymdBS+QRSWQRiaQRyYULyUULv8ULSIAAEJw/4IQIHACSnD5FhIgQAJQcI2ijqP8ogEgYAJYcJyx +nrOdso6PjY6KoJqwKIIRmBCGMJYRhTGVEowynBMc1Az7MgMgBRBQMPsWBCA0EFgwWdryY/6JwKX8 +1AYQNBBYMP8hEiIAAGiwWdrs0Q8AAAAAAPoSFSAAEFgwWUVD8qwAAGEAtqBY3JfyrAAOowA2oCsS +EvqsECABEGgw/aQWIBAQYDBZ0osvEhUvJgwv8Dn/JCggARBwMP4kJyIAAFCwWUR4KhIVKxIULRIS ++CEQIGACYHD4dTkgABBwMFjr4WP+TQBZRG8pIRApdTlj/fotEhX80+EQBRBQMP3SACA0EFgwWdrG +Y/4nAAAAbBAUKzEKFtPajTEe09oqYuMNjRT409kcAEB3cPsMSw2QBD9g+sIMagAgarD/AgAIAZrm +EIqnKRwQ+qIOIAAQKDCVkJWRlZKVk5WUlZWVlpWXlZiVmZWalZspMBD4kWxgARA4MGiSA8Ag0Q8j +Ihge08ONOowi/atADAkAd3D9Ngoi8gA3INogWQeiGNO9LzIRCP8CLzYRiSJkkxwf05kvFhCOINog +/AoBIIACWHD/07UfgAQ7oP8WEi4JADuw/hYRIAIQaDBYihvAINEPKTAe/wIAAAFWhmD/AgACAYKC +YCdi6SpyGCmhAiuhBS6hBPyiACNJADZg/Zz/If4CS7D8uxEJwAQ+YP2lAigAIE8wC5kMYAAuK6EF +LKEEDwIA+aIAIAICWvD7C08B/gJzMPulBS/ABDug/pkIBgEP3xAMvRENmQwACYsFtWDwCYAPjgC6 +4BjTjSmhBSiCrAmZEfRi4ygAIE7wqYgJiBH4RAgAUBBgMPpMICAAEFgwWdIeLyAHLkAHKvqY+Ar7 +LgIBfDD47gEP4AQ/4PggDC4JAHuw/kQHIPwQSDD/IAcuAEBLsPpEBSACEEgwKURF9URELiABfDD4 +RAwuCQB7sC5EBy1yGvJGCiACAmtwLXYaJUYaJURsLHIYlUglRgktwQIswQMpYhYNzAx8mwIsZhZk +QQ76TAAAAxBYMFk6XhzTYR3TYf7TYRIAAFEw+DEOICACWHD4FQ4gABB4MFkD0/esAAAvADagiaor +KgALmQL5pgogARBYMFkDq2Sh0clx+nwAAAAQWDD8CgAgAhBoMFkDA2RArCxAbMjMiUcrmRTItYqZ +yKFY28iJSPdi6SASADZgjUmVS5nQjkid4ZVIlUmJTC/6lv9EBSBgAH5wKkIW+osUCmABUDD6qg8A +AHZSUC1yV/2qCgAAEGAw+qIAIAEQaDBYfkAlRhaIR5VM+frAIEACejD7QgAuAEBP8PWFFCCAAnvw +n4ifiS5izPpyGCAAEGAw/rsMAAEQaDBYfjIpQEX/AgAAAGmGYP8CAAIAUYJgwEz1CgIiAABY8PwK +MCCgAlBwWdGq+iwAAAAQcDD80xsQABB4MPUUYCADEGgw/RYVIKACWHD0tBEgABBoMPwWACADEGAw +WdquwCDRDyWlBfP93mAAEFgwAABZS0ZlrMjz/59gFhAgMNogWNvKZa0aY/zoAAAurQSPOJ8YLuIe +nhlj/U8AAAAtcjn9qgoAABBgMPqiACABEGgwWH4GY/8ULnIasO4udhpj/1UAACsgB9og+wtBAAAQ +YDD7vBggABBoMFiKqmP8xyxyGbDMLHYZY/8tAAAtrQIo0r+YHS/Svp8cLtLB/hYPIEACWPD90sAg +EBBgMP0WDiBAAlBwWdFvGtLkiRQKmQKZFGP8xgCKR9sw+qIOIDAQYDBZ0WgrMQn7dTgiAABR8FkA +68Ag0Q8AwKX80tgQLBBYMFnZsvP9rmAAECAwbBAGizeIMIu++IgRAAMQSDD5iAICAABQ8Pi2ASA7 +ADSgLCAF/QoAIDAANyAttBH90skQAxBgMP7SxBACEHgw/7QQIAAQeDD+FgAgABBwMFnaW8Ag0Q8A +ACgKZSi0EWP/zQAAAGwQBikgBYIoKApzeYsviiLLoB/Sjp8QjiDaIPscAAABEGAw/9KdH4AEO6D/ +FgIuCQBjsP4WASACEGgwWIkRwCDRDwAAKyAH2iD7C0EAABBgMPu8GCAAEGgwWIpaY/+yAGwQBCgg +bMiMiScrmRTItYqZyKFY2xqJKBXSn8BA+iIJL5YQYDDzUo4gEAA2YJQrmaCLKJqxlCiUKYks/CQF +IGAAfnAqIhb6ixQKYAFQMPqqDwC8AFJwLTJX/aoKAAAQYDD6ogAgARBoMFh9kCQmFogniyD5+sAg +QAJ6MPQmDC4AQE/w9IUUIIACe/CfiZ+ILlJx+jIYIAAQYDD+uwwAARBoMFh9gikgRWiRKGiSGtEP +LTI5/aoKAAAQYDD6ogAgARBoMFh9emP/oi4yGrDuLjYa0Q8ALzIZsP8vNhnRDwAAbBAGKCIYH9Js +LSIS+IIIIgAAUPCLpxPSY/iCACADEGAw+7IOIAEQSDD/JhcsCQBPcP0mEimABDog+bQQKAkAYjCY +sfQiACAAEGgwLbQR9LYGIAAQcDDzFgAgABB4MFnZ7sAg0Q8AAABsEAopIhgPAgApkAUqCnP1CEcO +AzDSUP8CAAIDNxog1TD6LAAAAhBYMFhT5PasAAXMADagiqcDOwL6rCAiAABhMFiBAohgCIgRCEgC +mKEvMEQoMEX5MEYvgAQ/4Aj/AvgwRy+ABD/gCf8CCP8R+aEILgkAR/AvZhUuMEgvMEn4MEovgAQ7 +oP8wSy4JAHuw+WUIL4AEO6D4CgAuCQBDsPhmEy+ABDug+GRCLgkAe7AuZhSNpv1mEiABEFgw/DAh +IgAAKrD8ZEAiAABRsFk5FigiEv8CAAIB0uoQiSJlk5sb0h0sYEIf0hv4iUEAARBwMP6aEQAAEEAw ++eg4DaAEPmD+CgAgQAJJcPhiEy4FAEPwmRIMzAn70dEaACBasPsWAyCwAnlwnxAFzAv6FgQsCQB3 +cJ0R+mISIMACYzCcFWABHcWAKSEH/NGyGUABTDD/3QoJwAQ+YP/RqxgJAF5wmTD5IgAgHgJCMAhI +FPsKQCwFAHPw/DYCL4AEPmD7NgMuCQB+MJ8xH9HQLdKXjBEb0aMP3QH90fEcCQBrMPvRzRgJAF5w +LyEa+TYELAkAazD5EggsJgFkMP3RxRoAIG7w+7CALoAEP+CfNpw3+5sMDAkAb7D9NhQgYAJa8Js1 +jyktIhWp///8MCwAIE9w/yYJIGACa3D9JhUgYAB+sCoiEnynJSoiFio0OwqMFCw0OgyMFCw0OQyM +FCw0OCtSAPC3B3ACAmqwLSYWKHY5KyAWLgr/frENKiAH/BIHKiABUDBYhNMoYhMqYhIrYhX8YhQm +AO/GkLG7+2YVLAAgIzAsZhQvIAckIRsc0V37IhcuIAF8MPipDAfABD/g+tFZFgAgZfD9cjogHhBw +MP8WCSgDAF5w+voKBAMASTD0FgoqAcZ3UCqilylyOYsT+pMBDgG+VlCNFPALBwIAAEDw/dJ/IB4Q +SDBtmgIASGGOKfwiCiwAICdw/RYIIGACa3AtFgf+zAwAwAJw8P4WBioAwm8QKyAWLgr/0w9+sRAq +IAf6CkEAABBgMFiEzmSjUSgSAvSPFABAAlDwBAiGAEplAgiGAEpjAAiGAEphLzQmJDQnD48ULzQl +D48ULzQkLmIVLjRHDo4ULjRGDo4ULjRFDo4ULjRELWIULTRLDY0ULTRKDY0ULTRJDY0ULTRILGIT +K2ISLmBA/LsMAH4QUDD66gEARghZMC1SAA0PUWXytfgKgCAkADdw+KoCABQAf7ApCgEJqgIqNCEo +UhX/EgAgABBIMPSA2GCwAnDwKWRD+WRCKAMAQTAoNhUAD4gADootYhMITAz/UhcsACBHcC1mEytS +FZwaLlIW+LsMDgAgfjD7VhUhLAA24P9WFyoAA0PQse7+VhYgABBwMIhWH9EujRn70P8dMQA2IIlQ +/ugJA/6TrlApCmAJiArz/RtgAgJzsACIaMiOi2nAoJprmLCMaJvBmmiaaY1Q/wIAAADPK1D6LAAC +AABZsP5iFSACEGAw/lYHIAIQaDBYh97AINEPAAAA+iwAAgAAW3BYhJFkrnH70TgSAABRsFiJsNKg +0Q+JFShgQwmICoiA9ICDYLACePD7EgUoAwBBMCg2FSlgQwuZC7iZAgmIAE+KLmITLWBD+90KDgAg +Q7AuZhOM0AjMDJzQL2BDC/sKi7AITAycGvwSBSAhADbgDP8Li/OO8quL+/YDKgADQtCx7p7y8/8K +YAAQcDBk8Rz9YEIgABBwMC5kQ44Vsd39ZEIgMAJzsJ4VjxrA0PTw8moAAWwwiRUoYEOMGo8WCYgK +iID/vgoIAwBDMJjgLmBDCe4L/78LABACc7D1DhYAEAJ78ACPii5iEy9gQ/n/Cg4AIEOwLmYTjvAI +7gye8C9gQwn5ComQCMwMnBr1kEpgAgJzcPgSBiA6ADfg+WBCIAAQYDAsZEOMFbGZ+WRCIDACYzCc +FY8a+YwYIgAAa7D7mDkKAAFsMPgWBi9rALfgYABTwMEsZENj/9qNFQ3/C4zzi/KsjPz2AyoAA0MQ +sbub8mP+Hy76l/5kBSIAAFGwWIgxwCDRDwAAAAAAAPosAAIAAFmw/QqOIgAAYXBYhgzAINEPAMDQ +8/3qYgAAc3DA8S9kQ2P+8wCLGfosAAABEGAw+7wYIB4QaDBYiHhj/joPTAwsNCcMjBQsNCYMjBQs +NCUMjBQsNCRj/S6LGfosAAABEGAw+7wSIAAQaDBYiGtj/gcAAGiCJIg3LIkU9jwAADQANyCFiWP/ +cog3LYkU9jwAABoAN2CFiWP6MgDVMPP/WmAAEDAwAAAAAAAA8/oeYAAQKDDz/0RgABAoMGwQBiYi +GCZgBQM8AvQWASBzEEgw9QhHDgGYSZD/AgACAbAaICkwNy4wMC8wNCcwMfgwNSAAEFgw+P8RD4AE +O6D3MDIuCQA7sPgwNi4JAEfw+P8RD4AEO6D3MDMuCQA7sPggaC4JAEfw+P8RD4AEO6D3PAAOCQA7 +sPPQixAMAkIw8IAEDgkAT/D/CBkIoAF8MPYyAy4BghIgCooRCpkCKCEyCGYs/BYAIIUANaAd0HEt +0qwlMvXzMvsrkAQ6IPndCAABECAw/BYALZAEP2DzMhgkACBtcG1pVC0xBIYw+VwUDcAEP2D9ZggN +4AQ7IAxmDCZt//ZiPyyAAUwwANEEAEwa8NAEBgBAYbD2BhkAAgJa8PRgFmgAIE4whlpyaQyMXv1S +DSAOCHMwf9EWpaX80F4QAhBQMP0iACAwEFgwWdcuwFD2CgAiIgA1YI9ci1fzEgEu/xAgMPj6wC4A +QCfw/rEVIEACIvD5sgsoAEBBMP9WDCCAAmIwnLn8tggjwAQ84Pa1FCIAADsw+O4IAAAQMDD+7EAm +AQZmUPO1FCoAIGTw/wIACgEFX5CIEMqCKRIByZ36nAACAABLMG2pBQAIhgBJYStCAAzHAv9SDCoA +IB7w/wIABgETdtCbQIwQlneDUC4SARvQMvrCFiOABDzg/MIXLgkAG7AudgH5IGkv3xBoMPhxCCwA +QG/wLVYMC5sL87J/L/8QMDD9cgYv/xBwMPuyfingBD5g+FUIIhEANPDzzAEP/xBAMPzcCAoRAHbw ++6oBCgAD6xAqrAEd0BmtnS3Sf7DbfbsBwICry/y7BnoAIEKwsaoc0BOsnCzCf1nZ5C1QRKvdDQ1P +/VUzIAYCa3ANLRItVTIuIhL/AgACAFXrkC8iAmXwoChRMsqKKXBTypUqUgwrCkALqgL6VgwgNAD6 +sPxSEiIAAFFw/VINIKACWfBYSLZloG/6LAAAMBBYMFhHc/SgYWBAAkHw9AgWAgAASrAASWUCCIYA +SWMACIYASWEsIhJ8xyIoIhYopBsIjhQupBoOjhQupBkOjhQupBiNcHDXBS+MAS8mFtog+1wAADAQ +YDBYRyIi+pnyVAUgABAQMNEPAAAA+8/gEgAAUXBYiFHSoNEPAGiCFIg3KYkU9TwAAKwANmCHiWAA +CgAAAPc8AAAAECgw+iwAAgAAWXD9Co4iAABh8FiFAsAg0Q8AiDcqiRT1PAAAfwA2oIeJY/7zAAAA +AAAA8/0Cb/8QSDDAwJy78/4yYgAAOnAAAI0Q/O4MADkAN2CKEQ5PFP38CCIAAEtw/ao2AgAAWzBt +qQUGCYYAS2eKEYkQ/6oMCAAgdnBtqQUICYYATGmPXA47DKuLK7xAm0Bj/d+cQGP92gDz/2RgABA4 +MPP+emAAEDgwbBAGKSIYBQhH9pAFIgF5giAqCnP3CgAuAaxRkBnPi/8CAAIBs5ogKJLpK4IYLLEC +LrEELbEF+rIAI2IANyCYEf/M/yH+AnOw/N0RD8AEO6D/tQIqACBysA2qDGAALgAAACixBSmxBPqy +ACACAkIw+AhPAf4CanD4tQUtwAQ/YP2qCAYBK8ZQDIwRDKoMAAqLB4dg8AqAD5QAuiAZz3EqsQUV +z2kpkqwJqhH1UuMoACBSMKiYCYgR+FUIAFAQYDD6XCAgABBYMFnOAS4gBy1QB4sR/wr7LgIBcDD/ +3QEP4AQ7oP8gDCwJAHdw/VQHIAIQMDD+IAcvmBBIMPlUBSD8EEAw9lRFLABAR3D3VEQuIAFwMP9U +DCwJAHdwLVQHLLIaGs9K8lYKIAICYzAsthonVhonVGwrshiXWJdZLLECK7EDKqIWDLsMe6sFH88/ +K/YW9FGRb8AQYDCKV42oK6EV+aILIEACerD+qRQsAEBj8PwWAioAIGbw+7xAJgEt7lAMTBGs7v6l +FCoAIGsw/wIACgEoVtDJMMhO2dBtSQUAA4YASWGK8AyqCP8CAAYBP16QmvDT0I5Q/DIGL4AEO6D9 +MQguCQBxMJ4xLVUILFYS91YTIAEQWDD7VGwiAABRcPdUQiAAEFgwWTYcLyIS/wIAAgDka9CIIvkg +ByHOALYgKjAwLTAx/DAyK4AEOqANqgL7MDMrgAQ6oPhSDCoJAGKwCKoR+QlBCgkAWrD6Vg4gAG7+ +EMBAGs62/c8dEIAQWDD7iwIJwAQ6YPtWDCgAIFIwK4I6DZ0K/dKDJABzwuAsgjkoFgD9ywEOAGzv +EAIqAv8xCCABEGAw/lINIgAAaPD+Ngcu4AEgMFiGkYoQwJQppjmPXCgaAPj/AgAQEFgw/1YMIgAA +UXBZNeyLMHu2EiwKgnxBfC0iHbHdLSYdyFEnVGyIWMuFjlmXW5jgj1ie8ZdY91YJIAAQEDDRDye1 +BfP9pmAAEEAwJAqO+iwAAgAAWXD8PAACAABpMFiEHsAg0Q8AKiIcsaoqJhxj/QWZE/wyBiIAAFFw +/TIFIGgCWXBYSRaJE/SsAAEqALagiFxj/wQAKyE8sbsrJTxj/38AAAAAAPucGCIAAFCw/AoBIAQQ +aDBYhn/6XAAADxBYMFk1v/vO1BIAAFFwWIdE0qDRDwAAAP8CAAIAYgIgiDcsiRT1PAAAxwA3IIOJ +Y/9aiDctiRT1PAAArQA3YIOJY/5MwKX8zrYQLBBYMFnVkPP9o2AAECgwAAAAAAAAAPpcAAALEFgw +WTWlY/+XAAD6XAAADBBYMFk1oWP/h5er8/3YYgAAGnD9ugwANwA04ApLFP68CCIAAEDw/k42AgAA +S3DTD23pBQIIhgBJY4kSqjj7TgwAgAJKcG3pBQQIhgBJZYsSCs4MrrsrvECb8GP9h4gSKIxAmPBj +/X0AAAAA8/6pYAAQKDDz/aViAAAZ8PP+mWAAEBgwaaJEKiE9iFixqvolPSASADYgi1mXW5iwjFib +wZdYl1n7nBgiAABQsPwKASAAEGgwWIYz+lwAAA0QWDBZNXNj/swAAAAAAAAA/M6HEAIQUDD9UgAg +NhBYMP5RMiIAAHkwWdVN+lwAAA4QWDBZNWdj/iYAAABsEAYZzm4rko4oshrAYPr6/yABECgw985h +EADPpiAkshjTDy1BBP5CACACAlqw/Nz/K+cBWDD8rxEJwAQ/IPpFBSgAIE+wD58MAA+L/0EDKsAB +XDAFu2D/D0YOOgE64AyoEQiYDAIIiysKANMPBbti/wIADgBokuB6yQnI9v8CAAYAQd/QCaoR+85N +GgAgUvAscqwrsoiqzAnMEay7jLcpyRRkkEYtsAUuCpZ+0T0vsEVp8jeEyctCiDKPM45DjUL/7gwA +ARBgMPjdDAAAEEgw/sk4AAAQQDANyDh5gA2JuowgiZD/AgAGAGrmUBvONCuyjiyyGrFm/wIADf+R +4ZBgALYAAAmoEai4+FkUC8AEO2D+mREOACBTsPnuDAiAAUAw8IEEAfgCc7CI4PBcGg//EEgwCckD +CYgB+kEFLAkAQzCc4I5ALUEEsaoKCk/6RQUgIgRqsLDcDMkR8/8BaAAgT7DAoCpFBfP/6mAAEFAw +sbsKGhRlr/f63AAP/xBgMFiAW40QitjJoozZmsCO2PzmASAAEFgwm9ib2Zvb9BYBIBkAN2CP3Cgq +APj/AgIAAGEw/9YMIO4AV/DAINEPirL7FgAvvwA2oH6nDsed+xYAKABATrCZsmP/qBzOBtMP+xYA +L//QVxD9vAAAOgA2oPz6ACAAEFgw+sASf/AQcDAKihT0r3JgEAJa8HrI8f8CAA//sNeQCkoU8/9W +YAgCWvAAAAAAAPP/T2AAEFgw+iwAAgAAW3BYDn7AINEPAGwQCCkiGA8CAA8CACmQBfUIRwBzEFAw +9woALgLq0lD2PAACAvQaICgyAP8CAAICnTIQ+goxIgKlLhAoMCD7CiUmArvWEP8CAAYCp94Q+iwA +AAIQWDBYT2b1rAAFxAA2oIqnAzsC0w/6rCAiAABhMFh8hI9QCP8R/qEILgkAfTCfoS5VCCdWFSdW +FCdUQidWE42m/VYSIAIQWDD8MCEiAAAysPxUQCIAAFFwWTSrKCIS/wIAAgGRahCJIisgBxrNU/wK +HiMSALZgJCEbLSIXLlITKFIS/2IAKiABXDD5UEInwAQ+4PsWBCYAIFXwKnI6+ZkJDjYBfDCfFgaZ +Cw6IDP2INgDAAkpw+RYCJAMAQTD0FgUqAmHmkBnNPihyOQm5CimSlxrNWvmDAQ4CVk4QHs2W8AoH +AgAAQPBtygIASGGMFo0piyoOzAoswn/9uwwAwAJo8P0WACwAICMw/BYDIGACYzD8FgEqATDm0Csg +FiwK/w8CAHyxGCogBw8CAPoKQQAAEGAwWIC69KTHYP8QYDD0jRQAQAJBsPQIFgBAAlDwAEplAgiG +AEpjAAiGAEphLTQmJDQnDY0ULTQlDY0ULTQki2bA8fSyH2B+EEAwKVITLlISKlBACe4M+KgBADoI +cTCNYA0OUWXkTn3WDSsKgPuIAgAOAH6wD4gCKDQhKGIVZIH0wNAtVEP9VEIoAwBBMPg2FSCwAlmw +8QsWALACUPAACoopUhOomSlWEy1iFQhODJ4VCN0M/WYVIl8AN2AtYhf9jQgAABAgMPpiFioAA0NQ +saotZhf6ZhYgABBQMPqoCQBgEEgw+YgKAAICUrAezPIvIQcbzPT5zPEQHgJCMPhIFA9AAXww/P8R +CgUAV7D+zT0eCQBP8J8w+SIAIEAQaDCdM40WmzL4nxECAABZMP3rOA4JAH4wnzEezQ6PFArdEf3N +DRoJAG7wDv8KL/KX/SEaLgBAb/D7zS0eCQBf8P4SAyyABD9g+80HHgkAX/CdNp83/c0DHiYBfDD7 +zNQeACBf8C/wgA2tAi02FP/vDAgJAF5w+TYEIGACe/CfNY0pKyIV+SISLAAgd3D93DAqACB28P0m +CSBgAlrw+yYVIEwAcnAqIhYqNDsKixQrNDoLixQrNDkLixQrNDiJYHCXBLGtLSYWKHY5KyAWfLEN +KiAH/BIBKiABUDBYgBGIWP1iACASADYgi1mUW5iwjFibwZRYlFl61hj6LAACAABZcPwKAiACEGgw +WIOawCDRDwAALvqX/lQFIgAAUXBYhEvAINEPAAAAAAAA+iwAAgAAWzBYgEdkrZT7zPkSAABRcFiF +ZtKg0Q8AAAD0CgAgUBBAMPP+emAAEFAwiRIoUEMJiAqIgGSAkwhINig2FStQQwm7C/u8CCIAAFJw +8wsWALACSPAASYouUhMtUEP63QoOACBDsC5WE4vQCLsMm9AtUEMK2gqKoAhLDPsWBSAtADagiRIJ +3QuP0/+PCAAAECAw+tICKgADQ9Cxqp/TmtLz/e5gABBQMAAAAAD0CgAhVAA3YCsSAipQQvRUQyAw +Alrw+xYCIAICUrAqVEKLFfQKACERADbgwKAKDkCJEihQQ5IXixWCEAmICoiA8u0KCAMAQvCY0C1Q +QwndC/LiCwAQAmtw9Q0WABACELAAgootUhMiUEP5IgoMACBHcC1WE40gCN0MnSAtUEMJ2QqJkAi7 +DPsWBSACAlKw8hIHIEQAtmD7EgIgNgA3YClQQvRUQyAwAlrw+xYCIAICSnApVEKNEIsVKNwY/o05 +DgABUDD9FgAvaQC24GP9FwAAL1RDY//djhIO3QuL06uL/9ICKgADQtCx/5vTn9Jj/PX6LAACAABY +8PxMAAIAAGlwW/4S0qDRDwD6LAACAABY8PxMAAIAAGlwW/zb0qDRDwD6LAACAABY8PxMAAIAAGlw +W/oi0qDRDwDz/KpgABBQMPosAAIAAFjw/EwAAgAAaXBb+8nSoNEPAC9UQ2P+wosU+iwAAAEQYDD7 +vBggHhBoMFiEGWP95wAAaIJ3iDcsiRT1PAAAhAA3IIaJjWB81hjAINEPiDcuiRT1PAAAZAA3oIaJ +Y/qPAAAA+iwAAgAAWXD9Co4iAABhsFiBkMAg0Q8ADkkMKTQnCYkUKTQmCYkUKTQlCYkUKTQkY/uV +ixT6LAAAARBgMPu8EiAAEGgwWIP6Y/1q1jDz/5FgABAoMAAAAPP6MWIAADHw8/9+YAAQMDBsEAYo +IhgogAUFBkf0FgAgcRBIMP8CAAADECAw/wIABgBQThD/AgACAHABoIwniRCKzMCw/MwwIgAAKnD8 +rAwBkAJSsPSQWGoFAGawGcw7Kirw+pkIAAAQMDCpaQRXNAcHR215BQADhgBJYYon0w8PAgAqrDBY +gqD5zDAbwAQ94PZrBQIAABqw+irwIgAAWrD3VQwIACBWcPVfwGgAIE2w88wnEgAAKPD8EgAiAABQ +sP0KAiIAAFjwW/4v0lDRDwCMImTASmliNY0Qy9CGEPRmNAIAAFCw9gZHAgAAaXD7PAACAABhsFiC +Z4gQDGkR9ogMAgAgTPD4FgAv0gC2IMAg0Q8AAAAAAADz/5xgABAoMCsgB9og+wtBAAAQYDD7vBgg +ABBoMFiDqGP/mQBsEASJOImX/PrAIEACWnD8uwEAABBAMPiVFCCAAlrwm5n7lggiAABQ8Fj4s9EP +AABsEAYVy+YtUo4s0hgrwQMoIhj4FgEgARMm4MAw98vYEAAQSDD5FgIgcAJQsPoWACABEDAw8ABc +YJYQUDAAx70LywGbQolIyZCNSZnQjkj95gEgABBgMJxInEmIEYwvjRD/ghEgQAJJMCnGACxGCf1G +CCAEEFgw+SYPLgkAX/AvhhEtUo4s0hgrwQOxM/8CAAgAYlzQKMEEjsDzXxQJwAQ6IPjuCA/gBD/g +D+4MLu3//uI/KIABGDAAgQQAbxrwgAQOAEB7sA4OGWTvuChyrCRSiKg4CYgRqESOSnLpoy9ABXrx +pikKl3nxoChARWmCmokS+ZwBIJkQWDD5FgIgngRb8CwKmnzxRCgKmHjxPikKm/8CAAYAUs/QjEJk +zyb/AgAD/457EBvLq/8CAA//jGbQZMEAwLBtCBAt+gB80E8MjBT0wGFgEAJa8GP/6BzLppxLY//D +jRJk0OIey6OKIn6gBQovU2TwyisgB9og+wtBAAEQYDD7vBggABBoMFiDO40RLNIRwOgOzAIs1hHR +D8fwfPAMDEwU8AAGYAgCWvCxuwwcFGXP9/pMAA//EGAwWH3H8/6PYJYQUDCITP8CAAH/rP4QKUIW +HMt+KNI5++BpLmABTDAP/w8I/wqI9gmJFI/xCYgoCogR/LwKDgAgR/AvRhcfy3Iswn8oQhgPuwov +QhIrsn+o//DABAoAIH7w+ct3Ef4CWvALCxn5Rgsr4AFcMPtFMyAGAlrwCysSK0UyY/7l0Q/z/25g +ABBYMIkRKJIRwLL7iAICAABQsPiWESADEFgwWBJ20Q9sEAgjIhiIOi4iAvYqACABEDgw9ogBAAAQ +IDD4dDgCjQC3oBzLXS0yAP4iACAFEFAw/zAFIDAQWDBZ0hz2yz4QBhBgMPsKBCAAEDgw9EBYYHEQ +SDAtMAX6CnMmAPDPUHrRRSgiGIiHiSCIjgd9AviZEQIAAFCw94QRKAkAZnD5hgEgABBwMPuEECAA +EHgw9hYAIgAAWjBZ0sQFCUf/AgACAKOaYMAg0Q8tIhIkIAcN6lH0BEEAALeGoA3IUf8CAAAAuAYg +HMs2LiBp+goFIuABLDD0lRoAMBBYMP2GQQnABDug+GYCAgAAabD5FgAiAAB5sFnR7hvKtgxKEf3K +thoAIFqwK6I6DU0K/dKXIgDDxuAsojkZyrsYyyP9ywEOALtvEC8hBw8PSv3LHh/ABD/g/sq2HgkA +T/CfsPwiACMwEHgwn7eXtve2CCAYEEgwmbOesvi2BS/ABDmg/rYJIAMQQDD4yREMCQBrMPy2BCgJ +AEZwmbEfyvEopjkuIhIP7gL+JhIgoAB/sCsiGIu3/iIAIgAAULD7sg4gBhBgMPjK5RAAEGgw/woG +IAQQSDD5tBAvgAQ7oPe0ES4JAHuw/rYBIAAQeDD4FgAgABBwMFnSdmAACwD6IhAiAABYsFjd8P8C +AAP/YIDgiicPAgCMrPqsMCAAEFgw+s0MAZACYzANyzlYgVD8yukQMBBYMP0sAAIAABqw+goFIgAA +cPBZ0aPSMNEPAC4aAA7dAi0mEmP+iC8qAA/dAi0mEmP+hysgB9xw+wtBAgAAULD7vBggABBoMFiC +cAUDR2gyA8Ag0Q8eyo+eFI0g+xwQIgAAULD8ys8QARBwMPwWBi2ABD9g/t0CAAEQYDD9FgUiAABp +cFiBEMAg0Q/6LAAAMAJZMPwKACADEGgwWIJbY/+sAAD6CgUgMBBYMPzKvxIAAGiwWdF7Y/+RAABs +EAYSyruIMRnKkSIifwiIFAmIAQmIEagiLiAEwYj/MBAgNgRDsP0iACACEFAw/MqxEDYQWDBZ0WzA +INEPKiIYjqf+4g4gAKkH4P8CAAIARwPg+AqPJcYCO+AvMBH/AgAGAJPH0CkiEsC4C5kCKSYSKDIX +KCYXJTIYJSYWLzISL+YSHsqdjar7IhIsPAF4MP/vUQwJAHdw8v8QDlgBaDD0zBAPYAQ7oP/MAgoJ +AHbw/aYKKgkAYvAqJhIpMhL9CgIiAABY8PkJUwIAAGEw+SRpIgAAULBb/xnAINEPjDePMyQxCSTl +CZ/jjTLzIhgkABBIMP3mAiABECAw/cpWEBYAfzCIqgmIApiqiiKLOvQkBS/9EGAw/b0CDgBAYrD+ +JgIqCgFcMP02Ci4ADWaQ2iBY/i4YykkvMhEI/wIvNhFgAAkAANogWNMMZK7tiSJkkHj+IgAiAABQ +sPjKIBIAAFhw/8o/EAEQYDD/FgIvgAQ7oPgWAC4JACOw/hYBIAIQaDBYgKLAINEPAPosAAABEFgw +WBFfwCDRDwCNMy8xCS/lCZ3j/DICIgAAULD85gIgABBYMPkwJCACEGgw+eQkIAAQYDBY1fvAINEP +KyAH2iD7C0EAABBgMPu8GCAAEGgwWIHcY/9rbBAG88pFEgAAQPAiMoMqIlsVykMtoQQsoQUuoQKL +oP3c/y3ABDsg/N0RAf4Cc7D+pQIqACBu8Ay7DGAALAAroQUsoQT+ogAgAgJa8PsLTwH+Answ+6UF +JgCWXxAM/xH/6wgNwAQ+4A27DAALi8DADMxg8AuAD5AAuyAZygAroQUpksIJuxH3Mn0qACBfMKuZ +CZkRqXf2cgcgIxBYMCt0BCkiXoZu88odEAICSnD5Jl4iAABJsG1JBQAIhgBJYSpgENMP0w//AgAA +AIIGoPtcxCJ2ADqg/wIAAgDRhqD5CgAkAFmaoClWmSlWmilWmylWnPlWnSIAAELw+VaeIAsQUDBt +qgf5hq8gCAJCMClSmSlkFChSmihkFS9Smy9lCy5SnC5lDC1SnS1lDfxSniIAAFGw/GYNIAsQSDAP +AgDTD9MPbZoP+bKvIAgCWvD5pQ4gBAJSsPp8AAIAAFmw/EwAAgAAaPD1ycoQABBAMPhkESAAEHAw +9RYAIAAQeDBZ0WDAINEPAMCQKaUF8/7PYAAQWDAAAAD6fAACAABhMP08AAIAAFmw9cm6EAIQSDD5 +ZAcv6hBAMPhkESAAEHAw9RYAIAEQeDBZ0U7SoNEPAAAuIlku4QMuZBQtIlot0QMtZBWMIioiGCsi +FSzBAyxlCyuxAytlDCqhAyplDVjWeCIiOQ8CAA8CAIwgiyf+Ig4gjBBAMPzBAyCoAkiw+mYNIOAC +aLD8ZQ4gAxBQMPuxAyAUAmGwbaoq+8UKIDgCWjD6kgAoACBEsP/hAyBwAkIw/tIALAAgXLD/xQsg +CAJjMCuhAyvFCi/hA46QjdAvxQsu4QMuxQwt0QMtxQ1j/tgALCJZLcECLMEDDcwMLGQUKyJaLLEC +K7EDDLsMK2QViiIroQIqoQMpIhULqgwqZQsqkQIpkQMoIhgKmQwpZQwpgQIogQMJiAwoZQ1Y1kUu +UmQtIjksUmGL0K7MDKwM+rECIBwQQDD8Zg0gChBIMPuxAyAEAmGwbZob+NkIAAQCYzD5kgAgOAJC +MAq6DCrFDCqRAiuRAwq/DC/FDWP+OgAAAGwQDiocGPs8AA//EEAw+BYEIDAQYDBZx+IpMBBokU1o +kgPAINEP2jBY1xX7ChYgBwA2oHKhWvnJThIAAFCw+w4GAgAAYTD7HBggAhBoMP20ByABEHgw/rQR +IAAQaDD5FgAgABBwMFnQ39Kg0Q/aMFjXBPsKESAHADagY/+4KTAe0w9okSZokkHz/6pgExBYMACL +p4u+/zAQIAMQYDD/tBAgAhBoMFjWEsAg0Q+KOFjiG/WsAA/TADag2jBY1r/OofP/cmAcEFgwAAAq +PCD7PCggIAJgcFjh1vWsAA/dALagY/+kLlAHL6AH2zD4CvwgAxBgMPj/AQ4gAXAw9aYLLgkAe7D+ +pAcgAhBoMFjWL8Ag0Q8AAGwQBIgo8yIQIC8ANiD7CnAiAABQsFnRIm9DGMlF+iIIIA4ANODAsFgQ +NcAg0Q8AwLNYEDLAINEPiyeLvhzI/xrJA4uxGcksKqKkC4sU+ZKPKgBAZvCrqgmqEaqZmShj/6sA +AABsEAYjIAeKIsBC9CGVYiABHDD+pw1//RBAMAioAZgiYAASAMiuWc/B26D8+v8iAABQsFh7QRzI +lww7Ef7I1xoAIGbwKbI6Dj4K/uJ/IgChwmAtsjkfyLD+2gEOAJr3UB7Im/APBwIAAEqw/8iWH/AQ +QDAASWEASWGfoIwgwNj+pgIpgAQ/IP2mAygJACZw+aYBJgCIxpAYyMEIyAIopgQqIgcktjn0oA9g +YAJasCmiDP8CAA4AZVpQ8woAII0ANqD/+sAgQAJysPyiDC4AQHuw86UUIIACc7D+pgkgYAJqsP6m +CC4AR+sQGMiu/MiFH/8QSDD5pgAgEAJasPMmByoAWdYQKMJ9H8inm4Gfoy7CfZ6iLcJ/+8Z9IAIC +a3Atxn8jJAQjJAWTIiMkICMkISMkIiMkI5MpkyqTK5MsIyUa8yUbIAAQEDDRDyMkBCMkBZMiIyQg +IyQhIyQiIyQjkymTKpMrkywjJRrzJRsgABAQMNEPANogWPx+iidj/2oA2iBY/HvaIFjZn4onY/8q +AAAA+iwAADACWPD8CgAgAhBoMFiATYkiZJBPBQpHaKJlwCDRDyjCgC/NApuBn6MuwoCeoi3CgvvG +gCACAmtwLcaCIyQEIyQFkyIjJCAjJCEjJCIjJCOTKZMqkyuTLCMlGvMlGyAAEBAw0Q8rIAfaIPsL +QQAAEGAw+7wYIAAQaDBYgDJj/5QAH8hTnxCOINog+xwAAAEQYDD9yJsfgAQ7oP0WAi4JAGOw/hYB +IgAAaXBYftXAINEPbBAGGchGmRCIIP1MAAIAAFCw+IgRAAEQYDDzFgIoCQBiMPgWASIAAFhwWH7J +0Q8AbBAGF8hkLXKOnREt0hgo0QP/AgAAAPOmIPMKACAAEFgw/AqXIJkQeDD2yFIQcAJQsPoWACAB +ECgw8ABEYJYQUDDH7Q7eAZ5CiUjJkI1JmdCOSP3mASAAEEAwmEiYSY0RiS+OEP3SGCBAAkEwmJCZ +SZ5ImC8u0QOxM/8CAAgAY/TQLtEEiNDzWRQPwAQ7oP6ICAngBD5gCYgMKI3/+II/LoABGDAA4QQA +WRrw4AQIAEBKMAgIGWSPuyhirCRyiKg4CYgRCEQIKEIKcomnLkAFeuGhfOGeKUBFaZGY/+FZcAIC +WvAtCpp94U4oCph44UgpCpv7FgImAFdPkI1C+xICL0gAN2D/AgAD/5z7UB7IMP8CAA//mu+Q+xYC +INkAN2DAsG0IEC76AH3gQw2NFPTQVWAQAlrwY//omxIYyDqYS2P/twAAZLC0GcgmiiJ5oAQKK1PJ +tisgB9og+wtBAAEQYDD7vBggABBoMFh/vtEPx+B94AwNTRTwAAZgCAJa8LG7DR0UZd/3+kwAD/8Q +YDBYek0qCpb7EgIglxBgMPP+qGCZEHgwiEz/AgAB/6h+EIsRLkIWLUEzK7I5/o4UCGABdDAJmQ8L +mQr7kgYgBgJrcA0tEomRDrsoLUUy/cgCG6AEPuD9RgsoACBecClGF2P/CQAAAADz/45gABBYMPoi +ECAEEFgwWBAe0Q8AAABsEASIJxvHo/f6wCAEEFAw9YkUIgAAMLDyggkgQAIiMPmBFSQAQDkw9ExA +IIACKXD1hRQhgAIQsPKGCSoABCCQopKSiQALi/3HphIAACiw0w9tqgIARWGdIIxg+MwRAAQQaDDz +JgIsCQBrMJwh0Q8AbBAYkhCOIBXH6YkjiyGKIioWIisWJPkWIyABECAw9BYHIAAQQDD4FgUgBBBg +MPwWCiADEGgwnRn1FgYgAhB4MC8WCPXH2xAKEHgw/xYQIAsQaDD9FhEgDBBgMPwWEiAIEEAw+BYO +IAkQIDD0Fg8gBxBIMPkWDSAFEFgw+xYLIAYQUDD6FgwgDRBYMPsWEyAOEFAwKhYU9MfHEA8QSDD5 +FhUgBBBAMCgWBIYWiRUnYX4iYX8HmSgrEiT8EiIoACBMsPhC8ChgAUwwA5kK/pIAIgAAU7AmYj4t +EiP/UIAuACBDsAtgAI4XB+4oLBIk/RIiLgAgcLD4QvEuYAFwMAPuCo7gL1CB+hYWIgAAWrD6EiMu +ACBDsAtgAI4YB+4oLBIW/RIkLgAgcLD4QvIuYAFwMAPuCo7gL1CC+hYXIgAAWrD6EiIuACBDsAtg +AI4ZB+4oLBIX/RIWLgAgcLD4QvMuYAFwMAPuCo7gL1CD+hYYIgAAWrD6EiQuACBDsAtgAI4aB+4o +LBIY/RIXLgAgcLD4QvQuYAFwMAPuCi7iAC9QhPoWGSIAAFqw+hIWLgAgQ7ALYACOGwfuKCwSGf0S +GC4AIHCw+EL1LmABcDAD7gqO4C9QhfoWGiIAAFqw+hIXLgAgQ7ALYACOHAfuKCwSGv0SGS4AIHCw ++EL2LmABcDAD7gqO4C9QhvoWGyIAAFqw+hIYLgAgQ7ALYACOHQfuKCwSG/0SGi4AIHCw+EL3LmAB +cDAD7gqO4C9Qh/oWHCIAAFqw+hIZLgAgQ7ALYACOHgfuKCwSHP0SGy4AIHCw+EL4LmABcDAD7gqO +4C9QiPoWHSIAAFqw+hIaLgAgQ7ALYACOHwfuKCwSHf0SHC4AIHCw+EL5LmABcDAD7gqO4C9QifoW +HiIAAFqw+hIbLgAgQ7ALYAAuEhAH7igsEh79Eh0uACBwsPhC+i5gAXAwA+4KjuAvUIr6Fh8iAABa +sPoSHC4AIEOwC2AALhIRB+4oLBIf/RIeLgAgcLD4QvsuYAFwMAPuCo7gL1CL+hYgIgAAWrD6Eh0u +ACBDsAtgAC4SEgfuKCwSIP0SHy4AIHCw+EL8LmABcDAD7gqO4C9QjPoWISIAAFqw+hIeLgAgQ7AL +YAAuEhMsEiEH7igtEiD/UI0uACBwsPhC/S5gAXAwA+4KjuCaE/oSHyIAAFqw+xYBLgAgQ7ALYAAu +EhSMEQfuKC0SIf9Qji4AIHCw+EL+LmABcDAD7gqO4JoS+hIgIgAAWrD7FiMuACBDsAtgAC4SFSwS +IwfuKI0T/1CPLgAgcLD4Qv8uYAFwMAPuCo7g+hIhIgAAOrAnFiL47ggCAABZ8AtgAI4RKhYkKRIS +LRIVjxUrEhMsEhT4EhEgIAJ78P8WBSAgAlrw+xYTICACYzD8FhQgIAJCMPgWESAgAmtw/RYVICAC +SnApFhKNH4kciBuMHosd/xIQICACQjD4FgsgIAJjMPwWDiAgAlrw+xYNICACe/D/FhAgIAJKcPkW +DCAgAmtwnR+JFo0Zjxr7EgcggAIhMPwSCCAgAmtw/RYJICACe/D/FgogIAIpcP8SBCAgAmMw/BYI +ICACWvD7FgcgEAJKcPkWBiH+Anvw/xYEK+8At+CJEIsSjxOOkI2RjJL4kgMuACB7sP6WACwAIFdw +/ZYBLAAgOzD8lgIoACBaMJiT0Q8AAGwQBCkiFSv6gNMP+QlFADcQQDD5jAwKACAScPukECAgAiCw ++qwRLABcyhDAsFnFESwiFSsiFPHUBA3QBD8g/SYSIgAAQLD8uxgAAxBIMPsmEyACEFAwbaoMjoQE +7o7+hgQgCAJCMA8CANMP0w9tmiH5ggQgIAJCMIqBi4KMgwSZjgSqjgS7jgTMjpmAmoGbgpyD+0wA +AgAAULBb/p2KIIgiiSGPIwSIjgSZjgT/jgSqjpognyMpJgH4JgIiAABAsBnGBQAChgBDYfAJFwAL +EEgwbZoCAAiK0Q8AAAAAAAAA+woAIBACYzBZxOL4LAAABBBIMNMPbZoh+YIEICACQjCKgYuCjIME +mY4Eqo4Eu44EzI6ZgJqBm4Kcg/osAAIAAFkwW/572kDz/wBgOBBgMABsEAYqIhX4IhQgQBAwMA8C +APpKCAigAVQw+WYMCgADopAojAEoJhQqJhUGKgz6rFAqAHu1EPs8AAIAAGGwWcS2+CwAAAQQSDAP +AgDTD22aIfmCBCAgAkIwioGLgoyDBJmOBKqOBLuOBMyOmYCagZuCnIMlLBD6LAACAABZcFv+WAZH +DP8CAAwAV0Xg9jQIAgAAUXD2fAAAABAYMPQWACIAAEEw9ggWAAQQSDAASmcECIYASmUCCIYASmMA +CIbwCqACAABAsG2aIfmCBCAgAkIwioGLgoyDBJmOBKqOBLuOBMyOmYCagZuCnIP6LAACAABZcFv+ +O/pcAAACAhjw9mzAIIACITD/bZpiAABBMIsQ+jwRAgAAUXD8fAwKACBfMFnEftEPAAAAAPs8AAIA +AGEwWcR50Q+mPJwQ8//QYAAQGDAAAABsEAQYxhYZxhQaxhITxhWTI5gimSH6JgAgABBYMCsmFSsm +FNEPAAAAbBAG3iD04hAiAABhMBvGBvdCByIAAFHw/1z6IBMQQDDzQhUiAAAQ8PdyDioAFEPQGMYD +mhMI+AqIgJwSnhEKgACTECqyofxcAAIAAFiwWcj0ZKXH80YVIAAQEDDRDwAAAAAr4hILm1L+FgEv +6AA24BrF7vMWACIAAFiw+qLDIgAAYXBZyOdkpXoaxefbIPqixSIAAGFwWcjiI30F9KbVYQACGPAa +xeHbIPqixyIAAGFwWcjb9KaGY4AQMDAaxdvbIPqiySIAAGFwWcjVZKbHGsXW2yD6ossiAABhcFnI +0P8CAAAELKqgKzDlwVj/AgAEAr4q0Gm3ISU05YsQ+0YVIAAQEDDRD5MQKrKZ/FwAAgAAWLBZyMNk +pwqLEPtGFSAAEBAw0Q8AkxAqsqf8XAACAABYsFnIu2WvGvocAAALEFgwWNea+woBIAAQGDD6szgA +HAA2oPoSAiIAAFmwWcTOyKkcxbeNEQysNizWF2UzJY0Q/UYVIAAQEDDRDy5AbmTu0pMQKrK9/FwA +AgAAWLBZyKRlrr/6HAAAFhBYMFjXg/sKASAAEBAw+rI4ABUANqD6EgIiAABZsFnEuCx9AyrFKGUi +0Y0Q/UYVIAAQEDDRDwAAkxAqsq/8XAACAABYsFnIkGSitxrFkdsg0w/6opsiAABhcFnIi2WuWvoc +AAAFEFgwWNdq+woBIAAQEDD6sjgFAAA2oPoSAiIAAFmwWcSeLEBv/wIAAAJ1bxBkpOKKE/sKBSAN +EGAwWNdF0qDRD5MQKrK1/FwAAgAAWLBZyHVlrsf6HAAAEhBYMFjXVGSiNStAbmS3cvoSAiIAAFmw +WcSKLEIWCsw2LEYWixD7RhUgABAQMNEPkxAqsrP8XAACAABYsFnIY2SiMxrFZNsg+qKtIgAAYXBZ +yF5lrm36HAAADhBYMFjXPmSh2/oSAiIAAFmwWcR1K30CKrUUixD7RhUgABAQMNEPkxAqsqX8XAAC +AABYsFnIT2SiKhrFT9sg+qKxIgAAYXBZyEpko4caxUvbINMP+qKfIgAAYXBZyEVlrgf6HAAABxBY +MFjXJGShdStAbmS25hrFQIsS+qLrIgAAYbBZyDtlpkgrQG/AyAy7AitEb4sQ+0YVIAAQEDDRDwAA +kxAqsrv8XAACAABYsFnIMGSh7xrFMdsg0w/6op0iAABhcFnIK2Wtn/ocAAAGEFgwWNcKZKENK0Bu +ZLZsGsUmixL6ousiAABhsFnIIWSmfCtAbywK/Qy7AStEb4sQ+0YVIAAQEDDRDwCTECqyo/xcAAIA +AFiwWcgWZKG3GsUX2yDTD/qilyIAAGFwWcgRZKLaGsUR2yD6orciAABhcFnIDGSsXxrFDdsg+qK/ +IgAAYXBZyAdlrEwaxQiLEvqi2SIAAGGwWcgCZaRdixErshILmVLImWiSB/8CAAIA9h5gjBErxhLz +RhUgABAQMNEPkxAqspP8XAACAABYsFnH9WShehrE9dsg+qKVIgAAYXBZx/BlrLT6HAAAAhBYMFjW +z8qiGsTtixL6ousiAABhsFnH6GWslIoT+woCIA0QYDBY1q/SoNEPwCDRDwAAAPocAAAPEFgwWNbB +ZK/q+hICIgAAWbBZw/mLECx9AirFFftGFSAAEBAw0Q8AAAAAAPocAAAREFgwWNa1ZK+6LUBuZNUI +KUBv/wIAAf4ZelD/AgAB/hV+UPoSAiIAAFmwWcPnLkIXCu42LkYXixD7RhUgABAQMNEPAPocAAAK +EFgwWNajZK9yL0Bu0w9k9Hn6EgIiAABZsFnD2ShBNP8CAAoA9FIQihP7CgogDRBgMFjWgNKg0Q8A +AAD6HAAAFRBYMFjWk2SvMvoSASIAAFkw/BICIgAAabBY1fKLEPtGFSAAEBAw0Q8AAAD6HAAACRBY +MFjWh2SvAilAbmSUHBrEpIsS+qLrIgAAYbBZx55lomUrQG/9EgAgARBgMP1GFSoJAGbw+0RvIAAQ +EDDRDwAAAAD6HAAAARBYMFjWdWSuuhrEk4sS0w/6ousiAABhsFnHjWWrKYoT+woBIA0QYDBY1lTS +oNEPAAAAAPoSAiIAAFmwWcOi/wIABAFlBqDHL9EPAPocAAAIEFgwWNZh+woBIAAQEDD6sjgAKQA2 +oCxAbg8CAGTDhhrEgfsSAiIAAGGwWcd1ZaJ6LUBvwOgO3QItRG9lLjWPEP9GFSAAEBAw0Q8A+hIB +IgAAWTBY1ldlr5wrMOVj+nMAAAAA+hwAABAQWDBY1kdkrgIoQG7TD2SC9/oSAiIAAFmwWcN9KUIY +ixD7RhUoAwBWcPlGGCAAEBAw0Q/6HAAAAxBYMFjWOWStyhrEV4sS0w/6otEiAABhsFnHUfPEWxDp +ALagixErshILyVHImWiSB/8CAAP/kR5gjhH8EgAsAEAe8C3mEvxGFSAAEBAw0Q9lLYGPEP9GFSAA +EBAw0Q8AAAAAAPoSAiIAAFmwWcNaKkU0ghDyRhUgABAQMNEPJX0E9VyAIAAQWDD6XAAAgBBgMFnC +ofoSAiIAAFlwWNZTKzDlwMQMuwL6NOEq4AFcMCs05WP5dC0w5cDi+hICLAkAd3D9NOUiAABZsFnD +Qysw5So05GP5UwCKElmfti8w4n+pFYoSWZ+zK30E+hICIgAAYrBZxxtkobfAovzEJBAwEFgwWcrM +xy/RDxrEF4sS+qLTIgAAYbBZxxJlrjqLEdMPK7ISC8lRaJEKaJIH/wIAA/8TnmAexBcDvQH+EgEs +CQB3cIwQLeYS/EYVIAAQEDDRD4oT+woJIA0QYDBY1czSoNEPAAD6HAAABBBYMFjV32SsYhrD/YsS +0w/6otEiAABhsFnG9/PEBBCsALagixErshIL6VHImWiSB/8CAAP+3R5gjhH8EgAsAEAe8C3mEvxG +FSAAEBAw0Q8aw+yLEvqi2yIAAGGwWcbmZa2LixErshILmVJokQpokgf/AgAD/r0eYB/D2IIR/X0F +LgkAfvD/JhIhAAJrcCzQ5cDhDswCLNTl80YVIAAQEDDRDwCKE/sKCCANEGAwWNWd0qDRDyN9BSM8 +gCsw5cDBDLsCCwtHKzTlY/f1GsPNixL6otMiAABhsFnGx2WtD4sRK7ISC+lRaJEKaJIH/wIAA/5/ +HmAdw84DvAH9EgEsCQBrMCzWEosQ+0YVIAAQEDDRDwAA9nYIAAAQWDD6bAAAgBBgMFnCIsFQ+hIC +IgAAWbBY1dQrMOUFuwL6NOEq4AFcMCs05WP3eSsw5cDIDLsCCwtHKzTlY/doihP7CgcgDRBgMFjV +cNKg0Q+KE/sKECAMEGAwWNVr0qDRDwCKE/sKCiAMEGAwWNVn0qDRD4oT+woJIAwQYDBY1WPSoNEP +AIoT+woIIAwQYDBY1V7SoNEPihP7ChIgDBBgMFjVWtKg0Q+KE/sKESAMEGAwWNVW0qDRD4oT+woG +IAwQYDBY1VHSoNEPAIoT+woHIAwQYDBY1U3SoNEPihP7CgYgDRBgMFjVSdKg0Q8AAGwQBIgiZYCg +KCAHGcL3+jIFKCABQDAMhhH7wvQWACBJsPliOiA+AiKwBEQUC4sK+7KXKgBAplApYjkcwwv7nQEO +ADneUPAMBwIAAENwbUkCAEhhG8Lxm9CJIPgyBCBAAmDw/sLvECACW3D+1gIpgAQ+YPrWAygJAE0w ++dYBIgAAULALgAAFDEf0ZjkiOgA7IIon+woKIAAQYDD6rCAgChBoMFhuqtKg0Q/AINEPAAAAAAAA +APosAAIAAGkw+4wYIAAQYDBYetnAINEPAGwQBisxEtMP+wpLAgAAILD5wxQSAAqioHqSDSwhGwwM +S/8CAA4Bw1MQikeKrietBCKtAvUiniAEEEAwKCaAjDonfLD2fAAA0QA1YGTAySsin/vNAQoAQF1w +fbEFLCKlZMC1LUBY+hYBIgBbg2D9XAACAABRMP4KACABEFgw+0RYIAAQeDBZNGb1rAAAbwC2oCki +gbGZ+SaBJAGXkmDZMAgJhgBHaQYJhgBHZwQJhgBHZQIJhgBHYwAJhgBHYYJH+sK5ECACELBb5lcc +wrYdwyQewyWPQPusAAIAAFCwW+YPgkcPAgAPAgAiLBDaIFvhpv8CAAABbgagZFAU2kD7PAAAABBA +MPhmFSIAAGFwWToEwCDRDwAAAADz/99gFhAoMPrDEhAGEGAw+hYCIAAQWDD7JoEgBRBIMPkmgCC0 +AlkwWcFbGsMK/AoGIHQCWTBZwVgdwwf/wq4QABBAMPjUgSABEEgwKdR//9R9IEAQcDAu1H4u1Hz7 +0HYgABBQMCrUgPrC/RDwEGAw+tR1KmABXDD+CgAqCQB28PwKBSoAQGbw/tR4KgkAZvD1jhQAVBBg +MCzUeQ6PFCvUdv+JFAAIEFgwK9R0jDov1IMu1IQl1IUo1Iv81IkgCBBYMCvUigyMFCnUgizUiAyM +FCzUhwyMFCzUhgnqMCrcf7+q+aQBIAAQcDD5iRQA/gJ7cPmkACAaAnvw/DEPIP4Ca3D+9AAgIgJr +cCzUASj0AQyMFCzUAFnGjVnGgx3CzygKAQ8CAPvVTC/wAVgw/tVLLfABUDD81UkgOAJLcPrVSiAG +EFAwbapC+JR+IAICUjD7jAIgBgJiMPqUfyAIAlIw+5SAIAoCWjD8lIEgDAJiMPqUgiAOAlIw+5SD +IBACSnD8lHwgEAJCMCqUfRjCs/rCtBAAEHgwDwIA/4SNIAAQeDD/hIwgQBBYMFk2qhnCqwqIFNMP +KpSNKJSM/TEMIgAASPACCYYAR2MACYYAR2EOCYYAR28MCYYAR20KCYYAR2udEFnGWlnGUPwKACPo +EGgwWcqdKyaFjBIbwpiOESomhCmwjiuwjx3Cl/iZEQIAAFEw/u0EKAkAXnD55Q0gCBBYMFhQUPWs +AA27ALagJxIAGMIX/AoBIAAQUDD3yjgAHhBIMPxCByYFAFZw+HcoAAYQWDArJoD6fAAAIAITMFvl +q/3CJRIAAGHw/sKAEgAAWrD/QgAiAABQsFvlYoJHDwIAIiwQ2iBb4Pr/AgAB/qoeoGAAgNogWTpu +9KwADHUAtqD0LAAAFhAoMPP9N2AAEDAw8/0vYAIQKDDaIFvhDRLCawuoEfSgOWIAIECwDOowKyKF +i7Cwovy7CAIAAFCwWcwMHMJkKsJ/8CEEAAEQWDAAuxoLqgIqxn9ZzEFj/OIAAAD6CgcgARBYMFhw +PSwifywmg2P8y9ogW+D2EsJUC6gR9KA9YgAgQLAM6jArIoWLsLCi/LsIAgAAULBZy/Ucwk3TDyrC +f/AhBAABEFgwALsaC6oCKsZ/WcwpY/yEAAAAAAD6CgcgARBYMFhwJSwifywmg2P8a2wQBoQnhE4j +TQIoMrIl+v/7MrQiAAgiIGiwCAIqAlk16yU2tCggOi8gPysgOywgPC0gPS4gPi4UDi0UDfwUCiD+ +EFAwKhQMKhQA+xQJIAIQSDD/FA8ggBB4MP8UASgRAEowKBQI+E0DIP8QEDDyFAsgABAQMCIUByIU +BiIUBSIUBCIUAyIUAosQjBGNEo4TLjaxLTawLDav+zauIEAQUDAqheslNrf1NrYgARBIMCk2siKF +6tEPAABsEASFJ/kKQC//EBgw9VIOIAAQODAmXQUoXQMkXQIpRqojRu4jRu8lXQYjhfMjhfInRrIj +ZRMjZRL3RsIg4AIxsCZG3PZG3SGIAilwJUbxJUbyI0aC0Q8AbBAE+iwAAgAAWPD8CiogABBoMFjm +0S5ADi1AEC9AEfjdEQ5gAXAw/u4RDAkAf3AO3Qwt3Pj9DU8AOBBgMA3MNAwMT/zMKiIAAFkwWcAy +wCDRDwAAbBAE+zwAAgAAULD8CiogABBoMFjmvClADihAECtAEcNY+IgRCGABTDD+mREICQBaMPmI +DAAAEDAw+Iz4IgAAGrD6TCIo4AFAMPZEIiQBAMVw9kQlJOABLDD2RCQgEAJZcFk1xttA+kQlIFQC +YXD5QA4gBRBoMPfBaRDwEHgw90QVIEAQcDD+RBQoYAFMMP5EFigJAHZw+o4UCABAfnD+RCQoCQBu +cPlEDiIAAFDwWcAE2jD8CgYgDAJZMFnAASssOvwKBiAMAlDwWb/9K0AaLEAb/UAcK4AEPuAMuwL8 +QB0rgAQ+4A27Agi7EQy7Ais0IQuLFCs0IAuLFCs0HwuLFCs0HipAHi5AH/tAISA4Amlw/EAgK4AE +OqD2NBkqCQBysP00ESuABDqg/Y0UCgkAYrD9NBArgAQ6oPaMFAoJAFqwKjQdLDQYCooUKjQcCooU +KjQbCooU+jQaIAAQEDDRD2wQBMePCFgDCDgCCEgDqGjwcQQCACBAsAIiGKIy0Q8AbBAEBDgDCFgD +qGjwcQQCACBAsAIiGKIy0Q8AAGwQBAQ4AwhYAQhIA6ho8HEEAgAgQLACIhiiMtEPAAAAbBAEBUgD +CDgBCFgDqGjwcQQCACBAsAIiGKIy0Q8AAAAAAAAAbBAEE8EXAyIC0Q8AbBAOKiIQ0w8ooAUpCpJ5 +iRspIhL0CoAgKgAycPPBWhAaAOJwcJcMK6BuaLEbwCDRDwAAAPzBXxDsAD5wDJwB/CYSIAAQEDDR +DyMiGB/BD446jSIkCgH+q0AOCQB7sP42CiC+ADdgAioCWPTsGcEIKDIRCYgCKDYRiiJkoK4fwOOf +FI4g2iD8CgEgIAJYcP/BAB+ABDug/xYGLgkAI7D+FgUgAhBoMFh3ZsAg0Q8AiK4bwOn4jAEgYAJI +cPimDigJAFow+JQDL/8QUDCaHQiIFCiUAgiIFCiUAfiIFABAAlhw+JQAIgAAULBY7aAvIhLaIPwK +AyBAAlhw8/8CAAAQaDD5wSweCQAn8P8mEiAAEHAw+RYAIAAQeDBZyH/AINEP2iBYyaJlr09j/wEA +KyAH2iD7C0EAABBgMPu8GCAAEGgwWHiQY/81AGwQBCUxDQxVEfosAAIAAFlwWDha+6wAAEcANqAY +wJcqMQ0ACIv4vAAADQA2oG2pAgBIYSoxDW2pBQAEhgBLYdog+woAIgAAYXBYOBApIhIq+n8KmQH5 +JhIgABAQMNEPxy/RDwBsEAwuIhiJQP3AwRAAEGAw+OIKLjwBTDD8JhYqPgFMMPMmECpZAUgw96oQ +CiAEPuD0/xAINwFMMPmZEAhYAUAw+/8CCWAEOiD6/wIICQBKMP0mFy4JAEfw/yYSL4oQaDAt5Hic +FCwVCioiEisKgPnAfBoJAFqwKiYSmRCIIPTA4xACEGgw/AoDIgAAWHD4iBEABBBIMPQWAigJAEow ++BYBIgAAULBYdvv7HDAiAABQsPwKASACEGgwWHb2iiJkoEeCN/rA0xAgAhCwW+P0HMDQHcDCHsDQ +jzD7rAACAABQsFvjrII3DwIAIiwQ2iBb30T4oSpgARAgMIg8BIgCmDzRDwAAAAAAAAD6LAACAABY +cPwKBCACEGgwC0AAY/+h2iBb31cSwLYLqBEPAgD0oDhiACBAsAzqMCsihYuwsKL8uwgCAABQsFnK +VhzArSrCfwAhBABLGguqAirGf1nKjIw8BMwCnDzRDwD6CgcgARBYMFhuh408LiJ//iaDLAkAJ3Cd +PNEPbBAEF8ADGMCjGcBWLzENKIKGKpK1+Z3mIgAAaLD5kMEvwAQ/4P78PyuQBDqg/k4UCAAgUjD2 +jQEgGAB+cPAACmEAAjGwJo0DJmyAKWAHCQhBDIIR/L/wEgAgOLAqIjov/DD8jAoAAgI7sPzClyoA +RT6QKyI5GMAG/LoBDgA+ZtDwCAcAHgA7oNigbXkCAEhhKWAH+9IAIgAAcfD9CgEsAgFIMFnIBi5g +BythKfzAex4gAXAwAO4R/rsCD+EQaDD9pAgqCQBm8Jug+jAYIgAAQrAqhAkqMQ0MqRH5hQcgEAA2 +oCmMEG2pBQAEhgBJYfcmOSAAEBAw0Q/HL9EPbBAMKyIYi7eLvioiECOwHy6wHCywIC+wHS2wIfjM +EQ+ABDug/7AeLgkAe7D9sCIsCQBrMPjMEQ+ABDug/7AjLgkAe7D9sAAsCQBrMPjMEQ+ABDug8+4C +DAkAezD+yAwAPxAYMP0NRQAAFCIgL6IS/+gMABQEc/BmgAIuphIuohPTD/7JDAAUBGOwZpACLKYT ++NxmYCMQUDD8CiQmAL/XUP4KJiYA1udQ/woyJgDsd1D/AgAGAQr/UHPREMCi/MA4EDAQWDBZxsrH +L9EPKLAYKbAZ+rAaKYAEOiAJiAL5sBspgAQ6IAqIAgiIEQmIArGI+CYWIAAQEDDRDyMiEGQwdSmw +ECqwEfywEimABD5gCpkC+rATKYAEPmAMmQL9sBopgAQ+YPywGSgJAFZw+rAYIJgAOmAIqhEMqgL8 +sBsrgAQ6oA2qAgiqEQyqArGq+iYWIFYAOmApIhLTD/vAEhAUAEJwC5sBKyYSLDAFLQqV/wIABgCj +bxDAINEPAAAqsBQssBX9sBYrgAQ6oAyqAvywFyuABDqgDaoCCKoRDKoC9AqAIWYAOqAsIhJ4z8n6 +jxQASAJAcCqEA/+EAi//EEgwmRgPjxQvhAH/jxQAMAJocP+EACAQAnLw8Q4WACACWHDyHR4CAABQ +sFjsVikiEvscECIAAFCw/AoDIAAQaDD4v+IYCQAmcPkmEiAAEHAw+BYAIAAQeDBZxzVj/0wqsBgs +sBn9sBorgAQ6oAyqAvywGyuABDqgDaoCCKoRDKoCsar6JhYiAABQsFjU6cAg0Q8AAAAssBgtsBn+ +sBotgAQ7IA3MAv2wGy2ABDsgDswCCMwRDcwCscz8JhYiAABQsFjUbsAg0Q8tsBgusBn/sBotgAQ/ +YA7dAv6wGy2ABD9gD90CCN0RDt0Csd39JhYiAABQsFjUlsAg0Q8A+jwAAAYQWDBYB6zAINEPAAAu +sBgvsBn4sBovgAQ7oA/uAv+wGy+ABDugCO4CCO4RD+4Cse7+JhYiAABQsFjUCsAg0Q9sEASJPPa/ +YRAAECgw+vp/L4IQWDD7NEEoAEBWcPk2DCAAa35QiTiKIvS/YBBwAliw/DIJIBAANmCVO5nAjTic +0ZU4lTmMLx2/mSgyGCcyEikyFo46JWKO+YkUDmABTDAu4GklUjn4v1wWACBF8A//D/X/CgGAAikw +BeUK9VJ/L+AEO6D08gYuACAjsI/xLuJ/nTsJRCjwUAQOACA7sP7s/yWgBDkg/g4ZDgAgJ/D/Nhcv +4AFwMP41MyAGAnOwDi4S/jUyIEACSPCZwJs4nDn5Jg8uAAVGkAooU2SA2CsgB9og+wtBAAEQYDD7 +vBggABBoMFh22tEPjED++pcgGAArMP8CAAAAc95QLTBs/jQFIBIAN2CJNyuZFMi1ipnIoVjHlYk4 +8mKOL5YQUDD/MgkgEQA2YJU7mfCIOJ+BlTglNgmJPPo0BSBgAH5wKjIW+osUCmABUDD6qg8AvABS +cC0iV/2qCgAAEGAw+qIAIAEQaDBYagwlNhaIN4sw+frAIEACejD1NgwuAEBP8PWFFCCAAnvwn4mf +iC5icfoiGCAAEGAw/rsMAAEQaDBYaf4pMEVokShokhrRDy0iOf2qCgAAEGAw+qIAIAEQaDBYafZj +/6IuIhqw7i4mGtEPAC8iGbD/LyYZ0Q8AAAAAAAD6LAACAABY8PwKAiACEGgwWHWH0Q8AAABsEAoo +IATUIPYiGCAYEEgw977TEBIESjDAINEPAIpqwFH7vyIR5gDOsCoiEiwKjv/67yAAEBAw+64BAACF +fpAtQhP8MQsqBAFQMPVCES4AQHuw/kYSK/8QeDDyRhEsACBrMPxGEyHiADVgiVeOXCiZFBu/D/yS +CS4AQHuw/lYMIfgANiD/AgACAQxbkIjHZIHziTn5sCFyAAAbMInHGr8FCQtLsbv6mgELYAFcMAuq +AvrGByIAABsw/wIAAADGa5Acvv6NUC9SEvhSEyAFEFAw+BYAIDYQWDBZxYUqUhOOXClSEsf9D+4B +/lYMIBgIUnAo+n8I6AGYXIkwDwIADwIA/wIAAABHqlCON2TgGvy+6xA2EFgw/UIAL40QUDD6VEEg +AhBQMFnFcvtcAAIAAFEw/AoCIAIQaDBYdTfyRhEgABAQMNEPL2B4/wIAB/9mZ9AtQAUevtv03r5q +AEBasCsxCypGEo05KEIT/wIACADN65AuQhH6FggoACBaMPhGEyIBCmaQZOJAiez/AgACAGNyUNEP +KlBsyKyJVyuZFMi1ipnIoVjG84lYFr5482KOIBMANmCLWZJbmbCMWJvBklgiVgmOXC36lv1UBSBg +AH+wKlIW+osUCmABUDD6qg8AAHZTkC0yV/2qCgAAEGAw+qIAIAEQaDBYaWoiVhYoUgciVgz5+sAg +QAJ6MPtSAC4AQE/w8oUUIIACe/AvhggvhgkuYnH6MhggABBgMP67DAABEGgwWGlbKVBF/wIAAABc +hmD/AgACAE+CYPJGESAAEBAw0Q8AiOv67AACAABYsPwKACACEGgwC4AA8kYRIAAQEDDRDwAAAAAA +APbvJHIAAGCwiSdlnguPOdPA+/0BCAASW9BkriOdx2AAIQAAAAAAAAD6TAACAABZcFv+1MAg0Q8A +AJ3H+dwAAAkANqAH2QKZx2Xd2WP98QAAAAAtMjn9qgoAABBgMPqiACABEGgwWGkwY/8ULjIasO4u +NhryRhEgABAQMNEPLzIZsP8vNhnyRhEgABAQMNEPAPy+bxACEFAw/kIAIDAQWDBZxPUoQhAogAUp +CpX/AgAH/nhOEIlq/wIAA/5zTlAiQhiMKopC/KtADAkAOzD8JgogigA2oNpAWPHoHr4DLSIRDt0C +LSYRj0Jk8HwZvd+ZFIhABEoC/AoBICACWHD5vfsZgAQ6IPkWBigJACow+BYFIAIQaDBYdGHAINEP +HL5NKBIILeIA/uAFIAUQUDD4FgAgMBBYMFnE0ClCEir6v/JGESgAQFZw+UYSIAAQEDDRD9pAW/3N +Za9KY/502kBYxqplr4Jj/DkAACtAB9pA+wtBAAAQYDD7vBggABBoMFh1mGP/ZwBsEAooIAQqIhgp +Chj5gQhyAAAysMAg0Q+LqhW91B+94Py+LBHgAM7wLSISwEH7Co4gAJR/UP0WBSICUbdQDNgCKCYS +LjAgDg5FaeXHKjA2JjA0LjAwKTA1KDAx+O4RB4AEOaD5IGgmCQBJsPgwMi4JAEOw+O4RB4AEOaD6 +MDcmCQBRsPgwMy4JAEOw+ZwGJ4AEOaDwkAQGCQBRsPYJGQ+ABDug+O4CDgO+kmD6mxEKoAEwMAuq +Ai0hMonzDZks/AoAIHwANmAoUqwr8vUv8vuqiPnVEQmQBDog//IYKgAgRvBtmVko8QSJ8PpXFAnA +BDog+JkIB+AEPeAHmQwpnf/5kj8ogAFQMACBBABHGvCABAgAQD5w+QkZAAICYzD0kBtqACBTcIm6 +cpkRiL75sg0gGAhyMP8CAAYBe7ZQq1uNIPoKAiAwEFgw/L2XEgAAebBZxGjAINEPAAAuoHj/AgAH +/1pfkCsgBRi922S+pvoWCCwJAEdw/SYSIgK5t1CFLIk2JzAgKjEK9xYHIIsQQDD3B0UOAK2qUAoK +TvqsAy/8EEgw+aoBBgF7R5DC5fpZCAAhEEAw+SYMLAkAZ3D9JhIgOARB8P5xFHAxEEAw+HEMcCIQ +SDD/AgAOAwJJ0C4wMCgwMSUhMvkwMi+ABDug+iBoLgkAQ7D4MDMvgAQ7oPsWCS4JAEuw+O4RAAwC +UrDwoAQOCQBDsA4JGfcWBi4ChBJg+pwRCqABcDAMqgIYvVAp8gMr8vUogqwFmSz8CgAgcgA2YC/y ++/qICAeQBD1g/RYFKZAEOiD/8hgqACBG8G2ZTSjxBInw+l0UCcAEOiD4mQgN4AQ/YA2ZDCmd//mS +PyiAAVAwAIEEAE0a8IAECABAbnD5CRkAAgJjMPSQD2oAIFFwibpymQUtsg5+0Xqre4cW/L2KEAIQ +UDD9IgAgMBBYMFnEDCYiGJcWLiAFnhkcvYONFogZjmAvYHiJIPkWACACEFAw+BYBIDAQWDBZxAIq +IhAqoAUrCpX/AgAH/ozekIsYi7r/AgAD/obO0PosAAAAEFgw/AoAIAIQaDBYBn/AINEPAAAAAABk +v6KPGC/weMKh/bAFIIsQYDD7JhEuAflj0CgKmv8CAAYB88dQKQqb/wIABgHuT1AsCpb/AgAGAejn +UC8Kmf8CAA4CYvtQiBb0CggmAMnWEMLF/wIABgDE5hAsMEIuMEAvMDwoMEEpMD34/xEPgAQ7oPgw +Pi4JAEOw+TA/LgkAT/D47hEPgAQ/4PgwQy4JAEfwDO4C+O4RD4AEP+D5/wIOCQBDsA/tDPwiECAA +ESNgJcISf1EIBfgMZoACL8YSL8ITfvEID+kMZpACLsYTjryMFvTuAgAlEGgw/rYMJgCRbxCPFsOB +/wIABgDvR9D/AgAGAVDX0MLC/wIABgItZ9AtEBBk2+dgA7dku+GJvP8CAAP97lpQKkoACpoCmrwo +MCQsMCX9MCYpgAQ6IAyIAvwwJymABDog+r0gGAkAajD/shMpgAQ6IAyIAgqIAaj/L7YTLjAh/wIA +AACy45CMvMLQDcwCnLz7JhEgABAQMNEPAAAAAAAA/goDKHwBaDD/AgAP/oFHkC4wJCgwJfkwJi+A +BDugCO4C+DAnL4AEO6AJ7gII7hH47gIACAJKsPP802oFAHJwAI0gjhUcvQH6CgUgEBBAMP8xCy4J +AEOw/iYSIDAQWDBZw37AINEPAAAAAC4wI8Dx+RIGLgUAc/AutEH9sEEgJRBgMP0UEC//L+JQKDAh +/wIAAf9t/hAoMEIsMEAtMDwuMEEvMD343RENgAQ7IP4wPiwJAHMw/zA/LAkAf3D4zBENgAQ/YP4w +QywJAHdwCMwC+MwRDYAEP2D/3QIMCQBzMA3JDPoiECAAESJgLqISfeEIDt8MZvACLaYSLaITfNEI +DcgMZoACLKYTLDA4LTA5/jA6LYAEOyANzAL9MDstgAQ7IA7MAvqyDC2ABDsgDcwC+bzHEAICYzD8 +JhYqCQAisJq8mbtj/kMAAPsmESAAEBAw0Q8uMCQvMCX4MCYvgAQ7oPwwIS4JAHuw/zAnL4AEO6AI +7gII7hH/7gIAAVzjEC8wTCgwTfkwTi+ABD/gCP8C+DBPL4AEP+AJ/wII/xH14nNuCQBH8CoiEPqi +GCJuADfg/wIACgEzfpAvthItMEguMEn4MEotgAQ/YA7dAv4wSy2ABD9gCN0CCN0RDt0CLbYULDA0 +LTA1wID5MDYtgAQ7IP68mBwJAGsw/TA3LYAEOyD4thUsCQBLMPi2Ey2ABDsg/rYLLAkAazCcvWP9 +bC8wOCgwOfkwOi+ABD/gCP8C+DA7L4AEP+AJ/wII/xEI/wL+vIUQAgJ78C8mFp67Y/06ACoiEQ8C +AA8CAGShViqiByuhHigKkP8CAAoAfsLQLQpg/rzQIAIQUDD8vHgQMBBYMFnC9WP7ywAA8/sDb/8Q +UDAAAAAcvHL5EgUiAABzcP2yACAFEFAw+RYAIDAQWDBZwuotIhLE4A7dAi0mEi0wPiwwPCswQC4w +PS8wQfi7EQ2ABDsg/jA/LAkAczD/MEIqCQB+8Pi7EQ2ABDsg/TBDLAkAazAPuwL4zBELgAQ+4P7M +AgoJAG7wDL0M+iIQIfw1o2AtohJ80QgNzwxm8AIsphIsohP/AgAH/CjfEAy4DGaIRvumEyAAEBAw +0Q8AAAAAAPsSCCAAEEgwKSYRKrIHKTwg+qIOIAMQYDBtygUACYYASmHAINEPia7TD/mcMCAGEGAw +KjwgbckFAgqGAEljwCDRDwAAAAAAAPP4jm//EFAwAAAcvDP4EgciAAB7sP6yACACEFAw+BYAIDAQ +WDBZwqpj+p6KGCwxC4qnv8z7oR4tZAFgMAzNESncMP8CAAv/UU7Qia71z5pgYAJKcGP3mAAsMDgt +MDn+MDotgAQ7IA3MAv0wOy2ABDsgDswCCMwRDcwC+rwYEAICYzAsJhaau2P/OAAAKiIQKqIYDH0U ++hYAIDAQWDD8vBAQAhBQMFnCimP6Hi8wTCgwTfkwTi+ABD/g+iIQLgkAR/D4ME8vgAQ/4An/Avqi +GC+ABD/g8/+6bgkAR/BsEASIIiwgB/SACGwgAWAwwCDRD4knDwIALZkU+pIOLuABKDDzkgkhrAA3 +YBi7O/zGEQIA9Rug/bs5FgAgQbAvYjoNzQr90pckANXD4CliOf2bAQ4A0G5QKSBA/wIAAAC+hmD/ +AgACALACYP8CAAQArAegKgoAAz0C/zEILuABUDD8CgEiAABQsFhzE/MKAC+XECgwLyIS+AoEIJAC +ILDTD/hmOSB+BCPwJvpoKiISpqsssicltH0usiYuxgAtsiYs1gEjtibztichwAJSsFhyySkiEsCB +9JkMAAAQeDAJjzhk/8cqIGz1JAUgFgA2oIknK5kU+pIJIAkANuDIoVjD3YkoFbti+yIJL5YQaDD0 +Uo4gEAA2YJMrmbCMKJvBkyiTKYks/SQFIGAAfnAqIhb6ixQKYAFQMPqqDwDmAFJwLUJX/aoKAAAQ +YDD6ogAgARBoMFhmVCMmFogniyD5+sAgQAJ6MPMmDC4AQE/w84UUIIACe/CfiZ+ILlJx+kIYIAAQ +YDD+uwwAARBoMFhmRikgRWiRT/8CAAP/PBpgKkIasKr6RhogABAQMNEPAAAALUI5/aoKAAAQYDD6 +ogAgARBoMFhmOGP/jSqgAmP+qAAAAAAAAADz/lRgABAYMPP+lmCCEFAwLkIZsO7+RhkgABAQMNEP +AIgw+iwAAAQQaDD/u4IY+AFAMPgkQCAwAlsw/zYAIAEQYDBYctHAINEPKSBACJkQmTBj/g5sEASI +IiwgB/SACGwgAWAwwCDRD4knLZkUBQ5H9pIJIVQAN2D/AgACALIboC4gQQzEEfMKBCAAEGgw9QoA +IVkAt6AYuquoRC9COv8CAAoAxx/QH7qoK0I5D88KL/KXD7sB+rwAAX8ANuBl4aH9bAAO4AEoMP9h +CCIAAFqw/AoBIgAAULBYcoojRjkoIGwp+pf5JAUgEgA2IIknK5kUyLWKmcihWMNqiSgVuu/AQPoi +CS+WEGAw81KOIBAANmCUK5mgiyiasZQolCmJLPwkBSBgAH5wKiIW+osUCmABUDD6qg8A6ABScC0y +V/2qCgAAEGAw+qIAIAEQaDBYZeAkJhaIJ4sg+frAIEACejD0JgwuAEBP8PSFFCCAAnvwn4mfiC5S +cfoyGCAAEGAw/rsMAAEQaDBYZdIpIEVokUD/AgAD/2iaYCoyGrCq+jYaIAAQEDDRDwAAAAAtMjn9 +qgoAABBgMPqiACABEGgwWGXEY/+MAAAAAADz/qxgABAwMC4yGbDu/jYZIAAQEDDRDwAvIEAI/xCf +YGP+lIOeLTAEKDAF9TAGLYAEP2AI3QLzMActgAQ/YP+7ARwJAC9wCN0RA90CD90BI9xn80MUAIkQ +KDDz/nBgCAIY8AAAAAAAAPP+gWAAEFgwj2D9PAACAABQsP66/R74AXww/yRAIDACWzD+ZgAgARBg +MFhyS8Ag0Q8ALNxI+9xnIgAAcLD7SxQCAAB5sFnBtWP+RABsEASIIiwgB/SACGwgAWAwwCDRD4kn +LZkUBQ5H9JIJIUQAN2AYuin8wxECAL0boPq6JxIAIETwLzI6CsoK+qKXJACdw+ApMjn6mwEOAJhW +UCwgQfoKACFdALcg3UD/QQgu4AFQMPwKASIAAFCwWHIGwPQvNjktIGwu+pf+JAUgFgA3YIknK5kU ++pIJIAkANuDIoVjC5IkoFbppwED4IgkvlhBYMPNSjiARADZglCuZgIoomKGUKCQmCYks+yQFIGAA +fnAqIhb6ixQKYAFQMPqqDwDoAFJwLTJX/aoKAAAQYDD6ogAgARBoMFhlWiQmFogniyD5+sAgQAJ6 +MPQmDC4AQE/w9IUUIIACe/CfiZ+ILlJx+jIYIAAQYDD+uwwAARBoMFhlTCkgRWiRQP8CAAP/cJpg +KjIasKr6NhogABAQMNEPAAAAAC0yOf2qCgAAEGAw+qIAIAEQaDBYZT5j/4wAAAAAAPP+vGAAECAw +LjIZsO7+NhkgABAQMNEPAIhA+iwAAAQQaDD/uo4Y+AFAMPgkQCAwAlsw/0YAIAEQYDBYcdvAINEP +KSBACJkQmUBj/n4AAAAA8/6jYIkQUDBsEASKKiiiGCiABSkKc3mBJoknK5kU/JIJIBYANuDbIP4K +AiCOEGgwWG/vwCDRDwDz/+pgABBgMIivG7pz+yYLIEACeLD/hgAgABBgMPgmCSBwAkqw+SYIIAIQ +aDD/pg8vmBBwMP4kBSIAAFiwWG2dwCDRD2wQBIgiyIPAINEPAIk3LCAHGLmhKpkUDAxB/ZIJJcAE +OyD0oUZkACBBMCtCOh+5m/8CAAQAwELgLkI5D88KL/KX/+sBDgC3/5D6LAAABRBgMP8xCCCOEHAw +WHF/wGCJOPoyCSAEEEAw+EY5IBYANmCWO5mgiziasZY49jYJIAAQSDCMPCQwRfv6myIAXP8QLTBs +ydKKNyupFPqiCSALADbgyKNYwlSJOBe52Sj6lvVyjiASADZgjjmWO5ngjzie8ZY4ljmJPPg0BSBg +AH5wKjIW+osUCmABUDD6qg8AAEzSUC1SV/2qCgAAEGAw+qIAIAEQaDBYZMsmNhaIN4sw+frAIEAC +ejD2NgwuAEBP8PaFFCCAAnvwn4mfiC5ycfpSGCAAEGAw/rsMAAEQaDBYZL0pMEVokW1pkg0qUhqw +qipWGmAAAis0BYwuLSw4/wIAD/9b6xBoQTz6LAAAAhBYMFgAz8Ag0Q8AAAAAAADz/rpgABBoMAAA +LVI5/aoKAAAQYDD6ogAgARBoMFhkpmP/ZwAAAAAA+iIQIAMQWDBYAdbAINEPAC5SGbDuLlYZY/+X +AAAAAAD7zBgiAABQsP0KBCABEGAwWHFFwCDRDwBsEAaIIiwgB/QiGCKqALYgiTcqmRSLPPcaACAA +EDAw/ZIJIj0ANqD4uSkSANfe0CpCER+5J/wMQQAgEFgw/MURCgkAWrD6RhEkACBFcC5SOg/PCv/y +lyQBHMOgLlI5KQqO/+sBDgEV/5AsCkAMrAIsRhEpNEEo0gDTD/4KjiAwAC4wLiIdLuwB/iYdIAcA +NOAmNGwuMEHaIP8xCCABEGAwWHD6wIQoVjkvMgwcucj3/wIABRBQMP82DCAwEFgwWcA6KkIRiTgr +CoALqwL7RhEgMAA2YBy5v/0yACAFEFAw/jAFIDAQWDBZwDCMOZY7jjiewI04nNGWOPY2CSAAEEgw +jzz7+psiAGH/0CgwbMmAijcrqRTIuYqpZKAFWMHDKTIIGrlHLfqW9aKOIBIANmCLOZY7mbCMOJvB +ljiWOYs80w/9NAUgagB+8CoyFvqMFApgAVAw+qoPAACIUtAtUlfbwP2qCgAAEGAw+qIAIAEQaDBY +ZDkauTMmNhaIN4sw+frAIEACejD2NgwuAEBP8PaFFCCAAnvwn4mfiC6icfpSGCAAEGAw/rsMAAEQ +aDBYZCopMEX/AgAAAGYGYGmSDSpSGrCqKlYaYAACKzQFjC4tLDh9wVvAINEPAAAcuX6POi4wBY0w +j/CbEPkiACAFEFAw+RYBKAABWDD4FgIgMBBYMFm/6Y44/Ll0EAUQUDD7CjAgARBAMP0yCy4FAHIw +Wb/iKkIRwbALqgIqRhFj/pUAAPy5axAFEFAw+wowIAMQaDBZv9ksQhH3zAICAABQsPxGESACEFgw +WAAewCDRDwAAAPP9w2AAEGgwLVI528D9qgoAABBgMPqiACABEGgwWGP2Y/7wLlIZsO4uVhlj/z0A +APvMGCIAAFCw/QoEIAEQYDBYcJsSuOgvQhEC/wL/RhEgABAQMNEP2iBY7LsZuMAoQhEJiAL4RhEg +ABAQMNEPAABsEAYkIhiFR/e41hAGEDAw+goCIAAQeDD1Ug4gaQA04PwsOCAuADzg/wIAAgC7gOD/ +AgACAEeE4NEPAIgufIEkiS6KkPuSASAOADagmrCNkJvRn5CfkY6T+CIOIAYAN6Cfk3yJ2ilCEfwm +DyABEFAw/CYOKAkAVnD5RhEiAABQsFvs1NEPHbkiLCISiiINzAH8JhIvjhBYMPtEeCC1ADag/rjC +EgB3epD/AgAOAFLXkPsKACD8ADagx9DwAG9vABBgMAAoQhBkgNIZuN2DSChCEYMw/bkQGAkASjAo +RhH6VBAjgAQ84PshPCIJADTwk1EuIhyeWCwiHZxZK1UU+SE9IgAAULD/VBEiAABxMPlVFSIAAFlw +9xYAIgAAYbBZwC3RDwqKFPSgHWAQAlrwesjxetAMCkoU8AAGYAgCWvCxuwoaFGWv9/osAA//EGAw +WGrUiEjaIPiCACIAAFlw/AoGIAAQaDD5+o8gBBBwMPlUESmABDog/lQQKAkAMjD4VgEgABB4MPcW +ACAAEHAwWcAR0Q/HnQmpAZkiY/+02kBY5T/RD9ogW+yL0Q8AAAAAAADz/5JgABBYMGwQChu41yox +DCuyfxy4VfkwECAWECgw+6NZcAAQIDB8oVHbMPwKICAgAlBwWbbq/QoCIA8ANSCMQAjMEQ3MAiwW +BSscEPwKAiABEHAw/bhWEgUAITD9FgAiAABQsPXlOQAAEGgw/goAIgAAeXBZv+vAINEPaJFTaJIN +aJQqwFDz/59gABAgMAD8oQdwFhAoMHujAmAAAcBQ2jBY7Q/z/4FgABAgMAAAAP8CAAf/u2aQ/wIA +C/+3WpDaMFjs6dSg8/9fYAAQKDAAAAAA2jBY7Rn0rAAADAA2oPP/RmAAECgw8/8+YAwQKDBsEAQp +MBP0kBJg+BAoMP8CAAAAZwZgwCDRDwAAhCeIMIROKjAR8jwYIL4ALjD1TQMgABBYMPpEBCBAEGAw ++DASIFgCKXD4RAUiAABRcFm2syRNA/RMbCAAEFgw+kwAAQAQYDBZtq7aUPwwESIAAFiwWO0s2kD8 +MBIgsAJY8FjtKcAg0Q8AAAAA9k0CIAAQWDD6RAIg4BBgMPgwEiGYAjGw+EQDIgAAUbBZtpwkTQP0 +TKwgABBYMPpMAACAEGAwWbaX2mD8MBEiAABYsFjtFtpA/DASKgAgLPBY7RLAINEPAIQnhE4qMBEn +TQQpTQX6lGIgABBYMPgwEiDgEGAw+JRjIgAAUfBZtoUmTQX2bOAgABBYMPpsAACAEGAwWbaA2nD8 +MBEgMAJY8Fjs/tpg/DASKgAgLPBY7Pv6LAACAABZMFjtA8Ag0Q8AbBAEF7fZFrhLJ3KvJmKJpHcJ +dxGnZoRtIi0DA4gU9EAmbPgBIDAsJFKLbQsLXyskU4ptCooUKiRUiW0pJFUoJFYjJFfRDwAAIyRX +A4gU+CRWIEAQKDD1JFIgABB4MP8kUyAoEHAw/iRUL/gQaDAtJFXRDwBsEAj8uCwQARAgMPkiCiAA +EDAw/rfOH5UQeDD7t50fjhBoMPSQ9WGAEDgwGLfrKpIR9ZIIKgkAQrD6lhEgXgA84P8CAAIARoDg +/wIAAgE5BOD/AgAEAUEA4P8CAAQAaATg/wIABgCQAODRDwAoUhLzUhgqCQBasCqWEfpSAigAQGIw +KFYSLTR4/yQFIBMANqD/AgAAANB6kMe9C6sBm1IsUhJ+xhOKVyqsEFhk+Ry4BStSEgy7AStWEiYm +ECYmFSYmEY0sJiYUJCYS9CYTIAEYd1CKXixcOHyhIW0IGoteibD+sgEgEAA2YJngj7Ce8Zawil6W +sXyhA2P/3gCJKhq38iiSEZxe/FYPKAkAUjD4lhEiAABRcFvvGtEPAP8CAAAAtATg8/8ZYgAAKbAA +iSrImhy35iuSEQy7AiuWEY0s/wIAAgCGd1CDJ/q3tBAgAhjwW9rVHLeyHbejHrfdjyD7rAACAABQ +8FvajoMnIzwQ2jBb1ib/AgAAAQ+GoIgsBIgCmCzRD4kqjycet2MokhGP/tog+/0CKAkAcjD4lhEg +AhBgMPm3WB4AID/w9PSSIAAQaDD2tBEgABBwMPkWACABEHgwWb7tGrfDKFISiSwr+pL7JAUoCQBS +MPhWEiH/RnZQjFLH2w2dAf0mDCFoADcg2lBY6yKOUmThgf9SACIAAFFw+Le1ECACWHD5txgQARBg +MPkWBC+ABD/g+BYGLgkAJ/D/FgUgAhBoMFhtndEPAAAAAAD/AgAP/zPXkGShNPz6ACAAEFgw8AAW +b/AQaDDaIFjo+NEPCooU9KAdYBACWvB6yPF60AwKShTwAAZgCAJa8LG7ChoUZa/3+lwAD/8QYDBY +aXBj/hYokhElYhIjYhj6YgIoCQBaMPiWESQAQGVwJWYSLTR4/yQFIMEANqD/AgAAAEj6kPP93WIA +ACmwiiopohHBsAuZAvmmESIAAFFwW+6r0Q8Ailf7CgEgABBgMPqsICABEGgwWGKGiiorohHCwAy7 +AiumEVjj0dEPjieO7hi3APvtAiIAAFCw+e0FLgAgO7D05JMgAxB4MP/kkiACEGAw9pRlIAAQaDD2 +tBEgARB4MPgWACAAEHAwWb6O0Q8AAHrgHPP+8WIAACmwAAAAAAD6UhAiAABZcFjHi9EPAAAA8/03 +YgAAKbDz/S9iAAApsPP/AmAAEFgwK1AH2lD7C0EAABBgMPu8GCAAEGgwWG6UY/5i2jBb1bwTtxsL +qBH0oD5iACBE8AzqMCsyhYuwsKP8uwgCAABQ8FnAuxy3EyrCfwAxBABLGguqAirGf1nA8YwsBMwC +nCzRDwAAAAAAAAD6CgcgARBYMFhk640sLjJ//jaDLAkAJ3CdLNEPbBAGiCL0gBti4AEsMNogWOqb +iSLLmWgyUsAg0Q8AAAAAAAAA+iIQIgAAWLBYx1doMmmKJ4ys+qwwIAAQWDD6zQwBkAJjMA3LOVht +MtKg0Q8AKyAH2iD7C0EAABBgMPu8GCAAEGgwWG5faTKsH7aAnxCOINog+xwAAAEQYDD9txYfgAQ7 +oP0WAi4JAGOw/hYBIgAAaXBYbQLAINEPwCDRD2wQBiMiGBq2kIk6iCLAQfmrQAgJAFZw+TYKICQA +NiDaIFjqbhy2iisyEQy7Ais2EY0iZNBGBQ5HaOJcwCDRD9ogWL9K9a/obuABLDBo8niKJx22vCwy +EYiswLD6rDAsCQBrMPqJDAGQAkIw/DYRKgUATjBYbQDSoNEPAAArIAfaIPsLQQAAEGAw+7wYIAAQ +aDBYbixj/50AHrZNnhCNINog/LZrEgAAWHD8FgItgAQ/YPTdAgABEGAw/RYBIgAAaXBYbM/AINEP +wCDRD2wQCikwEMAj+raEEABHhmBokh9plBeLNiqifwm7EauqKKAFKQqV/wIABgBhThDAINEPAIs2 +KqJ/CbsRq6qCqowwwEHyIgggkhBoMPO2LRAeAH8wLKAF/wIABgBN7xCOImTg9NogWOoqjyJk8PqT +GIgg2iD8CgEgQAJYcPm2vBmABDog+RYKKAkAIjD4FgkgAhBoMFhsqMAg0Q8A2jBY68L5CgcvigA2 +oIuni74sso4MnVZ9kC8MfVh9ICketjf/vQIgABBoMP30ESACEGAw/hYAIgAAW/D+CgAgABB4MFm9 +y8Ag0Q9Y61DAINEPwLJb/mnAINEPZC81JSIYGrYgiVqIIvmrQAgJAFZw+VYKIHUANiACKgJY6f4c +thorUhEMuwIrVhGNImTQZpMUjiDaIPwKASAgAlhw/7YTH4AEO6D/FgYuCQAjsP4WBSACEGgwWGx5 +wCDRDwAA+iIQIgAAWLBYxq/AINEPACsgB9og+wtBAAAQYDD7vBggABBoMFhtvmP+6dogWL7GZa+Y +Y/6fAAArIAfaIPsLQQAAEGAw+7wYIAAQaDBYbbRj/30AbBAEiC4jLDhzgS0pIhJ6nzKLLoiz+iwA +AgAAYTD7vOAiAABpcAuAAIwi/SAFIAsAtyDI044uc+nXwCDRDwAAAAAAAAD9IgAgBRBQMPy2XhAw +EFgwWbzDwCDRDwBsEBiUHYc1LzEPKyAHJRYZiDTzFh4gARAoMJUf+MUUCiABXDD7FhgsCgFAMCwW +GvwSHiwLAUQw/RYdKg8BfDArFhQqwAAuwB39wT0j/xAwMP0WEiYfATww/hQAIHcQWDD8wh8gGgDW +MA8ISSgWFWAAAiYWFfwWECYA7l6QwPD/FhMgABAgMBm2OSgSGSmRfvlZDAjgAUAw+BYXKeABTDD5 +FhYiBEyCIIoi/wIAAgUJqqBkcF3A4P4WESAJADXg2lBY7ybAMPYKACGnADUgLRIeLdCDDV1CLxId +2nD+CgMgAhBgMPsSGiwFAHuwWO8Gpqb6Cg8gEAA1ICkSHimSKihsMAmGOXagUAZLFLG7KxYbYABL +LBIS/wIAAAQ3qyAtEh6N1X3WjvsSEiIAAFFw/BIQIAEQcDD+FhEiAABocFjvOP8CAAAEsi6g/woD +IAAQGDAK8zpkMRHDYAZIFCgWGy4SGB+1MvoSGyfABDug/LUxFgAgebApYjoM7Ar8wpcqBMxWUCti +OfYWDCoAQGbw9rwAAATIquAt8kr+tfYQBLIrYCjySSniX4wd+YsBDgSqThAqIBSWFtMPCqyH+iQU +LAS+kqAtEh3/EhYgDAA3YP8CAAIEyX/QZDCfKBIayIFkMFz7bAACAABQsPwKAyAYEGgwWO86ZDc5 +KRIUKxIV/LWAEAAQaDCdop2jnaT9pgUsCQBhcPC7EQggBD5g+5kCC7AEPOD8pgAoCQBecPy10hAc +EFgw+aYBIAUQUDBZvDMuEhf/AgACBH+boMAgiBwvEhsvhjnRDykSHimQgwlZQikWE/P+ImABECAw +9gowLmEAtSDz/mJgABBoMCoSEWSgcfsSBiIAAFCw/AoDIBgQaDBY7xMZtSsrEAAWtbYetbcLHxQm +Yp8M/xD+XgIOCQBP8Pa2CwBEAH7wLBIQK23/LRISKLI/K7F9nqCfoZ2inKObpJilYAAYLBIQLRIS +K2EFiGOeoC+mAZuimKOdpCymBSasGC0SFCwSFQ8CAALdEP0WCS0ABDsg/BYKJlAAteAuEh0ftTso +CgD4FgUuYAQ7oP4WCC4JAH1w/xYOIAIQeDAvFgv7bAACAABQsPwKAyAYEGgwWO7mLxIe+RIFInYA +NSAmEh4mYIOP9WSSfvwSCCJrADUgKBIeKICC9k5ABgABQDD87hAGoAQ5oAbtAv3MAgwUAXww/yhQ +DFAEP2D9zAIMEQF8MPOIEAwgBD9g+N0CCBMBeDAEiBAIzAL9Eh4sCQBrMIseGLVyjdSboJihnKUc +tXD8pgMtIAFsMP2mBCP/EGgwLaYCLhIL+ZwBIDACMrDTD/kWBSH+AnOw/hYLL0QAt6AvEhPTD/8C +AAAC1Yfg/wIAAgL1A+D/AgACAwEH4P8CAAQDDQPg/wIABAMZB+D/AgAGAyUD4P8CAAYDMQfgZEBP +LhIeLuIqZOBG+2wAAgAAULD8CgMgGBBoMFjupC8SHhi1TYke//IqI/8QWDCbovmmACwAEDAwlqP4 +pgEnNgF4MPamBC9gBD/g/6YFIDACMrD7bAACAABQsPwKAyAYEGgwWO6SGLU9/xIJIAMQYDD+Egog +GBBoMPYSDiAAEFgw9qYAIgAASrD/+v8uCQB7sP+mAiewBDjg/5YDIgAAULD7lgQmCQBxsPuWBSgJ +AEGw+JYBIDACWnBY7n0uEh4ZtSj7Eg4v/xBAMJijm6D2CgAoCQBNsJYRlhKWE5YUJqYC9qYEIBgC +YHD2pgUgIAJocPmmASAQAlhw+hwEIDACMrBY7HTToPwKASIAACKw9KSDZAUAUzCVF/4KASAAEGgw +BO048xYhLIQAN2ATtQ8pEh2EFxu1DPwKASIAAFJw/BIJKgUASzCIGvVqACgwBD5g+rU5CAkAZnD4 +mAIICQBNcPkWHCQJAEVwJRYfFbRq+QoDIAIQQDD+RBEIBQBScPgWICQJACkw8AEmYAAQKDAAAAAA +APP9kGAAEDAwwODz/algABAwMAAAAAAAAPRAxGwQAXgwKBIeKIIq/UoAKkUBNDD2CgAuYAEwMP67 +EAYFAENwD3hQCYgQ+LgCCg8BfDD5zBELwAQ+4Py7AgwtAXgw/21QDUAEOyD8uwIMFQF4MPDdEQzw +BDsg/cwCDBkBfDD8uwIMGAF4MPvdEAygBDsgDcwC/w1LCgkAZvD8EAAoCQBaMPhoAgACEFgw+7TM +GAkAWjD7pgItQAQ/YPimBCyABDsg+LTHHAkAY7D9Eg4sCQBrMJ2gnKWYoxy0KpyhY/01AAAA+woA +IAAQMDDz/1JgABBwMAAAAAAAAJmhlKCcopyjnKT8pgUgABBYMJumm6ebqJupLRIgsVX2rCgmARpt +UPtsAAIAAFCw/AoEICgQaDBY7fv0UExpsAQ9YCsSH/8CAAAAqIVg+5kCD/8QYDD1f6doCQAecI0T +LBIejhKPEYvMLMIQmaGbqfSmACAAEEAwmKKYpp+jnqScpZ2njBScqGP/jy0SHSwSHBu0lgyZAvTQ +iGgJAF5w/vr/ICEANeCZoZSgnqKeo56k/qYFIAAQaDCdpp2nnaidqWP/ViIWIyYSHiUWJSMWJC5i +GixiGy1iFStiGShhOSNhOC9hOiViFvJiFyMABDzg8xIkLgkAH/AmYTueo52mnKSbop+pmaGUoJWn +kqjyEiMpAAQ6IPUSJSYJAEGwlqVj/vgA+/r/ICEANeCZoZSgm6Kbo5uk+6YFIAAQQDCYppinmKiY +qWP+0iIWIyISHi4iGIwsKCIULyE5LSE7KyE49iE6LwAEP+D/EgQsCQB/cCIiEJ6knaX8pgcrAAQ+ +4PimCCYJAFmwlqmZoZKjlKCCEp+mkqIiEiNj/oAAKBIdLBIcG7RSZIBj/JkCD/8QcDD0cCFoCQBe +cJmhlKCeop6jnqT+pgUgABBoMJ2mnaedqJ2pY/5GLhIeIhYjLeISLOITK+IYiO2G7i/iFILvLuIR +nqKdo5ykm6WYppann6mZoZKolKAiEiNj/hEAACsSH8ff+5kCAAAQYDD0cBtoCQAecJmhlKCdop2j +naSdpZymnKecqJypY/3jmaGUoI4T/xIBIAAQQDCYopijmKSYppinmKifpZ6pY/3CKhIeiqUZtCQj +EiH1EgcgDgBOsGRwdBuzfQtbAiuW+mP4qACDH8DC8/i+YgUAPzDApfy0GhAcEFgw/l4RAgAAaXBZ +um5j91IAAAAA+hIWIAAQaDCdEZ0SnROdFFjrWJUX8xYhK+cANqD6EhYgABBYMFjrS5UXIxYhY/vP +LhIQ/wIAA/vHK6Bj9x0AAB+z1A9fAi+W+mP4M9xg+lwAAgAAWLD9Eh4gARBwMFjsHvP6cGIAADKw +AFjrR8irGLP50w/TDyiAgGSBAyoSFljrPWWrZfoSFiABEFgwWOsxY/tX3GD6XAACAABYsP0SHiAD +EHAwWOwM8/opYgAAMrAAAADcYPpcAAIAAFiw/RIeIAcQcDBY7ATz+gliAAAysAAAANxg+lwAAgAA +WLD9Eh4gCxBwMFjr/PP56WIAADKwAAAA3GD6XAACAABYsP0SHiAMEHAwWOv08/nJYgAAMrAAAADc +YPpcAAIAAFiw/RIeIA0QcDBY6+zz+aliAAAysAAAANxg+lwAAgAAWLD9Eh4gDxBwMFjr5PP5iWIA +ADKw+xISIgAAUXD8EhAiAABocFjsuGP2iQAAKxIejB39EhkiAABQsFhjnNKg0Q8AAAAA+rO2EUEQ +WDBZi037GkEhABBgMPqzsRwJAGKwWYtNY/7aAAAAAAAAAPosAAAcEFgw/AoAIAEQaDBYatdj/6mW +HPP2cWAAEFgwAAArEhj6LAAAABBgMP0SGyAwAlrwWGrOY/+E2iBbzP5j9n6KJ40dwMD6rCAiAABb +cFhej9KgjBwrEhsrxjnRDwAAAN3w/LOTEAQQUDD7ChggAhBwMFm55PP2XGAEEBgwbBAEFLONgiAk +Qn8Ts4wEIgwDIgLRDwAAbBAMJCITGbLqKEEp/wIABgB8ThAassDwCgcCAABIcABJYQBJYQBJYQBJ +YRizgR+zf44gG7N9+xYCIAQQUDD/FgAvgAQ7oPgWBioJAFOwmhEpQAcvQSkJCUEAmREJ/wL8s3Ue +CQBH8J8UKyA5A+4C/hYLIAIQaDD9FgkqCQBm8PsWCCIAS4TgiUcomRT0gIBgQAJycIuZLOIA+vrA +ICgQKDD0sENqAEBTsG0IMHvBOC2wAPmwByBkBCtwL+EF+vgICcAEPmD4jEAqACBO8Pi7D3IAAGrw ++9wAAA8AN2Bj/8gPvQxj/+4AAPvNDAAAEEgwDZs4z7T6TAACAABYcPwKBCACEGgwWFo60Q8AAAAA +AADz/4JgABBYMAAAKhw6/AoGIHQCWLBZsUBj/1vCdo24DY9Xd/FaL+EFqvb9vEAoADa20PvcAAAy +ADdge8EqKLAA0w/TD3WBIC2wBw8CAAzdEf27CACAAkmw+bsdcgAAavD73AAP1gC3YPvIDAAAEHgw +CPs4ZL9uY/+jD70MY//gACkgOQ0PQ3+ZmyiwL2iDlYkgCJkRCTkCmbvRDw/dDGP/kAAAAAAAAABs +EAQoIAUtIAfBlP0MQQ4AiMoQiSJlkNcuMAH8xhEAFABvsCogTmWhSxqyLP+yLRYAIFGwK2I6D88K +//KXIgB5QuArYjkPuwH3vAAA7AA24CiiShyyO2SArizCfymiSfybAQ4AUuZQLyAUD/SH/yQUKgBu +l+AYsiEfswMqIST+C0EMAgFoMPrMEAsABD7g+bL8GgkAZvD8IQkqCQBasPshIioJAHqwmnCKIP8x +ASACEGgw/3YEKgkATvD8dgMrgAQ6oPt2AioJAGqwmnGJM5l18AgXADACSfAACYoFDkf9Zjki9AI7 +oMAg0Q8AAAAAAAD6LAACAABY8PxMAAIAAGlwWGK70qDRDwD6LAAAHBBYMPwKASABEGgwWGoBY//R +AAD6LAACAABZcFhkPdKg0Q8A8/8UYAAQWDD7zBgiAABQsP0KAiABEGAwWGn1Y/+h2iBbzCUtIAcu +MAFj/xiKJ/tMAAIAAGkw+qwgIAAQYDBYXbTSoNEPwLgLmwKbImP/cABsEAYoIAUmIAf3PAACAABY +8PkKFCADEBgw9gZBDgDdyhAFCEf1sc4SJAA6IIwi9MB8a8AEOaDAINEPLSIdZdGniieLqP6hFS/A +EEAw+aILIEACerD8qRQoAEBD8PgWAS4AIEOw/uxAJgDfXlAMSRGpzPylFCoAIFpw+RYCKgDd15DJ +e/m8AAAZADUgjBJtSQUAB4YASWGK8A8CAA8CAKyq/wIABgDwdpCa8GP/fgClqi2iOm7TGR2xqiyi +OQ1tCi3SlxiykR+xrf3OAQgADmsQ+2wYIgAAULD8CgEgAxBoMFhpr8Ag0Q8AHLIYnOCJIPiZEQAB +EGAw/OYCKAkAHnCZ4YmzKIJ/HLGjCYkU+YgIABAQWDD45gMgIAJLsPAPFwAAEEAwsYjyGR4B9AI+ +IJzmm+cZsnaZ6IggCIgRA4gCmOkesnMjpjkvIAaKJ/kiAi/AEGgw//wBIAEQWDD/JAYgQAJSsP+p +BCgJAF5w+KIBLABAbrD5JgIggAJrcPmxqxBgAnvw/6UEIaACQjD4pgEqABJqEC2hBajYmKGZgI8g +CP8R/oYCLgkAH/D/hgEgABAQMNEPGbGdmYCPIP6yVR+ABD/g/oYCLgkAH/D/hgEgABAQMNEPAAAA ++iwAAgAAWXBYY6/SoNEPABiyS/AAKWCKEEgwGLFhKVIgiIQpkAf5FgAgABBQMAuAAIoQiRMKmQz4 +skEeLAA2YCuCgvkWAyGoAP7wY/4ZwMCcq/P9/mIAAFpwAAAAAAAA++oMADcANeAKTRT+3AgiAABB +8P5ONgIAAErw0w9t6QUACIYASWGJEap4/UwMAIACSnBtyQUCCIYASWONEowRCt0MrcwszECc8GP9 +p44RLuxAnvBj/Z0AAGwQBiggBSwgB/6xMBrgASgw/QoBIBQQSDD8DEEOAQ3KEP8CAAIA5YKgjyL8 +xxEACxBIMPXx0WYAIHXwKHI6H7Ek/BYAKgEBzhAocjkPyworspcLiwH2vAAB9wA24CjiShyyCmSB +uS/C8yniSf+bAQ4A2H5QKSAUKDAHmhIIiYf4JBQqAPGWIB6yAZ5giSD4mREABBB4MP1mAigJAH5w +mWGINhmx+4XOCCgU+7EQGABASjCoVZVj8AsXACACSbAACYoZsRD5ZgYgIBBAMPhmByBgAijw9gUW +AEACQbAASGf1+wcAYAIpsABFZS5mEIggCIgR/WYSKAkAejAoZhGFM4zMBYUU9cwIAMACabD8ZhMg +IBAoMPALFwCgAmGwAAyKKWYW9WYXICACYPAKDIYATWsIDIYATWkvMAEcsPr+MgMgAFR/0CggBwgo +QP0xASigBDog/CEkKAkAYjAoZiCIIClmIviIEQADEEgw9bHKGAkASjD4ZiEgGBBIMClmI/htASgB +AXww8fsHASACejAAT2EAT2EoIQkjIAf9ZikpYAQ+YP5mKCAAEHgw/2YlKUAEOiDzA0EICQBKMPAz +EQAaEEgw88MCCAkASjD4ZiYiCQAs8PNmJCALEEgw+XY5IgBNmqDAINEPAAAA8//tYAgQSDApIh1k +njIWsaPwAMRgihA4MAAAAAAAAAD6LAACAABY8PxMAAIAAGlwWGFx0qDRDwD6LAAAHBBYMPwKASAB +EGgwWGi3Y//RAAD6LAACAABZcFhi89Kg0Q8A8/4JYAAQWDD7zBgiAABQsP0KCyABEGAwWGirY/+h +2iBbytuKEhyxhvP+E2ABEGgwiif7TAACAABpMPqsICAAEGAwWFxp0qDRDxmwjhiwlSmSIIiEKZAH ++RYBIAAQUDALgACLEYoSHrCH+3cMAAEQaDD8EgAtbAA14C9igpwQ+hYCIY4A//Bj/VcAAABsEAqM +J4giLSAHL8EV+vrAIEACYzD8SxEMAEBTMPs7CAwAIGPw/MxAIgAAKvD9DUEKAkni0C5QB9ZQ9Vwg +IfwCO7D0gA5gBgJTsMAg0Q8AAAAAAAD6FgEqAjphUIlQ/LBmEAIQWDD4CoEgABBQMPzfEQj4AUww ++JkMDgAgZ/D48joqBQBK8PoWByoAIFHwuKn/AgAKAh9OEBiwWSvyOQjYCiiCl/oWACoAQEbw+rwA +BCwANuApwkr9sT8T8QA2YCjCSSnS8/mLAQ4B8c4QLCAUmhiaEwzOh/wkFCoCEJcgG7BmjjQcsFMZ +sFr9sTUQAF8nkCogB/hgASoCAVAw9GIDKqAEOqD6EgMoCQBOsCNhAS4hJJmghyD8pgIgGBAoMJWj ++HwRAAMQKDD5rBAsCQArMPymASACEDgw8AsHDAEBQDBtegIASWEoIAcpIQn0pggoIAFAMPOmCSkA +BDog+OgCD2AEOyD9iAIAOhBgMPimBC1ABD5g/goALAkAd3D+pgUsCQBncJ2mKyEJ2iD+YQEgABBo +MPX2OStABD7g/AoAKgkAZvBYYlPAINEPAIlQsX77CoEo+AFMMP2xABBGCFpwiROdkI0gsHv7GxQN +gAQ/YPuWAigJAGuwmJFgAEIAAJ4Snxn7EgMiAABQsFlUcy4hBxiw9A4OSgzuEQjuAp6gjSCIEgjd +EQ2IApihiBCOUY8ZHLAH/l4UAAoCQjCYEZ6iFbDnGbDkjjaIJ4meDi4U+4IJLgBAK7D1gRUgQAJC +MPUWBSgAIHZw+aYDIAQCcTD5+sAvwAQ7oPmIAQoAIHbw+BYEKAAgPTD5nAIkACBFcPVcQCnABD5g +/pkMCgAErtCIFQi7DPSQRG/ABDng+awQKAAgW7D5FgYqAP9BUAtVDAVNFG3ZBQALhgBJYYkU/XgM +CgAgVXD7vBAggAJKcG2JBQIJhgBLYy0iAAjdERmwu/jsECAEEFgw+AoBKgAgQrD4pgIqCQBfcJuh +G7CymaCJY4u8GK/JCYkU/rC0GgAgTvD7pgMgABBIMPAIFwAgAlqwsZnyGx4B9AI+YPymBiAgECgw +laeFNo00h2OJNf6wqBwAQHdw+zIKKJAEOeDzsKUcCQBHcPiwpBwJAHdwnaguYAn4YAskAEBFcPlg +CiIAQB5wLWAI9IgQDsAEO6D2mRAOCQAbsP1jQAgJAEZw/VgUAnAEPODxiBAICQAecPOwTRQJAEVw +9aYKKAkAdnCZqY5lnqv+YgYsgAFsMP6mDCyABD9g+WIHKgBAHvD5pg0qCQBu8JuuiGSYryNgAf8C +AAAAUvzQKSAHHa+eCSlA+yEkKKAEPmD9YQEoCQBucCmmEIgg/goYIAMQSDD+phMpgAQ6IPmvnRgJ +AEow/KYSLgEBGDD4phEgAhBAMPAJBwCgAkqwbYoCAElhLCAHKCEJwFD1phUlYAQ/oPwMQQlABDog +9bBgGAkAKjDwzBEAGhBIMP2mGSwJAGLw9RIBLAkAKzD3phgoCQBKMCimFvymFCAGAilwlRGOES72 +OS1gB4on9N0IAAAQYDD73AAAQAJSsFhbM9Kg0Q8AZH4ybXkFBAuGAEllY/4gAAAAAAAAAPosAAAc +EFgw/AoBIAEQaDBYZ1/AINEPAA+1DGP7agAAD1UMY/uJmhDz+9RgABBYMIgXjxHaIPj/CAAwAltw +/fwDIAEQYDBYZ1LAINEPAAAA/xYJIgAAULBbyX+PGYoYY/vQAABsEAYoIAUvIAf+CgMgFBBIMP8P +QQ4A28oQBQhH9frAIiQAOiCKIvuvMBB1ADagwCDRD4oni6gmoRX5ogsgQAI6sPypFCgAQCnw+BYA +JgAgQbD2bEAmAMPeUAxJEanM/KUUKgAgWnD5FgEqAMFVkMk6+bwAABgANSCMEW1JBQADhgBJYSpy +AA8CAAyqCP8CAAYA1DaQmnDz/4piAAAa8AAM+hGrqi2iOm7TGR2vECyiOQ39Ci3Slxuvhxiv9v3E +AQgADmsQ+/wYIgAAULD8CgEgAxBoMFhnFcAg0Q8Am0CJIPiZEQABEFgw+0YCKAkAdnCZQYkzKIJ/ +H68ECYkU/K/mGAAgSjCYQ/APFwAgAkkw/68EEAAQQDCxiPIZHgH0Aj4gnEj/RgYgEBBoMJ1HiSAI +mREOmQKZSS6mOSggBoonjyKxiPgkBiBAAlKw/akELgkAX/D4ogEsAEAqsPmhBSCAAmMw/yYCIGAC +a3D9pQQhoAJCMPimASoAFuIQ+68OGAAgQnCYoZuAiiD4qhEAABBYMPuGAioJAHKw+oYBIAAQEDDR +DwAbrwSbgIog+KoRAAAQWDD7hgIqCQBysPqGASAAEBAw0Q8AAAAAAAAA+iwAAgAAWXBYYRXSoNEP +AMDAnKvz/kBiAAAacAAAAAD7agwANwA04ApNFPzcCCIAAEDw/Ew2AgAASvDTD23JBQAIhgBJYYkQ +qjj9TAwAgAJKcG3JBQIIhgBJY40RjBAK3QytzCzMQJxwY/5diBAojECYcGP+UwAAbBAELSAHiCIb +rqf9DEEAAxBwMPWA1GvABDsg+K6jGgAgWrApojoIyAr4gpciAFXGYC+iORmuqvj7AQ4ATsfQGK6v +DSRACkQQ/CElJAkAQTCUsIQgH660+bYCICAQQDD5vBAlgAQ5IPi2AyQJAHEw9LYBIAQQIDDwDwcE +CBB4MABJYQBJYSggBy0hCRmvfvS2BSggAUAw9N0RCQAEOiD/3QIICQBDMP22BigJAEowmLSENpS5 +jzf/tgggQAJo8PENFgBQAkrwAAmKBQhH/qY5ImYCOiDAINEP+8wYIgAAULD9CgMgARBgMFhmf/os +AAIAAFjw/EwAAgAAaXBYZSrAINEPAIon+qwwIgAAWPBYZULSoNEPbBAGLCAHFK5iDwIADAxBDMMR +/q5gEgAgJPAoMjoPAgD+zgoAAxAgMP7ilyKQAT4gLTI5/tsBDgAe91AfrpX6IgAgABBAMCgWAPgW +AiAAEGAw/xYBIAUQaDD/ro0QHhBwMFhdMPQ2OSAAEBAw0Q8AAAAAAAD7zBgiAABQsP0KAyABEGAw +WGZTxyTRDwBsEAYoIHDAVPSuPxDuAHYwKyAHCwtB/a48E8AEPuCkMykyOg29CoQg/dKXJLgBOmAs +Mjn9ygEOACjvENtAWO2OwMH9CgAgARBwMPivJxAAEEgw+RYBIAAQeDD5FgIiAABasPgWACIAAFEw +WF0LJTY5KiBwKwr7C6oB+iRwIAAQEDDRD8Ag0Q8A+7wYIgAAULD8CgEgBBBoMFhmK8ck0Q8AbBAE +KyAHGK4XFK8QCwtB/a4WE8AEPuD0Qn8iACBE8CgyOg29Ci3Sl/6CTGQAIFkwLDI5/coBDgAg7xDb +QPwKACACEGgw/goCIBAQeDBZtjDAsfiu/xmABD0g+KYAKAkAXnCZoY8gn6LA4v42OSAAEBAw0Q8A +AAAA+7wYIgAAULD8CgEgAhBoMFhmB8ck0Q8AbBAU/jAQIAcQODD/rgAQARBgMPqt8BAAEDAw/QoY +IkMAN6D/AgAABEGHoGjiA8Ag0Q8rIAcFCUf5FhoqIAFcMPsWGyI0AjpgLiAF/wIACAW7w6AoIHL/ +AgACBbZ6ENogWF78/wIAAgQUqqCLIv8CAAIED6rgKiEajDUtIhD/Igkp8AQ+oPsWBCoACmJQDwlC +yJkKC0L/AgAABVuq4C4SG/mtzRAYEFAwDK1w+swXKcAEO6D6ShQIACBKMCgWF/iCOiAGAlqwmx77 +Fg0gDgJJMPkWCSoFe04QKBIXGa66KII5CekKKZKv+YsBDgVvzhCOKg0IPg/uDPgWGSoAPMOQLSAi +KSAjDZkM/wIAAAW2KmAtIAcfrcENDUEP3Qko0d4JjjYOiAwo1d4tICKeGA3eh/0kIiAFritgKPJ7 +jivwgQQB/gJ7cPD/GgABEEAwAIga+Iz/LgAge7D/IgkuCQBDsC4mCigSGQ/pDP8CAAoFl8ZQLSIQ +LyAHGK58Dy9ACv8Q+CEHLgkAR/CfsC8hCf4iAClAAUAw+RIOKMAEOiAI/wL4ISQvgAQ7oP4hIigJ +AHZwn7OZsR+t4hmuhJ21/66EHgkAe7D+tgIoCQBKMJi0KCA4nLj2tgcgAhBIMJm5+a58EEcQcDD2 +tgsoAwFAMP4KASYFAEew/rYKKAUAR/D4PBAoCQA+cPm2BiBgAkrwbakFAAiGAElhGa19mbyIMP8C +AAIEC6oQLRIXjB0s1jkrIBQqEhmku/skFCAXADagKBIZjykuIDgI/wj/JgkiBPj7kCkSGv8CAAIE +5ppgwCDRDwAAACggBykwES4gBY0i+XtACCABQDD4FhsoAwGboPkWCyIEi6tg+xYYLcAEPiD7rk0c +ACBXcPjSOiIAAHIw++sKABwQSDD7sq8qBJ1OECnSOf0WFygAQF5w3pD9nAAABJoqYCiiSv8CAAoE +c8IgGK5BKaJJKIJknhr4mwEOBGpGUJscLRYdKDAUKCQ4LjAVLiQ5JiQ7iTiOOYg2KCUiKSUJiDuJ +Oi4lIyklJI48KCUlLiRMiT2OGykkTSgyECglKCgyESgmFSwlKSYkTiYkTyYmGywmFywmGCwmGSYm +Hfwkcy5gAXAwLiQ6LiEaJiRwJiRy9iRxKAMF8dD7IDgv/BBoMPMWHywAQG+w/dzsIAIQSDD5twEO +AA7O0P4ISAABEEgw/pkUCAUAQnAJiAgOiBEI3QwerhHAgQ3jLA3uLg6OOfMKBC4AIBuw94c5AgBA +HvD4rU4SBQAeMNtg862WGgUAHjD43PwiAABJsP7THAgFADzw/oscCAkAXnAjJTQuEhgjIBT7JTUp +AAQ6IPDbEQgJAEJw+CYQKAkAXnD5Jg8gIBBIMPMSHyYAICTw9yQUJZwAN6CNKSwgB50siD4oFhAY +rQP7EgouAgFgMAruEAjuAp6wLiEIiCCfsvm2Ay4gAWQw+IkRAAMQYDDw/xEICQBmcPwKAS4JAHuw ++bYBKIAEPeD3rPMYCQBmcP8iCyAAEGAwLBYRmbeWtZ+5/bYIIBQQaDD9FgUuCQA+MP+2Bi4JADuw +/rYEIBgQODD2JBQgYAJa8PoyDyABEGAw+hYSIAAQaDD6IgAgABBIMPkWACAAEHAw+RYCIAEQQDD4 +FgEgARB4MFhbpSoWEyohKFmz5P4gOSCAEGgw/GwAAEAQeDD6FhQiAABJsPoiACoAAXQw+/k4AAIQ +WDD/IDguAEBbsA7cOPyZAgIAAGmw+/4BABAQYDD/D0AMBQB3MP4KICIAAGGw/iA4LAUAe7D/IhUi +AABBsP0KACwJAGsw/RYBKAkAZnD+LEAAABBoMP9vFA4DAXAw/xYVKAUAYvD7EhMgBBB4MPytmhgJ +AEow/BYALgkAQ7DTD/zuEQABEGAw/woALgkAe7D+FgIgABBwMFhbcywKAf+tjxIAAFqw+iIAJAAQ +SDD5FgAgABBoMPkWAiAAEEAw+BYBIAEQcDBYW2csEhL9EhAiAABasPoiAC//EEAwmBAuIST/ISUt +AAFsMPwMSA1wBD9gDcwC8P8RAAAQaDD8FgIuCQB7sPwKAS//EHgw/hYBIBoQcDBYW1QKqwL6IgAv +/xBgMPwWACAAEEgwKRYBKCEiKSEJLQoA8IgRABwQcDD4mQIP/xB4MPkWAiABEGAwWFtFLxIU+K1j +EgAAWrD6IgAv/xBIMJkQKRIRKICMHa0jLBIV+YgCAf4Ce/DynhAIEAQ6IPn/EQ4JAEOw/6znHgkA +e7D9CgAsCQBrMPwWAiABEGAw//r/LgkAe7D+FgEgHhBwMFhbLPwKASIAAFqw+iIAIAAQQDD4FgAg +ABBoMPgWASAAEHAw+BYCIAEQeDBYWyGJMP8CAAIBT6pQGq05KBIXH6yNLiEHJ4Y5LSAHL/KmiSCH +ICwgDCqim/sgDS4AID/w+CAVL5AEP+D/rTIaACB6sCoWFi6lBy2kByykDCukDYc5J6UJKKQVKDIR +KzIQ+6UoJ+ABPDAnpSMrEgwIaBT/8hwgFBBwMPmmHiABEGgw/aUpIgAAYfD+pAUgARBoMPj/CAAA +EHAw/6YWIP8QeDBY630uEhYt4BX5EhggARBYMPbkFC2ABDng9N0QACAQcDD+pAMsCQBrMPakACwJ +AFsw/KYBInEANmAvIDrAj/8CAAYBNkfQLDBXxJAMmQyZHychCf0KASAAEHAw/wr/ICACWrD6LAAC +AABh8FjrYi0gFcCx9iQUL4AEOeD2pAAsQAQ/YP4SDywJAHdw/qQDLAkAX3D9pgEgDBBgMIonHawN +iq6JFQANiwBKYQBKYQBKYQBKYQBKYQBKYQBKYQBKYR+r5C4SGCz2SSkkBfskFyArADegKCA6wJ95 +gR4ZrGEoMFAJiAooghD8MFcgoAJY8PosAAACEGgwC4AABQpH/wIAAgHEGqDAINEPAAAAAAD6LAAC +AABY8PxMAAIAAGlwWFyR0qDRDwAAAAULR/sWGiJEAjrgKyAFwcT/AgAGANhm0G64ci0gcn7fbC4g +FKTuLiQU2iBYXN9loGyPImXwZ4gweoZSKiAHGKu7CgpBDKcRqHcpcjr/AgAEAbNCYB2ssSxyOQ2t +Ci3Sr/3LAQ4BqW8QLyBxAzwC/grqIgAAULD/5jkCAABpMP8KASIAAHGwWFyewIQodjkpEhr/AgAC +AYMaYMAg0Q8A+iwAAgAAWPD8TAACAABpcFhcY9Kg0Q8A/KyiEAQQUDD9IgAgKhBYMFmyzx+rpi4h +GvP53GABEGAwAAAAAAAAAPw8AAIAAGkw/goAIgAAWrD/CgEiAABQsFhcgvP9RmAIAjnwKxIdHayQ +LhIbH6yOLdCAAOEE8McaAAMQcDD+9IAu4AE8MP34M3IAAHNwx5/4q7kYEQBP8PkSGywAQE9wCJkK +GKu1KJaXGayADX0CDQ1H/ZSAIWwAN6Bk0W/B8/8WBSABEHAw/hYRIAAQaDAtFhDz+oVgFRA4MAAA +AAAAAADz/fFgBhBgMMSAmB9j/ZoAiR74IHEiAABg8PosAAIAAGkw/grqIAEQeDD45jkJwAQ+YP5s +AAoAIE7wWFxSih60qpodY/e2jCcuyRQnzCD04RZgYAJLMI/JiJD5FhwgABBgMPmODAGQAkIw/ow5 +D8AQcDD08HJuAEBx8C4WBikWHIlwf5FiLvAAwYT/AgAGAFbHkMGV/wIABgBRz5DBhv8CAAYATMeQ +/wIABgBI75DBmf8CAAYAQ8+QwYp44X2IFi7wBylxBSkWB/iZCA/ABDug+ZxALgAgd/D5+0FyAABz +8P/sAA+cALegyc79EhwgLRB4MC7AAH/hQojOwMD42QwBkAJCMAmMOWXP5ywgTvkKFiIAAHGw8AAi +bgUAYnCOFw7+DGP/ugAAAP8CAAP6pIdQCawM8/U+YdACYzAuJHFj/Vhk3pfwAAZgARBIMMCQGKwf +L4LSx94N/wEPnwIvhtJj/nkAAAAAAADz/uxgABB4MPosAAIAAFjw/EwAAgAAaXBYW8/SoNEPAPos +AAAcEFgw/AoBIAAQaDBYYxVj/9HAINEPKxIb+iwAAAEQYDD9EgkgMAJa8FhjDmP8rC0WF/P2zmAA +EEgwAAAAACsSG/osAAABEGAw+7wYIBwQaDBYYwRj/4yKJ/tMAAAAEGAw+qwgIgAAaTBYVsbSoNEP +iif7TAAAABBgMPqsICIAAGkwWFbA0qDRD9ogWFtxY/YKiif7TAACAABpMPqsICAAEGAwWFa40qDR +DwAA+6wYIAEQYDD9CgQiAABQsFhi6WP80QAAKyAF/wIAAf4IhuCMFMDSDcwCnCJj/AAAjimeKvP0 +y2IAAHuwiBgqIAcfqt0I2wz7JCIqIAFQMA+vCS7x3qjuLvXeLSAizNeMKZwqYAApAAAZqtUpkn+O +K/CRBAH+AkNw8IgaAAEQeDAA/xr//P8uACBDsA/uAp4q+6wfIAEQYDD9CgAiAABQsFhixWP7iQAA +bBAEG6sHiSAYq7orsqb4go4oACBecPmZEQAQEFgw+yQFIAAQWDD7JBQoACBKMPuEFCIAAFCwW8dp +0Q8AbBAEGascijIpkn8JqhGqmSyQBviSAiAAEFgw/fr+IAsQcDD+lAUh/gJjMPyUBigAQGow+JYC +IgAAUnBbx1nAINEPAABsEAiVEogihjAvIAeUFPYHRwboATAw9YHwbiABfDD/FgEhJgA14Pt8ASIA +AFCwWa8h9qG4YgAAIrD2FgMvjRAoMPIWACDWADXg93IJAgAAMPD3PBAjwAQ4oPAAHmIAIBiwaYEI +ihCLZVjqI9SgZkDfJmww93wwJgBSFZAoYBDIjmiBRGmC6ShgEWWP1GAAcwAoYBHIimiBIGdP1HVB +0WAArooQi2X9EgMiAABh8FjqXPP/5GIAACKwAIoQi2VY6lPz/9RiAAAisChgEciKaIEgZ0+cdUGZ +YAB2ihCLZf0SAyIAAGHwWOpO8//kYgAAIrAAihCLZVjqRfP/1GIAACKwAAAAihD7YgUiAABh8Fjp +//P/WWIAACKwAAAAihD8Cv0gABBYMFmwJvwSAiIAACKw9voAJgB3rpCIMAaIAZgwYAANAAAAAAAA +8hYAIAAQIDCJERiqPgyXEfyqPhYAIEXwKnI6ghAMnAr8wpckAKlCoCtyOQy7AfW8AAFOADbgLYJK +/6pLESMAN2Augkkv8n+JFP/rAQ4Aif+QKCAUCImH+CQULACekiD7XAACAABg8PosAA7gASAw/RIE +IAEQeDBYWxmKEvoKRwAEEFgw+3Y5IjIAOqCKJ40UwMD6rCAiAABbcFhV89Kg0Q/AINEPx7TyFgAv +/67akPosAAAcEFgw/AoAICAQaDBYYiL8EgQiAABQsP0SAiIAAFjwWFrR0qDRDwAADAxH+cJyYAAQ +EDCIEIiHgoj3gRUvwBBgMPmCCyBAAmowDNwBrHf3fEAmAE2WUIQUKYkUDEQR8kUICAAgJnD5hRQq +AE2t0MkziBTIj9kgbYkFAAOGAElhJdIABFUI/wIABgBqPVCIIPXWACgAQDIw+CYAIAAQEDDRD4kw +BpkBmTDRDwAAAPosAAAcEFgw/AoAIAEQaDBYYfVj/0uCEPP+smAAEFgwixH6LAAAABBgMPu8GCAE +EGgwWGHtY/8p2iBbxB1j/r7AwJyLiJAGiAH4lgAgABAQMNEPAAAAAADyfwwANwA04I4UD0UU+lwI +IgAAQPD67jYCAABIsG3pBQAIhgBJYYsUrzj1uwwAgAJLMG25BQIIhgBJY4ggD04Mrs4u7ED+1gAo +AEAyMPgmACAAEBAw0Q8AiCAvzED/1gAoAEAyMPgmACAAEBAw0Q8AbBAEKCAFzY4qIgcrogwtqRT+ +ogkgYAJKsPy8yCAOBErwZcADyN3I6/osAAAAEFgwW8Zu0Q8cqcQfqez5+v8gEAJasPmmACAAEEAw ++CYHKgAR19Aown0fqeWbgZ+jLsJ9nqItwn/7xn0gAgJrcC3Gf9EPL8KALs0Cm/Geoy3CgJ2iKcKC ++8aAIAICSnApxoLRDwAAAGwQBByp5huqDyzCpCuyj6PMCcwRrLspsRrA8v6UCmAAEGgwLbUaYAAC +aJMQLrEaD+4CDg5P/rUaIioAP6D6LAAAABBYMFvGRNEPAAAAAByqiIqwK8F+C6oMWOnHY//dAGwQ +MCogBxipePoKQQIAAFjw+xYmI8AEPqD7qXQSACBE8CgyOvoWUSIAAGCw+6sKAEoQSDD7spcqB+JO +ECkyOQuZAfecAAAH3ypgjUgVqnL6qW4f/xBYMP3yUAAAQINQLRww8AoXAgAAMrAADYoABo0uQhIv +QhMqQhGNSShCEJ0ejU2YHyoWEIhPikwvFhIuFhGPTioWEy0WFC8WFSgWFo5L/hYXIMACaHAADYor +FhsrFhwrFh0rFh4rFh8rFiArFiErFiIrFiMpFiwsFlIuUkkvUkgvFhkuFhpgAErx+gcAYAJocABN +YQBNYQH6i49JLxYUjk0uFhWNTC0WFohL+BYXIMACaHAATWEATWErFiErFiIrFiMpFiwsFlIoUkkq +UkgqFh8oFiDHvysWI/sWIiBgAlBw+xYhIMACWHBY6Y4vUXkPAgD2rAAIBxh+kC9RhH+iDShRhQ+I +CP8CAAwHDkKQWOnK9vr0IAdbKqDaIFjpoiVRhA8CAKWl8xYnIAdlLWAfqW4YqcseqZcv8qQsEiYu +4o/zQhguACB9cPdCGS+QBD/g/+4IAAEQaDAt5RovQSslxgEvFkAcqhgmQhorQhcpQhYuQhQpFkMr +FkL5FgIoAEBDsCgWRPgWAyIAAGlw+xYBKngBcDD6FkEgABBYMPoWAC58AXAw/hYqIAUQUDBZsDHA +pfyqBxAAEFgw+aoEEgAAaPD5FgEo4AEQMPgWRSIAAHHw+BYAIgAAebBZsCXAkf4KACCAEGAw/HwB +AgAAW7D8nDkKBQBecPwSKioJAGbw/woCIgUqAyApFjQiFiv9Cgoh+gJDMPjcOAAAEEAw+BYzIAAQ +aDAtFjIZqabyqekQARBoMPk5AQAAEFAw+to5CAUAT3DwhAQICQBWcPc9GAAFEipgA3pTKhY1/wIA +AASupZAGWlD6FkYoFAEwMPgWRyIEiTGQKCIwCIhB+BZIIASH0ZAGyUH5FkkiBJE1kCoiMAoqQfkK +ASAQEEAw+HgBAAAQeDD/nzkIBQBCcAj/Av8CAAAE5qvgH6nI/xY2IAAQSDApFjcGyVAJ+BMJiAL/ +AgAABN8qIP+pChAAEEAwKBY4LxY5Bt9QD/kTD5kC/wIAAATXqmD4qbgQABBIMCkWOigWOwboUAj/ +Ewj/Av8CAAAE0Cvg+ajzEAAQeDAvFjwpFj0GuVAJ+BMJiAL/AgAABMoqICwWKv+pYxAAEEAwKBY+ +LxY/ACQEIhZT/AoBIAAQSDD6FlUgIBBAMPQWVCAAEHAw9AoQIgAAe7D6qMYYAEBB8PnJOQgFAEMw ++JgCAgAAE7D6OgEOBQBBMPio1hoFAFMw9AqAKgkASrD0CggiBQBRMPr6/ygAQEDw+hYAKAUAQzDy +7gIICQBKMPhPOQAGEBAw/QoEJGABaDD7EiwsBQBcsCQWKSISRvc/GAwJAH9w/hJHLAkAd3DxxAQJ +ZAEcMPc4GAlABD5g/w9BCIAEOiD3IhEICQBKMPkSPC9gBDug8qlyHgkAE7D4qSkUCQBBMPQWAi9A +BD/g9nRSDAkAd3D+GgAoAEBBsPISSC4FAECw+BJVLAkAd3D+RBAOCQB/cP39EwMABDig8v4TCKAE +OiD0EjYiCQAgsP4SNywJAHdw8hIzLgkAF/DyFkokCQBBMPQSSS4JACfwCPgT+BI4LgkAQ7D+IhEE +MAQ5IPT+EwwJAHdw9BJFLgkAJ/DyEjouCQATsPgSPi4JAEfw/hI0LAkAd3D5Ej0iCQBIsPISOS4J +ABfw+BI7LgkAR/D/FgEiAABRcP+pPx/QBDug8hIyLgkAE7D+Ej8sCQB3cPZEEAgJAEow+N0CApAE +OKD0IgIOCQB7sPQSVC//EHgw8hJTLAkAF3D+CgAsCQB3cP0WSyAAEGgwWFb9AWQELRI1/hIqKgoB +NDD8CgAo4AE0MP8SSyh8ARgw/xYCKIAEOiDzL10MBQBacPusAAIAAFFw+akdHkAEP+D5FgAuCQBH +8PDuEQzABD9g9z4YDAkAd3D+DkUMCQB/cPbuEQ//EHgw/goCLAkAczD9CgAsCQBrMPwWASABEGAw +WFbdJhIpKRJBLRJA/iFlL/8QeDD+Fkwv/xBgMPwWACIAAFqw/hYBIAEQYDDw2hEABBBwMPqZAgAA +EGgw+RYCIgAAUXBYVsz8CgEgABBoMP4KBi//EEAw+RJEIAAQeDD5FgIiAABasP8WASIAAFFw+BYA +L/8QeDBYVr/8EkIgABBoMPsSTCAIEHAw+xYCL/8QeDDTD/wWASIAAFqw/AoBL/8QUDD6FgAiAABR +cFhWsv4SSiABEGAw/fr/IgAAWrD9FgAiAABRcP5PFAiABDug+P8CAAAQaDD/FgEoQAQ7oPjuAg// +EHgw/hYCIAoQcDBYVqHAwf0KACAMEHAw+SIuL/8QeDD7rAAP/xBQMPoWACAAEFAw+hYCKFgBTDD5 +Fk0pAAQ+YPkWASIAAFFwWFaS/iFfL/8QeDD9Ek0v/xBIMPkWAC8AEGAw/ktbD0AEO6D9DV8KCQBm +8P7dAgABEGAw+xYBIA4QcDD9FgIiAABasP0KACIAAFFwWFZ/wND4EkMgEBBwMPDEBAP/EGAw9zkY +D/8QeDD/FgApIAFMMPkWTi//EHgw/JkQC2AEPiD4aFkKCQBm8PmIAgABEGAw+xYCIgAAWrD4FgEi +AABRcFhWasAw9/r/IAEQYDD/Ek4v/xBwMP0KACIAAFqw/RYBIgAAUXD+FgAgABBoMP/PSQASEHAw +/xYCL/8QeDBYVlvAwf0KACAUEHAw//r/IAAQSDD5FgEv/xBAMPkWAiIAAFqw+BYAIgAAUXBYVlD8 +qH4QFhBwMP36/yIAAFqw/RYAIAAQUDD6FgIv/xB4MPwWASIAAFFw/AoBIAAQaDBYVkPAwf0KACAY +EHAw//r/L/8QSDD5FgAgABBAMPkWAiIAAFqw+BYBIgAAUXBYVjj5rAAFmgA1oP8CAAICyQGg/wIA +AAMVBaD/AgAEAxEFoCMWGPMWGSDAAlhw97YCIP4CYHCXs5e0l7WXtpe3l7iXuZe6l7v9p00QEAJy +cPudASBAAlJw+BIrIAICMzD8p0kRAAJa8PsWMSCgAjhw9IQfYGACWnApFigYp3n/CgQiAAAZsPan +ORPgBDlg+CICCYAEOWDyFlAoCQB6MP+cAAAAEBAw+BZPIAMQQDBtinOd8CkST/n2ASIAAEuw8AYX +AIACc7AACYrCmJn1KRJRKBJQ+PYGKbAEOKD4qDEYCQBGcJz0+JkCAAICELDzPPAiAABA8Pn2ByIA +AEnw9AgWAeACOfD4rAAAgAJ78PAIpACAAlKw8gkWAgAAQvDwCKIAgAJa8C4SKPeoGBAAEEgwKRYY +K+0BI3LRIxYa93LQIAAQeDD3FhkgAhBIMNMP87wAAZACOvD7vOAh4AIY8G2ahv3mMCAoEFAw+BJP +IgAASfD45jEggAI58PAGFwAGAkPwAAmKLOY0+RJQI7AEOiAq5jX55jYgAgJ78P6EBmABEEgwwJAo +ElEImRECmQL5p/4YCQBKMC7sQPIcYCgJAEow+OYnIgAASPDyAhYCAABC8PAIogBgAhBw8AIWAIAC +GPDwCaAAgAJa8CcSKPd9ASBEEBgw8hImIIACOfApQSr7ElIgANPCUBin6B6nm51wibD8dgIgCBBQ +MJpz/nYFIAIQUDD4WAIJgAQ+YPh2BCgJAFZwmXHwBhcAMAJJ8AAJivM8AiBAAjnwj0DTDw8CAP8C +AAAA06vQKSABAJkyhSEAJAQuQhktQhj8Qhoq4AFIMCoWLg7dGPwGSQwgAWww/RYtIBgANqAvQhQZ +p2MPyFP4jP4uAEBP8Aj1OPuyACIAAFHw/QoBLBoBYDD+CgQgMBB4MFmu0R2mxisSLfwSLiAEEEgw +8A0HAgAAarAATWEATWEATWEep4UAvRH4p7UcCQBtsPimAiwJAHdw/aYAIBACeTDxDxYAIAJysAAO +ipWmKEIUDA0G/aQdKHwBQDD4pBwgCAJw8C8SJy72OfkkACAAEBAw0Q8AACgiLQiYUCgWR8CQ+RZG +Ift7MZAGClH6Fkgj+3zRkCgiMPgKQAIAAEuw+BhACAUAV/AJiAL4Fkkh+3M1kPP25GouATAwAAAA +AAAAAPkKASAAEEAw8hZTKmABaDD6rP8gABAQMPqYOAAAEFAwApo48hJTL//HRpDAgSgWR2P/igAA +AAAA/wIAAf9NRlAepuIvQhqdcIqw/HYCIBAQQDCYc591/3YHLgkAcXD+dgQgABBIMPiqEQACEHAw ++XYGKgkAcrD6dgEgBAIY8PP+VGBAAjnwAAAoEifzhjkgBBB4MP8kACAAEBAw0Q8pFjMiFiv9/AAA +ABBQMPoWNCwFAF+wLRYyY/W0KSIxCQlTKRY1Y/XZwID4FjYgABB4MC8WN2P2NMDw/xY4IAAQSDAp +Fjlj9kPAkPkWOiAAEEAwKBY7Y/ZSwID4FjwgABB4MC8WPWP2YQAAAPwWKiAAEHgw/xY+IAAQSDAp +Fj9j9moAAAAAE6ZO+hYwIAAQUDAqFi/0AwcA4AJAcABIZSMi0PMWHyAEEEAw8iLRI4AEPWD4pisS +CQBE8CIWIPKmZRvgBDlg8xZPIgAAGbD2jAAAAhBAMPISJioJABKw+hZQIgAAUnBtip4vEjCdoCgS +T5ih8AYXAgAAS7AACYr4Ei8gABBIMCIWU//8QCIAABPw/xYwIAEQeDAInzn4jAEpsAQ+ICgWLygS +UQj/EfymBCgJAH5w+accGAkASjAvElD/pgYggAJzsPmIAgIAAHnw+KYHICgQSDD5pgUiAABA8PoI +FgHgAjnw8AKqAeACGPDyElMiAABK8PgPFgCAAlrw8AmoAIACUrAnEjHz/GBgOBAYMAAA/QoAIBoQ +cDD8pwMf/xB4MPmnAhAAEEAw+RYBIgAAWrD8FgAiAABRcPgWAiABEGAwWFTD/hr/IAEQYDD9pvgf +/xB4MP8WACIAAFqw/RYCIgAAUXD+FgEgABBoMP+m7hAcEHAwWFS3wMH9CgAgHhBwMP+m7BAAEEgw ++RYBL/8QQDD5FgIiAABasPgWACIAAFFwWFSr8/nrYgAASrAAAAAAAPwKASAAEGgw+CIwIBoQcDD/ ++v8iAABasPkKACIAAFFw+RYCKBgBQDD/FgAo4AQ6IPgWAS//EHgwWFSZwMH9CgAgHBBwMP/6/yAA +EEgw+RYBL/8QQDD5FgIiAABasPgWACIAAFFwWFSOwMH9CgAgHhBwMP/6/yAAEEgw+RYBL/8QQDD5 +FgIiAABasPgWACIAAFFwWFSD8/lJYgAASrCLSS1BFv5BFyDuADSgHKa2KUIRKkIOL0INKEISJhYJ +KBYDKxYIKhYH+RYBIAUQUDD/FgUgABBIMPkWACAAEHgw/xYEIAAQWDD7FgYgABBAMPgWAiAoEFgw +Way88xYnIfjEraAiEib7ElIvnhBQMPokAS+eEEgw8/sEYAAQGDAAAAAAAPPwQmAAEEgwKxJR/QpK +IgAAUzD7vBggABBgMFhdhcck0Q8iEib8ppAQBRBQMPMWJyAYEFgwWaykKxJS9iQBL/QQSDDz+rRg +ABAYMCISJvymhxAFEFAw8xYnIBgQWDBZrJorElL2JAEv9BBIMPP6i2AAEBgwHKZ/iEyPTZYS+xYB +IAUQUDD4FgAgKBBYMFmsjv8CAAH4aK2gIxYnY/9BAABsEAosIAcYpVEMDEEMxhH+pVAWACBBsChi +OsDT/s4KABUQSDD+4pcqAWhOECtiOQ67Afq8AALKADbgKzADF6YN/KX1EtQAtuAlQhQFiFP4Fgcu +fAEsMPxVAQIAxIfgwFAtQSobpUb5pUcQAhBwMPimThAAi0NQjzGboI0gl6X5pgIuCQBH8P+mBC2A +BD9g+aU3HAkAd3D9pgEgCBBoMJ2j8AkXADACSrDyGR4AQAJSsLJVjkD/AgAAAIwrkCkwAQCZMgAk +BC1CGidCGf9CGCrgAUww+xYKLyABaDCeGAf/GPcyAS4gAXww/xYJIBUANuAoQhQIyVP8iAEB/AJK +cAmHOIsg/axQAAQQcDD/CjAgARBoMFmtOYkYjBodpSyLGRil8vANBwIAAGqwAE1hAE1hAE1hALIR +/6YdEgkAEnD/pgIiCQBAsPKmACAQAnEw8Q4WACACarAADYqXpiJCFAwIBvikHSJ8ARAw8qQcIAgC +eXD/ZjkgBBBwMP40ACAAEBAw0Q8AAAAAAP+lbBH/k0dQKEIajTGboIcg+aYCLAkAf3CdpJilmKf4 +dxEAEBBAMPimAyYJAHXw96YBIAAQODD3pgYgBAIpcPP+52BAAlKwAPVmOSAEEEAw+DQAIAAQEDDR +DwAfpfwZpfwoQhb6QSsiAABasJgVmhT6MgEgARBgMPoWBiAIEEAw+BYCIAwQcDD+FgAgABBoMPkW +ASACEHAwWFOvjhePFP2l7RIAAFqw+hIGIAAQYDCcEf0WACABEGAw8P8RAAAQaDD/CgAuCQB7sP4W +AiAEEHAwWFOhlRL8CgEgABBoMP4KBiIAAFqw+hIGL/8QSDD5FgAgABBAMPgWASAAEHgwWFOWixXA +0PUSBiAQEHAw+2xZC2AEPuD7FgIj/xB4MPwWASIAAFqw+soAIAEQYDD6FgAiAABRcFhTiPwKASAA +EGgw/goAIAAQQDD4FgAgAhB4MPgWASIAAFqw+BYCIgAAUXBYU30cpUrz/W5gDxAoMAAA8/02YAAQ +WDD7zBgiAABQsP0KFSAAEGAwWFyfxyTRDwBosyTBlnmxEca6+zQBL+oQSDDz/ZRgABAoMC36ni00 +AfP/7m+eEEgw/TQAIAAQEDDRDwAAbBAYLSAHF6R+DQ1B+0IIJcAEP2D/pHwUACA9cChSOv/fCgYf +AVww//KXJADgxiAuUjkWpZj/7AEOANn/kChhjhmkkP36/yEAADYg+hwwIPwAAvDwKRcAYAJQcAAK +iiwWJSpCEitCEy9CES5CEIhJACmNmB6ITZ4fLxYQjk+PTCsWEioWEYtOLxYTKBYUKxYVLhYWikv6 +FhcgwAJQcAAKii0WGy0WHC0WHS0WHi0WHy0WICpiQyliRCkWGioWGS0WIS0WIi0WI2AARQAAAAAJ +iwBKYQBKYQAJiywWJYhJKBYUj00vFhWOTC4WFotL+xYXIMACUHAASmEASmEtFiEtFiItFiMpYkQq +YkMqFh8pFiAtFiMtFiItFiH6HDAgwAJYcFjkmy1hbywSJfusAAgAa26QKmF6/mF7LAAHUtCq7v8C +AAwAYPLQwGD7IgAh1AC14MDQ/goEIgAAUzD/CigiAABhsFmsUh+lTBikpI4gLUEWKIJ/LaUCKUEX +CO4MKEIY/0IZLgkAe7CeoIxNnKKLTJuj/UIJKAkAMjD5pQMggBBIMPimBC4JAE/wn6X9jRQOgAQ7 +YJ6pnaj8QhogBBBYMPymByABEEgwK1Y5KTQAKiAGiCKxqvokBigJAEow+CYCIAAQEDDRDwAAAAAA ++9wYIgAAULD8CgAgBRBoMFhcEcck0Q8ALUEWLkEXhkn7FiQhxQA14BylGShCEYpOi00vQhKWGPoW +ByAAEEgwmRCbFZ8T+BYBIAAQeDD/FgQgABBAMCgWAvkSJCAAEFgw+xYGIAUQUDD5FgkgKBBYMFmr +HykSJPwSJSH/cK5ghzEAJAT9pJYfnhBwMC40ASpCFPhCGSAwEHgw9kIYIAQQcDD5QhoqfAFUMP0K +ASoAQGqw+GYYAfwCWvD7pzgCAABTMPmsUAYgATAw+yIAIyABSDBZq/sYo/DZoPAIBwADEHgwbfoC +AElhGKSyAGkR/6ThEgkASLD/pgIiCQBAsPKmACAQAnEw8Q4WACACarAADYqXpixCFCsKYvukHSx8 +AWAw/KQcIAQQSDApVjn5NAAgABAQMNEPwND+CgUiAABTMP8KQCIAAGGwWaveGKTZLEIRGaQwjyAu +QRYpkn8upQItQRctpQMJ/wyco/tCEC4JAEfwn6CboilCE4tJmaUoQhKYpI9NC4kUn6eOTJ6mjU+d +qYxOnKgvQhn4QhgqgAQ+4PmmDiCAEEgw+6YPLgkAT/D/pgsoCQAyMJiq/kIaIAUQaDD+pg0gARBY +MC1WOSs0ACwgBooiscz8JAYqCQBasPomAiAAEBAw0Q8AHKSrKBIkj02JTJkQ9hYBIAUQUDD4FgIg +KBBYMFmquioSJPwSJSH+pi6gY/5nAABsEAoFCEf2PAACAFgCIIkizJ0pMBhkkGVokXRokwZolBnA +INEPJTwY21D6LAACAABg8Fv5+GSgc2av5RqjcB2jiCuiSv3SfyFoADbgLKJJ/csBDgCu7xAuIBQO +5If+JBQsALOToIon+0wAAAAQYDD6rCAiAABpMFhPOtKg0Q/aIPw8AAAwAljwW/7cY/+mAAD1PBgi +AABQsPw8AAIAAFlwW/4DKzAYabOLY/97LDAY/wIABf+3GyBj/30tMRaPOC4xF4M5/+VQAJoAA/Ac +pHQrYhGIboltKmIS8xYIIAAQeDCfEJgXmhP5FgUgBRBQMPsWASAAEEgw+RYEIAAQWDD7FgIgABBA +MPgWBiAoEFgwWapyYAAaHKRiiGwvYg3zFgEgBRBQMPgWACAoEFgwWapqiieMqPuhFS/AEDgw86IL +IEACarAH1wH3uwgAABB4MPu8QCD6BGDwKKkUDE4Rroj4pRQqACBjsHqzdclq02D5zAAAFgA1IG1J +BQADhgBJYSrSAA8CAA6qCP8CAAYATl6QmtDzzAAAQgA1YC80GC80Gf80Gy//EFgwmzdj/mAAAAD6 +LAAAHBBYMPwKACABEGgwWFsfwCDRDwDaIFu9T2P+lP+mCy/GALVgwMMsNBhj/7z8uwwANgA1oAtD +FPg8CCIAAEmw+Eg2AgAAUzDTD22JBQIJhgBKYwtpCPNIDACAAlHwbYkFBAmGAEplC+kMqXkpnECZ +0GP/agAqfECa0GP/YWwQDh6kHCggBSwgByfhYCowA/wMQQAEAjEw9xdACBAAOiDAINEPjSLTD9MP +9RYFIoMAt2AvIBYoCv/6FgMgOgRD8CwWEfS1GgIAAFCwWAU1LBIR/qQIFAkANqAdovQaotst0IAM +yxGqu/+yOiBuAmtwDU0UDW0Js93/AgAKASbv0B+i0ymyOQ/PCi/yl/sWBCgAQH5w9ZwAAjsANmAo +okpkgfws4h4pokn8mwEOAPnmUB2j8fsWAiJlALXgKjAgLwrt/wIABgE5fpAoCuz/AgAGAN7GkCkK +DnmhCisK7v8CAA4Br1qQwMD8FgkgQAJQ8MDQnRgvIReLLB2j4RyjCYigHqPeLMLEKSAsAA6L/LwM +CABAajD8bBQAARBoMP3sYAkABD5gCf8CCP8C/xYKJgEZdxDAwC0gFv4K/yBAAnjw/xYLIDgEc3D8 +Fg0iAABT8Fu8JvusAAIAAFCwWAUUjB0vIQcYo8oeo8f5o8cfQAF8MAz/Ef7OCg4JAEfwL5YALSIA +LuIA+BIDIAAQYDD+lgMtgAQ/YPyVBSwJAG2w/ZYBICACWPDyCxYAIAJScABKY/iWDyHWALXgDM4C +KCAUCISH+CQULAEOkiCLFSdM/gx6EfoWByrgAVwwmxYfo6vdUPwKACIAAFvw9AsWAAICYzDwDaQF +6AI7II0WLFxADwIA+woAIgBxG2D9EgsiKAA5IPYNFgACAlrw8AymAegIOvDAkC8SCGXw5IgZjxeo +WPUSCi4AIC/w9YYQIIACe/D1/AAAHAA3oBqjkogaCogC+BYKJ/AEOaDz/4FgABBwMIQyJCYcjDH/ +Fg8iAABb8PkWASIAw4cQIwoA+RYBIADSLyCja4wU+8Y5IgAAEnDRD8LQnRnz/lpggAJQ8AAAAAAA +APosAAAcEFgw/AoBIAEQaDBYWlf6LAACAABY8P0SBSIAAGEwWFMH0qDRD5sU8/3FYAAQSDArzBj6 +LAAAARBgMFhaTGP/zQCKJy4WEJkR9eGvYEACUrD7CgIiAABpMFhODIsYLhIQ+awADx8ANuCNEP1W +ECAAEGAwLFYSY/8KKCAsACON8A0fCDAEOiAo5uAIDYsBEGlj/YQAHaNXizj8o1YQEBBIMJkZ/bsB +AEACaPD9FggqCQBm8JsQ8/2XYGACUPAssAD/AgACAKXjEMDAL7AB/wIAAgCy49DAkA+eEQ7MAmfN +sGR8mmAAwxijOx+jOQozjAAIayogLC/y3vChBAABEEgw8JkaCxcBeDD6mQEADxBAMP8MQg4AYE4Q +KTAQ/wIAAgC//lD/AgAAAF8HICvM/voKASAAEHAwC644Y/3aAAAuFhD7EgIiAABQsFu8Oi4SEGP9 +0gAA+iwAAgAAK/D7/AACAABhMFu9oYwxKRIB86wAC8AEPqD3zmRqACBdcNog/AoAIgAAaTBbvXOj +rKxsjRSCESzWOdEPAAAAAAAA+iwAAgAAWPBY4uNke9MdowoMM4zwDYwAABAQMNEPAAD7zBIiAABQ +sP0KACABEGAwWFnnY/48AAAozPv/CgEgABBwMAj+OGP9MRqifokaCpkCmRrz/SRgABBwMAAAAAAA ++woCIgAAaTBYAImJES4SEGP9bgAbi442LTELDQ8/Dg4/DguLDAhEDi9h+hYOKgBtw9Dz/phgARBg +MImi/wIAAAByDlAJyhQEO4sCK4sKDkn57AAMgAF8MAQZY/2TBnABEFAwwKB69wfwAA9iAABKsP8K +ASAAEEgwCvk4/BYMLloAtmCMMvosAAABEFgw/AxfAAAQaDBY4o+MHPP+PW//EEgwHqLWjTR+0TfA +4ReiNv/pSAB6AD8g/wIAA/4wGyAoICYaos8CiBEImAqqiBqiOaqIiID3iAEAABB4MAj+OGP8OCkx +CmmSwfP/wGAAEHAwHKLFDZsRrLuLsPe7AQAAEFAwC644Y/wSAIwy2iD8DF8AABBYMFjib4oeiyzz +/a5v/xBgMB6iuS0xDn7ZCioxD2P/EwAAAAAA/wIAAf7O59CcHPP/PW8gAXAwAABsEASJJ/iSCC/A +EHAw+pEVIgAAWLDykgsgQAJicP+ZFC4AQHMw/qoIDcAEPSD6rEAglgRAsK3//5UUKAAgR3B5o1HJ +N/I8AAAVADUg04BtSQUAAoYAQ2EpwgANmQh6kXuZwMhbCuow+rYXIgAAEjDRD9KA0Q8AAAAAAAAA ++CwAAAAQYDD8lgsv3AC1YGP/4QAAAAAA+KkMADYANOAJShT/rAgiAAAQ8P9PNgIAADow0w9t+QUA +AoYAR2EJMgj6RgwAgAIbsG1pBQIChgBDYwnaDKrqKqxAmsBj/4YALexAncBj/31sEAT4LAAPwAQ9 +YP0hBSnABDzg/CIBL8AQcDD+LgECAABZMPNUDAoAIHNw+qxAIgAgSzD5/wwKABHQkMn3DEYRpiZ2 +oxzITdMPbUkFAAKGAEthgoHRD9LA0Q8NIgxj/9oAAAKnDPdFFAIAABrwbVkFAAKGAENhC3MI9UkM +AIACE7BtmQUCAoYAQ2OCgdEPAABsEBAjFhYqMQ2VGJQbIhYVLRIV8jIAL/AQYDD0cgAiAAB58P3S +ByIAAEGw9WIAIwABEDDyFhAvwBAwMPfRFSAeAhCw/CwBAEACa3D21gECACAfMPcWASYAIDHw8zwg +IIACMbD5PAAKAW2w0C4SFicSFSPhDPdxByBgAnOwnhAuFhT3B0oKAWWzkCsSFv4SFCBAAjLwlh8m +sBGYFp8V/RYEJgAgcbAmFhMmsQsrsQqcE/kWAiYAIHGw/gp0KgAgdvD7Fg0uAEBysJ4cK7EAHqDz +JhYR9woBJ8AEOeD7yxQGCQBxsP4SCCH0Alrw9hYSIAAQMDALdjgboN72Fg4u4AFwMPJHFAfgBDug +9qDYEgAgWbD6Fgch/gJZ8PIWCiPABDug+xYJIgAgMLDwADVgABAwMC7ggCgiOvoSCiBuAnOwDk4U +rt393AcgABBIMPqilyoA4G4QKSI5CpkB9ZwAAbUANmCLE4oUjBL1uwgCAwAk8Pu8ECIAAGjwW7dM +KBIWA0QMjIcuEhUvEhIDzAych/9WACYAIDDw/uIAIEACSXD/oL4cACA+sP9WAiACAmtw/xIQL4AE +O6D/VgMuCQBzcP5WASChADcgjx8oEhTwDxYAIAJxcPAOoAAeAD3gihltqQUACIYASWEqEhMvoQKI +HimhBf0mOSACAmPw/84MC+ABZDAPuwz+Dk8KEAFcMA67DPylAigAIF5w/BIMKhABTDALmQz5pQUr +4AEcMPoSESAOALYgiR0okQKxiCiVAomhHqCjjRv8pA0oACBecPmmASH/cQ0gjhaNFZXg9tYAIAAQ +EDDRDy+BDAMOTw75DPyAECBaADZgIoET+SIMAgAAIjAiRRMkEhMPOwwP6AwqQQEiQQX7C08IEAFA +MAuIDPmqDAIAIECw+kUBKBABEDAIIgzyRQUiAEAHIGjEeIgeZYChix0qsQEJqgwqtQGOFy8Kff8S +ES4AQHuwjB8oEhT+9A0gQAJJcPIMFgAgAllw8AuiAB4APeCKGW2pBQQIhgBJZYwWixWVwPa2ACIA +ABNw0Q8AY/5GixgqEhX7vBggARBgMFhYY40WjBWV0PbGAC/0EBAw0Q8vEhMu8QwJ7gwu9Qxj/3eX +EQc5DGP9IAAAAAAAAP4SASIAAFuwDrsMKxYUY/0niB0vgQIJ/wwvhQJj/1oAbBAE8iIHIgAAQLDA +wPv6wCBAAlCw+awAALIANWCNMA0NSPyFKCHgAnNwLoUpLDEMLjEL8jEKLAAgY3D6MBEh4AI7MCc1 +Ey2RBfrIDAYAQFpw8sUMAeACQjD21ggB4AIpcPk8MCCAAjGw9JwACgBeslCkqS+RBQgGTwYGBqb/ ++JUBJhABeDAG/wwvlQUnMBCkIvhzK2QAICOwaHQjKCEACMgU+gr2JgBFAiAlJQEpQA0KmgEqRA35 +NQ0iAAAQ8NEPK8zOK5UMY//SAACFKC0hFY4rC68B9ikULAAgf3D93EAg1gQrsAxOEa5m9iUUIgAg +K7By02LJP8lN8jwAAgAAGXBtSQUAAoYAQ2EpggciogD5nCAiACBwsP8CAAYAROyQkqDz/vdiAAAZ +cA2UDGP/QChc2CglAiZADScK9gdnASdEDfY1DSIAABDw0Q+cK/P+y2IAABuwAAD13QwAPAA04A1J +FPacCCIAABDw9kY2AgAAOXDTD21pBQAChgBHYQ0yCPlGDACAAhvwbWkFAgKGAENjKYIHKZwgDeYM +pvYmbECWoGP/fC38QJ2gY/90AAAAbBAEKTAVjyfYIPz6wCigAUww9FC2YEACU/AdoQQUoOWHOYs4 +jjv350AAAhAwMPdmDAJwAVgw8GEEBWQBXDD3MgAuYAFcMPAiGg4AIC/w8v8KDgBAI7D//A4nAAE8 +MP+FKC/gAXww/+4MAcACOfD3hSkqAEBu8Ps2CCfgATww/jYHIKsANeD0kYFqAEBmsCQxCSIwEaQi +ApIJsiICAk8ihSwkoQUiLBDyMggKACBdMPUsMCCAAlrw/wIACgCu2VCGLPaGGCIAABDw0Q8Ahfgu +8RWC+/b5FCwAQGaw/e4IC8AEPSD+7EAmAKCskKtm9vUULgAgLvD/AgAKAKP/kMk38jwAABUANSDT +UG1JBQAChgBDYS+iAAv/CP8CAAYAtnfQn6DTUAbqMCaGF2P+7CShBfI8QCYAQGaw90cIAIACSjD7 +CgEoAHg80NogAAqGAElhhSEkgSiKI/mgthoANqkQJIYRjCGFIh6gs/TMDAoAIFEw/CYBKgAVopAt +ghD53QEAAgIpcPomAywJAF9w9SYCLAkAd3D9hhAiAAAQ8NEPAAAtghAeoKQJ3QH1JgIsCQBfcPom +AywJAHdw/YYQIgAAEPDRDwAAAAAA/xoAIC4EKTAZoJkmghAJZgL2hhAiAAAQ8NEPJIIQCUQBC0QC +JIYQjiD5oJAeCQB7sJ4gJoIQCWYC9oYQIgAAEPDRD8Cg+oUsIgAAEPDRDwAEWwyLsPuGGCIAABDw +0Q8AwNCd+/P+9GIAABiwBCIMY/8NAAAAAAAA9e4MADYANOAOTxT2/AgiAAAQ8PZGNgIAADlw0w9t +aQUCAoYAR2MOMgj/RgwAgAIbcG1pBQQChgBDZQ6/DK/fL/xAn6Bj/poAJtxAlqBj/pFsEAyUF5Ic +/hIMIgAAEPD1IgAiAABRcPNyACIAAHnw/uIHL8AQSDD0YgAlAAEsMPUWCC/wEGgw9uEVIgAAQbD+ +7CAgHgIpcP1dAQgAQE+w8tcICAAgTbD3fCAggAJKcPx8AAoAusnQmBSfE54SnRGcEAVHFJoVhRwb +nxKXGvVRByBAAjCwlhn3nxkW4AFQMP5pEQVAASww/FURCAAgXnD3nwcUCQA9cJkW9RYLJ8AEOaD1 +IQwmACA5sPAAM2AAEDgwAB6fFi7ggChiOvwSBiBuAnOwDk4Urt233fzClyoAaW4QK2I5DLsB9LwA +AM0ANuCLEYoSjBD0uwgEAwAdcPu8ECIAAGlwW7V9BTMMixyMGI8ciSeIG/oSCiIAAGqwBZkMmSeY +QP/yACYAID1w/p7uHAAgV3D4EgkgAgJrcP5GAi+ABD/g/EYDLgkAf3D/RgEgIAJJMG2pBQAIhgBJ +YSuyFfwiByAkALbgyscuIQwtZjn9Egcr/6bw0IIUjxOUIPf2ACAAEBAw0Q8osQCxiCi1AGP/1Ckh +DAWZDGWQQosUihOUsPemACIAABNw0Q8AAADz/zRgABBYMACLFYoc+7wYIAEQYDBYVs6NFIwTlND3 +xgAv9BAQMNEPBnwMY/6IAAAfnucrIBUpIBQsIBEoIQkuIRb8SggIACBecPjMCAgAIE1w+KsIDAAg +YnD8RQsoACBCcPm1EiAuBHuwjhSMEyilEZTg98YAIgAAE3DRD4IT+RIEIbACejAvpRKXIPSWACIA +ABNw0Q8AAGwQBIon+CwAAAAQWDD0UGpgQAJKsBaexykxDCwwFScwFCowESIxCSUxFvo0CAYAIGXw +8qoIBgAgTfDySQgKACA6sPo1EyIAIBHw95UaJgBKNVAiRRktMBUiMQkvMBH+MBQgdgA3YKL/r+6u +Pi7sMv6GFSIAABDw0Q8AAIWoLKEV8qILL8AQcDD/qRQuAEBycP7MCA3ABD0g/MxAIJ4EKLCt//+l +FCoAICtwesNKyTfyPAAAFQA1INNQbUkFAAKGAENhKpIADaoIfKF0mpDz/0RiAAAZcAAAAPuGFSIA +ABDw0Q8sLNgsRRpj/2mbq/P/JGIAABiwAAAA9coMADYANOAKTBT/zAgiAAAQ8P9PNgIAADlw0w9t ++QUAAoYAR2EKMgj8RgwAgAIbsG1pBQIChgBDYwrcDKzsLMxAnJBj/40ALexAnZBj/4RsEAQmIAcU +nlz3OiAmIAEwMAdnHCggFqRyIyKu8IEEAAEQSDAAlRp1OD0YnkAMZhH0IrEmACBBsIZg+CKvIAEQ +GDDyCgAkAEAhcPQyOAYAQDFw9pY5CAAFQVAAYhHRDwACYgEAIhHRDxOeOAiCCfNzCAPABDigoyIi +LQojIcoiIckDIgHRDwAAbBAGKCAHKjAOiSL8niYR/gJxMPqnCQggAUAw9ZDJbcAEPiAZnjgpkICs +3Z0Q/dI6IG4CSnD5SRQOAQBx8K6es+77EgAqAGn3UB2eFyuyOQ2NCi3Slw27Afa8AADEADbgLcJK +/54pEJkAN2Auwkkv8n8Ynhj8n0cY4AEsMP/rAQ4AQH+QLyEH/p4OH0ABfDAM/xEI/wIv5iyNIPjd +EQADEHgwD90C/eYtICACQPD0DAcCAFkaYG2pDgAIhgIIhgBGZQBGYQBGY8BQKCAUCISH+CQULMoA +uiCJMXGeY4oQ96Y5IgAAEXDRD/osAAIAAFjw/EwAAgAAaXBYTq/SoNEPAPosAAAcEFgw/AoBIAEQ +aDBYVfVj/9EAAPP/PGAAEFgw2iD3nQgAARBgMP3cAyAwAlowWFXtY/+v2iBbuB1j/5b8MgIiAABZ +sPwmHCIAAFCwW7mF8lwADgAgOrCPEC72OdEPAIUn+frAIEACYXD1URUgdwA2oAnNAaXZKZxAbakV +AgiGAAiGAEZlAEZj8AagCgAdyhDTDyXBBYnBKMkEDEoR+ogMCAAgVnD5xgEqACBpcPiIMgCAAlKw ++MUEKgAZ0lDIjPP/AmIAACpwBYgMY//CKdxAmcH5xgAgABAoMCXFBGP+5AAAAADz/61sAEBPMCrB +BQqZDJnBY//FAGwQBCcgBxWdu/g6ICYgATwwCHgcKSAWpYUjUq7wkQQAARBQMACmGnY4MROdnwxy +EflSsSIAIBiwgiAoUq/AQPlpAQIAQBGw8qI5CAADQZDRD8CBCYQ4BCIB0Q8AHZ2aCZwJ/Y0IDcAE +OyCtzCzNCi3ByivBySzBzQ27AXy7A8Ag0Q/SoNEPAABsEAQqIAccnZn/OiAqIAFQMA+vHCsgFvSd +iRwAIGPwKMKu8LEEAAEQaDAA3RrynrgYACfqEB6et/ypEQiABDrg/pkICAkAQPCYkC7Cr/nCsC4A +FvdQCdkCKcawDuowC7gJ/IgRCAAgJ/ComaKZKJJvLpZuA4gM+JZvIAAVLiDRDwu9CfzdEQwAICPw +rcwszQoqwcnzqgwAABBoMA2qNSrFydEPAC7CsQ7eAi7GsVgC1NEPAABsEAiVEYsiKiAH+TIAIAIC +YTCcFvwWBSogAVAw9bH4aQABTDAXnVIYnWouckqZEviCfyIdADegJnJJCGYB+WwAAhcANaAYnWEo +gIAMpREHVQj7UjogbgJCMAhIFKSMLMwE/wIACgDmZtAcnUErUjkMrAoswpcuCv/8tgEOANrm0C0g +FvkWACYAQPdQKjwQW7a/LSAHGZ1J+zogLCABbDAL2xwoIBapuS6SrvCBBAABEGAwAMwa/wIACAFZ +45D4jxAPwAQ7YP+vAg4AIDuwn+Mukq9+wDIukrAOzgIulrAO6jAXnSkIjwn3twgPwAQ/4K93J30K +J3zML3JvLnZuCv8M/3ZvIAFHr+AoIBQvIASkiPgJRwIAuAPg+SQULAD+EmAbnR6PEi0hBxqdHx6d +HPz8Dy1AAWww/EwUDcAEP2D+EgYsCQB3cJ1g+CIAIAICYzAMTAz5/BAqBQBi8PlmAymABDog+mYC +LgkAQ7CeYS0gLCshFxyePPDdEQAAEDgw+hIBKgkAbvD5bCAqCQBm8PtmBCAgAkDw/DIDKuABUDD/ +ZQsgABBwMP5lCi8AEGgw/AtHDABAazD8ZgYqwAQ+4PtmByIAZBqg+EENYf4CUTBtqQUACIYASWEu +IASwSvyqEQIARwOgiDIoJhyJMfgWBCYAIFGw9mwgIgCXhlD2kUpgABAYMKNLsbv7VjkiAAAR8NEP +AAAAAAAAAPosAAIAAFjw/RIBIgAAYTBYTZXSoNEPAACNFsDB/Y0IADACWrD93AMiAABQsFhU2mP/ +zAAAAAAA8/3pYAAQMDD6LAAAHBBYMPwKASABEGgwWFTRY/+pjjD/AgACAMurkI8V/1Y5IgAAEfDR +DygkFGP+lYwn+MIJL8AQaDD3yRQgQAJbMPrBFSwAQG7w/RYDKcAEPSD5dwwAIAJCMPjGCSwAIG6w ++HcyAIACa3D3xRQqAJ3qEGibOKiaKqzw/GwgKgBoV1BoQRiwTm3pBQAIhgBMYSqyAQqaCPe5BCHg +AlKw/wIABgDSbpD6tgEiAABCsGRw3/P+yGIAADowAAAAAAD7EgAiAABQsFu21WP9+dog+2wAAgAA +YjBbuD+IFIkxmhfzrAALwAQ+oPeevmYAIFmw+iwAAgAAWbD8CgAiAABqMFu4D6Ojo0uxu/tWOSIA +ABHw0Q8dnIcIjgn9vQgPwAQ7oK7dLd0KLNHJ+swMAAAQcDAOzDUs1clj/XQukrEOzgL+lrEiAABT +cFgB6mP9YAAI3QwNShRtqQUCCIYATGOIE61u+kwMAEACU7D4jEAgHgA/ILDPbfkFBAiGAEpliBMq +uQQNnAysiCiMMPi2AS8kALagjRPA4P61BCCAAmtwnbGdsPP/DGAAEEAwCogMmMlj/sAoIAcanG34 +L0AB/gJJMPyZEQ6gBD/g+v8CCAAgTbCfmIwg/pxdECAQUDD6lgsgAxBoMP6WCiuABD8g/ZxgGgkA +bvCbmY8rKyEI+iAUKCABQDD+IgkpAAQ6IPgKACoJAEbw+JYNKoAEOqCany+WEf8SBiwJAGswnJ7+ +lhAqCQBu8PuWDCAGAnvw+CQUIgAAEfAvVjnRD4gTKIxAmLFj/l0AAAAAAABsEAYsIAeIIh2cRfqc +LBwgAWAw9YCxZ8AEOyAt0ICqZv5iOiBuAmtwDU0ULdwD/wIACgBjb5AenCIrYjkOzgou4pcOuwH3 +vAAAuQA24C+iShmcNGTwiSmSfyiiSfmLAQ4AQE4QKiAUCqSH+iQULABSkqArIAT8Cv8oTgA64AUM +R2jCGIon+0wAAAAQYDD6rCAiAABpMFhH4tKg0Q/AINEPKyAsfLHWjTItJhyJMfGeb3IAAFnw9pCQ +YAAQGDAjZjlj/7kAAAAAAPosAAIAAFjw/EwAAgAAaXBYTL3SoNEPAPosAAAcEFgw/AoBIAEQaDBY +VANj/9EAAPP/SWAAEFgwAAArzBj6LAAAARBgMFhT/GP/tNogW7YsY/9WAAAAAAD9FgAiAABQsPt8 +AAIAAGNwW7eTjRCJMZoR86wAC8AEPqD3n3hqACBd8PosAAAAEGAwW7dl8/9lYgAgHrBsEAQTnCwj +MsQDIgwCYhTRDwAAAGwQCsDR/kICL/8QWDD1FgEgEAI5MP88AAIAABmw/xYCJgEWv5AfnEIVnBCT +EPAhBAAAEEgwmRTw1hoAABBgMPYWAyYRAFmwieGL4JuQiuAo7f6YFpmhnOGc4ItCKIJ+8/J/IAEQ +UDD3uwwAABBIMPupOAmQBDog+RYHIgAgRPCIMok3nhUtQRH+kgwoAEAyMPg2AiAAEBAw9UUSILwA +N2AtmRT6kgkgYAJCcPjoDAGQAnOw9NCZYgUAQ7CaGGUgSIoY9ZvpEDQANqAZnCQooAAVm+YJiAoo +ghD8oAciAABasP0KAyIAAFDwC4AALUEVK0ER+hYIKgA27tDMK4gYZY+7jDJgAGYAAAAZnBQoIAAJ +iAooghD8IAciAABYsPo8AAAEEGgwC4AALEEVK0ER8qwACgCfZtCLNy25FMjTirlgAAHAoJoYY/92 +AAAAAAAAAPP/Z2AAEFAwKEEQKEURY/8+AACMMszEZSBLZaBIGZvnfJA42sBZopvyCgAiAABasPz6 +/yIAAFDwWE4ZjjKNE4sWjEL6EgUsCQB3cJ0ymsEntoEstoCaQiJFEtEPfscgx/0PzAGcMosTiRaK +QfgSBSoJAGbwmzKYoCSWgCqWgZhBjRfAwPxFESCoALdgjhSx7v4WBCQaALugH5vSjkJj/lYAj0B0 ++VWIF/MSACBQADYgihGPEvAxBAABEEAw8IgaAyAQYDD+8sAv/xBIMPmbXxgRAEowDKwoCO4B/vbA +KAAgZnAskrEpkq3H7w7MAwyZARybQwyqEayqmaLRD9EPiUDTD3SRqvpMAAIAAFnwWN1D/kICL/8Q +WDDz/blgARBoMIwyZc73Za89ihhlrzhj/uwuQRCNEfgSACMgEEgw+d0oD8AEP2AZmy0bm0AIjBD5 +/wgMCQBjsPz2AyoAIF9wL7Kv8IEEAAEQYDAAzBr/AgAP/5j/ECiysAjIAii2sAjqMI8QGZslD/8J +/P8RCAAgT3Cp/y/9CS/8yCrysCj2rw6qDPr2sCH/fjKgKbKx+hIBKAkATzAptrFYAIlj/uMAAABs +EAgGZAkMRBHzFgAkACAg8IxAHpsd/ZsJEAEQWDD/+v8mAMzlEBObfvAhBAAAEEgw+RYEIyAQQDD4 +WCgJwAQ9YPC1GggAIG5wmRLwYQQIACByMJgT8LkaAAAQODD5FgEkEQB9cIvBjsCesI3AKs3+m9GX +wZfAiUAqon4oMn/yCgEgABAwMPSZDAuQBDqg+SY4CAAgUjCMh4+C+BYFIAAQEDD9wgwgABBQMPvJ +FC4AQC/w/4YCIGACczD+3gwBkAJrcPSwimIFAHNwisllIEPJrRmbXiigAAmICiiCEPygByIAAFqw ++hIFIAMQaDALgADNL2Wv1o0SjhOMEY3QLuKv/c0BAAEQeDD9/TkIAD1zEGAAPxmbTiggAAmICiiC +EPwgByIAAFiw+hIFIAQQaDALgACJFYmXK5kU8qwAAAsANuCKmWP/iAAA8/+DYAAQUDBj/3hl0EaO +QHTpXYkQihEoksDHv/8SAyoRAFqwCogBKJbAKPKxL/Ktx58JiAMI/wGIEp+C0Q+IE48RKIKxwOH4 +/wEAABBgMA/sOHzQuGVvtYkUsZn5FgQlXAC6YBObHYxA8/6wYAAQODDRD9Lg9JqfEAEQODD6CgQg +IBBYMPyb2hIAAGlwWaHQjBAAYQT7wsAv/xBwMPB9GgMgEFAw+looDBEAd3ANuwH7xsAqACASsCyi +sSqircff/FsRDBEAazD8qgEKACAm8Jqy0Q9sEAQemtwTm8Yu4rotMm2i7gnuEa7dGJqCHJqU/C4R +AyAQeDD/LygOACBDsIjgrPz6wrAgYAA2ICvCsWSwSnq8UinCr8uUG5u3Gpp8q6oK+ghtCB0oorAv +oq/5GRQOACBH8PqsMC4BAMfw/6ajIA4ANmBj/9sAAAAAAAAA+MKtIAAQSDApxrGY4orXKqwQWEgg +0Q8AgtciLBDaIFu5fGihAtEPANogW7mZEpr3C6gR9KA5YgAgQLAM6jArIoWLsCKs//y7CAIAAFCw +WaSYKjKa8CEEAAEQWDAAuxoLqgIqNppZpM3RDwAAAAAAAPoKByABEFgwWEjJLCJ/LCaD0Q8AbBAE +E5uJIzF+ojLRDwAAAAAAAABsEATAINEPAGwQBPSbgxMgECgwBSIo+JpEFAAgILAkQpfBXwNVDPVF +FnIAIECwAzQJDEQRpCIiLQsiIUjRDwAAEpri0Q8AAABsEAb8m3QQAhBoMPoKACIAACiw+TADIP8Q +cDD+JBYgABAQMPJVGyIAAFuw85QLAkkANmDAvysWACkwCBibZ/8CAAoAxRZgCJgKiIAKgACGM/aH +QgbgATAw+nwAAgAAWbBZoCscm1wnVAwmVA0ooQf4VQcgAhBoMPABU2D/EHAwiTP/AgAIAKSaYC1U +F2ABPoozmhBgATeLM264B/ABL2/qEBAwKlAHCgpBWULzHJtK+lQWIAIQaDDwARNg/xBwMIszK1QW +YAEGizP/AgAEAICC4Gi2KGi1K2i3KPi4JWAJEHgw/wIADgB0etAoUCDAlP1UBSgJAEowKFQgYADQ +LVQFYADKKlAgwLgLqgIqVCBgALyPMy9VG2AAtACIMyhVGmAAqy/CfYkzK8KA8LAECAAgfnD/CgYB +/gJKcPrCgigAQFZwCQkZDZk3Cpk2Dpk2KVQjYAB5iDOYXGAAcilQIoszm1v7VgkgKgA2YC/CgPDx +BAH+AlJw8KoaAAEQeDAA/xr//P8qACBS8A+qAppaYAA9m1pgADiIMyhVCGAAMBubD4oz+VAHKgAg +XrArsIAvCvv/mQEL4AQ+4PuZAgD8EFgwC5kBCpkCKVQHYAABxiq4M/8CAA//MiDQK1AWKlEbiBAf +mmgpwoAAgQQA+BoAkAQpUCMICBsNiDcImTYpVCMown0cmsIIzDYKyjgsURr5mvAQtgRy8C1QB/46 +ICwgAWwwDt0cqdkpkpfB7/vuDAgDAHqw/Ig3BAAV9lAemakLvwn+3ggPwAQ/4K/uLu0LLuFIDq42 +DO43DO4sDs4cLlUb0Q8MiCwIyBwoVRvRDwypLAnJHClVG9EPAMD/nxBj/14AbBAOH5qMKCAE+woB +IAAQcDD6mYwSAAAw8PUJRwIAzIIgJ5z+97c5AgBIAmAtIAcNDEGOImXhUCsgIQsZQmWRz8DVDAtH +DL4Rquopojr/AgACAKfGYCiiOQ+5CimSr/mLAQ4An04QKSAUpJkpJBSMYP8CAAIA8KsQKyAh+xwU +AAcQUDD/AgAIASLikMp1+iIHIPEQYDD8uwECAABpMPskISAAEGAw+qwgIgAAWTBYRT7SoNEPwCDR +DykgBf8CAAABFgZg/wIABgEUhmD/AgAIAW6CYPyZdx9VALZgLcJ/ZNWqKcJ9i5GIkJiwjZCb0Z6Q +npEown+wiCjGfyyd/4sg+8Y+IfACWnCbJy4kIC4kIfqalBAAEHAw/iQUIAgQeDAvJAUuJBcuJRv+ +JRogIAJq8J0eW70GHJqKHZnUHpqKjyD6Eg4iAABasFu8voonDwIAKqwQmh9buFb/AgAAAmoGoCsg +ISwK/vy7AQIAAFCw+yQhIgAAWPBb/wIamTIfmi5j/qkAAAAAAAD6LAACAABY8PxMAAIAAGlwWEnv +0qDRDwD7zBgiAABQsP0KAyABEGAwWFE1Y//RizCZFvsLRwIAjQJgjCItIAf1xQhqIAFsMAy5Eaqa +KKI6/wIAAgJyxiAoojkPuQopkq/5jAEOAmpOECkgFKSZKSQUjzD/AgACAnYr0IoW/wIAAgKkmqDA +INEP/wIAAABwhmD/AgACAHyCYP8CAAIB4gZg/wIABAH9AmDHxfz5UAAHEHAw+AoBIAAQWDD5izgA +BRBoMPztOw30ALbgY/8yIyAHHJkRAyhA/yEIKKAEOiDzA0EICQBiMPi2ACMABDzg85kBHgkAH/CO +IJOyE5kHwMPz/wIAIBBAMPPjAg+ABDug+LYDLgkAY7CesYgrjimftJi587YGKIAEOmD+tgggABBw +MP62BSgJAENwmLcuJBQspjlj/aspCvEJuwErJCFj/bJkvuYDtwsYmiKYGvABU2IAADDw0uDRDwCL +J2P+GY0riSl9kQfA4p4iY/8sACgK8fi4AQAEEEgwCYgCKCQhDAtHDL0Rqt0p0jr/AgACAiZGYC7S +OQ+4CiiCr50Z+OsBDgIcx5AcmdT6IgAgABBoMJ0RnBApYAP+CgEgABB4MP0KgSlABD5g+RYCIAAQ +YDBYR5wfmbMamLaOGcDTLeY5iSIsIAbAhv4gISABEFgw+5kCAAICYzD8JAYg8RBYMPkmAi4AQFuw +/iQhLgkAQ7AuJCFj/oUAAIsnhrj9sRUvwBBAMPyyCyBAAirwCFgB+BYHLAAgR3D93EAmAeE3ECm5 +FAxHEfZ8CAgAID5w+bUUKgHd51DJO9kw+2wAABcANSBtSQUACYYAS2GMUA8CAA8CAKfM/wIABgHv +bxCcUIlgCQlHZJFNBpcLG5nTmx3wAP1iAAApsADAy3yhRLhm/wIABgBjvZAqYAhkoJdooWRooulo +o1Zpqd6JY26T3mmT244n//rAIEACa7D/CgAsAEB/cP/lFCCAAmtwnemd6GP/uowajiKPJ40gKSAW +L/kUmRD4YgMgBRBQMPgWASAAEFgwWZ+iiGMoJBZj/4+JYyklCGP/hxyZrYtj+iAHLAAgYvAswIAt +Cvv9qgEN4AQ7IPyqAgD8EGAwDKoBC6oCKiQHY/9YAItjC4pC+hYLKuABXDCbHFmeaiyhB40cjhsu +JAwtJA0sJQdj/zIamFEfmU3z/LtgABBwMMCi/BINICgQWDBZn4IamEsfmUa4VXdRRC1QCGjRF2jY +DMCLeNnZiVMpJBZj/+SLUyslG2P/3IhgiVMr+gALiAEJiAKYYCwgIS0K8f0KAiwAQGswDcwCLCQh +Y/+2ACshG2SxDCcgFi0gB/UhGiD/EEAw/QxBAKIEQfD4mXMTIBBIMAnJHPkWCCgAIEZwKZKXwY8H +iAx4lSUYmC+JGCIWEAdyCfiZCAPABDig8hIQKAAgFnApnQspkUhgAAQAABmYzgm7NgW7NwW3LAdV +HPUlGyABEDgw8/pPYAMQKDAA/wIAA/4if5CJYCgK/AjYAf76ACgJAEJw/goIKABAdnD4JAcg8RBA +MPyZAggAQELw+WYAKAkAcjAoJCFgAAGJYPP8BmzgAUgwih9btz8bmJ0LrBGsu/sWBSBnADagDOow +K7KFK7IAKqz/+hYEKgAgZvBZoj0cmJWNFCrCf/DRBAABEFgwALsaC6oCKsZ/WaJxY/rkHJk9G5kD +LMJ/8/7magMAZvApwoCIkY2QnYCLkJixnpCekS3CgrDdLcaCY/pR+goHIAEQWDBYRmOPFS7yfy72 +g2P6oQAA+iwAADACWvD8CgEgAxBoMFhP7fosAAIAAFjw/EwAAgAAaXBYSJ3SoNEPJiEIE5fr8LgR +DgIBbDD6/xAGCQBBsPiX3x4JAB/wn8CDIJjCGJfkwvCfw/hmAgADEHgw+DgCA4AEPOAPMwKTwYUr +gymexZbEk8iVyfiTEAAEECgw+MYGIgkALPCTxy4kFC+mOWP6sIon+0wAAgAAaTD6rCAgABBgMFhD +kdKg0Q8AAAAAAAD7zBgiAABQsP0KAyABEGAwWE/BGpewH5ir8/qlb/QQYDCeu/P8e2IAADMwAAAA +AAD23AwANwA04AxNFPjcCCIAAEjw+Eg2AgAAWbDTD22JBQIJhgBLY4sXrDn9SAwAgAJa8G2JBQQJ +hgBLZY0XDHgMqN0t3ECdUGP8J4kXKZxAmVBj/B0AAAAAbBAEiScoIAYrmRQqnCD9kgkh/gJCMPSw +fmjgAUAw+CQGIA4ANiDAINEPAAAAAAAA/AoqIE4AN2Ar0AB8uUP+kRUvwBB4MPpM/y4AQH6w/KsR +D/AQQDD72wgOACB7sP7sQCBABEDw+dwQICACWvD4PBAqABjfkGhBCG2pBQAIhgBJYfosAAABEFgw +W7Q0wCDRDwAAAAAAAAD4JAYvigC2IGP/3g3tDCzc8AxMFLjLC6s2bbkFAAiGAElh/EoMCAAgG3D5 +/EAheAA+oC2s/23ZBQIIhgBJY2P/qAAAAGwQBIgy+iwAAgAAWPD8MAcgAxBoMAuAANKg0Q9sEAQo +IAT4hghiAAAZMMAg0Q8bmJwkIAcrsX7aIPsrFAQgASAwWPdoZa/i+iwAAgAAaPD8CgEgMAJZMFhP +V8Ag0Q8AAGwQBhiYkIouLyAH/Je6EAAQGDD/D0EGAG7GkCPCfwmoEagziDeIjpgQiicpqRT7ogkg +ygA2YC2wFN6w+LAVIBUAN2AqrBBYRO7AINEPAAAAAAAAAPnCfyCsADYgiZcrmRTAyP0KBCClADbg +i5kosBawiAjNOBiXJgz8EfiXJhwAIEMwKcI6CPgK+IKXKgCJ7lApwjn4nAEOAIRGUCkgBSiwBxSY +avS2ACFqAnpw/pkRAh4Av+AfmGSvmSmS+WAAAcCQCJ8RD4gCmLEk4BT44BUgFwC1IGSAgSmwFviR +NWH+AlJwKrQWiicqrBBYRMXAINEPAABj/zEAAAAAAPP/NmAAEFgw8/9tYAQQaDDz/11gABBYMNog +WTMFZD/JjBArwCgtwCn+wCorgAQ+4A27Av3AKyuABD7gDrsCCLsRDbsCsbsrxCsLixQrxCoLixQr +xCkLixQrxChj/4vaIFky82Q/g40QLNAoLtAp/9AqLYAEOyAOzAL+0CstgAQ7IA/MAgjMEQ7MArHM +LNQrDIwULNQqDIwULNQpDIwULNQoY/9F2iD4mCsQMAJb8PjmACABEGAwWE7owCDRDwAAAGwQCigg +BP8CAAYB344g9woAJAHboiAoIAf1DUcIIAFAMPgWCCIB1ANgii4WmBsrMQgrJQgpYh4JqhGqmSmQ +BfgKQiA+EFAw+yAWJgH61lD8Cj0mAfbGUP4K/y4CEuJQiDn4CUEABBAoMAlVDAUFQfVcDy/4EEgw +CVUB9Vx/KAAgKjD1RRQAaAJCMPgWBCA0BHLw/Nz+IAEQUDD6IEEsBQBisFhKRWSj94sYGZaqDLoR +/ZaqGgAgSrAsojr9vQoACAJBcP3SlyoBzMcQLKI5mBn9xAEOAcZvECwhIpcQKyBBKTIJ+pfuEAgQ +QDD8FgUgBBBwMPu7CQ4gAUww/+4MC8AEPuD/l+ceIAFwMP4WAyoAIFqw+qJ/IAMQYDD6FgYoACB2 +cPgkZCB4Akpw+RYHIAcQQDD4JFwiAABYcP+X2h4JAHuw/yUqL4AEO6D+FgAgygJQsFmVZY0WJyU1 +JyRo+CEHIC4QSDD5JFcgUhBQMCokBfmWhBBCEFAw+iR0KUABQDD6EgUpwAQ6IPmXsBgJAEow+EYA +IEQQcDD62xQMwAFoMP8iACtABD7g/kYDLkgBaDD9fUAPgAQ7oPXdEQwJAHMw/pe6GgkAbvD4/xEK +CQBm8PyXtR4JAH1wn0EflmmfQv8SBytABDqg+CBBKgkAYrCaRidFCv5GBykABDog944UCAkAWjD/ +RQsoCQBKMPhGBCCQAmiw8g0WAEACYTAATGP5ISogABBYMCtEMStEMvtEMyAAEFAwKkQ1KkQ2+kQ3 +IAAQQDD4RDAgABB4MC9ENC5ELilELSdELwmJFClELC0gVy1EOw2NFC1EOg2NFP1EOSAEEGAw/Y0U +AHgCUTD9RDgguAJYsFmVGPeLFADAAkCw8wgWAIACSTAASYoACIgACYqIEydEUytEUh2WOAuLFCtE +UfuLFABAAkjw+0RQILACUTAGCYgAyooECYgAior9RhogEAJaMCtGG/kgdCoAIEEwKaR0LyEHKDAH +mDEoIAcsIQj5li4bwAQ5YP8PSgoCAUQw/P8RCqAEPuD7/wIEACBRMPuW9x4JAE/w/0YAKCABQDD6 +IgAvAAQ6IPdGBSwJAHMw90YHIDAQSDD5RgMsCQBbMJxEm0b9RgIgBBBYMP2WARuABDqg/BIJKgkA +WrD6RgEgQAIhMAYDhgBEZwQDhgBEZQyPEQ3/CCz2OSsgFi4K/36xCCogQSwSBFhJXyUhFCMhEg8C +APQKACAqADVgylL6Yt8iAABY8PwKACABEGgwWEFLKGLg9EwBIAICGPAIMy51SdvaIFg+1MAg0Q+K +J4uo/KEVL8AQcDD5ogsgQAIysA5uAf4WASwAIHMw/MxAJgBoXlAoqRQMTxGviPilFCoAIFvw/xYC +KgBkVxDJOMlG2bBtSQUAA4YASWGOEopgDwIADwIADqoI/wIABgB4ZpCaYPP782IAABrwAAAAAAAA ++iwAAgAAWPD/CoQiAABhMP81CCIAAGlwWTdawCDRDwCJImWfY4sY+iwAAAEQYDD7vBgiAABqMFhN +yMAg0Q8AAPosAAIAAFjw/AqFIgAAaXD8NQgiAABhMFk3SsAg0Q8AjSJl3yMrIEH6LAAAARBgMPu8 +EiAAEGgwWE23wCDRDwCXq/P7Y2IAABpwAAAAAAAA+8oMADcANOAKTBT+zAgiAABA8P5ONgIAAErw +0w9t6QUICIYASWmJEao4/E8MAIACSnBt+QUKCIYASWuOEowRCu4MrswszECcYGP/FY8RL/xAn2Bj +/wsAAGwQBvgiByAAEGgwLRYAKiBBG5bYJiAHCqwJ+YkULcAEOyDzggkqACBm8PuyfyYgATAw+xYB +IzgANmD4CkkjMAA04C4wEvsKVSMpADegKSAF/Ar/JgGPXlArIBb4JAUgGgRi8ADFjlhJCmSjSMBB +GZVvwOz8aBEAARBQMPmVbRgAIEow/YI6IgAAeTD0rzkABBA4MPlpCgYFAH+w+ZKXKgF4v1AlgjkJ +VQH7lYAS6wA1YPhcAAIAAFFw8AsHAEACMXBteQIASGFkQbEtIQcflWMNDUoM3RH+lqwcCQB/cC1W +ACoiAPmWphBkEFgw/JVeEAgQeDD8VgIrgAQ6oPtWAyoJAHqwKlYB+SUqIAcQQDD4JFwiAABYcP8k +ZCADEGAw/hYAIMoCULBZlCYeln6KEf8hIiAuEGAw/CRXIEIQaDD9JHQgUhBgMCwkBf0gQSAAEGAw +LCU1D9gU/CRoL0AEP+D6CUYKSAFUMPSIEQoHAVAw+LsRDQAEP2D7mQILUAQ6oPqWgRgJAFIw/FUK +IFQQWDD5lnwYCQBKMPtVCywJAEdw+lYHLAkAd3D9VgQuCQBP8P9WBiCQAkiw8gkWAgAAQbAASGP7 +ISogABB4MC9UMS9UMv9UMyAAEHAwLlQ1LlQ2/lQ3IAAQaDAtVC78VC8gABBQMCpUMPtULSAAEEgw +KVQ0C4sUK1QsKCBXKFQ7CIgUKFQ6CIgU+FQ5IHgCUXD4iBQABBBgMPhUOCC4AliwWZPk9m0BIMAC +QLDzCBYAgAJJcABJigAIiAAJivpdASAAEFgw+1RTIAAQWDD7VFIgABBYMPtUUSAAEFgwK1RQ/iB0 +IQACMbD+VHAhAAJSsB6V0ywhBy0wB50xKSAHLyEI/ZT9HUABYDD8zBEKAgFMMPkJQQqgBD7g+8wC +CwAEPmD4MgAuCQBf8PuU6xwJAGswnKCMIPumAi4JAHfw/6YEIAAQaDCdpZ6m/aYHIDAQcDD4zBEA +BBBoMP6mAywJAGsw/KYBKPgBQDAGA4YARmcEA4YARmUqIgcclMr/+sAgNRBoMPybEQBAAlKw/68B +CgAgZvD3tjkgABBYMPulBCCAAnvw/6YBIDYQcDD/pgAghARyMH2BRcpIKyAWLgr/frEg+iBBIFQQ +YDBYSCLAINEPxP8vJAUoIGixiPgkaC/aALUgwCDRDygkBfP89WAAECAwZE/b2iBYPZtj/9jFkikk +BWP/sfP9FWAAECgwiiJlr9D7bBgiAABQsPwKASIAAGnwWEywwCDRDwCLImW/sysgQfosAAABEGAw ++7wSIAAQaDBYTKjAINEPbBAUlRaXFCIWHPMWBSIAAFkw+xYHIgAAePAs8APyISIiAAAYsPcyDiIA +ACHw9jAHIgAAabCSGigwQfKV2R/wEEgw9gZBDAAgezD4iAkAfgJjMPyIEQwAQEsw/BYJIgAgQLD6 +wgEgMAJBsJgYIiJ//MwQKgLh01DA4PIWASAAEFgwDtIMH5XNjvMJeBEI7ggu4Tcoev//AgAKAvby +EBWVBCYWAify/P8CAAIAADHw/wIACgBK01AuEgkv4gMCqgz3FgMuACB8sP7iAioAA5PQLuwBiBT3 +CgAgAqYmIP8CAAACoiagwCBtCFoKSDT2KQoIAQDBcJiQBigLn4OegomQCUQM+aoMAAICELD/7AAI +ACB6cPgWCyoAA0oQse/+/AAAAgI58P8SCyAYADyg8goAIDACMbD/AgAAAm8lIP8CAAACayagY/+e +DLoKDL4Lj+OKoJcT/uICLgAgfLDyqgwKAAMT0LHuwCDyFhAgABAQMP8CAAAAUqUgLRYbYAAsKBIQ ++7wBKAAgQfD4FhAgGAA+4PsKACAwAmMwDL4LDLoKiqCP4/7iAiAAN6Ug9woAL88ANqBqQcfTD9MP +bQhU9ikLCAEA0TD2LQoIAQDBcAhEDAiqDJjQ/pYCIAICELD/lgMsACB+MPjbBnIAAHuwse/+/AAA +AgI58PghDGIAAHtw8goAIDACMbBkr3P/AgAB/7glIGP/oAAtEhvAsJsQKzAWhBT2EgMg/xBIMP0W +GCAkBErwjBYqMEEAzI5YR6BkpFktEhD5lAUTkAA3YI4ajBL1EgEgkAJY8PsWESC4AlDw+hYSIMAC +QPD4FhMiwAEoMP7fFA3ABD8g9YdCD0AEP+D53QgHgAQ94P0WDyQHASww9VURAgkAOLD3lBAeCQAv +8PcWDC4JABfwLxYV/5VAHeAEOyD9k+oQABAoMPUWGS9ABDug/xIQLgkAe7DyFg4sACBrMPwWDSAA +EDgw/hYUIAoCe/D/FhcgBRAoMPAAEWAAEBAwKBIX0w//AgAGAXlFUMCVCVkv9JJ5YAICKXAnfQEn +fIApMQcak90JCUoMmREKmQKZcIgw/JULEEQQeDD+k9YQCBBIMP52AimABDog/3YDKAkASjCYcS0w +QQYoCoqAKxIV+BYWIAQQSDDw3REKIAFQMPqZDAoJAG7w+pURGgkAZvCbdPsSESggAUwwKRYaKIIA ++nYHIAAQUDAqdQr5EhQoACBKMPl2BiB4AkIwKHUL8AsWAEACSfAASWEpMSr6dC8gABBoMC10M/l0 +LSAAEHgw/3QwIAAQWDD7dDQgABBgMPx0MiAAEHAw/nQxIAAQYDD8dDcgABBwMP50NiAAEFgw+3Qu +IAAQeDAvdDUrEhIvEhkJiRQpdCz+MFcuACBH8C8WGS50Ow6OFC50Og6OFC50Of6OFAB4AlHw/nQ4 +IAQQYDBZkm75EhMggAJR8AIJiABKigAJiAAKiisyHCoSFyt0UwuLFCt0UguLFCt0UQuLFPt0UCB0 +CFFwLBIa/ZTUEIoCUfD7HAAAQhBwMP40dCwgAWAw/QoILAkAazD9NGUtgAQ7IPwWACADEGAwWZJU +LTE19ikLADYQcDAuNFf6kgMgAgJrcC01NS0SFhyUwSx2FovQK3YXiNCOPy8yHCp2GYmS+XYYLgAg +R/AvNhwvEhgt0gCxIvhEDA4AIH4w/xYYLAAgd3D9Ng8gGAA8oPIKACAwAjGwGZNjKXYaKRIawPUP +Xy+4mCh2G/gwdCgAID5w+JR0Lc4At+AqEhAFqgy2qv8CAAP+30Kgjh+NHi3mOSswFiwK/3yxCCow +QSwSGVhGr40eiRX6EhggRxBYMCs0BZqXjzIE+BOUmfiWCCCoALfg2jD7EgggARBgMFhLSNEPAC0S +EIwf9d0MAAUQeDD8wjogDAJrcA/dNg3dEf0WDioARu8QiB2HHyiClydyOQh3AWR/nokc/nwAAAAQ +UDDwCQcNUAA3YG0ICbGq8A6gB/6h7pBj/+8AjBLAoPsWDi3ABDsg+hYZLAAgSzCcH48fjh4u9jkr +MBYtCv99sQgqMEEsEhlYRoKLFYwX/RIGIgAAUPBb/YbRD4/DjsKKwCcWEGP7TAAA8//uYAAQEDDz +/4BgABA4MAAAjxmP9Pr/CAIAAHKw8hYBKgAzf1DAsPL8AAAAEHgw//wEIgAAcLD49A9gAgJa8CzM +GP8KACAAEFgwrPKCIK4ictvb/wIAC/0C81AN4gxj+f0lSgD2FgIkAwAvsPP6DmXgASwwKDBBKIwS +mBjz/q1gABBoMAAAAPP/yGAAEFgwbBAIlBIuISKXE5YU9SAHIgAAaXAqIEGdEfYwAyQgASww+qgJ +ADACOXD3FgUgABA4MPcWAC/wEEgw95QsFgAgGbD7IBYgfgIxsPyIEQYAQEmw+Ar/JgAgRfD3cn8g +KARC8J4XAM2OWEZo/hIHImsANqAYkswMVBH6kswUACBBMC1COgpaCvqilygBDkNgKUI5+pUBDgEI +1lAvIQcYks78kswfQAF8MPz/EQBEEGgw/tkUDgkAR/D/VgAqBwE4MPsiACtQBDqg9JkRDkgBPDD9 +VgMvgAQ/4Pi7EQAIEGgw/FYCKgkAbvD7VgEswAE4MP9iASwJAHsw+CBBKAkAVnD06hEICQBmcPuT +/BAEEGAw8IgRBiABfDD3xwwICQBKMPmT3xYgATww9/8ICgkAWrD6VgYgeAJ78P8WBigJAEowmFQv +VQsYk+74VgcgABBAMPhVCiCQAnCw8A4WAEACaXAATWH/ISogABBQMCpUNSpUNvpUNyAAEEgwKVQu ++FQvIAAQcDD+VDAgABBoMP1UNCAAEFgwK1QxK1QyL1QtK1QzD48UL1QsKyBXK1Q7C4sUK1Q6C4sU +K1Q5+4sUAHgCUXD7VDgguAJYsFmRXCksYPMJFgCAAlFwAEqKAAmIAAqKLSIcHJPKLVRTDY0U/VRS +IIoCUXD9jRQCAABYcP1UUSBCEEgw/Y0UCCABODD9VFAoCQBiMPkkdCAIEGAw/CRlKYAEOiD4FgAg +AxBgMFmRQxuSbPohNSA2EGAwLCRXj2OIYfliACACAlKwKiU1KVYWKFYXjWEvVhmOYi5WGC0mHCxi +ASwmD/tWGiAQAlHwKlYb+CB0KAAgPXAolHQvCggvRjkrIBYuCv9+sQgqIEEsEgZYRbL8EgIiAABQ +sP0SASIAAFjwW/y10Q/A2PkSBCBHEFAwKiQFmTeOIogT+DYJIAAQeDD/Nggv3wC3oNog+xIFIAEQ +YDBYSkXRDwArIEErvBKbFfP/w2AAEGgwbBAGKCAE/wIABgB2DiD7PAAEAHIiIAUIR/0KACIAe4Ig +KrADLLEIGZKeLCUIjC4pkn8JzBGsmfiQBSoAIFqw+qw/L/AQcDD8Cj4qAEBysP4KQiYAlWYQ/wo9 +JgCRdhD8kq0eAJn6ECggBf4KRyDQAjJw/wpJJgCddhD5k2QWALV+EC0kaC0kZi0lNfklKiAIEHAw +LiRk/iRnIC4QeDD/JFcvgBBAMPkiHCBSEHgw+CRlIAEQQDD4JFwgQRBwMP4kdCAHADZgKCRoLyQF +iLt4wykpoANpkSMqYQN4ox3aIPxMAAIAAGlw/7IGIAAQcDBb/wrAINEPwCDRDwDaIPxMAAIAAGlw +/7IGIAAQcDBb/VXAINEPiCf7gggnwAQ9IPyBFS/AEHAw+YILIEACMjD/iRQuAEBxsP4WACwAIHMw +/MxAJgB3XlD7eggOACA/8P+FFCoAd1cQyTb5vAAAFAA1INgwbUkFAAiGAElhimAHqgj/AgAGAItm +kJpgY/6j2iD8CoQiAABpcPy1CCIAAGEwWTNnwCDRD9og/QqFIgAAYTD9tQgiAABpcFkzYMAg0Q8A +iCcuiRRk4EeLiYi7eMNWL6ADafFQKpE3eKNK2iD+sgciAABhMP+yCSIAAGlwW/7OwCDRDwAAAAD6 +LAACAABY8PxMAAIAAGlwW/wlwCDRDwCI2/jDEHAAEFgwLKADacEFLZE3eNu02iD+sgciAABhMP+y +CSIAAGlwW/0OwCDRDwCdi/P962IAAFpwAAAAAAAA+8oMADcANOAKTBT+zAgiAABA8P5ONgIAAErw +0w9t6QUACIYASWGJEKo4/E8MAIACSnBt+QUCCIYASWOMEAp+DK7MLMxAnGBj/ZaPEC/8QJ9gY/2M +bBAYIhYkIxYjLiEVJBYWiC8vIAcrIhwsMAMrFh77FiAv8BBQMP8PQQYAIGTw/xYfIH4COfD0hEhm +AEBV8CwSJI9zKxIjLMETFJLT+7ILIAAQSDD0xBVvYAF8MJtRmVAqEiQOwwwvQmUooRIioRAmoRH6 +ohYpoAQ6IPoWAC4AIEfwLxYVKkKa/ZIQEgAAYLD1+v8kAQA0oPusAAAAEHAwbSkpgnMPAgCi4v9y +AioAA/CQL/wB/u0QKABAbLD5tgEoAEAr8Pi2ACAQAlrw/wIACgBMMxAjFiVtCFmJdMDh+ckSC2AB +TDD+CgAqBQBfsPrLCwgAIF5w9JAHY0AEPmBgADV2wWCJdcDh+ckSC2ABTDD+CgAqBQBfsPrLCwgA +IF5w9JAIY0AEPmBgAewA93wYKgAasxBj/5+Cd492/MwBIgAgE7D9KQEKAANwkLH/Lu0Q+bYBKABA +K/CYsPPj2XAQAlrwdsmeIxIlH5IVF5FPHpIeFZIpLRIkFJE6LBIVKNEjLdBAG5Ep+ogRAAAQEDD1 +0w5sACBDMCkSHglmDC0SIArdC/0WIiOiADTgLRIfDNUR+woKJAAgXXD4UjoqAwBc8Au3CQ93Ef8C +AAoB3D4QGZISKFI5CdkKKZKv+Y0BDgHUThAoEiQLMwwqghwpgSMigRUKugoqhhz6kSwSACBYsPKF +FSgAIF5wKYUj8AoHAgAAS3BteQIASWEnFhwlFhvzFiUiagA24CsWE4gQLRYU+swAAgAAG3D6iBEA +ABAQMPgWISAAEDgwbbmRClwUKRIkKBIhnjCFkJQ0KDYH/DYDIEAQWDD7NgUgAhBoMC02AvsSIyAG +EGgw+FwRBAkAfXD1NgYsCQBrMCw2ASwSIvuyCyAAEEAw+zYIIgAAaPD5kg8gUAIo8Pg2CywAIGHw ++TYJIAAQSDD5NgoiAABYsPa7MXAAEHgwj8GOwGAAJ/d8ICAIAhCw+qxAIMACGPApEhMjEiX9EhQg +ABBQMPAAXmgAgFZwwOD/1g0gAgJa8P7WDCAQAmtw9dm1cBACYzAekbcfkatj/7YAAAAAgnn8zAEi +ACATsP9yCCgAQGyw+bYBKgADcJCx//7tECgAQCvwmLDz49ZwEAJa8GP94gAAKxIbKhIc+rY5IQ0A +tOCOEC8SFgruEZ7wLhIkCZIJKuEh+OERIAAQYDAs5RUs5RP85hwgARBYMPvkQCBREGAwLOQF+ogM +A7AEOKD45SEiACATcNEPwGBqwRP8D0sAARBQMPzIEg4FAH6wqP+vZixwA7DM+sFLYgAAEbDecIjk +DwIA+A9LAAEQUDD4yBIOBQB+sPzM/y4AIEfw9MAcZgAgebCI5QgPS/jIEg4FAH6wCP8I/Mz/JgAg +ebD+7Bgh/9+PIJtRKBIk+VYAIAYCKbAFJRQqgRQihRAmhRHzXAACXgC2oAvLFLO7CysU+7wDIgAA +YHD7Fh0iAABSMFgLlC0SJCoWFSwSHSzVFC4SFS8SJPX1EywmALegwCDRDwAAAAAAAPxyAS8vADfg +r8wszfDz/yRgARAwMI9zDw9Lny9j+7EA8/67YAAQSDD8CgAsPAC1oGP8yAAjEiQtEiODP43XAAeL ++AoBIBACSHD9zRQCBQAeMP0zCAAEEEAwbYoCAElhLTz/DQ1BZNHPLRYX+NwBIAAQGDD4FhokAFOW +ICgSFykKBPiZDAIAAGqwbZlJKRIa+RYYKgAHMNCJ0IjRKBYZYAAJwJD5FhkgABBIMCgSGPIWJiAC +AhIw8hYaIBACEHACiAuZhiISGfKGByACAhjw8hImIBACa3AtEhdgAEEqEiT4EgAgARBoMC2kQCyh +ISuhEfKlFSBREEgwKaQFIqUTKRIWIqYc8hISKaAEOiCYkAy7DCulIdEPwCDRD9LQ0Q/AMw0zDHY7 +BSMWIGAAAiYWIC0SHwzYEauIKBYbKII6/wIABgC9QiApEhsF2Aoogq8pkjkImQEpFhQpEhT9nAAB +ZQA2YCgSJJ6QiYAtFhL4kxEICQB+cPnWBiAGEEgw+RIAIgkATPCU1PPWASGAAhsw81MUCaAEPmD5 +1gcgQBBIMJnVKRIj89YDIAIQGDCT0ombKdYI+IIPIAAQSDD51gogABAYMCPWC/PcMCBAAkhw+NYJ +IAUQQDBtigUACYgAA4otEiApEhvAhviWOSoAB2mQ8AAMYAAQMDAAAC0SIA1mDCgSJPkSICAGAhmw +AyMUKYYcKYUhIoRAI4UTY/sUK4ESKkJl/IIWK6AEPuD8FgAqACBasCoWFWP9sADA0w1tNv0WICBw +ADWgg6GJoJMb+RYKIiIBOaCDo4miYAANAAAAAAAA8woAIAAQSDCTHfkWDCIkAT2gg6WJpGAADgAA +AAAAAADzCgAgABBIMJMf+RYOJCQBOaCDp4mmYAAOAAAAAAAAAPMKACAAEEgwIxYRKRYQY/59wDDz +/5JgABBIMMCAKBYUY/6TKRIkIpUTIhIU0Q8AAGwQGiggBPogByIAADiw+TwABgCrjiD0xRoEAKei +IPMWKyjgASgw8woDKiABUDD6Fioi5AI6IIoni6j8oRUvwBAQMPiiCyBAAmqw9qkUIgBAE3DyzAgP +wAQ9IPzMQCYDO14QD2YI9qUUKgAgW/D/AgAKAzfXEMmXyUX4nAACAABK8G1JBQAIhgBJYSrSAA+q +CP8CAAYDWGaQmtDZsPkWKyABEGAwLRIri34fkOwt0QgtdQgq8h0JuxGrqiqgBS4KPvtwFiYC+naQ +LgpC/wo9JgL09pDyCkkuAyj6kCpwBfUKASYDNRaQLQr/fbELKnBBWEMYZKdMKnAFInAHxZHyAkEG +AEvOkMW0/wIABgBG3pAtEisckAyN233DVSgSK4qACgpHqoj4jD8v8BBQMAqIAS6AA2nhOot/ZLVS +GpDIKqLeLqEELaEFL6ECjKD+7P8twAQ/YPzuEQH+Anvw/6UCLAAgczANzAxgBBDAINEPAAAA+xIr +IgAAUfD9HAgiAABgcFv90GSlESwSK/0SACAAEFgwm8idySpwBRaPVfIWKC/ABDyg9v8IAFQQcDD/ +FikmAKb2kJUUkxofj/sucQj8EisgABBQMJoYmh4qFhIqFhT6Fhov/xBIMCkWG/kWISAAEFgw+xYG +IAAQaDD9FgcgGhBYMCsWHIbLjckZkJmZHy0WGf+QmR4JAHuwLxYVjMj+Fg0gAhBQMJoZDv4TLBYY +9oYUCIAEOaAmFh4cj3eeHCgWH/oSKSAbEEAw+BYQIB4QcDAuFhYqojosFiD2kIYQDxBYMPYWEyoC +IV6QKxIpHZAfK7I5DSwKLMKv/LIBDgIV5tCOcPRxByAgAkhw9goYIAUQUDD/j44SAABAsPQESgWA +BD+g9Y8iEgkAHXD/jyIeCQB7sPLsAAXABDkg9Y+FFAkAKTBtqi+UgJOBn4KWg5KEipSLlYySjZD+ +kgMgMAJKcJqG+4YHKgkAK3CciJ6J+oYFIGACQjAqEikpCg/5pjkgVBBAMPh0BSBUEFAwKxIpHo/3 +LRIoK7I6LBIpDt0K/dKvJgHDRuAswjkejwD4kEYQWBBYMP3CAQ4BuG8QLXEHDQ1K/xIrLcAEP2D8 +cSIsCQB3cJ0giXAekD37JgMgBxAgMPuO9BmABD5g+yYCKAkAJnCZISbyByYWJP/yBiAAEEgwKRYm +/xYlL4kQMDD2dGUgLhB4MP90VyAIEFgw+3RkIAUQaDAtdFwudSopdTUpdGcpdGYpcEH9cGggQhBw +MC50dAmbCfy7EQACAmtw/XRoKAAgWjD4gn8gUBB4MH+hEC4KTn6hCi8KVv8CAA4CL3qQ+5AYHMAB +RDD4g0IOBwFAMPzfFAAAEDAw9iUKIEgQKDD1JQsrQAQ7IPCYEQAQEGAw+Y/1H0AEP+D17hEDgAQ8 +4POQCRwJAB9w8yYHLgkAe7D+3QIKCQBasPt8SCgJAGow+iYGKAkASjD4JgQgQAJQsFmNi/hxKiAA +EHAw/iQvIAAQaDD9JDYgABBgMPwkMiAAEFgw+yQuIAAQeDAvJDP4JC0gABBQMPokNSAAEEgw+SQ3 +IAAQUDD6JDQgABBIMCkkMfiIFAAAEEgwKSQwKCQsL3BXLyQ7D48ULyQ6D48U/yQ5ILgCWfD/jxQA +BBBgMP8kOCB4AlCwWY1qKHxg8wgWAIACSLAASYoACIgACYotchwtJFMNjRQtJFL9jRQAqAJQsP0k +USAMEGAw/Y0UAP4CWHD9JFAgIgJa8FmNWSZwdCYkZC8SKhaOcQz/Eab/JPY5K3AWLgr/frEK+nBB +IEgQYDBYQdfEhfh0BSAAEBAw0Q8AACyhBS2hBLHM/AxPAf4CI3D8pQUmAI1vEI+gDEQR9PwID8AE +OyAOzAwADIvA0A3dYPAMgA+YALtgLqEFGo+zJXUTLKLi+qLhL5AEO6D1dRQsACB3cP11EiugBD9g +/cwICgAgWrD8dhYi7gA2oBuOSwwvEav/LxYpL/I68hYoJgFIw+AuEikUj0Eu4jkELwov8q//5AEO +AT5/kBaPJQpeFB+PLhqOTJ9A/3IALaAEPyCdR5pE/kYDIEAQWDD7RgUgAhBwMJ5C+hIrIAYQWDD4 +/BEGCQAz8PZGBiwJAFswnEGKq5pI+nIPIAAQeDD/RgsgABAwMJZKjoOeTYyCnEyGg5pJLG0Q+oIC +KgADMxCxqh6Oy/pGDi4AQHMwnk8oEimdECuGOSl0BfP7B2IAAFEwwPAvpQXz/uFgABBgMIqDCgpL +mn9j+qIAi3JlussrEir6fAAAARBgMPu8GCAHEGgwWEYfwCDRDwArEivacPwKhCIAAGlw/LUIIgAA +YTBZL6PAINEPwNCdq/P5wGIAAEow+8wMADYANmAMRhT+bAgiAABCcP5ONgIAAFLw0w9t6QUCCIYA +SmMMmAj2SgwAgAJIsG2pBQQIhgBJZQz+DK4uLuxAntBj+XIAKxIr2nD/CoUiAABhMP+1CCIAAGlw +WS+HwCDRDygsQJjQY/lNiXcqcAcrmRT0uhFoIAFQMImZZJoHHI3iDIsRrLsssjr/AgAEAKBDIB+O +2i6yOQ+PCi/yr//sAQ4Aln+QH47AI3EHHo3t8pAHKgIBUDD6qhADQAEcMPKWASPABDzg8IIRAgkA +VPD4jdwSCQB08PPGACIJABNw83IAIgkAeLD/xgYgBBBQMPjGAiAwEHAw8sYEIEACQzD+xgMgABBw +MP7GBSOABDzg/sYHIgkAVPDzxgEgAhAQMG0qBQYJhgBIZ4x3wND5+sAgQAJjMPq2OSgAQE8w/cUE +IIACSnCZwfnGACBSEEAw+HQFIAAQEDDRD8XSLXQFY/udjnJl6SErcEH6fAAAARBgMPu8EiAAEGgw +WEW1wCDRD8BAwMD8Ficn4AFoMBqO+/tsAAAAEGAw+qLeIAEQaDBYOP0YjvYqEicogt/2bAEgAgJS +sAhmLv8CAAH+7oagKhYnY//HAAAA8/jXYAAQUDCJcsia8nQFIAAQEDDRDwAA+nwAAAEQYDD7jBgi +AABp8FhFl/J0BSAAEBAw0Q8AAABsEAYmIhgmYAUFCEf3IhAgcxBIMP0KjiBgBEmw9TwAAgHEAiCI +NymJFPOCCSODADZg+iwAAgAAWXD8PAAAAhBwMFhDqcAg0Q/1CgAiAdoaIBiNvimC6SySGCvBAi3B +BfSzwGH+AnrwLsEEi8D5FgAh/gJzsP/FAi/ABDug/rsIDcAEP2ANuwxgAC4AAAAowQUpwQT7wgAg +AgJCMPgITwH+AnJw+MUFL8AEO6D+uwgGAXdGUAyNEQ27DAALiwWFYPALgA+UALogLcEFHI2lGo2e +LMKsCd0R+qLjLAAgbjCtzPnMEQAAEFgw/ApQKgAgYrD6FgIgQAJSsFmMNIgSLiAHLYAHixD/Cvsu +AgFwMP7uEQwAQH9w/yAMLAkAd3D9hAcvmBBIMP4gByD8EDAw/4QMLABAN3D1hEQgARAwMPaERS4g +AXAw+YQFLAkAd3AthAcsshkdjX3yhgogAgJjMCy2GSWGGiWEbCuyGJWJlYgssQIrsQMt0hYMuwz7 +2wpyAAAqMB+NcSv2FvRSjG/AEHAwileMqPuhFS/ABD0g+aILIEACarD2qRQuAEBzcP4WASoAIHbw ++7xAJgFAZlCvZvalFCoAIGPw/wIACgFDVtDJNslEDMkCbUkFAAOGAElhitAPAgAPAgCvqv8CAAYB +V16QmtDTwIpQ+41UHYAEPqD8MQgsCQBtMJ0xKXB4LFUIK7LMC6oM+mgUACAQWDD5uwwOARQSILac +AMEEAIwa8LEEAAEQQDDwiBoKoAFUMAioLPy7AgmgBDogC4gCBVoC+FYOIAgQWDBY9EAkXEgkVhIk +VhMvMCH0PCAuwAF8MP9UUCAApAfg/wIAAgCgA+AmUhIoXEjTD/8CAAYApEWQKSIQDwIAKZAFKgqV +/wIABgEEVlCKImWhMvosAAAwEFgwWAS4+KwAASQANqD2BBYCAABKsABJZwQEhgBJZQIEhgBJYywi +FhuM1iyEHwyMFCyEHgyMFCyEHQyMFCyEHPxSDiAAEGgw/YQEIAAQcDD+hAUgABBQMCqEA/qEByAA +EEgwKYQGLIQTKYQCDIwULIQSDIwULIQRDIwULIQQ8AsXAFACSjAACYovchEtUhIPiRQphBoJiRQv +hBsphBkJiRQphBiO1p9fLoQXDo4ULoQWDo4ULoQVDo4ULoQUjdcthCMNjRQthCINjRT9hCEiAABQ +sP2NFAIAAFlw/YQgIDAQYDBYBEQq+pn6VAUgABAQMNEPJcUF8/0PYAAQQDDz/IVgABAoMPP8fWAA +EBgwjTf8MgYiAABZcPosAA//EHAwWD9xZK6r8/xdYBYQaDCLWGW8Zo4vH43r/1YLIEACYXD85gAg +cAJosJ1Ynln8Jg8gABAQMNEPiDcpiRT1PAAAvwA2YIOJ8/5pYEACIPAA8/wVYI4QaDAAAADApfyM +1BAsEFgwWZOu8/1UYAAQKDDAsJur8/20YgAAGnAAAAAA8/3+b/8QQDD8ugwANwA04ApLFP68CCIA +AEDw/k42AgAASzDTD23pBQgIhgBJaYkRqjj7TgwAgAJKcG3pBQoIhgBJa4sRCv4MrrsrvECb0GP9 +V48RL/xAn9Bj/U2IWGSLmolZwCCSW5iQiliZoZJY8lYJIAAQEDDRDwAAAAAAAADz/0NgABAYMGwQ +BCogBPunB2AYEEAwa6QGeKEbwCDRD/osAAIAAFjw/EwAAgAAaXBY8IzAINEPAPosAAIAAFjw/EwA +AgAAaXBb/rvAINEPAGwQBiYiGCgiECZgBQUJR/0KjiBzEDgw92ExcgAAUjD1PAACAV6CYCgyBymJ +FPOCCSK3ADZg+iwAAgAAWXD8PAAAAhBwMFhCYsAg0Q+YERiMePUKACIB1BpgKYLpLJIYK8ECLcEF +JsEE/sIAI7cANuCwv/kWACH+Almw/N0RC8AEPuD/xQIqACBfsA27DGAAMQAAAAAowQUpwQTTD/vC +ACACAkIw+AhPAf4CcnD4xQUvwAQ7oP67CAYBDUZQDI0RDbsMAAuLBYVg8AuAD5AAuiAtwQUcjF0a +jFYswqwJ3RH6ouMsACBuMK3M+cwRAAAQWDD8ClAqACBisPoWAiBAAlKwWYrsiBIuIActgAf7EgAv +mBA4MP8K+y4CAXAw/u4RDABAf3D/IAwsCQB3cP2EByD8EDAw/iAHLABAN3D3hAUgARAwMCaERfWE +RC4gAXAw/4QMLAkAd3AthAcsshkdjDTyhgogAgJjMCy2GSWGGiWEbCuyGJWIlYkssQIrsQMt0hYM +uwx72wUfjCor9hbbgPW8AAKFADbgireMqPuhFS/AEHgw+aILIEACarD2qRQuAEB/cP+7CA/ABDkg ++7xAJgE85lAOZgj2pRQqACBjsP8CAAoBP1bQyTbJRAzJAm1JBQADhgBJYYrQDwIADwIArqr/AgAG +AVJekJrQ08CKUBuMDPkSAS2ABD6g/DEILAkAbTCdMSmQeCxVCCuyzAuqDPpoFAAgEFgw+bsMDgEO +kiC2nADBBACMGvCxBAABEEAw8IgaCqABVDAIqCz8uwIJoAQ6IAuIAgVaAvhWDiAJEFgwWPL3JFxI +JFYSJFYTLzAx9DwwLsABfDD/VFAk7gI/4MCwKjA4LjA5+TA6IBAQQDD2MDsrgAQ6oPCxBA4JAFOw +8O4aCYAEPmDwgQQGCQBJsABmGgbuAvtcAAIAAFCw/fr/L/8QYDBYPmzKpvP9Z2AWEGgwJcUF8/3j +YAAQQDAAAADz/VFgABAoMPP9SWAAEBgwAAAqIhAroAUsCpXTD/8CAAYAz+bQjSIPAgBl0Mf6LAAA +MBBYMFgDWPisAAC5ADag2aAGBIYASWcEBIYASWUCBIYASWMtIhYei3ctpB8NjRQtpB4NjRQtpB0N +jRQtpBz/Ug4gABAwMPakBCAAEFgwK6QC+6QGIAAQYDAspAMspAf/pBMgABBIMCmkBQ+PFC+kEg+P +FC+kEQ+PFC+kEPAOFwBQAkqwAAmKLhIBLuIRLqQbDo8UL6QaD48UL6QZ/48UAgAAWXD/hBggMBBg +MP5WDyIAAFCwWALwL/qZ/1QFIAAQEDDRD4ZYZWxtii8bjKf7VgsgQAJBcPimACBwAkiwmViaWfgm +DyAAEBAw0Q+INyyJFPU8AAC6ADcgiInz/uVgYAIiMAAAAADz/BlgjhBoMAAAAMCl/IuOECwQWDBZ +kmjz/VtgABBYMMDQnavz/bxiAAAacAAAAADz/glv/xBAMPy6DAA2ADTgCksU9rwIIgAAQPD2RjYC +AABLMNMPbWkFCAiGAElpCjgI+0YMAIACS/BtaQUKCIYASWsK6Ayo+CiMQJjQY/1iACn8QJnQY/1Z +iFhki6KLWcCgmluYsIxYm8GaWPpWCSAAEBAw0Q8AAADz/0hgABBAMGwQBvwKAiBCEDAw9QoDIAEQ +WDD4jFoQABA4MPcWACAuEEgw+CUqJABogSAqMBX5JFcgiAA1IP8CAAAAbwUg/wIAAgBhASBuRTgK +axR7UAUsMBQsJGAqLGX9jFcSAABYcP0WACADEGAwWYnVJyRoJyRpJyU1JyYcJiR0HoszLiU30Q9u +Q8P/jEASAABhcPskZCAjEEAw+CRcIMoCULD/FgAiAABYcFmJxickaCckaSclNScmHCYkdNEPACkw +MMGi/wIABgBE1lD7JGQgugJQsPwKAyAiEFgw+yRcIDoCWPBZibgqLGH8CgMgMgJY8FmJtCowFWP/ +UgAAHYwwLSUqLDQwY/8mwPb/JFwgCBBwMC4kZGP/NAAAAAD6LF0gOgJY8PwkXCAgEEAw+CRkIgAA +YXBZiaMpMBjTD3+XtCosYfwKAyAyAljwWYmeY/+jGosxLDEcKqJ/CcwRrKosoTYsNRyKoComHmP/ +XmwQBigiGCciECiABQUJR/sKcyAAEDAw+nwADgGu2hD/AgACAbUaYCowMBiK9cSS/wIACAG20lAp +gukqkhgsoQItoQUroQT+ogAjiQA3ILDP+RYAIf4CYvD83RENwAQ7IP+lAiwAIGOwDcwMYAAtAAAo +oQUpoQT8ogAgAgJCMPgITwH+AnJw+KUFL8AEO6D+zAgGAUFGUAyNEQ3MDAAMiwaGYPAMgA+UALog +GYrbKqEFFYrUKZKsCaoR9VLjKAAgUjComAmIEfhVCAAAEFgw+lwgIFAQYDBZiWstIAcsUAf6EgAv +mBBAMP4K+ywCAWww/swBDeAEP2D+IAwsCQBrMPxUByD8EHgw/SAHLABAezD4VAUgARB4MC9URfZU +RCwgAWww/lQMLAkAazAsVAcrohnyVgogAgJa8CumGSZWGhuKsCZUbCqiGJZYllksoQIqoQMrshYM +qgx6uwUeiqkq5hb0UfBvwBBwMIpXjKj9oRUvwAQ9IPmiCyBAAlqw+KkULgBAcvD+FgEsACB3cP3c +QCYBLGZQr4j4pRQqACBj8P8WAioBL1dQyTbJRAzJAm1JBQADhgBJYY4SirAPAgAOqgj/AgAGAURu +kJqw08CKUA8CAPuKix2ABD6g/DEILAkAbTAtNgEpcHgsVQgrsswLqgz6aBQAIBBYMPm7DA4A/hIg +tpwAwQQAjBrwsQQAARBAMPCIGgqgAVQwCKgs/LsCCaAEOiALiALaUPhWDiAHEFgwWPF3KiIQLKAF +LQqVDwIA/wIABgC67xCOImXhICiiEy+iFAj/DP8CAAAAfY/g+iwAADAQWDBYAfj4rAABAQA2oCk8 +MAYJhgBKZwQJhgBKZQIJhgBKYykwMGSQtgaPFCaEBw+LFCuEBQuLFC+EBiuEBCoiFiqEHwqKFCqE +HgqKFCqEHQqKFCqEHIleKYQTCYkUKYQSCYkUKYQRCYkUKYQQLXIRLYQbL4QCJoQDDY4ULoQaDo4U +LoQZ/o4UADAQYDD+hBgiAABZcP1WDyIAAFCwWAGWLDAwycct+pn9VAUgABAQMNEPJqUF8/17YAAQ +QDAAL3IRInIUsf//dhEgAgIQsPJ2FC+ZEHAw/lQFIAAQEDDRD8Ch+oQAL4EQSDAphAFj/zjAUNog ++1wAAgAAYPD+CgIgjhBoMFhADsAg0Q+LWGSw48Ag0Q8AAGiS1og3LIkU9TwAAPwANyCDiWP/xog3 +LYkU9TwAAPIAN2CDiWP+lgD6LAACAABY8PxMAAIAAGlwW/2HwCDRDwCIWGSPtI5ZlluY4I9YnvGW +WPZWCSAAEBAw0Q/ApfyKFhAsEFgwWZDw8/18YAAQKDCWq/P93mIAABpwAAAAAAAA8/4qb/8QQDD8 +2gwANwA04ApNFP7cCCIAAEDw/k42AgAASzDTD23pBQgIhgBJaYkRqjj9TwwAgAJKcG35BQoIhgBJ +a44SjREK7gyu3S3cQJ2wY/19jxEv/ECfsGP9c4ovG4r/+1YLIEACQXD4pgAgcAJIsJlYmln4Jg8g +ABAQMNEPAAAAAAAAAPP+0GAAEBgw8/2qYgAAGbBsEAYoIATTD/SAHGBzEGAw+4cMYBgQSDD/AgAE +Aa4KIHmBBMAg0Q8AKyIYJyIQK7AF9goAKOABLDD6fAAOAcvi0PwKQiIB0hpgLTAwGInJ/wIACAHW +6xApgukqkhgsoQItoQUroQT+ogAjyQA3ILDP+RYAIf4CYvD83RENwAQ7IP+lAiwAIGOwDcwMYAAt +AAAooQUpoQT8ogAgAgJCMPgITwH+AnJw+KUFL8AEO6D+zAgGAUFGUAyNEQ3MDAAMiwaGYPAMgA+U +ALogGYmvKqEFFYmoKZKsCaoR9VLjKAAgUjComAmIEfhVCAAAEFgw+lwgIFAQYDBZiD8tIAcsUAf6 +EgAvmBBAMP4K+ywCAWww/swBDeAEP2D+IAwsCQBrMPxUByD8EHgw/SAHLABAezD4VAUgARB4MC9U +RfZURCwgAWww/lQMLAkAazAsVAcrohnyVgogAgJa8CumGSZWGhuJhCZUbCqiGJZYllksoQIqoQMr +shYMqgx6uwUeiX0q5hb0Ug9vwBBwMIpXi6j9oRUvwAQ9IPmiCyBAAmKw+KkULgBAczD+FgEsACB3 +cP3cQCYBUF5Qr4j4pRQqACBb8P8WAioBT1dQyTbJRAu5Am1JBQADhgBJYY4SisAPAgAOqgj/AgAG +AWRukCrGAAuzAipSAPuJXx2ABD6g/DEILAkAbTAtNgEpcHgsVQgrsswLqgz6aBQAIBBYMPm7DA4B +FhIgLJwGAMEEAIwa8LEEAAEQQDDwiBoKoAFUMAioLPy7AgmgBDogC4gC2lD4Vg4gBxBYMFjwSyoi +ECygBS0KldMP/wIABgDa7xCOImXhPyiiEy+iFAj/DP8CAAAAjQ/g+iwAADAQWDBYAMz4rAABIAA2 +oCk8MAYJhgBKZwQJhgBKZQIJhgBKYykwMGSQtgaPFCaEBw+LFCuEBQuLFC+EBiuEBCoiFiqEHwqK +FCqEHgqKFCqEHQqKFCqEHIleKYQTCYkUKYQSCYkUKYQRCYkUKYQQLXIRJoQDL4QCLYQbDY4ULoQa +Do4ULoQZ/o4UADAQYDD+hBgiAABZcP1WDyIAAFCwWABqLDAwycct+pn9VAUgABAQMNEPJqUF8/17 +YAAQQDAAL3IRInIUsf//dhEgAgIQsPJ2FC+ZEHAw/lQFIAAQEDDRD8Ch+oQAL4EQSDAphAFj/zgA +AAAAAAD6LAACAABY8PxMAAIAAGlwWO8GwCDRDwAAwFDaIPtcAAIAAGDw/goCII4QaDBYPtrAINEP +i1hlvHGOLx+KBP9WCyBAAmFw/OYAIHACaLCdWJ5Z/CYPIAAQEDDRD2iSuYg3KYkU9TwAANgANmCD +iWP/qYg3K4kU9TwAAM4ANuCDiWP+WwAAAAAA+iwAAgAAWPD8TAACAABpcFv8S8Ag0Q8AiFhkjAWM +WZZbmMCNWJzRllj2VgkgABAQMNEPwKX8iNoQLBBYMFmPtPP9PGAAECgw8/37b/8QQDCWq/P9mGIA +ABpwAAAAAAAA+9oMADcANOAKTRT+3AgiAABA8P5ONgIAAErw0w9t6QUICIYASWmJEao4/U8MAIAC +SnBt+QUKCIYASWuOEo0RCu4Mrt0t3ECdwGP9Po8RL/xAn8Bj/TQAAPP+12AAEBgw8/2TYgAAGbBs +EAQqIAfAUP6IWRogAVAwHIhq+UwvK8AEOqD5SRQKACBysCmmOSsgFiogB/86ICD/EEAw9ohVENAE +QvAKCkEPrxys/CjCrvCxBAABEGgwAN0a8omCGAAzahD4uRAJwAQ6oPlJAggAIHIwmYMowq/+wrAu +ABbHUA7eAi7GsAjqMAu5CfyZEQ4AIDPwqe6i7inibyjmbgSZDPnmbyAAIi5gyTaJOP8yCSASADZg +lTuZ8Ig4n4GVOJU50Q/RDwu8CfzMEQoAIDPwrKoqrQopockEmQwFmTX5pckvyQC04GP/2S7CsQ7d +Ai3GsVvtmGP/sABsEAaIIisgB/SACGogAVwwwCDRDxeIGgy6Ef2IGRoAIDqw/KI6IF4CcPAOThQN +vQr90pcqAM53ECyiOR+IMP3KAQ4Ax28Q8A8HAgAASrBt6QIASWElIhIUiW6MKfgiCiQIASwwBFQK +JEJ/wNH8iAwEACAZMP8gIyoANSIQKCAiCP8MZPGqkxIpIAcTiA0JCUEDmQkokd72IgsiAwB+MAOI +DCiV3i8gIpMQGYgFD/OHgxL/JCIhlwA34CiSe/CBBAH+AkvwAJkaANga+Iz/JgAgSbAIZgKWKgxp +DP8CAAoAvCZQLyAWJiAH+If4EP8QYDDw8QQAvgRj8Pw6ICYgATAwDGwc/BYBLAAgQzAowq4A3Rr/ +AgAIAGnqEAxvEaf/j/Aowq//3wEAARBIMP+fOQgAB0NQ8AAZYgAAY/AAACnCscCB+dkBAAAQYDAJ +jDgM/AFkwMT7IgAgIAJ48PwKACAAEGgwWY/xH4krLCISHYfxG4f/+SEaLEoBYDD6WBENYAQ7IPXb +OAgJAGIw/iIAKAkAWjD4mRAMJgFEMP+HyBwAIH9wmaIt0ID4pgMuCQB7sJ6gDU0MnaGMKSsiFaTM +/CYJKgAgJvD7JhUgIAISsNEPAPu8GCIAAFCw/AoBIgAAa7BYP7fAINEPAByHrIkRD/gJDwIA/JkI +CcAEOiAJiAgojQopgcotgckogc0PAgAJ3QH8CgEr/55DUPu8EiIAAFCw/AoBIAAQaDBYP6XAINEP +ACkgBf8CAAH+7IZgiiLAsguqAvomAiAAEBAw0Q+cKvP+hWIAADMwiBArIAceh5kI/Az8JCIqIAFc +MA6+CSzh3qjMLOXeLyAizPWNKZ0qYAAiGoeRKqJ/jivwoQQB/gJL8ACZGgDYGviM/y4AIEuwCO4C +nir7vB8iAABQsPwKASAAEGgwWD+DwCDRDwAAbBAEKCICKyIUKiIT+6oMAAgANiDAINEPBQNHaDIC +ZKCCLCAHHYdnDAxBDMsRrbstsjpu0n4fh2MusjkPzwov8pf/7QEOADf/kC4hBxmHaf+Icx9AAXAw ++IfoH8AEO6D8h2YeCQBLsC7WAP4iACgJAEKw+NYFIAgQSDAp1gP81gIgAhBIMPjsEQ4JAHuw/tYE +LAkASzAs1gEptjkoIhQKiAgoJhT/AgACAIIY4MAg0Q8AAAAA+8wYIgAAULD9CgIgARBgMFg/T/8C +AAP/pJjgiScnmRT0cPRgQAJ6cIqZjPDz+sAgKhBwMPSgQGIAQB/wesE4KKAA0w8PAgB+gS0k8QUr +oAfzSQgLwAQ+4PuqCACAAkpw/wIAAgAAWrD/AgAKAEBKkPq8AA/IALbg+s0MAAAQKDANWjj2iIkQ +mQA2oIigCIhXfokJiaL/AgAH/2O2UCTxBSugB/NNCAvABD7g+6sIAIACa3D6vAAKAGbq0MqhesEf +KKAAKaAH0w9+gRQMmRGpqv2rHnIAAFqw+rwAD+EAtuAKywwLWjhlr6FgADMEqwxj/30Eqwxj/9+K +J/sKASAAEGAw+qwgIAEQaDBYMtnSoNEPAAAAAAAAAPP/DmAAEFAwivErfBAr9QT7PEAh4AJSsPr2 +ASoAF9qQLPEF/ocnGgAgUzCa8Z6gjSD43REAARBwMPamAiwJAHdw/aYBIAAQEDDRDx6HHZ6gjSD4 +3REAARBwMPamAiwJAHdw/aYBIAAQEDDRDwS6DGP/MAAAbBASIhYXJiBEGohHiyopIhcoITIkFhUd +hvofiEH/FhEgBBBgMJwY/RYEIBACcPAuFhT4FgsgIAIg8JQRmRoUiDmJJxiIOvuwaSAgAnNwnhco +gjmJnvkWBSFgAmqwDb0KnRP4giYgiAJisPy7CwngBD7g+xYAKAAgVnD5FgIoAEBBcCgWFmAAQC8S +F4/6L/AHDw9BiB6LG4ka+LsMAAAQMDD4hrcboAQ7IP0SDCgAIFZw+RYKL8AEP+D7FgsuACBH8P32 +OSQRADbgKhIXiqqLGC+gB4kbGIaqDw9B+5k2D8AEO+D5Fg4uACBDsPjiOimgBD5g+RYJIF4CSnAJ +SRT5FgwqAmJOEByGnyviOQz8CizClwy9Af0WDS4CVubQjRQoEg0ADYttmQIASGEuEheIHoISKeEz +LTAD8iJ/KeAEOiD5h/wYAwBKMI7sKBYTCYgL+BYGIAAQSDD5hn8gABB4MP+GfiAAbG+QjBAuwn8s +wn6FMsef+DIDKBEATzD5+v8kAEBNcAnpA/kKASgAQEow+Jg5BAUALnAIVQJkU54vEhcnEhQlEhEY +h+EAB4gABYongsUv8hgpgsSFMf8vDAYAQHXw94bFKABAZnD5hsQuAwAv8A9VDPU2ASAXADVghTOl +9f4yAioAA/lQLuwBlTOeMikSF4icxq/6iAECAABhsPiWDCBBALWgjxOHMS/yfywSE6J+8PAEAf4C +c7D+DhkB/gJjMP8WECwDAHMw/goAI40ANyDwAEtgARBQMAD8bAADSgA1oCkSEYgVbckFAAiIAAmK +ihMoEhOHMSqifwyIDPoWECgAIBXw8KAEAf4CSnAJCRn5jDYCAABTMP4KACBMADcgLgoAbclBGYZF +qugJiAspEhTzCRYIACAiMABIiocxhjOx7v8yAiQDADyw9XcMBgAgMXD3NgEgEAA14PY2AyoAAymQ +sf+fMtMPKBITqur/AgAOAIjSEGRxCYsWjDMstn+JMim2fo0XiRgYhizwDRcKIAFUMAuZDAioCyiN +H/kJQQCwAkIwbZkCAAiKiReNHIgZLhIXjB0fhwqO6p/AjxqO4AhYFJjC/18UD4AEO6D/xgMsCQB3 +cJ3B8AkXACACYzAADIoYhh2JHY8eKhIJ+pYHIAAQcDD4lgYiIgA34AmYAvUKBCBwAmJwbflyKhIX +HYYLLxIVi6oN7gsdhuaLsCkSFvmGCS4AICOw/4YKKgkAbvD7hggiAAB7MPqiGCCAAmMw+oYLIAAQ +SDD5hg0gABBoMP2GDCCAAkIwDA6IAY+KCg6IAU+KCA6IAQ+KBg6IAM+KBA6I8p8eAgAAcXC0VYwe +Y/yj/xIBIf4CY3CcH/8WGSAAEHAw/hYYICUAtyBj/uQoEhgtEhL4jAEgMAJi8PgWGCoFAG8w+xYZ +J/9lzhArEhMmEhgpEhksEhD+EhEmAAEwMAloCo2ADq4LAMAE+rsMDAAgaLD2FhIh/gJjMAwMGflm +CwoDAGbw+xYaIBACSbBtuTXVkP8FFgIAAHuwAc+KjYANJTb13QwAEAJzsP2GACAWADdgh2OPYqdX +92YDKgADKdCx/59i0w8rEhr4EhMgABBIMAu5OfsSGSoAIEqw+RIPL/+m0hBk30UtEhksEhINzAuN +Fo7DLtZ/jMIs1n5j/hIAAACPGikSFxiFsIobK5EzCOgL+pUyIAEQaDD6EggqIAFcMPy8AAGAAnvw +/5YXLAUAW3D4jR8qBQBi8CqURPkSBSBgAkIwbakFAAiIAAmKLBIXi8zA0g27AvvGDCAAEBAw0Q8A +AAAAAAD8bAANBAC1oI8ThzEPAgAv8n/8EhMuACA4sA8CAPDwBAH+AnOwDg4Z/xYQLAMAczD+CgAg +RAC3IPP9UmAAEFAw8/sIYAAQYDAAAAAAAACPE4cxL/J//BITLgAgOLDw8AQB/gJzsA4OGf8WECwD +AHMw/goAL8QANyDz/MpgABBQMPP9CmABEFAwAAAr/Bj9EgwgARBgMFg9fCgSF4IbiRophhcihTL2 +hEQgDBAQMNEPAGwQBogsG4XA+YbNEgAAMLD3so4gEAB+MMEh0Q+IKiiAafycsC/gBD4g/IgKDgAg +T/Av8n8ogn+lSan/8IAEAf4Ce/APDxn1Jhgv4AF8MP8lMyAGAmPw/CwSD5AQSDD8JTIgJARJ8Cn6 +pHkhB/XwDWH+AlvwwSbRDwAAAAAAHoa19IayGgBAW/D9hnweAAvf0Pys/yIAAHqw/KoBCf/6Y9AP +/xHyhqsQBBAoMPuGqBABEGAw+QoAIAYCU/D6KhQCAABCcP2tAQQAQCKw9MQ5DAUAbzD7qwECAEAS +sP4KCCoAQHKw8sI5CgUAXzD8nAAKBQBTMPUKECgFAFFw/Vw5AgAAUnDyCgIqBQATsPspOQoJAGKw ++ogCBAkASTD4cjgkCQBBMCpyOfRMDwv/pUEQCsoKiqAroQIOzBH8FgAgBgC24NEPWD5LiBAvcjke +hoOo/432Dk4Ki/D58gEtoAQ/YP2tKAIAAGKw+rEDKYAEOyD7sQIoCQBBMPhmFigAIG5wKWYXifYo +4q+P9AyZKAuqDPqLB34AIE/wKuavZDBNG4VaimArsnELqgwKaRRvniGLaiuwaLa7ALEE8JkaDKAB +UDD6+xEICQBPMPAABmgJAF5wx5+ZMIxs9cwCAAEQaDANzAL8ZgwgABAQMNEPjGz1zAIAARBoMA3M +AvxmDCAAEBAw0Q8AAGwQBhmE/fKSfiIAAHCw/UwAAgAAYPD/CgAqAI6Q0CWSfZUQK1EE9VIAIf4C +IzDzIwwAARBAMPy7EQIAABMw8AAOagAgLvCx//8CAAYAdZ/QD1YUDmYRBrYMJm3/9mI/KoABeDAA +oQQAiRrwoAQGAEBJsPYGGQACAhCw+QoAL8gAtaD4wTxgAgIz8G1JLgZXFA53EQe3DCd9//dyPySA +ATQwAFEEAIoa8FAEBgBAVfAHBxn1cAZgAgIxsLGZCcoMaaGDZMBLJxIADwIAKnEEKfr//KoRAgAA +G/BtyTTycgAkgAEcMPNUFAACAhjw8FEEBeAEPSDwghoEACBQsPVFDAQRAEiwJVz8hlAEZAEEIgKS +UBKEuSUigSzlEyIigP/lEiQAIC/w9dYAI6AEP+D15hYiACAYsNEPFYSwJVKBLOUT/+USJAAgL/CV +0PXmFiAAEBAw0Q9sEA4bhemSH/chFSIAAEEw8jADIgAAILD4FgEgBBBgMPcWAi/wEFAw9zIGIgAg +EPD9QRMgfgIQsPRAByIAQFCw+iIDLiABODD+zAwCAABI8PQEQQwgAWAw/BYDK2ABUDD6Fg4j2QC3 +YIgh94wAA5oANqCqiPiN8CABEDAwaoET+AtLAAEQaDD4zBIKBQBfcKy7q2YoIAOwiPqBWGIAABmw +2yBtCEqNtCiM//0KSwABEHAw/cwSCgUAU7D31wgKACBisPSAImYAIFGwKrIFCg9L+swSDgUAf7D4 +jP8uACBn8PenCAYAIHmw+7wYIAAEJiBj/64Ajh8j5RAm5REtkBNk0w2XUfoSDyAGAlmw+ysUAAAQ +YDCcUPsWCSIAAGBwW/9jjh+aFo0Z/eUUIqoANqD+hOsSAABI8PX6/yLlADTgGoWaKqKa/woAIgAA +QrBtOSKLI4Miq/v+vQEKAAN60LEzL/0Q/YYBLABAKPD8hgAgEAJCMPQWECoAYLJQwEGIJPgLSwAB +EGAw+MgSCgUAXzD7iAgAABB4MPSAPWwAgCYwCpgLbdoyiycPAgAPAgD5nAEqACBf8PMiBiwAQHbw +/YYBKgAD+tAjPAH//RAsAEAo8PyGACAQAkIw9pFZcAEQYDAoIgUIC0v4yBIKBQBfMPuICAAAEHgw +9IAzbACAJjAKmAtt2iiLKYMo+ZwBKgAgX/D+vQEKAAN60LEzL/0Q/YYBLABAKPD8hgAgEAJCMPIs +GCv/pjZQJBIQixKIFv4SCS/gBD7g/2YMCaAEPuD5iAgLsAQ+4PgWBioAIF6w+xYKIhkAN6Aeg/YM +TRH+EgksACB3cP0WBSAKEHgw/dI6LgMAe7CeGA7uCQ/uEf4WBCoA8fdQjxUZg+sv8jkJSQopkpcJ ++gH6FgcuAOdP0IwfihiJGSvBFRiEAgqZDPkWCSoAIFbwK8UVAAiLiBdt6QIASGGMGGTBQooWEoPn +GITIjRMZhLyOF/zPCQwAID9w/RYMIAAQWDD9EgAgABAoMPv/EQBAECAw/+4IAgAAO7D+Fg0toAQ/ +YP0WCyACEHAwCl0UjxyMH4MbmHCMwJJ0lHWeciN2By92CP12AyCAAlKw/xIKIAAQaDD9dgsiAAAZ +8P4SDiAAEGgw/XYKLYAEPyD+dgksCQBLMPx2BiIAAHLw/18IAAYQYDD1XCAsCQBncP12ASAFEGAw +bcoj9usMcAAQIDCE8Y3wYAACAMDQlD39NgwgAgJzsP/8CCAQAhjwjR20u/d8YCBAECAw/goCL/+w +adCNGMDgDt01jxmJFYgU+JY5IAgAN+DAINEPihCLEf3YCQugBDqgmrCLH4IX+4gRAAAQSDD5tRUg +URBQMPq0BSIAIECw0Q8AAADz/HBgABAwMJeWY/zsAAAA8/+rYAAQaDD5CgAgEAA1oBqE4CQWECqi +mmP9RhqE3SqimmP9+pdRK7Jlhh/+EgIgABB4MJ9QLGIWnBAsYRIjYRAO3gz+FgktoAQ7IPZhESoA +IGbwmxZj/L3AINEP0qDRD4gfihD7EgEgABBIMPmFFSBREBAw8oQFK6AEOqCasNEPAAAAbBAGKCIY +KIAF9QtHAI4QaDD5CnMgARA4MPmBR3AAEDAw+LIvYgAAKPCJNyuZFPOSCSAqADbg+iwAAgAAWXD8 +PAAAAhBwMFg5jcAg0Q8AAAAAAAAA8//eYAAQKDDz/9ZgABAYMPiyEWIAACjwiTcsmRRkw6+DmWAA +rB2DmNMPJdLpK1IYKbEC8xYAIroAtmDApfyDnhAsEFgwWYp48AKcYAAQKDAAAIqng6j7oRUvwBB4 +MPyiCyBAAmqwD98Br7v7vEAmAdefECipFAxOEa6I+KUUKgAgG7D/AgAKAdDW0IkQyZfckPk8AAAT +ADUgbUkFAAyGAElhKtIADqoI/wIABgHj3pCa0I1QCN0R/DEILAkAbTD9NgEiAABRcPxVCCAGEFgw +WOpyKiIQLqAFLwqV/wIABgGA/5CIImWC7yuiEymiFAuZDP8CAAAA+Y5gLFIM9DADIAEs/xAtUTLL +2iwwRC4wRf0wRi2ABDsg/swCAgAAUXD+MEctgAQ7IP3MAgoAICTw+7wwLYAEOyD9Ug4sCQBzMFv8 +I2WikisiFCoiEx2EctMPC6oMLq1A/IRwGgAD91B6yxL6LAAAABBYMPwKACACEGgwW/uG+iwAADAQ +WDBb+tT8rAACVQA2oNug/QoDIGACSPBt2gUCCYYAS2MnxAApIhYGiBQpxB8JiRQpxB4JiRQpxB0J +iRQpxByPXi4iEC/EEw+PFC/EEg+PFC/EEQ+PFC/EEC7iES7EGybEAyjEAg6PFC/EGg+PFC/EGf+P +FAIAAFCw/8QYIgAAWXD+Vg8gMBBgMFv6dywiEC3CFCvCEbHd/cYUIAICWvD7xhEvmRBQMPpUBSAA +EBAw0Q8tsQUbgxwcgxYrsqwJ3RH8wuMqACBqsKq6+aoRAAAQWDD8ClAqACBTMPoWASBAAlKwWYGs +ihErIAcPAgApoAf8CvsqAgFcMP67EQgAQGZw/CAMKAkAXnAppAf7IAcvmBBwMPykDCD8EGgw9qRE +KABAbnD3pEUqIAFcMP6kBSgJAF5wKaQHKFIZG4L18qYKIAICQjAoVhkmphompGwvUhiWqSamCCjx +Ai/xAyyyFgj/DH/LAi+2FvWsAA1uALag8/z2YI4QaDAAL7EEjLAqsQX+nP8h/gJL8P61AinABD5g ++ckIC8AEOqAKmQwECYsGpmTwCYQP/4ZCoCqxBS2xBPmyACACAlKw+gpPAf4Cc3D6tQUgGAhTcPa1 +BSAAEFAwDO4R/pkIDcAEOqAMmQxj/7ofg/AsMEQtMEUuIGkIzBH4MEYsCQBrMP/uCwwAICTw/dIP +IgAAUXD+4n8gcAJZcP8wRy2ABDsg+Pr/LAkAQzD4zBEOEQBDsP/MAgwAQHdwW/0DZK1V/IPcEAIQ +UDD9UTIgMBBYMFmJmvP8HWCNEGgwAAAAAAAAAPP8/mIAABmwiFjJjcAg0Q+JWGSf9opZlluZoItY +mrGWWPZWCSAAEBAw0Q+OLx+Dyf9WCyBAAmFw/OYAIHACaLCdWJ5Z/CYPIAAQEDDRD5ar8/yOYgAA +GzCIEPO7DAA4ADYgC0wU+MwIIgAASjD4SDYCAABQ8G2JBQYJhgBKZ4kQKvxA0w/8SAwIACBecG2J +BQgJhgBKaQvqDKr6KqxAmtBj/D4r/ECb0GP8NgBsECooIAQjFkj1FkcgGBAoMPoSRyWhADYg9goZ +JgLJjiD/AgAEAsWiIC8gB44wIxZG8hZJLiABfDD/FkIu4AFwMP4WQyDWAnOwDk4U/hZEJALeAiAo +EkkPAgAPAgAogAXEvvkKUSYCo14QeYErKwpUe4ElKhJJKxJG/BwEIBACaHBb/YT/AgAABYQqoCoS +RigSSYkRmacogAUsEkaDxvMHQQAEEDAwB2YM8oIXFiABMDD2MwgAVBBYMPPGBiYA494QLxJJHoNi +A4kUGoJIjMcsFhn6FiAgABAgMJQXlBaUGJQclB4kFhIkFhQkFhgkFhokFiskFiokFjAkFjIkFjb0 +FjggAxAwMJYa9hY0ID8QaDAtFiT9FiYgABA4MCcWLvkWHiABEEAwmBT+FhUqgAQ84CsWH/6B5xwA +EFgwKxYlKxYn+xYtL/8QQDAoFhsoFiH3go4T/xBIMCkWLPkWOSAeEGgwLRYWFoL8L/EI9xYNIBEQ +SDD5FiIgBhA4MCcWMS8WNxSDMSQWEyQSQvYWDyACEEAwmBn8TREAGhBYMPsWHCwAIHdwLRZF/dI6 +IBAQQDD4FiggDxAwMPYWMyAbEHAw/hYQKgSBd1ApEkUagr0pkjkKSgoqoq/6lAEOBHXWUBuB3ARI +AvALBwAbEEgwbZoCAEhhLBJJ88IAICACSHD2gigQCRBQMPzBByIAAHlw+D0RAAMQcDD+gbocCQB3 +cPwMSgIAAEEw9jMCDcAEOyD2gh0cCQBzMPTcAAIAACswbaovlYCUgZKCn4OThIqUi5WMko2Q/pID +IDACSnCahvuGByoJADNwnIieifqGBSBgAkIwJhJFLhJJwfv/ZjkgVBBoMC3kBSsSSdMPDwIAK7AW +Jwr/d7EWLBJHKhJJAMyOKqBBWDUk/wIAAAQgqqAkEkIegYjTD/aCgx3ABD0g/hJELAAgd3AtFkUt +0joGRgomYq//EkUqA+h3UC/yORiBnfb0AQ4D4TfQ8AgHAgAAQTBt6QIASGEqEkgsEkn7gskQABAw +MPYWQCAIEHgw/8RkIAYQcDD+xFwgLhBoMC3EVyvFKiqgFdMP0w/6ahQAAxBIMP8CAAgD6tJQKx0B +KhJJHILGLBZA+qxlIAMQYDBZgEYlEknAoCpUaCpUaSpVNSpWHPlRByBCEFAwKlR0GoFl+BJDKUAB +TDD7gZ0ZwAQ+YPtVNygJAFZwmUCHUCYSRCiMTPhGAyeABD3g8kYCJgkAObCWQSNQQR+CnShQBQM2 +CfxmEQBQEGgw9VEiLgAgN/D/8n8gJgRqMMS+e4EJxcb/AgAOA9riEP6CfRBAAlEw94KSF0AEOWD7 +EkkgABBgMPA9EQLAAXgw8xJDKEgBfDD8RQooBwF4MPXcFAlQBDog/4KHGYAEPmD/RgcgkAJa8Pdv +Ag1ABDsg+SICCAkAYjDzPDwiCQBAsPNFCywJABdw/0YGLAkAd3D9RgQgEBBgMFmABSsSSf6xKiAA +EGAw/EQvIAAQUDD6RDYgABBIMPlEMiAAEEAw+EQuIAAQaDAtRDP+RC0gABAwMPZENSAAEHgw/0Q3 +IAAQMDD2RDQgABB4MC9EMf6OFAAAEHgwL0QwLkQsLbBXLUQ7DY0ULUQ6DY0U/UQ5IHgCUTD9jRQA +BBBgMP1EOCC4AlrwWX/jKBJJ0w8ojGDzCBYAgAJxMABOigAIiAAOiiwSSSzCHCsSRixEUwyMFCxE +UgyMFCxEUQyMFPxEUCCoAlEw/BJDIGACWvBZf9ErEkkvEkP+sHQuACB9MC70WC0SRSwSRCzWOSuw +Fi0K/32xDSoSSfqgQSIAAGDwWDRNKhJJKBJGKQpFKaQFKIASDwIAZIBGFID8I6IHBIQo+kwAACAC +GPBbpJgvEkn9gRESAABhMP6CShIAAFqw//IAIgAAUPBbpE4iEkmCJyIsENogW5/m/wIAAALLhqDA +INEPeGL4dYL1JyIYJ3AFKApz+gpHBgCGRdD9Co4iVgA6oCUSSIlXKJkU85IJICkANiD6LAACAABZ +cPw8AAACEHAwWDbvwCDRDyMSSPP/4mAAECgwAAAA8//XYAAQGDD6LAACAABYcP0xCCIAAGDw/xJH +IAAQcDBYG50tCoj/AgAGAw9ukI8QZP90iveLqP2hFS/AEHAw+aILIEACYrAOzgH+FkEsACB3cP3c +QCYDDl5QJqkUDE4RDmYI9qUUKgAgW7D/AgAKAwjXUCgSSMmGyUQLuQJtSQUACIYASWGKwA8CAA8C +AK6q/wIABgMf7pCawI7wCO4RDk4CnrEoIAXDzvsWRiYC1mYQxGL/AgAGAtE2EMN9/wIADgMOuhAv +Fklj+YRoohElEkiJVyqZFGSjvoOZYACtAAAVgfMPAgAPAgAlUtUpUhgqkQLzEkgiygC2oCoKBfyA +zhAsEFgwWYeo8AKkYAAQUDAAiaeDmP2RFS/AEFgw/JILIEACenAL+wGr3f3cQCYCXR8QLJkUDE4R +rsz8lRQoACB08P8CAAoCV09QJhJIyWfcYPg8AAATADUgbUkFAAyGAEhhKfIADpkI/wIABgJqblCZ +8I2gCN0R/DEILAkAbTCdMfylCCAGEFgwWOejKCIQLoAFLwqV/wIABgIK/5CGImVjcCqCEymCFAqZ +DP8CAAABBI5gi1z0MAMgATZ+0CxRMtMPy8osMEQuMEX9MEYtgAQ7IP7MAgIAAFFw/jBHLYAEOyD9 +zAIKACAk8Pu8MC2ABDsg/VIOLAkAczBb+VRloxIpIhQoIhMdgaMJiAwujUB+0wUagaF4qxL6LAAA +ABBYMPwKACACEGgwW/i4+iwAADAQWDBb+Af8rAAC2QA2oCg8MPmsAAADEFgwbboFAgiGAEljKQoB +KcQAKCIWKMQfCIgUKMQeCIgUKMQdCIgUKMQcLlIOLSIQLsQTDo4ULsQSDo4ULsQRDo4ULsQQLdIR +/cQbIAAQMDD2xAMgABB4MC/EAg2OFC7EGg6OFC7EGf6OFAIAAFCw/sQYIgAAWXD9Vg8gMBBgMFv3 +piwiECvCES3CFLG7+8YRIAICa3D9xhQvmRBQMPpUBSAAEBAw0Q8cgEwukQUagW4swqwJ7hH6os8s +ACB3cK3M+cwRAAAQWDD8ClAqACBisPoWSiBAAlKwWX7bKRJKKiAHDwIAKJAHLfqY+wr7KgIBUDD+ +qhEIAEBaMPsgDCgJAFIw+JQHIAAQMDD6IAcg/BBgMPuUDCgAQGIw9pREIAEQYDD8lEUqIAFQMP2U +BSgJAFIwKJQHJ1IZHYFL8pYKIAICOfAnVhkmlhomlGwvUhiWmJaZJvECL/EDLdICBv8Mf9sFG4FB +L7YC2pD1rAANXQC2oPP8H2COEGgwLpEEjJArkQX9rP8h/gJTsP2VAivABDqg+soIC8AEPuALqgwE +CovA0A3dZPAKhA//f0NgKpEFLZEEsaoKCk/6lQUgHAhTcMCw+5UFIAAQUDCMkLDeDO4R/soIC8AE +PqALqgxj/70vMEcXgR0uIGn8MEQiAABRcPgwRSBwAllw9jBGLAAgJPD37gsNgAQ7IP7ifywJAEMw +/dIPLYAEOyD2+v8sCQAzMPjMEQ4RADOw/8wCDABAd3Bb+jBkrUD8gQkQAhBQMP1RMiAwEFgwWYbG +8/tIYI0QaDAA8/zwYAAQGDAtEkmN0mXa/ysSQvoSSSABEGAw/RJEIDACWvBYN5XAINEPLBJJjMJl +yt0rEkL6EkkgARBgMPu8GCAbEGgwWDeMwCDRDwAsEkmMwmXKuioSSSugQcDB+7wSIAAQaDBYN4TA +INEPLBJILRJJLMAULNRgY/gfjVhl2o+GLxiA4vhWCyBAAnFw/mYAIHACeLCfWJZZ/iYPIAAQEDDR +D9ogW56eEn/9C6YR9KCGYgAgMLAM6jArIoWLsLCi/LsIAgAAULBZiZ0cgNIqwvzwIQQAARBYMAC7 +GguqAirG/FmJ0sAg0Q8tEknFwizUBWP4Qy4SSY7iZeoTKxJC+hJJIAEQYDD7vBggQBBoMFg3WsAg +0Q+IWGSJ9I1ZwMCcW5jQjlid4ZxY/FYJIAAQEDDRDwAAAAAA+goHIAEQWDBYLbsvIn//JoMgABAQ +MNEPwDCTm/P7gmIAABswJhJI89cMADcANaAHSBT8jAgiAABJsPxMNgIAAGjwbckFBgmGAE1nKRJI +CE0M95kIAIACQvBt2QUICYYASGkH7AysvCzMQJzwY/syAC28QJ3wY/sp2iD7EkgiAABhMFkhtcAg +0Q/a8P0SRyCEEHAw/rUIIgAAYTBZILTAINEPwGCWq/P6IGIAAFpwAAApEkj72AwAPAA2YAhDFP08 +CCIAAFJw/U02AgAAOvBt2QUKCoYAR2sqEkgnEkEDRgz4qggAgAI58NMPbWkFDAqGAEdtKRJBCOoM +qpkpnECZwGP5xi0SQS3cQJ3AY/m72vD9EkcghRBwMP61CCIAAGEwWSCSwCDRDwBsEAgdgG0o0X7E +ZfV/pBAuEDgw9CxlIADT+hC4GvtMAAADEGAwWX3QjBIMjBQsFgIqMgYFqwErFgMpIAUsMB77MCIg +mggycP0KNiYAsT8Q/wIADgCx6xAuIGj/ITUuAKxbkCwxEC/8Af8CAA4ApXsQLCU1+yRoIgAAUTD4 +MgkgGAJYcPgmHCADEGAwWX23ijb5gEsSAIqikPsKQiwAhs6QKjAf/wIADgCBWpAsIAX/AgAOAHuz +EIknLSAHLpkU+pIJKiABbDD5IQcg3wA3oP5+wRDXADagDLwR+H6/HAAgczAvwjoIuAr4gpckARtD +4C/COfR+xhwCAWww9X+dHKAEP2D4/gEOAQ3H0AC7Ef9+xxlAAUww+CEIKcAEPmDzoAcoCQBucPOm +ASgJAH5w+eYAKAkAWjD/IgAoCQAqMJjk9eYGIAQQaDD05gIgMBAYMPPmAyAAEFgw++YFL4AEP+D7 +5gcuCQBv8P/mASBAAkuwAgqGAEljAAqGAElhjyf++sAgQAJ78P3GOS4AQHPw+/UEIIACc7Ce8P72 +ASBSEFAw+iQFIgAAEvDRD8Ag0Q8sMRArMCJj/rnFhSgkBWP+0Y4nL+kUZPFKiOmYFBp+ySkhN/8C +AAYAolZQjTYBGgL9jVcCAABZMP0WBSADEGAwWX1eihAKjRSdEI82jhUF/wGfEfsgBSAAmh+gdrmd +LDAed8EH/wIAAgCRnpB73hsoIHTEknmIEyogV3ehGC4gaC0wIn7RD2ABAQAALyBX/wIADgB8u9CO +Ly0xC4oUrt2dLyigE2SAq4qm/wIADgBR01D7CkggSBB4MP8kBSYATz8Qw4b/AgAOAGJDECowIikg +aP8CAA4AW1JQLSE1LDEQsd3/AgAOAFNrEB1/iSwlNR5/xyokaIoRLuF+/awBAgBje5D/AgAOAELu +kB9+ji0hN9MP/DEKIOQIe3AsJTd8p2p5rmd/rmR6rmF7rl58pgcoMB/EknmAU7Qb+jIJIAMQYDD6 +JhwiAABRMFl9HMAg0Q99ozf/AgAP/7U7ECwxECowImP/hMCwmxRj/rEsMQosJTdj/raNIsrZxOn+ +JAUgABAQMNEPAAAAAHzRkf8CAA//NrLQxfX/JAUgABAQMNEPAAAAAPosAAAwAlrw/AoBIgAAaLBY +Ni3E6f4kBSAAEBAw0Q8AABh/UvkKASIAAGsw/J05CAAMQpAfflsuITb8MQogNgR7sCghN3yJn/wK +ASAAEEgwDck4ZZ8jY/+OLCU2Y//oAGwQBMAg0Q8AbBAEFn5VJWLpKlIYKaEC+6EFIgAAOLD+oQQg +ABAgMPyiACEoADZg/Zz/If4CS7D8uxEJwAQ+YP2lAigAIE8wC5kMYAArK6EFLKEE+aIAIAICWvD7 +C08B/gJzMPulBSYAZN8QDO4R/pkIDcAEPuANmQwACYsEtGDwCYAPlAC64Bh+PCmhBSiCrAmZEfJi +4ygAIE7wqYgJiBH4IggAUBBgMPosICAAEFgwWXzMK3AHKiAH/Ar7KgIBXDD8qgEL4AQ+4P5wDCoJ +AFqwKiQH+3AHKOABHDD+JAwg/BBoMPcmCi+YEGAw8yRFKgBAarD8JAUqIAFcMPQkRCoJAFqw+iQH +IGoAPmBokjgkJhokJGwqUhiUKZQoK6ECKqEDLGIWC6oMessPKmYW0Q8kpQXz/zRgABBYMNEPK1IZ +sbsrVhlj/8YsUhqxzCxWGmP/u8Cl/H4OECwQWDBZhOjAINEPbBAMKCIYJyIQ0w8ogAUFCkf5CnMg +ARAwMP18AA4DAcoQ/wIAAgMIGqD6LAACAABZsFv/nPWsAAW3ADagKqIH2zD6rCAiAABhMFgsuotQ +/H5tHYAEPuANTQKdoSzCf/pweCIAABqwDLsM+2kUACAQcDD67gwOAveSYLavAPEEAJ8aAOEE8G0a +DqABWDANvSz/7gINoAQ/YA7dAp1e/zEIIgAAUXD/VQggBRBYMFjk1y0iECjQBSkKlf4KACYCxc4Q +iiJlowYs0hMr0hQMuwz9CgIgAo6O4CoiEi9wbxh9efqJFAoIAVAw/fwBABQAe/ANmwELqgIvIAcP +D0EM/RGo3SjSOsGe/xYHKgJ/zhAZfW0o0jkUftAJ+QopkpcEpAr5hgEOAnLOECRCf5oVnRb0w1Jg +YAIhMC0wRCgwRf8wRi2ABD9gCN0C+DBHLYAEP2D/IhcsCQB/cAjdEQjdAg/dNqTUiCmPKgj/DP8C +AAoBIifQKyAWKQr//BYKIEIESvAqIActFgn6CkEAABBgMFgw5YwajRn+CgAk3AA2oCk8MPQJFgBA +AlGwAEplAgmGAEpjAAmGAEphwIEoZCAvIhYvZD8PjxQvZD4PjxQvZD0PjxQvZDyLXitkMwuLFCtk +MguLFCtkMQuLFCtkMClyERt9QilkOwmKFCpkOgqKFCpkOQqKFCpkOJlf/lRCIcoANyAuZCMtZCf9 +iRQAwAJBsJgU+WQmIKACUbCaEAmJFClkJQmJFClkJCoyGQ6JFClkIvSiSmDgAkjw/lRDKgMAU3D6 +ZhUg0AJ48PEPFgCwAkGwAAiKLzIZCt0MCv8M/zYZIpYAN+AvMhuvr/0yGioAA1PQsd0vNhstNhrA +8Bh9GCkhBxp9GPkJSgoFAGYw+BIHKcAEPmD/+gkICQBWcJlgjSD7ZgIgQBAYMPNmAyBgEFgwC6oK ++305EB4CUrD6ShQJgAQ/YPN9WRgJAE6wmWELiAoZfTMogpeLFfnsAAgAQEow+zk4C6AEPuD7fVIY +CQBecAmIAvt+VRgJAFow+SEaIiYBRDDzfPsaACAe8Jhn+7CAKIAEPmD5ZgYsCQAfcJ1kC0sM+2YF +IBEANyAdfR+MELH7DbsCK8YAKyIViSmku/smFSgAICZwmSmIFiqGOSsgFi8K/3+xDyogB/oKQQIA +AGEwWDBBwOAtchQschH5UgggAgJrcP12FCACAmMw/HYRL5kQWDD7VAUgOwA2YI9ZnluZ8IJYnyGe +WP5WCSAAEBAw0Q8AnRmcGvosAAIAAFkwWDB5jBqNGf4KAC2pADagiFhkgffAINEPwPBlzq4pIQcY +fMMafMT9fPEZQAFMMPyLOQnABD5g+BIHKAkAVnCZYI4g/YgKAEAQeDD9EgUgBRBQMP9mAymABD+g ++2YCKAkAVnCZYRl84iiClx99BPkKACgAQEow/fk4DaAEP2D9fQEYCQBucAmIAv1+BBgJAGow+SEa +LiYBRDD/fKocACB/cJhn/dCAKIAEPmD5ZgYuCQB7sJ5kDU0MnWXz/stgABBwMAAAAAAAAPP82mAA +EGgwKlBDA6oKKqIcZKBrCto2KmYVL1BDCf8LuP/zDxYAsAJBsABIii9QQwn/CojwCogMmPAvUEOf +Ewn/Co/wmRj63QwAHgA34I0TCd0Lg9Ojo//SAioAA1DQsf+T05/SY/2aiBNkgM8qUEL+VEMgAgJS +sPpUQiAwAkpwgxT/CgAuzQA3YCpQQwmqCoqg8hYMKAABeDDzggoKAwBTcJogIlBDCSILuCIEAogD +ggv4FgIgEAIQsACCiihQQwmICoKACiIMkoAoUEOYEwmICoiAmRj63QwAAgJ78PISDCAzALYgiBPK +gSpQQv5UQyACAlKw+lRCIDACSnCKEig8GPXfhGIFAFYwY/5FwIEoVENj/+eNEwndC4nT89ICKAAg +TrD5FgEqAANSULEzk9KIEfjWAyzPALcgY/4YwKEqVENj/zqNLx59uP5WCyBAAllw+9YAIHACYLCc +WJ1Z+yYPIAAQEDDRDwDAUNog+1wAAgAAYPD+CgIgjhBoMFgyZsAg0Q+LF/osAAABEGAw+7wYIB4Q +aDBYNDpj/atoosmJNyyZFPU8AABAADcgg5lj/7mJNy6ZFPU8AABOADegg5lj+mqJWGSdhI9ZnluZ +8IJYnyGeWP5WCSIAABOw0Q8AAPP6Mm//EGgw8/9/YAAQGDCLF/osAAABEGAw+7wSIAAQaDBYNB9j +/T/z+iJgABAYMGwQDiogBBt8F/sWDiIAAEEw9KM4YHMQWDD2ChgmAZMOoP8CAAQBjyKgLCAHizD4 +FgQsIAFgMPwWBSrgAVww+xYMINYCWvD7SxQCAAAg8PsWDSQEdwKgKiAFxP7/AgAGAXP+kCYKR/8C +AAYFIzaQKyAWJwr/d7EQAMWOKiBBWC+E/wIAAAUmKqCIFRZ76AyFEfoSDSQAIDVwKVI69BYHKgTS +1lAZfN4nUjkJiQopkq/5dAEOBMjN0Bp7/SkSDfAKBwIAAEEwbZkCAEhh/X0sEAAQODAnFgH9JSog +LhBwMP4kVyAGEHgw/yRcIAgQMDAmJGQsMBX8bBQAAxBYMP8CAAgE+GLQKixl+H0rEAgCWHD4FgEg +AxBgMFl6qokX/SEHIAAQcDAuJGguJGkuJTX+JhwgQhBwMC4kdB57yfwSDC1AAWww/3wBHcAEP2D/ +JTcsCQB3cJ1AiyD6Eg0gmAJjMJxD/BIOK4AEPuD8RgIqCQBasJpBKZATZJe4IyBBKCAFH3z9AzcJ +/SEiJ8AEPeD3/wgAUBAwMP/yfyAmBDIwxJ55gQnFpv8CAA4E01IQGXze+3z0G0AEO2DwOBEAABA4 +MP8MRgZIAXgw8xIMLgcBeDD3RQovUAQ7oP3fFAeABDmg+6oCAJACWLDzPDwvQAQ/4PZ85RwJADMw +9kYHLgkAe7DzRQssCQBzMPpGBigJAGIw+kwgKAkASjD4RgQgEBBgMFl6aPYhKiAAEEAw+EQuIAAQ +SDApRDEpRDL5RDMgABBQMCpENSpENvpENyAAEFgw+0QvIAAQYDAsRDD2RC0gABBoMC1ENAaGFCZE +LC8gVy9EOw+PFC9EOg+PFP9EOSC4Aliw/48UAAQQYDD/RDggeAJRMFl6S/pMQCDAAkCwAgiIAEqK +AAiIAAqKLCIcixcsRFMMjBQsRFIMjBQsRFEMjBT8RFAgqAJRMPwSDCBgAlrwWXo8hhz/IHQmACAx +MC9kWI4dLlY5KyAWLQr/fbEK+iBBIgAAYPBYLrqIF8SWKSQFKIASZIBAFHtrgycEhCj6TAAAIAIY +8FufB/17gRIAAGEw/ny6EgAAWrD/IgAiAABQ8FuevoInIiwQ2iBbmldpoQVgB8R2oQbAINEPAAAA +JyIYJCIQ0w8ncAUFCkf5TAAOA4HZ0PgWBCIDiJqg2iD7CgEiAAA6MFv9JvWsAAaXADagiqcDOwLT +D/qsICIAAGHwWCpEi1AIvBEMfAKcofp8oBIAABqwKUB4KqJdtpwAwQQKugz6aBQAIBBYMPm7DA4D +dRIgAIwa8LEEAAEQQDDwiBoKoAFUMAioLPy7AgmgBDogC4gCmF78MQgiAABRcPxVCCAFEFgwWOJg +KSIQLZAFLgqV/wIABgNC91CPImXzKiiSEyaSFAhmDPsKAiAC/A2gKiISLEBvwe76iBQKCAFQMPvJ +AQAUAHswC4wBDKoCKCAHHHr7CAhBDIsRrLstsjr4FgsqAu13UB178SyyOZQaDY0KLdKvFHxX/cgB +DgLg7xAEpAokQn+aGJsZ9JOLYGACITAsMEQuMEX9MEYtgAQ7IA7MAv4wRy2ABDsg/SIXLAkAazAI +zBEOzAINzDakxI4pjSoO3Qz4FhEqATGnUCsgFvwWDyD/EHgw0w/4FhEgRgR68CogBykWEPoKQQAA +EGAwWC5sKBIRKRIQ/BIPJmoANqAqPDD0ChYAQAJaMABLZQIKhgBLYwAKhgBLYcDxL4QgLiIWixou +hD8OjhQuhD4OjhQuhD0OjhQuhDyNXh97IC2EMw2NFC2EMg2NFC2EMQ2NFC2EMCuyER56ySuEOwuN +FC2EOg2NFC2EOQ2NFC2EOPtWDyAAEFAw+lRCIfcANmAshCf8jRQAoAIyMJYS/YQmIMACUjCaFg2N +FC2EJQ2NFC2EJPoyGSAAEGgw/YQjIAAQaDAthCL0omhg4AJo8MCw+1RDKgMAUzD6hhUg0AIw8PUG +FgCwAlowAIuKJjIZCswMCmYM9jYZIqwANaAsMhusrPsyGioAA1MQsbssNhsrNhrAsBZ6mSohB4Me +HHqY9RYSK0ABUDD8qhECBQBNsPZ6whoJAGKwmoALugn8IgAgQBAoMPWGAyBgEGgwDaoKk4LzEgsg +HgJSsPpKFAWABD8gBaUClYEGMwoWerQjMpcdetb2EggiAEA08MBQ9tU4B6AEOaD+zAIECQA1cP17 +1hIJACzw9SEaIgkAfPD8hgQmJgEYMPOGBywAIDdw/dCAJIAEPWCVhiUSEg1NDP2GBSAQADZgHnqf +jRKxvA7MApzQhykoIhWkd/cmCSgAICIwKCYVhhkqZjkrIBYvCv9/sQ0qIAf6CkECAABhMFgtwY0a +LNIRLtIU+FIIIAICYzD81hEgAgJzsP7WFC+ZEFgw+1QFLEcANiCCWcDwn1uYIIZYkmGfWP9WCSAA +EBAw0Q+cHykWEPosAAIAAFkwWC35KBIRKRIQ/BIPLYcANqCIWGWMB4svHHu2/FYLIEACSXD5tgAg +cAJQsJpYm1n5Jg8gABAQMNEPwLBlnooqIQcWejsbejzzFhMrQAFQMPMSDivABDqg+3plGgkAWrCa +gPwiACIFAE2wk4KDG/0KQCAFEFAw/YYDJ4AEOyD7MwoGCQBRsJaBG3paIzKXHXp7+xIIIgBAXPDA +YPvWOAugBD7gC2YC/Xt9EgkANPD+zAICCQB88PYhGiomARww/IYELAAgX3At0IDzhgcmgAQ5oJaG +DU0MnYVj/qoAAAAAAADz/KFgABBgMCpQQwOqCiqiHGSgZQrKNiqGFSNQQw0zC7gz9wMWALACWjAA +y4omUEMNZgqDYAozDJNgI1BDDTsKi7D6zAwAHAA24A08C43Dra37wgIqAANTULG7ncObwmP9hGQx +miZQQsCg+lRDIAICMbD2VEIgMAJrcPsKAC7dADcgCwdAKlBDgxYNqgqKoPN2CgoDAFMwmmAmUEMN +ZgvzcwsAEAIxsPkGFgAQAhjwAQOKJlBDDWYKg2AKMwyTYCNQQw02CoZgsbv6zAwAPwC1oPoKACAv +ADTgJlBC+lRDIAICMbD2VEIgMAJrcIYWKmwY96Y5BgABXDD2FgYviAC3IGP+VsBhJlRDY//fDTwL +g8Ojo/3CAioAA1DQsd2Tw/3GAizGALZgY/4ziBcmghOWhmP4PAAAAAD6LAACAABYcP0xCCIAAGDw +/goAIgAAeXBYFKctCoj/AgAGARdukI8QZPnaiPeLiP6BFS/AEDAw+YILIEACIjAGRgH2FgMuACAz +sP7sQCYBFl5QjBQniRQMzBH7zQgGACBl8PeFFCoBEW+QyTomEgTJZfm8AAIAAEDwbWkFAAiGAElh +LUIADN0I/wIABgEk91CdQIbwhBQIZhEGRAKUsSggBcPu9LwABgDddhDEcv8CAAYA2D4Qw53/AgAO +ARLKEPP2a2IAABPwAMChKlRDY/5xAMBQ2iD7XAACAABg8P4KAiCOEGgwWC+4wCDRD4sb+iwAAAEQ +YDD7vBggHhBoMFgxjGP89IwiZcj8ixX6LAAAARBgMP0SDSAwAlrwWDGFwCDRD2iiq4g3LIkU9TwA +AJIANyCDiWP/mwCINy2JFPU8AADvADdgg4lj+XCIWGSIto9ZwOCeW5jwglifIZ5Y/lYJIAAQEDDR +DwDz+Tdv/xBAMPosAAIAAGlw/jILIgAAWPD/MgciAABiMFgKn8Ag0Q8AhiJlaHArIEH6LAAAARBg +MPu8EiAAEGgwWDFhwCDRDwAsMBQsJGBj9goAAAAAAAAA8/8PYAAQGDDaIFuYgxJ54QumEfSgYWIA +IDCwDOowKyKFi7Cwovy7CAIAAFCwWYOCHHq7KsKh8CEEAAEQWDAAuxoLqgIqxqFZg7fAINEPxcIs +JAVj9lWLG/osAAABEGAw+7wSIAAQaDBYMUFj+8oAAPP4h2AAEBgw+goHIAEQWDBYJ6ksIn/8JoMg +ABAQMNEP2iD8EgQiAABY8Fkbu8Ag0Q/a8PwSBCCEEGgw/bUIIgAAaXBZGrrAINEPwOCei/P+EGIA +AFpwAAD77QwAOgA04IYUDUkU+pwIIgAAOPD6ZjYCAABC8G1pBQYHhgBIZ44UiBMNNwj57gwAgAJC +MG3pBQgHhgBIaYYTDcgMqGYmbECWQGP9vIkTKZxAmUBj/bIA3VD8EgQghRBQMPq1CCIAAFPwWRqa +wCDRDwAAAAAAAABsEASLJ4u+K70C+7zwIgAAUPBYesuMJy7JFIvILcEV/u0BL8AQQDD0wgshQAJz +sP/MICoATXdQ+OwADgBAR/D+vQEsACB/cP3cQCYATt0QLuyg+MUUKgBPd1D/AgAGAFPvkJ7IGXkC +HnkZGHkU8AkHAgAASvAASWEASWEASWEASWEASWEASWEASWEASWEASWEASWEZeQmZsI0gwMr4tgIg +IAJ6sP62BC2ABD9g/7YFLAkAZ3D9tgEgFQA24I0iI7UQ+rURIBMAN2DAINEPwCzRDwAAAAAAAAD6 +LAAAAxBoMFu1yMAg0Q8AwOCey/P/dGIAAFkwC9gMCPgMKI0BKIzgmMhj/14p/ECZyGP/VgAAAGwQ +BownLskU8sIIIgAAULAtwRX+7QEvwBBAMPvCCyFAAnOw/8wgKgCDd1AI/wH6FgAsACB/cP3cQCYA +ixbQKy0BK7yg/sUUKgCKX1D/AgAGAI7u0JvIHHjBjRwbeNTwDAcCAABIsABJYQBJYQBJYQBJYQBJ +YQBJYQBJYQBJYQBJYQBJYRx6Ex54yP4mACBmEHgw+KIAIAEQSDD7JgIgXhBwMPwmBCIAAGNw/Zw5 +AAoQWDD4iBEOBQBj8P4mBSgJAFow+CYBIGcANKAnJgr9JgsiAABY8PkKViBgAlCw/wqIIE4QQDD/ +JRAoBQBicPgmCSAQEGAwWXde8xIAIgAAWTD8ChAggAJQsFl3WdtQ/AoQIKACULBZd1bbYPwKBiDA +AlCwWXdTijLIrcAg0Q/ALNEPAAAAAAAAAPo8AAIAAFiw/AoKIAMQaDBbtWrAINEPAMDQncvz/v5i +AAAS8ALeDA7+DC7tAS7s4J7IY/7oKPxAmMhj/uAAAABsEAYnLQQmcnFZfKiXEll8nictBid8xHZx +PisWASoWAPJsAAAcADVghmJoYBKLER14b/oSACAAEGAwWYDje2Mfy0SMJHTJNfosGCIAAFjwWOvv +zq+GIHZ5xsAg0Q8AAAD2IgAiAABQsFjrb4kSKJJwsIgolnBj/92MJGP/yYYgdnmdY//T0Q8AbBAQ +9iIHIAAQUDAqFBoqFBkqFBgqFBcqFBYqFBUqFBT6FBMg/xBIMCkUHCkUEIZu+hQSIAEQSDD5FBsp +oAQ44PgKAiYAIEGwKBQRJW0C+m0FIAMQcDD+VrIhAAJSsC6gRi+gRy8UHy4UHiqgRfoUHSAgAkBw +joGKgv+CACBAAkhwn5Cakp6RGng4iIOYk4ijjqGPoJ8QnhGYE4mi+RYCILAANSAorOCKgiuCAfyC +ACBgAkhwnJArlgEqlgIoggP4lgMiAABQsFh+YSwWEisWES0WE/oWECCAAmhwjtKE0P/SASCgAlhw +n7GUsJ6yJG0DLEnyjdP9tgMgARBQMPzMASAAEGgw/K04AAAQcDD8HDAiAABQsFudzChJ8miAcS5J +8/scUCIAAFCw+QoBIEACYHD+7AEgABBoMP6dOAAAEHAwW53BL0nzDwIADwIAaPBH+iwAAgAAWHD9 +bQUgQAJgcP3cuCABEHAwWJAlKFKz+iwAAgAAaPD8d/0QAgJCMPhWsyBkEFgwWOwFKla00Q8AACpF +8mP/hwAAKkXzY/+xAABsEAjzFgIiAABR8PcWASIAABlwWXwcWXwS1aD4MBFiAAA68P136BAAEGAw +WYBdqzNoYBT7fAACAABRcP134hAAEGAwWYBXq2YlLQT1UnEhkAI5cFl8DJcQWXwBmxMoLQb6FgQh +iAJCMPgWBSYAgK4Qh1L4cBdiAAARcIsTHXfS+hIEIAAQYDBZgEZ7czpkQE+MJHTJT/sSAiAwAlCw +WOtRZaBMhSCLFXW5xcCQwFD+EgAkBQBMsPJcAAA/ADVgk1KWU9EPAAAAAPVSACIAAFCwWOrLjRAs +0n6wzCzWfmP/xIwkY/+vhSCNFXXZg2P/ugDz/7hgARBIMAAu4n7TD/8SASQ2AT+gyfOKECqigFjq +vIwQ0w8rwn4rvP8rxn6MECzCfm/FQ1h7lPWsAAA9ADagixKTopajlKT6rBggEBBgMFl2Y40RyteP +ECjyf4IVLvJ+lYGSUZhQ9fZ/IAICc7D+9n4iAAARcNEP0lDRD2P/OYoQK6KAjBUpon6VsJtRnFD1 +poAgAgJKcPmmfiIAABFw0Q8AAGwQGCcwAll7ull7sCQtBChCQvWsAAIAADLw9EzgJBIAOiDAINEP +ANoQ/AoQICACWPBZdkIsMAsvMAYpMAUuMAQqMAf4MAopAAQ+YPjuEA+ABD/g/zAIKgkAerD5MAku +CQBLsAiIEfjMAgoJAHKw8JkRDoAEP+D6FiUuCQBP8PSgKmwJAHsw/BYkIEQAOqD9d2gSAABZsPpc +AAAAEGAwWX/bLhIlLBIkq+4uFiXJzvwWJCA4ADsg/XdeEgAAWbD6XAAAABBgMFl/0SwSJKvMKxAA +KQr++gr/JgF/TtD/AgAH/6FW0CkwA9MP0w/7EiUgWgBicPwWJCLzADbg+iwAAgAAWHD9EiUiAABh +8P4SJCAAEHgwW/9WLBIkKTAD/wIAAf+BZlApQkXTD/MKAiP/evZQLkIv/wIAAf91e5D/EAAj/3Fy +UCgK/v8CAAYBWUfQKRIl/wIAC/9mZlAqQZv8FiQmAVm+kC8SJWT+tv8CAA3/WZ3gLBYkLhAFKBAH +LxAG/xQWIP4QUDAqFBwoFBf+FBUg/xBIMCkUGy4QACkQAygQAioQBC8QAS8UESoUFCgUEoogKRQT +LhQQKaA/LqA8KKA+L6A9LxQdKBQeLhQaKKA6KRQfKaA7+RQZKBEAGjD4FBggIAJIcPiSASBAAnBw +mOGPkJ/gKEJKj5Kf4omT+eYDIAAGpiArLQUrvPBY6iUnRZsddwgsEiSKGisSJYkbiBiGGSZGRyhG +RilGSStGTipGSPxGTyABEFAwKhRLKkZKKkWajtOCIIzSi9GFJ/jSACHAAmtwj9L1Ug4gYAJIcJ6T +mJAlFiackvuWASACEGAwLBRBi9AjXQIlXQWJ0f3SAyADEDAwJjbCKFAHJlAGJhROKBRP9VAFIMAC +cHCf4iUUTZnh++YAIAAQSDApFEIpFEMpFEQpFEUpFEYpFEcpFEgpFEn5FEog/xBYMCsUTCsUQP3m +AyCAAlhwjbL/sgAgoAJgcJ/AncKOsS7GASuyA/vGAyIAAFCwWH0IKxYdKhYcJBImLBYeLRYf9U0F +IOACaHCM0frSAiD+Alhw+dIDIAICWvCZs5qyLLYBLdIALbYAKFkSLgoA/woBIgAAULD4jAEgABBo +MPj9OADAAmBwW5xxLFkS0w//AgAAAKGDIPhZEyIAAFCw/goAIKACYHD/CgEgABBoMPiMASD+Alhw ++P04AAICWvBbnGMpWRP/AgAAAHqCYPscMCIAAFCw/U0FIKACYHD93PggARBwMFiOyC4yw/x2oRIA +AFCw/uwBIGQQWDD+NsMgARBoMFjqp/o2xCAAEBAw0Q8vEAEoCsAI/wH/AgAP/nyb4GP8N9og+xwA +AgAAYfBY6i8sEiRj/RspEAEqCsAKmQH/AgAP/qKaYGP8EAAAAPotBSIAAFhw+qz4IgAAYfBY6gr8 +EiQtOgA2oCtCTvJ32xAsAjrgLRIlfSMyx+994y1gAEYAAAAA+2wAAgAAUXD9dncQABBgMFl+6ygS +JSpCTiwSJPuqDAoAA8SQeKsYLEZPLRIl/UZOIAAQEDDRDwAqVRNj/wgAAHorFCJGTvxGTyAAEBAw +0Q8qVRJj/roAAPxGTyAAEBAw0Q8AAGwQBCMiB/MyDiAFEFAw/He5EDAQWDBZfW8kPQIoQr19jwkp +QsLMkyoyksmsHHez/TKSIAUQUDD+QsIgMBBYMFl9Zccv0Q8AAAAAjCArID8MjUfwuxENgAQ/YPwM +RwoJAG7wDLsC+zaVILgCUTBYjxUtPQL61NwgABBgMCw22Pw22SABEFgw+zaSIgAAULBb/R/8dj8S +AABQsP0KACBkEFgwWOpF+jaUIAIQEDAiNpIuQr3A+A/uAv5GvSAAEBAw0Q8AAABsEAaKJ9sw/akU +IEgQGDD3oggiAQC88CyhFf3dAS/AEEAw/6ILIUACa3D+rCAqAIlvEPl9AS4AQEOw+HYyHAAgczD8 +zEAmAJU/0P2lFCFAAmpw/wIACgCTbxD/AgAGAJfnUJ2oGnYU/nd0EgAASfDwCgcAChBoMABJYQBJ +YQBJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYRl2GplwLCIA+HYCIIwCePD/dgUtgAQ7IP52BCwJAGsw +/HYBIIcANeD9EDMgbAJw8C51Ef0WACBQAlHw/XUQIBAQYDBZdLvbQPwKECBwAlHwWXS421DzdhIg +mAJR8PQSACAGEGAwWXSzLwqB+nxSIIgEeTAuYAAvYAEvdFMudFIsYAItYAMtdFUsdFQqYAQrYAUr +dFcqdFYoYAcpYAYpdFgodFmIIsmKwCDRD8As0Q8AAAAA+2wAAgAAYPBZdJ1j/+EAAPosAAIAAFnw +/AoKIAMQaDBbsrjAINEPAMCQmavz/uxiAAA78AfNDA3tDC3dAS3c4J2oY/7WL+xAn6hj/s4AAABs +EAgpMQcoMQMqMQAlIQEnIQUsIQcrIQYtIQQvIQL8MQEqACBm8PcxAiwAID9wJiED/iEAKgAgYrD8 +CjomACBF8PIxBCngASAw9jEGLgAgN/D1MQUuACArsP8KAC4AIHuw/xQALAAgd3D9uwgAABBwMP4U +ASAAEGgw/RQCIgAgKLD1EQAqACBasPwUAyYAIFXw9xEBIgAgOLD0Bl8CACAwsPhmCAIAIEiw91UI +AgAgMLClIvIFTwfwARAwpWX1BV8CACAwsKUiAgJP0Q9sEAonMBMkMBKWGSYiBwhEEfU3CAQJADkw +9mIOICACKfBZeb1ZebMoMBX8MBYg/xBIMNMP/Qr+LgCyShD/AgAOAK5rEC4wFy8KwA8CAA/uAf8C +AA4ApBugKDASKTATCIgR/W0CKAkASjD5CgEqAJfGIC/Sp5sX+hYGIBQAe/AJ+gIq1qf6HAAALAJY +8P0WCiAQEGAwWXQziBCDGi5wBokRKjLPLDLO/3AHIAEQWDD6mQwAABBoMPyIDA+ABDug+b04AAAQ +YDD4vDgOCQB7sP4WCC4AI28QKTLRKjLQjxKIEwr/DPmIDAAAEHAw+L44AAAQaDAPvTh+0B6LGGSx +dYsXHXVW+hIGIAAQYDBZfcqMGKvMLDbSYAAtjRjK2PptBSIAAFhw+qw4IBAQYDBZdA2LFx11SfoS +BiAAEGAwWX29jhir7i420ihwBCg2qi9wBXj3Cikyp/8CAAIAZHpQJEzwbkM4KnARDaoRekMvKlAB +9yxaK9AEOqApUAD4kUZiAAAasGiTK2iVFwNEDP5DDWQAIB1wKlABDaoRekvawCDRD2mo+PpsAAIA +AFlwWOjlY//Waazn+mwAAgAAWXBb/Zpj/8UAAGmo1IsYZL+7jCuyWfkWBSBmAB8wLJABK5AAK3QA +LHQBKpADKJACKHQCKnQDL5AFLpAELnQE/3QFIAIQaDAtJFhj/4DdkPosAAAAEFgw/hIJIgAAYHBY +6NSJFWP/toMn/HZqEAUQUDDzMg4gMBBYMFl8Hik9AiiSvfkWBCAoAPYwKpLC+RYEIAkAtqArMpLL +tI4UHHZe/TKSIAUQUDD+4sIgMBBYMFl8EGP+7QAAAAAA+m0FIAAQWDD6rDAgIBBgMFlzwmP+u4wg +KyA/DI1H8LsRDYAEP2D8DEcKCQBu8Ay7Avs2lSC4AlJwWI27Lj0C+uTcIAAQaDD9NtggARBYMP02 +2SABEGAw/DaSIgAAULBb+8T8dOQSAABQsP0KACBkEFgwWOjqiBT6NpQgAhBYMCs2ki+CvcCYCf8C +L4a9Y/5YbBAKHHY09yIHJAAgLPAmUAMoUAH5UAIh+AJRcCSgACqgASNyDvdQACAwEFgw+JkRCQAE +OiD5iAIFgAQ5IPoKBSQJAFEw+GYCAegCITD9fAACAABxMFl71Csykv8CAAABiKbgLjKV/wIADgDr +M5BkQmaXG/o9AyAAEDAw/hYIIQACUrD6FgkgABBoMPAAVmGAEFAwAAAAAAD4FgogABBgMP8KBCAR +EEAwDwIA0w9t+hT/sAgmACAXMCdwPLHM+7wBLgJvu9CJGvkWBCAIEFgw+2YCCgADR5DA7LTsrN3/ +AgAKAJujUK1bLLAFKbAEKLAGLrAH/7yEKYAEPmD4iBEMCQBLMPjuAg3gAWAw/g5PALYAPyD5CoAi +AESDIP8CAAAIAkLw/wIAA/+4hyD/AgAAGBBAMP8CAAQASIcg/woNJgBeByD/AgAADhBAMP8CAAYA +SP8Q+XWYFgBbRxD7zOkoCQBNsAuWOGP/bwCMGSzAXPv8AA4AZHMQwMBt6Rajx/+whCYAIFXwJ3Dc +scz7vAEuAgD50MCC8/9AZgkAQbAAAAD/AgAAEAJ68P8CAAoAR/ZQnhL/FgEgBBBgMPP/G2YJAGGw +AAAAAAAA+OlvcAgCYvD8FgUgIBBIMPP+/WYJAEmwKLAIL7AJ+XSXGYAEOiAI/wKfGPP+4mYJAEmw +tL//FgYggBBgMPP+0GYJAGGwGHRr8/7FZgkAQbD/AgAOAEZpEPcSCyIATkmQ9TpoI2AQIDDzKt0i +AIAB4Gh3HcAg0Q8A+goFIDAQWDD8daQSAABpsFl7VcAg0Q8AAIIngi78dZ8QBRBQMP0ikiAwEFgw +WXtOKCKS/wIAAgCggiApIpJok2AqIpJop1orIpJouFT9IpIgBRBQMPx1khAwEFgwWXtCwCDRDwAA +AAD6CgUgMBBYMPx1jRIAAHEwWXs7wCDRDwD8dYoQBRBQMP0SCCAwEFgwWXs1wCDRDwDz/0xgABAw +MAAAwsD/AgAP/6nlkMDU/wIAD/+k7ZD/AgACALFFkC4ikv8CAAgAq4OgIy0DjxIjPID7EgEiAABQ +8G35DyygXS2wALGq+7wBLgFEY1CHFWABVgAAAIQn/HVtEAUQUDD0Qg4gMBBYMFl7GChCkmiCOClC +kmiUMv1CkiAFEFAw/HVkEDAQWDBZexDAINEPAAAAAP0ykiAFEFAw/HVfEDAQWDBZewnAINEPAMKg +/wIAD/9W1ZDAtP8CAA//Ud2QeGcoLEKSjRYmTQMmbID90AQkAOEDIC1k3mAAFRh0Af8CAAn/XkGQ +Y/7GAAAmTQMmbICCEqNK+xIBIgAAYLBZcqEiZN0rEgQqTQP7FgogBBBgMPu8CCDAAlKwWXKaixr6 +TQMgBBBgMPu8DCDIAlKwWXKVghWlSg8CAPssBCAQEGAwWXKQ+k0DICgCWLD6rHggBBBgMFlyi/pN +AyAwAliw+qx8IAQQYDBZcocrQthksNvAxPxGkiAAEBAwIkaT0Q8AhhKjKvsSASIAAGGwWXJ9hxXz +LQMqACAosPM8gCAQEGAw9jTdIAgCWfBZcnbWMPp8AAAQEEAwbYoPLKAEK2DosWb6rAEuAJfbECki +kmiXFCoikmioDsC1+yaSIAAQEDDRDwAAAPotAyAoAlnw+qx4IAQQYDBZcmP6LQMgMAJZ8PqsfCAE +EGAwWXJfixT8CgQqACAgsPsWCiAQAlrwWXJZixr6LQMgBBBgMPu8DCDIAlKwWXJUKyLYy7nAxvwm +kiAAEBAw0Q8AAAAAAAAA/ULfIAAQEDDyRpMgBBBwMC5Gkg0dFA0eFP1G2CwAIHdwLUbZ0Q8AACgi +38D2LyaSCBgUCBkU+CbYKAAgSjD4JtkgABAQMNEPKWDe/wIAC/8d7lDApfx03hAwEFgwWXqIwCDR +DwAAAAD38wZ//xBYMMCxZLv1Y/ya9/MGf/8QWDDAsWS7F2P8iv3DBn//EFAwwKFkrW7Apfx0zxAw +EFgwWXp4wCDRDwAA+8MGf/8QUDDAoWSux8Cl/HTIEDAQWDBZenDAINEPAABsEA6UFCgxDioxGCkx +FicxFSIWEyYWEvYxDCAoAmhw8jEXIAAQeDAv1AL/1AMgABBgMPzUASAAEHAwLtQALDELLjENLzEQ ++TERJgAgTfD6MQ8iACBQsPgxEy4AIEOw/TESIDoQWDArFBf7MRQsACAzMP7MCAoAIHqw/KoICAAg +bnD2MRkoACBWcPuICAvgASAw+TEaKAAgSjD4EQsmACBF8PQHXwIAIDiw9hEKIgAgMLD6dwgCACBI +sPciCAIAAFkw9TcIBgAgQbD2IggCAABR8FjnlvIJTwnwARAwqYn5CV8IACBAsAmICAgIT3ipCipw +AftwACAiADagLXAA+goCIDQQWDD8dIMSAABxMFl6KsAg0Q8AAAAA/AqBLgBaAuD9CoImAWTm0P4K +hiYBbm7Q/AoXJgF3dtD0Cv8ghxB4MPgKiCYAU37Q+QqJJgD6RtD/AgAOAElK0CowFSswFtMP/Ar+ +LgBBIpB8uXotMBcuCsAO3QFp3m4oMBIpMBMIiBH5iAIAJxB4MHj7WikwJnSRVPt8AAAQEFAwbaoN +LLAYLbAI+7wBLgHdY1AqEhOKp/wKQCAwAlnw/fr/L/8QcDD6og4gARB4MFv69sAg0Q8AACoSE/s8 +AAIAAGEw/hISIgAAaXBY6QDAINEPJRITKzAVhVf1Ug4h4Agi8ChwCHSB5SswEi0wEwi7EQ27AnvL +1iwxCy0xDADMEQ3MAmXAji0xDS4xDgDdEQ7dAmXQfy4xDy8xEADuEQ/uAmXgcC8xESgxEgD/EQj/ +AmXwYSgwJnSJlCkwJ2mSjiowKGWviCwwKWXPgi0wKmXffC4wK2Xvdi8wLGX/cCgwLWWPaikwLmWf +ZCowL2WvXiwwMGXPWC0wMf8CAAH/qR9gLjAy/wIAD/+jo5DB+P8CAAv/nt/QKhww/AoQIBACWfBZ +cW37HDAiAABRcFjm+/usAA8cADagiKb/AgAD/4kmICmiBv8CAAIA0IZgKqIG/wIABf9+GqAsMQst +MQwAzBENzALOyi0xDS4xDgDdEQ7dAs3cLjEPLzEQAO4RD+4CZeAOLzERKDESAP8RCP8CZPHH+hIT +IBwCYPD+EhIiAABp8FjkhMAg0Q8AJRITKDAVDwIAhVf1Ug4v/0uiEChwCP8CAAf/RiYQKTASKjAT +CJkRCpkC/wIAC/88SxAqMCZ0qSkrcAQscAX9cAYrgAQ+4Ay7AvxwByuABD7gDbsCCLsRDLsC/wIA +A/8kBtAqHBj8ChAgEAJZ8FlxMPscGCIAAFFwWOa9+6wAAH0ANqCNpsDB+tMGYgAASzDAkMDgCc44 +ZO4Mj7b/AgAD/wOf4CoSE1jkbsAg0Q8qEhP7PAACAABhMP4SEiIAAGlwWOgCwCDRDwAqEhP7PAAC +AABhMP4SEiIAAGlwWOcNwCDRDyoSE/s8AAIAAGEw/hISIgAAaXBb/LXAINEPKhwo/AoGIDQCWfBZ +cQoocBjTD/8CAAP+yZogKRITiZt3lnIqEhMrHCj6rFogBhBgMFlxACwSE8Cy+8RYIAAQEDDRDwAt +MQsuMQwA3REO3QJl3VYuMQ0vMQ4A7hEP7gJl7UcvMQ8oMRAA/xEI/wJl/TgpMREqMRIAmREKmQJl +nSn/AgAB/pMGYCoSE1jkNsAg0Q8AAAAAKhIT/BwYIAAQWDD+EhIgUAJocFjl5GP/cwAAAAAA/XIw +EDMQcDAuFEAuFEGK0YnS+NIDIGACYHCYw5nCmsGN0J3AJRA8LhA9KhA/KhRFLhRDJRRCLRA+LRRE +KTAm/3IrEAEQQDD6EhMggAJwcPSZDAAAECgw+YU4ABACavD1FgAiAABbcFv5KsAg0Q8AAPzTBn// +EFgwwLFlvHhj/DlsEASHJx9x+Sp5FIh4KXEV+q0BL8AQaDD8cgshQAJSsPt8ICoAPVZQDbsBq5n5 +nEAg4gRDMC6NAfp1FCFAAlOw+pNscgAAMjB5oXWaePAPBwIAADmwAEdhAEdhAEdhAEdhAEdhAEdh +AEdhAEdhAEdhAEdhF3Hxl2CFIJNl9GYEIAoQODDyce4VgAQ9YPJmAiQJAD1w9WYBIgAAEbDRD8Ag +0Q/AgJh78/+jYgAAMzAAAAiaDAq6DCqtASqs4Jp4Y/+LLLxAnHhj/4MAAABsEAQoQA6KJy9AEClA +ES6pFPj/EQhgAUAw/ogRDgkAT/D4/wwAOBBoMPyhFSHwAnvw/u0BL+ABfDD+7KAsAQD/cP0NTwoA +W/cQg6iLq/j6wCBAAnqwCP8Br8z8zEAmAF8e0Cs9ASu8oP6lFCoAXl8Q/wIABgBi5tCbqBxxqRpx +u/AMBwIAAEjwAElhAElhAElhAElhAElhAElhAElhAElhAElhAElhmjCOIPlxsRAKEHgw9TYEIHQC +Q3D5NgIvgAQ7oPg2BS4JAHuw/jYBIC4ANODAsPXcKiBAAjDw+mwAAgAAYXBZcF7aYPtMAAIAAGFw +WXBQiyLIusAg0Q/ALNEPAAAAAPosAAIAAFjw/AoKIAMQaDBbrmjAINEPAMDAnKvz/1ZiAAAa8APO +DA7+DC7tAS7s4J6oY/9AKPxAmKhj/zgAAABsEAgrMB4uMB8PAgD/MCArgAQ+4PowGioJAHbw/jAh +K4AEPuD8cmoaCQB+8P1y2xuABD7g+KoRCgkAdvD/MBwoAEBi8P4wGyCwBGowDqoC/jAdK4AEOqAP +qgIIqhEOqgIMrgH8ciUQcgRrsB1yzA2+Af2vAQBWBGOwfPEjaLAgyb2KJ4quWOjg/AoSIBQANqAq +MCJ6wwnIqP8CAAgAigKg0Q+KJw8CAA8CAISuLcpQ9U0CIdoEaTAuUoBp5uIpMCcvMCYmTQMoYY0I +/xEJ/wJ4+c0qrBBYHt33TQQgBxBAMPhWgCEAAjnwKHBL0w8IGECYFFl1bFl1YvwKACPoEGgwWXmv +L1KFiRQPvwwvZWQuMCIudEr9MCMgQBBgMCx0TC10SyswFvt0TSAAEFAw+nRGIE8ANmAoIRi2O/gI +RgAGEGAw+k0EKfAEOiD4dE4hkAJSsFlv5xxyki9wSi5wSS1wSCtwSysWACpwTCoWAflwTSA0EFgw ++RYCIAUQUDBZeC4sTQTyzLAiAABQsPwKACIAAFiwWOhz2iD7CgAgBBBoMP1WgCBQEGAwWW/c0Q8A +AAD6LAACAABg8P1yexAAEFgwW/8+0Q8AAABsEAwoIAT0IAciAABRMCwiB/YsAAAcEEgw+hYKJCAB +IDD8wg4mAZXOECgiAvpyLBBuALYgKyBTLSAWC7sJ/gr/K8AEPuD8FggqACBasPqifyIBc4Tg9wpQ +JAFvgOD6FgkgJARzcPS1GgIAAFCwWGTyZKNK2iD2FgsgPgJZ8PtLFAIAAGHw+xYNIgAAaTBYZMv2 +rAAAVQC2oCwiAmTDCY4gGHJQ/RIKIAIQeDDzFgIvgAQ7oPgWAC4JAHuw/hYBIBEAN2Db0PwKBiAY +AlBwWW+W+iwAAgAAWHD8CgIiAABpcFghcdKg0Q8AAIobjRkbcj36oCYgABBgMP1/QAhIAWgw+IgR +D1AEP+D9DUYOCQBH8P/dAgsABDqg/GUKKgkAarD9cbEaCQBasPpmBCIBFITg/wIABAEQgODEsCtl +CykhGRhyKp1m+QxLD0AEPmD0wA9uCQBH8AneFATuEQ6uAp5k/2YGIgEYAOD/AgAEARQA4B5yH9MP ++eECIDACaHD51QIgQAJRsP7iACAGEGAw/tYAIgAAW3BZb2QechYccIX6bCYggAJ4sP8WDCRYAjzg +LyBBLSBALWQmL2QnKyBDKiBCKmQoK2QpKCBFKSBEKWQqKGQrYAAkAIwbLMAmG3B1DMwJDMwRrLsr +vSD7vDogBhBgMFlvTR5x/xxwbiNkMxpxyPpkLSCJEEgw+WQsIBAQQDD4ZC4gABB4MP9kMCAFEGgw +/WQxIgCSBOD/AgAEAI4A4MCqKmQ1+xILIAIQeDD/ZDggABBoMC1kN/9kOSAAEGgwLWQ2Co8UL2Q0 +K7AmC7sJDLsR+8sIAHQCUbD+uwgABhBgMFlvLSpsRPkKAyBwAliw+WRBIAQQQDD4ZEAgCBBgMFlv +JcC1+2RNIAsQUDD6ZEwgBhBgMPsSDCCcAlGwWW8eKmxY/AoIIJACWLBZbxsqbFX8CgMg0AJYsFlv +F/oSDSIASATg/wIABABEAOAfccYMThGv7prgLCAWLQr/fcEK+3zwIgAAULBYZCyKGIuhiaAFCEf3 +mQgAAgJa8PumASHoAkpw+aYAIlIAOiCKJ/sKAiAAEGAw+qwgIAIQaDBYG/LSoNEPAAAAAPP9IWD4 +EDgwwCDRDwAAAADz/uZgNBBQMIYoY/zTKwroK2ULY/3eAAAecab4bQEgKRBYMPtkYSAPEGAw/GRg +IAYQSDD5hAQgARB4MP+EBSAIEGAwLIQGLoQHY/9Hixr8CgYgQAJRsFlu4mP98wAAAAD6LAAAMAJZ +MP0SDSABEGAwWCgHY/zfjSJl3NorIFP6LAAAARBgMPu8EiAAEGgwWCgAY/zBbBAEhifCefZiDiKG +ALzgyzv8TAACAABpcPosAAIAAFjwW/8AyqH4CiQiAGEA4ClhErGZKWUSKiAF+wonJgBlxpD/AgAG +AGvekNEPAAAAbzUCbzNP+TXxYCYQWDAqIAV7oeb7PAACAABQsPwKACIAAGlwW/7sZK/QLCAFd8F3 ++3FoEgAAULBY6GeNZ4pmsdv9u1NwAgJysJtnnmbRDwAAAAAAAAD6LAACAABY8PxMAAIAAGlwW/7b +ZK+O+DRAYCgQQDApYRcpnAEpZRcvIAX/AgAP/7vD0CckBfsakCIAAFCwWOhQ0Q+bZ5pm0Q8qYROx +qiplE9EPwrUrJAVj/38sYRaxzCxlFtEPKyQF+wpkIgAAULBY6ETRDwAAAAD6LAAAKBBoMP0kBSGQ +EFgwWOg90Q8AAABsEAqHNPZw8RZwATwwB3gJDIgRqGYrYn/0MDMgOgA24BpwOh5v7S1tAi3QAC7i +tSqihq7dCd0R/aoIAAEQYDBZSYQpbQIpnIApkHn+lwdyAAAysH+fAdEP+jwAAgAAWHBY7lbIr8Ci +/HEiEDIQWDBZdrzRDwAA23D8MQoiAABRsFjuP/esAACjADag2nD8TAAAQAJY8FjtJGWvuvYKKSAo +EHAw/wonICUQaDD/AgAAJBBgMP8CAAAATIUg/wIAAgCDASD/AgACAJKFIGhEh2lFhCpwBdMP/wIA +BgDY5pD/AgAGAONukHriB/8CAAgAz36Q/wIAD/+wspAqfGj8CgMgQAJYcFjs/WWvSyocGPwKCCBw +AlnwWOz5/wIAAADmJqDaIFjs69EPAAAAKzEK+wtLAgAAUbBY7TT3rAAPTwC2oMCi/HDsEDIQWDBZ +doXRDwDacPscAAADEEAwbYoVLKBoJLAg/wIADgDo4RD6rAEgAgJa8CpwBcKUeaElfaExeuImf6Ij +2nD7HAAACBBgMG3KDy2wGCygSLGq+7wBLgCx41DaIFjsy9EP/wIAD/9VMpD8PCYiAABR8PsKAiIA +AGlwW/9C0Q8qcAV8oRf/AgAGAHjukP8CAA3/P9GQ/wIADf87+pDaIFjsutEPAAAqcAV8oQh9oTp6 +4i9/oizacPscAAADEGgwbdoVLKBoLbAg/wIADgCrY1D6rAEgAgJa8NogWOyr0Q8AAAD/AgAP/xUy +kNpw+xwAAAMQcDBt6hUsoGgtsCD/AgAOAJjjUPqsASACAlrw2nD7HAAACBB4MG36FSygSC2wGP8C +AA4Ab2NQ+qwBIAICWvD6fAAAAxBYMPwKACIAAGlwW/8R0Q8rfGj8CgMgQAJQcFjsmWWtudogWOyM +0Q8AAAAAAPp8AAIAAFhwWOw6ya6Jp4mewIEolH7RD/p8AAADEFgw/AoAIgAAaXBb/v7RD8Ci/HCI +EDIQWDBZdiDRDwAAAAD6fAAAAxBYMPwKACIAAGlwW/700Q8AAAD9wwZ//xBQMMCh/wIAAf9JpqAq +EQH/AgAB/0RykPw8JiIAAFHw+woCIgAAaXBb/ufRDwAAAAAAAPTDBn//EFAwwKFlrRBj/ir9wwZ/ +/xBQMMCh/wIAAf+QJqACKgJY7FzRDwAAAAAAAP3DBn//EFAwwKFlrOBj/qX9wwZ//xBYMMCxZL7N ++nwAAgAAaXD7CgQgTAJg8Fv+zdEPAAAAAAAAbBAWIhYg8xIgIgAAEPAtMAcGbgL/MAUgRxBQMPcW +BSwgAWww/RYOIEYQWDD93BggGARb8P8CAA4Da1PQJDEijD6dFJUZJiITJyAVKTBBLyADGG/2+ZkJ +D/AQUDD8mREOACAX8PmICAB+Anvw+RIFLgBAV/CK8fiCfyYkATww+BYNICACW/D5ZjYKAxNTkMDQ +/xYIIAAQKDAN7wwdb+qI0wnMEayMLME3KHr/9BYHKgAHYhAUbyKXFmAADwAAJEoABMQ29xYGJeAB +IDAs0vwPAgD/AgACAAA7MP8CAAoAT1OQjRiI0w+qDCwWA/3SAigAIEPw+BYKKgAD+hAt3AHA8PIW +DCIAAGNw/RIKIALCJaDyFgwgAr4moMAgbQhaCmk09ygKCAEAzTCZgAcpC52TnJKIgAhmDPiqDAAC +AhCw/cwACAAgbjD5Fg8qAANCULHN/NwAAAICe/D9Eg8gGAA8oPIKACAwAjnw/wIAAAKLpaD/AgAA +AoemoGP/npwTC10LC1oKiqCI05IcjdL/qgwIACBD8PgWCyoABnoQ8hYMIAICa3Dc0P0SCyAAEHgw +/xYeIAAQEDD/AgAAAFIloC4WH2AALgAAKBIe9VwBKAAgQ7D4Fh4gGAA9YPUKACAwAlrwC1wLC1oK +iqCNw/zCAiAANiWg/goAL88ANqBqYcdtCFT3KQsIAQDRsPcvCggBAMEwCGYMCKoMmPD8lgIgAgIQ +sP2WAy4AIG4w+PsGcgAAazCxzfzcAAACAnOw+CEMYgAAa/DyCgAgMAI58GSvd/8CAAH/uiWgY/+k +AAAuEh+IFfYSDCAAEDgwlxArMBYmYhMuFhv3EgMg/xBIMPhmNgAkBErwjBkqMEEAzI5YIa9kpH8t +Eh75bhQTnAA3YBhuE4UeiheNHR9uMP8WECCQAiDw9BYUILgCEPDyFhUgABAgMPrbFAzAAWgw/Y5C +C0AEPuD47hEMBwFsMPXdEQwJAHMw/jxgKgkAbvD+FhYgABBoMP0WHCtABDqg/G9QGgkAZvD7Fhkr +wAQ9YPm7CAXgBD1g/BIGKgkAYrD7FhMkACBFcPUWESAAEEAw9Qo1IAEQWDD6FhchpAJjMPy4OAA2 +EFgw+hYSKgUARXD7FhggABAQMPAAFGAAECgwAAAAAAAuEh7/AgAGAXP1UMD1D18v9PJqYAICKXAk +TQEkTIAtMQcebeUNDUoM3RH8beIcCQB3cJ1AizAHLgr8RgIgRBBoMPi7EQAIEGAw/UYDKgkAZvAr +RgEqMEEo4gApEhn+FhogBBB4MPgIQQsABDqg+m8EGAkAVnAI/wz7EhQuIAF8MP8WHSgJAFZwKUYE +LuIA+RIcIAAQQDAoRQr/EhcuACB7sP9GBiB4AnOw/kULIBAQYDD/bwsd4AF0MP9GBygAIE9w+RYc +IEACUTBZbJT/MSogABBQMPpEMiAAEFgw+0Q2IAAQYDD8RC4gABBoMP1EMyAAEHAwLkQ3/0QtIAAQ +QDD4RC8gABBIMPlENSAAEEAw+EQxIAAQSDD5RDQgABBAMChEMA+PFC9ELC4wVysSFS5EOw6OFC5E +Og6OFC5EOf6OFAB4AlEw/kQ4IAQQYDBZbHP5EhYggAJRMAIJiABKigAJiAAKiioyHCkSHipEUwqK +FCpEUgqKFCpEUQqKFPpEUCBwCElwKxIdHG8eLQpC/TR0KiABXDD8CgkqCQBm8Pw0ZSCKAlEw+LsR +AAMQYDD7FgAiAABYcFlsWS8SGywxNQcoCy0SGC00V/mCAyACAmMwLDU1LBIaG27GK0YWisAqRheO +wI0/KUYZiIL4RhguACB/sC82HIzA/mYMAAICELD/FhssACBrMPw2DyAYADyg8goAIDACOfAYbWoo +RhooEh3A5Q5eL7iPL0Yb/zB0KAAgIjD/hHQtywC3oCkSHgWZDLGZ/wIAA/7dwmAsEhMrEhIrxjkr +MBYqCv96sQgqMEEsEhxYILYtEhKJHCgSG5iblpeOMsT3/zQFIMQAN6DRDy0SHioSE/XdDAAFEHgw ++qI6IAICa3AP3TYN3RH9FhIqAFdukCgSESQSEyiClyRCOQhEAWRPsikSEP5MAAAAEFAw8AkHDVsA +N2BtCAmxqvAOoAf+p26QY//vjB7AoPsWEi3ABDsg+hYcLAAgSzAsFhMvEhMuEhIu9jkrMBYtCv99 +sQgqMEEsEhxYII2IHCiAE8iOiRyKP4mWepkGxKgqNAXRD8S2KzQF0Q+Ns4yyirAvFh5j+yUA8//v +YAAQEDDaMPsSBCABEGAwWCUh0Q8A8/9hYAAQIDCF9KpV9eNocgAAarD1FgIgABBAMPgWASAAECgw +iBGNEvVcASAIAkIw+BYBJCgAOiD5CgAgMAJa8PkWASAAECgwiBGriIiArYj4FgIr/+hDkP8WCCv8 +ymuQDt8MY/mM0Q8pMEEpnBKZFPP+p2AAEGgw8//cYAAQKDBsEAiUESgiByYxC/kgByBIEGAw/YkU +IEYQODD6IAUgRRBYMPkJQQGIAjGw9YIJIYkAN2D/AgAOAPjikCxQEsjL+RYEICACUjBYGpiJFIRQ +2lD7+sAk+AEgMPUWAiYBSoEgiBKIiiwwX/8CAAoBWjYQ9MFXacAEOmAnbDcHRxS0dxxszwyICCyC +OvVuaxoBTb8QHGzLKII5DJwKLMKXDIgBKBYA+BYDIokANiAebOQADotteQIASGH/AgAGAcCBIC8w +XxtszPls0xAzEEAw/DBeIXgAt+D/AgAGAJvFEP8CAAYAm4EgLaAT9KIGITQAN2AtIg//AgAOAa3p +EGXBSsCgjxIu8AcIqBH9IQcuCQBDsJ7xKCAHihP9DUoOAgFAMPzdEQ6gBDug/G2MHAkAd3D+IQgs +CQBPcP2mACggAUAw/SIAKQAEPiD7pgIuCQBLsPymBi4JAGOw/qYEIgAAS/D8CjAgABBwMP6mBS2A +BD9g/qYHIAQQcDD8pgMsCQB3cP2mASBAAlKwAgmGAEpjAAmGAEphG2yK+RICK8AEOiCrqiemOYmQ ++YlXADIQUDB6kSnaIFgVc9EPAPypf3AAECgwwMAswBJlzndj/oEtMF5l3qbz/qtgBBA4MAAmIRQj +IRL0CgAvzAA1oPpSYyIAAFjw/AoAIAEQaDBYF9MoUmT0TAEgAgIY8AgzLnZJ22P/oABkzupgADIA +AGTO4mAAKgAAZM7aYAAiAAD/AgAH/we+kP8CAAf/A96QY/95d6GB/wIAB/+/XpBj/2uKECwgBysh +CP5scBBuAiGw9EQUDAIBZDD8DEEMoAQ/YPDMEQwJAHdw/aYAKgkAZvD8IgAgMAJpsP2mAyAAEHAw +nqUdbewebFn+pgItgAQ7IP4SAiwJAGEw/KYBKgkAbvCbpABOjZannaYCCo8sIAwAzBH2pgcqCQBm +8PumBCIAAGGw+zxUIFACUrBZax+OEPlsTx/ABD0g+2xFHgAge7CeE/P+EmCJEFAwjSeFESzRFS3c +IAvdAf3NCAXABD1g/dxAJAAgLPD4XAAKAMbpUJgSY/1EAAAAAPP9TGIAADIw8/10YAAQQDCPImTx +Uv8CAAf/PgEgiCcpiRQmUpv0kTdgQAJSMIWJJVAH+woAL8AQIDD8bAACAABpcFgX74gniogpgRX7 +ggsgQAI6MAR9Af2ZCAIAAGHw+ZxAJgCR1tCLES6JFAy7Eavu/oUUKAAgWrD/AgAKAI3GUMozjhH/ +rAAAHwA3oG3pBQQDhgBPZYwniHAPAgAPAgD8zCAoACBaMP8CAAYAxk4QmHCLwynBBY4gjRH4wgAi +AEAjMPKZCA+ABDug+ZxALAkAd3D9pgEmAF3G0C/JBAxaEfqLCA4AIFfw/8UEKgCB3lDJa9Ng/4wA +ABcANWBtWQUGA4YAT2eLwA8CAA8CAKq7/wIABgCYztCbwNEPiieNEcDA+qwgIgAAW3BYF7WaEmP8 +bHTbEg1ODP6mBi3tALcg8/ycYIsQUDAE3wz/pgYt2gC3IPP8iWCMEFAwAAAAAADz/stgABAoMPuc +GCIAAGnw+iwAAAEQYDBYI9lj/pYAAAxYDGP+cMCQmYvz/yRiAABS8MCgmsPRD/qUDAA8ADTgjBEE +SRT+nAgiAABA8P7MNgIAAHqwbckFCAiGAE9pjxGkOPn/DACAAktwbfkFCgiGAElrjCcszCAEvgyu +3i7sQJ5w8/7Mb8AQIDAAAAAAAAD4lAwANgA1oARJFPucCCIAAHow+1s2AgAAQbDTD225BQwIhgBP +bQRoCPldDACAAkiwbdkFDgiGAElvBK4Mri4u7ECewNEPAAAv3ECfcPP+cW/AECAwKCxAmMDRDwAA +AABsEAgpMC4rMC/zMgQiAABQ8AiZEQuZAvMDUwAeAD5gaJYHwCDRDwAAAAAroDAsoDEIuxEMuwIr +vfhlv+UpoDQroDUImRH8bJ0YCQBecP1tDhAOAD5gaZLJK6BGLqBH/6BIK4AEPuAOuwL+oEkrgAQ+ +4A+7Agi7EQ67Agy8AX3BoRxtAx1sWQy8AX3BlfVtERASAHTwx9sNMwGNVBdrwRxsbfIKAC99ADdg +mhScFWAAviqwPC2wPfywPiuABDqgDaoC+7A/K4AEOqAMqgIIqhELqgKNFC/QNCjQNZoQKdBGKtBH +HGz8+9BIKYAEPmD+EgUoCQBWcP3QSSmABD5g+P8RCAkAXnD4/wIJgAQ+YPgSBigJAG5wmRGJQPkW +AiAFEFAw+IKeIDQQWDD4FgMiAABo8FlyfYwUK8BGLsBH/cBIK4AEPuAOuwL8wEkrgAQ+4A27Agi7 +Efy7AgIAAFGwWOLmZaGfjVSxIv8CAAv/W+iQKHKrJlL6qCgJiBGoZopr1GD5YDkhwgAisHk513mu +1NpgWTs5ZK/MihSKpHmmQooUKqEK+hYFK2ABUDD7a3kSABkioHqyKvsSBSIAAFGwWOO2/QoBIAAQ +cDD63jgAABBgMP7cOAIAACGw9M+HZAUAUrCJFIZHKpA/K5A+LpBHLZBGhm4okD3/kEgtgAQ/YPxt +AiwJAHdw/pBJLYAEP2D/kDwsCQB/cPwWBi2ABD9g/sKeLAkAd3D8bKwfgAQ/4P0WACIAAGjw+JA0 +LgkAR/D5kDUvgAQ/4PsKNC4JAF/w+P8RCYAEOiD6/wIICQBKMPgWASAFEFAwWXIwjxQu8Dwp8D34 +8D4vgAQ7oPnuAgAFEFAw//A/L4AEO6D47gIANBBYMPxskx+ABDug/WL2LgkAe7BZciGNFi3SgGjS +CYsU/wIAA/7/n2CLFCqwPC6wPfywPiuABDqgDqoC+7A/K4AEOqD+YvYqCQBisAiqEQuqAv8CAA/+ ++FOQ/BIGIhIAP2DAsyvGgMCl/Gx6EDQQWDBZcgpj/l+KFCmgNCqgNQiZEQqZAv8CAAAAQwZg/wIA +A/6CmmAfbHAtQRuMFYtL/A5LDABAf3AO3QINDE/8FgUgQAAe8IsUKkxa+7wmIAYQYDBZaaTAwvxE +WCAAEBAw0Q+NFCvQPCzQPf7QPiuABD7g/LsCAgAAUTD80D8rgAQ+4P3cNioJAHbw/hIFK4AEPuD8 +CgAqCQBm8FjelGP/pY8ULvA9LPA8/fBGIgAAUTD48EcgAhBYMPnwPi2ABDsg+N0RDAkAczD+8Egs +CQBHcPjwSS2ABDsg+N0RDAkASzD+8D8sCQB3cP/8Ni2ABD9g+MwRDAkAR3D+/AAMCQBzMFjcVcAg +0Q8AAGwQEvQyBCIAAHkwAiYC0w/ya+AUcAEgMARECQxEEaQiJCJ/DwIA/jELILUANSAaa/8Zatoo +LQIogAApkrX+FhQiAABZMPqiYSABEGAw9hYTKAAgSjD1FhIpkAQ6IP8WESoAIEKwWURrLzAzKzAx +LjA3LTA2KTAw+qAHIgAAYrAlMDT2MDUpgAQ+YPjdEQogAVAw+hYXJYAEPWD2IoMkCQA1cP4xCiwJ +AHdw+5kCAHACWPD3vAAARgA1oIpn+qIOIIgAPmD4kmxgDhBwMP8CAAIAVgZgaJQJ/wIABAEqBmDR +D2ny+mRv9ysWEPwWCSB0AmjwLRYWYAEjAAAAAPmRxGAAEFAw/wIAAAF7B+D7FhAjngI74I82Dx9S +/hYYJKcAN+D6zAACAABhcFjuBdEPAAAAAAAA/wIAAADQh+Bp8p8Ya7sogX7/AgAAAP32EC4wOMCY +fpKJaueG/wIABgJNh6AroSOxuyulIyoSEywSEf0SEiIAAFjwWPrR0Q8A/wIAAf+vh+D/AgAD/6ub +4GRfT/sWECAUEBgw8ADZYAAQIDAAKHABpIT3hwoKADepEClwAH6Z7C9wAihwAyphGQj/EQj/AvoK +Sw9gAXwwevnSKS0CKZyAKZB7A5kRCfkCKWUZiRgokRvaYPwSESIAAFjw/RISIAICQjD4lRsgBhBw +MFjsVCpwAdMP0w/0pAgADhBwMPenCgv/zK0QhmnLZosZKhIW+7AWIAYQYDD7ZBYggAJZsFjtlP4K +Di/gALagiWf3EhAgABAgMPmSDi/OADVgmRhj/1kA0Q8AAAAAAAD8a6If/z/akAwzAS1wAaTU99cK +CgHKKRAqcABoojL5pN5gCxBYMCYigy767/RuU2IAQHTwL3wEnxSKFPwKCCBwAlmwWO15ZK/Bhmll +b+pj/jEmIoPHi/RuKWIAQETwsnkpFhUqEhX8CgYggAJZsFjtbmSvloZpZW/pY/4GAC4wOMCofqIH +/wIABgF/j6DAuf8CAA/++FuQHGt9LzBDLjBCLTBBKjA9mhApMD6ZEfgwPyAyEFgw+BYCIAQQUDBZ +cQIqEhMsEhH9EhIiAABY8FjtYtEPKhITLBIR/RISIgAAWPBb+iHRDwAAGGoWijMSazgogqQiImGq +iAmIEagiiicrqRRksnqLqSYSFx1puAxqEfeyACoAIGqwKaI6Lwow+2sLEgAAKvD3h1cKAAx2UBhp +sC6iOQhoCiiCl/jmAQgAN0OQiSJkkzD/AgAP/px50IknLJkUJbL89MMVYEACUnCLmSawB9xQ+woA +IgAAabBYFXiKJ9sw/BIRIEACUrBYGLiNICwSEYsnCN0RDcwC/KYBIEACUvD7XAACAABhsFgYsNEP +LqBQse4upFDRDyggBxlppQgoQAqIEAmIAphgiCD8FgkgjBBQMP1plxAKEEgw/WYCKYAEOiD6ZgMo +CQBKMPhmASAwBHnwiictEhHAwPqsICIAAFtwWBVW1aAtIAcsIQj7axocIAFsMADdEf3MAgAAEDgw +92YFLAkAWzCcZABFjfIGHwBQAlGw+2YGIHQQYDD8ZgcgqAJY8FloURpqxIstiqP5uxEABhBgMPs9 +ASoAIFqw+hYPINgCUrD6Fg0hlAJa8FloR4of9zw9IAMQYDD6rEgiAABZ8FloQYsfi7f6aX0QIAJa +8JsbW40aHGl6HWnojx8eav/6EgsiAABasI/wW4zSih+KpyqsEJoeW4hq/wIAAAD1BqDbcPwKAyAy +AlFwWWgvKzxB/AoDIDoCUXBZaCuDHfcKACIAAFlw/G0BIgAAULD+UAcgDhBoMP5WASFAAmMwWQVE +H2rnGmroGGrmHWrnl6+Xrpetl6yXq5eql6mXqJenl6aXpZekl6OXovemASIAAFjw96YAIAQQcDD+ +hj8sCQBtMP2GPiAGEGAw/4WAIBQCUrBZaA0YataKGSiCfxtq0vwKBCAFEGgwC4AA2iBYEhPRD/4S +FCIAAFMw/xIYIgAAYXBY7YPRDwAAAPP9g2AAEFgwKhITLBIR/RISIgAAWPBY8LnRDymhIbGZKaUh +Y/tlAABlOtf3EhAgABAgMPAAHGALEGgwAIM5zzwrcAH0tAgACxBoMPe3CgoARikQLHAAfcnmZGqm +iWrznAAP3gA2YPkWBSASAnnw/xYHIBgCcfD+FgYgBAIR8Nog/AoGINgCWPBY7Idlr62KF/wKAyCQ +AljwWOyDZa+dihb8CgYggAJY8Fjsf2WvjYgVc4FiKYAFwqx6mYT6PAAAARBYMFjx8dowWPGu2jD7 +ClEgABBgMFjsGGP/ZItni74qsRyxqiq1HNEPAAAAAAAAAPP87WAAEFgw+iwAABwQWDD8CgEgDhBo +MFgg6RtqMPP8tWAwEHgw2mBY8qVj/yGKHluIDRxpbAutEQ8CAPSgO2wAIGswDeowK8KFK7IAsKrT +D/oWCioAIG7wWXMLHGogjRoqwjDw0QQAARBYMAC7GguqAirGMFlzP2P9zJwc+goHIAEQWDBYFzyP +HC7yfy72g2P9tABsEAgZajIrMQonMET9MgQgIhBwMP8wRSIAAGCw+goAIgAAETD0aesccAFsMPD2 +EQAOAOPwev90jDL/AgAAAWI3EP8CAAABXjMQG2j8iDMrsqQvkmGriAmIEfoWAC4AIEfwLxYBZHL0 +HGnTDGwBdMk1KjA8aKEy/wIAAgERBqBopVf/AgAGAReGoH6hHMLTfakX+hIBIgAAWPD8LAACAABp +cFkDzdEPeWYa0Q8AGGjWLzEn/wIABgBlx9CaEGP/pAAAAAAA+hIBIgAAWPD8LAACAABpcFgC29EP +jREp0AXEpnqZxYnXK5kUZLHgi5kv0GgZadIssAf6sBUgAgJ78P/UaCABEHAw/tRcIAgQQDAo1Gco +1GT51SogABBAMCjUZijUZf4wTiAtEEgw/zBPKiQBUDD41TUhpAJSsPjuEQAuEEAw+pg4DgkAe7D4 +1FcgQRB4MC/UdC7VNy6wFf5uFAADEFAwfqAFKbAUKdRg/jIVIgAAU3D/MhYiAABpcFv5odEPLzA8 +aPZhfvFemhD+0TcgeAJI8PAJFgC4AkNwAEhh/zEmILoCW3D/1TYgEAJQcP7VNyADEGAwWWcxixHA +w/q8XSDCAlrwWWctihErHAgPAgD6rGEgAxBgMFlnKP4KIi6HALXgYAF0AAAvwAT/AgAGAHYD4Bpp +7A3cCQzMEayqKqJ/ZK6jjDb7DUsNCAFgMC+hGQ8PS3/ZDouqyLkosT98gQuLuWW/9IqpZa/i0Q+K +upsU+hYAICsANqArPEGbEyqsTvsSAyADEGAwWQdV/goiIIMANqCKEIqo+hYAL+IAtqCLFGS+Qh1p +mS3RfvwwPCAOAHtwaMZ8fsFtjRQt0QiKFPw8AAAIAlhw/goAIgAAeXBYAwiNEWXe8mP+DPoSASIA +AFjw/CwAAgAAaXBZA0rRDwAAAPoSASIAAFjw/CwAAgAAaXBb+xnRDwAAAPP+HWAAEFgwjxCfFGP/ +hQCaEJwR8/6oYgAAazB9147z/5Bj/xBoMAAosAT/AgAF/74CINEPGWly0w8pkX7/AgAB/s56UPoW +ACBAAmDw+twAAgAAaHBZB+f9rAAASQC2oCowPCsKgf8CAA/+udqQihBkrWnbMP0WASIAAGCw/VwA +AIQQcDBZBx7RDwAAAAAAAPoSASIAAFjw/CwAAgAAaXBZBfbRD5oR8/ztYCIQcDAAbBAIKDAAKjEP +8xYFIHkQSDD8MQEgtgRKMP4SBSPzALagLeAsLuAt9mlyHYAEP2D3aCQcCQB3cCvd+P9pfBBGADbg ++Gf6FgEdf1D5aXkWAJ3HUPppGhYBIU9Q+2knFgEpV1D/AgAGAQFfUMAg0Q8AAHDPpcCl/GlvEDIQ +WDBZbvLAINEPgxUPAgCDNPxiBCJwARww/TcJcgAAcPDH6w4+AfMKAC/GADcgYAAGjGSxM3w7tyty +qypi+g8CAKs7CbsRC6oIL6ILePbjLKA5fOnbKhYE+hYAIaoAp/AuFgZZN67+EgYvxwA2oI0VjdR5 +1i2LFYoUK7EKWOAwjhaNFP8KASAAEEAw+vg4AAAQYDD4/DgMBQBWsP0WAC+SADcgjBUswDf/AgAA +AQ6HIP8CAAYAzQMgwdH/AgAP/5lrEI8VLvBCL/BDCO4R/wpDLgkAe7D/AgAP/4v7kIkVKJBEKZBF +CIgR+QpEKAkASjD/AgAP/35KEPsSBSIAAFCw/EwAAgAAaXBY38bAINEPiRUbaHqMZIOU/EgRAAAQ +EDD5kDQhwAJCMPTOxGJwARwwmRGbEpgTYAALjGSxIv8CAAv/V+CQKHKrJWL6qCgJiBGoVYpb1FD5 +UDkhwgAisHk513mu1NpQWTdtZK/MihWKpHmmQooVKqEK+hYCK2ABUDD7Z60SABkioHqyKvsSAiIA +AFFwWN/q/QoBIAAQcDD63jgAABBgMP7cOAIAACFw9M+HZAUAUrCLFSqwMiuwM/8SAyuABDqgC6oC +KKw2/wIAC/+0x9CNEf8qIyIAAGKw9ND4YiIQEDBgAKsAAAAAAPsSBSIAAFCw/EwAAgAAaXBb/KrA +INEPAPsSBSIAAFCw/EwAAgAAaXBb+6PAINEPAPsSBSIAAFCw/EwAAgAAaXBZB4DAINEPAPsSBSIA +AFCw/EwAAgAAaXBb/nDAINEPAI4VLeAuLOAwLuAxDQ1D+MwRDeAEP2D+zAIM4AFsMP8CAAv+wGNQ +/cgMABMQeDD/AgAL/rhD0IsV+hIAIEACWvBY3svAINEP/wIABgBKg2DBkf8CAAYAVc9Qw9aKEcO6 +/wIAD/6f2pCLFdpA/hICIEACWvBb89XAINEPAIsV+hIAIEACWvBb9bDAINEPjhUs4Fcu4Fb+FgEt +0AQ7IPzMCCB8Amsw/KwMBnQAO6DBkXnpqYoVraoroCAuoCEIuxEOuwL/AgAP/m760CugIi6gIwi7 +EQ67Av8CAA/+ZJLQYABNw9bB4/8CAAv+XWOQixXaQPu8ICIAAGNwWN1kwCDRDwCOFS3gVi7gVwjd +EQ7dAv8CAA/+SHtQiBUvgFgogFkI/xEI/wL/AgAP/j0T0MPWixX93AgiAABRMP4SAiBAAlrwW/Il +wCDRDwAdaIou0X4s0kD61X8uCQBTsP7VfiACAmMw/NZAIAAQEDDRDwBsEAQZZ1EoMAEJiAooghD6 +LAACAABhMP1cAAIAAFjwC4AAwCDRDwAAbBAGLDAHHmbaGGbB/eCALCABYDAMxRGoVfhSOiBuAmtw +DU0UuN3/AgAKAGNuEBhmuS9SOQjICiiCl/j7AQ4AWUfQ8Q4HAgAASvAASWEASWEASWEASWEASWEZ +aGH/aAoQARBgMPoiACAAEEAw+BYBIAAQaDD/FgAgAxBwMPkWAiAAEHgwWBWHLjEHH2atDg5K/WhV +H8AEO6D/ZqweCQB7sJ6g/CIAIBAQQDCYo/+mAiACEFgw+MkRDAkAazD8pgQoCQBecPmmASABEGAw +LKQZwOUuVjmLMsDXLSQE/DR4KgkAZvCbMolEx6cKmQGZRNEPjzLI8NEPK8wY+jwAAAEQYDBYHpTR +DwAAbBAIFmaBG2aZLiAHKGJK/g5BAAEQIDD7sn8iAQA2ICpiSQuqAfusAAH+ADagHWaOLdCADOoR +pqr8ojogbgJrcA1NFC3cFv8CAAoA+W8QHGZvKqI5DOwKLMKXDKoB+hYEIegANqCMJ8CQKSR2KMkU +KiAU98IJIY4ANiCMcQqsh/okFCwA8hKgH2cOLXEXHmgUhXOKeirmefWEFAAAEEAw+OZ4JIAEPWAl +5n/05n4sCQB/cC3mhf39EwG4AiOw/eaEIKgCK7CLFChCgoowLkJ/LUKEL0KDKUKBmRH9FgAgARBg +MPgWAiAAEGgwWBUsJEwY+hYEIaIIKTCIdIwn9SEHIBAQSDD9ZygYCQBKMP/JFCAAEEgw+HYEJUAB +LDD0IAclwAQ9YPsyACDkADfgg8mINMfI/jEXKABAYjD4NgQrQAQ+4PwgLCYCASQw9ARBBqAEPeD3 +ZkMUCQA9cPBPEQoJAF8w+2Y3GAkAWjD4NgQkCQA9cPWmAC4JAHuw/CIALgkAa7CepJml+6YCIIAC +OrD9pgYiAABY8PmmByAEEGgw+MwRADAQSDD5pgMsCQBrMPymASBAAkqwAguGAEljAAuGAElhhTIl +JhyJMf8CAAIAUYZQ9pC8YAAQGDDAs/oiByAAEGAw/E8RAAMQaDD2/wgAJgJw8P72OSBAAlKwWBHc +0qDRDwAA8/5yYgAAOnDAMPP/HGAAEEgwAAAAAAAA8/4FYAAQUDAAAACIImSAf/QkdiAAEBAw0Q8A +AAAAAADz/h1gABBQMAAAAAAAiSJln90r7Bj6LAAAARBgMFgd/PQkdiAAEBAw0Q8A2iBbgCpj/hcA +2iD7fAACAABhcFuBlIkx+hYFK8AEOqCqd/MSBSH/pjJg+3wAAgAAULD8CgAiAABpcFuBZPP/MWIA +IB6w+iwAABwQWDD8TAAAARBoMFgd4/QkdiAAEBAw0Q8AAABsEASGMMSC+QqEID4QODD2hlcAMBAg +MPRhPXAzEFAw9qIJcDcQYDDDsXtqCvbCOXA1EGgwfWIxIiAFdyFK+CFHcD0QcDD/CoUgQARwsP81 +CCABEBAw0Q8AIiAFdyEO+CELcC0QIDB0IQPAINEPKDAw+zr/JeoAPiAqMQj7oRNwARAQMCk1CNEP ++TUIIAEQEDDRD8Ah0Q8AAGwQBi8wPC4gBysxC4Yu/SIAKiABcDD8vMQgANIH4BdnGvQWACYA3Jvg +L3JhCWgR92WdHgAgR/Ao8AX8phEAPRBIMPe8EyYAIDmw90cUDgDcShApYjp3kxMZZZQoYjkJqQop +kpf5hAEIAD5KEIsiZLE2BQxH/wIAAgCWGyCKJ4uo/aEVL8AQEDD/ogsgQAJysALiAfipFCwAIBdw +/dxAJgC7X9CPEAz/Ea+I+KUUKgAgevD/AgAKALVXUIgQyTj5vAAAFgA2IG2JBQADhgBJYSriAA8C +AA+qCP8CAAYAxm6QmuDRDyUhB/nxCC2ABD9g+SUIIAYCQvD4SBQB6AJa8PtGAygJAENwmEn32wIP +4RBAMPtGAS0ABD6g+EQYK0ABKDD4ZW4bwAQ6oP7yHyoCAXQw/kYLKqAEPuD7ZXAaCQBasB5l+iXy +HvVGCiwJAG5w/EUPIAAQSDCZRZhCH2cJ+6oCAKgCWPD6RgAsCQB3cP1GBC4JAH8w/0YIIIACUTBZ +ZC6KJyv6wPdmOSBAAkqw+woAKABAXnD7pRQggAJKcJmpmajRD9EPAAD7rBgiAABp8PwKASIAAFCw +WB1LY/6yjSf++sAgQAJjcP4KACwAQHMw/tUUIIACYzCc2ZzY0Q/Cgnj52ilxfn2X1Ps8AAIAAGEw ++jr/IgAAaXD6JQgiAABQsFjwatEPxbX7JAUiAABQsFgOFdEPwMCcq9EPAAAAAAD73QwANgA04CgS +AA1JFCqcCPo8AAgDAFIwbYkFAgqGAEtjixAqLEDTD/m7DAgAIGzwbbkFBAmGAEplDfwMrCwszECc +4NEPAAAtLECd4NEPAGwQEt1w/RYSIAAQSDCZEJkRKCAHhUD5NgAiAABZMPdAByIgAUQw9GG+ZPgB +LDD6YgAmAM8BYCwgBCoVBP0KMCQA/wMgLiB8/hUFJgDq7VDA0Rtk+Aw6EauqKKI6jBD7EgEkAaNC +IBhk9C6iOQg4CiiCl8KY+OUBDgCER5AuIQcYZPn9FhQvQAFwMPwWFS/ABDug+xYWLgkAQ7CeUI4g +GGTz+FYCIAQQQDD5VgMpgAQ/oPgRBSgJAEZwmVEpIAQqFhcIiAn8iBEIAMyCYB5mkqju/uF/JACd +hmAoIhIoFhEpIEwpFhAZZowJOQIAhAQpVgQYZookFhj7/1AFFwFgMP9WBigAQELw/2aGGfAEOiD8 +eBQECQBBMCRWB/8SESgAQHow9BIQKAkAajD4VQopwAQ7oChWCP9EGA6ABD/g9FYMIAEQIDD0Znce +CQAn8CgRBP9WDS/gBDzg+FULLgkAJ/AvVgkoIAcIKED/ev8oYAQ6IA+IAihWCyQKBCSmOSQSGP9m +ahHfADVgAzoJ/WZoG8AEOqD7ZK8YACB+sCySf/IiACAQAkGw+MYAKgAgbvD8ZgMqACBasPpmAiOA +BDig+JZ/IgkAEfDyRgEgABAQMNEPHGTgK0En9UwABgCVZtDz/m9gABBoMAAA+0wAAgAAULBbh5v2 +rAAByQA2oC2pFPSiCSEmADdg8/4kYgAAWTAAACkiEykWESggUCgWEGP+xQAqsBj1vAACAGb+kCtc +HfwKAyAIAlBwWWNkY/4SAADaEPwKAyCiAliwWWNftBr8CgMgnAJYsFljXCsgVSsVBWP97R9mMx1k +8ykhF/gKACAgAlBwmKCYoZiimKOYpJilmKaYpy3Sf5iomKn97QwMSAFIMPnMEQwJAH9w+QhGCAcB +TDD9FhMpAAQ+YPwKASgJAGIw/BYEKAkASjD4FgYggAJYcFgL5GWgfhxmG/0SECAFEFAw/hIRIDIQ +WDBZa40qEhcrEhYsEhUtEhQpEhPz/ftgABBwMNoQ/AoDIDICWvBZYzJj/yYpIAT6FQQkAHEGYGiU +HStcQfwKAyAIAlBwWWMqY/66AAAAAADz/tpgABAgMNoQ/AoDIKICWLBZYyMpIFUpFQVj/8vApfxl +/BAyEFgwWWtvwKX8ZfkQMhBYMFlrbB9l8htl9wM6CSwSEgyqEf+pCAoAIFqw+MM1YBACWbAskoGb +wJxjmmIrloEqkoKNosvRjiAI7hEOfgL+RgEgABAQMNEPAAAAAPP91GAAECgwL5KAm/GaY59iK5aA +Y//LACIKiNEPK6AH+wtBAAEQYDD7vBggBBBoMFgcJ4wgCMwRDHwC/EYBIAAQEDDRD9oQ/AoDIJAC +WLBZYvQtIHwtFQVj/w4AbBAGGGQr9UwAAEACSPD1FgAgkAJQ8PAIBwCcAiDwAElhAElhAElhAElh +AElhAElhKSAEiCD3LFEkAHGGYBVkdS0iFiVSfwnWEf8hIiQAIDVwjFguUHwtNg0swAT4Ng4gnAIw +sP81IiAcEGgw/jRBJgBGbxD8CgYg5AJZcFli0dpA/AoGINgCWXBZYs71EgAgABAgMNtw/AoDIMIC +UPBZYsnbYPwKAyC6AlDwWWLGiSmZO/Q2DCAGADZgk5yTKS4gDS0hBywhCSsgByogFi8gDC80DC40 +DS01ByU1CCw1CSs0Byo0FvQ2AiAGEEgw+TQEIE8QQDAoNAXRDwAA9RIAIgAAWbBZBVr6TAACAABZ +8FkFWPP/fmAAECAwAAAbZRKMICggfCkhKSk1Ipw9+DRBIAYQYDD7Ng4g5AJYsFliodpA/AoGINgC +WLBZYp6JK/k2CyAAECAw9DYMIAYANmCTnJMrY/9YAAAAbBAIjDUZZW76ZXQZaAFgMAiICftjtBnA +BDogqooqon/+vR0oACBO8PmICAAAEFgw/a3/JgF7xpCPoSipEIegl/AmogAoFgQvZgEWY+/7pgEg +ARBIMPumACP/EDgw/uIDIMkANiAkogcvQgMlQgEjQgD7QgIgABBAMPWHFATgASww/5g4AvgBHDD3 +CgAmAEAx8PuXOAeQBDmg9uYIDgBsxdD5Ov8mAGiA4ChBCP8CAAYAY04Q99F9KuABZDD0snRh8AJy +sBxjxPj6wCAwAnqw+AoALgBAR/D41ZAggAJ78C/WR//WRioCA3cQG2OSL7J9HmO6mvEu1kEssn0s +1kApsn/6tn0gAgJKcCm2fxpkx/t8AAAAEGAw+qLGIAEQaDBYDs3AINEPAAAAAIWxBYgU+LIDJgBA +MjCEsvMKASAAEEgw+Dk4AAAQQDAEODiDsPUFRweQBDmg9LwABgAgM7Dzg1cOAApOEGg2DMCQKZEI +/wIAD/+hOlAZZRn30X0q4AFkMPWyMGHwAnKw/wIABgBLgOAsQQiPIP/WPiIAAFGw/iYHIgAAWLBb +/zyIIPcWBSIAAFHw/QpCID4QYDD4iBEAPRBwMPhYAgAwEHgw+EYBIDEQWDD3JQkmAHaA4P8xWnAz +EDgwc3IdezIaK2AF+iU2JgDSZtD/AgAGAM5u0P8CAA4BZnLQGGO1CDgKKIIQ+iwAAgAAWTD8XAAA +AhBoMAuAAMAg0Q8qkRr/AgAB/7N2kPP/YWP/EGAwAAAoYAT6JTYkAJACIIpACopXf6FAenICe6oJ +w7d6sqzD9X+ipypgBQ8CAA8CAHyhS32hSH6hlSgKhShFCPosAAIAAFkw/FwAAAIQaDBZBKzAINEP +AAAqYAV8oQx9oQnCnf8CAA//tEqQKkAw/wIABf+uhqArQQgsOv98sb8tCoQtRQhj/7YAAAAAAAAA +9yU3ILgCULD8ChAgeAJZMFlh4bQa/kEmIAMQYDD+JTYgugIYsPclNyIAAFjwWWHaKSBhKCBiKDQB ++TQAIAgCWHD/IGMgAxBgMP80AiDCAlCwWWHR+iwAAgAAWTD8XAAAAhBoMFv9PsAg0Q8AAAAAAPwi +ACIAAFGw/NY+IgAAWLD+Jgcj/xBgMFv+0vclCSIAAFCwWAvNwCDRDwAAKkwZ/AoDIKICWbBZYbwq +TB38CgMgnAJZsFlhuPsKMSA+EGAw/QpCID0QcDDz/rRgMBB4MPosAAIAAFkw/QqEIgAAYXD9RQgg +AhBoMFkEYsAg0Q8AABlkHI8UK9GR+xYCI8AEOWAC9Awpkvz5FgMvwBBAMPhPMgAwAmKw9NJHLABA +QzD/FgQqACBm8P/VkCCAAlrw/0wACgCW2RDLJK8k/wIACgCpJtDZ8P8SAyAbADVgbVkFAAmGAE9h +JNJHL9mQ/xYEJAAgILD/AgAGALXdECTWR4gUDwIAZIDVGWLm/wIACgB29lAcYrsown0fYuMqhgEv +1kEuwn0u1kArwn/6xn0gAgJa8CvGf/psAAIAAFhw/BIDIAAQaDD+CgAgAhB4MFv9hP0KiCngAVQw +fZkeaDYbKhID0w8qoQgrOv97oQ0GagL7EgMiAABhcFkFHhpkS/t8AAAAEGAw+qLyIAEQaDBYDeTA +INEPAAAAAPosAAIAAGFw+wqFIAIQaDD7RQgiAABZMFkEFMAg0Q8AHmKSKeKAKO0CmpEo1kEv4oAv +1kAs4oL65oAgAgJjMCzmgmP7+sDw/9WQIIACWzAr1kcr1kZj/xaPEg9PDC/WR2P+yxligS6SgCyd +AprhLNZBK5KAK9ZAKJKC+paAIAICQjAoloJj/xQAiRMPtAwESxRtuQUCD4YASWOPEynMQNMP+1gM +DgAgJ/BtiQUECYYAT2UEKAz52ZAoACBDMPkWBCCAAkIwKNZHY/6bKcxAKdZHY/6SbBAEijX8Yp0Y +NAFUMPtkDBErADZg/wIAAAC1hmD/AgACAIGCYCjCs/8CAAIATZ5g9bKHKWgBVDAJiAgJiBEIVQgo +UgIp+v76CkcIAEBKMPhWAiBZADag+KNzYBYQWDB7qUkpUgcsmRQjkglkwI0vMgT8Y/QQBRBQMP0x +CiAQEEAw/jIKLgkAR/D/NgQgLhBYMFlpXPpcAAIAAFjw/DAHIAUQaDBYAgDAINEPAPJWGSIAAFFw +9SYIIgAAWLBb+5iLKMiiibLLm8Ag0Q8AAACJV8CxK1R4KpkUwDDzVhkgBgA2oIOZ+lwAAAMQaDD8 +MAciAABY8FgB7GP/xAAA8/9uYAAQGDAssAfasPwLQQIAAGkw+7wYIAEQYDBYGhTAINEPAAAAAPos +AAIAAFjw/EwAAgAAaXBb/krAINEPACjCs/WyhyloAVQwqYgJiBGoVYlXHmKojDQtmRT00EBsAEBz +MIuZKrQbnLcsUAb8zP8iAABRcPxUBiABEFgwW36vwCDRDwAAAPosAAIAAFjw/EwAAgAAaXBZBLvA +INEPAPP/wmAAEFgwbBBKGWIbLCAHJRaGhzD1TP8o4AEoMPwMQQIAADFw+XcBAgCRAiCJIhhh1/WR +t2AGAmlwGWHt/MoRBgUAO3D9YdIaACBCsCoWh/qiOiAGAlmwKxaFDc0K/dKXKgDm3pArEocrsjkN +uwH7FoQhnAA24C6CSmTheSmSfy+CSfn7AQ4AuE/QKiAUCqSH+iQULADJEqD4PBAgKgA9IPpM/yIA +AEhwbakFAAiGAElhIhaA+h0CIgAAWHBZX1XYoPoWiCD+ADagwKP7HAACAABiMFlnzsl8+xKEIgAA +ULD9bAAAEAJg8FgQcPAAB2IAAFqwAAAA+EEXYgAAQHD6TP8iAABK8NMPbakFAAiGAElhjTP8XBEC +AABQsPwyAioAIGbwWBAmLBKHiif7EoUiAABpMPvGOSBAAlKw+0wAAAAQYDBYDWrSoNEPiieLqP2h +FS/AEHgw+aILIEACcrD+FoMuAEB7sP4WgSwAIHdw/dxAJgBiXlApqRQMSBGomfmlFCoAIFow+BaC +KgBeV1DJPMlK2bBtSQUAA4YASWEqEoMuEoIqogD+qggCAAAxcP8CAAYAdm6QLRKDmtDz/m1iAAAa +8IgQGWK/0w/9EoYo+AFAMAmICiiC7CoSgPwQByIAAFhwC4AAKBKIY/7cwCDRDwAAAAAAAPosAAAc +EFgw/AoAIAEQaDBYGXHAINEPAPvMGCIAAFCw/RKFIAAQYDBYGWvAINEPANogW3ubY/5p8/48YAAQ +WDDAsJur8/3uYgAAGnAAAAAA+9oMADoANOAKTxT9/AgiAABA8P1NNgIAAErw0w9t2QUACIYASWEp +EoGqONMP/04MAIACSnBt6QUCCIYASWMuEoItEoEK7gz+EoMsACB3cC3cQJ3gY/8dAC8SgSgSgy/8 +QJ+AY/8OAABsEAYoIHL6IAUgABAgMPkKCC/AEDAw+YgCABQQKDD4JHImAG2ukPdiLRASEBgw+jMy +cAsQKDBzoXHzCgkqAMSGoHWhcf8CAAgAQwag/wIABgDYnpDAufujBn/1EBAw0Q/SQNEP2iBYoLb6 +LAAAABBYMFgRrCwgcv8CAAIBCoMgHmFsjyAjJAUu4qYtcpuv7gnuEa7dj9cu/CAG7gH09RQggAJz +sJ75nvgk1AWPImTxYiogBWP/nYgiZY+YAioCW7LGZa/rwJr5JAUgChBQMIsiZb+A2iBbsp1lr9Qu +IAaMIiMkBf7sASABEGgw/iQGLAkAazCcIvP/W2AJEFAwiScomRTAsP6cICBgAnpw/ZIJIdAANiCD +8P83DAGQAhjw9zs5AgBAN7D3ChYgZgA3YIjg0w99gVos0AD5ChUmAF+vEP8CAAYAW88Q+AoYJgBX +vxD5ChkmAFPHEPgKGiYAT88Q/wIABgBLxxAs0Acp4QWZEPOZCA3ABDsg/N0IAIACSnD52zlyAABj +cP3MAA+iALcg/QotIBwANuAssAB9wVyOvsCw/vgMAZACc7AI6zllv+cvIE7cQPAAQmwFAHnwjBAM +3Axj/8IAjSJl3ojaIFuyqmWu3C8gBv4iAiAMEEAwKCQF//wBIAEQQDD/JAYuCQBDsJ4i8/5dYAwQ +UDAsJHFj/iSJImWeTcCoKiQF8/5FYAgQUDATYLIPAgArMkr/AgAKAGQu0C1yZCwySf3LAQ4AXW8Q +AioC/CEJIAAQaDD/Cv8gABBwMFigDvwhIyAAEGgw/goBIgAAWrD/CgIiAABQsFigByU2SS8gBv4i +AiAREEAwKCQF//wBIAEQQDD/JAYuCQBDsJ4i8/3KYBEQUDAAACogBxxgoysgIvQkIiogAVAwDKoJ +KaHeq5kppd4pICJkkEsvwnuLK/DxBAH+AnJw8O4aAAEQaDAA3Rr93P8qACB28A27ApsqY/2kAAAA +AAAA8/4wYgAAaTD6LAAAHBBYMPwKASAGEGgwWBiJY/2xiCmYKmP9eQAAAGwQBIoix436KVMAFgB6 +sAioAZgi0Q/InllnlNug/CICIgAAULBZZMfRDwAAbBAEiSf4kgwgIxAoMPYKJCAlEDgw8pwwIAAQ +WDDyiQwBkAJCMPmLOQApEBgw9AorIEMANuBgABQAir7AsA8CAPosDAGQAlKwDKs5yrUssABzyeUt +sBD6sB8hvggjcHWhBXahAnep0dogWBcs8//bYgAAWrDRDwAAbBAE9CIHL8AQQDAlTCD4VQEAABAY +MPNFFCCAAilwlUmVSNEPbBAEKCBw0w98hxQqIAf7IgAqAgFQMFkDosin0qDRDwDAINEPKyBwLAr3 +DLsB+yRwIgAAErDRDwBsEAQVYE8iUn/2CgAgJAA0oCJSfYQhiSCZQIgglIGWIZYgI1J/sDPzVn8h +8AIQsNEPIlKAhCGJIJlAiCCUgZYgliEjUoKwM/NWgiHwAhCw0Q8AAABsEBCHOYo49iAHKOABKDD5 ++gAvwBAoMPmqAQYAQE3w9gZBAgBJmiCNJ4zYK9EV/9ILIEACc3D15QEAABBAMPnZFCoAIC7w+7xA +IB4IY/CY2/AAYmIAABvwAAxPEa+Z+dUULAAgZ/D8uQwKAOlq0Ps8AAA4ADTgCUgU+BYSIBACQjD4 +SDYCAABrMG2JBQALhgBNYSgSEqk70w/4SAwAgAJpcG2JBQILhgBNYwn7DKtbK7xAm+DTwIsiyLLA +INEPjDQdYOz+YO8QBBB4MPVf7RAAou8QHGGz+AoAJcAEOaD4JhkkACApMChCOi0xCy8xCvzAfyQB +wsIgGGDeKUI5CGgKKIKvHl/t+JUBDgBzxlApIQcbX+cJCUoMmRELmQKZUIsgLBYU/lYCICgQQDD4 +uREABBBwMPhWAygJAHZwmVEpIAQqFhUN2An8iBEIAVSCYBthhKi7+7F/JAG4BmAtIhKdHSkgTJkc +HWF/DW0CAIQEHmF+nVT6eVgIHwE4MPhWBi4AQHHw+GF6H/AEO6D6fhQICQB2cJlX+BINLgBAQ7D/ +VQsuCQBzMC5VCv4SDCvABD7gm1j4iRAAARBYMPthbRgJAF5wmV347hgJ4AQ9oP5WDCgJAF5wmVko +IAcIKED5ev8oYAQ6IAmIAphbwOQuRjmLImRSg4g0xp/5iAEAARB4MPg2BC4JAH7w/yYCIAAQEDDR +DwAA/wIAAgFAcxArIHb4IHcgQQA24PsiGSIAAFCwW/kS0qDRDwAAAAAAAPnMAAAUADTgyExtSQUE +A4YASWWN4A/dCP8CAA4BHVtQL1xAn+Bj/k9ljlIpIHhknkwqUkpkowAo4mQrUkkIuwFksvQq7QQq +oIAMZxGld/lyOiBuAlKwCkoUt6r6FhAqAWDWUChyOQ1pCimSr/mKAQ4BWE4QLSAUmh4N1If9JBQs +AWgTYC4iGWTiQsCI/MkUCAkAQzD4NgQgABBYMMDQLSR4jDD9JhkgAPkrEIwnLskUZOI0hMmIRCch +B/MgBy/4EGAw/UIBKABAYjD4RgQpQAQ+YPwgLCuABD7g/kEXJ0ABPDD8dxEKCQBfcP1gPRgJAE8w ++YkCCAIBGDD7RgEooAQ6IPhfZhYJAEXwG19c+UYEIiABHDDwNhEGCQBF8PemAC4JADOw/CIALgkA +a7D+pgQgMBBIMPmmAyACEEAw+6YCIgAASTD9pgYgABBoMP2mBS2ABDsg/aYHLAkAezD8pgEgQAJa +sG2KBQYJhgBLZ4ZCJiYciUH3rEAiAPQGUC4KAP4WDyAA/i5g/hIPIAMQWDD6IgcgABBgMPw/EQAD +EGgw9f8IAAgCc7D+9jkgQAJSsFgK/dKg0Q8AGWDiLxYTGGAh/SEXIAAQcDCeEZ4TnhSeFZ4Wnhco +goueGP4WCSIAAFBw+LgMAAEQeDD9DEYICQBKMPgWES5IAWgw/X1AD5AEO6Dw3REMCQBzMP8WACwJ +AGsw/BYCIGACWHBYBpJkoNHApfxgyRAyEFgwWWY9wKX8YMcQMhBYMFlmOosiZbw++2wYIgAAULD8 +CgEgBBBoMFgXDsAg0Q+d4GP8HAAbX08rsqQq4psMzBSsuwm7EfuqCAIAAGkw+iYZIgAAYPDypggi +AABYsFv4K8Ag0Q8uIhOeHS0gUJ0cY/yQhTIlJhyJMZoe+6wAAgB7BlD2kQ9gABAYMIon20D8CgAi +AABpMPN2OSBAAlKwWAq40qDRD8GwC8sC+zYEIAAQSDDz/b5giBBYMAAAAAAAAPP9yWAAECAwAAAc +YJT9EgwgBRBQMP4SDSAyEFgwWWYGKhIVLBIULxITLRIR8/wYYAAQWDAAAAAA+2wYIgAAULD9EhAg +ARBgMFgW1cAg0Q8A+iwAABwQWDD8CgEgARBoMFgWz8Ag0Q8A2iBbeP+KHow08/0nYAQQeDDaIPt8 +AAIAAGGwW3pniUH6Fg8twAQ6oPeeDGYAIGXw+3wAAgAAULD8CgAiAABpsFt6N40fra2dH2P969og ++xIOIgAAYXBbeliLHokx86wADcAEOqD3nvlqACBm8Nog/AoAIgAAaXBbeirz/uRiACAesAAAbBAG +GWBkKiAF+CAHIgAAcPD2CgAiAABZcPwiByADECgw9KC/aCABQDALCkf9zDAiAHgCoBlejwyHEf9e +zhYAIE3wKXI6/48KBAEALTD/8n8qAKsuUC1yOf/ZAQ4Apf9QKCAHHF6ZCCtACrsQDLsCm5CGIPte +jReABDmg+5YCJgkAMXD2lgEuAKyhUCwwA/yWAyAgAkpw/wIAAgC9mqD+PBAgKgA9IPpM/yIAAEOw +bakFAAiGAElhwDD8YDcQBRBQMP0iACAoEFgwWWWgJXY5LiAE/yAFIAkAt6DM8WQwgtIw0Q8A+pL0 +L0EAtyBkodQqkvKNoYygnNCPoJ3xlqGWoCyS9LDMLJb0L63/jSD99j4h8AJisJwnJiQgJiQhY/8I +h8zAkP1/DAGQAjnwD3k59worLwEANmBgABGPnsCQ/9YMAZACe/AG+TlknucmkAB3aedknt5tSQUA +A4YASWHAINEPiScaXob7CgAv/xBgMPyWACAQAkJw+yYHKgCQzpAeYAUq4vISXn6YoZKTL+Lyn5It +4vT45vIgAgJrcP3m9CIAABDw0Q8AiiLA3nrQEI7C+BYBISwAt6DH8Q+qAZoimBH7FgAgvwA2oPos +AAIAAFjw/RIAIgAAYTBYFOXSoNEPG184LyEI/QogLCABQDD9lgMtAAQ7IPwKAC4JAGfwnJX7X+ce +CQBf8J+Um5bz/oZgQAJKcACLJ4q8jKGPoJ/AjaD81gEgABBoMP2mACBgAlrw/aYBIbACQrBtSQUA +CIYASWEWXk4orMj/AgAKAFhFkBxf0SjC+B9f0pqBn6EtwvidoCnC+vrG+CACAkpwKcb6ibDAMPua +DAGQAkpw8/45YgUAVnD6LAAAABBgMPuMGCIAAGlwWBYHY/8uAAAdX74i0vUfX8CYIZ+TLtL1npIs +0vf41vUgAgJjMPzW9yIAABDw0Q8AKpL1jaGMoJzQj6Cd8ZaglqEskvewzCyW92P+J5sQWWUJ26D8 +IgIiAABQsFgQiYsQiBGKImP+wwAfX6Ys8vsZX6mawZmhKPL7mKAt8v369vsgAgJrcC32/WP/UABs +EASKKImnKJkU+5IJIDYANiD5ogIgABBoMC0kBP0kBS/+EGAw8qYZKABAZnCZovywByADEGgwW/2m +0qDRDwAAAAAAAPP/ymAAEFgwbBAGKCAEw+L9Ci0gGBBQMPwKKyYBUgYg9QdHBgBwVhD/AgACAJcB +4CswEP8CAAYCSObQ/wIABgJs7tD2CiYmAMz20P8CAAYBELbQKSAH+QhBAgCyAeCKIvxdqxAAEFgw ++xYAIAMQaDD1pCRrwAQ+IP9d5hoAIGbwLLI6/48KDAEAbTD/8n8qAf5vEC6yOQksQArMEP/qAQ4B +9f+QHl2wDswCnKCGICmsEPxdpBeABDmg/KYCJgkAM3D2pgEuAjGjUC4wA56j/F3SEgJFmeD4PBAg +IAA9ICpM/22pBQAIhgBJYcCALbY5LyAE+SAFIAoAt+BlkAJkhP3SgNEPhzL4Ihgm+AE8MPsKASYA +62XQjyL6Xc8f/RBIMPmCCi4AQE/wKyQF/yYCKAkAVnCZiooiZKHRHF6EK4IRDLsCK4YRjSJk0k8F +Dkf/AgACATMDoMAg0Q8vIA2IMvX0Zmr4AUQwiSdklFwaXYgZXzb4xFMCAAB48PAKBwAQAkDw8Amg +AcACGnDxDxYCAABQ8PIaHgAgAkjwbUkFAAiIAAmK/18qGdAEOSC/hAREFPj0eyACAiEwJPR/Y/50 +hieKbCZsMP8CAAf/SraQK6zIZL6KwNGdEGACvQAAAAAAAP8CAAP/N5ngKCAiZIBFLSAHGl1XwOD+ +JCIsIAFsMArdCSzR3qjMLNXeKCAiZIQwLKJ7jyvwwQQB/gJaMPC7GgABEEgwAJka+Zz/LgAgX/AJ +/wKfKiggIC0gBcCUCYgC+CQgI/8IG2AICkP/AgAL/wKaoIonwLD7JCAgIAJSsFgK58DALCQULCQF +Y/3mAAAAAP8CAAP+75ngjSdk0AoCKgJb++vaIFv83ikgBfgKCCFBADZgLiAgCOgC+CQgI/7bGmAI +D0P/AgAL/tWb4IonwLD7JCAgIAJSsFgK0GP/ogAA+iwAAgAAWPD8TAACAABpcFv/Otyg+iIIIHQA +tyCNomTQasAg0Q8AACkwF8Lz/wIAB/8iflDCZf8CAAf/HTZQwqT/AgAP/wjSUGP+KMK2e3FWfHFT +/wIABgB4bdD/AgAGAIB10AUMR/8CAAIAYAMgiieNrPqsMCAAEFgw+t4MAZACa3AO2zlYE87SoNEP +K6AH+wtBAAEQYDD7vBgiAABpMFgU+8Ag0Q8AHV66jI99yQwpIhCInP8CAAIAXv4QwuZ+cW36LAAC +AABY8PxMAAIAAGlwWQDdZa2tY/+IKyAH2iD7C0EAABBgMPu8GCAAEGgwWBTnY/2UAAD6LAACAABY +8PxMAAIAAGlwWBOQwCDRDwCMJ2TAdfgkICAAEHAw/iQhIAcQaDAtJAVj/GfAINEPAPosAAIAAFjw +/EwAAgAAaXBZANVj/44AAPosAAIAAFjw/EwAAgAAaXBZAJRj/3YAAPosAAIAAFjw/EwAAgAAaXBZ +AFlj/16Kl8e+C4sB+5YMICACUrBYCm1j/zEcXnkswvRkwi4eXncp4vKKkYyQnKCLkPq2ASAAEHgw +n5CfkS3i9LDdLeb0L53/jiD+9j4h8AJqcJ0nY/9MAAAA2iD7jBggABBgMFgUrvosAAIAAFjw/EwA +AgAAaXBYE1iIImWOMYkQZJ4s+iwAAAAQWDBbeVfAINEPAAAAAPxeYxAFEFAw/SIAICgQWDD/MB8i +AABw8FljwSgwH8Kj/wIABgCuVhDCtP8CAAYAqV4QLAol/wIABgCj5hD6LAAAAhBYMFgAnmP7PwAA +AAAA+iwAAAIQWDBYAGtj+ywAAB9djRVeQy4hCPwKICkABD4g/KYDIAAQYDD8pgUuCQBLsPWmBi4J +AHuwnqTz+3dgQAJKsAAAjieK7I+hiKCY8Iig/4YBIAAQeDD/pgAgYAJzsP+mASGwAkKwbUkFAgiG +AEljKazI/wIACgBnzxAYXiYpgvgfXiiakZ+hKYL4maAvgvr6hvggAgJ78C+G+orgwID+rwwBkAJS +sPP7J2gFAHqwGl2WCARR/yAHKgAgUTAqoIApCvv5/wEL4AQ6oPkK/C4JAFfwCf8B+CUILgkAJ/Av +JAdj+22KJ/sKAC//EGgw/aYAIBACSrD7JgcqAEpXEB9eBizy8htcf5nBm6Mi8vKSoi7y9Pn28iAC +AnOw/vb0IgAAEjDRDwCOKZ4qY/vsAPosAAIAAFjw/EwAAgAAaXBb/ZDSoNEPABhd9CmC+x9d95qR +n6EpgvuZoC+C/fqG+yACAnvwL4b9Y/8xG13rKbL1jZGPkJ/QjpD95gEgABBgMJyQnJEqsvewqiq2 +92P9zRtd4i6y9R1d5JnhnaMssvWcoiKy9/m29SACAhCw8rb3IgAAEjDRDwBsEAQqICArCvPTD/uq +AQAAECAw+iQgIlIAOOBpMRn8Cv0gLAB6sAysASwkIAIqAlv7ty0gIGTQZdEPAAAAAAAA/6f0cAEQ +GDAuCv4OrgH+JCAiAABQsFv7tiggBxxcCSkgIvQkIiggAUAwDIgJL4Heqf8vhd4pICKKKy7Ce/SQ +L2H+AmpwAOEEAN0aADsa+7z/KgAgarALqgKaKmP/jYon0w8qrBBYCaEkJBQkJAXRD4spmypj/3QA +bBAEKiAFwIh6gzT1CgAgRQA2oCogIMBB86kCCAAPmpD5JCAi+AA44NogW/uK2iBb+2sqICAKCkFq +o1nRDwAAAPosAAIAAFjwWP9BZa/sKiAFY/+2iydlv7kbW+Ussn/5sn0gjgA3II6RiJCY4I+QnvGV +kJWRLbJ/sN0ttn8snf+LIPvGPiHwAlJwmiclJCAlJCFj/33aIFv7RiQkBdEPANogW/t1LiAHHFvI +LyAi9SQiLiABcDAM7gkt4d6v3S3l3ikgIo8rK8J79JAdYf4CUnAAsQQAqhoASBr4jP8uACBX8Aj/ +Ap8qY/89jCmcKmP/NimygI6RiJCY4I+QnvGVkJWRLbKCsN0ttoJj/28AAABsEAgqMAMpIAf4MBAi +AAAxMPgWBiALEGAw+hYEKCABTDD5FgUoAKGGIPgWBiYApeYQwNCdEo4iiRX6W44QABB4MP8WASDu +ALegDJcRqncrcjq0TPwWACoAoObQHFvHK3I5DJwKLMJ/DLsBKSAE+xYDIS8ANuD+XVIQmAA2YC+i +SmTwnCzi7CmiSfybAQ4ASeZQLSAUKBYGDdSH/SQULAEtE2D/AgAIAI0CIIoTHVt+naCIIPsSBC7g +ASww9Vt8ECACSrD7pgMpgAQ6IPWmAigJAEEw+KYBIgDTG+D4PBAgHgA9ILBKbakFAAiGAElhwKCP +MP8CAAIAbSvQJnY5KCAE+SAFIAkAtiDMkWSiPdKg0Q8qIBSkqiokFGP/hQAAAAD6LAAAHBBYMPwK +ACABEGgwWBNhixJksef6LAACAABY8PxMAAIAAGlwWBIKjCLMzY0RyNn6LAAAABBYMFt4CsAg0Q8A +AAAAAAD6LAAAARBYMFv/X4gWYAAM+iwAAAEQWDBb/y2IFgUOR/8CAAIAuwOgwPGfEmP+nQDz/s5g +ABBYMIsV/RIAIgAAULD4CgEgABBgMPmMOAAwAlrwWBM/Y/9y2iBY/5VkoW+MImTO3GP/Yi0gBIwg +LyAHG1s9/hIDIAEQMDD/KUAB/gJBMPyIEQigBD5g+5kCCAAgcjD00bFrgAQ/IJWGHVs7mYT/CgQg +MBBwMP6GBy4JAH7w/4YFIAMQYDDwDQcAQAJKMG3KAgBJYSwgBxlb9/YhCCBgAnow+1zhHCABYDDw +zBEAAhAoMPRVNgYJAGGw+4YKJgkASbD2hggiAABj8G1ZBQADhgBMYfYSACAAEGgwLfQGY/58jhL4 +IgchFQA3oIqMi6GNoJ2wjKD7xgEgABB4MP+mACBgAkIw/6YBIbACWrBtSQUCC4YASWMeWzMvrMj/ +AgAKAK5/kBtcwC6yGPrmASDAAmrwnaEsshicoCmyGvq2GCACAkpwKbYaj4DAoPj5DAGQAnvw8/39 +agUAS/AA2iBbdSGIFmP9n4knipwpnDD/AgAH/0HOkCusyGS+eMDBnBFj/hkAAPosAAIAAFjw/EwA +AgAAaXBYC5XSoNEPAC0gBf8CAAn/RJtgwOIuJAVj/nyJJ/9bDB//EFgw+5YAIAAQQDCYJ/icCCoA +bs/QHVyWItIS+CYBIJACe3Cfky7SEp6SLNIU+NYSIAICYzD81hQiAAASsNEPAAAAAAAAAPycAAAB +EFgw+owgIgAAaTBYBotj/UEAAC4hCPWGBiIgAXww+YYEICAQKDD1hgcgAxBIMPVawRgJAE7w+YYF +IwAEPODzIBQuCQAbsI0piSv17gIECQAvMJWKmY39hgwigAQ84P6GCCAAEHAw/oYJIgkANPCTiy4k +FPP85mAGAjEwHFxqL8Ib+vYBINgCczCeoS3CG52gK8Id+sYbIAICWvArxh1j/qQAABtcYC6yFfjm +ASCoAmrwnZMsshWckiKyF/i2FSACAhCw8rYXIgAAErDRDwAAbBAIiCIsIAf1gPhsIAFgMC0wEBpa +fcCA/gqCJ8AEOyD6ZggCAF4HYC5iOqhH/Vp3EAYCefD/FgIqAH3/kCtiOQ3NCi3Slw27AS8gBPsW +AyDsADbg+xYAIJwAN+AvokocWoNk8LYswn8pokn8mwEOAFbmUC0gFCgWBA3Uh/0kFCwBA5NgZIAM ++xIAIgAAULBY/s6aE/kSAy7gASgw+DwQIgBdG6D4QQ9h/gJRMNMPbakFAAiGAElhwICKE/kyACH+ +AlkwDLsR/Hz/KgAgWrD6FgMiAImqUPxmOSIAABIw0Q8tMCD/AgAP/6DzUPP/OWACEEAwAC8gFKT/ +LyQUY/+EAAAAAAD6LAACAABY8PxMAAIAAGlwWAsB0qDRDwD6LAAAHBBYMPwKACABEGgwWBJHY//R +AADz/xFgABBYMP0SAiAwAlsw+AoBIAAQYDD/jDgCAABQsFgSPWP/qY4n+OIJLcAEOSD56RQvwBBo +MPXhFSBAAluw/hYBLABAbvD8mQwAIAJCMPjmCSoAIGlw+JkyAIACUrD55RQqAKhSEGjLPKjFJVzw +/wIACgB0rpD/EgMgOAA9ILBJbZkFAAiGAE9hhbEFxQj5uQQh4AIpcP8CAAYAy1VQ9bYBIgAAQXBl +ntlgAO8AAAApIAQqIAeLIB1aHPVaFBwCAVAw+L8RDKAEOyD0kOxsCQBrMI4TGVof+gowIAQQWDD6 +5gMqCQBf8JvhleL85gAgAxBoMPAJBwAgAmOwbdoCAExhFVrbLiEIKSAHF1vGjxP5CUEAAhBoMPTd +NgkABD5g9/YGLgkAS7Dy/CAuCQArsP72BCIAAGCwbdkFAgOGAExjwLArJAaKEvpmOSIAABIw0Q/a +IFt0IogUY/3yjxMIpQwFShRtqQUECIYAT2WPE/pKDACAAkNw+KEPbgAgL/CwqW2ZBQYIhgBPZyq5 +BAXIDKjYKIww+LYBLesAtqDAoPq1BCCAAktwmbGZsPP91WAAEEAwBYgMmOlj/quEE/4hCCADEGgw +/EYALAkAb/CdQfVGAiAgEEgw/VnWFCABVDD5RgMlAAQ9YPkiCS4JACuw9SAULgkAa7DzIgssCQBu +8J1GnkSZSPhVEAABEEgw80YJIAAQGDDzRgUkCQBNcJVH8yQUIAQCEfDyZjkiAAASMNEPKNxAmLFj +/m0AAGwQBGhDBmhCUsAg0Q8oIAawiAgIR/gkBi/wALYgiSIsMAHHrvsK/SgAQFZw+SYCIjgBPyB7 +ydH6LAAAABBYMFt2WsAg0Q8AAAAAAAD6LAACAABY8Fj+lcAg0Q8A+zwQIgAAULBY/n3AINEPAGwQ +BP0sAAIAAHkw/jwAAHQANSAbWY0TW1oA4QT+6QkDIBBAMPgoKA//EFAw8goBKcAEPmDwIhoCACAe +MPQyrioRAFCw+zKvKAAgWjD8MrAoACBGcPmdCSQAQCKw9DauKgBAXrD7Nq8qAEBisPo2sCkABDvg +KJaiKJajJDKuBCICIjauwKT8Wz8QIBBYMFlgnsAg0Q9sEAgnFgAcWzv6EhAgIBBYMPgSESIAAGiw ++BYFIgAAcPD4FgIpgAQ9YPoWBC8ABD0g+hYBLgkAT/D6CgQuCQB9sFlgjBdbLfpbLRABEHAw+VlZ +EAAQaDD8+v8gqQA1IGhBA8Yq0Q+IFPsSEiMgECAwBCQoAz8J+UkID8AEP+D/EgUoACBP8AAxBPDu +GgQAIDkw+Z0KL+AEP+D7+zgBoAI6cPv7OADgADYgK5XILEKvGFsU+hIFLAkAY7AsRq8qlc34lmAg +2AA1YGlRlioSBCsSBVljUv0KCCAAEGAwWWG5/AoAI+gQaDBZYcXaIP1x4CIAAGLw/kKvIgAAWPBZ +C8vAINEPAPAxBAMgEGAwDCwo8OsaD/8QeDAPuwPzPwkEACA7MChCr/nMCA/ABD/gr8z8zQooAEBa +MChGryrGYP3FzSB+ADVg/wIAAf+MnWCKFIsVWWMy/QoIIAAQYDBZYZn8CgAj6BBoMFlhpdog/kKv +IgAAYvD9CgAiAABY8FkLq8Ag0Q8AAC9CrwzoAwj/AS9Gry2VzfqWYC8wALVg/wIAAf9hHaAtceD8 +EgQiAABQsP5CryIAAFjwWQudwCDRDwDJbf8CAAH/Tp2g/BIEIgAAULD+Qq8iAABY8FkLlMAg0Q/a +IPwSBCIAAFjwWJPJwCDRDwAAAGwQBikwAmSRC2iRQPiSCG/qEBAw0Q8AACIwBvhaJRMgEEgwCSkd +qYgogpckMAXzMgMgrgA2IPoKBCAgEFgw/Fq0EgAAaLBZYA7GKtEPLzEILjAHGFjb/TAGIHEAN+Ab +WqYA4QT+4wkDIBAQMPLSHQ//ECAw/DMRAAEQUDDwqhoKACBcsPiyryIAIECw/LKuJBEAIrD5srAi +ACAU8PM9CSgAQEEw+LavLABAYTD8tq4kAEBJMPS2sCMABDvgIjajIjaiLLKuDKoCKrauwKT8WosQ +IBBYMFlf6sAg0Q8AAAAA+goEICAQWDD8WosSAABosP5MAAIAAHjwWV/hZEBB/wIAAf+jnSD6LAAC +AABY8Fj9scAg0Q8qMAYrMAcsMAMtMAQuMAWPMogzmBApMQmZESgxCigWAlv/NdKg0Q8AAAAA+iwA +AgAAWPBY/eHAINEPAGwQBBJZ4iIgBCI0CCI0CSI0CvI0CyAAEBAwIjQC0Q8AbBAEwCDRDwBsEAQm +ISD1CgAgNgA1oCgiEScgeBpaTBlY2m0IHyOSs/KihyQAIEFwpDMJMxH1XAEiACAYsPckFioAA7FQ +Y//Z0Q8AAGwQBCIhBdEPbBAGFVj7/lpTEAAQIDD2CgAiAABI8PkWACAAEDgw/uF+IAEQYDDwADpg +ABAYMAAAAAAAAPoKACIAAGGwWWKZjxEuEgL7MwIAARBgMPb2CAYJAFXw9VwBIAICITD4SSxgCAIQ +sABABA4IG3+H5osgaLApKlAwnhIAoQQAyRoJCQb6FgEv/9heUMYq0Q+LEJOx97YAIAAQEDDRDwAA +/UwAAAIQUDD8Wi0QABBYMFlfg8Yq0Q8AbBAEAASLyFYDImAABGHRDwMiYNEPAAAAbBAE9VojEyAQ +QDAIKCioVS5SsvlSrCAMBBuwyJHRDwDApPxaHBAgEFgw/SwAAgAAePBZX28jVrL6LAACAABY8FkL +VhZZgiZgBPQKAC/QADWg2iD8PAACAABZMP5SrCAAEGgwWQrRsUR2SeVj/64AAGwQBCogB4gi/Fgn +GCABVDD1gJxrwAQ+YP5YJBoAIGbwLLI6Dp4K/uKXKgBPJxAtsjkfWCj+2AEOAEh3UIwyKSEHCi5A ++u4QCvgBYDD5CUoLAAQ6oPyZEQ4JAFOwCe4CD+4CnoCJIP1YHRH+AlEw/KwRDuABLDD9hgIpgAQ+ +YPyGAygJAE0w+YYBIqgCO+D5jBAgABAQMPg8ECAaAD0gbakFAAiGAElhJLY50Q8AAAAA+iwAAgAA +WPD8TAACAABpcFgIvdKg0Q8A+iwAADACWnD8CgEiAABpMFgQA2P/0YYngmnzaRQvwBAoMPphFSBA +AmGw/EkRBABALzD5MwwAIAIQsPJmCSwAIC6w+DMyAIACa3DzZRQqAE9okGibN6KaKqzw9owQKgAb +11D4QRxiAABBsC5M/23pBQAChgBIYYrBqprzyQQh4AJSsH2hbvrGASIAABKwZDBIJLY50Q8C3QwN +ShTTD22pBQIChgBGYwpPDPhcQC4AIGow+uwQICIAP+Cw/tMPbekFBAiGAEplL8kEDZIMolIiLDDy +xgEvuwC34MAg8sUEIIACQXCYwJjBJLY50Q8KIgySaWP/XSJcQJLBY/+QbBAIKxIQkhX3WZcSAABJ +8PYSBSIAABGwmxeZFPdYnxYAIDmwYAAEZFBuzSwqYoAKPAH8SfFx/gIpcI0UZNBN+tYAIAAQEDDR +DwCPF2TwQQjqMBlXqimSMcClCio3CpkoqYiYFgwCAIoXKXKC+FekGABAVnAIqY4IqAqIhAuAAAzq +MIsWDLsMa7HZY/+ewCDRD9ogWViBY/+S3jD9EgUiAAB5MPoWACAIEFgw/FlvEAEQUDBZXsLHK9EP +AABsEAQF6jAWV44oYjHAlQkpNwmIKBRYcvAAFmQAIEVwAAaoCoiEC4AACeowCVkMapETDAIAKkKC +CjoBCKqOZS/faabc0Q/RDwBsEAQTV7n2V5AQEAIosPpXtxoAEBTQK2J9lbGaIylifZkiKGJ/9WZ9 +IAICQjAoZn/RDy9igC5tApXxniMtYoCdIixigvVmgCACAmMwLGaC0Q8AAABsEAQTV6T2WUMQcAIo +sPpZKhoAERTQK2J9lbGaLylifZkuKGJ/9WZ9IAICQjAoZn/RDwAAL2KALm0ClfGeLy1igJ0uLGKC +9WaAIAICYzAsZoLRDwBsEAYWV6kZV6ArYogskrUnYo4oneYogMH3FgAiAAAosPdwJC2QBDsg/4cQ +egAgZvAivQHwAAthAAIQsAAivQMiLIByUQJkMHn1FgEgADsl4PV8AAAAECAw8ABEYAAQGDAAAC1i +cPxiiCIAAFiw/UoIAgAAcPD5qhEMACBtcPrKCA2QBD9g/UwADAAgazBZCIjzPAEgAgIhMPRxJHAC +AilwGVkJKZCAADAECQ4bf++ybQgKsTMAMAQJCht/r6Rj/+6FEQ90EWtIJxNXcIIQLDKrK2KIrEwJ +zBGsu4y7eMYLLbITddkFAioCWQhnsURpSNzRDwAAAAAAAGwQBBhYW40uH1jyLiIL+iIMIAAQGDD8 +8osgVhAgMPvsAAYAi8dQCdkR9KBsbAAgSzCeq4sryLCavIonkyvzJgwgIAJSsFgEuY0n9vrAIEAC +Y3AGzAHz1RQggAJjMJzZnNgrIAXzJBUmAJgm0CUgBxtYP/RY2BBPEGAwLCQFK7F+9EJ/IgAAULD7 +KxQEIAEsMFhAqmShGdEPAI3J+sILIMIIE3D+xgkiAABbsC7ABfgKQiAGADbgk7z/AgAP/77DkInJ +0w/6wgsvcQC2YGWvafvCACA/EEAwKMQFLvJw+vKOIAEQaDD+uwwAABBgMFgCNhpXQCmiE7CZKaYT +Y/86AAByqQaey4srY/+gjcpy2QmeyvP/lmIAAFuwLiAFdOmLLSE2/iE3IAUQUDD8WKsQMhBYMFld ++dEPAACILQmIEfWu72wAIEMwicv/AgAOAHASUJ7LiyvIsJO8KsAFw7D/AgAP/2xakI3LZd7Ojsxl +7smIzWWOxPvCACArEEAwKMQFLvJx+vKPIAEQaDD+uwwAABBgMFgCDWP+oC0hNv4hNyAFEFAw/FiO +EDIQWDBZXdvRD40nGViLmUAs0RX4IgAgARA4MPvSCCBAAnNw+dILLgBAN7D/zAgJgAQ6IPzMQCgJ +ADow+EYBINQEWnAq2RQqrBD61RQgIAJS8HrDXMhJAASGAEthitgqrBD/AgAGAEbmkJrgiyJlvn77 +XBgiAABQsPwKASBAEGgwWA6W0Q+NzXLZCZ7N8/8dYgAAW7CIzP8CAA//iZIQnszz/wliAABbsACT +22P/vAAAAPvMDAAyADUgDE0UuNr6ejYCAABJMG2pBQIJhgBLY6xJ+vxAICQAP2ANewzTD225BQQJ +hgBKZQz9DC3cUJ3gY/94KPxAmOBj/3AAAAAAAAAAbBAE+CIAL8AQSDD0MEloAEBMsNMPbQgwc4E8 +KjAA/DAHIGwEIrAqIQX5qwgNwAQ7IPu8QCIAIGTw+zsPcgAAOPDzfAAAEwA14GP/xgo3DGP/7gAA +AAAAAPOODAAAEGgwDtM40jDRDwBsEAQrIAf2Vl8QAxBoMAslQApVEPchCCQJADVwlTCIIBpWWv5W +UBAgEHgw/zYDLYAEOiD+NgIsCQBrMJwx+SIJKiABXDD2IBQrAAQ+4PsiCyYJAF3w+zYJIAAQKDD5 +NggoCQBSMPg2BiYJAFXw9zYEJoAEOaD1NgUmCQAxMJY39SQUIGACEPDRDwAAAGwQBCQgIhhWOPMi +CyABECgw9EAfYf4CMTAogn8AgQQAZhoAVRr1XP8iACA08AUzApMq0Q+JKZkq0Q8AAGwQBPVWKhAB +ECAwJVJ/hiuDKQBRBABHGvd8/y//EEAw9jIMBhEARfDwUAQGAEA5sAYzDPMDGQIFABEwoyLRDwBs +EAYoIAUuIAfTUP4KQQgAXJogiymPK/8CAA4AVtvQjCcswRTBkP8CAAoAT2ZQHVX9DKwRrcwtwjrA +YfUKACIATMdgGVX5KMI5CakKKZKX+Y0BDgBCzhAXVgkOJkAKZhD+Vf8WCQA5sJbQhiD3IQggIBBI +MJnT+GgRAAMQSDD+1gIoCQBKMJjR+FX+HwAEOqD+IBQmCQB18JXVn9n71ggugAQ7oPh3AgYJAEGw +9tYGIAEQMDD31gQuCQAzsC7WByUkFC4SASnGOQMIR/8CAAIASJogwCDRDwCJImSQqgMKR2micokn +K5kULZwg+xYAIJEANuCKmRRXtfSgom/AEDgw8AAHYCoQGDBkoJKL0PSgN24AQDtwerEvLKAA0w/5 +oAcgTgQbMC/RBf74CAnABD5g+IxAKgAgSrD4qx5yAABisPrMAA/RALcgCrwMDFo4ZKBMjqJ06bHA +INEPD6wMY//fiif7TAAAABBgMPqsICIAAGkwWAGF0qDRDwAAAAAAAADz/3FgABBQMPusGCABEGAw +/QoDIgAAULBYDbNj/z6LEIrRK7wQ+9UEKgBAP3D6rPAggAJa8PrWASoAFVqQLNEF/lXMGgAgUzCa +0Z6gjSAI3RH0pgIsCQA3cP2mASAAEBAw0Q8eVcOeoI0gCN0R9KYCLAkAN3D9pgEgABAQMNEPAGwQ +BiggBSwgB8GT/AxBDgCRyhAtIgL6CgAhLwC3YBNVgQzHEQN3CC5yOv8CAAYA4UOgGFV9JnI5CMgK +KIKXCGYB+2wAAbMANaApMkr/AgAGAMBCYB1XXywySS3S7/3GAQ4At+8Q/AoBIAAQaDD4IgkgGhBw +MPoiAC4AEHgw+CYMIAAQSDD5FgEpAAFAMP8WAClwBDog+BYCIAAQeDBYBEb4V0wSAABasPoiACAA +EEgwmRAogEAsCgH/Vm8QABBoMPkWAigQBDog+BYBIB4QcDBYBDnAlvYhCSIAAFmw+iwAAAEQaDD/ +Cv8gABBwMPl2OSIAAGGwWJS0LSAV/wpAIAAQcDD+JBQtgAQ5oP6kACxABD9g/QoBLAkAazD/pAMs +CQBrMJyhwLb7NkkgFBBQMCokBQUOR2jiDC8gOsCP/wIABgBpR9DAINEPBQlHaZL1iScnmRT0cHBg +QAJycIuZFVcd9LDHb8AQMDD27wEAKhAgMIzgy7F7wS8tsADTD/mwByBOBCNwI+EF/zgICcAEPmD4 +jEAqACBO8Pi7JXIAAGrw+9wAD9EAt2ALzQwNqzhksHqPsnXxjvW/t24AQDewYABqA70MY//YAPP/ +kmAAEFgw+iwAABwQWDD8CgEgBhBoMFgNIfP/YmAAEFAwAAAAAADz/k1iAAAysPvMGCIAAFCw/QoG +IAEQYDBYDRfz/zpgABBQMIon+0wAAAAQYDD6rCAiAABpMFgA2NKg0Q+K4St8EPvlBCoAQDew+7xA +IeACUrD65gEqABZakCzhBarKmuEeVSieoI0g+N0RAAEQcDD1pgIsCQB3cP2mASAAEBAw0Q8eVR+e +oI0g+N0RAAEQcDD1pgIsCQB3cP2mASAAEBAw0Q8AAGwQBCggIiUgBxdU8gOIDPgkIiQgASwwB1UJ +JFHeo0QkVd4jICKJK/xyeyABEFAw9DAcYf4CWPAAwQQAuxoAqhr6rP8oACBecAqZApkq0Q+NKZ0q +0Q8AAABsEAQoIAb4jP8iAABQsPgkBiABEFgwW3GMwCDRDwAAAAAAAABsEAQUVWYBIhGiMqQigiDR +DwAAAGwQBhhWoAEpEakz8AAJYgAgQPAAymzNeioigApLAftZ8nH+AjGwiRzyCgAgFAA2YGAACADa +cFlVoGP/25qQ0Q/AINEP3TD+TAACAAB5cPoWACAIEFgw/FaMEAEQUDBZW9/HK9EPAAAAbBAEGFaG +AScRpzeodyZygMePCEgDCGYBBlYCJnaADAIA0Q8AbBAEKSEEhyDzWBQJwAQ+YPl3CAngBDogCHcM +J3z89nIAKIABHDDwkQQAARBAMACIGvCQBAoAQDYw+wMZD/8QUDDwkQQIEQBSMPBIGgYAQEGwCGYC +9nYAIBkANWAlIQLNQiohA7FbCwtP+yUCICgEWrDSMNEPsFz8JQIiAAAQ8NEPwND9JQUiAAAQ8NEP +AAAAbBAEA1QUJSEEgiAMVRH1IggF4AQ5IAQiDCIt//IiPySAARgw8EEEAAEQKDAAVRrwQAQCAEAo +sAICGdEPbBAEJyEEiCAPAgD2fP8p5wEcMPklBSXABD2g9YUIDcAEOmAMXAwADIsqIQP9CgEqwAEc +MA07YAoKRg8CAP4+E2AAEGAwDJsRC1sMAguLDTxibz4T+WkJf/8QWDDIoXOhIwmSEaIy0Q8nIQSx +mQkJT/klBSCgBDpwsHYMZRHz/8RkACAuMAmfEa8//1QUD8AEOeD+RBEOACByMPTuDA6AAXww8PEE +AfgCc7CP4ADYGguEAwT/AfkhBSgJAHowmOCIIGP/oywlBfP/rWAAEEgwAGwQBIgzCIhXb4QDiSLO +loon9TIEIgAAWTDzMgUiAABpMPqsICAAEGAwWAAE+iwAAgAAWPALUADAINEPAGwQBPgsAAvABDlg +/YIBIgAAEPD7iQQiAAAZMPJUDAXABDyg/YEFIgAgK3D6uwwPwBBgMPWqDAwAQGIw+LsyCAAgZ3Dy +hgEggAJKcPuFBCoAIciQyqQKJQh1kz/JQW1JBQAChgBDYYWB+4kEJAAgVXB5UWX1hgEiAAARcMix +0Q8AJsxAloH2hgAgABAQMCKFBNEPDSIMkoFj/7gAApcMB0sU+0QMAgAAKPBtuQUAAoYARWHyzEAi +ACA88G1JBQIChgBDYy2JBAeiDKLCIixA8oYBL6sAt2Bj/6YizECSgWP/mQAAAGwQBvNV2xAAEDgw +9FXYEAQQMDDyFgAgARBIMPAhBAWwBDyg8J0aAAAQEDD9FgEkACApMPAAGmAAECgwAACXGrFV9mz/ +IEACITD0YNtgBAIY8CgxripCUvBRBAXCATog/lRPH9wANqAnQk4u4n+IcY1wL33/L/I+LYYALHIA +LUJQKMYB/H3/If4CWrDydgArkAQ74PJ2ASoAIFOw+0ZSIf4Ca3D9RlAh+AJjMPLFgSAdADbgKxIB +8FEEAAEQODAAdxpbcIHz/3dgARBIMC5NAS7sgCzgxi3M6A0NR/LkxyYwALtgGFWk+NgKD/8QeDAv +hqsvhrMs4MbbIAvkFgECAB5UnC3iggDBBAAvGgDBBPCYGg//EEgwCYgDCN0BD90CLeaCC+QWY/+K +AuQWAQIAG1SQKrKCjRHH7/4SACwRAHdwwPHw4QQGBQA/8PB8GgoAQGqwDKoCKraCAuQW0Q8AAABs +EAoqIAeIIvtVhBIAAEiw+gpBAAQQcDD6rAoApAC2IA7MEavLLbHi/t02AAAQGDD2seMhaAA3YBVV +eR9TjpsTmhL5FgEsACB7MAxiCyctFfd8RCABEHgwK3Kv+C0YIAAQIDD++oAgugRC8IixirCagImw +mJGUsfS2AC4AQHLwKuE5KeE4KOAH1LD4C0EAkARScA9oAwyIC6WLLrJuKI0YlOCeQfhGACACAhjw +9LZuIVAIaPDAkIoT9qXjIAB1LmDAINEPD2YDDGILJy0VJ3xEK3KvY/+UGVN4GFNfKZCADLoRqKr4 +ojogbgJKcAlJFLOZeYNbGFNaKaI5CLgKKIKX+hYEKABARnD7nAAAwQA2YCrgdZkV/BYIIEEANqCe +EP0WByIAAFpw/OIcIgAAU7BbbvuMGI0XixX+EgAgARB4MPyoEQIAAEqw8AAQagAgRvCaFPP/smAA +EEgwwJAq4HSZFp0X/BYIICUANqAuFgAcU4394hwiAABTsFtuwowYiRaNF44Q+akIAAEQeDCKFBhT +eSmmOSjmHGP+9wAA9rXjIAAQEDDRDx1TRC3QgIsS+hIBIG4Ca3D9TRQAARBgMP3cAiAwAlrwWAs1 +wCDRDy5yry8tGJThnkCfQSR2r/P+1m/0EEgwbBAEG1QjGVQhACEEJ7CA9pCAIAEQYDAAyBr6U1AY +4AFAMPRGOQQAQD4w9cU5AgAAIfD2lIAgYAQZcMfv+ioKDhEAcjDwPRoGAEB18P85EAYJAG3w+aaX +JuABPDD3tIAgCAA1IMl40Q/yVAsf+gA14C8i0sc+A/8BD88CLybS0Q8YVAUlgtLHnglVASWG0tEP +bBAEE1TqElTq0w+IPfxU6RAAEEgw+iAAIf4CWjBtiRsKrQoM3Qot0a710BNgAgJKcLGqCroBCgpH +KiQA0Q8AABxTPizCtC4y8vrKCAAAEFgw+aoRAAAQaDD66ggAABBgMFv/Si0gAI49/uz/IAICa3AO +3QEtJADRDwAAAGwQBBVTRoJZ9lTNGP8QQDD0IKBu/xBIMPRUyhAAXYSg+CIqYAYQODD/AgACAGYE +oP8CAAQAeICgaCVSaCYlglqwIvJWCi//EBAw0Q8AACliqiNCgAkpVymcpvlGfyD0ADTgl1kqCmQr +YqosSgD3UgogABBoMP1WCSoJAGbwK2aq96IMCABhVdCifp5a0Q8vYqoSVK3zVKwfEQF8MAL/HBJT ++fdWCS4AIB/wAv8sL0aAY/+wACliqioaAPMKASABEBAw8lYJKABARnDzVgooCQBWcClmqtEPLGKq +i1rAovpWCSwAQEsw/GaqIAICWvD7VgogARAQMNEPLmKq8lIKIwAQeDD47gEABBBoMP1WCS4JAHuw +/maqIAICELDyVgogARAQMNEPI2KqglrA9f9WCSIAQEzw82aqIAICELDyVgogARAQMNEPsXj4Vgog +ARAQMNEPwJOZWS5iqvJSCiMAEHgw+O4BAAQQaDD9VgkuCQB7sP5mqiACAhCw8lYKIAEQEDDRDwBs +EAT0Un8QARAYMCRAwfQEQAAAEBAwBDI40Q8AbBAEFFN3FVRpF1KpI0CAG1N1/lN1H/4QeDD9+v8g +DAA04LAyIkSA0Q8AwMH0CgAgBBBAMNMPbYpdKlHgKVHcKLCA8EEEAAEQMDD6kwZwARAYMMBgAMka +CQlHCJIBAjI59iEpcgAAUjANkgPwYhoIAEASMPKIAgLwBDmg8naXKOABQDD4tIAgFQA2oMmIsUT3 +fAQgBAIpcNEPAAAA8woBL+0ANiBgAAHAMCji0g+IAQg4Aijm0mP/1GwQBIUjiCAWUmD8UkcUIAEs +MPSAY2uwBDlgpqYpYn8nYn4dUkLymStwABBYMHJ5KytmfytmfoQhiCCYQIUgI2J9lFGbIPsmASH+ +AhjwI2Z90Q8AAP8CAAYAQBXQcpEciiGYoIwgKWJ9msGbIfsmACH+AkpwKWZ90Q/RDwCs3q6ufoEw ++GZ/IDUAtWDOjS9ifWryKCNieyNmf4UhiSCZUIgglYGbIPsmASH+AiPwJGZ90Q8AAPtmfy/VADVg +hSGJIJlQiCAkYn2VgZsg+yYBIf4CITAkZn3RD44hrN+vrw/vDA++OC5mfmP/cQAAbBAEIyEEFVIM +83RGAgBALPAEMwIjJQTRDwAAAGwQBIgjGlJ5Ky3+K7J8KqJ/+bsRD/wQSDD7qggIAEBKMAuAANKg +0Q9sEASJMBZSb4dAipEmYn+MkJygi5CIMvq2ASAAEFgwm5H7lgAh/gJCMJgyhSf1XP8nkAQ94PUm +ByIAID2w+0UDIAgANWDSMNEPJCAaDwIADwIAJkzo+yQbJuABMDD/ZhNv/xBIMBhTzQhoCimGqymG +syQgGvI8AAIAAFLwCuQWAQIAHVLFLNKCAEEEAL4a8EEEAAEQeDAA/xoJ/wMPzAEOzAIs1oIK5BbR +DwAAbBAEFlJuASURpTWmVZRQDAIA0Q8AAAAAbBAIGFOnkhT2EgQiAAARsPAACGYAIEGwylnNJypi +gAo5AflJ8nH+Ailw8goAIBMANeBgAAfaIFlSp2P/3ppw0Q/AINEP3jD9EgQiAAB5MPoWACAIEFgw +/FOTEAEQUDBZWObHK9EPAABsEAQaUpoWU6Xz+v4gABA4MCRirgACACmi0AOZASmm0BhSrSeGXFlV +Tllb9RVTnR1R5ggsEAxMAg3MAixmrhtTkie2hCpSEBRRr/ZR7xAAEBAw91N8EEYANqATU5IrYrkq +Uu+rKwm7EauqLjKALXCAACAE/Q0bDgBAI7D+NoAgHAB/cCyiH8jDwLFZFkMtUhCxIvM9QCv/4+yQ +xz4fU4Mu8oID7gEu9oJYiSDRDwAAAGwQBMBABOQWAQIAFlJsJWKCACEEADca8CEEAAEQQDDwiBoP +/xBIMAmIAwhVAQdVAiVmggTkFtEPbBAEKyAHFlF/HFGG+wpBCgIBXDD4UoIaoAQ+4PkhCCoJAGbw +mzCHIPQ2CCsABDqg9TYJKAkAVnD2NgIoCQBGcPg2BiAgEBAw8jYDIAMQQDD5NgQgABBIMPk2CieA +BD3g+TYLJgkARfD3NgEgYAIQ8NEPAABsEAQsIAf7IgAiAABQ8P0KASAEEHAw/CxAADAQeDBZWXkd +UW0YUjQeU0rwDQcCAABKsABJYQBJYQBJYSkgBy8hCAkJQfCZEQAAEFgw8qwwLgkAT/D+pgIuCQBH +8P+mACAgAkqwAgSGAEljAASGAElhK6QW0Q8AAABsEAQoIAcaUUwIKEAKiRAKmQKZMIcg9lE6F4AE +PeAHVwKXMfAGFwAQAjjwAAeK+yEIKcAEPWD6UsodAAQ6IP1RNhBgAhDw/TYEKgkAZvD8nOgqCQBW +8Ps2BiGgAkpw/DYFIAAQcDCeNwAEjZo4mTkCE4/RD2wQBJc2HlGN+VElEAMQQDD6USUQGBBYMPs2 +Ay+ABDyg+jYCLbAEPWD5NgAsEAQ5IP1TDhwJAGsw+BIKLgkAR/CYOZ8x/xIJLAkAYbD/NgguCQBw +sP1RDhwJAGswnjScNY4YnjfwDRcAUAIQ8AACiiI8MNEPbBAEGFLgJYJ/wJD2gn0gPwA1YIphjGCc +oItgmrGZYJlhJ4J/sHcnhn+OIZbgnmGSYPYmASGQAjGw8jwAAgAAGbBtSQUAAoYAQ2HSYNEPJoKA +hWGKYJpQh2CVcZlhmWAvgoKw/y+GgmP/vgAAbBAEiCD6IQUvwBBgMPIiAyIAADiw/EsRDABAYfD4 +uQgKACBisPqsQCB2BECwLXkEq939dQQqABrOkMk6yUjyPAACAAAaMG1JBQAChgBDYSlyAA8CAAuZ +CPqRWXIAABIwmXDRD8CgmnPRDwAIqQz5ugwANAA04AlLFP28CCIAABDw/U02AgAAMjBt2QUAAoYA +RmEJMgj7TgwAgAIbMG3pBQIChgBDY6rPL/xA/3YAIgAAEjDRDyLMQPJ2ACIAABIw0Q8AAGwQDJIb +lBeVGZYYKTADiCcrMAL3FgwiAABw8PiMICIAADlw+BYNIgHJAuAsChD8FgQgHgJScPpKFAACEBAw +hh31EgwpwAQ8oPNhBSACAmKw+PrALcAEPyD4ZgEMACBvsPYWCiYAIDDw9mxAJAAgTXD63AAKAjgz +UP/NEQIAAHqw/LwADgFc6tCIoYmg+VYAKAMAQfD4VgEgEAJKsPEJFgAQAhlwAAOKjaGKowh3DIPy ++N0MCgAgUjD99gEqAANCkLEzmvOT8vUWACABEEgw/Z05AAAQQDD9mDgABAJLMPSCwmoFAEZwhRD0 +crhgIAIZcIQX/0QRAAICUvD/AgAKAVMikBhQkcDQ+BYFICACQjD4FgYgABB4MG0IFwABMAAAMSAM +ECANAQABMQACAAACMCAMAYwdiRoswQWpyf62CwCAAkpw+mwACgB/SZCMoPPWCgBuADcg89wLCAMA +YfD4ZgAgEAIysPUGFgAQAmMwAIyKiaCGowh3DPyiAiACAnvw+JkMBgAgMjD5pgAqAANBkLHMlqP8 +pgIg/gA14GTQrfM8GCAAEGgw+BIGIABVcNDwCBcCAABI8AAJigAJigAJioyhZMBtA9YK89wLCAMA +ZfCZYPl3DAAgAjKw+QYWABACYzABDIqIoYaljKT5iAwAAgJ78PimASYAIDJw9qYFKgADSZCxzPym +BCCNADXgZNBc+BIGIDACGPD9EgUgsgBw8PAIFwIAAEjwAAmKAAmKAAmKwNCJoGSQTfRwWmACAlLw +dKtSY/7RDGoMY/7/APP/b2ABEGgwjBXwDAcCAABI8ABJYQBJYWAAJwAAAAAA8//CYAEQaDDwDQcC +AABI8ABJYQBJYWAADImhs7gJizhj/6dj/yxj/5or5AL/8wkADxBAMAgzCgNDFP/8ASIAIBiw/1UB +IAICELCDGyQxBxhQD/sSDCVAASAw/lALFcAEOSD9UAwUCQBBMJSwgzAZUfv8EgQsBQB/sPy2AyuA +BDjg/bYCKgkAULCasSmSf/8CAAIA2X5QiBhmgaiNGx5R8P3RGiwmAUAw+U/9HAAgczAswID4tgcs +gAQ/YJ22+xIJIgAAUvAJOQKZpAy7DJul0Q+EF5sS8xYBIAAQaDD/RBEAAgJS8PUWACoAK6KQ+xYC +IgAAGrD/FgMiAAAq8G0IKv68CwIAAHrw9ssicgAAUzCMoGXAmoyhsd31wNBgBgIY8LP79DsZcgAA +KvBj/86KEQrKDGP/2QAA8/7tYAAQeDCLEg3cCfP9MWoAIGbwv5r6ShQBKwA2YIMc8uwQIEACGPBt +qQUAAoYAQ2GHGQurCfMKASAEAhKw+XcMACACQnD4FgQgFQA14CwSBw/MEfy8DAAAEEgwDJM5/woB +IAAQaDAD/Thl3Cvz/qBgABB4MAAA/BIAKAMAYfD4xgEgEAJqsPsNFgAQAmMwAUyKiaCMowh3DIOi ++JkMDAAgYjD5pgAqAANDELEznKOTomAANoMQDH02/TYBICACQrD9CBYAEAIY8AGDio+hjKUNdwyD +pP3/DAwAIGNw/6YBKgADaxCxM5ylk6SJExxQxYmQ/BIAKABAZnCZwIigZYw/jaGzXA3LOGP8NRtR +h4oYjxyIGfRPkxgmAVQw+vYHKAAgXnD5kIAgABBwMP72BiQJACDwlPQJiAyY9dEPAAAD2gxj+43B +wJwU8/tMYAIQEDAAAGwQBIQpgywEMwwDA0gjJR8jJSHRDwAAAGwQBIknipz4mRQgABAQMPWcICBg +AiJw9KsMAZACUrD0gKFiBQBasIqZ9goNIFcANqAnCjzNNiugAHexR2i1LHa5CyygEGjBO3a5AmjC +NS2gB8DA+lwAAgAAW3Bb+zArWQSKUcm1Za/LYAAYACygEGnIzGAADgAAAAAAAADz/+VgABBQMPMK +LSAcADSgLSAAc9EZji7AIP5PDAGQAnOwD+I5ZS/nwCDRDwAAAAD7LAACAABRMFgGHfKsAA/RALag +Y//hAADz/2FgABBQMGwQBAUGR2liWoUniFj5URUvwBBgMPdSCyBAAlFw/VkULABAYrD8mQgLwAQ9 +IPmcQCBuBEHwq939VRQkACBeMHWTLckyyUBtSQUAA4YASGElogAPAgALVQj5UVhwABAQMJWg0Q/A +INEPwCCSW9EPAAD4lQwALgA04AVHFLh29kY2AgAAEPBtaQUAAoYASGEFMgj3SAwAgAIbMG2JBQIC +hgBDYwW5DKnJKZxA+aYAIAAQEDDRDyvMQPumACAAEBAw0Q8AAABsEAQuIAcfTx4OLkAK7hD9TxQe +CQB7sJ4w+CIAIgAAUTD0TyEQBBBYMP02AiAwEGAw/DYDKYAEOiD7T+IYCQBaMPg2ASIAAEjw8AQH +ACACGPAAQ2EAQ2EAQ2EtIAf4IQgtAAQ54PKcQCACECAw9UQ2DCABbDD1nCAtAAQ/YPvMAggJAGow +/JYGKAkAWjD4lgQiAAAZcG1JBQAKhgBDYQYOBi5UBtEPAABsEAT6IAUgCxAoMPZP3RAIEFgw9woB +IBIQGDD6MzJwABAgMHOhdvMKCSoAZAagdaF7/wIACABHhqD/AgAGAHGekMCJ+KMGf/UQEDDRD9JA +0Q/aIFiOZPosAAAAEFgwW/9aKSBy/wIAAgCbAmAbTxqMICMkBSuypipim6y7CbsRq6qMp/36wCBA +AlswDbsB9MUUIIACWvCbyZvIJKQFjCLzTrgQjgA3ICogBWP/k40iZd+O2iBboHFlr+zA6v4kBSAK +EFAwjyJl/3faIFugSWWv1SkgBogi8yQFIAICSnD5JAYoCQA6MJgi8/9VYAkQUDAAAIsiZb9J2iBb +oIhlr6ctIAaMIsDs/iQFIAICa3D9JAYsCQA7MJwi8/8lYAwQUDCPImX/GyskBfP/FWIAAFLwACgy +SvpiZCoAVi4QKTJJ+psBDgBQ1lDaIPwhCSAAEGgw/wr/IAAQcDBYjfL8ISMgABBoMP4KASIAAFqw +/woCIgAAULBYjessIAaLIvU2SSAREGgw/SQFIAICYzD8JAYqCQA+8Jsi8/6nYBEQUDAvIAccTogo +ICL0JCIuIAF8MAz/CS7x3qjuLvXeKSAiy5ktwnuIK/DRBAH+AlpwALsaAHoa+qz/KAAgWjAKiAKY +KmP+iQAA+iwAABwQWDD8CgEgBhBoMFgGc2P+rI4pnipj/moAAABsEATyIHAiAAAgsPQgCWgJABDw +KERw0Q/6TAAAABBYMFv+6CpAcAw5EQk5AgqZAilEcNEPbBAGhif3IAco4AEoMJgQhm73B0EC9gI6 +IBxQTf8CAAoAjBsQ/wIAAgCyASD/AgAKAJ4fEIknDwIADwIAKpkUyKkrIAb6kgkgAL6G4PosAAAE +EFgwW//dyKLAINEPjDONNishCQ0NQ/S7EQxgAWAw+8wRCgkAbvD8ChAqCQBm8Ay7AptgLSAFbths +LiByfu9m2iBb/01loIMvIAX5IgIosAE74Cggcn6PTftOJxBvALZgDHoR/U4mGgAgWrArojoNfQr9 +0pckALNC4CyiOZoR/csBDgCs7xD8bAAAAhBoMP4KACIAABqw/woCIgAAULBb/wzA5C42OY8QaPI3 +iif7TAAAABBgMPqsICIAAGkwW/nn0qDRDwAAAAAAAAD6LAACAABY8PxMAAIAAGlwW/7L0qDRDwDA +INEP2jBZVSccUAT7rAAD/3BCoP8CAAIAWQKg/wIABf9oFqD/AgAD/2RGoNogWVUGwCDRDwAAAPos +AAACEFgwW/+VZa7eLDwQ8AwWAgAAWbAAS2Fj/vgAjTENzVNo0X+OMv6OVwA3EHgw/wIAD/9Fe5D6 +LAAACBBYMFv/h2WupCg8EPIIFgIAAHmwAE9jY/6+ZK6DiaD5iVcAKhBgMP8CAA//O2JQHU7IjKL/ +AgAP/zTrEI8i+bz/L/4QQDD5JAYuAEBH8J8iY/5NjjP/AgAB/xBvkNogWVTswCDRDwAAAPosAAIA +AFjw/EwAAgAAaXBZVKHSoNEPAPosAAAwAlnw/AoBIAQQaDBYBdNj/tkAAGwQCBtPw5sQ+CIAIAAQ +SDCZEvkWAyIAAFCw8xYEIAIQaDD0FgUgAhBgMPUWBimABDog9hYHKAkAYjD4FgEiAABYcFv/XtEP +AGwQBMAg0Q8AbBAGkxD9CgEggAJZ8PogOyIAAGFw9iIHIgAASbD8FgIvwBBAMPkWASpgAVAw9Wwg +K8AEOqD6OggEAEBFcPAAJ2BQAlKwKCA7sYgoJDssYRX93AEuACAvMP6sECCAAnvw+uwACgB2e5D/ +ogEiAABKsPMJFgIAAGLwAEyK8QkWDgMAfTAADIqDoo6jn7GIof9EDA4AIHPw/qYDICACWvD/iAwC +AABg8PimASoAA3uQsTz8pgIh/8iNIBxN2SshIi4hCS8hJIgQGU9/KiAHiIAjIQf0EgEqAgFQMPlO +WxgAQEow8wNKCqAEOqD0BUMICQBSMPlNeBgJAEow+HYAJIAEPWD6IgAuCQAv8P92BCoJAGbw9HYG +IsAEOOD7dgIuCQATsP52AyAIAhNw+xICK4AEOqD7dgUqCQBQsJpxAAmN+U9iEGACKfAABYoJ2QKZ +ftEPDOoMY/8RAABsEAT9TV0QERBAMPs8EQoABJoQwZVzm2iLJ4kij7MosQOKsprw+rICKA4BQDD4 +iAkMACBvMA2ICviNFS//EHAw/6YBIAAQaDD9tgMqEQBxMP22AigAQFZwmSIvgq4ZT0Ww//+GriwA +IEswKsJQsKr6xlAgARB4MP21AyAVADag0Q/bMPwiAiIAAFCwWVGQ0Q8qzQEpoD4rnOgLC0f/thNi +AAATsBxPHQy8Ci7Gqy7GsymgPt7QDuQWAQIAGk4WKKKCAJEEANsaAJEEAPwaAswDDIgBC4gCKKaC +DuQW0Q8AAGwQCPdNgBIAAFHwKHL7lRIoghmUE/YWBCIAAEiw8jwAAcwANiCNc/MKACHCADdg9U1o +EAAQWDD5FgEgkAJ4sP8WBSAAEDAw8ABSYJYQIDAAiWjJko1pmdCOaP3mASAAEGAwnGicaZxrKCIT ++RIFIEACebCfgJhp+WYIIAICWvD/JhMgAIsGoP8CAAIAhwKgjXPAYLEz/wIACgCAaNAuUqwscvWu +PgnuEa7Mjscv6RRk/+AvwAV08dqO6WTv1YkgiMB5gc4vwEVp8chro09qoUyJE4jiLxICCYgMKeID +8hYHIAEQEDD/mQwAABB4MPkvOAAAEEgwCCk48hIHKABaelBkb42MYi36mv1kBS9EADcgfsdXx40I +yAGYYmP/MpoQ+xYGJAB2nqDA8CngOijgOwiZEfngOCgJAEowLuA5CJkR8PEEDgkAS7Dw7hoAEBBI +MACRBACIGgjuAo8UfvmhiRGIygmIDAjGOGP/lB1NL/8CAA//b2dQmxb6FgAgjAA3IMCwbQgQKvoA +fKA3DIwU9MBJYBACWvBj/+jAIPoWACAiALbg/goCIfYCerAP4jnRD4kRiMqJkIiACYgMCMY4Y/8+ +0Q/HoHygDAxMFPAABmAIAlrwsbsMHBRlz/f6bAAP/xBgMFv/T4oQixZj/mIsrPv7CgIgABAQMPoW +ACIFAGLw0Q8AAAAAAADz/89gABBYMPxOohACEFAw/RIAIDAQWDBZU82KEIsW8/9wYBYQEDAAbBAE ++kylEyAQaDANLSj+TcsaACBTcCiirvAxBAABEFgwALsa/0yRGAAoWhAYTcX8LBEIgAQ84PjMCAgJ +AE0wmcAooq/8orAuABbG0Ay8AiymsAjqMAM5CfyZEQwAIHtwqcyuzCnCbyjGbgSZDPnGbyAAFS5g +0Q8AAzkJ/JkRCAAge3CpiCiNCi6ByfTuDAAAEEgwCe41LoXJ0Q8sorEMuwL7prEiAABQsFux4NEP +AABsEAT2THkTIBBAMAgoKKaGJGKu8DEEAAEQSDAAlxp3SDEUTF4MIhGkIoIgKmKv8nIBAAAQQDDy +kjkIAANR0NEPKmKx+noBAAEQSDAKmDgIIgHRDx1MWQM8Cf2NCA3ABDsgrcwszQotwcorwckswc0N +uwF8uwPAINEP0pDRDwAAAGwQBCogIikgIx5MVfqZDAABEHgw9JBYYeACI7AsIAcMDEEOzAkrwd4J +vTYNuwwrxd4qICKLKwqth/okIiBLADagKOJ78IEEAf4CYrAAzBrw+BoKACBm8PwiCSH+AkIwCLsC +myoMuQxzkynAINEPAAAqIAVooXKLIsDCDLsC+yYCL/QQEDDRDwCLKZsq8//UYgAAYvArIAcNrAz8 +JCIqIAFcMA65CSiR3q2IKJXeKiAiy6kpQn+NK/CRBAH+AkKwAIgaAP4a/uz/LAAgR3AO3QKdKvu8 +HyIAAFCw/AoBIAAQaDBYBB/HJNEPxyTRD4opmipj/91sEAwoIhgogAUpCnN5gSSJNyqZFGSlbISZ +2iD9Co4iAABY8P4KAiIAAGEwWAI2wCDRDwAAKyIQK7AFLAqV/wIABgLk5tCMImXF1hdL9ykiEhpN +W/9MUxAAEHAw+YlBAAEQWDD6nREAABBAMPm4OAngBD5g+pkIDgUAQ/D5FgIsCQB3cJ0RYAJqAAAA +APgKACoAQFLwCpg4ihQIqgFkpVEtVCcNiBT2Fg0gABBQMCpUIypUIfhUJiAFEDAwJlQg+IgUAAAQ +MDAmVCIoVCUIiBT4VCQgcAJZMPELFgBQAklwAAmKiD4oVDMIiBQoVDIIiBQoVDEIiBQoVDCLPfZU +OiAAEEAwKFQ5K1Q3KlQ7C4sUK1Q2C4sUK1Q1C4sU+1Q0IAAQWDArVDgqIhYmVE4mVEIoVE0oVEEq +VD8rVEwrVED6ihQAABBYMCtUTypUPgqKFCtUQypUPQqKFCpUPCgyFbGJKTYVKFRHCIgUKFRGCIgU +KFRFCIkUKVREKzITJjIUq2YmVEsGhhQmVEoGhhQmVEkGhhQmVEgqMhKGHfuqDACwAkFw+tkQcAAQ +WDApUCEqCoAKmQIpVCEqQhkPAgD0ok5g0AJJMCs0Qvs0QyoDAFNwKlYVAgmIAEiKLjITqu4uNhMr +QhkK3gwtQhoKuwz7RhkirAA24C5CG66u/kYbKgAD05At3AH9RhogABBoMCkhBxpLkv9LkBlAAUww +/dgJCcAEPmD6S7sYCQBWcJlQ+RIIKeAEOiD7IgAg3gJCMAhIFP9WAiBAEHAw+pkKC4AEOuD+VgMq +CQBSMJpRGkuuKZKXjhH6S9EYAEBWcAnuAvpLfx4JAFOw+SEaKgkAVvCbVBtM0A5qQfpLphoAIFbw +K7CA/lYHKIAEPmD5VgYgAgJ7cPvLDA4JAFfw/1YUIGACWvCbVYopKSIVrKr6rDAoACBmcPomCSBg +AkpwKSYVKGY5KyAWLwr/f7ENKiAH/BIGKiABUDBb/r4sMhMrMhL/AgAGATXm0CogBwoKQQymEfxL +TBYAIDmwLWI6mhj8rgoAHhBYMP7ilyoBS99QLWI5/tUBDgFGd1AuIheJNy0yEoopL5kU/BICIMAC +QXD4FgMgABAgMPgyEyISADfghJkvMEKJKizCfwjdDPqZDAwDAHdw//8JDAAgazD0/wsAYAJTMPoW +BiIAAHNw//xwKgA4VlAoIBYqIAf7OiAg/xBIMPgWByf+h84QCgpBmhULqhwbSzaJF/oWACoAIFqw +KKKu8JEEAAEQWDAAuxr/AgAIAQVaEIkVDJkRp5mJkPm5AQABEEAw+KKvKAUATjCZFCqisfkKASn+ +VcLQihRj/LGcGZ8anRudHPsSBiIAAFCwW/7EjRyOG48a/BIJL3cANqBj/B8qMEMPqgqKoGSgggra +NipWFSswQw+7C7i79QsWALACSXAAiYooMhMkMEP/RAoIACBSMCg2E45ACu4MnkAkMEMPSwqLsPre +DAAmADbgD04Lj+ON4q+v/+YDKgADU9Cx3Z3i8/2ZYAAQaDAAAAAAAPkKACEkADUgKDBC0w8PAgD5 +NEMgAgJCMPg0QiAwAnvw+QoAIOwAN6AJC0AqMEONEw+qCoqg/bgKCgMAU7CagCQwQw9EC/29CwAQ +AiEw9wQWABACa3AAzYooMhMkMEP/RAoIACBSMCg2E41ACt0MnUAkMEMPSAqIgAruDPWARGACAmpw ++hIDIDQANSAoMELAkPk0QyACAkIw+DRCIDACe/D4rBgiAABLcPuKOQoAAUww+hYDL3cAt6BgAFbA +kSk0Q2P/3A9OC4Tjj+KkpPTmAyoAA1EQsf+f4mP8tGP98Ik4y5aLOcCgmjuZsIw4m8GaOPo2CS+Z +EEAw+DQFIAAQEDDRDwAAAAAAAPP6kWAAECAwwJDz/HpiAABqcC36mf00BSAAEBAw0Q8AwIEoNENj +/u+LGPosAAABEGAw+7wYIB4QaDBYAqvAINEPG0qfihAJmQn7qggJwAQ+YKqZKZ0KKZzYKpHeKJHd +KZHhCogB+goBK/1XyhCLGPosAAABEGAw+7wSIAAQaDBYAprAINEPiThkmh6MOcAgkjuZwI04nNGS +OJI50Q/AINEPAAAAbBAEiSeInNsw+ZwwIAAQIDD5iQwBkAJCMPmEOQIAAFCwWVKw9KAMauABLDCK +IsmqwCDRD2iyEIon+qwwIgAAWTBYAUzSoNEPwCDRDysgB9og+wtBAAAQYDD7vBggABBoMFgCeMAg +0Q9sEAoZSpiZEIgg+0xrEAMQUDD4iBECAABJMPsWAigJAFIw+BYBICACUHACCYYASmMACYYASmEl +FBaKQCsKgvumJHAAECAw/wIABgCa3VAsIh2xzCwmHWQw1fQ0bCAMALTgYADKAABkMMWJOP0yCSAW +ADZglDuZ0I44neGUOPQ2CSAAEEgwLzBsyfKKNyupFPqiCSALADbgyKNYUxaJOBZKmyv6lvVijiAS +ADZgiDmUO5mAijiYoZQ4lDmJPPs0BSBgAH5wKjIW+osUCmABUDD6qg8AAEnSUC1SV/2qCgAAEGAw ++qIAIAEQaDBb9Y4kNhaIN4sw+frAIEACejD0NgwuAEBP8PSFFCCAAnvwn4mfiC5icfpSGCAAEGAw +/rsMAAEQaDBb9YApMEVokV9okmeKIs2n+iwAAgAAWHBZUlDJrSsiAg8CAA8CAGSwV/osAAIAAFhw +/AoDIAIQaDBYAM7AINEPAAAALVI5/aoKAAAQYDD6ogAgARBoMFv1amP/bS4hPLHuLiU8Y/7LAAAv +Uhmw/y9WGWP/lyhSGrCIKFYaY/+MAAArIAfaIPsLQQAAEGAw+7wYIAAQaDBYAghj/4wAbBAE2iD8 +PAACAABxcPsKACAAEGgwWAAn0qDRD2wQBCUpBIch+CEFL8AQSDD8ShEIAEBMsPp3DAQAIFVw9SUE +IIACWnD3JgEqAARZ0Kh3lyH3pQgCACBCcPQwGmCAAhCwdSMY8jwAAgAAGfDTD21JBQAChgBDYdJw +0Q8AAAcpDAlIFPqMCCIAADHw+ko2AgAAEPBtqQUAAoYARmH4TAwCACAacNMPbckFAgKGAEtj0nDR +DwAAbBAEiifAw/f6wCjgATAw+6wgIjwAOiApqRT2ogkgCAA2YGAAAgDAYIoiZKEzwCDRDy6pFI+p +970BAAIQQDD93EAgYAJzsP6lFCGgAlvw+6YJKgAF6tAvoRWr+5upHUnkLbYAKiIAKbwQ/Uu3G4AE +OqD9tgIqCQBisPq2ASIAADLwbYoFAASGAElh9WQWL5oANOCJOMBQ/jIJIBYANmCVO5ngjzie8ZU4 +9TYJIgAASXAoMGzIjoo3K6kUyLeKqcijWFJviTgaSfQt+pb0oo4gEwA2YIs5lTuZsIw4m8GVOCU2 +CYk8/TQFIGAAfnAqMhb6ixQKYAFQMPqqDwAAcFJQLUJX/aoKAAAQYDD6ogAgARBoMFv05yU2Fog3 +Hknf+zIAIEACejD1NgwuAEA/8PWFFCCAAnvwn4kvhggu4nH6QhggABBgMP67DAABEGgwW/TYKTBF +aZFxKEIZsIgoRhlj/sYsIAcYSXAMDEEMwxH+SW4SACBE8CkyOg7OCv7ilyTyATpgLTI5/tsBDgA3 +d1AuYBb/YRAgIAJpsPosAAABEGAwWAFQiif7CgMgABBgMP0KAyAEEHAw/jY5IEACUrBb9TLSoNEP +AAAA/wIAA/8uGmAvQhqw/y9GGmP+TC1COf2qCgAAEGAw+qIAIAEQaDBb9LBj/yAAAAAA+8wYIgAA +ULD9CgQgABBgMFgBV8Ag0Q8AbBAEhT71IwwBkAIhcMAgA0I50Q9sEAQFBkdpYkgYSyCFJyqCf/Vc +MCAAEEgw8oJ9IDkANqCHIYsgm3CKIJehmSCZISaCf7BmJoZ/jVGS0C0mASUmAPJWASGQAmCwbUkF +AAOGAExhwCDRDyKCgI8hhyCX8IYgn2GZIZkgLoKCsO4uhoJj/8QAAGwQBIk/GksEhT6VkPsyDiBw +AjDw9ElhEAAQQDDyVwwAABAQMPm2ASGQAilw+DYPIgUAOXD4Ng4qABGdEC+ifR5K35bxnj8ton2d +Piyif/amfSACAmMwLKZ/0Q8rooAprQKWsZk/KKKAmD4kooL2poAgAgIhMCSmgtEPAABsEASFIPJU +DAGQAhlwwCAEMjnRD2wQCiogB4gi9woDIAAQMDD8IhgqIAFQMPWCDGXABDqgGEj3/Uj3FAAgQTAr +QjoNrQr90pckAUXC4ClCOf2bAQ4BQG5QBQVH/jwQIj4AOWCKNH6hJo+hlqOIoJjwg6CfMZag9qYB +IcACGrApwAUqCnN6kSb/AgACALeBYIonjKz6rDAgABBYMPrNDAGQAmMwDcs5W/+30qDRDwCJOPwy +CSAQADZgljuZwI04nNGWOJY5iTcumRT3kgkhPwA3oNog/jBBIAEQYDD/MQgiAABp8FgAu8C0K0Y5 +iTwqGgAPAgAKmQKZPI9wDwIA/QqCIEYAL/AsMEH/AgAGAJHvEC4iHS7sAS4mHfkyDCAHADTgJjRs ++PqXIgBrYlAvMGz4NAUgFAA34Ik3K5kUyLcqkglkoAJYUYmJOBdJDiz6lvRyjiATADZgijmWO5mg +iziasZY4JjYJiTz8NAUgYAB+cCoyFvqLFApgAVAw+qoPAABL0lAtQlf9qgoAABBgMPqiACABEGgw +W/QBJjYWiDeLMPn6wCBAAnow9jYMLgBAT/D2hRQggAJ78C+GCS+GCC5ycfpCGCAAEGAw/rsMAAEQ +aDBb8/IpMEVokRL/AgAD/1SaYCpCGrCqKkYaY/6ZK0IZsLv7Rhkj/0yZYMAg0Q8s+r8MnAGcPGP+ +fQAAAPP+wWAAEDgwAAAtQjn9qgoAABBgMPqiACABEGgwW/PcY/9pLiE8se4uJTxj/t4AAAUPR/8C +AAIARRvgiTjInIg5ljuZgIo4mKGWOJY5H0ignxCOINog+xwAAAMQYDD/SnMfgAQ7oP8WAi4JADuw +/hYBIAIQaDBb/yOMJ4jM/MwwIAAQSDD8igwBkAJCMAqJOY2e+5wAAAAQSDD9zgwBkAJrcA7ZOWWf +5y48IP62BCAgAnrwnzmfOP62BSAAEBAw0Q/AINEPAAAA+6wYIAAQYDD9CgAiAABQsFgAW2P/UQAA +bBAEKCBsyIyJJyuZFMi1ipnIoVhRG4koFUigwED6IgkvlhBgMPNSjiARADZglCuZoIsomrGUKCQm +CYks/CQFIGAAfnAqIhb6ixQKYAFQMPqqDwDAAFJwLTJX/aoKAAAQYDD6ogAgARBoMFvzkSQmFogn +iyD5+sAgQAJ6MPQmDC4AQE/w9IUUIIACe/AvhgkvhgguUnH6MhggABBgMP67DAABEGgwW/OCKSBF +aJEpaJIa0Q8tMjn9qgoAABBgMPqiACABEGgwW/N6Y/+gLjIasO4uNhrRDwAALzIZsP8vNhnRDwAA +bBAELCAH+yIAIgAAUPD9CgEgBBBwMPwsQAAwEHgwWVAzHUgn+EjuEgAASrDwDQcAAhBYMABJYQBJ +YQBJYS8gB/4KACkABD0g8qwwLiABfDD+pgEvAAQ/4PiZAg4JAH3w+aYCLgkAR/D/pgAgIAJKsAIF +hgBJYwAFhgBJYSukFyakFtEPbBAE+Un0EBEQQDD/AgAAARAwMP8CAAoARp4QCzoRqaksklDTD2TA +qhxH7Ign9EsJDAAgYrAMuwovvRUt8q37vRggEAJiMPzWACFgAlrw+4YCLyAEOSD7SGoXgAQ84P7y +riYJAHXw/YYDJgkAPXD89q0mCQBd8PeFAyACAnOwLvauLpJQLZ0BLdyA/dC+IAICc7AullCLIgDR +BABsGgy7Apsi0Q/B1f8CAAv/uJ9QGEnOCDgKKIJ/2jD7LAAAABBgMAuAAIkiADEEAGoaCpkCmSLR +DyydAfXEPyAAEDgwJ8Q9J8Q8/MA+IgAAQfAI5BYBAgAdSKAu0oIAwQTwbBoP/xB4MA/PAw/uAQ7M +AizWggjkFi886A8PR/8CAAf/hhPgHUmWDf0KJ9arJ9azY/74AGwQBIk3KiAHKJkUiyIKCkH9kgkh +VAA2IBhHnWWxigykEahELEI6/wIABADbQyAcR5gpQjkMrAoswpf8mwEOANFmUP4wQSIAAFCw/zEI +IAEQYDBb/37AIMC0K0Y5iTwqGgD9+pcoCQBWcPk2DCIAX+JQLDBs/TQFIBYANyCJNyuZFPqSCSAJ +ADbgyKFYUFeKOBVH3P4yCS+WEEAw9FKOIBEANqCSO5rgjzie8SI2CJI5iTz4NAUgYAB+cCoyFvqL +FApgAVAw+qoPAABU0lAtQlf9qgoAABBgMPqiACABEGgwW/LNIjYWiDeLMPn6wCBAAnow8jYMLgBA +T/DyhRQggAJ78J+Jn4guUnH6QhggABBgMP67DAABEGgwW/K/KTBFaJF3+JJlYAAQEDDRD4o4izn0 +oCRvvxBoMJI7mrCMOIk8m8GSOPI2CSwAQG5w/TYMIAAQEDDRDwAALfq/DZ0B/TYMIAAQEDDRD/P+ +rGAAEGgwAAAtQjn9qgoAABBgMPqiACABEGgwW/KkY/9XLkIasO7+RhogABAQMNEPL0IZsP//Rhkg +ABAQMNEPiDjIixlJQ/k2CyAAEBAw0Q+NL/pJQBBAAljw+9YAIHACYLCcOJ05my/6NgsgABAQMNEP +AAAAAPusGCABEGAw/QoEIgAAULBb/zdj/7IAAGwQBIQohSrIQsAg0Q+KX/MmCyBAAkCwmKD6Jgkg +cAJJcJko+FYPIAAQEDDRDwAAAGwQBGQgkmQwj2RQjIoix434qAEAFAB6sJgiYAASAMiuWU4226D8 ++v8iAABQsFv5thpHDQQJRwyYEfxHCxgAIFIw+oI6ID4CaPANTRQMnAr8wpcqACVukCuCOR5HIvy6 +AQ4AHmbQ8A4HAgAAQrBt2QIASGEYRwiYoIIgnVAfRwjzpgMjgAQ4oP+mAiIJABNw8qYBICACErDR +D8Ag0Q/aIPwKACAwAlkwW/8AwCDRDwAAbBAEKiAHG0cBCipACqoQ/UfQGgkAWrCaMIYg9UcGEAQQ +ODD5RvIQMBBAMPg2AyeABDmg+TYCJgkAObCWMfAFBwAgAjDwAEZhAEZhAEZhLiAHLCEIDg5B8O4R +AAAQeDD7SOIcCQBzMPs2BiwJAGsw/DYEIEACEPACBIYAQmMABIYAQmH/NCAggAIQ8NEPAAAAbBAE +KCEEJSEFKSEChCD4jP8lwAQ9YPyIEQH+Akpw+SUCJAAgQTAFRAzwADBgABBAMCUhBSYhBPQiACAC +Ailw9QVPAf4CSbD1JQUpwAQ+YPVhInQAIEkwDFcRB0QMAASLCFhg8ASAD5QAuWAiIQUJIhGiUtEP +KCUF8//bYAAQKDBsEATAUQMkLAMiLgJSOaQi0Q8AAAEQGAEAAQAAAAAAAAAAAAAgA1iCIANY5SAD +WG8gA1jlIANYbyADWOUgA1iGIANYhiADWM0gA1i1IANYnQAAAAAgA2G0IANhtCADX74gA2G0IANf +viADYZEgA2FpIANfviADYJkgA1++IANfviADYJAgA1++IANhtCADX74gA1++IANhtCADX8sAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAgA6b5IAOm0SADpuggA6boIAOm6CADpuggA6boIAOm6CADqJ8g +A6hjIAOm6CADpuggA6boIAOm6CADpuggA6boIAOoFSADp6wgA6dSIAOnPSADpyggA6cWAwEAAgAA +AAAgBQEjIAUCDSAFAqAgBQEjIAUCmCAFAn0gBQEjIAUBIyAFASMgBQJiIAUBIyAFASMgBQEjIAUB +IyAFASMgBQEjIAUCVSAFAkggBQEjIAUBIyAFASMgBQEjIAUBIyAFASMgBQEjIAUBIyAFASMgBQEj +IAUBIyAFASMgBQEjIAUBIyAFAUogBQEjIAUBRCAFAUQgBQEjIAUBRCAFAUQgBQIlIAUBRAAAAAAA +AAAAAAAAACAFH4ggBR+IIAUe6iAFH4ggBRvtIAUfgCAFH2AgBRvtIAUb7SAFG+0gBRvtIAUb7SAF +Hs4gBR+IIAUb7SAFHs4gBR+IAAAAAAAAAAAAAAAAIAUs5yAFK0sgBS97IAUvMyAFLvMgBS65IAUu +kyAFK6MgBS5rIAUuKyAFLcwgBS11IAUtKyAFLQMBEBgBAAIAAAEQGAEAAgAAAAAAAAAAAAAgBe/H +IAXrSSAF75sgBe9vIAXvQiAF7y0gBetrIAXrgiAF7xQgBeu3IAXroyAF62sgBeu3IAXrayAF62sg +BetrIAXvxwAAAAAAAAAAAAAAAAAAAAAgBjssIAYy2CAGMoAgBi9sIAYq+AAAAAAAAAAAIAYywCAG +MrogBjK6IAYyuiAGMsAgBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYy +uiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6 +IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrog +BjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAG +MrogBjK6IAYywCAGMrogBjK6IAYyuiAGMsAgBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYy +wCAGMrogBjK6IAYyuiAGMsAgBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYywCAGMrogBjK6 +IAYyuiAGMsAgBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYyuiAGMsAg +BjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYyuiAGMsAgBjK6IAYyuiAG +MrogBjLAIAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYy +uiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6 +IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYyuiAGMrog +BjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAG +MrogBjK6IAYyuiAGMrogBjLAIAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYyuiAGMsAgBjK6IAYy +uiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6 +IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrog +BjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAG +MrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYywCAGMrogBjK6IAYy +uiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6 +IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrog +BjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjK6IAYyuiAGMrogBjLAAAAAAAAA +AAAAAAAAIAYzFSAGN3kgBjdeIAY3SiAGNy8gBjcbIAY2+iAGNuYgBjbFIAY2siAGNpkgBjaGIAY2 +bSAGNlogBjZBIAYzESAGNicgBjYUIAY1+yAGNecgBjXMIAY1iyAGNUsgBjWLIAY1SyAGNTcgBjUc +IAYzESAGMxEgBjMRIAYzESAGNQkgBjMuIAYzESAGMxEgBjMRIAY07CAGNNMgBjTDIAY0rCAGMxEg +BjSZIAY0fyAGNGwgBjRSIAY0PyAGNCcgBjQUIAY0ASAGM6UgBjMRIAYzESAGMxEgBjMRIAYzESAG +MxEgBjNzIAYzYyAGM0sAAAAAIAY7dyAGO4EgBj2KIAY9XiAGPVcgBj1QIAY9SSAGPUIgBj07IAY9 +NCAGPS0gBj0jIAY9GSAGPQEgBjzWIAY8rSAGPKQgBjyJIAY8fyAGPHEgBjxhIAY8WiAGPEQgBjw9 +IAY7aCAGPBQgBjwKIAY8ACAGO/kgBjvyIAY74iAGO6ogBjujIAY7nCAGO44AAAAAAAAABQAAAAUA +AAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAAIAbtuCAG6xQgBumoIAbnWCAG +5QAgBtjYIAbZ0CAG4zggBthMIAblxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUoAw8IEqWog46T +kgAAAABSVgAAEAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZm91bmQgYWRkaXRpb25hbCBj +b25maWd1cmF0aW9uIGFmdGVyIFtmaW5pXQoAADAAAABmY29lAAAAAHZuaWNfaWQAdmxhbgAAAAB0 +b3MAZXRoZXJ0eXBlAAAAbWFjbWF0Y2gAAAAAbXBzaGl0dHlwZQAAZnJhZ21lbnRhdGlvbgAAAHNy +dnJzcmFtAAAAAGZjb2VtYXNrAAAAAGNvbXBhY3QAcGZfdmYAAABvdXRlcl92bGFuAABiYXNpY3Zp +cnR1YWwAAAAAZ2xiX2tleQBnbGJ2Zl9rZXkAAABwZnZmX2tleQAAAABpZHh2Zl9rZXkAAABzeW5t +YXBlbgAAAABzeW40dHVwZW5pcHY2AAAAc3luMnR1cGVuaXB2NgAAAHN5bjR0dXBlbmlwdjQAAABz +eW4ydHVwZW5pcHY0AAAAb2ZkbWFwZW4AAAAAdG5sbWFwZW4AAAAAdG5sYWxsbGtwAAAAaGFzaHRv +ZXBsaXR6AAAAAGxhbgB3YW4AY2x1c3RlcgBtYW51YWwAAHRwX3BpbwAAdHBfdG1fcGlvAAAAbmlj +X3ZtAABuaWNfdW0AAG5pY191bV9pc2dsAG5pY19oYXNoZmlsdGVyAABvZmxkAAAAAHJkZHAAAAAA +cmRtYWMAAABpc2NzaV9pbml0aWF0b3JfcGR1AGlzY3NpX3RhcmdldF9wZHUAAAAAaXNjc2lfaW5p +dGlhdG9yX2ZvZmxkAAAAaXNjc2lfdGFyZ2V0X2ZvZmxkAABmY29lX2luaXRpYXRvcgAAZmNvZV90 +YXJnZXQAcG9mY29lX2luaXRpYXRvcgAAAABwb2Zjb2VfdGFyZ2V0AAAAaXNjc2lfdDEwZGlmAAAA +AGlzY3NpX2luaXRpYXRvcl9jbWRvZmxkAGlzY3NpX3RhcmdldF9jbWRvZmxkAAAAAHRsc2tleXMA +Y3J5cHRvX2xvb2thc2lkZQAAAABwcHAAZGNieAAAAABiMmIAc29ja2V0bnVtAAAAY2VlAGllZWUA +AAAAYXV0bwAAAABhbl9kaXMAAHBkbGl0ZV9kaXMAACADGrgABAAAAAAEAAAEAAD/AgAAAAAAAAAA +AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AgAAAAAAAAAAAAAAAQAC/wIA +AAAAAAAAAAAAAAAAAv8CAAAAAAAAAAAAAAAAABYAAAAAAAAAAAAAAAAgBtgQAAAAACAG12AgBtTw +IAbTyCAGsnAgBkSkIAYqUCAGKTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBJGMIASeWCAEnlgg +BJ5YIASuICAEykggBNhAIAThnCAEjoQgBIv4IASB3CAE//QgBH+IIAR8fCAGKQQgBifUIAYhICAE +nlggBiBMIAYefCAGHbAgB4LYIAQKXCAEYvwgBviUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAgA1b4IAM/xCADUHQgA030IANMfAAAAAAgA0oYIANWMAAAAAAgBHN0AAAAAAAAAAAAAAAA +IAOmjAAAAAAAA///AAAD/wAAAD8AAAAPIAc9RCAHPHwgB5Q8IAc8bCAHPKggBzvAIAc9LCAHO5Ag +B5QoIAc8WP8YMGBgAAAAAAECAwAAAAAAAAAAAAAAACAG7mQgBI/cIADc0AAAAAAAAACBAAAAAAAA +AAAAAAAAAAECAwICAwMAAgMFAwMFBSAEZhwgBGeoIARnRCAEZ7wgBGY4AAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAACAEZswAAAAAAAAAAAAAAAAAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAAS +AAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAAAAAAAQAAAAEAAAACAAAEAAA +ACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgA +AAD////////wAP///////+AA////////wAD///////+AAP///////wAA///////+AAD///////wA +AP//////+AAA///////wAAD//////+AAAP//////wAAA//////+AAAD//////wAAAP/////+AAAA +//////wAAAD/////+AAAADAxMjM0NTY3ODlhYmNkZWZBQkNERUYAAAAAAAAAAAAAQUJDREVGR0hJ +SktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLwAA +AAAAAAAAAAAAAAAAAAAgAIQsAAEAACAAhAwABQABIACD8AADAAUgAIPQAAcAAGOCU2MAAAAA//// +////AAAAJhoLCggrMkECREADLQAAAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAU +AAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAA +CAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAD////////wAP///////+AA//////// +wAD///////+AAP///////wAA///////+AAD///////wAAP//////+AAA///////wAAD//////+AA +AP//////wAAA//////+AAAD//////wAAAP/////+AAAA//////wAAAD/////+AAAAAAAAAAAAAAE +AAAABAAAAAgABAQIAAAAAAAAAAAAAAAA//8BA/8C////AAAAAAAAAAAEBAgABAQIAAQECAAEBAgA +BAQIAAdDAAAAAAAAAAAAACEACQCBAEEAIQAJACEACQCBAEEAgQBBAIEAQQCBAEEAIQAJAIEAQQAh +AAkAIQARAIEAQQCBAEEAIQAJAIEAQQAhAAkAIQAJAQEAQQCBACEAgQAhABAQYQEBAIEBAQCBAwIB +AAQAAAAQIEAAAAAAAAQAAgABAACAAEAAIAAQAAggQIAAAAAAAAAAAAAAAAAAIAMJkAAAAAAgAxN4 +AAAAACADCZQAAAABIAMUIAAAAAIgAwmcAAAABCADCaQAAAAIIAMJrAAAABAgAxQoAAAAICADCbAA +AABAIAMJvAAAAIAgAwnIAAABACADCdQAAAIAIAMJ5AAAIAAgAwnwAABAACADCfwAAIAAAAAAAAAA +AAAAACocAAAqPAAAKlwAACp8CAcEAwoJAgAAAAAAAAAAAABAAEAAEAAQAAgACAAEAAIAAAAAAAAA +AAAAAAAAAAAAAAACBAAAAEQAAAAEAAAAQCAG8gggBvHAIAbwkCAG7zQgBu7wIAbuxCAG7xwAAAAA +AAACAAAABAAAAAgAWWVzADAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egAAAABu +b25lAAAAAGFsbAAqAAAAZGlzYWJsZWQAAAAAZW5hYmxlZAAweAAATkEAAFYwAABWMQAAVjIAAFYz +AABWNAAAVjUAAFY2AABWNwAAVjgAAFY5AABWQQAAVkIAAFZDAABWRAAAVkUAAFZGAABWRwAAVkgA +AFZJAABWSgAAVksAAFZMAABWTQAAVk4AAFZPAABWUAAAVlEAAFZSAABWUwAAVlQAAFZVAABwb3J0 +AAAAAHByb3RvY29sAAAAAGdsb2JhbAAAZnVuY3Rpb24AAAAAZmluaQAAAAByZWcAZmlsdGVyTW9k +ZQAAZmlsdGVyTWFzawAAdm5pY01vZGUAAAAAcnNzX2dsYl9jb25maWdfbW9kZQByc3Nfa2V5bW9k +ZQByc3NfZ2xiX2NvbmZpZ19vcHRpb25zAABzZ2VfdGltZXJfdmFsdWUAdHBfcG1yeAB0cF9wbXJ4 +X3BhZ2VzaXplAAAAAHRwX3BtcnhfZmxhZ3MAAAB0cF9ucnhjaAAAAAB0cF9wbXR4AHRwX3BtdHhf +cGFnZXNpemUAAAAAdHBfbnR4Y2gAAAAAdHBfbXR1cwB0cF90Y3B0dW5pbmcAAAAAdHBfdGltZXJy +ZXMAdHBfdGltZXJ2YWxzAAAAAHRwX2JhY2tvZmZ2YWxzAABzY2hlZF9pb3F0eF9icF9wcmlvcml0 +eQBwY2llX21hX3JzcF90aW1lcnZhbHVlAABwbF90aW1lb3V0X3ZhbHVlAAAAAG1lbWZyZWVfY29u +ZmlnAABiYXNlX21hY19wZgBiYXIydGhyb3R0bGVjb3VudAAAAGNwbHR4ZGF0YV9tZW1hbGlnbgAA +bWNfcGQAAABvZmxkX2ZsYWdzAABtY19tb2RlX2JyYwBtYwAAbnZmAHd4X2NhcHMAcl9jYXBzAABu +aXFmbGludAAAAABuZXEAbnFwY3EAAABuZXRoY3RybAAAAABudmkAcnNzbnZpAAByc3Nuc2VjcmV0 +AABuZXhhY3RmAG5yYXdmAAAAY21hc2sAAABwbWFzawAAAG5ldGhvZmxkAAAAAG5yb3V0ZQAAbmNs +aXAAAABuZmlsdGVyAG5zZXJ2ZXIAbmhhc2gAAAB0cF9sMnQAAHRwX2RkcAAAdHBfZGRwX2lzY3Np +AAAAAHRwX3N0YWcAdHBfcGJsAAB0cF9ycQAAAGlzY3NpX250YXNrAGlzY3NpX25zZXNzAGlzY3Np +X25jb25uX3Blcl9zZXNzaW9uAGlzY3NpX25pbml0aWF0b3JfaW5zdGFuY2UAAABpc2NzaV9tYXhf +c2dlAAAAcHBtX21heF96b25lcwAAAHBwbV96b25lX3JhbmdlMABwcG1fem9uZV9yYW5nZTEAcHBt +X3pvbmVfcmFuZ2UyAHBwbV96b25lX3JhbmdlMwBjb2lzY3NpX250YXJnZXQAY29pc2NzaV9udGFz +awAAAGZjb2VfbmZjZgAAAGZjb2VfbnZucAAAAGZjb2VfbnNzbgAAAGZjb2VfbmZjYgAAAGRjYgBk +Y2JfYXBwX3RsdgBkY2JfZGNieF9wcm90b2NvbAAAAGJnX21lbQAAbHBia19tZW0AAAAAaHdtAGx3 +bQBkd20AZGVib3VuY2V0aW1lAAAAAGFuX2FlY190aW1lAGFlY19yZXRyeV9jbnQAAAB2ZXJzaW9u +AGNoZWNrc3VtAAAAAFNlc3Npb25UeXBlAE9GTWFya2VyAAAAAElGTWFya2VyAAAAAERhdGFEaWdl +c3QAAEhlYWRlckRpZ2VzdAAAAABFcnJvclJlY292ZXJ5TGV2ZWwAAEltbWVkaWF0ZURhdGEAAABE +YXRhUERVSW5PcmRlcgAARGF0YVNlcXVlbmNlSW5PcmRlcgBJbml0aWFsUjJUAABNYXhDb25uZWN0 +aW9ucwAATWF4UmVjdkRhdGFTZWdtZW50TGVuZ3RoAAAAAEluaXRpYXRvck5hbWUAAABJbml0aWF0 +b3JBbGlhcwAARGVmYXVsdFRpbWUyV2FpdAAAAABEZWZhdWx0VGltZTJSZXRhaW4AAE1heEJ1cnN0 +TGVuZ3RoAABGaXJzdEJ1cnN0TGVuZ3RoAAAAAE1heE91dHN0YW5kaW5nUjJUAAAAVGFyZ2V0TmFt +ZQAAVGFyZ2V0QWxpYXMAVGFyZ2V0QWRkcmVzcwAAAFRhcmdldFBvcnRhbEdyb3VwVGFnAAAAAEF1 +dGhNZXRob2QAAFNlbmRUYXJnZXRzPUFsbABDSEFQX0EAAENIQVBfSQAAQ0hBUF9DAABDSEFQX04A +AENIQVBfUgAARGlzY292ZXJ5AAAATm9ybWFsAABOb25lAAAAAENSQzMyQwAAQ1JDMzJDLE5vbmUA +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 +IAMK7AAAABAgAwr0AAAAESADCtQAAAAAIAMK2AAAAAEgAwrcAAAAAiADCuQAAAADAAAAAAAA//8A +AAAAAAD//yADClQAAAEAIAMKYAAAAIAgAwpwAAAAQCADCoAAAAAgIAMKkAAAABAgAwqgAAAACCAD +CqwAAAAEIAMKuAAAAAIgAwrEAAAAAQAAAAAAAAAAIAMKBAAAAAAgAwoMAAAAASAJOuAgCTqaIAk6 +1iAJOtYgCTqaIAk6miAJOuAgCTrgIAk6miAJOuAgCTqaIAk64CAJOtYgCTqaIAk6miAJOpogCTqa +IAk6miAJOuAgCTqaIAk6miAJOpogCTqaIAk6miAJOuAgCTrgIAk64CAJOuAgCTrgIAk64CAJOuAg +CTrgIAk6miAJOpogCTqaIAk6miAJOpogCTqaIAk6miAJOpogCTqaIAk6miAJOpogCTqaIAk6miAJ +OpogCTqaIAk6miAJST0gCUk9IAlJJyAJSRkgCUlAIAlJEyAJSRMgCUkTIAlJQCAJSRMgCUkNIAlJ +QCAJSRMgCUkTIAlJEyAJSQ0gCUlAIAlJQCAJSUAgCUlAIAlJQCAJSUAgCUlAIAlJQCAJSUAgCUlA +IAlJQCAJSUAgCUlAIAlJQCAJSUAgCUlAAAYhegAAAAUAAAAEAAAAAQAAAFIAAAATAAAAGwAAABYA +AAAQAAAAAAAAAAAAAABSAAAAWwAIGzIAAAAGAAAADAAAAAIAAABnAAAAAAAAAB0AAAAUAAAAEAAA +AAAAAAAAAAAAVwAAAGMACYloAAAABwAAAAIAAAACAAAA/QAAAAMAAAAeAAAAGgAAABAAAAADAAAA +AAAAAFsAAABoAAoh/wAAAAcAAAACAAAAAgAAAGcAAAAcAAAAHgAAAB4AAABQAAAAAAAAAAIAAABc +AAAAbAAKupUAAAAIAAAACgAAAAMAAAD1AAAAAQAAAB4AAAAaAAAAEAAAAAEAAAAAAAAAXQAAAG0A +CyBPAAAACAAAAAoAAAADAAAAagAAAAIAAAAeAAAAGgAAABAAAAACAAAAAAAAAF4AAABuAAun8QAA +AAgAAAAKAAAAAwAAACkAAAACAAAAHwAAABwAAAAQAAAAAgAAAAIAAABfAAAAcQAMNQAAAAAIAAAA +CgAAAAMAAABSAAAAEwAAABsAAAAbAAAAUAAAAAAAAAAAAAAAYQAAAHMADELzAAAACAAAAAoAAAAD +AAAA9QAAAAEAAAAbAAAAGwAAABAAAAABAAAAAgAAAGEAAABzAAy3NgAAAAkAAAAGAAAAAwAAAP0A +AAADAAAAHAAAABwAAAAQAAAAAwAAAAAAAABkAAAAcAANHO8AAAAJAAAABgAAAAMAAAApAAAAAQAA +ABwAAAAcAAAAUAAAAAEAAAACAAAAZAAAAHEADj3VAAAACQAAAAYAAAADAAAAKgAAAB8AAAAfAAAA +HwAAABAAAAAAAAAAAgAAAGYAAAByAA7VvgAAAAoAAAAJAAAABAAAAGoAAAACAAAAHAAAABwAAAAQ +AAAAAgAAAAAAAABmAAAAdwAPQkAAAAAKAAAACQAAAAQAAAD9AAAAAgAAAB0AAAAdAAAAUAAAAAIA +AAACAAAAZgAAAHcAD7xSAAAACgAAAAkAAAAEAAAAKQAAAAEAAAAdAAAAHQAAAFAAAAABAAAAAgAA +AGsAAAB4ABBGBAAAAAoAAAAJAAAABAAAAGcAAAAZAAAAHgAAAB4AAABQAAAAAgAAAAIAAABrAAAA +eQcAOwACADgABAM7AQAAAAABNgFsAZYA8AEgAVMA4QExAWEAvADkAQsA9QEiAUkAxgDrAQ8AwgDq +ARMAnQC/AN4AywDtAQ0AqgDJAOQAowDEAOAAgQCiAL0ArwDMAOMAlACwAMYAiwCoAL8AAACBAJ0A +mgCzAMcAgQCbAK8AbgCPAKUAAAAAAAAAiQCfALEAbQCIAJsAAABhAHIAAAAAAAAAegCPAJ8AAABy +AIcAAAAAAAAAAAAAAAAAAAAAAAAAAAD7ASYBagDZAP8BNgDuAS4BjACrANMBEwDWAPkBKgC5ANoB +CgC3AOIBMACMAK0A4QC6ANkBBgCiAL4A5wCWALcA6gBlAIwAugCkAL8A5gCOAKgAzQB6AJgAwwAA +AAAAlACRAKoAzQB7AJUAtwAAAHoAowAAAAAAAACAAJgAuABkAIEAowAAAAAAfQAAAAAAAABtAIYA +pQAAAGYAjgAAAAAAAAAAAAAAAAAAAAAAAAAAAQABKQFVAM4A8wEVAMcA7gEWAKEAwwDgAM0A7QEM +AKsAygDjAKIAwQDdAH0AngC3AK0AyQDfAJMArQDBAIYAogC5AAAAAACLAJcArgDAAH0AlgCpAEwA +gQCZAAAAAAAAAIUAmgCrAGIAfwCTAAAAAAAAAAAAAAAAAHYAiQCZAAAAVgB5AAAAAAAAAAAAAAAA +AGYAegCJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3wEDATEAvwDfARAAvADkASwAjwCvAOIA +vQDcAQcApAC/AOcAlgC2AOYAVwCGALQApAC/AOQAjgCmAMoAdgCTALwAAAAAAAAAjwCnAMgAeACR +ALIAAABtAJkAAAAAAAAAfACUALIAWgB6AJgAAAAAAAAAAAAAAAAAZwCAAJ4AAAAAAIEAAAAAAAAA +AAAAAAAAAABqAIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADbAQABGwC3ANcA8ACwAM8A6ACQ +AK4AxgCzAM4A5ACZALIAxgCNAKcAvAAAAAAAjQCZAK8AwACAAJcAqQAAAHwAlAAAAAAAAACFAJkA +qABaAHsAjwAAAAAAAAAAAAAAAAB0AIcAlQAAAAAAAAAAAAAAAAAAAAAAAABhAHUAgwAAAAAAAAAA +AAAAAAAAAAAAAAAAAGAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwA6wEYALIAzwD2AKkA +zAEAAIIAoQDKAK0AyADtAJgAsQDVAIMAoADHAAAAAACWAJUArQDOAIAAmAC5AAAAdQCdAAAAAAAA +AH8AlgC0AFUAfQCfAAAAAAAAAAAAAAAAAGYAgACdAAAAAAB9AAAAAAAAAAAAAAAAAAAAYgCGAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAABfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/w//D/wA/w/4 +CdsP8A+lD+AJmQ/AAJkPgAAADwAAAA/8D/wP+AX8D/APtA/gBbQPwAC0D4AAAA8AAAAMAAAAD8AA +AA7AAAAPgAAADoAAAA8AAAAOAAAADAAAAAEAAAAAATiAAABoKgAATiAAAYagAAGGoAACCNUAAgjV +AAAAKAAAADIAAQRqAABoKgAASmcAAYagAAGGoAACCNUAAgjVAAAAKAAAADIAAVsBAABoKgAAUCAA +AgjVAAGGoAACCNUAArZxAAAAJgAAADIAASluAABoKgAATSkAAgjVAAGGoAACCNUAArZxAAAAJgAA +ADIAAQRBAABoKgAASmcAAgjVAAGGoAACCNUAArZxAAAAJgAAADIAAXQGAABsgQAAVAEAAosKAAII +1QACiwoAArZxAAAAHgAAAC0AAUWFAABsgQAAUWEAAosKAAII1QACiwoAArZxAAAAHgAAAC0AASFa +AABsgQAATuoAAosKAAII1QACiwoAArZxAAAAHgAAAC0AAQRqAABsgQAATJcAAosKAAII1QACiwoA +ArZxAAAAHgAAAC0AAYagAABvmwAAVs4AAosKAAII1QACiwoAAw1AAAAAHgAAACgAAVs4AABvmwAA +VHUAAosKAAII1QACiwoAAw1AAAAAHgAAACgAATiAAABvmwAAUjwAAosKAAII1QACiwoAAw1AAAAA +HgAAACgAARwYAABvnAAAUCEAAosKAAII1gACiwoAAw1AAAAAHgAAACgAAWx0AABy4wAAV2MAAw1A +AAKLCgACiwoAAw1AAAAAGwAAACMAAUtSAABy4wAAVVgAAw1AAAKLCgACiwoAAw1AAAAAGwAAACMA +AS+2AABy4wAAU2UAAw1AAAKLCgACiwoAAw1AAAAAGwAAACMAARhZAABy4wAAUYgAAw1AAAKLCgAC +iwoAAw1AAAAAGwAAACMAAXq6AAB2XwAAWj4AAw1AAAKLCgACiwoAAw1AAAAAGQAAACMAAVsrAAB2 +XwAAWFYAAw1AAAKLCgACiwoAAw1AAAAAGQAAACMAAUFeAAB2XwAAVoEAAw1AAAKLCgACiwoAAw1A +AAAAGQAAACMAASmTAAB2YAAAVMEAAw1BAAKLCwACiwsAAw1BAAAAGQAAACMAAREqAABvmwAAT90A +AgjVAAII1QACiwoAAw1AAAAAHgAAACgAARcEAABsgQAATiAAAosKAAKLCgACiwoAAw1AAAAAGwAA +ACMAAAAAK2gjgxhqDQYLKgAAAAAAAAAAADIAAAPoAAAAKAAATiAAAAAAAAPQkACYloAAD0JAAJiW +gAAAHCAAAABLAD0JAAAD0JAAmJaAAQEAAAMDAgIFBQQEBwcGBgAAADIAAAPoAAAAZAAAw1AAAAAA +AAPQkAPQkAAATEtAA9CQAAAAHCAAAABLAD0JAAAPQkAjw0YAAwIBAAcGBQQLCgkIDw4NDAAAADIA +AAPoAAAACgAAAfQAAAAAAAAD6ACYloAAD0JAAJiWgAAAHCAAAABLAD0JAAAD0JAAmJaAAwIBAAcG +BQQJCQgICwsKCgAAAAAAAAAAAAEAEAARAB4ADQASAAcAHwAOAAsAEwAVABsACAAXACAADwAdAAwA +BgAKABQAGgAWABwABQAJABkABAAYAAMAAgABAHsAdQD7APUARQBvAH0AdwBfAGkAxQDvAKMAPwD9 +APcAuwA5AN8A6QDPAJ0ARwBxAA8AWQAlAL8AEwBjAH8AeQBtAF0APQC5AJsADQBhAGsACwAJAFEA +HwAxAFMAxwDxACEAtQCPANkArQAzAKUAQQBVAJcAkwDjACkAyQD/APkA8wDDAO0A3QDnACMAvQA7 +ALcATwAdAI0A1wCRAOEA6wDbABsAiwCJAIcArwDRAJ8ANQAtALEA0wAXAKcASQBzAEMAZwChADcA +zQBXABEAWwCZAAcALwCzAKsAlQAnAMEA5QBNANUAGQCFACsAFQBlAMsABQCpAEsAgwADAIEAAAD6 +APQAfAB2AMQA7gD8APYA3gDoAEYAcAAkAL4AfgB4ADwAuABgAGoAUAAeAMYA8ACOANgApABAAJIA +4gD+APgA7ADcALwAOgAcAIwA4ADqAIoAiADQAJ4AsADSAEgAcgCgADYAEABaAC4AsgAmAMAA1AAY +ABQAZACoAEoAgAB6AHQARABuAF4AaACiAD4AugA4AM4AnAAOAFgAEgBiAGwAXACaAAwACgAIADAA +UgAgALQArAAyAFQAlgAoAMgA8gDCAOYAIgC2AE4A1gCQANoAGgCGAK4ANAAsABYApgBCAGYAzABW +AJgABgCqAJQA5ABMAIQAKgDKAAQAggACAAEAAwACAAQAAAAAAAAAAAABAAIAHAAbABYAFQAeAB0A +GAAXAAwACwAQAA8AIAAfABoAGQAUABMACgAJAA4ADQASABEACAAHAAYABQAEAAMAAQAAAAIABAAA +AAAAAAAAAAAwBAAAMBAAAFncAABagAAAWoQAAFqIAABajAAAWpAAAZQwAAAQJAAAEDAAABA8AAAQ +3AAAEQwAAHssAAB7NAAB4owAAeaMAAHqjAAB7owAAfKMAAH2jAAB+owAAf6MAACNzAAAjoAAAH50 +AACP3AABkVgAAZJwAACP/AAEExwABBMYAAQTEAAEkxwABJMYAASTEAAAd+AAAHfkAAB39AAAeAQA +AZw8AAEQdAABEIQAAJQIAACYXAAAlgwAAJYUAACWIAAAliwAAJbEAADQKAAAkAgAAwjcAANI3AAD +iNwAA8jcAAMI5AADSOQAA4jkAAPI5AABkFQAAGAcAAGg2AABkJAAAHfgAAB35AAAd/QAAHgEAAB4 +2AAAeOAAAHj0AAUAeAAFCHgABRMIAAGUBAAB48AAAefAAAHrwAAB78AAAfPAAAH3wAAB+8AAAf/A +AAGUDAAAAAAAAAAAAAAAAAAAMAC///9AAAAwCL///0AAAZQQn////wABlDQAAAAQAAGUCJ//4/8A +AZQ4AAAAEAAAECjh////AAAQLOH///8AABA0Af///wAAEDgB////AAAQQAAEAAAAABEQAP///wAA +ERQA////AAB7KAB9/+IAAHswP//u/wAAezgAAAABAAB7QD//7v8AAHwkAH3/4gAB4ogACAAAAAHm +iAAIAAAAAeqIAAgAAAAB7ogACAAAAAHyiAAIAAAAAfaIAAgAAAAB+ogACAAAAAH+iAAIAAAAAI3I +////8AAAjdD////wAACOfAAAAPAAAI6EAAAA8AAAfnB/v/9/AAB+eH+//38AAH4AAsAAAAABkVQB +////AAGRnAH///8AAI/YA3///wAAj/j/////AAQTFAAAAAcABBMMAAAACwAEkxQAAAAHAASTDAAA +AAsAAHfcAAAAAwAAd/T/////AAB4BAAAAAMAAZw4AAHAQAABnPgAAcBAAACQBAAAAD4AARB4AP// +/wABEHwA////AAEQiAAAAAAAAJQEAAD//wAAlBAAAP//AACYVAAAAf8AAJhYAAAB/wAAlggAAAAA +AACWHAD///8AAJYkAP///wAAligA////AACWMAD///8AANAgAAAABwAA0CQAAAAHAAMI2AAAAAMA +A0jYAAAAAwADiNgAAAADAAPI2AAAAAMAAwjkAAAAAwADSOQAAAADAAOI5AAAAAMAA8jkAAAAAwAB +kFAAAADvAAGg1AAAAYMAAZCMADgAAAABkJgAOAAAAAUAdAAAAAcABQBwAAAABQAFCHQAAAAHAAUI +cAAAAAUABRMEAAAAASADFFAgCOkkIAMUVCAI+iggAxRgIAj5OCADFGwgCPiEIAMUeCAI+DQgAxSM +IAj3UCADFJggCPakIAMUsCAI9TggAxTAIAj0ICADFMggCPP4IAMU3CAI89AgAxTsIAjzoCADFPgg +CPKEIAMVACAI8lwgAxUUIAjyKCADFSAgCPDEIAMVKCAI8BwgAxU4IAjvGCADFUQgCO4IIAMVVCAI +7QAgAxVkIAjr1CADFXwgCOikIAMVlCAI6FggAxWoIAjoGCADFbggCOfwIAMVxCAI51wgAxXYIAjn +NCADFewgCOY0IAMV9CAI5gwgAxYAIAjlHCADFgwgCOQcAAAAAAAAAAAgAxYQIAjj3CADFhQgCONg +IAMWHCAI4yggAxYkIAji8CADFjAgCOK4IAMWNCAI4oAgAxY8IAjiSCADFkggCOIQIAMWTCAI45gg +AxZUIAjh2CADFmAgCOGgIAMWaCAI4WggAxZwIAjhMCADFnggCN5QIAMWgCAI4OAgAxaMIAjg2CAD +FpQgCOCgIAMWnCAI4GggAxakIAjgMCADFqwgCN/4IAMUKCAI2/AgAxa0IAjbuCADFrwgCNuAIAMW +xCAI20ggAxbUIAjbECADFtwgCNrYIAMW5CAI2qAgAxbsIAjaeCADFvggCNpQIAMXBCAI2iAgAxcc +IAjZ+CADFzggCNnQIAMXSCAI2aggAxdYIAjZgCADF2ggCNlYIAMXeCAI2TAgAxeIIAjZCCADF5gg +CNikIAMXqCAI2OAgAxe4IAjYfCADF8QgCNhUIAMX0CAI2CwgAxfcIAjX8AAAAAAAAAAAIAMX6CAI +1rwgAxfsIAjU7CADF/ggCNQIIAMYDCAI09QgAxgUIAjToCADGCAgCNNsIAMYJCAI0zggAxgoIAjT +BCADGCwgCNLUIAMYPCAI0nQgAxhIIAjRKCADFOQgCNF0IAMYWCAI0QAgAxhgIAjQ2CADFDQgCP0g +IAMUPCAI/FQgAxQgIAj7pCADFEggCPsAH/+nxB//kiwgC2NQIAsBEAAAIEAAAYagIAsBYCALAeAA +AEANIAsBMCALAbAgCwIgIAsCQAAAQRcAAPADAABBBwAAQYwAAEGIAABBhgAAgAAAAEGBAACoGQAA +qBoAAMMAAACoGwAAqBwAAKgXAAD//wAAEAQAAOWfAAAfEQAA7gkAAP/+AADq/yALAmAAAP8AAACo +GCALAqAAAGANAA9CQCALAuAAAN6tIAsDACALA1DhAF4A/v/+/wEAAAABAAEAIDAAAAAAMNQgCwPQ +AABhqAAA/+kgCzAgH/+ZqCALMEDhAHIAH/+ZLOEEEgAAixRA4QP+AAAEAEjhBAIAAAQAIR//kDCG +EAAAAAQAQIAAAACAFAADgBYAA4ASACOAEbIDgBAABQAq8S8AAYafAArxLyALeyAABAAIIAswYB// +mHAgB7WwH/+rhCALe+DgAAAA4QB2ACALe1AgC3uQIAswkB//m3Af/5r44QGaAAIAAAAAAZ4M4QGe +AAABnnQAAZ6sAAGe2AABnvAAAZ8cH/+beB//mAAAAf//AAGfTAABn5wAAZ+w4QB6ACALMbAgCzIA +IAsyYAAAD/8/////IAsywCALMzAgCzNwIAszsCALM/AgCzQwIAs0cCALNLAgCzTwIAs1MB//mZQg +AxIg4QSSACADEcD/AP//AAwAAIAAAB+AAAA/H/+AsB//mZz/wP//ABAAAB//q5QAAAgAAKYMACAL +NbAgCzYQIAt+ICALNXAgC32wIAt80CALfRAgC31g4QAuAAQAAAAf/5JU4QBWAAKAUACAAACAAABA +AP/xAIAB8AAAjgHggAAAHwAgCAAAIAgY5AAAFUAgCAWg4QGSAOEADgAAAQAAAAIAAAB/AEAAAwAA +AIIAgADBAMD//yP/AADIABAgASAf/5jgH/+rsOEAfgDhAI4APAAAAP//v/9QaOhHkgAAAPAA8ADf +v//7IAAABH/3//+AAEIA//f/fwAGAAD/AAAAAEkkkgAAfhgQARABAAB+QCABIAEVFRUVhCGEIRAQ +EBDhAY4AAAC+fwQEQYDhAM4ARERERIiIiIjMzMzM4QCOBOEAjgjhAI4M4P/+ACAIEkQAAAjAgAHE +EcQRxBEA/wD/AEAAQP//P/8gC37QIAt/AB//mST/D///IAt+kCALfzD//+AB//D/AAACADMqKhUV +/v///x//qCQf/5pQH/+WHB//qjAf/5hMIAs3gB//mBwAAP/9AAD//B//kWQf/5IwIAs4QB//qHQg +CziQIAs3wCALOAAf/6gU4wACAOL//wAgCzjQIAj7ACALgCAgAAAAADAAAABgAAAgYAAA0AAAACAL +f2AgC3/wAAAQACADCUgf/63QH/+peB//p3gf/6e4H/+pVCALOyAAACgAAAAQRAAAP/8AAMAAAAAg +AOEAMgAgCAEAIAgBQCAIAYAf/5ek/4AP///+AB////AAAAB7YB/84gAIAAAAH/+ZiB//kmgf/6ew +H/+R1OEC/gDhA74A4QM+AOEDfgDhAeIA4QEOAOEAkgD///D/H/+mMAAACQAf/5hU4QEOBOEBDgjh +AQ4MH/+aMP/wAAAAAoAGH/+rtP/7//8gC0GQIAtB8CAIAgAf/5kAH/+YKB//q6wQAAAA//D//yAD +Dagf/5YwAAB+TEAAAAAAAPAAIAtCYCALQsAgC0MgH/+rmB//pxwf/6kQIAtDYCALQ+AgC4WwIAtD +kB//qZQf/5l8IAtEYCALRCAgC4OQH/+YMCALRNAgC0UQIAuGoB//qPggC4YA39AAACALhkAf/6kE +/4AAAP//4AAgC0VQIAtFgB//mkQgC4MAIAezhB//l/wgAw20AAQAACALRcAf/6m8H/+pYB//qVgf +/6yQH/+wLB//sGAf/6n0EgAAACALgNAEAAAIgQAAAAAAMAAgC4EAIAMNsB//rnwf/7B4SQAAACAL +gGAuADYAIAe3sAAPA/8DEQAAAxUAAB//q7ggB7GgIAtGAB//lxQf/6bsH/+abB//m6AgARtgH//u +1B//7iAf/+/cH/+rLAAAE4gCAIIQAgACEAIAABAAGgAAAPrGiAAgAADwAAAAH/+pfB//p3DhAwIA +4QMGACAHskggB7LwAAD/3wAA//cgC0YgIAgCEH//////8////n///yALRnAgC0ZAIAtGoB//mlQf +/6lEH/+YLAAA+AAAPDw8H/+u0B//ktgf/5agH/+rJAoUKFAgCBOkIAezQB//kOggAxIoH/+SXP// +x/8AAv/AH/+X0CALhWAgC4UAIAuH8CALg1AgC0dAIAuHMCALhwAgC0bQIAuHYCALhJAgC4PwIAuE +QB//mGwf/5hkIAuHkCALh8Af/6aYH/+mlCALSYAf/6fQIAgCkAAAJxAgC0nwH/+mWB//mMAf/5i8 +H/+YtB//mLAgCAKwH/+nyCADCbAgAwxEIAgC0B//q6ggC0pgH/+nXB//p2Af/6dkH/+n7B//p+Qf +/6eYH/+nlB//p5Af/6eMH/+niB//p4Af/6d0IAgDAB//qzAf/6bkAABAAx//kXQf/5joH/+mhIf/ +//8f/5lIH/+tRB//mZgAD//wIAtKoCAIA7AgC0sAIAgDwB//q8QgC0tAH/+ZXCALS5Af/5kwIAtL +wCALS/AgCAPQH/+YpAAAJYAgC0wgIAtMYB//mEgf/5Y0IAgD8B//mEQf/5bcIAgD+P//AAAD5/wY +IAtMkCAIBAAf/6iIIAMKKB//qITz////IAMKMCADCjwgAwpIIAMKGA////8gCARQH/+YoCADElAg +C0zwIAgY1P//6tAgCBh0///rMCAIFxQgCBhs///skCAIFhQgCBcM///tkB//mMwD///gAARyDAAE +chQABHIcAARwFAAEcCgABHAgAARwLAAAhYA////gAARAJAAEQEwABEokAAQA4AAEAAQgC1FAIAtR +cB//mIgABALEAAQCwCALjsAgC47wAARwZCALjyAABEHAAARBxAAEQcgABEB4AARA3AAEQUAABEFE +IAtSQCALUoAgC1KwIAtRoCALUeAgC1IQAARwWAAAECgABEFgIAtTAAAAd3cAADMzIAtUQCALU0Ag +C1PAIAtUACALU4AgC1LQAAAgKAAEdBgABErAAARAwAAEQMQABEHwAARB9AAEdBQgC46AIAtVYCAL +VSAgC1TgIAtUoCALVGAABAJwAAAI8AAEAnQABAJ8AAQCkAAAvygABHBcAAR0AAAA8AYABEvwAARy +KAABmy8AAWMdAAQBMAAEAOwABAEIAAR2AAAEAQQABHYEAAD/+AAEAQAABADkAAR2CAAA/8EABHIA +AABVVQAEcgQABAD4AAQA3AAEANgABHJIAAQBOAAEARgABHJMAAQA9AAEclAABHQIAARyCAAEQEgA +BErcIAtVoCALVeAgC1YgAARBLAAEQTwABEDgIAtWYAAEQQAgC1aQAARwSAAEcGAABHIgAAR2DAAE +eASAEAAAIAuPYCADExCAEgADAAQA6IAQAAMABADAAABOIAAEAMwABADEAAQAyAAEATQgCAt0IAgP +tAACACEABACAAA//KQAEAEQgC1bAAAQCRAAEAkwABAJIBgYAAAAEAYAAAB54AAEwsAAEANAABADU +AAQA8AAEAPwAAgjVAAEEagAEAQwABAEQAACiwgAEARQABAEcAAQBJAAEASgABAEsAAQBQAAEAUQA +BAJQAAQBIAAEAmAABAJkAAQCVAABACF3NZQAAARB/AAES/wAAIAgAAAICAAEcDAgCAhgAARgwAAE +YMQAAIgAAARB1AAES9QABEHYAARL2AAEQdwABEvcAARwOAAEcAAgC1bwAARwBCALVzAABGDIAACA +JAAEQBwABEocAAAXLCALV3AgC1egO5rKAAAEYOQABGDQIAtX0AAEQAAABEAEAARADAAEQAggAwv0 +AARKBAAEcDQABHAIAARQAAAEVAAABGDMAAB/AAAEQdAABEvQAARwUAAEUGgABFBAAARUaCAIDJAA +BFBQAARUUAAEUiQAAEBAAARSKAAEUiwABEAQAARIEAAEQBQABEgUIAgMsAAEQeAABEvgIAgM1AAE +QegABEvoAARB5AAES+QABEHsAARL7AAEQBgABEoYAADu8AAEUGAABFRgAAARAAAAETAAABAwIAgI +iCAIB9wgCAnoIAgJPCAIC0ggCAqcAAQTBAAEEyQA////AIECIB//kaAAAPD/AABQDQCAAADhAeJA +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 ++RYtIgAAUzBbuhktEiksEipbuI8sEjQqEi3+EicqAQBm8P8SJioAQFqwKhYs/RIsIgAAW7D9Figi +AABT8Fu6DC0SKSwSKlu4gigSLS8SNC4SLPwSKC4BAH7w+P8BDgAgcLD+/ggACBBoMA7dDCkxgPRU +bGjABD5gKhIwCtooCao21aArMnlktA8uQAnEgAjuAi5ECScSMCgxgZITnBH8eygPdAFQMPzWWxAF +EFAw/3coCXQBPDD5FgQowAQ6IPtLWwYDAEXw+xYCKXQBPDD5FgAgBhBYMFu2/GPz+xfVlBXVk2Pz +8im8PwaZASkmz2PxcwAAwKP81kgQBhBYMFu28hvVx/rV6BAAEGAw/HWAIAAQaDD9NiYgABBgMCw2 +JWP1QgAAwKP81j0QBhBYMFu25hvVu/rV3BAAEGgw/XWAIAAQcDD+NicgABBoMC02KGP1UhnVdmP4 +wgDA4PnuNggCBQNg8/j5YAAQaDAvQpIlRpHz+qZkACAv8PVCliB+AkFwBogBKEaV8/qpZAAgRXAA +ACVcPwZVASVGmfP6oWQAIE1wABrWH/42KCIAAGFw+BIZIgAAa/D4NicgCAJasFt3ai0yKGP5ZgAA +AAAa1hb+NiYiAABhcPkSLyIAAGvw+TYlIAgCWrBbd2AtMiZj+ejAo/zWCxAGEFgwW7azwKD6dYAg +ABBwMP42JyAAEGgwLTYoY/kmwKP81gAQBhBYMFu2qsCwKzYlKzYmK3WAY/myAAAa1fwvNif7rAQi +AABhcFt3Si0yKGP7IQAAAC8WPfoKAyAGEFgw/NXpEgAAajBbtpr/Ej0gABBgMCw2KSw2Kix1gGP6 +cCxyffpyfioBAHVwCzsUKxYjDKoMKhYfWmivKzD9LDD8LjD4KhYlLzD5LTD7KjD/+hYDKAAgd/D7 +FgIoACBucP0WACgAIGZw/BYBKAAgXnD81WkYACBWcPkWOyAAEGgw+RYEIAYQWDD1zQEgBRBQMFu2 +eS8SOy4w9CwSJSow9foWJiAIEFgwDLsM/bwAAowANqDdsPgKACgAIFew+BYhKAAgfnD5FiAgQgC3 +4P4WGiABEFgw+xY0IAAQUDD6FiIv/xBYMCsWLWAAWsCj/NW3EAYQWDBbtmDA0C02J/11gCAAEGgw +LTYoY/oVLhYa+xYdIAEQcDD+FjQv/xBwMP4WLSIAAFPwW7k9LRIgLBIhW7ezKhI0KRItCro3/RId +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 +IAeFpCADFBwQQAGQIAeFpEZDb0UgRERQIGZhaWxlZCA6IG94X2lkIDB4JXggcnhfaWQgMHgleAoA +AAAAAAAAAEZDb0UgRERQIGZhaWxlZCA6IERkcFJlcG9ydCAweCV4IERkcFZhbGlkIDB4JXgKAEZD +IHhjaGcgYWxsb2MgZmFpbGVkOiBhdmFpbCAlZAoARkNPRSBGcmVlOiBzdGlsbCB5aWVsZGVkIHdo +ZW4gZnJlZWluZy4uLmZsb3djX2lkICV4IGZsb3djX2ZsYWdzICV4IAoAAAAAAAAAAAAAAABQUkxJ +IFJzcCB0aW1lZG91dCA6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IAoAAAAA +AAAAaHdfYmNtODQ4NTZfY2hlY2sgZW50cnkKAAAAAAAAAABod19iY204NDg1Nl9jaGVjayBsb29w +ICV1IChjaGVjayAlI3gpCgAAAAAAAAAAAABbJXUgUG9ydCBjYXJkXWh3X2JjbTg0ODU2X2NoZWNr +IHVwX3J1bm5pbmcgKHBvcnQ9JXUgOmxvb3BfY250PSV1ICkKAAAAAAAAAAAAAAAAAGh3X2JjbTg0 +ODU2X2NoZWNrIGZhaWxlZCAoYmFkIENSQykKAAAAAAAAAAAAAAAAAFBIWSBmaXJtd2FyZSBsb2Fk +IHN1Y2Nlc3NmdWwgKHBvcnQldSkgd293Li4uISEhISAKAAAAAAAAAAAAAAAAAABiY204NDg1Nl9s +b2Fkc2VxdWVuY2U6IFN0YXJ0ZWQKAEJyb2FkY2FzdCBtb2RlIHR1cm5lZCBPTiAKAAAAAAAAYmNt +ODQ4NTZfbG9hZHNlcXVlbmNlOiBVcGxvYWQgaW1hZ2UgdG8gUEhZIG9uLWNoaXAgbWVtb3J5CgAA +AAAAAGJjbTg0ODU2X2xvYWRzZXF1ZW5jZTogZG9uZSBsb2FkaW5nIGltYWdlICgweCV4KQoAAAAA +AAAAAAAAAAAAAABXYWl0X1NQSV9MT09QOiBwaWQgPSAldSAKAAAAAAAAAGJjbTg0ODU2X2xvYWRz +ZXF1ZW5jZTpET1dOTE9BRCBGQUlMRUQgKGxvID0gJSN4LCBoaT0lI3gsIGNudD0ldSkKAAAAAAAA +AAAAAAAAAAAAWyV1IFBvcnQgY2FyZF0gYmNtODQ4NTZfbG9hZHNlcXVlbmNlIDpEb3dubG9hZCBj +b21wbGV0ZWQgYWZ0ZXIgJXUgbG9vcHMgZm9yIHBvcnQgJXUKAAAAAAAAAAAAAAAAaHdfY2w0NV9p +bml0WyV1XSBhY2FwcyAlI3gKAAAAAABiY204NDg1Nl9pbml0WyV1XQoAAAAAAAAAAAAAAAAAAGh3 +X2JjbTg0ODU2X2xvd3Bvd2VyWyV1XTogZW5hYmxlPSVkCgAAAAAAAAAAAAAAAGh3X2JjbTg0ODU2 +X2xvd3Bvd2VyWyV1XSwgZmFpbGVkIHRvIHNldCAzMC4weDQwMEEgYml0IDc7IDMwLjB4NDAwRSBi +aXQ9MSBhZnRlciA1bXMsIHJlZz0leAoAAAAAAGh3X2JjbTU0ODJfY2ZnbWRpWyV1XSBzZXR0aW5n +IHR5cGUgJXUKAAAAAAAAAAAAAGRoY3A2X3RpbWVyX2NiOiByZXNlbmRpbmcgREhDUDZTT0xJQ0lU +IGFnYWluCgAAAGRoY3A2X3RpbWVyX2NiOiBzZW5kaW5nIERIQ1A2UkVRVUVTVAoAAAAAAAAAAAAA +AGRoY3A2X3RpbWVyX2NiOiBzZW5kaW5nIERIQ1A2UkVORVcgcmVxdWVzdAoAAAAAAGRoY3A2X3Rp +bWVyX2NiOiBzZW5kaW5nIERIQ1A2UkVCSU5EIHJlcXVlc3QKAAAAAGRoY3A2X3RpbWVyX2NiOiBE +SENQNlJFUExZIHJjdmQsIHN0YXRlICV1CgAAAAAAAGZhaWxlZCB0byByZW5ldy9yZWJpbmQgZGhj +cHY2IGFkZHJlc3MKAAAAAAAAAAAAAHR5cGUgJXgsIHhpZCAleCwgdHlwZV94aWQgJXgKAAAAaXB2 +NiBwcmVmZXJyZWQgYWRkciBbJTA0eCAlMDR4ICUwNHggJTA0eF0KAAAAAAAAY2huZXRfZmluZF9s +MnRfZW50cnk6IGRhZGRyIFslMDh4XSwgWzB4JTA4eF0sIGxvY2FsIG5ldHdvcmsgWyVkXQoAAAAA +AAAAAAAAAAAAAABjaG5ldCBmaW5kIGwydGVudCBub3QgdmFsaWQsIDB4JXgsIGlkeCAldSwgc3Rh +dGUgMHgleCwgcmV0cnkgY291bnQgJXUKAAAAAAAAAAAAAGNobmV0IGwydGVudCAweCV4LCBpZHgg +JXUsIHJlZmNudCAldQoAAAAAAAAAAAAAAGNobmV0IGwydGVudCBmaW5kIGVycgoAAAAAAAAAAAAA +Y2huZXRfZmluZF9pcDZfbDJ0X2VudHJ5OiBmaW5kIHByZWZpeCBtYXRjaCBbJTA0eCAlMDR4ICUw +NHggJTA0eF0KAAAAAAAAAAAAAAAAAABObyByb3V0ZXIgY29uZmlndXJlZCwgbDJkZXZfZmMtPmZs +b3djX2lkIDB4JXgKAAAKUm91dGVyIGxpZmUgJXUgZXhwaXJlZC4gZGVsZXRpbmcgcm91dGVyIFsl +MDR4ICUwNHggJTA0eCAlMDR4XQoAVXNpbmcgcm91dGVyIFslMDR4ICUwNHggJTA0eCAlMDR4XSB0 +byByZWFjaCBbJTA0eCAlMDR4ICUwNHggJTA0eF0KAAAAAAAAAAAAAAAAAABjaG5ldCBmaW5kIGlw +NiBsMnRlbnQgbm90IHZhbGlkLCAweCV4LCBpZHggJXUsIHN0YXRlIDB4JXgsIHJldHJ5IGNvdW50 +ICV1CgAAAAAAAGNobmV0IGwydGVudCAlMHgsIGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAAAAAA +AGNobmV0IGlwNiBsMnRlbnQgZmluZCBlcnIKAAAAAAAAc2V0dXBfZGRwOiBpc3Rhc2s6MHgleCwg +bnBwb2QgJXUsIGFsbG9jIGZhaWxlZCAlZAoAAAAAAAAAAAAAAAAAAHNldF9kaWdlc3Q6IEJQIGFs +cmVhZHkgZmMgMHgleCBmbGFncyAweCV4CgAAAAAAAHNldF9kaWdlc3Q6IGNzayAweCV4IGNvbm4g +MHgleCBzdGF0ZQoAAAAAAAAAAAAAAHNldF9kaWdlc3Q6IHVwbHN1Ym1vZGU6JXgsIHBnaWR4OjB4 +JXgsIHZhbDoweCV4IGJ1ZmZlcmVkIDB4JXgKAABzZXRfZGlnZXN0OiBidWZfbGxfZmx1c2ggZmMg +MHgleCBuZXh0X3dyIDB4JXgKAABubyB2YWxpZCBsMnQgZW50cnkgZm9yIHJlamVjdCBjc2tfZmMg +JXAKAAAAAAAAAABubyB2YWxpZCBsMnQgZW50cnkgZm9yIGFjY2VwdCBjc2tfZmMgJXAKAAAAAAAA +AAB0Z3RfY29ubl93cjogZmxvdy1pZDoweCV4IHR5cGU6MHgleCBpcyB3cm9uZyBmb3Igc3Vib3A6 +MHgleAoAAAAAaXB2Nl9hZGRyWzBdIDB4JXggaXB2Nl9hZGRyWzFdIDB4JXgKAAAAAAAAAAAAAAAA +YWRkciAlcyBwb3J0ICVzIHRhZyAlcwoAAAAAAAAAAAByZWRpcmVjdCBJUHY2IDB4JXgtMHgleCwg +cG9ydCAleAoAAAAAAAAAAAAAAAAAAAByZWRpcmVjdCBJUHY0IDB4JXgsIHBvcnQgJXgKAAAAAGF1 +dGhlbnRpY2F0ZV90YXJnZXQ6IEluY29ycmVjdCBwYXNzd29yZAoAAAAAAAAAAENIQVBfQzogZGln +ZXN0IGV4cGFuc2lvbiBlcnJvcgoAQ0hBUF9OOiBUYXJnZXQgdXNlcmlkIG1pc21hdGNoCgBDSEFQ +X1I6IGRpZ2VzdCBleHBhbnNpb24gZXJyb3IKAHJjdmRfcGFyYW1zOiBlcnJvciwgbGVuICVkCgAA +AAAATG9nb3V0IGZyb20gc2Vzc2lvbiBbMHgleF0KAAAAAABpU0NTSSBTZWMtcGFyYW1zIHJlY2Vp +dmVkIGhhdmUgZXJyb3JzISEKAAAAAAAAAABUYXJnZXQgbW92ZWQgdGVtcC4gY29ubiAleCwgc2Vz +cyAleAoAAAAAAAAAAAAAAABMb2dpbiBGYWlsZWQhIS4gY29ubl9mYyBbMHgleF0sIHNlc3NfZmMg +WzB4JXhdLCBzdGF0dXNfY2xhc3MgWzB4JXhdCgAAAAAAAAAAAAAAAFByb3RvY29sIEVycm9yIGNi +aXQgJWQgdGJpdCAlZCBjc2cgJWQgbnNnICVkCgAAAG9mbGRfcnhfZGF0YTogbWVtX3NpemU6IDB4 +JXgsIGRsZW4gWzB4JXhdLCBhYm9ydGluZyBjb25uIDB4JXgKAABuZXRpZl9waW5nX3RpbWVyX2Ni +OiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBpbmRldmN0eHQgMHgleCBzdGF0ZSBbJWRdIHJl +dHJ5X2NudCBbJWRdCgAAAAAAAABuZXRpZl9waW5nX3RpbWVyX2NiOiBsMnRfaWR4ICVkLCBkZWxf +bDJ0ICVkCgAAAABuZXRpZl9waW5nX3RpbWVyX2NiOiB0aW1lIDB4JXggdHlwZSAlZCBjb2RlICVk +IHJldHZhbCAlZAoAAAAAAAAAbmV0aWZfcGluZ190aW1lcl9jYjogcGluZ190cyAweCV4JXggcnNw +X3RpbWUgMHgleCV4CgAAAAAAAAAAAAAAAGljbXBfbDJ0X2NiOiBzdWJvcCAlZAoAAAAAAAAAAAAA +aWNtcF9sMnRfY2I6IEludmFsaWQgc3Vib3AgJWQKAABsM2luNl9kZXZfY29uZmlnOiBsaW5rIGxv +Y2FsIElQIG5vdCBhc3NpZ25lZAoAAABsMmRldl9mYyBbMHgleCBdIEZhaWxlZCB0byBzdGFydCB0 +aW1lciBmb3IgaXB2NCBkYWQKAAAAAAAAAAAAAAAAY2huZXRfbDJkZXZfdXBfbWJfY2I6IHJjIFsl +ZF0sIHBvcnQgWyV1XSwgc3RhdGUgWyV1XSwgY29va2llIFsweCV4XQoAAAAAAAAAAAAAAABsb2dp +bl90aW1lZG91dDogQnJlYWtpbmcgcGF0aCBzIFsweCV4XSBjIFsweCV4XSBjc2sgWzB4JXhdCgAA +AAAAcmVjb3ZlcnlfdGltZW91dDogc2VzcyBpZCBbMHgleF0gaW4gbG9nb3V0CgAAAAAAZm9pc2Nz +aTogUmVjb3ZlcnkgdGltZWQgb3V0IGFmdGVyIFsldV0gcmV0cnksIGJhaWxpbmcgb3V0CgAAAAAA +AFRDUCBjb25uIGVzdGFibGlzaG1lbnQgZmFpbGVkICVkCgAAAAAAAAAAAAAAAAAAAEludmFsaWQg +b3Bjb2RlIDB4JXggaW4gY3RybCBwYXRoCgAAAAAAAAAAAAAAAAAAAGRhdGFfZGRwOiBpdGFzay1p +ZDoweCV4LCBmbGFnczoweCV4LCBkeGZlcl9sZW46JWQsIGRzZW50X2xlbjolZAoAAAAAAAAAAAAA +AAAAAAAAZGF0YV9kZHA6IHRpZCBbMHgleF0gZXJyb3IgWzB4JXhdCgAAAAAAAAAAAAAAAAAARERQ +IGVycm9yIFsweCV4XSwgYWJvcnRpbmcgY29ubm4gWzB4JXhdCgAAAAAAAAAAcnhfZGF0YV9kZHA6 +IFJlc3BvbmNlIHJlY2lldmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3Ig +Y29ubmVjdGlvbiBzdGF0ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBj +b25uIGZsYWdzIFsweCV4XQoAPT0+IHJlY2VpdmVkIGRhdGEgZmMgaWQgMHgleCBmbG93Y19pY29u +bl9mbGFncyAweCV4IGxlbiAweCV4CgAAAGZvaXNjc2lfdGFzayBOVUxMLCBvcDoweCV4IGNza19m +Y2lkOjB4JXggY3NrX3N0YXRlOjB4JXggdGNiX2ZjaWQ6MHgleCwgdGNiX3N0YXRlOjB4JXggCgAA +AAAAAAAAAGloZHI6IFJlc3BvbmNlIHJlY2lldmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZh +bGlkIHRhc2sgb3IgY29ubmVjdGlvbiBzdGF0ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3Rh +dGUgWzB4JXhdLCBjb25uIGZsYWdzIFsweCV4XQoAAAAAAAAAAGloZHI6IEludmFsaWQgdGFzayBz +dGF0ZSAweCV4IGZvciB0YXNrIDB4JXgsIGl0dCBbMHgleF0sIG9wYyBbMHgleF0KAAAAAAAAAAAA +AAAAaXNjc2lfaGRyX3J4OiBhYm9ydCBjb25uOiBmbGFncyA+PiA3IFsweCV4XSwgaGRzZ2xlbiBb +MHgleF0gZHNyX2R0bCBbMHgleF0sIG1heF9idXJzdCBbMHgleF0KAAAATWF4IGRhdGEgbGVuIGV4 +Y2VlZGVkICVkID4gJWQKAAByZXR1cm5fcGVuZGluZ190YXNrOiBubyBXUiBpdGFzazogaWQ6MHgl +eCwgc3RhdGU6MHgleCwgY29ubjoweCV4LCBmbGFnczoweCV4LCBjb25uLWlkOjB4JXgsIGRkcDol +ZAoAAAAAAAAAAAAAAAAAaGFuZGxlciAleCwgcXVldWVkICV4CgAAAAAAAAAAAAByZXR1cm5fcGVu +ZGluZ190YXNrOiBEb25lIHNlbmRpbmcgdGFzayBlcnJvciB0byBob3N0CgAAAAAAAAAAAAAAcmV0 +dXJuX3BlbmRpbmdfdGFzazogZGVxdWV1ZSB0YXNrIFsweCV4XSwgc3RhdGUgWzB4JXhdIGZyb20g +dHhfbGlzdAoAAAAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBhbGwgdGFza3MgcmV0dXJu +ZWQsIHJlY292ZXJ5IHN0YXRlIHRyYW5zIHRvIFsweCV4XQoAAAAAAAAAAHByb2Nlc3NfdHhfcXVl +dWU6IHR4X3F1ZXVlIGZvciBjb25uOjB4JXggc3RvcHBlZCwgYWJvcnRpbmcgdGFzay4KAAAAAAAA +AAAAAAAAAAAAV0FUQ0hET0dfZGlzcGF0Y2ggY2FzZSB0byBhdm9pZDogQ291bnRlcl93YXRjaGRv +ZyAldSBDb3VudGVyX3NjaGVkICV1IAoAAAAAAAAAAABXQVRDSERPRzogZGV2aWNlIHNodXRkb3du +CgAAAAAAAFdBVENIRE9HOiBwb3J0WyV1XSBwYXVzZSB3YXRjaGRvZyB0aW1lb3V0CgAAAAAAAFdB +VENIRE9HOiBieXBhc3MgdGltZW91dAoAAAAAAAAAV0FUQ0hET0c6IEZMUiAtIG5vdCBpbXBsZW1l +bnRlZCB5ZXQKAAAAAAAAAAAAAAAAV0FUQ0hET0c6IHRlbXBlcmF0dXJlIG9mICVkQyBleGNlZWRz +IHRocmVzaG9sZCBvZiAlZEMKAAAAAAAAAAAAAGZpbHRlcjogcG9yZ3JhbW1pbmcgdGlkICV1IChs +ZSB0Y2FtIGluZGV4ICV1KS4uLgoAAAAAAAAAAAAAAAAAAAB3cmhfZmlsdGVyOiBpeCAlZCBub3Qg +bXVsdGlwbGUgb2YgJWQKAAAAAAAAAAAAAABmaWx0ZXI6IHJlcXVlc3RpbmcgY29tcGxldGlvbi4u +LgoAAAAAAAAAAAAAAAAAAABkY2J4X2llZWVfY21kaFsldV0gd3JpdGUgb25seSBwZXJtaXR0ZWQg +b24gbG9jYWwgY29uZgoAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIGNhbm5vdCB3cml0ZSAl +dSBhcHBzIChNQVg6ICV1KQoAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSByZXF1ZXN0 +aW5nIERDQl9JRUVFX0NNRAoAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1bmtub3duIGZlYXR1cmUg +d3JpdGU6ICV1CgAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1bmtub3duIGZlYXR1cmUgcmVhZDogJXUK +AAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIGNvbm5lY3Rpb24KAAAAAGNhbm5v +dCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIElQdjYgY29ubmVjdGlvbgoAAAAAAAAAAAAAAAAA +AABkaXNwYXRjaF9kZWZlcnJlZF9jbGFzc19jbGFzc19zaGFwaW5nWyV1OiV1XTogbGlzdF9lbXB0 +eQoAAAAAAAAAbG9vcGJhY2sgYnVmZmVyIGdyb3VwWyV1XSBpcyBkaXNhYmxlZAoAAAAAAAAAAAAA +aW52YWxpZCBidWZmZXIgZ3JvdXBbJXVdIGNvbmZpZ3VyYXRpb246IG10dSAldSBsd20gJXUgaHdt +ICV1IGR3bSAldQoAAAAAAAAAAAAAAABmYyAldSB2ZiAldSBnb3QgaXZmPTB4JXgscmFuZ2U6ICUj +eC0lI3ggKCV1LyV1IHVzZWQpCgAAAAAAAAAAAAAAVkkgJXUgY2Fubm90IGdldCBSU1Mgc2xpY2U6 +IE5vIG1vcmUgc2xpY2VzIGF2YWlsYWJsZSAodXNlZCAldS8ldSkKAAAAAAAAAAAAAAAAAABwZm4g +JXUgdmZuICV1IHdpdGggcG9ydCBtYXNrIDB4JXggY2Fubm90IGFjY2VzcyBwb3J0ICV1LCByZXQg +JWQKAAAAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHZpaWQs +IHJldCAlZAoAAHBmbiAldSB2Zm4gJXUgY291bGQgbWFwIHZpaWQgIDB4JXggdG8gZmxvd2MsIHJl +dCAlZAoAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvdWxkIG5vdCBhbGxvY2F0ZSB1d2lyZSBm +dW5jICVkIG1hYyBhZGRyLCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBmICVkLCB2ZiAlZCwgRVJS +T1IgZXhjZWVkZWQgbWF4IG1hYyBsaW1pdCAlZC8lZAoAAAAAAAAAAAAAAAAAAABtaWlfaW5pdFsl +dV06IGFjYXBzIDB4JXgKAAAAAAAAAG1paV9mb3JjZV9zcGVlZFsldV06IHJjYXBzIDB4JXgKAAAA +AAAAAAAAAAAAAAAAAG1paV9wZG93blsldV06IHBvd2VyZG93biBlbiAldQoAcG9ydF9jbWRfaGFu +ZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4 +XTogbDFjZmcsIGludmFsaWQgcmVxdWVzdCwgcGNhcHMgMHgleCBhY2FwcyAweCV4IG1jYXBzIDB4 +JXgsIHJjYXBzIDB4JXgKAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIHBjYXBzICUj +eCBhY2FwcyAlI3ggcmNhcHMgJSN4IG1jYXBzICUjeAoAAAAAAAAAAABwb3J0WyV1OjB4JTAyeDow +eCUwMnhdOiBsMWNmZywgbWRpIGlzc3VlIHBjYXBzIDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4 +CgAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBjYW5ub3QgZm9yY2Ugbm8vbXVs +dGlwbGUgc3BlZWQocyksIHBjYXBzIDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAA +AAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1bmtub3duIGFjdGlvbiAweCV4CgAAAABwb3J0 +WyV1OjB4JTAyeDoweCUwMnhdOiB1bmtub3duIHJlYWQgYWN0aW9uIDB4JXgKAAAAAAAAAAAAAAAA +AAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBjcGwgMHglMDh4JTA4eAoAAAAAAAAAAAAAY3BsX2Vy +cl9ub3RpZnk6IHRpZCAldSBjcGwgMHglMDh4JTA4eCAweCUwOHglMDh4CgAAAAAAAAAAAAAAAAAA +AGNwbF9lcnJfbm90aWZ5OiB0aWQgJXUgbGVuICV1CgAARkNPRSBGcmVlOiBzdGlsbCB5aWVsZGVk +IHdoZW4gZnJlZWluZy4uLmZsb3djX2lkICV4IGZsb3djX2ZsYWdzICV4IAoAAAAAAAAAAAAAAABG +Q09FIEJQIFdSIEVSUjogV1Igd2l0aCBjb29raWUgJXgleCBlcnJvcmVkIGJhY2sgCgAAAAAAAAAA +AAAAAAAAYWJvcnQvY2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggd2FzIGlzc3VlZCBvbiBzc24g +MHgleCBpbiB3cm9uZyBzdGF0ZSAweCV4CgAAAABhYm9ydCBXUiBvbiBzc24gMHgleCBkaWQgbm90 +IGZpbmQgV1Igd2l0aCBjb29raWUgMHgleCV4CgAAAAAAAAAAY2xvc2UgV1Igd2l0aCBjb29raWUg +MHglbHggb24gc3NuIDB4JXg7ZGlkIG5vdCBmaW5kIFdSIHdpdGggY29va2llIDB4JWx4CgAAAAAA +AABhYm9ydCBXUiBvbiBzc24gMHgleCB3YXMgaXNzdWVkIG9uIHhjaGcgMHgleCB3aXRoIHJ4X2lk +IDB4JXggaW4gd3Jvbmcgc3RhdGUgMHgleAoAAAAAAAAAAAAAAAAAAABkY2J4X2FwcGx5X2FwcF9j +ZmdbJXVdTkVXIEFQUCBUTFYgCgAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1 +cmVbJXVdIEZFQVRVUkVfTElOS1VQCgBkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIFNF +VF9MT0NBTF9QQVJBTUVURVJTCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJl +WyV1XSBGRUFUVVJFX05PX0FEVkVSVElTRQoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0g +RmVhdHVyZVsldV0gRkVBVFVSRV9QRUVSX05PVF9BRFZFUlRJU0VfRENCWAoAAAAAAAAAAAAAAAAA +AAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJfTk9UX0FEVkVS +VElTRV9GRUFUVVJFCgAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVd +IEZFQVRVUkVfVVBEQVRFX09QRVJfVkVSU0lPTgoAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0 +dXJlWyV1XSBGRUFUVVJFX1BFRVJfVVBEQVRFX09QRVJfVkVSU0lPTgoAAAAAAAAAAAAAAAAAAABk +Y2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfR0VUX1BFRVJfQ0ZHCgAAAAAA +AAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0NGR19OT1RfQ09N +UEFUSUJMRQoAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0Vf +TE9DQUxfQ0ZHCgAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRV +UkVfVVNFX1BFRVJfQ0ZHCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1 +XSBGRUFUVVJFX0ZFQVRVUkVfRElTQUJMRUQKAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVh +dHVyZVsldV0gRkVBVFVSRV9FUlJPUl9DSEFOR0UKAAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vz +c1sldV0gcmVjZWl2ZWQgQldzIGRvIG5vdCBhZGQgdXAgdG8gMTAwIQoAAAAAAAAAV0FSTklORzog +cmVjZWl2ZWQgQXBwIFRMViBjb250YWlucyBtb3JlIHRoYW5GVyBjYW4gaGFuZGxlIChtYXg6ICV1 +OyB0bHYgY29udGFpbnM6ICV1CgAAAAAAAAAAAAAAZGNieF9pZWVlX3Byb2Nlc3NbJXVdIHN1YnR5 +cGUgJSN4IHJlbV9mdF9jaGFuZ2VkICV1IHNtX2NoYW5nZSAldQoAAAAAAAAAAAAAAAAAAABkY2J4 +X2llZWVfcHJvY2Vzc1sldV0gc3VidHlwZSB1bmtub3duCgAAAAAAAAAAAABkY2J4X3BhcnNlX3Br +dFsldV0gZXJyb3IgJWQKAAAAAGNobmV0X2wydF91cGRhdGU6IGwyZGV2X2ZjIFsweCV4XSwgbDJk +ZXZfZmMtPmZsb3djX2lkIFsldV0gbDJkZXZfZmMtPmZsb3djX2ZsYWdzIFsweCV4XSwgaW50ZiBb +MHgleF0KAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlOiBpbiBkZWxheWVkX3Byb2Nlc3Npbmcs +IGwydGVudCBbJTA4eF0KAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTogbDJ0IGlwNCBl +bnRyeSBub3QgZm91bmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGwy +dCBpcDYgZW50cnkgbm90IGZvdW5kCgAAAAAAAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlX2Nh +Y2hlOiBib3RoIGlwNCBhbmQgaXA2IGFkZHIgY2Fubm90IGJlIG51bGwKAAAAY2huZXRfbDJ0X3Vw +ZGF0ZV9jYWNoZTogbDJ0IGVudHJ5IGlkeCAldSwgc3RhdGUgMHgleAoAAAAAAAAAAAAAAGNobmV0 +X2wydF91cGRhdGU6IGwydF91cGRhdGUgcmVxdWVzdCBzZW50IGwydGVudCBbJTA4eF0sIGwydGVu +dC0+aWR4IFslZF0sIGwydGVudC0+dmxhbiBbJWRdCgAAAGljbXAgY2hlY2tzdW06MHgleAoAAAAA +AAAAAAAAAAAAaXB2NiB0Y3AgcmVjdiwgaW5pdCB0eHEgd3IgZmFpbGVkCgAAAAAAAAAAAAAAAAAA +REhDUHY2IHBhY2tldCB0eXBlICV1LCBvcHRzbGVuICV1IHJlY2VpdmVkCgAAAAAASW52YWxpZCBk +aGNwIHN0YXRlICVkCgAAAAAAAAAAAABJZ25vcmUgREhDUHY2IG1zZyB4aWQgJXgsICBkaDZjdHh0 +LT54aWQgJXgKAAAAAABFcnJvciBpbiBESENQdjYgb3B0aW9ucyBwYXJzaW5nLiBJZ25vcmluZyBt +c2csIGkgJWQsIG9wdHNsZW4gJWQKAAAAAAAAAAAAAAAAAAAAAERIQ1AgZmFpbGVkLCBzdGF0dXNj +b2RlICVkLiBJZ25vcmluZyBhZHZlcnRpc2UKAGljbXA2IGNoZWNrc3VtIHZhbGlkYXRpb24gZmFp +bGVkLCBvciBlcnIgcmN2ZGlnbm9yaW5nIGljbXA2IG1zZyAldSwgZGxlbiAldQoAAAAAdGNwIHJl +Y3YsIGluaXQgdHhxIHdyIGZhaWxlZAoAAABDb3VsZCBubyBhbGxvY2F0ZSBwY2IhISBGcmVlaW5n +IGZjZiAhISEKAAAAAAAAAAB2bl9wYXJzZSB1bmtub3duIHN1YmNvZGUgJXUKAAAAAHZuX3BhcnNl +IHVua25vd24gZHR5cGUgJXUKAAAAAAAAaWdub3JpbmcgZmlwIHJlY3YgZm9yIHBjYiBmbG93OiV4 +IGluIG9mZmxpbmUgc3RhdGUKAAAAAAAAAAAAAAAAAGZpcF92bjJ2bl9yZWN2X2VyciAKAAAAAAAA +AAAAAAAAQ291bGQgbm90IGFsbG9jYXRlIGZsb3djISEhIQoAAABDb3VsZCBub3QgYWxsb2NhdGUg +U0NCIGZsb3djISEhIQoAAAAAAAAAAAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9y +IGxvZ28KAAAAAAAAAAAAAAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgZmNmIGZsb3c6JXggaW4g +b2ZmbGluZSBzdGF0ZQoAAAAAAAAAAAAAAAAAQ291bGQgbm90IGZpbmQgcmlnaHQgc2NiIGZvciBm +bG9naQoAAAAAAAAAAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4LCByZXRyeSBub3Qgc3VwcG9y +dGVkCgAAAAAARmxvZ2kgcmVzcCByY3Ygd2l0aCB1bmtub3duIHhjaGcgb3hfaWQleCBzaWQgJTJ4 +JTJ4JTJ4IGRpZCAlMnglMnglMngKAAAAAAAAAAAAAABOX1BPUlQgMHgleCV4JXggcmVqZWN0ZWQg +UExPR0kgd2l0aCByZWFzb24gY29kZSAleAoAAAAAAAAAAAAAAAAAQUJUUyB3aGlsZSBhd2FpdGlu +ZyBQUkxJIFJzcDogZmxvd2NfaWQgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXggCgAAAAAAAAAA +AAAAAABBQlRTIGZha2UgUnNwOiBsb2MgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXgKAABsbGRw +X3J4X3BrdF9oYW5kbGVyWyV1XSBkcm9wIHByZS1pbml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAA +AAAAYXJwX3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9hZGRyLmFkZHIgWzB4JXhdLCBzaXAgWzB4JXhd +LCByaXAgWzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGluX2F0 +dHIuaXB2NC5hZGRyOjB4JXgsIGFoZHIuc2lwOjB4JXgKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2Fy +cF9yZWN2OiBpcCBjb25mbGljdCBkZXRlY3RlZAoAAAAAAAAAAAAAAGNobmV0X2FycF9yZWN2OiBw +aWQgWyV1XSwgdmxhbiBbMHgleF0sIGFycCBvcCBbMHgleF0sIHNpcCBbMHgleF0sIHJpcCBbMHgl +eF0gbDJkZXZfZmMtPmZsb3djX2lkICV4IGwyZGMtPmluNF9kZXYuaW5fYWRkci5hZGRyICV4CgAA +AAAAAAAAAAAAAAAAACV4JXgleCBSZWNpZXZlZCBMT0dPIGZyb20gJXgleCV4IAoAAAAAAAAAAAAA +AAAAAENQTF9SWF9QS1Q6IElnbm9yaW5nIE1PUCBvciBFT1AgZnJhbWVzCgAAAAAAAAAAAEZhaWxl +ZCB0byBwb3N0IHhjaGcgZXJyOiBzc25pIDB4JXggY29va2llIDB4JWx4IHJ2YWwgJXggCgAAAAAA +AABvZmxkX2Fib3J0X3JlcV9uZWdhZHZbJXVdOiB3ciAweCUwOHggY3BsX2Fib3J0X3JlcSBERUxJ +VkVSRUQKAAAAaG9zdF93clsldV06IHdyIDB4JTA4eCBjcGxfYWJvcnRfcmVxIHN0YXR1cyAweCV4 +CgAAAAAAAAAAAAAAAAAAAHBrdHNjaGVkX2NsX3JsWyV1OiV1XTogbW9kZSB8IHVuaXQgfCByYXRl +IDB4JTA2eCBtaW4gJXUgbWF4ICV1IHBrdHNpemUgJXUKAAAAAAAAcGYgJWQsIHZmICVkIHNlY3Jl +dCBrZXlfaW5kZXggJWQsIFZGIHNlY3JldCAweCV4CgAAAAAAAAAAAAAAAAAAAHBhcmFtX2NobmV0 +WzB4JXg6MHgleF06IGNobmV0IDB4JXggcmVhZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAABwYXJh +bV9kbWFxWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAA +AAAAUlNTU0VDUkVUS0VZOiByc3NzZWNyZXQgdGJsIGJhc2UgJWQsIHJzc25zZWNyZXQgJWQKAAAA +AAAAAAAAAAAAAE1DWyV1XSBpbml0X3N0YXRlX21hY2hpbmUgMHglMDJ4CgAAAAAAAAAAAAAAAAAA +AE1DIGluaXRpYWxpemF0aW9uIG5vdCBjb21wbGV0aW5nLCBNQyBjdXJyZW50IGluaXQgc3RhdGUg +aXMgMHglMDJ4CgAAAAAAAAAAAAAAAAAATUNbJXVdIF9od19tY19pbml0X21jCgAAAAAAAAAAAABf +aHdfbWNfaW5pdF9tYzogZXJyb3IsIHJldCAlZAoAAF9od19tY19pbml0X21jX2ZwZ2FbJXVdOiBl +cnJvciAlZAoAAAAAAAAAAAAAAAAAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9y +IHBoeSBmdyBmaWxlLCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1cGxlOiB0dXBsZSAl +dSBub3Qgc3BlY2lmaWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAAAAAAAAAAAGxlIGNv +bmZpZ3VyYXRpb246IGhhc2ggcmVnaW9uIHRvbyBsYXJnZSB0byBlbmFibGUgc2VydmVyIHNyYW0K +AABsZSBjb25maWd1cmF0aW9uOiBjYW5ub3QgZW5hYmxlIHNlcnZlciBzcmFtIHdoZW4gaGFzaCBy +ZWdpb24gaXMgZGlzYWJsZWQKAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiB0aW1lcl9ycyAl +dXVzIHRpbWVzdGFtcF9yZXMgJXV1cyBkZWxheWVkYWNrX3JlcyAldXVzCgAAAAAAaHdfdHBfdGNw +X3NldHRpbmdzX3c6IGRhY2tfdGltZXIgJXV1cyBtc2wgJXV1cyByeHRfbWluLG1heCAldSwldXVz +IHBlcnNfbWluLG1heCAldSwldXVzCgAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGtlZXBf +aWRsZSxpbnR2bCAldSwldXMgbWF4cnR0ICV1dXMgaW5pdHNydHQgJXV1cyBmaW53YWl0Ml90aW1l +ciAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZGFja190aW1lciBmcm9t +ICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIG1zbCBmcm9t +ICV1IHRvICV1AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4dF9taW4gZnJvbSAldSB0 +byAldQAAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWF4IGZy +b20gJXUgdG8gJXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVy +c19taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBw +aW5nIHBlcnNfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3Nf +dzogY2FwcGluZyBrZWVwX2lkbGUgZnJvbSAldSB0byAldQAAAAAAAAAAAAAAaHdfdHBfdGNwX3Nl +dHRpbmdzX3c6IGNhcHBpbmcga2VlcF9pbnR2bCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3Rw +X3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGluaXRfc3J0dF9tYXhydHQgZnJvbSAldSB0byAldQAA +AABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRfaW5pdHNydHQgZnJvbSAl +dSB0byAldQAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZmlud2FpdDJfdGltZXIgZnJv +bSAldSB0byAldQAAAAAAAGZpbHRlck1vZGU9JSN4IGlsbGVnYWw6IHNlbGVjdHMgJWQgYml0cyAo +bWF4ICVkKQoAAAAAAAAAAAAAAAAAAABsZSBjb25maWd1cmF0aW9uOiBuZW50cmllcyAldSByb3V0 +ZSAldSBjbGlwICV1IGZpbHRlciAldSBhY3RpdmUgJXUgc2VydmVyICV1IGhhc2ggJXUKAAAAAAAA +AAAAAABsZSBjb25maWd1cmF0aW9uOiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRl +ciAldSBzZXJ2ZXIgJXUgYWN0aXZlICV1IGhhc2ggJXUgbnNlcnZlcnNyYW0gJXUKAAAAAAAAAAAA +AAAAaHdfc2dlX3F1ZXVlX2Jhc2VfbWFwWyV1XTogZXhjZWVkZWQgbnVtYmVyIG9mIGVncmVzcyBx +dWV1ZXMsICV1CgAAAAAAAAAAAAAAAAAAAABod19zZ2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNl +ZWRlZCBudW1iZXIgb2YgaW5ncmVzcyBxdWV1ZXMgd2l0aCBmcmVlbGlzdCBhbmQgaW50ZXJydXB0 +LCAldQoAAABod19zZ2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5n +cmVzcyBxdWV1ZXMsICV1CgAAAAAAAAAAAAAAAAAAAEVycm9yLCBUb3RhbCBSU1MgU2VjcmV0IHRh +YmxlIGFsbG9jYXRpb24gJWQgPiAxNgoAAAAAAAAAAAAAAAAAAABza3UoMHgleCk6IGN1c3RvbSBz +a3UgNDBHX1NPIGRvZXMgbm90IHN1cHBvcnQgZXh0bWVtCgAAAAAAAAAAAAAAc2t1KDB4JXgpOiBj +dXN0b20gc2t1IDEwRyBkb2VzIG5vdCBzdXBwb3J0IDQwRyBwb3J0cwoAAAAAAAAAAAAAAHNrdSgw +eCV4KTogY3VzdG9tIHNrdSAxMEdfU08gZG9lcyBub3Qgc3VwcG9ydCA0MEcgcG9ydHMoJXUpIG9y +IGV4dG1lbSgldSkKAAAAAAAAc2t1OiBjdXN0b20gc2t1KDB4JXgpIDQwRyBwb3J0cygldSkgZXh0 +bWVtKCV1KSBzdXBwb3J0ZWQKAAAAAAAAAGNmX3BhcnNlOiBmaWxlIG1lbXR5cGUgMHgleCBtZW1h +ZGRyIDB4JXggbWFwcGVkIEAgJXA6CgAAAAAAAAAAAABjb25maWd1cmVkIHdpdGggY2FwcyBuYm18 +bGluayAweCUwOHggc3dpdGNofG5pYyAweCUwOHggdG9lfHJkbWEgMHglMDh4IGlzY3NpfGNyeXB0 +byAweCUwOHggZmNvZToweCV4CgAAAAAAAAAAAAAAbmV0IFZJIGFsbG9jYXRpb24gZmFpbGVkIGZv +ciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAG5ldCBWSSBtYWMgYWRkcmVzcyBw +cm9ncmFtbWluZyBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAA +AAAAbmV0IFZJIHJ4bW9kZSBwcm9ncmFtbWluZyBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJy +b3IgJWQKAAAAAG5ldCBWSSByc3MgaW5kaXJlY3Rpb24gdGFibGUgcHJvZ3JhbW1pbmcgZm9yIGZj +X2lkICV1IGZhaWxlZCB3aXRoIGVycm9yICVkCgAAAAAAbmV0IFZJIHJzcyBjb25maWcgY29tbWFu +ZCBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAG5ldCBWSSBjb21tYW5kIGZh +aWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAAAAAABmb2lzY3NpX2lu +aXQ6IGluaXRfZG9uZToldSwgZm9pc2NzaV9udGFza3M6JXUsIGZvaXNjc2lfbnNlc3M6JXUsIG5j +c29jazoldSwgbnNwb3J0czoldSwgZm9pc2NzaV9uaW5pdDoldSwgcmM6JWQKAAAAAAAAAAAAAAAA +AAAAAEZDb0UgRERQIGluaXQ6IGZjb2UgbGxpbWl0IDB4JXgsIGZjb2UgdWxpbWl0IDB4JXggZ2Js +IGxsaW1pdCAweCV4IGdibCB1bGltaXQgMHgleCBwY2JzeiAleAoAAAAAAEZDb0UgRERQIGluaXQ6 +IGZjb2UgcHBvZCBvZmYgMHgleCwgZmNvZSBzdCBwcG9kIGFkZHIgMHgleCBmY29lIG51bSBwcG9k +cyAweCV4CgAAY2hfY2xfcmF0ZVsldS8ldV06IGNhcHBlZCBjbGFzcyByYXRlIGZyb20gcmVxdWVz +dGVkICV1IHRvIGNvbmZpZ3VyZWQgKGVmZmVjdGl2ZSkgY2hhbm5lbCByYXRlICV1CgAAAAAAAAAA +AAAAAAAAAGNoX2NsX3JhdGVbJXUvJXVdOiBpbmNyZWFzZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVx +dWVzdGVkICV1IHRvIHJlcXVpcmVkIG1pbiBvZiAldTsgcmF0ZSAldSAoZWZmICV1KSBkZWZpY2l0 +X21heCAldQoAAAAAAAAAAAAAAAAAcGt0c2NoZWQgY2hhbm5lbCAldSBzZXRzIHNwZWVkIChmcm9t +ICV1KSB0byAldSBrYnBzCgAAAAAAAAAAAAAAAG5ldF9sMmRldl9ub3RpZnk6IHBnaWQgWzB4JXhd +LCBwcmlvIFsweCV4XSwgY2ggWzB4JXhdCgAAAAAAAAAAAABbJXVdIHVuYWJsZSB0byBleGVjdXRl +IGludGVybmFsIERDQl9JRUVFX0NNRAoAAABwb3J0WyV1XSBsaW5rIGRvd24gKCV1KSAobHN0YXR1 +cyAlI3gpCgAAAAAAAAAAAABpMmMgZXJyb3IgY2F1c2VkIGJ5IG1vZHVsZSB1bnBsdWcKAAAAAAAA +AAAAAAAAAABzZW5kdG8gcGVuZGluZzogd3JfcGVuZCAlcCBmb3IgcG9ydCAldSwgd2FudCB0byBz +ZW5kIHRvIHBvcnQgJXUKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHVwZGF0ZSAoZmxvd2NpZCAl +dSByYyAldSkKAAAAAAAAAAAAAAAAAHBvcnRfc2V0X2xvb3BiYWNrIHBvcnQgJSN4IGN1cnJlbnQg +JSN4IG1vZGUgJSN4CgAAAAAAAAAAAAAAAAAAAABwb3J0WyV1XSBzcGVlZCB1cGRhdGU6ICUjeAoA +AAAAAHBvcnRbJXVdIGJlZ2lubmluZyBkZWJvdW5jZQoAAAAAUVNGUCBtb2R1bGUgdW5wbHVnIC0g +cmVpbml0aWFsaXppbmcgcnhfbG9zICB0byAweGZmCgAAAAAAAAAAAAAAAGdwaW9fcXNmcF9tb2R1 +bGVfdXBkYXRlOiBjaGFuZ2VkIHJ4X2xvcyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABncGlvX3Fz +ZnBfbW9kdWxlX3VwZGF0ZTogY2hhbmdlZCB0eF9kaXMgZnJvbSAweCV4IHRvIDB4JXgKAAAAAAAA +ZGlzYWJsaW5nIHR4ICUjeCByeCAlI3gKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsl +dV0gcG93ZXJpbmcgZG93bgoAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJp +bmcgdXAKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gdW5rbm93biBzdGF0ZSAo +c3RhdGUgPSAlI3gpCgAAAAAAAAAAcG9ydF9saW5rX3N0YXRlX2hhbmRsZXI6IFNvbWV0aGluZyB3 +ZW50IHRlcnJpYmx5IHdyb25nLiByZXQgPSAlZAoAAAAAAAAAAAAAAAAAAABDYWxjdWxhdGlvbiBv +dXQgb2YgYm91bmRzIGZ1cmluZyBpbml0OiAlI3ggJSN4ICUjeAoAAAAAAAAAAAAAAAAAaHdfc2dl +X21hbWVtX2luaXQ6IGVuY291bnRlcmVkIGVycm9yICVkCgAAAAAAAAAAbGUgaW5pdGlhbGl6YXRp +b246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2 +ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAbGUgaW5pdGlhbGl6YXRpb246IG5lbnRyaWVzICV1IHJv +dXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAldSBhY3RpdmUgJXUgaGFzaCAldSBuc2Vy +dmVyc3JhbSAldQoAAAAAAAAAAAAAAGh3X3RwX2luaXQ6IHRjYiByZWdpb24gKHN0YXJ0IDB4JTA4 +cyBzaXplICV1KSBtdXN0IGJlIGluIGZpcnN0IDI1Nk1CIG9mIE1BIG1lbW9yeQoAAAAAAAAAAAAA +AAAAAGh3X3RwX2luaXQ6IHBnbW5ndCByZWdpb24gKHN0YXJ0IDB4JTA4cyBzaXplICV1KSBtdXN0 +IGJlIGluIGZpcnN0IDI1Nk1CIG9mIE1BIG1lbW9yeQoAAAAAAAAAAAAAAGh3X3RwX2luaXQ6IFRQ +IHBnbW5ndCBpbml0aWFsaXphdGlvbiBkaWQgbm90IGNvbXBsZXRlCgAAAAAAAAAAAABidWZtX2lu +aXQ6IG4gJXUgYnVmbGw2NGludF9zaXplIDB4JXgKAAAAAAAAAAAAAABidWZtX2luaXQ6IG5vdCBl +bm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIGludGVybmFsIGJ1ZmxsNjQgYnVmZmVycwoAAAAAAAAA +AAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgYnVmbGw2NCBi +dWZmZXJzCgAAAAAAAABtZW1faW5pdF9idWY6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRl +IGZsb3cgYnVmZmVycwoAAAAAAAAAbWVtX2luaXRfYnVmOiBub3QgZW5vdWdoIG1lbW9yeSB0byBh +bGxvY2F0ZSB0Y2JfY2FjaGUgKG9mZmVyZWQgJXUgdHJ5aW5nIHRvIHVzZSAldSBhdmFpbGFibGUg +JXUpCgAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fb3RoZXJzOiBzdGFydCAweCUwOHggc2l6ZSAl +dSAodW51c2VkICV1KSwgaG1hICV1CgAAAABtcGFydGl0aW9uX290aGVyczogc3RhcnQgMHglMDh4 +IHNpemUgJXUgKHVudXNlZCAldSkKAAAAAAAAAAAAAAAAbWVtX2luaXQ6IEVEQyBvdmVyY29tbWl0 +dGVkIGJ5ICVkIGJ5dGVzCgAAAAAAAAAAbWVtX2luaXQ6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFs +bG9jYXRlIGZsb3cgdGFibGUKAAAAAAAAAAAAAAAAAGN4Y25pY19kZXZpY2VfaW5pdDogY3hjbmlj +IFsweCUweF0sIGN4Y25pYy0+ZmlsdGVyIFslMHhdCgAAAAAAAABwb2Zjb2UgaW5pdCBkb25lCgAA +AAAAAAAAAAAAAAAAAHBvcnRfaW5pdFsldV0gcHR5cGUgMHgleAoAAAAAAAAAUG9ydFsldV06IFVu +a25vd24gU0dNSUkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gQlRf +WEZJIHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAcG9ydF9pbml0WyV1XTogcG9ydCB0eXBlIDB4JXgg +aXMgbm90IHN1cHBvcnRlZAoAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20g +MHglMDh4IHRvIDB4JTA4eCB0byBtYWtlIHJvb20gZm9yIExFIEhBU0ggYW5kL29yIFRQIFRDQnMK +AAAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25faW5pdDogbW92ZWQgcG1yeF9zdGFydCBmcm9tIDB4 +JTA4eCB0byAweCUwOHggKEVEUkFNKQoAAAAAAAAAAAAAAAAAAAAARVEgcGZuICV1IHZmbiAldTog +ZGVzdHJveWluZyBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBm +bGFncyAweCUwOHgKAAAAAAAAAAAAQWggaGEuLi5kb3VibGUgZnJlZSBveF9pZCAweCV4LCByeF9p +ZCAweCV4CgAAAAAASG9zdCBQUkxJIFJlc3BvbnNlIHRpbWVkb3V0OiBveF9pZCAweCV4IHJ4X2lk +IDB4JXgKAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgdmlhIGNvbW1hbmQKAAAAAAAAaHdfaTJj +X3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRyX29wIDB4JXggcmVnIDB4JXggZGlmZiAldSBjb250 +ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoAAAAAAAAAAAAAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0 +YSAldSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYgJXUgZHBvcyAldSBjb250ICV1IGZh +aWxlZCB3aXRoIGVyciAlZAoAAAAAAAAAAAAAAAAAAGkyYyB0cmFuc2FjdGlvbiBmYWlsZWQgdG8g +Y29tcGxldGUKAAAAAAAAAAAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXI6IGFlY19yZXRy +eV9jbnQgdmFsdWUgJWQgaXMgbm90IHdpdGhpbiB0aGUgYWxsb3dlZCBsaW1pdCBvZiAxIHRvIDI1 +NC5EaXNhYmxpbmcgaXQuCgAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBhbl9hZWNfdGlt +ZSB2YWx1ZSAlZCBpcyBiaWdnZXIgdGhhbiBhbGxvd2VkIGxpbWl0LkNoYW5naW5nIGl0IHRvIDEw +MDAwIG1zLgoAAAAAAAAAAAAARGVwcmVjYXRlZCBjb25maWcgb3B0aW9uIGZvdW5kIGluIGNvbmZp +ZyBmaWxlLiBJZ25vcmluZy4uCgAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXI6IHBsIHRp +bWVvdXQgdmFsdWUgaXMgdG9vIGxhcmdlLCBjaGFuZ2luZyBmcm9tICV1IHRvICV1dXNlY3MKAAAA +AAAAAAAAAFBMX1BDSUVfTElOSy5zcGVlZCBvZiAldSBpcyBub3Qgc3VwcG9ydGVkCmZpbGUsIHJl +dCBGV19FSU8KAAAAAABzY2hlZF9pb3F0eF9icF9wcmlvcml0eTogaGFzICV1IGVudHJpZXMgb25s +eSwgcmVxdWlyZXMgJXUgZW50cmllcwoAAAAAAAAAAAAAAAAAAHRwX2JhY2tvZmY6IHBhcnNlZCAl +ZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMKAAAAAHRwX3RpbWVydmFsczogcGFyc2VkICVkIGluc3Rl +YWQgb2YgJXUgZW50cmllcwoAAHRwX3RpbWVycmVzOiBwYXJzZWQgJWQgaW5zdGVhZCBvZiAldSBl +bnRyaWVzCgAAAHRwX210dXMgaGFzICV1IGVudHJpZXMgb25seSwgcmVxdWlyZXMgJXUgZW50cmll +cwoAAAAAAAAAAAAAAAAAAAB0cF9tdHVzWyV1XSBpcyAldSBieXRlcyB3aGljaCBpcyBub3Qgc3Vw +cG9ydGVkCgBjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBzZ2UgdGltZXIgdmFsdWVbJWRdIGlz +IHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJvbSAldSB0byAldXVzZWNzCgAAAAAAAABmaWx0ZXJtYXNr +IDB4JXggaXMgbm90IGVxdWFsL3N1YnNldCB0by9vZiBmaWx0ZXJtb2RlCgAAAAAAAAAAAAAAaHdf +bGVfY2xpcF9oYW5kbGVyOiByZW1vdmVkIHBvcz0ldSAoPWlkeCAldSkKAAAAaHdfbGVfY2xpcF9o +YW5kbGVyOiBhZGRpbmcgdG8gcG9zPSV1ICg9aWR4ICV1KQoAcGh5X2luaXQ6IHBvcnQgJXUgd2l0 +aCB0aGUgdHlwZSAldSAgaGF2ZSByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAGJlYW4vYWVjIGNvbXBs +ZXRlICV1CgAAAAAAAAAAAAAAaHdfbWFjX2luaXRfcG9ydFsldV0sIHB0eXBlIDB4JXgsIHNwZWVk +IDB4JXgsIGxhbmVzIDB4JXgsIGZlYyAweCV4CgAAAAAAAAAAAAAAAABtb2R1bGVbJXVdOiBwb3J0 +IG1vZHVsZSBpbnNlcnRlZCBhbmQgcmVhZHkKAAAAAABtb2R1bGVbJXVdOiBwb3J0IG1vZHVsZSBy +ZW1vdmVkCgAAAAAAAAAAAAAAAAAAAABtb2R1bGVbJXVdOiB1bmtub3duIG1vZHVsZSBpZGVudGlm +aWVyIDB4JTAyeAoAAABtb2R1bGVbJXVdOiBncGlvICV1IHZlbmRvciBpZCAlMDZ4LCBpZGVudGlm +aWVyIDB4JTAyeCwgU0ZQMjgoYnl0ZSAzNi8xOTIpIDB4JTAyeCwgU0ZQKGJ5dGUgMy8xMzEpIDB4 +JTAyeCwgMUcgKGJ5dGUgNikgMHglMDJ4CgAAAG9wdGljYWwgbGVuZ3RoKGJ5dGUgMTUvMTQyKSAl +dSwgY29wcGVyIGNhYmxlKGJ5dGUgOC8xNDcpIDB4JTAyeCwgbGVuZ3RoKGJ5dGUgMTgvMTQ2KSAl +dSwgbW9kdWxlX3R5cGUgMHglMDJ4CgAAAABtb2R1bGVbJXVdOiBncGlvICV1IHZlbmRvciBpZCAl +MDZ4LCBpZGVudGlmaWVyIDB4JTAyeCwgU0ZQMjgoYnl0ZSAzNi8xOTIpIDB4JTAyeCwgU0ZQKGJ5 +dGUgMy8xMzEpIDB4JTAyeCwgMUcgKGJ5dGUgNikgMHglMDJ4CgAAAG9wdGljYWwgbGVuZ3RoKGJ5 +dGUgMTUvMTQyKSAldSwgY29wcGVyIGNhYmxlKGJ5dGUgOC8xNDcpIDB4JTAyeCwgbGVuZ3RoKGJ5 +dGUgMTgvMTQ2KSAldSwgbW9kdWxlX3R5cGUgMHglMDJ4CgAAAABjeDRfY3JfbW9kdWxlX3J4X2xv +c1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgBNQzogZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNo +IHRvIENGRy4AAAAAAAAAAAAAAABNQzogZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNoIHRvIEFjY2Vz +cy4AAAAAAAAAAABNQzogZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNoIHRvIENGRy4AAAAAAAAAAAAA +AABNQzogZXhwZWN0ZWQgc3RhdGUgdG8gc3dpdGNoIHRvIEFjY2Vzcy4AAAAAAAAAAABJSS4xLmJ4 +IGRwMThbJXVdIHFbJXVdICUjeCAlI3ggJSN4ICUjeCBtaW4gJSN4IG1heCAlI3gKAAAAAAAAAAAA +SUkuMS5jLWQuICUjeCAlI3ggJSN4ICUjeCBhbGwgICUjeAoAAAAAAAAAAAAAAAAASUkuMi5iICgl +I3ggLSAlI3ggKyAlI3gpICUgMTI4ID0gJSN4CgAAAAAAAAAAAAAASUkuMyBpbmV3XzFlIGFmdGVy +IGxpbWl0IGNvbXB1dGUgaXRlbXBfMWUgJXgsIGluZXdfMWUgJXgKAAAAAAAAAElJLjMuIGl0ZW1w +XzFlICUjeCBpbmV3XzFlICUjeCBpbmV3XzFlICVkCgAAAAAAAElJLjQuIHNldF8xZSAlI3gKAAAA +AAAAAAAAAAAAAAAATUM6IGNhbGlicmF0aW9uIGZhaWxlZCBmb3IgZXJyYXRhMjkgZHAxOCAldQoA +AAAASVYuMS4gZHAxOFsldV0gcGhhc2Vfc2VsIGJlZm9yZSAlI3ggYWZ0ZXIgJSN4LCBnYXRlX2Rl +bGF5ICUjeAoAAE1DIGVycmF0YTI5IGlzc3VlOiBkcDE4ICV1IHF1YWQgJXUgY2Fubm90IGJlIGRl +Y3JlYXNlZAoAAAAAAAAAAABNQyBlcnJhdGEyOSBpc3N1ZTogZHAxOCAldSBxdWFkICV1IGNhbm5v +dCBiZSBkZWNyZWFzZWQKAAAAAAAAAAAATUMgZXJyYXRhMjkgaXNzdWU6IGRwMTggJXUgcXVhZCAl +dSBjYW5ub3QgYmUgZGVjcmVhc2VkCgAAAAAAAAAAAE1DIGVycmF0YTI5IGlzc3VlOiBkcDE4ICV1 +IHF1YWQgJXUgY2Fubm90IGJlIGRlY3JlYXNlZAoAAAAAAAAAAAB0ZW1wMl8xZSsweDEwID0gJSN4 +CgAAAAAAAAAAAAAAAE1DOiBjYWxpYnJhdGlvbiBmYWlsZWQgZm9yIGVycmF0YTIxIGl0ZXJhdGlv +biAldQoAAAAAAAAAAAAAAAAAAABNQyBlcnJhdGEgMjE6IGRwMThbJXVdIHByMCBuMDIgZmFpbGVk +IHRvIGdldCBhdmVyYWdlCgAAAAAAAAAAAAAATUMgZXJyYXRhIDIxOiBkcDE4WyV1XSBwcjAgbjEz +IGZhaWxlZCB0byBnZXQgYXZlcmFnZQoAAAAAAAAAAAAAAE1DIGVycmF0YSAyMTogZHAxOFsldV0g +cHIxIG4wMiBmYWlsZWQgdG8gZ2V0IGF2ZXJhZ2UKAAAAAAAAAAAAAABNQyBlcnJhdGEgMjE6IGRw +MThbJXVdIHByMSBuMTMgZmFpbGVkIHRvIGdldCBhdmVyYWdlCgAAAAAAAAAAAAAATUMgaW5pdGlh +bGl6YXRpb24gZmFpbGVkOiBERkkgaW5pdCBub3QgZ29pbmcgdG8gMAoAAAAAAAAAAAAAAAAAAE1D +IGluaXRpYWxpemF0aW9uIGZhaWxlZDogREZJIGluaXQgbm90IGNvbXBsZXRpbmcKAAAAAAAAAAAA +AAAAAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21wbGV0 +ZS4KAAAAAAAAAAAARFAxOCAldSwgYnl0ZV9sYW5lICV1LCBiaXRfc2VsZWN0ICV1CgAAAAAAAAAA +AAAARFAxOCAldSwgYnl0ZV9sYW5lICV1LCBiaXRfc2VsZWN0ICV1CgAAAAAAAAAAAAAATUMgZmFp +bGVkIHRvIGdldCBVUENUTCBwb3dlciB1cCBkb25lCgAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRp +b24gZmFpbGVkOiBEaWRuJ3QgZ2V0IGFsbCBEUDE4cyBsb2NrZWQKAAAAAAAAAAAAAE1DIGluaXRp +YWxpemF0aW9uIGZhaWxlZDogRGlkbid0IGdldCBib3RoIEFEUnMgbG9ja2VkCgAAAAAAAAAAAABD +dXJyZW50IFNsZXcgdHhfcm93ICVkOiB0eF9jb2wgJWQsIHZhbCAlZAoAAAAAAABDdXJyZW50IFNs +ZXcgYWRkcl9yb3cgJWQ6IGFkZHJfY29sICVkLCB2YWwgJWQKAABNQyBpbml0aWFsaXphdGlvbiBm +YWlsZWQ6IFNMRVdfRE9ORV9TVEFUVVMgbmV2ZXIgdG9nZ2xlZAAAAAAAAAAAcGZuICV1IHZmbiAl +dSBGU00gc3RhcnQKAAAAAAAAAABwZm4gJXUgdmZuICV1IEZTTSBjb21wbGV0ZQoAAAAAAGZscl9w +ZnZmX2ZzbVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUg +aW4gZDNob3QsIGlnbm9yaW5nLCBkM2hvdCAweCUwOHggUENJRV9TVEFUIDB4JTA4eAoAAAAAAAAA +AAAAAAAAAAAAaHcgcGYgYml0bWFwIDB4JTAyeCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4 +JTA4eDoweCUwOHgKAAAAAGFmdGVyIHZmaWQgZml4dXAsIHZmaWQgYml0bWFwIDB4JTA4eDoweCUw +OHg6MHglMDh4OjB4JTA4eAoAAAAAAABNQ1sldV06IGZhaWxlZCB0byBzd2l0Y2ggY29udHJvbGxl +ciB0byBDRkcgc3RhdGUKAAAAAAAAAAAAAAAAAAAATUNbJXVdOiBmYWlsZWQgdG8gc3dpdGNoIGNv +bnRyb2xsZXIgdG8gSU5JVF9NRU0gc3RhdGUKAAAAAAAAAAAAAE1DWyV1XTogZmFpbGVkIHRvIHN3 +aXRjaCBjb250cm9sbGVyIHRvIENGRyBzdGF0ZQoAAAAAAAAAAAAAAAAAAABNQ1sldV06IHBlcmlv +ZGljIGNhbGlicmF0aW9uIGZhaWxlZCB3aXRoIGVycm9yICV1CgAAAAAAAAAAAAAAAAAAdGltZXIg +cXVldWUgJXUgbG9zdCBhIHRpY2shIG5leHQgJXAgbGFzdCAlcCBudW1lICV1CgAAAAAAAAAAAAAA +AGZscl90aW1lcl9zdGFydDogZmxvd2NfaWQgJXUgJXAgYnVmICVwCgAAAAAAAAAAAE1BQzogUExM +cyBkaWRuJ3QgbG9jawoAAAAAAAAAAAAAcGNpZTogcmVhZCBmcm9tIHNlcmNmZyBwY2llX2lwX3Vy +X21heGZ1bmMgMHgleCBwZmJpdG1hcCAweCV4CgAAAFNlcmlhbCBDb25maWd1cmF0aW9uIHZlcnNp +b246IDB4JXggVlBEIHZlcnNpb246IDB4JXgKAAAAAAAAAAAAAABwY2llOiBTZXJpYWwgQ29uZmln +dXJhdGlvbiBTUEFSRTMgaGFzIENvb2tpZSBHZW5lcmF0aW9uIGVuYWJsZWQuCgAAAAAAAAAAAAAA +AAAAAHBjaWU6IG5wZiAldSAocGZiaXRtYXAgMHglMDJ4KSBudmYgJXUgKHBmIDAuLjcgMHglMDh4 +JTA4eCkgdmZzdHJpZGUgJXUKAAAAAAAAAAAAaHdfbWFjX3ByZXA6IGVycm9yLCByZXQgJWQKAAAA +AABod19ncGlvX3ByZXA6IGVycm9yLCByZXQgJWQKAAAAAE1DIENMSyBzZXR0aW5nIGZhaWxlZDog +UExMX01fTE9DSyBuZXZlciB0b2dnbGVkCgAAAAAAAAAAAAAAAAAAAABmYWlsZWQgdG8gZmluZCB0 +aGUgJWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAABmYWlsZWQgdG8gcGFyc2UgdGhlICVjJWMg +VlBEIHBhcmFtZXRlcgoAAAAAAAAAAABtZW1fcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAAAAAGZh +aWxlZCB0byBzdWNjZXNzZnVsbHkgZmluZCBDaGVsc2lvIFZQRAoAAAAAAAAAAHZwZF9wcmVwOiBl +cnJvciwgcmV0ICVkCgAAAAAAAAAAc2VyY2ZnX3ByZXA6IGVycm9yLCByZXQgJWQKAAAAAABsb2cg +aW5pdGlhbGl6ZWQgQCAweCUwOHggc2l6ZSAldSAoJXUgZW50cmllcykgZndyZXYgMHglMDh4IHBj +aWVfZncgMHglMDh4CgAAAAAAAGJvb3RzdHJhcCBmaXJtd2FyZSB0b29rICV1IG1zZWNzIHRvIHJ1 +bgoAAAAAAAAAAFBJIGVycm9yIGZsb3dpZF9sZW4xNiAweCV4LCBhcHBfdGFnIDB4JXgsIHJlZl90 +YWcgMHgleCwgcGlzYyAlMDR4ICUwNHggJTA0eCAlMDR4CgAAAAAAAAAAAAAAAAAAAGZsb3djICV1 +IChTR0UgZXFpZCAldSkgKEVUSENUUkwgcXVldWUpIGV4cGVyaWVuY2VkIGEgUENJIERNQSBSRUFE +IHdvcmsgcmVxdWVzdCBlcnJvciAoaW5ib3VuZCBxdWV1ZSAldSkKAAAAAAAAAABmbG93YyAldSAo +U0dFIGVxaWQgJXUpIGV4cGVyaWVuY2VkIGFuIHVuZXhwZWN0ZWQgUENJIERNQSBSRUFEIHdvcmsg +cmVxdWVzdCBlcnJvciAoaW5ib3VuZCBxdWV1ZSAldSkKAAAAAAAAAAAAAAAAZmxvd2MgJXUgZXhw +ZXJpZW5jZWQgYW4gdW5leHBlY3RlZCBQQ0kgRE1BIFJFQUQgZXJyb3IgKGluYm91bmQgcXVldWUg +JXUpCgAAAAAAAABnYXRoZXJfdGFza3NfZm9yX3RtZjogSW52YWxpZCB0eXBlIFsweCV4XSwgYmFp +bGluZyBvdXQuCgAAAAAAAAAAZmNfc2VuZF9hbGxvY19jcGw6IGZhaWxlZCB0byBzZXR1cCBmaWx0 +ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0ZV9jdHVwbGUgMHgleDoleAoAAAAA +Y29tcHV0ZV9jdHVwbGUoKTogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAA +AAAAAAAAAEZDb0UgRkNCIGxpbmtkb3duOiBpb19yZXEgMHgleCV4IGlxaWQgMHgleCBmbG93aWQg +MHgleCBvcCAweCV4CgBmY29lIG5vdGlmeSA6IFVwZGF0ZSBuZXcgRENCWCB2YWx1ZXMgVkkgc3Rh +dGUgMHgleCBwcmkgMHgleCBzY2hlZGNsIDB4JXggZGNieF9kb25lIDB4JXgKAAAAAAAAAABmY29l +IG5vdGlmeSA6IEZDRiBmbG93aWQgMHgleCwgdWxwY2ggMHgleCAKAAAAAABmY29lIG5vdGlmeSA6 +IEZDb0UgTElOS1VQOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgKAAAAAAAAAAAAAAAAAAAAZmNvZSBu +b3RpZnkgOiBGQ29FIExJTktET1dOOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgKAAAAAAAAAAAAAAAA +AGZjb2Ugbm90aWZ5IDogRENCWCA6IHBvcnQgMHgleCwgcHJpb3JpdHkgMHgleCB1bHB0eGNoIDB4 +JXggY2xhc3MgMHgleAoAAAAAAAAAAAAAUkRFViBtc2cgZmxvd2M6JXggc3RhdGUgMHgleCBldmVu +dCAweCV4CgAAAAAAAAAAY2FuY2VsIGZjYjoleCBzY2I6JXggc3RhdGU6JXgKAABGQ29FIEZDRiB0 +aW1lcjogZmxvd2Mgc3RhdGUgMHgleCwgcG9ydCAweCV4ICxmY2YgMHgleCwgZmxvd2NfaWQgMHgl +eAoAAAAAAAAAAAAAAGh3IHJlZ2lzdGVyIG9wZXJhdGlvbiBub3QgY29tcGxldGluZywgcmVnIDB4 +JTA4eCBtYXNrIDB4JTA4eCB2YWx1ZSAweCUwOHggKHJlZyAweCUwOHgpCgAAAAAAAAAAAE1ESU8g +Q0w0NTogZmFpbGVkIHRvIHNldCB1cCBNTUQgYWRkcgoAAAAAAAAAAAAAAE1ESU86IGZhaWxlZCB0 +byByZWFkCgAAAAAAAAAAAAAAV3JpdGVfYWxsX3BvcnRzOiBwaWQgPSAldSByZWcgPSAweCV4IAoA +AAAAAAAAAAAATURJTyBDTDQ1OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAA +TURJTzogZmFpbGVkIHRvIHdyaXRlCgAAAAAAAAAAAABtaWlfYWR2X2ZjWyV1XTogcmNhcHMgMHgl +eAoAAAAAAG1paV9hZHZfc3BlZWRbJXVdOiByY2FwcyAweCV4CgAAY3BsX3R4X3BrdDogdmxhbmlk +IFsweCV4XQoAAAAAAABmbG93Y19pZCBbJXVdIGwyZGV2X2ZjIFsweCV4XSBhbHJlYWR5IHJlY2Vp +dmVkIFJBLCBub3Qgc2VuZGluZyBSUwoAAAAAAAAAAAAAAAAAAGZsb3djaWQgWyV1XSBsMmRldl9m +YyBbMHgleF0gTm8gSVB2NiByb3V0ZXIKAAAAAGNobmV0IFslZC8lZF0gZnJlZSBsMnQgZW50cnk6 +IGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAAAAAAAAAAAABjaG5ldCBbJWQvJWRdIHB1dCBsMnQg +ZW50cnk6IGlkeCAldSwgcmVmY250ICV1CgAlMDh4OiAlMDh4ICUwOHggJTA4eCAlMDh4CgAAAAAA +AGNobmV0IFslZC8lZF0gZ2V0IGwydCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKAGNobmV0IFsl +ZC8lZF0gbDJ0IGFsbG9jIGwydGVudCAweCV4LCBpZHggJXUsIHJlZmNudCAldQoAAAAAAAAAAABv +dXQgb2YgYXRpZHM6IG1heCBhdGlkczogJWQKAAAAAHRhc2tfYWxsb2M6IE91dCBvZiB0YXNrcy4K +AAAAAAAAY29pc2NzaV9maW5kX3Rhc2s6IHRhc2sgbm90IGZvdW5kIHRjYl9mYyBpZCAweCV4IGl0 +dCAweCV4IHR0dCAweCV4CgAAAAAAAAAAAAAAAABwZW5kaW5nX2Nzb2NrczogY3NvY2s6ICVwIHRn +dF9mYzogJXAgaWR4ICV1IHN0YXRlIDB4JXgKAAAAAAAAAAAAZmxvd19pZCBbMHgleF0gaGlzdG9y +eSAweCUyeCAweCUyeCAweCUyeCAweCUyeCAweCUyeAoAAAAAAAAAAAAAAGZvaXNjc2lfdmFsaWRh +dGVfbG9naW5fc3RhZ2U6IC0gMQoAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogbWIgWzB4JXhd +LCBkZWZlcnJlZCwgc3RhdGUgWzB4JXhdLCBwb3J0IFsweCV4XQoAAABsMmRldl92aV9mc206IHZp +aWQgWzB4JXhdIHBvcnQgWzB4JXhdLCBtYWMtaWQgWyUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDol +MDJ4XS4gCgAAAAAAAAAAAAAAAAAAAABsMmRldl92aV9mc206IHNnZV9lcWlkIFsweCV4XSwgc2dl +X2lxaWQgWzB4JXhdLCBzZ2VfZXFjciBbMHgleF0sIHJzc19zeiBbMHgleF0KAGwyZGV2X3ZpX2Zz +bTogbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl9tdHUgWyV1XSwgbWJfc2NyYXRjaCBbMHgleF0s +IHBvcnQgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogdmlpZCBbJWRdLCB2aV9m +Yy0+Zmxvd2NfdmlfZmxhZ3MgWzB4JXhdCgAAAAAAAAAAAABsMmRldl92aV9mc206IHBmbiBbMHgl +eF0sIHZmbiBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGxwb3J0IFsweCV4XSwg +dmlpZCBbMHgleF0sIGZsYWdzIFsweCV4XQoAAAAAAAAAbDJkZXZfdmlfZnNtOiBFcnJvciBmcmVl +aW5nIFZJLCByYyBbMHgleF0KAAAAAAAAbDJkZXZfdmlfZnNtOiBwaWQgWzB4JXhdLCB2aWlkIFsw +eCV4XSwgbWJfbG9jIFsweCV4XSwgbWJfb3JpZ1sweCV4XSwgbDJkZXZfZmxhZ3MgWzB4JXhdLCBy +YyBbMHgleF0KAAAAAAAAAAAAAAAAAGZvaXNjc2lfZmluZF90YXNrOiB0YXNrIG5vdCBmb3VuZCB0 +Y2JfZmMgaWQgMHgleCBpdHQgMHgleAoAAAAAAABXQVRDSERPRzogTm8gdGVtcGVyYXR1cmUgc2Vu +c29yIGF2YWlsYWJsZS4KAAAAAABXQVRDSERPRzogQWN0aXZhdGluZwoAAAAAAAAAAAAAAFdBVENI +RE9HIC0gRW5hYmxlIGFjdGlvbiAldSB0aW1lICV1CgAAAAAAAAAAAAAAAFdBVENIRE9HIC0gRGlz +YWJsZSBhY3Rpb24gJXUKAAAAV0FUQ0hET0c6IERlLWFjdGl2YXRpbmcKAAAAAAAAAABwb3J0WyV1 +XSBzZXQgUEFVU0UgUEFSQU1TOiBwcHBlbiAldSB0eHBlICUjeCByeHBlICUjeAoAAAAAAAAAAAAA +bXBzX2xpbmtfdXBbJXVdIGFjYXBzICUjeCAoODAyLjMgJSN4KSArIGxwYWNhcHMgJSN4ID0+ICUj +eAoAAAAAAGRjYnhfcG9wdWxhdGVfY3RybCBjb2RlIGluY29tcGxldGUKAAAAAAAAAAAAAAAAAGNo +X2NsX3JhdGVbJXUvJXVdOiBjYXBwZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWlyZWQgJXUgdG8g +JXU7IHJhdGUgJXUgKGVmZiAldSkgZGVmaWNpdF9tYXggJXUKAERDQlg6IHN1bSBvZiByYXRlcyBv +biBhbGwgY2xhc3NlcyBtdXN0IGJlIDEwMCAoYWN0dWFsOiAldSkKAAAAAAByaV93cl9pbml0WyV1 +XTogbXNzICV1IGlzIG5vdCA4LWJ5dGUgYWxpZ25lZAoAAABjb3JlX3Byb2dyYW1fdGNiOiB0aWQg +JSN4IHRfc3RhdGUgJSN4IHJjdl9hZHYgMHglMDh4IHJjdl9zY2FsZSAlI3ggdHhfbWF4ICUjeCBy +Y3Zfbnh0ICUjeCBhdGlkICUjeAoAAAAAAAAAAAAAAAAACW9wdDAgJSN4JXggb3B0MiAlI3ggaXB2 +NiAlI3ggZmxhZ3NfdGltZXIgMHglMDh4CgAAAAAAAAAAAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93 +cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4 +JTA4eCBwaXAgMHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBAIExFIGluZGV4ICV1CgAA +AAAAAAAAAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUg +bHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmlsdGVyIDB4JTA4eCBl +eGlzdHMgQCBMRSBpbmRleCAldQoAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9u +IHdpdGggNS10dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBpcCAweCUw +OHglMDh4IGZpbHRlciAweCUwOHgKAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3 +aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmls +dGVyIDB4JTA4eAoAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgdG9v +IGxhcmdlIChtYXggJXUpCgAAAAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWlk +ICV1IG5vdCBhbGxvY2F0ZWQKAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSB0b28g +bGFyZ2UgKG1heCAldSkKAAAAAAAAAAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwwaWQg +JXUgbm90IGFsbG9jYXRlZAoAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgdG9vIGxh +cmdlIChtYXggJXUpCgAAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1 +IG5vdCBhbGxvY2F0ZWQKAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlk +IGJ1dCBub3QgZmwwaWQgJXUKAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBp +cyB2YWxpZCBidXQgaGVhZGVyIHNwbGl0IGZlYXR1cmUgaXMgbm90IGVuYWJsZWQKAAAAAAAAAAAA +AAAAAAAAaHdfdWxwdHhfd29ya2Fyb3VuZF9wcjE2OTQ5X2VuYWJsZWRfdmZpZDogdmZpZCAldSBl +bmFibGVkICV1CgAAAEVRIHBmbiAldSB2Zm4gJXU6IGNyZWF0aW5nIEVUSCBlcWlkICV1IHdpdGgg +cGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgKAAAAAAAAAEVRIHBm +biAldSB2Zm4gJXU6IGNyZWF0aW5nIENUUkwgZXFpZCAldSB3aXRoIHBlbmRpbmcgV1IocykgKG51 +bV9ieXRlcyAldSBhbmQgZmxhZ3MgMHglMDh4CgAAAAAAAEVRIHBmbiAldSB2Zm4gJXU6IGVxaWQg +JXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAEVRIHBmbiAldSB2Zm4gJXU6IGVxaWQgJXUgbm90IGFs +bG9jYXRlZAoAAAAAAAAAAHZpX3RjYW1fcmF3IGlkeCAldSBtYWMgMHglMDR4ICUwOHgKAAAAAAAA +AAAAAAAAAHBvcnRfYmxpbmtfbGVkX3Jlc3RvcmUKAAAAAAAAAAAAcG9ydF9ibGluazogYmxpbmtk +dXI9MHgleCBibGlua19yZWZjbnQKAAAAAAAAAAAAcG9ydF9ibGluazogCWJsaW5rX3JlZmNudD0w +eCV4CgBwb3J0X2JsaW5rOiAJYmxpbmtfcmVmY250PTB4JXgKAG1paV9hbnJlc3RhcnRbJXVdOiBh +Y2FwcyAweCV4CgAAbWlzc2luZyBwb3J0IGNhcHMzMiB0byBjYXBzMTYgdHJhbnNsYXRpb24gZm9y +ICUjbHgKAAAAAAAAAAAAAAAAAHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24gdS5kY2IudHlwZSAw +eCV4CgAAAAAAAG1pc3NpbmcgcG9ydCBjYXBzMTYgdG8gY2FwczMyIHRyYW5zbGF0aW9uIGZvciAl +I3gKAAAAAAAAAAAAAAAAAABiYWQgRmxvd0MgJWQgb24gZXN0YWJsaXNoZWQgY29ubmVjdGlvbgoA +AAAAAAAAAABldGhfZmxvd2NfaGFuZGxlclsweCV4XTogZmxhZ3MgMHglMDh4IG51bV9ieXRlcyAl +dSBzY2hlZGNsIDB4JXggLT4gMHgleAoAAAAAAAAAAHNjc2lfcmVhZDogcHBvZCBhbGxvYyBmYWls +ZWQsIG5wcG9kICV1CgAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9MSU5LVVAK +AAAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9VUERBVEVfRENCWF9UTFYK +AAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9QRUVSX05PVF9BRFZFUlRJU0VfRENCWAoA +AAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfVVBEQVRFX09QRVJfVkVSU0lP +TgoAAAAAAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1BST0NFU1NfUEVF +Ul9UTFYKAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX0FDS19QRUVSCgAAAAAAAAAAAAAA +ZGNieF9pZWVlX3ZhbGlkYXRlWyV1XSBlcnJvciAob3VpICUjeCBzdWJ0eXBlICUjeCBsZW4gJSN4 +KQoAAAAAAGRjYnhfY2VlX3ZhbGlkYXRlWyV1XSBlcnJvcgoAAAAAREhDUHY2IFJFUExZIHJlY2Vp +dmVkIHN0YXRlICV1CgBkaGNwIHJlcGx5IHJlY2VpdmVkIGluIHdyb25nIHN0YXRlICVkCgAAAAAA +AAAAAAB1bmtub3duIHNlcnZlcmlkLiBJZ25vcmluZyBkaGNwIHJlcGx5CgAAAAAAAAAAAAByZWNl +aXZlZCByZXBseSB3aXRoIGRpZmZlcmVudCBhZGRyZXNzLiBpZ25vcmluZyBkaGNwIHJlcGx5CgAA +AAAAREhDUHY2IEFEVkVSVElTRSByZWNlaXZlZAoAAAAAAABkaGNwIGFkdmVydGlzZSByZWNlaXZl +ZCBpbiB3cm9uZyBzdGF0ZSAlZAoAAAAAAABpZ25vcmluZyByY3ZkIGFkdmVydGlzZSBwcmVmZXJl +bmNlICV1CgAAAAAAAAAAAABTdGFydCBESENQdjYgdG8gZ2V0IHRoZSBpcCBhZGRyZXNzCgAAAAAA +AAAAAAAAAABObyBkaGNwLCBkaGNwIHN0YXRlICVkLCBhZGRyIHN0YXRlICVkCgAAAAAAAAAAAAAl +MDJ4ICUwMnggJTAyeCAlMDJ4ICUwMnggJTAyeAoAAHZuMnZuOiBwb3J0IDB4JXggZGlkOjB4JXgl +eCV4IFVQCgAAAAAAAAAAAAAAAAAAAHZuMnZuOiBwb3J0IDB4JXggZGlkOjB4JXgleCV4IERPV04K +AAAAAAAAAAAAAAAAAGZjX3NlbmRfYWxsb2NfY3BsOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0 +dXBsZQoAAAAAAAAAAAAAAAAAAABmY29lX2NvbXB1dGVfY3R1cGxlIDB4JXg6JXgKAAAAAGNvbXB1 +dGVfY3R1cGxlKCk6IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAA +AABmY29lX2NvbXB1dGVfY3R1cGxlIHZsYW4gJXggdmlpZCAleCBwb3J0ICV4IG1wc19pZHggJXgK +AAAAAAAAAAAAQUJUUyBBQ0MgYXdhaXRpbmcgUFJMSSBSc3A6IGZsb3djX2lkIDB4JXggb3hfaWQg +MHgleCByeF9pZCAweCV4IGlxaWQgMHgleAoAAAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIGNv +bW1hbmQgZmFpbGVkIHJldHJpZXMgMHgleAoAAAAAAAAAAAAAAAAAR290IENPTk5fRVhJU1QgZm9y +IHhpZDoweCV4LCB0YWc6MHgleCwgcmV0cnlpbmcuCgAAAAAAAAAAAAAAAAAAAGNoX3JhdGVbJXVd +OiBjYXBwZWQgdGljayBmcm9tIHJlcXVpcmVkICV1IHRvIHN1cHBvcnRlZCAldTsgcmF0ZSAldSAo +ZWZmICV1KSBkZWZpY2l0X2luY3IgJXUgdGljayAldQoAAAAAAAAAAAAAAABwa3RzY2hlZF9jaF9y +bFsldV06IGNoYW5uZWwgcmwgbm90IGF2YWlsYWJsZSBpbiBjb25qdW5jdGlvbiB3aXRoIGZsb3cg +c2hhcGluZwoAAHBrdHNjaGVkX2NoX3JsWyV1XTogcmF0ZSAldSBtYXggJXUKAAAAAAAAAAAAAAAA +AHBrdHNjaGVkX2NsX3dyclsldToldV06IHdlaWdodCAldQoAAAAAAAAAAAAAAAAAAGVxX3BhcmFt +c1sweCV4OjB4JXhdOiBkbWFxIDB4JXggcmVhZCAldSBwZiAldSBlcWlkX2FwaSAldSByZXQgJWQK +AAAAAAAAAAAAAAAAAAAAd2FpdF9mb3JfY2FsaWJfZG9uZTogcmV0ICVkIGluICV1IGF0dGVtcHRz +CgAAAAAAaHdfbWFfYWRkcl90b19tZW1fdHlwZV9vZmY6IE1BIGFkZHJlc3MgMHglMDh4IGlzIG5v +dCBtYXBwZWQKAAAAAGh3X21hX2FkZHJfdG9fbWVtX3R5cGVfb2ZmOiBNQSBhZGRyZXNzIDB4JTA4 +eCBtYXBzIHRvIHR5cGUgJXUgb2Zmc2V0IDB4JXgKAAAAAAAAbWVtX21hbGxvY190ZW1wOiBmYWls +ZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVybmluZyBOVUxMCgAAAHJpbmcgYmFja2JvbmUs +IGVuYWJsZSAlZCwgbXBzLmZsYWdzIDB4JXgKAAAAAAAAAHJpbmcgYmFja2JvbmUgbm8gY2hhbmdl +IGluIGNvbmZpZ3VyYXRpb24KAAAAAAAAAHJpbmcgYmFja2JvbmUgY29uZmlndXJhdGlvbiBlcnJv +ciwgVENBTSBub3QgZW1wdHkuIGF2YWlsYWJsZSAlZCwgc2l6ZSAlZAoAAAAAAAAAbWVtX21hbGxv +YzogZmFpbGVkIHRvIGFsbG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAAAAAAAAAGxl +IGNvbmZpZ3VyYXRpb246IGhhc2ggbW9kZSByZXF1aXJlcyBhdCBsZWFzdCAxNiBlbnRyaWVzLCBu +aGFzaCAldQoAAAAAAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBtb2RlIHJlcXVpcmVz +IGF0IGVudHJpZXMgdG8gYmUgYSBwb3dlciBvZiAyLCBuaGFzaCAldQoAAABsZSBjb25maWd1cmF0 +aW9uOiByZXF1ZXN0ZWQgJXUgdGNhbSBlbnRyaWVzIGJ1dCBvbmx5ICV1IGF2YWlsYWJsZSAobnJv +dXRlICV1IG5jbGlwICV1IG5maWx0ZXIgJXUgbnNlcnZlciAldQoAAAAAbGUgY29uZmlndXJhdGlv +bjogdGNhbSByZWdpb25zIG11c3QgaGF2ZSBtdWx0aXBsZSBvZiAzMiBlbnRyaWVzLCBucm91dGUg +JXUgbmNsaXAgJXUgbmZpbHRlciAldSBuc2VydmVyICV1CgAAAAAAAGh3X3RwX3RjcF90dW5pbmdz +OiB0dW5pbmcgZm9yIGNsdXN0ZXIgZW52aXJvbm1lbnQKAAAAAAAAAAAAAAAAAABod190cF90Y3Bf +dHVuaW5nczogdHVuaW5nIGZvciBMQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczog +dHVuaW5nIGZvciBXQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczogbWFudWFsIHR1 +bmluZwoAAAAAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBzdGFydAoA +AAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogZHN0IDB4JTA4IG9mZnNldCAweCUwOHgg +c2l6ZSAldSwgd2lkdGggb2YgJXUgaXMgbm90IHN1cHBvcnRlZAoAAAAAAAAAAAAAAABfaHdfY2lt +X2ZsYXNoX21lbWNweTogbWVtY3B5WCBlbmQKAAAAAAAAAAAAAAAAAABjb25maWd1cmF0aW9uIGZp +bGUgcGFyc2VyIGVuY291bnRlcmVkIGVycm9yIEAgbGluZSAldToKAAAAAAAAAAAAZmNvZSB4Y2hn +IG1nciBpbml0OiBOdW1iZXIgb2YgZXhjaGFuZ2VzIGZvciBGQ29FIGlzICV4CgAAAAAAAAAAAGZj +b2VfbDJ0X2luaXQ6IE5vIHVscHR4IGNyZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2VfbDJ0X2lu +aXQ6IGNoOlsldV0gbDJ0X2lkeCBbJXVdCgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVzIGNvbmZp +Z3VyZWQ7IGZvcmNpbmcgJXUgZW50cmllcywgc3RhcnRpbmcgYXQgJXUKAABkY2J4X2llZWVfY29u +c3RydWN0WyV1XSBldHMgJXUgcGZjICV1IGFwcCAldQoAAABkY2J4X3RpbWVvdXRbJXVdCgAAAAAA +AAAAAAAAAAAAAGRjYnhfcnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9JRUVF +CgAAAAAAAAAAAAAAAAAAAABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9S +VU5fQ0VFCgBkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fTk9ORQoA +AAAAAAAAAAAAAAAAAAAATUFDIGZhaWxlZCB0byByZXN5bmMgdHgKAAAAAAAAAABwb3J0WyV1XSBs +aW5rIHVwICgldSkgKHNwZWVkICUjeCBhY2FwcyAlI3ggbHBjYXBzICUjeCkKAAAAAAAAAAAAcG9y +dF9oc3Nfc2lnZGV0WyV1XTogaHNzX3NpZ2RldCBjaGFuZ2VkIHRvIDB4JXgKAAAAAAAAAAAAAAAA +AAAAAHBvcnRbJXVdIGluaXRpYWxpemluZyBLUgoAAAAAAAAAX2h3X3RwX3BnbW5ndDogdHhfcGFn +ZV9tYXggJXUgcnhfcGFnZV9tYXggJXUgcHN0cnVjdHMgJXUgc2l6ZSAldQoAAAAAAAAAAAAAAAAA +AABObyBzcGFjZSBsZWZ0IGZvciBwZ21uZ3QsIE5lZWQgJXVCLCBhdmFpbGFibGUgJXVCLCBObyBv +ZmZsb2FkCgAAbXBhcnRpdGlvbl9vdGhlcnNfdG90YWw6IG1lbSAldSwgZGRwICV1IGRkcF9pc2Nz +aSAldSBzdGFnICV1IHBibCAldSBycSAldSBycXVkcCAldSAtPiAldQoAAAAAAAAATm8gc3BhY2Ug +bGVmdCBmb3IgcG10eCBwYWdlcywgTmVlZCAldUIsIGF2YWlsYWJsZSAldUIsIE5vIG9mZmxvYWQK +AAAAAAAAAAAAAAAAAABObyBzcGFjZSBsZWZ0IGZvciBwbXJ4IHBhZ2VzLCBOZWVkICV1QiwgYXZh +aWxhYmxlICV1QiwgTm8gb2ZmbG9hZAoAAAAAAAAAAAAAAAAAAF9tcGFydGl0aW9uX2JhbmtzX21j +WDogbmJhbmtzX3BtdHggJXUgKCV1TUIpIG5iYW5rc19wbXJ4ICV1ICgldU1CKSBuYmFua3Nfb3Ro +ZXJzICV1ICgldU1CKSBuYmFua3NfZncgJXUgKCV1TUIpCgBfbXBhcnRpdGlvbl9iYW5rc19tYzE6 +IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1CKSBuYmFua3NfZncg +JXUgKCV1TUIpCgAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tYzA6IG5iYW5rc19wbXJ4ICV1ICgl +dU1CKSBuYmFua3Nfb3RoZXJzICV1ICgldU1CKQoAAAAAAAAAAAAAAG1lbV9tYWxsb2NfaW50ZXJu +YWw6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAAAAAAAAA +AAAAAAAAaHdfZWRjX2Jpc3RbJXVdOiBiaXN0X2NtZFsweCUwOHhdIGFkZHIgMHgleCBsZW4gMHgl +eAoAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1XTogZG9uZSwgZW5jb3VudGVyZWQgJXUgZXJyb3Jz +IG9uIGZpcnN0IGFuZCAldSBlcnJvcnMgb24gc2Vjb25kIGF0dGVtcHQgKCV1Z2JwcykKAG1lbV9p +bml0X2NhY2hlczogY2FjaGVfc2l6ZSAldSBmbG93Y19idWZfdGNiX2NhY2hlX3NpemUgJXUgYnVm +bGw2NF9jYWNoZV9zaXplICV1CgAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fcG10eDogbSAweCUw +OHggc2l6ZSAldQoAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fcG1yeDogbSAweCUwOHggc2l6ZSAl +dQoAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fZWRjIChubyBleHRtZW0pOiBtIDB4JTA4eCBzaXpl +ICV1CgAAAGVkYyBvdmVyY29tbWl0ZWQgYnkgJWRCLCAweCV4LzB4JXgKAAAAAAAAAAAAAAAAAGVk +YyBvdmVyY29tbWl0ZWQgYnkgJWRCLCAweCV4LzB4JXgvJWQKAAAAAAAAAAAAAG1wYXJ0aXRpb25f +ZWRjX2VzdGltYXRlOiBodyBtb2R1bGVzIHJlcXVpcmUgJWQgYnl0ZXMgaW4gRURDCgAAAABUZW1w +ZXJhdHVyZS9Wb2x0YWdlIFNlbnNvcjogQ29yZSBjbG9jayAldSA+ICV1OyBjYXBwaW5nIHRvIHN0 +YXkgaW4gY29tcGxpYW5jZSB3aXRoIGhhcmR3YXJlLgoAAABzZXR0aW5nIHVwIHJpbmcgYmFja2Jv +bmUKAAAAAAAAAHJpbmcgYmFja2JvbmUgY29uZmlnIGVycm9yLCBUQ0FNIG5vdCBlbXB0eS4gYXZh +aWxhYmxlICVkLCBzaXplICVkCgAAAAAAAAAAAAAAAAAAZm9pc2NzaV9jb3JlX2J5ZTogYWN0aXZl +IHNlc3NfY250ICVkCgAAAAAAAAAAAAAAaHdfbWFjX2FlY19jb21wbGV0ZVsldV0gb24gbGFuZXMg +JSN4IChzaWdkZXQgJSN4KSwgdHhfbGFuZXMgJSN4CgAAAAAAAAAAAAAAAAAAAABhZWNfZnNtWyV1 +XSA6IHN0YXRlIFNUQVJUIChzaWdkZXQgJSN4KQoAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHRyYW5z +aXRpb25pbmcgdG8gVFJBSU5JTkcKAAAAAAAAAABhZWNfZnNtWyV1XSA6IFRSQUlOSU5HX0NPTVBM +RVRFCgAAAAAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IExvY2FsIGZhdWx0IHdoaWxlIHdhaXRp +bmcgZm9yIGxpbmsgc3RhdHVzIDB4JXggOiAweCV4CgAAAAAAAAAAAAAAAGFlY19mc21bJXVdIDog +UmVtb3RlIGZhdWx0IHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4JXgKAABhZWNfZnNt +WyV1XSA6IFJlbW90ZSBmYXVsdCBjbGVhcmVkIHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVz +IDB4JXgKAAAAAAAAAAAAAGFlY19mc21bJXVdIDogRE9ORQoAAAAAAAAAAAAAAAAAYWVjX2ZzbVsl +dV0gdGltZWQgb3V0IHRyYWluaW5nIEZTTV9TVEFURV8wIDB4JXgsIF8xIDB4JXggXzIgMHgleCBf +MyAweCV4LCBMaW5rIFN0YXR1cyAweCV4CgAAAAAAYmVhbl9mc21bJXVdIDogc3RhdGUgU1RBUlQg +KGNvdW50ID0gJXUpCgAAAAAAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9T +SUdERVQKAAAAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgQkFTRVBfSEFORExFCgAA +AAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9DT01QTEVURQoAAAAAYmVhbl9m +c21bJXVdIDogREwgNDBHIE5lZ290aWF0aW9uIEVycm9yIC0gQXR0ZW1wdGluZyB0byBjb250aW51 +ZQoAAAAAAAAAAAAAAAAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBET05FCgAAAAAAAGJlYW5fZnNt +WyV1XSA6IHN0YXRlIFJFU1RBUlQxCgAAYmVhbl9mc21bJXVdIDogc3RhdGUgUkVTVEFSVDIKAABi +ZWFuX2ZzbVsldV0gOiBzdGF0ZSBSRVNUQVJUMwoAAGJlYW5fZnNtWyV1XSBUSU1FT1VUOyBzdGF0 +ZSAldSBldGhfc3RhdHVzICUjeCBiZWFuX3N0YXR1cyAlI3ggaHNzIHNpZ2RldCAlI3ggcmV0cnlf +Y250ICV1CgAAAAAAAGh3X21hY19saW5rX3N0YXR1c1sldV0gaW50X2NhdXNlIDB4JXgsIGxpbmtf +c3RhdHVzIDB4JXgKAAAAAAAAAABwb3J0ICV1IGNoYW5naW5nIHNwZWVkIHRvIDFHCgAAAHBvcnQg +JXUgbmVnb3RpYXRlZCB1bnN1cHBvcnRlZCBzcGVlZCAlI3gKAAAAAAAAAGJlYW4vYWVjIGNvbXBs +ZXRlIChyZXRyeTogJXUpCgAAcG9ydFsldV0gcmVzZXR0aW5nIEtSCgAAAAAAAAAAAABwb3J0ICV1 +IG5lZ290aWF0ZWQgdW5zdXBwb3J0ZWQgc3BlZWQgJSN4CgAAAAAAAABiZWFuL2FlYyBjb21wbGV0 +ZSAocmV0cnk6ICV1KQoAAFJhbmdlIGNhbGM6IEF2ZXJhZ2VkICUjeCBidXQgaWdub3JlZCB2YWx1 +ZSAlI3ggKGl0ZXJhdGlvbiAldSkKAABNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5v +dCBnb2luZyB0byAwCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBjb21wbGV0 +aW5nCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21wbGV0ZS4K +AAAAAAAAAAAAAAAATUMgY29tbWFuZCBmYWlsZWQgdG8gY29tcGxldGUob3Bjb2RlICUjeCBjYWRk +ciAlI3ggYmFkZHIgJSN4IGRlbGF5ICVkKQoAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvbXBsZXRl +IGltbWVkaWF0ZQoAAAAAAAAAAAAAAAAAAABwZm5fYml0bWFwIDB4JXgKAAAAAAAAAAAAAAAAAAAA +AGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4ID4gTEFTVEMy +RSAweCV4CgBtYWlsYm94IGNtZCBub3QgeWV0IHN1cHBvcnRlZDogcGZuIDB4JXggdmZuIDB4JXg7 +IG9wY29kZSAweCV4CgAAYmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2Rl +IDB4JXggaXMgdmFsaWQgcG9zdCBkZXZpY2UgaW5pdCBvbmx5CgBiYWQgbWFpbGJveCBjbWQ6IHBm +biAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHglMDJ4IHJhbWFzayAweCV4IGNtZCByYW1hc2sgMHgl +eAoAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCUwMnggbGVu +MTYgMHgleCB2ZXJzdXMgZXhwZWN0ZWQgbGVuMTYgMHgleAoAAAAAAAAAAGluc3VmZmljaWVudCBj +YXBzIHRvIHByb2Nlc3MgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2NhcHMgMHgl +eCB3eF9jYXBzIDB4JXggcmVxdWlyZWQgcl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAAAAAAAAAA +aW5zdWZmaWNpZW50IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4 +JXg7IHJfY2FwcyAweCV4IHd4X2NhcHMgMHgleCByZXF1aXJlZCByX2NhcHMgMHgleCB3X2NhcHMg +MHgleAoAAAAAAAAAAABkb3dubG9hZF9zcmFtOiBlcnJvciwgcmV0ICVkCgAAAGRvd25sb2FkX3Rj +YW06IGVycm9yLCByZXQgJWQKAAAAaHdfcG93ZXJfcHJlcDogVkREPU5PTkUgYnV0IFZDUz0lZAoA +AAAAAAAAAAAAAAAAaHdfcG93ZXJfcHJlcDogdW5zdXBwb3J0ZWQgZXh0ZXJuYWwgYWRqdXN0YWJs +ZSBwb3dlciByZWd1bGF0b3JzIFZERD0lZCwgVkNTPSVkCgBod19wb3dlcl9wcmVwOiB1bnN1cHBv +cnRlZCBWREQ9JWQKAAAAAAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWQ1M9 +JWQKAAAAAAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiBpMmMgd3JpdGUgZXJyb3IsIFZERD0lZCxy +ZXQ9JWQKAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWREQ9JWQKAAAAAAAAAAAAAAAAAABo +d19wb3dlcl9wcmVwOiBpMmMgd3JpdGUgZXJyb3IsIFZDUz0lZCxyZXQ9JWQKAABod19wb3dlcl9w +cmVwOiB1bnN1cHBvcnRlZCBWQ1M9JWQKAAAAAAAAAAAAAAAAAABWUEQgcmVnaW9uIGlzIHRvbyBz +bWFsbCAoU0VSQ0ZHX1NSX1BGTlZQRFNJWkUgMHgleCkKAAAAAAAAAAAAAAAAY2ZfcHJlcDogZXJy +b3IsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIIAAAEgAAAAAAAAAIIAAAEAAAAA +AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAgAAAAAAAAAAAAAAAAIAAAAAA +AAAAAAcAAAAAAAAAAAAAAAEAAAAAEAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAAAAAAAgBADAAAA +AAAACAAAAAACAAAAAAAAAAAAIAAAAAAAAAAAAAAAAQADgAAAAAAAAAAAAAACAAAAAAAAAAAAIAOA +AAAAAAAAAAAAEAKAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAA +IAAAAAAAAAAAAAAAgAACgAAAAAAAAAAAAAACgAAAAAAAAAAAgAACAAAAAAAAAAAAAAACAAAAAAAA +AAAAAAACgAAAAAAAAAAAAQADAAAAAAAAAAAAAAKDAAAAAAAAAAAAEAKAAAAAAAAAAAAAMAADAAAA +AAAACAAAMAADAAAAAAAAAAAAMAWDAAAAAAAACAAAMAWDAAAAAAAAAAAAMASDAAAAAAAACAAAMASD +AAAAAAAAAAAAMAMDAAAAAAAACAAAMAMDAAAAAAAAAAAAOAMDAAAAAAAAAAAAOAWDAAAAAAAAAAAA +OASDAAAAAAAAAAAAOAADAAAAAAAAAAAANAaCAAAAAAAAAAAAPAOCAAAAAAAAAAAAPAADAAAAAAAA +CAAAPAADAAAAAAAAAAAAPASDAAAAAAAAAAAAPAUDAAAAAAAAAAAAPQQDAAAAAAAAAAAAPAODAAAA +AAAAAAAALAACAAAAAAAAAAAALAWCAAAAAAAAAAAALAUCAAAAAAAAAAAAEAaAAAAAAAAAAAAAEAaC +gAAAAAAAAAAAAA6CAAAAAAAAAAAAEAeCgAAAACAAAAAAAAeCAAAAACAAAAAAEAcCgAAAAAAAAAAA +EAcCgAAAAAAAAAAAEAcCgAAAAAAAAAAAAAcCAAAAACAAAAAAEBeDAAAAAAAACAAAEBeDAAAAAAAA +CAAAEAAAAAAAAAAAAAAAEAYDgAAAAAAAAAAAAA4DAAAAAAAAAAAAEAYDQAAAAAAAAAAAEAYDAAAA +AAAAAAAAEAYAAAAAAAAAAAAAAAYDgAAAAAAAAAAAAAYDAAAAAAAAAAAAAA4CAAAAAAAAAAAAAA4C +AAAAAAAAAAAAEAYCAAAAAAAAAAAAEAYCAAAAAAAAAAAAEAYCgAAAAAAAAAAAEAYCgAAAAAAAAAAA +AAACAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAABADAAAAAAAA +CAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////AAAAIAAAAADAAAAAAAAAIAAAAADgAAAAAAAA +AAIAAAAAAAAAQAAAAAAAAAAAAAAAAAABIQAAAAAAAAAAAAEBIAAAAAAAAAAAAAACAAAABAAEAAAA +AACBQAAAAAAAAAAAAAaAAAAEAAAAAAAAAIAAQAAAAAAAAgAAAIAAIAAAAAAAAgAACIAAAAAAAEAA +AAACAQBAAAAAAAAAAAAAAQBCAAAAAAAAAAAAAAAgAAAAAAAAAAAAAhAgAAAAAAAAAAAAAgwCAAAA +AAAAAAAAAIUCAAAABAAAAAAAAIBCAAAAAAAAAAAAgIBCAEAAAAAAAAAAgIBCAAAAAAAAAAAAAgAi +AAAAAAAAAAAAAIBBAAAAAAAAAAAAgIBBAAAAAAAAAAAAAIBBgAAAAAAAAAAAgIBBgAAAAAAAAAAA +AgAhAAAAAAAAAAAAABAggAAAAAAAAAAAAiUAgAAAAAAAAAAAAAUAAAAAAAAAAAAACIgEgAAAAAAA +AAAACIgEgAAAAAAAAAAACKIAgAAAAAAAAAAACKIAgAAAAAAAAAAACKMAgAAAAAAAAAAACKMAgAAA +AAAAAAAACKSAgAAAAAAAAAAACKSAgAAAAAAAAAAABKSAwAAAAAAAAAAABKIAwAAAAAAAAAAABKMA +wAAAAAAAAAAABIgEwAAAAAAAAAAAAAkBgAAAAAAAAAAAAgwAgAAAAAAAAAAAAIgEwAAAAAAAAAAA +AIgEgAAAAAAAAAAAAgsAgAAAAAAAAAAAAIqAgAAAAAAAAAAAAAuAgAAAAAAAAAAAAIwAgAAAAAAA +AAAAAiAQgAAAAAAAAAAAAgoAgAAAAAAAAAAAAgqAgAAAAAAAAAAAAAkCgAAAAAAAAAAAAAEBAAAA +AAAAAAAAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAACBEAAAAAAAAAAAAACB +CAAAAAAAAAAAAACBBAAAAAAAAAAAAACBgAAAAAAAAAAAAIAAwAAAAAAAAAAAAIAAoAAAAAAAAAAA +AAAIAAAAAAAAAAAAAIGAAAAAAAAAAAAAAIGAgAAAAAAAAAAAAImAgAAAAAAAAAAAAImAwAAAAAAA +AAAAAAGCAAAAAAAAAAAAAgGAAAAAAAAAAAAAAgGAgAAAAAAAAAAAAEGBgAAAAAAAAAAAAgGBgAAA +AAAAAAAAAEmBgAAAAAAAAAAAAgmBgAAAAAAAAAAAAgGBAAAAAAAAAAAAAEGBAAAAAAAAAAAAIAAA +AAAAAAAAAAAAEAAAAgEAAAAAAAAAEAAAAgAAAAAAAAAAEAAAAAAAAAAAAAAAAIAAwAAAAAAAAAAA +AAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAJIAAAAA +AAAAA2YAIABAAAAAAAgAkgAAAAAAAAADcgElBEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAIAAAA +AgCIA4cAAFYAIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAA +AAAAAAAAAAAAA5YAIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAA +AAAAAAAAAAAAAAAAA5YAIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAACAAAAAIAiAOFAACWASAA +QAAAAAAIAAAAAgCIA4UAAJYBIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOW +ACAAQAAAAAAIAAAAAgCIA4UAAJYBIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAC +AAOWACYEQAAAAAAIRyABBAAAArAAAtIFQCREAAAAAAhHIAEEAAACsgAC0gVGJEAAAAAACAAAAAIA +iAOHAACWASYEQAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAABHIAEGDKGCskABkgRAJEQAAAAACAAA +AAIAiAOHAACWASYEQAAAAAAARyABBAygQrGAAhIFQCREAAAAAAgAAAACAIgDhwAAlgEmBEAAAAAA +CAAAAAIAiAOFAACWASAAQAAAAAAIAAAAAgCIA4UAAJYBIABAAAAAAAgAAAACAIgDhQAAlgEgAEAA +AAAAAAAAAAAAAAAAAAOWACAAQAAAAAANxRK6ArCA0xRUi+JKRiRAAAAAAAXFEroCt4DTFFSLYkmm +JEAAAAAABcUSogawgNMUVIviSkYkQAAAAAANxRKiBreA0xRUi2JJpiRAAAAAAAXFEqIGsIDTFFSL +4kpGJEAAAAAADcUSoga3gNMUVItiSaYkQAAAAAAFxRKiBrCA0xRUi+JKRiRAAAAAAA3FEqIGt4DT +FFSLYkmmJEAAAAAACcQQoAIAgJAAAItiacYkQAAAAAABxBCgBrCAkwZUi2JpxiRAAAAAAAHEEKAG +sICTBlSLYmnGJEAAAAAAAcUQuAawgJMWVItiSMYkQAAAAAAIoRCIAgCBWBIAC1IApiRAAAAAAAnA +EJACsIADFlSKkgHGJEAAAAAACcAQuAawgAMQlIviAkYkQAAAAAAJwBC4ArSAAxCUi2IBpiRAAAAA +AAnAELgCtIADEJSLYgGmJEAAAAAACcAQuAK0gAMQlItiAaYkQAAAAAAJwBC4ArSAAxCUi2IBpiRA +AAAAAAGgEJAGtIADEJSLYgGmJEAAAAAAAcAQgAKwgAMUVIpSAMYkQAAAAAABwBCAArCAAxRUilIA +xiRAAAAAAAHAEIACsIADFFSKUgDGJEAAAAAACEcgAQQAAAKwAALSBEAkQAAAAAAAgQAAAgCFWAdA +C1IApiRAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAAAAAAAAYAoYAAQAFWACAAQAAAAAAAAAAABACg +QAGAAdYAIABAAAAAAAiBAAACAIVZgAQLUgCmJEAAAAAACgFAAAAAABgCAANCASakQgAAAAAAAAAA +AAAAAAAAA5YAIABAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAACAAAAAIAiAOFAAPWACAAQAAAAAAI +AAAAAgCIA4UAA9YAIABAAAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAA +AAAAAAAABACgQAGAAdYAIABAAAAAAAnAELgCtIADEJSLYgGmJEAAAAAAAAAAAAAAAAACAAOWACYE +QAAAAAAAAAAAAAAAAAAAA5YAIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAQAoEABgAHW +ACAAQAAAAAAAAAAABACgQAGAAdYAIABAAAAAAAAAAAAEAKBAAYAB1gAgAEAAAAAACKEQiAIAgVgQ +AAkSAaYkQAAAAAAAAAAABACgQAGAAdYAIABAAAAAAAAAAAAGAKGAAEABVgAgAEAAAAAACAAAAAIA +iAOHQAjSAkYkQgAAAAAJxRKiApSI0hKAiyJJxiRAAAAAAAHAEIAGpIgBBVSLUgDGJEAAAAAACcAQ +gAKkiACFVItSAMYkQAAAAAAJwBCABrSIAwEUi1IBpiRAAAAAAA3AAAACsIDDFlSL4gNGJEAAAAAA +AAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAwAAQAAAACAAAC +ACYkQAAAAAAARzAABgMgArcACAIBwCRAAAAAAAgDAAACBqAKtwAIAgHGJEYAAAAAAAAAAAAAAAAC +AAACACYkQAAAAAAAIFAABAAAAAAAAAIBJiRGAAAAAAhgIACEAAAAAAAABgAgAEAAAAAACGAgAIQA +AAACATACACYlQAAAAAAIYAAABACEAYIEBAIBxiTCAAAAAAHAAAACQ4ADAgyIAgGmJEAAAAAACABg +AAQAAAACAAACACYkQAAAAAAIAGAABAAAAAAAAAQBIABAAAAAAAAAAAAAAAAAAAAABAEgAEAAAAAA +BAgUgAYKAAAHAUwCIKYmQAAAAAAIgAAABgCEAYAECAIBpiTAAAAAAABAAAACAKAAAEAIAgCmJEYA +AAAAAAAAAAAAAAACAAACACYkQAAAAAAEAAAAAoQAAwKKCAIEwCRAAAAAAAAAAAAAAAAAAgAABgEg +SEAAAAAAACBQAAQAAAACAAACACYkQAAAAAAIYCAAhAAAAAIAAAYAJgRAAAAAAAhgIACEAAAAAgAA +AgEmJUAAAAAACGAAAAQAhAGABAQCAcYkwAAAAAAIAGAABAAAAAAAAAQBIABAAAAAAAAAgAAgAAAA +AAAAAgAmTHAAAAAAAACAACAAAAAAAAAGASAAAAAAAAAAAIAAIAAAAAAAAAIAJkxwAAAAAAAAgAAg +AAAAAAAABgEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAnAAAAItIwECRYEAgTGJEAAAAAACcAAAAw0gAQJFgQCBMYkQAAAAAAECHSATAkAAFAAXAJh5iRA +AAAAAAwIdIBEAAAAUgBAAmEmJEAAAAAACAIQoAQAAAAAAQACACYkQAAAAAAIAhCgBAAAAAABAAIA +JiRAAAAAAAQIdABCAQAABwCIAmDGJEAAAAAADcgUAAIJAAAEQJwCYOYkQAAAAAAJyBCAArSABAKU +iAJlxiRAAAAAAA3IdABMtIADAJSIAmCmJMAAAAAABch0AEg0kAMAlIgCYKYkwAAAAAAIRwAABAAA +AAAAAAIBICRAAAAAAAhHAAAEAAAAAAAAAgRAJEAAAAAAAEcgAQwHIcK3AAgCAMAkRAAAAAAARyAB +DAchwrcACAIAwCREAAAAAABHIAEMByHCtwAIAgDAJEQAAAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAA +ACABCACEAAVAiAIBxiTAAAAAAAAAIAEIAIQABUCIAgHGJMAAAAAAAAAgAYaCAAECwIgCA8YkwAAA +AAAAACABgoIAAALAiAIDxiTAAAAAAAnAIAGCpIABBUCIAgHGJMAAAAAACAAAAAwAhAAFQIgCAcYk +wAAAAAAAACABhoIAAQLAiAIDxiTAAAAAAAAAIAGCggAAAMCIAgKmJMAAAAAACcAgAYKkgAEFQIgC +AcYkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAEAAQQJAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAW2dsb2JhbF0KcnNzX2dsYl9jb25maWdfbW9kZT1iYXNpY3ZpcnR1 +YWwKcnNzX2dsYl9jb25maWdfb3B0aW9ucz10bmxtYXBlbixoYXNodG9lcGxpdHosdG5sYWxsbGtw +CnBsX3RpbWVvdXRfdmFsdWU9MTAwMDAKcmVnWzB4MTAwOF09MHg0MDgxMC8weDIxYzcwCnJlZ1sw +eDEwMGNdPTB4MjIyMjIyMjIKcmVnWzB4MTBhMF09MHgwMTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2 +CnJlZ1sweDEwNDhdPTY1NTM2CnJlZ1sweDEwNGNdPTE1MzYKcmVnWzB4MTA1MF09OTAyNApyZWdb +MHgxMDU0XT05MjE2CnJlZ1sweDEwNThdPTIwNDgKcmVnWzB4MTA1Y109MTI4CnJlZ1sweDEwNjBd +PTgxOTIKcmVnWzB4MTA2NF09MTYzODQKcmVnWzB4MTBhNF09MHgwMDI4MDAwMC8weDNmZmMwMDAw +CnJlZ1sweDExMThdPTB4MDAwMDI4MDAvMHgwMDAwM2MwMApyZWdbMHgxMGE4XT0weDQwMjAwMC8w +eDQwMjAwMApiYXIydGhyb3R0bGVjb3VudD01MDAKc2dlX3RpbWVyX3ZhbHVlPTUsMTAsMjAsNTAs +MTAwLDIwMApyZWdbMHgxMTI0XT0weDAwMDAwNDAwLzB4MDAwMDA0MDAKcmVnWzB4MTEzMF09MHgw +MGQ1ZmZlYgpyZWdbMHgxMTNjXT0weDAwMDJmZmMwCnJlZ1sweDdkMDRdPTB4MDAwMTAwMDAvMHgw +MDAxMDAwMApyZWdbMHg3ZDZjXT0weDAwMDAwMDAwLzB4MDAwMDcwMDAKcmVnWzB4N2Q3OF09MHgw +MDAwMDQwMC8weDAwMDAwMDAwCnJlZ1sweDdkYzBdPTB4MGUyZjg4NDkKZmlsdGVyTW9kZT1mY29l +bWFzayxzcnZyc3JhbSxmcmFnbWVudGF0aW9uLG1wc2hpdHR5cGUscHJvdG9jb2wsdmxhbixwb3J0 +LGZjb2UKZmlsdGVyTWFzaz1wcm90b2NvbCxmY29lCnRwX3Btcng9MzAKdHBfcG1yeF9wYWdlc2l6 +ZT02NEsKdHBfbnJ4Y2g9MAp0cF9wbXR4PTUwCnRwX3BtdHhfcGFnZXNpemU9NjRLCnRwX250eGNo +PTAKdHBfbXR1cz04OCwyNTYsNTEyLDU3Niw4MDgsMTAyNCwxMjgwLDE0ODgsMTUwMCwyMDAyLDIw +NDgsNDA5Niw0MzUyLDgxOTIsOTAwMCw5NjAwCnJlZ1sweDdkMDhdPTB4MDAwMDA4MDAvMHgwMDAw +MDgwMApyZWdbMHg3ZDQ4XT0weDAwMDAwMDAwLzB4MDAwMDA0MDAKcmVnWzB4N2Q2MF09MHgwNjAw +MDAwMC8weDA3MDAwMDAwCnJlZ1sweDE5MTY4XT0weDA0MDIwMTAwCnJlZ1sweDE5YzA0XT0weDAw +NDAwMDAwLzB4MDA0MDAwMDAKbWNfbW9kZV9icmNbMF09MQptY19tb2RlX2JyY1sxXT0xCnJlZ1sw +eDhkYzBdPTB4MDAwMDAwMDQvMHgwMDAwMDAwNApbZnVuY3Rpb24iMCJdCm52Zj0xNgp3eF9jYXBz +PWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0 +Zj04CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEiXQpudmY9MTYKd3hfY2Fwcz1hbGwK +cl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApj +bWFzaz1hbGwKcG1hc2s9MHgyCltmdW5jdGlvbiIyIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fw +cz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9 +YWxsCnBtYXNrPTB4NApbZnVuY3Rpb24iMyJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxs +Cm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApw +bWFzaz0weDgKW2Z1bmN0aW9uIjQiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0yOApuaXFm +bGludD0xNzAKbmV0aGN0cmw9MTAwCm5lcT0yNTYKbnFwY3E9MTIyODgKbmV4YWN0Zj00MApjbWFz +az1hbGwKcG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbnJvdXRlPTMyCm5jbGlwPTMyCm5maWx0ZXI9 +NDk2Cm5zZXJ2ZXI9NDk2Cm5oYXNoPTEyMjg4CnByb3RvY29sPW5pY192bSxvZmxkLHJkZHAscmRt +YWMsaXNjc2lfaW5pdGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1LGlzY3NpX3QxMGRpZgp0cF9s +MnQ9MzA3Mgp0cF9kZHA9Mgp0cF9kZHBfaXNjc2k9Mgp0cF9zdGFnPTIKdHBfcGJsPTUKdHBfcnE9 +NwpbZnVuY3Rpb24iNSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxpbnQ9MzQK +bmV0aGN0cmw9MzIKbmVxPTY0Cm5leGFjdGY9MTYKY21hc2s9YWxsCnBtYXNrPWFsbApuc2VydmVy +PTE2Cm5oYXNoPTIwNDgKdHBfbDJ0PTEwMjAKcHJvdG9jb2w9aXNjc2lfaW5pdGlhdG9yX2ZvZmxk +CnRwX2RkcF9pc2NzaT0yCmlzY3NpX250YXNrPTIwNDgKaXNjc2lfbnNlc3M9MjA0OAppc2NzaV9u +Y29ubl9wZXJfc2Vzc2lvbj0xCmlzY3NpX25pbml0aWF0b3JfaW5zdGFuY2U9NjQKW2Z1bmN0aW9u +IjYiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00Cm5pcWZsaW50PTM0Cm5ldGhjdHJsPTMy +Cm5lcT02NgpuZXhhY3RmPTMyCmNtYXNrPWFsbApwbWFzaz1hbGwKbmhhc2g9MjA0OAp0cF9sMnQ9 +NApwcm90b2NvbD1mY29lX2luaXRpYXRvcgp0cF9kZHA9MgpmY29lX25mY2Y9MTYKZmNvZV9udm5w +PTMyCmZjb2VfbnNzbj0xMDI0CltmdW5jdGlvbiIxMDIzIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFs +bApudmk9NApjbWFzaz1hbGwKcG1hc2s9YWxsCm5leGFjdGY9OApuZmlsdGVyPTE2CltmdW5jdGlv +biIwLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3Ry +bD00Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIxLyoiXQp3 +eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3RybD00Cm5lcT04 +Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgyCltmdW5jdGlvbiIyLyoiXQp3eF9jYXBzPTB4 +ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3RybD00Cm5lcT04Cm5leGFjdGY9 +NApjbWFzaz1hbGwKcG1hc2s9MHg0CltmdW5jdGlvbiIzLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBz +PTB4ODYKbnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3RybD00Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1h +bGwKcG1hc2s9MHg4Cltwb3J0IjAiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1 +Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpk +Y2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2Nr +ZXRudW0sNQpbcG9ydCIxIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209 +MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2Fw +cF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVt +LDUKW3BvcnQiMiJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3 +bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2 +WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltw +b3J0IjMiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUK +ZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0w +eDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbZmluaV0K +dmVyc2lvbj0weDE0MjUwMDFjCmNoZWNrc3VtPTB4MzYyMjhjN2IKAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAW2dsb2JhbF0KcnNzX2dsYl9jb25maWdfbW9kZT1iYXNpY3ZpcnR1YWwKcnNzX2ds +Yl9jb25maWdfb3B0aW9ucz10bmxtYXBlbixoYXNodG9lcGxpdHosdG5sYWxsbGtwCnBsX3RpbWVv +dXRfdmFsdWU9MTAwMDAKcmVnWzB4MTAwOF09MHg0MDgxMC8weDIxYzcwCnJlZ1sweDEwMGNdPTB4 +MjIyMjIyMjIKcmVnWzB4MTBhMF09MHgwMTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sweDEw +NDhdPTY1NTM2CnJlZ1sweDEwNGNdPTE1MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0XT05 +MjE2CnJlZ1sweDEwNThdPTIwNDgKcmVnWzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIKcmVn +WzB4MTA2NF09MTYzODQKcmVnWzB4MTBhNF09MHhhMDAwYTAwMC8weGYwMDBmMDAwCnJlZ1sweDEw +YThdPTB4NDAyMDAwLzB4NDAyMDAwCmJhcjJ0aHJvdHRsZWNvdW50PTUwMApzZ2VfdGltZXJfdmFs +dWU9NSwxMCwyMCw1MCwxMDAsMjAwCnJlZ1sweDExMjRdPTB4MDAwMDA0MDAvMHgwMDAwMDQwMApy +ZWdbMHgxMTMwXT0weDAwZDVmZmViCnJlZ1sweDExM2NdPTB4MDAwMmZmYzAKcmVnWzB4N2QwNF09 +MHgwMDAxMDAwMC8weDAwMDEwMDAwCnJlZ1sweDdkNmNdPTB4MDAwMDAwMDAvMHgwMDAwNzAwMApy +ZWdbMHg3ZGMwXT0weDBlMmY4ODQ5CmZpbHRlck1vZGU9ZmNvZW1hc2ssc3J2cnNyYW0sZnJhZ21l +bnRhdGlvbixtcHNoaXR0eXBlLHByb3RvY29sLHZsYW4scG9ydCxmY29lCmZpbHRlck1hc2s9cHJv +dG9jb2wsZmNvZQp0cF9wbXJ4PTMwCnRwX3BtcnhfcGFnZXNpemU9NjRLCnRwX25yeGNoPTAKdHBf +cG10eD01MAp0cF9wbXR4X3BhZ2VzaXplPTY0Swp0cF9udHhjaD0wCnRwX210dXM9ODgsMjU2LDUx +Miw1NzYsODA4LDEwMjQsMTI4MCwxNDg4LDE1MDAsMjAwMiwyMDQ4LDQwOTYsNDM1Miw4MTkyLDkw +MDAsOTYwMApyZWdbMHg3ZDA4XT0weDAwMDAwODAwLzB4MDAwMDA4MDAKcmVnWzB4N2Q0OF09MHgw +MDAwMDAwMC8weDAwMDAwNDAwCnJlZ1sweDdkNjBdPTB4MDYwMDAwMDAvMHgwNzAwMDAwMApyZWdb +MHgxOTE2OF09MHgwNDAyMDEwMApyZWdbMHgxOWMwNF09MHgwMDQwMDAwMC8weDAwNDAwMDAwCm1j +X21vZGVfYnJjWzBdPTEKbWNfbW9kZV9icmNbMV09MQpbZnVuY3Rpb24iMCJdCnd4X2NhcHM9YWxs +CnJfY2Fwcz1hbGwKbnZpPTI4Cm5pcWZsaW50PTE3MApuZXRoY3RybD05NgpuZXE9MjUyCm5xcGNx +PTIwNDgKbmV4YWN0Zj00MApjbWFzaz1hbGwKcG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbnJvdXRl +PTMyCm5jbGlwPTMyCm5maWx0ZXI9NDgKbnNlcnZlcj0zMgpuaGFzaD0yMDQ4CnByb3RvY29sPW5p +Y192bSxvZmxkLHJkZHAscmRtYWMsaXNjc2lfaW5pdGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1 +LGlzY3NpX3QxMGRpZgp0cF9sMnQ9NDA5Mgp0cF9kZHA9Mgp0cF9kZHBfaXNjc2k9Mgp0cF9zdGFn +PTIKdHBfcGJsPTUKdHBfcnE9NwpbZnVuY3Rpb24iMSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwK +bnZpPTQKbmlxZmxpbnQ9MzQKbmV0aGN0cmw9MzIKbmVxPTY2Cm5leGFjdGY9MzIKY21hc2s9YWxs +CnBtYXNrPWFsbApuaGFzaD0yMDQ4CnByb3RvY29sPWZjb2VfaW5pdGlhdG9yCnRwX2wydD00CnRw +X2RkcD0yCmZjb2VfbmZjZj0xNgpmY29lX252bnA9MzIKZmNvZV9uc3NuPTEwMjQKW2Z1bmN0aW9u +IjEwMjMiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00CmNtYXNrPWFsbApwbWFzaz1hbGwK +bmV4YWN0Zj04Cm5maWx0ZXI9MTYKW2Z1bmN0aW9uIjAvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9 +MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFs +bApwbWFzaz0weDEKW2Z1bmN0aW9uIjEvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9 +MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0w +eDIKW3BvcnQiMCJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3 +bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2 +WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltw +b3J0IjEiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUK +ZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0w +eDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIy +Il0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0z +MApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0 +LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMyJdCmRj +Yj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNi +X2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhl +cnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1CltmaW5pXQp2ZXJzaW9uPTB4 +MTQyNTAwMWQKY2hlY2tzdW09MHg3ZGM0ZGNkCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAA +==== diff --git a/sys/dev/cxgbe/firmware/t6fw-1.16.59.0.bin.uu b/sys/dev/cxgbe/firmware/t6fw-1.16.59.0.bin.uu deleted file mode 100644 index d506b064eeac..000000000000 --- a/sys/dev/cxgbe/firmware/t6fw-1.16.59.0.bin.uu +++ /dev/null @@ -1,11974 +0,0 @@ -/*- - * Copyright (c) 2017 Chelsio Communications, Inc. - * All rights reserved. - * - * 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 AUTHOR 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 AUTHOR 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. - */ -begin-base64 644 t6fw -AAIFMgEQOwAAARcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAABRMFJAUsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IFNhdCBBdWcgMTIgMDc6 -MDQ6MTMgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j -dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDZ4eCAwMS4xMC4zYi4wMAAAAAAAAAAAAAAAAA+Q0RJg -ANQAH/zhSOEAe/AAEAAA4QGUQOEAVyDhADC4eP///x/84UCAAAAB4QB7cAAAEAAf/9oMIAAAAOEB -nAThBQAAIoIAQOEFCAAihgBAIIIARCCGAEThBQAEAAwAAIAAAQLhAHs84QB7ROEAe+TiAAAAAAEA -AOEAe5AgAAAAAACAAOEAewAAAEAB4QB7nAAGAIgAACAAREREQuAAAADjAAST4wAIACAAAlwAAAAA -H/8QAAAAAAAf/xAEAAAAAB//EAgAAAAAH/8QDB//gAAAAAAAAAAAAAAAAADAABH/yiIaB5IQghAS -/8kT/8mTIBL/yYMgJEoAA0QBZU/xwUEEMwEEMwNlP+YS/8PAMJMgEv/DE//DhCAEMwGTIBH/wRL/ -wpIQEf/BEv/CkhAR/8EB9DEA5DES/8AC5zECFgAR/7+BEAEBX8AhAhEByRER/7wS/7ySEBH/vBL/ -vJIQYAAPEf+3Ev+7khAR/7cS/7qSEIEQEf+5wCCSERL/uJISwCCSExL/t5IQghAC8lBlL/cR/7XH -L5IQEf+0khAS/7QT/7STIMAykyET/7OTIoIiEv+yE/+ykyAjIiEU/7EEMwHJOxP/sIMwA4MUCDMR -FP+upDOTIRP/opMiYAALAAAAwDCTIRP/npMiEv+pkCCQIZAikCOQJJAlkCaQJ5AokCmQKpArkCyQ -LZAukC8gJhAgJhEiIgIS/58CKDES/5kjCgAtNzAtNzgjPQFyM/MAAgAS/5nAMC83AC83IC83QC83 -YCM9AnIz7QACABL/jcAwKDcwKDc4Iz0BcjPzEv+OwDAnNwAnNyAnN0AnN2AjPQJyM+0S/4kV/4oW -/4rAMNcgBWYBYAASBDYFAAIA0w/TDwUzDG47FAdHFAcEQ3Yx5gQ2BQUzDG877QACABL/exX/fCMK -AAInAgcEQwQ+BQUzDAdHFG878AMCABL/d8kugyCEIYUivCJ0Ow6GULRVljC0M3Qz9GP/5gBlP+Jl -X98S/2zAMgMuBQMCABL/YsAwKDdAKDdIIz0BcjPzAAIAEv9nLScAwBEBSTEASDEBAgDAABT/YwTS -MRX/Y5RQFP9iBNMxFf9ilFAU/2IE1DEV/2GUUBT/YQTVMRX/YJRQEP9gAwAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAA9DAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA -H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/wAAH/8F0OMACfgf/wXQH/8F0OMAD8gf -/wXQH/8F0OMAD8gf/wXQH/8HvOMAD8gf/we8H/8P+OMAEbQf/xAAH/8zYOMAGfgf/zNgH/8zYOMA -PVgf/4AAH//a/OMAPVggAAAAIAABauMAmFQgAAF4IAABfOMAmcAgAAF8IAABheMAmcQgAAGYIAAB -nOMAmdAgAAGcIAABpeMAmdQgAAG4IAABvOMAmeAgAAG8IAABxeMAmeQgAAHYIAAB2OMAmfAgAAHc -IAAB4uMAmfAgAAH4IAAB+OMAmfggAAH8IAAB/OMAmfggAAIYIAACGOMAmfggAAIcIAACHOMAmfgg -AAI4IAACOOMAmfggAAI8IAACPOMAmfggAAJYIAACWOMAmfggAAJcIAACYuMAmfggAAJ4IAACeOMA -mgAgAAJ8IAACguMAmgAgAAKYIAJ/CuMAmgggAoAAIAKguOMDFnwgAqC4IAKguOMDNzQgAqC4IAek -3OMDNzQgB6TgIAepkOMIO1wgCAAAIAgZUOMIQAwgCBlQIAlIbuMIWVwgCUhwIAlJ5OMJiHwgCwAA -IAsAAOMJifAgCwAAIAsAAOMJifAgCwAAIAub6OMJifAAAAAAAAAAAAAAAAAf/wAAH/+AAB/8AAAf -/gAAH/+AACAAAAAAAAAAAAAAACAAT/MgAE/oIABUKyAAT+ggAFOVIABP6CAAUKsgAFMlIABSoCAA -T+ggAFJIIABR+CAAUYMgAE/TIABRKyAAT+ggAE/oIABP6CAAUNIAAAAA////////D/z///D///8A -/CABEzYgARSyIAEU4iABFKggARRmIAEUXCABFCkgARQfIAEUFSABE8AgARTgIAETtiABE4cgARTi -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 -H/8q/B//MRAf/zB4IAPjeCALL4Af/yj8H/8qkAAAD/DgAQAAH/ziCCALfzAgCy/AIAEPnCABDGQg -C36wIAt/ACACjPAf/xngIAsygB//HbQgCzzw4P/+ACALZ8Af/xJsH/8xFCAHqeAgC0gwIAtIYEgA -AAAgAjhgH/8qhCACOnQf/xiAH/8odB//K2Qf/yg8AAAZwAAAF+wgB6nUH/8otP//8f/hAF4AH/8q -XOEALgAf/ytg4QMGAOEADgDgBQAAA/8AAB//KGQgApXAH/y//zwAAAAAB///gwAAAB//KHwgC2Sg -IAeqQCAHrNAgAm3YH/8t5CACd3zgBgAAIAKVkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYAAAAAA -AAD/////////////////////H//VVB//1VQf/9UUH//VFB//1RQf/9UUH//OvB//0bgf/8/oH//P -6B//z+ggB16UAAAAAAAAAAAAAAAAAAAAACAHYbggB2G4AAAAAAAAAAAAAAAAAAAAACAHXpQgB16U -H//SxB//0sQf/9LEH//SxB//0sQf/9LEAAAAACACQDwAAAAAAAAAAAAAAAAAAAAAAgEAAAAAAAAA -AAAAAAAAAAQAAAAAAAAAgYAAAAAAABAEAAAAAAAAAoEAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -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 -+A+f6bDIQBBAAqvlJ8gAD1ALuCjCfR+2IpqBn7Muwn2esi3Cf+rNy8AQCALdLcZ/lS6VLyUmECUm -ESUmEiUmEyUmFCUmFSUmFiUmFyUmGCUmGSUmGiUmHCUmHSUmHiUmHyUkBCUkBZUiJSQgJSQhJSQi -JSQjlSmVKpUrlSwlJRrlK8FAD5gAo+sA2EAOgADA7SDYQApwD6biANhAD6ABEFvpQc+j6yewQAn4 -D09b6T5loKZgAQEAAOsD2EAKWA5giyeMTu2wk0AOgACg6ciUwA9oDNwMmjlkrx0roADkqO9AFvgE -a+7+WcAWeAh7iqLv7lnAFmgE6ujeWcARaAT66c5ZwBEoBIrrvlnAFagEmuyuWcAVaAS6fKGl2kDr -A9hAClgOR2P/mAAqTBDrAthAClgORGP/iQAA6wPYQApYDkCPJ45O7/CTQA6AAKDt6JTAD2gO/g7a -OWSgXSugAOSo70AW+ARr6PxZwBZ4CHuKounsWcAWaASK69xZwBFoBJrszFnAESgEuu28WcAVqATK -7qxZwBVoBNp+oaXaQOsD2EAKWA4nY/+YACpMEOsC2EAKWA4kY/+JAADqKO9ACmAPMYsnY/4CK2wY -6ijvQA6AAMDtINhACkgBFRm1uSgyEY8iCYgC6DHJQA0AA58FCkdook7iANhAD6ABECjCgOqByEAQ -EAP8n7MuwoCesi3CgurAzEAQCALd7cLMQAn4DhYAACsgB+oo70AOgADA6wuCQA6AANDruJFACkgA -/WP/rAAAHbWg7yCwQA+YAKLumFnAD5gAse4QyEAOgADB7RLIQA8ID4/s/+tAD5gA1e8RyEAKQA+V -4gDYQA+gARAAbBAS5BTJQBBoDfPvHdJAEHAN4+4e0kAQeA3T7R/SQA6AD18lFCDlHNJADoAAgugR -0kAOgABh5hvSQBBIDELkFclADoAAYCYUIiYUI+YU0kAQOAxE5hXSQBGAApHmFtJAD5gAcuYX0kAQ -cAxE5hjSQBEAAoHmGdJAD5gAU+Ya0kAQEANk7ICwQBaQDCbskMhAEAgMuOuRyEAQEAyo6pLIQBAY -DIjok8hACugCyOITyUAK6AK9GbVlLHE5KhYXKxYW4gDYQBDIBJzqyO9ACpgHBuqnukAPmAAqaaMB -0Q8ctVslFhLvMrBAEAgM4+0wsEAQGAyz6xDIQA6AAKXrQ9hACugGAuVht8AK6AKxWdKmJBYRKhYa -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 -IALoECAC6BAgAuj8IALoECAC6kEgAugQIALoECAC6kEgAuggAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAIAMhqCADIXkgAyGQIAMhkCADIZAgAyGQIAMhkCADIZAgAyNfIAMjICADIZAgAyGQIAMhkCAD -IZAgAyGQIAMhkCADItEgAyJrIAMiEiADIfcgAyHfIAMhxwMBAAIAAAAAIASvyCAEsO0gBLGJIASv -yCAEsYEgBLFkIASvyCAEr8ggBK/IIASxRyAEr8ggBK/IIASvyCAEr8ggBK/IIASvyCAEsTcgBLEq -IASvyCAEr8ggBK/IIASvyCAEr8ggBK/IIASvyCAEr8ggBK/IIASvyCAEr8ggBK/IIASvyCAEr8gg -BLAxIASvyCAEsCsgBLArIASvyCAEsCsgBLArIASxBSAEsCsAAAAAAAAAAAAAAAAgBNEkIATRJCAE -0HQgBNEkIATNRCAE0RogBND4IATNRCAEzUQgBM1EIATNRCAEzUQgBNBYIATRJCAEzUQgBNBYIATR -JAAAAAAAAAAAAAAAACAE32ggBN28IATiKiAE4d0gBOGeIAThWSAE4S8gBN4dIAThBCAE4L0gBOBc -IATgASAE37MgBN+IARAYAQACAAABEBgBAAIAAAAAAAAAAAAAIAWvNyAFqowgBa8MIAWu4SAFrrYg -Ba6iIAWqsCAFqs8gBa6JIAWrBCAFqvAgBaqwIAWrBCAFqrAgBaqwIAWqsCAFrzcAAAAAAAAAAAAA -AAAAAAAAIAX/oCAF9zAgBfbIIAXzgCAF7jgAAAAAAAAAACAF9xAgBfcIIAX3CCAF9wggBfcQIAX3 -CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcI -IAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wgg -BfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF -9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9xAgBfcIIAX3 -CCAF9wggBfcQIAX3CCAF9wggBfcIIAX3ECAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcQ -IAX3CCAF9wggBfcIIAX3ECAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcQIAX3CCAF9wgg -BfcIIAX3ECAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcQIAX3CCAF9wggBfcIIAX3ECAF -9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcQIAX3CCAF9wggBfcIIAX3ECAF9wggBfcIIAX3 -CCAF9xAgBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcI -IAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3ECAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wgg -BfcIIAX3CCAF9wggBfcIIAX3ECAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF -9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3 -ECAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcQIAX3CCAF9wggBfcIIAX3CCAF9wggBfcI -IAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wgg -BfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF -9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3 -CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9xAgBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcI -IAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wgg -BfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF -9wggBfcIIAX3CCAF9wggBfcIIAX3CCAF9wggBfcIIAX3EAAAAAAAAAAAAAAAACAF92kgBffFIAX8 -ACAF++4gBfvTIAX7wSAF+6AgBfuOIAX7bSAF+1wgBftBIAX7LCAF+xEgBfsAIAX65SAF92AgBfrK -IAX6uSAF+p4gBfqMIAX6cSAF+lggBfo1IAX6WCAF+jUgBfojIAX6CCAF92AgBfdgIAX3YCAF92Ag -Bfn3IAX3hSAF92AgBfdgIAX3YCAF+dYgBfm6IAX5rCAF+ZUgBfdgIAX5giAF+WQgBflRIAX5MyAF -+SAgBfkNIAX4+iAF+OcgBfjaIAX4yCAF+KcgBfiWIAX4eyAF+GkgBfhOIAX4GCAF+AcgBffsIAX3 -1yAF97AAAAAAAAAAAAAAAAAgBf/0IAYAAiAGAqAgBgJyIAYCZyAGAlwgBgJRIAYCRiAGAjsgBgIw -IAYCJSAGAhcgBgIJIAYB6yAGAbkgBgGNIAYBgCAGAWEgBgFTIAYBRSAGATEgBgEmIAYBDSAGAQIg -Bf/dIAYA0yAGAMUgBgC3IAYArCAGAKEgBgCLIAYATyAGAD4gBgAzIAYAKCAGABMAAAAFAAAABQAA -AAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAAgBjnuIAY6ACAGPGAgBjnuIAY6 -ACAGOgAgBjoAIAY8YCAGOe4gBjnuIAY57iAGOgAgBjnuIAY57iAGPFggBjxYIAY8UCAGPFAgBjxI -IAY8QCAGPEggBjxIAAAAAAAAAAAgBknHIAZIUCAGSecgBknHIAZIUCAGSFAgBkhQIAZJ5yAGSccg -BknHIAZJxyAGSFAgBknHIAZJxyAGSd8gBknfIAZJ1yAGSdcgBknPIAZJvyAGSc8gBknPAAAAAAAA -AAAgBkkjIAZJNCAGSg8gBkkjIAZJNCAGSTQgBkk0IAZKDyAGSSMgBkkjIAZJIyAGSTQgBkkjIAZJ -IyAGSgcgBkoHIAZJ/yAGSf8gBkn3IAZJ7yAGSfcgBkn3AAAAAAAAAAAgBkofIAZJSiAGSj8gBkof -IAZJSiAGSUogBklKIAZKPyAGSh8gBkofIAZKHyAGSUogBkofIAZKHyAGSjcgBko3IAZKLyAGSi8g -BkonIAZKFyAGSicgBkonAAAAAAAAAAAgBkm1IAZJcyAGSasgBkm1IAZJcyAGSXMgBklzIAZJqyAG -SbUgBkm1IAZJtSAGSXMgBkm1IAZJtSAGSaEgBkmhIAZJlyAGSZcgBkmNIAZJgyAGSY0gBkmNAAAA -AAAAAAAgBtfIIAbU4CAG0zQgBtDYIAbO8CAGwYAgBsLYIAbNCCAGwPAgBs/EAAAAAAAAAAAAACoY -AABAAAAAQAAAAAAAAAAqBAAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAIAcPmCAHD4YgBw+4IAcPmCAHD4YgBw+GIAcPhiAHD7ggBw+YIAcPmCAHD5ggBw+GIAcPmCAH -D5ggBw+wIAcPsCAHD6ggBw+oIAcPoCAHD5AgBw+gIAcPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -ACUoAw8IEqWog46TkgAAAAAgBxtLIAcfyiAHH9IgByCTIAcgdSAHG0sgByCTIAcbSyAHIDcgBxtL -IAcbSyAHICEgByAOIAcfAiAHG0sgBxtLIAcbSyAHG0sgBxtLIAcbSyAHG0sgBxtLIAcbSyAHG0sg -Bx/jIAcgSgAAAAAAAAAAIAczEiAHOjMgBznoIAc5XyAHNWggBzYNIAc2jiAHN0sgBzelIAc4CyAH -NQ0gBzitIAdueiAHblAgB25yIAdueiAHblAgB25QIAduUCAHbnIgB256IAdueiAHbnogB25QIAdu -eiAHbnogB25qIAduaiAHbmIgB25iIAduWiAHblggB25aIAduWgAAAAAAAAAAAAAAAwAAAAIAAAAB -AAAAAAAAAAQAAAAAAAAAAAAAAABSVgAAAAAAAEAkAAAAAAAAP1BiTdLxqfw/8AAAAAAAAD6wxveg -te2NEAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZm91bmQgYWRkaXRpb25hbCBjb25maWd1 -cmF0aW9uIGFmdGVyIFtmaW5pXQoAADAAAABmY29lAAAAAHZuaWNfaWQAdmxhbgAAAAB0b3MAZXRo -ZXJ0eXBlAAAAbWFjbWF0Y2gAAAAAbXBzaGl0dHlwZQAAZnJhZ21lbnRhdGlvbgAAAHNydnJzcmFt -AAAAAGZjb2VtYXNrAAAAAGNvbXBhY3QAcGZfdmYAAABvdXRlcl92bGFuAABlbmNhcHN1bGF0aW9u -AAAAYmFzaWN2aXJ0dWFsAAAAAGdsYl9rZXkAZ2xidmZfa2V5AAAAcGZ2Zl9rZXkAAAAAaWR4dmZf -a2V5AAAAc3lubWFwZW4AAAAAc3luNHR1cGVuaXB2NgAAAHN5bjJ0dXBlbmlwdjYAAABzeW40dHVw -ZW5pcHY0AAAAc3luMnR1cGVuaXB2NAAAAG9mZG1hcGVuAAAAAHRubG1hcGVuAAAAAHRubGFsbGxr -cAAAAGhhc2h0b2VwbGl0egAAAABkZHAAaXNjc2kAAAB0bHMAc3RhZwAAAABwYmwAcnEAAHJxdWRw -AAAAbGFuAHdhbgBjbHVzdGVyAG1hbnVhbAAAdHBfcGlvAAB0cF90bV9waW8AAABuaWNfdm0AAG5p -Y191bQAAbmljX3VtX2lzZ2wAbmljX2hhc2hmaWx0ZXIAAG9mbGQAAAAAcmRkcAAAAAByZG1hYwAA -AGlzY3NpX2luaXRpYXRvcl9wZHUAaXNjc2lfdGFyZ2V0X3BkdQAAAABpc2NzaV9pbml0aWF0b3Jf -Zm9mbGQAAABpc2NzaV90YXJnZXRfZm9mbGQAAGZjb2VfaW5pdGlhdG9yAABmY29lX3RhcmdldABw -b2Zjb2VfaW5pdGlhdG9yAAAAAHBvZmNvZV90YXJnZXQAAABpc2NzaV90MTBkaWYAAAAAaXNjc2lf -aW5pdGlhdG9yX2NtZG9mbGQAaXNjc2lfdGFyZ2V0X2NtZG9mbGQAAAAAdGxza2V5cwBjcnlwdG9f -bG9va2FzaWRlAAAAAHBwcABkY2J4AAAAAGIyYgBzb2NrZXRudW0AAABjZWUAaWVlZQAAAABhdXRv -AAAAAGFuX2RpcwAAcGRsaXRlX2RpcwAAIAKgRAAEAAAAAAQAAAQAAAAAAAD/AgAAAAAAAAAAAAAA -AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AgAAAAAAAAAAAAAAAQAC/wIAAAAA -AAAAAAAAAAAAAv8CAAAAAAAAAAAAAAAAABYAAAAAAAAAAAAAAAAgBsCoAAAAACAGwAggBr1kIAa6 -vCAGg7ggBgl8IAXtmCAF7GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBDegIARFDCAERQwgBEUM -IARUaCAEc5AgBINgIASNaCAENDwgBDGcIAQk9CAErqAgBCKsIAQfkCAF7DAgBerkIAXj4CAERQwg -BeLkIAXg/CAF4CggB2UIIAOuyCAEAWAgBur8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAgAt68IALGPCAC19AgAtUcIALTjAAAAAAgAtEkIALd6AAAAAAgBBZwAAAAAAAAAAAAAAAAIAMh -NCAG5HQAAAAAAA//8wAAAAAAAA/zAAAAAAAAAPMAAAAAAAAAMwAAAA//////AAAAAAAAAAAAAAAA -AA//8wAAAAAAAA/zAAAAAAAAAPMAAAAAAAAAMwAAAA//////AAAAAAAAAAAAAAAAAA//8wAAAAAA -AA/zAAAAAAAAAPMAAAAAAAAAMwAAAA//////AAAAAAAAAAAgB08wIAdOaCAHeSggB05UIAdOlCAH -TYAgB08UIAdNYCAHeRAgB05A/xgwYGAAAAAAAQIDAAAAAAAAAAAAAAAAIAbYaCAENdAgANboAAAA -AAAAAIEAAAAAAAAAAAAAAAAAAQIDAgIDAwACAwUDAwUFIAQE2CAEBowgBAYcIAQGqCAEBPwAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAQFmAAAAAAAAAAAAAAAAAAAAAwAAAANAAAADgAAAA8A -AAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAAAAAABAAA -AAQAAAAIAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAA -AAIAAAAEAAAACAAAAP////////AA////////4AD////////AAP///////4AA////////AAD///// -//4AAP///////AAA///////4AAD///////AAAP//////4AAA///////AAAD//////4AAAP////// -AAAA//////4AAAD//////AAAAP/////4AAAAMDEyMzQ1Njc4OWFiY2RlZkFCQ0RFRgAAAAAAAAAA -AABBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEy -MzQ1Njc4OSsvAAAAAAAAAAAAAAAAAAAAACAAZVQAAQAAIABlOAAFAAEgAGUgAAMABSAAZQAABwAA -Y4JTYwAAAAD///////8AAAAmGgsKCCsyQQJEQAMtAAAAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEA -AAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAQAAAAIAAAAEAAAACAAAAB -AAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAAP////////AA//// -////4AD////////AAP///////4AA////////AAD///////4AAP///////AAA///////4AAD///// -//AAAP//////4AAA///////AAAD//////4AAAP//////AAAA//////4AAAD//////AAAAP/////4 -AAAAAAAAAAAAAAQAAAAEAAAACAAEBAgABAQIAAAAAAAAAAD//wED/wL///8AAAAAAAAAAAQECAAE -BAgABAQIAAQECAAEBAgAB0MAAAAAAAAAAAAAIQAJAIEAQQAhAAkAIQAJAIEAQQCBAEEAgQBBAIEA -QQAhAAkAgQBBACEACQAhABEAgQBBAIEAQQAhAAkAgQBBACEACQAhAAkBAQBBAIEAIQCBACEAEBBh -AQEAgQEBAIEDAgEABAAAAAAAAAAAAAAAAAAD6AAAAGQAAAAKAAAAARAgQAAAAAAAAAAAAAAAAAAE -AAIAAQAAgABAACAAEAAIIECAAAAAAAAAAAAAAAAAACACjWQAAAAAIAKY6AAAAAAgAo1oAAAAASAC -mYwAAAACIAKNcAAAAAQgAo14AAAACCACjYAAAAAQIAKZlAAAACAgAo2EAAAAQCACjZAAAACAIAKN -nAAAAQAgAo2oAAACACACjbgAACAAIAKNxAAAQAAgAo3QAACAAAAAAAAAAAAAAAAqHAAAKjwAACpc -AAAqfAAAKgAAAAADAAAAAQAAKhgAAAAIAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHBAMK -CQIAAAAAAAAAAAAAQABAABAAEAAIAAgABAACAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAoAAAAPAAA -AHgAAAAeAAAAIgAAACgAAAAwAAAAPAAAAFAAAAB4AAAA8AAAAB4AAAAoAAAAPAAAAHgAAgABAAMA -BQAAAAQAAAAABAIGAQUDBwAAAAAAAAAAAAABAgMEBQYHCAgJCQoKCwsAAAAiAAAAMAAAAAAAAAAA -AAAAHgAAACIAAAAoAAAAMAAAADwAAABQAAAAeAAAAPAgBtwQIAbbyCAG2qAgBtlAIAbY+CAG2Mgg -BtkoAAAAAAAAAgAAAAQAAAAIAFllcwAwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4 -eXoAAAAAbm9uZQAAAABhbGwAKgAAAGRpc2FibGVkAAAAAGVuYWJsZWQAMHgAAE5BAABWMAAAVjEA -AFYyAABWMwAAVjQAAFY1AABWNgAAVjcAAFZBAABWQgAAVkMAAFZEAABWRQAAVkYAAFZHAABWSAAA -VkkAAFZKAABWSwAAVkwAAFZNAABWTgAAVk8AAFZQAABWUQAAVlIAAFZTAABWVAAAVlUAAFZWAABw -b3J0AAAAAHByb3RvY29sAAAAAGdsb2JhbAAAZnVuY3Rpb24AAAAAZmluaQAAAAByZWcAZmlsdGVy -TW9kZQAAZmlsdGVyTWFzawAAdm5pY01vZGUAAAAAcnNzX2dsYl9jb25maWdfbW9kZQByc3Nfa2V5 -bW9kZQByc3NfZ2xiX2NvbmZpZ19vcHRpb25zAABzZ2VfdGltZXJfdmFsdWUAdHNjaF90aWNrcwAA -dHBfcG1yeAB0cF9wbXJ4X3BhZ2VzaXplAAAAAHRwX3BtcnhfZmxhZ3MAAAB0cF9ucnhjaAAAAAB0 -cF9wbXR4AHRwX3BtdHhfcGFnZXNpemUAAAAAaG1hX3NpemUAAAAAaG1hX3JlZ2lvbnMAdHBfcG10 -eF9mbGFncwAAAHRwX250eGNoAAAAAHRwX210dXMAdHBfdGNwdHVuaW5nAAAAAHRwX3RpbWVycmVz -AHRwX3RpbWVydmFscwAAAAB0cF9iYWNrb2ZmdmFscwAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHkA -cGxfdGltZW91dF92YWx1ZQAAAABtZW1mcmVlX2NvbmZpZwAAYmFzZV9tYWNfcGYAb2ZsZF9mbGFn -cwAAbWNfbW9kZV9icmMAbWMAAG52ZgB3eF9jYXBzAHJfY2FwcwAAbmlxZmxpbnQAAAAAbmVxAG5x -cGNxAAAAdHBfc3JxAABuZXRoY3RybAAAAABuY3J5cHRvX2xvb2thc2lkZQAAAG52aQByc3NudmkA -AHJzc25zZWNyZXQAAG5leGFjdGYAbnJhd2YAAABjbWFzawAAAHBtYXNrAAAAbmV0aG9mbGQAAAAA -bnJvdXRlAABuY2xpcAAAAG5maWx0ZXIAbmhwZmlsdGVyAAAAbnNlcnZlcgBuaGFzaAAAAHRwX2wy -dAAAdHBfZGRwAAB0cF9kZHBfaXNjc2kAAAAAdHBfdGxzX2tleQAAdHBfdGxzX214cnhzaXplAHRw -X3N0YWcAdHBfcGJsAAB0cF9ycQAAAGlzY3NpX250YXNrAGlzY3NpX25zZXNzAGlzY3NpX25jb25u -X3Blcl9zZXNzaW9uAGlzY3NpX25pbml0aWF0b3JfaW5zdGFuY2UAAABpc2NzaV9tYXhfc2dlAAAA -cHBtX21heF96b25lcwAAAHBwbV96b25lX3JhbmdlMABwcG1fem9uZV9yYW5nZTEAcHBtX3pvbmVf -cmFuZ2UyAHBwbV96b25lX3JhbmdlMwBjb2lzY3NpX250YXJnZXQAY29pc2NzaV9udGFzawAAAGZj -b2VfbmZjZgAAAGZjb2VfbnZucAAAAGZjb2VfbnNzbgAAAGZjb2VfbmZjYgAAAGRjYgBkY2JfYXBw -X3RsdgBkY2JfZGNieF9wcm90b2NvbAAAAGh3bQBsd20AZHdtAGRlYm91bmNldGltZQAAAABhbl9h -ZWNfdGltZQBhZWNfcmV0cnlfY250AAAAZmVjAHZlcnNpb24AY2hlY2tzdW0AAAAAU2Vzc2lvblR5 -cGUAT0ZNYXJrZXIAAAAASUZNYXJrZXIAAAAARGF0YURpZ2VzdAAASGVhZGVyRGlnZXN0AAAAAEVy -cm9yUmVjb3ZlcnlMZXZlbAAASW1tZWRpYXRlRGF0YQAAAERhdGFQRFVJbk9yZGVyAABEYXRhU2Vx -dWVuY2VJbk9yZGVyAEluaXRpYWxSMlQAAE1heENvbm5lY3Rpb25zAABNYXhSZWN2RGF0YVNlZ21l -bnRMZW5ndGgAAAAASW5pdGlhdG9yTmFtZQAAAEluaXRpYXRvckFsaWFzAABEZWZhdWx0VGltZTJX -YWl0AAAAAERlZmF1bHRUaW1lMlJldGFpbgAATWF4QnVyc3RMZW5ndGgAAEZpcnN0QnVyc3RMZW5n -dGgAAAAATWF4T3V0c3RhbmRpbmdSMlQAAABUYXJnZXROYW1lAABUYXJnZXRBbGlhcwBUYXJnZXRB -ZGRyZXNzAAAAVGFyZ2V0UG9ydGFsR3JvdXBUYWcAAAAAQXV0aE1ldGhvZAAAU2VuZFRhcmdldHM9 -QWxsAENIQVBfQQAAQ0hBUF9JAABDSEFQX0MAAENIQVBfTgAAQ0hBUF9SAABEaXNjb3ZlcnkAAABO -b3JtYWwAAE5vbmUAAAAAQ1JDMzJDAABDUkMzMkMsTm9uZQBOb25lLENSQzMyQwBDSEFQAAAAAENI -QVAsTm9uZQAAAE5vbmUsQ0hBUAAAAE5vdFVuZGVyc3Rvb2QAAABJcnJlbGV2YW50AABSZWplY3QA -AE5vAAA1AAAAQ0hOZXQgMS4wMAAAAAAADAAAAAABAAF8AAwBAAAAABAAAAAUIAeSaAAAAwUOQAAA -AAAAEAAAACggB5VwAAADMA5QAAAf/AAAH/wAAB//M2Af/zNgIAepkCAHr4AgCUnoIAlJ6CAKAAAg -CoAAIAqAACAK5oAgAAAAH/8tICALAAAgCwAwH/8wdB//EFAAD///H/ziAB//K8Qf/y+wBAAACBoA -AACBAAAAH/8wPCALAIAgC2WAH/8tmB//MFgf/y5QH/8tBB//L8AwAAAQIAtlwCALZiAf/zHUH/8S -DCAHr0AXkAAAIAetRCACj2CAAAAEFLAAAAAAYAAgAo9wIAevSgAAIgoAAIP/FaAAACACgAAWoAAA -CFABACCgAAA/8AAAI6AAAAP/AB8AwAAEH/8x2AAA//8gB1/EKgAAACACzGQgC2ZQIAtmkCAHX3je -rb7/GsAAACAHrkggAo9sAAD/6iAHr1AAAAgUAACIAAAAgAAf/yzwIAep4B//LXgAACcQAB6EgAAA -QAAgAufMH/8udAAQAAAf/ys4H/8ukCACgBAgC2dQIAtnIOEAAAABAAAAKAAAADgAAAD/P///MAAA -dB//ANAgAoBAIAsA0DAAAAgwAAAMNAAACNAAAAAOAAAAAACJFDsAAAg0kAAAIAetWCACj9QgB6vg -BV1KgCAC7gwAGAAA/wf//wA4AAAAMAAAIAtncCALARAAAIAHAACABCALaMAABAAAAAAIAOEBjgAA -AZEMgAAAACALaKD///P/IAtoUCALaOAAALjuAAA0AAAAtO4AALT/AAC0AAAAuAD///AAAAgAAABz -AAMf/y04IAKQmAAAg/0gAo74IAMdLAABQUoAAQFuIAKPWADAAAEQAAAAIAtpACACkKgowAAAQAAA -AiACj6QooAAAgAAAAmsAAAAgAo8gIAMWjCALaSAgAx7UIAtpcO4AAAADYAAAIAKQ6APgAAAf/yyw -IAKAkB//MMDhAwYA/9///wABADbf////AkgCVOEC/gAgAoCgAAIAAP/9//8A/wAAAA9CQACYloAA -ACcPH/8tFAAArwBAAAAA4QEOAAAAiPcAIAAAAT8BQIGAAAAf/xeQggAAACAClbQMAAAAIAMkpB// -KzQgCwKwH/8rjCALakAAQAAAAIAAAAABAAAIAAAAH/zi5AIAAAAf/yz8IAsC0CALAyAgA4sAIAsD -oCALA3AgC2oQH/8tTCAD43gAAA//IAtqgAAAEAAf/xkEABAMAAlAAACD/9AAA//QACADhzAgAzC0 -IABsuB//LSwAAA/+IAA4PCAANnggADbgDwAAACACk0QgAJkoIAKUBAAQSAAgAzuIIAKTiCACkwQg -A0KwIANFWAAAIAAgC2qgDzwAAB//K1QgA0nIIAes0CAAkvAgAJZsIAsGQCAALtwgA1ZYABACMABB -AAAAUQQAIAsGcB//LdQgCwagH/8pLB//LZAJAAAAAABD/yADXJAAAIbdAEAP/SADXYgf/yuIH/8r -gB//LSj/8///AAAMAAAMAAAf/y0kAP///yAAQKhxAAAAH/8rSCAHpfAAD/wAIAKM8B//GBwf/xl0 -AAA+AFUAAAAf/yt0IAtq4CADYtz/9///AExLQCAD4YAgA8QAIAsG4CALBxAgCwdgIAsHMB//ApAf -/wOAIAsHgCAClHAgApPwIAKT0CAAZYAgCwgQIABptCALCDAgAGdUIAtrYCALCFAgCwiwIAsJACAD -2aggCwiAIAPfGP//B/8AADAAIAsJcCALCdAf/y1gIAsKACALCkDgAAAAIAMXzCALCoAgCwqgIAKU -6AAACAYgA4eAIAOKfB//LRAAAPAAIAO4RCADvXQgCwrAIAOqACALCvAf/xJsAMAAAB//K0AgB62Q -7/////9///8gCwswIAetWiADsHggC20gFJAAAEAAAAQgC22QIAttwCALa5AgB61QIAKPBCALa9Ag -C2wwAACP/iALbIAjKBUAA/8AACALbOAgA7/4/f///yAClOAgB6pAIAeqcB//LPgf/wLwH/8D8CAC -mMAf/wLQP////8////8f/wOsf///qwAAnE7//9BNAADRpP//Llwf/wLsIAKVvB//Augf/wNQIAsL -gB//LVAgA/fIH/8tACALaeAgC2mgIAPvPP//QAAgCwvwIAsLwCAAOLwgAGeoIAP0RAAAF3AgApEk -IAtvECALbsAgC26gIAQDiCALbnAgC27wIAKQlB//LOwgApEEIAsU8CALFUAf/ytgIAsVYCALFZDh -AF4AIAsVsB//KlwgB6eEIAsV4B//KRThAH4ABAAAAAUAAACAAAAdgAAACoAAAAyAAAAbgAAAHyAC -knAf/ytwH/8tCAAA8/8UAAAAIAQQOB//LdAgACBo4AAGAB/84gjgAAoMH/8baCALFpAAAJxA4AAK -AB//GlDgAA2AAJwAAOEALgAf/y0MIAsXcCALGFAgCxggIAtv8CALF/Af/xwUIAsXsAADBMDhAwIA -4P/+AOEAjgAAAJaAAACWQCAHqZAAAJagAACWYOEDACwAAwAA4QB6AB//LPQAAeAA4QGSAAAB4wAG -AAAAIAQm6PgAAAAB///nAAFAACAAAIDPAAAAHAAAAB//KSThAZoAH/8t8CACkJwgApCsIAKQpCAC -kLSAAAAD//z//3////8f/OIEH/8SHB//Epwf/xI4IAQ3oCALc1AgC3OQIAtzwCALdAAgC3QwIAt0 -cCALdKAgC3TgIAtzAP//AAAP///w//AAAB//KEQgBEUMIAt2ACALdjAgC3WgIAt1QB//GoAf/xj0 -H/8aIB//HIAAAAnWAAD/gAAAPAAAACMnIAsZYAAAkBAAAJEAAACQIAAAkRD/+///4QHiwJAAAPD8 -/wDAAgAAIP7/AMAgCxmwIAsZ8AAA+AAAAwEIAAMBUI////8AAwEMIAsaQCALGpAgCxrAIAsbAOEA -7gCAAf//gAD//4ABAADhAN4AH/8ZYOEA5gAf/ytk///gAAAA/wAAAREUAAETAAADAwgAAwIAAAHA -AP/+//8AAPwAIAsbUAADAwQAAREQIAt2kAAgEACAABAAH/8YhP//wAAAAwEEAAehIAX14P8HwAAQ -AAD//gAAJYAAAwMAH/8rXOD94sAf/ymYIAt24CALdxAgC3cwAAD//SALdsAgAoD4AAD/8yALG5AA -ACowAAD/+AAA/48AAFK1AABICgAAj4IAAI+GAAA4AAAAj4oAAOM/AACDrgAA//EgCxuwAAAQQP// -z78gC3dQAAASACALG+DhAy4A4QMyAP7////hAwEIAAMIBP//f/8gCxwA/mz/gCALHNABAABA/+// -/x//KZzwf///AYAAAP+f//8gC29wIAtvMCALHSAgCxwwIAsdcCALHcAgCx4wIAsckAAA//sgAoEA -IAsewCALHpAgC3ewAAD/9wAA/+8AAP/fAAD/vwAA/38AAP7/AAD9/wAA+/8AAPf/AADv/wAAv/8g -C3fgH/8pKCALH3AgCx8wIAsfACALH5AgCx/gEAAFDQHAgAAf/y8YIAKBsAAAgwAEAQAIIAshAAAA -ggAgCyAgIAsgcCALILAQAAcCAAAMvAAAiQYgCyFgIAtm0IiIiIggAoIAIAshwCALIZAgCySwIAsk -cCALJDAgCyPwIAsjsCALI3AgCyMgIAsi4CALIpAgCyJAIAsiACALePAgC3kgIAt5UCALeZAgC3nQ -IAt6ACALJeAgCyWQIAsk8CALJTAAAIDCAAAbISALJhAgC3owIAt6cCALJjAgB6nAAP/AABIAAAAg -BP/wIAsmoGAAAAAgCybgIAsnoCALJ2AgCyfgIAsnICALKEAAAH+mIAMNOCADD0QgAwygAGAAACAL -KGAgA8KAIAsp4CAClGAgBSFkIAt8UAAAH0AAABA2///v/x//Mdwf/zBoAAAIUCALKgAgCypQIAsq -MAD///wf/zJaMgAAAMAAAAAgAoI4M5AAACAHrUggAo/QIAt8sCALfRAgC3zwIAt9UCALKnAgAvkA -IAKCQCALKyAAAIAFIAsrUB//LVzerb7vIAsrkDAAABwwAAAEMAAAFB//MRQA//AAACgAACALK8AA -AAhAIAKPlCALK/AA///6IAssQDAAAAAwAAA0AACAASACglAAAIACIAV7sCALfeAQAAUQmQAAADQA -AAAgC32QIAssgAAZAAAgCyzQIAKWRAAAEg8gCy0AH/8wpAMVAACD/wAbIAsvAOEBkawAAZGsCwAA -ACAEj1wgApDUIAt+YH///w8gCzAQH/8sYB//K8D8AP//4QCWAOEAmgAAAAn/4QCeAAAAsAAf/y2M -IAKCoCALMFDhAA4A4QASAP/gOAAD/4AOAHP/gAMAAAAAOP//EwAAABEAAAAf/AAAH/8s3CALMJAg -C39gAAGUjwABlM8gAoLAH/8cTCACh0Af/ynUIAsw0L////8gCzEQIAek4CALMUAf/ymkH/8pbB// -EOQf/xqEH/8qwCACiEAf/xe8IAuAgCALgLAgC4DgAAQUAB//G1wf/xngH/8bVOEAWgACAbAAH/8S -BCALN/AgCzhAIAs4oCALOXAAP///H/8odB//Gfwf/yssH/8WHAAA/5cAAP7V//+rkx//LOjCAAAO -BdwBAMAAAAEgCzngIAs6ICALOnAgCzqwIAs7ACALO0AgAojQH/8pWB//GiwAf///H///8B//LeQC -AAAQH/8QeCALPCAgCz0w/7///yALd3AAAP4AIAuFAB//HIQbAAAAAAUAAjrAAAAgCz1wIAYsKCAL -hcAgC4VQIAuFkCAGMpggC4UwIAKJACALPaD//8H////fzwAA4AD//5//IAs90CALPgD//98wIAs+ -MB//KTAgCz5gH/8ScOEDKgD//83/IAKJYCALPpAgAonAIAKKICACioAgCz7QAAMAAgAKAAIgCz9Q -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 -jQfdAucI2EAPCAy87KrrQA9gDU3tLrBAD2AL2+uq60AQOAzB6jLIQBAwDLHqFbBAEKAB/eQQ2EAO -+A+O6N3lQAgAAAbAQH7XD+nf38AOgACC6ETrQA8oDZ191w/pv9/ADoAAiOhE60APKA2dfNcP6X/f -wA6AAIToROtADygNnXvXD+n+38AOgAGA6ETrQA8oDZ151w/oAthADvgLn+hE60APKA2df9YQGSJ2 -KApADwIA6ETrQA8oDZ1+1gwZIPrTD+dE60APKA2dfdYMGCJN0w/mROtADygNjXzWChkhX+VE60AP -KA2de9YNGCKdKRoA6UTrQA8oDY161g0YIOMpKgDpROtADygNjXnWCihKAOzd5UAPYASEeNYH70Tr -QA8oDe131gfrROtADygNrcnd6lDYQA6AAbjsCRNACigK7RoigBsg/x4heR8goBwjio0v5DbAQBCw -Af3kENhADvgPnund5UAIAAAIAADAQH7XD+jf38AOgACS6UTrQA8oDY191w/ov9/ADoAAmOlE60AP -KA2NfNcP6H/fwA6AAJTpROtADygNjXvXD+j+38AOgAGQ6UTrQA8oDY151w/pAthADvgLj+lE60AP -KA2Nf9YPGCIsKQpA0w/pROtADygNjX7WDxggsA8CANMP50TrQA8oDY191gwZIgPTD+ZE60APKA2d -fNYKGCEV5UTrQA8oDY171g0ZIlMoGgDoROtADygNnXrWDRkgmSgqAOhE60APKA2dedYKKUoA7N3l -QA9gBJR41gfvROtADygN7XfWB+tE60APKA2tyd3qUNhADoABuOxkE0AKKAqjGiI2GyC1HiEvHyBW -HCNAKCAv6DLRQBDIC5LpOMBAESANghkh0+Q3wEARcA3SLTQTqYgogPDA0OgYgEAPmACX6NnnwBCA -DNLpNNFAEMAB/cdOBN0B5BDYQAgAAA0AAAAAAAAAwEDiANhAEKAB7ejf38AOgACS6UTrQA8oDY19 -1w/ov9/ADoAAmOlE60APKA2NfNcP6H/fwA6AAJTpROtADygNjXvXD+j+38AOgAGQ6UTrQA8oDY15 -1w/pAthADvgLj+lE60APKA2Nf9YMGCHTxJDpROtADygNjX7WChggWOdE60APKA2NfdYMGSGr0w/m -ROtADygNnXzWChggveVE60APKA2Ne9YNGSH8KBoA6ETrQA8oDZ161g0ZIEIoKgDoROtADygNnXnW -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 -7ejIQA0ABIrsAN/ADoAAsO0P38AQkAmsCooU67iQQA0AAdp6yPF60Ay0u+pK7UAIAAAHALG7ChoU -Za/32kDs/9/AC3gD02P+ygAAAOsA2EAJ+A/sAAMABB//F5TAAAAA4QUOAAAAH/8f/xVcIAtQgAAF -EACAAAAAIAtQMCALUOAf/y2UH/8SDB//LlAf/xdQH/8X0CALUeAgC1GwIAtSEB//FWAgAAAAH/8W -UAAAQAABAAAA4QB2AB//FUwACAAAf////+EALgAf/yo04QGOAOEAegAf/xBQIAtScCALUkAgC1Fw -IAtRIOEBmgDhAZoE4QGaCOEBmgz/8AAAAAMABh//HDAAUQAGH/8vsCALUqAf///wH/8tCCALUtAf -/xtQIAtTACALUzAAAwAWAAMADgADAEAf/y0M4QMyACACl5DhAv4AIAKLECALU3ABAOAADAAAACAL -U8AAAwgE4QMGAOD/B//g//4ABQDAAAgA4AAJAGAABQCgAAUAIAAAACAAAACAAOEDLgAAAzAAAA4A -AADgAAD///AAAAAPG/8A////D///4QMqAAAAgAP//3/8AAwAAADAAAAgC4YA///N/+EDLDggC1QQ -AIAAAAAAKAEAAwh44QAAAB//LdAf/ymc//+//wD/AAD//3//AAMsHAADLBggApfA4QMOAOEDEgQg -C5VAIAuUsCALlRAgBmVAIAuU8CALlWAABAAA//P//wADAAD//P//AAMSECALVFAEAAABBAAAMR// -EegEgAAB+w//PgBAAAA+PgAPAAMNCAADDRwAAw0g4QMmAAADCiAAAwocAAMKCOEDChQAAD/gAAC5 -k+EDEgD//+//4QNGABAAAAAzIWjB///h/wAADgBj5sTwM5tlxdg9eaJAAAAAv////z5HdpAAABIA -BAAAgQQAALEEAABBBAAAcQAQAAAAEABAABAAIAAQABAAEAAIABAABAAQAAIgAotQAAGGoAAEk+Ag -B6ng4QBeAB//EHggAouwIAtU0CALVKAgC1UAIAek4CAHpgQgAovQIAtVgP/v/4EAAA//IAtVwCAL -VfD+f///IAtWQCALVsAgC1UwIAtXUCALV9AgC1cwH/8sEAAehIAAEwAGAZMADgATABABkwB4AZMA -DAGTACgAAxIEAAMSFAADCDQgC47gAAMqHAADKjwAAypcAAMqfCALj+AgC43gIAuOECALjkAgC46A -IAKXgCALjZAgC46wIAuPwCALjzAgC49wAYAAACACjEAgC5BAD4AAAP7//////2Pv//8AAB//G2gA -ADIA///t/wADLAAAAwgAIAuQcAADCKQf/ye4AAMsBAAAggMgC5EwIAuRsP//3/8gC5KAAAMsMCAL -ksAgC5OQIAuTsCALlCAAB6EgIAuUACALk+AAiVRAAA9CQACYloAgC5CgAAMsFAAAqAUgC5DQAAMs -NCALkfAgC5JAIAuRYCALkQAgC5LwIAuTQAADLDwgC5RAAAD/7yALWEAAACcQIAuVsCALlgAgC5WA -H/8WDIAPAADf//4A4AABAOEB4kAgB6qA4QHikB//EgQAADGAAAApQMAAAAYf/y0EAABcSOEAWgD/ -6A//H/8t8CoAAAAgB1IQIAtdsCALXZAgC11wAAAxhAAAWkwAAClEH/8tFB//KZCAAABE4QBWACAL -XeDhAFbg4QBecCALXiAgC15AIAtecB//K2jhAZIAIAuWQAAAMUQAADmEAABeTB//EZQgC16gIAte -0CALXwAAAD4EHQAAAB//ANDhAH4A///AwB//LcwgB1/EIAdfeCACjwQgB6fEADAAACAClpQgC5dA -IAuX8CALlnAgC5awIAuYcCALl5AgC5bwIAKQnCACkKQgApCsH/8qUOAAAAAf/y1wIAtfcCAHWAAf -/y50H/8usB//Mxgf/zMwH/8zSB//MHAf/zMcH/8zNB//M0wf/ytc7f///wACYlr/5///bf///wAa -AQAAGgGAP//////l/n8AABoaAJQAAPAAAAAAAwkEIAtfoOEDOgAgAoxwH/8aMCACjNAf/xo4IAtf -wCAHpbT//Ph/AAATiOAACgDgAA2QIAtgEOEAMYThAFpM4QAxRIQAAHjiAAAAIAqAAB//ETAAAB6A -H/8pBN////8AAQAAH/8qeJ////8gC5vQAwAAAL//8P8gApC0H/8t1B//Exgf/OIAH/8sROEADgDh -ABIAAgAAAAAA//8f/y8kH/8SbB//KaQAAP7/IAti4B//K8QgC2OwIAtjQCALZCAgC2RQIAep2AQB -AAiBAAAAMAAAAAQAAAggApRwCgAAAB/84uR/8AAAAB///wAP//9/+AAA/9///wAH//8AAA/+AAUQ -ROEBDgAAAwEIAAMBDAADAVDg/eLAAACQEAAAkQAAAJAgAACREAADAQQf/y0QIAetWiADsHggC20g -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 -AQAAAAAAAAQCAAAAAAAABhQAAAAAAAAHEgAAAAAAAAgDAAAAAAAAChUAAAAAAAAPEwAAAAAAABAE -AAAAAAAAIAUAAAAAAABABgAAAAAAAIAHAAAAAAAAwBYAAAAAAAEACAAAAAAAAgAJAAAAAAADABcA -AAAAAAQACgAAAAAACAALAAAAAAAMABgAAAAAABAADAAAAAAAGAAaAAAAAAAgAA0AAAAAAEAADgAA -AAAAgAAPAAAAAADAABoAAAAAAOAAGwAAAAABAAAQAAAAAAGAABwAAAAAAcAAHQAAAAAB4AAeAAAA -AAIAABEAAAAAAQABAAEAAQABAAEAAQABAAEAAgADAAQABQAGAAcACAAJAAoADgARABUAGQAeACMA -LQA8AFAAZADIASwBkAH0AAAAAAAAAAAAAAAAAAAAAAAAAAEAAQACAAIAAwADAAMAAwAEAAQABAAE -AAQABQAFAAUABQAFAAUABgAGAAcABwAAAAIAAAAGAAAACgAAAA4AAAAUAAAAHAAAACgAAAA4AAAA -UAAAAHAAAACgAAAA4AAAAUAAAAHAAAACgAAAA4AAAAUBAAAHAAAACgAAAA4AAAAUAAAAHAAAACgA -AAA4AAAAUAAAAHAAAACgAAAA4AAAAUAAAAHAAAACgAAAA4AA/wABAgIAAAAAAAAAAAAAACAIpJgg -CKUCIAikUyAIpDggCKUCIAij+yAIo/sgCKUCIAilAiAIo/sgCKUCIAilAiAIo/sgCKP7IAij0SAI -pQIgCKOYIAihyyAIomUgCKI7IAiiaCAIogIgCKUCIAilAiAIpQIgCKUCIAilAiAIpQIgCKUCIAil -AiAIpQIgCKH1IAKQcAAAAAEgApB4AAAAAiACmOgAAAD/IAKNZAAAAP8gApBcAAAAAiACkGAAAAAD -IAKQaAAAAAcAAAAAAAAAACACkEAAAAABIAKQRAAAAAIgApBMAAAABCACmOgAAAD/IAKNZAAAAP8A -AAAAAAAAACACjWQAAAAAIAKY6AAAAAAgAo8MAAAAASACjxQAAAAEIAKPHAAAAAggAo8oAAAAICAC -jzgAAABAIAKPQAAAAIAgAo9IAAABACACj1AAAAIAIAKPZAAABAAgAo94AAAIACACj5AAABAAIAKP -pAAAIAAgAo+0AABAACACj8AAAIAAIAKP1AABAAAgAo/kAAIAACACj/QAEAAAIAKQDAAgAAAgApAk -AEAAACACkCwAgAAAIAKO+AAAABAgAo8AAAAAESACjuAAAAAAIAKO5AAAAAEgAo7oAAAAAiACjvAA -AAADIAKOuAAAAAEgAo68AAAAAiACjsQAAAAEIAKOyAAAAAggAo7QAAAAECACjtQAAAAgIAKO2AAA -AEAgApjoAAAA/yACjWQAAAD/AAAAAAAAAAAAAAAAAAD//wAAAAAAAP//IAKOOAAAAQAgAo5EAAAA -gCACjlQAAABAIAKOZAAAACAgAo50AAAAECACjoQAAAAIIAKOkAAAAAQgAo6cAAAAAiACjqgAAAAB -AAAAAAAAAAAgAo3YAAAAACACjeAAAAABIAKN7AAAAAIAAAAAAAAAAAAAAE4AAABGAAAAPgAAADcA -AAAvAAAAJwAAAB8AAAAXAAABAQEBAQEBAQEBAQECAiAJLQAgCSy0IAks8yAJLPMgCSy0IAkstCAJ -LQAgCS0AIAkstCAJLQAgCSy0IAktACAJLPMgCSy0IAkstCAJLLQgCSy0IAkstCAJLQAgCSy0IAks -tCAJLLQgCSy0IAkstCAJLLQgCSy0IAktACAJLQAgCS0AIAktACAJLQAgCS0AIAkstCAJLLQgCSy0 -IAkstCAJLLQgCSy0IAkstCAJLLQgCSy0IAkstCAJLLQgCSy0IAkstCAJLLQgCSy0IAkstCAJPYAg -CT2AIAk9dSAJPYMgCT2DIAk9bSAJPW0gCT2DIAk9gyAJPW0gCT2DIAk9gyAJPW0gCT1tIAk9bSAJ -PYMgCT1lIAk9bSAJPW0gCT1tIAk9bSAJPYMgCT2DIAk9gyAJPYMgCT2DIAk9gyAJPYMgCT2DIAk9 -gyAJPYMgCT2DAAYhegAAAAUAAAAEAAAABAAAABIAAAAEAAAAGwAAABYAAAAAAAAAAQAAAAEAAABs -AAAAbAAIGzIAAAAGAAAABAAAAAwAAAARAAAABAAAAB0AAAAUAAAAAAAAAAEAAAABAAAAcAAAAHAA -AAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoh/wAA -AAcAAAACAAAAAgAAABEAAAAEAAAAHgAAABoAAAAAAAAAAQAAAAEAAAB0AAAAdQAAAAAAAAAAAAAA -AAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMNQAAAAAIAAAAAQAAAAoAAAAIAAAABQAA -AB0AAAAdAAAAAAAAAAMAAAABAAAAeAAAAHkADDUAAAAACAAAAAEAAAAKAAAACAAAAAUAAAAdAAAA -HQAAAAAAAAADAAAAAQAAAHgAAAB5AAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAADk4cAAAACQAAAAEAAAAGAAAABgAAAAIAAAAeAAAAHgAAAAAAAAABAAAAAQAA -AH0AAAB6AAAAAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA2ZAAAAAoA -AAAMAAAACQAAABEAAAAEAAAAHQAAAB0AAAAAAAAAAQAAAAEAAAAAAAAAfgAAAAAAAAAAAAAAAAAA -AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -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 -AAAABAAAAAAAAAAAAAEAAgAcABsAFgAVAB4AHQAYABcADAALABAADwAgAB8AGgAZABQAEwAKAAkA -DgANABIAEQAIAAcABgAFAAQAAwABAAIAAAAEAAAAAAAAAAAAADAEAAAwEAAAWdwAAFqAAABahAAA -WogAAFqMAABeoAAAXqQAAF6oAABerAAAXrAAAZQwAAAQJAAAEDAAABA8AAAQ3AAAEQwAABEoAAB7 -LAAAezQAAHs8AAHijAAB5owAAeqMAAHujAAB8owAAfaMAAH6jAAB/owAAI3MAACOgAAAfnQAAI/c -AAGRWAABknAAAI/8AAQTHAAEExgABBMQAAB34AAAd+QAAHf0AAB4BAABnDwAARB0AAEQhAAAlAgA -AJhcAACWDAAAlhQAAJYgAACWLAAAlsQAANAoAACQCAADCNwAA0jcAAMI5AADSOQAAwiIAANIiAAB -kFQAAGAcAAGg2AABkJAAAHfgAAB35AAAd/QAAHgEAAB42AAAeOAAAHj0AAUAeAAFCHgABRMIAAGU -BAAB48AAAefAAAHrwAAB78AAAfPAAAH3wAAB+8AAAf/AAAGUDAAAAAAAAAAAAAAwAJ///0AAADAI -n///QAABlBAf/2f/AAGUNAAAABAAAZQIH/9j/wABlDgAAAAQAAAQKGD///8AABAsYP///wAAEDQB -/F//AAAQOAH8X/8AABBAAAQAAAAAERAA////AAARFAD///8AAHsoAH3/5gAAezB//+7/AAB7OAAA -AAEAAHtAf//u/wAAfCQAff/mAAHiiAAIAAAAAeaIAAgAAAAB6ogACAAAAAHuiAAIAAAAAfKIAAgA -AAAB9ogACAAAAAH6iAAIAAAAAf6IAAgAAAAAjcj////wAACN0P////AAAH5wf7//fwAAfnh/v/9/ -AAB+AALAAAAAAZFUAf///wABkZwB////AACP2AN///8AAI/4/////wAEExQAAAAHAAQTDAAAAAoA -AHfcAAAABwAAd/T/////AAB4BAAAAAMAAZw4OcG/+QAAkAQAAAA+AAEQeAGMBgAAARB8AYwGAAAB -EIgAAAAAAACUBAAJ3+AAAJQQAAnf4AAAmFQAAAH/AACYWAAAAf8AAJYIAAAAAAAAlhwA////AACW -JAD///8AAJYoAP///wAAljAA////AADQIAAAAA8AANAkAAAADwADCNgAAAADAANI2AAAAAMAAwjk -AAAAAwADSOQAAAADAAGQUAAAAP8AAaDUAAABgwABkIwAOAAAAAGQmAA4AAAABQB0AAAALwAFAHAA -AAAtAAUIdAAAAC8ABQhwAAAALQAFEwQAAAA/AAUTAAAAAAEgApm8IAjZyCACmcAgCO6oIAKZzCAI -7bQgApnYIAjs4CACmeQgCOyEIAKZ+CAI64AgApoEIAjqzCACmhwgCOlgIAKaLCAI6AAgApo4IAjm -4CACmkAgCOa0IAKaVCAI5oggAppkIAjmUCACmnAgCOUsIAKaeCAI5QAgApqMIAjj9CACmpggCOQg -IAKapCAI48ggApq0IAjjkCACmsAgCOHkIAKayCAI4SQgAprYIAjgGCACmuQgCN74IAKa9CAI3eAg -ApsEIAjctCACmxwgCNlwIAKbMCAI2SggAptAIAjY/CACm0wgCNjQIAKbWCAI1+ggAptkIAjW6AAA -AAAAAAAAIAKbaCAI1pggAptsIAjWGCACm3QgCNXgIAKbfCAI1aggApuIIAjVcCACm4wgCNU4IAKb -lCAI1QAgApucIAjUyCACm6ggCM3QIAKbvCAI1JAgApvAIAjWUCACm8ggCNRYIAKb1CAI1CAgApvc -IAjT6CACm+QgCNOwIAKb7CAI0JAgApv0IAjTXCACnAAgCNNQIAKcCCAI0xggApwQIAjS4CACnBgg -CNKoIAKcJCAI0nAgApwsIAjSOCACmZQgCM38IAKcNCAIzZggApw8IAjNYCACnEQgCM0oIAKcVCAI -zPAgApxgIAjMsCACnHAgCMx4IAKceCAIzEAgApyAIAjMCCACnIggCMvcIAKclCAIy7AgApygIAjL -cCACnLggCMtEIAKc1CAIyxggApzkIAjK7CACnPQgCMrAIAKdBCAIypQgAp0UIAjKaCACnSQgCMo8 -IAKdNCAIycQgAp1EIAjKECACnVQgCMmYIAKdYCAIyWwgAp1sIAjJQCACnXggCMj4IAKdhCAIx5Ag -Ap2IIAjFsCACnZQgCMS4IAKdqCAIxIAgAp2sIAjESCACnbAgCMQQIAKdtCAIw9wgAp3EIAjDdCAC -ndAgCMHoIAKaXCAIwlggAp3gIAjCPAAAAAAAAAAAIAKd5CAIwbwgAp3sIAjBkCACmaAgCPHgIAKZ -qCAI8QAgApmMIAjwQCACmbQgCO+EAAANAB//AAAf/wAYH/8QUCAIBpAf/xsIIAsxkAAKAADhBBIA -4QQCAOED/gD/wf//ABAAAEIHCAACAAAA//+A7gAA8AAAABUAUAAAAAYAAAAABgAAEPAA8AAAMAAA -wAAAQDBCAAEAAACABAAB4AAAAIDACAABAEQg+OD//3AA/+CAMwABDw8AAAAgAAAAMAAAABAARoAA -AAEgCAAAAAARAIIAAAHAAAQAAAAP/1////8gAAAAIAsxsBAAAAAgCzHgAAQTACALMgAf/xuIIAsy -IB//GrAgB6ngH/8tZCALgEDhAHYAIAt/sCALf/AgCzJAH/8dUB//HNjhAZoAAAGeDOEBngAAAZ6s -H/8dWB//GeAAAf//AAGfTAABn5wAD0JA4QB6ACALMtAgCzMgIAszgAAA//8/////IAsz4CALNFAg -CzSQIAs00CALNRAgCzVQIAs1kCALNdAgCzYQIAs2UCAIAFAf/xfYH/8bDB//GtAgCzaQIAKWsCAC -llD/AP//AAwAAIAAAB+AAAA/H/8ppB//EmzhAM4ARERERIiIiIjMzMzMH/8tiB//G1Af/xqA4QEO -AAAAQADhAI4AAACAAB//ANAf/xt8H/8tdAAACAAgCzcQIAs3cAAACwAAAArAIAuB4CALNtAgC4Fw -IAuBMOEALgAEAAAAH/8SlOEAVgAEAYAAiAABAP/xgQAAAYAAIAgAcCAIFzQAABKg4QGSAAADAAAA -AgAAAH8AQACCAIAAAQAAAMEAwB//GlThAA4AH/8tkP//I/8AAMgAECABIOEAfgA8AAAA//+//1Bo -6EeSAAAA8ADwAN+///sgAAAEf/f//4AAAgD+//////f/fwAAfhj///AAEAEQASABIAEAAH5AFRUV -FSEhISEQEBAQ4QGOAIAAAADg//4AIAgQtAAACMCAAIAAAP8A/wBAAED//z//IAuCkCALgsAf/xsE -/w/////A//8gC4JQIAuC8B//KgQf/xosH/8uUCALOPAf/xyAH/8Z/AAA//2ADwAAH/8p9CALg+Dj -AAIA4v//ACALOTAgCO+EAEAAACBAAAAAgAAAIIAAANAAAAAgC4MgIAuDsAAAEAAgAo0cH/8vsB// -K1gf/ylYH/8sUB//KYgf/yhQIAs7oAAAKAAAABBEAAA//wAAwAAf/xqEIAs7gAAAIADhADIAH/8c -JP/wAAcgC4dQIAuHACAIAXAgCAGwIAgB8B//GXQAAHtgH/ziAAgAAAAf/ymQH/8SBOEC/gDhA74A -4QM+AOEDfgDhAeIA4QCSAOEBEgD///D/H/8cUAABnAgAAZwEAAEABf/wAAAAYAAAIAuHoOEBmgTh -AZoI4QGaDCALQhAgC0JwIAgCcB//GuAf/xoIH/8tjP/w//8gApI4H/8WUAAAfkxAAAAAIAtC4CAL -Q0AgC0OgH/8S3B//MMAf/y14H/8o/B//KvAgC0PgIAtEYCALidAgC0QQH/8rdB//KyQgC0TgIAtE -oB//LVAgf/4AIAuKwB//Ktgf/ypQ38AAACALiiAgC4pgH/8q5P+AAAD//+AAIAtFUCALRYAgB6X0 -IAuIAB//GdwgApJEAAQAAB//LZQgC0XAH/8rnB//K0Af/ys4H/8yHB//MlAf/yvEEgAAACALhJAE -AAAIgQAAACALhMAgApJAH/8wbB//MmhJAAAAIAuEIC4ANgAgB6vgAA8D/wMRAAADFQAAH/8tmCAH -pOAgC0YAH/8Y9B//KKwf/xwsH/8dgCABD5wf/8ZsH//FrB//LQwf/8d8AAATiAIAghACAAIQAgAA -EAAaAAAA+saI8AAAAB//K1wf/xF8H/8pMB//EljhAwIAIAeliAAA/98AAP/3IAtGICAIAoB///// -//P///5///8gC0ZwIAtGQCALRqAf/xiYH/8cOAAA+AAgApbAH/8SqAA8PDwf/xewH/8tBCAIEhQf -/+P/H//n/yAHpdAgApbQH/8SnB//ESj//8f/H/8X3B//GbAgC4mAIAuJICALjFAgC4vQIAuLUCAL -iyAgC0eAIAtG0CALRxAf/xpsIAuIsCALjCAf/xpMH/8aRCALi4Af/yh4H/8odCALS9Af/ymgIAtM -QCAIAwAAACcQIAtMcB//KCgf/ymUH/8akB//GowgCAMgH/8pmCACjYQgApBQIAgDQB//HBQgC0zg -H/8pPB//KUAf/ylEH/8pzB//KcQf/yl4H/8pdB//KXAf/ylsH/8paB//KWAf/ylQH/8pVB//KdQg -CANwH/8pTAAAQAMf/xGUH/8auB//KGQf/y8kH/8beAAP//AgC00gIAgEIB//LaQgC02AH/8bPCAL -TdAf/xsQIAtOACALTjAgCAQwAAAlgCALTmAgC06gH/8aKB//GLgf/xYcIAgEUB//F5Qf/xgUIAgE -oB//GiQf/xi8H/8YECAIBKgf/xpQIAtPcCALTxAf/xto//8AAAPn/BggC0+QIAgEsB//KmggAo4M -H/8qZPP///8gAo4UIAKOICACjiwgAo38D////yAIBQAgApcAIAtP8CAIFyT//+1wIAgWxP//7dAg -CBVE///vUCAIFEQgCBU8///wUP//AAEAAf/+AARwFAAEcCgABHAgAARwPAAA/wAABHAsAAD/gAAA -jYAgApAIAARAJAAEQcAABEHEAARByAAEQHgABEDcAARBQAAEQUQgC1kQIAtZUCALWYAgC1hwIAtY -sCALWOAABEFwAABAQAAEcFgAACAoAAAQKAAEQEwABEFgIAtaACALWiAAAHd3AAAzMyALWmAgC1rA -IAta8CALWpAgC1mgIAtZ0AAEAEAgC1sg///v/yALW2AABHBkIAtboOEEbgAAAL8AIAtb4CAIDCQg -CAwUIAgFINLxqfw/UGJNQCQAAAAEAIQA8AAAQgfIAMIHyAAABACAzw/oAAAEAoAABAEAAAB/AQAB -BGogCAukIAKYUAAEAkAgApggAAQCRAAAH58ABAJIAAAW+AAEAkwABAJQAAQCVAAEAlggApfwAAAc -P///D/8ABAIAH/8SSAX14QDgAPAAAAQCBAAEAgj/D/8/AAII1aC17Y0+sMb3P/AAAAACYloABhqA -/z///wAEAgwgC5YgAQAEQAAEAhB/P3f/AAQCFAcAAAAAAYafj/8ADwAEAUAABAFE4HD//wAEAUgA -BAFM8HD//wAEAVAABAFUAAQBWAAEAVwABAFgAAQBZAAEAWgABAFsAAQBcBAQAAAABAF0AAQBeAAE -AXwABAGAAAQBhNAABAAABAGIAAQBjAAEAzAABAM0AAQDOAAEAzygAAAAIAtcIAAEQEgABFLcIAtc -cAAEUiQgApBoAARABAAEQfwABEG8AARSBAAA4+4AABr/IAtcUCALXJB3NZQAAARg4AAAgCAgCAVA -IAgMsAAEE8gABFP8AAAYAAAEcDAAAPoKAARgwAAAiAAABGDEAARB2AAEQdwABEHUAART2AAA//AA -BHA4AARwAAAA//4gC1ywAARwBCALXPAABGDIAACAJAAEQBwABFIcAAAXLAAEU9QABGDkAARg0AAE -WGgABFxoAARwCAAEcDQAAL8vAAC/KAAEWEAABFhEAARYSAAEWEwABFhQAARYVAAEWFgABFhcAARY -AAAEXEAABGDUAARg2AAEYNwgCAzAAARaAAAA//IABFgQAARYFAAEWBgABFgcAARYIAAEWCQABFgo -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 -muegwEAJ+A/fpZvnsMhACfgP1QClnOfA0EAPoAEQpZ3n0MBAD6ABENEPAAAgApkQDMAABiAHZ8gg -ApkUCMAADCAHZ8ggApkYPMAAECAHZxAgApkcBsAAOCAHaTAgApkgCMAAPCAHZ8ggApkkAsAAQCAH -aaAgApkoCMAARCAHZ8ggApksCEAATCAHaFggApkwCEAAUCAHaFggApk0KEAAXCAHaFggApk4KEAA -cCAHaFggApk8KEAAhCAHaFggAplAKEAAmCAHaFggAplEKEAArCAHaFggAplIKEAAwCAHaFggAplM -KEAA1CAHaFggAplQKEAA6CAHaFggAplUEEAA/CAHZiAgAplYEEABDCAHZiAgAplcEEABHCAHZiAg -AplgEEABLCAHZiAgAplkEEABPCAHZiAgAploEEABTCAHZiAgAplsEEABXCAHZiAgAplwEEABbCAH -ZiAgApl0CEABfCAHaFggApl4CEABgCAHaFggApl8CEABhCAHaFggApmAEEABiCAHaFggApmEEEAB -kCAHaFggApmICEABmCAHaFhGQ29FIEREUCBmYWlsZWQgOiBveF9pZCAweCV4IHJ4X2lkIDB4JXgK -AAAAAAAAAABGQ29FIEREUCBmYWlsZWQgOiBEZHBSZXBvcnQgMHgleCBEZHBWYWxpZCAweCV4CgBG -QyB4Y2hnIGFsbG9jIGZhaWxlZDogYXZhaWwgJWQKAEZDT0UgRnJlZTogc3RpbGwgeWllbGRlZCB3 -aGVuIGZyZWVpbmcuLi5mbG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAAAAAAAAAAAAAAUFJM -SSBSc3AgdGltZWRvdXQgOiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAA -AAAAAGh3X2JjbTU0ODJfY2ZnbWRpWyV1XSBzZXR0aW5nIHR5cGUgJXUKAAAAAAAAAAAAAGRoY3A2 -X3RpbWVyX2NiOiByZXNlbmRpbmcgREhDUDZTT0xJQ0lUIGFnYWluCgAAAGRoY3A2X3RpbWVyX2Ni -OiBzZW5kaW5nIERIQ1A2UkVRVUVTVAoAAAAAAAAAAAAAAGRoY3A2X3RpbWVyX2NiOiBzZW5kaW5n -IERIQ1A2UkVORVcgcmVxdWVzdAoAAAAAAGRoY3A2X3RpbWVyX2NiOiBzZW5kaW5nIERIQ1A2UkVC -SU5EIHJlcXVlc3QKAAAAAGRoY3A2X3RpbWVyX2NiOiBESENQNlJFUExZIHJjdmQsIHN0YXRlICV1 -CgAAAAAAAGZhaWxlZCB0byByZW5ldy9yZWJpbmQgZGhjcHY2IGFkZHJlc3MKAAAAAAAAAAAAAHR5 -cGUgJXgsIHhpZCAleCwgdHlwZV94aWQgJXgKAAAAaXB2NiBwcmVmZXJyZWQgYWRkciBbJTA0eCAl -MDR4ICUwNHggJTA0eF0KAAAAAAAAJTA4eDogJTA4eCAlMDh4ICUwOHggJTA4eAoAAAAAAABjaG5l -dF9maW5kX2wydF9lbnRyeTogZGFkZHIgWyUwOHhdLCBbMHglMDh4XSwgbG9jYWwgbmV0d29yayBb -JWRdCgAAAAAAAAAAAAAAAAAAAGNobmV0IGZpbmQgbDJ0ZW50IG5vdCB2YWxpZCwgMHgleCwgaWR4 -ICV1LCBzdGF0ZSAweCV4LCByZXRyeSBjb3VudCAldQoAAAAAAAAAAAAAY2huZXQgbDJ0ZW50IDB4 -JXgsIGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAAAAAAY2huZXQgbDJ0ZW50IGZpbmQgZXJyCgAA -AAAAAAAAAABjaG5ldF9maW5kX2lwNl9sMnRfZW50cnk6IGZpbmQgcHJlZml4IG1hdGNoIFslMDR4 -ICUwNHggJTA0eCAlMDR4XQoAAAAAAAAAAAAAAAAAAE5vIHJvdXRlciBjb25maWd1cmVkLCBsMmRl -dl9mYy0+Zmxvd2NfaWQgMHgleAoAAApSb3V0ZXIgbGlmZSAldSBleHBpcmVkLiBkZWxldGluZyBy -b3V0ZXIgWyUwNHggJTA0eCAlMDR4ICUwNHhdCgBVc2luZyByb3V0ZXIgWyUwNHggJTA0eCAlMDR4 -ICUwNHhdIHRvIHJlYWNoIFslMDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAAAAAAAAAAAAAGNobmV0 -IGZpbmQgaXA2IGwydGVudCBub3QgdmFsaWQsIDB4JXgsIGlkeCAldSwgc3RhdGUgMHgleCwgcmV0 -cnkgY291bnQgJXUKAAAAAAAAY2huZXQgbDJ0ZW50ICUweCwgaWR4ICV1LCByZWZjbnQgJXUKAAAA -AAAAAAAAAAAAY2huZXQgaXA2IGwydGVudCBmaW5kIGVycgoAAAAAAABzZXRfZGlnZXN0OiBCUCBh -bHJlYWR5IGZjIDB4JXggZmxhZ3MgMHgleAoAAAAAAABzZXRfZGlnZXN0OiBjc2sgMHgleCBjb25u -IDB4JXggc3RhdGUKAAAAAAAAAAAAAABzZXRfZGlnZXN0OiB1cGxzdWJtb2RlOiV4LCBwZ2lkeDow -eCV4LCB2YWw6MHgleCBidWZmZXJlZCAweCV4CgAAc2V0X2RpZ2VzdDogYnVmX2xsX2ZsdXNoIGZj -IDB4JXggbmV4dF93ciAweCV4CgAAbm8gdmFsaWQgbDJ0IGVudHJ5IGZvciByZWplY3QgY3NrX2Zj -ICVwCgAAAAAAAAAAbm8gdmFsaWQgbDJ0IGVudHJ5IGZvciBhY2NlcHQgY3NrX2ZjICVwCgAAAAAA -AAAAdGd0X2Nvbm5fd3I6IGZsb3ctaWQ6MHgleCB0eXBlOjB4JXggaXMgd3JvbmcgZm9yIHN1Ym9w -OjB4JXgKAAAAAGlwdjZfYWRkclswXSAweCV4IGlwdjZfYWRkclsxXSAweCV4CgAAAAAAAAAAAAAA -AGFkZHIgJXMgcG9ydCAlcyB0YWcgJXMKAAAAAAAAAAAAcmVkaXJlY3QgSVB2NiAweCV4LTB4JXgs -IHBvcnQgJXgKAAAAAAAAAAAAAAAAAAAAcmVkaXJlY3QgSVB2NCAweCV4LCBwb3J0ICV4CgAAAABh -dXRoZW50aWNhdGVfdGFyZ2V0OiBJbmNvcnJlY3QgcGFzc3dvcmQKAAAAAAAAAABDSEFQX0M6IGRp -Z2VzdCBleHBhbnNpb24gZXJyb3IKAENIQVBfTjogVGFyZ2V0IHVzZXJpZCBtaXNtYXRjaAoAQ0hB -UF9SOiBkaWdlc3QgZXhwYW5zaW9uIGVycm9yCgByY3ZkX3BhcmFtczogZXJyb3IsIGxlbiAlZAoA -AAAAAExvZ291dCBmcm9tIHNlc3Npb24gWzB4JXhdCgAAAAAAaVNDU0kgU2VjLXBhcmFtcyByZWNl -aXZlZCBoYXZlIGVycm9ycyEhCgAAAAAAAAAAVGFyZ2V0IG1vdmVkIHRlbXAuIGNvbm4gJXgsIHNl -c3MgJXgKAAAAAAAAAAAAAAAATG9naW4gRmFpbGVkISEuIGNvbm5fZmMgWzB4JXhdLCBzZXNzX2Zj -IFsweCV4XSwgc3RhdHVzX2NsYXNzIFsweCV4XQoAAAAAAAAAAAAAAABQcm90b2NvbCBFcnJvciBj -Yml0ICVkIHRiaXQgJWQgY3NnICVkIG5zZyAlZAoAAABvZmxkX3J4X2RhdGE6IGludmFsaWQgb3Bj -b2RlIHJlY2VpdmVkLCBhYm9ydGluZyBjb25uZWN0aW9uICV4CgAAbmV0aWZfcGluZ190aW1lcl9j -YjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgaW5kZXZjdHh0IDB4JXggc3RhdGUgWyVkXSBy -ZXRyeV9jbnQgWyVkXQoAAAAAAAAAbmV0aWZfcGluZ190aW1lcl9jYjogbDJ0X2lkeCAlZCwgZGVs -X2wydCAlZAoAAAAAbmV0aWZfcGluZ190aW1lcl9jYjogdGltZSAweCV4IHR5cGUgJWQgY29kZSAl -ZCByZXR2YWwgJWQKAAAAAAAAAG5ldGlmX3BpbmdfdGltZXJfY2I6IHBpbmdfdHMgMHgleCV4IHJz -cF90aW1lIDB4JXgleAoAAAAAAAAAAAAAAABpY21wX2wydF9jYjogc3Vib3AgJWQKAAAAAAAAAAAA -AGljbXBfbDJ0X2NiOiBJbnZhbGlkIHN1Ym9wICVkCgAAbDNpbjZfZGV2X2NvbmZpZzogbGluayBs -b2NhbCBJUCBub3QgYXNzaWduZWQKAAAAbDJkZXZfZmMgWzB4JXggXSBGYWlsZWQgdG8gc3RhcnQg -dGltZXIgZm9yIGlwdjQgZGFkCgAAAAAAAAAAAAAAAGNobmV0X2wyZGV2X3VwX21iX2NiOiByYyBb -JWRdLCBwb3J0IFsldV0sIHN0YXRlIFsldV0sIGNvb2tpZSBbMHgleF0KAAAAAAAAAAAAAAAAbG9n -aW5fdGltZWRvdXQ6IEJyZWFraW5nIHBhdGggcyBbMHgleF0gYyBbMHgleF0gY3NrIFsweCV4XQoA -AAAAAHJlY292ZXJ5X3RpbWVvdXQ6IHNlc3MgaWQgWzB4JXhdIGluIGxvZ291dAoAAAAAAGZvaXNj -c2k6IFJlY292ZXJ5IHRpbWVkIG91dCBhZnRlciBbJXVdIHJldHJ5LCBiYWlsaW5nIG91dAoAAAAA -AABUQ1AgY29ubiBlc3RhYmxpc2htZW50IGZhaWxlZCAlZAoAAAAAAAAAAAAAAAAAAABkYXRhX2Rk -cDogaXRhc2staWQ6MHgleCwgZmxhZ3M6MHgleCwgZHhmZXJfbGVuOiVkLCBkc2VudF9sZW46JWQK -AAAAAAAAAAAAAAAAAAAAAGRhdGFfZGRwOiB0aWQgWzB4JXhdIGVycm9yIFsweCV4XQoAAAAAAAAA -AAAAAAAAAEREUCBlcnJvciBbMHgleF0sIGFib3J0aW5nIGNvbm5uIFsweCV4XQoAAAAAAAAAAHJ4 -X2RhdGFfZGRwOiBSZXNwb25jZSByZWNpZXZlZCBmb3IgdGFzayBbMHgleF0gd2hpbGUgaW52YWxp -ZCB0YXNrIG9yIGNvbm5lY3Rpb24gc3RhdGUuIHRhc2sgc3RhdGUgWzB4JXhdLCBjb25uIHN0YXRl -IFsweCV4XSwgY29ubiBmbGFncyBbMHgleF0KAD09PiByZWNlaXZlZCBkYXRhIGZjIGlkIDB4JXgg -Zmxvd2NfaWNvbm5fZmxhZ3MgMHgleCBsZW4gMHgleAoAAABmb2lzY3NpX3Rhc2sgTlVMTCwgb3A6 -MHgleCBjc2tfZmNpZDoweCV4IGNza19zdGF0ZToweCV4IHRjYl9mY2lkOjB4JXgsIHRjYl9zdGF0 -ZToweCV4IAoAAAAAAAAAAABpaGRyOiBSZXNwb25jZSByZWNpZXZlZCBmb3IgdGFzayBbMHgleF0g -d2hpbGUgaW52YWxpZCB0YXNrIG9yIGNvbm5lY3Rpb24gc3RhdGUuIHRhc2sgc3RhdGUgWzB4JXhd -LCBjb25uIHN0YXRlIFsweCV4XSwgY29ubiBmbGFncyBbMHgleF0KAAAAAAAAAABpaGRyOiBJbnZh -bGlkIHRhc2sgc3RhdGUgMHgleCBmb3IgdGFzayAweCV4LCBpdHQgWzB4JXhdLCBvcGMgWzB4JXhd -CgAAAAAAAAAAAAAAAGlzY3NpX2hkcl9yeDogYWJvcnQgY29ubjogZmxhZ3MgPj4gNyBbMHgleF0s -IGhkc2dsZW4gWzB4JXhdIGRzcl9kdGwgWzB4JXhdLCBtYXhfYnVyc3QgWzB4JXhdCgAAAE1heCBk -YXRhIGxlbiBleGNlZWRlZCAlZCA+ICVkCgAASW52YWxpZCBvcGNvZGUgMHgleCBpbiBjdHJsIHBh -dGgKAAAAAAAAAAAAAAAAAAAAY29pc2NzaV9maW5kX3Rhc2s6IHRhc2sgbm90IGZvdW5kIHRjYl9m -YyBpZCAweCV4IGl0dCAweCV4IHR0dCAweCV4CgAAAAAAAAAAAAAAAABkYXRhX2RkcDogaXRhc2st -aWQ6MHgleCwgZmxhZ3M6MHgleCwgZHhmZXJfbGVuOiVkLCBkc2VudF9sZW46JWQKAAAAAAAAAAAA -AAAAAAAAAGRhdGFfZGRwOiB0aWQgWzB4JXhdIGVycm9yIFsweCV4XQoAAAAAAAAAAAAAAAAAAERE -UCBlcnJvciBbMHgleF0sIGFib3J0aW5nIGNvbm5uIFsweCV4XQoAAAAAAAAAAGlzY3NpX2NtcDog -b3BjOjB4JXgsIGluIGRhdGEgcGF0aAoAAAAAAAAAAAAAAAAAAGlzY3NpX2NtcDogUmVzcG9uY2Ug -cmVjaWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9u -IHN0YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3Mg -WzB4JXhdCgAAAGlzY3NpX2NtcDogSW52YWxpZCB0YXNrIHN0YXRlIDB4JXggZm9yIHRhc2sgMHgl -eCwgaXR0IFsweCV4XSwgb3BjIFsweCV4XQoAAAAAAAAAaXNjc2lfaGRyX3J4OiBhYm9ydCBjb25u -OiBmbGFncyA+PiA3IFsweCV4XSwgaGRzZ2xlbiBbMHgleF0gZHNyX2R0bCBbMHgleF0sIG1heF9i -dXJzdCBbMHgleF0KAAAAaXNjc2lfY21wOiBvcGM6MHgleCwgaW4gY3RybCBwYXRoCgAAAAAAAAAA -AAAAAAAAPT0+IHJlY2VpdmVkIGRhdGEgZmMgaWQgMHgleCBmbG93Y19pY29ubl9mbGFncyAweCV4 -IGxlbiAweCV4CgAAAGlkYXRhOiB0aWQ6MHgleCwgb3A6MHgleCwgbGVuOjB4JXgsIHNlcToweCV4 -LCBzdGF0dXM6MHgleC4KAAAAAABNYXggZGF0YSBsZW4gZXhjZWVkZWQgJWQgPiAlZAoAAE1heCBk -YXRhIGxlbiBleGNlZWRlZCAlZCA+ICVkCgAAcmV0dXJuX3BlbmRpbmdfdGFzazogbm8gV1IgaXRh -c2s6IGlkOjB4JXgsIHN0YXRlOjB4JXgsIGNvbm46MHgleCwgZmxhZ3M6MHgleCwgY29ubi1pZDow -eCV4LCBkZHA6JWQKAAAAAAAAAAAAAAAAAGhhbmRsZXIgJXgsIHF1ZXVlZCAleAoAAAAAAAAAAAAA -cmV0dXJuX3BlbmRpbmdfdGFzazogRG9uZSBzZW5kaW5nIHRhc2sgZXJyb3IgdG8gaG9zdAoAAAAA -AAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IGRlcXVldWUgdGFzayBbMHgleF0sIHN0YXRlIFsw -eCV4XSBmcm9tIHR4X2xpc3QKAAAAAAAAAAAAAAAAcmV0dXJuX3BlbmRpbmdfdGFzazogYWxsIHRh -c2tzIHJldHVybmVkLCByZWNvdmVyeSBzdGF0ZSB0cmFucyB0byBbMHgleF0KAAAAAAAAAABwcm9j -ZXNzX3R4X3F1ZXVlOiB0eF9xdWV1ZSBmb3IgY29ubjoweCV4IHN0b3BwZWQsIGFib3J0aW5nIHRh -c2suCgAAAAAAAAAAAAAAAAAAAFdBVENIRE9HX2Rpc3BhdGNoIGNhc2UgdG8gYXZvaWQ6IENvdW50 -ZXJfd2F0Y2hkb2cgJXUgQ291bnRlcl9zY2hlZCAldSAKAAAAAAAAAAAAV0FUQ0hET0c6IGRldmlj -ZSBzaHV0ZG93bgoAAAAAAABXQVRDSERPRzogcG9ydFsldV0gcGF1c2Ugd2F0Y2hkb2cgdGltZW91 -dAoAAAAAAABXQVRDSERPRzogYnlwYXNzIHRpbWVvdXQKAAAAAAAAAFdBVENIRE9HOiBGTFIgLSBu -b3QgaW1wbGVtZW50ZWQgeWV0CgAAAAAAAAAAAAAAAFdBVENIRE9HOiB0ZW1wZXJhdHVyZSBvZiAl -ZEMgZXhjZWVkcyB0aHJlc2hvbGQgb2YgJWRDCgAAAAAAAAAAAABmaWx0ZXI6IHBvcmdyYW1taW5n -IHRpZCAldSAobGUgdGNhbSBpbmRleCAldSkuLi4KAAAAAAAAAAAAAAAAAAAAZmlsdGVyOiByZXF1 -ZXN0aW5nIGNvbXBsZXRpb24uLi4KAAAAAAAAAAAAAAAAAAAAaHdfY2ltX3RzY2hfY2hfY2xfcmF0 -ZV9tYXhfcmVzb2x1dGlvblsldS8ldV06IGNhcHBlZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1aXJl -ZCAldSB0byAldTsgcmF0ZSAldSAoZWZmICV1KSBkZWZpY2l0X21heCAldQoAAAAAAABDYW5ub3Qg -Z2V0IGNsYXNzIFsldS8ldV0gcmF0ZS9wZXJjZW50ICV1LyV1IHdpdGggY29uZmlndXJlZCBncmFu -dWxhcml0aWVzLiBDaGVjayBjb25maWcgZmlsZQoAAABkY2J4X2llZWVfY21kaFsldV0gd3JpdGUg -b25seSBwZXJtaXR0ZWQgb24gbG9jYWwgY29uZgoAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhbJXVd -IGNhbm5vdCB3cml0ZSAldSBhcHBzIChNQVg6ICV1KQoAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9j -bWRoWyV1XSByZXF1ZXN0aW5nIERDQl9JRUVFX0NNRAoAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1 -bmtub3duIGZlYXR1cmUgd3JpdGU6ICV1CgAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1bmtub3duIGZl -YXR1cmUgcmVhZDogJXUKAAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIGNvbm5l -Y3Rpb24KAAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIElQdjYgY29ubmVjdGlv -bgoAAAAAAAAAAAAAAAAAAABkaXNwYXRjaF9kZWZlcnJlZF9jbGFzc19jbGFzc19zaGFwaW5nWyV1 -OiV1XTogbGlzdF9lbXB0eQoAAAAAAAAAbG9vcGJhY2sgYnVmZmVyIGdyb3VwWyV1XSBpcyBkaXNh -YmxlZAoAAAAAAAAAAAAAaW52YWxpZCBidWZmZXIgZ3JvdXBbJXVdIGNvbmZpZ3VyYXRpb246IG10 -dSAldSBsd20gJXUgaHdtICV1IGR3bSAldQoAAAAAAAAAAAAAAABmYyAldSB2ZiAldSBnb3QgaXZm -PTB4JXgscmFuZ2U6ICUjeC0lI3ggKCV1LyV1IHVzZWQpCgAAAAAAAAAAAAAAVkkgJXUgY2Fubm90 -IGdldCBSU1Mgc2xpY2U6IE5vIG1vcmUgc2xpY2VzIGF2YWlsYWJsZSAodXNlZCAldS8ldSkKAAAA -AAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IHdpdGggcG9ydCBtYXNrIDB4JXggY2Fubm90IGFjY2Vz -cyBwb3J0ICV1LCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90 -IGFsbG9jYXRlIHZpaWQsIHJldCAlZAoAAHBmbiAldSB2Zm4gJXUgY291bGQgbWFwIHZpaWQgIDB4 -JXggdG8gZmxvd2MsIHJldCAlZAoAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvdWxkIG5vdCBh -bGxvY2F0ZSB1d2lyZSBmdW5jICVkIG1hYyBhZGRyLCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBm -ICVkLCB2ZiAlZCwgRVJST1IgZXhjZWVkZWQgbWF4IG1hYyBsaW1pdCAlZC8lZAoAAAAAAAAAAAAA -AAAAAABtaWlfaW5pdFsldV06IGFjYXBzIDB4JXgKAAAAAAAAAG1paV9mb3JjZV9zcGVlZFsldV06 -IHJjYXBzIDB4JXgKAAAAAAAAAAAAAAAAAAAAAG1paV9wZG93blsldV06IHBvd2VyZG93biBlbiAl -dQoAcG9ydF9jbWRfaGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAcG9ydFsl -dToweCUwMng6MHglMDJ4XTogbDFjZmcsIGludmFsaWQgcmVxdWVzdCwgcGNhcHMgMHgleCBhY2Fw -cyAweCV4IG1jYXBzIDB4JXgsIHJjYXBzIDB4JXgKAAAAUmV0dXJuaW5nIHN1Y2Nlc3MgYXMgdGhl -IGxpbmsgc3RhdHVzIHVwZGF0ZSBpcyBwZW5kaW5nCgAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4 -JTAyeF06IGwxY2ZnLCBwY2FwcyAlI3ggYWNhcHMgJSN4IHJjYXBzICUjeCBtY2FwcyAlI3gKAAAA -AAAAAAAAcG9ydFsldV06IGwxY2ZnLCBGaXJlIENvZGUgRkVDIGlzIG5vdCBzdXBwb3J0ZWQgZm9y -IDEwMEcsIHJjYXBzICUjeAoAAAAAAAAAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNm -ZywgbWRpIGlzc3VlIHBjYXBzIDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAHBvcnRb -JXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBjYW5ub3QgZm9yY2Ugbm8vbXVsdGlwbGUgc3BlZWQo -cyksIHBjYXBzIDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAAAABwb3J0WyV1 -OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgY2Fubm90IGZvcmNlIG11bHRpcGxlIGZlYyhzKSwgcGNh -cHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgKAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1 -bmtub3duIGFjdGlvbiAweCV4CgAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1bmtub3duIHJl -YWQgYWN0aW9uIDB4JXgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBjcGwg -MHglMDh4JTA4eAoAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBjcGwgMHglMDh4JTA4 -eCAweCUwOHglMDh4CgAAAAAAAAAAAAAAAAAAAGNwbF9lcnJfbm90aWZ5OiB0aWQgJXUgbGVuICV1 -CgAARkNPRSBGcmVlOiBzdGlsbCB5aWVsZGVkIHdoZW4gZnJlZWluZy4uLmZsb3djX2lkICV4IGZs -b3djX2ZsYWdzICV4IAoAAAAAAAAAAAAAAABGQ09FIEJQIFdSIEVSUjogV1Igd2l0aCBjb29raWUg -JXgleCBlcnJvcmVkIGJhY2sgCgAAAAAAAAAAAAAAAAAAYWJvcnQvY2xvc2UgV1Igd2l0aCBjb29r -aWUgMHglbHggd2FzIGlzc3VlZCBvbiBzc24gMHgleCBpbiB3cm9uZyBzdGF0ZSAweCV4CgAAAABh -Ym9ydCBXUiBvbiBzc24gMHgleCBkaWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUgMHgleCV4CgAA -AAAAAAAAY2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggb24gc3NuIDB4JXg7ZGlkIG5vdCBmaW5k -IFdSIHdpdGggY29va2llIDB4JWx4CgAAAAAAAABhYm9ydCBXUiBvbiBzc24gMHgleCB3YXMgaXNz -dWVkIG9uIHhjaGcgMHgleCB3aXRoIHJ4X2lkIDB4JXggaW4gd3Jvbmcgc3RhdGUgMHgleAoAAAAA -AAAAAAAAAAAAAABkY2J4X2FwcGx5X2FwcF9jZmdbJXVdTkVXIEFQUCBUTFYgCgAAAAAAAAAAAAAA -AABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfTElOS1VQCgBkY2J4X2Nl -ZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIFNFVF9MT0NBTF9QQVJBTUVURVJTCgAAAAAAAAAAAAAA -ZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX05PX0FEVkVSVElTRQoAAAAA -AAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9QRUVSX05PVF9B -RFZFUlRJU0VfRENCWAoAAAAAAAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJl -WyV1XSBGRUFUVVJFX1BFRVJfTk9UX0FEVkVSVElTRV9GRUFUVVJFCgAAAAAAAAAAAAAAAABkY2J4 -X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfVVBEQVRFX09QRVJfVkVSU0lPTgoA -AAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJfVVBEQVRFX09Q -RVJfVkVSU0lPTgoAAAAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVd -IEZFQVRVUkVfR0VUX1BFRVJfQ0ZHCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0 -dXJlWyV1XSBGRUFUVVJFX0NGR19OT1RfQ09NUEFUSUJMRQoAAAAAAGRjYnhfY2VlX2ZlYV9zbVsl -dV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0VfTE9DQUxfQ0ZHCgAAAAAAAAAAAABkY2J4X2NlZV9m -ZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfVVNFX1BFRVJfQ0ZHCgAAAAAAAAAAAAAAZGNi -eF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0ZFQVRVUkVfRElTQUJMRUQKAAAA -AAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9FUlJPUl9DSEFOR0UK -AAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vzc1sldV0gcmVjZWl2ZWQgQldzIGRvIG5vdCBhZGQg -dXAgdG8gMTAwIQoAAAAAAAAAV0FSTklORzogcmVjZWl2ZWQgQXBwIFRMViBjb250YWlucyBtb3Jl -IHRoYW5GVyBjYW4gaGFuZGxlIChtYXg6ICV1OyB0bHYgY29udGFpbnM6ICV1CgAAAAAAAAAAAAAA -ZGNieF9pZWVlX3Byb2Nlc3NbJXVdIHN1YnR5cGUgJSN4IHJlbV9mdF9jaGFuZ2VkICV1IHNtX2No -YW5nZSAldQoAAAAAAAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vzc1sldV0gc3VidHlwZSB1bmtu -b3duCgAAAAAAAAAAAABkY2J4X3BhcnNlX3BrdFsldV0gZXJyb3IgJWQKAAAAAGNobmV0X2wydF91 -cGRhdGU6IGwyZGV2X2ZjIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX2lkIFsldV0gbDJkZXZfZmMt -PmZsb3djX2ZsYWdzIFsweCV4XSwgaW50ZiBbMHgleF0KAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBk -YXRlOiBpbiBkZWxheWVkX3Byb2Nlc3NpbmcsIGwydGVudCBbJTA4eF0KAAAAAAAAAAAAY2huZXRf -bDJ0X3VwZGF0ZV9jYWNoZTogbDJ0IGlwNCBlbnRyeSBub3QgZm91bmQKAAAAAAAAAAAAAAAAAAAA -AGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGwydCBpcDYgZW50cnkgbm90IGZvdW5kCgAAAAAAAAAA -AAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBib3RoIGlwNCBhbmQgaXA2IGFkZHIgY2Fu -bm90IGJlIG51bGwKAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTogbDJ0IGVudHJ5IGlkeCAldSwg -c3RhdGUgMHgleAoAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGU6IGwydF91cGRhdGUgcmVxdWVz -dCBzZW50IGwydGVudCBbJTA4eF0sIGwydGVudC0+aWR4IFslZF0sIGwydGVudC0+dmxhbiBbJWRd -CgAAAGljbXAgY2hlY2tzdW06MHgleAoAAAAAAAAAAAAAAAAAaXB2NiB0Y3AgcmVjdiwgaW5pdCB0 -eHEgd3IgZmFpbGVkCgAAAAAAAAAAAAAAAAAAREhDUHY2IHBhY2tldCB0eXBlICV1LCBvcHRzbGVu -ICV1IHJlY2VpdmVkCgAAAAAASW52YWxpZCBkaGNwIHN0YXRlICVkCgAAAAAAAAAAAABJZ25vcmUg -REhDUHY2IG1zZyB4aWQgJXgsICBkaDZjdHh0LT54aWQgJXgKAAAAAABFcnJvciBpbiBESENQdjYg -b3B0aW9ucyBwYXJzaW5nLiBJZ25vcmluZyBtc2csIGkgJWQsIG9wdHNsZW4gJWQKAAAAAAAAAAAA -AAAAAAAAAERIQ1AgZmFpbGVkLCBzdGF0dXNjb2RlICVkLiBJZ25vcmluZyBhZHZlcnRpc2UKAGlj -bXA2IGNoZWNrc3VtIHZhbGlkYXRpb24gZmFpbGVkLCBvciBlcnIgcmN2ZGlnbm9yaW5nIGljbXA2 -IG1zZyAldSwgZGxlbiAldQoAAAAAdGNwIHJlY3YsIGluaXQgdHhxIHdyIGZhaWxlZAoAAABDb3Vs -ZCBubyBhbGxvY2F0ZSBwY2IhISBGcmVlaW5nIGZjZiAhISEKAAAAAAAAAAB2bl9wYXJzZSB1bmtu -b3duIHN1YmNvZGUgJXUKAAAAAHZuX3BhcnNlIHVua25vd24gZHR5cGUgJXUKAAAAAAAAaWdub3Jp -bmcgZmlwIHJlY3YgZm9yIHBjYiBmbG93OiV4IGluIG9mZmxpbmUgc3RhdGUKAAAAAAAAAAAAAAAA -AGZpcF92bjJ2bl9yZWN2X2VyciAKAAAAAAAAAAAAAAAAQ291bGQgbm90IGFsbG9jYXRlIGZsb3dj -ISEhIQoAAABDb3VsZCBub3QgYWxsb2NhdGUgU0NCIGZsb3djISEhIQoAAAAAAAAAAAAAAAAAAABD -b3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGxvZ28KAAAAAAAAAAAAAAAAAABpZ25vcmluZyBm -aXAgcmVjdiBmb3IgZmNmIGZsb3c6JXggaW4gb2ZmbGluZSBzdGF0ZQoAAAAAAAAAAAAAAAAAQ291 -bGQgbm90IGZpbmQgcmlnaHQgc2NiIGZvciBmbG9naQoAAAAAAAAAAAAAAAAAcG9ydCAweCV4LCBz -dGF0ZSAweCV4LCByZXRyeSBub3Qgc3VwcG9ydGVkCgAAAAAARmxvZ2kgcmVzcCByY3Ygd2l0aCB1 -bmtub3duIHhjaGcgb3hfaWQleCBzaWQgJTJ4JTJ4JTJ4IGRpZCAlMnglMnglMngKAAAAAAAAAAAA -AABOX1BPUlQgMHgleCV4JXggcmVqZWN0ZWQgUExPR0kgd2l0aCByZWFzb24gY29kZSAleAoAAAAA -AAAAAAAAAAAAQUJUUyB3aGlsZSBhd2FpdGluZyBQUkxJIFJzcDogZmxvd2NfaWQgMHgleCBveF9p -ZCAweCV4IHJ4X2lkIDB4JXggCgAAAAAAAAAAAAAAAABBQlRTIGZha2UgUnNwOiBsb2MgMHgleCBv -eF9pZCAweCV4IHJ4X2lkIDB4JXgKAABsbGRwX3J4X3BrdF9oYW5kbGVyWyV1XSBkcm9wIHByZS1p -bml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9h -ZGRyLmFkZHIgWzB4JXhdLCBzaXAgWzB4JXhdLCByaXAgWzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAA -AAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGluX2F0dHIuaXB2NC5hZGRyOjB4JXgsIGFoZHIuc2lwOjB4 -JXgKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2FycF9yZWN2OiBpcCBjb25mbGljdCBkZXRlY3RlZAoA -AAAAAAAAAAAAAGNobmV0X2FycF9yZWN2OiBwaWQgWyV1XSwgdmxhbiBbMHgleF0sIGFycCBvcCBb -MHgleF0sIHNpcCBbMHgleF0sIHJpcCBbMHgleF0gbDJkZXZfZmMtPmZsb3djX2lkICV4IGwyZGMt -PmluNF9kZXYuaW5fYWRkci5hZGRyICV4CgAAAAAAAAAAAAAAAAAAACV4JXgleCBSZWNpZXZlZCBM -T0dPIGZyb20gJXgleCV4IAoAAAAAAAAAAAAAAAAAAENQTF9SWF9QS1Q6IElnbm9yaW5nIE1PUCBv -ciBFT1AgZnJhbWVzCgAAAAAAAAAAAEZhaWxlZCB0byBwb3N0IHhjaGcgZXJyOiBzc25pIDB4JXgg -Y29va2llIDB4JWx4IHJ2YWwgJXggCgAAAAAAAABvZmxkX2Fib3J0X3JlcV9uZWdhZHZbJXVdOiB3 -ciAweCUwOHggY3BsX2Fib3J0X3JlcSBERUxJVkVSRUQKAAAAaG9zdF93clsldV06IHdyIDB4JTA4 -eCBjcGxfYWJvcnRfcmVxIHN0YXR1cyAweCV4CgAAAAAAAAAAAAAAAAAAAHBrdHNjaGVkX2NsX3Js -WyV1OiV1XTogbW9kZSB8IHVuaXQgfCByYXRlIDB4JTA2eCBtaW4gJXUgbWF4ICV1IHBrdHNpemUg -JXUKAAAAAAAAcGYgJWQsIHZmICVkIHNlY3JldCBrZXlfaW5kZXggJWQsIFZGIHNlY3JldCAweCV4 -CgAAAAAAAAAAAAAAAAAAAHBhcmFtX2NobmV0WzB4JXg6MHgleF06IGNobmV0IDB4JXggcmVhZCAl -dSBwZiAldSByZXQgJWQKAAAAAAAAAABwYXJhbV9kbWFxWzB4JXg6MHgleF06IGRtYXEgMHgleCBy -ZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAAAAUlNTU0VDUkVUS0VZOiByc3NzZWNyZXQgdGJs -IGJhc2UgJWQsIHJzc25zZWNyZXQgJWQKAAAAAAAAAAAAAAAAAE1DWyV1XSBpbml0X3N0YXRlX21h -Y2hpbmUgMHglMDJ4CgAAAAAAAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIG5vdCBjb21wbGV0 -aW5nLCBNQyBjdXJyZW50IGluaXQgc3RhdGUgaXMgMHglMDJ4CgAAAAAAAAAAAAAAAAAASW5pdGlh -bGl6aW5nIElCTSBERFIzNExNQwoAAAAAAABERFIgaW5pdCBjb21wbGV0ZSwgYmVnaW5uaW5nIGNh -bGlicmF0aW9uCgAAAAAAAABERFIgY2FsaWJyYXRpb24gc3VjY2VlZGVkCgAAAAAAAE1DWyV1XSBf -aHdfbWNfaW5pdF9tYwoAAAAAAAAAAAAAX2h3X21jX2luaXRfbWM6IGVycm9yLCByZXQgJWQKAABw -aHk6IGZhaWxlZCB0byBhbGxvY2F0ZWQgbWVtb3J5IGZvciBwaHkgZncgZmlsZSwgcmV0ICVkCgAA -AAAAAAAAaHdfbGVfZmlsdGVyX2N0dXBsZTogdHVwbGUgJXUgbm90IHNwZWNpZmllZCBidXQgcmVx -dWlyZWQgZm9yIG1hc2sgMHgleAoAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogdGltZXJf -cnMgJXV1cyB0aW1lc3RhbXBfcmVzICV1dXMgZGVsYXllZGFja19yZXMgJXV1cwoAAAAAAGh3X3Rw -X3RjcF9zZXR0aW5nc193OiBkYWNrX3RpbWVyICV1dXMgbXNsICV1dXMgcnh0X21pbixtYXggJXUs -JXV1cyBwZXJzX21pbixtYXggJXUsJXV1cwoAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBr -ZWVwX2lkbGUsaW50dmwgJXUsJXVzIG1heHJ0dCAldXVzIGluaXRzcnR0ICV1dXMgZmlud2FpdDJf -dGltZXIgJXV1cwoAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGRhY2tfdGltZXIg -ZnJvbSAldSB0byAldQAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBtc2wg -ZnJvbSAldSB0byAldQBod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWluIGZyb20g -JXUgdG8gJXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcnh0X21h -eCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5n -IHBlcnNfbWluIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3Nfdzog -Y2FwcGluZyBwZXJzX21heCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRp -bmdzX3c6IGNhcHBpbmcga2VlcF9pZGxlIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAGh3X3RwX3Rj -cF9zZXR0aW5nc193OiBjYXBwaW5nIGtlZXBfaW50dmwgZnJvbSAldSB0byAldQAAAAAAAAAAAABo -d190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRfbWF4cnR0IGZyb20gJXUgdG8g -JXUAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgaW5pdF9zcnR0X2luaXRzcnR0IGZy -b20gJXUgdG8gJXUAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGZpbndhaXQyX3RpbWVy -IGZyb20gJXUgdG8gJXUAAAAAAABITUEgaXMgc3VwcG9ydGVkIG9ubHkgd2hlbiBleHRlcm5hbCBt -ZW1vcnkgaXMgbm90IHByZXNlbnQKAAAAAAAAZmlsdGVyTW9kZT0lI3ggaWxsZWdhbDogc2VsZWN0 -cyAlZCBiaXRzIChtYXggJWQpCgAAAAAAAAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRy -aWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFz -aCAldQoAAAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IGNsaXAgJXUgbm9y -bWFsIGZpbHRlciAldSBoaSBwcmlvcml0eSBmaWx0ZXIgJXUgc2VydmVyICV1IGFjdGl2ZSAldSBo -YXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAaHdfc2dlX3F1ZXVlX2Jhc2VfbWFwWyV1XTog -ZXhjZWVkZWQgbnVtYmVyIG9mIGVncmVzcyBxdWV1ZXMsICV1CgAAAAAAAAAAAAAAAAAAAABod19z -Z2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5ncmVzcyBxdWV1ZXMg -d2l0aCBmcmVlbGlzdCBhbmQgaW50ZXJydXB0LCAldQoAAABod19zZ2VfcXVldWVfYmFzZV9tYXBb -JXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5ncmVzcyBxdWV1ZXMsICV1CgAAAAAAAAAAAAAAAAAA -AEVycm9yLCBUb3RhbCBSU1MgU2VjcmV0IHRhYmxlIGFsbG9jYXRpb24gJWQgPiAxNgoAAAAAAAAA -AAAAAAAAAABjZl9wYXJzZTogZmlsZSBtZW10eXBlIDB4JXggbWVtYWRkciAweCV4IG1hcHBlZCBA -ICVwOgoAAAAAAAAAAAAAY29uZmlndXJlZCB3aXRoIGNhcHMgbmJtfGxpbmsgMHglMDh4IHN3aXRj -aHxuaWMgMHglMDh4IHRvZXxyZG1hIDB4JTA4eCBpc2NzaXxjcnlwdG8gMHglMDh4IGZjb2U6MHgl -eAoAAAAAAAAAAAAAAG5ldCBWSSBhbGxvY2F0aW9uIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBl -cnJvciAlZAoAAAAAAAAAAAAAAABuZXQgVkkgbWFjIGFkZHJlc3MgcHJvZ3JhbW1pbmcgZmFpbGVk -IGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAAAAAG5ldCBWSSByeG1vZGUg -cHJvZ3JhbW1pbmcgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAABuZXQgVkkg -cnNzIGluZGlyZWN0aW9uIHRhYmxlIHByb2dyYW1taW5nIGZvciBmY19pZCAldSBmYWlsZWQgd2l0 -aCBlcnJvciAlZAoAAAAAAG5ldCBWSSByc3MgY29uZmlnIGNvbW1hbmQgZmFpbGVkIGZvciBmY19p -ZCAldSB3aXRoIGVycm9yICVkCgAAAABuZXQgVkkgY29tbWFuZCBmYWlsZWQgZm9yIGZjX2lkICV1 -IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAAaXNjc2kgZWRyYW0gc3RhcnQgJXggZW5kICV4 -CgAAAABmb2lzY3NpX2luaXQ6IGluaXRfZG9uZToldSwgZm9pc2NzaV9udGFza3M6JXUsIGZvaXNj -c2lfbnNlc3M6JXUsIG5jc29jazoldSwgbnNwb3J0czoldSwgZm9pc2NzaV9uaW5pdDoldSwgcmM6 -JWQKAAAAAAAAAAAAAAAAAAAAAGNoX2NsX3JhdGVbJXUvJXVdOiBjYXBwZWQgY2xhc3MgcmF0ZSBm -cm9tIHJlcXVlc3RlZCAldSB0byBjb25maWd1cmVkIChlZmZlY3RpdmUpIGNoYW5uZWwgcmF0ZSAl -dQoAAAAAAAAAAAAAAAAAAABDYW5ub3QgZ2V0IGNsYXNzIFsldS8ldV0gcmF0ZSAldSB3aXRoIGNv -bmZpZ3VyZWQgZ3JhbnVsYXJpdGllcy4gQ2hlY2sgY29uZmlnIGZpbGUKAAAAAAAAAAAAAAAAAABw -a3RzY2hlZCBjaGFubmVsICV1IHNldHMgc3BlZWQgKGZyb20gJXUpIHRvICV1IGticHMKAAAAAAAA -AAAAAAAAbmV0X2wyZGV2X25vdGlmeTogcGdpZCBbMHgleF0sIHByaW8gWzB4JXhdLCBjaCBbMHgl -eF0KAAAAAAAAAAAAAFsldV0gdW5hYmxlIHRvIGV4ZWN1dGUgaW50ZXJuYWwgRENCX0lFRUVfQ01E -CgAAAHBvcnRbJXVdIHB0eXBlICV1IGxhbmUgJXU6IHJ4Y2ZnID0gJSN4CgAAAAAAAAAAAHBvcnRb -JXVdIHB0eXBlICV1IGxhbmUgJXU6IHR4Y2ZnID0gJSN4CgAAAAAAAAAAAHJ4X2NvbmZpZyBzcGVl -ZCAweCV4IHBsbF9zZWwgJWQgYndfc2VsICVkCgAAAAAAAHR4X2NvbmZpZyBzcGVlZCAweCV4IHBs -bF9zZWwgJWQgYndfc2VsICVkCgAAAAAAAHBvcnRbJXVdIGxpbmsgZG93biAoJXUpIChsc3RhdHVz -ICUjeCkKAAAAAAAAAAAAAHBvcnRfcmVzZXRbJXVdOiBmb3JjaW5nIGZvciBwdHlwZSAweCV4LCBz -cGVlZCAweCV4CgAAAAAAAAAAAAAAAABpMmMgZXJyb3IgY2F1c2VkIGJ5IG1vZHVsZSB1bnBsdWcK -AAAAAAAAAAAAAAAAAABzZW5kdG8gcGVuZGluZzogd3JfcGVuZCAlcCBmb3IgcG9ydCAldSwgd2Fu -dCB0byBzZW5kIHRvIHBvcnQgJXUKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHVwZGF0ZSAoZmxv -d2NpZCAldSByYyAldSkKAAAAAAAAAAAAAAAAAHBvcnRfc2V0X2xvb3BiYWNrIHBvcnQgJSN4IGN1 -cnJlbnQgJSN4IG1vZGUgJSN4CgAAAAAAAAAAAAAAAAAAAABwb3J0WyV1XSBzcGVlZCB1cGRhdGU6 -ICUjeAoAAAAAAHBvcnRbJXVdIGJlZ2lubmluZyBkZWJvdW5jZQoAAAAAUVNGUCBtb2R1bGUgdW5w -bHVnIC0gcmVpbml0aWFsaXppbmcgcnhfbG9zICB0byAweGZmCgAAAAAAAAAAAAAAAGdwaW9fcXNm -cF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHJ4X2xvcyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABn -cGlvX3FzZnBfbW9kdWxlX3VwZGF0ZTogY2hhbmdlZCB0eF9kaXMgZnJvbSAweCV4IHRvIDB4JXgK -AAAAAAAAZGlzYWJsaW5nIHR4ICUjeCByeCAlI3gKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFu -ZGxlclsldV0gcG93ZXJpbmcgZG93bgoAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0g -cG93ZXJpbmcgdXAKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gdW5rbm93biBz -dGF0ZSAoc3RhdGUgPSAlI3gpCgAAAAAAAAAAcG9ydF9saW5rX3N0YXRlX2hhbmRsZXI6IFNvbWV0 -aGluZyB3ZW50IHRlcnJpYmx5IHdyb25nLiByZXQgPSAlZAoAAAAAAAAAAAAAAAAAAABsZSBjb25m -aWd1cmF0aW9uOiBoYXNoIHJlZ2lvbiB0b28gbGFyZ2UgdG8gZW5hYmxlIHNlcnZlciBzcmFtCgAA -bGUgaW5pdGlhbGl6YXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1 -IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAbGUgaW5pdGlhbGl6YXRpb246 -IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAldSBhY3RpdmUg -JXUgaGFzaCAldSBuc2VydmVyc3JhbSAldQoAAAAAAAAAAAAAAGh3X3RwX2luaXQ6IHRjYiByZWdp -b24gKHN0YXJ0IDB4JTA4cyBzaXplICV1KSBtdXN0IGJlIGluIGZpcnN0IDI1Nk1CIG9mIE1BIG1l -bW9yeQoAAAAAAAAAAAAAAAAAAGh3X3RwX2luaXQ6IHBnbW5ndCByZWdpb24gKHN0YXJ0IDB4JTA4 -cyBzaXplICV1KSBtdXN0IGJlIGluIGZpcnN0IDI1Nk1CIG9mIE1BIG1lbW9yeQoAAAAAAAAAAAAA -AGh3X3RwX2luaXQ6IFRQIHBnbW5ndCBpbml0aWFsaXphdGlvbiBkaWQgbm90IGNvbXBsZXRlCgAA -AAAAAAAAAABidWZtX2luaXQ6IG4gJXUgYnVmbGw2NGludF9zaXplIDB4JXgKAAAAAAAAAAAAAABi -dWZtX2luaXQ6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIGludGVybmFsIGJ1ZmxsNjQg -YnVmZmVycwoAAAAAAAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxs -b2NhdGUgYnVmbGw2NCBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9idWY6IG5vdCBlbm91Z2ggbWVt -b3J5IHRvIGFsbG9jYXRlIGZsb3cgYnVmZmVycwoAAAAAAAAAbWVtX2luaXRfYnVmOiBub3QgZW5v -dWdoIG1lbW9yeSB0byBhbGxvY2F0ZSB0Y2JfY2FjaGUgKG9mZmVyZWQgJXUgdHJ5aW5nIHRvIHVz -ZSAldSBhdmFpbGFibGUgJXUpCgAAAAAAAAAAAAAAAAAAAG1lbV9pbml0OiBFREMgb3ZlcmNvbW1p -dHRlZCBieSAlZCBieXRlcwoAAAAAAAAAAG1lbV9pbml0OiBub3QgZW5vdWdoIG1lbW9yeSB0byBh -bGxvY2F0ZSBmbG93IHRhYmxlCgAAAAAAAAAAAAAAAABjeGNuaWNfZGV2aWNlX2luaXQ6IGN4Y25p -YyBbMHglMHhdLCBjeGNuaWMtPmZpbHRlciBbJTB4XQoAAAAAAAAAcG9mY29lIGluaXQgZG9uZQoA -AAAAAAAAAAAAAAAAAABwb3J0X2luaXRbJXVdIHB0eXBlIDB4JXgKAAAAAAAAAFBvcnRbJXVdOiBV -bmtub3duIFNHTUlJIHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAAFBvcnRbJXVdOiBVbmtub3duIEJU -X1hGSSBzdWItdHlwZSAlI3gKAAAAAAAAAAAAAHBvcnRfaW5pdFsldV06IHBvcnQgdHlwZSAweCV4 -IGlzIG5vdCBzdXBwb3J0ZWQKAG1wYXJ0aXRpb25faW5pdDogZGRwX2lzY3NpIDB4JXggaXNjc2lf -cHBvZF9lZHJhbV9mbGFnIDB4JXgKAAAAAABtcGFydGl0aW9uX2luaXQ6IG1vdmVkIHBtcnhfc3Rh -cnQgZnJvbSAweCUwOHggdG8gMHglMDh4IHRvIG1ha2Ugcm9vbSBmb3IgTEUgSEFTSCBhbmQvb3Ig -VFAgVENCcwoAAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0 -IGZyb20gMHglMDh4IHRvIDB4JTA4eCAoRURSQU0pCgAAAAAAAAAAAAAAAAAAAABFUSBwZm4gJXUg -dmZuICV1OiBkZXN0cm95aW5nIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMg -JXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAAAABBaCBoYS4uLmRvdWJsZSBmcmVlIG94X2lkIDB4 -JXgsIHJ4X2lkIDB4JXgKAAAAAABIb3N0IFBSTEkgUmVzcG9uc2UgdGltZWRvdXQ6IG94X2lkIDB4 -JXggcnhfaWQgMHgleAoAAAAAAAAAAAAAAAAARkNvRSBERFAgaW5pdDogZmNvZSBsbGltaXQgMHgl -eCwgZmNvZSB1bGltaXQgMHgleCBnYmwgbGxpbWl0IDB4JXggZ2JsIHVsaW1pdCAweCV4IHBjYnN6 -ICV4CgAAAAAARkNvRSBERFAgaW5pdDogZmNvZSBwcG9kIG9mZiAweCV4LCBmY29lIHN0IHBwb2Qg -YWRkciAweCV4IGZjb2UgbnVtIHBwb2RzIDB4JXgKAAB0bHNfa2V5X3N0YXJ0OjB4JXgsIHRsc19r -ZXlfc2l6ZTolZAoAAAAAAAAAAAAAAABtcGFydGl0aW9uX290aGVyczogc3RhcnQgMHglMDh4IHNp -emUgJXUgKHVudXNlZCAldSksIGhtYSAldQoAAAAAbXBhcnRpdGlvbl9vdGhlcnM6IF9tOiV4IF9z -aXplOiVsZCBkZXYudHAudGxzX2tleV9zaXplOiVsZCAKAAAAAG1wYXJ0aXRpb25fb3RoZXJzOiBz -dGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAAAAAAAABjbWRoX2J5ZVsldTol -dV06IFVucmVnaXN0ZXJpbmcgSE1BCgAAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IHZpYSBjb21t -YW5kCgAAAAAAAGh3X2kyY190cmFuc2FjdGlvbjogbmRhdGEgJXUgYWRkcl9vcCAweCV4IGRhdGFb -MF0gMHgleCBkaWZmICV1CgBod19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJfb3AgMHgl -eCByZWcgMHgleCBkaWZmICV1IGNvbnQgJXUgZmFpbGVkIHdpdGggZXJyICVkCgAAAAAAAAAAAABo -d19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJfb3AgMHgleCBkYXRhWzBdIDB4JXggZGlm -ZiAldSBkcG9zICV1IGNvbnQgJXUgZmFpbGVkIHdpdGggZXJyICVkCgAAAAAAAAAAAAAAAAAAaTJj -IHRyYW5zYWN0aW9uIGZhaWxlZCB0byBjb21wbGV0ZQoAAAAAAAAAAAAAAAAAY29uZmlndXJhdGlv -biBmaWxlIHBhcnNlcjogYWVjX3JldHJ5X2NudCB2YWx1ZSAlZCBpcyBub3Qgd2l0aGluIHRoZSBh -bGxvd2VkIGxpbWl0IG9mIDEgdG8gMjU0LkRpc2FibGluZyBpdC4KAAAAAGZlYyBvcHRpb24gaW4g -Y29uZmlnIGZpbGUgaXMgZGVwcmVjYXRlZAoAAAAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJz -ZXI6IGFuX2FlY190aW1lIHZhbHVlICVkIGlzIGJpZ2dlciB0aGFuIGFsbG93ZWQgbGltaXQuQ2hh -bmdpbmcgaXQgdG8gMTAwMDAgbXMuCgAAAAAAAAAAAABEZXByZWNhdGVkIGNvbmZpZyBvcHRpb24g -Zm91bmQgaW4gY29uZmlnIGZpbGUuIElnbm9yaW5nLi4KAAAAAAAAY29uZmlndXJhdGlvbiBmaWxl -IHBhcnNlcjogcGwgdGltZW91dCB2YWx1ZSBpcyB0b28gbGFyZ2UsIGNoYW5naW5nIGZyb20gJXUg -dG8gJXV1c2VjcwoAAAAAAAAAAAAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHk6IGhhcyAldSBlbnRy -aWVzIG9ubHksIHJlcXVpcmVzICV1IGVudHJpZXMKAAAAAAAAAAAAAAAAAAB0cF9iYWNrb2ZmOiBw -YXJzZWQgJWQgaW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAAAB0cF90aW1lcnZhbHM6IHBhcnNlZCAl -ZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMKAAB0cF90aW1lcnJlczogcGFyc2VkICVkIGluc3RlYWQg -b2YgJXUgZW50cmllcwoAAAB0cF9tdHVzIGhhcyAldSBlbnRyaWVzIG9ubHksIHJlcXVpcmVzICV1 -IGVudHJpZXMKAAAAAAAAAAAAAAAAAAAAdHBfbXR1c1sldV0gaXMgJXUgYnl0ZXMgd2hpY2ggaXMg -bm90IHN1cHBvcnRlZAoAaHdfY2ltX3RzY2hfdGlja19pbml0OiBUSUNLJWQsIHZhbHVlIDB4JXgs -IHJhdGUgJXUga2JwcwoAAAAAAAAAAGludmFsaWQgdGljayBncmFudWxhcml0eSAldSBrYnBzIG9y -IGdyYW51bGFyaXR5IHZhbCBtdXN0IGJlIDwgJXUsIGNoYW5nZWQgdG8gJXUKAAAAAAAAAAAAAAAA -AAAAAFRpY2sgZ3JhbnVsYXJpdGllcyAldWticHMKAAAAAAAAY29uZmlndXJhdGlvbiBmaWxlIHBh -cnNlcjogc2dlIHRpbWVyIHZhbHVlWyVkXSBpcyB0b28gbGFyZ2UsIGNoYW5naW5nIGZyb20gJXUg -dG8gJXV1c2VjcwoAAAAAAAAAZmlsdGVybWFzayAweCV4IGlzIG5vdCBlcXVhbC9zdWJzZXQgdG8v -b2YgZmlsdGVybW9kZQoAAAAAAAAAAAAAAGNvbmZpZ19obWFfb2Zmc2V0X3RhYmxlOiBFYWNoIHJl -Z2lvbiBuZWVkcyB0byBoYXZlIG11bHRpcGxlIG9mIDggcGFnZXMKAAAAAAAAAAAAY29uZmlnX2ht -YV9vZmZzZXRfdGFibGVbJXU6JXVdOiByZWdpb25bJXVdOiBwYWdlX3NpemUgJXUsIHRvdGFsIHNp -emUgJXUsIGJhc2UgMHgleAoAAAAAAAAAAAAAAAAAY29uZmlnX2htYV9vZmZzZXRfdGFibGU6IEhN -QSB0YWJsZSB3cml0ZSBmYWlsZWQgJWQKAAAAAAAAAAAAAAAAAGNtZGhfaG1hX2NtZDogSE1BIG5v -dCBlbmFibGVkIGluIHRoZSBjb25maWcgZmlsZSAoaG1hX3NpemU9WCBpbiBNQnMpCgAAAAAAAAAA -AAAAY21kaF9obWFfY21kOiBIb3N0IG1lbW9yeSBzaG91bGQgYmUgYXRsZWFzdCAxTUIKAAAAAAAA -AAAAAAAAAAAAAGNtZGhfaG1hX2NtZDogcGFnZSBzaXplIHNob3VsZCBiZSBwb3dlciBvZiAyCgAA -AGNtZGhfaG1hX2NtZDogSG9zdCBtZW1vcnkgYWxyZWFkeSByZWdpc3RlcmVkCgAAAGNtZGhfaG1h -X2NtZFsldToldV06IG1vZGUgJWQgSE1BIHNpemUgJXUKAAAAAAAAAGNtZGhfaG1hX2NtZDogT25s -eSAldSByZWdpb25zIHN1cHBvcnRlZAoAAAAAAAAAAGNtZGhfaG1hX2NtZDogT25seSAldSBwYWdl -cyBzdXBwb3J0ZWQKAAAAAAAAAAAAAGNsaXAgZW50cnkgZGVsZXRpb24gZmFpbGVkIGF0IHBvcyAl -dSwgcmV0ICVkCgAAAGh3X2xlX2NsaXBfaGFuZGxlcjogcmVtb3ZlZCBwb3M9JXUgKD1pZHggJXUp -CgAAAGh3X2xlX2NsaXBfaGFuZGxlcjogYWRkaW5nIHRvIHBvcz0ldSAoPWlkeCAldSkKAHBoeV9p -bml0OiBwb3J0ICV1IHdpdGggdGhlIHR5cGUgJXUgIGhhdmUgcmV0ICVkCgAAAAAAAAAAAAAAAAAA -AABod19tYWNfYWVjX2NvbXBsZXRlWyV1XSBvbiBsYW5lcyAlI3ggKHNpZ2RldCAlI3gpLCB0eF9s -YW5lcyAlI3gKAAAAAAAAAAAAAAAAAAAAAGh3X21hY19tdGlwX2VuYWJsZVsldV06IHB0eXBlIDB4 -JXgsIHNwZWVkIDB4JXgsIGZlYyAweCV4LCBkaXNhYmxlICVkCgAAAAAAAAAAAAAAY29uc29ydGl1 -bV9mZWNbJXVdOiBsb2NhbCAweCV4LCByZW1vdGUgMHgleCwgbmVnb3RpYXRlZCAweCV4CgAAAGh3 -X21hY19pbml0X3BvcnRbJXVdLCBwdHlwZSAweCV4LCBzcGVlZCAweCV4LCBsYW5lcyAweCV4LCBm -ZWMgMHgleAoAAAAAAAAAAAAAAAAAbW9kdWxlWyV1XTogcG9ydCBtb2R1bGUgaW5zZXJ0ZWQgYW5k -IHJlYWR5CgAAAAAAbW9kdWxlWyV1XTogcG9ydCBtb2R1bGUgcmVtb3ZlZAoAAAAAAAAAAAAAAAAA -AAAAbW9kdWxlWyV1XTogdW5rbm93biBtb2R1bGUgaWRlbnRpZmllciAweCUwMngKAAAAbW9kdWxl -WyV1XTogZXhjZXB0aW9uIGNhYmxlIGZlYyBhYmlsaXR5IG9mIHBvcnQgMHgleCwgb2YgY2FibGUg -MHgleAoAAAAAAAAAAAAAAABtb2R1bGVbJXVdOiB1bnNwZWNpZmllZCBleHRlbmRlZCBjb21wbGlh -bmNlIGNvZGUgMHglMDJ4CgAAAAAAAAAAbW9kdWxlWyV1XTogZmVjIGFiaWxpdHkgb2YgY2FibGUg -MHgleAoAAAAAAAAAAAAAbW9kdWxlWyV1XTogRGlzYWJsaW5nIGZlYyAoMHgleCkgYXMgaXQgaXMg -bm90IHN1cHBvcnRlZCBieSB0aGUgcG9ydAoAAAAAAAAAAAAAAABtb2R1bGVbJXVdOiBncGlvICV1 -IHZlbmRvciBpZCAlMDZ4LCBpZGVudGlmaWVyIDB4JTAyeCwgU0ZQMjgoYnl0ZSAzNi8xOTIpIDB4 -JTAyeCwgU0ZQKGJ5dGUgMy8xMzEpIDB4JTAyeCwgMUcgKGJ5dGUgNikgMHglMDJ4CgAAAG9wdGlj -YWwgbGVuZ3RoKGJ5dGUgMTUvMTQyKSAldSwgY29wcGVyIGNhYmxlKGJ5dGUgOC8xNDcpIDB4JTAy -eCwgbGVuZ3RoKGJ5dGUgMTgvMTQ2KSAldSwgbW9kdWxlX3R5cGUgMHglMDJ4CgAAAABwb3J0IGlu -aXRpYWxpemF0aW9uIGZhaWxlZAoAAAAAAG1vZHVsZVsldV06IGdwaW8gJXUgdmVuZG9yIGlkICUw -NngsIGlkZW50aWZpZXIgMHglMDJ4LCBTRlAyOChieXRlIDM2LzE5MikgMHglMDJ4LCBTRlAoYnl0 -ZSAzLzEzMSkgMHglMDJ4LCAxRyAoYnl0ZSA2KSAweCUwMngKAAAAb3B0aWNhbCBsZW5ndGgoYnl0 -ZSAxNS8xNDIpICV1LCBjb3BwZXIgY2FibGUoYnl0ZSA4LzE0NykgMHglMDJ4LCBsZW5ndGgoYnl0 -ZSAxOC8xNDYpICV1LCBtb2R1bGVfdHlwZSAweCUwMngKAAAAAGN4NF9jcl9tb2R1bGVfcnhfbG9z -WyV1XTogcnhfbG9zIGNoYW5nZWQgdG8gJXUKAElJLjEuYnggZHAxOFsldV0gcVsldV0gJSN4ICUj -eCAlI3ggJSN4IG1pbiAlI3ggbWF4ICUjeAoAAAAAAAAAAABJSS4xLmMtZC4gJSN4ICUjeCAlI3gg -JSN4IGFsbCAgJSN4CgAAAAAAAAAAAAAAAABJSS4yLmIgKCUjeCAtICUjeCArICUjeCkgJSAxMjgg -PSAlI3gKAAAAAAAAAAAAAABJSS4zIGluZXdfMWUgYWZ0ZXIgbGltaXQgY29tcHV0ZSBpdGVtcF8x -ZSAleCwgaW5ld18xZSAleAoAAAAAAAAASUkuMy4gaXRlbXBfMWUgJSN4IGluZXdfMWUgJSN4IGlu -ZXdfMWUgJWQKAAAAAAAASUkuNC4gc2V0XzFlICUjeAoAAAAAAAAAAAAAAAAAAABNQzogRXJyYXRh -MTkgRFFTIEFsaWduIGNhbGlicmF0aW9uIEZBSUxFRAoAAAAAAABNQzogRXJyYXRhMTkgUkRDTEsg -QWxpZ24gY2FsaWJyYXRpb24gRkFJTEVECgAAAAB0ZW1wMl8xZSsweDEwID0gJSN4CgAAAAAAAAAA -AAAAAElWLjEuIGRwMThbJXVdIHBoYXNlX3NlbCBiZWZvcmUgJSN4IGFmdGVyICUjeCwgZ2F0ZV9k -ZWxheSAlI3gKAABNQyBlcnJhdGExOSBpc3N1ZTE6IGRwMTggJXUgcXVhZCAldQoAAAAAAAAAAAAA -AABNQyBlcnJhdGExOSBpc3N1ZTI6IGRwMTggJXUgcXVhZCAldQoAAAAAAAAAAAAAAABNQyBlcnJh -dGExOSBpc3N1ZTM6IGRwMTggJXUgcXVhZCAldQoAAAAAAAAAAAAAAABNQyBlcnJhdGExOSBpc3N1 -ZTQ6IGRwMTggJXUgcXVhZCAldQoAAAAAAAAAAAAAAABNQyBjYWxpYnJhdGlvbiBGQUlMRUQ6IERG -SV9JTklUX0NPTVBMRVRFIG5vdCBiZWNvbWluZyAwCgAAAAAAAAAATUMgY2FsaWJyYXRpb24gRkFJ -TEVEOiBERklfSU5JVF9DT01QTEVURSBub3QgYmVjb21pbmcgMQoAAAAAAAAAAE1DIGNhbGlicmF0 -aW9uIEZBSUxFRDogSU5JVF9DQUxfQ09NUExFVEUgbm90IGJlY29taW5nIDEKAAAAAAAAAABNQyBj -YWxpYnJhdGlvbiBGQUlMRUQ6IFBDX0lOSVRfQ0FMX0VSUk9SIGlzIDB4JXgKAAAAAAAAAAAAAAAA -AAAARERSIGluaXQgY29tcGxldGUsIEJlZ2lubmluZyBjYWxpYnJhdGlvbgoAAAAAAAAATUM6IElu -aXRpYWwgQ2FsaWJyYXRpb24gRkFJTEVECgBNQzogSW5pdGlhbCBDYWxpYnJhdGlvbiBQQVNTRUQK -AE1DOiBFcnJhdGExOSBUYXNrIEZBSUxFRAoAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVk -OiBEaWRuJ3QgZ2V0IGFsbCBEUDE4cyBsb2NrZWQKAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9u -IGZhaWxlZDogRGlkbid0IGdldCBib3RoIEFEUnMgbG9ja2VkCgAAAAAAAAAAAABNQyBpbml0aWFs -aXphdGlvbiBmYWlsZWQ6IFNMRVdfRE9ORV9TVEFUVVMgbmV2ZXIgdG9nZ2xlZAAAAAAAAAAAcGZu -ICV1IHZmbiAldSBGU00gc3RhcnQKAAAAAAAAAABwZm4gJXUgdmZuICV1IEZTTSBjb21wbGV0ZQoA -AAAAAGZscl9wZnZmX2ZzbVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAAAHBmbiAl -dSBQQ0lFIFBNX0RBVEFfUE1DU1IgMHglMDh4IFNUQVQgMHglMDh4IERTVEFURSAweCUwOHgKAAAA -AABodyBwZiBiaXRtYXAgMHglMDJ4CgAAAAAAAAAAAAAAACZ2ZmlkX2JpdG1hcFswXSAweCUwOHg6 -MHglMDh4OjB4JTA4eDoweCUwOHgKAAAAACZ2ZmlkX2JpdG1hcFs0XSAweCUwOHg6MHglMDh4OjB4 -JTA4eDoweCUwOHgKAAAAAGFmdGVyIHZmaWQgZml4dXAgaHcgcGYgYml0bWFwIDB4JTAyeAoAAAAA -AAAAAAAAACZ2ZmlkX2JpdG1hcFswXSAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUwOHgKAAAAACZ2 -ZmlkX2JpdG1hcFs0XSAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUwOHgKAAAAAHRpbWVyIHF1ZXVl -ICV1IGxvc3QgYSB0aWNrISBuZXh0ICVwIGxhc3QgJXAgbnVtZSAldQoAAAAAAAAAAAAAAABmbHJf -dGltZXJfc3RhcnQ6IGZsb3djX2lkICV1ICVwIGJ1ZiAlcAoAAAAAAAAAAABNQUM6IFBMTHMgZGlk -bid0IGxvY2sKAAAAAAAAAAAAAGh3X21jX3ByZXBfbWM6IG1jICVkLCBtb2RlICVkLCBkZW5zaXR5 -ICVkLCB3aWR0aCAlZCwgc2l6ZSAweCV4LCBudW1fY2hpcHMgJWQgCgAAcGNpZTogcmVhZCBmcm9t -IHNlcmNmZyBwY2llX2lwX3VyX21heGZ1bmMgMHgleCBwZmJpdG1hcCAweCV4CgAAAHBjaWU6IG5w -ZiAldSAocGZiaXRtYXAgMHglMDJ4KSBudmYgJXUgKHBmIDAuLjcgMHglMDh4JTA4eCkgdmZzdHJp -ZGUgJXUKAAAAAAAAAAAAaHdfbWFjX3ByZXA6IGVycm9yLCByZXQgJWQKAAAAAABod19ncGlvX3By -ZXA6IGVycm9yLCByZXQgJWQKAAAAAGh3X21jX3NldF9jbGtfY2ZnOiBmb3JjZV9yZXNldCAlZCwg -Y3Vycl9zdGF0ZSAlZCwgc2l6ZSAldQoAAAAAAABNQyBDTEsgc2V0dGluZyBmYWlsZWQ6IFBMTF9N -X0xPQ0sgbmV2ZXIgdG9nZ2xlZAoAAAAAAAAAAAAAAAAAAAAAZmFpbGVkIHRvIGZpbmQgdGhlICVj -JWMgVlBEIHBhcmFtZXRlcgoAAAAAAAAAAAAAZmFpbGVkIHRvIHBhcnNlIHRoZSAlYyVjIFZQRCBw -YXJhbWV0ZXIKAAAAAAAAAAAAbWVtX3ByZXA6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRl -IHBhZ2UgdGFibGVzCgAAAAAAAAAAAAAAAG1lbV9wcmVwOiBlcnJvciwgcmV0ICVkCgAAAAAAAAAA -ZmFpbGVkIHRvIHN1Y2Nlc3NmdWxseSBmaW5kIENoZWxzaW8gVlBECgAAAAAAAAAAdnBkX3ByZXA6 -IGVycm9yLCByZXQgJWQKAAAAAAAAAABzZXJjZmdfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAGxv -ZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgldSBlbnRyaWVzKSBmd3JldiAweCUwOHgg -cGNpZV9mdyAweCUwOHgKAAAAAAAAUEkgZXJyb3IgZmxvd2lkX2xlbjE2IDB4JXgsIGFwcF90YWcg -MHgleCwgcmVmX3RhZyAweCV4LCBwaXNjICUwNHggJTA0eCAlMDR4ICUwNHgKAAAAAAAAAAAAAAAA -AAAAZmxvd2MgJXUgKFNHRSBlcWlkICV1KSAoRVRIQ1RSTCBxdWV1ZSkgZXhwZXJpZW5jZWQgYSBQ -Q0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1KQoAAAAAAAAA -AGZsb3djICV1IChTR0UgZXFpZCAldSkgZXhwZXJpZW5jZWQgYW4gdW5leHBlY3RlZCBQQ0kgRE1B -IFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1KQoAAAAAAAAAAAAAAABF -bmNvdW50ZXJlZCBTR0UgZmxvcCB3b3JrYXJvdW5kLCBJZ25vcmUgb3Bjb2RlCgBmbG93YyAldSBl -eHBlcmllbmNlZCBhbiB1bmV4cGVjdGVkIFBDSSBETUEgUkVBRCBlcnJvciAoaW5ib3VuZCBxdWV1 -ZSAldSkKAAAAAAAAAGdhdGhlcl90YXNrc19mb3JfdG1mOiBJbnZhbGlkIHR5cGUgWzB4JXhdLCBi -YWlsaW5nIG91dC4KAAAAAAAAAABmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZp -bHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAA -AABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAA -AAAAAAAAAAAARkNvRSBGQ0IgbGlua2Rvd246IGlvX3JlcSAweCV4JXggaXFpZCAweCV4IGZsb3dp -ZCAweCV4IG9wIDB4JXgKAGZjb2Ugbm90aWZ5IDogVXBkYXRlIG5ldyBEQ0JYIHZhbHVlcyBWSSBz -dGF0ZSAweCV4IHByaSAweCV4IHNjaGVkY2wgMHgleCBkY2J4X2RvbmUgMHgleAoAAAAAAAAAAGZj -b2Ugbm90aWZ5IDogRkNGIGZsb3dpZCAweCV4LCB1bHBjaCAweCV4IAoAAAAAAGZjb2Ugbm90aWZ5 -IDogRkNvRSBMSU5LVVA6IHBvcnQgMHgleCwgZXZlbnQgMHgleAoAAAAAAAAAAAAAAAAAAABmY29l -IG5vdGlmeSA6IEZDb0UgTElOS0RPV046IHBvcnQgMHgleCwgZXZlbnQgMHgleAoAAAAAAAAAAAAA -AAAAZmNvZSBub3RpZnkgOiBEQ0JYIDogcG9ydCAweCV4LCBwcmlvcml0eSAweCV4IHVscHR4Y2gg -MHgleCBjbGFzcyAweCV4CgAAAAAAAAAAAABSREVWIG1zZyBmbG93YzoleCBzdGF0ZSAweCV4IGV2 -ZW50IDB4JXgKAAAAAAAAAABjYW5jZWwgZmNiOiV4IHNjYjoleCBzdGF0ZToleAoAAEZDb0UgRkNG -IHRpbWVyOiBmbG93YyBzdGF0ZSAweCV4LCBwb3J0IDB4JXggLGZjZiAweCV4LCBmbG93Y19pZCAw -eCV4CgAAAAAAAAAAAAAAaHcgcmVnaXN0ZXIgb3BlcmF0aW9uIG5vdCBjb21wbGV0aW5nLCByZWcg -MHglMDh4IG1hc2sgMHglMDh4IHZhbHVlIDB4JTA4eCAocmVnIDB4JTA4eCkKAAAAAAAAAAAATURJ -TyBDTDQ1OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAATURJTzogZmFpbGVk -IHRvIHdyaXRlCgAAAAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAgTU1EIGFkZHIK -AAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gcmVhZAoAAAAAAAAAAAAAAG1paV9hZHZfZmNbJXVd -OiByY2FwcyAweCV4CgAAAAAAbWlpX2Fkdl9zcGVlZFsldV06IHJjYXBzIDB4JXgKAABjcGxfdHhf -cGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGZsb3djX2lkIFsldV0gbDJkZXZfZmMgWzB4JXhdIGFs -cmVhZHkgcmVjZWl2ZWQgUkEsIG5vdCBzZW5kaW5nIFJTCgAAAAAAAAAAAAAAAAAAZmxvd2NpZCBb -JXVdIGwyZGV2X2ZjIFsweCV4XSBObyBJUHY2IHJvdXRlcgoAAAAAY2huZXQgWyVkLyVkXSBmcmVl -IGwydCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKAAAAAAAAAAAAAAAAAAAAAGNobmV0IFslZC8l -ZF0gcHV0IGwydCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKAGNobmV0IFslZC8lZF0gZ2V0IGwy -dCBlbnRyeTogaWR4ICV1LCByZWZjbnQgJXUKAGNobmV0IFslZC8lZF0gbDJ0IGFsbG9jIGwydGVu -dCAweCV4LCBpZHggJXUsIHJlZmNudCAldQoAAAAAAAAAAABvdXQgb2YgYXRpZHM6IG1heCBhdGlk -czogJWQKAAAAAHNldHVwX2RkcDogaXN0YXNrOjB4JXgsIG5wcG9kICV1LCBhbGxvYyBmYWlsZWQg -JWQKAAAAAAAAAAAAAAAAAABwZW5kaW5nX2Nzb2NrczogY3NvY2s6ICVwIHRndF9mYzogJXAgaWR4 -ICV1IHN0YXRlIDB4JXgKAAAAAAAAAAAAZmxvd19pZCBbMHgleF0gaGlzdG9yeSAweCUyeCAweCUy -eCAweCUyeCAweCUyeCAweCUyeAoAAAAAAAAAAAAAAGZvaXNjc2lfdmFsaWRhdGVfbG9naW5fc3Rh -Z2U6IC0gMQoAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogbWIgWzB4JXhdLCBkZWZlcnJlZCwg -c3RhdGUgWzB4JXhdLCBwb3J0IFsweCV4XQoAAABsMmRldl92aV9mc206IHZpaWQgWzB4JXhdIHBv -cnQgWzB4JXhdLCBtYWMtaWQgWyUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XS4gCgAAAAAA -AAAAAAAAAAAAAABsMmRldl92aV9mc206IHNnZV9lcWlkIFsweCV4XSwgc2dlX2lxaWQgWzB4JXhd -LCBzZ2VfZXFjciBbMHgleF0sIHJzc19zeiBbMHgleF0KAGwyZGV2X3ZpX2ZzbTogbDJkZXZfZmMt -PmZsb3djX25ldF9sMmRldl9tdHUgWyV1XSwgbWJfc2NyYXRjaCBbMHgleF0sIHBvcnQgWzB4JXhd -CgAAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogdmlpZCBbJWRdLCB2aV9mYy0+Zmxvd2Nfdmlf -ZmxhZ3MgWzB4JXhdCgAAAAAAAAAAAABsMmRldl92aV9mc206IHBmbiBbMHgleF0sIHZmbiBbMHgl -eF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGxwb3J0IFsweCV4XSwgdmlpZCBbMHgleF0s -IGZsYWdzIFsweCV4XQoAAAAAAAAAbDJkZXZfdmlfZnNtOiBFcnJvciBmcmVlaW5nIFZJLCByYyBb -MHgleF0KAAAAAAAAbDJkZXZfdmlfZnNtOiBwaWQgWzB4JXhdLCB2aWlkIFsweCV4XSwgbWJfbG9j -IFsweCV4XSwgbWJfb3JpZ1sweCV4XSwgbDJkZXZfZmxhZ3MgWzB4JXhdLCByYyBbMHgleF0KAAAA -AAAAAAAAAAAAAGZvaXNjc2lfZmluZF90YXNrOiB0YXNrIG5vdCBmb3VuZCB0Y2JfZmMgaWQgMHgl -eCBpdHQgMHgleAoAAAAAAABXQVRDSERPRzogTm8gdGVtcGVyYXR1cmUgc2Vuc29yIGF2YWlsYWJs -ZS4KAAAAAABXQVRDSERPRzogQWN0aXZhdGluZwoAAAAAAAAAAAAAAFdBVENIRE9HIC0gRW5hYmxl -IGFjdGlvbiAldSB0aW1lICV1CgAAAAAAAAAAAAAAAFdBVENIRE9HIC0gRGlzYWJsZSBhY3Rpb24g -JXUKAAAAV0FUQ0hET0c6IERlLWFjdGl2YXRpbmcKAAAAAAAAAABwb3J0WyV1XSBzZXQgUEFVU0Ug -UEFSQU1TOiBwcHBlbiAldSB0eHBlICUjeCByeHBlICUjeAoAAAAAAAAAAAAAbXBzX2xpbmtfdXBb -JXVdIGFjYXBzICUjeCAoODAyLjMgJSN4KSArIGxwYWNhcHMgJSN4ID0+ICUjeAoAAAAAAEludmFs -aWQgcmF0ZSAldSBrYnBzLCBvdXQgb2YgY29uZmlndXJlZCBncmFudWxhcml0eSByYW5nZXMKAAAA -AABEQ0JYOiBzdW0gb2YgcmF0ZXMgb24gYWxsIGNsYXNzZXMgbXVzdCBiZSAxMDAgKGFjdHVhbDog -JXUpCgAAAAAAcmlfd3JfaW5pdFsldV06IG1zcyAldSBpcyBub3QgOC1ieXRlIGFsaWduZWQKAAAA -Y29yZV9wcm9ncmFtX3RjYjogdGlkICUjeCB0X3N0YXRlICUjeCByY3ZfYWR2IDB4JTA4eCByY3Zf -c2NhbGUgJSN4IHR4X21heCAlI3ggcmN2X254dCAlI3ggYXRpZCAlI3gKAAAAAAAAAAAAAAAAAAlv -cHQwICUjeCV4IG9wdDIgJSN4IGlwdjYgJSN4IGZsYWdzX3RpbWVyIDB4JTA4eAoAAAAAAAAAAAAA -AAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0 -eCBmcCAweCUwNHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmlsdGVyIDB4JTA4eCBl -eGlzdHMgQCBMRSBpbmRleCAldQoAAAAAAAAAAAAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNv -bm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCBwaXAg -MHglMDh4IGZpbHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAG9mbGRfY29u -bmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBs -aXAgMHglMDh4JTA4eCBwaXAgMHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4CgAAAABvZmxkX2Nvbm5l -Y3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlw -IDB4JTA4eCBwaXAgMHglMDh4IGZpbHRlciAweCUwOHgKAAAAAAAAAAAAAAAARVEgKGZyZWVzbGlz -dCkgcGZuICV1IHZmbiAldTogZmxpZF9hICV1IGZldGNoIGJ1cnN0IG1heFsldV0gJXUgKCV1IGJ5 -dGVzKSA+IDI4CgBJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgdG9vIGxhcmdlIChtYXgg -JXUpCgAAAAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWlkICV1IG5vdCBhbGxv -Y2F0ZWQKAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSB0b28gbGFyZ2UgKG1heCAl -dSkKAAAAAAAAAAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwwaWQgJXUgbm90IGFsbG9j -YXRlZAoAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUp -CgAAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IG5vdCBhbGxvY2F0 -ZWQKAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBub3QgZmww -aWQgJXUKAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBpcyB2YWxpZCBidXQg -aGVhZGVyIHNwbGl0IGZlYXR1cmUgaXMgbm90IGVuYWJsZWQKAAAAAAAAAAAAAAAAAAAARVEgcGZu -ICV1IHZmbiAldTogY3JlYXRpbmcgRVRIIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1f -Ynl0ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAARVEgcGZuICV1IHZmbiAldTogY3JlYXRp -bmcgQ1RSTCBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFn -cyAweCUwOHgKAAAAAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSB0b28gbGFyZ2UgKG1heCAl -dSkKAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAAAAAAAAZGNi -eF9wb3B1bGF0ZV9jdHJsIGNvZGUgaW5jb21wbGV0ZQoAAAAAAAAAAAAAAAAAdmlfdGNhbV9yYXcg -aWR4ICV1IG1hYyAweCUwNHggJTA4eAoAAAAAAAAAAAAAAAAAcG9ydF9ibGlua19sZWRfcmVzdG9y -ZQoAAAAAAAAAAABwb3J0X2JsaW5rOiBibGlua2R1cj0weCV4IGJsaW5rX3JlZmNudAoAAAAAAAAA -AABwb3J0X2JsaW5rOiAJYmxpbmtfcmVmY250PTB4JXgKAHBvcnRfYmxpbms6IAlibGlua19yZWZj -bnQ9MHgleAoAbWlpX2FucmVzdGFydFsldV06IGFjYXBzIDB4JXgKAABtaXNzaW5nIHBvcnQgY2Fw -czMyIHRvIGNhcHMxNiB0cmFuc2xhdGlvbiBmb3IgJSNseAoAAAAAAAAAAAAAAAAAcG9ydF9jbWRf -aGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAbWlzc2luZyBwb3J0IGNhcHMx -NiB0byBjYXBzMzIgdHJhbnNsYXRpb24gZm9yICUjeAoAAAAAAAAAAAAAAAAAAGJhZCBGbG93QyAl -ZCBvbiBlc3RhYmxpc2hlZCBjb25uZWN0aW9uCgAAAAAAAAAAAGV0aF9mbG93Y19oYW5kbGVyWzB4 -JXhdOiBmbGFncyAweCUwOHggbnVtX2J5dGVzICV1IHNjaGVkY2wgMHgleCAtPiAweCV4CgAAAAAA -AAAAdGFza19hbGxvYzogT3V0IG9mIHRhc2tzLgoAAAAAAABzY3NpX3JlYWQ6IHBwb2QgYWxsb2Mg -ZmFpbGVkLCBucHBvZCAldQoAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfTElO -S1VQCgAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfVVBEQVRFX0RDQlhf -VExWCgAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfUEVFUl9OT1RfQURWRVJUSVNFX0RD -QlgKAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1VQREFURV9PUEVSX1ZF -UlNJT04KAAAAAAAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9QUk9DRVNT -X1BFRVJfVExWCgAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9BQ0tfUEVFUgoAAAAAAAAA -AAAAAGRjYnhfaWVlZV92YWxpZGF0ZVsldV0gZXJyb3IgKG91aSAlI3ggc3VidHlwZSAlI3ggbGVu -ICUjeCkKAAAAAABkY2J4X2NlZV92YWxpZGF0ZVsldV0gZXJyb3IKAAAAAERIQ1B2NiBSRVBMWSBy -ZWNlaXZlZCBzdGF0ZSAldQoAZGhjcCByZXBseSByZWNlaXZlZCBpbiB3cm9uZyBzdGF0ZSAlZAoA -AAAAAAAAAAAAdW5rbm93biBzZXJ2ZXJpZC4gSWdub3JpbmcgZGhjcCByZXBseQoAAAAAAAAAAAAA -cmVjZWl2ZWQgcmVwbHkgd2l0aCBkaWZmZXJlbnQgYWRkcmVzcy4gaWdub3JpbmcgZGhjcCByZXBs -eQoAAAAAAERIQ1B2NiBBRFZFUlRJU0UgcmVjZWl2ZWQKAAAAAAAAZGhjcCBhZHZlcnRpc2UgcmVj -ZWl2ZWQgaW4gd3Jvbmcgc3RhdGUgJWQKAAAAAAAAaWdub3JpbmcgcmN2ZCBhZHZlcnRpc2UgcHJl -ZmVyZW5jZSAldQoAAAAAAAAAAAAAU3RhcnQgREhDUHY2IHRvIGdldCB0aGUgaXAgYWRkcmVzcwoA -AAAAAAAAAAAAAAAATm8gZGhjcCwgZGhjcCBzdGF0ZSAlZCwgYWRkciBzdGF0ZSAlZAoAAAAAAAAA -AAAAJTAyeCAlMDJ4ICUwMnggJTAyeCAlMDJ4ICUwMngKAAB2bjJ2bjogcG9ydCAweCV4IGRpZDow -eCV4JXgleCBVUAoAAAAAAAAAAAAAAAAAAAB2bjJ2bjogcG9ydCAweCV4IGRpZDoweCV4JXgleCBE -T1dOCgAAAAAAAAAAAAAAAABmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRl -ciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABj -b21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAA -AAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSB2bGFuICV4IHZpaWQgJXggcG9ydCAleCBtcHNfaWR4 -ICV4CgAAAAAAAAAAAEFCVFMgQUNDIGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19pZCAweCV4IG94 -X2lkIDB4JXggcnhfaWQgMHgleCBpcWlkIDB4JXgKAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4 -LCBjb21tYW5kIGZhaWxlZCByZXRyaWVzIDB4JXgKAAAAAAAAAAAAAAAAAEdvdCBDT05OX0VYSVNU -IGZvciB4aWQ6MHgleCwgdGFnOjB4JXgsIHJldHJ5aW5nLgoAAAAAAAAAAAAAAAAAAABDYW5ub3Qg -Z2V0IGNoYW5uZWwgcmF0ZSAldSB3aXRoIGNvbmZpZ3VyZWQgZ3JhbnVsYXJpdGllcy4gQ2hlY2sg -Y29uZmlnIGZpbGUKAAAAAHBrdHNjaGVkX2NoX3JsWyV1XTogY2hhbm5lbCBybCBub3QgYXZhaWxh -YmxlIGluIGNvbmp1bmN0aW9uIHdpdGggZmxvdyBzaGFwaW5nCgAAcGt0c2NoZWRfY2hfcmxbJXVd -OiByYXRlICV1IG1heCAldQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfd3JyWyV1OiV1XTogd2Vp -Z2h0ICV1CgAAAAAAAAAAAAAAAAAAZXFfcGFyYW1zWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFk -ICV1IHBmICV1IGVxaWRfYXBpICV1IHJldCAlZAoAAAAAAAAAAAAAAAAAAABod19tYV9hZGRyX3Rv -X21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUwOHggaXMgbm90IG1hcHBlZAoAAAAAaHdfbWFf -YWRkcl90b19tZW1fdHlwZV9vZmY6IE1BIGFkZHJlc3MgMHglMDh4IG1hcHMgdG8gdHlwZSAldSBv -ZmZzZXQgMHgleAoAAAAAAABtZW1fbWFsbG9jX3RlbXA6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBi -eXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAcmluZyBiYWNrYm9uZSwgZW5hYmxlICVkLCBtcHMuZmxh -Z3MgMHgleAoAAAAAAAAAcmluZyBiYWNrYm9uZSBubyBjaGFuZ2UgaW4gY29uZmlndXJhdGlvbgoA -AAAAAAAAcmluZyBiYWNrYm9uZSBjb25maWd1cmF0aW9uIGVycm9yLCBUQ0FNIG5vdCBlbXB0eS4g -YXZhaWxhYmxlICVkLCBzaXplICVkCgAAAAAAAABtZW1fbWFsbG9jOiBmYWlsZWQgdG8gYWxsb2Nh -dGUgJXUgYnl0ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogcmVx -dWVzdGVkICV1IHRjYW0gZW50cmllcyBidXQgb25seSAldSBhdmFpbGFibGUgKG5maWx0ZXIgJXUg -bnNlcnZlciAldSBuaHBmaWx0ZXIgJXUKAAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IHRjYW0g -cmVnaW9ucyBtdXN0IGhhdmUgbXVsdGlwbGUgb2YgNjQgZW50cmllcywgbmZpbHRlciAldSBuaHBm -aWx0ZXIgJXUgbnNlcnZlciAldQoAAAAAAAAAAAAAAABod190cF90Y3BfdHVuaW5nczogdHVuaW5n -IGZvciBjbHVzdGVyIGVudmlyb25tZW50CgAAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6 -IHR1bmluZyBmb3IgTEFOIGVudmlyb25tZW50CgAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBm -b3IgV0FOIGVudmlyb25tZW50CgAAaHdfdHBfdGNwX3R1bmluZ3M6IG1hbnVhbCB0dW5pbmcKAAAA -AAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6IG1lbWNweVggc3RhcnQKAAAAAAAAAAAA -AAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6IGRzdCAweCUwOCBvZmZzZXQgMHglMDh4IHNpemUgJXUs -IHdpZHRoIG9mICV1IGlzIG5vdCBzdXBwb3J0ZWQKAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9t -ZW1jcHk6IG1lbWNweVggZW5kCgAAAAAAAAAAAAAAAAAAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNl -ciBlbmNvdW50ZXJlZCBlcnJvciBAIGxpbmUgJXU6CgAAAAAAAAAAAGZjb2UgeGNoZyBtZ3IgaW5p -dDogTnVtYmVyIG9mIGV4Y2hhbmdlcyBmb3IgRkNvRSBpcyAleAoAAAAAAAAAAABmY29lX2wydF9p -bml0OiBObyB1bHB0eCBjcmVkaXQgY2g6WyV1XQoAAAAAAAAAAABmY29lX2wydF9pbml0OiBjaDpb -JXVdIGwydF9pZHggWyV1XQoAAAAAAAAAAAAAAABubyBsMnQgZW50cmllcyBjb25maWd1cmVkOyBm -b3JjaW5nICV1IGVudHJpZXMsIHN0YXJ0aW5nIGF0ICV1CgAAZGNieF9pZWVlX2NvbnN0cnVjdFsl -dV0gZXRzICV1IHBmYyAldSBhcHAgJXUKAAAAZGNieF90aW1lb3V0WyV1XQoAAAAAAAAAAAAAAAAA -AABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fSUVFRQoAAAAAAAAA -AAAAAAAAAAAAZGNieF9ydW5fdmVyc2lvbl9zbVsldV0gRENCWF9WRVJfU1RBVEVfUlVOX0NFRQoA -ZGNieF9ydW5fdmVyc2lvbl9zbVsldV0gRENCWF9WRVJfU1RBVEVfUlVOX05PTkUKAAAAAAAAAAAA -AAAAAAAAAE1BQyBmYWlsZWQgdG8gcmVzeW5jIHR4CgAAAAAAAAAAcG9ydFsldV0gbGluayB1cCAo -JXUpIChzcGVlZCAlI3ggYWNhcHMgJSN4IGxwY2FwcyAlI3gpCgAAAAAAAAAAAHBvcnRfaHNzX3Np -Z2RldFsldV06IGhzc19zaWdkZXQgY2hhbmdlZCB0byAweCV4CgAAAAAAAAAAAAAAAAAAAABwb3J0 -WyV1XSBpbml0aWFsaXppbmcgS1IKAAAAAAAAAENhbGN1bGF0aW9uIG91dCBvZiBib3VuZHMgZnVy -aW5nIGluaXQ6ICUjeCAlI3ggJSN4CgAAAAAAAAAAAAAAAABsZSBjb25maWd1cmF0aW9uOiBoYXNo -IG1vZGUgcmVxdWlyZXMgYXQgbGVhc3QgMTYgZW50cmllcywgbmhhc2ggJXUKAAAAAAAAAAAAAAAA -AGxlIGNvbmZpZ3VyYXRpb246IGhhc2ggc2l6ZSAldSBtdXN0IGJlIG11bHRpcGxlIG9mICV1LCBu -aGFzaCAldQoAAAAAAAAAAAAAAAAAAAAAQWRkaW5nIG1hdGNoLWFsbCBjbGlwIGVudHJ5IEAgbG9j -IDB4JXgvJWQKAAAAAAAAaHdfc2dlX21hbWVtX2luaXQ6IGVuY291bnRlcmVkIGVycm9yICVkCgAA -AAAAAAAAX2h3X3RwX3BnbW5ndDogdHhfcGFnZV9tYXggJXUgcnhfcGFnZV9tYXggJXUgcHN0cnVj -dHMgJXUgc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX290aGVyc190b3RhbDogbWVt -ICV1LCBkZHAgJXUgZGRwX2lzY3NpICV1IHN0YWcgJXUgcGJsICV1IHJxICV1IHJxdWRwICV1IC0+ -ICV1CgAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tY1g6IG5iYW5rc19wbXR4ICV1ICgldU1CKSBu -YmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1 -ICgldU1CKQoAX21wYXJ0aXRpb25fYmFua3NfbWMxOiBuYmFua3NfcG10eCAldSAoJXVNQikgbmJh -bmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAAAAAAAAAX21wYXJ0aXRp -b25fYmFua3NfbWMwOiBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVN -QikKAAAAAAAAAAAAAABtZW1fbWFsbG9jX2ludGVybmFsOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUg -Ynl0ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1XTogYmlz -dF9jbWRbMHglMDh4XSBhZGRyIDB4JXggbGVuIDB4JXgKAAAAAAAAAAAAAABod19lZGNfYmlzdFsl -dV06IGRvbmUsIGVuY291bnRlcmVkICV1IGVycm9ycyBvbiBmaXJzdCBhbmQgJXUgZXJyb3JzIG9u -IHNlY29uZCBhdHRlbXB0ICgldWdicHMpCgBtZW1faW5pdF9jYWNoZXM6IGNhY2hlX3NpemUgJXUg -Zmxvd2NfYnVmX3RjYl9jYWNoZV9zaXplICV1IGJ1ZmxsNjRfY2FjaGVfc2l6ZSAldQoAAAAAAAAA -AAAAAAAAAABtcGFydGl0aW9uX3BtdHg6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABt -cGFydGl0aW9uX3Btcng6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9u -X2JhbmtzX21jWDogZGRwX2lzY3NpIDB4JXggaXNjc2lfcHBvZF9lZHJhbV9mbGFnIDB4JXgKAAAA -AAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fYmFua3NfbWMwOiBkZHBfaXNjc2kgMHgleCBpc2NzaV9w -cG9kX2VkcmFtX2ZsYWcgMHgleAoAAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9lZGMgKG5vIGV4 -dG1lbSk6IG0gMHglMDh4IHNpemUgJXUKAAAAbXBhcnRpdGlvbl9lZGNfZXN0aW1hdGU6IGh3IG1v -ZHVsZXMgcmVxdWlyZSAlZCBieXRlcyBpbiBFREMKAAAAAFRlbXBlcmF0dXJlL1ZvbHRhZ2UgU2Vu -c29yOiBDb3JlIGNsb2NrICV1ID4gJXU7IGNhcHBpbmcgdG8gc3RheSBpbiBjb21wbGlhbmNlIHdp -dGggaGFyZHdhcmUuCgAAAHNldHRpbmcgdXAgcmluZyBiYWNrYm9uZQoAAAAAAAAAcmluZyBiYWNr -Ym9uZSBjb25maWcgZXJyb3IsIFRDQU0gbm90IGVtcHR5LiBhdmFpbGFibGUgJWQsIHNpemUgJWQK -AAAAAAAAAAAAAAAAAABmb2lzY3NpX2NvcmVfYnllOiBhY3RpdmUgc2Vzc19jbnQgJWQKAAAAAAAA -AAAAAABod19tYWNfYWVjX2NvbXBsZXRlWyV1XSBvbiBsYW5lcyAlI3ggKHNpZ2RldCAlI3gpLCB0 -eF9sYW5lcyAlI3gKAAAAAAAAAAAAAAAAAAAAAGFlY19mc21bJXVdIDogc3RhdGUgU1RBUlQgKHNp -Z2RldCAlI3gpCgAAAAAAAAAAAGFlY19mc21bJXVdIDogVHJhbnNpdGlvbmluZyB0byBUUkFJTklO -R19MT0NBTAoAAGFlY19mc21bJXVdIDogVHJhbnNpdGlvbmluZyB0byBDT0VGX1NUQVRVU19VUEFE -VEUKAAAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHRyYW5zaXRpb25pbmcgdG8gVFJBSU5JTkcK -AAAAAAAAAABhZWNfZnNtWyV1XSA6IFRSQUlOSU5HX0NPTVBMRVRFCgAAAAAAAAAAAAAAAAAAAABh -ZWNfZnNtWyV1XSA6IExvY2FsIGZhdWx0IHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4 -JXggOiAweCV4CgAAAAAAAAAAAAAAAGFlY19mc21bJXVdIDogUmVtb3RlIGZhdWx0IHdoaWxlIHdh -aXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4JXgKAABhZWNfZnNtWyV1XSA6IFJlbW90ZSBmYXVsdCBj -bGVhcmVkIHdoaWxlIHdhaXRpbmcgZm9yIGxpbmsgc3RhdHVzIDB4JXgKAAAAAAAAAAAAAGFlY19m -c21bJXVdIDogRE9ORQoAAAAAAAAAAAAAAAAAYWVjX2ZzbVsldV0gdGltZWQgb3V0IHRyYWluaW5n -IEZTTV9TVEFURV8wIDB4JXgsIF8xIDB4JXggXzIgMHgleCBfMyAweCV4LCBMaW5rIFN0YXR1cyAw -eCV4CgAAAAAAYmVhbl9mc21bJXVdIDogc3RhdGUgU1RBUlQgKGNvdW50ID0gJXUpCgAAAAAAAAAA -YmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9TSUdERVQKAAAAAAAAYmVhbl9mc21b -JXVdIDogZW50ZXJpbmcgc3RhdGUgQkFTRVBfSEFORExFCgAAAAAAYmVhbl9mc21bJXVdIDogZW50 -ZXJpbmcgc3RhdGUgTlhQX0hBTkRMRQoAAAAAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3Rh -dGUgV0FJVF9DT01QTEVURQoAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgRVhUX05Y -UF9IQU5ETEUKAAAAYmVhbl9mc21bJXVdIDogUEVFUiBkb2Vzbid0IHN1cHBvcnQgTlAuIEVudGVy -aW5nIHN0YXRlIFdBSVRfQ09NUExFVEUKAAAAAAAAAAAAAABiZWFuX2ZzbVsldV0gOiBFWFRfTlhQ -X0hBTkRMRSBJbnZhbGlkIG5leHQgcGFnZQoAAAAAAAAAAAAAAAAAAAAAYmVhbl9mc21bJXVdIDog -Q29uc29ydGl1bSBpbmNvbXBhdGlibGUgc3BlZWQuIGFiaWxpdHkgbG9jYWwgMHgleCwgcmVtb3Rl -IDB4JXgKAABiZWFuX2ZzbVsldV0gOiBlbnRlcmluZyBzdGF0ZSBFWFRfTU9SRV9OWFBfSEFORExF -CgAAAAAAAAAAAAAAAAAAYmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgV0FJVF9GT1JfTlVM -TF9QQUdFCgAAAAAAAAAAAAAAAAAAAGJlYW5fZnNtWyV1XSA6IGVudGVyaW5nIHN0YXRlIFdBSVRf -Q09NUExFVEUKAAAAAGJlYW5fZnNtWyV1XSA6IElFRUUgaW5jb21wYXRpYmxlIHNwZWVkLiBhYmls -aXR5IGxvY2FsIDB4JXgsIHJlbW90ZSAweCV4CgAAAAAAAAAAYmVhbl9mc21bJXVdIDogSUVFRSBz -cGVlZCAweCV4LCBGRUMgcmVtb3RlIDB4JXgsIG5lZ290aWF0ZWQgMHgleAoAAAAAAAAAAAAAAAAA -AABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBET05FCgAAAAAAAGJlYW5fZnNtWyV1XSA6IEZFQyBsb2Nh -bCAweCV4LCBuZWdvdGlhdGVkIDB4JXgKAGJlYW5fZnNtWyV1XSA6IHN0YXRlIFJFU1RBUlQxCgAA -YmVhbl9mc21bJXVdIDogc3RhdGUgUkVTVEFSVDIKAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBSRVNU -QVJUMwoAAGJlYW5fZnNtWyV1XSBUSU1FT1VUOyBzdGF0ZSAldSBldGhfc3RhdHVzICUjeCBiZWFu -X3N0YXR1cyAlI3ggUENTX0RFQlVHMF9STyAlI3ggaHNzIHNpZ2RldCAlI3ggcmV0cnlfY250ICV1 -CgAAAABod19tYWNfbGlua19zdGF0dXNbJXVdIGludF9jYXVzZSAweCV4LCBsaW5rX3N0YXR1cyAw -eCV4CgAAAAAAAAAAcG9ydCAldSBjaGFuZ2luZyBzcGVlZCB0byAxRwoAAABwb3J0ICV1IG5lZ290 -aWF0ZWQgdW5zdXBwb3J0ZWQgc3BlZWQgJSN4CgAAAAAAAABiZWFuL2FlYyBjb21wbGV0ZSAocmV0 -cnk6ICV1KQoAAHBvcnRbJXVdIHJlc2V0dGluZyBLUgoAAAAAAAAAAAAAcG9ydCAldSBuZWdvdGlh -dGVkIHVuc3VwcG9ydGVkIHNwZWVkCgAAAAAAAAAAAAAAcG9ydFsldV0gbmVnb3RpYXRlZCBwdHlw -ZSAweCV4LCBzcGVlZCAweCV4LCBsYW5lcyAweCV4OjB4JXgsIGZlYyAweCV4CgAAAAAAAAAAAABi -ZWFuL2FlYyBjb21wbGV0ZSAocmV0cnk6ICV1KQoAAE1DOiBHUE8gMHgleCwgUkxPIDB4JXgKAAAA -AAAAAAAAcGZuICV1IHZmbiAldSBjb21wbGV0ZSBpbW1lZGlhdGUKAAAAAAAAAAAAAAAAAAAAYmFk -IG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXggPiBMQVNUQzJFIDB4 -JXgKAG1haWxib3ggY21kIG5vdCB5ZXQgc3VwcG9ydGVkOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bj -b2RlIDB4JXgKAABiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHgl -eCBpcyB2YWxpZCBwb3N0IGRldmljZSBpbml0IG9ubHkKAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4 -JXggdmZuIDB4JXg7IG9wY29kZSAweCUwMnggcmFtYXNrIDB4JXggY21kIHJhbWFzayAweCV4CgAA -YmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JTAyeCBsZW4xNiAw -eCV4IHZlcnN1cyBleHBlY3RlZCBsZW4xNiAweCV4CgAAAAAAAAAAaW5zdWZmaWNpZW50IGNhcHMg -dG8gcHJvY2VzcyBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IHJfY2FwcyAweCV4IHd4 -X2NhcHMgMHgleCByZXF1aXJlZCByX2NhcHMgMHgleCB3X2NhcHMgMHgleAoAAAAAAAAAAABpbnN1 -ZmZpY2llbnQgY2FwcyB0byBwcm9jZXNzIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsg -cl9jYXBzIDB4JXggd3hfY2FwcyAweCV4IHJlcXVpcmVkIHJfY2FwcyAweCV4IHdfY2FwcyAweCV4 -CgAAAAAAAAAAAE1DOiBUYWtpbmcgUEhZIG91dCBvZiByZXNldCAoRlBHQSkuCgAAAAAAAAAAAAAA -AGRvd25sb2FkX3NyYW06IGVycm9yLCByZXQgJWQKAAAAZG93bmxvYWRfdGNhbTogZXJyb3IsIHJl -dCAlZAoAAABod19wb3dlcl9wcmVwOiBWREQ9Tk9ORSBidXQgVkNTPSVkCgAAAAAAAAAAAAAAAABo -d19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBleHRlcm5hbCBhZGp1c3RhYmxlIHBvd2VyIHJlZ3Vs -YXRvcnMgVkREPSVkLCBWQ1M9JWQKAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZERD0lZAoA -AAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZDUz0lZAoAAAAAAAAAAAAA -AAAAAGh3X3Bvd2VyX3ByZXA6IGkyYyB3cml0ZSBlcnJvciwgVkREPSVkLHJldD0lZAoAAGh3X3Bv -d2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZERD0lZAoAAAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6 -IGkyYyB3cml0ZSBlcnJvciwgVkNTPSVkLHJldD0lZAoAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9y -dGVkIFZDUz0lZAoAAAAAAAAAAAAAAAAAAGV4dG1lbSBjbGsgbW9kZSAlZCwgZXh0bWVtICV1LCBy -ZWZfY2xrICV1CgAAAAAAAHVwIGNsayBtb2RlICVkLCByZWZfY2xrICV1LCBkZXYuY2xrLnVwICV1 -CgAAAAAAAGNsayBtb2RlICVkLCByZWZfY2xrICV1LCBkZXYuY2xrLmNvcmUgJXUKAAAAAAAAAFZQ -RCByZWdpb24gaXMgdG9vIHNtYWxsIChTRVJDRkdfU1JfUEZOVlBEU0laRSAweCV4KQoAAAAAAAAA -AAAAAABjZl9wcmVwOiBlcnJvciwgcmV0ICVkCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAIIAAAEgAAAAAAAAAAAAAACCAAABAAAAAAAAAAAAAAAAggAAAMAA -AAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaA -gAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAA -AAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAgBADAAAAAAAACAAAAAAAAAAAAgAA -AAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAA -AAAgA4AAAAAAAAAAAAAAAAAAEAKAAIAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAACAAAKAAAAAAAAAAAAAAAAA -AAACAAAAAAAAAAAAAAAAAIAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACgAAAAAAA -AAAAAAAAAAEAAwAAAAAAAAAAAAAAAAAAAoMAAAAAAAAAAAAAAAAAEAKAAAAAAAAAAAAAAAAAADAA -AwAAAAAEAAAAAAAAAAAwAwMAAAAABAAAAAAAAAAAMAADAAAAAAAACAAAAAAAADAAAwAAAAAAAAAA -AAAAAAAwBYMAAAAAAAAIAAAAAAAAMAWDAAAAAAAAAAAAAAAAADAEgwAAAAAAAAgAAAAAAAAwBIMA -AAAAAAAAAAAAAAAAMAMDAAAAAAAACAAAAAAAADADAwAAAAAAAAAAAAAAAAA4AwMAAAAAAAAAAAAA -AAAAOAWDAAAAAAAAAAAAAAAAADgEgwAAAAAAAAAAAAAAAAA4AAMAAAAAAAAAAAAAAAAANAaCAAAA -AAAAAAAAAAAAADwDggAAAAAAAAAAAAAAAAA8AAMAAAAAAAAIAAAAAAAAPAADAAAAAAAAAAAAAAAA -ADwEgwAAAAAAAAAAAAAAAAA8BQMAAAAAAAAAAAAAAAAAPQQDAAAAAAAAAAAAAAAAADwDgwAAAAAA -AAAAAAAAAAAsAAIAAAAAAAAAAAAAAAAALAWCAAAAAAAAAAAAAAAAACwFAgAAAAAAAAAAAAAAAAAQ -BoAAAAAAAAAAAAAAAAAAEAaCgAAAAAAAAAAAAAAAAIAOggAAAAAAAAAAAAAAAACQB4KAAAAAIAAA -AAAAAAAAgAeCAAAAACAAAAAAAAAAABAHAoAAAAAAAAAAAAAAAAAQBwKAAAAAAAAAAAAAAAAAEAcC -gAAAAAAAAAAAAAAAABAGAgAAAAAAAAAAAAAAAAAQBgKAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAA -AAAAAAAHAgAAAAAgAAAAAAAAAAAQF4MAAAAAAAAIAAAAAAAAEBeDAAAAAAAACAAAAAAAABAAAAAA -AAAAAAAAAAAAAAAQBgOAAAAAAAAAAAAAAAAAAA4DAAAAAAAAAAAAAAAAABAGA0AAAAAAAAAAAAAA -AAAQBgMAAAAAAAAAAAAAAAAAEAYAAAAAAAAAAAAAAAAAAAAGA4AAAAAAAAAAAAAAAAAABgMAAAAA -AAAAAAAAAAAAAA4CAAAAAAAAAAAAAAAAAAAOAgAAAAAAAAAAAAAAAAAQBgIAAAAAAAAAAAAAAAAA -EAYCgAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAEAMAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAA//////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -/////////wAAAAAAAAAgAAAAAMAAAAAAAAAAAAAAIAAAAADgAAAAAAAAAAAAACAAAAABIAAAAAAA -AAAAAAAAAgAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAASEAAAAAAAAAAAAAAAAAAQEgAAAA -AAAAAAAAAAAAAAACAAAABAAEAAAAAAAAAAAAgUAAAAAAAAAAAAAAAAAABoAAAAQAAAAAAAAAAAAA -AIAAQAAAAAAAAgAAAAAAAACAACAAAAAAAAIAAAAAAAAIgAAAAAAAQAAAAAIAAAAAAQBAAAAAAAAA -AAAAAAAAAAEAQgAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAhAgAAAAAAAAAAAAAAAAAAIM -AgAAAAAAAAAAAAAAAAAAhQIAAAAEAAAAAAAAAAAAAIBCAAAAAAAAAAAAAAAAAICAQgBAAAAAAAAA -AAAAAACAgEIAAAAAAAAAAAAAAAAAAgAiAAAAAAAAAAAAAAAAAACAQQAAAAAAAAAAAAAAAACAACEA -AAAAAAAAAAAAAAAAAIBBgAAAAAAAAAAAAAAAAICAQYAAAAAAAAAAAAAAAAACACEAAAAAAAAAAAAA -AAAAABAggAAAAAAAAAAAAAAAAAIlAIAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAiIAEgAAA -AAAAAAAAAAAAAIiEgIAAAAAAAAAAAAAAAAAIiASAAAAAAAAAAAAAAAAACIgEgAAAAAAAAAAAAAAA -AAiiAIAAAAAAAAAAAAAAAAAIogCAAAAAAAAAAAAAAAAACKMAgAAAAAAAAAAAAAAAAAijAIAAAAAA -AAAAAAAAAAAIpICAAAAAAAAAAAAAAAAACKSAgAAAAAAAAAAAAAAAAASkgMAAAAAAAAAAAAAAAAAE -ogDAAAAAAAAAAAAAAAAABKMAwAAAAAAAAAAAAAAAAASIBMAAAAAAAAAAAAAAAAAACQGAAAAAAAAA -AAAAAAAAAgwAgAAAAAAAAAAAAAAAAACIBMAAAAAAAAAAAAAAAAAAiASAAAAAAAAAAAAAAAAAAgsA -gAAAAAAAAAAAAAAAAACKgIAAAAAAAAAAAAAAAAAAC4CAAAAAAAAAAAAAAAAAAIwAgAAAAAAAAAAA -AAAAAAIgEIAAAAAAAAAAAAAAAAACCgCAAAAAAAAAAAAAAAAAAgqAgAAAAAAAAAAAAAAAAAAJAoAA -AAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAACAAAAAAAAAAAAAAAAAAACBEAAAAAAAAAAAAAAAAAAAgQgAAAAAAAAAAAAAAAAAAIEEAAAA -AAAAAAAAAAAAAEmBgAAAAAAAAAAAAAAAAABBgQAAAAAAAAAAAAAAAACAAAEAAAAAAAAAAAAAAAAA -AACBgAAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAgACgAAAAAAAAAAAAAAAAAAAIAAAAAAAA -AAAAAAAAAACBgAAAAAAAAAAAAAAAAAAAgYCAAAAAAAAAAAAAAAAAAImAgAAAAAAAAAAAAAAAAACJ -gMAAAAAAAAAAAAAAAAAAAYIAAAAAAAAAAAAAAAAAAgGAAAAAAAAAAAAAAAAAAAIBgIAAAAAAAAAA -AAAAAAAAQYGAAAAAAAAAAAAAAAAAAgGBgAAAAAAAAAAAAAAAAAIJgYAAAAAAAAAAAAAAAAACAYEA -AAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAIBAAAAAAAAAAAAAAAQAAACAAAAAAAAAAAA -AAAAEAAAAAAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAJIAAAAAAAAAAbMAEAAgAAAAAAgAkgAAAAAAAgAB -uQASgiAAAAAACACSAAAAAAAAAAGzABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAgAAAAFAEQB -w4AAKwEQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAA -AAAAAAABywAQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAA -AAAAAAAAAAABywAQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAIAAAABQBEAcGAAEsAEAAgAAAA -AAgAAAAFAEQBwYAASwAQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAg -AAAAAAgAAAAFAEQBwYAASwAQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAAAAAAAAAAAAAAAcsB -EwIgAAAAAAhHIAEEAAABWgABaQMgEiJAAAAACEcgAQQAAAFaAAFpAiMSIEAAAAAIAAAABQBEAcGA -AEsBEwIgAAAAAAAAAAAAAAAAAAABywAQACAAAAAACEcgAQEGUMFYIADJAiASIkAAAAAIAAAABQBE -AcGAAEsBEwIgAAAAAAhHIAEABlAhWsABCQMgEiJAAAAACAAAAAUARAHBgABLARMCIAAAAAAIAAAA -BQBEAcGAAEsAEAAgAAAAAAgAAAAFAEQBwYAASwAQACAAAAAACAAAAAUARAHBgABLABAAIAAAAAAA -AAAAAAAAAAAAAcsAEAAgAAAAAAgAAAAFAEQBwYAASwETAiAAAAAACAAAAAUARAHBgABLARMCIAAA -AAAFxRK6AVhAaYsqRfEkoxIgAAAAAAXFEroFW8BpiSpFsSRTEiAAAAAADcUSogVYQGmLKkXxJKMS -IAAAAAANxRKiAVvAaYkqRbEkUxIgAAAAAA3FEqIFWEBpiypF8SSjEiAAAAAADcUSogFbwGmJKkWx -JFMSIAAAAAANxRKiBVhAaYsqRfEkoxIgAAAAAA3FEqIBW8BpiSpFsSRTEiAAAAAACcQQoAEAQEgC -AEWxNGMSIAAAAAAJxBCgBVhASYEqRbE1YxIgAAAAAAnEEKAFWEBJgSpFsTVjEiAAAAAAAcUQuAFY -QEmLKkWxJWMSIAAAAAAAoRCIBQBArAgABakBUxIgAAAAAAnAEJAFWEABiSpFSQFjEiAAAAAACcAQ -uAVYQAGISkXxAKMSIAAAAAABwBC4BVpAAYpKRbEAUxIgAAAAAAHAELgFWkABikpFsQBTEiAAAAAA -AcAQuAVaQAGKSkWxAFMSIAAAAAABwBC4BVpAAYpKRbEAUxIgAAAAAAmgEJABWkABikpFsQBTEiAA -AAAAAcAQgAVYQAGLKkUpAGMSIAAAAAABwBCABVhAAYsqRSkAYxIgAAAAAAHAEIAFWEABiypFKQBj -EiAAAAAACEcgAQQAAAFYAAFpAyASIEAAAAAIgQAAAQBCrAOgBakBUxIgAAAAAAgAAAAAAFAgAMAA -6wAQACAAAAAACAAAAAEAUMAAIACrABAAIAAAAAAIAAAAAABQIADAAOsAEAAgAAAAAACBAAAFAEKs -wAIFqQBTEiAAAAAACgFAAAAAAAwCAAGhARNSIQAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAChEIgF -AECsCgAEiQBTEiAAAAAACAAAAAUARAHDoARpAaMSIQAAAAAIAAAABQBEAcGAAEsBEwIgAAAAAAgA -AAAAAFAgAMAA6wAQACAAAAAACAAAAAUARAHDgAHrABAAIAAAAAAIAAAABQBEAcOAAesAEAAgAAAA -AAAAAAAAAAAAAAABywAQACAAAAAAAAAAAAAAAAAAAAHLABAAIAAAAAAIAAAAAABQIADAAOsAEAAg -AAAAAAHAELgFWkABikpFsQBTEiAAAAAAAAAAAAAAAAAAAAHLARMCIAAAAAAAAAAAAAAAAAAAAcsA -EAAgAAAAAAgAAAAFAEQBwYAASwAQACAAAAAACAAAAAAAUCAAwADrABAAIAAAAAAIAAAAAABQIADA -AOsAEAAgAAAAAAgAAAAAAFAgAMAA6wAQACAAAAAACAAAAAAAUCAAwADrABAAIAAAAAAIAAAAAQBQ -wAAgAKsAEAAgAAAAAAnFEyIBSkRpCkBFkSVjEiAAAAAAAcARAAFSRACDqkWpAGMSIAAAAAAJwBEA -BVJEAEOqRakAYxIgAAAAAAHAEIABWkQBgopFqQBTEiAAAAAADcAAAAVYQGGJKkXxAaMSIAAAAAAA -AAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAwAAQAAAAAAAABARMSIAAAAAAARzAAAQGQAVuABAEAYDIg -QAAAAABHMAAFAYABW4AEAQBgMiBAAAAAAAMAAAEAUAVZgAQBAGMSI0AAAAAAAwAABAAABVmABAEA -YxIjQAAAAAAAAAAAAAAAAAAAAQETEiAAAAAAACBQAAQAAAACAAABABMSIwAAAAAIYCAAhAAAAAAA -AAMAEAAgAAAAAACgIACAAAAAAACYAQETEqAAAAAACGAAAAQAQgDCAgIBAWMSYQAAAAAJwAAABSHA -AYIGRAEAExIgAAAAAAgAYAAEAAAAAgAAAAEQACAAAAAACABgAAQAAAACAAACABAAIAAAAAAAAAAA -AAAAAAIAAAIAEAAgAAAAAAwIFIAFBQAAA4CmARBTE2AAAAAAAIAAAAEAQgDCAgQBAFMSYAAAAAAI -QAAABQBQAAAgBAEAUxIjAAAAAACgAAAAAAAAAAAAAQETEiAAAAAADAAAAAVCAAGARQQBA2ASIAAA -AAAAAAAAAAAAAAIAAAMBECQgAAAAAAAgUAAEAAAAAAAAAQETEiAAAAAACGAgAIQAAAAAAAADABAA -IAAAAAAAoCAAgAAAAAIAAAEBExKgAAAAAAhgAAAEAEIAwgICAQBjEmAAAAAACABgAAQAAAACAAAC -ABAAIAAAAAAIAIAAFAAAAAAAAAEAEyY4AAAAAAgAgAAUAAAAAgAAAwAQAAAAAAAACACAABQAAAAA -AAABABMmOAAAAAAIAIAAFAAAAAIAAAMAEAAAAAAAAAwAAAAFsgABgk0EAQIAAiAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnAAAACWkYCBIsCAQJjEiAAAAAAAcAA -AAIaQAIEiwIBAmMSIAAAAAAMCHSAQgSAACoALgEwcxIgAAAAAAwIdIBEAAAAKgAgATETEiAAAAAA -CAIQoAQAAAAAAIABABMSIAAAAAAIAhCgBAAAAAAAgAEAExIgAAAAAAQIdABFAIAAA4BEATFjEiAA -AAAABcgUAAEEgAADIE4BMHMSIAAAAAAByBCABVpAAgJKRAEzYxIgAAAAAA3IdABGWkABgEpEATBT -EmAAAAAABch0AEIaSAGASkQBMFMSYAAAAAAIRwAABAAAAAIAAAEAEBIgAAAAAAhHAAAEAAAAAAAA -AQIgEiAAAAAAAEcgAQIDkOFbgAQBAGASIkAAAAAARyABAgOQ4VuABAEAYBIiQAAAAABHIAECA5Dh -W4AEAQBgEiJAAAAACAAgAQIAQgABoEQBAGMSYAAAAAAIACABAgBCAAGgRAEAYxJgAAAAAAgAIAEC -AEIAAaBEAQBjEmAAAAAAAAAgAYVBAACCYEQBAeMSYAAAAAAIACABhUEAAAJgRAEB4xJgAAAAAAnA -IAGFUkAAgaBEAQBjEmAAAAAAAAAAAAYAQgABoEQBAGMSYAAAAAAIAAAABUEAAIJgRAEB4xJgAAAA -AAAAAAAFQQAAAGBEAQDTEmAAAAAAAcAAAAVSQACBoEQBAGMSYAAAAAAIAKABhAAAAAAARAEAExJg -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAARcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW2dsb2Jh -bF0KcnNzX2dsYl9jb25maWdfbW9kZT1iYXNpY3ZpcnR1YWwKcnNzX2dsYl9jb25maWdfb3B0aW9u -cz10bmxtYXBlbixoYXNodG9lcGxpdHosdG5sYWxsbGtwCnBsX3RpbWVvdXRfdmFsdWU9MjAwCnJl -Z1sweDEwMDhdPTB4NDA4MDAvMHgyMWM3MApyZWdbMHgxMDBjXT0weDIyMjIyMjIyCnJlZ1sweDEw -YTBdPTB4MDEwNDA4MTAKcmVnWzB4MTA0NF09NDA5NgpyZWdbMHgxMDQ4XT02NTUzNgpyZWdbMHgx -MDRjXT0xNTM2CnJlZ1sweDEwNTBdPTkwMjQKcmVnWzB4MTA1NF09OTIxNgpyZWdbMHgxMDU4XT0y -MDQ4CnJlZ1sweDEwNWNdPTEyOApyZWdbMHgxMDYwXT04MTkyCnJlZ1sweDEwNjRdPTE2Mzg0CnNn -ZV90aW1lcl92YWx1ZT01LDEwLDIwLDUwLDEwMCwyMDAKcmVnWzB4MTBjNF09MHgyMDAwMDAwMC8w -eDIwMDAwMDAwCnJlZ1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZGMwXT0w -eDBlMmY4ODQ5CnRzY2hfdGlja3M9MTAwMDAwLDEwMDAwLDEwMDAsMTAKZmlsdGVyTW9kZT1mY29l -bWFzayxzcnZyc3JhbSxmcmFnbWVudGF0aW9uLG1wc2hpdHR5cGUscHJvdG9jb2wsdmxhbixwb3J0 -LGZjb2UKZmlsdGVyTWFzaz1wcm90b2NvbCxmY29lCnRwX3Btcng9MzAKdHBfcG1yeF9wYWdlc2l6 -ZT02NEsKdHBfbnJ4Y2g9MAp0cF9wbXR4PTUwCnRwX3BtdHhfcGFnZXNpemU9NjRLCnRwX250eGNo -PTAKdHBfbXR1cz04OCwyNTYsNTEyLDU3Niw4MDgsMTAyNCwxMjgwLDE0ODgsMTUwMCwyMDAyLDIw -NDgsNDA5Niw0MzUyLDgxOTIsOTAwMCw5NjAwCnJlZ1sweDdkMDRdPTB4MDAwMTAwMDgvMHgwMDAx -MDAwOApyZWdbMHg3ZDA4XT0weDAwMDAwODAwLzB4MDAwMDA4MDAKcmVnWzB4N2Q0OF09MHgwMDAw -MDAwMC8weDAwMDAwNDAwCnJlZ1sweDdkNjBdPTB4MDYwMDAwMDAvMHgwNzAwMDAwMApyZWdbMHgx -OWMwNF09MHgwMDAwMDAwMC8weDAwNDQwMDAwCnJlZ1sweDE5YzI4XT0weDAwODAwMDAwLzB4MDFm -MDAwMDAKcmVnWzB4OGRjMF09MHgwMDAwMDEwNC8weDAwMDAwMTA0CnJlZ1sweDE5MjVjXT0weDAw -MDA0MWMwLzB4MDAwMDMxYzAKaG1hX3NpemU9NjQKaG1hX3JlZ2lvbnM9c3RhZyxwYmwscnEKW2Z1 -bmN0aW9uIjAiXQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04 -Cm5ldGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlv -biIxIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRo -Y3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4MgpbZnVuY3Rpb24iMiJd -Cm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9 -OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDQKW2Z1bmN0aW9uIjMiXQpudmY9 -MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgKbmVx -PTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9MHg4CltmdW5jdGlvbiI0Il0Kd3hfY2Fwcz1h -bGwKcl9jYXBzPWFsbApudmk9MjgKbmlxZmxpbnQ9MjAyCm5ldGhjdHJsPTExNgpuZXE9MjU2Cm5x -cGNxPTEyMjg4Cm5leGFjdGY9NDAKbnJhd2Y9MgpjbWFzaz1hbGwKcG1hc2s9YWxsCm5ldGhvZmxk -PTEwMjQKbmNyeXB0b19sb29rYXNpZGU9MTYKbmNsaXA9MzIwCm5maWx0ZXI9NDk2Cm5zZXJ2ZXI9 -NDk2Cm5oYXNoPTEyMjg4Cm5ocGZpbHRlcj02NApwcm90b2NvbD1uaWNfdm0sb2ZsZCxyZGRwLHJk -bWFjLGlzY3NpX2luaXRpYXRvcl9wZHUsaXNjc2lfdGFyZ2V0X3BkdSxpc2NzaV90MTBkaWYsdGxz -a2V5cyxjcnlwdG9fbG9va2FzaWRlCnRwX2wydD0zMDcyCnRwX2RkcD0yCnRwX2RkcF9pc2NzaT0y -CnRwX3Rsc19rZXk9Mwp0cF90bHNfbXhyeHNpemU9MTc0MDgKdHBfc3RhZz0yCnRwX3BibD01CnRw -X3JxPTcKdHBfc3JxPTEyOApbZnVuY3Rpb24iNSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZp -PTQKbmlxZmxpbnQ9MzQKbmV0aGN0cmw9MzIKbmVxPTY0Cm5leGFjdGY9MTYKY21hc2s9YWxsCnBt -YXNrPWFsbApuc2VydmVyPTE2Cm5oYXNoPTIwNDgKdHBfbDJ0PTEwMjAKbmNsaXA9NjQKcHJvdG9j -b2w9aXNjc2lfaW5pdGlhdG9yX2ZvZmxkCnRwX2RkcF9pc2NzaT0yCmlzY3NpX250YXNrPTIwNDgK -aXNjc2lfbnNlc3M9MjA0OAppc2NzaV9uY29ubl9wZXJfc2Vzc2lvbj0xCmlzY3NpX25pbml0aWF0 -b3JfaW5zdGFuY2U9NjQKW2Z1bmN0aW9uIjYiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00 -Cm5pcWZsaW50PTM0Cm5ldGhjdHJsPTMyCm5lcT02NgpuZXhhY3RmPTMyCmNtYXNrPWFsbApwbWFz -az1hbGwKbmhhc2g9MjA0OAp0cF9sMnQ9NApwcm90b2NvbD1mY29lX2luaXRpYXRvcgp0cF9kZHA9 -MgpmY29lX25mY2Y9MTYKZmNvZV9udm5wPTMyCmZjb2VfbnNzbj0xMDI0CltmdW5jdGlvbiIxMDIz -Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9NApjbWFzaz1hbGwKcG1hc2s9YWxsCm5leGFj -dGY9OApuZmlsdGVyPTE2CltmdW5jdGlvbiIwLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYK -bnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3RybD00Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1h -c2s9MHgxCltmdW5jdGlvbiIxLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlx -ZmxpbnQ9NgpuZXRoY3RybD00Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgyCltm -dW5jdGlvbiIyLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9Ngpu -ZXRoY3RybD00Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIz -LyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NgpuZXRoY3RybD00 -Cm5lcT04Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgyCltwb3J0IjAiXQpkY2I9cHBwLGRj -YngKaHdtPTYwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwz -CmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNv -Y2tldG51bSw1Cltwb3J0IjEiXQpkY2I9cHBwLGRjYngKaHdtPTYwCmx3bT0xNQpkd209MzAKZGNi -X2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhl -cnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1CltmaW5pXQp2ZXJzaW9uPTB4 -MTQyNTAwMWMKY2hlY2tzdW09MHg4MTM2ZDBmNgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFtnbG9iYWxdCnJzc19n -bGJfY29uZmlnX21vZGU9YmFzaWN2aXJ0dWFsCnJzc19nbGJfY29uZmlnX29wdGlvbnM9dG5sbWFw -ZW4saGFzaHRvZXBsaXR6LHRubGFsbGxrcApwbF90aW1lb3V0X3ZhbHVlPTEwMDAKcmVnWzB4MTAw -OF09MHg0MDgxMC8weDIxYzcwCnJlZ1sweDEwMGNdPTB4MjIyMjIyMjIKcmVnWzB4MTBhMF09MHgw -MTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sweDEwNDhdPTY1NTM2CnJlZ1sweDEwNGNdPTE1 -MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0XT05MjE2CnJlZ1sweDEwNThdPTIwNDgKcmVn -WzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIKcmVnWzB4MTA2NF09MTYzODQKcmVnWzB4MTBh -NF09MHhhMDAwYTAwMC8weGYwMDBmMDAwCnJlZ1sweDEwYThdPTB4NDAyMDAwLzB4NDAyMDAwCnNn -ZV90aW1lcl92YWx1ZT01LDEwLDIwLDUwLDEwMCwyMDAKcmVnWzB4MTBjNF09MHgyMDAwMDAwMC8w -eDIwMDAwMDAwCnJlZ1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZGMwXT0w -eDBlMmY4ODQ5CnRzY2hfdGlja3M9MTAwMCwxMDAsMTAsMQpmaWx0ZXJNb2RlPWZjb2VtYXNrLHNy -dnJzcmFtLGZyYWdtZW50YXRpb24sbXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBvcnQsZmNvZQpm -aWx0ZXJNYXNrPXByb3RvY29sLGZjb2UKdHBfcG1yeD0zMAp0cF9wbXJ4X3BhZ2VzaXplPTY0Swp0 -cF9ucnhjaD0wCnRwX3BtdHg9NTAKdHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4Y2g9MAp0cF9t -dHVzPTg4LDI1Niw1MTIsNTc2LDgwOCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIsMjA0OCw0MDk2 -LDQzNTIsODE5Miw5MDAwLDk2MDAKcmVnWzB4N2QwNF09MHgwMDAxMDAwOC8weDAwMDEwMDA4CnJl -Z1sweDdkMDhdPTB4MDAwMDA4MDAvMHgwMDAwMDgwMApyZWdbMHg3ZDQ4XT0weDAwMDAwMDAwLzB4 -MDAwMDA0MDAKcmVnWzB4N2Q2MF09MHgwNjAwMDAwMC8weDA3MDAwMDAwCnJlZ1sweDE5YzA0XT0w -eDAwNDAwMDAwLzB4MDA0NDAwMDAKcmVnWzB4MTljMjhdPTB4MDA4MDAwMDAvMHgwMWYwMDAwMApy -ZWdbMHg4ZGMwXT0weDAwMDAwMTA0LzB4MDAwMDAxMDQKcmVnWzB4MTkyNWNdPTB4MDEwMDM0MDAv -MHgwMTAwMzQwMApbZnVuY3Rpb24iMCJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTI4Cm5p -cWZsaW50PTE3MApuZXRoY3RybD05NgpuZXE9MjUyCm5leGFjdGY9NDAKbnJhd2Y9MgpjbWFzaz1h -bGwKcG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbmNyeXB0b19sb29rYXNpZGU9MzIKbmNsaXA9MzIK -bmZpbHRlcj00OApuc2VydmVyPTQ4Cm5oYXNoPTIwNDgKbmhwZmlsdGVyPTAKcHJvdG9jb2w9bmlj -X3ZtLG9mbGQscmRkcCxyZG1hYyxpc2NzaV9pbml0aWF0b3JfcGR1LGlzY3NpX3RhcmdldF9wZHUs -aXNjc2lfdDEwZGlmLHRsc2tleXMsY3J5cHRvX2xvb2thc2lkZQp0cF9sMnQ9MzA3Mgp0cF9kZHA9 -Mgp0cF9kZHBfaXNjc2k9Mgp0cF90bHNfa2V5PTMKdHBfc3RhZz0yCnRwX3BibD01CnRwX3JxPTcK -dHBfc3JxPTEyOApbZnVuY3Rpb24iMSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlx -ZmxpbnQ9MzQKbmV0aGN0cmw9MzIKbmVxPTY0Cm5leGFjdGY9MTYKY21hc2s9YWxsCnBtYXNrPWFs -bApuc2VydmVyPTE2Cm5oYXNoPTIwNDgKdHBfbDJ0PTEwMjAKcHJvdG9jb2w9aXNjc2lfaW5pdGlh -dG9yX2ZvZmxkCnRwX2RkcF9pc2NzaT0yCmlzY3NpX250YXNrPTIwNDgKaXNjc2lfbnNlc3M9MjA0 -OAppc2NzaV9uY29ubl9wZXJfc2Vzc2lvbj0xCmlzY3NpX25pbml0aWF0b3JfaW5zdGFuY2U9NjQK -W2Z1bmN0aW9uIjEwMjMiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00CmNtYXNrPWFsbApw -bWFzaz1hbGwKbmV4YWN0Zj04Cm5maWx0ZXI9MTYKW2Z1bmN0aW9uIjAvKiJdCnd4X2NhcHM9MHg4 -MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00 -CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9 -MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFs -bApwbWFzaz0weDIKW3BvcnQiMCJdCmRjYj1wcHAsZGNieCxiMmIKaHdtPTMwCmx3bT0xNQpkd209 -MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkx -NCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0IjEiXQpk -Y2I9cHBwLGRjYngsYjJiCmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkw -NixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90 -bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbZmluaV0KdmVyc2lvbj0weDE0MjUwMDFkCmNoZWNrc3Vt -PTB4MzYxYjk1NmIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= -==== diff --git a/sys/dev/cxgbe/firmware/t6fw-1.16.63.0.bin.uu b/sys/dev/cxgbe/firmware/t6fw-1.16.63.0.bin.uu new file mode 100644 index 000000000000..bfc308f1dafa --- /dev/null +++ b/sys/dev/cxgbe/firmware/t6fw-1.16.63.0.bin.uu @@ -0,0 +1,12037 @@ +/*- + * Copyright (c) 2017 Chelsio Communications, Inc. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + */ +begin-base64 644 t6fw +AAIFOQEQPwAAARcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAABRoFKwUzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IEZyaSBTZXAgIDggMTE6 +MDQ6NDIgUERUIDIwMTcgb24gdm5jNC5hc2ljZGVzaWduZXJzLmNvbTovaG9tZS9maXJtd2FyZS9j +dnMvZnctcmVsZWFzZSksIFZlcnNpb24gVDZ4eCAwMS4xMC4zZi4wMAAAAAAAAAAAAAAAAOsKHZhg +ANQAH/zhSOEAe/AAEAAA4QGUQOEAVyDhADC4eP///x/84UCAAAAB4QB7cAAAEAAf/9o8IAAAAOEB +nAThBQAAIoIAQOEFCAAihgBAIIIARCCGAEThBQAEAAwAAIAAAQLhAHs84QB7ROEAe+TiAAAAAAEA +AOEAe5AgAAAAAACAAOEAewAAAEAB4QB7nAAGAIgAACAAREREQuAAAADjAAST4wAIACAAAlwAAAAA +H/8P8AAAAAAf/w/0AAAAAB//D/gAAAAAH/8P/B//gAAAAAAAAAAAAAAAAADAABH/yiIaB5IQghAS +/8kT/8mTIBL/yYMgJEoAA0QBZU/xwUEEMwEEMwNlP+YS/8PAMJMgEv/DE//DhCAEMwGTIBH/wRL/ +wpIQEf/BEv/CkhAR/8EB9DEA5DES/8AC5zECFgAR/7+BEAEBX8AhAhEByRER/7wS/7ySEBH/vBL/ +vJIQYAAPEf+3Ev+7khAR/7cS/7qSEIEQEf+5wCCSERL/uJISwCCSExL/t5IQghAC8lBlL/cR/7XH +L5IQEf+0khAS/7QT/7STIMAykyET/7OTIoIiEv+yE/+ykyAjIiEU/7EEMwHJOxP/sIMwA4MUCDMR +FP+upDOTIRP/opMiYAALAAAAwDCTIRP/npMiEv+pkCCQIZAikCOQJJAlkCaQJ5AokCmQKpArkCyQ +LZAukC8gJhAgJhEiIgIS/58CKDES/5kjCgAtNzAtNzgjPQFyM/MAAgAS/5nAMC83AC83IC83QC83 +YCM9AnIz7QACABL/jcAwKDcwKDc4Iz0BcjPzEv+OwDAnNwAnNyAnN0AnN2AjPQJyM+0S/4kV/4oW +/4rAMNcgBWYBYAASBDYFAAIA0w/TDwUzDG47FAdHFAcEQ3Yx5gQ2BQUzDG877QACABL/exX/fCMK +AAInAgcEQwQ+BQUzDAdHFG878AMCABL/d8kugyCEIYUivCJ0Ow6GULRVljC0M3Qz9GP/5gBlP+Jl +X98S/2zAMgMuBQMCABL/YsAwKDdAKDdIIz0BcjPzAAIAEv9nLScAwBEBSTEASDEBAgDAABT/YwTS +MRX/Y5RQFP9iBNMxFf9ilFAU/2IE1DEV/2GUUBT/YQTVMRX/YJRQEP9gAwAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA9DAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAA +H/wAAOMACfgf/AAAH/wAAOMACfgf/AAAH/wAAOMACfgf/wAAH/8F0OMACfgf/wXQH/8F0OMAD8gf +/wXQH/8F0OMAD8gf/wXQH/8HuOMAD8gf/we4H/8P8OMAEbAf/w/wH/8zUOMAGegf/zNQH/8zUOMA +PUgf/4AAH//bLOMAPUggAAAAIAABauMAmHQgAAF4IAABfOMAmeAgAAF8IAABheMAmeQgAAGYIAAB +nOMAmfAgAAGcIAABpeMAmfQgAAG4IAABvOMAmgAgAAG8IAABxeMAmgQgAAHYIAAB2OMAmhAgAAHc +IAAB4uMAmhAgAAH4IAAB+OMAmhggAAH8IAAB/OMAmhggAAIYIAACGOMAmhggAAIcIAACHOMAmhgg +AAI4IAACOOMAmhggAAI8IAACPOMAmhggAAJYIAACWOMAmhggAAJcIAACYuMAmhggAAJ4IAACeOMA +miAgAAJ8IAACguMAmiAgAAKYIAJ+OuMAmiggAoAAIAKh2OMDFcwgAqHYIAKh2OMDN6QgAqHYIAer +ZOMDN6QgB6twIAewIOMIQTwgCAAAIAgZUOMIRewgCBlQIAlLluMIXzwgCUugIAlNFOMJkYwgCwAA +IAsAAOMJkwAgCwAAIAsAAOMJkwAgCwAAIAufSOMJkwAAAAAAAAAAAAAAAAAf/wAAH/+AAB/8AAAf +/gAAH/+AACAAAAAAAAAAAAAAACAAT/MgAE/oIABUKyAAT+ggAFOVIABP6CAAUKsgAFMlIABSoCAA +T+ggAFJIIABR+CAAUYMgAE/TIABRKyAAT+ggAE/oIABP6CAAUNIAAAAA////////D/z///D///8A +/CABEfYgARNyIAEToiABE2ggARMmIAETHCABEukgARLfIAES1SABEoAgAROgIAESdiABEkcgAROi +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 +H/8vsCACl0AgApbQgYAAAAQAAAiCgAAAgQAAACAClrQMAAAAH/8YAB//GBAf/x2Y//+//8MAAAAE +AQAIH/8wsB//LDQf/zAsH/8o1CALAGAf/y54H/8udB//Ltgf/y+gIAsCAAAPQkAgApHYIAAgaCAL +AXAgABVoIAsCMCALAUAgCwGgIAsB0CADEuwgApHoAABgAABgAABgAAAAAACG3SALAmAqAAAAIABa +wCAAKeAgApG4IAMcrCALAoAgABqIIAKR+CAAAAAf/ywkGgAAACCAAAAf/yrIIAJoCCACamQgAnEI +IACghCADV6AgADjwgAAAACAALtwAAP//IAsDwCALBNAgCwVQIAsEQCALBIAgCwUgIAsEECAAazgg +ADdYH/8s7AAAIAAgCwWgIAsF0AUAAACD/wAAABAAACALBhAgCwVwH/8tGB//LkAgA2LwH/8pZB// +LNAAD///IABBHA88AAAgAI70DwAAACAAlPQgApToH/8FEB//ANBnRSMB782riZi63P4QMlR2H/8A +IAAAPyggApncz////yALB9AQAAAAP////wIAAABAAAAAAAAP/gAAgAAgA440IAe0YCAHtGYAAEAA +IAez+AAACAAgB7SCIABhlCADizgf/y5kH/8txP/+//8gAGTYH/zi5B//LPAgA90gAExLQCAD5bAg +CwwwH/8s9OEAAAAgA8d4IAPikAAgAAAAABAA//v//w/+gAD///AAIAsMYCALDLAP9oAAIAsM4CAL +DRAABAAAAP///wABAAAf/ys4IAtvMCALDeAgCw2gIACMnCAAjnAgAIpgIAsPgCALDkAgCw7QIACI +ICALDyAgCw+g//9//yALD9AgCxAgIAsQcCALENAf/yzgIAsQoCALEkAgCxEAIAsRkCALEeAgCxKw +IAsS8AAA//4gCxJwIAsTEFMAAABSAAAAUQAAACACYWwgCxPAIAsUACALEzAgCxOgIAsUUAOAAAAf +/ylA//f////9//8EAAAACAAAACAD+zAACAAAIACfNABAAAAf/y0QIAsUoB//HCggCxaQFAAAAIAA +AAJ8UAAAgAAAEIAAAAaAAAAFAAAKAIAAsAAA/zSS///wD4AAsQAgCxYgH/8ZmAAAfkAgCxZgH/8s +5AD/wAAmAAAAAQAAACgAAADgAAAABYAAAAYAAAAf/yiYKwAAACAAvOAf/N4AH/8qZAf///81AAAA +A0AAAB////8ID///AD///4BAAADCAAAAAADAAB//LMg9AAAAH/8rRIEEAQCBBAAABwAAAB//LKAA +ADqYGAAAAB//EQAAAA//AEMAAB//KiggC3IAH/8yhB//MNAf/xeAAAIAAOEAegAf/yzUH/8s2B// +KJwf/yxoH/8cLB//HCAgC3IwAAMHgCALcqAf/xoAAAAJAAAAMAD//Ph/wAAAAKP/uwCj/7oADQAA +AOADAACD/7YAD////w//+AD/AAAAD//+ASALcuAgCxkwIAsZYCALc3AACgAAAA8AAP//AA8f/xw0 +A//AAIP/wAAgC3PwIAt0YB//LcAf/zFA/0DwAB//MRAf/wBwH/8QAASAAAgARAAA/x///wDAAAAB +gMIAAAMCAOEA4AAAAIEA/7//////AAAAgAAAAAALbB//HZwgCxmgH/8tWB//KPwf/x4IH/8YDB// +AIAgB6yAAAAnEB//sLAgC3nwIAt5wB//GAQf/xwU3q2+7yACkNg0AAAAPwAAAB//Lpwf/zBIAJkA +AAAAiQYQAAcC7gAAAAHAgACZAAAAH/8vCACIAAiCgAABH/8wmB//LqADFQAAAxEAAAAPA/8f/yuA +IAFIoCALekAgAU5gKQAAAAAAiRQgAVUQIAKSpAAQQAAgApbYIAFi1B//MWAAACEgIAKStB//Lkgf +/y9o8PDw8P8A/wCqqqqqzMzMzB//KQgAA///AAAn/yACkvggC3pgIAF1VCAC6RQf/yvQH/8tiAAJ +AAAf/yy0ABBIAIIAAAAgAY6QH/8tPCAALDAAABwgIAt9cCALfaAgACegIAspkCALKeAgC3wwIAt8 +UCALKhAgCypgIAt88CALfRAgCynAIAt9QCALfIAgC3ywIAsqkH8AAADwAAAAIAt90CAAYfA7AAAI +DgAAANAAAAAf/wDAAAAiCgAACFAAAB9AIAsrsCALK9AgCyvwAAkACB//MJQwAAAAH/8rJCALLxAg +Cy5AIAsuoCALLuAAAOAA///3/yALL6AgAu9UAACD/yAHtNggB7XQFaAAACACkHgf/zBYAAAIBgAA +iMwgCy/QH/8ZsAAEA/8KAAAAIAezCDMAAAAf/zFUA//gAH///wAAP/aQH/8wYAAAIhgD//AAIAtm +ICALZeAgC2ZAH/8yYB//MFwf/y5YIAt/wCACkCQgB6xEH/8nQCALMEAf/yrgH/8q1B//Kuwf/zEA +H/8waCAD5vAgCzCAH/8o7B//KoAAAA/w4AEAAB/84gggC4FQIAswwCABDlwgAQskIAuA0CALgSAg +Ao4QH/8Z0CALM4Af/x2kIAs+sOD//gAgC2jAH/8SXB//MQQgB7BwIAtJMCALSWBIAAAAIAI3gB// +KnQgAjmYH/8YcB//KGQf/ytUH/8oLAAAGcAAABfsIAewZB//KKT///H/4QBeAB//KkzhAC4AH/8r +UOEDBgDhAA4A4AUAAAP/AAAf/yhUIAKW4B/8v/88AAAAAAf//4MAAAAf/yhsIAtloCAHsNAgB7Ng +IAJtCB//LdQgAnas4AYAACAClrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBgAAAAAAAAP////////////////// +//8f/9WEH//VhB//1UQf/9VEH//VRB//1UQf/87gH//R4B//0BAf/9AQH//QECAHZPwAAAAAAAAA +AAAAAAAAAAAAIAdoICAHaCAAAAAAAAAAAAAAAAAAAAAAIAdk/CAHZPwf/9LwH//S8B//0vAf/9Lw +H//S8B//0vAAAAAAIAI/bAAAAAAAAAAAAAAAAAAAAAACAQAAAAAAAAAAAAAAAAAABAAAAAAAAACB +gAAAAAAAEAQAAAAAAAACgQAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +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 +QA+gARCTEOqztkAPmADF6yjvQArgC3BkodUarWnrKO9AD5gAxeqntUAK4AtqZKL4Gq1k6yjvQA+Y +AMXqp7dACuALZWSsERqtXuso70APmADF6q+3QArgC19lq/sarVnsaO9AEBAMseqptcAK4AtaZaSc +ixErshILmVJkkApokgfiFPAgECADWYwR68LJQA6AACDjRclAD6ABEACTEOqztUAPmADF6yjvQArg +C0pkoYUarUTrKO9AD5gAxeqltUAK4AtFZaxp2hDrINhACmAH7MqsGq077GjvQBAQDLHqq7bACuAL +PGWsR+sg2EAQGAyh7NDYQApgB83iqO9AD6ABEOIA2EAPoAEQ2hDr8NhACmAH3GSv6ooS62jvQArg +BqTscphADoAAIOrFwUAQAAyx60XJQA+gARAA2hDrEdhACmAH0GSvui1AbmTVhClAb+IU8B/e8AHp +4hTwH96wAfmKEuto70AK4AaRLkIXCu42LkYX6xCwQA6AACDrRclAD6ABENoQ66DYQApgB75kr3Ev +QG5k9NuKEuto70AK4AaEKEE04hTwAA9wCajroNhAEBgMoezQ2EAKYAed4qjvQA+gARDaEOtR2EAK +YAeuZK8xihHsErBAD5gAtO1o70AKYAcJ6xCwQA6AACDrRclAD6ABENoQ65DYQApgB6JkrwIpQG5k +lIQarO/saO9AEBAMseqrtsAK4ArwZaKGK0BvwCDtELBADoAAwe1FyUAPYAvL60/SwA+gARDaEOsQ +2EAKYAeQZK68Gqzf7GjvQBAQDLHqq7bACuAK4GWq1usQ2EAQGAyh7NDYQApgB3HiqO9AD6ABEAAA +AAAAihLraO9ACuAGS+IU8CAYIAUK4v/fwA+gARDaEOuA2EAKYAd66xDYQA6AACDqsubADQACWixA +bmTD7xqsy4sS7GjvQArgCsZloq8tQG/A6A7dAi1Eb2UuMe8QsEAOgAAg70XJQA+gARCKEetI70AK +YAdxZa+cKzDlY/oO2hDrAdhACmAHYmSuAShAbmSDU4oS62jvQArgBigpQhjrELBADoAAIOtFyUAP +SAmp6UjJQA+gARDaEOsw2EAKYAdUZK3JGqyi7GjvQBAQDLHqobXACuAKo+NaVMAOCABKixErshIL +yVHImWiSB+IU8D/5MANZjhHjveVADoAAIO3iyUAQAAzB7EXJQA+gARBlLXzvELBADoAAIO9FyUAP +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 +IAS2/yAEtYAgBLWAIAS1gCAEtuIgBLWAIAS1gCAEtYAgBLWAIAS1gCAEtYAgBLbSIAS2xSAEtYAg +BLWAIAS1gCAEtYAgBLWAIAS1gCAEtYAgBLWAIAS1gCAEtYAgBLWAIAS1gCAEtYAgBLWAIAS1qSAE +tYAgBLWjIAS1oyAEtYAgBLWjIAS1oyAEtqAgBLWjAAAAAAAAAAAAAAAAIATWFiAE1hYgBNVqIATW +FiAE0jwgBNYMIATV6CAE0jwgBNI8IATSPCAE0jwgBNI8IATVTiAE1hYgBNI8IATVTiAE1hYAAAAA +AAAAAAAAAAAgBORYIATinCAE5xogBObNIATmjiAE5kkgBOYfIATi/SAE5fQgBOWtIATlTCAE5PEg +BOSjIATkeAEQGAEAAgAAARAYAQACAAAAAAAAAAAAACAFtM8gBbAkIAW0pCAFtHkgBbROIAW0OiAF +sEggBbBnIAW0ISAFsJwgBbCIIAWwSCAFsJwgBbBIIAWwSCAFsEggBbTPAAAAAAAAAAAAAAAAAAAA +ACAGBgggBf2YIAX9MCAF+eggBfSgAAAAAAAAAAAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAgBf1w +IAX9cCAF/XAgBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAg +Bf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF +/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9 +cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1w +IAX9eCAF/XAgBf1wIAX9cCAF/XggBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAg +Bf1wIAX9cCAF/XggBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAgBf1wIAX9cCAF +/XggBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAgBf1wIAX9cCAF/XggBf1wIAX9 +cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAgBf1wIAX9cCAF/XggBf1wIAX9cCAF/XAgBf14 +IAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAg +Bf1wIAX9cCAF/XAgBf1wIAX9cCAF/XggBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF +/XAgBf1wIAX9cCAF/XggBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9 +cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XggBf1w +IAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9eCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAg +Bf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF +/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9 +cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1w +IAX9cCAF/XAgBf1wIAX9cCAF/XAgBf14IAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAg +Bf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF +/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9 +cCAF/XAgBf1wIAX9cCAF/XAgBf1wIAX9cCAF/XgAAAAAAAAAAAAAAAAgBf3RIAX+LSAGAmggBgJW +IAYCOyAGAikgBgIIIAYB9iAGAdUgBgHEIAYBqSAGAZQgBgF5IAYBaCAGAU0gBf3IIAYBMiAGASEg +BgEGIAYA9CAGANkgBgDAIAYAnSAGAMAgBgCdIAYAiyAGAHAgBf3IIAX9yCAF/cggBf3IIAYAXyAF +/e0gBf3IIAX9yCAF/cggBgA+IAYAIiAGABQgBf/9IAX9yCAF/+ogBf/MIAX/uSAF/5sgBf+IIAX/ +dSAF/2IgBf9PIAX/QiAF/zAgBf8PIAX+/iAF/uMgBf7RIAX+tiAF/oAgBf5vIAX+VCAF/j8gBf4Y +AAAAAAAAAAAAAAAAIAYGZCAGBnIgBgkIIAYI2iAGCM8gBgjEIAYIuSAGCK4gBgijIAYImCAGCI0g +Bgh/IAYIcSAGCFMgBgghIAYH9SAGB+ggBgfJIAYHuyAGB60gBgeZIAYHjiAGB3UgBgdqIAYGTSAG +BzsgBgctIAYHHyAGBxQgBgcJIAYG+CAGBrwgBgauIAYGoyAGBpggBgaDAAAABQAAAAUAAAAKAAAA +CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAAIAZBPiAGQVAgBkOwIAZBPiAGQVAgBkFQ +IAZBUCAGQ7AgBkE+IAZBPiAGQT4gBkFQIAZBPiAGQT4gBkOoIAZDqCAGQ6AgBkOgIAZDmCAGQ5Ag +BkOYIAZDmAAAAAAAAAAAIAZMPCAGS0YgBkxcIAZMPCAGS0YgBktGIAZLRiAGTFwgBkw8IAZMPCAG +TDwgBktGIAZMPCAGTDwgBkxUIAZMVCAGTEwgBkxMIAZMRCAGTDQgBkxEIAZMRAAAAAAAAAAAIAZR +3yAGUGggBlH/IAZR3yAGUGggBlBoIAZQaCAGUf8gBlHfIAZR3yAGUd8gBlBoIAZR3yAGUd8gBlH3 +IAZR9yAGUe8gBlHvIAZR5yAGUdcgBlHnIAZR5wAAAAAAAAAAIAZROyAGUUwgBlInIAZROyAGUUwg +BlFMIAZRTCAGUicgBlE7IAZROyAGUTsgBlFMIAZROyAGUTsgBlIfIAZSHyAGUhcgBlIXIAZSDyAG +UgcgBlIPIAZSDwAAAAAAAAAAIAZSNyAGUWIgBlJXIAZSNyAGUWIgBlFiIAZRYiAGUlcgBlI3IAZS +NyAGUjcgBlFiIAZSNyAGUjcgBlJPIAZSTyAGUkcgBlJHIAZSPyAGUi8gBlI/IAZSPwAAAAAAAAAA +IAZRzSAGUYsgBlHDIAZRzSAGUYsgBlGLIAZRiyAGUcMgBlHNIAZRzSAGUc0gBlGLIAZRzSAGUc0g +BlG5IAZRuSAGUa8gBlGvIAZRpSAGUZsgBlGlIAZRpQAAAAAAAAAAIAZ0AiAGcpggBnRgIAZ0AiAG +cpggBnKYIAZymCAGdGAgBnQCIAZ0AiAGdAIgBnKYIAZ0AiAGdAIgBnRYIAZ0WCAGdFAgBnRQIAZ0 +SCAGc/ogBnRIIAZ0SAAAAAAAAAAAIAbg6CAG3gAgBtxUIAbZ/CAG2BggBssQIAbMaCAG1jAgBsqA +IAbY7AAAAAAAAAAAAAAqGAAAQAAAAEAAAAAAAAAAKgQAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAACAG/PYgBvzwIAb+kCAG/PYgBvzwIAb88CAG/PAgBv6QIAb89iAG +/PYgBvz2IAb88CAG/PYgBvz2IAb+iCAG/oggBv6AIAb+gCAG/nggBv5wIAb+eCAG/ngAAAAAAAAA +ACAHGIAgBxhuIAcYoCAHGIAgBxhuIAcYbiAHGG4gBxigIAcYgCAHGIAgBxiAIAcYbiAHGIAgBxiA +IAcYmCAHGJggBxiQIAcYkCAHGIggBxh4IAcYiCAHGIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl +KAMPCBKlqIOOk5IAAAAAIAckNiAHKKIgByk4IAcpJSAHKRIgByQ2IAcpJSAHJDYgBykKIAckNiAH +JDYgByj0IAcoyCAHKNAgByQ2IAckNiAHJDYgByQ2IAckNiAHJDYgByQ2IAckNiAHJDYgByQ2IAco +qiAHJ9oAAAAAAAAAACAHOzggB0HnIAdBmiAHQRYgBz2AIAc+GyAHPpggBz9QIAc/qCAHQAMgBz0r +IAdAYiAHdQIgB3TYIAd0+iAHdQIgB3TYIAd02CAHdNggB3T6IAd1AiAHdQIgB3UCIAd02CAHdQIg +B3UCIAd08iAHdPIgB3TqIAd06iAHdOIgB3TgIAd04iAHdOIAAAAAAAAAAAAAAAMAAAACAAAAAQAA +AAAAAAAEAAAAAAAAAAAAAAAAUlYAAAAAAABAJAAAAAAAAD9QYk3S8an8P/AAAAAAAAA+sMb3oLXt +jRAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyIGZvdW5kIGFkZGl0aW9uYWwgY29uZmlndXJh +dGlvbiBhZnRlciBbZmluaV0KAAAwAAAAZmNvZQAAAAB2bmljX2lkAHZsYW4AAAAAdG9zAGV0aGVy +dHlwZQAAAG1hY21hdGNoAAAAAG1wc2hpdHR5cGUAAGZyYWdtZW50YXRpb24AAABzcnZyc3JhbQAA +AABmY29lbWFzawAAAABjb21wYWN0AHBmX3ZmAAAAb3V0ZXJfdmxhbgAAZW5jYXBzdWxhdGlvbgAA +AGJhc2ljdmlydHVhbAAAAABnbGJfa2V5AGdsYnZmX2tleQAAAHBmdmZfa2V5AAAAAGlkeHZmX2tl +eQAAAHN5bm1hcGVuAAAAAHN5bjR0dXBlbmlwdjYAAABzeW4ydHVwZW5pcHY2AAAAc3luNHR1cGVu +aXB2NAAAAHN5bjJ0dXBlbmlwdjQAAABvZmRtYXBlbgAAAAB0bmxtYXBlbgAAAAB0bmxhbGxsa3AA +AABoYXNodG9lcGxpdHoAAAAAZGRwAGlzY3NpAAAAdGxzAHN0YWcAAAAAcGJsAHJxAABycXVkcAAA +AGxhbgB3YW4AY2x1c3RlcgBtYW51YWwAAHRwX3BpbwAAdHBfdG1fcGlvAAAAbmljX3ZtAABuaWNf +dW0AAG5pY191bV9pc2dsAG5pY19oYXNoZmlsdGVyAABvZmxkAAAAAHJkZHAAAAAAcmRtYWMAAABp +c2NzaV9pbml0aWF0b3JfcGR1AGlzY3NpX3RhcmdldF9wZHUAAAAAaXNjc2lfaW5pdGlhdG9yX2Zv +ZmxkAAAAaXNjc2lfdGFyZ2V0X2ZvZmxkAABmY29lX2luaXRpYXRvcgAAZmNvZV90YXJnZXQAcG9m +Y29lX2luaXRpYXRvcgAAAABwb2Zjb2VfdGFyZ2V0AAAAaXNjc2lfdDEwZGlmAAAAAGlzY3NpX2lu +aXRpYXRvcl9jbWRvZmxkAGlzY3NpX3RhcmdldF9jbWRvZmxkAAAAAHRsc2tleXMAY3J5cHRvX2xv +b2thc2lkZQAAAABwcHAAZGNieAAAAABiMmIAc29ja2V0bnVtAAAAY2VlAGllZWUAAAAAYXV0bwAA +AABhbl9kaXMAAHBkbGl0ZV9kaXMAACACoWQABAAAAAAEAAAEAAAAAAAA/wIAAAAAAAAAAAAAAAAA +AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wIAAAAAAAAAAAAAAAEAAv8CAAAAAAAA +AAAAAAAAAAL/AgAAAAAAAAAAAAAAAAAWAAAAAAAAAAAAAAAAIAbKOAAAAAAgBsmYIAbG9CAGxEwg +Bo1AIAYP5CAF9AAgBfLIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAQ78CAESVwgBElcIARJXCAE +WLggBHfgIASHsCAEkbggBDiMIAQ17CAEKUQgBLRAIAQm/CAEI+AgBfKYIAXxTCAF6kggBElcIAXp +TCAF52QgBeaQIAdrcCADskAgBATIIAb0HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +IALgBCACx4QgAtkYIALWZCAC1NQAAAAAIALSbCAC3zAAAAAAIAQajAAAAAAAAAAAAAAAACADInwg +Bu2UAAAAAAAP//MAAAAAAAAP8wAAAAAAAADzAAAAAAAAADMAAAAP/////wAAAAAAAAAAAAAAAAAP +//MAAAAAAAAP8wAAAAAAAADzAAAAAAAAADMAAAAP/////wAAAAAAAAAAAAAAAAAP//MAAAAAAAAP +8wAAAAAAAADzAAAAAAAAADMAAAAP/////wAAAAAAAAAAIAdVkCAHVMggB3+wIAdUtCAHVPQgB1Pk +IAdVdCAHU8QgB3+YIAdUoP8YMGBgAAAAAAECAwAAAAAAAAAAAAAAACAG4YggBDogIADVoAAAAAAA +AACBAAAAAAAAAAAAAAAAAAECAwICAwMAAgMFAwMFBSAECEAgBAn0IAQJhCAEChAgBAhkAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAECQAAAAAAAAAAAAAAAAAAAAAMAAAADQAAAA4AAAAPAAAA +EAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAAAAAAAQAAAAE +AAAACAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAAC +AAAABAAAAAgAAAD////////wAP///////+AA////////wAD///////+AAP///////wAA///////+ +AAD///////wAAP//////+AAA///////wAAD//////+AAAP//////wAAA//////+AAAD//////wAA +AP/////+AAAA//////wAAAD/////+AAAADAxMjM0NTY3ODlhYmNkZWZBQkNERUYAAAAAAAAAAAAA +QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0 +NTY3ODkrLwAAAAAAAAAAAAAAAAAAAAAgAGPEAAEAACAAY6gABQABIABjkAADAAUgAGNwAAcAAGOC +U2MAAAAA////////AAAAJhoLCggrMkECREADLQAAAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAA +EgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAEAAAACAAAABAAAAAgAAAAQAA +AAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAD////////wAP////// +/+AA////////wAD///////+AAP///////wAA///////+AAD///////wAAP//////+AAA///////w +AAD//////+AAAP//////wAAA//////+AAAD//////wAAAP/////+AAAA//////wAAAD/////+AAA +AAAAAAAAAAAEAAAABAAAAAgABAQIAAQECAAAAAAAAAAA//8BA/8C////AAAAAAAAAAAEBAgABAQI +AAQECAAEBAgABAQIAAdDAAAAAAAAAAAAACEACQCBAEEAIQAJACEACQCBAEEAgQBBAIEAQQCBAEEA +IQAJAIEAQQAhAAkAIQARAIEAQQCBAEEAIQAJAIEAQQAhAAkAIQAJAQEAQQCBACEAgQAhABAQYQEB +AIEBAQCBAwIBAAQAAAAAAAAAAAAAAAAAA+gAAABkAAAACgAAAAEQIEAAAAAAAAAAAAAAAAAABAAC +AAEAAIAAQAAgABAACCBAgAAAAAAAAAAAAAAAAAAgAo6EAAAAACACmggAAAAAIAKOiAAAAAEgApqs +AAAAAiACjpAAAAAEIAKOmAAAAAggAo6gAAAAECACmrQAAAAgIAKOpAAAAEAgAo6wAAAAgCACjrwA +AAEAIAKOyAAAAgAgAo7YAAAgACACjuQAAEAAIAKO8AAAgAAAAAAAAAAAAAAAKhwAACo8AAAqXAAA +KnwAACoAAAAAAwAAAAEAACoYAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBwQDCgkC +AAAAAAAAAAAAAEAAQAAQABAACAAIAAQAAgAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAKAAAADwAAAB4 +AAAAHgAAACIAAAAoAAAAMAAAADwAAABQAAAAeAAAAPAAAAAeAAAAKAAAADwAAAB4AAIAAQADAAUA +AAAEAAAAAAQCBgEFAwcAAAAAAAAAAAAAAQIDBAUGBwgICQkKCgsLAAAAIgAAADAAAAAAAAAAAAAA +AB4AAAAiAAAAKAAAADAAAAA8AAAAUAAAAHgAAADwIAblMCAG5OggBuPAIAbiYCAG4hggBuHoIAbi +SAAAAAAAAAIAAAAEAAAACABZZXMAMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6 +AAAAAG5vbmUAAAAAYWxsACoAAABkaXNhYmxlZAAAAABlbmFibGVkADB4AABOQQAAVjAAAFYxAABW +MgAAVjMAAFY0AABWNQAAVjYAAFY3AABWQQAAVkIAAFZDAABWRAAAVkUAAFZGAABWRwAAVkgAAFZJ +AABWSgAAVksAAFZMAABWTQAAVk4AAFZPAABWUAAAVlEAAFZSAABWUwAAVlQAAFZVAABWVgAAcG9y +dAAAAABwcm90b2NvbAAAAABnbG9iYWwAAGZ1bmN0aW9uAAAAAGZpbmkAAAAAcmVnAGZpbHRlck1v +ZGUAAGZpbHRlck1hc2sAAHZuaWNNb2RlAAAAAHJzc19nbGJfY29uZmlnX21vZGUAcnNzX2tleW1v +ZGUAcnNzX2dsYl9jb25maWdfb3B0aW9ucwAAc2dlX3RpbWVyX3ZhbHVlAHRzY2hfdGlja3MAAHRw +X3BtcngAdHBfcG1yeF9wYWdlc2l6ZQAAAAB0cF9wbXJ4X2ZsYWdzAAAAdHBfbnJ4Y2gAAAAAdHBf +cG10eAB0cF9wbXR4X3BhZ2VzaXplAAAAAGhtYV9zaXplAAAAAGhtYV9yZWdpb25zAHRwX3BtdHhf +ZmxhZ3MAAAB0cF9udHhjaAAAAAB0cF9tdHVzAHRwX3RjcHR1bmluZwAAAAB0cF90aW1lcnJlcwB0 +cF90aW1lcnZhbHMAAAAAdHBfYmFja29mZnZhbHMAAHNjaGVkX2lvcXR4X2JwX3ByaW9yaXR5AHBs +X3RpbWVvdXRfdmFsdWUAAAAAbWVtZnJlZV9jb25maWcAAGJhc2VfbWFjX3BmAG9mbGRfZmxhZ3MA +AG1jX21vZGVfYnJjAG1jAABudmYAd3hfY2FwcwByX2NhcHMAAG5pcWZsaW50AAAAAG5lcQBucXBj +cQAAAHRwX3NycQAAbmV0aGN0cmwAAAAAbmNyeXB0b19sb29rYXNpZGUAAABudmkAcnNzbnZpAABy +c3Nuc2VjcmV0AABuZXhhY3RmAG5yYXdmAAAAY21hc2sAAABwbWFzawAAAG5ldGhvZmxkAAAAAG5y +b3V0ZQAAbmNsaXAAAABuZmlsdGVyAG5ocGZpbHRlcgAAAG5zZXJ2ZXIAbmhhc2gAAAB0cF9sMnQA +AHRwX2RkcAAAdHBfZGRwX2lzY3NpAAAAAHRwX3Rsc19rZXkAAHRwX3Rsc19teHJ4c2l6ZQB0cF9z +dGFnAHRwX3BibAAAdHBfcnEAAABpc2NzaV9udGFzawBpc2NzaV9uc2VzcwBpc2NzaV9uY29ubl9w +ZXJfc2Vzc2lvbgBpc2NzaV9uaW5pdGlhdG9yX2luc3RhbmNlAAAAaXNjc2lfbWF4X3NnZQAAAHBw +bV9tYXhfem9uZXMAAABwcG1fem9uZV9yYW5nZTAAcHBtX3pvbmVfcmFuZ2UxAHBwbV96b25lX3Jh +bmdlMgBwcG1fem9uZV9yYW5nZTMAY29pc2NzaV9udGFyZ2V0AGNvaXNjc2lfbnRhc2sAAABmY29l +X25mY2YAAABmY29lX252bnAAAABmY29lX25zc24AAABmY29lX25mY2IAAABkY2IAZGNiX2FwcF90 +bHYAZGNiX2RjYnhfcHJvdG9jb2wAAABod20AbHdtAGR3bQBkZWJvdW5jZXRpbWUAAAAAYW5fYWVj +X3RpbWUAYWVjX3JldHJ5X2NudAAAAGZlYwB2ZXJzaW9uAGNoZWNrc3VtAAAAAFNlc3Npb25UeXBl +AE9GTWFya2VyAAAAAElGTWFya2VyAAAAAERhdGFEaWdlc3QAAEhlYWRlckRpZ2VzdAAAAABFcnJv +clJlY292ZXJ5TGV2ZWwAAEltbWVkaWF0ZURhdGEAAABEYXRhUERVSW5PcmRlcgAARGF0YVNlcXVl +bmNlSW5PcmRlcgBJbml0aWFsUjJUAABNYXhDb25uZWN0aW9ucwAATWF4UmVjdkRhdGFTZWdtZW50 +TGVuZ3RoAAAAAEluaXRpYXRvck5hbWUAAABJbml0aWF0b3JBbGlhcwAARGVmYXVsdFRpbWUyV2Fp +dAAAAABEZWZhdWx0VGltZTJSZXRhaW4AAE1heEJ1cnN0TGVuZ3RoAABGaXJzdEJ1cnN0TGVuZ3Ro +AAAAAE1heE91dHN0YW5kaW5nUjJUAAAAVGFyZ2V0TmFtZQAAVGFyZ2V0QWxpYXMAVGFyZ2V0QWRk +cmVzcwAAAFRhcmdldFBvcnRhbEdyb3VwVGFnAAAAAEF1dGhNZXRob2QAAFNlbmRUYXJnZXRzPUFs +bABDSEFQX0EAAENIQVBfSQAAQ0hBUF9DAABDSEFQX04AAENIQVBfUgAARGlzY292ZXJ5AAAATm9y +bWFsAABOb25lAAAAAENSQzMyQwAAQ1JDMzJDLE5vbmUATm9uZSxDUkMzMkMAQ0hBUAAAAABDSEFQ +LE5vbmUAAABOb25lLENIQVAAAABOb3RVbmRlcnN0b29kAAAASXJyZWxldmFudAAAUmVqZWN0AABO +bwAANQAAAENITmV0IDEuMDAAAAAAAAwAAAAAAQABfAAMAQAAAAAQAAAAFCAHmPAAAAMFDkAAAAAA +ABAAAAAoIAeb+AAAAzAOUAAAH/wAAB/8AAAf/zNQH/8zUCAHsCAgB7YQIAlNGCAJTRggCgAAIAqA +ACAKgAAgCuaAIAAAAB//LRAgCwAAIAsAMB//MGQf/xBAAA///x/84gAf/yu0H/8voAQAAAgaAAAA +gQAAAB//MCwgCwCAIAtmgB//LYgf/zBIH/8uQB//LPQf/y+wMAAAECALZsAgC2cgH/8xxB//Efwg +B7XQF5AAACAHs9QgApCAgAAABBSwAAAAAGAAIAKQkCAHtdoAACIKAACD/xWgAAAgAoAAFqAAAAhQ +AQAgoAAAP/AAACOgAAAD/wAfAMAABB//McgAAP//IAdmLCoAAAAgAs2sIAtnUCALZ5AgB2Xg3q2+ +/xrAAAAgB7TYIAKQjAAA/+ogB7XgAAAIFAAAiAAAAIAAH/8s4CAHsHAf/y1oAAAnEAAehIAAAEAA +IALpFB//LmQAEAAAH/8rKB//LoAgAoAQIAtoUCALaCDhAAAAAQAAACgAAAA4AAAA/z///zAAAHQf +/wDQIAKAQCALANAwAAAIMAAADDQAAAjQAAAADgAAAAAAiRQ7AAAINJAAACAHs+ggApD0IAeycAVd +SoAgAu9UABgAAP8H//8AOAAAADAAACALaHAgCwEQAACABwAAgAQgC2nAAAQAAAAACADhAY4AAAGR +DIAAAAAgC2mg///z/yALaVAgC2ngAAC47gAANAAAALTuAAC0/wAAtAAAALgA///wAAAIAAAAcwAD +H/8tKCACkbgAAIP9IAKQGCADHnQAAUFKAAEBbiACkHgAwAABEAAAACALagAgApHIKMAAAEAAAAIg +ApDEKKAAAIAAAAJrAAAAIAKQQCADF9QgC2ogIAMgHCALanDuAAAAA2AAACACkggD4AAAH/8soCAC +gJAf/zCw4QMGAP/f//8AAQA23////wJIAlThAv4AIAKAoAACAAD//f//AP8AAAAPQkAAmJaAAAAn +Dx//LQQAAK8AQAAAAOEBDgAAAIj3ACAAAAE/AUCBgAAAH/8XgIIAAAAgApbUDAAAACADJewf/ysk +IAsCsB//K3wgC2tAAEAAAACAAAAAAQAACAAAAB/84uQCAAAAH/8s7CALAtAgCwMgIAOOuCALA6Ag +CwNwIAtrECAD5vAf/y08AAAP/yALa4AAABAAH/8Y9AlAAAAAEAwAg//QAAP/0AAgA4roIAMx/CAA +azgf/y0cAAAP/iAAODwgADZ4IAA24A8AAAAgApRkIACXsCAClSQAEEgAIAM80CAClKggApQkIAND ++CADRqAAACAAIAtroA88AAAf/ytEIANLECAHs2AgAJF4IACU9CALBkAgAC7cIANXoAAQAjAAQQAA +AFEEACALBnAf/y3EIAsGoB//KRwf/y2ACQAAAAAAQ/8gA13YAACG3QBAD/0gA17QH/8reB//K3Af +/y0Y//P//wAADAAADAAAH/8tFAD///8gAECocQAAAB//KzggB6yAAA/8ACACjhAf/xgMH/8ZZAAA +PgBVAAAAH/8rZCALa+AgA2Qk//f//wBMS0AgA+T4IAPHeCALBuAgCwcQIAsHYCALBzAf/wKQH/8D +gCALB4AgApWQIAKVECAClPAgAGPwIAsIECAAaCQgCwgwIABlxCALbGAgCwhQIAsIsCALCQAgA90g +IAsIgCAD4pD3////IAsJMP//B/8AADAAIAsJcCALCdAf/y1QIAsKACALCkDgAAAAIAMZFCALCoAg +CwqgIAKWCAAACAYgA4s4IAOONB//LQAAAPAAIAO7vCADwOwgCwrAIAOteCALCvAf/xJcAMAAAB// +KzAgB7Qg7/////9///8gCwswIAOz8CAHs+ogC24gFJAAAEAAAAQgC26QIAtuwCALbJAgB7PgIAKQ +JCALbNAgC20wAACP/iALbYAjKBUAA/8AACALbeAgA8Nw/f///yAClgAgB7DQIAexAB//LOgf/wLw +H/8D8CACmeAf/wLQP////8////8f/wOsf///qwAAnE7//9BNAADRpP//Llwf/wLsIAKW3B//Augf +/wNQIAsLgB//LUAgA/swH/8s8CALauAgC2qgIAPypP//QAAgCwvwIAsLwCAAOLwgAGYYIAP3rAAA +F3AgApJEIAtwECALb8AgC2+gIAQG8CALb3AgC2/wIAKRtB//LNwgApIkIAsU8CALFUAf/ytQIAsV +YCALFZDhAF4AIAsVsB//KkwgB64UIAsV4B//KQThAH4ABAAAAAUAAACAAAAdgAAACoAAAAyAAAAb +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 +EDAMseoVsEAQoAH95BDYQA74D47o3eVACAAABsBAftcP6d/fwA6AAILoROtADygNnX3XD+m/38AO +gACI6ETrQA8oDZ181w/pf9/ADoAAhOhE60APKA2de9cP6f7fwA6AAYDoROtADygNnXnXD+gC2EAO ++Auf6ETrQA8oDZ1/1hAZINkoCkAPAgDoROtADygNnX7WDBkfWNMP50TrQA8oDZ191gwYILDTD+ZE +60APKA2NfNYKGR+95UTrQA8oDZ171g0YIQApGgDpROtADygNjXrWDRgfQSkqAOlE60APKA2NedYK +KEoA7N3lQA9gBIR41gfvROtADygN7XfWB+tE60APKA2tyd3qUNhADoABuOyPEUAKKAqlGiDjGx9d +Hh/ZHx7+HCHyjS/kNsBAELAB/eQQ2EAO+A+e6d3lQAgAAAgAAMBAftcP6N/fwA6AAJLpROtADygN +jX3XD+i/38AOgACY6UTrQA8oDY181w/of9/ADoAAlOlE60APKA2Ne9cP6P7fwA6AAZDpROtADygN +jXnXD+kC2EAO+AuP6UTrQA8oDY1/1g8YII8pCkDTD+lE60APKA2NftYPGB8ODwIA0w/nROtADygN +jX3WDBkgZtMP5kTrQA8oDZ181goYH3PlROtADygNjXvWDRkgtigaAOhE60APKA2detYNGR73KCoA +6ETrQA8oDZ151gopSgDs3eVAD2AElHjWB+9E60APKA3td9YH60TrQA8oDa3J3epQ2EAOgAG47OoR +QAooClsaIJkbHxMeH48fHrQcIagoIC/oMtFAEMgLkuk4wEARIA2CGSA25DfAQBFwDdItNBOpiCiA +8MDQ6BiAQA+YAJfo2efAEIAM0uk00UAQwAH9x04E3QHkENhACAAADQAAAAAAAADAQOIA2EAQoAHt +6N/fwA6AAJLpROtADygNjX3XD+i/38AOgACY6UTrQA8oDY181w/of9/ADoAAlOlE60APKA2Ne9cP +6P7fwA6AAZDpROtADygNjXnXD+kC2EAO+AuP6UTrQA8oDY1/1gwYIDbEkOlE60APKA2NftYKGB62 +50TrQA8oDY191gwZIA7TD+ZE60APKA2dfNYKGB8b5UTrQA8oDY171g0ZIF8oGgDoROtADygNnXrW +DRkeoCgqAOhE60APKA2dedYKKUoA7N3lQA9gBJR41gfvROtADygN7XfWB+tE60APKA2tyN7qUNhA +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 +IAkv3CAJMBsgCTAbIAkv3CAJL9wgCTAoIAkwKCAJL9wgCTAoIAkv3CAJMCggCTAbIAkv3CAJL9wg +CS/cIAkv3CAJL9wgCTAoIAkv3CAJL9wgCS/cIAkv3CAJL9wgCS/cIAkv3CAJMCggCTAoIAkwKCAJ +MCggCTAoIAkwKCAJL9wgCS/cIAkv3CAJL9wgCS/cIAkv3CAJL9wgCS/cIAkv3CAJL9wgCS/cIAkv +3CAJL9wgCS/cIAkv3CAJL9wgCUCoIAlAqCAJQJ0gCUCrIAlAqyAJQJUgCUCVIAlAqyAJQKsgCUCV +IAlAqyAJQKsgCUCVIAlAlSAJQJUgCUCrIAlAjSAJQJUgCUCVIAlAlSAJQJUgCUCrIAlAqyAJQKsg +CUCrIAlAqyAJQKsgCUCrIAlAqyAJQKsgCUCrIAlAqwAGIXoAAAAFAAAABAAAAAQAAAASAAAABAAA +ABsAAAAWAAAAAAAAAAEAAAABAAAAbAAAAGwACBsyAAAABgAAAAQAAAAMAAAAEQAAAAQAAAAdAAAA +FAAAAAAAAAABAAAAAQAAAHAAAABwAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAKIf8AAAAHAAAAAgAAAAIAAAARAAAABAAAAB4AAAAaAAAAAAAAAAEA +AAABAAAAdAAAAHUAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDUA +AAAACAAAAAEAAAAKAAAACAAAAAUAAAAdAAAAHQAAAAAAAAADAAAAAQAAAHgAAAB5AAw1AAAAAAgA +AAABAAAACgAAAAgAAAAFAAAAHQAAAB0AAAAAAAAAAwAAAAEAAAB4AAAAeQAAAAAAAAAAAAAAAAAA +AAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5OHAAAAAkAAAABAAAABgAAAAYAAAAC +AAAAHgAAAB4AAAAAAAAAAQAAAAEAAAB9AAAAegAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAQNmQAAAAKAAAADAAAAAkAAAARAAAABAAAAB0AAAAdAAAAAAAAAAEAAAAB +AAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwvkwAAAAkAAAABAAAACgAAABcAAAAGAAAA +HwAAABwAAAAAAAAAAQAAAAEAAABhAAAAcwAMNQAAAAAJAAAAAQAAAAoAAAAIAAAABQAAAB0AAAAd +AAAAAAAAAAMAAAABAAAAYQAAAHMADTlrAAAACgAAAAEAAAAGAAAAGgAAAA8AAAAdAAAAHQAAAAAA +AAADAAAAAQAAAGQAAABkAA27oAAAAAoAAAABAAAABgAAAAkAAAAFAAAAHQAAAB0AAAAAAAAAAwAA +AAEAAABkAAAAcQAOPdUAAAAKAAAAAQAAAAYAAAAcAAAADwAAAB0AAAAdAAAAAAAAAAMAAAABAAAA +ZgAAAHIADra+AAAACwAAAAwAAAAJAAAAGwAAAAcAAAAdAAAAHQAAAAAAAAABAAAAAQAAAGYAAAB3 +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 +AANI3AADCOQAA0jkAAMIiAADSIgAAZBUAABgHAABoNgAAZCQAAB34AAAd+QAAHf0AAB4BAAAeNgA +AHjgAAB49AAFAHgABQh4AAUTCAABlAQAAePAAAHnwAAB68AAAe/AAAHzwAAB98AAAfvAAAH/wAAB +lAwAAAAAAAAAAAAAMACf//9AAAAwCJ///0AAAZQQH/9n/wABlDQAAAAQAAGUCB//Y/8AAZQ4AAAA +EAAAEChg////AAAQLGD///8AABA0Afxf/wAAEDgB/F//AAAQQAAEAAAAABEQAP///wAAERQA//// +AAB7KAB9/+YAAHswf//u/wAAezgAAAABAAB7QH//7v8AAHwkAH3/5gAB4ogACAAAAAHmiAAIAAAA +AeqIAAgAAAAB7ogACAAAAAHyiAAIAAAAAfaIAAgAAAAB+ogACAAAAAH+iAAIAAAAAI3I////8AAA +jdD////wAAB+cH+//38AAH54f7//fwAAfgACwAAAAAGRVAH///8AAZGcAf///wAAj9gDf///AACP ++P////8ABBMUAAAABwAEEwwAAAAKAAB33AAAAAcAAHf0/////wAAeAQAAAADAAGcODnBv/kAAJAE +AAAAPgABEHgBjAYAAAEQfAGMBgAAARCIAAAAAAAAlAQACd/gAACUEAAJ3+AAAJhUAAAB/wAAmFgA +AAH/AACWCAAAAAAAAJYcAP///wAAliQA////AACWKAD///8AAJYwAP///wAA0CAAAAAPAADQJAAA +AA8AAwjYAAAAAwADSNgAAAADAAMI5AAAAAMAA0jkAAAAAwABkFAAAAD/AAGg1AAAAYMAAZCMADgA +AAABkJgAOAAAAAUAdAAAAC8ABQBwAAAALQAFCHQAAAAvAAUIcAAAAC0ABRMEAAAAPwAFEwAAAAAB +IAKa3CAI3OggAprgIAjxyCACmuwgCPDUIAKa+CAI8AAgApsEIAjvpCACmxggCO6gIAKbJCAI7ewg +Aps8IAjsgCACm0wgCOsgIAKbWCAI6gAgAptgIAjp1CACm3QgCOmoIAKbhCAI6XAgApuQIAjoTCAC +m5ggCOggIAKbrCAI5xQgApu4IAjnQCACm8QgCOboIAKb1CAI5rAgApvgIAjlBCACm+ggCOREIAKb ++CAI4zggApwEIAjiGCACnBQgCOEAIAKcJCAI39QgApw8IAjckCACnFAgCNxIIAKcYCAI3BwgApxs +IAjb8CACnHggCNsIIAKchCAI2ggAAAAAAAAAACACnIggCNm4IAKcjCAI2TggApyUIAjZACACnJwg +CNjIIAKcqCAI2JAgApysIAjYWCACnLQgCNggIAKcvCAI1+ggApzIIAjQ8CACnNwgCNewIAKc4CAI +2XAgApzoIAjXeCACnPQgCNdAIAKc/CAI1wggAp0EIAjW0CACnQwgCNOwIAKdFCAI1nwgAp0gIAjW +cCACnSggCNY4IAKdMCAI1gAgAp04IAjVyCACnUQgCNWQIAKdTCAI1VggApq0IAjRHCACnVQgCNC4 +IAKdXCAI0IAgAp1kIAjQSCACnXQgCNAQIAKdgCAIz9AgAp2QIAjPmCACnZggCM9gIAKdoCAIzygg +Ap2oIAjO/CACnbQgCM7QIAKdwCAIzpAgAp3YIAjOZCACnfQgCM44IAKeBCAIzgwgAp4UIAjN4CAC +niQgCM20IAKeNCAIzYggAp5EIAjNXCACnlQgCMzkIAKeZCAIzTAgAp50IAjMuCACnoAgCMyMIAKe +jCAIzGAgAp6YIAjMGCACnqQgCMqwIAKeqCAIyNAgAp60IAjH2CACnsggCMegIAKezCAIx2ggAp7Q +IAjHMCACntQgCMb8IAKe5CAIxpQgAp7wIAjFCCACm3wgCMV4IAKfACAIxVwAAAAAAAAAACACnwQg +CMTcIAKfDCAIxLAgAprAIAj1ACACmsggCPQgIAKarCAI82AgAprUIAjypAAADQAf/wAAH/8AGB// +EEAgCAaQH/8a+CALMpAACgAA4QQSAOEEAgDhA/4A/8H//wAQAABCBwgAAgAAAP//gO4AAPAAAAAV +AFAAAAAGAAAAAAYAABDwAPAAADAAAMAAAEAwQgABAAAAgAQAAeAAAACAwAgAAQBEIPjg//9wAP/g +gDMAAQ8PAAAAIAAAADAAAAAQAEaAAAABIAgAAAAAEQCCAAABwAAEAAAAD/9f////IAAAACALMrAQ +AAAAIAsy4AAEEwAgCzMAH/8beCALMyAf/xqgIAewcB//LVQgC4Jg4QB2ACALgdAgC4IQIAszQB// +HUAf/xzI4QGaAAABngzhAZ4AAAGerB//HUgf/xnQAAH//wABn0wAAZ+cAA9CQOEAegAgCzPQIAs0 +ICALNIAAAP//P////yALNOAgCzVQIAs1kCALNdAgCzYQIAs2UCALNpAgCzbQIAs3ECALN1Af/xr8 +IAgAUB//F8gf/xrAIAs3kCACl9AgApdw/wD//wAMAACAAAAfgAAAPx//KZQf/xJc4QDOAERERESI +iIiIzMzMzB//LXgf/xtAH/8acOEBDgAAAEAA4QCOAAAAgAAf/wDQH/8bbB//LWQAAAgAIAs4ECAL +OHAAAAsAAAAKwCALhAAgCzfQIAuDkCALg1DhAC4ABAAAAB//EoThAFYABAGAAIgAAQD/8YEAAAGA +ACAIAHAgCBc0AAASoOEBkgAAAwAAAAIAAAB/AEAAggCAAAEAAADBAMAf/xpE4QAOAB//LYD//yP/ +AADIABAgASDhAH4APAAAAP//v/9QaOhHkgAAAPAA8ADfv//7IAAABH/3//+AAAIA/v/////3/38A +AH4Y///wABABEAEgASABAAB+QBUVFRUhISEhEBAQEOEBjgAAAEGAgAAAAOD//gAgCBC0AAAIwIAA +gAAA/wD/AEAAQP//P/8gC4SwIAuE4B//GvT/D////8D//yALhHAgC4UQH/8p9B//Ghwf/y5AIAs5 +8B//HHAf/xnsAAD//YAPAAAf/ynkIAuGAOMAAgDi//8AIAs6MCAI8qQAQAAAIEAAAACAAAAggAAA +0AAAACALhUAgC4XQAAAQACACjjwf/y+gH/8rSB//KUgf/yxAH/8peB//KEAgCzygAAAoAAAAEEQA +AD//AADAAB//GnQgCzyAAAAgAOEAMgAf/xwU//AAByALiXAgC4kgIAgBcCAIAbAgCAHwH/8ZZAAA +e2Af/OIACAAAAB//KYAf/xH04QL+AOEDvgDhAz4A4QN+AOEB4gDhAJIA4QESAP//8P8f/xxAAAGc +CAABnAQAAQAF//AAAABgAAAgC4nA4QGaBOEBmgjhAZoMIAtDECALQ3AgCAJwH/8a0B//Gfgf/y18 +//D//yACk1gf/xZAAAB+TEAAAAAgC0PgIAtEQCALRKAf/xLMH/8wsB//LWgf/yjsH/8q4CALROAg +C0VgIAuM0CALRRAf/ytkH/8rFB//G0wgC0XgIAtFoB//LUAgf/4AIAuNwB//Ksgf/ypA38AAACAL +jSAgC41gH/8q1P+AAAD//+AAIAtGUCALRoAgC4ogIAeshB//GcwgApNkAAQAAB//LYQgC0bAH/8r +jB//KzAf/ysoH/8yDB//MkAf/yu0EgAAACALhrAEAAAIgQAAACALhuAgApNgH/8wXB//MlhJAAAA +IAuGQC4ANgAgB7JwAA8D/wMRAAADFQAAH/8tiCAHq3AgC0cAH/8Y5B//KJwf/xwcH/8dcCABDlwf +/8aMH//FzB//x5wf/yz8AAATiAIAghACAAIQAgAAEAAaAAAA+saI8AAAAB//K0wf/xFsH/8pIB// +EkjhAwIAIAesGAAA/98AAP/3IAtHICAIAoB///////P///5///8gC0dwIAtHQCALR6Af/xiIH/8c +KAAA+AAgApfgH/8SmAA8PDwf/xegH/8s9CAIEhQf/+P/H//n/yAHrGAgApfwH/8SjB//ERj//8f/ +H/8XzB//GaAgC4yAIAuMICALj7AgC47QIAuOUCALjiAgC0iAIAtH0CALinAgC0gQH/8aXCALi7Ag +C48gIAuLECALi2Af/xo8H/8aNCALjoAgC49QIAuPgB//KGgf/yhkIAtMkB//KZAgC00AIAgDAAAA +JxAgC00wH/8oGB//KYQf/xqAH/8afCAIAyAf/ymIIAKOpCACkXAgCANAH/8cBCALTaAf/yksH/8p +MB//KTQf/ym8H/8ptB//KWgf/ylkH/8pYB//KVwf/ylYH/8pUB//KUAf/ylEH/8pxCAIA3Af/yk8 +AABAAx//EYQf/xqoH/8oVB//LxQf/xtoAA//8CALTeAgCAQgH/8tlCALTkAf/xssIAtOkB//GwAg +C07AIAtO8CAIBDAAACWAIAtPICALT2Af/xoYH/8YqB//FgwgCARQH/8XhB//GAQgCASgH/8aFB// +GKwf/xgAIAgEqB//GkAgC1AwIAtP0B//G1j//wAAA+f8GCALUFAgCASwH/8qWCACjywf/ypU8/// +/yACjzQgAo9AIAKPTCACjxwP////IAgFACACmCAgC1CwIAgXJP//7XAgCBbE///t0CAIFUT//+9Q +IAgURCAIFTz///BQ//8AAQAB//4ABHAUAARwKAAEcCAABHA8AAD/AAAEcCwAAP+AAACNgCACkSgA +BEAkAARBwAAEQcQABEHIAARAeAAEQNwABEFAAARBRCALWdAgC1oQIAtaQCALWTAgC1lwIAtZoAAE +QXAAAEBAAARwWAAAICgAABAoAARATAAEQWAgC1rAIAta4AAAd3cAADMzIAtbICALW4AgC1uwIAtb +UCALWmAgC1qQAAQAQCALW+D//+//IAtcIAAEcGQgC1xg4QRuAAAAvwAgC1ygIAgMJCAIDBQgCAUg +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 +RkNvRSBERFAgZmFpbGVkIDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBERFAg +ZmFpbGVkIDogRGRwUmVwb3J0IDB4JXggRGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBmYWls +ZWQ6IGF2YWlsICVkCgBGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxv +d2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAFBSTEkgUnNwIHRpbWVkb3V0IDog +Zmxvd2NfaWQgMHgleCBveF9pZCAweCV4IHJ4X2lkIDB4JXggCgAAAAAAAABod19iY201NDgyX2Nm +Z21kaVsldV0gc2V0dGluZyB0eXBlICV1CgAAAAAAAAAAAABkaGNwNl90aW1lcl9jYjogcmVzZW5k +aW5nIERIQ1A2U09MSUNJVCBhZ2FpbgoAAABkaGNwNl90aW1lcl9jYjogc2VuZGluZyBESENQNlJF +UVVFU1QKAAAAAAAAAAAAAABkaGNwNl90aW1lcl9jYjogc2VuZGluZyBESENQNlJFTkVXIHJlcXVl +c3QKAAAAAABkaGNwNl90aW1lcl9jYjogc2VuZGluZyBESENQNlJFQklORCByZXF1ZXN0CgAAAABk +aGNwNl90aW1lcl9jYjogREhDUDZSRVBMWSByY3ZkLCBzdGF0ZSAldQoAAAAAAABmYWlsZWQgdG8g +cmVuZXcvcmViaW5kIGRoY3B2NiBhZGRyZXNzCgAAAAAAAAAAAAB0eXBlICV4LCB4aWQgJXgsIHR5 +cGVfeGlkICV4CgAAAGlwdjYgcHJlZmVycmVkIGFkZHIgWyUwNHggJTA0eCAlMDR4ICUwNHhdCgAA +AAAAACUwOHg6ICUwOHggJTA4eCAlMDh4ICUwOHgKAAAAAAAAY2huZXRfZmluZF9sMnRfZW50cnk6 +IGRhZGRyIFslMDh4XSwgWzB4JTA4eF0sIGxvY2FsIG5ldHdvcmsgWyVkXQoAAAAAAAAAAAAAAAAA +AABjaG5ldCBmaW5kIGwydGVudCBub3QgdmFsaWQsIDB4JXgsIGlkeCAldSwgc3RhdGUgMHgleCwg +cmV0cnkgY291bnQgJXUKAAAAAAAAAAAAAGNobmV0IGwydGVudCAweCV4LCBpZHggJXUsIHJlZmNu +dCAldQoAAAAAAAAAAAAAAGNobmV0IGwydGVudCBmaW5kIGVycgoAAAAAAAAAAAAAY2huZXRfZmlu +ZF9pcDZfbDJ0X2VudHJ5OiBmaW5kIHByZWZpeCBtYXRjaCBbJTA0eCAlMDR4ICUwNHggJTA0eF0K +AAAAAAAAAAAAAAAAAABObyByb3V0ZXIgY29uZmlndXJlZCwgbDJkZXZfZmMtPmZsb3djX2lkIDB4 +JXgKAAAKUm91dGVyIGxpZmUgJXUgZXhwaXJlZC4gZGVsZXRpbmcgcm91dGVyIFslMDR4ICUwNHgg +JTA0eCAlMDR4XQoAVXNpbmcgcm91dGVyIFslMDR4ICUwNHggJTA0eCAlMDR4XSB0byByZWFjaCBb +JTA0eCAlMDR4ICUwNHggJTA0eF0KAAAAAAAAAAAAAAAAAABjaG5ldCBmaW5kIGlwNiBsMnRlbnQg +bm90IHZhbGlkLCAweCV4LCBpZHggJXUsIHN0YXRlIDB4JXgsIHJldHJ5IGNvdW50ICV1CgAAAAAA +AGNobmV0IGwydGVudCAlMHgsIGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAAAAAAAGNobmV0IGlw +NiBsMnRlbnQgZmluZCBlcnIKAAAAAAAAc2V0X2RpZ2VzdDogQlAgYWxyZWFkeSBmYyAweCV4IGZs +YWdzIDB4JXgKAAAAAAAAc2V0X2RpZ2VzdDogY3NrIDB4JXggY29ubiAweCV4IHN0YXRlCgAAAAAA +AAAAAAAAc2V0X2RpZ2VzdDogdXBsc3VibW9kZToleCwgcGdpZHg6MHgleCwgdmFsOjB4JXggYnVm +ZmVyZWQgMHgleAoAAHNldF9kaWdlc3Q6IGJ1Zl9sbF9mbHVzaCBmYyAweCV4IG5leHRfd3IgMHgl +eAoAAG5vIHZhbGlkIGwydCBlbnRyeSBmb3IgcmVqZWN0IGNza19mYyAlcAoAAAAAAAAAAG5vIHZh +bGlkIGwydCBlbnRyeSBmb3IgYWNjZXB0IGNza19mYyAlcAoAAAAAAAAAAHRndF9jb25uX3dyOiBm +bG93LWlkOjB4JXggdHlwZToweCV4IGlzIHdyb25nIGZvciBzdWJvcDoweCV4CgAAAABpcHY2X2Fk +ZHJbMF0gMHgleCBpcHY2X2FkZHJbMV0gMHgleAoAAAAAAAAAAAAAAABhZGRyICVzIHBvcnQgJXMg +dGFnICVzCgAAAAAAAAAAAHJlZGlyZWN0IElQdjYgMHgleC0weCV4LCBwb3J0ICV4CgAAAAAAAAAA +AAAAAAAAAHJlZGlyZWN0IElQdjQgMHgleCwgcG9ydCAleAoAAAAAYXV0aGVudGljYXRlX3Rhcmdl +dDogSW5jb3JyZWN0IHBhc3N3b3JkCgAAAAAAAAAAQ0hBUF9DOiBkaWdlc3QgZXhwYW5zaW9uIGVy +cm9yCgBDSEFQX046IFRhcmdldCB1c2VyaWQgbWlzbWF0Y2gKAENIQVBfUjogZGlnZXN0IGV4cGFu +c2lvbiBlcnJvcgoAcmN2ZF9wYXJhbXM6IGVycm9yLCBsZW4gJWQKAAAAAABMb2dvdXQgZnJvbSBz +ZXNzaW9uIFsweCV4XQoAAAAAAGlTQ1NJIFNlYy1wYXJhbXMgcmVjZWl2ZWQgaGF2ZSBlcnJvcnMh +IQoAAAAAAAAAAFRhcmdldCBtb3ZlZCB0ZW1wLiBjb25uICV4LCBzZXNzICV4CgAAAAAAAAAAAAAA +AExvZ2luIEZhaWxlZCEhLiBjb25uX2ZjIFsweCV4XSwgc2Vzc19mYyBbMHgleF0sIHN0YXR1c19j +bGFzcyBbMHgleF0KAAAAAAAAAAAAAAAAUHJvdG9jb2wgRXJyb3IgY2JpdCAlZCB0Yml0ICVkIGNz +ZyAlZCBuc2cgJWQKAAAAb2ZsZF9yeF9kYXRhOiBtZW1fc2l6ZTogMHgleCwgZGxlbiBbMHgleF0s +IGFib3J0aW5nIGNvbm4gMHgleAoAAG5ldGlmX3BpbmdfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93 +Y19pZCBbMHgleF0sIGluZGV2Y3R4dCAweCV4IHN0YXRlIFslZF0gcmV0cnlfY250IFslZF0KAAAA +AAAAAG5ldGlmX3BpbmdfdGltZXJfY2I6IGwydF9pZHggJWQsIGRlbF9sMnQgJWQKAAAAAG5ldGlm +X3BpbmdfdGltZXJfY2I6IHRpbWUgMHgleCB0eXBlICVkIGNvZGUgJWQgcmV0dmFsICVkCgAAAAAA +AABuZXRpZl9waW5nX3RpbWVyX2NiOiBwaW5nX3RzIDB4JXgleCByc3BfdGltZSAweCV4JXgKAAAA +AAAAAAAAAAAAaWNtcF9sMnRfY2I6IHN1Ym9wICVkCgAAAAAAAAAAAABpY21wX2wydF9jYjogSW52 +YWxpZCBzdWJvcCAlZAoAAGwzaW42X2Rldl9jb25maWc6IGxpbmsgbG9jYWwgSVAgbm90IGFzc2ln +bmVkCgAAAGwyZGV2X2ZjIFsweCV4IF0gRmFpbGVkIHRvIHN0YXJ0IHRpbWVyIGZvciBpcHY0IGRh +ZAoAAAAAAAAAAAAAAABjaG5ldF9sMmRldl91cF9tYl9jYjogcmMgWyVkXSwgcG9ydCBbJXVdLCBz +dGF0ZSBbJXVdLCBjb29raWUgWzB4JXhdCgAAAAAAAAAAAAAAAGxvZ2luX3RpbWVkb3V0OiBCcmVh +a2luZyBwYXRoIHMgWzB4JXhdIGMgWzB4JXhdIGNzayBbMHgleF0KAAAAAAByZWNvdmVyeV90aW1l +b3V0OiBzZXNzIGlkIFsweCV4XSBpbiBsb2dvdXQKAAAAAABmb2lzY3NpOiBSZWNvdmVyeSB0aW1l +ZCBvdXQgYWZ0ZXIgWyV1XSByZXRyeSwgYmFpbGluZyBvdXQKAAAAAAAAVENQIGNvbm4gZXN0YWJs +aXNobWVudCBmYWlsZWQgJWQKAAAAAAAAAAAAAAAAAAAAZGF0YV9kZHA6IGl0YXNrLWlkOjB4JXgs +IGZsYWdzOjB4JXgsIGR4ZmVyX2xlbjolZCwgZHNlbnRfbGVuOiVkCgAAAAAAAAAAAAAAAAAAAABk +YXRhX2RkcDogdGlkIFsweCV4XSBlcnJvciBbMHgleF0KAAAAAAAAAAAAAAAAAABERFAgZXJyb3Ig +WzB4JXhdLCBhYm9ydGluZyBjb25ubiBbMHgleF0KAAAAAAAAAAByeF9kYXRhX2RkcDogUmVzcG9u +Y2UgcmVjaWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0 +aW9uIHN0YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxh +Z3MgWzB4JXhdCgA9PT4gcmVjZWl2ZWQgZGF0YSBmYyBpZCAweCV4IGZsb3djX2ljb25uX2ZsYWdz +IDB4JXggbGVuIDB4JXgKAAAAZm9pc2NzaV90YXNrIE5VTEwsIG9wOjB4JXggY3NrX2ZjaWQ6MHgl +eCBjc2tfc3RhdGU6MHgleCB0Y2JfZmNpZDoweCV4LCB0Y2Jfc3RhdGU6MHgleCAKAAAAAAAAAAAA +aWhkcjogUmVzcG9uY2UgcmVjaWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFz +ayBvciBjb25uZWN0aW9uIHN0YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgl +eF0sIGNvbm4gZmxhZ3MgWzB4JXhdCgAAAAAAAAAAaWhkcjogSW52YWxpZCB0YXNrIHN0YXRlIDB4 +JXggZm9yIHRhc2sgMHgleCwgaXR0IFsweCV4XSwgb3BjIFsweCV4XQoAAAAAAAAAAAAAAABpc2Nz +aV9oZHJfcng6IGFib3J0IGNvbm46IGZsYWdzID4+IDcgWzB4JXhdLCBoZHNnbGVuIFsweCV4XSBk +c3JfZHRsIFsweCV4XSwgbWF4X2J1cnN0IFsweCV4XQoAAABNYXggZGF0YSBsZW4gZXhjZWVkZWQg +JWQgPiAlZAoAAEludmFsaWQgb3Bjb2RlIDB4JXggaW4gY3RybCBwYXRoCgAAAAAAAAAAAAAAAAAA +AGNvaXNjc2lfZmluZF90YXNrOiB0YXNrIG5vdCBmb3VuZCB0Y2JfZmMgaWQgMHgleCBpdHQgMHgl +eCB0dHQgMHgleAoAAAAAAAAAAAAAAAAAZGF0YV9kZHA6IGl0YXNrLWlkOjB4JXgsIGZsYWdzOjB4 +JXgsIGR4ZmVyX2xlbjolZCwgZHNlbnRfbGVuOiVkCgAAAAAAAAAAAAAAAAAAAABkYXRhX2RkcDog +dGlkIFsweCV4XSBlcnJvciBbMHgleF0KAAAAAAAAAAAAAAAAAABERFAgZXJyb3IgWzB4JXhdLCBh +Ym9ydGluZyBjb25ubiBbMHgleF0KAAAAAAAAAABpc2NzaV9jbXA6IG9wYzoweCV4LCBpbiBkYXRh +IHBhdGgKAAAAAAAAAAAAAAAAAABpc2NzaV9jbXA6IFJlc3BvbmNlIHJlY2lldmVkIGZvciB0YXNr +IFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3IgY29ubmVjdGlvbiBzdGF0ZS4gdGFzayBzdGF0 +ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBjb25uIGZsYWdzIFsweCV4XQoAAABpc2NzaV9j +bXA6IEludmFsaWQgdGFzayBzdGF0ZSAweCV4IGZvciB0YXNrIDB4JXgsIGl0dCBbMHgleF0sIG9w +YyBbMHgleF0KAAAAAAAAAGlzY3NpX2hkcl9yeDogYWJvcnQgY29ubjogZmxhZ3MgPj4gNyBbMHgl +eF0sIGhkc2dsZW4gWzB4JXhdIGRzcl9kdGwgWzB4JXhdLCBtYXhfYnVyc3QgWzB4JXhdCgAAAGlz +Y3NpX2NtcDogb3BjOjB4JXgsIGluIGN0cmwgcGF0aAoAAAAAAAAAAAAAAAAAAD09PiByZWNlaXZl +ZCBkYXRhIGZjIGlkIDB4JXggZmxvd2NfaWNvbm5fZmxhZ3MgMHgleCBsZW4gMHgleAoAAABpZGF0 +YTogdGlkOjB4JXgsIG9wOjB4JXgsIGxlbjoweCV4LCBzZXE6MHgleCwgc3RhdHVzOjB4JXguCgAA +AAAATWF4IGRhdGEgbGVuIGV4Y2VlZGVkICVkID4gJWQKAABNYXggZGF0YSBsZW4gZXhjZWVkZWQg +JWQgPiAlZAoAAHJldHVybl9wZW5kaW5nX3Rhc2s6IG5vIFdSIGl0YXNrOiBpZDoweCV4LCBzdGF0 +ZToweCV4LCBjb25uOjB4JXgsIGZsYWdzOjB4JXgsIGNvbm4taWQ6MHgleCwgZGRwOiVkCgAAAAAA +AAAAAAAAAABoYW5kbGVyICV4LCBxdWV1ZWQgJXgKAAAAAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rh +c2s6IERvbmUgc2VuZGluZyB0YXNrIGVycm9yIHRvIGhvc3QKAAAAAAAAAAAAAAByZXR1cm5fcGVu +ZGluZ190YXNrOiBkZXF1ZXVlIHRhc2sgWzB4JXhdLCBzdGF0ZSBbMHgleF0gZnJvbSB0eF9saXN0 +CgAAAAAAAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IGFsbCB0YXNrcyByZXR1cm5lZCwgcmVj +b3Zlcnkgc3RhdGUgdHJhbnMgdG8gWzB4JXhdCgAAAAAAAAAAcHJvY2Vzc190eF9xdWV1ZTogdHhf +cXVldWUgZm9yIGNvbm46MHgleCBzdG9wcGVkLCBhYm9ydGluZyB0YXNrLgoAAAAAAAAAAAAAAAAA +AABXQVRDSERPR19kaXNwYXRjaCBjYXNlIHRvIGF2b2lkOiBDb3VudGVyX3dhdGNoZG9nICV1IENv +dW50ZXJfc2NoZWQgJXUgCgAAAAAAAAAAAFdBVENIRE9HOiBkZXZpY2Ugc2h1dGRvd24KAAAAAAAA +V0FUQ0hET0c6IHBvcnRbJXVdIHBhdXNlIHdhdGNoZG9nIHRpbWVvdXQKAAAAAAAAV0FUQ0hET0c6 +IGJ5cGFzcyB0aW1lb3V0CgAAAAAAAABXQVRDSERPRzogRkxSIC0gbm90IGltcGxlbWVudGVkIHll +dAoAAAAAAAAAAAAAAABXQVRDSERPRzogdGVtcGVyYXR1cmUgb2YgJWRDIGV4Y2VlZHMgdGhyZXNo +b2xkIG9mICVkQwoAAAAAAAAAAAAAZmlsdGVyOiBwb3JncmFtbWluZyB0aWQgJXUgKGxlIHRjYW0g +aW5kZXggJXUpLi4uCgAAAAAAAAAAAAAAAAAAAHdyaF9maWx0ZXI6IGl4ICVkIG5vdCBtdWx0aXBs +ZSBvZiAlZAoAAAAAAAAAAAAAAGZpbHRlcjogcmVxdWVzdGluZyBjb21wbGV0aW9uLi4uCgAAAAAA +AAAAAAAAAAAAAGh3X2NpbV90c2NoX2NoX2NsX3JhdGVfbWF4X3Jlc29sdXRpb25bJXUvJXVdOiBj +YXBwZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWlyZWQgJXUgdG8gJXU7IHJhdGUgJXUgKGVmZiAl +dSkgZGVmaWNpdF9tYXggJXUKAAAAAAAAQ2Fubm90IGdldCBjbGFzcyBbJXUvJXVdIHJhdGUvcGVy +Y2VudCAldS8ldSB3aXRoIGNvbmZpZ3VyZWQgZ3JhbnVsYXJpdGllcy4gQ2hlY2sgY29uZmlnIGZp +bGUKAAAAaHdfY2ltX3RzY2hfY2hfY2xfcmF0ZV9wZXJjZW50WyV1LyV1XTogaW5jcmVhc2VkIGRl +ZmljaXRfaW5jciBmcm9tIHJlcXVlc3RlZCAldSB0byByZXF1aXJlZCBtaW4gb2YgJXU7IHJhdGUg +JXUgKGVmZiAldSkKAAAAAAAAAABkY2J4X2llZWVfY21kaFsldV0gd3JpdGUgb25seSBwZXJtaXR0 +ZWQgb24gbG9jYWwgY29uZgoAAAAAAAAAAAAAZGNieF9pZWVlX2NtZGhbJXVdIGNhbm5vdCB3cml0 +ZSAldSBhcHBzIChNQVg6ICV1KQoAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSByZXF1 +ZXN0aW5nIERDQl9JRUVFX0NNRAoAAAAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1bmtub3duIGZlYXR1 +cmUgd3JpdGU6ICV1CgAAAGRjYnhfaWVlZV9jbWRoWyV1XSB1bmtub3duIGZlYXR1cmUgcmVhZDog +JXUKAAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIGNvbm5lY3Rpb24KAAAAAGNh +bm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIElQdjYgY29ubmVjdGlvbgoAAAAAAAAAAAAA +AAAAAABkaXNwYXRjaF9kZWZlcnJlZF9jbGFzc19jbGFzc19zaGFwaW5nWyV1OiV1XTogbGlzdF9l +bXB0eQoAAAAAAAAAbG9vcGJhY2sgYnVmZmVyIGdyb3VwWyV1XSBpcyBkaXNhYmxlZAoAAAAAAAAA +AAAAaW52YWxpZCBidWZmZXIgZ3JvdXBbJXVdIGNvbmZpZ3VyYXRpb246IG10dSAldSBsd20gJXUg +aHdtICV1IGR3bSAldQoAAAAAAAAAAAAAAABmYyAldSB2ZiAldSBnb3QgaXZmPTB4JXgscmFuZ2U6 +ICUjeC0lI3ggKCV1LyV1IHVzZWQpCgAAAAAAAAAAAAAAVkkgJXUgY2Fubm90IGdldCBSU1Mgc2xp +Y2U6IE5vIG1vcmUgc2xpY2VzIGF2YWlsYWJsZSAodXNlZCAldS8ldSkKAAAAAAAAAAAAAAAAAABw +Zm4gJXUgdmZuICV1IHdpdGggcG9ydCBtYXNrIDB4JXggY2Fubm90IGFjY2VzcyBwb3J0ICV1LCBy +ZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHZp +aWQsIHJldCAlZAoAAHBmbiAldSB2Zm4gJXUgY291bGQgbWFwIHZpaWQgIDB4JXggdG8gZmxvd2Ms +IHJldCAlZAoAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvdWxkIG5vdCBhbGxvY2F0ZSB1d2ly +ZSBmdW5jICVkIG1hYyBhZGRyLCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBmICVkLCB2ZiAlZCwg +RVJST1IgZXhjZWVkZWQgbWF4IG1hYyBsaW1pdCAlZC8lZAoAAAAAAAAAAAAAAAAAAABtaWlfaW5p +dFsldV06IGFjYXBzIDB4JXgKAAAAAAAAAG1paV9mb3JjZV9zcGVlZFsldV06IHJjYXBzIDB4JXgK +AAAAAAAAAAAAAAAAAAAAAG1paV9wZG93blsldV06IHBvd2VyZG93biBlbiAldQoAcG9ydF9jbWRf +aGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAcG9ydFsldToweCUwMng6MHgl +MDJ4XTogbDFjZmcsIGludmFsaWQgcmVxdWVzdCwgcGNhcHMgMHgleCBhY2FwcyAweCV4IG1jYXBz +IDB4JXgsIHJjYXBzIDB4JXgKAAAAUmV0dXJuaW5nIHN1Y2Nlc3MgYXMgdGhlIGxpbmsgc3RhdHVz +IHVwZGF0ZSBpcyBwZW5kaW5nCgAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2Zn +LCBwY2FwcyAlI3ggYWNhcHMgJSN4IHJjYXBzICUjeCBtY2FwcyAlI3gKAAAAAAAAAAAAcG9ydFsl +dV06IGwxY2ZnLCBGaXJlIENvZGUgRkVDIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIDEwMEcsIHJjYXBz +ICUjeAoAAAAAAAAAAAAAAABwb3J0WyV1XTogbDFjZmcsIEZFQyBpcyBub3Qgc3VwcG9ydGVkIGZv +ciB0aGlzIHNwZWVkLCByY2FwcyAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4 +JTAyeF06IGwxY2ZnLCBtZGkgaXNzdWUgcGNhcHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgK +AAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIGNhbm5vdCBmb3JjZSBuby9tdWx0 +aXBsZSBzcGVlZChzKSwgcGNhcHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgKAAAAAAAAAAAA +AAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBjYW5ub3QgZm9yY2UgbXVsdGlwbGUg +ZmVjKHMpLCBwY2FwcyAweCV4IGFjYXBzIDB4JXggcmNhcHMgMHgleAoAAHBvcnRbJXU6MHglMDJ4 +OjB4JTAyeF06IHVua25vd24gYWN0aW9uIDB4JXgKAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06 +IHVua25vd24gcmVhZCBhY3Rpb24gMHgleAoAAAAAAAAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTog +dGlkICV1IGNwbCAweCUwOHglMDh4CgAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNw +bCAweCUwOHglMDh4IDB4JTA4eCUwOHgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRp +ZCAldSBsZW4gJXUKAABGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxv +d2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAEZDT0UgQlAgV1IgRVJSOiBXUiB3 +aXRoIGNvb2tpZSAleCV4IGVycm9yZWQgYmFjayAKAAAAAAAAAAAAAAAAAABhYm9ydC9jbG9zZSBX +UiB3aXRoIGNvb2tpZSAweCVseCB3YXMgaXNzdWVkIG9uIHNzbiAweCV4IGluIHdyb25nIHN0YXRl +IDB4JXgKAAAAAGFib3J0IFdSIG9uIHNzbiAweCV4IGRpZCBub3QgZmluZCBXUiB3aXRoIGNvb2tp +ZSAweCV4JXgKAAAAAAAAAABjbG9zZSBXUiB3aXRoIGNvb2tpZSAweCVseCBvbiBzc24gMHgleDtk +aWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUgMHglbHgKAAAAAAAAAGFib3J0IFdSIG9uIHNzbiAw +eCV4IHdhcyBpc3N1ZWQgb24geGNoZyAweCV4IHdpdGggcnhfaWQgMHgleCBpbiB3cm9uZyBzdGF0 +ZSAweCV4CgAAAAAAAAAAAAAAAAAAAGRjYnhfYXBwbHlfYXBwX2NmZ1sldV1ORVcgQVBQIFRMViAK +AAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9MSU5L +VVAKAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gU0VUX0xPQ0FMX1BBUkFNRVRFUlMK +AAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfTk9fQURW +RVJUSVNFCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJF +X1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21b +JXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0ZFQVRVUkUKAAAAAAAA +AAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VUERBVEVfT1BF +Ul9WRVJTSU9OCgAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVF +Ul9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0g +RmVhdHVyZVsldV0gRkVBVFVSRV9HRVRfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFf +c21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfQ0ZHX05PVF9DT01QQVRJQkxFCgAAAAAAZGNieF9j +ZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9MT0NBTF9DRkcKAAAAAAAAAAAA +AGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0VfUEVFUl9DRkcKAAAA +AAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfRkVBVFVSRV9E +SVNBQkxFRAoAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0VS +Uk9SX0NIQU5HRQoAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9jZXNzWyV1XSByZWNlaXZlZCBCV3Mg +ZG8gbm90IGFkZCB1cCB0byAxMDAhCgAAAAAAAABXQVJOSU5HOiByZWNlaXZlZCBBcHAgVExWIGNv +bnRhaW5zIG1vcmUgdGhhbkZXIGNhbiBoYW5kbGUgKG1heDogJXU7IHRsdiBjb250YWluczogJXUK +AAAAAAAAAAAAAABkY2J4X2llZWVfcHJvY2Vzc1sldV0gc3VidHlwZSAlI3ggcmVtX2Z0X2NoYW5n +ZWQgJXUgc21fY2hhbmdlICV1CgAAAAAAAAAAAAAAAAAAAGRjYnhfaWVlZV9wcm9jZXNzWyV1XSBz +dWJ0eXBlIHVua25vd24KAAAAAAAAAAAAAGRjYnhfcGFyc2VfcGt0WyV1XSBlcnJvciAlZAoAAAAA +Y2huZXRfbDJ0X3VwZGF0ZTogbDJkZXZfZmMgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfaWQgWyV1 +XSBsMmRldl9mYy0+Zmxvd2NfZmxhZ3MgWzB4JXhdLCBpbnRmIFsweCV4XQoAAAAAAAAAAAAAAGNo +bmV0X2wydF91cGRhdGU6IGluIGRlbGF5ZWRfcHJvY2Vzc2luZywgbDJ0ZW50IFslMDh4XQoAAAAA +AAAAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBsMnQgaXA0IGVudHJ5IG5vdCBmb3VuZAoAAAAA +AAAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZV9jYWNoZTogbDJ0IGlwNiBlbnRyeSBub3QgZm91 +bmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2wydF91cGRhdGVfY2FjaGU6IGJvdGggaXA0IGFuZCBp +cDYgYWRkciBjYW5ub3QgYmUgbnVsbAoAAABjaG5ldF9sMnRfdXBkYXRlX2NhY2hlOiBsMnQgZW50 +cnkgaWR4ICV1LCBzdGF0ZSAweCV4CgAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJ0X3Vw +ZGF0ZSByZXF1ZXN0IHNlbnQgbDJ0ZW50IFslMDh4XSwgbDJ0ZW50LT5pZHggWyVkXSwgbDJ0ZW50 +LT52bGFuIFslZF0KAAAAaWNtcCBjaGVja3N1bToweCV4CgAAAAAAAAAAAAAAAABpcHY2IHRjcCBy +ZWN2LCBpbml0IHR4cSB3ciBmYWlsZWQKAAAAAAAAAAAAAAAAAABESENQdjYgcGFja2V0IHR5cGUg +JXUsIG9wdHNsZW4gJXUgcmVjZWl2ZWQKAAAAAABJbnZhbGlkIGRoY3Agc3RhdGUgJWQKAAAAAAAA +AAAAAElnbm9yZSBESENQdjYgbXNnIHhpZCAleCwgIGRoNmN0eHQtPnhpZCAleAoAAAAAAEVycm9y +IGluIERIQ1B2NiBvcHRpb25zIHBhcnNpbmcuIElnbm9yaW5nIG1zZywgaSAlZCwgb3B0c2xlbiAl +ZAoAAAAAAAAAAAAAAAAAAAAAREhDUCBmYWlsZWQsIHN0YXR1c2NvZGUgJWQuIElnbm9yaW5nIGFk +dmVydGlzZQoAaWNtcDYgY2hlY2tzdW0gdmFsaWRhdGlvbiBmYWlsZWQsIG9yIGVyciByY3ZkaWdu +b3JpbmcgaWNtcDYgbXNnICV1LCBkbGVuICV1CgAAAAB0Y3AgcmVjdiwgaW5pdCB0eHEgd3IgZmFp +bGVkCgAAAENvdWxkIG5vIGFsbG9jYXRlIHBjYiEhIEZyZWVpbmcgZmNmICEhIQoAAAAAAAAAAHZu +X3BhcnNlIHVua25vd24gc3ViY29kZSAldQoAAAAAdm5fcGFyc2UgdW5rbm93biBkdHlwZSAldQoA +AAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgcGNiIGZsb3c6JXggaW4gb2ZmbGluZSBzdGF0ZQoA +AAAAAAAAAAAAAAAAZmlwX3ZuMnZuX3JlY3ZfZXJyIAoAAAAAAAAAAAAAAABDb3VsZCBub3QgYWxs +b2NhdGUgZmxvd2MhISEhCgAAAENvdWxkIG5vdCBhbGxvY2F0ZSBTQ0IgZmxvd2MhISEhCgAAAAAA +AAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgbG9nbwoAAAAAAAAAAAAAAAAA +AGlnbm9yaW5nIGZpcCByZWN2IGZvciBmY2YgZmxvdzoleCBpbiBvZmZsaW5lIHN0YXRlCgAAAAAA +AAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGZsb2dpCgAAAAAAAAAAAAAAAABw +b3J0IDB4JXgsIHN0YXRlIDB4JXgsIHJldHJ5IG5vdCBzdXBwb3J0ZWQKAAAAAABGbG9naSByZXNw +IHJjdiB3aXRoIHVua25vd24geGNoZyBveF9pZCV4IHNpZCAlMnglMnglMnggZGlkICUyeCUyeCUy +eAoAAAAAAAAAAAAAAE5fUE9SVCAweCV4JXgleCByZWplY3RlZCBQTE9HSSB3aXRoIHJlYXNvbiBj +b2RlICV4CgAAAAAAAAAAAAAAAABBQlRTIHdoaWxlIGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19p +ZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAAAAAAAAAAAAAAAEFCVFMgZmFrZSBSc3A6 +IGxvYyAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAGxsZHBfcnhfcGt0X2hhbmRsZXJbJXVd +IGRyb3AgcHJlLWluaXQgKGNvdW50ID0gJXUpCgAAAAAAAAAAAAAAAABhcnBfcmVjdjogaXBpZCBb +MHgleF0sIGluX2FkZHIuYWRkciBbMHgleF0sIHNpcCBbMHgleF0sIHJpcCBbMHgleF0sIGFycF9v +cCBbMHgleF0KAAAAAAAAAAAAAAAAAABhcnBfcmVjdjogaW5fYXR0ci5pcHY0LmFkZHI6MHgleCwg +YWhkci5zaXA6MHgleAoAAAAAAAAAAAAAAAAAAAAAY2huZXRfYXJwX3JlY3Y6IGlwIGNvbmZsaWN0 +IGRldGVjdGVkCgAAAAAAAAAAAAAAY2huZXRfYXJwX3JlY3Y6IHBpZCBbJXVdLCB2bGFuIFsweCV4 +XSwgYXJwIG9wIFsweCV4XSwgc2lwIFsweCV4XSwgcmlwIFsweCV4XSBsMmRldl9mYy0+Zmxvd2Nf +aWQgJXggbDJkYy0+aW40X2Rldi5pbl9hZGRyLmFkZHIgJXgKAAAAAAAAAAAAAAAAAAAAJXgleCV4 +IFJlY2lldmVkIExPR08gZnJvbSAleCV4JXggCgAAAAAAAAAAAAAAAAAAQ1BMX1JYX1BLVDogSWdu +b3JpbmcgTU9QIG9yIEVPUCBmcmFtZXMKAAAAAAAAAAAARmFpbGVkIHRvIHBvc3QgeGNoZyBlcnI6 +IHNzbmkgMHgleCBjb29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAG9mbGRfYWJvcnRfcmVxX25l +Z2FkdlsldV06IHdyIDB4JTA4eCBjcGxfYWJvcnRfcmVxIERFTElWRVJFRAoAAABob3N0X3dyWyV1 +XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgc3RhdHVzIDB4JXgKAAAAAAAAAAAAAAAAAAAAcGt0 +c2NoZWRfY2xfcmxbJXU6JXVdOiBtb2RlIHwgdW5pdCB8IHJhdGUgMHglMDZ4IG1pbiAldSBtYXgg +JXUgcGt0c2l6ZSAldQoAAAAAAABwZiAlZCwgdmYgJWQgc2VjcmV0IGtleV9pbmRleCAlZCwgVkYg +c2VjcmV0IDB4JXgKAAAAAAAAAAAAAAAAAAAAcGFyYW1fY2huZXRbMHgleDoweCV4XTogY2huZXQg +MHgleCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAHBhcmFtX2RtYXFbMHgleDoweCV4XTog +ZG1hcSAweCV4IHJlYWQgJXUgcGYgJXUgcmV0ICVkCgAAAAAAAAAAAABSU1NTRUNSRVRLRVk6IHJz +c3NlY3JldCB0YmwgYmFzZSAlZCwgcnNzbnNlY3JldCAlZAoAAAAAAAAAAAAAAAAATUNbJXVdIGlu +aXRfc3RhdGVfbWFjaGluZSAweCUwMngKAAAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24g +bm90IGNvbXBsZXRpbmcsIE1DIGN1cnJlbnQgaW5pdCBzdGF0ZSBpcyAweCUwMngKAAAAAAAAAAAA +AAAAAABJbml0aWFsaXppbmcgSUJNIEREUjM0TE1DCgAAAAAAAEREUiBpbml0IGNvbXBsZXRlLCBi +ZWdpbm5pbmcgY2FsaWJyYXRpb24KAAAAAAAAAEREUiBjYWxpYnJhdGlvbiBzdWNjZWVkZWQKAAAA +AAAATUNbJXVdIF9od19tY19pbml0X21jCgAAAAAAAAAAAABfaHdfbWNfaW5pdF9tYzogZXJyb3Is +IHJldCAlZAoAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9yIHBoeSBmdyBmaWxl +LCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1cGxlOiB0dXBsZSAldSBub3Qgc3BlY2lm +aWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5n +c193OiB0aW1lcl9ycyAldXVzIHRpbWVzdGFtcF9yZXMgJXV1cyBkZWxheWVkYWNrX3JlcyAldXVz +CgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGRhY2tfdGltZXIgJXV1cyBtc2wgJXV1cyByeHRf +bWluLG1heCAldSwldXVzIHBlcnNfbWluLG1heCAldSwldXVzCgAAAAAAAAAAaHdfdHBfdGNwX3Nl +dHRpbmdzX3c6IGtlZXBfaWRsZSxpbnR2bCAldSwldXMgbWF4cnR0ICV1dXMgaW5pdHNydHQgJXV1 +cyBmaW53YWl0Ml90aW1lciAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcg +ZGFja190aW1lciBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBj +YXBwaW5nIG1zbCBmcm9tICV1IHRvICV1AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4 +dF9taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2Fw +cGluZyByeHRfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdz +X3c6IGNhcHBpbmcgcGVyc19taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9z +ZXR0aW5nc193OiBjYXBwaW5nIHBlcnNfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190 +cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBrZWVwX2lkbGUgZnJvbSAldSB0byAldQAAAAAAAAAA +AAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcga2VlcF9pbnR2bCBmcm9tICV1IHRvICV1 +AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGluaXRfc3J0dF9tYXhydHQg +ZnJvbSAldSB0byAldQAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRf +aW5pdHNydHQgZnJvbSAldSB0byAldQAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZmlu +d2FpdDJfdGltZXIgZnJvbSAldSB0byAldQAAAAAAAEhNQSBpcyBzdXBwb3J0ZWQgb25seSB3aGVu +IGV4dGVybmFsIG1lbW9yeSBpcyBub3QgcHJlc2VudAoAAAAAAABmaWx0ZXJNb2RlPSUjeCBpbGxl +Z2FsOiBzZWxlY3RzICVkIGJpdHMgKG1heCAlZCkKAAAAAAAAAAAAAAAAAAAAbGUgY29uZmlndXJh +dGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNl +cnZlciAldSBoYXNoICV1CgAAAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogbmVudHJpZXMgJXUg +Y2xpcCAldSBub3JtYWwgZmlsdGVyICV1IGhpIHByaW9yaXR5IGZpbHRlciAldSBzZXJ2ZXIgJXUg +YWN0aXZlICV1IGhhc2ggJXUgbnNlcnZlcnNyYW0gJXUKAAAAAAAAAABod19zZ2VfcXVldWVfYmFz +ZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgZWdyZXNzIHF1ZXVlcywgJXUKAAAAAAAAAAAA +AAAAAAAAAGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdy +ZXNzIHF1ZXVlcyB3aXRoIGZyZWVsaXN0IGFuZCBpbnRlcnJ1cHQsICV1CgAAAGh3X3NnZV9xdWV1 +ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1ZXVlcywgJXUKAAAA +AAAAAAAAAAAAAAAARXJyb3IsIFRvdGFsIFJTUyBTZWNyZXQgdGFibGUgYWxsb2NhdGlvbiAlZCA+ +IDE2CgAAAAAAAAAAAAAAAAAAAGNmX3BhcnNlOiBmaWxlIG1lbXR5cGUgMHgleCBtZW1hZGRyIDB4 +JXggbWFwcGVkIEAgJXA6CgAAAAAAAAAAAABjb25maWd1cmVkIHdpdGggY2FwcyBuYm18bGluayAw +eCUwOHggc3dpdGNofG5pYyAweCUwOHggdG9lfHJkbWEgMHglMDh4IGlzY3NpfGNyeXB0byAweCUw +OHggZmNvZToweCV4CgAAAAAAAAAAAAAAbmV0IFZJIGFsbG9jYXRpb24gZmFpbGVkIGZvciBmY19p +ZCAldSB3aXRoIGVycm9yICVkCgAAAAAAAAAAAAAAAG5ldCBWSSBtYWMgYWRkcmVzcyBwcm9ncmFt +bWluZyBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAAbmV0 +IFZJIHJ4bW9kZSBwcm9ncmFtbWluZyBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQK +AAAAAG5ldCBWSSByc3MgaW5kaXJlY3Rpb24gdGFibGUgcHJvZ3JhbW1pbmcgZm9yIGZjX2lkICV1 +IGZhaWxlZCB3aXRoIGVycm9yICVkCgAAAAAAbmV0IFZJIHJzcyBjb25maWcgY29tbWFuZCBmYWls +ZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAG5ldCBWSSBjb21tYW5kIGZhaWxlZCBm +b3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAAAAAABpc2NzaSBlZHJhbSBzdGFy +dCAleCBlbmQgJXgKAAAAAGZvaXNjc2lfaW5pdDogaW5pdF9kb25lOiV1LCBmb2lzY3NpX250YXNr +czoldSwgZm9pc2NzaV9uc2VzczoldSwgbmNzb2NrOiV1LCBuc3BvcnRzOiV1LCBmb2lzY3NpX25p +bml0OiV1LCByYzolZAoAAAAAAAAAAAAAAAAAAAAAY2hfY2xfcmF0ZVsldS8ldV06IGNhcHBlZCBj +bGFzcyByYXRlIGZyb20gcmVxdWVzdGVkICV1IHRvIGNvbmZpZ3VyZWQgKGVmZmVjdGl2ZSkgY2hh +bm5lbCByYXRlICV1CgAAAAAAAAAAAAAAAAAAAENhbm5vdCBnZXQgY2xhc3MgWyV1LyV1XSByYXRl +ICV1IHdpdGggY29uZmlndXJlZCBncmFudWxhcml0aWVzLiBDaGVjayBjb25maWcgZmlsZQoAAAAA +AAAAAAAAAAAAAGNoX2NsX3JhdGVbJXUvJXVdOiBpbmNyZWFzZWQgZGVmaWNpdF9pbmNyIGZyb20g +cmVxdWVzdGVkICV1IHRvIHJlcXVpcmVkIG1pbiBvZiAldTsgcmF0ZSAldSAoZWZmICV1KSBkZWZp +Y2l0X21heCAldQoAAAAAAAAAAAAAAAAAY2hfY2xfcmF0ZVsldS8ldV06IHRpY2sgJWQvJWQsIGRl +ZmljaXRfaW5jciAlZCwgZWZmICVkCgAAAAAAAAAAAHBrdHNjaGVkIGNoYW5uZWwgJXUgc2V0cyBz +cGVlZCAoZnJvbSAldSkgdG8gJXUga2JwcwoAAAAAAAAAAAAAAABuZXRfbDJkZXZfbm90aWZ5OiBw +Z2lkIFsweCV4XSwgcHJpbyBbMHgleF0sIGNoIFsweCV4XQoAAAAAAAAAAAAAWyV1XSB1bmFibGUg +dG8gZXhlY3V0ZSBpbnRlcm5hbCBEQ0JfSUVFRV9DTUQKAAAAcG9ydFsldV0gbGluayBkb3duICgl +dSkgKGxzdGF0dXMgJSN4KQoAAAAAAAAAAAAAcG9ydF9yZXNldFsldV06IGZvcmNpbmcgZm9yIHB0 +eXBlIDB4JXgsIHNwZWVkIDB4JXgKAAAAAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVzZWQgYnkgbW9k +dWxlIHVucGx1ZwoAAAAAAAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5kICVwIGZvciBw +b3J0ICV1LCB3YW50IHRvIHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0g +dXBkYXRlIChmbG93Y2lkICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRfbG9vcGJhY2sg +cG9ydCAlI3ggY3VycmVudCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHNw +ZWVkIHVwZGF0ZTogJSN4CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNlCgAAAABRU0ZQ +IG1vZHVsZSB1bnBsdWcgLSByZWluaXRpYWxpemluZyByeF9sb3MgIHRvIDB4ZmYKAAAAAAAAAAAA +AAAAZ3Bpb19xc2ZwX21vZHVsZV91cGRhdGU6IGNoYW5nZWQgcnhfbG9zIGZyb20gMHgleCB0byAw +eCV4CgAAAAAAAGdwaW9fcXNmcF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHR4X2RpcyBmcm9tIDB4 +JXggdG8gMHgleAoAAAAAAABkaXNhYmxpbmcgdHggJSN4IHJ4ICUjeAoAAAAAAAAAAHBvcnRfbGlu +a19zdGF0ZV9oYW5kbGVyWyV1XSBwb3dlcmluZyBkb3duCgAAAAAAAHBvcnRfbGlua19zdGF0ZV9o +YW5kbGVyWyV1XSBwb3dlcmluZyB1cAoAAAAAAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1 +XSB1bmtub3duIHN0YXRlIChzdGF0ZSA9ICUjeCkKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFu +ZGxlcjogU29tZXRoaW5nIHdlbnQgdGVycmlibHkgd3JvbmcuIHJldCA9ICVkCgAAAAAAAAAAAAAA +AAAAAGxlIGNvbmZpZ3VyYXRpb246IGhhc2ggcmVnaW9uIHRvbyBsYXJnZSB0byBlbmFibGUgc2Vy +dmVyIHNyYW0KAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAl +dSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBpbml0 +aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2VydmVy +ICV1IGFjdGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBfaW5p +dDogdGNiIHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2 +TUIgb2YgTUEgbWVtb3J5CgAAAAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lvbiAo +c3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVtb3J5 +CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBub3Qg +Y29tcGxldGUKAAAAAAAAAAAAAGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgleAoA +AAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50ZXJu +YWwgYnVmbGw2NCBidWZmZXJzCgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdoIG1l +bW9yeSB0byBhbGxvY2F0ZSBidWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjogbm90 +IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9i +dWY6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAldSB0 +cnlpbmcgdG8gdXNlICV1IGF2YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbWVtX2luaXQ6IEVE +QyBvdmVyY29tbWl0dGVkIGJ5ICVkIGJ5dGVzCgAAAAAAAAAAbWVtX2luaXQ6IG5vdCBlbm91Z2gg +bWVtb3J5IHRvIGFsbG9jYXRlIGZsb3cgdGFibGUKAAAAAAAAAAAAAAAAAGN4Y25pY19kZXZpY2Vf +aW5pdDogY3hjbmljIFsweCUweF0sIGN4Y25pYy0+ZmlsdGVyIFslMHhdCgAAAAAAAABwb2Zjb2Ug +aW5pdCBkb25lCgAAAAAAAAAAAAAAAAAAAHBvcnRfaW5pdFsldV0gcHR5cGUgMHgleAoAAAAAAAAA +UG9ydFsldV06IFVua25vd24gU0dNSUkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAAAAUG9ydFsldV06 +IFVua25vd24gQlRfWEZJIHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAcG9ydF9pbml0WyV1XTogcG9y +dCB0eXBlIDB4JXggaXMgbm90IHN1cHBvcnRlZAoAbXBhcnRpdGlvbl9pbml0OiBkZHBfaXNjc2kg +MHgleCBpc2NzaV9wcG9kX2VkcmFtX2ZsYWcgMHgleAoAAAAAAG1wYXJ0aXRpb25faW5pdDogbW92 +ZWQgcG1yeF9zdGFydCBmcm9tIDB4JTA4eCB0byAweCUwOHggdG8gbWFrZSByb29tIGZvciBMRSBI +QVNIIGFuZC9vciBUUCBUQ0JzCgAAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX2luaXQ6IG1vdmVk +IHBtcnhfc3RhcnQgZnJvbSAweCUwOHggdG8gMHglMDh4IChFRFJBTSkKAAAAAAAAAAAAAAAAAAAA +AEVRIHBmbiAldSB2Zm4gJXU6IGRlc3Ryb3lpbmcgZXFpZCAldSB3aXRoIHBlbmRpbmcgV1Iocykg +KG51bV9ieXRlcyAldSBhbmQgZmxhZ3MgMHglMDh4CgAAAAAAAAAAAEFoIGhhLi4uZG91YmxlIGZy +ZWUgb3hfaWQgMHgleCwgcnhfaWQgMHgleAoAAAAAAEhvc3QgUFJMSSBSZXNwb25zZSB0aW1lZG91 +dDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAAAAAAAABGQ29FIEREUCBpbml0OiBmY29l +IGxsaW1pdCAweCV4LCBmY29lIHVsaW1pdCAweCV4IGdibCBsbGltaXQgMHgleCBnYmwgdWxpbWl0 +IDB4JXggcGNic3ogJXgKAAAAAABGQ29FIEREUCBpbml0OiBmY29lIHBwb2Qgb2ZmIDB4JXgsIGZj +b2Ugc3QgcHBvZCBhZGRyIDB4JXggZmNvZSBudW0gcHBvZHMgMHgleAoAAHRsc19rZXlfc3RhcnQ6 +MHgleCwgdGxzX2tleV9zaXplOiVkCgAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fb3RoZXJzOiBzdGFy +dCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KSwgaG1hICV1CgAAAABtcGFydGl0aW9uX290aGVy +czogX206JXggX3NpemU6JWxkIGRldi50cC50bHNfa2V5X3NpemU6JWxkIAoAAAAAbXBhcnRpdGlv +bl9vdGhlcnM6IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpCgAAAAAAAAAAAAAAAGNt +ZGhfYnllWyV1OiV1XTogVW5yZWdpc3RlcmluZyBITUEKAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4g +JXUgdmlhIGNvbW1hbmQKAAAAAAAAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRyX29w +IDB4JXggcmVnIDB4JXggZGlmZiAldSBjb250ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoAAAAAAAAA +AAAAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4 +IGRpZmYgJXUgZHBvcyAldSBjb250ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoAAAAAAAAAAAAAAAAA +AGkyYyB0cmFuc2FjdGlvbiBmYWlsZWQgdG8gY29tcGxldGUKAAAAAAAAAAAAAAAAAGNvbmZpZ3Vy +YXRpb24gZmlsZSBwYXJzZXI6IGFlY19yZXRyeV9jbnQgdmFsdWUgJWQgaXMgbm90IHdpdGhpbiB0 +aGUgYWxsb3dlZCBsaW1pdCBvZiAxIHRvIDI1NC5EaXNhYmxpbmcgaXQuCgAAAABmZWMgb3B0aW9u +IGluIGNvbmZpZyBmaWxlIGlzIGRlcHJlY2F0ZWQKAAAAAAAAAABjb25maWd1cmF0aW9uIGZpbGUg +cGFyc2VyOiBhbl9hZWNfdGltZSB2YWx1ZSAlZCBpcyBiaWdnZXIgdGhhbiBhbGxvd2VkIGxpbWl0 +LkNoYW5naW5nIGl0IHRvIDEwMDAwIG1zLgoAAAAAAAAAAAAARGVwcmVjYXRlZCBjb25maWcgb3B0 +aW9uIGZvdW5kIGluIGNvbmZpZyBmaWxlLiBJZ25vcmluZy4uCgAAAAAAAGNvbmZpZ3VyYXRpb24g +ZmlsZSBwYXJzZXI6IHBsIHRpbWVvdXQgdmFsdWUgaXMgdG9vIGxhcmdlLCBjaGFuZ2luZyBmcm9t +ICV1IHRvICV1dXNlY3MKAAAAAAAAAAAAAHNjaGVkX2lvcXR4X2JwX3ByaW9yaXR5OiBoYXMgJXUg +ZW50cmllcyBvbmx5LCByZXF1aXJlcyAldSBlbnRyaWVzCgAAAAAAAAAAAAAAAAAAdHBfYmFja29m +ZjogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50cmllcwoAAAAAdHBfdGltZXJ2YWxzOiBwYXJz +ZWQgJWQgaW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAdHBfdGltZXJyZXM6IHBhcnNlZCAlZCBpbnN0 +ZWFkIG9mICV1IGVudHJpZXMKAAAAdHBfbXR1cyBoYXMgJXUgZW50cmllcyBvbmx5LCByZXF1aXJl +cyAldSBlbnRyaWVzCgAAAAAAAAAAAAAAAAAAAHRwX210dXNbJXVdIGlzICV1IGJ5dGVzIHdoaWNo +IGlzIG5vdCBzdXBwb3J0ZWQKAGh3X2NpbV90c2NoX3RpY2tfaW5pdDogVElDSyVkLCB2YWx1ZSAw +eCV4LCByYXRlICV1IGticHMKAAAAAAAAAABpbnZhbGlkIHRpY2sgZ3JhbnVsYXJpdHkgJXUga2Jw +cyBvciBncmFudWxhcml0eSB2YWwgbXVzdCBiZSA8ICV1LCBjaGFuZ2VkIHRvICV1CgAAAAAAAAAA +AAAAAAAAAABUaWNrIGdyYW51bGFyaXRpZXMgJXVrYnBzCgAAAAAAAGNvbmZpZ3VyYXRpb24gZmls +ZSBwYXJzZXI6IHNnZSB0aW1lciB2YWx1ZVslZF0gaXMgdG9vIGxhcmdlLCBjaGFuZ2luZyBmcm9t +ICV1IHRvICV1dXNlY3MKAAAAAAAAAGZpbHRlcm1hc2sgMHgleCBpcyBub3QgZXF1YWwvc3Vic2V0 +IHRvL29mIGZpbHRlcm1vZGUKAAAAAAAAAAAAAABjb25maWdfaG1hX29mZnNldF90YWJsZTogRWFj +aCByZWdpb24gbmVlZHMgdG8gaGF2ZSBtdWx0aXBsZSBvZiA4IHBhZ2VzCgAAAAAAAAAAAGNvbmZp +Z19obWFfb2Zmc2V0X3RhYmxlWyV1OiV1XTogcmVnaW9uWyV1XTogcGFnZV9zaXplICV1LCB0b3Rh +bCBzaXplICV1LCBiYXNlIDB4JXgKAAAAAAAAAAAAAAAAAGNvbmZpZ19obWFfb2Zmc2V0X3RhYmxl +OiBITUEgdGFibGUgd3JpdGUgZmFpbGVkICVkCgAAAAAAAAAAAAAAAABjbWRoX2htYV9jbWQ6IEhN +QSBub3QgZW5hYmxlZCBpbiB0aGUgY29uZmlnIGZpbGUgKGhtYV9zaXplPVggaW4gTUJzKQoAAAAA +AAAAAAAAAGNtZGhfaG1hX2NtZDogSG9zdCBtZW1vcnkgc2hvdWxkIGJlIGF0bGVhc3QgMU1CCgAA +AAAAAAAAAAAAAAAAAABjbWRoX2htYV9jbWQ6IHBhZ2Ugc2l6ZSBzaG91bGQgYmUgcG93ZXIgb2Yg +MgoAAABjbWRoX2htYV9jbWQ6IEhvc3QgbWVtb3J5IGFscmVhZHkgcmVnaXN0ZXJlZAoAAABjbWRo +X2htYV9jbWRbJXU6JXVdOiBtb2RlICVkIEhNQSBzaXplICV1CgAAAAAAAABjbWRoX2htYV9jbWQ6 +IE9ubHkgJXUgcmVnaW9ucyBzdXBwb3J0ZWQKAAAAAAAAAABjbWRoX2htYV9jbWQ6IE9ubHkgJXUg +cGFnZXMgc3VwcG9ydGVkCgAAAAAAAAAAAABjbGlwIGVudHJ5IGRlbGV0aW9uIGZhaWxlZCBhdCBw +b3MgJXUsIHJldCAlZAoAAABod19sZV9jbGlwX2hhbmRsZXI6IHJlbW92ZWQgcG9zPSV1ICg9aWR4 +ICV1KQoAAABod19sZV9jbGlwX2hhbmRsZXI6IGFkZGluZyB0byBwb3M9JXUgKD1pZHggJXUpCgBw +aHlfaW5pdDogcG9ydCAldSB3aXRoIHRoZSB0eXBlICV1ICBoYXZlIHJldCAlZAoAAAAAAAAAAAAA +AAAAAAAAaHdfbWFjX2FlY19jb21wbGV0ZVsldV0gb24gbGFuZXMgJSN4IChzaWdkZXQgJSN4KSwg +dHhfbGFuZXMgJSN4CgAAAAAAAAAAAAAAAAAAAABod19tYWNfbXRpcF9lbmFibGVbJXVdOiBwdHlw +ZSAweCV4LCBzcGVlZCAweCV4LCBmZWMgMHgleCwgYW4gJWQKAAAAAAAAAAAAAAAAAAAAAGNvbnNv +cnRpdW1fZmVjWyV1XTogbG9jYWwgMHgleCwgcmVtb3RlIDB4JXgsIG5lZ290aWF0ZWQgMHgleAoA +AABod19tYWNfaW5pdF9wb3J0WyV1XSwgcHR5cGUgMHgleCwgc3BlZWQgMHgleCwgbGFuZXMgMHgl +eCwgZmVjIDB4JXgKAAAAAAAAAAAAAAAAAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIGluc2VydGVk +IGFuZCByZWFkeQoAAAAAAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIHJlbW92ZWQKAAAAAAAAAAAA +AAAAAAAAAG1vZHVsZVsldV06IHVua25vd24gbW9kdWxlIGlkZW50aWZpZXIgMHglMDJ4CgAAAG1v +ZHVsZVsldV06IGV4Y2VwdGlvbiBjYWJsZSBmZWMgYWJpbGl0eSBvZiBwb3J0IDB4JXgsIG9mIGNh +YmxlIDB4JXgKAAAAAAAAAAAAAAAAbW9kdWxlWyV1XTogdW5zcGVjaWZpZWQgZXh0ZW5kZWQgY29t +cGxpYW5jZSBjb2RlIDB4JTAyeAoAAAAAAAAAAG1vZHVsZVsldV06IGZlYyBhYmlsaXR5IG9mIGNh +YmxlIDB4JXgKAAAAAAAAAAAAAG1vZHVsZVsldV06IERpc2FibGluZyBmZWMgKDB4JXgpIGFzIGl0 +IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHBvcnQKAAAAAAAAAAAAAAAAbW9kdWxlWyV1XTogZ3Bp +byAldSB2ZW5kb3IgaWQgJTA2eCwgaWRlbnRpZmllciAweCUwMngsIFNGUDI4KGJ5dGUgMzYvMTky +KSAweCUwMngsIFNGUChieXRlIDMvMTMxKSAweCUwMngsIDFHIChieXRlIDYpIDB4JTAyeAoAAABv +cHRpY2FsIGxlbmd0aChieXRlIDE1LzE0MikgJXUsIGNvcHBlciBjYWJsZShieXRlIDgvMTQ3KSAw +eCUwMngsIGxlbmd0aChieXRlIDE4LzE0NikgJXUsIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAAcG9y +dCBpbml0aWFsaXphdGlvbiBmYWlsZWQKAAAAAABtb2R1bGVbJXVdOiBncGlvICV1IHZlbmRvciBp +ZCAlMDZ4LCBpZGVudGlmaWVyIDB4JTAyeCwgU0ZQMjgoYnl0ZSAzNi8xOTIpIDB4JTAyeCwgU0ZQ +KGJ5dGUgMy8xMzEpIDB4JTAyeCwgMUcgKGJ5dGUgNikgMHglMDJ4CgAAAG9wdGljYWwgbGVuZ3Ro +KGJ5dGUgMTUvMTQyKSAldSwgY29wcGVyIGNhYmxlKGJ5dGUgOC8xNDcpIDB4JTAyeCwgbGVuZ3Ro +KGJ5dGUgMTgvMTQ2KSAldSwgbW9kdWxlX3R5cGUgMHglMDJ4CgAAAABjeDRfY3JfbW9kdWxlX3J4 +X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgBJSS4xLmJ4IGRwMThbJXVdIHFbJXVdICUj +eCAlI3ggJSN4ICUjeCBtaW4gJSN4IG1heCAlI3gKAAAAAAAAAAAASUkuMS5jLWQuICUjeCAlI3gg +JSN4ICUjeCBhbGwgICUjeAoAAAAAAAAAAAAAAAAASUkuMi5iICglI3ggLSAlI3ggKyAlI3gpICUg +MTI4ID0gJSN4CgAAAAAAAAAAAAAASUkuMyBpbmV3XzFlIGFmdGVyIGxpbWl0IGNvbXB1dGUgaXRl +bXBfMWUgJXgsIGluZXdfMWUgJXgKAAAAAAAAAElJLjMuIGl0ZW1wXzFlICUjeCBpbmV3XzFlICUj +eCBpbmV3XzFlICVkCgAAAAAAAElJLjQuIHNldF8xZSAlI3gKAAAAAAAAAAAAAAAAAAAATUM6IEVy +cmF0YTE5IERRUyBBbGlnbiBjYWxpYnJhdGlvbiBGQUlMRUQKAAAAAAAATUM6IEVycmF0YTE5IFJE +Q0xLIEFsaWduIGNhbGlicmF0aW9uIEZBSUxFRAoAAAAAdGVtcDJfMWUrMHgxMCA9ICUjeAoAAAAA +AAAAAAAAAABJVi4xLiBkcDE4WyV1XSBwaGFzZV9zZWwgYmVmb3JlICUjeCBhZnRlciAlI3gsIGdh +dGVfZGVsYXkgJSN4CgAATUMgZXJyYXRhMTkgaXNzdWUxOiBkcDE4ICV1IHF1YWQgJXUKAAAAAAAA +AAAAAAAATUMgZXJyYXRhMTkgaXNzdWUyOiBkcDE4ICV1IHF1YWQgJXUKAAAAAAAAAAAAAAAATUMg +ZXJyYXRhMTkgaXNzdWUzOiBkcDE4ICV1IHF1YWQgJXUKAAAAAAAAAAAAAAAATUMgZXJyYXRhMTkg +aXNzdWU0OiBkcDE4ICV1IHF1YWQgJXUKAAAAAAAAAAAAAAAATUMgY2FsaWJyYXRpb24gRkFJTEVE +OiBERklfSU5JVF9DT01QTEVURSBub3QgYmVjb21pbmcgMAoAAAAAAAAAAE1DIGNhbGlicmF0aW9u +IEZBSUxFRDogREZJX0lOSVRfQ09NUExFVEUgbm90IGJlY29taW5nIDEKAAAAAAAAAABNQyBjYWxp +YnJhdGlvbiBGQUlMRUQ6IElOSVRfQ0FMX0NPTVBMRVRFIG5vdCBiZWNvbWluZyAxCgAAAAAAAAAA +TUMgY2FsaWJyYXRpb24gRkFJTEVEOiBQQ19JTklUX0NBTF9FUlJPUiBpcyAweCV4CgAAAAAAAAAA +AAAAAAAAAEREUiBpbml0IGNvbXBsZXRlLCBCZWdpbm5pbmcgY2FsaWJyYXRpb24KAAAAAAAAAE1D +OiBJbml0aWFsIENhbGlicmF0aW9uIEZBSUxFRAoATUM6IEluaXRpYWwgQ2FsaWJyYXRpb24gUEFT +U0VECgBNQzogRXJyYXRhMTkgVGFzayBGQUlMRUQKAAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIGZh +aWxlZDogRGlkbid0IGdldCBhbGwgRFAxOHMgbG9ja2VkCgAAAAAAAAAAAABNQyBpbml0aWFsaXph +dGlvbiBmYWlsZWQ6IERpZG4ndCBnZXQgYm90aCBBRFJzIGxvY2tlZAoAAAAAAAAAAAAATUMgaW5p +dGlhbGl6YXRpb24gZmFpbGVkOiBTTEVXX0RPTkVfU1RBVFVTIG5ldmVyIHRvZ2dsZWQAAAAAAAAA +AHBmbiAldSB2Zm4gJXUgRlNNIHN0YXJ0CgAAAAAAAAAAcGZuICV1IHZmbiAldSBGU00gY29tcGxl +dGUKAAAAAABmbHJfcGZ2Zl9mc21bJXU6JXVdOiB1bmtub3duIHN0YXRlICV1CgAAAAAAAAAAAABw +Zm4gJXUgUENJRSBQTV9EQVRBX1BNQ1NSIDB4JTA4eCBTVEFUIDB4JTA4eCBEU1RBVEUgMHglMDh4 +CgAAAAAAaHcgcGYgYml0bWFwIDB4JTAyeAoAAAAAAAAAAAAAAAAmdmZpZF9iaXRtYXBbMF0gMHgl +MDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAAAAAmdmZpZF9iaXRtYXBbNF0gMHglMDh4OjB4JTA4 +eDoweCUwOHg6MHglMDh4CgAAAABhZnRlciB2ZmlkIGZpeHVwIGh3IHBmIGJpdG1hcCAweCUwMngK +AAAAAAAAAAAAAAAmdmZpZF9iaXRtYXBbMF0gMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAA +AAAmdmZpZF9iaXRtYXBbNF0gMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAAAAB0aW1lciBx +dWV1ZSAldSBsb3N0IGEgdGljayEgbmV4dCAlcCBsYXN0ICVwIG51bWUgJXUKAAAAAAAAAAAAAAAA +ZmxyX3RpbWVyX3N0YXJ0OiBmbG93Y19pZCAldSAlcCBidWYgJXAKAAAAAAAAAAAATUFDOiBQTExz +IGRpZG4ndCBsb2NrCgAAAAAAAAAAAABod19tY19wcmVwX21jOiBtYyAlZCwgbW9kZSAlZCwgZGVu +c2l0eSAlZCwgd2lkdGggJWQsIHNpemUgMHgleCwgbnVtX2NoaXBzICVkIAoAAHBjaWU6IHJlYWQg +ZnJvbSBzZXJjZmcgcGNpZV9pcF91cl9tYXhmdW5jIDB4JXggcGZiaXRtYXAgMHgleAoAAABTZXJp +YWwgQ29uZmlndXJhdGlvbiB2ZXJzaW9uOiAweCV4IFZQRCB2ZXJzaW9uOiAweCV4CgAAAAAAAAAA +AAAAcGNpZTogbnBmICV1IChwZmJpdG1hcCAweCUwMngpIG52ZiAldSAocGYgMC4uNyAweCUwOHgl +MDh4KSB2ZnN0cmlkZSAldQoAAAAAAAAAAABod19tYWNfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAA +AGh3X2dwaW9fcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAaHdfbWNfc2V0X2Nsa19jZmc6IGZvcmNl +X3Jlc2V0ICVkLCBjdXJyX3N0YXRlICVkLCBzaXplICV1CgAAAAAAAE1DIENMSyBzZXR0aW5nIGZh +aWxlZDogUExMX01fTE9DSyBuZXZlciB0b2dnbGVkCgAAAAAAAAAAAAAAAAAAAABmYWlsZWQgdG8g +ZmluZCB0aGUgJWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAABmYWlsZWQgdG8gcGFyc2UgdGhl +ICVjJWMgVlBEIHBhcmFtZXRlcgoAAAAAAAAAAABtZW1fcHJlcDogbm90IGVub3VnaCBtZW1vcnkg +dG8gYWxsb2NhdGUgcGFnZSB0YWJsZXMKAAAAAAAAAAAAAAAAbWVtX3ByZXA6IGVycm9yLCByZXQg +JWQKAAAAAAAAAABmYWlsZWQgdG8gc3VjY2Vzc2Z1bGx5IGZpbmQgQ2hlbHNpbyBWUEQKAAAAAAAA +AAB2cGRfcHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAAAAAHNlcmNmZ19wcmVwOiBlcnJvciwgcmV0 +ICVkCgAAAAAAbG9nIGluaXRpYWxpemVkIEAgMHglMDh4IHNpemUgJXUgKCV1IGVudHJpZXMpIGZ3 +cmV2IDB4JTA4eCBwY2llX2Z3IDB4JTA4eAoAAAAAAABQSSBlcnJvciBmbG93aWRfbGVuMTYgMHgl +eCwgYXBwX3RhZyAweCV4LCByZWZfdGFnIDB4JXgsIHBpc2MgJTA0eCAlMDR4ICUwNHggJTA0eAoA +AAAAAAAAAAAAAAAAAABmbG93YyAldSAoU0dFIGVxaWQgJXUpIChFVEhDVFJMIHF1ZXVlKSBleHBl +cmllbmNlZCBhIFBDSSBETUEgUkVBRCB3b3JrIHJlcXVlc3QgZXJyb3IgKGluYm91bmQgcXVldWUg +JXUpCgAAAAAAAAAAZmxvd2MgJXUgKFNHRSBlcWlkICV1KSBleHBlcmllbmNlZCBhbiB1bmV4cGVj +dGVkIFBDSSBETUEgUkVBRCB3b3JrIHJlcXVlc3QgZXJyb3IgKGluYm91bmQgcXVldWUgJXUpCgAA +AAAAAAAAAAAAAEVuY291bnRlcmVkIFNHRSBmbG9wIHdvcmthcm91bmQsIElnbm9yZSBvcGNvZGUK +AGZsb3djICV1IGV4cGVyaWVuY2VkIGFuIHVuZXhwZWN0ZWQgUENJIERNQSBSRUFEIGVycm9yIChp +bmJvdW5kIHF1ZXVlICV1KQoAAAAAAAAAZ2F0aGVyX3Rhc2tzX2Zvcl90bWY6IEludmFsaWQgdHlw +ZSBbMHgleF0sIGJhaWxpbmcgb3V0LgoAAAAAAAAAAGZjX3NlbmRfYWxsb2NfY3BsOiBmYWlsZWQg +dG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAABmY29lX2NvbXB1dGVfY3R1cGxl +IDB4JXg6JXgKAAAAAGNvbXB1dGVfY3R1cGxlKCk6IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1 +cGxlCgAAAAAAAAAAAAAAAAAAAABGQ29FIEZDQiBsaW5rZG93bjogaW9fcmVxIDB4JXgleCBpcWlk +IDB4JXggZmxvd2lkIDB4JXggb3AgMHgleAoAZmNvZSBub3RpZnkgOiBVcGRhdGUgbmV3IERDQlgg +dmFsdWVzIFZJIHN0YXRlIDB4JXggcHJpIDB4JXggc2NoZWRjbCAweCV4IGRjYnhfZG9uZSAweCV4 +CgAAAAAAAAAAZmNvZSBub3RpZnkgOiBGQ0YgZmxvd2lkIDB4JXgsIHVscGNoIDB4JXggCgAAAAAA +ZmNvZSBub3RpZnkgOiBGQ29FIExJTktVUDogcG9ydCAweCV4LCBldmVudCAweCV4CgAAAAAAAAAA +AAAAAAAAAGZjb2Ugbm90aWZ5IDogRkNvRSBMSU5LRE9XTjogcG9ydCAweCV4LCBldmVudCAweCV4 +CgAAAAAAAAAAAAAAAABmY29lIG5vdGlmeSA6IERDQlggOiBwb3J0IDB4JXgsIHByaW9yaXR5IDB4 +JXggdWxwdHhjaCAweCV4IGNsYXNzIDB4JXgKAAAAAAAAAAAAAFJERVYgbXNnIGZsb3djOiV4IHN0 +YXRlIDB4JXggZXZlbnQgMHgleAoAAAAAAAAAAGNhbmNlbCBmY2I6JXggc2NiOiV4IHN0YXRlOiV4 +CgAARkNvRSBGQ0YgdGltZXI6IGZsb3djIHN0YXRlIDB4JXgsIHBvcnQgMHgleCAsZmNmIDB4JXgs +IGZsb3djX2lkIDB4JXgKAAAAAAAAAAAAAABodyByZWdpc3RlciBvcGVyYXRpb24gbm90IGNvbXBs +ZXRpbmcsIHJlZyAweCUwOHggbWFzayAweCUwOHggdmFsdWUgMHglMDh4IChyZWcgMHglMDh4KQoA +AAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAgTU1EIGFkZHIKAAAAAAAAAAAAAABN +RElPOiBmYWlsZWQgdG8gd3JpdGUKAAAAAAAAAAAAAE1ESU8gQ0w0NTogZmFpbGVkIHRvIHNldCB1 +cCBNTUQgYWRkcgoAAAAAAAAAAAAAAE1ESU86IGZhaWxlZCB0byByZWFkCgAAAAAAAAAAAAAAbWlp +X2Fkdl9mY1sldV06IHJjYXBzIDB4JXgKAAAAAABtaWlfYWR2X3NwZWVkWyV1XTogcmNhcHMgMHgl +eAoAAGNwbF90eF9wa3Q6IHZsYW5pZCBbMHgleF0KAAAAAAAAZmxvd2NfaWQgWyV1XSBsMmRldl9m +YyBbMHgleF0gYWxyZWFkeSByZWNlaXZlZCBSQSwgbm90IHNlbmRpbmcgUlMKAAAAAAAAAAAAAAAA +AABmbG93Y2lkIFsldV0gbDJkZXZfZmMgWzB4JXhdIE5vIElQdjYgcm91dGVyCgAAAABjaG5ldCBb +JWQvJWRdIGZyZWUgbDJ0IGVudHJ5OiBpZHggJXUsIHJlZmNudCAldQoAAAAAAAAAAAAAAAAAAAAA +Y2huZXQgWyVkLyVkXSBwdXQgbDJ0IGVudHJ5OiBpZHggJXUsIHJlZmNudCAldQoAY2huZXQgWyVk +LyVkXSBnZXQgbDJ0IGVudHJ5OiBpZHggJXUsIHJlZmNudCAldQoAY2huZXQgWyVkLyVkXSBsMnQg +YWxsb2MgbDJ0ZW50IDB4JXgsIGlkeCAldSwgcmVmY250ICV1CgAAAAAAAAAAAG91dCBvZiBhdGlk +czogbWF4IGF0aWRzOiAlZAoAAAAAc2V0dXBfZGRwOiBpc3Rhc2s6MHgleCwgbnBwb2QgJXUsIGFs +bG9jIGZhaWxlZCAlZAoAAAAAAAAAAAAAAAAAAHBlbmRpbmdfY3NvY2tzOiBjc29jazogJXAgdGd0 +X2ZjOiAlcCBpZHggJXUgc3RhdGUgMHgleAoAAAAAAAAAAABmbG93X2lkIFsweCV4XSBoaXN0b3J5 +IDB4JTJ4IDB4JTJ4IDB4JTJ4IDB4JTJ4IDB4JTJ4CgAAAAAAAAAAAAAAZm9pc2NzaV92YWxpZGF0 +ZV9sb2dpbl9zdGFnZTogLSAxCgAAAAAAAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiBtYiBbMHgleF0s +IGRlZmVycmVkLCBzdGF0ZSBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAGwyZGV2X3ZpX2ZzbTogdmlp +ZCBbMHgleF0gcG9ydCBbMHgleF0sIG1hYy1pZCBbJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUw +MnhdLiAKAAAAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogc2dlX2VxaWQgWzB4JXhdLCBzZ2Vf +aXFpZCBbMHgleF0sIHNnZV9lcWNyIFsweCV4XSwgcnNzX3N6IFsweCV4XQoAbDJkZXZfdmlfZnNt +OiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X210dSBbJXVdLCBtYl9zY3JhdGNoIFsweCV4XSwg +cG9ydCBbMHgleF0KAAAAAAAAAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiB2aWlkIFslZF0sIHZpX2Zj +LT5mbG93Y192aV9mbGFncyBbMHgleF0KAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogcGZuIFsweCV4 +XSwgdmZuIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbHBvcnQgWzB4JXhdLCB2 +aWlkIFsweCV4XSwgZmxhZ3MgWzB4JXhdCgAAAAAAAABsMmRldl92aV9mc206IEVycm9yIGZyZWVp +bmcgVkksIHJjIFsweCV4XQoAAAAAAABsMmRldl92aV9mc206IHBpZCBbMHgleF0sIHZpaWQgWzB4 +JXhdLCBtYl9sb2MgWzB4JXhdLCBtYl9vcmlnWzB4JXhdLCBsMmRldl9mbGFncyBbMHgleF0sIHJj +IFsweCV4XQoAAAAAAAAAAAAAAAAAZm9pc2NzaV9maW5kX3Rhc2s6IHRhc2sgbm90IGZvdW5kIHRj +Yl9mYyBpZCAweCV4IGl0dCAweCV4CgAAAAAAAFdBVENIRE9HOiBObyB0ZW1wZXJhdHVyZSBzZW5z +b3IgYXZhaWxhYmxlLgoAAAAAAFdBVENIRE9HOiBBY3RpdmF0aW5nCgAAAAAAAAAAAAAAV0FUQ0hE +T0cgLSBFbmFibGUgYWN0aW9uICV1IHRpbWUgJXUKAAAAAAAAAAAAAAAAV0FUQ0hET0cgLSBEaXNh +YmxlIGFjdGlvbiAldQoAAABXQVRDSERPRzogRGUtYWN0aXZhdGluZwoAAAAAAAAAAHBvcnRbJXVd +IHNldCBQQVVTRSBQQVJBTVM6IHBwcGVuICV1IHR4cGUgJSN4IHJ4cGUgJSN4CgAAAAAAAAAAAABt +cHNfbGlua191cFsldV0gYWNhcHMgJSN4ICg4MDIuMyAlI3gpICsgbHBhY2FwcyAlI3ggPT4gJSN4 +CgAAAAAAZGNieF9wb3B1bGF0ZV9jdHJsIGNvZGUgaW5jb21wbGV0ZQoAAAAAAAAAAAAAAAAAcmF0 +ZSAldSBrYnBzIGlzIG91dCBvZiBjb25maWd1cmVkIGdyYW51bGFyaXR5IHJhbmdlcyBtaW4gJWQg +a2JwcyAtIG1heCAlZCBrYnBzLiBVc2luZyBtaW5pbXVtIHBvc3NpYmxlIGdyYW51bGFyaXR5ICVk +IGticHMKAAAAAABDYW5ub3QgZ2V0IHJhdGUgJXUgd2l0aCBjb25maWd1cmVkIGdyYW51bGFyaXRp +ZXMuIFVzaW5nIGxvd2VzdCBwb3NzaWJsZSB0aWNrICVkCgAAAAAAAAAAAAAAAAAAAABEQ0JYOiBz +dW0gb2YgcmF0ZXMgb24gYWxsIGNsYXNzZXMgbXVzdCBiZSAxMDAgKGFjdHVhbDogJXUpCgAAAAAA +cmlfd3JfaW5pdFsldV06IG1zcyAldSBpcyBub3QgOC1ieXRlIGFsaWduZWQKAAAAY29yZV9wcm9n +cmFtX3RjYjogdGlkICUjeCB0X3N0YXRlICUjeCByY3ZfYWR2IDB4JTA4eCByY3Zfc2NhbGUgJSN4 +IHR4X21heCAlI3ggcmN2X254dCAlI3ggYXRpZCAlI3gKAAAAAAAAAAAAAAAAAAlvcHQwICUjeCV4 +IG9wdDIgJSN4IGlwdjYgJSN4IGZsYWdzX3RpbWVyIDB4JTA4eAoAAAAAAAAAAAAAAAAAAABvZmxk +X2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUw +NHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmlsdGVyIDB4JTA4eCBleGlzdHMgQCBM +RSBpbmRleCAldQoAAAAAAAAAAAAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24g +d2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCBwaXAgMHglMDh4IGZp +bHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93 +cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4 +JTA4eCBwaXAgMHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4CgAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6 +IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCBw +aXAgMHglMDh4IGZpbHRlciAweCUwOHgKAAAAAAAAAAAAAAAARVEgKGZyZWVzbGlzdCkgcGZuICV1 +IHZmbiAldTogZmxpZF9hICV1IGZldGNoIGJ1cnN0IG1heFsldV0gJXUgKCV1IGJ5dGVzKSA+IDI4 +CgBJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAA +AAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWlkICV1IG5vdCBhbGxvY2F0ZWQKAAAA +SVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAAAAAA +AAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwwaWQgJXUgbm90IGFsbG9jYXRlZAoAAElR +RkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAAAAAA +AAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IG5vdCBhbGxvY2F0ZWQKAABJUUZM +SU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBub3QgZmwwaWQgJXUKAAAA +AAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBpcyB2YWxpZCBidXQgaGVhZGVyIHNw +bGl0IGZlYXR1cmUgaXMgbm90IGVuYWJsZWQKAAAAAAAAAAAAAAAAAAAARVEgcGZuICV1IHZmbiAl +dTogY3JlYXRpbmcgRVRIIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMgJXUg +YW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAARVEgcGZuICV1IHZmbiAldTogY3JlYXRpbmcgQ1RSTCBl +cWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgK +AAAAAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAARVEg +cGZuICV1IHZmbiAldTogZXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAAAAAAAAdmlfdGNhbV9yYXcg +aWR4ICV1IG1hYyAweCUwNHggJTA4eAoAAAAAAAAAAAAAAAAAcG9ydF9ibGlua19sZWRfcmVzdG9y +ZQoAAAAAAAAAAABwb3J0X2JsaW5rOiBibGlua2R1cj0weCV4IGJsaW5rX3JlZmNudAoAAAAAAAAA +AABwb3J0X2JsaW5rOiAJYmxpbmtfcmVmY250PTB4JXgKAHBvcnRfYmxpbms6IAlibGlua19yZWZj +bnQ9MHgleAoAbWlpX2FucmVzdGFydFsldV06IGFjYXBzIDB4JXgKAABtaXNzaW5nIHBvcnQgY2Fw +czMyIHRvIGNhcHMxNiB0cmFuc2xhdGlvbiBmb3IgJSNseAoAAAAAAAAAAAAAAAAAcG9ydF9jbWRf +aGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAbWlzc2luZyBwb3J0IGNhcHMx +NiB0byBjYXBzMzIgdHJhbnNsYXRpb24gZm9yICUjeAoAAAAAAAAAAAAAAAAAAGJhZCBGbG93QyAl +ZCBvbiBlc3RhYmxpc2hlZCBjb25uZWN0aW9uCgAAAAAAAAAAAGV0aF9mbG93Y19oYW5kbGVyWzB4 +JXhdOiBmbGFncyAweCUwOHggbnVtX2J5dGVzICV1IHNjaGVkY2wgMHgleCAtPiAweCV4CgAAAAAA +AAAAdGFza19hbGxvYzogT3V0IG9mIHRhc2tzLgoAAAAAAABzY3NpX3JlYWQ6IHBwb2QgYWxsb2Mg +ZmFpbGVkLCBucHBvZCAldQoAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfTElO +S1VQCgAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfVVBEQVRFX0RDQlhf +VExWCgAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfUEVFUl9OT1RfQURWRVJUSVNFX0RD +QlgKAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1VQREFURV9PUEVSX1ZF +UlNJT04KAAAAAAAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9QUk9DRVNT +X1BFRVJfVExWCgAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9BQ0tfUEVFUgoAAAAAAAAA +AAAAAGRjYnhfaWVlZV92YWxpZGF0ZVsldV0gZXJyb3IgKG91aSAlI3ggc3VidHlwZSAlI3ggbGVu +ICUjeCkKAAAAAABkY2J4X2NlZV92YWxpZGF0ZVsldV0gZXJyb3IKAAAAAERIQ1B2NiBSRVBMWSBy +ZWNlaXZlZCBzdGF0ZSAldQoAZGhjcCByZXBseSByZWNlaXZlZCBpbiB3cm9uZyBzdGF0ZSAlZAoA +AAAAAAAAAAAAdW5rbm93biBzZXJ2ZXJpZC4gSWdub3JpbmcgZGhjcCByZXBseQoAAAAAAAAAAAAA +cmVjZWl2ZWQgcmVwbHkgd2l0aCBkaWZmZXJlbnQgYWRkcmVzcy4gaWdub3JpbmcgZGhjcCByZXBs +eQoAAAAAAERIQ1B2NiBBRFZFUlRJU0UgcmVjZWl2ZWQKAAAAAAAAZGhjcCBhZHZlcnRpc2UgcmVj +ZWl2ZWQgaW4gd3Jvbmcgc3RhdGUgJWQKAAAAAAAAaWdub3JpbmcgcmN2ZCBhZHZlcnRpc2UgcHJl +ZmVyZW5jZSAldQoAAAAAAAAAAAAAU3RhcnQgREhDUHY2IHRvIGdldCB0aGUgaXAgYWRkcmVzcwoA +AAAAAAAAAAAAAAAATm8gZGhjcCwgZGhjcCBzdGF0ZSAlZCwgYWRkciBzdGF0ZSAlZAoAAAAAAAAA +AAAAJTAyeCAlMDJ4ICUwMnggJTAyeCAlMDJ4ICUwMngKAAB2bjJ2bjogcG9ydCAweCV4IGRpZDow +eCV4JXgleCBVUAoAAAAAAAAAAAAAAAAAAAB2bjJ2bjogcG9ydCAweCV4IGRpZDoweCV4JXgleCBE +T1dOCgAAAAAAAAAAAAAAAABmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRl +ciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABj +b21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAA +AAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSB2bGFuICV4IHZpaWQgJXggcG9ydCAleCBtcHNfaWR4 +ICV4CgAAAAAAAAAAAEFCVFMgQUNDIGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19pZCAweCV4IG94 +X2lkIDB4JXggcnhfaWQgMHgleCBpcWlkIDB4JXgKAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4 +LCBjb21tYW5kIGZhaWxlZCByZXRyaWVzIDB4JXgKAAAAAAAAAAAAAAAAAEdvdCBDT05OX0VYSVNU +IGZvciB4aWQ6MHgleCwgdGFnOjB4JXgsIHJldHJ5aW5nLgoAAAAAAAAAAAAAAAAAAABDYW5ub3Qg +Z2V0IGNoYW5uZWwgcmF0ZSAldSB3aXRoIGNvbmZpZ3VyZWQgZ3JhbnVsYXJpdGllcy4gQ2hlY2sg +Y29uZmlnIGZpbGUKAAAAAF9od19jaW1fdHNjaF9jaF9yYXRlX3BlcmNlbnRbJXVdOiBpbmNyZWFz +ZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWVzdGVkICV1IHRvIHJlcXVpcmVkIG1pbiBvZiAldTsg +cmF0ZSAldSAoZWZmICV1KQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2hfcmxbJXVdOiBjaGFubmVs +IHJsIG5vdCBhdmFpbGFibGUgaW4gY29uanVuY3Rpb24gd2l0aCBmbG93IHNoYXBpbmcKAABwa3Rz +Y2hlZF9jaF9ybFsldV06IHJhdGUgJXUgbWF4ICV1CgAAAAAAAAAAAAAAAABwa3RzY2hlZF9jbF93 +cnJbJXU6JXVdOiB3ZWlnaHQgJXUKAAAAAAAAAAAAAAAAAABlcV9wYXJhbXNbMHgleDoweCV4XTog +ZG1hcSAweCV4IHJlYWQgJXUgcGYgJXUgZXFpZF9hcGkgJXUgcmV0ICVkCgAAAAAAAAAAAAAAAAAA +AGh3X21hX2FkZHJfdG9fbWVtX3R5cGVfb2ZmOiBNQSBhZGRyZXNzIDB4JTA4eCBpcyBub3QgbWFw +cGVkCgAAAABod19tYV9hZGRyX3RvX21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUwOHggbWFw +cyB0byB0eXBlICV1IG9mZnNldCAweCV4CgAAAAAAAG1lbV9tYWxsb2NfdGVtcDogZmFpbGVkIHRv +IGFsbG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAAByaW5nIGJhY2tib25lLCBlbmFi +bGUgJWQsIG1wcy5mbGFncyAweCV4CgAAAAAAAAByaW5nIGJhY2tib25lIG5vIGNoYW5nZSBpbiBj +b25maWd1cmF0aW9uCgAAAAAAAAByaW5nIGJhY2tib25lIGNvbmZpZ3VyYXRpb24gZXJyb3IsIFRD +QU0gbm90IGVtcHR5LiBhdmFpbGFibGUgJWQsIHNpemUgJWQKAAAAAAAAAG1lbV9tYWxsb2M6IGZh +aWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAAAAAAABsZSBjb25m +aWd1cmF0aW9uOiByZXF1ZXN0ZWQgJXUgdGNhbSBlbnRyaWVzIGJ1dCBvbmx5ICV1IGF2YWlsYWJs +ZSAobmZpbHRlciAldSBuc2VydmVyICV1IG5ocGZpbHRlciAldQoAAAAAAAAAAAAAbGUgY29uZmln +dXJhdGlvbjogdGNhbSByZWdpb25zIG11c3QgaGF2ZSBtdWx0aXBsZSBvZiA2NCBlbnRyaWVzLCBu +ZmlsdGVyICV1IG5ocGZpbHRlciAldSBuc2VydmVyICV1CgAAAAAAAAAAAAAAAGh3X3RwX3RjcF90 +dW5pbmdzOiB0dW5pbmcgZm9yIGNsdXN0ZXIgZW52aXJvbm1lbnQKAAAAAAAAAAAAAAAAAABod190 +cF90Y3BfdHVuaW5nczogdHVuaW5nIGZvciBMQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVu +aW5nczogdHVuaW5nIGZvciBXQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczogbWFu +dWFsIHR1bmluZwoAAAAAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBz +dGFydAoAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogZHN0IDB4JTA4IG9mZnNldCAw +eCUwOHggc2l6ZSAldSwgd2lkdGggb2YgJXUgaXMgbm90IHN1cHBvcnRlZAoAAAAAAAAAAAAAAABf +aHdfY2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBlbmQKAAAAAAAAAAAAAAAAAABjb25maWd1cmF0 +aW9uIGZpbGUgcGFyc2VyIGVuY291bnRlcmVkIGVycm9yIEAgbGluZSAldToKAAAAAAAAAAAAZmNv +ZSB4Y2hnIG1nciBpbml0OiBOdW1iZXIgb2YgZXhjaGFuZ2VzIGZvciBGQ29FIGlzICV4CgAAAAAA +AAAAAGZjb2VfbDJ0X2luaXQ6IE5vIHVscHR4IGNyZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2Vf +bDJ0X2luaXQ6IGNoOlsldV0gbDJ0X2lkeCBbJXVdCgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVz +IGNvbmZpZ3VyZWQ7IGZvcmNpbmcgJXUgZW50cmllcywgc3RhcnRpbmcgYXQgJXUKAABkY2J4X2ll +ZWVfY29uc3RydWN0WyV1XSBldHMgJXUgcGZjICV1IGFwcCAldQoAAABkY2J4X3RpbWVvdXRbJXVd +CgAAAAAAAAAAAAAAAAAAAGRjYnhfcnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JV +Tl9JRUVFCgAAAAAAAAAAAAAAAAAAAABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9T +VEFURV9SVU5fQ0VFCgBkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5f +Tk9ORQoAAAAAAAAAAAAAAAAAAAAATUFDIGZhaWxlZCB0byByZXN5bmMgdHgKAAAAAAAAAABwb3J0 +WyV1XSBsaW5rIHVwICgldSkgKHNwZWVkICUjeCBhY2FwcyAlI3ggbHBjYXBzICUjeCkKAAAAAAAA +AAAAcG9ydF9oc3Nfc2lnZGV0WyV1XTogaHNzX3NpZ2RldCBjaGFuZ2VkIHRvIDB4JXgKAAAAAAAA +AAAAAAAAAAAAAHBvcnRbJXVdIGluaXRpYWxpemluZyBLUgoAAAAAAAAAQ2FsY3VsYXRpb24gb3V0 +IG9mIGJvdW5kcyBmdXJpbmcgaW5pdDogJSN4ICUjeCAlI3gKAAAAAAAAAAAAAAAAAGxlIGNvbmZp +Z3VyYXRpb246IGhhc2ggbW9kZSByZXF1aXJlcyBhdCBsZWFzdCAxNiBlbnRyaWVzLCBuaGFzaCAl +dQoAAAAAAAAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBzaXplICV1IG11c3QgYmUgbXVs +dGlwbGUgb2YgJXUsIG5oYXNoICV1CgAAAAAAAAAAAAAAAAAAAABBZGRpbmcgbWF0Y2gtYWxsIGNs +aXAgZW50cnkgQCBsb2MgMHgleC8lZAoAAAAAAABod19zZ2VfbWFtZW1faW5pdDogZW5jb3VudGVy +ZWQgZXJyb3IgJWQKAAAAAAAAAABfaHdfdHBfcGdtbmd0OiB0eF9wYWdlX21heCAldSByeF9wYWdl +X21heCAldSBwc3RydWN0cyAldSBzaXplICV1CgAAAAAAAAAAAAAAAAAAAE5vIHNwYWNlIGxlZnQg +Zm9yIHBnbW5ndCwgTmVlZCAldUIsIGF2YWlsYWJsZSAldUIsIE5vIG9mZmxvYWQKAABtcGFydGl0 +aW9uX290aGVyc190b3RhbDogbWVtICV1LCBkZHAgJXUgZGRwX2lzY3NpICV1IHN0YWcgJXUgcGJs +ICV1IHJxICV1IHJxdWRwICV1IC0+ICV1CgAAAAAAAABObyBzcGFjZSBsZWZ0IGZvciBwbXR4IHBh +Z2VzLCBOZWVkICV1QiwgYXZhaWxhYmxlICV1QiwgTm8gb2ZmbG9hZAoAAAAAAAAAAAAAAAAAAE5v +IHNwYWNlIGxlZnQgZm9yIHBtcnggcGFnZXMsIE5lZWQgJXVCLCBhdmFpbGFibGUgJXVCLCBObyBv +ZmZsb2FkCgAAAAAAAAAAAAAAAAAAX21wYXJ0aXRpb25fYmFua3NfbWNYOiBuYmFua3NfcG10eCAl +dSAoJXVNQikgbmJhbmtzX3BtcnggJXUgKCV1TUIpIG5iYW5rc19vdGhlcnMgJXUgKCV1TUIpIG5i +YW5rc19mdyAldSAoJXVNQikKAF9tcGFydGl0aW9uX2JhbmtzX21jMTogbmJhbmtzX3BtdHggJXUg +KCV1TUIpIG5iYW5rc19vdGhlcnMgJXUgKCV1TUIpIG5iYW5rc19mdyAldSAoJXVNQikKAAAAAAAA +AF9tcGFydGl0aW9uX2JhbmtzX21jMDogbmJhbmtzX3BtcnggJXUgKCV1TUIpIG5iYW5rc19vdGhl +cnMgJXUgKCV1TUIpCgAAAAAAAAAAAAAAbWVtX21hbGxvY19pbnRlcm5hbDogZmFpbGVkIHRvIGFs +bG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAAAAAAAAAAAAAAAAAABod19lZGNfYmlz +dFsldV06IGJpc3RfY21kWzB4JTA4eF0gYWRkciAweCV4IGxlbiAweCV4CgAAAAAAAAAAAAAAaHdf +ZWRjX2Jpc3RbJXVdOiBkb25lLCBlbmNvdW50ZXJlZCAldSBlcnJvcnMgb24gZmlyc3QgYW5kICV1 +IGVycm9ycyBvbiBzZWNvbmQgYXR0ZW1wdCAoJXVnYnBzKQoAbWVtX2luaXRfY2FjaGVzOiBjYWNo +ZV9zaXplICV1IGZsb3djX2J1Zl90Y2JfY2FjaGVfc2l6ZSAldSBidWZsbDY0X2NhY2hlX3NpemUg +JXUKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9wbXR4OiBtIDB4JTA4eCBzaXplICV1CgAAAAAA +AAAAAAAAAAAAbXBhcnRpdGlvbl9wbXJ4OiBtIDB4JTA4eCBzaXplICV1CgAAAAAAAAAAAAAAAAAA +bXBhcnRpdGlvbl9iYW5rc19tY1g6IGRkcF9pc2NzaSAweCV4IGlzY3NpX3Bwb2RfZWRyYW1fZmxh +ZyAweCV4CgAAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX2JhbmtzX21jMDogZGRwX2lzY3NpIDB4 +JXggaXNjc2lfcHBvZF9lZHJhbV9mbGFnIDB4JXgKAAAAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25f +ZWRjIChubyBleHRtZW0pOiBtIDB4JTA4eCBzaXplICV1CgAAAGVkYyBvdmVyY29tbWl0ZWQgYnkg +JWRCLCAweCV4LzB4JXgKAAAAAAAAAAAAAAAAAGVkYyBvdmVyY29tbWl0ZWQgYnkgJWRCLCAweCV4 +LzB4JXgvJWQKAAAAAAAAAAAAAG1wYXJ0aXRpb25fZWRjX2VzdGltYXRlOiBodyBtb2R1bGVzIHJl +cXVpcmUgJWQgYnl0ZXMgaW4gRURDCgAAAABUZW1wZXJhdHVyZS9Wb2x0YWdlIFNlbnNvcjogQ29y +ZSBjbG9jayAldSA+ICV1OyBjYXBwaW5nIHRvIHN0YXkgaW4gY29tcGxpYW5jZSB3aXRoIGhhcmR3 +YXJlLgoAAABzZXR0aW5nIHVwIHJpbmcgYmFja2JvbmUKAAAAAAAAAHJpbmcgYmFja2JvbmUgY29u +ZmlnIGVycm9yLCBUQ0FNIG5vdCBlbXB0eS4gYXZhaWxhYmxlICVkLCBzaXplICVkCgAAAAAAAAAA +AAAAAAAAZm9pc2NzaV9jb3JlX2J5ZTogYWN0aXZlIHNlc3NfY250ICVkCgAAAAAAAAAAAAAAaHdf +bWFjX2FlY19jb21wbGV0ZVsldV0gb24gbGFuZXMgJSN4IChzaWdkZXQgJSN4KSwgdHhfbGFuZXMg +JSN4CgAAAAAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHN0YXRlIFNUQVJUIChzaWdkZXQgJSN4 +KQoAAAAAAAAAAABhZWNfZnNtWyV1XSA6IFRyYW5zaXRpb25pbmcgdG8gVFJBSU5JTkdfTE9DQUwK +AABhZWNfZnNtWyV1XSA6IFRyYW5zaXRpb25pbmcgdG8gQ09FRl9TVEFUVVNfVVBBRFRFCgAAAAAA +AAAAAAAAAAAAYWVjX2ZzbVsldV0gOiB0cmFuc2l0aW9uaW5nIHRvIFRSQUlOSU5HCgAAAAAAAAAA +YWVjX2ZzbVsldV0gOiBUUkFJTklOR19DT01QTEVURQoAAAAAAAAAAAAAAAAAAAAAYWVjX2ZzbVsl +dV0gOiBMb2NhbCBmYXVsdCB3aGlsZSB3YWl0aW5nIGZvciBsaW5rIHN0YXR1cyAweCV4IDogMHgl +eAoAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IFJlbW90ZSBmYXVsdCB3aGlsZSB3YWl0aW5nIGZv +ciBsaW5rIHN0YXR1cyAweCV4CgAAYWVjX2ZzbVsldV0gOiBSZW1vdGUgZmF1bHQgY2xlYXJlZCB3 +aGlsZSB3YWl0aW5nIGZvciBsaW5rIHN0YXR1cyAweCV4CgAAAAAAAAAAAABhZWNfZnNtWyV1XSA6 +IERPTkUKAAAAAAAAAAAAAAAAAGFlY19mc21bJXVdIHRpbWVkIG91dCB0cmFpbmluZyBGU01fU1RB +VEVfMCAweCV4LCBfMSAweCV4IF8yIDB4JXggXzMgMHgleCwgTGluayBTdGF0dXMgMHgleAoAAAAA +AGJlYW5fZnNtWyV1XSA6IHN0YXRlIFNUQVJUIChjb3VudCA9ICV1KQoAAAAAAAAAAGJlYW5fZnNt +WyV1XSA6IGVudGVyaW5nIHN0YXRlIFdBSVRfU0lHREVUCgAAAAAAAGJlYW5fZnNtWyV1XSA6IGVu +dGVyaW5nIHN0YXRlIEJBU0VQX0hBTkRMRQoAAAAAAGJlYW5fZnNtWyV1XSA6IGVudGVyaW5nIHN0 +YXRlIE5YUF9IQU5ETEUKAAAAAAAAAGJlYW5fZnNtWyV1XSA6IGVudGVyaW5nIHN0YXRlIFdBSVRf +Q09NUExFVEUKAAAAAGJlYW5fZnNtWyV1XSA6IGVudGVyaW5nIHN0YXRlIEVYVF9OWFBfSEFORExF +CgAAAGJlYW5fZnNtWyV1XSA6IFBFRVIgZG9lc24ndCBzdXBwb3J0IE5QLiBFbnRlcmluZyBzdGF0 +ZSBXQUlUX0NPTVBMRVRFCgAAAAAAAAAAAAAAYmVhbl9mc21bJXVdIDogRVhUX05YUF9IQU5ETEUg +SW52YWxpZCBuZXh0IHBhZ2UKAAAAAAAAAAAAAAAAAAAAAGJlYW5fZnNtWyV1XSA6IENvbnNvcnRp +dW0gaW5jb21wYXRpYmxlIHNwZWVkLiBhYmlsaXR5IGxvY2FsIDB4JXgsIHJlbW90ZSAweCV4CgAA +YmVhbl9mc21bJXVdIDogZW50ZXJpbmcgc3RhdGUgRVhUX01PUkVfTlhQX0hBTkRMRQoAAAAAAAAA +AAAAAAAAAGJlYW5fZnNtWyV1XSA6IGVudGVyaW5nIHN0YXRlIFdBSVRfRk9SX05VTExfUEFHRQoA +AAAAAAAAAAAAAAAAAABiZWFuX2ZzbVsldV0gOiBlbnRlcmluZyBzdGF0ZSBXQUlUX0NPTVBMRVRF +CgAAAABiZWFuX2ZzbVsldV0gOiBJRUVFIGluY29tcGF0aWJsZSBzcGVlZC4gYWJpbGl0eSBsb2Nh +bCAweCV4LCByZW1vdGUgMHgleAoAAAAAAAAAAGJlYW5fZnNtWyV1XSA6IElFRUUgc3BlZWQgMHgl +eCwgRkVDIHJlbW90ZSAweCV4LCBuZWdvdGlhdGVkIDB4JXgKAAAAAAAAAAAAAAAAAAAAYmVhbl9m +c21bJXVdIDogc3RhdGUgRE9ORQoAAAAAAABiZWFuX2ZzbVsldV0gOiBGRUMgbG9jYWwgMHgleCwg +bmVnb3RpYXRlZCAweCV4CgBiZWFuX2ZzbVsldV0gOiBzdGF0ZSBSRVNUQVJUMQoAAGJlYW5fZnNt +WyV1XSA6IHN0YXRlIFJFU1RBUlQyCgAAYmVhbl9mc21bJXVdIDogc3RhdGUgUkVTVEFSVDMKAABi +ZWFuX2ZzbVsldV0gVElNRU9VVDsgc3RhdGUgJXUgZXRoX3N0YXR1cyAlI3ggYmVhbl9zdGF0dXMg +JSN4IFBDU19ERUJVRzBfUk8gJSN4IGhzcyBzaWdkZXQgJSN4IHJldHJ5X2NudCAldQoAAAAAaHdf +bWFjX2xpbmtfc3RhdHVzWyV1XSBpbnRfY2F1c2UgMHgleCwgbGlua19zdGF0dXMgMHgleAoAAAAA +AAAAAHBvcnQgJXUgY2hhbmdpbmcgc3BlZWQgdG8gMUcKAAAAcG9ydCAldSBuZWdvdGlhdGVkIHVu +c3VwcG9ydGVkIHNwZWVkICUjeAoAAAAAAAAAYmVhbi9hZWMgY29tcGxldGUgKHJldHJ5OiAldSkK +AABwb3J0WyV1XSByZXNldHRpbmcgS1IKAAAAAAAAAAAAAHBvcnQgJXUgbmVnb3RpYXRlZCB1bnN1 +cHBvcnRlZCBzcGVlZAoAAAAAAAAAAAAAAHBvcnRbJXVdIG5lZ290aWF0ZWQgcHR5cGUgMHgleCwg +c3BlZWQgMHgleCwgbGFuZXMgMHgleDoweCV4LCBmZWMgMHgleAoAAAAAAAAAAAAAYmVhbi9hZWMg +Y29tcGxldGUgKHJldHJ5OiAldSkKAABNQzogR1BPIDB4JXgsIFJMTyAweCV4CgAAAAAAAAAAAHBm +biAldSB2Zm4gJXUgY29tcGxldGUgaW1tZWRpYXRlCgAAAAAAAAAAAAAAAAAAAGJhZCBtYWlsYm94 +IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4ID4gTEFTVEMyRSAweCV4CgBtYWls +Ym94IGNtZCBub3QgeWV0IHN1cHBvcnRlZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4 +CgAAYmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXggaXMgdmFs +aWQgcG9zdCBkZXZpY2UgaW5pdCBvbmx5CgBiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAw +eCV4OyBvcGNvZGUgMHglMDJ4IHJhbWFzayAweCV4IGNtZCByYW1hc2sgMHgleAoAAGJhZCBtYWls +Ym94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCUwMnggbGVuMTYgMHgleCB2ZXJz +dXMgZXhwZWN0ZWQgbGVuMTYgMHgleAoAAAAAAAAAAGluc3VmZmljaWVudCBjYXBzIHRvIHByb2Nl +c3MgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2NhcHMgMHgleCB3eF9jYXBzIDB4 +JXggcmVxdWlyZWQgcl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAAAAAAAAAAaW5zdWZmaWNpZW50 +IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IHJfY2FwcyAw +eCV4IHd4X2NhcHMgMHgleCByZXF1aXJlZCByX2NhcHMgMHgleCB3X2NhcHMgMHgleAoAAAAAAAAA +AABNQzogVGFraW5nIFBIWSBvdXQgb2YgcmVzZXQgKEZQR0EpLgoAAAAAAAAAAAAAAABkb3dubG9h +ZF9zcmFtOiBlcnJvciwgcmV0ICVkCgAAAGRvd25sb2FkX3RjYW06IGVycm9yLCByZXQgJWQKAAAA +aHdfcG93ZXJfcHJlcDogVkREPU5PTkUgYnV0IFZDUz0lZAoAAAAAAAAAAAAAAAAAaHdfcG93ZXJf +cHJlcDogdW5zdXBwb3J0ZWQgZXh0ZXJuYWwgYWRqdXN0YWJsZSBwb3dlciByZWd1bGF0b3JzIFZE +RD0lZCwgVkNTPSVkCgBod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWREQ9JWQKAAAAAAAAAAAA +AAAAAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWQ1M9JWQKAAAAAAAAAAAAAAAAAABod19w +b3dlcl9wcmVwOiBpMmMgd3JpdGUgZXJyb3IsIFZERD0lZCxyZXQ9JWQKAABod19wb3dlcl9wcmVw +OiB1bnN1cHBvcnRlZCBWREQ9JWQKAAAAAAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiBpMmMgd3Jp +dGUgZXJyb3IsIFZDUz0lZCxyZXQ9JWQKAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBWQ1M9 +JWQKAAAAAAAAAAAAAAAAAABleHRtZW0gY2xrIG1vZGUgJWQsIGV4dG1lbSAldSwgcmVmX2NsayAl +dQoAAAAAAAB1cCBjbGsgbW9kZSAlZCwgcmVmX2NsayAldSwgZGV2LmNsay51cCAldQoAAAAAAABj +bGsgbW9kZSAlZCwgcmVmX2NsayAldSwgZGV2LmNsay5jb3JlICV1CgAAAAAAAABWUEQgcmVnaW9u +IGlzIHRvbyBzbWFsbCAoU0VSQ0ZHX1NSX1BGTlZQRFNJWkUgMHgleCkKAAAAAAAAAAAAAAAAY2Zf +cHJlcDogZXJyb3IsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAggAAASAAAAAAAAAAAAAAAIIAAAEAAAAAAAAAAAAAAACCAAAAwAAAAAAAAAAA +AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoCAAAAAAAAA +AAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAAAAAAAAD +AAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAACAEAMAAAAAAAAIAAAAAAAAAAACAAAAAAAAAAAA +AAAAACAAAAAAAAAAAAAAAAAAAAABAAOAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAACADgAAA +AAAAAAAAAAAAAAAQAoAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAQAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAIAAAoAAAAAAAAAAAAAAAAAAAAIAAAAA +AAAAAAAAAAAAgAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAA +AQADAAAAAAAAAAAAAAAAAAACgwAAAAAAAAAAAAAAAAAQAoAAAAAAAAAAAAAAAAAAMAADAAAAAAQA +AAAAAAAAADADAwAAAAAEAAAAAAAAAAAwAAMAAAAAAAAIAAAAAAAAMAADAAAAAAAAAAAAAAAAADAF +gwAAAAAAAAgAAAAAAAAwBYMAAAAAAAAAAAAAAAAAMASDAAAAAAAACAAAAAAAADAEgwAAAAAAAAAA +AAAAAAAwAwMAAAAAAAAIAAAAAAAAMAMDAAAAAAAAAAAAAAAAADgDAwAAAAAAAAAAAAAAAAA4BYMA +AAAAAAAAAAAAAAAAOASDAAAAAAAAAAAAAAAAADgAAwAAAAAAAAAAAAAAAAA0BoIAAAAAAAAAAAAA +AAAAPAOCAAAAAAAAAAAAAAAAADwAAwAAAAAAAAgAAAAAAAA8AAMAAAAAAAAAAAAAAAAAPASDAAAA +AAAAAAAAAAAAADwFAwAAAAAAAAAAAAAAAAA9BAMAAAAAAAAAAAAAAAAAPAODAAAAAAAAAAAAAAAA +ACwAAgAAAAAAAAAAAAAAAAAsBYIAAAAAAAAAAAAAAAAALAUCAAAAAAAAAAAAAAAAABAGgAAAAAAA +AAAAAAAAAAAQBoKAAAAAAAAAAAAAAAAAgA6CAAAAAAAAAAAAAAAAAJAHgoAAAAAgAAAAAAAAAACA +B4IAAAAAIAAAAAAAAAAAEAcCgAAAAAAAAAAAAAAAABAHAoAAAAAAAAAAAAAAAAAQBwKAAAAAAAAA +AAAAAAAAEAYCAAAAAAAAAAAAAAAAABAGAoAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAcC +AAAAACAAAAAAAAAAABAXgwAAAAAAAAgAAAAAAAAQF4MAAAAAAAAIAAAAAAAAEAAAAAAAAAAAAAAA +AAAAABAGA4AAAAAAAAAAAAAAAAAADgMAAAAAAAAAAAAAAAAAEAYDQAAAAAAAAAAAAAAAABAGAwAA +AAAAAAAAAAAAAAAQBgAAAAAAAAAAAAAAAAAAAAYDgAAAAAAAAAAAAAAAAAAGAwAAAAAAAAAAAAAA +AAAADgIAAAAAAAAAAAAAAAAAAA4CAAAAAAAAAAAAAAAAABAGAgAAAAAAAAAAAAAAAAAQBgKAAAAA +AAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAgAAAAAAAAAAAAAAAAAQAwAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAD///////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +AAAAAAAAACAAAAAAwAAAAAAAAAAAAAAgAAAAAOAAAAAAAAAAAAAAIAAAAAEgAAAAAAAAAAAAAAAC +AAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAABIQAAAAAAAAAAAAAAAAABASAAAAAAAAAAAAAA +AAAAAAIAAAAEAAQAAAAAAAAAAACBQAAAAAAAAAAAAAAAAAAGgAAABAAAAAAAAAAAAAAAgABAAAAA +AAACAAAAAAAAAIAAIAAAAAAAAgAAAAAAAAiAAAAAAABAAAAAAgAAAAABAEAAAAAAAAAAAAAAAAAA +AQBCAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAACECAAAAAAAAAAAAAAAAAAAgwCAAAAAAAA +AAAAAAAAAACFAgAAAAQAAAAAAAAAAAAAgEIAAAAAAAAAAAAAAAAAgIBCAEAAAAAAAAAAAAAAAICA +QgAAAAAAAAAAAAAAAAACACIAAAAAAAAAAAAAAAAAAIBBAAAAAAAAAAAAAAAAAIAAIQAAAAAAAAAA +AAAAAAAAgEGAAAAAAAAAAAAAAAAAgIBBgAAAAAAAAAAAAAAAAAIAIQAAAAAAAAAAAAAAAAAAECCA +AAAAAAAAAAAAAAAAAiUAgAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAACIgASAAAAAAAAAAAAA +AAAAiISAgAAAAAAAAAAAAAAAAAiIBIAAAAAAAAAAAAAAAAAIiASAAAAAAAAAAAAAAAAACKIAgAAA +AAAAAAAAAAAAAAiiAIAAAAAAAAAAAAAAAAAIowCAAAAAAAAAAAAAAAAACKMAgAAAAAAAAAAAAAAA +AAikgIAAAAAAAAAAAAAAAAAIpICAAAAAAAAAAAAAAAAABKSAwAAAAAAAAAAAAAAAAASiAMAAAAAA +AAAAAAAAAAAEowDAAAAAAAAAAAAAAAAABIgEwAAAAAAAAAAAAAAAAAAJAYAAAAAAAAAAAAAAAAAC +DACAAAAAAAAAAAAAAAAAAIgEwAAAAAAAAAAAAAAAAACIBIAAAAAAAAAAAAAAAAACCwCAAAAAAAAA +AAAAAAAAAIqAgAAAAAAAAAAAAAAAAAALgIAAAAAAAAAAAAAAAAAAjACAAAAAAAAAAAAAAAAAAiAQ +gAAAAAAAAAAAAAAAAAIKAIAAAAAAAAAAAAAAAAACCoCAAAAAAAAAAAAAAAAAAAkCgAAAAAAAAAAA +AAAAAAABAQAAAAAAAAAAAAAAAAAAAQCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAA +AAAAAAAAAAAAAAAAAIEQAAAAAAAAAAAAAAAAAACBCAAAAAAAAAAAAAAAAAAAgQQAAAAAAAAAAAAA +AAAASYGAAAAAAAAAAAAAAAAAAEGBAAAAAAAAAAAAAAAAAIAAAQAAAAAAAAAAAAAAAAAAAIGAAAAA +AAAAAAAAAAAAAIAAwAAAAAAAAAAAAAAAAACAAKAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAA +AIGAAAAAAAAAAAAAAAAAAACBgIAAAAAAAAAAAAAAAAAAiYCAAAAAAAAAAAAAAAAAAImAwAAAAAAA +AAAAAAAAAAABggAAAAAAAAAAAAAAAAACAYAAAAAAAAAAAAAAAAAAAgGAgAAAAAAAAAAAAAAAAABB +gYAAAAAAAAAAAAAAAAACAYGAAAAAAAAAAAAAAAAAAgmBgAAAAAAAAAAAAAAAAAIBgQAAAAAAAAAA +AAAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAAgEAAAAAAAAAAAAAABAAAAIAAAAAAAAAAAAAAAAQAAAA +AAAAAAAAAAAAAAAAAIAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAgAkgAAAAAAAAABswAQACAAAAAACACSAAAAAAACAAG5ABKCIAAA +AAAIAJIAAAAAAAAAAbMAEAAgAAAAAAAAAAAAAAAAAAABywAQACAAAAAACAAAAAUARAHDgAArARAA +IAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAAAAAAAAABywAQACAAAAAAAAAAAAAAAAAAAAHL +ABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAAAAAAAAABywAQACAAAAAAAAAAAAAAAAAA +AAHLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAgAAAAFAEQBwYAASwAQACAAAAAACAAAAAUA +RAHBgABLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAAAAAAAAABywAQACAAAAAACAAA +AAUARAHBgABLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAAAAAAAAAAAAAABywETAiAAAAAA +CEcgAQQAAAFaAAFpAyASIkAAAAAIRyABBAAAAVoAAWkCIxIgQAAAAAgAAAAFAEQBwYAASwETAiAA +AAAAAAAAAAAAAAAAAAHLABAAIAAAAAAIRyABAQZQwVggAMkCIBIiQAAAAAgAAAAFAEQBwYAASwET +AiAAAAAACEcgAQAGUCFawAEJAyASIkAAAAAIAAAABQBEAcGAAEsBEwIgAAAAAAgAAAAFAEQBwYAA +SwAQACAAAAAACAAAAAUARAHBgABLABAAIAAAAAAIAAAABQBEAcGAAEsAEAAgAAAAAAAAAAAAAAAA +AAABywAQACAAAAAACAAAAAUARAHBgABLARMCIAAAAAAIAAAABQBEAcGAAEsBEwIgAAAAAAXFEroB +WEBpiypF8SSjEiAAAAAABcUSugVbwGmJKkWxJFMSIAAAAAANxRKiBVhAaYsqRfEkoxIgAAAAAA3F +EqIBW8BpiSpFsSRTEiAAAAAADcUSogVYQGmLKkXxJKMSIAAAAAANxRKiAVvAaYkqRbEkUxIgAAAA +AA3FEqIFWEBpiypF8SSjEiAAAAAADcUSogFbwGmJKkWxJFMSIAAAAAAJxBCgAQBASAIARbE0YxIg +AAAAAAnEEKAFWEBJgSpFsTVjEiAAAAAACcQQoAVYQEmBKkWxNWMSIAAAAAABxRC4AVhASYsqRbEl +YxIgAAAAAAChEIgFAECsCAAFqQFTEiAAAAAACcAQkAVYQAGJKkVJAWMSIAAAAAAJwBC4BVhAAYhK +RfEAoxIgAAAAAAHAELgFWkABikpFsQBTEiAAAAAAAcAQuAVaQAGKSkWxAFMSIAAAAAABwBC4BVpA +AYpKRbEAUxIgAAAAAAHAELgFWkABikpFsQBTEiAAAAAACaAQkAFaQAGKSkWxAFMSIAAAAAABwBCA +BVhAAYsqRSkAYxIgAAAAAAHAEIAFWEABiypFKQBjEiAAAAAAAcAQgAVYQAGLKkUpAGMSIAAAAAAI +RyABBAAAAVgAAWkDIBIgQAAAAAiBAAABAEKsA6AFqQFTEiAAAAAACAAAAAAAUCAAwADrABAAIAAA +AAAIAAAAAQBQwAAgAKsAEAAgAAAAAAgAAAAAAFAgAMAA6wAQACAAAAAAAIEAAAUAQqzAAgWpAFMS +IAAAAAAKAUAAAAAADAIAAaEBE1IhAAAAAAAAAAAAAAAAAAABywAQACAAAAAAAKEQiAUAQKwKAASJ +AFMSIAAAAAAIAAAABQBEAcOgBGkBoxIhAAAAAAgAAAAFAEQBwYAASwETAiAAAAAACAAAAAAAUCAA +wADrABAAIAAAAAAIAAAABQBEAcOAAesAEAAgAAAAAAgAAAAFAEQBw4AB6wAQACAAAAAAAAAAAAAA +AAAAAAHLABAAIAAAAAAAAAAAAAAAAAAAAcsAEAAgAAAAAAgAAAAAAFAgAMAA6wAQACAAAAAAAcAQ +uAVaQAGKSkWxAFMSIAAAAAAAAAAAAAAAAAAAAcsBEwIgAAAAAAAAAAAAAAAAAAABywAQACAAAAAA +CAAAAAUARAHBgABLABAAIAAAAAAIAAAAAABQIADAAOsAEAAgAAAAAAgAAAAAAFAgAMAA6wAQACAA +AAAACAAAAAAAUCAAwADrABAAIAAAAAAIAAAAAABQIADAAOsAEAAgAAAAAAgAAAABAFDAACAAqwAQ +ACAAAAAACcUTIgFKRGkKQEWRJWMSIAAAAAABwBEAAVJEAIOqRakAYxIgAAAAAAnAEQAFUkQAQ6pF +qQBjEiAAAAAAAcAQgAFaRAGCikWpAFMSIAAAAAANwAAABVhAYYkqRfEBoxIgAAAAAAAAAAAAAAAA +AAABywAQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAIADAABAAAAAAAAAEBExIgAAAAAABHMAABAZABW4AEAQBgMiBAAAAAAEcw +AAUBgAFbgAQBAGAyIEAAAAAAAwAAAQBQBVmABAEAYxIjQAAAAAADAAAEAAAFWYAEAQBjEiNAAAAA +AAAAAAAAAAAAAAABARMSIAAAAAAAIFAABAAAAAIAAAEAExIjAAAAAAhgIACEAAAAAAAAAwAQACAA +AAAAAKAgAIAAAAAAAJgBARMSoAAAAAAIYAAABABCAMICAgEBYxJhAAAAAAnAAAAFIcABggZEAQAT +EiAAAAAACABgAAQAAAACAAAAARAAIAAAAAAIAGAABAAAAAIAAAIAEAAgAAAAAAAAAAAAAAAAAgAA +AgAQACAAAAAADAgUgAUFAAADgKYBEFMTYAAAAAAAgAAAAQBCAMICBAEAUxJgAAAAAAhAAAAFAFAA +ACAEAQBTEiMAAAAAAKAAAAAAAAAAAAABARMSIAAAAAAMAAAABUIAAYBFBAEDYBIgAAAAAAAAAAAA +AAAAAgAAAwEQJCAAAAAAACBQAAQAAAAAAAABARMSIAAAAAAIYCAAhAAAAAAAAAMAEAAgAAAAAACg +IACAAAAAAgAAAQETEqAAAAAACGAAAAQAQgDCAgIBAGMSYAAAAAAIAGAABAAAAAIAAAIAEAAgAAAA +AAgAgAAUAAAAAAAAAQATJjgAAAAACACAABQAAAACAAADABAAAAAAAAAIAIAAFAAAAAAAAAEAEyY4 +AAAAAAgAgAAUAAAAAgAAAwAQAAAAAAAADAAAAAWyAAGCTQQBAgACIAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcAAAAJaRgIEiwIBAmMSIAAAAAABwAAAAhpAAgSL +AgECYxIgAAAAAAwIdIBCBIAAKgAuATBzEiAAAAAADAh0gEQAAAAqACABMRMSIAAAAAAIAhCgBAAA +AAAAgAEAExIgAAAAAAgCEKAEAAAAAACAAQATEiAAAAAABAh0AEUAgAADgEQBMWMSIAAAAAAFyBQA +AQSAAAMgTgEwcxIgAAAAAAHIEIAFWkACAkpEATNjEiAAAAAADch0AEZaQAGASkQBMFMSYAAAAAAF +yHQAQhpIAYBKRAEwUxJgAAAAAAhHAAAEAAAAAgAAAQAQEiAAAAAACEcAAAQAAAAAAAABAiASIAAA +AAAARyABAgOQ4VuABAEAYBIiQAAAAABHIAECA5DhW4AEAQBgEiJAAAAAAEcgAQIDkOFbgAQBAGAS +IkAAAAAIACABAgBCAAGgRAEAYxJgAAAAAAgAIAECAEIAAaBEAQBjEmAAAAAACAAgAQIAQgABoEQB +AGMSYAAAAAAAACABhUEAAIJgRAEB4xJgAAAAAAgAIAGFQQAAAmBEAQHjEmAAAAAACcAgAYVSQACB +oEQBAGMSYAAAAAAAAAAABgBCAAGgRAEAYxJgAAAAAAgAAAAFQQAAgmBEAQHjEmAAAAAAAAAAAAVB +AAAAYEQBANMSYAAAAAABwAAABVJAAIGgRAEAYxJgAAAAAAgAoAGEAAAAAABEAQATEmAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAABFwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbZ2xvYmFsXQpyc3Nf +Z2xiX2NvbmZpZ19tb2RlPWJhc2ljdmlydHVhbApyc3NfZ2xiX2NvbmZpZ19vcHRpb25zPXRubG1h +cGVuLGhhc2h0b2VwbGl0eix0bmxhbGxsa3AKcGxfdGltZW91dF92YWx1ZT0yMDAKcmVnWzB4MTAw +OF09MHg0MDgwMC8weDIxYzcwCnJlZ1sweDEwMGNdPTB4MjIyMjIyMjIKcmVnWzB4MTBhMF09MHgw +MTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sweDEwNDhdPTY1NTM2CnJlZ1sweDEwNGNdPTE1 +MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0XT05MjE2CnJlZ1sweDEwNThdPTIwNDgKcmVn +WzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIKcmVnWzB4MTA2NF09MTYzODQKc2dlX3RpbWVy +X3ZhbHVlPTUsMTAsMjAsNTAsMTAwLDIwMApyZWdbMHgxMGM0XT0weDIwMDAwMDAwLzB4MjAwMDAw +MDAKcmVnWzB4N2QwNF09MHgwMDAxMDAwMC8weDAwMDEwMDAwCnJlZ1sweDdkYzBdPTB4MGUyZjg4 +NDkKdHNjaF90aWNrcz0xMDAwMDAsMTAwMDAsMTAwMCwxMApmaWx0ZXJNb2RlPWZjb2VtYXNrLHNy +dnJzcmFtLGZyYWdtZW50YXRpb24sbXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBvcnQsZmNvZQpm +aWx0ZXJNYXNrPXByb3RvY29sLGZjb2UKdHBfcG1yeD0zMAp0cF9wbXJ4X3BhZ2VzaXplPTY0Swp0 +cF9ucnhjaD0wCnRwX3BtdHg9NTAKdHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4Y2g9MAp0cF9t +dHVzPTg4LDI1Niw1MTIsNTc2LDgwOCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIsMjA0OCw0MDk2 +LDQzNTIsODE5Miw5MDAwLDk2MDAKcmVnWzB4N2QwNF09MHgwMDAxMDAwOC8weDAwMDEwMDA4CnJl +Z1sweDdkMDhdPTB4MDAwMDA4MDAvMHgwMDAwMDgwMApyZWdbMHg3ZDQ4XT0weDAwMDAwMDAwLzB4 +MDAwMDA0MDAKcmVnWzB4N2Q2MF09MHgwNjAwMDAwMC8weDA3MDAwMDAwCnJlZ1sweDE5YzA0XT0w +eDAwMDAwMDAwLzB4MDA0NDAwMDAKcmVnWzB4MTljMjhdPTB4MDA4MDAwMDAvMHgwMWYwMDAwMApy +ZWdbMHg4ZGMwXT0weDAwMDAwMTA0LzB4MDAwMDAxMDQKcmVnWzB4MTkyNWNdPTB4MDAwMDQxYzAv +MHgwMDAwMzFjMApobWFfc2l6ZT02NApobWFfcmVnaW9ucz1zdGFnLHBibCxycQpbZnVuY3Rpb24i +MCJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0 +cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEiXQpu +dmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJsPTgK +bmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9MHgyCltmdW5jdGlvbiIyIl0KbnZmPTE2 +Cnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5lcT0x +NgpuZXhhY3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4NApbZnVuY3Rpb24iMyJdCm52Zj0xNgp3eF9j +YXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4 +YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDgKW2Z1bmN0aW9uIjQiXQp3eF9jYXBzPWFsbApyX2Nh +cHM9YWxsCm52aT0yOApuaXFmbGludD0yMDIKbmV0aGN0cmw9MTE2Cm5lcT0yNTYKbnFwY3E9MTIy +ODgKbmV4YWN0Zj00MApucmF3Zj0yCmNtYXNrPWFsbApwbWFzaz1hbGwKbmV0aG9mbGQ9MTAyNApu +Y3J5cHRvX2xvb2thc2lkZT0xNgpuY2xpcD0zMjAKbmZpbHRlcj00OTYKbnNlcnZlcj00OTYKbmhh +c2g9MTIyODgKbmhwZmlsdGVyPTY0CnByb3RvY29sPW5pY192bSxvZmxkLHJkZHAscmRtYWMsaXNj +c2lfaW5pdGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1LGlzY3NpX3QxMGRpZix0bHNrZXlzLGNy +eXB0b19sb29rYXNpZGUKdHBfbDJ0PTMwNzIKdHBfZGRwPTIKdHBfZGRwX2lzY3NpPTIKdHBfdGxz +X2tleT0zCnRwX3Rsc19teHJ4c2l6ZT0xNzQwOAp0cF9zdGFnPTIKdHBfcGJsPTUKdHBfcnE9Nwp0 +cF9zcnE9MTI4CltmdW5jdGlvbiI1Il0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9NApuaXFm +bGludD0zNApuZXRoY3RybD0zMgpuZXE9NjQKbmV4YWN0Zj0xNgpjbWFzaz1hbGwKcG1hc2s9YWxs +Cm5zZXJ2ZXI9MTYKbmhhc2g9MjA0OAp0cF9sMnQ9MTAyMApuY2xpcD02NApwcm90b2NvbD1pc2Nz +aV9pbml0aWF0b3JfZm9mbGQKdHBfZGRwX2lzY3NpPTIKaXNjc2lfbnRhc2s9MjA0OAppc2NzaV9u +c2Vzcz0yMDQ4CmlzY3NpX25jb25uX3Blcl9zZXNzaW9uPTEKaXNjc2lfbmluaXRpYXRvcl9pbnN0 +YW5jZT02NApbZnVuY3Rpb24iNiJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxp +bnQ9MzQKbmV0aGN0cmw9MzIKbmVxPTY2Cm5leGFjdGY9MzIKY21hc2s9YWxsCnBtYXNrPWFsbApu +aGFzaD0yMDQ4CnRwX2wydD00CnByb3RvY29sPWZjb2VfaW5pdGlhdG9yCnRwX2RkcD0yCmZjb2Vf +bmZjZj0xNgpmY29lX252bnA9MzIKZmNvZV9uc3NuPTEwMjQKW2Z1bmN0aW9uIjEwMjMiXQp3eF9j +YXBzPWFsbApyX2NhcHM9YWxsCm52aT00CmNtYXNrPWFsbApwbWFzaz1hbGwKbmV4YWN0Zj04Cm5m +aWx0ZXI9MTYKW2Z1bmN0aW9uIjAvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpu +aXFmbGludD02Cm5ldGhjdHJsPTQKbmVxPTgKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDEK +W2Z1bmN0aW9uIjEvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02 +Cm5ldGhjdHJsPTQKbmVxPTgKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDIKW2Z1bmN0aW9u +IjIvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhjdHJs +PTQKbmVxPTgKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjMvKiJdCnd4 +X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD02Cm5ldGhjdHJsPTQKbmVxPTgK +bmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDIKW3BvcnQiMCJdCmRjYj1wcHAsZGNieApod209 +NjAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2Fw +cF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVt +LDUKW3BvcnQiMSJdCmRjYj1wcHAsZGNieApod209NjAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3Rs +dlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwz +CmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW2ZpbmldCnZlcnNpb249MHgxNDI1MDAx +YwpjaGVja3N1bT0weDgxMzZkMGY2CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW2dsb2JhbF0KcnNzX2dsYl9jb25m +aWdfbW9kZT1iYXNpY3ZpcnR1YWwKcnNzX2dsYl9jb25maWdfb3B0aW9ucz10bmxtYXBlbixoYXNo +dG9lcGxpdHosdG5sYWxsbGtwCnBsX3RpbWVvdXRfdmFsdWU9MTAwMApyZWdbMHgxMDA4XT0weDQw +ODEwLzB4MjFjNzAKcmVnWzB4MTAwY109MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEw +CnJlZ1sweDEwNDRdPTQwOTYKcmVnWzB4MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdb +MHgxMDUwXT05MDI0CnJlZ1sweDEwNTRdPTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVj +XT0xMjgKcmVnWzB4MTA2MF09ODE5MgpyZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEw +MDBhMDAwLzB4ZjAwMGYwMDAKcmVnWzB4MTBhOF09MHg0MDIwMDAvMHg0MDIwMDAKc2dlX3RpbWVy +X3ZhbHVlPTUsMTAsMjAsNTAsMTAwLDIwMApyZWdbMHgxMGM0XT0weDIwMDAwMDAwLzB4MjAwMDAw +MDAKcmVnWzB4N2QwNF09MHgwMDAxMDAwMC8weDAwMDEwMDAwCnJlZ1sweDdkYzBdPTB4MGUyZjg4 +NDkKdHNjaF90aWNrcz0xMDAwLDEwMCwxMCwxCmZpbHRlck1vZGU9ZmNvZW1hc2ssc3J2cnNyYW0s +ZnJhZ21lbnRhdGlvbixtcHNoaXR0eXBlLHByb3RvY29sLHZsYW4scG9ydCxmY29lCmZpbHRlck1h +c2s9cHJvdG9jb2wsZmNvZQp0cF9wbXJ4PTMwCnRwX3BtcnhfcGFnZXNpemU9NjRLCnRwX25yeGNo +PTAKdHBfcG10eD01MAp0cF9wbXR4X3BhZ2VzaXplPTY0Swp0cF9udHhjaD0wCnRwX210dXM9ODgs +MjU2LDUxMiw1NzYsODA4LDEwMjQsMTI4MCwxNDg4LDE1MDAsMjAwMiwyMDQ4LDQwOTYsNDM1Miw4 +MTkyLDkwMDAsOTYwMApyZWdbMHg3ZDA0XT0weDAwMDEwMDA4LzB4MDAwMTAwMDgKcmVnWzB4N2Qw +OF09MHgwMDAwMDgwMC8weDAwMDAwODAwCnJlZ1sweDdkNDhdPTB4MDAwMDAwMDAvMHgwMDAwMDQw +MApyZWdbMHg3ZDYwXT0weDA2MDAwMDAwLzB4MDcwMDAwMDAKcmVnWzB4MTljMDRdPTB4MDA0MDAw +MDAvMHgwMDQ0MDAwMApyZWdbMHgxOWMyOF09MHgwMDgwMDAwMC8weDAxZjAwMDAwCnJlZ1sweDhk +YzBdPTB4MDAwMDAxMDQvMHgwMDAwMDEwNApyZWdbMHgxOTI1Y109MHgwMTAwMzQwMC8weDAxMDAz +NDAwCltmdW5jdGlvbiIwIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MjgKbmlxZmxpbnQ9 +MTcwCm5ldGhjdHJsPTk2Cm5lcT0yNTIKbmV4YWN0Zj00MApucmF3Zj0yCmNtYXNrPWFsbApwbWFz +az1hbGwKbmV0aG9mbGQ9MTAyNApuY3J5cHRvX2xvb2thc2lkZT0zMgpuY2xpcD0zMgpuZmlsdGVy +PTQ4Cm5zZXJ2ZXI9NDgKbmhhc2g9MjA0OApuaHBmaWx0ZXI9MApwcm90b2NvbD1uaWNfdm0sb2Zs +ZCxyZGRwLHJkbWFjLGlzY3NpX2luaXRpYXRvcl9wZHUsaXNjc2lfdGFyZ2V0X3BkdSxpc2NzaV90 +MTBkaWYsdGxza2V5cyxjcnlwdG9fbG9va2FzaWRlCnRwX2wydD0zMDcyCnRwX2RkcD0yCnRwX2Rk +cF9pc2NzaT0yCnRwX3Rsc19rZXk9Mwp0cF9zdGFnPTIKdHBfcGJsPTUKdHBfcnE9Nwp0cF9zcnE9 +MTI4CltmdW5jdGlvbiIxIl0Kd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9NApuaXFmbGludD0z +NApuZXRoY3RybD0zMgpuZXE9NjQKbmV4YWN0Zj0xNgpjbWFzaz1hbGwKcG1hc2s9YWxsCm5zZXJ2 +ZXI9MTYKbmhhc2g9MjA0OAp0cF9sMnQ9MTAyMApwcm90b2NvbD1pc2NzaV9pbml0aWF0b3JfZm9m +bGQKdHBfZGRwX2lzY3NpPTIKaXNjc2lfbnRhc2s9MjA0OAppc2NzaV9uc2Vzcz0yMDQ4CmlzY3Np +X25jb25uX3Blcl9zZXNzaW9uPTEKaXNjc2lfbmluaXRpYXRvcl9pbnN0YW5jZT02NApbZnVuY3Rp +b24iMTAyMyJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKY21hc2s9YWxsCnBtYXNrPWFs +bApuZXhhY3RmPTgKbmZpbHRlcj0xNgpbZnVuY3Rpb24iMC8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fw +cz0weDg2Cm52aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9 +YWxsCnBtYXNrPTB4MQpbZnVuY3Rpb24iMS8qIl0Kd3hfY2Fwcz0weDgyCnJfY2Fwcz0weDg2Cm52 +aT0xCm5pcWZsaW50PTQKbmV0aGN0cmw9MgpuZXE9NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNr +PTB4MgpbcG9ydCIwIl0KZGNiPXBwcCxkY2J4LGIyYgpod209MzAKbHdtPTE1CmR3bT0zMApkY2Jf +YXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVy +dHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMSJdCmRjYj1wcHAs +ZGNieCxiMmIKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVy +dHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0z +MjYwLHNvY2tldG51bSw1CltmaW5pXQp2ZXJzaW9uPTB4MTQyNTAwMWQKY2hlY2tzdW09MHgzNjFi +OTU2YgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== +==== diff --git a/sys/dev/cxgbe/firmware/t6fw_cfg.txt b/sys/dev/cxgbe/firmware/t6fw_cfg.txt index 84647d18994b..d02788e539ed 100644 --- a/sys/dev/cxgbe/firmware/t6fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t6fw_cfg.txt @@ -153,6 +153,7 @@ nexactf = 456 cmask = all pmask = all + ncrypto_lookaside = 16 nclip = 320 # TCAM has 6K cells; each region must start at a multiple of 128 cell. @@ -162,7 +163,7 @@ nserver = 512 nhpfilter = 0 nhash = 16384 - protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu, iscsi_t10dif + protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu, iscsi_t10dif, crypto_lookaside tp_l2t = 4096 tp_ddp = 2 tp_ddp_iscsi = 2 @@ -272,7 +273,7 @@ [fini] version = 0x1 - checksum = 0xf438bb8f + checksum = 0x7191019f # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t6fw_cfg_uwire.txt b/sys/dev/cxgbe/firmware/t6fw_cfg_uwire.txt index c9973c8f9ebd..887adca271c7 100644 --- a/sys/dev/cxgbe/firmware/t6fw_cfg_uwire.txt +++ b/sys/dev/cxgbe/firmware/t6fw_cfg_uwire.txt @@ -109,6 +109,7 @@ # filter tuples : fragmentation, mpshittype, macmatch, ethertype, # protocol, tos, vlan, vnic_id, port, fcoe # valid filterModes are described the Terminator 5 Data Book + # vnicMode = pf_vf #default. Other values are outer_vlan, encapsulation filterMode = fcoemask, srvrsram, fragmentation, mpshittype, protocol, vlan, port, fcoe # filter tuples enforced in LE active region (equal to or subset of filterMode) @@ -178,6 +179,10 @@ # MC configuration #mc_mode_brc[0] = 1 # mc0 - 1: enable BRC, 0: enable RBC + # HMA configuration + hma_size = 64 # Size (in MBs) of host memory expected + hma_regions = stag,pbl,rq # What all regions to place in host memory + # Some "definitions" to make the rest of this a bit more readable. We support # 4 ports, 3 functions (NIC, FCoE and iSCSI), scaling up to 8 "CPU Queue Sets" # per function per port ... @@ -565,8 +570,8 @@ dcb_app_tlv[2] = 3260, socketnum, 5 [fini] - version = 0x01000028 - checksum = 0x4f820cc6 + version = 0x1425001c + checksum = 0x8136d0f8 # Total resources used by above allocations: # Virtual Interfaces: 104 diff --git a/sys/dev/cxgbe/iw_cxgbe/provider.c b/sys/dev/cxgbe/iw_cxgbe/provider.c index ad47891f1ba0..0cc698a7e38f 100644 --- a/sys/dev/cxgbe/iw_cxgbe/provider.c +++ b/sys/dev/cxgbe/iw_cxgbe/provider.c @@ -388,6 +388,24 @@ c4iw_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) return 0; } +static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num, + struct ib_port_immutable *immutable) +{ + struct ib_port_attr attr; + int err; + + immutable->core_cap_flags = RDMA_CORE_PORT_IWARP; + + err = ib_query_port(ibdev, port_num, &attr); + if (err) + return err; + + immutable->pkey_tbl_len = attr.pkey_tbl_len; + immutable->gid_tbl_len = attr.gid_tbl_len; + + return 0; +} + /* * Returns -errno on error. */ @@ -471,6 +489,7 @@ c4iw_register_device(struct c4iw_dev *dev) ibdev->post_send = c4iw_post_send; ibdev->post_recv = c4iw_post_receive; ibdev->uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION; + ibdev->get_port_immutable = c4iw_port_immutable; iwcm = kmalloc(sizeof(*iwcm), GFP_KERNEL); if (iwcm == NULL) diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index a4a4c4f34265..9471be400348 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -295,6 +295,14 @@ TUNABLE_INT("hw.cxgbe.nofldtxq_vi", &t4_nofldtxq_vi); static int t4_nofldrxq_vi = -NOFLDRXQ_VI; TUNABLE_INT("hw.cxgbe.nofldrxq_vi", &t4_nofldrxq_vi); +#define TMR_IDX_OFLD 1 +int t4_tmr_idx_ofld = TMR_IDX_OFLD; +TUNABLE_INT("hw.cxgbe.holdoff_timer_idx_ofld", &t4_tmr_idx_ofld); + +#define PKTC_IDX_OFLD (-1) +int t4_pktc_idx_ofld = PKTC_IDX_OFLD; +TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_ofld", &t4_pktc_idx_ofld); + /* 0 means chip/fw default, non-zero number is value in microseconds */ static u_long t4_toe_keepalive_idle = 0; TUNABLE_ULONG("hw.cxgbe.toe.keepalive_idle", &t4_toe_keepalive_idle); @@ -452,7 +460,7 @@ TUNABLE_INT("hw.cxgbe.toecaps_allowed", &t4_toecaps_allowed); static int t4_rdmacaps_allowed = -1; TUNABLE_INT("hw.cxgbe.rdmacaps_allowed", &t4_rdmacaps_allowed); -static int t4_cryptocaps_allowed = 0; +static int t4_cryptocaps_allowed = -1; TUNABLE_INT("hw.cxgbe.cryptocaps_allowed", &t4_cryptocaps_allowed); static int t4_iscsicaps_allowed = -1; @@ -600,6 +608,8 @@ static int sysctl_tp_dack_timer(SYSCTL_HANDLER_ARGS); static int sysctl_tp_timer(SYSCTL_HANDLER_ARGS); static int sysctl_tp_shift_cnt(SYSCTL_HANDLER_ARGS); static int sysctl_tp_backoff(SYSCTL_HANDLER_ARGS); +static int sysctl_holdoff_tmr_idx_ofld(SYSCTL_HANDLER_ARGS); +static int sysctl_holdoff_pktc_idx_ofld(SYSCTL_HANDLER_ARGS); #endif static uint32_t fconf_iconf_to_mode(uint32_t, uint32_t); static uint32_t mode_to_fconf(uint32_t); @@ -1182,6 +1192,8 @@ t4_attach(device_t dev) vi->rsrv_noflowq = 0; #ifdef TCP_OFFLOAD + vi->ofld_tmr_idx = t4_tmr_idx_ofld; + vi->ofld_pktc_idx = t4_pktc_idx_ofld; vi->first_ofld_rxq = ofld_rqidx; vi->first_ofld_txq = ofld_tqidx; if (port_top_speed(pi) >= 10) { @@ -3551,6 +3563,19 @@ get_params__post_init(struct adapter *sc) ("%s: L2 table size (%u) larger than expected (%u)", __func__, sc->vres.l2t.size, L2T_SIZE)); + /* + * MPSBGMAP is queried separately because only recent firmwares support + * it as a parameter and we don't want the compound query above to fail + * on older firmwares. + */ + param[0] = FW_PARAM_DEV(MPSBGMAP); + val[0] = 0; + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, param, val); + if (rc == 0) + sc->params.mps_bg_map = val[0]; + else + sc->params.mps_bg_map = 0; + /* get capabilites */ bzero(&caps, sizeof(caps)); caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | @@ -5049,8 +5074,7 @@ vi_refresh_stats(struct adapter *sc, struct vi_info *vi) static void cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi) { - int i; - u_int v, tnl_cong_drops; + u_int i, v, tnl_cong_drops, bg_map; struct timeval tv; const struct timeval interval = {0, 250000}; /* 250ms */ @@ -5061,14 +5085,15 @@ cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi) tnl_cong_drops = 0; t4_get_port_stats(sc, pi->tx_chan, &pi->stats); - for (i = 0; i < sc->chip_params->nchan; i++) { - if (pi->rx_chan_map & (1 << i)) { - mtx_lock(&sc->reg_lock); - t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v, - 1, A_TP_MIB_TNL_CNG_DROP_0 + i); - mtx_unlock(&sc->reg_lock); - tnl_cong_drops += v; - } + bg_map = pi->mps_bg_map; + while (bg_map) { + i = ffs(bg_map) - 1; + mtx_lock(&sc->reg_lock); + t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v, 1, + A_TP_MIB_TNL_CNG_DROP_0 + i); + mtx_unlock(&sc->reg_lock); + tnl_cong_drops += v; + bg_map &= ~(1 << i); } pi->tnl_cong_drops = tnl_cong_drops; getmicrotime(&pi->last_refreshed); @@ -5579,6 +5604,14 @@ vi_sysctls(struct vi_info *vi) SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_ofld_txq", CTLFLAG_RD, &vi->first_ofld_txq, 0, "index of first TOE tx queue"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_tmr_idx_ofld", + CTLTYPE_INT | CTLFLAG_RW, vi, 0, + sysctl_holdoff_tmr_idx_ofld, "I", + "holdoff timer index for TOE queues"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_pktc_idx_ofld", + CTLTYPE_INT | CTLFLAG_RW, vi, 0, + sysctl_holdoff_pktc_idx_ofld, "I", + "holdoff packet counter index for TOE queues"); } #endif #ifdef DEV_NETMAP @@ -5652,6 +5685,10 @@ cxgbe_sysctls(struct port_info *pi) SYSCTL_ADD_INT(ctx, children, OID_AUTO, "max_speed", CTLFLAG_RD, NULL, port_top_speed(pi), "max speed (in Gbps)"); + SYSCTL_ADD_INT(ctx, children, OID_AUTO, "mps_bg_map", CTLFLAG_RD, NULL, + pi->mps_bg_map, "MPS buffer group map"); + SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_e_chan_map", CTLFLAG_RD, + NULL, pi->rx_e_chan_map, "TP rx e-channel map"); if (sc->flags & IS_VF) return; @@ -5929,9 +5966,6 @@ sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS) struct adapter *sc = vi->pi->adapter; int idx, rc, i; struct sge_rxq *rxq; -#ifdef TCP_OFFLOAD - struct sge_ofld_rxq *ofld_rxq; -#endif uint8_t v; idx = vi->tmr_idx; @@ -5956,15 +5990,6 @@ sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS) rxq->iq.intr_params = v; #endif } -#ifdef TCP_OFFLOAD - for_each_ofld_rxq(vi, i, ofld_rxq) { -#ifdef atomic_store_rel_8 - atomic_store_rel_8(&ofld_rxq->iq.intr_params, v); -#else - ofld_rxq->iq.intr_params = v; -#endif - } -#endif vi->tmr_idx = idx; end_synchronized_op(sc, LOCK_HELD); @@ -8380,6 +8405,73 @@ sysctl_tp_backoff(SYSCTL_HANDLER_ARGS) return (sysctl_handle_int(oidp, &v, 0, req)); } + +static int +sysctl_holdoff_tmr_idx_ofld(SYSCTL_HANDLER_ARGS) +{ + struct vi_info *vi = arg1; + struct adapter *sc = vi->pi->adapter; + int idx, rc, i; + struct sge_ofld_rxq *ofld_rxq; + uint8_t v; + + idx = vi->ofld_tmr_idx; + + rc = sysctl_handle_int(oidp, &idx, 0, req); + if (rc != 0 || req->newptr == NULL) + return (rc); + + if (idx < 0 || idx >= SGE_NTIMERS) + return (EINVAL); + + rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, + "t4otmr"); + if (rc) + return (rc); + + v = V_QINTR_TIMER_IDX(idx) | V_QINTR_CNT_EN(vi->ofld_pktc_idx != -1); + for_each_ofld_rxq(vi, i, ofld_rxq) { +#ifdef atomic_store_rel_8 + atomic_store_rel_8(&ofld_rxq->iq.intr_params, v); +#else + ofld_rxq->iq.intr_params = v; +#endif + } + vi->ofld_tmr_idx = idx; + + end_synchronized_op(sc, LOCK_HELD); + return (0); +} + +static int +sysctl_holdoff_pktc_idx_ofld(SYSCTL_HANDLER_ARGS) +{ + struct vi_info *vi = arg1; + struct adapter *sc = vi->pi->adapter; + int idx, rc; + + idx = vi->ofld_pktc_idx; + + rc = sysctl_handle_int(oidp, &idx, 0, req); + if (rc != 0 || req->newptr == NULL) + return (rc); + + if (idx < -1 || idx >= SGE_NCOUNTERS) + return (EINVAL); + + rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, + "t4opktc"); + if (rc) + return (rc); + + if (vi->flags & VI_INIT_DONE) + rc = EBUSY; /* cannot be changed once the queues are created */ + else + vi->ofld_pktc_idx = idx; + + end_synchronized_op(sc, LOCK_HELD); + return (rc); +} #endif static uint32_t @@ -9908,6 +10000,12 @@ tweak_tunables(void) FW_CAPS_CONFIG_ISCSI_TARGET_PDU | FW_CAPS_CONFIG_ISCSI_T10DIF; } + + if (t4_tmr_idx_ofld < 0 || t4_tmr_idx_ofld >= SGE_NTIMERS) + t4_tmr_idx_ofld = TMR_IDX_OFLD; + + if (t4_pktc_idx_ofld < -1 || t4_pktc_idx_ofld >= SGE_NCOUNTERS) + t4_pktc_idx_ofld = PKTC_IDX_OFLD; #else if (t4_toecaps_allowed == -1) t4_toecaps_allowed = 0; diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 1dd1d83c8b3b..5c7ff8bebf43 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -1138,7 +1138,7 @@ t4_setup_vi_queues(struct vi_info *vi) } for_each_ofld_rxq(vi, i, ofld_rxq) { - init_iq(&ofld_rxq->iq, sc, vi->tmr_idx, vi->pktc_idx, + init_iq(&ofld_rxq->iq, sc, vi->ofld_tmr_idx, vi->ofld_pktc_idx, vi->qsize_rxq); snprintf(name, sizeof(name), "%s ofld_rxq%d-fl", @@ -1670,10 +1670,10 @@ cl_metadata(struct adapter *sc, struct sge_fl *fl, struct cluster_layout *cll, } static void -rxb_free(struct mbuf *m, void *arg1, void *arg2) +rxb_free(struct mbuf *m) { - uma_zone_t zone = arg1; - caddr_t cl = arg2; + uma_zone_t zone = m->m_ext.ext_arg1; + void *cl = m->m_ext.ext_arg2; uma_zfree(zone, cl); counter_u64_add(extfree_rels, 1); @@ -3085,7 +3085,7 @@ tnl_cong(struct port_info *pi, int drop) else if (drop == 1) return (0); else - return (pi->rx_chan_map); + return (pi->rx_e_chan_map); } static int @@ -3195,8 +3195,7 @@ alloc_ofld_rxq(struct vi_info *vi, struct sge_ofld_rxq *ofld_rxq, struct sysctl_oid_list *children; char name[16]; - rc = alloc_iq_fl(vi, &ofld_rxq->iq, &ofld_rxq->fl, intr_idx, - pi->rx_chan_map); + rc = alloc_iq_fl(vi, &ofld_rxq->iq, &ofld_rxq->fl, intr_idx, 0); if (rc != 0) return (rc); diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index ba1fcbc7288c..a4cacdd32c39 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -71,19 +71,6 @@ __FBSDID("$FreeBSD$"); #include "tom/t4_tom_l2t.h" #include "tom/t4_tom.h" -VNET_DECLARE(int, tcp_do_autosndbuf); -#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf) -VNET_DECLARE(int, tcp_autosndbuf_inc); -#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc) -VNET_DECLARE(int, tcp_autosndbuf_max); -#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) -VNET_DECLARE(int, tcp_do_autorcvbuf); -#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) -VNET_DECLARE(int, tcp_autorcvbuf_inc); -#define V_tcp_autorcvbuf_inc VNET(tcp_autorcvbuf_inc) -VNET_DECLARE(int, tcp_autorcvbuf_max); -#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) - #define IS_AIOTX_MBUF(m) \ ((m)->m_flags & M_EXT && (m)->m_ext.ext_flags & EXT_FLAG_AIOTX) @@ -1979,9 +1966,9 @@ free_aiotx_buffer(struct aiotx_buffer *ab) } static void -t4_aiotx_mbuf_free(struct mbuf *m, void *buffer, void *arg) +t4_aiotx_mbuf_free(struct mbuf *m) { - struct aiotx_buffer *ab = buffer; + struct aiotx_buffer *ab = m->m_ext.ext_arg1; #ifdef VERBOSE_TRACES CTR3(KTR_CXGBE, "%s: completed %d bytes for tid %d", __func__, diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c index 762eb2eeeffa..e32fc4fb18a6 100644 --- a/sys/dev/cxgbe/tom/t4_ddp.c +++ b/sys/dev/cxgbe/tom/t4_ddp.c @@ -67,13 +67,6 @@ __FBSDID("$FreeBSD$"); #include "common/t4_tcb.h" #include "tom/t4_tom.h" -VNET_DECLARE(int, tcp_do_autorcvbuf); -#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) -VNET_DECLARE(int, tcp_autorcvbuf_inc); -#define V_tcp_autorcvbuf_inc VNET(tcp_autorcvbuf_inc) -VNET_DECLARE(int, tcp_autorcvbuf_max); -#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) - /* * Use the 'backend3' field in AIO jobs to store the amount of data * received by the AIO job so far. @@ -1277,7 +1270,8 @@ pscmp(struct pageset *ps, struct vmspace *vm, vm_offset_t start, int npages, int pgoff, int len) { - if (ps->npages != npages || ps->offset != pgoff || ps->len != len) + if (ps->start != start || ps->npages != npages || + ps->offset != pgoff || ps->len != len) return (1); return (ps->vm != vm || ps->vm_timestamp != vm->vm_map.timestamp); @@ -1378,6 +1372,7 @@ hold_aio(struct toepcb *toep, struct kaiocb *job, struct pageset **pps) ps->len = job->uaiocb.aio_nbytes; atomic_add_int(&vm->vm_refcnt, 1); ps->vm = vm; + ps->start = start; CTR5(KTR_CXGBE, "%s: tid %d, new pageset %p for job %p, npages %d", __func__, toep->tid, ps, job, ps->npages); diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h index 452d99ba46eb..7da80d712178 100644 --- a/sys/dev/cxgbe/tom/t4_tom.h +++ b/sys/dev/cxgbe/tom/t4_tom.h @@ -112,6 +112,7 @@ struct pageset { int len; struct ppod_reservation prsv; struct vmspace *vm; + vm_offset_t start; u_int vm_timestamp; }; diff --git a/sys/dev/dpaa/bman.c b/sys/dev/dpaa/bman.c index dabdad4eb18a..401855a416dc 100644 --- a/sys/dev/dpaa/bman.c +++ b/sys/dev/dpaa/bman.c @@ -96,8 +96,8 @@ bman_attach(device_t dev) /* Allocate resources */ sc->sc_rrid = 0; - sc->sc_rres = bus_alloc_resource(dev, SYS_RES_MEMORY, - &sc->sc_rrid, 0, ~0, BMAN_CCSR_SIZE, RF_ACTIVE); + sc->sc_rres = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY, + &sc->sc_rrid, BMAN_CCSR_SIZE, RF_ACTIVE); if (sc->sc_rres == NULL) return (ENXIO); diff --git a/sys/dev/dpaa/fman.c b/sys/dev/dpaa/fman.c index 4a90c10514a5..fcb0ccfd2ead 100644 --- a/sys/dev/dpaa/fman.c +++ b/sys/dev/dpaa/fman.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "opt_platform.h" #include @@ -85,12 +87,185 @@ struct fman_config { */ const uint32_t fman_firmware[] = FMAN_UC_IMG; const uint32_t fman_firmware_size = sizeof(fman_firmware); -static struct fman_softc *fm_sc = NULL; + +int +fman_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + struct fman_softc *sc; + bus_space_tag_t bt; + bus_space_handle_t bh; + int i, rv; + + sc = device_get_softc(bus); + if (type != SYS_RES_IRQ) { + for (i = 0; i < sc->sc_base.nranges; i++) { + if (rman_is_region_manager(res, &sc->rman) != 0) { + bt = rman_get_bustag(sc->mem_res); + rv = bus_space_subregion(bt, + rman_get_bushandle(sc->mem_res), + rman_get_start(res) - + rman_get_start(sc->mem_res), + rman_get_size(res), &bh); + if (rv != 0) + return (rv); + rman_set_bustag(res, bt); + rman_set_bushandle(res, bh); + return (rman_activate_resource(res)); + } + } + return (EINVAL); + } + return (bus_generic_activate_resource(bus, child, type, rid, res)); +} + +int +fman_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + struct fman_softc *sc; + struct resource_list *rl; + struct resource_list_entry *rle; + int passthrough, rv; + + passthrough = (device_get_parent(child) != bus); + rl = BUS_GET_RESOURCE_LIST(bus, child); + sc = device_get_softc(bus); + if (type != SYS_RES_IRQ) { + if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){ + rv = bus_deactivate_resource(child, type, rid, res); + if (rv != 0) + return (rv); + } + rv = rman_release_resource(res); + if (rv != 0) + return (rv); + if (!passthrough) { + rle = resource_list_find(rl, type, rid); + KASSERT(rle != NULL, + ("%s: resource entry not found!", __func__)); + KASSERT(rle->res != NULL, + ("%s: resource entry is not busy", __func__)); + rle->res = NULL; + } + return (0); + } + return (resource_list_release(rl, bus, child, type, rid, res)); +} + +struct resource * +fman_alloc_resource(device_t bus, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + struct fman_softc *sc; + struct resource_list *rl; + struct resource_list_entry *rle = NULL; + struct resource *res; + int i, isdefault, passthrough; + + isdefault = RMAN_IS_DEFAULT_RANGE(start, end); + passthrough = (device_get_parent(child) != bus); + sc = device_get_softc(bus); + rl = BUS_GET_RESOURCE_LIST(bus, child); + switch (type) { + case SYS_RES_MEMORY: + KASSERT(!(isdefault && passthrough), + ("%s: passthrough of default allocation", __func__)); + if (!passthrough) { + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + return (NULL); + KASSERT(rle->res == NULL, + ("%s: resource entry is busy", __func__)); + if (isdefault) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + } + + res = NULL; + /* Map fman ranges to nexus ranges. */ + for (i = 0; i < sc->sc_base.nranges; i++) { + if (start >= sc->sc_base.ranges[i].bus && end < + sc->sc_base.ranges[i].bus + sc->sc_base.ranges[i].size) { + start += rman_get_start(sc->mem_res); + end += rman_get_start(sc->mem_res); + res = rman_reserve_resource(&sc->rman, start, + end, count, flags & ~RF_ACTIVE, child); + if (res == NULL) + return (NULL); + rman_set_rid(res, *rid); + if ((flags & RF_ACTIVE) != 0 && bus_activate_resource( + child, type, *rid, res) != 0) { + rman_release_resource(res); + return (NULL); + } + break; + } + } + if (!passthrough) + rle->res = res; + return (res); + case SYS_RES_IRQ: + return (resource_list_alloc(rl, bus, child, type, rid, start, + end, count, flags)); + } + return (NULL); +} + +static int +fman_fill_ranges(phandle_t node, struct simplebus_softc *sc) +{ + int host_address_cells; + cell_t *base_ranges; + ssize_t nbase_ranges; + int err; + int i, j, k; + + err = OF_searchencprop(OF_parent(node), "#address-cells", + &host_address_cells, sizeof(host_address_cells)); + if (err <= 0) + return (-1); + + nbase_ranges = OF_getproplen(node, "ranges"); + if (nbase_ranges < 0) + return (-1); + sc->nranges = nbase_ranges / sizeof(cell_t) / + (sc->acells + host_address_cells + sc->scells); + if (sc->nranges == 0) + return (0); + + sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]), + M_DEVBUF, M_WAITOK); + base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); + OF_getencprop(node, "ranges", base_ranges, nbase_ranges); + + for (i = 0, j = 0; i < sc->nranges; i++) { + sc->ranges[i].bus = 0; + for (k = 0; k < sc->acells; k++) { + sc->ranges[i].bus <<= 32; + sc->ranges[i].bus |= base_ranges[j++]; + } + sc->ranges[i].host = 0; + for (k = 0; k < host_address_cells; k++) { + sc->ranges[i].host <<= 32; + sc->ranges[i].host |= base_ranges[j++]; + } + sc->ranges[i].size = 0; + for (k = 0; k < sc->scells; k++) { + sc->ranges[i].size <<= 32; + sc->ranges[i].size |= base_ranges[j++]; + } + } + + free(base_ranges, M_DEVBUF); + return (sc->nranges); +} static t_Handle fman_init(struct fman_softc *sc, struct fman_config *cfg) { - struct ofw_bus_devinfo obd; phandle_t node; t_FmParams fm_params; t_Handle muram_handle, fm_handle; @@ -166,9 +341,11 @@ fman_init(struct fman_softc *sc, struct fman_config *cfg) simplebus_init(sc->sc_base.dev, 0); node = ofw_bus_get_node(sc->sc_base.dev); + fman_fill_ranges(node, &sc->sc_base); + sc->rman.rm_type = RMAN_ARRAY; + sc->rman.rm_descr = "FMan range"; + rman_init_from_resource(&sc->rman, sc->mem_res); for (node = OF_child(node); node > 0; node = OF_peer(node)) { - if (ofw_bus_gen_setup_devinfo(&obd, node) != 0) - continue; simplebus_add_device(sc->sc_base.dev, node, 0, NULL, -1, NULL); } @@ -208,49 +385,31 @@ fman_error_callback(t_Handle app_handle, e_FmPortType port_type, */ int -fman_get_handle(t_Handle *fmh) +fman_get_handle(device_t dev, t_Handle *fmh) { + struct fman_softc *sc = device_get_softc(dev); - if (fm_sc == NULL) - return (ENOMEM); - - *fmh = fm_sc->fm_handle; + *fmh = sc->fm_handle; return (0); } int -fman_get_muram_handle(t_Handle *muramh) +fman_get_muram_handle(device_t dev, t_Handle *muramh) { + struct fman_softc *sc = device_get_softc(dev); - if (fm_sc == NULL) - return (ENOMEM); - - *muramh = fm_sc->muram_handle; + *muramh = sc->muram_handle; return (0); } int -fman_get_bushandle(vm_offset_t *fm_base) +fman_get_bushandle(device_t dev, vm_offset_t *fm_base) { + struct fman_softc *sc = device_get_softc(dev); - if (fm_sc == NULL) - return (ENOMEM); - - *fm_base = rman_get_bushandle(fm_sc->mem_res); - - return (0); -} - -int -fman_get_dev(device_t *fm_dev) -{ - - if (fm_sc == NULL) - return (ENOMEM); - - *fm_dev = fm_sc->sc_base.dev; + *fm_base = rman_get_bushandle(sc->mem_res); return (0); } @@ -265,7 +424,6 @@ fman_attach(device_t dev) sc = device_get_softc(dev); sc->sc_base.dev = dev; - fm_sc = sc; /* Check if MallocSmart allocator is ready */ if (XX_MallocSmartInit() != E_OK) { @@ -375,7 +533,7 @@ fman_suspend(device_t dev) } int -fman_resume(device_t dev) +fman_resume_dev(device_t dev) { return (0); diff --git a/sys/dev/dpaa/fman.h b/sys/dev/dpaa/fman.h index 96cdd86b0362..0d9070958796 100644 --- a/sys/dev/dpaa/fman.h +++ b/sys/dev/dpaa/fman.h @@ -39,6 +39,7 @@ struct fman_softc { struct resource *mem_res; struct resource *irq_res; struct resource *err_irq_res; + struct rman rman; int mem_rid; int irq_rid; int err_irq_rid; @@ -54,10 +55,16 @@ struct fman_softc { * @group QMan bus interface. * @{ */ +struct resource * fman_alloc_resource(device_t bus, device_t child, int type, + int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags); +int fman_activate_resource(device_t bus, device_t child, + int type, int rid, struct resource *res); +int fman_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *res); int fman_attach(device_t dev); int fman_detach(device_t dev); int fman_suspend(device_t dev); -int fman_resume(device_t dev); +int fman_resume_dev(device_t dev); int fman_shutdown(device_t dev); int fman_read_ivar(device_t dev, device_t child, int index, uintptr_t *result); @@ -65,9 +72,8 @@ int fman_qman_channel_id(device_t, int); /** @} */ uint32_t fman_get_clock(struct fman_softc *sc); -int fman_get_handle(t_Handle *fmh); -int fman_get_muram_handle(t_Handle *muramh); -int fman_get_bushandle(vm_offset_t *fm_base); -int fman_get_dev(device_t *fmd); +int fman_get_handle(device_t dev, t_Handle *fmh); +int fman_get_muram_handle(device_t dev, t_Handle *muramh); +int fman_get_bushandle(device_t dev, vm_offset_t *fm_base); #endif /* FMAN_H_ */ diff --git a/sys/dev/dpaa/fman_fdt.c b/sys/dev/dpaa/fman_fdt.c index b4693b5de956..6f7950f308c4 100644 --- a/sys/dev/dpaa/fman_fdt.c +++ b/sys/dev/dpaa/fman_fdt.c @@ -54,8 +54,11 @@ static device_method_t fman_methods[] = { DEVMETHOD(device_shutdown, fman_shutdown), DEVMETHOD(device_suspend, fman_suspend), - DEVMETHOD(device_resume, fman_resume), + DEVMETHOD(device_resume, fman_resume_dev), + DEVMETHOD(bus_alloc_resource, fman_alloc_resource), + DEVMETHOD(bus_activate_resource, fman_activate_resource), + DEVMETHOD(bus_release_resource, fman_release_resource), { 0, 0 } }; diff --git a/sys/dev/dpaa/fman_mdio.c b/sys/dev/dpaa/fman_mdio.c index fad7fea5e8ec..f6e9a4b7bfda 100644 --- a/sys/dev/dpaa/fman_mdio.c +++ b/sys/dev/dpaa/fman_mdio.c @@ -130,7 +130,7 @@ pqmdio_fdt_attach(device_t dev) sc = device_get_softc(dev); - fman_get_bushandle(&sc->sc_handle); + fman_get_bushandle(device_get_parent(dev), &sc->sc_handle); bus_get_resource(dev, SYS_RES_MEMORY, 0, &start, &count); sc->sc_offset = start; diff --git a/sys/dev/dpaa/if_dtsec.c b/sys/dev/dpaa/if_dtsec.c index 38f27fc847c3..d8c2e6643b3d 100644 --- a/sys/dev/dpaa/if_dtsec.c +++ b/sys/dev/dpaa/if_dtsec.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" +#include #include #include #include @@ -187,7 +188,7 @@ dtsec_fm_mac_init(struct dtsec_softc *sc, uint8_t *mac) memset(¶ms, 0, sizeof(params)); memcpy(¶ms.addr, mac, sizeof(params.addr)); - params.baseAddr = sc->sc_fm_base + sc->sc_mac_mem_offset; + params.baseAddr = rman_get_bushandle(sc->sc_mem); params.enetMode = sc->sc_mac_enet_mode; params.macId = sc->sc_eth_id; params.mdioIrq = sc->sc_mac_mdio_irq; @@ -568,15 +569,15 @@ int dtsec_attach(device_t dev) { struct dtsec_softc *sc; + device_t parent; int error; struct ifnet *ifp; sc = device_get_softc(dev); + parent = device_get_parent(dev); sc->sc_dev = dev; sc->sc_mac_mdio_irq = NO_IRQ; - sc->sc_eth_id = device_get_unit(dev); - /* Check if MallocSmart allocator is ready */ if (XX_MallocSmartInit() != E_OK) @@ -593,13 +594,13 @@ dtsec_attach(device_t dev) callout_init(&sc->sc_tick_callout, CALLOUT_MPSAFE); /* Read configuraton */ - if ((error = fman_get_handle(&sc->sc_fmh)) != 0) + if ((error = fman_get_handle(parent, &sc->sc_fmh)) != 0) return (error); - if ((error = fman_get_muram_handle(&sc->sc_muramh)) != 0) + if ((error = fman_get_muram_handle(parent, &sc->sc_muramh)) != 0) return (error); - if ((error = fman_get_bushandle(&sc->sc_fm_base)) != 0) + if ((error = fman_get_bushandle(parent, &sc->sc_fm_base)) != 0) return (error); /* Configure working mode */ diff --git a/sys/dev/dpaa/if_dtsec.h b/sys/dev/dpaa/if_dtsec.h index 0f9aa341d97e..609111274c0e 100644 --- a/sys/dev/dpaa/if_dtsec.h +++ b/sys/dev/dpaa/if_dtsec.h @@ -52,6 +52,7 @@ struct dtsec_softc { struct ifnet *sc_ifnet; device_t sc_dev; + struct resource *sc_mem; struct mtx sc_lock; int sc_mode; @@ -65,7 +66,7 @@ struct dtsec_softc { /* dTSEC data */ enum eth_dev_type sc_eth_dev_type; - uint8_t sc_eth_id; + uint8_t sc_eth_id; /* Ethernet ID within its frame manager */ uintptr_t sc_mac_mem_offset; e_EnetMode sc_mac_enet_mode; int sc_mac_mdio_irq; diff --git a/sys/dev/dpaa/if_dtsec_fdt.c b/sys/dev/dpaa/if_dtsec_fdt.c index b653fbd5f0c1..2e2b9a2c15d9 100644 --- a/sys/dev/dpaa/if_dtsec_fdt.c +++ b/sys/dev/dpaa/if_dtsec_fdt.c @@ -32,8 +32,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include + #include #include @@ -133,7 +136,8 @@ dtsec_fdt_attach(device_t dev) phandle_t enet_node, phy_node; phandle_t fman_rxtx_node[2]; char phy_type[6]; - pcell_t fman_tx_cell; + pcell_t fman_tx_cell, mac_id; + int rid; sc = device_get_softc(dev); enet_node = ofw_bus_get_node(dev); @@ -154,8 +158,9 @@ dtsec_fdt_attach(device_t dev) return(ENXIO); /* Get MAC memory offset in SoC */ - if (OF_getprop(enet_node, "reg", (void *)&sc->sc_mac_mem_offset, - sizeof(sc->sc_mac_mem_offset)) <= 0) + rid = 0; + sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (sc->sc_mem == NULL) return (ENXIO); /* Get PHY address */ @@ -187,6 +192,11 @@ dtsec_fdt_attach(device_t dev) else return (ENXIO); + if (OF_getencprop(enet_node, "cell-index", + (void *)&mac_id, sizeof(mac_id)) <= 0) + return (ENXIO); + sc->sc_eth_id = mac_id; + /* Get RX/TX port handles */ if (OF_getprop(enet_node, "fsl,fman-ports", (void *)fman_rxtx_node, sizeof(fman_rxtx_node)) <= 0) diff --git a/sys/dev/dpaa/if_dtsec_im.c b/sys/dev/dpaa/if_dtsec_im.c index 335f489cc591..cae0499c282b 100644 --- a/sys/dev/dpaa/if_dtsec_im.c +++ b/sys/dev/dpaa/if_dtsec_im.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" +#include #include #include #include diff --git a/sys/dev/dpaa/if_dtsec_rm.c b/sys/dev/dpaa/if_dtsec_rm.c index 7939ae10648e..e1b6cc77cf03 100644 --- a/sys/dev/dpaa/if_dtsec_rm.c +++ b/sys/dev/dpaa/if_dtsec_rm.c @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" +#include +#include #include #include #include @@ -150,7 +152,7 @@ dtsec_rm_fm_port_rx_init(struct dtsec_softc *sc, int unit) { t_FmPortParams params; t_FmPortRxParams *rx_params; - t_FmPortExtPools *pool_params; + t_FmExtPools *pool_params; t_Error error; memset(¶ms, 0, sizeof(params)); @@ -159,7 +161,7 @@ dtsec_rm_fm_port_rx_init(struct dtsec_softc *sc, int unit) params.h_Fm = sc->sc_fmh; params.portType = dtsec_fm_port_rx_type(sc->sc_eth_dev_type); params.portId = sc->sc_eth_id; - params.independentModeEnable = FALSE; + params.independentModeEnable = false; params.liodnBase = FM_PORT_LIODN_BASE; params.f_Exception = dtsec_fm_port_rx_exception_callback; params.h_App = sc; @@ -207,7 +209,7 @@ dtsec_rm_fm_port_tx_init(struct dtsec_softc *sc, int unit) params.h_Fm = sc->sc_fmh; params.portType = dtsec_fm_port_tx_type(sc->sc_eth_dev_type); params.portId = sc->sc_eth_id; - params.independentModeEnable = FALSE; + params.independentModeEnable = false; params.liodnBase = FM_PORT_LIODN_BASE; params.f_Exception = dtsec_fm_port_tx_exception_callback; params.h_App = sc; @@ -337,15 +339,17 @@ dtsec_rm_pool_rx_init(struct dtsec_softc *sc) * @{ */ static void -dtsec_rm_fqr_mext_free(struct mbuf *m, void *buffer, void *arg) +dtsec_rm_fqr_mext_free(struct mbuf *m) { struct dtsec_softc *sc; + void *buffer; - sc = arg; + buffer = m->m_ext.ext_arg1; + sc = m->m_ext.ext_arg2; if (bman_count(sc->sc_rx_pool) <= DTSEC_RM_POOL_RX_MAX_SIZE) bman_put_buffer(sc->sc_rx_pool, buffer); else - dtsec_rm_pool_rx_put_buffer(arg, buffer, NULL); + dtsec_rm_pool_rx_put_buffer(sc, buffer, NULL); } static e_RxStoreResponse @@ -454,7 +458,7 @@ dtsec_rm_fqr_rx_init(struct dtsec_softc *sc) /* Default Frame Queue */ fqr = qman_fqr_create(1, DTSEC_RM_FQR_RX_CHANNEL, DTSEC_RM_FQR_RX_WQ, - FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0); + false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create default RX queue" "\n"); @@ -493,7 +497,7 @@ dtsec_rm_fqr_tx_init(struct dtsec_softc *sc) /* TX Frame Queue */ fqr = qman_fqr_create(1, sc->sc_port_tx_qman_chan, - DTSEC_RM_FQR_TX_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0); + DTSEC_RM_FQR_TX_WQ, false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create default TX queue" "\n"); @@ -504,7 +508,7 @@ dtsec_rm_fqr_tx_init(struct dtsec_softc *sc) /* TX Confirmation Frame Queue */ fqr = qman_fqr_create(1, DTSEC_RM_FQR_TX_CONF_CHANNEL, - DTSEC_RM_FQR_TX_CONF_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, + DTSEC_RM_FQR_TX_CONF_WQ, false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create TX confirmation " @@ -637,9 +641,9 @@ dtsec_rm_if_start_locked(struct dtsec_softc *sc) DPAA_FD_SET_LENGTH(&fd, psize); DPAA_FD_SET_FORMAT(&fd, e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF); - DPAA_FD_SET_DD(&fd, 0); - DPAA_FD_SET_PID(&fd, 0); - DPAA_FD_SET_BPID(&fd, 0); + fd.liodn = 0; + fd.bpid = 0; + fd.elion = 0; DPAA_FD_SET_OFFSET(&fd, 0); DPAA_FD_SET_STATUS(&fd, 0); diff --git a/sys/dev/dpaa/portals.h b/sys/dev/dpaa/portals.h index 3f006768f97e..7714d34936b9 100644 --- a/sys/dev/dpaa/portals.h +++ b/sys/dev/dpaa/portals.h @@ -37,7 +37,7 @@ typedef struct dpaa_portal { vm_paddr_t dp_ci_pa; /* portal's CI area PA */ uint32_t dp_ce_size; /* portal's CE area size */ uint32_t dp_ci_size; /* portal's CI area size */ - uint32_t dp_intr_num; /* portal's intr. number */ + uintptr_t dp_intr_num; /* portal's intr. number */ } dpaa_portal_t; struct dpaa_portals_softc { diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index f0d66d9b2ff2..b29625fc0713 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -321,7 +321,7 @@ typedef struct drm_pci_id_list { int vendor; int device; - long driver_private; + intptr_t driver_private; char *name; } drm_pci_id_list_t; diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c index 621316d132b9..290e4c1595a5 100644 --- a/sys/dev/drm2/i915/i915_drv.c +++ b/sys/dev/drm2/i915/i915_drv.c @@ -1236,6 +1236,8 @@ MODULE_DEPEND(i915kms, agp, 1, 1, 1); MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); MODULE_DEPEND(i915kms, iic, 1, 1, 1); MODULE_DEPEND(i915kms, iicbb, 1, 1, 1); +MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:human", vgapci, i915, pciidlist, + sizeof(pciidlist[0]), nitems(pciidlist)); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c index 0fa5249e553b..40d432ce73f1 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm2/i915/i915_gem.c @@ -1890,8 +1890,7 @@ i915_gem_object_put_pages_range_locked(struct drm_i915_gem_object *obj, KASSERT(page->pindex == i, ("pindex %jx %jx", (uintmax_t)page->pindex, (uintmax_t)i)); vm_page_lock(page); - vm_page_unwire(page, PQ_INACTIVE); - if (page->wire_count == 0) + if (vm_page_unwire(page, PQ_INACTIVE)) atomic_add_long(&i915_gem_wired_pages_cnt, -1); vm_page_unlock(page); } @@ -4736,12 +4735,15 @@ i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh) int rv; VM_OBJECT_ASSERT_WLOCKED(object); - page = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); + page = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | + VM_ALLOC_WIRED); if (page->valid != VM_PAGE_BITS_ALL) { + vm_page_xbusy(page); if (vm_pager_has_page(object, pindex, NULL, NULL)) { rv = vm_pager_get_pages(object, &page, 1, NULL, NULL); if (rv != VM_PAGER_OK) { vm_page_lock(page); + vm_page_unwire(page, PQ_NONE); vm_page_free(page); vm_page_unlock(page); return (NULL); @@ -4755,13 +4757,9 @@ i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh) if (fresh != NULL) *fresh = false; } - } else if (fresh != NULL) { + vm_page_xunbusy(page); + } else if (fresh != NULL) *fresh = false; - } - vm_page_lock(page); - vm_page_wire(page); - vm_page_unlock(page); - vm_page_xunbusy(page); atomic_add_long(&i915_gem_wired_pages_cnt, 1); return (page); } diff --git a/sys/dev/drm2/i915/i915_gem_gtt.c b/sys/dev/drm2/i915/i915_gem_gtt.c index 5cd50ad96840..35b5900ac7ec 100644 --- a/sys/dev/drm2/i915/i915_gem_gtt.c +++ b/sys/dev/drm2/i915/i915_gem_gtt.c @@ -198,7 +198,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) free(ppgtt->pt_dma_addr, DRM_I915_GEM); for (i = 0; i < ppgtt->num_pd_entries; i++) { if (ppgtt->pt_pages[i]) { - vm_page_unwire(ppgtt->pt_pages[i], PQ_INACTIVE); + vm_page_unwire(ppgtt->pt_pages[i], PQ_NONE); vm_page_free(ppgtt->pt_pages[i]); } } @@ -228,7 +228,7 @@ void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) free(ppgtt->pt_dma_addr, DRM_I915_GEM); for (i = 0; i < ppgtt->num_pd_entries; i++) { - vm_page_unwire(ppgtt->pt_pages[i], PQ_INACTIVE); + vm_page_unwire(ppgtt->pt_pages[i], PQ_NONE); vm_page_free(ppgtt->pt_pages[i]); } free(ppgtt->pt_pages, DRM_I915_GEM); diff --git a/sys/dev/drm2/radeon/radeon_drv.c b/sys/dev/drm2/radeon/radeon_drv.c index fd0495927fd2..7fdaf5b993e6 100644 --- a/sys/dev/drm2/radeon/radeon_drv.c +++ b/sys/dev/drm2/radeon/radeon_drv.c @@ -401,3 +401,5 @@ MODULE_DEPEND(radeonkms, iicbus, 1, 1, 1); MODULE_DEPEND(radeonkms, iic, 1, 1, 1); MODULE_DEPEND(radeonkms, iicbb, 1, 1, 1); MODULE_DEPEND(radeonkms, firmware, 1, 1, 1); +MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:human", vgapci, radeonkms, + pciidlist, sizeof(pciidlist[0]), nitems(pciidlist)); diff --git a/sys/dev/e1000/e1000_80003es2lan.c b/sys/dev/e1000/e1000_80003es2lan.c index 7377d8e9d867..e7c42d5386eb 100644 --- a/sys/dev/e1000/e1000_80003es2lan.c +++ b/sys/dev/e1000/e1000_80003es2lan.c @@ -59,6 +59,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); +static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); @@ -67,6 +68,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); +static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); @@ -297,7 +299,7 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_phy_80003es2lan"); mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; - return e1000_acquire_swfw_sync(hw, mask); + return e1000_acquire_swfw_sync_80003es2lan(hw, mask); } /** @@ -313,7 +315,7 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_release_phy_80003es2lan"); mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; - e1000_release_swfw_sync(hw, mask); + e1000_release_swfw_sync_80003es2lan(hw, mask); } /** @@ -331,7 +333,7 @@ static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw) mask = E1000_SWFW_CSR_SM; - return e1000_acquire_swfw_sync(hw, mask); + return e1000_acquire_swfw_sync_80003es2lan(hw, mask); } /** @@ -348,7 +350,7 @@ static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw) mask = E1000_SWFW_CSR_SM; - e1000_release_swfw_sync(hw, mask); + e1000_release_swfw_sync_80003es2lan(hw, mask); } /** @@ -363,14 +365,14 @@ static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_nvm_80003es2lan"); - ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM); + ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); if (ret_val) return ret_val; ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) - e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM); + e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); return ret_val; } @@ -386,7 +388,78 @@ static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_release_nvm_80003es2lan"); e1000_release_nvm_generic(hw); - e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM); + e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); +} + +/** + * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Acquire the SW/FW semaphore to access the PHY or NVM. The mask + * will also specify which port we're acquiring the lock for. + **/ +static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 16; + s32 i = 0; + s32 timeout = 50; + + DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); + + while (i < timeout) { + if (e1000_get_hw_semaphore_generic(hw)) + return -E1000_ERR_SWFW_SYNC; + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + if (!(swfw_sync & (fwmask | swmask))) + break; + + /* Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) + */ + e1000_put_hw_semaphore_generic(hw); + msec_delay_irq(5); + i++; + } + + if (i == timeout) { + DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); + return -E1000_ERR_SWFW_SYNC; + } + + swfw_sync |= swmask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); + + return E1000_SUCCESS; +} + +/** + * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Release the SW/FW semaphore used to access the PHY or NVM. The mask + * will also specify which port we're releasing the lock for. + **/ +static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + + DEBUGFUNC("e1000_release_swfw_sync_80003es2lan"); + + while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) + ; /* Empty */ + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + swfw_sync &= ~mask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); } /** diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c index 38f7e0f90955..5ff17f098a21 100644 --- a/sys/dev/e1000/e1000_82571.c +++ b/sys/dev/e1000/e1000_82571.c @@ -70,8 +70,11 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw); static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data); static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); +static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw); static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, @@ -122,8 +125,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->ops.get_cable_length = e1000_get_cable_length_igp_2; phy->ops.read_reg = e1000_read_phy_reg_igp; phy->ops.write_reg = e1000_write_phy_reg_igp; - phy->ops.acquire = e1000_get_hw_semaphore; - phy->ops.release = e1000_put_hw_semaphore; + phy->ops.acquire = e1000_get_hw_semaphore_82571; + phy->ops.release = e1000_put_hw_semaphore_82571; break; case e1000_82573: phy->type = e1000_phy_m88; @@ -135,11 +138,12 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->ops.get_cable_length = e1000_get_cable_length_m88; phy->ops.read_reg = e1000_read_phy_reg_m88; phy->ops.write_reg = e1000_write_phy_reg_m88; - phy->ops.acquire = e1000_get_hw_semaphore; - phy->ops.release = e1000_put_hw_semaphore; + phy->ops.acquire = e1000_get_hw_semaphore_82571; + phy->ops.release = e1000_put_hw_semaphore_82571; break; case e1000_82574: case e1000_82583: + E1000_MUTEX_INIT(&hw->dev_spec._82571.swflag_mutex); phy->type = e1000_phy_bm; phy->ops.get_cfg_done = e1000_get_cfg_done_generic; @@ -502,21 +506,99 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) } /** - * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore + * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) +{ + u32 swsm; + s32 sw_timeout = hw->nvm.word_size + 1; + s32 fw_timeout = hw->nvm.word_size + 1; + s32 i = 0; + + DEBUGFUNC("e1000_get_hw_semaphore_82571"); + + /* If we have timedout 3 times on trying to acquire + * the inter-port SMBI semaphore, there is old code + * operating on the other port, and it is not + * releasing SMBI. Modify the number of times that + * we try for the semaphore to interwork with this + * older code. + */ + if (hw->dev_spec._82571.smb_counter > 2) + sw_timeout = 1; + + /* Get the SW semaphore */ + while (i < sw_timeout) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == sw_timeout) { + DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); + hw->dev_spec._82571.smb_counter++; + } + /* Get the FW semaphore. */ + for (i = 0; i < fw_timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + if (i == fw_timeout) { + /* Release semaphores */ + e1000_put_hw_semaphore_82571(hw); + DEBUGOUT("Driver can't access the NVM\n"); + return -E1000_ERR_NVM; + } + + return E1000_SUCCESS; +} + +/** + * e1000_put_hw_semaphore_82571 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) +{ + u32 swsm; + + DEBUGFUNC("e1000_put_hw_semaphore_generic"); + + swsm = E1000_READ_REG(hw, E1000_SWSM); + + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + + E1000_WRITE_REG(hw, E1000_SWSM, swsm); +} + +/** + * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore * @hw: pointer to the HW structure * * Acquire the HW semaphore during reset. * **/ -static s32 -e1000_get_hw_semaphore_82574(struct e1000_hw *hw) +static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) { u32 extcnf_ctrl; s32 i = 0; - /* XXX assert that mutex is held */ + DEBUGFUNC("e1000_get_hw_semaphore_82573"); - ASSERT_CTX_LOCK_HELD(hw); extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); do { extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; @@ -532,7 +614,7 @@ e1000_get_hw_semaphore_82574(struct e1000_hw *hw) if (i == MDIO_OWNERSHIP_TIMEOUT) { /* Release semaphores */ - e1000_put_hw_semaphore_82574(hw); + e1000_put_hw_semaphore_82573(hw); DEBUGOUT("Driver can't access the PHY\n"); return -E1000_ERR_PHY; } @@ -541,24 +623,58 @@ e1000_get_hw_semaphore_82574(struct e1000_hw *hw) } /** - * e1000_put_hw_semaphore_82574 - Release hardware semaphore + * e1000_put_hw_semaphore_82573 - Release hardware semaphore * @hw: pointer to the HW structure * * Release hardware semaphore used during reset. * **/ -static void -e1000_put_hw_semaphore_82574(struct e1000_hw *hw) +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) { u32 extcnf_ctrl; - DEBUGFUNC("e1000_put_hw_semaphore_82574"); + DEBUGFUNC("e1000_put_hw_semaphore_82573"); extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); } +/** + * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM. + * + **/ +static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) +{ + s32 ret_val; + + DEBUGFUNC("e1000_get_hw_semaphore_82574"); + + E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex); + ret_val = e1000_get_hw_semaphore_82573(hw); + if (ret_val) + E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex); + return ret_val; +} + +/** + * e1000_put_hw_semaphore_82574 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + * + **/ +static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_put_hw_semaphore_82574"); + + e1000_put_hw_semaphore_82573(hw); + E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex); +} + /** * e1000_set_d0_lplu_state_82574 - Set Low Power Linkup D0 state * @hw: pointer to the HW structure @@ -630,7 +746,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_nvm_82571"); - ret_val = e1000_get_hw_semaphore(hw); + ret_val = e1000_get_hw_semaphore_82571(hw); if (ret_val) return ret_val; @@ -643,7 +759,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) } if (ret_val) - e1000_put_hw_semaphore(hw); + e1000_put_hw_semaphore_82571(hw); return ret_val; } @@ -659,7 +775,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_release_nvm_82571"); e1000_release_nvm_generic(hw); - e1000_put_hw_semaphore(hw); + e1000_put_hw_semaphore_82571(hw); } /** @@ -976,6 +1092,8 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) */ switch (hw->mac.type) { case e1000_82573: + ret_val = e1000_get_hw_semaphore_82573(hw); + break; case e1000_82574: case e1000_82583: ret_val = e1000_get_hw_semaphore_82574(hw); @@ -992,6 +1110,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) /* Must release MDIO ownership and mutex after MAC reset. */ switch (hw->mac.type) { case e1000_82573: + /* Release mutex only if the hw semaphore is acquired */ + if (!ret_val) + e1000_put_hw_semaphore_82573(hw); + break; case e1000_82574: case e1000_82583: /* Release mutex only if the hw semaphore is acquired */ @@ -999,7 +1121,6 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) e1000_put_hw_semaphore_82574(hw); break; default: - panic("unknown mac type %x\n", hw->mac.type); break; } diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c index 064731a7d551..5d68e8b9718c 100644 --- a/sys/dev/e1000/e1000_82575.c +++ b/sys/dev/e1000/e1000_82575.c @@ -79,9 +79,11 @@ static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data); static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data); static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); +static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex); static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); +static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); static bool e1000_sgmii_active_82575(struct e1000_hw *hw); static s32 e1000_reset_init_script_82575(struct e1000_hw *hw); static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw); @@ -509,8 +511,12 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_82575; /* acquire SW_FW sync */ - mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync; - mac->ops.release_swfw_sync = e1000_release_swfw_sync; + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575; + if (mac->type >= e1000_i210) { + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210; + } /* set lan id for port to determine which phy lock to use */ hw->mac.ops.set_lan_id(hw); @@ -982,7 +988,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_nvm_82575"); - ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM); + ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); if (ret_val) goto out; @@ -1013,7 +1019,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) - e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM); + e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); out: return ret_val; @@ -1032,7 +1038,83 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw) e1000_release_nvm_generic(hw); - e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM); + e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); +} + +/** + * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Acquire the SW/FW semaphore to access the PHY or NVM. The mask + * will also specify which port we're acquiring the lock for. + **/ +static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 16; + s32 ret_val = E1000_SUCCESS; + s32 i = 0, timeout = 200; + + DEBUGFUNC("e1000_acquire_swfw_sync_82575"); + + while (i < timeout) { + if (e1000_get_hw_semaphore_generic(hw)) { + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + if (!(swfw_sync & (fwmask | swmask))) + break; + + /* + * Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) + */ + e1000_put_hw_semaphore_generic(hw); + msec_delay_irq(5); + i++; + } + + if (i == timeout) { + DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync |= swmask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); + +out: + return ret_val; +} + +/** + * e1000_release_swfw_sync_82575 - Release SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Release the SW/FW semaphore used to access the PHY or NVM. The mask + * will also specify which port we're releasing the lock for. + **/ +static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + + DEBUGFUNC("e1000_release_swfw_sync_82575"); + + while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) + ; /* Empty */ + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + swfw_sync &= ~mask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); } /** diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h index c90066dc9435..e1464a7b655a 100644 --- a/sys/dev/e1000/e1000_hw.h +++ b/sys/dev/e1000/e1000_hw.h @@ -934,6 +934,7 @@ struct e1000_dev_spec_82543 { struct e1000_dev_spec_82571 { bool laa_is_present; u32 smb_counter; + E1000_MUTEX swflag_mutex; }; struct e1000_dev_spec_80003es2lan { @@ -957,6 +958,8 @@ enum e1000_ulp_state { struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS]; + E1000_MUTEX nvm_mutex; + E1000_MUTEX swflag_mutex; bool nvm_k1_enabled; bool disable_k1_off; bool eee_disable; diff --git a/sys/dev/e1000/e1000_i210.c b/sys/dev/e1000/e1000_i210.c index f03fbac1f13d..cd8d7c7e1f56 100644 --- a/sys/dev/e1000/e1000_i210.c +++ b/sys/dev/e1000/e1000_i210.c @@ -37,6 +37,7 @@ static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw); static void e1000_release_nvm_i210(struct e1000_hw *hw); +static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw); static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw); @@ -57,7 +58,7 @@ static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_nvm_i210"); - ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM); + ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); return ret_val; } @@ -73,7 +74,152 @@ static void e1000_release_nvm_i210(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_i210"); - e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM); + e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); +} + +/** + * e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Acquire the SW/FW semaphore to access the PHY or NVM. The mask + * will also specify which port we're acquiring the lock for. + **/ +s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 16; + s32 ret_val = E1000_SUCCESS; + s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ + + DEBUGFUNC("e1000_acquire_swfw_sync_i210"); + + while (i < timeout) { + if (e1000_get_hw_semaphore_i210(hw)) { + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + if (!(swfw_sync & (fwmask | swmask))) + break; + + /* + * Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) + */ + e1000_put_hw_semaphore_generic(hw); + msec_delay_irq(5); + i++; + } + + if (i == timeout) { + DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync |= swmask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); + +out: + return ret_val; +} + +/** + * e1000_release_swfw_sync_i210 - Release SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Release the SW/FW semaphore used to access the PHY or NVM. The mask + * will also specify which port we're releasing the lock for. + **/ +void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + + DEBUGFUNC("e1000_release_swfw_sync_i210"); + + while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS) + ; /* Empty */ + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + swfw_sync &= ~mask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_generic(hw); +} + +/** + * e1000_get_hw_semaphore_i210 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) +{ + u32 swsm; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + DEBUGFUNC("e1000_get_hw_semaphore_i210"); + + /* Get the SW semaphore */ + while (i < timeout) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == timeout) { + /* In rare circumstances, the SW semaphore may already be held + * unintentionally. Clear the semaphore once before giving up. + */ + if (hw->dev_spec._82575.clear_semaphore_once) { + hw->dev_spec._82575.clear_semaphore_once = FALSE; + e1000_put_hw_semaphore_generic(hw); + for (i = 0; i < timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + } + } + + /* If we do not have the semaphore here, we have to give up. */ + if (i == timeout) { + DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + } + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + if (i == timeout) { + /* Release semaphores */ + e1000_put_hw_semaphore_generic(hw); + DEBUGOUT("Driver can't access the NVM\n"); + return -E1000_ERR_NVM; + } + + return E1000_SUCCESS; } /** diff --git a/sys/dev/e1000/e1000_i210.h b/sys/dev/e1000/e1000_i210.h index 960e2c5a730f..f940915b0619 100644 --- a/sys/dev/e1000/e1000_i210.h +++ b/sys/dev/e1000/e1000_i210.h @@ -43,6 +43,8 @@ s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); +s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data); s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c index ebb5aad94494..9be9ac799d94 100644 --- a/sys/dev/e1000/e1000_ich8lan.c +++ b/sys/dev/e1000/e1000_ich8lan.c @@ -694,6 +694,9 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) dev_spec->shadow_ram[i].value = 0xFFFF; } + E1000_MUTEX_INIT(&dev_spec->nvm_mutex); + E1000_MUTEX_INIT(&dev_spec->swflag_mutex); + /* Function Pointers */ nvm->ops.acquire = e1000_acquire_nvm_ich8lan; nvm->ops.release = e1000_release_nvm_ich8lan; @@ -1844,7 +1847,7 @@ static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_acquire_nvm_ich8lan"); - ASSERT_CTX_LOCK_HELD(hw); + E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.nvm_mutex); return E1000_SUCCESS; } @@ -1859,7 +1862,9 @@ static void e1000_release_nvm_ich8lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_ich8lan"); - ASSERT_CTX_LOCK_HELD(hw); + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.nvm_mutex); + + return; } /** @@ -1876,7 +1881,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_swflag_ich8lan"); - ASSERT_CTX_LOCK_HELD(hw); + E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.swflag_mutex); while (timeout) { extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); @@ -1917,6 +1922,9 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) } out: + if (ret_val) + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); + return ret_val; } @@ -1941,6 +1949,10 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) } else { DEBUGOUT("Semaphore unexpectedly released by sw/fw/hw\n"); } + + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); + + return; } /** @@ -5010,6 +5022,8 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FEXTNVM3, reg); } + if (!ret_val) + E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex); if (ctrl & E1000_CTRL_PHY_RST) { ret_val = hw->phy.ops.get_cfg_done(hw); diff --git a/sys/dev/e1000/e1000_mac.c b/sys/dev/e1000/e1000_mac.c index 2140ba985e2f..1c863073f082 100644 --- a/sys/dev/e1000/e1000_mac.c +++ b/sys/dev/e1000/e1000_mac.c @@ -1706,6 +1706,76 @@ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSED return E1000_SUCCESS; } +/** + * e1000_get_hw_semaphore_generic - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) +{ + u32 swsm; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + DEBUGFUNC("e1000_get_hw_semaphore_generic"); + + /* Get the SW semaphore */ + while (i < timeout) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == timeout) { + DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + if (i == timeout) { + /* Release semaphores */ + e1000_put_hw_semaphore_generic(hw); + DEBUGOUT("Driver can't access the NVM\n"); + return -E1000_ERR_NVM; + } + + return E1000_SUCCESS; +} + +/** + * e1000_put_hw_semaphore_generic - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +void e1000_put_hw_semaphore_generic(struct e1000_hw *hw) +{ + u32 swsm; + + DEBUGFUNC("e1000_put_hw_semaphore_generic"); + + swsm = E1000_READ_REG(hw, E1000_SWSM); + + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + + E1000_WRITE_REG(hw, E1000_SWSM, swsm); +} + /** * e1000_get_auto_rd_done_generic - Check for auto read completion * @hw: pointer to the HW structure @@ -2181,186 +2251,3 @@ s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, return E1000_SUCCESS; } - -/** - * e1000_get_hw_semaphore - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore to access the PHY or NVM - **/ -s32 e1000_get_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - s32 timeout = hw->nvm.word_size + 1; - s32 i = 0; - - DEBUGFUNC("e1000_get_hw_semaphore"); -#ifdef notyet - /* _82571 */ - /* If we have timedout 3 times on trying to acquire - * the inter-port SMBI semaphore, there is old code - * operating on the other port, and it is not - * releasing SMBI. Modify the number of times that - * we try for the semaphore to interwork with this - * older code. - */ - if (hw->dev_spec._82571.smb_counter > 2) - sw_timeout = 1; - -#endif - /* Get the SW semaphore */ - while (i < timeout) { - swsm = E1000_READ_REG(hw, E1000_SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - usec_delay(50); - i++; - } - - if (i == timeout) { -#ifdef notyet - /* - * XXX This sounds more like a driver bug whereby we either - * recursed accidentally or missed clearing it previously - */ - /* In rare circumstances, the SW semaphore may already be held - * unintentionally. Clear the semaphore once before giving up. - */ - if (hw->dev_spec._82575.clear_semaphore_once) { - hw->dev_spec._82575.clear_semaphore_once = FALSE; - e1000_put_hw_semaphore_generic(hw); - for (i = 0; i < timeout; i++) { - swsm = E1000_READ_REG(hw, E1000_SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - usec_delay(50); - } - } -#endif - - DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); - return -E1000_ERR_NVM; - } - - /* Get the FW semaphore. */ - for (i = 0; i < timeout; i++) { - swsm = E1000_READ_REG(hw, E1000_SWSM); - E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); - - /* Semaphore acquired if bit latched */ - if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) - break; - - usec_delay(50); - } - - if (i == timeout) { - /* Release semaphores */ - e1000_put_hw_semaphore(hw); - DEBUGOUT("Driver can't access the NVM\n"); - return -E1000_ERR_NVM; - } - - return E1000_SUCCESS; -} - -/** - * e1000_put_hw_semaphore - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -void e1000_put_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - - DEBUGFUNC("e1000_put_hw_semaphore"); - - swsm = E1000_READ_REG(hw, E1000_SWSM); - - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); - - E1000_WRITE_REG(hw, E1000_SWSM, swsm); -} - - -/** - * e1000_acquire_swfw_sync - Acquire SW/FW semaphore - * @hw: pointer to the HW structure - * @mask: specifies which semaphore to acquire - * - * Acquire the SW/FW semaphore to access the PHY or NVM. The mask - * will also specify which port we're acquiring the lock for. - **/ -s32 -e1000_acquire_swfw_sync(struct e1000_hw *hw, u16 mask) -{ - u32 swfw_sync; - u32 swmask = mask; - u32 fwmask = mask << 16; - s32 ret_val = E1000_SUCCESS; - s32 i = 0, timeout = 200; - - DEBUGFUNC("e1000_acquire_swfw_sync"); - ASSERT_NO_LOCKS(); - while (i < timeout) { - if (e1000_get_hw_semaphore(hw)) { - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } - - swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); - if (!(swfw_sync & (fwmask | swmask))) - break; - - /* - * Firmware currently using resource (fwmask) - * or other software thread using resource (swmask) - */ - e1000_put_hw_semaphore(hw); - msec_delay_irq(5); - i++; - } - - if (i == timeout) { - DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } - - swfw_sync |= swmask; - E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); - - e1000_put_hw_semaphore(hw); - -out: - return ret_val; -} - -/** - * e1000_release_swfw_sync - Release SW/FW semaphore - * @hw: pointer to the HW structure - * @mask: specifies which semaphore to acquire - * - * Release the SW/FW semaphore used to access the PHY or NVM. The mask - * will also specify which port we're releasing the lock for. - **/ -void -e1000_release_swfw_sync(struct e1000_hw *hw, u16 mask) -{ - u32 swfw_sync; - - DEBUGFUNC("e1000_release_swfw_sync"); - - while (e1000_get_hw_semaphore(hw) != E1000_SUCCESS) - ; /* Empty */ - - swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); - swfw_sync &= ~mask; - E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); - - e1000_put_hw_semaphore(hw); -} - diff --git a/sys/dev/e1000/e1000_mac.h b/sys/dev/e1000/e1000_mac.h index 2953bd52364f..ef9789bbb537 100644 --- a/sys/dev/e1000/e1000_mac.h +++ b/sys/dev/e1000/e1000_mac.h @@ -60,6 +60,7 @@ s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw); s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw); void e1000_set_lan_id_single_port(struct e1000_hw *hw); void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw); +s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw); s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, u16 *duplex); s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, @@ -84,15 +85,11 @@ void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw); void e1000_clear_vfta_generic(struct e1000_hw *hw); void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count); void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw); +void e1000_put_hw_semaphore_generic(struct e1000_hw *hw); s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw); void e1000_reset_adaptive_generic(struct e1000_hw *hw); void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop); void e1000_update_adaptive_generic(struct e1000_hw *hw); void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); -s32 e1000_get_hw_semaphore(struct e1000_hw *hw); -void e1000_put_hw_semaphore(struct e1000_hw *hw); -s32 e1000_acquire_swfw_sync(struct e1000_hw *hw, u16 mask); -void e1000_release_swfw_sync(struct e1000_hw *hw, u16 mask); - #endif diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h index 840bbfcfcdce..c7c23e582ca9 100644 --- a/sys/dev/e1000/e1000_osdep.h +++ b/sys/dev/e1000/e1000_osdep.h @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -48,14 +47,6 @@ #include #include #include - -#include -#include -#include -#include - - - #include #include #include @@ -67,40 +58,11 @@ #define ASSERT(x) if(!(x)) panic("EM: x") -#define us_scale(x) max(1, (x/(1000000/hz))) -static inline int -ms_scale(int x) { - if (hz == 1000) { - return (x); - } else if (hz > 1000) { - return (x*(hz/1000)); - } else { - return (max(1, x/(1000/hz))); - } -} -static inline void -safe_pause_us(int x) { - if (cold) { - DELAY(x); - } else { - pause("e1000_delay", max(1, x/(1000000/hz))); - } -} - -static inline void -safe_pause_ms(int x) { - if (cold) { - DELAY(x*1000); - } else { - pause("e1000_delay", ms_scale(x)); - } -} - -#define usec_delay(x) safe_pause_us(x) +#define usec_delay(x) DELAY(x) #define usec_delay_irq(x) usec_delay(x) -#define msec_delay(x) safe_pause_ms(x) -#define msec_delay_irq(x) msec_delay(x) +#define msec_delay(x) DELAY(1000*(x)) +#define msec_delay_irq(x) DELAY(1000*(x)) /* Enable/disable debugging statements in shared code */ #define DBG 0 @@ -119,6 +81,16 @@ safe_pause_ms(int x) { #define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ #define PCI_COMMAND_REGISTER PCIR_COMMAND +/* Mutex used in the shared code */ +#define E1000_MUTEX struct mtx +#define E1000_MUTEX_INIT(mutex) mtx_init((mutex), #mutex, \ + MTX_NETWORK_LOCK, \ + MTX_DEF | MTX_DUPOK) +#define E1000_MUTEX_DESTROY(mutex) mtx_destroy(mutex) +#define E1000_MUTEX_LOCK(mutex) mtx_lock(mutex) +#define E1000_MUTEX_TRYLOCK(mutex) mtx_trylock(mutex) +#define E1000_MUTEX_UNLOCK(mutex) mtx_unlock(mutex) + typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; @@ -144,12 +116,6 @@ typedef int8_t s8; #endif #endif /*__FreeBSD_version < 800000 */ -#ifdef INVARIANTS -#define ASSERT_CTX_LOCK_HELD(hw) (sx_assert(iflib_ctx_lock_get(((struct e1000_osdep *)hw->back)->ctx), SX_XLOCKED)) -#else -#define ASSERT_CTX_LOCK_HELD(hw) -#endif - #if defined(__i386__) || defined(__amd64__) static __inline void prefetch(void *x) @@ -169,7 +135,6 @@ struct e1000_osdep bus_space_tag_t flash_bus_space_tag; bus_space_handle_t flash_bus_space_handle; device_t dev; - if_ctx_t ctx; }; #define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \ @@ -251,22 +216,5 @@ struct e1000_osdep bus_space_write_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \ ((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value) - -#if defined(INVARIANTS) -#include - -#define ASSERT_NO_LOCKS() \ - do { \ - int unknown_locks = curthread->td_locks - mtx_owned(&Giant); \ - if (unknown_locks > 0) { \ - WITNESS_WARN(WARN_GIANTOK|WARN_SLEEPOK|WARN_PANIC, NULL, "unexpected non-sleepable lock"); \ - } \ - MPASS(curthread->td_rw_rlocks == 0); \ - MPASS(curthread->td_lk_slocks == 0); \ - } while (0) -#else -#define ASSERT_NO_LOCKS() -#endif - #endif /* _FREEBSD_OS_H_ */ diff --git a/sys/dev/e1000/em_txrx.c b/sys/dev/e1000/em_txrx.c index 6e3ddedc65d0..22e983b370a0 100644 --- a/sys/dev/e1000/em_txrx.c +++ b/sys/dev/e1000/em_txrx.c @@ -66,7 +66,6 @@ static void em_receive_checksum(uint32_t status, if_rxd_info_t ri); static int em_determine_rsstype(u32 pkt_info); extern int em_intr(void *arg); - struct if_txrx em_txrx = { em_isc_txd_encap, em_isc_txd_flush, @@ -75,7 +74,7 @@ struct if_txrx em_txrx = { em_isc_rxd_pkt_get, em_isc_rxd_refill, em_isc_rxd_flush, - em_intr, + em_intr }; struct if_txrx lem_txrx = { @@ -86,7 +85,7 @@ struct if_txrx lem_txrx = { lem_isc_rxd_pkt_get, lem_isc_rxd_refill, em_isc_rxd_flush, - em_intr, + em_intr }; extern if_shared_ctx_t em_sctx; @@ -524,8 +523,8 @@ em_isc_rxd_refill(void *arg, if_rxd_update_t iru) for (i = 0, next_pidx = pidx; i < count; i++) { rxd = &rxr->rx_base[next_pidx]; rxd->read.buffer_addr = htole64(paddrs[i]); - /* Zero out rx desc status */ - rxd->wb.upper.status_error &= htole32(~0xFF); + /* DD bits must be cleared */ + rxd->wb.upper.status_error = 0; if (++next_pidx == scctx->isc_nrxd[0]) next_pidx = 0; @@ -552,9 +551,14 @@ lem_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) struct e1000_rx_desc *rxd; u32 staterr = 0; int cnt, i; - budget = min(budget, scctx->isc_nrxd[0]); - for (cnt = 0, i = idx; cnt <= budget;) { + if (budget == 1) { + rxd = (struct e1000_rx_desc *)&rxr->rx_base[idx]; + staterr = rxd->status; + return (staterr & E1000_RXD_STAT_DD); + } + + for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) { rxd = (struct e1000_rx_desc *)&rxr->rx_base[i]; staterr = rxd->status; @@ -567,7 +571,6 @@ lem_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) if (staterr & E1000_RXD_STAT_EOP) cnt++; } - MPASS(cnt <= scctx->isc_nrxd[0]); return (cnt); } @@ -581,9 +584,14 @@ em_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) union e1000_rx_desc_extended *rxd; u32 staterr = 0; int cnt, i; - budget = min(budget, scctx->isc_nrxd[0]); - for (cnt = 0, i = idx; cnt <= budget;) { + if (budget == 1) { + rxd = &rxr->rx_base[idx]; + staterr = le32toh(rxd->wb.upper.status_error); + return (staterr & E1000_RXD_STAT_DD); + } + + for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) { rxd = &rxr->rx_base[i]; staterr = le32toh(rxd->wb.upper.status_error); @@ -598,7 +606,6 @@ em_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) cnt++; } - MPASS(cnt <= scctx->isc_nrxd[0]); return (cnt); } @@ -687,8 +694,7 @@ em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri) pkt_info = le32toh(rxd->wb.lower.mrq); /* Error Checking then decrement count */ - KASSERT(staterr & E1000_RXD_STAT_DD, - ("cidx=%d i=%d iri_len=%d", cidx, i, ri->iri_len)); + MPASS ((staterr & E1000_RXD_STAT_DD) != 0); len = le16toh(rxd->wb.upper.length); ri->iri_len += len; diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 516c27d25be4..9f50d5e6c0e1 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -339,6 +339,8 @@ MODULE_DEPEND(em, pci, 1, 1, 1); MODULE_DEPEND(em, ether, 1, 1, 1); MODULE_DEPEND(em, iflib, 1, 1, 1); +IFLIB_PNP_INFO(pci, em, em_vendor_info_array); + static driver_t igb_driver = { "igb", igb_methods, sizeof(struct adapter), }; @@ -350,6 +352,7 @@ MODULE_DEPEND(igb, pci, 1, 1, 1); MODULE_DEPEND(igb, ether, 1, 1, 1); MODULE_DEPEND(igb, iflib, 1, 1, 1); +IFLIB_PNP_INFO(pci, igb, igb_vendor_info_array); static device_method_t em_if_methods[] = { DEVMETHOD(ifdi_attach_pre, em_if_attach_pre), @@ -483,7 +486,7 @@ static struct if_shared_ctx em_sctx_init = { .isc_vendor_info = em_vendor_info_array, .isc_driver_version = em_driver_version, .isc_driver = &em_if_driver, - .isc_flags = IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM, + .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM, .isc_nrxd_min = {EM_MIN_RXD}, .isc_ntxd_min = {EM_MIN_TXD}, @@ -511,7 +514,7 @@ static struct if_shared_ctx igb_sctx_init = { .isc_vendor_info = igb_vendor_info_array, .isc_driver_version = em_driver_version, .isc_driver = &em_if_driver, - .isc_flags = IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM, + .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM, .isc_nrxd_min = {EM_MIN_RXD}, .isc_ntxd_min = {EM_MIN_TXD}, @@ -723,7 +726,7 @@ em_if_attach_pre(if_ctx_t ctx) return (ENXIO); } - adapter->ctx = adapter->osdep.ctx = ctx; + adapter->ctx = ctx; adapter->dev = adapter->osdep.dev = dev; scctx = adapter->shared = iflib_get_softc_ctx(ctx); adapter->media = iflib_get_media(ctx); @@ -1405,9 +1408,7 @@ em_msix_link(void *arg) { struct adapter *adapter = arg; u32 reg_icr; - int is_igb; - is_igb = (adapter->hw.mac.type >= igb_mac_min); ++adapter->link_irq; MPASS(adapter->hw.back != NULL); reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); @@ -1415,29 +1416,26 @@ em_msix_link(void *arg) if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; - if (is_igb) { - if (reg_icr & E1000_ICR_LSC) - em_handle_link(adapter->ctx); - E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_LSC); - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask); + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + em_handle_link(adapter->ctx); } else { - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - em_handle_link(adapter->ctx); - } E1000_WRITE_REG(&adapter->hw, E1000_IMS, - EM_MSIX_LINK | E1000_IMS_LSC); - - /* - * Because we must read the ICR for this interrupt - * it may clear other causes using autoclear, for - * this reason we simply create a soft interrupt - * for all these vectors. - */ - if (reg_icr) { - E1000_WRITE_REG(&adapter->hw, - E1000_ICS, adapter->ims); - } + EM_MSIX_LINK | E1000_IMS_LSC); + if (adapter->hw.mac.type >= igb_mac_min) + E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask); } + + /* + * Because we must read the ICR for this interrupt + * it may clear other causes using autoclear, for + * this reason we simply create a soft interrupt + * for all these vectors. + */ + if (reg_icr && adapter->hw.mac.type < igb_mac_min) { + E1000_WRITE_REG(&adapter->hw, + E1000_ICS, adapter->ims); + } + return (FILTER_HANDLED); } @@ -1675,6 +1673,13 @@ em_if_timer(if_ctx_t ctx, uint16_t qid) return; iflib_admin_intr_deferred(ctx); + /* Reset LAA into RAR[0] on 82571 */ + if ((adapter->hw.mac.type == e1000_82571) && + e1000_get_laa_state_82571(&adapter->hw)) + e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); + + if (adapter->hw.mac.type < em_mac_min) + lem_smartspeed(adapter); /* Mask to use in the irq trigger */ if (adapter->intr_type == IFLIB_INTR_MSIX) { @@ -1785,14 +1790,6 @@ em_if_update_admin_status(if_ctx_t ctx) } em_update_stats_counters(adapter); - /* Reset LAA into RAR[0] on 82571 */ - if ((adapter->hw.mac.type == e1000_82571) && - e1000_get_laa_state_82571(&adapter->hw)) - e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); - - if (adapter->hw.mac.type < em_mac_min) - lem_smartspeed(adapter); - E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC); } @@ -1908,87 +1905,6 @@ em_allocate_pci_resources(if_ctx_t ctx) return (0); } -static int -igb_intr_assign(if_ctx_t ctx, int msix) -{ - struct adapter *adapter = iflib_get_softc(ctx); - struct em_rx_queue *rx_que = adapter->rx_queues; - struct em_tx_queue *tx_que = adapter->tx_queues; - int error, rid, i, vector = 0, rx_vectors; - char buf[16]; - - /* First set up ring resources */ - for (i = 0; i < adapter->rx_num_queues; i++, rx_que++, vector++) { - rid = vector + 1; - snprintf(buf, sizeof(buf), "rxq%d", i); - error = iflib_irq_alloc_generic(ctx, &rx_que->que_irq, rid, IFLIB_INTR_RXTX, - em_msix_que, rx_que, rx_que->me, buf); - if (error) { - device_printf(iflib_get_dev(ctx), "Failed to allocate que int %d err: %d\n", i, error); - adapter->rx_num_queues = i; - goto fail; - } - - rx_que->msix = vector; - - /* - * Set the bit to enable interrupt - * in E1000_IMS -- bits 20 and 21 - * are for RX0 and RX1, note this has - * NOTHING to do with the MSIX vector - */ - if (adapter->hw.mac.type == e1000_82574) { - rx_que->eims = 1 << (20 + i); - adapter->ims |= rx_que->eims; - adapter->ivars |= (8 | rx_que->msix) << (i * 4); - } else if (adapter->hw.mac.type == e1000_82575) - rx_que->eims = E1000_EICR_TX_QUEUE0 << vector; - else - rx_que->eims = 1 << vector; - } - rx_vectors = vector; - - vector = 0; - for (i = 0; i < adapter->tx_num_queues; i++, tx_que++, vector++) { - snprintf(buf, sizeof(buf), "txq%d", i); - tx_que = &adapter->tx_queues[i]; - tx_que->msix = adapter->rx_queues[i % adapter->rx_num_queues].msix; - rid = rman_get_start(adapter->rx_queues[i % adapter->rx_num_queues].que_irq.ii_res); - iflib_softirq_alloc_generic(ctx, rid, IFLIB_INTR_TX, tx_que, tx_que->me, buf); - - if (adapter->hw.mac.type == e1000_82574) { - tx_que->eims = 1 << (22 + i); - adapter->ims |= tx_que->eims; - adapter->ivars |= (8 | tx_que->msix) << (8 + (i * 4)); - } else if (adapter->hw.mac.type == e1000_82575) { - tx_que->eims = E1000_EICR_TX_QUEUE0 << (i % adapter->tx_num_queues); - } else { - tx_que->eims = 1 << (i % adapter->tx_num_queues); - } - } - - /* Link interrupt */ - rid = rx_vectors + 1; - error = iflib_irq_alloc_generic(ctx, &adapter->irq, rid, IFLIB_INTR_ADMIN, em_msix_link, adapter, 0, "aq"); - - if (error) { - device_printf(iflib_get_dev(ctx), "Failed to register admin handler"); - goto fail; - } - adapter->linkvec = rx_vectors; - if (adapter->hw.mac.type < igb_mac_min) { - adapter->ivars |= (8 | rx_vectors) << 16; - adapter->ivars |= 0x80000000; - } - return (0); -fail: - iflib_irq_free(ctx, &adapter->irq); - rx_que = adapter->rx_queues; - for (int i = 0; i < adapter->rx_num_queues; i++, rx_que++) - iflib_irq_free(ctx, &rx_que->que_irq); - return (error); -} - /********************************************************************* * * Setup the MSIX Interrupt handlers @@ -2000,18 +1916,14 @@ em_if_msix_intr_assign(if_ctx_t ctx, int msix) struct adapter *adapter = iflib_get_softc(ctx); struct em_rx_queue *rx_que = adapter->rx_queues; struct em_tx_queue *tx_que = adapter->tx_queues; - int error, rid, i, vector = 0; + int error, rid, i, vector = 0, rx_vectors; char buf[16]; - if (adapter->hw.mac.type >= igb_mac_min) { - return igb_intr_assign(ctx, msix); - } - /* First set up ring resources */ for (i = 0; i < adapter->rx_num_queues; i++, rx_que++, vector++) { rid = vector + 1; snprintf(buf, sizeof(buf), "rxq%d", i); - error = iflib_irq_alloc_generic(ctx, &rx_que->que_irq, rid, IFLIB_INTR_RX, em_msix_que, rx_que, rx_que->me, buf); + error = iflib_irq_alloc_generic(ctx, &rx_que->que_irq, rid, IFLIB_INTR_RXTX, em_msix_que, rx_que, rx_que->me, buf); if (error) { device_printf(iflib_get_dev(ctx), "Failed to allocate que int %d err: %d", i, error); adapter->rx_num_queues = i + 1; @@ -2035,19 +1947,18 @@ em_if_msix_intr_assign(if_ctx_t ctx, int msix) else rx_que->eims = 1 << vector; } + rx_vectors = vector; + vector = 0; for (i = 0; i < adapter->tx_num_queues; i++, tx_que++, vector++) { rid = vector + 1; snprintf(buf, sizeof(buf), "txq%d", i); tx_que = &adapter->tx_queues[i]; + iflib_softirq_alloc_generic(ctx, + &adapter->rx_queues[i % adapter->rx_num_queues].que_irq, + IFLIB_INTR_TX, tx_que, tx_que->me, buf); - error = iflib_irq_alloc_generic(ctx, &tx_que->que_irq, rid, IFLIB_INTR_TX, em_msix_que, tx_que, tx_que->me, buf); - if (error) { - device_printf(iflib_get_dev(ctx), "Failed to allocate que int %d err: %d", i, error); - adapter->tx_num_queues = i + 1; - goto fail; - } - tx_que->msix = vector; + tx_que->msix = (vector % adapter->tx_num_queues); /* * Set the bit to enable interrupt @@ -2060,24 +1971,23 @@ em_if_msix_intr_assign(if_ctx_t ctx, int msix) adapter->ims |= tx_que->eims; adapter->ivars |= (8 | tx_que->msix) << (8 + (i * 4)); } else if (adapter->hw.mac.type == e1000_82575) { - tx_que->eims = E1000_EICR_TX_QUEUE0 << vector; + tx_que->eims = E1000_EICR_TX_QUEUE0 << (i % adapter->tx_num_queues); } else { - tx_que->eims = 1 << vector; + tx_que->eims = 1 << (i % adapter->tx_num_queues); } } /* Link interrupt */ - rid = vector + 1; + rid = rx_vectors + 1; error = iflib_irq_alloc_generic(ctx, &adapter->irq, rid, IFLIB_INTR_ADMIN, em_msix_link, adapter, 0, "aq"); if (error) { device_printf(iflib_get_dev(ctx), "Failed to register admin handler"); goto fail; } - - adapter->linkvec = vector; + adapter->linkvec = rx_vectors; if (adapter->hw.mac.type < igb_mac_min) { - adapter->ivars |= (8 | vector) << 16; + adapter->ivars |= (8 | rx_vectors) << 16; adapter->ivars |= 0x80000000; } return (0); @@ -2234,24 +2144,15 @@ static void em_free_pci_resources(if_ctx_t ctx) { struct adapter *adapter = iflib_get_softc(ctx); - struct em_rx_queue *rxque = adapter->rx_queues; - struct em_tx_queue *txque = adapter->tx_queues; + struct em_rx_queue *que = adapter->rx_queues; device_t dev = iflib_get_dev(ctx); - int is_igb; - is_igb = (adapter->hw.mac.type >= igb_mac_min); /* Release all msix queue resources */ if (adapter->intr_type == IFLIB_INTR_MSIX) iflib_irq_free(ctx, &adapter->irq); - for (int i = 0; i < adapter->rx_num_queues; i++, rxque++) { - iflib_irq_free(ctx, &rxque->que_irq); - } - - if (!is_igb) { - for (int i = 0; i < adapter->tx_num_queues; i++, txque++) { - iflib_irq_free(ctx, &txque->que_irq); - } + for (int i = 0; i < adapter->rx_num_queues; i++, que++) { + iflib_irq_free(ctx, &que->que_irq); } /* First release all the interrupt resources */ diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 19154c5a3c8d..6e19449ac8b4 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -434,7 +434,6 @@ struct em_tx_queue { u32 eims; /* This queue's EIMS bit */ u32 me; struct tx_ring txr; - struct if_irq que_irq; }; struct em_rx_queue { @@ -444,7 +443,7 @@ struct em_rx_queue { u32 eims; struct rx_ring rxr; u64 irqs; - struct if_irq que_irq; + struct if_irq que_irq; }; /* Our adapter structure */ diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c new file mode 100644 index 000000000000..9f54494d68fa --- /dev/null +++ b/sys/dev/efidev/efirt.c @@ -0,0 +1,388 @@ +/*- + * Copyright (c) 2004 Marcel Moolenaar + * Copyright (c) 2001 Doug Rabson + * Copyright (c) 2016 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +static struct efi_systbl *efi_systbl; +static struct efi_cfgtbl *efi_cfgtbl; +static struct efi_rt *efi_runtime; + +static int efi_status2err[25] = { + 0, /* EFI_SUCCESS */ + ENOEXEC, /* EFI_LOAD_ERROR */ + EINVAL, /* EFI_INVALID_PARAMETER */ + ENOSYS, /* EFI_UNSUPPORTED */ + EMSGSIZE, /* EFI_BAD_BUFFER_SIZE */ + EOVERFLOW, /* EFI_BUFFER_TOO_SMALL */ + EBUSY, /* EFI_NOT_READY */ + EIO, /* EFI_DEVICE_ERROR */ + EROFS, /* EFI_WRITE_PROTECTED */ + EAGAIN, /* EFI_OUT_OF_RESOURCES */ + EIO, /* EFI_VOLUME_CORRUPTED */ + ENOSPC, /* EFI_VOLUME_FULL */ + ENXIO, /* EFI_NO_MEDIA */ + ESTALE, /* EFI_MEDIA_CHANGED */ + ENOENT, /* EFI_NOT_FOUND */ + EACCES, /* EFI_ACCESS_DENIED */ + ETIMEDOUT, /* EFI_NO_RESPONSE */ + EADDRNOTAVAIL, /* EFI_NO_MAPPING */ + ETIMEDOUT, /* EFI_TIMEOUT */ + EDOOFUS, /* EFI_NOT_STARTED */ + EALREADY, /* EFI_ALREADY_STARTED */ + ECANCELED, /* EFI_ABORTED */ + EPROTO, /* EFI_ICMP_ERROR */ + EPROTO, /* EFI_TFTP_ERROR */ + EPROTO /* EFI_PROTOCOL_ERROR */ +}; + +static int +efi_status_to_errno(efi_status status) +{ + u_long code; + + code = status & 0x3ffffffffffffffful; + return (code < nitems(efi_status2err) ? efi_status2err[code] : EDOOFUS); +} + +static struct mtx efi_lock; + +static int +efi_init(void) +{ + struct efi_map_header *efihdr; + struct efi_md *map; + caddr_t kmdp; + size_t efisz; + + mtx_init(&efi_lock, "efi", NULL, MTX_DEF); + + if (efi_systbl_phys == 0) { + if (bootverbose) + printf("EFI systbl not available\n"); + return (0); + } + efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys); + if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { + efi_systbl = NULL; + if (bootverbose) + printf("EFI systbl signature invalid\n"); + return (0); + } + efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL : + (struct efi_cfgtbl *)efi_systbl->st_cfgtbl; + if (efi_cfgtbl == NULL) { + if (bootverbose) + printf("EFI config table is not present\n"); + } + + kmdp = preload_search_by_type("elf kernel"); + if (kmdp == NULL) + kmdp = preload_search_by_type("elf64 kernel"); + efihdr = (struct efi_map_header *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_EFI_MAP); + if (efihdr == NULL) { + if (bootverbose) + printf("EFI map is not present\n"); + return (0); + } + efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; + map = (struct efi_md *)((uint8_t *)efihdr + efisz); + if (efihdr->descriptor_size == 0) + return (ENOMEM); + + if (!efi_create_1t1_map(map, efihdr->memory_size / + efihdr->descriptor_size, efihdr->descriptor_size)) { + if (bootverbose) + printf("EFI cannot create runtime map\n"); + return (ENOMEM); + } + + efi_runtime = (efi_systbl->st_rt == 0) ? NULL : + (struct efi_rt *)efi_systbl->st_rt; + if (efi_runtime == NULL) { + if (bootverbose) + printf("EFI runtime services table is not present\n"); + efi_destroy_1t1_map(); + return (ENXIO); + } + + return (0); +} + +static void +efi_uninit(void) +{ + + efi_destroy_1t1_map(); + + efi_systbl = NULL; + efi_cfgtbl = NULL; + efi_runtime = NULL; + + mtx_destroy(&efi_lock); +} + +int +efi_rt_ok(void) +{ + + if (efi_runtime == NULL) + return (ENXIO); + return (0); +} + +static int +efi_enter(void) +{ + struct thread *td; + pmap_t curpmap; + int error; + + if (efi_runtime == NULL) + return (ENXIO); + td = curthread; + curpmap = &td->td_proc->p_vmspace->vm_pmap; + PMAP_LOCK(curpmap); + mtx_lock(&efi_lock); + error = fpu_kern_enter(td, NULL, FPU_KERN_NOCTX); + if (error != 0) { + PMAP_UNLOCK(curpmap); + return (error); + } + + return (efi_arch_enter()); +} + +static void +efi_leave(void) +{ + struct thread *td; + pmap_t curpmap; + + efi_arch_leave(); + + curpmap = &curproc->p_vmspace->vm_pmap; + td = curthread; + fpu_kern_leave(td, NULL); + mtx_unlock(&efi_lock); + PMAP_UNLOCK(curpmap); +} + +int +efi_get_table(struct uuid *uuid, void **ptr) +{ + struct efi_cfgtbl *ct; + u_long count; + + if (efi_cfgtbl == NULL || efi_systbl == NULL) + return (ENXIO); + count = efi_systbl->st_entries; + ct = efi_cfgtbl; + while (count--) { + if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { + *ptr = (void *)PHYS_TO_DMAP(ct->ct_data); + return (0); + } + ct++; + } + return (ENOENT); +} + +static int +efi_get_time_locked(struct efi_tm *tm) +{ + efi_status status; + int error; + + EFI_TIME_OWNED() + error = efi_enter(); + if (error != 0) + return (error); + status = efi_runtime->rt_gettime(tm, NULL); + efi_leave(); + error = efi_status_to_errno(status); + return (error); +} + +int +efi_get_time(struct efi_tm *tm) +{ + int error; + + if (efi_runtime == NULL) + return (ENXIO); + EFI_TIME_LOCK() + error = efi_get_time_locked(tm); + EFI_TIME_UNLOCK() + return (error); +} + +int +efi_reset_system(void) +{ + int error; + + error = efi_enter(); + if (error != 0) + return (error); + efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL); + efi_leave(); + return (EIO); +} + +static int +efi_set_time_locked(struct efi_tm *tm) +{ + efi_status status; + int error; + + EFI_TIME_OWNED(); + error = efi_enter(); + if (error != 0) + return (error); + status = efi_runtime->rt_settime(tm); + efi_leave(); + error = efi_status_to_errno(status); + return (error); +} + +int +efi_set_time(struct efi_tm *tm) +{ + int error; + + if (efi_runtime == NULL) + return (ENXIO); + EFI_TIME_LOCK() + error = efi_set_time_locked(tm); + EFI_TIME_UNLOCK() + return (error); +} + +int +efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, + size_t *datasize, void *data) +{ + efi_status status; + int error; + + error = efi_enter(); + if (error != 0) + return (error); + status = efi_runtime->rt_getvar(name, vendor, attrib, datasize, data); + efi_leave(); + error = efi_status_to_errno(status); + return (error); +} + +int +efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) +{ + efi_status status; + int error; + + error = efi_enter(); + if (error != 0) + return (error); + status = efi_runtime->rt_scanvar(namesize, name, vendor); + efi_leave(); + error = efi_status_to_errno(status); + return (error); +} + +int +efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, + size_t datasize, void *data) +{ + efi_status status; + int error; + + error = efi_enter(); + if (error != 0) + return (error); + status = efi_runtime->rt_setvar(name, vendor, attrib, datasize, data); + efi_leave(); + error = efi_status_to_errno(status); + return (error); +} + +static int +efirt_modevents(module_t m, int event, void *arg __unused) +{ + + switch (event) { + case MOD_LOAD: + return (efi_init()); + + case MOD_UNLOAD: + efi_uninit(); + return (0); + + case MOD_SHUTDOWN: + return (0); + + default: + return (EOPNOTSUPP); + } +} + +static moduledata_t efirt_moddata = { + .name = "efirt", + .evhand = efirt_modevents, + .priv = NULL, +}; +DECLARE_MODULE(efirt, efirt_moddata, SI_SUB_VM_CONF, SI_ORDER_ANY); +MODULE_VERSION(efirt, 1); diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index d2046963df41..51fbdaa2f0ec 100644 --- a/sys/dev/ena/ena.c +++ b/sys/dev/ena/ena.c @@ -141,7 +141,6 @@ static void ena_free_irqs(struct ena_adapter*); static void ena_disable_msix(struct ena_adapter *); static void ena_unmask_all_io_irqs(struct ena_adapter *); static int ena_rss_configure(struct ena_adapter *); -static void ena_update_hw_stats(void *, int); static int ena_up_complete(struct ena_adapter *); static int ena_up(struct ena_adapter *); static void ena_down(struct ena_adapter *); @@ -1582,7 +1581,12 @@ ena_rx_cleanup(struct ena_ring *rx_ring) ena_rx_checksum(rx_ring, &ena_rx_ctx, mbuf); } - counter_u64_add(rx_ring->rx_stats.bytes, mbuf->m_pkthdr.len); + counter_enter(); + counter_u64_add_protected(rx_ring->rx_stats.bytes, + mbuf->m_pkthdr.len); + counter_u64_add_protected(adapter->hw_stats.rx_bytes, + mbuf->m_pkthdr.len); + counter_exit(); /* * LRO is only for IP/TCP packets and TCP checksum of the packet * should be computed by hardware. @@ -1607,12 +1611,15 @@ ena_rx_cleanup(struct ena_ring *rx_ring) (*ifp->if_input)(ifp, mbuf); } - counter_u64_add(rx_ring->rx_stats.cnt, 1); + counter_enter(); + counter_u64_add_protected(rx_ring->rx_stats.cnt, 1); + counter_u64_add_protected(adapter->hw_stats.rx_packets, 1); + counter_exit(); } while (--budget); rx_ring->next_to_clean = next_to_clean; - refill_required = ena_com_sq_empty_space(io_sq); + refill_required = ena_com_free_desc(io_sq); refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DEVIDER; if (refill_required > refill_threshold) { @@ -2047,41 +2054,22 @@ static int ena_rss_configure(struct ena_adapter *adapter) /* Set indirect table */ rc = ena_com_indirect_table_set(ena_dev); - if (unlikely(rc && rc != EPERM)) + if (unlikely(rc && rc != EOPNOTSUPP)) return rc; /* Configure hash function (if supported) */ rc = ena_com_set_hash_function(ena_dev); - if (unlikely(rc && (rc != EPERM))) + if (unlikely(rc && (rc != EOPNOTSUPP))) return rc; /* Configure hash inputs (if supported) */ rc = ena_com_set_hash_ctrl(ena_dev); - if (unlikely(rc && (rc != EPERM))) + if (unlikely(rc && (rc != EOPNOTSUPP))) return rc; return 0; } -static void -ena_update_hw_stats(void *arg, int pending) -{ - struct ena_adapter *adapter = arg; - int rc; - - for (;;) { - if (!adapter->up) - return; - - rc = ena_update_stats_counters(adapter); - if (rc) - ena_trace(ENA_WARNING, - "Error updating stats counters, rc = %d", rc); - - pause("ena update hw stats", hz); - } -} - static int ena_up_complete(struct ena_adapter *adapter) { @@ -2095,6 +2083,8 @@ ena_up_complete(struct ena_adapter *adapter) ena_change_mtu(adapter->ifp, adapter->ifp->if_mtu); ena_refill_all_rx_bufs(adapter); + ena_reset_counters((counter_u64_t *)&adapter->hw_stats, + sizeof(adapter->hw_stats)); return (0); } @@ -2164,8 +2154,6 @@ ena_up(struct ena_adapter *adapter) callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S, ena_timer_service, (void *)adapter, 0); - taskqueue_enqueue(adapter->stats_tq, &adapter->stats_task); - adapter->up = true; ena_unmask_all_io_irqs(adapter); @@ -2185,36 +2173,6 @@ ena_up(struct ena_adapter *adapter) return (rc); } -int -ena_update_stats_counters(struct ena_adapter *adapter) -{ - struct ena_admin_basic_stats ena_stats; - struct ena_hw_stats *stats = &adapter->hw_stats; - int rc = 0; - - if (!adapter->up) - return (rc); - - rc = ena_com_get_dev_basic_stats(adapter->ena_dev, &ena_stats); - if (rc) - return (rc); - - stats->tx_bytes = ((uint64_t)ena_stats.tx_bytes_high << 32) | - ena_stats.tx_bytes_low; - stats->rx_bytes = ((uint64_t)ena_stats.rx_bytes_high << 32) | - ena_stats.rx_bytes_low; - - stats->rx_packets = ((uint64_t)ena_stats.rx_pkts_high << 32) | - ena_stats.rx_pkts_low; - stats->tx_packets = ((uint64_t)ena_stats.tx_pkts_high << 32) | - ena_stats.tx_pkts_low; - - stats->rx_drops = ((uint64_t)ena_stats.rx_drops_high << 32) | - ena_stats.rx_drops_low; - - return (0); -} - static uint64_t ena_get_counter(if_t ifp, ift_counter cnt) { @@ -2226,15 +2184,15 @@ ena_get_counter(if_t ifp, ift_counter cnt) switch (cnt) { case IFCOUNTER_IPACKETS: - return (stats->rx_packets); + return (counter_u64_fetch(stats->rx_packets)); case IFCOUNTER_OPACKETS: - return (stats->tx_packets); + return (counter_u64_fetch(stats->tx_packets)); case IFCOUNTER_IBYTES: - return (stats->rx_bytes); + return (counter_u64_fetch(stats->rx_bytes)); case IFCOUNTER_OBYTES: - return (stats->tx_bytes); + return (counter_u64_fetch(stats->tx_bytes)); case IFCOUNTER_IQDROPS: - return (stats->rx_drops); + return (counter_u64_fetch(stats->rx_drops)); default: return (if_get_counter_default(ifp, cnt)); } @@ -2506,6 +2464,7 @@ ena_setup_ifnet(device_t pdev, struct ena_adapter *adapter, static void ena_down(struct ena_adapter *adapter) { + int rc; if (adapter->up) { device_printf(adapter->pdev, "device is going DOWN\n"); @@ -2516,12 +2475,16 @@ ena_down(struct ena_adapter *adapter) if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); - /* Drain task responsible for updating hw stats */ - while (taskqueue_cancel(adapter->stats_tq, &adapter->stats_task, NULL)) - taskqueue_drain(adapter->stats_tq, &adapter->stats_task); - ena_free_io_irq(adapter); + if (adapter->trigger_reset) { + rc = ena_com_dev_reset(adapter->ena_dev, + adapter->reset_reason); + if (rc) + device_printf(adapter->pdev, + "Device reset failed\n"); + } + ena_destroy_all_io_queues(adapter); ena_free_all_tx_bufs(adapter); @@ -2745,6 +2708,10 @@ ena_xmit_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf) counter_enter(); counter_u64_add_protected(tx_ring->tx_stats.cnt, 1); counter_u64_add_protected(tx_ring->tx_stats.bytes, (*mbuf)->m_pkthdr.len); + + counter_u64_add_protected(adapter->hw_stats.tx_packets, 1); + counter_u64_add_protected(adapter->hw_stats.tx_bytes, + (*mbuf)->m_pkthdr.len); counter_exit(); tx_info->tx_descs = nb_hw_desc; @@ -2789,7 +2756,8 @@ ena_start_xmit(struct ena_ring *tx_ring) " header csum flags %#jx", mbuf, mbuf->m_flags, mbuf->m_pkthdr.csum_flags); - if (ena_com_sq_empty_space(io_sq) < ENA_TX_CLEANUP_TRESHOLD) + if (!ena_com_sq_have_enough_space(io_sq, + ENA_TX_CLEANUP_THRESHOLD)) ena_tx_cleanup(tx_ring); if ((ret = ena_xmit_mbuf(tx_ring, &mbuf)) != 0) { @@ -2831,7 +2799,8 @@ ena_start_xmit(struct ena_ring *tx_ring) counter_u64_add(tx_ring->tx_stats.doorbells, 1); } - if (ena_com_sq_empty_space(io_sq) < ENA_TX_CLEANUP_TRESHOLD) + if (!ena_com_sq_have_enough_space(io_sq, + ENA_TX_CLEANUP_THRESHOLD)) ena_tx_cleanup(tx_ring); } @@ -3000,7 +2969,7 @@ static int ena_rss_init_default(struct ena_adapter *adapter) #endif rc = ena_com_indirect_table_fill_entry(ena_dev, i, ENA_IO_RXQ_IDX(qid)); - if (unlikely(rc && (rc != EPERM))) { + if (unlikely(rc && (rc != EOPNOTSUPP))) { device_printf(dev, "Cannot fill indirect table\n"); goto err_fill_indir; } @@ -3008,13 +2977,13 @@ static int ena_rss_init_default(struct ena_adapter *adapter) rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL, ENA_HASH_KEY_SIZE, 0xFFFFFFFF); - if (unlikely(rc && (rc != EPERM))) { + if (unlikely(rc && (rc != EOPNOTSUPP))) { device_printf(dev, "Cannot fill hash function\n"); goto err_fill_indir; } rc = ena_com_set_default_hash_ctrl(ena_dev); - if (unlikely(rc && (rc != EPERM))) { + if (unlikely(rc && (rc != EOPNOTSUPP))) { device_printf(dev, "Cannot fill hash control\n"); goto err_fill_indir; } @@ -3087,7 +3056,7 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev) rc = ena_com_set_host_attributes(ena_dev); if (rc) { - if (rc == EPERM) + if (rc == EOPNOTSUPP) ena_trace(ENA_WARNING, "Cannot set host attributes\n"); else ena_trace(ENA_ALERT, "Cannot set host attributes\n"); @@ -3124,7 +3093,7 @@ ena_device_init(struct ena_adapter *adapter, device_t pdev, readless_supported = !(pci_get_revid(pdev) & ENA_MMIO_DISABLE_REG_READ); ena_com_set_mmio_read_mode(ena_dev, readless_supported); - rc = ena_com_dev_reset(ena_dev); + rc = ena_com_dev_reset(ena_dev, ENA_REGS_RESET_NORMAL); if (rc) { device_printf(pdev, "Can not reset device\n"); goto err_mmio_read_less; @@ -3232,7 +3201,15 @@ static void ena_keep_alive_wd(void *adapter_data, struct ena_admin_aenq_entry *aenq_e) { struct ena_adapter *adapter = (struct ena_adapter *)adapter_data; + struct ena_admin_aenq_keep_alive_desc *desc; sbintime_t stime; + uint64_t rx_drops; + + desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e; + + rx_drops = ((uint64_t)desc->rx_drops_high << 32) | desc->rx_drops_low; + counter_u64_zero(adapter->hw_stats.rx_drops); + counter_u64_add(adapter->hw_stats.rx_drops, rx_drops); stime = getsbinuptime(); atomic_store_rel_64(&adapter->keep_alive_timestamp, stime); @@ -3255,6 +3232,7 @@ static void check_for_missing_keep_alive(struct ena_adapter *adapter) device_printf(adapter->pdev, "Keep alive watchdog timeout.\n"); counter_u64_add(adapter->dev_stats.wd_expired, 1); + adapter->reset_reason = ENA_REGS_RESET_KEEP_ALIVE_TO; adapter->trigger_reset = true; } } @@ -3266,6 +3244,7 @@ static void check_for_admin_com_state(struct ena_adapter *adapter) device_printf(adapter->pdev, "ENA admin queue is not in running state!\n"); counter_u64_add(adapter->dev_stats.admin_q_pause, 1); + adapter->reset_reason = ENA_REGS_RESET_ADMIN_TO; adapter->trigger_reset = true; } } @@ -3331,6 +3310,8 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter) "is above the threshold (%d > %d). " "Reset the device\n", missed_tx, adapter->missing_tx_threshold); + adapter->reset_reason = + ENA_REGS_RESET_MISS_TX_CMPL; adapter->trigger_reset = true; return; } @@ -3398,15 +3379,15 @@ ena_reset_task(void *arg, int pending) dev_up = adapter->up; ena_com_set_admin_running_state(ena_dev, false); - ena_free_mgmnt_irq(adapter); ena_down(adapter); - ena_com_dev_reset(ena_dev); + ena_free_mgmnt_irq(adapter); ena_disable_msix(adapter); ena_com_abort_admin_commands(ena_dev); ena_com_wait_for_abort_completion(ena_dev); ena_com_admin_destroy(ena_dev); ena_com_mmio_reg_read_request_destroy(ena_dev); + adapter->reset_reason = ENA_REGS_RESET_NORMAL; adapter->trigger_reset = false; /* Finished destroy part. Restart the device */ @@ -3443,7 +3424,6 @@ ena_reset_task(void *arg, int pending) return; err_msix_free: - ena_com_dev_reset(ena_dev); ena_free_mgmnt_irq(adapter); ena_disable_msix(adapter); err_com_free: @@ -3588,6 +3568,8 @@ ena_attach(device_t pdev) goto err_com_free; } + adapter->reset_reason = ENA_REGS_RESET_NORMAL; + adapter->tx_ring_size = queue_size; adapter->rx_ring_size = queue_size; @@ -3637,22 +3619,11 @@ ena_attach(device_t pdev) taskqueue_start_threads(&adapter->reset_tq, 1, PI_NET, "%s rstq", device_get_nameunit(adapter->pdev)); - /* Initialize task queue responsible for updating hw stats */ - TASK_INIT(&adapter->stats_task, 0, ena_update_hw_stats, adapter); - adapter->stats_tq = taskqueue_create_fast("ena_stats_update", - M_WAITOK | M_ZERO, taskqueue_thread_enqueue, &adapter->stats_tq); - if (adapter->stats_tq == NULL) { - device_printf(adapter->pdev, - "Unable to create taskqueue for updating hw stats\n"); - goto err_stats_tq; - } - taskqueue_start_threads(&adapter->stats_tq, 1, PI_REALTIME, - "%s stats tq", device_get_nameunit(adapter->pdev)); - /* Initialize statistics */ ena_alloc_counters((counter_u64_t *)&adapter->dev_stats, sizeof(struct ena_stats_dev)); - ena_update_stats_counters(adapter); + ena_alloc_counters((counter_u64_t *)&adapter->hw_stats, + sizeof(struct ena_hw_stats)); ena_sysctl_add_nodes(adapter); /* Tell the stack that the interface is not active */ @@ -3661,9 +3632,8 @@ ena_attach(device_t pdev) adapter->running = true; return (0); -err_stats_tq: - taskqueue_free(adapter->reset_tq); err_reset_tq: + ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); ena_free_mgmnt_irq(adapter); ena_disable_msix(adapter); err_ifp_free: @@ -3718,8 +3688,6 @@ ena_detach(device_t pdev) ena_down(adapter); sx_unlock(&adapter->ioctl_sx); - taskqueue_free(adapter->stats_tq); - if (adapter->ifp != NULL) { ether_ifdetach(adapter->ifp); if_free(adapter->ifp); @@ -3727,6 +3695,8 @@ ena_detach(device_t pdev) ena_free_all_io_rings_resources(adapter); + ena_free_counters((counter_u64_t *)&adapter->hw_stats, + sizeof(struct ena_hw_stats)); ena_free_counters((counter_u64_t *)&adapter->dev_stats, sizeof(struct ena_stats_dev)); @@ -3745,7 +3715,7 @@ ena_detach(device_t pdev) /* Reset the device only if the device is running. */ if (adapter->running) - ena_com_dev_reset(ena_dev); + ena_com_dev_reset(ena_dev, adapter->reset_reason); ena_com_delete_host_info(ena_dev); diff --git a/sys/dev/ena/ena.h b/sys/dev/ena/ena.h index 22701d8e20c9..6ab468ceb9b3 100644 --- a/sys/dev/ena/ena.h +++ b/sys/dev/ena/ena.h @@ -40,7 +40,7 @@ #include "ena-com/ena_eth_com.h" #define DRV_MODULE_VER_MAJOR 0 -#define DRV_MODULE_VER_MINOR 7 +#define DRV_MODULE_VER_MINOR 8 #define DRV_MODULE_VER_SUBMINOR 0 #define DRV_MODULE_NAME "ena" @@ -76,7 +76,7 @@ #define ENA_NAME_MAX_LEN 20 #define ENA_IRQNAME_SIZE 40 -#define ENA_PKT_MAX_BUFS 19 +#define ENA_PKT_MAX_BUFS 19 #define ENA_STALL_TIMEOUT 100 #define ENA_RX_RSS_TABLE_LOG_SIZE 7 @@ -86,11 +86,11 @@ #define ENA_DMA_BITS_MASK 40 #define ENA_MAX_FRAME_LEN 10000 -#define ENA_MIN_FRAME_LEN 60 +#define ENA_MIN_FRAME_LEN 60 #define ENA_RX_HASH_KEY_NUM 10 -#define ENA_RX_THASH_TABLE_SIZE (1 << 8) +#define ENA_RX_THASH_TABLE_SIZE (1 << 8) -#define ENA_TX_CLEANUP_TRESHOLD 128 +#define ENA_TX_CLEANUP_THRESHOLD 128 #define DB_THRESHOLD 64 @@ -307,13 +307,13 @@ struct ena_stats_dev { }; struct ena_hw_stats { - uint64_t rx_packets; - uint64_t tx_packets; + counter_u64_t rx_packets; + counter_u64_t tx_packets; - uint64_t rx_bytes; - uint64_t tx_bytes; + counter_u64_t rx_bytes; + counter_u64_t tx_bytes; - uint64_t rx_drops; + counter_u64_t rx_drops; }; /* Board specific private data structure */ @@ -403,13 +403,11 @@ struct ena_adapter { uint32_t missing_tx_max_queues; uint32_t missing_tx_threshold; - /* Task updating hw stats */ - struct task stats_task; - struct taskqueue *stats_tq; - /* Statistics */ struct ena_stats_dev dev_stats; struct ena_hw_stats hw_stats; + + enum ena_regs_reset_reason_types reset_reason; }; @@ -425,8 +423,6 @@ struct ena_dev *ena_efa_enadev_get(device_t pdev); int ena_register_adapter(struct ena_adapter *adapter); void ena_unregister_adapter(struct ena_adapter *adapter); -int ena_update_stats_counters(struct ena_adapter *adapter); - static inline int ena_mbuf_count(struct mbuf *mbuf) { int count = 1; diff --git a/sys/dev/ena/ena_sysctl.c b/sys/dev/ena/ena_sysctl.c index 859ef2aed699..eb94d5a4136c 100644 --- a/sys/dev/ena/ena_sysctl.c +++ b/sys/dev/ena/ena_sysctl.c @@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include "ena_sysctl.h" -static int ena_sysctl_update_stats(SYSCTL_HANDLER_ARGS); static void ena_sysctl_add_stats(struct ena_adapter *); void @@ -205,20 +204,17 @@ ena_sysctl_add_stats(struct ena_adapter *adapter) CTLFLAG_RD, NULL, "Statistics from hardware"); hw_list = SYSCTL_CHILDREN(hw_node); - SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "rx_packets", CTLFLAG_RD, - &hw_stats->rx_packets, 0, "Packets received"); - SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "tx_packets", CTLFLAG_RD, - &hw_stats->tx_packets, 0, "Packets transmitted"); - SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "rx_bytes", CTLFLAG_RD, - &hw_stats->rx_bytes, 0, "Bytes received"); - SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "tx_bytes", CTLFLAG_RD, - &hw_stats->tx_bytes, 0, "Bytes transmitted"); - SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "rx_drops", CTLFLAG_RD, - &hw_stats->rx_drops, 0, "Receive packet drops"); + SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_packets", CTLFLAG_RD, + &hw_stats->rx_packets, "Packets received"); + SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_packets", CTLFLAG_RD, + &hw_stats->tx_packets, "Packets transmitted"); + SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_bytes", CTLFLAG_RD, + &hw_stats->rx_bytes, "Bytes received"); + SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_bytes", CTLFLAG_RD, + &hw_stats->tx_bytes, "Bytes transmitted"); + SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_drops", CTLFLAG_RD, + &hw_stats->rx_drops, "Receive packet drops"); - SYSCTL_ADD_PROC(ctx, hw_list, OID_AUTO, "update_stats", - CTLTYPE_INT|CTLFLAG_RD, adapter, 0, ena_sysctl_update_stats, - "A", "Update stats from hardware"); /* ENA Admin queue stats */ admin_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "admin_stats", CTLFLAG_RD, NULL, "ENA Admin Queue statistics"); @@ -236,16 +232,3 @@ ena_sysctl_add_stats(struct ena_adapter *adapter) &admin_stats->no_completion, 0, "Commands not completed"); } -static int -ena_sysctl_update_stats(SYSCTL_HANDLER_ARGS) -{ - struct ena_adapter *adapter = (struct ena_adapter *)arg1; - int rc; - - if (adapter->up) - ena_update_stats_counters(adapter); - - rc = sysctl_handle_string(oidp, "", 1, req); - return (rc); -} - diff --git a/sys/dev/evdev/evdev.c b/sys/dev/evdev/evdev.c index e580a08f98f6..94b3ecdc83fd 100644 --- a/sys/dev/evdev/evdev.c +++ b/sys/dev/evdev/evdev.c @@ -64,12 +64,14 @@ MALLOC_DEFINE(M_EVDEV, "evdev", "evdev memory"); int evdev_rcpt_mask = EVDEV_RCPT_SYSMOUSE | EVDEV_RCPT_KBDMUX; int evdev_sysmouse_t_axis = 0; +#ifdef EVDEV_SUPPORT SYSCTL_NODE(_kern, OID_AUTO, evdev, CTLFLAG_RW, 0, "Evdev args"); SYSCTL_INT(_kern_evdev, OID_AUTO, rcpt_mask, CTLFLAG_RW, &evdev_rcpt_mask, 0, "Who is receiving events: bit0 - sysmouse, bit1 - kbdmux, " "bit2 - mouse hardware, bit3 - keyboard hardware"); SYSCTL_INT(_kern_evdev, OID_AUTO, sysmouse_t_axis, CTLFLAG_RW, &evdev_sysmouse_t_axis, 0, "Extract T-axis from 0-none, 1-ums, 2-psm"); +#endif static void evdev_start_repeat(struct evdev_dev *, uint16_t); static void evdev_stop_repeat(struct evdev_dev *); @@ -577,7 +579,8 @@ evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, *value = KEY_EVENT_REPEAT; } else { /* Start/stop callout for evdev repeats */ - if (bit_test(evdev->ev_key_states, code) == !*value) { + if (bit_test(evdev->ev_key_states, code) == !*value && + !LIST_EMPTY(&evdev->ev_clients)) { if (*value == KEY_EVENT_DOWN) evdev_start_repeat(evdev, code); else @@ -632,8 +635,6 @@ evdev_sparse_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, break; case EV_SND: - if (bit_test(evdev->ev_snd_states, code) == value) - return (EV_SKIP_EVENT); bit_change(evdev->ev_snd_states, code, value); break; @@ -811,7 +812,11 @@ evdev_inject_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, case EV_ABS: case EV_SW: push: + if (evdev->ev_lock_type != EV_LOCK_INTERNAL) + EVDEV_LOCK(evdev); ret = evdev_push_event(evdev, type, code, value); + if (evdev->ev_lock_type != EV_LOCK_INTERNAL) + EVDEV_UNLOCK(evdev); break; default: diff --git a/sys/dev/evdev/evdev.h b/sys/dev/evdev/evdev.h index 946913c4dd8b..31f0c2c3ccf9 100644 --- a/sys/dev/evdev/evdev.h +++ b/sys/dev/evdev/evdev.h @@ -197,7 +197,7 @@ static __inline int evdev_push_snd(struct evdev_dev *evdev, uint16_t code, int32_t value) { - return (evdev_push_event(evdev, EV_SND, code, value != 0)); + return (evdev_push_event(evdev, EV_SND, code, value)); } static __inline int diff --git a/sys/dev/evdev/evdev_utils.c b/sys/dev/evdev/evdev_utils.c index e0b1104f7424..f4f028b1f87b 100644 --- a/sys/dev/evdev/evdev_utils.c +++ b/sys/dev/evdev/evdev_utils.c @@ -32,7 +32,9 @@ #include #include #include +#include #include +#include #include #include @@ -138,7 +140,7 @@ static uint16_t evdev_at_set1_scancodes[] = { KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT, - NONE, NONE, NONE, KEY_F11, + NONE, NONE, KEY_102ND, KEY_F11, KEY_F12, NONE, NONE, NONE, NONE, NONE, NONE, NONE, /* 0x60 - 0x7f */ @@ -314,19 +316,26 @@ evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type, leds |= 1 << i; else leds &= ~(1 << i); - if (leds != oleds) + if (leds != oleds) { + mtx_lock(&Giant); kbdd_ioctl(kbd, KDSETLED, (caddr_t)&leds); + mtx_unlock(&Giant); + } break; } } } else if (type == EV_REP && code == REP_DELAY) { delay[0] = value; delay[1] = kbd->kb_delay2; + mtx_lock(&Giant); kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); + mtx_unlock(&Giant); } else if (type == EV_REP && code == REP_PERIOD) { delay[0] = kbd->kb_delay1; delay[1] = value; + mtx_lock(&Giant); kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); + mtx_unlock(&Giant); } } diff --git a/sys/dev/ffec/if_ffec.c b/sys/dev/ffec/if_ffec.c index e18e3f1c2d20..d93547af9dfe 100644 --- a/sys/dev/ffec/if_ffec.c +++ b/sys/dev/ffec/if_ffec.c @@ -97,16 +97,21 @@ enum { FECTYPE_NONE, FECTYPE_GENERIC, FECTYPE_IMX53, - FECTYPE_IMX6, + FECTYPE_IMX6, /* imx6 and imx7 */ FECTYPE_MVF, }; /* * Flags that describe general differences between the FEC hardware in various - * SoCs. These are ORed into the FECTYPE enum values. + * SoCs. These are ORed into the FECTYPE enum values in the ofw_compat_data, so + * the low 8 bits are reserved for the type enum. In the softc, the type and + * flags are put into separate members, so that you don't need to mask the flags + * out of the type to compare it. */ -#define FECTYPE_MASK 0x0000ffff -#define FECFLAG_GBE (0x0001 << 16) +#define FECTYPE_MASK 0x000000ff +#define FECFLAG_GBE (1 << 8) +#define FECFLAG_AVB (1 << 9) +#define FECFLAG_RACC (1 << 10) /* * Table of supported FDT compat strings and their associated FECTYPE values. @@ -114,9 +119,11 @@ enum { static struct ofw_compat_data compat_data[] = { {"fsl,imx51-fec", FECTYPE_GENERIC}, {"fsl,imx53-fec", FECTYPE_IMX53}, - {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_GBE}, - {"fsl,imx6ul-fec", FECTYPE_IMX6}, - {"fsl,mvf600-fec", FECTYPE_MVF}, + {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_RACC | FECFLAG_GBE }, + {"fsl,imx6ul-fec", FECTYPE_IMX6 | FECFLAG_RACC }, + {"fsl,imx7d-fec", FECTYPE_IMX6 | FECFLAG_RACC | FECFLAG_GBE | + FECFLAG_AVB }, + {"fsl,mvf600-fec", FECTYPE_MVF | FECFLAG_RACC }, {"fsl,mvf-fec", FECTYPE_MVF}, {NULL, FECTYPE_NONE}, }; @@ -131,6 +138,8 @@ static struct ofw_compat_data compat_data[] = { #define WATCHDOG_TIMEOUT_SECS 5 +#define MAX_IRQ_COUNT 3 + struct ffec_bufmap { struct mbuf *mbuf; bus_dmamap_t map; @@ -143,16 +152,19 @@ struct ffec_softc { struct ifnet *ifp; int if_flags; struct mtx mtx; - struct resource *irq_res; + struct resource *irq_res[MAX_IRQ_COUNT]; struct resource *mem_res; - void * intr_cookie; + void * intr_cookie[MAX_IRQ_COUNT]; struct callout ffec_callout; mii_contype_t phy_conn_type; + uint32_t fecflags; uint8_t fectype; boolean_t link_is_up; boolean_t is_attached; boolean_t is_detaching; int tx_watchdog_count; + int rxbuf_align; + int txbuf_align; bus_dma_tag_t rxdesc_tag; bus_dmamap_t rxdesc_map; @@ -173,6 +185,13 @@ struct ffec_softc { int txcount; }; +static struct resource_spec irq_res_spec[MAX_IRQ_COUNT + 1] = { + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, + RESOURCE_SPEC_END +}; + #define FFEC_LOCK(sc) mtx_lock(&(sc)->mtx) #define FFEC_UNLOCK(sc) mtx_unlock(&(sc)->mtx) #define FFEC_LOCK_INIT(sc) mtx_init(&(sc)->mtx, \ @@ -246,7 +265,7 @@ ffec_miigasket_setup(struct ffec_softc *sc) * We only need the gasket for MII and RMII connections on certain SoCs. */ - switch (sc->fectype & FECTYPE_MASK) + switch (sc->fectype) { case FECTYPE_IMX53: break; @@ -747,14 +766,17 @@ ffec_setup_rxbuf(struct ffec_softc *sc, int idx, struct mbuf * m) int error, nsegs; struct bus_dma_segment seg; - /* - * We need to leave at least ETHER_ALIGN bytes free at the beginning of - * the buffer to allow the data to be re-aligned after receiving it (by - * copying it backwards ETHER_ALIGN bytes in the same buffer). We also - * have to ensure that the beginning of the buffer is aligned to the - * hardware's requirements. - */ - m_adj(m, roundup(ETHER_ALIGN, FEC_RXBUF_ALIGN)); + if (!(sc->fecflags & FECFLAG_RACC)) { + /* + * The RACC[SHIFT16] feature is not available. So, we need to + * leave at least ETHER_ALIGN bytes free at the beginning of the + * buffer to allow the data to be re-aligned after receiving it + * (by copying it backwards ETHER_ALIGN bytes in the same + * buffer). We also have to ensure that the beginning of the + * buffer is aligned to the hardware's requirements. + */ + m_adj(m, roundup(ETHER_ALIGN, sc->rxbuf_align)); + } error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map, m, &seg, &nsegs, 0); @@ -802,23 +824,6 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len) return; } - /* - * Unfortunately, the protocol headers need to be aligned on a 32-bit - * boundary for the upper layers. The hardware requires receive - * buffers to be 16-byte aligned. The ethernet header is 14 bytes, - * leaving the protocol header unaligned. We used m_adj() after - * allocating the buffer to leave empty space at the start of the - * buffer, now we'll use the alignment agnostic bcopy() routine to - * shuffle all the data backwards 2 bytes and adjust m_data. - * - * XXX imx6 hardware is able to do this 2-byte alignment by setting the - * SHIFT16 bit in the RACC register. Older hardware doesn't have that - * feature, but for them could we speed this up by copying just the - * protocol headers into their own small mbuf then chaining the cluster - * to it? That way we'd only need to copy like 64 bytes or whatever - * the biggest header is, instead of the whole 1530ish-byte frame. - */ - FFEC_UNLOCK(sc); bmap = &sc->rxbuf_map[sc->rx_idx]; @@ -831,10 +836,24 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len) m->m_pkthdr.len = len; m->m_pkthdr.rcvif = sc->ifp; - src = mtod(m, uint8_t*); - dst = src - ETHER_ALIGN; - bcopy(src, dst, len); - m->m_data = dst; + /* + * Align the protocol headers in the receive buffer on a 32-bit + * boundary. Newer hardware does the alignment for us. On hardware + * that doesn't support this feature, we have to copy-align the data. + * + * XXX for older hardware, could we speed this up by copying just the + * protocol headers into their own small mbuf then chaining the cluster + * to it? That way we'd only need to copy like 64 bytes or whatever the + * biggest header is, instead of the whole 1530ish-byte frame. + */ + if (sc->fecflags & FECFLAG_RACC) { + m->m_data = mtod(m, uint8_t *) + 2; + } else { + src = mtod(m, uint8_t*); + dst = src - ETHER_ALIGN; + bcopy(src, dst, len); + m->m_data = dst; + } sc->ifp->if_input(sc->ifp, m); FFEC_LOCK(sc); @@ -1098,7 +1117,7 @@ ffec_init_locked(struct ffec_softc *sc) * when we support jumbo frames and receiving fragments of them into * separate buffers. */ - maxbuf = MCLBYTES - roundup(ETHER_ALIGN, FEC_RXBUF_ALIGN); + maxbuf = MCLBYTES - roundup(ETHER_ALIGN, sc->rxbuf_align); maxfl = min(maxbuf, 0x7ff); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -1208,6 +1227,14 @@ ffec_init_locked(struct ffec_softc *sc) ffec_clear_stats(sc); WR4(sc, FEC_MIBC_REG, regval & ~FEC_MIBC_DIS); + if (sc->fecflags & FECFLAG_RACC) { + /* + * RACC - Receive Accelerator Function Configuration. + */ + regval = RD4(sc, FEC_RACC_REG); + WR4(sc, FEC_RACC_REG, regval | FEC_RACC_SHIFT16); + } + /* * ECR - Ethernet control register. * @@ -1360,7 +1387,7 @@ ffec_detach(device_t dev) { struct ffec_softc *sc; bus_dmamap_t map; - int idx; + int idx, irq; /* * NB: This function can be called internally to unwind a failure to @@ -1411,14 +1438,16 @@ ffec_detach(device_t dev) bus_dmamap_destroy(sc->txdesc_tag, sc->txdesc_map); } if (sc->txdesc_tag != NULL) - bus_dma_tag_destroy(sc->txdesc_tag); + bus_dma_tag_destroy(sc->txdesc_tag); /* Release bus resources. */ - if (sc->intr_cookie) - bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); - - if (sc->irq_res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); + for (irq = 0; irq < MAX_IRQ_COUNT; ++irq) { + if (sc->intr_cookie[irq] != NULL) { + bus_teardown_intr(dev, sc->irq_res[irq], + sc->intr_cookie[irq]); + } + } + bus_release_resources(dev, irq_res_spec, sc->irq_res); if (sc->mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); @@ -1434,10 +1463,11 @@ ffec_attach(device_t dev) struct ifnet *ifp = NULL; struct mbuf *m; void *dummy; + uintptr_t typeflags; phandle_t ofw_node; - int error, phynum, rid; - uint8_t eaddr[ETHER_ADDR_LEN]; uint32_t idx, mscr; + int error, phynum, rid, irq; + uint8_t eaddr[ETHER_ADDR_LEN]; sc = device_get_softc(dev); sc->dev = dev; @@ -1448,7 +1478,17 @@ ffec_attach(device_t dev) * There are differences in the implementation and features of the FEC * hardware on different SoCs, so figure out what type we are. */ - sc->fectype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + typeflags = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + sc->fectype = (uint8_t)(typeflags & FECTYPE_MASK); + sc->fecflags = (uint32_t)(typeflags & ~FECTYPE_MASK); + + if (sc->fecflags & FECFLAG_AVB) { + sc->rxbuf_align = 64; + sc->txbuf_align = 1; + } else { + sc->rxbuf_align = 16; + sc->txbuf_align = 16; + } /* * We have to be told what kind of electrical connection exists between @@ -1478,12 +1518,10 @@ ffec_attach(device_t dev) error = ENOMEM; goto out; } - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) { - device_printf(dev, "could not allocate interrupt resources.\n"); - error = ENOMEM; + + error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res); + if (error != 0) { + device_printf(dev, "could not allocate interrupt resources\n"); goto out; } @@ -1525,7 +1563,7 @@ ffec_attach(device_t dev) error = bus_dma_tag_create( bus_get_dma_tag(dev), /* Parent tag. */ - FEC_TXBUF_ALIGN, 0, /* alignment, boundary */ + sc->txbuf_align, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -1627,15 +1665,34 @@ ffec_attach(device_t dev) /* Try to get the MAC address from the hardware before resetting it. */ ffec_get_hwaddr(sc, eaddr); - /* Reset the hardware. Disables all interrupts. */ - WR4(sc, FEC_ECR_REG, FEC_ECR_RESET); + /* + * Reset the hardware. Disables all interrupts. + * + * When the FEC is connected to the AXI bus (indicated by AVB flag), a + * MAC reset while a bus transaction is pending can hang the bus. + * Instead of resetting, turn off the ENABLE bit, which allows the + * hardware to complete any in-progress transfers (appending a bad CRC + * to any partial packet) and release the AXI bus. This could probably + * be done unconditionally for all hardware variants, but that hasn't + * been tested. + */ + if (sc->fecflags & FECFLAG_AVB) + WR4(sc, FEC_ECR_REG, 0); + else + WR4(sc, FEC_ECR_REG, FEC_ECR_RESET); /* Setup interrupt handler. */ - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, ffec_intr, sc, &sc->intr_cookie); - if (error != 0) { - device_printf(dev, "could not setup interrupt handler.\n"); - goto out; + for (irq = 0; irq < MAX_IRQ_COUNT; ++irq) { + if (sc->irq_res[irq] != NULL) { + error = bus_setup_intr(dev, sc->irq_res[irq], + INTR_TYPE_NET | INTR_MPSAFE, NULL, ffec_intr, sc, + &sc->intr_cookie[irq]); + if (error != 0) { + device_printf(dev, + "could not setup interrupt handler.\n"); + goto out; + } + } } /* @@ -1701,7 +1758,7 @@ ffec_attach(device_t dev) } error = mii_attach(dev, &sc->miibus, ifp, ffec_media_change, ffec_media_status, BMSR_DEFCAPMASK, phynum, MII_OFFSET_ANY, - (sc->fectype & FECTYPE_MVF) ? MIIF_FORCEANEG : 0); + (sc->fecflags & FECTYPE_MVF) ? MIIF_FORCEANEG : 0); if (error != 0) { device_printf(dev, "PHY attach failed\n"); goto out; diff --git a/sys/dev/ffec/if_ffecreg.h b/sys/dev/ffec/if_ffecreg.h index bc44af3a5184..bb1d19790c14 100644 --- a/sys/dev/ffec/if_ffecreg.h +++ b/sys/dev/ffec/if_ffecreg.h @@ -317,8 +317,6 @@ struct ffec_hwdesc * The hardware imposes alignment restrictions on various objects involved in * DMA transfers. These values are expressed in bytes (not bits). */ -#define FEC_DESC_RING_ALIGN 16 -#define FEC_RXBUF_ALIGN 16 -#define FEC_TXBUF_ALIGN 16 +#define FEC_DESC_RING_ALIGN 64 #endif /* IF_FFECREG_H */ diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c index e7d6b229486d..6b005aede523 100644 --- a/sys/dev/flash/mx25l.c +++ b/sys/dev/flash/mx25l.c @@ -122,6 +122,7 @@ struct mx25l_flash_ident flash_devices[] = { { "s25fl064", 0x01, 0x0216, 64 * 1024, 128, FL_NONE }, { "s25fl128", 0x01, 0x2018, 64 * 1024, 256, FL_NONE }, { "s25fl256s", 0x01, 0x0219, 64 * 1024, 512, FL_NONE }, + { "SST25VF010A", 0xbf, 0x2549, 4 * 1024, 32, FL_ERASE_4K | FL_ERASE_32K }, { "SST25VF032B", 0xbf, 0x254a, 64 * 1024, 64, FL_ERASE_4K | FL_ERASE_32K }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ diff --git a/sys/dev/hpt27xx/hpt27xx_config.c b/sys/dev/hpt27xx/hpt27xx_config.c index c9687bc7afe5..09e88fc18e43 100644 --- a/sys/dev/hpt27xx/hpt27xx_config.c +++ b/sys/dev/hpt27xx/hpt27xx_config.c @@ -60,7 +60,7 @@ int init_config(void) const char driver_name[] = "hpt27xx"; const char driver_name_long[] = "RocketRAID 27xx controller driver"; -const char driver_ver[] = "v1.2.7"; +const char driver_ver[] = "v1.2.8"; int osm_max_targets = 0xff; diff --git a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c index 6df9acaacc6a..b2e9ed25ee55 100644 --- a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c +++ b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c @@ -31,7 +31,7 @@ #include #include -static HIM *hpt_match(device_t dev) +static HIM *hpt_match(device_t dev, int scan) { PCI_ID pci_id; HIM *him; @@ -39,7 +39,7 @@ static HIM *hpt_match(device_t dev) for (him = him_list; him; him = him->next) { for (i=0; him->get_supported_device_id(i, &pci_id); i++) { - if (him->get_controller_count) + if (scan && him->get_controller_count) him->get_controller_count(&pci_id,0,0); if ((pci_get_vendor(dev) == pci_id.vid) && (pci_get_device(dev) == pci_id.did)){ @@ -54,7 +54,7 @@ static int hpt_probe(device_t dev) { HIM *him; - him = hpt_match(dev); + him = hpt_match(dev, 0); if (him != NULL) { KdPrint(("hpt_probe: adapter at PCI %d:%d:%d, IRQ %d", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev), pci_get_irq(dev) @@ -77,7 +77,7 @@ static int hpt_attach(device_t dev) KdPrint(("hpt_attach(%d/%d/%d)", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev))); - him = hpt_match(dev); + him = hpt_match(dev, 1); hba->ext_type = EXT_TYPE_HBA; hba->ldm_adapter.him = him; pci_enable_busmaster(dev); diff --git a/sys/dev/hptnr/hptnr_config.c b/sys/dev/hptnr/hptnr_config.c index 10695936e9ca..2164f17efc4b 100644 --- a/sys/dev/hptnr/hptnr_config.c +++ b/sys/dev/hptnr/hptnr_config.c @@ -46,7 +46,7 @@ int init_config(void) const char driver_name[] = "hptnr"; const char driver_name_long[] = "R750/DC7280 controller driver"; -const char driver_ver[] = "v1.1.4"; +const char driver_ver[] = "v1.1.5"; int osm_max_targets = 0xff; diff --git a/sys/dev/hptnr/hptnr_osm_bsd.c b/sys/dev/hptnr/hptnr_osm_bsd.c index 338770c8e834..4d712b31c6f8 100644 --- a/sys/dev/hptnr/hptnr_osm_bsd.c +++ b/sys/dev/hptnr/hptnr_osm_bsd.c @@ -32,7 +32,7 @@ #include int msi = 0; int debug_flag = 0; -static HIM *hpt_match(device_t dev) +static HIM *hpt_match(device_t dev, int scan) { PCI_ID pci_id; HIM *him; @@ -40,7 +40,7 @@ static HIM *hpt_match(device_t dev) for (him = him_list; him; him = him->next) { for (i=0; him->get_supported_device_id(i, &pci_id); i++) { - if (him->get_controller_count) + if (scan && him->get_controller_count) him->get_controller_count(&pci_id,0,0); if ((pci_get_vendor(dev) == pci_id.vid) && (pci_get_device(dev) == pci_id.did)){ @@ -56,7 +56,7 @@ static int hpt_probe(device_t dev) { HIM *him; - him = hpt_match(dev); + him = hpt_match(dev, 0); if (him != NULL) { KdPrint(("hpt_probe: adapter at PCI %d:%d:%d, IRQ %d", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev), pci_get_irq(dev) @@ -79,7 +79,7 @@ static int hpt_attach(device_t dev) KdPrint(("hpt_attach(%d/%d/%d)", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev))); - him = hpt_match(dev); + him = hpt_match(dev, 1); hba->ext_type = EXT_TYPE_HBA; hba->ldm_adapter.him = him; diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 7221071de0f8..44a22d20dc2f 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -108,7 +108,7 @@ static struct amd_descr amd_pmcdesc[AMD_NPMCS] = struct amd_event_code_map { enum pmc_event pe_ev; /* enum value */ - uint8_t pe_code; /* encoded event mask */ + uint16_t pe_code; /* encoded event mask */ uint8_t pe_mask; /* bits allowed in unit mask */ }; diff --git a/sys/dev/hwpmc/hwpmc_amd.h b/sys/dev/hwpmc/hwpmc_amd.h index b995dbe08c95..8b0b29f0e981 100644 --- a/sys/dev/hwpmc/hwpmc_amd.h +++ b/sys/dev/hwpmc/hwpmc_amd.h @@ -64,10 +64,10 @@ #define AMD_PMC_UNITMASK_MOESI 0x1F #define AMD_PMC_UNITMASK 0xFF00 -#define AMD_PMC_EVENTMASK 0x00FF +#define AMD_PMC_EVENTMASK 0xF000000FF #define AMD_PMC_TO_UNITMASK(x) (((x) << 8) & AMD_PMC_UNITMASK) -#define AMD_PMC_TO_EVENTMASK(x) ((x) & 0xFF) +#define AMD_PMC_TO_EVENTMASK(x) (((x) & 0xFF) | (((uint64_t)(x) & 0xF00) << 24)) #define AMD_VALID_BITS (AMD_PMC_COUNTERMASK | AMD_PMC_INVERT | \ AMD_PMC_ENABLE | AMD_PMC_INT | AMD_PMC_PC | AMD_PMC_EDGE | \ AMD_PMC_OS | AMD_PMC_USR | AMD_PMC_UNITMASK | AMD_PMC_EVENTMASK) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 459f9542d41b..7f8b1adb6841 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -720,8 +720,8 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(0CH_02H, 0x0C, 0x02, IAP_F_FM | IAP_F_CC2), IAPDESCR(0CH_03H, 0x0C, 0x03, IAP_F_FM | IAP_F_CA), - IAPDESCR(0DH_01H, 0x0D, 0x80, IAP_F_FM | IAP_F_SLX), - IAPDESCR(0DH_03H, 0x0D, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | + IAPDESCR(0DH_01H, 0x0D, 0x01, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(0DH_03H, 0x0D, 0x03, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | IAP_F_IB | IAP_F_IBX | IAP_F_HWX | IAP_F_BW | IAP_F_BWX), IAPDESCR(0DH_40H, 0x0D, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(0DH_80H, 0x0D, 0x80, IAP_F_FM | IAP_F_SL | IAP_F_SLX), @@ -1142,7 +1142,7 @@ static struct iap_event_descr iap_events[] = { IAP_F_BW | IAP_F_BWX ), IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | - IAP_F_BW | IAP_F_BWX), + IAP_F_BW | IAP_F_BWX | IAP_F_SL), IAPDESCR(64H, 0x64, IAP_M_CORE, IAP_F_CA | IAP_F_CC2), IAPDESCR(64H_40H, 0x64, 0x40, IAP_F_FM | IAP_F_CC), @@ -1425,11 +1425,11 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SL | IAP_F_SLX), - IAPDESCR(A6H_02H, 0xA3, 0x02, IAP_F_FM | IAP_F_SL | IAP_F_SLX), - IAPDESCR(A6H_04H, 0xA3, 0x04, IAP_F_FM | IAP_F_SL | IAP_F_SLX), - IAPDESCR(A6H_08H, 0xA3, 0x08, IAP_F_FM | IAP_F_SL | IAP_F_SLX), - IAPDESCR(A6H_10H, 0xA3, 0x10, IAP_F_FM | IAP_F_SL | IAP_F_SLX), - IAPDESCR(A6H_40H, 0xA3, 0x40, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(A6H_02H, 0xA6, 0x02, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(A6H_04H, 0xA6, 0x04, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(A6H_08H, 0xA6, 0x08, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(A6H_10H, 0xA6, 0x10, IAP_F_FM | IAP_F_SL | IAP_F_SLX), + IAPDESCR(A6H_40H, 0xA6, 0x40, IAP_F_FM | IAP_F_SL | IAP_F_SLX), IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM ), @@ -1446,7 +1446,7 @@ static struct iap_event_descr iap_events[] = { IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(ABH_02H, 0xAB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_BW | IAP_F_BWX | - IAP_F_SLX), + IAP_F_SL | IAP_F_SLX), IAPDESCR(ACH_02H, 0xAC, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_SL), IAPDESCR(ACH_08H, 0xAC, 0x08, IAP_F_FM | IAP_F_SB | IAP_F_IB | @@ -1486,7 +1486,8 @@ static struct iap_event_descr iap_events[] = { IAP_F_BW | IAP_F_BWX | IAP_F_SL | IAP_F_SLX), IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SLX), + IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SL | + IAP_F_SLX), IAPDESCR(B1H_1FH, 0xB1, 0x1F, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B1H_20H, 0xB1, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B1H_3FH, 0xB1, 0x3F, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -1495,7 +1496,7 @@ static struct iap_event_descr iap_events[] = { IAP_F_WM), IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_SBX | IAP_F_SLX), + IAP_F_SB | IAP_F_SBX | IAP_F_SL | IAP_F_SLX), IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_WM | IAP_F_I7O), @@ -1656,7 +1657,7 @@ static struct iap_event_descr iap_events[] = { IAP_F_SL | IAP_F_SLX), IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | - IAP_F_BWX | IAP_F_SLX), + IAP_F_BWX | IAP_F_SL | IAP_F_SLX), IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_SL | IAP_F_SLX), IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB | diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c index d6fdd970d816..b7027f9113dc 100644 --- a/sys/dev/hwpmc/hwpmc_intel.c +++ b/sys/dev/hwpmc/hwpmc_intel.c @@ -179,8 +179,12 @@ pmc_intel_initialize(void) cputype = PMC_CPU_INTEL_IVYBRIDGE_XEON; nclasses = 3; break; + /* Skylake */ case 0x4e: case 0x5e: + /* Kabylake */ + case 0x8E: /* Per Intel document 325462-063US July 2017. */ + case 0x9E: /* Per Intel document 325462-063US July 2017. */ cputype = PMC_CPU_INTEL_SKYLAKE; nclasses = 3; break; diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index f7c0223a9c1f..2ed5e5ea4809 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -234,6 +235,54 @@ pmclog_get_buffer(struct pmc_owner *po) return (plb ? 0 : ENOMEM); } +struct pmclog_proc_init_args { + struct proc *kthr; + struct pmc_owner *po; + bool exit; + bool acted; +}; + +int +pmclog_proc_create(struct thread *td, void **handlep) +{ + struct pmclog_proc_init_args *ia; + int error; + + ia = malloc(sizeof(*ia), M_TEMP, M_WAITOK | M_ZERO); + error = kproc_create(pmclog_loop, ia, &ia->kthr, + RFHIGHPID, 0, "hwpmc: proc(%d)", td->td_proc->p_pid); + if (error == 0) + *handlep = ia; + return (error); +} + +void +pmclog_proc_ignite(void *handle, struct pmc_owner *po) +{ + struct pmclog_proc_init_args *ia; + + ia = handle; + mtx_lock(&pmc_kthread_mtx); + MPASS(!ia->acted); + MPASS(ia->po == NULL); + MPASS(!ia->exit); + MPASS(ia->kthr != NULL); + if (po == NULL) { + ia->exit = true; + } else { + ia->po = po; + KASSERT(po->po_kthread == NULL, + ("[pmclog,%d] po=%p kthread (%p) already present", + __LINE__, po, po->po_kthread)); + po->po_kthread = ia->kthr; + } + wakeup(ia); + while (!ia->acted) + msleep(ia, &pmc_kthread_mtx, PWAIT, "pmclogw", 0); + mtx_unlock(&pmc_kthread_mtx); + free(ia, M_TEMP); +} + /* * Log handler loop. * @@ -243,20 +292,45 @@ pmclog_get_buffer(struct pmc_owner *po) static void pmclog_loop(void *arg) { - int error; + struct pmclog_proc_init_args *ia; struct pmc_owner *po; struct pmclog_buffer *lb; struct proc *p; struct ucred *ownercred; struct ucred *mycred; struct thread *td; + sigset_t unb; struct uio auio; struct iovec aiov; size_t nbytes; + int error; - po = (struct pmc_owner *) arg; - p = po->po_owner; td = curthread; + + SIGEMPTYSET(unb); + SIGADDSET(unb, SIGHUP); + (void)kern_sigprocmask(td, SIG_UNBLOCK, &unb, NULL, 0); + + ia = arg; + MPASS(ia->kthr == curproc); + MPASS(!ia->acted); + mtx_lock(&pmc_kthread_mtx); + while (ia->po == NULL && !ia->exit) + msleep(ia, &pmc_kthread_mtx, PWAIT, "pmclogi", 0); + if (ia->exit) { + ia->acted = true; + wakeup(ia); + mtx_unlock(&pmc_kthread_mtx); + kproc_exit(0); + } + MPASS(ia->po != NULL); + po = ia->po; + ia->acted = true; + wakeup(ia); + mtx_unlock(&pmc_kthread_mtx); + ia = NULL; + + p = po->po_owner; mycred = td->td_ucred; PROC_LOCK(p); @@ -291,16 +365,8 @@ pmclog_loop(void *arg) mtx_unlock_spin(&po->po_mtx); /* No more buffers and shutdown required. */ - if (po->po_flags & PMC_PO_SHUTDOWN) { - mtx_unlock(&pmc_kthread_mtx); - /* - * Close the file to get PMCLOG_EOF - * error in pmclog(3). - */ - fo_close(po->po_file, curthread); - mtx_lock(&pmc_kthread_mtx); + if (po->po_flags & PMC_PO_SHUTDOWN) break; - } (void) msleep(po, &pmc_kthread_mtx, PWAIT, "pmcloop", 0); @@ -541,19 +607,16 @@ pmclog_schedule_io(struct pmc_owner *po) static void pmclog_stop_kthread(struct pmc_owner *po) { - /* - * Close the file to force the thread out of fo_write, - * unset flag, wakeup the helper thread, - * wait for it to exit - */ - - if (po->po_file != NULL) - fo_close(po->po_file, curthread); mtx_lock(&pmc_kthread_mtx); po->po_flags &= ~PMC_PO_OWNS_LOGFILE; + if (po->po_kthread != NULL) { + PROC_LOCK(po->po_kthread); + kern_psignal(po->po_kthread, SIGHUP); + PROC_UNLOCK(po->po_kthread); + } wakeup_one(po); - if (po->po_kthread) + while (po->po_kthread) msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0); mtx_unlock(&pmc_kthread_mtx); } @@ -572,15 +635,11 @@ pmclog_stop_kthread(struct pmc_owner *po) int pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) { - int error; struct proc *p; cap_rights_t rights; - /* - * As long as it is possible to get a LOR between pmc_sx lock and - * proctree/allproc sx locks used for adding a new process, assure - * the former is not held here. - */ - sx_assert(&pmc_sx, SA_UNLOCKED); + int error; + + sx_assert(&pmc_sx, SA_XLOCKED); PMCDBG2(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); p = po->po_owner; @@ -589,9 +648,6 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) if (po->po_flags & PMC_PO_OWNS_LOGFILE) return (EBUSY); - KASSERT(po->po_kthread == NULL, - ("[pmclog,%d] po=%p kthread (%p) already present", __LINE__, po, - po->po_kthread)); KASSERT(po->po_file == NULL, ("[pmclog,%d] po=%p file (%p) already present", __LINE__, po, po->po_file)); @@ -604,10 +660,6 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) /* mark process as owning a log file */ po->po_flags |= PMC_PO_OWNS_LOGFILE; - error = kproc_create(pmclog_loop, po, &po->po_kthread, - RFHIGHPID, 0, "hwpmc: proc(%d)", p->p_pid); - if (error) - goto error; /* mark process as using HWPMCs */ PROC_LOCK(p); @@ -624,10 +676,6 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) return (0); error: - /* shutdown the thread */ - if (po->po_kthread) - pmclog_stop_kthread(po); - KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not " "stopped", __LINE__, po)); @@ -685,8 +733,11 @@ pmclog_deconfigure_log(struct pmc_owner *po) } /* drop a reference to the fd */ - error = fdrop(po->po_file, curthread); - po->po_file = NULL; + if (po->po_file != NULL) { + error = fdrop(po->po_file, curthread); + po->po_file = NULL; + } else + error = 0; po->po_error = 0; return (error); diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 821617138ecf..7cf3e1f634b9 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -311,27 +311,23 @@ SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_syspmcs, CTLFLAG_RWTUN, /* The `sysent' for the new syscall */ static struct sysent pmc_sysent = { - 2, /* sy_narg */ - pmc_syscall_handler /* sy_call */ + .sy_narg = 2, + .sy_call = pmc_syscall_handler, }; static struct syscall_module_data pmc_syscall_mod = { - load, - NULL, - &pmc_syscall_num, - &pmc_sysent, -#if (__FreeBSD_version >= 1100000) - { 0, NULL }, - SY_THR_STATIC_KLD, -#else - { 0, NULL } -#endif + .chainevh = load, + .chainarg = NULL, + .offset = &pmc_syscall_num, + .new_sysent = &pmc_sysent, + .old_sysent = { .sy_narg = 0, .sy_call = NULL }, + .flags = SY_THR_STATIC_KLD, }; static moduledata_t pmc_mod = { - PMC_MODULE_NAME, - syscall_module_handler, - &pmc_syscall_mod + .name = PMC_MODULE_NAME, + .evhand = syscall_module_handler, + .priv = &pmc_syscall_mod, }; #ifdef EARLY_AP_STARTUP @@ -2858,21 +2854,30 @@ static const char *pmc_op_to_name[] = { static int pmc_syscall_handler(struct thread *td, void *syscall_args) { - int error, is_sx_downgraded, is_sx_locked, op; + int error, is_sx_downgraded, op; struct pmc_syscall_args *c; + void *pmclog_proc_handle; void *arg; - PMC_GET_SX_XLOCK(ENOSYS); - - DROP_GIANT(); - - is_sx_downgraded = 0; - is_sx_locked = 1; - - c = (struct pmc_syscall_args *) syscall_args; - + c = (struct pmc_syscall_args *)syscall_args; op = c->pmop_code; arg = c->pmop_data; + if (op == PMC_OP_CONFIGURELOG) { + /* + * We cannot create the logging process inside + * pmclog_configure_log() because there is a LOR + * between pmc_sx and process structure locks. + * Instead, pre-create the process and ignite the loop + * if everything is fine, otherwise direct the process + * to exit. + */ + error = pmclog_proc_create(td, &pmclog_proc_handle); + if (error != 0) + goto done_syscall; + } + + PMC_GET_SX_XLOCK(ENOSYS); + is_sx_downgraded = 0; PMCDBG3(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op, pmc_op_to_name[op], arg); @@ -2880,8 +2885,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) error = 0; atomic_add_int(&pmc_stats.pm_syscalls, 1); - switch(op) - { + switch (op) { /* @@ -2897,15 +2901,16 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) struct pmc_owner *po; struct pmc_op_configurelog cl; - sx_assert(&pmc_sx, SX_XLOCKED); - - if ((error = copyin(arg, &cl, sizeof(cl))) != 0) + if ((error = copyin(arg, &cl, sizeof(cl))) != 0) { + pmclog_proc_ignite(pmclog_proc_handle, NULL); break; + } /* mark this process as owning a log file */ p = td->td_proc; if ((po = pmc_find_owner_descriptor(p)) == NULL) if ((po = pmc_allocate_owner_descriptor(p)) == NULL) { + pmclog_proc_ignite(pmclog_proc_handle, NULL); error = ENOMEM; break; } @@ -2917,10 +2922,11 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) * de-configure it. */ if (cl.pm_logfd >= 0) { - sx_xunlock(&pmc_sx); - is_sx_locked = 0; error = pmclog_configure_log(md, po, cl.pm_logfd); + pmclog_proc_ignite(pmclog_proc_handle, error == 0 ? + po : NULL); } else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { + pmclog_proc_ignite(pmclog_proc_handle, NULL); pmclog_process_closelog(po); error = pmclog_close(po); if (error == 0) { @@ -2930,11 +2936,10 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) pmc_stop(pm); error = pmclog_deconfigure_log(po); } - } else + } else { + pmclog_proc_ignite(pmclog_proc_handle, NULL); error = EINVAL; - - if (error) - break; + } } break; @@ -4029,19 +4034,15 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) break; } - if (is_sx_locked != 0) { - if (is_sx_downgraded) - sx_sunlock(&pmc_sx); - else - sx_xunlock(&pmc_sx); - } - + if (is_sx_downgraded) + sx_sunlock(&pmc_sx); + else + sx_xunlock(&pmc_sx); +done_syscall: if (error) atomic_add_int(&pmc_stats.pm_syscall_errors, 1); - PICKUP_GIANT(); - - return error; + return (error); } /* diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index f0bc43f703ed..e8f5454c1158 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -2030,7 +2030,7 @@ __PMC_EV_ALIAS("L2_RQSTS.PF_HIT", IAP_EVENT_24H_D8H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_E1H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_RFO", IAP_EVENT_24H_E2H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_CODE_RD", IAP_EVENT_24H_E4H) \ -__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_REFERENCES", IAP_EVENT_24H_F7H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_REFERENCES", IAP_EVENT_24H_E7H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_PF", IAP_EVENT_24H_F8H) \ __PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_EFH) \ __PMC_EV_ALIAS("LONGEST_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH) \ diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h index d3536a1289d3..dcd91bd035a6 100644 --- a/sys/dev/hyperv/include/hyperv.h +++ b/sys/dev/hyperv/include/hyperv.h @@ -90,6 +90,7 @@ int hyperv_guid2str(const struct hyperv_guid *, char *, */ extern hyperv_tc64_t hyperv_tc64; extern u_int hyperv_features; /* CPUID_HV_MSR_ */ +extern u_int hyperv_ver_major; #endif /* _KERNEL */ diff --git a/sys/dev/hyperv/netvsc/hn_nvs.c b/sys/dev/hyperv/netvsc/hn_nvs.c index 5605b2dfa128..f21f989d876a 100644 --- a/sys/dev/hyperv/netvsc/hn_nvs.c +++ b/sys/dev/hyperv/netvsc/hn_nvs.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -503,7 +504,7 @@ hn_nvs_conf_ndis(struct hn_softc *sc, int mtu) memset(&conf, 0, sizeof(conf)); conf.nvs_type = HN_NVS_TYPE_NDIS_CONF; - conf.nvs_mtu = mtu; + conf.nvs_mtu = mtu + ETHER_HDR_LEN; conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; if (sc->hn_nvs_ver >= HN_NVS_VERSION_5) conf.nvs_caps |= HN_NVS_NDIS_CONF_SRIOV; @@ -600,6 +601,11 @@ hn_nvs_attach(struct hn_softc *sc, int mtu) { int error; + if (hyperv_ver_major >= 10) { + /* UDP 4-tuple hash is enforced. */ + sc->hn_caps |= HN_CAP_UDPHASH; + } + /* * Initialize NVS. */ diff --git a/sys/dev/hyperv/netvsc/hn_rndis.c b/sys/dev/hyperv/netvsc/hn_rndis.c index 39d72acf883d..b9bf683fe811 100644 --- a/sys/dev/hyperv/netvsc/hn_rndis.c +++ b/sys/dev/hyperv/netvsc/hn_rndis.c @@ -188,6 +188,24 @@ hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status) return (0); } +int +hn_rndis_get_mtu(struct hn_softc *sc, uint32_t *mtu) +{ + size_t size; + int error; + + size = sizeof(*mtu); + error = hn_rndis_query(sc, OID_GEN_MAXIMUM_FRAME_SIZE, NULL, 0, + mtu, &size); + if (error) + return (error); + if (size != sizeof(uint32_t)) { + if_printf(sc->hn_ifp, "invalid mtu len %zu\n", size); + return (EINVAL); + } + return (0); +} + static const void * hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, struct hn_nvs_sendctx *sndc, size_t *comp_len) @@ -502,7 +520,11 @@ hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt0) /* Commit! */ sc->hn_rss_ind_size = indsz; - sc->hn_rss_hash = hash_func | hash_types; + sc->hn_rss_hcap = hash_func | hash_types; + if (sc->hn_caps & HN_CAP_UDPHASH) { + /* UDP 4-tuple hash is unconditionally enabled. */ + sc->hn_rss_hcap |= NDIS_HASH_UDP_IPV4_X; + } *rxr_cnt0 = rxr_cnt; return (0); } @@ -742,8 +764,10 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) ("NDIS 6.20+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); /* XXX only one can be specified through, popcnt? */ - KASSERT((sc->hn_rss_hash & NDIS_HASH_FUNCTION_MASK), ("no hash func")); - KASSERT((sc->hn_rss_hash & NDIS_HASH_TYPE_MASK), ("no hash types")); + KASSERT((sc->hn_rss_hash & NDIS_HASH_FUNCTION_MASK), + ("no hash func %08x", sc->hn_rss_hash)); + KASSERT((sc->hn_rss_hash & NDIS_HASH_STD), + ("no standard hash types %08x", sc->hn_rss_hash)); KASSERT(sc->hn_rss_ind_size > 0, ("no indirect table size")); if (bootverbose) { @@ -762,7 +786,8 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; prm->ndis_hdr.ndis_size = rss_size; prm->ndis_flags = flags; - prm->ndis_hash = sc->hn_rss_hash; + prm->ndis_hash = sc->hn_rss_hash & + (NDIS_HASH_FUNCTION_MASK | NDIS_HASH_STD); prm->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->hn_rss_ind_size; prm->ndis_indoffset = __offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]); diff --git a/sys/dev/hyperv/netvsc/hn_rndis.h b/sys/dev/hyperv/netvsc/hn_rndis.h index c4cd952e6f39..4610d5a10526 100644 --- a/sys/dev/hyperv/netvsc/hn_rndis.h +++ b/sys/dev/hyperv/netvsc/hn_rndis.h @@ -41,6 +41,7 @@ int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); /* link_status: NDIS_MEDIA_STATE_ */ int hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status); +int hn_rndis_get_mtu(struct hn_softc *sc, uint32_t *mtu); /* filter: NDIS_PACKET_TYPE_. */ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index 2d2dadf7a04e..9700c9191086 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -61,7 +61,9 @@ __FBSDID("$FreeBSD$"); #include "opt_rss.h" #include +#include #include +#include #include #include #include @@ -76,7 +78,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -284,6 +285,8 @@ static void hn_xpnt_vf_init_taskfunc(void *, int); static void hn_xpnt_vf_init(struct hn_softc *); static void hn_xpnt_vf_setenable(struct hn_softc *); static void hn_xpnt_vf_setdisable(struct hn_softc *, bool); +static void hn_vf_rss_fixup(struct hn_softc *, bool); +static void hn_vf_rss_restore(struct hn_softc *); static int hn_rndis_rxinfo(const void *, int, struct hn_rxinfo *); @@ -327,6 +330,8 @@ static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); #endif static int hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rss_hcap_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rss_mbuf_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_size_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_pkts_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_pktmax_sysctl(SYSCTL_HANDLER_ARGS); @@ -380,19 +385,22 @@ static void hn_link_status(struct hn_softc *); static int hn_create_rx_data(struct hn_softc *, int); static void hn_destroy_rx_data(struct hn_softc *); static int hn_check_iplen(const struct mbuf *, int); +static void hn_rxpkt_proto(const struct mbuf *, int *, int *); static int hn_set_rxfilter(struct hn_softc *, uint32_t); static int hn_rxfilter_config(struct hn_softc *); -#ifndef RSS static int hn_rss_reconfig(struct hn_softc *); -#endif static void hn_rss_ind_fixup(struct hn_softc *); +static void hn_rss_mbuf_hash(struct hn_softc *, uint32_t); static int hn_rxpkt(struct hn_rx_ring *, const void *, int, const struct hn_rxinfo *); +static uint32_t hn_rss_type_fromndis(uint32_t); +static uint32_t hn_rss_type_tondis(uint32_t); static int hn_tx_ring_create(struct hn_softc *, int); static void hn_tx_ring_destroy(struct hn_tx_ring *); static int hn_create_tx_data(struct hn_softc *, int); static void hn_fixup_tx_data(struct hn_softc *); +static void hn_fixup_rx_data(struct hn_softc *); static void hn_destroy_tx_data(struct hn_softc *); static void hn_txdesc_dmamap_destroy(struct hn_txdesc *); static void hn_txdesc_gc(struct hn_tx_ring *, @@ -453,6 +461,35 @@ SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostip, CTLFLAG_RDTUN, "Trust ip packet verification on host side, " "when csum info is missing (global setting)"); +/* + * Offload UDP/IPv4 checksum. + */ +static int hn_enable_udp4cs = 1; +SYSCTL_INT(_hw_hn, OID_AUTO, enable_udp4cs, CTLFLAG_RDTUN, + &hn_enable_udp4cs, 0, "Offload UDP/IPv4 checksum"); + +/* + * Offload UDP/IPv6 checksum. + */ +static int hn_enable_udp6cs = 1; +SYSCTL_INT(_hw_hn, OID_AUTO, enable_udp6cs, CTLFLAG_RDTUN, + &hn_enable_udp6cs, 0, "Offload UDP/IPv6 checksum"); + +/* Stats. */ +static counter_u64_t hn_udpcs_fixup; +SYSCTL_COUNTER_U64(_hw_hn, OID_AUTO, udpcs_fixup, CTLFLAG_RW, + &hn_udpcs_fixup, "# of UDP checksum fixup"); + +/* + * See hn_set_hlen(). + * + * This value is for Azure. For Hyper-V, set this above + * 65536 to disable UDP datagram checksum fixup. + */ +static int hn_udpcs_fixup_mtu = 1420; +SYSCTL_INT(_hw_hn, OID_AUTO, udpcs_fixup_mtu, CTLFLAG_RWTUN, + &hn_udpcs_fixup_mtu, 0, "UDP checksum fixup MTU threshold"); + /* Limit TSO burst size */ static int hn_tso_maxlen = IP_MAXPACKET; SYSCTL_INT(_hw_hn, OID_AUTO, tso_maxlen, CTLFLAG_RDTUN, @@ -547,7 +584,7 @@ SYSCTL_PROC(_hw_hn, OID_AUTO, vfmap, CTLFLAG_RD | CTLTYPE_STRING, 0, 0, hn_vfmap_sysctl, "A", "VF mapping"); /* Transparent VF */ -static int hn_xpnt_vf = 0; +static int hn_xpnt_vf = 1; SYSCTL_INT(_hw_hn, OID_AUTO, vf_transparent, CTLFLAG_RDTUN, &hn_xpnt_vf, 0, "Transparent VF mod"); @@ -720,6 +757,7 @@ hn_tso_fixup(struct mbuf *m_head) ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; else ehlen = ETHER_HDR_LEN; + m_head->m_pkthdr.l2hlen = ehlen; #ifdef INET if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) { @@ -729,6 +767,7 @@ hn_tso_fixup(struct mbuf *m_head) PULLUP_HDR(m_head, ehlen + sizeof(*ip)); ip = mtodo(m_head, ehlen); iphlen = ip->ip_hl << 2; + m_head->m_pkthdr.l3hlen = iphlen; PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th)); th = mtodo(m_head, ehlen + iphlen); @@ -752,6 +791,7 @@ hn_tso_fixup(struct mbuf *m_head) m_freem(m_head); return (NULL); } + m_head->m_pkthdr.l3hlen = sizeof(*ip6); PULLUP_HDR(m_head, ehlen + sizeof(*ip6) + sizeof(*th)); th = mtodo(m_head, ehlen + sizeof(*ip6)); @@ -761,41 +801,55 @@ hn_tso_fixup(struct mbuf *m_head) } #endif return (m_head); - } /* * NOTE: If this function failed, the m_head would be freed. */ static __inline struct mbuf * -hn_check_tcpsyn(struct mbuf *m_head, int *tcpsyn) +hn_set_hlen(struct mbuf *m_head) { const struct ether_vlan_header *evl; - const struct tcphdr *th; int ehlen; - *tcpsyn = 0; - PULLUP_HDR(m_head, sizeof(*evl)); evl = mtod(m_head, const struct ether_vlan_header *); if (evl->evl_encap_proto == ntohs(ETHERTYPE_VLAN)) ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; else ehlen = ETHER_HDR_LEN; + m_head->m_pkthdr.l2hlen = ehlen; #ifdef INET - if (m_head->m_pkthdr.csum_flags & CSUM_IP_TCP) { + if (m_head->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP_UDP)) { const struct ip *ip; int iphlen; PULLUP_HDR(m_head, ehlen + sizeof(*ip)); ip = mtodo(m_head, ehlen); iphlen = ip->ip_hl << 2; + m_head->m_pkthdr.l3hlen = iphlen; - PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th)); - th = mtodo(m_head, ehlen + iphlen); - if (th->th_flags & TH_SYN) - *tcpsyn = 1; + /* + * UDP checksum offload does not work in Azure, if the + * following conditions meet: + * - sizeof(IP hdr + UDP hdr + payload) > 1420. + * - IP_DF is not set in the IP hdr. + * + * Fallback to software checksum for these UDP datagrams. + */ + if ((m_head->m_pkthdr.csum_flags & CSUM_IP_UDP) && + m_head->m_pkthdr.len > hn_udpcs_fixup_mtu + ehlen && + (ntohs(ip->ip_off) & IP_DF) == 0) { + uint16_t off = ehlen + iphlen; + + counter_u64_add(hn_udpcs_fixup, 1); + PULLUP_HDR(m_head, off + sizeof(struct udphdr)); + *(uint16_t *)(m_head->m_data + off + + m_head->m_pkthdr.csum_data) = in_cksum_skip( + m_head, m_head->m_pkthdr.len, off); + m_head->m_pkthdr.csum_flags &= ~CSUM_IP_UDP; + } } #endif #if defined(INET6) && defined(INET) @@ -807,18 +861,36 @@ hn_check_tcpsyn(struct mbuf *m_head, int *tcpsyn) PULLUP_HDR(m_head, ehlen + sizeof(*ip6)); ip6 = mtodo(m_head, ehlen); - if (ip6->ip6_nxt != IPPROTO_TCP) - return (m_head); - - PULLUP_HDR(m_head, ehlen + sizeof(*ip6) + sizeof(*th)); - th = mtodo(m_head, ehlen + sizeof(*ip6)); - if (th->th_flags & TH_SYN) - *tcpsyn = 1; + if (ip6->ip6_nxt != IPPROTO_TCP) { + m_freem(m_head); + return (NULL); + } + m_head->m_pkthdr.l3hlen = sizeof(*ip6); } #endif return (m_head); } +/* + * NOTE: If this function failed, the m_head would be freed. + */ +static __inline struct mbuf * +hn_check_tcpsyn(struct mbuf *m_head, int *tcpsyn) +{ + const struct tcphdr *th; + int ehlen, iphlen; + + *tcpsyn = 0; + ehlen = m_head->m_pkthdr.l2hlen; + iphlen = m_head->m_pkthdr.l3hlen; + + PULLUP_HDR(m_head, ehlen + iphlen + sizeof(*th)); + th = mtodo(m_head, ehlen + iphlen); + if (th->th_flags & TH_SYN) + *tcpsyn = 1; + return (m_head); +} + #undef PULLUP_HDR #endif /* INET6 || INET */ @@ -953,7 +1025,6 @@ hn_get_txswq_depth(const struct hn_tx_ring *txr) return hn_tx_swq_depth; } -#ifndef RSS static int hn_rss_reconfig(struct hn_softc *sc) { @@ -992,7 +1063,6 @@ hn_rss_reconfig(struct hn_softc *sc) } return (0); } -#endif /* !RSS */ static void hn_rss_ind_fixup(struct hn_softc *sc) @@ -1134,11 +1204,13 @@ hn_rxvf_change(struct hn_softc *sc, struct ifnet *ifp, bool rxvf) hn_rxvf_set(sc, rxvf ? ifp : NULL); if (rxvf) { + hn_vf_rss_fixup(sc, true); hn_suspend_mgmt(sc); sc->hn_link_flags &= ~(HN_LINK_FLAG_LINKUP | HN_LINK_FLAG_NETCHG); if_link_state_change(hn_ifp, LINK_STATE_DOWN); } else { + hn_vf_rss_restore(sc); hn_resume_mgmt(sc); } @@ -1335,6 +1407,258 @@ hn_mtu_change_fixup(struct hn_softc *sc) #endif } +static uint32_t +hn_rss_type_fromndis(uint32_t rss_hash) +{ + uint32_t types = 0; + + if (rss_hash & NDIS_HASH_IPV4) + types |= RSS_TYPE_IPV4; + if (rss_hash & NDIS_HASH_TCP_IPV4) + types |= RSS_TYPE_TCP_IPV4; + if (rss_hash & NDIS_HASH_IPV6) + types |= RSS_TYPE_IPV6; + if (rss_hash & NDIS_HASH_IPV6_EX) + types |= RSS_TYPE_IPV6_EX; + if (rss_hash & NDIS_HASH_TCP_IPV6) + types |= RSS_TYPE_TCP_IPV6; + if (rss_hash & NDIS_HASH_TCP_IPV6_EX) + types |= RSS_TYPE_TCP_IPV6_EX; + if (rss_hash & NDIS_HASH_UDP_IPV4_X) + types |= RSS_TYPE_UDP_IPV4; + return (types); +} + +static uint32_t +hn_rss_type_tondis(uint32_t types) +{ + uint32_t rss_hash = 0; + + KASSERT((types & (RSS_TYPE_UDP_IPV6 | RSS_TYPE_UDP_IPV6_EX)) == 0, + ("UDP6 and UDP6EX are not supported")); + + if (types & RSS_TYPE_IPV4) + rss_hash |= NDIS_HASH_IPV4; + if (types & RSS_TYPE_TCP_IPV4) + rss_hash |= NDIS_HASH_TCP_IPV4; + if (types & RSS_TYPE_IPV6) + rss_hash |= NDIS_HASH_IPV6; + if (types & RSS_TYPE_IPV6_EX) + rss_hash |= NDIS_HASH_IPV6_EX; + if (types & RSS_TYPE_TCP_IPV6) + rss_hash |= NDIS_HASH_TCP_IPV6; + if (types & RSS_TYPE_TCP_IPV6_EX) + rss_hash |= NDIS_HASH_TCP_IPV6_EX; + if (types & RSS_TYPE_UDP_IPV4) + rss_hash |= NDIS_HASH_UDP_IPV4_X; + return (rss_hash); +} + +static void +hn_rss_mbuf_hash(struct hn_softc *sc, uint32_t mbuf_hash) +{ + int i; + + HN_LOCK_ASSERT(sc); + + for (i = 0; i < sc->hn_rx_ring_cnt; ++i) + sc->hn_rx_ring[i].hn_mbuf_hash = mbuf_hash; +} + +static void +hn_vf_rss_fixup(struct hn_softc *sc, bool reconf) +{ + struct ifnet *ifp, *vf_ifp; + struct ifrsshash ifrh; + struct ifrsskey ifrk; + int error; + uint32_t my_types, diff_types, mbuf_types = 0; + + HN_LOCK_ASSERT(sc); + KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, + ("%s: synthetic parts are not attached", sc->hn_ifp->if_xname)); + + if (sc->hn_rx_ring_inuse == 1) { + /* No RSS on synthetic parts; done. */ + return; + } + if ((sc->hn_rss_hcap & NDIS_HASH_FUNCTION_TOEPLITZ) == 0) { + /* Synthetic parts do not support Toeplitz; done. */ + return; + } + + ifp = sc->hn_ifp; + vf_ifp = sc->hn_vf_ifp; + + /* + * Extract VF's RSS key. Only 40 bytes key for Toeplitz is + * supported. + */ + memset(&ifrk, 0, sizeof(ifrk)); + strlcpy(ifrk.ifrk_name, vf_ifp->if_xname, sizeof(ifrk.ifrk_name)); + error = vf_ifp->if_ioctl(vf_ifp, SIOCGIFRSSKEY, (caddr_t)&ifrk); + if (error) { + if_printf(ifp, "%s SIOCGRSSKEY failed: %d\n", + vf_ifp->if_xname, error); + goto done; + } + if (ifrk.ifrk_func != RSS_FUNC_TOEPLITZ) { + if_printf(ifp, "%s RSS function %u is not Toeplitz\n", + vf_ifp->if_xname, ifrk.ifrk_func); + goto done; + } + if (ifrk.ifrk_keylen != NDIS_HASH_KEYSIZE_TOEPLITZ) { + if_printf(ifp, "%s invalid RSS Toeplitz key length %d\n", + vf_ifp->if_xname, ifrk.ifrk_keylen); + goto done; + } + + /* + * Extract VF's RSS hash. Only Toeplitz is supported. + */ + memset(&ifrh, 0, sizeof(ifrh)); + strlcpy(ifrh.ifrh_name, vf_ifp->if_xname, sizeof(ifrh.ifrh_name)); + error = vf_ifp->if_ioctl(vf_ifp, SIOCGIFRSSHASH, (caddr_t)&ifrh); + if (error) { + if_printf(ifp, "%s SIOCGRSSHASH failed: %d\n", + vf_ifp->if_xname, error); + goto done; + } + if (ifrh.ifrh_func != RSS_FUNC_TOEPLITZ) { + if_printf(ifp, "%s RSS function %u is not Toeplitz\n", + vf_ifp->if_xname, ifrh.ifrh_func); + goto done; + } + + my_types = hn_rss_type_fromndis(sc->hn_rss_hcap); + if ((ifrh.ifrh_types & my_types) == 0) { + /* This disables RSS; ignore it then */ + if_printf(ifp, "%s intersection of RSS types failed. " + "VF %#x, mine %#x\n", vf_ifp->if_xname, + ifrh.ifrh_types, my_types); + goto done; + } + + diff_types = my_types ^ ifrh.ifrh_types; + my_types &= ifrh.ifrh_types; + mbuf_types = my_types; + + /* + * Detect RSS hash value/type confliction. + * + * NOTE: + * We don't disable the hash type, but stop delivery the hash + * value/type through mbufs on RX path. + * + * XXX If HN_CAP_UDPHASH is set in hn_caps, then UDP 4-tuple + * hash is delivered with type of TCP_IPV4. This means if + * UDP_IPV4 is enabled, then TCP_IPV4 should be forced, at + * least to hn_mbuf_hash. However, given that _all_ of the + * NICs implement TCP_IPV4, this will _not_ impose any issues + * here. + */ + if ((my_types & RSS_TYPE_IPV4) && + (diff_types & ifrh.ifrh_types & + (RSS_TYPE_TCP_IPV4 | RSS_TYPE_UDP_IPV4))) { + /* Conflict; disable IPV4 hash type/value delivery. */ + if_printf(ifp, "disable IPV4 mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_IPV4; + } + if ((my_types & RSS_TYPE_IPV6) && + (diff_types & ifrh.ifrh_types & + (RSS_TYPE_TCP_IPV6 | RSS_TYPE_UDP_IPV6 | + RSS_TYPE_TCP_IPV6_EX | RSS_TYPE_UDP_IPV6_EX | + RSS_TYPE_IPV6_EX))) { + /* Conflict; disable IPV6 hash type/value delivery. */ + if_printf(ifp, "disable IPV6 mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_IPV6; + } + if ((my_types & RSS_TYPE_IPV6_EX) && + (diff_types & ifrh.ifrh_types & + (RSS_TYPE_TCP_IPV6 | RSS_TYPE_UDP_IPV6 | + RSS_TYPE_TCP_IPV6_EX | RSS_TYPE_UDP_IPV6_EX | + RSS_TYPE_IPV6))) { + /* Conflict; disable IPV6_EX hash type/value delivery. */ + if_printf(ifp, "disable IPV6_EX mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_IPV6_EX; + } + if ((my_types & RSS_TYPE_TCP_IPV6) && + (diff_types & ifrh.ifrh_types & RSS_TYPE_TCP_IPV6_EX)) { + /* Conflict; disable TCP_IPV6 hash type/value delivery. */ + if_printf(ifp, "disable TCP_IPV6 mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_TCP_IPV6; + } + if ((my_types & RSS_TYPE_TCP_IPV6_EX) && + (diff_types & ifrh.ifrh_types & RSS_TYPE_TCP_IPV6)) { + /* Conflict; disable TCP_IPV6_EX hash type/value delivery. */ + if_printf(ifp, "disable TCP_IPV6_EX mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_TCP_IPV6_EX; + } + if ((my_types & RSS_TYPE_UDP_IPV6) && + (diff_types & ifrh.ifrh_types & RSS_TYPE_UDP_IPV6_EX)) { + /* Conflict; disable UDP_IPV6 hash type/value delivery. */ + if_printf(ifp, "disable UDP_IPV6 mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_UDP_IPV6; + } + if ((my_types & RSS_TYPE_UDP_IPV6_EX) && + (diff_types & ifrh.ifrh_types & RSS_TYPE_UDP_IPV6)) { + /* Conflict; disable UDP_IPV6_EX hash type/value delivery. */ + if_printf(ifp, "disable UDP_IPV6_EX mbuf hash delivery\n"); + mbuf_types &= ~RSS_TYPE_UDP_IPV6_EX; + } + + /* + * Indirect table does not matter. + */ + + sc->hn_rss_hash = (sc->hn_rss_hcap & NDIS_HASH_FUNCTION_MASK) | + hn_rss_type_tondis(my_types); + memcpy(sc->hn_rss.rss_key, ifrk.ifrk_key, sizeof(sc->hn_rss.rss_key)); + sc->hn_flags |= HN_FLAG_HAS_RSSKEY; + + if (reconf) { + error = hn_rss_reconfig(sc); + if (error) { + /* XXX roll-back? */ + if_printf(ifp, "hn_rss_reconfig failed: %d\n", error); + /* XXX keep going. */ + } + } +done: + /* Hash deliverability for mbufs. */ + hn_rss_mbuf_hash(sc, hn_rss_type_tondis(mbuf_types)); +} + +static void +hn_vf_rss_restore(struct hn_softc *sc) +{ + + HN_LOCK_ASSERT(sc); + KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, + ("%s: synthetic parts are not attached", sc->hn_ifp->if_xname)); + + if (sc->hn_rx_ring_inuse == 1) + goto done; + + /* + * Restore hash types. Key does _not_ matter. + */ + if (sc->hn_rss_hash != sc->hn_rss_hcap) { + int error; + + sc->hn_rss_hash = sc->hn_rss_hcap; + error = hn_rss_reconfig(sc); + if (error) { + if_printf(sc->hn_ifp, "hn_rss_reconfig failed: %d\n", + error); + /* XXX keep going. */ + } + } +done: + /* Hash deliverability for mbufs. */ + hn_rss_mbuf_hash(sc, NDIS_HASH_ALL); +} + static void hn_xpnt_vf_setready(struct hn_softc *sc) { @@ -1501,6 +1825,13 @@ hn_xpnt_vf_init(struct hn_softc *sc) */ hn_nvs_set_datapath(sc, HN_NVS_DATAPATH_VF); + /* + * NOTE: + * Fixup RSS related bits _after_ the VF is brought up, since + * many VFs generate RSS key during it's initialization. + */ + hn_vf_rss_fixup(sc, true); + /* Mark transparent mode VF as enabled. */ hn_xpnt_vf_setenable(sc); } @@ -1659,7 +1990,8 @@ hn_ifnet_detevent(void *xsc, struct ifnet *ifp) ifp->if_input = sc->hn_vf_input; sc->hn_vf_input = NULL; - if (sc->hn_xvf_flags & HN_XVFFLAG_ENABLED) + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) && + (sc->hn_xvf_flags & HN_XVFFLAG_ENABLED)) hn_nvs_set_datapath(sc, HN_NVS_DATAPATH_SYNTH); if (sc->hn_vf_rdytick == 0) { @@ -1681,11 +2013,18 @@ hn_ifnet_detevent(void *xsc, struct ifnet *ifp) sc->hn_ifp->if_hw_tsomaxsegsize = sc->hn_saved_tsosegsz; } - /* - * Resume link status management, which was suspended - * by hn_ifnet_attevent(). - */ - hn_resume_mgmt(sc); + if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) { + /* + * Restore RSS settings. + */ + hn_vf_rss_restore(sc); + + /* + * Resume link status management, which was suspended + * by hn_ifnet_attevent(). + */ + hn_resume_mgmt(sc); + } } /* Mark transparent mode VF as disabled. */ @@ -1737,6 +2076,7 @@ hn_attach(device_t dev) uint8_t eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp = NULL; int error, ring_cnt, tx_ring_cnt; + uint32_t mtu; sc->hn_dev = dev; sc->hn_prichan = vmbus_get_channel(dev); @@ -1893,6 +2233,12 @@ hn_attach(device_t dev) if (error) goto failed; + error = hn_rndis_get_mtu(sc, &mtu); + if (error) + mtu = ETHERMTU; + else if (bootverbose) + device_printf(dev, "RNDIS mtu %u\n", mtu); + #if __FreeBSD_version >= 1100099 if (sc->hn_rx_ring_inuse > 1) { /* @@ -1904,9 +2250,10 @@ hn_attach(device_t dev) #endif /* - * Fixup TX stuffs after synthetic parts are attached. + * Fixup TX/RX stuffs after synthetic parts are attached. */ hn_fixup_tx_data(sc); + hn_fixup_rx_data(sc); ctx = device_get_sysctl_ctx(dev); child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); @@ -1935,6 +2282,12 @@ hn_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_hash", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_rss_hash_sysctl, "A", "RSS hash"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_hashcap", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_rss_hcap_sysctl, "A", "RSS hash capabilities"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "mbuf_hash", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_rss_mbuf_sysctl, "A", "RSS hash for mbufs"); SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rss_ind_size", CTLFLAG_RD, &sc->hn_rss_ind_size, 0, "RSS indirect entry count"); #ifndef RSS @@ -2071,6 +2424,10 @@ hn_attach(device_t dev) if_printf(ifp, "TSO segcnt %u segsz %u\n", ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize); } + if (mtu < ETHERMTU) { + if_printf(ifp, "fixup mtu %u -> %u\n", ifp->if_mtu, mtu); + ifp->if_mtu = mtu; + } /* Inform the upper layer about the long frame support. */ ifp->if_hdrlen = sizeof(struct ether_vlan_header); @@ -2727,7 +3084,8 @@ hn_encap(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd, NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO); #ifdef INET if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) { - *pi_data = NDIS_LSO2_INFO_MAKEIPV4(0, + *pi_data = NDIS_LSO2_INFO_MAKEIPV4( + m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen, m_head->m_pkthdr.tso_segsz); } #endif @@ -2736,7 +3094,8 @@ hn_encap(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd, #endif #ifdef INET6 { - *pi_data = NDIS_LSO2_INFO_MAKEIPV6(0, + *pi_data = NDIS_LSO2_INFO_MAKEIPV6( + m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen, m_head->m_pkthdr.tso_segsz); } #endif @@ -2753,11 +3112,15 @@ hn_encap(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd, *pi_data |= NDIS_TXCSUM_INFO_IPCS; } - if (m_head->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP)) - *pi_data |= NDIS_TXCSUM_INFO_TCPCS; - else if (m_head->m_pkthdr.csum_flags & - (CSUM_IP_UDP | CSUM_IP6_UDP)) - *pi_data |= NDIS_TXCSUM_INFO_UDPCS; + if (m_head->m_pkthdr.csum_flags & + (CSUM_IP_TCP | CSUM_IP6_TCP)) { + *pi_data |= NDIS_TXCSUM_INFO_MKTCPCS( + m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen); + } else if (m_head->m_pkthdr.csum_flags & + (CSUM_IP_UDP | CSUM_IP6_UDP)) { + *pi_data |= NDIS_TXCSUM_INFO_MKUDPCS( + m_head->m_pkthdr.l2hlen + m_head->m_pkthdr.l3hlen); + } } pkt_hlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; @@ -3026,14 +3389,22 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, { struct ifnet *ifp, *hn_ifp = rxr->hn_ifp; struct mbuf *m_new; - int size, do_lro = 0, do_csum = 1; - int hash_type; + int size, do_lro = 0, do_csum = 1, is_vf = 0; + int hash_type = M_HASHTYPE_NONE; + int l3proto = ETHERTYPE_MAX, l4proto = IPPROTO_DONE; - /* - * If the non-transparent mode VF is active, inject this packet - * into the VF. - */ - ifp = rxr->hn_rxvf_ifp ? rxr->hn_rxvf_ifp : hn_ifp; + ifp = hn_ifp; + if (rxr->hn_rxvf_ifp != NULL) { + /* + * Non-transparent mode VF; pretend this packet is from + * the VF. + */ + ifp = rxr->hn_rxvf_ifp; + is_vf = 1; + } else if (rxr->hn_rx_flags & HN_RX_FLAG_XPNT_VF) { + /* Transparent mode VF. */ + is_vf = 1; + } if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { /* @@ -3120,31 +3491,9 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) do_lro = 1; } else { - const struct ether_header *eh; - uint16_t etype; - int hoff; - - hoff = sizeof(*eh); - /* Checked at the beginning of this function. */ - KASSERT(m_new->m_len >= hoff, ("not ethernet frame")); - - eh = mtod(m_new, struct ether_header *); - etype = ntohs(eh->ether_type); - if (etype == ETHERTYPE_VLAN) { - const struct ether_vlan_header *evl; - - hoff = sizeof(*evl); - if (m_new->m_len < hoff) - goto skip; - evl = mtod(m_new, struct ether_vlan_header *); - etype = ntohs(evl->evl_proto); - } - - if (etype == ETHERTYPE_IP) { - int pr; - - pr = hn_check_iplen(m_new, hoff); - if (pr == IPPROTO_TCP) { + hn_rxpkt_proto(m_new, &l3proto, &l4proto); + if (l3proto == ETHERTYPE_IP) { + if (l4proto == IPPROTO_TCP) { if (do_csum && (rxr->hn_trust_hcsum & HN_TRUST_HCSUM_TCP)) { @@ -3155,7 +3504,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, m_new->m_pkthdr.csum_data = 0xffff; } do_lro = 1; - } else if (pr == IPPROTO_UDP) { + } else if (l4proto == IPPROTO_UDP) { if (do_csum && (rxr->hn_trust_hcsum & HN_TRUST_HCSUM_UDP)) { @@ -3165,7 +3514,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, CSUM_DATA_VALID | CSUM_PSEUDO_HDR); m_new->m_pkthdr.csum_data = 0xffff; } - } else if (pr != IPPROTO_DONE && do_csum && + } else if (l4proto != IPPROTO_DONE && do_csum && (rxr->hn_trust_hcsum & HN_TRUST_HCSUM_IP)) { rxr->hn_csum_trusted++; m_new->m_pkthdr.csum_flags |= @@ -3173,7 +3522,7 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, } } } -skip: + if (info->vlan_info != HN_NDIS_VLAN_INFO_INVALID) { m_new->m_pkthdr.ether_vtag = EVL_MAKETAG( NDIS_VLAN_INFO_ID(info->vlan_info), @@ -3186,16 +3535,6 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, * If VF is activated (tranparent/non-transparent mode does not * matter here). * - * - Don't setup mbuf hash, if 'options RSS' is set. - * - * In Azure, when VF is activated, TCP SYN and SYN|ACK go - * through hn(4) while the rest of segments and ACKs belonging - * to the same TCP 4-tuple go through the VF. So don't setup - * mbuf hash, if a VF is activated and 'options RSS' is not - * enabled. hn(4) and the VF may use neither the same RSS - * hash key nor the same RSS hash function, so the hash value - * for packets belonging to the same flow could be different! - * * - Disable LRO * * hn(4) will only receive broadcast packets, multicast packets, @@ -3206,20 +3545,23 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, * all, since the LRO flush will use hn(4) as the receiving * interface; i.e. hn_ifp->if_input(hn_ifp, m). */ - if (hn_ifp != ifp || (rxr->hn_rx_flags & HN_RX_FLAG_XPNT_VF)) { - do_lro = 0; /* disable LRO. */ -#ifndef RSS - goto skip_hash; /* skip mbuf hash setup */ -#endif - } + if (is_vf) + do_lro = 0; + /* + * If VF is activated (tranparent/non-transparent mode does not + * matter here), do _not_ mess with unsupported hash types or + * functions. + */ if (info->hash_info != HN_NDIS_HASH_INFO_INVALID) { rxr->hn_rss_pkts++; m_new->m_pkthdr.flowid = info->hash_value; - hash_type = M_HASHTYPE_OPAQUE_HASH; + if (!is_vf) + hash_type = M_HASHTYPE_OPAQUE_HASH; if ((info->hash_info & NDIS_HASH_FUNCTION_MASK) == NDIS_HASH_FUNCTION_TOEPLITZ) { - uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK); + uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK & + rxr->hn_mbuf_hash); /* * NOTE: @@ -3235,6 +3577,37 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, case NDIS_HASH_TCP_IPV4: hash_type = M_HASHTYPE_RSS_TCP_IPV4; + if (rxr->hn_rx_flags & HN_RX_FLAG_UDP_HASH) { + int def_htype = M_HASHTYPE_OPAQUE_HASH; + + if (is_vf) + def_htype = M_HASHTYPE_NONE; + + /* + * UDP 4-tuple hash is delivered as + * TCP 4-tuple hash. + */ + if (l3proto == ETHERTYPE_MAX) { + hn_rxpkt_proto(m_new, + &l3proto, &l4proto); + } + if (l3proto == ETHERTYPE_IP) { + if (l4proto == IPPROTO_UDP && + (rxr->hn_mbuf_hash & + NDIS_HASH_UDP_IPV4_X)) { + hash_type = + M_HASHTYPE_RSS_UDP_IPV4; + do_lro = 0; + } else if (l4proto != + IPPROTO_TCP) { + hash_type = def_htype; + do_lro = 0; + } + } else { + hash_type = def_htype; + do_lro = 0; + } + } break; case NDIS_HASH_IPV6: @@ -3256,15 +3629,12 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, break; } } - } else { + } else if (!is_vf) { m_new->m_pkthdr.flowid = rxr->hn_rx_idx; hash_type = M_HASHTYPE_OPAQUE; } M_HASHTYPE_SET(m_new, hash_type); -#ifndef RSS -skip_hash: -#endif if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); if (hn_ifp != ifp) { const struct ether_header *eh; @@ -3318,6 +3688,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) int mask, error = 0; struct ifrsskey *ifrk; struct ifrsshash *ifrh; + uint32_t mtu; switch (cmd) { case SIOCSIFMTU: @@ -3381,11 +3752,23 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } + error = hn_rndis_get_mtu(sc, &mtu); + if (error) + mtu = ifr->ifr_mtu; + else if (bootverbose) + if_printf(ifp, "RNDIS mtu %u\n", mtu); + /* * Commit the requested MTU, after the synthetic parts * have been successfully attached. */ - ifp->if_mtu = ifr->ifr_mtu; + if (mtu >= ifr->ifr_mtu) { + mtu = ifr->ifr_mtu; + } else { + if_printf(ifp, "fixup mtu %d -> %u\n", + ifr->ifr_mtu, mtu); + } + ifp->if_mtu = mtu; /* * Synthetic parts' reattach may change the chimney @@ -3589,20 +3972,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifrh->ifrh_func = RSS_FUNC_TOEPLITZ; else ifrh->ifrh_func = RSS_FUNC_PRIVATE; - - ifrh->ifrh_types = 0; - if (sc->hn_rss_hash & NDIS_HASH_IPV4) - ifrh->ifrh_types |= RSS_TYPE_IPV4; - if (sc->hn_rss_hash & NDIS_HASH_TCP_IPV4) - ifrh->ifrh_types |= RSS_TYPE_TCP_IPV4; - if (sc->hn_rss_hash & NDIS_HASH_IPV6) - ifrh->ifrh_types |= RSS_TYPE_IPV6; - if (sc->hn_rss_hash & NDIS_HASH_IPV6_EX) - ifrh->ifrh_types |= RSS_TYPE_IPV6_EX; - if (sc->hn_rss_hash & NDIS_HASH_TCP_IPV6) - ifrh->ifrh_types |= RSS_TYPE_TCP_IPV6; - if (sc->hn_rss_hash & NDIS_HASH_TCP_IPV6_EX) - ifrh->ifrh_types |= RSS_TYPE_TCP_IPV6_EX; + ifrh->ifrh_types = hn_rss_type_fromndis(sc->hn_rss_hash); HN_UNLOCK(sc); break; @@ -4154,6 +4524,16 @@ hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) if (error || req->newptr == NULL) goto back; + if ((sc->hn_flags & HN_FLAG_RXVF) || + (hn_xpnt_vf && sc->hn_vf_ifp != NULL)) { + /* + * RSS key is synchronized w/ VF's, don't allow users + * to change it. + */ + error = EBUSY; + goto back; + } + error = SYSCTL_IN(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key)); if (error) goto back; @@ -4219,6 +4599,34 @@ hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS) return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req); } +static int +hn_rss_hcap_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char hash_str[128]; + uint32_t hash; + + HN_LOCK(sc); + hash = sc->hn_rss_hcap; + HN_UNLOCK(sc); + snprintf(hash_str, sizeof(hash_str), "%b", hash, NDIS_HASH_BITS); + return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req); +} + +static int +hn_rss_mbuf_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char hash_str[128]; + uint32_t hash; + + HN_LOCK(sc); + hash = sc->hn_rx_ring[0].hn_mbuf_hash; + HN_UNLOCK(sc); + snprintf(hash_str, sizeof(hash_str), "%b", hash, NDIS_HASH_BITS); + return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req); +} + static int hn_vf_sysctl(SYSCTL_HANDLER_ARGS) { @@ -4450,6 +4858,36 @@ hn_check_iplen(const struct mbuf *m, int hoff) return ip->ip_p; } +static void +hn_rxpkt_proto(const struct mbuf *m_new, int *l3proto, int *l4proto) +{ + const struct ether_header *eh; + uint16_t etype; + int hoff; + + hoff = sizeof(*eh); + /* Checked at the beginning of this function. */ + KASSERT(m_new->m_len >= hoff, ("not ethernet frame")); + + eh = mtod(m_new, const struct ether_header *); + etype = ntohs(eh->ether_type); + if (etype == ETHERTYPE_VLAN) { + const struct ether_vlan_header *evl; + + hoff = sizeof(*evl); + if (m_new->m_len < hoff) + return; + evl = mtod(m_new, const struct ether_vlan_header *); + etype = ntohs(evl->evl_proto); + } + *l3proto = etype; + + if (etype == ETHERTYPE_IP) + *l4proto = hn_check_iplen(m_new, hoff); + else + *l4proto = IPPROTO_DONE; +} + static int hn_create_rx_data(struct hn_softc *sc, int ring_cnt) { @@ -4519,6 +4957,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_UDP; if (hn_trust_hostip) rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_IP; + rxr->hn_mbuf_hash = NDIS_HASH_ALL; rxr->hn_ifp = sc->hn_ifp; if (i < sc->hn_tx_ring_cnt) rxr->hn_txr = &sc->hn_tx_ring[i]; @@ -5140,11 +5579,11 @@ hn_fixup_tx_data(struct hn_softc *sc) csum_assist |= CSUM_IP; if (sc->hn_caps & HN_CAP_TCP4CS) csum_assist |= CSUM_IP_TCP; - if (sc->hn_caps & HN_CAP_UDP4CS) + if ((sc->hn_caps & HN_CAP_UDP4CS) && hn_enable_udp4cs) csum_assist |= CSUM_IP_UDP; if (sc->hn_caps & HN_CAP_TCP6CS) csum_assist |= CSUM_IP6_TCP; - if (sc->hn_caps & HN_CAP_UDP6CS) + if ((sc->hn_caps & HN_CAP_UDP6CS) && hn_enable_udp6cs) csum_assist |= CSUM_IP6_UDP; for (i = 0; i < sc->hn_tx_ring_cnt; ++i) sc->hn_tx_ring[i].hn_csum_assist = csum_assist; @@ -5160,6 +5599,18 @@ hn_fixup_tx_data(struct hn_softc *sc) } } +static void +hn_fixup_rx_data(struct hn_softc *sc) +{ + + if (sc->hn_caps & HN_CAP_UDPHASH) { + int i; + + for (i = 0; i < sc->hn_rx_ring_cnt; ++i) + sc->hn_rx_ring[i].hn_rx_flags |= HN_RX_FLAG_UDP_HASH; + } +} + static void hn_destroy_tx_data(struct hn_softc *sc) { @@ -5247,6 +5698,13 @@ hn_start_locked(struct hn_tx_ring *txr, int len) if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); continue; } + } else if (m_head->m_pkthdr.csum_flags & + (CSUM_IP_UDP | CSUM_IP_TCP | CSUM_IP6_UDP | CSUM_IP6_TCP)) { + m_head = hn_set_hlen(m_head); + if (__predict_false(m_head == NULL)) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + continue; + } } #endif @@ -5527,8 +5985,8 @@ hn_transmit(struct ifnet *ifp, struct mbuf *m) #if defined(INET6) || defined(INET) /* - * Perform TSO packet header fixup now, since the TSO - * packet header should be cache-hot. + * Perform TSO packet header fixup or get l2/l3 header length now, + * since packet headers should be cache-hot. */ if (m->m_pkthdr.csum_flags & CSUM_TSO) { m = hn_tso_fixup(m); @@ -5536,6 +5994,13 @@ hn_transmit(struct ifnet *ifp, struct mbuf *m) if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return EIO; } + } else if (m->m_pkthdr.csum_flags & + (CSUM_IP_UDP | CSUM_IP_TCP | CSUM_IP6_UDP | CSUM_IP6_TCP)) { + m = hn_set_hlen(m); + if (__predict_false(m == NULL)) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + return EIO; + } } #endif @@ -5980,6 +6445,7 @@ hn_synth_attach(struct hn_softc *sc, int mtu) /* Clear RSS stuffs. */ sc->hn_rss_ind_size = 0; sc->hn_rss_hash = 0; + sc->hn_rss_hcap = 0; /* * Attach the primary channel _before_ attaching NVS and RNDIS. @@ -6098,6 +6564,12 @@ hn_synth_attach(struct hn_softc *sc, int mtu) hn_rss_ind_fixup(sc); } + sc->hn_rss_hash = sc->hn_rss_hcap; + if ((sc->hn_flags & HN_FLAG_RXVF) || + (sc->hn_xvf_flags & HN_XVFFLAG_ENABLED)) { + /* NOTE: Don't reconfigure RSS; will do immediately. */ + hn_vf_rss_fixup(sc, false); + } error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE); if (error) goto failed; @@ -6976,6 +7448,8 @@ hn_sysinit(void *arg __unused) { int i; + hn_udpcs_fixup = counter_u64_alloc(M_WAITOK); + #ifdef HN_IFSTART_SUPPORT /* * Don't use ifnet.if_start if transparent VF mode is requested; @@ -7055,5 +7529,7 @@ hn_sysuninit(void *arg __unused) if (hn_vfmap != NULL) free(hn_vfmap, M_DEVBUF); rm_destroy(&hn_vfmap_lock); + + counter_u64_free(hn_udpcs_fixup); } SYSUNINIT(hn_sysuninit, SI_SUB_DRIVERS, SI_ORDER_SECOND, hn_sysuninit, NULL); diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index a3efc9fa12d6..c0e17c9643e0 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -36,8 +36,7 @@ #define HN_RXBUF_SIZE (16 * 1024 * 1024) #define HN_RXBUF_SIZE_COMPAT (15 * 1024 * 1024) -/* Claimed to be 12232B */ -#define HN_MTU_MAX (9 * 1024) +#define HN_MTU_MAX (65535 - ETHER_ADDR_LEN) #define HN_TXBR_SIZE (128 * PAGE_SIZE) #define HN_RXBR_SIZE (128 * PAGE_SIZE) @@ -64,6 +63,7 @@ struct hn_rx_ring { void *hn_pktbuf; int hn_pktbuf_len; int hn_rx_flags; /* HN_RX_FLAG_ */ + uint32_t hn_mbuf_hash; /* NDIS_HASH_ */ uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ int hn_rx_idx; @@ -97,6 +97,7 @@ struct hn_rx_ring { #define HN_RX_FLAG_ATTACHED 0x0001 #define HN_RX_FLAG_BR_REF 0x0002 #define HN_RX_FLAG_XPNT_VF 0x0004 +#define HN_RX_FLAG_UDP_HASH 0x0008 struct hn_tx_ring { #ifndef HN_USE_TXDESC_BUFRING @@ -238,7 +239,8 @@ struct hn_softc { uint32_t hn_rndis_agg_align; int hn_rss_ind_size; - uint32_t hn_rss_hash; /* NDIS_HASH_ */ + uint32_t hn_rss_hash; /* setting, NDIS_HASH_ */ + uint32_t hn_rss_hcap; /* caps, NDIS_HASH_ */ struct ndis_rssprm_toeplitz hn_rss; eventhandler_tag hn_ifaddr_evthand; @@ -303,11 +305,12 @@ do { \ #define HN_CAP_TSO4 0x0080 #define HN_CAP_TSO6 0x0100 #define HN_CAP_HASHVAL 0x0200 +#define HN_CAP_UDPHASH 0x0400 /* Capability description for use with printf(9) %b identifier. */ #define HN_CAP_BITS \ "\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \ - "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL" + "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL\13UDPHASH" #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h index 9d01471553c6..4e34b51ca30f 100644 --- a/sys/dev/hyperv/netvsc/ndis.h +++ b/sys/dev/hyperv/netvsc/ndis.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2016 Microsoft Corp. + * Copyright (c) 2016-2017 Microsoft Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,10 +56,26 @@ #define NDIS_HASH_IPV6_EX 0x00000800 #define NDIS_HASH_TCP_IPV6 0x00001000 #define NDIS_HASH_TCP_IPV6_EX 0x00002000 +#define NDIS_HASH_UDP_IPV4_X 0x00004000 /* XXX non-standard */ + +#define NDIS_HASH_ALL (NDIS_HASH_IPV4 | \ + NDIS_HASH_TCP_IPV4 | \ + NDIS_HASH_IPV6 | \ + NDIS_HASH_IPV6_EX | \ + NDIS_HASH_TCP_IPV6 | \ + NDIS_HASH_TCP_IPV6_EX |\ + NDIS_HASH_UDP_IPV4_X) + +#define NDIS_HASH_STD (NDIS_HASH_IPV4 | \ + NDIS_HASH_TCP_IPV4 | \ + NDIS_HASH_IPV6 | \ + NDIS_HASH_IPV6_EX | \ + NDIS_HASH_TCP_IPV6 | \ + NDIS_HASH_TCP_IPV6_EX) /* Hash description for use with printf(9) %b identifier. */ #define NDIS_HASH_BITS \ - "\20\1TOEPLITZ\11IP4\12TCP4\13IP6\14IP6EX\15TCP6\16TCP6EX" + "\20\1TOEPLITZ\11IP4\12TCP4\13IP6\14IP6EX\15TCP6\16TCP6EX\17UDP4_X" #define NDIS_HASH_KEYSIZE_TOEPLITZ 40 #define NDIS_HASH_INDCNT 128 @@ -395,4 +411,13 @@ struct ndis_offload { #define NDIS_TXCSUM_INFO_IPCS 0x00000010 #define NDIS_TXCSUM_INFO_THOFF 0x03ff0000 +#define NDIS_TXCSUM_INFO_MKL4CS(thoff, flag) \ + ((((uint32_t)(thoff)) << 16) | (flag)) + +#define NDIS_TXCSUM_INFO_MKTCPCS(thoff) \ + NDIS_TXCSUM_INFO_MKL4CS((thoff), NDIS_TXCSUM_INFO_TCPCS) + +#define NDIS_TXCSUM_INFO_MKUDPCS(thoff) \ + NDIS_TXCSUM_INFO_MKL4CS((thoff), NDIS_TXCSUM_INFO_UDPCS) + #endif /* !_NET_NDIS_H_ */ diff --git a/sys/dev/hyperv/vmbus/hyperv.c b/sys/dev/hyperv/vmbus/hyperv.c index 2d00b45cebb4..dfc85f12f49d 100644 --- a/sys/dev/hyperv/vmbus/hyperv.c +++ b/sys/dev/hyperv/vmbus/hyperv.c @@ -77,6 +77,8 @@ static u_int hyperv_get_timecount(struct timecounter *); static bool hyperv_identify(void); static void hypercall_memfree(void); +u_int hyperv_ver_major; + u_int hyperv_features; u_int hyperv_recommends; @@ -169,8 +171,9 @@ hyperv_identify(void) hyperv_features3 = regs[3]; do_cpuid(CPUID_LEAF_HV_IDENTITY, regs); + hyperv_ver_major = regs[1] >> 16; printf("Hyper-V Version: %d.%d.%d [SP%d]\n", - regs[1] >> 16, regs[1] & 0xffff, regs[0], regs[2]); + hyperv_ver_major, regs[1] & 0xffff, regs[0], regs[2]); printf(" Features=0x%b\n", hyperv_features, "\020" diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c index dc924d0a7934..e8c683f59f4d 100644 --- a/sys/dev/hyperv/vmbus/vmbus.c +++ b/sys/dev/hyperv/vmbus/vmbus.c @@ -128,6 +128,13 @@ static void vmbus_event_proc_dummy(struct vmbus_softc *, static struct vmbus_softc *vmbus_sc; +SYSCTL_NODE(_hw, OID_AUTO, vmbus, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, + "Hyper-V vmbus"); + +static int vmbus_pin_evttask = 1; +SYSCTL_INT(_hw_vmbus, OID_AUTO, pin_evttask, CTLFLAG_RDTUN, + &vmbus_pin_evttask, 0, "Pin event tasks to their respective CPU"); + extern inthand_t IDTVEC(vmbus_isr); static const uint32_t vmbus_version[] = { @@ -905,10 +912,16 @@ vmbus_intr_setup(struct vmbus_softc *sc) VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast( "hyperv event", M_WAITOK, taskqueue_thread_enqueue, VMBUS_PCPU_PTR(sc, event_tq, cpu)); - CPU_SETOF(cpu, &cpu_mask); - taskqueue_start_threads_cpuset( - VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, &cpu_mask, - "hvevent%d", cpu); + if (vmbus_pin_evttask) { + CPU_SETOF(cpu, &cpu_mask); + taskqueue_start_threads_cpuset( + VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, + &cpu_mask, "hvevent%d", cpu); + } else { + taskqueue_start_threads( + VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, + "hvevent%d", cpu); + } /* * Setup tasks and taskqueues to handle messages. diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index e35360c676d2..6083d9778c01 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -1418,7 +1418,7 @@ ndis_rxeof(adapter, packets, pktcnt) p = packets[i]; if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) { p->np_refcnt++; - (void)ndis_return_packet(NULL ,p, block); + ndis_return_packet(p); } } return; @@ -1431,7 +1431,7 @@ ndis_rxeof(adapter, packets, pktcnt) if (ndis_ptom(&m0, p)) { device_printf(sc->ndis_dev, "ptom failed\n"); if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) - (void)ndis_return_packet(NULL, p, block); + ndis_return_packet(p); } else { #ifdef notdef if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) { diff --git a/sys/dev/iicbus/icee.c b/sys/dev/iicbus/icee.c index fffb356b1b66..d581e29b404f 100644 --- a/sys/dev/iicbus/icee.c +++ b/sys/dev/iicbus/icee.c @@ -206,9 +206,23 @@ icee_attach(device_t dev) return (0); } +static int +icee_detach(device_t dev) +{ + struct icee_softc *sc = device_get_softc(dev); + + destroy_dev(sc->cdev); + return (0); +} + static int icee_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { + struct icee_softc *sc; + + sc = CDEV2SOFTC(dev); + if (device_get_state(sc->dev) < DS_BUSY) + device_busy(sc->dev); return (0); } @@ -216,7 +230,10 @@ icee_open(struct cdev *dev, int oflags, int devtype, struct thread *td) static int icee_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { + struct icee_softc *sc; + sc = CDEV2SOFTC(dev); + device_unbusy(sc->dev); return (0); } @@ -345,6 +362,7 @@ icee_write(struct cdev *dev, struct uio *uio, int ioflag) static device_method_t icee_methods[] = { DEVMETHOD(device_probe, icee_probe), DEVMETHOD(device_attach, icee_attach), + DEVMETHOD(device_detach, icee_detach), DEVMETHOD_END }; diff --git a/sys/dev/iicbus/rtc8583.c b/sys/dev/iicbus/rtc8583.c new file mode 100644 index 000000000000..ac00df1b26e7 --- /dev/null +++ b/sys/dev/iicbus/rtc8583.c @@ -0,0 +1,295 @@ +/*- + * Copyright (c) 2017 Hiroki Mori. All rights reserved. + * Copyright (c) 2017 Ian Lepore. All rights reserved. + * + * 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 AUTHOR ``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 AUTHOR 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. + * + * This code base on isl12xx.c + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for realtime clock EPSON RTC-8583 + */ + +#include "opt_platform.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef FDT +#include +#include +#endif + +#include +#include + +#include "clock_if.h" +#include "iicbus_if.h" + +#define RTC8583_SC_REG 0x01 /* RTC Seconds */ +#define RTC8583_USERSRAM_REG 0x10 /* User SRAM register (first) */ +#define MAX_TRANSFER 16 + +/* + * A struct laid out in the same order as the time registers in the chip. + */ +struct time_regs { + uint8_t msec, sec, min, hour, day, month; +}; + +struct rtc8583_softc { + device_t dev; + device_t busdev; + struct intr_config_hook + init_hook; +}; + +#ifdef FDT +static struct ofw_compat_data compat_data[] = { + {"epson,rtc8583", 1}, + {NULL, 0}, +}; +#endif + +static void rtc8583_init(void *arg); +static int rtc8583_probe(device_t dev); +static int rtc8583_attach(device_t dev); +static int rtc8583_detach(device_t dev); + +static int rtc8583_gettime(device_t dev, struct timespec *ts); +static int rtc8583_settime(device_t dev, struct timespec *ts); + +static int rtc8583_writeto(device_t slavedev, uint8_t regaddr, + void *buffer, uint16_t buflen, int waithow); + +/* Implementation */ + +static int +rtc8583_writeto(device_t slavedev, uint8_t regaddr, void *buffer, + uint16_t buflen, int waithow) +{ + struct iic_msg msgs; + uint8_t slaveaddr; + uint8_t newbuf[MAX_TRANSFER]; + + slaveaddr = iicbus_get_addr(slavedev); + + newbuf[0] = regaddr; + memcpy(newbuf + 1, buffer, buflen); + msgs.slave = slaveaddr; + msgs.flags = IIC_M_WR; + msgs.len = 1 + buflen; + msgs.buf = newbuf; + + return (iicbus_transfer_excl(slavedev, &msgs, 1, waithow)); +} + +static inline int +rtc8583_read1(struct rtc8583_softc *sc, uint8_t reg, uint8_t *data) +{ + + return (iicdev_readfrom(sc->dev, reg, data, 1, IIC_WAIT)); +} + +static inline int +rtc8583_write1(struct rtc8583_softc *sc, uint8_t reg, uint8_t val) +{ + + return (rtc8583_writeto(sc->dev, reg, &val, 1, IIC_WAIT)); +} + +static void +rtc8583_init(void *arg) +{ + struct rtc8583_softc *sc; + + sc = (struct rtc8583_softc*)arg; + config_intrhook_disestablish(&sc->init_hook); + + /* + * Register as a system realtime clock. + */ + clock_register_flags(sc->dev, 1000000, CLOCKF_SETTIME_NO_ADJ); + clock_schedule(sc->dev, 1); + return; +} + +static int +rtc8583_probe(device_t dev) +{ + +#ifdef FDT + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + device_set_desc(dev, "EPSON RTC-8583"); + return (BUS_PROBE_DEFAULT); + } +#endif + return (ENXIO); +} + +static int +rtc8583_attach(device_t dev) +{ + struct rtc8583_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->busdev = device_get_parent(sc->dev); + + /* + * Chip init must wait until interrupts are enabled. Often i2c access + * works only when the interrupts are available. + */ + sc->init_hook.ich_func = rtc8583_init; + sc->init_hook.ich_arg = sc; + if (config_intrhook_establish(&sc->init_hook) != 0) + return (ENOMEM); + + return (0); +} + +static int +rtc8583_detach(device_t dev) +{ + + clock_unregister(dev); + return (0); +} + +static int +rtc8583_gettime(device_t dev, struct timespec *ts) +{ + struct rtc8583_softc *sc; + struct clocktime ct; + struct time_regs tregs; + uint8_t y, ytmp, sreg; + int err; + + sc = device_get_softc(dev); + + /* Read the bcd time registers. */ + if ((err = iicdev_readfrom(sc->dev, RTC8583_SC_REG, &tregs, sizeof(tregs), + IIC_WAIT)) != 0) + return (err); + + y = tregs.day >> 6; + /* Get year from user SRAM */ + rtc8583_read1(sc, RTC8583_USERSRAM_REG, &sreg); + + /* + * Check if year adjustment is required. + * RTC has only 2 bits for year value (i.e. maximum is 4 years), so + * full year value is stored in user SRAM and updated manually or + * by this code. + */ + ytmp = sreg & 0x03; + if (ytmp != y) { + /* shift according to difference */ + sreg += y - ytmp; + + /* check if overflow happened */ + if (ytmp > y) + sreg += 4; + + if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) != 0) + return (err); + rtc8583_write1(sc, RTC8583_USERSRAM_REG, sreg); + iicbus_release_bus(sc->busdev, sc->dev); + } + + ct.nsec = FROMBCD(tregs.msec) * 10 * 1000 * 1000; + ct.sec = FROMBCD(tregs.sec); + ct.min = FROMBCD(tregs.min); + ct.hour = FROMBCD(tregs.hour & 0x3f); + ct.day = FROMBCD(tregs.day & 0x3f); + ct.mon = FROMBCD(tregs.month & 0x1f); + ct.year = 2000 + sreg; + + return (clock_ct_to_ts(&ct, ts)); +} + +static int +rtc8583_settime(device_t dev, struct timespec *ts) +{ + struct rtc8583_softc *sc; + struct clocktime ct; + struct time_regs tregs; + uint8_t sreg; + int err; + + sc = device_get_softc(dev); + ts->tv_sec -= utc_offset(); + ts->tv_nsec = 0; + clock_ts_to_ct(ts, &ct); + + tregs.sec = TOBCD(ct.sec); + tregs.min = TOBCD(ct.min); + tregs.hour = TOBCD(ct.hour); + tregs.day = TOBCD(ct.day) | ((ct.year & 0x03) << 6); + tregs.month = TOBCD(ct.mon); + + if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) != 0) + return (err); + err = rtc8583_writeto(sc->dev, RTC8583_SC_REG, &tregs, + sizeof(tregs), IIC_WAIT); + sreg = ct.year - 2000; + /* save to year to sram */ + rtc8583_write1(sc, RTC8583_USERSRAM_REG, sreg); + iicbus_release_bus(sc->busdev, sc->dev); + + return (err); +} + +static device_method_t rtc8583_methods[] = { + /* device_if methods */ + DEVMETHOD(device_probe, rtc8583_probe), + DEVMETHOD(device_attach, rtc8583_attach), + DEVMETHOD(device_detach, rtc8583_detach), + + /* clock_if methods */ + DEVMETHOD(clock_gettime, rtc8583_gettime), + DEVMETHOD(clock_settime, rtc8583_settime), + + DEVMETHOD_END, +}; + +static driver_t rtc8583_driver = { + "rtc8583", + rtc8583_methods, + sizeof(struct rtc8583_softc), +}; +static devclass_t rtc8583_devclass; + +DRIVER_MODULE(rtc8583, iicbus, rtc8583_driver, rtc8583_devclass, NULL, NULL); +MODULE_VERSION(rtc8583, 1); +MODULE_DEPEND(rtc8583, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); diff --git a/sys/dev/intpm/intpm.c b/sys/dev/intpm/intpm.c index 913283a97691..a822d54e2a6a 100644 --- a/sys/dev/intpm/intpm.c +++ b/sys/dev/intpm/intpm.c @@ -88,34 +88,38 @@ static int intsmb_stop_poll(struct intsmb_softc *sc); static int intsmb_free(struct intsmb_softc *sc); static void intsmb_rawintr(void *arg); +const struct intsmb_device { + uint32_t devid; + const char *description; +} intsmb_products[] = { + { 0x71138086, "Intel PIIX4 SMBUS Interface" }, + { 0x719b8086, "Intel PIIX4 SMBUS Interface" }, +#if 0 + /* Not a good idea yet, this stops isab0 functioning */ + { 0x02001166, "ServerWorks OSB4" }, +#endif + { 0x43721002, "ATI IXP400 SMBus Controller" }, + { AMDSB_SMBUS_DEVID, "AMD SB600/7xx/8xx/9xx SMBus Controller" }, + { AMDFCH_SMBUS_DEVID, "AMD FCH SMBus Controller" }, + { AMDCZ_SMBUS_DEVID, "AMD FCH SMBus Controller" }, +}; + static int intsmb_probe(device_t dev) { + const struct intsmb_device *isd; + uint32_t devid; + size_t i; - switch (pci_get_devid(dev)) { - case 0x71138086: /* Intel 82371AB */ - case 0x719b8086: /* Intel 82443MX */ -#if 0 - /* Not a good idea yet, this stops isab0 functioning */ - case 0x02001166: /* ServerWorks OSB4 */ -#endif - device_set_desc(dev, "Intel PIIX4 SMBUS Interface"); - break; - case 0x43721002: - device_set_desc(dev, "ATI IXP400 SMBus Controller"); - break; - case AMDSB_SMBUS_DEVID: - device_set_desc(dev, "AMD SB600/7xx/8xx/9xx SMBus Controller"); - break; - case AMDFCH_SMBUS_DEVID: /* AMD FCH */ - case AMDCZ_SMBUS_DEVID: /* AMD Carizzo FCH */ - device_set_desc(dev, "AMD FCH SMBus Controller"); - break; - default: - return (ENXIO); + devid = pci_get_devid(dev); + for (i = 0; i < nitems(intsmb_products); i++) { + isd = &intsmb_products[i]; + if (isd->devid == devid) { + device_set_desc(dev, isd->description); + return (BUS_PROBE_DEFAULT); + } } - - return (BUS_PROBE_DEFAULT); + return (ENXIO); } static uint8_t @@ -891,3 +895,5 @@ DRIVER_MODULE_ORDERED(intsmb, pci, intsmb_driver, intsmb_devclass, 0, 0, DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); MODULE_VERSION(intsmb, 1); +MODULE_PNP_INFO("W32:vendor/device;D:human", pci, intpm, intsmb_products, + sizeof(intsmb_products[0]), nitems(intsmb_products)); diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 1224e207bec0..2052ff48c4b9 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -236,10 +236,11 @@ static struct _pcsid { 0x6f278086, "BDX IOAT Ch7" }, { 0x6f2e8086, "BDX IOAT Ch0 (RAID)" }, { 0x6f2f8086, "BDX IOAT Ch1 (RAID)" }, - - { 0x00000000, NULL } }; +MODULE_PNP_INFO("W32:vendor/device;D:human", pci, ioat, pci_ids, + sizeof(pci_ids[0]), nitems(pci_ids)); + /* * OS <-> Driver linkage functions */ @@ -250,7 +251,7 @@ ioat_probe(device_t device) u_int32_t type; type = pci_get_devid(device); - for (ep = pci_ids; ep->type; ep++) { + for (ep = pci_ids; ep < &pci_ids[nitems(pci_ids)]; ep++) { if (ep->type == type) { device_set_desc(device, ep->desc); return (0); diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c index 314d4d696c08..8cc8bdc4f2b3 100644 --- a/sys/dev/ipmi/ipmi.c +++ b/sys/dev/ipmi/ipmi.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -80,10 +81,32 @@ static void ipmi_dtor(void *arg); int ipmi_attached = 0; static int on = 1; +static bool wd_in_shutdown = false; +static int wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE; +static int wd_shutdown_countdown = 0; /* sec */ +static int wd_startup_countdown = 0; /* sec */ +static int wd_pretimeout_countdown = 120; /* sec */ +static int cycle_wait = 10; /* sec */ + static SYSCTL_NODE(_hw, OID_AUTO, ipmi, CTLFLAG_RD, 0, "IPMI driver parameters"); -SYSCTL_INT(_hw_ipmi, OID_AUTO, on, CTLFLAG_RW, +SYSCTL_INT(_hw_ipmi, OID_AUTO, on, CTLFLAG_RWTUN, &on, 0, ""); +SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_timer_actions, CTLFLAG_RW, + &wd_timer_actions, 0, + "IPMI watchdog timer actions (including pre-timeout interrupt)"); +SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_shutdown_countdown, CTLFLAG_RW, + &wd_shutdown_countdown, 0, + "IPMI watchdog countdown for shutdown (seconds)"); +SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_startup_countdown, CTLFLAG_RDTUN, + &wd_startup_countdown, 0, + "IPMI watchdog countdown initialized during startup (seconds)"); +SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_pretimeout_countdown, CTLFLAG_RW, + &wd_pretimeout_countdown, 0, + "IPMI watchdog pre-timeout countdown (seconds)"); +SYSCTL_INT(_hw_ipmi, OID_AUTO, cyle_wait, CTLFLAG_RWTUN, + &cycle_wait, 0, + "IPMI power cycle on reboot delay time (seconds)"); static struct cdevsw ipmi_cdevsw = { .d_version = D_VERSION, @@ -630,8 +653,8 @@ ipmi_set_watchdog(struct ipmi_softc *sc, unsigned int sec) if (sec) { req->ir_request[0] = IPMI_SET_WD_TIMER_DONT_STOP | IPMI_SET_WD_TIMER_SMS_OS; - req->ir_request[1] = IPMI_SET_WD_ACTION_RESET; - req->ir_request[2] = 0; + req->ir_request[1] = (wd_timer_actions & 0xff); + req->ir_request[2] = (wd_pretimeout_countdown & 0xff); req->ir_request[3] = 0; /* Timer use */ req->ir_request[4] = (sec * 10) & 0xff; req->ir_request[5] = (sec * 10) >> 8; @@ -656,21 +679,40 @@ ipmi_wd_event(void *arg, unsigned int cmd, int *error) unsigned int timeout; int e; - if (dumping) + /* Ignore requests while disabled. */ + if (!on) return; + /* + * To prevent infinite hangs, we don't let anyone pat or change + * the watchdog when we're shutting down. (See ipmi_shutdown_event().) + * However, we do want to keep patting the watchdog while we are doing + * a coredump. + */ + if (wd_in_shutdown) { + if (dumping && sc->ipmi_watchdog_active) + ipmi_reset_watchdog(sc); + return; + } + cmd &= WD_INTERVAL; if (cmd > 0 && cmd <= 63) { timeout = ((uint64_t)1 << cmd) / 1000000000; if (timeout == 0) timeout = 1; - if (timeout != sc->ipmi_watchdog_active) { + if (timeout != sc->ipmi_watchdog_active || + wd_timer_actions != sc->ipmi_watchdog_actions || + wd_pretimeout_countdown != sc->ipmi_watchdog_pretimeout) { e = ipmi_set_watchdog(sc, timeout); if (e == 0) { sc->ipmi_watchdog_active = timeout; + sc->ipmi_watchdog_actions = wd_timer_actions; + sc->ipmi_watchdog_pretimeout = wd_pretimeout_countdown; } else { (void)ipmi_set_watchdog(sc, 0); sc->ipmi_watchdog_active = 0; + sc->ipmi_watchdog_actions = 0; + sc->ipmi_watchdog_pretimeout = 0; } } if (sc->ipmi_watchdog_active != 0) { @@ -680,15 +722,93 @@ ipmi_wd_event(void *arg, unsigned int cmd, int *error) } else { (void)ipmi_set_watchdog(sc, 0); sc->ipmi_watchdog_active = 0; + sc->ipmi_watchdog_actions = 0; + sc->ipmi_watchdog_pretimeout = 0; } } } else if (atomic_readandclear_int(&sc->ipmi_watchdog_active) != 0) { + sc->ipmi_watchdog_actions = 0; + sc->ipmi_watchdog_pretimeout = 0; + e = ipmi_set_watchdog(sc, 0); if (e != 0 && cmd == 0) *error = EOPNOTSUPP; } } +static void +ipmi_shutdown_event(void *arg, unsigned int cmd, int *error) +{ + struct ipmi_softc *sc = arg; + + /* Ignore event if disabled. */ + if (!on) + return; + + /* + * Positive wd_shutdown_countdown value will re-arm watchdog; + * Zero value in wd_shutdown_countdown will disable watchdog; + * Negative value in wd_shutdown_countdown will keep existing state; + * + * Revert to using a power cycle to ensure that the watchdog will + * do something useful here. Having the watchdog send an NMI + * instead is useless during shutdown, and might be ignored if an + * NMI already triggered. + */ + + wd_in_shutdown = true; + if (wd_shutdown_countdown == 0) { + /* disable watchdog */ + ipmi_set_watchdog(sc, 0); + sc->ipmi_watchdog_active = 0; + } else if (wd_shutdown_countdown > 0) { + /* set desired action and time, and, reset watchdog */ + wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE; + ipmi_set_watchdog(sc, wd_shutdown_countdown); + sc->ipmi_watchdog_active = wd_shutdown_countdown; + ipmi_reset_watchdog(sc); + } +} + +static void +ipmi_power_cycle(void *arg, int howto) +{ + struct ipmi_softc *sc = arg; + struct ipmi_request *req; + + /* + * Ignore everything except power cycling requests + */ + if ((howto & RB_POWERCYCLE) == 0) + return; + + device_printf(sc->ipmi_dev, "Power cycling using IPMI\n"); + + /* + * Send a CHASSIS_CONTROL command to the CHASSIS device, subcommand 2 + * as described in IPMI v2.0 spec section 28.3. + */ + IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_CHASSIS_REQUEST, 0), + IPMI_CHASSIS_CONTROL, 1, 0); + req->ir_request[0] = IPMI_CC_POWER_CYCLE; + + ipmi_submit_driver_request(sc, req, MAX_TIMEOUT); + + if (req->ir_error != 0 || req->ir_compcode != 0) { + device_printf(sc->ipmi_dev, "Power cycling via IPMI failed code %#x %#x\n", + req->ir_error, req->ir_compcode); + return; + } + + /* + * BMCs are notoriously slow, give it cyle_wait seconds for the power + * down leg of the power cycle. If that fails, fallback to the next + * hanlder in the shutdown_final chain and/or the platform failsafe. + */ + DELAY(cycle_wait * 1000 * 1000); + device_printf(sc->ipmi_dev, "Power cycling via IPMI timed out\n"); +} + static void ipmi_startup(void *arg) { @@ -737,10 +857,12 @@ ipmi_startup(void *arg) } device_printf(dev, "IPMI device rev. %d, firmware rev. %d.%d%d, " - "version %d.%d\n", - req->ir_reply[1] & 0x0f, - req->ir_reply[2] & 0x7f, req->ir_reply[3] >> 4, req->ir_reply[3] & 0x0f, - req->ir_reply[4] & 0x0f, req->ir_reply[4] >> 4); + "version %d.%d, device support mask %#x\n", + req->ir_reply[1] & 0x0f, + req->ir_reply[2] & 0x7f, req->ir_reply[3] >> 4, req->ir_reply[3] & 0x0f, + req->ir_reply[4] & 0x0f, req->ir_reply[4] >> 4, req->ir_reply[5]); + + sc->ipmi_dev_support = req->ir_reply[5]; IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_CLEAR_FLAGS, 1, 0); @@ -781,7 +903,10 @@ ipmi_startup(void *arg) device_printf(dev, "Attached watchdog\n"); /* register the watchdog event handler */ sc->ipmi_watchdog_tag = EVENTHANDLER_REGISTER( - watchdog_list, ipmi_wd_event, sc, 0); + watchdog_list, ipmi_wd_event, sc, 0); + sc->ipmi_shutdown_tag = EVENTHANDLER_REGISTER( + shutdown_pre_sync, ipmi_shutdown_event, + sc, 0); } } @@ -792,6 +917,34 @@ ipmi_startup(void *arg) return; } sc->ipmi_cdev->si_drv1 = sc; + + /* + * Set initial watchdog state. If desired, set an initial + * watchdog on startup. Or, if the watchdog device is + * disabled, clear any existing watchdog. + */ + if (on && wd_startup_countdown > 0) { + wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE; + if (ipmi_set_watchdog(sc, wd_startup_countdown) == 0 && + ipmi_reset_watchdog(sc) == 0) { + sc->ipmi_watchdog_active = wd_startup_countdown; + sc->ipmi_watchdog_actions = wd_timer_actions; + sc->ipmi_watchdog_pretimeout = wd_pretimeout_countdown; + } else + (void)ipmi_set_watchdog(sc, 0); + ipmi_reset_watchdog(sc); + } else if (!on) + (void)ipmi_set_watchdog(sc, 0); + /* + * Power cycle the system off using IPMI. We use last - 1 since we don't + * handle all the other kinds of reboots. We'll let others handle them. + * We only try to do this if the BMC supports the Chassis device. + */ + if (sc->ipmi_dev_support & IPMI_ADS_CHASSIS) { + device_printf(dev, "Establishing power cycle handler\n"); + sc->ipmi_power_cycle_tag = EVENTHANDLER_REGISTER(shutdown_final, + ipmi_power_cycle, sc, SHUTDOWN_PRI_LAST - 1); + } } int @@ -839,11 +992,18 @@ ipmi_detach(device_t dev) destroy_dev(sc->ipmi_cdev); /* Detach from watchdog handling and turn off watchdog. */ + if (sc->ipmi_shutdown_tag) + EVENTHANDLER_DEREGISTER(shutdown_pre_sync, + sc->ipmi_shutdown_tag); if (sc->ipmi_watchdog_tag) { EVENTHANDLER_DEREGISTER(watchdog_list, sc->ipmi_watchdog_tag); ipmi_set_watchdog(sc, 0); } + /* Detach from shutdown handling for power cycle reboot */ + if (sc->ipmi_power_cycle_tag) + EVENTHANDLER_DEREGISTER(shutdown_final, sc->ipmi_power_cycle_tag); + /* XXX: should use shutdown callout I think. */ /* If the backend uses a kthread, shut it down. */ IPMI_LOCK(sc); diff --git a/sys/dev/ipmi/ipmivars.h b/sys/dev/ipmi/ipmivars.h index 6682b56b6299..35234b5bf57a 100644 --- a/sys/dev/ipmi/ipmivars.h +++ b/sys/dev/ipmi/ipmivars.h @@ -103,11 +103,16 @@ struct ipmi_softc { void *ipmi_irq; int ipmi_detaching; int ipmi_opened; + uint8_t ipmi_dev_support; /* IPMI_ADS_* */ struct cdev *ipmi_cdev; TAILQ_HEAD(,ipmi_request) ipmi_pending_requests; int ipmi_driver_requests_polled; + eventhandler_tag ipmi_power_cycle_tag; eventhandler_tag ipmi_watchdog_tag; + eventhandler_tag ipmi_shutdown_tag; int ipmi_watchdog_active; + int ipmi_watchdog_actions; + int ipmi_watchdog_pretimeout; struct intr_config_hook ipmi_ich; struct mtx ipmi_requests_lock; struct cv ipmi_request_added; diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index fc2553d48b9d..673af553b658 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -291,17 +291,14 @@ iscsi_session_logout(struct iscsi_session *is) static void iscsi_session_terminate_task(struct iscsi_session *is, - struct iscsi_outstanding *io, bool requeue) + struct iscsi_outstanding *io, cam_status status) { ISCSI_SESSION_LOCK_ASSERT(is); if (io->io_ccb != NULL) { io->io_ccb->ccb_h.status &= ~(CAM_SIM_QUEUED | CAM_STATUS_MASK); - if (requeue) - io->io_ccb->ccb_h.status |= CAM_REQUEUE_REQ; - else - io->io_ccb->ccb_h.status |= CAM_REQ_ABORTED; + io->io_ccb->ccb_h.status |= status; if ((io->io_ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { io->io_ccb->ccb_h.status |= CAM_DEV_QFRZN; xpt_freeze_devq(io->io_ccb->ccb_h.path, 1); @@ -313,14 +310,14 @@ iscsi_session_terminate_task(struct iscsi_session *is, } static void -iscsi_session_terminate_tasks(struct iscsi_session *is, bool requeue) +iscsi_session_terminate_tasks(struct iscsi_session *is, cam_status status) { struct iscsi_outstanding *io, *tmp; ISCSI_SESSION_LOCK_ASSERT(is); TAILQ_FOREACH_SAFE(io, &is->is_outstanding, io_next, tmp) { - iscsi_session_terminate_task(is, io, requeue); + iscsi_session_terminate_task(is, io, status); } } @@ -354,11 +351,11 @@ iscsi_session_cleanup(struct iscsi_session *is, bool destroy_sim) /* * Terminate SCSI tasks, asking CAM to requeue them. */ - iscsi_session_terminate_tasks(is, true); + iscsi_session_terminate_tasks(is, CAM_REQUEUE_REQ); return; } - iscsi_session_terminate_tasks(is, false); + iscsi_session_terminate_tasks(is, CAM_DEV_NOT_THERE); if (is->is_sim == NULL) return; @@ -434,6 +431,8 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is) sc = is->is_softc; sx_xlock(&sc->sc_lock); + TAILQ_REMOVE(&sc->sc_sessions, is, is_next); + sx_xunlock(&sc->sc_lock); icl_conn_close(is->is_conn); callout_drain(&is->is_callout); @@ -465,8 +464,6 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is) #ifdef ICL_KERNEL_PROXY cv_destroy(&is->is_login_cv); #endif - TAILQ_REMOVE(&sc->sc_sessions, is, is_next); - sx_xunlock(&sc->sc_lock); ISCSI_SESSION_DEBUG(is, "terminated"); free(is, M_ISCSI); @@ -1021,7 +1018,7 @@ iscsi_pdu_handle_task_response(struct icl_pdu *response) } else { aio = iscsi_outstanding_find(is, io->io_datasn); if (aio != NULL && aio->io_ccb != NULL) - iscsi_session_terminate_task(is, aio, false); + iscsi_session_terminate_task(is, aio, CAM_REQ_ABORTED); } iscsi_outstanding_remove(is, io); @@ -2461,8 +2458,10 @@ static void iscsi_shutdown_post(struct iscsi_softc *sc) { - ISCSI_DEBUG("removing all sessions due to shutdown"); - iscsi_terminate_sessions(sc); + if (panicstr == NULL) { + ISCSI_DEBUG("removing all sessions due to shutdown"); + iscsi_terminate_sessions(sc); + } } static int diff --git a/sys/dev/iscsi_initiator/isc_soc.c b/sys/dev/iscsi_initiator/isc_soc.c index 1e25f7268360..ed84f192a6cf 100644 --- a/sys/dev/iscsi_initiator/isc_soc.c +++ b/sys/dev/iscsi_initiator/isc_soc.c @@ -70,12 +70,13 @@ static int ou_refcnt = 0; | function for freeing external storage for mbuf */ static void -ext_free(struct mbuf *m, void *a, void *b) +ext_free(struct mbuf *m) { - pduq_t *pq = b; + pduq_t *pq = m->m_ext.ext_arg1; if(pq->buf != NULL) { - debug(3, "ou_refcnt=%d a=%p b=%p", ou_refcnt, a, pq->buf); + debug(3, "ou_refcnt=%d a=%p b=%p", + ou_refcnt, m->m_ext.ext_buf, pq->buf); free(pq->buf, M_ISCSIBUF); pq->buf = NULL; } @@ -137,11 +138,8 @@ isc_sendPDU(isc_session_t *sp, pduq_t *pq) md->m_ext.ext_cnt = &ou_refcnt; l = min(MCLBYTES, len); debug(4, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l); - MEXTADD(md, pp->ds_addr + off, l, ext_free, -#if __FreeBSD_version >= 800000 - pp->ds_addr + off, -#endif - pq, 0, EXT_EXTREF); + m_extadd(md, pp->ds_addr + off, l, ext_free, pq, NULL, 0, + EXT_EXTREF); md->m_len = l; md->m_next = NULL; mh->m_pkthdr.len += l; diff --git a/sys/dev/isp/DriverManual.txt b/sys/dev/isp/DriverManual.txt index ded4f3a976c3..b21fab1a9d04 100644 --- a/sys/dev/isp/DriverManual.txt +++ b/sys/dev/isp/DriverManual.txt @@ -625,7 +625,7 @@ Various URLs of interest: http://www.netbsd.org - NetBSD's Web Page http://www.openbsd.org - OpenBSD's Web Page -http://www.freebsd.org - FreeBSD's Web Page +https://www.freebsd.org - FreeBSD's Web Page http://www.t10.org - ANSI SCSI Commitee's Web Page (SCSI Specs) diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c index f7f3f3cb9ae6..27258afe0c3c 100644 --- a/sys/dev/iwm/if_iwm.c +++ b/sys/dev/iwm/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.42 2015/05/30 02:49:23 deraadt Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.167 2017/04/04 00:40:52 claudio Exp $ */ /* * Copyright (c) 2014 genua mbh @@ -5690,6 +5690,7 @@ iwm_intr(void *arg) #define PCI_PRODUCT_INTEL_WL_7265_2 0x095b #define PCI_PRODUCT_INTEL_WL_8260_1 0x24f3 #define PCI_PRODUCT_INTEL_WL_8260_2 0x24f4 +#define PCI_PRODUCT_INTEL_WL_8265_1 0x24fd static const struct iwm_devices { uint16_t device; @@ -5705,6 +5706,7 @@ static const struct iwm_devices { { PCI_PRODUCT_INTEL_WL_7265_2, &iwm7265_cfg }, { PCI_PRODUCT_INTEL_WL_8260_1, &iwm8260_cfg }, { PCI_PRODUCT_INTEL_WL_8260_2, &iwm8260_cfg }, + { PCI_PRODUCT_INTEL_WL_8265_1, &iwm8265_cfg }, }; static int diff --git a/sys/dev/iwm/if_iwm_8000.c b/sys/dev/iwm/if_iwm_8000.c index 440936707918..59df62528809 100644 --- a/sys/dev/iwm/if_iwm_8000.c +++ b/sys/dev/iwm/if_iwm_8000.c @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include "if_iwm_config.h" #define IWM8000_FW "iwm8000Cfw" +#define IWM8265_FW "iwm8265fw" #define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10 @@ -93,3 +94,10 @@ const struct iwm_cfg iwm8260_cfg = { IWM_DEVICE_8000_COMMON, .host_interrupt_operation_mode = 0, }; + +const struct iwm_cfg iwm8265_cfg = { + .name = "Intel(R) Dual Band Wireless AC 8265", + .fw_name = IWM8265_FW, + IWM_DEVICE_8000_COMMON, + .host_interrupt_operation_mode = 0, +}; diff --git a/sys/dev/iwm/if_iwm_config.h b/sys/dev/iwm/if_iwm_config.h index 74f34ba62f02..0d3d4a063272 100644 --- a/sys/dev/iwm/if_iwm_config.h +++ b/sys/dev/iwm/if_iwm_config.h @@ -131,5 +131,6 @@ extern const struct iwm_cfg iwm3165_cfg; extern const struct iwm_cfg iwm7265_cfg; extern const struct iwm_cfg iwm7265d_cfg; extern const struct iwm_cfg iwm8260_cfg; +extern const struct iwm_cfg iwm8265_cfg; #endif /* __IWM_CONFIG_H__ */ diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 0902a7ff99a1..46338a76e47c 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -469,9 +469,6 @@ ixgbe_initialize_rss_mapping(struct adapter *adapter) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP; if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX) - device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, but not supported\n", - __func__); if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX) @@ -1757,15 +1754,17 @@ ixgbe_setup_vlan_hw_support(struct adapter *adapter) return; /* Setup the queues for vlans */ - for (i = 0; i < adapter->num_queues; i++) { - rxr = &adapter->rx_rings[i]; - /* On 82599 the VLAN enable is per/queue in RXDCTL */ - if (hw->mac.type != ixgbe_mac_82598EB) { - ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); - ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl); + if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { + for (i = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + /* On 82599 the VLAN enable is per/queue in RXDCTL */ + if (hw->mac.type != ixgbe_mac_82598EB) { + ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)); + ctrl |= IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl); + } + rxr->vtag_strip = TRUE; } - rxr->vtag_strip = TRUE; } if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0) diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c index 5e3a3fe03b34..58425a485e8a 100644 --- a/sys/dev/ixgbe/if_ixv.c +++ b/sys/dev/ixgbe/if_ixv.c @@ -1403,9 +1403,6 @@ ixv_initialize_rss_mapping(struct adapter *adapter) __func__); if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; - if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX) - device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, but not supported\n", - __func__); if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX) diff --git a/sys/dev/ixgbe/ixgbe_rss.h b/sys/dev/ixgbe/ixgbe_rss.h index e22560b99457..7e7620be63f4 100644 --- a/sys/dev/ixgbe/ixgbe_rss.h +++ b/sys/dev/ixgbe/ixgbe_rss.h @@ -49,7 +49,6 @@ #define RSS_HASHTYPE_RSS_IPV6_EX (1 << 5) #define RSS_HASHTYPE_RSS_TCP_IPV6_EX (1 << 6) #define RSS_HASHTYPE_RSS_UDP_IPV4 (1 << 7) -#define RSS_HASHTYPE_RSS_UDP_IPV4_EX (1 << 8) #define RSS_HASHTYPE_RSS_UDP_IPV6 (1 << 9) #define RSS_HASHTYPE_RSS_UDP_IPV6_EX (1 << 10) diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c index 7872d0a4b925..3501ebc4cd50 100644 --- a/sys/dev/ixl/ixl_txrx.c +++ b/sys/dev/ixl/ixl_txrx.c @@ -1446,10 +1446,8 @@ static inline int ixl_ptype_to_hash(u8 ptype) { struct i40e_rx_ptype_decoded decoded; - u8 ex = 0; decoded = decode_rx_desc_ptype(ptype); - ex = decoded.outer_frag; if (!decoded.known) return M_HASHTYPE_OPAQUE_HASH; @@ -1460,34 +1458,22 @@ ixl_ptype_to_hash(u8 ptype) /* Note: anything that gets to this point is IP */ if (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6) { switch (decoded.inner_prot) { - case I40E_RX_PTYPE_INNER_PROT_TCP: - if (ex) - return M_HASHTYPE_RSS_TCP_IPV6_EX; - else - return M_HASHTYPE_RSS_TCP_IPV6; - case I40E_RX_PTYPE_INNER_PROT_UDP: - if (ex) - return M_HASHTYPE_RSS_UDP_IPV6_EX; - else - return M_HASHTYPE_RSS_UDP_IPV6; - default: - if (ex) - return M_HASHTYPE_RSS_IPV6_EX; - else - return M_HASHTYPE_RSS_IPV6; + case I40E_RX_PTYPE_INNER_PROT_TCP: + return M_HASHTYPE_RSS_TCP_IPV6; + case I40E_RX_PTYPE_INNER_PROT_UDP: + return M_HASHTYPE_RSS_UDP_IPV6; + default: + return M_HASHTYPE_RSS_IPV6; } } if (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4) { switch (decoded.inner_prot) { - case I40E_RX_PTYPE_INNER_PROT_TCP: - return M_HASHTYPE_RSS_TCP_IPV4; - case I40E_RX_PTYPE_INNER_PROT_UDP: - if (ex) - return M_HASHTYPE_RSS_UDP_IPV4_EX; - else - return M_HASHTYPE_RSS_UDP_IPV4; - default: - return M_HASHTYPE_RSS_IPV4; + case I40E_RX_PTYPE_INNER_PROT_TCP: + return M_HASHTYPE_RSS_TCP_IPV4; + case I40E_RX_PTYPE_INNER_PROT_UDP: + return M_HASHTYPE_RSS_UDP_IPV4; + default: + return M_HASHTYPE_RSS_IPV4; } } /* We should never get here!! */ diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c index 262aab35522b..115d2fa74729 100644 --- a/sys/dev/lge/if_lge.c +++ b/sys/dev/lge/if_lge.c @@ -123,7 +123,7 @@ static int lge_detach(device_t); static int lge_alloc_jumbo_mem(struct lge_softc *); static void lge_free_jumbo_mem(struct lge_softc *); static void *lge_jalloc(struct lge_softc *); -static void lge_jfree(struct mbuf *, void *, void *); +static void lge_jfree(struct mbuf *); static int lge_newbuf(struct lge_softc *, struct lge_rx_desc *, struct mbuf *); static int lge_encap(struct lge_softc *, struct mbuf *, u_int32_t *); @@ -689,7 +689,7 @@ lge_newbuf(sc, c, m) struct mbuf *m; { struct mbuf *m_new = NULL; - caddr_t *buf = NULL; + char *buf = NULL; if (m == NULL) { MGETHDR(m_new, M_NOWAIT, MT_DATA); @@ -710,10 +710,9 @@ lge_newbuf(sc, c, m) return(ENOBUFS); } /* Attach the buffer to the mbuf */ - m_new->m_data = (void *)buf; m_new->m_len = m_new->m_pkthdr.len = LGE_JUMBO_FRAMELEN; - MEXTADD(m_new, buf, LGE_JUMBO_FRAMELEN, lge_jfree, - buf, (struct lge_softc *)sc, 0, EXT_NET_DRV); + m_extadd(m_new, buf, LGE_JUMBO_FRAMELEN, lge_jfree, sc, NULL, + 0, EXT_NET_DRV); } else { m_new = m; m_new->m_len = m_new->m_pkthdr.len = LGE_JUMBO_FRAMELEN; @@ -848,20 +847,20 @@ lge_jalloc(sc) * Release a jumbo buffer. */ static void -lge_jfree(struct mbuf *m, void *buf, void *args) +lge_jfree(struct mbuf *m) { struct lge_softc *sc; int i; struct lge_jpool_entry *entry; /* Extract the softc struct pointer. */ - sc = args; + sc = m->m_ext.ext_arg1; if (sc == NULL) panic("lge_jfree: can't find softc pointer!"); /* calculate the slot this buffer belongs to */ - i = ((vm_offset_t)buf + i = ((vm_offset_t)m->m_ext.ext_buf - (vm_offset_t)sc->lge_cdata.lge_jumbo_buf) / LGE_JLEN; if ((i < 0) || (i >= LGE_JSLOTS)) diff --git a/sys/dev/liquidio/base/cn23xx_pf_device.c b/sys/dev/liquidio/base/cn23xx_pf_device.c index 9623b5e478c8..0df5f7767232 100644 --- a/sys/dev/liquidio/base/cn23xx_pf_device.c +++ b/sys/dev/liquidio/base/cn23xx_pf_device.c @@ -162,11 +162,11 @@ lio_cn23xx_pf_setup_global_mac_regs(struct octeon_device *oct) lio_write_csr64(oct, LIO_CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num), reg_val); - lio_dev_dbg(oct, "SLI_PKT_MAC(%d)_PF(%d)_RINFO : 0x%016lx\n", mac_no, + lio_dev_dbg(oct, "SLI_PKT_MAC(%d)_PF(%d)_RINFO : 0x%016llx\n", mac_no, pf_num, - lio_read_csr64(oct, + LIO_CAST64(lio_read_csr64(oct, LIO_CN23XX_SLI_PKT_MAC_RINFO64(mac_no, - pf_num))); + pf_num)))); } static int diff --git a/sys/dev/liquidio/base/lio_device.c b/sys/dev/liquidio/base/lio_device.c index c6a1200b8b9b..8bcf4f329848 100644 --- a/sys/dev/liquidio/base/lio_device.c +++ b/sys/dev/liquidio/base/lio_device.c @@ -817,8 +817,8 @@ lio_core_drv_init(struct lio_recv_info *recv_info, void *buf) cs = &core_setup[oct->octeon_id]; if (recv_pkt->buffer_size[0] != (sizeof(*cs) + LIO_DROQ_INFO_SIZE)) { - lio_dev_dbg(oct, "Core setup bytes expected %lu found %d\n", - (uint32_t)sizeof(*cs) + LIO_DROQ_INFO_SIZE, + lio_dev_dbg(oct, "Core setup bytes expected %llu found %d\n", + LIO_CAST64(sizeof(*cs) + LIO_DROQ_INFO_SIZE), recv_pkt->buffer_size[0]); } diff --git a/sys/dev/liquidio/base/lio_device.h b/sys/dev/liquidio/base/lio_device.h index 25229ba469eb..d5ba3361b2fc 100644 --- a/sys/dev/liquidio/base/lio_device.h +++ b/sys/dev/liquidio/base/lio_device.h @@ -873,16 +873,26 @@ static inline uint64_t lio_read_csr64(struct octeon_device *oct, uint32_t reg) { +#ifdef __i386__ + return (lio_read_csr32(oct, reg) | + ((uint64_t)lio_read_csr32(oct, reg + 4) << 32)); +#else return (bus_space_read_8(oct->mem_bus_space[0].tag, oct->mem_bus_space[0].handle, reg)); +#endif } static inline void lio_write_csr64(struct octeon_device *oct, uint32_t reg, uint64_t val) { +#ifdef __i386__ + lio_write_csr32(oct, reg, (uint32_t)val); + lio_write_csr32(oct, reg + 4, val >> 32); +#else bus_space_write_8(oct->mem_bus_space[0].tag, oct->mem_bus_space[0].handle, reg, val); +#endif } #endif /* _LIO_DEVICE_H_ */ diff --git a/sys/dev/liquidio/base/lio_droq.c b/sys/dev/liquidio/base/lio_droq.c index 3829e5d734c0..d8a58e52fafb 100644 --- a/sys/dev/liquidio/base/lio_droq.c +++ b/sys/dev/liquidio/base/lio_droq.c @@ -294,8 +294,8 @@ lio_init_droq(struct octeon_device *oct, uint32_t q_no, return (1); } - lio_dev_dbg(oct, "droq[%d]: desc_ring: virt: 0x%p, dma: %lx\n", q_no, - droq->desc_ring, droq->desc_ring_dma); + lio_dev_dbg(oct, "droq[%d]: desc_ring: virt: 0x%p, dma: %llx\n", q_no, + droq->desc_ring, LIO_CAST64(droq->desc_ring_dma)); lio_dev_dbg(oct, "droq[%d]: num_desc: %d\n", q_no, droq->max_count); size = droq->max_count * LIO_DROQ_RECVBUF_SIZE; diff --git a/sys/dev/liquidio/base/lio_mem_ops.c b/sys/dev/liquidio/base/lio_mem_ops.c index 0c821c196bf8..64526438e333 100644 --- a/sys/dev/liquidio/base/lio_mem_ops.c +++ b/sys/dev/liquidio/base/lio_mem_ops.c @@ -65,20 +65,48 @@ lio_write_bar1_mem8(struct octeon_device *oct, uint32_t reg, uint64_t val) oct->mem_bus_space[1].handle, reg, val); } +#ifdef __i386__ +static inline uint32_t +lio_read_bar1_mem32(struct octeon_device *oct, uint32_t reg) +{ + + return (bus_space_read_4(oct->mem_bus_space[1].tag, + oct->mem_bus_space[1].handle, reg)); +} + +static inline void +lio_write_bar1_mem32(struct octeon_device *oct, uint32_t reg, uint32_t val) +{ + + bus_space_write_4(oct->mem_bus_space[1].tag, + oct->mem_bus_space[1].handle, reg, val); +} +#endif + static inline uint64_t lio_read_bar1_mem64(struct octeon_device *oct, uint32_t reg) { +#ifdef __i386__ + return (lio_read_bar1_mem32(oct, reg) | + ((uint64_t)lio_read_bar1_mem32(oct, reg + 4) << 32)); +#else return (bus_space_read_8(oct->mem_bus_space[1].tag, oct->mem_bus_space[1].handle, reg)); +#endif } static inline void lio_write_bar1_mem64(struct octeon_device *oct, uint32_t reg, uint64_t val) { +#ifdef __i386__ + lio_write_bar1_mem32(oct, reg, (uint32_t)val); + lio_write_bar1_mem32(oct, reg + 4, val >> 32); +#else bus_space_write_8(oct->mem_bus_space[1].tag, oct->mem_bus_space[1].handle, reg, val); +#endif } static void diff --git a/sys/dev/liquidio/base/lio_request_manager.c b/sys/dev/liquidio/base/lio_request_manager.c index 2dd9ec5be874..db7548e7ddff 100644 --- a/sys/dev/liquidio/base/lio_request_manager.c +++ b/sys/dev/liquidio/base/lio_request_manager.c @@ -97,7 +97,7 @@ lio_init_instr_queue(struct octeon_device *oct, union octeon_txpciq txpciq, return (1); } - iq->base_addr = lio_dma_alloc(q_size, &iq->base_addr_dma); + iq->base_addr = lio_dma_alloc(q_size, (vm_paddr_t *)&iq->base_addr_dma); if (!iq->base_addr) { lio_dev_err(oct, "Cannot allocate memory for instr queue %d\n", iq_no); @@ -118,8 +118,9 @@ lio_init_instr_queue(struct octeon_device *oct, union octeon_txpciq txpciq, return (1); } - lio_dev_dbg(oct, "IQ[%d]: base: %p basedma: %lx count: %d\n", - iq_no, iq->base_addr, iq->base_addr_dma, iq->max_count); + lio_dev_dbg(oct, "IQ[%d]: base: %p basedma: %llx count: %d\n", + iq_no, iq->base_addr, LIO_CAST64(iq->base_addr_dma), + iq->max_count); /* Create the descriptor buffer dma maps */ request_buf = iq->request_list; @@ -736,7 +737,7 @@ lio_setup_sc_buffer_pool(struct octeon_device *oct) for (i = 0; i < LIO_MAX_SOFT_COMMAND_BUFFERS; i++) { sc = (struct lio_soft_command *) - lio_dma_alloc(LIO_SOFT_COMMAND_BUFFER_SIZE, &dma_addr); + lio_dma_alloc(LIO_SOFT_COMMAND_BUFFER_SIZE, (vm_paddr_t *)&dma_addr); if (sc == NULL) { lio_free_sc_buffer_pool(oct); return (1); diff --git a/sys/dev/liquidio/lio_main.c b/sys/dev/liquidio/lio_main.c index 7f43bb407ad8..99e9ad2e3164 100644 --- a/sys/dev/liquidio/lio_main.c +++ b/sys/dev/liquidio/lio_main.c @@ -1013,7 +1013,7 @@ lio_get_media_subtype(struct octeon_device *oct) return (IFM_10G_SR); } -static unsigned long +static uint64_t lio_get_baudrate(struct octeon_device *oct) { @@ -1318,15 +1318,16 @@ lio_setup_nic_devices(struct octeon_device *octeon_dev) if (!(num_iqueues) || !(num_oqueues)) { lio_dev_err(octeon_dev, - "Got bad iqueues (%016lX) or oqueues (%016lX) from firmware.\n", - resp->cfg_info.iqmask, - resp->cfg_info.oqmask); + "Got bad iqueues (%016llX) or oqueues (%016llX) from firmware.\n", + LIO_CAST64(resp->cfg_info.iqmask), + LIO_CAST64(resp->cfg_info.oqmask)); goto setup_nic_dev_fail; } lio_dev_dbg(octeon_dev, - "interface %d, iqmask %016lx, oqmask %016lx, numiqueues %d, numoqueues %d\n", - i, resp->cfg_info.iqmask, resp->cfg_info.oqmask, + "interface %d, iqmask %016llx, oqmask %016llx, numiqueues %d, numoqueues %d\n", + i, LIO_CAST64(resp->cfg_info.iqmask), + LIO_CAST64(resp->cfg_info.oqmask), num_iqueues, num_oqueues); ifp = if_alloc(IFT_ETHER); diff --git a/sys/dev/liquidio/lio_main.h b/sys/dev/liquidio/lio_main.h index f5cd2370f2c2..4be961d10240 100644 --- a/sys/dev/liquidio/lio_main.h +++ b/sys/dev/liquidio/lio_main.h @@ -43,11 +43,7 @@ extern unsigned int lio_hwlro; -#ifdef __LP64__ #define LIO_CAST64(v) ((long long)(long)(v)) -#else -#error "Unknown system architecture" -#endif #define LIO_DRV_NAME "lio" @@ -107,9 +103,9 @@ lio_map_pci_barx(struct octeon_device *oct, int baridx) oct->mem_bus_space[baridx].handle = rman_get_bushandle(oct->mem_bus_space[baridx].pci_mem); - lio_dev_dbg(oct, "BAR%d Tag 0x%lx Handle 0x%lx\n", - baridx, oct->mem_bus_space[baridx].tag, - oct->mem_bus_space[baridx].handle); + lio_dev_dbg(oct, "BAR%d Tag 0x%llx Handle 0x%llx\n", + baridx, LIO_CAST64(oct->mem_bus_space[baridx].tag), + LIO_CAST64(oct->mem_bus_space[baridx].handle)); return (0); } diff --git a/sys/dev/liquidio/lio_rxtx.c b/sys/dev/liquidio/lio_rxtx.c index 0516800770ca..c966797c5e3c 100644 --- a/sys/dev/liquidio/lio_rxtx.c +++ b/sys/dev/liquidio/lio_rxtx.c @@ -218,8 +218,8 @@ lio_xmit(struct lio *lio, struct lio_instr_queue *iq, drop_packet: stats->tx_dropped++; - lio_dev_err(oct, "IQ%d Transmit dropped: %lu\n", iq_no, - stats->tx_dropped); + lio_dev_err(oct, "IQ%d Transmit dropped: %llu\n", iq_no, + LIO_CAST64(stats->tx_dropped)); m_freem(*m_headp); *m_headp = NULL; diff --git a/sys/dev/liquidio/lio_sysctl.c b/sys/dev/liquidio/lio_sysctl.c index dd99be59d8e1..e4c02a791c9f 100644 --- a/sys/dev/liquidio/lio_sysctl.c +++ b/sys/dev/liquidio/lio_sysctl.c @@ -634,13 +634,15 @@ lio_get_eeprom(SYSCTL_HANDLER_ARGS) board_info = (struct lio_board_info *)(&oct_dev->boardinfo); if (oct_dev->uboot_len == 0) - sprintf(buf, "boardname:%s serialnum:%s maj:%ld min:%ld", + sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld", board_info->name, board_info->serial_number, - board_info->major, board_info->minor); + LIO_CAST64(board_info->major), + LIO_CAST64(board_info->minor)); else { - sprintf(buf, "boardname:%s serialnum:%s maj:%ld min:%ld\n%s", + sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n%s", board_info->name, board_info->serial_number, - board_info->major, board_info->minor, + LIO_CAST64(board_info->major), + LIO_CAST64(board_info->minor), &oct_dev->uboot_version[oct_dev->uboot_sidx]); } @@ -777,184 +779,184 @@ lio_cn23xx_pf_read_csr_reg(char *s, struct octeon_device *oct) /* 0x29030 or 0x29040 */ reg = LIO_CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num); - len += sprintf(s + len, "[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016lx\n", + len += sprintf(s + len, "[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n", reg, oct->pcie_port, oct->pf_num, - lio_read_csr64(oct, reg)); + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x27080 or 0x27090 */ reg = LIO_CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num); - len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016lx\n", + len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n", reg, oct->pcie_port, oct->pf_num, - lio_read_csr64(oct, reg)); + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x27000 or 0x27010 */ reg = LIO_CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num); - len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016lx\n", + len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n", reg, oct->pcie_port, oct->pf_num, - lio_read_csr64(oct, reg)); + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29120 */ reg = 0x29120; - len += sprintf(s + len, "[%08x] (SLI_PKT_MEM_CTL): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x27300 */ reg = 0x27300 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET + (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET; - len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016lx\n", + len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg, oct->pcie_port, oct->pf_num, - lio_read_csr64(oct, reg)); + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x27200 */ reg = 0x27200 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET + (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET; - len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016lx\n", + len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n", reg, oct->pcie_port, oct->pf_num, - lio_read_csr64(oct, reg)); + LIO_CAST64(lio_read_csr64(oct, reg))); /* 29130 */ reg = LIO_CN23XX_SLI_PKT_CNT_INT; - len += sprintf(s + len, "[%08x] (SLI_PKT_CNT_INT): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29140 */ reg = LIO_CN23XX_SLI_PKT_TIME_INT; - len += sprintf(s + len, "[%08x] (SLI_PKT_TIME_INT): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29160 */ reg = 0x29160; - len += sprintf(s + len, "[%08x] (SLI_PKT_INT): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_INT): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29180 */ reg = LIO_CN23XX_SLI_OQ_WMARK; - len += sprintf(s + len, "[%08x] (SLI_PKT_OUTPUT_WMARK): %016lx\n", - reg, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n", + reg, LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x291E0 */ reg = LIO_CN23XX_SLI_PKT_IOQ_RING_RST; - len += sprintf(s + len, "[%08x] (SLI_PKT_RING_RST): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_RING_RST): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29210 */ reg = LIO_CN23XX_SLI_GBL_CONTROL; - len += sprintf(s + len, "[%08x] (SLI_PKT_GBL_CONTROL): %016lx\n", reg, - lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg, + LIO_CAST64(lio_read_csr64(oct, reg))); /* 0x29220 */ reg = 0x29220; - len += sprintf(s + len, "[%08x] (SLI_PKT_BIST_STATUS): %016lx\n", - reg, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_BIST_STATUS): %016llx\n", + reg, LIO_CAST64(lio_read_csr64(oct, reg))); /* PF only */ if (pf_num == 0) { /* 0x29260 */ reg = LIO_CN23XX_SLI_OUT_BP_EN_W1S; - len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN_W1S): %016lx\n", - reg, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN_W1S): %016llx\n", + reg, LIO_CAST64(lio_read_csr64(oct, reg))); } else if (pf_num == 1) { /* 0x29270 */ reg = LIO_CN23XX_SLI_OUT_BP_EN2_W1S; - len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016lx\n", - reg, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n", + reg, LIO_CAST64(lio_read_csr64(oct, reg))); } for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_BUFF_INFO_SIZE(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_OUT_SIZE): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10040 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i); - len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10080 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_PKTS_CREDIT(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10090 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_SIZE(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10050 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_PKT_CONTROL(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10070 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_BASE_ADDR64(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BADDR): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x100a0 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_INT_LEVELS): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x100b0 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_OQ_PKTS_SENT(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_CNTS): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_CNTS): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x100c0 */ for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { reg = 0x100c0 + i * LIO_CN23XX_OQ_OFFSET; - len += sprintf(s + len, "[%08x] (SLI_PKT%d_ERROR_INFO): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10000 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_IQ_PKT_CONTROL64(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_INPUT_CONTROL): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10010 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_IQ_BASE_ADDR64(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BADDR): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10020 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_IQ_DOORBELL(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10030 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { reg = LIO_CN23XX_SLI_IQ_SIZE(i); - len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); } /* 0x10040 */ for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i); - len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016lx\n", - reg, i, lio_read_csr64(oct, reg)); + len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", + reg, i, LIO_CAST64(lio_read_csr64(oct, reg))); return (len); } @@ -1574,8 +1576,8 @@ lio_set_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg) lio_dev_err(oct_dev, "intrmod config failed. Status: %llx\n", LIO_CAST64(retval)); else - lio_dev_info(oct_dev, "Rx-Adaptive Interrupt moderation enabled:%lx\n", - intr_cfg->rx_enable); + lio_dev_info(oct_dev, "Rx-Adaptive Interrupt moderation enabled:%llx\n", + LIO_CAST64(intr_cfg->rx_enable)); lio_free_soft_command(oct_dev, sc); diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index d9c41f130235..21ad615ef05d 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -207,6 +207,7 @@ struct md_s { unsigned opencount; unsigned fwheads; unsigned fwsectors; + char ident[32]; unsigned flags; char name[20]; struct proc *procp; @@ -1111,7 +1112,10 @@ mdstart_swap(struct md_s *sc, struct bio *bp) if (m != NULL) { vm_page_xunbusy(m); vm_page_lock(m); - vm_page_activate(m); + if (vm_page_active(m)) + vm_page_reference(m); + else + vm_page_activate(m); vm_page_unlock(m); } @@ -1178,6 +1182,9 @@ md_kthread(void *arg) sc->fwheads))) || g_handleattr_int(bp, "GEOM::candelete", 1)) error = -1; + else if (sc->ident[0] != '\0' && + g_handleattr_str(bp, "GEOM::ident", sc->ident)) + error = -1; else if (g_handleattr_int(bp, "MNT::verified", isv)) error = -1; else @@ -1411,6 +1418,8 @@ mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td) sc->fwsectors = mdio->md_fwsectors; if (mdio->md_fwheads != 0) sc->fwheads = mdio->md_fwheads; + snprintf(sc->ident, sizeof(sc->ident), "MD-DEV%ju-INO%ju", + (uintmax_t)vattr.va_fsid, (uintmax_t)vattr.va_fileid); sc->flags = mdio->md_options & (MD_FORCE | MD_ASYNC | MD_VERIFY); if (!(flags & FWRITE)) sc->flags |= MD_READONLY; @@ -1895,6 +1904,11 @@ g_md_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, indent, (uintmax_t) mp->fwheads); sbuf_printf(sb, "%s%ju\n", indent, (uintmax_t) mp->fwsectors); + if (mp->ident[0] != '\0') { + sbuf_printf(sb, "%s", indent); + g_conf_printf_escaped(sb, "%s", mp->ident); + sbuf_printf(sb, "\n"); + } sbuf_printf(sb, "%s%ju\n", indent, (uintmax_t) mp->mediasize); sbuf_printf(sb, "%s%s\n", indent, diff --git a/sys/dev/mlx4/mlx4_en/en.h b/sys/dev/mlx4/mlx4_en/en.h index 9e0349137cd9..5e4b4fa60841 100644 --- a/sys/dev/mlx4/mlx4_en/en.h +++ b/sys/dev/mlx4/mlx4_en/en.h @@ -795,6 +795,8 @@ int mlx4_en_map_buffer(struct mlx4_buf *buf); void mlx4_en_unmap_buffer(struct mlx4_buf *buf); void mlx4_en_calc_rx_buf(struct net_device *dev); +const u32 *mlx4_en_get_rss_key(struct mlx4_en_priv *priv, u16 *keylen); +u8 mlx4_en_get_rss_mask(struct mlx4_en_priv *priv); int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv); diff --git a/sys/dev/mlx4/mlx4_en/mlx4_en_netdev.c b/sys/dev/mlx4/mlx4_en/mlx4_en_netdev.c index 7bdfc03730db..c7f169aa549b 100644 --- a/sys/dev/mlx4/mlx4_en/mlx4_en_netdev.c +++ b/sys/dev/mlx4/mlx4_en/mlx4_en_netdev.c @@ -1896,6 +1896,10 @@ static int mlx4_en_ioctl(struct ifnet *dev, u_long command, caddr_t data) struct ifreq *ifr; int error; int mask; + struct ifrsskey *ifrk; + const u32 *key; + struct ifrsshash *ifrh; + u8 rss_mask; error = 0; mask = 0; @@ -2024,6 +2028,39 @@ static int mlx4_en_ioctl(struct ifnet *dev, u_long command, caddr_t data) break; } #endif + case SIOCGIFRSSKEY: + ifrk = (struct ifrsskey *)data; + ifrk->ifrk_func = RSS_FUNC_TOEPLITZ; + mutex_lock(&mdev->state_lock); + key = mlx4_en_get_rss_key(priv, &ifrk->ifrk_keylen); + if (ifrk->ifrk_keylen > RSS_KEYLEN) + error = EINVAL; + else + memcpy(ifrk->ifrk_key, key, ifrk->ifrk_keylen); + mutex_unlock(&mdev->state_lock); + break; + + case SIOCGIFRSSHASH: + mutex_lock(&mdev->state_lock); + rss_mask = mlx4_en_get_rss_mask(priv); + mutex_unlock(&mdev->state_lock); + ifrh = (struct ifrsshash *)data; + ifrh->ifrh_func = RSS_FUNC_TOEPLITZ; + ifrh->ifrh_types = 0; + if (rss_mask & MLX4_RSS_IPV4) + ifrh->ifrh_types |= RSS_TYPE_IPV4; + if (rss_mask & MLX4_RSS_TCP_IPV4) + ifrh->ifrh_types |= RSS_TYPE_TCP_IPV4; + if (rss_mask & MLX4_RSS_IPV6) + ifrh->ifrh_types |= RSS_TYPE_IPV6; + if (rss_mask & MLX4_RSS_TCP_IPV6) + ifrh->ifrh_types |= RSS_TYPE_TCP_IPV6; + if (rss_mask & MLX4_RSS_UDP_IPV4) + ifrh->ifrh_types |= RSS_TYPE_UDP_IPV4; + if (rss_mask & MLX4_RSS_UDP_IPV6) + ifrh->ifrh_types |= RSS_TYPE_UDP_IPV6; + break; + default: error = ether_ioctl(dev, command, data); break; diff --git a/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c b/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c index 05bf7b41467c..300478205920 100644 --- a/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c +++ b/sys/dev/mlx4/mlx4_en/mlx4_en_rx.c @@ -555,6 +555,53 @@ mlx4_en_rx_mb(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring, return (mb); } +static __inline int +mlx4_en_rss_hash(__be16 status, int udp_rss) +{ + enum { + status_all = cpu_to_be16( + MLX4_CQE_STATUS_IPV4 | + MLX4_CQE_STATUS_IPV4F | + MLX4_CQE_STATUS_IPV6 | + MLX4_CQE_STATUS_TCP | + MLX4_CQE_STATUS_UDP), + status_ipv4_tcp = cpu_to_be16( + MLX4_CQE_STATUS_IPV4 | + MLX4_CQE_STATUS_TCP), + status_ipv6_tcp = cpu_to_be16( + MLX4_CQE_STATUS_IPV6 | + MLX4_CQE_STATUS_TCP), + status_ipv4_udp = cpu_to_be16( + MLX4_CQE_STATUS_IPV4 | + MLX4_CQE_STATUS_UDP), + status_ipv6_udp = cpu_to_be16( + MLX4_CQE_STATUS_IPV6 | + MLX4_CQE_STATUS_UDP), + status_ipv4 = cpu_to_be16(MLX4_CQE_STATUS_IPV4), + status_ipv6 = cpu_to_be16(MLX4_CQE_STATUS_IPV6) + }; + + status &= status_all; + switch (status) { + case status_ipv4_tcp: + return (M_HASHTYPE_RSS_TCP_IPV4); + case status_ipv6_tcp: + return (M_HASHTYPE_RSS_TCP_IPV6); + case status_ipv4_udp: + return (udp_rss ? M_HASHTYPE_RSS_UDP_IPV4 + : M_HASHTYPE_RSS_IPV4); + case status_ipv6_udp: + return (udp_rss ? M_HASHTYPE_RSS_UDP_IPV6 + : M_HASHTYPE_RSS_IPV6); + default: + if (status & status_ipv4) + return (M_HASHTYPE_RSS_IPV4); + if (status & status_ipv6) + return (M_HASHTYPE_RSS_IPV6); + return (M_HASHTYPE_OPAQUE_HASH); + } +} + /* For cpu arch with cache line of 64B the performance is better when cqe size==64B * To enlarge cqe size from 32B to 64B --> 32B of garbage (i.e. 0xccccccc) * was added in the beginning of each cqe (the real data is in the corresponding 32B). @@ -578,6 +625,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud u32 size_mask = ring->size_mask; int size = cq->size; int factor = priv->cqe_factor; + const int udp_rss = priv->mdev->profile.udp_rss; if (!priv->port_up) return 0; @@ -625,7 +673,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud /* forward Toeplitz compatible hash value */ mb->m_pkthdr.flowid = be32_to_cpu(cqe->immed_rss_invalid); - M_HASHTYPE_SET(mb, M_HASHTYPE_OPAQUE_HASH); + M_HASHTYPE_SET(mb, mlx4_en_rss_hash(cqe->status, udp_rss)); mb->m_pkthdr.rcvif = dev; if (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_VLAN_PRESENT_MASK) { @@ -814,6 +862,38 @@ void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv) mlx4_qp_release_range(priv->mdev->dev, qpn, 1); } +const u32 * +mlx4_en_get_rss_key(struct mlx4_en_priv *priv __unused, + u16 *keylen) +{ + static const u32 rsskey[10] = { + cpu_to_be32(0xD181C62C), + cpu_to_be32(0xF7F4DB5B), + cpu_to_be32(0x1983A2FC), + cpu_to_be32(0x943E1ADB), + cpu_to_be32(0xD9389E6B), + cpu_to_be32(0xD1039C2C), + cpu_to_be32(0xA74499AD), + cpu_to_be32(0x593D56D9), + cpu_to_be32(0xF3253C06), + cpu_to_be32(0x2ADC1FFC) + }; + + if (keylen != NULL) + *keylen = sizeof(rsskey); + return (rsskey); +} + +u8 mlx4_en_get_rss_mask(struct mlx4_en_priv *priv) +{ + u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 | + MLX4_RSS_TCP_IPV6); + + if (priv->mdev->profile.udp_rss) + rss_mask |= MLX4_RSS_UDP_IPV4 | MLX4_RSS_UDP_IPV6; + return (rss_mask); +} + /* Allocate rx qp's and configure them according to rss map */ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) { @@ -821,16 +901,12 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) struct mlx4_en_rss_map *rss_map = &priv->rss_map; struct mlx4_qp_context context; struct mlx4_rss_context *rss_context; + const u32 *key; int rss_rings; void *ptr; - u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 | - MLX4_RSS_TCP_IPV6); int i; int err = 0; int good_qps = 0; - static const u32 rsskey[10] = { 0xD181C62C, 0xF7F4DB5B, 0x1983A2FC, - 0x943E1ADB, 0xD9389E6B, 0xD1039C2C, 0xA74499AD, - 0x593D56D9, 0xF3253C06, 0x2ADC1FFC}; en_dbg(DRV, priv, "Configuring rss steering\n"); err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num, @@ -874,14 +950,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) rss_context->base_qpn = cpu_to_be32(ilog2(rss_rings) << 24 | (rss_map->base_qpn)); rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); - if (priv->mdev->profile.udp_rss) { - rss_mask |= MLX4_RSS_UDP_IPV4 | MLX4_RSS_UDP_IPV6; + if (priv->mdev->profile.udp_rss) rss_context->base_qpn_udp = rss_context->default_qpn; - } - rss_context->flags = rss_mask; + rss_context->flags = mlx4_en_get_rss_mask(priv); rss_context->hash_fn = MLX4_RSS_HASH_TOP; + key = mlx4_en_get_rss_key(priv, NULL); for (i = 0; i < 10; i++) - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); + rss_context->rss_key[i] = key[i]; err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c index 4ceaa6d77b17..298e7e698937 100644 --- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c +++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c @@ -2229,6 +2229,38 @@ static int mlx4_ib_dev_idx(struct mlx4_dev *dev) return -1; } +static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num, + struct ib_port_immutable *immutable) +{ + struct ib_port_attr attr; + struct mlx4_ib_dev *mdev = to_mdev(ibdev); + int err; + + if (mlx4_ib_port_link_layer(ibdev, port_num) == IB_LINK_LAYER_INFINIBAND) { + immutable->core_cap_flags = RDMA_CORE_PORT_IBA_IB; + immutable->max_mad_size = IB_MGMT_MAD_SIZE; + } else { + if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE) + immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE; + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCEV2) + immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE | + RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP; + immutable->core_cap_flags |= RDMA_CORE_PORT_RAW_PACKET; + if (immutable->core_cap_flags & (RDMA_CORE_PORT_IBA_ROCE | + RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP)) + immutable->max_mad_size = IB_MGMT_MAD_SIZE; + } + + err = ib_query_port(ibdev, port_num, &attr); + if (err) + return err; + + immutable->pkey_tbl_len = attr.pkey_tbl_len; + immutable->gid_tbl_len = attr.gid_tbl_len; + + return 0; +} + static void *mlx4_ib_add(struct mlx4_dev *dev) { struct mlx4_ib_dev *ibdev; @@ -2360,6 +2392,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach; ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; ibdev->ib_dev.process_mad = mlx4_ib_process_mad; + ibdev->ib_dev.get_port_immutable = mlx4_port_immutable; ibdev->ib_dev.get_netdev = mlx4_ib_get_netdev; ibdev->ib_dev.ioctl = mlx4_ib_ioctl; ibdev->ib_dev.query_values = mlx4_ib_query_values; diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h index c3bcba7a0223..376aafe8b990 100644 --- a/sys/dev/mlx5/mlx5_en/en.h +++ b/sys/dev/mlx5/mlx5_en/en.h @@ -800,12 +800,12 @@ mlx5e_tx_notify_hw(struct mlx5e_sq *sq, u32 *wqe, int bf_sz) } static inline void -mlx5e_cq_arm(struct mlx5e_cq *cq) +mlx5e_cq_arm(struct mlx5e_cq *cq, spinlock_t *dblock) { struct mlx5_core_cq *mcq; mcq = &cq->mcq; - mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, NULL, cq->wq.cc); + mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, dblock, cq->wq.cc); } extern const struct ethtool_ops mlx5e_ethtool_ops; diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index e816eb1e270a..b5277fd59fd4 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -1408,7 +1408,7 @@ mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param, int eq_ix) if (err) return (err); - mlx5e_cq_arm(cq); + mlx5e_cq_arm(cq, MLX5_GET_DOORBELL_LOCK(&cq->priv->doorbell_lock)); return (0); } diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c index 7c490deba86d..62189d4a6189 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c @@ -430,7 +430,7 @@ mlx5e_rx_cq_comp(struct mlx5_core_cq *mcq) mlx5e_post_rx_wqes(rq); } mlx5e_post_rx_wqes(rq); - mlx5e_cq_arm(&rq->cq); + mlx5e_cq_arm(&rq->cq, MLX5_GET_DOORBELL_LOCK(&rq->channel->priv->doorbell_lock)); tcp_lro_flush_all(&rq->lro); mtx_unlock(&rq->mtx); } diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c index fe0eb20ab071..6f20bd1fc359 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c @@ -574,7 +574,7 @@ mlx5e_tx_cq_comp(struct mlx5_core_cq *mcq) mtx_lock(&sq->comp_lock); mlx5e_poll_tx_cq(sq, MLX5E_BUDGET_MAX); - mlx5e_cq_arm(&sq->cq); + mlx5e_cq_arm(&sq->cq, MLX5_GET_DOORBELL_LOCK(&sq->priv->doorbell_lock)); mtx_unlock(&sq->comp_lock); } diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c index 2177045ade5f..ac1bb7a916a5 100644 --- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c +++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c @@ -562,26 +562,6 @@ mlx5_make_default_gid(struct net_device *dev, union ib_gid *gid) mlx5_addrconf_ifid_eui48(&gid->raw[8], dev); } -static inline int -mlx5_ip2gid(const struct sockaddr *addr, union ib_gid *gid) -{ - switch (addr->sa_family) { - case AF_INET: - ipv6_addr_set_v4mapped(((const struct sockaddr_in *)addr)->sin_addr.s_addr, - (struct in6_addr *)gid->raw); - break; - case AF_INET6: - memcpy(gid->raw, &((const struct sockaddr_in6 *)addr)->sin6_addr, 16); - /* clear SCOPE ID */ - gid->raw[2] = 0; - gid->raw[3] = 0; - break; - default: - return -EINVAL; - } - return 0; -} - static void mlx5_ib_roce_port_update(void *arg) { @@ -639,7 +619,7 @@ mlx5_ib_roce_port_update(void *arg) gid_index >= MLX5_IB_GID_MAX) continue; memset(&gid_temp, 0, sizeof(gid_temp)); - mlx5_ip2gid(ifa->ifa_addr, &gid_temp); + rdma_ip2gid(ifa->ifa_addr, &gid_temp); /* check for existing entry */ for (j = 0; j != gid_index; j++) { if (bcmp(&gid_temp, &port->gid_table[j], sizeof(gid_temp)) == 0) @@ -1690,6 +1670,57 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr) mlx5_ib_dealloc_pd(devr->p0); } +static u32 get_core_cap_flags(struct ib_device *ibdev) +{ + struct mlx5_ib_dev *dev = to_mdev(ibdev); + enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, 1); + u8 l3_type_cap = MLX5_CAP_ROCE(dev->mdev, l3_type); + u8 roce_version_cap = MLX5_CAP_ROCE(dev->mdev, roce_version); + u32 ret = 0; + + if (ll == IB_LINK_LAYER_INFINIBAND) + return RDMA_CORE_PORT_IBA_IB; + + ret = RDMA_CORE_PORT_RAW_PACKET; + + if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV4_CAP)) + return ret; + + if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV6_CAP)) + return ret; + + if (roce_version_cap & MLX5_ROCE_VERSION_1_CAP) + ret |= RDMA_CORE_PORT_IBA_ROCE; + + if (roce_version_cap & MLX5_ROCE_VERSION_2_CAP) + ret |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP; + + return ret; +} + +static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num, + struct ib_port_immutable *immutable) +{ + struct ib_port_attr attr; + struct mlx5_ib_dev *dev = to_mdev(ibdev); + enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, port_num); + int err; + + immutable->core_cap_flags = get_core_cap_flags(ibdev); + + err = ib_query_port(ibdev, port_num, &attr); + if (err) + return err; + + immutable->pkey_tbl_len = attr.pkey_tbl_len; + immutable->gid_tbl_len = attr.gid_tbl_len; + immutable->core_cap_flags = get_core_cap_flags(ibdev); + if ((ll == IB_LINK_LAYER_INFINIBAND) || MLX5_CAP_GEN(dev->mdev, roce)) + immutable->max_mad_size = IB_MGMT_MAD_SIZE; + + return 0; +} + static void enable_dc_tracer(struct mlx5_ib_dev *dev) { struct device *device = dev->ib_dev.dma_device; @@ -2135,6 +2166,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) dev->ib_dev.attach_mcast = mlx5_ib_mcg_attach; dev->ib_dev.detach_mcast = mlx5_ib_mcg_detach; dev->ib_dev.process_mad = mlx5_ib_process_mad; + dev->ib_dev.get_port_immutable = mlx5_port_immutable; dev->ib_dev.alloc_fast_reg_mr = mlx5_ib_alloc_fast_reg_mr; dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list; dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list; diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c index 3e691dc206c4..cdbf1a7382fc 100644 --- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c +++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c @@ -1576,7 +1576,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah, int gid_type; if ((ll == IB_LINK_LAYER_ETHERNET) || (ah->ah_flags & IB_AH_GRH)) { - int len = dev->ib_dev.gid_tbl_len[port - 1]; + int len = dev->mdev->port_caps[port - 1].gid_table_len; if (ah->grh.sgid_index >= len) { printf("mlx5_ib: ERR: ""sgid_index (%u) too large. max is %d\n", ah->grh.sgid_index, len - 1); return -EINVAL; diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index 18b6dee4dad6..cb374a0e240e 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_mmccam.h" + #include "mmcbr_if.h" #define dprintf(x, arg...) @@ -1181,4 +1183,6 @@ static devclass_t dwmmc_devclass; DRIVER_MODULE(dwmmc, simplebus, dwmmc_driver, dwmmc_devclass, NULL, NULL); DRIVER_MODULE(dwmmc, ofwbus, dwmmc_driver, dwmmc_devclass, NULL, NULL); +#ifndef MMCCAM MMC_DECLARE_BRIDGE(dwmmc); +#endif diff --git a/sys/dev/mmc/mmcsd.c b/sys/dev/mmc/mmcsd.c index 3c626a99defd..70ffb77e796b 100644 --- a/sys/dev/mmc/mmcsd.c +++ b/sys/dev/mmc/mmcsd.c @@ -327,7 +327,7 @@ mmcsd_attach(device_t dev) (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) + (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) + (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24)) * - (sc->high_cap != 0 ? MMC_SECTOR_SIZE : 1); + (sc->high_cap == 0 ? MMC_SECTOR_SIZE : 1); } else if (bootverbose) device_printf(dev, "enhanced user data area spans entire device\n"); diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c index c5df73003715..1a75707cbe33 100644 --- a/sys/dev/mpr/mpr.c +++ b/sys/dev/mpr/mpr.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -105,6 +106,9 @@ static int mpr_reregister_events(struct mpr_softc *sc); static void mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm); static int mpr_get_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts); static int mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag); +static int mpr_debug_sysctl(SYSCTL_HANDLER_ARGS); +static void mpr_parse_debug(struct mpr_softc *sc, char *list); + SYSCTL_NODE(_hw, OID_AUTO, mpr, CTLFLAG_RD, 0, "MPR Driver Parameters"); MALLOC_DEFINE(M_MPR, "mpr", "mpr driver memory"); @@ -1591,7 +1595,7 @@ mpr_init_queues(struct mpr_softc *sc) void mpr_get_tunables(struct mpr_softc *sc) { - char tmpstr[80]; + char tmpstr[80], mpr_debug[80]; /* XXX default to some debugging for now */ sc->mpr_debug = MPR_INFO | MPR_FAULT; @@ -1611,7 +1615,9 @@ mpr_get_tunables(struct mpr_softc *sc) /* * Grab the global variables. */ - TUNABLE_INT_FETCH("hw.mpr.debug_level", &sc->mpr_debug); + bzero(mpr_debug, 80); + if (TUNABLE_STR_FETCH("hw.mpr.debug_level", mpr_debug, 80) != 0) + mpr_parse_debug(sc, mpr_debug); TUNABLE_INT_FETCH("hw.mpr.disable_msix", &sc->disable_msix); TUNABLE_INT_FETCH("hw.mpr.disable_msi", &sc->disable_msi); TUNABLE_INT_FETCH("hw.mpr.max_msix", &sc->max_msix); @@ -1628,7 +1634,9 @@ mpr_get_tunables(struct mpr_softc *sc) /* Grab the unit-instance variables */ snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level", device_get_unit(sc->mpr_dev)); - TUNABLE_INT_FETCH(tmpstr, &sc->mpr_debug); + bzero(mpr_debug, 80); + if (TUNABLE_STR_FETCH(tmpstr, mpr_debug, 80) != 0) + mpr_parse_debug(sc, mpr_debug); snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.disable_msix", device_get_unit(sc->mpr_dev)); @@ -1714,9 +1722,9 @@ mpr_setup_sysctl(struct mpr_softc *sc) sysctl_tree = sc->sysctl_tree; } - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "debug_level", CTLFLAG_RW, &sc->mpr_debug, 0, - "mpr debug level"); + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, + sc, 0, mpr_debug_sysctl, "A", "mpr debug level"); SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, "disable_msix", CTLFLAG_RD, &sc->disable_msix, 0, @@ -1809,6 +1817,132 @@ mpr_setup_sysctl(struct mpr_softc *sc) &sc->prp_page_alloc_fail, "PRP page allocation failures"); } +static struct mpr_debug_string { + char *name; + int flag; +} mpr_debug_strings[] = { + {"info", MPR_INFO}, + {"fault", MPR_FAULT}, + {"event", MPR_EVENT}, + {"log", MPR_LOG}, + {"recovery", MPR_RECOVERY}, + {"error", MPR_ERROR}, + {"init", MPR_INIT}, + {"xinfo", MPR_XINFO}, + {"user", MPR_USER}, + {"mapping", MPR_MAPPING}, + {"trace", MPR_TRACE} +}; + +enum mpr_debug_level_combiner { + COMB_NONE, + COMB_ADD, + COMB_SUB +}; + +static int +mpr_debug_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct mpr_softc *sc; + struct mpr_debug_string *string; + struct sbuf *sbuf; + char *buffer; + size_t sz; + int i, len, debug, error; + + sc = (struct mpr_softc *)arg1; + + error = sysctl_wire_old_buffer(req, 0); + if (error != 0) + return (error); + + sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req); + debug = sc->mpr_debug; + + sbuf_printf(sbuf, "%#x", debug); + + sz = sizeof(mpr_debug_strings) / sizeof(mpr_debug_strings[0]); + for (i = 0; i < sz; i++) { + string = &mpr_debug_strings[i]; + if (debug & string->flag) + sbuf_printf(sbuf, ",%s", string->name); + } + + error = sbuf_finish(sbuf); + sbuf_delete(sbuf); + + if (error || req->newptr == NULL) + return (error); + + len = req->newlen - req->newidx; + if (len == 0) + return (0); + + buffer = malloc(len, M_MPR, M_ZERO|M_WAITOK); + error = SYSCTL_IN(req, buffer, len); + + mpr_parse_debug(sc, buffer); + + free(buffer, M_MPR); + return (error); +} + +static void +mpr_parse_debug(struct mpr_softc *sc, char *list) +{ + struct mpr_debug_string *string; + enum mpr_debug_level_combiner op; + char *token, *endtoken; + size_t sz; + int flags, i; + + if (list == NULL || *list == '\0') + return; + + if (*list == '+') { + op = COMB_ADD; + list++; + } else if (*list == '-') { + op = COMB_SUB; + list++; + } else + op = COMB_NONE; + if (*list == '\0') + return; + + flags = 0; + sz = sizeof(mpr_debug_strings) / sizeof(mpr_debug_strings[0]); + while ((token = strsep(&list, ":,")) != NULL) { + + /* Handle integer flags */ + flags |= strtol(token, &endtoken, 0); + if (token != endtoken) + continue; + + /* Handle text flags */ + for (i = 0; i < sz; i++) { + string = &mpr_debug_strings[i]; + if (strcasecmp(token, string->name) == 0) { + flags |= string->flag; + break; + } + } + } + + switch (op) { + case COMB_NONE: + sc->mpr_debug = flags; + break; + case COMB_ADD: + sc->mpr_debug |= flags; + break; + case COMB_SUB: + sc->mpr_debug &= (~flags); + break; + } + return; +} + int mpr_attach(struct mpr_softc *sc) { diff --git a/sys/dev/mpr/mpr_mapping.c b/sys/dev/mpr/mpr_mapping.c index 8154bfd6c916..6d90c79efca8 100644 --- a/sys/dev/mpr/mpr_mapping.c +++ b/sys/dev/mpr/mpr_mapping.c @@ -2207,7 +2207,7 @@ mpr_mapping_free_memory(struct mpr_softc *sc) free(sc->dpm_pg0, M_MPR); } -static void +static bool _mapping_process_dpm_pg0(struct mpr_softc *sc) { u8 missing_cnt, enc_idx; @@ -2336,7 +2336,7 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc) "%s: Conflict in mapping table for " " enclosure %d\n", __func__, enc_idx); - break; + goto fail; } physical_id = dpm_entry->PhysicalIdentifier.High; @@ -2363,7 +2363,7 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc) mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " "Conflict in mapping table for device %d\n", __func__, map_idx); - break; + goto fail; } physical_id = dpm_entry->PhysicalIdentifier.High; mt_entry->physical_id = (physical_id << 32) | @@ -2375,6 +2375,18 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc) mt_entry->device_info = MPR_DEV_RESERVED; } } /*close the loop for DPM table */ + return (true); + +fail: + for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { + sc->dpm_entry_used[entry_num] = 0; + /* + * for IR firmware, it may be necessary to wipe out + * sc->mapping_table volumes tooi + */ + } + sc->num_enc_table_entries = 0; + return (false); } /* @@ -2614,9 +2626,11 @@ mpr_mapping_initialize(struct mpr_softc *sc) } } - if (sc->is_dpm_enable) - _mapping_process_dpm_pg0(sc); - else { + if (sc->is_dpm_enable) { + if (!_mapping_process_dpm_pg0(sc)) + sc->is_dpm_enable = 0; + } + if (! sc->is_dpm_enable) { mpr_dprint(sc, MPR_MAPPING, "%s: DPM processing is disabled. " "Device mappings will not persist across reboots or " "resets.\n", __func__); diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c index 9430db5925de..03f3143040c2 100644 --- a/sys/dev/mpr/mpr_pci.c +++ b/sys/dev/mpr/mpr_pci.c @@ -269,8 +269,8 @@ mpr_pci_alloc_interrupts(struct mpr_softc *sc) msgs = min(msgs, MPR_MSIX_MAX); msgs = min(msgs, 1); /* XXX */ if (msgs != 0) { - mpr_dprint(sc, MPR_INIT, "Attempting to allocate %d MSI-X " - "messages\n", msgs); + mpr_dprint(sc, MPR_INIT, "Attempting to allocate %d " + "MSI-X messages\n", msgs); error = mpr_alloc_msix(sc, msgs); } } @@ -279,8 +279,8 @@ mpr_pci_alloc_interrupts(struct mpr_softc *sc) mpr_dprint(sc, MPR_INIT, "Counted %d MSI messages\n", msgs); msgs = min(msgs, MPR_MSI_MAX); if (msgs != 0) { - mpr_dprint(sc, MPR_INIT, "Attempting to allocated %d MSI " - "messages\n", MPR_MSI_MAX); + mpr_dprint(sc, MPR_INIT, "Attempting to allocated %d " + "MSI messages\n", MPR_MSI_MAX); error = mpr_alloc_msi(sc, MPR_MSI_MAX); } } diff --git a/sys/dev/mpr/mpr_sas.h b/sys/dev/mpr/mpr_sas.h index c3e9bf6ddee3..c2ab1e40d236 100644 --- a/sys/dev/mpr/mpr_sas.h +++ b/sys/dev/mpr/mpr_sas.h @@ -70,9 +70,6 @@ struct mprsas_target { uint16_t parent_handle; uint64_t parent_sasaddr; uint32_t parent_devinfo; - struct sysctl_ctx_list sysctl_ctx; - struct sysctl_oid *sysctl_tree; - TAILQ_ENTRY(mprsas_target) sysctl_link; uint64_t issued; uint64_t completed; unsigned int outstanding; diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c index 34f5e4c4e19d..967effb79a37 100644 --- a/sys/dev/mpr/mpr_sas_lsi.c +++ b/sys/dev/mpr/mpr_sas_lsi.c @@ -781,9 +781,11 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate) sassc = sc->sassc; mprsas_startup_increment(sassc); - if ((mpr_config_get_sas_device_pg0(sc, &mpi_reply, &config_page, - MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { - printf("%s: error reading SAS device page0\n", __func__); + if (mpr_config_get_sas_device_pg0(sc, &mpi_reply, &config_page, + MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle) != 0) { + mpr_dprint(sc, MPR_INFO|MPR_MAPPING|MPR_FAULT, + "Error reading SAS device %#x page0, iocstatus= 0x%x\n", + handle, mpi_reply.IOCStatus); error = ENXIO; goto out; } @@ -795,12 +797,14 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate) Mpi2ConfigReply_t tmp_mpi_reply; Mpi2SasDevicePage0_t parent_config_page; - if ((mpr_config_get_sas_device_pg0(sc, &tmp_mpi_reply, - &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, - le16toh(config_page.ParentDevHandle)))) { + if (mpr_config_get_sas_device_pg0(sc, &tmp_mpi_reply, + &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, + le16toh(config_page.ParentDevHandle)) != 0) { mpr_dprint(sc, MPR_MAPPING|MPR_FAULT, - "%s: error reading SAS device %#x page0\n", - __func__, le16toh(config_page.ParentDevHandle)); + "Error reading parent SAS device %#x page0, " + "iocstatus= 0x%x\n", + le16toh(config_page.ParentDevHandle), + tmp_mpi_reply.IOCStatus); } else { parent_sas_address = parent_config_page.SASAddress.High; parent_sas_address = (parent_sas_address << 32) | @@ -1148,8 +1152,9 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, * If the request returns an error then we need to do a diag * reset */ - printf("%s: request for page completed with error %d", - __func__, error); + mpr_dprint(sc, MPR_INFO|MPR_FAULT|MPR_MAPPING, + "Request for SATA PASSTHROUGH page completed with error %d", + error); error = ENXIO; goto out; } @@ -1157,8 +1162,9 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, bcopy(reply, mpi_reply, sizeof(Mpi2SataPassthroughReply_t)); if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) { - printf("%s: error reading SATA PASSTHRU; iocstatus = 0x%x\n", - __func__, reply->IOCStatus); + mpr_dprint(sc, MPR_INFO|MPR_MAPPING|MPR_FAULT, + "Error reading device %#x SATA PASSTHRU; iocstatus= 0x%x\n", + handle, reply->IOCStatus); error = ENXIO; goto out; } diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index 206282750d9e..8bc461db3ab4 100644 --- a/sys/dev/mps/mps.c +++ b/sys/dev/mps/mps.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -102,6 +103,9 @@ static int mps_reregister_events(struct mps_softc *sc); static void mps_enqueue_request(struct mps_softc *sc, struct mps_command *cm); static int mps_get_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts); static int mps_wait_db_ack(struct mps_softc *sc, int timeout, int sleep_flag); +static int mps_debug_sysctl(SYSCTL_HANDLER_ARGS); +static void mps_parse_debug(struct mps_softc *sc, char *list); + SYSCTL_NODE(_hw, OID_AUTO, mps, CTLFLAG_RD, 0, "MPS Driver Parameters"); MALLOC_DEFINE(M_MPT2, "mps", "mpt2 driver memory"); @@ -1452,7 +1456,7 @@ mps_init_queues(struct mps_softc *sc) void mps_get_tunables(struct mps_softc *sc) { - char tmpstr[80]; + char tmpstr[80], mps_debug[80]; /* XXX default to some debugging for now */ sc->mps_debug = MPS_INFO|MPS_FAULT; @@ -1472,7 +1476,9 @@ mps_get_tunables(struct mps_softc *sc) /* * Grab the global variables. */ - TUNABLE_INT_FETCH("hw.mps.debug_level", &sc->mps_debug); + bzero(mps_debug, 80); + if (TUNABLE_STR_FETCH("hw.mps.debug_level", mps_debug, 80) != 0) + mps_parse_debug(sc, mps_debug); TUNABLE_INT_FETCH("hw.mps.disable_msix", &sc->disable_msix); TUNABLE_INT_FETCH("hw.mps.disable_msi", &sc->disable_msi); TUNABLE_INT_FETCH("hw.mps.max_msix", &sc->max_msix); @@ -1489,7 +1495,9 @@ mps_get_tunables(struct mps_softc *sc) /* Grab the unit-instance variables */ snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.debug_level", device_get_unit(sc->mps_dev)); - TUNABLE_INT_FETCH(tmpstr, &sc->mps_debug); + bzero(mps_debug, 80); + if (TUNABLE_STR_FETCH(tmpstr, mps_debug, 80) != 0) + mps_parse_debug(sc, mps_debug); snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.disable_msix", device_get_unit(sc->mps_dev)); @@ -1576,9 +1584,9 @@ mps_setup_sysctl(struct mps_softc *sc) sysctl_tree = sc->sysctl_tree; } - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "debug_level", CTLFLAG_RW, &sc->mps_debug, 0, - "mps debug level"); + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW |CTLFLAG_MPSAFE, + sc, 0, mps_debug_sysctl, "A", "mps debug level"); SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, "disable_msix", CTLFLAG_RD, &sc->disable_msix, 0, @@ -1671,6 +1679,133 @@ mps_setup_sysctl(struct mps_softc *sc) "Use the phy number for enumeration"); } +static struct mps_debug_string { + char *name; + int flag; +} mps_debug_strings[] = { + {"info", MPS_INFO}, + {"fault", MPS_FAULT}, + {"event", MPS_EVENT}, + {"log", MPS_LOG}, + {"recovery", MPS_RECOVERY}, + {"error", MPS_ERROR}, + {"init", MPS_INIT}, + {"xinfo", MPS_XINFO}, + {"user", MPS_USER}, + {"mapping", MPS_MAPPING}, + {"trace", MPS_TRACE} +}; + +enum mps_debug_level_combiner { + COMB_NONE, + COMB_ADD, + COMB_SUB +}; + +static int +mps_debug_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct mps_softc *sc; + struct mps_debug_string *string; + struct sbuf *sbuf; + char *buffer; + size_t sz; + int i, len, debug, error; + + sc = (struct mps_softc *)arg1; + + error = sysctl_wire_old_buffer(req, 0); + if (error != 0) + return (error); + + sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req); + debug = sc->mps_debug; + + sbuf_printf(sbuf, "%#x", debug); + + sz = sizeof(mps_debug_strings) / sizeof(mps_debug_strings[0]); + for (i = 0; i < sz; i++) { + string = &mps_debug_strings[i]; + if (debug & string->flag) + sbuf_printf(sbuf, ",%s", string->name); + } + + error = sbuf_finish(sbuf); + sbuf_delete(sbuf); + + if (error || req->newptr == NULL) + return (error); + + len = req->newlen - req->newidx; + if (len == 0) + return (0); + + buffer = malloc(len, M_MPT2, M_ZERO|M_WAITOK); + error = SYSCTL_IN(req, buffer, len); + + mps_parse_debug(sc, buffer); + + free(buffer, M_MPT2); + return (error); +} + +static void +mps_parse_debug(struct mps_softc *sc, char *list) +{ + struct mps_debug_string *string; + enum mps_debug_level_combiner op; + char *token, *endtoken; + size_t sz; + int flags, i; + + if (list == NULL || *list == '\0') + return; + + if (*list == '+') { + op = COMB_ADD; + list++; + } else if (*list == '-') { + op = COMB_SUB; + list++; + } else + op = COMB_NONE; + if (*list == '\0') + return; + + flags = 0; + sz = sizeof(mps_debug_strings) / sizeof(mps_debug_strings[0]); + while ((token = strsep(&list, ":,")) != NULL) { + + /* Handle integer flags */ + flags |= strtol(token, &endtoken, 0); + if (token != endtoken) + continue; + + /* Handle text flags */ + for (i = 0; i < sz; i++) { + string = &mps_debug_strings[i]; + if (strcasecmp(token, string->name) == 0) { + flags |= string->flag; + break; + } + } + } + + switch (op) { + case COMB_NONE: + sc->mps_debug = flags; + break; + case COMB_ADD: + sc->mps_debug |= flags; + break; + case COMB_SUB: + sc->mps_debug &= (~flags); + break; + } + + return; +} + int mps_attach(struct mps_softc *sc) { diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c index 8dcf246a7359..2e00241d329e 100644 --- a/sys/dev/mps/mps_pci.c +++ b/sys/dev/mps/mps_pci.c @@ -254,8 +254,8 @@ mps_pci_alloc_interrupts(struct mps_softc *sc) msgs = min(msgs, MPS_MSIX_MAX); msgs = min(msgs, 1); /* XXX */ if (msgs != 0) { - mps_dprint(sc, MPS_INIT, "Attempting to allocate %d MSI-X " - "messages\n", msgs); + mps_dprint(sc, MPS_INIT, "Attempting to allocate %d " + "MSI-X messages\n", msgs); error = mps_alloc_msix(sc, msgs); } } @@ -264,8 +264,8 @@ mps_pci_alloc_interrupts(struct mps_softc *sc) mps_dprint(sc, MPS_INIT, "Counted %d MSI messages\n", msgs); msgs = min(msgs, MPS_MSI_MAX); if (msgs != 0) { - mps_dprint(sc, MPS_INIT, "Attempting to allocate %d MSI " - "messages\n", MPS_MSI_MAX); + mps_dprint(sc, MPS_INIT, "Attempting to allocate %d " + "MSI messages\n", MPS_MSI_MAX); error = mps_alloc_msi(sc, MPS_MSI_MAX); } } diff --git a/sys/dev/mps/mps_sas.h b/sys/dev/mps/mps_sas.h index d03258d9a7c9..ce7593d1b625 100644 --- a/sys/dev/mps/mps_sas.h +++ b/sys/dev/mps/mps_sas.h @@ -67,9 +67,6 @@ struct mpssas_target { uint16_t parent_handle; uint64_t parent_sasaddr; uint32_t parent_devinfo; - struct sysctl_ctx_list sysctl_ctx; - struct sysctl_oid *sysctl_tree; - TAILQ_ENTRY(mpssas_target) sysctl_link; uint64_t issued; uint64_t completed; unsigned int outstanding; diff --git a/sys/dev/mps/mps_sas_lsi.c b/sys/dev/mps/mps_sas_lsi.c index 5ab50f0de52f..38989e8e0713 100644 --- a/sys/dev/mps/mps_sas_lsi.c +++ b/sys/dev/mps/mps_sas_lsi.c @@ -628,9 +628,11 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){ sassc = sc->sassc; mpssas_startup_increment(sassc); - if ((mps_config_get_sas_device_pg0(sc, &mpi_reply, &config_page, - MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { - printf("%s: error reading SAS device page0\n", __func__); + if (mps_config_get_sas_device_pg0(sc, &mpi_reply, &config_page, + MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle) != 0) { + mps_dprint(sc, MPS_INFO|MPS_MAPPING|MPS_FAULT, + "Error reading SAS device %#x page0, iocstatus= 0x%x\n", + handle, mpi_reply.IOCStatus); error = ENXIO; goto out; } @@ -642,12 +644,14 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){ Mpi2ConfigReply_t tmp_mpi_reply; Mpi2SasDevicePage0_t parent_config_page; - if ((mps_config_get_sas_device_pg0(sc, &tmp_mpi_reply, - &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, - le16toh(config_page.ParentDevHandle)))) { + if (mps_config_get_sas_device_pg0(sc, &tmp_mpi_reply, + &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, + le16toh(config_page.ParentDevHandle)) != 0) { mps_dprint(sc, MPS_MAPPING|MPS_FAULT, - "%s: error reading SAS device %#x page0\n", - __func__, le16toh(config_page.ParentDevHandle)); + "Error reading parent SAS device %#x page0, " + "iocstatus= 0x%x\n", + le16toh(config_page.ParentDevHandle), + tmp_mpi_reply.IOCStatus); } else { parent_sas_address = parent_config_page.SASAddress.High; parent_sas_address = (parent_sas_address << 32) | @@ -973,8 +977,9 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, * If the request returns an error then we need to do a diag * reset */ - printf("%s: request for page completed with error %d", - __func__, error); + mps_dprint(sc, MPS_INFO|MPS_FAULT|MPS_MAPPING, + "Request for SATA PASSTHROUGH page completed with error %d", + error); error = ENXIO; goto out; } @@ -982,8 +987,9 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, bcopy(reply, mpi_reply, sizeof(Mpi2SataPassthroughReply_t)); if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) { - printf("%s: error reading SATA PASSTHRU; iocstatus = 0x%x\n", - __func__, reply->IOCStatus); + mps_dprint(sc, MPS_INFO|MPS_MAPPING|MPS_FAULT, + "Error reading device %#x SATA PASSTHRU; iocstatus= 0x%x\n", + handle, reply->IOCStatus); error = ENXIO; goto out; } diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 79172aaf7bd7..861cbff950f3 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -2522,12 +2522,12 @@ mwl_rxbuf_init(struct mwl_softc *sc, struct mwl_rxbuf *bf) } static void -mwl_ext_free(struct mbuf *m, void *data, void *arg) +mwl_ext_free(struct mbuf *m) { - struct mwl_softc *sc = arg; + struct mwl_softc *sc = m->m_ext.ext_arg1; /* XXX bounds check data */ - mwl_putrxdma(sc, data); + mwl_putrxdma(sc, m->m_ext.ext_buf); /* * If we were previously blocked by a lack of rx dma buffers * check if we now have enough to restart rx interrupt handling. @@ -2746,8 +2746,8 @@ mwl_rx_proc(void *arg, int npending) * descriptor using the replacement dma * buffer we just installed above. */ - MEXTADD(m, data, MWL_AGGR_SIZE, mwl_ext_free, - data, sc, 0, EXT_NET_DRV); + m_extadd(m, data, MWL_AGGR_SIZE, mwl_ext_free, sc, NULL, 0, + EXT_NET_DRV); m->m_data += off - hdrlen; m->m_pkthdr.len = m->m_len = pktlen; /* NB: dma buffer assumed read-only */ diff --git a/sys/dev/neta/if_mvneta.c b/sys/dev/neta/if_mvneta.c index 010cdd5bce7e..ae3e958b29ec 100644 --- a/sys/dev/neta/if_mvneta.c +++ b/sys/dev/neta/if_mvneta.c @@ -97,16 +97,6 @@ __FBSDID("$FreeBSD$"); #define A3700_TCLK_250MHZ 250000000 -STATIC uint32_t -mvneta_get_clk() -{ -#if defined(__aarch64__) - return (A3700_TCLK_250MHZ); -#else - return (get_tclk()); -#endif -} - /* Device Register Initialization */ STATIC int mvneta_initreg(struct ifnet *); @@ -213,6 +203,9 @@ STATIC int mvneta_detach(device_t); STATIC int mvneta_miibus_readreg(device_t, int, int); STATIC int mvneta_miibus_writereg(device_t, int, int, int); +/* Clock */ +STATIC uint32_t mvneta_get_clk(void); + static device_method_t mvneta_methods[] = { /* Device interface */ DEVMETHOD(device_detach, mvneta_detach), @@ -354,6 +347,16 @@ static struct { { mvneta_rxtxth_intr, "MVNETA aggregated interrupt" }, }; +STATIC uint32_t +mvneta_get_clk() +{ +#if defined(__aarch64__) + return (A3700_TCLK_250MHZ); +#else + return (get_tclk()); +#endif +} + static int mvneta_set_mac_address(struct mvneta_softc *sc, uint8_t *addr) { @@ -831,11 +834,9 @@ STATIC int mvneta_detach(device_t dev) { struct mvneta_softc *sc; - struct ifnet *ifp; int q; sc = device_get_softc(dev); - ifp = sc->ifp; mvneta_stop(sc); /* Detach network interface */ @@ -3410,6 +3411,7 @@ sysctl_mvneta_init(struct mvneta_softc *sc) }; #undef MVNETA_SYSCTL_NAME +#ifndef NO_SYSCTL_DESCR #define MVNETA_SYSCTL_DESCR(num) "configuration parameters for queue " # num static const char *sysctl_queue_descrs[] = { MVNETA_SYSCTL_DESCR(0), MVNETA_SYSCTL_DESCR(1), @@ -3418,6 +3420,7 @@ sysctl_mvneta_init(struct mvneta_softc *sc) MVNETA_SYSCTL_DESCR(6), MVNETA_SYSCTL_DESCR(7), }; #undef MVNETA_SYSCTL_DESCR +#endif ctx = device_get_sysctl_ctx(sc->dev); @@ -3441,15 +3444,14 @@ sysctl_mvneta_init(struct mvneta_softc *sc) */ /* dev.mvneta.[unit].mib. */ for (i = 0; i < MVNETA_PORTMIB_NOCOUNTER; i++) { - const char *name = mvneta_mib_list[i].sysctl_name; - const char *desc = mvneta_mib_list[i].desc; struct mvneta_sysctl_mib *mib_arg = &sc->sysctl_mib[i]; mib_arg->sc = sc; mib_arg->index = i; - SYSCTL_ADD_PROC(ctx, mchildren, OID_AUTO, name, + SYSCTL_ADD_PROC(ctx, mchildren, OID_AUTO, + mvneta_mib_list[i].sysctl_name, CTLTYPE_U64|CTLFLAG_RD, (void *)mib_arg, 0, - sysctl_read_mib, "I", desc); + sysctl_read_mib, "I", mvneta_mib_list[i].desc); } SYSCTL_ADD_UQUAD(ctx, mchildren, OID_AUTO, "rx_discard", CTLFLAG_RD, &sc->counter_pdfc, "Port Rx Discard Frame Counter"); diff --git a/sys/dev/netmap/netmap_generic.c b/sys/dev/netmap/netmap_generic.c index 30f83a920825..939fed5b573b 100644 --- a/sys/dev/netmap/netmap_generic.c +++ b/sys/dev/netmap/netmap_generic.c @@ -166,7 +166,7 @@ nm_os_get_mbuf(struct ifnet *ifp, int len) * has a KASSERT(), checking that the mbuf dtor function is not NULL. */ -static void void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { } +static void void_mbuf_dtor(struct mbuf *m) { } #define SET_MBUF_DESTRUCTOR(m, fn) do { \ (m)->m_ext.ext_free = (fn != NULL) ? \ @@ -624,7 +624,7 @@ generic_mbuf_destructor(struct mbuf *m) * txsync. */ netmap_generic_irq(na, r, NULL); #ifdef __FreeBSD__ - void_mbuf_dtor(m, NULL, NULL); + void_mbuf_dtor(m); #endif } diff --git a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c index ce15d1034528..cac6f9b60a4e 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c @@ -495,8 +495,6 @@ static struct ntb_hw_info pci_ids[] = { { 0x6F0D8086, "BDX Xeon E5 V4 Non-Transparent Bridge B2B", NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | NTB_SB01BASE_LOCKUP }, - - { 0x00000000, NULL, NTB_ATOM, 0 } }; static const struct ntb_reg atom_reg = { @@ -1390,12 +1388,11 @@ intel_ntb_get_msix_info(struct ntb_softc *ntb) static struct ntb_hw_info * intel_ntb_get_device_info(uint32_t device_id) { - struct ntb_hw_info *ep = pci_ids; + struct ntb_hw_info *ep; - while (ep->device_id) { + for (ep = pci_ids; ep < &pci_ids[nitems(pci_ids)]; ep++) { if (ep->device_id == device_id) return (ep); - ++ep; } return (NULL); } @@ -3122,3 +3119,5 @@ static DEFINE_CLASS_0(ntb_hw, ntb_intel_driver, ntb_intel_methods, DRIVER_MODULE(ntb_hw_intel, pci, ntb_intel_driver, ntb_hw_devclass, NULL, NULL); MODULE_DEPEND(ntb_hw_intel, ntb, 1, 1, 1); MODULE_VERSION(ntb_hw_intel, 1); +MODULE_PNP_INFO("W32:vendor/device;D:human", pci, ntb_hw_intel, pci_ids, + sizeof(pci_ids[0]), nitems(pci_ids)); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw_plx.c b/sys/dev/ntb/ntb_hw/ntb_hw_plx.c index ced58818ff99..98ca60b651f1 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw_plx.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw_plx.c @@ -80,6 +80,7 @@ struct ntb_plx_softc { u_int ntx; /* NTx number within chip. */ u_int link; /* Link v/s Virtual side. */ u_int port; /* Port number within chip. */ + u_int alut; /* A-LUT is enabled for NTx */ int int_rid; struct resource *int_res; @@ -197,8 +198,12 @@ ntb_plx_init(device_t dev) } } - /* Enable Link Interface LUT entry 0 for 0:0.0. */ - PNTX_WRITE(sc, 0xdb4, 1); + /* Make sure Virtual to Link A-LUT is disabled. */ + if (sc->alut) + PNTX_WRITE(sc, 0xc94, 0); + + /* Enable Link Interface LUT entries 0/1 for peer 0/1. */ + PNTX_WRITE(sc, 0xdb4, 0x00090001); } /* @@ -329,6 +334,12 @@ ntb_plx_attach(device_t dev) val = bus_read_4(sc->conf_res, 0x360); sc->port = (val >> ((sc->ntx == 0) ? 8 : 16)) & 0x1f; + /* Detect A-LUT enable and size. */ + val >>= 30; + sc->alut = (val == 0x3) ? 1 : ((val & (1 << sc->ntx)) ? 2 : 0); + if (sc->alut) + device_printf(dev, "%u A-LUT entries\n", 128 * sc->alut); + /* Find configured memory windows at BAR2-5. */ sc->mw_count = 0; for (i = 2; i <= 5; i++) { @@ -561,22 +572,31 @@ ntb_plx_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base, /* * Remote to local memory window translation address alignment. - * XXX: In B2B mode we can change window size (and so alignmet) - * live, but there is no way to report it, so report safe value. + * Translation address has to be aligned to the BAR size, but A-LUT + * entries re-map addresses can be aligned to 1/128 or 1/256 of it. + * XXX: In B2B mode we can change BAR size (and so alignmet) live, + * but there is no way to report it here, so report safe value. */ - if (align != NULL) - *align = mw->mw_size - off; + if (align != NULL) { + if (sc->alut && mw->mw_bar == 2) + *align = (mw->mw_size - off) / 128 / sc->alut; + else + *align = mw->mw_size - off; + } /* * Remote to local memory window size alignment. - * XXX: The chip has no limit registers. In B2B case size must be - * power of 2 (since we can reprogram BAR size), but there is no way - * to report it, so report 1MB -- minimal BAR size. In non-B2B case - * there is no control at all, so report the precofigured BAR size. + * The chip has no limit registers, but A-LUT, when available, allows + * access control with granularity of 1/128 or 1/256 of the BAR size. + * XXX: In B2B case we can change BAR size live, but there is no way + * to report it, so report half of the BAR size, that should be safe. + * In non-B2B case there is no control at all, so report the BAR size. */ if (align_size != NULL) { - if (sc->b2b_mw >= 0) - *align_size = 1024 * 1024; + if (sc->alut && mw->mw_bar == 2) + *align_size = (mw->mw_size - off) / 128 / sc->alut; + else if (sc->b2b_mw >= 0) + *align_size = (mw->mw_size - off) / 2; else *align_size = mw->mw_size - off; } @@ -593,8 +613,9 @@ ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx) { struct ntb_plx_softc *sc = device_get_softc(dev); struct ntb_plx_mw_info *mw; - uint64_t addr, off, size, val64; + uint64_t addr, eaddr, off, size, bsize, esize, val64; uint32_t val; + int i; mw = &sc->mw_info[mw_idx]; addr = mw->mw_xlat_addr; @@ -615,29 +636,35 @@ ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx) if (size > 0) { /* Round BAR size to next power of 2 or at least 1MB. */ - if (!powerof2(size)) - size = 1LL << flsll(size); - if (size < 1024 * 1024) - size = 1024 * 1024; + bsize = size; + if (!powerof2(bsize)) + bsize = 1LL << flsll(bsize); + if (bsize < 1024 * 1024) + bsize = 1024 * 1024; - /* Hardware requires addr aligned to BAR size. */ - if ((addr & (size - 1)) != 0) + /* A-LUT has 128 or 256 times better granularity. */ + esize = bsize; + if (sc->alut && mw->mw_bar == 2) + esize /= 128 * sc->alut; + + /* addr should be aligned to BAR or A-LUT element size. */ + if ((addr & (esize - 1)) != 0) return (EINVAL); - } + } else + esize = bsize = 0; if (mw->mw_64bit) { if (sc->b2b_mw >= 0) { /* Set Link Interface BAR size and enable/disable it. */ val64 = 0; - if (size > 0) - val64 = (~(size - 1) & ~0xfffff); - val64 |= 0x4; + if (bsize > 0) + val64 = (~(bsize - 1) & ~0xfffff); + val64 |= 0xc; PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val64); PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4 + 4, val64 >> 32); /* Set Link Interface BAR address. */ val64 = 0x2000000000000000 * mw->mw_bar + off; - val64 |= 0x4; PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar), val64); PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar) + 4, val64 >> 32); } @@ -649,14 +676,14 @@ ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx) /* Make sure we fit into 32-bit address space. */ if ((addr & UINT32_MAX) != addr) return (ERANGE); - if (((addr + size) & UINT32_MAX) != (addr + size)) + if (((addr + bsize) & UINT32_MAX) != (addr + bsize)) return (ERANGE); if (sc->b2b_mw >= 0) { /* Set Link Interface BAR size and enable/disable it. */ val = 0; - if (size > 0) - val = (~(size - 1) & ~0xfffff); + if (bsize > 0) + val = (~(bsize - 1) & ~0xfffff); PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val); /* Set Link Interface BAR address. */ @@ -667,6 +694,27 @@ ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx) /* Set Virtual Interface BARs address translation */ PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, addr); } + + /* Configure and enable Link to Virtual A-LUT if we need it. */ + if (sc->alut && mw->mw_bar == 2 && + ((addr & (bsize - 1)) != 0 || size != bsize)) { + eaddr = addr; + for (i = 0; i < 128 * sc->alut; i++) { + val = sc->link ? 0 : 1; + if (sc->alut == 1) + val += 2 * sc->ntx; + val *= 0x1000 * sc->alut; + val += 0x38000 + i * 4 + (i >= 128 ? 0x0e00 : 0); + bus_write_4(sc->conf_res, val, eaddr); + bus_write_4(sc->conf_res, val + 0x400, eaddr >> 32); + bus_write_4(sc->conf_res, val + 0x800, + (eaddr < addr + size) ? 0x3 : 0); + eaddr += esize; + } + NTX_WRITE(sc, 0xc94, 0x10000000); + } else if (sc->alut && mw->mw_bar == 2) + NTX_WRITE(sc, 0xc94, 0); + return (0); } diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c index d946da6208ff..22654a251de4 100644 --- a/sys/dev/null/null.c +++ b/sys/dev/null/null.c @@ -114,7 +114,7 @@ null_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, case DIOCSKERNELDUMP_FREEBSD11: #endif case DIOCSKERNELDUMP: - error = set_dumper(NULL, NULL, td, 0, NULL, 0, NULL); + error = set_dumper(NULL, NULL, td, 0, 0, NULL, 0, NULL); break; case FIONBIO: break; diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h index d4fc131ef643..aff4fbc66a61 100644 --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -1068,7 +1068,12 @@ uint32_t nvme_ns_get_stripesize(struct nvme_namespace *ns); int nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp, nvme_cb_fn_t cb_fn); -/* Command building helper functions -- shared with CAM */ +/* + * Command building helper functions -- shared with CAM + * These functions assume allocator zeros out cmd structure + * CAM's xpt_get_ccb and the request allocator for nvme both + * do zero'd allocations. + */ static inline void nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid) { @@ -1086,9 +1091,6 @@ void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid, cmd->cdw10 = lba & 0xffffffffu; cmd->cdw11 = lba >> 32; cmd->cdw12 = count-1; - cmd->cdw13 = 0; - cmd->cdw14 = 0; - cmd->cdw15 = 0; } static inline diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 95fa39fce5f4..b036eb64bf9f 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -151,7 +151,7 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr) * not a hard limit and will need to be revisitted when the upper layers * of the storage system grows multi-queue support. */ - ctrlr->max_hw_pend_io = num_trackers * ctrlr->num_io_queues / 4; + ctrlr->max_hw_pend_io = num_trackers * ctrlr->num_io_queues * 3 / 4; /* * This was calculated previously when setting up interrupts, but @@ -815,18 +815,33 @@ nvme_ctrlr_reset_task(void *arg, int pending) atomic_cmpset_32(&ctrlr->is_resetting, 1, 0); } +/* + * Poll all the queues enabled on the device for completion. + */ +void +nvme_ctrlr_poll(struct nvme_controller *ctrlr) +{ + int i; + + nvme_qpair_process_completions(&ctrlr->adminq); + + for (i = 0; i < ctrlr->num_io_queues; i++) + if (ctrlr->ioq && ctrlr->ioq[i].cpl) + nvme_qpair_process_completions(&ctrlr->ioq[i]); +} + +/* + * Poll the single-vector intertrupt case: num_io_queues will be 1 and + * there's only a single vector. While we're polling, we mask further + * interrupts in the controller. + */ void nvme_ctrlr_intx_handler(void *arg) { struct nvme_controller *ctrlr = arg; nvme_mmio_write_4(ctrlr, intms, 1); - - nvme_qpair_process_completions(&ctrlr->adminq); - - if (ctrlr->ioq && ctrlr->ioq[0].cpl) - nvme_qpair_process_completions(&ctrlr->ioq[0]); - + nvme_ctrlr_poll(ctrlr); nvme_mmio_write_4(ctrlr, intmc, 1); } diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index d37af2932252..6f3df62155f7 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -542,5 +542,6 @@ void nvme_notify_fail_consumers(struct nvme_controller *ctrlr); void nvme_notify_new_controller(struct nvme_controller *ctrlr); void nvme_ctrlr_intx_handler(void *arg); +void nvme_ctrlr_poll(struct nvme_controller *ctrlr); #endif /* __NVME_PRIVATE_H__ */ diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index 3bab7540fc0a..94169055919c 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -73,11 +73,13 @@ nvme_sim_nvmeio_done(void *ccb_arg, const struct nvme_completion *cpl) * it means. Make our best guess, though for the status code. */ memcpy(&ccb->nvmeio.cpl, cpl, sizeof(*cpl)); - if (nvme_completion_is_error(cpl)) + if (nvme_completion_is_error(cpl)) { ccb->ccb_h.status = CAM_REQ_CMP_ERR; - else + xpt_done(ccb); + } else { ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); + xpt_done_direct(ccb); + } } static void @@ -244,7 +246,7 @@ static void nvme_sim_poll(struct cam_sim *sim) { - nvme_ctrlr_intx_handler(sim2ctrlr(sim)); + nvme_ctrlr_poll(sim2ctrlr(sim)); } static void * diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h index 605869695181..521c59059184 100644 --- a/sys/dev/ofw/ofw_bus_subr.h +++ b/sys/dev/ofw/ofw_bus_subr.h @@ -63,7 +63,7 @@ struct intr_map_data_fdt { }; #endif -#define SIMPLEBUS_PNP_DESCR "Z:compat;P:private;" +#define SIMPLEBUS_PNP_DESCR "Z:compat;P:#;" #define SIMPLEBUS_PNP_INFO(t) \ MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h index 3bc27e352105..e29c51b0eaee 100644 --- a/sys/dev/pccard/pccardvar.h +++ b/sys/dev/pccard/pccardvar.h @@ -91,7 +91,7 @@ struct pccard_product { * are informative, according to the standard, but I have a dim memory of using these * strings to match things, though I can't find the example right now. */ -#define PCCARD_PNP_DESCR "D:human;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;" +#define PCCARD_PNP_DESCR "D:#;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;" #define PCCARD_PNP_INFO(t) \ MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); \ diff --git a/sys/dev/pccbb/pccbb_isa.c b/sys/dev/pccbb/pccbb_isa.c index d2a0d03fc933..df936c6738c6 100644 --- a/sys/dev/pccbb/pccbb_isa.c +++ b/sys/dev/pccbb/pccbb_isa.c @@ -75,11 +75,11 @@ static SYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters"); static int isa_intr_mask = EXCA_INT_MASK_ALLOWED; SYSCTL_INT(_hw_pcic, OID_AUTO, intr_mask, CTLFLAG_RDTUN, &isa_intr_mask, 0, - "Mask of allowable interrupts for this laptop. The default is generally\n\ -correct, but some laptops do not route all the IRQ pins to the bridge to\n\ -save wires. Sometimes you need a more restrictive mask because some of the\n\ -hardware in your laptop may not have a driver so its IRQ might not be\n\ -allocated."); + "Mask of allowable interrupts for this laptop. The default is generally" + " correct, but some laptops do not route all the IRQ pins to the bridge to" + " save wires. Sometimes you need a more restrictive mask because some of" + " the hardware in your laptop may not have a driver so its IRQ might not be" + " allocated."); /* * CL-PD6722's VSENSE method @@ -90,13 +90,13 @@ allocated."); int pcic_pd6722_vsense = 1; SYSCTL_INT(_hw_pcic, OID_AUTO, pd6722_vsense, CTLFLAG_RDTUN, &pcic_pd6722_vsense, 1, - "Select CL-PD6722's VSENSE method. VSENSE is used to determine the\n\ -volatage of inserted cards. The CL-PD6722 has two methods to determine the\n\ -voltage of the card. 0 means assume a 5.0V card and do not check. 1 means\n\ -use the same method that the CL-PD6710 uses (default). 2 means use the\n\ -same method as the CL-PD6729. 2 is documented in the datasheet as being\n\ -the correct way, but 1 seems to give better results on more laptops."); - + "Select CL-PD6722's VSENSE method. VSENSE is used to determine the" + " voltage of inserted cards. The CL-PD6722 has two methods to determine" + " the voltage of the card. 0 means assume a 5.0V card and do not check. 1" + " means use the same method that the CL-PD6710 uses (default). 2 means use" + " the same method as the CL-PD6729. 2 is documented in the datasheet as" + " being the correct way, but 1 seems to give better results on more" + " laptops."); /***************************************************************************** * End of configurable parameters. *****************************************************************************/ diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index e240ef87d0f2..eb26b3627e69 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -321,9 +321,9 @@ SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD, 0, "PCI bus tuning parameters"); static int pci_enable_io_modes = 1; SYSCTL_INT(_hw_pci, OID_AUTO, enable_io_modes, CTLFLAG_RWTUN, &pci_enable_io_modes, 1, - "Enable I/O and memory bits in the config register. Some BIOSes do not\n\ -enable these bits correctly. We'd like to do this all the time, but there\n\ -are some peripherals that this causes problems with."); + "Enable I/O and memory bits in the config register. Some BIOSes do not" + " enable these bits correctly. We'd like to do this all the time, but" + " there are some peripherals that this causes problems with."); static int pci_do_realloc_bars = 0; SYSCTL_INT(_hw_pci, OID_AUTO, realloc_bars, CTLFLAG_RWTUN, @@ -334,10 +334,10 @@ SYSCTL_INT(_hw_pci, OID_AUTO, realloc_bars, CTLFLAG_RWTUN, static int pci_do_power_nodriver = 0; SYSCTL_INT(_hw_pci, OID_AUTO, do_power_nodriver, CTLFLAG_RWTUN, &pci_do_power_nodriver, 0, - "Place a function into D3 state when no driver attaches to it. 0 means\n\ -disable. 1 means conservatively place devices into D3 state. 2 means\n\ -aggressively place devices into D3 state. 3 means put absolutely everything\n\ -in D3 state."); + "Place a function into D3 state when no driver attaches to it. 0 means" + " disable. 1 means conservatively place devices into D3 state. 2 means" + " aggressively place devices into D3 state. 3 means put absolutely" + " everything in D3 state."); int pci_do_power_resume = 1; SYSCTL_INT(_hw_pci, OID_AUTO, do_power_resume, CTLFLAG_RWTUN, @@ -372,9 +372,10 @@ static int pci_usb_takeover = 1; static int pci_usb_takeover = 0; #endif SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN, - &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\ -Disable this if you depend on BIOS emulation of USB devices, that is\n\ -you use USB devices (like keyboard or mouse) but do not load USB drivers"); + &pci_usb_takeover, 1, + "Enable early takeover of USB controllers. Disable this if you depend on" + " BIOS emulation of USB devices, that is you use USB devices (like" + " keyboard or mouse) but do not load USB drivers"); static int pci_clear_bars; SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0, diff --git a/sys/dev/pms/freebsd/driver/common/lxencrypt.c b/sys/dev/pms/freebsd/driver/common/lxencrypt.c index 92e4ce1aae34..c53c52fb2378 100644 --- a/sys/dev/pms/freebsd/driver/common/lxencrypt.c +++ b/sys/dev/pms/freebsd/driver/common/lxencrypt.c @@ -41,8 +41,8 @@ #include -static atomic_t ioerr_queue_count; #ifdef ENCRYPT_ENHANCE +static atomic_t ioerr_queue_count; /****************************************************************************** careful_write(): diff --git a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c index ac96eada9752..ef7dc19c05ce 100644 --- a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c +++ b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c @@ -533,9 +533,6 @@ static int agtiapi_CharIoctl( struct cdev *dev, tiIOCTLPayload_t *pIoctlPayload; struct agtiapi_softc *pCard; pCard=dev->si_drv1; - void *param1 = NULL; - void *param2 = NULL; - void *param3 = NULL; U32 status = 0; U32 retValue; int err = 0; @@ -649,8 +646,8 @@ static int agtiapi_CharIoctl( struct cdev *dev, status = tiCOMMgntIOCTL( &pCard->tiRoot, pIoctlPayload, pCard, - param2, - param3 ); + NULL, + NULL ); if (status == IOCTL_CALL_PENDING) { ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL); @@ -2069,17 +2066,14 @@ int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb) /* get a ccb */ if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL) { - ag_device_t *targ; AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n"); if (pmcsc != NULL) { + ag_device_t *targ; TID = INDEX(pmcsc, TID); targ = &pmcsc->pDevList[TID]; - } - if (targ != NULL) - { agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth); - } + } ccb->ccb_h.status &= ~CAM_SIM_QUEUED; ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_REQUEUE_REQ; @@ -3089,7 +3083,6 @@ STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc ) ccb_t *pccb; int TID; ag_device_t *targ; - struct ccb_relsim crs; AGTIAPI_IO( "agtiapi_StartIO: start\n" ); @@ -4345,18 +4338,6 @@ int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd ) } -int agtiapi_eh_DeviceReset( struct agtiapi_softc *pmcsc, union ccb *cmnd ) -{ - AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n", - cmnd ); - - if( cmnd == NULL ) - { - printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" ); - return tiInvalidHandle; - } - return agtiapi_DoSoftReset( pmcsc ); -} /****************************************************************************** agtiapi_QueueCCB() @@ -5661,8 +5642,7 @@ agtiapi_scan() static void agtiapi_scan(struct agtiapi_softc *pmcsc) { union ccb *ccb; - int bus, tid, lun, card_no; - static int num=0; + int bus, tid, lun; AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo); diff --git a/sys/dev/pms/freebsd/driver/ini/src/osapi.c b/sys/dev/pms/freebsd/driver/ini/src/osapi.c index 2faaff8126f0..a70ada46f20a 100644 --- a/sys/dev/pms/freebsd/driver/ini/src/osapi.c +++ b/sys/dev/pms/freebsd/driver/ini/src/osapi.c @@ -764,7 +764,6 @@ ostiSetDeviceQueueDepth( tiRoot_t *tiRoot, ) { bit32 retVal = 0; - struct agtiapi_softc *pCard = TIROOT_TO_CARD(tiRoot); ccb_t *pccb = (ccb_t *) tiIORequest->osData; tiDeviceHandle_t *tiDeviceHandle = pccb->devHandle; ag_device_t *pDevice = (ag_device_t *)tiDeviceHandle->osData; diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c index 4186aadb5f74..08967344021f 100644 --- a/sys/dev/ppc/ppc.c +++ b/sys/dev/ppc/ppc.c @@ -1720,7 +1720,8 @@ ppc_probe(device_t dev, int rid) if (bootverbose) device_printf(dev, "using normal I/O port range\n"); } else { - device_printf(dev, "cannot reserve I/O port range\n"); + if (bootverbose) + device_printf(dev, "cannot reserve I/O port range\n"); goto error; } } diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c index 4ae97eccc45a..83c9bdb9a1a4 100644 --- a/sys/dev/psci/psci.c +++ b/sys/dev/psci/psci.c @@ -97,6 +97,7 @@ struct psci_softc *psci_softc = NULL; #ifdef FDT static struct ofw_compat_data compat_data[] = { + {"arm,psci-1.0", (uintptr_t)psci_v0_2_init}, {"arm,psci-0.2", (uintptr_t)psci_v0_2_init}, {"arm,psci", (uintptr_t)psci_v0_1_init}, {NULL, 0} @@ -332,9 +333,11 @@ psci_fdt_callfn(psci_callfn_t *callfn) phandle_t node; node = ofw_bus_find_compatible(OF_peer(0), "arm,psci-0.2"); - if (node == 0) - /* TODO: Handle psci 0.1 */ - return (PSCI_MISSING); + if (node == 0) { + node = ofw_bus_find_compatible(OF_peer(0), "arm,psci-1.0"); + if (node == 0) + return (PSCI_MISSING); + } *callfn = psci_fdt_get_callfn(node); return (0); @@ -490,9 +493,9 @@ psci_v0_2_init(device_t dev) return (1); if ((PSCI_VER_MAJOR(version) == 0 && PSCI_VER_MINOR(version) == 2) || - (PSCI_VER_MAJOR(version) == 1 && PSCI_VER_MINOR(version) == 0)) { + PSCI_VER_MAJOR(version) == 1) { if (bootverbose) - device_printf(dev, "PSCI version 0.2 available\n"); + device_printf(dev, "PSCI version 0.2 compatible\n"); /* * We only register this for v0.2 since v0.1 doesn't support diff --git a/sys/dev/qlnx/qlnxe/qlnx_def.h b/sys/dev/qlnx/qlnxe/qlnx_def.h index dad7a10e73e8..6c487e578a2b 100644 --- a/sys/dev/qlnx/qlnxe/qlnx_def.h +++ b/sys/dev/qlnx/qlnxe/qlnx_def.h @@ -486,7 +486,7 @@ struct qlnx_host { typedef struct qlnx_host qlnx_host_t; /* note that align has to be a power of 2 */ -#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1); +#define QL_ALIGN(size, align) (((size) + ((align) - 1)) & (~((align) - 1))) #define QL_MIN(x, y) ((x < y) ? x : y) #define QL_RUNNING(ifp) \ diff --git a/sys/dev/qlxgb/qla_def.h b/sys/dev/qlxgb/qla_def.h index 77b678c7bc83..d5b11c156768 100644 --- a/sys/dev/qlxgb/qla_def.h +++ b/sys/dev/qlxgb/qla_def.h @@ -200,7 +200,7 @@ struct qla_host { typedef struct qla_host qla_host_t; /* note that align has to be a power of 2 */ -#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1); +#define QL_ALIGN(size, align) (((size) + ((align) - 1)) & (~((align) - 1))) #define QL_MIN(x, y) ((x < y) ? x : y) #define QL_RUNNING(ifp) \ diff --git a/sys/dev/qlxgbe/ql_def.h b/sys/dev/qlxgbe/ql_def.h index beb3f4e459af..168cd265f66c 100644 --- a/sys/dev/qlxgbe/ql_def.h +++ b/sys/dev/qlxgbe/ql_def.h @@ -201,7 +201,6 @@ struct qla_host { qla_rx_buf_t *rxb_free; uint32_t rxb_free_count; - volatile uint32_t posting; /* stats */ uint32_t err_m_getcl; @@ -239,6 +238,7 @@ struct qla_host { volatile const char *qla_lock; volatile const char *qla_unlock; uint32_t dbg_level; + uint32_t enable_minidump; uint8_t fw_ver_str[32]; @@ -263,7 +263,7 @@ struct qla_host { typedef struct qla_host qla_host_t; /* note that align has to be a power of 2 */ -#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1); +#define QL_ALIGN(size, align) (((size) + ((align) - 1)) & (~((align) - 1))) #define QL_MIN(x, y) ((x < y) ? x : y) #define QL_RUNNING(ifp) (ifp->if_drv_flags & IFF_DRV_RUNNING) diff --git a/sys/dev/qlxgbe/ql_glbl.h b/sys/dev/qlxgbe/ql_glbl.h index 463ab7a70cd5..f8c7c8b165c1 100644 --- a/sys/dev/qlxgbe/ql_glbl.h +++ b/sys/dev/qlxgbe/ql_glbl.h @@ -75,6 +75,7 @@ extern int ql_hw_check_health(qla_host_t *ha); extern void qla_hw_async_event(qla_host_t *ha); extern int qla_get_nic_partition(qla_host_t *ha, uint32_t *supports_9kb, uint32_t *num_rcvq); +extern int qla_hw_del_all_mcast(qla_host_t *ha); extern int ql_iscsi_pdu(qla_host_t *ha, struct mbuf *mp); extern void ql_minidump(qla_host_t *ha); @@ -111,4 +112,8 @@ extern unsigned int ql83xx_resetseq_len; extern unsigned char ql83xx_minidump[]; extern unsigned int ql83xx_minidump_len; +extern void ql_alloc_drvr_state_buffer(qla_host_t *ha); +extern void ql_free_drvr_state_buffer(qla_host_t *ha); +extern void ql_capture_drvr_state(qla_host_t *ha); + #endif /* #ifndef_QL_GLBL_H_ */ diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c index 7388b5b13b06..5bd8c9397ff4 100644 --- a/sys/dev/qlxgbe/ql_hw.c +++ b/sys/dev/qlxgbe/ql_hw.c @@ -64,7 +64,6 @@ static int qla_link_event_req(qla_host_t *ha, uint16_t cntxt_id); static int qla_tx_tso(qla_host_t *ha, struct mbuf *mp, q80_tx_cmd_t *tx_cmd, uint8_t *hdr); static int qla_hw_add_all_mcast(qla_host_t *ha); -static int qla_hw_del_all_mcast(qla_host_t *ha); static int qla_add_rcv_rings(qla_host_t *ha, uint32_t sds_idx, uint32_t nsds); static int qla_init_nic_func(qla_host_t *ha); @@ -2324,7 +2323,7 @@ ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs, if (total_length > QLA_MAX_TSO_FRAME_SIZE) { device_printf(dev, "%s: total length exceeds maxlen(%d)\n", __func__, total_length); - return (-1); + return (EINVAL); } eh = mtod(mp, struct ether_vlan_header *); @@ -2375,6 +2374,20 @@ ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs, } } + for (i = 0; i < num_tx_cmds; i++) { + int j; + + j = (tx_idx+i) & (NUM_TX_DESCRIPTORS - 1); + + if (NULL != ha->tx_ring[txr_idx].tx_buf[j].m_head) { + QL_ASSERT(ha, 0, \ + ("%s [%d]: txr_idx = %d tx_idx = %d mbuf = %p\n",\ + __func__, __LINE__, txr_idx, j,\ + ha->tx_ring[txr_idx].tx_buf[j].m_head)); + return (EINVAL); + } + } + tx_cmd = &hw->tx_cntxt[txr_idx].tx_ring_base[tx_idx]; if (!(mp->m_pkthdr.csum_flags & CSUM_TSO)) { @@ -3249,6 +3262,7 @@ qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx) hw_tx_cntxt->txr_free = NUM_TX_DESCRIPTORS; hw_tx_cntxt->txr_next = hw_tx_cntxt->txr_comp = 0; + *(hw_tx_cntxt->tx_cons) = 0; if (qla_mbx_cmd(ha, (uint32_t *)tcntxt, (sizeof (q80_rq_tx_cntxt_t) >> 2), @@ -3413,7 +3427,7 @@ qla_hw_add_all_mcast(qla_host_t *ha) return (ret); } -static int +int qla_hw_del_all_mcast(qla_host_t *ha) { int ret; diff --git a/sys/dev/qlxgbe/ql_hw.h b/sys/dev/qlxgbe/ql_hw.h index 84260087f16f..e8f53c86407d 100644 --- a/sys/dev/qlxgbe/ql_hw.h +++ b/sys/dev/qlxgbe/ql_hw.h @@ -1703,6 +1703,9 @@ typedef struct _qla_hw { uint32_t mdump_buffer_size; void *mdump_template; uint32_t mdump_template_size; + + /* driver state related */ + void *drvr_state; } qla_hw_t; #define QL_UPDATE_RDS_PRODUCER_INDEX(ha, prod_reg, val) \ diff --git a/sys/dev/qlxgbe/ql_ioctl.c b/sys/dev/qlxgbe/ql_ioctl.c index 8284cc72306c..7675d54823c4 100644 --- a/sys/dev/qlxgbe/ql_ioctl.c +++ b/sys/dev/qlxgbe/ql_ioctl.c @@ -39,7 +39,11 @@ __FBSDID("$FreeBSD$"); #include "ql_inline.h" #include "ql_glbl.h" #include "ql_ioctl.h" +#include "ql_ver.h" +#include "ql_dbg.h" +static int ql_drvr_state(qla_host_t *ha, qla_driver_state_t *drvr_state); +static uint32_t ql_drvr_state_size(qla_host_t *ha); static int ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td); @@ -279,6 +283,10 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, rval = ENXIO; break; + case QLA_RD_DRVR_STATE: + rval = ql_drvr_state(ha, (qla_driver_state_t *)data); + break; + case QLA_RD_PCI_IDS: pci_ids = (qla_rd_pci_ids_t *)data; pci_ids->ven_id = pci_get_vendor(pci_dev); @@ -295,3 +303,223 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, return rval; } + +static int +ql_drvr_state(qla_host_t *ha, qla_driver_state_t *state) +{ + int rval = 0; + uint32_t drvr_state_size; + qla_drvr_state_hdr_t *hdr; + + drvr_state_size = ql_drvr_state_size(ha); + + if (state->buffer == NULL) { + state->size = drvr_state_size; + return (0); + } + + if (state->size < drvr_state_size) + return (ENXIO); + + if (ha->hw.drvr_state == NULL) + return (ENOMEM); + + hdr = ha->hw.drvr_state; + + if (!hdr->drvr_version_major) + ql_capture_drvr_state(ha); + + rval = copyout(ha->hw.drvr_state, state->buffer, drvr_state_size); + + bzero(ha->hw.drvr_state, drvr_state_size); + + return (rval); +} + +static uint32_t +ql_drvr_state_size(qla_host_t *ha) +{ + uint32_t drvr_state_size; + uint32_t size; + + size = sizeof (qla_drvr_state_hdr_t); + drvr_state_size = QL_ALIGN(size, 64); + + size = ha->hw.num_tx_rings * (sizeof (qla_drvr_state_tx_t)); + drvr_state_size += QL_ALIGN(size, 64); + + size = ha->hw.num_rds_rings * (sizeof (qla_drvr_state_rx_t)); + drvr_state_size += QL_ALIGN(size, 64); + + size = ha->hw.num_sds_rings * (sizeof (qla_drvr_state_sds_t)); + drvr_state_size += QL_ALIGN(size, 64); + + size = sizeof(q80_tx_cmd_t) * NUM_TX_DESCRIPTORS * ha->hw.num_tx_rings; + drvr_state_size += QL_ALIGN(size, 64); + + size = sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS * ha->hw.num_rds_rings; + drvr_state_size += QL_ALIGN(size, 64); + + size = sizeof(q80_stat_desc_t) * NUM_STATUS_DESCRIPTORS * + ha->hw.num_sds_rings; + drvr_state_size += QL_ALIGN(size, 64); + + return (drvr_state_size); +} + +static void +ql_get_tx_state(qla_host_t *ha, qla_drvr_state_tx_t *tx_state) +{ + int i; + + for (i = 0; i < ha->hw.num_tx_rings; i++) { + tx_state->base_p_addr = ha->hw.tx_cntxt[i].tx_ring_paddr; + tx_state->cons_p_addr = ha->hw.tx_cntxt[i].tx_cons_paddr; + tx_state->tx_prod_reg = ha->hw.tx_cntxt[i].tx_prod_reg; + tx_state->tx_cntxt_id = ha->hw.tx_cntxt[i].tx_cntxt_id; + tx_state->txr_free = ha->hw.tx_cntxt[i].txr_free; + tx_state->txr_next = ha->hw.tx_cntxt[i].txr_next; + tx_state->txr_comp = ha->hw.tx_cntxt[i].txr_comp; + tx_state++; + } + return; +} + +static void +ql_get_rx_state(qla_host_t *ha, qla_drvr_state_rx_t *rx_state) +{ + int i; + + for (i = 0; i < ha->hw.num_rds_rings; i++) { + rx_state->prod_std = ha->hw.rds[i].prod_std; + rx_state->rx_next = ha->hw.rds[i].rx_next; + rx_state++; + } + return; +} + +static void +ql_get_sds_state(qla_host_t *ha, qla_drvr_state_sds_t *sds_state) +{ + int i; + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + sds_state->sdsr_next = ha->hw.sds[i].sdsr_next; + sds_state->sds_consumer = ha->hw.sds[i].sds_consumer; + sds_state++; + } + return; +} + +void +ql_capture_drvr_state(qla_host_t *ha) +{ + uint8_t *state_buffer; + uint8_t *ptr; + uint32_t drvr_state_size; + qla_drvr_state_hdr_t *hdr; + uint32_t size; + int i; + + drvr_state_size = ql_drvr_state_size(ha); + + state_buffer = ha->hw.drvr_state; + + if (state_buffer == NULL) + return; + + bzero(state_buffer, drvr_state_size); + + hdr = (qla_drvr_state_hdr_t *)state_buffer; + + hdr->drvr_version_major = QLA_VERSION_MAJOR; + hdr->drvr_version_minor = QLA_VERSION_MINOR; + hdr->drvr_version_build = QLA_VERSION_BUILD; + + bcopy(ha->hw.mac_addr, hdr->mac_addr, ETHER_ADDR_LEN); + + hdr->link_speed = ha->hw.link_speed; + hdr->cable_length = ha->hw.cable_length; + hdr->cable_oui = ha->hw.cable_oui; + hdr->link_up = ha->hw.link_up; + hdr->module_type = ha->hw.module_type; + hdr->link_faults = ha->hw.link_faults; + hdr->rcv_intr_coalesce = ha->hw.rcv_intr_coalesce; + hdr->xmt_intr_coalesce = ha->hw.xmt_intr_coalesce; + + size = sizeof (qla_drvr_state_hdr_t); + hdr->tx_state_offset = QL_ALIGN(size, 64); + + ptr = state_buffer + hdr->tx_state_offset; + + ql_get_tx_state(ha, (qla_drvr_state_tx_t *)ptr); + + size = ha->hw.num_tx_rings * (sizeof (qla_drvr_state_tx_t)); + hdr->rx_state_offset = hdr->tx_state_offset + QL_ALIGN(size, 64); + ptr = state_buffer + hdr->rx_state_offset; + + ql_get_rx_state(ha, (qla_drvr_state_rx_t *)ptr); + + size = ha->hw.num_rds_rings * (sizeof (qla_drvr_state_rx_t)); + hdr->sds_state_offset = hdr->rx_state_offset + QL_ALIGN(size, 64); + ptr = state_buffer + hdr->sds_state_offset; + + ql_get_sds_state(ha, (qla_drvr_state_sds_t *)ptr); + + size = ha->hw.num_sds_rings * (sizeof (qla_drvr_state_sds_t)); + hdr->txr_offset = hdr->sds_state_offset + QL_ALIGN(size, 64); + ptr = state_buffer + hdr->txr_offset; + + hdr->num_tx_rings = ha->hw.num_tx_rings; + hdr->txr_size = sizeof(q80_tx_cmd_t) * NUM_TX_DESCRIPTORS; + hdr->txr_entries = NUM_TX_DESCRIPTORS; + + size = hdr->num_tx_rings * hdr->txr_size; + bcopy(ha->hw.dma_buf.tx_ring.dma_b, ptr, size); + + hdr->rxr_offset = hdr->txr_offset + QL_ALIGN(size, 64); + ptr = state_buffer + hdr->rxr_offset; + + hdr->rxr_size = sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS; + hdr->rxr_entries = NUM_RX_DESCRIPTORS; + hdr->num_rx_rings = ha->hw.num_rds_rings; + + for (i = 0; i < ha->hw.num_rds_rings; i++) { + bcopy(ha->hw.dma_buf.rds_ring[i].dma_b, ptr, hdr->rxr_size); + ptr += hdr->rxr_size; + } + + size = hdr->rxr_size * hdr->num_rx_rings; + hdr->sds_offset = hdr->rxr_offset + QL_ALIGN(size, 64); + hdr->sds_ring_size = sizeof(q80_stat_desc_t) * NUM_STATUS_DESCRIPTORS; + hdr->sds_entries = NUM_STATUS_DESCRIPTORS; + hdr->num_sds_rings = ha->hw.num_sds_rings; + + ptr = state_buffer + hdr->sds_offset; + for (i = 0; i < ha->hw.num_sds_rings; i++) { + bcopy(ha->hw.dma_buf.sds_ring[i].dma_b, ptr, hdr->sds_ring_size); + ptr += hdr->sds_ring_size; + } + return; +} + +void +ql_alloc_drvr_state_buffer(qla_host_t *ha) +{ + uint32_t drvr_state_size; + + drvr_state_size = ql_drvr_state_size(ha); + + ha->hw.drvr_state = malloc(drvr_state_size, M_QLA83XXBUF, M_NOWAIT); + + return; +} + +void +ql_free_drvr_state_buffer(qla_host_t *ha) +{ + if (ha->hw.drvr_state != NULL) + free(ha->hw.drvr_state, M_QLA83XXBUF); + return; +} + diff --git a/sys/dev/qlxgbe/ql_ioctl.h b/sys/dev/qlxgbe/ql_ioctl.h index 8787af4e611c..f985958a74e6 100644 --- a/sys/dev/qlxgbe/ql_ioctl.h +++ b/sys/dev/qlxgbe/ql_ioctl.h @@ -93,6 +93,72 @@ struct qla_rd_fw_dump { }; typedef struct qla_rd_fw_dump qla_rd_fw_dump_t; +struct qla_drvr_state_tx { + uint64_t base_p_addr; + uint64_t cons_p_addr; + uint32_t tx_prod_reg; + uint32_t tx_cntxt_id; + uint32_t txr_free; + uint32_t txr_next; + uint32_t txr_comp; +}; +typedef struct qla_drvr_state_tx qla_drvr_state_tx_t; + +struct qla_drvr_state_sds { + uint32_t sdsr_next; /* next entry in SDS ring to process */ + uint32_t sds_consumer; +}; +typedef struct qla_drvr_state_sds qla_drvr_state_sds_t; + +struct qla_drvr_state_rx { + uint32_t prod_std; + uint32_t rx_next; /* next standard rcv ring to arm fw */; +}; +typedef struct qla_drvr_state_rx qla_drvr_state_rx_t; + +struct qla_drvr_state_hdr { + uint32_t drvr_version_major; + uint32_t drvr_version_minor; + uint32_t drvr_version_build; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint16_t link_speed; + uint16_t cable_length; + uint32_t cable_oui; + uint8_t link_up; + uint8_t module_type; + uint8_t link_faults; + uint32_t rcv_intr_coalesce; + uint32_t xmt_intr_coalesce; + + uint32_t tx_state_offset;/* size = sizeof (qla_drvr_state_tx_t) * num_tx_rings */ + uint32_t rx_state_offset;/* size = sizeof (qla_drvr_state_rx_t) * num_rx_rings */ + uint32_t sds_state_offset;/* size = sizeof (qla_drvr_state_sds_t) * num_sds_rings */ + + uint32_t num_tx_rings; /* number of tx rings */ + uint32_t txr_size; /* size of each tx ring in bytes */ + uint32_t txr_entries; /* number of descriptors in each tx ring */ + uint32_t txr_offset; /* start of tx ring [0 - #rings] content */ + + uint32_t num_rx_rings; /* number of rx rings */ + uint32_t rxr_size; /* size of each rx ring in bytes */ + uint32_t rxr_entries; /* number of descriptors in each rx ring */ + uint32_t rxr_offset; /* start of rx ring [0 - #rings] content */ + + uint32_t num_sds_rings; /* number of sds rings */ + uint32_t sds_ring_size; /* size of each sds ring in bytes */ + uint32_t sds_entries; /* number of descriptors in each sds ring */ + uint32_t sds_offset; /* start of sds ring [0 - #rings] content */ +}; + +typedef struct qla_drvr_state_hdr qla_drvr_state_hdr_t; + +struct qla_driver_state { + uint32_t size; + void *buffer; +}; +typedef struct qla_driver_state qla_driver_state_t; + /* * Read/Write Register */ @@ -133,4 +199,10 @@ typedef struct qla_rd_fw_dump qla_rd_fw_dump_t; */ #define QLA_RD_FW_DUMP _IOWR('q', 8, qla_rd_fw_dump_t) +/* + * Read Driver State + */ +#define QLA_RD_DRVR_STATE _IOWR('q', 9, qla_driver_state_t) + + #endif /* #ifndef _QL_IOCTL_H_ */ diff --git a/sys/dev/qlxgbe/ql_minidump.c b/sys/dev/qlxgbe/ql_minidump.c index e3721068340d..c1bde8cdff82 100644 --- a/sys/dev/qlxgbe/ql_minidump.c +++ b/sys/dev/qlxgbe/ql_minidump.c @@ -41,7 +41,7 @@ unsigned int ql83xx_minidump_version_sub = 66; unsigned char ql83xx_minidump[] = { 0x63, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xaa, 0x05, 0x00, 0x00, 0x04, 0x00, 0x02, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x52, 0x1d, 0x95, 0x7b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x87, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -49,7 +49,7 @@ unsigned char ql83xx_minidump[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0xdc, 0xfb, 0x07, 0x00, - 0x00, 0x8a, 0x2b, 0x00, 0x80, 0x73, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8a, 0x2b, 0x00, 0x40, 0x6f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x4a, 0x3b, 0x00, 0x00, 0x10, 0x03, 0x08, 0x00, 0x08, 0x31, 0x77, 0x04, 0x08, 0x31, 0x77, 0x08, 0x08, 0x31, 0x77, 0x0c, 0x08, 0x31, 0x77, 0x10, 0x08, 0x31, 0x77, 0x1c, 0x08, 0x31, 0x77, @@ -61,8 +61,8 @@ unsigned char ql83xx_minidump[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, - 0xe0, 0x91, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x62, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x30, 0x77, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, @@ -2935,10 +2935,26 @@ unsigned char ql83xx_minidump[] = { 0x08, 0xd6, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x07, 0x00, 0x18, 0x02, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x08, 0xdc, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0xe8, 0x01, 0x06, 0x00, 0x00, 0x02, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x08, 0xdc, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x11, 0x06, 0x00, 0x80, 0x02, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xe0, 0x17, 0x00, 0x00, + 0x08, 0xdc, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x14, 0x06, 0xe0, 0x17, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, + 0x08, 0xdc, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x55, 0x06, 0xe0, 0x1f, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd5, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xd5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0xca, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2946,7 +2962,7 @@ unsigned char ql83xx_minidump[] = { 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x14, 0x00, 0x04, 0xc9, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x0a, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0a, 0x14, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x02, 0xd7, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3050,11 +3066,11 @@ unsigned char ql83xx_minidump[] = { 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xd4, 0x00, 0x50, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0xd9, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x76, 0x03, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x96, 0x03, 0x20, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0xff, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3151,30 +3167,14 @@ unsigned char ql83xx_minidump[] = { 0x04, 0xff, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x08, 0xcd, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xc6, 0x01, 0x00, 0x40, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x08, 0xce, 0x00, 0x00, 0x00, 0x50, 0x1a, 0x01, 0x06, 0xc1, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x1a, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -10959,8 +10959,8 @@ unsigned char ql83xx_minidump[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x05, 0x00, 0x40, 0x40, 0x05, 0x04, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x40, 0x40, 0x05, 0x04, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x39, 0x7c, 0xbf + 0x00, 0x00, 0x00, 0x00, 0x34, 0x39, 0x7b, 0xbf }; unsigned int ql83xx_minidump_len = 131072; diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c index f504de1377ca..fb94f3994bdf 100644 --- a/sys/dev/qlxgbe/ql_os.c +++ b/sys/dev/qlxgbe/ql_os.c @@ -185,6 +185,13 @@ qla_add_sysctls(qla_host_t *ha) OID_AUTO, "debug", CTLFLAG_RW, &ha->dbg_level, ha->dbg_level, "Debug Level"); + ha->enable_minidump = 1; + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "enable_minidump", CTLFLAG_RW, + &ha->enable_minidump, ha->enable_minidump, + "Minidump retrival is enabled only when this is set"); + ha->std_replenish = QL_STD_REPLENISH_THRES; SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), @@ -485,6 +492,7 @@ qla_pci_attach(device_t dev) device_printf(dev, "%s: ql_minidump_init failed\n", __func__); goto qla_pci_attach_err; } + ql_alloc_drvr_state_buffer(ha); /* create the o.s ethernet interface */ qla_init_ifnet(dev, ha); @@ -638,6 +646,7 @@ qla_release(qla_host_t *ha) if (ha->ifp != NULL) ether_ifdetach(ha->ifp); + ql_free_drvr_state_buffer(ha); ql_free_dma(ha); qla_free_parent_dma_tag(ha); @@ -968,7 +977,19 @@ qla_set_multi(qla_host_t *ha, uint32_t add_multi) return (-1); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ret = ql_hw_set_multi(ha, mta, mcnt, add_multi); + + if (!add_multi) { + ret = qla_hw_del_all_mcast(ha); + + if (ret) + device_printf(ha->pci_dev, + "%s: qla_hw_del_all_mcast() failed\n", + __func__); + } + + if (!ret) + ret = ql_hw_set_multi(ha, mta, mcnt, 1); + } QLA_UNLOCK(ha, __func__); @@ -1213,6 +1234,17 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx, QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__)); tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next; + + if (NULL != ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head) { + QL_ASSERT(ha, 0, ("%s [%d]: txr_idx = %d tx_idx = %d "\ + "mbuf = %p\n", __func__, __LINE__, txr_idx, tx_idx,\ + ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head)); + if (m_head) + m_freem(m_head); + *m_headp = NULL; + return (ret); + } + map = ha->tx_ring[txr_idx].tx_buf[tx_idx].map; ret = bus_dmamap_load_mbuf_sg(ha->tx_tag, map, m_head, segs, &nsegs, @@ -1280,6 +1312,7 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx, ha->tx_ring[txr_idx].iscsi_pkt_count++; ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head; } else { + bus_dmamap_unload(ha->tx_tag, map); if (ret == EINVAL) { if (m_head) m_freem(m_head); @@ -1365,7 +1398,8 @@ qla_fp_taskqueue(void *context, int pending) goto qla_fp_taskqueue_exit; } - while (rx_pkts_left && !ha->stop_rcv) { + while (rx_pkts_left && !ha->stop_rcv && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) { rx_pkts_left = ql_rcv_isr(ha, fp->txr_idx, 64); #ifdef QL_ENABLE_ISCSI_TLV @@ -1408,6 +1442,11 @@ qla_fp_taskqueue(void *context, int pending) drbr_advance(ifp, fp->tx_br); } + /* Send a copy of the frame to the BPF listener */ + ETHER_BPF_MTAP(ifp, mp); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + mp = drbr_peek(ifp, fp->tx_br); } } @@ -1670,16 +1709,24 @@ qla_clear_tx_buf(qla_host_t *ha, qla_tx_buf_t *txb) { QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__)); - if (txb->m_head && txb->map) { + if (txb->m_head) { + bus_dmamap_sync(ha->tx_tag, txb->map, + BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(ha->tx_tag, txb->map); m_freem(txb->m_head); txb->m_head = NULL; + + bus_dmamap_destroy(ha->tx_tag, txb->map); + txb->map = NULL; } - if (txb->map) + if (txb->map) { + bus_dmamap_unload(ha->tx_tag, txb->map); bus_dmamap_destroy(ha->tx_tag, txb->map); + txb->map = NULL; + } QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__)); } @@ -2025,7 +2072,8 @@ device_printf(ha->pci_dev, "%s: enter\n", __func__); ha->msg_from_peer = 0; - ql_minidump(ha); + if (ha->enable_minidump) + ql_minidump(ha); (void) ql_init_hw(ha); diff --git a/sys/dev/qlxgbe/ql_ver.h b/sys/dev/qlxgbe/ql_ver.h index e6c06ed299dd..24a9d30d1901 100644 --- a/sys/dev/qlxgbe/ql_ver.h +++ b/sys/dev/qlxgbe/ql_ver.h @@ -36,6 +36,6 @@ #define QLA_VERSION_MAJOR 3 #define QLA_VERSION_MINOR 10 -#define QLA_VERSION_BUILD 34 +#define QLA_VERSION_BUILD 35 #endif /* #ifndef _QL_VER_H_ */ diff --git a/sys/dev/qlxge/qls_def.h b/sys/dev/qlxge/qls_def.h index 815946fafd5f..8d191e060290 100644 --- a/sys/dev/qlxge/qls_def.h +++ b/sys/dev/qlxge/qls_def.h @@ -361,7 +361,7 @@ struct qla_host { typedef struct qla_host qla_host_t; /* note that align has to be a power of 2 */ -#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1); +#define QL_ALIGN(size, align) (((size) + ((align) - 1)) & (~((align) - 1))) #define QL_MIN(x, y) ((x < y) ? x : y) #define QL_RUNNING(ifp) \ diff --git a/sys/dev/random/fortuna.c b/sys/dev/random/fortuna.c index e300c6ffb4ca..98473a1b08ef 100644 --- a/sys/dev/random/fortuna.c +++ b/sys/dev/random/fortuna.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2017 W. Dean Freeman * Copyright (c) 2013-2015 Mark R V Murray * All rights reserved. * @@ -87,7 +88,7 @@ __FBSDID("$FreeBSD$"); * and too small may compromise initial security but get faster reseeds. */ #define RANDOM_FORTUNA_MINPOOLSIZE 16 -#define RANDOM_FORTUNA_MAXPOOLSIZE UINT_MAX +#define RANDOM_FORTUNA_MAXPOOLSIZE INT_MAX CTASSERT(RANDOM_FORTUNA_MINPOOLSIZE <= RANDOM_FORTUNA_DEFPOOLSIZE); CTASSERT(RANDOM_FORTUNA_DEFPOOLSIZE <= RANDOM_FORTUNA_MAXPOOLSIZE); @@ -232,17 +233,29 @@ random_fortuna_process_event(struct harvest_event *event) * during accumulation/reseeding and reading/regating. */ pl = event->he_destination % RANDOM_FORTUNA_NPOOLS; - randomdev_hash_iterate(&fortuna_state.fs_pool[pl].fsp_hash, event, sizeof(*event)); + /* + * We ignore low entropy static/counter fields towards the end of the + * he_event structure in order to increase measurable entropy when + * conducting SP800-90B entropy analysis measurements of seed material + * fed into PRNG. + * -- wdf + */ + KASSERT(event->he_size <= sizeof(event->he_entropy), + ("%s: event->he_size: %hhu > sizeof(event->he_entropy): %zu\n", + __func__, event->he_size, sizeof(event->he_entropy))); + randomdev_hash_iterate(&fortuna_state.fs_pool[pl].fsp_hash, + &event->he_somecounter, sizeof(event->he_somecounter)); + randomdev_hash_iterate(&fortuna_state.fs_pool[pl].fsp_hash, + event->he_entropy, event->he_size); + /*- - * Don't wrap the length. Doing this the hard way so as not to wrap at MAXUINT. - * This is a "saturating" add. + * Don't wrap the length. This is a "saturating" add. * XXX: FIX!!: We don't actually need lengths for anything but fs_pool[0], * but it's been useful debugging to see them all. */ - if (RANDOM_FORTUNA_MAXPOOLSIZE - fortuna_state.fs_pool[pl].fsp_length > event->he_size) - fortuna_state.fs_pool[pl].fsp_length += event->he_size; - else - fortuna_state.fs_pool[pl].fsp_length = RANDOM_FORTUNA_MAXPOOLSIZE; + fortuna_state.fs_pool[pl].fsp_length = MIN(RANDOM_FORTUNA_MAXPOOLSIZE, + fortuna_state.fs_pool[pl].fsp_length + + sizeof(event->he_somecounter) + event->he_size); explicit_bzero(event, sizeof(*event)); RANDOM_RESEED_UNLOCK(); } diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c index 69cbd278d484..1b8e38bba211 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -1,4 +1,6 @@ /*- + * Copyright (c) 2017 Oliver Pinter + * Copyright (c) 2017 W. Dean Freeman * Copyright (c) 2000-2015 Mark R V Murray * Copyright (c) 2013 Arthur Mesh * Copyright (c) 2004 Robert N. M. Watson @@ -240,7 +242,27 @@ read_rate_increment(u_int chunk) } /* ARGSUSED */ -RANDOM_CHECK_UINT(harvestmask, 0, RANDOM_HARVEST_EVERYTHING_MASK); +static int +random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS) +{ + int error; + u_int value, orig_value; + + orig_value = value = harvest_context.hc_source_mask; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (flsl(value) > ENTROPYSOURCE) + return (EINVAL); + + /* + * Disallow userspace modification of pure entropy sources. + */ + harvest_context.hc_source_mask = (value & ~RANDOM_HARVEST_PURE_MASK) | + (orig_value & RANDOM_HARVEST_PURE_MASK); + return (0); +} /* ARGSUSED */ static int @@ -252,7 +274,7 @@ random_print_harvestmask(SYSCTL_HANDLER_ARGS) error = sysctl_wire_old_buffer(req, 0); if (error == 0) { sbuf_new_for_sysctl(&sbuf, NULL, 128, req); - for (i = RANDOM_ENVIRONMENTAL_END; i >= 0; i--) + for (i = ENTROPYSOURCE - 1; i >= 0; i--) sbuf_cat(&sbuf, (harvest_context.hc_source_mask & (1 << i)) ? "1" : "0"); error = sbuf_finish(&sbuf); sbuf_delete(&sbuf); @@ -260,26 +282,28 @@ random_print_harvestmask(SYSCTL_HANDLER_ARGS) return (error); } -static const char *(random_source_descr[]) = { - "CACHED", - "ATTACH", - "KEYBOARD", - "MOUSE", - "NET_TUN", - "NET_ETHER", - "NET_NG", - "INTERRUPT", - "SWI", - "FS_ATIME", - "UMA", /* ENVIRONMENTAL_END */ - "PURE_OCTEON", - "PURE_SAFE", - "PURE_GLXSB", - "PURE_UBSEC", - "PURE_HIFN", - "PURE_RDRAND", - "PURE_NEHEMIAH", - "PURE_RNDTEST", +static const char *random_source_descr[ENTROPYSOURCE] = { + [RANDOM_CACHED] = "CACHED", + [RANDOM_ATTACH] = "ATTACH", + [RANDOM_KEYBOARD] = "KEYBOARD", + [RANDOM_MOUSE] = "MOUSE", + [RANDOM_NET_TUN] = "NET_TUN", + [RANDOM_NET_ETHER] = "NET_ETHER", + [RANDOM_NET_NG] = "NET_NG", + [RANDOM_INTERRUPT] = "INTERRUPT", + [RANDOM_SWI] = "SWI", + [RANDOM_FS_ATIME] = "FS_ATIME", + [RANDOM_UMA] = "UMA", /* ENVIRONMENTAL_END */ + [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */ + [RANDOM_PURE_SAFE] = "PURE_SAFE", + [RANDOM_PURE_GLXSB] = "PURE_GLXSB", + [RANDOM_PURE_UBSEC] = "PURE_UBSEC", + [RANDOM_PURE_HIFN] = "PURE_HIFN", + [RANDOM_PURE_RDRAND] = "PURE_RDRAND", + [RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH", + [RANDOM_PURE_RNDTEST] = "PURE_RNDTEST", + [RANDOM_PURE_VIRTIO] = "PURE_VIRTIO", + [RANDOM_PURE_BROADCOM] = "PURE_BROADCOM", /* "ENTROPYSOURCE" */ }; @@ -289,15 +313,22 @@ random_print_harvestmask_symbolic(SYSCTL_HANDLER_ARGS) { struct sbuf sbuf; int error, i; + bool first; + first = true; error = sysctl_wire_old_buffer(req, 0); if (error == 0) { sbuf_new_for_sysctl(&sbuf, NULL, 128, req); - for (i = RANDOM_ENVIRONMENTAL_END; i >= 0; i--) { - sbuf_cat(&sbuf, (i == RANDOM_ENVIRONMENTAL_END) ? "" : ","); + for (i = ENTROPYSOURCE - 1; i >= 0; i--) { + if (i >= RANDOM_PURE_START && + (harvest_context.hc_source_mask & (1 << i)) == 0) + continue; + if (!first) + sbuf_cat(&sbuf, ","); sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "[" : ""); sbuf_cat(&sbuf, random_source_descr[i]); sbuf_cat(&sbuf, !(harvest_context.hc_source_mask & (1 << i)) ? "]" : ""); + first = false; } error = sbuf_finish(&sbuf); sbuf_delete(&sbuf); @@ -319,8 +350,7 @@ random_harvestq_init(void *unused __unused) SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_o), OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW, - &harvest_context.hc_source_mask, 0, - random_check_uint_harvestmask, "IU", + NULL, 0, random_check_uint_harvestmask, "IU", "Entropy harvesting mask"); SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_o), @@ -493,4 +523,18 @@ random_harvest_direct(const void *entropy, u_int size, u_int bits, enum random_e explicit_bzero(&event, sizeof(event)); } +void +random_harvest_register_source(enum random_entropy_source source) +{ + + harvest_context.hc_source_mask |= (1 << source); +} + +void +random_harvest_deregister_source(enum random_entropy_source source) +{ + + harvest_context.hc_source_mask &= ~(1 << source); +} + MODULE_VERSION(random_harvestq, 1); diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index 7edfca8ad607..28a191f8f7b6 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2017 Oliver Pinter * Copyright (c) 2000-2015 Mark R V Murray * All rights reserved. * @@ -321,6 +322,8 @@ random_source_register(struct random_source *rsource) rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK); rrs->rrs_source = rsource; + random_harvest_register_source(rsource->rs_source); + printf("random: registering fast source %s\n", rsource->rs_ident); LIST_INSERT_HEAD(&source_list, rrs, rrs_entries); } @@ -331,6 +334,9 @@ random_source_deregister(struct random_source *rsource) struct random_sources *rrs = NULL; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); + + random_harvest_deregister_source(rsource->rs_source); + LIST_FOREACH(rrs, &source_list, rrs_entries) if (rrs->rrs_source == rsource) { LIST_REMOVE(rrs, rrs_entries); diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.h b/sys/dev/rtwn/usb/rtwn_usb_attach.h index ee6d9137fd8b..6bbdf5bcd398 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_attach.h +++ b/sys/dev/rtwn/usb/rtwn_usb_attach.h @@ -137,6 +137,8 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = { RTWN_RTL8812AU_DEV(SENAO, EUB1200AC), RTWN_RTL8812AU_DEV(SITECOMEU, WLA7100), RTWN_RTL8812AU_DEV(TPLINK, T4U), + RTWN_RTL8812AU_DEV(TPLINK, T4UV2), + RTWN_RTL8812AU_DEV(TPLINK, T4UHV2), RTWN_RTL8812AU_DEV(TRENDNET, TEW805UB), RTWN_RTL8812AU_DEV(ZYXEL, NWD6605), #undef RTWN_RTL8812AU_DEV diff --git a/sys/dev/sdhci/fsl_sdhci.c b/sys/dev/sdhci/fsl_sdhci.c index 08f5b94df83d..c023ed9348b1 100644 --- a/sys/dev/sdhci/fsl_sdhci.c +++ b/sys/dev/sdhci/fsl_sdhci.c @@ -803,9 +803,26 @@ fsl_sdhci_get_platform_clock(device_t dev) static int fsl_sdhci_detach(device_t dev) { + struct fsl_sdhci_softc *sc = device_get_softc(dev); - /* sdhci_fdt_gpio_teardown(sc->gpio); */ - return (EBUSY); + if (sc->gpio != NULL) + sdhci_fdt_gpio_teardown(sc->gpio); + + callout_drain(&sc->r1bfix_callout); + + if (sc->intr_cookie != NULL) + bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); + if (sc->irq_res != NULL) + bus_release_resource(dev, SYS_RES_IRQ, + rman_get_rid(sc->irq_res), sc->irq_res); + + if (sc->mem_res != NULL) { + sdhci_cleanup_slot(&sc->slot); + bus_release_resource(dev, SYS_RES_MEMORY, + rman_get_rid(sc->mem_res), sc->mem_res); + } + + return (0); } static int @@ -913,22 +930,12 @@ fsl_sdhci_attach(device_t dev) bus_generic_probe(dev); bus_generic_attach(dev); -#ifdef MMCCAM - sdhci_cam_start_slot(&sc->slot); -#else sdhci_start_slot(&sc->slot); -#endif return (0); fail: - if (sc->intr_cookie) - bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); - + fsl_sdhci_detach(dev); return (err); } @@ -936,7 +943,7 @@ static int fsl_sdhci_probe(device_t dev) { - if (!ofw_bus_status_okay(dev)) + if (!ofw_bus_status_okay(dev)) return (ENXIO); switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 294f3f48e65d..e3efc3332bf5 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -1051,12 +1051,14 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) return (0); } +#ifndef MMCCAM void sdhci_start_slot(struct sdhci_slot *slot) { sdhci_card_task(slot, 0); } +#endif int sdhci_cleanup_slot(struct sdhci_slot *slot) @@ -2383,7 +2385,7 @@ sdhci_generic_write_ivar(device_t bus, device_t child, int which, #ifdef MMCCAM void -sdhci_cam_start_slot(struct sdhci_slot *slot) +sdhci_start_slot(struct sdhci_slot *slot) { if ((slot->devq = cam_simq_alloc(1)) == NULL) { goto fail; diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index b11cabb8416a..883655002eeb 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -430,9 +430,4 @@ bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot); void sdhci_generic_set_uhs_timing(device_t brdev, struct sdhci_slot *slot); void sdhci_handle_card_present(struct sdhci_slot *slot, bool is_present); -#ifdef MMCCAM -/* CAM-related */ -void sdhci_cam_start_slot(struct sdhci_slot *slot); -#endif - #endif /* __SDHCI_H__ */ diff --git a/sys/dev/sdhci/sdhci_pci.c b/sys/dev/sdhci/sdhci_pci.c index 1b568bee9505..ebafee025b77 100644 --- a/sys/dev/sdhci/sdhci_pci.c +++ b/sys/dev/sdhci/sdhci_pci.c @@ -395,11 +395,7 @@ sdhci_pci_attach(device_t dev) pci_enable_busmaster(dev); /* Process cards detection. */ for (i = 0; i < sc->num_slots; i++) { -#ifdef MMCCAM - sdhci_cam_start_slot(&sc->slots[i]); -#else sdhci_start_slot(&sc->slots[i]); -#endif } return (0); diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c index b0a46c9d97ef..265172970634 100644 --- a/sys/dev/sk/if_sk.c +++ b/sys/dev/sk/if_sk.c @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$"); * the SK-984x series adapters, both single port and dual port. * References: * The XaQti XMAC II datasheet, - * http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf + * https://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf * The SysKonnect GEnesis manual, http://www.syskonnect.com * * Note: XaQti has been acquired by Vitesse, and Vitesse does not have the diff --git a/sys/dev/smbus/smb.c b/sys/dev/smbus/smb.c index 5f6eff039628..262973340b20 100644 --- a/sys/dev/smbus/smb.c +++ b/sys/dev/smbus/smb.c @@ -47,9 +47,7 @@ struct smb_softc { device_t sc_dev; - int sc_count; /* >0 if device opened */ struct cdev *sc_devnode; - struct mtx sc_lock; }; static void smb_identify(driver_t *driver, device_t parent); @@ -78,15 +76,11 @@ static driver_t smb_driver = { sizeof(struct smb_softc), }; -static d_open_t smbopen; -static d_close_t smbclose; static d_ioctl_t smbioctl; static struct cdevsw smb_cdevsw = { .d_version = D_VERSION, .d_flags = D_TRACKCLOSE, - .d_open = smbopen, - .d_close = smbclose, .d_ioctl = smbioctl, .d_name = "smb", }; @@ -112,59 +106,31 @@ smb_probe(device_t dev) static int smb_attach(device_t dev) { - struct smb_softc *sc = device_get_softc(dev); - int unit; - - unit = device_get_unit(dev); + struct smb_softc *sc; + struct make_dev_args mda; + int error; + + sc = device_get_softc(dev); sc->sc_dev = dev; - sc->sc_devnode = make_dev(&smb_cdevsw, unit, UID_ROOT, GID_WHEEL, - 0600, "smb%d", unit); - sc->sc_devnode->si_drv1 = sc; - mtx_init(&sc->sc_lock, device_get_nameunit(dev), NULL, MTX_DEF); - - return (0); + make_dev_args_init(&mda); + mda.mda_devsw = &smb_cdevsw; + mda.mda_unit = device_get_unit(dev); + mda.mda_uid = UID_ROOT; + mda.mda_gid = GID_WHEEL; + mda.mda_mode = 0600; + mda.mda_si_drv1 = sc; + error = make_dev_s(&mda, &sc->sc_devnode, "smb%d", mda.mda_unit); + return (error); } static int smb_detach(device_t dev) { - struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev); - - if (sc->sc_devnode) - destroy_dev(sc->sc_devnode); - mtx_destroy(&sc->sc_lock); - - return (0); -} - -static int -smbopen(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - struct smb_softc *sc = dev->si_drv1; - - mtx_lock(&sc->sc_lock); - if (sc->sc_count != 0) { - mtx_unlock(&sc->sc_lock); - return (EBUSY); - } - - sc->sc_count++; - mtx_unlock(&sc->sc_lock); - - return (0); -} - -static int -smbclose(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - struct smb_softc *sc = dev->si_drv1; - - mtx_lock(&sc->sc_lock); - KASSERT(sc->sc_count == 1, ("device not busy")); - sc->sc_count--; - mtx_unlock(&sc->sc_lock); + struct smb_softc *sc; + sc = device_get_softc(dev); + destroy_dev(sc->sc_devnode); return (0); } diff --git a/sys/dev/smbus/smbconf.h b/sys/dev/smbus/smbconf.h index ceb80aca267c..e994606c549c 100644 --- a/sys/dev/smbus/smbconf.h +++ b/sys/dev/smbus/smbconf.h @@ -25,8 +25,8 @@ * * $FreeBSD$ */ -#ifndef __SMBONF_H -#define __SMBONF_H +#ifndef __DEV_SMBUS_SMBCONF_H +#define __DEV_SMBUS_SMBCONF_H #include @@ -124,4 +124,4 @@ extern devclass_t smbus_devclass; #define SMBUS_MAXVER 1 #define SMBUS_PREFVER SMBUS_MODVER -#endif +#endif /* __DEV_SMBUS_SMBCONF_H */ diff --git a/sys/dev/smc/if_smc.c b/sys/dev/smc/if_smc.c index db76a9d79411..ecb97c4fa5c0 100644 --- a/sys/dev/smc/if_smc.c +++ b/sys/dev/smc/if_smc.c @@ -782,7 +782,7 @@ smc_task_rx(void *context, int pending) } #ifdef DEVICE_POLLING -static void +static int smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct smc_softc *sc; @@ -792,12 +792,13 @@ smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) SMC_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { SMC_UNLOCK(sc); - return; + return (0); } SMC_UNLOCK(sc); if (cmd == POLL_AND_CHECK_STATUS) taskqueue_enqueue(sc->smc_tq, &sc->smc_intr); + return (0); } #endif diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 4726edd78410..a41e44831253 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -175,6 +175,7 @@ static const struct { { HDA_NVIDIA_ALL, "NVIDIA", 0, 0 }, { HDA_ATI_ALL, "ATI", 0, 0 }, { HDA_AMD_ALL, "AMD", 0, 0 }, + { HDA_CREATIVE_ALL, "Creative", 0, 0 }, { HDA_VIA_ALL, "VIA", 0, 0 }, { HDA_SIS_ALL, "SiS", 0, 0 }, { HDA_ULI_ALL, "ULI", 0, 0 }, diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h index d20501a72024..0adc6ddce85f 100644 --- a/sys/dev/sound/pci/hda/hdac.h +++ b/sys/dev/sound/pci/hda/hdac.h @@ -150,6 +150,10 @@ #define RDC_VENDORID 0x17f3 #define HDA_RDC_M3010 HDA_MODEL_CONSTRUCT(RDC, 0x3010) +/* Creative */ +#define CREATIVE_VENDORID 0x1102 +#define HDA_CREATIVE_ALL HDA_MODEL_CONSTRUCT(CREATIVE, 0xffff) + /* VIA */ #define VIA_VENDORID 0x1106 #define HDA_VIA_VT82XX HDA_MODEL_CONSTRUCT(VIA, 0x3288) diff --git a/sys/dev/syscons/sysmouse.c b/sys/dev/syscons/sysmouse.c index 3582ad584a82..8ea0939eb575 100644 --- a/sys/dev/syscons/sysmouse.c +++ b/sys/dev/syscons/sysmouse.c @@ -107,11 +107,11 @@ smdev_evdev_write(int x, int y, int z, int buttons) } break; case EVDEV_SYSMOUSE_T_AXIS_UMS: - /* XXX: Edge triggering should be used here */ - if (buttons & (1 << 5)) + if (buttons & (1 << 6)) evdev_push_rel(sysmouse_evdev, REL_HWHEEL, 1); - else if (buttons & (1 << 6)) + else if (buttons & (1 << 5)) evdev_push_rel(sysmouse_evdev, REL_HWHEEL, -1); + buttons &= ~((1 << 5)|(1 << 6)); /* PASSTHROUGH */ case EVDEV_SYSMOUSE_T_AXIS_NONE: default: diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index d3f15feb837a..421f5fd16145 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -1621,7 +1621,7 @@ ti_newbuf_jumbo(struct ti_softc *sc, int idx, struct mbuf *m_old) } sf[i] = sf_buf_alloc(frame, SFB_NOWAIT); if (sf[i] == NULL) { - vm_page_unwire(frame, PQ_INACTIVE); + vm_page_unwire(frame, PQ_NONE); vm_page_free(frame); device_printf(sc->ti_dev, "buffer allocation " "failed -- packet dropped!\n"); diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index dbb013c3e955..7072f4e6f9e4 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -873,7 +873,7 @@ ns8250_bus_probe(struct uart_softc *sc) count = 0; goto describe; } - } while ((lsr & LSR_OE) == 0 && count < 130); + } while ((lsr & LSR_OE) == 0 && count < 260); count--; uart_setreg(bas, REG_MCR, mcr); @@ -894,6 +894,9 @@ ns8250_bus_probe(struct uart_softc *sc) } else if (count >= 112 && count <= 128) { sc->sc_rxfifosz = 128; device_set_desc(sc->sc_dev, "16950 or compatible"); + } else if (count >= 224 && count <= 256) { + sc->sc_rxfifosz = 256; + device_set_desc(sc->sc_dev, "16x50 with 256 byte FIFO"); } else { sc->sc_rxfifosz = 16; device_set_desc(sc->sc_dev, diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c index f9571f2108fe..c393f31a94e7 100644 --- a/sys/dev/usb/input/ums.c +++ b/sys/dev/usb/input/ums.c @@ -296,7 +296,7 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) if ((info->sc_flags & UMS_FLAG_T_AXIS) && (id == info->sc_iid_t)) { - dt -= hid_get_data(buf, len, &info->sc_loc_t); + dt += hid_get_data(buf, len, &info->sc_loc_t); /* T-axis is translated into button presses */ buttons_found |= (1UL << 5) | (1UL << 6); } @@ -332,10 +332,10 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) /* translate T-axis into button presses until further */ if (dt > 0) { ums_put_queue(sc, 0, 0, 0, 0, buttons); - buttons |= 1UL << 5; + buttons |= 1UL << 6; } else if (dt < 0) { ums_put_queue(sc, 0, 0, 0, 0, buttons); - buttons |= 1UL << 6; + buttons |= 1UL << 5; } sc->sc_status.button = buttons; diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c index f8f7a4b6f44a..907f74c19757 100644 --- a/sys/dev/usb/misc/udbp.c +++ b/sys/dev/usb/misc/udbp.c @@ -264,6 +264,7 @@ static const STRUCT_USB_HOST_ID udbp_devs[] = { {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_GADGETZERO, 0)}, {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, 0)}, {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, 0)}, + {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL27A1, 0)}, {USB_VPI(USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, 0)}, {USB_VPI(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB, 0)}, }; diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index 375ab5f21894..1b4c2e353740 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -1568,8 +1568,9 @@ smsc_fdt_find_eth_node(phandle_t start) /* Traverse through entire tree to find usb ethernet nodes. */ for (node = OF_child(start); node != 0; node = OF_peer(node)) { - if (ofw_bus_node_is_compatible(node, "net,ethernet") && - ofw_bus_node_is_compatible(node, "usb,device")) + if ((ofw_bus_node_is_compatible(node, "net,ethernet") && + ofw_bus_node_is_compatible(node, "usb,device")) || + ofw_bus_node_is_compatible(node, "usb424,ec00")) return (node); child = smsc_fdt_find_eth_node(node); if (child != -1) @@ -1636,6 +1637,37 @@ smsc_fdt_find_eth_node_by_path(phandle_t start) return (-1); } +/* + * Look through known names that can contain mac address + * return 0 if valid MAC address has been found + */ +static int +smsc_fdt_read_mac_property(phandle_t node, unsigned char *mac) +{ + int len; + + /* Check if there is property */ + if ((len = OF_getproplen(node, "local-mac-address")) > 0) { + if (len != ETHER_ADDR_LEN) + return (EINVAL); + + OF_getprop(node, "local-mac-address", mac, + ETHER_ADDR_LEN); + return (0); + } + + if ((len = OF_getproplen(node, "mac-address")) > 0) { + if (len != ETHER_ADDR_LEN) + return (EINVAL); + + OF_getprop(node, "mac-address", mac, + ETHER_ADDR_LEN); + return (0); + } + + return (ENXIO); +} + /** * Get MAC address from FDT blob. Firmware or loader should fill * mac-address or local-mac-address property. Returns 0 if MAC address @@ -1645,37 +1677,22 @@ static int smsc_fdt_find_mac(unsigned char *mac) { phandle_t node, root; - int len; root = OF_finddevice("/"); node = smsc_fdt_find_eth_node(root); + if (node != -1) { + if (smsc_fdt_read_mac_property(node, mac) == 0) + return (0); + } + /* * If it's not FreeBSD FDT blob for RPi, try more * generic .../usb/hub/ethernet */ - if (node == -1) - node = smsc_fdt_find_eth_node_by_path(root); + node = smsc_fdt_find_eth_node_by_path(root); - if (node != -1) { - /* Check if there is property */ - if ((len = OF_getproplen(node, "local-mac-address")) > 0) { - if (len != ETHER_ADDR_LEN) - return (EINVAL); - - OF_getprop(node, "local-mac-address", mac, - ETHER_ADDR_LEN); - return (0); - } - - if ((len = OF_getproplen(node, "mac-address")) > 0) { - if (len != ETHER_ADDR_LEN) - return (EINVAL); - - OF_getprop(node, "mac-address", mac, - ETHER_ADDR_LEN); - return (0); - } - } + if (node != -1) + return smsc_fdt_read_mac_property(node, mac); return (ENXIO); } diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c index 59fa71f215d6..d58b1fc6837f 100644 --- a/sys/dev/usb/net/if_ure.c +++ b/sys/dev/usb/net/if_ure.c @@ -67,6 +67,7 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0, */ static const STRUCT_USB_HOST_ID ure_devs[] = { #define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } + URE_DEV(LENOVO, RTL8153, 0), URE_DEV(REALTEK, RTL8152, URE_FLAG_8152), URE_DEV(REALTEK, RTL8153, 0), #undef URE_DEV diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 9a57d5c697e0..75bb6e863093 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -236,6 +236,8 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(DLINK, DWR510, 0), U3G_DEV(DLINK, DWM157_CD, U3GINIT_SCSIEJECT), U3G_DEV(DLINK, DWM157, 0), + U3G_DEV(DLINK, DWM222_CD, U3GINIT_SCSIEJECT), + U3G_DEV(DLINK, DWM222, 0), U3G_DEV(DLINK3, DWM652, 0), U3G_DEV(HP, EV2200, 0), U3G_DEV(HP, HS2300, 0), diff --git a/sys/dev/usb/template/usb_template_audio.c b/sys/dev/usb/template/usb_template_audio.c index 7c7cebe33367..ccf50937e317 100644 --- a/sys/dev/usb/template/usb_template_audio.c +++ b/sys/dev/usb/template/usb_template_audio.c @@ -199,8 +199,8 @@ static const void *audio_raw_iface_0_desc[] = { static const struct usb_temp_interface_desc audio_iface_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = audio_raw_iface_0_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 1, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL, .bInterfaceProtocol = 0, .iInterface = INDEX_AUDIO_MIXER, }; @@ -257,8 +257,8 @@ static const struct usb_temp_endpoint_desc *audio_iface_1_ep[] = { static const struct usb_temp_interface_desc audio_iface_1_alt_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = NULL, /* no raw descriptors */ - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_AUDIO_PLAYBACK, }; @@ -266,8 +266,8 @@ static const struct usb_temp_interface_desc audio_iface_1_alt_0 = { static const struct usb_temp_interface_desc audio_iface_1_alt_1 = { .ppEndpoints = audio_iface_1_ep, .ppRawDesc = audio_raw_iface_1_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_AUDIO_PLAYBACK, .isAltInterface = 1, /* this is an alternate setting */ @@ -315,8 +315,8 @@ static const struct usb_temp_endpoint_desc *audio_iface_2_ep[] = { static const struct usb_temp_interface_desc audio_iface_2_alt_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = NULL, /* no raw descriptors */ - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_AUDIO_RECORD, }; @@ -324,8 +324,8 @@ static const struct usb_temp_interface_desc audio_iface_2_alt_0 = { static const struct usb_temp_interface_desc audio_iface_2_alt_1 = { .ppEndpoints = audio_iface_2_ep, .ppRawDesc = audio_raw_iface_2_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_AUDIO_RECORD, .isAltInterface = 1, /* this is an alternate setting */ diff --git a/sys/dev/usb/template/usb_template_kbd.c b/sys/dev/usb/template/usb_template_kbd.c index 306b2fee155c..25d4d17d9fa0 100644 --- a/sys/dev/usb/template/usb_template_kbd.c +++ b/sys/dev/usb/template/usb_template_kbd.c @@ -130,9 +130,9 @@ static const void *keyboard_iface_0_desc[] = { static const struct usb_temp_interface_desc keyboard_iface_0 = { .ppRawDesc = keyboard_iface_0_desc, .ppEndpoints = keyboard_endpoints, - .bInterfaceClass = 3, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, + .bInterfaceClass = UICLASS_HID, + .bInterfaceSubClass = UISUBCLASS_BOOT, + .bInterfaceProtocol = UIPROTO_BOOT_KEYBOARD, .iInterface = INDEX_KEYBOARD, }; diff --git a/sys/dev/usb/template/usb_template_midi.c b/sys/dev/usb/template/usb_template_midi.c index 9be1b9e5a18c..923137e63ef3 100644 --- a/sys/dev/usb/template/usb_template_midi.c +++ b/sys/dev/usb/template/usb_template_midi.c @@ -89,8 +89,8 @@ static const void *midi_descs_0[] = { static const struct usb_temp_interface_desc midi_iface_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = midi_descs_0, - .bInterfaceClass = 1, - .bInterfaceSubClass = 1, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL, .bInterfaceProtocol = 0, .iInterface = INDEX_MIDI_IF, }; @@ -171,8 +171,8 @@ static const void *midi_descs_1[] = { static const struct usb_temp_interface_desc midi_iface_1 = { .ppRawDesc = midi_descs_1, .ppEndpoints = midi_iface_1_ep, - .bInterfaceClass = 0x01, /* MIDI */ - .bInterfaceSubClass = 3, /* MIDI streaming */ + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_MIDISTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_MIDI_IF, }; diff --git a/sys/dev/usb/template/usb_template_modem.c b/sys/dev/usb/template/usb_template_modem.c index 6a976f7cbf17..cf520eff3a1b 100644 --- a/sys/dev/usb/template/usb_template_modem.c +++ b/sys/dev/usb/template/usb_template_modem.c @@ -156,17 +156,17 @@ static const void *modem_iface_0_desc[] = { static const struct usb_temp_interface_desc modem_iface_0 = { .ppRawDesc = modem_iface_0_desc, .ppEndpoints = modem_iface_0_ep, - .bInterfaceClass = 2, - .bInterfaceSubClass = 2, - .bInterfaceProtocol = 1, + .bInterfaceClass = UICLASS_CDC, + .bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = UIPROTO_CDC_AT, .iInterface = INDEX_MODEM, }; static const struct usb_temp_interface_desc modem_iface_1 = { .ppEndpoints = modem_iface_1_ep, - .bInterfaceClass = 10, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, + .bInterfaceClass = UICLASS_CDC_DATA, + .bInterfaceSubClass = UISUBCLASS_DATA, + .bInterfaceProtocol = UIPROTO_CDC_NONE, .iInterface = INDEX_MODEM, }; diff --git a/sys/dev/usb/template/usb_template_mouse.c b/sys/dev/usb/template/usb_template_mouse.c index a48ccf4d61d6..215cede76005 100644 --- a/sys/dev/usb/template/usb_template_mouse.c +++ b/sys/dev/usb/template/usb_template_mouse.c @@ -128,9 +128,9 @@ static const void *mouse_iface_0_desc[] = { static const struct usb_temp_interface_desc mouse_iface_0 = { .ppRawDesc = mouse_iface_0_desc, .ppEndpoints = mouse_endpoints, - .bInterfaceClass = 3, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 2, + .bInterfaceClass = UICLASS_HID, + .bInterfaceSubClass = UISUBCLASS_BOOT, + .bInterfaceProtocol = UIPROTO_MOUSE, .iInterface = INDEX_MOUSE, }; diff --git a/sys/dev/usb/template/usb_template_phone.c b/sys/dev/usb/template/usb_template_phone.c index c58103e9b444..149c7fa517fb 100644 --- a/sys/dev/usb/template/usb_template_phone.c +++ b/sys/dev/usb/template/usb_template_phone.c @@ -156,8 +156,8 @@ static const void *phone_raw_iface_0_desc[] = { static const struct usb_temp_interface_desc phone_iface_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = phone_raw_iface_0_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 1, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_MIXER, }; @@ -213,8 +213,8 @@ static const struct usb_temp_endpoint_desc *phone_iface_1_ep[] = { static const struct usb_temp_interface_desc phone_iface_1_alt_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = NULL, /* no raw descriptors */ - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_PLAYBACK, }; @@ -222,8 +222,8 @@ static const struct usb_temp_interface_desc phone_iface_1_alt_0 = { static const struct usb_temp_interface_desc phone_iface_1_alt_1 = { .ppEndpoints = phone_iface_1_ep, .ppRawDesc = phone_raw_iface_1_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_PLAYBACK, .isAltInterface = 1, /* this is an alternate setting */ @@ -270,8 +270,8 @@ static const struct usb_temp_endpoint_desc *phone_iface_2_ep[] = { static const struct usb_temp_interface_desc phone_iface_2_alt_0 = { .ppEndpoints = NULL, /* no endpoints */ .ppRawDesc = NULL, /* no raw descriptors */ - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_RECORD, }; @@ -279,8 +279,8 @@ static const struct usb_temp_interface_desc phone_iface_2_alt_0 = { static const struct usb_temp_interface_desc phone_iface_2_alt_1 = { .ppEndpoints = phone_iface_2_ep, .ppRawDesc = phone_raw_iface_2_desc, - .bInterfaceClass = 1, - .bInterfaceSubClass = 2, + .bInterfaceClass = UICLASS_AUDIO, + .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_RECORD, .isAltInterface = 1, /* this is an alternate setting */ @@ -321,7 +321,7 @@ static const struct usb_temp_endpoint_desc *phone_iface_3_ep[] = { static const struct usb_temp_interface_desc phone_iface_3 = { .ppEndpoints = phone_iface_3_ep, .ppRawDesc = phone_hid_desc_0, - .bInterfaceClass = 3, + .bInterfaceClass = UICLASS_HID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = INDEX_PHONE_HID, diff --git a/sys/dev/usb/template/usb_template_serialnet.c b/sys/dev/usb/template/usb_template_serialnet.c index beb5e9c4986e..7763fe7574ce 100644 --- a/sys/dev/usb/template/usb_template_serialnet.c +++ b/sys/dev/usb/template/usb_template_serialnet.c @@ -202,7 +202,7 @@ static const struct usb_temp_interface_desc eth_control_interface = { .ppRawDesc = eth_control_if_desc, .bInterfaceClass = UICLASS_CDC, .bInterfaceSubClass = UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, - .bInterfaceProtocol = 0, + .bInterfaceProtocol = UIPROTO_CDC_NONE, .iInterface = STRING_ETH_CONTROL_INDEX, }; @@ -215,7 +215,7 @@ static const struct usb_temp_endpoint_desc *eth_data_endpoints[] = { static const struct usb_temp_interface_desc eth_data_null_interface = { .ppEndpoints = NULL, /* no endpoints */ .bInterfaceClass = UICLASS_CDC_DATA, - .bInterfaceSubClass = 0, + .bInterfaceSubClass = UISUBCLASS_DATA, .bInterfaceProtocol = 0, .iInterface = STRING_ETH_DATA_INDEX, }; @@ -304,16 +304,16 @@ static const void *modem_iface_0_desc[] = { static const struct usb_temp_interface_desc modem_iface_0 = { .ppRawDesc = modem_iface_0_desc, .ppEndpoints = modem_iface_0_ep, - .bInterfaceClass = 2, - .bInterfaceSubClass = 2, - .bInterfaceProtocol = 1, + .bInterfaceClass = UICLASS_CDC, + .bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = UIPROTO_CDC_AT, .iInterface = STRING_MODEM_INDEX, }; static const struct usb_temp_interface_desc modem_iface_1 = { .ppEndpoints = modem_iface_1_ep, - .bInterfaceClass = 10, - .bInterfaceSubClass = 0, + .bInterfaceClass = UICLASS_CDC_DATA, + .bInterfaceSubClass = UISUBCLASS_DATA, .bInterfaceProtocol = 0, .iInterface = STRING_MODEM_INDEX, }; diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 3f5f5e1cba0f..624bb381670b 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -100,7 +100,9 @@ SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RWTUN, #if USB_HAVE_DISABLE_ENUM static int usb_disable_enumeration = 0; SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN, - &usb_disable_enumeration, 0, "Set to disable all USB device enumeration."); + &usb_disable_enumeration, 0, "Set to disable all USB device enumeration. " + "This can secure against USB devices turning evil, " + "for example a USB memory stick becoming a USB keyboard."); static int usb_disable_port_power = 0; SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN, diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index eb3557dfd313..905597ef4e2a 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1673,8 +1673,10 @@ product DLINK DSB650TX2 0x4102 10/100 Ethernet product DLINK DUB1312 0x4a00 10/100/1000 Ethernet product DLINK DWM157 0x7d02 DWM-157 product DLINK DWR510 0x7e12 DWR-510 +product DLINK DWM222 0x7e35 DWM-222 product DLINK DWM157_CD 0xa707 DWM-157 CD-ROM Mode product DLINK DWR510_CD 0xa805 DWR-510 CD-ROM Mode +product DLINK DWM222_CD 0xab00 DWM-222 CD-ROM Mode product DLINK DSB650 0xabc1 10/100 Ethernet product DLINK DUBH7 0xf103 DUB-H7 USB 2.0 7-Port Hub product DLINK2 RTL8192SU_1 0x3300 RTL8192SU @@ -2703,6 +2705,7 @@ product LEADTEK 9531 0x2101 9531 GPS /* Lenovo products */ product LENOVO GIGALAN 0x304b USB 3.0 Ethernet product LENOVO ETHERNET 0x7203 USB 2.0 Ethernet +product LENOVO RTL8153 0x7205 USB 3.0 Ethernet /* Lexar products */ product LEXAR JUMPSHOT 0x0001 jumpSHOT CompactFlash Reader @@ -3676,6 +3679,7 @@ product PROLIFIC PL2305 0x2305 Parallel printer product PROLIFIC ATAPI4 0x2307 ATAPI-4 Controller product PROLIFIC PL2501 0x2501 PL2501 Host-Host interface product PROLIFIC PL2506 0x2506 PL2506 USB to IDE Bridge +product PROLIFIC PL27A1 0x27A1 PL27A1 USB 3.0 Host-Host interface product PROLIFIC HCR331 0x331a HCR331 Hybrid Card Reader product PROLIFIC PHAROS 0xaaa0 Prolific Pharos product PROLIFIC RSAQ3 0xaaa2 PL2303 Serial Adapter (IODATA USB-RSAQ3) @@ -4533,6 +4537,8 @@ product TOSHIBA TRANSMEMORY 0x6545 USB ThumbDrive product TPLINK T4U 0x0101 Archer T4U product TPLINK WN822NV4 0x0108 TL-WN822N v4 product TPLINK WN823NV2 0x0109 TL-WN823N v2 +product TPLINK T4UV2 0x010d Archer T4U ver 2 +product TPLINK T4UHV2 0x010e Archer T4UH ver 2 /* Trek Technology products */ product TREK THUMBDRIVE 0x1111 ThumbDrive diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 0751618022a0..49eaee2b6aea 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -68,8 +68,11 @@ __FBSDID("$FreeBSD$"); #include #include "usbdevs.h" +#include /* XXX */ #include +#define RSU_RATE_IS_CCK RTWN_RATE_IS_CCK + #ifdef USB_DEBUG static int rsu_debug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, rsu, CTLFLAG_RW, 0, "USB rsu"); @@ -2382,44 +2385,6 @@ rsu_rx_frame(struct rsu_softc *sc, struct mbuf *m) rssi = rsu_hwrssi_to_rssi(sc, sc->sc_currssi); } - if (ieee80211_radiotap_active(ic)) { - struct rsu_rx_radiotap_header *tap = &sc->sc_rxtap; - - /* Map HW rate index to 802.11 rate. */ - tap->wr_flags = 0; /* TODO */ - tap->wr_tsft = rsu_get_tsf_high(sc); - if (le32toh(stat->tsf_low) > rsu_get_tsf_low(sc)) - tap->wr_tsft--; - tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32; - tap->wr_tsft += stat->tsf_low; - - if (rate < 12) { - switch (rate) { - /* CCK. */ - case 0: tap->wr_rate = 2; break; - case 1: tap->wr_rate = 4; break; - case 2: tap->wr_rate = 11; break; - case 3: tap->wr_rate = 22; break; - /* OFDM. */ - case 4: tap->wr_rate = 12; break; - case 5: tap->wr_rate = 18; break; - case 6: tap->wr_rate = 24; break; - case 7: tap->wr_rate = 36; break; - case 8: tap->wr_rate = 48; break; - case 9: tap->wr_rate = 72; break; - case 10: tap->wr_rate = 96; break; - case 11: tap->wr_rate = 108; break; - } - } else { /* MCS0~15. */ - /* Bit 7 set means HT MCS instead of rate. */ - tap->wr_rate = 0x80 | (rate - 12); - } - - tap->wr_dbm_antsignal = rssi; - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - }; - /* Hardware does Rx TCP checksum offload. */ /* * This flag can be set for some other @@ -2465,65 +2430,34 @@ rsu_rx_frame(struct rsu_softc *sc, struct mbuf *m) rxs.c_nf = -96; /* Rate */ - if (!(rxdw3 & R92S_RXDW3_HTC)) { - switch (rate) { - /* CCK. */ - case 0: - rxs.c_rate = 2; + if (rate < 12) { + rxs.c_rate = ridx2rate[rate]; + if (RSU_RATE_IS_CCK(rate)) rxs.c_pktflags |= IEEE80211_RX_F_CCK; - break; - case 1: - rxs.c_rate = 4; - rxs.c_pktflags |= IEEE80211_RX_F_CCK; - break; - case 2: - rxs.c_rate = 11; - rxs.c_pktflags |= IEEE80211_RX_F_CCK; - break; - case 3: - rxs.c_rate = 22; - rxs.c_pktflags |= IEEE80211_RX_F_CCK; - break; - /* OFDM. */ - case 4: - rxs.c_rate = 12; + else rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 5: - rxs.c_rate = 18; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 6: - rxs.c_rate = 24; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 7: - rxs.c_rate = 36; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 8: - rxs.c_rate = 48; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 9: - rxs.c_rate = 72; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 10: - rxs.c_rate = 96; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - case 11: - rxs.c_rate = 108; - rxs.c_pktflags |= IEEE80211_RX_F_OFDM; - break; - } - } else if (rate >= 12) { /* MCS0~15. */ - /* Bit 7 set means HT MCS instead of rate. */ - rxs.c_rate = (rate - 12); + } else { + rxs.c_rate = IEEE80211_RATE_MCS | (rate - 12); rxs.c_pktflags |= IEEE80211_RX_F_HT; } + if (ieee80211_radiotap_active(ic)) { + struct rsu_rx_radiotap_header *tap = &sc->sc_rxtap; + + /* Map HW rate index to 802.11 rate. */ + tap->wr_flags = 0; /* TODO */ + tap->wr_tsft = rsu_get_tsf_high(sc); + if (le32toh(stat->tsf_low) > rsu_get_tsf_low(sc)) + tap->wr_tsft--; + tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32; + tap->wr_tsft += stat->tsf_low; + + tap->wr_rate = rxs.c_rate; + tap->wr_dbm_antsignal = rssi; + tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + }; + (void) ieee80211_add_rx_params(m, &rxs); /* Drop descriptor. */ diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 470be6fcdead..d667795ff9b1 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -2201,17 +2201,19 @@ uath_sysctl_node(struct uath_softc *sc) #undef UATH_SYSCTL_STAT_ADD32 +CTASSERT(sizeof(u_int) >= sizeof(uint32_t)); + static void uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) { struct uath_cmd_hdr *hdr; - int dlen; + uint32_t dlen; hdr = (struct uath_cmd_hdr *)cmd->buf; /* NB: msgid is passed thru w/o byte swapping */ #ifdef UATH_DEBUG if (sc->sc_debug & UATH_DEBUG_CMDS) { - int len = be32toh(hdr->len); + uint32_t len = be32toh(hdr->len); printf("%s: %s [ix %u] len %u status %u\n", __func__, uath_codename(be32toh(hdr->code)), hdr->msgid, len, be32toh(hdr->magic)); @@ -2227,15 +2229,9 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) switch (hdr->code & 0xff) { /* reply to a read command */ default: - dlen = hdr->len - sizeof(*hdr); - if (dlen < 0) { - device_printf(sc->sc_dev, - "Invalid header length %d\n", dlen); - return; - } DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL, - "%s: code %d data len %u\n", - __func__, hdr->code & 0xff, dlen); + "%s: code %d hdr len %u\n", + __func__, hdr->code & 0xff, hdr->len); /* * The first response from the target after the * HOST_AVAILABLE has an invalid msgid so we must @@ -2245,8 +2241,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) uint32_t *rp = (uint32_t *)(hdr+1); u_int olen; - if (!(sizeof(*hdr) <= hdr->len && - hdr->len < UATH_MAX_CMDSZ)) { + if (sizeof(*hdr) > hdr->len || + hdr->len >= UATH_MAX_CMDSZ) { device_printf(sc->sc_dev, "%s: invalid WDC msg length %u; " "msg ignored\n", __func__, hdr->len); @@ -2258,7 +2254,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) * number of bytes--unless it's 0 in which * case a single 32-bit word should be present. */ - if (dlen >= (int)sizeof(uint32_t)) { + dlen = hdr->len - sizeof(*hdr); + if (dlen >= sizeof(uint32_t)) { olen = be32toh(rp[0]); dlen -= sizeof(uint32_t); if (olen == 0) { @@ -2278,7 +2275,7 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) cmd->olen); olen = cmd->olen; } - if (olen > (u_int)dlen) { + if (olen > dlen) { /* XXX complain, shouldn't happen */ device_printf(sc->sc_dev, "%s: cmd 0x%x olen %u dlen %u\n", @@ -2300,8 +2297,10 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) return; } dlen = hdr->len - sizeof(*hdr); - if (dlen != (int)sizeof(uint32_t)) { - /* XXX something wrong */ + if (dlen != sizeof(uint32_t)) { + device_printf(sc->sc_dev, + "%s: dlen (%u) != %zu!\n", + __func__, dlen, sizeof(uint32_t)); return; } /* XXX have submitter do this */ @@ -2330,6 +2329,7 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct uath_softc *sc = usbd_xfer_softc(xfer); struct uath_cmd *cmd; + struct uath_cmd_hdr *hdr; struct usb_page_cache *pc; int actlen; @@ -2347,10 +2347,25 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error) STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next); UATH_STAT_INC(sc, st_cmd_inactive); - KASSERT(actlen >= (int)sizeof(struct uath_cmd_hdr), - ("short xfer error")); + if (actlen < sizeof(struct uath_cmd_hdr)) { + device_printf(sc->sc_dev, + "%s: short xfer error (actlen %d)\n", + __func__, actlen); + goto setup; + } + pc = usbd_xfer_get_frame(xfer, 0); usbd_copy_out(pc, 0, cmd->buf, actlen); + + hdr = (struct uath_cmd_hdr *)cmd->buf; + hdr->len = be32toh(hdr->len); + if (hdr->len > (uint32_t)actlen) { + device_printf(sc->sc_dev, + "%s: truncated xfer (len %u, actlen %d)\n", + __func__, hdr->len, actlen); + goto setup; + } + uath_cmdeof(sc, cmd); case USB_ST_SETUP: setup: @@ -2451,6 +2466,8 @@ uath_update_rxstat(struct uath_softc *sc, uint32_t status) } } +CTASSERT(UATH_MIN_RXBUFSZ >= sizeof(struct uath_chunk)); + static struct mbuf * uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, struct uath_rx_desc **pdesc) @@ -2473,13 +2490,24 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, } chunk = (struct uath_chunk *)data->buf; - if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) { + chunklen = be16toh(chunk->length); + if (chunk->seqnum == 0 && chunk->flags == 0 && chunklen == 0) { device_printf(sc->sc_dev, "%s: strange response\n", __func__); counter_u64_add(ic->ic_ierrors, 1); UATH_RESET_INTRX(sc); return (NULL); } + if (chunklen > actlen) { + device_printf(sc->sc_dev, + "%s: invalid chunk length (len %u > actlen %d)\n", + __func__, chunklen, actlen); + counter_u64_add(ic->ic_ierrors, 1); + /* XXX cleanup? */ + UATH_RESET_INTRX(sc); + return (NULL); + } + if (chunk->seqnum != sc->sc_intrx_nextnum) { DPRINTF(sc, UATH_DEBUG_XMIT, "invalid seqnum %d, expected %d\n", chunk->seqnum, sc->sc_intrx_nextnum); @@ -2496,9 +2524,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, chunk->flags & UATH_CFLAGS_RXMSG) UATH_STAT_INC(sc, st_multichunk); - chunklen = be16toh(chunk->length); - if (chunk->flags & UATH_CFLAGS_FINAL) + if (chunk->flags & UATH_CFLAGS_FINAL) { + if (chunklen < sizeof(struct uath_rx_desc)) { + device_printf(sc->sc_dev, + "%s: invalid chunk length %d\n", + __func__, chunklen); + counter_u64_add(ic->ic_ierrors, 1); + if (sc->sc_intrx_head != NULL) + m_freem(sc->sc_intrx_head); + UATH_RESET_INTRX(sc); + return (NULL); + } chunklen -= sizeof(struct uath_rx_desc); + } if (chunklen > 0 && (!(chunk->flags & UATH_CFLAGS_FINAL) || !(chunk->seqnum == 0))) { @@ -2559,6 +2597,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, (struct uath_rx_desc *)(((uint8_t *)chunk) + sizeof(struct uath_chunk) + be16toh(chunk->length) - sizeof(struct uath_rx_desc)); + if ((uint8_t *)chunk + actlen - sizeof(struct uath_rx_desc) < + (uint8_t *)desc) { + device_printf(sc->sc_dev, + "%s: wrong Rx descriptor pointer " + "(desc %p chunk %p actlen %d)\n", + __func__, desc, chunk, actlen); + counter_u64_add(ic->ic_ierrors, 1); + if (sc->sc_intrx_head != NULL) + m_freem(sc->sc_intrx_head); + UATH_RESET_INTRX(sc); + return (NULL); + } + *pdesc = desc; DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL, @@ -2586,8 +2637,33 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, /* finalize mbuf */ if (sc->sc_intrx_head == NULL) { - m->m_pkthdr.len = m->m_len = - be32toh(desc->framelen) - UATH_RX_DUMMYSIZE; + uint32_t framelen; + + if (be32toh(desc->framelen) < UATH_RX_DUMMYSIZE) { + device_printf(sc->sc_dev, + "%s: framelen too small (%u)\n", + __func__, be32toh(desc->framelen)); + counter_u64_add(ic->ic_ierrors, 1); + if (sc->sc_intrx_head != NULL) + m_freem(sc->sc_intrx_head); + UATH_RESET_INTRX(sc); + return (NULL); + } + + framelen = be32toh(desc->framelen) - UATH_RX_DUMMYSIZE; + if (framelen > actlen - sizeof(struct uath_chunk) || + framelen < sizeof(struct ieee80211_frame_ack)) { + device_printf(sc->sc_dev, + "%s: wrong frame length (%u, actlen %d)!\n", + __func__, framelen, actlen); + counter_u64_add(ic->ic_ierrors, 1); + if (sc->sc_intrx_head != NULL) + m_freem(sc->sc_intrx_head); + UATH_RESET_INTRX(sc); + return (NULL); + } + + m->m_pkthdr.len = m->m_len = framelen; m->m_data += sizeof(struct uath_chunk); } else { mp = sc->sc_intrx_head; diff --git a/sys/dev/vt/vt_sysmouse.c b/sys/dev/vt/vt_sysmouse.c index 78e85ab65ec9..019050b7694e 100644 --- a/sys/dev/vt/vt_sysmouse.c +++ b/sys/dev/vt/vt_sysmouse.c @@ -139,11 +139,11 @@ sysmouse_evdev_store(int x, int y, int z, int buttons) } break; case EVDEV_SYSMOUSE_T_AXIS_UMS: - /* XXX: Edge triggering should be used here */ - if (buttons & (1 << 5)) + if (buttons & (1 << 6)) evdev_push_rel(sysmouse_evdev, REL_HWHEEL, 1); - else if (buttons & (1 << 6)) + else if (buttons & (1 << 5)) evdev_push_rel(sysmouse_evdev, REL_HWHEEL, -1); + buttons &= ~((1 << 5)|(1 << 6)); /* PASSTHROUGH */ case EVDEV_SYSMOUSE_T_AXIS_NONE: default: diff --git a/sys/dev/wb/if_wb.c b/sys/dev/wb/if_wb.c index ca66226dd898..aa882f0d26c0 100644 --- a/sys/dev/wb/if_wb.c +++ b/sys/dev/wb/if_wb.c @@ -143,7 +143,7 @@ static int wb_probe(device_t); static int wb_attach(device_t); static int wb_detach(device_t); -static void wb_bfree(struct mbuf *, void *addr, void *args); +static void wb_bfree(struct mbuf *); static int wb_newbuf(struct wb_softc *, struct wb_chain_onefrag *, struct mbuf *); static int wb_encap(struct wb_softc *, struct wb_chain *, struct mbuf *); @@ -824,7 +824,7 @@ wb_list_rx_init(sc) } static void -wb_bfree(struct mbuf *m, void *buf, void *args) +wb_bfree(struct mbuf *m) { } @@ -843,10 +843,9 @@ wb_newbuf(sc, c, m) MGETHDR(m_new, M_NOWAIT, MT_DATA); if (m_new == NULL) return(ENOBUFS); - m_new->m_data = c->wb_buf; m_new->m_pkthdr.len = m_new->m_len = WB_BUFBYTES; - MEXTADD(m_new, c->wb_buf, WB_BUFBYTES, wb_bfree, c->wb_buf, - NULL, 0, EXT_NET_DRV); + m_extadd(m_new, c->wb_buf, WB_BUFBYTES, wb_bfree, NULL, NULL, + 0, EXT_NET_DRV); } else { m_new = m; m_new->m_len = m_new->m_pkthdr.len = WB_BUFBYTES; diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 651b5a3218a9..9f54a8c09878 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -783,6 +783,9 @@ cd9660_pathconf(ap) { switch (ap->a_name) { + case _PC_FILESIZEBITS: + *ap->a_retval = 32; + return (0); case _PC_LINK_MAX: *ap->a_retval = 1; return (0); @@ -792,6 +795,12 @@ cd9660_pathconf(ap) else *ap->a_retval = 37; return (0); + case _PC_SYMLINK_MAX: + if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) { + *ap->a_retval = MAXPATHLEN; + return (0); + } + return (EINVAL); case _PC_NO_TRUNC: *ap->a_retval = 1; return (0); diff --git a/sys/fs/cuse/cuse.c b/sys/fs/cuse/cuse.c index 79a2d1b2d020..a50633fa5cb4 100644 --- a/sys/fs/cuse/cuse.c +++ b/sys/fs/cuse/cuse.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /*- - * Copyright (c) 2010-2013 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2010-2017 Hans Petter Selasky. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,9 @@ #include #include +#include +#include +#include #include #include @@ -69,8 +73,6 @@ MODULE_VERSION(cuse, 1); */ MODULE_VERSION(cuse4bsd, 1); -#define NBUSY ((uint8_t *)1) - #ifdef FEATURE FEATURE(cuse, "Userspace character devices"); #endif @@ -94,10 +96,10 @@ struct cuse_client_command { }; struct cuse_memory { - struct cuse_server *owner; - uint8_t *virtaddr; + TAILQ_ENTRY(cuse_memory) entry; + vm_object_t object; uint32_t page_count; - uint32_t is_allocated; + uint32_t alloc_nr; }; struct cuse_server_dev { @@ -112,6 +114,7 @@ struct cuse_server { TAILQ_HEAD(, cuse_client_command) head; TAILQ_HEAD(, cuse_server_dev) hdev; TAILQ_HEAD(, cuse_client) hcli; + TAILQ_HEAD(, cuse_memory) hmem; struct cv cv; struct selinfo selinfo; pid_t pid; @@ -128,8 +131,8 @@ struct cuse_client { uint8_t ioctl_buffer[CUSE_BUFFER_MAX] __aligned(4); - int fflags; /* file flags */ - int cflags; /* client flags */ + int fflags; /* file flags */ + int cflags; /* client flags */ #define CUSE_CLI_IS_CLOSING 0x01 #define CUSE_CLI_KNOTE_NEED_READ 0x02 #define CUSE_CLI_KNOTE_NEED_WRITE 0x04 @@ -140,14 +143,13 @@ struct cuse_client { #define CUSE_CLIENT_CLOSING(pcc) \ ((pcc)->cflags & CUSE_CLI_IS_CLOSING) -static MALLOC_DEFINE(M_CUSE, "cuse", "CUSE memory"); +static MALLOC_DEFINE(M_CUSE, "cuse", "CUSE memory"); static TAILQ_HEAD(, cuse_server) cuse_server_head; static struct mtx cuse_mtx; static struct cdev *cuse_dev; static struct cuse_server *cuse_alloc_unit[CUSE_DEVICES_MAX]; static int cuse_alloc_unit_id[CUSE_DEVICES_MAX]; -static struct cuse_memory cuse_mem[CUSE_ALLOC_UNIT_MAX]; static void cuse_server_wakeup_all_client_locked(struct cuse_server *pcs); static void cuse_client_kqfilter_read_detach(struct knote *kn); @@ -173,7 +175,7 @@ static d_ioctl_t cuse_client_ioctl; static d_read_t cuse_client_read; static d_write_t cuse_client_write; static d_poll_t cuse_client_poll; -static d_mmap_t cuse_client_mmap; +static d_mmap_single_t cuse_client_mmap_single; static d_kqfilter_t cuse_client_kqfilter; static struct cdevsw cuse_client_devsw = { @@ -186,7 +188,7 @@ static struct cdevsw cuse_client_devsw = { .d_read = cuse_client_read, .d_write = cuse_client_write, .d_poll = cuse_client_poll, - .d_mmap = cuse_client_mmap, + .d_mmap_single = cuse_client_mmap_single, .d_kqfilter = cuse_client_kqfilter, }; @@ -196,7 +198,7 @@ static d_ioctl_t cuse_server_ioctl; static d_read_t cuse_server_read; static d_write_t cuse_server_write; static d_poll_t cuse_server_poll; -static d_mmap_t cuse_server_mmap; +static d_mmap_single_t cuse_server_mmap_single; static struct cdevsw cuse_server_devsw = { .d_version = D_VERSION, @@ -208,7 +210,7 @@ static struct cdevsw cuse_server_devsw = { .d_read = cuse_server_read, .d_write = cuse_server_write, .d_poll = cuse_server_poll, - .d_mmap = cuse_server_mmap, + .d_mmap_single = cuse_server_mmap_single, }; static void cuse_client_is_closing(struct cuse_client *); @@ -252,7 +254,6 @@ cuse_kern_init(void *arg) (CUSE_VERSION >> 16) & 0xFF, (CUSE_VERSION >> 8) & 0xFF, (CUSE_VERSION >> 0) & 0xFF); } - SYSINIT(cuse_kern_init, SI_SUB_DEVFS, SI_ORDER_ANY, cuse_kern_init, 0); static void @@ -280,7 +281,6 @@ cuse_kern_uninit(void *arg) mtx_destroy(&cuse_mtx); } - SYSUNINIT(cuse_kern_uninit, SI_SUB_DEVFS, SI_ORDER_ANY, cuse_kern_uninit, 0); static int @@ -390,80 +390,88 @@ cuse_convert_error(int error) return (EFAULT); case CUSE_ERR_SIGNAL: return (EINTR); + case CUSE_ERR_NO_DEVICE: + return (ENODEV); default: return (ENXIO); } } static void -cuse_server_free_memory(struct cuse_server *pcs) +cuse_vm_memory_free(struct cuse_memory *mem) { - struct cuse_memory *mem; - uint32_t n; + /* last user is gone - free */ + vm_object_deallocate(mem->object); - for (n = 0; n != CUSE_ALLOC_UNIT_MAX; n++) { - mem = &cuse_mem[n]; - - /* this memory is never freed */ - if (mem->owner == pcs) { - mem->owner = NULL; - mem->is_allocated = 0; - } - } + /* free CUSE memory */ + free(mem, M_CUSE); } static int -cuse_server_alloc_memory(struct cuse_server *pcs, - struct cuse_memory *mem, uint32_t page_count) +cuse_server_alloc_memory(struct cuse_server *pcs, uint32_t alloc_nr, + uint32_t page_count) { - void *ptr; + struct cuse_memory *temp; + struct cuse_memory *mem; + vm_object_t object; int error; - cuse_lock(); + mem = malloc(sizeof(*mem), M_CUSE, M_WAITOK | M_ZERO); + if (mem == NULL) + return (ENOMEM); - if (mem->virtaddr == NBUSY) { - cuse_unlock(); - return (EBUSY); - } - if (mem->virtaddr != NULL) { - if (mem->is_allocated != 0) { - cuse_unlock(); - return (EBUSY); - } - if (mem->page_count == page_count) { - mem->is_allocated = 1; - mem->owner = pcs; - cuse_unlock(); - return (0); - } - cuse_unlock(); - return (EBUSY); - } - memset(mem, 0, sizeof(*mem)); - - mem->virtaddr = NBUSY; - - cuse_unlock(); - - ptr = malloc(page_count * PAGE_SIZE, M_CUSE, M_WAITOK | M_ZERO); - if (ptr == NULL) + object = vm_pager_allocate(OBJT_SWAP, NULL, PAGE_SIZE * page_count, + VM_PROT_DEFAULT, 0, curthread->td_ucred); + if (object == NULL) { error = ENOMEM; - else - error = 0; + goto error_0; + } cuse_lock(); - - if (error) { - mem->virtaddr = NULL; - cuse_unlock(); - return (error); + /* check if allocation number already exists */ + TAILQ_FOREACH(temp, &pcs->hmem, entry) { + if (temp->alloc_nr == alloc_nr) + break; } - mem->virtaddr = ptr; + if (temp != NULL) { + cuse_unlock(); + error = EBUSY; + goto error_1; + } + mem->object = object; mem->page_count = page_count; - mem->is_allocated = 1; - mem->owner = pcs; + mem->alloc_nr = alloc_nr; + TAILQ_INSERT_TAIL(&pcs->hmem, mem, entry); cuse_unlock(); + return (0); + +error_1: + vm_object_deallocate(object); +error_0: + free(mem, M_CUSE); + return (error); +} + +static int +cuse_server_free_memory(struct cuse_server *pcs, uint32_t alloc_nr) +{ + struct cuse_memory *mem; + + cuse_lock(); + TAILQ_FOREACH(mem, &pcs->hmem, entry) { + if (mem->alloc_nr == alloc_nr) + break; + } + if (mem == NULL) { + cuse_unlock(); + return (EINVAL); + } + TAILQ_REMOVE(&pcs->hmem, mem, entry); + cuse_unlock(); + + cuse_vm_memory_free(mem); + return (0); } @@ -644,10 +652,10 @@ cuse_server_free_dev(struct cuse_server_dev *pcsd) } static void -cuse_server_free(void *arg) +cuse_server_unref(struct cuse_server *pcs) { - struct cuse_server *pcs = arg; struct cuse_server_dev *pcsd; + struct cuse_memory *mem; cuse_lock(); pcs->refs--; @@ -670,7 +678,12 @@ cuse_server_free(void *arg) cuse_lock(); } - cuse_server_free_memory(pcs); + while ((mem = TAILQ_FIRST(&pcs->hmem)) != NULL) { + TAILQ_REMOVE(&pcs->hmem, mem, entry); + cuse_unlock(); + cuse_vm_memory_free(mem); + cuse_lock(); + } knlist_clear(&pcs->selinfo.si_note, 1); knlist_destroy(&pcs->selinfo.si_note); @@ -684,6 +697,15 @@ cuse_server_free(void *arg) free(pcs, M_CUSE); } +static void +cuse_server_free(void *arg) +{ + struct cuse_server *pcs = arg; + + /* drop refcount */ + cuse_server_unref(pcs); +} + static int cuse_server_open(struct cdev *dev, int fflags, int devtype, struct thread *td) { @@ -698,13 +720,13 @@ cuse_server_open(struct cdev *dev, int fflags, int devtype, struct thread *td) free(pcs, M_CUSE); return (ENOMEM); } - /* store current process ID */ pcs->pid = curproc->p_pid; TAILQ_INIT(&pcs->head); TAILQ_INIT(&pcs->hdev); TAILQ_INIT(&pcs->hcli); + TAILQ_INIT(&pcs->hmem); cv_init(&pcs->cv, "cuse-server-cv"); @@ -1091,12 +1113,12 @@ cuse_server_ioctl(struct cdev *dev, unsigned long cmd, error = ENOMEM; break; } - if (pai->page_count > CUSE_ALLOC_PAGES_MAX) { + if (pai->page_count >= CUSE_ALLOC_PAGES_MAX) { error = ENOMEM; break; } error = cuse_server_alloc_memory(pcs, - &cuse_mem[pai->alloc_nr], pai->page_count); + pai->alloc_nr, pai->page_count); break; case CUSE_IOCTL_FREE_MEMORY: @@ -1106,16 +1128,7 @@ cuse_server_ioctl(struct cdev *dev, unsigned long cmd, error = ENOMEM; break; } - /* we trust the character device driver in this case */ - - cuse_lock(); - if (cuse_mem[pai->alloc_nr].owner == pcs) { - cuse_mem[pai->alloc_nr].is_allocated = 0; - cuse_mem[pai->alloc_nr].owner = NULL; - } else { - error = EINVAL; - } - cuse_unlock(); + error = cuse_server_free_memory(pcs, pai->alloc_nr); break; case CUSE_IOCTL_GET_SIG: @@ -1274,49 +1287,49 @@ cuse_server_poll(struct cdev *dev, int events, struct thread *td) } static int -cuse_server_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) +cuse_server_mmap_single(struct cdev *dev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **object, int nprot) { - uint32_t page_nr = offset / PAGE_SIZE; + uint32_t page_nr = *offset / PAGE_SIZE; uint32_t alloc_nr = page_nr / CUSE_ALLOC_PAGES_MAX; struct cuse_memory *mem; struct cuse_server *pcs; - uint8_t *ptr; int error; - if (alloc_nr >= CUSE_ALLOC_UNIT_MAX) - return (ENOMEM); - error = cuse_server_get(&pcs); if (error != 0) - pcs = NULL; + return (error); cuse_lock(); - mem = &cuse_mem[alloc_nr]; - - /* try to enforce slight ownership */ - if ((pcs != NULL) && (mem->owner != pcs)) { - cuse_unlock(); - return (EINVAL); + /* lookup memory structure */ + TAILQ_FOREACH(mem, &pcs->hmem, entry) { + if (mem->alloc_nr == alloc_nr) + break; } - if (mem->virtaddr == NULL) { - cuse_unlock(); - return (ENOMEM); - } - if (mem->virtaddr == NBUSY) { + if (mem == NULL) { cuse_unlock(); return (ENOMEM); } + /* verify page offset */ page_nr %= CUSE_ALLOC_PAGES_MAX; - if (page_nr >= mem->page_count) { cuse_unlock(); return (ENXIO); } - ptr = mem->virtaddr + (page_nr * PAGE_SIZE); + /* verify mmap size */ + if ((size % PAGE_SIZE) != 0 || (size < PAGE_SIZE) || + (size > ((mem->page_count - page_nr) * PAGE_SIZE))) { + cuse_unlock(); + return (EINVAL); + } + vm_object_reference(mem->object); + *object = mem->object; cuse_unlock(); - *paddr = vtophys(ptr); + /* set new VM object offset to use */ + *offset = page_nr * PAGE_SIZE; + /* success */ return (0); } @@ -1349,7 +1362,7 @@ cuse_client_free(void *arg) free(pcc, M_CUSE); /* drop reference on server */ - cuse_server_free(pcs); + cuse_server_unref(pcs); } static int @@ -1392,13 +1405,13 @@ cuse_client_open(struct cdev *dev, int fflags, int devtype, struct thread *td) pcc = malloc(sizeof(*pcc), M_CUSE, M_WAITOK | M_ZERO); if (pcc == NULL) { /* drop reference on server */ - cuse_server_free(pcs); + cuse_server_unref(pcs); return (ENOMEM); } if (devfs_set_cdevpriv(pcc, &cuse_client_free)) { printf("Cuse: Cannot set cdevpriv.\n"); /* drop reference on server */ - cuse_server_free(pcs); + cuse_server_unref(pcs); free(pcc, M_CUSE); return (ENOMEM); } @@ -1548,7 +1561,6 @@ cuse_client_read(struct cdev *dev, struct uio *uio, int ioflag) error = ENOMEM; break; } - len = uio->uio_iov->iov_len; cuse_lock(); @@ -1608,7 +1620,6 @@ cuse_client_write(struct cdev *dev, struct uio *uio, int ioflag) error = ENOMEM; break; } - len = uio->uio_iov->iov_len; cuse_lock(); @@ -1751,59 +1762,56 @@ cuse_client_poll(struct cdev *dev, int events, struct thread *td) } return (revents); - pollnval: +pollnval: /* XXX many clients don't understand POLLNVAL */ return (events & (POLLHUP | POLLPRI | POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)); } static int -cuse_client_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) +cuse_client_mmap_single(struct cdev *dev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **object, int nprot) { - uint32_t page_nr = offset / PAGE_SIZE; + uint32_t page_nr = *offset / PAGE_SIZE; uint32_t alloc_nr = page_nr / CUSE_ALLOC_PAGES_MAX; struct cuse_memory *mem; - struct cuse_server *pcs; struct cuse_client *pcc; - uint8_t *ptr; int error; - if (alloc_nr >= CUSE_ALLOC_UNIT_MAX) - return (ENOMEM); - error = cuse_client_get(&pcc); if (error != 0) - pcs = NULL; - else - pcs = pcc->server; + return (error); cuse_lock(); - mem = &cuse_mem[alloc_nr]; - - /* try to enforce slight ownership */ - if ((pcs != NULL) && (mem->owner != pcs)) { - cuse_unlock(); - return (EINVAL); + /* lookup memory structure */ + TAILQ_FOREACH(mem, &pcc->server->hmem, entry) { + if (mem->alloc_nr == alloc_nr) + break; } - if (mem->virtaddr == NULL) { - cuse_unlock(); - return (ENOMEM); - } - if (mem->virtaddr == NBUSY) { + if (mem == NULL) { cuse_unlock(); return (ENOMEM); } + /* verify page offset */ page_nr %= CUSE_ALLOC_PAGES_MAX; - if (page_nr >= mem->page_count) { cuse_unlock(); return (ENXIO); } - ptr = mem->virtaddr + (page_nr * PAGE_SIZE); + /* verify mmap size */ + if ((size % PAGE_SIZE) != 0 || (size < PAGE_SIZE) || + (size > ((mem->page_count - page_nr) * PAGE_SIZE))) { + cuse_unlock(); + return (EINVAL); + } + vm_object_reference(mem->object); + *object = mem->object; cuse_unlock(); - *paddr = vtophys(ptr); + /* set new VM object offset to use */ + *offset = page_nr * PAGE_SIZE; + /* success */ return (0); } diff --git a/sys/fs/cuse/cuse_defs.h b/sys/fs/cuse/cuse_defs.h index 0134bfee8fdc..cf148af85d15 100644 --- a/sys/fs/cuse/cuse_defs.h +++ b/sys/fs/cuse/cuse_defs.h @@ -27,7 +27,7 @@ #ifndef _CUSE_DEFS_H_ #define _CUSE_DEFS_H_ -#define CUSE_VERSION 0x000122 +#define CUSE_VERSION 0x000123 #define CUSE_ERR_NONE 0 #define CUSE_ERR_BUSY -1 @@ -38,6 +38,7 @@ #define CUSE_ERR_SIGNAL -6 #define CUSE_ERR_OTHER -7 #define CUSE_ERR_NOT_LOADED -8 +#define CUSE_ERR_NO_DEVICE -9 #define CUSE_POLL_NONE 0 #define CUSE_POLL_READ 1 diff --git a/sys/fs/cuse/cuse_ioctl.h b/sys/fs/cuse/cuse_ioctl.h index ff0393a4420a..322ff28a4131 100644 --- a/sys/fs/cuse/cuse_ioctl.h +++ b/sys/fs/cuse/cuse_ioctl.h @@ -35,6 +35,7 @@ #define CUSE_BUF_MIN_PTR 0x10000UL #define CUSE_BUF_MAX_PTR 0x20000UL #define CUSE_ALLOC_UNIT_MAX 128 /* units */ +/* All memory allocations must be less than the following limit */ #define CUSE_ALLOC_PAGES_MAX (((16UL * 1024UL * 1024UL) + PAGE_SIZE - 1) / PAGE_SIZE) struct cuse_dev; diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 18b962eadffc..b30b65e2e582 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1178,6 +1178,24 @@ devfs_pathconf(struct vop_pathconf_args *ap) { switch (ap->a_name) { + case _PC_MAX_CANON: + if (ap->a_vp->v_vflag & VV_ISTTY) { + *ap->a_retval = MAX_CANON; + return (0); + } + return (EINVAL); + case _PC_MAX_INPUT: + if (ap->a_vp->v_vflag & VV_ISTTY) { + *ap->a_retval = MAX_INPUT; + return (0); + } + return (EINVAL); + case _PC_VDISABLE: + if (ap->a_vp->v_vflag & VV_ISTTY) { + *ap->a_retval = _POSIX_VDISABLE; + return (0); + } + return (EINVAL); case _PC_MAC_PRESENT: #ifdef MAC /* diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c index 1875ed622762..638af7371fa6 100644 --- a/sys/fs/ext2fs/ext2_alloc.c +++ b/sys/fs/ext2fs/ext2_alloc.c @@ -56,9 +56,8 @@ static daddr_t ext2_alloccg(struct inode *, int, daddr_t, int); static daddr_t ext2_clusteralloc(struct inode *, int, daddr_t, int); static u_long ext2_dirpref(struct inode *); -static void ext2_fserr(struct m_ext2fs *, uid_t, char *); -static u_long ext2_hashalloc(struct inode *, int, long, int, - daddr_t (*)(struct inode *, int, daddr_t, +static e4fs_daddr_t ext2_hashalloc(struct inode *, int, long, int, + daddr_t (*)(struct inode *, int, daddr_t, int)); static daddr_t ext2_nodealloccg(struct inode *, int, daddr_t, int); static daddr_t ext2_mapsearch(struct m_ext2fs *, char *, daddr_t); @@ -86,7 +85,7 @@ ext2_alloc(struct inode *ip, daddr_t lbn, e4fs_daddr_t bpref, int size, { struct m_ext2fs *fs; struct ext2mount *ump; - int32_t bno; + e4fs_daddr_t bno; int cg; *bnp = 0; @@ -135,20 +134,21 @@ ext2_alloc(struct inode *ip, daddr_t lbn, e4fs_daddr_t bpref, int size, /* * Allocate EA's block for inode. */ -daddr_t -ext2_allocfacl(struct inode *ip) +e4fs_daddr_t +ext2_alloc_meta(struct inode *ip) { struct m_ext2fs *fs; - daddr_t facl; + daddr_t blk; fs = ip->i_e2fs; EXT2_LOCK(ip->i_ump); - facl = ext2_alloccg(ip, ino_to_cg(fs, ip->i_number), 0, fs->e2fs_bsize); - if (0 == facl) + blk = ext2_hashalloc(ip, ino_to_cg(fs, ip->i_number), 0, fs->e2fs_bsize, + ext2_alloccg); + if (0 == blk) EXT2_UNLOCK(ip->i_ump); - return (facl); + return (blk); } /* @@ -173,7 +173,7 @@ static int doasyncfree = 1; SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "Use asychronous writes to update block pointers when freeing blocks"); -static int doreallocblks = 1; +static int doreallocblks = 0; SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, ""); @@ -201,7 +201,7 @@ ext2_reallocblks(struct vop_reallocblks_args *ap) fs = ip->i_e2fs; ump = ip->i_ump; - if (fs->e2fs_contigsumsize <= 0) + if (fs->e2fs_contigsumsize <= 0 || ip->i_flag & IN_E4EXTENTS) return (ENOSPC); buflist = ap->a_buflist; @@ -376,7 +376,7 @@ ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp) struct inode *ip; struct ext2mount *ump; ino_t ino, ipref; - int i, error, cg; + int error, cg; *vpp = NULL; pip = VTOI(pvp); @@ -422,11 +422,12 @@ ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp) ip->i_blocks = 0; ip->i_mode = 0; ip->i_flags = 0; - /* now we want to make sure that the block pointers are zeroed out */ - for (i = 0; i < EXT2_NDADDR; i++) - ip->i_db[i] = 0; - for (i = 0; i < EXT2_NIADDR; i++) - ip->i_ib[i] = 0; + if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_EXTENTS) + && (S_ISREG(mode) || S_ISDIR(mode))) + ext4_ext_tree_init(ip); + else + memset(ip->i_data, 0, sizeof(ip->i_data)); + /* * Set up a new generation number for this inode. @@ -576,8 +577,11 @@ e4fs_daddr_t ext2_blkpref(struct inode *ip, e2fs_lbn_t lbn, int indx, e2fs_daddr_t *bap, e2fs_daddr_t blocknr) { + struct m_ext2fs *fs; int tmp; + fs = ip->i_e2fs; + mtx_assert(EXT2_MTX(ip->i_ump), MA_OWNED); /* @@ -600,10 +604,9 @@ ext2_blkpref(struct inode *ip, e2fs_lbn_t lbn, int indx, e2fs_daddr_t *bap, * Else lets fall back to the blocknr or, if there is none, follow * the rule that a block should be allocated near its inode. */ - return blocknr ? blocknr : + return (blocknr ? blocknr : (e2fs_daddr_t)(ip->i_block_group * - EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + - ip->i_e2fs->e2fs->e2fs_first_dblock; + EXT2_BLOCKS_PER_GROUP(fs)) + fs->e2fs->e2fs_first_dblock); } /* @@ -614,12 +617,12 @@ ext2_blkpref(struct inode *ip, e2fs_lbn_t lbn, int indx, e2fs_daddr_t *bap, * 2) quadradically rehash on the cylinder group number. * 3) brute force search for a free block. */ -static u_long +static e4fs_daddr_t ext2_hashalloc(struct inode *ip, int cg, long pref, int size, daddr_t (*allocator) (struct inode *, int, daddr_t, int)) { struct m_ext2fs *fs; - ino_t result; + e4fs_daddr_t result; int i, icg = cg; mtx_assert(EXT2_MTX(ip->i_ump), MA_OWNED); @@ -1178,7 +1181,7 @@ ext2_blkfree(struct inode *ip, e4fs_daddr_t bno, long size) fs = ip->i_e2fs; ump = ip->i_ump; cg = dtog(fs, bno); - if ((u_int)bno >= fs->e2fs->e2fs_bcount) { + if (bno >= fs->e2fs->e2fs_bcount) { printf("bad block %lld, ino %ju\n", (long long)bno, (uintmax_t)ip->i_number); ext2_fserr(fs, ip->i_uid, "bad block"); @@ -1303,7 +1306,7 @@ ext2_mapsearch(struct m_ext2fs *fs, char *bbp, daddr_t bpref) * The form of the error message is: * fs: error message */ -static void +void ext2_fserr(struct m_ext2fs *fs, uid_t uid, char *cp) { diff --git a/sys/fs/ext2fs/ext2_balloc.c b/sys/fs/ext2fs/ext2_balloc.c index d45791e22cde..888d8fe4af38 100644 --- a/sys/fs/ext2fs/ext2_balloc.c +++ b/sys/fs/ext2fs/ext2_balloc.c @@ -51,6 +51,76 @@ #include #include +static int +ext2_ext_balloc(struct inode *ip, uint32_t lbn, int size, + struct ucred *cred, struct buf **bpp, int flags) +{ + struct m_ext2fs *fs; + struct buf *bp = NULL; + struct vnode *vp = ITOV(ip); + uint32_t nb; + int osize, nsize, blks, error, allocated; + + fs = ip->i_e2fs; + blks = howmany(size, fs->e2fs_bsize); + + error = ext4_ext_get_blocks(ip, lbn, blks, cred, NULL, &allocated, &nb); + if (error) + return (error); + + if (allocated) { + if (ip->i_size < (lbn + 1) * fs->e2fs_bsize) + nsize = fragroundup(fs, size); + else + nsize = fs->e2fs_bsize; + + bp = getblk(vp, lbn, nsize, 0, 0, 0); + if(!bp) + return (EIO); + + bp->b_blkno = fsbtodb(fs, nb); + if (flags & BA_CLRBUF) + vfs_bio_clrbuf(bp); + } else { + if (ip->i_size >= (lbn + 1) * fs->e2fs_bsize) { + + error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (error); + } + bp->b_blkno = fsbtodb(fs, nb); + *bpp = bp; + return (0); + } + + /* + * Consider need to reallocate a fragment. + */ + osize = fragroundup(fs, blkoff(fs, ip->i_size)); + nsize = fragroundup(fs, size); + if (nsize <= osize) { + error = bread(vp, lbn, osize, NOCRED, &bp); + if (error) { + brelse(bp); + return (error); + } + bp->b_blkno = fsbtodb(fs, nb); + } else { + error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (error); + } + bp->b_blkno = fsbtodb(fs, nb); + } + } + + *bpp = bp; + + return (error); +} + /* * Balloc defines the structure of filesystem storage * by allocating the physical blocks on a device given @@ -84,6 +154,10 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, ip->i_next_alloc_block++; ip->i_next_alloc_goal++; } + + if (ip->i_flag & IN_E4EXTENTS) + return (ext2_ext_balloc(ip, lbn, size, cred, bpp, flags)); + /* * The first EXT2_NDADDR blocks are direct blocks */ diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index ea28bb05b5ff..9ff20636ae9e 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -53,8 +53,6 @@ #include #include -static int ext4_bmapext(struct vnode *, int32_t, int64_t *, int *, int *); - /* * Bmap converts the logical block number of a file to its physical block * number on the disk. The conversion is done by using the logical block @@ -89,55 +87,52 @@ ext2_bmap(struct vop_bmap_args *ap) * Convert the logical block number of a file to its physical block number * on the disk within ext4 extents. */ -static int +int ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) { struct inode *ip; struct m_ext2fs *fs; + struct ext4_extent_header *ehp; struct ext4_extent *ep; - struct ext4_extent_path path = {.ep_bp = NULL}; + struct ext4_extent_path *path = NULL; daddr_t lbn; - int error; + int error, depth; ip = VTOI(vp); fs = ip->i_e2fs; lbn = bn; + ehp = (struct ext4_extent_header *)ip->i_data; + depth = ehp->eh_depth; + *bnp = -1; if (runp != NULL) *runp = 0; if (runb != NULL) *runb = 0; - error = 0; - ext4_ext_find_extent(fs, ip, lbn, &path); - if (path.ep_is_sparse) { - *bnp = -1; - if (runp != NULL) - *runp = path.ep_sparse_ext.e_len - - (lbn - path.ep_sparse_ext.e_blk) - 1; - if (runb != NULL) - *runb = lbn - path.ep_sparse_ext.e_blk; - } else { - if (path.ep_ext == NULL) { - error = EIO; - goto out; + error = ext4_ext_find_extent(ip, lbn, &path); + if (error) + return (error); + + ep = path[depth].ep_ext; + if(ep) { + if (lbn < ep->e_blk) { + if (runp != NULL) + *runp = ep->e_blk - lbn - 1; + } else if (ep->e_blk <= lbn && lbn < ep->e_blk + ep->e_len) { + *bnp = fsbtodb(fs, lbn - ep->e_blk + + (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); + if (runp != NULL) + *runp = ep->e_len - (lbn - ep->e_blk) - 1; + if (runb != NULL) + *runb = lbn - ep->e_blk; + } else { + if (runb != NULL) + *runb = ep->e_blk + lbn - ep->e_len; } - ep = path.ep_ext; - *bnp = fsbtodb(fs, lbn - ep->e_blk + - (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); - - if (*bnp == 0) - *bnp = -1; - - if (runp != NULL) - *runp = ep->e_len - (lbn - ep->e_blk) - 1; - if (runb != NULL) - *runb = lbn - ep->e_blk; } -out: - if (path.ep_bp != NULL) - brelse(path.ep_bp); + ext4_ext_path_free(path); return (error); } diff --git a/sys/fs/ext2fs/ext2_extattr.c b/sys/fs/ext2fs/ext2_extattr.c index d19d4a0daf6e..a86ffdfebff5 100644 --- a/sys/fs/ext2fs/ext2_extattr.c +++ b/sys/fs/ext2fs/ext2_extattr.c @@ -612,7 +612,7 @@ ext2_extattr_block_clone(struct inode *ip, struct buf **bpp) if (header->h_magic != EXTATTR_MAGIC || header->h_refcount == 1) return (EINVAL); - facl = ext2_allocfacl(ip); + facl = ext2_alloc_meta(ip); if (!facl) return (ENOSPC); @@ -1137,7 +1137,7 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace, return (ENOSPC); /* Allocate block, fill EA header and insert entry */ - ip->i_facl = ext2_allocfacl(ip); + ip->i_facl = ext2_alloc_meta(ip); if (0 == ip->i_facl) return (ENOSPC); diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c index 14ed4a65c520..b9910c0c2661 100644 --- a/sys/fs/ext2fs/ext2_extents.c +++ b/sys/fs/ext2fs/ext2_extents.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -43,87 +44,163 @@ #include #include -static bool -ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path *path, - daddr_t lbn, daddr_t *first_lbn, daddr_t *last_lbn){ - struct ext4_extent_header *ehp = path->ep_header; - struct ext4_extent_index *first, *last, *l, *r, *m; +static MALLOC_DEFINE(M_EXT2EXTENTS, "ext2_extents", "EXT2 extents"); - first = (struct ext4_extent_index *)(char *)(ehp + 1); - last = first + ehp->eh_ecount - 1; - l = first; - r = last; - while (l <= r) { - m = l + (r - l) / 2; - if (lbn < m->ei_blk) - r = m - 1; - else - l = m + 1; +#ifdef EXT2FS_DEBUG +static void +ext4_ext_print_extent(struct ext4_extent *ep) +{ + + printf(" ext %p => (blk %u len %u start %lu)\n", + ep, ep->e_blk, ep->e_len, + (uint64_t)ep->e_start_hi << 32 | ep->e_start_lo); +} + +static void ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp); + +static void +ext4_ext_print_index(struct inode *ip, struct ext4_extent_index *ex, int do_walk) +{ + struct m_ext2fs *fs; + struct buf *bp; + int error; + + fs = ip->i_e2fs; + + printf(" index %p => (blk %u pblk %lu)\n", + ex, ex->ei_blk, (uint64_t)ex->ei_leaf_hi << 32 | ex->ei_leaf_lo); + + if(!do_walk) + return; + + if ((error = bread(ip->i_devvp, + fsbtodb(fs, ((uint64_t)ex->ei_leaf_hi << 32 | ex->ei_leaf_lo)), + (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) { + brelse(bp); + return; } - if (l == first) { - path->ep_sparse_ext.e_blk = *first_lbn; - path->ep_sparse_ext.e_len = first->ei_blk - *first_lbn; - path->ep_sparse_ext.e_start_hi = 0; - path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = true; - return (true); - } - path->ep_index = l - 1; - *first_lbn = path->ep_index->ei_blk; - if (path->ep_index < last) - *last_lbn = l->ei_blk - 1; - return (false); + ext4_ext_print_header(ip, (struct ext4_extent_header *)bp->b_data); + + brelse(bp); + } static void -ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn, - daddr_t first_lbn, daddr_t last_lbn) +ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp) { - struct ext4_extent_header *ehp = path->ep_header; - struct ext4_extent *first, *l, *r, *m; + int i; - if (ehp->eh_ecount == 0) - return; + printf("header %p => (magic 0x%x entries %d max %d depth %d gen %d)\n", + ehp, ehp->eh_magic, ehp->eh_ecount, ehp->eh_max, ehp->eh_depth, + ehp->eh_gen); - first = (struct ext4_extent *)(char *)(ehp + 1); - l = first; - r = first + ehp->eh_ecount - 1; - while (l <= r) { - m = l + (r - l) / 2; - if (lbn < m->e_blk) - r = m - 1; + for (i = 0; i < ehp->eh_ecount; i++) + if (ehp->eh_depth != 0) + ext4_ext_print_index(ip, + (struct ext4_extent_index *)(ehp + 1 + i), 1); else - l = m + 1; - } + ext4_ext_print_extent((struct ext4_extent *)(ehp + 1 + i)); +} - if (l == first) { - path->ep_sparse_ext.e_blk = first_lbn; - path->ep_sparse_ext.e_len = first->e_blk - first_lbn; - path->ep_sparse_ext.e_start_hi = 0; - path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = true; - return; - } - path->ep_ext = l - 1; - if (path->ep_ext->e_blk + path->ep_ext->e_len <= lbn) { - path->ep_sparse_ext.e_blk = path->ep_ext->e_blk + - path->ep_ext->e_len; - if (l <= (first + ehp->eh_ecount - 1)) - path->ep_sparse_ext.e_len = l->e_blk - - path->ep_sparse_ext.e_blk; - else - path->ep_sparse_ext.e_len = last_lbn - - path->ep_sparse_ext.e_blk + 1; - path->ep_sparse_ext.e_start_hi = 0; - path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = true; +static void +ext4_ext_print_path(struct inode *ip, struct ext4_extent_path *path) +{ + int k, l; + + l = path->ep_depth + + printf("ip=%d, Path:\n", ip->i_number); + for (k = 0; k <= l; k++, path++) { + if (path->ep_index) { + ext4_ext_print_index(ip, path->ep_index, 0); + } else if (path->ep_ext) { + ext4_ext_print_extent(path->ep_ext); + } } } -/* - * Find a block in ext4 extent cache. - */ +void +ext4_ext_print_extent_tree_status(struct inode * ip) +{ + struct m_ext2fs *fs; + struct ext4_extent_header *ehp; + + fs = ip->i_e2fs; + ehp = (struct ext4_extent_header *)(char *)ip->i_db; + + printf("Extent status:ip=%d\n", ip->i_number); + if (!(ip->i_flag & IN_E4EXTENTS)) + return; + + ext4_ext_print_header(ip, ehp); + + return; +} +#endif + +static inline struct ext4_extent_header * +ext4_ext_inode_header(struct inode *ip) +{ + + return ((struct ext4_extent_header *)ip->i_db); +} + +static inline struct ext4_extent_header * +ext4_ext_block_header(char *bdata) +{ + + return ((struct ext4_extent_header *)bdata); +} + +static inline unsigned short +ext4_ext_inode_depth(struct inode *ip) +{ + struct ext4_extent_header *ehp; + + ehp = (struct ext4_extent_header *)ip->i_data; + return (ehp->eh_depth); +} + +static inline e4fs_daddr_t +ext4_ext_index_pblock(struct ext4_extent_index *index) +{ + e4fs_daddr_t blk; + + blk = index->ei_leaf_lo; + blk |= (e4fs_daddr_t)index->ei_leaf_hi << 32; + + return (blk); +} + +static inline void +ext4_index_store_pblock(struct ext4_extent_index *index, e4fs_daddr_t pb) +{ + + index->ei_leaf_lo = pb & 0xffffffff; + index->ei_leaf_hi = (pb >> 32) & 0xffff; +} + + +static inline e4fs_daddr_t +ext4_ext_extent_pblock(struct ext4_extent *extent) +{ + e4fs_daddr_t blk; + + blk = extent->e_start_lo; + blk |= (e4fs_daddr_t)extent->e_start_hi << 32; + + return (blk); +} + +static inline void +ext4_ext_store_pblock(struct ext4_extent *ex, e4fs_daddr_t pb) +{ + + ex->e_start_lo = pb & 0xffffffff; + ex->e_start_hi = (pb >> 32) & 0xffff; +} + int ext4_ext_in_cache(struct inode *ip, daddr_t lbn, struct ext4_extent *ep) { @@ -131,8 +208,6 @@ ext4_ext_in_cache(struct inode *ip, daddr_t lbn, struct ext4_extent *ep) int ret = EXT4_EXT_CACHE_NO; ecp = &ip->i_ext_cache; - - /* cache is invalid */ if (ecp->ec_type == EXT4_EXT_CACHE_NO) return (ret); @@ -146,74 +221,1361 @@ ext4_ext_in_cache(struct inode *ip, daddr_t lbn, struct ext4_extent *ep) return (ret); } -/* - * Put an ext4_extent structure in ext4 cache. - */ -void -ext4_ext_put_cache(struct inode *ip, struct ext4_extent *ep, int type) +static int +ext4_ext_check_header(struct inode *ip, struct ext4_extent_header *eh) { - struct ext4_extent_cache *ecp; + struct m_ext2fs *fs; + char *error_msg; - ecp = &ip->i_ext_cache; - ecp->ec_type = type; - ecp->ec_blk = ep->e_blk; - ecp->ec_len = ep->e_len; - ecp->ec_start = (daddr_t)ep->e_start_hi << 32 | ep->e_start_lo; -} + fs = ip->i_e2fs; -/* - * Find an extent. - */ -struct ext4_extent_path * -ext4_ext_find_extent(struct m_ext2fs *fs, struct inode *ip, - daddr_t lbn, struct ext4_extent_path *path) -{ - struct ext4_extent_header *ehp; - uint16_t i; - int error, size; - daddr_t nblk; - - ehp = (struct ext4_extent_header *)(char *)ip->i_db; - - if (ehp->eh_magic != EXT4_EXT_MAGIC) - return (NULL); - - path->ep_header = ehp; - - daddr_t first_lbn = 0; - daddr_t last_lbn = lblkno(ip->i_e2fs, ip->i_size); - - for (i = ehp->eh_depth; i != 0; --i) { - path->ep_depth = i; - path->ep_ext = NULL; - if (ext4_ext_binsearch_index(ip, path, lbn, &first_lbn, - &last_lbn)) { - return (path); - } - - nblk = (daddr_t)path->ep_index->ei_leaf_hi << 32 | - path->ep_index->ei_leaf_lo; - size = blksize(fs, ip, nblk); - if (path->ep_bp != NULL) { - brelse(path->ep_bp); - path->ep_bp = NULL; - } - error = bread(ip->i_devvp, fsbtodb(fs, nblk), size, NOCRED, - &path->ep_bp); - if (error) { - brelse(path->ep_bp); - path->ep_bp = NULL; - return (NULL); - } - ehp = (struct ext4_extent_header *)path->ep_bp->b_data; - path->ep_header = ehp; + if (eh->eh_magic != EXT4_EXT_MAGIC) { + error_msg = "invalid magic"; + goto corrupted; + } + if (eh->eh_max == 0) { + error_msg = "invalid eh_max"; + goto corrupted; + } + if (eh->eh_ecount > eh->eh_max) { + error_msg = "invalid eh_entries"; + goto corrupted; } - path->ep_depth = i; - path->ep_ext = NULL; - path->ep_index = NULL; - path->ep_is_sparse = false; + return (0); - ext4_ext_binsearch(ip, path, lbn, first_lbn, last_lbn); - return (path); +corrupted: + ext2_fserr(fs, ip->i_uid, error_msg); + return (EIO); +} + +static void +ext4_ext_binsearch_index(struct ext4_extent_path *path, int blk) +{ + struct ext4_extent_header *eh; + struct ext4_extent_index *r, *l, *m; + + eh = path->ep_header; + + KASSERT(eh->eh_ecount <= eh->eh_max && eh->eh_ecount > 0, + ("ext4_ext_binsearch_index: bad args")); + + l = EXT_FIRST_INDEX(eh) + 1; + r = EXT_FIRST_INDEX(eh) + eh->eh_ecount - 1; + while (l <= r) { + m = l + (r - l) / 2; + if (blk < m->ei_blk) + r = m - 1; + else + l = m + 1; + } + + path->ep_index = l - 1; +} + +static void +ext4_ext_binsearch_ext(struct ext4_extent_path *path, int blk) +{ + struct ext4_extent_header *eh; + struct ext4_extent *r, *l, *m; + + eh = path->ep_header; + + KASSERT(eh->eh_ecount <= eh->eh_max, + ("ext4_ext_binsearch_ext: bad args")); + + if (eh->eh_ecount == 0) + return; + + l = EXT_FIRST_EXTENT(eh) + 1; + r = EXT_FIRST_EXTENT(eh) + eh->eh_ecount - 1; + + while (l <= r) { + m = l + (r - l) / 2; + if (blk < m->e_blk) + r = m - 1; + else + l = m + 1; + } + + path->ep_ext = l - 1; +} + +static int +ext4_ext_fill_path_bdata(struct ext4_extent_path *path, + struct buf *bp, uint64_t blk) +{ + + KASSERT(path->ep_data == NULL, + ("ext4_ext_fill_path_bdata: bad ep_data")); + + path->ep_data = malloc(bp->b_bufsize, M_EXT2EXTENTS, M_WAITOK); + if (!path->ep_data) + return (ENOMEM); + + memcpy(path->ep_data, bp->b_data, bp->b_bufsize); + path->ep_blk = blk; + + return (0); +} + +static void +ext4_ext_fill_path_buf(struct ext4_extent_path *path, struct buf *bp) +{ + + KASSERT(path->ep_data != NULL, + ("ext4_ext_fill_path_buf: bad ep_data")); + + memcpy(bp->b_data, path->ep_data, bp->b_bufsize); +} + +static void +ext4_ext_drop_refs(struct ext4_extent_path *path) +{ + int depth, i; + + if (!path) + return; + + depth = path->ep_depth; + for (i = 0; i <= depth; i++, path++) + if (path->ep_data) { + free(path->ep_data, M_EXT2EXTENTS); + path->ep_data = NULL; + } +} + +void +ext4_ext_path_free(struct ext4_extent_path *path) +{ + + if (!path) + return; + + ext4_ext_drop_refs(path); + free(path, M_EXT2EXTENTS); +} + +int +ext4_ext_find_extent(struct inode *ip, daddr_t block, + struct ext4_extent_path **ppath) +{ + struct m_ext2fs *fs; + struct ext4_extent_header *eh; + struct ext4_extent_path *path; + struct buf *bp; + uint64_t blk; + int error, depth, i, ppos, alloc; + + fs = ip->i_e2fs; + eh = ext4_ext_inode_header(ip); + depth = ext4_ext_inode_depth(ip); + ppos = 0; + alloc = 0; + + error = ext4_ext_check_header(ip, eh); + if (error) + return (error); + + if (ppath == NULL) + return (EINVAL); + + path = *ppath; + if (path == NULL) { + path = malloc(EXT4_EXT_DEPTH_MAX * + sizeof(struct ext4_extent_path), + M_EXT2EXTENTS, M_WAITOK | M_ZERO); + if (!path) + return (ENOMEM); + + *ppath = path; + alloc = 1; + } + + path[0].ep_header = eh; + path[0].ep_data = NULL; + + /* Walk through the tree. */ + i = depth; + while (i) { + ext4_ext_binsearch_index(&path[ppos], block); + blk = ext4_ext_index_pblock(path[ppos].ep_index); + path[ppos].ep_depth = i; + path[ppos].ep_ext = NULL; + + error = bread(ip->i_devvp, fsbtodb(ip->i_e2fs, blk), + ip->i_e2fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp); + goto error; + } + + ppos++; + if (ppos > depth) { + ext2_fserr(fs, ip->i_uid, + "ppos > depth => extent corrupted"); + error = EIO; + brelse(bp); + goto error; + } + + ext4_ext_fill_path_bdata(&path[ppos], bp, blk); + bqrelse(bp); + + eh = ext4_ext_block_header(path[ppos].ep_data); + error = ext4_ext_check_header(ip, eh); + if (error) + goto error; + + path[ppos].ep_header = eh; + + i--; + } + + error = ext4_ext_check_header(ip, eh); + if (error) + goto error; + + /* Find extent. */ + path[ppos].ep_depth = i; + path[ppos].ep_header = eh; + path[ppos].ep_ext = NULL; + path[ppos].ep_index = NULL; + ext4_ext_binsearch_ext(&path[ppos], block); + return (0); + +error: + ext4_ext_drop_refs(path); + if (alloc) + free(path, M_EXT2EXTENTS); + + *ppath = NULL; + + return (error); +} + +static inline int +ext4_ext_space_root(struct inode *ip) +{ + int size; + + size = sizeof(ip->i_data); + size -= sizeof(struct ext4_extent_header); + size /= sizeof(struct ext4_extent); + + return (size); +} + +static inline int +ext4_ext_space_block(struct inode *ip) +{ + struct m_ext2fs *fs; + int size; + + fs = ip->i_e2fs; + + size = (fs->e2fs_bsize - sizeof(struct ext4_extent_header)) / + sizeof(struct ext4_extent); + + return (size); +} + +static inline int +ext4_ext_space_block_index(struct inode *ip) +{ + struct m_ext2fs *fs; + int size; + + fs = ip->i_e2fs; + + size = (fs->e2fs_bsize - sizeof(struct ext4_extent_header)) / + sizeof(struct ext4_extent_index); + + return (size); +} + +void +ext4_ext_tree_init(struct inode *ip) +{ + struct ext4_extent_header *ehp; + + ip->i_flag |= IN_E4EXTENTS; + + memset(ip->i_data, 0, EXT2_NDADDR + EXT2_NIADDR); + ehp = (struct ext4_extent_header *)ip->i_data; + ehp->eh_magic = EXT4_EXT_MAGIC; + ehp->eh_max = ext4_ext_space_root(ip); + ip->i_ext_cache.ec_type = EXT4_EXT_CACHE_NO; + ip->i_flag |= IN_CHANGE | IN_UPDATE; + ext2_update(ip->i_vnode, 1); +} + +static inline void +ext4_ext_put_in_cache(struct inode *ip, uint32_t blk, + uint32_t len, uint32_t start, int type) +{ + + KASSERT(len != 0, ("ext4_ext_put_in_cache: bad input")); + + ip->i_ext_cache.ec_type = type; + ip->i_ext_cache.ec_blk = blk; + ip->i_ext_cache.ec_len = len; + ip->i_ext_cache.ec_start = start; +} + +static e4fs_daddr_t +ext4_ext_blkpref(struct inode *ip, struct ext4_extent_path *path, + e4fs_daddr_t block) +{ + struct m_ext2fs *fs; + struct ext4_extent *ex; + e4fs_daddr_t bg_start; + int depth; + + fs = ip->i_e2fs; + + if (path) { + depth = path->ep_depth; + ex = path[depth].ep_ext; + if (ex) { + e4fs_daddr_t pblk = ext4_ext_extent_pblock(ex); + e2fs_daddr_t blk = ex->e_blk; + + if (block > blk) + return (pblk + (block - blk)); + else + return (pblk - (blk - block)); + } + + /* Try to get block from index itself. */ + if (path[depth].ep_data) + return (path[depth].ep_blk); + } + + /* Use inode's group. */ + bg_start = (ip->i_block_group * EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + + fs->e2fs->e2fs_first_dblock; + + return (bg_start + block); +} + +static int inline +ext4_can_extents_be_merged(struct ext4_extent *ex1, + struct ext4_extent *ex2) +{ + + if (ex1->e_blk + ex1->e_len != ex2->e_blk) + return (0); + + if (ex1->e_len + ex2->e_len > EXT4_MAX_LEN) + return (0); + + if (ext4_ext_extent_pblock(ex1) + ex1->e_len == + ext4_ext_extent_pblock(ex2)) + return (1); + + return (0); +} + +static unsigned +ext4_ext_next_leaf_block(struct inode *ip, struct ext4_extent_path *path) +{ + int depth = path->ep_depth; + + /* Empty tree */ + if (depth == 0) + return (EXT4_MAX_BLOCKS); + + /* Go to indexes. */ + depth--; + + while (depth >= 0) { + if (path[depth].ep_index != + EXT_LAST_INDEX(path[depth].ep_header)) + return (path[depth].ep_index[1].ei_blk); + + depth--; + } + + return (EXT4_MAX_BLOCKS); +} + +static int +ext4_ext_dirty(struct inode *ip, struct ext4_extent_path *path) +{ + struct m_ext2fs *fs; + struct buf *bp; + uint64_t blk; + int error; + + fs = ip->i_e2fs; + + if (!path) + return (EINVAL); + + if (path->ep_data) { + blk = path->ep_blk; + bp = getblk(ip->i_devvp, fsbtodb(fs, blk), + fs->e2fs_bsize, 0, 0, 0); + if (!bp) + return (EIO); + ext4_ext_fill_path_buf(path, bp); + error = bwrite(bp); + } else { + ip->i_flag |= IN_CHANGE | IN_UPDATE; + error = ext2_update(ip->i_vnode, 1); + } + + return (error); +} + +static int +ext4_ext_insert_index(struct inode *ip, struct ext4_extent_path *path, + uint32_t lblk, e4fs_daddr_t blk) +{ + struct m_ext2fs *fs; + struct ext4_extent_index *idx; + int len; + + fs = ip->i_e2fs; + + if (lblk == path->ep_index->ei_blk) { + ext2_fserr(fs, ip->i_uid, + "lblk == index blk => extent corrupted"); + return (EIO); + } + + if (path->ep_header->eh_ecount >= path->ep_header->eh_max) { + ext2_fserr(fs, ip->i_uid, + "ecout > maxcount => extent corrupted"); + return (EIO); + } + + if (lblk > path->ep_index->ei_blk) { + /* Insert after. */ + idx = path->ep_index + 1; + } else { + /* Insert before. */ + idx = path->ep_index; + } + + len = EXT_LAST_INDEX(path->ep_header) - idx + 1; + if (len > 0) + memmove(idx + 1, idx, len * sizeof(struct ext4_extent_index)); + + if (idx > EXT_MAX_INDEX(path->ep_header)) { + ext2_fserr(fs, ip->i_uid, + "index is out of range => extent corrupted"); + return (EIO); + } + + idx->ei_blk = lblk; + ext4_index_store_pblock(idx, blk); + path->ep_header->eh_ecount++; + + return (ext4_ext_dirty(ip, path)); +} + +static e4fs_daddr_t +ext4_ext_alloc_meta(struct inode *ip) +{ + e4fs_daddr_t blk = ext2_alloc_meta(ip); + if (blk) { + ip->i_blocks += btodb(ip->i_e2fs->e2fs_bsize); + ip->i_flag |= IN_CHANGE | IN_UPDATE; + ext2_update(ip->i_vnode, 1); + } + + return (blk); +} + +static void +ext4_ext_blkfree(struct inode *ip, uint64_t blk, int count, int flags) +{ + struct m_ext2fs *fs; + int i, blocksreleased; + + fs = ip->i_e2fs; + blocksreleased = count; + + for(i = 0; i < count; i++) + ext2_blkfree(ip, blk + i, fs->e2fs_bsize); + + if (ip->i_blocks >= blocksreleased) + ip->i_blocks -= (btodb(fs->e2fs_bsize)*blocksreleased); + else + ip->i_blocks = 0; + + ip->i_flag |= IN_CHANGE | IN_UPDATE; + ext2_update(ip->i_vnode, 1); +} + +static int +ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, + struct ext4_extent *newext, int at) +{ + struct m_ext2fs *fs; + struct buf *bp; + int depth = ext4_ext_inode_depth(ip); + struct ext4_extent_header *neh; + struct ext4_extent_index *fidx; + struct ext4_extent *ex; + int i = at, k, m, a; + e4fs_daddr_t newblk, oldblk; + uint32_t border; + e4fs_daddr_t *ablks = NULL; + int error = 0; + + fs = ip->i_e2fs; + bp = NULL; + + /* + * We will split at current extent for now. + */ + if (path[depth].ep_ext > EXT_MAX_EXTENT(path[depth].ep_header)) { + ext2_fserr(fs, ip->i_uid, + "extent is out of range => extent corrupted"); + return (EIO); + } + + if (path[depth].ep_ext != EXT_MAX_EXTENT(path[depth].ep_header)) + border = path[depth].ep_ext[1].e_blk; + else + border = newext->e_blk; + + /* Allocate new blocks. */ + ablks = malloc(sizeof(e4fs_daddr_t) * depth, + M_EXT2EXTENTS, M_WAITOK | M_ZERO); + if (!ablks) + return (ENOMEM); + for (a = 0; a < depth - at; a++) { + newblk = ext4_ext_alloc_meta(ip); + if (newblk == 0) + goto cleanup; + ablks[a] = newblk; + } + + newblk = ablks[--a]; + bp = getblk(ip->i_devvp, fsbtodb(fs, newblk), fs->e2fs_bsize, 0, 0, 0); + if (!bp) { + error = EIO; + goto cleanup; + } + + neh = ext4_ext_block_header(bp->b_data); + neh->eh_ecount = 0; + neh->eh_max = ext4_ext_space_block(ip); + neh->eh_magic = EXT4_EXT_MAGIC; + neh->eh_depth = 0; + ex = EXT_FIRST_EXTENT(neh); + + if (path[depth].ep_header->eh_ecount != path[depth].ep_header->eh_max) { + ext2_fserr(fs, ip->i_uid, + "extents count out of range => extent corrupted"); + error = EIO; + goto cleanup; + } + + /* Start copy from next extent. */ + m = 0; + path[depth].ep_ext++; + while (path[depth].ep_ext <= EXT_MAX_EXTENT(path[depth].ep_header)) { + path[depth].ep_ext++; + m++; + } + if (m) { + memmove(ex, path[depth].ep_ext - m, + sizeof(struct ext4_extent) * m); + neh->eh_ecount = neh->eh_ecount + m; + } + + bwrite(bp); + bp = NULL; + + /* Fix old leaf. */ + if (m) { + path[depth].ep_header->eh_ecount = + path[depth].ep_header->eh_ecount - m; + ext4_ext_dirty(ip, path + depth); + } + + /* Create intermediate indexes. */ + k = depth - at - 1; + KASSERT(k >= 0, ("ext4_ext_split: negative k")); + + /* Insert new index into current index block. */ + i = depth - 1; + while (k--) { + oldblk = newblk; + newblk = ablks[--a]; + error = bread(ip->i_devvp, fsbtodb(fs, newblk), + (int)fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp); + goto cleanup; + } + + neh = (struct ext4_extent_header *)bp->b_data; + neh->eh_ecount = 1; + neh->eh_magic = EXT4_EXT_MAGIC; + neh->eh_max = ext4_ext_space_block_index(ip); + neh->eh_depth = depth - i; + fidx = EXT_FIRST_INDEX(neh); + fidx->ei_blk = border; + ext4_index_store_pblock(fidx, oldblk); + + m = 0; + path[i].ep_index++; + while (path[i].ep_index <= EXT_MAX_INDEX(path[i].ep_header)) { + path[i].ep_index++; + m++; + } + if (m) { + memmove(++fidx, path[i].ep_index - m, + sizeof(struct ext4_extent_index) * m); + neh->eh_ecount = neh->eh_ecount + m; + } + + bwrite(bp); + bp = NULL; + + /* Fix old index. */ + if (m) { + path[i].ep_header->eh_ecount = + path[i].ep_header->eh_ecount - m; + ext4_ext_dirty(ip, path + i); + } + + i--; + } + + error = ext4_ext_insert_index(ip, path + at, border, newblk); + +cleanup: + if (bp) + brelse(bp); + + if (error) { + for (i = 0; i < depth; i++) { + if (!ablks[i]) + continue; + ext4_ext_blkfree(ip, ablks[i], 1, 0); + } + } + + free(ablks, M_EXT2EXTENTS); + + return (error); +} + +static int +ext4_ext_grow_indepth(struct inode *ip, struct ext4_extent_path *path, + struct ext4_extent *newext) +{ + struct m_ext2fs *fs; + struct ext4_extent_path *curpath; + struct ext4_extent_header *neh; + struct ext4_extent_index *fidx; + struct buf *bp; + e4fs_daddr_t newblk; + int error = 0; + + fs = ip->i_e2fs; + curpath = path; + + newblk = ext4_ext_alloc_meta(ip); + if (newblk == 0) + return (error); + + bp = getblk(ip->i_devvp, fsbtodb(fs, newblk), fs->e2fs_bsize, 0, 0, 0); + if (!bp) + return (EIO); + + /* Move top-level index/leaf into new block. */ + memmove(bp->b_data, curpath->ep_header, sizeof(ip->i_data)); + + /* Set size of new block */ + neh = ext4_ext_block_header(bp->b_data); + neh->eh_magic = EXT4_EXT_MAGIC; + + if (ext4_ext_inode_depth(ip)) + neh->eh_max = ext4_ext_space_block_index(ip); + else + neh->eh_max = ext4_ext_space_block(ip); + + error = bwrite(bp); + if (error) + goto out; + + bp = NULL; + + curpath->ep_header->eh_magic = EXT4_EXT_MAGIC; + curpath->ep_header->eh_max = ext4_ext_space_root(ip); + curpath->ep_header->eh_ecount = 1; + curpath->ep_index = EXT_FIRST_INDEX(curpath->ep_header); + curpath->ep_index->ei_blk = EXT_FIRST_EXTENT(path[0].ep_header)->e_blk; + ext4_index_store_pblock(curpath->ep_index, newblk); + + neh = ext4_ext_inode_header(ip); + fidx = EXT_FIRST_INDEX(neh); + neh->eh_depth = path->ep_depth + 1; + ext4_ext_dirty(ip, curpath); +out: + brelse(bp); + + return (error); +} + +static int +ext4_ext_create_new_leaf(struct inode *ip, struct ext4_extent_path *path, + struct ext4_extent *newext) +{ + struct m_ext2fs *fs; + struct ext4_extent_path *curpath; + int depth, i, error; + + fs = ip->i_e2fs; + +repeat: + i = depth = ext4_ext_inode_depth(ip); + + /* Look for free index entry int the tree */ + curpath = path + depth; + while (i > 0 && !EXT_HAS_FREE_INDEX(curpath)) { + i--; + curpath--; + } + + /* + * We use already allocated block for index block, + * so subsequent data blocks should be contiguous. + */ + if (EXT_HAS_FREE_INDEX(curpath)) { + error = ext4_ext_split(ip, path, newext, i); + if (error) + goto out; + + /* Refill path. */ + ext4_ext_drop_refs(path); + error = ext4_ext_find_extent(ip, newext->e_blk, &path); + if (error) + goto out; + } else { + /* Tree is full, do grow in depth. */ + error = ext4_ext_grow_indepth(ip, path, newext); + if (error) + goto out; + + /* Refill path. */ + ext4_ext_drop_refs(path); + error = ext4_ext_find_extent(ip, newext->e_blk, &path); + if (error) + goto out; + + /* Check and split tree if required. */ + depth = ext4_ext_inode_depth(ip); + if (path[depth].ep_header->eh_ecount == + path[depth].ep_header->eh_max) + goto repeat; + } + +out: + return (error); +} + +static int +ext4_ext_correct_indexes(struct inode *ip, struct ext4_extent_path *path) +{ + struct ext4_extent_header *eh; + struct ext4_extent *ex; + int32_t border; + int depth, k; + + depth = ext4_ext_inode_depth(ip); + eh = path[depth].ep_header; + ex = path[depth].ep_ext; + + if (ex == NULL || eh == NULL) + return (EIO); + + if (!depth) + return (0); + + /* We will correct tree if first leaf got modified only. */ + if (ex != EXT_FIRST_EXTENT(eh)) + return (0); + + k = depth - 1; + border = path[depth].ep_ext->e_blk; + path[k].ep_index->ei_blk = border; + ext4_ext_dirty(ip, path + k); + while (k--) { + /* Change all left-side indexes. */ + if (path[k+1].ep_index != EXT_FIRST_INDEX(path[k+1].ep_header)) + break; + + path[k].ep_index->ei_blk = border; + ext4_ext_dirty(ip, path + k); + } + + return (0); +} + +static int +ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, + struct ext4_extent *newext) +{ + struct m_ext2fs *fs; + struct ext4_extent_header * eh; + struct ext4_extent *ex, *nex, *nearex; + struct ext4_extent_path *npath; + int depth, len, error, next; + + fs = ip->i_e2fs; + depth = ext4_ext_inode_depth(ip); + ex = path[depth].ep_ext; + npath = NULL; + + if (newext->e_len == 0 || path[depth].ep_header == NULL) + return (EINVAL); + + /* Insert block into found extent. */ + if (ex && ext4_can_extents_be_merged(ex, newext)) { + ex->e_len = ex->e_len + newext->e_len; + eh = path[depth].ep_header; + nearex = ex; + goto merge; + } + +repeat: + depth = ext4_ext_inode_depth(ip); + eh = path[depth].ep_header; + if (eh->eh_ecount < eh->eh_max) + goto has_space; + + /* Try next leaf */ + nex = EXT_LAST_EXTENT(eh); + next = ext4_ext_next_leaf_block(ip, path); + if (newext->e_blk > nex->e_blk && next != EXT4_MAX_BLOCKS) { + KASSERT(npath == NULL, + ("ext4_ext_insert_extent: bad path")); + + error = ext4_ext_find_extent(ip, next, &npath); + if (error) + goto cleanup; + + if (npath->ep_depth != path->ep_depth) { + error = EIO; + goto cleanup; + } + + eh = npath[depth].ep_header; + if (eh->eh_ecount < eh->eh_max) { + path = npath; + goto repeat; + } + } + + /* + * There is no free space in the found leaf, + * try to add a new leaf to the tree. + */ + error = ext4_ext_create_new_leaf(ip, path, newext); + if (error) + goto cleanup; + + depth = ext4_ext_inode_depth(ip); + eh = path[depth].ep_header; + +has_space: + nearex = path[depth].ep_ext; + if (!nearex) { + /* Create new extent in the leaf. */ + path[depth].ep_ext = EXT_FIRST_EXTENT(eh); + } else if (newext->e_blk > nearex->e_blk) { + if (nearex != EXT_LAST_EXTENT(eh)) { + len = EXT_MAX_EXTENT(eh) - nearex; + len = (len - 1) * sizeof(struct ext4_extent); + len = len < 0 ? 0 : len; + memmove(nearex + 2, nearex + 1, len); + } + path[depth].ep_ext = nearex + 1; + } else { + len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext4_extent); + len = len < 0 ? 0 : len; + memmove(nearex + 1, nearex, len); + path[depth].ep_ext = nearex; + } + + eh->eh_ecount = eh->eh_ecount + 1; + nearex = path[depth].ep_ext; + nearex->e_blk = newext->e_blk; + nearex->e_start_lo = newext->e_start_lo; + nearex->e_start_hi = newext->e_start_hi; + nearex->e_len = newext->e_len; + +merge: + /* Try to merge extents to the right. */ + while (nearex < EXT_LAST_EXTENT(eh)) { + if (!ext4_can_extents_be_merged(nearex, nearex + 1)) + break; + + /* Merge with next extent. */ + nearex->e_len = nearex->e_len + nearex[1].e_len; + if (nearex + 1 < EXT_LAST_EXTENT(eh)) { + len = (EXT_LAST_EXTENT(eh) - nearex - 1) * + sizeof(struct ext4_extent); + memmove(nearex + 1, nearex + 2, len); + } + + eh->eh_ecount = eh->eh_ecount - 1; + KASSERT(eh->eh_ecount != 0, + ("ext4_ext_insert_extent: bad ecount")); + } + + /* + * Try to merge extents to the left, + * start from inexes correction. + */ + error = ext4_ext_correct_indexes(ip, path); + if (error) + goto cleanup; + + ext4_ext_dirty(ip, path + depth); + +cleanup: + if (npath) { + ext4_ext_drop_refs(npath); + free(npath, M_EXT2EXTENTS); + } + + ip->i_ext_cache.ec_type = EXT4_EXT_CACHE_NO; + return (error); +} + +static e4fs_daddr_t +ext4_new_blocks(struct inode *ip, daddr_t lbn, e4fs_daddr_t pref, + struct ucred *cred, unsigned long *count, int *perror) +{ + struct m_ext2fs *fs; + struct ext2mount *ump; + e4fs_daddr_t newblk; + + fs = ip->i_e2fs; + ump = ip->i_ump; + + /* + * We will allocate only single block for now. + */ + if (*count > 1) + return (0); + + EXT2_LOCK(ip->i_ump); + *perror = ext2_alloc(ip, lbn, pref, (int)fs->e2fs_bsize, cred, &newblk); + if (*perror) + return (0); + + if (newblk) { + ip->i_flag |= IN_CHANGE | IN_UPDATE; + ext2_update(ip->i_vnode, 1); + } + + return (newblk); +} + +int +ext4_ext_get_blocks(struct inode *ip, e4fs_daddr_t iblk, + unsigned long max_blocks, struct ucred *cred, struct buf **bpp, + int *pallocated, uint32_t *nb) +{ + struct m_ext2fs *fs; + struct buf *bp = NULL; + struct ext4_extent_path *path; + struct ext4_extent newex, *ex; + e4fs_daddr_t bpref, newblk = 0; + unsigned long allocated = 0; + int error = 0, depth; + + fs = ip->i_e2fs; + *pallocated = 0; + path = NULL; + if(bpp) + *bpp = NULL; + + /* Check cache. */ + if ((bpref = ext4_ext_in_cache(ip, iblk, &newex))) { + if (bpref == EXT4_EXT_CACHE_IN) { + /* Block is already allocated. */ + newblk = iblk - newex.e_blk + + ext4_ext_extent_pblock(&newex); + allocated = newex.e_len - (iblk - newex.e_blk); + goto out; + } else { + error = EIO; + goto out2; + } + } + + error = ext4_ext_find_extent(ip, iblk, &path); + if (error) { + goto out2; + } + + depth = ext4_ext_inode_depth(ip); + if (path[depth].ep_ext == NULL && depth != 0) { + error = EIO; + goto out2; + } + + if ((ex = path[depth].ep_ext)) { + uint64_t lblk = ex->e_blk; + uint16_t e_len = ex->e_len; + e4fs_daddr_t e_start = ext4_ext_extent_pblock(ex); + + if (e_len > EXT4_MAX_LEN) + goto out2; + + /* If we found extent covers block, simply return it. */ + if (iblk >= lblk && iblk < lblk + e_len) { + newblk = iblk - lblk + e_start; + allocated = e_len - (iblk - lblk); + ext4_ext_put_in_cache(ip, lblk, e_len, + e_start, EXT4_EXT_CACHE_IN); + goto out; + } + } + + /* Allocate the new block. */ + if (S_ISREG(ip->i_mode) && (!ip->i_next_alloc_block)) { + ip->i_next_alloc_goal = 0; + } + + bpref = ext4_ext_blkpref(ip, path, iblk); + allocated = max_blocks; + newblk = ext4_new_blocks(ip, iblk, bpref, cred, &allocated, &error); + if (!newblk) + goto out2; + + /* Try to insert new extent into found leaf and return. */ + newex.e_blk = iblk; + ext4_ext_store_pblock(&newex, newblk); + newex.e_len = allocated; + error = ext4_ext_insert_extent(ip, path, &newex); + if (error) + goto out2; + + newblk = ext4_ext_extent_pblock(&newex); + ext4_ext_put_in_cache(ip, iblk, allocated, newblk, EXT4_EXT_CACHE_IN); + *pallocated = 1; + +out: + if (allocated > max_blocks) + allocated = max_blocks; + + if (bpp) + { + error = bread(ip->i_devvp, fsbtodb(fs, newblk), + fs->e2fs_bsize, cred, &bp); + if (error) { + brelse(bp); + } else { + *bpp = bp; + } + } + +out2: + if (path) { + ext4_ext_drop_refs(path); + free(path, M_EXT2EXTENTS); + } + + if (nb) + *nb = newblk; + + return (error); +} + +static inline uint16_t +ext4_ext_get_actual_len(struct ext4_extent *ext) +{ + + return (ext->e_len <= EXT_INIT_MAX_LEN ? + ext->e_len : (ext->e_len - EXT_INIT_MAX_LEN)); +} + +static inline struct ext4_extent_header * +ext4_ext_header(struct inode *ip) +{ + + return (struct ext4_extent_header *)ip->i_db; +} + +static int +ext4_remove_blocks(struct inode *ip, struct ext4_extent *ex, + unsigned long from, unsigned long to) +{ + unsigned long num, start; + + if (from >= ex->e_blk && + to == ex->e_blk + ext4_ext_get_actual_len(ex) - 1) { + /* Tail cleanup. */ + num = ex->e_blk + ext4_ext_get_actual_len(ex) - from; + start = ext4_ext_extent_pblock(ex) + + ext4_ext_get_actual_len(ex) - num; + ext4_ext_blkfree(ip, start, num, 0); + } + + return (0); +} + +static int +ext4_ext_rm_index(struct inode *ip, struct ext4_extent_path *path) +{ + e4fs_daddr_t leaf; + + /* Free index block. */ + path--; + leaf = ext4_ext_index_pblock(path->ep_index); + KASSERT(path->ep_header->eh_ecount != 0, + ("ext4_ext_rm_index: bad ecount")); + path->ep_header->eh_ecount--; + ext4_ext_dirty(ip, path); + ext4_ext_blkfree(ip, leaf, 1, 0); + return (0); +} + +static int +ext4_ext_rm_leaf(struct inode *ip, struct ext4_extent_path *path, + uint64_t start) +{ + struct m_ext2fs *fs; + int depth; + struct ext4_extent_header *eh; + unsigned int a, b, block, num; + unsigned long ex_blk; + unsigned short ex_len; + struct ext4_extent *ex; + int error, correct_index; + + fs = ip->i_e2fs; + depth = ext4_ext_inode_depth(ip); + correct_index = 0; + + if (!path[depth].ep_header) { + if (path[depth].ep_data == NULL) + return (EINVAL); + path[depth].ep_header = + (struct ext4_extent_header* )path[depth].ep_data; + } + + eh = path[depth].ep_header; + if (!eh) { + ext2_fserr(fs, ip->i_uid, "bad header => extent corrupted"); + return (EIO); + } + + ex = EXT_LAST_EXTENT(eh); + ex_blk = ex->e_blk; + ex_len = ext4_ext_get_actual_len(ex); + + while (ex >= EXT_FIRST_EXTENT(eh) && ex_blk + ex_len > start) { + path[depth].ep_ext = ex; + a = ex_blk > start ? ex_blk : start; + b = (uint64_t)ex_blk + ex_len - 1 < + EXT4_MAX_BLOCKS ? ex_blk + ex_len - 1 : EXT4_MAX_BLOCKS; + + if (a != ex_blk && b != ex_blk + ex_len - 1) + return (EINVAL); + else if (a != ex_blk) { + /* Remove tail of the extent. */ + block = ex_blk; + num = a - block; + } else if (b != ex_blk + ex_len - 1) { + /* Remove head of the extent, not implemented. */ + return (EINVAL); + } else { + /* Remove whole extent. */ + block = ex_blk; + num = 0; + } + + if (ex == EXT_FIRST_EXTENT(eh)) + correct_index = 1; + + error = ext4_remove_blocks(ip, ex, a, b); + if (error) + goto out; + + if (num == 0) { + ext4_ext_store_pblock(ex, 0); + eh->eh_ecount--; + } + + ex->e_blk = block; + ex->e_len = num; + + ext4_ext_dirty(ip, path + depth); + + ex--; + ex_blk = ex->e_blk; + ex_len = ext4_ext_get_actual_len(ex); + }; + + if (correct_index && eh->eh_ecount) + error = ext4_ext_correct_indexes(ip, path); + + /* + * If this leaf is free, we should + * remove it from index block above. + */ + if (error == 0 && eh->eh_ecount == 0 && path[depth].ep_data != NULL) + error = ext4_ext_rm_index(ip, path + depth); + +out: + return (error); +} + +static struct buf * +ext4_read_extent_tree_block(struct inode *ip, e4fs_daddr_t pblk, + int depth, int flags) +{ + struct m_ext2fs *fs; + struct ext4_extent_header *eh; + struct buf *bp; + int error; + + fs = ip->i_e2fs; + + error = bread(ip->i_devvp, fsbtodb(fs, pblk), + fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (NULL); + } + + eh = ext4_ext_block_header(bp->b_data); + if (eh->eh_depth != depth) { + ext2_fserr(fs, ip->i_uid, "unexpected eh_depth"); + goto err; + } + + error = ext4_ext_check_header(ip, eh); + if (error) + goto err; + + return (bp); + +err: + brelse(bp); + return (NULL); + +} + +static int inline +ext4_ext_more_to_rm(struct ext4_extent_path *path) +{ + + KASSERT(path->ep_index != NULL, + ("ext4_ext_more_to_rm: bad index from path")); + + if (path->ep_index < EXT_FIRST_INDEX(path->ep_header)) + return (0); + + if (path->ep_header->eh_ecount == path->index_count) + return (0); + + return (1); +} + +int +ext4_ext_remove_space(struct inode *ip, off_t length, int flags, + struct ucred *cred, struct thread *td) +{ + struct buf *bp; + struct ext4_extent_header *ehp; + struct ext4_extent_path *path; + int depth; + int i, error; + + ehp = (struct ext4_extent_header *)ip->i_db; + depth = ext4_ext_inode_depth(ip); + + error = ext4_ext_check_header(ip, ehp); + if(error) + return (error); + + path = malloc(sizeof(struct ext4_extent_path) * (depth + 1), + M_EXT2EXTENTS, M_WAITOK | M_ZERO); + if (!path) + return (ENOMEM); + + i = 0; + path[0].ep_header = ehp; + path[0].ep_depth = depth; + while (i >= 0 && error == 0) { + if (i == depth) { + /* This is leaf. */ + error = ext4_ext_rm_leaf(ip, path, length); + if (error) + break; + free(path[i].ep_data, M_EXT2EXTENTS); + path[i].ep_data = NULL; + i--; + continue; + } + + /* This is index. */ + if (!path[i].ep_header) + path[i].ep_header = + (struct ext4_extent_header *)path[i].ep_data; + + if (!path[i].ep_index) { + /* This level hasn't touched yet. */ + path[i].ep_index = EXT_LAST_INDEX(path[i].ep_header); + path[i].index_count = path[i].ep_header->eh_ecount + 1; + } else { + /* We've already was here, see at next index. */ + path[i].ep_index--; + } + + if (ext4_ext_more_to_rm(path + i)) { + memset(path + i + 1, 0, sizeof(*path)); + bp = ext4_read_extent_tree_block(ip, + ext4_ext_index_pblock(path[i].ep_index), + path[0].ep_depth - (i + 1), 0); + if (!bp) { + error = EIO; + break; + } + + ext4_ext_fill_path_bdata(&path[i+1], bp, + ext4_ext_index_pblock(path[i].ep_index)); + brelse(bp); + path[i].index_count = path[i].ep_header->eh_ecount; + i++; + } else { + if (path[i].ep_header->eh_ecount == 0 && i > 0) { + /* Index is empty, remove it. */ + error = ext4_ext_rm_index(ip, path + i); + } + free(path[i].ep_data, M_EXT2EXTENTS); + path[i].ep_data = NULL; + i--; + } + } + + if (path->ep_header->eh_ecount == 0) { + /* + * Truncate the tree to zero. + */ + ext4_ext_header(ip)->eh_depth = 0; + ext4_ext_header(ip)->eh_max = ext4_ext_space_root(ip); + ext4_ext_dirty(ip, path); + + } + + ext4_ext_drop_refs(path); + free(path, M_EXT2EXTENTS); + + return (error); } diff --git a/sys/fs/ext2fs/ext2_extents.h b/sys/fs/ext2fs/ext2_extents.h index 91cb0d32346c..b69da4cdba19 100644 --- a/sys/fs/ext2fs/ext2_extents.h +++ b/sys/fs/ext2fs/ext2_extents.h @@ -31,6 +31,10 @@ #include #define EXT4_EXT_MAGIC 0xf30a +#define EXT4_MAX_BLOCKS 0xffffffff +#define EXT_INIT_MAX_LEN (1UL << 15) +#define EXT4_MAX_LEN (EXT_INIT_MAX_LEN - 1) +#define EXT4_EXT_DEPTH_MAX 5 #define EXT4_EXT_CACHE_NO 0 #define EXT4_EXT_CACHE_GAP 1 @@ -82,23 +86,41 @@ struct ext4_extent_cache { * Save path to some extent. */ struct ext4_extent_path { + int index_count; uint16_t ep_depth; - struct buf *ep_bp; - bool ep_is_sparse; - union { - struct ext4_extent ep_sparse_ext; - struct ext4_extent *ep_ext; - }; + uint64_t ep_blk; + char *ep_data; + struct ext4_extent *ep_ext; struct ext4_extent_index *ep_index; struct ext4_extent_header *ep_header; }; +#define EXT_FIRST_EXTENT(hdr) ((struct ext4_extent *)(((char *)(hdr)) + \ + sizeof(struct ext4_extent_header))) +#define EXT_FIRST_INDEX(hdr) ((struct ext4_extent_index *)(((char *)(hdr)) + \ + sizeof(struct ext4_extent_header))) +#define EXT_LAST_EXTENT(hdr) (EXT_FIRST_EXTENT((hdr)) + (hdr)->eh_ecount - 1) +#define EXT_LAST_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + (hdr)->eh_ecount - 1) +#define EXT4_EXTENT_TAIL_OFFSET(hdr) (sizeof(struct ext4_extent_header) + \ + (sizeof(struct ext4_extent) * (hdr)->eh_max)) +#define EXT_HAS_FREE_INDEX(path) \ + ((path)->ep_header->eh_ecount < (path)->ep_header->eh_max) +#define EXT_MAX_EXTENT(hdr) (EXT_FIRST_EXTENT(hdr) + ((hdr)->eh_max) - 1) +#define EXT_MAX_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + (hdr)->eh_max - 1) + struct inode; struct m_ext2fs; +void ext4_ext_tree_init(struct inode *ip); int ext4_ext_in_cache(struct inode *, daddr_t, struct ext4_extent *); void ext4_ext_put_cache(struct inode *, struct ext4_extent *, int); -struct ext4_extent_path * -ext4_ext_find_extent(struct m_ext2fs *fs, - struct inode *, daddr_t, struct ext4_extent_path *); +int ext4_ext_find_extent(struct inode *, daddr_t, struct ext4_extent_path **); +void ext4_ext_path_free(struct ext4_extent_path *path); +int ext4_ext_remove_space(struct inode *ip, off_t length, int flags, + struct ucred *cred, struct thread *td); +int ext4_ext_get_blocks(struct inode *ip, int64_t iblock, + unsigned long max_blocks, struct ucred *cred, struct buf **bpp, int *allocate, uint32_t *); +#ifdef EXT2FS_DEBUG +void ext4_ext_print_extent_tree_status(struct inode * ip); +#endif #endif /* !_FS_EXT2FS_EXT2_EXTENTS_H_ */ diff --git a/sys/fs/ext2fs/ext2_extern.h b/sys/fs/ext2fs/ext2_extern.h index 9b8ffd6cbb0f..626de2f1fd7c 100644 --- a/sys/fs/ext2fs/ext2_extern.h +++ b/sys/fs/ext2fs/ext2_extern.h @@ -51,7 +51,7 @@ struct vnode; int ext2_add_entry(struct vnode *, struct ext2fs_direct_2 *); int ext2_alloc(struct inode *, daddr_t, e4fs_daddr_t, int, struct ucred *, e4fs_daddr_t *); -daddr_t ext2_allocfacl(struct inode *ip); +e4fs_daddr_t ext2_alloc_meta(struct inode *ip); int ext2_balloc(struct inode *, e2fs_lbn_t, int, struct ucred *, struct buf **, int); int ext2_blkatoff(struct vnode *, off_t, char **, struct buf **); @@ -60,11 +60,13 @@ e4fs_daddr_t ext2_blkpref(struct inode *, e2fs_lbn_t, int, e2fs_daddr_t *, e2fs_daddr_t); int ext2_bmap(struct vop_bmap_args *); int ext2_bmaparray(struct vnode *, daddr_t, daddr_t *, int *, int *); -void ext2_clusteracct(struct m_ext2fs *, char *, int, daddr_t, int); +int ext4_bmapext(struct vnode *, int32_t, int64_t *, int *, int *); +void ext2_clusteracct(struct m_ext2fs *, char *, int, e4fs_daddr_t, int); void ext2_dirbad(struct inode *ip, doff_t offset, char *how); +void ext2_fserr(struct m_ext2fs *, uid_t, char *); void ext2_ei2i(struct ext2fs_dinode *, struct inode *); int ext2_getlbns(struct vnode *, daddr_t, struct indir *, int *); -void ext2_i2ei(struct inode *, struct ext2fs_dinode *); +int ext2_i2ei(struct inode *, struct ext2fs_dinode *); void ext2_itimes(struct vnode *vp); int ext2_reallocblks(struct vop_reallocblks_args *); int ext2_reclaim(struct vop_reclaim_args *); diff --git a/sys/fs/ext2fs/ext2_inode.c b/sys/fs/ext2fs/ext2_inode.c index d153bf8257df..dbb3f37306dc 100644 --- a/sys/fs/ext2fs/ext2_inode.c +++ b/sys/fs/ext2fs/ext2_inode.c @@ -55,9 +55,6 @@ #include #include -static int ext2_indirtrunc(struct inode *, daddr_t, daddr_t, - daddr_t, int, e4fs_daddr_t *); - /* * Update the access, modified, and inode change times as specified by the * IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. Write the inode @@ -90,8 +87,12 @@ ext2_update(struct vnode *vp, int waitfor) brelse(bp); return (error); } - ext2_i2ei(ip, (struct ext2fs_dinode *)((char *)bp->b_data + + error = ext2_i2ei(ip, (struct ext2fs_dinode *)((char *)bp->b_data + EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number))); + if (error) { + brelse(bp); + return (error); + } if (waitfor && !DOINGASYNC(vp)) return (bwrite(bp)); else { @@ -103,18 +104,129 @@ ext2_update(struct vnode *vp, int waitfor) #define SINGLE 0 /* index of single indirect block */ #define DOUBLE 1 /* index of double indirect block */ #define TRIPLE 2 /* index of triple indirect block */ + +/* + * Release blocks associated with the inode ip and stored in the indirect + * block bn. Blocks are free'd in LIFO order up to (but not including) + * lastbn. If level is greater than SINGLE, the block is an indirect block + * and recursive calls to indirtrunc must be used to cleanse other indirect + * blocks. + * + * NB: triple indirect blocks are untested. + */ +static int +ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, + daddr_t lastbn, int level, e4fs_daddr_t *countp) +{ + struct buf *bp; + struct m_ext2fs *fs = ip->i_e2fs; + struct vnode *vp; + e2fs_daddr_t *bap, *copy; + int i, nblocks, error = 0, allerror = 0; + e2fs_lbn_t nb, nlbn, last; + e4fs_daddr_t blkcount, factor, blocksreleased = 0; + + /* + * Calculate index in current block of last + * block to be kept. -1 indicates the entire + * block so we need not calculate the index. + */ + factor = 1; + for (i = SINGLE; i < level; i++) + factor *= NINDIR(fs); + last = lastbn; + if (lastbn > 0) + last /= factor; + nblocks = btodb(fs->e2fs_bsize); + /* + * Get buffer of block pointers, zero those entries corresponding + * to blocks to be free'd, and update on disk copy first. Since + * double(triple) indirect before single(double) indirect, calls + * to bmap on these blocks will fail. However, we already have + * the on disk address, so we have to set the b_blkno field + * explicitly instead of letting bread do everything for us. + */ + vp = ITOV(ip); + bp = getblk(vp, lbn, (int)fs->e2fs_bsize, 0, 0, 0); + if ((bp->b_flags & (B_DONE | B_DELWRI)) == 0) { + bp->b_iocmd = BIO_READ; + if (bp->b_bcount > bp->b_bufsize) + panic("ext2_indirtrunc: bad buffer size"); + bp->b_blkno = dbn; + vfs_busy_pages(bp, 0); + bp->b_iooffset = dbtob(bp->b_blkno); + bstrategy(bp); + error = bufwait(bp); + } + if (error) { + brelse(bp); + *countp = 0; + return (error); + } + bap = (e2fs_daddr_t *)bp->b_data; + copy = malloc(fs->e2fs_bsize, M_TEMP, M_WAITOK); + bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->e2fs_bsize); + bzero((caddr_t)&bap[last + 1], + (NINDIR(fs) - (last + 1)) * sizeof(e2fs_daddr_t)); + if (last == -1) + bp->b_flags |= B_INVAL; + if (DOINGASYNC(vp)) { + bdwrite(bp); + } else { + error = bwrite(bp); + if (error) + allerror = error; + } + bap = copy; + + /* + * Recursively free totally unused blocks. + */ + for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; + i--, nlbn += factor) { + nb = bap[i]; + if (nb == 0) + continue; + if (level > SINGLE) { + if ((error = ext2_indirtrunc(ip, nlbn, + fsbtodb(fs, nb), (int32_t)-1, level - 1, &blkcount)) != 0) + allerror = error; + blocksreleased += blkcount; + } + ext2_blkfree(ip, nb, fs->e2fs_bsize); + blocksreleased += nblocks; + } + + /* + * Recursively free last partial block. + */ + if (level > SINGLE && lastbn >= 0) { + last = lastbn % factor; + nb = bap[i]; + if (nb != 0) { + if ((error = ext2_indirtrunc(ip, nlbn, fsbtodb(fs, nb), + last, level - 1, &blkcount)) != 0) + allerror = error; + blocksreleased += blkcount; + } + } + free(copy, M_TEMP); + *countp = blocksreleased; + return (allerror); +} + /* * Truncate the inode oip to at most length size, freeing the * disk blocks. */ -int -ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, +static int +ext2_ind_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, struct thread *td) { struct vnode *ovp = vp; - int32_t lastblock; + e4fs_daddr_t lastblock; struct inode *oip; - int32_t bn, lbn, lastiblock[EXT2_NIADDR], indir_lbn[EXT2_NIADDR]; + e4fs_daddr_t bn, lbn, lastiblock[EXT2_NIADDR], indir_lbn[EXT2_NIADDR]; uint32_t oldblks[EXT2_NDADDR + EXT2_NIADDR]; uint32_t newblks[EXT2_NDADDR + EXT2_NIADDR]; struct m_ext2fs *fs; @@ -132,26 +244,6 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, bo = &ovp->v_bufobj; #endif - ASSERT_VOP_LOCKED(vp, "ext2_truncate"); - - if (length < 0) - return (EINVAL); - - if (ovp->v_type == VLNK && - oip->i_size < ovp->v_mount->mnt_maxsymlinklen) { -#ifdef INVARIANTS - if (length != 0) - panic("ext2_truncate: partial truncate of symlink"); -#endif - bzero((char *)&oip->i_shortlink, (u_int)oip->i_size); - oip->i_size = 0; - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (ext2_update(ovp, 1)); - } - if (oip->i_size == length) { - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (ext2_update(ovp, 0)); - } fs = oip->i_e2fs; osize = oip->i_size; /* @@ -361,115 +453,131 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, return (allerror); } -/* - * Release blocks associated with the inode ip and stored in the indirect - * block bn. Blocks are free'd in LIFO order up to (but not including) - * lastbn. If level is greater than SINGLE, the block is an indirect block - * and recursive calls to indirtrunc must be used to cleanse other indirect - * blocks. - * - * NB: triple indirect blocks are untested. - */ - static int -ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, - daddr_t lastbn, int level, e4fs_daddr_t *countp) +ext2_ext_truncate(struct vnode *vp, off_t length, int flags, + struct ucred *cred, struct thread *td) { + struct vnode *ovp = vp; + int32_t lastblock; + struct m_ext2fs *fs; + struct inode *oip; struct buf *bp; - struct m_ext2fs *fs = ip->i_e2fs; - struct vnode *vp; - e2fs_daddr_t *bap, *copy; - int i, nblocks, error = 0, allerror = 0; - e2fs_lbn_t nb, nlbn, last; - e4fs_daddr_t blkcount, factor, blocksreleased = 0; + uint32_t lbn, offset; + int error, size; + off_t osize; - /* - * Calculate index in current block of last - * block to be kept. -1 indicates the entire - * block so we need not calculate the index. - */ - factor = 1; - for (i = SINGLE; i < level; i++) - factor *= NINDIR(fs); - last = lastbn; - if (lastbn > 0) - last /= factor; - nblocks = btodb(fs->e2fs_bsize); - /* - * Get buffer of block pointers, zero those entries corresponding - * to blocks to be free'd, and update on disk copy first. Since - * double(triple) indirect before single(double) indirect, calls - * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field - * explicitly instead of letting bread do everything for us. - */ - vp = ITOV(ip); - bp = getblk(vp, lbn, (int)fs->e2fs_bsize, 0, 0, 0); - if ((bp->b_flags & (B_DONE | B_DELWRI)) == 0) { - bp->b_iocmd = BIO_READ; - if (bp->b_bcount > bp->b_bufsize) - panic("ext2_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; - vfs_busy_pages(bp, 0); - bp->b_iooffset = dbtob(bp->b_blkno); - bstrategy(bp); - error = bufwait(bp); + oip = VTOI(ovp); + fs = oip->i_e2fs; + osize = oip->i_size; + + if (osize < length) { + if (length > oip->i_e2fs->e2fs_maxfilesize) { + return (EFBIG); + } + vnode_pager_setsize(ovp, length); + offset = blkoff(fs, length - 1); + lbn = lblkno(fs, length - 1); + flags |= BA_CLRBUF; + error = ext2_balloc(oip, lbn, offset + 1, cred, &bp, flags); + if (error) { + vnode_pager_setsize(vp, osize); + return (error); + } + oip->i_size = length; + if (bp->b_bufsize == fs->e2fs_bsize) + bp->b_flags |= B_CLUSTEROK; + if (flags & IO_SYNC) + bwrite(bp); + else if (DOINGASYNC(ovp)) + bdwrite(bp); + else + bawrite(bp); + oip->i_flag |= IN_CHANGE | IN_UPDATE; + return (ext2_update(ovp, !DOINGASYNC(ovp))); } - if (error) { - brelse(bp); - *countp = 0; + + lastblock = (length + fs->e2fs_bsize - 1) / fs->e2fs_bsize; + error = ext4_ext_remove_space(oip, lastblock, flags, cred, td); + if (error) return (error); - } - bap = (e2fs_daddr_t *)bp->b_data; - copy = malloc(fs->e2fs_bsize, M_TEMP, M_WAITOK); - bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->e2fs_bsize); - bzero((caddr_t)&bap[last + 1], - (NINDIR(fs) - (last + 1)) * sizeof(e2fs_daddr_t)); - if (last == -1) - bp->b_flags |= B_INVAL; - if (DOINGASYNC(vp)) { - bdwrite(bp); + + offset = blkoff(fs, length); + if (offset == 0) { + oip->i_size = length; } else { - error = bwrite(bp); - if (error) - allerror = error; - } - bap = copy; - - /* - * Recursively free totally unused blocks. - */ - for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; - i--, nlbn += factor) { - nb = bap[i]; - if (nb == 0) - continue; - if (level > SINGLE) { - if ((error = ext2_indirtrunc(ip, nlbn, - fsbtodb(fs, nb), (int32_t)-1, level - 1, &blkcount)) != 0) - allerror = error; - blocksreleased += blkcount; + lbn = lblkno(fs, length); + flags |= BA_CLRBUF; + error = ext2_balloc(oip, lbn, offset, cred, &bp, flags); + if (error) { + return (error); } - ext2_blkfree(ip, nb, fs->e2fs_bsize); - blocksreleased += nblocks; + oip->i_size = length; + size = blksize(fs, oip, lbn); + bzero((char *)bp->b_data + offset, (u_int)(size - offset)); + allocbuf(bp, size); + if (bp->b_bufsize == fs->e2fs_bsize) + bp->b_flags |= B_CLUSTEROK; + if (flags & IO_SYNC) + bwrite(bp); + else if (DOINGASYNC(ovp)) + bdwrite(bp); + else + bawrite(bp); } - /* - * Recursively free last partial block. - */ - if (level > SINGLE && lastbn >= 0) { - last = lastbn % factor; - nb = bap[i]; - if (nb != 0) { - if ((error = ext2_indirtrunc(ip, nlbn, fsbtodb(fs, nb), - last, level - 1, &blkcount)) != 0) - allerror = error; - blocksreleased += blkcount; - } + oip->i_size = osize; + error = vtruncbuf(ovp, cred, length, (int)fs->e2fs_bsize); + if (error) + return (error); + + vnode_pager_setsize(ovp, length); + + oip->i_size = length; + oip->i_flag |= IN_CHANGE | IN_UPDATE; + error = ext2_update(ovp, !DOINGASYNC(ovp)); + + return (error); +} + +/* + * Truncate the inode ip to at most length size, freeing the + * disk blocks. + */ +int +ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, + struct thread *td) +{ + struct inode *ip; + int error; + + ASSERT_VOP_LOCKED(vp, "ext2_truncate"); + + if (length < 0) + return (EINVAL); + + ip = VTOI(vp); + if (vp->v_type == VLNK && + ip->i_size < vp->v_mount->mnt_maxsymlinklen) { +#ifdef INVARIANTS + if (length != 0) + panic("ext2_truncate: partial truncate of symlink"); +#endif + bzero((char *)&ip->i_shortlink, (u_int)ip->i_size); + ip->i_size = 0; + ip->i_flag |= IN_CHANGE | IN_UPDATE; + return (ext2_update(vp, 1)); } - free(copy, M_TEMP); - *countp = blocksreleased; - return (allerror); + if (ip->i_size == length) { + ip->i_flag |= IN_CHANGE | IN_UPDATE; + return (ext2_update(vp, 0)); + } + + if (ip->i_flag & IN_E4EXTENTS) + error = ext2_ext_truncate(vp, length, flags, cred, td); + else + error = ext2_ind_truncate(vp, length, flags, cred, td); + + return (error); } /* @@ -491,7 +599,8 @@ ext2_inactive(struct vop_inactive_args *ap) if (ip->i_nlink <= 0) { ext2_extattr_free(ip); error = ext2_truncate(vp, (off_t)0, 0, NOCRED, td); - ip->i_rdev = 0; + if (!(ip->i_flag & IN_E4EXTENTS)) + ip->i_rdev = 0; mode = ip->i_mode; ip->i_mode = 0; ip->i_flag |= IN_CHANGE | IN_UPDATE; diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 6d709a7bd326..ef2fe60ef3f9 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -51,7 +51,7 @@ ext2_print_inode(struct inode *in) printf("Inode: %5ju", (uintmax_t)in->i_number); printf( /* "Inode: %5d" */ - " Type: %10s Mode: 0x%o Flags: 0x%x Version: %d acl: 0x%llx\n", + " Type: %10s Mode: 0x%o Flags: 0x%x Version: %d acl: 0x%lx\n", "n/a", in->i_mode, in->i_flags, in->i_gen, in->i_facl); printf("User: %5u Group: %5u Size: %ju\n", in->i_uid, in->i_gid, (uintmax_t)in->i_size); @@ -62,19 +62,22 @@ ext2_print_inode(struct inode *in) printf("mtime: 0x%x", in->i_mtime); if (E2DI_HAS_XTIME(in)) printf("crtime %#x ", in->i_birthtime); - printf("BLOCKS:"); - for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++) - printf(" %d", in->i_db[i]); - printf("\n"); - printf("Extents:\n"); - ehp = (struct ext4_extent_header *)in->i_db; - printf("Header (magic 0x%x entries %d max %d depth %d gen %d)\n", - ehp->eh_magic, ehp->eh_ecount, ehp->eh_max, ehp->eh_depth, - ehp->eh_gen); - ep = (struct ext4_extent *)(char *)(ehp + 1); - printf("Index (blk %d len %d start_lo %d start_hi %d)\n", ep->e_blk, - ep->e_len, ep->e_start_lo, ep->e_start_hi); - printf("\n"); + if (in->i_flag & IN_E4EXTENTS) { + printf("Extents:\n"); + ehp = (struct ext4_extent_header *)in->i_db; + printf("Header (magic 0x%x entries %d max %d depth %d gen %d)\n", + ehp->eh_magic, ehp->eh_ecount, ehp->eh_max, ehp->eh_depth, + ehp->eh_gen); + ep = (struct ext4_extent *)(char *)(ehp + 1); + printf("Index (blk %d len %d start_lo %d start_hi %d)\n", ep->e_blk, + ep->e_len, ep->e_start_lo, ep->e_start_hi); + printf("\n"); + } else { + printf("BLOCKS:"); + for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++) + printf(" %d", in->i_db[i]); + printf("\n"); + } } #endif /* EXT2FS_DEBUG */ @@ -84,8 +87,6 @@ ext2_print_inode(struct inode *in) void ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) { - int i; - ip->i_nlink = ei->e2di_nlink; /* * Godmar thinks - if the link count is zero, then the inode is @@ -127,20 +128,18 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) ip->i_uid |= (uint32_t)ei->e2di_uid_high << 16; ip->i_gid |= (uint32_t)ei->e2di_gid_high << 16; - for (i = 0; i < EXT2_NDADDR; i++) - ip->i_db[i] = ei->e2di_blocks[i]; - for (i = 0; i < EXT2_NIADDR; i++) - ip->i_ib[i] = ei->e2di_blocks[EXT2_NDIR_BLOCKS + i]; + memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks)); } /* * inode to raw ext2 inode */ -void +int ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) { - int i; + struct m_ext2fs *fs; + fs = ip->i_e2fs; ei->e2di_mode = ip->i_mode; ei->e2di_nlink = ip->i_nlink; /* @@ -167,8 +166,19 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) ei->e2di_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0; ei->e2di_flags |= (ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0; ei->e2di_flags |= (ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0; - ei->e2di_nblock = ip->i_blocks & 0xffffffff; - ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff; + if (ip->i_blocks > ~0U && + !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) { + ext2_fserr(fs, ip->i_uid, "i_blocks value is out of range"); + return (EIO); + } + if (ip->i_blocks <= 0xffffffffffffULL) { + ei->e2di_nblock = ip->i_blocks & 0xffffffff; + ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff; + } else { + ei->e2di_flags |= EXT4_HUGE_FILE; + ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); + ei->e2di_nblock_high = dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff; + } ei->e2di_facl = ip->i_facl & 0xffffffff; ei->e2di_facl_high = ip->i_facl >> 32 & 0xffff; ei->e2di_gen = ip->i_gen; @@ -177,8 +187,7 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) ei->e2di_gid = ip->i_gid & 0xffff; ei->e2di_gid_high = ip->i_gid >> 16 & 0xffff; - for (i = 0; i < EXT2_NDADDR; i++) - ei->e2di_blocks[i] = ip->i_db[i]; - for (i = 0; i < EXT2_NIADDR; i++) - ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i]; + memcpy(ei->e2di_blocks, ip->i_data, sizeof(ei->e2di_blocks)); + + return (0); } diff --git a/sys/fs/ext2fs/ext2_subr.c b/sys/fs/ext2fs/ext2_subr.c index a481b9985b8f..9a9d426b950d 100644 --- a/sys/fs/ext2fs/ext2_subr.c +++ b/sys/fs/ext2fs/ext2_subr.c @@ -66,63 +66,22 @@ ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) struct m_ext2fs *fs; struct buf *bp; e2fs_lbn_t lbn; - int bsize, error; - daddr_t newblk; - struct ext4_extent *ep; - struct ext4_extent_path path; + int error, bsize; ip = VTOI(vp); fs = ip->i_e2fs; lbn = lblkno(fs, offset); bsize = blksize(fs, ip, lbn); - *bpp = NULL; - /* - * IN_E4EXTENTS requires special treatment as we can otherwise fall - * back to the normal path. - */ - if (!(ip->i_flag & IN_E4EXTENTS)) - goto normal; - - memset(&path, 0, sizeof(path)); - if (ext4_ext_find_extent(fs, ip, lbn, &path) == NULL) - goto normal; - ep = path.ep_ext; - if (ep == NULL) - goto normal; - - newblk = lbn - ep->e_blk + - (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32); - - if (path.ep_bp != NULL) { - brelse(path.ep_bp); - path.ep_bp = NULL; - } - error = bread(ip->i_devvp, fsbtodb(fs, newblk), bsize, NOCRED, &bp); - if (error != 0) { + if ((error = bread(vp, lbn, bsize, NOCRED, &bp)) != 0) { brelse(bp); return (error); } if (res) *res = (char *)bp->b_data + blkoff(fs, offset); - /* - * If IN_E4EXTENTS is enabled we would get a wrong offset so - * reset b_offset here. - */ - bp->b_offset = lbn * bsize; - *bpp = bp; - return (0); -normal: - if (*bpp == NULL) { - if ((error = bread(vp, lbn, bsize, NOCRED, &bp)) != 0) { - brelse(bp); - return (error); - } - if (res) - *res = (char *)bp->b_data + blkoff(fs, offset); - *bpp = bp; - } + *bpp = bp; + return (0); } @@ -132,11 +91,12 @@ ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) * Cnt == 1 means free; cnt == -1 means allocating. */ void -ext2_clusteracct(struct m_ext2fs *fs, char *bbp, int cg, daddr_t bno, int cnt) +ext2_clusteracct(struct m_ext2fs *fs, char *bbp, int cg, e4fs_daddr_t bno, int cnt) { int32_t *sump = fs->e2fs_clustersum[cg].cs_sum; int32_t *lp; - int back, bit, end, forw, i, loc, start; + e4fs_daddr_t start, end, loc, forw, back; + int bit, i; /* Initialize the cluster summary array. */ if (fs->e2fs_clustersum[cg].cs_init == 0) { diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index 98d4f0a73b2c..fe509872500c 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -992,6 +992,7 @@ ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) } #ifdef EXT2FS_DEBUG ext2_print_inode(ip); + ext4_ext_print_extent_tree_status(ip); #endif bqrelse(bp); diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index d5fd6260b890..41b046a74e21 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -91,8 +91,6 @@ static int ext2_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); static void ext2_itimes_locked(struct vnode *); -static int ext4_ext_read(struct vop_read_args *); -static int ext2_ind_read(struct vop_read_args *); static vop_access_t ext2_access; static int ext2_chmod(struct vnode *, int, struct ucred *, struct thread *); @@ -630,7 +628,8 @@ ext2_mknod(struct vop_mknod_args *ap) * Want to be able to use this to make badblock * inodes, so don't truncate the dev number. */ - ip->i_rdev = vap->va_rdev; + if (!(ip->i_flag & IN_E4EXTENTS)) + ip->i_rdev = vap->va_rdev; } /* * Remove inode, then reload it through VFS_VGET so it is @@ -1542,7 +1541,12 @@ ext2_strategy(struct vop_strategy_args *ap) if (vp->v_type == VBLK || vp->v_type == VCHR) panic("ext2_strategy: spec"); if (bp->b_blkno == bp->b_lblkno) { - error = ext2_bmaparray(vp, bp->b_lblkno, &blkno, NULL, NULL); + + if (VTOI(ap->a_vp)->i_flag & IN_E4EXTENTS) + error = ext4_bmapext(vp, bp->b_lblkno, &blkno, NULL, NULL); + else + error = ext2_bmaparray(vp, bp->b_lblkno, &blkno, NULL, NULL); + bp->b_blkno = blkno; if (error) { bp->b_error = error; @@ -1987,28 +1991,6 @@ ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, */ static int ext2_read(struct vop_read_args *ap) -{ - struct vnode *vp; - struct inode *ip; - int error; - - vp = ap->a_vp; - ip = VTOI(vp); - - /* EXT4_EXT_LOCK(ip); */ - if (ip->i_flag & IN_E4EXTENTS) - error = ext4_ext_read(ap); - else - error = ext2_ind_read(ap); - /* EXT4_EXT_UNLOCK(ip); */ - return (error); -} - -/* - * Vnode op for reading. - */ -static int -ext2_ind_read(struct vop_read_args *ap) { struct vnode *vp; struct inode *ip; @@ -2130,122 +2112,6 @@ ext2_ioctl(struct vop_ioctl_args *ap) } } -/* - * this function handles ext4 extents block mapping - */ -static int -ext4_ext_read(struct vop_read_args *ap) -{ - static unsigned char zeroes[EXT2_MAX_BLOCK_SIZE]; - struct vnode *vp; - struct inode *ip; - struct uio *uio; - struct m_ext2fs *fs; - struct buf *bp; - struct ext4_extent nex, *ep; - struct ext4_extent_path path; - daddr_t lbn, newblk; - off_t bytesinfile; - int cache_type; - ssize_t orig_resid; - int error; - long size, xfersize, blkoffset; - - vp = ap->a_vp; - ip = VTOI(vp); - uio = ap->a_uio; - memset(&path, 0, sizeof(path)); - - orig_resid = uio->uio_resid; - KASSERT(orig_resid >= 0, ("%s: uio->uio_resid < 0", __func__)); - if (orig_resid == 0) - return (0); - KASSERT(uio->uio_offset >= 0, ("%s: uio->uio_offset < 0", __func__)); - fs = ip->i_e2fs; - if (uio->uio_offset < ip->i_size && uio->uio_offset >= fs->e2fs_maxfilesize) - return (EOVERFLOW); - - while (uio->uio_resid > 0) { - if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0) - break; - lbn = lblkno(fs, uio->uio_offset); - size = blksize(fs, ip, lbn); - blkoffset = blkoff(fs, uio->uio_offset); - - xfersize = fs->e2fs_fsize - blkoffset; - xfersize = MIN(xfersize, uio->uio_resid); - xfersize = MIN(xfersize, bytesinfile); - - /* get block from ext4 extent cache */ - cache_type = ext4_ext_in_cache(ip, lbn, &nex); - switch (cache_type) { - case EXT4_EXT_CACHE_NO: - ext4_ext_find_extent(fs, ip, lbn, &path); - if (path.ep_is_sparse) - ep = &path.ep_sparse_ext; - else - ep = path.ep_ext; - if (ep == NULL) - return (EIO); - - ext4_ext_put_cache(ip, ep, - path.ep_is_sparse ? EXT4_EXT_CACHE_GAP : EXT4_EXT_CACHE_IN); - - newblk = lbn - ep->e_blk + (ep->e_start_lo | - (daddr_t)ep->e_start_hi << 32); - - if (path.ep_bp != NULL) { - brelse(path.ep_bp); - path.ep_bp = NULL; - } - break; - - case EXT4_EXT_CACHE_GAP: - /* block has not been allocated yet */ - break; - - case EXT4_EXT_CACHE_IN: - newblk = lbn - nex.e_blk + (nex.e_start_lo | - (daddr_t)nex.e_start_hi << 32); - break; - - default: - panic("%s: invalid cache type", __func__); - } - - if (cache_type == EXT4_EXT_CACHE_GAP || - (cache_type == EXT4_EXT_CACHE_NO && path.ep_is_sparse)) { - if (xfersize > sizeof(zeroes)) - xfersize = sizeof(zeroes); - error = uiomove(zeroes, xfersize, uio); - if (error) - return (error); - } else { - error = bread(ip->i_devvp, fsbtodb(fs, newblk), size, - NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - - size -= bp->b_resid; - if (size < xfersize) { - if (size == 0) { - bqrelse(bp); - break; - } - xfersize = size; - } - error = uiomove(bp->b_data + blkoffset, xfersize, uio); - bqrelse(bp); - if (error) - return (error); - } - } - - return (0); -} - /* * Vnode op for writing. */ diff --git a/sys/fs/ext2fs/ext2fs.h b/sys/fs/ext2fs/ext2fs.h index ff0457357bd1..b3a321b9ecb2 100644 --- a/sys/fs/ext2fs/ext2fs.h +++ b/sys/fs/ext2fs/ext2fs.h @@ -385,7 +385,6 @@ struct ext2_gd { /* * Macro-instructions used to manage several block sizes */ -#define EXT2_MAX_BLOCK_SIZE 4096 #define EXT2_MIN_BLOCK_LOG_SIZE 10 #define EXT2_BLOCK_SIZE(s) ((s)->e2fs_bsize) #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(uint32_t)) diff --git a/sys/fs/ext2fs/inode.h b/sys/fs/ext2fs/inode.h index c0178d711eae..a65dc1901893 100644 --- a/sys/fs/ext2fs/inode.h +++ b/sys/fs/ext2fs/inode.h @@ -107,8 +107,13 @@ struct inode { uint32_t i_gen; /* Generation number. */ uint64_t i_facl; /* EA block number. */ uint32_t i_flags; /* Status flags (chflags). */ - uint32_t i_db[EXT2_NDADDR]; /* Direct disk blocks. */ - uint32_t i_ib[EXT2_NIADDR]; /* Indirect disk blocks. */ + union { + struct { + uint32_t i_db[EXT2_NDADDR]; /* Direct disk blocks. */ + uint32_t i_ib[EXT2_NIADDR]; /* Indirect disk blocks. */ + }; + uint32_t i_data[EXT2_NDADDR + EXT2_NIADDR]; + }; struct ext4_extent_cache i_ext_cache; /* cache for ext4 extent */ }; diff --git a/sys/fs/fuse/fuse_ipc.c b/sys/fs/fuse/fuse_ipc.c index a22147e7eea3..376dab6b8ecd 100644 --- a/sys/fs/fuse/fuse_ipc.c +++ b/sys/fs/fuse/fuse_ipc.c @@ -636,23 +636,20 @@ fuse_body_audit(struct fuse_ticket *ftick, size_t blen) break; case FUSE_SETXATTR: - panic("FUSE_SETXATTR implementor has forgotten to define a" - " response body format check"); + err = (blen == 0) ? 0 : EINVAL; break; case FUSE_GETXATTR: - panic("FUSE_GETXATTR implementor has forgotten to define a" - " response body format check"); - break; - case FUSE_LISTXATTR: - panic("FUSE_LISTXATTR implementor has forgotten to define a" - " response body format check"); + /* + * These can have varying response lengths, and 0 length + * isn't necessarily invalid. + */ + err = 0; break; case FUSE_REMOVEXATTR: - panic("FUSE_REMOVEXATTR implementor has forgotten to define a" - " response body format check"); + err = (blen == 0) ? 0 : EINVAL; break; case FUSE_FLUSH: diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 0a12e192d36c..a70ff10bf2c1 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -112,10 +113,13 @@ __FBSDID("$FreeBSD$"); static vop_access_t fuse_vnop_access; static vop_close_t fuse_vnop_close; static vop_create_t fuse_vnop_create; +static vop_deleteextattr_t fuse_vnop_deleteextattr; static vop_fsync_t fuse_vnop_fsync; static vop_getattr_t fuse_vnop_getattr; +static vop_getextattr_t fuse_vnop_getextattr; static vop_inactive_t fuse_vnop_inactive; static vop_link_t fuse_vnop_link; +static vop_listextattr_t fuse_vnop_listextattr; static vop_lookup_t fuse_vnop_lookup; static vop_mkdir_t fuse_vnop_mkdir; static vop_mknod_t fuse_vnop_mknod; @@ -128,6 +132,7 @@ static vop_remove_t fuse_vnop_remove; static vop_rename_t fuse_vnop_rename; static vop_rmdir_t fuse_vnop_rmdir; static vop_setattr_t fuse_vnop_setattr; +static vop_setextattr_t fuse_vnop_setextattr; static vop_strategy_t fuse_vnop_strategy; static vop_symlink_t fuse_vnop_symlink; static vop_write_t fuse_vnop_write; @@ -140,10 +145,13 @@ struct vop_vector fuse_vnops = { .vop_access = fuse_vnop_access, .vop_close = fuse_vnop_close, .vop_create = fuse_vnop_create, + .vop_deleteextattr = fuse_vnop_deleteextattr, .vop_fsync = fuse_vnop_fsync, .vop_getattr = fuse_vnop_getattr, + .vop_getextattr = fuse_vnop_getextattr, .vop_inactive = fuse_vnop_inactive, .vop_link = fuse_vnop_link, + .vop_listextattr = fuse_vnop_listextattr, .vop_lookup = fuse_vnop_lookup, .vop_mkdir = fuse_vnop_mkdir, .vop_mknod = fuse_vnop_mknod, @@ -157,6 +165,7 @@ struct vop_vector fuse_vnops = { .vop_rename = fuse_vnop_rename, .vop_rmdir = fuse_vnop_rmdir, .vop_setattr = fuse_vnop_setattr, + .vop_setextattr = fuse_vnop_setextattr, .vop_strategy = fuse_vnop_strategy, .vop_symlink = fuse_vnop_symlink, .vop_write = fuse_vnop_write, @@ -1958,6 +1967,383 @@ fuse_vnop_putpages(struct vop_putpages_args *ap) return rtvals[0]; } +static const char extattr_namespace_separator = '.'; + +/* + struct vop_getextattr_args { + struct vop_generic_args a_gen; + struct vnode *a_vp; + int a_attrnamespace; + const char *a_name; + struct uio *a_uio; + size_t *a_size; + struct ucred *a_cred; + struct thread *a_td; + }; +*/ +static int +fuse_vnop_getextattr(struct vop_getextattr_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct uio *uio = ap->a_uio; + struct fuse_dispatcher fdi = {0}; + struct fuse_getxattr_in *get_xattr_in; + struct fuse_getxattr_out *get_xattr_out; + struct mount *mp = vnode_mount(vp); + char *prefix; + size_t len; + char *attr_str; + struct thread *td = ap->a_td; + struct ucred *cred = ap->a_cred; + int err = 0; + + fuse_trace_printf_vnop(); + + if (fuse_isdeadfs(vp)) + return ENXIO; + + /* Default to looking for user attributes. */ + if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) + prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; + else + prefix = EXTATTR_NAMESPACE_USER_STRING; + + len = strlen(prefix) + sizeof(extattr_namespace_separator) + + strlen(ap->a_name) + 1; + + fdisp_init(&fdi, len + sizeof(*get_xattr_in)); + fdisp_make_vp(&fdi, FUSE_GETXATTR, vp, td, cred); + + get_xattr_in = fdi.indata; + /* + * Check to see whether we're querying the available size or + * issuing the actual request. If we pass in 0, we get back struct + * fuse_getxattr_out. If we pass in a non-zero size, we get back + * that much data, without the struct fuse_getxattr_out header. + */ + if (ap->a_size != NULL) + get_xattr_in->size = 0; + else + get_xattr_in->size = uio->uio_resid; + + attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); + snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, + ap->a_name); + + err = fdisp_wait_answ(&fdi); + + if (err != 0) { + if (err == ENOSYS) + fsess_set_notimpl(mp, FUSE_GETXATTR); + debug_printf("getxattr: got err=%d from daemon\n", err); + goto out; + } + + /* + * If we get to this point (i.e. no error), we should have a valid + * answer of some sort. i.e. non-zero iosize and a valid pointer. + */ + if ((fdi.answ == NULL) || (fdi.iosize == 0)) { + debug_printf("getxattr: err = 0, but answ = %p, iosize = %zu\n", + fdi.answ, fdi.iosize); + err = EINVAL; + goto out; + } + get_xattr_out = fdi.answ; + + if (ap->a_size != NULL) { + *ap->a_size = get_xattr_out->size; + } else if (fdi.iosize > 0) { + err = uiomove(fdi.answ, fdi.iosize, uio); + } else { + err = EINVAL; + } + +out: + fdisp_destroy(&fdi); + return (err); +} + +/* + struct vop_setextattr_args { + struct vop_generic_args a_gen; + struct vnode *a_vp; + int a_attrnamespace; + const char *a_name; + struct uio *a_uio; + struct ucred *a_cred; + struct thread *a_td; + }; +*/ +static int +fuse_vnop_setextattr(struct vop_setextattr_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct uio *uio = ap->a_uio; + struct fuse_dispatcher fdi = {0}; + struct fuse_setxattr_in *set_xattr_in; + struct mount *mp = vnode_mount(vp); + char *prefix; + size_t len; + char *attr_str; + struct thread *td = ap->a_td; + struct ucred *cred = ap->a_cred; + int err = 0; + + fuse_trace_printf_vnop(); + + if (fuse_isdeadfs(vp)) + return ENXIO; + + /* Default to looking for user attributes. */ + if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) + prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; + else + prefix = EXTATTR_NAMESPACE_USER_STRING; + + len = strlen(prefix) + sizeof(extattr_namespace_separator) + + strlen(ap->a_name) + 1; + + fdisp_init(&fdi, len + sizeof(*set_xattr_in) + uio->uio_resid); + fdisp_make_vp(&fdi, FUSE_SETXATTR, vp, td, cred); + + set_xattr_in = fdi.indata; + set_xattr_in->size = uio->uio_resid; + + attr_str = (char *)fdi.indata + sizeof(*set_xattr_in); + snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, + ap->a_name); + + err = uiomove((char *)fdi.indata + sizeof(*set_xattr_in) + len, + uio->uio_resid, uio); + if (err != 0) { + debug_printf("setxattr: got error %d from uiomove\n", err); + goto out; + } + + err = fdisp_wait_answ(&fdi); + + if (err != 0) { + if (err == ENOSYS) + fsess_set_notimpl(mp, FUSE_SETXATTR); + debug_printf("setxattr: got err=%d from daemon\n", err); + goto out; + } + +out: + fdisp_destroy(&fdi); + return (err); +} + +/* + * The Linux / FUSE extended attribute list is simply a collection of + * NUL-terminated strings. The FreeBSD extended attribute list is a single + * byte length followed by a non-NUL terminated string. So, this allows + * conversion of the Linux / FUSE format to the FreeBSD format in place. + * Linux attribute names are reported with the namespace as a prefix (e.g. + * "user.attribute_name"), but in FreeBSD they are reported without the + * namespace prefix (e.g. "attribute_name"). So, we're going from: + * + * user.attr_name1\0user.attr_name2\0 + * + * to: + * + * attr_name1attr_name2 + * + * Where "" is a single byte number of characters in the attribute name. + * + * Args: + * prefix - exattr namespace prefix string + * list, list_len - input list with namespace prefixes + * bsd_list, bsd_list_len - output list compatible with bsd vfs + */ +static int +fuse_xattrlist_convert(char *prefix, const char *list, int list_len, + char *bsd_list, int *bsd_list_len) +{ + int len, pos, dist_to_next, prefix_len; + + pos = 0; + *bsd_list_len = 0; + prefix_len = strlen(prefix); + + while (pos < list_len && list[pos] != '\0') { + dist_to_next = strlen(&list[pos]) + 1; + if (bcmp(&list[pos], prefix, prefix_len) == 0 && + list[pos + prefix_len] == extattr_namespace_separator) { + len = dist_to_next - + (prefix_len + sizeof(extattr_namespace_separator)) - 1; + if (len >= EXTATTR_MAXNAMELEN) + return (ENAMETOOLONG); + + bsd_list[*bsd_list_len] = len; + memcpy(&bsd_list[*bsd_list_len + 1], + &list[pos + prefix_len + + sizeof(extattr_namespace_separator)], len); + + *bsd_list_len += len + 1; + } + + pos += dist_to_next; + } + + return (0); +} + +/* + struct vop_listextattr_args { + struct vop_generic_args a_gen; + struct vnode *a_vp; + int a_attrnamespace; + struct uio *a_uio; + size_t *a_size; + struct ucred *a_cred; + struct thread *a_td; + }; +*/ +static int +fuse_vnop_listextattr(struct vop_listextattr_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct uio *uio = ap->a_uio; + struct fuse_dispatcher fdi = {0}; + struct fuse_getxattr_in *get_xattr_in; + struct fuse_getxattr_out *get_xattr_out; + struct mount *mp = vnode_mount(vp); + size_t len; + char *prefix; + char *attr_str; + char *bsd_list = NULL; + int bsd_list_len; + struct thread *td = ap->a_td; + struct ucred *cred = ap->a_cred; + int err = 0; + + fuse_trace_printf_vnop(); + + if (fuse_isdeadfs(vp)) + return ENXIO; + + /* + * Add space for a NUL and the period separator if enabled. + * Default to looking for user attributes. + */ + if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) + prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; + else + prefix = EXTATTR_NAMESPACE_USER_STRING; + + len = strlen(prefix) + sizeof(extattr_namespace_separator) + 1; + + fdisp_init(&fdi, sizeof(*get_xattr_in) + len); + fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); + + get_xattr_in = fdi.indata; + if (ap->a_size != NULL) + get_xattr_in->size = 0; + else + get_xattr_in->size = uio->uio_resid + sizeof(*get_xattr_out); + + + attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); + snprintf(attr_str, len, "%s%c", prefix, extattr_namespace_separator); + + err = fdisp_wait_answ(&fdi); + if (err != 0) { + if (err == ENOSYS) + fsess_set_notimpl(mp, FUSE_LISTXATTR); + debug_printf("listextattr: got err=%d from daemon\n", err); + goto out; + } + + if ((fdi.answ == NULL) || (fdi.iosize == 0)) { + err = EINVAL; + goto out; + } + get_xattr_out = fdi.answ; + + if (ap->a_size != NULL) { + *ap->a_size = get_xattr_out->size; + } else if (fdi.iosize > 0) { + /* + * The Linux / FUSE attribute list format isn't the same + * as FreeBSD's format. So we need to transform it into + * FreeBSD's format before giving it to the user. + */ + bsd_list = malloc(fdi.iosize, M_TEMP, M_WAITOK); + err = fuse_xattrlist_convert(prefix, fdi.answ, fdi.iosize, + bsd_list, &bsd_list_len); + if (err != 0) + goto out; + + err = uiomove(bsd_list, bsd_list_len, uio); + } else { + debug_printf("listextattr: returned iosize %zu for %s attribute list is " + "too small\n", fdi.iosize, prefix); + err = EINVAL; + } + +out: + free(bsd_list, M_TEMP); + fdisp_destroy(&fdi); + return (err); +} + +/* + struct vop_deleteextattr_args { + struct vop_generic_args a_gen; + struct vnode *a_vp; + int a_attrnamespace; + const char *a_name; + struct ucred *a_cred; + struct thread *a_td; + }; +*/ +static int +fuse_vnop_deleteextattr(struct vop_deleteextattr_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct fuse_dispatcher fdi = {0}; + struct mount *mp = vnode_mount(vp); + char *prefix; + size_t len; + char *attr_str; + struct thread *td = ap->a_td; + struct ucred *cred = ap->a_cred; + int err; + + fuse_trace_printf_vnop(); + + if (fuse_isdeadfs(vp)) + return ENXIO; + + /* Default to looking for user attributes. */ + if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) + prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; + else + prefix = EXTATTR_NAMESPACE_USER_STRING; + + len = strlen(prefix) + sizeof(extattr_namespace_separator) + + strlen(ap->a_name) + 1; + + fdisp_init(&fdi, len); + fdisp_make_vp(&fdi, FUSE_REMOVEXATTR, vp, td, cred); + + attr_str = fdi.indata; + snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, + ap->a_name); + + err = fdisp_wait_answ(&fdi); + if (err != 0) { + if (err == ENOSYS) + fsess_set_notimpl(mp, FUSE_REMOVEXATTR); + debug_printf("removexattr: got err=%d from daemon\n", err); + } + + fdisp_destroy(&fdi); + return (err); +} + /* struct vnop_print_args { struct vnode *a_vp; diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c index 6d92c60be355..debf1984782f 100644 --- a/sys/fs/msdosfs/msdosfs_conv.c +++ b/sys/fs/msdosfs/msdosfs_conv.c @@ -594,7 +594,7 @@ winChkName(struct mbnambuf *nbp, const u_char *un, size_t unlen, int chksum, return -1; #ifdef MSDOSFS_DEBUG - printf("winChkName(): un=%s:%d,d_name=%s:%d\n", un, unlen, + printf("winChkName(): un=%s:%zu,d_name=%s:%d\n", un, unlen, dirbuf.d_name, dirbuf.d_namlen); #endif diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c index 4b1f0c70472b..1c67568273f1 100644 --- a/sys/fs/msdosfs/msdosfs_denode.c +++ b/sys/fs/msdosfs/msdosfs_denode.c @@ -590,8 +590,9 @@ msdosfs_inactive(struct vop_inactive_args *ap) * as empty. (This may not be necessary for the dos filesystem.) */ #ifdef MSDOSFS_DEBUG - printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %x, MNT_RDONLY %x\n", - dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY); + printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %llx, MNT_RDONLY %llx\n", + dep, dep->de_refcnt, (unsigned long long)vp->v_mount->mnt_flag, + (unsigned long long)MNT_RDONLY); #endif if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { error = detrunc(dep, (u_long) 0, 0, NOCRED); diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 30b463c46083..237c1b9592c3 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -75,6 +75,10 @@ #include #include +#ifdef MSDOSFS_DEBUG +#include +#endif + static const char msdosfs_lock_msg[] = "fatlk"; /* Mount options that we support. */ diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 2af5ae0c892e..1a3b8bbc10dc 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -348,10 +348,13 @@ msdosfs_setattr(struct vop_setattr_args *ap) (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { #ifdef MSDOSFS_DEBUG printf("msdosfs_setattr(): returning EINVAL\n"); - printf(" va_type %d, va_nlink %x, va_fsid %lx, va_fileid %lx\n", - vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid); - printf(" va_blocksize %lx, va_rdev %x, va_bytes %qx, va_gen %lx\n", - vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen); + printf(" va_type %d, va_nlink %llx, va_fsid %llx, va_fileid %llx\n", + vap->va_type, (unsigned long long)vap->va_nlink, + (unsigned long long)vap->va_fsid, + (unsigned long long)vap->va_fileid); + printf(" va_blocksize %lx, va_rdev %llx, va_bytes %llx, va_gen %lx\n", + vap->va_blocksize, (unsigned long long)vap->va_rdev, + (unsigned long long)vap->va_bytes, vap->va_gen); printf(" va_uid %x, va_gid %x\n", vap->va_uid, vap->va_gid); #endif diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 2661e1270cdb..75439e370dba 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -176,6 +176,17 @@ struct nfsd_nfsd_args { int maxthreads; /* maximum service thread count */ }; +/* + * NFSDEV_MIRRORSTR - string of digits that number the DSs 0->999. + * (To support more than 1000 DSs on an MDS, this needs to be increased.) + * NFSDEV_MAXMIRRORS - Maximum # of mirrors for a DS. + * (Most will only have a single mirror, but this setting allows up to 3.) + * NFSDEV_MAXVERS - maximum number of NFS versions supported by Flex File. + */ +#define NFSDEV_MIRRORSTR 3 +#define NFSDEV_MAXMIRRORS 4 +#define NFSDEV_MAXVERS 4 + /* * Arguments for use by the callback daemon. */ diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 8faf192ddb9f..ec912767dc34 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1121,9 +1121,29 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, int newnfs_nmcancelreqs(struct nfsmount *nmp) { + struct nfsclds *dsp; + struct __rpc_client *cl; if (nmp->nm_sockreq.nr_client != NULL) CLNT_CLOSE(nmp->nm_sockreq.nr_client); +lookformore: + NFSLOCKMNT(nmp); + TAILQ_FOREACH(dsp, &nmp->nm_sess, nfsclds_list) { + NFSLOCKDS(dsp); + if (dsp != TAILQ_FIRST(&nmp->nm_sess) && + (dsp->nfsclds_flags & NFSCLDS_CLOSED) == 0 && + dsp->nfsclds_sockp != NULL && + dsp->nfsclds_sockp->nr_client != NULL) { + dsp->nfsclds_flags |= NFSCLDS_CLOSED; + cl = dsp->nfsclds_sockp->nr_client; + NFSUNLOCKDS(dsp); + NFSUNLOCKMNT(nmp); + CLNT_CLOSE(cl); + goto lookformore; + } + NFSUNLOCKDS(dsp); + } + NFSUNLOCKMNT(nmp); return (0); } diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index cebacaf6c531..853753c86636 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$"); * to this BSD variant. */ #include +#include #include +#include #include #include #include @@ -68,6 +70,8 @@ int nfsrv_lughashsize = 100; void (*nfsd_call_servertimer)(void) = NULL; void (*ncl_call_invalcaches)(struct vnode *) = NULL; +int nfs_pnfsio(task_fn_t *, void *); + static int nfs_realign_test; static int nfs_realign_count; static struct ext_nfsstats oldnfsstats; @@ -84,6 +88,9 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, debuglevel, CTLFLAG_RW, &nfscl_debuglevel, 0, "Debug level for NFS client"); SYSCTL_INT(_vfs_nfs, OID_AUTO, userhashsize, CTLFLAG_RDTUN, &nfsrv_lughashsize, 0, "Size of hash tables for uid/name mapping"); +int nfs_pnfsiothreads = 0; +SYSCTL_INT(_vfs_nfs, OID_AUTO, pnfsiothreads, CTLFLAG_RW, &nfs_pnfsiothreads, + 0, "Number of pNFS mirror I/O threads"); /* * Defines for malloc @@ -691,6 +698,50 @@ nfs_supportsnfsv4acls(struct vnode *vp) return (0); } +/* + * These are the first fields of all the context structures passed into + * nfs_pnfsio(). + */ +struct pnfsio { + int done; + int inprog; + struct task tsk; +}; + +/* + * Do a mirror I/O on a pNFS thread. + */ +int +nfs_pnfsio(task_fn_t *func, void *context) +{ + struct pnfsio *pio; + int ret; + static struct taskqueue *pnfsioq = NULL; + + pio = (struct pnfsio *)context; + if (pnfsioq == NULL) { + if (nfs_pnfsiothreads == 0) + nfs_pnfsiothreads = mp_ncpus * 4; + pnfsioq = taskqueue_create("pnfsioq", M_WAITOK, + taskqueue_thread_enqueue, &pnfsioq); + if (pnfsioq == NULL) + return (ENOMEM); + ret = taskqueue_start_threads(&pnfsioq, nfs_pnfsiothreads, + 0, "pnfsiot"); + if (ret != 0) { + taskqueue_free(pnfsioq); + pnfsioq = NULL; + return (ret); + } + } + pio->inprog = 1; + TASK_INIT(&pio->tsk, 0, func, context); + ret = taskqueue_enqueue(pnfsioq, &pio->tsk); + if (ret != 0) + pio->inprog = 0; + return (ret); +} + extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *); /* diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index f1e003df8f84..e198218ca978 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -3938,14 +3938,13 @@ newnfs_sndunlock(int *flagp) } APPLESTATIC int -nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_storage *sa, - int *isudp) +nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_in *sin, + struct sockaddr_in6 *sin6, sa_family_t *saf, int *isudp) { - struct sockaddr_in *sad; - struct sockaddr_in6 *sad6; struct in_addr saddr; uint32_t portnum, *tl; - int af = 0, i, j, k; + int i, j, k; + sa_family_t af = AF_UNSPEC; char addr[64], protocol[5], *cp; int cantparse = 0, error = 0; uint16_t portv; @@ -4023,20 +4022,20 @@ nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_storage *sa, cantparse = 1; if (cantparse == 0) { if (af == AF_INET) { - sad = (struct sockaddr_in *)sa; - if (inet_pton(af, addr, &sad->sin_addr) == 1) { - sad->sin_len = sizeof(*sad); - sad->sin_family = AF_INET; - sad->sin_port = htons(portv); + if (inet_pton(af, addr, &sin->sin_addr) == 1) { + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_port = htons(portv); + *saf = af; return (0); } } else { - sad6 = (struct sockaddr_in6 *)sa; - if (inet_pton(af, addr, &sad6->sin6_addr) + if (inet_pton(af, addr, &sin6->sin6_addr) == 1) { - sad6->sin6_len = sizeof(*sad6); - sad6->sin6_family = AF_INET6; - sad6->sin6_port = htons(portv); + sin6->sin6_len = sizeof(*sin6); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons(portv); + *saf = af; return (0); } } diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 7c0008242bd8..86db40ec1521 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -287,8 +287,8 @@ void nfsrv_cleanusergroup(void); int nfsrv_checkutf8(u_int8_t *, int); int newnfs_sndlock(int *); void newnfs_sndunlock(int *); -int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_storage *, - int *); +int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_in *, + struct sockaddr_in6 *, sa_family_t *, int *); int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *, struct mbuf **, uint16_t); void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **); @@ -301,8 +301,9 @@ struct ucred *nfsrv_getgrpscred(struct ucred *); /* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); +struct mbuf *nfsm_uiombuflist(struct uio *, int, struct mbuf **, char **); void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *, - u_int8_t *, int, u_int32_t **, struct nfsclsession *); + u_int8_t *, int, u_int32_t **, struct nfsclsession *, int, int); nfsuint64 *nfscl_getcookie(struct nfsnode *, off_t off, int); void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *, vnode_t, int, u_int32_t); @@ -478,17 +479,14 @@ int nfsrpc_destroysession(struct nfsmount *, struct nfsclclient *, struct ucred *, NFSPROC_T *); int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *, struct ucred *, NFSPROC_T *); -int nfsrpc_layoutget(struct nfsmount *, uint8_t *, int, int, uint64_t, uint64_t, - uint64_t, int, nfsv4stateid_t *, int *, struct nfsclflayouthead *, - struct ucred *, NFSPROC_T *, void *); int nfsrpc_getdeviceinfo(struct nfsmount *, uint8_t *, int, uint32_t *, struct nfscldevinfo **, struct ucred *, NFSPROC_T *); int nfsrpc_layoutcommit(struct nfsmount *, uint8_t *, int, int, - uint64_t, uint64_t, uint64_t, nfsv4stateid_t *, int, int, uint8_t *, - struct ucred *, NFSPROC_T *, void *); -int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t, - int, uint64_t, uint64_t, nfsv4stateid_t *, int, uint32_t *, struct ucred *, + uint64_t, uint64_t, uint64_t, nfsv4stateid_t *, int, struct ucred *, NFSPROC_T *, void *); +int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t, + int, uint64_t, uint64_t, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, + void *); int nfsrpc_reclaimcomplete(struct nfsmount *, struct ucred *, NFSPROC_T *); int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, int, struct ucred *, NFSPROC_T *); @@ -557,7 +555,7 @@ int nfscl_tryclose(struct nfsclopen *, struct ucred *, struct nfsmount *, NFSPROC_T *); void nfscl_cleanup(NFSPROC_T *); int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t *, int, nfsv4stateid_t *, - int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *, + int, int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *, NFSPROC_T *); struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int, uint64_t, struct nfsclflayout **, int *); diff --git a/sys/fs/nfs/nfscl.h b/sys/fs/nfs/nfscl.h index 903efb2e468e..5e7c690a5a79 100644 --- a/sys/fs/nfs/nfscl.h +++ b/sys/fs/nfs/nfscl.h @@ -49,7 +49,8 @@ struct nfsv4node { */ #define NFSCL_REQSTART(n, p, v) \ nfscl_reqstart((n), (p), VFSTONFS((v)->v_mount), \ - VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL, NULL) + VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL, \ + NULL, 0, 0) /* * These two macros convert between a lease duration and renew interval. diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index ffc50ead64d7..ceef870b9c7c 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -91,6 +91,7 @@ struct nfsclds { #define NFSCLDS_HASWRITEVERF 0x0001 #define NFSCLDS_MDS 0x0002 #define NFSCLDS_DS 0x0004 +#define NFSCLDS_CLOSED 0x0008 struct nfsclclient { LIST_ENTRY(nfsclclient) nfsc_list; @@ -258,9 +259,24 @@ struct nfscllayout { #define NFSLY_RECALLALL 0x0040 #define NFSLY_RETONCLOSE 0x0080 #define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */ +#define NFSLY_FLEXFILE 0x0200 /* - * MALLOC'd to the correct length to accommodate the file handle list. + * Flex file layout mirror specific stuff for nfsclflayout. + */ +struct nfsffm { + nfsv4stateid_t st; + char dev[NFSX_V4DEVICEID]; + uint32_t eff; + uid_t user; + gid_t group; + struct nfsfh *fh[NFSDEV_MAXVERS]; + uint16_t fhcnt; +}; + +/* + * MALLOC'd to the correct length to accommodate the file handle list for File + * layout and the list of mirrors for the Flex File Layout. * These hang off of nfsly_flayread and nfsly_flayrw, sorted in increasing * offset order. * The nfsly_flayread list holds the ones with iomode == NFSLAYOUTIOMODE_READ, @@ -268,23 +284,49 @@ struct nfscllayout { */ struct nfsclflayout { LIST_ENTRY(nfsclflayout) nfsfl_list; - uint8_t nfsfl_dev[NFSX_V4DEVICEID]; uint64_t nfsfl_off; uint64_t nfsfl_end; - uint64_t nfsfl_patoff; - struct nfscldevinfo *nfsfl_devp; uint32_t nfsfl_iomode; - uint32_t nfsfl_util; - uint32_t nfsfl_stripe1; + struct nfscldevinfo *nfsfl_devp; uint16_t nfsfl_flags; - uint16_t nfsfl_fhcnt; - struct nfsfh *nfsfl_fh[1]; /* FH list for DS */ + union { + struct { + uint64_t patoff; + uint32_t util; + uint32_t stripe1; + uint8_t dev[NFSX_V4DEVICEID]; + uint16_t fhcnt; + } fl; + struct { + uint64_t stripeunit; + uint32_t fflags; + uint32_t statshint; + uint16_t mirrorcnt; + } ff; + } nfsfl_un; + union { + struct nfsfh *fh[0]; /* FH list for DS File layout */ + struct nfsffm ffm[0]; /* Mirror list for Flex File */ + } nfsfl_un2; /* Must be last. Malloc'd to correct array length */ }; +#define nfsfl_patoff nfsfl_un.fl.patoff +#define nfsfl_util nfsfl_un.fl.util +#define nfsfl_stripe1 nfsfl_un.fl.stripe1 +#define nfsfl_dev nfsfl_un.fl.dev +#define nfsfl_fhcnt nfsfl_un.fl.fhcnt +#define nfsfl_stripeunit nfsfl_un.ff.stripeunit +#define nfsfl_fflags nfsfl_un.ff.fflags +#define nfsfl_statshint nfsfl_un.ff.statshint +#define nfsfl_mirrorcnt nfsfl_un.ff.mirrorcnt +#define nfsfl_fh nfsfl_un2.fh +#define nfsfl_ffm nfsfl_un2.ffm /* * Flags for nfsfl_flags. */ #define NFSFL_RECALL 0x0001 /* File layout has been recalled */ +#define NFSFL_FILE 0x0002 /* File layout */ +#define NFSFL_FLEXFILE 0x0004 /* Flex File layout */ /* * Structure that is used to store a LAYOUTRECALL. @@ -306,6 +348,7 @@ struct nfsclrecalllayout { * - stripe indices, each stored as one byte, since there can be many * of them. (This implies a limit of 256 on nfsdi_addrcnt, since the * indices select which address.) + * For Flex File, the addrcnt is always one and no stripe indices exist. */ struct nfscldevinfo { LIST_ENTRY(nfscldevinfo) nfsdi_list; @@ -313,10 +356,33 @@ struct nfscldevinfo { struct nfsclclient *nfsdi_clp; uint32_t nfsdi_refcnt; uint32_t nfsdi_layoutrefs; - uint16_t nfsdi_stripecnt; + union { + struct { + uint16_t stripecnt; + } fl; + struct { + int versindex; + uint32_t vers; + uint32_t minorvers; + uint32_t rsize; + uint32_t wsize; + } ff; + } nfsdi_un; uint16_t nfsdi_addrcnt; + uint16_t nfsdi_flags; struct nfsclds *nfsdi_data[0]; }; +#define nfsdi_stripecnt nfsdi_un.fl.stripecnt +#define nfsdi_versindex nfsdi_un.ff.versindex +#define nfsdi_vers nfsdi_un.ff.vers +#define nfsdi_minorvers nfsdi_un.ff.minorvers +#define nfsdi_rsize nfsdi_un.ff.rsize +#define nfsdi_wsize nfsdi_un.ff.wsize + +/* Flags for nfsdi_flags. */ +#define NFSDI_FILELAYOUT 0x0001 +#define NFSDI_FLEXFILE 0x0002 +#define NFSDI_TIGHTCOUPLED 0X0004 /* These inline functions return values from nfsdi_data[]. */ /* diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index f537372cd48f..ff4390bf7d97 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -896,6 +896,7 @@ int newnfs_realign(struct mbuf **, int); #define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier */ #define NFSSTA_GOTFSINFO 0x00100000 /* Got the fsinfo */ #define NFSSTA_OPENMODE 0x00200000 /* Must use correct open mode */ +#define NFSSTA_FLEXFILE 0x00800000 /* Use Flex File Layout */ #define NFSSTA_NOLAYOUTCOMMIT 0x04000000 /* Don't do LayoutCommit */ #define NFSSTA_SESSPERSIST 0x08000000 /* Has a persistent session */ #define NFSSTA_TIMEO 0x10000000 /* Experiencing a timeout */ @@ -926,6 +927,7 @@ int newnfs_realign(struct mbuf **, int); #define NFSHASNOLAYOUTCOMMIT(n) ((n)->nm_state & NFSSTA_NOLAYOUTCOMMIT) #define NFSHASSESSPERSIST(n) ((n)->nm_state & NFSSTA_SESSPERSIST) #define NFSHASPNFS(n) ((n)->nm_state & NFSSTA_PNFS) +#define NFSHASFLEXFILE(n) ((n)->nm_state & NFSSTA_FLEXFILE) #define NFSHASOPENMODE(n) ((n)->nm_state & NFSSTA_OPENMODE) #define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \ (n)->nm_minorvers > 0) diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index 13c7c3327837..ab346621935e 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -637,6 +637,7 @@ #define NFSLAYOUT_NFSV4_1_FILES 0x1 #define NFSLAYOUT_OSD2_OBJECTS 0x2 #define NFSLAYOUT_BLOCK_VOLUME 0x3 +#define NFSLAYOUT_FLEXFILE 0x4 #define NFSLAYOUTIOMODE_READ 1 #define NFSLAYOUTIOMODE_RW 2 @@ -650,6 +651,12 @@ #define NFSFLAYUTIL_DENSE 0x1 #define NFSFLAYUTIL_COMMIT_THRU_MDS 0x2 +/* Flags for Flex File Layout. */ +#define NFSFLEXFLAG_NO_LAYOUTCOMMIT 0x00000001 +#define NFSFLEXFLAG_NOIO_MDS 0x00000002 +#define NFSFLEXFLAG_NO_READIO 0x00000004 +#define NFSFLEXFLAG_WRITE_ONEMIRROR 0x00000008 + /* Conversion macros */ #define vtonfsv2_mode(t,m) \ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c index cf3ab8e43b3b..e060b31f9c3c 100644 --- a/sys/fs/nfsclient/nfs_clcomsubs.c +++ b/sys/fs/nfsclient/nfs_clcomsubs.c @@ -131,7 +131,8 @@ static int nfs_bigrequest[NFSV41_NPROCS] = { */ APPLESTATIC void nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, - u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep) + u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, + int vers, int minorvers) { struct mbuf *mb; u_int32_t *tl; @@ -142,14 +143,22 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, * First, fill in some of the fields of nd. */ nd->nd_slotseq = NULL; - if (NFSHASNFSV4(nmp)) { + if (vers == NFS_VER4) { nd->nd_flag = ND_NFSV4 | ND_NFSCL; - if (NFSHASNFSV4N(nmp)) + if (minorvers == NFSV41_MINORVERSION) nd->nd_flag |= ND_NFSV41; - } else if (NFSHASNFSV3(nmp)) + } else if (vers == NFS_VER3) nd->nd_flag = ND_NFSV3 | ND_NFSCL; - else - nd->nd_flag = ND_NFSV2 | ND_NFSCL; + else { + if (NFSHASNFSV4(nmp)) { + nd->nd_flag = ND_NFSV4 | ND_NFSCL; + if (NFSHASNFSV4N(nmp)) + nd->nd_flag |= ND_NFSV41; + } else if (NFSHASNFSV3(nmp)) + nd->nd_flag = ND_NFSV3 | ND_NFSCL; + else + nd->nd_flag = ND_NFSV2 | ND_NFSCL; + } nd->nd_procnum = procnum; nd->nd_repstat = 0; @@ -250,7 +259,6 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]); } -#ifndef APPLE /* * copies a uio scatter/gather list to an mbuf chain. * NOTE: can ony handle iovcnt == 1 @@ -332,7 +340,77 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz) nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp); nd->nd_mb = mp; } -#endif /* !APPLE */ + +/* + * copies a uio scatter/gather list to an mbuf chain. + * This version returns the mbuf list and does not use "nd". + * NOTE: can ony handle iovcnt == 1 + */ +struct mbuf * +nfsm_uiombuflist(struct uio *uiop, int siz, struct mbuf **mbp, char **cpp) +{ + char *uiocp; + struct mbuf *mp, *mp2, *firstmp; + int xfer, left, mlen; + int uiosiz, clflg, rem; + char *tcp; + + KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1")); + + if (siz > ncl_mbuf_mlen) /* or should it >= MCLBYTES ?? */ + clflg = 1; + else + clflg = 0; + rem = NFSM_RNDUP(siz) - siz; + if (clflg != 0) + NFSMCLGET(mp, M_WAITOK); + else + NFSMGET(mp); + mbuf_setlen(mp, 0); + firstmp = mp2 = mp; + while (siz > 0) { + left = uiop->uio_iov->iov_len; + uiocp = uiop->uio_iov->iov_base; + if (left > siz) + left = siz; + uiosiz = left; + while (left > 0) { + mlen = M_TRAILINGSPACE(mp); + if (mlen == 0) { + if (clflg) + NFSMCLGET(mp, M_WAITOK); + else + NFSMGET(mp); + mbuf_setlen(mp, 0); + mbuf_setnext(mp2, mp); + mp2 = mp; + mlen = M_TRAILINGSPACE(mp); + } + xfer = (left > mlen) ? mlen : left; + if (uiop->uio_segflg == UIO_SYSSPACE) + NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + + mbuf_len(mp), xfer); + else + copyin(uiocp, NFSMTOD(mp, caddr_t) + + mbuf_len(mp), xfer); + mbuf_setlen(mp, mbuf_len(mp) + xfer); + left -= xfer; + uiocp += xfer; + uiop->uio_offset += xfer; + uiop->uio_resid -= xfer; + } + tcp = (char *)uiop->uio_iov->iov_base; + tcp += uiosiz; + uiop->uio_iov->iov_base = (void *)tcp; + uiop->uio_iov->iov_len -= uiosiz; + siz -= uiosiz; + } + if (cpp != NULL) + *cpp = NFSMTOD(mp, caddr_t) + mbuf_len(mp); + if (mbp != NULL) + *mbp = mp; + return (firstmp); +} /* * Load vnode attributes from the xdr file attributes. diff --git a/sys/fs/nfsclient/nfs_clkdtrace.c b/sys/fs/nfsclient/nfs_clkdtrace.c index 540daae70559..180198fc3f4d 100644 --- a/sys/fs/nfsclient/nfs_clkdtrace.c +++ b/sys/fs/nfsclient/nfs_clkdtrace.c @@ -162,16 +162,16 @@ static char *dtnfsclient_miss_str = "miss"; static char *dtnfsclient_start_str = "start"; static dtrace_pops_t dtnfsclient_pops = { - dtnfsclient_provide, - NULL, - dtnfsclient_enable, - dtnfsclient_disable, - NULL, - NULL, - dtnfsclient_getargdesc, - NULL, - NULL, - dtnfsclient_destroy + .dtps_provide = dtnfsclient_provide, + .dtps_provide_module = NULL, + .dtps_enable = dtnfsclient_enable, + .dtps_disable = dtnfsclient_disable, + .dtps_suspend = NULL, + .dtps_resume = NULL, + .dtps_getargdesc = dtnfsclient_getargdesc, + .dtps_getargval = NULL, + .dtps_usermode = NULL, + .dtps_destroy = dtnfsclient_destroy }; static dtrace_provider_id_t dtnfsclient_id; diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 654bb9c054d4..4c1d78f2a2b8 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include SYSCTL_DECL(_vfs_nfs); @@ -64,6 +65,7 @@ extern nfstype nfsv34_type[9]; extern int nfsrv_useacl; extern char nfsv4_callbackaddr[INET6_ADDRSTRLEN]; extern int nfscl_debuglevel; +extern int nfs_pnfsiothreads; NFSCLSTATEMUTEX; int nfstest_outofseq = 0; int nfscl_assumeposixlocks = 1; @@ -87,6 +89,30 @@ enum nfsclds_state { NFSDSP_NOTFOUND = 2, }; +/* + * Do a write RPC on a DS data file, using this structure for the arguments, + * so that this function can be executed by a separate kernel process. + */ +struct nfsclwritedsdorpc { + int done; + int inprog; + struct task tsk; + struct vnode *vp; + int iomode; + int must_commit; + nfsv4stateid_t *stateidp; + struct nfsclds *dsp; + uint64_t off; + int len; + struct nfsfh *fhp; + struct mbuf *m; + int vers; + int minorvers; + struct ucred *cred; + NFSPROC_T *p; + int err; +}; + static int nfsrpc_setattrrpc(vnode_t , struct vattr *, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); static int nfsrpc_readrpc(vnode_t , struct uio *, struct ucred *, @@ -109,25 +135,41 @@ static int nfsrpc_setaclrpc(vnode_t, struct ucred *, NFSPROC_T *, static int nfsrpc_getlayout(struct nfsmount *, vnode_t, struct nfsfh *, int, uint32_t *, nfsv4stateid_t *, uint64_t, struct nfscllayout **, struct ucred *, NFSPROC_T *); -static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_storage *, - struct nfsclds **, NFSPROC_T *); +static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_in *, + struct sockaddr_in6 *, sa_family_t, int, struct nfsclds **, NFSPROC_T *); static void nfscl_initsessionslots(struct nfsclsession *); static int nfscl_doflayoutio(vnode_t, struct uio *, int *, int *, int *, nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *, struct nfsclflayout *, uint64_t, uint64_t, int, struct ucred *, NFSPROC_T *); +static int nfscl_dofflayoutio(vnode_t, struct uio *, int *, int *, int *, + nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *, + struct nfsclflayout *, uint64_t, uint64_t, int, int, struct mbuf *, + struct nfsclwritedsdorpc *, struct ucred *, NFSPROC_T *); +static struct mbuf *nfsm_copym(struct mbuf *, int, int); static int nfsrpc_readds(vnode_t, struct uio *, nfsv4stateid_t *, int *, - struct nfsclds *, uint64_t, int, struct nfsfh *, struct ucred *, - NFSPROC_T *); + struct nfsclds *, uint64_t, int, struct nfsfh *, int, int, int, + struct ucred *, NFSPROC_T *); static int nfsrpc_writeds(vnode_t, struct uio *, int *, int *, nfsv4stateid_t *, struct nfsclds *, uint64_t, int, - struct nfsfh *, int, struct ucred *, NFSPROC_T *); + struct nfsfh *, int, int, int, int, struct ucred *, NFSPROC_T *); +static int nfsio_writedsmir(vnode_t, int *, int *, nfsv4stateid_t *, + struct nfsclds *, uint64_t, int, struct nfsfh *, struct mbuf *, int, int, + struct nfsclwritedsdorpc *, struct ucred *, NFSPROC_T *); +static int nfsrpc_writedsmir(vnode_t, int *, int *, nfsv4stateid_t *, + struct nfsclds *, uint64_t, int, struct nfsfh *, struct mbuf *, int, int, + struct ucred *, NFSPROC_T *); static enum nfsclds_state nfscl_getsameserver(struct nfsmount *, struct nfsclds *, struct nfsclds **); +static int nfsio_commitds(vnode_t, uint64_t, int, struct nfsclds *, + struct nfsfh *, int, int, struct nfsclwritedsdorpc *, struct ucred *, + NFSPROC_T *); static int nfsrpc_commitds(vnode_t, uint64_t, int, struct nfsclds *, - struct nfsfh *, struct ucred *, NFSPROC_T *); + struct nfsfh *, int, int, struct ucred *, NFSPROC_T *); static void nfsrv_setuplayoutget(struct nfsrv_descript *, int, uint64_t, - uint64_t, uint64_t, nfsv4stateid_t *, int, int); + uint64_t, uint64_t, nfsv4stateid_t *, int, int, int); +static int nfsrv_parseug(struct nfsrv_descript *, int, uid_t *, gid_t *, + NFSPROC_T *); static int nfsrv_parselayoutget(struct nfsrv_descript *, nfsv4stateid_t *, int *, struct nfsclflayouthead *); static int nfsrpc_getopenlayout(struct nfsmount *, vnode_t, u_int8_t *, @@ -139,16 +181,21 @@ static int nfsrpc_getcreatelayout(vnode_t, char *, int, struct vattr *, struct nfsfh **, int *, int *, void *, int *); static int nfsrpc_openlayoutrpc(struct nfsmount *, vnode_t, u_int8_t *, int, uint8_t *, int, uint32_t, struct nfsclopen *, uint8_t *, int, - struct nfscldeleg **, nfsv4stateid_t *, int, int, int *, + struct nfscldeleg **, nfsv4stateid_t *, int, int, int, int *, struct nfsclflayouthead *, int *, struct ucred *, NFSPROC_T *); static int nfsrpc_createlayout(vnode_t, char *, int, struct vattr *, nfsquad_t, int, struct nfsclowner *, struct nfscldeleg **, struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *, struct nfsfh **, int *, int *, void *, int *, nfsv4stateid_t *, - int, int, int *, struct nfsclflayouthead *, int *); + int, int, int, int *, struct nfsclflayouthead *, int *); +static int nfsrpc_layoutget(struct nfsmount *, uint8_t *, int, int, uint64_t, + uint64_t, uint64_t, int, int, nfsv4stateid_t *, int *, + struct nfsclflayouthead *, struct ucred *, NFSPROC_T *, void *); static int nfsrpc_layoutgetres(struct nfsmount *, vnode_t, uint8_t *, int, nfsv4stateid_t *, int, uint32_t *, struct nfscllayout **, - struct nfsclflayouthead *, int, int *, struct ucred *, NFSPROC_T *); + struct nfsclflayouthead *, int, int, int *, struct ucred *, NFSPROC_T *); + +int nfs_pnfsio(task_fn_t *, void *); /* * nfs null call from vfs. @@ -426,7 +473,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, dp = *dpp; *dpp = NULL; - nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); @@ -782,7 +829,7 @@ nfsrpc_closerpc(struct nfsrv_descript *nd, struct nfsmount *nmp, int error; nfscl_reqstart(nd, NFSPROC_CLOSE, nmp, op->nfso_fh, - op->nfso_fhlen, NULL, NULL); + op->nfso_fhlen, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); if (NFSHASNFSV4N(nmp)) @@ -824,7 +871,8 @@ nfsrpc_openconfirm(vnode_t vp, u_int8_t *nfhp, int fhlen, nmp = VFSTONFS(vnode_mount(vp)); if (NFSHASNFSV4N(nmp)) return (0); /* No confirmation for NFSv4.1. */ - nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, nmp, nfhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, nmp, nfhp, fhlen, NULL, NULL, + 0, 0); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); *tl++ = op->nfso_stateid.seqid; *tl++ = op->nfso_stateid.other[0]; @@ -938,7 +986,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, tsep = NFSMNT_MDSSESSION(nmp); NFSUNLOCKMNT(nmp); - nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsboottime.tv_sec); *tl = txdr_unsigned(clp->nfsc_rev); @@ -1008,7 +1056,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, * and confirm it. */ nfscl_reqstart(nd, NFSPROC_SETCLIENTIDCFRM, nmp, NULL, 0, NULL, - NULL); + NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED); *tl++ = tsep->nfsess_clientid.lval[0]; *tl++ = tsep->nfsess_clientid.lval[1]; @@ -1023,7 +1071,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim, nd->nd_mrep = NULL; if (nd->nd_repstat == 0) { nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, nmp->nm_fh, - nmp->nm_fhsize, NULL, NULL); + nmp->nm_fhsize, NULL, NULL, 0, 0); NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_LEASETIME); (void) nfsrv_putattrbit(nd, &attrbits); @@ -1090,7 +1138,7 @@ nfsrpc_getattrnovp(struct nfsmount *nmp, u_int8_t *fhp, int fhlen, int syscred, int error, vers = NFS_VER2; nfsattrbit_t attrbits; - nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL, 0, 0); if (nd->nd_flag & ND_NFSV4) { vers = NFS_VER4; NFSGETATTR_ATTRBIT(&attrbits); @@ -4006,7 +4054,7 @@ nfsrpc_locku(struct nfsrv_descript *nd, struct nfsmount *nmp, int error; nfscl_reqstart(nd, NFSPROC_LOCKU, nmp, lp->nfsl_open->nfso_fh, - lp->nfsl_open->nfso_fhlen, NULL, NULL); + lp->nfsl_open->nfso_fhlen, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(type); *tl = txdr_unsigned(lp->nfsl_seqid); @@ -4058,7 +4106,7 @@ nfsrpc_lock(struct nfsrv_descript *nd, struct nfsmount *nmp, vnode_t vp, uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX]; struct nfsclsession *tsep; - nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); if (type == F_RDLCK) *tl++ = txdr_unsigned(NFSV4LOCKT_READ); @@ -4331,10 +4379,11 @@ nfsrpc_renew(struct nfsclclient *clp, struct nfsclds *dsp, struct ucred *cred, if (nmp == NULL) return (0); if (dsp == NULL) - nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, NULL, 0, + 0); else nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, - &dsp->nfsclds_sess); + &dsp->nfsclds_sess, 0, 0); if (!NFSHASNFSV4N(nmp)) { /* NFSv4.1 just uses a Sequence Op and not a Renew. */ NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); @@ -4378,11 +4427,11 @@ nfsrpc_rellockown(struct nfsmount *nmp, struct nfscllockowner *lp, if (NFSHASNFSV4N(nmp)) { /* For NFSv4.1, do a FreeStateID. */ nfscl_reqstart(nd, NFSPROC_FREESTATEID, nmp, NULL, 0, NULL, - NULL); + NULL, 0, 0); nfsm_stateidtom(nd, &lp->nfsl_stateid, NFSSTATEID_PUTSTATEID); } else { nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL, - NULL); + NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -4415,7 +4464,8 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred, int error, cnt, len, setnil; u_int32_t *opcntp; - nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL); + nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0, + 0); cp = dirpath; cnt = 0; do { @@ -4482,7 +4532,7 @@ nfsrpc_delegreturn(struct nfscldeleg *dp, struct ucred *cred, int error; nfscl_reqstart(nd, NFSPROC_DELEGRETURN, nmp, dp->nfsdl_fh, - dp->nfsdl_fhlen, NULL, NULL); + dp->nfsdl_fhlen, NULL, NULL, 0, 0); NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID); if (NFSHASNFSV4N(nmp)) *tl++ = 0; @@ -4592,7 +4642,7 @@ nfsrpc_exchangeid(struct nfsmount *nmp, struct nfsclclient *clp, int error, len; *dspp = NULL; - nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL, 0, 0); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsboottime.tv_sec); /* Client owner */ *tl = txdr_unsigned(clp->nfsc_rev); @@ -4679,7 +4729,8 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep, nmp->nm_rsize = NFS_MAXBSIZE; if (nmp->nm_wsize > NFS_MAXBSIZE || nmp->nm_wsize == 0) nmp->nm_wsize = NFS_MAXBSIZE; - nfscl_reqstart(nd, NFSPROC_CREATESESSION, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_CREATESESSION, nmp, NULL, 0, NULL, NULL, 0, + 0); NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); *tl++ = sep->nfsess_clientid.lval[0]; *tl++ = sep->nfsess_clientid.lval[1]; @@ -4793,7 +4844,8 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclclient *clp, int error; struct nfsclsession *tsep; - nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, + 0); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); tsep = nfsmnt_mdssession(nmp); bcopy(tsep->nfsess_sessionid, tl, NFSX_V4SESSIONID); @@ -4820,7 +4872,8 @@ nfsrpc_destroyclient(struct nfsmount *nmp, struct nfsclclient *clp, int error; struct nfsclsession *tsep; - nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL, 0, + 0); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -4838,18 +4891,20 @@ nfsrpc_destroyclient(struct nfsmount *nmp, struct nfsclclient *clp, /* * Do the NFSv4.1 LayoutGet. */ -int +static int nfsrpc_layoutget(struct nfsmount *nmp, uint8_t *fhp, int fhlen, int iomode, - uint64_t offset, uint64_t len, uint64_t minlen, int layoutlen, - nfsv4stateid_t *stateidp, int *retonclosep, struct nfsclflayouthead *flhp, - struct ucred *cred, NFSPROC_T *p, void *stuff) + uint64_t offset, uint64_t len, uint64_t minlen, int layouttype, + int layoutlen, nfsv4stateid_t *stateidp, int *retonclosep, + struct nfsclflayouthead *flhp, struct ucred *cred, NFSPROC_T *p, + void *stuff) { struct nfsrv_descript nfsd, *nd = &nfsd; int error; - nfscl_reqstart(nd, NFSPROC_LAYOUTGET, nmp, fhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_LAYOUTGET, nmp, fhp, fhlen, NULL, NULL, 0, + 0); nfsrv_setuplayoutget(nd, iomode, offset, len, minlen, stateidp, - layoutlen, 0); + layouttype, layoutlen, 0); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); @@ -4872,18 +4927,22 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype, uint32_t *notifybitsp, struct nfscldevinfo **ndip, struct ucred *cred, NFSPROC_T *p) { - uint32_t cnt, *tl; + uint32_t cnt, *tl, vers, minorvers; struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; - struct sockaddr_storage ss; - struct nfsclds *dsp = NULL, **dspp; + struct sockaddr_in sin, ssin; + struct sockaddr_in6 sin6, ssin6; + struct nfsclds *dsp = NULL, **dspp, **gotdspp; struct nfscldevinfo *ndi; - int addrcnt, bitcnt, error, i, isudp, j, pos, safilled, stripecnt; + int addrcnt = 0, bitcnt, error, gotvers, i, isudp, j, stripecnt; uint8_t stripeindex; + sa_family_t af, safilled; *ndip = NULL; ndi = NULL; - nfscl_reqstart(nd, NFSPROC_GETDEVICEINFO, nmp, NULL, 0, NULL, NULL); + gotdspp = NULL; + nfscl_reqstart(nd, NFSPROC_GETDEVICEINFO, nmp, NULL, 0, NULL, NULL, 0, + 0); NFSM_BUILD(tl, uint32_t *, NFSX_V4DEVICEID + 3 * NFSX_UNSIGNED); NFSBCOPY(deviceid, tl, NFSX_V4DEVICEID); tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); @@ -4901,55 +4960,72 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype, if (error != 0) return (error); if (nd->nd_repstat == 0) { - NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED); - if (layouttype != fxdr_unsigned(int, *tl++)) + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + if (layouttype != fxdr_unsigned(int, *tl)) printf("EEK! devinfo layout type not same!\n"); - stripecnt = fxdr_unsigned(int, *++tl); - NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt); - if (stripecnt < 1 || stripecnt > 4096) { - printf("NFS devinfo stripecnt %d: out of range\n", - stripecnt); - error = NFSERR_BADXDR; - goto nfsmout; - } - NFSM_DISSECT(tl, uint32_t *, (stripecnt + 1) * NFSX_UNSIGNED); - addrcnt = fxdr_unsigned(int, *(tl + stripecnt)); - NFSCL_DEBUG(4, "addrcnt=%d\n", addrcnt); - if (addrcnt < 1 || addrcnt > 128) { - printf("NFS devinfo addrcnt %d: out of range\n", - addrcnt); - error = NFSERR_BADXDR; - goto nfsmout; - } - - /* - * Now we know how many stripe indices and addresses, so - * we can allocate the structure the correct size. - */ - i = (stripecnt * sizeof(uint8_t)) / sizeof(struct nfsclds *) - + 1; - NFSCL_DEBUG(4, "stripeindices=%d\n", i); - ndi = malloc(sizeof(*ndi) + (addrcnt + i) * - sizeof(struct nfsclds *), M_NFSDEVINFO, M_WAITOK | M_ZERO); - NFSBCOPY(deviceid, ndi->nfsdi_deviceid, NFSX_V4DEVICEID); - ndi->nfsdi_refcnt = 0; - ndi->nfsdi_stripecnt = stripecnt; - ndi->nfsdi_addrcnt = addrcnt; - /* Fill in the stripe indices. */ - for (i = 0; i < stripecnt; i++) { - stripeindex = fxdr_unsigned(uint8_t, *tl++); - NFSCL_DEBUG(4, "stripeind=%d\n", stripeindex); - if (stripeindex >= addrcnt) { - printf("NFS devinfo stripeindex %d: too big\n", - (int)stripeindex); + if (layouttype == NFSLAYOUT_NFSV4_1_FILES) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + stripecnt = fxdr_unsigned(int, *tl); + NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt); + if (stripecnt < 1 || stripecnt > 4096) { + printf("pNFS File layout devinfo stripecnt %d:" + " out of range\n", stripecnt); error = NFSERR_BADXDR; goto nfsmout; } - nfsfldi_setstripeindex(ndi, i, stripeindex); + NFSM_DISSECT(tl, uint32_t *, (stripecnt + 1) * + NFSX_UNSIGNED); + addrcnt = fxdr_unsigned(int, *(tl + stripecnt)); + NFSCL_DEBUG(4, "addrcnt=%d\n", addrcnt); + if (addrcnt < 1 || addrcnt > 128) { + printf("NFS devinfo addrcnt %d: out of range\n", + addrcnt); + error = NFSERR_BADXDR; + goto nfsmout; + } + + /* + * Now we know how many stripe indices and addresses, so + * we can allocate the structure the correct size. + */ + i = (stripecnt * sizeof(uint8_t)) / + sizeof(struct nfsclds *) + 1; + NFSCL_DEBUG(4, "stripeindices=%d\n", i); + ndi = malloc(sizeof(*ndi) + (addrcnt + i) * + sizeof(struct nfsclds *), M_NFSDEVINFO, M_WAITOK | + M_ZERO); + NFSBCOPY(deviceid, ndi->nfsdi_deviceid, + NFSX_V4DEVICEID); + ndi->nfsdi_refcnt = 0; + ndi->nfsdi_flags = NFSDI_FILELAYOUT; + ndi->nfsdi_stripecnt = stripecnt; + ndi->nfsdi_addrcnt = addrcnt; + /* Fill in the stripe indices. */ + for (i = 0; i < stripecnt; i++) { + stripeindex = fxdr_unsigned(uint8_t, *tl++); + NFSCL_DEBUG(4, "stripeind=%d\n", stripeindex); + if (stripeindex >= addrcnt) { + printf("pNFS File Layout devinfo" + " stripeindex %d: too big\n", + (int)stripeindex); + error = NFSERR_BADXDR; + goto nfsmout; + } + nfsfldi_setstripeindex(ndi, i, stripeindex); + } + } else if (layouttype == NFSLAYOUT_FLEXFILE) { + /* For Flex File, we only get one address list. */ + ndi = malloc(sizeof(*ndi) + sizeof(struct nfsclds *), + M_NFSDEVINFO, M_WAITOK | M_ZERO); + NFSBCOPY(deviceid, ndi->nfsdi_deviceid, + NFSX_V4DEVICEID); + ndi->nfsdi_refcnt = 0; + ndi->nfsdi_flags = NFSDI_FLEXFILE; + addrcnt = ndi->nfsdi_addrcnt = 1; } /* Now, dissect the server address(es). */ - safilled = 0; + safilled = AF_UNSPEC; for (i = 0; i < addrcnt; i++) { NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); cnt = fxdr_unsigned(uint32_t, *tl); @@ -4959,63 +5035,107 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype, goto nfsmout; } dspp = nfsfldi_addr(ndi, i); - pos = arc4random() % cnt; /* Choose one. */ - safilled = 0; + safilled = AF_UNSPEC; for (j = 0; j < cnt; j++) { - error = nfsv4_getipaddr(nd, &ss, &isudp); + error = nfsv4_getipaddr(nd, &sin, &sin6, &af, + &isudp); if (error != 0 && error != EPERM) { error = NFSERR_BADXDR; goto nfsmout; } if (error == 0 && isudp == 0) { /* - * The algorithm is: - * - use "pos" entry if it is of the - * same af_family or none of them - * is of the same af_family - * else - * - use the first one of the same - * af_family. + * The priority is: + * - Same address family. + * Save the address and dspp, so that + * the connection can be done after + * parsing is complete. */ - if ((safilled == 0 && ss.ss_family == - nmp->nm_nam->sa_family) || - (j == pos && - (safilled == 0 || ss.ss_family == - nmp->nm_nam->sa_family)) || - (safilled == 1 && ss.ss_family == - nmp->nm_nam->sa_family)) { - error = nfsrpc_fillsa(nmp, &ss, - &dsp, p); - if (error == 0) { - *dspp = dsp; - if (ss.ss_family == - nmp->nm_nam->sa_family) - safilled = 2; - else - safilled = 1; - } + if (safilled == AF_UNSPEC || + (af == nmp->nm_nam->sa_family && + safilled != nmp->nm_nam->sa_family) + ) { + if (af == AF_INET) + ssin = sin; + else + ssin6 = sin6; + safilled = af; + gotdspp = dspp; } } } - if (safilled == 0) - break; + } + + gotvers = NFS_VER4; /* Always NFSv4 for File Layout. */ + /* For Flex File, we will take one of the versions to use. */ + if (layouttype == NFSLAYOUT_FLEXFILE) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + j = fxdr_unsigned(int, *tl); + if (j < 1 || j > NFSDEV_MAXVERS) { + printf("pNFS: too many versions\n"); + error = NFSERR_BADXDR; + goto nfsmout; + } + gotvers = 0; + for (i = 0; i < j; i++) { + NFSM_DISSECT(tl, uint32_t *, 5 * NFSX_UNSIGNED); + vers = fxdr_unsigned(uint32_t, *tl++); + minorvers = fxdr_unsigned(uint32_t, *tl++); + if ((vers == NFS_VER4 && minorvers == + NFSV41_MINORVERSION) || (vers == NFS_VER3 && + gotvers == 0)) { + gotvers = vers; + /* We'll take this one. */ + ndi->nfsdi_versindex = i; + ndi->nfsdi_vers = vers; + ndi->nfsdi_minorvers = minorvers; + ndi->nfsdi_rsize = fxdr_unsigned( + uint32_t, *tl++); + ndi->nfsdi_wsize = fxdr_unsigned( + uint32_t, *tl++); + if (*tl == newnfs_true) + ndi->nfsdi_flags |= + NFSDI_TIGHTCOUPLED; + else + ndi->nfsdi_flags &= + ~NFSDI_TIGHTCOUPLED; + } + } + if (gotvers == 0) { + printf("pNFS: no NFSv3 or NFSv4.1\n"); + error = NFSERR_BADXDR; + goto nfsmout; + } } /* And the notify bits. */ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); - if (safilled != 0) { - bitcnt = fxdr_unsigned(int, *tl); - if (bitcnt > 0) { - NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); - if (notifybitsp != NULL) - *notifybitsp = - fxdr_unsigned(uint32_t, *tl); - } + bitcnt = fxdr_unsigned(int, *tl); + if (bitcnt > 0) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (notifybitsp != NULL) + *notifybitsp = + fxdr_unsigned(uint32_t, *tl); + } + if (safilled != AF_UNSPEC) { + KASSERT(ndi != NULL, ("ndi is NULL")); *ndip = ndi; } else error = EPERM; + if (error == 0) { + /* + * Now we can do a TCP connection for the correct + * NFS version and IP address. + */ + error = nfsrpc_fillsa(nmp, &ssin, &ssin6, safilled, + gotvers, &dsp, p); + } + if (error == 0) { + KASSERT(gotdspp != NULL, ("gotdspp is NULL")); + *gotdspp = dsp; + } } - if (nd->nd_repstat != 0) + if (nd->nd_repstat != 0 && error == 0) error = nd->nd_repstat; nfsmout: if (error != 0 && ndi != NULL) @@ -5030,15 +5150,14 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype, int nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, uint64_t off, uint64_t len, uint64_t lastbyte, nfsv4stateid_t *stateidp, - int layouttype, int layoutupdatecnt, uint8_t *layp, struct ucred *cred, - NFSPROC_T *p, void *stuff) + int layouttype, struct ucred *cred, NFSPROC_T *p, void *stuff) { uint32_t *tl; struct nfsrv_descript nfsd, *nd = &nfsd; - int error, outcnt, i; - uint8_t *cp; + int error; - nfscl_reqstart(nd, NFSPROC_LAYOUTCOMMIT, nmp, fh, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_LAYOUTCOMMIT, nmp, fh, fhlen, NULL, NULL, + 0, 0); NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED + 3 * NFSX_HYPER + NFSX_STATEID); txdr_hyper(off, tl); @@ -5062,17 +5181,8 @@ nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, tl += 2; *tl++ = newnfs_false; *tl++ = txdr_unsigned(layouttype); - *tl = txdr_unsigned(layoutupdatecnt); - if (layoutupdatecnt > 0) { - KASSERT(layouttype != NFSLAYOUT_NFSV4_1_FILES, - ("Must be nil for Files Layout")); - outcnt = NFSM_RNDUP(layoutupdatecnt); - NFSM_BUILD(cp, uint8_t *, outcnt); - NFSBCOPY(layp, cp, layoutupdatecnt); - cp += layoutupdatecnt; - for (i = 0; i < (outcnt - layoutupdatecnt); i++) - *cp++ = 0x0; - } + /* All supported layouts are 0 length. */ + *tl = txdr_unsigned(0); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); @@ -5089,15 +5199,15 @@ nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, int nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, int layouttype, uint32_t iomode, int layoutreturn, uint64_t offset, - uint64_t len, nfsv4stateid_t *stateidp, int layoutcnt, uint32_t *layp, - struct ucred *cred, NFSPROC_T *p, void *stuff) + uint64_t len, nfsv4stateid_t *stateidp, struct ucred *cred, NFSPROC_T *p, + void *stuff) { uint32_t *tl; struct nfsrv_descript nfsd, *nd = &nfsd; - int error, outcnt, i; - uint8_t *cp; + int error; - nfscl_reqstart(nd, NFSPROC_LAYOUTRETURN, nmp, fh, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_LAYOUTRETURN, nmp, fh, fhlen, NULL, NULL, + 0, 0); NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); if (reclaim != 0) *tl++ = newnfs_true; @@ -5118,14 +5228,14 @@ nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, *tl++ = stateidp->other[0]; *tl++ = stateidp->other[1]; *tl++ = stateidp->other[2]; - *tl = txdr_unsigned(layoutcnt); - if (layoutcnt > 0) { - outcnt = NFSM_RNDUP(layoutcnt); - NFSM_BUILD(cp, uint8_t *, outcnt); - NFSBCOPY(layp, cp, layoutcnt); - cp += layoutcnt; - for (i = 0; i < (outcnt - layoutcnt); i++) - *cp++ = 0x0; + if (layouttype == NFSLAYOUT_NFSV4_1_FILES) + *tl = txdr_unsigned(0); + else if (layouttype == NFSLAYOUT_FLEXFILE) { + *tl = txdr_unsigned(2 * NFSX_UNSIGNED); + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); + /* No ioerrs or stats yet. */ + *tl++ = 0; + *tl = 0; } } nd->nd_flag |= ND_USEGSSNAME; @@ -5162,11 +5272,15 @@ nfsrpc_getlayout(struct nfsmount *nmp, vnode_t vp, struct nfsfh *nfhp, struct nfscllayout *lyp; struct nfsclflayout *flp; struct nfsclflayouthead flh; - int error = 0, islocked, layoutlen, recalled, retonclose; + int error = 0, islocked, layoutlen, layouttype, recalled, retonclose; nfsv4stateid_t stateid; struct nfsclsession *tsep; *lypp = NULL; + if (NFSHASFLEXFILE(nmp)) + layouttype = NFSLAYOUT_FLEXFILE; + else + layouttype = NFSLAYOUT_NFSV4_1_FILES; /* * If lyp is returned non-NULL, there will be a refcnt (shared lock) * on it, iff flp != NULL or a lock (exclusive lock) on it iff @@ -5189,8 +5303,8 @@ nfsrpc_getlayout(struct nfsmount *nmp, vnode_t vp, struct nfsfh *nfhp, stateid.other[2] = stateidp->other[2]; error = nfsrpc_layoutget(nmp, nfhp->nfh_fh, nfhp->nfh_len, iomode, (uint64_t)0, UINT64_MAX, - (uint64_t)0, layoutlen, &stateid, &retonclose, - &flh, cred, p, NULL); + (uint64_t)0, layouttype, layoutlen, &stateid, + &retonclose, &flh, cred, p, NULL); } else { islocked = 1; stateid.seqid = lyp->nfsly_stateid.seqid; @@ -5199,12 +5313,12 @@ nfsrpc_getlayout(struct nfsmount *nmp, vnode_t vp, struct nfsfh *nfhp, stateid.other[2] = lyp->nfsly_stateid.other[2]; error = nfsrpc_layoutget(nmp, nfhp->nfh_fh, nfhp->nfh_len, iomode, off, UINT64_MAX, - (uint64_t)0, layoutlen, &stateid, &retonclose, - &flh, cred, p, NULL); + (uint64_t)0, layouttype, layoutlen, &stateid, + &retonclose, &flh, cred, p, NULL); } error = nfsrpc_layoutgetres(nmp, vp, nfhp->nfh_fh, nfhp->nfh_len, &stateid, retonclose, notifybitsp, &lyp, - &flh, error, NULL, cred, p); + &flh, layouttype, error, NULL, cred, p); if (error == 0) *lypp = lyp; else if (islocked != 0) @@ -5220,11 +5334,12 @@ nfsrpc_getlayout(struct nfsmount *nmp, vnode_t vp, struct nfsfh *nfhp, * mount point and a pointer to it is returned. */ static int -nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, - struct nfsclds **dspp, NFSPROC_T *p) +nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_in *sin, + struct sockaddr_in6 *sin6, sa_family_t af, int vers, struct nfsclds **dspp, + NFSPROC_T *p) { - struct sockaddr_in *msad, *sad, *ssd; - struct sockaddr_in6 *msad6, *sad6, *ssd6; + struct sockaddr_in *msad, *sad; + struct sockaddr_in6 *msad6, *sad6; struct nfsclclient *clp; struct nfssockreq *nrp; struct nfsclds *dsp, *tdsp; @@ -5239,10 +5354,8 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, NFSUNLOCKCLSTATE(); if (clp == NULL) return (EPERM); - if (ssp->ss_family == AF_INET) { - ssd = (struct sockaddr_in *)ssp; + if (af == AF_INET) { NFSLOCKMNT(nmp); - /* * Check to see if we already have a session for this * address that is usable for a DS. @@ -5253,8 +5366,8 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, tdsp = TAILQ_FIRST(&nmp->nm_sess); while (tdsp != NULL) { if (msad != NULL && msad->sin_family == AF_INET && - ssd->sin_addr.s_addr == msad->sin_addr.s_addr && - ssd->sin_port == msad->sin_port && + sin->sin_addr.s_addr == msad->sin_addr.s_addr && + sin->sin_port == msad->sin_port && (tdsp->nfsclds_flags & NFSCLDS_DS) != 0 && tdsp->nfsclds_sess.nfsess_defunct == 0) { *dspp = tdsp; @@ -5275,14 +5388,12 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, sad = malloc(sizeof(*sad), M_SONAME, M_WAITOK | M_ZERO); sad->sin_len = sizeof(*sad); sad->sin_family = AF_INET; - sad->sin_port = ssd->sin_port; - sad->sin_addr.s_addr = ssd->sin_addr.s_addr; + sad->sin_port = sin->sin_port; + sad->sin_addr.s_addr = sin->sin_addr.s_addr; nrp = malloc(sizeof(*nrp), M_NFSSOCKREQ, M_WAITOK | M_ZERO); nrp->nr_nam = (struct sockaddr *)sad; - } else if (ssp->ss_family == AF_INET6) { - ssd6 = (struct sockaddr_in6 *)ssp; + } else if (af == AF_INET6) { NFSLOCKMNT(nmp); - /* * Check to see if we already have a session for this * address that is usable for a DS. @@ -5293,9 +5404,9 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, tdsp = TAILQ_FIRST(&nmp->nm_sess); while (tdsp != NULL) { if (msad6 != NULL && msad6->sin6_family == AF_INET6 && - IN6_ARE_ADDR_EQUAL(&ssd6->sin6_addr, + IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &msad6->sin6_addr) && - ssd6->sin6_port == msad6->sin6_port && + sin6->sin6_port == msad6->sin6_port && (tdsp->nfsclds_flags & NFSCLDS_DS) != 0 && tdsp->nfsclds_sess.nfsess_defunct == 0) { *dspp = tdsp; @@ -5315,8 +5426,8 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, sad6 = malloc(sizeof(*sad6), M_SONAME, M_WAITOK | M_ZERO); sad6->sin6_len = sizeof(*sad6); sad6->sin6_family = AF_INET6; - sad6->sin6_port = ssd6->sin6_port; - NFSBCOPY(&ssd6->sin6_addr, &sad6->sin6_addr, + sad6->sin6_port = sin6->sin6_port; + NFSBCOPY(&sin6->sin6_addr, &sad6->sin6_addr, sizeof(struct in6_addr)); nrp = malloc(sizeof(*nrp), M_NFSSOCKREQ, M_WAITOK | M_ZERO); nrp->nr_nam = (struct sockaddr *)sad6; @@ -5326,7 +5437,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, nrp->nr_sotype = SOCK_STREAM; mtx_init(&nrp->nr_mtx, "nfssock", NULL, MTX_DEF); nrp->nr_prog = NFS_PROG; - nrp->nr_vers = NFS_VER4; + nrp->nr_vers = vers; /* * Use the credentials that were used for the mount, which are @@ -5339,38 +5450,53 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, error = newnfs_connect(nmp, nrp, NULL, p, 0); NFSCL_DEBUG(3, "DS connect=%d\n", error); + dsp = NULL; /* Now, do the exchangeid and create session. */ if (error == 0) { - error = nfsrpc_exchangeid(nmp, clp, nrp, NFSV4EXCH_USEPNFSDS, - &dsp, nrp->nr_cred, p); - NFSCL_DEBUG(3, "DS exchangeid=%d\n", error); - if (error != 0) - newnfs_disconnect(nrp); + if (vers == NFS_VER4) { + error = nfsrpc_exchangeid(nmp, clp, nrp, + NFSV4EXCH_USEPNFSDS, &dsp, nrp->nr_cred, p); + NFSCL_DEBUG(3, "DS exchangeid=%d\n", error); + if (error != 0) + newnfs_disconnect(nrp); + } else { + dsp = malloc(sizeof(struct nfsclds), M_NFSCLDS, + M_WAITOK | M_ZERO); + dsp->nfsclds_flags |= NFSCLDS_DS; + dsp->nfsclds_expire = INT32_MAX; /* No renews needed. */ + mtx_init(&dsp->nfsclds_mtx, "nfsds", NULL, MTX_DEF); + mtx_init(&dsp->nfsclds_sess.nfsess_mtx, "nfssession", + NULL, MTX_DEF); + } } if (error == 0) { dsp->nfsclds_sockp = nrp; - NFSLOCKMNT(nmp); - retv = nfscl_getsameserver(nmp, dsp, &tdsp); - NFSCL_DEBUG(3, "getsame ret=%d\n", retv); - if (retv == NFSDSP_USETHISSESSION) { + if (vers == NFS_VER4) { + NFSLOCKMNT(nmp); + retv = nfscl_getsameserver(nmp, dsp, &tdsp); + NFSCL_DEBUG(3, "getsame ret=%d\n", retv); + if (retv == NFSDSP_USETHISSESSION) { + NFSUNLOCKMNT(nmp); + /* + * If there is already a session for this + * server, use it. + */ + (void)newnfs_disconnect(nrp); + nfscl_freenfsclds(dsp); + *dspp = tdsp; + return (0); + } + if (retv == NFSDSP_SEQTHISSESSION) + sequenceid = + tdsp->nfsclds_sess.nfsess_sequenceid; + else + sequenceid = + dsp->nfsclds_sess.nfsess_sequenceid; NFSUNLOCKMNT(nmp); - /* - * If there is already a session for this server, - * use it. - */ - (void)newnfs_disconnect(nrp); - nfscl_freenfsclds(dsp); - *dspp = tdsp; - return (0); + error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, + nrp, sequenceid, 0, nrp->nr_cred, p); + NFSCL_DEBUG(3, "DS createsess=%d\n", error); } - if (retv == NFSDSP_SEQTHISSESSION) - sequenceid = tdsp->nfsclds_sess.nfsess_sequenceid; - else - sequenceid = dsp->nfsclds_sess.nfsess_sequenceid; - NFSUNLOCKMNT(nmp); - error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, - nrp, sequenceid, 0, nrp->nr_cred, p); - NFSCL_DEBUG(3, "DS createsess=%d\n", error); } else { NFSFREECRED(nrp->nr_cred); NFSFREEMUTEX(&nrp->nr_mtx); @@ -5407,7 +5533,8 @@ nfsrpc_reclaimcomplete(struct nfsmount *nmp, struct ucred *cred, NFSPROC_T *p) struct nfsrv_descript *nd = &nfsd; int error; - nfscl_reqstart(nd, NFSPROC_RECLAIMCOMPL, nmp, NULL, 0, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_RECLAIMCOMPL, nmp, NULL, 0, NULL, NULL, 0, + 0); NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = newnfs_false; nd->nd_flag |= ND_USEGSSNAME; @@ -5450,11 +5577,18 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, struct nfscllayout *layp; struct nfscldevinfo *dip; struct nfsclflayout *rflp; + struct mbuf *m; + struct nfsclwritedsdorpc *drpc, *tdrpc; nfsv4stateid_t stateid; struct ucred *newcred; uint64_t lastbyte, len, off, oresid, xfer; - int eof, error, iolaymode, recalled; + int eof, error, firstmirror, i, iolaymode, mirrorcnt, recalled, timo; void *lckp; + uint8_t *dev; + void *iovbase; + size_t iovlen; + off_t offs; + ssize_t resid; if (!NFSHASPNFS(nmp) || nfscl_enablecallb == 0 || nfs_numnfscbd == 0 || (np->n_flag & NNOLAYOUT) != 0) @@ -5522,30 +5656,119 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, oresid = xfer = (uint64_t)uiop->uio_resid; if (xfer > (rflp->nfsfl_end - rflp->nfsfl_off)) xfer = rflp->nfsfl_end - rflp->nfsfl_off; - dip = nfscl_getdevinfo(nmp->nm_clp, rflp->nfsfl_dev, - rflp->nfsfl_devp); - if (dip != NULL) { - error = nfscl_doflayoutio(vp, uiop, iomode, - must_commit, &eof, &stateid, rwaccess, dip, - layp, rflp, off, xfer, docommit, newcred, - p); - nfscl_reldevinfo(dip); - lastbyte = off + xfer - 1; - if (error == 0) { - NFSLOCKCLSTATE(); - if (lastbyte > layp->nfsly_lastbyte) - layp->nfsly_lastbyte = lastbyte; - NFSUNLOCKCLSTATE(); - } else if (error == NFSERR_OPENMODE && - rwaccess == NFSV4OPEN_ACCESSREAD) { - NFSLOCKMNT(nmp); - nmp->nm_state |= NFSSTA_OPENMODE; - NFSUNLOCKMNT(nmp); + /* + * For Flex File layout with mirrored DSs, select one + * of them at random for reads. For writes and commits, + * do all mirrors. + */ + m = NULL; + drpc = NULL; + firstmirror = 0; + mirrorcnt = 1; + if ((layp->nfsly_flags & NFSLY_FLEXFILE) != 0 && + (mirrorcnt = rflp->nfsfl_mirrorcnt) > 1) { + if (rwaccess == NFSV4OPEN_ACCESSREAD) { + firstmirror = arc4random() % mirrorcnt; + mirrorcnt = firstmirror + 1; + } else { + if (docommit == 0) { + /* + * Save values, so uiop can be + * rolled back upon a write + * error. + */ + offs = uiop->uio_offset; + resid = uiop->uio_resid; + iovbase = + uiop->uio_iov->iov_base; + iovlen = uiop->uio_iov->iov_len; + m = nfsm_uiombuflist(uiop, len, + NULL, NULL); + } + tdrpc = drpc = malloc(sizeof(*drpc) * + (mirrorcnt - 1), M_TEMP, M_WAITOK | + M_ZERO); } + } + for (i = firstmirror; i < mirrorcnt && error == 0; i++){ + if ((layp->nfsly_flags & NFSLY_FLEXFILE) != 0) + dev = rflp->nfsfl_ffm[i].dev; + else + dev = rflp->nfsfl_dev; + dip = nfscl_getdevinfo(nmp->nm_clp, dev, + rflp->nfsfl_devp); + if (dip != NULL) { + if ((rflp->nfsfl_flags & NFSFL_FLEXFILE) + != 0) + error = nfscl_dofflayoutio(vp, + uiop, iomode, must_commit, + &eof, &stateid, rwaccess, + dip, layp, rflp, off, xfer, + i, docommit, m, tdrpc, + newcred, p); + else + error = nfscl_doflayoutio(vp, + uiop, iomode, must_commit, + &eof, &stateid, rwaccess, + dip, layp, rflp, off, xfer, + docommit, newcred, p); + nfscl_reldevinfo(dip); + } else + error = EIO; + tdrpc++; + } + if (m != NULL) + m_freem(m); + tdrpc = drpc; + timo = hz / 50; /* Wait for 20msec. */ + if (timo < 1) + timo = 1; + for (i = firstmirror; i < mirrorcnt - 1 && + tdrpc != NULL; i++, tdrpc++) { + /* + * For the unused drpc entries, both inprog and + * err == 0, so this loop won't break. + */ + while (tdrpc->inprog != 0 && tdrpc->done == 0) + tsleep(&tdrpc->tsk, PVFS, "clrpcio", + timo); + if (error == 0 && tdrpc->err != 0) + error = tdrpc->err; + } + free(drpc, M_TEMP); + if (error == 0) { + if (mirrorcnt > 1 && rwaccess == + NFSV4OPEN_ACCESSWRITE && docommit == 0) { + NFSLOCKCLSTATE(); + layp->nfsly_flags |= NFSLY_WRITTEN; + NFSUNLOCKCLSTATE(); + } + lastbyte = off + xfer - 1; + NFSLOCKCLSTATE(); + if (lastbyte > layp->nfsly_lastbyte) + layp->nfsly_lastbyte = lastbyte; + NFSUNLOCKCLSTATE(); + } else if (error == NFSERR_OPENMODE && + rwaccess == NFSV4OPEN_ACCESSREAD) { + NFSLOCKMNT(nmp); + nmp->nm_state |= NFSSTA_OPENMODE; + NFSUNLOCKMNT(nmp); } else error = EIO; if (error == 0) len -= (oresid - (uint64_t)uiop->uio_resid); + else if (mirrorcnt > 1 && rwaccess == + NFSV4OPEN_ACCESSWRITE && docommit == 0) { + /* + * In case the rpc gets retried, roll the + * uio fields changed by nfsm_uiombuflist() + * back. + */ + uiop->uio_offset = offs; + uiop->uio_resid = resid; + uiop->uio_iov->iov_base = iovbase; + uiop->uio_iov->iov_len = iovlen; + } } } if (lckp != NULL) @@ -5556,6 +5779,38 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, return (error); } +/* + * Make a copy of the mbuf chain and add an mbuf for null padding, as required. + */ +static struct mbuf * +nfsm_copym(struct mbuf *m, int off, int xfer) +{ + struct mbuf *m2, *m3, *m4; + uint32_t *tl; + int rem; + + m2 = m_copym(m, off, xfer, M_WAITOK); + rem = NFSM_RNDUP(xfer) - xfer; + if (rem > 0) { + /* + * The zero padding to a multiple of 4 bytes is required by + * the XDR. So that the mbufs copied by reference aren't + * modified, add an mbuf with the zero'd bytes to the list. + * rem will be a maximum of 3, so one zero'd uint32_t is + * sufficient. + */ + m3 = m2; + while (m3->m_next != NULL) + m3 = m3->m_next; + NFSMGET(m4); + tl = NFSMTOD(m4, uint32_t *); + *tl = 0; + mbuf_setlen(m4, rem); + mbuf_setnext(m3, m4); + } + return (m2); +} + /* * Find a file layout that will handle the first bytes of the requested * range and return the information from it needed to to the I/O operation. @@ -5661,7 +5916,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, if (docommit != 0) { if (error == 0) error = nfsrpc_commitds(vp, io_off, xfer, - *dspp, fhp, cred, p); + *dspp, fhp, 0, 0, cred, p); if (error == 0) { /* * Set both eof and uio_resid = 0 to end any @@ -5674,13 +5929,13 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, np->n_flag &= ~NDSCOMMIT; mtx_unlock(&np->n_mtx); } - } else if (rwflag == FREAD) + } else if (rwflag == NFSV4OPEN_ACCESSREAD) error = nfsrpc_readds(vp, uiop, stateidp, eofp, *dspp, - io_off, xfer, fhp, cred, p); + io_off, xfer, fhp, 0, 0, 0, cred, p); else { error = nfsrpc_writeds(vp, uiop, iomode, must_commit, stateidp, *dspp, io_off, xfer, fhp, commit_thru_mds, - cred, p); + 0, 0, 0, cred, p); if (error == 0) { NFSLOCKCLSTATE(); lyp->nfsly_flags |= NFSLY_WRITTEN; @@ -5697,43 +5952,196 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, return (error); } +/* + * Do I/O using an NFSv4.1 flex file layout. + */ +static int +nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, + int *eofp, nfsv4stateid_t *stateidp, int rwflag, struct nfscldevinfo *dp, + struct nfscllayout *lyp, struct nfsclflayout *flp, uint64_t off, + uint64_t len, int mirror, int docommit, struct mbuf *mp, + struct nfsclwritedsdorpc *drpc, struct ucred *cred, NFSPROC_T *p) +{ + uint64_t transfer, xfer; + int error, rel_off; + struct nfsnode *np; + struct nfsfh *fhp; + struct nfsclds **dspp; + struct ucred *tcred; + struct mbuf *m; + + np = VTONFS(vp); + error = 0; + rel_off = 0; + NFSCL_DEBUG(4, "nfscl_dofflayoutio: off=%ju len=%ju\n", (uintmax_t)off, + (uintmax_t)len); + /* Loop around, doing I/O for each stripe unit. */ + while (len > 0 && error == 0) { + dspp = nfsfldi_addr(dp, 0); + fhp = flp->nfsfl_ffm[mirror].fh[dp->nfsdi_versindex]; + stateidp = &flp->nfsfl_ffm[mirror].st; + NFSCL_DEBUG(4, "mirror=%d vind=%d fhlen=%d st.seqid=0x%x\n", + mirror, dp->nfsdi_versindex, fhp->nfh_len, stateidp->seqid); + if ((dp->nfsdi_flags & NFSDI_TIGHTCOUPLED) == 0) { + tcred = NFSNEWCRED(cred); + tcred->cr_uid = flp->nfsfl_ffm[mirror].user; + tcred->cr_groups[0] = flp->nfsfl_ffm[mirror].group; + tcred->cr_ngroups = 1; + } else + tcred = cred; + if (rwflag == NFSV4OPEN_ACCESSREAD) + transfer = dp->nfsdi_rsize; + else + transfer = dp->nfsdi_wsize; + mtx_lock(&np->n_mtx); + np->n_flag |= NDSCOMMIT; + mtx_unlock(&np->n_mtx); + if (len > transfer && docommit == 0) + xfer = transfer; + else + xfer = len; + if (docommit != 0) { + if (error == 0) { + /* + * Do last mirrored DS commit with this thread. + */ + if (mirror < flp->nfsfl_mirrorcnt - 1) + error = nfsio_commitds(vp, off, xfer, + *dspp, fhp, dp->nfsdi_vers, + dp->nfsdi_minorvers, drpc, tcred, + p); + else + error = nfsrpc_commitds(vp, off, xfer, + *dspp, fhp, dp->nfsdi_vers, + dp->nfsdi_minorvers, tcred, p); + } + NFSCL_DEBUG(4, "aft nfsio_commitds=%d\n", error); + if (error == 0) { + /* + * Set both eof and uio_resid = 0 to end any + * loops. + */ + *eofp = 1; + uiop->uio_resid = 0; + } else { + mtx_lock(&np->n_mtx); + np->n_flag &= ~NDSCOMMIT; + mtx_unlock(&np->n_mtx); + } + } else if (rwflag == NFSV4OPEN_ACCESSREAD) + error = nfsrpc_readds(vp, uiop, stateidp, eofp, *dspp, + off, xfer, fhp, 1, dp->nfsdi_vers, + dp->nfsdi_minorvers, tcred, p); + else { + if (flp->nfsfl_mirrorcnt == 1) { + error = nfsrpc_writeds(vp, uiop, iomode, + must_commit, stateidp, *dspp, off, xfer, + fhp, 0, 1, dp->nfsdi_vers, + dp->nfsdi_minorvers, tcred, p); + if (error == 0) { + NFSLOCKCLSTATE(); + lyp->nfsly_flags |= NFSLY_WRITTEN; + NFSUNLOCKCLSTATE(); + } + } else { + m = nfsm_copym(mp, rel_off, xfer); + NFSCL_DEBUG(4, "mcopy reloff=%d xfer=%jd\n", + rel_off, (uintmax_t)xfer); + /* + * Do last write to a mirrored DS with this + * thread. + */ + if (mirror < flp->nfsfl_mirrorcnt - 1) + error = nfsio_writedsmir(vp, iomode, + must_commit, stateidp, *dspp, off, + xfer, fhp, m, dp->nfsdi_vers, + dp->nfsdi_minorvers, drpc, tcred, + p); + else + error = nfsrpc_writedsmir(vp, iomode, + must_commit, stateidp, *dspp, off, + xfer, fhp, m, dp->nfsdi_vers, + dp->nfsdi_minorvers, tcred, p); + NFSCL_DEBUG(4, "nfsio_writedsmir=%d\n", error); + } + } + NFSCL_DEBUG(4, "aft read/writeds=%d\n", error); + if (error == 0) { + len -= xfer; + off += xfer; + rel_off += xfer; + } + if ((dp->nfsdi_flags & NFSDI_TIGHTCOUPLED) == 0) + NFSFREECRED(tcred); + } + NFSCL_DEBUG(4, "eo nfscl_dofflayoutio=%d\n", error); + return (error); +} + /* * The actual read RPC done to a DS. */ static int nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4stateid_t *stateidp, int *eofp, - struct nfsclds *dsp, uint64_t io_off, int len, struct nfsfh *fhp, - struct ucred *cred, NFSPROC_T *p) + struct nfsclds *dsp, uint64_t io_off, int len, struct nfsfh *fhp, int flex, + int vers, int minorvers, struct ucred *cred, NFSPROC_T *p) { uint32_t *tl; - int error, retlen; + int attrflag, error, retlen; struct nfsrv_descript nfsd; struct nfsmount *nmp = VFSTONFS(vnode_mount(vp)); struct nfsrv_descript *nd = &nfsd; struct nfssockreq *nrp; + struct nfsvattr na; nd->nd_mrep = NULL; - nfscl_reqstart(nd, NFSPROC_READDS, nmp, fhp->nfh_fh, fhp->nfh_len, - NULL, &dsp->nfsclds_sess); - nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSEQIDZERO); + if (vers == 0 || vers == NFS_VER4) { + nfscl_reqstart(nd, NFSPROC_READDS, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + vers = NFS_VER4; + NFSCL_DEBUG(4, "nfsrpc_readds: vers4 minvers=%d\n", minorvers); + if (flex != 0) + nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); + else + nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSEQIDZERO); + } else { + nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSCL_DEBUG(4, "nfsrpc_readds: vers3\n"); + } NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); txdr_hyper(io_off, tl); *(tl + 2) = txdr_unsigned(len); nrp = dsp->nfsclds_sockp; + NFSCL_DEBUG(4, "nfsrpc_readds: nrp=%p\n", nrp); if (nrp == NULL) /* If NULL, use the MDS socket. */ nrp = &nmp->nm_sockreq; error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, - NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess); + NFS_PROG, vers, NULL, 1, NULL, &dsp->nfsclds_sess); + NFSCL_DEBUG(4, "nfsrpc_readds: stat=%d err=%d\n", nd->nd_repstat, + error); if (error != 0) return (error); + if (vers == NFS_VER3) { + error = nfscl_postop_attr(nd, &na, &attrflag, NULL); + NFSCL_DEBUG(4, "nfsrpc_readds: postop=%d\n", error); + if (error != 0) + goto nfsmout; + } if (nd->nd_repstat != 0) { error = nd->nd_repstat; goto nfsmout; } - NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); - *eofp = fxdr_unsigned(int, *tl); + if (vers == NFS_VER3) { + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + *eofp = fxdr_unsigned(int, *(tl + 1)); + } else { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + *eofp = fxdr_unsigned(int, *tl); + } NFSM_STRSIZ(retlen, len); + NFSCL_DEBUG(4, "nfsrpc_readds: retlen=%d eof=%d\n", retlen, *eofp); error = nfsm_mbufuio(nd, uiop, retlen); nfsmout: if (nd->nd_mrep != NULL) @@ -5747,24 +6155,40 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4stateid_t *stateidp, int *eofp, static int nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, nfsv4stateid_t *stateidp, struct nfsclds *dsp, uint64_t io_off, int len, - struct nfsfh *fhp, int commit_thru_mds, struct ucred *cred, NFSPROC_T *p) + struct nfsfh *fhp, int commit_thru_mds, int flex, int vers, int minorvers, + struct ucred *cred, NFSPROC_T *p) { uint32_t *tl; struct nfsmount *nmp = VFSTONFS(vnode_mount(vp)); - int error, rlen, commit, committed = NFSWRITE_FILESYNC; + int attrflag, error, rlen, commit, committed = NFSWRITE_FILESYNC; int32_t backup; struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; struct nfssockreq *nrp; + struct nfsvattr na; KASSERT(uiop->uio_iovcnt == 1, ("nfs: writerpc iovcnt > 1")); nd->nd_mrep = NULL; - nfscl_reqstart(nd, NFSPROC_WRITEDS, nmp, fhp->nfh_fh, fhp->nfh_len, - NULL, &dsp->nfsclds_sess); - nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSEQIDZERO); - NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); + if (vers == 0 || vers == NFS_VER4) { + nfscl_reqstart(nd, NFSPROC_WRITEDS, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSCL_DEBUG(4, "nfsrpc_writeds: vers4 minvers=%d\n", minorvers); + vers = NFS_VER4; + if (flex != 0) + nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); + else + nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSEQIDZERO); + NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); + } else { + nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSCL_DEBUG(4, "nfsrpc_writeds: vers3\n"); + NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); + } txdr_hyper(io_off, tl); tl += 2; + if (vers == NFS_VER3) + *tl++ = txdr_unsigned(len); *tl++ = txdr_unsigned(*iomode); *tl = txdr_unsigned(len); nfsm_uiombuf(nd, uiop, len); @@ -5773,7 +6197,9 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, /* If NULL, use the MDS socket. */ nrp = &nmp->nm_sockreq; error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, - NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess); + NFS_PROG, vers, NULL, 1, NULL, &dsp->nfsclds_sess); + NFSCL_DEBUG(4, "nfsrpc_writeds: err=%d stat=%d\n", error, + nd->nd_repstat); if (error != 0) return (error); if (nd->nd_repstat != 0) { @@ -5788,8 +6214,16 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, uio_iov_len_add(uiop, len); error = nd->nd_repstat; } else { + if (vers == NFS_VER3) { + error = nfscl_wcc_data(nd, vp, &na, &attrflag, NULL, + NULL); + NFSCL_DEBUG(4, "nfsrpc_writeds: wcc_data=%d\n", error); + if (error != 0) + goto nfsmout; + } NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_VERF); rlen = fxdr_unsigned(int, *tl++); + NFSCL_DEBUG(4, "nfsrpc_writeds: len=%d rlen=%d\n", len, rlen); if (rlen == 0) { error = NFSERR_IO; goto nfsmout; @@ -5843,6 +6277,173 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, return (error); } +/* + * The actual write RPC done to a DS. + * This variant is called from a separate kernel process for mirrors. + * Any short write is considered an IO error. + */ +static int +nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_commit, + nfsv4stateid_t *stateidp, struct nfsclds *dsp, uint64_t io_off, int len, + struct nfsfh *fhp, struct mbuf *m, int vers, int minorvers, + struct ucred *cred, NFSPROC_T *p) +{ + uint32_t *tl; + struct nfsmount *nmp = VFSTONFS(vnode_mount(vp)); + int attrflag, error, commit, committed = NFSWRITE_FILESYNC, rlen; + struct nfsrv_descript nfsd; + struct nfsrv_descript *nd = &nfsd; + struct nfssockreq *nrp; + struct nfsvattr na; + + nd->nd_mrep = NULL; + if (vers == 0 || vers == NFS_VER4) { + nfscl_reqstart(nd, NFSPROC_WRITEDS, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + vers = NFS_VER4; + NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers4 minvers=%d\n", + minorvers); + nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID); + NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 2 * NFSX_UNSIGNED); + } else { + nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers3\n"); + NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); + } + txdr_hyper(io_off, tl); + tl += 2; + if (vers == NFS_VER3) + *tl++ = txdr_unsigned(len); + *tl++ = txdr_unsigned(*iomode); + *tl = txdr_unsigned(len); + if (len > 0) { + /* Put data in mbuf chain. */ + nd->nd_mb->m_next = m; + /* Set nd_mb and nd_bpos to end of data. */ + while (m->m_next != NULL) + m = m->m_next; + nd->nd_mb = m; + nd->nd_bpos = mtod(m, char *) + m->m_len; + NFSCL_DEBUG(4, "nfsrpc_writedsmir: lastmb len=%d\n", m->m_len); + } + nrp = dsp->nfsclds_sockp; + if (nrp == NULL) + /* If NULL, use the MDS socket. */ + nrp = &nmp->nm_sockreq; + error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, + NFS_PROG, vers, NULL, 1, NULL, &dsp->nfsclds_sess); + NFSCL_DEBUG(4, "nfsrpc_writedsmir: err=%d stat=%d\n", error, + nd->nd_repstat); + if (error != 0) + return (error); + if (nd->nd_repstat != 0) + error = nd->nd_repstat; + else { + if (vers == NFS_VER3) { + error = nfscl_wcc_data(nd, vp, &na, &attrflag, NULL, + NULL); + NFSCL_DEBUG(4, "nfsrpc_writedsmir: wcc_data=%d\n", + error); + if (error != 0) + goto nfsmout; + } + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_VERF); + rlen = fxdr_unsigned(int, *tl++); + NFSCL_DEBUG(4, "nfsrpc_writedsmir: len=%d rlen=%d\n", len, + rlen); + if (rlen != len) { + error = NFSERR_IO; + NFSCL_DEBUG(4, "nfsrpc_writedsmir: len=%d rlen=%d\n", + len, rlen); + goto nfsmout; + } + commit = fxdr_unsigned(int, *tl++); + + /* + * Return the lowest commitment level + * obtained by any of the RPCs. + */ + if (committed == NFSWRITE_FILESYNC) + committed = commit; + else if (committed == NFSWRITE_DATASYNC && + commit == NFSWRITE_UNSTABLE) + committed = commit; + NFSLOCKDS(dsp); + if ((dsp->nfsclds_flags & NFSCLDS_HASWRITEVERF) == 0) { + NFSBCOPY(tl, dsp->nfsclds_verf, NFSX_VERF); + dsp->nfsclds_flags |= NFSCLDS_HASWRITEVERF; + } else if (NFSBCMP(tl, dsp->nfsclds_verf, NFSX_VERF)) { + *must_commit = 1; + NFSBCOPY(tl, dsp->nfsclds_verf, NFSX_VERF); + } + NFSUNLOCKDS(dsp); + } +nfsmout: + if (nd->nd_mrep != NULL) + mbuf_freem(nd->nd_mrep); + *iomode = committed; + if (nd->nd_repstat != 0 && error == 0) + error = nd->nd_repstat; + return (error); +} + +/* + * Start up the thread that will execute nfsrpc_writedsmir(). + */ +static void +start_writedsmir(void *arg, int pending) +{ + struct nfsclwritedsdorpc *drpc; + + drpc = (struct nfsclwritedsdorpc *)arg; + drpc->err = nfsrpc_writedsmir(drpc->vp, &drpc->iomode, + &drpc->must_commit, drpc->stateidp, drpc->dsp, drpc->off, drpc->len, + drpc->fhp, drpc->m, drpc->vers, drpc->minorvers, drpc->cred, + drpc->p); + drpc->done = 1; + NFSCL_DEBUG(4, "start_writedsmir: err=%d\n", drpc->err); +} + +/* + * Set up the write DS mirror call for the pNFS I/O thread. + */ +static int +nfsio_writedsmir(vnode_t vp, int *iomode, int *must_commit, + nfsv4stateid_t *stateidp, struct nfsclds *dsp, uint64_t off, int len, + struct nfsfh *fhp, struct mbuf *m, int vers, int minorvers, + struct nfsclwritedsdorpc *drpc, struct ucred *cred, NFSPROC_T *p) +{ + int error, ret; + + error = 0; + drpc->done = 0; + drpc->vp = vp; + drpc->iomode = *iomode; + drpc->must_commit = *must_commit; + drpc->stateidp = stateidp; + drpc->dsp = dsp; + drpc->off = off; + drpc->len = len; + drpc->fhp = fhp; + drpc->m = m; + drpc->vers = vers; + drpc->minorvers = minorvers; + drpc->cred = cred; + drpc->p = p; + drpc->inprog = 0; + ret = EIO; + if (nfs_pnfsiothreads > 0) { + ret = nfs_pnfsio(start_writedsmir, drpc); + NFSCL_DEBUG(4, "nfsio_writedsmir: nfs_pnfsio=%d\n", ret); + } + if (ret != 0) + error = nfsrpc_writedsmir(vp, iomode, must_commit, stateidp, + dsp, off, len, fhp, m, vers, minorvers, cred, p); + NFSCL_DEBUG(4, "nfsio_writedsmir: error=%d\n", error); + return (error); +} + /* * Free up the nfsclds structure. */ @@ -5915,17 +6516,26 @@ nfscl_getsameserver(struct nfsmount *nmp, struct nfsclds *newdsp, */ static int nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, - struct nfsfh *fhp, struct ucred *cred, NFSPROC_T *p) + struct nfsfh *fhp, int vers, int minorvers, struct ucred *cred, + NFSPROC_T *p) { uint32_t *tl; struct nfsrv_descript nfsd, *nd = &nfsd; struct nfsmount *nmp = VFSTONFS(vnode_mount(vp)); struct nfssockreq *nrp; - int error; + struct nfsvattr na; + int attrflag, error; nd->nd_mrep = NULL; - nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, fhp->nfh_len, - NULL, &dsp->nfsclds_sess); + if (vers == 0 || vers == NFS_VER4) { + nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + vers = NFS_VER4; + } else + nfscl_reqstart(nd, NFSPROC_COMMIT, nmp, fhp->nfh_fh, + fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSCL_DEBUG(4, "nfsrpc_commitds: vers=%d minvers=%d\n", vers, + minorvers); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED); txdr_hyper(offset, tl); tl += 2; @@ -5935,10 +6545,19 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, /* If NULL, use the MDS socket. */ nrp = &nmp->nm_sockreq; error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, - NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess); + NFS_PROG, vers, NULL, 1, NULL, &dsp->nfsclds_sess); + NFSCL_DEBUG(4, "nfsrpc_commitds: err=%d stat=%d\n", error, + nd->nd_repstat); if (error != 0) return (error); if (nd->nd_repstat == 0) { + if (vers == NFS_VER3) { + error = nfscl_wcc_data(nd, vp, &na, &attrflag, NULL, + NULL); + NFSCL_DEBUG(4, "nfsrpc_commitds: wccdata=%d\n", error); + if (error != 0) + goto nfsmout; + } NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF); NFSLOCKDS(dsp); if (NFSBCMP(tl, dsp->nfsclds_verf, NFSX_VERF)) { @@ -5954,20 +6573,70 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, return (error); } +/* + * Start up the thread that will execute nfsrpc_commitds(). + */ +static void +start_commitds(void *arg, int pending) +{ + struct nfsclwritedsdorpc *drpc; + + drpc = (struct nfsclwritedsdorpc *)arg; + drpc->err = nfsrpc_commitds(drpc->vp, drpc->off, drpc->len, + drpc->dsp, drpc->fhp, drpc->vers, drpc->minorvers, drpc->cred, + drpc->p); + drpc->done = 1; + NFSCL_DEBUG(4, "start_commitds: err=%d\n", drpc->err); +} + +/* + * Set up the commit DS mirror call for the pNFS I/O thread. + */ +static int +nfsio_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, + struct nfsfh *fhp, int vers, int minorvers, + struct nfsclwritedsdorpc *drpc, struct ucred *cred, NFSPROC_T *p) +{ + int error, ret; + + error = 0; + drpc->done = 0; + drpc->vp = vp; + drpc->off = offset; + drpc->len = cnt; + drpc->dsp = dsp; + drpc->fhp = fhp; + drpc->vers = vers; + drpc->minorvers = minorvers; + drpc->cred = cred; + drpc->p = p; + drpc->inprog = 0; + ret = EIO; + if (nfs_pnfsiothreads > 0) { + ret = nfs_pnfsio(start_commitds, drpc); + NFSCL_DEBUG(4, "nfsio_commitds: nfs_pnfsio=%d\n", ret); + } + if (ret != 0) + error = nfsrpc_commitds(vp, offset, cnt, dsp, fhp, vers, + minorvers, cred, p); + NFSCL_DEBUG(4, "nfsio_commitds: error=%d\n", error); + return (error); +} + /* * Set up the XDR arguments for the LayoutGet operation. */ static void nfsrv_setuplayoutget(struct nfsrv_descript *nd, int iomode, uint64_t offset, - uint64_t len, uint64_t minlen, nfsv4stateid_t *stateidp, int layoutlen, - int usecurstateid) + uint64_t len, uint64_t minlen, nfsv4stateid_t *stateidp, int layouttype, + int layoutlen, int usecurstateid) { uint32_t *tl; NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED + 3 * NFSX_HYPER + NFSX_STATEID); *tl++ = newnfs_false; /* Don't signal availability. */ - *tl++ = txdr_unsigned(NFSLAYOUT_NFSV4_1_FILES); + *tl++ = txdr_unsigned(layouttype); *tl++ = txdr_unsigned(iomode); txdr_hyper(offset, tl); tl += 2; @@ -6000,11 +6669,15 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, { uint32_t *tl; struct nfsclflayout *flp, *prevflp, *tflp; - int cnt, error, gotiomode, fhcnt, nfhlen, i, j; - uint64_t retlen; + int cnt, error, fhcnt, gotiomode, i, iomode, j, k, l, laytype, nfhlen; + int m, mirrorcnt; + uint64_t retlen, off; struct nfsfh *nfhp; uint8_t *cp; + uid_t user; + gid_t grp; + NFSCL_DEBUG(4, "in nfsrv_parselayoutget\n"); error = 0; flp = NULL; gotiomode = -1; @@ -6027,64 +6700,204 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, goto nfsmout; } for (i = 0; i < cnt; i++) { - /* Dissect all the way to the file handle cnt. */ - NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_HYPER + - 6 * NFSX_UNSIGNED + NFSX_V4DEVICEID); - fhcnt = fxdr_unsigned(int, *(tl + 11 + - NFSX_V4DEVICEID / NFSX_UNSIGNED)); - NFSCL_DEBUG(4, "fhcnt=%d\n", fhcnt); - if (fhcnt < 0 || fhcnt > 100) { - /* Don't accept more than 100 file handles. */ - error = NFSERR_BADXDR; - goto nfsmout; - } - if (fhcnt > 1) - flp = malloc(sizeof(*flp) + (fhcnt - 1) * - sizeof(struct nfsfh *), M_NFSFLAYOUT, M_WAITOK); - else - flp = malloc(sizeof(*flp), M_NFSFLAYOUT, M_WAITOK); - flp->nfsfl_flags = 0; - flp->nfsfl_fhcnt = 0; - flp->nfsfl_devp = NULL; - flp->nfsfl_off = fxdr_hyper(tl); tl += 2; + /* Dissect to the layout type. */ + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_HYPER + + 3 * NFSX_UNSIGNED); + off = fxdr_hyper(tl); tl += 2; retlen = fxdr_hyper(tl); tl += 2; - if (flp->nfsfl_off + retlen < flp->nfsfl_off) - flp->nfsfl_end = UINT64_MAX - flp->nfsfl_off; - else - flp->nfsfl_end = flp->nfsfl_off + retlen; - flp->nfsfl_iomode = fxdr_unsigned(int, *tl++); - if (gotiomode == -1) - gotiomode = flp->nfsfl_iomode; - if (fxdr_unsigned(int, *tl++) != NFSLAYOUT_NFSV4_1_FILES) { - printf("NFSv4.1: got non-files layout\n"); - error = NFSERR_BADXDR; - goto nfsmout; - } - NFSBCOPY(++tl, flp->nfsfl_dev, NFSX_V4DEVICEID); - tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); - flp->nfsfl_util = fxdr_unsigned(uint32_t, *tl++); - NFSCL_DEBUG(4, "flutil=0x%x\n", flp->nfsfl_util); - flp->nfsfl_stripe1 = fxdr_unsigned(uint32_t, *tl++); - flp->nfsfl_patoff = fxdr_hyper(tl); tl += 2; - if (fxdr_unsigned(int, *tl) != fhcnt) { - printf("EEK! bad fhcnt\n"); - error = NFSERR_BADXDR; - goto nfsmout; - } - for (j = 0; j < fhcnt; j++) { - NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); - nfhlen = fxdr_unsigned(int, *tl); - if (nfhlen <= 0 || nfhlen > NFSX_V4FHMAX) { + iomode = fxdr_unsigned(int, *tl++); + laytype = fxdr_unsigned(int, *tl); + NFSCL_DEBUG(4, "layt=%d off=%ju len=%ju iom=%d\n", laytype, + (uintmax_t)off, (uintmax_t)retlen, iomode); + /* Ignore length of layout body for now. */ + if (laytype == NFSLAYOUT_NFSV4_1_FILES) { + /* Parse the File layout up to fhcnt. */ + NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED + + NFSX_HYPER + NFSX_V4DEVICEID); + fhcnt = fxdr_unsigned(int, *(tl + 4 + + NFSX_V4DEVICEID / NFSX_UNSIGNED)); + NFSCL_DEBUG(4, "fhcnt=%d\n", fhcnt); + if (fhcnt < 0 || fhcnt > 100) { + /* Don't accept more than 100 file handles. */ error = NFSERR_BADXDR; goto nfsmout; } - nfhp = malloc(sizeof(*nfhp) + nfhlen - 1, M_NFSFH, - M_WAITOK); - flp->nfsfl_fh[j] = nfhp; - flp->nfsfl_fhcnt++; - nfhp->nfh_len = nfhlen; - NFSM_DISSECT(cp, uint8_t *, NFSM_RNDUP(nfhlen)); - NFSBCOPY(cp, nfhp->nfh_fh, nfhlen); + if (fhcnt > 0) + flp = malloc(sizeof(*flp) + fhcnt * + sizeof(struct nfsfh *), M_NFSFLAYOUT, + M_WAITOK); + else + flp = malloc(sizeof(*flp), M_NFSFLAYOUT, + M_WAITOK); + flp->nfsfl_flags = NFSFL_FILE; + flp->nfsfl_fhcnt = 0; + flp->nfsfl_devp = NULL; + flp->nfsfl_off = off; + if (flp->nfsfl_off + retlen < flp->nfsfl_off) + flp->nfsfl_end = UINT64_MAX - flp->nfsfl_off; + else + flp->nfsfl_end = flp->nfsfl_off + retlen; + flp->nfsfl_iomode = iomode; + if (gotiomode == -1) + gotiomode = flp->nfsfl_iomode; + /* Ignore layout body length for now. */ + NFSBCOPY(tl, flp->nfsfl_dev, NFSX_V4DEVICEID); + tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); + flp->nfsfl_util = fxdr_unsigned(uint32_t, *tl++); + NFSCL_DEBUG(4, "flutil=0x%x\n", flp->nfsfl_util); + flp->nfsfl_stripe1 = fxdr_unsigned(uint32_t, *tl++); + flp->nfsfl_patoff = fxdr_hyper(tl); tl += 2; + NFSCL_DEBUG(4, "stripe1=%u poff=%ju\n", + flp->nfsfl_stripe1, (uintmax_t)flp->nfsfl_patoff); + for (j = 0; j < fhcnt; j++) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + nfhlen = fxdr_unsigned(int, *tl); + if (nfhlen <= 0 || nfhlen > NFSX_V4FHMAX) { + error = NFSERR_BADXDR; + goto nfsmout; + } + nfhp = malloc(sizeof(*nfhp) + nfhlen - 1, + M_NFSFH, M_WAITOK); + flp->nfsfl_fh[j] = nfhp; + flp->nfsfl_fhcnt++; + nfhp->nfh_len = nfhlen; + NFSM_DISSECT(cp, uint8_t *, NFSM_RNDUP(nfhlen)); + NFSBCOPY(cp, nfhp->nfh_fh, nfhlen); + } + } else if (laytype == NFSLAYOUT_FLEXFILE) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED + + NFSX_HYPER); + mirrorcnt = fxdr_unsigned(int, *(tl + 2)); + NFSCL_DEBUG(4, "mirrorcnt=%d\n", mirrorcnt); + if (mirrorcnt < 1 || mirrorcnt > NFSDEV_MAXMIRRORS) { + error = NFSERR_BADXDR; + goto nfsmout; + } + flp = malloc(sizeof(*flp) + mirrorcnt * + sizeof(struct nfsffm), M_NFSFLAYOUT, M_WAITOK); + flp->nfsfl_flags = NFSFL_FLEXFILE; + flp->nfsfl_mirrorcnt = mirrorcnt; + flp->nfsfl_devp = NULL; + flp->nfsfl_off = off; + if (flp->nfsfl_off + retlen < flp->nfsfl_off) + flp->nfsfl_end = UINT64_MAX - flp->nfsfl_off; + else + flp->nfsfl_end = flp->nfsfl_off + retlen; + flp->nfsfl_iomode = iomode; + if (gotiomode == -1) + gotiomode = flp->nfsfl_iomode; + flp->nfsfl_stripeunit = fxdr_hyper(tl); + NFSCL_DEBUG(4, "stripeunit=%ju\n", + (uintmax_t)flp->nfsfl_stripeunit); + for (j = 0; j < mirrorcnt; j++) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + k = fxdr_unsigned(int, *tl); + if (k < 1 || k > 128) { + error = NFSERR_BADXDR; + goto nfsmout; + } + NFSCL_DEBUG(4, "servercnt=%d\n", k); + for (l = 0; l < k; l++) { + NFSM_DISSECT(tl, uint32_t *, + NFSX_V4DEVICEID + NFSX_STATEID + + 2 * NFSX_UNSIGNED); + if (l == 0) { + /* Just use the first server. */ + NFSBCOPY(tl, + flp->nfsfl_ffm[j].dev, + NFSX_V4DEVICEID); + tl += (NFSX_V4DEVICEID / + NFSX_UNSIGNED); + tl++; + flp->nfsfl_ffm[j].st.seqid = + *tl++; + flp->nfsfl_ffm[j].st.other[0] = + *tl++; + flp->nfsfl_ffm[j].st.other[1] = + *tl++; + flp->nfsfl_ffm[j].st.other[2] = + *tl++; + NFSCL_DEBUG(4, "st.seqid=%u " + "st.o0=0x%x st.o1=0x%x " + "st.o2=0x%x\n", + flp->nfsfl_ffm[j].st.seqid, + flp->nfsfl_ffm[j].st.other[0], + flp->nfsfl_ffm[j].st.other[1], + flp->nfsfl_ffm[j].st.other[2]); + } else + tl += ((NFSX_V4DEVICEID + + NFSX_STATEID + + NFSX_UNSIGNED) / + NFSX_UNSIGNED); + fhcnt = fxdr_unsigned(int, *tl); + NFSCL_DEBUG(4, "fhcnt=%d\n", fhcnt); + if (fhcnt < 1 || + fhcnt > NFSDEV_MAXVERS) { + error = NFSERR_BADXDR; + goto nfsmout; + } + for (m = 0; m < fhcnt; m++) { + NFSM_DISSECT(tl, uint32_t *, + NFSX_UNSIGNED); + nfhlen = fxdr_unsigned(int, + *tl); + NFSCL_DEBUG(4, "nfhlen=%d\n", + nfhlen); + if (nfhlen <= 0 || nfhlen > + NFSX_V4FHMAX) { + error = NFSERR_BADXDR; + goto nfsmout; + } + NFSM_DISSECT(cp, uint8_t *, + NFSM_RNDUP(nfhlen)); + if (l == 0) { + flp->nfsfl_ffm[j].fhcnt + = fhcnt; + nfhp = malloc( + sizeof(*nfhp) + + nfhlen - 1, M_NFSFH, + M_WAITOK); + flp->nfsfl_ffm[j].fh[m] + = nfhp; + nfhp->nfh_len = nfhlen; + NFSBCOPY(cp, + nfhp->nfh_fh, + nfhlen); + NFSCL_DEBUG(4, + "got fh\n"); + } + } + /* Now, get the ffsd_user/ffds_group. */ + error = nfsrv_parseug(nd, 0, &user, + &grp, curthread); + NFSCL_DEBUG(4, "after parseu=%d\n", + error); + if (error == 0) + error = nfsrv_parseug(nd, 1, + &user, &grp, curthread); + NFSCL_DEBUG(4, "aft parseg=%d\n", + grp); + if (error != 0) + goto nfsmout; + NFSCL_DEBUG(4, "user=%d group=%d\n", + user, grp); + if (l == 0) { + flp->nfsfl_ffm[j].user = user; + flp->nfsfl_ffm[j].group = grp; + NFSCL_DEBUG(4, + "usr=%d grp=%d\n", user, + grp); + } + } + } + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + flp->nfsfl_fflags = fxdr_unsigned(uint32_t, *tl++); + flp->nfsfl_statshint = fxdr_unsigned(uint32_t, *tl); + NFSCL_DEBUG(4, "fflags=0x%x statshint=%d\n", + flp->nfsfl_fflags, flp->nfsfl_statshint); + } else { + error = NFSERR_BADXDR; + goto nfsmout; } if (flp->nfsfl_iomode == gotiomode) { /* Keep the list in increasing offset order. */ @@ -6100,6 +6913,7 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, else LIST_INSERT_AFTER(prevflp, flp, nfsfl_list); + NFSCL_DEBUG(4, "flp inserted\n"); } else { printf("nfscl_layoutget(): got wrong iomode\n"); nfscl_freeflayout(flp); @@ -6107,11 +6921,57 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, flp = NULL; } nfsmout: + NFSCL_DEBUG(4, "eo nfsrv_parselayoutget=%d\n", error); if (error != 0 && flp != NULL) nfscl_freeflayout(flp); return (error); } +/* + * Parse a user/group digit string. + */ +static int +nfsrv_parseug(struct nfsrv_descript *nd, int dogrp, uid_t *uidp, gid_t *gidp, + NFSPROC_T *p) +{ + uint32_t *tl; + char *cp, *str, str0[NFSV4_SMALLSTR + 1]; + uint32_t len = 0; + int error = 0; + + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + len = fxdr_unsigned(uint32_t, *tl); + if (len > NFSV4_OPAQUELIMIT) { + error = NFSERR_BADXDR; + goto nfsmout; + } + NFSCL_DEBUG(4, "nfsrv_parseug: len=%d\n", len); + if (len == 0) { + if (dogrp != 0) + *gidp = GID_NOGROUP; + else + *uidp = UID_NOBODY; + return (0); + } + if (len > NFSV4_SMALLSTR) + str = malloc(len + 1, M_TEMP, M_WAITOK); + else + str = str0; + NFSM_DISSECT(cp, char *, NFSM_RNDUP(len)); + NFSBCOPY(cp, str, len); + str[len] = '\0'; + NFSCL_DEBUG(4, "nfsrv_parseug: str=%s\n", str); + if (dogrp != 0) + error = nfsv4_strtogid(nd, str, len, gidp, p); + else + error = nfsv4_strtouid(nd, str, len, uidp, p); +nfsmout: + if (len > NFSV4_SMALLSTR) + free(str, M_TEMP); + NFSCL_DEBUG(4, "eo nfsrv_parseug=%d\n", error); + return (error); +} + /* * Similar to nfsrpc_getlayout(), except that it uses nfsrpc_openlayget(), * so that it does both an Open and a Layoutget. @@ -6126,11 +6986,15 @@ nfsrpc_getopenlayout(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, struct nfsclflayout *flp; struct nfsclflayouthead flh; int error, islocked, layoutlen, recalled, retonclose, usecurstateid; - int laystat; + int layouttype, laystat; nfsv4stateid_t stateid; struct nfsclsession *tsep; error = 0; + if (NFSHASFLEXFILE(nmp)) + layouttype = NFSLAYOUT_FLEXFILE; + else + layouttype = NFSLAYOUT_NFSV4_1_FILES; /* * If lyp is returned non-NULL, there will be a refcnt (shared lock) * on it, iff flp != NULL or a lock (exclusive lock) on it iff @@ -6161,13 +7025,13 @@ nfsrpc_getopenlayout(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, } error = nfsrpc_openlayoutrpc(nmp, vp, nfhp, fhlen, newfhp, newfhlen, mode, op, name, namelen, - dpp, &stateid, usecurstateid, layoutlen, + dpp, &stateid, usecurstateid, layouttype, layoutlen, &retonclose, &flh, &laystat, cred, p); NFSCL_DEBUG(4, "aft nfsrpc_openlayoutrpc laystat=%d err=%d\n", laystat, error); laystat = nfsrpc_layoutgetres(nmp, vp, newfhp, newfhlen, - &stateid, retonclose, NULL, &lyp, &flh, laystat, &islocked, - cred, p); + &stateid, retonclose, NULL, &lyp, &flh, layouttype, laystat, + &islocked, cred, p); } else error = nfsrpc_openrpc(nmp, vp, nfhp, fhlen, newfhp, newfhlen, mode, op, name, namelen, dpp, 0, 0, cred, p, 0, 0); @@ -6189,7 +7053,7 @@ static int nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, uint8_t *newfhp, int newfhlen, uint32_t mode, struct nfsclopen *op, uint8_t *name, int namelen, struct nfscldeleg **dpp, - nfsv4stateid_t *stateidp, int usecurstateid, + nfsv4stateid_t *stateidp, int usecurstateid, int layouttype, int layoutlen, int *retonclosep, struct nfsclflayouthead *flhp, int *laystatp, struct ucred *cred, NFSPROC_T *p) { @@ -6204,7 +7068,8 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, *dpp = NULL; *laystatp = ENXIO; - nfscl_reqstart(nd, NFSPROC_OPENLAYGET, nmp, nfhp, fhlen, NULL, NULL); + nfscl_reqstart(nd, NFSPROC_OPENLAYGET, nmp, nfhp, fhlen, NULL, NULL, + 0, 0); NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); @@ -6230,7 +7095,7 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, else iomode = NFSLAYOUTIOMODE_READ; nfsrv_setuplayoutget(nd, iomode, 0, UINT64_MAX, 0, stateidp, - layoutlen, usecurstateid); + layouttype, layoutlen, usecurstateid); error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, vp, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); if (error != 0) @@ -6364,7 +7229,7 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, struct ucred *cred, NFSPROC_T *p, struct nfsvattr *dnap, struct nfsvattr *nnap, struct nfsfh **nfhpp, int *attrflagp, int *dattrflagp, void *dstuff, int *unlockedp, nfsv4stateid_t *stateidp, - int usecurstateid, int layoutlen, int *retonclosep, + int usecurstateid, int layouttype, int layoutlen, int *retonclosep, struct nfsclflayouthead *flhp, int *laystatp) { uint32_t *tl; @@ -6443,7 +7308,7 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, *tl++ = txdr_unsigned(NFSV4OP_RESTOREFH); *tl = txdr_unsigned(NFSV4OP_LAYOUTGET); nfsrv_setuplayoutget(nd, NFSLAYOUTIOMODE_RW, 0, UINT64_MAX, 0, stateidp, - layoutlen, usecurstateid); + layouttype, layoutlen, usecurstateid); error = nfscl_request(nd, dvp, p, cred, dstuff); if (error != 0) return (error); @@ -6629,17 +7494,21 @@ nfsrpc_getcreatelayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, struct nfsclsession *tsep; struct nfsmount *nmp; nfsv4stateid_t stateid; - int error, layoutlen, retonclose, laystat; + int error, layoutlen, layouttype, retonclose, laystat; error = 0; nmp = VFSTONFS(dvp->v_mount); + if (NFSHASFLEXFILE(nmp)) + layouttype = NFSLAYOUT_FLEXFILE; + else + layouttype = NFSLAYOUT_NFSV4_1_FILES; LIST_INIT(&flh); tsep = nfsmnt_mdssession(nmp); layoutlen = tsep->nfsess_maxcache - (NFSX_STATEID + 3 * NFSX_UNSIGNED); error = nfsrpc_createlayout(dvp, name, namelen, vap, cverf, fmode, owp, dpp, cred, p, dnap, nnap, nfhpp, attrflagp, dattrflagp, - dstuff, unlockedp, &stateid, 1, layoutlen, &retonclose, &flh, - &laystat); + dstuff, unlockedp, &stateid, 1, layouttype, layoutlen, &retonclose, + &flh, &laystat); NFSCL_DEBUG(4, "aft nfsrpc_createlayoutrpc laystat=%d err=%d\n", laystat, error); lyp = NULL; @@ -6647,10 +7516,11 @@ nfsrpc_getcreatelayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, nfhp = *nfhpp; laystat = nfsrpc_layoutgetres(nmp, dvp, nfhp->nfh_fh, nfhp->nfh_len, &stateid, retonclose, NULL, &lyp, &flh, - laystat, NULL, cred, p); + layouttype, laystat, NULL, cred, p); } else laystat = nfsrpc_layoutgetres(nmp, dvp, NULL, 0, &stateid, - retonclose, NULL, &lyp, &flh, laystat, NULL, cred, p); + retonclose, NULL, &lyp, &flh, layouttype, laystat, NULL, + cred, p); if (laystat == 0) nfscl_rellayout(lyp, 0); return (error); @@ -6662,17 +7532,23 @@ nfsrpc_getcreatelayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, static int nfsrpc_layoutgetres(struct nfsmount *nmp, vnode_t vp, uint8_t *newfhp, int newfhlen, nfsv4stateid_t *stateidp, int retonclose, uint32_t *notifybit, - struct nfscllayout **lypp, struct nfsclflayouthead *flhp, + struct nfscllayout **lypp, struct nfsclflayouthead *flhp, int layouttype, int laystat, int *islockedp, struct ucred *cred, NFSPROC_T *p) { struct nfsclflayout *tflp; struct nfscldevinfo *dip; + uint8_t *dev; if (laystat == NFSERR_UNKNLAYOUTTYPE) { - /* Disable PNFS. */ - NFSCL_DEBUG(1, "disable PNFS\n"); NFSLOCKMNT(nmp); - nmp->nm_state &= ~NFSSTA_PNFS; + if (!NFSHASFLEXFILE(nmp)) { + /* Switch to using Flex File Layout. */ + nmp->nm_state |= NFSSTA_FLEXFILE; + } else if (layouttype == NFSLAYOUT_FLEXFILE) { + /* Disable pNFS. */ + NFSCL_DEBUG(1, "disable PNFS\n"); + nmp->nm_state &= ~(NFSSTA_PNFS | NFSSTA_FLEXFILE); + } NFSUNLOCKMNT(nmp); } if (laystat == 0) { @@ -6681,9 +7557,12 @@ nfsrpc_layoutgetres(struct nfsmount *nmp, vnode_t vp, uint8_t *newfhp, laystat = nfscl_adddevinfo(nmp, NULL, tflp); NFSCL_DEBUG(4, "aft adddev=%d\n", laystat); if (laystat != 0) { - laystat = nfsrpc_getdeviceinfo(nmp, - tflp->nfsfl_dev, NFSLAYOUT_NFSV4_1_FILES, - notifybit, &dip, cred, p); + if (layouttype == NFSLAYOUT_FLEXFILE) + dev = tflp->nfsfl_ffm[0].dev; + else + dev = tflp->nfsfl_dev; + laystat = nfsrpc_getdeviceinfo(nmp, dev, + layouttype, notifybit, &dip, cred, p); NFSCL_DEBUG(4, "aft nfsrpc_gdi=%d\n", laystat); if (laystat != 0) @@ -6702,7 +7581,7 @@ nfsrpc_layoutgetres(struct nfsmount *nmp, vnode_t vp, uint8_t *newfhp, * get the fsid for the file system. */ laystat = nfscl_layout(nmp, vp, newfhp, newfhlen, stateidp, - retonclose, flhp, lypp, cred, p); + layouttype, retonclose, flhp, lypp, cred, p); NFSCL_DEBUG(4, "nfsrpc_layoutgetres: aft nfscl_layout=%d\n", laystat); if (laystat == 0 && islockedp != NULL) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 96b0a6e7be27..cedc157b0dac 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -1627,6 +1627,14 @@ nfscl_cleanclient(struct nfsclclient *clp) { struct nfsclowner *owp, *nowp; struct nfsclopen *op, *nop; + struct nfscllayout *lyp, *nlyp; + struct nfscldevinfo *dip, *ndip; + + TAILQ_FOREACH_SAFE(lyp, &clp->nfsc_layout, nfsly_list, nlyp) + nfscl_freelayout(lyp); + + LIST_FOREACH_SAFE(dip, &clp->nfsc_devinfo, nfsdi_list, ndip) + nfscl_freedevinfo(dip); /* Now, all the OpenOwners, etc. */ LIST_FOREACH_SAFE(owp, &clp->nfsc_owner, nfsow_list, nowp) { @@ -4775,7 +4783,7 @@ nfscl_errmap(struct nfsrv_descript *nd, u_int32_t minorvers) */ APPLESTATIC int nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen, - nfsv4stateid_t *stateidp, int retonclose, + nfsv4stateid_t *stateidp, int layouttype, int retonclose, struct nfsclflayouthead *fhlp, struct nfscllayout **lypp, struct ucred *cred, NFSPROC_T *p) { @@ -4827,8 +4835,12 @@ nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen, lyp->nfsly_filesid[0] = np->n_vattr.na_filesid[0]; lyp->nfsly_filesid[1] = np->n_vattr.na_filesid[1]; lyp->nfsly_clp = clp; - lyp->nfsly_flags = (retonclose != 0) ? - (NFSLY_FILES | NFSLY_RETONCLOSE) : NFSLY_FILES; + if (layouttype == NFSLAYOUT_FLEXFILE) + lyp->nfsly_flags = NFSLY_FLEXFILE; + else + lyp->nfsly_flags = NFSLY_FILES; + if (retonclose != 0) + lyp->nfsly_flags |= NFSLY_RETONCLOSE; lyp->nfsly_fhlen = fhlen; NFSBCOPY(fhp, lyp->nfsly_fh, fhlen); TAILQ_INSERT_HEAD(&clp->nfsc_layout, lyp, nfsly_list); @@ -5071,6 +5083,7 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, { struct nfsclclient *clp; struct nfscldevinfo *tdip; + uint8_t *dev; NFSLOCKCLSTATE(); clp = nmp->nm_clp; @@ -5080,7 +5093,11 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, free(dip, M_NFSDEVINFO); return (ENODEV); } - tdip = nfscl_finddevinfo(clp, flp->nfsfl_dev); + if ((flp->nfsfl_flags & NFSFL_FILE) != 0) + dev = flp->nfsfl_dev; + else + dev = flp->nfsfl_ffm[0].dev; + tdip = nfscl_finddevinfo(clp, dev); if (tdip != NULL) { tdip->nfsdi_layoutrefs++; flp->nfsfl_devp = tdip; @@ -5132,10 +5149,15 @@ nfscl_freelayout(struct nfscllayout *layp) APPLESTATIC void nfscl_freeflayout(struct nfsclflayout *flp) { - int i; + int i, j; - for (i = 0; i < flp->nfsfl_fhcnt; i++) - free(flp->nfsfl_fh[i], M_NFSFH); + if ((flp->nfsfl_flags & NFSFL_FILE) != 0) + for (i = 0; i < flp->nfsfl_fhcnt; i++) + free(flp->nfsfl_fh[i], M_NFSFH); + if ((flp->nfsfl_flags & NFSFL_FLEXFILE) != 0) + for (i = 0; i < flp->nfsfl_mirrorcnt; i++) + for (j = 0; j < flp->nfsfl_ffm[i].fhcnt; j++) + free(flp->nfsfl_ffm[i].fh[j], M_NFSFH); if (flp->nfsfl_devp != NULL) flp->nfsfl_devp->nfsdi_layoutrefs--; free(flp, M_NFSFLAYOUT); @@ -5227,15 +5249,20 @@ nfscl_layoutreturn(struct nfsmount *nmp, struct nfscllayout *lyp, { struct nfsclrecalllayout *rp; nfsv4stateid_t stateid; + int layouttype; NFSBCOPY(lyp->nfsly_stateid.other, stateid.other, NFSX_STATEIDOTHER); stateid.seqid = lyp->nfsly_stateid.seqid; + if ((lyp->nfsly_flags & NFSLY_FILES) != 0) + layouttype = NFSLAYOUT_NFSV4_1_FILES; + else + layouttype = NFSLAYOUT_FLEXFILE; LIST_FOREACH(rp, &lyp->nfsly_recall, nfsrecly_list) { (void)nfsrpc_layoutreturn(nmp, lyp->nfsly_fh, - lyp->nfsly_fhlen, 0, NFSLAYOUT_NFSV4_1_FILES, + lyp->nfsly_fhlen, 0, layouttype, rp->nfsrecly_iomode, rp->nfsrecly_recalltype, rp->nfsrecly_off, rp->nfsrecly_len, - &stateid, 0, NULL, cred, p, NULL); + &stateid, cred, p, NULL); } } @@ -5248,15 +5275,27 @@ nfscl_dolayoutcommit(struct nfsmount *nmp, struct nfscllayout *lyp, { struct nfsclflayout *flp; uint64_t len; - int error; + int error, layouttype; + if ((lyp->nfsly_flags & NFSLY_FILES) != 0) + layouttype = NFSLAYOUT_NFSV4_1_FILES; + else + layouttype = NFSLAYOUT_FLEXFILE; LIST_FOREACH(flp, &lyp->nfsly_flayrw, nfsfl_list) { - if (flp->nfsfl_off <= lyp->nfsly_lastbyte) { + if (layouttype == NFSLAYOUT_FLEXFILE && + (flp->nfsfl_fflags & NFSFLEXFLAG_NO_LAYOUTCOMMIT) != 0) { + NFSCL_DEBUG(4, "Flex file: no layoutcommit\n"); + /* If not supported, don't bother doing it. */ + NFSLOCKMNT(nmp); + nmp->nm_state |= NFSSTA_NOLAYOUTCOMMIT; + NFSUNLOCKMNT(nmp); + break; + } else if (flp->nfsfl_off <= lyp->nfsly_lastbyte) { len = flp->nfsfl_end - flp->nfsfl_off; error = nfsrpc_layoutcommit(nmp, lyp->nfsly_fh, lyp->nfsly_fhlen, 0, flp->nfsfl_off, len, lyp->nfsly_lastbyte, &lyp->nfsly_stateid, - NFSLAYOUT_NFSV4_1_FILES, 0, NULL, cred, p, NULL); + layouttype, cred, p, NULL); NFSCL_DEBUG(4, "layoutcommit err=%d\n", error); if (error == NFSERR_NOTSUPP) { /* If not supported, don't bother doing it. */ diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 507f4b41fcd8..509849d148d8 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -921,7 +921,7 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int isdgram, nd->nd_md, nd->nd_dpos, nd->nd_cred, p); error = nfsm_advance(nd, NFSM_RNDUP(retlen), -1); if (error) - panic("nfsrv_write mbuf"); + goto nfsmout; } if (nd->nd_flag & ND_NFSV4) aftat_ret = 0; @@ -3729,6 +3729,7 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, uint32_t sp4type, v41flags; uint64_t owner_minor; struct timespec verstime; + struct sockaddr_in *sad, *rad; if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) { nd->nd_repstat = NFSERR_WRONGSEC; @@ -3752,6 +3753,13 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx); NFSSOCKADDRALLOC(clp->lc_req.nr_nam); NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in)); + sad = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *); + rad = NFSSOCKADDR(clp->lc_req.nr_nam, struct sockaddr_in *); + rad->sin_family = AF_INET; + rad->sin_addr.s_addr = 0; + rad->sin_port = 0; + if (sad->sin_family == AF_INET) + rad->sin_addr.s_addr = sad->sin_addr.s_addr; clp->lc_req.nr_cred = NULL; NFSBCOPY(verf, clp->lc_verf, NFSX_VERF); clp->lc_idlen = idlen; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f494071171f3..47716024a934 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3891,11 +3891,11 @@ nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) u_char protocol[5], addr[24]; int error = 0, cantparse = 0; union { - u_long ival; + in_addr_t ival; u_char cval[4]; } ip; union { - u_short sval; + in_port_t sval; u_char cval[2]; } port; @@ -3989,8 +3989,10 @@ nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) } if (cantparse) { sad = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *); - rad->sin_addr.s_addr = sad->sin_addr.s_addr; - rad->sin_port = 0x0; + if (sad->sin_family == AF_INET) { + rad->sin_addr.s_addr = sad->sin_addr.s_addr; + rad->sin_port = 0x0; + } clp->lc_program = 0; } nfsmout: diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index c42de32486bf..52f307ee950d 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -81,7 +81,6 @@ typedef enum { */ struct pfs_info; struct pfs_node; -struct pfs_bitmap; /* * Init / uninit callback @@ -121,8 +120,6 @@ struct vattr; int name(PFS_ATTR_ARGS); typedef int (*pfs_attr_t)(PFS_ATTR_ARGS); -struct pfs_bitmap; /* opaque */ - /* * Visibility callback * Called with proc locked diff --git a/sys/fs/tmpfs/tmpfs_fifoops.c b/sys/fs/tmpfs/tmpfs_fifoops.c index f1743db50de9..30e5d1a91493 100644 --- a/sys/fs/tmpfs/tmpfs_fifoops.c +++ b/sys/fs/tmpfs/tmpfs_fifoops.c @@ -69,5 +69,5 @@ struct vop_vector tmpfs_fifoop_entries = { .vop_access = tmpfs_access, .vop_getattr = tmpfs_getattr, .vop_setattr = tmpfs_setattr, + .vop_print = tmpfs_print, }; - diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index b04d28ba4055..8180a2cd2a4c 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -350,7 +350,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, case VREG: uobj = node->tn_reg.tn_aobj; if (uobj != NULL) { - atomic_subtract_long(&tmp->tm_pages_used, uobj->size); + if (uobj->size != 0) + atomic_subtract_long(&tmp->tm_pages_used, uobj->size); KASSERT((uobj->flags & OBJ_TMPFS) == 0, ("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj)); vm_object_deallocate(uobj); @@ -361,7 +362,13 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, panic("tmpfs_free_node: type %p %d", node, (int)node->tn_type); } - free_unr(tmp->tm_ino_unr, node->tn_id); + /* + * If we are unmounting there is no need for going through the overhead + * of freeing the inodes from the unr individually, so free them all in + * one go later. + */ + if (!detach) + free_unr(tmp->tm_ino_unr, node->tn_id); uma_zfree(tmp->tm_node_pool, node); TMPFS_LOCK(tmp); tmpfs_free_tmp(tmp); @@ -1375,6 +1382,12 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr) oldpages = OFF_TO_IDX(oldsize + PAGE_MASK); MPASS(oldpages == uobj->size); newpages = OFF_TO_IDX(newsize + PAGE_MASK); + + if (__predict_true(newpages == oldpages && newsize >= oldsize)) { + node->tn_size = newsize; + return (0); + } + if (newpages > oldpages && tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0) return (ENOSPC); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 4b336ba150dd..a1c6c027d16a 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -342,6 +342,7 @@ tmpfs_free_tmp(struct tmpfs_mount *tmp) uma_zdestroy(tmp->tm_dirent_pool); uma_zdestroy(tmp->tm_node_pool); + clear_unrhdr(tmp->tm_ino_unr); delete_unrhdr(tmp->tm_ino_unr); mtx_destroy(&tmp->tm_allnode_lock); diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 3eed85a43266..866f4e209dcf 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1310,7 +1310,7 @@ tmpfs_reclaim(struct vop_reclaim_args *v) return 0; } -static int +int tmpfs_print(struct vop_print_args *v) { struct vnode *vp = v->a_vp; @@ -1353,7 +1353,7 @@ tmpfs_pathconf(struct vop_pathconf_args *v) break; case _PC_FILESIZEBITS: - *retval = 0; /* XXX Don't know which value should I return. */ + *retval = 64; break; default: diff --git a/sys/fs/tmpfs/tmpfs_vnops.h b/sys/fs/tmpfs/tmpfs_vnops.h index db614a051291..f479bf816b91 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.h +++ b/sys/fs/tmpfs/tmpfs_vnops.h @@ -49,6 +49,7 @@ extern struct vop_vector tmpfs_vnodeop_nonc_entries; vop_access_t tmpfs_access; vop_getattr_t tmpfs_getattr; vop_setattr_t tmpfs_setattr; +vop_print_t tmpfs_print; vop_reclaim_t tmpfs_reclaim; #endif /* _FS_TMPFS_TMPFS_VNOPS_H_ */ diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c index 7432283b8591..9d3863bbd8dd 100644 --- a/sys/fs/udf/udf_vnops.c +++ b/sys/fs/udf/udf_vnops.c @@ -383,20 +383,23 @@ udf_pathconf(struct vop_pathconf_args *a) { switch (a->a_name) { + case _PC_FILESIZEBITS: + *a->a_retval = 64; + return (0); case _PC_LINK_MAX: *a->a_retval = 65535; return (0); case _PC_NAME_MAX: *a->a_retval = NAME_MAX; return (0); - case _PC_PATH_MAX: - *a->a_retval = PATH_MAX; + case _PC_SYMLINK_MAX: + *a->a_retval = MAXPATHLEN; return (0); case _PC_NO_TRUNC: *a->a_retval = 1; return (0); default: - return (EINVAL); + return (vop_stdpathconf(a)); } } diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c index f8f3836f66eb..7c10b3b2b5a9 100644 --- a/sys/gdb/gdb_main.c +++ b/sys/gdb/gdb_main.c @@ -94,6 +94,33 @@ gdb_init(void) return (cur_pri); } +static void +gdb_do_mem_search(void) +{ + size_t patlen; + intmax_t addr, size; + const unsigned char *found; + + if (gdb_rx_varhex(&addr) || gdb_rx_char() != ';' || + gdb_rx_varhex(&size) || gdb_rx_char() != ';' || + gdb_rx_bindata(gdb_bindata, sizeof(gdb_bindata), &patlen)) { + gdb_tx_err(EINVAL); + return; + } + if (gdb_search_mem((char *)(uintptr_t)addr, size, gdb_bindata, + patlen, &found)) { + if (found == 0ULL) + gdb_tx_begin('0'); + else { + gdb_tx_begin('1'); + gdb_tx_char(','); + gdb_tx_hex((intmax_t)(uintptr_t)found, 8); + } + gdb_tx_end(); + } else + gdb_tx_err(EIO); +} + static int gdb_trap(int type, int code) { @@ -257,27 +284,7 @@ gdb_trap(int type, int code) gdb_tx_end(); } } else if (gdb_rx_equal("Search:memory:")) { - size_t patlen; - intmax_t addr, size; - const unsigned char *found; - if (gdb_rx_varhex(&addr) || gdb_rx_char() != ';' || - gdb_rx_varhex(&size) || gdb_rx_char() != ';' || - gdb_rx_bindata(gdb_bindata, sizeof(gdb_bindata), &patlen)) { - gdb_tx_err(EINVAL); - break; - } - if (gdb_search_mem((char *)(uintptr_t)addr, size, gdb_bindata, patlen, &found)) { - if (found == 0ULL) - gdb_tx_begin('0'); - else { - gdb_tx_begin('1'); - gdb_tx_char(','); - gdb_tx_hex((intmax_t)(uintptr_t)found, 8); - } - gdb_tx_end(); - } else - gdb_tx_err(EIO); - break; + gdb_do_mem_search(); } else if (!gdb_cpu_query()) gdb_tx_empty(); break; diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 03a404682b1c..202c9f7dc0a4 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -138,7 +138,7 @@ g_dev_setdumpdev(struct cdev *dev, struct diocskerneldump_arg *kda, int error, len; if (dev == NULL || kda == NULL) - return (set_dumper(NULL, NULL, td, 0, NULL, 0, NULL)); + return (set_dumper(NULL, NULL, td, 0, 0, NULL, 0, NULL)); cp = dev->si_drv2; len = sizeof(kd); @@ -148,8 +148,9 @@ g_dev_setdumpdev(struct cdev *dev, struct diocskerneldump_arg *kda, if (error != 0) return (error); - error = set_dumper(&kd.di, devtoname(dev), td, kda->kda_encryption, - kda->kda_key, kda->kda_encryptedkeysize, kda->kda_encryptedkey); + error = set_dumper(&kd.di, devtoname(dev), td, kda->kda_compression, + kda->kda_encryption, kda->kda_key, kda->kda_encryptedkeysize, + kda->kda_encryptedkey); if (error == 0) dev->si_flags |= SI_DUMPDEV; @@ -832,7 +833,7 @@ g_dev_orphan(struct g_consumer *cp) /* Reset any dump-area set on this device */ if (dev->si_flags & SI_DUMPDEV) - (void)set_dumper(NULL, NULL, curthread, 0, NULL, 0, NULL); + (void)set_dumper(NULL, NULL, curthread, 0, 0, NULL, 0, NULL); /* Destroy the struct cdev *so we get no more requests */ destroy_dev_sched_cb(dev, g_dev_callback, cp); diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h index bffb27ef6cb4..7fcd43566ecb 100644 --- a/sys/geom/geom_disk.h +++ b/sys/geom/geom_disk.h @@ -37,6 +37,11 @@ #ifndef _GEOM_GEOM_DISK_H_ #define _GEOM_GEOM_DISK_H_ +#define DISK_RR_UNKNOWN 0 +#define DISK_RR_NON_ROTATING 1 +#define DISK_RR_MIN 0x0401 +#define DISK_RR_MAX 0xfffe + #ifdef _KERNEL #include @@ -127,11 +132,6 @@ struct disk { #define DISKFLAG_DIRECT_COMPLETION 0x20 #define DISKFLAG_CANZONE 0x80 -#define DISK_RR_UNKNOWN 0 -#define DISK_RR_NON_ROTATING 1 -#define DISK_RR_MIN 0x0401 -#define DISK_RR_MAX 0xfffe - struct disk *disk_alloc(void); void disk_create(struct disk *disk, int version); void disk_destroy(struct disk *disk); diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 2102ae9c0809..6cf17fcdfde3 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -72,10 +71,19 @@ g_slice_alloc(unsigned nslice, unsigned scsize) } static void -g_slice_free(struct g_slicer *gsp) +g_slice_free(struct g_geom *gp) { + struct g_slicer *gsp; - if (gsp == NULL) /* XXX: phk thinks about this */ + gsp = gp->softc; + gp->softc = NULL; + + /* + * We can get multiple spoiled events before wither-washer + * detaches our consumer, so this can get called multiple + * times. + */ + if (gsp == NULL) return; g_free(gsp->slices); if (gsp->hotspot != NULL) @@ -127,6 +135,15 @@ g_slice_access(struct g_provider *pp, int dr, int dw, int de) if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1) de--; error = g_access(cp, dr, dw, de); + + /* + * Free the softc if all providers have been closed and this geom + * is being removed. + */ + if (error == 0 && (gp->flags & G_GEOM_WITHER) != 0 && + (cp->acr + cp->acw + cp->ace) == 0) + g_slice_free(gp); + return (error); } @@ -470,19 +487,30 @@ g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length, int r } void -g_slice_spoiled(struct g_consumer *cp) +g_slice_orphan(struct g_consumer *cp) { struct g_geom *gp; - struct g_slicer *gsp; g_topology_assert(); gp = cp->geom; - g_trace(G_T_TOPOLOGY, "g_slice_spoiled(%p/%s)", cp, gp->name); - cp->flags |= G_CF_ORPHAN; - gsp = gp->softc; - gp->softc = NULL; - g_slice_free(gsp); + g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name); g_wither_geom(gp, ENXIO); + + /* + * We can safely free the softc now if there are no accesses, + * otherwise g_slice_access() will do that after the last close. + */ + if ((cp->acr + cp->acw + cp->ace) == 0) + g_slice_free(gp); +} + +void +g_slice_spoiled(struct g_consumer *cp) +{ + + g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->geom->name); + cp->flags |= G_CF_ORPHAN; + g_slice_orphan(cp); } int @@ -507,10 +535,10 @@ g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_co gp = g_new_geomf(mp, "%s", pp->name); gsp = g_slice_alloc(slices, extra); gsp->start = start; - gp->access = g_slice_access; - gp->orphan = g_slice_orphan; gp->softc = gsp; gp->start = g_slice_start; + gp->access = g_slice_access; + gp->orphan = g_slice_orphan; gp->spoiled = g_slice_spoiled; if (gp->dumpconf == NULL) gp->dumpconf = g_slice_dumpconf; @@ -530,18 +558,3 @@ g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_co *cpp = cp; return (gp); } - -void -g_slice_orphan(struct g_consumer *cp) -{ - struct g_slicer *gsp; - - g_trace(G_T_TOPOLOGY, "g_slice_orphan(%p/%s)", cp, cp->provider->name); - g_topology_assert(); - - /* XXX: Not good enough we leak the softc and its suballocations */ - gsp = cp->geom->softc; - cp->geom->softc = NULL; - g_slice_free(gsp); - g_wither_geom(cp->geom, ENXIO); -} diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index e1fd0296c31f..fbbe0d904317 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -631,6 +631,14 @@ g_resize_provider_event(void *arg, int flag) LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) { gp = cp->geom; if (gp->resize == NULL && size < pp->mediasize) { + /* + * XXX: g_dev_orphan method does deferred destroying + * and it is possible, that other event could already + * call the orphan method. Check consumer's flags to + * do not schedule it twice. + */ + if (cp->flags & G_CF_ORPHAN) + continue; cp->flags |= G_CF_ORPHAN; cp->geom->orphan(cp); } @@ -820,6 +828,7 @@ g_attach(struct g_consumer *cp, struct g_provider *pp) g_trace(G_T_TOPOLOGY, "g_attach(%p, %p)", cp, pp); KASSERT(cp->provider == NULL, ("attach but attached")); cp->provider = pp; + cp->flags &= ~G_CF_ORPHAN; LIST_INSERT_HEAD(&pp->consumers, cp, consumers); error = redo_rank(cp->geom); if (error) { diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 4447ce2a2dd2..7f8f670d7461 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -982,7 +982,13 @@ g_mirror_regular_request(struct bio *bp) if (g_mirror_disconnect_on_failure && g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE) > 1) { - sc->sc_bump_id |= G_MIRROR_BUMP_GENID; + if (bp->bio_error == ENXIO && + bp->bio_cmd == BIO_READ) + sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID; + else if (bp->bio_error == ENXIO) + sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID_NOW; + else + sc->sc_bump_id |= G_MIRROR_BUMP_GENID; g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DISCONNECTED, G_MIRROR_EVENT_DONTWAIT); @@ -2518,6 +2524,10 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool force) sc->sc_bump_id &= ~G_MIRROR_BUMP_GENID; g_mirror_bump_genid(sc); } + if ((sc->sc_bump_id & G_MIRROR_BUMP_SYNCID_NOW) != 0) { + sc->sc_bump_id &= ~G_MIRROR_BUMP_SYNCID_NOW; + g_mirror_bump_syncid(sc); + } break; default: KASSERT(1 == 0, ("Wrong device state (%s, %s).", @@ -3078,8 +3088,10 @@ g_mirror_destroy(struct g_mirror_softc *sc, int how) } } - if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) + if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) { + sx_xunlock(&sc->sc_lock); return (0); + } sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY; sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DRAIN; G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc); diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h index e573acc5e806..f3a4a0070093 100644 --- a/sys/geom/mirror/g_mirror.h +++ b/sys/geom/mirror/g_mirror.h @@ -169,9 +169,11 @@ struct g_mirror_event { #define G_MIRROR_TYPE_AUTOMATIC 1 /* Bump syncid on first write. */ -#define G_MIRROR_BUMP_SYNCID 0x1 +#define G_MIRROR_BUMP_SYNCID 0x1 /* Bump genid immediately. */ -#define G_MIRROR_BUMP_GENID 0x2 +#define G_MIRROR_BUMP_GENID 0x2 +/* Bump syncid immediately. */ +#define G_MIRROR_BUMP_SYNCID_NOW 0x4 struct g_mirror_softc { u_int sc_type; /* Device type (manual/automatic). */ u_int sc_state; /* Device state. */ diff --git a/sys/geom/mountver/g_mountver.c b/sys/geom/mountver/g_mountver.c index 278157b355d3..a9ffe3848e82 100644 --- a/sys/geom/mountver/g_mountver.c +++ b/sys/geom/mountver/g_mountver.c @@ -190,6 +190,11 @@ g_mountver_start(struct bio *bp) * requests in order to maintain ordering. */ if (sc->sc_orphaned || !TAILQ_EMPTY(&sc->sc_queue)) { + if (sc->sc_shutting_down) { + G_MOUNTVER_LOGREQ(bp, "Discarding request due to shutdown."); + g_io_deliver(bp, ENXIO); + return; + } G_MOUNTVER_LOGREQ(bp, "Queueing request."); g_mountver_queue(bp); if (!sc->sc_orphaned) @@ -252,7 +257,7 @@ g_mountver_create(struct gctl_req *req, struct g_class *mp, struct g_provider *p } gp = g_new_geomf(mp, "%s", name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); - mtx_init(&sc->sc_mtx, "gmountver", NULL, MTX_DEF); + mtx_init(&sc->sc_mtx, "gmountver", NULL, MTX_DEF | MTX_RECURSE); TAILQ_INIT(&sc->sc_queue); sc->sc_provider_name = strdup(pp->name, M_GEOM); gp->softc = sc; @@ -265,8 +270,18 @@ g_mountver_create(struct gctl_req *req, struct g_class *mp, struct g_provider *p newpp = g_new_providerf(gp, "%s", gp->name); newpp->mediasize = pp->mediasize; newpp->sectorsize = pp->sectorsize; + newpp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; + + if ((pp->flags & G_PF_ACCEPT_UNMAPPED) != 0) { + G_MOUNTVER_DEBUG(0, "Unmapped supported for %s.", gp->name); + newpp->flags |= G_PF_ACCEPT_UNMAPPED; + } else { + G_MOUNTVER_DEBUG(0, "Unmapped unsupported for %s.", gp->name); + newpp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; error = g_attach(cp, pp); if (error != 0) { gctl_error(req, "Cannot attach to provider %s.", pp->name); @@ -607,13 +622,20 @@ g_mountver_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, static void g_mountver_shutdown_pre_sync(void *arg, int howto) { + struct g_mountver_softc *sc; struct g_class *mp; struct g_geom *gp, *gp2; mp = arg; g_topology_lock(); - LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) - g_mountver_destroy(gp, 1); + LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { + if (gp->softc == NULL) + continue; + sc = gp->softc; + sc->sc_shutting_down = 1; + if (sc->sc_orphaned) + g_mountver_destroy(gp, 1); + } g_topology_unlock(); } diff --git a/sys/geom/mountver/g_mountver.h b/sys/geom/mountver/g_mountver.h index 1dc8372cf872..3fb9e863c6d3 100644 --- a/sys/geom/mountver/g_mountver.h +++ b/sys/geom/mountver/g_mountver.h @@ -62,6 +62,7 @@ struct g_mountver_softc { char *sc_provider_name; char sc_ident[DISK_IDENT_SIZE]; int sc_orphaned; + int sc_shutting_down; int sc_access_r; int sc_access_w; int sc_access_e; diff --git a/sys/gnu/dts/arm/aks-cdu.dts b/sys/gnu/dts/arm/aks-cdu.dts index 5b1bf92d927c..888bfcd4a402 100644 --- a/sys/gnu/dts/arm/aks-cdu.dts +++ b/sys/gnu/dts/arm/aks-cdu.dts @@ -62,32 +62,36 @@ status = "okay"; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; - status = "okay"; + ebi: ebi@10000000 { + nand_controller: nand-controller { + nand: nand@3 { + partitions { + bootstrap@0 { + label = "bootstrap"; + reg = <0x0 0x40000>; + }; - bootstrap@0 { - label = "bootstrap"; - reg = <0x0 0x40000>; - }; + uboot@40000 { + label = "uboot"; + reg = <0x40000 0x80000>; + }; - uboot@40000 { - label = "uboot"; - reg = <0x40000 0x80000>; - }; - ubootenv@c0000 { - label = "ubootenv"; - reg = <0xc0000 0x40000>; - }; - kernel@100000 { - label = "kernel"; - reg = <0x100000 0x400000>; - }; - rootfs@500000 { - label = "rootfs"; - reg = <0x500000 0x7b00000>; + ubootenv@c0000 { + label = "ubootenv"; + reg = <0xc0000 0x40000>; + }; + + kernel@100000 { + label = "kernel"; + reg = <0x100000 0x400000>; + }; + + rootfs@500000 { + label = "rootfs"; + reg = <0x500000 0x7b00000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/am335x-baltos.dtsi b/sys/gnu/dts/arm/am335x-baltos.dtsi index d42b98f15e8b..ec6052c521ef 100644 --- a/sys/gnu/dts/arm/am335x-baltos.dtsi +++ b/sys/gnu/dts/arm/am335x-baltos.dtsi @@ -255,7 +255,7 @@ }; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <8>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am335x-base0033.dts b/sys/gnu/dts/arm/am335x-base0033.dts index c2bee452dab8..29782be07605 100644 --- a/sys/gnu/dts/arm/am335x-base0033.dts +++ b/sys/gnu/dts/arm/am335x-base0033.dts @@ -89,7 +89,7 @@ &i2c0 { eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; }; diff --git a/sys/gnu/dts/arm/am335x-bone-common.dtsi b/sys/gnu/dts/arm/am335x-bone-common.dtsi index bf6b26abe35b..1d154444dfef 100644 --- a/sys/gnu/dts/arm/am335x-bone-common.dtsi +++ b/sys/gnu/dts/arm/am335x-bone-common.dtsi @@ -232,7 +232,7 @@ }; baseboard_eeprom: baseboard_eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; #address-cells = <1>; @@ -251,7 +251,7 @@ clock-frequency = <100000>; cape_eeprom0: cape_eeprom0@54 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x54>; #address-cells = <1>; #size-cells = <1>; @@ -261,7 +261,7 @@ }; cape_eeprom1: cape_eeprom1@55 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x55>; #address-cells = <1>; #size-cells = <1>; @@ -271,7 +271,7 @@ }; cape_eeprom2: cape_eeprom2@56 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x56>; #address-cells = <1>; #size-cells = <1>; @@ -281,7 +281,7 @@ }; cape_eeprom3: cape_eeprom3@57 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x57>; #address-cells = <1>; #size-cells = <1>; diff --git a/sys/gnu/dts/arm/am335x-boneblack-wireless.dts b/sys/gnu/dts/arm/am335x-boneblack-wireless.dts index 105bd10655f7..83f49f616b19 100644 --- a/sys/gnu/dts/arm/am335x-boneblack-wireless.dts +++ b/sys/gnu/dts/arm/am335x-boneblack-wireless.dts @@ -97,6 +97,11 @@ pinctrl-names = "default"; pinctrl-0 = <&uart3_pins &bt_pins>; status = "okay"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; }; &gpio3 { diff --git a/sys/gnu/dts/arm/am335x-boneblack.dts b/sys/gnu/dts/arm/am335x-boneblack.dts index 935ed17d22e4..d154d3133c16 100644 --- a/sys/gnu/dts/arm/am335x-boneblack.dts +++ b/sys/gnu/dts/arm/am335x-boneblack.dts @@ -22,7 +22,7 @@ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed * to support 1GHz OPP so enable it for PG 2.0 on this board. */ - oppnitro@1000000000 { + oppnitro-1000000000 { opp-supported-hw = <0x06 0x0100>; }; }; diff --git a/sys/gnu/dts/arm/am335x-boneblue.dts b/sys/gnu/dts/arm/am335x-boneblue.dts new file mode 100644 index 000000000000..cdc1b2be792f --- /dev/null +++ b/sys/gnu/dts/arm/am335x-boneblue.dts @@ -0,0 +1,460 @@ +/* + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include + +/ { + model = "TI AM335x BeagleBone Blue"; + compatible = "ti,am335x-bone-blue", "ti,am33xx"; + + cpus { + cpu@0 { + cpu0-supply = <&dcdc2_reg>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + chosen { + stdout-path = &uart0; + }; + + leds { + pinctrl-names = "default"; + pinctrl-0 = <&user_leds_s0>; + + compatible = "gpio-leds"; + + usr_0_led { + label = "beaglebone:green:usr0"; + gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + usr_1_led { + label = "beaglebone:green:usr1"; + gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + + usr_2_led { + label = "beaglebone:green:usr2"; + gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "cpu0"; + default-state = "off"; + }; + + usr_3_led { + label = "beaglebone:green:usr3"; + gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + default-state = "off"; + }; + + wifi_led { + label = "wifi"; + gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "phy0assoc"; + }; + + red_led { + label = "red"; + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + green_led { + label = "green"; + gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + batt_1_led { + label = "bat25"; + gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + batt_2_led { + label = "bat50"; + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + batt_3_led { + label = "bat75"; + gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + batt_4_led { + label = "bat100"; + gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + vmmcsd_fixed: fixedregulator0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + wlan_en_reg: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "wlan-en-regulator"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us= <70000>; + + /* WL_EN */ + gpio = <&gpio3 9 0>; + enable-active-high; + }; +}; + +&am33xx_pinmux { + user_leds_s0: user_leds_s0 { + pinctrl-single,pins = < + AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7) /* (V15) gpmc_a5.gpio1[21] - USR_LED_0 */ + AM33XX_IOPAD(0x858, PIN_OUTPUT | MUX_MODE7) /* (U15) gpmc_a6.gpio1[22] - USR_LED_1 */ + AM33XX_IOPAD(0x85c, PIN_OUTPUT | MUX_MODE7) /* (T15) gpmc_a7.gpio1[23] - USR_LED_2 */ + AM33XX_IOPAD(0x860, PIN_OUTPUT | MUX_MODE7) /* (V16) gpmc_a8.gpio1[24] - USR_LED_3 */ + AM33XX_IOPAD(0x9b0, PIN_OUTPUT | MUX_MODE7) /* (A15) xdma_event_intr0.gpio0[19] - WIFI_LED */ + AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE7) /* (R7) gpmc_advn_ale.gpio2[2] - P8.7, LED_RED, GP1_PIN_5 */ + AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE7) /* (T7) gpmc_oen_ren.gpio2[3] - P8.8, LED_GREEN, GP1_PIN_6 */ + AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE7) /* (U12) gpmc_ad11.gpio0[27] - P8.17, BATT_LED_1 */ + AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE7) /* (T5) lcd_data15.gpio0[11] - P8.32, BATT_LED_2 */ + AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE7) /* (V6) gpmc_csn0.gpio1[29] - P8.26, BATT_LED_3 */ + AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7) /* (T11) gpmc_ad10.gpio0[26] - P8.14, BATT_LED_4 */ + + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* (C17) I2C0_SDA.I2C0_SDA */ + AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* (C16) I2C0_SCL.I2C0_SCL */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3) /* (D18) uart1_ctsn.I2C2_SDA */ + AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3) /* (D17) uart1_rtsn.I2C2_SCL */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* (E15) uart0_rxd.uart0_rxd */ + AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* (E16) uart0_txd.uart0_txd */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* (C15) spi0_cs1.gpio0[6] */ + >; + }; + + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* (U9) gpmc_csn1.mmc1_clk */ + AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* (V9) gpmc_csn2.mmc1_cmd */ + AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* (U7) gpmc_ad0.mmc1_dat0 */ + AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* (V7) gpmc_ad1.mmc1_dat1 */ + AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* (R8) gpmc_ad2.mmc1_dat2 */ + AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* (T8) gpmc_ad3.mmc1_dat3 */ + AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* (U8) gpmc_ad4.mmc1_dat4 */ + AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* (V8) gpmc_ad5.mmc1_dat5 */ + AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* (R9) gpmc_ad6.mmc1_dat6 */ + AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* (T9) gpmc_ad7.mmc1_dat7 */ + >; + }; + + mmc3_pins: pinmux_mmc3_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE6) /* (L15) gmii1_rxd1.mmc2_clk */ + AM33XX_IOPAD(0x914, PIN_INPUT_PULLUP | MUX_MODE6) /* (J16) gmii1_txen.mmc2_cmd */ + AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE5) /* (J17) gmii1_rxdv.mmc2_dat0 */ + AM33XX_IOPAD(0x91c, PIN_INPUT_PULLUP | MUX_MODE5) /* (J18) gmii1_txd3.mmc2_dat1 */ + AM33XX_IOPAD(0x920, PIN_INPUT_PULLUP | MUX_MODE5) /* (K15) gmii1_txd2.mmc2_dat2 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLUP | MUX_MODE5) /* (H16) gmii1_col.mmc2_dat3 */ + >; + }; + + bt_pins: pinmux_bt_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLUP | MUX_MODE7) /* (K17) gmii1_txd0.gpio0[28] - BT_EN */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE1) /* (L17) gmii1_rxd3.uart3_rxd */ + AM33XX_IOPAD(0x938, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* (L16) gmii1_rxd2.uart3_txd */ + AM33XX_IOPAD(0x948, PIN_INPUT | MUX_MODE3) /* (M17) mdio_data.uart3_ctsn */ + AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* (M18) mdio_clk.uart3_rtsn */ + >; + }; + + wl18xx_pins: pinmux_wl18xx_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* (K18) gmii1_txclk.gpio3[9] - WL_EN */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7) /* (H18) rmii1_refclk.gpio0[29] - WL_IRQ */ + AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLUP | MUX_MODE7) /* (L18) gmii1_rxclk.gpio3[10] - LS_BUF_EN */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&usb_ctrl_mod { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "peripheral"; + interrupts-extended = <&intc 18 &tps 0>; + interrupt-names = "mc", "vbus"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&cppi41dma { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tps: tps@24 { + reg = <0x24>; + }; + + baseboard_eeprom: baseboard_eeprom@50 { + compatible = "at,24c256"; + reg = <0x50>; + + #address-cells = <1>; + #size-cells = <1>; + baseboard_data: baseboard_data@0 { + reg = <0 0x100>; + }; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + + status = "okay"; + clock-frequency = <400000>; + + mpu9250@68 { + compatible = "invensense,mpu9250"; + reg = <0x68>; + interrupt-parent = <&gpio3>; + interrupts = <21 GPIO_ACTIVE_LOW>; + i2c-gate { + #address-cells = <1>; + #size-cells = <0>; + ax8975@c { + compatible = "ak,ak8975"; + reg = <0x0c>; + }; + }; + }; + + pressure@76 { + compatible = "bosch,bmp280"; + reg = <0x76>; + }; +}; + +/include/ "tps65217.dtsi" + +&tps { + interrupts = <7>; /* NMI */ + interrupt-parent = <&intc>; + + charger { + interrupts = <0>, <1>; + interrupt-names = "USB", "AC"; + status = "okay"; + }; + + pwrbutton { + interrupts = <2>; + status = "okay"; + }; + + regulators { + dcdc1_reg: regulator@0 { + regulator-name = "vdds_dpr"; + regulator-always-on; + }; + + dcdc2_reg: regulator@1 { + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <1351500>; + regulator-boot-on; + regulator-always-on; + }; + + dcdc3_reg: regulator@2 { + /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: regulator@3 { + regulator-name = "vio,vrtc,vdds"; + regulator-always-on; + }; + + ldo2_reg: regulator@4 { + regulator-name = "vdd_3v3aux"; + regulator-always-on; + }; + + ldo3_reg: regulator@5 { + regulator-name = "vdd_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo4_reg: regulator@6 { + regulator-name = "vdd_3v3a"; + regulator-always-on; + }; + }; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; +}; + +&mmc2 { + status = "okay"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; +}; + +&mmc3 { + dmas = <&edma_xbar 12 0 1 + &edma_xbar 13 0 2>; + dma-names = "tx", "rx"; + status = "okay"; + vmmc-supply = <&wlan_en_reg>; + bus-width = <4>; + non-removable; + cap-power-off-card; + ti,needs-special-hs-handling; + keep-power-in-suspend; + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_pins &wl18xx_pins>; + + #address-cells = <1>; + #size-cells = <0>; + wlcore: wlcore@2 { + compatible = "ti,wl1835"; + reg = <2>; + interrupt-parent = <&gpio0>; + interrupts = <29 IRQ_TYPE_EDGE_RISING>; + }; +}; + +&tscadc { + status = "okay"; + adc { + ti,adc-channels = <0 1 2 3 4 5 6 7>; + }; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins &bt_pins>; + status = "okay"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; +}; + +&aes { + status = "okay"; +}; + +&sham { + status = "okay"; +}; + +&rtc { + system-power-controller; + clocks = <&clk_32768_ck>, <&clkdiv32k_ick>; + clock-names = "ext-clk", "int-clk"; +}; + +&gpio3 { + ls_buf_en { + gpio-hog; + gpios = <10 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "LS_BUF_EN"; + }; +}; diff --git a/sys/gnu/dts/arm/am335x-bonegreen-wireless.dts b/sys/gnu/dts/arm/am335x-bonegreen-wireless.dts index 9d1a0fd555f3..57731f0daf10 100644 --- a/sys/gnu/dts/arm/am335x-bonegreen-wireless.dts +++ b/sys/gnu/dts/arm/am335x-bonegreen-wireless.dts @@ -97,6 +97,11 @@ pinctrl-names = "default"; pinctrl-0 = <&uart3_pins &bt_pins>; status = "okay"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; + }; }; &gpio1 { diff --git a/sys/gnu/dts/arm/am335x-nano.dts b/sys/gnu/dts/arm/am335x-nano.dts index 807494bc722b..946d7069f417 100644 --- a/sys/gnu/dts/arm/am335x-nano.dts +++ b/sys/gnu/dts/arm/am335x-nano.dts @@ -224,7 +224,7 @@ }; eeprom@53 { - compatible = "microchip,24c02"; + compatible = "microchip,24c02", "atmel,24c02"; reg = <0x53>; pagesize = <8>; }; diff --git a/sys/gnu/dts/arm/am335x-pepper.dts b/sys/gnu/dts/arm/am335x-pepper.dts index 30e2f8770aaf..03c7d77023c6 100644 --- a/sys/gnu/dts/arm/am335x-pepper.dts +++ b/sys/gnu/dts/arm/am335x-pepper.dts @@ -67,7 +67,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am335x-phycore-som.dtsi b/sys/gnu/dts/arm/am335x-phycore-som.dtsi index 14533ff6d0ad..428a25e952b0 100644 --- a/sys/gnu/dts/arm/am335x-phycore-som.dtsi +++ b/sys/gnu/dts/arm/am335x-phycore-som.dtsi @@ -138,7 +138,7 @@ }; i2c_rtc: rtc@68 { - compatible = "rv4162"; + compatible = "microcrystal,rv4162"; reg = <0x68>; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/am335x-shc.dts b/sys/gnu/dts/arm/am335x-shc.dts index bf8727a19ece..4f6a286ea293 100644 --- a/sys/gnu/dts/arm/am335x-shc.dts +++ b/sys/gnu/dts/arm/am335x-shc.dts @@ -188,7 +188,7 @@ }; at24@50 { - compatible = "at24,24c32"; + compatible = "atmel,24c32"; pagesize = <32>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am335x-sl50.dts b/sys/gnu/dts/arm/am335x-sl50.dts index fc864a855991..1bcc60424ecd 100644 --- a/sys/gnu/dts/arm/am335x-sl50.dts +++ b/sys/gnu/dts/arm/am335x-sl50.dts @@ -305,7 +305,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am33xx.dtsi b/sys/gnu/dts/arm/am33xx.dtsi index 9e242943dcec..7d7ca054c557 100644 --- a/sys/gnu/dts/arm/am33xx.dtsi +++ b/sys/gnu/dts/arm/am33xx.dtsi @@ -64,64 +64,64 @@ * because the can not be enabled simultaneously on a * single SoC. */ - opp50@300000000 { + opp50-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <950000 931000 969000>; opp-supported-hw = <0x06 0x0010>; opp-suspend; }; - opp100@275000000 { + opp100-275000000 { opp-hz = /bits/ 64 <275000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0x00FF>; opp-suspend; }; - opp100@300000000 { + opp100-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0020>; opp-suspend; }; - opp100@500000000 { + opp100-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp100@600000000 { + opp100-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0040>; }; - opp120@600000000 { + opp120-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp120@720000000 { + opp120-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x06 0x0080>; }; - oppturbo@720000000 { + oppturbo-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x01 0xFFFF>; }; - oppturbo@800000000 { + oppturbo-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x06 0x0100>; }; - oppnitro@1000000000 { + oppnitro-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1325000 1298500 1351500>; opp-supported-hw = <0x04 0x0200>; @@ -431,7 +431,6 @@ &edma_xbar 25 0 0>; dma-names = "tx", "rx"; interrupts = <64>; - interrupt-parent = <&intc>; reg = <0x48060000 0x1000>; status = "disabled"; }; @@ -444,7 +443,6 @@ &edma 3 0>; dma-names = "tx", "rx"; interrupts = <28>; - interrupt-parent = <&intc>; reg = <0x481d8000 0x1000>; status = "disabled"; }; @@ -454,7 +452,6 @@ ti,hwmods = "mmc3"; ti,needs-special-reset; interrupts = <29>; - interrupt-parent = <&intc>; reg = <0x47810000 0x1000>; status = "disabled"; }; @@ -853,7 +850,6 @@ 0x4a101200 0x100>; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&intc>; /* * c0_rx_thresh_pend * c0_rx_pend @@ -908,7 +904,6 @@ lcdc: lcdc@4830e000 { compatible = "ti,am33xx-tilcdc"; reg = <0x4830e000 0x1000>; - interrupt-parent = <&intc>; interrupts = <36>; ti,hwmods = "lcdc"; status = "disabled"; @@ -917,7 +912,6 @@ tscadc: tscadc@44e0d000 { compatible = "ti,am3359-tscadc"; reg = <0x44e0d000 0x1000>; - interrupt-parent = <&intc>; interrupts = <16>; ti,hwmods = "adc_tsc"; status = "disabled"; diff --git a/sys/gnu/dts/arm/am4372.dtsi b/sys/gnu/dts/arm/am4372.dtsi index 176e09e9a45e..e5b061469bf8 100644 --- a/sys/gnu/dts/arm/am4372.dtsi +++ b/sys/gnu/dts/arm/am4372.dtsi @@ -59,32 +59,32 @@ compatible = "operating-points-v2-ti-cpu"; syscon = <&scm_conf>; - opp50@300000000 { + opp50-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <950000 931000 969000>; opp-supported-hw = <0xFF 0x01>; opp-suspend; }; - opp100@600000000 { + opp100-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0xFF 0x04>; }; - opp120@720000000 { + opp120-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0xFF 0x08>; }; - oppturbo@800000000 { + oppturbo-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0xFF 0x10>; }; - oppnitro@1000000000 { + oppnitro-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1325000 1298500 1351500>; opp-supported-hw = <0xFF 0x20>; diff --git a/sys/gnu/dts/arm/am437x-gp-evm.dts b/sys/gnu/dts/arm/am437x-gp-evm.dts index 397e98b7e246..29a538ecd405 100644 --- a/sys/gnu/dts/arm/am437x-gp-evm.dts +++ b/sys/gnu/dts/arm/am437x-gp-evm.dts @@ -549,8 +549,6 @@ dcdc3: regulator-dcdc3 { regulator-name = "vdcdc3"; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; regulator-boot-on; regulator-always-on; regulator-state-mem { diff --git a/sys/gnu/dts/arm/am437x-idk-evm.dts b/sys/gnu/dts/arm/am437x-idk-evm.dts index c1f7f9336e64..5e364473067f 100644 --- a/sys/gnu/dts/arm/am437x-idk-evm.dts +++ b/sys/gnu/dts/arm/am437x-idk-evm.dts @@ -339,7 +339,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am437x-sk-evm.dts b/sys/gnu/dts/arm/am437x-sk-evm.dts index 4dc54bee2f36..2c6bf0684f50 100644 --- a/sys/gnu/dts/arm/am437x-sk-evm.dts +++ b/sys/gnu/dts/arm/am437x-sk-evm.dts @@ -451,8 +451,6 @@ dcdc3: regulator-dcdc3 { regulator-name = "vdds_ddr"; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; regulator-boot-on; regulator-always-on; regulator-state-mem { @@ -511,7 +509,7 @@ }; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am43x-epos-evm.dts b/sys/gnu/dts/arm/am43x-epos-evm.dts index 9acd4ccdec4e..54f40f370011 100644 --- a/sys/gnu/dts/arm/am43x-epos-evm.dts +++ b/sys/gnu/dts/arm/am43x-epos-evm.dts @@ -442,8 +442,6 @@ dcdc3: regulator-dcdc3 { regulator-name = "vdcdc3"; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; regulator-boot-on; regulator-always-on; }; @@ -477,7 +475,7 @@ }; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/am43xx-clocks.dtsi b/sys/gnu/dts/arm/am43xx-clocks.dtsi index d1d73b725f47..430be5829f8f 100644 --- a/sys/gnu/dts/arm/am43xx-clocks.dtsi +++ b/sys/gnu/dts/arm/am43xx-clocks.dtsi @@ -833,4 +833,40 @@ ti,bit-shift = <23>; reg = <0x4100>; }; + + clkout2_src_mux_ck: clkout2_src_mux_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_rc32k_ck>, <&sysclk_div>, <&dpll_ddr_m2_ck>, + <&dpll_per_m2_ck>, <&dpll_disp_m2_ck>, + <&dpll_mpu_m2_ck>, <&dpll_extdev_ck>; + reg = <0x4108>; + }; + + clkout2_pre_div_ck: clkout2_pre_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout2_src_mux_ck>; + ti,bit-shift = <4>; + ti,max-div = <8>; + reg = <0x4108>; + }; + + clkout2_post_div_ck: clkout2_post_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout2_pre_div_ck>; + ti,bit-shift = <8>; + ti,max-div = <32>; + ti,index-power-of-two; + reg = <0x4108>; + }; + + clkout2_ck: clkout2_ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkout2_post_div_ck>; + ti,bit-shift = <16>; + reg = <0x4108>; + }; }; diff --git a/sys/gnu/dts/arm/am571x-idk.dts b/sys/gnu/dts/arm/am571x-idk.dts index ad68d1eb3bc3..7b207835b2d1 100644 --- a/sys/gnu/dts/arm/am571x-idk.dts +++ b/sys/gnu/dts/arm/am571x-idk.dts @@ -79,3 +79,20 @@ id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>; vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>; }; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; +}; diff --git a/sys/gnu/dts/arm/am572x-idk.dts b/sys/gnu/dts/arm/am572x-idk.dts index 8350b4b34b08..9da6d83ca185 100644 --- a/sys/gnu/dts/arm/am572x-idk.dts +++ b/sys/gnu/dts/arm/am572x-idk.dts @@ -91,3 +91,23 @@ &pcie1 { gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; }; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; + mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + status = "okay"; + }; +}; diff --git a/sys/gnu/dts/arm/am57xx-beagle-x15-common.dtsi b/sys/gnu/dts/arm/am57xx-beagle-x15-common.dtsi index 585d792a8fdd..fdfe5b16b806 100644 --- a/sys/gnu/dts/arm/am57xx-beagle-x15-common.dtsi +++ b/sys/gnu/dts/arm/am57xx-beagle-x15-common.dtsi @@ -388,7 +388,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c32"; + compatible = "atmel,24c32"; reg = <0x50>; }; }; diff --git a/sys/gnu/dts/arm/animeo_ip.dts b/sys/gnu/dts/arm/animeo_ip.dts index 9cc372b9fb9b..26ade8c0a960 100644 --- a/sys/gnu/dts/arm/animeo_ip.dts +++ b/sys/gnu/dts/arm/animeo_ip.dts @@ -83,25 +83,44 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - barebox@0 { - label = "barebox"; - reg = <0x0 0x58000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - u_boot_env@58000 { - label = "u_boot_env"; - reg = <0x58000 0x8000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - ubi@60000 { - label = "ubi"; - reg = <0x60000 0x1FA0000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + barebox@0 { + label = "barebox"; + reg = <0x0 0x58000>; + }; + + u_boot_env@58000 { + label = "u_boot_env"; + reg = <0x58000 0x8000>; + }; + + ubi@60000 { + label = "ubi"; + reg = <0x60000 0x1FA0000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/armada-370.dtsi b/sys/gnu/dts/arm/armada-370.dtsi index cc011c8bc36b..f9cf1273f35e 100644 --- a/sys/gnu/dts/arm/armada-370.dtsi +++ b/sys/gnu/dts/arm/armada-370.dtsi @@ -137,29 +137,38 @@ }; gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <2>; gpio-controller; diff --git a/sys/gnu/dts/arm/armada-385-linksys-caiman.dts b/sys/gnu/dts/arm/armada-385-linksys-caiman.dts index f3cee918d285..ee669ae61011 100644 --- a/sys/gnu/dts/arm/armada-385-linksys-caiman.dts +++ b/sys/gnu/dts/arm/armada-385-linksys-caiman.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1200AC"; compatible = "linksys,caiman", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "caiman:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "caiman:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "caiman:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "caiman:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "caiman:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "caiman:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "caiman:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "caiman:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "caiman:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; +&expander0 { + wan_amber@0 { + label = "caiman:amber:wan"; + reg = <0x0>; }; - gpio-leds { - power { - label = "caiman:white:power"; - }; + wan_white@1 { + label = "caiman:white:wan"; + reg = <0x1>; + }; - sata { - label = "caiman:white:sata"; - }; + wlan_2g@2 { + label = "caiman:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "caiman:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "caiman:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "caiman:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "caiman:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "caiman:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "caiman:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "caiman:white:power"; + }; + + sata { + label = "caiman:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; + + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/sys/gnu/dts/arm/armada-385-linksys-cobra.dts b/sys/gnu/dts/arm/armada-385-linksys-cobra.dts index 111071860559..5169ca89c55a 100644 --- a/sys/gnu/dts/arm/armada-385-linksys-cobra.dts +++ b/sys/gnu/dts/arm/armada-385-linksys-cobra.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1900ACv2"; compatible = "linksys,cobra", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "cobra:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "cobra:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "cobra:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "cobra:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "cobra:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "cobra:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "cobra:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "cobra:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "cobra:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; +&expander0 { + wan_amber@0 { + label = "cobra:amber:wan"; + reg = <0x0>; }; - gpio-leds { - power { - label = "cobra:white:power"; - }; + wan_white@1 { + label = "cobra:white:wan"; + reg = <0x1>; + }; - sata { - label = "cobra:white:sata"; - }; + wlan_2g@2 { + label = "cobra:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "cobra:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "cobra:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "cobra:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "cobra:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "cobra:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "cobra:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "cobra:white:power"; + }; + + sata { + label = "cobra:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; + + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/sys/gnu/dts/arm/armada-385-linksys-rango.dts b/sys/gnu/dts/arm/armada-385-linksys-rango.dts new file mode 100644 index 000000000000..da8a0f3d432b --- /dev/null +++ b/sys/gnu/dts/arm/armada-385-linksys-rango.dts @@ -0,0 +1,203 @@ +/* + * Device Tree file for the Linksys WRT3200ACM (Rango) + * + * Copyright (C) 2016 Imre Kaloz + * + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include +#include +#include "armada-385-linksys.dtsi" + +/ { + model = "Linksys WRT3200ACM"; + compatible = "linksys,rango", "linksys,armada385", "marvell,armada385", + "marvell,armada380"; +}; + +&expander0 { + wan_amber@0 { + label = "rango:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "rango:white:wan"; + reg = <0x1>; + }; + + usb2@5 { + label = "rango:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "rango:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "rango:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "rango:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "rango:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; + label = "rango:white:power"; + }; + + sata { + gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; + label = "rango:white:sata"; + }; + + wlan_2g { + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + label = "rango:white:wlan_2g"; + }; + + wlan_5g { + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + label = "rango:white:wlan_5g"; + }; +}; + +&gpio_leds_pins { + marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56"; +}; + +&nand { + /* AMD/Spansion S34ML02G2 256MiB, OEM Layout */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@200000 { + label = "u_env"; + reg = <0x200000 0x20000>; /* 128KiB */ + }; + + partition@220000 { + label = "s_env"; + reg = <0x220000 0x40000>; /* 256KiB */ + }; + + partition@7e0000 { + label = "devinfo"; + reg = <0x7e0000 0x40000>; /* 256KiB */ + read-only; + }; + + partition@820000 { + label = "sysdiag"; + reg = <0x820000 0x1e0000>; /* 1920KiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x5000000>; /* 80MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x4a00000>; /* 74MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@5a00000 { + label = "kernel2"; + reg = <0x5a00000 0x5000000>; /* 80MiB */ + }; + + partition@6000000 { + label = "rootfs2"; + reg = <0x6000000 0x4a00000>; /* 74MiB */ + }; + + /* + * 86MiB, last MiB is for the BBT, not writable + */ + partition@aa00000 { + label = "syscfg"; + reg = <0xaa00000 0x5600000>; + }; + + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x260000 0x5c0000>; /* 5.75MiB */ + }; +}; + +&sdhci { + pinctrl-names = "default"; + pinctrl-0 = <&sdhci_pins>; + no-1-8-v; + non-removable; + wp-inverted; + bus-width = <8>; + status = "okay"; +}; + +&usb3_1_vbus { + gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; +}; + +&usb3_1_vbus_pins { + marvell,pins = "mpp44"; +}; diff --git a/sys/gnu/dts/arm/armada-385-linksys-shelby.dts b/sys/gnu/dts/arm/armada-385-linksys-shelby.dts index c7a8ddd7f9a5..94aa35bc0bff 100644 --- a/sys/gnu/dts/arm/armada-385-linksys-shelby.dts +++ b/sys/gnu/dts/arm/armada-385-linksys-shelby.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1900ACS"; compatible = "linksys,shelby", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "shelby:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "shelby:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "shelby:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "shelby:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "shelby:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "shelby:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "shelby:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "shelby:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "shelby:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; +&expander0 { + wan_amber@0 { + label = "shelby:amber:wan"; + reg = <0x0>; }; - gpio-leds { - power { - label = "shelby:white:power"; - }; + wan_white@1 { + label = "shelby:white:wan"; + reg = <0x1>; + }; - sata { - label = "shelby:white:sata"; - }; + wlan_2g@2 { + label = "shelby:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "shelby:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "shelby:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "shelby:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "shelby:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "shelby:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "shelby:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "shelby:white:power"; + }; + + sata { + label = "shelby:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; + + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/sys/gnu/dts/arm/armada-385-linksys.dtsi b/sys/gnu/dts/arm/armada-385-linksys.dtsi index 2306c45685b1..e1f355ffc8f7 100644 --- a/sys/gnu/dts/arm/armada-385-linksys.dtsi +++ b/sys/gnu/dts/arm/armada-385-linksys.dtsi @@ -52,7 +52,7 @@ memory { device_type = "memory"; - reg = <0x00000000 0x20000000>; /* 512 MB */ + reg = <0x00000000 0x20000000>; /* 512 MiB */ }; soc { @@ -61,255 +61,45 @@ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - i2c@11000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; - - tmp421@4c { - compatible = "ti,tmp421"; - reg = <0x4c>; - }; - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nxp,pca9635"; - reg = <0x68>; - }; - }; - - /* J10: VCC, NC, RX, NC, TX, GND */ - serial@12000 { - status = "okay"; - }; - - ethernet@70000 { - status = "okay"; - phy-mode = "rgmii-id"; - buffer-manager = <&bm>; - bm,pool-long = <2>; - bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - ethernet@34000 { - status = "okay"; - phy-mode = "sgmii"; - buffer-manager = <&bm>; - bm,pool-long = <0>; - bm,pool-short = <1>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - mdio@72004 { - status = "okay"; - - switch@0 { - compatible = "marvell,mv88e6085"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - label = "lan4"; - }; - - port@1 { - reg = <1>; - label = "lan3"; - }; - - port@2 { - reg = <2>; - label = "lan2"; - }; - - port@3 { - reg = <3>; - label = "lan1"; - }; - - port@4 { - reg = <4>; - label = "wan"; - }; - - port@5 { - reg = <5>; - label = "cpu"; - ethernet = <ð2>; - - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - }; - }; - }; - - sata@a8000 { - status = "okay"; - }; - - bm@c8000 { - status = "okay"; - }; - - /* USB part of the eSATA/USB 2.0 port */ - usb@58000 { - status = "okay"; - }; - - usb3@f8000 { - status = "okay"; - usb-phy = <&usb3_phy>; - }; - - flash@d0000 { - status = "okay"; - num-cs = <1>; - marvell,nand-keep-config; - marvell,nand-enable-arbiter; - nand-on-flash-bbt; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x200000>; /* 2MB */ - read-only; - }; - - partition@100000 { - label = "u_env"; - reg = <0x200000 0x40000>; /* 256KB */ - }; - - partition@140000 { - label = "s_env"; - reg = <0x240000 0x40000>; /* 256KB */ - }; - - partition@900000 { - label = "devinfo"; - reg = <0x900000 0x100000>; /* 1MB */ - read-only; - }; - - /* kernel1 overlaps with rootfs1 by design */ - partition@a00000 { - label = "kernel1"; - reg = <0xa00000 0x2800000>; /* 40MB */ - }; - - partition@1000000 { - label = "rootfs1"; - reg = <0x1000000 0x2200000>; /* 34MB */ - }; - - /* kernel2 overlaps with rootfs2 by design */ - partition@3200000 { - label = "kernel2"; - reg = <0x3200000 0x2800000>; /* 40MB */ - }; - - partition@3800000 { - label = "rootfs2"; - reg = <0x3800000 0x2200000>; /* 34MB */ - }; - - /* - * 38MB, last MB is for the BBT, not writable - */ - partition@5a00000 { - label = "syscfg"; - reg = <0x5a00000 0x2600000>; - }; - - /* - * Unused area between "s_env" and "devinfo". - * Moved here because otherwise the renumbered - * partitions would break the bootloader - * supplied bootargs - */ - partition@180000 { - label = "unused_area"; - reg = <0x280000 0x680000>; /* 6.5MB */ - }; - }; - }; - - bm-bppi { - status = "okay"; - }; - - pcie-controller { - status = "okay"; - - pcie@1,0 { - /* Marvell 88W8864, 5GHz-only */ - status = "okay"; - }; - - pcie@2,0 { - /* Marvell 88W8864, 2GHz-only */ - status = "okay"; - }; - }; }; - usb3_phy: usb3_phy { + usb3_1_phy: usb3_1-phy { compatible = "usb-nop-xceiv"; - vcc-supply = <®_xhci0_vbus>; + vcc-supply = <&usb3_1_vbus>; }; - reg_xhci0_vbus: xhci0-vbus { + usb3_1_vbus: usb3_1-vbus { compatible = "regulator-fixed"; pinctrl-names = "default"; - pinctrl-0 = <&xhci0_vbus_pins>; - regulator-name = "xhci0-vbus"; + pinctrl-0 = <&usb3_1_vbus_pins>; + regulator-name = "usb3_1-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>; }; - gpio_keys { + gpio_keys: gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&keys_pin>; + pinctrl-0 = <&gpio_keys_pins>; pinctrl-names = "default"; - button@1 { + wps { label = "WPS"; linux,code = ; gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; }; - button@2 { + reset { label = "Factory Reset Button"; linux,code = ; gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; }; }; - gpio-leds { + gpio_leds: gpio-leds { compatible = "gpio-leds"; - pinctrl-0 = <&power_led_pin &sata_led_pin>; + pinctrl-0 = <&gpio_leds_pins>; pinctrl-names = "default"; power { @@ -323,21 +113,83 @@ linux,default-trigger = "disk-activity"; }; }; +}; - dsa@0 { - status = "disabled"; +&ahci0 { + status = "okay"; +}; - compatible = "marvell,dsa"; - #address-cells = <2>; +&bm { + status = "okay"; +}; + +&bm_bppi { + status = "okay"; +}; + +ð0 { + status = "okay"; + phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +ð2 { + status = "okay"; + phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; + + tmp421@4c { + compatible = "ti,tmp421"; + reg = <0x4c>; + }; + + expander0: pca9635@68 { + #address-cells = <1>; #size-cells = <0>; + compatible = "nxp,pca9635"; + reg = <0x68>; + }; +}; - dsa,ethernet = <ð2>; - dsa,mii-bus = <&mdio>; +&nand { + /* 128MiB or 256MiB */ + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; +}; - switch@0 { +&mdio { + status = "okay"; + + switch@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + ports { #address-cells = <1>; #size-cells = <0>; - reg = <0x0 0>; /* MDIO address 0, switch 0 in tree */ port@0 { reg = <0>; @@ -367,28 +219,45 @@ port@5 { reg = <5>; label = "cpu"; + ethernet = <ð2>; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; }; }; }; +&pciec { + status = "okay"; +}; + +&pcie1 { + /* Marvell 88W8864, 5GHz-only */ + status = "okay"; +}; + +&pcie2 { + /* Marvell 88W8864, 2GHz-only */ + status = "okay"; +}; + &pinctrl { - keys_pin: keys-pin { + gpio_keys_pins: gpio-keys-pins { + /* mpp24: wps, mpp29: reset */ marvell,pins = "mpp24", "mpp29"; marvell,function = "gpio"; }; - power_led_pin: power-led-pin { - marvell,pins = "mpp55"; + gpio_leds_pins: gpio-leds-pins { + /* mpp54: sata, mpp55: power */ + marvell,pins = "mpp54", "mpp55"; marvell,function = "gpio"; }; - sata_led_pin: sata-led-pin { - marvell,pins = "mpp54"; - marvell,function = "gpio"; - }; - - xhci0_vbus_pins: xhci0-vbus-pins { + usb3_1_vbus_pins: usb3_1-vbus-pins { marvell,pins = "mpp50"; marvell,function = "gpio"; }; @@ -397,3 +266,18 @@ &spi0 { status = "disabled"; }; + +&uart0 { + /* J10: VCC, NC, RX, NC, TX, GND */ + status = "okay"; +}; + +&usb0 { + /* USB part of the eSATA/USB 2.0 port */ + status = "okay"; +}; + +&usb3_1 { + status = "okay"; + usb-phy = <&usb3_1_phy>; +}; diff --git a/sys/gnu/dts/arm/armada-385-turris-omnia.dts b/sys/gnu/dts/arm/armada-385-turris-omnia.dts index 28eede180e4f..be16ce39fb3d 100644 --- a/sys/gnu/dts/arm/armada-385-turris-omnia.dts +++ b/sys/gnu/dts/arm/armada-385-turris-omnia.dts @@ -171,7 +171,7 @@ /* leds device (in STM32F0) at address 0x2b */ eeprom@54 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x54>; /* The EEPROM contains data for bootloader. diff --git a/sys/gnu/dts/arm/armada-388-gp.dts b/sys/gnu/dts/arm/armada-388-gp.dts index 895fa6cfa15a..563901e0ec07 100644 --- a/sys/gnu/dts/arm/armada-388-gp.dts +++ b/sys/gnu/dts/arm/armada-388-gp.dts @@ -75,7 +75,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pca0_pins>; interrupt-parent = <&gpio0>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -87,7 +87,7 @@ compatible = "nxp,pca9555"; pinctrl-names = "default"; interrupt-parent = <&gpio0>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; gpio-controller; #gpio-cells = <2>; interrupt-controller; diff --git a/sys/gnu/dts/arm/armada-38x.dtsi b/sys/gnu/dts/arm/armada-38x.dtsi index 8b165c31de1e..af31f5d6c0e5 100644 --- a/sys/gnu/dts/arm/armada-38x.dtsi +++ b/sys/gnu/dts/arm/armada-38x.dtsi @@ -312,31 +312,39 @@ }; gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = , , , ; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <28>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = , , , ; + clocks = <&coreclk 0>; }; systemc: system-controller@18200 { diff --git a/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi b/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi index 84cc232a29e9..be22ec5236ac 100644 --- a/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi +++ b/sys/gnu/dts/arm/armada-xp-98dx3236.dtsi @@ -311,6 +311,10 @@ reg = <0x20a00 0x2d0>, <0x21070 0x58>; }; +&rtc { + status = "disabled"; +}; + &timer { compatible = "marvell,armada-xp-timer"; clocks = <&coreclk 2>, <&refclk>; diff --git a/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi b/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi index 51de91b31a9d..bc9f824020eb 100644 --- a/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi +++ b/sys/gnu/dts/arm/armada-xp-98dx4251.dtsi @@ -87,4 +87,5 @@ &pp0 { compatible = "marvell,prestera-98dx4251"; + interrupts = <33>, <34>, <35>, <36>; }; diff --git a/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts b/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts index 9efcf59c9b44..6d705f518254 100644 --- a/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts +++ b/sys/gnu/dts/arm/armada-xp-linksys-mamba.dts @@ -308,13 +308,11 @@ }; }; - gpio_fan { + pwm_fan { /* SUNON HA4010V4-0000-C99 */ - compatible = "gpio-fan"; - gpios = <&gpio0 24 0>; - gpio-fan,speed-map = <0 0 - 4500 1>; + compatible = "pwm-fan"; + pwms = <&gpio0 24 4000>; }; dsa { diff --git a/sys/gnu/dts/arm/armada-xp-mv78230.dtsi b/sys/gnu/dts/arm/armada-xp-mv78230.dtsi index 07c5090ecd29..9f25814077f2 100644 --- a/sys/gnu/dts/arm/armada-xp-mv78230.dtsi +++ b/sys/gnu/dts/arm/armada-xp-mv78230.dtsi @@ -202,25 +202,33 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <17>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>; + clocks = <&coreclk 0>; }; }; }; diff --git a/sys/gnu/dts/arm/armada-xp-mv78260.dtsi b/sys/gnu/dts/arm/armada-xp-mv78260.dtsi index 64e936ae7b22..2bfe07aebf1a 100644 --- a/sys/gnu/dts/arm/armada-xp-mv78260.dtsi +++ b/sys/gnu/dts/arm/armada-xp-mv78260.dtsi @@ -285,29 +285,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/sys/gnu/dts/arm/armada-xp-mv78460.dtsi b/sys/gnu/dts/arm/armada-xp-mv78460.dtsi index d1383dde43eb..6c33935f7074 100644 --- a/sys/gnu/dts/arm/armada-xp-mv78460.dtsi +++ b/sys/gnu/dts/arm/armada-xp-mv78460.dtsi @@ -323,29 +323,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/sys/gnu/dts/arm/aspeed-g4.dtsi b/sys/gnu/dts/arm/aspeed-g4.dtsi index 8c6bc29eb7f6..8a04c7e2d818 100644 --- a/sys/gnu/dts/arm/aspeed-g4.dtsi +++ b/sys/gnu/dts/arm/aspeed-g4.dtsi @@ -886,13 +886,12 @@ }; timer: timer@1e782000 { + /* This timer is a Faraday FTTMR010 derivative */ compatible = "aspeed,ast2400-timer"; reg = <0x1e782000 0x90>; - // The moxart_timer driver registers only one - // interrupt and assumes it's for timer 1 - //interrupts = <16 17 18 35 36 37 38 39>; - interrupts = <16>; + interrupts = <16 17 18 35 36 37 38 39>; clocks = <&clk_apb>; + clock-names = "PCLK"; }; wdt1: wdt@1e785000 { diff --git a/sys/gnu/dts/arm/aspeed-g5.dtsi b/sys/gnu/dts/arm/aspeed-g5.dtsi index a0bea4a6ec77..9cffe347b828 100644 --- a/sys/gnu/dts/arm/aspeed-g5.dtsi +++ b/sys/gnu/dts/arm/aspeed-g5.dtsi @@ -993,13 +993,12 @@ }; timer: timer@1e782000 { + /* This timer is a Faraday FTTMR010 derivative */ compatible = "aspeed,ast2400-timer"; reg = <0x1e782000 0x90>; - // The moxart_timer driver registers only one - // interrupt and assumes it's for timer 1 - //interrupts = <16 17 18 35 36 37 38 39>; - interrupts = <16>; + interrupts = <16 17 18 35 36 37 38 39>; clocks = <&clk_apb>; + clock-names = "PCLK"; }; diff --git a/sys/gnu/dts/arm/at91-cosino.dtsi b/sys/gnu/dts/arm/at91-cosino.dtsi index 02d8ef43de3a..89cde175154e 100644 --- a/sys/gnu/dts/arm/at91-cosino.dtsi +++ b/sys/gnu/dts/arm/at91-cosino.dtsi @@ -82,38 +82,61 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; /* Enable PMECC */ - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_addr_nand + &pinctrl_ebi_data_0_7>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_oe_we + &pinctrl_nand_cs + &pinctrl_nand_rb>; + pinctrl-names = "default"; - uboot@40000 { - label = "u-boot"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; - ubootenv@c0000 { - label = "U-Boot Env"; - reg = <0xc0000 0x140000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + uboot@40000 { + label = "u-boot"; + reg = <0x40000 0x80000>; + }; + + ubootenv@c0000 { + label = "U-Boot Env"; + reg = <0xc0000 0x140000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-kizbox.dts b/sys/gnu/dts/arm/at91-kizbox.dts index b4f147c193fd..1f31df846d61 100644 --- a/sys/gnu/dts/arm/at91-kizbox.dts +++ b/sys/gnu/dts/arm/at91-kizbox.dts @@ -59,19 +59,39 @@ status = "okay"; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; + ebi: ebi@10000000 { status = "okay"; - bootstrap@0 { - label = "bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - ubi@20000 { - label = "ubi"; - reg = <0x20000 0x7fe0000>; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + bootstrap@0 { + label = "bootstrap"; + reg = <0x0 0x20000>; + }; + + ubi@20000 { + label = "ubi"; + reg = <0x20000 0x7fe0000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-kizbox2.dts b/sys/gnu/dts/arm/at91-kizbox2.dts index 50a14568f094..4372c0287c1c 100644 --- a/sys/gnu/dts/arm/at91-kizbox2.dts +++ b/sys/gnu/dts/arm/at91-kizbox2.dts @@ -141,23 +141,40 @@ status = "okay"; }; - nand0: nand@60000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; status = "okay"; - bootstrap@0 { - label = "bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; - ubi@20000 { - label = "ubi"; - reg = <0x20000 0x7fe0000>; + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + bootstrap@0 { + label = "bootstrap"; + reg = <0x0 0x20000>; + }; + + ubi@20000 { + label = "ubi"; + reg = <0x20000 0x7fe0000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-kizboxmini.dts b/sys/gnu/dts/arm/at91-kizboxmini.dts index 9682d105d4d8..33238fcb6d0b 100644 --- a/sys/gnu/dts/arm/at91-kizboxmini.dts +++ b/sys/gnu/dts/arm/at91-kizboxmini.dts @@ -68,6 +68,49 @@ status = "okay"; }; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_addr_nand + &pinctrl_ebi_data_0_7>; + pinctrl-names = "default"; + status = "okay"; + + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_oe_we + &pinctrl_nand_cs + &pinctrl_nand_rb>; + pinctrl-names = "default"; + + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + bootstrap@0 { + label = "bootstrap"; + reg = <0x0 0x20000>; + }; + + ubi@20000 { + label = "ubi"; + reg = <0x20000 0x7fe0000>; + }; + }; + }; + }; + }; + nand0: nand@40000000 { nand-bus-width = <8>; nand-ecc-mode = "hw"; @@ -77,15 +120,6 @@ nand-on-flash-bbt; status = "okay"; - bootstrap@0 { - label = "bootstrap"; - reg = <0x0 0x20000>; - }; - - ubi@20000 { - label = "ubi"; - reg = <0x20000 0x7fe0000>; - }; }; }; diff --git a/sys/gnu/dts/arm/at91-linea.dtsi b/sys/gnu/dts/arm/at91-linea.dtsi index 0721c8472509..87e5090fb4c4 100644 --- a/sys/gnu/dts/arm/at91-linea.dtsi +++ b/sys/gnu/dts/arm/at91-linea.dtsi @@ -31,19 +31,30 @@ status = "okay"; eeprom@51 { - compatible = "st,24c64"; + compatible = "st,24c64", "atmel,24c64"; reg = <0x51>; pagesize = <32>; }; }; -&nand0 { +&ebi { + pinctrl-0 = <&pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; + status = "okay"; +}; + + +&nand_controller { status = "okay"; - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + nand: nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; + }; }; diff --git a/sys/gnu/dts/arm/at91-qil_a9260.dts b/sys/gnu/dts/arm/at91-qil_a9260.dts index 8f019184fccf..f46352790a41 100644 --- a/sys/gnu/dts/arm/at91-qil_a9260.dts +++ b/sys/gnu/dts/arm/at91-qil_a9260.dts @@ -107,50 +107,69 @@ status = "okay"; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@a0000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@c0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4c0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7cc0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@a0000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@c0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4c0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7cc0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-sama5d2_xplained.dts b/sys/gnu/dts/arm/at91-sama5d2_xplained.dts index 0bef9e0b89c6..2e2c3d1a1fa2 100644 --- a/sys/gnu/dts/arm/at91-sama5d2_xplained.dts +++ b/sys/gnu/dts/arm/at91-sama5d2_xplained.dts @@ -56,10 +56,6 @@ stdout-path = "serial0:115200n8"; }; - memory { - reg = <0x20000000 0x80000>; - }; - clocks { slow_xtal { clock-frequency = <32768>; @@ -227,6 +223,10 @@ }; }; + pwm0: pwm@f802c000 { + status = "okay"; + }; + flx0: flexcom@f8034000 { atmel,flexcom-mode = ; status = "disabled"; /* conflict with ISC_D2 & ISC_D3 data pins */ @@ -258,6 +258,12 @@ status = "okay"; }; + can0: can@f8054000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; + status = "okay"; + }; + uart3: serial@fc008000 { atmel,use-dma-rx; atmel,use-dma-tx; @@ -322,6 +328,18 @@ bias-disable; }; + pinctrl_can0_default: can0_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_can1_default: can1_default { + pinmux = , + ; + bias-disable; + }; + pinctrl_charger_chglev: charger_chglev { pinmux = ; bias-disable; @@ -469,6 +487,12 @@ }; }; + + can1: can@fc050000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_default>; + status = "okay"; + }; }; }; diff --git a/sys/gnu/dts/arm/at91-sama5d3_xplained.dts b/sys/gnu/dts/arm/at91-sama5d3_xplained.dts index 5a53fcf542ab..3af088d2cba7 100644 --- a/sys/gnu/dts/arm/at91-sama5d3_xplained.dts +++ b/sys/gnu/dts/arm/at91-sama5d3_xplained.dts @@ -235,46 +235,6 @@ }; }; - nand0: nand@60000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; - status = "okay"; - - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; - - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; - - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; - - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; - - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; - - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; - }; - }; - usb0: gadget@00500000 { atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */ pinctrl-names = "default"; @@ -294,6 +254,63 @@ usb2: ehci@00700000 { status = "okay"; }; + + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; + status = "okay"; + + nand_controller: nand-controller { + status = "okay"; + + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; + }; + }; }; vcc_mmc0_reg: fixedregulator_mmc0 { diff --git a/sys/gnu/dts/arm/at91-sama5d4_ma5d4.dtsi b/sys/gnu/dts/arm/at91-sama5d4_ma5d4.dtsi index b5a5a91bc2ef..b813fdfa2842 100644 --- a/sys/gnu/dts/arm/at91-sama5d4_ma5d4.dtsi +++ b/sys/gnu/dts/arm/at91-sama5d4_ma5d4.dtsi @@ -75,7 +75,7 @@ reg = <0>; clocks = <&clk20m>; interrupt-parent = <&pioE>; - interrupts = <6 GPIO_ACTIVE_LOW>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; spi-max-frequency = <10000000>; }; @@ -84,7 +84,7 @@ reg = <1>; clocks = <&clk20m>; interrupt-parent = <&pioE>; - interrupts = <7 GPIO_ACTIVE_LOW>; + interrupts = <7 IRQ_TYPE_EDGE_RISING>; spi-max-frequency = <10000000>; }; }; diff --git a/sys/gnu/dts/arm/at91-sama5d4_xplained.dts b/sys/gnu/dts/arm/at91-sama5d4_xplained.dts index 5ab14cedb1db..cf712444b2c2 100644 --- a/sys/gnu/dts/arm/at91-sama5d4_xplained.dts +++ b/sys/gnu/dts/arm/at91-sama5d4_xplained.dts @@ -190,41 +190,60 @@ status = "okay"; }; - nand0: nand@80000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - nand-on-flash-bbt; - atmel,has-pmecc; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_cs3 &pinctrl_ebi_nrd_nandoe + &pinctrl_ebi_nwe_nandwe &pinctrl_ebi_nandrdy + &pinctrl_ebi_data_0_7 &pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + label = "atmel_nand"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-sama5d4ek.dts b/sys/gnu/dts/arm/at91-sama5d4ek.dts index f8b96cef5e1a..bae5248f126e 100644 --- a/sys/gnu/dts/arm/at91-sama5d4ek.dts +++ b/sys/gnu/dts/arm/at91-sama5d4ek.dts @@ -236,41 +236,60 @@ status = "okay"; }; - nand0: nand@80000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - nand-on-flash-bbt; - atmel,has-pmecc; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_cs3 &pinctrl_ebi_nrd_nandoe + &pinctrl_ebi_nwe_nandwe &pinctrl_ebi_nandrdy + &pinctrl_ebi_data_0_7 &pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + label = "atmel_nand"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/at91-tse850-3.dts b/sys/gnu/dts/arm/at91-tse850-3.dts index 498fba3e52b5..5f29010cdbd8 100644 --- a/sys/gnu/dts/arm/at91-tse850-3.dts +++ b/sys/gnu/dts/arm/at91-tse850-3.dts @@ -161,45 +161,51 @@ }; }; -&nand0 { - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; +&nand { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - barebox@40000 { - label = "bootloader"; - reg = <0x40000 0x60000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - bareboxenv@c0000 { - label = "bareboxenv"; - reg = <0xc0000 0x40000>; - }; + barebox@40000 { + label = "bootloader"; + reg = <0x40000 0x60000>; + }; - bareboxenv2@100000 { - label = "bareboxenv2"; - reg = <0x100000 0x40000>; - }; + bareboxenv@c0000 { + label = "bareboxenv"; + reg = <0xc0000 0x40000>; + }; - oftree@180000 { - label = "oftree"; - reg = <0x180000 0x20000>; - }; + bareboxenv2@100000 { + label = "bareboxenv2"; + reg = <0x100000 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x500000>; - }; + oftree@180000 { + label = "oftree"; + reg = <0x180000 0x20000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; - }; + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x500000>; + }; - ovlfs@10000000 { - label = "ovlfs"; - reg = <0x10000000 0x10000000>; + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + + ovlfs@10000000 { + label = "ovlfs"; + reg = <0x10000000 0x10000000>; + }; }; }; @@ -239,7 +245,7 @@ }; eeprom@50 { - compatible = "nxp,24c02"; + compatible = "nxp,24c02", "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; diff --git a/sys/gnu/dts/arm/at91sam9260.dtsi b/sys/gnu/dts/arm/at91sam9260.dtsi index 9e035b21e1b6..6582f3cca929 100644 --- a/sys/gnu/dts/arm/at91sam9260.dtsi +++ b/sys/gnu/dts/arm/at91sam9260.dtsi @@ -99,6 +99,16 @@ reg = <0xffffea00 0x200>; }; + smc: smc@ffffec00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffec00 0x200>; + }; + + matrix: matrix@ffffee00 { + compatible = "atmel,at91sam9260-matrix", "syscon"; + reg = <0xffffee00 0x200>; + }; + pmc: pmc@fffffc00 { compatible = "atmel,at91sam9260-pmc", "syscon"; reg = <0xfffffc00 0x100>; @@ -522,10 +532,14 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PC14 gpio enable pin pull_up */ + ; + }; + + pinctrl_nand_cs: nand-cs-0 { + atmel,pins = + ; }; }; @@ -985,24 +999,6 @@ }; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40000000 0x10000000 - 0xffffe800 0x200 - >; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioC 13 GPIO_ACTIVE_HIGH - &pioC 14 GPIO_ACTIVE_HIGH - 0 - >; - status = "disabled"; - }; - usb0: ohci@500000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x100000>; @@ -1011,6 +1007,33 @@ clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; + + ebi: ebi@10000000 { + compatible = "atmel,at91sam9260-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x80000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000 + 0x6 0x0 0x70000000 0x10000000 + 0x7 0x0 0x80000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9260-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; }; i2c-gpio-0 { diff --git a/sys/gnu/dts/arm/at91sam9261.dtsi b/sys/gnu/dts/arm/at91sam9261.dtsi index 7e80acda8f69..a05353f96151 100644 --- a/sys/gnu/dts/arm/at91sam9261.dtsi +++ b/sys/gnu/dts/arm/at91sam9261.dtsi @@ -91,20 +91,31 @@ status = "disabled"; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; + ebi: ebi@10000000 { + compatible = "atmel,at91sam9261-ebi"; + #address-cells = <2>; #size-cells = <1>; - reg = <0x40000000 0x10000000>; - atmel,nand-addr-offset = <22>; - atmel,nand-cmd-offset = <21>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - - gpios = <&pioC 15 GPIO_ACTIVE_HIGH>, - <&pioC 14 GPIO_ACTIVE_HIGH>, - <0>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x80000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000 + 0x6 0x0 0x70000000 0x10000000 + 0x7 0x0 0x80000000 0x10000000>; + clocks = <&mck>; status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9261-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; }; apb { @@ -262,6 +273,11 @@ reg = <0xffffea00 0x200>; }; + smc: smc@ffffec00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffec00 0x200>; + }; + matrix: matrix@ffffee00 { compatible = "atmel,at91sam9261-matrix", "syscon"; reg = <0xffffee00 0x200>; @@ -362,9 +378,13 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { + atmel,pins = + ; + }; + + pinctrl_nand_cs: nand-cs-0 { atmel,pins = - , ; }; }; diff --git a/sys/gnu/dts/arm/at91sam9261ek.dts b/sys/gnu/dts/arm/at91sam9261ek.dts index 55bd51f07fa6..157e1493e6eb 100644 --- a/sys/gnu/dts/arm/at91sam9261ek.dts +++ b/sys/gnu/dts/arm/at91sam9261ek.dts @@ -68,40 +68,59 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 15 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/at91sam9263.dtsi b/sys/gnu/dts/arm/at91sam9263.dtsi index a1888f6d892b..ed4b564f8de5 100644 --- a/sys/gnu/dts/arm/at91sam9263.dtsi +++ b/sys/gnu/dts/arm/at91sam9263.dtsi @@ -361,11 +361,26 @@ reg = <0xffffe200 0x200>; }; + smc0: smc@ffffe400 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffe400 0x200>; + }; + ramc1: ramc@ffffe800 { compatible = "atmel,at91sam9260-sdramc"; reg = <0xffffe800 0x200>; }; + smc1: smc@ffffea00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffea00 0x200>; + }; + + matrix: matrix@ffffec00 { + compatible = "atmel,at91sam9263-matrix", "syscon"; + reg = <0xffffec00 0x200>; + }; + pit: timer@fffffd30 { compatible = "atmel,at91sam9260-pit"; reg = <0xfffffd30 0xf>; @@ -472,10 +487,14 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PD15 gpio enable pin pull_up */ + ; + }; + + pinctrl_nand_cs: nand-cs-0 { + atmel,pins = + ; }; }; @@ -991,24 +1010,6 @@ status = "disabled"; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40000000 0x10000000 - 0xffffe000 0x200 - >; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioA 22 GPIO_ACTIVE_HIGH - &pioD 15 GPIO_ACTIVE_HIGH - 0 - >; - status = "disabled"; - }; - usb0: ohci@00a00000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00a00000 0x100000>; @@ -1017,6 +1018,52 @@ clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; + + ebi0: ebi@10000000 { + compatible = "atmel,at91sam9263-ebi0"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc0>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x80000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller0: nand-controller { + compatible = "atmel,at91sam9260-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; + + ebi1: ebi@70000000 { + compatible = "atmel,at91sam9263-ebi1"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc1>; + atmel,matrix = <&matrix>; + reg = <0x80000000 0x20000000>; + ranges = <0x0 0x0 0x80000000 0x10000000 + 0x1 0x0 0x90000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller1: nand-controller { + compatible = "atmel,at91sam9260-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; }; i2c-gpio-0 { diff --git a/sys/gnu/dts/arm/at91sam9263ek.dts b/sys/gnu/dts/arm/at91sam9263ek.dts index 127cc42e9e29..10a0925da10e 100644 --- a/sys/gnu/dts/arm/at91sam9263ek.dts +++ b/sys/gnu/dts/arm/at91sam9263ek.dts @@ -125,50 +125,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt = <1>; + ebi0: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/at91sam9g20ek_common.dtsi b/sys/gnu/dts/arm/at91sam9g20ek_common.dtsi index 27847a47c108..ac9a1511e239 100644 --- a/sys/gnu/dts/arm/at91sam9g20ek_common.dtsi +++ b/sys/gnu/dts/arm/at91sam9g20ek_common.dtsi @@ -123,50 +123,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/at91sam9g45.dtsi b/sys/gnu/dts/arm/at91sam9g45.dtsi index e567d5fd3f9d..a4808c4fbc05 100644 --- a/sys/gnu/dts/arm/at91sam9g45.dtsi +++ b/sys/gnu/dts/arm/at91sam9g45.dtsi @@ -113,6 +113,16 @@ clock-names = "ddrck"; }; + smc: smc@ffffe800 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffe800 0x200>; + }; + + matrix: matrix@ffffea00 { + compatible = "atmel,at91sam9g45-matrix", "syscon"; + reg = <0xffffea00 0x200>; + }; + pmc: pmc@fffffc00 { compatible = "atmel,at91sam9g45-pmc", "syscon"; reg = <0xfffffc00 0x100>; @@ -601,10 +611,14 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PC14 gpio enable pin pull_up */ + ; + }; + + pinctrl_nand_cs: nand-cs-0 { + atmel,pins = + ; }; }; @@ -1278,25 +1292,6 @@ status = "disabled"; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40000000 0x10000000 - 0xffffe200 0x200 - >; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioC 8 GPIO_ACTIVE_HIGH - &pioC 14 GPIO_ACTIVE_HIGH - 0 - >; - status = "disabled"; - }; - usb0: ohci@00700000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00700000 0x100000>; @@ -1314,6 +1309,31 @@ clock-names = "usb_clk", "ehci_clk"; status = "disabled"; }; + + ebi: ebi@10000000 { + compatible = "atmel,at91sam9g45-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x80000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9g45-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; }; i2c-gpio-0 { diff --git a/sys/gnu/dts/arm/at91sam9m10g45ek.dts b/sys/gnu/dts/arm/at91sam9m10g45ek.dts index 2400c99134f7..2522c3308305 100644 --- a/sys/gnu/dts/arm/at91sam9m10g45ek.dts +++ b/sys/gnu/dts/arm/at91sam9m10g45ek.dts @@ -245,25 +245,44 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - boot@0 { - label = "bootstrap/uboot/kernel"; - reg = <0x0 0x400000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - rootfs@400000 { - label = "rootfs"; - reg = <0x400000 0x3C00000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 8 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - data@4000000 { - label = "data"; - reg = <0x4000000 0xC000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot@0 { + label = "bootstrap/uboot/kernel"; + reg = <0x0 0x400000>; + }; + + rootfs@400000 { + label = "rootfs"; + reg = <0x400000 0x3C00000>; + }; + + data@4000000 { + label = "data"; + reg = <0x4000000 0xC000000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/at91sam9n12.dtsi b/sys/gnu/dts/arm/at91sam9n12.dtsi index f43d7695352d..06516d02d351 100644 --- a/sys/gnu/dts/arm/at91sam9n12.dtsi +++ b/sys/gnu/dts/arm/at91sam9n12.dtsi @@ -89,6 +89,17 @@ atmel,external-irqs = <31>; }; + matrix: matrix@ffffde00 { + compatible = "atmel,at91sam9n12-matrix", "syscon"; + reg = <0xffffde00 0x100>; + }; + + pmecc: ecc-engine@ffffe000 { + compatible = "atmel,at91sam9g45-pmecc"; + reg = <0xffffe000 0x600>, + <0xffffe600 0x200>; + }; + ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; @@ -96,6 +107,11 @@ clock-names = "ddrck"; }; + smc: smc@ffffea00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffea00 0x200>; + }; + pmc: pmc@fffffc00 { compatible = "atmel,at91sam9n12-pmc", "syscon"; reg = <0xfffffc00 0x200>; @@ -627,10 +643,14 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PD4 gpio enable pin pull_up */ + ; + }; + + pinctrl_nand_cs: nand-cs-0 { + atmel,pins = + ; }; }; @@ -998,28 +1018,6 @@ }; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = < 0x40000000 0x10000000 - 0xffffe000 0x00000600 - 0xffffe600 0x00000200 - 0x00108000 0x00018000 - >; - atmel,pmecc-lookup-table-offset = <0x0 0x8000>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioD 5 GPIO_ACTIVE_HIGH - &pioD 4 GPIO_ACTIVE_HIGH - 0 - >; - status = "disabled"; - }; - usb0: ohci@00500000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00500000 0x00100000>; @@ -1028,6 +1026,32 @@ clock-names = "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; + + ebi: ebi@10000000 { + compatible = "atmel,at91sam9x5-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x60000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9g45-nand-controller"; + ecc-engine = <&pmecc>; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; }; i2c-gpio-0 { diff --git a/sys/gnu/dts/arm/at91sam9n12ek.dts b/sys/gnu/dts/arm/at91sam9n12ek.dts index 626c67d66626..5bea8c59b115 100644 --- a/sys/gnu/dts/arm/at91sam9n12ek.dts +++ b/sys/gnu/dts/arm/at91sam9n12ek.dts @@ -147,14 +147,26 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <2>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; + + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; + + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-ecc-strength = <2>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; + }; + }; }; usb0: ohci@00500000 { diff --git a/sys/gnu/dts/arm/at91sam9rl.dtsi b/sys/gnu/dts/arm/at91sam9rl.dtsi index f4c129a98f17..7768342a6638 100644 --- a/sys/gnu/dts/arm/at91sam9rl.dtsi +++ b/sys/gnu/dts/arm/at91sam9rl.dtsi @@ -92,21 +92,29 @@ status = "disabled"; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; + ebi: ebi@10000000 { + compatible = "atmel,at91sam9rl-ebi"; + #address-cells = <2>; #size-cells = <1>; - reg = <0x40000000 0x10000000>, - <0xffffe800 0x200>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioD 17 GPIO_ACTIVE_HIGH>, - <&pioB 6 GPIO_ACTIVE_HIGH>, - <0>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x80000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000>; + clocks = <&mck>; status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9g45-nand-controller"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; }; apb { @@ -364,6 +372,16 @@ reg = <0xffffea00 0x200>; }; + smc: smc@ffffec00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffec00 0x200>; + }; + + matrix: matrix@ffffee00 { + compatible = "atmel,at91sam9rl-matrix", "syscon"; + reg = <0xffffee00 0x200>; + }; + aic: interrupt-controller@fffff000 { #interrupt-cells = <3>; compatible = "atmel,at91rm9200-aic"; @@ -443,6 +461,14 @@ }; }; + ebi { + pinctrl_ebi_addr_nand: ebi-addr-0 { + atmel,pins = + , + ; + }; + }; + fb { pinctrl_fb: fb-0 { atmel,pins = @@ -507,28 +533,21 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_rb: nand-rb-0 { + atmel,pins = + ; + }; + + pinctrl_nand_cs: nand-cs-0 { atmel,pins = - , ; }; - pinctrl_nand0_ale_cle: nand_ale_cle-0 { - atmel,pins = - , - ; - }; - - pinctrl_nand0_oe_we: nand_oe_we-0 { + pinctrl_nand_oe_we: nand-oe-we-0 { atmel,pins = , ; }; - - pinctrl_nand0_cs: nand_cs-0 { - atmel,pins = - ; - }; }; pwm0 { diff --git a/sys/gnu/dts/arm/at91sam9rlek.dts b/sys/gnu/dts/arm/at91sam9rlek.dts index 2e567d90fba8..9047c168298a 100644 --- a/sys/gnu/dts/arm/at91sam9rlek.dts +++ b/sys/gnu/dts/arm/at91sam9rlek.dts @@ -63,40 +63,63 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt = <1>; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_addr_nand>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_oe_we + &pinctrl_nand_cs + &pinctrl_nand_rb>; + pinctrl-names = "default"; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 17 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioB 6 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/at91sam9x5.dtsi b/sys/gnu/dts/arm/at91sam9x5.dtsi index f66bae925705..57f307541d2e 100644 --- a/sys/gnu/dts/arm/at91sam9x5.dtsi +++ b/sys/gnu/dts/arm/at91sam9x5.dtsi @@ -97,6 +97,17 @@ atmel,external-irqs = <31>; }; + matrix: matrix@ffffde00 { + compatible = "atmel,at91sam9x5-matrix", "syscon"; + reg = <0xffffde00 0x100>; + }; + + pmecc: ecc-engine@ffffe000 { + compatible = "atmel,at91sam9g45-pmecc"; + reg = <0xffffe000 0x600>, + <0xffffe600 0x200>; + }; + ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; @@ -104,6 +115,11 @@ clock-names = "ddrck"; }; + smc: smc@ffffea00 { + compatible = "atmel,at91sam9260-smc", "syscon"; + reg = <0xffffea00 0x200>; + }; + pmc: pmc@fffffc00 { compatible = "atmel,at91sam9x5-pmc", "syscon"; reg = <0xfffffc00 0x200>; @@ -465,6 +481,38 @@ }; }; + ebi { + pinctrl_ebi_data_0_7: ebi-data-lsb-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_data_8_15: ebi-data-msb-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_addr_nand: ebi-addr-0 { + atmel,pins = + ; + }; + }; + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @@ -551,34 +599,20 @@ }; nand { - pinctrl_nand: nand-0 { + pinctrl_nand_oe_we: nand-oe-we-0 { atmel,pins = - ; /* PD13 periph A Data bit 7 */ + ; }; - pinctrl_nand_16bits: nand_16bits-0 { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PD21 periph A Data bit 15 */ + ; + }; + + pinctrl_nand_cs: nand-cs-0 { + atmel,pins = + ; }; }; @@ -1197,28 +1231,6 @@ }; }; - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40000000 0x10000000 - 0xffffe000 0x600 /* PMECC Registers */ - 0xffffe600 0x200 /* PMECC Error Location Registers */ - 0x00108000 0x18000 /* PMECC looup table in ROM code */ - >; - atmel,pmecc-lookup-table-offset = <0x0 0x8000>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - gpios = <&pioD 5 GPIO_ACTIVE_HIGH - &pioD 4 GPIO_ACTIVE_HIGH - 0 - >; - status = "disabled"; - }; - usb0: ohci@00600000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; @@ -1236,6 +1248,32 @@ clock-names = "usb_clk", "ehci_clk"; status = "disabled"; }; + + ebi: ebi@10000000 { + compatible = "atmel,at91sam9x5-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&smc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x60000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x20000000 0x10000000 + 0x2 0x0 0x30000000 0x10000000 + 0x3 0x0 0x40000000 0x10000000 + 0x4 0x0 0x50000000 0x10000000 + 0x5 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,at91sam9g45-nand-controller"; + ecc-engine = <&pmecc>; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; }; i2c-gpio-0 { diff --git a/sys/gnu/dts/arm/at91sam9x5cm.dtsi b/sys/gnu/dts/arm/at91sam9x5cm.dtsi index b098ad8cd93a..bdeaa0b64a5b 100644 --- a/sys/gnu/dts/arm/at91sam9x5cm.dtsi +++ b/sys/gnu/dts/arm/at91sam9x5cm.dtsi @@ -37,38 +37,61 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; /* Enable PMECC */ - atmel,pmecc-cap = <2>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_addr_nand + &pinctrl_ebi_data_0_7>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_oe_we + &pinctrl_nand_cs + &pinctrl_nand_rb>; + pinctrl-names = "default"; - uboot@40000 { - label = "u-boot"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <2>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; - ubootenv@c0000 { - label = "U-Boot Env"; - reg = <0xc0000 0x140000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x1f800000>; + uboot@40000 { + label = "u-boot"; + reg = <0x40000 0x80000>; + }; + + ubootenv@c0000 { + label = "U-Boot Env"; + reg = <0xc0000 0x140000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x1f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/axp209.dtsi b/sys/gnu/dts/arm/axp209.dtsi index 9677dd5cf6b6..3c8fa26e87b7 100644 --- a/sys/gnu/dts/arm/axp209.dtsi +++ b/sys/gnu/dts/arm/axp209.dtsi @@ -64,6 +64,11 @@ #gpio-cells = <2>; }; + battery_power_supply: battery-power-supply { + compatible = "x-powers,axp209-battery-power-supply"; + status = "disabled"; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <1500>; diff --git a/sys/gnu/dts/arm/axp22x.dtsi b/sys/gnu/dts/arm/axp22x.dtsi index 67331c5f1714..87fb08e812ec 100644 --- a/sys/gnu/dts/arm/axp22x.dtsi +++ b/sys/gnu/dts/arm/axp22x.dtsi @@ -57,6 +57,11 @@ status = "disabled"; }; + battery_power_supply: battery-power-supply { + compatible = "x-powers,axp221-battery-power-supply"; + status = "disabled"; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <3000>; diff --git a/sys/gnu/dts/arm/bcm-cygnus.dtsi b/sys/gnu/dts/arm/bcm-cygnus.dtsi index 9644fddb5e3c..bf8c83815753 100644 --- a/sys/gnu/dts/arm/bcm-cygnus.dtsi +++ b/sys/gnu/dts/arm/bcm-cygnus.dtsi @@ -142,6 +142,55 @@ interrupts = <0>; }; + mdio: mdio@18002000 { + compatible = "brcm,iproc-mdio"; + reg = <0x18002000 0x8>; + #size-cells = <1>; + #address-cells = <0>; + status = "disabled"; + + gphy0: ethernet-phy@0 { + reg = <0>; + }; + + gphy1: ethernet-phy@1 { + reg = <1>; + }; + }; + + switch: switch@18007000 { + compatible = "brcm,bcm11360-srab", "brcm,cygnus-srab"; + reg = <0x18007000 0x1000>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + phy-handle = <&gphy0>; + phy-mode = "rgmii"; + }; + + port@1 { + reg = <1>; + phy-handle = <&gphy1>; + phy-mode = "rgmii"; + }; + + port@8 { + reg = <8>; + label = "cpu"; + ethernet = <ð0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + i2c0: i2c@18008000 { compatible = "brcm,cygnus-iproc-i2c", "brcm,iproc-i2c"; reg = <0x18008000 0x100>; @@ -295,6 +344,15 @@ status = "disabled"; }; + eth0: ethernet@18042000 { + compatible = "brcm,amac"; + reg = <0x18042000 0x1000>, + <0x18110000 0x1000>; + reg-names = "amac_base", "idm_base"; + interrupts = ; + status = "disabled"; + }; + nand: nand@18046000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x18046000 0x600>, <0xf8105408 0x600>, @@ -386,6 +444,19 @@ status = "disabled"; }; + v3d: v3d@180a2000 { + compatible = "brcm,cygnus-v3d"; + reg = <0x180a2000 0x1000>; + clocks = <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; + clock-names = "v3d_clk"; + interrupts = ; + status = "disabled"; + }; + + vc4: gpu { + compatible = "brcm,cygnus-vc4"; + }; + adc: adc@180a6000 { compatible = "brcm,iproc-static-adc"; #io-channel-cells = <1>; diff --git a/sys/gnu/dts/arm/bcm-nsp.dtsi b/sys/gnu/dts/arm/bcm-nsp.dtsi index fe6cba994a97..7204d1def23d 100644 --- a/sys/gnu/dts/arm/bcm-nsp.dtsi +++ b/sys/gnu/dts/arm/bcm-nsp.dtsi @@ -413,6 +413,12 @@ <0x3f408 0x04>; }; + thermal: thermal@3f2c0 { + compatible = "brcm,ns-thermal"; + reg = <0x3f2c0 0x10>; + #thermal-sensor-cells = <0>; + }; + sata_phy: sata_phy@40100 { compatible = "brcm,iproc-nsp-sata-phy"; reg = <0x40100 0x340>; @@ -563,4 +569,24 @@ brcm,pcie-msi-inten; }; }; + + thermal-zones { + cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + coefficients = <(-556) 418000>; + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; }; diff --git a/sys/gnu/dts/arm/bcm2835-rpi-zero.dts b/sys/gnu/dts/arm/bcm2835-rpi-zero.dts index cc8b832c4c78..79a20d520931 100644 --- a/sys/gnu/dts/arm/bcm2835-rpi-zero.dts +++ b/sys/gnu/dts/arm/bcm2835-rpi-zero.dts @@ -12,7 +12,7 @@ /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" -#include "bcm283x-rpi-usb-host.dtsi" +#include "bcm283x-rpi-usb-otg.dtsi" / { compatible = "raspberrypi,model-zero", "brcm,bcm2835"; diff --git a/sys/gnu/dts/arm/bcm2835-rpi.dtsi b/sys/gnu/dts/arm/bcm2835-rpi.dtsi index a7b5ce133784..e55b362b9d6e 100644 --- a/sys/gnu/dts/arm/bcm2835-rpi.dtsi +++ b/sys/gnu/dts/arm/bcm2835-rpi.dtsi @@ -65,13 +65,13 @@ &sdhci { pinctrl-names = "default"; pinctrl-0 = <&emmc_gpio48>; - status = "okay"; bus-width = <4>; }; &sdhost { pinctrl-names = "default"; pinctrl-0 = <&sdhost_gpio48>; + status = "okay"; bus-width = <4>; }; diff --git a/sys/gnu/dts/arm/bcm2835.dtsi b/sys/gnu/dts/arm/bcm2835.dtsi index 0890d97e674d..659b6e9513b1 100644 --- a/sys/gnu/dts/arm/bcm2835.dtsi +++ b/sys/gnu/dts/arm/bcm2835.dtsi @@ -24,6 +24,10 @@ }; }; +&cpu_thermal { + coefficients = <(-538) 407000>; +}; + /* enable thermal sensor with the correct compatible property set */ &thermal { compatible = "brcm,bcm2835-thermal"; diff --git a/sys/gnu/dts/arm/bcm2836.dtsi b/sys/gnu/dts/arm/bcm2836.dtsi index 519a44f5d25a..da3deeb42592 100644 --- a/sys/gnu/dts/arm/bcm2836.dtsi +++ b/sys/gnu/dts/arm/bcm2836.dtsi @@ -77,6 +77,10 @@ interrupts = <8>; }; +&cpu_thermal { + coefficients = <(-538) 407000>; +}; + /* enable thermal sensor with the correct compatible property set */ &thermal { compatible = "brcm,bcm2836-thermal"; diff --git a/sys/gnu/dts/arm/bcm2837-rpi-3-b.dts b/sys/gnu/dts/arm/bcm2837-rpi-3-b.dts new file mode 100644 index 000000000000..c72a27d908b6 --- /dev/null +++ b/sys/gnu/dts/arm/bcm2837-rpi-3-b.dts @@ -0,0 +1 @@ +#include "arm64/broadcom/bcm2837-rpi-3-b.dts" diff --git a/sys/gnu/dts/arm/bcm283x-rpi-usb-otg.dtsi b/sys/gnu/dts/arm/bcm283x-rpi-usb-otg.dtsi new file mode 100644 index 000000000000..e7d217c967a1 --- /dev/null +++ b/sys/gnu/dts/arm/bcm283x-rpi-usb-otg.dtsi @@ -0,0 +1,10 @@ +&usb { + dr_mode = "otg"; + g-rx-fifo-size = <256>; + g-np-tx-fifo-size = <32>; + /* + * According to dwc2 the sum of all device EP + * fifo sizes shouldn't exceed 3776 bytes. + */ + g-tx-fifo-size = <256 256 512 512 512 768 768>; +}; diff --git a/sys/gnu/dts/arm/bcm283x.dtsi b/sys/gnu/dts/arm/bcm283x.dtsi index 9444a9a9ba10..431dcfc900c0 100644 --- a/sys/gnu/dts/arm/bcm283x.dtsi +++ b/sys/gnu/dts/arm/bcm283x.dtsi @@ -24,6 +24,26 @@ bootargs = "earlyprintk console=ttyAMA0"; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <80000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; @@ -435,6 +455,7 @@ compatible = "brcm,bcm2835-thermal"; reg = <0x7e212000 0x8>; clocks = <&clocks BCM2835_CLOCK_TSENS>; + #thermal-sensor-cells = <0>; status = "disabled"; }; @@ -573,6 +594,8 @@ #size-cells = <0>; clocks = <&clk_usb>; clock-names = "otg"; + phys = <&usbphy>; + phy-names = "usb2-phy"; }; v3d: v3d@7ec00000 { @@ -608,4 +631,8 @@ clock-frequency = <480000000>; }; }; + + usbphy: phy { + compatible = "usb-nop-xceiv"; + }; }; diff --git a/sys/gnu/dts/arm/bcm5301x.dtsi b/sys/gnu/dts/arm/bcm5301x.dtsi index acee36a61004..98647d22b291 100644 --- a/sys/gnu/dts/arm/bcm5301x.dtsi +++ b/sys/gnu/dts/arm/bcm5301x.dtsi @@ -320,6 +320,14 @@ }; }; + mdio: mdio@18003000 { + compatible = "brcm,iproc-mdio"; + reg = <0x18003000 0x8>; + #size-cells = <1>; + #address-cells = <0>; + status = "disabled"; + }; + i2c0: i2c@18009000 { compatible = "brcm,iproc-i2c"; reg = <0x18009000 0x50>; @@ -349,6 +357,12 @@ "sata2"; }; + thermal: thermal@1800c2c0 { + compatible = "brcm,ns-thermal"; + reg = <0x1800c2c0 0x10>; + #thermal-sensor-cells = <0>; + }; + srab: srab@18007000 { compatible = "brcm,bcm5301x-srab"; reg = <0x18007000 0x1000>; @@ -412,4 +426,24 @@ status = "disabled"; }; }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + coefficients = <(-556) 418000>; + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; }; diff --git a/sys/gnu/dts/arm/bcm911360_entphn.dts b/sys/gnu/dts/arm/bcm911360_entphn.dts index 8b3800f46288..000f5f19215e 100644 --- a/sys/gnu/dts/arm/bcm911360_entphn.dts +++ b/sys/gnu/dts/arm/bcm911360_entphn.dts @@ -57,6 +57,26 @@ }; }; +ð0 { + status = "okay"; +}; + +&mdio { + status = "okay"; +}; + +&switch { + status = "okay"; +}; + +&v3d { + assigned-clocks = + <&mipipll BCM_CYGNUS_MIPIPLL>, + <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; + assigned-clock-rates = <525000000>, <300000000>; + status = "okay"; +}; + &uart3 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/da850-evm.dts b/sys/gnu/dts/arm/da850-evm.dts index 8d244cd76c36..67e72bc72e80 100644 --- a/sys/gnu/dts/arm/da850-evm.dts +++ b/sys/gnu/dts/arm/da850-evm.dts @@ -82,6 +82,8 @@ tca6416: gpio@20 { compatible = "ti,tca6416"; reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; }; }; wdt: wdt@21000 { @@ -299,25 +301,4 @@ pinctrl-names = "default"; pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>; status = "okay"; - - /* VPIF capture port */ - port@0 { - vpif_input_ch0: endpoint@0 { - reg = <0>; - bus-width = <8>; - }; - - vpif_input_ch1: endpoint@1 { - reg = <1>; - bus-width = <8>; - data-shift = <8>; - }; - }; - - /* VPIF display port */ - port@1 { - vpif_output_ch0: endpoint { - bus-width = <8>; - }; - }; }; diff --git a/sys/gnu/dts/arm/da850-lcdk.dts b/sys/gnu/dts/arm/da850-lcdk.dts index b837fec70eec..a0f0916156e6 100644 --- a/sys/gnu/dts/arm/da850-lcdk.dts +++ b/sys/gnu/dts/arm/da850-lcdk.dts @@ -318,11 +318,4 @@ pinctrl-names = "default"; pinctrl-0 = <&vpif_capture_pins>; status = "okay"; - - /* VPIF capture port */ - port { - vpif_ch0: endpoint { - bus-width = <8>; - }; - }; }; diff --git a/sys/gnu/dts/arm/da850-lego-ev3.dts b/sys/gnu/dts/arm/da850-lego-ev3.dts index 512604ad8b71..45983c04a8a7 100644 --- a/sys/gnu/dts/arm/da850-lego-ev3.dts +++ b/sys/gnu/dts/arm/da850-lego-ev3.dts @@ -172,6 +172,18 @@ gpio = <&gpio 111 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + /* + * The EV3 can use 6-AA batteries or a rechargeable Li-ion battery pack. + */ + battery { + pinctrl-names = "default"; + pintctrl-0 = <&battery_pins>; + compatible = "lego,ev3-battery"; + io-channels = <&adc 4>, <&adc 3>; + io-channel-names = "voltage", "current"; + rechargeable-gpios = <&gpio 136 GPIO_ACTIVE_LOW>; + }; }; &pmx_core { @@ -228,6 +240,15 @@ 0x34 0x00000008 0x0000000f >; }; + + battery_pins: pinmux_battery_pins { + pinctrl-single,bits = < + /* GP0[6] */ + 0x04 0x00000080 0x000000f0 + /* GP8[8] */ + 0x4c 0x00000080 0x000000f0 + >; + }; }; &pinconf { @@ -342,6 +363,13 @@ &gpio { status = "okay"; + + /* Don't pull down battery voltage adc io channel */ + batt_volt_en { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-low; + }; }; &usb_phy { diff --git a/sys/gnu/dts/arm/da850.dtsi b/sys/gnu/dts/arm/da850.dtsi index 941d455000a7..af68ef7b0caa 100644 --- a/sys/gnu/dts/arm/da850.dtsi +++ b/sys/gnu/dts/arm/da850.dtsi @@ -446,13 +446,38 @@ }; usb0: usb@200000 { compatible = "ti,da830-musb"; - reg = <0x200000 0x10000>; + reg = <0x200000 0x1000>; + ranges; interrupts = <58>; interrupt-names = "mc"; dr_mode = "otg"; phys = <&usb_phy 0>; phy-names = "usb-phy"; status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + dmas = <&cppi41dma 0 0 &cppi41dma 1 0 + &cppi41dma 2 0 &cppi41dma 3 0 + &cppi41dma 0 1 &cppi41dma 1 1 + &cppi41dma 2 1 &cppi41dma 3 1>; + dma-names = + "rx1", "rx2", "rx3", "rx4", + "tx1", "tx2", "tx3", "tx4"; + + cppi41dma: dma-controller@201000 { + compatible = "ti,da830-cppi41"; + reg = <0x201000 0x1000 + 0x202000 0x1000 + 0x204000 0x4000>; + reg-names = "controller", + "scheduler", "queuemgr"; + interrupts = <58>; + #dma-cells = <2>; + #dma-channels = <4>; + status = "okay"; + }; }; sata: sata@218000 { compatible = "ti,da850-ahci"; @@ -503,6 +528,8 @@ ti,ngpio = <144>; ti,davinci-gpio-unbanked = <0>; status = "disabled"; + interrupt-controller; + #interrupt-cells = <2>; }; pinconf: pin-controller@22c00c { compatible = "ti,da850-pupd"; diff --git a/sys/gnu/dts/arm/dm8168-evm.dts b/sys/gnu/dts/arm/dm8168-evm.dts index 1865976db5f9..c72a2132aa82 100644 --- a/sys/gnu/dts/arm/dm8168-evm.dts +++ b/sys/gnu/dts/arm/dm8168-evm.dts @@ -68,6 +68,34 @@ DM816X_IOPAD(0x0d08, MUX_MODE0) /* USB1_DRVVBUS */ >; }; + + nandflash_pins: nandflash_pins { + pinctrl-single,pins = < + DM816X_IOPAD(0x0b38, PULL_UP | MUX_MODE0) /* PINCTRL207 GPMC_CS0*/ + DM816X_IOPAD(0x0b60, PULL_ENA | MUX_MODE0) /* PINCTRL217 GPMC_ADV_ALE */ + DM816X_IOPAD(0x0b54, PULL_UP | PULL_ENA | MUX_MODE0) /* PINCTRL214 GPMC_OE_RE */ + DM816X_IOPAD(0x0b58, PULL_ENA | MUX_MODE0) /* PINCTRL215 GPMC_BE0_CLE */ + DM816X_IOPAD(0x0b50, PULL_UP | MUX_MODE0) /* PINCTRL213 GPMC_WE */ + DM816X_IOPAD(0x0b6c, MUX_MODE0) /* PINCTRL220 GPMC_WAIT */ + DM816X_IOPAD(0x0be4, PULL_ENA | MUX_MODE0) /* PINCTRL250 GPMC_CLK */ + DM816X_IOPAD(0x0ba4, MUX_MODE0) /* PINCTRL234 GPMC_D0 */ + DM816X_IOPAD(0x0ba8, MUX_MODE0) /* PINCTRL234 GPMC_D1 */ + DM816X_IOPAD(0x0bac, MUX_MODE0) /* PINCTRL234 GPMC_D2 */ + DM816X_IOPAD(0x0bb0, MUX_MODE0) /* PINCTRL234 GPMC_D3 */ + DM816X_IOPAD(0x0bb4, MUX_MODE0) /* PINCTRL234 GPMC_D4 */ + DM816X_IOPAD(0x0bb8, MUX_MODE0) /* PINCTRL234 GPMC_D5 */ + DM816X_IOPAD(0x0bbc, MUX_MODE0) /* PINCTRL234 GPMC_D6 */ + DM816X_IOPAD(0x0bc0, MUX_MODE0) /* PINCTRL234 GPMC_D7 */ + DM816X_IOPAD(0x0bc4, MUX_MODE0) /* PINCTRL234 GPMC_D8 */ + DM816X_IOPAD(0x0bc8, MUX_MODE0) /* PINCTRL234 GPMC_D9 */ + DM816X_IOPAD(0x0bcc, MUX_MODE0) /* PINCTRL234 GPMC_D10 */ + DM816X_IOPAD(0x0bd0, MUX_MODE0) /* PINCTRL234 GPMC_D11 */ + DM816X_IOPAD(0x0bd4, MUX_MODE0) /* PINCTRL234 GPMC_D12 */ + DM816X_IOPAD(0x0bd8, MUX_MODE0) /* PINCTRL234 GPMC_D13 */ + DM816X_IOPAD(0x0bdc, MUX_MODE0) /* PINCTRL234 GPMC_D14 */ + DM816X_IOPAD(0x0be0, MUX_MODE0) /* PINCTRL234 GPMC_D15 */ + >; + }; }; &i2c1 { @@ -90,6 +118,8 @@ &gpmc { ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */ + pinctrl-names = "default"; + pinctrl-0 = <&nandflash_pins>; nand@0,0 { compatible = "ti,omap2-nand"; @@ -98,9 +128,11 @@ interrupt-parent = <&gpmc>; interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ + rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ #address-cells = <1>; #size-cells = <1>; ti,nand-ecc-opt = "bch8"; + ti,elm-id = <&elm>; nand-bus-width = <16>; gpmc,device-width = <2>; gpmc,sync-clk-ps = <0>; @@ -164,7 +196,7 @@ vmmc-supply = <&vmmcsd_fixed>; bus-width = <4>; cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; }; /* At least dm8168-evm rev c won't support multipoint, later may */ diff --git a/sys/gnu/dts/arm/dm816x.dtsi b/sys/gnu/dts/arm/dm816x.dtsi index 59cbf958fcc3..566b2a8c8b96 100644 --- a/sys/gnu/dts/arm/dm816x.dtsi +++ b/sys/gnu/dts/arm/dm816x.dtsi @@ -145,7 +145,7 @@ }; elm: elm@48080000 { - compatible = "ti,816-elm"; + compatible = "ti,am3352-elm"; ti,hwmods = "elm"; reg = <0x48080000 0x2000>; interrupts = <4>; diff --git a/sys/gnu/dts/arm/dra7-evm.dts b/sys/gnu/dts/arm/dra7-evm.dts index 31a9e061ddd0..f47fc4daf062 100644 --- a/sys/gnu/dts/arm/dra7-evm.dts +++ b/sys/gnu/dts/arm/dra7-evm.dts @@ -529,7 +529,8 @@ }; &usb1 { - dr_mode = "peripheral"; + dr_mode = "otg"; + extcon = <&extcon_usb1>; }; &usb2 { diff --git a/sys/gnu/dts/arm/dra7.dtsi b/sys/gnu/dts/arm/dra7.dtsi index e7144662af45..0f0f6f58bd18 100644 --- a/sys/gnu/dts/arm/dra7.dtsi +++ b/sys/gnu/dts/arm/dra7.dtsi @@ -99,14 +99,14 @@ compatible = "operating-points-v2-ti-cpu"; syscon = <&scm_wkup>; - opp_nom@1000000000 { + opp_nom-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1060000 850000 1150000>; opp-supported-hw = <0xFF 0x01>; opp-suspend; }; - opp_od@1176000000 { + opp_od-1176000000 { opp-hz = /bits/ 64 <1176000000>; opp-microvolt = <1160000 885000 1160000>; opp-supported-hw = <0xFF 0x02>; diff --git a/sys/gnu/dts/arm/dra71-evm.dts b/sys/gnu/dts/arm/dra71-evm.dts index 4d57a55473af..a6298eb56978 100644 --- a/sys/gnu/dts/arm/dra71-evm.dts +++ b/sys/gnu/dts/arm/dra71-evm.dts @@ -190,7 +190,7 @@ ti,rx-internal-delay = ; ti,tx-internal-delay = ; ti,fifo-depth = ; - ti,impedance-control = <0x1f>; + ti,min-output-impedance; }; dp83867_1: ethernet-phy@3 { @@ -198,7 +198,7 @@ ti,rx-internal-delay = ; ti,tx-internal-delay = ; ti,fifo-depth = ; - ti,impedance-control = <0x1f>; + ti,min-output-impedance; }; }; diff --git a/sys/gnu/dts/arm/dra72-evm-common.dtsi b/sys/gnu/dts/arm/dra72-evm-common.dtsi index ad24544adf0f..85780549bc26 100644 --- a/sys/gnu/dts/arm/dra72-evm-common.dtsi +++ b/sys/gnu/dts/arm/dra72-evm-common.dtsi @@ -392,7 +392,8 @@ }; &usb1 { - dr_mode = "peripheral"; + dr_mode = "otg"; + extcon = <&extcon_usb1>; }; &usb2 { diff --git a/sys/gnu/dts/arm/dra7xx-clocks.dtsi b/sys/gnu/dts/arm/dra7xx-clocks.dtsi index 3330738e4c6e..cf229dfabf61 100644 --- a/sys/gnu/dts/arm/dra7xx-clocks.dtsi +++ b/sys/gnu/dts/arm/dra7xx-clocks.dtsi @@ -338,6 +338,8 @@ compatible = "ti,omap4-dpll-clock"; clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>; reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; + assigned-clocks = <&dpll_dsp_ck>; + assigned-clock-rates = <600000000>; }; dpll_dsp_m2_ck: dpll_dsp_m2_ck@244 { @@ -349,6 +351,8 @@ reg = <0x0244>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_dsp_m2_ck>; + assigned-clock-rates = <600000000>; }; iva_dpll_hs_clk_div: iva_dpll_hs_clk_div { @@ -372,6 +376,8 @@ compatible = "ti,omap4-dpll-clock"; clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>; reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; + assigned-clocks = <&dpll_iva_ck>; + assigned-clock-rates = <1165000000>; }; dpll_iva_m2_ck: dpll_iva_m2_ck@1b0 { @@ -383,6 +389,8 @@ reg = <0x01b0>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_iva_m2_ck>; + assigned-clock-rates = <388333334>; }; iva_dclk: iva_dclk { @@ -406,6 +414,8 @@ compatible = "ti,omap4-dpll-clock"; clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>; reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; + assigned-clocks = <&dpll_gpu_ck>; + assigned-clock-rates = <1277000000>; }; dpll_gpu_m2_ck: dpll_gpu_m2_ck@2e8 { @@ -417,6 +427,8 @@ reg = <0x02e8>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_gpu_m2_ck>; + assigned-clock-rates = <425666667>; }; dpll_core_m2_ck: dpll_core_m2_ck@130 { @@ -659,6 +671,8 @@ reg = <0x0248>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_dsp_m3x2_ck>; + assigned-clock-rates = <400000000>; }; dpll_gmac_x2_ck: dpll_gmac_x2_ck { @@ -791,6 +805,8 @@ clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; ti,bit-shift = <24>; reg = <0x0520>; + assigned-clocks = <&ipu1_gfclk_mux>; + assigned-clock-parents = <&dpll_core_h22x2_ck>; }; mcasp1_ahclkr_mux: mcasp1_ahclkr_mux@550 { @@ -1748,6 +1764,8 @@ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; ti,bit-shift = <24>; reg = <0x1220>; + assigned-clocks = <&gpu_core_gclk_mux>; + assigned-clock-parents = <&dpll_gpu_m2_ck>; }; gpu_hyd_gclk_mux: gpu_hyd_gclk_mux@1220 { @@ -1756,6 +1774,8 @@ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; ti,bit-shift = <26>; reg = <0x1220>; + assigned-clocks = <&gpu_hyd_gclk_mux>; + assigned-clock-parents = <&dpll_gpu_m2_ck>; }; l3instr_ts_gclk_div: l3instr_ts_gclk_div@e50 { diff --git a/sys/gnu/dts/arm/emev2.dtsi b/sys/gnu/dts/arm/emev2.dtsi index 0124faf175c8..42ea246e71cb 100644 --- a/sys/gnu/dts/arm/emev2.dtsi +++ b/sys/gnu/dts/arm/emev2.dtsi @@ -197,7 +197,7 @@ clock-names = "sclk"; }; - pfc: pfc@e0140200 { + pfc: pin-controller@e0140200 { compatible = "renesas,pfc-emev2"; reg = <0xe0140200 0x100>; }; diff --git a/sys/gnu/dts/arm/ethernut5.dts b/sys/gnu/dts/arm/ethernut5.dts index 4687229a3ab9..123b203be06c 100644 --- a/sys/gnu/dts/arm/ethernut5.dts +++ b/sys/gnu/dts/arm/ethernut5.dts @@ -55,25 +55,38 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - gpios = <0 - &pioC 14 GPIO_ACTIVE_HIGH - 0 - >; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs>; + pinctrl-names = "default"; - root@0 { - label = "root"; - reg = <0x0 0x08000000>; - }; + nand: nand@3 { + reg = <0x3 0x0 0x800000>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - data@20000 { - label = "data"; - reg = <0x08000000 0x38000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + root@0 { + label = "root"; + reg = <0x0 0x08000000>; + }; + + data@20000 { + label = "data"; + reg = <0x08000000 0x38000000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/exynos3250-monk.dts b/sys/gnu/dts/arm/exynos3250-monk.dts index cccfe4b791d1..accee81da266 100644 --- a/sys/gnu/dts/arm/exynos3250-monk.dts +++ b/sys/gnu/dts/arm/exynos3250-monk.dts @@ -67,7 +67,7 @@ max77836: subpmic@25 { compatible = "maxim,max77836"; interrupt-parent = <&gpx1>; - interrupts = <5 0>; + interrupts = <5 IRQ_TYPE_NONE>; reg = <0x25>; wakeup-source; @@ -191,7 +191,7 @@ s2mps14_pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; - interrupts = <7 0>; + interrupts = <7 IRQ_TYPE_NONE>; reg = <0x66>; wakeup-source; @@ -414,7 +414,7 @@ fuelgauge@36 { compatible = "maxim,max77836-battery"; interrupt-parent = <&gpx1>; - interrupts = <2 8>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; reg = <0x36>; }; }; diff --git a/sys/gnu/dts/arm/exynos3250-rinato.dts b/sys/gnu/dts/arm/exynos3250-rinato.dts index c9f191ca7b9c..443e0c98dc73 100644 --- a/sys/gnu/dts/arm/exynos3250-rinato.dts +++ b/sys/gnu/dts/arm/exynos3250-rinato.dts @@ -58,7 +58,7 @@ max77836: subpmic@25 { compatible = "maxim,max77836"; interrupt-parent = <&gpx1>; - interrupts = <5 0>; + interrupts = <5 IRQ_TYPE_NONE>; reg = <0x25>; wakeup-source; @@ -240,7 +240,7 @@ reg = <0>; vdd3-supply = <&ldo16_reg>; vci-supply = <&ldo20_reg>; - reset-gpios = <&gpe0 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpe0 1 GPIO_ACTIVE_LOW>; te-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>; power-on-delay= <30>; power-off-delay= <120>; @@ -295,7 +295,7 @@ s2mps14_pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; - interrupts = <7 0>; + interrupts = <7 IRQ_TYPE_NONE>; reg = <0x66>; wakeup-source; @@ -626,7 +626,7 @@ fuelgauge@36 { compatible = "maxim,max77836-battery"; interrupt-parent = <&gpx1>; - interrupts = <2 8>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; reg = <0x36>; }; }; diff --git a/sys/gnu/dts/arm/exynos4.dtsi b/sys/gnu/dts/arm/exynos4.dtsi index 497a9470c888..5739389f5bb8 100644 --- a/sys/gnu/dts/arm/exynos4.dtsi +++ b/sys/gnu/dts/arm/exynos4.dtsi @@ -59,6 +59,9 @@ compatible = "samsung,exynos4210-audss-clock"; reg = <0x03810000 0x0C>; #clock-cells = <1>; + clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>, + <&clock CLK_SCLK_AUDIO0>, <&clock CLK_SCLK_AUDIO0>; + clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in"; }; i2s0: i2s@03830000 { diff --git a/sys/gnu/dts/arm/exynos4210-origen.dts b/sys/gnu/dts/arm/exynos4210-origen.dts index 312650e2450f..084fcc5574ef 100644 --- a/sys/gnu/dts/arm/exynos4210-origen.dts +++ b/sys/gnu/dts/arm/exynos4210-origen.dts @@ -151,7 +151,7 @@ compatible = "maxim,max8997-pmic"; reg = <0x66>; interrupt-parent = <&gpx0>; - interrupts = <4 0>, <3 0>; + interrupts = <4 IRQ_TYPE_NONE>, <3 IRQ_TYPE_NONE>; max8997,pmic-buck1-dvs-voltage = <1350000>; max8997,pmic-buck2-dvs-voltage = <1100000>; diff --git a/sys/gnu/dts/arm/exynos4210-trats.dts b/sys/gnu/dts/arm/exynos4210-trats.dts index 1743ca850070..645feffb9239 100644 --- a/sys/gnu/dts/arm/exynos4210-trats.dts +++ b/sys/gnu/dts/arm/exynos4210-trats.dts @@ -281,7 +281,7 @@ compatible = "melfas,mms114"; reg = <0x48>; interrupt-parent = <&gpx0>; - interrupts = <4 2>; + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; x-size = <720>; y-size = <1280>; avdd-supply = <&tsp_reg>; @@ -302,7 +302,7 @@ reg = <0x66>; interrupt-parent = <&gpx0>; - interrupts = <7 0>; + interrupts = <7 IRQ_TYPE_NONE>; max8997,pmic-buck1-uses-gpio-dvs; max8997,pmic-buck2-uses-gpio-dvs; diff --git a/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi b/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi index 0f1ff792fe44..219d587c5a85 100644 --- a/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi +++ b/sys/gnu/dts/arm/exynos4412-odroid-common.dtsi @@ -32,7 +32,7 @@ power_key { interrupt-parent = <&gpx1>; - interrupts = <3 0>; + interrupts = <3 IRQ_TYPE_NONE>; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; label = "power key"; @@ -266,7 +266,7 @@ max77686: pmic@09 { compatible = "maxim,max77686"; interrupt-parent = <&gpx3>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_NONE>; pinctrl-names = "default"; pinctrl-0 = <&max77686_irq>; reg = <0x09>; @@ -484,7 +484,7 @@ compatible = "maxim,max98090"; reg = <0x10>; interrupt-parent = <&gpx0>; - interrupts = <0 0>; + interrupts = <0 IRQ_TYPE_NONE>; clocks = <&i2s0 CLK_I2S_CDCLK>; clock-names = "mclk"; #sound-dai-cells = <0>; diff --git a/sys/gnu/dts/arm/exynos4412-odroidu3.dts b/sys/gnu/dts/arm/exynos4412-odroidu3.dts index 7504a5aa538e..44a4de08466b 100644 --- a/sys/gnu/dts/arm/exynos4412-odroidu3.dts +++ b/sys/gnu/dts/arm/exynos4412-odroidu3.dts @@ -78,6 +78,10 @@ regulator-max-microvolt = <3300000>; }; +&hdmicec { + needs-hpd; +}; + /* VDDQ for MSHC (eMMC card) */ &ldo22_reg { regulator-name = "LDO22_VDDQ_MMC4_2.8V"; diff --git a/sys/gnu/dts/arm/exynos4412-odroidx.dts b/sys/gnu/dts/arm/exynos4412-odroidx.dts index 46b931eec228..97882267ef09 100644 --- a/sys/gnu/dts/arm/exynos4412-odroidx.dts +++ b/sys/gnu/dts/arm/exynos4412-odroidx.dts @@ -44,7 +44,7 @@ home_key { interrupt-parent = <&gpx2>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_NONE>; gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>; linux,code = ; label = "home key"; diff --git a/sys/gnu/dts/arm/exynos4412-trats2.dts b/sys/gnu/dts/arm/exynos4412-trats2.dts index 82221a00444d..35e9b94b86b8 100644 --- a/sys/gnu/dts/arm/exynos4412-trats2.dts +++ b/sys/gnu/dts/arm/exynos4412-trats2.dts @@ -144,7 +144,7 @@ max77693@66 { compatible = "maxim,max77693"; interrupt-parent = <&gpx1>; - interrupts = <5 2>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; reg = <0x66>; regulators { @@ -224,7 +224,7 @@ compatible = "capella,cm36651"; reg = <0x18>; interrupt-parent = <&gpx0>; - interrupts = <2 2>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; vled-supply = <&ps_als_reg>; }; }; @@ -573,7 +573,7 @@ compatible = "melfas,mms114"; reg = <0x48>; interrupt-parent = <&gpm2>; - interrupts = <3 2>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; x-size = <720>; y-size = <1280>; avdd-supply = <&ldo23_reg>; @@ -611,7 +611,7 @@ max77686: max77686_pmic@09 { compatible = "maxim,max77686"; interrupt-parent = <&gpx0>; - interrupts = <7 0>; + interrupts = <7 IRQ_TYPE_NONE>; reg = <0x09>; #clock-cells = <1>; diff --git a/sys/gnu/dts/arm/exynos5.dtsi b/sys/gnu/dts/arm/exynos5.dtsi index b74c5379ca26..66d22521c976 100644 --- a/sys/gnu/dts/arm/exynos5.dtsi +++ b/sys/gnu/dts/arm/exynos5.dtsi @@ -55,38 +55,38 @@ interrupt-controller; samsung,combiner-nr = <32>; reg = <0x10440000 0x1000>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 4 IRQ_TYPE_LEVEL_HIGH>, - <0 5 IRQ_TYPE_LEVEL_HIGH>, - <0 6 IRQ_TYPE_LEVEL_HIGH>, - <0 7 IRQ_TYPE_LEVEL_HIGH>, - <0 8 IRQ_TYPE_LEVEL_HIGH>, - <0 9 IRQ_TYPE_LEVEL_HIGH>, - <0 10 IRQ_TYPE_LEVEL_HIGH>, - <0 11 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>, - <0 18 IRQ_TYPE_LEVEL_HIGH>, - <0 19 IRQ_TYPE_LEVEL_HIGH>, - <0 20 IRQ_TYPE_LEVEL_HIGH>, - <0 21 IRQ_TYPE_LEVEL_HIGH>, - <0 22 IRQ_TYPE_LEVEL_HIGH>, - <0 23 IRQ_TYPE_LEVEL_HIGH>, - <0 24 IRQ_TYPE_LEVEL_HIGH>, - <0 25 IRQ_TYPE_LEVEL_HIGH>, - <0 26 IRQ_TYPE_LEVEL_HIGH>, - <0 27 IRQ_TYPE_LEVEL_HIGH>, - <0 28 IRQ_TYPE_LEVEL_HIGH>, - <0 29 IRQ_TYPE_LEVEL_HIGH>, - <0 30 IRQ_TYPE_LEVEL_HIGH>, - <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; gic: interrupt-controller@10481000 { @@ -109,31 +109,31 @@ serial_0: serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; - interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; serial_1: serial@12C10000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C10000 0x100>; - interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; serial_2: serial@12C20000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C20000 0x100>; - interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; serial_3: serial@12C30000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C30000 0x100>; - interrupts = <0 54 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; i2c_0: i2c@12C60000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C60000 0x100>; - interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; samsung,sysreg-phandle = <&sysreg_system_controller>; @@ -143,7 +143,7 @@ i2c_1: i2c@12C70000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C70000 0x100>; - interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; samsung,sysreg-phandle = <&sysreg_system_controller>; @@ -153,7 +153,7 @@ i2c_2: i2c@12C80000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C80000 0x100>; - interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; samsung,sysreg-phandle = <&sysreg_system_controller>; @@ -163,7 +163,7 @@ i2c_3: i2c@12C90000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C90000 0x100>; - interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; samsung,sysreg-phandle = <&sysreg_system_controller>; @@ -180,8 +180,8 @@ rtc: rtc@101E0000 { compatible = "samsung,s3c6410-rtc"; reg = <0x101E0000 0x100>; - interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>, - <0 44 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/exynos5250-arndale.dts b/sys/gnu/dts/arm/exynos5250-arndale.dts index 6098dacd09f1..6a432460eb77 100644 --- a/sys/gnu/dts/arm/exynos5250-arndale.dts +++ b/sys/gnu/dts/arm/exynos5250-arndale.dts @@ -14,7 +14,6 @@ #include #include #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Insignal Arndale evaluation board based on EXYNOS5250"; diff --git a/sys/gnu/dts/arm/exynos5250-pinctrl.dtsi b/sys/gnu/dts/arm/exynos5250-pinctrl.dtsi index 2f6ab32b5954..1fd122db18e6 100644 --- a/sys/gnu/dts/arm/exynos5250-pinctrl.dtsi +++ b/sys/gnu/dts/arm/exynos5250-pinctrl.dtsi @@ -589,6 +589,13 @@ samsung,pin-pud = ; samsung,pin-drv = ; }; + + hdmi_cec: hdmi-cec { + samsung,pins = "gpx3-6"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; }; &pinctrl_1 { diff --git a/sys/gnu/dts/arm/exynos5250-smdk5250.dts b/sys/gnu/dts/arm/exynos5250-smdk5250.dts index a97a785ccc6b..6632f657394e 100644 --- a/sys/gnu/dts/arm/exynos5250-smdk5250.dts +++ b/sys/gnu/dts/arm/exynos5250-smdk5250.dts @@ -13,7 +13,6 @@ #include #include #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "SAMSUNG SMDK5250 board based on EXYNOS5250"; diff --git a/sys/gnu/dts/arm/exynos5250-snow-common.dtsi b/sys/gnu/dts/arm/exynos5250-snow-common.dtsi index 8f3a80430748..e1d293dbbe5d 100644 --- a/sys/gnu/dts/arm/exynos5250-snow-common.dtsi +++ b/sys/gnu/dts/arm/exynos5250-snow-common.dtsi @@ -272,6 +272,10 @@ vdd_pll-supply = <&ldo8_reg>; }; +&hdmicec { + status = "okay"; +}; + &i2c_0 { status = "okay"; samsung,i2c-sda-delay = <100>; diff --git a/sys/gnu/dts/arm/exynos5250-spring.dts b/sys/gnu/dts/arm/exynos5250-spring.dts index 4d7bdb735ed3..95c3bcace9dc 100644 --- a/sys/gnu/dts/arm/exynos5250-spring.dts +++ b/sys/gnu/dts/arm/exynos5250-spring.dts @@ -14,7 +14,6 @@ #include #include #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Spring"; diff --git a/sys/gnu/dts/arm/exynos5250.dtsi b/sys/gnu/dts/arm/exynos5250.dtsi index 79c9c885613a..8dbeb873e99c 100644 --- a/sys/gnu/dts/arm/exynos5250.dtsi +++ b/sys/gnu/dts/arm/exynos5250.dtsi @@ -153,10 +153,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; + interrupts = , + , + , + ; /* * Unfortunately we need this since some versions * of U-Boot on Exynos don't set the CNTFRQ register, @@ -689,6 +689,19 @@ samsung,syscon-phandle = <&pmu_system_controller>; }; + hdmicec: cec@101B0000 { + compatible = "samsung,s5p-cec"; + reg = <0x101B0000 0x200>; + interrupts = ; + clocks = <&clock CLK_HDMI_CEC>; + clock-names = "hdmicec"; + samsung,syscon-phandle = <&pmu_system_controller>; + hdmi-phandle = <&hdmi>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_cec>; + status = "disabled"; + }; + mixer@14450000 { compatible = "samsung,exynos5250-mixer"; reg = <0x14450000 0x10000>; diff --git a/sys/gnu/dts/arm/exynos5420-arndale-octa.dts b/sys/gnu/dts/arm/exynos5420-arndale-octa.dts index 9cc83c51c925..ee1bb9b8b366 100644 --- a/sys/gnu/dts/arm/exynos5420-arndale-octa.dts +++ b/sys/gnu/dts/arm/exynos5420-arndale-octa.dts @@ -16,7 +16,6 @@ #include #include #include -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Insignal Arndale Octa evaluation board based on EXYNOS5420"; diff --git a/sys/gnu/dts/arm/exynos5420-peach-pit.dts b/sys/gnu/dts/arm/exynos5420-peach-pit.dts index 1f964ec35c5e..f9a75bfd3f2b 100644 --- a/sys/gnu/dts/arm/exynos5420-peach-pit.dts +++ b/sys/gnu/dts/arm/exynos5420-peach-pit.dts @@ -16,7 +16,6 @@ #include #include "exynos5420.dtsi" #include "exynos5420-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Peach Pit Rev 6+"; @@ -604,7 +603,7 @@ max98090: codec@10 { compatible = "maxim,max98090"; reg = <0x10>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_NONE>; interrupt-parent = <&gpx0>; pinctrl-names = "default"; pinctrl-0 = <&max98090_irq>; @@ -945,7 +944,7 @@ cros_ec: cros-ec@0 { compatible = "google,cros-ec-spi"; interrupt-parent = <&gpx1>; - interrupts = <5 0>; + interrupts = <5 IRQ_TYPE_NONE>; pinctrl-names = "default"; pinctrl-0 = <&ec_spi_cs &ec_irq>; reg = <0>; diff --git a/sys/gnu/dts/arm/exynos5420-pinctrl.dtsi b/sys/gnu/dts/arm/exynos5420-pinctrl.dtsi index 3924b4fafe72..65aa0e300c23 100644 --- a/sys/gnu/dts/arm/exynos5420-pinctrl.dtsi +++ b/sys/gnu/dts/arm/exynos5420-pinctrl.dtsi @@ -67,6 +67,13 @@ samsung,pin-pud = ; samsung,pin-drv = ; }; + + hdmi_cec: hdmi-cec { + samsung,pins = "gpx3-6"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; }; &pinctrl_1 { diff --git a/sys/gnu/dts/arm/exynos5420-smdk5420.dts b/sys/gnu/dts/arm/exynos5420-smdk5420.dts index aaccd0da41e5..08c8ab173e87 100644 --- a/sys/gnu/dts/arm/exynos5420-smdk5420.dts +++ b/sys/gnu/dts/arm/exynos5420-smdk5420.dts @@ -13,7 +13,6 @@ #include "exynos5420.dtsi" #include "exynos5420-cpus.dtsi" #include -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Samsung SMDK5420 board based on EXYNOS5420"; diff --git a/sys/gnu/dts/arm/exynos5420.dtsi b/sys/gnu/dts/arm/exynos5420.dtsi index 0db0bcf8da36..02d2f898efa6 100644 --- a/sys/gnu/dts/arm/exynos5420.dtsi +++ b/sys/gnu/dts/arm/exynos5420.dtsi @@ -193,7 +193,7 @@ mfc: codec@11000000 { compatible = "samsung,mfc-v7"; reg = <0x11000000 0x10000>; - interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_MFC>; clock-names = "mfc"; power-domains = <&mfc_pd>; @@ -203,7 +203,7 @@ mmc_0: mmc@12200000 { compatible = "samsung,exynos5420-dw-mshc-smu"; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; reg = <0x12200000 0x2000>; @@ -215,7 +215,7 @@ mmc_1: mmc@12210000 { compatible = "samsung,exynos5420-dw-mshc-smu"; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; reg = <0x12210000 0x2000>; @@ -227,7 +227,7 @@ mmc_2: mmc@12220000 { compatible = "samsung,exynos5420-dw-mshc"; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; reg = <0x12220000 0x1000>; @@ -325,37 +325,37 @@ pinctrl_0: pinctrl@13400000 { compatible = "samsung,exynos5420-pinctrl"; reg = <0x13400000 0x1000>; - interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; wakeup-interrupt-controller { compatible = "samsung,exynos4210-wakeup-eint"; interrupt-parent = <&gic>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; }; pinctrl_1: pinctrl@13410000 { compatible = "samsung,exynos5420-pinctrl"; reg = <0x13410000 0x1000>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; pinctrl_2: pinctrl@14000000 { compatible = "samsung,exynos5420-pinctrl"; reg = <0x14000000 0x1000>; - interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; pinctrl_3: pinctrl@14010000 { compatible = "samsung,exynos5420-pinctrl"; reg = <0x14010000 0x1000>; - interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; pinctrl_4: pinctrl@03860000 { compatible = "samsung,exynos5420-pinctrl"; reg = <0x03860000 0x1000>; - interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; amba { @@ -368,7 +368,7 @@ adma: adma@03880000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x03880000 0x1000>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock_audss EXYNOS_ADMA>; clock-names = "apb_pclk"; #dma-cells = <1>; @@ -379,7 +379,7 @@ pdma0: pdma@121A0000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x121A0000 0x1000>; - interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_PDMA0>; clock-names = "apb_pclk"; #dma-cells = <1>; @@ -390,7 +390,7 @@ pdma1: pdma@121B0000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x121B0000 0x1000>; - interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_PDMA1>; clock-names = "apb_pclk"; #dma-cells = <1>; @@ -401,7 +401,7 @@ mdma0: mdma@10800000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x10800000 0x1000>; - interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_MDMA0>; clock-names = "apb_pclk"; #dma-cells = <1>; @@ -412,7 +412,7 @@ mdma1: mdma@11C10000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x11C10000 0x1000>; - interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_MDMA1>; clock-names = "apb_pclk"; #dma-cells = <1>; @@ -484,7 +484,7 @@ spi_0: spi@12d20000 { compatible = "samsung,exynos4210-spi"; reg = <0x12d20000 0x100>; - interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&pdma0 5 &pdma0 4>; dma-names = "tx", "rx"; @@ -500,7 +500,7 @@ spi_1: spi@12d30000 { compatible = "samsung,exynos4210-spi"; reg = <0x12d30000 0x100>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&pdma1 5 &pdma1 4>; dma-names = "tx", "rx"; @@ -516,7 +516,7 @@ spi_2: spi@12d40000 { compatible = "samsung,exynos4210-spi"; reg = <0x12d40000 0x100>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&pdma0 7 &pdma0 6>; dma-names = "tx", "rx"; @@ -544,7 +544,7 @@ dsi@14500000 { compatible = "samsung,exynos5410-mipi-dsi"; reg = <0x14500000 0x10000>; - interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; phys = <&mipi_phy 1>; phy-names = "dsim"; clocks = <&clock CLK_DSIM1>, <&clock CLK_SCLK_MIPI1>; @@ -557,7 +557,7 @@ adc: adc@12D10000 { compatible = "samsung,exynos-adc-v2"; reg = <0x12D10000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TSADC>; clock-names = "adc"; #io-channel-cells = <1>; @@ -569,7 +569,7 @@ hsi2c_8: i2c@12E00000 { compatible = "samsung,exynos5250-hsi2c"; reg = <0x12E00000 0x1000>; - interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -582,7 +582,7 @@ hsi2c_9: i2c@12E10000 { compatible = "samsung,exynos5250-hsi2c"; reg = <0x12E10000 0x1000>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -595,7 +595,7 @@ hsi2c_10: i2c@12E20000 { compatible = "samsung,exynos5250-hsi2c"; reg = <0x12E20000 0x1000>; - interrupts = <0 203 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -608,7 +608,7 @@ hdmi: hdmi@14530000 { compatible = "samsung,exynos5420-hdmi"; reg = <0x14530000 0x70000>; - interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, <&clock CLK_DOUT_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, <&clock CLK_MOUT_HDMI>; @@ -624,10 +624,23 @@ reg = <0x145D0000 0x20>; }; + hdmicec: cec@101B0000 { + compatible = "samsung,s5p-cec"; + reg = <0x101B0000 0x200>; + interrupts = ; + clocks = <&clock CLK_HDMI_CEC>; + clock-names = "hdmicec"; + samsung,syscon-phandle = <&pmu_system_controller>; + hdmi-phandle = <&hdmi>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_cec>; + status = "disabled"; + }; + mixer: mixer@14450000 { compatible = "samsung,exynos5420-mixer"; reg = <0x14450000 0x10000>; - interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>; clock-names = "mixer", "hdmi", "sclk_hdmi"; @@ -638,7 +651,7 @@ rotator: rotator@11C00000 { compatible = "samsung,exynos5250-rotator"; reg = <0x11C00000 0x64>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_ROTATOR>; clock-names = "rotator"; iommus = <&sysmmu_rotator>; @@ -647,7 +660,7 @@ gsc_0: video-scaler@13e00000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e00000 0x1000>; - interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_GSCL0>; clock-names = "gscl"; power-domains = <&gsc_pd>; @@ -657,7 +670,7 @@ gsc_1: video-scaler@13e10000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e10000 0x1000>; - interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_GSCL1>; clock-names = "gscl"; power-domains = <&gsc_pd>; @@ -667,7 +680,7 @@ jpeg_0: jpeg@11F50000 { compatible = "samsung,exynos5420-jpeg"; reg = <0x11F50000 0x1000>; - interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clock-names = "jpeg"; clocks = <&clock CLK_JPEG>; iommus = <&sysmmu_jpeg0>; @@ -676,7 +689,7 @@ jpeg_1: jpeg@11F60000 { compatible = "samsung,exynos5420-jpeg"; reg = <0x11F60000 0x1000>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clock-names = "jpeg"; clocks = <&clock CLK_JPEG2>; iommus = <&sysmmu_jpeg1>; @@ -696,7 +709,7 @@ tmu_cpu0: tmu@10060000 { compatible = "samsung,exynos5420-tmu"; reg = <0x10060000 0x100>; - interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TMU>; clock-names = "tmu_apbif"; #include "exynos5420-tmu-sensor-conf.dtsi" @@ -705,7 +718,7 @@ tmu_cpu1: tmu@10064000 { compatible = "samsung,exynos5420-tmu"; reg = <0x10064000 0x100>; - interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TMU>; clock-names = "tmu_apbif"; #include "exynos5420-tmu-sensor-conf.dtsi" @@ -714,7 +727,7 @@ tmu_cpu2: tmu@10068000 { compatible = "samsung,exynos5420-tmu-ext-triminfo"; reg = <0x10068000 0x100>, <0x1006c000 0x4>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TMU>, <&clock CLK_TMU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; #include "exynos5420-tmu-sensor-conf.dtsi" @@ -723,7 +736,7 @@ tmu_cpu3: tmu@1006c000 { compatible = "samsung,exynos5420-tmu-ext-triminfo"; reg = <0x1006c000 0x100>, <0x100a0000 0x4>; - interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; #include "exynos5420-tmu-sensor-conf.dtsi" @@ -732,7 +745,7 @@ tmu_gpu: tmu@100a0000 { compatible = "samsung,exynos5420-tmu-ext-triminfo"; reg = <0x100a0000 0x100>, <0x10068000 0x4>; - interrupts = <0 215 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>; clock-names = "tmu_apbif", "tmu_triminfo_apbif"; #include "exynos5420-tmu-sensor-conf.dtsi" @@ -804,7 +817,7 @@ sysmmu_scaler1r: sysmmu@0x12890000 { compatible = "samsung,exynos-sysmmu"; reg = <0x12890000 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clock-names = "sysmmu", "master"; clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>; #iommu-cells = <0>; @@ -813,7 +826,7 @@ sysmmu_scaler2r: sysmmu@0x128A0000 { compatible = "samsung,exynos-sysmmu"; reg = <0x128A0000 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clock-names = "sysmmu", "master"; clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>; #iommu-cells = <0>; @@ -872,7 +885,7 @@ sysmmu_jpeg1: sysmmu@0x11F20000 { compatible = "samsung,exynos-sysmmu"; reg = <0x11F20000 0x1000>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clock-names = "sysmmu", "master"; clocks = <&clock CLK_SMMU_JPEG2>, <&clock CLK_JPEG2>; #iommu-cells = <0>; diff --git a/sys/gnu/dts/arm/exynos5422-odroidxu3-audio.dtsi b/sys/gnu/dts/arm/exynos5422-odroidxu3-audio.dtsi index 9493923ec652..c0b85981c6bf 100644 --- a/sys/gnu/dts/arm/exynos5422-odroidxu3-audio.dtsi +++ b/sys/gnu/dts/arm/exynos5422-odroidxu3-audio.dtsi @@ -49,7 +49,7 @@ compatible = "maxim,max98090"; reg = <0x10>; interrupt-parent = <&gpx3>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_NONE>; clocks = <&i2s0 CLK_I2S_CDCLK>; clock-names = "mclk"; #sound-dai-cells = <0>; diff --git a/sys/gnu/dts/arm/exynos5422-odroidxu3-common.dtsi b/sys/gnu/dts/arm/exynos5422-odroidxu3-common.dtsi index 05b9afdd6757..a183b56283f8 100644 --- a/sys/gnu/dts/arm/exynos5422-odroidxu3-common.dtsi +++ b/sys/gnu/dts/arm/exynos5422-odroidxu3-common.dtsi @@ -18,7 +18,6 @@ #include #include "exynos5800.dtsi" #include "exynos5422-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { memory@40000000 { @@ -265,6 +264,11 @@ vdd-supply = <&ldo6_reg>; }; +&hdmicec { + status = "okay"; + needs-hpd; +}; + &hsi2c_4 { status = "okay"; diff --git a/sys/gnu/dts/arm/exynos5440.dtsi b/sys/gnu/dts/arm/exynos5440.dtsi index a4ea018464fc..bc4954e69f7b 100644 --- a/sys/gnu/dts/arm/exynos5440.dtsi +++ b/sys/gnu/dts/arm/exynos5440.dtsi @@ -200,7 +200,7 @@ compatible = "snps,dwmac-3.70a", "snps,dwmac"; reg = <0x00230000 0x8000>; interrupt-parent = <&gic>; - interrupts = ; + interrupts = ; interrupt-names = "macirq"; phy-mode = "sgmii"; clocks = <&clock CLK_GMAC0>; diff --git a/sys/gnu/dts/arm/exynos5800-peach-pi.dts b/sys/gnu/dts/arm/exynos5800-peach-pi.dts index f9ff7f07ae0c..953dc8677dc8 100644 --- a/sys/gnu/dts/arm/exynos5800-peach-pi.dts +++ b/sys/gnu/dts/arm/exynos5800-peach-pi.dts @@ -16,7 +16,6 @@ #include #include "exynos5800.dtsi" #include "exynos5420-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Peach Pi Rev 10+"; @@ -604,7 +603,7 @@ max98091: codec@10 { compatible = "maxim,max98091"; reg = <0x10>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_NONE>; interrupt-parent = <&gpx0>; pinctrl-names = "default"; pinctrl-0 = <&max98091_irq>; @@ -914,7 +913,7 @@ cros_ec: cros-ec@0 { compatible = "google,cros-ec-spi"; interrupt-parent = <&gpx1>; - interrupts = <5 0>; + interrupts = <5 IRQ_TYPE_NONE>; pinctrl-names = "default"; pinctrl-0 = <&ec_spi_cs &ec_irq>; reg = <0>; diff --git a/sys/gnu/dts/arm/ge863-pro3.dtsi b/sys/gnu/dts/arm/ge863-pro3.dtsi index 4aee5cc75fa4..8613944ea5c5 100644 --- a/sys/gnu/dts/arm/ge863-pro3.dtsi +++ b/sys/gnu/dts/arm/ge863-pro3.dtsi @@ -23,20 +23,39 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - boot@0 { - label = "boot"; - reg = <0x0 0x7c0000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - root@07c0000 { - label = "root"; - reg = <0x7c0000 0x7840000>; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot@0 { + label = "boot"; + reg = <0x0 0x7c0000>; + }; + + root@07c0000 { + label = "root"; + reg = <0x7c0000 0x7840000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/gemini-nas4220b.dts b/sys/gnu/dts/arm/gemini-nas4220b.dts index 7668ba52158e..55f6a4f1f801 100644 --- a/sys/gnu/dts/arm/gemini-nas4220b.dts +++ b/sys/gnu/dts/arm/gemini-nas4220b.dts @@ -98,5 +98,15 @@ read-only; }; }; + + sata: sata@46000000 { + cortina,gemini-ata-muxmode = <0>; + cortina,gemini-enable-sata-bridge; + status = "okay"; + }; + + ata@63000000 { + status = "okay"; + }; }; }; diff --git a/sys/gnu/dts/arm/gemini-sq201.dts b/sys/gnu/dts/arm/gemini-sq201.dts index 46309e79cc7b..4d200f0bcd45 100644 --- a/sys/gnu/dts/arm/gemini-sq201.dts +++ b/sys/gnu/dts/arm/gemini-sq201.dts @@ -93,6 +93,12 @@ }; }; + sata: sata@46000000 { + cortina,gemini-ata-muxmode = <0>; + cortina,gemini-enable-sata-bridge; + status = "okay"; + }; + pci@50000000 { status = "okay"; interrupt-map-mask = <0xf800 0 0 7>; @@ -114,5 +120,9 @@ <0x6000 0 0 3 &pci_intc 1>, <0x6000 0 0 4 &pci_intc 2>; }; + + ata@63000000 { + status = "okay"; + }; }; }; diff --git a/sys/gnu/dts/arm/gemini.dtsi b/sys/gnu/dts/arm/gemini.dtsi index b8d011bdcc76..141d8d3a1d07 100644 --- a/sys/gnu/dts/arm/gemini.dtsi +++ b/sys/gnu/dts/arm/gemini.dtsi @@ -25,8 +25,11 @@ }; syscon: syscon@40000000 { - compatible = "cortina,gemini-syscon", "syscon", "simple-mfd"; + compatible = "cortina,gemini-syscon", + "syscon", "simple-mfd"; reg = <0x40000000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; syscon-reboot { compatible = "syscon-reboot"; @@ -42,23 +45,30 @@ compatible = "cortina,gemini-watchdog"; reg = <0x41000000 0x1000>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon 23>; + clocks = <&syscon 2>; }; uart0: serial@42000000 { compatible = "ns16550a"; reg = <0x42000000 0x100>; - clock-frequency = <48000000>; + resets = <&syscon 18>; + clocks = <&syscon 6>; interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; }; timer@43000000 { - compatible = "cortina,gemini-timer"; + compatible = "faraday,fttmr010"; reg = <0x43000000 0x1000>; interrupt-parent = <&intcon>; interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */ <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */ <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */ + resets = <&syscon 17>; + /* APB clock or RTC clock */ + clocks = <&syscon 2>, <&syscon 0>; + clock-names = "PCLK", "EXTCLK"; syscon = <&syscon>; }; @@ -66,11 +76,28 @@ compatible = "cortina,gemini-rtc"; reg = <0x45000000 0x100>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon 16>; + clocks = <&syscon 2>, <&syscon 0>; + clock-names = "PCLK", "EXTCLK"; + }; + + sata: sata@46000000 { + compatible = "cortina,gemini-sata-bridge"; + reg = <0x46000000 0x100>; + resets = <&syscon 26>, + <&syscon 27>; + reset-names = "sata0", "sata1"; + clocks = <&syscon 10>, + <&syscon 11>; + clock-names = "SATA0_PCLK", "SATA1_PCLK"; + syscon = <&syscon>; + status = "disabled"; }; intcon: interrupt-controller@48000000 { compatible = "faraday,ftintc010"; reg = <0x48000000 0x1000>; + resets = <&syscon 14>; interrupt-controller; #interrupt-cells = <2>; }; @@ -85,6 +112,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4d000000 0x100>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon 20>; + clocks = <&syscon 2>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -95,6 +124,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4e000000 0x100>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon 21>; + clocks = <&syscon 2>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -105,6 +136,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4f000000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; + resets = <&syscon 22>; + clocks = <&syscon 2>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -118,6 +151,9 @@ * to configure the host bridge. */ reg = <0x50000000 0x100>; + resets = <&syscon 7>; + clocks = <&syscon 15>, <&syscon 4>; + clock-names = "PCLK", "PCICLK"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; @@ -152,5 +188,44 @@ #interrupt-cells = <1>; }; }; + + ata@63000000 { + compatible = "cortina,gemini-pata", "faraday,ftide010"; + reg = <0x63000000 0x1000>; + interrupts = <4 IRQ_TYPE_EDGE_RISING>; + resets = <&syscon 2>; + clocks = <&syscon 14>; + clock-names = "PCLK"; + sata = <&sata>; + status = "disabled"; + }; + + ata@63400000 { + compatible = "cortina,gemini-pata", "faraday,ftide010"; + reg = <0x63400000 0x1000>; + interrupts = <5 IRQ_TYPE_EDGE_RISING>; + resets = <&syscon 2>; + clocks = <&syscon 14>; + clock-names = "PCLK"; + sata = <&sata>; + status = "disabled"; + }; + + dma-controller@67000000 { + compatible = "faraday,ftdma020", "arm,pl080", "arm,primecell"; + /* Faraday Technology FTDMAC020 variant */ + arm,primecell-periphid = <0x0003b080>; + reg = <0x67000000 0x1000>; + interrupts = <9 IRQ_TYPE_EDGE_RISING>; + resets = <&syscon 10>; + clocks = <&syscon 1>; + clock-names = "apb_pclk"; + /* Bus interface AHB1 (AHB0) is totally tilted */ + lli-bus-interface-ahb2; + mem-bus-interface-ahb2; + memcpy-burst-size = <256>; + memcpy-bus-width = <32>; + #dma-cells = <2>; + }; }; }; diff --git a/sys/gnu/dts/arm/imx23-sansa.dts b/sys/gnu/dts/arm/imx23-sansa.dts index 4ec32f4c7885..221fd55e967e 100644 --- a/sys/gnu/dts/arm/imx23-sansa.dts +++ b/sys/gnu/dts/arm/imx23-sansa.dts @@ -42,6 +42,7 @@ */ /dts-v1/; +#include #include "imx23.dtsi" / { @@ -149,9 +150,8 @@ regulator-name = "vdd-touchpad0"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&gpio0 26 0>; + gpio = <&gpio0 26 GPIO_ACTIVE_LOW>; regulator-always-on; - enable-active-low; }; reg_vdd_tuner: regulator-vdd-tuner0 { @@ -159,9 +159,8 @@ regulator-name = "vdd-tuner0"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&gpio0 29 0>; + gpio = <&gpio0 29 GPIO_ACTIVE_LOW>; regulator-always-on; - enable-active-low; }; backlight { diff --git a/sys/gnu/dts/arm/imx25-karo-tx25.dts b/sys/gnu/dts/arm/imx25-karo-tx25.dts index 9b31faa96377..30a62d4be8d9 100644 --- a/sys/gnu/dts/arm/imx25-karo-tx25.dts +++ b/sys/gnu/dts/arm/imx25-karo-tx25.dts @@ -97,7 +97,7 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; - phy-reset-gpios = <&gpio3 7 0>; + phy-reset-gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; phy-mode = "rmii"; phy-supply = <®_fec_phy>; status = "okay"; diff --git a/sys/gnu/dts/arm/imx25-pdk.dts b/sys/gnu/dts/arm/imx25-pdk.dts index d921dd2ed676..c52692821fb1 100644 --- a/sys/gnu/dts/arm/imx25-pdk.dts +++ b/sys/gnu/dts/arm/imx25-pdk.dts @@ -125,7 +125,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-supply = <®_fec_3v3>; - phy-reset-gpios = <&gpio4 8 0>; + phy-reset-gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx25.dtsi b/sys/gnu/dts/arm/imx25.dtsi index 0cdf333336cd..0ade3619f3c3 100644 --- a/sys/gnu/dts/arm/imx25.dtsi +++ b/sys/gnu/dts/arm/imx25.dtsi @@ -9,6 +9,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include #include "imx25-pinfunc.h" / { @@ -296,6 +297,7 @@ #address-cells = <1>; #size-cells = <1>; status = "disabled"; + ranges; adc: adc@50030800 { compatible = "fsl,imx25-gcq"; diff --git a/sys/gnu/dts/arm/imx27-phytec-phycard-s-som.dtsi b/sys/gnu/dts/arm/imx27-phytec-phycard-s-som.dtsi index 4f3e0f473581..0b8490b21a38 100644 --- a/sys/gnu/dts/arm/imx27-phytec-phycard-s-som.dtsi +++ b/sys/gnu/dts/arm/imx27-phytec-phycard-s-som.dtsi @@ -40,7 +40,7 @@ status = "okay"; at24@52 { - compatible = "at,24c32"; + compatible = "atmel,24c32"; pagesize = <32>; reg = <0x52>; }; diff --git a/sys/gnu/dts/arm/imx27-phytec-phycore-som.dtsi b/sys/gnu/dts/arm/imx27-phytec-phycore-som.dtsi index 82fec935ce83..c973c5d91875 100644 --- a/sys/gnu/dts/arm/imx27-phytec-phycore-som.dtsi +++ b/sys/gnu/dts/arm/imx27-phytec-phycore-som.dtsi @@ -193,7 +193,7 @@ status = "okay"; at24@52 { - compatible = "at,24c32"; + compatible = "atmel,24c32"; pagesize = <32>; reg = <0x52>; }; diff --git a/sys/gnu/dts/arm/imx28-cfa10037.dts b/sys/gnu/dts/arm/imx28-cfa10037.dts index e5beaa58bb40..3d13b321d27b 100644 --- a/sys/gnu/dts/arm/imx28-cfa10037.dts +++ b/sys/gnu/dts/arm/imx28-cfa10037.dts @@ -64,7 +64,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a &mac0_pins_cfa10037>; - phy-reset-gpios = <&gpio2 21 0>; + phy-reset-gpios = <&gpio2 21 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-cfa10049.dts b/sys/gnu/dts/arm/imx28-cfa10049.dts index a9c347e48bcf..4cd52d53cf00 100644 --- a/sys/gnu/dts/arm/imx28-cfa10049.dts +++ b/sys/gnu/dts/arm/imx28-cfa10049.dts @@ -327,7 +327,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a &mac0_pins_cfa10049>; - phy-reset-gpios = <&gpio2 21 0>; + phy-reset-gpios = <&gpio2 21 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-cfa10057.dts b/sys/gnu/dts/arm/imx28-cfa10057.dts index 7a80bd686c40..c6067915b238 100644 --- a/sys/gnu/dts/arm/imx28-cfa10057.dts +++ b/sys/gnu/dts/arm/imx28-cfa10057.dts @@ -162,7 +162,7 @@ phy-mode = "rmii"; pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a>; - phy-reset-gpios = <&gpio2 21 0>; + phy-reset-gpios = <&gpio2 21 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-cfa10058.dts b/sys/gnu/dts/arm/imx28-cfa10058.dts index f5c6dce34abe..70c7bb4a5a0e 100644 --- a/sys/gnu/dts/arm/imx28-cfa10058.dts +++ b/sys/gnu/dts/arm/imx28-cfa10058.dts @@ -129,7 +129,7 @@ phy-mode = "rmii"; pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a>; - phy-reset-gpios = <&gpio2 21 0>; + phy-reset-gpios = <&gpio2 21 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-eukrea-mbmx287lc.dts b/sys/gnu/dts/arm/imx28-eukrea-mbmx287lc.dts index e773144e1e03..b61fd61eb1c7 100644 --- a/sys/gnu/dts/arm/imx28-eukrea-mbmx287lc.dts +++ b/sys/gnu/dts/arm/imx28-eukrea-mbmx287lc.dts @@ -31,7 +31,7 @@ phy-mode = "rmii"; pinctrl-names = "default"; pinctrl-0 = <&mac1_pins_a>; - phy-reset-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio3 27 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-evk.dts b/sys/gnu/dts/arm/imx28-evk.dts index a5ba669b4eaa..5309bb90d7d5 100644 --- a/sys/gnu/dts/arm/imx28-evk.dts +++ b/sys/gnu/dts/arm/imx28-evk.dts @@ -203,7 +203,7 @@ }; at24@51 { - compatible = "at24,24c32"; + compatible = "atmel,24c32"; pagesize = <32>; reg = <0x51>; }; @@ -262,7 +262,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a>; phy-supply = <®_fec_3v3>; - phy-reset-gpios = <&gpio4 13 0>; + phy-reset-gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx28-m28cu3.dts b/sys/gnu/dts/arm/imx28-m28cu3.dts index bb5329479c62..9d6c8fe28d74 100644 --- a/sys/gnu/dts/arm/imx28-m28cu3.dts +++ b/sys/gnu/dts/arm/imx28-m28cu3.dts @@ -188,7 +188,7 @@ phy-mode = "rmii"; pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a>; - phy-reset-gpios = <&gpio4 13 0>; + phy-reset-gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx50-evk.dts b/sys/gnu/dts/arm/imx50-evk.dts index dba2d951aa15..98b5faa06e27 100644 --- a/sys/gnu/dts/arm/imx50-evk.dts +++ b/sys/gnu/dts/arm/imx50-evk.dts @@ -53,7 +53,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio4 12 0>; + phy-reset-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx50.dtsi b/sys/gnu/dts/arm/imx50.dtsi index 2a98afcd8a4e..3747d80104f4 100644 --- a/sys/gnu/dts/arm/imx50.dtsi +++ b/sys/gnu/dts/arm/imx50.dtsi @@ -12,6 +12,7 @@ */ #include "imx50-pinfunc.h" +#include #include / { diff --git a/sys/gnu/dts/arm/imx51-apf51.dts b/sys/gnu/dts/arm/imx51-apf51.dts index e88b2a6be079..c83ac1600322 100644 --- a/sys/gnu/dts/arm/imx51-apf51.dts +++ b/sys/gnu/dts/arm/imx51-apf51.dts @@ -36,7 +36,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "mii"; - phy-reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; phy-reset-duration = <1>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx53-mba53.dts b/sys/gnu/dts/arm/imx53-mba53.dts index 2e44d2aba14e..df705ba48897 100644 --- a/sys/gnu/dts/arm/imx53-mba53.dts +++ b/sys/gnu/dts/arm/imx53-mba53.dts @@ -195,7 +195,7 @@ }; &fec { - phy-reset-gpios = <&gpio7 6 0>; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx53-qsb-common.dtsi b/sys/gnu/dts/arm/imx53-qsb-common.dtsi index 40b3e31935d0..683dcbe27cbd 100644 --- a/sys/gnu/dts/arm/imx53-qsb-common.dtsi +++ b/sys/gnu/dts/arm/imx53-qsb-common.dtsi @@ -344,7 +344,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio7 6 0>; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx53-smd.dts b/sys/gnu/dts/arm/imx53-smd.dts index 472f6f0f55b3..33cb64fc8372 100644 --- a/sys/gnu/dts/arm/imx53-smd.dts +++ b/sys/gnu/dts/arm/imx53-smd.dts @@ -273,6 +273,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio7 6 0>; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx53-tqma53.dtsi b/sys/gnu/dts/arm/imx53-tqma53.dtsi index 85972f2201c2..eecdc1c55eef 100644 --- a/sys/gnu/dts/arm/imx53-tqma53.dtsi +++ b/sys/gnu/dts/arm/imx53-tqma53.dtsi @@ -272,7 +272,7 @@ }; eeprom: 24c64@50 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; pagesize = <32>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/imx53-tx53.dtsi b/sys/gnu/dts/arm/imx53-tx53.dtsi index 3a3220141988..7807c1fa1101 100644 --- a/sys/gnu/dts/arm/imx53-tx53.dtsi +++ b/sys/gnu/dts/arm/imx53-tx53.dtsi @@ -201,7 +201,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; phy-handle = <&phy0>; mac-address = [000000000000]; /* placeholder; will be overwritten by bootloader */ status = "okay"; diff --git a/sys/gnu/dts/arm/imx53-voipac-dmm-668.dtsi b/sys/gnu/dts/arm/imx53-voipac-dmm-668.dtsi index 524192cf6a0f..df8dafe2564d 100644 --- a/sys/gnu/dts/arm/imx53-voipac-dmm-668.dtsi +++ b/sys/gnu/dts/arm/imx53-voipac-dmm-668.dtsi @@ -137,7 +137,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio4 2 0>; + phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6dl-gw560x.dts b/sys/gnu/dts/arm/imx6dl-gw560x.dts new file mode 100644 index 000000000000..21bdfaf8df53 --- /dev/null +++ b/sys/gnu/dts/arm/imx6dl-gw560x.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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 file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6qdl-gw560x.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 DualLite/Solo GW560X"; + compatible = "gw,imx6dl-gw560x", "gw,ventana", "fsl,imx6dl"; +}; diff --git a/sys/gnu/dts/arm/imx6dl-riotboard.dts b/sys/gnu/dts/arm/imx6dl-riotboard.dts index 2cb72824e800..29b45f2e64e0 100644 --- a/sys/gnu/dts/arm/imx6dl-riotboard.dts +++ b/sys/gnu/dts/arm/imx6dl-riotboard.dts @@ -94,7 +94,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio3 31 0>; + phy-reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>, <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; fsl,err006687-workaround-present; diff --git a/sys/gnu/dts/arm/imx6dl-sabrelite.dts b/sys/gnu/dts/arm/imx6dl-sabrelite.dts index 2f904527a097..33040761b253 100644 --- a/sys/gnu/dts/arm/imx6dl-sabrelite.dts +++ b/sys/gnu/dts/arm/imx6dl-sabrelite.dts @@ -48,3 +48,8 @@ model = "Freescale i.MX6 DualLite SABRE Lite Board"; compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl"; }; + +&ipu1_csi1_from_ipu1_csi1_mux { + clock-lanes = <0>; + data-lanes = <1 2>; +}; diff --git a/sys/gnu/dts/arm/imx6dl-sabresd.dts b/sys/gnu/dts/arm/imx6dl-sabresd.dts index 1e45f2f9d0b6..9607afe088fc 100644 --- a/sys/gnu/dts/arm/imx6dl-sabresd.dts +++ b/sys/gnu/dts/arm/imx6dl-sabresd.dts @@ -15,3 +15,8 @@ model = "Freescale i.MX6 DualLite SABRE Smart Device Board"; compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl"; }; + +&ipu1_csi1_from_ipu1_csi1_mux { + clock-lanes = <0>; + data-lanes = <1 2>; +}; diff --git a/sys/gnu/dts/arm/imx6dl.dtsi b/sys/gnu/dts/arm/imx6dl.dtsi index 7aa120fbdc71..8475e6cc59ac 100644 --- a/sys/gnu/dts/arm/imx6dl.dtsi +++ b/sys/gnu/dts/arm/imx6dl.dtsi @@ -100,6 +100,11 @@ }; }; + capture-subsystem { + compatible = "fsl,imx-capture-subsystem"; + ports = <&ipu1_csi0>, <&ipu1_csi1>; + }; + display-subsystem { compatible = "fsl,imx-display-subsystem"; ports = <&ipu1_di0>, <&ipu1_di1>; @@ -164,6 +169,116 @@ <&iomuxc 9 207 1>, <&iomuxc 10 206 1>, <&iomuxc 11 133 3>; }; +&gpr { + ipu1_csi0_mux: ipu1_csi0_mux@34 { + compatible = "video-mux"; + mux-controls = <&mux 0>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ipu1_csi0_mux_from_mipi_vc0: endpoint { + remote-endpoint = <&mipi_vc0_to_ipu1_csi0_mux>; + }; + }; + + port@1 { + reg = <1>; + + ipu1_csi0_mux_from_mipi_vc1: endpoint { + remote-endpoint = <&mipi_vc1_to_ipu1_csi0_mux>; + }; + }; + + port@2 { + reg = <2>; + + ipu1_csi0_mux_from_mipi_vc2: endpoint { + remote-endpoint = <&mipi_vc2_to_ipu1_csi0_mux>; + }; + }; + + port@3 { + reg = <3>; + + ipu1_csi0_mux_from_mipi_vc3: endpoint { + remote-endpoint = <&mipi_vc3_to_ipu1_csi0_mux>; + }; + }; + + port@4 { + reg = <4>; + + ipu1_csi0_mux_from_parallel_sensor: endpoint { + }; + }; + + port@5 { + reg = <5>; + + ipu1_csi0_mux_to_ipu1_csi0: endpoint { + remote-endpoint = <&ipu1_csi0_from_ipu1_csi0_mux>; + }; + }; + }; + + ipu1_csi1_mux: ipu1_csi1_mux@34 { + compatible = "video-mux"; + mux-controls = <&mux 1>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ipu1_csi1_mux_from_mipi_vc0: endpoint { + remote-endpoint = <&mipi_vc0_to_ipu1_csi1_mux>; + }; + }; + + port@1 { + reg = <1>; + + ipu1_csi1_mux_from_mipi_vc1: endpoint { + remote-endpoint = <&mipi_vc1_to_ipu1_csi1_mux>; + }; + }; + + port@2 { + reg = <2>; + + ipu1_csi1_mux_from_mipi_vc2: endpoint { + remote-endpoint = <&mipi_vc2_to_ipu1_csi1_mux>; + }; + }; + + port@3 { + reg = <3>; + + ipu1_csi1_mux_from_mipi_vc3: endpoint { + remote-endpoint = <&mipi_vc3_to_ipu1_csi1_mux>; + }; + }; + + port@4 { + reg = <4>; + + ipu1_csi1_mux_from_parallel_sensor: endpoint { + }; + }; + + port@5 { + reg = <5>; + + ipu1_csi1_mux_to_ipu1_csi1: endpoint { + remote-endpoint = <&ipu1_csi1_from_ipu1_csi1_mux>; + }; + }; + }; +}; + &gpt { compatible = "fsl,imx6dl-gpt"; }; @@ -172,6 +287,12 @@ compatible = "fsl,imx6dl-hdmi"; }; +&ipu1_csi1 { + ipu1_csi1_from_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_to_ipu1_csi1>; + }; +}; + &ldb { clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>, @@ -181,6 +302,74 @@ "di0", "di1"; }; +&mipi_csi { + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_vc0_to_ipu1_csi0_mux: endpoint@0 { + remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc0>; + }; + + mipi_vc0_to_ipu1_csi1_mux: endpoint@1 { + remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc0>; + }; + }; + + port@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_vc1_to_ipu1_csi0_mux: endpoint@0 { + remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc1>; + }; + + mipi_vc1_to_ipu1_csi1_mux: endpoint@1 { + remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc1>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_vc2_to_ipu1_csi0_mux: endpoint@0 { + remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc2>; + }; + + mipi_vc2_to_ipu1_csi1_mux: endpoint@1 { + remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc2>; + }; + }; + + port@4 { + reg = <4>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_vc3_to_ipu1_csi0_mux: endpoint@0 { + remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc3>; + }; + + mipi_vc3_to_ipu1_csi1_mux: endpoint@1 { + remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc3>; + }; + }; +}; + +&mux { + mux-reg-masks = <0x34 0x00000007>, /* IPU_CSI0_MUX */ + <0x34 0x00000038>, /* IPU_CSI1_MUX */ + <0x0c 0x0000000c>, /* HDMI_MUX_CTL */ + <0x0c 0x000000c0>, /* LVDS0_MUX_CTL */ + <0x0c 0x00000300>, /* LVDS1_MUX_CTL */ + <0x28 0x00000003>, /* DCIC1_MUX_CTL */ + <0x28 0x0000000c>; /* DCIC2_MUX_CTL */ +}; + &vpu { compatible = "fsl,imx6dl-vpu", "cnm,coda960"; }; diff --git a/sys/gnu/dts/arm/imx6q-ba16.dtsi b/sys/gnu/dts/arm/imx6q-ba16.dtsi index 14fa6b25dc45..5fcb0372d58b 100644 --- a/sys/gnu/dts/arm/imx6q-ba16.dtsi +++ b/sys/gnu/dts/arm/imx6q-ba16.dtsi @@ -321,7 +321,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>; fsl,tx-swing-full = <103>; fsl,tx-swing-low = <103>; status = "okay"; diff --git a/sys/gnu/dts/arm/imx6q-cm-fx6.dts b/sys/gnu/dts/arm/imx6q-cm-fx6.dts index 66cac5328b86..fe6ab0aa34f9 100644 --- a/sys/gnu/dts/arm/imx6q-cm-fx6.dts +++ b/sys/gnu/dts/arm/imx6q-cm-fx6.dts @@ -64,6 +64,14 @@ }; }; + awnh387_pwrseq: pwrseq { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwrseq>; + compatible = "mmc-pwrseq-sd8787"; + powerdown-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>; + }; + reg_pcie_power_on_gpio: regulator-pcie-power-on-gpio { compatible = "regulator-fixed"; regulator-name = "regulator-pcie-power-on-gpio"; @@ -215,7 +223,7 @@ clock-frequency = <100000>; eeprom@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; @@ -304,6 +312,13 @@ >; }; + pinctrl_pwrseq: pwrseqgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x1b0b0 + >; + }; + pinctrl_spdif: spdifgrp { fsl,pins = < MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 @@ -330,6 +345,17 @@ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x130b0 >; }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; }; &pcie { @@ -382,3 +408,18 @@ dr_mode = "otg"; status = "okay"; }; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + mmc-pwrseq = <&awnh387_pwrseq>; + non-removable; + /* + * If the OS probes the Bluetooth AMP function advertised on this bus + * but the firmware in place does not support it, the WiFi/BT module + * gets unresponsive. + * Users who configured their OS properly can enable this node to gain + * WiFi and/or plain Bluetooth support. + */ + status = "disabled"; +}; diff --git a/sys/gnu/dts/arm/imx6q-dmo-edmqmx6.dts b/sys/gnu/dts/arm/imx6q-dmo-edmqmx6.dts index f28883bbe7b1..33eb7f180995 100644 --- a/sys/gnu/dts/arm/imx6q-dmo-edmqmx6.dts +++ b/sys/gnu/dts/arm/imx6q-dmo-edmqmx6.dts @@ -118,7 +118,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio1 25 0>; + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; phy-supply = <&vgen2_1v2_eth>; status = "okay"; }; @@ -435,7 +435,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio4 8 0>; + reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6q-evi.dts b/sys/gnu/dts/arm/imx6q-evi.dts index fd2220aa49e2..1f0f950dc11e 100644 --- a/sys/gnu/dts/arm/imx6q-evi.dts +++ b/sys/gnu/dts/arm/imx6q-evi.dts @@ -135,7 +135,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio1 25 0>; + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>, <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; fsl,err006687-workaround-present; diff --git a/sys/gnu/dts/arm/imx6q-gw5400-a.dts b/sys/gnu/dts/arm/imx6q-gw5400-a.dts index 8e84713f42c0..9dbeea05a949 100644 --- a/sys/gnu/dts/arm/imx6q-gw5400-a.dts +++ b/sys/gnu/dts/arm/imx6q-gw5400-a.dts @@ -19,7 +19,6 @@ /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; i2c0 = &i2c1; i2c1 = &i2c2; i2c2 = &i2c3; @@ -154,7 +153,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>; status = "okay"; }; @@ -347,10 +346,6 @@ &pcie { reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &ssi1 { diff --git a/sys/gnu/dts/arm/imx6q-gw560x.dts b/sys/gnu/dts/arm/imx6q-gw560x.dts new file mode 100644 index 000000000000..735f2bbf1439 --- /dev/null +++ b/sys/gnu/dts/arm/imx6q-gw560x.dts @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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 file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include "imx6qdl-gw560x.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 Dual/Quad GW560X"; + compatible = "gw,imx6q-gw560x", "gw,ventana", "fsl,imx6q"; +}; + +&sata { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/imx6q-novena.dts b/sys/gnu/dts/arm/imx6q-novena.dts index 0fa32b2f3aec..d83cfb6ec598 100644 --- a/sys/gnu/dts/arm/imx6q-novena.dts +++ b/sys/gnu/dts/arm/imx6q-novena.dts @@ -217,7 +217,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet_novena>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; rxc-skew-ps = <3000>; rxdv-skew-ps = <0>; txc-skew-ps = <3000>; @@ -446,7 +446,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie_novena>; - reset-gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio3 29 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6q-sabrelite.dts b/sys/gnu/dts/arm/imx6q-sabrelite.dts index 02a7cdfd57c9..dc51262e7b2f 100644 --- a/sys/gnu/dts/arm/imx6q-sabrelite.dts +++ b/sys/gnu/dts/arm/imx6q-sabrelite.dts @@ -52,3 +52,8 @@ &sata { status = "okay"; }; + +&ipu1_csi1_from_mipi_vc1 { + clock-lanes = <0>; + data-lanes = <1 2>; +}; diff --git a/sys/gnu/dts/arm/imx6q-sabresd.dts b/sys/gnu/dts/arm/imx6q-sabresd.dts index 9cbdfe7a0931..527772b62fee 100644 --- a/sys/gnu/dts/arm/imx6q-sabresd.dts +++ b/sys/gnu/dts/arm/imx6q-sabresd.dts @@ -23,3 +23,8 @@ &sata { status = "okay"; }; + +&ipu1_csi1_from_mipi_vc1 { + clock-lanes = <0>; + data-lanes = <1 2>; +}; diff --git a/sys/gnu/dts/arm/imx6q-utilite-pro.dts b/sys/gnu/dts/arm/imx6q-utilite-pro.dts index d900ad6ec5f8..16d5be1aeb3c 100644 --- a/sys/gnu/dts/arm/imx6q-utilite-pro.dts +++ b/sys/gnu/dts/arm/imx6q-utilite-pro.dts @@ -130,7 +130,7 @@ #size-cells = <0>; eeprom@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; diff --git a/sys/gnu/dts/arm/imx6q-zii-rdu2.dts b/sys/gnu/dts/arm/imx6q-zii-rdu2.dts index b2d346640fd7..6be8a1eea895 100644 --- a/sys/gnu/dts/arm/imx6q-zii-rdu2.dts +++ b/sys/gnu/dts/arm/imx6q-zii-rdu2.dts @@ -41,8 +41,8 @@ /dts-v1/; -#include -#include +#include "imx6q.dtsi" +#include "imx6qdl-zii-rdu2.dtsi" / { model = "ZII RDU2 Board"; diff --git a/sys/gnu/dts/arm/imx6q.dtsi b/sys/gnu/dts/arm/imx6q.dtsi index e9a5d0b8c7b0..90a741732f60 100644 --- a/sys/gnu/dts/arm/imx6q.dtsi +++ b/sys/gnu/dts/arm/imx6q.dtsi @@ -125,7 +125,7 @@ clocks = <&clks IMX6QDL_CLK_OPENVG_AXI>, <&clks IMX6QDL_CLK_GPU2D_CORE>; clock-names = "bus", "core"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; ipu2: ipu@02800000 { @@ -143,10 +143,18 @@ ipu2_csi0: port@0 { reg = <0>; + + ipu2_csi0_from_mipi_vc2: endpoint { + remote-endpoint = <&mipi_vc2_to_ipu2_csi0>; + }; }; ipu2_csi1: port@1 { reg = <1>; + + ipu2_csi1_from_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_to_ipu2_csi1>; + }; }; ipu2_di0: port@2 { @@ -198,6 +206,11 @@ }; }; + capture-subsystem { + compatible = "fsl,imx-capture-subsystem"; + ports = <&ipu1_csi0>, <&ipu1_csi1>, <&ipu2_csi0>, <&ipu2_csi1>; + }; + display-subsystem { compatible = "fsl,imx-display-subsystem"; ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>; @@ -246,6 +259,68 @@ gpio-ranges = <&iomuxc 0 172 9>, <&iomuxc 9 189 2>, <&iomuxc 11 146 3>; }; +&gpr { + ipu1_csi0_mux { + compatible = "video-mux"; + mux-controls = <&mux 0>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ipu1_csi0_mux_from_mipi_vc0: endpoint { + remote-endpoint = <&mipi_vc0_to_ipu1_csi0_mux>; + }; + }; + + port@1 { + reg = <1>; + + ipu1_csi0_mux_from_parallel_sensor: endpoint { + }; + }; + + port@2 { + reg = <2>; + + ipu1_csi0_mux_to_ipu1_csi0: endpoint { + remote-endpoint = <&ipu1_csi0_from_ipu1_csi0_mux>; + }; + }; + }; + + ipu2_csi1_mux { + compatible = "video-mux"; + mux-controls = <&mux 1>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ipu2_csi1_mux_from_mipi_vc3: endpoint { + remote-endpoint = <&mipi_vc3_to_ipu2_csi1_mux>; + }; + }; + + port@1 { + reg = <1>; + + ipu2_csi1_mux_from_parallel_sensor: endpoint { + }; + }; + + port@2 { + reg = <2>; + + ipu2_csi1_mux_to_ipu2_csi1: endpoint { + remote-endpoint = <&ipu2_csi1_from_ipu2_csi1_mux>; + }; + }; + }; +}; + &hdmi { compatible = "fsl,imx6q-hdmi"; @@ -266,6 +341,12 @@ }; }; +&ipu1_csi1 { + ipu1_csi1_from_mipi_vc1: endpoint { + remote-endpoint = <&mipi_vc1_to_ipu1_csi1>; + }; +}; + &ldb { clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>, @@ -312,6 +393,40 @@ }; }; +&mipi_csi { + port@1 { + reg = <1>; + + mipi_vc0_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc0>; + }; + }; + + port@2 { + reg = <2>; + + mipi_vc1_to_ipu1_csi1: endpoint { + remote-endpoint = <&ipu1_csi1_from_mipi_vc1>; + }; + }; + + port@3 { + reg = <3>; + + mipi_vc2_to_ipu2_csi0: endpoint { + remote-endpoint = <&ipu2_csi0_from_mipi_vc2>; + }; + }; + + port@4 { + reg = <4>; + + mipi_vc3_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_mipi_vc3>; + }; + }; +}; + &mipi_dsi { ports { port@2 { @@ -332,6 +447,16 @@ }; }; +&mux { + mux-reg-masks = <0x04 0x00080000>, /* MIPI_IPU1_MUX */ + <0x04 0x00100000>, /* MIPI_IPU2_MUX */ + <0x0c 0x0000000c>, /* HDMI_MUX_CTL */ + <0x0c 0x000000c0>, /* LVDS0_MUX_CTL */ + <0x0c 0x00000300>, /* LVDS1_MUX_CTL */ + <0x28 0x00000003>, /* DCIC1_MUX_CTL */ + <0x28 0x0000000c>; /* DCIC2_MUX_CTL */ +}; + &vpu { compatible = "fsl,imx6q-vpu", "cnm,coda960"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-apf6dev.dtsi b/sys/gnu/dts/arm/imx6qdl-apf6dev.dtsi index 550e100e85fc..9cd2a7477ed7 100644 --- a/sys/gnu/dts/arm/imx6qdl-apf6dev.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-apf6dev.dtsi @@ -232,7 +232,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio6 2 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio6 2 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-aristainetos.dtsi b/sys/gnu/dts/arm/imx6qdl-aristainetos.dtsi index b2debc0aa720..7d64075204ae 100644 --- a/sys/gnu/dts/arm/imx6qdl-aristainetos.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-aristainetos.dtsi @@ -118,7 +118,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-aristainetos2.dtsi b/sys/gnu/dts/arm/imx6qdl-aristainetos2.dtsi index ec68f1cace31..1b1872873207 100644 --- a/sys/gnu/dts/arm/imx6qdl-aristainetos2.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-aristainetos2.dtsi @@ -320,7 +320,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio7 18 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio7 18 GPIO_ACTIVE_LOW>; txd0-skew-ps = <0>; txd1-skew-ps = <0>; txd2-skew-ps = <0>; @@ -335,7 +335,7 @@ }; &pcie { - reset-gpio = <&gpio2 16 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio2 16 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-colibri.dtsi b/sys/gnu/dts/arm/imx6qdl-colibri.dtsi index e8078758f26c..ad84eddb6836 100644 --- a/sys/gnu/dts/arm/imx6qdl-colibri.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-colibri.dtsi @@ -254,6 +254,7 @@ clocks = <&clks IMX6QDL_CLK_CKO>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_3p3v>; + lrclk-strength = <3>; }; /* STMPE811 touch screen controller */ diff --git a/sys/gnu/dts/arm/imx6qdl-gw53xx.dtsi b/sys/gnu/dts/arm/imx6qdl-gw53xx.dtsi index a208e7e0dc6e..5bc6ed1a5b35 100644 --- a/sys/gnu/dts/arm/imx6qdl-gw53xx.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-gw53xx.dtsi @@ -14,7 +14,6 @@ / { /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; led0 = &led0; led1 = &led1; led2 = &led2; @@ -342,10 +341,6 @@ pinctrl-0 = <&pinctrl_pcie>; reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &pwm2 { diff --git a/sys/gnu/dts/arm/imx6qdl-gw54xx.dtsi b/sys/gnu/dts/arm/imx6qdl-gw54xx.dtsi index 968fda94d14b..66fcf838e964 100644 --- a/sys/gnu/dts/arm/imx6qdl-gw54xx.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-gw54xx.dtsi @@ -14,7 +14,6 @@ / { /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; led0 = &led0; led1 = &led1; led2 = &led2; @@ -379,10 +378,6 @@ pinctrl-0 = <&pinctrl_pcie>; reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &pwm1 { diff --git a/sys/gnu/dts/arm/imx6qdl-gw560x.dtsi b/sys/gnu/dts/arm/imx6qdl-gw560x.dtsi new file mode 100644 index 000000000000..d894dde6e85d --- /dev/null +++ b/sys/gnu/dts/arm/imx6qdl-gw560x.dtsi @@ -0,0 +1,749 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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 file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/ { + /* these are used by bootloader for disabling nodes */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + ssi0 = &ssi1; + usb0 = &usbh1; + usb1 = &usbotg; + }; + + chosen { + stdout-path = &uart2; + }; + + backlight-display { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 5000000>; + brightness-levels = < + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 + >; + default-brightness-level = <100>; + }; + + backlight-keypad { + compatible = "gpio-backlight"; + gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; + default-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led0: user1 { + label = "user1"; + gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + led1: user2 { + label = "user2"; + gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ + default-state = "off"; + }; + + led2: user3 { + label = "user3"; + gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ + default-state = "off"; + }; + }; + + memory@10000000 { + reg = <0x10000000 0x40000000>; + }; + + pps { + compatible = "pps-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_5p0v: regulator-5p0v { + compatible = "regulator-fixed"; + regulator-name = "5P0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_12p0v: regulator-12p0v { + compatible = "regulator-fixed"; + regulator-name = "12P0V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_1p4v: regulator-vddsoc { + compatible = "regulator-fixed"; + regulator-name = "vdd_soc"; + regulator-min-microvolt = <1400000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + sound { + compatible = "fsl,imx6q-ventana-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "sgtl5000-audio"; + ssi-controller = <&ssi1>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&ecspi3 { + cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3>; + status = "okay"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan>; + status = "okay"; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c3>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + eeprom1: eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + eeprom2: eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; + + eeprom3: eeprom@52 { + compatible = "atmel,24c02"; + reg = <0x52>; + pagesize = <16>; + }; + + eeprom4: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; + + pca9555: gpio@23 { + compatible = "nxp,pca9555"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + }; + + ds1672: rtc@68 { + compatible = "dallas,ds1672"; + reg = <0x68>; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6QDL_CLK_CKO>; + VDDA-supply = <®_1p8v>; + VDDIO-supply = <®_3p3v>; + }; + + tca8418: keypad@34 { + compatible = "ti,tca8418"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_keypad>; + reg = <0x34>; + interrupt-parent = <&gpio5>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + linux,keymap = < MATRIX_KEY(0x00, 0x01, BTN_0) + MATRIX_KEY(0x00, 0x00, BTN_1) + MATRIX_KEY(0x01, 0x01, BTN_2) + MATRIX_KEY(0x01, 0x00, BTN_3) + MATRIX_KEY(0x02, 0x00, BTN_4) + MATRIX_KEY(0x00, 0x03, BTN_5) + MATRIX_KEY(0x00, 0x02, BTN_6) + MATRIX_KEY(0x01, 0x03, BTN_7) + MATRIX_KEY(0x01, 0x02, BTN_8) + MATRIX_KEY(0x02, 0x02, BTN_9) + >; + keypad,num-rows = <4>; + keypad,num-columns = <4>; + }; + + ltc3676: pmic@3c { + compatible = "lltc,ltc3676"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + reg = <0x3c>; + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + + regulators { + /* VDD_DDR (1+R1/R2 = 2.105) */ + reg_vdd_ddr: sw2 { + regulator-name = "vddddr"; + regulator-min-microvolt = <868310>; + regulator-max-microvolt = <1684000>; + lltc,fb-voltage-divider = <221000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_ARM (1+R1/R2 = 1.931) */ + reg_vdd_arm: sw3 { + regulator-name = "vddarm"; + regulator-min-microvolt = <796551>; + regulator-max-microvolt = <1544827>; + lltc,fb-voltage-divider = <243000 261000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <®_vdd_arm>; + }; + + /* VDD_1P8 (1+R1/R2 = 2.505): GPS/VideoIn/ENET-PHY */ + reg_1p8v: sw4 { + regulator-name = "vdd1p8"; + regulator-min-microvolt = <1033310>; + regulator-max-microvolt = <2004000>; + lltc,fb-voltage-divider = <301000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_1P0 (1+R1/R2 = 1.39): PCIe/ENET-PHY */ + reg_1p0v: ldo2 { + regulator-name = "vdd1p0"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1050000>; + lltc,fb-voltage-divider = <78700 200000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_AUD_1P8: Audio codec */ + reg_aud_1p8v: ldo3 { + regulator-name = "vdd1p8a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + /* VDD_HIGH (1+R1/R2 = 4.17) */ + reg_3p0v: ldo4 { + regulator-name = "vdd3p0"; + regulator-min-microvolt = <3023250>; + regulator-max-microvolt = <3023250>; + lltc,fb-voltage-divider = <634000 200000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + egalax_ts: touchscreen@4 { + compatible = "eeti,egalax_ts"; + reg = <0x04>; + interrupt-parent = <&gpio5>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + wakeup-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + }; +}; + +&ldb { + fsl,dual-channel; + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: hsd100pxn1 { + clock-frequency = <65000000>; + hactive = <1024>; + vactive = <768>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio4 31 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */ + status = "disabled"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */ + status = "disabled"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + uart-has-rtscts; + rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; + vmmc-supply = <®_3p3v>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + /* AUD4 */ + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */ + /* AUD6 */ + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x130b0 + MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x130b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x130b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x130b0 + >; + }; + + pinctrl_ecspi3: escpi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1 + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1 + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x100b1 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x4001b0b0 /* PHY_RST# */ + >; + }; + + pinctrl_flexcan: flexcangrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b1 + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b1 + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x4001b0b0 /* CAN_STBY */ + >; + }; + + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0 + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x4001b0b0 /* DIOI2C_DIS# */ + MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x0001b0b0 /* LVDS_TOUCH_IRQ# */ + MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x0001b0b0 /* LVDS_BACKEN */ + >; + }; + + pinctrl_keypad: keypadgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x0001b0b0 /* KEYPAD_IRQ# */ + MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x0001b0b0 /* KEYPAD_LED_EN */ + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT10__GPIO4_IO31 0x1b0b0 /* PCI_RST# */ + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x4001b0b0 /* PCIESKT_WDIS# */ + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0001b0b0 /* PMIC_IRQ# */ + >; + }; + + pinctrl_pps: ppsgrp { + fsl,pins = < + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x4001b0b1 /* TEN */ + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x4001b0b0 /* USBHUB_RST# */ + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* PWR_EN */ + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0 /* OC */ + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170f9 + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x170f9 + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x170f9 + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x170f9 + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x170f9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x17059 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x17059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x170b9 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x170f9 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x170f9 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x1b0b0 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx6qdl-microsom-ar8035.dtsi b/sys/gnu/dts/arm/imx6qdl-microsom-ar8035.dtsi index a9b207751a02..900e8c781f91 100644 --- a/sys/gnu/dts/arm/imx6qdl-microsom-ar8035.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-microsom-ar8035.dtsi @@ -46,7 +46,7 @@ pinctrl-0 = <&pinctrl_microsom_enet_ar8035>; phy-mode = "rgmii"; phy-reset-duration = <2>; - phy-reset-gpios = <&gpio4 15 0>; + phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-nitrogen6_max.dtsi b/sys/gnu/dts/arm/imx6qdl-nitrogen6_max.dtsi index bad3c9f9eeac..b63134e3b51a 100644 --- a/sys/gnu/dts/arm/imx6qdl-nitrogen6_max.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-nitrogen6_max.dtsi @@ -408,7 +408,7 @@ }; rtc: rtc@68 { - compatible = "st,rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rv4162>; reg = <0x68>; diff --git a/sys/gnu/dts/arm/imx6qdl-nitrogen6_som2.dtsi b/sys/gnu/dts/arm/imx6qdl-nitrogen6_som2.dtsi index 559da17297ef..a24e4f1911ab 100644 --- a/sys/gnu/dts/arm/imx6qdl-nitrogen6_som2.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-nitrogen6_som2.dtsi @@ -326,7 +326,7 @@ }; rtc@68 { - compatible = "st,rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rv4162>; reg = <0x68>; @@ -507,7 +507,7 @@ pinctrl_pcie: pciegrp { fsl,pins = < /* PCIe reset */ - MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x030b0 + MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x030b0 MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x030b0 >; }; @@ -668,7 +668,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>; + reset-gpio = <&gpio3 0 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-nitrogen6x.dtsi b/sys/gnu/dts/arm/imx6qdl-nitrogen6x.dtsi index 70772ebadd4d..f22e5879340b 100644 --- a/sys/gnu/dts/arm/imx6qdl-nitrogen6x.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-nitrogen6x.dtsi @@ -271,7 +271,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio1 27 0>; + phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; txen-skew-ps = <0>; txc-skew-ps = <3000>; rxdv-skew-ps = <0>; diff --git a/sys/gnu/dts/arm/imx6qdl-phytec-pfla02.dtsi b/sys/gnu/dts/arm/imx6qdl-phytec-pfla02.dtsi index 6e5cb6a99550..d81b0078a100 100644 --- a/sys/gnu/dts/arm/imx6qdl-phytec-pfla02.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-phytec-pfla02.dtsi @@ -374,7 +374,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio4 17 0>; + reset-gpio = <&gpio4 17 GPIO_ACTIVE_LOW>; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/imx6qdl-sabreauto.dtsi b/sys/gnu/dts/arm/imx6qdl-sabreauto.dtsi index a2a714d199ea..6a7594e5d183 100644 --- a/sys/gnu/dts/arm/imx6qdl-sabreauto.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-sabreauto.dtsi @@ -108,6 +108,76 @@ default-brightness-level = <7>; status = "okay"; }; + + i2cmux { + compatible = "i2c-mux-gpio"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3mux>; + mux-gpios = <&gpio5 4 0>; + i2c-parent = <&i2c3>; + idle-state = <0>; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + adv7180: camera@21 { + compatible = "adi,adv7180"; + reg = <0x21>; + powerdown-gpios = <&max7310_b 2 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio1>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; + + max7310_a: gpio@30 { + compatible = "maxim,max7310"; + reg = <0x30>; + gpio-controller; + #gpio-cells = <2>; + }; + + max7310_b: gpio@32 { + compatible = "maxim,max7310"; + reg = <0x32>; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_max7310>; + reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; + + max7310_c: gpio@34 { + compatible = "maxim,max7310"; + reg = <0x34>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + }; +}; + +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi0_mux>; + bus-width = <8>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; }; &clks { @@ -290,27 +360,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; - - max7310_a: gpio@30 { - compatible = "maxim,max7310"; - reg = <0x30>; - gpio-controller; - #gpio-cells = <2>; - }; - - max7310_b: gpio@32 { - compatible = "maxim,max7310"; - reg = <0x32>; - gpio-controller; - #gpio-cells = <2>; - }; - - max7310_c: gpio@34 { - compatible = "maxim,max7310"; - reg = <0x34>; - gpio-controller; - #gpio-cells = <2>; - }; }; &iomuxc { @@ -418,12 +467,52 @@ >; }; + pinctrl_i2c3mux: i2c3muxgrp { + fsl,pins = < + MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x0b0b1 + >; + }; + + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + >; + }; + + pinctrl_max7310: max7310grp { + fsl,pins = < + MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0 + >; + }; + pinctrl_pwm3: pwm1grp { fsl,pins = < MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 >; }; + pinctrl_gpt_input_capture0: gptinputcapture0grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT0__GPT_CAPTURE1 0x1b0b0 + >; + }; + + pinctrl_gpt_input_capture1: gptinputcapture1grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT1__GPT_CAPTURE2 0x1b0b0 + >; + }; + pinctrl_spdif: spdifgrp { fsl,pins = < MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0 diff --git a/sys/gnu/dts/arm/imx6qdl-sabrelite.dtsi b/sys/gnu/dts/arm/imx6qdl-sabrelite.dtsi index 84131794e97b..afe7449c47da 100644 --- a/sys/gnu/dts/arm/imx6qdl-sabrelite.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-sabrelite.dtsi @@ -39,6 +39,8 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ + +#include #include #include @@ -94,6 +96,42 @@ pinctrl-0 = <&pinctrl_can_xcvr>; gpio = <&gpio1 2 GPIO_ACTIVE_LOW>; }; + + reg_1p5v: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "1P5V"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + reg_1p8v: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_2p8v: regulator@6 { + compatible = "regulator-fixed"; + reg = <6>; + regulator-name = "2P8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + }; + + mipi_xclk: mipi_xclk { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <22000000>; + clock-output-names = "mipi_pwm3"; + pwms = <&pwm3 0 45>; /* 1 / 45 ns = 22 MHz */ + status = "okay"; }; gpio-keys { @@ -220,6 +258,22 @@ }; }; +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; + data-shift = <12>; /* Lines 19:12 used */ + hsync-active = <1>; + vync-active = <1>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&ov5642_to_ipu1_csi0_mux>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; +}; + &audmux { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_audmux>; @@ -270,9 +324,6 @@ txd1-skew-ps = <0>; txd2-skew-ps = <0>; txd3-skew-ps = <0>; - interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>, - <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; - fsl,err006687-workaround-present; status = "okay"; }; @@ -301,6 +352,53 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; + + ov5640: camera@40 { + compatible = "ovti,ov5640"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ov5640>; + reg = <0x40>; + clocks = <&mipi_xclk>; + clock-names = "xclk"; + DOVDD-supply = <®_1p8v>; + AVDD-supply = <®_2p8v>; + DVDD-supply = <®_1p5v>; + reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* NANDF_D5 */ + powerdown-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* NANDF_WP_B */ + + port { + #address-cells = <1>; + #size-cells = <0>; + + ov5640_to_mipi_csi2: endpoint { + remote-endpoint = <&mipi_csi2_in>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + }; + + ov5642: camera@42 { + compatible = "ovti,ov5642"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ov5642>; + clocks = <&clks IMX6QDL_CLK_CKO2>; + clock-names = "xclk"; + reg = <0x42>; + reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + powerdown-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + gp-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; + status = "disabled"; + + port { + ov5642_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; }; &i2c3 { @@ -373,7 +471,6 @@ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 /* Phy reset */ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x000b0 - MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1 >; }; @@ -415,6 +512,23 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x1b0b0 + >; + }; + pinctrl_j15: j15grp { fsl,pins = < MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10 @@ -448,6 +562,22 @@ >; }; + pinctrl_ov5640: ov5640grp { + fsl,pins = < + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000b0 + MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x0b0b0 + >; + }; + + pinctrl_ov5642: ov5642grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0 + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b0 + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x130b0 + MX6QDL_PAD_GPIO_3__CCM_CLKO2 0x000b0 + >; + }; + pinctrl_pwm1: pwm1grp { fsl,pins = < MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1 @@ -602,3 +732,17 @@ vmmc-supply = <®_3p3v>; status = "okay"; }; + +&mipi_csi { + status = "okay"; + + port@0 { + reg = <0>; + + mipi_csi2_in: endpoint { + remote-endpoint = <&ov5640_to_mipi_csi2>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi b/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi index 58055ceec6dc..b72b6fa47580 100644 --- a/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-sabresd.dtsi @@ -10,6 +10,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include #include #include @@ -146,6 +147,36 @@ }; }; +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; + data-shift = <12>; /* Lines 19:12 used */ + hsync-active = <1>; + vsync-active = <1>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&ov5642_to_ipu1_csi0_mux>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; +}; + +&mipi_csi { + status = "okay"; + + port@0 { + reg = <0>; + + mipi_csi2_in: endpoint { + remote-endpoint = <&ov5640_to_mipi_csi2>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; +}; + &audmux { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_audmux>; @@ -178,7 +209,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio1 25 0>; + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; status = "okay"; }; @@ -213,7 +244,32 @@ 0x8014 /* 4:FN_DMICCDAT */ 0x0000 /* 5:Default */ >; - }; + }; + + ov5642: camera@3c { + compatible = "ovti,ov5642"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ov5642>; + clocks = <&clks IMX6QDL_CLK_CKO>; + clock-names = "xclk"; + reg = <0x3c>; + DOVDD-supply = <&vgen4_reg>; /* 1.8v */ + AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3 + rev B board is VGEN5 */ + DVDD-supply = <&vgen2_reg>; /* 1.5v*/ + powerdown-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + status = "disabled"; + + port { + ov5642_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; }; &i2c2 { @@ -222,6 +278,32 @@ pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; + ov5640: camera@3c { + compatible = "ovti,ov5640"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ov5640>; + reg = <0x3c>; + clocks = <&clks IMX6QDL_CLK_CKO>; + clock-names = "xclk"; + DOVDD-supply = <&vgen4_reg>; /* 1.8v */ + AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3 + rev B board is VGEN5 */ + DVDD-supply = <&vgen2_reg>; /* 1.5v*/ + powerdown-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + ov5640_to_mipi_csi2: endpoint { + remote-endpoint = <&mipi_csi2_in>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + }; + pmic: pfuze100@08 { compatible = "fsl,pfuze100"; reg = <0x08>; @@ -425,6 +507,36 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + >; + }; + + pinctrl_ov5640: ov5640grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT2__GPIO1_IO19 0x1b0b0 + MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x1b0b0 + >; + }; + + pinctrl_ov5642: ov5642grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0 + MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b0 + >; + }; + pinctrl_pcie: pciegrp { fsl,pins = < MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 diff --git a/sys/gnu/dts/arm/imx6qdl-tx6.dtsi b/sys/gnu/dts/arm/imx6qdl-tx6.dtsi index 1691714f13a2..c6bec97fbeaf 100644 --- a/sys/gnu/dts/arm/imx6qdl-tx6.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-tx6.dtsi @@ -133,8 +133,7 @@ regulator-max-microvolt = <3300000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan_xcvr>; - gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; - enable-active-low; + gpio = <&gpio4 21 GPIO_ACTIVE_LOW>; }; reg_lcd0_pwr: regulator-lcd0-pwr { @@ -249,7 +248,7 @@ <&clks IMX6QDL_CLK_ENET_REF>; clock-names = "ipg", "ahb", "ptp", "enet_out"; phy-mode = "rmii"; - phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; phy-handle = <&etnphy>; phy-supply = <®_3v3_etn>; status = "okay"; diff --git a/sys/gnu/dts/arm/imx6qdl-wandboard.dtsi b/sys/gnu/dts/arm/imx6qdl-wandboard.dtsi index 82dc5744ae19..b4fa7f1d63da 100644 --- a/sys/gnu/dts/arm/imx6qdl-wandboard.dtsi +++ b/sys/gnu/dts/arm/imx6qdl-wandboard.dtsi @@ -88,6 +88,7 @@ clocks = <&clks IMX6QDL_CLK_CKO>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_3p3v>; + lrclk-strength = <3>; }; }; @@ -208,7 +209,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii"; - phy-reset-gpios = <&gpio3 29 0>; + phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>, <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; fsl,err006687-workaround-present; diff --git a/sys/gnu/dts/arm/imx6qdl.dtsi b/sys/gnu/dts/arm/imx6qdl.dtsi index e426faa9c243..a9723b94bafa 100644 --- a/sys/gnu/dts/arm/imx6qdl.dtsi +++ b/sys/gnu/dts/arm/imx6qdl.dtsi @@ -156,7 +156,7 @@ <&clks IMX6QDL_CLK_GPU3D_CORE>, <&clks IMX6QDL_CLK_GPU3D_SHADER>; clock-names = "bus", "core", "shader"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; gpu_2d: gpu@00134000 { @@ -166,7 +166,7 @@ clocks = <&clks IMX6QDL_CLK_GPU2D_AXI>, <&clks IMX6QDL_CLK_GPU2D_CORE>; clock-names = "bus", "core"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; timer@00a00600 { @@ -434,7 +434,7 @@ clocks = <&clks IMX6QDL_CLK_VPU_AXI>, <&clks IMX6QDL_CLK_MMDC_CH0_AXI>; clock-names = "per", "ahb"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; resets = <&src 1>; iram = <&ocram>; }; @@ -644,6 +644,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -658,6 +659,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -672,6 +674,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2875000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { @@ -797,19 +800,39 @@ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>, <0 90 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&intc>; - pu-supply = <®_pu>; - clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, - <&clks IMX6QDL_CLK_GPU3D_SHADER>, - <&clks IMX6QDL_CLK_GPU2D_CORE>, - <&clks IMX6QDL_CLK_GPU2D_AXI>, - <&clks IMX6QDL_CLK_OPENVG_AXI>, - <&clks IMX6QDL_CLK_VPU_AXI>; - #power-domain-cells = <1>; + clocks = <&clks IMX6QDL_CLK_IPG>; + clock-names = "ipg"; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + power-domain@0 { + reg = <0>; + #power-domain-cells = <0>; + }; + pd_pu: power-domain@1 { + reg = <1>; + #power-domain-cells = <0>; + power-supply = <®_pu>; + clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, + <&clks IMX6QDL_CLK_GPU3D_SHADER>, + <&clks IMX6QDL_CLK_GPU2D_CORE>, + <&clks IMX6QDL_CLK_GPU2D_AXI>, + <&clks IMX6QDL_CLK_OPENVG_AXI>, + <&clks IMX6QDL_CLK_VPU_AXI>; + }; + }; }; gpr: iomuxc-gpr@020e0000 { - compatible = "fsl,imx6q-iomuxc-gpr", "syscon"; + compatible = "fsl,imx6q-iomuxc-gpr", "syscon", "simple-mfd"; reg = <0x020e0000 0x38>; + + mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + }; }; iomuxc: iomuxc@020e0000 { @@ -1135,7 +1158,16 @@ }; mipi_csi: mipi@021dc000 { + compatible = "fsl,imx6-mipi-csi2"; reg = <0x021dc000 0x4000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 100 0x04>, <0 101 0x04>; + clocks = <&clks IMX6QDL_CLK_HSI_TX>, + <&clks IMX6QDL_CLK_VIDEO_27M>, + <&clks IMX6QDL_CLK_EIM_PODF>; + clock-names = "dphy", "ref", "pix"; + status = "disabled"; }; mipi_dsi: mipi@021e0000 { @@ -1237,6 +1269,10 @@ ipu1_csi0: port@0 { reg = <0>; + + ipu1_csi0_from_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_to_ipu1_csi0>; + }; }; ipu1_csi1: port@1 { diff --git a/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts b/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts index 882b3bd97e07..547a76677ab3 100644 --- a/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts +++ b/sys/gnu/dts/arm/imx6qp-zii-rdu2.dts @@ -41,8 +41,8 @@ /dts-v1/; -#include -#include +#include "imx6qp.dtsi" +#include "imx6qdl-zii-rdu2.dtsi" / { model = "ZII RDU2+ Board"; diff --git a/sys/gnu/dts/arm/imx6qp.dtsi b/sys/gnu/dts/arm/imx6qp.dtsi index 59453f2ac4ba..299d863690c5 100644 --- a/sys/gnu/dts/arm/imx6qp.dtsi +++ b/sys/gnu/dts/arm/imx6qp.dtsi @@ -120,6 +120,10 @@ <0 119 IRQ_TYPE_LEVEL_HIGH>; }; +&gpc { + compatible = "fsl,imx6qp-gpc", "fsl,imx6q-gpc"; +}; + &ipu1 { compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; fsl,prg = <&prg1>; diff --git a/sys/gnu/dts/arm/imx6sl.dtsi b/sys/gnu/dts/arm/imx6sl.dtsi index cc9572ea2860..3243af4a9984 100644 --- a/sys/gnu/dts/arm/imx6sl.dtsi +++ b/sys/gnu/dts/arm/imx6sl.dtsi @@ -530,6 +530,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -544,6 +545,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -558,6 +560,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2850000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/sys/gnu/dts/arm/imx6sx-nitrogen6sx.dts b/sys/gnu/dts/arm/imx6sx-nitrogen6sx.dts index 802da45aa551..c5578d1c1ee4 100644 --- a/sys/gnu/dts/arm/imx6sx-nitrogen6sx.dts +++ b/sys/gnu/dts/arm/imx6sx-nitrogen6sx.dts @@ -296,7 +296,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio4 10 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio4 10 GPIO_ACTIVE_LOW>; status = "okay"; }; @@ -374,7 +374,7 @@ cap-sdio-irq; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio7>; diff --git a/sys/gnu/dts/arm/imx6sx-sdb.dts b/sys/gnu/dts/arm/imx6sx-sdb.dts index d71da30c9cff..c0139d7e497a 100644 --- a/sys/gnu/dts/arm/imx6sx-sdb.dts +++ b/sys/gnu/dts/arm/imx6sx-sdb.dts @@ -128,3 +128,11 @@ reg = <1>; }; }; + +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_soc { + vin-supply = <&sw1a_reg>; +}; diff --git a/sys/gnu/dts/arm/imx6sx.dtsi b/sys/gnu/dts/arm/imx6sx.dtsi index 3f1416be4c36..f16b9df9d0c6 100644 --- a/sys/gnu/dts/arm/imx6sx.dtsi +++ b/sys/gnu/dts/arm/imx6sx.dtsi @@ -587,6 +587,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -601,6 +602,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -615,6 +617,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2875000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/sys/gnu/dts/arm/imx6ul-opos6ul.dtsi b/sys/gnu/dts/arm/imx6ul-opos6ul.dtsi index 51095df33a90..aec5ccce0321 100644 --- a/sys/gnu/dts/arm/imx6ul-opos6ul.dtsi +++ b/sys/gnu/dts/arm/imx6ul-opos6ul.dtsi @@ -120,7 +120,7 @@ #address-cells = <1>; #size-cells = <0>; - brcmf: bcrmf@1 { + brcmf: wifi@1 { compatible = "brcm,bcm4329-fmac"; reg = <1>; interrupt-parent = <&gpio2>; diff --git a/sys/gnu/dts/arm/imx6ul-tx6ul-mainboard.dts b/sys/gnu/dts/arm/imx6ul-tx6ul-mainboard.dts index 7c5dd1b316ca..28d055e3f301 100644 --- a/sys/gnu/dts/arm/imx6ul-tx6ul-mainboard.dts +++ b/sys/gnu/dts/arm/imx6ul-tx6ul-mainboard.dts @@ -78,7 +78,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_mdio &pinctrl_etnphy1_rst>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; phy-supply = <®_3v3_etn>; phy-handle = <&etnphy1>; status = "okay"; diff --git a/sys/gnu/dts/arm/imx6ul-tx6ul.dtsi b/sys/gnu/dts/arm/imx6ul-tx6ul.dtsi index c784a0b75ca0..ec745eb3b6a8 100644 --- a/sys/gnu/dts/arm/imx6ul-tx6ul.dtsi +++ b/sys/gnu/dts/arm/imx6ul-tx6ul.dtsi @@ -173,8 +173,7 @@ regulator-max-microvolt = <3300000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan_xcvr>; - gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>; - enable-active-low; + gpio = <&gpio3 5 GPIO_ACTIVE_LOW>; }; reg_lcd_pwr: regulator-lcdpwr { @@ -308,7 +307,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1_mdio &pinctrl_etnphy0_rst>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; phy-supply = <®_3v3_etn>; phy-handle = <&etnphy0>; status = "okay"; @@ -343,7 +342,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2 &pinctrl_etnphy1_rst>; phy-mode = "rmii"; - phy-reset-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>; + phy-reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; phy-supply = <®_3v3_etn>; phy-handle = <&etnphy1>; status = "disabled"; diff --git a/sys/gnu/dts/arm/imx6ul.dtsi b/sys/gnu/dts/arm/imx6ul.dtsi index b9d7d2d09402..6da2b77edd46 100644 --- a/sys/gnu/dts/arm/imx6ul.dtsi +++ b/sys/gnu/dts/arm/imx6ul.dtsi @@ -542,6 +542,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/sys/gnu/dts/arm/imx7-colibri.dtsi b/sys/gnu/dts/arm/imx7-colibri.dtsi index 2d87489f9105..d7753f79937a 100644 --- a/sys/gnu/dts/arm/imx7-colibri.dtsi +++ b/sys/gnu/dts/arm/imx7-colibri.dtsi @@ -43,7 +43,7 @@ / { bl: backlight { compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000>; + pwms = <&pwm1 0 5000000 0>; }; reg_module_3v3: regulator-module-3v3 { diff --git a/sys/gnu/dts/arm/imx7d-nitrogen7.dts b/sys/gnu/dts/arm/imx7d-nitrogen7.dts index 5d98e2b5d54b..e7998308861f 100644 --- a/sys/gnu/dts/arm/imx7d-nitrogen7.dts +++ b/sys/gnu/dts/arm/imx7d-nitrogen7.dts @@ -67,7 +67,7 @@ backlight-j20 { compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000>; + pwms = <&pwm1 0 5000000 0>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; status = "okay"; @@ -279,7 +279,7 @@ status = "okay"; rtc@68 { - compatible = "rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2_rv4162>; reg = <0x68>; @@ -738,7 +738,7 @@ pinctrl_wdog1: wdog1grp { fsl,pins = < - MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG_B 0x75 + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x75 >; }; }; diff --git a/sys/gnu/dts/arm/imx7d-pico.dts b/sys/gnu/dts/arm/imx7d-pico.dts new file mode 100644 index 000000000000..e78c2c9cc28a --- /dev/null +++ b/sys/gnu/dts/arm/imx7d-pico.dts @@ -0,0 +1,403 @@ +/* + * Copyright 2017 NXP + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx7d.dtsi" + +/ { + model = "Technexion Pico i.MX7D Board"; + compatible = "technexion,imx7d-pico", "fsl,imx7d"; + + memory { + reg = <0x80000000 0x80000000>; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_usb_otg1_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 5 GPIO_ACTIVE_LOW>; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_vref_1v8: regulator-vref-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vref-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx7-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + }; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>, + <&clks IMX7D_ENET1_TIME_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + assigned-clock-rates = <0>, <100000000>; + phy-mode = "rgmii"; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + status = "okay"; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + codec: sgtl5000@0a { + #sound-dai-cells = <0>; + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_vref_1v8>; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + pmic: pfuze3000@08 { + compatible = "fsl,pfuze3000"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1a { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + /* use sw1c_reg to align with pfuze100/pfuze200 */ + sw1c_reg: sw1b { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1475000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen2_reg: vldo2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vccsd { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen4_reg: v33 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen5_reg: vldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <24576000>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + assigned-clocks = <&clks IMX7D_UART5_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>; + status = "okay"; +}; + +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; + status = "okay"; +}; + +&usbotg2 { + vbus-supply = <®_usb_otg2_vbus>; + dr_mode = "host"; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>; + assigned-clock-rates = <400000000>; + bus-width = <8>; + no-1-8-v; + fsl,tuning-step = <2>; + non-removable; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_enet1: enet1grp { + fsl,pins = < + MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x3 + MX7D_PAD_SD2_WP__ENET1_MDC 0x3 + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1 + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1 + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1 + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1 + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1 + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1 + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1 + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1 + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1 + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1 + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1 + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX7D_PAD_UART1_TX_DATA__I2C1_SDA 0x4000007f + MX7D_PAD_UART1_RX_DATA__I2C1_SCL 0x4000007f + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX7D_PAD_SAI1_RX_BCLK__I2C4_SDA 0x4000007f + MX7D_PAD_SAI1_RX_SYNC__I2C4_SCL 0x4000007f + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f + MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f + MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30 + MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX7D_PAD_I2C4_SDA__UART5_DCE_TX 0x79 + MX7D_PAD_I2C4_SCL__UART5_DCE_RX 0x79 + >; + }; + + pinctrl_usbotg1_pwr: usbotg_pwr { + fsl,pins = < + MX7D_PAD_UART3_TX_DATA__GPIO4_IO5 0x14 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x59 + MX7D_PAD_SD3_CLK__SD3_CLK 0x19 + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59 + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59 + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59 + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59 + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59 + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59 + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59 + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp_100mhz { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x5a + MX7D_PAD_SD3_CLK__SD3_CLK 0x1a + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp_200mhz { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x5b + MX7D_PAD_SD3_CLK__SD3_CLK 0x1b + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b + >; + }; +}; + +&iomuxc_lpsr { + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74 + >; + }; +}; diff --git a/sys/gnu/dts/arm/imx7d-pinfunc.h b/sys/gnu/dts/arm/imx7d-pinfunc.h index f6f7e78f8820..f2493bc63da4 100644 --- a/sys/gnu/dts/arm/imx7d-pinfunc.h +++ b/sys/gnu/dts/arm/imx7d-pinfunc.h @@ -17,9 +17,9 @@ #define MX7D_PAD_LPSR_GPIO1_IO00__GPIO1_IO0 0x0000 0x0030 0x0000 0x0 0x0 #define MX7D_PAD_LPSR_GPIO1_IO00__PWM4_OUT 0x0000 0x0030 0x0000 0x1 0x0 -#define MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG_ANY 0x0000 0x0030 0x0000 0x2 0x0 -#define MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG_B 0x0000 0x0030 0x0000 0x3 0x0 -#define MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB 0x0000 0x0030 0x0000 0x4 0x0 +#define MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_ANY 0x0000 0x0030 0x0000 0x2 0x0 +#define MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x0000 0x0030 0x0000 0x3 0x0 +#define MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG__RST_B_DEB 0x0000 0x0030 0x0000 0x4 0x0 #define MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x0004 0x0034 0x0000 0x0 0x0 #define MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x0004 0x0034 0x0000 0x1 0x0 #define MX7D_PAD_LPSR_GPIO1_IO01__CCM_ENET_REF_CLK3 0x0004 0x0034 0x0000 0x2 0x0 diff --git a/sys/gnu/dts/arm/imx7d-sdb.dts b/sys/gnu/dts/arm/imx7d-sdb.dts index 5be01a1bf840..0a24d1bf3c39 100644 --- a/sys/gnu/dts/arm/imx7d-sdb.dts +++ b/sys/gnu/dts/arm/imx7d-sdb.dts @@ -52,47 +52,70 @@ reg = <0x80000000 0x80000000>; }; - regulators { - compatible = "simple-bus"; + spi4 { + compatible = "spi-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi4>; + gpio-sck = <&gpio1 13 GPIO_ACTIVE_HIGH>; + gpio-mosi = <&gpio1 9 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; + num-chipselects = <1>; #address-cells = <1>; #size-cells = <0>; - reg_usb_otg1_vbus: regulator@0 { - compatible = "regulator-fixed"; + extended_io: gpio-expander@0 { + compatible = "fairchild,74hc595"; + gpio-controller; + #gpio-cells = <2>; reg = <0>; - regulator-name = "usb_otg1_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; - enable-active-high; + registers-number = <1>; + spi-max-frequency = <100000>; }; + }; - reg_usb_otg2_vbus: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "usb_otg2_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; + reg_usb_otg1_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; - reg_can2_3v3: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "can2-3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio1 7 GPIO_ACTIVE_LOW>; - }; + reg_usb_otg2_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; - reg_vref_1v8: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "vref-1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; + reg_can2_3v3: regulator-can2-3v3 { + compatible = "regulator-fixed"; + regulator-name = "can2-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 7 GPIO_ACTIVE_LOW>; + }; + + reg_vref_1v8: regulator-vref-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vref-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_brcm: regulator-brcm { + compatible = "regulator-fixed"; + gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "brcm_reg"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_brcm_reg>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <200000>; }; }; @@ -328,6 +351,11 @@ }; }; +&pcie { + reset-gpio = <&extended_io 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + &pwm1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm1>; @@ -342,6 +370,15 @@ status = "okay"; }; +&uart6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart6>; + assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>; + uart-has-rtscts; + status = "okay"; +}; + &usbotg1 { vbus-supply = <®_usb_otg1_vbus>; status = "okay"; @@ -363,6 +400,19 @@ status = "okay"; }; +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + wakeup-source; + keep-power-in-suspend; + non-removable; + vmmc-supply = <®_brcm>; + fsl,tuning-step = <2>; + status = "okay"; +}; + &usdhc3 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc3>; @@ -387,6 +437,12 @@ pinctrl-0 = <&pinctrl_hog>; imx7d-sdb { + pinctrl_brcm_reg: brcmreggrp { + fsl,pins = < + MX7D_PAD_ECSPI2_MOSI__GPIO4_IO21 0x14 + >; + }; + pinctrl_ecspi3: ecspi3grp { fsl,pins = < MX7D_PAD_SAI2_TX_SYNC__ECSPI3_MISO 0x2 @@ -501,6 +557,14 @@ >; }; + pinctrl_spi4: spi4grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 + MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59 + MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59 + >; + }; + pinctrl_tsc2046_pendown: tsc2046_pendown { fsl,pins = < MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x59 @@ -554,7 +618,6 @@ MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59 MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59 MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59 - MX7D_PAD_ECSPI2_MOSI__GPIO4_IO21 0x59 /* WL_REG_ON */ >; }; @@ -634,7 +697,7 @@ &iomuxc_lpsr { pinctrl_wdog: wdoggrp { fsl,pins = < - MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG_B 0x74 + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74 >; }; diff --git a/sys/gnu/dts/arm/imx7d.dtsi b/sys/gnu/dts/arm/imx7d.dtsi index f6dee41a05d9..f46814a7ea44 100644 --- a/sys/gnu/dts/arm/imx7d.dtsi +++ b/sys/gnu/dts/arm/imx7d.dtsi @@ -42,6 +42,7 @@ */ #include "imx7s.dtsi" +#include / { cpus { @@ -127,6 +128,42 @@ fsl,num-rx-queues=<3>; status = "disabled"; }; + + pcie: pcie@0x33800000 { + compatible = "fsl,imx7d-pcie", "snps,dw-pcie"; + reg = <0x33800000 0x4000>, + <0x4ff00000 0x80000>; + reg-names = "dbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x81000000 0 0 0x4ff80000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */ + num-lanes = <1>; + interrupts = ; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>, + <&clks IMX7D_PCIE_PHY_ROOT_CLK>; + clock-names = "pcie", "pcie_bus", "pcie_phy"; + assigned-clocks = <&clks IMX7D_PCIE_CTRL_ROOT_SRC>, + <&clks IMX7D_PCIE_PHY_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + + fsl,max-link-speed = <2>; + power-domains = <&pgc_pcie_phy>; + resets = <&src IMX7_RESET_PCIEPHY>, + <&src IMX7_RESET_PCIE_CTRL_APPS_EN>; + reset-names = "pciephy", "apps"; + status = "disabled"; + }; }; &ca_funnel_ports { diff --git a/sys/gnu/dts/arm/imx7s-warp.dts b/sys/gnu/dts/arm/imx7s-warp.dts index d5237fd0fa65..07b63f8b7314 100644 --- a/sys/gnu/dts/arm/imx7s-warp.dts +++ b/sys/gnu/dts/arm/imx7s-warp.dts @@ -295,6 +295,7 @@ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>; assigned-clock-rates = <400000000>; bus-width = <8>; + no-1-8-v; fsl,tuning-step = <2>; non-removable; status = "okay"; @@ -442,7 +443,7 @@ &iomuxc_lpsr { pinctrl_wdog: wdoggrp { fsl,pins = < - MX7D_PAD_LPSR_GPIO1_IO00__WDOD1_WDOG_B 0x74 + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74 >; }; }; diff --git a/sys/gnu/dts/arm/imx7s.dtsi b/sys/gnu/dts/arm/imx7s.dtsi index c4f12fd2e044..4cf6c458b583 100644 --- a/sys/gnu/dts/arm/imx7s.dtsi +++ b/sys/gnu/dts/arm/imx7s.dtsi @@ -42,6 +42,7 @@ */ #include +#include #include #include #include @@ -119,7 +120,7 @@ #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; - interrupt-parent = <&intc>; + interrupt-parent = <&gpc>; ranges; funnel@30041000 { @@ -301,6 +302,7 @@ interrupts = ; #interrupt-cells = <3>; interrupt-controller; + interrupt-parent = <&intc>; reg = <0x31001000 0x1000>, <0x31002000 0x2000>, <0x31004000 0x2000>, @@ -309,6 +311,7 @@ timer { compatible = "arm,armv7-timer"; + interrupt-parent = <&intc>; interrupts = , , , @@ -488,7 +491,8 @@ }; gpr: iomuxc-gpr@30340000 { - compatible = "fsl,imx7d-iomuxc-gpr", "syscon"; + compatible = "fsl,imx7d-iomuxc-gpr", + "fsl,imx6q-iomuxc-gpr", "syscon"; reg = <0x30340000 0x10000>; }; @@ -516,6 +520,7 @@ anatop-min-bit-val = <8>; anatop-min-voltage = <800000>; anatop-max-voltage = <1200000>; + anatop-enable-bit = <0>; }; }; @@ -563,6 +568,27 @@ interrupts = ; #reset-cells = <1>; }; + + gpc: gpc@303a0000 { + compatible = "fsl,imx7d-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + #power-domain-cells = <1>; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + pgc_pcie_phy: pgc-power-domain@IMX7_POWER_DOMAIN_PCIE_PHY { + #power-domain-cells = <0>; + reg = ; + power-supply = <®_1p0d>; + }; + }; + }; }; aips2: aips-bus@30400000 { @@ -609,7 +635,7 @@ clocks = <&clks IMX7D_PWM1_ROOT_CLK>, <&clks IMX7D_PWM1_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -620,7 +646,7 @@ clocks = <&clks IMX7D_PWM2_ROOT_CLK>, <&clks IMX7D_PWM2_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -631,7 +657,7 @@ clocks = <&clks IMX7D_PWM3_ROOT_CLK>, <&clks IMX7D_PWM3_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -642,7 +668,7 @@ clocks = <&clks IMX7D_PWM4_ROOT_CLK>, <&clks IMX7D_PWM4_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -934,8 +960,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b40000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC1_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -946,8 +972,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b50000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC2_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -958,8 +984,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b60000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC3_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; diff --git a/sys/gnu/dts/arm/keystone-k2g-evm.dts b/sys/gnu/dts/arm/keystone-k2g-evm.dts index 692fcbb1434a..61883cb969d2 100644 --- a/sys/gnu/dts/arm/keystone-k2g-evm.dts +++ b/sys/gnu/dts/arm/keystone-k2g-evm.dts @@ -20,7 +20,7 @@ compatible = "ti,k2g-evm", "ti,k2g", "ti,keystone"; model = "Texas Instruments K2G General Purpose EVM"; - memory { + memory@800000000 { device_type = "memory"; reg = <0x00000008 0x00000000 0x00000000 0x80000000>; }; diff --git a/sys/gnu/dts/arm/keystone-k2g-ice.dts b/sys/gnu/dts/arm/keystone-k2g-ice.dts new file mode 100644 index 000000000000..d820d37b5148 --- /dev/null +++ b/sys/gnu/dts/arm/keystone-k2g-ice.dts @@ -0,0 +1,35 @@ +/* + * Device Tree Source for K2G Industrial Communication Engine EVM + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0 + */ +/dts-v1/; + +#include "keystone-k2g.dtsi" + +/ { + compatible = "ti,k2g-ice", "ti,k2g", "ti,keystone"; + model = "Texas Instruments K2G Industrial Communication EVM"; + + memory@800000000 { + device_type = "memory"; + reg = <0x00000008 0x00000000 0x00000000 0x20000000>; + }; +}; + +&k2g_pinctrl { + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x11cc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + K2G_CORE_IOPAD(0x11d0) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/keystone-k2g.dtsi b/sys/gnu/dts/arm/keystone-k2g.dtsi index f59567fe7d91..a789f75a1ed5 100644 --- a/sys/gnu/dts/arm/keystone-k2g.dtsi +++ b/sys/gnu/dts/arm/keystone-k2g.dtsi @@ -15,7 +15,6 @@ #include #include -#include "skeleton.dtsi" / { compatible = "ti,k2g","ti,keystone"; @@ -24,6 +23,8 @@ #size-cells = <2>; interrupt-parent = <&gic>; + chosen { }; + aliases { serial0 = &uart0; }; diff --git a/sys/gnu/dts/arm/kirkwood-openblocks_a6.dts b/sys/gnu/dts/arm/kirkwood-openblocks_a6.dts index 94e49f32d5f9..c75da5f0ca48 100644 --- a/sys/gnu/dts/arm/kirkwood-openblocks_a6.dts +++ b/sys/gnu/dts/arm/kirkwood-openblocks_a6.dts @@ -141,7 +141,7 @@ partition@d4000 { label = "test"; - reg = <0xd4000 0x24000>; + reg = <0xd4000 0x20000>; }; partition@f4000 { diff --git a/sys/gnu/dts/arm/logicpd-torpedo-som.dtsi b/sys/gnu/dts/arm/logicpd-torpedo-som.dtsi index efe53998c961..6d89736c7b44 100644 --- a/sys/gnu/dts/arm/logicpd-torpedo-som.dtsi +++ b/sys/gnu/dts/arm/logicpd-torpedo-som.dtsi @@ -7,6 +7,10 @@ #include / { + chosen { + stdout-path = &uart1; + }; + cpus { cpu@0 { cpu0-supply = <&vcc>; diff --git a/sys/gnu/dts/arm/ls1021a.dtsi b/sys/gnu/dts/arm/ls1021a.dtsi index 45ea57fafa18..7bb9df2c1460 100644 --- a/sys/gnu/dts/arm/ls1021a.dtsi +++ b/sys/gnu/dts/arm/ls1021a.dtsi @@ -75,7 +75,7 @@ compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <0xf00>; - clocks = <&cluster1_clk>; + clocks = <&clockgen 1 0>; #cooling-cells = <2>; }; @@ -83,10 +83,17 @@ compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <0xf01>; - clocks = <&cluster1_clk>; + clocks = <&clockgen 1 0>; }; }; + sysclk: sysclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "sysclk"; + }; + timer { compatible = "arm,armv7-timer"; interrupts = , @@ -165,7 +172,7 @@ <0x0 0x20220520 0x0 0x4>; reg-names = "ahci", "sata-ecc"; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; dma-coherent; status = "disabled"; }; @@ -216,41 +223,10 @@ }; clockgen: clocking@1ee1000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x0 0x1ee1000 0x10000>; - - sysclk: sysclk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-output-names = "sysclk"; - }; - - cga_pll1: pll@800 { - compatible = "fsl,qoriq-core-pll-2.0"; - #clock-cells = <1>; - reg = <0x800 0x10>; - clocks = <&sysclk>; - clock-output-names = "cga-pll1", "cga-pll1-div2", - "cga-pll1-div4"; - }; - - platform_clk: pll@c00 { - compatible = "fsl,qoriq-core-pll-2.0"; - #clock-cells = <1>; - reg = <0xc00 0x10>; - clocks = <&sysclk>; - clock-output-names = "platform-clk", "platform-clk-div2"; - }; - - cluster1_clk: clk0c0@0 { - compatible = "fsl,qoriq-core-mux-2.0"; - #clock-cells = <0>; - reg = <0x0 0x10>; - clock-names = "pll1cga", "pll1cga-div2", "pll1cga-div4"; - clocks = <&cga_pll1 0>, <&cga_pll1 1>, <&cga_pll1 2>; - clock-output-names = "cluster1-clk"; - }; + compatible = "fsl,ls1021a-clockgen"; + reg = <0x0 0x1ee1000 0x0 0x1000>; + #clock-cells = <2>; + clocks = <&sysclk>; }; tmu: tmu@1f00000 { @@ -338,7 +314,7 @@ reg = <0x0 0x2100000 0x0 0x10000>; interrupts = ; clock-names = "dspi"; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; spi-num-chipselects = <6>; big-endian; status = "disabled"; @@ -351,7 +327,7 @@ reg = <0x0 0x2110000 0x0 0x10000>; interrupts = ; clock-names = "dspi"; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; spi-num-chipselects = <6>; big-endian; status = "disabled"; @@ -364,7 +340,7 @@ reg = <0x0 0x2180000 0x0 0x10000>; interrupts = ; clock-names = "i2c"; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; status = "disabled"; }; @@ -375,7 +351,7 @@ reg = <0x0 0x2190000 0x0 0x10000>; interrupts = ; clock-names = "i2c"; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; status = "disabled"; }; @@ -386,7 +362,7 @@ reg = <0x0 0x21a0000 0x0 0x10000>; interrupts = ; clock-names = "i2c"; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; status = "disabled"; }; @@ -479,7 +455,7 @@ compatible = "fsl,ls1021a-lpuart"; reg = <0x0 0x2960000 0x0 0x1000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "ipg"; status = "disabled"; }; @@ -488,7 +464,7 @@ compatible = "fsl,ls1021a-lpuart"; reg = <0x0 0x2970000 0x0 0x1000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "ipg"; status = "disabled"; }; @@ -497,7 +473,7 @@ compatible = "fsl,ls1021a-lpuart"; reg = <0x0 0x2980000 0x0 0x1000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "ipg"; status = "disabled"; }; @@ -506,7 +482,7 @@ compatible = "fsl,ls1021a-lpuart"; reg = <0x0 0x2990000 0x0 0x1000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "ipg"; status = "disabled"; }; @@ -515,7 +491,7 @@ compatible = "fsl,ls1021a-lpuart"; reg = <0x0 0x29a0000 0x0 0x1000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "ipg"; status = "disabled"; }; @@ -524,7 +500,7 @@ compatible = "fsl,imx21-wdt"; reg = <0x0 0x2ad0000 0x0 0x10000>; interrupts = ; - clocks = <&platform_clk 1>; + clocks = <&clockgen 4 1>; clock-names = "wdog-en"; big-endian; }; @@ -534,8 +510,8 @@ compatible = "fsl,vf610-sai"; reg = <0x0 0x2b50000 0x0 0x10000>; interrupts = ; - clocks = <&platform_clk 1>, <&platform_clk 1>, - <&platform_clk 1>, <&platform_clk 1>; + clocks = <&clockgen 4 1>, <&clockgen 4 1>, + <&clockgen 4 1>, <&clockgen 4 1>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dma-names = "tx", "rx"; dmas = <&edma0 1 47>, @@ -548,8 +524,8 @@ compatible = "fsl,vf610-sai"; reg = <0x0 0x2b60000 0x0 0x10000>; interrupts = ; - clocks = <&platform_clk 1>, <&platform_clk 1>, - <&platform_clk 1>, <&platform_clk 1>; + clocks = <&clockgen 4 1>, <&clockgen 4 1>, + <&clockgen 4 1>, <&clockgen 4 1>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dma-names = "tx", "rx"; dmas = <&edma0 1 45>, @@ -569,16 +545,16 @@ dma-channels = <32>; big-endian; clock-names = "dmamux0", "dmamux1"; - clocks = <&platform_clk 1>, - <&platform_clk 1>; + clocks = <&clockgen 4 1>, + <&clockgen 4 1>; }; dcu: dcu@2ce0000 { compatible = "fsl,ls1021a-dcu"; reg = <0x0 0x2ce0000 0x0 0x10000>; interrupts = ; - clocks = <&platform_clk 0>, - <&platform_clk 0>; + clocks = <&clockgen 4 0>, + <&clockgen 4 0>; clock-names = "dcu", "pix"; big-endian; status = "disabled"; diff --git a/sys/gnu/dts/arm/meson.dtsi b/sys/gnu/dts/arm/meson.dtsi index 8c77c87660cd..15204e44161d 100644 --- a/sys/gnu/dts/arm/meson.dtsi +++ b/sys/gnu/dts/arm/meson.dtsi @@ -45,6 +45,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include /include/ "skeleton.dtsi" / { @@ -65,99 +67,158 @@ #interrupt-cells = <3>; }; - timer@c1109940 { - compatible = "amlogic,meson6-timer"; - reg = <0xc1109940 0x18>; - interrupts = <0 10 1>; - }; - soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - wdt: watchdog@c1109900 { - compatible = "amlogic,meson6-wdt"; - reg = <0xc1109900 0x8>; - interrupts = <0 0 1>; + cbus: cbus@c1100000 { + compatible = "simple-bus"; + reg = <0xc1100000 0x200000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xc1100000 0x200000>; + + hwrng: rng@8100 { + compatible = "amlogic,meson-rng"; + reg = <0x8100 0x8>; + }; + + uart_A: serial@84c0 { + compatible = "amlogic,meson-uart"; + reg = <0x84c0 0x18>; + interrupts = ; + status = "disabled"; + }; + + uart_B: serial@84dc { + compatible = "amlogic,meson-uart"; + reg = <0x84dc 0x18>; + interrupts = ; + status = "disabled"; + }; + + i2c_A: i2c@8500 { + compatible = "amlogic,meson6-i2c"; + reg = <0x8500 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + saradc: adc@8680 { + compatible = "amlogic,meson-saradc"; + reg = <0x8680 0x34>; + #io-channel-cells = <1>; + interrupts = ; + status = "disabled"; + }; + + uart_C: serial@8700 { + compatible = "amlogic,meson-uart"; + reg = <0x8700 0x18>; + interrupts = ; + status = "disabled"; + }; + + i2c_B: i2c@87c0 { + compatible = "amlogic,meson6-i2c"; + reg = <0x87c0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + usb0_phy: phy@8800 { + compatible = "amlogic,meson-mx-usb2-phy"; + #phy-cells = <0>; + reg = <0x8800 0x20>; + status = "disabled"; + }; + + usb1_phy: phy@8820 { + compatible = "amlogic,meson-mx-usb2-phy"; + #phy-cells = <0>; + reg = <0x8820 0x20>; + status = "disabled"; + }; + + spifc: spi@8c80 { + compatible = "amlogic,meson6-spifc"; + reg = <0x8c80 0x80>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + wdt: watchdog@9900 { + compatible = "amlogic,meson6-wdt"; + reg = <0x9900 0x8>; + interrupts = ; + }; + + timer@9940 { + compatible = "amlogic,meson6-timer"; + reg = <0x9940 0x18>; + interrupts = ; + }; }; - uart_AO: serial@c81004c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc81004c0 0x18>; - interrupts = <0 90 1>; - clocks = <&clk81>; - status = "disabled"; + aobus: aobus@c8100000 { + compatible = "simple-bus"; + reg = <0xc8100000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xc8100000 0x100000>; + + ir_receiver: ir-receiver@480 { + compatible= "amlogic,meson6-ir"; + reg = <0x480 0x20>; + interrupts = ; + status = "disabled"; + }; + + uart_AO: serial@4c0 { + compatible = "amlogic,meson-uart"; + reg = <0x4c0 0x18>; + interrupts = ; + status = "disabled"; + }; + + i2c_AO: i2c@500 { + compatible = "amlogic,meson6-i2c"; + reg = <0x500 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; - uart_A: serial@c11084c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc11084c0 0x18>; - interrupts = <0 26 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - uart_B: serial@c11084dc { - compatible = "amlogic,meson-uart"; - reg = <0xc11084dc 0x18>; - interrupts = <0 75 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - uart_C: serial@c1108700 { - compatible = "amlogic,meson-uart"; - reg = <0xc1108700 0x18>; - interrupts = <0 93 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - i2c_AO: i2c@c8100500 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc8100500 0x20>; - interrupts = <0 92 1>; - clocks = <&clk81>; + usb0: usb@c9040000 { + compatible = "snps,dwc2"; #address-cells = <1>; #size-cells = <0>; + reg = <0xc9040000 0x40000>; + interrupts = ; + phys = <&usb0_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; status = "disabled"; }; - i2c_A: i2c@c1108500 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc1108500 0x20>; - interrupts = <0 21 1>; - clocks = <&clk81>; + usb1: usb@c90c0000 { + compatible = "snps,dwc2"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; - }; - - i2c_B: i2c@c11087c0 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc11087c0 0x20>; - interrupts = <0 128 1>; - clocks = <&clk81>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - ir_receiver: ir-receiver@c8100480 { - compatible= "amlogic,meson6-ir"; - reg = <0xc8100480 0x20>; - interrupts = <0 15 1>; - status = "disabled"; - }; - - spifc: spi@c1108c80 { - compatible = "amlogic,meson6-spifc"; - reg = <0xc1108c80 0x80>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clk81>; + reg = <0xc90c0000 0x40000>; + interrupts = ; + phys = <&usb1_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; status = "disabled"; }; @@ -165,10 +226,8 @@ compatible = "amlogic,meson6-dwmac", "snps,dwmac"; reg = <0xc9410000 0x10000 0xc1108108 0x4>; - interrupts = <0 8 1>; + interrupts = ; interrupt-names = "macirq"; - clocks = <&clk81>; - clock-names = "stmmaceth"; status = "disabled"; }; }; diff --git a/sys/gnu/dts/arm/meson6-atv1200.dts b/sys/gnu/dts/arm/meson6-atv1200.dts index 1237faa63ce6..9444b0d9628f 100644 --- a/sys/gnu/dts/arm/meson6-atv1200.dts +++ b/sys/gnu/dts/arm/meson6-atv1200.dts @@ -46,7 +46,7 @@ */ /dts-v1/; -/include/ "meson6.dtsi" +#include "meson6.dtsi" / { model = "Geniatech ATV1200"; diff --git a/sys/gnu/dts/arm/meson6.dtsi b/sys/gnu/dts/arm/meson6.dtsi index 7bfbb35f9c26..ddc9038c4117 100644 --- a/sys/gnu/dts/arm/meson6.dtsi +++ b/sys/gnu/dts/arm/meson6.dtsi @@ -45,14 +45,12 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/include/ "meson.dtsi" +#include "meson.dtsi" / { model = "Amlogic Meson6 SoC"; compatible = "amlogic,meson6"; - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/meson8.dtsi b/sys/gnu/dts/arm/meson8.dtsi index a3f05950000e..cada35828931 100644 --- a/sys/gnu/dts/arm/meson8.dtsi +++ b/sys/gnu/dts/arm/meson8.dtsi @@ -43,15 +43,14 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include #include -/include/ "meson.dtsi" +#include "meson.dtsi" / { model = "Amlogic Meson8 SoC"; compatible = "amlogic,meson8"; - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -85,67 +84,51 @@ }; }; - clk81: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <141666666>; - }; - - pinctrl_cbus: pinctrl@c1109880 { - compatible = "amlogic,meson8-cbus-pinctrl"; - reg = <0xc1109880 0x10>; + reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; - gpio: banks@c11080b0 { - reg = <0xc11080b0 0x28>, - <0xc11080e8 0x18>, - <0xc1108120 0x18>, - <0xc1108030 0x30>; - reg-names = "mux", "pull", "pull-enable", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_cbus 0 0 120>; + /* 2 MiB reserved for Hardware ROM Firmware? */ + hwrom@0 { + reg = <0x0 0x200000>; + no-map; }; - spi_nor_pins: nor { - mux { - groups = "nor_d", "nor_q", "nor_c", "nor_cs"; - function = "nor"; - }; - }; - - ir_recv_pins: remote { - mux { - groups = "remote_input"; - function = "remote"; - }; - }; - - eth_pins: ethernet { - mux { - groups = "eth_tx_clk_50m", "eth_tx_en", - "eth_txd1", "eth_txd0", - "eth_rx_clk_in", "eth_rx_dv", - "eth_rxd1", "eth_rxd0", "eth_mdio", - "eth_mdc"; - function = "ethernet"; - }; + /* + * 1 MiB reserved for the "ARM Power Firmware": this is ARM + * code which is responsible for system suspend. It loads a + * piece of ARC code ("arc_power" in the vendor u-boot tree) + * into SRAM, executes that and shuts down the (last) ARM core. + * The arc_power firmware then checks various wakeup sources + * (IR remote receiver, HDMI CEC, WIFI and Bluetooth wakeup or + * simply the power key) and re-starts the ARM core once it + * detects a wakeup request. + */ + power-firmware@4f00000 { + reg = <0x4f00000 0x100000>; + no-map; }; }; - pinctrl_aobus: pinctrl@c8100084 { + scu@c4300000 { + compatible = "arm,cortex-a9-scu"; + reg = <0xc4300000 0x100>; + }; +}; /* end of / */ + +&aobus { + pinctrl_aobus: pinctrl@84 { compatible = "amlogic,meson8-aobus-pinctrl"; - reg = <0xc8100084 0xc>; + reg = <0x84 0xc>; #address-cells = <1>; #size-cells = <1>; ranges; - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; + gpio_ao: ao-bank@14 { + reg = <0x14 0x4>, + <0x2c 0x4>, + <0x24 0x8>; reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; @@ -165,9 +148,176 @@ function = "i2c_mst_ao"; }; }; + + ir_recv_pins: remote { + mux { + groups = "remote_input"; + function = "remote"; + }; + }; + + pwm_f_ao_pins: pwm-f-ao { + mux { + groups = "pwm_f_ao"; + function = "pwm_f_ao"; + }; + }; }; -}; /* end of / */ +}; + +&cbus { + clkc: clock-controller@4000 { + #clock-cells = <1>; + compatible = "amlogic,meson8-clkc"; + reg = <0x8000 0x4>, <0x4000 0x460>; + }; + + pinctrl_cbus: pinctrl@9880 { + compatible = "amlogic,meson8-cbus-pinctrl"; + reg = <0x9880 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio: banks@80b0 { + reg = <0x80b0 0x28>, + <0x80e8 0x18>, + <0x8120 0x18>, + <0x8030 0x30>; + reg-names = "mux", "pull", "pull-enable", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_cbus 0 0 120>; + }; + + sd_a_pins: sd-a { + mux { + groups = "sd_d0_a", "sd_d1_a", "sd_d2_a", + "sd_d3_a", "sd_clk_a", "sd_cmd_a"; + function = "sd_a"; + }; + }; + + sd_b_pins: sd-b { + mux { + groups = "sd_d0_b", "sd_d1_b", "sd_d2_b", + "sd_d3_b", "sd_clk_b", "sd_cmd_b"; + function = "sd_b"; + }; + }; + + sd_c_pins: sd-c { + mux { + groups = "sd_d0_c", "sd_d1_c", "sd_d2_c", + "sd_d3_c", "sd_clk_c", "sd_cmd_c"; + function = "sd_c"; + }; + }; + + spi_nor_pins: nor { + mux { + groups = "nor_d", "nor_q", "nor_c", "nor_cs"; + function = "nor"; + }; + }; + + eth_pins: ethernet { + mux { + groups = "eth_tx_clk_50m", "eth_tx_en", + "eth_txd1", "eth_txd0", + "eth_rx_clk_in", "eth_rx_dv", + "eth_rxd1", "eth_rxd0", "eth_mdio", + "eth_mdc"; + function = "ethernet"; + }; + }; + + pwm_e_pins: pwm-e { + mux { + groups = "pwm_e"; + function = "pwm_e"; + }; + }; + }; +}; + +ðmac { + clocks = <&clkc CLKID_ETH>; + clock-names = "stmmaceth"; +}; + +&hwrng { + compatible = "amlogic,meson8-rng", "amlogic,meson-rng"; + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&i2c_AO { + clocks = <&clkc CLKID_CLK81>; +}; + +&i2c_A { + clocks = <&clkc CLKID_CLK81>; +}; + +&i2c_B { + clocks = <&clkc CLKID_CLK81>; +}; &L2 { - interrupts = <0 143 1>; + arm,data-latency = <3 3 3>; + arm,tag-latency = <2 2 2>; + arm,filter-ranges = <0x100000 0xc0000000>; +}; + +&saradc { + compatible = "amlogic,meson8-saradc", "amlogic,meson-saradc"; + clocks = <&clkc CLKID_XTAL>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>; + clock-names = "clkin", "core", "sana"; +}; + +&spifc { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_AO { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_A { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_B { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_C { + clocks = <&clkc CLKID_CLK81>; +}; + +&usb0 { + compatible = "amlogic,meson8-usb", "snps,dwc2"; + clocks = <&clkc CLKID_USB0_DDR_BRIDGE>; + clock-names = "otg"; +}; + +&usb1 { + compatible = "amlogic,meson8-usb", "snps,dwc2"; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; + clock-names = "otg"; +}; + +&usb0_phy { + compatible = "amlogic,meson8-usb2-phy", "amlogic,meson-mx-usb2-phy"; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; +}; + +&usb1_phy { + compatible = "amlogic,meson8-usb2-phy", "amlogic,meson-mx-usb2-phy"; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>; + clock-names = "usb_general", "usb"; }; diff --git a/sys/gnu/dts/arm/meson8b.dtsi b/sys/gnu/dts/arm/meson8b.dtsi index 828aa49c678c..72e4f425f190 100644 --- a/sys/gnu/dts/arm/meson8b.dtsi +++ b/sys/gnu/dts/arm/meson8b.dtsi @@ -47,11 +47,9 @@ #include #include #include -#include "skeleton.dtsi" +#include "meson.dtsi" / { - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -85,146 +83,162 @@ }; }; - soc { - compatible = "simple-bus"; + scu@c4300000 { + compatible = "arm,cortex-a5-scu"; + reg = <0xc4300000 0x100>; + }; +}; /* end of / */ + +&aobus { + pinctrl_aobus: pinctrl@84 { + compatible = "amlogic,meson8b-aobus-pinctrl"; + reg = <0x84 0xc>; #address-cells = <1>; #size-cells = <1>; ranges; - L2: l2-cache-controller@c4200000 { - compatible = "arm,pl310-cache"; - reg = <0xc4200000 0x1000>; - cache-unified; - cache-level = <2>; + gpio_ao: ao-bank@14 { + reg = <0x14 0x4>, + <0x2c 0x4>, + <0x24 0x8>; + reg-names = "mux", "pull", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 130 16>; }; - gic: interrupt-controller@c4301000 { - compatible = "arm,cortex-a9-gic"; - reg = <0xc4301000 0x1000>, - <0xc4300100 0x0100>; - interrupt-controller; - #interrupt-cells = <3>; - }; - - reset: reset-controller@c1104404 { - compatible = "amlogic,meson8b-reset"; - reg = <0xc1104404 0x20>; - #reset-cells = <1>; - }; - - wdt: watchdog@c1109900 { - compatible = "amlogic,meson8b-wdt"; - reg = <0xc1109900 0x8>; - interrupts = <0 0 1>; - }; - - timer@c1109940 { - compatible = "amlogic,meson6-timer"; - reg = <0xc1109940 0x18>; - interrupts = <0 10 1>; - }; - - uart_AO: serial@c81004c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc81004c0 0x18>; - interrupts = <0 90 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; - - uart_A: serial@c11084c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc11084c0 0x18>; - interrupts = <0 26 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; - - uart_B: serial@c11084dc { - compatible = "amlogic,meson-uart"; - reg = <0xc11084dc 0x18>; - interrupts = <0 75 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; - - uart_C: serial@c1108700 { - compatible = "amlogic,meson-uart"; - reg = <0xc1108700 0x18>; - interrupts = <0 93 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; - - clkc: clock-controller@c1104000 { - #clock-cells = <1>; - compatible = "amlogic,meson8b-clkc"; - reg = <0xc1108000 0x4>, <0xc1104000 0x460>; - }; - - pwm_ab: pwm@8550 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc1108550 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_cd: pwm@8650 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc1108650 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_ef: pwm@86c0 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc11086c0 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pinctrl_cbus: pinctrl@c1109880 { - compatible = "amlogic,meson8b-cbus-pinctrl"; - reg = <0xc1109880 0x10>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gpio: banks@c11080b0 { - reg = <0xc11080b0 0x28>, - <0xc11080e8 0x18>, - <0xc1108120 0x18>, - <0xc1108030 0x38>; - reg-names = "mux", "pull", "pull-enable", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_cbus 0 0 130>; - }; - }; - - pinctrl_aobus: pinctrl@c8100084 { - compatible = "amlogic,meson8b-aobus-pinctrl"; - reg = <0xc8100084 0xc>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_aobus 0 130 16>; - }; - - uart_ao_a_pins: uart_ao_a { - mux { - groups = "uart_tx_ao_a", "uart_rx_ao_a"; - function = "uart_ao"; - }; + uart_ao_a_pins: uart_ao_a { + mux { + groups = "uart_tx_ao_a", "uart_rx_ao_a"; + function = "uart_ao"; }; }; }; -}; /* end of / */ +}; + +&cbus { + clkc: clock-controller@4000 { + #clock-cells = <1>; + compatible = "amlogic,meson8b-clkc"; + reg = <0x8000 0x4>, <0x4000 0x460>; + }; + + reset: reset-controller@4404 { + compatible = "amlogic,meson8b-reset"; + reg = <0x4404 0x20>; + #reset-cells = <1>; + }; + + pwm_ab: pwm@8550 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x8550 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_cd: pwm@8650 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x8650 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ef: pwm@86c0 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x86c0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + + wdt: watchdog@9900 { + compatible = "amlogic,meson8b-wdt"; + reg = <0x9900 0x8>; + interrupts = <0 0 1>; + }; + + pinctrl_cbus: pinctrl@9880 { + compatible = "amlogic,meson8b-cbus-pinctrl"; + reg = <0x9880 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio: banks@80b0 { + reg = <0x80b0 0x28>, + <0x80e8 0x18>, + <0x8120 0x18>, + <0x8030 0x38>; + reg-names = "mux", "pull", "pull-enable", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_cbus 0 0 130>; + }; + }; +}; + +ðmac { + clocks = <&clkc CLKID_ETH>; + clock-names = "stmmaceth"; +}; + +&hwrng { + compatible = "amlogic,meson8b-rng", "amlogic,meson-rng"; + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&L2 { + arm,data-latency = <3 3 3>; + arm,tag-latency = <2 2 2>; + arm,filter-ranges = <0x100000 0xc0000000>; +}; + +&saradc { + compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc"; + clocks = <&clkc CLKID_XTAL>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>; + clock-names = "clkin", "core", "sana"; +}; + +&uart_AO { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_A { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_B { + clocks = <&clkc CLKID_CLK81>; +}; + +&uart_C { + clocks = <&clkc CLKID_CLK81>; +}; + +&usb0 { + compatible = "amlogic,meson8b-usb", "snps,dwc2"; + clocks = <&clkc CLKID_USB0_DDR_BRIDGE>; + clock-names = "otg"; +}; + +&usb1 { + compatible = "amlogic,meson8b-usb", "snps,dwc2"; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; + clock-names = "otg"; +}; + +&usb0_phy { + compatible = "amlogic,meson8b-usb2-phy", "amlogic,meson-mx-usb2-phy"; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; + resets = <&reset RESET_USB_OTG>; +}; + +&usb1_phy { + compatible = "amlogic,meson8b-usb2-phy", "amlogic,meson-mx-usb2-phy"; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>; + clock-names = "usb_general", "usb"; + resets = <&reset RESET_USB_OTG>; +}; diff --git a/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi b/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi index f5aeb3959afd..1eb5da1dc8f0 100644 --- a/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi +++ b/sys/gnu/dts/arm/motorola-cpcap-mapphone.dtsi @@ -26,6 +26,22 @@ #io-channel-cells = <1>; }; + cpcap_battery: battery { + compatible = "motorola,cpcap-battery"; + interrupts-extended = < + &cpcap 6 0 &cpcap 5 0 &cpcap 3 0 + &cpcap 20 0 &cpcap 54 0 + >; + interrupt-names = + "eol", "lowbph", "lowbpl", + "chrgcurr1", "battdetb"; + io-channels = <&cpcap_adc 0 &cpcap_adc 1 + &cpcap_adc 5 &cpcap_adc 6>; + io-channel-names = "battdetb", "battp", + "chg_isense", "batti"; + power-supplies = <&cpcap_charger>; + }; + cpcap_charger: charger { compatible = "motorola,mapphone-cpcap-charger"; interrupts-extended = < diff --git a/sys/gnu/dts/arm/moxart.dtsi b/sys/gnu/dts/arm/moxart.dtsi index e86f8c905ac5..1f4c795d3f72 100644 --- a/sys/gnu/dts/arm/moxart.dtsi +++ b/sys/gnu/dts/arm/moxart.dtsi @@ -58,10 +58,11 @@ }; timer: timer@98400000 { - compatible = "moxa,moxart-timer"; + compatible = "moxa,moxart-timer", "faraday,fttmr010"; reg = <0x98400000 0x42>; interrupts = <19 IRQ_TYPE_EDGE_FALLING>; clocks = <&clk_apb>; + clock-names = "PCLK"; }; gpio: gpio@98700000 { diff --git a/sys/gnu/dts/arm/mt2701-evb.dts b/sys/gnu/dts/arm/mt2701-evb.dts index a4837985b7a7..f48497354221 100644 --- a/sys/gnu/dts/arm/mt2701-evb.dts +++ b/sys/gnu/dts/arm/mt2701-evb.dts @@ -22,13 +22,95 @@ memory { reg = <0 0x80000000 0 0x40000000>; }; + + sound:sound { + compatible = "mediatek,mt2701-cs42448-machine"; + mediatek,platform = <&afe>; + /* CS42448 Machine name */ + audio-routing = + "Line Out Jack", "AOUT1L", + "Line Out Jack", "AOUT1R", + "Line Out Jack", "AOUT2L", + "Line Out Jack", "AOUT2R", + "Line Out Jack", "AOUT3L", + "Line Out Jack", "AOUT3R", + "Line Out Jack", "AOUT4L", + "Line Out Jack", "AOUT4R", + "AIN1L", "AMIC", + "AIN1R", "AMIC", + "AIN2L", "Tuner In", + "AIN2R", "Tuner In", + "AIN3L", "Satellite Tuner In", + "AIN3R", "Satellite Tuner In", + "AIN3L", "AUX In", + "AIN3R", "AUX In"; + mediatek,audio-codec = <&cs42448>; + mediatek,audio-codec-bt-mrg = <&bt_sco_codec>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + i2s1-in-sel-gpio1 = <&pio 53 0>; + i2s1-in-sel-gpio2 = <&pio 54 0>; + status = "okay"; + }; + + bt_sco_codec:bt_sco_codec { + compatible = "linux,bt-sco"; + }; }; &auxadc { status = "okay"; }; +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + cs42448: cs42448@48 { + compatible = "cirrus,cs42448"; + reg = <0x48>; + clocks = <&topckgen CLK_TOP_AUD_I2S1_MCLK>; + clock-names = "mclk"; + }; +}; + &pio { + i2c0_pins_a: i2c0@0 { + pins1 { + pinmux = , + ; + bias-disable; + }; + }; + + i2c1_pins_a: i2c1@0 { + pins1 { + pinmux = , + ; + bias-disable; + }; + }; + + i2c2_pins_a: i2c2@0 { + pins1 { + pinmux = , + ; + bias-disable; + }; + }; + spi_pins_a: spi0@0 { pins_spi { pinmux = , @@ -39,6 +121,31 @@ }; }; + aud_pins_default: audiodefault { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + drive-strength = ; + bias-pull-down; + }; + }; + spi_pins_b: spi1@0 { pins_spi { pinmux = , @@ -78,6 +185,31 @@ status = "disabled"; }; +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&nor_pins_default>; + status = "okay"; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + }; +}; + +&pio { + nor_pins_default: nor { + pins1 { + pinmux = , + , + , + , + , + ; + drive-strength = ; + bias-pull-up; + }; + }; +}; + &uart0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/mt2701.dtsi b/sys/gnu/dts/arm/mt2701.dtsi index 803721050116..f1efdc63656a 100644 --- a/sys/gnu/dts/arm/mt2701.dtsi +++ b/sys/gnu/dts/arm/mt2701.dtsi @@ -16,13 +16,14 @@ #include #include #include +#include #include #include "skeleton64.dtsi" #include "mt2701-pinfunc.h" / { compatible = "mediatek,mt2701"; - interrupt-parent = <&sysirq>; + interrupt-parent = <&cirq>; cpus { #address-cells = <1>; @@ -210,6 +211,16 @@ reg = <0 0x10200100 0 0x1c>; }; + cirq: interrupt-controller@10204000 { + compatible = "mediatek,mt2701-cirq", + "mediatek,mtk-cirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&sysirq>; + reg = <0 0x10204000 0 0x400>; + mediatek,ext-irq-range = <32 200>; + }; + iommu: mmsys_iommu@10205000 { compatible = "mediatek,mt2701-m4u"; reg = <0 0x10205000 0 0x1000>; @@ -286,6 +297,48 @@ status = "disabled"; }; + i2c0: i2c@11007000 { + compatible = "mediatek,mt2701-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11007000 0 0x70>, + <0 0x11000200 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C0>, <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@11008000 { + compatible = "mediatek,mt2701-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11008000 0 0x70>, + <0 0x11000280 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C1>, <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@11009000 { + compatible = "mediatek,mt2701-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11009000 0 0x70>, + <0 0x11000300 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C2>, <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + spi0: spi@1100a000 { compatible = "mediatek,mt2701-spi"; #address-cells = <1>; @@ -334,6 +387,18 @@ status = "disabled"; }; + nor_flash: spi@11014000 { + compatible = "mediatek,mt2701-nor", + "mediatek,mt8173-nor"; + reg = <0 0x11014000 0 0xe0>; + clocks = <&pericfg CLK_PERI_FLASH>, + <&topckgen CLK_TOP_FLASH_SEL>; + clock-names = "spi", "sf"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + spi1: spi@11016000 { compatible = "mediatek,mt2701-spi"; #address-cells = <1>; @@ -360,6 +425,104 @@ status = "disabled"; }; + afe: audio-controller@11220000 { + compatible = "mediatek,mt2701-audio"; + reg = <0 0x11220000 0 0x2000>, + <0 0x112a0000 0 0x20000>; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + + clocks = <&infracfg CLK_INFRA_AUDIO>, + <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>, + <&topckgen CLK_TOP_AUD_48K_TIMING>, + <&topckgen CLK_TOP_AUD_44K_TIMING>, + <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, + <&topckgen CLK_TOP_APLL_SEL>, + <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>, + <&topckgen CLK_TOP_HADDS2PLL_98M>, + <&topckgen CLK_TOP_HADDS2PLL_294M>, + <&topckgen CLK_TOP_AUDPLL>, + <&topckgen CLK_TOP_AUDPLL_D4>, + <&topckgen CLK_TOP_AUDPLL_D8>, + <&topckgen CLK_TOP_AUDPLL_D16>, + <&topckgen CLK_TOP_AUDPLL_D24>, + <&topckgen CLK_TOP_AUDINTBUS_SEL>, + <&clk26m>, + <&topckgen CLK_TOP_SYSPLL1_D4>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&topckgen CLK_TOP_AUD_I2S5_MCLK>, + <&topckgen CLK_TOP_AUD_I2S6_MCLK>, + <&topckgen CLK_TOP_ASM_M_SEL>, + <&topckgen CLK_TOP_ASM_H_SEL>, + <&topckgen CLK_TOP_UNIVPLL2_D4>, + <&topckgen CLK_TOP_UNIVPLL2_D2>, + <&topckgen CLK_TOP_SYSPLL_D5>; + + clock-names = "infra_sys_audio_clk", + "top_audio_mux1_sel", + "top_audio_mux2_sel", + "top_audio_mux1_div", + "top_audio_mux2_div", + "top_audio_48k_timing", + "top_audio_44k_timing", + "top_audpll_mux_sel", + "top_apll_sel", + "top_aud1_pll_98M", + "top_aud2_pll_90M", + "top_hadds2_pll_98M", + "top_hadds2_pll_294M", + "top_audpll", + "top_audpll_d4", + "top_audpll_d8", + "top_audpll_d16", + "top_audpll_d24", + "top_audintbus_sel", + "clk_26m", + "top_syspll1_d4", + "top_aud_k1_src_sel", + "top_aud_k2_src_sel", + "top_aud_k3_src_sel", + "top_aud_k4_src_sel", + "top_aud_k5_src_sel", + "top_aud_k6_src_sel", + "top_aud_k1_src_div", + "top_aud_k2_src_div", + "top_aud_k3_src_div", + "top_aud_k4_src_div", + "top_aud_k5_src_div", + "top_aud_k6_src_div", + "top_aud_i2s1_mclk", + "top_aud_i2s2_mclk", + "top_aud_i2s3_mclk", + "top_aud_i2s4_mclk", + "top_aud_i2s5_mclk", + "top_aud_i2s6_mclk", + "top_asm_m_sel", + "top_asm_h_sel", + "top_univpll2_d4", + "top_univpll2_d2", + "top_syspll_d5"; + }; + mmsys: syscon@14000000 { compatible = "mediatek,mt2701-mmsys", "syscon"; reg = <0 0x14000000 0 0x1000>; @@ -392,6 +555,20 @@ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; }; + jpegdec: jpegdec@15004000 { + compatible = "mediatek,mt2701-jpgdec"; + reg = <0 0x15004000 0 0x1000>; + interrupts = ; + clocks = <&imgsys CLK_IMG_JPGDEC_SMI>, + <&imgsys CLK_IMG_JPGDEC>; + clock-names = "jpgdec-smi", + "jpgdec"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; + mediatek,larb = <&larb2>; + iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, + <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; + }; + vdecsys: syscon@16000000 { compatible = "mediatek,mt2701-vdecsys", "syscon"; reg = <0 0x16000000 0 0x1000>; diff --git a/sys/gnu/dts/arm/mt7623.dtsi b/sys/gnu/dts/arm/mt7623.dtsi index 3a9e9b6aea68..d81158b2b02f 100644 --- a/sys/gnu/dts/arm/mt7623.dtsi +++ b/sys/gnu/dts/arm/mt7623.dtsi @@ -1,6 +1,7 @@ /* - * Copyright (c) 2016 MediaTek Inc. + * Copyright (c) 2017 MediaTek Inc. * Author: John Crispin + * Sean Wang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +15,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include "skeleton64.dtsi" / { @@ -53,16 +60,18 @@ #clock-cells = <0>; }; - rtc_clk: dummy32k { + rtc32k: oscillator@1 { compatible = "fixed-clock"; - clock-frequency = <32000>; #clock-cells = <0>; + clock-frequency = <32000>; + clock-output-names = "rtc32k"; }; - uart_clk: dummy26m { + clk26m: oscillator@0 { compatible = "fixed-clock"; - clock-frequency = <26000000>; #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; }; timer { @@ -76,6 +85,65 @@ arm,cpu-registers-not-fw-configured; }; + topckgen: syscon@10000000 { + compatible = "mediatek,mt7623-topckgen", + "mediatek,mt2701-topckgen", + "syscon"; + reg = <0 0x10000000 0 0x1000>; + #clock-cells = <1>; + }; + + infracfg: syscon@10001000 { + compatible = "mediatek,mt7623-infracfg", + "mediatek,mt2701-infracfg", + "syscon"; + reg = <0 0x10001000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pericfg: syscon@10003000 { + compatible = "mediatek,mt7623-pericfg", + "mediatek,mt2701-pericfg", + "syscon"; + reg = <0 0x10003000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt7623-pinctrl", + "mediatek,mt2701-pinctrl"; + reg = <0 0x1000b000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupts = , + ; + }; + + syscfg_pctl_a: syscfg@10005000 { + compatible = "mediatek,mt7623-pctl-a-syscfg", "syscon"; + reg = <0 0x10005000 0 0x1000>; + }; + + scpsys: scpsys@10006000 { + compatible = "mediatek,mt7623-scpsys", + "mediatek,mt2701-scpsys", + "syscon"; + #power-domain-cells = <1>; + reg = <0 0x10006000 0 0x1000>; + infracfg = <&infracfg>; + clocks = <&topckgen CLK_TOP_MM_SEL>, + <&topckgen CLK_TOP_MFG_SEL>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "mm", "mfg", "ethif"; + }; + watchdog: watchdog@10007000 { compatible = "mediatek,mt7623-wdt", "mediatek,mt6589-wdt"; @@ -87,10 +155,32 @@ "mediatek,mt6577-timer"; reg = <0 0x10008000 0 0x80>; interrupts = ; - clocks = <&system_clk>, <&rtc_clk>; + clocks = <&system_clk>, <&rtc32k>; clock-names = "system-clk", "rtc-clk"; }; + pwrap: pwrap@1000d000 { + compatible = "mediatek,mt7623-pwrap", + "mediatek,mt2701-pwrap"; + reg = <0 0x1000d000 0 0x1000>; + reg-names = "pwrap"; + interrupts = ; + resets = <&infracfg MT2701_INFRA_PMIC_WRAP_RST>; + reset-names = "pwrap"; + clocks = <&infracfg CLK_INFRA_PMICSPI>, + <&infracfg CLK_INFRA_PMICWRAP>; + clock-names = "spi", "wrap"; + }; + + cir: cir@0x10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_IRRX>; + clock-names = "clk"; + status = "disabled"; + }; + sysirq: interrupt-controller@10200100 { compatible = "mediatek,mt7623-sysirq", "mediatek,mt6577-sysirq"; @@ -100,6 +190,32 @@ reg = <0 0x10200100 0 0x1c>; }; + efuse: efuse@10206000 { + compatible = "mediatek,mt7623-efuse", + "mediatek,mt8173-efuse"; + reg = <0 0x10206000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + thermal_calibration_data: calib@424 { + reg = <0x424 0xc>; + }; + }; + + apmixedsys: syscon@10209000 { + compatible = "mediatek,mt7623-apmixedsys", + "mediatek,mt2701-apmixedsys", + "syscon"; + reg = <0 0x10209000 0 0x1000>; + #clock-cells = <1>; + }; + + rng: rng@1020f000 { + compatible = "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x1000>; + clocks = <&infracfg CLK_INFRA_TRNG>; + clock-names = "rng"; + }; + gic: interrupt-controller@10211000 { compatible = "arm,cortex-a7-gic"; interrupt-controller; @@ -111,12 +227,23 @@ <0 0x10216000 0 0x2000>; }; + auxadc: adc@11001000 { + compatible = "mediatek,mt7623-auxadc", + "mediatek,mt2701-auxadc"; + reg = <0 0x11001000 0 0x1000>; + clocks = <&pericfg CLK_PERI_AUXADC>; + clock-names = "main"; + #io-channel-cells = <1>; + }; + uart0: serial@11002000 { compatible = "mediatek,mt7623-uart", "mediatek,mt6577-uart"; reg = <0 0x11002000 0 0x400>; interrupts = ; - clocks = <&uart_clk>; + clocks = <&pericfg CLK_PERI_UART0_SEL>, + <&pericfg CLK_PERI_UART0>; + clock-names = "baud", "bus"; status = "disabled"; }; @@ -125,7 +252,9 @@ "mediatek,mt6577-uart"; reg = <0 0x11003000 0 0x400>; interrupts = ; - clocks = <&uart_clk>; + clocks = <&pericfg CLK_PERI_UART1_SEL>, + <&pericfg CLK_PERI_UART1>; + clock-names = "baud", "bus"; status = "disabled"; }; @@ -134,7 +263,9 @@ "mediatek,mt6577-uart"; reg = <0 0x11004000 0 0x400>; interrupts = ; - clocks = <&uart_clk>; + clocks = <&pericfg CLK_PERI_UART2_SEL>, + <&pericfg CLK_PERI_UART2>; + clock-names = "baud", "bus"; status = "disabled"; }; @@ -143,7 +274,402 @@ "mediatek,mt6577-uart"; reg = <0 0x11005000 0 0x400>; interrupts = ; - clocks = <&uart_clk>; + clocks = <&pericfg CLK_PERI_UART3_SEL>, + <&pericfg CLK_PERI_UART3>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + pwm: pwm@11006000 { + compatible = "mediatek,mt7623-pwm"; + reg = <0 0x11006000 0 0x1000>; + #pwm-cells = <2>; + clocks = <&topckgen CLK_TOP_PWM_SEL>, + <&pericfg CLK_PERI_PWM>, + <&pericfg CLK_PERI_PWM1>, + <&pericfg CLK_PERI_PWM2>, + <&pericfg CLK_PERI_PWM3>, + <&pericfg CLK_PERI_PWM4>, + <&pericfg CLK_PERI_PWM5>; + clock-names = "top", "main", "pwm1", "pwm2", + "pwm3", "pwm4", "pwm5"; + status = "disabled"; + }; + + i2c0: i2c@11007000 { + compatible = "mediatek,mt7623-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11007000 0 0x70>, + <0 0x11000200 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C0>, + <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@11008000 { + compatible = "mediatek,mt7623-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11008000 0 0x70>, + <0 0x11000280 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C1>, + <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@11009000 { + compatible = "mediatek,mt7623-i2c", + "mediatek,mt6577-i2c"; + reg = <0 0x11009000 0 0x70>, + <0 0x11000300 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C2>, + <&pericfg CLK_PERI_AP_DMA>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,mt7623-spi", + "mediatek,mt2701-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1100a000 0 0x100>; + interrupts = ; + clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, + <&topckgen CLK_TOP_SPI0_SEL>, + <&pericfg CLK_PERI_SPI0>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + thermal: thermal@1100b000 { + #thermal-sensor-cells = <1>; + compatible = "mediatek,mt7623-thermal", + "mediatek,mt2701-thermal"; + reg = <0 0x1100b000 0 0x1000>; + interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; + clock-names = "therm", "auxadc"; + resets = <&pericfg MT2701_PERI_THERM_SW_RST>; + reset-names = "therm"; + mediatek,auxadc = <&auxadc>; + mediatek,apmixedsys = <&apmixedsys>; + nvmem-cells = <&thermal_calibration_data>; + nvmem-cell-names = "calibration-data"; + }; + + spi1: spi@11016000 { + compatible = "mediatek,mt7623-spi", + "mediatek,mt2701-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11016000 0 0x100>; + interrupts = ; + clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, + <&topckgen CLK_TOP_SPI1_SEL>, + <&pericfg CLK_PERI_SPI1>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi2: spi@11017000 { + compatible = "mediatek,mt7623-spi", + "mediatek,mt2701-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11017000 0 0x1000>; + interrupts = ; + clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, + <&topckgen CLK_TOP_SPI2_SEL>, + <&pericfg CLK_PERI_SPI2>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + nandc: nfi@1100d000 { + compatible = "mediatek,mt7623-nfc", + "mediatek,mt2701-nfc"; + reg = <0 0x1100d000 0 0x1000>; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + clocks = <&pericfg CLK_PERI_NFI>, + <&pericfg CLK_PERI_NFI_PAD>; + clock-names = "nfi_clk", "pad_clk"; + status = "disabled"; + ecc-engine = <&bch>; + #address-cells = <1>; + #size-cells = <0>; + }; + + bch: ecc@1100e000 { + compatible = "mediatek,mt7623-ecc", + "mediatek,mt2701-ecc"; + reg = <0 0x1100e000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_NFI_ECC>; + clock-names = "nfiecc_clk"; + status = "disabled"; + }; + + afe: audio-controller@11220000 { + compatible = "mediatek,mt7623-audio", + "mediatek,mt2701-audio"; + reg = <0 0x11220000 0 0x2000>, + <0 0x112a0000 0 0x20000>; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + + clocks = <&infracfg CLK_INFRA_AUDIO>, + <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>, + <&topckgen CLK_TOP_AUD_48K_TIMING>, + <&topckgen CLK_TOP_AUD_44K_TIMING>, + <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, + <&topckgen CLK_TOP_APLL_SEL>, + <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>, + <&topckgen CLK_TOP_HADDS2PLL_98M>, + <&topckgen CLK_TOP_HADDS2PLL_294M>, + <&topckgen CLK_TOP_AUDPLL>, + <&topckgen CLK_TOP_AUDPLL_D4>, + <&topckgen CLK_TOP_AUDPLL_D8>, + <&topckgen CLK_TOP_AUDPLL_D16>, + <&topckgen CLK_TOP_AUDPLL_D24>, + <&topckgen CLK_TOP_AUDINTBUS_SEL>, + <&clk26m>, + <&topckgen CLK_TOP_SYSPLL1_D4>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&topckgen CLK_TOP_AUD_I2S5_MCLK>, + <&topckgen CLK_TOP_AUD_I2S6_MCLK>, + <&topckgen CLK_TOP_ASM_M_SEL>, + <&topckgen CLK_TOP_ASM_H_SEL>, + <&topckgen CLK_TOP_UNIVPLL2_D4>, + <&topckgen CLK_TOP_UNIVPLL2_D2>, + <&topckgen CLK_TOP_SYSPLL_D5>; + + clock-names = "infra_sys_audio_clk", + "top_audio_mux1_sel", + "top_audio_mux2_sel", + "top_audio_mux1_div", + "top_audio_mux2_div", + "top_audio_48k_timing", + "top_audio_44k_timing", + "top_audpll_mux_sel", + "top_apll_sel", + "top_aud1_pll_98M", + "top_aud2_pll_90M", + "top_hadds2_pll_98M", + "top_hadds2_pll_294M", + "top_audpll", + "top_audpll_d4", + "top_audpll_d8", + "top_audpll_d16", + "top_audpll_d24", + "top_audintbus_sel", + "clk_26m", + "top_syspll1_d4", + "top_aud_k1_src_sel", + "top_aud_k2_src_sel", + "top_aud_k3_src_sel", + "top_aud_k4_src_sel", + "top_aud_k5_src_sel", + "top_aud_k6_src_sel", + "top_aud_k1_src_div", + "top_aud_k2_src_div", + "top_aud_k3_src_div", + "top_aud_k4_src_div", + "top_aud_k5_src_div", + "top_aud_k6_src_div", + "top_aud_i2s1_mclk", + "top_aud_i2s2_mclk", + "top_aud_i2s3_mclk", + "top_aud_i2s4_mclk", + "top_aud_i2s5_mclk", + "top_aud_i2s6_mclk", + "top_asm_m_sel", + "top_asm_h_sel", + "top_univpll2_d4", + "top_univpll2_d2", + "top_syspll_d5"; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt8135-mmc"; + reg = <0 0x11230000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_MSDC30_0>, + <&topckgen CLK_TOP_MSDC30_0_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + + mmc1: mmc@11240000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt8135-mmc"; + reg = <0 0x11240000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_MSDC30_1>, + <&topckgen CLK_TOP_MSDC30_1_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + + usb1: usb@1a1c0000 { + compatible = "mediatek,mt7623-xhci", + "mediatek,mt8173-xhci"; + reg = <0 0x1a1c0000 0 0x1000>, + <0 0x1a1c4700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB0PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "free_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy1: usb-phy@1a1c4000 { + compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + reg = <0 0x1a1c4000 0 0x0700>; + clocks = <&clk26m>; + clock-names = "u3phya_ref"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1a1c4800 { + reg = <0 0x1a1c4800 0 0x0100>; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@1a1c4900 { + reg = <0 0x1a1c4900 0 0x0700>; + #phy-cells = <1>; + status = "okay"; + }; + }; + + usb2: usb@1a240000 { + compatible = "mediatek,mt7623-xhci", + "mediatek,mt8173-xhci"; + reg = <0 0x1a240000 0 0x1000>, + <0 0x1a244700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB1PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "free_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy2: usb-phy@1a244000 { + compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + reg = <0 0x1a244000 0 0x0700>; + clocks = <&clk26m>; + clock-names = "u3phya_ref"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port1: usb-phy@1a244800 { + reg = <0 0x1a244800 0 0x0100>; + #phy-cells = <1>; + status = "okay"; + }; + + u3port1: usb-phy@1a244900 { + reg = <0 0x1a244900 0 0x0700>; + #phy-cells = <1>; + status = "okay"; + }; + }; + + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + ethsys: syscon@1b000000 { + compatible = "mediatek,mt7623-ethsys", + "mediatek,mt2701-ethsys", + "syscon"; + reg = <0 0x1b000000 0 0x1000>; + #clock-cells = <1>; + }; + + eth: ethernet@1b100000 { + compatible = "mediatek,mt2701-eth", "syscon"; + reg = <0 0x1b100000 0 0x20000>; + interrupts = , + , + ; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <ðsys CLK_ETHSYS_ESW>, + <ðsys CLK_ETHSYS_GP1>, + <ðsys CLK_ETHSYS_GP2>, + <&apmixedsys CLK_APMIXED_TRGPLL>; + clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; + mediatek,ethsys = <ðsys>; + mediatek,pctl = <&syscfg_pctl_a>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + crypto: crypto@1b240000 { + compatible = "mediatek,mt7623-crypto"; + reg = <0 0x1b240000 0 0x20000>; + interrupts = , + , + , + , + ; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <ðsys CLK_ETHSYS_CRYPTO>; + clock-names = "ethif","cryp"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; status = "disabled"; }; }; diff --git a/sys/gnu/dts/arm/omap3-cm-t3x.dtsi b/sys/gnu/dts/arm/omap3-cm-t3x.dtsi index 57b9a028a49a..fccd5383243c 100644 --- a/sys/gnu/dts/arm/omap3-cm-t3x.dtsi +++ b/sys/gnu/dts/arm/omap3-cm-t3x.dtsi @@ -188,7 +188,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/omap3-devkit8000-common.dtsi b/sys/gnu/dts/arm/omap3-devkit8000-common.dtsi index f330c69cc683..82aa9c4a0f1c 100644 --- a/sys/gnu/dts/arm/omap3-devkit8000-common.dtsi +++ b/sys/gnu/dts/arm/omap3-devkit8000-common.dtsi @@ -201,7 +201,8 @@ }; &gpmc { - ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ + ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */ + 6 0 0x2c000000 0x1000000>; /* CS6: 16MB for DM9000 */ nand@0,0 { compatible = "ti,omap2-nand"; @@ -256,12 +257,8 @@ reg = <0x680000 0xf980000>; }; }; -}; -&gpmc { - ranges = <6 0 0x2c000000 0x1000000>; /* CS6: 16MB for DM9000 */ - - ethernet@0,0 { + ethernet@6,0 { compatible = "davicom,dm9000"; reg = <6 0x000 2 6 0x400 2>; /* CS6, offset 0 and 0x400, IO size 2 */ diff --git a/sys/gnu/dts/arm/omap3-evm-37xx.dts b/sys/gnu/dts/arm/omap3-evm-37xx.dts index 4f9a76544602..c963b31ec3b3 100644 --- a/sys/gnu/dts/arm/omap3-evm-37xx.dts +++ b/sys/gnu/dts/arm/omap3-evm-37xx.dts @@ -34,7 +34,15 @@ >; }; +&hsusb2_phy { + pinctrl-names = "default"; + pinctrl-0 = <&ehci_phy_pins>; +}; + &omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = <&on_board_gpio_61 &hsusb2_pins>; + dss_dpi_pins1: pinmux_dss_dpi_pins2 { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */ @@ -98,6 +106,37 @@ >; }; + /* Devices are routed with gpmc_nbe1.gpio_61 to on-board devices */ + on_board_gpio_61: pinmux_ehci_port_select_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x20c8, PIN_OUTPUT | MUX_MODE4) + >; + }; + + /* Used by OHCI and EHCI. OHCI won't work without external phy */ + hsusb2_pins: pinmux_hsusb2_pins { + pinctrl-single,pins = < + + /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_cs1.hsusb2_data3 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) + >; + }; + wl12xx_gpio: pinmux_wl12xx_gpio { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */ @@ -112,6 +151,46 @@ }; }; +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_2_pins>; + + ehci_phy_pins: pinmux_ehci_phy_pins { + pinctrl-single,pins = < + + /* EHCI PHY reset GPIO etk_d7.gpio_21 */ + OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) + + /* EHCI VBUS etk_d8.gpio_22 */ + OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) + >; + }; + + /* Used by OHCI and EHCI. OHCI won't work without external phy */ + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + + /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) + + /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) + + /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d15.hsusb2_data1 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) + >; + }; +}; + &omap3_pmx_wkup { dss_dpi_pins2: pinmux_dss_dpi_pins1 { pinctrl-single,pins = < @@ -153,6 +232,29 @@ pinctrl-0 = <&uart3_pins>; }; +/* + * GPIO_61 (nUSB2_EN_1V8) must be low to enable on-board EHCI USB2 interface + * for bus switch SN74CB3Q3384A, level-shifter SN74AVC16T245DGGR, and 1.8V. + */ +&gpio2 { + en_usb2_port { + gpio-hog; + gpios = <29 GPIO_ACTIVE_HIGH>; /* gpio_61 */ + output-low; + line-name = "enable usb2 port"; + }; +}; + +/* T2_GPIO_2 low to route GPIO_61 to on-board devices */ +&twl_gpio { + en_on_board_gpio_61 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "en_hsusb2_clk"; + }; +}; + &gpmc { ranges = <0 0 0x30000000 0x1000000>, /* CS0: 16MB for NAND */ <5 0 0x2c000000 0x01000000>; diff --git a/sys/gnu/dts/arm/omap3-evm-common.dtsi b/sys/gnu/dts/arm/omap3-evm-common.dtsi index 090475083c2f..2b1d6977a535 100644 --- a/sys/gnu/dts/arm/omap3-evm-common.dtsi +++ b/sys/gnu/dts/arm/omap3-evm-common.dtsi @@ -12,6 +12,24 @@ }; }; + /* HS USB Port 2 Power */ + hsusb2_power: hsusb2_power_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb2_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>; /* gpio_22 */ + startup-delay-us = <70000>; + enable-active-high; + }; + + /* HS USB Host PHY on PORT 2 */ + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */ + vcc-supply = <&hsusb2_power>; + }; + leds { compatible = "gpio-leds"; ledb { @@ -76,7 +94,6 @@ &lcd_3v3 { gpio = <&gpio5 25 GPIO_ACTIVE_LOW>; /* gpio153 */ - enable-active-low; }; &lcd0 { @@ -143,6 +160,14 @@ >; }; +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + &usb_otg_hs { interface-type = <0>; usb-phy = <&usb2_phy>; @@ -159,3 +184,10 @@ reg = <5 0 0xff>; }; }; + +&vaux2 { + regulator-name = "usb_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; diff --git a/sys/gnu/dts/arm/omap3-gta04.dtsi b/sys/gnu/dts/arm/omap3-gta04.dtsi index 9ec737069369..4504908c23fe 100644 --- a/sys/gnu/dts/arm/omap3-gta04.dtsi +++ b/sys/gnu/dts/arm/omap3-gta04.dtsi @@ -419,7 +419,7 @@ /* RFID EEPROM */ m24lr64@50 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x50>; }; }; diff --git a/sys/gnu/dts/arm/omap3-overo-base.dtsi b/sys/gnu/dts/arm/omap3-overo-base.dtsi index 401fae838fe9..cd220342a805 100644 --- a/sys/gnu/dts/arm/omap3-overo-base.dtsi +++ b/sys/gnu/dts/arm/omap3-overo-base.dtsi @@ -74,16 +74,6 @@ gpio = <&gpio1 16 GPIO_ACTIVE_HIGH>; /* gpio_16: WiFi nReset */ startup-delay-us = <10000>; }; - - /* Regulator to trigger the nReset signal of the Bluetooth module */ - w3cbw003c_bt_nreset: regulator-w3cbw003c-bt-nreset { - compatible = "regulator-fixed"; - regulator-name = "regulator-w3cbw003c-bt-nreset"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* gpio_164: BT nReset */ - startup-delay-us = <10000>; - }; }; &omap3_pmx_core { @@ -191,7 +181,6 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&w3cbw003c_npoweron>; - vqmmc-supply = <&w3cbw003c_bt_nreset>; vmmc_aux-supply = <&w3cbw003c_wifi_nreset>; bus-width = <4>; cap-sdio-irq; diff --git a/sys/gnu/dts/arm/omap3-sb-t35.dtsi b/sys/gnu/dts/arm/omap3-sb-t35.dtsi index 73643fabde5d..4476fb685a1b 100644 --- a/sys/gnu/dts/arm/omap3-sb-t35.dtsi +++ b/sys/gnu/dts/arm/omap3-sb-t35.dtsi @@ -50,7 +50,6 @@ pinctrl-names = "default"; pinctrl-0 = <&sb_t35_audio_amp>; gpio = <&gpio2 29 GPIO_ACTIVE_LOW>; /* gpio_61 */ - enable-active-low; regulator-always-on; }; }; @@ -90,7 +89,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/omap3-tao3530.dtsi b/sys/gnu/dts/arm/omap3-tao3530.dtsi index dc80886b5329..06ac0f80bcf0 100644 --- a/sys/gnu/dts/arm/omap3-tao3530.dtsi +++ b/sys/gnu/dts/arm/omap3-tao3530.dtsi @@ -63,7 +63,6 @@ regulator-min-microvolt = <3150000>; regulator-max-microvolt = <3150000>; gpio = <&gpio5 29 GPIO_ACTIVE_LOW>; /* gpio_157 */ - enable-active-low; startup-delay-us = <10000>; }; }; diff --git a/sys/gnu/dts/arm/omap4-droid4-xt894.dts b/sys/gnu/dts/arm/omap4-droid4-xt894.dts index 89eb607f4a9e..10ca1c174995 100644 --- a/sys/gnu/dts/arm/omap4-droid4-xt894.dts +++ b/sys/gnu/dts/arm/omap4-droid4-xt894.dts @@ -301,7 +301,7 @@ #address-cells = <1>; #size-cells = <0>; wlcore: wlcore@2 { - compatible = "ti,wl1283"; + compatible = "ti,wl1285", "ti,wl1283"; reg = <2>; interrupt-parent = <&gpio4>; interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; /* gpio100 */ @@ -348,6 +348,17 @@ interrupt-names = "irq", "wakeup"; wakeup-source; }; + + isl29030@44 { + compatible = "isil,isl29030"; + reg = <0x44>; + + pinctrl-names = "default"; + pinctrl-0 = <&als_proximity_pins>; + + interrupt-parent = <&gpio6>; + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; /* gpio177 */ + }; }; &omap4_pmx_core { @@ -395,6 +406,12 @@ >; }; + als_proximity_pins: pinmux_als_proximity_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x18c, PIN_INPUT_PULLUP | MUX_MODE3) + >; + }; + usb_ulpi_pins: pinmux_usb_ulpi_pins { pinctrl-single,pins = < OMAP4_IOPAD(0x196, MUX_MODE7) @@ -453,6 +470,15 @@ OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7) >; }; + + uart4_pins: pinmux_uart4_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx */ + OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx */ + OMAP4_IOPAD(0x110, PIN_INPUT_PULLUP | MUX_MODE5) /* uart4_cts */ + OMAP4_IOPAD(0x112, PIN_OUTPUT_PULLUP | MUX_MODE5) /* uart4_rts */ + >; + }; }; &omap4_pmx_wkup { @@ -469,6 +495,17 @@ &omap4_pmx_core 0x17c>; }; +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + + bluetooth { + compatible = "ti,wl1285-st"; + enable-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* gpio 174 */ + max-speed = <3686400>; + }; +}; + &usbhsehci { phys = <&hsusb1_phy>; }; diff --git a/sys/gnu/dts/arm/omap4-duovero.dtsi b/sys/gnu/dts/arm/omap4-duovero.dtsi index ec0bd9779e1a..6e6810c258eb 100644 --- a/sys/gnu/dts/arm/omap4-duovero.dtsi +++ b/sys/gnu/dts/arm/omap4-duovero.dtsi @@ -12,6 +12,10 @@ model = "Gumstix Duovero"; compatible = "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4"; + chosen { + stdout-path = &uart3; + }; + memory@80000000 { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/sys/gnu/dts/arm/omap4-var-som-om44.dtsi b/sys/gnu/dts/arm/omap4-var-som-om44.dtsi index 758b6eb7ae43..6500bfc8d130 100644 --- a/sys/gnu/dts/arm/omap4-var-som-om44.dtsi +++ b/sys/gnu/dts/arm/omap4-var-som-om44.dtsi @@ -241,7 +241,7 @@ }; eeprom@50 { - compatible = "microchip,24c32"; + compatible = "microchip,24c32", "atmel,24c32"; reg = <0x50>; }; }; diff --git a/sys/gnu/dts/arm/omap4.dtsi b/sys/gnu/dts/arm/omap4.dtsi index 578c53f08309..64d00f5893a6 100644 --- a/sys/gnu/dts/arm/omap4.dtsi +++ b/sys/gnu/dts/arm/omap4.dtsi @@ -900,15 +900,24 @@ ctrl-module = <&omap_control_usbotg>; }; - aes: aes@4b501000 { + aes1: aes@4b501000 { compatible = "ti,omap4-aes"; - ti,hwmods = "aes"; + ti,hwmods = "aes1"; reg = <0x4b501000 0xa0>; interrupts = ; dmas = <&sdma 111>, <&sdma 110>; dma-names = "tx", "rx"; }; + aes2: aes@4b701000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes2"; + reg = <0x4b701000 0xa0>; + interrupts = ; + dmas = <&sdma 114>, <&sdma 113>; + dma-names = "tx", "rx"; + }; + des: des@480a5000 { compatible = "ti,omap4-des"; ti,hwmods = "des"; @@ -918,6 +927,15 @@ dma-names = "tx", "rx"; }; + sham: sham@4b100000 { + compatible = "ti,omap4-sham"; + ti,hwmods = "sham"; + reg = <0x4b100000 0x300>; + interrupts = ; + dmas = <&sdma 119>; + dma-names = "rx"; + }; + abb_mpu: regulator-abb-mpu { compatible = "ti,abb-v2"; regulator-name = "abb_mpu"; diff --git a/sys/gnu/dts/arm/omap44xx-clocks.dtsi b/sys/gnu/dts/arm/omap44xx-clocks.dtsi index 9573b37fbaa7..05732ed4f50f 100644 --- a/sys/gnu/dts/arm/omap44xx-clocks.dtsi +++ b/sys/gnu/dts/arm/omap44xx-clocks.dtsi @@ -357,6 +357,8 @@ compatible = "ti,omap4-dpll-clock"; clocks = <&sys_clkin_ck>, <&iva_hsd_byp_clk_mux_ck>; reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; + assigned-clocks = <&dpll_iva_ck>; + assigned-clock-rates = <931200000>; }; dpll_iva_x2_ck: dpll_iva_x2_ck { @@ -374,6 +376,8 @@ reg = <0x01b8>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_iva_m4x2_ck>; + assigned-clock-rates = <465600000>; }; dpll_iva_m5x2_ck: dpll_iva_m5x2_ck@1bc { @@ -385,6 +389,8 @@ reg = <0x01bc>; ti,index-starts-at-one; ti,invert-autoidle-bit; + assigned-clocks = <&dpll_iva_m5x2_ck>; + assigned-clock-rates = <266100000>; }; dpll_mpu_ck: dpll_mpu_ck@160 { @@ -969,22 +975,6 @@ ti,max-div = <2>; }; - aes1_fck: aes1_fck@15a0 { - #clock-cells = <0>; - compatible = "ti,gate-clock"; - clocks = <&l3_div_ck>; - ti,bit-shift = <1>; - reg = <0x15a0>; - }; - - aes2_fck: aes2_fck@15a8 { - #clock-cells = <0>; - compatible = "ti,gate-clock"; - clocks = <&l3_div_ck>; - ti,bit-shift = <1>; - reg = <0x15a8>; - }; - dss_sys_clk: dss_sys_clk@1120 { #clock-cells = <0>; compatible = "ti,gate-clock"; diff --git a/sys/gnu/dts/arm/omap5-cm-t54.dts b/sys/gnu/dts/arm/omap5-cm-t54.dts index b153f604932a..78397f66d0b2 100644 --- a/sys/gnu/dts/arm/omap5-cm-t54.dts +++ b/sys/gnu/dts/arm/omap5-cm-t54.dts @@ -404,7 +404,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/omap5-sbc-t54.dts b/sys/gnu/dts/arm/omap5-sbc-t54.dts index 337bbbc01a35..7b8810d13257 100644 --- a/sys/gnu/dts/arm/omap5-sbc-t54.dts +++ b/sys/gnu/dts/arm/omap5-sbc-t54.dts @@ -44,7 +44,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/sys/gnu/dts/arm/omap5-uevm.dts b/sys/gnu/dts/arm/omap5-uevm.dts index 0d42c46f13e7..ec2c8baef62a 100644 --- a/sys/gnu/dts/arm/omap5-uevm.dts +++ b/sys/gnu/dts/arm/omap5-uevm.dts @@ -137,6 +137,13 @@ }; }; +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + + cd-gpios = <&gpio5 24 GPIO_ACTIVE_LOW>; /* gpio5_152 */ +}; + &omap5_pmx_core { evm_keys_pins: pinmux_evm_keys_gpio_pins { pinctrl-single,pins = < @@ -150,6 +157,12 @@ OMAP5_IOPAD(0x1c8, PIN_INPUT | MUX_MODE0) /* i2c5_sda */ >; }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x1d4, PIN_INPUT_PULLUP | MUX_MODE6) /* gpio5_152 */ + >; + }; }; &tpd12s015 { diff --git a/sys/gnu/dts/arm/omap54xx-clocks.dtsi b/sys/gnu/dts/arm/omap54xx-clocks.dtsi index 4899c2359d0a..529193442620 100644 --- a/sys/gnu/dts/arm/omap54xx-clocks.dtsi +++ b/sys/gnu/dts/arm/omap54xx-clocks.dtsi @@ -315,6 +315,8 @@ compatible = "ti,omap4-dpll-clock"; clocks = <&sys_clkin>, <&dpll_iva_byp_mux>; reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; + assigned-clocks = <&dpll_iva_ck>; + assigned-clock-rates = <1165000000>; }; dpll_iva_x2_ck: dpll_iva_x2_ck { @@ -330,6 +332,8 @@ ti,max-div = <63>; reg = <0x01b8>; ti,index-starts-at-one; + assigned-clocks = <&dpll_iva_h11x2_ck>; + assigned-clock-rates = <465920000>; }; dpll_iva_h12x2_ck: dpll_iva_h12x2_ck@1bc { @@ -339,6 +343,8 @@ ti,max-div = <63>; reg = <0x01bc>; ti,index-starts-at-one; + assigned-clocks = <&dpll_iva_h12x2_ck>; + assigned-clock-rates = <388300000>; }; mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div { diff --git a/sys/gnu/dts/arm/owl-s500-guitar-bb-rev-b.dts b/sys/gnu/dts/arm/owl-s500-guitar-bb-rev-b.dts new file mode 100644 index 000000000000..521463d4cac6 --- /dev/null +++ b/sys/gnu/dts/arm/owl-s500-guitar-bb-rev-b.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; + +#include "owl-s500-guitar.dtsi" + +/ { + compatible = "lemaker,guitar-bb-rev-b", "lemaker,guitar", "actions,s500"; + model = "LeMaker Guitar Base Board rev. B"; + + aliases { + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial3:115200n8"; + }; +}; + +&uart3 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/owl-s500-guitar.dtsi b/sys/gnu/dts/arm/owl-s500-guitar.dtsi new file mode 100644 index 000000000000..079b2c02cc13 --- /dev/null +++ b/sys/gnu/dts/arm/owl-s500-guitar.dtsi @@ -0,0 +1,22 @@ +/* + * LeMaker Guitar SoM + * + * Copyright (c) 2016-2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#include "owl-s500.dtsi" + +/ { + compatible = "lemaker,guitar", "actions,s500"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; +}; + +&timer { + clocks = <&hosc>; +}; diff --git a/sys/gnu/dts/arm/owl-s500.dtsi b/sys/gnu/dts/arm/owl-s500.dtsi new file mode 100644 index 000000000000..51a48741d4c0 --- /dev/null +++ b/sys/gnu/dts/arm/owl-s500.dtsi @@ -0,0 +1,186 @@ +/* + * Actions Semi S500 SoC + * + * Copyright (c) 2016-2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#include + +/ { + compatible = "actions,s500"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0x0>; + enable-method = "actions,s500-smp"; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0x1>; + enable-method = "actions,s500-smp"; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0x2>; + enable-method = "actions,s500-smp"; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0x3>; + enable-method = "actions,s500-smp"; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + hosc: hosc { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + scu: scu@b0020000 { + compatible = "arm,cortex-a9-scu"; + reg = <0xb0020000 0x100>; + }; + + global_timer: timer@b0020200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xb0020200 0x100>; + interrupts = ; + status = "disabled"; + }; + + twd_timer: timer@b0020600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xb0020600 0x20>; + interrupts = ; + status = "disabled"; + }; + + twd_wdt: wdt@b0020620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0xb0020620 0xe0>; + interrupts = ; + status = "disabled"; + }; + + gic: interrupt-controller@b0021000 { + compatible = "arm,cortex-a9-gic"; + reg = <0xb0021000 0x1000>, + <0xb0020100 0x0100>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + l2: cache-controller@b0022000 { + compatible = "arm,pl310-cache"; + reg = <0xb0022000 0x1000>; + cache-unified; + cache-level = <2>; + interrupts = ; + arm,tag-latency = <3 3 2>; + arm,data-latency = <5 3 3>; + }; + + uart0: serial@b0120000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb0120000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart1: serial@b0122000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb0122000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart2: serial@b0124000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb0124000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart3: serial@b0126000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb0126000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart4: serial@b0128000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb0128000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart5: serial@b012a000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb012a000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + uart6: serial@b012c000 { + compatible = "actions,s500-uart", "actions,owl-uart"; + reg = <0xb012c000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + timer: timer@b0168000 { + compatible = "actions,s500-timer"; + reg = <0xb0168000 0x8000>; + interrupts = , + , + , + ; + interrupt-names = "2hz0", "2hz1", "timer0", "timer1"; + }; + + sps: power-controller@b01b0100 { + compatible = "actions,s500-sps"; + reg = <0xb01b0100 0x100>; + #power-domain-cells = <1>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/pm9g45.dts b/sys/gnu/dts/arm/pm9g45.dts index 0abd7bf17568..3139221737ee 100644 --- a/sys/gnu/dts/arm/pm9g45.dts +++ b/sys/gnu/dts/arm/pm9g45.dts @@ -37,12 +37,10 @@ }; pinctrl@fffff200 { - - board { - pinctrl_board_nand: nand0-board { + nand { + pinctrl_nand_rb: nand-rb-0 { atmel,pins = - ; /* PC14 gpio enable pin pull_up */ + ; }; }; @@ -71,50 +69,61 @@ phy-mode = "rmii"; status = "okay"; }; - }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; - pinctrl-0 = <&pinctrl_board_nand>; - - gpios = <&pioD 3 GPIO_ACTIVE_HIGH - &pioC 14 GPIO_ACTIVE_HIGH - 0 - >; - + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioD 3 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x1A0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - kernel@200000 { - label = "bareboxenv2"; - reg = <0x200000 0x300000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - kernel@500000 { - label = "root"; - reg = <0x500000 0x400000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - data@900000 { - label = "data"; - reg = <0x900000 0x8340000>; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x1A0000>; + }; + + kernel@200000 { + label = "bareboxenv2"; + reg = <0x200000 0x300000>; + }; + + kernel@500000 { + label = "root"; + reg = <0x500000 0x400000>; + }; + + data@900000 { + label = "data"; + reg = <0x900000 0x8340000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/pxa25x.dtsi b/sys/gnu/dts/arm/pxa25x.dtsi index f9f4726396a0..95d59be97213 100644 --- a/sys/gnu/dts/arm/pxa25x.dtsi +++ b/sys/gnu/dts/arm/pxa25x.dtsi @@ -93,22 +93,22 @@ pxa250_opp_table: opp_table0 { compatible = "operating-points-v2"; - opp@99532800 { + opp-99532800 { opp-hz = /bits/ 64 <99532800>; opp-microvolt = <1000000 950000 1650000>; clock-latency-ns = <20>; }; - opp@199065600 { + opp-199065600 { opp-hz = /bits/ 64 <199065600>; opp-microvolt = <1000000 950000 1650000>; clock-latency-ns = <20>; }; - opp@298598400 { + opp-298598400 { opp-hz = /bits/ 64 <298598400>; opp-microvolt = <1100000 1045000 1650000>; clock-latency-ns = <20>; }; - opp@398131200 { + opp-398131200 { opp-hz = /bits/ 64 <398131200>; opp-microvolt = <1300000 1235000 1650000>; clock-latency-ns = <20>; diff --git a/sys/gnu/dts/arm/pxa27x.dtsi b/sys/gnu/dts/arm/pxa27x.dtsi index e0fab48ba6fa..5f1d6da02a4c 100644 --- a/sys/gnu/dts/arm/pxa27x.dtsi +++ b/sys/gnu/dts/arm/pxa27x.dtsi @@ -141,37 +141,37 @@ pxa270_opp_table: opp_table0 { compatible = "operating-points-v2"; - opp@104000000 { + opp-104000000 { opp-hz = /bits/ 64 <104000000>; opp-microvolt = <900000 900000 1705000>; clock-latency-ns = <20>; }; - opp@156000000 { + opp-156000000 { opp-hz = /bits/ 64 <156000000>; opp-microvolt = <1000000 1000000 1705000>; clock-latency-ns = <20>; }; - opp@208000000 { + opp-208000000 { opp-hz = /bits/ 64 <208000000>; opp-microvolt = <1180000 1180000 1705000>; clock-latency-ns = <20>; }; - opp@312000000 { + opp-312000000 { opp-hz = /bits/ 64 <312000000>; opp-microvolt = <1250000 1250000 1705000>; clock-latency-ns = <20>; }; - opp@416000000 { + opp-416000000 { opp-hz = /bits/ 64 <416000000>; opp-microvolt = <1350000 1350000 1705000>; clock-latency-ns = <20>; }; - opp@520000000 { + opp-520000000 { opp-hz = /bits/ 64 <520000000>; opp-microvolt = <1450000 1450000 1705000>; clock-latency-ns = <20>; }; - opp@624000000 { + opp-624000000 { opp-hz = /bits/ 64 <624000000>; opp-microvolt = <1550000 1550000 1705000>; clock-latency-ns = <20>; diff --git a/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts b/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts index 2da1413f5720..9d725f983282 100644 --- a/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts +++ b/sys/gnu/dts/arm/qcom-apq8060-dragonboard.dts @@ -23,6 +23,7 @@ #include #include #include +#include #include "qcom-msm8660.dtsi" / { @@ -83,6 +84,25 @@ }; }; + /* + * Capella CM3605 light and proximity sensor mounted directly + * on the sensor board. + */ + cm3605 { + compatible = "capella,cm3605"; + vdd-supply = <&pm8058_l14>; // 2.85V + aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>; + capella,aset-resistance-ohms = <100000>; + /* GPIO34 has interrupt 225 on the PM8058 */ + /* Trig on both edges - getting close or far away */ + interrupts-extended = <&pm8058 225 IRQ_TYPE_EDGE_BOTH>; + /* MPP05 analog input to the XOADC */ + io-channels = <&xoadc 0x00 0x05>; + io-channel-names = "aout"; + pinctrl-names = "default"; + pinctrl-0 = <&dragon_cm3605_gpios>, <&dragon_cm3605_mpps>; + }; + soc { pinctrl@800000 { /* eMMMC pins, all 8 data lines connected */ @@ -160,6 +180,19 @@ }; }; + dragon_gsbi8_i2c_pins: gsbi8_i2c { + mux { + pins = "gpio64", "gpio65"; + function = "gsbi8"; + }; + pinconf { + pins = "gpio64", "gpio65"; + drive-strength = <16>; + /* These have external pull-up 2.2kOhm to 1.8V */ + bias-disable; + }; + }; + dragon_gsbi12_i2c_pins: gsbi12_i2c { mux { pins = "gpio115", "gpio116"; @@ -317,6 +350,24 @@ power-source = ; }; }; + dragon_cm3605_gpios: cm3605-gpios { + /* Pin 34 connected to the proxy IRQ */ + pinconf_gpio34 { + pins = "gpio34"; + function = "normal"; + input-enable; + bias-disable; + power-source = ; + }; + /* Pin 35 connected to ASET */ + pinconf_gpio35 { + pins = "gpio35"; + function = "normal"; + output-high; + bias-disable; + power-source = ; + }; + }; dragon_veth_gpios: veth-gpios { pinconf { pins = "gpio40"; @@ -327,6 +378,47 @@ }; }; + mpps@50 { + dragon_cm3605_mpps: cm3605-mpps { + pinconf { + pins = "mpp5"; + function = "analog"; + input-enable; + bias-high-impedance; + /* Let's use channel 5 */ + qcom,amux-route = ; + power-source = ; + }; + }; + }; + + xoadc@197 { + /* Reference voltage 2.2 V */ + xoadc-ref-supply = <&pm8058_l18>; + + /* Board-specific channels */ + mpp5@05 { + /* Connected to AOUT of ALS sensor */ + reg = <0x00 0x05>; + }; + mpp6@06 { + /* Connected to test point TP43 */ + reg = <0x00 0x06>; + }; + mpp7@07 { + /* Connected to battery thermistor */ + reg = <0x00 0x07>; + }; + mpp8@08 { + /* Connected to battery ID detector */ + reg = <0x00 0x08>; + }; + mpp9@09 { + /* Connected to XO thermistor */ + reg = <0x00 0x09>; + }; + }; + led@48 { /* * The keypad LED @0x48 is routed to @@ -340,6 +432,7 @@ reg = <0x48>; label = "pm8058:infrared:proximitysensor"; default-state = "off"; + linux,default-trigger = "cm3605"; }; led@131 { compatible = "qcom,pm8058-led"; @@ -368,6 +461,42 @@ }; }; + gsbi@19800000 { + status = "ok"; + qcom,mode = ; + + i2c@19880000 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&dragon_gsbi8_i2c_pins>; + + eeprom@52 { + /* A 16KiB Platform ID EEPROM on the CPU carrier board */ + compatible = "atmel,24c128"; + reg = <0x52>; + vcc-supply = <&pm8058_s3>; + pagesize = <64>; + }; + wm8903: wm8903@1a { + /* This Woolfson Micro device has an unrouted interrupt line */ + compatible = "wlf,wm8903"; + reg = <0x1a>; + + AVDD-supply = <&pm8058_l16>; + CPVDD-supply = <&pm8058_l16>; + DBVDD-supply = <&pm8058_s3>; + DCVDD-supply = <&pm8058_l0>; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; + }; + }; + }; + gsbi@19c00000 { status = "ok"; qcom,mode = ; diff --git a/sys/gnu/dts/arm/qcom-apq8064-arrow-sd-600eval.dts b/sys/gnu/dts/arm/qcom-apq8064-arrow-sd-600eval.dts index 8f5de029bca9..f245064f320e 100644 --- a/sys/gnu/dts/arm/qcom-apq8064-arrow-sd-600eval.dts +++ b/sys/gnu/dts/arm/qcom-apq8064-arrow-sd-600eval.dts @@ -319,44 +319,38 @@ target-supply = <&pm8921_lvs7>; }; - /* OTG */ - phy@12500000 { - status = "okay"; - dr_mode = "peripheral"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget@12500000 { - status = "okay"; - }; - /* OTG */ usb@12500000 { status = "okay"; + dr_mode = "peripheral"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; usb@12520000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; usb@12530000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; amba { diff --git a/sys/gnu/dts/arm/qcom-apq8064-asus-nexus7-flo.dts b/sys/gnu/dts/arm/qcom-apq8064-asus-nexus7-flo.dts index e39440a86739..3483a66e44c1 100644 --- a/sys/gnu/dts/arm/qcom-apq8064-asus-nexus7-flo.dts +++ b/sys/gnu/dts/arm/qcom-apq8064-asus-nexus7-flo.dts @@ -320,22 +320,16 @@ }; }; - /* OTG */ - phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - dr_mode = "otg"; - }; - - gadget@12500000 { - status = "okay"; - }; - /* OTG */ usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; amba { diff --git a/sys/gnu/dts/arm/qcom-apq8064-cm-qs600.dts b/sys/gnu/dts/arm/qcom-apq8064-cm-qs600.dts index 35f1d46edded..5b151e425530 100644 --- a/sys/gnu/dts/arm/qcom-apq8064-cm-qs600.dts +++ b/sys/gnu/dts/arm/qcom-apq8064-cm-qs600.dts @@ -150,42 +150,37 @@ }; /* OTG */ - usb1_phy: phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - usb3_phy: phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - usb4_phy: phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget1: gadget@12500000 { + usb@12500000 { status = "ok"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; - /* OTG */ - usb1: usb@12500000 { - status = "ok"; - }; - - usb3: usb@12520000 { + usb@12520000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; - usb4: usb@12530000 { + usb@12530000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; /* on board fixed 3.3v supply */ diff --git a/sys/gnu/dts/arm/qcom-apq8064-ifc6410.dts b/sys/gnu/dts/arm/qcom-apq8064-ifc6410.dts index 881ce707311a..053b5bdd7808 100644 --- a/sys/gnu/dts/arm/qcom-apq8064-ifc6410.dts +++ b/sys/gnu/dts/arm/qcom-apq8064-ifc6410.dts @@ -244,42 +244,37 @@ }; /* OTG */ - usb1_phy: phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - usb3_phy: phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - usb4_phy: phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget1: gadget@12500000 { + usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; - /* OTG */ - usb1: usb@12500000 { + usb@12520000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; - usb3: usb@12520000 { - status = "okay"; - }; - - usb4: usb@12530000 { + usb@12530000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; pci@1b500000 { diff --git a/sys/gnu/dts/arm/qcom-apq8064-sony-xperia-yuga.dts b/sys/gnu/dts/arm/qcom-apq8064-sony-xperia-yuga.dts index a34ba3555454..88a9aff41e2f 100644 --- a/sys/gnu/dts/arm/qcom-apq8064-sony-xperia-yuga.dts +++ b/sys/gnu/dts/arm/qcom-apq8064-sony-xperia-yuga.dts @@ -349,15 +349,15 @@ }; }; - phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - gadget@12500000 { + usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; gsbi@1a200000 { diff --git a/sys/gnu/dts/arm/qcom-apq8064.dtsi b/sys/gnu/dts/arm/qcom-apq8064.dtsi index 14a6f5ed02de..f3db185a6809 100644 --- a/sys/gnu/dts/arm/qcom-apq8064.dtsi +++ b/sys/gnu/dts/arm/qcom-apq8064.dtsi @@ -197,7 +197,7 @@ clock-frequency = <27000000>; }; - sleep_clk { + sleep_clk: sleep_clk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32768>; @@ -884,81 +884,97 @@ }; }; - usb1_phy: phy@12500000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12500000 0x400>; - interrupts = ; - status = "disabled"; - - clocks = <&gcc USB_HS1_XCVR_CLK>, - <&gcc USB_HS1_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS1_RESET>; - reset-names = "link"; - }; - - usb3_phy: phy@12520000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12520000 0x400>; - interrupts = ; - status = "disabled"; - dr_mode = "host"; - - clocks = <&gcc USB_HS3_XCVR_CLK>, - <&gcc USB_HS3_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS3_RESET>; - reset-names = "link"; - }; - - usb4_phy: phy@12530000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12530000 0x400>; - interrupts = ; - status = "disabled"; - dr_mode = "host"; - - clocks = <&gcc USB_HS4_XCVR_CLK>, - <&gcc USB_HS4_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS4_RESET>; - reset-names = "link"; - }; - - gadget1: gadget@12500000 { - compatible = "qcom,ci-hdrc"; - reg = <0x12500000 0x400>; - status = "disabled"; - dr_mode = "peripheral"; - interrupts = ; - usb-phy = <&usb1_phy>; - }; - usb1: usb@12500000 { - compatible = "qcom,ehci-host"; - reg = <0x12500000 0x400>; - interrupts = ; - status = "disabled"; - usb-phy = <&usb1_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12500000 0x200>, + <0x12500200 0x200>; + interrupts = ; + clocks = <&gcc USB_HS1_XCVR_CLK>, <&gcc USB_HS1_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS1_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS1_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs1_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs1_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb1 0>; + reset-names = "por"; + }; + }; }; usb3: usb@12520000 { - compatible = "qcom,ehci-host"; - reg = <0x12520000 0x400>; - interrupts = ; - status = "disabled"; - usb-phy = <&usb3_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12520000 0x200>, + <0x12520200 0x200>; + interrupts = ; + clocks = <&gcc USB_HS3_XCVR_CLK>, <&gcc USB_HS3_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS3_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS3_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs3_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs3_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb3 0>; + reset-names = "por"; + }; + }; }; usb4: usb@12530000 { - compatible = "qcom,ehci-host"; - reg = <0x12530000 0x400>; - interrupts = ; - status = "disabled"; - usb-phy = <&usb4_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12530000 0x200>, + <0x12530200 0x200>; + interrupts = ; + clocks = <&gcc USB_HS4_XCVR_CLK>, <&gcc USB_HS4_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS4_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS4_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs4_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs4_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb4 0>; + reset-names = "por"; + }; + }; }; sata_phy0: phy@1b400000 { diff --git a/sys/gnu/dts/arm/qcom-apq8074-dragonboard.dts b/sys/gnu/dts/arm/qcom-apq8074-dragonboard.dts index ad51df27dfb7..32f3b81f609c 100644 --- a/sys/gnu/dts/arm/qcom-apq8074-dragonboard.dts +++ b/sys/gnu/dts/arm/qcom-apq8074-dragonboard.dts @@ -44,6 +44,26 @@ vqmmc-supply = <&pm8941_l13>; }; + usb@f9a55000 { + status = "ok"; + phys = <&usb_hs2_phy>; + phy-select = <&tcsr 0xb000 1>; + extcon = <&smbb>, <&usb_id>; + vbus-supply = <&chg_otg>; + hnp-disable; + srp-disable; + adp-disable; + ulpi { + phy@b { + status = "ok"; + v3p3-supply = <&pm8941_l24>; + v1p8-supply = <&pm8941_l6>; + extcon = <&smbb>; + qcom,init-seq = /bits/ 8 <0x1 0x63>; + }; + }; + }; + pinctrl@fd510000 { i2c11_pins: i2c11 { diff --git a/sys/gnu/dts/arm/qcom-ipq4019.dtsi b/sys/gnu/dts/arm/qcom-ipq4019.dtsi index b7a24af8f47b..4b7d97275c62 100644 --- a/sys/gnu/dts/arm/qcom-ipq4019.dtsi +++ b/sys/gnu/dts/arm/qcom-ipq4019.dtsi @@ -154,10 +154,10 @@ i2c_0: i2c@78b7000 { compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x78b7000 0x6000>; + reg = <0x78b7000 0x600>; interrupts = ; clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; + <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>; clock-names = "iface", "core"; #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/qcom-ipq8064.dtsi b/sys/gnu/dts/arm/qcom-ipq8064.dtsi index 76f4e8921d58..f1fbffe59b93 100644 --- a/sys/gnu/dts/arm/qcom-ipq8064.dtsi +++ b/sys/gnu/dts/arm/qcom-ipq8064.dtsi @@ -284,6 +284,29 @@ }; }; + gsbi7: gsbi@16600000 { + status = "disabled"; + compatible = "qcom,gsbi-v1.0.0"; + cell-index = <7>; + reg = <0x16600000 0x100>; + clocks = <&gcc GSBI7_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + syscon-tcsr = <&tcsr>; + + gsbi7_serial: serial@16640000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x16640000 0x1000>, + <0x16600000 0x1000>; + interrupts = <0 158 0x0>; + clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + }; + sata_phy: sata-phy@1b400000 { compatible = "qcom,ipq806x-sata-phy"; reg = <0x1b400000 0x200>; diff --git a/sys/gnu/dts/arm/qcom-msm8660.dtsi b/sys/gnu/dts/arm/qcom-msm8660.dtsi index 747669a62aa8..1b5d31b33b5e 100644 --- a/sys/gnu/dts/arm/qcom-msm8660.dtsi +++ b/sys/gnu/dts/arm/qcom-msm8660.dtsi @@ -63,6 +63,22 @@ }; }; + /* + * These channels from the ADC are simply hardware monitors. + * That is why the ADC is referred to as "HKADC" - HouseKeeping + * ADC. + */ + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&xoadc 0x00 0x01>, /* Battery */ + <&xoadc 0x00 0x02>, /* DC in (charger) */ + <&xoadc 0x00 0x04>, /* VPH the main system voltage */ + <&xoadc 0x00 0x0b>, /* Die temperature */ + <&xoadc 0x00 0x0c>, /* Reference voltage 1.25V */ + <&xoadc 0x00 0x0d>, /* Reference voltage 0.625V */ + <&xoadc 0x00 0x0e>; /* Reference voltage 0.325V */ + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; @@ -107,6 +123,31 @@ reg = <0x900000 0x4000>; }; + + gsbi8: gsbi@19800000 { + compatible = "qcom,gsbi-v1.0.0"; + cell-index = <12>; + reg = <0x19800000 0x100>; + clocks = <&gcc GSBI8_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + syscon-tcsr = <&tcsr>; + + gsbi8_i2c: i2c@19880000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x19880000 0x1000>; + interrupts = ; + clocks = <&gcc GSBI8_QUP_CLK>, <&gcc GSBI8_H_CLK>; + clock-names = "core", "iface"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + gsbi12: gsbi@19c00000 { compatible = "qcom,gsbi-v1.0.0"; cell-index = <12>; @@ -267,6 +308,49 @@ row-hold = <91500>; }; + xoadc: xoadc@197 { + compatible = "qcom,pm8058-adc"; + reg = <0x197>; + interrupts-extended = <&pm8058 76 IRQ_TYPE_EDGE_RISING>; + #address-cells = <2>; + #size-cells = <0>; + #io-channel-cells = <2>; + + vcoin: adc-channel@00 { + reg = <0x00 0x00>; + }; + vbat: adc-channel@01 { + reg = <0x00 0x01>; + }; + dcin: adc-channel@02 { + reg = <0x00 0x02>; + }; + ichg: adc-channel@03 { + reg = <0x00 0x03>; + }; + vph_pwr: adc-channel@04 { + reg = <0x00 0x04>; + }; + usb_vbus: adc-channel@0a { + reg = <0x00 0x0a>; + }; + die_temp: adc-channel@0b { + reg = <0x00 0x0b>; + }; + ref_625mv: adc-channel@0c { + reg = <0x00 0x0c>; + }; + ref_1250mv: adc-channel@0d { + reg = <0x00 0x0d>; + }; + ref_325mv: adc-channel@0e { + reg = <0x00 0x0e>; + }; + ref_muxoff: adc-channel@0f { + reg = <0x00 0x0f>; + }; + }; + rtc@1e8 { compatible = "qcom,pm8058-rtc"; reg = <0x1e8>; diff --git a/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts b/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts index e7c1577d56f4..50966378f9e4 100644 --- a/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts +++ b/sys/gnu/dts/arm/qcom-msm8974-sony-xperia-honami.dts @@ -92,7 +92,6 @@ vdd_l9_l10_l17_l22-supply = <&vreg_boost>; vdd_l13_l20_l23_l24-supply = <&vreg_boost>; vdd_l21-supply = <&vreg_boost>; - vin_5vs-supply = <&pm8941_5v>; s1 { regulator-min-microvolt = <1300000>; diff --git a/sys/gnu/dts/arm/qcom-msm8974.dtsi b/sys/gnu/dts/arm/qcom-msm8974.dtsi index 307bf6a647b3..c5ee68a3f7f5 100644 --- a/sys/gnu/dts/arm/qcom-msm8974.dtsi +++ b/sys/gnu/dts/arm/qcom-msm8974.dtsi @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "skeleton.dtsi" @@ -551,6 +552,11 @@ reg = <0xfc400000 0x4000>; }; + tcsr: syscon@fd4a0000 { + compatible = "syscon"; + reg = <0xfd4a0000 0x10000>; + }; + tcsr_mutex_block: syscon@fd484000 { compatible = "syscon"; reg = <0xfd484000 0x2000>; @@ -620,6 +626,50 @@ status = "disabled"; }; + otg: usb@f9a55000 { + compatible = "qcom,ci-hdrc"; + reg = <0xf9a55000 0x200>, + <0xf9a55200 0x200>; + interrupts = ; + clocks = <&gcc GCC_USB_HS_AHB_CLK>, + <&gcc GCC_USB_HS_SYSTEM_CLK>; + clock-names = "iface", "core"; + assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; + assigned-clock-rates = <75000000>; + resets = <&gcc GCC_USB_HS_BCR>; + reset-names = "core"; + phy_type = "ulpi"; + dr_mode = "otg"; + ahb-burst-config = <0>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs1_phy: phy@a { + compatible = "qcom,usb-hs-phy-msm8974", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>; + reset-names = "phy", "por"; + status = "disabled"; + }; + + usb_hs2_phy: phy@b { + compatible = "qcom,usb-hs-phy-msm8974", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2B_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2B_PHY_BCR>, <&otg 1>; + reset-names = "phy", "por"; + status = "disabled"; + }; + }; + }; + rng@f9bff000 { compatible = "qcom,prng"; reg = <0xf9bff000 0x200>; @@ -1021,7 +1071,6 @@ pm8941_s1: s1 {}; pm8941_s2: s2 {}; pm8941_s3: s3 {}; - pm8941_5v: s4 {}; pm8941_l1: l1 {}; pm8941_l2: l2 {}; @@ -1051,9 +1100,6 @@ pm8941_lvs1: lvs1 {}; pm8941_lvs2: lvs2 {}; pm8941_lvs3: lvs3 {}; - - pm8941_5vs1: 5vs1 {}; - pm8941_5vs2: 5vs2 {}; }; }; }; diff --git a/sys/gnu/dts/arm/qcom-pm8941.dtsi b/sys/gnu/dts/arm/qcom-pm8941.dtsi index f8eb5e31c920..3fc9f34f45bb 100644 --- a/sys/gnu/dts/arm/qcom-pm8941.dtsi +++ b/sys/gnu/dts/arm/qcom-pm8941.dtsi @@ -26,7 +26,14 @@ bias-pull-up; }; - charger@1000 { + usb_id: misc@900 { + compatible = "qcom,pm8941-misc"; + reg = <0x900>; + interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "usb_id"; + }; + + smbb: charger@1000 { compatible = "qcom,pm8941-charger"; reg = <0x1000>; interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, @@ -45,6 +52,10 @@ "chg-gone", "usb-valid", "dc-valid"; + + usb-otg-in-supply = <&pm8941_5vs1>; + + chg_otg: otg-vbus { }; }; pm8941_gpios: gpios@c000 { @@ -171,5 +182,28 @@ status = "disabled"; }; + + regulators { + compatible = "qcom,pm8941-regulators"; + interrupts = <0x1 0x83 0x2 0>, <0x1 0x84 0x2 0>; + interrupt-names = "ocp-5vs1", "ocp-5vs2"; + vin_5vs-supply = <&pm8941_5v>; + + pm8941_5v: s4 { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-enable-ramp-delay = <500>; + }; + + pm8941_5vs1: 5vs1 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/r7s72100-gr-peach.dts b/sys/gnu/dts/arm/r7s72100-gr-peach.dts new file mode 100644 index 000000000000..a1b2aef984f6 --- /dev/null +++ b/sys/gnu/dts/arm/r7s72100-gr-peach.dts @@ -0,0 +1,66 @@ +/* + * Device Tree Source for the GR-Peach board + * + * Copyright (C) 2017 Jacopo Mondi + * Copyright (C) 2016 Renesas Electronics + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r7s72100.dtsi" + +/ { + model = "GR-Peach"; + compatible = "renesas,gr-peach", "renesas,r7s72100"; + + aliases { + serial0 = &scif2; + }; + + chosen { + bootargs = "ignore_loglevel rw root=/dev/mtdblock0"; + stdout-path = "serial0:115200n8"; + }; + + memory@20000000 { + device_type = "memory"; + reg = <0x20000000 0x00a00000>; + + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; + + flash@18000000 { + compatible = "mtd-rom"; + probe-type = "map_rom"; + reg = <0x18000000 0x00800000>; + bank-width = <4>; + device-width = <1>; + + #address-cells = <1>; + #size-cells = <1>; + + rootfs@600000 { + label = "rootfs"; + reg = <0x00600000 0x00200000>; + }; + }; +}; + +&extal_clk { + clock-frequency = <13333000>; +}; + +&usb_x1_clk { + clock-frequency = <48000000>; +}; + +&scif2 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/r7s72100.dtsi b/sys/gnu/dts/arm/r7s72100.dtsi index 0423996e4dcc..5cf53e9943af 100644 --- a/sys/gnu/dts/arm/r7s72100.dtsi +++ b/sys/gnu/dts/arm/r7s72100.dtsi @@ -144,9 +144,9 @@ #clock-cells = <1>; compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0xfcfe0430 4>; - clocks = <&b_clk>; - clock-indices = ; - clock-output-names = "ether"; + clocks = <&b_clk>, <&p1_clk>, <&p1_clk>; + clock-indices = ; + clock-output-names = "ether", "usb0", "usb1"; }; mstp8_clks: mstp8_clks@fcfe0434 { diff --git a/sys/gnu/dts/arm/r8a73a4.dtsi b/sys/gnu/dts/arm/r8a73a4.dtsi index 1f5c9f6dddba..310222634570 100644 --- a/sys/gnu/dts/arm/r8a73a4.dtsi +++ b/sys/gnu/dts/arm/r8a73a4.dtsi @@ -219,7 +219,7 @@ power-domains = <&pd_c4>; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-r8a73a4"; reg = <0 0xe6050000 0 0x9000>; gpio-controller; diff --git a/sys/gnu/dts/arm/r8a7740-armadillo800eva.dts b/sys/gnu/dts/arm/r8a7740-armadillo800eva.dts index 7885075428bb..1788e186a512 100644 --- a/sys/gnu/dts/arm/r8a7740-armadillo800eva.dts +++ b/sys/gnu/dts/arm/r8a7740-armadillo800eva.dts @@ -266,7 +266,9 @@ lcd0_pins: lcd0 { groups = "lcd0_data24_0", "lcd0_lclk_1", "lcd0_sync"; function = "lcd0"; + }; + lcd0_mux { /* DBGMD/LCDC0/FSIA MUX */ gpio-hog; gpios = <176 0>; diff --git a/sys/gnu/dts/arm/r8a7740.dtsi b/sys/gnu/dts/arm/r8a7740.dtsi index 34159a8349de..d37d22682a63 100644 --- a/sys/gnu/dts/arm/r8a7740.dtsi +++ b/sys/gnu/dts/arm/r8a7740.dtsi @@ -299,7 +299,7 @@ status = "disabled"; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-r8a7740"; reg = <0xe6050000 0x8000>, <0xe605800c 0x20>; diff --git a/sys/gnu/dts/arm/r8a7743-iwg20d-q7.dts b/sys/gnu/dts/arm/r8a7743-iwg20d-q7.dts new file mode 100644 index 000000000000..9b54783cc2a5 --- /dev/null +++ b/sys/gnu/dts/arm/r8a7743-iwg20d-q7.dts @@ -0,0 +1,25 @@ +/* + * Device Tree Source for the iWave-RZG1M Qseven carrier board + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r8a7743-iwg20m.dtsi" + +/ { + model = "iWave Systems RainboW-G20D-Qseven board based on RZ/G1M"; + compatible = "iwave,g20d", "iwave,g20m", "renesas,r8a7743"; + + aliases { + serial0 = &scif0; + }; +}; + +&scif0 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/r8a7743-iwg20m.dtsi b/sys/gnu/dts/arm/r8a7743-iwg20m.dtsi new file mode 100644 index 000000000000..001ca9144f4b --- /dev/null +++ b/sys/gnu/dts/arm/r8a7743-iwg20m.dtsi @@ -0,0 +1,29 @@ +/* + * Device Tree Source for the iWave-RZG1M-20M Qseven SOM + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include "r8a7743.dtsi" + +/ { + compatible = "iwave,g20m", "renesas,r8a7743"; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x20000000>; + }; + + memory@200000000 { + device_type = "memory"; + reg = <2 0x00000000 0 0x20000000>; + }; +}; + +&extal_clk { + clock-frequency = <20000000>; +}; diff --git a/sys/gnu/dts/arm/r8a7778.dtsi b/sys/gnu/dts/arm/r8a7778.dtsi index 1e93c94a9eac..8f3156c0e575 100644 --- a/sys/gnu/dts/arm/r8a7778.dtsi +++ b/sys/gnu/dts/arm/r8a7778.dtsi @@ -142,7 +142,7 @@ interrupt-controller; }; - pfc: pfc@fffc0000 { + pfc: pin-controller@fffc0000 { compatible = "renesas,pfc-r8a7778"; reg = <0xfffc0000 0x118>; }; diff --git a/sys/gnu/dts/arm/r8a7779.dtsi b/sys/gnu/dts/arm/r8a7779.dtsi index ae2d9a9c65af..8ee0b2ca5d39 100644 --- a/sys/gnu/dts/arm/r8a7779.dtsi +++ b/sys/gnu/dts/arm/r8a7779.dtsi @@ -286,7 +286,7 @@ status = "disabled"; }; - pfc: pfc@fffc0000 { + pfc: pin-controller@fffc0000 { compatible = "renesas,pfc-r8a7779"; reg = <0xfffc0000 0x23c>; }; diff --git a/sys/gnu/dts/arm/r8a7790.dtsi b/sys/gnu/dts/arm/r8a7790.dtsi index 99269aaca6fc..2805a8608d4b 100644 --- a/sys/gnu/dts/arm/r8a7790.dtsi +++ b/sys/gnu/dts/arm/r8a7790.dtsi @@ -614,7 +614,7 @@ max-frequency = <97500000>; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7790"; reg = <0 0xe6060000 0 0x250>; }; @@ -1602,16 +1602,14 @@ 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { + usb@1,0 { reg = <0x800 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; - usb@0,2 { + usb@2,0 { reg = <0x1000 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; @@ -1658,16 +1656,14 @@ 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { - reg = <0x800 0 0 0 0>; - device_type = "pci"; + usb@1,0 { + reg = <0x20800 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; - usb@0,2 { - reg = <0x1000 0 0 0 0>; - device_type = "pci"; + usb@2,0 { + reg = <0x21000 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; diff --git a/sys/gnu/dts/arm/r8a7791.dtsi b/sys/gnu/dts/arm/r8a7791.dtsi index 4d0c2ce59900..bd93f699ad84 100644 --- a/sys/gnu/dts/arm/r8a7791.dtsi +++ b/sys/gnu/dts/arm/r8a7791.dtsi @@ -562,7 +562,7 @@ status = "disabled"; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7791"; reg = <0 0xe6060000 0 0x250>; }; @@ -776,6 +776,15 @@ status = "disabled"; }; + adc: adc@e6e54000 { + compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc"; + reg = <0 0xe6e54000 0 64>; + clocks = <&mstp9_clks R8A7791_CLK_GYROADC>; + clock-names = "fck"; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + status = "disabled"; + }; + scif2: serial@e6e58000 { compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", "renesas,scif"; @@ -1425,13 +1434,15 @@ mstp9_clks: mstp9_clks@e6150994 { compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; - clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, + clocks = <&p_clk>, + <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&p_clk>, <&p_clk>, <&cpg_clocks R8A7791_CLK_QSPI>, <&hp_clk>, <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>; #clock-cells = <1>; clock-indices = < + R8A7791_CLK_GYROADC R8A7791_CLK_GPIO7 R8A7791_CLK_GPIO6 R8A7791_CLK_GPIO5 R8A7791_CLK_GPIO4 R8A7791_CLK_GPIO3 R8A7791_CLK_GPIO2 R8A7791_CLK_GPIO1 R8A7791_CLK_GPIO0 R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD R8A7791_CLK_I2C5 @@ -1439,6 +1450,7 @@ R8A7791_CLK_I2C1 R8A7791_CLK_I2C0 >; clock-output-names = + "gyroadc", "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0", "rcan1", "rcan0", "qspi_mod", "i2c5", "i2c6", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0"; @@ -1601,16 +1613,14 @@ 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { + usb@1,0 { reg = <0x800 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; - usb@0,2 { + usb@2,0 { reg = <0x1000 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; @@ -1636,16 +1646,14 @@ 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { - reg = <0x800 0 0 0 0>; - device_type = "pci"; + usb@1,0 { + reg = <0x10800 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; - usb@0,2 { - reg = <0x1000 0 0 0 0>; - device_type = "pci"; + usb@2,0 { + reg = <0x11000 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; diff --git a/sys/gnu/dts/arm/r8a7793-gose.dts b/sys/gnu/dts/arm/r8a7793-gose.dts index 806c93f6ae8b..76e3aca2029e 100644 --- a/sys/gnu/dts/arm/r8a7793-gose.dts +++ b/sys/gnu/dts/arm/r8a7793-gose.dts @@ -253,17 +253,38 @@ }; }; + hdmi-in { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&adv7612_in>; + }; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; port { - hdmi_con: endpoint { + hdmi_con_out: endpoint { remote-endpoint = <&adv7511_out>; }; }; }; + composite-in { + compatible = "composite-video-connector"; + + port { + composite_con_in: endpoint { + remote-endpoint = <&adv7180_in>; + }; + }; + }; + x2_clk: x2-clock { compatible = "fixed-clock"; #clock-cells = <0>; @@ -348,16 +369,37 @@ sdhi0_pins: sd0 { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; + power-source = <3300>; + }; + + sdhi0_pins_uhs: sd0_uhs { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <1800>; }; sdhi1_pins: sd1 { groups = "sdhi1_data4", "sdhi1_ctrl"; function = "sdhi1"; + power-source = <3300>; + }; + + sdhi1_pins_uhs: sd1_uhs { + groups = "sdhi1_data4", "sdhi1_ctrl"; + function = "sdhi1"; + power-source = <1800>; }; sdhi2_pins: sd2 { groups = "sdhi2_data4", "sdhi2_ctrl"; function = "sdhi2"; + power-source = <3300>; + }; + + sdhi2_pins_uhs: sd2_uhs { + groups = "sdhi2_data4", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <1800>; }; qspi_pins: qspi { @@ -374,6 +416,16 @@ groups = "audio_clk_a"; function = "audio_clk"; }; + + vin0_pins: vin0 { + groups = "vin0_data24", "vin0_sync", "vin0_clkenb", "vin0_clk"; + function = "vin0"; + }; + + vin1_pins: vin1 { + groups = "vin1_data8", "vin1_clk"; + function = "vin1"; + }; }; ðer { @@ -416,33 +468,40 @@ &sdhi0 { pinctrl-0 = <&sdhi0_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi0_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi0>; vqmmc-supply = <&vccq_sdhi0>; cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>; + sd-uhs-sdr50; + sd-uhs-sdr104; status = "okay"; }; &sdhi1 { pinctrl-0 = <&sdhi1_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi1_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi1>; vqmmc-supply = <&vccq_sdhi1>; cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>; + sd-uhs-sdr50; status = "okay"; }; &sdhi2 { pinctrl-0 = <&sdhi2_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi2_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi2>; vqmmc-supply = <&vccq_sdhi2>; cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>; + sd-uhs-sdr50; status = "okay"; }; @@ -498,6 +557,32 @@ reg = <0x12>; }; + composite-in@20 { + compatible = "adi,adv7180cp"; + reg = <0x20>; + remote = <&vin1>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7180_in: endpoint { + remote-endpoint = <&composite_con_in>; + }; + }; + + port@3 { + reg = <3>; + adv7180_out: endpoint { + bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; + }; + }; + hdmi@39 { compatible = "adi,adv7511w"; reg = <0x39>; @@ -524,7 +609,34 @@ port@1 { reg = <1>; adv7511_out: endpoint { - remote-endpoint = <&hdmi_con>; + remote-endpoint = <&hdmi_con_out>; + }; + }; + }; + }; + + hdmi-in@4c { + compatible = "adi,adv7612"; + reg = <0x4c>; + interrupt-parent = <&gpio4>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + default-input = <0>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7612_in: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; + }; + + port@2 { + reg = <2>; + adv7612_out: endpoint { + remote-endpoint = <&vin0ep2>; }; }; }; @@ -578,3 +690,42 @@ &ssi1 { shared-pin; }; + +/* HDMI video input */ +&vin0 { + status = "okay"; + pinctrl-0 = <&vin0_pins>; + pinctrl-names = "default"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin0ep2: endpoint { + remote-endpoint = <&adv7612_out>; + bus-width = <24>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; + data-active = <1>; + }; + }; +}; + +/* composite video input */ +&vin1 { + pinctrl-0 = <&vin1_pins>; + pinctrl-names = "default"; + + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin1ep: endpoint { + remote-endpoint = <&adv7180_out>; + bus-width = <8>; + }; + }; +}; diff --git a/sys/gnu/dts/arm/r8a7793.dtsi b/sys/gnu/dts/arm/r8a7793.dtsi index 4de6041d61f9..13b980f27bbc 100644 --- a/sys/gnu/dts/arm/r8a7793.dtsi +++ b/sys/gnu/dts/arm/r8a7793.dtsi @@ -529,7 +529,7 @@ status = "disabled"; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7793"; reg = <0 0xe6060000 0 0x250>; }; @@ -542,6 +542,7 @@ dmas = <&dmac0 0xcd>, <&dmac0 0xce>, <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <195000000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; @@ -554,6 +555,7 @@ dmas = <&dmac0 0xc1>, <&dmac0 0xc2>, <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <97500000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; @@ -566,6 +568,7 @@ dmas = <&dmac0 0xd3>, <&dmac0 0xd4>, <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <97500000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; diff --git a/sys/gnu/dts/arm/r8a7794.dtsi b/sys/gnu/dts/arm/r8a7794.dtsi index a19b884fb258..7d9a81d970d8 100644 --- a/sys/gnu/dts/arm/r8a7794.dtsi +++ b/sys/gnu/dts/arm/r8a7794.dtsi @@ -820,16 +820,14 @@ 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { + usb@1,0 { reg = <0x800 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; - usb@0,2 { + usb@2,0 { reg = <0x1000 0 0 0 0>; - device_type = "pci"; phys = <&usb0 0>; phy-names = "usb"; }; @@ -855,16 +853,14 @@ 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; - usb@0,1 { - reg = <0x800 0 0 0 0>; - device_type = "pci"; + usb@1,0 { + reg = <0x10800 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; - usb@0,2 { - reg = <0x1000 0 0 0 0>; - device_type = "pci"; + usb@2,0 { + reg = <0x11000 0 0 0 0>; phys = <&usb2 0>; phy-names = "usb"; }; diff --git a/sys/gnu/dts/arm/r8a77xx-aa104xd12-panel.dtsi b/sys/gnu/dts/arm/r8a77xx-aa104xd12-panel.dtsi index 65cb50f0c29f..238d14bb0ebe 100644 --- a/sys/gnu/dts/arm/r8a77xx-aa104xd12-panel.dtsi +++ b/sys/gnu/dts/arm/r8a77xx-aa104xd12-panel.dtsi @@ -10,10 +10,11 @@ / { panel { - compatible = "mitsubishi,aa104xd12", "panel-dpi"; + compatible = "mitsubishi,aa104xd12", "panel-lvds"; width-mm = <210>; height-mm = <158>; + data-mapping = "jeida-18"; panel-timing { /* 1024x768 @65Hz */ diff --git a/sys/gnu/dts/arm/r8a77xx-aa121td01-panel.dtsi b/sys/gnu/dts/arm/r8a77xx-aa121td01-panel.dtsi index a07ebf8f6938..04aafd479775 100644 --- a/sys/gnu/dts/arm/r8a77xx-aa121td01-panel.dtsi +++ b/sys/gnu/dts/arm/r8a77xx-aa121td01-panel.dtsi @@ -10,10 +10,11 @@ / { panel { - compatible = "mitsubishi,aa121td01", "panel-dpi"; + compatible = "mitsubishi,aa121td01", "panel-lvds"; width-mm = <261>; height-mm = <163>; + data-mapping = "jeida-18"; panel-timing { /* 1280x800 @60Hz */ diff --git a/sys/gnu/dts/arm/rk3229-evb.dts b/sys/gnu/dts/arm/rk3229-evb.dts index 275092a950ef..1b55192b7d04 100644 --- a/sys/gnu/dts/arm/rk3229-evb.dts +++ b/sys/gnu/dts/arm/rk3229-evb.dts @@ -58,6 +58,17 @@ #clock-cells = <0>; }; + vcc_host: vcc-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host_vbus_drv>; + regulator-name = "vcc_host"; + regulator-always-on; + regulator-boot-on; + }; + vcc_phy: vcc-phy-regulator { compatible = "regulator-fixed"; enable-active-high; @@ -85,6 +96,69 @@ status = "okay"; }; +&pinctrl { + usb { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + &uart2 { status = "okay"; }; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + phy-supply = <&vcc_host>; + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc_host>; + status = "okay"; + }; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host2_ehci { + status = "okay"; +}; + +&usb_host2_ohci { + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rk322x.dtsi b/sys/gnu/dts/arm/rk322x.dtsi index 48a0c1cf4301..f3e4ffd9f818 100644 --- a/sys/gnu/dts/arm/rk322x.dtsi +++ b/sys/gnu/dts/arm/rk322x.dtsi @@ -66,10 +66,7 @@ compatible = "arm,cortex-a7"; reg = <0xf00>; resets = <&cru SRST_CORE0>; - operating-points = < - /* KHz uV */ - 816000 1000000 - >; + operating-points-v2 = <&cpu0_opp_table>; #cooling-cells = <2>; /* min followed by max */ clock-latency = <40000>; clocks = <&cru ARMCLK>; @@ -80,6 +77,7 @@ compatible = "arm,cortex-a7"; reg = <0xf01>; resets = <&cru SRST_CORE1>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu2: cpu@f02 { @@ -87,6 +85,7 @@ compatible = "arm,cortex-a7"; reg = <0xf02>; resets = <&cru SRST_CORE2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu3: cpu@f03 { @@ -94,6 +93,35 @@ compatible = "arm,cortex-a7"; reg = <0xf03>; resets = <&cru SRST_CORE3>; + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1175000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1275000>; }; }; @@ -182,8 +210,61 @@ }; grf: syscon@11000000 { - compatible = "syscon"; + compatible = "syscon", "simple-mfd"; reg = <0x11000000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy0: usb2-phy@760 { + compatible = "rockchip,rk3228-usb2phy"; + reg = <0x0760 0x0c>; + clocks = <&cru SCLK_OTGPHY0>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy0"; + #clock-cells = <0>; + status = "disabled"; + + u2phy0_otg: otg-port { + interrupts = , + , + ; + interrupt-names = "otg-bvalid", "otg-id", + "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + + u2phy0_host: host-port { + interrupts = ; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + }; + + u2phy1: usb2-phy@800 { + compatible = "rockchip,rk3228-usb2phy"; + reg = <0x0800 0x0c>; + clocks = <&cru SCLK_OTGPHY1>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy1"; + #clock-cells = <0>; + status = "disabled"; + + u2phy1_otg: otg-port { + interrupts = ; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + + u2phy1_host: host-port { + interrupts = ; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + }; }; uart0: serial@11010000 { @@ -280,6 +361,14 @@ status = "disabled"; }; + wdt: watchdog@110a0000 { + compatible = "snps,dw-wdt"; + reg = <0x110a0000 0x100>; + interrupts = ; + clocks = <&cru PCLK_CPU>; + status = "disabled"; + }; + pwm0: pwm@110b0000 { compatible = "rockchip,rk3288-pwm"; reg = <0x110b0000 0x10>; @@ -338,8 +427,18 @@ rockchip,grf = <&grf>; #clock-cells = <1>; #reset-cells = <1>; - assigned-clocks = <&cru PLL_GPLL>; - assigned-clock-rates = <594000000>; + assigned-clocks = + <&cru PLL_GPLL>, <&cru ARMCLK>, + <&cru PLL_CPLL>, <&cru ACLK_PERI>, + <&cru HCLK_PERI>, <&cru PCLK_PERI>, + <&cru ACLK_CPU>, <&cru HCLK_CPU>, + <&cru PCLK_CPU>; + assigned-clock-rates = + <594000000>, <816000000>, + <500000000>, <150000000>, + <150000000>, <75000000>, + <150000000>, <150000000>, + <75000000>; }; thermal-zones { @@ -388,6 +487,8 @@ interrupts = ; clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; clock-names = "tsadc", "apb_pclk"; + assigned-clocks = <&cru SCLK_TSADC>; + assigned-clock-rates = <32768>; resets = <&cru SRST_TSADC>; reset-names = "tsadc-apb"; pinctrl-names = "init", "default", "sleep"; @@ -419,6 +520,89 @@ status = "disabled"; }; + usb_otg: usb@30040000 { + compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0x30040000 0x40000>; + interrupts = ; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy0_otg>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_host0_ehci: usb@30080000 { + compatible = "generic-ehci"; + reg = <0x30080000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy0>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy0_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host0_ohci: usb@300a0000 { + compatible = "generic-ohci"; + reg = <0x300a0000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy0>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy0_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host1_ehci: usb@300c0000 { + compatible = "generic-ehci"; + reg = <0x300c0000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST1>, <&u2phy1>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy1_otg>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host1_ohci: usb@300e0000 { + compatible = "generic-ohci"; + reg = <0x300e0000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST1>, <&u2phy1>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy1_otg>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host2_ehci: usb@30100000 { + compatible = "generic-ehci"; + reg = <0x30100000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST2>, <&u2phy1>; + phys = <&u2phy1_host>; + phy-names = "usb"; + clock-names = "usbhost", "utmi"; + status = "disabled"; + }; + + usb_host2_ohci: usb@30120000 { + compatible = "generic-ohci"; + reg = <0x30120000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST2>, <&u2phy1>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy1_host>; + phy-names = "usb"; + status = "disabled"; + }; + gmac: ethernet@30200000 { compatible = "rockchip,rk3228-gmac"; reg = <0x30200000 0x10000>; @@ -621,9 +805,9 @@ <0 12 RK_FUNC_1 &pcfg_pull_none>, <0 13 RK_FUNC_1 &pcfg_pull_none>, <0 14 RK_FUNC_1 &pcfg_pull_none>, - <1 2 RK_FUNC_1 &pcfg_pull_none>, - <1 4 RK_FUNC_1 &pcfg_pull_none>, - <1 5 RK_FUNC_1 &pcfg_pull_none>; + <1 2 RK_FUNC_2 &pcfg_pull_none>, + <1 4 RK_FUNC_2 &pcfg_pull_none>, + <1 5 RK_FUNC_2 &pcfg_pull_none>; }; }; @@ -693,10 +877,15 @@ uart2 { uart2_xfer: uart2-xfer { - rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>, + rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>, <1 19 RK_FUNC_2 &pcfg_pull_none>; }; + uart21_xfer: uart21-xfer { + rockchip,pins = <1 10 RK_FUNC_2 &pcfg_pull_up>, + <1 9 RK_FUNC_2 &pcfg_pull_none>; + }; + uart2_cts: uart2-cts { rockchip,pins = <0 25 RK_FUNC_1 &pcfg_pull_none>; }; diff --git a/sys/gnu/dts/arm/rk3288-firefly-reload.dts b/sys/gnu/dts/arm/rk3288-firefly-reload.dts index d0b3204a4799..b11a282c334c 100644 --- a/sys/gnu/dts/arm/rk3288-firefly-reload.dts +++ b/sys/gnu/dts/arm/rk3288-firefly-reload.dts @@ -48,6 +48,19 @@ model = "Firefly-RK3288-reload"; compatible = "firefly,firefly-rk3288-reload", "rockchip,rk3288"; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + + button-recovery { + label = "Recovery"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + }; + gpio-keys { compatible = "gpio-keys"; @@ -246,6 +259,10 @@ status = "okay"; }; +&saradc { + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; diff --git a/sys/gnu/dts/arm/rk3288-firefly.dtsi b/sys/gnu/dts/arm/rk3288-firefly.dtsi index 10793ac18599..32dabae12e67 100644 --- a/sys/gnu/dts/arm/rk3288-firefly.dtsi +++ b/sys/gnu/dts/arm/rk3288-firefly.dtsi @@ -49,6 +49,19 @@ reg = <0 0x80000000>; }; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + + button-recovery { + label = "Recovery"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + }; + dovdd_1v8: dovdd-1v8-regulator { compatible = "regulator-fixed"; regulator-name = "dovdd_1v8"; @@ -219,6 +232,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/sys/gnu/dts/arm/rk3288-rock2-som.dtsi b/sys/gnu/dts/arm/rk3288-rock2-som.dtsi index f0778a46bca9..749a9b86e6e2 100644 --- a/sys/gnu/dts/arm/rk3288-rock2-som.dtsi +++ b/sys/gnu/dts/arm/rk3288-rock2-som.dtsi @@ -113,6 +113,11 @@ tx_delay = <0x30>; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &i2c0 { status = "okay"; diff --git a/sys/gnu/dts/arm/rk3288-rock2-square.dts b/sys/gnu/dts/arm/rk3288-rock2-square.dts index a23a94811be8..8ed25e9f60bc 100644 --- a/sys/gnu/dts/arm/rk3288-rock2-square.dts +++ b/sys/gnu/dts/arm/rk3288-rock2-square.dts @@ -125,10 +125,6 @@ gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&host_vbus_drv>; - /* Always on as the rockchip usb phy doesn't have a vbus-supply - * property - */ - regulator-always-on; regulator-name = "vcc_host"; }; @@ -279,6 +275,10 @@ status = "okay"; }; +&usbphy1 { + vbus-supply = <&vcc_usb_host>; +}; + &usb_host0_ehci { status = "okay"; }; diff --git a/sys/gnu/dts/arm/rk3288-veyron.dtsi b/sys/gnu/dts/arm/rk3288-veyron.dtsi index 5d1eb0a25827..d709fa1847f9 100644 --- a/sys/gnu/dts/arm/rk3288-veyron.dtsi +++ b/sys/gnu/dts/arm/rk3288-veyron.dtsi @@ -161,6 +161,11 @@ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/sys/gnu/dts/arm/rk3288.dtsi b/sys/gnu/dts/arm/rk3288.dtsi index ad5d6022e95f..858e1fed762a 100644 --- a/sys/gnu/dts/arm/rk3288.dtsi +++ b/sys/gnu/dts/arm/rk3288.dtsi @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1125,6 +1126,48 @@ }; }; + gpu: gpu@ffa30000 { + compatible = "rockchip,rk3288-mali", "arm,mali-t760"; + reg = <0xffa30000 0x10000>; + interrupts = , + , + ; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&cru ACLK_GPU>; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&power RK3288_PD_GPU>; + status = "disabled"; + }; + + gpu_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + opp@100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <950000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <950000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <1000000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1100000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1200000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1250000>; + }; + }; + qos_gpu_r: qos@ffaa0000 { compatible = "syscon"; reg = <0xffaa0000 0x20>; diff --git a/sys/gnu/dts/arm/rv1108-evb.dts b/sys/gnu/dts/arm/rv1108-evb.dts new file mode 100644 index 000000000000..58cf4ac079c3 --- /dev/null +++ b/sys/gnu/dts/arm/rv1108-evb.dts @@ -0,0 +1,69 @@ +/* + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "rv1108.dtsi" + +/ { + model = "Rockchip RV1108 Evaluation board"; + compatible = "rockchip,rv1108-evb", "rockchip,rv1108"; + + memory@60000000 { + device_type = "memory"; + reg = <0x60000000 0x08000000>; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/rv1108.dtsi b/sys/gnu/dts/arm/rv1108.dtsi new file mode 100644 index 000000000000..437098b556eb --- /dev/null +++ b/sys/gnu/dts/arm/rv1108.dtsi @@ -0,0 +1,452 @@ +/* + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +/ { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "rockchip,rv1108"; + + interrupt-parent = <&gic>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@f00 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0xf00>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = ; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = , + ; + clock-frequency = <24000000>; + }; + + xin24m: oscillator { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xin24m"; + #clock-cells = <0>; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pdma: pdma@102a0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x102a0000 0x4000>; + interrupts = ; + #dma-cells = <1>; + arm,pl330-broken-no-flushp; + clocks = <&cru ACLK_DMAC>; + clock-names = "apb_pclk"; + }; + }; + + bus_intmem@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x2000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x10080000 0x2000>; + }; + + uart2: serial@10210000 { + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; + reg = <0x10210000 0x100>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m0_xfer>; + status = "disabled"; + }; + + uart1: serial@10220000 { + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; + reg = <0x10220000 0x100>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer>; + status = "disabled"; + }; + + uart0: serial@10230000 { + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; + reg = <0x10230000 0x100>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + status = "disabled"; + }; + + grf: syscon@10300000 { + compatible = "rockchip,rv1108-grf", "syscon"; + reg = <0x10300000 0x1000>; + }; + + pmugrf: syscon@20060000 { + compatible = "rockchip,rv1108-pmugrf", "syscon"; + reg = <0x20060000 0x1000>; + }; + + cru: clock-controller@20200000 { + compatible = "rockchip,rv1108-cru"; + reg = <0x20200000 0x1000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + emmc: dwmmc@30110000 { + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x30110000 0x4000>; + status = "disabled"; + }; + + sdio: dwmmc@30120000 { + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x30120000 0x4000>; + status = "disabled"; + }; + + sdmmc: dwmmc@30130000 { + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 100000000>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0x30130000 0x4000>; + status = "disabled"; + }; + + gic: interrupt-controller@32010000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + #address-cells = <0>; + + reg = <0x32011000 0x1000>, + <0x32012000 0x2000>, + <0x32014000 0x2000>, + <0x32016000 0x2000>; + interrupts = ; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rv1108-pinctrl"; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmugrf>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@20030000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20030000 0x100>; + interrupts = ; + clocks = <&xin24m>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio1@10310000 { + compatible = "rockchip,gpio-bank"; + reg = <0x10310000 0x100>; + interrupts = ; + clocks = <&xin24m>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio2@10320000 { + compatible = "rockchip,gpio-bank"; + reg = <0x10320000 0x100>; + interrupts = ; + clocks = <&xin24m>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio3@10330000 { + compatible = "rockchip,gpio-bank"; + reg = <0x10330000 0x100>; + interrupts = ; + clocks = <&xin24m>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcfg_pull_up: pcfg-pull-up { + bias-pull-up; + }; + + pcfg_pull_down: pcfg-pull-down { + bias-pull-down; + }; + + pcfg_pull_none: pcfg-pull-none { + bias-disable; + }; + + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { + drive-strength = <8>; + }; + + pcfg_pull_none_drv_12ma: pcfg-pull-none-drv-12ma { + drive-strength = <12>; + }; + + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { + bias-pull-up; + drive-strength = <8>; + }; + + pcfg_pull_none_drv_4ma: pcfg-pull-none-drv-4ma { + drive-strength = <4>; + }; + + pcfg_pull_up_drv_4ma: pcfg-pull-up-drv-4ma { + bias-pull-up; + drive-strength = <4>; + }; + + pcfg_output_high: pcfg-output-high { + output-high; + }; + + pcfg_output_low: pcfg-output-low { + output-low; + }; + + pcfg_input_high: pcfg-input-high { + bias-pull-up; + input-enable; + }; + + i2c1 { + i2c1_xfer: i2c1-xfer { + rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, + <2 RK_PD4 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + i2c2m1 { + i2c2m1_xfer: i2c2m1-xfer { + rockchip,pins = <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>, + <0 RK_PC6 RK_FUNC_3 &pcfg_pull_none>; + }; + + i2c2m1_gpio: i2c2m1-gpio { + rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + i2c2m05v { + i2c2m05v_xfer: i2c2m05v-xfer { + rockchip,pins = <1 RK_PD5 RK_FUNC_2 &pcfg_pull_none>, + <1 RK_PD4 RK_FUNC_2 &pcfg_pull_none>; + }; + + i2c2m05v_gpio: i2c2m05v-gpio { + rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>, + <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + i2c3 { + i2c3_xfer: i2c3-xfer { + rockchip,pins = <0 RK_PB6 RK_FUNC_1 &pcfg_pull_none>, + <0 RK_PC4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdmmc { + sdmmc_clk: sdmmc-clk { + rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <3 RK_PC5 RK_FUNC_1 &pcfg_pull_up_drv_4ma>; + }; + + sdmmc_cd: sdmmc-cd { + rockchip,pins = <0 RK_PA1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>; + }; + + sdmmc_bus1: sdmmc-bus1 { + rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>, + <3 RK_PC2 RK_FUNC_1 &pcfg_pull_up_drv_4ma>, + <3 RK_PC1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>, + <3 RK_PC0 RK_FUNC_1 &pcfg_pull_up_drv_4ma>; + }; + }; + + uart0 { + uart0_xfer: uart0-xfer { + rockchip,pins = <3 RK_PA6 RK_FUNC_1 &pcfg_pull_up>, + <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_cts: uart0-cts { + rockchip,pins = <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_rts: uart0-rts { + rockchip,pins = <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_rts_gpio: uart0-rts-gpio { + rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + uart1 { + uart1_xfer: uart1-xfer { + rockchip,pins = <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, + <1 RK_PD2 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_cts: uart1-cts { + rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_rts: uart1-rts { + rockchip,pins = <1 RK_PD1 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart2m0 { + uart2m0_xfer: uart2m0-xfer { + rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up>, + <2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart2m1 { + uart2m1_xfer: uart2m1-xfer { + rockchip,pins = <3 RK_PC3 RK_FUNC_2 &pcfg_pull_up>, + <3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + uart2_5v { + uart2_5v_cts: uart2_5v-cts { + rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart2_5v_rts: uart2_5v-rts { + rockchip,pins = <1 RK_PD5 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + }; +}; diff --git a/sys/gnu/dts/arm/sama5d2.dtsi b/sys/gnu/dts/arm/sama5d2.dtsi index 8067c71c3a38..60e69aeacbdb 100644 --- a/sys/gnu/dts/arm/sama5d2.dtsi +++ b/sys/gnu/dts/arm/sama5d2.dtsi @@ -135,6 +135,12 @@ #size-cells = <1>; ranges; + nfc_sram: sram@00100000 { + compatible = "mmio-sram"; + no-memory-wc; + reg = <0x00100000 0x2400>; + }; + usb0: gadget@00300000 { #address-cells = <1>; #size-cells = <0>; @@ -291,6 +297,32 @@ cache-level = <2>; }; + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&hsmc>; + reg = <0x10000000 0x10000000 + 0x60000000 0x30000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x60000000 0x10000000 + 0x2 0x0 0x70000000 0x10000000 + 0x3 0x0 0x80000000 0x10000000>; + clocks = <&mck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,sama5d3-nand-controller"; + atmel,nfc-sram = <&nfc_sram>; + atmel,nfc-io = <&nfc_io>; + ecc-engine = <&pmecc>; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; + nand0: nand@80000000 { compatible = "atmel,sama5d2-nand"; #address-cells = <1>; @@ -347,6 +379,11 @@ status = "disabled"; }; + nfc_io: nfc-io@c0000000 { + compatible = "atmel,sama5d3-nfc-io", "syscon"; + reg = <0xc0000000 0x8000000>; + }; + apb { compatible = "simple-bus"; #address-cells = <1>; @@ -762,6 +799,18 @@ atmel,clk-output-range = <0 83000000>; }; + can0_clk: can0_clk { + #clock-cells = <0>; + reg = <56>; + atmel,clk-output-range = <0 83000000>; + }; + + can1_clk: can1_clk { + #clock-cells = <0>; + reg = <57>; + atmel,clk-output-range = <0 83000000>; + }; + classd_clk: classd_clk { #clock-cells = <0>; reg = <59>; @@ -890,6 +939,18 @@ #clock-cells = <0>; reg = <55>; }; + + can0_gclk: can0_gclk { + #clock-cells = <0>; + reg = <56>; + atmel,clk-output-range = <0 80000000>; + }; + + can1_gclk: can1_gclk { + #clock-cells = <0>; + reg = <57>; + atmel,clk-output-range = <0 80000000>; + }; }; }; @@ -986,6 +1047,22 @@ clock-names = "t0_clk", "slow_clk"; }; + hsmc: hsmc@f8014000 { + compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd"; + reg = <0xf8014000 0x1000>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>; + clocks = <&hsmc_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pmecc: ecc-engine@f8014070 { + compatible = "atmel,sama5d2-pmecc"; + reg = <0xf8014070 0x490>, + <0xf8014500 0x100>; + }; + }; + pdmic: pdmic@f8018000 { compatible = "atmel,sama5d2-pdmic"; reg = <0xf8018000 0x124>; @@ -1065,6 +1142,14 @@ status = "disabled"; }; + pwm0: pwm@f802c000 { + compatible = "atmel,sama5d2-pwm"; + reg = <0xf802c000 0x4000>; + interrupts = <38 IRQ_TYPE_LEVEL_HIGH 7>; + #pwm-cells = <3>; + clocks = <&pwm_clk>; + }; + sfr: sfr@f8030000 { compatible = "atmel,sama5d2-sfr", "syscon"; reg = <0xf8030000 0x98>; @@ -1144,6 +1229,22 @@ clocks = <&clk32k>; }; + can0: can@f8054000 { + compatible = "bosch,m_can"; + reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg-names = "m_can", "message_ram"; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, + <64 IRQ_TYPE_LEVEL_HIGH 7>; + interrupt-names = "int0", "int1"; + clocks = <&can0_clk>, <&can0_gclk>; + clock-names = "hclk", "cclk"; + assigned-clocks = <&can0_gclk>; + assigned-clock-parents = <&utmi>; + assigned-clock-rates = <40000000>; + bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>; + status = "disabled"; + }; + spi1: spi@fc000000 { compatible = "atmel,at91rm9200-spi"; reg = <0xfc000000 0x100>; @@ -1305,6 +1406,22 @@ status = "okay"; }; + can1: can@fc050000 { + compatible = "bosch,m_can"; + reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg-names = "m_can", "message_ram"; + interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, + <65 IRQ_TYPE_LEVEL_HIGH 7>; + interrupt-names = "int0", "int1"; + clocks = <&can1_clk>, <&can1_gclk>; + clock-names = "hclk", "cclk"; + assigned-clocks = <&can1_gclk>; + assigned-clock-parents = <&utmi>; + assigned-clock-rates = <40000000>; + bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + status = "disabled"; + }; + sfrbu: sfr@fc05c000 { compatible = "atmel,sama5d2-sfrbu", "syscon"; reg = <0xfc05c000 0x20>; diff --git a/sys/gnu/dts/arm/sama5d3.dtsi b/sys/gnu/dts/arm/sama5d3.dtsi index b06448ba6649..554d0bdedc7a 100644 --- a/sys/gnu/dts/arm/sama5d3.dtsi +++ b/sys/gnu/dts/arm/sama5d3.dtsi @@ -429,6 +429,22 @@ clocks = <&trng_clk>; }; + hsmc: hsmc@ffffc000 { + compatible = "atmel,sama5d3-smc", "syscon", "simple-mfd"; + reg = <0xffffc000 0x1000>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>; + clocks = <&hsmc_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pmecc: ecc-engine@ffffc070 { + compatible = "atmel,at91sam9g45-pmecc"; + reg = <0xffffc070 0x490>, + <0xffffc500 0x100>; + }; + }; + dma0: dma-controller@ffffe600 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffe600 0x200>; @@ -554,6 +570,66 @@ }; }; + ebi { + pinctrl_ebi_addr: ebi-addr-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nand_addr: ebi-addr-1 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs0: ebi-cs0-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs1: ebi-cs1-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs2: ebi-cs2-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nwait: ebi-nwait-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nwr1_nbs1: ebi-nwr1-nbs1-0 { + atmel,pins = + ; + }; + }; + i2c0 { pinctrl_i2c0: i2c0-0 { atmel,pins = @@ -1326,6 +1402,12 @@ }; }; + nfc_sram: sram@200000 { + compatible = "mmio-sram"; + no-memory-wc; + reg = <0x200000 0x2400>; + }; + usb0: gadget@00500000 { #address-cells = <1>; #size-cells = <0>; @@ -1461,36 +1543,35 @@ status = "disabled"; }; - nand0: nand@60000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; #size-cells = <1>; - ranges; - reg = < 0x60000000 0x01000000 /* EBI CS3 */ - 0xffffc070 0x00000490 /* SMC PMECC regs */ - 0xffffc500 0x00000100 /* SMC PMECC Error Location regs */ - 0x00110000 0x00018000 /* ROM code */ - >; - interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand0_ale_cle>; - atmel,pmecc-lookup-table-offset = <0x0 0x8000>; + atmel,smc = <&hsmc>; + reg = <0x10000000 0x10000000 + 0x40000000 0x30000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x40000000 0x10000000 + 0x2 0x0 0x50000000 0x10000000 + 0x3 0x0 0x60000000 0x10000000>; + clocks = <&mck>; status = "disabled"; - nfc@70000000 { - compatible = "atmel,sama5d3-nfc"; - #address-cells = <1>; + nand_controller: nand-controller { + compatible = "atmel,sama5d3-nand-controller"; + atmel,nfc-sram = <&nfc_sram>; + atmel,nfc-io = <&nfc_io>; + ecc-engine = <&pmecc>; + #address-cells = <2>; #size-cells = <1>; - reg = < - 0x70000000 0x08000000 /* NFC Command Registers */ - 0xffffc000 0x00000070 /* NFC HSMC regs */ - 0x00200000 0x00100000 /* NFC SRAM banks */ - >; - clocks = <&hsmc_clk>; + ranges; + status = "disabled"; }; }; + + nfc_io: nfc-io@70000000 { + compatible = "atmel,sama5d3-nfc-io", "syscon"; + reg = <0x70000000 0x8000000>; + }; }; }; diff --git a/sys/gnu/dts/arm/sama5d3xcm.dtsi b/sys/gnu/dts/arm/sama5d3xcm.dtsi index b5e111b29da1..9506daf5efb6 100644 --- a/sys/gnu/dts/arm/sama5d3xcm.dtsi +++ b/sys/gnu/dts/arm/sama5d3xcm.dtsi @@ -36,43 +36,82 @@ }; }; - nand0: nand@60000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_addr &pinctrl_ebi_cs0>; + pinctr-name = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; + nor: flash@0,0 { + compatible = "cfi-flash"; + linux,mtd-name = "physmap-flash.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x0 0x1000000>; + bank-width = <2>; + atmel,smc-read-mode = "nrd"; + atmel,smc-write-mode = "nwe"; + atmel,smc-bus-width = <16>; + atmel,smc-ncs-rd-setup-ns = <0>; + atmel,smc-ncs-wr-setup-ns = <0>; + atmel,smc-nwe-setup-ns = <8>; + atmel,smc-nrd-setup-ns = <16>; + atmel,smc-ncs-rd-pulse-ns = <84>; + atmel,smc-ncs-wr-pulse-ns = <84>; + atmel,smc-nrd-pulse-ns = <76>; + atmel,smc-nwe-pulse-ns = <76>; + atmel,smc-nrd-cycle-ns = <107>; + atmel,smc-nwe-cycle-ns = <84>; + atmel,smc-tdf-ns = <16>; }; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand_controller: nand-controller { + status = "okay"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/sama5d3xcm_cmp.dtsi b/sys/gnu/dts/arm/sama5d3xcm_cmp.dtsi index dc7572bc7ff0..75cbf4d4ab1a 100644 --- a/sys/gnu/dts/arm/sama5d3xcm_cmp.dtsi +++ b/sys/gnu/dts/arm/sama5d3xcm_cmp.dtsi @@ -148,43 +148,60 @@ }; }; - nand0: nand@60000000 { - nand-bus-width = <8>; - nand-ecc-mode = "hw"; - atmel,has-pmecc; - atmel,pmecc-cap = <4>; - atmel,pmecc-sector-size = <512>; - nand-on-flash-bbt; + ebi: ebi@10000000 { + pinctrl-0 = <&pinctrl_ebi_nand_addr>; + pinctrl-names = "default"; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x40000>; - }; + nand_controller: nand-controller { + status = "okay"; - bootloader@40000 { - label = "bootloader"; - reg = <0x40000 0x80000>; - }; + nand@3 { + reg = <0x3 0x0 0x2>; + atmel,rb = <0>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + label = "atmel_nand"; - bootloaderenv@c0000 { - label = "bootloader env"; - reg = <0xc0000 0xc0000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - dtb@180000 { - label = "device tree"; - reg = <0x180000 0x80000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; - kernel@200000 { - label = "kernel"; - reg = <0x200000 0x600000>; - }; + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; - rootfs@800000 { - label = "rootfs"; - reg = <0x800000 0x0f800000>; + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/sama5d4.dtsi b/sys/gnu/dts/arm/sama5d4.dtsi index d3889c9d25a9..2fa36c525957 100644 --- a/sys/gnu/dts/arm/sama5d4.dtsi +++ b/sys/gnu/dts/arm/sama5d4.dtsi @@ -124,6 +124,12 @@ #size-cells = <1>; ranges; + nfc_sram: sram@100000 { + compatible = "mmio-sram"; + no-memory-wc; + reg = <0x100000 0x2400>; + }; + usb0: gadget@00400000 { #address-cells = <1>; #size-cells = <0>; @@ -280,37 +286,37 @@ cache-level = <2>; }; - nand0: nand@80000000 { - compatible = "atmel,sama5d4-nand", "atmel,at91rm9200-nand"; - #address-cells = <1>; + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; #size-cells = <1>; - ranges; - reg = < 0x80000000 0x08000000 /* EBI CS3 */ - 0xfc05c070 0x00000490 /* SMC PMECC regs */ - 0xfc05c500 0x00000100 /* SMC PMECC Error Location regs */ - >; - interrupts = <22 IRQ_TYPE_LEVEL_HIGH 6>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - atmel,nand-has-dma; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; + atmel,smc = <&hsmc>; + reg = <0x10000000 0x10000000 + 0x60000000 0x28000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x60000000 0x10000000 + 0x2 0x0 0x70000000 0x10000000 + 0x3 0x0 0x80000000 0x8000000>; + clocks = <&mck>; status = "disabled"; - nfc@90000000 { - compatible = "atmel,sama5d3-nfc"; - #address-cells = <1>; + nand_controller: nand-controller { + compatible = "atmel,sama5d3-nand-controller"; + atmel,nfc-sram = <&nfc_sram>; + atmel,nfc-io = <&nfc_io>; + ecc-engine = <&pmecc>; + #address-cells = <2>; #size-cells = <1>; - reg = < - 0x90000000 0x08000000 /* NFC Command Registers */ - 0xfc05c000 0x00000070 /* NFC HSMC regs */ - 0x00100000 0x00100000 /* NFC SRAM banks */ - >; - clocks = <&hsmc_clk>; - atmel,write-by-sram; + ranges; + status = "disabled"; }; }; + nfc_io: nfc-io@90000000 { + compatible = "atmel,sama5d3-nfc-io", "syscon"; + reg = <0x90000000 0x8000000>; + }; + apb { compatible = "simple-bus"; #address-cells = <1>; @@ -1287,6 +1293,22 @@ status = "okay"; }; + hsmc: smc@fc05c000 { + compatible = "atmel,sama5d3-smc", "syscon", "simple-mfd"; + reg = <0xfc05c000 0x1000>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH 6>; + clocks = <&hsmc_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pmecc: ecc-engine@ffffc070 { + compatible = "atmel,sama5d4-pmecc"; + reg = <0xfc05c070 0x490>, + <0xfc05c500 0x100>; + }; + }; + rstc@fc068600 { compatible = "atmel,sama5d3-rstc", "atmel,at91sam9g45-rstc"; reg = <0xfc068600 0x10>; @@ -1447,6 +1469,113 @@ }; }; + ebi { + pinctrl_ebi_addr: ebi-addr-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nand_addr: ebi-addr-1 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs0: ebi-cs0-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs1: ebi-cs1-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs2: ebi-cs2-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_cs3: ebi-cs3-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_data_0_7: ebi-data-lsb-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_data_8_15: ebi-data-msb-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nandrdy: ebi-nandrdy-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nrd_nandoe: ebi-nrd-nandoe-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nwait: ebi-nwait-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nwe_nandwe: ebi-nwe-nandwe-0 { + atmel,pins = + ; + }; + + pinctrl_ebi_nwr1_nbs1: ebi-nwr1-nbs1-0 { + atmel,pins = + ; + }; + }; + i2c0 { pinctrl_i2c0: i2c0-0 { atmel,pins = diff --git a/sys/gnu/dts/arm/sh73a0.dtsi b/sys/gnu/dts/arm/sh73a0.dtsi index 6b01ab354e88..4ea5c5a16c57 100644 --- a/sys/gnu/dts/arm/sh73a0.dtsi +++ b/sys/gnu/dts/arm/sh73a0.dtsi @@ -444,7 +444,7 @@ status = "disabled"; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-sh73a0"; reg = <0xe6050000 0x8000>, <0xe605801c 0x1c>; diff --git a/sys/gnu/dts/arm/socfpga.dtsi b/sys/gnu/dts/arm/socfpga.dtsi index b2674bdb8e6a..7e24dc8e82d4 100644 --- a/sys/gnu/dts/arm/socfpga.dtsi +++ b/sys/gnu/dts/arm/socfpga.dtsi @@ -557,7 +557,7 @@ interrupts = <0 115 4>; interrupt-names = "macirq"; mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ - clocks = <&emac0_clk>; + clocks = <&emac_0_clk>; clock-names = "stmmaceth"; resets = <&rst EMAC0_RESET>; reset-names = "stmmaceth"; @@ -575,7 +575,7 @@ interrupts = <0 120 4>; interrupt-names = "macirq"; mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ - clocks = <&emac1_clk>; + clocks = <&emac_1_clk>; clock-names = "stmmaceth"; resets = <&rst EMAC1_RESET>; reset-names = "stmmaceth"; diff --git a/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi b/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi index 94e088473823..3a32de9ded3b 100644 --- a/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi +++ b/sys/gnu/dts/arm/socfpga_arria10_socdk.dtsi @@ -130,13 +130,13 @@ }; &i2c1 { - speed-mode = <0>; status = "okay"; /* * adjust the falling times to decrease the i2c frequency to 50Khz * because the LCD module does not work at the standard 100Khz */ + clock-frequency = <100000>; i2c-sda-falling-time-ns = <6000>; i2c-scl-falling-time-ns = <6000>; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts b/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts index 7b49395452b6..b280e6494193 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_de0_sockit.dts @@ -86,7 +86,7 @@ &i2c0 { status = "okay"; - speed-mode = <0>; + clock-frequency = <100000>; adxl345: adxl345@0 { compatible = "adi,adxl345"; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts b/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts index 21e397287e29..c2eb88aab8b3 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_mcvevk.dts @@ -58,7 +58,7 @@ &i2c0 { status = "okay"; - speed-mode = <0>; + clock-frequency = <100000>; stmpe1: stmpe811@41 { compatible = "st,stmpe811"; diff --git a/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts b/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts index 893198049397..655fe87e272d 100644 --- a/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts +++ b/sys/gnu/dts/arm/socfpga_cyclone5_vining_fpga.dts @@ -69,34 +69,7 @@ * to be added to the gmac1 device tree blob. */ ethernet0 = &gmac1; - }; - - leds { - compatible = "gpio-leds"; - - hps_led0 { - label = "hps:green:led0"; /* ALIVE_LED_GR */ - gpios = <&portb 19 0>; /* HPS_GPIO48 */ - linux,default-trigger = "heartbeat"; - }; - - hps_led1 { - label = "hps:red:led0"; /* ALIVE_LED_RD */ - gpios = <&portb 24 0>; /* HPS_GPIO53 */ - linux,default-trigger = "none"; - }; - - hps_led2 { - label = "hps:green:led1"; /* LINK2HOST_LED_GR */ - gpios = <&portb 25 0>; /* HPS_GPIO54 */ - linux,default-trigger = "heartbeat"; - }; - - hps_led3 { - label = "hps:red:led1"; /* LINK2HOST_LED_RD */ - gpios = <&portc 7 0>; /* HPS_GPIO65 */ - linux,default-trigger = "none"; - }; + ethernet1 = &gmac0; }; gpio-keys { @@ -203,69 +176,39 @@ #address-cells = <1>; #size-cells = <0>; reg = <0>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; i2c@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; i2c@2 { #address-cells = <1>; #size-cells = <0>; reg = <2>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; i2c@3 { #address-cells = <1>; #size-cells = <0>; reg = <3>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; i2c@4 { #address-cells = <1>; #size-cells = <0>; reg = <4>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; i2c@5 { #address-cells = <1>; #size-cells = <0>; reg = <5>; - eeprom@51 { - compatible = "at,24c01"; - pagesize = <8>; - reg = <0x51>; - }; }; - i2c@6 { + i2c@6 { /* Backplane EEPROM */ #address-cells = <1>; #size-cells = <0>; reg = <6>; @@ -276,7 +219,7 @@ }; }; - i2c@7 { + i2c@7 { /* Power board EEPROM */ #address-cells = <1>; #size-cells = <0>; reg = <7>; @@ -300,6 +243,44 @@ }; }; +&qspi { + status = "okay"; + + n25q128@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128"; + reg = <0>; /* chip select */ + spi-max-frequency = <100000000>; + m25p,fast-read; + + cdns,page-size = <256>; + cdns,block-size = <16>; + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + }; + + n25q00@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q00"; + reg = <1>; /* chip select */ + spi-max-frequency = <100000000>; + m25p,fast-read; + + cdns,page-size = <256>; + cdns,block-size = <16>; + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + }; +}; + &usb0 { dr_mode = "host"; status = "okay"; diff --git a/sys/gnu/dts/arm/stm32429i-eval.dts b/sys/gnu/dts/arm/stm32429i-eval.dts index b6331146aa02..dcda0bbefe5b 100644 --- a/sys/gnu/dts/arm/stm32429i-eval.dts +++ b/sys/gnu/dts/arm/stm32429i-eval.dts @@ -48,6 +48,7 @@ /dts-v1/; #include "stm32f429.dtsi" #include +#include / { model = "STMicroelectronics STM32429i-EVAL board"; @@ -66,6 +67,14 @@ serial0 = &usart1; }; + clocks { + clk_ext_camera: clk-ext-camera { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + }; + soc { dma-ranges = <0xc0000000 0x0 0x10000000>; }; @@ -124,6 +133,16 @@ clocks = <&rcc 0 STM32F4_AHB1_CLOCK(OTGHSULPI)>; clock-names = "main_clk"; }; + + panel_rgb: panel-rgb { + compatible = "ampire,am-480272h3tmqw-t01h"; + status = "okay"; + port { + panel_in_rgb: endpoint { + remote-endpoint = <<dc_out_rgb>; + }; + }; + }; }; &adc { @@ -141,10 +160,79 @@ clock-frequency = <25000000>; }; +&crc { + status = "okay"; +}; + +&dcmi { + status = "okay"; + + port { + dcmi_0: endpoint { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; + }; + }; +}; + &i2c1 { pinctrl-0 = <&i2c1_pins>; pinctrl-names = "default"; status = "okay"; + + ov2640: camera@30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + resetb-gpios = <&stmpegpio 2 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&stmpegpio 0 GPIO_ACTIVE_LOW>; + clocks = <&clk_ext_camera>; + clock-names = "xvclk"; + status = "okay"; + + port { + ov2640_0: endpoint { + remote-endpoint = <&dcmi_0>; + }; + }; + }; + + stmpe1600: stmpe1600@42 { + compatible = "st,stmpe1600"; + reg = <0x42>; + irq-gpio = <&gpioi 8 0>; + irq-trigger = <3>; + interrupts = <8 3>; + interrupt-parent = <&exti>; + interrupt-controller; + wakeup-source; + + stmpegpio: stmpe_gpio { + compatible = "st,stmpe-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + }; +}; + +&iwdg { + status = "okay"; + timeout-sec = <32>; +}; + +<dc { + status = "okay"; + pinctrl-0 = <<dc_pins>; + pinctrl-names = "default"; + dma-ranges; + + port { + ltdc_out_rgb: endpoint { + remote-endpoint = <&panel_in_rgb>; + }; + }; }; &mac { diff --git a/sys/gnu/dts/arm/stm32f429-disco.dts b/sys/gnu/dts/arm/stm32f429-disco.dts index 191fa50e34eb..ae47cde7952f 100644 --- a/sys/gnu/dts/arm/stm32f429-disco.dts +++ b/sys/gnu/dts/arm/stm32f429-disco.dts @@ -102,6 +102,10 @@ clock-frequency = <8000000>; }; +&crc { + status = "okay"; +}; + &rtc { assigned-clocks = <&rcc 1 CLK_RTC>; assigned-clock-parents = <&rcc 1 CLK_LSI>; diff --git a/sys/gnu/dts/arm/stm32f429.dtsi b/sys/gnu/dts/arm/stm32f429.dtsi index b2a2b5c38caa..a8113dc879cf 100644 --- a/sys/gnu/dts/arm/stm32f429.dtsi +++ b/sys/gnu/dts/arm/stm32f429.dtsi @@ -65,7 +65,7 @@ clock-frequency = <32768>; }; - clk-lsi { + clk_lsi: clk-lsi { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32000>; @@ -307,6 +307,13 @@ status = "disabled"; }; + iwdg: watchdog@40003000 { + compatible = "st,stm32-iwdg"; + reg = <0x40003000 0x400>; + clocks = <&clk_lsi>; + status = "disabled"; + }; + usart2: serial@40004400 { compatible = "st,stm32-usart", "st,stm32-uart"; reg = <0x40004400 0x400>; @@ -549,7 +556,17 @@ reg = <0x40007000 0x400>; }; - pin-controller { + ltdc: display-controller@40016800 { + compatible = "st,stm32-ltdc"; + reg = <0x40016800 0x200>; + interrupts = <88>, <89>; + resets = <&rcc STM32F4_APB2_RESET(LTDC)>; + clocks = <&rcc 1 CLK_LCD>; + clock-names = "lcd"; + status = "disabled"; + }; + + pinctrl: pin-controller { #address-cells = <1>; #size-cells = <1>; compatible = "st,stm32f429-pinctrl"; @@ -561,6 +578,8 @@ gpioa: gpio@40020000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x0 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; st,bank-name = "GPIOA"; @@ -569,6 +588,8 @@ gpiob: gpio@40020400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x400 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; st,bank-name = "GPIOB"; @@ -577,6 +598,8 @@ gpioc: gpio@40020800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x800 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; st,bank-name = "GPIOC"; @@ -585,6 +608,8 @@ gpiod: gpio@40020c00 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0xc00 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; st,bank-name = "GPIOD"; @@ -593,6 +618,8 @@ gpioe: gpio@40021000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1000 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; st,bank-name = "GPIOE"; @@ -601,6 +628,8 @@ gpiof: gpio@40021400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1400 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; st,bank-name = "GPIOF"; @@ -609,6 +638,8 @@ gpiog: gpio@40021800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1800 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; st,bank-name = "GPIOG"; @@ -617,6 +648,8 @@ gpioh: gpio@40021c00 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1c00 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; st,bank-name = "GPIOH"; @@ -625,6 +658,8 @@ gpioi: gpio@40022000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2000 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; st,bank-name = "GPIOI"; @@ -633,6 +668,8 @@ gpioj: gpio@40022400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2400 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; st,bank-name = "GPIOJ"; @@ -641,6 +678,8 @@ gpiok: gpio@40022800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2800 0x400>; clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; st,bank-name = "GPIOK"; @@ -764,6 +803,70 @@ slew-rate = <3>; }; }; + + ltdc_pins: ltdc@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + + dcmi_pins: dcmi@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + }; + }; + + crc: crc@40023000 { + compatible = "st,stm32f4-crc"; + reg = <0x40023000 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(CRC)>; + status = "disabled"; }; rcc: rcc@40023810 { @@ -842,6 +945,20 @@ status = "disabled"; }; + dcmi: dcmi@50050000 { + compatible = "st,stm32-dcmi"; + reg = <0x50050000 0x400>; + interrupts = <78>; + resets = <&rcc STM32F4_AHB2_RESET(DCMI)>; + clocks = <&rcc 0 STM32F4_AHB2_CLOCK(DCMI)>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&dcmi_pins>; + dmas = <&dma2 1 1 0x414 0x3>; + dma-names = "tx"; + status = "disabled"; + }; + rng: rng@50060800 { compatible = "st,stm32-rng"; reg = <0x50060800 0x400>; diff --git a/sys/gnu/dts/arm/stm32f746-disco.dts b/sys/gnu/dts/arm/stm32f746-disco.dts new file mode 100644 index 000000000000..18f656074437 --- /dev/null +++ b/sys/gnu/dts/arm/stm32f746-disco.dts @@ -0,0 +1,74 @@ +/* + * Copyright 2017 - Vikas MANOCHA + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "stm32f746.dtsi" +#include + +/ { + model = "STMicroelectronics STM32F746-DISCO board"; + compatible = "st,stm32f746-disco", "st,stm32f746"; + + chosen { + bootargs = "root=/dev/ram"; + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0xC0000000 0x800000>; + }; + + aliases { + serial0 = &usart1; + }; + +}; + +&clk_hse { + clock-frequency = <25000000>; +}; + +&usart1 { + pinctrl-0 = <&usart1_pins_b>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/stm32f746.dtsi b/sys/gnu/dts/arm/stm32f746.dtsi index c2765ce12e2e..4506eb97a4ab 100644 --- a/sys/gnu/dts/arm/stm32f746.dtsi +++ b/sys/gnu/dts/arm/stm32f746.dtsi @@ -229,6 +229,8 @@ gpioa: gpio@40020000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x0 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>; st,bank-name = "GPIOA"; @@ -237,6 +239,8 @@ gpiob: gpio@40020400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x400 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>; st,bank-name = "GPIOB"; @@ -245,6 +249,8 @@ gpioc: gpio@40020800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x800 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>; st,bank-name = "GPIOC"; @@ -253,6 +259,8 @@ gpiod: gpio@40020c00 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0xc00 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>; st,bank-name = "GPIOD"; @@ -261,6 +269,8 @@ gpioe: gpio@40021000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1000 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>; st,bank-name = "GPIOE"; @@ -269,6 +279,8 @@ gpiof: gpio@40021400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1400 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>; st,bank-name = "GPIOF"; @@ -277,6 +289,8 @@ gpiog: gpio@40021800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1800 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>; st,bank-name = "GPIOG"; @@ -285,6 +299,8 @@ gpioh: gpio@40021c00 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x1c00 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>; st,bank-name = "GPIOH"; @@ -293,6 +309,8 @@ gpioi: gpio@40022000 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2000 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>; st,bank-name = "GPIOI"; @@ -301,6 +319,8 @@ gpioj: gpio@40022400 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2400 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>; st,bank-name = "GPIOJ"; @@ -309,6 +329,8 @@ gpiok: gpio@40022800 { gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; reg = <0x2800 0x400>; clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>; st,bank-name = "GPIOK"; @@ -326,6 +348,19 @@ bias-disable; }; }; + + usart1_pins_b: usart1@1 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; }; crc: crc@40023000 { @@ -336,6 +371,7 @@ }; rcc: rcc@40023800 { + #reset-cells = <1>; #clock-cells = <2>; compatible = "st,stm32f746-rcc", "st,stm32-rcc"; reg = <0x40023800 0x400>; diff --git a/sys/gnu/dts/arm/stm32f769-disco.dts b/sys/gnu/dts/arm/stm32f769-disco.dts new file mode 100644 index 000000000000..166728aeb166 --- /dev/null +++ b/sys/gnu/dts/arm/stm32f769-disco.dts @@ -0,0 +1,74 @@ +/* + * Copyright 2017 - Vikas MANOCHA + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "stm32f746.dtsi" +#include + +/ { + model = "STMicroelectronics STM32F769-DISCO board"; + compatible = "st,stm32f769-disco", "st,stm32f7"; + + chosen { + bootargs = "root=/dev/ram"; + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0xC0000000 0x1000000>; + }; + + aliases { + serial0 = &usart1; + }; + +}; + +&clk_hse { + clock-frequency = <25000000>; +}; + +&usart1 { + pinctrl-0 = <&usart1_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi b/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi index fcc1e0640233..76bbd6575fae 100644 --- a/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi +++ b/sys/gnu/dts/arm/stm32h743-pinctrl.dtsi @@ -151,6 +151,19 @@ bias-disable; }; }; + + usart2_pins: usart2@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/stm32h743.dtsi b/sys/gnu/dts/arm/stm32h743.dtsi index 46856298ee16..36a99db0a3b4 100644 --- a/sys/gnu/dts/arm/stm32h743.dtsi +++ b/sys/gnu/dts/arm/stm32h743.dtsi @@ -68,6 +68,14 @@ }; + usart2: serial@40004400 { + compatible = "st,stm32f7-usart", "st,stm32f7-uart"; + reg = <0x40004400 0x400>; + interrupts = <38>; + status = "disabled"; + clocks = <&timer_clk>; + }; + timer5: timer@40000c00 { compatible = "st,stm32-timer"; reg = <0x40000c00 0x400>; diff --git a/sys/gnu/dts/arm/stm32h743i-disco.dts b/sys/gnu/dts/arm/stm32h743i-disco.dts new file mode 100644 index 000000000000..79e841d94079 --- /dev/null +++ b/sys/gnu/dts/arm/stm32h743i-disco.dts @@ -0,0 +1,73 @@ +/* + * Copyright 2017 - Patrice Chotard + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "stm32h743.dtsi" +#include "stm32h743-pinctrl.dtsi" + +/ { + model = "STMicroelectronics STM32H743i-Discovery board"; + compatible = "st,stm32h743i-disco", "st,stm32h743"; + + chosen { + bootargs = "root=/dev/ram"; + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0xd0000000 0x2000000>; + }; + + aliases { + serial0 = &usart2; + }; +}; + +&clk_hse { + clock-frequency = <125000000>; +}; + +&usart2 { + pinctrl-0 = <&usart2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/sun4i-a10-a1000.dts b/sys/gnu/dts/arm/sun4i-a10-a1000.dts index f2a01fe2bebc..f80d37ddc4c6 100644 --- a/sys/gnu/dts/arm/sun4i-a10-a1000.dts +++ b/sys/gnu/dts/arm/sun4i-a10-a1000.dts @@ -171,7 +171,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-ba10-tvbox.dts b/sys/gnu/dts/arm/sun4i-a10-ba10-tvbox.dts index 942d739a4384..6b02de592a02 100644 --- a/sys/gnu/dts/arm/sun4i-a10-ba10-tvbox.dts +++ b/sys/gnu/dts/arm/sun4i-a10-ba10-tvbox.dts @@ -109,7 +109,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-chuwi-v7-cw0825.dts b/sys/gnu/dts/arm/sun4i-a10-chuwi-v7-cw0825.dts index 17f8c5ec011c..a7d61994b8fd 100644 --- a/sys/gnu/dts/arm/sun4i-a10-chuwi-v7-cw0825.dts +++ b/sys/gnu/dts/arm/sun4i-a10-chuwi-v7-cw0825.dts @@ -128,7 +128,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts b/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts index d844938e2aa7..404ce7694899 100644 --- a/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts +++ b/sys/gnu/dts/arm/sun4i-a10-cubieboard.dts @@ -142,7 +142,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -182,6 +182,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; diff --git a/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts b/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts index aad3bec1cb39..e0777ae808c7 100644 --- a/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts +++ b/sys/gnu/dts/arm/sun4i-a10-dserve-dsrv9703c.dts @@ -163,7 +163,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-gemei-g9.dts b/sys/gnu/dts/arm/sun4i-a10-gemei-g9.dts index 9616cdecce93..d8bfd7b74916 100644 --- a/sys/gnu/dts/arm/sun4i-a10-gemei-g9.dts +++ b/sys/gnu/dts/arm/sun4i-a10-gemei-g9.dts @@ -146,7 +146,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH01 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-hackberry.dts b/sys/gnu/dts/arm/sun4i-a10-hackberry.dts index a1a7282199d5..856cfc9128e6 100644 --- a/sys/gnu/dts/arm/sun4i-a10-hackberry.dts +++ b/sys/gnu/dts/arm/sun4i-a10-hackberry.dts @@ -107,7 +107,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-hyundai-a7hd.dts b/sys/gnu/dts/arm/sun4i-a10-hyundai-a7hd.dts index 85dcf81ab64e..6506595268b2 100644 --- a/sys/gnu/dts/arm/sun4i-a10-hyundai-a7hd.dts +++ b/sys/gnu/dts/arm/sun4i-a10-hyundai-a7hd.dts @@ -79,7 +79,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -120,10 +120,6 @@ status = "okay"; }; -&usb2_vbus_pin_a { - pins = "PH6"; -}; - &usb_otg { dr_mode = "otg"; status = "okay"; diff --git a/sys/gnu/dts/arm/sun4i-a10-inet1.dts b/sys/gnu/dts/arm/sun4i-a10-inet1.dts index b8923b92cb36..d51d8c302daf 100644 --- a/sys/gnu/dts/arm/sun4i-a10-inet1.dts +++ b/sys/gnu/dts/arm/sun4i-a10-inet1.dts @@ -161,7 +161,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-inet97fv2.dts b/sys/gnu/dts/arm/sun4i-a10-inet97fv2.dts index a1a2bbb3f9d3..a8e479fe43ca 100644 --- a/sys/gnu/dts/arm/sun4i-a10-inet97fv2.dts +++ b/sys/gnu/dts/arm/sun4i-a10-inet97fv2.dts @@ -147,7 +147,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts b/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts index 4a27eb9102cd..2acb89a87d41 100644 --- a/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts +++ b/sys/gnu/dts/arm/sun4i-a10-inet9f-rev03.dts @@ -305,7 +305,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-itead-iteaduino-plus.dts b/sys/gnu/dts/arm/sun4i-a10-itead-iteaduino-plus.dts index 4e798f014c99..92e3e030ced3 100644 --- a/sys/gnu/dts/arm/sun4i-a10-itead-iteaduino-plus.dts +++ b/sys/gnu/dts/arm/sun4i-a10-itead-iteaduino-plus.dts @@ -100,7 +100,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts b/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts index 308dc1513041..92b2d4af3d21 100644 --- a/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts +++ b/sys/gnu/dts/arm/sun4i-a10-jesurun-q5.dts @@ -140,7 +140,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-marsboard.dts b/sys/gnu/dts/arm/sun4i-a10-marsboard.dts index 98a5f7258dca..0f927da28ee1 100644 --- a/sys/gnu/dts/arm/sun4i-a10-marsboard.dts +++ b/sys/gnu/dts/arm/sun4i-a10-marsboard.dts @@ -141,7 +141,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts b/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts index 484c57493bd2..a5ed9e4e22c6 100644 --- a/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts +++ b/sys/gnu/dts/arm/sun4i-a10-mini-xplus.dts @@ -97,7 +97,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-mk802.dts b/sys/gnu/dts/arm/sun4i-a10-mk802.dts index 2b75745cd246..81db6824a2c7 100644 --- a/sys/gnu/dts/arm/sun4i-a10-mk802.dts +++ b/sys/gnu/dts/arm/sun4i-a10-mk802.dts @@ -72,7 +72,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-mk802ii.dts b/sys/gnu/dts/arm/sun4i-a10-mk802ii.dts index c861fa7e356c..e74a881fd9a7 100644 --- a/sys/gnu/dts/arm/sun4i-a10-mk802ii.dts +++ b/sys/gnu/dts/arm/sun4i-a10-mk802ii.dts @@ -83,7 +83,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts b/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts index 3a2522a9419d..462412ee903c 100644 --- a/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts +++ b/sys/gnu/dts/arm/sun4i-a10-olinuxino-lime.dts @@ -145,7 +145,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-pcduino.dts b/sys/gnu/dts/arm/sun4i-a10-pcduino.dts index 83596fd2ccfc..84f55e76df0c 100644 --- a/sys/gnu/dts/arm/sun4i-a10-pcduino.dts +++ b/sys/gnu/dts/arm/sun4i-a10-pcduino.dts @@ -147,7 +147,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts b/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts index a68c7cc53b94..c0f8c88b5a7d 100644 --- a/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts +++ b/sys/gnu/dts/arm/sun4i-a10-pov-protab2-ips9.dts @@ -149,7 +149,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun4i-a10.dtsi b/sys/gnu/dts/arm/sun4i-a10.dtsi index b63668ece151..41c2579143fd 100644 --- a/sys/gnu/dts/arm/sun4i-a10.dtsi +++ b/sys/gnu/dts/arm/sun4i-a10.dtsi @@ -1030,12 +1030,6 @@ bias-pull-up; }; - mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { - pins = "PH1"; - function = "gpio_in"; - bias-pull-up; - }; - ps20_pins_a: ps20@0 { pins = "PI20", "PI21"; function = "ps2"; diff --git a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts index c6f742a7e69f..d2dee8d434bf 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t003.dts @@ -136,14 +136,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG13"; -}; - -&usb1_vbus_pin_a { - pins = "PB10"; -}; - &usb_otg { dr_mode = "host"; status = "okay"; diff --git a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts index a27c3fa58736..16f839df4227 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-auxtek-t004.dts @@ -168,10 +168,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - pins = "PG13"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts b/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts index 894f874a5beb..da95118af4dc 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-olinuxino-micro.dts @@ -63,6 +63,17 @@ stdout-path = "serial0:115200n8"; }; + connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -76,6 +87,10 @@ }; }; +&be0 { + status = "okay"; +}; + &ehci0 { status = "okay"; }; @@ -91,6 +106,16 @@ status = "okay"; }; +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; @@ -248,6 +273,10 @@ status = "okay"; }; +&tcon0 { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -271,10 +300,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG11"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts b/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts index ea3e5655a61b..5482be174e12 100644 --- a/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts +++ b/sys/gnu/dts/arm/sun5i-a10s-wobo-i5.dts @@ -216,10 +216,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; diff --git a/sys/gnu/dts/arm/sun5i-a10s.dtsi b/sys/gnu/dts/arm/sun5i-a10s.dtsi index 1e38ff80366c..18f25c5e75ae 100644 --- a/sys/gnu/dts/arm/sun5i-a10s.dtsi +++ b/sys/gnu/dts/arm/sun5i-a10s.dtsi @@ -71,7 +71,46 @@ }; }; + display-engine { + compatible = "allwinner,sun5i-a10s-display-engine"; + allwinner,pipelines = <&fe0>; + }; + soc@01c00000 { + hdmi: hdmi@01c16000 { + compatible = "allwinner,sun5i-a10s-hdmi"; + reg = <0x01c16000 0x1000>; + interrupts = <58>; + clocks = <&ccu CLK_AHB_HDMI>, <&ccu CLK_HDMI>, + <&ccu 9>, + <&ccu 16>; + clock-names = "ahb", "mod", "pll-0", "pll-1"; + dmas = <&dma SUN4I_DMA_NORMAL 16>, + <&dma SUN4I_DMA_NORMAL 16>, + <&dma SUN4I_DMA_DEDICATED 24>; + dma-names = "ddc-tx", "ddc-rx", "audio-tx"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + + hdmi_in_tcon0: endpoint { + remote-endpoint = <&tcon0_out_hdmi>; + }; + }; + + hdmi_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + pwm: pwm@01c20e00 { compatible = "allwinner,sun5i-a10s-pwm"; reg = <0x01c20e00 0xc>; @@ -128,3 +167,11 @@ &sram_a { }; + +&tcon0_out { + tcon0_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_tcon0>; + allwinner,tcon-channel = <1>; + }; +}; diff --git a/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts b/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts index 34411d27aadf..3dbb0d7c2f8c 100644 --- a/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts +++ b/sys/gnu/dts/arm/sun5i-a13-empire-electronix-d709.dts @@ -207,10 +207,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts b/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts index 2489c16f7efa..584fa579ded2 100644 --- a/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts +++ b/sys/gnu/dts/arm/sun5i-a13-hsg-h702.dts @@ -186,7 +186,6 @@ }; ®_usb0_vbus { - pinctrl-0 = <&usb0_vbus_pin_a>; gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ status = "okay"; }; @@ -202,10 +201,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts b/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts index 95f591bb8ced..38072c7e10e2 100644 --- a/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts +++ b/sys/gnu/dts/arm/sun5i-a13-olinuxino.dts @@ -269,10 +269,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/sys/gnu/dts/arm/sun5i-r8-chip.dts b/sys/gnu/dts/arm/sun5i-r8-chip.dts index d0785602663b..879a4b0f3bd5 100644 --- a/sys/gnu/dts/arm/sun5i-r8-chip.dts +++ b/sys/gnu/dts/arm/sun5i-r8-chip.dts @@ -132,6 +132,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins_a>; diff --git a/sys/gnu/dts/arm/sun5i.dtsi b/sys/gnu/dts/arm/sun5i.dtsi index 5175f9cc9bed..98cc00341b00 100644 --- a/sys/gnu/dts/arm/sun5i.dtsi +++ b/sys/gnu/dts/arm/sun5i.dtsi @@ -272,6 +272,7 @@ tcon0_out_tve0: endpoint@1 { reg = <1>; remote-endpoint = <&tve0_in_tcon0>; + allwinner,tcon-channel = <1>; }; }; }; @@ -355,6 +356,15 @@ status = "disabled"; }; + crypto: crypto-engine@01c15000 { + compatible = "allwinner,sun5i-a13-crypto", + "allwinner,sun4i-a10-crypto"; + reg = <0x01c15000 0x1000>; + interrupts = <54>; + clocks = <&ccu CLK_AHB_SS>, <&ccu CLK_SS>; + clock-names = "ahb", "mod"; + }; + spi2: spi@01c17000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c17000 0x1000>; diff --git a/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts b/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts index d4f74f476f25..9ecb5f0b3f83 100644 --- a/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts +++ b/sys/gnu/dts/arm/sun6i-a31-hummingbird.dts @@ -253,6 +253,10 @@ #include "axp22x.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_aldo1 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -319,7 +323,6 @@ &tcon0 { pinctrl-names = "default"; pinctrl-0 = <&lcd0_rgb888_pins>; - status = "okay"; }; &tcon0_out { @@ -344,11 +347,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - /* different pin from sunxi-common-regulators */ - pins = "PH24"; -}; - &usbphy { usb0_id_det-gpio = <&pio 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */ usb0_vbus_det-gpio = <&pio 0 16 GPIO_ACTIVE_HIGH>; /* PA16 */ diff --git a/sys/gnu/dts/arm/sun6i-a31.dtsi b/sys/gnu/dts/arm/sun6i-a31.dtsi index 9c999d3788f6..aebc3f9dc7b6 100644 --- a/sys/gnu/dts/arm/sun6i-a31.dtsi +++ b/sys/gnu/dts/arm/sun6i-a31.dtsi @@ -232,7 +232,7 @@ de: display-engine { compatible = "allwinner,sun6i-a31-display-engine"; - allwinner,pipelines = <&fe0>; + allwinner,pipelines = <&fe0>, <&fe1>; status = "disabled"; }; @@ -264,7 +264,6 @@ "tcon-ch0", "tcon-ch1"; clock-output-names = "tcon0-pixel-clock"; - status = "disabled"; ports { #address-cells = <1>; @@ -289,6 +288,43 @@ }; }; + tcon1: lcd-controller@01c0d000 { + compatible = "allwinner,sun6i-a31-tcon"; + reg = <0x01c0d000 0x1000>; + interrupts = ; + resets = <&ccu RST_AHB1_LCD1>; + reset-names = "lcd"; + clocks = <&ccu CLK_AHB1_LCD1>, + <&ccu CLK_LCD1_CH0>, + <&ccu CLK_LCD1_CH1>; + clock-names = "ahb", + "tcon-ch0", + "tcon-ch1"; + clock-output-names = "tcon1-pixel-clock"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon1_in_drc1: endpoint@0 { + reg = <0>; + remote-endpoint = <&drc1_out_tcon1>; + }; + }; + + tcon1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + mmc0: mmc@01c0f000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; @@ -780,7 +816,8 @@ }; crypto: crypto-engine@01c15000 { - compatible = "allwinner,sun4i-a10-crypto"; + compatible = "allwinner,sun6i-a31-crypto", + "allwinner,sun4i-a10-crypto"; reg = <0x01c15000 0x1000>; interrupts = ; clocks = <&ccu CLK_AHB1_SS>, <&ccu CLK_SS>; @@ -896,6 +933,130 @@ reg = <0>; remote-endpoint = <&be0_in_fe0>; }; + + fe0_out_be1: endpoint@1 { + reg = <1>; + remote-endpoint = <&be1_in_fe0>; + }; + }; + }; + }; + + fe1: display-frontend@01e20000 { + compatible = "allwinner,sun6i-a31-display-frontend"; + reg = <0x01e20000 0x20000>; + interrupts = ; + clocks = <&ccu CLK_AHB1_FE1>, <&ccu CLK_FE1>, + <&ccu CLK_DRAM_FE1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_FE1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + fe1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + fe1_out_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_in_fe1>; + }; + + fe1_out_be1: endpoint@1 { + reg = <1>; + remote-endpoint = <&be1_in_fe1>; + }; + }; + }; + }; + + be1: display-backend@01e40000 { + compatible = "allwinner,sun6i-a31-display-backend"; + reg = <0x01e40000 0x10000>; + interrupts = ; + clocks = <&ccu CLK_AHB1_BE1>, <&ccu CLK_BE1>, + <&ccu CLK_DRAM_BE1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_BE1>; + + assigned-clocks = <&ccu CLK_BE1>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + be1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + be1_in_fe0: endpoint@0 { + reg = <0>; + remote-endpoint = <&fe0_out_be1>; + }; + + be1_in_fe1: endpoint@1 { + reg = <1>; + remote-endpoint = <&fe1_out_be1>; + }; + }; + + be1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + be1_out_drc1: endpoint@0 { + reg = <0>; + remote-endpoint = <&drc1_in_be1>; + }; + }; + }; + }; + + drc1: drc@01e50000 { + compatible = "allwinner,sun6i-a31-drc"; + reg = <0x01e50000 0x10000>; + interrupts = ; + clocks = <&ccu CLK_AHB1_DRC1>, <&ccu CLK_IEP_DRC1>, + <&ccu CLK_DRAM_DRC1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_DRC1>; + + assigned-clocks = <&ccu CLK_IEP_DRC1>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + drc1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + drc1_in_be1: endpoint@0 { + reg = <0>; + remote-endpoint = <&be1_out_drc1>; + }; + }; + + drc1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + drc1_out_tcon1: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon1_in_drc1>; + }; }; }; }; @@ -926,6 +1087,11 @@ reg = <0>; remote-endpoint = <&fe0_out_be0>; }; + + be0_in_fe1: endpoint@1 { + reg = <1>; + remote-endpoint = <&fe1_out_be0>; + }; }; be0_out: port@1 { diff --git a/sys/gnu/dts/arm/sun6i-a31s-primo81.dts b/sys/gnu/dts/arm/sun6i-a31s-primo81.dts index f3712753fa42..4c10123509c4 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-primo81.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-primo81.dts @@ -158,11 +158,16 @@ reg = <0x68>; interrupt-parent = <&nmi_intc>; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + x-powers,drive-vbus-en; }; }; #include "axp22x.dtsi" +&battery_power_supply { + status = "okay"; +}; + ®_aldo3 { regulator-always-on; regulator-min-microvolt = <2700000>; @@ -226,6 +231,11 @@ regulator-name = "vddio-csi"; }; +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + ®_eldo3 { regulator-min-microvolt = <1080000>; regulator-max-microvolt = <1320000>; @@ -238,12 +248,18 @@ }; &usb_otg { - /* otg support requires support for AXP221 usb-power-supply and GPIO */ - dr_mode = "host"; + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { status = "okay"; }; &usbphy { + usb0_id_det-gpio = <&pio 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb0_vbus-supply = <®_drivevbus>; usb1_vbus-supply = <®_dldo1>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts b/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts index bdfdce8ca6ba..51e6f1d21c32 100644 --- a/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts +++ b/sys/gnu/dts/arm/sun6i-a31s-sinovoip-bpi-m2.dts @@ -138,7 +138,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&r_pio>; diff --git a/sys/gnu/dts/arm/sun7i-a20-bananapi-m1-plus.dts b/sys/gnu/dts/arm/sun7i-a20-bananapi-m1-plus.dts index 08e776ae095a..eb55e74232c9 100644 --- a/sys/gnu/dts/arm/sun7i-a20-bananapi-m1-plus.dts +++ b/sys/gnu/dts/arm/sun7i-a20-bananapi-m1-plus.dts @@ -144,6 +144,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + &ir0 { pinctrl-names = "default"; pinctrl-0 = <&ir0_rx_pins_a>; @@ -172,7 +176,7 @@ wakeup-source; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/sys/gnu/dts/arm/sun7i-a20-bananapi.dts b/sys/gnu/dts/arm/sun7i-a20-bananapi.dts index ed2f35adf542..88a1c2363c6c 100644 --- a/sys/gnu/dts/arm/sun7i-a20-bananapi.dts +++ b/sys/gnu/dts/arm/sun7i-a20-bananapi.dts @@ -177,6 +177,57 @@ }; &pio { + gpio-line-names = + /* PA */ + "ERXD3", "ERXD2", "ERXD1", "ERXD0", "ETXD3", + "ETXD2", "ETXD1", "ETXD0", + "ERXCK", "ERXERR", "ERXDV", "EMDC", "EMDIO", + "ETXEN", "ETXCK", "ECRS", + "ECOL", "ETXERR", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PB */ + "PMU-SCK", "PMU-SDA", "", "", "", "", "", "", + "", "USB0-DRV", "", "", "", "", "", "", + "", "", "", "", "SCL", "SDA", "", "", + "", "", "", "", "", "", "", "", + /* PC */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PD */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PE */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PF */ + "SD0-D1", "SD0-D0", "SD0-CLK", "SD0-CMD", "SD0-D3", + "SD0-D2", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PG */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PH */ + "TXD0", "RXD0", "IO-1", "PH3", "USB0-IDDET", "PH5", "", "", + "", "", "SD0-DET", "", "", "", "", "", + "", "", "", "", "IO-4", "IO-5", "", "EMAC-PWR-EN", + "LED1", "", "", "", "", "", "", "", + /* PI */ + "", "", "", "IO-GCLK", "", "", "", "", + "", "", "SPI-CE0", "SPI-CLK", "SPI-MOSI", + "SPI-MISO", "SPI-CE1", "", + "IO-6", "IO-3", "IO-2", "IO-0", "", "", "", "", + "", "", "", "", "", "", "", ""; + usb0_id_detect_pin: usb0_id_detect_pin@0 { pins = "PH4"; function = "gpio_in"; diff --git a/sys/gnu/dts/arm/sun7i-a20-bananapro.dts b/sys/gnu/dts/arm/sun7i-a20-bananapro.dts index 83516bc81225..e7af1b7c33d5 100644 --- a/sys/gnu/dts/arm/sun7i-a20-bananapro.dts +++ b/sys/gnu/dts/arm/sun7i-a20-bananapro.dts @@ -172,7 +172,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts b/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts index a2eab7aa80e0..2a50207618cb 100644 --- a/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts +++ b/sys/gnu/dts/arm/sun7i-a20-cubieboard2.dts @@ -137,7 +137,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -174,13 +174,12 @@ status = "okay"; }; -&usb_otg { - dr_mode = "otg"; +#include "axp209.dtsi" + +&ac_power_supply { status = "okay"; }; -#include "axp209.dtsi" - ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; @@ -220,6 +219,11 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts b/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts index 102903e83bd2..bb510187602c 100644 --- a/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts +++ b/sys/gnu/dts/arm/sun7i-a20-cubietruck.dts @@ -178,7 +178,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -195,7 +195,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; @@ -336,6 +336,7 @@ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; usb0_id_det-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */ usb0_vbus_det-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */ + usb0_vbus_power-supply = <&usb_power_supply>; usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; diff --git a/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts b/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts index 99c00b9a1546..6e6264cd69f8 100644 --- a/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts +++ b/sys/gnu/dts/arm/sun7i-a20-hummingbird.dts @@ -160,7 +160,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v0>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts b/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts index 4da49717da21..55809973a568 100644 --- a/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts +++ b/sys/gnu/dts/arm/sun7i-a20-i12-tvbox.dts @@ -157,7 +157,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -173,7 +173,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts b/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts index 28d3abbdc2d4..794e7617f545 100644 --- a/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts +++ b/sys/gnu/dts/arm/sun7i-a20-icnova-swac.dts @@ -104,7 +104,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; /* PI5 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-itead-ibox.dts b/sys/gnu/dts/arm/sun7i-a20-itead-ibox.dts index d52222c82cb8..8a8a6dbcd414 100644 --- a/sys/gnu/dts/arm/sun7i-a20-itead-ibox.dts +++ b/sys/gnu/dts/arm/sun7i-a20-itead-ibox.dts @@ -121,7 +121,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts b/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts index 96bb0bc198ba..004b6ddac813 100644 --- a/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts +++ b/sys/gnu/dts/arm/sun7i-a20-lamobo-r1.dts @@ -85,10 +85,6 @@ }; }; -&ahci_pwr_pin_a { - pins = "PB3"; -}; - &ahci { target-supply = <®_ahci_5v>; status = "okay"; @@ -319,10 +315,6 @@ status = "okay"; }; -&usb2_vbus_pin_a { - pins = "PH12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/sys/gnu/dts/arm/sun7i-a20-m3.dts b/sys/gnu/dts/arm/sun7i-a20-m3.dts index 86f69813683e..43c94787ef07 100644 --- a/sys/gnu/dts/arm/sun7i-a20-m3.dts +++ b/sys/gnu/dts/arm/sun7i-a20-m3.dts @@ -117,7 +117,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-mk808c.dts b/sys/gnu/dts/arm/sun7i-a20-mk808c.dts index c4ee30709f3a..f7413094183c 100644 --- a/sys/gnu/dts/arm/sun7i-a20-mk808c.dts +++ b/sys/gnu/dts/arm/sun7i-a20-mk808c.dts @@ -109,7 +109,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v0>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts b/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts index 1af5b46862cb..64c8ef9a2756 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olimex-som-evb.dts @@ -187,7 +187,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts index dcd0f7a0dffa..2ce1a9f13a17 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime.dts @@ -130,7 +130,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts index e7d45425758c..097bd755764c 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-lime2.dts @@ -131,7 +131,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts b/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts index def0ad8395bb..0b7403e4d687 100644 --- a/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts +++ b/sys/gnu/dts/arm/sun7i-a20-olinuxino-micro.dts @@ -198,7 +198,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-pcduino3-nano.dts b/sys/gnu/dts/arm/sun7i-a20-pcduino3-nano.dts index f47a5c46bc20..39bc73db72e5 100644 --- a/sys/gnu/dts/arm/sun7i-a20-pcduino3-nano.dts +++ b/sys/gnu/dts/arm/sun7i-a20-pcduino3-nano.dts @@ -130,7 +130,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts b/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts index 7c96b53b76bf..777152a3df0f 100644 --- a/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts +++ b/sys/gnu/dts/arm/sun7i-a20-pcduino3.dts @@ -106,10 +106,6 @@ status = "okay"; }; -&ahci_pwr_pin_a { - pins = "PH2"; -}; - &codec { status = "okay"; }; @@ -160,7 +156,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-wexler-tab7200.dts b/sys/gnu/dts/arm/sun7i-a20-wexler-tab7200.dts index e19f17177755..f8d0aafb9f88 100644 --- a/sys/gnu/dts/arm/sun7i-a20-wexler-tab7200.dts +++ b/sys/gnu/dts/arm/sun7i-a20-wexler-tab7200.dts @@ -151,7 +151,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/sys/gnu/dts/arm/sun7i-a20-wits-pro-a20-dkt.dts b/sys/gnu/dts/arm/sun7i-a20-wits-pro-a20-dkt.dts index c3078d4f1093..7f8405a0dd0f 100644 --- a/sys/gnu/dts/arm/sun7i-a20-wits-pro-a20-dkt.dts +++ b/sys/gnu/dts/arm/sun7i-a20-wits-pro-a20-dkt.dts @@ -120,7 +120,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -137,7 +137,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/sys/gnu/dts/arm/sun7i-a20.dtsi b/sys/gnu/dts/arm/sun7i-a20.dtsi index 93aa55970bd7..96bee776e145 100644 --- a/sys/gnu/dts/arm/sun7i-a20.dtsi +++ b/sys/gnu/dts/arm/sun7i-a20.dtsi @@ -1019,7 +1019,8 @@ }; crypto: crypto-engine@01c15000 { - compatible = "allwinner,sun4i-a10-crypto"; + compatible = "allwinner,sun7i-a20-crypto", + "allwinner,sun4i-a10-crypto"; reg = <0x01c15000 0x1000>; interrupts = ; clocks = <&ahb_gates 5>, <&ss_clk>; @@ -1190,12 +1191,6 @@ bias-pull-up; }; - mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { - pins = "PH1"; - function = "gpio_in"; - bias-pull-up; - }; - mmc2_pins_a: mmc2@0 { pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11"; diff --git a/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts b/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts index 9b620cc1d5f1..433cf2a2a9a2 100644 --- a/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts +++ b/sys/gnu/dts/arm/sun8i-a33-sinlinx-sina33.dts @@ -88,13 +88,13 @@ }; &cpu0_opp_table { - opp@1104000000 { + opp-1104000000 { opp-hz = /bits/ 64 <1104000000>; opp-microvolt = <1320000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <1320000>; clock-latency-ns = <244144>; /* 8 32k periods */ @@ -196,6 +196,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + ®_aldo1 { regulator-always-on; regulator-min-microvolt = <3000000>; diff --git a/sys/gnu/dts/arm/sun8i-a33.dtsi b/sys/gnu/dts/arm/sun8i-a33.dtsi index 013978259372..22660919bd08 100644 --- a/sys/gnu/dts/arm/sun8i-a33.dtsi +++ b/sys/gnu/dts/arm/sun8i-a33.dtsi @@ -50,73 +50,73 @@ compatible = "operating-points-v2"; opp-shared; - opp@120000000 { + opp-120000000 { opp-hz = /bits/ 64 <120000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@240000000 { + opp-240000000 { opp-hz = /bits/ 64 <240000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@312000000 { + opp-312000000 { opp-hz = /bits/ 64 <312000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@408000000 { + opp-408000000 { opp-hz = /bits/ 64 <408000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@480000000 { + opp-480000000 { opp-hz = /bits/ 64 <480000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@504000000 { + opp-504000000 { opp-hz = /bits/ 64 <504000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@648000000 { + opp-648000000 { opp-hz = /bits/ 64 <648000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@720000000 { + opp-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1100000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@816000000 { + opp-816000000 { opp-hz = /bits/ 64 <816000000>; opp-microvolt = <1100000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@912000000 { + opp-912000000 { opp-hz = /bits/ 64 <912000000>; opp-microvolt = <1200000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@1008000000 { + opp-1008000000 { opp-hz = /bits/ 64 <1008000000>; opp-microvolt = <1200000>; clock-latency-ns = <244144>; /* 8 32k periods */ @@ -164,15 +164,15 @@ mali_opp_table: gpu-opp-table { compatible = "operating-points-v2"; - opp@144000000 { + opp-144000000 { opp-hz = /bits/ 64 <144000000>; }; - opp@240000000 { + opp-240000000 { opp-hz = /bits/ 64 <240000000>; }; - opp@384000000 { + opp-384000000 { opp-hz = /bits/ 64 <384000000>; }; }; diff --git a/sys/gnu/dts/arm/sun8i-a83t-allwinner-h8homlet-v2.dts b/sys/gnu/dts/arm/sun8i-a83t-allwinner-h8homlet-v2.dts index 342e1d33fa1c..aecdeeb368ed 100644 --- a/sys/gnu/dts/arm/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/sys/gnu/dts/arm/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -59,6 +59,6 @@ &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_b>; + pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-a83t-cubietruck-plus.dts b/sys/gnu/dts/arm/sun8i-a83t-cubietruck-plus.dts index 88b1e0970b8d..cff33454fc24 100644 --- a/sys/gnu/dts/arm/sun8i-a83t-cubietruck-plus.dts +++ b/sys/gnu/dts/arm/sun8i-a83t-cubietruck-plus.dts @@ -45,6 +45,8 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include + / { model = "Cubietech Cubietruck Plus"; compatible = "cubietech,cubietruck-plus", "allwinner,sun8i-a83t"; @@ -56,10 +58,56 @@ chosen { stdout-path = "serial0:115200n8"; }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "cubietruck-plus:blue:usr"; + gpios = <&pio 3 25 GPIO_ACTIVE_HIGH>; /* PD25 */ + }; + + orange { + label = "cubietruck-plus:orange:usr"; + gpios = <&pio 3 26 GPIO_ACTIVE_HIGH>; /* PD26 */ + }; + + white { + label = "cubietruck-plus:white:usr"; + gpios = <&pio 3 27 GPIO_ACTIVE_HIGH>; /* PD27 */ + }; + + green { + label = "cubietruck-plus:green:usr"; + gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>; /* PE4 */ + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "On-board SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + spdif_out: spdif-out { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + }; +}; + +&spdif { + status = "okay"; }; &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_b>; + pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-a83t.dtsi b/sys/gnu/dts/arm/sun8i-a83t.dtsi index 0ec143773ee9..19a8f4fcfab5 100644 --- a/sys/gnu/dts/arm/sun8i-a83t.dtsi +++ b/sys/gnu/dts/arm/sun8i-a83t.dtsi @@ -40,15 +40,24 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "skeleton.dtsi" - #include +#include +#include +#include + / { interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + }; + + chosen { + }; cpus { #address-cells = <1>; @@ -121,6 +130,7 @@ #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <24000000>; + clock-accuracy = <50000>; clock-output-names = "osc24M"; }; @@ -146,25 +156,55 @@ }; }; + memory { + reg = <0x40000000 0x80000000>; + device_type = "memory"; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - pio: pinctrl@01c20800 { + syscon: syscon@1c00000 { + compatible = "allwinner,sun8i-a83t-system-controller", + "syscon"; + reg = <0x01c00000 0x1000>; + }; + + dma: dma-controller@1c02000 { + compatible = "allwinner,sun8i-a83t-dma"; + reg = <0x01c02000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_DMA>; + resets = <&ccu RST_BUS_DMA>; + #dma-cells = <1>; + }; + + ccu: clock@1c20000 { + compatible = "allwinner,sun8i-a83t-ccu"; + reg = <0x01c20000 0x400>; + clocks = <&osc24M>, <&osc16Md512>; + clock-names = "hosc", "losc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pio: pinctrl@1c20800 { compatible = "allwinner,sun8i-a83t-pinctrl"; interrupts = , , ; reg = <0x01c20800 0x400>; - clocks = <&osc24M>; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc16Md512>; + clock-names = "apb", "hosc", "losc"; gpio-controller; interrupt-controller; #interrupt-cells = <3>; #gpio-cells = <3>; - mmc0_pins_a: mmc0@0 { + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; function = "mmc0"; @@ -172,18 +212,23 @@ bias-pull-up; }; - uart0_pins_a: uart0@0 { - pins = "PF2", "PF4"; + spdif_tx_pin: spdif-tx-pin { + pins = "PE18"; + function = "spdif"; + }; + + uart0_pb_pins: uart0-pb-pins { + pins = "PB9", "PB10"; function = "uart0"; }; - uart0_pins_b: uart0@1 { - pins = "PB9", "PB10"; + uart0_pf_pins: uart0-pf-pins { + pins = "PF2", "PF4"; function = "uart0"; }; }; - timer@01c20c00 { + timer@1c20c00 { compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0xa0>; interrupts = , @@ -191,24 +236,41 @@ clocks = <&osc24M>; }; - watchdog@01c20ca0 { + watchdog@1c20ca0 { compatible = "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; interrupts = ; clocks = <&osc24M>; }; + spdif: spdif@1c21000 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun8i-a83t-spdif", + "allwinner,sun8i-h3-spdif"; + reg = <0x01c21000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; + resets = <&ccu RST_BUS_SPDIF>; + clock-names = "apb", "spdif"; + dmas = <&dma 2>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx_pin>; + status = "disabled"; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; - clocks = <&osc24M>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; status = "disabled"; }; - gic: interrupt-controller@01c81000 { + gic: interrupt-controller@1c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, <0x01c82000 0x2000>, @@ -218,5 +280,28 @@ #interrupt-cells = <3>; interrupts = ; }; + + r_ccu: clock@1f01400 { + compatible = "allwinner,sun8i-a83t-r-ccu"; + reg = <0x01f01400 0x400>; + clocks = <&osc24M>, <&osc16Md512>, <&osc16M>, + <&ccu 6>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + r_pio: pinctrl@1f02c00 { + compatible = "allwinner,sun8i-a83t-r-pinctrl"; + reg = <0x01f02c00 0x400>; + interrupts = ; + clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, + <&osc16Md512>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + }; }; }; diff --git a/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts b/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts index 9e8b082c134f..b1502df7b509 100644 --- a/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts +++ b/sys/gnu/dts/arm/sun8i-h2-plus-orangepi-zero.dts @@ -56,7 +56,6 @@ aliases { serial0 = &uart0; - /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ ethernet1 = &xr819; }; @@ -143,6 +142,19 @@ status = "okay"; }; +&spi0 { + /* Disable SPI NOR by default: it optional on Orange Pi Zero boards */ + status = "disabled"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mxicy,mx25l1606e", "winbond,w25q128"; + reg = <0>; + spi-max-frequency = <40000000>; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; diff --git a/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts b/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts index 52acbe111cad..a337af1de322 100644 --- a/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts +++ b/sys/gnu/dts/arm/sun8i-h3-bananapi-m2-plus.dts @@ -84,6 +84,16 @@ }; }; + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -92,6 +102,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -126,7 +140,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; @@ -145,6 +159,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -170,6 +188,11 @@ }; }; +®_usb0_vbus { + gpio = <&pio 3 11 GPIO_ACTIVE_HIGH>; /* PD11 */ + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -182,7 +205,14 @@ status = "okay"; }; -&usbphy { - /* USB VBUS is on as long as VCC-IO is on */ +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + usb0_vbus-supply = <®_usb0_vbus>; + /* USB host VBUS is on as long as VCC-IO is on */ status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-h3-nanopi-m1-plus.dts b/sys/gnu/dts/arm/sun8i-h3-nanopi-m1-plus.dts new file mode 100644 index 000000000000..8ddd1b2cc097 --- /dev/null +++ b/sys/gnu/dts/arm/sun8i-h3-nanopi-m1-plus.dts @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 Jagan Teki + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "sun8i-h3-nanopi.dtsi" + +/ { + model = "FriendlyArm NanoPi M1 Plus"; + compatible = "friendlyarm,nanopi-m1-plus", "allwinner,sun8i-h3"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts index 5b6d14555b7c..8ff71b1bb45b 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-2.dts @@ -104,6 +104,15 @@ }; }; +&codec { + allwinner,pa-gpios = <&pio 0 16 GPIO_ACTIVE_HIGH>; /* PA16 */ + allwinner,audio-routing = + "Speaker", "LINEOUT", + "MIC1", "Mic", + "Mic", "MBIAS"; + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -195,10 +204,6 @@ status = "disabled"; }; -&usb1_vbus_pin_a { - pins = "PG13"; -}; - &usbphy { usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts index f148111c326d..1a044b17d6c6 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-pc.dts @@ -97,6 +97,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -125,6 +129,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -156,6 +164,11 @@ }; }; +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -180,7 +193,14 @@ status = "disabled"; }; -&usbphy { - /* USB VBUS is always on */ +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + usb0_vbus-supply = <®_usb0_vbus>; + /* VBUS on USB host ports are always on */ status = "okay"; }; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-plus.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-plus.dts index 8c40ab7bfa72..828ae7a526d9 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-plus.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-plus.dts @@ -47,6 +47,16 @@ model = "Xunlong Orange Pi Plus / Plus 2"; compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3"; + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; + }; + reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; pinctrl-names = "default"; diff --git a/sys/gnu/dts/arm/sun8i-h3-orangepi-plus2e.dts b/sys/gnu/dts/arm/sun8i-h3-orangepi-plus2e.dts index 5851a47a3089..97920b12a944 100644 --- a/sys/gnu/dts/arm/sun8i-h3-orangepi-plus2e.dts +++ b/sys/gnu/dts/arm/sun8i-h3-orangepi-plus2e.dts @@ -50,4 +50,14 @@ / { model = "Xunlong Orange Pi Plus 2E"; compatible = "xunlong,orangepi-plus2e", "allwinner,sun8i-h3"; + + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ + }; }; diff --git a/sys/gnu/dts/arm/sun8i-v3s-licheepi-zero-dock.dts b/sys/gnu/dts/arm/sun8i-v3s-licheepi-zero-dock.dts new file mode 100644 index 000000000000..d1311098ea45 --- /dev/null +++ b/sys/gnu/dts/arm/sun8i-v3s-licheepi-zero-dock.dts @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "sun8i-v3s-licheepi-zero.dts" + +#include + +/ { + model = "Lichee Pi Zero with Dock"; + compatible = "licheepi,licheepi-zero-dock", "licheepi,licheepi-zero", + "allwinner,sun8i-v3s"; + + leds { + /* The LEDs use PG0~2 pins, which conflict with MMC1 */ + status = "disbaled"; + }; +}; + +&mmc1 { + broken-cd; + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&lradc { + vref-supply = <®_vcc3v0>; + status = "okay"; + + button@200 { + label = "Volume Up"; + linux,code = ; + channel = <0>; + voltage = <200000>; + }; + + button@400 { + label = "Volume Down"; + linux,code = ; + channel = <0>; + voltage = <400000>; + }; + + button@600 { + label = "Select"; + linux,code = ; + channel = <0>; + voltage = <600000>; + }; + + button@800 { + label = "Start"; + linux,code = ; + channel = <0>; + voltage = <800000>; + }; +}; diff --git a/sys/gnu/dts/arm/sun8i-v3s.dtsi b/sys/gnu/dts/arm/sun8i-v3s.dtsi index 71075969e5e6..3a06dc5b3746 100644 --- a/sys/gnu/dts/arm/sun8i-v3s.dtsi +++ b/sys/gnu/dts/arm/sun8i-v3s.dtsi @@ -41,6 +41,8 @@ */ #include +#include +#include / { #address-cells = <1>; @@ -55,10 +57,16 @@ compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <0>; - clocks = <&ccu 14>; + clocks = <&ccu CLK_CPU>; }; }; + de: display-engine { + compatible = "allwinner,sun8i-v3s-display-engine"; + allwinner,pipelines = <&mixer0>; + status = "disabled"; + }; + timer { compatible = "arm,armv7-timer"; interrupts = , @@ -93,18 +101,95 @@ #size-cells = <1>; ranges; + display_clocks: clock@1000000 { + compatible = "allwinner,sun8i-v3s-de2-clk"; + reg = <0x01000000 0x100000>; + clocks = <&ccu CLK_DE>, + <&ccu CLK_BUS_DE>; + clock-names = "mod", + "bus"; + resets = <&ccu RST_BUS_DE>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mixer0: mixer@1100000 { + compatible = "allwinner,sun8i-v3s-de2-mixer"; + reg = <0x01100000 0x100000>; + clocks = <&display_clocks 0>, + <&display_clocks 6>; + clock-names = "bus", + "mod"; + resets = <&display_clocks 0>; + assigned-clocks = <&display_clocks 6>; + assigned-clock-rates = <150000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mixer0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + mixer0_out_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_in_mixer0>; + }; + }; + }; + }; + + tcon0: lcd-controller@1c0c000 { + compatible = "allwinner,sun8i-v3s-tcon"; + reg = <0x01c0c000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_TCON0>, + <&ccu CLK_TCON0>; + clock-names = "ahb", + "tcon-ch0"; + clock-output-names = "tcon-pixel-clock"; + resets = <&ccu RST_BUS_TCON0>; + reset-names = "lcd"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon0_in_mixer0: endpoint@0 { + reg = <0>; + remote-endpoint = <&mixer0_out_tcon0>; + }; + }; + + tcon0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + + mmc0: mmc@01c0f000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; - clocks = <&ccu 22>, - <&ccu 45>, - <&ccu 47>, - <&ccu 46>; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 7>; + resets = <&ccu RST_BUS_MMC0>; reset-names = "ahb"; interrupts = ; status = "disabled"; @@ -115,17 +200,19 @@ mmc1: mmc@01c10000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c10000 0x1000>; - clocks = <&ccu 23>, - <&ccu 48>, - <&ccu 50>, - <&ccu 49>; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 8>; + resets = <&ccu RST_BUS_MMC1>; reset-names = "ahb"; interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -134,15 +221,15 @@ mmc2: mmc@01c11000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c11000 0x1000>; - clocks = <&ccu 24>, - <&ccu 51>, - <&ccu 53>, - <&ccu 52>; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 9>; + resets = <&ccu RST_BUS_MMC2>; reset-names = "ahb"; interrupts = ; status = "disabled"; @@ -153,8 +240,8 @@ usb_otg: usb@01c19000 { compatible = "allwinner,sun8i-h3-musb"; reg = <0x01c19000 0x0400>; - clocks = <&ccu 29>; - resets = <&ccu 17>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; interrupts = ; interrupt-names = "mc"; phys = <&usbphy 0>; @@ -169,9 +256,9 @@ <0x01c1a800 0x4>; reg-names = "phy_ctrl", "pmu0"; - clocks = <&ccu 56>; + clocks = <&ccu CLK_USB_PHY0>; clock-names = "usb0_phy"; - resets = <&ccu 0>; + resets = <&ccu RST_USB_PHY0>; reset-names = "usb0_reset"; status = "disabled"; #phy-cells = <1>; @@ -198,7 +285,7 @@ reg = <0x01c20800 0x400>; interrupts = , ; - clocks = <&ccu 37>, <&osc24M>, <&osc32k>; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; clock-names = "apb", "hosc", "losc"; gpio-controller; #gpio-cells = <3>; @@ -222,6 +309,19 @@ drive-strength = <30>; bias-pull-up; }; + + mmc1_pins: mmc1 { + pins = "PG0", "PG1", "PG2", "PG3", + "PG4", "PG5"; + function = "mmc1"; + drive-strength = <30>; + bias-pull-up; + }; + + spi0_pins: spi0 { + pins = "PC0", "PC1", "PC2", "PC3"; + function = "spi0"; + }; }; timer@01c20c00 { @@ -238,14 +338,21 @@ interrupts = ; }; + lradc: lradc@1c22800 { + compatible = "allwinner,sun4i-a10-lradc-keys"; + reg = <0x01c22800 0x400>; + interrupts = ; + status = "disabled"; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 40>; - resets = <&ccu 49>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; status = "disabled"; }; @@ -255,8 +362,8 @@ interrupts = ; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 41>; - resets = <&ccu 50>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; status = "disabled"; }; @@ -266,8 +373,8 @@ interrupts = ; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 42>; - resets = <&ccu 51>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; status = "disabled"; }; @@ -275,8 +382,8 @@ compatible = "allwinner,sun6i-a31-i2c"; reg = <0x01c2ac00 0x400>; interrupts = ; - clocks = <&ccu 38>; - resets = <&ccu 46>; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; status = "disabled"; @@ -288,8 +395,22 @@ compatible = "allwinner,sun6i-a31-i2c"; reg = <0x01c2b000 0x400>; interrupts = ; - clocks = <&ccu 39>; - resets = <&ccu 47>; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@1c68000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c68000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + resets = <&ccu RST_BUS_SPI0>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/sunxi-common-regulators.dtsi b/sys/gnu/dts/arm/sunxi-common-regulators.dtsi index ce5c53e4452f..d8e5826fb3de 100644 --- a/sys/gnu/dts/arm/sunxi-common-regulators.dtsi +++ b/sys/gnu/dts/arm/sunxi-common-regulators.dtsi @@ -44,33 +44,9 @@ #include -&pio { - ahci_pwr_pin_a: ahci_pwr_pin@0 { - pins = "PB8"; - function = "gpio_out"; - }; - - usb0_vbus_pin_a: usb0_vbus_pin@0 { - pins = "PB9"; - function = "gpio_out"; - }; - - usb1_vbus_pin_a: usb1_vbus_pin@0 { - pins = "PH6"; - function = "gpio_out"; - }; - - usb2_vbus_pin_a: usb2_vbus_pin@0 { - pins = "PH3"; - function = "gpio_out"; - }; -}; - / { reg_ahci_5v: ahci-5v { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&ahci_pwr_pin_a>; regulator-name = "ahci-5v"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -82,8 +58,6 @@ reg_usb0_vbus: usb0-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb0_vbus_pin_a>; regulator-name = "usb0-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -94,8 +68,6 @@ reg_usb1_vbus: usb1-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb1_vbus_pin_a>; regulator-name = "usb1-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -107,8 +79,6 @@ reg_usb2_vbus: usb2-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb2_vbus_pin_a>; regulator-name = "usb2-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; diff --git a/sys/gnu/dts/arm/sunxi-h3-h5.dtsi b/sys/gnu/dts/arm/sunxi-h3-h5.dtsi index d4f600dbb7eb..11240a8313c2 100644 --- a/sys/gnu/dts/arm/sunxi-h3-h5.dtsi +++ b/sys/gnu/dts/arm/sunxi-h3-h5.dtsi @@ -41,8 +41,10 @@ */ #include +#include #include #include +#include / { interrupt-parent = <&gic>; @@ -83,6 +85,12 @@ #size-cells = <1>; ranges; + syscon: syscon@1c00000 { + compatible = "allwinner,sun8i-h3-system-controller", + "syscon"; + reg = <0x01c00000 0x1000>; + }; + dma: dma-controller@01c02000 { compatible = "allwinner,sun8i-h3-dma"; reg = <0x01c02000 0x1000>; @@ -279,6 +287,14 @@ interrupt-controller; #interrupt-cells = <3>; + emac_rgmii_pins: emac0 { + pins = "PD0", "PD1", "PD2", "PD3", "PD4", + "PD5", "PD7", "PD8", "PD9", "PD10", + "PD12", "PD13", "PD15", "PD16", "PD17"; + function = "emac"; + drive-strength = <40>; + }; + i2c0_pins: i2c0 { pins = "PA11", "PA12"; function = "i2c0"; @@ -574,9 +590,9 @@ ir: ir@01f02000 { compatible = "allwinner,sun5i-a13-ir"; - clocks = <&r_ccu 4>, <&r_ccu 11>; + clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; clock-names = "apb", "ir"; - resets = <&r_ccu 0>; + resets = <&r_ccu RST_APB0_IR>; interrupts = ; reg = <0x01f02000 0x40>; status = "disabled"; @@ -586,7 +602,7 @@ compatible = "allwinner,sun8i-h3-r-pinctrl"; reg = <0x01f02c00 0x400>; interrupts = ; - clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>; + clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>; clock-names = "apb", "hosc", "losc"; gpio-controller; #gpio-cells = <3>; diff --git a/sys/gnu/dts/arm/tango4-vantage-1172.dts b/sys/gnu/dts/arm/tango4-vantage-1172.dts index 86d8df98802f..13bcc460bcb2 100644 --- a/sys/gnu/dts/arm/tango4-vantage-1172.dts +++ b/sys/gnu/dts/arm/tango4-vantage-1172.dts @@ -22,7 +22,7 @@ }; ð0 { - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; phy-handle = <ð0_phy>; #address-cells = <1>; #size-cells = <0>; diff --git a/sys/gnu/dts/arm/tegra124-apalis-eval.dts b/sys/gnu/dts/arm/tegra124-apalis-eval.dts index 5b860ad5cbee..ecffcd115fa7 100644 --- a/sys/gnu/dts/arm/tegra124-apalis-eval.dts +++ b/sys/gnu/dts/arm/tegra124-apalis-eval.dts @@ -63,7 +63,7 @@ stdout-path = "serial0:115200n8"; }; - pcie-controller@01003000 { + pcie@1003000 { pci@1,0 { status = "okay"; }; diff --git a/sys/gnu/dts/arm/tegra124-apalis.dtsi b/sys/gnu/dts/arm/tegra124-apalis.dtsi index f9e623bdd5c3..5d9b18ef5af6 100644 --- a/sys/gnu/dts/arm/tegra124-apalis.dtsi +++ b/sys/gnu/dts/arm/tegra124-apalis.dtsi @@ -54,7 +54,7 @@ reg = <0x0 0x80000000 0x0 0x80000000>; }; - pcie-controller@01003000 { + pcie@1003000 { status = "okay"; avddio-pex-supply = <&vdd_1v05>; diff --git a/sys/gnu/dts/arm/tegra124-jetson-tk1.dts b/sys/gnu/dts/arm/tegra124-jetson-tk1.dts index 53994f9fbbcc..7bacb2954f58 100644 --- a/sys/gnu/dts/arm/tegra124-jetson-tk1.dts +++ b/sys/gnu/dts/arm/tegra124-jetson-tk1.dts @@ -27,7 +27,7 @@ reg = <0x0 0x80000000 0x0 0x80000000>; }; - pcie-controller@01003000 { + pcie@1003000 { status = "okay"; avddio-pex-supply = <&vdd_1v05_run>; diff --git a/sys/gnu/dts/arm/tegra124.dtsi b/sys/gnu/dts/arm/tegra124.dtsi index 187a36c6d0fc..1b10b14a6abd 100644 --- a/sys/gnu/dts/arm/tegra124.dtsi +++ b/sys/gnu/dts/arm/tegra124.dtsi @@ -14,7 +14,7 @@ #address-cells = <2>; #size-cells = <2>; - pcie-controller@01003000 { + pcie@1003000 { compatible = "nvidia,tegra124-pcie"; device_type = "pci"; reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ @@ -54,6 +54,7 @@ device_type = "pci"; assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>; reg = <0x000800 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; @@ -67,6 +68,7 @@ device_type = "pci"; assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>; reg = <0x001000 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; diff --git a/sys/gnu/dts/arm/tegra20-harmony.dts b/sys/gnu/dts/arm/tegra20-harmony.dts index d4fb4d39ede7..41749693ec3c 100644 --- a/sys/gnu/dts/arm/tegra20-harmony.dts +++ b/sys/gnu/dts/arm/tegra20-harmony.dts @@ -566,7 +566,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller@80003000 { + pcie@80003000 { status = "okay"; avdd-pex-supply = <&pci_vdd_reg>; diff --git a/sys/gnu/dts/arm/tegra20-tamonten.dtsi b/sys/gnu/dts/arm/tegra20-tamonten.dtsi index 27d2bbbf1eae..7361f4a82e80 100644 --- a/sys/gnu/dts/arm/tegra20-tamonten.dtsi +++ b/sys/gnu/dts/arm/tegra20-tamonten.dtsi @@ -478,7 +478,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller@80003000 { + pcie@80003000 { avdd-pex-supply = <&pci_vdd_reg>; vdd-pex-supply = <&pci_vdd_reg>; avdd-pex-pll-supply = <&pci_vdd_reg>; diff --git a/sys/gnu/dts/arm/tegra20-tec.dts b/sys/gnu/dts/arm/tegra20-tec.dts index c12d8bead2ee..9cb534f4441e 100644 --- a/sys/gnu/dts/arm/tegra20-tec.dts +++ b/sys/gnu/dts/arm/tegra20-tec.dts @@ -32,7 +32,7 @@ }; }; - pcie-controller@80003000 { + pcie@80003000 { status = "okay"; pci@1,0 { diff --git a/sys/gnu/dts/arm/tegra20-trimslice.dts b/sys/gnu/dts/arm/tegra20-trimslice.dts index 87b07fbadbbe..b902ab594afa 100644 --- a/sys/gnu/dts/arm/tegra20-trimslice.dts +++ b/sys/gnu/dts/arm/tegra20-trimslice.dts @@ -321,7 +321,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller@80003000 { + pcie@80003000 { status = "okay"; avdd-pex-supply = <&pci_vdd_reg>; diff --git a/sys/gnu/dts/arm/tegra20.dtsi b/sys/gnu/dts/arm/tegra20.dtsi index e8807503f87c..7c85f97f72ea 100644 --- a/sys/gnu/dts/arm/tegra20.dtsi +++ b/sys/gnu/dts/arm/tegra20.dtsi @@ -586,7 +586,7 @@ reset-names = "fuse"; }; - pcie-controller@80003000 { + pcie@80003000 { compatible = "nvidia,tegra20-pcie"; device_type = "pci"; reg = <0x80003000 0x00000800 /* PADS registers */ @@ -625,6 +625,7 @@ device_type = "pci"; assigned-addresses = <0x82000800 0 0x80000000 0 0x1000>; reg = <0x000800 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; @@ -638,6 +639,7 @@ device_type = "pci"; assigned-addresses = <0x82001000 0 0x80001000 0 0x1000>; reg = <0x001000 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; diff --git a/sys/gnu/dts/arm/tegra30-apalis-eval.dts b/sys/gnu/dts/arm/tegra30-apalis-eval.dts index 99a69457dbf5..fc530e4a96c4 100644 --- a/sys/gnu/dts/arm/tegra30-apalis-eval.dts +++ b/sys/gnu/dts/arm/tegra30-apalis-eval.dts @@ -21,7 +21,7 @@ stdout-path = "serial0:115200n8"; }; - pcie-controller@00003000 { + pcie@3000 { status = "okay"; pci@1,0 { diff --git a/sys/gnu/dts/arm/tegra30-apalis.dtsi b/sys/gnu/dts/arm/tegra30-apalis.dtsi index f6c7c3e958ac..7a6a1a014603 100644 --- a/sys/gnu/dts/arm/tegra30-apalis.dtsi +++ b/sys/gnu/dts/arm/tegra30-apalis.dtsi @@ -9,7 +9,7 @@ model = "Toradex Apalis T30"; compatible = "toradex,apalis_t30", "nvidia,tegra30"; - pcie-controller@00003000 { + pcie@3000 { avdd-pexa-supply = <&vdd2_reg>; vdd-pexa-supply = <&vdd2_reg>; avdd-pexb-supply = <&vdd2_reg>; diff --git a/sys/gnu/dts/arm/tegra30-beaver.dts b/sys/gnu/dts/arm/tegra30-beaver.dts index 0350002849d5..4f41b18d9547 100644 --- a/sys/gnu/dts/arm/tegra30-beaver.dts +++ b/sys/gnu/dts/arm/tegra30-beaver.dts @@ -20,7 +20,7 @@ reg = <0x80000000 0x7ff00000>; }; - pcie-controller@00003000 { + pcie@3000 { status = "okay"; avdd-pexa-supply = <&ldo1_reg>; diff --git a/sys/gnu/dts/arm/tegra30-cardhu.dtsi b/sys/gnu/dts/arm/tegra30-cardhu.dtsi index f11012bb58cc..83dc14a9b353 100644 --- a/sys/gnu/dts/arm/tegra30-cardhu.dtsi +++ b/sys/gnu/dts/arm/tegra30-cardhu.dtsi @@ -43,7 +43,7 @@ reg = <0x80000000 0x40000000>; }; - pcie-controller@00003000 { + pcie@3000 { status = "okay"; /* AVDD_PEXA and VDD_PEXA inputs are grounded on Cardhu. */ diff --git a/sys/gnu/dts/arm/tegra30.dtsi b/sys/gnu/dts/arm/tegra30.dtsi index bbb1c002e7f1..13960fda7471 100644 --- a/sys/gnu/dts/arm/tegra30.dtsi +++ b/sys/gnu/dts/arm/tegra30.dtsi @@ -10,7 +10,7 @@ compatible = "nvidia,tegra30"; interrupt-parent = <&lic>; - pcie-controller@00003000 { + pcie@3000 { compatible = "nvidia,tegra30-pcie"; device_type = "pci"; reg = <0x00003000 0x00000800 /* PADS registers */ @@ -51,6 +51,7 @@ device_type = "pci"; assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>; reg = <0x000800 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; @@ -64,6 +65,7 @@ device_type = "pci"; assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>; reg = <0x001000 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; @@ -77,6 +79,7 @@ device_type = "pci"; assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>; reg = <0x001800 0 0 0 0>; + bus-range = <0x00 0xff>; status = "disabled"; #address-cells = <3>; diff --git a/sys/gnu/dts/arm/tny_a9260_common.dtsi b/sys/gnu/dts/arm/tny_a9260_common.dtsi index f9dc463b9e48..5d83df4675a1 100644 --- a/sys/gnu/dts/arm/tny_a9260_common.dtsi +++ b/sys/gnu/dts/arm/tny_a9260_common.dtsi @@ -32,50 +32,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/tny_a9263.dts b/sys/gnu/dts/arm/tny_a9263.dts index 9161cd9889b4..8cf0a9e08571 100644 --- a/sys/gnu/dts/arm/tny_a9263.dts +++ b/sys/gnu/dts/arm/tny_a9263.dts @@ -42,50 +42,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi0: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; }; diff --git a/sys/gnu/dts/arm/twl4030.dtsi b/sys/gnu/dts/arm/twl4030.dtsi index 36ae9160b558..16533b62b0a2 100644 --- a/sys/gnu/dts/arm/twl4030.dtsi +++ b/sys/gnu/dts/arm/twl4030.dtsi @@ -23,6 +23,8 @@ compatible = "ti,twl4030-bci"; interrupts = <9>, <2>; bci3v1-supply = <&vusb3v1>; + io-channels = <&twl_madc 11>; + io-channel-names = "vac"; }; watchdog { diff --git a/sys/gnu/dts/arm/uniphier-ld4-ref.dts b/sys/gnu/dts/arm/uniphier-ld4-ref.dts index e0da4ee21c21..4817ebb28eb2 100644 --- a/sys/gnu/dts/arm/uniphier-ld4-ref.dts +++ b/sys/gnu/dts/arm/uniphier-ld4-ref.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-ld4.dtsi b/sys/gnu/dts/arm/uniphier-ld4.dtsi index 4f5fe15eaee2..fb2fd9605b9d 100644 --- a/sys/gnu/dts/arm/uniphier-ld4.dtsi +++ b/sys/gnu/dts/arm/uniphier-ld4.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -201,7 +165,7 @@ pinctrl-0 = <&pinctrl_system_bus>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-ld6b-ref.dts b/sys/gnu/dts/arm/uniphier-ld6b-ref.dts index a397a8811c78..96db4abc02c3 100644 --- a/sys/gnu/dts/arm/uniphier-ld6b-ref.dts +++ b/sys/gnu/dts/arm/uniphier-ld6b-ref.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-ld6b.dtsi b/sys/gnu/dts/arm/uniphier-ld6b.dtsi index 905c77d499eb..8b9a79731bd3 100644 --- a/sys/gnu/dts/arm/uniphier-ld6b.dtsi +++ b/sys/gnu/dts/arm/uniphier-ld6b.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /* diff --git a/sys/gnu/dts/arm/uniphier-pro4-ace.dts b/sys/gnu/dts/arm/uniphier-pro4-ace.dts index fefc89149234..11690b57931c 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-ace.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-ace.dts @@ -4,43 +4,7 @@ * Copyright (C) 2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; @@ -88,7 +52,7 @@ status = "okay"; eeprom@54 { - compatible = "st,24c64"; + compatible = "st,24c64", "atmel,24c64"; reg = <0x54>; pagesize = <32>; }; diff --git a/sys/gnu/dts/arm/uniphier-pro4-ref.dts b/sys/gnu/dts/arm/uniphier-pro4-ref.dts index 6077e634d14a..4cf539245f2e 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-ref.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-ref.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-pro4-sanji.dts b/sys/gnu/dts/arm/uniphier-pro4-sanji.dts index 6c63c8bad825..2763cebcd76a 100644 --- a/sys/gnu/dts/arm/uniphier-pro4-sanji.dts +++ b/sys/gnu/dts/arm/uniphier-pro4-sanji.dts @@ -4,43 +4,7 @@ * Copyright (C) 2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; @@ -83,7 +47,7 @@ status = "okay"; eeprom@54 { - compatible = "st,24c64"; + compatible = "st,24c64", "atmel,24c64"; reg = <0x54>; pagesize = <32>; }; diff --git a/sys/gnu/dts/arm/uniphier-pro4.dtsi b/sys/gnu/dts/arm/uniphier-pro4.dtsi index 794a85a7068b..37400becf4ba 100644 --- a/sys/gnu/dts/arm/uniphier-pro4.dtsi +++ b/sys/gnu/dts/arm/uniphier-pro4.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -233,7 +197,7 @@ pinctrl-0 = <&pinctrl_system_bus>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-pro5.dtsi b/sys/gnu/dts/arm/uniphier-pro5.dtsi index df07b555cbed..9577769a0add 100644 --- a/sys/gnu/dts/arm/uniphier-pro5.dtsi +++ b/sys/gnu/dts/arm/uniphier-pro5.dtsi @@ -77,67 +77,67 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; clock-latency-ns = <300>; }; - opp@116667000 { + opp-116667000 { opp-hz = /bits/ 64 <116667000>; clock-latency-ns = <300>; }; - opp@150000000 { + opp-150000000 { opp-hz = /bits/ 64 <150000000>; clock-latency-ns = <300>; }; - opp@175000000 { + opp-175000000 { opp-hz = /bits/ 64 <175000000>; clock-latency-ns = <300>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; clock-latency-ns = <300>; }; - opp@233334000 { + opp-233334000 { opp-hz = /bits/ 64 <233334000>; clock-latency-ns = <300>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; clock-latency-ns = <300>; }; - opp@350000000 { + opp-350000000 { opp-hz = /bits/ 64 <350000000>; clock-latency-ns = <300>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; clock-latency-ns = <300>; }; - opp@466667000 { + opp-466667000 { opp-hz = /bits/ 64 <466667000>; clock-latency-ns = <300>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; clock-latency-ns = <300>; }; - opp@700000000 { + opp-700000000 { opp-hz = /bits/ 64 <700000000>; clock-latency-ns = <300>; }; - opp@800000000 { + opp-800000000 { opp-hz = /bits/ 64 <800000000>; clock-latency-ns = <300>; }; - opp@933334000 { + opp-933334000 { opp-hz = /bits/ 64 <933334000>; clock-latency-ns = <300>; }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; clock-latency-ns = <300>; }; - opp@1400000000 { + opp-1400000000 { opp-hz = /bits/ 64 <1400000000>; clock-latency-ns = <300>; }; @@ -320,7 +320,7 @@ pinctrl-0 = <&pinctrl_system_bus>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts b/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts index cccc86658d20..81560f75bfa7 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts +++ b/sys/gnu/dts/arm/uniphier-pxs2-gentil.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; @@ -80,7 +44,7 @@ status = "okay"; eeprom@54 { - compatible = "st,24c64"; + compatible = "st,24c64", "atmel,24c64"; reg = <0x54>; pagesize = <32>; }; diff --git a/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts b/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts index 803a39aa39d0..dc2d0579c666 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts +++ b/sys/gnu/dts/arm/uniphier-pxs2-vodka.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-pxs2.dtsi b/sys/gnu/dts/arm/uniphier-pxs2.dtsi index 58c3e2f35706..bace751d4023 100644 --- a/sys/gnu/dts/arm/uniphier-pxs2.dtsi +++ b/sys/gnu/dts/arm/uniphier-pxs2.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -97,35 +61,35 @@ compatible = "operating-points-v2"; opp-shared; - opp@100000000 { + opp-100000000 { opp-hz = /bits/ 64 <100000000>; clock-latency-ns = <300>; }; - opp@150000000 { + opp-150000000 { opp-hz = /bits/ 64 <150000000>; clock-latency-ns = <300>; }; - opp@200000000 { + opp-200000000 { opp-hz = /bits/ 64 <200000000>; clock-latency-ns = <300>; }; - opp@300000000 { + opp-300000000 { opp-hz = /bits/ 64 <300000000>; clock-latency-ns = <300>; }; - opp@400000000 { + opp-400000000 { opp-hz = /bits/ 64 <400000000>; clock-latency-ns = <300>; }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; clock-latency-ns = <300>; }; - opp@800000000 { + opp-800000000 { opp-hz = /bits/ 64 <800000000>; clock-latency-ns = <300>; }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; clock-latency-ns = <300>; }; @@ -304,7 +268,7 @@ pinctrl-0 = <&pinctrl_system_bus>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi b/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi index c62ae1a81f47..7a1c29b558d5 100644 --- a/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi +++ b/sys/gnu/dts/arm/uniphier-ref-daughter.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2017 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ &i2c0 { diff --git a/sys/gnu/dts/arm/uniphier-sld3-ref.dts b/sys/gnu/dts/arm/uniphier-sld3-ref.dts index eb63dcca92b5..70cda39a3dd2 100644 --- a/sys/gnu/dts/arm/uniphier-sld3-ref.dts +++ b/sys/gnu/dts/arm/uniphier-sld3-ref.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-sld3.dtsi b/sys/gnu/dts/arm/uniphier-sld3.dtsi index 01d77edac01f..408287936613 100644 --- a/sys/gnu/dts/arm/uniphier-sld3.dtsi +++ b/sys/gnu/dts/arm/uniphier-sld3.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -216,7 +180,7 @@ #size-cells = <1>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-sld8-ref.dts b/sys/gnu/dts/arm/uniphier-sld8-ref.dts index 737d276349fd..4536d5b71297 100644 --- a/sys/gnu/dts/arm/uniphier-sld8-ref.dts +++ b/sys/gnu/dts/arm/uniphier-sld8-ref.dts @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; diff --git a/sys/gnu/dts/arm/uniphier-sld8.dtsi b/sys/gnu/dts/arm/uniphier-sld8.dtsi index eb06fdc04b02..9fb9167f2db4 100644 --- a/sys/gnu/dts/arm/uniphier-sld8.dtsi +++ b/sys/gnu/dts/arm/uniphier-sld8.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -201,7 +165,7 @@ pinctrl-0 = <&pinctrl_system_bus>; }; - smpctrl@59800000 { + smpctrl@59801000 { compatible = "socionext,uniphier-smpctrl"; reg = <0x59801000 0x400>; }; diff --git a/sys/gnu/dts/arm/uniphier-support-card.dtsi b/sys/gnu/dts/arm/uniphier-support-card.dtsi index f61dfec2807f..6c825f192e65 100644 --- a/sys/gnu/dts/arm/uniphier-support-card.dtsi +++ b/sys/gnu/dts/arm/uniphier-support-card.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2017 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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 file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ &system_bus { @@ -53,14 +17,14 @@ #size-cells = <1>; ranges = <0x00000000 1 0x01f00000 0x00100000>; - ethsc: ethernet@00000000 { + ethsc: ethernet@0 { compatible = "smsc,lan9118", "smsc,lan9115"; reg = <0x00000000 0x1000>; phy-mode = "mii"; reg-io-width = <4>; }; - serialsc: uart@000b0000 { + serialsc: uart@b0000 { compatible = "ns16550a"; reg = <0x000b0000 0x20>; clock-frequency = <12288000>; diff --git a/sys/gnu/dts/arm/usb_a9260_common.dtsi b/sys/gnu/dts/arm/usb_a9260_common.dtsi index 7514b347cdd2..34a49995eda3 100644 --- a/sys/gnu/dts/arm/usb_a9260_common.dtsi +++ b/sys/gnu/dts/arm/usb_a9260_common.dtsi @@ -34,50 +34,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/usb_a9263.dts b/sys/gnu/dts/arm/usb_a9263.dts index bfc48a272417..482381c1c962 100644 --- a/sys/gnu/dts/arm/usb_a9263.dts +++ b/sys/gnu/dts/arm/usb_a9263.dts @@ -62,50 +62,69 @@ }; }; - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; + ebi0: ebi@10000000 { status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; + nand_controller: nand-controller { + status = "okay"; + pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>; + pinctrl-names = "default"; - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; + nand@3 { + reg = <0x3 0x0 0x800000>; + rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>; + cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>; + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + label = "atmel_nand"; - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x20000>; - }; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - bareboxenv2@80000 { - label = "bareboxenv2"; - reg = <0x80000 0x20000>; - }; + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; - oftree@80000 { - label = "oftree"; - reg = <0xa0000 0x20000>; - }; + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; - kernel@a0000 { - label = "kernel"; - reg = <0xc0000 0x400000>; - }; + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; - rootfs@4a0000 { - label = "rootfs"; - reg = <0x4c0000 0x7800000>; - }; + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; - data@7ca0000 { - label = "data"; - reg = <0x7cc0000 0x8340000>; + oftree@80000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; }; }; diff --git a/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts b/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts index 37f95427616f..acdf12ad0622 100644 --- a/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts +++ b/sys/gnu/dts/arm/vf610-zii-dev-rev-b.dts @@ -78,6 +78,7 @@ interrupts = <27 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <2>; + eeprom-length = <512>; ports { #address-cells = <1>; @@ -163,6 +164,7 @@ interrupts = <26 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <2>; + eeprom-length = <512>; ports { #address-cells = <1>; diff --git a/sys/gnu/dts/include/dt-bindings/clock/bcm-sr.h b/sys/gnu/dts/include/dt-bindings/clock/bcm-sr.h new file mode 100644 index 000000000000..cff6c6fe2947 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/bcm-sr.h @@ -0,0 +1,101 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Broadcom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +#ifndef _CLOCK_BCM_SR_H +#define _CLOCK_BCM_SR_H + +/* GENPLL 0 clock channel ID SCR HSLS FS PCIE */ +#define BCM_SR_GENPLL0 0 +#define BCM_SR_GENPLL0_SATA_CLK 1 +#define BCM_SR_GENPLL0_SCR_CLK 2 +#define BCM_SR_GENPLL0_250M_CLK 3 +#define BCM_SR_GENPLL0_PCIE_AXI_CLK 4 +#define BCM_SR_GENPLL0_PAXC_AXI_X2_CLK 5 +#define BCM_SR_GENPLL0_PAXC_AXI_CLK 6 + +/* GENPLL 1 clock channel ID MHB PCIE NITRO */ +#define BCM_SR_GENPLL1 0 +#define BCM_SR_GENPLL1_PCIE_TL_CLK 1 +#define BCM_SR_GENPLL1_MHB_APB_CLK 2 + +/* GENPLL 2 clock channel ID NITRO MHB*/ +#define BCM_SR_GENPLL2 0 +#define BCM_SR_GENPLL2_NIC_CLK 1 +#define BCM_SR_GENPLL2_250_NITRO_CLK 2 +#define BCM_SR_GENPLL2_125_NITRO_CLK 3 +#define BCM_SR_GENPLL2_CHIMP_CLK 4 + +/* GENPLL 3 HSLS clock channel ID */ +#define BCM_SR_GENPLL3 0 +#define BCM_SR_GENPLL3_HSLS_CLK 1 +#define BCM_SR_GENPLL3_SDIO_CLK 2 + +/* GENPLL 4 SCR clock channel ID */ +#define BCM_SR_GENPLL4 0 +#define BCM_SR_GENPLL4_CCN_CLK 1 + +/* GENPLL 5 FS4 clock channel ID */ +#define BCM_SR_GENPLL5 0 +#define BCM_SR_GENPLL5_FS_CLK 1 +#define BCM_SR_GENPLL5_SPU_CLK 2 + +/* GENPLL 6 NITRO clock channel ID */ +#define BCM_SR_GENPLL6 0 +#define BCM_SR_GENPLL6_48_USB_CLK 1 + +/* LCPLL0 clock channel ID */ +#define BCM_SR_LCPLL0 0 +#define BCM_SR_LCPLL0_SATA_REF_CLK 1 +#define BCM_SR_LCPLL0_USB_REF_CLK 2 +#define BCM_SR_LCPLL0_SATA_REFPN_CLK 3 + +/* LCPLL1 clock channel ID */ +#define BCM_SR_LCPLL1 0 +#define BCM_SR_LCPLL1_WAN_CLK 1 + +/* LCPLL PCIE clock channel ID */ +#define BCM_SR_LCPLL_PCIE 0 +#define BCM_SR_LCPLL_PCIE_PHY_REF_CLK 1 + +/* GENPLL EMEM0 clock channel ID */ +#define BCM_SR_EMEMPLL0 0 +#define BCM_SR_EMEMPLL0_EMEM_CLK 1 + +/* GENPLL EMEM0 clock channel ID */ +#define BCM_SR_EMEMPLL1 0 +#define BCM_SR_EMEMPLL1_EMEM_CLK 1 + +/* GENPLL EMEM0 clock channel ID */ +#define BCM_SR_EMEMPLL2 0 +#define BCM_SR_EMEMPLL2_EMEM_CLK 1 + +#endif /* _CLOCK_BCM_SR_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/boston-clock.h b/sys/gnu/dts/include/dt-bindings/clock/boston-clock.h new file mode 100644 index 000000000000..a6f009821137 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/boston-clock.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ +#define __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ + +#define BOSTON_CLK_INPUT 0 +#define BOSTON_CLK_SYS 1 +#define BOSTON_CLK_CPU 2 + +#endif /* __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/cortina,gemini-clock.h b/sys/gnu/dts/include/dt-bindings/clock/cortina,gemini-clock.h new file mode 100644 index 000000000000..acf5cd550b0c --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/cortina,gemini-clock.h @@ -0,0 +1,29 @@ +#ifndef DT_BINDINGS_CORTINA_GEMINI_CLOCK_H +#define DT_BINDINGS_CORTINA_GEMINI_CLOCK_H + +/* RTC, AHB, APB, CPU, PCI, TVC, UART clocks and 13 gates */ +#define GEMINI_NUM_CLKS 20 + +#define GEMINI_CLK_RTC 0 +#define GEMINI_CLK_AHB 1 +#define GEMINI_CLK_APB 2 +#define GEMINI_CLK_CPU 3 +#define GEMINI_CLK_PCI 4 +#define GEMINI_CLK_TVC 5 +#define GEMINI_CLK_UART 6 +#define GEMINI_CLK_GATES 7 +#define GEMINI_CLK_GATE_SECURITY 7 +#define GEMINI_CLK_GATE_GMAC0 8 +#define GEMINI_CLK_GATE_GMAC1 9 +#define GEMINI_CLK_GATE_SATA0 10 +#define GEMINI_CLK_GATE_SATA1 11 +#define GEMINI_CLK_GATE_USB0 12 +#define GEMINI_CLK_GATE_USB1 13 +#define GEMINI_CLK_GATE_IDE 14 +#define GEMINI_CLK_GATE_PCI 15 +#define GEMINI_CLK_GATE_DDR 16 +#define GEMINI_CLK_GATE_FLASH 17 +#define GEMINI_CLK_GATE_TVC 18 +#define GEMINI_CLK_GATE_BOOT 19 + +#endif /* DT_BINDINGS_CORTINA_GEMINI_CLOCK_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/exynos5420.h b/sys/gnu/dts/include/dt-bindings/clock/exynos5420.h index 6fd21c291416..2740ae0424a9 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/exynos5420.h +++ b/sys/gnu/dts/include/dt-bindings/clock/exynos5420.h @@ -217,6 +217,9 @@ #define CLK_MOUT_MCLK_CDREX 654 #define CLK_MOUT_BPLL 655 #define CLK_MOUT_MX_MSPLL_CCORE 656 +#define CLK_MOUT_EPLL 657 +#define CLK_MOUT_MAU_EPLL 658 +#define CLK_MOUT_USER_MAU_EPLL 659 /* divider clocks */ #define CLK_DOUT_PIXEL 768 diff --git a/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h b/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h index 3190e30b9398..e3e9f7919c31 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h +++ b/sys/gnu/dts/include/dt-bindings/clock/gxbb-clkc.h @@ -5,7 +5,6 @@ #ifndef __GXBB_CLKC_H #define __GXBB_CLKC_H -#define CLKID_CPUCLK 1 #define CLKID_HDMI_PLL 2 #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 @@ -13,24 +12,30 @@ #define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 #define CLKID_MPLL2 15 +#define CLKID_SPICC 21 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 #define CLKID_RNG0 25 +#define CLKID_UART0 26 #define CLKID_SPI 34 #define CLKID_ETH 36 #define CLKID_AIU_GLUE 38 +#define CLKID_IEC958 39 #define CLKID_I2S_OUT 40 #define CLKID_MIXER_IFACE 44 #define CLKID_AIU 47 +#define CLKID_UART1 48 #define CLKID_USB0 50 #define CLKID_USB1 51 #define CLKID_USB 55 #define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_UART2 68 #define CLKID_SANA 69 #define CLKID_GCLK_VENCI_INT0 77 #define CLKID_AOCLK_GATE 80 +#define CLKID_IEC958_GATE 81 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 @@ -42,5 +47,8 @@ #define CLKID_MALI_1_SEL 103 #define CLKID_MALI_1 105 #define CLKID_MALI 106 +#define CLKID_CTS_AMCLK 107 +#define CLKID_CTS_MCLK_I958 110 +#define CLKID_CTS_I958 113 #endif /* __GXBB_CLKC_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/hi3660-clock.h b/sys/gnu/dts/include/dt-bindings/clock/hi3660-clock.h index 1c00b7fe296f..adb768d447a5 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/hi3660-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/hi3660-clock.h @@ -154,6 +154,23 @@ #define HI3660_CLK_DIV_UFSPERI 137 #define HI3660_CLK_DIV_AOMM 138 #define HI3660_CLK_DIV_IOPERI 139 +#define HI3660_VENC_VOLT_HOLD 140 +#define HI3660_PERI_VOLT_HOLD 141 +#define HI3660_CLK_GATE_VENC 142 +#define HI3660_CLK_GATE_VDEC 143 +#define HI3660_CLK_ANDGT_VENC 144 +#define HI3660_CLK_ANDGT_VDEC 145 +#define HI3660_CLK_MUX_VENC 146 +#define HI3660_CLK_MUX_VDEC 147 +#define HI3660_CLK_DIV_VENC 148 +#define HI3660_CLK_DIV_VDEC 149 +#define HI3660_CLK_FAC_ISP_SNCLK 150 +#define HI3660_CLK_GATE_ISP_SNCLK0 151 +#define HI3660_CLK_GATE_ISP_SNCLK1 152 +#define HI3660_CLK_GATE_ISP_SNCLK2 153 +#define HI3660_CLK_ANGT_ISP_SNCLK 154 +#define HI3660_CLK_MUX_ISP_SNCLK 155 +#define HI3660_CLK_DIV_ISP_SNCLK 156 /* clk in pmuctrl */ #define HI3660_GATE_ABB_192 0 diff --git a/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h b/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h index b8ba665aab7b..409cc02cd844 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/hi6220-clock.h @@ -174,4 +174,8 @@ #define HI6220_DDRC_AXI1 7 #define HI6220_POWER_NR_CLKS 8 + +/* clk in Hi6220 acpu sctrl */ +#define HI6220_ACPU_SFT_AT_S 0 + #endif diff --git a/sys/gnu/dts/include/dt-bindings/clock/histb-clock.h b/sys/gnu/dts/include/dt-bindings/clock/histb-clock.h index 181c0f070f7c..067f5e501b0c 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/histb-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/histb-clock.h @@ -53,7 +53,14 @@ #define HISTB_ETH1_MAC_CLK 31 #define HISTB_ETH1_MACIF_CLK 32 #define HISTB_COMBPHY1_CLK 33 - +#define HISTB_USB2_BUS_CLK 34 +#define HISTB_USB2_PHY_CLK 35 +#define HISTB_USB2_UTMI_CLK 36 +#define HISTB_USB2_12M_CLK 37 +#define HISTB_USB2_48M_CLK 38 +#define HISTB_USB2_OTG_UTMI_CLK 39 +#define HISTB_USB2_PHY1_REF_CLK 40 +#define HISTB_USB2_PHY2_REF_CLK 41 /* clocks provided by mcu CRG */ #define HISTB_MCE_CLK 1 diff --git a/sys/gnu/dts/include/dt-bindings/clock/imx7d-clock.h b/sys/gnu/dts/include/dt-bindings/clock/imx7d-clock.h index a7a1a50f33ef..de62a83b6c80 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/imx7d-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/imx7d-clock.h @@ -450,5 +450,7 @@ #define IMX7D_CLK_ARM 437 #define IMX7D_CKIL 438 #define IMX7D_OCOTP_CLK 439 -#define IMX7D_CLK_END 440 +#define IMX7D_NAND_RAWNAND_CLK 440 +#define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441 +#define IMX7D_CLK_END 442 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/meson8b-clkc.h b/sys/gnu/dts/include/dt-bindings/clock/meson8b-clkc.h index a55ff8c9b30f..e29227fb52a1 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/meson8b-clkc.h +++ b/sys/gnu/dts/include/dt-bindings/clock/meson8b-clkc.h @@ -21,5 +21,15 @@ #define CLKID_ZERO 13 #define CLKID_MPEG_SEL 14 #define CLKID_MPEG_DIV 15 +#define CLKID_SAR_ADC 23 +#define CLKID_RNG0 25 +#define CLKID_SDIO 30 +#define CLKID_ETH 36 +#define CLKID_USB0 50 +#define CLKID_USB1 51 +#define CLKID_USB 55 +#define CLKID_USB1_DDR_BRIDGE 64 +#define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_SANA 69 #endif /* __MESON8B_CLKC_H */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/mt2701-clk.h b/sys/gnu/dts/include/dt-bindings/clock/mt2701-clk.h index 2062c67e2e51..551f7600ab58 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/mt2701-clk.h +++ b/sys/gnu/dts/include/dt-bindings/clock/mt2701-clk.h @@ -221,7 +221,8 @@ #define CLK_INFRA_PMICWRAP 17 #define CLK_INFRA_DDCCI 18 #define CLK_INFRA_CLK_13M 19 -#define CLK_INFRA_NR 20 +#define CLK_INFRA_CPUSEL 20 +#define CLK_INFRA_NR 21 /* PERICFG */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/mt8173-clk.h b/sys/gnu/dts/include/dt-bindings/clock/mt8173-clk.h index 6094bf7e50ab..8aea623dd518 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/mt8173-clk.h +++ b/sys/gnu/dts/include/dt-bindings/clock/mt8173-clk.h @@ -193,7 +193,9 @@ #define CLK_INFRA_PMICSPI 10 #define CLK_INFRA_PMICWRAP 11 #define CLK_INFRA_CLK_13M 12 -#define CLK_INFRA_NR_CLK 13 +#define CLK_INFRA_CA53SEL 13 +#define CLK_INFRA_CA57SEL 14 +#define CLK_INFRA_NR_CLK 15 /* PERI_SYS */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/omap4.h b/sys/gnu/dts/include/dt-bindings/clock/omap4.h new file mode 100644 index 000000000000..e86c758e50ce --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/omap4.h @@ -0,0 +1,146 @@ +/* + * Copyright 2017 Texas Instruments, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program 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. + */ +#ifndef __DT_BINDINGS_CLK_OMAP4_H +#define __DT_BINDINGS_CLK_OMAP4_H + +#define OMAP4_CLKCTRL_OFFSET 0x20 +#define OMAP4_CLKCTRL_INDEX(offset) ((offset) - OMAP4_CLKCTRL_OFFSET) + +/* mpuss clocks */ +#define OMAP4_MPU_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* tesla clocks */ +#define OMAP4_DSP_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* abe clocks */ +#define OMAP4_L4_ABE_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_AESS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_MCPDM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_DMIC_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) +#define OMAP4_MCASP_CLKCTRL OMAP4_CLKCTRL_INDEX(0x40) +#define OMAP4_MCBSP1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x48) +#define OMAP4_MCBSP2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x50) +#define OMAP4_MCBSP3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x58) +#define OMAP4_SLIMBUS1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x60) +#define OMAP4_TIMER5_CLKCTRL OMAP4_CLKCTRL_INDEX(0x68) +#define OMAP4_TIMER6_CLKCTRL OMAP4_CLKCTRL_INDEX(0x70) +#define OMAP4_TIMER7_CLKCTRL OMAP4_CLKCTRL_INDEX(0x78) +#define OMAP4_TIMER8_CLKCTRL OMAP4_CLKCTRL_INDEX(0x80) +#define OMAP4_WD_TIMER3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x88) + +/* l4_ao clocks */ +#define OMAP4_SMARTREFLEX_MPU_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_SMARTREFLEX_IVA_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_SMARTREFLEX_CORE_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) + +/* l3_1 clocks */ +#define OMAP4_L3_MAIN_1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l3_2 clocks */ +#define OMAP4_L3_MAIN_2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_GPMC_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_OCMC_RAM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) + +/* ducati clocks */ +#define OMAP4_IPU_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l3_dma clocks */ +#define OMAP4_DMA_SYSTEM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l3_emif clocks */ +#define OMAP4_DMM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_EMIF1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_EMIF2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) + +/* d2d clocks */ +#define OMAP4_C2C_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l4_cfg clocks */ +#define OMAP4_L4_CFG_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_SPINLOCK_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_MAILBOX_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) + +/* l3_instr clocks */ +#define OMAP4_L3_MAIN_3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_L3_INSTR_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_OCP_WP_NOC_CLKCTRL OMAP4_CLKCTRL_INDEX(0x40) + +/* ivahd clocks */ +#define OMAP4_IVA_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_SL2IF_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) + +/* iss clocks */ +#define OMAP4_ISS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_FDIF_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) + +/* l3_dss clocks */ +#define OMAP4_DSS_CORE_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l3_gfx clocks */ +#define OMAP4_GPU_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +/* l3_init clocks */ +#define OMAP4_MMC1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_MMC2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_HSI_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) +#define OMAP4_USB_HOST_HS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x58) +#define OMAP4_USB_OTG_HS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x60) +#define OMAP4_USB_TLL_HS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x68) +#define OMAP4_USB_HOST_FS_CLKCTRL OMAP4_CLKCTRL_INDEX(0xd0) +#define OMAP4_OCP2SCP_USB_PHY_CLKCTRL OMAP4_CLKCTRL_INDEX(0xe0) + +/* l4_per clocks */ +#define OMAP4_TIMER10_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28) +#define OMAP4_TIMER11_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_TIMER2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) +#define OMAP4_TIMER3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x40) +#define OMAP4_TIMER4_CLKCTRL OMAP4_CLKCTRL_INDEX(0x48) +#define OMAP4_TIMER9_CLKCTRL OMAP4_CLKCTRL_INDEX(0x50) +#define OMAP4_ELM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x58) +#define OMAP4_GPIO2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x60) +#define OMAP4_GPIO3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x68) +#define OMAP4_GPIO4_CLKCTRL OMAP4_CLKCTRL_INDEX(0x70) +#define OMAP4_GPIO5_CLKCTRL OMAP4_CLKCTRL_INDEX(0x78) +#define OMAP4_GPIO6_CLKCTRL OMAP4_CLKCTRL_INDEX(0x80) +#define OMAP4_HDQ1W_CLKCTRL OMAP4_CLKCTRL_INDEX(0x88) +#define OMAP4_I2C1_CLKCTRL OMAP4_CLKCTRL_INDEX(0xa0) +#define OMAP4_I2C2_CLKCTRL OMAP4_CLKCTRL_INDEX(0xa8) +#define OMAP4_I2C3_CLKCTRL OMAP4_CLKCTRL_INDEX(0xb0) +#define OMAP4_I2C4_CLKCTRL OMAP4_CLKCTRL_INDEX(0xb8) +#define OMAP4_L4_PER_CLKCTRL OMAP4_CLKCTRL_INDEX(0xc0) +#define OMAP4_MCBSP4_CLKCTRL OMAP4_CLKCTRL_INDEX(0xe0) +#define OMAP4_MCSPI1_CLKCTRL OMAP4_CLKCTRL_INDEX(0xf0) +#define OMAP4_MCSPI2_CLKCTRL OMAP4_CLKCTRL_INDEX(0xf8) +#define OMAP4_MCSPI3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x100) +#define OMAP4_MCSPI4_CLKCTRL OMAP4_CLKCTRL_INDEX(0x108) +#define OMAP4_MMC3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x120) +#define OMAP4_MMC4_CLKCTRL OMAP4_CLKCTRL_INDEX(0x128) +#define OMAP4_SLIMBUS2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x138) +#define OMAP4_UART1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x140) +#define OMAP4_UART2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x148) +#define OMAP4_UART3_CLKCTRL OMAP4_CLKCTRL_INDEX(0x150) +#define OMAP4_UART4_CLKCTRL OMAP4_CLKCTRL_INDEX(0x158) +#define OMAP4_MMC5_CLKCTRL OMAP4_CLKCTRL_INDEX(0x160) + +/* l4_wkup clocks */ +#define OMAP4_L4_WKUP_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) +#define OMAP4_WD_TIMER2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30) +#define OMAP4_GPIO1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38) +#define OMAP4_TIMER1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x40) +#define OMAP4_COUNTER_32K_CLKCTRL OMAP4_CLKCTRL_INDEX(0x50) +#define OMAP4_KBD_CLKCTRL OMAP4_CLKCTRL_INDEX(0x78) + +/* emu_sys clocks */ +#define OMAP4_DEBUGSS_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20) + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/sys/gnu/dts/include/dt-bindings/clock/qcom,gcc-ipq8074.h new file mode 100644 index 000000000000..370c83c3bccc --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/qcom,gcc-ipq8074.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program 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. + */ + +#ifndef _DT_BINDINGS_CLOCK_IPQ_GCC_8074_H +#define _DT_BINDINGS_CLOCK_IPQ_GCC_8074_H + +#define GPLL0 0 +#define GPLL0_MAIN 1 +#define GCC_SLEEP_CLK_SRC 2 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 3 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 4 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 5 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 6 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 7 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 8 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 9 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 10 +#define BLSP1_QUP5_I2C_APPS_CLK_SRC 11 +#define BLSP1_QUP5_SPI_APPS_CLK_SRC 12 +#define BLSP1_QUP6_I2C_APPS_CLK_SRC 13 +#define BLSP1_QUP6_SPI_APPS_CLK_SRC 14 +#define BLSP1_UART1_APPS_CLK_SRC 15 +#define BLSP1_UART2_APPS_CLK_SRC 16 +#define BLSP1_UART3_APPS_CLK_SRC 17 +#define BLSP1_UART4_APPS_CLK_SRC 18 +#define BLSP1_UART5_APPS_CLK_SRC 19 +#define BLSP1_UART6_APPS_CLK_SRC 20 +#define GCC_BLSP1_AHB_CLK 21 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 22 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 23 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 24 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 25 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 26 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 27 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 28 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 29 +#define GCC_BLSP1_QUP5_I2C_APPS_CLK 30 +#define GCC_BLSP1_QUP5_SPI_APPS_CLK 31 +#define GCC_BLSP1_QUP6_I2C_APPS_CLK 32 +#define GCC_BLSP1_QUP6_SPI_APPS_CLK 33 +#define GCC_BLSP1_UART1_APPS_CLK 34 +#define GCC_BLSP1_UART2_APPS_CLK 35 +#define GCC_BLSP1_UART3_APPS_CLK 36 +#define GCC_BLSP1_UART4_APPS_CLK 37 +#define GCC_BLSP1_UART5_APPS_CLK 38 +#define GCC_BLSP1_UART6_APPS_CLK 39 +#define GCC_PRNG_AHB_CLK 40 +#define GCC_QPIC_AHB_CLK 41 +#define GCC_QPIC_CLK 42 +#define PCNOC_BFDCD_CLK_SRC 43 + +#define GCC_BLSP1_BCR 0 +#define GCC_BLSP1_QUP1_BCR 1 +#define GCC_BLSP1_UART1_BCR 2 +#define GCC_BLSP1_QUP2_BCR 3 +#define GCC_BLSP1_UART2_BCR 4 +#define GCC_BLSP1_QUP3_BCR 5 +#define GCC_BLSP1_UART3_BCR 6 +#define GCC_BLSP1_QUP4_BCR 7 +#define GCC_BLSP1_UART4_BCR 8 +#define GCC_BLSP1_QUP5_BCR 9 +#define GCC_BLSP1_UART5_BCR 10 +#define GCC_BLSP1_QUP6_BCR 11 +#define GCC_BLSP1_UART6_BCR 12 +#define GCC_IMEM_BCR 13 +#define GCC_SMMU_BCR 14 +#define GCC_APSS_TCU_BCR 15 +#define GCC_SMMU_XPU_BCR 16 +#define GCC_PCNOC_TBU_BCR 17 +#define GCC_SMMU_CFG_BCR 18 +#define GCC_PRNG_BCR 19 +#define GCC_BOOT_ROM_BCR 20 +#define GCC_CRYPTO_BCR 21 +#define GCC_WCSS_BCR 22 +#define GCC_WCSS_Q6_BCR 23 +#define GCC_NSS_BCR 24 +#define GCC_SEC_CTRL_BCR 25 +#define GCC_ADSS_BCR 26 +#define GCC_DDRSS_BCR 27 +#define GCC_SYSTEM_NOC_BCR 28 +#define GCC_PCNOC_BCR 29 +#define GCC_TCSR_BCR 30 +#define GCC_QDSS_BCR 31 +#define GCC_DCD_BCR 32 +#define GCC_MSG_RAM_BCR 33 +#define GCC_MPM_BCR 34 +#define GCC_SPMI_BCR 35 +#define GCC_SPDM_BCR 36 +#define GCC_RBCPR_BCR 37 +#define GCC_RBCPR_MX_BCR 38 +#define GCC_TLMM_BCR 39 +#define GCC_RBCPR_WCSS_BCR 40 +#define GCC_USB0_PHY_BCR 41 +#define GCC_USB3PHY_0_PHY_BCR 42 +#define GCC_USB0_BCR 43 +#define GCC_USB1_PHY_BCR 44 +#define GCC_USB3PHY_1_PHY_BCR 45 +#define GCC_USB1_BCR 46 +#define GCC_QUSB2_0_PHY_BCR 47 +#define GCC_QUSB2_1_PHY_BCR 48 +#define GCC_SDCC1_BCR 49 +#define GCC_SDCC2_BCR 50 +#define GCC_SNOC_BUS_TIMEOUT0_BCR 51 +#define GCC_SNOC_BUS_TIMEOUT2_BCR 52 +#define GCC_SNOC_BUS_TIMEOUT3_BCR 53 +#define GCC_PCNOC_BUS_TIMEOUT0_BCR 54 +#define GCC_PCNOC_BUS_TIMEOUT1_BCR 55 +#define GCC_PCNOC_BUS_TIMEOUT2_BCR 56 +#define GCC_PCNOC_BUS_TIMEOUT3_BCR 57 +#define GCC_PCNOC_BUS_TIMEOUT4_BCR 58 +#define GCC_PCNOC_BUS_TIMEOUT5_BCR 59 +#define GCC_PCNOC_BUS_TIMEOUT6_BCR 60 +#define GCC_PCNOC_BUS_TIMEOUT7_BCR 61 +#define GCC_PCNOC_BUS_TIMEOUT8_BCR 62 +#define GCC_PCNOC_BUS_TIMEOUT9_BCR 63 +#define GCC_UNIPHY0_BCR 64 +#define GCC_UNIPHY1_BCR 65 +#define GCC_UNIPHY2_BCR 66 +#define GCC_CMN_12GPLL_BCR 67 +#define GCC_QPIC_BCR 68 +#define GCC_MDIO_BCR 69 +#define GCC_PCIE1_TBU_BCR 70 +#define GCC_WCSS_CORE_TBU_BCR 71 +#define GCC_WCSS_Q6_TBU_BCR 72 +#define GCC_USB0_TBU_BCR 73 +#define GCC_USB1_TBU_BCR 74 +#define GCC_PCIE0_TBU_BCR 75 +#define GCC_NSS_NOC_TBU_BCR 76 +#define GCC_PCIE0_BCR 77 +#define GCC_PCIE0_PHY_BCR 78 +#define GCC_PCIE0PHY_PHY_BCR 79 +#define GCC_PCIE0_LINK_DOWN_BCR 80 +#define GCC_PCIE1_BCR 81 +#define GCC_PCIE1_PHY_BCR 82 +#define GCC_PCIE1PHY_PHY_BCR 83 +#define GCC_PCIE1_LINK_DOWN_BCR 84 +#define GCC_DCC_BCR 85 +#define GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR 86 +#define GCC_APC1_VOLTAGE_DROOP_DETECTOR_BCR 87 +#define GCC_SMMU_CATS_BCR 88 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h index bc256d31099a..7dd8bc0c3cd0 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r7s72100-clock.h @@ -12,8 +12,18 @@ #define R7S72100_CLK_PLL 0 +/* MSTP2 */ +#define R7S72100_CLK_CORESIGHT 0 + /* MSTP3 */ +#define R7S72100_CLK_IEBUS 7 +#define R7S72100_CLK_IRDA 6 +#define R7S72100_CLK_LIN0 5 +#define R7S72100_CLK_LIN1 4 #define R7S72100_CLK_MTU2 3 +#define R7S72100_CLK_CAN 2 +#define R7S72100_CLK_ADCPWR 1 +#define R7S72100_CLK_PWM 0 /* MSTP4 */ #define R7S72100_CLK_SCIF0 7 @@ -26,23 +36,51 @@ #define R7S72100_CLK_SCIF7 0 /* MSTP5 */ +#define R7S72100_CLK_SCI0 7 +#define R7S72100_CLK_SCI1 6 +#define R7S72100_CLK_SG0 5 +#define R7S72100_CLK_SG1 4 +#define R7S72100_CLK_SG2 3 +#define R7S72100_CLK_SG3 2 #define R7S72100_CLK_OSTM0 1 #define R7S72100_CLK_OSTM1 0 /* MSTP6 */ +#define R7S72100_CLK_ADC 7 +#define R7S72100_CLK_CEU 6 +#define R7S72100_CLK_DOC0 5 +#define R7S72100_CLK_DOC1 4 +#define R7S72100_CLK_DRC0 3 +#define R7S72100_CLK_DRC1 2 +#define R7S72100_CLK_JCU 1 #define R7S72100_CLK_RTC 0 /* MSTP7 */ +#define R7S72100_CLK_VDEC0 7 +#define R7S72100_CLK_VDEC1 6 #define R7S72100_CLK_ETHER 4 +#define R7S72100_CLK_NAND 3 +#define R7S72100_CLK_USB0 1 +#define R7S72100_CLK_USB1 0 /* MSTP8 */ +#define R7S72100_CLK_IMR0 7 +#define R7S72100_CLK_IMR1 6 +#define R7S72100_CLK_IMRDISP 5 #define R7S72100_CLK_MMCIF 4 +#define R7S72100_CLK_MLB 3 +#define R7S72100_CLK_ETHAVB 2 +#define R7S72100_CLK_SCUX 1 /* MSTP9 */ #define R7S72100_CLK_I2C0 7 #define R7S72100_CLK_I2C1 6 #define R7S72100_CLK_I2C2 5 #define R7S72100_CLK_I2C3 4 +#define R7S72100_CLK_SPIBSC0 3 +#define R7S72100_CLK_SPIBSC1 2 +#define R7S72100_CLK_VDC50 1 /* and LVDS */ +#define R7S72100_CLK_VDC51 0 /* MSTP10 */ #define R7S72100_CLK_SPI0 7 @@ -50,6 +88,17 @@ #define R7S72100_CLK_SPI2 5 #define R7S72100_CLK_SPI3 4 #define R7S72100_CLK_SPI4 3 +#define R7S72100_CLK_CDROM 2 +#define R7S72100_CLK_SPDIF 1 +#define R7S72100_CLK_RGPVG2 0 + +/* MSTP11 */ +#define R7S72100_CLK_SSI0 5 +#define R7S72100_CLK_SSI1 4 +#define R7S72100_CLK_SSI2 3 +#define R7S72100_CLK_SSI3 2 +#define R7S72100_CLK_SSI4 1 +#define R7S72100_CLK_SSI5 0 /* MSTP12 */ #define R7S72100_CLK_SDHI00 3 @@ -57,4 +106,8 @@ #define R7S72100_CLK_SDHI10 1 #define R7S72100_CLK_SDHI11 0 +/* MSTP13 */ +#define R7S72100_CLK_PIX1 2 +#define R7S72100_CLK_PIX0 1 + #endif /* __DT_BINDINGS_CLOCK_R7S72100_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7790-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7790-cpg-mssr.h new file mode 100644 index 000000000000..1625b8bf3482 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7790-cpg-mssr.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ + +#include + +/* r8a7790 CPG Core Clocks */ +#define R8A7790_CLK_Z 0 +#define R8A7790_CLK_Z2 1 +#define R8A7790_CLK_ZG 2 +#define R8A7790_CLK_ZTR 3 +#define R8A7790_CLK_ZTRD2 4 +#define R8A7790_CLK_ZT 5 +#define R8A7790_CLK_ZX 6 +#define R8A7790_CLK_ZS 7 +#define R8A7790_CLK_HP 8 +#define R8A7790_CLK_I 9 +#define R8A7790_CLK_B 10 +#define R8A7790_CLK_LB 11 +#define R8A7790_CLK_P 12 +#define R8A7790_CLK_CL 13 +#define R8A7790_CLK_M2 14 +#define R8A7790_CLK_ADSP 15 +#define R8A7790_CLK_IMP 16 +#define R8A7790_CLK_ZB3 17 +#define R8A7790_CLK_ZB3D2 18 +#define R8A7790_CLK_DDR 19 +#define R8A7790_CLK_SDH 20 +#define R8A7790_CLK_SD0 21 +#define R8A7790_CLK_SD1 22 +#define R8A7790_CLK_SD2 23 +#define R8A7790_CLK_SD3 24 +#define R8A7790_CLK_MMC0 25 +#define R8A7790_CLK_MMC1 26 +#define R8A7790_CLK_MP 27 +#define R8A7790_CLK_SSP 28 +#define R8A7790_CLK_SSPRS 29 +#define R8A7790_CLK_QSPI 30 +#define R8A7790_CLK_CP 31 +#define R8A7790_CLK_RCAN 32 +#define R8A7790_CLK_R 33 +#define R8A7790_CLK_OSC 34 + +#endif /* __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h index adc50dc31ab3..ef692134146b 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-clock.h @@ -109,6 +109,7 @@ #define R8A7791_CLK_SATA0 15 /* MSTP9 */ +#define R8A7791_CLK_GYROADC 1 #define R8A7791_CLK_GPIO7 4 #define R8A7791_CLK_GPIO6 5 #define R8A7791_CLK_GPIO5 7 diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7791-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-cpg-mssr.h new file mode 100644 index 000000000000..e8823410c01c --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7791-cpg-mssr.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ + +#include + +/* r8a7791 CPG Core Clocks */ +#define R8A7791_CLK_Z 0 +#define R8A7791_CLK_ZG 1 +#define R8A7791_CLK_ZTR 2 +#define R8A7791_CLK_ZTRD2 3 +#define R8A7791_CLK_ZT 4 +#define R8A7791_CLK_ZX 5 +#define R8A7791_CLK_ZS 6 +#define R8A7791_CLK_HP 7 +#define R8A7791_CLK_I 8 +#define R8A7791_CLK_B 9 +#define R8A7791_CLK_LB 10 +#define R8A7791_CLK_P 11 +#define R8A7791_CLK_CL 12 +#define R8A7791_CLK_M2 13 +#define R8A7791_CLK_ADSP 14 +#define R8A7791_CLK_ZB3 15 +#define R8A7791_CLK_ZB3D2 16 +#define R8A7791_CLK_DDR 17 +#define R8A7791_CLK_SDH 18 +#define R8A7791_CLK_SD0 19 +#define R8A7791_CLK_SD2 20 +#define R8A7791_CLK_SD3 21 +#define R8A7791_CLK_MMC0 22 +#define R8A7791_CLK_MP 23 +#define R8A7791_CLK_SSP 24 +#define R8A7791_CLK_SSPRS 25 +#define R8A7791_CLK_QSPI 26 +#define R8A7791_CLK_CP 27 +#define R8A7791_CLK_RCAN 28 +#define R8A7791_CLK_R 29 +#define R8A7791_CLK_OSC 30 + +#endif /* __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7792-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7792-cpg-mssr.h new file mode 100644 index 000000000000..72ce85cb2f94 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7792-cpg-mssr.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ + +#include + +/* r8a7792 CPG Core Clocks */ +#define R8A7792_CLK_Z 0 +#define R8A7792_CLK_ZG 1 +#define R8A7792_CLK_ZTR 2 +#define R8A7792_CLK_ZTRD2 3 +#define R8A7792_CLK_ZT 4 +#define R8A7792_CLK_ZX 5 +#define R8A7792_CLK_ZS 6 +#define R8A7792_CLK_HP 7 +#define R8A7792_CLK_I 8 +#define R8A7792_CLK_B 9 +#define R8A7792_CLK_LB 10 +#define R8A7792_CLK_P 11 +#define R8A7792_CLK_CL 12 +#define R8A7792_CLK_M2 13 +#define R8A7792_CLK_IMP 14 +#define R8A7792_CLK_ZB3 15 +#define R8A7792_CLK_ZB3D2 16 +#define R8A7792_CLK_DDR 17 +#define R8A7792_CLK_SD 18 +#define R8A7792_CLK_MP 19 +#define R8A7792_CLK_QSPI 20 +#define R8A7792_CLK_CP 21 +#define R8A7792_CLK_CPEX 22 +#define R8A7792_CLK_RCAN 23 +#define R8A7792_CLK_R 24 +#define R8A7792_CLK_OSC 25 + +#endif /* __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7793-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7793-cpg-mssr.h new file mode 100644 index 000000000000..8809b0f62d61 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7793-cpg-mssr.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ + +#include + +/* r8a7793 CPG Core Clocks */ +#define R8A7793_CLK_Z 0 +#define R8A7793_CLK_ZG 1 +#define R8A7793_CLK_ZTR 2 +#define R8A7793_CLK_ZTRD2 3 +#define R8A7793_CLK_ZT 4 +#define R8A7793_CLK_ZX 5 +#define R8A7793_CLK_ZS 6 +#define R8A7793_CLK_HP 7 +#define R8A7793_CLK_I 8 +#define R8A7793_CLK_B 9 +#define R8A7793_CLK_LB 10 +#define R8A7793_CLK_P 11 +#define R8A7793_CLK_CL 12 +#define R8A7793_CLK_M2 13 +#define R8A7793_CLK_ADSP 14 +#define R8A7793_CLK_ZB3 15 +#define R8A7793_CLK_ZB3D2 16 +#define R8A7793_CLK_DDR 17 +#define R8A7793_CLK_SDH 18 +#define R8A7793_CLK_SD0 19 +#define R8A7793_CLK_SD2 20 +#define R8A7793_CLK_SD3 21 +#define R8A7793_CLK_MMC0 22 +#define R8A7793_CLK_MP 23 +#define R8A7793_CLK_SSP 24 +#define R8A7793_CLK_SSPRS 25 +#define R8A7793_CLK_QSPI 26 +#define R8A7793_CLK_CP 27 +#define R8A7793_CLK_RCAN 28 +#define R8A7793_CLK_R 29 +#define R8A7793_CLK_OSC 30 + +#endif /* __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/r8a7794-cpg-mssr.h b/sys/gnu/dts/include/dt-bindings/clock/r8a7794-cpg-mssr.h new file mode 100644 index 000000000000..9d720311ae3a --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/r8a7794-cpg-mssr.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ + +#include + +/* r8a7794 CPG Core Clocks */ +#define R8A7794_CLK_Z2 0 +#define R8A7794_CLK_ZG 1 +#define R8A7794_CLK_ZTR 2 +#define R8A7794_CLK_ZTRD2 3 +#define R8A7794_CLK_ZT 4 +#define R8A7794_CLK_ZX 5 +#define R8A7794_CLK_ZS 6 +#define R8A7794_CLK_HP 7 +#define R8A7794_CLK_I 8 +#define R8A7794_CLK_B 9 +#define R8A7794_CLK_LB 10 +#define R8A7794_CLK_P 11 +#define R8A7794_CLK_CL 12 +#define R8A7794_CLK_CP 13 +#define R8A7794_CLK_M2 14 +#define R8A7794_CLK_ADSP 15 +#define R8A7794_CLK_ZB3 16 +#define R8A7794_CLK_ZB3D2 17 +#define R8A7794_CLK_DDR 18 +#define R8A7794_CLK_SDH 19 +#define R8A7794_CLK_SD0 20 +#define R8A7794_CLK_SD2 21 +#define R8A7794_CLK_SD3 22 +#define R8A7794_CLK_MMC0 23 +#define R8A7794_CLK_MP 24 +#define R8A7794_CLK_QSPI 25 +#define R8A7794_CLK_CPEX 26 +#define R8A7794_CLK_RCAN 27 +#define R8A7794_CLK_R 28 +#define R8A7794_CLK_OSC 29 + +#endif /* __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk3128-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rk3128-cru.h new file mode 100644 index 000000000000..92894f4306cf --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/rk3128-cru.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2017 Rockchip Electronics Co. Ltd. + * Author: Elaine + * + * This program 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 program 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. + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_GPLL 4 +#define ARMCLK 5 +#define PLL_GPLL_DIV2 6 +#define PLL_GPLL_DIV3 7 + +/* sclk gates (special clocks) */ +#define SCLK_SPI0 65 +#define SCLK_NANDC 67 +#define SCLK_SDMMC 68 +#define SCLK_SDIO 69 +#define SCLK_EMMC 71 +#define SCLK_UART0 77 +#define SCLK_UART1 78 +#define SCLK_UART2 79 +#define SCLK_I2S0 80 +#define SCLK_I2S1 81 +#define SCLK_SPDIF 83 +#define SCLK_TIMER0 85 +#define SCLK_TIMER1 86 +#define SCLK_TIMER2 87 +#define SCLK_TIMER3 88 +#define SCLK_TIMER4 89 +#define SCLK_TIMER5 90 +#define SCLK_SARADC 91 +#define SCLK_I2S_OUT 113 +#define SCLK_SDMMC_DRV 114 +#define SCLK_SDIO_DRV 115 +#define SCLK_EMMC_DRV 117 +#define SCLK_SDMMC_SAMPLE 118 +#define SCLK_SDIO_SAMPLE 119 +#define SCLK_EMMC_SAMPLE 121 +#define SCLK_VOP 122 +#define SCLK_MAC_SRC 124 +#define SCLK_MAC 126 +#define SCLK_MAC_REFOUT 127 +#define SCLK_MAC_REF 128 +#define SCLK_MAC_RX 129 +#define SCLK_MAC_TX 130 +#define SCLK_HEVC_CORE 134 +#define SCLK_RGA 135 +#define SCLK_CRYPTO 138 +#define SCLK_TSP 139 +#define SCLK_OTGPHY0 142 +#define SCLK_OTGPHY1 143 +#define SCLK_DDRC 144 +#define SCLK_PVTM_FUNC 145 +#define SCLK_PVTM_CORE 146 +#define SCLK_PVTM_GPU 147 +#define SCLK_MIPI_24M 148 +#define SCLK_PVTM 149 +#define SCLK_CIF_SRC 150 +#define SCLK_CIF_OUT_SRC 151 +#define SCLK_CIF_OUT 152 +#define SCLK_SFC 153 +#define SCLK_USB480M 154 + +/* dclk gates */ +#define DCLK_VOP 190 +#define DCLK_EBC 191 + +/* aclk gates */ +#define ACLK_VIO0 192 +#define ACLK_VIO1 193 +#define ACLK_DMAC 194 +#define ACLK_CPU 195 +#define ACLK_VEPU 196 +#define ACLK_VDPU 197 +#define ACLK_CIF 198 +#define ACLK_IEP 199 +#define ACLK_LCDC0 204 +#define ACLK_RGA 205 +#define ACLK_PERI 210 +#define ACLK_VOP 211 +#define ACLK_GMAC 212 +#define ACLK_GPU 213 + +/* pclk gates */ +#define PCLK_SARADC 318 +#define PCLK_WDT 319 +#define PCLK_GPIO0 320 +#define PCLK_GPIO1 321 +#define PCLK_GPIO2 322 +#define PCLK_GPIO3 323 +#define PCLK_VIO_H2P 324 +#define PCLK_MIPI 325 +#define PCLK_EFUSE 326 +#define PCLK_HDMI 327 +#define PCLK_ACODEC 328 +#define PCLK_GRF 329 +#define PCLK_I2C0 332 +#define PCLK_I2C1 333 +#define PCLK_I2C2 334 +#define PCLK_I2C3 335 +#define PCLK_SPI0 338 +#define PCLK_UART0 341 +#define PCLK_UART1 342 +#define PCLK_UART2 343 +#define PCLK_TSADC 344 +#define PCLK_PWM 350 +#define PCLK_TIMER 353 +#define PCLK_CPU 354 +#define PCLK_PERI 363 +#define PCLK_GMAC 367 +#define PCLK_PMU_PRE 368 +#define PCLK_SIM_CARD 369 + +/* hclk gates */ +#define HCLK_SPDIF 440 +#define HCLK_GPS 441 +#define HCLK_USBHOST 442 +#define HCLK_I2S_8CH 443 +#define HCLK_I2S_2CH 444 +#define HCLK_VOP 452 +#define HCLK_NANDC 453 +#define HCLK_SDMMC 456 +#define HCLK_SDIO 457 +#define HCLK_EMMC 459 +#define HCLK_CPU 460 +#define HCLK_VEPU 461 +#define HCLK_VDPU 462 +#define HCLK_LCDC0 463 +#define HCLK_EBC 465 +#define HCLK_VIO 466 +#define HCLK_RGA 467 +#define HCLK_IEP 468 +#define HCLK_VIO_H2P 469 +#define HCLK_CIF 470 +#define HCLK_HOST2 473 +#define HCLK_OTG 474 +#define HCLK_TSP 475 +#define HCLK_CRYPTO 476 +#define HCLK_PERI 478 + +#define CLK_NR_CLKS (HCLK_PERI + 1) + +/* soft-reset indices */ +#define SRST_CORE0_PO 0 +#define SRST_CORE1_PO 1 +#define SRST_CORE2_PO 2 +#define SRST_CORE3_PO 3 +#define SRST_CORE0 4 +#define SRST_CORE1 5 +#define SRST_CORE2 6 +#define SRST_CORE3 7 +#define SRST_CORE0_DBG 8 +#define SRST_CORE1_DBG 9 +#define SRST_CORE2_DBG 10 +#define SRST_CORE3_DBG 11 +#define SRST_TOPDBG 12 +#define SRST_ACLK_CORE 13 +#define SRST_STRC_SYS_A 14 +#define SRST_L2C 15 + +#define SRST_CPUSYS_H 18 +#define SRST_AHB2APBSYS_H 19 +#define SRST_SPDIF 20 +#define SRST_INTMEM 21 +#define SRST_ROM 22 +#define SRST_PERI_NIU 23 +#define SRST_I2S_2CH 24 +#define SRST_I2S_8CH 25 +#define SRST_GPU_PVTM 26 +#define SRST_FUNC_PVTM 27 +#define SRST_CORE_PVTM 29 +#define SRST_EFUSE_P 30 +#define SRST_ACODEC_P 31 + +#define SRST_GPIO0 32 +#define SRST_GPIO1 33 +#define SRST_GPIO2 34 +#define SRST_GPIO3 35 +#define SRST_MIPIPHY_P 36 +#define SRST_UART0 39 +#define SRST_UART1 40 +#define SRST_UART2 41 +#define SRST_I2C0 43 +#define SRST_I2C1 44 +#define SRST_I2C2 45 +#define SRST_I2C3 46 +#define SRST_SFC 47 + +#define SRST_PWM 48 +#define SRST_DAP_PO 50 +#define SRST_DAP 51 +#define SRST_DAP_SYS 52 +#define SRST_CRYPTO 53 +#define SRST_GRF 55 +#define SRST_GMAC 56 +#define SRST_PERIPH_SYS_A 57 +#define SRST_PERIPH_SYS_H 58 +#define SRST_PERIPH_SYS_P 59 +#define SRST_SMART_CARD 60 +#define SRST_CPU_PERI 61 +#define SRST_EMEM_PERI 62 +#define SRST_USB_PERI 63 + +#define SRST_DMA 64 +#define SRST_GPS 67 +#define SRST_NANDC 68 +#define SRST_USBOTG0 69 +#define SRST_OTGC0 71 +#define SRST_USBOTG1 72 +#define SRST_OTGC1 74 +#define SRST_DDRMSCH 79 + +#define SRST_SDMMC 81 +#define SRST_SDIO 82 +#define SRST_EMMC 83 +#define SRST_SPI 84 +#define SRST_WDT 86 +#define SRST_SARADC 87 +#define SRST_DDRPHY 88 +#define SRST_DDRPHY_P 89 +#define SRST_DDRCTRL 90 +#define SRST_DDRCTRL_P 91 +#define SRST_TSP 92 +#define SRST_TSP_CLKIN 93 +#define SRST_HOST0_ECHI 94 + +#define SRST_HDMI_P 96 +#define SRST_VIO_ARBI_H 97 +#define SRST_VIO0_A 98 +#define SRST_VIO_BUS_H 99 +#define SRST_VOP_A 100 +#define SRST_VOP_H 101 +#define SRST_VOP_D 102 +#define SRST_UTMI0 103 +#define SRST_UTMI1 104 +#define SRST_USBPOR 105 +#define SRST_IEP_A 106 +#define SRST_IEP_H 107 +#define SRST_RGA_A 108 +#define SRST_RGA_H 109 +#define SRST_CIF0 110 +#define SRST_PMU 111 + +#define SRST_VCODEC_A 112 +#define SRST_VCODEC_H 113 +#define SRST_VIO1_A 114 +#define SRST_HEVC_CORE 115 +#define SRST_VCODEC_NIU_A 116 +#define SRST_PMU_NIU_P 117 +#define SRST_LCDC0_S 119 +#define SRST_GPU 120 +#define SRST_GPU_NIU_A 122 +#define SRST_EBC_A 123 +#define SRST_EBC_H 124 + +#define SRST_CORE_DBG 128 +#define SRST_DBG_P 129 +#define SRST_TIMER0 130 +#define SRST_TIMER1 131 +#define SRST_TIMER2 132 +#define SRST_TIMER3 133 +#define SRST_TIMER4 134 +#define SRST_TIMER5 135 +#define SRST_VIO_H2P 136 +#define SRST_VIO_MIPI_DSI 137 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk3228-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rk3228-cru.h index b27e2b1a65e3..56f841c22801 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/rk3228-cru.h +++ b/sys/gnu/dts/include/dt-bindings/clock/rk3228-cru.h @@ -61,6 +61,17 @@ #define SCLK_MAC_TX 130 #define SCLK_MAC_PHY 131 #define SCLK_MAC_OUT 132 +#define SCLK_VDEC_CABAC 133 +#define SCLK_VDEC_CORE 134 +#define SCLK_RGA 135 +#define SCLK_HDCP 136 +#define SCLK_HDMI_CEC 137 +#define SCLK_CRYPTO 138 +#define SCLK_TSP 139 +#define SCLK_HSADC 140 +#define SCLK_WIFI 141 +#define SCLK_OTGPHY0 142 +#define SCLK_OTGPHY1 143 /* dclk gates */ #define DCLK_VOP 190 @@ -68,15 +79,32 @@ /* aclk gates */ #define ACLK_DMAC 194 +#define ACLK_CPU 195 +#define ACLK_VPU_PRE 196 +#define ACLK_RKVDEC_PRE 197 +#define ACLK_RGA_PRE 198 +#define ACLK_IEP_PRE 199 +#define ACLK_HDCP_PRE 200 +#define ACLK_VOP_PRE 201 +#define ACLK_VPU 202 +#define ACLK_RKVDEC 203 +#define ACLK_IEP 204 +#define ACLK_RGA 205 +#define ACLK_HDCP 206 #define ACLK_PERI 210 #define ACLK_VOP 211 #define ACLK_GMAC 212 +#define ACLK_GPU 213 /* pclk gates */ #define PCLK_GPIO0 320 #define PCLK_GPIO1 321 #define PCLK_GPIO2 322 #define PCLK_GPIO3 323 +#define PCLK_VIO_H2P 324 +#define PCLK_HDCP 325 +#define PCLK_EFUSE_1024 326 +#define PCLK_EFUSE_256 327 #define PCLK_GRF 329 #define PCLK_I2C0 332 #define PCLK_I2C1 333 @@ -89,6 +117,7 @@ #define PCLK_TSADC 344 #define PCLK_PWM 350 #define PCLK_TIMER 353 +#define PCLK_CPU 354 #define PCLK_PERI 363 #define PCLK_HDMI_CTRL 364 #define PCLK_HDMI_PHY 365 @@ -104,6 +133,24 @@ #define HCLK_SDMMC 456 #define HCLK_SDIO 457 #define HCLK_EMMC 459 +#define HCLK_CPU 460 +#define HCLK_VPU_PRE 461 +#define HCLK_RKVDEC_PRE 462 +#define HCLK_VIO_PRE 463 +#define HCLK_VPU 464 +#define HCLK_RKVDEC 465 +#define HCLK_VIO 466 +#define HCLK_RGA 467 +#define HCLK_IEP 468 +#define HCLK_VIO_H2P 469 +#define HCLK_HDCP_MMU 470 +#define HCLK_HOST0 471 +#define HCLK_HOST1 472 +#define HCLK_HOST2 473 +#define HCLK_OTG 474 +#define HCLK_TSP 475 +#define HCLK_M_CRYPTO 476 +#define HCLK_S_CRYPTO 477 #define HCLK_PERI 478 #define CLK_NR_CLKS (HCLK_PERI + 1) diff --git a/sys/gnu/dts/include/dt-bindings/clock/rk3399-cru.h b/sys/gnu/dts/include/dt-bindings/clock/rk3399-cru.h index 220a60f20d3b..22cb1dfa9004 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/rk3399-cru.h +++ b/sys/gnu/dts/include/dt-bindings/clock/rk3399-cru.h @@ -132,6 +132,8 @@ #define SCLK_RMII_SRC 166 #define SCLK_PCIEPHY_REF100M 167 #define SCLK_DDRC 168 +#define SCLK_TESTCLKOUT1 169 +#define SCLK_TESTCLKOUT2 170 #define DCLK_VOP0 180 #define DCLK_VOP1 181 diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun5i-ccu.h b/sys/gnu/dts/include/dt-bindings/clock/sun5i-ccu.h index aeb2e2f781fb..81f34d477aeb 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/sun5i-ccu.h +++ b/sys/gnu/dts/include/dt-bindings/clock/sun5i-ccu.h @@ -19,6 +19,9 @@ #define CLK_HOSC 1 +#define CLK_PLL_VIDEO0_2X 9 + +#define CLK_PLL_VIDEO1_2X 16 #define CLK_CPU 17 #define CLK_AHB_OTG 23 diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun8i-a83t-ccu.h b/sys/gnu/dts/include/dt-bindings/clock/sun8i-a83t-ccu.h new file mode 100644 index 000000000000..78af5085f630 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/sun8i-a83t-ccu.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2017 Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ +#define _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ + +#define CLK_PLL_PERIPH 6 + +#define CLK_PLL_DE 9 + +#define CLK_C0CPUX 11 +#define CLK_C1CPUX 12 + +#define CLK_BUS_MIPI_DSI 19 +#define CLK_BUS_SS 20 +#define CLK_BUS_DMA 21 +#define CLK_BUS_MMC0 22 +#define CLK_BUS_MMC1 23 +#define CLK_BUS_MMC2 24 +#define CLK_BUS_NAND 25 +#define CLK_BUS_DRAM 26 +#define CLK_BUS_EMAC 27 +#define CLK_BUS_HSTIMER 28 +#define CLK_BUS_SPI0 29 +#define CLK_BUS_SPI1 30 +#define CLK_BUS_OTG 31 +#define CLK_BUS_EHCI0 32 +#define CLK_BUS_EHCI1 33 +#define CLK_BUS_OHCI0 34 + +#define CLK_BUS_VE 35 +#define CLK_BUS_TCON0 36 +#define CLK_BUS_TCON1 37 +#define CLK_BUS_CSI 38 +#define CLK_BUS_HDMI 39 +#define CLK_BUS_DE 40 +#define CLK_BUS_GPU 41 +#define CLK_BUS_MSGBOX 42 +#define CLK_BUS_SPINLOCK 43 + +#define CLK_BUS_SPDIF 44 +#define CLK_BUS_PIO 45 +#define CLK_BUS_I2S0 46 +#define CLK_BUS_I2S1 47 +#define CLK_BUS_I2S2 48 +#define CLK_BUS_TDM 49 + +#define CLK_BUS_I2C0 50 +#define CLK_BUS_I2C1 51 +#define CLK_BUS_I2C2 52 +#define CLK_BUS_UART0 53 +#define CLK_BUS_UART1 54 +#define CLK_BUS_UART2 55 +#define CLK_BUS_UART3 56 +#define CLK_BUS_UART4 57 + +#define CLK_NAND 59 +#define CLK_MMC0 60 +#define CLK_MMC0_SAMPLE 61 +#define CLK_MMC0_OUTPUT 62 +#define CLK_MMC1 63 +#define CLK_MMC1_SAMPLE 64 +#define CLK_MMC1_OUTPUT 65 +#define CLK_MMC2 66 +#define CLK_MMC2_SAMPLE 67 +#define CLK_MMC2_OUTPUT 68 +#define CLK_SS 69 +#define CLK_SPI0 70 +#define CLK_SPI1 71 +#define CLK_I2S0 72 +#define CLK_I2S1 73 +#define CLK_I2S2 74 +#define CLK_TDM 75 +#define CLK_SPDIF 76 +#define CLK_USB_PHY0 77 +#define CLK_USB_PHY1 78 +#define CLK_USB_HSIC 79 +#define CLK_USB_HSIC_12M 80 +#define CLK_USB_OHCI0 81 + +#define CLK_DRAM_VE 83 +#define CLK_DRAM_CSI 84 + +#define CLK_TCON0 85 +#define CLK_TCON1 86 +#define CLK_CSI_MISC 87 +#define CLK_MIPI_CSI 88 +#define CLK_CSI_MCLK 89 +#define CLK_CSI_SCLK 90 +#define CLK_VE 91 +#define CLK_AVS 92 +#define CLK_HDMI 93 +#define CLK_HDMI_SLOW 94 + +#define CLK_MIPI_DSI0 96 +#define CLK_MIPI_DSI1 97 +#define CLK_GPU_CORE 98 +#define CLK_GPU_MEMORY 99 +#define CLK_GPU_HYD 100 + +#endif /* _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/sun8i-de2.h b/sys/gnu/dts/include/dt-bindings/clock/sun8i-de2.h new file mode 100644 index 000000000000..3bed63b524aa --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/clock/sun8i-de2.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#ifndef _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ +#define _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ + +#define CLK_BUS_MIXER0 0 +#define CLK_BUS_MIXER1 1 +#define CLK_BUS_WB 2 + +#define CLK_MIXER0 6 +#define CLK_MIXER1 7 +#define CLK_WB 8 + +#endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/clock/zx296718-clock.h b/sys/gnu/dts/include/dt-bindings/clock/zx296718-clock.h index 822d52385080..092c9751a697 100644 --- a/sys/gnu/dts/include/dt-bindings/clock/zx296718-clock.h +++ b/sys/gnu/dts/include/dt-bindings/clock/zx296718-clock.h @@ -157,7 +157,11 @@ #define AUDIO_TDM_WCLK 17 #define AUDIO_TDM_PCLK 18 #define AUDIO_TS_PCLK 19 +#define I2S0_WCLK_MUX 20 +#define I2S1_WCLK_MUX 21 +#define I2S2_WCLK_MUX 22 +#define I2S3_WCLK_MUX 23 -#define AUDIO_NR_CLKS 20 +#define AUDIO_NR_CLKS 24 #endif diff --git a/sys/gnu/dts/include/dt-bindings/gpio/gpio.h b/sys/gnu/dts/include/dt-bindings/gpio/gpio.h index b4f54da694eb..c5074584561d 100644 --- a/sys/gnu/dts/include/dt-bindings/gpio/gpio.h +++ b/sys/gnu/dts/include/dt-bindings/gpio/gpio.h @@ -28,4 +28,8 @@ #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) +/* Bit 3 express GPIO suspend/resume persistence */ +#define GPIO_SLEEP_MAINTAIN_VALUE 0 +#define GPIO_SLEEP_MAY_LOOSE_VALUE 8 + #endif diff --git a/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h b/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h index f5a8d96e1e09..179891074b3c 100644 --- a/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h +++ b/sys/gnu/dts/include/dt-bindings/input/linux-event-codes.h @@ -600,6 +600,7 @@ #define KEY_APPSELECT 0x244 /* AL Select Task/Application */ #define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ +#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ diff --git a/sys/gnu/dts/include/dt-bindings/interrupt-controller/mvebu-icu.h b/sys/gnu/dts/include/dt-bindings/interrupt-controller/mvebu-icu.h new file mode 100644 index 000000000000..8249558545c7 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/interrupt-controller/mvebu-icu.h @@ -0,0 +1,15 @@ +/* + * This header provides constants for the MVEBU ICU driver. + */ + +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MVEBU_ICU_H +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_MVEBU_ICU_H + +/* interrupt specifier cell 0 */ + +#define ICU_GRP_NSR 0x0 +#define ICU_GRP_SR 0x1 +#define ICU_GRP_SEI 0x4 +#define ICU_GRP_REI 0x5 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/mux/mux.h b/sys/gnu/dts/include/dt-bindings/mux/mux.h new file mode 100644 index 000000000000..c8e855c4a609 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/mux/mux.h @@ -0,0 +1,16 @@ +/* + * This header provides constants for most Multiplexer bindings. + * + * Most Multiplexer bindings specify an idle state. In most cases, the + * the multiplexer can be left as is when idle, and in some cases it can + * disconnect the input/output and leave the multiplexer in a high + * impedance state. + */ + +#ifndef _DT_BINDINGS_MUX_MUX_H +#define _DT_BINDINGS_MUX_MUX_H + +#define MUX_IDLE_AS_IS (-1) +#define MUX_IDLE_DISCONNECT (-2) + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/pinctrl/brcm,pinctrl-stingray.h b/sys/gnu/dts/include/dt-bindings/pinctrl/brcm,pinctrl-stingray.h new file mode 100644 index 000000000000..caa6c664b4f6 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/pinctrl/brcm,pinctrl-stingray.h @@ -0,0 +1,68 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Broadcom Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +#ifndef __DT_BINDINGS_PINCTRL_BRCM_STINGRAY_H__ +#define __DT_BINDINGS_PINCTRL_BRCM_STINGRAY_H__ + +/* Alternate functions available in MUX controller */ +#define MODE_NITRO 0 +#define MODE_NAND 1 +#define MODE_PNOR 2 +#define MODE_GPIO 3 + +/* Pad configuration attribute */ +#define PAD_SLEW_RATE_ENA (1 << 0) +#define PAD_SLEW_RATE_ENA_MASK (1 << 0) + +#define PAD_DRIVE_STRENGTH_2_MA (0 << 1) +#define PAD_DRIVE_STRENGTH_4_MA (1 << 1) +#define PAD_DRIVE_STRENGTH_6_MA (2 << 1) +#define PAD_DRIVE_STRENGTH_8_MA (3 << 1) +#define PAD_DRIVE_STRENGTH_10_MA (4 << 1) +#define PAD_DRIVE_STRENGTH_12_MA (5 << 1) +#define PAD_DRIVE_STRENGTH_14_MA (6 << 1) +#define PAD_DRIVE_STRENGTH_16_MA (7 << 1) +#define PAD_DRIVE_STRENGTH_MASK (7 << 1) + +#define PAD_PULL_UP_ENA (1 << 4) +#define PAD_PULL_UP_ENA_MASK (1 << 4) + +#define PAD_PULL_DOWN_ENA (1 << 5) +#define PAD_PULL_DOWN_ENA_MASK (1 << 5) + +#define PAD_INPUT_PATH_DIS (1 << 6) +#define PAD_INPUT_PATH_DIS_MASK (1 << 6) + +#define PAD_HYSTERESIS_ENA (1 << 7) +#define PAD_HYSTERESIS_ENA_MASK (1 << 7) + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/pinctrl/r7s72100-pinctrl.h b/sys/gnu/dts/include/dt-bindings/pinctrl/r7s72100-pinctrl.h new file mode 100644 index 000000000000..6b609fe10910 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/pinctrl/r7s72100-pinctrl.h @@ -0,0 +1,16 @@ +/* + * Defines macros and constants for Renesas RZ/A1 pin controller pin + * muxing functions. + */ +#ifndef __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H +#define __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H + +#define RZA1_PINS_PER_PORT 16 + +/* + * Create the pin index from its bank and position numbers and store in + * the upper 16 bits the alternate function identifier + */ +#define RZA1_PINMUX(b, p, f) ((b) * RZA1_PINS_PER_PORT + (p) | (f << 16)) + +#endif /* __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H */ diff --git a/sys/gnu/dts/include/dt-bindings/power/mt6797-power.h b/sys/gnu/dts/include/dt-bindings/power/mt6797-power.h new file mode 100644 index 000000000000..a60c1d81cf75 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/power/mt6797-power.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Mars.C + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_POWER_MT6797_POWER_H +#define _DT_BINDINGS_POWER_MT6797_POWER_H + +#define MT6797_POWER_DOMAIN_VDEC 0 +#define MT6797_POWER_DOMAIN_VENC 1 +#define MT6797_POWER_DOMAIN_ISP 2 +#define MT6797_POWER_DOMAIN_MM 3 +#define MT6797_POWER_DOMAIN_AUDIO 4 +#define MT6797_POWER_DOMAIN_MFG_ASYNC 5 +#define MT6797_POWER_DOMAIN_MFG 6 +#define MT6797_POWER_DOMAIN_MFG_CORE0 7 +#define MT6797_POWER_DOMAIN_MFG_CORE1 8 +#define MT6797_POWER_DOMAIN_MFG_CORE2 9 +#define MT6797_POWER_DOMAIN_MFG_CORE3 10 +#define MT6797_POWER_DOMAIN_MJC 11 + +#endif /* _DT_BINDINGS_POWER_MT6797_POWER_H */ diff --git a/sys/gnu/dts/include/dt-bindings/power/owl-s500-powergate.h b/sys/gnu/dts/include/dt-bindings/power/owl-s500-powergate.h new file mode 100644 index 000000000000..0a1c451865ea --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/power/owl-s500-powergate.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ +#ifndef DT_BINDINGS_POWER_OWL_S500_POWERGATE_H +#define DT_BINDINGS_POWER_OWL_S500_POWERGATE_H + +#define S500_PD_VDE 0 +#define S500_PD_VCE_SI 1 +#define S500_PD_USB2_1 2 +#define S500_PD_CPU2 3 +#define S500_PD_CPU3 4 +#define S500_PD_DMA 5 +#define S500_PD_DS 6 +#define S500_PD_USB3 7 +#define S500_PD_USB2_0 8 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-s10.h b/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-s10.h new file mode 100644 index 000000000000..7978c21e4fad --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/altr,rst-mgr-s10.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 Intel Corporation. All rights reserved + * Copyright (C) 2016 Altera Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program. If not, see . + * + * derived from Steffen Trumtrar's "altr,rst-mgr-a10.h" + */ + +#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_S10_H +#define _DT_BINDINGS_RESET_ALTR_RST_MGR_S10_H + +/* MPUMODRST */ +#define CPU0_RESET 0 +#define CPU1_RESET 1 +#define CPU2_RESET 2 +#define CPU3_RESET 3 + +/* PER0MODRST */ +#define EMAC0_RESET 32 +#define EMAC1_RESET 33 +#define EMAC2_RESET 34 +#define USB0_RESET 35 +#define USB1_RESET 36 +#define NAND_RESET 37 +/* 38 is empty */ +#define SDMMC_RESET 39 +#define EMAC0_OCP_RESET 40 +#define EMAC1_OCP_RESET 41 +#define EMAC2_OCP_RESET 42 +#define USB0_OCP_RESET 43 +#define USB1_OCP_RESET 44 +#define NAND_OCP_RESET 45 +/* 46 is empty */ +#define SDMMC_OCP_RESET 47 +#define DMA_RESET 48 +#define SPIM0_RESET 49 +#define SPIM1_RESET 50 +#define SPIS0_RESET 51 +#define SPIS1_RESET 52 +#define DMA_OCP_RESET 53 +#define EMAC_PTP_RESET 54 +/* 55 is empty*/ +#define DMAIF0_RESET 56 +#define DMAIF1_RESET 57 +#define DMAIF2_RESET 58 +#define DMAIF3_RESET 59 +#define DMAIF4_RESET 60 +#define DMAIF5_RESET 61 +#define DMAIF6_RESET 62 +#define DMAIF7_RESET 63 + +/* PER1MODRST */ +#define WATCHDOG0_RESET 64 +#define WATCHDOG1_RESET 65 +#define WATCHDOG2_RESET 66 +#define WATCHDOG3_RESET 67 +#define L4SYSTIMER0_RESET 68 +#define L4SYSTIMER1_RESET 69 +#define SPTIMER0_RESET 70 +#define SPTIMER1_RESET 71 +#define I2C0_RESET 72 +#define I2C1_RESET 73 +#define I2C2_RESET 74 +#define I2C3_RESET 75 +#define I2C4_RESET 76 +/* 77-79 is empty */ +#define UART0_RESET 80 +#define UART1_RESET 81 +/* 82-87 is empty */ +#define GPIO0_RESET 88 +#define GPIO1_RESET 89 + +/* BRGMODRST */ +#define SOC2FPGA_RESET 96 +#define LWHPS2FPGA_RESET 97 +#define FPGA2SOC_RESET 98 +#define F2SSDRAM0_RESET 99 +#define F2SSDRAM1_RESET 100 +#define F2SSDRAM2_RESET 101 +#define DDRSCH_RESET 102 + +/* COLDMODRST */ +#define CPUPO0_RESET 160 +#define CPUPO1_RESET 161 +#define CPUPO2_RESET 162 +#define CPUPO3_RESET 163 +/* 164-167 is empty */ +#define L2_RESET 168 + +/* DBGMODRST */ +#define DBG_RESET 224 +#define CSDAP_RESET 225 + +/* TAPMODRST */ +#define TAP_RESET 256 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/reset/cortina,gemini-reset.h b/sys/gnu/dts/include/dt-bindings/reset/cortina,gemini-reset.h new file mode 100644 index 000000000000..0b886aee65e3 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/cortina,gemini-reset.h @@ -0,0 +1,36 @@ +#ifndef _DT_BINDINGS_RESET_CORTINA_GEMINI_H +#define _DT_BINDINGS_RESET_CORTINA_GEMINI_H + +#define GEMINI_RESET_DRAM 0 +#define GEMINI_RESET_FLASH 1 +#define GEMINI_RESET_IDE 2 +#define GEMINI_RESET_RAID 3 +#define GEMINI_RESET_SECURITY 4 +#define GEMINI_RESET_GMAC0 5 +#define GEMINI_RESET_GMAC1 6 +#define GEMINI_RESET_PCI 7 +#define GEMINI_RESET_USB0 8 +#define GEMINI_RESET_USB1 9 +#define GEMINI_RESET_DMAC 10 +#define GEMINI_RESET_APB 11 +#define GEMINI_RESET_LPC 12 +#define GEMINI_RESET_LCD 13 +#define GEMINI_RESET_INTCON0 14 +#define GEMINI_RESET_INTCON1 15 +#define GEMINI_RESET_RTC 16 +#define GEMINI_RESET_TIMER 17 +#define GEMINI_RESET_UART 18 +#define GEMINI_RESET_SSP 19 +#define GEMINI_RESET_GPIO0 20 +#define GEMINI_RESET_GPIO1 21 +#define GEMINI_RESET_GPIO2 22 +#define GEMINI_RESET_WDOG 23 +#define GEMINI_RESET_EXTERN 24 +#define GEMINI_RESET_CIR 25 +#define GEMINI_RESET_SATA0 26 +#define GEMINI_RESET_SATA1 27 +#define GEMINI_RESET_TVC 28 +#define GEMINI_RESET_CPU1 30 +#define GEMINI_RESET_GLOBAL 31 + +#endif diff --git a/sys/gnu/dts/include/dt-bindings/reset/sun8i-a83t-ccu.h b/sys/gnu/dts/include/dt-bindings/reset/sun8i-a83t-ccu.h new file mode 100644 index 000000000000..784f6e11664e --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/sun8i-a83t-ccu.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ +#define _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ + +#define RST_USB_PHY0 0 +#define RST_USB_PHY1 1 +#define RST_USB_HSIC 2 + +#define RST_DRAM 3 +#define RST_MBUS 4 + +#define RST_BUS_MIPI_DSI 5 +#define RST_BUS_SS 6 +#define RST_BUS_DMA 7 +#define RST_BUS_MMC0 8 +#define RST_BUS_MMC1 9 +#define RST_BUS_MMC2 10 +#define RST_BUS_NAND 11 +#define RST_BUS_DRAM 12 +#define RST_BUS_EMAC 13 +#define RST_BUS_HSTIMER 14 +#define RST_BUS_SPI0 15 +#define RST_BUS_SPI1 16 +#define RST_BUS_OTG 17 +#define RST_BUS_EHCI0 18 +#define RST_BUS_EHCI1 19 +#define RST_BUS_OHCI0 20 + +#define RST_BUS_VE 21 +#define RST_BUS_TCON0 22 +#define RST_BUS_TCON1 23 +#define RST_BUS_CSI 24 +#define RST_BUS_HDMI0 25 +#define RST_BUS_HDMI1 26 +#define RST_BUS_DE 27 +#define RST_BUS_GPU 28 +#define RST_BUS_MSGBOX 29 +#define RST_BUS_SPINLOCK 30 + +#define RST_BUS_LVDS 31 + +#define RST_BUS_SPDIF 32 +#define RST_BUS_I2S0 33 +#define RST_BUS_I2S1 34 +#define RST_BUS_I2S2 35 +#define RST_BUS_TDM 36 + +#define RST_BUS_I2C0 37 +#define RST_BUS_I2C1 38 +#define RST_BUS_I2C2 39 +#define RST_BUS_UART0 40 +#define RST_BUS_UART1 41 +#define RST_BUS_UART2 42 +#define RST_BUS_UART3 43 +#define RST_BUS_UART4 44 + +#endif /* _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ */ diff --git a/sys/gnu/dts/include/dt-bindings/reset/sun8i-de2.h b/sys/gnu/dts/include/dt-bindings/reset/sun8i-de2.h new file mode 100644 index 000000000000..9526017432f0 --- /dev/null +++ b/sys/gnu/dts/include/dt-bindings/reset/sun8i-de2.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#ifndef _DT_BINDINGS_RESET_SUN8I_DE2_H_ +#define _DT_BINDINGS_RESET_SUN8I_DE2_H_ + +#define RST_MIXER0 0 +#define RST_MIXER1 1 +#define RST_WB 2 + +#endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */ diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index aa9b92800ee7..6e3f9b9a8cce 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -28,10 +28,11 @@ makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security -options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_HHOOK # hhook(9) framework for TCP options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol diff --git a/sys/i386/conf/GENERIC-NODEBUG b/sys/i386/conf/GENERIC-NODEBUG index 2aabed6880ac..4cf57ee9ae91 100644 --- a/sys/i386/conf/GENERIC-NODEBUG +++ b/sys/i386/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 992fc9278d16..5a4bc6135ee2 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -189,8 +189,7 @@ IDTVEC(xen_intr_upcall) SUPERALIGN_TEXT invltlb_ret: call as_lapic_eoi - POP_FRAME - iret + jmp doreti SUPERALIGN_TEXT IDTVEC(invltlb) @@ -274,9 +273,7 @@ IDTVEC(cpustop) call as_lapic_eoi call cpustop_handler - - POP_FRAME - iret + jmp doreti /* * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. @@ -290,9 +287,7 @@ IDTVEC(cpususpend) call as_lapic_eoi call cpususpend_handler - - POP_FRAME - jmp doreti_iret + jmp doreti /* * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. @@ -314,7 +309,6 @@ IDTVEC(rendezvous) call smp_rendezvous_action call as_lapic_eoi - POP_FRAME - iret + jmp doreti #endif /* SMP */ diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index b905fb1fd635..25b36e0d1f61 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -425,8 +425,16 @@ doreti_iret: * doreti_iret_fault and friends. Alternative return code for * the case where we get a fault in the doreti_exit code * above. trap() (i386/i386/trap.c) catches this specific - * case, sends the process a signal and continues in the - * corresponding place in the code below. + * case, and continues in the corresponding place in the code + * below. + * + * If the fault occured during return to usermode, we recreate + * the trap frame and call trap() to send a signal. Otherwise + * the kernel was tricked into fault by attempt to restore invalid + * usermode segment selectors on return from nested fault or + * interrupt, where interrupted kernel entry code not yet loaded + * kernel selectors. In the latter case, emulate iret and zero + * the invalid selector. */ ALIGN_TEXT .globl doreti_iret_fault @@ -437,18 +445,35 @@ doreti_iret_fault: movw %ds,(%esp) .globl doreti_popl_ds_fault doreti_popl_ds_fault: + testb $SEL_RPL_MASK,TF_CS-TF_DS(%esp) + jz doreti_popl_ds_kfault pushl $0 movw %es,(%esp) .globl doreti_popl_es_fault doreti_popl_es_fault: + testb $SEL_RPL_MASK,TF_CS-TF_ES(%esp) + jz doreti_popl_es_kfault pushl $0 movw %fs,(%esp) .globl doreti_popl_fs_fault doreti_popl_fs_fault: + testb $SEL_RPL_MASK,TF_CS-TF_FS(%esp) + jz doreti_popl_fs_kfault sti movl $0,TF_ERR(%esp) /* XXX should be the error code */ movl $T_PROTFLT,TF_TRAPNO(%esp) jmp alltraps_with_regs_pushed + +doreti_popl_ds_kfault: + movl $0,(%esp) + jmp doreti_popl_ds +doreti_popl_es_kfault: + movl $0,(%esp) + jmp doreti_popl_es +doreti_popl_fs_kfault: + movl $0,(%esp) + jmp doreti_popl_fs + #ifdef HWPMC_HOOKS doreti_nmi: /* diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 8390e5c517ed..c9c5357abebd 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -88,7 +88,6 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_PFLAGS, offsetof(struct thread, td_pflags)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(TD_MD, offsetof(struct thread, td_md)); -ASSYM(TD_TID, offsetof(struct thread, td_tid)); ASSYM(TDP_CALLCHAIN, TDP_CALLCHAIN); @@ -156,11 +155,15 @@ ASSYM(PCB_IDT, offsetof(struct pcb, pcb_idt)); ASSYM(PCB_LDT, offsetof(struct pcb, pcb_ldt)); ASSYM(PCB_TR, offsetof(struct pcb, pcb_tr)); +ASSYM(TF_FS, offsetof(struct trapframe, tf_fs)); +ASSYM(TF_ES, offsetof(struct trapframe, tf_es)); +ASSYM(TF_DS, offsetof(struct trapframe, tf_ds)); ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); ASSYM(TF_EIP, offsetof(struct trapframe, tf_eip)); ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags)); + ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); #ifdef COMPAT_43 ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 910392921928..41d16510ae71 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1132,6 +1132,15 @@ exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) else mtx_unlock_spin(&dt_lock); + /* + * Reset the fs and gs bases. The values from the old address + * space do not make sense for the new program. In particular, + * gsbase might be the TLS base for the old program but the new + * program has no TLS now. + */ + set_fsbase(td, 0); + set_gsbase(td, 0); + bzero((char *)regs, sizeof(struct trapframe)); regs->tf_eip = imgp->entry_addr; regs->tf_esp = stack; @@ -2842,7 +2851,6 @@ static int set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate, size_t xfpustate_len) { - union savefpu *fpstate; int error; if (mcp->mc_fpformat == _MC_FPFMT_NODEV) @@ -2856,10 +2864,8 @@ set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate, error = 0; } else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || mcp->mc_ownedfp == _MC_FPOWNED_PCB) { - fpstate = (union savefpu *)&mcp->mc_fpstate; - if (cpu_fxsr) - fpstate->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask; - error = npxsetregs(td, fpstate, xfpustate, xfpustate_len); + error = npxsetregs(td, (union savefpu *)&mcp->mc_fpstate, + xfpustate, xfpustate_len); } else return (EINVAL); return (error); diff --git a/sys/i386/i386/minidump_machdep.c b/sys/i386/i386/minidump_machdep.c index d28a64f52fc3..689982af81d6 100644 --- a/sys/i386/i386/minidump_machdep.c +++ b/sys/i386/i386/minidump_machdep.c @@ -54,7 +54,6 @@ uint32_t *vm_page_dump; int vm_page_dump_size; static struct kerneldumpheader kdh; -static off_t dumplo; /* Handle chunked writes. */ static size_t fragsz; @@ -86,8 +85,7 @@ blk_flush(struct dumperinfo *di) if (fragsz == 0) return (0); - error = dump_write(di, dump_va, 0, dumplo, fragsz); - dumplo += fragsz; + error = dump_append(di, dump_va, 0, fragsz); fragsz = 0; return (error); } @@ -135,10 +133,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) wdog_kern_pat(WD_LASTVAL); if (ptr) { - error = dump_write(di, ptr, 0, dumplo, len); + error = dump_append(di, ptr, 0, len); if (error) return (error); - dumplo += len; ptr += len; sz -= len; } else { @@ -258,7 +255,7 @@ minidumpsys(struct dumperinfo *di) printf("Physical memory: %ju MB\n", ptoa((uintmax_t)physmem) / 1048576); printf("Dumping %llu MB:", (long long)dumpsize >> 20); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -334,7 +331,7 @@ minidumpsys(struct dumperinfo *di) if (error) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index e3e51298efdb..7106648e0170 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -100,6 +100,7 @@ __FBSDID("$FreeBSD$"); #include "opt_cpu.h" #include "opt_pmap.h" #include "opt_smp.h" +#include "opt_vm.h" #include "opt_xbox.h" #include @@ -288,7 +289,9 @@ static void free_pv_entry(pmap_t pmap, pv_entry_t pv); static pv_entry_t get_pv_entry(pmap_t pmap, boolean_t try); static void pmap_pv_demote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); static boolean_t pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); +#if VM_NRESERVLEVEL > 0 static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); +#endif static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); @@ -309,7 +312,9 @@ static boolean_t pmap_is_referenced_pvh(struct md_page *pvh); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static void pmap_kenter_pde(vm_offset_t va, pd_entry_t newpde); static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); +#if VM_NRESERVLEVEL > 0 static void pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); +#endif static boolean_t pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot); static void pmap_pte_attr(pt_entry_t *pte, int cache_bits); @@ -2504,6 +2509,7 @@ pmap_pv_demote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) } while (va < va_last); } +#if VM_NRESERVLEVEL > 0 static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) { @@ -2537,6 +2543,7 @@ pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) pmap_pvh_free(&m->md, pmap, va); } while (va < va_last); } +#endif /* VM_NRESERVLEVEL > 0 */ static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va) @@ -3312,6 +3319,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) PMAP_UNLOCK(pmap); } +#if VM_NRESERVLEVEL > 0 /* * Tries to promote the 512 or 1024, contiguous 4KB page mappings that are * within a single page table page (PTP) to a single 2- or 4MB page mapping. @@ -3448,6 +3456,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) CTR2(KTR_PMAP, "pmap_promote_pde: success for va %#x" " in pmap %p", va, pmap); } +#endif /* VM_NRESERVLEVEL > 0 */ /* * Insert the given physical page (p) at @@ -3664,6 +3673,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, pte_store(pte, newpte); } +#if VM_NRESERVLEVEL > 0 /* * If both the page table page and the reservation are fully * populated, then attempt promotion. @@ -3672,6 +3682,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, pg_ps_enabled && (m->flags & PG_FICTITIOUS) == 0 && vm_reserv_level_iffullpop(m) == 0) pmap_promote_pde(pmap, pde, va); +#endif sched_unpin(); rw_wunlock(&pvh_global_lock); diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index 00edf7d864d3..4562c7ed87f4 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -258,7 +258,6 @@ sw1: movl %eax,(%esp) movl %edx, PCPU(CURPCB) - movl TD_TID(%ecx),%eax movl %ecx, PCPU(CURTHREAD) /* into next thread */ /* @@ -279,6 +278,10 @@ sw1: pushl %edx /* Preserve pointer to pcb. */ addl $P_MD,%eax /* Pointer to mdproc is arg. */ pushl %eax + /* + * Holding dt_lock prevents context switches, so dt_lock cannot + * be held now and set_user_ldt() will not deadlock acquiring it. + */ call set_user_ldt addl $4,%esp popl %edx diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 3afed49c7b3b..a2beccfecc4f 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -68,10 +69,10 @@ __FBSDID("$FreeBSD$"); #define NULL_LDT_BASE ((caddr_t)NULL) #ifdef SMP -static void set_user_ldt_rv(struct vmspace *vmsp); +static void set_user_ldt_rv(void *arg); #endif static int i386_set_ldt_data(struct thread *, int start, int num, - union descriptor *descs); + union descriptor *descs); static int i386_ldt_grow(struct thread *td, int len); void @@ -90,6 +91,37 @@ fill_based_sd(struct segment_descriptor *sdp, uint32_t base) sdp->sd_gran = 1; } +/* + * Construct special descriptors for "base" selectors. Store them in + * the PCB for later use by cpu_switch(). Store them in the GDT for + * more immediate use. The GDT entries are part of the current + * context. Callers must load related segment registers to complete + * setting up the current context. + */ +void +set_fsbase(struct thread *td, uint32_t base) +{ + struct segment_descriptor sd; + + fill_based_sd(&sd, base); + critical_enter(); + td->td_pcb->pcb_fsd = sd; + PCPU_GET(fsgs_gdt)[0] = sd; + critical_exit(); +} + +void +set_gsbase(struct thread *td, uint32_t base) +{ + struct segment_descriptor sd; + + fill_based_sd(&sd, base); + critical_enter(); + td->td_pcb->pcb_gsd = sd; + PCPU_GET(fsgs_gdt)[1] = sd; + critical_exit(); +} + #ifndef _SYS_SYSPROTO_H_ struct sysarch_args { int op; @@ -108,7 +140,7 @@ sysarch(struct thread *td, struct sysarch_args *uap) struct i386_get_xfpustate xfpu; } kargs; uint32_t base; - struct segment_descriptor sd, *sdp; + struct segment_descriptor *sdp; AUDIT_ARG_CMD(uap->op); @@ -153,8 +185,6 @@ sysarch(struct thread *td, struct sysarch_args *uap) if ((error = copyin(uap->parms, &kargs.largs, sizeof(struct i386_ldt_args))) != 0) return (error); - if (kargs.largs.num > MAX_LD || kargs.largs.num <= 0) - return (EINVAL); break; case I386_GET_XFPUSTATE: if ((error = copyin(uap->parms, &kargs.xfpu, @@ -165,14 +195,15 @@ sysarch(struct thread *td, struct sysarch_args *uap) break; } - switch(uap->op) { + switch (uap->op) { case I386_GET_LDT: error = i386_get_ldt(td, &kargs.largs); break; case I386_SET_LDT: if (kargs.largs.descs != NULL) { - lp = (union descriptor *)malloc( - kargs.largs.num * sizeof(union descriptor), + if (kargs.largs.num > MAX_LD) + return (EINVAL); + lp = malloc(kargs.largs.num * sizeof(union descriptor), M_TEMP, M_WAITOK); error = copyin(kargs.largs.descs, lp, kargs.largs.num * sizeof(union descriptor)); @@ -204,16 +235,11 @@ sysarch(struct thread *td, struct sysarch_args *uap) error = copyin(uap->parms, &base, sizeof(base)); if (error == 0) { /* - * Construct a descriptor and store it in the pcb for - * the next context switch. Also store it in the gdt - * so that the load of tf_fs into %fs will activate it - * at return to userland. + * Construct the special descriptor for fsbase + * and arrange for doreti to load its selector + * soon enough. */ - fill_based_sd(&sd, base); - critical_enter(); - td->td_pcb->pcb_fsd = sd; - PCPU_GET(fsgs_gdt)[0] = sd; - critical_exit(); + set_fsbase(td, base); td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL); } break; @@ -226,15 +252,11 @@ sysarch(struct thread *td, struct sysarch_args *uap) error = copyin(uap->parms, &base, sizeof(base)); if (error == 0) { /* - * Construct a descriptor and store it in the pcb for - * the next context switch. Also store it in the gdt - * because we have to do a load_gs() right now. + * Construct the special descriptor for gsbase. + * The selector is loaded immediately, since we + * normally only reload %gs on context switches. */ - fill_based_sd(&sd, base); - critical_enter(); - td->td_pcb->pcb_gsd = sd; - PCPU_GET(fsgs_gdt)[1] = sd; - critical_exit(); + set_gsbase(td, base); load_gs(GSEL(GUGS_SEL, SEL_UPL)); } break; @@ -383,41 +405,40 @@ i386_get_ioperm(td, uap) * Update the GDT entry pointing to the LDT to point to the LDT of the * current process. Manage dt_lock holding/unholding autonomously. */ +static void +set_user_ldt_locked(struct mdproc *mdp) +{ + struct proc_ldt *pldt; + int gdt_idx; + + mtx_assert(&dt_lock, MA_OWNED); + + pldt = mdp->md_ldt; + gdt_idx = GUSERLDT_SEL; + gdt_idx += PCPU_GET(cpuid) * NGDT; /* always 0 on UP */ + gdt[gdt_idx].sd = pldt->ldt_sd; + lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); + PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL)); +} + void set_user_ldt(struct mdproc *mdp) { - struct proc_ldt *pldt; - int dtlocked; - dtlocked = 0; - if (!mtx_owned(&dt_lock)) { - mtx_lock_spin(&dt_lock); - dtlocked = 1; - } - - pldt = mdp->md_ldt; -#ifdef SMP - gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd; -#else - gdt[GUSERLDT_SEL].sd = pldt->ldt_sd; -#endif - lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); - PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL)); - if (dtlocked) - mtx_unlock_spin(&dt_lock); + mtx_lock_spin(&dt_lock); + set_user_ldt_locked(mdp); + mtx_unlock_spin(&dt_lock); } #ifdef SMP static void -set_user_ldt_rv(struct vmspace *vmsp) +set_user_ldt_rv(void *arg) { - struct thread *td; + struct proc *p; - td = curthread; - if (vmsp != td->td_proc->p_vmspace) - return; - - set_user_ldt(&td->td_proc->p_md); + p = curproc; + if (arg == p->p_vmspace) + set_user_ldt(&p->p_md); } #endif @@ -431,8 +452,7 @@ user_ldt_alloc(struct mdproc *mdp, int len) mtx_assert(&dt_lock, MA_OWNED); mtx_unlock_spin(&dt_lock); - new_ldt = malloc(sizeof(struct proc_ldt), - M_SUBPROC, M_WAITOK); + new_ldt = malloc(sizeof(struct proc_ldt), M_SUBPROC, M_WAITOK); new_ldt->ldt_len = len = NEW_MAX_LD(len); new_ldt->ldt_base = (caddr_t)kmem_malloc(kernel_arena, @@ -462,10 +482,11 @@ user_ldt_alloc(struct mdproc *mdp, int len) void user_ldt_free(struct thread *td) { - struct mdproc *mdp = &td->td_proc->p_md; + struct mdproc *mdp; struct proc_ldt *pldt; mtx_assert(&dt_lock, MA_OWNED); + mdp = &td->td_proc->p_md; if ((pldt = mdp->md_ldt) == NULL) { mtx_unlock_spin(&dt_lock); return; @@ -501,61 +522,55 @@ user_ldt_deref(struct proc_ldt *pldt) * the OS-specific one. */ int -i386_get_ldt(td, uap) - struct thread *td; - struct i386_ldt_args *uap; +i386_get_ldt(struct thread *td, struct i386_ldt_args *uap) { - int error = 0; struct proc_ldt *pldt; - int nldt, num; - union descriptor *lp; + char *data; + u_int nldt, num; + int error; -#ifdef DEBUG - printf("i386_get_ldt: start=%d num=%d descs=%p\n", +#ifdef DEBUG + printf("i386_get_ldt: start=%u num=%u descs=%p\n", uap->start, uap->num, (void *)uap->descs); #endif + num = min(uap->num, MAX_LD); + data = malloc(num * sizeof(union descriptor), M_TEMP, M_WAITOK); mtx_lock_spin(&dt_lock); - if ((pldt = td->td_proc->p_md.md_ldt) != NULL) { - nldt = pldt->ldt_len; - lp = &((union descriptor *)(pldt->ldt_base))[uap->start]; - mtx_unlock_spin(&dt_lock); - num = min(uap->num, nldt); + pldt = td->td_proc->p_md.md_ldt; + nldt = pldt != NULL ? pldt->ldt_len : nitems(ldt); + if (uap->start >= nldt) { + num = 0; } else { - mtx_unlock_spin(&dt_lock); - nldt = sizeof(ldt)/sizeof(ldt[0]); - num = min(uap->num, nldt); - lp = &ldt[uap->start]; + num = min(num, nldt - uap->start); + bcopy(pldt != NULL ? + &((union descriptor *)(pldt->ldt_base))[uap->start] : + &ldt[uap->start], data, num * sizeof(union descriptor)); } - - if ((uap->start > (unsigned int)nldt) || - ((unsigned int)num > (unsigned int)nldt) || - ((unsigned int)(uap->start + num) > (unsigned int)nldt)) - return(EINVAL); - - error = copyout(lp, uap->descs, num * sizeof(union descriptor)); - if (!error) + mtx_unlock_spin(&dt_lock); + error = copyout(data, uap->descs, num * sizeof(union descriptor)); + if (error == 0) td->td_retval[0] = num; - - return(error); + free(data, M_TEMP); + return (error); } int -i386_set_ldt(td, uap, descs) - struct thread *td; - struct i386_ldt_args *uap; - union descriptor *descs; +i386_set_ldt(struct thread *td, struct i386_ldt_args *uap, + union descriptor *descs) { - int error = 0, i; - int largest_ld; - struct mdproc *mdp = &td->td_proc->p_md; + struct mdproc *mdp; struct proc_ldt *pldt; union descriptor *dp; + u_int largest_ld, i; + int error; -#ifdef DEBUG - printf("i386_set_ldt: start=%d num=%d descs=%p\n", +#ifdef DEBUG + printf("i386_set_ldt: start=%u num=%u descs=%p\n", uap->start, uap->num, (void *)uap->descs); #endif + error = 0; + mdp = &td->td_proc->p_md; if (descs == NULL) { /* Free descriptors */ @@ -567,8 +582,6 @@ i386_set_ldt(td, uap, descs) uap->start = NLDT; uap->num = MAX_LD - NLDT; } - if (uap->num == 0) - return (EINVAL); mtx_lock_spin(&dt_lock); if ((pldt = mdp->md_ldt) == NULL || uap->start >= pldt->ldt_len) { @@ -578,19 +591,18 @@ i386_set_ldt(td, uap, descs) largest_ld = uap->start + uap->num; if (largest_ld > pldt->ldt_len) largest_ld = pldt->ldt_len; - i = largest_ld - uap->start; - bzero(&((union descriptor *)(pldt->ldt_base))[uap->start], - sizeof(union descriptor) * i); + for (i = uap->start; i < largest_ld; i++) + atomic_store_rel_64(&((uint64_t *)(pldt->ldt_base))[i], + 0); mtx_unlock_spin(&dt_lock); return (0); } - if (!(uap->start == LDT_AUTO_ALLOC && uap->num == 1)) { + if (uap->start != LDT_AUTO_ALLOC || uap->num != 1) { /* verify range of descriptors to modify */ largest_ld = uap->start + uap->num; - if (uap->start >= MAX_LD || largest_ld > MAX_LD) { + if (uap->start >= MAX_LD || largest_ld > MAX_LD) return (EINVAL); - } } /* Check descriptors for access violations */ @@ -616,12 +628,7 @@ i386_set_ldt(td, uap, descs) case SDT_SYS386TGT: /* system 386 trap gate */ case SDT_SYS286CGT: /* system 286 call gate */ case SDT_SYS386CGT: /* system 386 call gate */ - /* I can't think of any reason to allow a user proc - * to create a segment of these types. They are - * for OS use only. - */ return (EACCES); - /*NOTREACHED*/ /* memory segment types */ case SDT_MEMEC: /* memory execute only conforming */ @@ -646,12 +653,11 @@ i386_set_ldt(td, uap, descs) case SDT_MEMERA: /* memory execute read accessed */ break; default: - return(EINVAL); - /*NOTREACHED*/ + return (EINVAL); } /* Only user (ring-3) descriptors may be present. */ - if ((dp->sd.sd_p != 0) && (dp->sd.sd_dpl != SEL_UPL)) + if (dp->sd.sd_p != 0 && dp->sd.sd_dpl != SEL_UPL) return (EACCES); } @@ -702,27 +708,37 @@ i386_set_ldt(td, uap, descs) static int i386_set_ldt_data(struct thread *td, int start, int num, - union descriptor *descs) + union descriptor *descs) { - struct mdproc *mdp = &td->td_proc->p_md; - struct proc_ldt *pldt = mdp->md_ldt; + struct mdproc *mdp; + struct proc_ldt *pldt; + uint64_t *dst, *src; + int i; mtx_assert(&dt_lock, MA_OWNED); - /* Fill in range */ - bcopy(descs, - &((union descriptor *)(pldt->ldt_base))[start], - num * sizeof(union descriptor)); + mdp = &td->td_proc->p_md; + pldt = mdp->md_ldt; + dst = (uint64_t *)(pldt->ldt_base); + src = (uint64_t *)descs; + + /* + * Atomic(9) is used only to get 64bit atomic store with + * cmpxchg8b when available. There is no op without release + * semantic. + */ + for (i = 0; i < num; i++) + atomic_store_rel_64(&dst[start + i], src[i]); return (0); } static int i386_ldt_grow(struct thread *td, int len) { - struct mdproc *mdp = &td->td_proc->p_md; + struct mdproc *mdp; struct proc_ldt *new_ldt, *pldt; - caddr_t old_ldt_base = NULL_LDT_BASE; - int old_ldt_len = 0; + caddr_t old_ldt_base; + int old_ldt_len; mtx_assert(&dt_lock, MA_OWNED); @@ -731,6 +747,10 @@ i386_ldt_grow(struct thread *td, int len) if (len < NLDT + 1) len = NLDT + 1; + mdp = &td->td_proc->p_md; + old_ldt_base = NULL_LDT_BASE; + old_ldt_len = 0; + /* Allocate a user ldt. */ if ((pldt = mdp->md_ldt) == NULL || len > pldt->ldt_len) { new_ldt = user_ldt_alloc(mdp, len); @@ -772,10 +792,10 @@ i386_ldt_grow(struct thread *td, int len) * to acquire it. */ mtx_unlock_spin(&dt_lock); - smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, - NULL, td->td_proc->p_vmspace); + smp_rendezvous(NULL, set_user_ldt_rv, NULL, + td->td_proc->p_vmspace); #else - set_user_ldt(&td->td_proc->p_md); + set_user_ldt_locked(&td->td_proc->p_md); mtx_unlock_spin(&dt_lock); #endif if (old_ldt_base != NULL_LDT_BASE) { diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index a0a9473b3bdf..562cdfdd756c 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -524,6 +524,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, (((int)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4; td->td_frame->tf_eip = (int)entry; + /* Return address sentinel value to stop stack unwinding. */ + suword((void *)td->td_frame->tf_esp, 0); + /* Pass the argument to the entry point. */ suword((void *)(td->td_frame->tf_esp + sizeof(void *)), (int)arg); diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h index a9cac104abe5..2795faa86d4b 100644 --- a/sys/i386/include/asmacros.h +++ b/sys/i386/include/asmacros.h @@ -153,13 +153,6 @@ pushl $0 ; \ movw %fs,(%esp) -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp - /* * Access per-CPU data. */ diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index 2ca8c856fdf6..7da2c1163fc4 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -66,6 +66,8 @@ void init_AMD_Elan_sc520(void); vm_paddr_t kvtop(void *addr); void panicifcpuunsupported(void); void ppro_reenable_apic(void); +void set_fsbase(struct thread *td, uint32_t base); +void set_gsbase(struct thread *td, uint32_t base); void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec); union savefpu *get_pcb_user_save_td(struct thread *td); union savefpu *get_pcb_user_save_pcb(struct pcb *pcb); diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index 8b27ee7edcab..d2a4bd99c391 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -1045,6 +1045,8 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, if (!hw_float) return (ENXIO); + if (cpu_fxsr) + addr->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask; pcb = td->td_pcb; critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf index e2aa04638cc9..61a8817af810 100644 --- a/sys/kern/capabilities.conf +++ b/sys/kern/capabilities.conf @@ -488,6 +488,7 @@ poll ## ## Allow I/O-related file descriptors, subject to capability rights. ## +posix_fallocate pread preadv diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index c3695da3b0e2..8ff3d58c1af2 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1110,9 +1110,7 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); -#ifdef AT_EHDRFLAGS AUXARGS_ENTRY(pos, AT_EHDRFLAGS, args->hdr_eflags); -#endif if (imgp->execpathp != 0) AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp); AUXARGS_ENTRY(pos, AT_OSRELDATE, @@ -1133,6 +1131,10 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : imgp->sysent->sv_stackprot); + if (imgp->sysent->sv_hwcap != NULL) + AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap); + if (imgp->sysent->sv_hwcap2 != NULL) + AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c index aaf521cf251e..bc21714aab29 100644 --- a/sys/kern/imgact_shell.c +++ b/sys/kern/imgact_shell.c @@ -97,8 +97,7 @@ CTASSERT(MAXSHELLCMDLEN >= MAXINTERP + 3); * 6.x branch on May 28, 2005 (matching __FreeBSD_version 600029). */ int -exec_shell_imgact(imgp) - struct image_params *imgp; +exec_shell_imgact(struct image_params *imgp) { const char *image_header = imgp->image_header; const char *ihp, *interpb, *interpe, *maxp, *optb, *opte, *fname; @@ -125,7 +124,7 @@ exec_shell_imgact(imgp) * However, we don't know how far into the page the contents are * valid -- the actual file might be much shorter than the page. * So find out the file size. - */ + */ error = VOP_GETATTR(imgp->vp, &vattr, imgp->proc->p_ucred); if (error) return (error); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index f71ba6efaf55..62d23be77de7 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -420,6 +420,10 @@ proc0_init(void *dummy __unused) struct proc *p; struct thread *td; struct ucred *newcred; + struct uidinfo tmpuinfo; + struct loginclass tmplc = { + .lc_name = "", + }; vm_paddr_t pageablemem; int i; @@ -502,10 +506,17 @@ proc0_init(void *dummy __unused) /* Create credentials. */ newcred = crget(); newcred->cr_ngroups = 1; /* group 0 */ + /* A hack to prevent uifind from tripping over NULL pointers. */ + curthread->td_ucred = newcred; + tmpuinfo.ui_uid = 1; + newcred->cr_uidinfo = newcred->cr_ruidinfo = &tmpuinfo; newcred->cr_uidinfo = uifind(0); newcred->cr_ruidinfo = uifind(0); - newcred->cr_prison = &prison0; + newcred->cr_loginclass = &tmplc; newcred->cr_loginclass = loginclass_find("default"); + /* End hack. creds get properly set later with thread_cow_get_proc */ + curthread->td_ucred = NULL; + newcred->cr_prison = &prison0; proc_set_cred_init(p, newcred); #ifdef AUDIT audit_cred_kproc0(newcred); diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 125587d50574..58eedb2a058a 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -581,7 +581,7 @@ struct sysent sysent[] = { { AS(rctl_get_limits_args), (sy_call_t *)sys_rctl_get_limits, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 527 = rctl_get_limits */ { AS(rctl_add_rule_args), (sy_call_t *)sys_rctl_add_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 528 = rctl_add_rule */ { AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */ - { AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = posix_fallocate */ + { AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_POSIX_FALLOCATE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 530 = posix_fallocate */ { AS(posix_fadvise_args), (sy_call_t *)sys_posix_fadvise, AUE_POSIX_FADVISE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = posix_fadvise */ { AS(wait6_args), (sy_call_t *)sys_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = wait6 */ { AS(cap_rights_limit_args), (sy_call_t *)sys_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 533 = cap_rights_limit */ diff --git a/sys/kern/kern_dump.c b/sys/kern/kern_dump.c index a8e32a75a98b..d2914966957a 100644 --- a/sys/kern/kern_dump.c +++ b/sys/kern/kern_dump.c @@ -51,8 +51,6 @@ CTASSERT(sizeof(struct kerneldumpheader) == 512); #define MD_ALIGN(x) roundup2((off_t)(x), PAGE_SIZE) -off_t dumplo; - /* Handle buffered writes. */ static size_t fragsz; @@ -122,11 +120,9 @@ dumpsys_buf_seek(struct dumperinfo *di, size_t sz) while (sz > 0) { nbytes = MIN(sz, sizeof(buf)); - error = dump_write(di, buf, 0, dumplo, nbytes); + error = dump_append(di, buf, 0, nbytes); if (error) return (error); - dumplo += nbytes; - sz -= nbytes; } @@ -148,11 +144,9 @@ dumpsys_buf_write(struct dumperinfo *di, char *ptr, size_t sz) ptr += len; sz -= len; if (fragsz == di->blocksize) { - error = dump_write(di, di->blockbuf, 0, dumplo, - di->blocksize); + error = dump_append(di, di->blockbuf, 0, di->blocksize); if (error) return (error); - dumplo += di->blocksize; fragsz = 0; } } @@ -167,8 +161,7 @@ dumpsys_buf_flush(struct dumperinfo *di) if (fragsz == 0) return (0); - error = dump_write(di, di->blockbuf, 0, dumplo, di->blocksize); - dumplo += di->blocksize; + error = dump_append(di, di->blockbuf, 0, di->blocksize); fragsz = 0; return (error); } @@ -216,11 +209,10 @@ dumpsys_cb_dumpdata(struct dump_pa *mdp, int seqnr, void *arg) wdog_kern_pat(WD_LASTVAL); #endif - error = dump_write(di, va, 0, dumplo, sz); + error = dump_append(di, va, 0, sz); dumpsys_unmap_chunk(pa, chunk, va); if (error) break; - dumplo += sz; pgs -= chunk; pa += sz; @@ -347,7 +339,7 @@ dumpsys_generic(struct dumperinfo *di) printf("Dumping %ju MB (%d chunks)\n", (uintmax_t)dumpsize >> 20, ehdr.e_phnum - DUMPSYS_NUM_AUX_HDRS); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -369,19 +361,18 @@ dumpsys_generic(struct dumperinfo *di) * All headers are written using blocked I/O, so we know the * current offset is (still) block aligned. Skip the alignement * in the file to have the segment contents aligned at page - * boundary. We cannot use MD_ALIGN on dumplo, because we don't - * care and may very well be unaligned within the dump device. + * boundary. */ error = dumpsys_buf_seek(di, (size_t)hdrgap); if (error) goto fail; - /* Dump memory chunks (updates dumplo) */ + /* Dump memory chunks. */ error = dumpsys_foreach_chunk(dumpsys_cb_dumpdata, di); if (error < 0) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 953da2d908a7..3c594da1b2c5 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -849,28 +849,23 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p) p->p_args = newargs; newargs = NULL; + PROC_UNLOCK(p); + #ifdef HWPMC_HOOKS /* * Check if system-wide sampling is in effect or if the * current process is using PMCs. If so, do exec() time * processing. This processing needs to happen AFTER the * P_INEXEC flag is cleared. - * - * The proc lock needs to be released before taking the PMC - * SX. */ if (PMC_SYSTEM_SAMPLING_ACTIVE() || PMC_PROC_IS_USING_PMCS(p)) { - PROC_UNLOCK(p); VOP_UNLOCK(imgp->vp, 0); pe.pm_credentialschanged = credential_changing; pe.pm_entryaddr = imgp->entry_addr; PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe); vn_lock(imgp->vp, LK_SHARED | LK_RETRY); - } else - PROC_UNLOCK(p); -#else /* !HWPMC_HOOKS */ - PROC_UNLOCK(p); + } #endif /* Set values passed into the program in registers. */ @@ -905,10 +900,12 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p) free(imgp->freepath, M_TEMP); if (error == 0) { - PROC_LOCK(p); - if (p->p_ptevents & PTRACE_EXEC) - td->td_dbgflags |= TDB_EXEC; - PROC_UNLOCK(p); + if (p->p_ptevents & PTRACE_EXEC) { + PROC_LOCK(p); + if (p->p_ptevents & PTRACE_EXEC) + td->td_dbgflags |= TDB_EXEC; + PROC_UNLOCK(p); + } /* * Stop the process here if its stop event mask has diff --git a/sys/kern/kern_gzio.c b/sys/kern/kern_gzio.c index cee21f0655b1..f659b9bb7d7a 100644 --- a/sys/kern/kern_gzio.c +++ b/sys/kern/kern_gzio.c @@ -60,7 +60,6 @@ struct gzio_stream * gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg) { struct gzio_stream *s; - uint8_t *hdr; int error; if (bufsz < KERN_GZ_HDRLEN) @@ -72,7 +71,6 @@ gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg) s->gz_bufsz = bufsz; s->gz_buffer = gz_alloc(NULL, 1, s->gz_bufsz); s->gz_mode = mode; - s->gz_crc = ~0U; s->gz_cb = cb; s->gz_arg = arg; @@ -87,6 +85,26 @@ gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg) if (error != 0) goto fail; + gzio_reset(s); + + return (s); + +fail: + gz_free(NULL, s->gz_buffer); + gz_free(NULL, s); + return (NULL); +} + +void +gzio_reset(struct gzio_stream *s) +{ + uint8_t *hdr; + + (void)deflateReset(&s->gz_stream); + + s->gz_off = 0; + s->gz_crc = ~0U; + s->gz_stream.avail_out = s->gz_bufsz; s->gz_stream.next_out = s->gz_buffer; @@ -99,13 +117,6 @@ gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg) hdr[9] = OS_CODE; s->gz_stream.next_out += KERN_GZ_HDRLEN; s->gz_stream.avail_out -= KERN_GZ_HDRLEN; - - return (s); - -fail: - gz_free(NULL, s->gz_buffer); - gz_free(NULL, s); - return (NULL); } int diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 06cd3c0a5750..49914bb9bd52 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -288,7 +288,7 @@ linker_file_sysuninit(linker_file_t lf) } static void -linker_file_register_sysctls(linker_file_t lf) +linker_file_register_sysctls(linker_file_t lf, bool enable) { struct sysctl_oid **start, **stop, **oidp; @@ -298,13 +298,39 @@ linker_file_register_sysctls(linker_file_t lf) sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) + return; + + sx_xunlock(&kld_sx); + sysctl_wlock(); + for (oidp = start; oidp < stop; oidp++) { + if (enable) + sysctl_register_oid(*oidp); + else + sysctl_register_disabled_oid(*oidp); + } + sysctl_wunlock(); + sx_xlock(&kld_sx); +} + +static void +linker_file_enable_sysctls(linker_file_t lf) +{ + struct sysctl_oid **start, **stop, **oidp; + + KLD_DPF(FILE, + ("linker_file_enable_sysctls: enable SYSCTLs for %s\n", + lf->filename)); + + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) return; sx_xunlock(&kld_sx); sysctl_wlock(); for (oidp = start; oidp < stop; oidp++) - sysctl_register_oid(*oidp); + sysctl_enable_oid(*oidp); sysctl_wunlock(); sx_xlock(&kld_sx); } @@ -430,7 +456,7 @@ linker_load_file(const char *filename, linker_file_t *result) return (error); } modules = !TAILQ_EMPTY(&lf->modules); - linker_file_register_sysctls(lf); + linker_file_register_sysctls(lf, false); linker_file_sysinit(lf); lf->flags |= LINKER_FILE_LINKED; @@ -443,6 +469,7 @@ linker_load_file(const char *filename, linker_file_t *result) linker_file_unload(lf, LINKER_UNLOAD_FORCE); return (ENOEXEC); } + linker_file_enable_sysctls(lf); EVENTHANDLER_INVOKE(kld_load, lf); *result = lf; return (0); @@ -692,8 +719,8 @@ linker_file_unload(linker_file_t file, int flags) */ if (file->flags & LINKER_FILE_LINKED) { file->flags &= ~LINKER_FILE_LINKED; - linker_file_sysuninit(file); linker_file_unregister_sysctls(file); + linker_file_sysuninit(file); } TAILQ_REMOVE(&linker_files, file, link); @@ -1642,7 +1669,7 @@ linker_preload(void *arg) if (linker_file_lookup_set(lf, "sysinit_set", &si_start, &si_stop, NULL) == 0) sysinit_add(si_start, si_stop); - linker_file_register_sysctls(lf); + linker_file_register_sysctls(lf, true); lf->flags |= LINKER_FILE_LINKED; continue; fail: diff --git a/sys/kern/kern_loginclass.c b/sys/kern/kern_loginclass.c index 07ef910a5519..d74dd6553698 100644 --- a/sys/kern/kern_loginclass.c +++ b/sys/kern/kern_loginclass.c @@ -135,6 +135,12 @@ loginclass_find(const char *name) if (name[0] == '\0' || strlen(name) >= MAXLOGNAME) return (NULL); + lc = curthread->td_ucred->cr_loginclass; + if (strcmp(name, lc->lc_name) == 0) { + loginclass_hold(lc); + return (lc); + } + rw_rlock(&loginclasses_lock); lc = loginclass_lookup(name); rw_runlock(&loginclasses_lock); diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 0d0c1c86b168..718c141ec383 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -504,7 +504,7 @@ mb_ctor_clust(void *mem, int size, void *arg, int how) #endif m = (struct mbuf *)arg; if (m != NULL) { - m->m_ext.ext_buf = (caddr_t)mem; + m->m_ext.ext_buf = (char *)mem; m->m_data = m->m_ext.ext_buf; m->m_flags |= M_EXT; m->m_ext.ext_free = NULL; @@ -675,28 +675,18 @@ mb_free_ext(struct mbuf *m) uma_zfree(zone_mbuf, mref); break; case EXT_SFBUF: - sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2); - uma_zfree(zone_mbuf, mref); - break; - case EXT_SFBUF_NOCACHE: - sf_ext_free_nocache(m->m_ext.ext_arg1, - m->m_ext.ext_arg2); - uma_zfree(zone_mbuf, mref); - break; case EXT_NET_DRV: case EXT_MOD_TYPE: case EXT_DISPOSABLE: - KASSERT(m->m_ext.ext_free != NULL, + KASSERT(mref->m_ext.ext_free != NULL, ("%s: ext_free not set", __func__)); - (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, - m->m_ext.ext_arg2); + mref->m_ext.ext_free(mref); uma_zfree(zone_mbuf, mref); break; case EXT_EXTREF: KASSERT(m->m_ext.ext_free != NULL, ("%s: ext_free not set", __func__)); - (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, - m->m_ext.ext_arg2); + m->m_ext.ext_free(m); break; default: KASSERT(m->m_ext.ext_type == 0, @@ -918,9 +908,8 @@ m_getm2(struct mbuf *m, int len, int how, short type, int flags) * Nothing. */ void -m_extadd(struct mbuf *mb, caddr_t buf, u_int size, - void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2, - int flags, int type) +m_extadd(struct mbuf *mb, char *buf, u_int size, m_ext_free_t freef, + void *arg1, void *arg2, int flags, int type) { KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__)); diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 72a582f3534e..435cbe753bf7 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -217,7 +217,7 @@ owner_mtx(const struct lock_object *lock, struct thread **owner) m = (const struct mtx *)lock; x = m->mtx_lock; *owner = (struct thread *)(x & ~MTX_FLAGMASK); - return (x != MTX_UNOWNED); + return (*owner != NULL); } #endif @@ -248,7 +248,7 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line) tid = (uintptr_t)curthread; v = MTX_UNOWNED; if (!_mtx_obtain_lock_fetch(m, &v, tid)) - _mtx_lock_sleep(m, v, tid, opts, file, line); + _mtx_lock_sleep(m, v, opts, file, line); else LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire, m, 0, 0, file, line); @@ -289,9 +289,9 @@ __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file, int line) { struct mtx *m; - - if (SCHEDULER_STOPPED()) - return; +#ifdef SMP + uintptr_t tid, v; +#endif m = mtxlock2mtx(c); @@ -308,7 +308,18 @@ __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file, opts &= ~MTX_RECURSE; WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL); +#ifdef SMP + spinlock_enter(); + tid = (uintptr_t)curthread; + v = MTX_UNOWNED; + if (!_mtx_obtain_lock_fetch(m, &v, tid)) + _mtx_lock_spin(m, v, opts, file, line); + else + LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire, + m, 0, 0, file, line); +#else __mtx_lock_spin(m, curthread, opts, file, line); +#endif LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file, line); WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line); @@ -348,9 +359,6 @@ __mtx_unlock_spin_flags(volatile uintptr_t *c, int opts, const char *file, { struct mtx *m; - if (SCHEDULER_STOPPED()) - return; - m = mtxlock2mtx(c); KASSERT(m->mtx_lock != MTX_DESTROYED, @@ -443,15 +451,17 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line) */ #if LOCK_DEBUG > 0 void -__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, - const char *file, int line) +__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, int opts, const char *file, + int line) #else void -__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid) +__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v) #endif { + struct thread *td; struct mtx *m; struct turnstile *ts; + uintptr_t tid; #ifdef ADAPTIVE_MUTEXES volatile struct thread *owner; #endif @@ -473,8 +483,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid) #if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING) int doing_lockprof; #endif - - if (SCHEDULER_STOPPED()) + td = curthread; + tid = (uintptr_t)td; + if (SCHEDULER_STOPPED_TD(td)) return; #if defined(ADAPTIVE_MUTEXES) @@ -486,7 +497,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid) if (__predict_false(v == MTX_UNOWNED)) v = MTX_READ_VALUE(m); - if (__predict_false(lv_mtx_owner(v) == (struct thread *)tid)) { + if (__predict_false(lv_mtx_owner(v) == td)) { KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 || (opts & MTX_RECURSE) != 0, ("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n", @@ -679,12 +690,18 @@ _mtx_lock_spin_failed(struct mtx *m) * This is only called if we need to actually spin for the lock. Recursion * is handled inline. */ +#if LOCK_DEBUG > 0 void -_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, - int opts, const char *file, int line) +_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, int opts, + const char *file, int line) +#else +void +_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v) +#endif { struct mtx *m; struct lock_delay_arg lda; + uintptr_t tid; #ifdef LOCK_PROFILING int contested = 0; uint64_t waittime = 0; @@ -696,10 +713,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int doing_lockprof; #endif - if (SCHEDULER_STOPPED()) - return; - - lock_delay_arg_init(&lda, &mtx_spin_delay); + tid = (uintptr_t)curthread; m = mtxlock2mtx(c); if (__predict_false(v == MTX_UNOWNED)) @@ -710,6 +724,11 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, return; } + if (SCHEDULER_STOPPED()) + return; + + lock_delay_arg_init(&lda, &mtx_spin_delay); + if (LOCK_LOG_TEST(&m->lock_object, opts)) CTR1(KTR_LOCK, "_mtx_lock_spin: %p spinning", m); KTR_STATE1(KTR_SCHED, "thread", sched_tdname((struct thread *)tid), @@ -772,6 +791,66 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, } #endif /* SMP */ +#ifdef INVARIANTS +static void +thread_lock_validate(struct mtx *m, int opts, const char *file, int line) +{ + + KASSERT(m->mtx_lock != MTX_DESTROYED, + ("thread_lock() of destroyed mutex @ %s:%d", file, line)); + KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_spin, + ("thread_lock() of sleep mutex %s @ %s:%d", + m->lock_object.lo_name, file, line)); + if (mtx_owned(m)) + KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0, + ("thread_lock: recursed on non-recursive mutex %s @ %s:%d\n", + m->lock_object.lo_name, file, line)); + WITNESS_CHECKORDER(&m->lock_object, + opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL); +} +#else +#define thread_lock_validate(m, opts, file, line) do { } while (0) +#endif + +#ifndef LOCK_PROFILING +#if LOCK_DEBUG > 0 +void +_thread_lock(struct thread *td, int opts, const char *file, int line) +#else +void +_thread_lock(struct thread *td) +#endif +{ + struct mtx *m; + uintptr_t tid, v; + + tid = (uintptr_t)curthread; + + spinlock_enter(); + m = td->td_lock; + thread_lock_validate(m, 0, file, line); + v = MTX_READ_VALUE(m); + if (__predict_true(v == MTX_UNOWNED)) { + if (__predict_false(!_mtx_obtain_lock(m, tid))) + goto slowpath_unlocked; + } else if (v == tid) { + m->mtx_recurse++; + } else + goto slowpath_unlocked; + if (__predict_true(m == td->td_lock)) { + WITNESS_LOCK(&m->lock_object, LOP_EXCLUSIVE, file, line); + return; + } + if (m->mtx_recurse != 0) + m->mtx_recurse--; + else + _mtx_release_lock_quick(m); +slowpath_unlocked: + spinlock_exit(); + thread_lock_flags_(td, 0, 0, 0); +} +#endif + void thread_lock_flags_(struct thread *td, int opts, const char *file, int line) { @@ -815,17 +894,7 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line) v = MTX_UNOWNED; spinlock_enter(); m = td->td_lock; - KASSERT(m->mtx_lock != MTX_DESTROYED, - ("thread_lock() of destroyed mutex @ %s:%d", file, line)); - KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_spin, - ("thread_lock() of sleep mutex %s @ %s:%d", - m->lock_object.lo_name, file, line)); - if (mtx_owned(m)) - KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0, - ("thread_lock: recursed on non-recursive mutex %s @ %s:%d\n", - m->lock_object.lo_name, file, line)); - WITNESS_CHECKORDER(&m->lock_object, - opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL); + thread_lock_validate(m, opts, file, line); for (;;) { if (_mtx_obtain_lock_fetch(m, &v, tid)) break; diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 72eb06013fe7..53c08f1b8aa2 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -389,23 +389,28 @@ pget(pid_t pid, int flags, struct proc **pp) struct proc *p; int error; - sx_slock(&allproc_lock); - if (pid <= PID_MAX) { - p = pfind_locked(pid); - if (p == NULL && (flags & PGET_NOTWEXIT) == 0) - p = zpfind_locked(pid); - } else if ((flags & PGET_NOTID) == 0) { - p = pfind_tid_locked(pid); + p = curproc; + if (p->p_pid == pid) { + PROC_LOCK(p); } else { - p = NULL; - } - sx_sunlock(&allproc_lock); - if (p == NULL) - return (ESRCH); - if ((flags & PGET_CANSEE) != 0) { - error = p_cansee(curthread, p); - if (error != 0) - goto errout; + sx_slock(&allproc_lock); + if (pid <= PID_MAX) { + p = pfind_locked(pid); + if (p == NULL && (flags & PGET_NOTWEXIT) == 0) + p = zpfind_locked(pid); + } else if ((flags & PGET_NOTID) == 0) { + p = pfind_tid_locked(pid); + } else { + p = NULL; + } + sx_sunlock(&allproc_lock); + if (p == NULL) + return (ESRCH); + if ((flags & PGET_CANSEE) != 0) { + error = p_cansee(curthread, p); + if (error != 0) + goto errout; + } } if ((flags & PGET_CANDEBUG) != 0) { error = p_candebug(curthread, p); @@ -2547,7 +2552,7 @@ sysctl_kern_proc_kstack(SYSCTL_HANDLER_ARGS) return (error); kkstp = malloc(sizeof(*kkstp), M_TEMP, M_WAITOK); - st = stack_create(); + st = stack_create(M_WAITOK); lwpidarray = NULL; PROC_LOCK(p); diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 4cb6f4299600..835c39295e1e 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -1253,6 +1253,18 @@ struct uidinfo * uifind(uid_t uid) { struct uidinfo *new_uip, *uip; + struct ucred *cred; + + cred = curthread->td_ucred; + if (cred->cr_uidinfo->ui_uid == uid) { + uip = cred->cr_uidinfo; + uihold(uip); + return (uip); + } else if (cred->cr_ruidinfo->ui_uid == uid) { + uip = cred->cr_ruidinfo; + uihold(uip); + return (uip); + } rw_rlock(&uihashtbl_lock); uip = uilookup(uid); diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 61e8c3615330..9f0b059280b9 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -414,7 +414,7 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v, #ifdef ADAPTIVE_RWLOCKS volatile struct thread *owner; int spintries = 0; - int i; + int i, n; #endif #ifdef LOCK_PROFILING uint64_t waittime = 0; @@ -488,13 +488,13 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v, KTR_STATE1(KTR_SCHED, "thread", sched_tdname(curthread), "spinning", "lockname:\"%s\"", rw->lock_object.lo_name); - for (i = 0; i < rowner_loops; i++) { + for (i = 0; i < rowner_loops; i += n) { + n = RW_READERS(v); + lock_delay_spin(n); v = RW_READ_VALUE(rw); if ((v & RW_LOCK_READ) == 0 || RW_CAN_READ(td, v)) break; - cpu_spinwait(); } - v = RW_READ_VALUE(rw); #ifdef KDTRACE_HOOKS lda.spin_cnt += rowner_loops - i; #endif @@ -831,7 +831,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, #ifdef ADAPTIVE_RWLOCKS volatile struct thread *owner; int spintries = 0; - int i; + int i, n; #endif uintptr_t x; #ifdef LOCK_PROFILING @@ -842,11 +842,14 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, struct lock_delay_arg lda; #endif #ifdef KDTRACE_HOOKS - uintptr_t state; u_int sleep_cnt = 0; int64_t sleep_time = 0; int64_t all_time = 0; #endif +#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING) + uintptr_t state; + int doing_lockprof; +#endif if (SCHEDULER_STOPPED()) return; @@ -875,10 +878,17 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__, rw->lock_object.lo_name, (void *)rw->rw_lock, file, line); -#ifdef KDTRACE_HOOKS - all_time -= lockstat_nsecs(&rw->lock_object); +#ifdef LOCK_PROFILING + doing_lockprof = 1; state = v; +#elif defined(KDTRACE_HOOKS) + doing_lockprof = lockstat_enabled; + if (__predict_false(doing_lockprof)) { + all_time -= lockstat_nsecs(&rw->lock_object); + state = v; + } #endif + for (;;) { if (v == RW_UNLOCKED) { if (_rw_write_lock_fetch(rw, &v, tid)) @@ -929,14 +939,15 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, KTR_STATE1(KTR_SCHED, "thread", sched_tdname(curthread), "spinning", "lockname:\"%s\"", rw->lock_object.lo_name); - for (i = 0; i < rowner_loops; i++) { - if ((rw->rw_lock & RW_LOCK_WRITE_SPINNER) == 0) + for (i = 0; i < rowner_loops; i += n) { + n = RW_READERS(v); + lock_delay_spin(n); + v = RW_READ_VALUE(rw); + if ((v & RW_LOCK_WRITE_SPINNER) == 0) break; - cpu_spinwait(); } KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread), "running"); - v = RW_READ_VALUE(rw); #ifdef KDTRACE_HOOKS lda.spin_cnt += rowner_loops - i; #endif @@ -1023,6 +1034,10 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, #endif v = RW_READ_VALUE(rw); } +#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING) + if (__predict_true(!doing_lockprof)) + return; +#endif #ifdef KDTRACE_HOOKS all_time += lockstat_nsecs(&rw->lock_object); if (sleep_time) diff --git a/sys/kern/kern_sdt.c b/sys/kern/kern_sdt.c index 5191a88f1bbe..ebbf04e46c82 100644 --- a/sys/kern/kern_sdt.c +++ b/sys/kern/kern_sdt.c @@ -37,6 +37,7 @@ SDT_PROVIDER_DEFINE(sdt); * dtrace_probe() when it loads. */ sdt_probe_func_t sdt_probe_func = sdt_probe_stub; +volatile bool __read_frequently sdt_probes_enabled; /* * This is a stub for probe calls in case kernel DTrace support isn't diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index f107d16ba082..039913508e78 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -62,6 +62,9 @@ __FBSDID("$FreeBSD$"); #include #include +#define EXT_FLAG_SYNC EXT_FLAG_VENDOR1 +#define EXT_FLAG_NOCACHE EXT_FLAG_VENDOR2 + /* * Structure describing a single sendfile(2) I/O, which may consist of * several underlying pager I/Os. @@ -80,7 +83,7 @@ struct sf_io { volatile u_int nios; u_int error; int npages; - struct file *sock_fp; + struct socket *so; struct mbuf *m; vm_page_t pa[]; }; @@ -122,63 +125,66 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW, * Detach mapped page and release resources back to the system. Called * by mbuf(9) code when last reference to a page is freed. */ -void -sf_ext_free(void *arg1, void *arg2) +static void +sendfile_free_page(vm_page_t pg, bool nocache) { - struct sf_buf *sf = arg1; - struct sendfile_sync *sfs = arg2; - vm_page_t pg = sf_buf_page(sf); - - sf_buf_free(sf); vm_page_lock(pg); /* - * Check for the object going away on us. This can - * happen since we don't hold a reference to it. - * If so, we're responsible for freeing the page. + * In either case check for the object going away on us. This can + * happen since we don't hold a reference to it. If so, we're + * responsible for freeing the page. In 'noncache' case try to free + * the page, but only if it is cheap to. */ - if (vm_page_unwire(pg, PQ_INACTIVE) && pg->object == NULL) - vm_page_free(pg); - vm_page_unlock(pg); - - if (sfs != NULL) { - mtx_lock(&sfs->mtx); - KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0")); - if (--sfs->count == 0) - cv_signal(&sfs->cv); - mtx_unlock(&sfs->mtx); - } -} - -/* - * Same as above, but forces the page to be detached from the object - * and go into free pool. - */ -void -sf_ext_free_nocache(void *arg1, void *arg2) -{ - struct sf_buf *sf = arg1; - struct sendfile_sync *sfs = arg2; - vm_page_t pg = sf_buf_page(sf); - - sf_buf_free(sf); - - vm_page_lock(pg); - if (vm_page_unwire(pg, PQ_NONE)) { + if (vm_page_unwire(pg, nocache ? PQ_NONE : PQ_INACTIVE)) { vm_object_t obj; - /* Try to free the page, but only if it is cheap to. */ if ((obj = pg->object) == NULL) vm_page_free(pg); - else if (!vm_page_xbusied(pg) && VM_OBJECT_TRYWLOCK(obj)) { - vm_page_free(pg); - VM_OBJECT_WUNLOCK(obj); - } else - vm_page_deactivate(pg); + else if (nocache) { + if (!vm_page_xbusied(pg) && VM_OBJECT_TRYWLOCK(obj)) { + bool freed; + + /* Only free unmapped pages. */ + if (obj->ref_count == 0 || + !pmap_page_is_mapped(pg)) + /* + * The busy test before the object is + * locked cannot be relied upon. + */ + freed = vm_page_try_to_free(pg); + else + freed = false; + VM_OBJECT_WUNLOCK(obj); + if (!freed) + vm_page_deactivate_noreuse(pg); + } else + vm_page_deactivate_noreuse(pg); + } } vm_page_unlock(pg); +} + +static void +sendfile_free_mext(struct mbuf *m) +{ + struct sf_buf *sf; + vm_page_t pg; + bool nocache; + + KASSERT(m->m_flags & M_EXT && m->m_ext.ext_type == EXT_SFBUF, + ("%s: m %p !M_EXT or !EXT_SFBUF", __func__, m)); + + sf = m->m_ext.ext_arg1; + pg = sf_buf_page(sf); + nocache = m->m_ext.ext_flags & EXT_FLAG_NOCACHE; + + sf_buf_free(sf); + sendfile_free_page(pg, nocache); + + if (m->m_ext.ext_flags & EXT_FLAG_SYNC) { + struct sendfile_sync *sfs = m->m_ext.ext_arg2; - if (sfs != NULL) { mtx_lock(&sfs->mtx); KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0")); if (--sfs->count == 0) @@ -255,7 +261,7 @@ static void sendfile_iodone(void *arg, vm_page_t *pg, int count, int error) { struct sf_io *sfio = arg; - struct socket *so; + struct socket *so = sfio->so; for (int i = 0; i < count; i++) if (pg[i] != bogus_page) @@ -267,8 +273,6 @@ sendfile_iodone(void *arg, vm_page_t *pg, int count, int error) if (!refcount_release(&sfio->nios)) return; - so = sfio->sock_fp->f_data; - if (sfio->error) { struct mbuf *m; @@ -296,8 +300,8 @@ sendfile_iodone(void *arg, vm_page_t *pg, int count, int error) CURVNET_RESTORE(); } - /* XXXGL: curthread */ - fdrop(sfio->sock_fp, curthread); + SOCK_LOCK(so); + sorele(so); free(sfio, M_TEMP); } @@ -516,8 +520,6 @@ sendfile_getsock(struct thread *td, int s, struct file **sock_fp, *so = (*sock_fp)->f_data; if ((*so)->so_type != SOCK_STREAM) return (EINVAL); - if (((*so)->so_state & SS_ISCONNECTED) == 0) - return (ENOTCONN); return (0); } @@ -626,6 +628,12 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, SOCKBUF_UNLOCK(&so->so_snd); goto done; } + if ((so->so_state & SS_ISCONNECTED) == 0) { + SOCKBUF_UNLOCK(&so->so_snd); + error = ENOTCONN; + goto done; + } + space = sbspace(&so->so_snd); if (space < rem && (space <= 0 || @@ -724,6 +732,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, sfio = malloc(sizeof(struct sf_io) + npages * sizeof(vm_page_t), M_TEMP, M_WAITOK); refcount_init(&sfio->nios, 1); + sfio->so = so; sfio->error = 0; nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages, @@ -778,7 +787,9 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, m0->m_ext.ext_buf = (char *)sf_buf_kva(sf); m0->m_ext.ext_size = PAGE_SIZE; m0->m_ext.ext_arg1 = sf; - m0->m_ext.ext_arg2 = sfs; + m0->m_ext.ext_type = EXT_SFBUF; + m0->m_ext.ext_flags = EXT_FLAG_EMBREF; + m0->m_ext.ext_free = sendfile_free_mext; /* * SF_NOCACHE sets the page as being freed upon send. * However, we ignore it for the last page in 'space', @@ -786,14 +797,18 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, * send (rem > space), or if we have readahead * configured (rhpages > 0). */ - if ((flags & SF_NOCACHE) == 0 || - (i == npages - 1 && - ((off + space) & PAGE_MASK) && - (rem > space || rhpages > 0))) - m0->m_ext.ext_type = EXT_SFBUF; - else - m0->m_ext.ext_type = EXT_SFBUF_NOCACHE; - m0->m_ext.ext_flags = EXT_FLAG_EMBREF; + if ((flags & SF_NOCACHE) && + (i != npages - 1 || + !((off + space) & PAGE_MASK) || + !(rem > space || rhpages > 0))) + m0->m_ext.ext_flags |= EXT_FLAG_NOCACHE; + if (sfs != NULL) { + m0->m_ext.ext_flags |= EXT_FLAG_SYNC; + m0->m_ext.ext_arg2 = sfs; + mtx_lock(&sfs->mtx); + sfs->count++; + mtx_unlock(&sfs->mtx); + } m0->m_ext.ext_count = 1; m0->m_flags |= (M_EXT | M_RDONLY); if (nios) @@ -811,12 +826,6 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, else m = m0; mtail = m0; - - if (sfs != NULL) { - mtx_lock(&sfs->mtx); - sfs->count++; - mtx_unlock(&sfs->mtx); - } } if (vp != NULL) @@ -858,9 +867,8 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, error = (*so->so_proto->pr_usrreqs->pru_send) (so, 0, m, NULL, NULL, td); } else { - sfio->sock_fp = sock_fp; sfio->npages = npages; - fhold(sock_fp); + soref(so); error = (*so->so_proto->pr_usrreqs->pru_send) (so, PRUS_NOTREADY, m, NULL, NULL, td); sendfile_iodone(sfio, NULL, 0, 0); diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 168da47170af..8f4a5c8b2200 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include "opt_ekcd.h" +#include "opt_gzio.h" #include "opt_kdb.h" #include "opt_panic.h" #include "opt_sched.h" @@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -157,12 +159,29 @@ struct kerneldumpcrypto { uint8_t kdc_iv[KERNELDUMP_IV_MAX_SIZE]; keyInstance kdc_ki; cipherInstance kdc_ci; - off_t kdc_nextoffset; uint32_t kdc_dumpkeysize; struct kerneldumpkey kdc_dumpkey[]; }; #endif +#ifdef GZIO +struct kerneldumpgz { + struct gzio_stream *kdgz_stream; + uint8_t *kdgz_buf; + size_t kdgz_resid; +}; + +static struct kerneldumpgz *kerneldumpgz_create(struct dumperinfo *di, + uint8_t compression); +static void kerneldumpgz_destroy(struct dumperinfo *di); +static int kerneldumpgz_write_cb(void *cb, size_t len, off_t off, void *arg); + +static int kerneldump_gzlevel = 6; +SYSCTL_INT(_kern, OID_AUTO, kerneldump_gzlevel, CTLFLAG_RWTUN, + &kerneldump_gzlevel, 0, + "Kernel crash dump gzip compression level"); +#endif /* GZIO */ + /* * Variable panicstr contains argument to first call to panic; used as flag * to indicate that the kernel has already called panic. @@ -264,6 +283,8 @@ shutdown_nice(int howto) PROC_LOCK(initproc); if (howto & RB_POWEROFF) kern_psignal(initproc, SIGUSR2); + else if (howto & RB_POWERCYCLE) + kern_psignal(initproc, SIGWINCH); else if (howto & RB_HALT) kern_psignal(initproc, SIGUSR1); else @@ -798,7 +819,7 @@ static void poweroff_wait(void *junk, int howto) { - if (!(howto & RB_POWEROFF) || poweroff_delay <= 0) + if ((howto & (RB_POWEROFF | RB_POWERCYCLE)) == 0 || poweroff_delay <= 0) return; DELAY(poweroff_delay * 1000); } @@ -858,6 +879,9 @@ static char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)]; SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, dumpdevname, 0, "Device for kernel dumps"); +static int _dump_append(struct dumperinfo *di, void *virtual, + vm_offset_t physical, size_t length); + #ifdef EKCD static struct kerneldumpcrypto * kerneldumpcrypto_create(size_t blocksize, uint8_t encryption, @@ -931,8 +955,6 @@ kerneldumpcrypto_init(struct kerneldumpcrypto *kdc) goto out; } - kdc->kdc_nextoffset = 0; - kdk = kdc->kdc_dumpkey; memcpy(kdk->kdk_iv, kdc->kdc_iv, sizeof(kdk->kdk_iv)); out: @@ -950,11 +972,45 @@ kerneldumpcrypto_dumpkeysize(const struct kerneldumpcrypto *kdc) } #endif /* EKCD */ +#ifdef GZIO +static struct kerneldumpgz * +kerneldumpgz_create(struct dumperinfo *di, uint8_t compression) +{ + struct kerneldumpgz *kdgz; + + if (compression != KERNELDUMP_COMP_GZIP) + return (NULL); + kdgz = malloc(sizeof(*kdgz), M_DUMPER, M_WAITOK | M_ZERO); + kdgz->kdgz_stream = gzio_init(kerneldumpgz_write_cb, GZIO_DEFLATE, + di->maxiosize, kerneldump_gzlevel, di); + if (kdgz->kdgz_stream == NULL) { + free(kdgz, M_DUMPER); + return (NULL); + } + kdgz->kdgz_buf = malloc(di->maxiosize, M_DUMPER, M_WAITOK | M_NODUMP); + return (kdgz); +} + +static void +kerneldumpgz_destroy(struct dumperinfo *di) +{ + struct kerneldumpgz *kdgz; + + kdgz = di->kdgz; + if (kdgz == NULL) + return; + gzio_fini(kdgz->kdgz_stream); + explicit_bzero(kdgz->kdgz_buf, di->maxiosize); + free(kdgz->kdgz_buf, M_DUMPER); + free(kdgz, M_DUMPER); +} +#endif /* GZIO */ + /* Registration of dumpers */ int set_dumper(struct dumperinfo *di, const char *devname, struct thread *td, - uint8_t encryption, const uint8_t *key, uint32_t encryptedkeysize, - const uint8_t *encryptedkey) + uint8_t compression, uint8_t encryption, const uint8_t *key, + uint32_t encryptedkeysize, const uint8_t *encryptedkey) { size_t wantcopy; int error; @@ -972,6 +1028,7 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td, dumper = *di; dumper.blockbuf = NULL; dumper.kdc = NULL; + dumper.kdgz = NULL; if (encryption != KERNELDUMP_ENC_NONE) { #ifdef EKCD @@ -990,7 +1047,28 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td, wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); if (wantcopy >= sizeof(dumpdevname)) { printf("set_dumper: device name truncated from '%s' -> '%s'\n", - devname, dumpdevname); + devname, dumpdevname); + } + + if (compression != KERNELDUMP_COMP_NONE) { +#ifdef GZIO + /* + * We currently can't support simultaneous encryption and + * compression. + */ + if (encryption != KERNELDUMP_ENC_NONE) { + error = EOPNOTSUPP; + goto cleanup; + } + dumper.kdgz = kerneldumpgz_create(&dumper, compression); + if (dumper.kdgz == NULL) { + error = EINVAL; + goto cleanup; + } +#else + error = EOPNOTSUPP; + goto cleanup; +#endif } dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO); @@ -1003,6 +1081,11 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td, free(dumper.kdc, M_EKCD); } #endif + +#ifdef GZIO + kerneldumpgz_destroy(&dumper); +#endif + if (dumper.blockbuf != NULL) { explicit_bzero(dumper.blockbuf, dumper.blocksize); free(dumper.blockbuf, M_DUMPER); @@ -1024,24 +1107,20 @@ dump_check_bounds(struct dumperinfo *di, off_t offset, size_t length) (uintmax_t)length, (intmax_t)di->mediasize); return (ENOSPC); } + if (length % di->blocksize != 0) { + printf("Attempt to write partial block of length %ju.\n", + (uintmax_t)length); + return (EINVAL); + } + if (offset % di->blocksize != 0) { + printf("Attempt to write at unaligned offset %jd.\n", + (intmax_t)offset); + return (EINVAL); + } return (0); } -/* Call dumper with bounds checking. */ -static int -dump_raw_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, - off_t offset, size_t length) -{ - int error; - - error = dump_check_bounds(di, offset, length); - if (error != 0) - return (error); - - return (di->dumper(di->priv, virtual, physical, offset, length)); -} - #ifdef EKCD static int dump_encrypt(struct kerneldumpcrypto *kdc, uint8_t *buf, size_t size) @@ -1067,40 +1146,16 @@ dump_encrypt(struct kerneldumpcrypto *kdc, uint8_t *buf, size_t size) /* Encrypt data and call dumper. */ static int -dump_encrypted_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, - off_t offset, size_t length) +dump_encrypted_write(struct dumperinfo *di, void *virtual, + vm_offset_t physical, off_t offset, size_t length) { static uint8_t buf[KERNELDUMP_BUFFER_SIZE]; struct kerneldumpcrypto *kdc; int error; size_t nbytes; - off_t nextoffset; kdc = di->kdc; - error = dump_check_bounds(di, offset, length); - if (error != 0) - return (error); - - /* Signal completion. */ - if (virtual == NULL && physical == 0 && offset == 0 && length == 0) { - return (di->dumper(di->priv, virtual, physical, offset, - length)); - } - - /* Data have to be aligned to block size. */ - if ((length % di->blocksize) != 0) - return (EINVAL); - - /* - * Data have to be written continuously becase we're encrypting using - * CBC mode which has this assumption. - */ - if (kdc->kdc_nextoffset != 0 && kdc->kdc_nextoffset != offset) - return (EINVAL); - - nextoffset = offset + (off_t)length; - while (length > 0) { nbytes = MIN(length, sizeof(buf)); bcopy(virtual, buf, nbytes); @@ -1108,7 +1163,7 @@ dump_encrypted_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, if (dump_encrypt(kdc, buf, nbytes) != 0) return (EIO); - error = di->dumper(di->priv, buf, physical, offset, nbytes); + error = dump_write(di, buf, physical, offset, nbytes); if (error != 0) return (error); @@ -1117,43 +1172,61 @@ dump_encrypted_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, length -= nbytes; } - kdc->kdc_nextoffset = nextoffset; - return (0); } static int -dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset) +dump_write_key(struct dumperinfo *di, off_t offset) { struct kerneldumpcrypto *kdc; kdc = di->kdc; if (kdc == NULL) return (0); - - return (dump_raw_write(di, kdc->kdc_dumpkey, physical, offset, + return (dump_write(di, kdc->kdc_dumpkey, 0, offset, kdc->kdc_dumpkeysize)); } #endif /* EKCD */ -int -dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, - off_t offset, size_t length) +#ifdef GZIO +static int +kerneldumpgz_write_cb(void *base, size_t length, off_t offset, void *arg) { + struct dumperinfo *di; + size_t resid, rlength; + int error; -#ifdef EKCD - if (di->kdc != NULL) { - return (dump_encrypted_write(di, virtual, physical, offset, - length)); + di = arg; + + if (length % di->blocksize != 0) { + /* + * This must be the final write after flushing the compression + * stream. Write as many full blocks as possible and stash the + * residual data in the dumper's block buffer. It will be + * padded and written in dump_finish(). + */ + rlength = rounddown(length, di->blocksize); + if (rlength != 0) { + error = _dump_append(di, base, 0, rlength); + if (error != 0) + return (error); + } + resid = length - rlength; + memmove(di->blockbuf, (uint8_t *)base + rlength, resid); + di->kdgz->kdgz_resid = resid; + return (EAGAIN); } -#endif - - return (dump_raw_write(di, virtual, physical, offset, length)); + return (_dump_append(di, base, 0, length)); } +#endif /* GZIO */ +/* + * Write a kerneldumpheader at the specified offset. The header structure is 512 + * bytes in size, but we must pad to the device sector size. + */ static int dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh, - vm_offset_t physical, off_t offset) + off_t offset) { void *buf; size_t hdrsz; @@ -1170,7 +1243,7 @@ dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh, memcpy(buf, kdh, hdrsz); } - return (dump_raw_write(di, buf, physical, offset, di->blocksize)); + return (dump_write(di, buf, 0, offset, di->blocksize)); } /* @@ -1180,19 +1253,30 @@ dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh, #define SIZEOF_METADATA (64 * 1024) /* - * Do some preliminary setup for a kernel dump: verify that we have enough space - * on the dump device, write the leading header, and optionally write the crypto - * key. + * Do some preliminary setup for a kernel dump: initialize state for encryption, + * if requested, and make sure that we have enough space on the dump device. + * + * We set things up so that the dump ends before the last sector of the dump + * device, at which the trailing header is written. + * + * +-----------+------+-----+----------------------------+------+ + * | | lhdr | key | ... kernel dump ... | thdr | + * +-----------+------+-----+----------------------------+------+ + * 1 blk opt <------- dump extent --------> 1 blk + * + * Dumps written using dump_append() start at the beginning of the extent. + * Uncompressed dumps will use the entire extent, but compressed dumps typically + * will not. The true length of the dump is recorded in the leading and trailing + * headers once the dump has been completed. */ int -dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t *dumplop) +dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh) { - uint64_t dumpsize; + uint64_t dumpextent; uint32_t keysize; - int error; #ifdef EKCD - error = kerneldumpcrypto_init(di->kdc); + int error = kerneldumpcrypto_init(di->kdc); if (error != 0) return (error); keysize = kerneldumpcrypto_dumpkeysize(di->kdc); @@ -1200,37 +1284,157 @@ dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t *dumplop) keysize = 0; #endif - dumpsize = dtoh64(kdh->dumplength) + 2 * di->blocksize + keysize; - if (di->mediasize < SIZEOF_METADATA + dumpsize) - return (E2BIG); - - *dumplop = di->mediaoffset + di->mediasize - dumpsize; - - error = dump_write_header(di, kdh, 0, *dumplop); - if (error != 0) - return (error); - *dumplop += di->blocksize; - -#ifdef EKCD - error = dump_write_key(di, 0, *dumplop); - if (error != 0) - return (error); - *dumplop += keysize; + dumpextent = dtoh64(kdh->dumpextent); + if (di->mediasize < SIZEOF_METADATA + dumpextent + 2 * di->blocksize + + keysize) { +#ifdef GZIO + if (di->kdgz != NULL) { + /* + * We don't yet know how much space the compressed dump + * will occupy, so try to use the whole swap partition + * (minus the first 64KB) in the hope that the + * compressed dump will fit. If that doesn't turn out to + * be enouch, the bounds checking in dump_write() + * will catch us and cause the dump to fail. + */ + dumpextent = di->mediasize - SIZEOF_METADATA - + 2 * di->blocksize - keysize; + kdh->dumpextent = htod64(dumpextent); + } else #endif + return (E2BIG); + } + + /* The offset at which to begin writing the dump. */ + di->dumpoff = di->mediaoffset + di->mediasize - di->blocksize - + dumpextent; return (0); } -/* - * Write the trailing kernel dump header and signal to the lower layers that the - * dump has completed. - */ -int -dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t dumplo) +static int +_dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical, + size_t length) { int error; - error = dump_write_header(di, kdh, 0, dumplo); +#ifdef EKCD + if (di->kdc != NULL) + error = dump_encrypted_write(di, virtual, physical, di->dumpoff, + length); + else +#endif + error = dump_write(di, virtual, physical, di->dumpoff, length); + if (error == 0) + di->dumpoff += length; + return (error); +} + +/* + * Write to the dump device starting at dumpoff. When compression is enabled, + * writes to the device will be performed using a callback that gets invoked + * when the compression stream's output buffer is full. + */ +int +dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical, + size_t length) +{ +#ifdef GZIO + void *buf; + + if (di->kdgz != NULL) { + /* Bounce through a buffer to avoid gzip CRC errors. */ + if (length > di->maxiosize) + return (EINVAL); + buf = di->kdgz->kdgz_buf; + memmove(buf, virtual, length); + return (gzio_write(di->kdgz->kdgz_stream, buf, length)); + } +#endif + return (_dump_append(di, virtual, physical, length)); +} + +/* + * Write to the dump device at the specified offset. + */ +int +dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, + off_t offset, size_t length) +{ + int error; + + error = dump_check_bounds(di, offset, length); + if (error != 0) + return (error); + return (di->dumper(di->priv, virtual, physical, offset, length)); +} + +/* + * Perform kernel dump finalization: flush the compression stream, if necessary, + * write the leading and trailing kernel dump headers now that we know the true + * length of the dump, and optionally write the encryption key following the + * leading header. + */ +int +dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh) +{ + uint64_t extent; + uint32_t keysize; + int error; + + extent = dtoh64(kdh->dumpextent); + +#ifdef EKCD + keysize = kerneldumpcrypto_dumpkeysize(di->kdc); +#else + keysize = 0; +#endif + +#ifdef GZIO + if (di->kdgz != NULL) { + error = gzio_flush(di->kdgz->kdgz_stream); + if (error == EAGAIN) { + /* We have residual data in di->blockbuf. */ + error = dump_write(di, di->blockbuf, 0, di->dumpoff, + di->blocksize); + di->dumpoff += di->kdgz->kdgz_resid; + di->kdgz->kdgz_resid = 0; + } + if (error != 0) + return (error); + + /* + * We now know the size of the compressed dump, so update the + * header accordingly and recompute parity. + */ + kdh->dumplength = htod64(di->dumpoff - + (di->mediaoffset + di->mediasize - di->blocksize - extent)); + kdh->parity = 0; + kdh->parity = kerneldump_parity(kdh); + + gzio_reset(di->kdgz->kdgz_stream); + } +#endif + + /* + * Write kerneldump headers at the beginning and end of the dump extent. + * Write the key after the leading header. + */ + error = dump_write_header(di, kdh, + di->mediaoffset + di->mediasize - 2 * di->blocksize - extent - + keysize); + if (error != 0) + return (error); + +#ifdef EKCD + error = dump_write_key(di, + di->mediaoffset + di->mediasize - di->blocksize - extent - keysize); + if (error != 0) + return (error); +#endif + + error = dump_write_header(di, kdh, + di->mediaoffset + di->mediasize - di->blocksize); if (error != 0) return (error); @@ -1250,6 +1454,7 @@ dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh, kdh->version = htod32(KERNELDUMPVERSION); kdh->architectureversion = htod32(archver); kdh->dumplength = htod64(dumplen); + kdh->dumpextent = kdh->dumplength; kdh->dumptime = htod64(time_second); #ifdef EKCD kdh->dumpkeysize = htod32(kerneldumpcrypto_dumpkeysize(di->kdc)); @@ -1263,6 +1468,10 @@ dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh, kdh->versionstring[dstsize - 2] = '\n'; if (panicstr != NULL) strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); +#ifdef GZIO + if (di->kdgz != NULL) + kdh->compression = KERNELDUMP_COMP_GZIP; +#endif kdh->parity = kerneldump_parity(kdh); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index ce5e7b2768f0..ea3b68e370c6 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2786,15 +2786,15 @@ issignal(struct thread *td) struct sigacts *ps; struct sigqueue *queue; sigset_t sigpending; - int sig, prop; ksiginfo_t ksi; + int prop, sig, traced; p = td->td_proc; ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED); for (;;) { - int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); + traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); sigpending = td->td_sigqueue.sq_signals; SIGSETOR(sigpending, p->p_sigqueue.sq_signals); @@ -2855,15 +2855,32 @@ issignal(struct thread *td) mtx_lock(&ps->ps_mtx); /* - * Keep looking if the debugger discarded the signal - * or replaced it with a masked signal. - * - * If the traced bit got turned off, go back up - * to the top to rescan signals. This ensures - * that p_sig* and p_sigact are consistent. + * Keep looking if the debugger discarded or + * replaced the signal. */ - if (sig == 0 || (p->p_flag & P_TRACED) == 0) + if (sig == 0) continue; + + /* + * If the signal became masked, re-queue it. + */ + if (SIGISMEMBER(td->td_sigmask, sig)) { + ksi.ksi_flags |= KSI_HEAD; + sigqueue_add(&p->p_sigqueue, sig, &ksi); + continue; + } + + /* + * If the traced bit got turned off, requeue + * the signal and go back up to the top to + * rescan signals. This ensures that p_sig* + * and p_sigact are consistent. + */ + if ((p->p_flag & P_TRACED) == 0) { + ksi.ksi_flags |= KSI_HEAD; + sigqueue_add(queue, sig, &ksi); + continue; + } } prop = sigprop(sig); @@ -2982,11 +2999,10 @@ thread_stopped(struct proc *p) * from the current set of pending signals. */ int -postsig(sig) - int sig; +postsig(int sig) { - struct thread *td = curthread; - struct proc *p = td->td_proc; + struct thread *td; + struct proc *p; struct sigacts *ps; sig_t action; ksiginfo_t ksi; @@ -2994,6 +3010,8 @@ postsig(sig) KASSERT(sig != 0, ("postsig")); + td = curthread; + p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); @@ -3010,7 +3028,7 @@ postsig(sig) ktrpsig(sig, action, td->td_pflags & TDP_OLDMASK ? &td->td_oldsigmask : &td->td_sigmask, ksi.ksi_code); #endif - if (p->p_stops & S_SIG) { + if ((p->p_stops & S_SIG) != 0) { mtx_unlock(&ps->ps_mtx); stopevent(p, S_SIG, sig); mtx_lock(&ps->ps_mtx); @@ -3029,8 +3047,10 @@ postsig(sig) /* * If we get here, the signal must be caught. */ - KASSERT(action != SIG_IGN && !SIGISMEMBER(td->td_sigmask, sig), - ("postsig action")); + KASSERT(action != SIG_IGN, ("postsig action %p", action)); + KASSERT(!SIGISMEMBER(td->td_sigmask, sig), + ("postsig action: blocked sig %d", sig)); + /* * Set the new mask value and also defer further * occurrences of this signal. diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index ed0108f7dad2..bc3d22b21f37 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -502,7 +502,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts, GIANT_DECLARE; #ifdef ADAPTIVE_SX volatile struct thread *owner; - u_int i, spintries = 0; + u_int i, n, spintries = 0; #endif #ifdef LOCK_PROFILING uint64_t waittime = 0; @@ -600,23 +600,23 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts, "lockname:\"%s\"", sx->lock_object.lo_name); GIANT_SAVE(); spintries++; - for (i = 0; i < asx_loops; i++) { + for (i = 0; i < asx_loops; i += n) { if (LOCK_LOG_TEST(&sx->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", __func__, sx, spintries, i); - x = sx->sx_lock; + n = SX_SHARERS(x); + lock_delay_spin(n); + x = SX_READ_VALUE(sx); if ((x & SX_LOCK_SHARED) == 0 || SX_SHARERS(x) == 0) break; - cpu_spinwait(); -#ifdef KDTRACE_HOOKS - lda.spin_cnt++; -#endif } +#ifdef KDTRACE_HOOKS + lda.spin_cnt += i; +#endif KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread), "running"); - x = SX_READ_VALUE(sx); if (i != asx_loops) continue; } diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index e218d2c5de5e..340549ff5749 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -88,7 +88,7 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); * sysctl requests larger than a single page via an exclusive lock. */ static struct rmlock sysctllock; -static struct sx sysctlmemlock; +static struct sx __exclusive_cache_line sysctlmemlock; #define SYSCTL_WLOCK() rm_wlock(&sysctllock) #define SYSCTL_WUNLOCK() rm_wunlock(&sysctllock) @@ -509,6 +509,37 @@ sysctl_register_oid(struct sysctl_oid *oidp) } } +void +sysctl_register_disabled_oid(struct sysctl_oid *oidp) +{ + + /* + * Mark the leaf as dormant if it's not to be immediately enabled. + * We do not disable nodes as they can be shared between modules + * and it is always safe to access a node. + */ + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, + ("internal flag is set in oid_kind")); + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + oidp->oid_kind |= CTLFLAG_DORMANT; + sysctl_register_oid(oidp); +} + +void +sysctl_enable_oid(struct sysctl_oid *oidp) +{ + + SYSCTL_ASSERT_WLOCKED(); + if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, + ("sysctl node is marked as dormant")); + return; + } + KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0, + ("enabling already enabled sysctl oid")); + oidp->oid_kind &= ~CTLFLAG_DORMANT; +} + void sysctl_unregister_oid(struct sysctl_oid *oidp) { @@ -1057,7 +1088,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, *next = oidp->oid_number; *oidpp = oidp; - if (oidp->oid_kind & CTLFLAG_SKIP) + if ((oidp->oid_kind & (CTLFLAG_SKIP | CTLFLAG_DORMANT)) != 0) continue; if (!namelen) { @@ -1878,6 +1909,8 @@ sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, } lsp = SYSCTL_CHILDREN(oid); } else if (indx == namelen) { + if ((oid->oid_kind & CTLFLAG_DORMANT) != 0) + return (ENOENT); *noid = oid; if (nindx != NULL) *nindx = indx; @@ -2061,16 +2094,9 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, } } req.validlen = req.oldlen; - - if (old) { - if (!useracc(old, req.oldlen, VM_PROT_WRITE)) - return (EFAULT); - req.oldptr= old; - } + req.oldptr = old; if (new != NULL) { - if (!useracc(new, newlen, VM_PROT_READ)) - return (EFAULT); req.newlen = newlen; req.newptr = new; } @@ -2083,12 +2109,11 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, if (KTRPOINT(curthread, KTR_SYSCTL)) ktrsysctl(name, namelen); #endif - - if (req.oldptr && req.oldlen > PAGE_SIZE) { + memlocked = 0; + if (req.oldptr && req.oldlen > 4 * PAGE_SIZE) { memlocked = 1; sx_xlock(&sysctlmemlock); - } else - memlocked = 0; + } CURVNET_SET(TD_TO_VNET(td)); for (;;) { diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 088fcb41cfa4..e060f485053d 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1413,10 +1413,8 @@ tc_windup(struct bintime *new_boottimebin) if (bt.sec != t) th->th_boottime.sec += bt.sec - t; } - th->th_bintime = th->th_offset; - bintime_add(&th->th_bintime, &th->th_boottime); /* Update the UTC timestamps used by the get*() functions. */ - /* XXX shouldn't do this here. Should force non-`get' versions. */ + th->th_bintime = bt; bintime2timeval(&bt, &th->th_microtime); bintime2timespec(&bt, &th->th_nanotime); diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index d72c57d5f59b..58f37171718e 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -1579,8 +1579,7 @@ umtx_pi_setowner(struct umtx_pi *pi, struct thread *owner) uq_owner = owner->td_umtxq; mtx_assert(&umtx_lock, MA_OWNED); - if (pi->pi_owner != NULL) - panic("pi_owner != NULL"); + MPASS(pi->pi_owner == NULL); pi->pi_owner = owner; TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link); } diff --git a/sys/kern/md4c.c b/sys/kern/md4c.c index 7cfb84ba8991..dcfbe20bac35 100644 --- a/sys/kern/md4c.c +++ b/sys/kern/md4c.c @@ -90,8 +90,8 @@ static unsigned char PADDING[64] = { /* MD4 initialization. Begins an MD4 operation, writing a new context. */ -void MD4Init (context) -MD4_CTX *context; /* context */ +void +MD4Init(MD4_CTX *context) { context->count[0] = context->count[1] = 0; @@ -107,10 +107,9 @@ MD4_CTX *context; /* context */ operation, processing another message block, and updating the context. */ -void MD4Update (context, input, inputLen) -MD4_CTX *context; /* context */ -const unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ +void +MD4Update(MD4_CTX *context, const unsigned char *input, + unsigned int inputLen) { unsigned int i, index, partLen; @@ -142,8 +141,8 @@ unsigned int inputLen; /* length of input block */ } /* MD4 padding. */ -void MD4Pad (context) -MD4_CTX *context; /* context */ +void +MD4Pad(MD4_CTX *context) { unsigned char bits[8]; unsigned int index, padLen; @@ -164,7 +163,8 @@ MD4_CTX *context; /* context */ /* MD4 finalization. Ends an MD4 message-digest operation, writing the the message digest and zeroizing the context. */ -void MD4Final (unsigned char digest[static 16], MD4_CTX *context) +void +MD4Final(unsigned char digest[static 16], MD4_CTX *context) { /* Do padding */ MD4Pad (context); @@ -179,9 +179,8 @@ void MD4Final (unsigned char digest[static 16], MD4_CTX *context) /* MD4 basic transformation. Transforms state based on block. */ -static void MD4Transform (state, block) -UINT4 state[4]; -const unsigned char block[64]; +static void +MD4Transform(UINT4 state[4], const unsigned char block[64]) { UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; @@ -254,10 +253,8 @@ const unsigned char block[64]; /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ -static void Encode (output, input, len) -unsigned char *output; -UINT4 *input; -unsigned int len; +static void +Encode(unsigned char *output, UINT4 *input, unsigned int len) { unsigned int i, j; @@ -272,11 +269,8 @@ unsigned int len; /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ -static void Decode (output, input, len) - -UINT4 *output; -const unsigned char *input; -unsigned int len; +static void +Decode(UINT4 *output, const unsigned char *input, unsigned int len) { unsigned int i, j; diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index a4d0a040297e..c6889ccd9332 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -2939,7 +2939,7 @@ SYSCTL_INT(_kern_sched, OID_AUTO, steal_idle, CTLFLAG_RW, &steal_idle, 0, SYSCTL_INT(_kern_sched, OID_AUTO, steal_thresh, CTLFLAG_RW, &steal_thresh, 0, "Minimum load on remote CPU before we'll steal"); SYSCTL_PROC(_kern_sched, OID_AUTO, topology_spec, CTLTYPE_STRING | - CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A", + CTLFLAG_MPSAFE | CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A", "XML dump of detected CPU topology"); #endif diff --git a/sys/kern/subr_blist.c b/sys/kern/subr_blist.c index 6934f3b21187..0c79448a8400 100644 --- a/sys/kern/subr_blist.c +++ b/sys/kern/subr_blist.c @@ -32,14 +32,17 @@ * try to interpret the meaning of a 'block' other than to return * SWAPBLK_NONE on an allocation failure. * - * A radix tree is used to maintain the bitmap. Two radix constants are - * involved: One for the bitmaps contained in the leaf nodes (typically - * 64), and one for the meta nodes (typically 16). Both meta and leaf - * nodes have a hint field. This field gives us a hint as to the largest - * free contiguous range of blocks under the node. It may contain a - * value that is too high, but will never contain a value that is too - * low. When the radix tree is searched, allocation failures in subtrees - * update the hint. + * A radix tree controls access to pieces of the bitmap, and includes + * auxiliary information at each interior node about the availabilty of + * contiguous free blocks in the subtree rooted at that node. Two radix + * constants are involved: one for the size of the bitmaps contained in the + * leaf nodes (BLIST_BMAP_RADIX), and one for the number of descendents of + * each of the meta (interior) nodes (BLIST_META_RADIX). Each subtree is + * associated with a range of blocks. The root of any subtree stores a + * hint field that defines an upper bound on the size of the largest + * allocation that can begin in the associated block range. A hint is an + * upper bound on a potential allocation, but not necessarily a tight upper + * bound. * * The radix tree also implements two collapsed states for meta nodes: * the ALL-ALLOCATED state and the ALL-FREE state. If a meta node is @@ -105,6 +108,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -112,7 +116,7 @@ __FBSDID("$FreeBSD$"); #define bitcount64(x) __bitcount64((uint64_t)(x)) #define malloc(a,b,c) calloc(a, 1) #define free(a,b) free(a) -#define CTASSERT(expr) +static __inline int imax(int a, int b) { return (a > b ? a : b); } #include @@ -123,8 +127,7 @@ void panic(const char *ctl, ...); /* * static support functions */ -static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, - daddr_t cursor); +static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count); static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix); static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count); @@ -135,7 +138,6 @@ static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count); static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, u_daddr_t radix); -static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count); #ifndef _KERNEL static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, int tab); @@ -145,7 +147,9 @@ static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, static MALLOC_DEFINE(M_SWAP, "SWAP", "Swap space"); #endif -CTASSERT(BLIST_BMAP_RADIX % BLIST_META_RADIX == 0); +_Static_assert(BLIST_BMAP_RADIX % BLIST_META_RADIX == 0, + "radix divisibility error"); +#define BLIST_BMAP_MASK (BLIST_BMAP_RADIX - 1) #define BLIST_META_MASK (BLIST_META_RADIX - 1) /* @@ -214,30 +218,70 @@ blist_t blist_create(daddr_t blocks, int flags) { blist_t bl; - daddr_t nodes, radix; + daddr_t i, last_block; + u_daddr_t nodes, radix, skip; + int digit; /* - * Calculate the radix field used for scanning. + * Calculate the radix and node count used for scanning. Find the last + * block that is followed by a terminator. */ + last_block = blocks - 1; radix = BLIST_BMAP_RADIX; while (radix < blocks) { + if (((last_block / radix + 1) & BLIST_META_MASK) != 0) + /* + * A terminator will be added. Update last_block to the + * position just before that terminator. + */ + last_block |= radix - 1; radix *= BLIST_META_RADIX; } - nodes = 1 + blst_radix_init(NULL, radix, blocks); - bl = malloc(sizeof(struct blist), M_SWAP, flags); + /* + * Count the meta-nodes in the expanded tree, including the final + * terminator, from the bottom level up to the root. + */ + nodes = (last_block >= blocks) ? 2 : 1; + last_block /= BLIST_BMAP_RADIX; + while (last_block > 0) { + nodes += last_block + 1; + last_block /= BLIST_META_RADIX; + } + bl = malloc(offsetof(struct blist, bl_root[nodes]), M_SWAP, flags | + M_ZERO); if (bl == NULL) return (NULL); bl->bl_blocks = blocks; bl->bl_radix = radix; bl->bl_cursor = 0; - bl->bl_root = malloc(nodes * sizeof(blmeta_t), M_SWAP, flags); - if (bl->bl_root == NULL) { - free(bl, M_SWAP); - return (NULL); + + /* + * Initialize the empty tree by filling in root values, then initialize + * just the terminators in the rest of the tree. + */ + bl->bl_root[0].bm_bighint = 0; + if (radix == BLIST_BMAP_RADIX) + bl->bl_root[0].u.bmu_bitmap = 0; + else + bl->bl_root[0].u.bmu_avail = 0; + last_block = blocks - 1; + i = 0; + while (radix > BLIST_BMAP_RADIX) { + radix /= BLIST_META_RADIX; + skip = radix_to_skip(radix); + digit = last_block / radix; + i += 1 + digit * skip; + if (digit != BLIST_META_MASK) { + /* + * Add a terminator. + */ + bl->bl_root[i + skip].bm_bighint = (daddr_t)-1; + bl->bl_root[i + skip].u.bmu_bitmap = 0; + } + last_block %= radix; } - blst_radix_init(bl->bl_root, radix, blocks); #if defined(BLIST_DEBUG) printf( @@ -257,7 +301,7 @@ blist_create(daddr_t blocks, int flags) void blist_destroy(blist_t bl) { - free(bl->bl_root, M_SWAP); + free(bl, M_SWAP); } @@ -575,33 +619,16 @@ blist_stats(blist_t bl, struct sbuf *s) * time is proportional to log2(count) + bitpos time. */ static daddr_t -blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, daddr_t cursor) +blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count) { u_daddr_t mask; - int count1, lo, num_shifts, range1, range_ext; + int count1, hi, lo, num_shifts, range1, range_ext; - if (count == BLIST_BMAP_RADIX) { - /* - * Optimize allocation of BLIST_BMAP_RADIX bits. If this wasn't - * a special case, then forming the final value of 'mask' below - * would require special handling to avoid an invalid left shift - * when count equals the number of bits in mask. - */ - if (~scan->u.bmu_bitmap != 0) { - scan->bm_bighint = BLIST_BMAP_RADIX - 1; - return (SWAPBLK_NONE); - } - if (cursor != blk) - return (SWAPBLK_NONE); - scan->u.bmu_bitmap = 0; - scan->bm_bighint = 0; - return (blk); - } range1 = 0; count1 = count - 1; num_shifts = fls(count1); mask = scan->u.bmu_bitmap; - while (mask != 0 && num_shifts > 0) { + while ((-mask & ~mask) != 0 && num_shifts > 0) { /* * If bit i is set in mask, then bits in [i, i+range1] are set * in scan->u.bmu_bitmap. The value of range1 is equal to @@ -609,27 +636,32 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, daddr_t cursor) * while preserving these invariants. The updates to mask leave * fewer bits set, but each bit that remains set represents a * longer string of consecutive bits set in scan->u.bmu_bitmap. + * If more updates to mask cannot clear more bits, because mask + * is partitioned with all 0 bits preceding all 1 bits, the loop + * terminates immediately. */ num_shifts--; range_ext = range1 + ((count1 >> num_shifts) & 1); - mask &= mask >> range_ext; + /* + * mask is a signed quantity for the shift because when it is + * shifted right, the sign bit should copied; when the last + * block of the leaf is free, pretend, for a while, that all the + * blocks that follow it are also free. + */ + mask &= (daddr_t)mask >> range_ext; range1 += range_ext; } if (mask == 0) { /* * Update bighint. There is no allocation bigger than range1 - * available in this leaf. + * starting in this leaf. */ scan->bm_bighint = range1; return (SWAPBLK_NONE); } - /* - * Discard any candidates that appear before the cursor. - */ - lo = cursor - blk; - mask &= ~(u_daddr_t)0 << lo; - + /* Discard any candidates that appear before blk. */ + mask &= (u_daddr_t)-1 << (blk & BLIST_BMAP_MASK); if (mask == 0) return (SWAPBLK_NONE); @@ -641,13 +673,58 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, daddr_t cursor) mask &= -mask; lo = bitpos(mask); - /* - * Set in mask exactly the bits being allocated, and clear them from - * the set of available bits. - */ - mask = (mask << count) - mask; + hi = lo + count; + if (hi > BLIST_BMAP_RADIX) { + /* + * An allocation within this leaf is impossible, so a successful + * allocation depends on the next leaf providing some of the blocks. + */ + if (((blk / BLIST_BMAP_RADIX + 1) & BLIST_META_MASK) == 0) { + /* + * The next leaf has a different meta-node parent, so it + * is not necessarily initialized. Update bighint, + * comparing the range found at the end of mask to the + * largest earlier range that could have been made to + * vanish in the initial processing of mask. + */ + scan->bm_bighint = imax(BLIST_BMAP_RADIX - lo, range1); + return (SWAPBLK_NONE); + } + hi -= BLIST_BMAP_RADIX; + if (((scan[1].u.bmu_bitmap + 1) & ~((u_daddr_t)-1 << hi)) != 0) { + /* + * The next leaf doesn't have enough free blocks at the + * beginning to complete the spanning allocation. The + * hint cannot be updated, because the same allocation + * request could be satisfied later, by this leaf, if + * the state of the next leaf changes, and without any + * changes to this leaf. + */ + return (SWAPBLK_NONE); + } + /* Clear the first 'hi' bits in the next leaf, allocating them. */ + scan[1].u.bmu_bitmap &= (u_daddr_t)-1 << hi; + hi = BLIST_BMAP_RADIX; + } + + /* Set the bits of mask at position 'lo' and higher. */ + mask = -mask; + if (hi == BLIST_BMAP_RADIX) { + /* + * Update bighint. There is no allocation bigger than range1 + * available in this leaf after this allocation completes. + */ + scan->bm_bighint = range1; + } else { + /* Clear the bits of mask at position 'hi' and higher. */ + mask &= (u_daddr_t)-1 >> (BLIST_BMAP_RADIX - hi); + /* If this allocation uses all the bits, clear the hint. */ + if (mask == scan->u.bmu_bitmap) + scan->bm_bighint = 0; + } + /* Clear the allocated bits from this leaf. */ scan->u.bmu_bitmap &= ~mask; - return (blk + lo); + return ((blk & ~BLIST_BMAP_MASK) + lo); } /* @@ -665,9 +742,8 @@ blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix) int child; bool scan_from_start; - blk = cursor & -radix; if (radix == BLIST_BMAP_RADIX) - return (blst_leaf_alloc(scan, blk, count, cursor)); + return (blst_leaf_alloc(scan, cursor, count)); if (scan->u.bmu_avail < count) { /* * The meta node's hint must be too large if the allocation @@ -677,6 +753,7 @@ blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix) scan->bm_bighint = scan->u.bmu_avail; return (SWAPBLK_NONE); } + blk = cursor & -radix; skip = radix_to_skip(radix); next_skip = skip / BLIST_META_RADIX; @@ -715,7 +792,7 @@ blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix) for (i = 1 + child * next_skip; i < skip; i += next_skip) { if (count <= scan[i].bm_bighint) { /* - * The allocation might fit in the i'th subtree. + * The allocation might fit beginning in the i'th subtree. */ r = blst_meta_alloc(&scan[i], cursor > blk ? cursor : blk, count, radix); @@ -748,22 +825,20 @@ blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix) static void blst_leaf_free(blmeta_t *scan, daddr_t blk, int count) { + u_daddr_t mask; + int n; + /* * free some data in this bitmap - * - * e.g. - * 0000111111111110000 + * mask=0000111111111110000 * \_________/\__/ - * v n + * count n */ - int n = blk & (BLIST_BMAP_RADIX - 1); - u_daddr_t mask; - + n = blk & BLIST_BMAP_MASK; mask = ((u_daddr_t)-1 << n) & ((u_daddr_t)-1 >> (BLIST_BMAP_RADIX - count - n)); - if (scan->u.bmu_bitmap & mask) - panic("blst_radix_free: freeing free block"); + panic("freeing free block"); scan->u.bmu_bitmap |= mask; /* @@ -944,10 +1019,11 @@ blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, blist_t dest, static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count) { - int n = blk & (BLIST_BMAP_RADIX - 1); daddr_t nblks; u_daddr_t mask; + int n; + n = blk & BLIST_BMAP_MASK; mask = ((u_daddr_t)-1 << n) & ((u_daddr_t)-1 >> (BLIST_BMAP_RADIX - count - n)); @@ -1036,79 +1112,6 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, u_daddr_t radix) return (nblks); } -/* - * BLST_RADIX_INIT() - initialize radix tree - * - * Initialize our meta structures and bitmaps and calculate the exact - * amount of space required to manage 'count' blocks - this space may - * be considerably less than the calculated radix due to the large - * RADIX values we use. - */ -static daddr_t -blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count) -{ - daddr_t i, memindex, next_skip, skip; - - memindex = 0; - - /* - * Leaf node - */ - - if (radix == BLIST_BMAP_RADIX) { - if (scan) { - scan->bm_bighint = 0; - scan->u.bmu_bitmap = 0; - } - return (memindex); - } - - /* - * Meta node. If allocating the entire object we can special - * case it. However, we need to figure out how much memory - * is required to manage 'count' blocks, so we continue on anyway. - */ - - if (scan) { - scan->bm_bighint = 0; - scan->u.bmu_avail = 0; - } - - skip = radix_to_skip(radix); - next_skip = skip / BLIST_META_RADIX; - radix /= BLIST_META_RADIX; - - for (i = 1; i < skip; i += next_skip) { - if (count >= radix) { - /* - * Allocate the entire object - */ - memindex = i + - blst_radix_init(((scan) ? &scan[i] : NULL), radix, - radix); - count -= radix; - } else if (count > 0) { - /* - * Allocate a partial object - */ - memindex = i + - blst_radix_init(((scan) ? &scan[i] : NULL), radix, - count); - count = 0; - } else { - /* - * Add terminator and break out - */ - if (scan) - scan[i].bm_bighint = (daddr_t)-1; - break; - } - } - if (memindex < i) - memindex = i; - return (memindex); -} - #ifdef BLIST_DEBUG static void diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 73658b530387..8c5b975d2aaf 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -2936,6 +2936,7 @@ device_attach(device_t dev) else dev->state = DS_ATTACHED; dev->flags &= ~DF_DONENOMATCH; + EVENTHANDLER_INVOKE(device_attach, dev); devadded(dev); return (0); } @@ -2969,8 +2970,13 @@ device_detach(device_t dev) if (dev->state != DS_ATTACHED) return (0); - if ((error = DEVICE_DETACH(dev)) != 0) + EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN); + if ((error = DEVICE_DETACH(dev)) != 0) { + EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED); return (error); + } else { + EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE); + } devremoved(dev); if (!device_is_quiet(dev)) device_printf(dev, "detached\n"); diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c index 5894099abd2e..793210cfe946 100644 --- a/sys/kern/subr_eventhandler.c +++ b/sys/kern/subr_eventhandler.c @@ -180,8 +180,9 @@ vimage_eventhandler_register(struct eventhandler_list *list, const char *name, } #endif -void -eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) +static void +_eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag, + bool wait) { struct eventhandler_entry *ep = tag; @@ -215,11 +216,26 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) ep->ee_priority = EHE_DEAD_PRIORITY; } } - while (list->el_runcount > 0) + while (wait && list->el_runcount > 0) mtx_sleep(list, &list->el_lock, 0, "evhrm", 0); EHL_UNLOCK(list); } +void +eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) +{ + + _eventhandler_deregister(list, tag, true); +} + +void +eventhandler_deregister_nowait(struct eventhandler_list *list, + eventhandler_tag tag) +{ + + _eventhandler_deregister(list, tag, false); +} + /* * Internal version for use when eventhandler list is already locked. */ diff --git a/sys/kern/subr_gtaskqueue.c b/sys/kern/subr_gtaskqueue.c index 716aef6b1053..27463d93445d 100644 --- a/sys/kern/subr_gtaskqueue.c +++ b/sys/kern/subr_gtaskqueue.c @@ -51,23 +51,14 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_GTASKQUEUE, "gtaskqueue", "Group Task Queues"); static void gtaskqueue_thread_enqueue(void *); static void gtaskqueue_thread_loop(void *arg); -static int _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri); -TASKQGROUP_DEFINE(softirq, mp_ncpus, 1, false, PI_SOFT); + +TASKQGROUP_DEFINE(softirq, mp_ncpus, 1); struct gtaskqueue_busy { struct gtask *tb_running; TAILQ_ENTRY(gtaskqueue_busy) tb_link; }; -struct gt_intr_thread { - int git_flags; /* (j) IT_* flags. */ - int git_need; /* Needs service. */ -}; - -/* Interrupt thread flags kept in it_flags */ -#define IT_DEAD 0x000001 /* Thread is waiting to exit. */ -#define IT_WAIT 0x000002 /* Thread is waiting for completion. */ - static struct gtask * const TB_DRAIN_WAITER = (struct gtask *)0x1; struct gtaskqueue { @@ -78,7 +69,6 @@ struct gtaskqueue { TAILQ_HEAD(, gtaskqueue_busy) tq_active; struct mtx tq_mutex; struct thread **tq_threads; - struct gt_intr_thread *tq_gt_intrs; int tq_tcount; int tq_spin; int tq_flags; @@ -90,7 +80,6 @@ struct gtaskqueue { #define TQ_FLAGS_ACTIVE (1 << 0) #define TQ_FLAGS_BLOCKED (1 << 1) #define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2) -#define TQ_FLAGS_INTR (1 << 3) #define DT_CALLOUT_ARMED (1 << 0) @@ -191,32 +180,6 @@ gtaskqueue_free(struct gtaskqueue *queue) free(queue, M_GTASKQUEUE); } -static void -schedule_ithread(struct gtaskqueue *queue) -{ - struct proc *p; - struct thread *td; - struct gt_intr_thread *git; - - MPASS(queue->tq_tcount == 1); - td = queue->tq_threads[0]; - git = &queue->tq_gt_intrs[0]; - p = td->td_proc; - - atomic_store_rel_int(&git->git_need, 1); - thread_lock(td); - if (TD_AWAITING_INTR(td)) { - CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, - td->td_name); - TD_CLR_IWAIT(td); - sched_add(td, SRQ_INTR); - } else { - CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", - __func__, p->p_pid, td->td_name, git->git_need, td->td_state); - } - thread_unlock(td); -} - int grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *gtask) { @@ -234,13 +197,8 @@ grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *gtask) STAILQ_INSERT_TAIL(&queue->tq_queue, gtask, ta_link); gtask->ta_flags |= TASK_ENQUEUED; TQ_UNLOCK(queue); - if ((queue->tq_flags & TQ_FLAGS_BLOCKED) == 0) { - if (queue->tq_flags & TQ_FLAGS_INTR) { - schedule_ithread(queue); - } else { - queue->tq_enqueue(queue->tq_context); - } - } + if ((queue->tq_flags & TQ_FLAGS_BLOCKED) == 0) + queue->tq_enqueue(queue->tq_context); return (0); } @@ -445,7 +403,7 @@ gtaskqueue_drain_all(struct gtaskqueue *queue) static int _gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, - cpuset_t *mask, bool intr, const char *name, va_list ap) + cpuset_t *mask, const char *name, va_list ap) { char ktname[MAXCOMLEN + 1]; struct thread *td; @@ -464,12 +422,6 @@ _gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, printf("%s: no memory for %s threads\n", __func__, ktname); return (ENOMEM); } - tq->tq_gt_intrs = malloc(sizeof(struct gt_intr_thread) * count, M_GTASKQUEUE, - M_NOWAIT | M_ZERO); - if (tq->tq_gt_intrs == NULL) { - printf("%s: no memory for %s intr info\n", __func__, ktname); - return (ENOMEM); - } for (i = 0; i < count; i++) { if (count == 1) @@ -487,9 +439,6 @@ _gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, } else tq->tq_tcount++; } - if (intr) - tq->tq_flags |= TQ_FLAGS_INTR; - for (i = 0; i < count; i++) { if (tq->tq_threads[i] == NULL) continue; @@ -509,14 +458,7 @@ _gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, } thread_lock(td); sched_prio(td, pri); - if (intr) { - /* we need to schedule the thread from the interrupt handler for this to work */ - TD_SET_IWAIT(td); - sched_class(td, PRI_ITHD); - td->td_pflags |= TDP_ITHREAD; - } else { - sched_add(td, SRQ_BORING); - } + sched_add(td, SRQ_BORING); thread_unlock(td); } @@ -525,13 +467,13 @@ _gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, static int gtaskqueue_start_threads(struct gtaskqueue **tqp, int count, int pri, - bool intr, const char *name, ...) + const char *name, ...) { va_list ap; int error; va_start(ap, name); - error = _gtaskqueue_start_threads(tqp, count, pri, NULL, intr, name, ap); + error = _gtaskqueue_start_threads(tqp, count, pri, NULL, name, ap); va_end(ap); return (error); } @@ -549,58 +491,16 @@ gtaskqueue_run_callback(struct gtaskqueue *tq, } static void -intr_thread_loop(struct gtaskqueue *tq) +gtaskqueue_thread_loop(void *arg) { - struct gt_intr_thread *git; - struct thread *td; - - git = &tq->tq_gt_intrs[0]; - td = tq->tq_threads[0]; - MPASS(tq->tq_tcount == 1); + struct gtaskqueue **tqp, *tq; + tqp = arg; + tq = *tqp; + gtaskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_INIT); + TQ_LOCK(tq); while ((tq->tq_flags & TQ_FLAGS_ACTIVE) != 0) { - THREAD_NO_SLEEPING(); - while (atomic_cmpset_acq_int(&git->git_need, 1, 0) != 0) { - gtaskqueue_run_locked(tq); - } - THREAD_SLEEPING_OK(); - - /* - * Because taskqueue_run() can drop tq_mutex, we need to - * check if the TQ_FLAGS_ACTIVE flag wasn't removed in the - * meantime, which means we missed a wakeup. - */ - if ((tq->tq_flags & TQ_FLAGS_ACTIVE) == 0) - break; - - TQ_UNLOCK(tq); - WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); - mtx_assert(&Giant, MA_NOTOWNED); - thread_lock(td); - if (atomic_load_acq_int(&git->git_need) == 0 && - (git->git_flags & (IT_DEAD | IT_WAIT)) == 0) { - TD_SET_IWAIT(td); - mi_switch(SW_VOL | SWT_IWAIT, NULL); - } -#if 0 - /* XXX is this something we want? */ - if (git->git_flags & IT_WAIT) { - wake = 1; - git->git_flags &= ~IT_WAIT; - } -#endif - thread_unlock(td); - TQ_LOCK(tq); - } - THREAD_NO_SLEEPING(); - gtaskqueue_run_locked(tq); - THREAD_SLEEPING_OK(); -} - -static void -timeshare_thread_loop(struct gtaskqueue *tq) -{ - while ((tq->tq_flags & TQ_FLAGS_ACTIVE) != 0) { + /* XXX ? */ gtaskqueue_run_locked(tq); /* * Because taskqueue_run() can drop tq_mutex, we need to @@ -612,23 +512,6 @@ timeshare_thread_loop(struct gtaskqueue *tq) TQ_SLEEP(tq, tq, &tq->tq_mutex, 0, "-", 0); } gtaskqueue_run_locked(tq); -} - -static void -gtaskqueue_thread_loop(void *arg) -{ - struct gtaskqueue **tqp, *tq; - - tqp = arg; - tq = *tqp; - gtaskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_INIT); - TQ_LOCK(tq); - if (curthread->td_pflags & TDP_ITHREAD) { - intr_thread_loop(tq); - } else { - timeshare_thread_loop(tq); - } - /* * This thread is on its way out, so just drop the lock temporarily * in order to call the shutdown callback. This allows the callback @@ -675,17 +558,11 @@ struct taskqgroup_cpu { struct taskqgroup { struct taskqgroup_cpu tqg_queue[MAXCPU]; struct mtx tqg_lock; - void (*adjust_func)(void*); char * tqg_name; int tqg_adjusting; int tqg_stride; int tqg_cnt; - int tqg_pri; - int tqg_flags; - bool tqg_intr; }; -#define TQG_NEED_ADJUST 0x1 -#define TQG_ADJUSTED 0x2 struct taskq_bind_task { struct gtask bt_task; @@ -693,16 +570,16 @@ struct taskq_bind_task { }; static void -taskqgroup_cpu_create(struct taskqgroup *qgroup, int idx, int cpu, bool intr, int pri) +taskqgroup_cpu_create(struct taskqgroup *qgroup, int idx, int cpu) { struct taskqgroup_cpu *qcpu; qcpu = &qgroup->tqg_queue[idx]; LIST_INIT(&qcpu->tgc_tasks); - qcpu->tgc_taskq = gtaskqueue_create_fast(NULL, M_WAITOK | M_ZERO, + qcpu->tgc_taskq = gtaskqueue_create_fast(NULL, M_WAITOK, taskqueue_thread_enqueue, &qcpu->tgc_taskq); - gtaskqueue_start_threads(&qcpu->tgc_taskq, 1, pri, - intr, "%s_%d", qgroup->tqg_name, idx); + gtaskqueue_start_threads(&qcpu->tgc_taskq, 1, PI_SOFT, + "%s_%d", qgroup->tqg_name, idx); qcpu->tgc_cpu = cpu; } @@ -789,17 +666,9 @@ taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *gtask, int qid, error; gtask->gt_uniq = uniq; - gtask->gt_name = name; + snprintf(gtask->gt_name, GROUPTASK_NAMELEN, "%s", name ? name : "grouptask"); gtask->gt_irq = irq; gtask->gt_cpu = -1; - - mtx_lock(&qgroup->tqg_lock); - qgroup->tqg_flags |= TQG_NEED_ADJUST; - mtx_unlock(&qgroup->tqg_lock); - - if (tqg_smp_started && !(qgroup->tqg_flags & TQG_ADJUSTED)) - qgroup->adjust_func(NULL); - mtx_lock(&qgroup->tqg_lock); qid = taskqgroup_find(qgroup, uniq); qgroup->tqg_queue[qid].tgc_cnt++; @@ -810,9 +679,9 @@ taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *gtask, CPU_ZERO(&mask); CPU_SET(qgroup->tqg_queue[qid].tgc_cpu, &mask); mtx_unlock(&qgroup->tqg_lock); - error = intr_setaffinity(irq, CPU_WHICH_INTRHANDLER, &mask); + error = intr_setaffinity(irq, CPU_WHICH_IRQ, &mask); if (error) - printf("taskqgroup_attach: setaffinity failed: %d\n", error); + printf("%s: setaffinity failed for %s: %d\n", __func__, gtask->gt_name, error); } else mtx_unlock(&qgroup->tqg_lock); } @@ -831,10 +700,11 @@ taskqgroup_attach_deferred(struct taskqgroup *qgroup, struct grouptask *gtask) CPU_ZERO(&mask); CPU_SET(cpu, &mask); - error = intr_setaffinity(gtask->gt_irq, CPU_WHICH_INTRHANDLER, &mask); + error = intr_setaffinity(gtask->gt_irq, CPU_WHICH_IRQ, &mask); mtx_lock(&qgroup->tqg_lock); if (error) - printf("taskqgroup_attach_deferred: setaffinity failed: %d\n", error); + printf("%s: %s setaffinity failed: %d\n", __func__, gtask->gt_name, error); + } qgroup->tqg_queue[qid].tgc_cnt++; @@ -845,79 +715,28 @@ taskqgroup_attach_deferred(struct taskqgroup *qgroup, struct grouptask *gtask) mtx_unlock(&qgroup->tqg_lock); } -static int -taskqgroup_adjust_deferred(struct taskqgroup *qgroup, int cpu) -{ - int i, error = 0, cpu_max = -1; - - mtx_lock(&qgroup->tqg_lock); - for (i = 0; i < qgroup->tqg_cnt; i++) - if (qgroup->tqg_queue[i].tgc_cpu > cpu_max) - cpu_max = qgroup->tqg_queue[i].tgc_cpu; - if (cpu_max >= cpu) { - mtx_unlock(&qgroup->tqg_lock); - return (0); - } - MPASS(cpu <= mp_maxid); - error = _taskqgroup_adjust(qgroup, cpu + 1, qgroup->tqg_stride, - qgroup->tqg_intr, qgroup->tqg_pri); - if (error) { - printf("%s: _taskqgroup_adjust(%p, %d, %d, %d, %d) => %d\n\n", - __func__, qgroup, cpu + 1, qgroup->tqg_stride, qgroup->tqg_intr, - qgroup->tqg_pri, error); - goto out; - } - for (i = 0; i < qgroup->tqg_cnt; i++) - if (qgroup->tqg_queue[i].tgc_cpu > cpu_max) - cpu_max = qgroup->tqg_queue[i].tgc_cpu; - MPASS(cpu_max >= cpu); -out: - mtx_unlock(&qgroup->tqg_lock); - return (error); -} - int taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *gtask, void *uniq, int cpu, int irq, char *name) { cpuset_t mask; - int i, error, qid; + int i, qid, error; qid = -1; gtask->gt_uniq = uniq; - gtask->gt_name = name; + snprintf(gtask->gt_name, GROUPTASK_NAMELEN, "%s", name ? name : "grouptask"); gtask->gt_irq = irq; gtask->gt_cpu = cpu; - MPASS(cpu >= 0); - - mtx_lock(&qgroup->tqg_lock); - qgroup->tqg_flags |= TQG_NEED_ADJUST; - mtx_unlock(&qgroup->tqg_lock); - - if (tqg_smp_started && !(qgroup->tqg_flags & TQG_ADJUSTED)) { - uintptr_t cpuid = cpu + 1; - qgroup->adjust_func((void *)cpuid); - } - if ((error = taskqgroup_adjust_deferred(qgroup, cpu))) - return (error); - mtx_lock(&qgroup->tqg_lock); if (tqg_smp_started) { - for (i = 0; i < qgroup->tqg_cnt; i++) { + for (i = 0; i < qgroup->tqg_cnt; i++) if (qgroup->tqg_queue[i].tgc_cpu == cpu) { qid = i; break; } -#ifdef INVARIANTS - else - printf("qgroup->tqg_queue[%d].tgc_cpu=0x%x tgc_cnt=0x%x\n", - i, qgroup->tqg_queue[i].tgc_cpu, qgroup->tqg_queue[i].tgc_cnt); - -#endif - } if (qid == -1) { mtx_unlock(&qgroup->tqg_lock); - printf("%s: qid not found for cpu=%d\n", __func__, cpu); + printf("%s: qid not found for %s cpu=%d\n", __func__, gtask->gt_name, cpu); return (EINVAL); } } else @@ -931,9 +750,9 @@ taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *gtask, CPU_ZERO(&mask); CPU_SET(cpu, &mask); if (irq != -1 && tqg_smp_started) { - error = intr_setaffinity(irq, CPU_WHICH_INTRHANDLER, &mask); + error = intr_setaffinity(irq, CPU_WHICH_IRQ, &mask); if (error) - printf("taskqgroup_attach_cpu: setaffinity failed: %d\n", error); + printf("%s: setaffinity failed: %d\n", __func__, error); } return (0); } @@ -948,12 +767,7 @@ taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtas irq = gtask->gt_irq; cpu = gtask->gt_cpu; MPASS(tqg_smp_started); - - if ((error = taskqgroup_adjust_deferred(qgroup, cpu))) - return (error); mtx_lock(&qgroup->tqg_lock); - /* adjust as needed */ - MPASS(cpu <= mp_maxid); for (i = 0; i < qgroup->tqg_cnt; i++) if (qgroup->tqg_queue[i].tgc_cpu == cpu) { qid = i; @@ -961,7 +775,7 @@ taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtas } if (qid == -1) { mtx_unlock(&qgroup->tqg_lock); - printf("%s: qid not found for cpu=%d\n", __func__, cpu); + printf("%s: qid not found for %s cpu=%d\n", __func__, gtask->gt_name, cpu); return (EINVAL); } qgroup->tqg_queue[qid].tgc_cnt++; @@ -974,9 +788,9 @@ taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtas CPU_SET(cpu, &mask); if (irq != -1) { - error = intr_setaffinity(irq, CPU_WHICH_INTRHANDLER, &mask); + error = intr_setaffinity(irq, CPU_WHICH_IRQ, &mask); if (error) - printf("taskqgroup_attach_cpu: setaffinity failed: %d\n", error); + printf("%s: setaffinity failed: %d\n", __func__, error); } return (0); } @@ -991,7 +805,7 @@ taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask) if (qgroup->tqg_queue[i].tgc_taskq == gtask->gt_taskqueue) break; if (i == qgroup->tqg_cnt) - panic("taskqgroup_detach: task not in group\n"); + panic("taskqgroup_detach: task %s not in group\n", gtask->gt_name); qgroup->tqg_queue[i].tgc_cnt--; LIST_REMOVE(gtask, gt_list); mtx_unlock(&qgroup->tqg_lock); @@ -1013,28 +827,11 @@ taskqgroup_binder(void *ctx) thread_unlock(curthread); if (error) - printf("taskqgroup_binder: setaffinity failed: %d\n", + printf("%s: setaffinity failed: %d\n", __func__, error); free(gtask, M_DEVBUF); - } -static void -taskqgroup_ithread_binder(void *ctx) -{ - struct taskq_bind_task *gtask = (struct taskq_bind_task *)ctx; - cpuset_t mask; - int error; - CPU_ZERO(&mask); - CPU_SET(gtask->bt_cpuid, &mask); - error = cpuset_setthread(curthread->td_tid, &mask); - - if (error) - printf("taskqgroup_binder: setaffinity failed: %d\n", - error); - free(gtask, M_DEVBUF); - -} static void taskqgroup_bind(struct taskqgroup *qgroup) { @@ -1050,10 +847,7 @@ taskqgroup_bind(struct taskqgroup *qgroup) for (i = 0; i < qgroup->tqg_cnt; i++) { gtask = malloc(sizeof (*gtask), M_DEVBUF, M_WAITOK); - if (qgroup->tqg_intr) - GTASK_INIT(>ask->bt_task, 0, 0, taskqgroup_ithread_binder, gtask); - else - GTASK_INIT(>ask->bt_task, 0, 0, taskqgroup_binder, gtask); + GTASK_INIT(>ask->bt_task, 0, 0, taskqgroup_binder, gtask); gtask->bt_cpuid = qgroup->tqg_queue[i].tgc_cpu; grouptaskqueue_enqueue(qgroup->tqg_queue[i].tgc_taskq, >ask->bt_task); @@ -1061,7 +855,7 @@ taskqgroup_bind(struct taskqgroup *qgroup) } static int -_taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri) +_taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride) { LIST_HEAD(, grouptask) gtask_head = LIST_HEAD_INITIALIZER(NULL); struct grouptask *gtask; @@ -1076,22 +870,14 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, return (EINVAL); } if (qgroup->tqg_adjusting) { - printf("%s: failed: adjusting\n", __func__); + printf("%s failed: adjusting\n", __func__); return (EBUSY); } - /* No work to be done */ - if (qgroup->tqg_cnt == cnt) - return (0); qgroup->tqg_adjusting = 1; old_cnt = qgroup->tqg_cnt; old_cpu = 0; - if (old_cnt < cnt) { - int old_max_idx = max(0, old_cnt-1); - old_cpu = qgroup->tqg_queue[old_max_idx].tgc_cpu; - if (old_cnt > 0) - for (k = 0; k < stride; k++) - old_cpu = CPU_NEXT(old_cpu); - } + if (old_cnt < cnt) + old_cpu = qgroup->tqg_queue[old_cnt].tgc_cpu; mtx_unlock(&qgroup->tqg_lock); /* * Set up queue for tasks added before boot. @@ -1107,7 +893,7 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, */ cpu = old_cpu; for (i = old_cnt; i < cnt; i++) { - taskqgroup_cpu_create(qgroup, i, cpu, ithread, pri); + taskqgroup_cpu_create(qgroup, i, cpu); for (k = 0; k < stride; k++) cpu = CPU_NEXT(cpu); @@ -1115,8 +901,6 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, mtx_lock(&qgroup->tqg_lock); qgroup->tqg_cnt = cnt; qgroup->tqg_stride = stride; - qgroup->tqg_intr = ithread; - qgroup->tqg_pri = pri; /* * Adjust drivers to use new taskqs. @@ -1162,34 +946,12 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, } int -taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri) +taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride) { int error; mtx_lock(&qgroup->tqg_lock); - error = _taskqgroup_adjust(qgroup, cnt, stride, ithread, pri); - mtx_unlock(&qgroup->tqg_lock); - - return (error); -} - -void -taskqgroup_set_adjust(struct taskqgroup *qgroup, void (*adjust_func)(void*)) -{ - qgroup-> adjust_func = adjust_func; -} - -int -taskqgroup_adjust_once(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri) -{ - int error = 0; - - mtx_lock(&qgroup->tqg_lock); - if ((qgroup->tqg_flags & (TQG_ADJUSTED|TQG_NEED_ADJUST)) == TQG_NEED_ADJUST) { - qgroup->tqg_flags |= TQG_ADJUSTED; - error = _taskqgroup_adjust(qgroup, cnt, stride, ithread, pri); - MPASS(error == 0); - } + error = _taskqgroup_adjust(qgroup, cnt, stride); mtx_unlock(&qgroup->tqg_lock); return (error); @@ -1204,9 +966,7 @@ taskqgroup_create(char *name) mtx_init(&qgroup->tqg_lock, "taskqgroup", NULL, MTX_DEF); qgroup->tqg_name = name; LIST_INIT(&qgroup->tqg_queue[0].tgc_tasks); - MPASS(qgroup->tqg_queue[0].tgc_cnt == 0); - MPASS(qgroup->tqg_queue[0].tgc_cpu == 0); - MPASS(qgroup->tqg_queue[0].tgc_taskq == 0); + return (qgroup); } diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index d20c56b85ef4..249aab4b3471 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #include #endif -int kdb_active = 0; +u_char __read_frequently kdb_active = 0; static void *kdb_jmpbufp = NULL; struct kdb_dbbe *kdb_dbbe = NULL; static struct pcb kdb_pcb; @@ -513,12 +513,12 @@ kdb_reenter(void) struct pcb * kdb_thr_ctx(struct thread *thr) -{ +{ #if defined(SMP) && defined(KDB_STOPPEDPCB) struct pcpu *pc; #endif - - if (thr == curthread) + + if (thr == curthread) return (&kdb_pcb); #if defined(SMP) && defined(KDB_STOPPEDPCB) diff --git a/sys/kern/subr_mbpool.c b/sys/kern/subr_mbpool.c deleted file mode 100644 index de79ad4d8c76..000000000000 --- a/sys/kern/subr_mbpool.c +++ /dev/null @@ -1,398 +0,0 @@ -/*- - * Copyright (c) 2003 - * Fraunhofer Institute for Open Communication Systems (FhG Fokus). - * All rights reserved. - * - * 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 AUTHOR 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 AUTHOR 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. - * - * Author: Hartmut Brandt - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -MODULE_VERSION(libmbpool, 1); - -/* - * Memory is allocated as DMA-able pages. Each page is divided into a number - * of equal chunks where the last 4 bytes of each chunk are occupied by - * the page number and the chunk number. The caller must take these four - * bytes into account when specifying the chunk size. Each page is mapped by - * its own DMA map using the user specified DMA tag. - * - * Each chunk has a used and a card bit in the high bits of its page number. - * 0 0 chunk is free and may be allocated - * 1 1 chunk has been given to the interface - * 0 1 chunk is traveling through the system - * 1 0 illegal - */ -struct mbtrail { - uint16_t chunk; - uint16_t page; -}; -#define MBP_CARD 0x8000 -#define MBP_USED 0x4000 -#define MBP_PMSK 0x3fff /* page number mask */ -#define MBP_CMSK 0x01ff /* chunk number mask */ - -struct mbfree { - SLIST_ENTRY(mbfree) link; /* link on free list */ -}; - -struct mbpage { - bus_dmamap_t map; /* map for this page */ - bus_addr_t phy; /* physical address */ - void *va; /* the memory */ -}; - -struct mbpool { - const char *name; /* a name for this pool */ - bus_dma_tag_t dmat; /* tag for mapping */ - u_int max_pages; /* maximum number of pages */ - size_t page_size; /* size of each allocation */ - size_t chunk_size; /* size of each external mbuf */ - - struct mtx free_lock; /* lock of free list */ - SLIST_HEAD(, mbfree) free_list; /* free list */ - u_int npages; /* current number of pages */ - u_int nchunks; /* chunks per page */ - struct mbpage pages[]; /* pages */ -}; - -static MALLOC_DEFINE(M_MBPOOL, "mbpools", "mbuf pools"); - -/* - * Make a trail pointer from a chunk pointer - */ -#define C2T(P, C) ((struct mbtrail *)((char *)(C) + (P)->chunk_size - \ - sizeof(struct mbtrail))) - -/* - * Make a free chunk pointer from a chunk number - */ -#define N2C(P, PG, C) ((struct mbfree *)((char *)(PG)->va + \ - (C) * (P)->chunk_size)) - -/* - * Make/parse handles - */ -#define HMAKE(P, C) ((((P) & MBP_PMSK) << 16) | ((C) << 7)) -#define HPAGE(H) (((H) >> 16) & MBP_PMSK) -#define HCHUNK(H) (((H) >> 7) & MBP_CMSK) - -/* - * initialize a pool - */ -int -mbp_create(struct mbpool **pp, const char *name, bus_dma_tag_t dmat, - u_int max_pages, size_t page_size, size_t chunk_size) -{ - u_int nchunks; - - if (max_pages > MBPOOL_MAX_MAXPAGES || chunk_size == 0) - return (EINVAL); - nchunks = page_size / chunk_size; - if (nchunks == 0 || nchunks > MBPOOL_MAX_CHUNKS) - return (EINVAL); - - (*pp) = malloc(sizeof(struct mbpool) + - max_pages * sizeof(struct mbpage), - M_MBPOOL, M_WAITOK | M_ZERO); - - (*pp)->name = name; - (*pp)->dmat = dmat; - (*pp)->max_pages = max_pages; - (*pp)->page_size = page_size; - (*pp)->chunk_size = chunk_size; - (*pp)->nchunks = nchunks; - - SLIST_INIT(&(*pp)->free_list); - mtx_init(&(*pp)->free_lock, name, NULL, MTX_DEF); - - return (0); -} - -/* - * destroy a pool - */ -void -mbp_destroy(struct mbpool *p) -{ - u_int i; - struct mbpage *pg; -#ifdef DIAGNOSTIC - struct mbtrail *tr; - u_int b; -#endif - - for (i = 0; i < p->npages; i++) { - pg = &p->pages[i]; -#ifdef DIAGNOSTIC - for (b = 0; b < p->nchunks; b++) { - tr = C2T(p, N2C(p, pg, b)); - if (tr->page & MBP_CARD) - printf("%s: (%s) buf still on card" - " %u/%u\n", __func__, p->name, i, b); - if (tr->page & MBP_USED) - printf("%s: (%s) sbuf still in use" - " %u/%u\n", __func__, p->name, i, b); - } -#endif - bus_dmamap_unload(p->dmat, pg->map); - bus_dmamem_free(p->dmat, pg->va, pg->map); - } - mtx_destroy(&p->free_lock); - - free(p, M_MBPOOL); -} - -/* - * Helper function when loading a one segment DMA buffer. - */ -static void -mbp_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - if (error == 0) - *(bus_addr_t *)arg = segs[0].ds_addr; -} - -/* - * Allocate a new page - */ -static void -mbp_alloc_page(struct mbpool *p) -{ - int error; - struct mbpage *pg; - u_int i; - struct mbfree *f; - struct mbtrail *t; - - if (p->npages == p->max_pages) { -#ifdef DIAGNOSTIC - printf("%s: (%s) page limit reached %u\n", __func__, - p->name, p->max_pages); -#endif - return; - } - pg = &p->pages[p->npages]; - - error = bus_dmamem_alloc(p->dmat, &pg->va, BUS_DMA_NOWAIT, &pg->map); - if (error != 0) - return; - - error = bus_dmamap_load(p->dmat, pg->map, pg->va, p->page_size, - mbp_callback, &pg->phy, 0); - if (error != 0) { - bus_dmamem_free(p->dmat, pg->va, pg->map); - return; - } - - for (i = 0; i < p->nchunks; i++) { - f = N2C(p, pg, i); - t = C2T(p, f); - t->page = p->npages; - t->chunk = i; - SLIST_INSERT_HEAD(&p->free_list, f, link); - } - - p->npages++; -} - -/* - * allocate a chunk - */ -void * -mbp_alloc(struct mbpool *p, bus_addr_t *pap, uint32_t *hp) -{ - struct mbfree *cf; - struct mbtrail *t; - - mtx_lock(&p->free_lock); - if ((cf = SLIST_FIRST(&p->free_list)) == NULL) { - mbp_alloc_page(p); - cf = SLIST_FIRST(&p->free_list); - } - if (cf == NULL) { - mtx_unlock(&p->free_lock); - return (NULL); - } - SLIST_REMOVE_HEAD(&p->free_list, link); - mtx_unlock(&p->free_lock); - - t = C2T(p, cf); - - *pap = p->pages[t->page].phy + t->chunk * p->chunk_size; - *hp = HMAKE(t->page, t->chunk); - - t->page |= MBP_CARD | MBP_USED; - - return (cf); -} - -/* - * Free a chunk - */ -void -mbp_free(struct mbpool *p, void *ptr) -{ - struct mbtrail *t; - - mtx_lock(&p->free_lock); - t = C2T(p, ptr); - t->page &= ~(MBP_USED | MBP_CARD); - SLIST_INSERT_HEAD(&p->free_list, (struct mbfree *)ptr, link); - mtx_unlock(&p->free_lock); -} - -/* - * Mbuf system external mbuf free routine - */ -void -mbp_ext_free(struct mbuf *m, void *buf, void *arg) -{ - - mbp_free(arg, buf); -} - -/* - * Free all buffers that are marked as being on the card - */ -void -mbp_card_free(struct mbpool *p) -{ - u_int i, b; - struct mbpage *pg; - struct mbtrail *tr; - struct mbfree *cf; - - mtx_lock(&p->free_lock); - for (i = 0; i < p->npages; i++) { - pg = &p->pages[i]; - for (b = 0; b < p->nchunks; b++) { - cf = N2C(p, pg, b); - tr = C2T(p, cf); - if (tr->page & MBP_CARD) { - tr->page &= MBP_PMSK; - SLIST_INSERT_HEAD(&p->free_list, cf, link); - } - } - } - mtx_unlock(&p->free_lock); -} - -/* - * Count buffers - */ -void -mbp_count(struct mbpool *p, u_int *used, u_int *card, u_int *free) -{ - u_int i, b; - struct mbpage *pg; - struct mbtrail *tr; - struct mbfree *cf; - - *used = *card = *free = 0; - for (i = 0; i < p->npages; i++) { - pg = &p->pages[i]; - for (b = 0; b < p->nchunks; b++) { - tr = C2T(p, N2C(p, pg, b)); - if (tr->page & MBP_CARD) - (*card)++; - if (tr->page & MBP_USED) - (*used)++; - } - } - mtx_lock(&p->free_lock); - SLIST_FOREACH(cf, &p->free_list, link) - (*free)++; - mtx_unlock(&p->free_lock); -} - -/* - * Get the buffer from a handle and clear the card flag. - */ -void * -mbp_get(struct mbpool *p, uint32_t h) -{ - struct mbfree *cf; - struct mbtrail *tr; - - cf = N2C(p, &p->pages[HPAGE(h)], HCHUNK(h)); - tr = C2T(p, cf); - -#ifdef DIAGNOSTIC - if (!(tr->page & MBP_CARD)) - printf("%s: (%s) chunk %u page %u not on card\n", __func__, - p->name, HCHUNK(h), HPAGE(h)); -#endif - - tr->page &= ~MBP_CARD; - return (cf); -} - -/* - * Get the buffer from a handle and keep the card flag. - */ -void * -mbp_get_keep(struct mbpool *p, uint32_t h) -{ - struct mbfree *cf; - struct mbtrail *tr; - - cf = N2C(p, &p->pages[HPAGE(h)], HCHUNK(h)); - tr = C2T(p, cf); - -#ifdef DIAGNOSTIC - if (!(tr->page & MBP_CARD)) - printf("%s: (%s) chunk %u page %u not on card\n", __func__, - p->name, HCHUNK(h), HPAGE(h)); -#endif - - return (cf); -} - -/* - * sync the chunk - */ -void -mbp_sync(struct mbpool *p, uint32_t h, bus_addr_t off, bus_size_t len, u_int op) -{ - -#if 0 - bus_dmamap_sync_size(p->dmat, p->pages[HPAGE(h)].map, - HCHUNK(h) * p->chunk_size + off, len, op); -#endif -} diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index 7edc605d96a1..2195c98d77a4 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -93,7 +93,10 @@ __FBSDID("$FreeBSD$"); * Constants for the hash table of sleep queue chains. * SC_TABLESIZE must be a power of two for SC_MASK to work properly. */ -#define SC_TABLESIZE 256 /* Must be power of 2. */ +#ifndef SC_TABLESIZE +#define SC_TABLESIZE 256 +#endif +CTASSERT(powerof2(SC_TABLESIZE)); #define SC_MASK (SC_TABLESIZE - 1) #define SC_SHIFT 8 #define SC_HASH(wc) ((((uintptr_t)(wc) >> SC_SHIFT) ^ (uintptr_t)(wc)) & \ @@ -137,7 +140,7 @@ struct sleepqueue_chain { u_int sc_depth; /* Length of sc_queues. */ u_int sc_max_depth; /* Max length of sc_queues. */ #endif -}; +} __aligned(CACHE_LINE_SIZE); #ifdef SLEEPQUEUE_PROFILING u_int sleepq_max_depth; @@ -1163,7 +1166,7 @@ sleepq_sbuf_print_stacks(struct sbuf *sb, void *wchan, int queue, M_TEMP, M_WAITOK); for (stack_idx = 0; stack_idx < stacks_to_allocate; stack_idx++) - st[stack_idx] = stack_create(); + st[stack_idx] = stack_create(M_WAITOK); /* Where we will store the td name, tid, etc. */ td_infos = malloc(sizeof(struct sbuf *) * stacks_to_allocate, @@ -1435,7 +1438,7 @@ DB_SHOW_COMMAND(sleepq, db_show_sleepqueue) if (TAILQ_EMPTY(&sq->sq_blocked[i])) db_printf("\tempty\n"); else - TAILQ_FOREACH(td, &sq->sq_blocked[0], + TAILQ_FOREACH(td, &sq->sq_blocked[i], td_slpq) { db_printf("\t%p (tid %d, pid %d, \"%s\")\n", td, td->td_tid, td->td_proc->p_pid, diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 81e11ee70e73..108705c98a25 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -84,8 +84,9 @@ SYSCTL_INT(_kern_smp, OID_AUTO, maxid, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxid, 0, SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxcpus, 0, "Max number of CPUs that the system was compiled for."); -SYSCTL_PROC(_kern_smp, OID_AUTO, active, CTLFLAG_RD | CTLTYPE_INT, NULL, 0, - sysctl_kern_smp_active, "I", "Indicates system is running in SMP mode"); +SYSCTL_PROC(_kern_smp, OID_AUTO, active, CTLFLAG_RD|CTLTYPE_INT|CTLFLAG_MPSAFE, + NULL, 0, sysctl_kern_smp_active, "I", + "Indicates system is running in SMP mode"); int smp_disabled = 0; /* has smp been disabled? */ SYSCTL_INT(_kern_smp, OID_AUTO, disabled, CTLFLAG_RDTUN|CTLFLAG_CAPRD, diff --git a/sys/kern/subr_stack.c b/sys/kern/subr_stack.c index 85102c04f03d..eb155726f00c 100644 --- a/sys/kern/subr_stack.c +++ b/sys/kern/subr_stack.c @@ -50,11 +50,11 @@ static int stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, static int stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset); struct stack * -stack_create(void) +stack_create(int flags) { struct stack *st; - st = malloc(sizeof *st, M_STACK, M_WAITOK | M_ZERO); + st = malloc(sizeof(*st), M_STACK, flags | M_ZERO); return (st); } diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c index 3d510775b9ef..867edbe75460 100644 --- a/sys/kern/subr_unit.c +++ b/sys/kern/subr_unit.c @@ -366,6 +366,26 @@ delete_unrhdr(struct unrhdr *uh) Free(uh); } +void +clear_unrhdr(struct unrhdr *uh) +{ + struct unr *up, *uq; + + KASSERT(TAILQ_EMPTY(&uh->ppfree), + ("unrhdr has postponed item for free")); + TAILQ_FOREACH_SAFE(up, &uh->head, list, uq) { + if (up->ptr != uh) { + Free(up->ptr); + } + Free(up); + } + uh->busy = 0; + uh->alloc = 0; + init_unrhdr(uh, uh->low, uh->high, uh->mtx); + + check_unrhdr(uh, __LINE__); +} + static __inline int is_bitmap(struct unrhdr *uh, struct unr *up) { diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index be3ca31df356..08385514d5d4 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -137,7 +137,7 @@ __FBSDID("$FreeBSD$"); #define WITNESS_COUNT 1536 #endif #define WITNESS_HASH_SIZE 251 /* Prime, gives load factor < 2 */ -#define WITNESS_PENDLIST (1024 + MAXCPU) +#define WITNESS_PENDLIST (2048 + MAXCPU) /* Allocate 256 KB of stack data space */ #define WITNESS_LO_DATA_COUNT 2048 @@ -2539,31 +2539,18 @@ DB_SHOW_COMMAND(witness, db_witness_display) } #endif -static int -sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) +static void +sbuf_print_witness_badstacks(struct sbuf *sb, size_t *oldidx) { struct witness_lock_order_data *data1, *data2, *tmp_data1, *tmp_data2; struct witness *tmp_w1, *tmp_w2, *w1, *w2; - struct sbuf *sb; u_int w_rmatrix1, w_rmatrix2; - int error, generation, i, j; + int generation, i, j; tmp_data1 = NULL; tmp_data2 = NULL; tmp_w1 = NULL; tmp_w2 = NULL; - if (witness_watch < 1) { - error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning)); - return (error); - } - if (witness_cold) { - error = SYSCTL_OUT(req, w_stillcold, sizeof(w_stillcold)); - return (error); - } - error = 0; - sb = sbuf_new(NULL, NULL, badstack_sbuf_size, SBUF_AUTOEXTEND); - if (sb == NULL) - return (ENOMEM); /* Allocate and init temporary storage space. */ tmp_w1 = malloc(sizeof(struct witness), M_TEMP, M_WAITOK | M_ZERO); @@ -2587,7 +2574,7 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) mtx_unlock_spin(&w_mtx); /* The graph has changed, try again. */ - req->oldidx = 0; + *oldidx = 0; sbuf_clear(sb); goto restart; } @@ -2613,7 +2600,7 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) mtx_unlock_spin(&w_mtx); /* The graph has changed, try again. */ - req->oldidx = 0; + *oldidx = 0; sbuf_clear(sb); goto restart; } @@ -2672,7 +2659,7 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) * The graph changed while we were printing stack data, * try again. */ - req->oldidx = 0; + *oldidx = 0; sbuf_clear(sb); goto restart; } @@ -2683,6 +2670,28 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) free(tmp_data2, M_TEMP); free(tmp_w1, M_TEMP); free(tmp_w2, M_TEMP); +} + +static int +sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) +{ + struct sbuf *sb; + int error; + + if (witness_watch < 1) { + error = SYSCTL_OUT(req, w_notrunning, sizeof(w_notrunning)); + return (error); + } + if (witness_cold) { + error = SYSCTL_OUT(req, w_stillcold, sizeof(w_stillcold)); + return (error); + } + error = 0; + sb = sbuf_new(NULL, NULL, badstack_sbuf_size, SBUF_AUTOEXTEND); + if (sb == NULL) + return (ENOMEM); + + sbuf_print_witness_badstacks(sb, &req->oldidx); sbuf_finish(sb); error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); @@ -2691,6 +2700,27 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS) return (error); } +#ifdef DDB +static int +sbuf_db_printf_drain(void *arg __unused, const char *data, int len) +{ + + return (db_printf("%.*s", len, data)); +} + +DB_SHOW_COMMAND(badstacks, db_witness_badstacks) +{ + struct sbuf sb; + char buffer[128]; + size_t dummy; + + sbuf_new(&sb, buffer, sizeof(buffer), SBUF_FIXEDLEN); + sbuf_set_drain(&sb, sbuf_db_printf_drain, NULL); + sbuf_print_witness_badstacks(&sb, &dummy); + sbuf_finish(&sb); +} +#endif + static int sysctl_debug_witness_channel(SYSCTL_HANDLER_ARGS) { diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 4014c5fc6645..8a7e0d99d114 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -1039,8 +1039,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) switch (req) { case PT_STEP: - CTR2(KTR_PTRACE, "PT_STEP: tid %d (pid %d)", - td2->td_tid, p->p_pid); + CTR3(KTR_PTRACE, "PT_STEP: tid %d (pid %d), sig = %d", + td2->td_tid, p->p_pid, data); error = ptrace_single_step(td2); if (error) goto out; @@ -1129,6 +1129,13 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) } sendsig: + /* + * Clear the pending event for the thread that just + * reported its event (p_xthread). This may not be + * the thread passed to PT_CONTINUE, PT_STEP, etc. if + * the debugger is resuming a different thread. + */ + td2 = p->p_xthread; if (proctree_locked) { sx_xunlock(&proctree_lock); proctree_locked = 0; diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 60688960e24e..116fc437e4b9 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -1412,6 +1412,8 @@ semexit_myhook(void *arg, struct proc *p) * Go through the chain of undo vectors looking for one * associated with this process. */ + if (LIST_EMPTY(&semu_list)) + return; SEMUNDO_LOCK(); LIST_FOREACH(suptr, &semu_list, un_next) { if (suptr->un_proc == p) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 4d4cb3888ee1..6fe5f7630c58 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -188,7 +188,17 @@ mb_dupcl(struct mbuf *n, struct mbuf *m) KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n)); - n->m_ext = m->m_ext; + /* + * Cache access optimization. For most kinds of external + * storage we don't need full copy of m_ext, since the + * holder of the 'ext_count' is responsible to carry the + * free routine and its arguments. Exclusion is EXT_EXTREF, + * where 'ext_cnt' doesn't point into mbuf at all. + */ + if (m->m_ext.ext_type == EXT_EXTREF) + bcopy(&m->m_ext, &n->m_ext, sizeof(struct m_ext)); + else + bcopy(&m->m_ext, &n->m_ext, m_ext_copylen); n->m_flags |= M_EXT; n->m_flags |= m->m_flags & M_RDONLY; @@ -1439,62 +1449,59 @@ m_collapse(struct mbuf *m0, int how, int maxfrags) struct mbuf * m_fragment(struct mbuf *m0, int how, int length) { - struct mbuf *m_new = NULL, *m_final = NULL; - int progress = 0; + struct mbuf *m_first, *m_last; + int divisor = 255, progress = 0, fraglen; if (!(m0->m_flags & M_PKTHDR)) return (m0); - if ((length == 0) || (length < -2)) + if (length == 0 || length < -2) return (m0); + if (length > MCLBYTES) + length = MCLBYTES; + if (length < 0 && divisor > MCLBYTES) + divisor = MCLBYTES; + if (length == -1) + length = 1 + (arc4random() % divisor); + if (length > 0) + fraglen = length; m_fixhdr(m0); /* Needed sanity check */ - m_final = m_getcl(how, MT_DATA, M_PKTHDR); - - if (m_final == NULL) + m_first = m_getcl(how, MT_DATA, M_PKTHDR); + if (m_first == NULL) goto nospace; - if (m_dup_pkthdr(m_final, m0, how) == 0) + if (m_dup_pkthdr(m_first, m0, how) == 0) goto nospace; - m_new = m_final; - - if (length == -1) - length = 1 + (arc4random() & 255); + m_last = m_first; while (progress < m0->m_pkthdr.len) { - int fraglen; - - if (length > 0) - fraglen = length; - else - fraglen = 1 + (arc4random() & 255); + if (length == -2) + fraglen = 1 + (arc4random() % divisor); if (fraglen > m0->m_pkthdr.len - progress) fraglen = m0->m_pkthdr.len - progress; - if (fraglen > MCLBYTES) - fraglen = MCLBYTES; - - if (m_new == NULL) { - m_new = m_getcl(how, MT_DATA, 0); + if (progress != 0) { + struct mbuf *m_new = m_getcl(how, MT_DATA, 0); if (m_new == NULL) goto nospace; + + m_last->m_next = m_new; + m_last = m_new; } - m_copydata(m0, progress, fraglen, mtod(m_new, caddr_t)); + m_copydata(m0, progress, fraglen, mtod(m_last, caddr_t)); progress += fraglen; - m_new->m_len = fraglen; - if (m_new != m_final) - m_cat(m_final, m_new); - m_new = NULL; + m_last->m_len = fraglen; } m_freem(m0); - m0 = m_final; + m0 = m_first; return (m0); nospace: - if (m_final) - m_freem(m_final); + if (m_first) + m_freem(m_first); /* Return the original chain on failure */ return (m0); } diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index 33e0ddfd65fb..a4fdb85a95c3 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -209,12 +209,10 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) } vm_page_lock(m); vm_page_hold(m); - if (m->queue == PQ_NONE) { - vm_page_deactivate(m); - } else { - /* Requeue to maintain LRU ordering. */ - vm_page_requeue(m); - } + if (vm_page_active(m)) + vm_page_reference(m); + else + vm_page_activate(m); vm_page_unlock(m); VM_OBJECT_WUNLOCK(obj); error = uiomove_fromphys(&m, offset, tlen, uio); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 5b3015de6caf..ae4c651d686f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -3688,24 +3688,41 @@ soisconnecting(struct socket *so) void soisconnected(struct socket *so) { - struct socket *head; - int ret; - /* - * XXXGL: this is the only place where we acquire socket locks - * in reverse order: first child, then listening socket. To - * avoid possible LOR, use try semantics. - */ -restart: SOCK_LOCK(so); - if ((head = so->so_listen) != NULL && - __predict_false(SOLISTEN_TRYLOCK(head) == 0)) { - SOCK_UNLOCK(so); - goto restart; - } so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); so->so_state |= SS_ISCONNECTED; - if (head != NULL && (so->so_qstate == SQ_INCOMP)) { + + if (so->so_qstate == SQ_INCOMP) { + struct socket *head = so->so_listen; + int ret; + + KASSERT(head, ("%s: so %p on incomp of NULL", __func__, so)); + /* + * Promoting a socket from incomplete queue to complete, we + * need to go through reverse order of locking. We first do + * trylock, and if that doesn't succeed, we go the hard way + * leaving a reference and rechecking consistency after proper + * locking. + */ + if (__predict_false(SOLISTEN_TRYLOCK(head) == 0)) { + soref(head); + SOCK_UNLOCK(so); + SOLISTEN_LOCK(head); + SOCK_LOCK(so); + if (__predict_false(head != so->so_listen)) { + /* + * The socket went off the listen queue, + * should be lost race to close(2) of sol. + * The socket is about to soabort(). + */ + SOCK_UNLOCK(so); + sorele(head); + return; + } + /* Not the last one, as so holds a ref. */ + refcount_release(&head->so_count); + } again: if ((so->so_options & SO_ACCEPTFILTER) == 0) { TAILQ_REMOVE(&head->sol_incomp, so, so_list); @@ -3734,8 +3751,6 @@ soisconnected(struct socket *so) } return; } - if (head != NULL) - SOLISTEN_UNLOCK(head); SOCK_UNLOCK(so); wakeup(&so->so_timeo); sorwakeup(so); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 26bbb2f09623..f594dbba4ef8 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1646,12 +1646,20 @@ unp_pcblist(SYSCTL_HANDLER_ARGS) if (unp->unp_addr != NULL) bcopy(unp->unp_addr, &xu->xu_addr, unp->unp_addr->sun_len); + else + bzero(&xu->xu_addr, sizeof(xu->xu_addr)); if (unp->unp_conn != NULL && unp->unp_conn->unp_addr != NULL) bcopy(unp->unp_conn->unp_addr, &xu->xu_caddr, unp->unp_conn->unp_addr->sun_len); - bcopy(unp, &xu->xu_unp, sizeof *unp); + else + bzero(&xu->xu_caddr, sizeof(xu->xu_caddr)); + xu->unp_vnode = unp->unp_vnode; + xu->unp_conn = unp->unp_conn; + xu->xu_firstref = LIST_FIRST(&unp->unp_refs); + xu->xu_nextref = LIST_NEXT(unp, unp_reflink); + xu->unp_gencnt = unp->unp_gencnt; sotoxsocket(unp->unp_socket, &xu->xu_socket); UNP_PCB_UNLOCK(unp); error = SYSCTL_OUT(req, xu, sizeof *xu); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 302ab9e3b134..33cf46e65e14 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -90,11 +90,11 @@ static uint64_t jobseqno; #endif #ifndef MAX_AIO_QUEUE_PER_PROC -#define MAX_AIO_QUEUE_PER_PROC 256 /* Bigger than AIO_LISTIO_MAX */ +#define MAX_AIO_QUEUE_PER_PROC 256 #endif #ifndef MAX_AIO_QUEUE -#define MAX_AIO_QUEUE 1024 /* Bigger than AIO_LISTIO_MAX */ +#define MAX_AIO_QUEUE 1024 /* Bigger than MAX_AIO_QUEUE_PER_PROC */ #endif #ifndef MAX_BUF_AIO @@ -105,6 +105,7 @@ FEATURE(aio, "Asynchronous I/O"); SYSCTL_DECL(_p1003_1b); static MALLOC_DEFINE(M_LIO, "lio", "listio aio control block list"); +static MALLOC_DEFINE(M_AIOS, "aios", "aio_suspend aio control block list"); static SYSCTL_NODE(_vfs, OID_AUTO, aio, CTLFLAG_RW, 0, "Async IO management"); @@ -169,10 +170,14 @@ static int max_buf_aio = MAX_BUF_AIO; SYSCTL_INT(_vfs_aio, OID_AUTO, max_buf_aio, CTLFLAG_RW, &max_buf_aio, 0, "Maximum buf aio requests per process (stored in the process)"); -static int aio_listio_max = AIO_LISTIO_MAX; +/* + * Though redundant with vfs.aio.max_aio_queue_per_proc, POSIX requires + * sysconf(3) to support AIO_LISTIO_MAX, and we implement that with + * vfs.aio.aio_listio_max. + */ SYSCTL_INT(_p1003_1b, CTL_P1003_1B_AIO_LISTIO_MAX, aio_listio_max, - CTLFLAG_RDTUN | CTLFLAG_CAPRD, &aio_listio_max, 0, - "Maximum aio requests for a single lio_listio call"); + CTLFLAG_RD | CTLFLAG_CAPRD, &max_aio_queue_per_proc, + 0, "Maximum aio requests for a single lio_listio call"); #ifdef COMPAT_FREEBSD6 typedef struct oaiocb { @@ -334,10 +339,9 @@ static int filt_lio(struct knote *kn, long hint); * kaio Per process async io info * aiop async io process data * aiocb async io jobs - * aiol list io job pointer - internal to aio_suspend XXX * aiolio list io jobs */ -static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiol_zone, aiolio_zone; +static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiolio_zone; /* kqueue filters for aio */ static struct filterops aio_filtops = { @@ -394,11 +398,6 @@ static int aio_onceonly(void) { - if (aio_listio_max < AIO_LISTIO_MAX) - aio_listio_max = AIO_LISTIO_MAX; - if (aio_listio_max > MIN(MAX_AIO_QUEUE_PER_PROC, max_queue_count)) - aio_listio_max = MIN(MAX_AIO_QUEUE_PER_PROC, max_queue_count); - exit_tag = EVENTHANDLER_REGISTER(process_exit, aio_proc_rundown, NULL, EVENTHANDLER_PRI_ANY); exec_tag = EVENTHANDLER_REGISTER(process_exec, aio_proc_rundown_exec, @@ -416,8 +415,6 @@ aio_onceonly(void) NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); aiocb_zone = uma_zcreate("AIOCB", sizeof(struct kaiocb), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); - aiol_zone = uma_zcreate("AIOL", aio_listio_max * sizeof(intptr_t) , - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); aiolio_zone = uma_zcreate("AIOLIO", sizeof(struct aioliojob), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); aiod_lifetime = AIOD_LIFETIME_DEFAULT; @@ -1953,7 +1950,7 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_args *uap) struct aiocb **ujoblist; int error; - if (uap->nent < 0 || uap->nent > aio_listio_max) + if (uap->nent < 0 || uap->nent > max_aio_queue_per_proc) return (EINVAL); if (uap->timeout) { @@ -1964,11 +1961,11 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_args *uap) } else tsp = NULL; - ujoblist = uma_zalloc(aiol_zone, M_WAITOK); + ujoblist = malloc(uap->nent * sizeof(ujoblist[0]), M_AIOS, M_WAITOK); error = copyin(uap->aiocbp, ujoblist, uap->nent * sizeof(ujoblist[0])); if (error == 0) error = kern_aio_suspend(td, uap->nent, ujoblist, tsp); - uma_zfree(aiol_zone, ujoblist); + free(ujoblist, M_AIOS); return (error); } @@ -2161,7 +2158,7 @@ kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list, if ((mode != LIO_NOWAIT) && (mode != LIO_WAIT)) return (EINVAL); - if (nent < 0 || nent > aio_listio_max) + if (nent < 0 || nent > max_aio_queue_per_proc) return (EINVAL); if (p->p_aioinfo == NULL) @@ -2293,7 +2290,7 @@ freebsd6_lio_listio(struct thread *td, struct freebsd6_lio_listio_args *uap) return (EINVAL); nent = uap->nent; - if (nent < 0 || nent > aio_listio_max) + if (nent < 0 || nent > max_aio_queue_per_proc) return (EINVAL); if (uap->sig && (uap->mode == LIO_NOWAIT)) { @@ -2330,7 +2327,7 @@ sys_lio_listio(struct thread *td, struct lio_listio_args *uap) return (EINVAL); nent = uap->nent; - if (nent < 0 || nent > aio_listio_max) + if (nent < 0 || nent > max_aio_queue_per_proc) return (EINVAL); if (uap->sig && (uap->mode == LIO_NOWAIT)) { @@ -2799,7 +2796,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebsd32_aio_suspend_args *uap) uint32_t *ujoblist32; int error, i; - if (uap->nent < 0 || uap->nent > aio_listio_max) + if (uap->nent < 0 || uap->nent > max_aio_queue_per_proc) return (EINVAL); if (uap->timeout) { @@ -2812,17 +2809,17 @@ freebsd32_aio_suspend(struct thread *td, struct freebsd32_aio_suspend_args *uap) } else tsp = NULL; - ujoblist = uma_zalloc(aiol_zone, M_WAITOK); + ujoblist = malloc(uap->nent * sizeof(ujoblist[0]), M_AIOS, M_WAITOK); ujoblist32 = (uint32_t *)ujoblist; error = copyin(uap->aiocbp, ujoblist32, uap->nent * sizeof(ujoblist32[0])); if (error == 0) { - for (i = uap->nent; i > 0; i--) + for (i = uap->nent - 1; i >= 0; i--) ujoblist[i] = PTRIN(ujoblist32[i]); error = kern_aio_suspend(td, uap->nent, ujoblist, tsp); } - uma_zfree(aiol_zone, ujoblist); + free(ujoblist, M_AIOS); return (error); } @@ -2925,7 +2922,7 @@ freebsd6_freebsd32_lio_listio(struct thread *td, return (EINVAL); nent = uap->nent; - if (nent < 0 || nent > aio_listio_max) + if (nent < 0 || nent > max_aio_queue_per_proc) return (EINVAL); if (uap->sig && (uap->mode == LIO_NOWAIT)) { @@ -2971,7 +2968,7 @@ freebsd32_lio_listio(struct thread *td, struct freebsd32_lio_listio_args *uap) return (EINVAL); nent = uap->nent; - if (nent < 0 || nent > aio_listio_max) + if (nent < 0 || nent > max_aio_queue_per_proc) return (EINVAL); if (uap->sig && (uap->mode == LIO_NOWAIT)) { diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 77490be4d1f1..dd1f9bbd235a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -119,6 +119,8 @@ static void vfs_vmio_truncate(struct buf *bp, int npages); static void vfs_vmio_extend(struct buf *bp, int npages, int size); static int vfs_bio_clcheck(struct vnode *vp, int size, daddr_t lblkno, daddr_t blkno); +static void breada(struct vnode *, daddr_t *, int *, int, struct ucred *, int, + void (*)(struct buf *)); static int buf_flush(struct vnode *vp, int); static int buf_recycle(bool); static int buf_scan(bool); @@ -1783,15 +1785,14 @@ bufkva_reclaim(vmem_t *vmem, int flags) return; } - /* * Attempt to initiate asynchronous I/O on read-ahead blocks. We must * clear BIO_ERROR and B_INVAL prior to initiating I/O . If B_CACHE is set, * the buffer is valid and we do not have to do anything. */ -void -breada(struct vnode * vp, daddr_t * rablkno, int * rabsize, - int cnt, struct ucred * cred) +static void +breada(struct vnode * vp, daddr_t * rablkno, int * rabsize, int cnt, + struct ucred * cred, int flags, void (*ckhashfunc)(struct buf *)) { struct buf *rabp; int i; @@ -1800,31 +1801,34 @@ breada(struct vnode * vp, daddr_t * rablkno, int * rabsize, if (inmem(vp, *rablkno)) continue; rabp = getblk(vp, *rablkno, *rabsize, 0, 0, 0); - - if ((rabp->b_flags & B_CACHE) == 0) { - if (!TD_IS_IDLETHREAD(curthread)) { -#ifdef RACCT - if (racct_enable) { - PROC_LOCK(curproc); - racct_add_buf(curproc, rabp, 0); - PROC_UNLOCK(curproc); - } -#endif /* RACCT */ - curthread->td_ru.ru_inblock++; - } - rabp->b_flags |= B_ASYNC; - rabp->b_flags &= ~B_INVAL; - rabp->b_ioflags &= ~BIO_ERROR; - rabp->b_iocmd = BIO_READ; - if (rabp->b_rcred == NOCRED && cred != NOCRED) - rabp->b_rcred = crhold(cred); - vfs_busy_pages(rabp, 0); - BUF_KERNPROC(rabp); - rabp->b_iooffset = dbtob(rabp->b_blkno); - bstrategy(rabp); - } else { + if ((rabp->b_flags & B_CACHE) != 0) { brelse(rabp); + continue; } + if (!TD_IS_IDLETHREAD(curthread)) { +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(curproc); + racct_add_buf(curproc, rabp, 0); + PROC_UNLOCK(curproc); + } +#endif /* RACCT */ + curthread->td_ru.ru_inblock++; + } + rabp->b_flags |= B_ASYNC; + rabp->b_flags &= ~B_INVAL; + if ((flags & GB_CKHASH) != 0) { + rabp->b_flags |= B_CKHASH; + rabp->b_ckhashcalc = ckhashfunc; + } + rabp->b_ioflags &= ~BIO_ERROR; + rabp->b_iocmd = BIO_READ; + if (rabp->b_rcred == NOCRED && cred != NOCRED) + rabp->b_rcred = crhold(cred); + vfs_busy_pages(rabp, 0); + BUF_KERNPROC(rabp); + rabp->b_iooffset = dbtob(rabp->b_blkno); + bstrategy(rabp); } } @@ -1840,10 +1844,11 @@ breada(struct vnode * vp, daddr_t * rablkno, int * rabsize, */ int breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno, - int *rabsize, int cnt, struct ucred *cred, int flags, struct buf **bpp) + int *rabsize, int cnt, struct ucred *cred, int flags, + void (*ckhashfunc)(struct buf *), struct buf **bpp) { struct buf *bp; - int rv = 0, readwait = 0; + int readwait, rv; CTR3(KTR_BUF, "breadn(%p, %jd, %d)", vp, blkno, size); /* @@ -1853,7 +1858,10 @@ breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno, if (bp == NULL) return (EBUSY); - /* if not found in cache, do some I/O */ + /* + * If not found in cache, do some I/O + */ + readwait = 0; if ((bp->b_flags & B_CACHE) == 0) { if (!TD_IS_IDLETHREAD(curthread)) { #ifdef RACCT @@ -1867,6 +1875,10 @@ breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno, } bp->b_iocmd = BIO_READ; bp->b_flags &= ~B_INVAL; + if ((flags & GB_CKHASH) != 0) { + bp->b_flags |= B_CKHASH; + bp->b_ckhashcalc = ckhashfunc; + } bp->b_ioflags &= ~BIO_ERROR; if (bp->b_rcred == NOCRED && cred != NOCRED) bp->b_rcred = crhold(cred); @@ -1876,8 +1888,12 @@ breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno, ++readwait; } - breada(vp, rablkno, rabsize, cnt, cred); + /* + * Attempt to initiate asynchronous I/O on read-ahead blocks. + */ + breada(vp, rablkno, rabsize, cnt, cred, flags, ckhashfunc); + rv = 0; if (readwait) { rv = bufwait(bp); if (rv != 0) { @@ -4048,6 +4064,10 @@ bufdone(struct buf *bp) runningbufwakeup(bp); if (bp->b_iocmd == BIO_WRITE) dropobj = bp->b_bufobj; + else if ((bp->b_flags & B_CKHASH) != 0) { + KASSERT(buf_mapped(bp), ("biodone: bp %p not mapped", bp)); + (*bp->b_ckhashcalc)(bp); + } /* call optional completion function if requested */ if (bp->b_iodone != NULL) { biodone = bp->b_iodone; diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 6ccbac6052c1..49a21ba1da55 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -194,7 +194,7 @@ static __read_mostly LIST_HEAD(nchashhead, namecache) *nchashtbl;/* Hash Table * static u_long __read_mostly nchash; /* size of hash table */ SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0, "Size of namecache hash table"); -static u_long __read_mostly ncnegfactor = 16; /* ratio of negative entries */ +static u_long __read_mostly ncnegfactor = 12; /* ratio of negative entries */ SYSCTL_ULONG(_vfs, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0, "Ratio of negative namecache entries"); static u_long __exclusive_cache_line numneg; /* number of negative entries allocated */ @@ -983,6 +983,28 @@ cache_zap_locked_vnode(struct namecache *ncp, struct vnode *vp) return (error); } +static int +cache_zap_wlocked_bucket(struct namecache *ncp, struct rwlock *blp) +{ + struct mtx *dvlp, *vlp; + + cache_assert_bucket_locked(ncp, RA_WLOCKED); + + dvlp = VP2VNODELOCK(ncp->nc_dvp); + vlp = NULL; + if (!(ncp->nc_flag & NCF_NEGATIVE)) + vlp = VP2VNODELOCK(ncp->nc_vp); + if (cache_trylock_vnodes(dvlp, vlp) == 0) { + cache_zap_locked(ncp, false); + rw_wunlock(blp); + cache_unlock_vnodes(dvlp, vlp); + return (0); + } + + rw_wunlock(blp); + return (EAGAIN); +} + static int cache_zap_rlocked_bucket(struct namecache *ncp, struct rwlock *blp) { @@ -1058,7 +1080,6 @@ cache_lookup_unlock(struct rwlock *blp, struct mtx *vlp) if (blp != NULL) { rw_runlock(blp); - mtx_assert(vlp, MA_NOTOWNED); } else { mtx_unlock(vlp); } @@ -1117,6 +1138,87 @@ cache_lookup_dot(struct vnode *dvp, struct vnode **vpp, struct componentname *cn * not recursively acquired. */ +static __noinline int +cache_lookup_nomakeentry(struct vnode *dvp, struct vnode **vpp, + struct componentname *cnp, struct timespec *tsp, int *ticksp) +{ + struct namecache *ncp; + struct rwlock *blp; + struct mtx *dvlp, *dvlp2; + uint32_t hash; + int error; + + if (cnp->cn_namelen == 2 && + cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.') { + counter_u64_add(dotdothits, 1); + dvlp = VP2VNODELOCK(dvp); + dvlp2 = NULL; + mtx_lock(dvlp); +retry_dotdot: + ncp = dvp->v_cache_dd; + if (ncp == NULL) { + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, + "..", NULL); + mtx_unlock(dvlp); + return (0); + } + if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) { + if (ncp->nc_dvp != dvp) + panic("dvp %p v_cache_dd %p\n", dvp, ncp); + if (!cache_zap_locked_vnode_kl2(ncp, + dvp, &dvlp2)) + goto retry_dotdot; + MPASS(dvp->v_cache_dd == NULL); + mtx_unlock(dvlp); + if (dvlp2 != NULL) + mtx_unlock(dvlp2); + cache_free(ncp); + } else { + dvp->v_cache_dd = NULL; + mtx_unlock(dvlp); + if (dvlp2 != NULL) + mtx_unlock(dvlp2); + } + return (0); + } + + hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp); + blp = HASH2BUCKETLOCK(hash); +retry: + if (LIST_EMPTY(NCHHASH(hash))) + goto out_no_entry; + + rw_wlock(blp); + + LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { + counter_u64_add(numchecks, 1); + if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && + !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen)) + break; + } + + /* We failed to find an entry */ + if (ncp == NULL) { + rw_wunlock(blp); + goto out_no_entry; + } + + counter_u64_add(numposzaps, 1); + + error = cache_zap_wlocked_bucket(ncp, blp); + if (error != 0) { + zap_and_exit_bucket_fail++; + cache_maybe_yield(); + goto retry; + } + cache_free(ncp); + return (0); +out_no_entry: + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, NULL); + counter_u64_add(nummisszap, 1); + return (0); +} + int cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct timespec *tsp, int *ticksp) @@ -1132,69 +1234,52 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, cnp->cn_flags &= ~MAKEENTRY; return (0); } -retry: - blp = NULL; - dvlp = VP2VNODELOCK(dvp); - error = 0; + counter_u64_add(numcalls, 1); - if (cnp->cn_nameptr[0] == '.') { - if (cnp->cn_namelen == 1) - return (cache_lookup_dot(dvp, vpp, cnp, tsp, ticksp)); - if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { - counter_u64_add(dotdothits, 1); - dvlp2 = NULL; - mtx_lock(dvlp); -retry_dotdot: - ncp = dvp->v_cache_dd; - if (ncp == NULL) { - SDT_PROBE3(vfs, namecache, lookup, miss, dvp, - "..", NULL); - mtx_unlock(dvlp); - return (0); - } - if ((cnp->cn_flags & MAKEENTRY) == 0) { - if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) { - if (ncp->nc_dvp != dvp) - panic("dvp %p v_cache_dd %p\n", dvp, ncp); - if (!cache_zap_locked_vnode_kl2(ncp, - dvp, &dvlp2)) - goto retry_dotdot; - MPASS(dvp->v_cache_dd == NULL); - mtx_unlock(dvlp); - if (dvlp2 != NULL) - mtx_unlock(dvlp2); - cache_free(ncp); - } else { - dvp->v_cache_dd = NULL; - mtx_unlock(dvlp); - if (dvlp2 != NULL) - mtx_unlock(dvlp2); - } - return (0); - } - if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) { - if (ncp->nc_flag & NCF_NEGATIVE) - *vpp = NULL; - else - *vpp = ncp->nc_vp; - } else - *vpp = ncp->nc_dvp; - /* Return failure if negative entry was found. */ - if (*vpp == NULL) - goto negative_success; - CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", - dvp, cnp->cn_nameptr, *vpp); - SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..", - *vpp); - cache_out_ts(ncp, tsp, ticksp); - if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) == - NCF_DTS && tsp != NULL) { - ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc); - *tsp = ncp_ts->nc_dotdottime; - } - goto success; + if (__predict_false(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')) + return (cache_lookup_dot(dvp, vpp, cnp, tsp, ticksp)); + + if ((cnp->cn_flags & MAKEENTRY) == 0) + return (cache_lookup_nomakeentry(dvp, vpp, cnp, tsp, ticksp)); + +retry: + blp = NULL; + error = 0; + if (cnp->cn_namelen == 2 && + cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.') { + counter_u64_add(dotdothits, 1); + dvlp = VP2VNODELOCK(dvp); + dvlp2 = NULL; + mtx_lock(dvlp); + ncp = dvp->v_cache_dd; + if (ncp == NULL) { + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, + "..", NULL); + mtx_unlock(dvlp); + return (0); } + if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) { + if (ncp->nc_flag & NCF_NEGATIVE) + *vpp = NULL; + else + *vpp = ncp->nc_vp; + } else + *vpp = ncp->nc_dvp; + /* Return failure if negative entry was found. */ + if (*vpp == NULL) + goto negative_success; + CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", + dvp, cnp->cn_nameptr, *vpp); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..", + *vpp); + cache_out_ts(ncp, tsp, ticksp); + if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) == + NCF_DTS && tsp != NULL) { + ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc); + *tsp = ncp_ts->nc_dotdottime; + } + goto success; } hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp); @@ -1210,23 +1295,13 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, /* We failed to find an entry */ if (ncp == NULL) { + rw_runlock(blp); SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, NULL); - if ((cnp->cn_flags & MAKEENTRY) == 0) { - counter_u64_add(nummisszap, 1); - } else { - counter_u64_add(nummiss, 1); - } - cache_lookup_unlock(blp, dvlp); + counter_u64_add(nummiss, 1); return (0); } - /* We don't want to have an entry, so dump it */ - if ((cnp->cn_flags & MAKEENTRY) == 0) { - counter_u64_add(numposzaps, 1); - goto zap_and_exit; - } - /* We found a "positive" match, return the vnode */ if (!(ncp->nc_flag & NCF_NEGATIVE)) { counter_u64_add(numposhits, 1); @@ -1531,6 +1606,7 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp, int flag; int len; bool neg_locked; + int lnumcache; CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp, @@ -1670,7 +1746,6 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp, dvp->v_cache_dd = ncp; } - atomic_add_rel_long(&numcache, 1); if (vp != NULL) { if (vp->v_type == VDIR) { if (flag != NCF_ISDOTDOT) { @@ -1723,7 +1798,8 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp, ncp->nc_name); } cache_enter_unlock(&cel); - if (numneg * ncnegfactor > numcache) + lnumcache = atomic_fetchadd_long(&numcache, 1) + 1; + if (numneg * ncnegfactor > lnumcache) cache_negative_zap_one(); cache_free(ndd); return; @@ -1754,16 +1830,20 @@ nchinit(void *dummy __unused) cache_zone_small = uma_zcreate("S VFS Cache", sizeof(struct namecache) + CACHE_PATH_CUTOFF + 1, - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); + NULL, NULL, NULL, NULL, UMA_ALIGNOF(struct namecache), + UMA_ZONE_ZINIT); cache_zone_small_ts = uma_zcreate("STS VFS Cache", sizeof(struct namecache_ts) + CACHE_PATH_CUTOFF + 1, - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); + NULL, NULL, NULL, NULL, UMA_ALIGNOF(struct namecache_ts), + UMA_ZONE_ZINIT); cache_zone_large = uma_zcreate("L VFS Cache", sizeof(struct namecache) + NAME_MAX + 1, - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); + NULL, NULL, NULL, NULL, UMA_ALIGNOF(struct namecache), + UMA_ZONE_ZINIT); cache_zone_large_ts = uma_zcreate("LTS VFS Cache", sizeof(struct namecache_ts) + NAME_MAX + 1, - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); + NULL, NULL, NULL, NULL, UMA_ALIGNOF(struct namecache_ts), + UMA_ZONE_ZINIT); nchashtbl = hashinit(desiredvnodes * 2, M_VFSCACHE, &nchash); ncbuckethash = cache_roundup_2(mp_ncpus * 64) - 1; @@ -1914,6 +1994,8 @@ cache_purge_negative(struct vnode *vp) CTR1(KTR_VFS, "cache_purge_negative(%p)", vp); SDT_PROBE1(vfs, namecache, purge_negative, done, vp); + if (LIST_EMPTY(&vp->v_cache_src)) + return; TAILQ_INIT(&ncps); vlp = VP2VNODELOCK(vp); mtx_lock(vlp); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 5c343e7f3ffc..608cbad1ffc8 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -486,21 +486,12 @@ vop_stdpathconf(ap) case _PC_LINK_MAX: *ap->a_retval = LINK_MAX; return (0); - case _PC_MAX_CANON: - *ap->a_retval = MAX_CANON; - return (0); - case _PC_MAX_INPUT: - *ap->a_retval = MAX_INPUT; - return (0); case _PC_PIPE_BUF: *ap->a_retval = PIPE_BUF; return (0); case _PC_CHOWN_RESTRICTED: *ap->a_retval = 1; return (0); - case _PC_VDISABLE: - *ap->a_retval = _POSIX_VDISABLE; - return (0); default: return (EINVAL); } diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 03fa23e85e78..5fce9ed4b28d 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -448,44 +448,45 @@ static struct netcred * vfs_export_lookup(struct mount *mp, struct sockaddr *nam) { struct netexport *nep; - struct netcred *np; + struct netcred *np = NULL; struct radix_node_head *rnh; struct sockaddr *saddr; nep = mp->mnt_export; if (nep == NULL) return (NULL); - np = NULL; - if (mp->mnt_flag & MNT_EXPORTED) { - /* - * Lookup in the export list first. - */ - if (nam != NULL) { - saddr = nam; - rnh = NULL; - switch (saddr->sa_family) { - case AF_INET: - rnh = nep->ne4; - break; - case AF_INET6: - rnh = nep->ne6; - break; - } - if (rnh != NULL) { - RADIX_NODE_HEAD_RLOCK(rnh); - np = (struct netcred *) - (*rnh->rnh_matchaddr)(saddr, &rnh->rh); - RADIX_NODE_HEAD_RUNLOCK(rnh); - if (np && np->netc_rnodes->rn_flags & RNF_ROOT) - np = NULL; - } + if ((mp->mnt_flag & MNT_EXPORTED) == 0) + return (NULL); + + /* + * Lookup in the export list + */ + if (nam != NULL) { + saddr = nam; + rnh = NULL; + switch (saddr->sa_family) { + case AF_INET: + rnh = nep->ne4; + break; + case AF_INET6: + rnh = nep->ne6; + break; + } + if (rnh != NULL) { + RADIX_NODE_HEAD_RLOCK(rnh); + np = (struct netcred *) (*rnh->rnh_matchaddr)(saddr, &rnh->rh); + RADIX_NODE_HEAD_RUNLOCK(rnh); + if (np != NULL && (np->netc_rnodes->rn_flags & RNF_ROOT) != 0) + return (NULL); } - /* - * If no address match, use the default if it exists. - */ - if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED) - np = &nep->ne_defexported; } + + /* + * If no address match, use the default if it exists. + */ + if (np == NULL && (mp->mnt_flag & MNT_DEFEXPORTED) != 0) + return (&nep->ne_defexported); + return (np); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 4ee90e40d1c8..09503e4ca477 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1390,13 +1390,13 @@ kern_alternate_path(struct thread *td, const char *prefix, const char *path, for (cp = &ptr[len] - 1; *cp != '/'; cp--); *cp = '\0'; - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf, td); error = namei(&nd); *cp = '/'; if (error != 0) goto keeporig; } else { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf, td); error = namei(&nd); if (error != 0) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 117ad95438d2..5141de78c605 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -529,6 +529,8 @@ vfs_mount_destroy(struct mount *mp) if (mp->mnt_lockref != 0) panic("vfs_mount_destroy: nonzero lock refcount"); MNT_IUNLOCK(mp); + if (mp->mnt_vnodecovered != NULL) + vrele(mp->mnt_vnodecovered); #ifdef MAC mac_mount_destroy(mp); #endif @@ -819,6 +821,7 @@ vfs_domount_first( error = VFS_MOUNT(mp); if (error != 0) { vfs_unbusy(mp); + mp->mnt_vnodecovered = NULL; vfs_mount_destroy(mp); VI_LOCK(vp); vp->v_iflag &= ~VI_MOUNT; @@ -1259,7 +1262,7 @@ dounmount_cleanup(struct mount *mp, struct vnode *coveredvp, int mntkflags) int dounmount(struct mount *mp, int flags, struct thread *td) { - struct vnode *coveredvp, *fsrootvp; + struct vnode *coveredvp; int error; uint64_t async_flag; int mnt_gen_r; @@ -1361,22 +1364,6 @@ dounmount(struct mount *mp, int flags, struct thread *td) MNT_IUNLOCK(mp); cache_purgevfs(mp, false); /* remove cache entries for this file sys */ vfs_deallocate_syncvnode(mp); - /* - * For forced unmounts, move process cdir/rdir refs on the fs root - * vnode to the covered vnode. For non-forced unmounts we want - * such references to cause an EBUSY error. - */ - if ((flags & MNT_FORCE) && - VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { - if (mp->mnt_vnodecovered != NULL && - (mp->mnt_flag & MNT_IGNORE) == 0) - mountcheckdirs(fsrootvp, mp->mnt_vnodecovered); - if (fsrootvp == rootvnode) { - vrele(rootvnode); - rootvnode = NULL; - } - vput(fsrootvp); - } if ((mp->mnt_flag & MNT_RDONLY) != 0 || (flags & MNT_FORCE) != 0 || (error = VFS_SYNC(mp, MNT_WAIT)) == 0) error = VFS_UNMOUNT(mp, flags); @@ -1388,17 +1375,6 @@ dounmount(struct mount *mp, int flags, struct thread *td) * it doesn't exist anymore. */ if (error && error != ENXIO) { - if ((flags & MNT_FORCE) && - VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { - if (mp->mnt_vnodecovered != NULL && - (mp->mnt_flag & MNT_IGNORE) == 0) - mountcheckdirs(mp->mnt_vnodecovered, fsrootvp); - if (rootvnode == NULL) { - rootvnode = fsrootvp; - vref(rootvnode); - } - vput(fsrootvp); - } MNT_ILOCK(mp); mp->mnt_kern_flag &= ~MNTK_NOINSMNTQ; if ((mp->mnt_flag & MNT_RDONLY) == 0) { @@ -1426,9 +1402,13 @@ dounmount(struct mount *mp, int flags, struct thread *td) EVENTHANDLER_INVOKE(vfs_unmounted, mp, td); if (coveredvp != NULL) { coveredvp->v_mountedhere = NULL; - vput(coveredvp); + VOP_UNLOCK(coveredvp, 0); } vfs_event_signal(NULL, VQ_UNMOUNT, 0); + if (rootvnode != NULL && mp == rootvnode->v_mount) { + vrele(rootvnode); + rootvnode = NULL; + } if (mp == rootdevmp) rootdevmp = NULL; vfs_mount_destroy(mp); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 2c144ab17c2f..53ec47b525e9 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1746,8 +1746,6 @@ flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag, ((flags & V_ALT) && (bp->b_xflags & BX_ALTDATA) == 0)) { continue; } - lblkno = 0; - xflags = 0; if (nbp != NULL) { lblkno = nbp->b_lblkno; xflags = nbp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN); @@ -1782,6 +1780,8 @@ flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag, bp->b_flags &= ~B_ASYNC; brelse(bp); BO_LOCK(bo); + if (nbp == NULL) + break; nbp = gbincore(bo, lblkno); if (nbp == NULL || (nbp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN)) != xflags) @@ -3054,8 +3054,8 @@ vinactive(struct vnode *vp, struct thread *td) * point that VOP_INACTIVE() is called, there could still be * pending I/O and dirty pages in the object. */ - obj = vp->v_object; - if (obj != NULL && (obj->flags & OBJ_MIGHTBEDIRTY) != 0) { + if ((obj = vp->v_object) != NULL && (vp->v_vflag & VV_NOSYNC) == 0 && + (obj->flags & OBJ_MIGHTBEDIRTY) != 0) { VM_OBJECT_WLOCK(obj); vm_object_page_clean(obj, 0, 0, 0); VM_OBJECT_WUNLOCK(obj); @@ -5299,12 +5299,18 @@ __mnt_vnode_next_all(struct vnode **mvp, struct mount *mp) kern_yield(PRI_USER); MNT_ILOCK(mp); KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); - vp = TAILQ_NEXT(*mvp, v_nmntvnodes); - while (vp != NULL && (vp->v_type == VMARKER || - (vp->v_iflag & VI_DOOMED) != 0)) - vp = TAILQ_NEXT(vp, v_nmntvnodes); - - /* Check if we are done */ + for (vp = TAILQ_NEXT(*mvp, v_nmntvnodes); vp != NULL; + vp = TAILQ_NEXT(vp, v_nmntvnodes)) { + /* Allow a racy peek at VI_DOOMED to save a lock acquisition. */ + if (vp->v_type == VMARKER || (vp->v_iflag & VI_DOOMED) != 0) + continue; + VI_LOCK(vp); + if ((vp->v_iflag & VI_DOOMED) != 0) { + VI_UNLOCK(vp); + continue; + } + break; + } if (vp == NULL) { __mnt_vnode_markerfree_all(mvp, mp); /* MNT_IUNLOCK(mp); -- done in above function */ @@ -5313,7 +5319,6 @@ __mnt_vnode_next_all(struct vnode **mvp, struct mount *mp) } TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes); TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); - VI_LOCK(vp); MNT_IUNLOCK(mp); return (vp); } @@ -5326,14 +5331,20 @@ __mnt_vnode_first_all(struct vnode **mvp, struct mount *mp) *mvp = malloc(sizeof(struct vnode), M_VNODE_MARKER, M_WAITOK | M_ZERO); MNT_ILOCK(mp); MNT_REF(mp); + (*mvp)->v_mount = mp; (*mvp)->v_type = VMARKER; - vp = TAILQ_FIRST(&mp->mnt_nvnodelist); - while (vp != NULL && (vp->v_type == VMARKER || - (vp->v_iflag & VI_DOOMED) != 0)) - vp = TAILQ_NEXT(vp, v_nmntvnodes); - - /* Check if we are done */ + TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) { + /* Allow a racy peek at VI_DOOMED to save a lock acquisition. */ + if (vp->v_type == VMARKER || (vp->v_iflag & VI_DOOMED) != 0) + continue; + VI_LOCK(vp); + if ((vp->v_iflag & VI_DOOMED) != 0) { + VI_UNLOCK(vp); + continue; + } + break; + } if (vp == NULL) { MNT_REL(mp); MNT_IUNLOCK(mp); @@ -5341,14 +5352,11 @@ __mnt_vnode_first_all(struct vnode **mvp, struct mount *mp) *mvp = NULL; return (NULL); } - (*mvp)->v_mount = mp; TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes); - VI_LOCK(vp); MNT_IUNLOCK(mp); return (vp); } - void __mnt_vnode_markerfree_all(struct vnode **mvp, struct mount *mp) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index b4408e3ac919..be8a9f512ed1 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1248,9 +1248,6 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, if (error == 0 && dev == VNOVAL) error = EINVAL; break; - case S_IFMT: - error = priv_check(td, PRIV_VFS_MKNOD_BAD); - break; case S_IFWHT: error = priv_check(td, PRIV_VFS_MKNOD_WHT); break; @@ -1288,9 +1285,6 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, whiteout = 0; switch (mode & S_IFMT) { - case S_IFMT: /* used by badsect to flag bad sectors */ - vattr.va_type = VBAD; - break; case S_IFCHR: vattr.va_type = VCHR; break; @@ -4400,7 +4394,7 @@ kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) if (offset > OFF_MAX - len) return (EFBIG); AUDIT_ARG_FD(fd); - error = fget(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_PWRITE), &fp); if (error != 0) return (error); AUDIT_ARG_FILE(td->td_proc, fp); diff --git a/sys/libkern/crc32.c b/sys/libkern/crc32.c index 7eaacd454661..149de3de6dee 100644 --- a/sys/libkern/crc32.c +++ b/sys/libkern/crc32.c @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #include + +#ifdef _KERNEL #include #include @@ -57,6 +59,7 @@ __FBSDID("$FreeBSD$"); #if defined(__aarch64__) #include #endif +#endif /* _KERNEL */ const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, @@ -759,6 +762,7 @@ calculate_crc32c(uint32_t crc32c, const unsigned char *buffer, unsigned int length) { +#ifdef _KERNEL #if defined(__amd64__) || defined(__i386__) if ((cpu_feature2 & CPUID2_SSE42) != 0) { return (sse42_crc32c(crc32c, buffer, length)); @@ -776,6 +780,7 @@ calculate_crc32c(uint32_t crc32c, return (armv8_crc32c(crc32c, buffer, length)); } else #endif +#endif /* _KERNEL */ if (length < 4) { return (singletable_crc32c(crc32c, buffer, length)); } else { diff --git a/sys/mips/broadcom/bcm_machdep.c b/sys/mips/broadcom/bcm_machdep.c index eef277c07bfd..b61cca31a148 100644 --- a/sys/mips/broadcom/bcm_machdep.c +++ b/sys/mips/broadcom/bcm_machdep.c @@ -2,9 +2,12 @@ * Copyright (c) 2007 Bruce M. Simpson. * Copyright (c) 2016 Michael Zhilin * Copyright (c) 2016 Landon Fuller - * + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -74,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include @@ -105,7 +109,7 @@ static int bcm_find_core(struct bcm_platform *bp, static int bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, bhnd_erom_t *erom, size_t esize, - struct bhnd_chipid *cid); + struct bhnd_erom_io *eio, struct bhnd_chipid *cid); extern int *edata; extern int *end; @@ -146,6 +150,17 @@ bcm_get_bus_addr(void) return (BHND_DEFAULT_CHIPC_ADDR); } +static bus_size_t +bcm_get_bus_size(void) +{ + long msize; + + if (resource_long_value("bhnd", 0, "msize", &msize) == 0) + return ((u_long)msize); + + return (BHND_DEFAULT_ENUM_SIZE); +} + /** * Search the device enumeration table for a core matching @p descs, * @@ -239,24 +254,30 @@ bcm_get_nvram(struct bcm_platform *bp, const char *name, void *buf, size_t *len, * @param esize The total available number of bytes allocated * for @p erom. If this is less than is required * by @p erom_cls ENOMEM will be returned. + * @param eio EROM I/O callbacks to be used. * @param[out] cid On success, the probed chip identification. */ static int bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, - bhnd_erom_t *erom, size_t esize, struct bhnd_chipid *cid) + bhnd_erom_t *erom, size_t esize, struct bhnd_erom_io *eio, + struct bhnd_chipid *cid) { bhnd_erom_class_t **clsp; - bus_space_tag_t bst; - bus_space_handle_t bsh; bus_addr_t bus_addr; int error, prio, result; - bus_addr = bcm_get_bus_addr(); *erom_cls = NULL; prio = 0; - bst = mips_bus_space_generic; - bsh = BCM_SOC_BSH(bus_addr, 0); + /* Map our first bus core for the erom probe */ + bus_addr = bcm_get_bus_addr(); + if ((error = bhnd_erom_io_map(eio, bus_addr, BHND_DEFAULT_CORE_SIZE))) { + BCM_ERR("failed to map first core at %#jx+%#jx: %d\n", + (uintmax_t)bus_addr, (uintmax_t)BHND_DEFAULT_CORE_SIZE, + error); + + return (error); + } SET_FOREACH(clsp, bhnd_erom_class_set) { struct bhnd_chipid pcid; @@ -269,8 +290,7 @@ bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, kobj_class_compile_static(cls, &kops); /* Probe the bus address */ - result = bhnd_erom_probe_static(cls, bst, bsh, bus_addr, NULL, - &pcid); + result = bhnd_erom_probe(cls, eio, NULL, &pcid); /* Drop pointer to stack allocated ops table */ cls->ops = NULL; @@ -296,6 +316,7 @@ bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, if (*erom_cls == NULL) { BCM_ERR("no erom parser found for root bus at %#jx\n", (uintmax_t)bus_addr); + return (ENOENT); } @@ -303,9 +324,7 @@ bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, kobj_class_compile_static(*erom_cls, erom_ops); /* ... and initialize the erom parser instance */ - bsh = BCM_SOC_BSH(cid->enum_addr, 0); - error = bhnd_erom_init_static(*erom_cls, erom, esize, cid, - mips_bus_space_generic, bsh); + error = bhnd_erom_init_static(*erom_cls, erom, esize, cid, eio); return (error); } @@ -316,8 +335,14 @@ bcm_erom_probe_and_attach(bhnd_erom_class_t **erom_cls, kobj_ops_t erom_ops, static int bcm_init_platform_data(struct bcm_platform *bp) { - bool aob, pmu; - int error; + bus_addr_t bus_addr, bus_size; + bus_space_tag_t erom_bst; + bus_space_handle_t erom_bsh; + bool aob, pmu; + int error; + + bus_addr = bcm_get_bus_addr(); + bus_size = bcm_get_bus_size(); #ifdef CFE /* Fetch CFE console handle (if any). Must be initialized before @@ -336,10 +361,21 @@ bcm_init_platform_data(struct bcm_platform *bp) /* Probe and attach device table provider, populating our * chip identification */ + erom_bst = mips_bus_space_generic; + erom_bsh = BCM_SOC_BSH(bus_addr, 0); + + error = bhnd_erom_iobus_init(&bp->erom_io, bus_addr, bus_size, erom_bst, + erom_bsh); + if (error) { + BCM_ERR("failed to initialize erom I/O callbacks: %d\n", error); + return (error); + } + error = bcm_erom_probe_and_attach(&bp->erom_impl, &bp->erom_ops, - &bp->erom.obj, sizeof(bp->erom), &bp->cid); + &bp->erom.obj, sizeof(bp->erom), &bp->erom_io.eio, &bp->cid); if (error) { BCM_ERR("error attaching erom parser: %d\n", error); + bhnd_erom_io_fini(&bp->erom_io.eio); return (error); } @@ -393,6 +429,12 @@ bcm_init_platform_data(struct bcm_platform *bp) } } + /* Initialize our platform service registry */ + if ((error = bhnd_service_registry_init(&bp->services))) { + BCM_ERR("error initializing service registry: %d\n", error); + return (error); + } + bcm_platform_data_avail = true; return (0); } diff --git a/sys/mips/broadcom/bcm_machdep.h b/sys/mips/broadcom/bcm_machdep.h index a20f40754c69..7d85338f906c 100644 --- a/sys/mips/broadcom/bcm_machdep.h +++ b/sys/mips/broadcom/bcm_machdep.h @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -36,7 +40,7 @@ #include #include -#include +#include #include @@ -45,33 +49,36 @@ extern const struct bhnd_pmu_io bcm_pmu_soc_io; struct bcm_platform { - struct bhnd_chipid cid; /**< chip id */ - struct bhnd_core_info cc_id; /**< chipc core info */ - uintptr_t cc_addr; /**< chipc core phys address */ - uint32_t cc_caps; /**< chipc capabilities */ - uint32_t cc_caps_ext; /**< chipc extended capabilies */ + struct bhnd_chipid cid; /**< chip id */ + struct bhnd_core_info cc_id; /**< chipc core info */ + uintptr_t cc_addr; /**< chipc core phys address */ + uint32_t cc_caps; /**< chipc capabilities */ + uint32_t cc_caps_ext; /**< chipc extended capabilies */ /* On non-AOB devices, the PMU register block is mapped to chipc; * the pmu_id and pmu_addr values will be copied from cc_id * and cc_addr. */ - struct bhnd_core_info pmu_id; /**< PMU core info */ - uintptr_t pmu_addr; /**< PMU core phys address, or + struct bhnd_core_info pmu_id; /**< PMU core info */ + uintptr_t pmu_addr; /**< PMU core phys address, or 0x0 if no PMU */ - struct bhnd_pmu_query pmu; /**< PMU query instance */ + struct bhnd_pmu_query pmu; /**< PMU query instance */ - bhnd_erom_class_t *erom_impl; /**< erom parser class */ - struct kobj_ops erom_ops; /**< compiled kobj opcache */ + bhnd_erom_class_t *erom_impl; /**< erom parser class */ + struct kobj_ops erom_ops; /**< compiled kobj opcache */ + struct bhnd_erom_iobus erom_io; /**< erom I/O callbacks */ union { bhnd_erom_static_t data; bhnd_erom_t obj; } erom; - struct bhnd_nvram_io *nvram_io; /**< NVRAM I/O context, or NULL if unavailable */ - bhnd_nvram_data_class *nvram_cls; /**< NVRAM data class, or NULL if unavailable */ + struct bhnd_nvram_io *nvram_io; /**< NVRAM I/O context, or NULL if unavailable */ + bhnd_nvram_data_class *nvram_cls; /**< NVRAM data class, or NULL if unavailable */ + + struct bhnd_service_registry services; /**< platform service providers */ #ifdef CFE - int cfe_console; /**< Console handle, or -1 */ + int cfe_console; /**< Console handle, or -1 */ #endif }; diff --git a/sys/mips/broadcom/bcm_nvram_cfe.c b/sys/mips/broadcom/bcm_nvram_cfe.c index 7132a45ae38c..a237e9832534 100644 --- a/sys/mips/broadcom/bcm_nvram_cfe.c +++ b/sys/mips/broadcom/bcm_nvram_cfe.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -120,6 +124,13 @@ bhnd_nvram_cfe_attach(device_t dev) if (error) return (error); + error = bhnd_service_registry_add(&bp->services, dev, + BHND_SERVICE_NVRAM, 0); + if (error) { + bhnd_nvram_store_free(sc->store); + return (error); + } + return (error); } @@ -138,10 +149,18 @@ bhnd_nvram_cfe_suspend(device_t dev) static int bhnd_nvram_cfe_detach(device_t dev) { - struct bhnd_nvram_cfe_softc *sc; + struct bcm_platform *bp; + struct bhnd_nvram_cfe_softc *sc; + int error; + bp = bcm_get_platform(); sc = device_get_softc(dev); + error = bhnd_service_registry_remove(&bp->services, dev, + BHND_SERVICE_ANY); + if (error) + return (error); + bhnd_nvram_store_free(sc->store); return (0); diff --git a/sys/mips/broadcom/bhnd_nexus.c b/sys/mips/broadcom/bhnd_nexus.c index f2a4d117b62e..72996f9ee010 100644 --- a/sys/mips/broadcom/bhnd_nexus.c +++ b/sys/mips/broadcom/bhnd_nexus.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2015-2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -54,6 +58,17 @@ __FBSDID("$FreeBSD$"); #include "bhnd_nexusvar.h" + +/** + * Default bhnd_nexus implementation of BHND_BUS_GET_SERVICE_REGISTRY(). + */ +static struct bhnd_service_registry * +bhnd_nexus_get_service_registry(device_t dev, device_t child) +{ + struct bcm_platform *bp = bcm_get_platform(); + return (&bp->services); +} + /** * Default bhnd_nexus implementation of BHND_BUS_ACTIVATE_RESOURCE(). */ @@ -160,6 +175,11 @@ bhnd_nexus_assign_intr(device_t dev, device_t child, int rid) static device_method_t bhnd_nexus_methods[] = { /* bhnd interface */ + DEVMETHOD(bhnd_bus_get_service_registry,bhnd_nexus_get_service_registry), + DEVMETHOD(bhnd_bus_register_provider, bhnd_bus_generic_sr_register_provider), + DEVMETHOD(bhnd_bus_deregister_provider, bhnd_bus_generic_sr_deregister_provider), + DEVMETHOD(bhnd_bus_retain_provider, bhnd_bus_generic_sr_retain_provider), + DEVMETHOD(bhnd_bus_release_provider, bhnd_bus_generic_sr_release_provider), DEVMETHOD(bhnd_bus_activate_resource, bhnd_nexus_activate_resource), DEVMETHOD(bhnd_bus_deactivate_resource, bhnd_nexus_deactivate_resource), DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_nexus_is_hw_disabled), diff --git a/sys/mips/conf/ADM5120 b/sys/mips/conf/ADM5120 index a32adf69e8fb..7990e56f8cc2 100644 --- a/sys/mips/conf/ADM5120 +++ b/sys/mips/conf/ADM5120 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/ALCHEMY b/sys/mips/conf/ALCHEMY index 2d1acd901160..6bfe23865b87 100644 --- a/sys/mips/conf/ALCHEMY +++ b/sys/mips/conf/ALCHEMY @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/ERL b/sys/mips/conf/ERL index 6363a6c5deda..58552101db73 100644 --- a/sys/mips/conf/ERL +++ b/sys/mips/conf/ERL @@ -5,11 +5,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/GXEMUL b/sys/mips/conf/GXEMUL index dcfa3d3af276..4ad01b96ad7f 100644 --- a/sys/mips/conf/GXEMUL +++ b/sys/mips/conf/GXEMUL @@ -30,6 +30,7 @@ options KDB options SMP # Symmetric MultiProcessor Kernel options SCHED_ULE +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP diff --git a/sys/mips/conf/GXEMUL32 b/sys/mips/conf/GXEMUL32 index da3e71a67eed..c6c3f25a6a97 100644 --- a/sys/mips/conf/GXEMUL32 +++ b/sys/mips/conf/GXEMUL32 @@ -28,6 +28,7 @@ options KDB options SMP # Symmetric MultiProcessor Kernel options SCHED_ULE +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP diff --git a/sys/mips/conf/MT7620 b/sys/mips/conf/MT7620 index ea61949a0c92..6d34a55d55dc 100644 --- a/sys/mips/conf/MT7620 +++ b/sys/mips/conf/MT7620 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 34f8ef1d6408..42f36772adc1 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/QEMU b/sys/mips/conf/QEMU index b8f33fe92f42..ca46c22641b8 100644 --- a/sys/mips/conf/QEMU +++ b/sys/mips/conf/QEMU @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -31,6 +31,7 @@ options DDB options KDB options SCHED_4BSD #4BSD scheduler +options VIMAGE # Subsystem virtualization, e.g. VNET options INET #InterNETworking options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client @@ -45,6 +46,11 @@ options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + device loop device ether device md diff --git a/sys/mips/conf/RT305X b/sys/mips/conf/RT305X index fc629b62e9d1..b49857cc8ea5 100644 --- a/sys/mips/conf/RT305X +++ b/sys/mips/conf/RT305X @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/RT5350 b/sys/mips/conf/RT5350 index b2f02c6170b1..0775f6e0435e 100644 --- a/sys/mips/conf/RT5350 +++ b/sys/mips/conf/RT5350 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLP b/sys/mips/conf/XLP index 6105fa0ce64d..20fcb115cf9a 100644 --- a/sys/mips/conf/XLP +++ b/sys/mips/conf/XLP @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLP64 b/sys/mips/conf/XLP64 index adefda5d5f4f..1e44c1212ef4 100644 --- a/sys/mips/conf/XLP64 +++ b/sys/mips/conf/XLP64 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLPN32 b/sys/mips/conf/XLPN32 index 2b345f8e8bc2..e8d21dfd21bc 100644 --- a/sys/mips/conf/XLPN32 +++ b/sys/mips/conf/XLPN32 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index f61fb743c4ca..0c2cd72053a0 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -31,11 +31,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLR64 b/sys/mips/conf/XLR64 index ab7d5aea38da..7a0daab7354d 100644 --- a/sys/mips/conf/XLR64 +++ b/sys/mips/conf/XLR64 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/conf/XLRN32 b/sys/mips/conf/XLRN32 index 3640e75ffcc6..ff671948996e 100644 --- a/sys/mips/conf/XLRN32 +++ b/sys/mips/conf/XLRN32 @@ -3,11 +3,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index 5ebaf4cc1720..d4150edd7822 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -279,6 +279,15 @@ MIPS_RW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); MIPS_RW32_COP0(prid, MIPS_COP_0_PRID); /* XXX 64-bit? */ MIPS_RW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1); + +#if defined(CPU_MIPS24K) || defined(CPU_MIPS34K) || \ + defined(CPU_MIPS74K) || defined(CPU_MIPS1004K) || \ + defined(CPU_MIPS1074K) || defined(CPU_INTERAPTIV) || \ + defined(CPU_PROAPTIV) +/* MIPS32/64 r2 intctl */ +MIPS_RW32_COP0_SEL(intctl, MIPS_COP_0_INTCTL, 1); +#endif + #ifdef CPU_XBURST MIPS_RW32_COP0_SEL(xburst_mbox0, MIPS_COP_0_XBURST_MBOX, 0); MIPS_RW32_COP0_SEL(xburst_mbox1, MIPS_COP_0_XBURST_MBOX, 1); diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index b6f2433e1509..ca86a1c5c6ac 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -468,6 +468,7 @@ * 10 MIPS_COP_0_TLB_HI 3636 TLB entry high. * 11 MIPS_COP_0_COMPARE .333 Compare (against Count). * 12 MIPS_COP_0_STATUS 3333 Status register. + * 12/1 MIPS_COP_0_INTCTL ..33 Interrupt setup (MIPS32/64 r2). * 13 MIPS_COP_0_CAUSE 3333 Exception cause register. * 14 MIPS_COP_0_EXC_PC 3636 Exception PC. * 15 MIPS_COP_0_PRID 3333 Processor revision identifier. @@ -548,6 +549,7 @@ /* MIPS32/64 */ #define MIPS_COP_0_USERLOCAL _(4) /* sel 2 is userlevel register */ #define MIPS_COP_0_HWRENA _(7) +#define MIPS_COP_0_INTCTL _(12) #define MIPS_COP_0_DEBUG _(23) #define MIPS_COP_0_DEPC _(24) #define MIPS_COP_0_PERFCNT _(25) @@ -561,6 +563,16 @@ #define MIPS_MMU_BAT 0x02 /* Standard BAT */ #define MIPS_MMU_FIXED 0x03 /* Standard fixed mapping */ +/* + * IntCtl Register Fields + */ +#define MIPS_INTCTL_IPTI_MASK 0xE0000000 /* bits 31..29 timer intr # */ +#define MIPS_INTCTL_IPTI_SHIFT 29 +#define MIPS_INTCTL_IPPCI_MASK 0x1C000000 /* bits 26..29 perf counter intr # */ +#define MIPS_INTCTL_IPPCI_SHIFT 26 +#define MIPS_INTCTL_VS_MASK 0x000001F0 /* bits 5..9 vector spacing */ +#define MIPS_INTCTL_VS_SHIFT 4 + /* * Config Register Fields * (See "MIPS Architecture for Programmers Volume III", MD00091, Table 9.39) diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index a33c09027e78..26c4799cec5e 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -144,8 +144,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ #define ET_DYN_LOAD_ADDR 0x0120000 diff --git a/sys/mips/mediatek/mtk_pinctrl.c b/sys/mips/mediatek/mtk_pinctrl.c index ebe08081552c..8897e73cf6fc 100644 --- a/sys/mips/mediatek/mtk_pinctrl.c +++ b/sys/mips/mediatek/mtk_pinctrl.c @@ -169,6 +169,9 @@ mtk_pinctrl_configure(device_t dev, phandle_t cfgxref) socid = mtk_soc_get_socid(); switch (socid) { + case MTK_SOC_RT2880: + pintable = rt2880_pintable; + break; case MTK_SOC_RT3050: /* fallthrough */ case MTK_SOC_RT3052: case MTK_SOC_RT3350: diff --git a/sys/mips/mediatek/mtk_pinctrl.h b/sys/mips/mediatek/mtk_pinctrl.h index ea01c8212174..b5e3cfae28cd 100644 --- a/sys/mips/mediatek/mtk_pinctrl.h +++ b/sys/mips/mediatek/mtk_pinctrl.h @@ -118,6 +118,14 @@ DECL_FUNC(gex_func) = { FUNC("ge1", 0), FUNC("ge2", 0), FUNC("gpio", 1) }; +DECL_FUNC(rt2880_uartf_func) = { + FUNC("uartf", 0), FUNC("gpio", 1) +}; + +DECL_FUNC(rt2880_pci_func) = { + FUNC("pci", 0), FUNC("gpio", 1) +}; + DECL_FUNC(rt3883_pci_func) = { FUNC("pci-dev", 0), FUNC("pci-host2", 1), FUNC("pci-host1", 2), FUNC("pci-fnc", 3), FUNC("gpio", 7) @@ -298,6 +306,18 @@ DECL_TABLE(mt7620_pintable) = { GROUP_END }; +DECL_TABLE(rt2880_pintable) = { + GROUP("i2c", SYSCTL_GPIOMODE, 0, 1, i2c_func), + GROUP("uartf", SYSCTL_GPIOMODE, 1, 1, rt2880_uartf_func), + GROUP("spi", SYSCTL_GPIOMODE, 2, 1, spi_func), + GROUP("uartlite", SYSCTL_GPIOMODE, 3, 1, uartlite_func), + GROUP("jtag", SYSCTL_GPIOMODE, 4, 1, jtag_func), + GROUP("mdio", SYSCTL_GPIOMODE, 5, 1, mdio_func), + GROUP("sdram", SYSCTL_GPIOMODE, 6, 1, sdram_func), + GROUP("pci", SYSCTL_GPIOMODE, 7, 1, rt2880_pci_func), + GROUP_END +}; + DECL_TABLE(rt3050_pintable) = { GROUP("i2c", SYSCTL_GPIOMODE, 0, 1, i2c_func), GROUP("spi", SYSCTL_GPIOMODE, 1, 1, spi_func), diff --git a/sys/mips/mips/minidump_machdep.c b/sys/mips/mips/minidump_machdep.c index c38e60412a99..9b55ddbb3c5f 100644 --- a/sys/mips/mips/minidump_machdep.c +++ b/sys/mips/mips/minidump_machdep.c @@ -56,7 +56,6 @@ uint32_t *vm_page_dump; int vm_page_dump_size; static struct kerneldumpheader kdh; -static off_t dumplo; /* Handle chunked writes. */ static uint64_t counter, progress, dumpsize; @@ -166,10 +165,9 @@ write_buffer(struct dumperinfo *di, char *ptr, size_t sz) wdog_kern_pat(WD_LASTVAL); if (ptr) { - error = dump_write(di, ptr, 0, dumplo, len); + error = dump_append(di, ptr, 0, len); if (error) return (error); - dumplo += len; ptr += len; sz -= len; } else { @@ -267,7 +265,7 @@ minidumpsys(struct dumperinfo *di) printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20, ptoa((uintmax_t)physmem) / 1048576); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -335,7 +333,7 @@ minidumpsys(struct dumperinfo *di) } } - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 0f1508c7f2d3..016257be7c13 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -970,12 +971,13 @@ trap(struct trapframe *trapframe) case T_COP_UNUSABLE + T_USER: cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT; if (cop == 1) { -#if !defined(CPU_HAVEFPU) - /* FP (COP1) instruction */ - log_illegal_instruction("COP1_UNUSABLE", trapframe); - i = SIGILL; - break; -#else + /* FP (COP1) instruction */ + if (cpuinfo.fpu_id == 0) { + log_illegal_instruction("COP1_UNUSABLE", + trapframe); + i = SIGILL; + break; + } addr = trapframe->pc; MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame); PCPU_SET(fpcurthread, td); @@ -986,7 +988,6 @@ trap(struct trapframe *trapframe) #endif td->td_md.md_flags |= MDTD_FPUSED; goto out; -#endif } #ifdef CPU_CNMIPS else if (cop == 2) { diff --git a/sys/mips/rmi/rootfs_list.txt b/sys/mips/rmi/rootfs_list.txt index e68b2d865d75..abf81a7a60de 100644 --- a/sys/mips/rmi/rootfs_list.txt +++ b/sys/mips/rmi/rootfs_list.txt @@ -448,7 +448,6 @@ ./sbin ./sbin/adjkerntz ./sbin/atacontrol -./sbin/badsect ./sbin/bsdlabel ./sbin/camcontrol ./sbin/ccdconfig diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 3b607c7a647b..7d90d5ab444e 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -218,7 +218,6 @@ SUBDIR= \ lge \ libalias \ libiconv \ - libmbpool \ libmchain \ ${_linprocfs} \ ${_linsysfs} \ @@ -426,7 +425,7 @@ _autofs= autofs .endif .if ${MK_CDDL} != "no" || defined(ALL_MODULES) -.if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv6*} != "") && \ +.if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv[67]*} != "") && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_CPUARCH} != "sparc64" SUBDIR+= dtrace @@ -562,6 +561,7 @@ _cxgb= cxgb .if ${MACHINE_CPUARCH} == "aarch64" _armv8crypto= armv8crypto +_efirt= efirt _em= em .endif @@ -603,6 +603,9 @@ _ixv= ixv _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux +.if ${MK_SOURCELESS_UCODE} != "no" +_lio= lio +.endif _nctgpio= nctgpio _ndis= ndis _pccard= pccard @@ -711,9 +714,6 @@ _ixl= ixl _ixlv= ixlv _linux64= linux64 _linux_common= linux_common -.if ${MK_SOURCELESS_UCODE} != "no" -_lio= lio -.endif _ntb= ntb _pms= pms _qlxge= qlxge @@ -800,7 +800,7 @@ _em= em _epic= epic .endif -.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH} == "armv6" || \ +.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH:Marmv[67]*} != "" || \ ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif @@ -810,7 +810,7 @@ _cloudabi64= cloudabi64 .endif -.if ${MACHINE_ARCH} == "armv6" +.if ${MACHINE_ARCH:Marmv[67]*} != "" _ffec= ffec .endif diff --git a/sys/modules/aesni/Makefile b/sys/modules/aesni/Makefile index 82f6d1178ff8..56500faa8e4a 100644 --- a/sys/modules/aesni/Makefile +++ b/sys/modules/aesni/Makefile @@ -1,6 +1,7 @@ # $FreeBSD$ .PATH: ${SRCTOP}/sys/crypto/aesni +.PATH: ${SRCTOP}/contrib/llvm/tools/clang/lib/Headers KMOD= aesni SRCS= aesni.c @@ -8,6 +9,7 @@ SRCS+= aeskeys_${MACHINE_CPUARCH}.S SRCS+= device_if.h bus_if.h opt_bus.h cryptodev_if.h OBJS+= aesni_ghash.o aesni_wrap.o +OBJS+= intel_sha1.o intel_sha256.o # Remove -nostdinc so we can get the intrinsics. aesni_ghash.o: aesni_ghash.c @@ -21,8 +23,20 @@ aesni_wrap.o: aesni_wrap.c -mmmx -msse -msse4 -maes ${.IMPSRC} ${CTFCONVERT_CMD} +intel_sha1.o: intel_sha1.c + ${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} \ + -mmmx -msse -msse4 -msha ${.IMPSRC} + ${CTFCONVERT_CMD} + +intel_sha256.o: intel_sha256.c + ${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} \ + -mmmx -msse -msse4 -msha ${.IMPSRC} + ${CTFCONVERT_CMD} + aesni_ghash.o: aesni.h aesni_wrap.o: aesni.h +intel_sha1.o: sha_sse.h immintrin.h shaintrin.h tmmintrin.h xmmintrin.h +intel_sha256.o: sha_sse.h immintrin.h shaintrin.h tmmintrin.h xmmintrin.h .include diff --git a/sys/modules/bhnd/bhndb_pci/Makefile b/sys/modules/bhnd/bhndb_pci/Makefile index 9e4f18185ac5..5ede56c7df6f 100644 --- a/sys/modules/bhnd/bhndb_pci/Makefile +++ b/sys/modules/bhnd/bhndb_pci/Makefile @@ -6,6 +6,7 @@ KMOD= bhndb_pci SRCS= bhndb_pci.c bhndb_pci_hwdata.c \ bhndb_pci_sprom.c SRCS+= bhnd_bus_if.h bhndb_bus_if.h bhndb_if.h +SRCS+= bhnd_erom_if.h SRCS+= bhnd_nvram_if.h SRCS+= device_if.h bus_if.h pci_if.h diff --git a/sys/modules/cloudabi32/Makefile b/sys/modules/cloudabi32/Makefile index 42482e74d0ee..d162e000a746 100644 --- a/sys/modules/cloudabi32/Makefile +++ b/sys/modules/cloudabi32/Makefile @@ -18,7 +18,7 @@ CLEANFILES=cloudabi32_vdso.o VDSO_SRCS=${SYSDIR}/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S OUTPUT_TARGET=elf64-x86-64-freebsd BINARY_ARCHITECTURE=i386 -.elif ${MACHINE_ARCH} == "armv6" +.elif ${MACHINE_ARCH:Marmv[67]*} != "" VDSO_SRCS=${SYSDIR}/contrib/cloudabi/cloudabi_vdso_armv6.S OUTPUT_TARGET=elf32-littlearm BINARY_ARCHITECTURE=arm diff --git a/sys/modules/cxgbe/t4_firmware/Makefile b/sys/modules/cxgbe/t4_firmware/Makefile index 2f0e5b7657bd..4b234a81f4f4 100644 --- a/sys/modules/cxgbe/t4_firmware/Makefile +++ b/sys/modules/cxgbe/t4_firmware/Makefile @@ -17,7 +17,7 @@ FIRMWS+= ${F}:${F:C/.txt//}:1.0.0.0 .endif .endfor -T4FW_VER= 1.16.59.0 +T4FW_VER= 1.16.63.0 FIRMWS+= t4fw.fw:t4fw:${T4FW_VER} CLEANFILES+= t4fw.fw diff --git a/sys/modules/cxgbe/t5_firmware/Makefile b/sys/modules/cxgbe/t5_firmware/Makefile index ba93924edfad..bf0d6bf7a376 100644 --- a/sys/modules/cxgbe/t5_firmware/Makefile +++ b/sys/modules/cxgbe/t5_firmware/Makefile @@ -17,7 +17,7 @@ FIRMWS+= ${F}:${F:C/.txt//}:1.0.0.0 .endif .endfor -T5FW_VER= 1.16.59.0 +T5FW_VER= 1.16.63.0 FIRMWS+= t5fw.fw:t5fw:${T5FW_VER} CLEANFILES+= t5fw.fw diff --git a/sys/modules/cxgbe/t6_firmware/Makefile b/sys/modules/cxgbe/t6_firmware/Makefile index 1c710b5a0602..a93522ea7f2a 100644 --- a/sys/modules/cxgbe/t6_firmware/Makefile +++ b/sys/modules/cxgbe/t6_firmware/Makefile @@ -17,7 +17,7 @@ FIRMWS+= ${F}:${F:C/.txt//}:1.0.0.0 .endif .endfor -T6FW_VER= 1.16.59.0 +T6FW_VER= 1.16.63.0 FIRMWS+= t6fw.fw:t6fw:${T6FW_VER} CLEANFILES+= t6fw.fw diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile index f2654f5491f9..c21856c0dfee 100644 --- a/sys/modules/dtb/allwinner/Makefile +++ b/sys/modules/dtb/allwinner/Makefile @@ -3,7 +3,6 @@ DTS= \ nanopi-neo.dts \ orangepi-plus-2e.dts \ - sinovoip-bpi-m3.dts \ sun4i-a10-cubieboard.dts \ sun4i-a10-olinuxino-lime.dts \ sun6i-a31s-sinovoip-bpi-m2.dts \ diff --git a/sys/modules/efirt/Makefile b/sys/modules/efirt/Makefile index f840bc1524bf..af5cee4ee4bb 100644 --- a/sys/modules/efirt/Makefile +++ b/sys/modules/efirt/Makefile @@ -4,7 +4,7 @@ .PATH: ${SRCTOP}/sys/dev/efidev KMOD= efirt -SRCS= efirt.c efidev.c +SRCS= efirt.c efirt_machdep.c efidev.c SRCS+= device_if.h bus_if.h .include diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile index 7567990110ad..b9caaa2d3cc1 100644 --- a/sys/modules/em/Makefile +++ b/sys/modules/em/Makefile @@ -22,7 +22,6 @@ CFLAGS += -I${SRCTOP}/sys/dev/e1000 # DEVICE_POLLING for a non-interrupt-driven method #CFLAGS += -DDEVICE_POLLING -afterinstall: - ln -sf ${DESTDIR}${KMODDIR}/${KMOD}.ko ${DESTDIR}${KMODDIR}/if_igb.ko +LINKS= ${KMODDIR}/${KMOD}.ko ${KMODDIR}/if_igb.ko .include diff --git a/sys/modules/i2c/Makefile b/sys/modules/i2c/Makefile index 34124c6e6253..5e73eb3db47a 100644 --- a/sys/modules/i2c/Makefile +++ b/sys/modules/i2c/Makefile @@ -6,6 +6,7 @@ SUBDIR = \ ds1307 \ ds13rtc \ ds3231 \ + icee \ if_ic \ iic \ iicbb \ diff --git a/sys/modules/i2c/ds1307/Makefile b/sys/modules/i2c/ds1307/Makefile index 32b80394f450..a0b0f43dd653 100644 --- a/sys/modules/i2c/ds1307/Makefile +++ b/sys/modules/i2c/ds1307/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = ds1307 -SRCS = ds1307.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = ds1307.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/i2c/ds13rtc/Makefile b/sys/modules/i2c/ds13rtc/Makefile index e50bc2f72075..a269efd57fbf 100644 --- a/sys/modules/i2c/ds13rtc/Makefile +++ b/sys/modules/i2c/ds13rtc/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = ds13rtc -SRCS = ds13rtc.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = ds13rtc.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/i2c/ds3231/Makefile b/sys/modules/i2c/ds3231/Makefile index e75c47c21c2e..f0785245f7ee 100644 --- a/sys/modules/i2c/ds3231/Makefile +++ b/sys/modules/i2c/ds3231/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = ds3231 -SRCS = ds3231.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = ds3231.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/i2c/icee/Makefile b/sys/modules/i2c/icee/Makefile new file mode 100644 index 000000000000..e9d12fd9a36a --- /dev/null +++ b/sys/modules/i2c/icee/Makefile @@ -0,0 +1,14 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/dev/iicbus +KMOD= icee +SRCS= icee.c + +SRCS+= \ + bus_if.h \ + device_if.h \ + iicbus_if.h \ + ofw_bus_if.h \ + opt_platform.h \ + +.include diff --git a/sys/modules/i2c/isl12xx/Makefile b/sys/modules/i2c/isl12xx/Makefile index 5f31317fc3b7..93f935bb38bd 100644 --- a/sys/modules/i2c/isl12xx/Makefile +++ b/sys/modules/i2c/isl12xx/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = isl12xx -SRCS = isl12xx.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = isl12xx.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/i2c/nxprtc/Makefile b/sys/modules/i2c/nxprtc/Makefile index d2252b148e33..29cd2d05b546 100644 --- a/sys/modules/i2c/nxprtc/Makefile +++ b/sys/modules/i2c/nxprtc/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = nxprtc -SRCS = nxprtc.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = nxprtc.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/i2c/s35390a/Makefile b/sys/modules/i2c/s35390a/Makefile index 1e6e93e60e41..6f8e45f41478 100644 --- a/sys/modules/i2c/s35390a/Makefile +++ b/sys/modules/i2c/s35390a/Makefile @@ -2,6 +2,6 @@ .PATH: ${SRCTOP}/sys/dev/iicbus KMOD = s35390a -SRCS = s35390a.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h +SRCS = s35390a.c bus_if.h clock_if.h device_if.h iicbus_if.h ofw_bus_if.h opt_platform.h .include diff --git a/sys/modules/iwmfw/Makefile b/sys/modules/iwmfw/Makefile index d38f54241530..1b310ef5b2cf 100644 --- a/sys/modules/iwmfw/Makefile +++ b/sys/modules/iwmfw/Makefile @@ -1,5 +1,10 @@ # $FreeBSD$ -SUBDIR= iwm3160fw iwm7260fw iwm7265fw iwm8000Cfw iwm7265Dfw +SUBDIR= iwm3160fw \ + iwm7260fw \ + iwm7265fw \ + iwm7265Dfw \ + iwm8000Cfw \ + iwm8265fw .include diff --git a/sys/modules/iwmfw/iwm8265fw/Makefile b/sys/modules/iwmfw/iwm8265fw/Makefile new file mode 100644 index 000000000000..4e4ff4d92466 --- /dev/null +++ b/sys/modules/iwmfw/iwm8265fw/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +KMOD= iwm8265fw +IMG= iwm-8265-22 + +.include diff --git a/sys/modules/libmbpool/Makefile b/sys/modules/libmbpool/Makefile deleted file mode 100644 index 2b694be83962..000000000000 --- a/sys/modules/libmbpool/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/kern - -KMOD= libmbpool -SRCS= subr_mbpool.c - -EXPORT_SYMS= mbp_create \ - mbp_destroy \ - mbp_alloc \ - mbp_free \ - mbp_ext_free \ - mbp_card_free \ - mbp_count \ - mbp_get \ - mbp_get_keep \ - mbp_sync - -.include diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 0ce0ac936ff1..e5cb1f7d7e53 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -79,12 +79,16 @@ ZFS_SRCS= ${ZFS_OBJS:C/.o$/.c/} SRCS+= ${ZFS_SRCS} SRCS+= vdev_geom.c SRCS+= trim_map.c +.PATH: ${SUNW}/uts/common/fs/zfs/lua +LUA_SRCS= ${LUA_OBJS:C/.o$/.c/} +SRCS+= ${LUA_SRCS} # Use FreeBSD's namecache. CFLAGS+=-DFREEBSD_NAMECACHE CFLAGS+=-I${SYSDIR}/cddl/compat/opensolaris CFLAGS+=-I${SUNW}/uts/common/fs/zfs +CFLAGS+=-I${SUNW}/uts/common/fs/zfs/lua CFLAGS+=-I${SUNW}/uts/common/zmod CFLAGS+=-I${SUNW}/uts/common CFLAGS+=-I${SYSDIR} diff --git a/sys/net/bpf_zerocopy.c b/sys/net/bpf_zerocopy.c index 5d54f649e133..13757168573b 100644 --- a/sys/net/bpf_zerocopy.c +++ b/sys/net/bpf_zerocopy.c @@ -114,8 +114,7 @@ zbuf_page_free(vm_page_t pp) { vm_page_lock(pp); - vm_page_unwire(pp, PQ_INACTIVE); - if (pp->wire_count == 0 && pp->object == NULL) + if (vm_page_unwire(pp, PQ_INACTIVE) && pp->object == NULL) vm_page_free(pp); vm_page_unlock(pp); } diff --git a/sys/net/if.c b/sys/net/if.c index bc6c5a2cfa80..a5428a2fbdea 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1708,7 +1708,7 @@ ifa_maintain_loopback_route(int cmd, const char *otype, struct ifaddr *ifa, bzero(&info, sizeof(info)); if (cmd != RTM_DELETE) info.rti_ifp = V_loif; - info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC; + info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC | RTF_PINNED; info.rti_info[RTAX_DST] = ia; info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; link_init_sdl(ifp, (struct sockaddr *)&null_sdl, ifp->if_type); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index e67e287bd861..efd50d9c7f4f 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -584,6 +584,7 @@ static moduledata_t bridge_mod = { }; DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(if_bridge, 1); MODULE_DEPEND(if_bridge, bridgestp, 1, 1, 1); /* diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 3b5884e841d5..cba0d9ad7d69 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -595,39 +595,21 @@ ifc_name2unit(const char *name, int *unit) return (0); } -int -ifc_alloc_unit(struct if_clone *ifc, int *unit) +static int +ifc_alloc_unit_specific(struct if_clone *ifc, int *unit) { char name[IFNAMSIZ]; - int wildcard; - wildcard = (*unit < 0); -retry: if (*unit > ifc->ifc_maxunit) return (ENOSPC); - if (*unit < 0) { - *unit = alloc_unr(ifc->ifc_unrhdr); - if (*unit == -1) - return (ENOSPC); - } else { - *unit = alloc_unr_specific(ifc->ifc_unrhdr, *unit); - if (*unit == -1) { - if (wildcard) { - (*unit)++; - goto retry; - } else - return (EEXIST); - } - } + + if (alloc_unr_specific(ifc->ifc_unrhdr, *unit) == -1) + return (EEXIST); snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, *unit); if (ifunit(name) != NULL) { free_unr(ifc->ifc_unrhdr, *unit); - if (wildcard) { - (*unit)++; - goto retry; - } else - return (EEXIST); + return (EEXIST); } IF_CLONE_ADDREF(ifc); @@ -635,6 +617,36 @@ ifc_alloc_unit(struct if_clone *ifc, int *unit) return (0); } +static int +ifc_alloc_unit_next(struct if_clone *ifc, int *unit) +{ + int error; + + *unit = alloc_unr(ifc->ifc_unrhdr); + if (*unit == -1) + return (ENOSPC); + + free_unr(ifc->ifc_unrhdr, *unit); + for (;;) { + error = ifc_alloc_unit_specific(ifc, unit); + if (error != EEXIST) + break; + + (*unit)++; + } + + return (error); +} + +int +ifc_alloc_unit(struct if_clone *ifc, int *unit) +{ + if (*unit < 0) + return (ifc_alloc_unit_next(ifc, unit)); + else + return (ifc_alloc_unit_specific(ifc, unit)); +} + void ifc_free_unit(struct if_clone *ifc, int unit) { diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index fec623b59706..e7fd4f8a80b7 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -980,6 +980,17 @@ vnet_epair_uninit(const void *unused __unused) VNET_SYSUNINIT(vnet_epair_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY, vnet_epair_uninit, NULL); +static void +epair_uninit(const void *unused __unused) +{ + netisr_unregister(&epair_nh); + epair_dpcpu_detach(); + if (bootverbose) + printf("%s unloaded.\n", epairname); +} +SYSUNINIT(epair_uninit, SI_SUB_INIT_IF, SI_ORDER_MIDDLE, + epair_uninit, NULL); + static int epair_modevent(module_t mod, int type, void *data) { @@ -997,10 +1008,7 @@ epair_modevent(module_t mod, int type, void *data) printf("%s initialized.\n", epairname); break; case MOD_UNLOAD: - netisr_unregister(&epair_nh); - epair_dpcpu_detach(); - if (bootverbose) - printf("%s unloaded.\n", epairname); + /* Handled in epair_uninit() */ break; default: return (EOPNOTSUPP); diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 4c077d5c0a03..14d267812388 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include + #include #include #include @@ -58,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -67,6 +69,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -136,6 +140,8 @@ typedef struct iflib_fl *iflib_fl_t; struct iflib_ctx; +static void iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid); + typedef struct iflib_filter_info { driver_filter_t *ifi_filter; void *ifi_filter_arg; @@ -156,7 +162,7 @@ struct iflib_ctx { if_shared_ctx_t ifc_sctx; struct if_softc_ctx ifc_softc_ctx; - struct sx ifc_sx; + struct mtx ifc_mtx; uint16_t ifc_nhwtxqs; uint16_t ifc_nhwrxqs; @@ -184,7 +190,6 @@ struct iflib_ctx { uint16_t ifc_sysctl_ntxqs; uint16_t ifc_sysctl_nrxqs; uint16_t ifc_sysctl_qs_eq_override; - uint16_t ifc_cpuid_highest; uint16_t ifc_sysctl_rx_budget; qidx_t ifc_sysctl_ntxds[8]; @@ -204,66 +209,8 @@ struct iflib_ctx { eventhandler_tag ifc_vlan_detach_event; uint8_t ifc_mac[ETHER_ADDR_LEN]; char ifc_mtx_name[16]; - LIST_ENTRY(iflib_ctx) ifc_next; }; -static LIST_HEAD(ctx_head, iflib_ctx) ctx_list; -static struct mtx ctx_list_lock; - -TASKQGROUP_DEFINE(if_io, mp_ncpus, 1, true, PI_NET); -TASKQGROUP_DEFINE(if_config, 1, 1, false, PI_SOFT); - -static void -iflib_ctx_apply(void (*fn)(if_ctx_t ctx, void *arg), void *arg) -{ - if_ctx_t ctx; - - mtx_lock(&ctx_list_lock); - LIST_FOREACH(ctx, &ctx_list, ifc_next) { - (fn)(ctx, arg); - } - mtx_unlock(&ctx_list_lock); -} - -static void -_iflib_cpuid_highest(if_ctx_t ctx, void *arg) { - int *cpuid = arg; - - if (*cpuid < ctx->ifc_cpuid_highest) - *cpuid = ctx->ifc_cpuid_highest; -} - -static int -iflib_cpuid_highest(void) -{ - int cpuid = 0; - - iflib_ctx_apply(_iflib_cpuid_highest, &cpuid); - return (cpuid); -} - -static void -iflib_ctx_insert(if_ctx_t ctx) -{ - mtx_lock(&ctx_list_lock); - LIST_INSERT_HEAD(&ctx_list, ctx, ifc_next); - mtx_unlock(&ctx_list_lock); -} - -static void -iflib_ctx_remove(if_ctx_t ctx) -{ - int max_cpuid_prev, max_cpuid_new; - - max_cpuid_prev = iflib_cpuid_highest(); - mtx_lock(&ctx_list_lock); - LIST_REMOVE(ctx, ifc_next); - mtx_unlock(&ctx_list_lock); - max_cpuid_new = max(1, iflib_cpuid_highest()); - if (max_cpuid_new < max_cpuid_prev) { - taskqgroup_adjust(qgroup_if_io, max_cpuid_new, 1, true, PI_NET); - } -} void * iflib_get_softc(if_ctx_t ctx) @@ -322,11 +269,9 @@ iflib_get_sctx(if_ctx_t ctx) #define CTX_IS_VF(ctx) ((ctx)->ifc_sctx->isc_flags & IFLIB_IS_VF) #define RX_SW_DESC_MAP_CREATED (1 << 0) -#define RX_SW_DESC_INUSE (1 << 1) -#define RX_NETMAP_INUSE (1 << 2) - -#define TX_SW_DESC_MAP_CREATED (1 << 0) -#define TX_SW_DESC_MAPPED (1 << 1) +#define TX_SW_DESC_MAP_CREATED (1 << 1) +#define RX_SW_DESC_INUSE (1 << 3) +#define TX_SW_DESC_MAPPED (1 << 4) #define M_TOOBIG M_PROTO1 @@ -346,7 +291,8 @@ typedef struct iflib_sw_tx_desc_array { /* magic number that should be high enough for any hardware */ #define IFLIB_MAX_TX_SEGS 128 -#define IFLIB_MAX_RX_SEGS 32 +/* bnxt supports 64 with hardware LRO enabled */ +#define IFLIB_MAX_RX_SEGS 64 #define IFLIB_RX_COPY_THRESH 128 #define IFLIB_MAX_RX_REFRESH 32 /* The minimum descriptors per second before we start coalescing */ @@ -418,7 +364,6 @@ struct iflib_txq { uint8_t ift_qstatus; uint8_t ift_closed; uint8_t ift_update_freq; - uint8_t ift_stall_count; struct iflib_filter_info ift_filter_info; bus_dma_tag_t ift_desc_tag; bus_dma_tag_t ift_tso_desc_tag; @@ -510,11 +455,9 @@ struct iflib_rxq { struct grouptask ifr_task; struct iflib_filter_info ifr_filter_info; iflib_dma_info_t ifr_ifdi; - struct if_rxd_info ifr_ri; - struct if_rxd_update ifr_iru; + /* dynamically allocate if any drivers need a value substantially larger than this */ struct if_rxd_frag ifr_frags[IFLIB_MAX_RX_SEGS] __aligned(CACHE_LINE_SIZE); - #ifdef IFLIB_DIAGNOSTICS uint64_t ifr_cpu_exec_count[256]; #endif @@ -529,11 +472,11 @@ typedef struct if_rxsd { /* multiple of word size */ #ifdef __LP64__ -#define PKT_INFO_SIZE 7 +#define PKT_INFO_SIZE 6 #define RXD_INFO_SIZE 5 #define PKT_TYPE uint64_t #else -#define PKT_INFO_SIZE 12 +#define PKT_INFO_SIZE 11 #define RXD_INFO_SIZE 8 #define PKT_TYPE uint32_t #endif @@ -559,10 +502,9 @@ pkt_info_zero(if_pkt_info_t pi) pi_pad = (if_pkt_info_pad_t)pi; pi_pad->pkt_val[0] = 0; pi_pad->pkt_val[1] = 0; pi_pad->pkt_val[2] = 0; pi_pad->pkt_val[3] = 0; pi_pad->pkt_val[4] = 0; pi_pad->pkt_val[5] = 0; - pi_pad->pkt_val[6] = 0; #ifndef __LP64__ - pi_pad->pkt_val[7] = 0; pi_pad->pkt_val[8] = 0; pi_pad->pkt_val[9] = 0; - pi_pad->pkt_val[10] = 0; pi_pad->pkt_val[11] = 0; + pi_pad->pkt_val[6] = 0; pi_pad->pkt_val[7] = 0; pi_pad->pkt_val[8] = 0; + pi_pad->pkt_val[9] = 0; pi_pad->pkt_val[10] = 0; #endif } @@ -590,24 +532,14 @@ rxd_info_zero(if_rxd_info_t ri) #define MAX_SINGLE_PACKET_FRACTION 12 #define IF_BAD_DMA (bus_addr_t)-1 -static SYSCTL_NODE(_net, OID_AUTO, iflib, CTLFLAG_RD, 0, - "iflib driver parameters"); - -static int iflib_timer_int; -SYSCTL_INT(_net_iflib, OID_AUTO, timer_int, CTLFLAG_RW, &iflib_timer_int, - 0, "interval at which to run per-queue timers (in ticks)"); - -static int force_busdma = 0; -SYSCTL_INT(_net_iflib, OID_AUTO, force_busdma, CTLFLAG_RDTUN, &force_busdma, - 1, "force busdma"); - #define CTX_ACTIVE(ctx) ((if_getdrvflags((ctx)->ifc_ifp) & IFF_DRV_RUNNING)) -#define CTX_LOCK_INIT(_sc, _name) sx_init(&(_sc)->ifc_sx, _name) +#define CTX_LOCK_INIT(_sc, _name) mtx_init(&(_sc)->ifc_mtx, _name, "iflib ctx lock", MTX_DEF) + +#define CTX_LOCK(ctx) mtx_lock(&(ctx)->ifc_mtx) +#define CTX_UNLOCK(ctx) mtx_unlock(&(ctx)->ifc_mtx) +#define CTX_LOCK_DESTROY(ctx) mtx_destroy(&(ctx)->ifc_mtx) -#define CTX_LOCK(ctx) sx_xlock(&(ctx)->ifc_sx) -#define CTX_UNLOCK(ctx) sx_xunlock(&(ctx)->ifc_sx) -#define CTX_LOCK_DESTROY(ctx) sx_destroy(&(ctx)->ifc_sx) #define CALLOUT_LOCK(txq) mtx_lock(&txq->ift_mtx) #define CALLOUT_UNLOCK(txq) mtx_unlock(&txq->ift_mtx) @@ -628,6 +560,9 @@ MODULE_VERSION(iflib, 1); MODULE_DEPEND(iflib, pci, 1, 1, 1); MODULE_DEPEND(iflib, ether, 1, 1, 1); +TASKQGROUP_DEFINE(if_io_tqg, mp_ncpus, 1); +TASKQGROUP_DEFINE(if_config_tqg, 1, 1); + #ifndef IFLIB_DEBUG_COUNTERS #ifdef INVARIANTS #define IFLIB_DEBUG_COUNTERS 1 @@ -636,6 +571,9 @@ MODULE_DEPEND(iflib, ether, 1, 1, 1); #endif /* !INVARIANTS */ #endif +static SYSCTL_NODE(_net, OID_AUTO, iflib, CTLFLAG_RD, 0, + "iflib driver parameters"); + /* * XXX need to ensure that this can't accidentally cause the head to be moved backwards */ @@ -758,14 +696,7 @@ iflib_debug_reset(void) static void iflib_debug_reset(void) {} #endif -typedef void async_gtask_fn_t(if_ctx_t ctx, void *arg); -struct async_task_arg { - async_gtask_fn_t *ata_fn; - if_ctx_t ata_ctx; - void *ata_arg; - struct grouptask *ata_gtask; -}; #define IFLIB_DEBUG 0 @@ -787,12 +718,6 @@ static void iflib_ifmp_purge(iflib_txq_t txq); static void _iflib_pre_assert(if_softc_ctx_t scctx); static void iflib_stop(if_ctx_t ctx); static void iflib_if_init_locked(if_ctx_t ctx); -static int async_if_ioctl(if_ctx_t ctx, u_long command, caddr_t data); -static int iflib_config_async_gtask_dispatch(if_ctx_t ctx, async_gtask_fn_t *fn, char *name, void *arg); -static void iflib_admin_reset_deferred(if_ctx_t ctx); - - - #ifndef __NO_STRICT_ALIGNMENT static struct mbuf * iflib_fixup_rx(struct mbuf *m); #endif @@ -804,6 +729,8 @@ static struct mbuf * iflib_fixup_rx(struct mbuf *m); MODULE_DEPEND(iflib, netmap, 1, 1, 1); +static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init); + /* * device-specific sysctl variables: * @@ -866,20 +793,6 @@ iflib_netmap_register(struct netmap_adapter *na, int onoff) return (status); } -static void -iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid) -{ - iflib_fl_t fl; - - fl = &rxq->ifr_fl[flid]; - iru->iru_paddrs = fl->ifl_bus_addrs; - iru->iru_vaddrs = &fl->ifl_vm_addrs[0]; - iru->iru_idxs = fl->ifl_rxd_idxs; - iru->iru_qsidx = rxq->ifr_id; - iru->iru_buf_size = fl->ifl_buf_size; - iru->iru_flidx = fl->ifl_id; -} - static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init) { @@ -888,56 +801,61 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo u_int head = kring->rhead; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; - if_rxd_update_t iru; + struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = &rxq->ifr_fl[0]; uint32_t refill_pidx, nic_i; - iru = &rxq->ifr_iru; - iru_init(iru, rxq, 0 /* flid */); + if (nm_i == head && __predict_true(!init)) + return 0; + iru_init(&iru, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; refill_pidx = netmap_idx_k2n(kring, nm_i); - if (init && (nm_i == head)) - head = nm_prev(head, lim); - for (int tmp_pidx = 0; nm_i != head; tmp_pidx++) { - struct netmap_slot *slot = &ring->slot[nm_i]; - void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[tmp_pidx]); - uint32_t nic_i_dma = refill_pidx; - nic_i = netmap_idx_k2n(kring, nm_i); + /* + * IMPORTANT: we must leave one free slot in the ring, + * so move head back by one unit + */ + head = nm_prev(head, lim); + while (nm_i != head) { + for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) { + struct netmap_slot *slot = &ring->slot[nm_i]; + void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[tmp_pidx]); + uint32_t nic_i_dma = refill_pidx; + nic_i = netmap_idx_k2n(kring, nm_i); - MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH); + MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH); - if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ - return netmap_ring_reinit(kring); + if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ + return netmap_ring_reinit(kring); - fl->ifl_vm_addrs[tmp_pidx] = addr; - if (__predict_false(init) && map) { - netmap_load_map(na, fl->ifl_ifdi->idi_tag, map[nic_i], addr); - } else if (map && (slot->flags & NS_BUF_CHANGED)) { - /* buffer has changed, reload map */ - netmap_reload_map(na, fl->ifl_ifdi->idi_tag, map[nic_i], addr); - } - slot->flags &= ~NS_BUF_CHANGED; + fl->ifl_vm_addrs[tmp_pidx] = addr; + if (__predict_false(init) && map) { + netmap_load_map(na, fl->ifl_ifdi->idi_tag, map[nic_i], addr); + } else if (map && (slot->flags & NS_BUF_CHANGED)) { + /* buffer has changed, reload map */ + netmap_reload_map(na, fl->ifl_ifdi->idi_tag, map[nic_i], addr); + } + slot->flags &= ~NS_BUF_CHANGED; - nm_i = nm_next(nm_i, lim); - fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim); - if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1) - continue; + nm_i = nm_next(nm_i, lim); + fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim); + if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1) + continue; - iru->iru_pidx = refill_pidx; - iru->iru_count = tmp_pidx+1; - ctx->isc_rxd_refill(ctx->ifc_softc, iru); + iru.iru_pidx = refill_pidx; + iru.iru_count = tmp_pidx+1; + ctx->isc_rxd_refill(ctx->ifc_softc, &iru); - tmp_pidx = 0; - refill_pidx = nic_i; - if (map == NULL) - continue; + refill_pidx = nic_i; + if (map == NULL) + continue; - for (int n = 0; n < iru->iru_count; n++) { - bus_dmamap_sync(fl->ifl_ifdi->idi_tag, map[nic_i_dma], - BUS_DMASYNC_PREREAD); - /* XXX - change this to not use the netmap func*/ - nic_i_dma = nm_next(nic_i_dma, lim); + for (int n = 0; n < iru.iru_count; n++) { + bus_dmamap_sync(fl->ifl_ifdi->idi_tag, map[nic_i_dma], + BUS_DMASYNC_PREREAD); + /* XXX - change this to not use the netmap func*/ + nic_i_dma = nm_next(nic_i_dma, lim); + } } } kring->nr_hwcur = head; @@ -945,11 +863,6 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo if (map) bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - /* - * IMPORTANT: we must leave one free slot in the ring, - * so move nic_i back by one unit - */ - nic_i = nm_prev(nic_i, lim); ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); return (0); } @@ -1017,7 +930,7 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags) * to prefetch the next slot and txr entry. */ - nm_i = kring->nr_hwcur; + nm_i = netmap_idx_n2k(kring, kring->nr_hwcur); pkt_info_zero(&pi); pi.ipi_segs = txq->ift_segs; pi.ipi_qsidx = kring->ring_id; @@ -1114,17 +1027,14 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) uint32_t nic_i; /* index into the NIC ring */ u_int i, n; u_int const lim = kring->nkr_num_slots - 1; - u_int const head = kring->rhead; + u_int const head = netmap_idx_n2k(kring, kring->rhead); int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; - struct if_rxd_info *ri; - struct if_rxd_update *iru; + struct if_rxd_info ri; struct ifnet *ifp = na->ifp; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; iflib_fl_t fl = rxq->ifr_fl; - ri = &rxq->ifr_ri; - iru = &rxq->ifr_iru; if (head > lim) return netmap_ring_reinit(kring); @@ -1155,19 +1065,20 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) int error, avail; uint16_t slot_flags = kring->nkr_slot_flags; - for (fl = rxq->ifr_fl, i = 0; i < rxq->ifr_nfl; i++, fl++) { + for (i = 0; i < rxq->ifr_nfl; i++) { + fl = &rxq->ifr_fl[i]; nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); avail = iflib_rxd_avail(ctx, rxq, nic_i, USHRT_MAX); for (n = 0; avail > 0; n++, avail--) { - rxd_info_zero(ri); - ri->iri_frags = rxq->ifr_frags; - ri->iri_qsidx = kring->ring_id; - ri->iri_ifp = ctx->ifc_ifp; - ri->iri_cidx = nic_i; + rxd_info_zero(&ri); + ri.iri_frags = rxq->ifr_frags; + ri.iri_qsidx = kring->ring_id; + ri.iri_ifp = ctx->ifc_ifp; + ri.iri_cidx = nic_i; - error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ri); - ring->slot[nm_i].len = error ? 0 : ri->iri_len - crclen; + error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri); + ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; ring->slot[nm_i].flags = slot_flags; if (fl->ifl_sds.ifsd_map) bus_dmamap_sync(fl->ifl_ifdi->idi_tag, @@ -1182,7 +1093,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) iflib_rx_miss_bufs += n; } fl->ifl_cidx = nic_i; - kring->nr_hwtail = nm_i; + kring->nr_hwtail = netmap_idx_k2n(kring, nm_i); } kring->nr_kflags &= ~NKR_PENDINTR; } @@ -1196,9 +1107,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) * nm_i == (nic_i + kring->nkr_hwofs) % ring_size */ /* XXX not sure how this will work with multiple free lists */ - nm_i = kring->nr_hwcur; - if (nm_i == head) - return (0); + nm_i = netmap_idx_n2k(kring, kring->nr_hwcur); return (netmap_fl_refill(rxq, kring, nm_i, false)); } @@ -1209,12 +1118,13 @@ iflib_netmap_intr(struct netmap_adapter *na, int onoff) struct ifnet *ifp = na->ifp; if_ctx_t ctx = ifp->if_softc; - /* XXX - do we need synchronization here?*/ + CTX_LOCK(ctx); if (onoff) { IFDI_INTR_ENABLE(ctx); } else { IFDI_INTR_DISABLE(ctx); } + CTX_UNLOCK(ctx); } @@ -1267,6 +1177,7 @@ iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) netmap_load_map(na, txq->ift_desc_tag, txq->ift_sds.ifsd_map[i], NMB(na, slot + si)); } } + static void iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) { @@ -1302,7 +1213,7 @@ prefetch(void *x) __asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); } static __inline void -prefetch2(void *x) +prefetch2cachelines(void *x) { __asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); #if (CACHE_LINE_SIZE < 128) @@ -1311,9 +1222,23 @@ prefetch2(void *x) } #else #define prefetch(x) -#define prefetch2(x) +#define prefetch2cachelines(x) #endif +static void +iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid) +{ + iflib_fl_t fl; + + fl = &rxq->ifr_fl[flid]; + iru->iru_paddrs = fl->ifl_bus_addrs; + iru->iru_vaddrs = &fl->ifl_vm_addrs[0]; + iru->iru_idxs = fl->ifl_rxd_idxs; + iru->iru_qsidx = rxq->ifr_id; + iru->iru_buf_size = fl->ifl_buf_size; + iru->iru_flidx = fl->ifl_id; +} + static void _iflib_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) { @@ -1427,25 +1352,6 @@ iflib_dma_free_multi(iflib_dma_info_t *dmalist, int count) iflib_dma_free(*dmaiter); } -static void -txq_validate(iflib_txq_t txq) { -#ifdef INVARIANTS - uint32_t cidx = txq->ift_cidx; - struct mbuf **ifsd_m = txq->ift_sds.ifsd_m; - if (txq->ift_pidx > cidx) { - int i; - for (i = txq->ift_pidx; i < txq->ift_size; i++) - MPASS(ifsd_m[i] == NULL); - for (i = 0; i < cidx; i++) - MPASS(ifsd_m[i] == NULL); - } else if (txq->ift_pidx < cidx) { - int i; - for (i = txq->ift_pidx; i < cidx; i++) - MPASS(ifsd_m[i] == NULL); - } -#endif -} - #ifdef EARLY_AP_STARTUP static const int iflib_started = 1; #else @@ -1474,7 +1380,6 @@ iflib_fast_intr(void *arg) { iflib_filter_info_t info = arg; struct grouptask *gtask = info->ifi_task; - if (!iflib_started) return (FILTER_HANDLED); @@ -1486,35 +1391,6 @@ iflib_fast_intr(void *arg) return (FILTER_HANDLED); } -static int -iflib_fast_intr_rx(void *arg) -{ - iflib_filter_info_t info = arg; - struct grouptask *gtask = info->ifi_task; - iflib_rxq_t rxq = (iflib_rxq_t)info->ifi_ctx; - if_ctx_t ctx; - int cidx; - - if (!iflib_started) - return (FILTER_HANDLED); - - DBG_COUNTER_INC(fast_intrs); - if (info->ifi_filter != NULL && info->ifi_filter(info->ifi_filter_arg) == FILTER_HANDLED) - return (FILTER_HANDLED); - - ctx = rxq->ifr_ctx; - if (ctx->ifc_sctx->isc_flags & IFLIB_HAS_RXCQ) - cidx = rxq->ifr_cq_cidx; - else - cidx = rxq->ifr_fl[0].ifl_cidx; - if (iflib_rxd_avail(ctx, rxq, cidx, 1)) - GROUPTASK_ENQUEUE(gtask); - else - IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id); - return (FILTER_HANDLED); -} - - static int iflib_fast_intr_rxtx(void *arg) { @@ -1531,10 +1407,11 @@ iflib_fast_intr_rxtx(void *arg) if (info->ifi_filter != NULL && info->ifi_filter(info->ifi_filter_arg) == FILTER_HANDLED) return (FILTER_HANDLED); - ctx = rxq->ifr_ctx; for (i = 0; i < rxq->ifr_ntxqirq; i++) { qidx_t txqid = rxq->ifr_txqid[i]; + ctx = rxq->ifr_ctx; + if (!ctx->isc_txd_credits_update(ctx->ifc_softc, txqid, false)) { IFDI_TX_QUEUE_INTR_ENABLE(ctx, txqid); continue; @@ -1944,20 +1821,22 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) int n, i = 0; uint64_t bus_addr; int err; + qidx_t credits; sd_m = fl->ifl_sds.ifsd_m; sd_map = fl->ifl_sds.ifsd_map; sd_cl = fl->ifl_sds.ifsd_cl; sd_flags = fl->ifl_sds.ifsd_flags; idx = pidx; + credits = fl->ifl_credits; n = count; MPASS(n > 0); - MPASS(fl->ifl_credits + n <= fl->ifl_size); + MPASS(credits + n <= fl->ifl_size); if (pidx < fl->ifl_cidx) MPASS(pidx + n <= fl->ifl_cidx); - if (pidx == fl->ifl_cidx && (fl->ifl_credits < fl->ifl_size)) + if (pidx == fl->ifl_cidx && (credits < fl->ifl_size)) MPASS(fl->ifl_gen == 0); if (pidx > fl->ifl_cidx) MPASS(n <= fl->ifl_size - pidx + fl->ifl_cidx); @@ -1965,12 +1844,7 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) DBG_COUNTER_INC(fl_refills); if (n > 8) DBG_COUNTER_INC(fl_refills_large); - iru.iru_paddrs = fl->ifl_bus_addrs; - iru.iru_vaddrs = &fl->ifl_vm_addrs[0]; - iru.iru_idxs = fl->ifl_rxd_idxs; - iru.iru_qsidx = fl->ifl_rxq->ifr_id; - iru.iru_buf_size = fl->ifl_buf_size; - iru.iru_flidx = fl->ifl_id; + iru_init(&iru, fl->ifl_rxq, fl->ifl_id); while (n--) { /* * We allocate an uninitialized mbuf + cluster, mbuf is @@ -2035,9 +1909,9 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) fl->ifl_rxd_idxs[i] = frag_idx; fl->ifl_bus_addrs[i] = bus_addr; fl->ifl_vm_addrs[i] = cl; - fl->ifl_credits++; + credits++; i++; - MPASS(fl->ifl_credits <= fl->ifl_size); + MPASS(credits <= fl->ifl_size); if (++idx == fl->ifl_size) { fl->ifl_gen = 1; idx = 0; @@ -2049,10 +1923,18 @@ _iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) i = 0; pidx = idx; fl->ifl_pidx = idx; + fl->ifl_credits = credits; } } done: + if (i) { + iru.iru_pidx = pidx; + iru.iru_count = i; + ctx->isc_rxd_refill(ctx->ifc_softc, &iru); + fl->ifl_pidx = idx; + fl->ifl_credits = credits; + } DBG_COUNTER_INC(rxd_flush); if (fl->ifl_pidx == 0) pidx = fl->ifl_size - 1; @@ -2106,33 +1988,20 @@ iflib_fl_bufs_free(iflib_fl_t fl) if (*sd_cl != NULL) uma_zfree(fl->ifl_zone, *sd_cl); *sd_flags = 0; - } else if (*sd_flags & RX_NETMAP_INUSE) { - if (fl->ifl_sds.ifsd_map != NULL) { - bus_dmamap_t sd_map = fl->ifl_sds.ifsd_map[i]; - bus_dmamap_unload(fl->ifl_desc_tag, sd_map); - bus_dmamap_destroy(fl->ifl_desc_tag, sd_map); - } - *sd_flags = 0; - MPASS(*sd_cl == NULL); - MPASS(*sd_m == NULL); } else { MPASS(*sd_cl == NULL); MPASS(*sd_m == NULL); } - #if MEMORY_LOGGING - if (*sd_m != NULL) - fl->ifl_m_dequeued++; - if (*sd_cl != NULL) - fl->ifl_cl_dequeued++; + fl->ifl_m_dequeued++; + fl->ifl_cl_dequeued++; #endif *sd_cl = NULL; *sd_m = NULL; } #ifdef INVARIANTS for (i = 0; i < fl->ifl_size; i++) { - KASSERT(fl->ifl_sds.ifsd_flags[i] == 0, ("fl->ifl_sds.ifsd_flags[%d]=0x%x, expected 0", - i, fl->ifl_sds.ifsd_flags[i])); + MPASS(fl->ifl_sds.ifsd_flags[i] == 0); MPASS(fl->ifl_sds.ifsd_cl[i] == NULL); MPASS(fl->ifl_sds.ifsd_m[i] == NULL); } @@ -2156,7 +2025,7 @@ iflib_fl_setup(iflib_fl_t fl) if_ctx_t ctx = rxq->ifr_ctx; if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; - bit_nclear(fl->ifl_rx_bitmap, 0, fl->ifl_size-1); + bit_nclear(fl->ifl_rx_bitmap, 0, fl->ifl_size); /* ** Free current RX buffer structs and their mbufs */ @@ -2235,19 +2104,6 @@ iflib_rx_sds_free(iflib_rxq_t rxq) } } -/* CONFIG context only */ -static void -iflib_handle_hang(if_ctx_t ctx, void *arg __unused) -{ - - CTX_LOCK(ctx); - if_setdrvflagbits(ctx->ifc_ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); - IFDI_WATCHDOG_RESET(ctx); - ctx->ifc_watchdog_events++; - iflib_if_init_locked(ctx); - CTX_UNLOCK(ctx); -} - /* * MI independent logic * @@ -2255,49 +2111,46 @@ iflib_handle_hang(if_ctx_t ctx, void *arg __unused) static void iflib_timer(void *arg) { - iflib_txq_t txq_i, txq = arg; + iflib_txq_t txq = arg; if_ctx_t ctx = txq->ift_ctx; + if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) return; - /* handle any laggards */ - if (txq->ift_db_pending) - GROUPTASK_ENQUEUE(&txq->ift_task); - IFDI_TIMER(ctx, txq->ift_id); - - if (ifmp_ring_is_stalled(txq->ift_br) && - txq->ift_cleaned_prev == txq->ift_cleaned) - txq->ift_stall_count++; - txq->ift_cleaned_prev = txq->ift_cleaned; - if (txq->ift_stall_count > 2) { - txq->ift_qstatus = IFLIB_QUEUE_HUNG; - device_printf(ctx->ifc_dev, "TX(%d) desc avail = %d, pidx = %d\n", - txq->ift_id, TXQ_AVAIL(txq), txq->ift_pidx); - } - if (txq->ift_id != 0) { - if (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING) - callout_reset_on(&txq->ift_timer, iflib_timer_int, iflib_timer, - txq, txq->ift_timer.c_cpu); - return; - } /* ** Check on the state of the TX queue(s), this ** can be done without the lock because its RO ** and the HUNG state will be static if set. */ - txq_i = ctx->ifc_txqs; - for (int i = 0; i < ctx->ifc_softc_ctx.isc_ntxqsets; i++, txq_i++) { - if (txq_i->ift_qstatus == IFLIB_QUEUE_HUNG) { - iflib_config_async_gtask_dispatch(ctx, iflib_handle_hang, "hang handler", txq); - /* init will reset the callout */ - return; - } - } + IFDI_TIMER(ctx, txq->ift_id); + if ((txq->ift_qstatus == IFLIB_QUEUE_HUNG) && + ((txq->ift_cleaned_prev == txq->ift_cleaned) || + (sctx->isc_pause_frames == 0))) + goto hung; + if (ifmp_ring_is_stalled(txq->ift_br)) + txq->ift_qstatus = IFLIB_QUEUE_HUNG; + txq->ift_cleaned_prev = txq->ift_cleaned; + /* handle any laggards */ + if (txq->ift_db_pending) + GROUPTASK_ENQUEUE(&txq->ift_task); + sctx->isc_pause_frames = 0; if (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING) - callout_reset_on(&txq->ift_timer, iflib_timer_int, iflib_timer, - txq, txq->ift_timer.c_cpu); + callout_reset_on(&txq->ift_timer, hz/2, iflib_timer, txq, txq->ift_timer.c_cpu); + return; +hung: + CTX_LOCK(ctx); + if_setdrvflagbits(ctx->ifc_ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); + device_printf(ctx->ifc_dev, "TX(%d) desc avail = %d, pidx = %d\n", + txq->ift_id, TXQ_AVAIL(txq), txq->ift_pidx); + + IFDI_WATCHDOG_RESET(ctx); + ctx->ifc_watchdog_events++; + + ctx->ifc_flags |= IFC_DO_RESET; + iflib_admin_intr_deferred(ctx); + CTX_UNLOCK(ctx); } static void @@ -2309,10 +2162,8 @@ iflib_init_locked(if_ctx_t ctx) iflib_fl_t fl; iflib_txq_t txq; iflib_rxq_t rxq; - int i, j, tx_ip_csum_flags, tx_ip6_csum_flags, running, reset; + int i, j, tx_ip_csum_flags, tx_ip6_csum_flags; - running = !!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING); - reset = !!(ctx->ifc_flags & IFC_DO_RESET); if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); IFDI_INTR_DISABLE(ctx); @@ -2341,8 +2192,6 @@ iflib_init_locked(if_ctx_t ctx) #endif IFDI_INIT(ctx); MPASS(if_getdrvflags(ifp) == i); - if (!running && reset) - return; for (i = 0, rxq = ctx->ifc_rxqs; i < sctx->isc_nrxqsets; i++, rxq++) { /* XXX this should really be done on a per-queue basis */ if (if_getcapenable(ifp) & IFCAP_NETMAP) { @@ -2362,11 +2211,10 @@ iflib_init_locked(if_ctx_t ctx) IFDI_INTR_ENABLE(ctx); txq = ctx->ifc_txqs; for (i = 0; i < sctx->isc_ntxqsets; i++, txq++) - callout_reset_on(&txq->ift_timer, iflib_timer_int, iflib_timer, - txq, txq->ift_timer.c_cpu); + callout_reset_on(&txq->ift_timer, hz/2, iflib_timer, txq, + txq->ift_timer.c_cpu); } -/* CONFIG context only */ static int iflib_media_change(if_t ifp) { @@ -2380,19 +2228,17 @@ iflib_media_change(if_t ifp) return (err); } -/* CONFIG context only */ static void iflib_media_status(if_t ifp, struct ifmediareq *ifmr) { if_ctx_t ctx = if_getsoftc(ifp); - iflib_admin_intr_deferred(ctx); CTX_LOCK(ctx); + IFDI_UPDATE_ADMIN_STATUS(ctx); IFDI_MEDIA_STATUS(ctx, ifmr); CTX_UNLOCK(ctx); } -/* CONFIG context only */ static void iflib_stop(if_ctx_t ctx) { @@ -2407,7 +2253,9 @@ iflib_stop(if_ctx_t ctx) if_setdrvflagbits(ctx->ifc_ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); IFDI_INTR_DISABLE(ctx); + DELAY(1000); IFDI_STOP(ctx); + DELAY(1000); iflib_debug_reset(); /* Wait for current tx queue users to exit to disarm watchdog timer. */ @@ -2420,13 +2268,11 @@ iflib_stop(if_ctx_t ctx) for (j = 0; j < txq->ift_size; j++) { iflib_txsd_free(ctx, txq, j); } - /* XXX please rewrite to simply bzero this range */ - txq->ift_processed = txq->ift_cleaned = txq->ift_cleaned_prev = 0; - txq->ift_stall_count = txq->ift_cidx_processed = 0; - txq->ift_in_use = txq->ift_gen = txq->ift_cidx = txq->ift_pidx = 0; + txq->ift_processed = txq->ift_cleaned = txq->ift_cidx_processed = 0; + txq->ift_in_use = txq->ift_gen = txq->ift_cidx = txq->ift_pidx = txq->ift_no_desc_avail = 0; txq->ift_closed = txq->ift_mbuf_defrag = txq->ift_mbuf_defrag_failed = 0; txq->ift_no_tx_dma_setup = txq->ift_txd_encap_efbig = txq->ift_map_failed = 0; - txq->ift_no_desc_avail = txq->ift_pullups = 0; + txq->ift_pullups = 0; ifmp_ring_reset_stats(txq->ift_br); for (j = 0, di = txq->ift_ifdi; j < ctx->ifc_nhwtxqs; j++, di++) bzero((void *)di->idi_vaddr, di->idi_size); @@ -2569,9 +2415,6 @@ assemble_segments(iflib_rxq_t rxq, if_rxd_info_t ri, if_rxsd_t sd) } cl = *sd->ifsd_cl; *sd->ifsd_cl = NULL; -#if MEMORY_LOGGING - sd->ifsd_fl->ifl_cl_dequeued++; -#endif /* Can these two be made one ? */ m_init(m, M_NOWAIT, MT_DATA, flags); @@ -2623,6 +2466,51 @@ iflib_rxd_pkt_get(iflib_rxq_t rxq, if_rxd_info_t ri) return (m); } +#if defined(INET6) || defined(INET) +/* + * Returns true if it's possible this packet could be LROed. + * if it returns false, it is guaranteed that tcp_lro_rx() + * would not return zero. + */ +static bool +iflib_check_lro_possible(struct lro_ctrl *lc, struct mbuf *m) +{ + struct ether_header *eh; + uint16_t eh_type; + + eh = mtod(m, struct ether_header *); + eh_type = ntohs(eh->ether_type); + switch (eh_type) { +#if defined(INET6) + case ETHERTYPE_IPV6: + { + CURVNET_SET(lc->ifp->if_vnet); + if (VNET(ip6_forwarding) == 0) { + CURVNET_RESTORE(); + return true; + } + CURVNET_RESTORE(); + break; + } +#endif +#if defined (INET) + case ETHERTYPE_IP: + { + CURVNET_SET(lc->ifp->if_vnet); + if (VNET(ipforwarding) == 0) { + CURVNET_RESTORE(); + return true; + } + CURVNET_RESTORE(); + break; + } +#endif + } + + return false; +} +#endif + static bool iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) { @@ -2636,6 +2524,7 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) iflib_fl_t fl; struct ifnet *ifp; int lro_enabled; + bool lro_possible = false; /* * XXX early demux data packets so that if_input processing only handles @@ -2646,7 +2535,7 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) ifp = ctx->ifc_ifp; mh = mt = NULL; MPASS(budget > 0); - rx_pkts = rx_bytes = 0; + rx_pkts = rx_bytes = 0; if (sctx->isc_flags & IFLIB_HAS_RXCQ) cidxp = &rxq->ifr_cq_cidx; else @@ -2709,14 +2598,12 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) } /* make sure that we can refill faster than drain */ for (i = 0, fl = &rxq->ifr_fl[0]; i < sctx->isc_nfl; i++, fl++) - __iflib_fl_refill_lt(ctx, fl, 2*budget + 8); + __iflib_fl_refill_lt(ctx, fl, budget + 8); lro_enabled = (if_getcapenable(ifp) & IFCAP_LRO); mt = mf = NULL; while (mh != NULL) { m = mh; - if (mf == NULL) - mf = m; mh = mh->m_nextpkt; m->m_nextpkt = NULL; #ifndef __NO_STRICT_ALIGNMENT @@ -2726,12 +2613,27 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) rx_bytes += m->m_pkthdr.len; rx_pkts++; #if defined(INET6) || defined(INET) - if (lro_enabled && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0) { - if (mf == m) - mf = NULL; - continue; + if (lro_enabled) { + if (!lro_possible) { + lro_possible = iflib_check_lro_possible(&rxq->ifr_lc, m); + if (lro_possible && mf != NULL) { + ifp->if_input(ifp, mf); + DBG_COUNTER_INC(rx_if_input); + mt = mf = NULL; + } + } + if (lro_possible && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0) + continue; } #endif + if (lro_possible) { + ifp->if_input(ifp, m); + DBG_COUNTER_INC(rx_if_input); + continue; + } + + if (mf == NULL) + mf = m; if (mt != NULL) mt->m_nextpkt = m; mt = m; @@ -2741,10 +2643,8 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) DBG_COUNTER_INC(rx_if_input); } - if (rx_pkts) { - if_inc_counter(ifp, IFCOUNTER_IBYTES, rx_bytes); - if_inc_counter(ifp, IFCOUNTER_IPACKETS, rx_pkts); - } + if_inc_counter(ifp, IFCOUNTER_IBYTES, rx_bytes); + if_inc_counter(ifp, IFCOUNTER_IPACKETS, rx_pkts); /* * Flush any outstanding LRO work @@ -2752,9 +2652,14 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) #if defined(INET6) || defined(INET) tcp_lro_flush_all(&rxq->ifr_lc); #endif - return (avail || iflib_rxd_avail(ctx, rxq, *cidxp, 1)); + if (avail) + return true; + return (iflib_rxd_avail(ctx, rxq, *cidxp, 1)); err: - iflib_admin_reset_deferred(ctx); + CTX_LOCK(ctx); + ctx->ifc_flags |= IFC_DO_RESET; + iflib_admin_intr_deferred(ctx); + CTX_UNLOCK(ctx); return (false); } @@ -2841,19 +2746,20 @@ print_pkt(if_pkt_info_t pi) static int iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) { - if_ctx_t ctx = txq->ift_ctx; -#ifdef INET - if_shared_ctx_t sctx = ctx->ifc_sctx; -#endif - if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; + if_shared_ctx_t sctx = txq->ift_ctx->ifc_sctx; struct ether_vlan_header *eh; struct mbuf *m, *n; - int err; - if (scctx->isc_txrx->ift_txd_errata && - (err = scctx->isc_txrx->ift_txd_errata(ctx->ifc_softc, mp))) - return (err); n = m = *mp; + if ((sctx->isc_flags & IFLIB_NEED_SCRATCH) && + M_WRITABLE(m) == 0) { + if ((m = m_dup(m, M_NOWAIT)) == NULL) { + return (ENOMEM); + } else { + m_freem(*mp); + n = *mp = m; + } + } /* * Determine where frame payload starts. @@ -2874,10 +2780,6 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) pi->ipi_ehdrlen = ETHER_HDR_LEN; } - if (if_getmtu(txq->ift_ctx->ifc_ifp) >= pi->ipi_len) { - pi->ipi_csum_flags &= ~(CSUM_IP_TSO|CSUM_IP6_TSO); - } - switch (pi->ipi_etype) { #ifdef INET case ETHERTYPE_IP: @@ -3084,9 +2986,9 @@ iflib_busdma_load_mbuf_sg(iflib_txq_t txq, bus_dma_tag_t tag, bus_dmamap_t map, ifsd_m = txq->ift_sds.ifsd_m; ntxd = txq->ift_size; pidx = txq->ift_pidx; - MPASS(ifsd_m[pidx] == NULL); - if (force_busdma || map != NULL) { + if (map != NULL) { uint8_t *ifsd_flags = txq->ift_sds.ifsd_flags; + err = bus_dmamap_load_mbuf_sg(tag, map, *m0, segs, nsegs, BUS_DMA_NOWAIT); if (err) @@ -3239,8 +3141,7 @@ iflib_encap(iflib_txq_t txq, struct mbuf **m_headp) next = (cidx + CACHE_LINE_SIZE) & (ntxd-1); prefetch(&txq->ift_sds.ifsd_flags[next]); } - } - if (txq->ift_sds.ifsd_map != NULL) + } else if (txq->ift_sds.ifsd_map != NULL) map = txq->ift_sds.ifsd_map[pidx]; if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { @@ -3265,7 +3166,6 @@ iflib_encap(iflib_txq_t txq, struct mbuf **m_headp) if (__predict_false((err = iflib_parse_header(txq, &pi, m_headp)) != 0)) return (err); m_head = *m_headp; - pi.ipi_hdr_data = mtod(m_head, caddr_t); } retry: @@ -3442,7 +3342,6 @@ iflib_tx_desc_free(iflib_txq_t txq, int n) gen = 0; } } - txq_validate(txq); txq->ift_cidx = cidx; txq->ift_gen = gen; } @@ -3492,10 +3391,10 @@ _ring_peek_one(struct ifmp_ring *r, int cidx, int offset, int remaining) prefetch(items[(cidx + offset) & (size-1)]); if (remaining > 1) { - prefetch2(&items[next]); - prefetch2(items[(cidx + offset + 1) & (size-1)]); - prefetch2(items[(cidx + offset + 2) & (size-1)]); - prefetch2(items[(cidx + offset + 3) & (size-1)]); + prefetch2cachelines(&items[next]); + prefetch2cachelines(items[(cidx + offset + 1) & (size-1)]); + prefetch2cachelines(items[(cidx + offset + 2) & (size-1)]); + prefetch2cachelines(items[(cidx + offset + 3) & (size-1)]); } return (__DEVOLATILE(struct mbuf **, &r->items[(cidx + offset) & (size-1)])); } @@ -3735,44 +3634,43 @@ _task_fn_rx(void *context) GROUPTASK_ENQUEUE(&rxq->ifr_task); } -/* CONFIG context only */ static void _task_fn_admin(void *context) { if_ctx_t ctx = context; if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; iflib_txq_t txq; - int i, running; + int i; + + if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) { + if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_OACTIVE)) { + return; + } + } CTX_LOCK(ctx); - running = !!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING); - for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) { CALLOUT_LOCK(txq); callout_stop(&txq->ift_timer); CALLOUT_UNLOCK(txq); } - if (running) { - for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) - callout_reset_on(&txq->ift_timer, iflib_timer_int, iflib_timer, - txq, txq->ift_timer.c_cpu); - IFDI_LINK_INTR_ENABLE(ctx); - } - if (ctx->ifc_flags & IFC_DO_RESET) { - iflib_if_init_locked(ctx); - ctx->ifc_flags &= ~IFC_DO_RESET; - } IFDI_UPDATE_ADMIN_STATUS(ctx); + for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) + callout_reset_on(&txq->ift_timer, hz/2, iflib_timer, txq, txq->ift_timer.c_cpu); + IFDI_LINK_INTR_ENABLE(ctx); + if (ctx->ifc_flags & IFC_DO_RESET) { + ctx->ifc_flags &= ~IFC_DO_RESET; + iflib_if_init_locked(ctx); + } CTX_UNLOCK(ctx); - if (LINK_ACTIVE(ctx) == 0 || !running) + if (LINK_ACTIVE(ctx) == 0) return; for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) iflib_txq_check_drain(txq, IFLIB_RESTART_BUDGET); } -/* CONFIG context only */ static void _task_fn_iov(void *context) { @@ -3900,7 +3798,6 @@ iflib_if_transmit(if_t ifp, struct mbuf *m) return (err); } -/* CONFIG context only */ static void iflib_if_qflush(if_t ifp) { @@ -3984,12 +3881,29 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) CTX_UNLOCK(ctx); break; case SIOCSIFFLAGS: - err = async_if_ioctl(ctx, command, data); + CTX_LOCK(ctx); + if (if_getflags(ifp) & IFF_UP) { + if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { + if ((if_getflags(ifp) ^ ctx->ifc_if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) { + err = IFDI_PROMISC_SET(ctx, if_getflags(ifp)); + } + } else + reinit = 1; + } else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { + iflib_stop(ctx); + } + ctx->ifc_if_flags = if_getflags(ifp); + CTX_UNLOCK(ctx); break; case SIOCADDMULTI: case SIOCDELMULTI: if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { - err = async_if_ioctl(ctx, command, data); + CTX_LOCK(ctx); + IFDI_INTR_DISABLE(ctx); + IFDI_MULTI_SET(ctx); + IFDI_INTR_ENABLE(ctx); + CTX_UNLOCK(ctx); } break; case SIOCSIFMEDIA: @@ -4083,7 +3997,6 @@ iflib_if_get_counter(if_t ifp, ift_counter cnt) * **********************************************************************/ -/* CONFIG context only */ static void iflib_vlan_register(void *arg, if_t ifp, uint16_t vtag) { @@ -4103,7 +4016,6 @@ iflib_vlan_register(void *arg, if_t ifp, uint16_t vtag) CTX_UNLOCK(ctx); } -/* CONFIG context only */ static void iflib_vlan_unregister(void *arg, if_t ifp, uint16_t vtag) { @@ -4123,7 +4035,6 @@ iflib_vlan_unregister(void *arg, if_t ifp, uint16_t vtag) CTX_UNLOCK(ctx); } -/* CONFIG context only */ static void iflib_led_func(void *arg, int onoff) { @@ -4268,10 +4179,8 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct scctx->isc_ntxd[i] = sctx->isc_ntxd_max[i]; } } - CTX_LOCK(ctx); - err = IFDI_ATTACH_PRE(ctx); - CTX_UNLOCK(ctx); - if (err) { + + if ((err = IFDI_ATTACH_PRE(ctx)) != 0) { device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err); return (err); } @@ -4299,8 +4208,6 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct /* set unconditionally for !x86 */ ctx->ifc_flags |= IFC_DMAR; #endif - if (force_busdma) - ctx->ifc_flags |= IFC_DMAR; msix_bar = scctx->isc_msix_bar; main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; @@ -4313,7 +4220,6 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct if (!powerof2(scctx->isc_nrxd[i])) { /* round down instead? */ device_printf(dev, "# rx descriptors must be a power of 2\n"); - err = EINVAL; goto fail; } @@ -4352,7 +4258,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct GROUPTASK_INIT(&ctx->ifc_admin_task, 0, _task_fn_admin, ctx); /* XXX format name */ - taskqgroup_attach(qgroup_if_config, &ctx->ifc_admin_task, ctx, -1, "admin"); + taskqgroup_attach(qgroup_if_config_tqg, &ctx->ifc_admin_task, ctx, -1, "admin"); /* ** Now setup MSI or MSI/X, should ** return us the number of supported @@ -4411,10 +4317,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct } } ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac); - CTX_LOCK(ctx); - err = IFDI_ATTACH_POST(ctx); - CTX_UNLOCK(ctx); - if (err) { + if ((err = IFDI_ATTACH_POST(ctx)) != 0) { device_printf(dev, "IFDI_ATTACH_POST failed %d\n", err); goto fail_detach; } @@ -4426,7 +4329,6 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct if_setgetcounterfn(ctx->ifc_ifp, iflib_if_get_counter); iflib_add_device_sysctl_post(ctx); - iflib_ctx_insert(ctx); ctx->ifc_flags |= IFC_INIT_DONE; return (0); fail_detach: @@ -4437,9 +4339,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct fail_queues: /* XXX free queues */ fail: - CTX_LOCK(ctx); IFDI_DETACH(ctx); - CTX_UNLOCK(ctx); return (err); } @@ -4487,10 +4387,12 @@ iflib_device_deregister(if_ctx_t ctx) iflib_netmap_detach(ifp); ether_ifdetach(ifp); + /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/ + CTX_LOCK_DESTROY(ctx); if (ctx->ifc_led_dev != NULL) led_destroy(ctx->ifc_led_dev); /* XXX drain any dependent tasks */ - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) { callout_drain(&txq->ift_timer); if (txq->ift_task.gt_uniq != NULL) @@ -4504,16 +4406,13 @@ iflib_device_deregister(if_ctx_t ctx) free(fl->ifl_rx_bitmap, M_IFLIB); } - tqg = qgroup_if_config; + tqg = qgroup_if_config_tqg; if (ctx->ifc_admin_task.gt_uniq != NULL) taskqgroup_detach(tqg, &ctx->ifc_admin_task); if (ctx->ifc_vflr_task.gt_uniq != NULL) taskqgroup_detach(tqg, &ctx->ifc_vflr_task); - CTX_LOCK(ctx); IFDI_DETACH(ctx); - CTX_UNLOCK(ctx); - CTX_LOCK_DESTROY(ctx); device_set_softc(ctx->ifc_dev, NULL); if (ctx->ifc_softc_ctx.isc_intr != IFLIB_INTR_LEGACY) { pci_release_msi(dev); @@ -4534,7 +4433,6 @@ iflib_device_deregister(if_ctx_t ctx) iflib_rx_structures_free(ctx); if (ctx->ifc_flags & IFC_SC_ALLOCATED) free(ctx->ifc_softc, M_IFLIB); - iflib_ctx_remove(ctx); free(ctx, M_IFLIB); return (0); } @@ -4630,14 +4528,13 @@ iflib_device_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) * **********************************************************************/ +/* + * - Start a fast taskqueue thread for each core + * - Start a taskqueue for control operations + */ static int iflib_module_init(void) { - - iflib_timer_int = hz / 2; - TUNABLE_INT_FETCH("net.iflib.timer_int", &iflib_timer_int); - LIST_INIT(&ctx_list); - mtx_init(&ctx_list_lock, "ctx list", NULL, MTX_DEF); return (0); } @@ -5081,124 +4978,25 @@ iflib_irq_alloc(if_ctx_t ctx, if_irq_t irq, int rid, return (_iflib_irq_alloc(ctx, irq, rid, filter, handler, arg, name)); } -#ifdef SMP static int -find_nth(if_ctx_t ctx, int qid) +find_nth(if_ctx_t ctx, cpuset_t *cpus, int qid) { - cpuset_t cpus; int i, cpuid, eqid, count; - CPU_COPY(&ctx->ifc_cpus, &cpus); + CPU_COPY(&ctx->ifc_cpus, cpus); count = CPU_COUNT(&ctx->ifc_cpus); eqid = qid % count; /* clear up to the qid'th bit */ for (i = 0; i < eqid; i++) { - cpuid = CPU_FFS(&cpus); + cpuid = CPU_FFS(cpus); MPASS(cpuid != 0); - CPU_CLR(cpuid-1, &cpus); + CPU_CLR(cpuid-1, cpus); } - cpuid = CPU_FFS(&cpus); + cpuid = CPU_FFS(cpus); MPASS(cpuid != 0); return (cpuid-1); } -static int -find_child_with_core(int cpu, struct cpu_group *grp) -{ - int i; - - if (grp->cg_children == 0) - return -1; - - MPASS(grp->cg_child); - for (i = 0; i < grp->cg_children; i++) { - if (CPU_ISSET(cpu, &grp->cg_child[i].cg_mask)) - return i; - } - - return -1; -} - -/* - * Find the nth thread on the specified core - */ -static int -find_thread(int cpu, int thread_num) -{ - struct cpu_group *grp; - int i; - cpuset_t cs; - - grp = smp_topo(); - if (grp == NULL) - return cpu; - i = 0; - while ((i = find_child_with_core(cpu, grp)) != -1) { - /* If the child only has one cpu, don't descend */ - if (grp->cg_child[i].cg_count <= 1) - break; - grp = &grp->cg_child[i]; - } - - /* If they don't share at least an L2 cache, use the same CPU */ - if (grp->cg_level > CG_SHARE_L2 || grp->cg_level == CG_SHARE_NONE) - return cpu; - - /* Now pick one */ - CPU_COPY(&grp->cg_mask, &cs); - for (i = thread_num % grp->cg_count; i > 0; i--) { - MPASS(CPU_FFS(&cs)); - CPU_CLR(CPU_FFS(&cs) - 1, &cs); - } - MPASS(CPU_FFS(&cs)); - return CPU_FFS(&cs) - 1; -} - -static int -get_thread_num(if_ctx_t ctx, iflib_intr_type_t type, int qid) -{ - switch (type) { - case IFLIB_INTR_TX: - /* TX queues get threads on the same core as the corresponding RX queue */ - /* XXX handle multiple RX threads per core and more than two threads per core */ - return qid / CPU_COUNT(&ctx->ifc_cpus) + 1; - case IFLIB_INTR_RX: - case IFLIB_INTR_RXTX: - /* RX queues get the first thread on their core */ - return qid / CPU_COUNT(&ctx->ifc_cpus); - default: - return -1; - } -} -#else -#define get_thread_num(ctx, type, qid) 0 -#define find_thread(cpuid, tid) 0 -#define find_nth(ctx, gid) 0 -#endif - -/* Just to avoid copy/paste */ -static inline int -iflib_irq_set_affinity(if_ctx_t ctx, int irq, iflib_intr_type_t type, int qid, - struct grouptask *gtask, struct taskqgroup *tqg, void *uniq, char *name) -{ - int cpuid; - int err, tid; - - cpuid = find_nth(ctx, qid); - tid = get_thread_num(ctx, type, qid); - MPASS(tid >= 0); - cpuid = find_thread(cpuid, tid); - err = taskqgroup_attach_cpu(tqg, gtask, uniq, cpuid, irq, name); - if (err) { - device_printf(ctx->ifc_dev, "taskqgroup_attach_cpu failed %d\n", err); - return (err); - } - if (cpuid > ctx->ifc_cpuid_highest) - ctx->ifc_cpuid_highest = cpuid; - MPASS(gtask->gt_taskqueue != NULL); - return 0; -} - int iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, iflib_intr_type_t type, driver_filter_t *filter, @@ -5207,8 +5005,9 @@ iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, struct grouptask *gtask; struct taskqgroup *tqg; iflib_filter_info_t info; + cpuset_t cpus; gtask_fn_t *fn; - int tqrid, err; + int tqrid, err, cpuid; driver_filter_t *intr_fast; void *q; @@ -5221,7 +5020,7 @@ iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, q = &ctx->ifc_txqs[qid]; info = &ctx->ifc_txqs[qid].ift_filter_info; gtask = &ctx->ifc_txqs[qid].ift_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; fn = _task_fn_tx; intr_fast = iflib_fast_intr; GROUPTASK_INIT(gtask, 0, fn, q); @@ -5230,16 +5029,16 @@ iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, q = &ctx->ifc_rxqs[qid]; info = &ctx->ifc_rxqs[qid].ifr_filter_info; gtask = &ctx->ifc_rxqs[qid].ifr_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; fn = _task_fn_rx; - intr_fast = iflib_fast_intr_rx; + intr_fast = iflib_fast_intr; GROUPTASK_INIT(gtask, 0, fn, q); break; case IFLIB_INTR_RXTX: q = &ctx->ifc_rxqs[qid]; info = &ctx->ifc_rxqs[qid].ifr_filter_info; gtask = &ctx->ifc_rxqs[qid].ifr_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; fn = _task_fn_rx; intr_fast = iflib_fast_intr_rxtx; GROUPTASK_INIT(gtask, 0, fn, q); @@ -5249,7 +5048,7 @@ iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, tqrid = -1; info = &ctx->ifc_filter_info; gtask = &ctx->ifc_admin_task; - tqg = qgroup_if_config; + tqg = qgroup_if_config_tqg; fn = _task_fn_admin; intr_fast = iflib_fast_intr_ctx; break; @@ -5271,57 +5070,52 @@ iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, return (0); if (tqrid != -1) { - err = iflib_irq_set_affinity(ctx, rman_get_start(irq->ii_res), type, qid, gtask, tqg, q, name); - if (err) - return (err); + cpuid = find_nth(ctx, &cpus, qid); + taskqgroup_attach_cpu(tqg, gtask, q, cpuid, rman_get_start(irq->ii_res), name); } else { - taskqgroup_attach(tqg, gtask, q, tqrid, name); + taskqgroup_attach(tqg, gtask, q, rman_get_start(irq->ii_res), name); } return (0); } void -iflib_softirq_alloc_generic(if_ctx_t ctx, int rid, iflib_intr_type_t type, void *arg, int qid, char *name) +iflib_softirq_alloc_generic(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type, void *arg, int qid, char *name) { struct grouptask *gtask; struct taskqgroup *tqg; gtask_fn_t *fn; void *q; - int err; + int irq_num = -1; switch (type) { case IFLIB_INTR_TX: q = &ctx->ifc_txqs[qid]; gtask = &ctx->ifc_txqs[qid].ift_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; fn = _task_fn_tx; + if (irq != NULL) + irq_num = rman_get_start(irq->ii_res); break; case IFLIB_INTR_RX: q = &ctx->ifc_rxqs[qid]; gtask = &ctx->ifc_rxqs[qid].ifr_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; fn = _task_fn_rx; + if (irq != NULL) + irq_num = rman_get_start(irq->ii_res); break; case IFLIB_INTR_IOV: q = ctx; gtask = &ctx->ifc_vflr_task; - tqg = qgroup_if_config; - rid = -1; + tqg = qgroup_if_config_tqg; fn = _task_fn_iov; break; default: panic("unknown net intr type"); } GROUPTASK_INIT(gtask, 0, fn, q); - if (rid != -1) { - err = iflib_irq_set_affinity(ctx, rid, type, qid, gtask, tqg, q, name); - if (err) - taskqgroup_attach(tqg, gtask, q, rid, name); - } - else { - taskqgroup_attach(tqg, gtask, q, rid, name); - } + taskqgroup_attach(tqg, gtask, q, irq_num, name); } void @@ -5351,7 +5145,7 @@ iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filter_arg, int * q = &ctx->ifc_rxqs[0]; info = &rxq[0].ifr_filter_info; gtask = &rxq[0].ifr_task; - tqg = qgroup_if_io; + tqg = qgroup_if_io_tqg; tqrid = irq->ii_rid = *rid; fn = _task_fn_rx; @@ -5368,7 +5162,7 @@ iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filter_arg, int * taskqgroup_attach(tqg, gtask, q, tqrid, name); GROUPTASK_INIT(&txq->ift_task, 0, _task_fn_tx, txq); - taskqgroup_attach(qgroup_if_io, &txq->ift_task, txq, tqrid, "tx"); + taskqgroup_attach(qgroup_if_io_tqg, &txq->ift_task, txq, tqrid, "tx"); return (0); } @@ -5407,22 +5201,6 @@ iflib_admin_intr_deferred(if_ctx_t ctx) GROUPTASK_ENQUEUE(&ctx->ifc_admin_task); } -/* CONFIG context only */ -static void -iflib_handle_reset(if_ctx_t ctx, void *arg) -{ - CTX_LOCK(ctx); - ctx->ifc_flags |= IFC_DO_RESET; - iflib_admin_intr_deferred(ctx); - CTX_UNLOCK(ctx); -} - -static void -iflib_admin_reset_deferred(if_ctx_t ctx) -{ - iflib_config_async_gtask_dispatch(ctx, iflib_handle_reset, "reset handler", NULL); -} - void iflib_iov_intr_deferred(if_ctx_t ctx) { @@ -5434,7 +5212,7 @@ void iflib_io_tqg_attach(struct grouptask *gt, void *uniq, int cpu, char *name) { - taskqgroup_attach_cpu(qgroup_if_io, gt, uniq, cpu, -1, name); + taskqgroup_attach_cpu(qgroup_if_io_tqg, gt, uniq, cpu, -1, name); } void @@ -5443,104 +5221,14 @@ iflib_config_gtask_init(if_ctx_t ctx, struct grouptask *gtask, gtask_fn_t *fn, { GROUPTASK_INIT(gtask, 0, fn, ctx); - taskqgroup_attach(qgroup_if_config, gtask, gtask, -1, name); + taskqgroup_attach(qgroup_if_config_tqg, gtask, gtask, -1, name); } -static void -iflib_multi_set(if_ctx_t ctx, void *arg) -{ - CTX_LOCK(ctx); - IFDI_INTR_DISABLE(ctx); - IFDI_MULTI_SET(ctx); - IFDI_INTR_ENABLE(ctx); - CTX_UNLOCK(ctx); -} - -static void -iflib_flags_set(if_ctx_t ctx, void *arg) -{ - int reinit, err; - if_t ifp = ctx->ifc_ifp; - - err = reinit = 0; - CTX_LOCK(ctx); - if (if_getflags(ifp) & IFF_UP) { - if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { - if ((if_getflags(ifp) ^ ctx->ifc_if_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) { - err = IFDI_PROMISC_SET(ctx, if_getflags(ifp)); - } - } else - reinit = 1; - } else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { - iflib_stop(ctx); - } - ctx->ifc_if_flags = if_getflags(ifp); - if (reinit) - iflib_if_init_locked(ctx); - CTX_UNLOCK(ctx); - if (err) - log(LOG_WARNING, "IFDI_PROMISC_SET returned %d\n", err); -} - -static void -async_gtask(void *ctx) -{ - struct async_task_arg *at_arg = ctx; - if_ctx_t if_ctx = at_arg->ata_ctx; - void *arg = at_arg->ata_arg; - - at_arg->ata_fn(if_ctx, arg); - taskqgroup_detach(qgroup_if_config, at_arg->ata_gtask); - free(at_arg->ata_gtask, M_IFLIB); -} - -static int -iflib_config_async_gtask_dispatch(if_ctx_t ctx, async_gtask_fn_t *fn, char *name, void *arg) -{ - struct grouptask *gtask; - struct async_task_arg *at_arg; - - if ((gtask = malloc(sizeof(struct grouptask) + sizeof(struct async_task_arg), M_IFLIB, M_NOWAIT|M_ZERO)) == NULL) - return (ENOMEM); - - at_arg = (struct async_task_arg *)(gtask + 1); - at_arg->ata_fn = fn; - at_arg->ata_ctx = ctx; - at_arg->ata_arg = arg; - at_arg->ata_gtask = gtask; - - GROUPTASK_INIT(gtask, 0, async_gtask, at_arg); - taskqgroup_attach(qgroup_if_config, gtask, gtask, -1, name); - GROUPTASK_ENQUEUE(gtask); - return (0); -} - -static int -async_if_ioctl(if_ctx_t ctx, u_long command, caddr_t data) -{ - int rc; - - switch (command) { - case SIOCADDMULTI: - case SIOCDELMULTI: - rc = iflib_config_async_gtask_dispatch(ctx, iflib_multi_set, "async_if_multi", NULL); - break; - case SIOCSIFFLAGS: - rc = iflib_config_async_gtask_dispatch(ctx, iflib_flags_set, "async_if_flags", NULL); - break; - default: - panic("unknown command %lx", command); - } - return (rc); -} - - void iflib_config_gtask_deinit(struct grouptask *gtask) { - taskqgroup_detach(qgroup_if_config, gtask); + taskqgroup_detach(qgroup_if_config_tqg, gtask); } void @@ -5607,11 +5295,11 @@ iflib_add_int_delay_sysctl(if_ctx_t ctx, const char *name, info, 0, iflib_sysctl_int_delay, "I", description); } -struct sx * +struct mtx * iflib_ctx_lock_get(if_ctx_t ctx) { - return (&ctx->ifc_sx); + return (&ctx->ifc_mtx); } static int @@ -5631,6 +5319,19 @@ iflib_msix_init(if_ctx_t ctx) bar = ctx->ifc_softc_ctx.isc_msix_bar; admincnt = sctx->isc_admin_intrcnt; + /* Override by global tuneable */ + { + int i; + size_t len = sizeof(i); + err = kernel_sysctlbyname(curthread, "hw.pci.enable_msix", &i, &len, NULL, 0, NULL, 0); + if (err == 0) { + if (i == 0) + goto msi; + } + else { + device_printf(dev, "unable to read hw.pci.enable_msix."); + } + } /* Override by tuneable */ if (scctx->isc_disable_msix) goto msi; @@ -5731,22 +5432,13 @@ iflib_msix_init(if_ctx_t ctx) rx_queues = min(rx_queues, tx_queues); } - device_printf(dev, "trying %d rx queues %d tx queues \n", rx_queues, tx_queues); + device_printf(dev, "using %d rx queues %d tx queues \n", rx_queues, tx_queues); - vectors = tx_queues + rx_queues + admincnt; + vectors = rx_queues + admincnt; if ((err = pci_alloc_msix(dev, &vectors)) == 0) { device_printf(dev, "Using MSIX interrupts with %d vectors\n", vectors); scctx->isc_vectors = vectors; - - if (vectors < tx_queues + rx_queues + admincnt) { - vectors -= admincnt; - if (vectors % 2 != 0) - vectors -= 1; - if (rx_queues > vectors / 2) - rx_queues = vectors / 2; - tx_queues = vectors - rx_queues; - } scctx->isc_nrxqsets = rx_queues; scctx->isc_ntxqsets = tx_queues; scctx->isc_intr = IFLIB_INTR_MSIX; @@ -5897,10 +5589,6 @@ iflib_add_device_sysctl_pre(if_ctx_t ctx) CTLTYPE_STRING|CTLFLAG_RWTUN, ctx, IFLIB_NRXD_HANDLER, mp_ndesc_handler, "A", "list of # of rx descriptors to use, 0 = use default #"); - - SYSCTL_ADD_INT(ctx_list, oid_list, OID_AUTO, "watchdog_events", - CTLFLAG_RD, &ctx->ifc_watchdog_events, 0, - "Watchdog events seen since load"); } static void diff --git a/sys/net/iflib.h b/sys/net/iflib.h index 8c7ebb4594aa..70992fdde39f 100644 --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -119,7 +119,6 @@ typedef struct if_pkt_info { qidx_t ipi_pidx; /* start pidx for encap */ qidx_t ipi_new_pidx; /* next available pidx post-encap */ /* offload handling */ - caddr_t ipi_hdr_data; /* raw header */ uint8_t ipi_ehdrlen; /* ether header length */ uint8_t ipi_ip_hlen; /* ip header length */ uint8_t ipi_tcp_hlen; /* tcp header length */ @@ -174,6 +173,11 @@ typedef struct pci_vendor_info { #define PVID_OEM(vendor, devid, svid, sdevid, revid, name) {vendor, devid, svid, sdevid, revid, 0, name} #define PVID_END {0, 0, 0, 0, 0, 0, NULL} +#define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \ + "U32:revision;U32:class;D:human" +#define IFLIB_PNP_INFO(b, u, t) \ + MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t)) + typedef struct if_txrx { int (*ift_txd_encap) (void *, if_pkt_info_t); void (*ift_txd_flush) (void *, uint16_t, qidx_t pidx); @@ -184,7 +188,6 @@ typedef struct if_txrx { void (*ift_rxd_refill) (void * , if_rxd_update_t iru); void (*ift_rxd_flush) (void *, uint16_t qsidx, uint8_t flidx, qidx_t pidx); int (*ift_legacy_intr) (void *); - int (*ift_txd_errata) (void *, struct mbuf **mp); } *if_txrx_t; typedef struct if_softc_ctx { @@ -296,9 +299,9 @@ typedef enum { */ #define IFLIB_HAS_TXCQ 0x08 /* - * + * Interface does checksum in place */ -#define IFLIB_UNUSED___0 0x10 +#define IFLIB_NEED_SCRATCH 0x10 /* * Interface doesn't expect in_pseudo for th_sum */ @@ -358,7 +361,7 @@ int iflib_irq_alloc(if_ctx_t, if_irq_t, int, driver_filter_t, void *filter_arg, int iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid, iflib_intr_type_t type, driver_filter_t *filter, void *filter_arg, int qid, char *name); -void iflib_softirq_alloc_generic(if_ctx_t ctx, int rid, iflib_intr_type_t type, void *arg, int qid, char *name); +void iflib_softirq_alloc_generic(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type, void *arg, int qid, char *name); void iflib_irq_free(if_ctx_t ctx, if_irq_t irq); @@ -387,7 +390,7 @@ int iflib_dma_alloc_multi(if_ctx_t ctx, int *sizes, iflib_dma_info_t *dmalist, i void iflib_dma_free_multi(iflib_dma_info_t *dmalist, int count); -struct sx *iflib_ctx_lock_get(if_ctx_t); +struct mtx *iflib_ctx_lock_get(if_ctx_t); struct mtx *iflib_qset_lock_get(if_ctx_t, uint16_t); void iflib_led_create(if_ctx_t ctx); diff --git a/sys/net/mp_ring.c b/sys/net/mp_ring.c index e2e94e9087c8..d7878f6d480b 100644 --- a/sys/net/mp_ring.c +++ b/sys/net/mp_ring.c @@ -226,15 +226,11 @@ drain_ring_lockless(struct ifmp_ring *r, union ring_state os, uint16_t prev, int if (cidx != pidx && pending < 64 && total < budget) continue; critical_enter(); - os.state = ns.state = r->state; - ns.cidx = cidx; - ns.flags = state_to_flags(ns, total >= budget); - while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0) { - cpu_spinwait(); + do { os.state = ns.state = r->state; ns.cidx = cidx; ns.flags = state_to_flags(ns, total >= budget); - } + } while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0); critical_exit(); if (ns.flags == ABDICATED) diff --git a/sys/net/rss_config.c b/sys/net/rss_config.c index 9597614c210c..0fc62c740a06 100644 --- a/sys/net/rss_config.c +++ b/sys/net/rss_config.c @@ -489,7 +489,6 @@ rss_gethashconfig(void) | RSS_HASHTYPE_RSS_TCP_IPV6_EX #if 0 | RSS_HASHTYPE_RSS_UDP_IPV4 - | RSS_HASHTYPE_RSS_UDP_IPV4_EX | RSS_HASHTYPE_RSS_UDP_IPV6 | RSS_HASHTYPE_RSS_UDP_IPV6_EX #endif diff --git a/sys/net/rss_config.h b/sys/net/rss_config.h index 2ab32a43f58b..202dbef50e72 100644 --- a/sys/net/rss_config.h +++ b/sys/net/rss_config.h @@ -66,7 +66,6 @@ #define RSS_HASHTYPE_RSS_IPV6_EX (1 << 5) /* IPv6 2-tuple + ext hdrs */ #define RSS_HASHTYPE_RSS_TCP_IPV6_EX (1 << 6) /* TCPv6 4-tiple + ext hdrs */ #define RSS_HASHTYPE_RSS_UDP_IPV4 (1 << 7) /* IPv4 UDP 4-tuple */ -#define RSS_HASHTYPE_RSS_UDP_IPV4_EX (1 << 8) /* IPv4 UDP 4-tuple + ext hdrs */ #define RSS_HASHTYPE_RSS_UDP_IPV6 (1 << 9) /* IPv6 UDP 4-tuple */ #define RSS_HASHTYPE_RSS_UDP_IPV6_EX (1 << 10) /* IPv6 UDP 4-tuple + ext hdrs */ diff --git a/sys/net/vnet.c b/sys/net/vnet.c index b2cad6302253..eb07efbf4fb3 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -312,9 +312,8 @@ static void vnet0_init(void *arg __unused) { - /* Warn people before take off - in case we crash early. */ - printf("WARNING: VIMAGE (virtualized network stack) is a highly " - "experimental feature.\n"); + if (bootverbose) + printf("VIMAGE (virtualized network stack) enabled\n"); /* * We MUST clear curvnet in vi_init_done() before going SMP, diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h index cff07c68e9ca..9bdf7790d590 100644 --- a/sys/net80211/ieee80211_input.h +++ b/sys/net80211/ieee80211_input.h @@ -131,6 +131,38 @@ ishtinfooui(const uint8_t *frm) return frm[1] > 3 && le32dec(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI); } +static __inline int +ieee80211_check_rxseq_amsdu(const struct ieee80211_rx_stats *rxs) +{ + + return (!! (rxs->c_pktflags & IEEE80211_RX_F_AMSDU)); +} + +/* + * Return 1 if the rxseq check should increment the sequence + * number. Return 0 if it's part of an AMSDU batch and it isn't + * the final frame in the decap'ed burst. + */ +static __inline int +ieee80211_check_rxseq_amsdu_more(const struct ieee80211_rx_stats *rxs) +{ + /* No state? ok */ + if (rxs == NULL) + return (1); + + /* State but no AMSDU set? ok */ + if ((rxs->c_pktflags & IEEE80211_RX_F_AMSDU) == 0) + return (1); + + /* State, AMSDU set, then _MORE means "don't inc yet" */ + if (rxs->c_pktflags & IEEE80211_RX_F_AMSDU_MORE) { + return (0); + } + + /* Both are set, so return ok */ + return (1); +} + /* * Check the current frame sequence number against the current TID * state and return whether it's in sequence or should be dropped. @@ -238,7 +270,20 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh, goto fail; ok: - ni->ni_rxseqs[tid] = rxseq; + /* + * Only bump the sequence number if it's the last frame + * in a batch. That way frames in the rest of the batch + * get included, and the last frame in the batch kicks + * it next. + */ + if (ieee80211_check_rxseq_amsdu_more(rxs)) { + ni->ni_rxseqs[tid] = rxseq; + if ((rxs != NULL) && ieee80211_check_rxseq_amsdu(rxs)) + IEEE80211_NODE_STAT(ni, rx_amsdu_more_end); + } else { + /* .. still waiting */ + IEEE80211_NODE_STAT(ni, rx_amsdu_more); + } return 1; diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index 7d472bc64c8d..a565593e780d 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -84,7 +84,11 @@ struct ieee80211_nodestats { uint32_t ns_tx_deauth_code; /* last deauth reason */ uint32_t ns_tx_disassoc; /* disassociations */ uint32_t ns_tx_disassoc_code; /* last disassociation reason */ - uint32_t ns_spare[8]; + + /* Hardware A-MSDU decode */ + uint32_t ns_rx_amsdu_more; /* RX decap A-MSDU, more coming from A-MSDU */ + uint32_t ns_rx_amsdu_more_end; /* RX decap A-MSDU (or any other frame), no more coming */ + uint32_t ns_spare[6]; }; /* diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index b5f5626a04d1..3079f002f807 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -59,11 +59,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -112,9 +114,15 @@ struct ng_iface_private { int unit; /* Interface unit number */ node_p node; /* Our netgraph node */ hook_p hooks[NUM_FAMILIES]; /* Hook for each address family */ + struct rmlock lock; /* Protect private data changes */ }; typedef struct ng_iface_private *priv_p; +#define PRIV_RLOCK(priv, t) rm_rlock(&priv->lock, t) +#define PRIV_RUNLOCK(priv, t) rm_runlock(&priv->lock, t) +#define PRIV_WLOCK(priv) rm_wlock(&priv->lock) +#define PRIV_WUNLOCK(priv) rm_wunlock(&priv->lock) + /* Interface methods */ static void ng_iface_start(struct ifnet *ifp); static int ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); @@ -431,8 +439,10 @@ ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family) static int ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) { + struct rm_priotracker priv_tracker; const priv_p priv = (priv_p) ifp->if_softc; const iffam_p iffam = get_iffam_from_af(sa); + hook_p hook; int error; int len; @@ -446,10 +456,20 @@ ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) /* Copy length before the mbuf gets invalidated. */ len = m->m_pkthdr.len; - /* Send packet. If hook is not connected, mbuf will get freed. */ + PRIV_RLOCK(priv, &priv_tracker); + hook = *get_hook_from_iffam(priv, iffam); + if (hook == NULL) { + NG_FREE_M(m); + PRIV_RUNLOCK(priv, &priv_tracker); + return ENETDOWN; + } + NG_HOOK_REF(hook); + PRIV_RUNLOCK(priv, &priv_tracker); + NG_OUTBOUND_THREAD_REF(); - NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m); + NG_SEND_DATA_ONLY(error, hook, m); NG_OUTBOUND_THREAD_UNREF(); + NG_HOOK_UNREF(hook); /* Update stats. */ if (error == 0) { @@ -516,6 +536,8 @@ ng_iface_constructor(node_p node) return (ENOMEM); } + rm_init(&priv->lock, "ng_iface private rmlock"); + /* Link them together */ ifp->if_softc = priv; priv->ifp = ifp; @@ -562,16 +584,21 @@ static int ng_iface_newhook(node_p node, hook_p hook, const char *name) { const iffam_p iffam = get_iffam_from_name(name); + const priv_p priv = NG_NODE_PRIVATE(node); hook_p *hookptr; if (iffam == NULL) return (EPFNOSUPPORT); - hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam); - if (*hookptr != NULL) + PRIV_WLOCK(priv); + hookptr = get_hook_from_iffam(priv, iffam); + if (*hookptr != NULL) { + PRIV_WUNLOCK(priv); return (EISCONN); + } *hookptr = hook; NG_HOOK_HI_STACK(hook); NG_HOOK_SET_TO_INBOUND(hook); + PRIV_WUNLOCK(priv); return (0); } @@ -730,6 +757,7 @@ ng_iface_shutdown(node_p node) CURVNET_RESTORE(); priv->ifp = NULL; free_unr(V_ng_iface_unit, priv->unit); + rm_destroy(&priv->lock); free(priv, M_NETGRAPH_IFACE); NG_NODE_SET_PRIVATE(node, NULL); NG_NODE_UNREF(node); @@ -748,7 +776,9 @@ ng_iface_disconnect(hook_p hook) if (iffam == NULL) panic("%s", __func__); + PRIV_WLOCK(priv); *get_hook_from_iffam(priv, iffam) = NULL; + PRIV_WUNLOCK(priv); return (0); } diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index b84df2396082..eb2e455cbe67 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -175,8 +175,8 @@ static int proto_reg[] = {-1, -1}; * Each softc has a lock sc_mtx. It is used to synchronise carp_input_c(), * callout-driven events and ioctl()s. * - * To traverse the list of softcs on an ifnet we use CIF_LOCK(), to - * traverse the global list we use the mutex carp_mtx. + * To traverse the list of softcs on an ifnet we use CIF_LOCK() or carp_sx. + * To traverse the global list we use the mutex carp_mtx. * * Known issues with locking: * @@ -286,7 +286,8 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_carp, OID_AUTO, stats, struct carpstats, ++_i) #define IFNET_FOREACH_CARP(ifp, sc) \ - CIF_LOCK_ASSERT(ifp->if_carp); \ + KASSERT(mtx_owned(&ifp->if_carp->cif_mtx) || \ + sx_xlocked(&carp_sx), ("cif_vrs not locked")); \ TAILQ_FOREACH((sc), &(ifp)->if_carp->cif_vrs, sc_list) #define DEMOTE_ADVSKEW(sc) \ @@ -1562,6 +1563,8 @@ carp_alloc(struct ifnet *ifp) struct carp_softc *sc; struct carp_if *cif; + sx_assert(&carp_sx, SA_XLOCKED); + if ((cif = ifp->if_carp) == NULL) cif = carp_alloc_if(ifp); @@ -1751,11 +1754,9 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td) } if (ifp->if_carp) { - CIF_LOCK(ifp->if_carp); IFNET_FOREACH_CARP(ifp, sc) if (sc->sc_vhid == carpr.carpr_vhid) break; - CIF_UNLOCK(ifp->if_carp); } if (sc == NULL) { sc = carp_alloc(ifp); @@ -1826,11 +1827,9 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td) priveleged = (priv_check(td, PRIV_NETINET_CARP) == 0); if (carpr.carpr_vhid != 0) { - CIF_LOCK(ifp->if_carp); IFNET_FOREACH_CARP(ifp, sc) if (sc->sc_vhid == carpr.carpr_vhid) break; - CIF_UNLOCK(ifp->if_carp); if (sc == NULL) { error = ENOENT; break; @@ -1841,7 +1840,6 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td) int i, count; count = 0; - CIF_LOCK(ifp->if_carp); IFNET_FOREACH_CARP(ifp, sc) count++; @@ -1863,7 +1861,6 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td) } i++; } - CIF_UNLOCK(ifp->if_carp); } break; } @@ -1918,11 +1915,9 @@ carp_attach(struct ifaddr *ifa, int vhid) return (ENOPROTOOPT); } - CIF_LOCK(cif); IFNET_FOREACH_CARP(ifp, sc) if (sc->sc_vhid == vhid) break; - CIF_UNLOCK(cif); if (sc == NULL) { sx_xunlock(&carp_sx); return (ENOENT); diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 5983b3386af8..cb14888620fe 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -185,17 +185,14 @@ kmod_icmpstat_inc(int statnum) void icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) { - struct ip *oip = mtod(n, struct ip *), *nip; - unsigned oiphlen = oip->ip_hl << 2; + struct ip *oip, *nip; struct icmp *icp; struct mbuf *m; - unsigned icmplen, icmpelen, nlen; + unsigned icmplen, icmpelen, nlen, oiphlen; + + KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", + __func__)); - KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", __func__)); -#ifdef ICMPPRINTFS - if (icmpprintfs) - printf("icmp_error(%p, %x, %d)\n", oip, type, code); -#endif if (type != ICMP_REDIRECT) ICMPSTAT_INC(icps_error); /* @@ -207,19 +204,28 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) */ if (n->m_flags & M_DECRYPTED) goto freeit; - if (oip->ip_off & htons(~(IP_MF|IP_DF))) - goto freeit; if (n->m_flags & (M_BCAST|M_MCAST)) goto freeit; + + /* Drop if IP header plus 8 bytes is not contiguous in first mbuf. */ + if (n->m_len < sizeof(struct ip) + ICMP_MINLEN) + goto freeit; + oip = mtod(n, struct ip *); + oiphlen = oip->ip_hl << 2; + if (n->m_len < oiphlen + ICMP_MINLEN) + goto freeit; +#ifdef ICMPPRINTFS + if (icmpprintfs) + printf("icmp_error(%p, %x, %d)\n", oip, type, code); +#endif + if (oip->ip_off & htons(~(IP_MF|IP_DF))) + goto freeit; if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && - n->m_len >= oiphlen + ICMP_MINLEN && - !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiphlen))->icmp_type)) { + !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + + oiphlen))->icmp_type)) { ICMPSTAT_INC(icps_oldicmp); goto freeit; } - /* Drop if IP header plus 8 bytes is not contignous in first mbuf. */ - if (oiphlen + 8 > n->m_len) - goto freeit; /* * Calculate length to quote from original packet and * prevent the ICMP mbuf from overflowing. @@ -235,9 +241,10 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) n->m_next == NULL) goto stdreply; if (n->m_len < oiphlen + sizeof(struct tcphdr) && - ((n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL)) + (n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL) goto freeit; - th = (struct tcphdr *)((caddr_t)oip + oiphlen); + oip = mtod(n, struct ip *); + th = mtodo(n, oiphlen); tcphlen = th->th_off << 2; if (tcphlen < sizeof(struct tcphdr)) goto freeit; @@ -245,8 +252,8 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) goto freeit; if (oiphlen + tcphlen > n->m_len && n->m_next == NULL) goto stdreply; - if (n->m_len < oiphlen + tcphlen && - ((n = m_pullup(n, oiphlen + tcphlen)) == NULL)) + if (n->m_len < oiphlen + tcphlen && + (n = m_pullup(n, oiphlen + tcphlen)) == NULL) goto freeit; icmpelen = max(tcphlen, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen)); @@ -262,24 +269,31 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) if (n->m_len < oiphlen + sizeof(struct sctphdr) && (n = m_pullup(n, oiphlen + sizeof(struct sctphdr))) == NULL) goto freeit; + oip = mtod(n, struct ip *); icmpelen = max(sizeof(struct sctphdr), min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen)); - sh = (struct sctphdr *)((caddr_t)oip + oiphlen); + sh = mtodo(n, oiphlen); if (ntohl(sh->v_tag) == 0 && - ntohs(oip->ip_len) >= oiphlen + sizeof(struct sctphdr) + 8 && + ntohs(oip->ip_len) >= oiphlen + + sizeof(struct sctphdr) + 8 && (n->m_len >= oiphlen + sizeof(struct sctphdr) + 8 || n->m_next != NULL)) { if (n->m_len < oiphlen + sizeof(struct sctphdr) + 8 && - (n = m_pullup(n, oiphlen + sizeof(struct sctphdr) + 8)) == NULL) + (n = m_pullup(n, oiphlen + + sizeof(struct sctphdr) + 8)) == NULL) goto freeit; + oip = mtod(n, struct ip *); + sh = mtodo(n, oiphlen); ch = (struct sctp_chunkhdr *)(sh + 1); if (ch->chunk_type == SCTP_INITIATION) { icmpelen = max(sizeof(struct sctphdr) + 8, - min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen)); + min(V_icmp_quotelen, ntohs(oip->ip_len) - + oiphlen)); } } } else -stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen)); +stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - + oiphlen)); icmplen = min(oiphlen + icmpelen, nlen); if (icmplen < sizeof(struct ip)) @@ -294,7 +308,8 @@ stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen)); #ifdef MAC mac_netinet_icmp_reply(n, m); #endif - icmplen = min(icmplen, M_TRAILINGSPACE(m) - sizeof(struct ip) - ICMP_MINLEN); + icmplen = min(icmplen, M_TRAILINGSPACE(m) - + sizeof(struct ip) - ICMP_MINLEN); m_align(m, ICMP_MINLEN + icmplen); m->m_len = ICMP_MINLEN + icmplen; diff --git a/sys/netinet/sctp.h b/sys/netinet/sctp.h index ec42cffaf661..578be4f64cad 100644 --- a/sys/netinet/sctp.h +++ b/sys/netinet/sctp.h @@ -545,7 +545,6 @@ struct sctp_error_auth_invalid_hmac { #define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010 #define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020 #define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040 -#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080 /* socket options */ #define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100 #define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200 diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index c6e14f1fc8ae..9387f9a80bde 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -2305,39 +2305,6 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa) return (0); } -void -sctp_set_primary_ip_address(struct sctp_ifa *ifa) -{ - struct sctp_inpcb *inp; - - /* go through all our PCB's */ - LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) { - struct sctp_tcb *stcb; - - /* process for all associations for this endpoint */ - LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { - /* queue an ASCONF:SET_PRIM_ADDR to be sent */ - if (!sctp_asconf_queue_add(stcb, ifa, - SCTP_SET_PRIM_ADDR)) { - /* set primary queuing succeeded */ - SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ", - (void *)stcb); - SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa); - if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || - (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { -#ifdef SCTP_TIMER_BASED_ASCONF - sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, - stcb->sctp_ep, stcb, - stcb->asoc.primary_destination); -#else - sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED); -#endif - } - } - } /* for each stcb */ - } /* for each inp */ -} - int sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa) { diff --git a/sys/netinet/sctp_asconf.h b/sys/netinet/sctp_asconf.h index c8d670e59bc5..ed9160e1a919 100644 --- a/sys/netinet/sctp_asconf.h +++ b/sys/netinet/sctp_asconf.h @@ -72,9 +72,6 @@ extern int32_t sctp_set_primary_ip_address_sa(struct sctp_tcb *, struct sockaddr *); -extern void - sctp_set_primary_ip_address(struct sctp_ifa *ifa); - extern void sctp_check_address_list(struct sctp_tcb *, struct mbuf *, int, int, struct sockaddr *, uint16_t, uint16_t, uint16_t, uint16_t); diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index fd7dbd85dca2..371d01138446 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -1606,9 +1606,9 @@ sctp_zero_m(struct mbuf *m, uint32_t m_offset, uint32_t size) /* now use the rest of the mbuf chain */ while ((m_tmp != NULL) && (size > 0)) { data = mtod(m_tmp, uint8_t *)+m_offset; - if (size > (uint32_t)SCTP_BUF_LEN(m_tmp)) { - memset(data, 0, SCTP_BUF_LEN(m_tmp)); - size -= SCTP_BUF_LEN(m_tmp); + if (size > (uint32_t)(SCTP_BUF_LEN(m_tmp) - m_offset)) { + memset(data, 0, SCTP_BUF_LEN(m_tmp) - m_offset); + size -= SCTP_BUF_LEN(m_tmp) - m_offset; } else { memset(data, 0, size); size = 0; diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index dca34cc59ffa..fb678e964571 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -97,10 +97,6 @@ __FBSDID("$FreeBSD$"); */ #define SCTP_DEFAULT_VRF_SIZE 4 -/* constants for rto calc */ -#define sctp_align_safe_nocopy 0 -#define sctp_align_unsafe_makecopy 1 - /* JRS - Values defined for the HTCP algorithm */ #define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */ #define BETA_MIN (1<<6) /* 0.5 with shift << 7 */ @@ -555,11 +551,9 @@ __FBSDID("$FreeBSD$"); #define SCTP_TIMER_TYPE_INPKILL 15 #define SCTP_TIMER_TYPE_ASOCKILL 16 #define SCTP_TIMER_TYPE_ADDR_WQ 17 -#define SCTP_TIMER_TYPE_ZERO_COPY 18 -#define SCTP_TIMER_TYPE_ZCOPY_SENDQ 19 -#define SCTP_TIMER_TYPE_PRIM_DELETED 20 +#define SCTP_TIMER_TYPE_PRIM_DELETED 18 /* add new timers here - and increment LAST */ -#define SCTP_TIMER_TYPE_LAST 21 +#define SCTP_TIMER_TYPE_LAST 19 #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ ((t) < SCTP_TIMER_TYPE_LAST)) @@ -971,9 +965,6 @@ __FBSDID("$FreeBSD$"); #define SCTP_SO_NOT_LOCKED 0 -#define SCTP_HOLDS_LOCK 1 -#define SCTP_NOT_LOCKED 0 - /*- * For address locks, do we hold the lock? */ diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index d167292b292f..8a12d3c6bbb0 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -88,12 +88,14 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc) if (stcb->sctp_socket == NULL) { return (calc); } + KASSERT(asoc->cnt_on_reasm_queue > 0 || asoc->size_on_reasm_queue == 0, + ("size_on_reasm_queue is %u", asoc->size_on_reasm_queue)); + KASSERT(asoc->cnt_on_all_streams > 0 || asoc->size_on_all_streams == 0, + ("size_on_all_streams is %u", asoc->size_on_all_streams)); if (stcb->asoc.sb_cc == 0 && - asoc->size_on_reasm_queue == 0 && - asoc->size_on_all_streams == 0) { + asoc->cnt_on_reasm_queue == 0 && + asoc->cnt_on_all_streams == 0) { /* Full rwnd granted */ - KASSERT(asoc->cnt_on_reasm_queue == 0, ("cnt_on_reasm_queue is %u", asoc->cnt_on_reasm_queue)); - KASSERT(asoc->cnt_on_all_streams == 0, ("cnt_on_all_streams is %u", asoc->cnt_on_all_streams)); calc = max(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), SCTP_MINIMAL_RWND); return (calc); } @@ -1245,6 +1247,19 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc, } done = (control->end_added) && (control->last_frag_seen); if (control->on_read_q == 0) { + if (!done) { + if (asoc->size_on_all_streams >= control->length) { + asoc->size_on_all_streams -= control->length; + } else { +#ifdef INVARIANTS + panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length); +#else + asoc->size_on_all_streams = 0; +#endif + } + strm->pd_api_started = 1; + control->pdapi_started = 1; + } sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, control->end_added, @@ -1254,10 +1269,6 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc, if (done) { control = nctl; goto deliver_more; - } else { - /* We are now doing PD API */ - strm->pd_api_started = 1; - control->pdapi_started = 1; } } } @@ -1316,15 +1327,11 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control, } else if (control->on_strm_q == SCTP_ON_ORDERED) { /* Ordered */ TAILQ_REMOVE(&strm->inqueue, control, next_instrm); - if (asoc->size_on_all_streams >= control->length) { - asoc->size_on_all_streams -= control->length; - } else { -#ifdef INVARIANTS - panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length); -#else - asoc->size_on_all_streams = 0; -#endif - } + /* + * Don't need to decrement + * size_on_all_streams, since control is on + * the read queue. + */ sctp_ucount_decr(asoc->cnt_on_all_streams); control->on_strm_q = 0; #ifdef INVARIANTS @@ -1379,10 +1386,10 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, } if (sctp_place_control_in_stream(strm, asoc, control)) { /* Duplicate SSN? */ - sctp_clean_up_control(stcb, control); sctp_abort_in_reasm(stcb, control, chk, abort_flag, SCTP_FROM_SCTP_INDATA + SCTP_LOC_6); + sctp_clean_up_control(stcb, control); return; } if ((tsn == (asoc->cumulative_tsn + 1) && (asoc->idata_supported == 0))) { @@ -1594,9 +1601,17 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, next_fsn, control->fsn_included); TAILQ_REMOVE(&control->reasm, at, sctp_next); lenadded = sctp_add_chk_to_control(control, strm, stcb, asoc, at, SCTP_READ_LOCK_NOT_HELD); - asoc->size_on_all_streams += lenadded; if (control->on_read_q) { do_wakeup = 1; + } else { + /* + * We only add to the + * size-on-all-streams if its not on + * the read q. The read q flag will + * cause a sballoc so its accounted + * for there. + */ + asoc->size_on_all_streams += lenadded; } next_fsn++; if (control->end_added && control->pdapi_started) { @@ -1609,7 +1624,6 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, control, &stcb->sctp_socket->so_rcv, control->end_added, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - do_wakeup = 1; } break; } @@ -2634,10 +2648,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, struct sctp_association *asoc; int num_chunks = 0; /* number of control chunks processed */ int stop_proc = 0; - int chk_length, break_flag, last_chunk; + int break_flag, last_chunk; int abort_flag = 0, was_a_gap; struct mbuf *m; uint32_t highest_tsn; + uint16_t chk_length; /* set the rwnd */ sctp_set_rwnd(stcb, &stcb->asoc); @@ -2689,7 +2704,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, } /* get pointer to the first chunk header */ ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, - sizeof(struct sctp_chunkhdr), (uint8_t *)&chunk_buf); + sizeof(struct sctp_chunkhdr), + (uint8_t *)&chunk_buf); if (ch == NULL) { return (1); } @@ -2731,7 +2747,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, } if ((ch->chunk_type == SCTP_DATA) || (ch->chunk_type == SCTP_IDATA)) { - int clen; + uint16_t clen; if (ch->chunk_type == SCTP_DATA) { clen = sizeof(struct sctp_data_chunk); @@ -2746,7 +2762,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, struct mbuf *op_err; char msg[SCTP_DIAG_INFO_LEN]; - snprintf(msg, sizeof(msg), "DATA chunk of length %d", + snprintf(msg, sizeof(msg), "%s chunk of length %u", + ch->chunk_type == SCTP_DATA ? "DATA" : "I-DATA", chk_length); op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_20; @@ -2823,7 +2840,25 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, return (2); } default: - /* unknown chunk type, use bit rules */ + /* + * Unknown chunk type: use bit rules after + * checking length + */ + if (chk_length < sizeof(struct sctp_chunkhdr)) { + /* + * Need to send an abort since we + * had a invalid chunk. + */ + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + + snprintf(msg, sizeof(msg), "Chunk of length %u", + chk_length); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); + stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_20; + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); + return (2); + } if (ch->chunk_type & 0x40) { /* Add a error report to the queue */ struct mbuf *op_err; @@ -2859,7 +2894,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, continue; } ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, - sizeof(struct sctp_chunkhdr), (uint8_t *)&chunk_buf); + sizeof(struct sctp_chunkhdr), + (uint8_t *)&chunk_buf); if (ch == NULL) { *offset = length; stop_proc = 1; @@ -3051,7 +3087,6 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1 &stcb->asoc, tp1->whoTo, &tp1->sent_rcv_time, - sctp_align_safe_nocopy, SCTP_RTT_FROM_DATA); *rto_ok = 0; } @@ -4023,7 +4058,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, sctp_calculate_rto(stcb, asoc, tp1->whoTo, &tp1->sent_rcv_time, - sctp_align_safe_nocopy, SCTP_RTT_FROM_DATA); rto_ok = 0; } @@ -4205,8 +4239,6 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, again: j = 0; TAILQ_FOREACH(net, &asoc->nets, sctp_next) { - int to_ticks; - if (win_probe_recovery && (net->window_probe)) { win_probe_recovered = 1; /* @@ -4222,15 +4254,9 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, } } } - if (net->RTO == 0) { - to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); - } else { - to_ticks = MSEC_TO_TICKS(net->RTO); - } if (net->flight_size) { j++; - (void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks, - sctp_timeout_handler, &net->rxt_timer); + sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net); if (net->window_probe) { net->window_probe = 0; } @@ -4242,8 +4268,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, */ net->window_probe = 0; if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { - SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks, - sctp_timeout_handler, &net->rxt_timer); + sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net); } } else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, @@ -4638,7 +4663,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, sctp_calculate_rto(stcb, asoc, tp1->whoTo, &tp1->sent_rcv_time, - sctp_align_safe_nocopy, SCTP_RTT_FROM_DATA); rto_ok = 0; } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 5005a6d5fbe7..17ae947f650f 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -197,8 +197,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, sctp_send_initiate_ack(inp, stcb, net, m, iphlen, offset, src, dst, sh, cp, mflowtype, mflowid, - vrf_id, port, - ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED)); + vrf_id, port); } outnow: if (stcb == NULL) { @@ -518,7 +517,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3); /* calculate the RTO */ - net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy, + net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, SCTP_RTT_FROM_NON_DATA); retval = sctp_send_cookie_echo(m, offset, stcb, net); if (retval < 0) { @@ -640,7 +639,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp, tv.tv_sec = cp->heartbeat.hb_info.time_value_1; tv.tv_usec = cp->heartbeat.hb_info.time_value_2; /* Now lets do a RTO with this */ - r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy, + r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, SCTP_RTT_FROM_NON_DATA); if (!(r_net->dest_state & SCTP_ADDR_REACHABLE)) { r_net->dest_state |= SCTP_ADDR_REACHABLE; @@ -700,6 +699,14 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb) */ struct sctpasochead *head; + if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) || + (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); + SCTP_INP_INFO_WLOCK(); + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + } if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) { /* generate a new vtag and send init */ LIST_REMOVE(stcb, sctp_asocs); @@ -711,6 +718,7 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb) */ LIST_INSERT_HEAD(head, stcb, sctp_asocs); sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); + SCTP_INP_INFO_WUNLOCK(); return (1); } if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { @@ -732,6 +740,7 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb) */ LIST_INSERT_HEAD(head, stcb, sctp_asocs); sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); + SCTP_INP_INFO_WUNLOCK(); return (1); } return (0); @@ -754,7 +763,8 @@ sctp_handle_nat_missing_state(struct sctp_tcb *stcb, } -static void +/* Returns 1 if the stcb was aborted, 0 otherwise */ +static int sctp_handle_abort(struct sctp_abort_chunk *abort, struct sctp_tcb *stcb, struct sctp_nets *net) { @@ -766,29 +776,29 @@ sctp_handle_abort(struct sctp_abort_chunk *abort, SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: handling ABORT\n"); if (stcb == NULL) - return; + return (0); len = ntohs(abort->ch.chunk_length); - if (len > sizeof(struct sctp_chunkhdr)) { + if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause)) { /* * Need to check the cause codes for our two magic nat * aborts which don't kill the assoc necessarily. */ - struct sctp_gen_error_cause *cause; + struct sctp_error_cause *cause; - cause = (struct sctp_gen_error_cause *)(abort + 1); + cause = (struct sctp_error_cause *)(abort + 1); error = ntohs(cause->code); if (error == SCTP_CAUSE_NAT_COLLIDING_STATE) { SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n", abort->ch.chunk_flags); if (sctp_handle_nat_colliding_state(stcb)) { - return; + return (0); } } else if (error == SCTP_CAUSE_NAT_MISSING_STATE) { SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n", abort->ch.chunk_flags); if (sctp_handle_nat_missing_state(stcb, net)) { - return; + return (0); } } } else { @@ -823,6 +833,7 @@ sctp_handle_abort(struct sctp_abort_chunk *abort, SCTP_SOCKET_UNLOCK(so, 1); #endif SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: finished\n"); + return (1); } static void @@ -1478,6 +1489,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, struct sctp_init_ack_chunk *initack_cp, initack_buf; struct sctp_nets *net; struct mbuf *op_err; + struct timeval old; int init_offset, initack_offset, i; int retval; int spec_flag = 0; @@ -1638,10 +1650,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, * since we did not send a HB make sure we don't * double things */ + old.tv_sec = cookie->time_entered.tv_sec; + old.tv_usec = cookie->time_entered.tv_usec; net->hb_responded = 1; net->RTO = sctp_calculate_rto(stcb, asoc, net, - &cookie->time_entered, - sctp_align_unsafe_makecopy, + &old, SCTP_RTT_FROM_NON_DATA); if (stcb->asoc.sctp_autoclose_ticks && @@ -2358,10 +2371,13 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, } (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); if ((netp != NULL) && (*netp != NULL)) { + struct timeval old; + /* calculate the RTT and set the encaps port */ + old.tv_sec = cookie->time_entered.tv_sec; + old.tv_usec = cookie->time_entered.tv_usec; (*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp, - &cookie->time_entered, sctp_align_unsafe_makecopy, - SCTP_RTT_FROM_NON_DATA); + &old, SCTP_RTT_FROM_NON_DATA); } /* respond with a COOKIE-ACK */ sctp_send_cookie_ack(stcb); @@ -2553,15 +2569,12 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, /* Expire time is in Ticks, so we convert to seconds */ time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life); time_expires.tv_usec = cookie->time_entered.tv_usec; - /* - * TODO sctp_constants.h needs alternative time macros when _KERNEL - * is undefined. - */ if (timevalcmp(&now, &time_expires, >)) { /* cookie is stale! */ struct mbuf *op_err; struct sctp_error_stale_cookie *cause; - uint32_t tim; + struct timeval diff; + uint32_t staleness; op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_error_stale_cookie), 0, M_NOWAIT, 1, MT_DATA); @@ -2575,12 +2588,19 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, cause->cause.code = htons(SCTP_CAUSE_STALE_COOKIE); cause->cause.length = htons((sizeof(struct sctp_paramhdr) + (sizeof(uint32_t)))); - /* seconds to usec */ - tim = (now.tv_sec - time_expires.tv_sec) * 1000000; - /* add in usec */ - if (tim == 0) - tim = now.tv_usec - cookie->time_entered.tv_usec; - cause->stale_time = htonl(tim); + diff = now; + timevalsub(&diff, &time_expires); + if (diff.tv_sec > UINT32_MAX / 1000000) { + staleness = UINT32_MAX; + } else { + staleness = diff.tv_sec * 1000000; + } + if (UINT32_MAX - staleness >= (uint32_t)diff.tv_usec) { + staleness += diff.tv_usec; + } else { + staleness = UINT32_MAX; + } + cause->stale_time = htonl(staleness); sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, mflowtype, mflowid, l_inp->fibnum, vrf_id, port); @@ -2923,7 +2943,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED, SCTP_STAT_INCR_GAUGE32(sctps_currestab); if (asoc->overall_error_count == 0) { net->RTO = sctp_calculate_rto(stcb, asoc, net, - &asoc->time_entered, sctp_align_safe_nocopy, + &asoc->time_entered, SCTP_RTT_FROM_NON_DATA); } (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered); @@ -4500,7 +4520,6 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, * until we get into jumbo grams and such.. */ uint8_t chunk_buf[SCTP_CHUNK_BUFFER_SIZE]; - struct sctp_tcb *locked_tcb = stcb; int got_auth = 0; uint32_t auth_offset = 0, auth_len = 0; int auth_skipped = 0; @@ -4512,31 +4531,29 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_process_control: iphlen=%u, offset=%u, length=%u stcb:%p\n", iphlen, *offset, length, (void *)stcb); + if (stcb) { + SCTP_TCB_LOCK_ASSERT(stcb); + } /* validate chunk header length... */ if (ntohs(ch->chunk_length) < sizeof(*ch)) { SCTPDBG(SCTP_DEBUG_INPUT1, "Invalid header length %d\n", ntohs(ch->chunk_length)); - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + *offset = length; + return (stcb); } /* * validate the verification tag */ vtag_in = ntohl(sh->v_tag); - if (locked_tcb) { - SCTP_TCB_LOCK_ASSERT(locked_tcb); - } if (ch->chunk_type == SCTP_INITIATION) { SCTPDBG(SCTP_DEBUG_INPUT1, "Its an INIT of len:%d vtag:%x\n", ntohs(ch->chunk_length), vtag_in); if (vtag_in != 0) { /* protocol error- silently discard... */ SCTP_STAT_INCR(sctps_badvtag); - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4559,9 +4576,6 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if (*offset >= length) { /* no more data left in the mbuf chain */ *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } return (NULL); } ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, @@ -4570,10 +4584,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if (ch == NULL) { /* Help */ *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } if (ch->chunk_type == SCTP_COOKIE_ECHO) { goto process_control_chunks; @@ -4610,10 +4621,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, * sctp_findassociation_ep_asconf(). */ SCTP_INP_DECR_REF(inp); - } else { - locked_tcb = stcb; } - /* now go back and verify any auth chunk to be sure */ if (auth_skipped && (stcb != NULL)) { struct sctp_auth_chunk *auth; @@ -4627,10 +4635,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, auth_offset)) { /* auth HMAC failed so dump it */ *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } else { /* remaining chunks are HMAC checked */ stcb->asoc.authenticated = 1; @@ -4646,9 +4651,6 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, mflowtype, mflowid, inp->fibnum, vrf_id, port); *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } return (NULL); } asoc = &stcb->asoc; @@ -4660,13 +4662,14 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) && (vtag_in == asoc->my_vtag)) || (((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) && + (asoc->peer_vtag != htonl(0)) && (vtag_in == asoc->peer_vtag))) { /* this is valid */ } else { /* drop this packet... */ SCTP_STAT_INCR(sctps_badvtag); - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4679,8 +4682,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, * but it won't complete until the shutdown * is completed */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __func__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), @@ -4699,8 +4702,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, "invalid vtag: %xh, expect %xh\n", vtag_in, asoc->my_vtag); SCTP_STAT_INCR(sctps_badvtag); - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } *offset = length; return (NULL); @@ -4736,10 +4739,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if (chk_length < sizeof(*ch) || (*offset + (int)chk_length) > length) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } SCTP_STAT_INCR_COUNTER64(sctps_incontrolchunks); /* @@ -4754,8 +4754,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, sizeof(struct sctp_init_ack_chunk), chunk_buf); if (ch == NULL) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4777,8 +4777,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, chunk_buf); if (ch == NULL) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4789,8 +4789,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if (ch == NULL) { SCTP_PRINTF("sctp_process_control: Can't get the all data....\n"); *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4830,8 +4830,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, (length - *offset > (int)SCTP_SIZE32(chk_length))) { /* RFC 4960 requires that no ABORT is sent */ *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); } @@ -4851,8 +4851,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, mflowtype, mflowid, vrf_id, port); *offset = length; - if ((!abort_no_unlock) && (locked_tcb)) { - SCTP_TCB_UNLOCK(locked_tcb); + if ((!abort_no_unlock) && (stcb != NULL)) { + SCTP_TCB_UNLOCK(stcb); } return (NULL); break; @@ -4862,15 +4862,11 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n"); if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { /* We are not interested anymore */ - if ((stcb) && (stcb->asoc.total_output_queue_size)) { + if ((stcb != NULL) && (stcb->asoc.total_output_queue_size)) { ; } else { - if ((locked_tcb != NULL) && (locked_tcb != stcb)) { - /* Very unlikely */ - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - if (stcb) { + if (stcb != NULL) { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) so = SCTP_INP_SO(inp); atomic_add_int(&stcb->asoc.refcnt, 1); @@ -4892,10 +4888,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if ((num_chunks > 1) || (length - *offset > (int)SCTP_SIZE32(chk_length))) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } if ((netp) && (*netp)) { ret = sctp_handle_init_ack(m, iphlen, *offset, @@ -4919,10 +4912,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if ((stcb != NULL) && (ret == 0)) { sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED); } - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); break; case SCTP_SELECTIVE_ACK: { @@ -5114,10 +5104,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if ((stcb == NULL) || (chk_length != sizeof(struct sctp_heartbeat_chunk))) { /* Its not ours */ *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } /* He's alive so give him credit */ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) { @@ -5136,21 +5123,23 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, case SCTP_ABORT_ASSOCIATION: SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n", (void *)stcb); - if ((stcb) && netp && *netp) - sctp_handle_abort((struct sctp_abort_chunk *)ch, - stcb, *netp); *offset = length; - return (NULL); + if ((stcb != NULL) && (netp != NULL) && (*netp != NULL)) { + if (sctp_handle_abort((struct sctp_abort_chunk *)ch, stcb, *netp)) { + return (NULL); + } else { + return (stcb); + } + } else { + return (NULL); + } break; case SCTP_SHUTDOWN: SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN, stcb %p\n", (void *)stcb); if ((stcb == NULL) || (chk_length != sizeof(struct sctp_shutdown_chunk))) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } if (netp && *netp) { int abort_flag = 0; @@ -5187,7 +5176,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { /* We are not interested anymore */ abend: - if (stcb) { + if (stcb != NULL) { SCTP_TCB_UNLOCK(stcb); } *offset = length; @@ -5244,6 +5233,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, } } if (netp) { + struct sctp_tcb *locked_stcb; + + locked_stcb = stcb; ret_buf = sctp_handle_cookie_echo(m, iphlen, *offset, @@ -5254,11 +5246,17 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, auth_skipped, auth_offset, auth_len, - &locked_tcb, + &locked_stcb, mflowtype, mflowid, vrf_id, port); + if ((locked_stcb != NULL) && (locked_stcb != stcb)) { + SCTP_TCB_UNLOCK(locked_stcb); + } + if (stcb != NULL) { + SCTP_TCB_LOCK_ASSERT(stcb); + } } else { ret_buf = NULL; } @@ -5266,8 +5264,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTP_ASOC_CREATE_UNLOCK(linp); } if (ret_buf == NULL) { - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); + if (stcb != NULL) { + SCTP_TCB_UNLOCK(stcb); } SCTPDBG(SCTP_DEBUG_INPUT3, "GAK, null buffer\n"); @@ -5294,10 +5292,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, case SCTP_COOKIE_ACK: SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", (void *)stcb); if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) { - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { /* We are not interested anymore */ @@ -5339,11 +5334,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, /* He's alive so give him credit */ if ((stcb == NULL) || (chk_length != sizeof(struct sctp_ecne_chunk))) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if (stcb) { if (stcb->asoc.ecn_supported == 0) { @@ -5366,12 +5358,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-CWR\n"); /* He's alive so give him credit */ if ((stcb == NULL) || (chk_length != sizeof(struct sctp_cwr_chunk))) { - /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if (stcb) { if (stcb->asoc.ecn_supported == 0) { @@ -5394,10 +5382,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, if ((num_chunks > 1) || (length - *offset > (int)SCTP_SIZE32(chk_length))) { *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); + return (stcb); } if ((stcb) && netp && *netp) { sctp_handle_shutdown_complete((struct sctp_shutdown_complete_chunk *)ch, @@ -5430,11 +5415,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF-ACK\n"); if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if ((stcb) && netp && *netp) { if (stcb->asoc.asconf_supported == 0) { @@ -5460,11 +5442,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD-TSN\n"); if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } /* He's alive so give him credit */ if (stcb) { @@ -5527,11 +5506,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_STREAM_RESET\n"); if (((stcb == NULL) || (ch == NULL) || (chk_length < sizeof(struct sctp_stream_reset_tsn_req)))) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if (stcb->asoc.reconfig_supported == 0) { goto unknown_chunk; @@ -5547,11 +5523,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, /* re-get it all please */ if (chk_length < sizeof(struct sctp_pktdrop_chunk)) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if (ch && (stcb) && netp && (*netp)) { if (stcb->asoc.pktdrop_supported == 0) { @@ -5560,7 +5533,6 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch, stcb, *netp, min(chk_length, (sizeof(chunk_buf) - 4))); - } break; case SCTP_AUTHENTICATION: @@ -5582,11 +5554,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, (chk_length > (sizeof(struct sctp_auth_chunk) + SCTP_AUTH_DIGEST_LEN_MAX))) { /* Its not ours */ - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } if (got_auth == 1) { /* skip this chunk... it's already auth'd */ @@ -5651,11 +5620,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, sizeof(struct sctp_chunkhdr), chunk_buf); if (ch == NULL) { - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } *offset = length; - return (NULL); + return (stcb); } } /* while */ diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 9afd8592da5c..5c0b80db1da1 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -404,11 +404,6 @@ typedef struct rtentry sctp_rtentry_t; #define SCTP_RTALLOC(ro, vrf_id, fibnum) \ rtalloc_ign_fib((struct route *)ro, 0UL, fibnum) -/* Future zero copy wakeup/send function */ -#define SCTP_ZERO_COPY_EVENT(inp, so) -/* This is re-pulse ourselves for sendbuf */ -#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so) - /* * SCTP protocol specific mbuf flags. */ diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index c292b3a976c3..3d5ba00eb596 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3465,32 +3465,35 @@ static int sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) { struct cmsghdr cmh; - int tlen, at, found; struct sctp_sndinfo sndinfo; struct sctp_prinfo prinfo; struct sctp_authinfo authinfo; + int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off; + int found; - tlen = SCTP_BUF_LEN(control); - at = 0; - found = 0; /* * Independent of how many mbufs, find the c_type inside the control * structure and copy out the data. */ - while (at < tlen) { - if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) { + found = 0; + tot_len = SCTP_BUF_LEN(control); + for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) { + rem_len = tot_len - off; + if (rem_len < (int)CMSG_ALIGN(sizeof(cmh))) { /* There is not enough room for one more. */ return (found); } - m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh); + m_copydata(control, off, sizeof(cmh), (caddr_t)&cmh); if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) { /* We dont't have a complete CMSG header. */ return (found); } - if (((int)cmh.cmsg_len + at) > tlen) { + if ((cmh.cmsg_len > INT_MAX) || ((int)cmh.cmsg_len > rem_len)) { /* We don't have the complete CMSG. */ return (found); } + cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh)); + cmsg_data_off = off + CMSG_ALIGN(sizeof(cmh)); if ((cmh.cmsg_level == IPPROTO_SCTP) && ((c_type == cmh.cmsg_type) || ((c_type == SCTP_SNDRCV) && @@ -3498,11 +3501,14 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) (cmh.cmsg_type == SCTP_PRINFO) || (cmh.cmsg_type == SCTP_AUTHINFO))))) { if (c_type == cmh.cmsg_type) { - if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < cpsize) { + if (cpsize > INT_MAX) { + return (found); + } + if (cmsg_data_len < (int)cpsize) { return (found); } /* It is exactly what we want. Copy it out. */ - m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), (int)cpsize, (caddr_t)data); + m_copydata(control, cmsg_data_off, (int)cpsize, (caddr_t)data); return (1); } else { struct sctp_sndrcvinfo *sndrcvinfo; @@ -3516,10 +3522,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) } switch (cmh.cmsg_type) { case SCTP_SNDINFO: - if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_sndinfo)) { + if (cmsg_data_len < (int)sizeof(struct sctp_sndinfo)) { return (found); } - m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_sndinfo), (caddr_t)&sndinfo); + m_copydata(control, cmsg_data_off, sizeof(struct sctp_sndinfo), (caddr_t)&sndinfo); sndrcvinfo->sinfo_stream = sndinfo.snd_sid; sndrcvinfo->sinfo_flags = sndinfo.snd_flags; sndrcvinfo->sinfo_ppid = sndinfo.snd_ppid; @@ -3527,10 +3533,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) sndrcvinfo->sinfo_assoc_id = sndinfo.snd_assoc_id; break; case SCTP_PRINFO: - if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_prinfo)) { + if (cmsg_data_len < (int)sizeof(struct sctp_prinfo)) { return (found); } - m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo); + m_copydata(control, cmsg_data_off, sizeof(struct sctp_prinfo), (caddr_t)&prinfo); if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) { sndrcvinfo->sinfo_timetolive = prinfo.pr_value; } else { @@ -3539,10 +3545,10 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) sndrcvinfo->sinfo_flags |= prinfo.pr_policy; break; case SCTP_AUTHINFO: - if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_authinfo)) { + if (cmsg_data_len < (int)sizeof(struct sctp_authinfo)) { return (found); } - m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_authinfo), (caddr_t)&authinfo); + m_copydata(control, cmsg_data_off, sizeof(struct sctp_authinfo), (caddr_t)&authinfo); sndrcvinfo->sinfo_keynumber_valid = 1; sndrcvinfo->sinfo_keynumber = authinfo.auth_keynumber; break; @@ -3552,7 +3558,6 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) found = 1; } } - at += CMSG_ALIGN(cmh.cmsg_len); } return (found); } @@ -4268,12 +4273,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, /* free tempy routes */ RO_RTFREE(ro); } else { - /* - * PMTU check versus smallest asoc MTU goes - * here - */ - if ((ro->ro_rt != NULL) && - (net->ro._s_addr)) { + if ((ro->ro_rt != NULL) && (net->ro._s_addr) && + ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) { uint32_t mtu; mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt); @@ -4630,8 +4631,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } net->src_addr_selected = 0; } - if ((ro->ro_rt != NULL) && - (net->ro._s_addr)) { + if ((ro->ro_rt != NULL) && (net->ro._s_addr) && + ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) { uint32_t mtu; mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt); @@ -5491,7 +5492,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_init_chunk *init_chk, uint8_t mflowtype, uint32_t mflowid, - uint32_t vrf_id, uint16_t port, int hold_inp_lock) + uint32_t vrf_id, uint16_t port) { struct sctp_association *asoc; struct mbuf *m, *m_tmp, *m_last, *m_cookie, *op_err; @@ -5501,6 +5502,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_paramhdr *ph; union sctp_sockstore *over_addr; struct sctp_scoping scp; + struct timeval now; #ifdef INET struct sockaddr_in *dst4 = (struct sockaddr_in *)dst; struct sockaddr_in *src4 = (struct sockaddr_in *)src; @@ -5601,7 +5603,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, memset(&stc, 0, sizeof(struct sctp_state_cookie)); /* the time I built cookie */ - (void)SCTP_GETTIME_TIMEVAL(&stc.time_entered); + (void)SCTP_GETTIME_TIMEVAL(&now); + stc.time_entered.tv_sec = now.tv_sec; + stc.time_entered.tv_usec = now.tv_usec; /* populate any tie tags */ if (asoc != NULL) { @@ -5839,10 +5843,6 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } else { uint32_t vtag, itsn; - if (hold_inp_lock) { - SCTP_INP_INCR_REF(inp); - SCTP_INP_RUNLOCK(inp); - } if (asoc) { atomic_add_int(&asoc->refcnt, 1); SCTP_TCB_UNLOCK(stcb); @@ -5862,12 +5862,12 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_TCB_LOCK(stcb); atomic_add_int(&asoc->refcnt, -1); } else { + SCTP_INP_INCR_REF(inp); + SCTP_INP_RUNLOCK(inp); vtag = sctp_select_a_tag(inp, inp->sctp_lport, sh->src_port, 1); initack->init.initiate_tag = htonl(vtag); /* get a TSN to use too */ initack->init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep)); - } - if (hold_inp_lock) { SCTP_INP_RLOCK(inp); SCTP_INP_DECR_REF(inp); } diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index 32f968c1dafb..0a5cf10b35fb 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -86,7 +86,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct sockaddr *, struct sockaddr *, struct sctphdr *, struct sctp_init_chunk *, uint8_t, uint32_t, - uint32_t, uint16_t, int); + uint32_t, uint16_t); struct mbuf * sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *, diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index a13ccad8144c..860867a79d60 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -709,12 +709,11 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, SCTP_WQ_ADDR_LOCK(); LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); - SCTP_WQ_ADDR_UNLOCK(); - sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, (struct sctp_inpcb *)NULL, (struct sctp_tcb *)NULL, (struct sctp_nets *)NULL); + SCTP_WQ_ADDR_UNLOCK(); } else { /* it's ready for use */ sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE; @@ -821,12 +820,11 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, * the newest first :-0 */ LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); - SCTP_WQ_ADDR_UNLOCK(); - sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, (struct sctp_inpcb *)NULL, (struct sctp_tcb *)NULL, (struct sctp_nets *)NULL); + SCTP_WQ_ADDR_UNLOCK(); } return; } @@ -2486,7 +2484,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE | SCTP_PCB_FLAGS_UNBOUND); /* Be sure we have blocking IO by default */ + SOCK_LOCK(so); SCTP_CLEAR_SO_NBIO(so); + SOCK_UNLOCK(so); } else { /* * unsupported socket type (RAW, etc)- in case we missed it @@ -2577,6 +2577,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* number of streams to pre-open on a association */ m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default); + m->default_mtu = 0; /* Add adaptation cookie */ m->adaptation_layer_indicator = 0; m->adaptation_layer_indicator_provided = 0; @@ -3942,7 +3943,28 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, net, 0, stcb->asoc.vrf_id); - if (net->ro._s_addr != NULL) { + if (stcb->asoc.default_mtu > 0) { + net->mtu = stcb->asoc.default_mtu; + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: + net->mtu += SCTP_MIN_V4_OVERHEAD; + break; +#endif +#ifdef INET6 + case AF_INET6: + net->mtu += SCTP_MIN_OVERHEAD; + break; +#endif + default: + break; + } +#if defined(INET) || defined(INET6) + if (net->port) { + net->mtu += (uint32_t)sizeof(struct udphdr); + } +#endif + } else if (net->ro._s_addr != NULL) { uint32_t imtu, rmtu, hcmtu; net->src_addr_selected = 1; @@ -3966,19 +3988,42 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, } } if (net->mtu == 0) { - switch (newaddr->sa_family) { + if (stcb->asoc.default_mtu > 0) { + net->mtu = stcb->asoc.default_mtu; + switch (net->ro._l_addr.sa.sa_family) { #ifdef INET - case AF_INET: - net->mtu = SCTP_DEFAULT_MTU; - break; + case AF_INET: + net->mtu += SCTP_MIN_V4_OVERHEAD; + break; #endif #ifdef INET6 - case AF_INET6: - net->mtu = 1280; - break; + case AF_INET6: + net->mtu += SCTP_MIN_OVERHEAD; + break; #endif - default: - break; + default: + break; + } +#if defined(INET) || defined(INET6) + if (net->port) { + net->mtu += (uint32_t)sizeof(struct udphdr); + } +#endif + } else { + switch (newaddr->sa_family) { +#ifdef INET + case AF_INET: + net->mtu = SCTP_DEFAULT_MTU; + break; +#endif +#ifdef INET6 + case AF_INET6: + net->mtu = 1280; + break; +#endif + default: + break; + } } } #if defined(INET) || defined(INET6) diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index 86fae1f4adac..8d40b698aee0 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -287,6 +287,7 @@ struct sctp_pcb { sctp_auth_chklist_t *local_auth_chunks; sctp_hmaclist_t *local_hmacs; uint16_t default_keyid; + uint32_t default_mtu; /* various thresholds */ /* Max times I will init at a guy */ @@ -314,10 +315,6 @@ struct sctp_pcb { */ struct sctp_timer signature_change; - /* Zero copy full buffer timer */ - struct sctp_timer zero_copy_timer; - /* Zero copy app to transport (sendq) read repulse timer */ - struct sctp_timer zero_copy_sendq_timer; uint32_t def_cookie_life; /* defaults to 0 */ int auto_close_time; diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index f7371748f554..ed907f1c4a9c 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -1098,6 +1098,7 @@ struct sctp_association { uint32_t chunks_on_out_queue; /* total chunks floating around, * locked by send socket buffer */ uint32_t peers_adaptation; + uint32_t default_mtu; uint16_t peer_hmac_id; /* peer HMAC id to send */ /* diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 6decb6b92b2f..28b2d24aa379 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -202,6 +202,10 @@ sctp_notify(struct sctp_inpcb *inp, #endif /* no need to unlock here, since the TCB is gone */ } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) { + if ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0) { + SCTP_TCB_UNLOCK(stcb); + return; + } /* Find the next (smaller) MTU */ if (next_mtu == 0) { /* @@ -2412,7 +2416,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, #endif #ifdef INET6 case AF_INET6: - paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD; + paddrp->spp_pathmtu -= SCTP_MIN_OVERHEAD; break; #endif default: @@ -2447,7 +2451,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, * value */ paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; - paddrp->spp_pathmtu = 0; + paddrp->spp_pathmtu = stcb->asoc.default_mtu; if (stcb->asoc.default_dscp & 0x01) { paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc; paddrp->spp_flags |= SPP_DSCP; @@ -2494,8 +2498,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; } #endif - /* can't return this */ - paddrp->spp_pathmtu = 0; + paddrp->spp_pathmtu = inp->sctp_ep.default_mtu; if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { paddrp->spp_flags |= SPP_HB_ENABLE; @@ -5479,6 +5482,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, sctp_pathmtu_adjustment(stcb, net->mtu); } } + stcb->asoc.default_mtu = paddrp->spp_pathmtu; sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { @@ -5488,6 +5492,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, } net->dest_state &= ~SCTP_ADDR_NO_PMTUD; } + stcb->asoc.default_mtu = 0; sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_DSCP) { @@ -5544,8 +5549,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); } if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { + inp->sctp_ep.default_mtu = 0; sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { + if (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU) { + inp->sctp_ep.default_mtu = paddrp->spp_pathmtu; + } sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_DSCP) { diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index f61a3edc60ab..444419ba2d3c 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1042,6 +1042,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max; asoc->initial_rto = inp->sctp_ep.initial_rto; + asoc->default_mtu = inp->sctp_ep.default_mtu; asoc->max_init_times = inp->sctp_ep.max_init_times; asoc->max_send_times = inp->sctp_ep.max_send_times; asoc->def_net_failure = inp->sctp_ep.def_net_failure; @@ -1462,13 +1463,11 @@ sctp_handle_addr_wq(void) LIST_INIT(&asc->list_of_work); asc->cnt = 0; - SCTP_WQ_ADDR_LOCK(); LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { LIST_REMOVE(wi, sctp_nxt_addr); LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); asc->cnt++; } - SCTP_WQ_ADDR_UNLOCK(); if (asc->cnt == 0) { SCTP_FREE(asc, SCTP_M_ASC_IT); @@ -1492,11 +1491,9 @@ sctp_handle_addr_wq(void) if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { sctp_asconf_iterator_end(asc, 0); } else { - SCTP_WQ_ADDR_LOCK(); LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) { LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); } - SCTP_WQ_ADDR_UNLOCK(); SCTP_FREE(asc, SCTP_M_ASC_IT); } } @@ -1565,8 +1562,7 @@ sctp_timeout_handler(void *t) (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) && (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) && (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) && - (tmr->type != SCTP_TIMER_TYPE_ASOCKILL)) - ) { + (tmr->type != SCTP_TIMER_TYPE_ASOCKILL))) { SCTP_INP_DECR_REF(inp); CURVNET_RESTORE(); return; @@ -1612,6 +1608,12 @@ sctp_timeout_handler(void *t) CURVNET_RESTORE(); return; } + } else if (inp != NULL) { + if (type != SCTP_TIMER_TYPE_INPKILL) { + SCTP_INP_WLOCK(inp); + } + } else { + SCTP_WQ_ADDR_LOCK(); } /* record in stopped what t-o occurred */ tmr->stopped_from = type; @@ -1633,22 +1635,6 @@ sctp_timeout_handler(void *t) /* call the handler for the appropriate timer type */ switch (type) { - case SCTP_TIMER_TYPE_ZERO_COPY: - if (inp == NULL) { - break; - } - if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { - SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); - } - break; - case SCTP_TIMER_TYPE_ZCOPY_SENDQ: - if (inp == NULL) { - break; - } - if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { - SCTP_ZERO_COPY_SENDQ_EVENT(inp, inp->sctp_socket); - } - break; case SCTP_TIMER_TYPE_ADDR_WQ: sctp_handle_addr_wq(); break; @@ -1775,7 +1761,6 @@ sctp_timeout_handler(void *t) } SCTP_STAT_INCR(sctps_timosecret); (void)SCTP_GETTIME_TIMEVAL(&tv); - SCTP_INP_WLOCK(inp); inp->sctp_ep.time_of_secret_change = tv.tv_sec; inp->sctp_ep.last_secret_number = inp->sctp_ep.current_secret_number; @@ -1789,7 +1774,6 @@ sctp_timeout_handler(void *t) inp->sctp_ep.secret_key[secret][i] = sctp_select_initial_TSN(&inp->sctp_ep); } - SCTP_INP_WUNLOCK(inp); sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net); } did_output = 0; @@ -1937,7 +1921,12 @@ sctp_timeout_handler(void *t) get_out: if (stcb) { SCTP_TCB_UNLOCK(stcb); + } else if (inp != NULL) { + SCTP_INP_WUNLOCK(inp); + } else { + SCTP_WQ_ADDR_UNLOCK(); } + out_decr: if (inp) { SCTP_INP_DECR_REF(inp); @@ -1962,14 +1951,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_TCB_LOCK_ASSERT(stcb); } switch (t_type) { - case SCTP_TIMER_TYPE_ZERO_COPY: - tmr = &inp->sctp_ep.zero_copy_timer; - to_ticks = SCTP_ZERO_COPY_TICK_DELAY; - break; - case SCTP_TIMER_TYPE_ZCOPY_SENDQ: - tmr = &inp->sctp_ep.zero_copy_sendq_timer; - to_ticks = SCTP_ZERO_COPY_SENDQ_TICK_DELAY; - break; case SCTP_TIMER_TYPE_ADDR_WQ: /* Only 1 tick away :-) */ tmr = &SCTP_BASE_INFO(addr_wq_timer); @@ -2251,12 +2232,6 @@ sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, SCTP_TCB_LOCK_ASSERT(stcb); } switch (t_type) { - case SCTP_TIMER_TYPE_ZERO_COPY: - tmr = &inp->sctp_ep.zero_copy_timer; - break; - case SCTP_TIMER_TYPE_ZCOPY_SENDQ: - tmr = &inp->sctp_ep.zero_copy_sendq_timer; - break; case SCTP_TIMER_TYPE_ADDR_WQ: tmr = &SCTP_BASE_INFO(addr_wq_timer); break; @@ -2448,8 +2423,8 @@ uint32_t sctp_calculate_rto(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_nets *net, - struct timeval *told, - int safe, int rtt_from_sack) + struct timeval *old, + int rtt_from_sack) { /*- * given an association and the starting time of the current RTT @@ -2458,19 +2433,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb, int32_t rtt; /* RTT in ms */ uint32_t new_rto; int first_measure = 0; - struct timeval now, then, *old; + struct timeval now; - /* Copy it out for sparc64 */ - if (safe == sctp_align_unsafe_makecopy) { - old = &then; - memcpy(&then, told, sizeof(struct timeval)); - } else if (safe == sctp_align_safe_nocopy) { - old = told; - } else { - /* error */ - SCTP_PRINTF("Huh, bad rto calc call\n"); - return (0); - } /************************/ /* 1. calculate new RTT */ /************************/ @@ -4470,36 +4434,32 @@ sctp_wakeup_the_read_socket(struct sctp_inpcb *inp, ) { if ((inp != NULL) && (inp->sctp_socket != NULL)) { - if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { - SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); - } else { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) - struct socket *so; + struct socket *so; - so = SCTP_INP_SO(inp); - if (!so_locked) { - if (stcb) { - atomic_add_int(&stcb->asoc.refcnt, 1); - SCTP_TCB_UNLOCK(stcb); - } - SCTP_SOCKET_LOCK(so, 1); - if (stcb) { - SCTP_TCB_LOCK(stcb); - atomic_subtract_int(&stcb->asoc.refcnt, 1); - } - if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { - SCTP_SOCKET_UNLOCK(so, 1); - return; - } + so = SCTP_INP_SO(inp); + if (!so_locked) { + if (stcb) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); } -#endif - sctp_sorwakeup(inp, inp->sctp_socket); -#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) - if (!so_locked) { + SCTP_SOCKET_LOCK(so, 1); + if (stcb) { + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + } + if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { SCTP_SOCKET_UNLOCK(so, 1); + return; } -#endif } +#endif + sctp_sorwakeup(inp, inp->sctp_socket); +#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + if (!so_locked) { + SCTP_SOCKET_UNLOCK(so, 1); + } +#endif } } @@ -6180,11 +6140,11 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id) * newest first :-0 */ LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); - SCTP_WQ_ADDR_UNLOCK(); sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, (struct sctp_inpcb *)NULL, (struct sctp_tcb *)NULL, (struct sctp_nets *)NULL); + SCTP_WQ_ADDR_UNLOCK(); return (0); } diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 97b336549ec2..598f9f367e17 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -135,7 +135,7 @@ void uint32_t sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *, - struct sctp_nets *, struct timeval *, int, int); + struct sctp_nets *, struct timeval *, int); uint32_t sctp_calculate_len(struct mbuf *); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 28b9b0de7cc5..6961d24a2342 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -145,7 +145,6 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_VNET | CTLFLAG_RW, "Delay ACK to try and piggyback it onto a data packet"); VNET_DEFINE(int, drop_synfin) = 0; -#define V_drop_synfin VNET(drop_synfin) SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(drop_synfin), 0, "Drop TCP packets with SYN+FIN set"); @@ -156,7 +155,6 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc6675_pipe, CTLFLAG_VNET | CTLFLAG_RW, "Use calculated pipe/in-flight bytes per RFC 6675"); VNET_DEFINE(int, tcp_do_rfc3042) = 1; -#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc3042), 0, "Enable RFC 3042 (Limited Transmit)"); @@ -194,13 +192,11 @@ SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, maxretries, CTLFLAG_VNET | CTLFLAG_RW, "Max retries before giving up on ECN"); VNET_DEFINE(int, tcp_insecure_syn) = 0; -#define V_tcp_insecure_syn VNET(tcp_insecure_syn) SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_syn, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_insecure_syn), 0, "Follow RFC793 instead of RFC5961 criteria for accepting SYN packets"); VNET_DEFINE(int, tcp_insecure_rst) = 0; -#define V_tcp_insecure_rst VNET(tcp_insecure_rst) SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_rst, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_insecure_rst), 0, "Follow RFC793 instead of RFC5961 criteria for accepting RST packets"); @@ -211,19 +207,16 @@ SYSCTL_INT(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_VNET | CTLFLAG_RW &VNET_NAME(tcp_recvspace), 0, "Initial receive socket buffer size"); VNET_DEFINE(int, tcp_do_autorcvbuf) = 1; -#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_auto, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_autorcvbuf), 0, "Enable automatic receive buffer sizing"); VNET_DEFINE(int, tcp_autorcvbuf_inc) = 16*1024; -#define V_tcp_autorcvbuf_inc VNET(tcp_autorcvbuf_inc) SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_inc, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autorcvbuf_inc), 0, "Incrementor step size of automatic receive buffer"); VNET_DEFINE(int, tcp_autorcvbuf_max) = 2*1024*1024; -#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_max, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autorcvbuf_max), 0, "Max size of automatic receive buffer"); diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 2c9898469d71..2afd3e7e0940 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -102,7 +102,6 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_VNET | CTLFLAG_R "Enable Path MTU Discovery"); VNET_DEFINE(int, tcp_do_tso) = 1; -#define V_tcp_do_tso VNET(tcp_do_tso) SYSCTL_INT(_net_inet_tcp, OID_AUTO, tso, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_tso), 0, "Enable TCP Segmentation Offload"); @@ -113,19 +112,16 @@ SYSCTL_INT(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_VNET | CTLFLAG_RW &VNET_NAME(tcp_sendspace), 0, "Initial send socket buffer size"); VNET_DEFINE(int, tcp_do_autosndbuf) = 1; -#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf) SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_autosndbuf), 0, "Enable automatic send buffer sizing"); VNET_DEFINE(int, tcp_autosndbuf_inc) = 8*1024; -#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc) SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_inc, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autosndbuf_inc), 0, "Incrementor step size of automatic send buffer"); VNET_DEFINE(int, tcp_autosndbuf_max) = 2*1024*1024; -#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autosndbuf_max), 0, "Max size of automatic send buffer"); diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index d96e19ea1e1a..6a750fcd0496 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -133,19 +133,16 @@ SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, enable, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_sack), 0, "Enable/Disable TCP SACK support"); VNET_DEFINE(int, tcp_sack_maxholes) = 128; -#define V_tcp_sack_maxholes VNET(tcp_sack_maxholes) SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, maxholes, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sack_maxholes), 0, "Maximum number of TCP SACK holes allowed per connection"); VNET_DEFINE(int, tcp_sack_globalmaxholes) = 65536; -#define V_tcp_sack_globalmaxholes VNET(tcp_sack_globalmaxholes) SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, globalmaxholes, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sack_globalmaxholes), 0, "Global maximum number of TCP SACK holes"); VNET_DEFINE(int, tcp_sack_globalholes) = 0; -#define V_tcp_sack_globalholes VNET(tcp_sack_globalholes) SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, globalholes, CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_sack_globalholes), 0, "Global number of TCP SACK holes currently allocated"); diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c index 42a5d9525678..92db0d551fee 100644 --- a/sys/netinet/tcp_stacks/fastpath.c +++ b/sys/netinet/tcp_stacks/fastpath.c @@ -120,21 +120,6 @@ __FBSDID("$FreeBSD$"); #include -VNET_DECLARE(int, tcp_autorcvbuf_inc); -#define V_tcp_autorcvbuf_inc VNET(tcp_autorcvbuf_inc) -VNET_DECLARE(int, tcp_autorcvbuf_max); -#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) -VNET_DECLARE(int, tcp_do_rfc3042); -#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) -VNET_DECLARE(int, tcp_do_autorcvbuf); -#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) -VNET_DECLARE(int, tcp_insecure_rst); -#define V_tcp_insecure_rst VNET(tcp_insecure_rst) -VNET_DECLARE(int, tcp_insecure_syn); -#define V_tcp_insecure_syn VNET(tcp_insecure_syn) -VNET_DECLARE(int, drop_synfin); -#define V_drop_synfin VNET(drop_synfin) - static void tcp_do_segment_fastslow(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, int, int, uint8_t, int); diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 64a2e36b3da8..84241f98fa83 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1195,6 +1195,7 @@ syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m, TCPSTAT_INC(tcps_sc_aborted); atomic_subtract_int(pending_counter, 1); } else { + soisconnected(*lsop); inp = sotoinpcb(*lsop); tp = intotcpcb(inp); tp->t_flags |= TF_FASTOPEN; @@ -1634,9 +1635,7 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked, tlen = hlen + sizeof(struct tcphdr); /* Determine MSS we advertize to other end of connection. */ - mssopt = tcp_mssopt(&sc->sc_inc); - if (sc->sc_peer_mss) - mssopt = max( min(sc->sc_peer_mss, mssopt), V_tcp_minmss); + mssopt = max(tcp_mssopt(&sc->sc_inc), V_tcp_minmss); /* XXX: Assume that the entire packet will fit in a header mbuf. */ KASSERT(max_linkhdr + tlen + TCP_MAXOLEN <= MHLEN, @@ -1985,7 +1984,7 @@ syncookie_mac(struct in_conninfo *inc, tcp_seq irs, uint8_t flags, static tcp_seq syncookie_generate(struct syncache_head *sch, struct syncache *sc) { - u_int i, mss, secbit, wscale; + u_int i, secbit, wscale; uint32_t iss, hash; uint8_t *secbits; union syncookie cookie; @@ -1995,8 +1994,8 @@ syncookie_generate(struct syncache_head *sch, struct syncache *sc) cookie.cookie = 0; /* Map our computed MSS into the 3-bit index. */ - mss = min(tcp_mssopt(&sc->sc_inc), max(sc->sc_peer_mss, V_tcp_minmss)); - for (i = nitems(tcp_sc_msstab) - 1; tcp_sc_msstab[i] > mss && i > 0; + for (i = nitems(tcp_sc_msstab) - 1; + tcp_sc_msstab[i] > sc->sc_peer_mss && i > 0; i--) ; cookie.flags.mss_idx = i; diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 04e0f9cd216c..df5eb2c12839 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -141,16 +141,14 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, rexmit_drop_options, CTLFLAG_RW, &tcp_rexmit_drop_options, 0, "Drop TCP options from 3rd and later retransmitted SYN"); -static VNET_DEFINE(int, tcp_pmtud_blackhole_detect); -#define V_tcp_pmtud_blackhole_detect VNET(tcp_pmtud_blackhole_detect) +VNET_DEFINE(int, tcp_pmtud_blackhole_detect); SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_pmtud_blackhole_detect), 0, "Path MTU Discovery Black Hole Detection Enabled"); #ifdef INET -static VNET_DEFINE(int, tcp_pmtud_blackhole_mss) = 1200; -#define V_tcp_pmtud_blackhole_mss VNET(tcp_pmtud_blackhole_mss) +VNET_DEFINE(int, tcp_pmtud_blackhole_mss) = 1200; SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_pmtud_blackhole_mss), 0, @@ -158,8 +156,7 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss, #endif #ifdef INET6 -static VNET_DEFINE(int, tcp_v6pmtud_blackhole_mss) = 1220; -#define V_tcp_v6pmtud_blackhole_mss VNET(tcp_v6pmtud_blackhole_mss) +VNET_DEFINE(int, tcp_v6pmtud_blackhole_mss) = 1220; SYSCTL_INT(_net_inet_tcp, OID_AUTO, v6pmtud_blackhole_mss, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_v6pmtud_blackhole_mss), 0, diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h index f14f929a4f95..5f4138cb26d2 100644 --- a/sys/netinet/tcp_timer.h +++ b/sys/netinet/tcp_timer.h @@ -198,6 +198,13 @@ extern int tcp_syn_backoff[]; extern int tcp_finwait2_timeout; extern int tcp_fast_finwait2_recycle; +VNET_DECLARE(int, tcp_pmtud_blackhole_detect); +#define V_tcp_pmtud_blackhole_detect VNET(tcp_pmtud_blackhole_detect) +VNET_DECLARE(int, tcp_pmtud_blackhole_mss); +#define V_tcp_pmtud_blackhole_mss VNET(tcp_pmtud_blackhole_mss) +VNET_DECLARE(int, tcp_v6pmtud_blackhole_mss); +#define V_tcp_v6pmtud_blackhole_mss VNET(tcp_v6pmtud_blackhole_mss) + int tcp_inpinfo_lock_add(struct inpcb *inp); void tcp_inpinfo_lock_del(struct inpcb *inp, struct tcpcb *tp); diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index 81725c7560fd..d9f21f37a30c 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifndef INVARIANTS +#include +#endif #include #include @@ -709,10 +712,29 @@ tcp_tw_2msl_scan(int reuse) INP_WLOCK(inp); tw = intotw(inp); if (in_pcbrele_wlocked(inp)) { - KASSERT(tw == NULL, ("%s: held last inp " - "reference but tw not NULL", __func__)); - INP_INFO_RUNLOCK(&V_tcbinfo); - continue; + if (__predict_true(tw == NULL)) { + INP_INFO_RUNLOCK(&V_tcbinfo); + continue; + } else { + /* This should not happen as in TIMEWAIT + * state the inp should not be destroyed + * before its tcptw. If INVARIANTS is + * defined panic. + */ +#ifdef INVARIANTS + panic("%s: Panic before an infinite " + "loop: INP_TIMEWAIT && (INP_FREED " + "|| inp last reference) && tw != " + "NULL", __func__); +#else + log(LOG_ERR, "%s: Avoid an infinite " + "loop: INP_TIMEWAIT && (INP_FREED " + "|| inp last reference) && tw != " + "NULL", __func__); +#endif + INP_INFO_RUNLOCK(&V_tcbinfo); + break; + } } if (tw == NULL) { diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 967a51398630..1210a32eb2b4 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -201,12 +201,6 @@ struct tcpcb { #endif /* _KERNEL || _WANT_TCPCB */ #ifdef _KERNEL -/* - * Kernel variables for tcp. - */ -VNET_DECLARE(int, tcp_do_rfc1323); -#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323) - struct tcptemp { u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */ struct tcphdr tt_t; @@ -701,50 +695,83 @@ SYSCTL_DECL(_net_inet_tcp_sack); MALLOC_DECLARE(M_TCPLOG); #endif -VNET_DECLARE(struct inpcbhead, tcb); /* queue of active tcpcb's */ -VNET_DECLARE(struct inpcbinfo, tcbinfo); extern int tcp_log_in_vain; -VNET_DECLARE(int, tcp_mssdflt); /* XXX */ -VNET_DECLARE(int, tcp_minmss); -VNET_DECLARE(int, tcp_delack_enabled); -VNET_DECLARE(int, tcp_do_rfc3390); -VNET_DECLARE(int, tcp_initcwnd_segments); -VNET_DECLARE(int, tcp_sendspace); -VNET_DECLARE(int, tcp_recvspace); + +/* + * Global TCP tunables shared between different stacks. + * Please keep the list sorted. + */ +VNET_DECLARE(int, drop_synfin); VNET_DECLARE(int, path_mtu_discovery); -VNET_DECLARE(int, tcp_do_rfc3465); VNET_DECLARE(int, tcp_abc_l_var); -#define V_tcb VNET(tcb) -#define V_tcbinfo VNET(tcbinfo) -#define V_tcp_mssdflt VNET(tcp_mssdflt) -#define V_tcp_minmss VNET(tcp_minmss) -#define V_tcp_delack_enabled VNET(tcp_delack_enabled) -#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390) -#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments) -#define V_tcp_sendspace VNET(tcp_sendspace) -#define V_tcp_recvspace VNET(tcp_recvspace) -#define V_path_mtu_discovery VNET(path_mtu_discovery) -#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465) -#define V_tcp_abc_l_var VNET(tcp_abc_l_var) - -VNET_DECLARE(int, tcp_do_sack); /* SACK enabled/disabled */ -VNET_DECLARE(int, tcp_sc_rst_sock_fail); /* RST on sock alloc failure */ -#define V_tcp_do_sack VNET(tcp_do_sack) -#define V_tcp_sc_rst_sock_fail VNET(tcp_sc_rst_sock_fail) - -VNET_DECLARE(int, tcp_do_ecn); /* TCP ECN enabled/disabled */ +VNET_DECLARE(int, tcp_autorcvbuf_inc); +VNET_DECLARE(int, tcp_autorcvbuf_max); +VNET_DECLARE(int, tcp_autosndbuf_inc); +VNET_DECLARE(int, tcp_autosndbuf_max); +VNET_DECLARE(int, tcp_delack_enabled); +VNET_DECLARE(int, tcp_do_autorcvbuf); +VNET_DECLARE(int, tcp_do_autosndbuf); +VNET_DECLARE(int, tcp_do_ecn); +VNET_DECLARE(int, tcp_do_rfc1323); +VNET_DECLARE(int, tcp_do_rfc3042); +VNET_DECLARE(int, tcp_do_rfc3390); +VNET_DECLARE(int, tcp_do_rfc3465); +VNET_DECLARE(int, tcp_do_rfc6675_pipe); +VNET_DECLARE(int, tcp_do_sack); +VNET_DECLARE(int, tcp_do_tso); VNET_DECLARE(int, tcp_ecn_maxretries); -#define V_tcp_do_ecn VNET(tcp_do_ecn) -#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) +VNET_DECLARE(int, tcp_initcwnd_segments); +VNET_DECLARE(int, tcp_insecure_rst); +VNET_DECLARE(int, tcp_insecure_syn); +VNET_DECLARE(int, tcp_minmss); +VNET_DECLARE(int, tcp_mssdflt); +VNET_DECLARE(int, tcp_recvspace); +VNET_DECLARE(int, tcp_sack_globalholes); +VNET_DECLARE(int, tcp_sack_globalmaxholes); +VNET_DECLARE(int, tcp_sack_maxholes); +VNET_DECLARE(int, tcp_sc_rst_sock_fail); +VNET_DECLARE(int, tcp_sendspace); +VNET_DECLARE(struct inpcbhead, tcb); +VNET_DECLARE(struct inpcbinfo, tcbinfo); + +#define V_drop_synfin VNET(drop_synfin) +#define V_path_mtu_discovery VNET(path_mtu_discovery) +#define V_tcb VNET(tcb) +#define V_tcbinfo VNET(tcbinfo) +#define V_tcp_abc_l_var VNET(tcp_abc_l_var) +#define V_tcp_autorcvbuf_inc VNET(tcp_autorcvbuf_inc) +#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) +#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc) +#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) +#define V_tcp_delack_enabled VNET(tcp_delack_enabled) +#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) +#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf) +#define V_tcp_do_ecn VNET(tcp_do_ecn) +#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323) +#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) +#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390) +#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465) +#define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) +#define V_tcp_do_sack VNET(tcp_do_sack) +#define V_tcp_do_tso VNET(tcp_do_tso) +#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) +#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments) +#define V_tcp_insecure_rst VNET(tcp_insecure_rst) +#define V_tcp_insecure_syn VNET(tcp_insecure_syn) +#define V_tcp_minmss VNET(tcp_minmss) +#define V_tcp_mssdflt VNET(tcp_mssdflt) +#define V_tcp_recvspace VNET(tcp_recvspace) +#define V_tcp_sack_globalholes VNET(tcp_sack_globalholes) +#define V_tcp_sack_globalmaxholes VNET(tcp_sack_globalmaxholes) +#define V_tcp_sack_maxholes VNET(tcp_sack_maxholes) +#define V_tcp_sc_rst_sock_fail VNET(tcp_sc_rst_sock_fail) +#define V_tcp_sendspace VNET(tcp_sendspace) #ifdef TCP_HHOOK VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]); #define V_tcp_hhh VNET(tcp_hhh) #endif -VNET_DECLARE(int, tcp_do_rfc6675_pipe); -#define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) - int tcp_addoptions(struct tcpopt *, u_char *); int tcp_ccalgounload(struct cc_algo *unload_algo); struct tcpcb * diff --git a/sys/netinet6/ip6_fastfwd.c b/sys/netinet6/ip6_fastfwd.c index 5358868b68af..e7a8a7b03749 100644 --- a/sys/netinet6/ip6_fastfwd.c +++ b/sys/netinet6/ip6_fastfwd.c @@ -194,6 +194,16 @@ ip6_tryforward(struct mbuf *m) in6_ifstat_inc(rcvif, ifs6_in_noroute); goto dropin; } + + /* + * Outgoing packet firewall processing. + */ + if (!PFIL_HOOKED(&V_inet6_pfil_hook)) + goto passout; + if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, + NULL) != 0 || m == NULL) + goto dropout; + /* * We used slow path processing for packets with scoped addresses. * So, scope checks aren't needed here. @@ -205,14 +215,6 @@ ip6_tryforward(struct mbuf *m) goto dropout; } - /* - * Outgoing packet firewall processing. - */ - if (!PFIL_HOOKED(&V_inet6_pfil_hook)) - goto passout; - if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, - NULL) != 0 || m == NULL) - goto dropout; /* * If packet filter sets the M_FASTFWD_OURS flag, this means * that new destination or next hop is our local address. diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index c88ca96f5c2f..a61eae1104db 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -229,6 +229,10 @@ sctp6_notify(struct sctp_inpcb *inp, } break; case ICMP6_PACKET_TOO_BIG: + if ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0) { + SCTP_TCB_UNLOCK(stcb); + break; + } if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { timer_stopped = 1; sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, diff --git a/sys/netinet6/send.c b/sys/netinet6/send.c index 66b36db7827b..df07c0f18b33 100644 --- a/sys/netinet6/send.c +++ b/sys/netinet6/send.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index a7615078d657..fd53da983c7c 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -149,6 +149,15 @@ sysctl_def_policy(SYSCTL_HANDLER_ARGS) * 0 take anything */ VNET_DEFINE(int, crypto_support) = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE; + +/* + * Use asynchronous mode to parallelize crypto jobs: + * + * 0 - disabled + * 1 - enabled + */ +VNET_DEFINE(int, async_crypto) = 0; + /* * TCP/UDP checksum handling policy for transport mode NAT-T (RFC3948) * @@ -195,6 +204,9 @@ SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, ecn, SYSCTL_INT(_net_inet_ipsec, OID_AUTO, crypto_support, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(crypto_support), 0, "Crypto driver selection."); +SYSCTL_INT(_net_inet_ipsec, OID_AUTO, async_crypto, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(async_crypto), 0, + "Use asynchronous mode to parallelize crypto jobs."); SYSCTL_INT(_net_inet_ipsec, OID_AUTO, check_policy_history, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(check_policy_history), 0, "Use strict check of inbound packets to security policy compliance."); diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index cbd9f7fbadc8..1e73c0133de1 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -283,6 +283,7 @@ VNET_DECLARE(int, ip4_ipsec_dfbit); VNET_DECLARE(int, ip4_ipsec_ecn); VNET_DECLARE(int, ip4_esp_randpad); VNET_DECLARE(int, crypto_support); +VNET_DECLARE(int, async_crypto); VNET_DECLARE(int, natt_cksum_policy); #define IPSECSTAT_INC(name) \ @@ -296,6 +297,7 @@ VNET_DECLARE(int, natt_cksum_policy); #define V_ip4_ipsec_ecn VNET(ip4_ipsec_ecn) #define V_ip4_esp_randpad VNET(ip4_esp_randpad) #define V_crypto_support VNET(crypto_support) +#define V_async_crypto VNET(async_crypto) #define V_natt_cksum_policy VNET(natt_cksum_policy) #define ipseclog(x) do { if (V_ipsec_debug) log x; } while (0) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 7a57a315c874..3c320cec116f 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -5100,7 +5100,7 @@ key_updateaddresses(struct socket *so, struct mbuf *m, newsav->natt = NULL; newsav->sah = sah; newsav->state = SADB_SASTATE_MATURE; - error = key_setnatt(sav, mhp); + error = key_setnatt(newsav, mhp); if (error != 0) goto fail; diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index fada7b7e005f..5d8c62bb7ff8 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -193,9 +193,9 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria) return EINVAL; } keylen = _KEYLEN(sav->key_auth); - if (keylen != thash->keysize && thash->keysize != 0) { + if (keylen > thash->keysize && thash->keysize != 0) { DPRINTF(("%s: invalid keylength %d, algorithm %s requires " - "keysize %d\n", __func__, + "keysize less than %d\n", __func__, keylen, thash->name, thash->keysize)); return EINVAL; } @@ -657,6 +657,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) /* Crypto operation descriptor. */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_CBIFSYNC; + if (V_async_crypto) + crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; crp->crp_buf = (caddr_t) m; crp->crp_callback = ah_input_cb; crp->crp_sid = cryptoid; @@ -1033,6 +1035,8 @@ ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, /* Crypto operation descriptor. */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_CBIFSYNC; + if (V_async_crypto) + crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; crp->crp_buf = (caddr_t) m; crp->crp_callback = ah_output_cb; crp->crp_sid = cryptoid; diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 39d5b8c79e02..02064a909d4b 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -385,6 +385,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) /* Crypto operation descriptor */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_CBIFSYNC; + if (V_async_crypto) + crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; crp->crp_buf = (caddr_t) m; crp->crp_callback = esp_input_cb; crp->crp_sid = cryptoid; @@ -841,6 +843,8 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, /* Crypto operation descriptor. */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_CBIFSYNC; + if (V_async_crypto) + crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; crp->crp_buf = (caddr_t) m; crp->crp_callback = esp_output_cb; crp->crp_opaque = (caddr_t) xd; diff --git a/sys/netpfil/ipfw/dn_sched_fifo.c b/sys/netpfil/ipfw/dn_sched_fifo.c index be51649fd921..d808825694b6 100644 --- a/sys/netpfil/ipfw/dn_sched_fifo.c +++ b/sys/netpfil/ipfw/dn_sched_fifo.c @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM diff --git a/sys/netpfil/ipfw/dn_sched_fq_codel.c b/sys/netpfil/ipfw/dn_sched_fq_codel.c index c78373004751..38b9379f52a5 100644 --- a/sys/netpfil/ipfw/dn_sched_fq_codel.c +++ b/sys/netpfil/ipfw/dn_sched_fq_codel.c @@ -218,13 +218,14 @@ fq_codel_classify_flow(struct mbuf *m, uint16_t fcount, struct fq_codel_si *si) uint8_t tuple[41]; uint16_t hash=0; + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); //#ifdef INET6 struct ip6_hdr *ip6; int isip6; - isip6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; + isip6 = (ip->ip_v == 6); if(isip6) { - ip6 = mtod(m, struct ip6_hdr *); + ip6 = (struct ip6_hdr *)ip; *((uint8_t *) &tuple[0]) = ip6->ip6_nxt; *((uint32_t *) &tuple[1]) = si->perturbation; memcpy(&tuple[5], ip6->ip6_src.s6_addr, 16); @@ -253,7 +254,6 @@ fq_codel_classify_flow(struct mbuf *m, uint16_t fcount, struct fq_codel_si *si) //#endif /* IPv4 */ - ip = mtod(m, struct ip *); *((uint8_t *) &tuple[0]) = ip->ip_p; *((uint32_t *) &tuple[1]) = si->perturbation; *((uint32_t *) &tuple[5]) = ip->ip_src.s_addr; diff --git a/sys/netpfil/ipfw/dn_sched_fq_pie.c b/sys/netpfil/ipfw/dn_sched_fq_pie.c index 5ee40069fa42..b6f235d8ba6d 100644 --- a/sys/netpfil/ipfw/dn_sched_fq_pie.c +++ b/sys/netpfil/ipfw/dn_sched_fq_pie.c @@ -792,13 +792,14 @@ fq_pie_classify_flow(struct mbuf *m, uint16_t fcount, struct fq_pie_si *si) uint8_t tuple[41]; uint16_t hash=0; + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); //#ifdef INET6 struct ip6_hdr *ip6; int isip6; - isip6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; + isip6 = (ip->ip_v == 6); if(isip6) { - ip6 = mtod(m, struct ip6_hdr *); + ip6 = (struct ip6_hdr *)ip; *((uint8_t *) &tuple[0]) = ip6->ip6_nxt; *((uint32_t *) &tuple[1]) = si->perturbation; memcpy(&tuple[5], ip6->ip6_src.s6_addr, 16); @@ -826,7 +827,6 @@ fq_pie_classify_flow(struct mbuf *m, uint16_t fcount, struct fq_pie_si *si) //#endif /* IPv4 */ - ip = mtod(m, struct ip *); *((uint8_t *) &tuple[0]) = ip->ip_p; *((uint32_t *) &tuple[1]) = si->perturbation; *((uint32_t *) &tuple[5]) = ip->ip_src.s_addr; diff --git a/sys/netpfil/ipfw/dn_sched_prio.c b/sys/netpfil/ipfw/dn_sched_prio.c index 915b4cb531c5..3d3dc87fd73e 100644 --- a/sys/netpfil/ipfw/dn_sched_prio.c +++ b/sys/netpfil/ipfw/dn_sched_prio.c @@ -32,13 +32,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM diff --git a/sys/netpfil/ipfw/dn_sched_qfq.c b/sys/netpfil/ipfw/dn_sched_qfq.c index 5e2549e8cfa1..1679c55541d3 100644 --- a/sys/netpfil/ipfw/dn_sched_qfq.c +++ b/sys/netpfil/ipfw/dn_sched_qfq.c @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM diff --git a/sys/netpfil/ipfw/dn_sched_rr.c b/sys/netpfil/ipfw/dn_sched_rr.c index e45ee63d52b7..099b71990152 100644 --- a/sys/netpfil/ipfw/dn_sched_rr.c +++ b/sys/netpfil/ipfw/dn_sched_rr.c @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM diff --git a/sys/netpfil/ipfw/dn_sched_wf2q.c b/sys/netpfil/ipfw/dn_sched_wf2q.c index 06f92a9c688b..631b6a7d569d 100644 --- a/sys/netpfil/ipfw/dn_sched_wf2q.c +++ b/sys/netpfil/ipfw/dn_sched_wf2q.c @@ -34,13 +34,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c index 831b909213dc..7295f7ba1101 100644 --- a/sys/netpfil/ipfw/ip_dn_io.c +++ b/sys/netpfil/ipfw/ip_dn_io.c @@ -236,28 +236,11 @@ SYSEND static void dummynet_send(struct mbuf *); -/* - * Packets processed by dummynet have an mbuf tag associated with - * them that carries their dummynet state. - * Outside dummynet, only the 'rule' field is relevant, and it must - * be at the beginning of the structure. - */ -struct dn_pkt_tag { - struct ipfw_rule_ref rule; /* matching rule */ - - /* second part, dummynet specific */ - int dn_dir; /* action when packet comes out.*/ - /* see ip_fw_private.h */ - uint64_t output_time; /* when the pkt is due for delivery*/ - struct ifnet *ifp; /* interface, for ip_output */ - struct _ip6dn_args ip6opt; /* XXX ipv6 options */ -}; - /* * Return the mbuf tag holding the dummynet state (it should * be the first one on the list). */ -static struct dn_pkt_tag * +struct dn_pkt_tag * dn_tag_get(struct mbuf *m) { struct m_tag *mtag = m_tag_first(m); @@ -448,7 +431,7 @@ int ecn_mark(struct mbuf* m) { struct ip *ip; - ip = mtod(m, struct ip *); + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); switch (ip->ip_v) { case IPVERSION: @@ -472,7 +455,7 @@ ecn_mark(struct mbuf* m) #ifdef INET6 case (IPV6_VERSION >> 4): { - struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + struct ip6_hdr *ip6 = (struct ip6_hdr *)ip; u_int32_t flowlabel; flowlabel = ntohl(ip6->ip6_flow); @@ -859,6 +842,7 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa) dt->ifp = fwa->oif; /* dt->output tame is updated as we move through */ dt->output_time = dn_cfg.curr_time; + dt->iphdr_off = (dir & PROTO_LAYER2) ? ETHER_HDR_LEN : 0; return 0; } diff --git a/sys/netpfil/ipfw/ip_dn_private.h b/sys/netpfil/ipfw/ip_dn_private.h index 2fce13667dae..5b3c05f57d95 100644 --- a/sys/netpfil/ipfw/ip_dn_private.h +++ b/sys/netpfil/ipfw/ip_dn_private.h @@ -367,6 +367,24 @@ enum { DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */ }; +/* + * Packets processed by dummynet have an mbuf tag associated with + * them that carries their dummynet state. + * Outside dummynet, only the 'rule' field is relevant, and it must + * be at the beginning of the structure. + */ +struct dn_pkt_tag { + struct ipfw_rule_ref rule; /* matching rule */ + + /* second part, dummynet specific */ + int dn_dir; /* action when packet comes out.*/ + /* see ip_fw_private.h */ + uint64_t output_time; /* when the pkt is due for delivery*/ + struct ifnet *ifp; /* interface, for ip_output */ + struct _ip6dn_args ip6opt; /* XXX ipv6 options */ + uint16_t iphdr_off; /* IP header offset for mtodo() */ +}; + extern struct dn_parms dn_cfg; //VNET_DECLARE(struct dn_parms, _base_dn_cfg); //#define dn_cfg VNET(_base_dn_cfg) @@ -374,6 +392,7 @@ extern struct dn_parms dn_cfg; int dummynet_io(struct mbuf **, int , struct ip_fw_args *); void dummynet_task(void *context, int pending); void dn_reschedule(void); +struct dn_pkt_tag * dn_tag_get(struct mbuf *m); struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *, struct ipfw_flow_id *); diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index a32261dac8a7..46c58bed5821 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -963,7 +963,7 @@ ipfw_chk(struct ip_fw_args *args) uint8_t proto; uint16_t src_port = 0, dst_port = 0; /* NOTE: host format */ struct in_addr src_ip, dst_ip; /* NOTE: network format */ - uint16_t iplen=0; + int iplen = 0; int pktlen; uint16_t etype = 0; /* Host order stored ether type */ @@ -1205,6 +1205,7 @@ do { \ args->f_id.src_ip = 0; args->f_id.dst_ip = 0; args->f_id.flow_id6 = ntohl(ip6->ip6_flow); + iplen = ntohs(ip6->ip6_plen) + sizeof(*ip6); } else if (pktlen >= sizeof(struct ip) && (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) { is_ipv4 = 1; @@ -1219,7 +1220,6 @@ do { \ dst_ip = ip->ip_dst; offset = ntohs(ip->ip_off) & IP_OFFMASK; iplen = ntohs(ip->ip_len); - pktlen = iplen < pktlen ? iplen : pktlen; if (offset == 0) { switch (proto) { @@ -1258,6 +1258,7 @@ do { \ args->f_id.dst_ip = ntohl(dst_ip.s_addr); } #undef PULLUP_TO + pktlen = iplen < pktlen ? iplen: pktlen; if (proto) { /* we may have port numbers, store them */ args->f_id.proto = proto; args->f_id.src_port = src_port = ntohs(src_port); @@ -1609,10 +1610,7 @@ do { \ case O_IP_SRC_ME: if (is_ipv4) { - struct ifnet *tif; - - INADDR_TO_IFP(src_ip, tif); - match = (tif != NULL); + match = in_localip(src_ip); break; } #ifdef INET6 @@ -1648,10 +1646,7 @@ do { \ case O_IP_DST_ME: if (is_ipv4) { - struct ifnet *tif; - - INADDR_TO_IFP(dst_ip, tif); - match = (tif != NULL); + match = in_localip(dst_ip); break; } #ifdef INET6 @@ -1669,8 +1664,8 @@ do { \ * to guarantee that we have a * packet with port info. */ - if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP) - && offset == 0) { + if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP || + proto==IPPROTO_SCTP) && offset == 0) { u_int16_t x = (cmd->opcode == O_IP_SRCPORT) ? src_port : dst_port ; @@ -1777,10 +1772,25 @@ do { \ uint16_t x; uint16_t *p; int i; +#ifdef INET6 + if (is_ipv6) { + struct ip6_hdr *ip6; + ip6 = (struct ip6_hdr *)ip; + if (ip6->ip6_plen == 0) { + /* + * Jumbo payload is not + * supported by this + * opcode. + */ + break; + } + x = iplen - hlen; + } else +#endif /* INET6 */ + x = iplen - (ip->ip_hl << 2); tcp = TCP(ulp); - x = iplen - - ((ip->ip_hl + tcp->th_off) << 2); + x -= tcp->th_off << 2; if (cmdlen == 1) { match = (cmd->arg1 == x); break; @@ -2448,6 +2458,7 @@ do { \ sa6->sin6_len = sizeof(*sa6); sa6->sin6_addr = TARG_VAL( chain, tablearg, nh6); + sa6->sin6_port = sa->sin_port; /* * Set sin6_scope_id only for * link-local unicast addresses. @@ -2461,6 +2472,8 @@ do { \ } else #endif { + args->hopstore.sin_port = + sa->sin_port; sa = args->next_hop = &args->hopstore; sa->sin_family = AF_INET; diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c index ebf345a45fb2..162d4e6ea08e 100644 --- a/sys/netpfil/ipfw/ip_fw_dynamic.c +++ b/sys/netpfil/ipfw/ip_fw_dynamic.c @@ -418,9 +418,7 @@ dyn_create(struct ip_fw_chain *ch, struct tid_info *ti, return (ENOSPC); } ipfw_objhash_add(ni, &obj->no); - IPFW_WLOCK(ch); SRV_OBJECT(ch, obj->no.kidx) = obj; - IPFW_WUNLOCK(ch); obj->no.refcnt++; *pkidx = obj->no.kidx; IPFW_UH_WUNLOCK(ch); @@ -440,10 +438,8 @@ dyn_destroy(struct ip_fw_chain *ch, struct named_object *no) no->name, no->etlv, no->kidx, no->refcnt)); DYN_DEBUG("kidx %d", no->kidx); - IPFW_WLOCK(ch); obj = SRV_OBJECT(ch, no->kidx); SRV_OBJECT(ch, no->kidx) = NULL; - IPFW_WUNLOCK(ch); ipfw_objhash_del(CHAIN_TO_SRV(ch), no); ipfw_objhash_free_idx(CHAIN_TO_SRV(ch), no->kidx); diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c index d3723e58ba3d..c7c7fa1e4824 100644 --- a/sys/netpfil/ipfw/ip_fw_table.c +++ b/sys/netpfil/ipfw/ip_fw_table.c @@ -1925,9 +1925,7 @@ create_table_internal(struct ip_fw_chain *ch, struct tid_info *ti, tc->no.kidx = kidx; tc->no.etlv = IPFW_TLV_TBL_NAME; - IPFW_WLOCK(ch); link_table(ch, tc); - IPFW_WUNLOCK(ch); } if (compat != 0) @@ -3229,7 +3227,6 @@ link_table(struct ip_fw_chain *ch, struct table_config *tc) uint16_t kidx; IPFW_UH_WLOCK_ASSERT(ch); - IPFW_WLOCK_ASSERT(ch); ni = CHAIN_TO_NI(ch); kidx = tc->no.kidx; diff --git a/sys/netpfil/ipfw/nat64/nat64lsn_control.c b/sys/netpfil/ipfw/nat64/nat64lsn_control.c index 3d79085b9da1..5787bdf79b5a 100644 --- a/sys/netpfil/ipfw/nat64/nat64lsn_control.c +++ b/sys/netpfil/ipfw/nat64/nat64lsn_control.c @@ -208,10 +208,7 @@ nat64lsn_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3, ipfw_objhash_add(CHAIN_TO_SRV(ch), &cfg->no); /* Okay, let's link data */ - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = cfg; - IPFW_WUNLOCK(ch); - nat64lsn_start_instance(cfg); IPFW_UH_WUNLOCK(ch); @@ -259,10 +256,7 @@ nat64lsn_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3, return (EBUSY); } - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = NULL; - IPFW_WUNLOCK(ch); - nat64lsn_detach_config(ch, cfg); IPFW_UH_WUNLOCK(ch); diff --git a/sys/netpfil/ipfw/nat64/nat64stl_control.c b/sys/netpfil/ipfw/nat64/nat64stl_control.c index d8599d961bf0..dd52e2c4c2d9 100644 --- a/sys/netpfil/ipfw/nat64/nat64stl_control.c +++ b/sys/netpfil/ipfw/nat64/nat64stl_control.c @@ -220,10 +220,7 @@ nat64stl_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3, error = nat64stl_create_internal(ch, cfg, uc); if (error == 0) { /* Okay, let's link data */ - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = cfg; - IPFW_WUNLOCK(ch); - IPFW_UH_WUNLOCK(ch); return (0); } @@ -342,10 +339,7 @@ nat64stl_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3, return (EBUSY); } - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = NULL; - IPFW_WUNLOCK(ch); - nat64stl_detach_config(ch, cfg); IPFW_UH_WUNLOCK(ch); diff --git a/sys/netpfil/ipfw/nptv6/nptv6.c b/sys/netpfil/ipfw/nptv6/nptv6.c index c720a336675f..302560ddaf77 100644 --- a/sys/netpfil/ipfw/nptv6/nptv6.c +++ b/sys/netpfil/ipfw/nptv6/nptv6.c @@ -560,9 +560,7 @@ nptv6_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3, return (ENOSPC); } ipfw_objhash_add(ni, &cfg->no); - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = cfg; - IPFW_WUNLOCK(ch); IPFW_UH_WUNLOCK(ch); return (0); } @@ -599,10 +597,7 @@ nptv6_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3, return (EBUSY); } - IPFW_WLOCK(ch); SRV_OBJECT(ch, cfg->no.kidx) = NULL; - IPFW_WUNLOCK(ch); - ipfw_objhash_del(CHAIN_TO_SRV(ch), &cfg->no); ipfw_objhash_free_idx(CHAIN_TO_SRV(ch), cfg->no.kidx); IPFW_UH_WUNLOCK(ch); diff --git a/sys/netsmb/smb_subr.c b/sys/netsmb/smb_subr.c index 2992f994b171..c4b97308d617 100644 --- a/sys/netsmb/smb_subr.c +++ b/sys/netsmb/smb_subr.c @@ -110,22 +110,11 @@ smb_strdup(const char *s) char * smb_strdupin(char *s, size_t maxlen) { - char *p, bt; + char *p; int error; - size_t len; - len = 0; - for (p = s; ;p++) { - if (copyin(p, &bt, 1)) - return NULL; - len++; - if (maxlen && len > maxlen) - return NULL; - if (bt == 0) - break; - } - p = malloc(len, M_SMBSTR, M_WAITOK); - error = copyin(s, p, len); + p = malloc(maxlen + 1, M_SMBSTR, M_WAITOK); + error = copyinstr(s, p, maxlen + 1, NULL); if (error) { free(p, M_SMBSTR); return (NULL); diff --git a/sys/ofed/drivers/infiniband/hw/mthca/mthca_provider.c b/sys/ofed/drivers/infiniband/hw/mthca/mthca_provider.c index adc24aae6e9b..264db51e7758 100644 --- a/sys/ofed/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/sys/ofed/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1297,6 +1297,25 @@ static int mthca_init_node_data(struct mthca_dev *dev) return err; } +static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num, + struct ib_port_immutable *immutable) +{ + struct ib_port_attr attr; + int err; + + immutable->core_cap_flags = RDMA_CORE_PORT_IBA_IB; + + err = ib_query_port(ibdev, port_num, &attr); + if (err) + return err; + + immutable->pkey_tbl_len = attr.pkey_tbl_len; + immutable->gid_tbl_len = attr.gid_tbl_len; + immutable->max_mad_size = IB_MGMT_MAD_SIZE; + + return 0; +} + int mthca_register_device(struct mthca_dev *dev) { int ret; @@ -1376,6 +1395,7 @@ int mthca_register_device(struct mthca_dev *dev) dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr; dev->ib_dev.reg_user_mr = mthca_reg_user_mr; dev->ib_dev.dereg_mr = mthca_dereg_mr; + dev->ib_dev.get_port_immutable = mthca_port_immutable; if (dev->mthca_flags & MTHCA_FLAG_FMR) { dev->ib_dev.alloc_fmr = mthca_alloc_fmr; diff --git a/sys/ofed/include/rdma/ib_addr.h b/sys/ofed/include/rdma/ib_addr.h index 1dbe844cc8d0..2c27977eb295 100644 --- a/sys/ofed/include/rdma/ib_addr.h +++ b/sys/ofed/include/rdma/ib_addr.h @@ -177,6 +177,12 @@ static inline int rdma_ip2gid(const struct sockaddr *addr, union ib_gid *gid) break; case AF_INET6: memcpy(gid->raw, &((const struct sockaddr_in6 *)addr)->sin6_addr, 16); + /* make sure scope ID gets zeroed inside GID */ + if (IN6_IS_SCOPE_LINKLOCAL((struct in6_addr *)gid->raw) || + IN6_IS_ADDR_MC_INTFACELOCAL((struct in6_addr *)gid->raw)) { + gid->raw[2] = 0; + gid->raw[3] = 0; + } break; default: return -EINVAL; diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c index 60ab34c8dc60..f4e71e7189e4 100644 --- a/sys/opencrypto/crypto.c +++ b/sys/opencrypto/crypto.c @@ -70,7 +70,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include @@ -135,26 +137,51 @@ static int crypto_drivers_num = 0; * operations. */ static int crp_sleep = 0; -static TAILQ_HEAD(,cryptop) crp_q; /* request queues */ +static TAILQ_HEAD(cryptop_q ,cryptop) crp_q; /* request queues */ static TAILQ_HEAD(,cryptkop) crp_kq; static struct mtx crypto_q_mtx; #define CRYPTO_Q_LOCK() mtx_lock(&crypto_q_mtx) #define CRYPTO_Q_UNLOCK() mtx_unlock(&crypto_q_mtx) /* - * There are two queues for processing completed crypto requests; one - * for the symmetric and one for the asymmetric ops. We only need one - * but have two to avoid type futzing (cryptop vs. cryptkop). A single - * mutex is used to lock access to both queues. Note that this lock - * must be separate from the lock on request queues to insure driver - * callbacks don't generate lock order reversals. + * Taskqueue used to dispatch the crypto requests + * that have the CRYPTO_F_ASYNC flag */ -static TAILQ_HEAD(,cryptop) crp_ret_q; /* callback queues */ -static TAILQ_HEAD(,cryptkop) crp_ret_kq; -static struct mtx crypto_ret_q_mtx; -#define CRYPTO_RETQ_LOCK() mtx_lock(&crypto_ret_q_mtx) -#define CRYPTO_RETQ_UNLOCK() mtx_unlock(&crypto_ret_q_mtx) -#define CRYPTO_RETQ_EMPTY() (TAILQ_EMPTY(&crp_ret_q) && TAILQ_EMPTY(&crp_ret_kq)) +static struct taskqueue *crypto_tq; + +/* + * Crypto seq numbers are operated on with modular arithmetic + */ +#define CRYPTO_SEQ_GT(a,b) ((int)((a)-(b)) > 0) + +struct crypto_ret_worker { + struct mtx crypto_ret_mtx; + + TAILQ_HEAD(,cryptop) crp_ordered_ret_q; /* ordered callback queue for symetric jobs */ + TAILQ_HEAD(,cryptop) crp_ret_q; /* callback queue for symetric jobs */ + TAILQ_HEAD(,cryptkop) crp_ret_kq; /* callback queue for asym jobs */ + + u_int32_t reorder_ops; /* total ordered sym jobs received */ + u_int32_t reorder_cur_seq; /* current sym job dispatched */ + + struct proc *cryptoretproc; +}; +static struct crypto_ret_worker *crypto_ret_workers = NULL; + +#define CRYPTO_RETW(i) (&crypto_ret_workers[i]) +#define CRYPTO_RETW_ID(w) ((w) - crypto_ret_workers) +#define FOREACH_CRYPTO_RETW(w) \ + for (w = crypto_ret_workers; w < crypto_ret_workers + crypto_workers_num; ++w) + +#define CRYPTO_RETW_LOCK(w) mtx_lock(&w->crypto_ret_mtx) +#define CRYPTO_RETW_UNLOCK(w) mtx_unlock(&w->crypto_ret_mtx) +#define CRYPTO_RETW_EMPTY(w) \ + (TAILQ_EMPTY(&w->crp_ret_q) && TAILQ_EMPTY(&w->crp_ret_kq) && TAILQ_EMPTY(&w->crp_ordered_ret_q)) + +static int crypto_workers_num = 0; +SYSCTL_INT(_kern, OID_AUTO, crypto_workers_num, CTLFLAG_RDTUN, + &crypto_workers_num, 0, + "Number of crypto workers used to dispatch crypto jobs"); static uma_zone_t cryptop_zone; static uma_zone_t cryptodesc_zone; @@ -172,11 +199,12 @@ MALLOC_DEFINE(M_CRYPTO_DATA, "crypto", "crypto session records"); static void crypto_proc(void); static struct proc *cryptoproc; -static void crypto_ret_proc(void); -static struct proc *cryptoretproc; +static void crypto_ret_proc(struct crypto_ret_worker *ret_worker); static void crypto_destroy(void); static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint); static int crypto_kinvoke(struct cryptkop *krp, int flags); +static void crypto_task_invoke(void *ctx, int pending); +static void crypto_batch_enqueue(struct cryptop *crp); static struct cryptostats cryptostats; SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats, @@ -222,6 +250,7 @@ struct keybuf * get_keybuf(void) { static int crypto_init(void) { + struct crypto_ret_worker *ret_worker; int error; mtx_init(&crypto_drivers_mtx, "crypto", "crypto driver table", @@ -231,10 +260,6 @@ crypto_init(void) TAILQ_INIT(&crp_kq); mtx_init(&crypto_q_mtx, "crypto", "crypto op queues", MTX_DEF); - TAILQ_INIT(&crp_ret_q); - TAILQ_INIT(&crp_ret_kq); - mtx_init(&crypto_ret_q_mtx, "crypto", "crypto return queues", MTX_DEF); - cryptop_zone = uma_zcreate("cryptop", sizeof (struct cryptop), 0, 0, 0, 0, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); @@ -256,6 +281,20 @@ crypto_init(void) goto bad; } + if (crypto_workers_num < 1 || crypto_workers_num > mp_ncpus) + crypto_workers_num = mp_ncpus; + + crypto_tq = taskqueue_create("crypto", M_WAITOK|M_ZERO, + taskqueue_thread_enqueue, &crypto_tq); + if (crypto_tq == NULL) { + printf("crypto init: cannot setup crypto taskqueue\n"); + error = ENOMEM; + goto bad; + } + + taskqueue_start_threads(&crypto_tq, crypto_workers_num, PRI_MIN_KERN, + "crypto"); + error = kproc_create((void (*)(void *)) crypto_proc, NULL, &cryptoproc, 0, 0, "crypto"); if (error) { @@ -264,15 +303,35 @@ crypto_init(void) goto bad; } - error = kproc_create((void (*)(void *)) crypto_ret_proc, NULL, - &cryptoretproc, 0, 0, "crypto returns"); - if (error) { - printf("crypto_init: cannot start cryptoret thread; error %d", - error); + crypto_ret_workers = malloc(crypto_workers_num * sizeof(struct crypto_ret_worker), + M_CRYPTO_DATA, M_NOWAIT|M_ZERO); + if (crypto_ret_workers == NULL) { + error = ENOMEM; + printf("crypto_init: cannot allocate ret workers\n"); goto bad; } - keybuf_init(); + + FOREACH_CRYPTO_RETW(ret_worker) { + TAILQ_INIT(&ret_worker->crp_ordered_ret_q); + TAILQ_INIT(&ret_worker->crp_ret_q); + TAILQ_INIT(&ret_worker->crp_ret_kq); + + ret_worker->reorder_ops = 0; + ret_worker->reorder_cur_seq = 0; + + mtx_init(&ret_worker->crypto_ret_mtx, "crypto", "crypto return queues", MTX_DEF); + + error = kproc_create((void (*)(void *)) crypto_ret_proc, ret_worker, + &ret_worker->cryptoretproc, 0, 0, "crypto returns %td", CRYPTO_RETW_ID(ret_worker)); + if (error) { + printf("crypto_init: cannot start cryptoret thread; error %d", + error); + goto bad; + } + } + + keybuf_init(); return 0; bad: @@ -308,12 +367,17 @@ crypto_terminate(struct proc **pp, void *q) static void crypto_destroy(void) { + struct crypto_ret_worker *ret_worker; + /* * Terminate any crypto threads. */ + if (crypto_tq != NULL) + taskqueue_drain_all(crypto_tq); CRYPTO_DRIVER_LOCK(); crypto_terminate(&cryptoproc, &crp_q); - crypto_terminate(&cryptoretproc, &crp_ret_q); + FOREACH_CRYPTO_RETW(ret_worker) + crypto_terminate(&ret_worker->cryptoretproc, &ret_worker->crp_ret_q); CRYPTO_DRIVER_UNLOCK(); /* XXX flush queues??? */ @@ -329,7 +393,11 @@ crypto_destroy(void) if (cryptop_zone != NULL) uma_zdestroy(cryptop_zone); mtx_destroy(&crypto_q_mtx); - mtx_destroy(&crypto_ret_q_mtx); + FOREACH_CRYPTO_RETW(ret_worker) + mtx_destroy(&ret_worker->crypto_ret_mtx); + free(crypto_ret_workers, M_CRYPTO_DATA); + if (crypto_tq != NULL) + taskqueue_free(crypto_tq); mtx_destroy(&crypto_drivers_mtx); } @@ -460,7 +528,7 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid) CRYPTDEB("dev newsession failed"); } else { CRYPTDEB("no driver"); - err = EINVAL; + err = EOPNOTSUPP; } CRYPTO_DRIVER_UNLOCK(); return err; @@ -572,7 +640,7 @@ crypto_get_driverid(device_t dev, int flags) crypto_drivers[i].cc_dev = dev; crypto_drivers[i].cc_flags = flags; if (bootverbose) - printf("crypto: assign %s driver id %u, flags %u\n", + printf("crypto: assign %s driver id %u, flags 0x%x\n", device_get_nameunit(dev), i, flags); CRYPTO_DRIVER_UNLOCK(); @@ -828,9 +896,26 @@ crypto_dispatch(struct cryptop *crp) binuptime(&crp->crp_tstamp); #endif - hid = CRYPTO_SESID2HID(crp->crp_sid); + if (CRYPTOP_ASYNC(crp)) { + if (crp->crp_flags & CRYPTO_F_ASYNC_KEEPORDER) { + struct crypto_ret_worker *ret_worker; + + crp->crp_retw_id = crp->crp_sid % crypto_workers_num; + ret_worker = CRYPTO_RETW(crp->crp_retw_id); + + CRYPTO_RETW_LOCK(ret_worker); + crp->crp_seq = ret_worker->reorder_ops++; + CRYPTO_RETW_UNLOCK(ret_worker); + } + + TASK_INIT(&crp->crp_task, 0, crypto_task_invoke, crp); + taskqueue_enqueue(crypto_tq, &crp->crp_task); + return (0); + } if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) { + hid = CRYPTO_SESID2HID(crp->crp_sid); + /* * Caller marked the request to be processed * immediately; dispatch it directly to the @@ -849,12 +934,19 @@ crypto_dispatch(struct cryptop *crp) */ } } + crypto_batch_enqueue(crp); + return 0; +} + +void +crypto_batch_enqueue(struct cryptop *crp) +{ + CRYPTO_Q_LOCK(); TAILQ_INSERT_TAIL(&crp_q, crp, crp_next); if (crp_sleep) wakeup_one(&crp_q); CRYPTO_Q_UNLOCK(); - return 0; } /* @@ -1035,6 +1127,23 @@ crypto_tstat(struct cryptotstat *ts, struct bintime *bt) } #endif +static void +crypto_task_invoke(void *ctx, int pending) +{ + struct cryptocap *cap; + struct cryptop *crp; + int hid, result; + + crp = (struct cryptop *)ctx; + + hid = CRYPTO_SESID2HID(crp->crp_sid); + cap = crypto_checkdriver(hid); + + result = crypto_invoke(cap, crp, 0); + if (result == ERESTART) + crypto_batch_enqueue(crp); +} + /* * Dispatch a crypto request to the appropriate crypto devices. */ @@ -1097,6 +1206,7 @@ crypto_freereq(struct cryptop *crp) #ifdef DIAGNOSTIC { struct cryptop *crp2; + struct crypto_ret_worker *ret_worker; CRYPTO_Q_LOCK(); TAILQ_FOREACH(crp2, &crp_q, crp_next) { @@ -1105,13 +1215,16 @@ crypto_freereq(struct cryptop *crp) crp)); } CRYPTO_Q_UNLOCK(); - CRYPTO_RETQ_LOCK(); - TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) { - KASSERT(crp2 != crp, - ("Freeing cryptop from the return queue (%p).", - crp)); + + FOREACH_CRYPTO_RETW(ret_worker) { + CRYPTO_RETW_LOCK(ret_worker); + TAILQ_FOREACH(crp2, &ret_worker->crp_ret_q, crp_next) { + KASSERT(crp2 != crp, + ("Freeing cryptop from the return queue (%p).", + crp)); + } + CRYPTO_RETW_UNLOCK(ret_worker); } - CRYPTO_RETQ_UNLOCK(); } #endif @@ -1169,9 +1282,10 @@ crypto_done(struct cryptop *crp) * doing extraneous context switches; the latter is mostly * used with the software crypto driver. */ - if ((crp->crp_flags & CRYPTO_F_CBIMM) || + if (!CRYPTOP_ASYNC_KEEPORDER(crp) && + ((crp->crp_flags & CRYPTO_F_CBIMM) || ((crp->crp_flags & CRYPTO_F_CBIFSYNC) && - (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) { + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC)))) { /* * Do the callback directly. This is ok when the * callback routine does very little (e.g. the @@ -1192,14 +1306,45 @@ crypto_done(struct cryptop *crp) #endif crp->crp_callback(crp); } else { + struct crypto_ret_worker *ret_worker; + bool wake; + + ret_worker = CRYPTO_RETW(crp->crp_retw_id); + wake = false; + /* * Normal case; queue the callback for the thread. */ - CRYPTO_RETQ_LOCK(); - if (CRYPTO_RETQ_EMPTY()) - wakeup_one(&crp_ret_q); /* shared wait channel */ - TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next); - CRYPTO_RETQ_UNLOCK(); + CRYPTO_RETW_LOCK(ret_worker); + if (CRYPTOP_ASYNC_KEEPORDER(crp)) { + struct cryptop *tmp; + + TAILQ_FOREACH_REVERSE(tmp, &ret_worker->crp_ordered_ret_q, + cryptop_q, crp_next) { + if (CRYPTO_SEQ_GT(crp->crp_seq, tmp->crp_seq)) { + TAILQ_INSERT_AFTER(&ret_worker->crp_ordered_ret_q, + tmp, crp, crp_next); + break; + } + } + if (tmp == NULL) { + TAILQ_INSERT_HEAD(&ret_worker->crp_ordered_ret_q, + crp, crp_next); + } + + if (crp->crp_seq == ret_worker->reorder_cur_seq) + wake = true; + } + else { + if (CRYPTO_RETW_EMPTY(ret_worker)) + wake = true; + + TAILQ_INSERT_TAIL(&ret_worker->crp_ret_q, crp, crp_next); + } + + if (wake) + wakeup_one(&ret_worker->crp_ret_q); /* shared wait channel */ + CRYPTO_RETW_UNLOCK(ret_worker); } } @@ -1209,6 +1354,7 @@ crypto_done(struct cryptop *crp) void crypto_kdone(struct cryptkop *krp) { + struct crypto_ret_worker *ret_worker; struct cryptocap *cap; if (krp->krp_status != 0) @@ -1223,11 +1369,14 @@ crypto_kdone(struct cryptkop *krp) crypto_remove(cap); } CRYPTO_DRIVER_UNLOCK(); - CRYPTO_RETQ_LOCK(); - if (CRYPTO_RETQ_EMPTY()) - wakeup_one(&crp_ret_q); /* shared wait channel */ - TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next); - CRYPTO_RETQ_UNLOCK(); + + ret_worker = CRYPTO_RETW(0); + + CRYPTO_RETW_LOCK(ret_worker); + if (CRYPTO_RETW_EMPTY(ret_worker)) + wakeup_one(&ret_worker->crp_ret_q); /* shared wait channel */ + TAILQ_INSERT_TAIL(&ret_worker->crp_ret_kq, krp, krp_next); + CRYPTO_RETW_UNLOCK(ret_worker); } int @@ -1427,24 +1576,36 @@ crypto_proc(void) * callbacks typically are expensive and would slow interrupt handling. */ static void -crypto_ret_proc(void) +crypto_ret_proc(struct crypto_ret_worker *ret_worker) { struct cryptop *crpt; struct cryptkop *krpt; - CRYPTO_RETQ_LOCK(); + CRYPTO_RETW_LOCK(ret_worker); for (;;) { /* Harvest return q's for completed ops */ - crpt = TAILQ_FIRST(&crp_ret_q); - if (crpt != NULL) - TAILQ_REMOVE(&crp_ret_q, crpt, crp_next); + crpt = TAILQ_FIRST(&ret_worker->crp_ordered_ret_q); + if (crpt != NULL) { + if (crpt->crp_seq == ret_worker->reorder_cur_seq) { + TAILQ_REMOVE(&ret_worker->crp_ordered_ret_q, crpt, crp_next); + ret_worker->reorder_cur_seq++; + } else { + crpt = NULL; + } + } - krpt = TAILQ_FIRST(&crp_ret_kq); + if (crpt == NULL) { + crpt = TAILQ_FIRST(&ret_worker->crp_ret_q); + if (crpt != NULL) + TAILQ_REMOVE(&ret_worker->crp_ret_q, crpt, crp_next); + } + + krpt = TAILQ_FIRST(&ret_worker->crp_ret_kq); if (krpt != NULL) - TAILQ_REMOVE(&crp_ret_kq, krpt, krp_next); + TAILQ_REMOVE(&ret_worker->crp_ret_kq, krpt, krp_next); if (crpt != NULL || krpt != NULL) { - CRYPTO_RETQ_UNLOCK(); + CRYPTO_RETW_UNLOCK(ret_worker); /* * Run callbacks unlocked. */ @@ -1466,22 +1627,22 @@ crypto_ret_proc(void) } if (krpt != NULL) krpt->krp_callback(krpt); - CRYPTO_RETQ_LOCK(); + CRYPTO_RETW_LOCK(ret_worker); } else { /* * Nothing more to be processed. Sleep until we're * woken because there are more returns to process. */ - msleep(&crp_ret_q, &crypto_ret_q_mtx, PWAIT, + msleep(&ret_worker->crp_ret_q, &ret_worker->crypto_ret_mtx, PWAIT, "crypto_ret_wait", 0); - if (cryptoretproc == NULL) + if (ret_worker->cryptoretproc == NULL) break; cryptostats.cs_rets++; } } - CRYPTO_RETQ_UNLOCK(); + CRYPTO_RETW_UNLOCK(ret_worker); - crypto_finis(&crp_ret_q); + crypto_finis(&ret_worker->crp_ret_q); } #ifdef DDB @@ -1516,6 +1677,7 @@ db_show_drivers(void) DB_SHOW_COMMAND(crypto, db_show_crypto) { struct cryptop *crp; + struct crypto_ret_worker *ret_worker; db_show_drivers(); db_printf("\n"); @@ -1534,16 +1696,19 @@ DB_SHOW_COMMAND(crypto, db_show_crypto) , crp->crp_callback ); } - if (!TAILQ_EMPTY(&crp_ret_q)) { - db_printf("\n%4s %4s %4s %8s\n", - "HID", "Etype", "Flags", "Callback"); - TAILQ_FOREACH(crp, &crp_ret_q, crp_next) { - db_printf("%4u %4u %04x %8p\n" - , (int) CRYPTO_SESID2HID(crp->crp_sid) - , crp->crp_etype - , crp->crp_flags - , crp->crp_callback - ); + FOREACH_CRYPTO_RETW(ret_worker) { + db_printf("\n%8s %4s %4s %4s %8s\n", + "ret_worker", "HID", "Etype", "Flags", "Callback"); + if (!TAILQ_EMPTY(&ret_worker->crp_ret_q)) { + TAILQ_FOREACH(crp, &ret_worker->crp_ret_q, crp_next) { + db_printf("%8td %4u %4u %04x %8p\n" + , CRYPTO_RETW_ID(ret_worker) + , (int) CRYPTO_SESID2HID(crp->crp_sid) + , crp->crp_etype + , crp->crp_flags + , crp->crp_callback + ); + } } } } @@ -1551,6 +1716,7 @@ DB_SHOW_COMMAND(crypto, db_show_crypto) DB_SHOW_COMMAND(kcrypto, db_show_kcrypto) { struct cryptkop *krp; + struct crypto_ret_worker *ret_worker; db_show_drivers(); db_printf("\n"); @@ -1566,10 +1732,12 @@ DB_SHOW_COMMAND(kcrypto, db_show_kcrypto) , krp->krp_callback ); } - if (!TAILQ_EMPTY(&crp_ret_q)) { + + ret_worker = CRYPTO_RETW(0); + if (!TAILQ_EMPTY(&ret_worker->crp_ret_q)) { db_printf("%4s %5s %8s %4s %8s\n", "Op", "Status", "CRID", "HID", "Callback"); - TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) { + TAILQ_FOREACH(krp, &ret_worker->crp_ret_kq, krp_next) { db_printf("%4u %5u %08x %4u %8p\n" , krp->krp_op , krp->krp_status diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index bda77c79b969..d73e09fcb6a5 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -520,7 +520,8 @@ cryptof_ioctl( if (thash) { cria.cri_alg = thash->type; cria.cri_klen = sop->mackeylen * 8; - if (sop->mackeylen != thash->keysize) { + if (thash->keysize != 0 && + sop->mackeylen > thash->keysize) { CRYPTDEB("invalid mac key length"); error = EINVAL; goto bail; @@ -731,18 +732,22 @@ cryptodev_op( goto bail; } - if (cse->thash) { - crda = crp->crp_desc; - if (cse->txform) - crde = crda->crd_next; - } else { - if (cse->txform) + if (cse->thash && cse->txform) { + if (cop->flags & COP_F_CIPHER_FIRST) { crde = crp->crp_desc; - else { - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - error = EINVAL; - goto bail; + crda = crde->crd_next; + } else { + crda = crp->crp_desc; + crde = crda->crd_next; } + } else if (cse->thash) { + crda = crp->crp_desc; + } else if (cse->txform) { + crde = crp->crp_desc; + } else { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + error = EINVAL; + goto bail; } if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, @@ -898,7 +903,7 @@ cryptodev_aead( uio->uio_iov = &cse->iovec; uio->uio_iovcnt = 1; uio->uio_offset = 0; - uio->uio_resid = caead->len + caead->aadlen + cse->thash->hashsize; + uio->uio_resid = caead->aadlen + caead->len + cse->thash->hashsize; uio->uio_segflg = UIO_SYSSPACE; uio->uio_rw = UIO_WRITE; uio->uio_td = td; @@ -913,20 +918,33 @@ cryptodev_aead( goto bail; } - crda = crp->crp_desc; - crde = crda->crd_next; + if (caead->flags & COP_F_CIPHER_FIRST) { + crde = crp->crp_desc; + crda = crde->crd_next; + } else { + crda = crp->crp_desc; + crde = crda->crd_next; + } - if ((error = copyin(caead->src, cse->uio.uio_iov[0].iov_base, - caead->len))) + if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base, + caead->aadlen))) goto bail; - if ((error = copyin(caead->aad, (char *)cse->uio.uio_iov[0].iov_base + - caead->len, caead->aadlen))) + if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base + + caead->aadlen, caead->len))) goto bail; - crda->crd_skip = caead->len; - crda->crd_len = caead->aadlen; - crda->crd_inject = caead->len + caead->aadlen; + /* + * For GCM, crd_len covers only the AAD. For other ciphers + * chained with an HMAC, crd_len covers both the AAD and the + * cipher text. + */ + crda->crd_skip = 0; + if (cse->cipher == CRYPTO_AES_NIST_GCM_16) + crda->crd_len = caead->aadlen; + else + crda->crd_len = caead->aadlen + caead->len; + crda->crd_inject = caead->aadlen + caead->len; crda->crd_alg = cse->mac; crda->crd_key = cse->mackey; @@ -936,15 +954,15 @@ cryptodev_aead( crde->crd_flags |= CRD_F_ENCRYPT; else crde->crd_flags &= ~CRD_F_ENCRYPT; - /* crde->crd_skip set below */ + crde->crd_skip = caead->aadlen; crde->crd_len = caead->len; - crde->crd_inject = 0; + crde->crd_inject = caead->aadlen; crde->crd_alg = cse->cipher; crde->crd_key = cse->key; crde->crd_klen = cse->keylen * 8; - crp->crp_ilen = caead->len + caead->aadlen; + crp->crp_ilen = caead->aadlen + caead->len; crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH); crp->crp_buf = (caddr_t)&cse->uio.uio_iov; @@ -962,10 +980,9 @@ cryptodev_aead( goto bail; bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen); crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; - crde->crd_skip = 0; } else { crde->crd_flags |= CRD_F_IV_PRESENT; - crde->crd_skip = cse->txform->blocksize; + crde->crd_skip += cse->txform->blocksize; crde->crd_len -= cse->txform->blocksize; } @@ -1005,12 +1022,13 @@ cryptodev_aead( goto bail; } - if (caead->dst && (error = copyout(cse->uio.uio_iov[0].iov_base, - caead->dst, caead->len))) + if (caead->dst && (error = copyout( + (caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, + caead->len))) goto bail; if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + - caead->len + caead->aadlen, caead->tag, cse->thash->hashsize))) + caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) goto bail; bail: diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index ca584694b7c5..cfbda0684ee0 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -63,6 +63,7 @@ #define _CRYPTO_CRYPTO_H_ #include +#include /* Some initial values */ #define CRYPTO_DRIVERS_INITIAL 4 @@ -95,13 +96,6 @@ #define HMAC_IPAD_VAL 0x36 #define HMAC_OPAD_VAL 0x5C /* HMAC Key Length */ -#define NULL_HMAC_KEY_LEN 0 -#define MD5_HMAC_KEY_LEN 16 -#define SHA1_HMAC_KEY_LEN 20 -#define RIPEMD160_HMAC_KEY_LEN 20 -#define SHA2_256_HMAC_KEY_LEN 32 -#define SHA2_384_HMAC_KEY_LEN 48 -#define SHA2_512_HMAC_KEY_LEN 64 #define AES_128_GMAC_KEY_LEN 16 #define AES_192_GMAC_KEY_LEN 24 #define AES_256_GMAC_KEY_LEN 32 @@ -238,7 +232,8 @@ struct crypt_op { #define COP_ENCRYPT 1 #define COP_DECRYPT 2 u_int16_t flags; -#define COP_F_BATCH 0x0008 /* Batch op if possible */ +#define COP_F_CIPHER_FIRST 0x0001 /* Cipher before MAC. */ +#define COP_F_BATCH 0x0008 /* Batch op if possible */ u_int len; c_caddr_t src; /* become iov[] inside kernel */ caddr_t dst; @@ -397,6 +392,8 @@ struct cryptodesc { struct cryptop { TAILQ_ENTRY(cryptop) crp_next; + struct task crp_task; + u_int64_t crp_sid; /* Session ID */ int crp_ilen; /* Input data total length */ int crp_olen; /* Result total length */ @@ -419,6 +416,14 @@ struct cryptop { #define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */ #define CRYPTO_F_DONE 0x0020 /* Operation completed */ #define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */ +#define CRYPTO_F_ASYNC 0x0080 /* Dispatch crypto jobs on several threads + * if op is synchronous + */ +#define CRYPTO_F_ASYNC_KEEPORDER 0x0100 /* + * Dispatch the crypto jobs in the same + * order there are submitted. Applied only + * if CRYPTO_F_ASYNC flags is set + */ caddr_t crp_buf; /* Data to be processed */ caddr_t crp_opaque; /* Opaque pointer, passed along */ @@ -427,8 +432,20 @@ struct cryptop { int (*crp_callback)(struct cryptop *); /* Callback function */ struct bintime crp_tstamp; /* performance time stamp */ + uint32_t crp_seq; /* used for ordered dispatch */ + uint32_t crp_retw_id; /* + * the return worker to be used, + * used for ordered dispatch + */ }; +#define CRYPTOP_ASYNC(crp) \ + (((crp)->crp_flags & CRYPTO_F_ASYNC) && \ + CRYPTO_SESID2CAPS((crp)->crp_sid) & CRYPTOCAP_F_SYNC) +#define CRYPTOP_ASYNC_KEEPORDER(crp) \ + (CRYPTOP_ASYNC(crp) && \ + (crp)->crp_flags & CRYPTO_F_ASYNC_KEEPORDER) + #define CRYPTO_BUF_CONTIG 0x0 #define CRYPTO_BUF_IOV 0x1 #define CRYPTO_BUF_MBUF 0x2 diff --git a/sys/opencrypto/xform_md5.c b/sys/opencrypto/xform_md5.c index 3a8751d9c020..47dfc75c5b54 100644 --- a/sys/opencrypto/xform_md5.c +++ b/sys/opencrypto/xform_md5.c @@ -57,17 +57,27 @@ static int MD5Update_int(void *, const u_int8_t *, u_int16_t); /* Authentication instances */ struct auth_hash auth_hash_hmac_md5 = { - CRYPTO_MD5_HMAC, "HMAC-MD5", - MD5_HMAC_KEY_LEN, MD5_HASH_LEN, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN, - (void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int, - (void (*) (u_int8_t *, void *)) MD5Final + .type = CRYPTO_MD5_HMAC, + .name = "HMAC-MD5", + .keysize = MD5_HMAC_BLOCK_LEN, + .hashsize = MD5_HASH_LEN, + .ctxsize = sizeof(MD5_CTX), + .blocksize = MD5_HMAC_BLOCK_LEN, + .Init = (void (*) (void *)) MD5Init, + .Update = MD5Update_int, + .Final = (void (*) (u_int8_t *, void *)) MD5Final, }; struct auth_hash auth_hash_key_md5 = { - CRYPTO_MD5_KPDK, "Keyed MD5", - NULL_HMAC_KEY_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0, - (void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int, - (void (*)(u_int8_t *, void *)) MD5Final + .type = CRYPTO_MD5_KPDK, + .name = "Keyed MD5", + .keysize = 0, + .hashsize = MD5_KPDK_HASH_LEN, + .ctxsize = sizeof(MD5_CTX), + .blocksize = 0, + .Init = (void (*)(void *)) MD5Init, + .Update = MD5Update_int, + .Final = (void (*)(u_int8_t *, void *)) MD5Final, }; /* diff --git a/sys/opencrypto/xform_null.c b/sys/opencrypto/xform_null.c index 74f410cba945..3c499b31ccd1 100644 --- a/sys/opencrypto/xform_null.c +++ b/sys/opencrypto/xform_null.c @@ -76,10 +76,18 @@ struct enc_xform enc_xform_null = { }; /* Authentication instances */ -struct auth_hash auth_hash_null = { /* NB: context isn't used */ - CRYPTO_NULL_HMAC, "NULL-HMAC", - NULL_HMAC_KEY_LEN, NULL_HASH_LEN, sizeof(int), NULL_HMAC_BLOCK_LEN, - null_init, null_reinit, null_reinit, null_update, null_final +struct auth_hash auth_hash_null = { + .type = CRYPTO_NULL_HMAC, + .name = "NULL-HMAC", + .keysize = 0, + .hashsize = NULL_HASH_LEN, + .ctxsize = sizeof(int), /* NB: context isn't used */ + .blocksize = NULL_HMAC_BLOCK_LEN, + .Init = null_init, + .Setkey = null_reinit, + .Reinit = null_reinit, + .Update = null_update, + .Final = null_final, }; /* diff --git a/sys/opencrypto/xform_rmd160.c b/sys/opencrypto/xform_rmd160.c index 4bce0729fa0b..ee344e803102 100644 --- a/sys/opencrypto/xform_rmd160.c +++ b/sys/opencrypto/xform_rmd160.c @@ -57,11 +57,15 @@ static int RMD160Update_int(void *, const u_int8_t *, u_int16_t); /* Authentication instances */ struct auth_hash auth_hash_hmac_ripemd_160 = { - CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160", - RIPEMD160_HMAC_KEY_LEN, RIPEMD160_HASH_LEN, sizeof(RMD160_CTX), - RIPEMD160_HMAC_BLOCK_LEN, - (void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int, - (void (*)(u_int8_t *, void *)) RMD160Final + .type = CRYPTO_RIPEMD160_HMAC, + .name = "HMAC-RIPEMD-160", + .keysize = RIPEMD160_HMAC_BLOCK_LEN, + .hashsize = RIPEMD160_HASH_LEN, + .ctxsize = sizeof(RMD160_CTX), + .blocksize = RIPEMD160_HMAC_BLOCK_LEN, + .Init = (void (*)(void *)) RMD160Init, + .Update = RMD160Update_int, + .Final = (void (*)(u_int8_t *, void *)) RMD160Final, }; /* diff --git a/sys/opencrypto/xform_sha1.c b/sys/opencrypto/xform_sha1.c index 29a5916559c2..974dfb8a7e25 100644 --- a/sys/opencrypto/xform_sha1.c +++ b/sys/opencrypto/xform_sha1.c @@ -59,15 +59,27 @@ static void SHA1Final_int(u_int8_t *, void *); /* Authentication instances */ struct auth_hash auth_hash_hmac_sha1 = { - CRYPTO_SHA1_HMAC, "HMAC-SHA1", - SHA1_HMAC_KEY_LEN, SHA1_HASH_LEN, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN, - SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int + .type = CRYPTO_SHA1_HMAC, + .name = "HMAC-SHA1", + .keysize = SHA1_HMAC_BLOCK_LEN, + .hashsize = SHA1_HASH_LEN, + .ctxsize = sizeof(SHA1_CTX), + .blocksize = SHA1_HMAC_BLOCK_LEN, + .Init = SHA1Init_int, + .Update = SHA1Update_int, + .Final = SHA1Final_int, }; struct auth_hash auth_hash_key_sha1 = { - CRYPTO_SHA1_KPDK, "Keyed SHA1", - NULL_HMAC_KEY_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0, - SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int + .type = CRYPTO_SHA1_KPDK, + .name = "Keyed SHA1", + .keysize = 0, + .hashsize = SHA1_KPDK_HASH_LEN, + .ctxsize = sizeof(SHA1_CTX), + .blocksize = 0, + .Init = SHA1Init_int, + .Update = SHA1Update_int, + .Final = SHA1Final_int, }; /* diff --git a/sys/opencrypto/xform_sha2.c b/sys/opencrypto/xform_sha2.c index 389cb8dab981..7844b8ff8a16 100644 --- a/sys/opencrypto/xform_sha2.c +++ b/sys/opencrypto/xform_sha2.c @@ -61,27 +61,39 @@ static int SHA512Update_int(void *, const u_int8_t *, u_int16_t); /* Authentication instances */ struct auth_hash auth_hash_hmac_sha2_256 = { - CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256", - SHA2_256_HMAC_KEY_LEN, SHA2_256_HASH_LEN, sizeof(SHA256_CTX), - SHA2_256_HMAC_BLOCK_LEN, - (void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int, - (void (*)(u_int8_t *, void *)) SHA256_Final + .type = CRYPTO_SHA2_256_HMAC, + .name = "HMAC-SHA2-256", + .keysize = SHA2_256_HMAC_BLOCK_LEN, + .hashsize = SHA2_256_HASH_LEN, + .ctxsize = sizeof(SHA256_CTX), + .blocksize = SHA2_256_HMAC_BLOCK_LEN, + .Init = (void (*)(void *)) SHA256_Init, + .Update = SHA256Update_int, + .Final = (void (*)(u_int8_t *, void *)) SHA256_Final, }; struct auth_hash auth_hash_hmac_sha2_384 = { - CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384", - SHA2_384_HMAC_KEY_LEN, SHA2_384_HASH_LEN, sizeof(SHA384_CTX), - SHA2_384_HMAC_BLOCK_LEN, - (void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int, - (void (*)(u_int8_t *, void *)) SHA384_Final + .type = CRYPTO_SHA2_384_HMAC, + .name = "HMAC-SHA2-384", + .keysize = SHA2_384_HMAC_BLOCK_LEN, + .hashsize = SHA2_384_HASH_LEN, + .ctxsize = sizeof(SHA384_CTX), + .blocksize = SHA2_384_HMAC_BLOCK_LEN, + .Init = (void (*)(void *)) SHA384_Init, + .Update = SHA384Update_int, + .Final = (void (*)(u_int8_t *, void *)) SHA384_Final, }; struct auth_hash auth_hash_hmac_sha2_512 = { - CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512", - SHA2_512_HMAC_KEY_LEN, SHA2_512_HASH_LEN, sizeof(SHA512_CTX), - SHA2_512_HMAC_BLOCK_LEN, - (void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int, - (void (*)(u_int8_t *, void *)) SHA512_Final + .type = CRYPTO_SHA2_512_HMAC, + .name = "HMAC-SHA2-512", + .keysize = SHA2_512_HMAC_BLOCK_LEN, + .hashsize = SHA2_512_HASH_LEN, + .ctxsize = sizeof(SHA512_CTX), + .blocksize = SHA2_512_HMAC_BLOCK_LEN, + .Init = (void (*)(void *)) SHA512_Init, + .Update = SHA512Update_int, + .Final = (void (*)(u_int8_t *, void *)) SHA512_Final, }; /* diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index 04066418fcc1..b576474fcd1d 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -287,6 +287,7 @@ boolean_t moea_is_referenced(mmu_t, vm_page_t); int moea_ts_referenced(mmu_t, vm_page_t); vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int); boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t); +void moea_page_init(mmu_t, vm_page_t); int moea_page_wired_mappings(mmu_t, vm_page_t); void moea_pinit(mmu_t, pmap_t); void moea_pinit0(mmu_t, pmap_t); @@ -334,6 +335,7 @@ static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_ts_referenced, moea_ts_referenced), MMUMETHOD(mmu_map, moea_map), MMUMETHOD(mmu_page_exists_quick,moea_page_exists_quick), + MMUMETHOD(mmu_page_init, moea_page_init), MMUMETHOD(mmu_page_wired_mappings,moea_page_wired_mappings), MMUMETHOD(mmu_pinit, moea_pinit), MMUMETHOD(mmu_pinit0, moea_pinit0), @@ -1594,6 +1596,15 @@ moea_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m) return (rv); } +void +moea_page_init(mmu_t mmu __unused, vm_page_t m) +{ + + m->md.mdpg_attrs = 0; + m->md.mdpg_cache_attrs = VM_MEMATTR_DEFAULT; + LIST_INIT(&m->md.mdpg_pvoh); +} + /* * Return the number of managed mappings to the given physical page * that are wired. diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index c0461ff57453..28c9c79916f1 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -251,6 +251,7 @@ boolean_t moea64_is_referenced(mmu_t, vm_page_t); int moea64_ts_referenced(mmu_t, vm_page_t); vm_offset_t moea64_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int); boolean_t moea64_page_exists_quick(mmu_t, pmap_t, vm_page_t); +void moea64_page_init(mmu_t, vm_page_t); int moea64_page_wired_mappings(mmu_t, vm_page_t); void moea64_pinit(mmu_t, pmap_t); void moea64_pinit0(mmu_t, pmap_t); @@ -298,6 +299,7 @@ static mmu_method_t moea64_methods[] = { MMUMETHOD(mmu_ts_referenced, moea64_ts_referenced), MMUMETHOD(mmu_map, moea64_map), MMUMETHOD(mmu_page_exists_quick,moea64_page_exists_quick), + MMUMETHOD(mmu_page_init, moea64_page_init), MMUMETHOD(mmu_page_wired_mappings,moea64_page_wired_mappings), MMUMETHOD(mmu_pinit, moea64_pinit), MMUMETHOD(mmu_pinit0, moea64_pinit0), @@ -1898,6 +1900,15 @@ moea64_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m) return (rv); } +void +moea64_page_init(mmu_t mmu __unused, vm_page_t m) +{ + + m->md.mdpg_attrs = 0; + m->md.mdpg_cache_attrs = VM_MEMATTR_DEFAULT; + LIST_INIT(&m->md.mdpg_pvoh); +} + /* * Return the number of managed mappings to the given physical page * that are wired. diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index 12526320ec41..f5e5ddadf7b5 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -57,6 +57,7 @@ #define THREAD_REG %r13 #define ADDR(x) \ .llong x +#define WORD_SIZE 8 #else #define GET_TOCBASE(r) #define TOC_RESTORE @@ -72,6 +73,7 @@ #define THREAD_REG %r2 #define ADDR(x) \ .long x +#define WORD_SIZE 4 #endif .text diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S index 55b8f1a7de3c..3253ea17c7d9 100644 --- a/sys/powerpc/booke/trap_subr.S +++ b/sys/powerpc/booke/trap_subr.S @@ -365,7 +365,7 @@ ld %r30, (TLBSAVE_BOOKE_R30)(br); \ ld %r31, (TLBSAVE_BOOKE_R31)(br); #define TLB_NEST(outr,inr) \ - rlwinm outr, inr, 7, 23, 24; /* 8 x TLBSAVE_LEN */ + rlwinm outr, inr, 7, 22, 24; /* 8 x TLBSAVE_LEN */ #else #define TLB_SAVE_REGS(br) \ stmw %r20, TLBSAVE_BOOKE_R20(br) @@ -970,19 +970,14 @@ int_debug_int: GET_CPUINFO(%r3) LOAD %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r3) bl 0f -#ifdef __powerpc64__ - .llong interrupt_vector_base-. - .llong interrupt_vector_top-. -#else - .long interrupt_vector_base-. - .long interrupt_vector_top-. -#endif + ADDR(interrupt_vector_base-.) + ADDR(interrupt_vector_top-.) 0: mflr %r5 LOAD %r4,0(%r5) /* interrupt_vector_base in r4 */ add %r4,%r4,%r5 CMPL cr0, %r3, %r4 blt trap_common - LOAD %r4,4(%r5) /* interrupt_vector_top in r4 */ + LOAD %r4,WORD_SIZE(%r5) /* interrupt_vector_top in r4 */ add %r4,%r4,%r5 addi %r4,%r4,4 CMPL cr0, %r3, %r4 diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index 374f1ae2ea37..bcae983fa58e 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -35,10 +35,11 @@ options PSERIES #PAPR-compliant systems options FDT options SCHED_ULE #ULE scheduler options PREEMPTION #Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET #InterNETworking options INET6 #IPv6 communications protocols options IPSEC # IP (v4/v6) security -options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_HHOOK # hhook(9) framework for TCP options SCTP #Stream Control Transmission Protocol options FFS #Berkeley Fast Filesystem diff --git a/sys/powerpc/conf/GENERIC-NODEBUG b/sys/powerpc/conf/GENERIC-NODEBUG index 517f71410678..8dca0363f25a 100644 --- a/sys/powerpc/conf/GENERIC-NODEBUG +++ b/sys/powerpc/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 2325bb059d78..67b550953d57 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -4,11 +4,11 @@ # For more information on this file, please read the handbook section on # Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -35,6 +35,7 @@ options PSERIES #PAPR-compliant systems (e.g. IBM p) options FDT #Flattened Device Tree options SCHED_ULE #ULE scheduler options PREEMPTION #Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET #InterNETworking options INET6 #IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX index fe32f298c995..69ab965db10f 100644 --- a/sys/powerpc/conf/MPC85XX +++ b/sys/powerpc/conf/MPC85XX @@ -11,7 +11,8 @@ ident MPC85XX machine powerpc powerpc include "dpaa/config.dpaa" -makeoptions DEBUG="-Wa,-me500 -g" +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions WITH_CTF=1 makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls" makeoptions NO_MODULES=yes @@ -67,9 +68,11 @@ options DDB_CTF # Kernel ELF linker loads CTF data device ata device bpf device cfi +device cpufreq device crypto device cryptodev device da +device ds1307 device ds1553 device em device alc @@ -102,6 +105,8 @@ device uart options USB_DEBUG # enable debug msgs #device uhci device ehci +device ukbd +device ums device umass device usb device vlan diff --git a/sys/powerpc/conf/MPC85XXSPE b/sys/powerpc/conf/MPC85XXSPE index d1928a5b208c..6dc3a8d4350e 100644 --- a/sys/powerpc/conf/MPC85XXSPE +++ b/sys/powerpc/conf/MPC85XXSPE @@ -11,7 +11,8 @@ ident MPC85XX machine powerpc powerpcspe include "dpaa/config.dpaa" -makeoptions DEBUG="-Wa,-me500 -g" +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions WITH_CTF=1 makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls" makeoptions NO_MODULES=yes @@ -67,9 +68,11 @@ options DDB_CTF # Kernel ELF linker loads CTF data device ata device bpf device cfi +device cpufreq device crypto device cryptodev device da +device ds1307 device ds1553 device em device alc @@ -103,6 +106,8 @@ device uart options USB_DEBUG # enable debug msgs #device uhci device ehci +device ukbd +device ums device umass device usb device vlan diff --git a/sys/powerpc/conf/QORIQ64 b/sys/powerpc/conf/QORIQ64 index b834377f3cca..61ec76826afe 100644 --- a/sys/powerpc/conf/QORIQ64 +++ b/sys/powerpc/conf/QORIQ64 @@ -11,15 +11,14 @@ ident MPC85XX machine powerpc powerpc64 -makeoptions DEBUG="-Wa,-me500 -g" +include "dpaa/config.dpaa" +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions WITH_CTF=1 makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls" makeoptions NO_MODULES=yes -#options EARLY_PRINTF - options FPU_EMU -options BOOTVERBOSE=1 options _KPOSIX_PRIORITY_SCHEDULING options ALT_BREAK_TO_DEBUGGER options BREAK_TO_DEBUGGER @@ -35,15 +34,22 @@ options DEVICE_POLLING #options DIAGNOSTIC options FDT #makeoptions FDT_DTS_FILE=mpc8555cds.dts -options FFS +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +options UFS_GJOURNAL #Enable gjournal-based UFS journaling +options QUOTA #Enable disk quotas for UFS options GDB options GEOM_PART_GPT +options GEOM_LABEL #Provides labelization options INET options INET6 options TCP_HHOOK # hhook(9) framework for TCP options INVARIANTS options INVARIANT_SUPPORT options KDB +options KDB_TRACE # Print a stack trace for a panic. options KTRACE options MD_ROOT options MPC85XX @@ -51,18 +57,22 @@ options MSDOSFS options NFS_ROOT options NFSCL options NFSLOCKD -options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options PROCFS options PSEUDOFS options SCHED_ULE options CAPABILITIES options CAPABILITY_MODE options SMP +options STACK #stack(9) support options SYSVMSG options SYSVSEM options SYSVSHM options WITNESS options WITNESS_SKIPSPIN +options HWPMC_HOOKS +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # Kernel ELF linker loads CTF data device ata device bpf @@ -70,9 +80,11 @@ device cfi device crypto device cryptodev device da +device ds1307 device ds1553 device em device alc +device dpaa device ether device fxp device gpio @@ -93,6 +105,8 @@ device scbus device scc device sdhci device sec +device spibus +device spigen device tun device uart options USB_DEBUG # enable debug msgs diff --git a/sys/powerpc/conf/dpaa/config.dpaa b/sys/powerpc/conf/dpaa/config.dpaa index 1eafce970e9d..64f3968a3559 100644 --- a/sys/powerpc/conf/dpaa/config.dpaa +++ b/sys/powerpc/conf/dpaa/config.dpaa @@ -2,9 +2,10 @@ files "dpaa/files.dpaa" -makeoptions DPAA_COMPILE_CMD="${NORMAL_C} \ +makeoptions DPAA_COMPILE_CMD="${LINUXKPI_C} \ -Wno-cast-qual -Wno-unused-function -Wno-init-self -fms-extensions \ -include $S/contrib/ncsw/build/dflags.h \ + -Wno-error=missing-prototypes \ -I$S/contrib/ncsw/build/ \ -I$S/contrib/ncsw/inc \ -I$S/contrib/ncsw/inc/cores \ @@ -20,4 +21,5 @@ makeoptions DPAA_COMPILE_CMD="${NORMAL_C} \ -I$S/contrib/ncsw/Peripherals/FM/Port \ -I$S/contrib/ncsw/Peripherals/FM/Rtc \ -I$S/contrib/ncsw/Peripherals/QM \ + -I$S/contrib/ncsw/inc/flib \ -I$S/contrib/ncsw/inc/integrations" diff --git a/sys/powerpc/conf/dpaa/files.dpaa b/sys/powerpc/conf/dpaa/files.dpaa index b4a6c1aa29bb..ba53da3d54de 100644 --- a/sys/powerpc/conf/dpaa/files.dpaa +++ b/sys/powerpc/conf/dpaa/files.dpaa @@ -3,7 +3,7 @@ # NetCommSw drivers contrib/ncsw/etc/error.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" -contrib/ncsw/etc/list.c optional dpaa \ +contrib/ncsw/etc/ncsw_list.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/etc/memcpy.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" @@ -21,8 +21,14 @@ contrib/ncsw/Peripherals/BM/bm_pool.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/BM/bm_portal.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/SP/fm_sp.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/Rtc/fman_rtc.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/Port/fman_port.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Port/fm_port.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Port/fm_port_im.c optional dpaa \ @@ -31,6 +37,8 @@ contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/Pcd/fman_kg.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c optional dpaa \ @@ -39,23 +47,33 @@ contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/Pcd/fman_prs.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/MAC/dtsec.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/MAC/fman_dtsec_mii_acc.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/MAC/fm_mac.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/MAC/fman_dtsec.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/MAC/tgec.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" +contrib/ncsw/Peripherals/FM/MAC/fman_tgec.c optional dpaa \ + no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/HC/hc.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/FM/fm_muram.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" -contrib/ncsw/Peripherals/FM/fm_guest.c optional dpaa \ +contrib/ncsw/Peripherals/FM/fm_ncsw.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" -contrib/ncsw/Peripherals/FM/fm.c optional dpaa \ +contrib/ncsw/Peripherals/FM/fman_ncsw.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" contrib/ncsw/Peripherals/QM/qm.c optional dpaa \ no-depend compile-with "${DPAA_COMPILE_CMD}" diff --git a/sys/powerpc/include/elf.h b/sys/powerpc/include/elf.h index 0e81b4a7c9fd..aa36caff65fd 100644 --- a/sys/powerpc/include/elf.h +++ b/sys/powerpc/include/elf.h @@ -107,8 +107,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 19 /* Number of pagesizes. */ #define AT_STACKPROT 21 /* Initial stack protection. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 23 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* * Relocation types. diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h index 5fbf9ee07ae9..aba0c9215787 100644 --- a/sys/powerpc/include/intr_machdep.h +++ b/sys/powerpc/include/intr_machdep.h @@ -30,7 +30,7 @@ #define INTR_VECTORS 256 -#define MAX_PICS 16 +#define MAX_PICS 32 #define MAP_IRQ(node, pin) powerpc_get_irq(node, pin) /* diff --git a/sys/powerpc/include/psl.h b/sys/powerpc/include/psl.h index bb4756f0637d..9ea07f3f6dc1 100644 --- a/sys/powerpc/include/psl.h +++ b/sys/powerpc/include/psl.h @@ -45,15 +45,16 @@ #define PSL_FP 0x00002000UL /* floating point enable */ #define PSL_ME 0x00001000UL /* machine check enable */ #define PSL_FE0 0x00000800UL /* floating point interrupt mode 0 */ -#define PSL_BE 0x00000200UL /* branch trace enable */ #define PSL_FE1 0x00000100UL /* floating point interrupt mode 1 */ #define PSL_PMM 0x00000004UL /* performance monitor mark */ +#define PSL_RI 0x00000002UL /* recoverable interrupt */ /* Machine State Register - Book-E cores */ #ifdef __powerpc64__ #define PSL_CM 0x80000000UL /* Computation Mode (64-bit) */ #endif +#define PSL_GS 0x10000000UL /* Guest state */ #define PSL_UCLE 0x04000000UL /* User mode cache lock enable */ #define PSL_WE 0x00040000UL /* Wait state enable */ #define PSL_CE 0x00020000UL /* Critical interrupt enable */ @@ -72,10 +73,10 @@ #define PSL_POW 0x00040000UL /* power management */ #define PSL_ILE 0x00010000UL /* interrupt endian mode (1 == le) */ #define PSL_SE 0x00000400UL /* single-step trace enable */ +#define PSL_BE 0x00000200UL /* branch trace enable */ #define PSL_IP 0x00000040UL /* interrupt prefix - 601 only */ #define PSL_IR 0x00000020UL /* instruction address relocation */ #define PSL_DR 0x00000010UL /* data address relocation */ -#define PSL_RI 0x00000002UL /* recoverable interrupt */ #define PSL_LE 0x00000001UL /* endian mode (1 == le) */ /* diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 13fb125c67d4..f09fbdcd6dbb 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -736,6 +736,8 @@ #define SVR_P4040E 0x8208 #define SVR_P4080 0x8201 #define SVR_P4080E 0x8209 +#define SVR_P5010 0x8221 +#define SVR_P5010E 0x8229 #define SVR_P5020 0x8220 #define SVR_P5020E 0x8228 #define SVR_P5021 0x8205 diff --git a/sys/powerpc/mpc85xx/fsl_diu.c b/sys/powerpc/mpc85xx/fsl_diu.c index 5019b209d1f3..a63775567c87 100644 --- a/sys/powerpc/mpc85xx/fsl_diu.c +++ b/sys/powerpc/mpc85xx/fsl_diu.c @@ -35,13 +35,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include #include #include -#include -#include #include #include @@ -59,8 +54,6 @@ __FBSDID("$FreeBSD$"); #include -#include "gpio_if.h" - #include #include diff --git a/sys/powerpc/mpc85xx/fsl_sata.c b/sys/powerpc/mpc85xx/fsl_sata.c new file mode 100644 index 000000000000..bcb6c05b3969 --- /dev/null +++ b/sys/powerpc/mpc85xx/fsl_sata.c @@ -0,0 +1,1918 @@ +/*- + * Copyright (c) 2009-2012 Alexander Motin + * Copyright (c) 2017 Justin Hibbits + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 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 AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "fsl_sata.h" + +struct fsl_sata_channel; +struct fsl_sata_slot; +enum fsl_sata_err_type; +struct fsl_sata_cmd_tab; + + +/* local prototypes */ +static int fsl_sata_init(device_t dev); +static int fsl_sata_deinit(device_t dev); +static int fsl_sata_suspend(device_t dev); +static int fsl_sata_resume(device_t dev); +static void fsl_sata_pm(void *arg); +static void fsl_sata_intr(void *arg); +static void fsl_sata_intr_main(struct fsl_sata_channel *ch, uint32_t istatus); +static void fsl_sata_begin_transaction(struct fsl_sata_channel *ch, union ccb *ccb); +static void fsl_sata_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error); +static void fsl_sata_execute_transaction(struct fsl_sata_slot *slot); +static void fsl_sata_timeout(struct fsl_sata_slot *slot); +static void fsl_sata_end_transaction(struct fsl_sata_slot *slot, enum fsl_sata_err_type et); +static int fsl_sata_setup_fis(struct fsl_sata_channel *ch, struct fsl_sata_cmd_tab *ctp, union ccb *ccb, int tag); +static void fsl_sata_dmainit(device_t dev); +static void fsl_sata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); +static void fsl_sata_dmafini(device_t dev); +static void fsl_sata_slotsalloc(device_t dev); +static void fsl_sata_slotsfree(device_t dev); +static void fsl_sata_reset(struct fsl_sata_channel *ch); +static void fsl_sata_start(struct fsl_sata_channel *ch); +static void fsl_sata_stop(struct fsl_sata_channel *ch); + +static void fsl_sata_issue_recovery(struct fsl_sata_channel *ch); +static void fsl_sata_process_read_log(struct fsl_sata_channel *ch, union ccb *ccb); +static void fsl_sata_process_request_sense(struct fsl_sata_channel *ch, union ccb *ccb); + +static void fsl_sataaction(struct cam_sim *sim, union ccb *ccb); +static void fsl_satapoll(struct cam_sim *sim); + +static MALLOC_DEFINE(M_FSL_SATA, "FSL SATA driver", "FSL SATA driver data buffers"); + +#define recovery_type spriv_field0 +#define RECOVERY_NONE 0 +#define RECOVERY_READ_LOG 1 +#define RECOVERY_REQUEST_SENSE 2 +#define recovery_slot spriv_field1 + +#define FSL_SATA_P_CQR 0x0 +#define FSL_SATA_P_CAR 0x4 +#define FSL_SATA_P_CCR 0x10 +#define FSL_SATA_P_CER 0x18 +#define FSL_SATA_P_DER 0x20 +#define FSL_SATA_P_CHBA 0x24 +#define FSL_SATA_P_HSTS 0x28 +#define FSL_SATA_P_HSTS_HS_ON 0x80000000 +#define FSL_SATA_P_HSTS_ME 0x00040000 +#define FSL_SATA_P_HSTS_DLM 0x00001000 +#define FSL_SATA_P_HSTS_FOT 0x00000200 +#define FSL_SATA_P_HSTS_FOR 0x00000100 +#define FSL_SATA_P_HSTS_FE 0x00000020 +#define FSL_SATA_P_HSTS_PR 0x00000010 +#define FSL_SATA_P_HSTS_SNTFU 0x00000004 +#define FSL_SATA_P_HSTS_DE 0x00000002 +#define FSL_SATA_P_HCTRL 0x2c +#define FSL_SATA_P_HCTRL_HC_ON 0x80000000 +#define FSL_SATA_P_HCTRL_HC_FORCE_OFF 0x40000000 +#define FSL_SATA_P_HCTRL_ENT 0x10000000 +#define FSL_SATA_P_HCTRL_SNOOP 0x00000400 +#define FSL_SATA_P_HCTRL_PM 0x00000200 +#define FSL_SATA_P_HCTRL_FATAL 0x00000020 +#define FSL_SATA_P_HCTRL_PHYRDY 0x00000010 +#define FSL_SATA_P_HCTRL_SIG 0x00000008 +#define FSL_SATA_P_HCTRL_SNTFY 0x00000004 +#define FSL_SATA_P_HCTRL_DE 0x00000002 +#define FSL_SATA_P_HCTRL_CC 0x00000001 +#define FSL_SATA_P_HCTRL_INT_MASK 0x0000003f +#define FSL_SATA_P_CQPMP 0x30 +#define FSL_SATA_P_SIG 0x34 +#define FSL_SATA_P_ICC 0x38 +#define FSL_SATA_P_ICC_ITC_M 0x1f000000 +#define FSL_SATA_P_ICC_ITC_S 24 +#define FSL_SATA_P_ICC_ITTCV_M 0x0007ffff +#define FSL_SATA_P_PCC 0x15c +#define FSL_SATA_P_PCC_SLUMBER 0x0000000c +#define FSL_SATA_P_PCC_PARTIAL 0x0000000a +#define FSL_SATA_PCC_LPB_EN 0x0000000e + +#define FSL_SATA_MAX_SLOTS 16 +/* FSL_SATA register defines */ + +#define FSL_SATA_P_SSTS 0x100 +#define FSL_SATA_P_SERR 0x104 +#define FSL_SATA_P_SCTL 0x108 +#define FSL_SATA_P_SNTF 0x10c + +/* Pessimistic prognosis on number of required S/G entries */ +#define FSL_SATA_SG_ENTRIES 63 +/* Command list. 16 commands. First, 1Kbyte aligned. */ +#define FSL_SATA_CL_OFFSET 0 +#define FSL_SATA_CL_SIZE 16 +/* Command tables. Up to 32 commands, Each, 4-byte aligned. */ +#define FSL_SATA_CT_OFFSET (FSL_SATA_CL_OFFSET + FSL_SATA_CL_SIZE * FSL_SATA_MAX_SLOTS) +#define FSL_SATA_CT_SIZE (96 + FSL_SATA_SG_ENTRIES * 16) +/* Total main work area. */ +#define FSL_SATA_WORK_SIZE (FSL_SATA_CT_OFFSET + FSL_SATA_CT_SIZE * FSL_SATA_MAX_SLOTS) +#define FSL_SATA_MAX_XFER (64 * 1024 * 1024) + +/* Some convenience macros for getting the CTP and CLP */ +#define FSL_SATA_CTP_BUS(ch, slot) \ + ((ch->dma.work_bus + FSL_SATA_CT_OFFSET + (FSL_SATA_CT_SIZE * slot->slot))) +#define FSL_SATA_PRD_OFFSET(prd) (96 + (prd) * 16) +#define FSL_SATA_CTP(ch, slot) \ + ((struct fsl_sata_cmd_tab *)(ch->dma.work + FSL_SATA_CT_OFFSET + \ + (FSL_SATA_CT_SIZE * slot->slot))) +#define FSL_SATA_CLP(ch, slot) \ + ((struct fsl_sata_cmd_list *) (ch->dma.work + FSL_SATA_CL_OFFSET + \ + (FSL_SATA_CL_SIZE * slot->slot))) + +struct fsl_sata_dma_prd { + uint32_t dba; + uint32_t reserved; + uint32_t reserved2; + uint32_t dwc_flg; /* 0 based */ +#define FSL_SATA_PRD_MASK 0x01fffffc /* max 32MB */ +#define FSL_SATA_PRD_MAX (FSL_SATA_PRD_MASK + 4) +#define FSL_SATA_PRD_SNOOP 0x10000000 +#define FSL_SATA_PRD_EXT 0x80000000 +} __packed; + +struct fsl_sata_cmd_tab { + uint8_t cfis[32]; + uint8_t sfis[32]; + uint8_t acmd[16]; + uint8_t reserved[16]; + struct fsl_sata_dma_prd prd_tab[FSL_SATA_SG_ENTRIES]; +#define FSL_SATA_PRD_EXT_INDEX 15 +#define FSL_SATA_PRD_MAX_DIRECT 16 +} __packed; + +struct fsl_sata_cmd_list { + uint32_t cda; /* word aligned */ + uint16_t fis_length; /* length in bytes (aligned to words) */ + uint16_t prd_length; /* PRD entries */ + uint32_t ttl; + uint32_t cmd_flags; +#define FSL_SATA_CMD_TAG_MASK 0x001f +#define FSL_SATA_CMD_ATAPI 0x0020 +#define FSL_SATA_CMD_BIST 0x0040 +#define FSL_SATA_CMD_RESET 0x0080 +#define FSL_SATA_CMD_QUEUED 0x0100 +#define FSL_SATA_CMD_SNOOP 0x0200 +#define FSL_SATA_CMD_VBIST 0x0400 +#define FSL_SATA_CMD_WRITE 0x0800 + +} __packed; + +/* misc defines */ +#define ATA_IRQ_RID 0 +#define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) + +struct ata_dmaslot { + bus_dmamap_t data_map; /* data DMA map */ + int nsegs; /* Number of segs loaded */ +}; + +/* structure holding DMA related information */ +struct ata_dma { + bus_dma_tag_t work_tag; /* workspace DMA tag */ + bus_dmamap_t work_map; /* workspace DMA map */ + uint8_t *work; /* workspace */ + bus_addr_t work_bus; /* bus address of work */ + bus_dma_tag_t data_tag; /* data DMA tag */ +}; + +enum fsl_sata_slot_states { + FSL_SATA_SLOT_EMPTY, + FSL_SATA_SLOT_LOADING, + FSL_SATA_SLOT_RUNNING, + FSL_SATA_SLOT_EXECUTING +}; + +struct fsl_sata_slot { + struct fsl_sata_channel *ch; /* Channel */ + uint8_t slot; /* Number of this slot */ + enum fsl_sata_slot_states state; /* Slot state */ + union ccb *ccb; /* CCB occupying slot */ + struct ata_dmaslot dma; /* DMA data of this slot */ + struct callout timeout; /* Execution timeout */ + uint32_t ttl; +}; + +struct fsl_sata_device { + int revision; + int mode; + u_int bytecount; + u_int atapi; + u_int tags; + u_int caps; +}; + +/* structure describing an ATA channel */ +struct fsl_sata_channel { + device_t dev; /* Device handle */ + int unit; /* Physical channel */ + struct resource *r_mem; /* Memory of this channel */ + struct resource *r_irq; /* Interrupt of this channel */ + void *ih; /* Interrupt handle */ + struct ata_dma dma; /* DMA data */ + struct cam_sim *sim; + struct cam_path *path; + uint32_t caps; /* Controller capabilities */ + int pm_level; /* power management level */ + int devices; /* What is present */ + int pm_present; /* PM presence reported */ + + union ccb *hold[FSL_SATA_MAX_SLOTS]; + struct fsl_sata_slot slot[FSL_SATA_MAX_SLOTS]; + uint32_t oslots; /* Occupied slots */ + uint32_t rslots; /* Running slots */ + uint32_t aslots; /* Slots with atomic commands */ + uint32_t eslots; /* Slots in error */ + uint32_t toslots; /* Slots in timeout */ + int lastslot; /* Last used slot */ + int taggedtarget; /* Last tagged target */ + int numrslots; /* Number of running slots */ + int numrslotspd[16];/* Number of running slots per dev */ + int numtslots; /* Number of tagged slots */ + int numtslotspd[16];/* Number of tagged slots per dev */ + int numhslots; /* Number of held slots */ + int recoverycmd; /* Our READ LOG active */ + int fatalerr; /* Fatal error happend */ + int resetting; /* Hard-reset in progress. */ + int resetpolldiv; /* Hard-reset poll divider. */ + union ccb *frozen; /* Frozen command */ + struct callout pm_timer; /* Power management events */ + struct callout reset_timer; /* Hard-reset timeout */ + + struct fsl_sata_device user[16]; /* User-specified settings */ + struct fsl_sata_device curr[16]; /* Current settings */ + + struct mtx_padalign mtx; /* state lock */ + STAILQ_HEAD(, ccb_hdr) doneq; /* queue of completed CCBs */ + int batch; /* doneq is in use */ +}; + +enum fsl_sata_err_type { + FSL_SATA_ERR_NONE, /* No error */ + FSL_SATA_ERR_INVALID, /* Error detected by us before submitting. */ + FSL_SATA_ERR_INNOCENT, /* Innocent victim. */ + FSL_SATA_ERR_TFE, /* Task File Error. */ + FSL_SATA_ERR_SATA, /* SATA error. */ + FSL_SATA_ERR_TIMEOUT, /* Command execution timeout. */ + FSL_SATA_ERR_NCQ, /* NCQ command error. CCB should be put on hold + * until READ LOG executed to reveal error. */ +}; + +/* macros to hide busspace uglyness */ +#define ATA_INB(res, offset) \ + bus_read_1((res), (offset)) +#define ATA_INW(res, offset) \ + bus_read_2((res), (offset)) +#define ATA_INL(res, offset) \ + bus_read_4((res), (offset)) +#define ATA_INSW(res, offset, addr, count) \ + bus_read_multi_2((res), (offset), (addr), (count)) +#define ATA_INSW_STRM(res, offset, addr, count) \ + bus_read_multi_stream_2((res), (offset), (addr), (count)) +#define ATA_INSL(res, offset, addr, count) \ + bus_read_multi_4((res), (offset), (addr), (count)) +#define ATA_INSL_STRM(res, offset, addr, count) \ + bus_read_multi_stream_4((res), (offset), (addr), (count)) +#define ATA_OUTB(res, offset, value) \ + bus_write_1((res), (offset), (value)) +#define ATA_OUTW(res, offset, value) \ + bus_write_2((res), (offset), (value)) +#define ATA_OUTL(res, offset, value) \ + bus_write_4((res), (offset), (value)) +#define ATA_OUTSW(res, offset, addr, count) \ + bus_write_multi_2((res), (offset), (addr), (count)) +#define ATA_OUTSW_STRM(res, offset, addr, count) \ + bus_write_multi_stream_2((res), (offset), (addr), (count)) +#define ATA_OUTSL(res, offset, addr, count) \ + bus_write_multi_4((res), (offset), (addr), (count)) +#define ATA_OUTSL_STRM(res, offset, addr, count) \ + bus_write_multi_stream_4((res), (offset), (addr), (count)) + +static int +fsl_sata_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "fsl,pq-sata-v2") && + !ofw_bus_is_compatible(dev, "fsl,pq-sata")) + return (ENXIO); + + device_set_desc_copy(dev, "Freescale Integrated SATA Controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +fsl_sata_attach(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + struct cam_devq *devq; + int rid, error, i, sata_rev = 0; + + ch->dev = dev; + ch->unit = (intptr_t)device_get_ivars(dev); + mtx_init(&ch->mtx, "FSL SATA channel lock", NULL, MTX_DEF); + ch->pm_level = 0; + resource_int_value(device_get_name(dev), + device_get_unit(dev), "pm_level", &ch->pm_level); + STAILQ_INIT(&ch->doneq); + if (ch->pm_level > 3) + callout_init_mtx(&ch->pm_timer, &ch->mtx, 0); + resource_int_value(device_get_name(dev), + device_get_unit(dev), "sata_rev", &sata_rev); + for (i = 0; i < 16; i++) { + ch->user[i].revision = sata_rev; + ch->user[i].mode = 0; + ch->user[i].bytecount = 8192; + ch->user[i].tags = FSL_SATA_MAX_SLOTS; + ch->user[i].caps = 0; + ch->curr[i] = ch->user[i]; + if (ch->pm_level) { + ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ | + CTS_SATA_CAPS_D_PMREQ; + } + ch->user[i].caps |= CTS_SATA_CAPS_H_AN; + } + rid = 0; + if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE))) + return (ENXIO); + rman_set_bustag(ch->r_mem, &bs_le_tag); + fsl_sata_dmainit(dev); + fsl_sata_slotsalloc(dev); + fsl_sata_init(dev); + rid = ATA_IRQ_RID; + if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &rid, RF_SHAREABLE | RF_ACTIVE))) { + device_printf(dev, "Unable to map interrupt\n"); + error = ENXIO; + goto err0; + } + if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL, + fsl_sata_intr, ch, &ch->ih))) { + device_printf(dev, "Unable to setup interrupt\n"); + error = ENXIO; + goto err1; + } + mtx_lock(&ch->mtx); + /* Create the device queue for our SIM. */ + devq = cam_simq_alloc(FSL_SATA_MAX_SLOTS); + if (devq == NULL) { + device_printf(dev, "Unable to allocate simq\n"); + error = ENOMEM; + goto err1; + } + /* Construct SIM entry */ + ch->sim = cam_sim_alloc(fsl_sataaction, fsl_satapoll, "fslsata", ch, + device_get_unit(dev), (struct mtx *)&ch->mtx, 2, FSL_SATA_MAX_SLOTS, + devq); + if (ch->sim == NULL) { + cam_simq_free(devq); + device_printf(dev, "unable to allocate sim\n"); + error = ENOMEM; + goto err1; + } + if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) { + device_printf(dev, "unable to register xpt bus\n"); + error = ENXIO; + goto err2; + } + if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + device_printf(dev, "unable to create path\n"); + error = ENXIO; + goto err3; + } + if (ch->pm_level > 3) { + callout_reset(&ch->pm_timer, + (ch->pm_level == 4) ? hz / 1000 : hz / 8, + fsl_sata_pm, ch); + } + mtx_unlock(&ch->mtx); + return (0); + +err3: + xpt_bus_deregister(cam_sim_path(ch->sim)); +err2: + cam_sim_free(ch->sim, /*free_devq*/TRUE); +err1: + mtx_unlock(&ch->mtx); + bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); +err0: + bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); + mtx_destroy(&ch->mtx); + return (error); +} + +static int +fsl_sata_detach(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + + mtx_lock(&ch->mtx); + xpt_async(AC_LOST_DEVICE, ch->path, NULL); + + xpt_free_path(ch->path); + xpt_bus_deregister(cam_sim_path(ch->sim)); + cam_sim_free(ch->sim, /*free_devq*/TRUE); + mtx_unlock(&ch->mtx); + + if (ch->pm_level > 3) + callout_drain(&ch->pm_timer); + bus_teardown_intr(dev, ch->r_irq, ch->ih); + bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); + + fsl_sata_deinit(dev); + fsl_sata_slotsfree(dev); + fsl_sata_dmafini(dev); + + bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); + mtx_destroy(&ch->mtx); + return (0); +} + +static int +fsl_sata_wait_register(struct fsl_sata_channel *ch, bus_size_t off, + unsigned int mask, unsigned int val, int t) +{ + int timeout = 0; + uint32_t rval; + + while (((rval = ATA_INL(ch->r_mem, off)) & mask) != val) { + if (timeout > t) { + return (EBUSY); + } + DELAY(1000); + timeout++; + } + return (0); +} + +static int +fsl_sata_init(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + uint64_t work; + uint32_t r; + + /* Disable port interrupts */ + r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); + r &= ~FSL_SATA_P_HCTRL_HC_ON; + r |= FSL_SATA_P_HCTRL_HC_FORCE_OFF; + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_INT_MASK); + fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, + FSL_SATA_P_HSTS_HS_ON, 0, 1000); + /* Setup work areas */ + work = ch->dma.work_bus + FSL_SATA_CL_OFFSET; + ATA_OUTL(ch->r_mem, FSL_SATA_P_CHBA, work); + r &= ~FSL_SATA_P_HCTRL_ENT; + r &= ~FSL_SATA_P_HCTRL_PM; + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r); + r = ATA_INL(ch->r_mem, FSL_SATA_P_PCC); + ATA_OUTL(ch->r_mem, FSL_SATA_P_PCC, r & ~FSL_SATA_PCC_LPB_EN); + ATA_OUTL(ch->r_mem, FSL_SATA_P_ICC, (1 << FSL_SATA_P_ICC_ITC_S)); + fsl_sata_start(ch); + return (0); +} + +static int +fsl_sata_deinit(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + uint32_t r; + + /* Disable port interrupts. */ + r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_INT_MASK); + /* Reset command register. */ + fsl_sata_stop(ch); + /* Allow everything, including partial and slumber modes. */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_SCTL, 0); + DELAY(100); + /* Disable PHY. */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_SCTL, ATA_SC_DET_DISABLE); + r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); + /* Turn off the controller. */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_HC_ON); + return (0); +} + +static int +fsl_sata_suspend(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + + mtx_lock(&ch->mtx); + xpt_freeze_simq(ch->sim, 1); + while (ch->oslots) + msleep(ch, &ch->mtx, PRIBIO, "fsl_satasusp", hz/100); + fsl_sata_deinit(dev); + mtx_unlock(&ch->mtx); + return (0); +} + +static int +fsl_sata_resume(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + + mtx_lock(&ch->mtx); + fsl_sata_init(dev); + fsl_sata_reset(ch); + xpt_release_simq(ch->sim, TRUE); + mtx_unlock(&ch->mtx); + return (0); +} + +devclass_t fsl_satach_devclass; +static device_method_t fsl_satach_methods[] = { + DEVMETHOD(device_probe, fsl_sata_probe), + DEVMETHOD(device_attach, fsl_sata_attach), + DEVMETHOD(device_detach, fsl_sata_detach), + DEVMETHOD(device_suspend, fsl_sata_suspend), + DEVMETHOD(device_resume, fsl_sata_resume), + DEVMETHOD_END +}; +static driver_t fsl_satach_driver = { + "fslsata", + fsl_satach_methods, + sizeof(struct fsl_sata_channel) +}; +DRIVER_MODULE(fsl_satach, simplebus, fsl_satach_driver, fsl_satach_devclass, NULL, NULL); + +struct fsl_sata_dc_cb_args { + bus_addr_t maddr; + int error; +}; + +static void +fsl_sata_dmainit(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + struct fsl_sata_dc_cb_args dcba; + + /* Command area. */ + if (bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + NULL, NULL, FSL_SATA_WORK_SIZE, 1, FSL_SATA_WORK_SIZE, + 0, NULL, NULL, &ch->dma.work_tag)) + goto error; + if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work, + BUS_DMA_ZERO, &ch->dma.work_map)) + goto error; + if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work, + FSL_SATA_WORK_SIZE, fsl_sata_dmasetupc_cb, &dcba, 0) || dcba.error) { + bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); + goto error; + } + ch->dma.work_bus = dcba.maddr; + /* Data area. */ + if (bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + NULL, NULL, FSL_SATA_MAX_XFER, + FSL_SATA_SG_ENTRIES - 1, FSL_SATA_PRD_MAX, + 0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) { + goto error; + } + if (bootverbose) + device_printf(dev, "work area: %p\n", ch->dma.work); + return; + +error: + device_printf(dev, "WARNING - DMA initialization failed\n"); + fsl_sata_dmafini(dev); +} + +static void +fsl_sata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) +{ + struct fsl_sata_dc_cb_args *dcba = (struct fsl_sata_dc_cb_args *)xsc; + + if (!(dcba->error = error)) + dcba->maddr = segs[0].ds_addr; +} + +static void +fsl_sata_dmafini(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + + if (ch->dma.data_tag) { + bus_dma_tag_destroy(ch->dma.data_tag); + ch->dma.data_tag = NULL; + } + if (ch->dma.work_bus) { + bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map); + bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); + ch->dma.work_bus = 0; + ch->dma.work = NULL; + } + if (ch->dma.work_tag) { + bus_dma_tag_destroy(ch->dma.work_tag); + ch->dma.work_tag = NULL; + } +} + +static void +fsl_sata_slotsalloc(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + int i; + + /* Alloc and setup command/dma slots */ + bzero(ch->slot, sizeof(ch->slot)); + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + struct fsl_sata_slot *slot = &ch->slot[i]; + + slot->ch = ch; + slot->slot = i; + slot->state = FSL_SATA_SLOT_EMPTY; + slot->ccb = NULL; + callout_init_mtx(&slot->timeout, &ch->mtx, 0); + + if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map)) + device_printf(ch->dev, "FAILURE - create data_map\n"); + } +} + +static void +fsl_sata_slotsfree(device_t dev) +{ + struct fsl_sata_channel *ch = device_get_softc(dev); + int i; + + /* Free all dma slots */ + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + struct fsl_sata_slot *slot = &ch->slot[i]; + + callout_drain(&slot->timeout); + if (slot->dma.data_map) { + bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); + slot->dma.data_map = NULL; + } + } +} + +static int +fsl_sata_phy_check_events(struct fsl_sata_channel *ch, u_int32_t serr) +{ + + if (((ch->pm_level == 0) && (serr & ATA_SE_PHY_CHANGED)) || + ((ch->pm_level != 0) && (serr & ATA_SE_EXCHANGED))) { + u_int32_t status = ATA_INL(ch->r_mem, FSL_SATA_P_SSTS); + union ccb *ccb; + + if (bootverbose) { + if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) + device_printf(ch->dev, "CONNECT requested\n"); + else + device_printf(ch->dev, "DISCONNECT requested\n"); + } + /* Issue soft reset */ + xpt_async(AC_BUS_RESET, ch->path, NULL); + if ((ccb = xpt_alloc_ccb_nowait()) == NULL) + return (0); + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(ch->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + return (0); + } + xpt_rescan(ccb); + return (1); + } + return (0); +} + +static void +fsl_sata_notify_events(struct fsl_sata_channel *ch, u_int32_t status) +{ + struct cam_path *dpath; + int i; + + ATA_OUTL(ch->r_mem, FSL_SATA_P_SNTF, status); + if (bootverbose) + device_printf(ch->dev, "SNTF 0x%04x\n", status); + for (i = 0; i < 16; i++) { + if ((status & (1 << i)) == 0) + continue; + if (xpt_create_path(&dpath, NULL, + xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) { + xpt_async(AC_SCSI_AEN, dpath, NULL); + xpt_free_path(dpath); + } + } +} + +static void +fsl_sata_done(struct fsl_sata_channel *ch, union ccb *ccb) +{ + + mtx_assert(&ch->mtx, MA_OWNED); + if ((ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0 || + ch->batch == 0) { + xpt_done(ccb); + return; + } + + STAILQ_INSERT_TAIL(&ch->doneq, &ccb->ccb_h, sim_links.stqe); +} + +static void +fsl_sata_intr(void *arg) +{ + struct fsl_sata_channel *ch = (struct fsl_sata_channel *)arg; + struct ccb_hdr *ccb_h; + uint32_t istatus; + STAILQ_HEAD(, ccb_hdr) tmp_doneq = STAILQ_HEAD_INITIALIZER(tmp_doneq); + + /* Read interrupt statuses. */ + istatus = ATA_INL(ch->r_mem, FSL_SATA_P_HSTS) & 0x7ffff; + if ((istatus & 0x3f) == 0) + return; + + mtx_lock(&ch->mtx); + ch->batch = 1; + fsl_sata_intr_main(ch, istatus); + ch->batch = 0; + /* + * Prevent the possibility of issues caused by processing the queue + * while unlocked below by moving the contents to a local queue. + */ + STAILQ_CONCAT(&tmp_doneq, &ch->doneq); + mtx_unlock(&ch->mtx); + while ((ccb_h = STAILQ_FIRST(&tmp_doneq)) != NULL) { + STAILQ_REMOVE_HEAD(&tmp_doneq, sim_links.stqe); + xpt_done_direct((union ccb *)ccb_h); + } + /* Clear interrupt statuses. */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, istatus & 0x3f); + +} + +static void +fsl_sata_pm(void *arg) +{ + struct fsl_sata_channel *ch = (struct fsl_sata_channel *)arg; + uint32_t work; + + if (ch->numrslots != 0) + return; + work = ATA_INL(ch->r_mem, FSL_SATA_P_PCC) & ~FSL_SATA_PCC_LPB_EN; + if (ch->pm_level == 4) + work |= FSL_SATA_P_PCC_PARTIAL; + else + work |= FSL_SATA_P_PCC_SLUMBER; + ATA_OUTL(ch->r_mem, FSL_SATA_P_PCC, work); +} + +/* XXX: interrupt todo */ +static void +fsl_sata_intr_main(struct fsl_sata_channel *ch, uint32_t istatus) +{ + uint32_t cer, der, serr = 0, sntf = 0, ok, err; + enum fsl_sata_err_type et; + int i; + + /* Complete all successful commands. */ + ok = ATA_INL(ch->r_mem, FSL_SATA_P_CCR); + if (ch->aslots == 0) + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (((ok >> i) & 1) && ch->slot[i].ccb != NULL) + fsl_sata_end_transaction(&ch->slot[i], FSL_SATA_ERR_NONE); + } + /* Read command statuses. */ + if (istatus & FSL_SATA_P_HSTS_SNTFU) + sntf = ATA_INL(ch->r_mem, FSL_SATA_P_SNTF); + /* XXX: Process PHY events */ + serr = ATA_INL(ch->r_mem, FSL_SATA_P_SERR); + ATA_OUTL(ch->r_mem, FSL_SATA_P_SERR, serr); + if (istatus & (FSL_SATA_P_HSTS_PR)) { + if (serr) { + fsl_sata_phy_check_events(ch, serr); + } + } + /* Process command errors */ + err = (istatus & (FSL_SATA_P_HSTS_FE | FSL_SATA_P_HSTS_DE)); + cer = ATA_INL(ch->r_mem, FSL_SATA_P_CER); + ATA_OUTL(ch->r_mem, FSL_SATA_P_CER, cer); + der = ATA_INL(ch->r_mem, FSL_SATA_P_DER); + ATA_OUTL(ch->r_mem, FSL_SATA_P_DER, der); + /* On error, complete the rest of commands with error statuses. */ + if (err) { + if (ch->frozen) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; + if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { + xpt_freeze_devq(fccb->ccb_h.path, 1); + fccb->ccb_h.status |= CAM_DEV_QFRZN; + } + fsl_sata_done(ch, fccb); + } + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (ch->slot[i].ccb == NULL) + continue; + if ((cer & (1 << i)) != 0) + et = FSL_SATA_ERR_TFE; + else if ((der & (1 << ch->slot[i].ccb->ccb_h.target_id)) != 0) + et = FSL_SATA_ERR_SATA; + else + et = FSL_SATA_ERR_INVALID; + fsl_sata_end_transaction(&ch->slot[i], et); + } + } + /* Process NOTIFY events */ + if (sntf) + fsl_sata_notify_events(ch, sntf); +} + +/* Must be called with channel locked. */ +static int +fsl_sata_check_collision(struct fsl_sata_channel *ch, union ccb *ccb) +{ + int t = ccb->ccb_h.target_id; + + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { + /* Tagged command while we have no supported tag free. */ + if (((~ch->oslots) & (0xffffffff >> (32 - + ch->curr[t].tags))) == 0) + return (1); + /* Tagged command while untagged are active. */ + if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] == 0) + return (1); + } else { + /* Untagged command while tagged are active. */ + if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] != 0) + return (1); + } + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { + /* Atomic command while anything active. */ + if (ch->numrslots != 0) + return (1); + } + /* We have some atomic command running. */ + if (ch->aslots != 0) + return (1); + return (0); +} + +/* Must be called with channel locked. */ +static void +fsl_sata_begin_transaction(struct fsl_sata_channel *ch, union ccb *ccb) +{ + struct fsl_sata_slot *slot; + int tag, tags; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("fsl_sata_begin_transaction func_code=0x%x\n", ccb->ccb_h.func_code)); + /* Choose empty slot. */ + tags = FSL_SATA_MAX_SLOTS; + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) + tags = ch->curr[ccb->ccb_h.target_id].tags; + if (ch->lastslot + 1 < tags) + tag = ffs(~(ch->oslots >> (ch->lastslot + 1))); + else + tag = 0; + if (tag == 0 || tag + ch->lastslot >= tags) + tag = ffs(~ch->oslots) - 1; + else + tag += ch->lastslot; + ch->lastslot = tag; + /* Occupy chosen slot. */ + slot = &ch->slot[tag]; + slot->ccb = ccb; + slot->ttl = 0; + /* Stop PM timer. */ + if (ch->numrslots == 0 && ch->pm_level > 3) + callout_stop(&ch->pm_timer); + /* Update channel stats. */ + ch->oslots |= (1 << tag); + ch->numrslots++; + ch->numrslotspd[ccb->ccb_h.target_id]++; + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { + ch->numtslots++; + ch->numtslotspd[ccb->ccb_h.target_id]++; + ch->taggedtarget = ccb->ccb_h.target_id; + } + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) + ch->aslots |= (1 << tag); + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { + slot->state = FSL_SATA_SLOT_LOADING; + bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, ccb, + fsl_sata_dmasetprd, slot, 0); + } else { + slot->dma.nsegs = 0; + fsl_sata_execute_transaction(slot); + } + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("fsl_sata_begin_transaction exit\n")); +} + +/* Locked by busdma engine. */ +static void +fsl_sata_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error) +{ + struct fsl_sata_slot *slot = arg; + struct fsl_sata_channel *ch = slot->ch; + struct fsl_sata_cmd_tab *ctp; + struct fsl_sata_dma_prd *prd; + int i, j, len, extlen; + + if (error) { + device_printf(ch->dev, "DMA load error %d\n", error); + fsl_sata_end_transaction(slot, FSL_SATA_ERR_INVALID); + return; + } + KASSERT(nsegs <= FSL_SATA_SG_ENTRIES - 1, + ("too many DMA segment entries\n")); + /* Get a piece of the workspace for this request */ + ctp = FSL_SATA_CTP(ch, slot); + /* Fill S/G table */ + prd = &ctp->prd_tab[0]; + for (i = 0, j = 0; i < nsegs; i++, j++) { + if (j == FSL_SATA_PRD_EXT_INDEX && + FSL_SATA_PRD_MAX_DIRECT < nsegs) { + prd[j].dba = htole32(FSL_SATA_CTP_BUS(ch, slot) + + FSL_SATA_PRD_OFFSET(j+1)); + j++; + extlen = 0; + } + len = segs[i].ds_len; + len = roundup2(len, sizeof(uint32_t)); + prd[j].dba = htole32((uint32_t)segs[i].ds_addr); + prd[j].dwc_flg = htole32(FSL_SATA_PRD_SNOOP | len); + slot->ttl += len; + if (j > FSL_SATA_PRD_MAX_DIRECT) + extlen += len; + } + slot->dma.nsegs = j; + if (j > FSL_SATA_PRD_MAX_DIRECT) + prd[FSL_SATA_PRD_EXT_INDEX].dwc_flg = + htole32(FSL_SATA_PRD_SNOOP | FSL_SATA_PRD_EXT | extlen); + bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, + ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ? + BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); + fsl_sata_execute_transaction(slot); +} + +/* Must be called with channel locked. */ +static void +fsl_sata_execute_transaction(struct fsl_sata_slot *slot) +{ + struct fsl_sata_channel *ch = slot->ch; + struct fsl_sata_cmd_tab *ctp; + struct fsl_sata_cmd_list *clp; + union ccb *ccb = slot->ccb; + int port = ccb->ccb_h.target_id & 0x0f; + int fis_size, i, softreset; + uint32_t tmp; + uint32_t cmd_flags = FSL_SATA_CMD_WRITE | FSL_SATA_CMD_SNOOP; + + softreset = 0; + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("fsl_sata_execute_transaction func_code=0x%x\n", ccb->ccb_h.func_code)); + /* Get a piece of the workspace for this request */ + ctp = FSL_SATA_CTP(ch, slot); + /* Setup the FIS for this request */ + if (!(fis_size = fsl_sata_setup_fis(ch, ctp, ccb, slot->slot))) { + device_printf(ch->dev, "Setting up SATA FIS failed\n"); + fsl_sata_end_transaction(slot, FSL_SATA_ERR_INVALID); + return; + } + /* Setup the command list entry */ + clp = FSL_SATA_CLP(ch, slot); + clp->fis_length = htole16(fis_size); + clp->prd_length = htole16(slot->dma.nsegs); + /* Special handling for Soft Reset command. */ + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { + if (ccb->ataio.cmd.control & ATA_A_RESET) { + softreset = 1; + cmd_flags |= FSL_SATA_CMD_RESET; + } else { + /* Prepare FIS receive area for check. */ + for (i = 0; i < 32; i++) + ctp->sfis[i] = 0xff; + softreset = 2; + } + } + if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) + cmd_flags |= FSL_SATA_CMD_QUEUED; + clp->cmd_flags = htole32(cmd_flags | + (ccb->ccb_h.func_code == XPT_SCSI_IO ? FSL_SATA_CMD_ATAPI : 0) | + slot->slot); + clp->ttl = htole32(slot->ttl); + clp->cda = htole32(FSL_SATA_CTP_BUS(ch, slot)); + bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* Issue command to the controller. */ + slot->state = FSL_SATA_SLOT_RUNNING; + ch->rslots |= (1 << slot->slot); + ATA_OUTL(ch->r_mem, FSL_SATA_P_CQPMP, port); + ATA_OUTL(ch->r_mem, FSL_SATA_P_CQR, (1 << slot->slot)); + /* Device reset commands don't interrupt. Poll them. */ + if (ccb->ccb_h.func_code == XPT_ATA_IO && + (ccb->ataio.cmd.command == ATA_DEVICE_RESET || softreset)) { + int count, timeout = ccb->ccb_h.timeout * 100; + enum fsl_sata_err_type et = FSL_SATA_ERR_NONE; + + for (count = 0; count < timeout; count++) { + DELAY(10); + tmp = 0; + if (softreset == 2) { + tmp = ATA_INL(ch->r_mem, FSL_SATA_P_SIG); + if (tmp != 0 && tmp != 0xffffffff) + break; + continue; + } + if ((ATA_INL(ch->r_mem, FSL_SATA_P_CCR) & (1 << slot->slot)) != 0) + break; + } + + if (timeout && (count >= timeout)) { + device_printf(ch->dev, "Poll timeout on slot %d port %d (round %d)\n", + slot->slot, port, softreset); + device_printf(ch->dev, "hsts %08x cqr %08x ccr %08x ss %08x " + "rs %08x cer %08x der %08x serr %08x car %08x sig %08x\n", + ATA_INL(ch->r_mem, FSL_SATA_P_HSTS), + ATA_INL(ch->r_mem, FSL_SATA_P_CQR), + ATA_INL(ch->r_mem, FSL_SATA_P_CCR), + ATA_INL(ch->r_mem, FSL_SATA_P_SSTS), ch->rslots, + ATA_INL(ch->r_mem, FSL_SATA_P_CER), + ATA_INL(ch->r_mem, FSL_SATA_P_DER), + ATA_INL(ch->r_mem, FSL_SATA_P_SERR), + ATA_INL(ch->r_mem, FSL_SATA_P_CAR), + ATA_INL(ch->r_mem, FSL_SATA_P_SIG)); + et = FSL_SATA_ERR_TIMEOUT; + } + + fsl_sata_end_transaction(slot, et); + return; + } + /* Start command execution timeout */ + callout_reset_sbt(&slot->timeout, SBT_1MS * ccb->ccb_h.timeout / 2, + 0, (timeout_t*)fsl_sata_timeout, slot, 0); + return; +} + +/* Must be called with channel locked. */ +static void +fsl_sata_process_timeout(struct fsl_sata_channel *ch) +{ + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + /* Handle the rest of commands. */ + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + /* Do we have a running request on slot? */ + if (ch->slot[i].state < FSL_SATA_SLOT_RUNNING) + continue; + fsl_sata_end_transaction(&ch->slot[i], FSL_SATA_ERR_TIMEOUT); + } +} + +/* Must be called with channel locked. */ +static void +fsl_sata_rearm_timeout(struct fsl_sata_channel *ch) +{ + int i; + + mtx_assert(&ch->mtx, MA_OWNED); + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + struct fsl_sata_slot *slot = &ch->slot[i]; + + /* Do we have a running request on slot? */ + if (slot->state < FSL_SATA_SLOT_RUNNING) + continue; + if ((ch->toslots & (1 << i)) == 0) + continue; + callout_reset_sbt(&slot->timeout, + SBT_1MS * slot->ccb->ccb_h.timeout / 2, 0, + (timeout_t*)fsl_sata_timeout, slot, 0); + } +} + +/* Locked by callout mechanism. */ +static void +fsl_sata_timeout(struct fsl_sata_slot *slot) +{ + struct fsl_sata_channel *ch = slot->ch; + device_t dev = ch->dev; + uint32_t sstatus; + + /* Check for stale timeout. */ + if (slot->state < FSL_SATA_SLOT_RUNNING) + return; + + /* Check if slot was not being executed last time we checked. */ + if (slot->state < FSL_SATA_SLOT_EXECUTING) { + /* Check if slot started executing. */ + sstatus = ATA_INL(ch->r_mem, FSL_SATA_P_CAR); + if ((sstatus & (1 << slot->slot)) != 0) + slot->state = FSL_SATA_SLOT_EXECUTING; + + callout_reset_sbt(&slot->timeout, + SBT_1MS * slot->ccb->ccb_h.timeout / 2, 0, + (timeout_t*)fsl_sata_timeout, slot, 0); + return; + } + + device_printf(dev, "Timeout on slot %d port %d\n", + slot->slot, slot->ccb->ccb_h.target_id & 0x0f); + + /* Handle frozen command. */ + if (ch->frozen) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; + if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { + xpt_freeze_devq(fccb->ccb_h.path, 1); + fccb->ccb_h.status |= CAM_DEV_QFRZN; + } + fsl_sata_done(ch, fccb); + } + if (ch->toslots == 0) + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); + if ((ch->rslots & ~ch->toslots) == 0) + fsl_sata_process_timeout(ch); + else + device_printf(dev, " ... waiting for slots %08x\n", + ch->rslots & ~ch->toslots); +} + +/* Must be called with channel locked. */ +static void +fsl_sata_end_transaction(struct fsl_sata_slot *slot, enum fsl_sata_err_type et) +{ + struct fsl_sata_channel *ch = slot->ch; + union ccb *ccb = slot->ccb; + struct fsl_sata_cmd_list *clp; + int lastto; + uint32_t sig; + + bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + clp = FSL_SATA_CLP(ch, slot); + /* Read result registers to the result struct */ + if (ccb->ccb_h.func_code == XPT_ATA_IO) { + struct ata_res *res = &ccb->ataio.res; + + if ((et == FSL_SATA_ERR_TFE) || + (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { + struct fsl_sata_cmd_tab *ctp = FSL_SATA_CTP(ch, slot); + uint8_t *fis = ctp->sfis; + + res->status = fis[2]; + res->error = fis[3]; + res->lba_low = fis[4]; + res->lba_mid = fis[5]; + res->lba_high = fis[6]; + res->device = fis[7]; + res->lba_low_exp = fis[8]; + res->lba_mid_exp = fis[9]; + res->lba_high_exp = fis[10]; + res->sector_count = fis[12]; + res->sector_count_exp = fis[13]; + + if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET) == 0) { + sig = ATA_INL(ch->r_mem, FSL_SATA_P_SIG); + res->lba_high = sig >> 24; + res->lba_mid = sig >> 16; + res->lba_low = sig >> 8; + res->sector_count = sig; + } + } else + bzero(res, sizeof(*res)); + if ((ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) == 0 && + (ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { + ccb->ataio.resid = + ccb->ataio.dxfer_len - le32toh(clp->ttl); + } + } else { + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { + ccb->csio.resid = + ccb->csio.dxfer_len - le32toh(clp->ttl); + } + } + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { + bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, + (ccb->ccb_h.flags & CAM_DIR_IN) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map); + } + if (et != FSL_SATA_ERR_NONE) + ch->eslots |= (1 << slot->slot); + /* In case of error, freeze device for proper recovery. */ + if ((et != FSL_SATA_ERR_NONE) && (!ch->recoverycmd) && + !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { + xpt_freeze_devq(ccb->ccb_h.path, 1); + ccb->ccb_h.status |= CAM_DEV_QFRZN; + } + /* Set proper result status. */ + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + switch (et) { + case FSL_SATA_ERR_NONE: + ccb->ccb_h.status |= CAM_REQ_CMP; + if (ccb->ccb_h.func_code == XPT_SCSI_IO) + ccb->csio.scsi_status = SCSI_STATUS_OK; + break; + case FSL_SATA_ERR_INVALID: + ch->fatalerr = 1; + ccb->ccb_h.status |= CAM_REQ_INVALID; + break; + case FSL_SATA_ERR_INNOCENT: + ccb->ccb_h.status |= CAM_REQUEUE_REQ; + break; + case FSL_SATA_ERR_TFE: + case FSL_SATA_ERR_NCQ: + if (ccb->ccb_h.func_code == XPT_SCSI_IO) { + ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; + ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; + } else { + ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; + } + break; + case FSL_SATA_ERR_SATA: + ch->fatalerr = 1; + if (!ch->recoverycmd) { + xpt_freeze_simq(ch->sim, 1); + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + } + ccb->ccb_h.status |= CAM_UNCOR_PARITY; + break; + case FSL_SATA_ERR_TIMEOUT: + if (!ch->recoverycmd) { + xpt_freeze_simq(ch->sim, 1); + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + } + ccb->ccb_h.status |= CAM_CMD_TIMEOUT; + break; + default: + ch->fatalerr = 1; + ccb->ccb_h.status |= CAM_REQ_CMP_ERR; + } + /* Free slot. */ + ch->oslots &= ~(1 << slot->slot); + ch->rslots &= ~(1 << slot->slot); + ch->aslots &= ~(1 << slot->slot); + slot->state = FSL_SATA_SLOT_EMPTY; + slot->ccb = NULL; + /* Update channel stats. */ + ch->numrslots--; + ch->numrslotspd[ccb->ccb_h.target_id]--; + ATA_OUTL(ch->r_mem, FSL_SATA_P_CCR, 1 << slot->slot); + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { + ch->numtslots--; + ch->numtslotspd[ccb->ccb_h.target_id]--; + } + /* Cancel timeout state if request completed normally. */ + if (et != FSL_SATA_ERR_TIMEOUT) { + lastto = (ch->toslots == (1 << slot->slot)); + ch->toslots &= ~(1 << slot->slot); + if (lastto) + xpt_release_simq(ch->sim, TRUE); + } + /* If it was first request of reset sequence and there is no error, + * proceed to second request. */ + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET) && + et == FSL_SATA_ERR_NONE) { + ccb->ataio.cmd.control &= ~ATA_A_RESET; + fsl_sata_begin_transaction(ch, ccb); + return; + } + /* If it was our READ LOG command - process it. */ + if (ccb->ccb_h.recovery_type == RECOVERY_READ_LOG) { + fsl_sata_process_read_log(ch, ccb); + /* If it was our REQUEST SENSE command - process it. */ + } else if (ccb->ccb_h.recovery_type == RECOVERY_REQUEST_SENSE) { + fsl_sata_process_request_sense(ch, ccb); + /* If it was NCQ or ATAPI command error, put result on hold. */ + } else if (et == FSL_SATA_ERR_NCQ || + ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && + (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)) { + ch->hold[slot->slot] = ccb; + ch->numhslots++; + } else + fsl_sata_done(ch, ccb); + /* If we have no other active commands, ... */ + if (ch->rslots == 0) { + /* if there was fatal error - reset port. */ + if (ch->toslots != 0 || ch->fatalerr) { + fsl_sata_reset(ch); + } else { + /* if we have slots in error, we can reinit port. */ + if (ch->eslots != 0) { + fsl_sata_stop(ch); + fsl_sata_start(ch); + } + /* if there commands on hold, we can do READ LOG. */ + if (!ch->recoverycmd && ch->numhslots) + fsl_sata_issue_recovery(ch); + } + /* If all the rest of commands are in timeout - give them chance. */ + } else if ((ch->rslots & ~ch->toslots) == 0 && + et != FSL_SATA_ERR_TIMEOUT) + fsl_sata_rearm_timeout(ch); + /* Unfreeze frozen command. */ + if (ch->frozen && !fsl_sata_check_collision(ch, ch->frozen)) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + fsl_sata_begin_transaction(ch, fccb); + xpt_release_simq(ch->sim, TRUE); + } + /* Start PM timer. */ + if (ch->numrslots == 0 && ch->pm_level > 3 && + (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { + callout_schedule(&ch->pm_timer, + (ch->pm_level == 4) ? hz / 1000 : hz / 8); + } +} + +static void +fsl_sata_issue_recovery(struct fsl_sata_channel *ch) +{ + union ccb *ccb; + struct ccb_ataio *ataio; + struct ccb_scsiio *csio; + int i; + + /* Find some held command. */ + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (ch->hold[i]) + break; + } + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + device_printf(ch->dev, "Unable to allocate recovery command\n"); +completeall: + /* We can't do anything -- complete held commands. */ + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (ch->hold[i] == NULL) + continue; + ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; + ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL; + fsl_sata_done(ch, ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + fsl_sata_reset(ch); + return; + } + ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */ + if (ccb->ccb_h.func_code == XPT_ATA_IO) { + /* READ LOG */ + ccb->ccb_h.recovery_type = RECOVERY_READ_LOG; + ccb->ccb_h.func_code = XPT_ATA_IO; + ccb->ccb_h.flags = CAM_DIR_IN; + ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ + ataio = &ccb->ataio; + ataio->data_ptr = malloc(512, M_FSL_SATA, M_NOWAIT); + if (ataio->data_ptr == NULL) { + xpt_free_ccb(ccb); + device_printf(ch->dev, + "Unable to allocate memory for READ LOG command\n"); + goto completeall; + } + ataio->dxfer_len = 512; + bzero(&ataio->cmd, sizeof(ataio->cmd)); + ataio->cmd.flags = CAM_ATAIO_48BIT; + ataio->cmd.command = 0x2F; /* READ LOG EXT */ + ataio->cmd.sector_count = 1; + ataio->cmd.sector_count_exp = 0; + ataio->cmd.lba_low = 0x10; + ataio->cmd.lba_mid = 0; + ataio->cmd.lba_mid_exp = 0; + } else { + /* REQUEST SENSE */ + ccb->ccb_h.recovery_type = RECOVERY_REQUEST_SENSE; + ccb->ccb_h.recovery_slot = i; + ccb->ccb_h.func_code = XPT_SCSI_IO; + ccb->ccb_h.flags = CAM_DIR_IN; + ccb->ccb_h.status = 0; + ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ + csio = &ccb->csio; + csio->data_ptr = (void *)&ch->hold[i]->csio.sense_data; + csio->dxfer_len = ch->hold[i]->csio.sense_len; + csio->cdb_len = 6; + bzero(&csio->cdb_io, sizeof(csio->cdb_io)); + csio->cdb_io.cdb_bytes[0] = 0x03; + csio->cdb_io.cdb_bytes[4] = csio->dxfer_len; + } + /* Freeze SIM while doing recovery. */ + ch->recoverycmd = 1; + xpt_freeze_simq(ch->sim, 1); + fsl_sata_begin_transaction(ch, ccb); +} + +static void +fsl_sata_process_read_log(struct fsl_sata_channel *ch, union ccb *ccb) +{ + uint8_t *data; + struct ata_res *res; + int i; + + ch->recoverycmd = 0; + + data = ccb->ataio.data_ptr; + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && + (data[0] & 0x80) == 0) { + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (!ch->hold[i]) + continue; + if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO) + continue; + if ((data[0] & 0x1F) == i) { + res = &ch->hold[i]->ataio.res; + res->status = data[2]; + res->error = data[3]; + res->lba_low = data[4]; + res->lba_mid = data[5]; + res->lba_high = data[6]; + res->device = data[7]; + res->lba_low_exp = data[8]; + res->lba_mid_exp = data[9]; + res->lba_high_exp = data[10]; + res->sector_count = data[12]; + res->sector_count_exp = data[13]; + } else { + ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; + ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ; + } + fsl_sata_done(ch, ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + } else { + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + device_printf(ch->dev, "Error while READ LOG EXT\n"); + else if ((data[0] & 0x80) == 0) { + device_printf(ch->dev, "Non-queued command error in READ LOG EXT\n"); + } + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (!ch->hold[i]) + continue; + if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO) + continue; + fsl_sata_done(ch, ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + } + free(ccb->ataio.data_ptr, M_FSL_SATA); + xpt_free_ccb(ccb); + xpt_release_simq(ch->sim, TRUE); +} + +static void +fsl_sata_process_request_sense(struct fsl_sata_channel *ch, union ccb *ccb) +{ + int i; + + ch->recoverycmd = 0; + + i = ccb->ccb_h.recovery_slot; + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { + ch->hold[i]->ccb_h.status |= CAM_AUTOSNS_VALID; + } else { + ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; + ch->hold[i]->ccb_h.status |= CAM_AUTOSENSE_FAIL; + } + fsl_sata_done(ch, ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + xpt_free_ccb(ccb); + xpt_release_simq(ch->sim, TRUE); +} + +static void +fsl_sata_start(struct fsl_sata_channel *ch) +{ + u_int32_t cmd; + + /* Clear SATA error register */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_SERR, 0xFFFFFFFF); + /* Clear any interrupts pending on this channel */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, 0x3F); + ATA_OUTL(ch->r_mem, FSL_SATA_P_CER, 0xFFFF); + ATA_OUTL(ch->r_mem, FSL_SATA_P_DER, 0xFFFF); + /* Start operations on this channel */ + cmd = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); + cmd |= FSL_SATA_P_HCTRL_HC_ON | FSL_SATA_P_HCTRL_SNOOP; + cmd &= ~FSL_SATA_P_HCTRL_HC_FORCE_OFF; + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, cmd | + (ch->pm_present ? FSL_SATA_P_HCTRL_PM : 0)); + fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, + FSL_SATA_P_HSTS_PR, FSL_SATA_P_HSTS_PR, 500); + ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, + ATA_INL(ch->r_mem, FSL_SATA_P_HSTS) & FSL_SATA_P_HSTS_PR); +} + +static void +fsl_sata_stop(struct fsl_sata_channel *ch) +{ + uint32_t cmd; + int i; + + /* Kill all activity on this channel */ + cmd = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); + cmd &= ~FSL_SATA_P_HCTRL_HC_ON; + + for (i = 0; i < 2; i++) { + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, cmd); + if (fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, + FSL_SATA_P_HSTS_HS_ON, 0, 500)) { + if (i != 0) + device_printf(ch->dev, + "stopping FSL SATA engine failed\n"); + cmd |= FSL_SATA_P_HCTRL_HC_FORCE_OFF; + } else + break; + } + ch->eslots = 0; +} + +static void +fsl_sata_reset(struct fsl_sata_channel *ch) +{ + uint32_t ctrl; + int i; + + xpt_freeze_simq(ch->sim, 1); + if (bootverbose) + device_printf(ch->dev, "FSL SATA reset...\n"); + + /* Requeue freezed command. */ + if (ch->frozen) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; + if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { + xpt_freeze_devq(fccb->ccb_h.path, 1); + fccb->ccb_h.status |= CAM_DEV_QFRZN; + } + fsl_sata_done(ch, fccb); + } + /* Kill the engine and requeue all running commands. */ + fsl_sata_stop(ch); + DELAY(1000); /* sleep for 1ms */ + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + /* Do we have a running request on slot? */ + if (ch->slot[i].state < FSL_SATA_SLOT_RUNNING) + continue; + /* XXX; Commands in loading state. */ + fsl_sata_end_transaction(&ch->slot[i], FSL_SATA_ERR_INNOCENT); + } + for (i = 0; i < FSL_SATA_MAX_SLOTS; i++) { + if (!ch->hold[i]) + continue; + fsl_sata_done(ch, ch->hold[i]); + ch->hold[i] = NULL; + ch->numhslots--; + } + if (ch->toslots != 0) + xpt_release_simq(ch->sim, TRUE); + ch->eslots = 0; + ch->toslots = 0; + ch->fatalerr = 0; + /* Tell the XPT about the event */ + xpt_async(AC_BUS_RESET, ch->path, NULL); + /* Disable port interrupts */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, + ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) & ~0x3f); + /* Reset and reconnect PHY, */ + fsl_sata_start(ch); + if (fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, 0x08, 0x08, 500)) { + if (bootverbose) + device_printf(ch->dev, + "FSL SATA reset: device not found\n"); + ch->devices = 0; + /* Enable wanted port interrupts */ + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, + ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) | FSL_SATA_P_HCTRL_PHYRDY); + xpt_release_simq(ch->sim, TRUE); + return; + } + if (bootverbose) + device_printf(ch->dev, "FSL SATA reset: device found\n"); + ch->devices = 1; + /* Enable wanted port interrupts */ + ctrl = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) & ~0x3f; + ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, + ctrl | FSL_SATA_P_HCTRL_FATAL | FSL_SATA_P_HCTRL_PHYRDY | + FSL_SATA_P_HCTRL_SIG | FSL_SATA_P_HCTRL_SNTFY | + FSL_SATA_P_HCTRL_DE | FSL_SATA_P_HCTRL_CC); + xpt_release_simq(ch->sim, TRUE); +} + +static int +fsl_sata_setup_fis(struct fsl_sata_channel *ch, struct fsl_sata_cmd_tab *ctp, union ccb *ccb, int tag) +{ + uint8_t *fis = &ctp->cfis[0]; + + bzero(fis, 32); + fis[0] = 0x27; /* host to device */ + fis[1] = (ccb->ccb_h.target_id & 0x0f); + if (ccb->ccb_h.func_code == XPT_SCSI_IO) { + fis[1] |= 0x80; + fis[2] = ATA_PACKET_CMD; + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) + fis[3] = ATA_F_DMA; + else { + fis[5] = ccb->csio.dxfer_len; + fis[6] = ccb->csio.dxfer_len >> 8; + } + fis[7] = ATA_D_LBA; + fis[15] = ATA_A_4BIT; + bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ? + ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes, + ctp->acmd, ccb->csio.cdb_len); + bzero(ctp->acmd + ccb->csio.cdb_len, 32 - ccb->csio.cdb_len); + } else if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) { + fis[1] |= 0x80; + fis[2] = ccb->ataio.cmd.command; + fis[3] = ccb->ataio.cmd.features; + fis[4] = ccb->ataio.cmd.lba_low; + fis[5] = ccb->ataio.cmd.lba_mid; + fis[6] = ccb->ataio.cmd.lba_high; + fis[7] = ccb->ataio.cmd.device; + fis[8] = ccb->ataio.cmd.lba_low_exp; + fis[9] = ccb->ataio.cmd.lba_mid_exp; + fis[10] = ccb->ataio.cmd.lba_high_exp; + fis[11] = ccb->ataio.cmd.features_exp; + if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { + fis[12] = tag << 3; + fis[13] = 0; + } else { + fis[12] = ccb->ataio.cmd.sector_count; + fis[13] = ccb->ataio.cmd.sector_count_exp; + } + fis[15] = ATA_A_4BIT; + } else { + fis[15] = ccb->ataio.cmd.control; + } + return (20); +} + +static int +fsl_sata_check_ids(struct fsl_sata_channel *ch, union ccb *ccb) +{ + + if (ccb->ccb_h.target_id > 15) { + ccb->ccb_h.status = CAM_TID_INVALID; + fsl_sata_done(ch, ccb); + return (-1); + } + if (ccb->ccb_h.target_lun != 0) { + ccb->ccb_h.status = CAM_LUN_INVALID; + fsl_sata_done(ch, ccb); + return (-1); + } + return (0); +} + +static void +fsl_sataaction(struct cam_sim *sim, union ccb *ccb) +{ + struct fsl_sata_channel *ch; + + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("fsl_sataaction func_code=0x%x\n", ccb->ccb_h.func_code)); + + ch = (struct fsl_sata_channel *)cam_sim_softc(sim); + switch (ccb->ccb_h.func_code) { + /* Common cases first */ + case XPT_ATA_IO: /* Execute the requested I/O operation */ + case XPT_SCSI_IO: + if (fsl_sata_check_ids(ch, ccb)) + return; + if (ch->devices == 0 || + (ch->pm_present == 0 && + ccb->ccb_h.target_id > 0 && ccb->ccb_h.target_id < 15)) { + ccb->ccb_h.status = CAM_SEL_TIMEOUT; + break; + } + ccb->ccb_h.recovery_type = RECOVERY_NONE; + /* Check for command collision. */ + if (fsl_sata_check_collision(ch, ccb)) { + /* Freeze command. */ + ch->frozen = ccb; + /* We have only one frozen slot, so freeze simq also. */ + xpt_freeze_simq(ch->sim, 1); + return; + } + fsl_sata_begin_transaction(ch, ccb); + return; + case XPT_ABORT: /* Abort the specified CCB */ + /* XXX Implement */ + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + case XPT_SET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + struct fsl_sata_device *d; + + if (fsl_sata_check_ids(ch, ccb)) + return; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) + d->revision = cts->xport_specific.sata.revision; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) + d->mode = cts->xport_specific.sata.mode; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) + d->bytecount = min(8192, cts->xport_specific.sata.bytecount); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) + d->tags = min(FSL_SATA_MAX_SLOTS, cts->xport_specific.sata.tags); + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) + ch->pm_present = cts->xport_specific.sata.pm_present; + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI) + d->atapi = cts->xport_specific.sata.atapi; + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_GET_TRAN_SETTINGS: + /* Get default/user set transfer settings for the target */ + { + struct ccb_trans_settings *cts = &ccb->cts; + struct fsl_sata_device *d; + uint32_t status; + + if (fsl_sata_check_ids(ch, ccb)) + return; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + d = &ch->curr[ccb->ccb_h.target_id]; + else + d = &ch->user[ccb->ccb_h.target_id]; + cts->protocol = PROTO_UNSPECIFIED; + cts->protocol_version = PROTO_VERSION_UNSPECIFIED; + cts->transport = XPORT_SATA; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->proto_specific.valid = 0; + cts->xport_specific.sata.valid = 0; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS && + (ccb->ccb_h.target_id == 15 || + (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { + status = ATA_INL(ch->r_mem, FSL_SATA_P_SSTS) & ATA_SS_SPD_MASK; + if (status & 0x0f0) { + cts->xport_specific.sata.revision = + (status & 0x0f0) >> 4; + cts->xport_specific.sata.valid |= + CTS_SATA_VALID_REVISION; + } + cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; + if (ch->pm_level) { + cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; + } + cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; + cts->xport_specific.sata.caps &= + ch->user[ccb->ccb_h.target_id].caps; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; + } else { + cts->xport_specific.sata.revision = d->revision; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; + cts->xport_specific.sata.caps = d->caps; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; + } + cts->xport_specific.sata.mode = d->mode; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; + cts->xport_specific.sata.bytecount = d->bytecount; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; + cts->xport_specific.sata.pm_present = ch->pm_present; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; + cts->xport_specific.sata.tags = d->tags; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; + cts->xport_specific.sata.atapi = d->atapi; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_RESET_BUS: /* Reset the specified SCSI bus */ + case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ + fsl_sata_reset(ch); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_TERM_IO: /* Terminate the I/O process */ + /* XXX Implement */ + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + case XPT_PATH_INQ: /* Path routing inquiry */ + { + struct ccb_pathinq *cpi = &ccb->cpi; + + cpi->version_num = 1; /* XXX??? */ + cpi->hba_inquiry = PI_SDTR_ABLE; + cpi->hba_inquiry |= PI_TAG_ABLE; +#if 0 + /* + * XXX: CAM tries to reset port 15 if it sees port multiplier + * support. Disable it for now. + */ + cpi->hba_inquiry |= PI_SATAPM; +#endif + cpi->target_sprt = 0; + cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED; + cpi->hba_eng_cnt = 0; + /* + * XXX: This should be 15, since hardware *does* support a port + * multiplier. See above. + */ + cpi->max_target = 0; + cpi->max_lun = 0; + cpi->initiator_id = 0; + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 150000; + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "FSL SATA", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->transport = XPORT_SATA; + cpi->transport_version = XPORT_VERSION_UNSPECIFIED; + cpi->protocol = PROTO_ATA; + cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; + cpi->maxio = MAXPHYS; + cpi->ccb_h.status = CAM_REQ_CMP; + break; + } + default: + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + } + fsl_sata_done(ch, ccb); +} + +static void +fsl_satapoll(struct cam_sim *sim) +{ + struct fsl_sata_channel *ch = (struct fsl_sata_channel *)cam_sim_softc(sim); + uint32_t istatus; + + /* Read interrupt statuses and process if any. */ + istatus = ATA_INL(ch->r_mem, FSL_SATA_P_HSTS); + if (istatus != 0) + fsl_sata_intr_main(ch, istatus); +} +MODULE_VERSION(fsl_sata, 1); +MODULE_DEPEND(fsl_sata, cam, 1, 1, 1); diff --git a/sys/powerpc/mpc85xx/fsl_sata.h b/sys/powerpc/mpc85xx/fsl_sata.h new file mode 100644 index 000000000000..3a9ea20484b0 --- /dev/null +++ b/sys/powerpc/mpc85xx/fsl_sata.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1998 - 2008 Søren Schmidt + * Copyright (c) 2009-2012 Alexander Motin + * Copyright (c) 2015-2016 Justin Hibbits + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 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 AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* ATA register defines */ + +#define ATA_FEATURE 1 /* (W) feature */ +#define ATA_F_DMA 0x01 /* enable DMA */ +#define ATA_F_OVL 0x02 /* enable overlap */ + +#define ATA_COUNT 2 /* (W) sector count */ + +#define ATA_SECTOR 3 /* (RW) sector # */ +#define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ +#define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ +#define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ +#define ATA_D_LBA 0x40 /* use LBA addressing */ +#define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ + +#define ATA_COMMAND 7 /* (W) command */ + +#define ATA_ERROR 8 /* (R) error */ +#define ATA_E_ILI 0x01 /* illegal length */ +#define ATA_E_NM 0x02 /* no media */ +#define ATA_E_ABORT 0x04 /* command aborted */ +#define ATA_E_MCR 0x08 /* media change request */ +#define ATA_E_IDNF 0x10 /* ID not found */ +#define ATA_E_MC 0x20 /* media changed */ +#define ATA_E_UNC 0x40 /* uncorrectable data */ +#define ATA_E_ICRC 0x80 /* UDMA crc error */ +#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ + +#define ATA_IREASON 9 /* (R) interrupt reason */ +#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ +#define ATA_I_IN 0x02 /* read (1) | write (0) */ +#define ATA_I_RELEASE 0x04 /* released bus (1) */ +#define ATA_I_TAGMASK 0xf8 /* tag mask */ + +#define ATA_STATUS 10 /* (R) status */ +#define ATA_ALTSTAT 11 /* (R) alternate status */ +#define ATA_S_ERROR 0x01 /* error */ +#define ATA_S_INDEX 0x02 /* index */ +#define ATA_S_CORR 0x04 /* data corrected */ +#define ATA_S_DRQ 0x08 /* data request */ +#define ATA_S_DSC 0x10 /* drive seek completed */ +#define ATA_S_SERVICE 0x10 /* drive needs service */ +#define ATA_S_DWF 0x20 /* drive write fault */ +#define ATA_S_DMA 0x20 /* DMA ready */ +#define ATA_S_READY 0x40 /* drive ready */ +#define ATA_S_BUSY 0x80 /* busy */ + +#define ATA_CONTROL 12 /* (W) control */ +#define ATA_A_IDS 0x02 /* disable interrupts */ +#define ATA_A_RESET 0x04 /* RESET controller */ +#define ATA_A_4BIT 0x08 /* 4 head bits */ +#define ATA_A_HOB 0x80 /* High Order Byte enable */ + +/* SATA register defines */ +#define ATA_SSTATUS 13 +#define ATA_SS_DET_MASK 0x0000000f +#define ATA_SS_DET_NO_DEVICE 0x00000000 +#define ATA_SS_DET_DEV_PRESENT 0x00000001 +#define ATA_SS_DET_PHY_ONLINE 0x00000003 +#define ATA_SS_DET_PHY_OFFLINE 0x00000004 + +#define ATA_SS_SPD_MASK 0x000000f0 +#define ATA_SS_SPD_NO_SPEED 0x00000000 +#define ATA_SS_SPD_GEN1 0x00000010 +#define ATA_SS_SPD_GEN2 0x00000020 +#define ATA_SS_SPD_GEN3 0x00000030 + +#define ATA_SS_IPM_MASK 0x00000f00 +#define ATA_SS_IPM_NO_DEVICE 0x00000000 +#define ATA_SS_IPM_ACTIVE 0x00000100 +#define ATA_SS_IPM_PARTIAL 0x00000200 +#define ATA_SS_IPM_SLUMBER 0x00000600 +#define ATA_SS_IPM_DEVSLEEP 0x00000800 + +#define ATA_SERROR 14 +#define ATA_SE_DATA_CORRECTED 0x00000001 +#define ATA_SE_COMM_CORRECTED 0x00000002 +#define ATA_SE_DATA_ERR 0x00000100 +#define ATA_SE_COMM_ERR 0x00000200 +#define ATA_SE_PROT_ERR 0x00000400 +#define ATA_SE_HOST_ERR 0x00000800 +#define ATA_SE_PHY_CHANGED 0x00010000 +#define ATA_SE_PHY_IERROR 0x00020000 +#define ATA_SE_COMM_WAKE 0x00040000 +#define ATA_SE_DECODE_ERR 0x00080000 +#define ATA_SE_PARITY_ERR 0x00100000 +#define ATA_SE_CRC_ERR 0x00200000 +#define ATA_SE_HANDSHAKE_ERR 0x00400000 +#define ATA_SE_LINKSEQ_ERR 0x00800000 +#define ATA_SE_TRANSPORT_ERR 0x01000000 +#define ATA_SE_UNKNOWN_FIS 0x02000000 +#define ATA_SE_EXCHANGED 0x04000000 + +#define ATA_SCONTROL 15 +#define ATA_SC_DET_MASK 0x0000000f +#define ATA_SC_DET_IDLE 0x00000000 +#define ATA_SC_DET_RESET 0x00000001 +#define ATA_SC_DET_DISABLE 0x00000004 + +#define ATA_SC_SPD_MASK 0x000000f0 +#define ATA_SC_SPD_NO_SPEED 0x00000000 +#define ATA_SC_SPD_SPEED_GEN1 0x00000010 +#define ATA_SC_SPD_SPEED_GEN2 0x00000020 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 + +#define ATA_SC_IPM_MASK 0x00000f00 +#define ATA_SC_IPM_NONE 0x00000000 +#define ATA_SC_IPM_DIS_PARTIAL 0x00000100 +#define ATA_SC_IPM_DIS_SLUMBER 0x00000200 +#define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400 + diff --git a/sys/powerpc/mpc85xx/lbc.c b/sys/powerpc/mpc85xx/lbc.c index 576fe8202d6e..8193d26d1c84 100644 --- a/sys/powerpc/mpc85xx/lbc.c +++ b/sys/powerpc/mpc85xx/lbc.c @@ -651,8 +651,8 @@ lbc_attach(device_t dev) free(di, M_LBC); continue; } - debugf("added child name='%s', node=%p\n", di->di_ofw.obd_name, - (void *)child); + debugf("added child name='%s', node=%x\n", di->di_ofw.obd_name, + child); device_set_ivars(cdev, di); } diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c index 2042e704f469..25b2009e056c 100644 --- a/sys/powerpc/ofw/ofw_machdep.c +++ b/sys/powerpc/ofw/ofw_machdep.c @@ -461,7 +461,7 @@ openfirmware_core(void *args) /* Restore initially saved trap vectors */ ofw_restore_trap_vec(save_trap_init); -#if defined(AIM) && !defined(__powerpc64__) +#ifndef __powerpc64__ /* * Clear battable[] translations */ diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index c9592e0567f1..91ccfaf136f6 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -530,16 +530,32 @@ cpu_booke_setup(int cpuid, uint16_t vers) { #ifdef BOOKE_E500 register_t hid0; + const char *bitmask; hid0 = mfspr(SPR_HID0); - /* Programe power-management mode. */ - hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP); - hid0 |= HID0_DOZE; + switch (vers) { + case FSL_E500mc: + bitmask = HID0_E500MC_BITMASK; + break; + case FSL_E5500: + case FSL_E6500: + bitmask = HID0_E5500_BITMASK; + break; + case FSL_E500v1: + case FSL_E500v2: + /* Only e500v1/v2 support HID0 power management setup. */ - mtspr(SPR_HID0, hid0); + /* Programe power-management mode. */ + hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP); + hid0 |= HID0_DOZE; - printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK); + mtspr(SPR_HID0, hid0); + default: + bitmask = HID0_E500_BITMASK; + break; + } + printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask); #endif if (cpu_idle_hook == NULL) diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c index ceecacfe534d..a3ee988d4386 100644 --- a/sys/powerpc/powerpc/db_trace.c +++ b/sys/powerpc/powerpc/db_trace.c @@ -118,12 +118,12 @@ db_frame(struct db_variable *vp, db_expr_t *valuep, int op) if (kdb_frame == NULL) return (0); - reg = (register_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep); - if (op == DB_VAR_GET) - *valuep = *reg; - else - *reg = *valuep; - return (1); + reg = (register_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep); + if (op == DB_VAR_GET) + *valuep = *reg; + else + *reg = *valuep; + return (1); } @@ -215,12 +215,17 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) switch (tf->exc) { case EXC_DSI: /* XXX take advantage of the union. */ +#ifdef BOOKE + db_printf("DSI %s trap @ %#zx by ", + (tf->cpu.booke.esr & ESR_ST) ? "write" + : "read", tf->dar); +#else db_printf("DSI %s trap @ %#zx by ", (tf->cpu.aim.dsisr & DSISR_STORE) ? "write" : "read", tf->dar); +#endif goto print_trap; case EXC_ALI: - /* XXX take advantage of the union. */ db_printf("ALI trap @ %#zx (xSR %#x) ", tf->dar, (uint32_t)tf->cpu.aim.dsisr); goto print_trap; @@ -237,8 +242,8 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) case EXC_SC: trapstr = "SC"; break; case EXC_EXI: trapstr = "EXI"; break; case EXC_MCHK: trapstr = "MCHK"; break; -#if !defined(BOOKE) case EXC_VEC: trapstr = "VEC"; break; +#if !defined(BOOKE) case EXC_FPA: trapstr = "FPA"; break; case EXC_BPT: trapstr = "BPT"; break; case EXC_TRC: trapstr = "TRC"; break; diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index c9af882c45dd..8ecfe0ab06bc 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -225,6 +225,7 @@ ASSYM(MAXCOMLEN, MAXCOMLEN); #ifdef __powerpc64__ ASSYM(PSL_CM, PSL_CM); #endif +ASSYM(PSL_GS, PSL_GS); ASSYM(PSL_DE, PSL_DE); ASSYM(PSL_DS, PSL_DS); ASSYM(PSL_IS, PSL_IS); diff --git a/sys/powerpc/powerpc/stack_machdep.c b/sys/powerpc/powerpc/stack_machdep.c index 451e7bef71b8..20e1f79238a6 100644 --- a/sys/powerpc/powerpc/stack_machdep.c +++ b/sys/powerpc/powerpc/stack_machdep.c @@ -110,6 +110,6 @@ stack_save(struct stack *st) { register_t frame; - frame = (register_t)__builtin_frame_address(1); + frame = (register_t)__builtin_frame_address(0); stack_capture(st, frame); } diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC index 0c78e688f479..09e0ac16bf29 100644 --- a/sys/riscv/conf/GENERIC +++ b/sys/riscv/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -30,11 +30,12 @@ makeoptions WITHOUT_MODULES="usb otusfw mwlfw ispfw mwlfw ralfw rtwnfw" options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP options IPSEC # IP (v4/v6) security -options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem diff --git a/sys/riscv/include/elf.h b/sys/riscv/include/elf.h index 3a89577ebe31..ee09e3ce5bbc 100644 --- a/sys/riscv/include/elf.h +++ b/sys/riscv/include/elf.h @@ -90,8 +90,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #define ELF_TARG_CLASS ELFCLASS64 diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 8011ced6b662..0fee628470f9 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -1614,7 +1614,7 @@ free_pv_chunk(struct pv_chunk *pc) #if 0 /* TODO: For minidump */ dump_drop_page(m->phys_addr); #endif - vm_page_unwire(m, PQ_INACTIVE); + vm_page_unwire(m, PQ_NONE); vm_page_free(m); } diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index 18bf80d57854..0f00fb2e02c0 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -4,11 +4,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the @@ -28,10 +28,11 @@ makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption +options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security -options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 +options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem diff --git a/sys/sparc64/conf/GENERIC-NODEBUG b/sys/sparc64/conf/GENERIC-NODEBUG index ce5a89551a84..ce4d097d2d75 100644 --- a/sys/sparc64/conf/GENERIC-NODEBUG +++ b/sys/sparc64/conf/GENERIC-NODEBUG @@ -12,11 +12,11 @@ # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # -# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the -# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the diff --git a/sys/sparc64/include/elf.h b/sys/sparc64/include/elf.h index 448ca66793ec..745cf55efeb6 100644 --- a/sys/sparc64/include/elf.h +++ b/sys/sparc64/include/elf.h @@ -92,8 +92,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #if __ELF_WORD_SIZE == 32 diff --git a/sys/sparc64/sparc64/dump_machdep.c b/sys/sparc64/sparc64/dump_machdep.c index 769c8d1a2cf6..5b61c5d237c8 100644 --- a/sys/sparc64/sparc64/dump_machdep.c +++ b/sys/sparc64/sparc64/dump_machdep.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); static off_t fileofs; -extern off_t dumplo; extern struct dump_pa dump_map[DUMPSYS_MD_PA_NPAIRS]; int do_minidump = 0; @@ -99,7 +98,7 @@ dumpsys(struct dumperinfo *di) printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg); - error = dump_start(di, &kdh, &dumplo); + error = dump_start(di, &kdh); if (error != 0) goto fail; @@ -128,7 +127,7 @@ dumpsys(struct dumperinfo *di) if (error < 0) goto fail; - error = dump_finish(di, &kdh, dumplo); + error = dump_finish(di, &kdh); if (error != 0) goto fail; diff --git a/sys/sparc64/sparc64/stack_machdep.c b/sys/sparc64/sparc64/stack_machdep.c index 329368d78051..451aead4e631 100644 --- a/sys/sparc64/sparc64/stack_machdep.c +++ b/sys/sparc64/sparc64/stack_machdep.c @@ -93,5 +93,5 @@ void stack_save(struct stack *st) { - stack_capture(st, (struct frame *)__builtin_frame_address(1)); + stack_capture(st, (struct frame *)__builtin_frame_address(0)); } diff --git a/sys/sys/_kstack_cache.h b/sys/sys/_kstack_cache.h index 0ad8f5081891..7271206c1503 100644 --- a/sys/sys/_kstack_cache.h +++ b/sys/sys/_kstack_cache.h @@ -38,6 +38,10 @@ struct kstack_cache_entry { extern struct kstack_cache_entry *kstack_cache; +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + #endif diff --git a/sys/sys/_task.h b/sys/sys/_task.h index d3be7198dc2f..d46659f43e87 100644 --- a/sys/sys/_task.h +++ b/sys/sys/_task.h @@ -65,7 +65,8 @@ struct grouptask { void *gt_taskqueue; LIST_ENTRY(grouptask) gt_list; void *gt_uniq; - char *gt_name; +#define GROUPTASK_NAMELEN 32 + char gt_name[GROUPTASK_NAMELEN]; int16_t gt_irq; int16_t gt_cpu; }; diff --git a/sys/arm/allwinner/a10_gpio.h b/sys/sys/auxv.h similarity index 79% rename from sys/arm/allwinner/a10_gpio.h rename to sys/sys/auxv.h index 8e998c9aef7a..d389bac49623 100644 --- a/sys/arm/allwinner/a10_gpio.h +++ b/sys/sys/auxv.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013 Ganbold Tsagaankhuu + * Copyright (c) 2017 Michal Meloun * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -17,19 +17,23 @@ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 + * 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 + * 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. * * $FreeBSD$ */ -#ifndef _A10_GPIO_H_ -#define _A10_GPIO_H_ +#ifndef _SYS_AUXV_H_ +#define _SYS_AUXV_H_ -#define A10_GPIO_FUNC_MII 2 -#define A10_GPIO_FUNC_RGMII 5 +#include +#include -#endif +__BEGIN_DECLS +int elf_aux_info(int aux, void *buf, int buflen); +__END_DECLS + +#endif /* !_SYS_AUXV_H_ */ diff --git a/sys/sys/blist.h b/sys/sys/blist.h index 486e04eb6910..049f28c80894 100644 --- a/sys/sys/blist.h +++ b/sys/sys/blist.h @@ -82,7 +82,7 @@ typedef struct blist { daddr_t bl_blocks; /* area of coverage */ u_daddr_t bl_radix; /* coverage radix */ daddr_t bl_cursor; /* next-fit search starts at */ - blmeta_t *bl_root; /* root of radix tree */ + blmeta_t bl_root[1]; /* root of radix tree */ } *blist_t; #define BLIST_META_RADIX 16 diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 58bd91e34ff9..5d4f0dc6784e 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -70,7 +70,7 @@ extern struct bio_ops { struct vm_object; struct vm_page; -typedef unsigned char b_xflags_t; +typedef uint32_t b_xflags_t; /* * The buffer header describes an I/O operation in the kernel. @@ -104,6 +104,8 @@ struct buf { off_t b_iooffset; long b_resid; void (*b_iodone)(struct buf *); + void (*b_ckhashcalc)(struct buf *); + uint64_t b_ckhash; /* B_CKHASH requested check-hash */ daddr_t b_blkno; /* Underlying physical block number. */ off_t b_offset; /* Offset into file. */ TAILQ_ENTRY(buf) b_bobufs; /* (V) Buffer's associated vnode. */ @@ -209,7 +211,7 @@ struct buf { #define B_CACHE 0x00000020 /* Bread found us in the cache. */ #define B_VALIDSUSPWRT 0x00000040 /* Valid write during suspension. */ #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */ -#define B_00000100 0x00000100 /* Available flag. */ +#define B_CKHASH 0x00000100 /* checksum hash calculated on read */ #define B_DONE 0x00000200 /* I/O completed. */ #define B_EINTR 0x00000400 /* I/O was interrupted */ #define B_NOREUSE 0x00000800 /* Contents not reused once released. */ @@ -242,12 +244,17 @@ struct buf { /* * These flags are kept in b_xflags. + * + * BX_FSPRIV reserves a set of eight flags that may be used by individual + * filesystems for their own purpose. Their specific definitions are + * found in the header files for each filesystem that uses them. */ #define BX_VNDIRTY 0x00000001 /* On vnode dirty list */ #define BX_VNCLEAN 0x00000002 /* On vnode clean list */ #define BX_BKGRDWRITE 0x00000010 /* Do writes in background */ #define BX_BKGRDMARKER 0x00000020 /* Mark buffer for splay tree */ #define BX_ALTDATA 0x00000040 /* Holds extended data */ +#define BX_FSPRIV 0x00FF0000 /* filesystem-specific flags mask */ #define PRINT_BUF_XFLAGS "\20\7altdata\6bkgrdmarker\5bkgrdwrite\2clean\1dirty" @@ -467,6 +474,7 @@ buf_track(struct buf *bp, const char *location) #define GB_NOWAIT_BD 0x0004 /* Do not wait for bufdaemon. */ #define GB_UNMAPPED 0x0008 /* Do not mmap buffer pages. */ #define GB_KVAALLOC 0x0010 /* But allocate KVA. */ +#define GB_CKHASH 0x0020 /* If reading, calc checksum hash */ #ifdef _KERNEL extern int nbuf; /* The number of buffer headers */ @@ -504,15 +512,15 @@ int buf_dirty_count_severe(void); void bremfree(struct buf *); void bremfreef(struct buf *); /* XXX Force bremfree, only for nfs. */ #define bread(vp, blkno, size, cred, bpp) \ - breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, 0, bpp) + breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, 0, NULL, bpp) #define bread_gb(vp, blkno, size, cred, gbflags, bpp) \ breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, \ - gbflags, bpp) + gbflags, NULL, bpp) #define breadn(vp, blkno, size, rablkno, rabsize, cnt, cred, bpp) \ - breadn_flags(vp, blkno, size, rablkno, rabsize, cnt, cred, 0, bpp) + breadn_flags(vp, blkno, size, rablkno, rabsize, cnt, cred, \ + 0, NULL, bpp) int breadn_flags(struct vnode *, daddr_t, int, daddr_t *, int *, int, - struct ucred *, int, struct buf **); -void breada(struct vnode *, daddr_t *, int *, int, struct ucred *); + struct ucred *, int, void (*)(struct buf *), struct buf **); void bdwrite(struct buf *); void bawrite(struct buf *); void babarrierwrite(struct buf *); diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 03912978c512..34644c24aa98 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -491,6 +491,7 @@ struct resource_spec { int rid; int flags; }; +#define RESOURCE_SPEC_END {-1, 0, 0} int bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res); @@ -632,7 +633,6 @@ struct sysctl_oid *devclass_get_sysctl_tree(devclass_t dc); /* * Access functions for device resources. */ - int resource_int_value(const char *name, int unit, const char *resname, int *result); int resource_long_value(const char *name, int unit, const char *resname, @@ -644,12 +644,6 @@ int resource_find_match(int *anchor, const char **name, int *unit, const char *resname, const char *value); int resource_find_dev(int *anchor, const char *name, int *unit, const char *resname, const char *value); -int resource_set_int(const char *name, int unit, const char *resname, - int value); -int resource_set_long(const char *name, int unit, const char *resname, - long value); -int resource_set_string(const char *name, int unit, const char *resname, - const char *value); int resource_unset_value(const char *name, int unit, const char *resname); /* diff --git a/sys/sys/cnv.h b/sys/sys/cnv.h index 8b76e596bf2e..c89eed37df3e 100644 --- a/sys/sys/cnv.h +++ b/sys/sys/cnv.h @@ -47,6 +47,12 @@ typedef struct nvlist nvlist_t; __BEGIN_DECLS +/* + * Functions which returns information about the given cookie. + */ +const char *cnvlist_name(void *cookiep); +int cnvlist_type(void *cookiep); + /* * The cnvlist_get functions returns value associated with the given cookie. * If it returns a pointer, the pointer represents internal buffer and should diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 1b4e576db25c..90e2afe20529 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -336,21 +336,24 @@ struct dumperinfo { off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ void *blockbuf; /* Buffer for padding shorter dump blocks */ + off_t dumpoff; /* Offset of ongoing kernel dump. */ struct kerneldumpcrypto *kdc; /* Kernel dump crypto. */ + struct kerneldumpgz *kdgz; /* Kernel dump compression. */ }; +extern int dumping; /* system is dumping */ + +int doadump(boolean_t); int set_dumper(struct dumperinfo *di, const char *devname, struct thread *td, - uint8_t encrypt, const uint8_t *key, uint32_t encryptedkeysize, - const uint8_t *encryptedkey); + uint8_t compression, uint8_t encryption, const uint8_t *key, + uint32_t encryptedkeysize, const uint8_t *encryptedkey); + +int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh); +int dump_append(struct dumperinfo *, void *, vm_offset_t, size_t); +int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); +int dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh); void dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh, char *magic, uint32_t archver, uint64_t dumplen); -int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh, - off_t *dumplop); -int dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh, - off_t dumplo); -int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); -int doadump(boolean_t); -extern int dumping; /* system is dumping */ #endif /* _KERNEL */ diff --git a/sys/sys/disk.h b/sys/sys/disk.h index 873efd1ee213..4ab0b09e12cd 100644 --- a/sys/sys/disk.h +++ b/sys/sys/disk.h @@ -134,6 +134,7 @@ struct diocgattr_arg { char str[DISK_IDENT_SIZE]; off_t off; int i; + uint16_t u16; } value; }; #define DIOCGATTR _IOWR('d', 142, struct diocgattr_arg) @@ -142,6 +143,7 @@ struct diocgattr_arg { struct diocskerneldump_arg { uint8_t kda_enable; + uint8_t kda_compression; uint8_t kda_encryption; uint8_t kda_key[KERNELDUMP_KEY_MAX_SIZE]; uint32_t kda_encryptedkeysize; diff --git a/sys/sys/efi.h b/sys/sys/efi.h index 05ccfab4908a..4e381ee84552 100644 --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -168,6 +168,25 @@ struct efi_systbl { }; extern vm_paddr_t efi_systbl_phys; + +/* Internal MD EFI functions */ +int efi_arch_enter(void); +void efi_arch_leave(void); +bool efi_create_1t1_map(struct efi_md *, int, int); +void efi_destroy_1t1_map(void); + +/* Public MI EFI functions */ +int efi_rt_ok(void); +int efi_get_table(struct uuid *uuid, void **ptr); +int efi_get_time(struct efi_tm *tm); +int efi_reset_system(void); +int efi_set_time(struct efi_tm *tm); +int efi_var_get(uint16_t *name, struct uuid *vendor, uint32_t *attrib, + size_t *datasize, void *data); +int efi_var_nextname(size_t *namesize, uint16_t *name, struct uuid *vendor); +int efi_var_set(uint16_t *name, struct uuid *vendor, uint32_t attrib, + size_t datasize, void *data); + #endif /* _KERNEL */ #endif /* _SYS_EFI_H_ */ diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index c66bbae499eb..8634e0a9d5db 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -757,6 +757,7 @@ typedef struct { #define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */ #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */ +#define NT_ARM_VFP 0x400 /* ARM VFP registers */ /* Symbol Binding - ELFNN_ST_BIND - st_info */ #define STB_LOCAL 0 /* Local symbol */ diff --git a/sys/sys/errno.h b/sys/sys/errno.h index 97fe1bdb63db..52e5a1d91511 100644 --- a/sys/sys/errno.h +++ b/sys/sys/errno.h @@ -38,7 +38,7 @@ #ifndef _SYS_ERRNO_H_ #define _SYS_ERRNO_H_ -#ifndef _KERNEL +#if !defined(_KERNEL) && !defined(_STAND) #include __BEGIN_DECLS int * __error(void); diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index b071c63926ee..7fccffffa8a8 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -141,12 +141,21 @@ do { \ if ((_el = eventhandler_find_list(#name)) != NULL) \ eventhandler_deregister(_el, tag); \ } while(0) - + +#define EVENTHANDLER_DEREGISTER_NOWAIT(name, tag) \ +do { \ + struct eventhandler_list *_el; \ + \ + if ((_el = eventhandler_find_list(#name)) != NULL) \ + eventhandler_deregister_nowait(_el, tag); \ +} while(0) eventhandler_tag eventhandler_register(struct eventhandler_list *list, const char *name, void *func, void *arg, int priority); void eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag); +void eventhandler_deregister_nowait(struct eventhandler_list *list, + eventhandler_tag tag); struct eventhandler_list *eventhandler_find_list(const char *name); void eventhandler_prune_list(struct eventhandler_list *list); @@ -284,4 +293,15 @@ typedef void (*swapoff_fn)(void *, struct swdevt *); EVENTHANDLER_DECLARE(swapon, swapon_fn); EVENTHANDLER_DECLARE(swapoff, swapoff_fn); +/* newbus device events */ +enum evhdev_detach { + EVHDEV_DETACH_BEGIN, /* Before detach() is called */ + EVHDEV_DETACH_COMPLETE, /* After detach() returns 0 */ + EVHDEV_DETACH_FAILED /* After detach() returns err */ +}; +typedef void (*device_attach_fn)(void *, device_t); +typedef void (*device_detach_fn)(void *, device_t, enum evhdev_detach); +EVENTHANDLER_DECLARE(device_attach, device_attach_fn); +EVENTHANDLER_DECLARE(device_detach, device_detach_fn); + #endif /* _SYS_EVENTHANDLER_H_ */ diff --git a/sys/sys/gtaskqueue.h b/sys/sys/gtaskqueue.h index be36a4756af8..e85196372323 100644 --- a/sys/sys/gtaskqueue.h +++ b/sys/sys/gtaskqueue.h @@ -58,9 +58,7 @@ int taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *grptask, void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask); struct taskqgroup *taskqgroup_create(char *name); void taskqgroup_destroy(struct taskqgroup *qgroup); -int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri); -int taskqgroup_adjust_once(struct taskqgroup *qgroup, int cnt, int stride, bool ithread, int pri); -void taskqgroup_set_adjust(struct taskqgroup *qgroup, void (*adjust_func)(void*)); +int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride); #define TASK_ENQUEUED 0x1 #define TASK_SKIP_WAKEUP 0x2 @@ -82,40 +80,27 @@ void taskqgroup_set_adjust(struct taskqgroup *qgroup, void (*adjust_func)(void*) #define TASKQGROUP_DECLARE(name) \ extern struct taskqgroup *qgroup_##name - -#define TASKQGROUP_DEFINE(name, cnt, stride, intr, pri) \ +#define TASKQGROUP_DEFINE(name, cnt, stride) \ \ struct taskqgroup *qgroup_##name; \ \ static void \ -taskqgroup_adjust_##name(void *arg) \ -{ \ - int max = (intr) ? 1 : (cnt); \ - if (arg != NULL) { \ - uintptr_t maxcpu = (uintptr_t) arg; \ - max = maxcpu; \ - } \ - \ - taskqgroup_adjust_once(qgroup_##name, max, (stride), (intr), (pri)); \ -} \ - \ -SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \ - taskqgroup_adjust_##name, NULL); \ - \ -static void \ taskqgroup_define_##name(void *arg) \ { \ qgroup_##name = taskqgroup_create(#name); \ - taskqgroup_set_adjust(qgroup_##name, taskqgroup_adjust_##name); \ } \ + \ SYSINIT(taskqgroup_##name, SI_SUB_TASKQ, SI_ORDER_FIRST, \ - taskqgroup_define_##name, NULL) - - - - - - + taskqgroup_define_##name, NULL); \ + \ +static void \ +taskqgroup_adjust_##name(void *arg) \ +{ \ + taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \ +} \ + \ +SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \ + taskqgroup_adjust_##name, NULL) TASKQGROUP_DECLARE(net); TASKQGROUP_DECLARE(softirq); diff --git a/sys/sys/gzio.h b/sys/sys/gzio.h index c61c2818f2e9..524d80238fac 100644 --- a/sys/sys/gzio.h +++ b/sys/sys/gzio.h @@ -40,6 +40,7 @@ typedef int (*gzio_cb)(void *, size_t, off_t, void *); struct gzio_stream; struct gzio_stream *gzio_init(gzio_cb cb, enum gzio_mode, size_t, int, void *); +void gzio_reset(struct gzio_stream *); int gzio_write(struct gzio_stream *, void *, u_int); int gzio_flush(struct gzio_stream *); void gzio_fini(struct gzio_stream *); diff --git a/sys/sys/ipmi.h b/sys/sys/ipmi.h index b8e318a921bc..e54010a61108 100644 --- a/sys/sys/ipmi.h +++ b/sys/sys/ipmi.h @@ -56,8 +56,25 @@ #define IPMI_ASYNC_EVENT_RECV_TYPE 2 #define IPMI_CMD_RECV_TYPE 3 +#define IPMI_CHASSIS_REQUEST 0x00 +# define IPMI_CHASSIS_CONTROL 0x02 +# define IPMI_CC_POWER_DOWN 0x0 +# define IPMI_CC_POWER_UP 0x1 +# define IPMI_CC_POWER_CYCLE 0x2 +# define IPMI_CC_HARD_RESET 0x3 +# define IPMI_CC_PULSE_DI 0x4 +# define IPMI_CC_SOFT_OVERTEMP 0x5 + #define IPMI_APP_REQUEST 0x06 #define IPMI_GET_DEVICE_ID 0x01 +# define IPMI_ADS_CHASSIS 0x80 +# define IPMI_ADS_BRIDGE 0x40 +# define IPMI_ADS_EVENT_GEN 0x20 +# define IPMI_ADS_EVENT_RCV 0x10 +# define IPMI_ADS_FRU_INV 0x08 +# define IPMI_ADS_SEL 0x04 +# define IPMI_ADS_SDR 0x02 +# define IPMI_ADS_SENSOR 0x01 #define IPMI_CLEAR_FLAGS 0x30 #define IPMI_GET_MSG_FLAGS 0x31 # define IPMI_MSG_AVAILABLE 0x01 @@ -72,7 +89,14 @@ #define IPMI_SET_WD_TIMER_SMS_OS 0x04 #define IPMI_SET_WD_TIMER_DONT_STOP 0x40 +#define IPMI_SET_WD_ACTION_NONE 0x00 #define IPMI_SET_WD_ACTION_RESET 0x01 +#define IPMI_SET_WD_ACTION_POWER_DOWN 0x02 +#define IPMI_SET_WD_ACTION_POWER_CYCLE 0x03 +#define IPMI_SET_WD_PREACTION_NONE (0x00 << 4) +#define IPMI_SET_WD_PREACTION_SMI (0x01 << 4) +#define IPMI_SET_WD_PREACTION_NMI (0x02 << 4) +#define IPMI_SET_WD_PREACTION_MI (0x03 << 4) struct ipmi_msg { unsigned char netfn; diff --git a/sys/sys/kdb.h b/sys/sys/kdb.h index 49c8c32071d8..1e68c3982850 100644 --- a/sys/sys/kdb.h +++ b/sys/sys/kdb.h @@ -59,7 +59,7 @@ struct kdb_dbbe { }; \ DATA_SET(kdb_dbbe_set, name##_dbbe) -extern int kdb_active; /* Non-zero while in debugger. */ +extern u_char kdb_active; /* Non-zero while in debugger. */ extern int debugger_on_panic; /* enter the debugger on panic. */ extern struct kdb_dbbe *kdb_dbbe; /* Default debugger backend or NULL. */ extern struct trapframe *kdb_frame; /* Frame to kdb_trap(). */ diff --git a/sys/sys/kerneldump.h b/sys/sys/kerneldump.h index afd762923a57..864640ae5ff1 100644 --- a/sys/sys/kerneldump.h +++ b/sys/sys/kerneldump.h @@ -55,6 +55,9 @@ #define htod64(x) (x) #endif +#define KERNELDUMP_COMP_NONE 0 +#define KERNELDUMP_COMP_GZIP 1 + #define KERNELDUMP_ENC_NONE 0 #define KERNELDUMP_ENC_AES_256_CBC 1 @@ -75,8 +78,8 @@ struct kerneldumpheader { #define KERNELDUMPMAGIC_CLEARED "Cleared Kernel Dump" char architecture[12]; uint32_t version; -#define KERNELDUMPVERSION 2 -#define KERNELDUMP_TEXT_VERSION 2 +#define KERNELDUMPVERSION 3 +#define KERNELDUMP_TEXT_VERSION 3 uint32_t architectureversion; #define KERNELDUMP_AARCH64_VERSION 1 #define KERNELDUMP_AMD64_VERSION 2 @@ -87,12 +90,14 @@ struct kerneldumpheader { #define KERNELDUMP_RISCV_VERSION 1 #define KERNELDUMP_SPARC64_VERSION 1 uint64_t dumplength; /* excl headers */ + uint64_t dumpextent; uint64_t dumptime; uint32_t dumpkeysize; uint32_t blocksize; + uint8_t compression; char hostname[64]; char versionstring[192]; - char panicstring[188]; + char panicstring[179]; uint32_t parity; }; diff --git a/sys/sys/lock.h b/sys/sys/lock.h index a5beba116fca..fb3ad3101e88 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -226,6 +226,13 @@ lock_delay_arg_init(struct lock_delay_arg *la, struct lock_delay_config *lc) la->spin_cnt = 0; } +#define lock_delay_spin(n) do { \ + u_int _i; \ + \ + for (_i = (n); _i > 0; _i--) \ + cpu_spinwait(); \ +} while (0) + #define LOCK_DELAY_SYSINIT(func) \ SYSINIT(func##_ld, SI_SUB_LOCK, SI_ORDER_ANY, func, NULL) diff --git a/sys/sys/mbpool.h b/sys/sys/mbpool.h deleted file mode 100644 index 48fd89eb99b5..000000000000 --- a/sys/sys/mbpool.h +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * Copyright (c) 2003 - * Fraunhofer Institute for Open Communication Systems (FhG Fokus). - * All rights reserved. - * - * 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 AUTHOR 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 AUTHOR 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. - * - * Author: Hartmut Brandt - */ - -/* - * This implements pools of DMA-able buffers that conserve DMA address space - * by putting several buffers into one page and that allow to map between - * 32-bit handles for the buffer and buffer addresses (to use 32-bit network - * interfaces on 64bit machines). This assists network interfaces that may need - * huge numbers of mbufs. - * - * $FreeBSD$ - */ -#ifndef _SYS_MBPOOL_H_ -#define _SYS_MBPOOL_H_ - -#ifdef _KERNEL - -#include - -/* opaque */ -struct mbpool; - -/* size of reserved area at end of each chunk */ -#define MBPOOL_TRAILER_SIZE 4 - -/* maximum value of max_pages */ -#define MBPOOL_MAX_MAXPAGES ((1 << 14) - 1) - -/* maximum number of chunks per page */ -#define MBPOOL_MAX_CHUNKS (1 << 9) - -/* initialize a pool */ -int mbp_create(struct mbpool **, const char *, bus_dma_tag_t, u_int, - size_t, size_t); - -/* destroy a pool */ -void mbp_destroy(struct mbpool *); - -/* allocate a chunk and set used and on card */ -void *mbp_alloc(struct mbpool *, bus_addr_t *, uint32_t *); - -/* free a chunk */ -void mbp_free(struct mbpool *, void *); - -/* free a chunk that is an external mbuf */ -void mbp_ext_free(struct mbuf *, void *, void *); - -/* free all buffers that are marked to be on the card */ -void mbp_card_free(struct mbpool *); - -/* count used buffers and buffers on card */ -void mbp_count(struct mbpool *, u_int *, u_int *, u_int *); - -/* get the buffer from a handle and clear card bit */ -void *mbp_get(struct mbpool *, uint32_t); - -/* get the buffer from a handle and don't clear card bit */ -void *mbp_get_keep(struct mbpool *, uint32_t); - -/* sync the chunk */ -void mbp_sync(struct mbpool *, uint32_t, bus_addr_t, bus_size_t, u_int); - -#endif /* _KERNEL */ -#endif /* _SYS_MBPOOL_H_ */ diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 817153d7698c..b4f21014bf5e 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -197,17 +197,33 @@ struct pkthdr { * Compile-time assertions in uipc_mbuf.c test these values to ensure that * they are correct. */ +typedef void m_ext_free_t(struct mbuf *); struct m_ext { union { - volatile u_int ext_count; /* value of ref count info */ - volatile u_int *ext_cnt; /* pointer to ref count info */ + /* + * If EXT_FLAG_EMBREF is set, then we use refcount in the + * mbuf, the 'ext_count' member. Otherwise, we have a + * shadow copy and we use pointer 'ext_cnt'. The original + * mbuf is responsible to carry the pointer to free routine + * and its arguments. They aren't copied into shadows in + * mb_dupcl() to avoid dereferencing next cachelines. + */ + volatile u_int ext_count; + volatile u_int *ext_cnt; }; - caddr_t ext_buf; /* start of buffer */ + char *ext_buf; /* start of buffer */ uint32_t ext_size; /* size of buffer, for ext_free */ uint32_t ext_type:8, /* type of external storage */ ext_flags:24; /* external storage mbuf flags */ - void (*ext_free) /* free routine if not the usual */ - (struct mbuf *, void *, void *); + /* + * Fields below store the free context for the external storage. + * They are valid only in the refcount carrying mbuf, the one with + * EXT_FLAG_EMBREF flag, with exclusion for EXT_EXTREF type, where + * the free context is copied into all mbufs that use same external + * storage. + */ +#define m_ext_copylen offsetof(struct m_ext, ext_free) + m_ext_free_t *ext_free; /* free routine if not the usual */ void *ext_arg1; /* optional argument pointer */ void *ext_arg2; /* optional argument pointer */ }; @@ -335,6 +351,16 @@ struct mbuf { * for ordering and distribution without explicit affinity. Additionally, * M_HASHTYPE_OPAQUE_HASH indicates that the flow identifier has hash * properties. + * + * The meaning of the IPV6_EX suffix: + * "o Home address from the home address option in the IPv6 destination + * options header. If the extension header is not present, use the Source + * IPv6 Address. + * o IPv6 address that is contained in the Routing-Header-Type-2 from the + * associated extension header. If the extension header is not present, + * use the Destination IPv6 Address." + * Quoted from: + * https://docs.microsoft.com/en-us/windows-hardware/drivers/network/rss-hashing-types#ndishashipv6ex */ #define M_HASHTYPE_HASHPROP 0x80 /* has hash properties */ #define M_HASHTYPE_HASH(t) (M_HASHTYPE_HASHPROP | (t)) @@ -348,10 +374,7 @@ struct mbuf { * ext hdrs */ #define M_HASHTYPE_RSS_TCP_IPV6_EX M_HASHTYPE_HASH(6) /* TCPv6 4-tuple + * ext hdrs */ -/* Non-standard RSS hash types */ #define M_HASHTYPE_RSS_UDP_IPV4 M_HASHTYPE_HASH(7) /* IPv4 UDP 4-tuple*/ -#define M_HASHTYPE_RSS_UDP_IPV4_EX M_HASHTYPE_HASH(8) /* IPv4 UDP 4-tuple + - * ext hdrs */ #define M_HASHTYPE_RSS_UDP_IPV6 M_HASHTYPE_HASH(9) /* IPv6 UDP 4-tuple*/ #define M_HASHTYPE_RSS_UDP_IPV6_EX M_HASHTYPE_HASH(10)/* IPv6 UDP 4-tuple + * ext hdrs */ @@ -403,7 +426,6 @@ struct mbuf { #define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */ #define EXT_PACKET 6 /* mbuf+cluster from packet zone */ #define EXT_MBUF 7 /* external mbuf reference */ -#define EXT_SFBUF_NOCACHE 8 /* sendfile(2)'s sf_buf not to be cached */ #define EXT_VENDOR1 224 /* for vendor-internal use */ #define EXT_VENDOR2 225 /* for vendor-internal use */ @@ -429,10 +451,10 @@ struct mbuf { #define EXT_FLAG_NOFREE 0x000010 /* don't free mbuf to pool, notyet */ -#define EXT_FLAG_VENDOR1 0x010000 /* for vendor-internal use */ -#define EXT_FLAG_VENDOR2 0x020000 /* for vendor-internal use */ -#define EXT_FLAG_VENDOR3 0x040000 /* for vendor-internal use */ -#define EXT_FLAG_VENDOR4 0x080000 /* for vendor-internal use */ +#define EXT_FLAG_VENDOR1 0x010000 /* These flags are vendor */ +#define EXT_FLAG_VENDOR2 0x020000 /* or submodule specific, */ +#define EXT_FLAG_VENDOR3 0x040000 /* not used by mbuf code. */ +#define EXT_FLAG_VENDOR4 0x080000 /* Set/read by submodule. */ #define EXT_FLAG_EXP1 0x100000 /* for experimental use */ #define EXT_FLAG_EXP2 0x200000 /* for experimental use */ @@ -448,12 +470,6 @@ struct mbuf { "\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \ "\30EXT_FLAG_EXP4" -/* - * External reference/free functions. - */ -void sf_ext_free(void *, void *); -void sf_ext_free_nocache(void *, void *); - /* * Flags indicating checksum, segmentation and other offload work to be * done, or already done, by hardware or lower layers. It is split into @@ -603,9 +619,8 @@ struct mbuf *m_devget(char *, int, int, struct ifnet *, void (*)(char *, caddr_t, u_int)); struct mbuf *m_dup(const struct mbuf *, int); int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); -void m_extadd(struct mbuf *, caddr_t, u_int, - void (*)(struct mbuf *, void *, void *), void *, void *, - int, int); +void m_extadd(struct mbuf *, char *, u_int, m_ext_free_t, + void *, void *, int, int); u_int m_fixhdr(struct mbuf *); struct mbuf *m_fragment(struct mbuf *, int, int); void m_freem(struct mbuf *); @@ -660,8 +675,8 @@ m_gettype(int size) * Associated an external reference counted buffer with an mbuf. */ static __inline void -m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt, - void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2) +m_extaddref(struct mbuf *m, char *buf, u_int size, u_int *ref_cnt, + m_ext_free_t freef, void *arg1, void *arg2) { KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__)); @@ -857,7 +872,7 @@ m_extrefcnt(struct mbuf *m) #define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) #define MCLGET(m, how) m_clget((m), (how)) #define MEXTADD(m, buf, size, free, arg1, arg2, flags, type) \ - m_extadd((m), (caddr_t)(buf), (size), (free), (arg1), (arg2), \ + m_extadd((m), (char *)(buf), (size), (free), (arg1), (arg2), \ (flags), (type)) #define m_getm(m, len, how, type) \ m_getm2((m), (len), (how), (type), M_PKTHDR) diff --git a/sys/sys/module.h b/sys/sys/module.h index 5a268fc11d7e..754716114ac0 100644 --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -183,7 +183,7 @@ struct mod_pnp_match_info &_module_pnp_##b##_##unique, #b); /** * descr is a string that describes each entry in the table. The general - * form is (TYPE:pnp_name[/pnp_name];)* + * form is the grammar (TYPE:pnp_name[/pnp_name];)* * where TYPE is one of the following: * U8 uint8_t element * V8 like U8 and 0xff means match any @@ -196,12 +196,14 @@ struct mod_pnp_match_info * V32 like U32 and 0xffffffff means match any * W32 Two 16-bit values with first pnp_name in LSW and second in MSW. * Z pointer to a string to match exactly - * D like Z, but is the string passed to device_set_descr() + * D pointer to a string to human readable description for device * P A pointer that should be ignored * E EISA PNP Identifier (in binary, but bus publishes string) * K Key for whole table. pnp_name=value. must be last, if present. * * The pnp_name "#" is reserved for other fields that should be ignored. + * Otherwise pnp_name must match the name from the parent device's pnpinfo + * output. The second pnp_name is used for the W32 type. */ extern struct sx modules_sx; diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h index 0097d0800a48..d2b3702f2a17 100644 --- a/sys/sys/mutex.h +++ b/sys/sys/mutex.h @@ -65,15 +65,11 @@ * State bits kept in mutex->mtx_lock, for the DEFAULT lock type. None of this, * with the exception of MTX_UNOWNED, applies to spin locks. */ +#define MTX_UNOWNED 0x00000000 /* Cookie for free mutex */ #define MTX_RECURSED 0x00000001 /* lock recursed (for MTX_DEF only) */ #define MTX_CONTESTED 0x00000002 /* lock contested (for MTX_DEF only) */ -#define MTX_UNOWNED 0x00000004 /* Cookie for free mutex */ -#define MTX_FLAGMASK (MTX_RECURSED | MTX_CONTESTED | MTX_UNOWNED) - -/* - * Value stored in mutex->mtx_lock to denote a destroyed mutex. - */ -#define MTX_DESTROYED (MTX_CONTESTED | MTX_UNOWNED) +#define MTX_DESTROYED 0x00000004 /* lock destroyed */ +#define MTX_FLAGMASK (MTX_RECURSED | MTX_CONTESTED | MTX_DESTROYED) /* * Prototypes @@ -99,18 +95,22 @@ int _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line); void mutex_init(void); #if LOCK_DEBUG > 0 -void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, - int opts, const char *file, int line); +void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, int opts, + const char *file, int line); void __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file, int line); #else -void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid); +void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v); void __mtx_unlock_sleep(volatile uintptr_t *c); #endif #ifdef SMP -void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, - int opts, const char *file, int line); +#if LOCK_DEBUG > 0 +void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, int opts, + const char *file, int line); +#else +void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v); +#endif #endif void __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line); @@ -127,9 +127,23 @@ void __mtx_assert(const volatile uintptr_t *c, int what, const char *file, int line); #endif void thread_lock_flags_(struct thread *, int, const char *, int); +#if LOCK_DEBUG > 0 +void _thread_lock(struct thread *td, int opts, const char *file, int line); +#else +void _thread_lock(struct thread *); +#endif +#if defined(LOCK_PROFILING) || defined(KLD_MODULE) #define thread_lock(tdp) \ thread_lock_flags_((tdp), 0, __FILE__, __LINE__) +#elif LOCK_DEBUG > 0 +#define thread_lock(tdp) \ + _thread_lock((tdp), 0, __FILE__, __LINE__) +#else +#define thread_lock(tdp) \ + _thread_lock((tdp)) +#endif + #define thread_lock_flags(tdp, opt) \ thread_lock_flags_((tdp), (opt), __FILE__, __LINE__) #define thread_unlock(tdp) \ @@ -147,19 +161,24 @@ void thread_lock_flags_(struct thread *, int, const char *, int); #define mtx_trylock_flags_(m, o, f, l) \ _mtx_trylock_flags_(&(m)->mtx_lock, o, f, l) #if LOCK_DEBUG > 0 -#define _mtx_lock_sleep(m, v, t, o, f, l) \ - __mtx_lock_sleep(&(m)->mtx_lock, v, t, o, f, l) +#define _mtx_lock_sleep(m, v, o, f, l) \ + __mtx_lock_sleep(&(m)->mtx_lock, v, o, f, l) #define _mtx_unlock_sleep(m, o, f, l) \ __mtx_unlock_sleep(&(m)->mtx_lock, o, f, l) #else -#define _mtx_lock_sleep(m, v, t, o, f, l) \ - __mtx_lock_sleep(&(m)->mtx_lock, v, t) +#define _mtx_lock_sleep(m, v, o, f, l) \ + __mtx_lock_sleep(&(m)->mtx_lock, v) #define _mtx_unlock_sleep(m, o, f, l) \ __mtx_unlock_sleep(&(m)->mtx_lock) #endif #ifdef SMP -#define _mtx_lock_spin(m, v, t, o, f, l) \ - _mtx_lock_spin_cookie(&(m)->mtx_lock, v, t, o, f, l) +#if LOCK_DEBUG > 0 +#define _mtx_lock_spin(m, v, o, f, l) \ + _mtx_lock_spin_cookie(&(m)->mtx_lock, v, o, f, l) +#else +#define _mtx_lock_spin(m, v, o, f, l) \ + _mtx_lock_spin_cookie(&(m)->mtx_lock, v) +#endif #endif #define _mtx_lock_flags(m, o, f, l) \ __mtx_lock_flags(&(m)->mtx_lock, o, f, l) @@ -208,7 +227,7 @@ void thread_lock_flags_(struct thread *, int, const char *, int); \ if (__predict_false(LOCKSTAT_PROFILE_ENABLED(adaptive__acquire) ||\ !_mtx_obtain_lock_fetch((mp), &_v, _tid))) \ - _mtx_lock_sleep((mp), _v, _tid, (opts), (file), (line));\ + _mtx_lock_sleep((mp), _v, (opts), (file), (line)); \ } while (0) /* @@ -223,11 +242,9 @@ void thread_lock_flags_(struct thread *, int, const char *, int); uintptr_t _v = MTX_UNOWNED; \ \ spinlock_enter(); \ - if (!_mtx_obtain_lock_fetch((mp), &_v, _tid)) \ - _mtx_lock_spin((mp), _v, _tid, (opts), (file), (line)); \ - else \ - LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire, \ - mp, 0, 0, file, line); \ + if (__predict_false(LOCKSTAT_PROFILE_ENABLED(spin__acquire) || \ + !_mtx_obtain_lock_fetch((mp), &_v, _tid))) \ + _mtx_lock_spin((mp), _v, (opts), (file), (line)); \ } while (0) #define __mtx_trylock_spin(mp, tid, opts, file, line) __extension__ ({ \ uintptr_t _tid = (uintptr_t)(tid); \ diff --git a/sys/sys/param.h b/sys/sys/param.h index 71ccde2936d5..e899d403b9b1 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200044 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200052 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/pmclog.h b/sys/sys/pmclog.h index 69062f7fe895..a6bbf0b98dc3 100644 --- a/sys/sys/pmclog.h +++ b/sys/sys/pmclog.h @@ -260,6 +260,8 @@ int pmclog_deconfigure_log(struct pmc_owner *_po); int pmclog_flush(struct pmc_owner *_po); int pmclog_close(struct pmc_owner *_po); void pmclog_initialize(void); +int pmclog_proc_create(struct thread *td, void **handlep); +void pmclog_proc_ignite(void *handle, struct pmc_owner *po); void pmclog_process_callchain(struct pmc *_pm, struct pmc_sample *_ps); void pmclog_process_closelog(struct pmc_owner *po); void pmclog_process_dropnotify(struct pmc_owner *po); diff --git a/sys/sys/priv.h b/sys/sys/priv.h index 86ea05e92ac3..828c19f25efb 100644 --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -266,7 +266,7 @@ #define PRIV_VFS_GETFH 327 /* Can retrieve file handles. */ #define PRIV_VFS_GETQUOTA 328 /* getquota(). */ #define PRIV_VFS_LINK 329 /* bsd.hardlink_check_uid */ -#define PRIV_VFS_MKNOD_BAD 330 /* Can mknod() to mark bad inodes. */ +#define PRIV_VFS_MKNOD_BAD 330 /* Was: mknod() can mark bad inodes. */ #define PRIV_VFS_MKNOD_DEV 331 /* Can mknod() to create dev nodes. */ #define PRIV_VFS_MKNOD_WHT 332 /* Can mknod() to create whiteout. */ #define PRIV_VFS_MOUNT 333 /* Can mount(). */ diff --git a/sys/sys/random.h b/sys/sys/random.h index 480621a1e2d3..9d4a9fb097f7 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -58,9 +58,9 @@ read_random(void *a __unused, u_int b __unused) #endif /* - * Note: if you add or remove members of random_entropy_source, remember to also update the - * KASSERT regarding what valid members are in random_harvest_internal(), and remember the - * strings in the static array random_source_descr[] in random_harvestq.c. + * Note: if you add or remove members of random_entropy_source, remember to + * also update the strings in the static array random_source_descr[] in + * random_harvestq.c. * * NOTE: complain loudly to markm@ or on the lists if this enum gets more than 32 * distinct values (0-31)! ENTROPYSOURCE may be == 32, but not > 32. @@ -81,7 +81,8 @@ enum random_entropy_source { RANDOM_UMA, /* Special!! UMA/SLAB Allocator */ RANDOM_ENVIRONMENTAL_END = RANDOM_UMA, /* Fast hardware random-number sources from here on. */ - RANDOM_PURE_OCTEON, + RANDOM_PURE_START, + RANDOM_PURE_OCTEON = RANDOM_PURE_START, RANDOM_PURE_SAFE, RANDOM_PURE_GLXSB, RANDOM_PURE_UBSEC, @@ -95,6 +96,7 @@ enum random_entropy_source { }; #define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1) +#define RANDOM_HARVEST_PURE_MASK (((1 << ENTROPYSOURCE) - 1) & (-1UL << RANDOM_PURE_START)) #define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy" #define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache" @@ -104,10 +106,14 @@ enum random_entropy_source { void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source); void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source); void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_source); +void random_harvest_register_source(enum random_entropy_source); +void random_harvest_deregister_source(enum random_entropy_source); #else #define random_harvest_queue(a, b, c, d) do {} while (0) #define random_harvest_fast(a, b, c, d) do {} while (0) #define random_harvest_direct(a, b, c, d) do {} while (0) +#define random_harvest_register_source(a) do {} while (0) +#define random_harvest_deregister_source(a) do {} while (0) #endif #if defined(RANDOM_ENABLE_UMA) diff --git a/sys/sys/reboot.h b/sys/sys/reboot.h index ec2a5705a1c7..9dbad4c2c4b0 100644 --- a/sys/sys/reboot.h +++ b/sys/sys/reboot.h @@ -60,6 +60,7 @@ #define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */ #define RB_PAUSE 0x100000 /* pause after each output line during probe */ #define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */ +#define RB_POWERCYCLE 0x400000 /* Power cycle if possible */ #define RB_MULTIPLE 0x20000000 /* use multiple consoles */ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h index c680ea85718a..6771bf9f1177 100644 --- a/sys/sys/sdt.h +++ b/sys/sys/sdt.h @@ -80,13 +80,14 @@ #include #include +extern volatile bool sdt_probes_enabled; + #ifndef KDTRACE_HOOKS #define SDT_PROVIDER_DEFINE(prov) #define SDT_PROVIDER_DECLARE(prov) #define SDT_PROBE_DEFINE(prov, mod, func, name) #define SDT_PROBE_DECLARE(prov, mod, func, name) -#define SDT_PROBE_ENABLED(prov, mod, func, name) 0 #define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) #define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype) @@ -161,14 +162,13 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype); #define SDT_PROBE_DECLARE(prov, mod, func, name) \ extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1] -#define SDT_PROBE_ENABLED(prov, mod, func, name) \ - __predict_false((sdt_##prov##_##mod##_##func##_##name->id)) - #define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \ - if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \ + if (__predict_false(sdt_probes_enabled)) { \ + if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \ (*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \ (uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \ (uintptr_t) arg3, (uintptr_t) arg4); \ + } \ } while (0) #define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype) \ diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h index a4ed33274d79..ad675b360aae 100644 --- a/sys/sys/sockbuf.h +++ b/sys/sys/sockbuf.h @@ -32,15 +32,9 @@ */ #ifndef _SYS_SOCKBUF_H_ #define _SYS_SOCKBUF_H_ -#include -#include -#include -#include - -#define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */ /* - * Constants for sb_flags field of struct sockbuf. + * Constants for sb_flags field of struct sockbuf/xsockbuf. */ #define SB_WAIT 0x04 /* someone is waiting for data/space */ #define SB_SEL 0x08 /* someone is selecting */ @@ -59,24 +53,20 @@ #define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */ #define SBS_RCVATMARK 0x0040 /* at mark on input */ +#if defined(_KERNEL) || defined(_WANT_SOCKET) +#include +#include +#include +#include + +#define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */ + struct mbuf; struct sockaddr; struct socket; struct thread; struct selinfo; -struct xsockbuf { - u_int sb_cc; - u_int sb_hiwat; - u_int sb_mbcnt; - u_int sb_mcnt; - u_int sb_ccnt; - u_int sb_mbmax; - int sb_lowat; - int sb_timeo; - short sb_flags; -}; - /* * Variables for socket buffering. * @@ -113,6 +103,7 @@ struct sockbuf { struct task sb_aiotask; /* AIO task */ }; +#endif /* defined(_KERNEL) || defined(_WANT_SOCKET) */ #ifdef _KERNEL /* @@ -174,7 +165,6 @@ struct mbuf * sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff); struct mbuf * sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff); -void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); void sbunlock(struct sockbuf *sb); diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 1780bb197fce..9c5709fb4230 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -34,6 +34,12 @@ #ifndef _SYS_SOCKETVAR_H_ #define _SYS_SOCKETVAR_H_ +/* + * Socket generation count type. Also used in xinpcb, xtcpcb, xunpcb. + */ +typedef uint64_t so_gen_t; + +#if defined(_KERNEL) || defined(_WANT_SOCKET) #include /* for TAILQ macros */ #include /* for struct selinfo */ #include @@ -41,7 +47,6 @@ #include #include #include -#include #ifdef _KERNEL #include #include @@ -55,7 +60,6 @@ struct vnet; * handle on protocol and pointer to protocol * private data and error information. */ -typedef uint64_t so_gen_t; typedef int so_upcall_t(struct socket *, void *, int); struct socket; @@ -167,6 +171,39 @@ struct socket { }; }; }; +#endif /* defined(_KERNEL) || defined(_WANT_SOCKET) */ + +/* + * Socket state bits. + * + * Historically, this bits were all kept in the so_state field. For + * locking reasons, they are now in multiple fields, as they are + * locked differently. so_state maintains basic socket state protected + * by the socket lock. so_qstate holds information about the socket + * accept queues. Each socket buffer also has a state field holding + * information relevant to that socket buffer (can't send, rcv). Many + * fields will be read without locks to improve performance and avoid + * lock order issues. However, this approach must be used with caution. + */ +#define SS_NOFDREF 0x0001 /* no file table ref any more */ +#define SS_ISCONNECTED 0x0002 /* socket connected to a peer */ +#define SS_ISCONNECTING 0x0004 /* in process of connecting to peer */ +#define SS_ISDISCONNECTING 0x0008 /* in process of disconnecting */ +#define SS_NBIO 0x0100 /* non-blocking ops */ +#define SS_ASYNC 0x0200 /* async i/o notify */ +#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */ +#define SS_ISDISCONNECTED 0x2000 /* socket disconnected from peer */ + +/* + * Protocols can mark a socket as SS_PROTOREF to indicate that, following + * pru_detach, they still want the socket to persist, and will free it + * themselves when they are done. Protocols should only ever call sofree() + * following setting this flag in pru_detach(), and never otherwise, as + * sofree() bypasses socket reference counting. + */ +#define SS_PROTOREF 0x4000 /* strong protocol reference */ + +#ifdef _KERNEL #define SOCK_MTX(so) &(so)->so_lock #define SOCK_LOCK(so) mtx_lock(&(so)->so_lock) @@ -193,32 +230,6 @@ struct socket { ("%s: %p not listening", __func__, (sol))); \ } while (0) -/* - * Externalized form of struct socket used by the sysctl(3) interface. - */ -struct xsocket { - size_t xso_len; /* length of this structure */ - struct socket *xso_so; /* makes a convenient handle sometimes */ - short so_type; - short so_options; - short so_linger; - short so_state; - caddr_t so_pcb; /* another convenient handle */ - int xso_protocol; - int xso_family; - u_int so_qlen; - u_int so_incqlen; - u_int so_qlimit; - short so_timeo; - u_short so_error; - pid_t so_pgid; - u_long so_oobmark; - struct xsockbuf so_rcv, so_snd; - uid_t so_uid; /* XXX */ -}; - -#ifdef _KERNEL - /* * Macros for sockets and socket buffering. */ @@ -422,7 +433,6 @@ int sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td); int soshutdown(struct socket *so, int how); -void sotoxsocket(struct socket *so, struct xsocket *xso); void soupcall_clear(struct socket *, int); void soupcall_set(struct socket *, int, so_upcall_t, void *); void solisten_upcall_set(struct socket *, so_upcall_t, void *); @@ -431,6 +441,14 @@ void sowakeup_aio(struct socket *so, struct sockbuf *sb); void solisten_wakeup(struct socket *); int selsocket(struct socket *so, int events, struct timeval *tv, struct thread *td); +void soisconnected(struct socket *so); +void soisconnecting(struct socket *so); +void soisdisconnected(struct socket *so); +void soisdisconnecting(struct socket *so); +void socantrcvmore(struct socket *so); +void socantrcvmore_locked(struct socket *so); +void socantsendmore(struct socket *so); +void socantsendmore_locked(struct socket *so); /* * Accept filter functions (duh). @@ -447,4 +465,58 @@ int accept_filt_generic_mod_event(module_t mod, int event, void *data); #endif /* _KERNEL */ +/* + * Structure to export socket from kernel to utilities, via sysctl(3). + */ +struct xsocket { + size_t xso_len; /* length of this structure */ + union { + void *xso_so; /* kernel address of struct socket */ + int64_t ph_so; + }; + union { + void *so_pcb; /* kernel address of struct inpcb */ + int64_t ph_pcb; + }; + uint64_t so_oobmark; + int64_t so_spare64[8]; + int32_t xso_protocol; + int32_t xso_family; + uint32_t so_qlen; + uint32_t so_incqlen; + uint32_t so_qlimit; + pid_t so_pgid; + uid_t so_uid; + int32_t so_spare32[8]; + int16_t so_type; + int16_t so_options; + int16_t so_linger; + int16_t so_state; + int16_t so_timeo; + uint16_t so_error; + struct xsockbuf { + uint32_t sb_cc; + uint32_t sb_hiwat; + uint32_t sb_mbcnt; + uint32_t sb_mcnt; + uint32_t sb_ccnt; + uint32_t sb_mbmax; + int32_t sb_lowat; + int32_t sb_timeo; + int16_t sb_flags; + } so_rcv, so_snd; +}; + +#ifdef _KERNEL +void sotoxsocket(struct socket *so, struct xsocket *xso); +void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); +#endif + +/* + * Socket buffer state bits. Exported via libprocstat(3). + */ +#define SBS_CANTSENDMORE 0x0010 /* can't send more data to peer */ +#define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */ +#define SBS_RCVATMARK 0x0040 /* at mark on input */ + #endif /* !_SYS_SOCKETVAR_H_ */ diff --git a/sys/sys/sockstate.h b/sys/sys/sockstate.h deleted file mode 100644 index 9648f5a32052..000000000000 --- a/sys/sys/sockstate.h +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)socketvar.h 8.3 (Berkeley) 2/19/95 - * - * $FreeBSD$ - */ -#ifndef _SYS_SOCKTATE_H_ -#define _SYS_SOCKTATE_H_ - -/* - * Socket state bits. - * - * Historically, this bits were all kept in the so_state field. For - * locking reasons, they are now in multiple fields, as they are - * locked differently. so_state maintains basic socket state protected - * by the socket lock. so_qstate holds information about the socket - * accept queues. Each socket buffer also has a state field holding - * information relevant to that socket buffer (can't send, rcv). Many - * fields will be read without locks to improve performance and avoid - * lock order issues. However, this approach must be used with caution. - */ -#define SS_NOFDREF 0x0001 /* no file table ref any more */ -#define SS_ISCONNECTED 0x0002 /* socket connected to a peer */ -#define SS_ISCONNECTING 0x0004 /* in process of connecting to peer */ -#define SS_ISDISCONNECTING 0x0008 /* in process of disconnecting */ -#define SS_NBIO 0x0100 /* non-blocking ops */ -#define SS_ASYNC 0x0200 /* async i/o notify */ -#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */ -#define SS_ISDISCONNECTED 0x2000 /* socket disconnected from peer */ - -/* - * Protocols can mark a socket as SS_PROTOREF to indicate that, following - * pru_detach, they still want the socket to persist, and will free it - * themselves when they are done. Protocols should only ever call sofree() - * following setting this flag in pru_detach(), and never otherwise, as - * sofree() bypasses socket reference counting. - */ -#define SS_PROTOREF 0x4000 /* strong protocol reference */ - -/* - * Socket state bits now stored in the socket buffer state field. - */ -#define SBS_CANTSENDMORE 0x0010 /* can't send more data to peer */ -#define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */ -#define SBS_RCVATMARK 0x0040 /* at mark on input */ - -struct socket; - -void soisconnected(struct socket *so); -void soisconnecting(struct socket *so); -void soisdisconnected(struct socket *so); -void soisdisconnecting(struct socket *so); -void socantrcvmore(struct socket *so); -void socantrcvmore_locked(struct socket *so); -void socantsendmore(struct socket *so); -void socantsendmore_locked(struct socket *so); -#endif /* _SYS_SOCKTATE_H_ */ diff --git a/sys/sys/stack.h b/sys/sys/stack.h index e26b535e12ab..113269b1a966 100644 --- a/sys/sys/stack.h +++ b/sys/sys/stack.h @@ -34,7 +34,7 @@ struct sbuf; /* MI Routines. */ -struct stack *stack_create(void); +struct stack *stack_create(int); void stack_destroy(struct stack *); int stack_put(struct stack *, vm_offset_t); void stack_copy(const struct stack *, struct stack *); diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index d7721618cbba..5fcdc11630c1 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -83,6 +83,7 @@ struct ctlname { #define CTLFLAG_RD 0x80000000 /* Allow reads of variable */ #define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */ #define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR) +#define CTLFLAG_DORMANT 0x20000000 /* This sysctl is not active yet */ #define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */ #define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */ #define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */ @@ -219,6 +220,8 @@ int sysctl_dpcpu_quad(SYSCTL_HANDLER_ARGS); * These functions are used to add/remove an oid from the mib. */ void sysctl_register_oid(struct sysctl_oid *oidp); +void sysctl_register_disabled_oid(struct sysctl_oid *oidp); +void sysctl_enable_oid(struct sysctl_oid *oidp); void sysctl_unregister_oid(struct sysctl_oid *oidp); /* Declare a static oid to allow child oids to be added to it. */ diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index a4049876454b..329268494219 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -129,6 +129,8 @@ struct sysentvec { void (*sv_schedtail)(struct thread *); void (*sv_thread_detach)(struct thread *); int (*sv_trap)(struct thread *); + u_long *sv_hwcap; /* Value passed in AT_HWCAP. */ + u_long *sv_hwcap2; /* Value passed in AT_HWCAP2. */ }; #define SV_ILP32 0x000100 /* 32-bit executable. */ diff --git a/sys/sys/systm.h b/sys/sys/systm.h index ddebe0a68431..4fa3e6bb3444 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -450,6 +450,7 @@ struct unrhdr; struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex); void init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex); void delete_unrhdr(struct unrhdr *uh); +void clear_unrhdr(struct unrhdr *uh); void clean_unrhdr(struct unrhdr *uh); void clean_unrhdrl(struct unrhdr *uh); int alloc_unr(struct unrhdr *uh); diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h index f18786553de4..34a4d7392488 100644 --- a/sys/sys/unpcb.h +++ b/sys/sys/unpcb.h @@ -33,6 +33,9 @@ #ifndef _SYS_UNPCB_H_ #define _SYS_UNPCB_H_ +typedef uint64_t unp_gen_t; + +#if defined(_KERNEL) || defined(_WANT_UNPCB) #include #include @@ -61,7 +64,6 @@ * so that changes in the sockbuf may be computed to modify * back pressure on the sender accordingly. */ -typedef u_quad_t unp_gen_t; LIST_HEAD(unp_head, unpcb); struct unpcb { @@ -74,8 +76,6 @@ struct unpcb { struct unp_head unp_refs; /* referencing socket linked list */ LIST_ENTRY(unpcb) unp_reflink; /* link in unp_refs list */ struct sockaddr_un *unp_addr; /* bound address of socket */ - int reserved1; - int reserved2; unp_gen_t unp_gencnt; /* generation count of this instance */ short unp_flags; /* flags */ short unp_gcflag; /* Garbage collector flags. */ @@ -116,32 +116,50 @@ struct unpcb { #define sotounpcb(so) ((struct unpcb *)((so)->so_pcb)) -/* Hack alert -- this structure depends on . */ +#endif /* _KERNEL || _WANT_UNPCB */ + +/* + * UNPCB structure exported to user-land via sysctl(3). + * + * Fields prefixed with "xu_" are unique to the export structure, and fields + * with "unp_" or other prefixes match corresponding fields of 'struct unpcb'. + * + * Legend: + * (s) - used by userland utilities in src + * (p) - used by utilities in ports + * (3) - is known to be used by third party software not in ports + * (n) - no known usage + * + * Evil hack: declare only if sys/socketvar.h have been included. + */ #ifdef _SYS_SOCKETVAR_H_ struct xunpcb { - size_t xu_len; /* length of this structure */ - struct unpcb *xu_unpp; /* to help netstat, fstat */ - struct unpcb xu_unp; /* our information */ + size_t xu_len; /* length of this structure */ + void *xu_unpp; /* to help netstat, fstat */ + void *unp_vnode; /* (s) */ + void *unp_conn; /* (s) */ + void *xu_firstref; /* (s) */ + void *xu_nextref; /* (s) */ + unp_gen_t unp_gencnt; /* (s) */ + int64_t xu_spare64[8]; + int32_t xu_spare32[8]; union { - struct sockaddr_un xuu_addr; /* our bound address */ + struct sockaddr_un xu_addr; /* our bound address */ char xu_dummy1[256]; - } xu_au; -#define xu_addr xu_au.xuu_addr + }; union { - struct sockaddr_un xuu_caddr; /* their bound address */ + struct sockaddr_un xu_caddr; /* their bound address */ char xu_dummy2[256]; - } xu_cau; -#define xu_caddr xu_cau.xuu_caddr - struct xsocket xu_socket; - u_quad_t xu_alignment_hack; -}; + }; + struct xsocket xu_socket; +} __aligned(8); struct xunpgen { size_t xug_len; u_int xug_count; unp_gen_t xug_gen; so_gen_t xug_sogen; -}; +} __aligned(8);; #endif /* _SYS_SOCKETVAR_H_ */ #endif /* _SYS_UNPCB_H_ */ diff --git a/sys/sys/vmmeter.h b/sys/sys/vmmeter.h index bc536f71e7b5..62106ee7e989 100644 --- a/sys/sys/vmmeter.h +++ b/sys/sys/vmmeter.h @@ -131,7 +131,6 @@ struct vmmeter { u_int v_free_reserved; /* (c) pages reserved for deadlock */ u_int v_free_target; /* (c) pages desired free */ u_int v_free_min; /* (c) pages desired free */ - u_int v_free_count; /* (f) pages free */ u_int v_inactive_target; /* (c) pages desired inactive */ u_int v_pageout_free_min; /* (c) min pages reserved for kernel */ u_int v_interrupt_free_min; /* (c) reserved pages for int code */ @@ -141,6 +140,7 @@ struct vmmeter { u_int v_inactive_count VMMETER_ALIGNED; /* (a) pages inactive */ u_int v_laundry_count VMMETER_ALIGNED; /* (a) pages eligible for laundering */ + u_int v_free_count VMMETER_ALIGNED; /* (f) pages free */ }; #endif /* _KERNEL || _WANT_VMMETER */ @@ -208,10 +208,10 @@ vm_paging_target(void) * Returns TRUE if the pagedaemon needs to be woken up. */ static inline int -vm_paging_needed(void) +vm_paging_needed(u_int free_count) { - return (vm_cnt.v_free_count < vm_pageout_wakeup_thresh); + return (free_count < vm_pageout_wakeup_thresh); } /* diff --git a/sys/tools/embed_mfs.sh b/sys/tools/embed_mfs.sh index a7ac80c8f8d3..780ad891ae06 100644 --- a/sys/tools/embed_mfs.sh +++ b/sys/tools/embed_mfs.sh @@ -32,13 +32,22 @@ # $2: MFS image filename # +if [ $# -ne 2 ]; then + echo "usage: $(basename $0) target mfs_image" + exit 0 +fi +if [ ! -w "$1" ]; then + echo $1 not writable + exit 1 +fi + mfs_size=`stat -f '%z' $2 2> /dev/null` # If we can't determine MFS image size - bail. [ -z ${mfs_size} ] && echo "Can't determine MFS image size" && exit 1 sec_info=`elfdump -c $1 2> /dev/null | grep -A 5 -E "sh_name: oldmfs$"` # If we can't find the mfs section within the given kernel - bail. -[ -z "${sec_info}" ] && echo "Can't locate mfs section within kernel" && exit 1 +[ -z "${sec_info}" ] && echo "Can't locate mfs section within $1" && exit 1 sec_size=`echo "${sec_info}" | awk '/sh_size/ {print $2}' 2> /dev/null` sec_start=`echo "${sec_info}" | awk '/sh_offset/ {print $2}' 2> /dev/null` diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index f1dbfab28fd0..bd78b760442f 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -123,6 +123,7 @@ static ufs2_daddr_t ffs_nodealloccg(struct inode *, u_int, ufs2_daddr_t, int, static ufs1_daddr_t ffs_mapsearch(struct fs *, struct cg *, ufs2_daddr_t, int); static int ffs_reallocblks_ufs1(struct vop_reallocblks_args *); static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *); +static void ffs_ckhash_cg(struct buf *); /* * Allocate a block in the filesystem. @@ -2583,6 +2584,15 @@ ffs_mapsearch(fs, cgp, bpref, allocsiz) return (-1); } +static const struct statfs * +ffs_getmntstat(struct vnode *devvp) +{ + + if (devvp->v_type == VCHR) + return (&devvp->v_rdev->si_mountpt->mnt_stat); + return (ffs_getmntstat(VFSTOUFS(devvp->v_mount)->um_devvp)); +} + /* * Fetch and verify a cylinder group. */ @@ -2596,27 +2606,60 @@ ffs_getcg(fs, devvp, cg, bpp, cgpp) { struct buf *bp; struct cg *cgp; - int error; + const struct statfs *sfs; + int flags, error; *bpp = NULL; *cgpp = NULL; - error = bread(devvp, devvp->v_type == VREG ? + flags = 0; + if ((fs->fs_metackhash & CK_CYLGRP) != 0) + flags |= GB_CKHASH; + error = breadn_flags(devvp, devvp->v_type == VREG ? fragstoblks(fs, cgtod(fs, cg)) : fsbtodb(fs, cgtod(fs, cg)), - (int)fs->fs_cgsize, NOCRED, &bp); + (int)fs->fs_cgsize, NULL, NULL, 0, NOCRED, flags, + ffs_ckhash_cg, &bp); if (error != 0) return (error); cgp = (struct cg *)bp->b_data; - if (!cg_chkmagic(cgp) || cgp->cg_cgx != cg) { + if (((fs->fs_metackhash & CK_CYLGRP) != 0 && + (bp->b_flags & B_CKHASH) != 0 && + cgp->cg_ckhash != bp->b_ckhash) || + !cg_chkmagic(cgp) || cgp->cg_cgx != cg) { + sfs = ffs_getmntstat(devvp); + printf("UFS %s%s (%s) cylinder checksum failed: cg %u, cgp: " + "0x%x != bp: 0x%jx\n", + devvp->v_type == VCHR ? "" : "snapshot of ", + sfs->f_mntfromname, sfs->f_mntonname, + cg, cgp->cg_ckhash, (uintmax_t)bp->b_ckhash); + bp->b_flags &= ~B_CKHASH; + bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); return (EIO); } + bp->b_flags &= ~B_CKHASH; bp->b_xflags |= BX_BKGRDWRITE; + if ((fs->fs_metackhash & CK_CYLGRP) != 0) + bp->b_xflags |= BX_CYLGRP; cgp->cg_old_time = cgp->cg_time = time_second; *bpp = bp; *cgpp = cgp; return (0); } +static void +ffs_ckhash_cg(bp) + struct buf *bp; +{ + uint32_t ckhash; + struct cg *cgp; + + cgp = (struct cg *)bp->b_data; + ckhash = cgp->cg_ckhash; + cgp->cg_ckhash = 0; + bp->b_ckhash = calculate_crc32c(~0L, bp->b_data, bp->b_bcount); + cgp->cg_ckhash = ckhash; +} + /* * Fserr prints the name of a filesystem with an error diagnostic. * diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 5a2099d4bf28..8d74b4e3ac3d 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -110,9 +110,9 @@ ffs_update(vp, waitfor) if (IS_SNAPSHOT(ip)) flags = GB_LOCK_NOWAIT; loop: - error = breadn_flags(ITODEVVP(ip), + error = bread_gb(ITODEVVP(ip), fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), - (int) fs->fs_bsize, 0, 0, 0, NOCRED, flags, &bp); + (int) fs->fs_bsize, NOCRED, flags, &bp); if (error != 0) { if (error != EBUSY) return (error); diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index abfe29ba9b99..8ddcb9cbd232 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -927,7 +927,7 @@ cgaccount(cg, vp, nbp, passno) error = UFS_BALLOC(vp, lblktosize(fs, (off_t)(base + loc)), fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp); if (error) { - return (error); + goto out; } indiroff = (base + loc - UFS_NDADDR) % NINDIR(fs); for ( ; loc < len; loc++, indiroff++) { @@ -939,7 +939,7 @@ cgaccount(cg, vp, nbp, passno) lblktosize(fs, (off_t)(base + loc)), fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp); if (error) { - return (error); + goto out; } indiroff = 0; } @@ -967,7 +967,21 @@ cgaccount(cg, vp, nbp, passno) if (passno == 2) ibp->b_flags |= B_VALIDSUSPWRT; bdwrite(ibp); - return (0); +out: + /* + * We have to calculate the crc32c here rather than just setting the + * BX_CYLGRP b_xflags because the allocation of the block for the + * the cylinder group map will always be a full size block (fs_bsize) + * even though the cylinder group may be smaller (fs_cgsize). The + * crc32c must be computed only over fs_cgsize whereas the BX_CYLGRP + * flag causes it to be computed over the size of the buffer. + */ + if ((fs->fs_metackhash & CK_CYLGRP) != 0) { + ((struct cg *)nbp->b_data)->cg_ckhash = 0; + ((struct cg *)nbp->b_data)->cg_ckhash = + calculate_crc32c(~0L, nbp->b_data, fs->fs_cgsize); + } + return (error); } /* diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 3cf915df8d85..8f2b00900010 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -1535,10 +1535,10 @@ remove_from_worklist(wk) struct ufsmount *ump; ump = VFSTOUFS(wk->wk_mp); - WORKLIST_REMOVE(wk); if (ump->softdep_worklist_tail == wk) ump->softdep_worklist_tail = (struct worklist *)wk->wk_list.le_prev; + WORKLIST_REMOVE(wk); ump->softdep_on_worklist -= 1; } @@ -1836,11 +1836,11 @@ process_worklist_item(mp, target, flags) wake_worklist(wk); add_to_worklist(wk, WK_HEAD); } - LIST_REMOVE(&sentinel, wk_list); /* Sentinal could've become the tail from remove_from_worklist. */ if (ump->softdep_worklist_tail == &sentinel) ump->softdep_worklist_tail = (struct worklist *)sentinel.wk_list.le_prev; + LIST_REMOVE(&sentinel, wk_list); PRELE(curproc); return (matchcnt); } @@ -2894,7 +2894,6 @@ remove_from_journal(wk) if (ump->softdep_journal_tail == wk) ump->softdep_journal_tail = (struct worklist *)wk->wk_list.le_prev; - WORKLIST_REMOVE(wk); ump->softdep_on_journal -= 1; } @@ -3596,15 +3595,13 @@ complete_jseg(jseg) { struct worklist *wk; struct jmvref *jmvref; - int waiting; #ifdef INVARIANTS int i = 0; #endif while ((wk = LIST_FIRST(&jseg->js_entries)) != NULL) { WORKLIST_REMOVE(wk); - waiting = wk->wk_state & IOWAITING; - wk->wk_state &= ~(INPROGRESS | IOWAITING); + wk->wk_state &= ~INPROGRESS; wk->wk_state |= COMPLETE; KASSERT(i++ < jseg->js_cnt, ("handle_written_jseg: overflow %d >= %d", @@ -3645,8 +3642,6 @@ complete_jseg(jseg) TYPENAME(wk->wk_type)); /* NOTREACHED */ } - if (waiting) - wakeup(wk); } /* Release the self reference so the structure may be freed. */ rele_jseg(jseg); @@ -11532,7 +11527,7 @@ handle_written_inodeblock(inodedep, bp, flags) */ if (inodedep->id_savedsize == -1 || inodedep->id_savedextsize == -1) panic("handle_written_inodeblock: bad size"); - if (inodedep->id_savednlink > LINK_MAX) + if (inodedep->id_savednlink > UFS_LINK_MAX) panic("handle_written_inodeblock: Invalid link count " "%jd for inodedep %p", (uintmax_t)inodedep->id_savednlink, inodedep); @@ -14132,11 +14127,7 @@ getdirtybuf(bp, lock, waitfor) BUF_UNLOCK(bp); if (waitfor != MNT_WAIT) return (NULL); - /* - * The lock argument must be bp->b_vp's mutex in - * this case. - */ -#ifdef DEBUG_VFS_LOCKS +#ifdef DEBUG_VFS_LOCKS if (bp->b_vp->v_type != VCHR) ASSERT_BO_WLOCKED(bp->b_bufobj); #endif @@ -14293,25 +14284,14 @@ softdep_get_depcounts(struct mount *mp, /* * Wait for pending output on a vnode to complete. - * Must be called with vnode lock and interlock locked. - * - * XXX: Should just be a call to bufobj_wwait(). */ static void drain_output(vp) struct vnode *vp; { - struct bufobj *bo; - bo = &vp->v_bufobj; ASSERT_VOP_LOCKED(vp, "drain_output"); - ASSERT_BO_WLOCKED(bo); - - while (bo->bo_numoutput) { - bo->bo_flag |= BO_WWAIT; - msleep((caddr_t)&bo->bo_numoutput, - BO_LOCKPTR(bo), PRIBIO + 1, "drainvp", 0); - } + (void)bufobj_wwait(&vp->v_bufobj, 0, 0); } /* diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index d73d0ca0c466..b9a1ec412448 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -838,7 +838,11 @@ ffs_mountfs(devvp, mp, td) goto out; } fs->fs_fmod = 0; - fs->fs_flags &= ~FS_INDEXDIRS; /* no support for directory indices */ + /* none of these types of check-hashes are maintained */ + fs->fs_metackhash &= ~(CK_SUPERBLOCK | CK_INODE | CK_INDIR | CK_DIR); + /* no support for directory indices or any other undefined flags */ + fs->fs_flags &= ~FS_INDEXDIRS; + fs->fs_flags &= FS_SUPPORTED; fs->fs_flags &= ~FS_UNCLEAN; if (fs->fs_clean == 0) { fs->fs_flags |= FS_UNCLEAN; @@ -2150,7 +2154,8 @@ ffs_bufwrite(struct buf *bp) BO_LOCK(bp->b_bufobj); bp->b_vflags |= BV_BKGRDINPROG; BO_UNLOCK(bp->b_bufobj); - newbp->b_xflags |= BX_BKGRDMARKER; + newbp->b_xflags |= + (bp->b_xflags & BX_FSPRIV) | BX_BKGRDMARKER; newbp->b_lblkno = bp->b_lblkno; newbp->b_blkno = bp->b_blkno; newbp->b_offset = bp->b_offset; @@ -2194,9 +2199,8 @@ static void ffs_geom_strategy(struct bufobj *bo, struct buf *bp) { struct vnode *vp; - int error; struct buf *tbp; - int nocopy; + int error, nocopy; vp = bo2vnode(bo); if (bp->b_iocmd == BIO_WRITE) { @@ -2247,6 +2251,32 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp) } #endif + /* + * Check for metadata that needs check-hashes and update them. + */ + switch (bp->b_xflags & BX_FSPRIV) { + case BX_CYLGRP: + ((struct cg *)bp->b_data)->cg_ckhash = 0; + ((struct cg *)bp->b_data)->cg_ckhash = + calculate_crc32c(~0L, bp->b_data, bp->b_bcount); + break; + + case BX_SUPERBLOCK: + case BX_INODE: + case BX_INDIR: + case BX_DIR: + printf("Check-hash write is unimplemented!!!\n"); + break; + + case 0: + break; + + default: + printf("multiple buffer types 0x%b\n", + (u_int)(bp->b_xflags & BX_FSPRIV), + PRINT_UFS_BUF_XFLAGS); + break; + } } g_vfs_strategy(bo, bp); } diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index f8a186d7eed4..5ee9ff5fc38d 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -587,7 +587,7 @@ ffs_read(ap) */ u_int nextsize = blksize(fs, ip, nextlbn); error = breadn_flags(vp, lbn, size, &nextlbn, - &nextsize, 1, NOCRED, GB_UNMAPPED, &bp); + &nextsize, 1, NOCRED, GB_UNMAPPED, NULL, &bp); } else { /* * Failing all of the above, just read what the diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index 81fbeda84c1e..8315b3f359f3 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -361,7 +361,8 @@ struct fs { int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */ ufs_time_t fs_mtime; /* Last mount or fsck time. */ int32_t fs_sujfree; /* SUJ free list */ - int32_t fs_sparecon32[23]; /* reserved for future constants */ + int32_t fs_sparecon32[22]; /* reserved for future constants */ + u_int32_t fs_metackhash; /* metadata check-hash, see CK_ below */ int32_t fs_flags; /* see FS_ flags below */ int32_t fs_contigsumsize; /* size of cluster summary array */ int32_t fs_maxsymlinklen; /* max length of an internal symlink */ @@ -388,7 +389,6 @@ CTASSERT(sizeof(struct fs) == 1376); #define FS_UFS1_MAGIC 0x011954 /* UFS1 fast filesystem magic number */ #define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast filesystem magic number */ #define FS_BAD_MAGIC 0x19960408 /* UFS incomplete newfs magic number */ -#define FS_OKAY 0x7c269d38 /* superblock checksum */ #define FS_42INODEFMT -1 /* 4.2BSD inode format */ #define FS_44INODEFMT 2 /* 4.4BSD inode format */ @@ -415,7 +415,11 @@ CTASSERT(sizeof(struct fs) == 1376); * on-disk auxiliary indexes (such as B-trees) for speeding directory * accesses. Kernels that do not support auxiliary indices clear the * flag to indicate that the indices need to be rebuilt (by fsck) before - * they can be used. + * they can be used. When a filesystem is mounted, any flags not + * included in FS_SUPPORTED are cleared. This lets newer features + * know that the filesystem has been run on an older version of the + * filesystem and thus that data structures associated with those + * features are out-of-date and need to be rebuilt. * * FS_ACLS indicates that POSIX.1e ACLs are administratively enabled * for the file system, so they should be loaded from extended attributes, @@ -437,6 +441,28 @@ CTASSERT(sizeof(struct fs) == 1376); #define FS_NFS4ACLS 0x0100 /* file system has NFSv4 ACLs enabled */ #define FS_INDEXDIRS 0x0200 /* kernel supports indexed directories */ #define FS_TRIM 0x0400 /* issue BIO_DELETE for deleted blocks */ +#define FS_SUPPORTED 0xFFFF /* supported flags, others cleared at mount */ + +/* + * The fs_metackhash field indicates the types of metadata check-hash + * that are maintained for a filesystem. Not all filesystems check-hash + * all metadata. + */ +#define CK_SUPERBLOCK 0x0001 /* the superblock */ +#define CK_CYLGRP 0x0002 /* the cylinder groups */ +#define CK_INODE 0x0004 /* inodes */ +#define CK_INDIR 0x0008 /* indirect blocks */ +#define CK_DIR 0x0010 /* directory contents */ +/* + * The BX_FSPRIV buffer b_xflags are used to track types of data in buffers. + */ +#define BX_SUPERBLOCK 0x00010000 /* superblock */ +#define BX_CYLGRP 0x00020000 /* cylinder groups */ +#define BX_INODE 0x00040000 /* inodes */ +#define BX_INDIR 0x00080000 /* indirect blocks */ +#define BX_DIR 0x00100000 /* directory contents */ + +#define PRINT_UFS_BUF_XFLAGS "\20\25dir\24indir\23inode\22cylgrp\21superblock" /* * Macros to access bits in the fs_active array. @@ -506,7 +532,8 @@ struct cg { u_int32_t cg_niblk; /* number of inode blocks this cg */ u_int32_t cg_initediblk; /* last initialized inode */ u_int32_t cg_unrefs; /* number of unreferenced inodes */ - int32_t cg_sparecon32[2]; /* reserved for future use */ + int32_t cg_sparecon32[1]; /* reserved for future use */ + u_int32_t cg_ckhash; /* check-hash of this cg */ ufs_time_t cg_time; /* time last written */ int64_t cg_sparecon64[3]; /* reserved for future use */ u_int8_t cg_space[1]; /* space for cylinder group maps */ diff --git a/sys/ufs/ufs/dinode.h b/sys/ufs/ufs/dinode.h index 0e90ac24ab0a..73c6acbe270b 100644 --- a/sys/ufs/ufs/dinode.h +++ b/sys/ufs/ufs/dinode.h @@ -186,4 +186,6 @@ struct ufs1_dinode { u_int64_t di_modrev; /* 120: i_modrev for NFSv4 */ }; +#define UFS_LINK_MAX 32767 + #endif /* _UFS_UFS_DINODE_H_ */ diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index d42b36a5a446..c9cc6475316a 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -981,7 +981,7 @@ ufs_link(ap) goto out; } ip = VTOI(vp); - if ((nlink_t)ip->i_nlink >= LINK_MAX) { + if (ip->i_nlink >= UFS_LINK_MAX) { error = EMLINK; goto out; } @@ -1266,7 +1266,7 @@ ufs_rename(ap) doingdirectory = 0; newparent = 0; ino = fip->i_number; - if (fip->i_nlink >= LINK_MAX) { + if (fip->i_nlink >= UFS_LINK_MAX) { error = EMLINK; goto unlockout; } @@ -1369,7 +1369,7 @@ ufs_rename(ap) * actual link modification is completed when * .. is rewritten below. */ - if ((nlink_t)tdp->i_nlink >= LINK_MAX) { + if (tdp->i_nlink >= UFS_LINK_MAX) { error = EMLINK; goto bad; } @@ -1793,7 +1793,7 @@ ufs_mkdir(ap) panic("ufs_mkdir: no name"); #endif dp = VTOI(dvp); - if ((nlink_t)dp->i_nlink >= LINK_MAX) { + if (dp->i_nlink >= UFS_LINK_MAX) { error = EMLINK; goto out; } @@ -2442,6 +2442,9 @@ ufs_pathconf(ap) error = 0; switch (ap->a_name) { + case _PC_LINK_MAX: + *ap->a_retval = UFS_LINK_MAX; + break; case _PC_NAME_MAX: *ap->a_retval = UFS_MAXNAMLEN; break; diff --git a/sys/vm/memguard.c b/sys/vm/memguard.c index e22a313dfb03..5d59f7d1a6d0 100644 --- a/sys/vm/memguard.c +++ b/sys/vm/memguard.c @@ -284,7 +284,7 @@ v2sizev(vm_offset_t va) void * memguard_alloc(unsigned long req_size, int flags) { - vm_offset_t addr; + vm_offset_t addr, origaddr; u_long size_p, size_v; int do_guard, rv; @@ -328,7 +328,7 @@ memguard_alloc(unsigned long req_size, int flags) for (;;) { if (vmem_xalloc(memguard_arena, size_v, 0, 0, 0, memguard_cursor, VMEM_ADDR_MAX, - M_BESTFIT | M_NOWAIT, &addr) == 0) + M_BESTFIT | M_NOWAIT, &origaddr) == 0) break; /* * The map has no space. This may be due to @@ -343,11 +343,12 @@ memguard_alloc(unsigned long req_size, int flags) memguard_wrap++; memguard_cursor = memguard_base; } + addr = origaddr; if (do_guard) addr += PAGE_SIZE; rv = kmem_back(kmem_object, addr, size_p, flags); if (rv != KERN_SUCCESS) { - vmem_xfree(memguard_arena, addr, size_v); + vmem_xfree(memguard_arena, origaddr, size_v); memguard_fail_pgs++; addr = (vm_offset_t)NULL; goto out; diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 946f92b55e78..02891e90880f 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -157,7 +157,7 @@ static vm_ooffset_t swap_reserved; SYSCTL_QUAD(_vm, OID_AUTO, swap_reserved, CTLFLAG_RD, &swap_reserved, 0, "Amount of swap storage needed to back all allocated anonymous memory."); static int overcommit = 0; -SYSCTL_INT(_vm, OID_AUTO, overcommit, CTLFLAG_RW, &overcommit, 0, +SYSCTL_INT(_vm, VM_OVERCOMMIT, overcommit, CTLFLAG_RW, &overcommit, 0, "Configure virtual memory overcommit behavior. See tuning(7) " "for details."); static unsigned long swzone; @@ -541,7 +541,15 @@ swap_pager_swap_init(void) */ n -= ((n + 2) / 3); } while (n > 0); - if (n2 != n) + + /* + * Often uma_zone_reserve_kva() cannot reserve exactly the + * requested size. Account for the difference when + * calculating swap_maxpages. + */ + n = uma_zone_get_max(swblk_zone); + + if (n < n2) printf("Swap blk zone entries reduced from %lu to %lu.\n", n2, n); swap_maxpages = n * SWAP_META_PAGES; @@ -1524,7 +1532,7 @@ swp_pager_async_iodone(struct buf *bp) * so it doesn't clog the inactive list, * then finish the I/O. */ - vm_page_dirty(m); + MPASS(m->dirty == VM_PAGE_BITS_ALL); vm_page_lock(m); vm_page_activate(m); vm_page_unlock(m); @@ -1635,9 +1643,12 @@ swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex) if (m->valid == VM_PAGE_BITS_ALL) { vm_object_pip_wakeup(object); vm_page_dirty(m); +#ifdef INVARIANTS vm_page_lock(m); - vm_page_activate(m); + if (m->wire_count == 0 && m->queue == PQ_NONE) + panic("page %p is neither wired nor queued", m); vm_page_unlock(m); +#endif vm_page_xunbusy(m); vm_pager_page_unswapped(m); return; diff --git a/sys/vm/uma.h b/sys/vm/uma.h index 395415da21db..71027b898cff 100644 --- a/sys/vm/uma.h +++ b/sys/vm/uma.h @@ -296,6 +296,7 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, #define UMA_ALIGN_SHORT (sizeof(short) - 1) /* "" short */ #define UMA_ALIGN_CHAR (sizeof(char) - 1) /* "" char */ #define UMA_ALIGN_CACHE (0 - 1) /* Cache line size align */ +#define UMA_ALIGNOF(type) (_Alignof(type) - 1) /* Alignment fit for 'type' */ /* * Destroys an empty uma zone. If the zone is not empty uma complains loudly. diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h index 8423d1cb0afc..ee315abf2dbb 100644 --- a/sys/vm/uma_int.h +++ b/sys/vm/uma_int.h @@ -28,6 +28,7 @@ * */ +#include #include /* @@ -210,7 +211,7 @@ struct uma_keg { vm_offset_t uk_kva; /* Zone base KVA */ uma_zone_t uk_slabzone; /* Slab zone backing us, if OFFPAGE */ - uint16_t uk_pgoff; /* Offset to uma_slab struct */ + uint32_t uk_pgoff; /* Offset to uma_slab struct */ uint16_t uk_ppera; /* pages per allocation from backend */ uint16_t uk_ipers; /* Items per slab */ uint32_t uk_flags; /* Internal flags */ diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index a95a1bf395d5..d67ba18c94a5 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -71,7 +71,6 @@ void kmem_init(vm_offset_t, vm_offset_t); void kmem_init_zero_region(void); void kmeminit(void); -void swapout_procs(int); int kernacc(void *, int, int); int useracc(void *, int, int); int vm_fault(vm_map_t, vm_offset_t, vm_prot_t, int); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 3da7263f04a6..da4200f1caa8 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -101,13 +101,6 @@ __FBSDID("$FreeBSD$"); #include -#ifndef NO_SWAPPING -static int swapout(struct proc *); -static void swapclear(struct proc *); -static void vm_thread_swapin(struct thread *td); -static void vm_thread_swapout(struct thread *td); -#endif - /* * MPSAFE * @@ -308,10 +301,6 @@ SYSCTL_INT(_vm, OID_AUTO, kstack_cache_size, CTLFLAG_RW, &kstack_cache_size, 0, SYSCTL_INT(_vm, OID_AUTO, kstacks, CTLFLAG_RD, &kstacks, 0, ""); -#ifndef KSTACK_MAX_PAGES -#define KSTACK_MAX_PAGES 32 -#endif - /* * Create the kernel stack (including pcb for i386) for a new thread. * This routine directly affects the fork perf for a process and @@ -527,79 +516,6 @@ intr_prof_stack_use(struct thread *td, struct trapframe *frame) } #endif /* KSTACK_USAGE_PROF */ -#ifndef NO_SWAPPING -/* - * Allow a thread's kernel stack to be paged out. - */ -static void -vm_thread_swapout(struct thread *td) -{ - vm_object_t ksobj; - vm_page_t m; - int i, pages; - - cpu_thread_swapout(td); - pages = td->td_kstack_pages; - ksobj = td->td_kstack_obj; - pmap_qremove(td->td_kstack, pages); - VM_OBJECT_WLOCK(ksobj); - for (i = 0; i < pages; i++) { - m = vm_page_lookup(ksobj, i); - if (m == NULL) - panic("vm_thread_swapout: kstack already missing?"); - vm_page_dirty(m); - vm_page_lock(m); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_unlock(m); - } - VM_OBJECT_WUNLOCK(ksobj); -} - -/* - * Bring the kernel stack for a specified thread back in. - */ -static void -vm_thread_swapin(struct thread *td) -{ - vm_object_t ksobj; - vm_page_t ma[KSTACK_MAX_PAGES]; - int pages; - - pages = td->td_kstack_pages; - ksobj = td->td_kstack_obj; - VM_OBJECT_WLOCK(ksobj); - (void)vm_page_grab_pages(ksobj, 0, VM_ALLOC_NORMAL | VM_ALLOC_WIRED, ma, - pages); - for (int i = 0; i < pages;) { - int j, a, count, rv; - - vm_page_assert_xbusied(ma[i]); - if (ma[i]->valid == VM_PAGE_BITS_ALL) { - vm_page_xunbusy(ma[i]); - i++; - continue; - } - vm_object_pip_add(ksobj, 1); - for (j = i + 1; j < pages; j++) - if (ma[j]->valid == VM_PAGE_BITS_ALL) - break; - rv = vm_pager_has_page(ksobj, ma[i]->pindex, NULL, &a); - KASSERT(rv == 1, ("%s: missing page %p", __func__, ma[i])); - count = min(a + 1, j - i); - rv = vm_pager_get_pages(ksobj, ma + i, count, NULL, NULL); - KASSERT(rv == VM_PAGER_OK, ("%s: cannot get kstack for proc %d", - __func__, td->td_proc->p_pid)); - vm_object_pip_wakeup(ksobj); - for (j = i; j < i + count; j++) - vm_page_xunbusy(ma[j]); - i += count; - } - VM_OBJECT_WUNLOCK(ksobj); - pmap_qenter(td->td_kstack, ma, pages); - cpu_thread_swapin(td); -} -#endif /* !NO_SWAPPING */ - /* * Implement fork's actions on an address space. * Here we arrange for the address space to be copied or referenced, @@ -672,426 +588,9 @@ vm_waitproc(p) vmspace_exitfree(p); /* and clean-out the vmspace */ } -void -faultin(p) - struct proc *p; -{ -#ifdef NO_SWAPPING - - PROC_LOCK_ASSERT(p, MA_OWNED); - if ((p->p_flag & P_INMEM) == 0) - panic("faultin: proc swapped out with NO_SWAPPING!"); -#else /* !NO_SWAPPING */ - struct thread *td; - - PROC_LOCK_ASSERT(p, MA_OWNED); - /* - * If another process is swapping in this process, - * just wait until it finishes. - */ - if (p->p_flag & P_SWAPPINGIN) { - while (p->p_flag & P_SWAPPINGIN) - msleep(&p->p_flag, &p->p_mtx, PVM, "faultin", 0); - return; - } - if ((p->p_flag & P_INMEM) == 0) { - /* - * Don't let another thread swap process p out while we are - * busy swapping it in. - */ - ++p->p_lock; - p->p_flag |= P_SWAPPINGIN; - PROC_UNLOCK(p); - - /* - * We hold no lock here because the list of threads - * can not change while all threads in the process are - * swapped out. - */ - FOREACH_THREAD_IN_PROC(p, td) - vm_thread_swapin(td); - PROC_LOCK(p); - swapclear(p); - p->p_swtick = ticks; - - wakeup(&p->p_flag); - - /* Allow other threads to swap p out now. */ - --p->p_lock; - } -#endif /* NO_SWAPPING */ -} - -/* - * This swapin algorithm attempts to swap-in processes only if there - * is enough space for them. Of course, if a process waits for a long - * time, it will be swapped in anyway. - */ -void -swapper(void) -{ - struct proc *p; - struct thread *td; - struct proc *pp; - int slptime; - int swtime; - int ppri; - int pri; - -loop: - if (vm_page_count_min()) { - VM_WAIT; - goto loop; - } - - pp = NULL; - ppri = INT_MIN; - sx_slock(&allproc_lock); - FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); - if (p->p_state == PRS_NEW || - p->p_flag & (P_SWAPPINGOUT | P_SWAPPINGIN | P_INMEM)) { - PROC_UNLOCK(p); - continue; - } - swtime = (ticks - p->p_swtick) / hz; - FOREACH_THREAD_IN_PROC(p, td) { - /* - * An otherwise runnable thread of a process - * swapped out has only the TDI_SWAPPED bit set. - * - */ - thread_lock(td); - if (td->td_inhibitors == TDI_SWAPPED) { - slptime = (ticks - td->td_slptick) / hz; - pri = swtime + slptime; - if ((td->td_flags & TDF_SWAPINREQ) == 0) - pri -= p->p_nice * 8; - /* - * if this thread is higher priority - * and there is enough space, then select - * this process instead of the previous - * selection. - */ - if (pri > ppri) { - pp = p; - ppri = pri; - } - } - thread_unlock(td); - } - PROC_UNLOCK(p); - } - sx_sunlock(&allproc_lock); - - /* - * Nothing to do, back to sleep. - */ - if ((p = pp) == NULL) { - tsleep(&proc0, PVM, "swapin", MAXSLP * hz / 2); - goto loop; - } - PROC_LOCK(p); - - /* - * Another process may be bringing or may have already - * brought this process in while we traverse all threads. - * Or, this process may even be being swapped out again. - */ - if (p->p_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) { - PROC_UNLOCK(p); - goto loop; - } - - /* - * We would like to bring someone in. (only if there is space). - * [What checks the space? ] - */ - faultin(p); - PROC_UNLOCK(p); - goto loop; -} - void kick_proc0(void) { wakeup(&proc0); } - -#ifndef NO_SWAPPING - -/* - * Swap_idle_threshold1 is the guaranteed swapped in time for a process - */ -static int swap_idle_threshold1 = 2; -SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold1, CTLFLAG_RW, - &swap_idle_threshold1, 0, "Guaranteed swapped in time for a process"); - -/* - * Swap_idle_threshold2 is the time that a process can be idle before - * it will be swapped out, if idle swapping is enabled. - */ -static int swap_idle_threshold2 = 10; -SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold2, CTLFLAG_RW, - &swap_idle_threshold2, 0, "Time before a process will be swapped out"); - -/* - * First, if any processes have been sleeping or stopped for at least - * "swap_idle_threshold1" seconds, they are swapped out. If, however, - * no such processes exist, then the longest-sleeping or stopped - * process is swapped out. Finally, and only as a last resort, if - * there are no sleeping or stopped processes, the longest-resident - * process is swapped out. - */ -void -swapout_procs(action) -int action; -{ - struct proc *p; - struct thread *td; - int didswap = 0; - -retry: - sx_slock(&allproc_lock); - FOREACH_PROC_IN_SYSTEM(p) { - struct vmspace *vm; - int minslptime = 100000; - int slptime; - - PROC_LOCK(p); - /* - * Watch out for a process in - * creation. It may have no - * address space or lock yet. - */ - if (p->p_state == PRS_NEW) { - PROC_UNLOCK(p); - continue; - } - /* - * An aio daemon switches its - * address space while running. - * Perform a quick check whether - * a process has P_SYSTEM. - * Filter out exiting processes. - */ - if ((p->p_flag & (P_SYSTEM | P_WEXIT)) != 0) { - PROC_UNLOCK(p); - continue; - } - _PHOLD_LITE(p); - PROC_UNLOCK(p); - sx_sunlock(&allproc_lock); - - /* - * Do not swapout a process that - * is waiting for VM data - * structures as there is a possible - * deadlock. Test this first as - * this may block. - * - * Lock the map until swapout - * finishes, or a thread of this - * process may attempt to alter - * the map. - */ - vm = vmspace_acquire_ref(p); - if (vm == NULL) - goto nextproc2; - if (!vm_map_trylock(&vm->vm_map)) - goto nextproc1; - - PROC_LOCK(p); - if (p->p_lock != 1 || (p->p_flag & (P_STOPPED_SINGLE | - P_TRACED | P_SYSTEM)) != 0) - goto nextproc; - - /* - * only aiod changes vmspace, however it will be - * skipped because of the if statement above checking - * for P_SYSTEM - */ - if ((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) != P_INMEM) - goto nextproc; - - switch (p->p_state) { - default: - /* Don't swap out processes in any sort - * of 'special' state. */ - break; - - case PRS_NORMAL: - /* - * do not swapout a realtime process - * Check all the thread groups.. - */ - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - if (PRI_IS_REALTIME(td->td_pri_class)) { - thread_unlock(td); - goto nextproc; - } - slptime = (ticks - td->td_slptick) / hz; - /* - * Guarantee swap_idle_threshold1 - * time in memory. - */ - if (slptime < swap_idle_threshold1) { - thread_unlock(td); - goto nextproc; - } - - /* - * Do not swapout a process if it is - * waiting on a critical event of some - * kind or there is a thread whose - * pageable memory may be accessed. - * - * This could be refined to support - * swapping out a thread. - */ - if (!thread_safetoswapout(td)) { - thread_unlock(td); - goto nextproc; - } - /* - * If the system is under memory stress, - * or if we are swapping - * idle processes >= swap_idle_threshold2, - * then swap the process out. - */ - if (((action & VM_SWAP_NORMAL) == 0) && - (((action & VM_SWAP_IDLE) == 0) || - (slptime < swap_idle_threshold2))) { - thread_unlock(td); - goto nextproc; - } - - if (minslptime > slptime) - minslptime = slptime; - thread_unlock(td); - } - - /* - * If the pageout daemon didn't free enough pages, - * or if this process is idle and the system is - * configured to swap proactively, swap it out. - */ - if ((action & VM_SWAP_NORMAL) || - ((action & VM_SWAP_IDLE) && - (minslptime > swap_idle_threshold2))) { - _PRELE(p); - if (swapout(p) == 0) - didswap++; - PROC_UNLOCK(p); - vm_map_unlock(&vm->vm_map); - vmspace_free(vm); - goto retry; - } - } -nextproc: - PROC_UNLOCK(p); - vm_map_unlock(&vm->vm_map); -nextproc1: - vmspace_free(vm); -nextproc2: - sx_slock(&allproc_lock); - PRELE(p); - } - sx_sunlock(&allproc_lock); - /* - * If we swapped something out, and another process needed memory, - * then wakeup the sched process. - */ - if (didswap) - wakeup(&proc0); -} - -static void -swapclear(p) - struct proc *p; -{ - struct thread *td; - - PROC_LOCK_ASSERT(p, MA_OWNED); - - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - td->td_flags |= TDF_INMEM; - td->td_flags &= ~TDF_SWAPINREQ; - TD_CLR_SWAPPED(td); - if (TD_CAN_RUN(td)) - if (setrunnable(td)) { -#ifdef INVARIANTS - /* - * XXX: We just cleared TDI_SWAPPED - * above and set TDF_INMEM, so this - * should never happen. - */ - panic("not waking up swapper"); -#endif - } - thread_unlock(td); - } - p->p_flag &= ~(P_SWAPPINGIN|P_SWAPPINGOUT); - p->p_flag |= P_INMEM; -} - -static int -swapout(p) - struct proc *p; -{ - struct thread *td; - - PROC_LOCK_ASSERT(p, MA_OWNED); -#if defined(SWAP_DEBUG) - printf("swapping out %d\n", p->p_pid); -#endif - - /* - * The states of this process and its threads may have changed - * by now. Assuming that there is only one pageout daemon thread, - * this process should still be in memory. - */ - KASSERT((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) == P_INMEM, - ("swapout: lost a swapout race?")); - - /* - * remember the process resident count - */ - p->p_vmspace->vm_swrss = vmspace_resident_count(p->p_vmspace); - /* - * Check and mark all threads before we proceed. - */ - p->p_flag &= ~P_INMEM; - p->p_flag |= P_SWAPPINGOUT; - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - if (!thread_safetoswapout(td)) { - thread_unlock(td); - swapclear(p); - return (EBUSY); - } - td->td_flags &= ~TDF_INMEM; - TD_SET_SWAPPED(td); - thread_unlock(td); - } - td = FIRST_THREAD_IN_PROC(p); - ++td->td_ru.ru_nswap; - PROC_UNLOCK(p); - - /* - * This list is stable because all threads are now prevented from - * running. The list is only modified in the context of a running - * thread in this process. - */ - FOREACH_THREAD_IN_PROC(p, td) - vm_thread_swapout(td); - - PROC_LOCK(p); - p->p_flag &= ~P_SWAPPINGOUT; - p->p_swtick = ticks; - return (0); -} -#endif /* !NO_SWAPPING */ diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 65fb65decb1c..3f609b0339d2 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -122,8 +122,7 @@ SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD, * a mapping on demand through vm_fault() will result in a panic. */ vm_offset_t -kva_alloc(size) - vm_size_t size; +kva_alloc(vm_size_t size) { vm_offset_t addr; @@ -144,9 +143,7 @@ kva_alloc(size) * This routine may not block on kernel maps. */ void -kva_free(addr, size) - vm_offset_t addr; - vm_size_t size; +kva_free(vm_offset_t addr, vm_size_t size) { size = round_page(size); @@ -433,9 +430,7 @@ kmem_free(struct vmem *vmem, vm_offset_t addr, vm_size_t size) * This routine may block. */ vm_offset_t -kmap_alloc_wait(map, size) - vm_map_t map; - vm_size_t size; +kmap_alloc_wait(vm_map_t map, vm_size_t size) { vm_offset_t addr; @@ -473,10 +468,7 @@ kmap_alloc_wait(map, size) * waiting for memory in that map. */ void -kmap_free_wakeup(map, addr, size) - vm_map_t map; - vm_offset_t addr; - vm_size_t size; +kmap_free_wakeup(vm_map_t map, vm_offset_t addr, vm_size_t size) { vm_map_lock(map); @@ -520,8 +512,7 @@ kmem_init_zero_region(void) * `start' as allocated, and the range between `start' and `end' as free. */ void -kmem_init(start, end) - vm_offset_t start, end; +kmem_init(vm_offset_t start, vm_offset_t end) { vm_map_t m; diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 69e68a2d3e82..bcf1204b9937 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -713,9 +713,15 @@ static void vm_object_terminate_pages(vm_object_t object) { vm_page_t p, p_next; + struct mtx *mtx, *mtx1; + struct vm_pagequeue *pq, *pq1; + int dequeued; VM_OBJECT_ASSERT_WLOCKED(object); + mtx = NULL; + pq = NULL; + /* * Free any remaining pageable pages. This also removes them from the * paging queues. However, don't free wired pages, just remove them @@ -724,21 +730,60 @@ vm_object_terminate_pages(vm_object_t object) */ TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) { vm_page_assert_unbusied(p); - vm_page_lock(p); - /* - * Optimize the page's removal from the object by resetting - * its "object" field. Specifically, if the page is not - * wired, then the effect of this assignment is that - * vm_page_free()'s call to vm_page_remove() will return - * immediately without modifying the page or the object. - */ - p->object = NULL; - if (p->wire_count == 0) { - vm_page_free(p); - VM_CNT_INC(v_pfree); + if ((object->flags & OBJ_UNMANAGED) == 0) { + /* + * vm_page_free_prep() only needs the page + * lock for managed pages. + */ + mtx1 = vm_page_lockptr(p); + if (mtx1 != mtx) { + if (mtx != NULL) + mtx_unlock(mtx); + if (pq != NULL) { + vm_pagequeue_cnt_add(pq, dequeued); + vm_pagequeue_unlock(pq); + pq = NULL; + } + mtx = mtx1; + mtx_lock(mtx); + } } - vm_page_unlock(p); + p->object = NULL; + if (p->wire_count != 0) + goto unlist; + VM_CNT_INC(v_pfree); + p->flags &= ~PG_ZERO; + if (p->queue != PQ_NONE) { + KASSERT(p->queue < PQ_COUNT, ("vm_object_terminate: " + "page %p is not queued", p)); + pq1 = vm_page_pagequeue(p); + if (pq != pq1) { + if (pq != NULL) { + vm_pagequeue_cnt_add(pq, dequeued); + vm_pagequeue_unlock(pq); + } + pq = pq1; + vm_pagequeue_lock(pq); + dequeued = 0; + } + p->queue = PQ_NONE; + TAILQ_REMOVE(&pq->pq_pl, p, plinks.q); + dequeued--; + } + if (vm_page_free_prep(p, true)) + continue; +unlist: + TAILQ_REMOVE(&object->memq, p, listq); } + if (pq != NULL) { + vm_pagequeue_cnt_add(pq, dequeued); + vm_pagequeue_unlock(pq); + } + if (mtx != NULL) + mtx_unlock(mtx); + + vm_page_free_phys_pglist(&object->memq); + /* * If the object contained any pages, then reset it to an empty state. * None of the object's fields, including "resident_page_count", were @@ -1048,8 +1093,8 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size, * I/O. */ if (object->type == OBJT_VNODE && - (object->flags & OBJ_MIGHTBEDIRTY) != 0) { - vp = object->handle; + (object->flags & OBJ_MIGHTBEDIRTY) != 0 && + ((vp = object->handle)->v_vflag & VV_NOSYNC) == 0) { VM_OBJECT_WUNLOCK(object); (void) vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); @@ -1918,6 +1963,7 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, { vm_page_t p, next; struct mtx *mtx; + struct pglist pgl; VM_OBJECT_ASSERT_WLOCKED(object); KASSERT((object->flags & OBJ_UNMANAGED) == 0 || @@ -1926,6 +1972,7 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, if (object->resident_page_count == 0) return; vm_object_pip_add(object, 1); + TAILQ_INIT(&pgl); again: p = vm_page_find_least(object, start); mtx = NULL; @@ -1953,7 +2000,8 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, goto again; } if (p->wire_count != 0) { - if ((options & OBJPR_NOTMAPPED) == 0) + if ((options & OBJPR_NOTMAPPED) == 0 && + object->ref_count != 0) pmap_remove_all(p); if ((options & OBJPR_CLEANONLY) == 0) { p->valid = 0; @@ -1970,17 +2018,21 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, KASSERT((p->flags & PG_FICTITIOUS) == 0, ("vm_object_page_remove: page %p is fictitious", p)); if ((options & OBJPR_CLEANONLY) != 0 && p->valid != 0) { - if ((options & OBJPR_NOTMAPPED) == 0) + if ((options & OBJPR_NOTMAPPED) == 0 && + object->ref_count != 0) pmap_remove_write(p); - if (p->dirty) + if (p->dirty != 0) continue; } - if ((options & OBJPR_NOTMAPPED) == 0) + if ((options & OBJPR_NOTMAPPED) == 0 && object->ref_count != 0) pmap_remove_all(p); - vm_page_free(p); + p->flags &= ~PG_ZERO; + if (vm_page_free_prep(p, false)) + TAILQ_INSERT_TAIL(&pgl, p, listq); } if (mtx != NULL) mtx_unlock(mtx); + vm_page_free_phys_pglist(&pgl); vm_object_pip_wakeup(object); } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 60d03c4f6a38..4604a7ebc6b6 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -163,6 +163,7 @@ static uma_zone_t fakepg_zone; static void vm_page_alloc_check(vm_page_t m); static void vm_page_clear_dirty_mask(vm_page_t m, vm_page_bits_t pagebits); static void vm_page_enqueue(uint8_t queue, vm_page_t m); +static void vm_page_free_phys(vm_page_t m); static void vm_page_free_wakeup(void); static void vm_page_init(void *dummy); static int vm_page_insert_after(vm_page_t m, vm_object_t object, @@ -1587,6 +1588,7 @@ vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, int req, { vm_page_t m; int flags, req_class; + u_int free_count; KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0) && (object != NULL || (req & VM_ALLOC_SBUSY) == 0) && @@ -1654,7 +1656,7 @@ vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, int req, * At this point we had better have found a good page. */ KASSERT(m != NULL, ("missing page")); - vm_phys_freecnt_adj(m, -1); + free_count = vm_phys_freecnt_adj(m, -1); mtx_unlock(&vm_page_queue_free_mtx); vm_page_alloc_check(m); @@ -1712,7 +1714,7 @@ vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, int req, * Don't wakeup too often - wakeup the pageout daemon when * we would be nearly out of memory. */ - if (vm_paging_needed()) + if (vm_paging_needed(free_count)) pagedaemon_wakeup(); return (m); @@ -1898,7 +1900,7 @@ vm_page_alloc_contig(vm_object_t object, vm_pindex_t pindex, int req, pmap_page_set_memattr(m, memattr); pindex++; } - if (vm_paging_needed()) + if (vm_paging_needed(vm_cnt.v_free_count)) pagedaemon_wakeup(); return (m_ret); } @@ -1947,7 +1949,7 @@ vm_page_t vm_page_alloc_freelist(int flind, int req) { vm_page_t m; - u_int flags; + u_int flags, free_count; int req_class; req_class = req & VM_ALLOC_CLASS_MASK; @@ -1979,7 +1981,7 @@ vm_page_alloc_freelist(int flind, int req) mtx_unlock(&vm_page_queue_free_mtx); return (NULL); } - vm_phys_freecnt_adj(m, -1); + free_count = vm_phys_freecnt_adj(m, -1); mtx_unlock(&vm_page_queue_free_mtx); vm_page_alloc_check(m); @@ -2001,7 +2003,7 @@ vm_page_alloc_freelist(int flind, int req) } /* Unmanaged pages don't use "act_count". */ m->oflags = VPO_UNMANAGED; - if (vm_paging_needed()) + if (vm_paging_needed(free_count)) pagedaemon_wakeup(); return (m); } @@ -2402,13 +2404,7 @@ vm_page_reclaim_run(int req_class, u_long npages, vm_page_t m_run, mtx_lock(&vm_page_queue_free_mtx); do { SLIST_REMOVE_HEAD(&free, plinks.s.ss); - vm_phys_freecnt_adj(m, 1); -#if VM_NRESERVLEVEL > 0 - if (!vm_reserv_free_page(m)) -#else - if (true) -#endif - vm_phys_free_pages(m, 0); + vm_page_free_phys(m); } while ((m = SLIST_FIRST(&free)) != NULL); vm_page_free_wakeup(); mtx_unlock(&vm_page_queue_free_mtx); @@ -2744,7 +2740,7 @@ vm_page_activate(vm_page_t m) * * The page queues must be locked. */ -static inline void +static void vm_page_free_wakeup(void) { @@ -2770,17 +2766,30 @@ vm_page_free_wakeup(void) } /* - * vm_page_free_toq: + * vm_page_free_prep: * - * Returns the given page to the free list, - * disassociating it with any VM object. + * Prepares the given page to be put on the free list, + * disassociating it from any VM object. The caller may return + * the page to the free list only if this function returns true. * - * The object must be locked. The page must be locked if it is managed. + * The object must be locked. The page must be locked if it is + * managed. For a queued managed page, the pagequeue_locked + * argument specifies whether the page queue is already locked. */ -void -vm_page_free_toq(vm_page_t m) +bool +vm_page_free_prep(vm_page_t m, bool pagequeue_locked) { +#if defined(DIAGNOSTIC) && defined(PHYS_TO_DMAP) + if ((m->flags & PG_ZERO) != 0) { + uint64_t *p; + int i; + p = (uint64_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)); + for (i = 0; i < PAGE_SIZE / sizeof(uint64_t); i++, p++) + KASSERT(*p == 0, ("vm_page_free_prep %p PG_ZERO %d %jx", + m, i, (uintmax_t)*p)); + } +#endif if ((m->oflags & VPO_UNMANAGED) == 0) { vm_page_lock_assert(m, MA_OWNED); KASSERT(!pmap_page_is_mapped(m), @@ -2793,23 +2802,26 @@ vm_page_free_toq(vm_page_t m) if (vm_page_sbusied(m)) panic("vm_page_free: freeing busy page %p", m); - /* - * Unqueue, then remove page. Note that we cannot destroy - * the page here because we do not want to call the pager's - * callback routine until after we've put the page on the - * appropriate free queue. - */ - vm_page_remque(m); vm_page_remove(m); /* * If fictitious remove object association and - * return, otherwise delay object association removal. + * return. */ if ((m->flags & PG_FICTITIOUS) != 0) { - return; + KASSERT(m->wire_count == 1, + ("fictitious page %p is not wired", m)); + KASSERT(m->queue == PQ_NONE, + ("fictitious page %p is queued", m)); + return (false); } + if (m->queue != PQ_NONE) { + if (pagequeue_locked) + vm_page_dequeue_locked(m); + else + vm_page_dequeue(m); + } m->valid = 0; vm_page_undirty(m); @@ -2820,28 +2832,68 @@ vm_page_free_toq(vm_page_t m) KASSERT((m->flags & PG_UNHOLDFREE) == 0, ("vm_page_free: freeing PG_UNHOLDFREE page %p", m)); m->flags |= PG_UNHOLDFREE; - } else { - /* - * Restore the default memory attribute to the page. - */ - if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT) - pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT); - - /* - * Insert the page into the physical memory allocator's free - * page queues. - */ - mtx_lock(&vm_page_queue_free_mtx); - vm_phys_freecnt_adj(m, 1); -#if VM_NRESERVLEVEL > 0 - if (!vm_reserv_free_page(m)) -#else - if (TRUE) -#endif - vm_phys_free_pages(m, 0); - vm_page_free_wakeup(); - mtx_unlock(&vm_page_queue_free_mtx); + return (false); } + + /* + * Restore the default memory attribute to the page. + */ + if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT) + pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT); + + return (true); +} + +/* + * Insert the page into the physical memory allocator's free page + * queues. This is the last step to free a page. + */ +static void +vm_page_free_phys(vm_page_t m) +{ + + mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); + + vm_phys_freecnt_adj(m, 1); +#if VM_NRESERVLEVEL > 0 + if (!vm_reserv_free_page(m)) +#endif + vm_phys_free_pages(m, 0); +} + +void +vm_page_free_phys_pglist(struct pglist *tq) +{ + vm_page_t m; + + if (TAILQ_EMPTY(tq)) + return; + mtx_lock(&vm_page_queue_free_mtx); + TAILQ_FOREACH(m, tq, listq) + vm_page_free_phys(m); + vm_page_free_wakeup(); + mtx_unlock(&vm_page_queue_free_mtx); +} + +/* + * vm_page_free_toq: + * + * Returns the given page to the free list, disassociating it + * from any VM object. + * + * The object must be locked. The page must be locked if it is + * managed. + */ +void +vm_page_free_toq(vm_page_t m) +{ + + if (!vm_page_free_prep(m, false)) + return; + mtx_lock(&vm_page_queue_free_mtx); + vm_page_free_phys(m); + vm_page_free_wakeup(); + mtx_unlock(&vm_page_queue_free_mtx); } /* @@ -3038,26 +3090,29 @@ vm_page_unswappable(vm_page_t m) } /* - * vm_page_try_to_free() + * Attempt to free the page. If it cannot be freed, do nothing. Returns true + * if the page is freed and false otherwise. * - * Attempt to free the page. If we cannot free it, we do nothing. - * 1 is returned on success, 0 on failure. + * The page must be managed. The page and its containing object must be + * locked. */ -int +bool vm_page_try_to_free(vm_page_t m) { - vm_page_lock_assert(m, MA_OWNED); - if (m->object != NULL) - VM_OBJECT_ASSERT_WLOCKED(m->object); - if (m->dirty || m->hold_count || m->wire_count || - (m->oflags & VPO_UNMANAGED) != 0 || vm_page_busied(m)) - return (0); - pmap_remove_all(m); - if (m->dirty) - return (0); + vm_page_assert_locked(m); + VM_OBJECT_ASSERT_WLOCKED(m->object); + KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("page %p is unmanaged", m)); + if (m->dirty != 0 || m->hold_count != 0 || m->wire_count != 0 || + vm_page_busied(m)) + return (false); + if (m->object->ref_count != 0) { + pmap_remove_all(m); + if (m->dirty != 0) + return (false); + } vm_page_free(m); - return (1); + return (true); } /* diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 8c41eca015a5..9bbe7291e46e 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -477,12 +477,13 @@ void vm_page_change_lock(vm_page_t m, struct mtx **mtx); vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int); int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags, vm_page_t *ma, int count); -int vm_page_try_to_free (vm_page_t); void vm_page_deactivate (vm_page_t); void vm_page_deactivate_noreuse(vm_page_t); void vm_page_dequeue(vm_page_t m); void vm_page_dequeue_locked(vm_page_t m); vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t); +void vm_page_free_phys_pglist(struct pglist *tq); +bool vm_page_free_prep(vm_page_t m, bool pagequeue_locked); vm_page_t vm_page_getfake(vm_paddr_t paddr, vm_memattr_t memattr); void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr); int vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t); @@ -511,6 +512,7 @@ void vm_page_set_valid_range(vm_page_t m, int base, int size); int vm_page_sleep_if_busy(vm_page_t m, const char *msg); vm_offset_t vm_page_startup(vm_offset_t vaddr); void vm_page_sunbusy(vm_page_t m); +bool vm_page_try_to_free(vm_page_t m); int vm_page_trysbusy(vm_page_t m); void vm_page_unhold_pages(vm_page_t *ma, int count); void vm_page_unswappable(vm_page_t m); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 921c003047b0..2872aeb49028 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -141,19 +141,6 @@ SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_SECOND, kproc_start, SDT_PROVIDER_DEFINE(vm); SDT_PROBE_DEFINE(vm, , , vm__lowmem_scan); -#if !defined(NO_SWAPPING) -/* the kernel process "vm_daemon"*/ -static void vm_daemon(void); -static struct proc *vmproc; - -static struct kproc_desc vm_kp = { - "vmdaemon", - vm_daemon, - &vmproc -}; -SYSINIT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, &vm_kp); -#endif - /* Pagedaemon activity rates, in subdivisions of one second. */ #define VM_LAUNDER_RATE 10 #define VM_INACT_SCAN_RATE 2 @@ -171,27 +158,12 @@ static enum { VM_LAUNDRY_SHORTFALL } vm_laundry_request = VM_LAUNDRY_IDLE; -#if !defined(NO_SWAPPING) -static int vm_pageout_req_swapout; /* XXX */ -static int vm_daemon_needed; -static struct mtx vm_daemon_mtx; -/* Allow for use by vm_pageout before vm_daemon is initialized. */ -MTX_SYSINIT(vm_daemon, &vm_daemon_mtx, "vm daemon", MTX_DEF); -#endif static int vm_pageout_update_period; static int disable_swap_pageouts; static int lowmem_period = 10; static time_t lowmem_uptime; static int swapdev_enabled; -#if defined(NO_SWAPPING) -static int vm_swap_enabled = 0; -static int vm_swap_idle_enabled = 0; -#else -static int vm_swap_enabled = 1; -static int vm_swap_idle_enabled = 0; -#endif - static int vm_panic_on_oom = 0; SYSCTL_INT(_vm, OID_AUTO, panic_on_oom, @@ -209,18 +181,6 @@ SYSCTL_INT(_vm, OID_AUTO, pageout_update_period, SYSCTL_INT(_vm, OID_AUTO, lowmem_period, CTLFLAG_RW, &lowmem_period, 0, "Low memory callback period"); -#if defined(NO_SWAPPING) -SYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled, - CTLFLAG_RD, &vm_swap_enabled, 0, "Enable entire process swapout"); -SYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled, - CTLFLAG_RD, &vm_swap_idle_enabled, 0, "Allow swapout on idle criteria"); -#else -SYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled, - CTLFLAG_RW, &vm_swap_enabled, 0, "Enable entire process swapout"); -SYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled, - CTLFLAG_RW, &vm_swap_idle_enabled, 0, "Allow swapout on idle criteria"); -#endif - SYSCTL_INT(_vm, OID_AUTO, disable_swapspace_pageouts, CTLFLAG_RW, &disable_swap_pageouts, 0, "Disallow swapout of dirty pages"); @@ -262,11 +222,6 @@ static boolean_t vm_pageout_fallback_object_lock(vm_page_t, vm_page_t *); static int vm_pageout_launder(struct vm_domain *vmd, int launder, bool in_shortfall); static void vm_pageout_laundry_worker(void *arg); -#if !defined(NO_SWAPPING) -static void vm_pageout_map_deactivate_pages(vm_map_t, long); -static void vm_pageout_object_deactivate_pages(pmap_t, vm_object_t, long); -static void vm_req_vmdaemon(int req); -#endif static boolean_t vm_pageout_page_lock(vm_page_t, vm_page_t *); /* @@ -632,171 +587,6 @@ vm_pageout_swapoff(void *arg __unused, struct swdevt *sp __unused) atomic_store_rel_int(&swapdev_enabled, 0); } -#if !defined(NO_SWAPPING) -/* - * vm_pageout_object_deactivate_pages - * - * Deactivate enough pages to satisfy the inactive target - * requirements. - * - * The object and map must be locked. - */ -static void -vm_pageout_object_deactivate_pages(pmap_t pmap, vm_object_t first_object, - long desired) -{ - vm_object_t backing_object, object; - vm_page_t p; - int act_delta, remove_mode; - - VM_OBJECT_ASSERT_LOCKED(first_object); - if ((first_object->flags & OBJ_FICTITIOUS) != 0) - return; - for (object = first_object;; object = backing_object) { - if (pmap_resident_count(pmap) <= desired) - goto unlock_return; - VM_OBJECT_ASSERT_LOCKED(object); - if ((object->flags & OBJ_UNMANAGED) != 0 || - object->paging_in_progress != 0) - goto unlock_return; - - remove_mode = 0; - if (object->shadow_count > 1) - remove_mode = 1; - /* - * Scan the object's entire memory queue. - */ - TAILQ_FOREACH(p, &object->memq, listq) { - if (pmap_resident_count(pmap) <= desired) - goto unlock_return; - if (vm_page_busied(p)) - continue; - VM_CNT_INC(v_pdpages); - vm_page_lock(p); - if (p->wire_count != 0 || p->hold_count != 0 || - !pmap_page_exists_quick(pmap, p)) { - vm_page_unlock(p); - continue; - } - act_delta = pmap_ts_referenced(p); - if ((p->aflags & PGA_REFERENCED) != 0) { - if (act_delta == 0) - act_delta = 1; - vm_page_aflag_clear(p, PGA_REFERENCED); - } - if (!vm_page_active(p) && act_delta != 0) { - vm_page_activate(p); - p->act_count += act_delta; - } else if (vm_page_active(p)) { - if (act_delta == 0) { - p->act_count -= min(p->act_count, - ACT_DECLINE); - if (!remove_mode && p->act_count == 0) { - pmap_remove_all(p); - vm_page_deactivate(p); - } else - vm_page_requeue(p); - } else { - vm_page_activate(p); - if (p->act_count < ACT_MAX - - ACT_ADVANCE) - p->act_count += ACT_ADVANCE; - vm_page_requeue(p); - } - } else if (vm_page_inactive(p)) - pmap_remove_all(p); - vm_page_unlock(p); - } - if ((backing_object = object->backing_object) == NULL) - goto unlock_return; - VM_OBJECT_RLOCK(backing_object); - if (object != first_object) - VM_OBJECT_RUNLOCK(object); - } -unlock_return: - if (object != first_object) - VM_OBJECT_RUNLOCK(object); -} - -/* - * deactivate some number of pages in a map, try to do it fairly, but - * that is really hard to do. - */ -static void -vm_pageout_map_deactivate_pages(map, desired) - vm_map_t map; - long desired; -{ - vm_map_entry_t tmpe; - vm_object_t obj, bigobj; - int nothingwired; - - if (!vm_map_trylock(map)) - return; - - bigobj = NULL; - nothingwired = TRUE; - - /* - * first, search out the biggest object, and try to free pages from - * that. - */ - tmpe = map->header.next; - while (tmpe != &map->header) { - if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { - obj = tmpe->object.vm_object; - if (obj != NULL && VM_OBJECT_TRYRLOCK(obj)) { - if (obj->shadow_count <= 1 && - (bigobj == NULL || - bigobj->resident_page_count < obj->resident_page_count)) { - if (bigobj != NULL) - VM_OBJECT_RUNLOCK(bigobj); - bigobj = obj; - } else - VM_OBJECT_RUNLOCK(obj); - } - } - if (tmpe->wired_count > 0) - nothingwired = FALSE; - tmpe = tmpe->next; - } - - if (bigobj != NULL) { - vm_pageout_object_deactivate_pages(map->pmap, bigobj, desired); - VM_OBJECT_RUNLOCK(bigobj); - } - /* - * Next, hunt around for other pages to deactivate. We actually - * do this search sort of wrong -- .text first is not the best idea. - */ - tmpe = map->header.next; - while (tmpe != &map->header) { - if (pmap_resident_count(vm_map_pmap(map)) <= desired) - break; - if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { - obj = tmpe->object.vm_object; - if (obj != NULL) { - VM_OBJECT_RLOCK(obj); - vm_pageout_object_deactivate_pages(map->pmap, obj, desired); - VM_OBJECT_RUNLOCK(obj); - } - } - tmpe = tmpe->next; - } - - /* - * Remove all mappings if a process is swapped out, this will free page - * table pages. - */ - if (desired == 0 && nothingwired) { - pmap_remove(vm_map_pmap(map), vm_map_min(map), - vm_map_max(map)); - } - - vm_map_unlock(map); -} -#endif /* !defined(NO_SWAPPING) */ - /* * Attempt to acquire all of the necessary locks to launder a page and * then call through the clustering layer to PUTPAGES. Wait a short @@ -1563,14 +1353,12 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) vm_pagequeue_unlock(pq); } -#if !defined(NO_SWAPPING) /* * Wakeup the swapout daemon if we didn't free the targeted number of * pages. */ - if (vm_swap_enabled && page_shortage > 0) - vm_req_vmdaemon(VM_SWAP_NORMAL); -#endif + if (page_shortage > 0) + vm_swapout_run(); /* * If the inactive queue scan fails repeatedly to meet its @@ -1720,19 +1508,8 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) vm_page_unlock(m); } vm_pagequeue_unlock(pq); -#if !defined(NO_SWAPPING) - /* - * Idle process swapout -- run once per second when we are reclaiming - * pages. - */ - if (vm_swap_idle_enabled && pass > 0) { - static long lsec; - if (time_second != lsec) { - vm_req_vmdaemon(VM_SWAP_IDLE); - lsec = time_second; - } - } -#endif + if (pass > 0) + vm_swapout_run_idle(); return (page_shortage <= 0); } @@ -2158,167 +1935,3 @@ pagedaemon_wakeup(void) wakeup(&vm_pageout_wanted); } } - -#if !defined(NO_SWAPPING) -static void -vm_req_vmdaemon(int req) -{ - static int lastrun = 0; - - mtx_lock(&vm_daemon_mtx); - vm_pageout_req_swapout |= req; - if ((ticks > (lastrun + hz)) || (ticks < lastrun)) { - wakeup(&vm_daemon_needed); - lastrun = ticks; - } - mtx_unlock(&vm_daemon_mtx); -} - -static void -vm_daemon(void) -{ - struct rlimit rsslim; - struct proc *p; - struct thread *td; - struct vmspace *vm; - int breakout, swapout_flags, tryagain, attempts; -#ifdef RACCT - uint64_t rsize, ravailable; -#endif - - while (TRUE) { - mtx_lock(&vm_daemon_mtx); - msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", -#ifdef RACCT - racct_enable ? hz : 0 -#else - 0 -#endif - ); - swapout_flags = vm_pageout_req_swapout; - vm_pageout_req_swapout = 0; - mtx_unlock(&vm_daemon_mtx); - if (swapout_flags) - swapout_procs(swapout_flags); - - /* - * scan the processes for exceeding their rlimits or if - * process is swapped out -- deactivate pages - */ - tryagain = 0; - attempts = 0; -again: - attempts++; - sx_slock(&allproc_lock); - FOREACH_PROC_IN_SYSTEM(p) { - vm_pindex_t limit, size; - - /* - * if this is a system process or if we have already - * looked at this process, skip it. - */ - PROC_LOCK(p); - if (p->p_state != PRS_NORMAL || - p->p_flag & (P_INEXEC | P_SYSTEM | P_WEXIT)) { - PROC_UNLOCK(p); - continue; - } - /* - * if the process is in a non-running type state, - * don't touch it. - */ - breakout = 0; - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - if (!TD_ON_RUNQ(td) && - !TD_IS_RUNNING(td) && - !TD_IS_SLEEPING(td) && - !TD_IS_SUSPENDED(td)) { - thread_unlock(td); - breakout = 1; - break; - } - thread_unlock(td); - } - if (breakout) { - PROC_UNLOCK(p); - continue; - } - /* - * get a limit - */ - lim_rlimit_proc(p, RLIMIT_RSS, &rsslim); - limit = OFF_TO_IDX( - qmin(rsslim.rlim_cur, rsslim.rlim_max)); - - /* - * let processes that are swapped out really be - * swapped out set the limit to nothing (will force a - * swap-out.) - */ - if ((p->p_flag & P_INMEM) == 0) - limit = 0; /* XXX */ - vm = vmspace_acquire_ref(p); - _PHOLD_LITE(p); - PROC_UNLOCK(p); - if (vm == NULL) { - PRELE(p); - continue; - } - sx_sunlock(&allproc_lock); - - size = vmspace_resident_count(vm); - if (size >= limit) { - vm_pageout_map_deactivate_pages( - &vm->vm_map, limit); - size = vmspace_resident_count(vm); - } -#ifdef RACCT - if (racct_enable) { - rsize = IDX_TO_OFF(size); - PROC_LOCK(p); - if (p->p_state == PRS_NORMAL) - racct_set(p, RACCT_RSS, rsize); - ravailable = racct_get_available(p, RACCT_RSS); - PROC_UNLOCK(p); - if (rsize > ravailable) { - /* - * Don't be overly aggressive; this - * might be an innocent process, - * and the limit could've been exceeded - * by some memory hog. Don't try - * to deactivate more than 1/4th - * of process' resident set size. - */ - if (attempts <= 8) { - if (ravailable < rsize - - (rsize / 4)) { - ravailable = rsize - - (rsize / 4); - } - } - vm_pageout_map_deactivate_pages( - &vm->vm_map, - OFF_TO_IDX(ravailable)); - /* Update RSS usage after paging out. */ - size = vmspace_resident_count(vm); - rsize = IDX_TO_OFF(size); - PROC_LOCK(p); - if (p->p_state == PRS_NORMAL) - racct_set(p, RACCT_RSS, rsize); - PROC_UNLOCK(p); - if (rsize > ravailable) - tryagain = 1; - } - } -#endif - vmspace_free(vm); - sx_slock(&allproc_lock); - PRELE(p); - } - sx_sunlock(&allproc_lock); - if (tryagain != 0 && attempts <= 10) - goto again; - } -} -#endif /* !defined(NO_SWAPPING) */ diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h index adc32a23817b..f0c28835eba5 100644 --- a/sys/vm/vm_pageout.h +++ b/sys/vm/vm_pageout.h @@ -77,12 +77,6 @@ extern int vm_pageout_page_count; extern bool vm_pageout_wanted; extern bool vm_pages_needed; -/* - * Swap out requests - */ -#define VM_SWAP_NORMAL 1 -#define VM_SWAP_IDLE 2 - #define VM_OOM_MEM 1 #define VM_OOM_SWAPZ 2 @@ -109,5 +103,8 @@ extern void vm_waitpfault(void); #ifdef _KERNEL int vm_pageout_flush(vm_page_t *, int, int, int, int *, boolean_t *); void vm_pageout_oom(int shortage); + +void vm_swapout_run(void); +void vm_swapout_run_idle(void); #endif #endif /* _VM_VM_PAGEOUT_H_ */ diff --git a/sys/vm/vm_param.h b/sys/vm/vm_param.h index 8ca83bf18ddf..ff36bbb6d1d8 100644 --- a/sys/vm/vm_param.h +++ b/sys/vm/vm_param.h @@ -84,7 +84,8 @@ #define VM_V_PAGEOUT_FREE_MIN 9 /* vm_cnt.v_pageout_free_min */ #define VM_OBSOLETE_10 10 /* pageout algorithm */ #define VM_SWAPPING_ENABLED 11 /* swapping enabled */ -#define VM_MAXID 12 /* number of valid vm ids */ +#define VM_OVERCOMMIT 12 /* vm.overcommit */ +#define VM_MAXID 13 /* number of valid vm ids */ /* * Structure for swap device statistics diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h index ef0a95e4933f..4a08be7a42d1 100644 --- a/sys/vm/vm_phys.h +++ b/sys/vm/vm_phys.h @@ -112,13 +112,13 @@ vm_phys_domain(vm_page_t m) #endif } -static inline void +static inline u_int vm_phys_freecnt_adj(vm_page_t m, int adj) { mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); - vm_cnt.v_free_count += adj; vm_phys_domain(m)->vmd_free_count += adj; + return (vm_cnt.v_free_count += adj); } #endif /* _KERNEL */ diff --git a/sys/vm/vm_swapout.c b/sys/vm/vm_swapout.c new file mode 100644 index 000000000000..726c2e2f91a0 --- /dev/null +++ b/sys/vm/vm_swapout.c @@ -0,0 +1,975 @@ +/*- + * Copyright (c) 1991 Regents of the University of California. + * All rights reserved. + * Copyright (c) 1994 John S. Dyson + * All rights reserved. + * Copyright (c) 1994 David Greenman + * All rights reserved. + * Copyright (c) 2005 Yahoo! Technologies Norway AS + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * The Mach Operating System project at Carnegie-Mellon University. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * from: @(#)vm_pageout.c 7.4 (Berkeley) 5/7/91 + * + * + * Copyright (c) 1987, 1990 Carnegie-Mellon University. + * All rights reserved. + * + * Authors: Avadis Tevanian, Jr., Michael Wayne Young + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_kstack_pages.h" +#include "opt_kstack_max_pages.h" +#include "opt_vm.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* the kernel process "vm_daemon" */ +static void vm_daemon(void); +static struct proc *vmproc; + +static struct kproc_desc vm_kp = { + "vmdaemon", + vm_daemon, + &vmproc +}; +SYSINIT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, &vm_kp); + +static int vm_swap_enabled = 1; +static int vm_swap_idle_enabled = 0; + +SYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled, CTLFLAG_RW, + &vm_swap_enabled, 0, + "Enable entire process swapout"); +SYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled, CTLFLAG_RW, + &vm_swap_idle_enabled, 0, + "Allow swapout on idle criteria"); + +/* + * Swap_idle_threshold1 is the guaranteed swapped in time for a process + */ +static int swap_idle_threshold1 = 2; +SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold1, CTLFLAG_RW, + &swap_idle_threshold1, 0, + "Guaranteed swapped in time for a process"); + +/* + * Swap_idle_threshold2 is the time that a process can be idle before + * it will be swapped out, if idle swapping is enabled. + */ +static int swap_idle_threshold2 = 10; +SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold2, CTLFLAG_RW, + &swap_idle_threshold2, 0, + "Time before a process will be swapped out"); + +static int vm_pageout_req_swapout; /* XXX */ +static int vm_daemon_needed; +static struct mtx vm_daemon_mtx; +/* Allow for use by vm_pageout before vm_daemon is initialized. */ +MTX_SYSINIT(vm_daemon, &vm_daemon_mtx, "vm daemon", MTX_DEF); + +static void swapclear(struct proc *); +static int swapout(struct proc *); +static void vm_swapout_map_deactivate_pages(vm_map_t, long); +static void vm_swapout_object_deactivate_pages(pmap_t, vm_object_t, long); +static void swapout_procs(int action); +static void vm_req_vmdaemon(int req); +static void vm_thread_swapin(struct thread *td); +static void vm_thread_swapout(struct thread *td); + +/* + * vm_swapout_object_deactivate_pages + * + * Deactivate enough pages to satisfy the inactive target + * requirements. + * + * The object and map must be locked. + */ +static void +vm_swapout_object_deactivate_pages(pmap_t pmap, vm_object_t first_object, + long desired) +{ + vm_object_t backing_object, object; + vm_page_t p; + int act_delta, remove_mode; + + VM_OBJECT_ASSERT_LOCKED(first_object); + if ((first_object->flags & OBJ_FICTITIOUS) != 0) + return; + for (object = first_object;; object = backing_object) { + if (pmap_resident_count(pmap) <= desired) + goto unlock_return; + VM_OBJECT_ASSERT_LOCKED(object); + if ((object->flags & OBJ_UNMANAGED) != 0 || + object->paging_in_progress != 0) + goto unlock_return; + + remove_mode = 0; + if (object->shadow_count > 1) + remove_mode = 1; + /* + * Scan the object's entire memory queue. + */ + TAILQ_FOREACH(p, &object->memq, listq) { + if (pmap_resident_count(pmap) <= desired) + goto unlock_return; + if (vm_page_busied(p)) + continue; + VM_CNT_INC(v_pdpages); + vm_page_lock(p); + if (p->wire_count != 0 || p->hold_count != 0 || + !pmap_page_exists_quick(pmap, p)) { + vm_page_unlock(p); + continue; + } + act_delta = pmap_ts_referenced(p); + if ((p->aflags & PGA_REFERENCED) != 0) { + if (act_delta == 0) + act_delta = 1; + vm_page_aflag_clear(p, PGA_REFERENCED); + } + if (!vm_page_active(p) && act_delta != 0) { + vm_page_activate(p); + p->act_count += act_delta; + } else if (vm_page_active(p)) { + if (act_delta == 0) { + p->act_count -= min(p->act_count, + ACT_DECLINE); + if (!remove_mode && p->act_count == 0) { + pmap_remove_all(p); + vm_page_deactivate(p); + } else + vm_page_requeue(p); + } else { + vm_page_activate(p); + if (p->act_count < ACT_MAX - + ACT_ADVANCE) + p->act_count += ACT_ADVANCE; + vm_page_requeue(p); + } + } else if (vm_page_inactive(p)) + pmap_remove_all(p); + vm_page_unlock(p); + } + if ((backing_object = object->backing_object) == NULL) + goto unlock_return; + VM_OBJECT_RLOCK(backing_object); + if (object != first_object) + VM_OBJECT_RUNLOCK(object); + } +unlock_return: + if (object != first_object) + VM_OBJECT_RUNLOCK(object); +} + +/* + * deactivate some number of pages in a map, try to do it fairly, but + * that is really hard to do. + */ +static void +vm_swapout_map_deactivate_pages(vm_map_t map, long desired) +{ + vm_map_entry_t tmpe; + vm_object_t obj, bigobj; + int nothingwired; + + if (!vm_map_trylock(map)) + return; + + bigobj = NULL; + nothingwired = TRUE; + + /* + * first, search out the biggest object, and try to free pages from + * that. + */ + tmpe = map->header.next; + while (tmpe != &map->header) { + if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { + obj = tmpe->object.vm_object; + if (obj != NULL && VM_OBJECT_TRYRLOCK(obj)) { + if (obj->shadow_count <= 1 && + (bigobj == NULL || + bigobj->resident_page_count < + obj->resident_page_count)) { + if (bigobj != NULL) + VM_OBJECT_RUNLOCK(bigobj); + bigobj = obj; + } else + VM_OBJECT_RUNLOCK(obj); + } + } + if (tmpe->wired_count > 0) + nothingwired = FALSE; + tmpe = tmpe->next; + } + + if (bigobj != NULL) { + vm_swapout_object_deactivate_pages(map->pmap, bigobj, desired); + VM_OBJECT_RUNLOCK(bigobj); + } + /* + * Next, hunt around for other pages to deactivate. We actually + * do this search sort of wrong -- .text first is not the best idea. + */ + tmpe = map->header.next; + while (tmpe != &map->header) { + if (pmap_resident_count(vm_map_pmap(map)) <= desired) + break; + if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { + obj = tmpe->object.vm_object; + if (obj != NULL) { + VM_OBJECT_RLOCK(obj); + vm_swapout_object_deactivate_pages(map->pmap, + obj, desired); + VM_OBJECT_RUNLOCK(obj); + } + } + tmpe = tmpe->next; + } + + /* + * Remove all mappings if a process is swapped out, this will free page + * table pages. + */ + if (desired == 0 && nothingwired) { + pmap_remove(vm_map_pmap(map), vm_map_min(map), + vm_map_max(map)); + } + + vm_map_unlock(map); +} + +/* + * Swap out requests + */ +#define VM_SWAP_NORMAL 1 +#define VM_SWAP_IDLE 2 + +void +vm_swapout_run(void) +{ + + if (vm_swap_enabled) + vm_req_vmdaemon(VM_SWAP_NORMAL); +} + +/* + * Idle process swapout -- run once per second when pagedaemons are + * reclaiming pages. + */ +void +vm_swapout_run_idle(void) +{ + static long lsec; + + if (!vm_swap_idle_enabled || time_second == lsec) + return; + vm_req_vmdaemon(VM_SWAP_IDLE); + lsec = time_second; +} + +static void +vm_req_vmdaemon(int req) +{ + static int lastrun = 0; + + mtx_lock(&vm_daemon_mtx); + vm_pageout_req_swapout |= req; + if ((ticks > (lastrun + hz)) || (ticks < lastrun)) { + wakeup(&vm_daemon_needed); + lastrun = ticks; + } + mtx_unlock(&vm_daemon_mtx); +} + +static void +vm_daemon(void) +{ + struct rlimit rsslim; + struct proc *p; + struct thread *td; + struct vmspace *vm; + int breakout, swapout_flags, tryagain, attempts; +#ifdef RACCT + uint64_t rsize, ravailable; +#endif + + while (TRUE) { + mtx_lock(&vm_daemon_mtx); + msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", +#ifdef RACCT + racct_enable ? hz : 0 +#else + 0 +#endif + ); + swapout_flags = vm_pageout_req_swapout; + vm_pageout_req_swapout = 0; + mtx_unlock(&vm_daemon_mtx); + if (swapout_flags) + swapout_procs(swapout_flags); + + /* + * scan the processes for exceeding their rlimits or if + * process is swapped out -- deactivate pages + */ + tryagain = 0; + attempts = 0; +again: + attempts++; + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + vm_pindex_t limit, size; + + /* + * if this is a system process or if we have already + * looked at this process, skip it. + */ + PROC_LOCK(p); + if (p->p_state != PRS_NORMAL || + p->p_flag & (P_INEXEC | P_SYSTEM | P_WEXIT)) { + PROC_UNLOCK(p); + continue; + } + /* + * if the process is in a non-running type state, + * don't touch it. + */ + breakout = 0; + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + if (!TD_ON_RUNQ(td) && + !TD_IS_RUNNING(td) && + !TD_IS_SLEEPING(td) && + !TD_IS_SUSPENDED(td)) { + thread_unlock(td); + breakout = 1; + break; + } + thread_unlock(td); + } + if (breakout) { + PROC_UNLOCK(p); + continue; + } + /* + * get a limit + */ + lim_rlimit_proc(p, RLIMIT_RSS, &rsslim); + limit = OFF_TO_IDX( + qmin(rsslim.rlim_cur, rsslim.rlim_max)); + + /* + * let processes that are swapped out really be + * swapped out set the limit to nothing (will force a + * swap-out.) + */ + if ((p->p_flag & P_INMEM) == 0) + limit = 0; /* XXX */ + vm = vmspace_acquire_ref(p); + _PHOLD_LITE(p); + PROC_UNLOCK(p); + if (vm == NULL) { + PRELE(p); + continue; + } + sx_sunlock(&allproc_lock); + + size = vmspace_resident_count(vm); + if (size >= limit) { + vm_swapout_map_deactivate_pages( + &vm->vm_map, limit); + size = vmspace_resident_count(vm); + } +#ifdef RACCT + if (racct_enable) { + rsize = IDX_TO_OFF(size); + PROC_LOCK(p); + if (p->p_state == PRS_NORMAL) + racct_set(p, RACCT_RSS, rsize); + ravailable = racct_get_available(p, RACCT_RSS); + PROC_UNLOCK(p); + if (rsize > ravailable) { + /* + * Don't be overly aggressive; this + * might be an innocent process, + * and the limit could've been exceeded + * by some memory hog. Don't try + * to deactivate more than 1/4th + * of process' resident set size. + */ + if (attempts <= 8) { + if (ravailable < rsize - + (rsize / 4)) { + ravailable = rsize - + (rsize / 4); + } + } + vm_swapout_map_deactivate_pages( + &vm->vm_map, + OFF_TO_IDX(ravailable)); + /* Update RSS usage after paging out. */ + size = vmspace_resident_count(vm); + rsize = IDX_TO_OFF(size); + PROC_LOCK(p); + if (p->p_state == PRS_NORMAL) + racct_set(p, RACCT_RSS, rsize); + PROC_UNLOCK(p); + if (rsize > ravailable) + tryagain = 1; + } + } +#endif + vmspace_free(vm); + sx_slock(&allproc_lock); + PRELE(p); + } + sx_sunlock(&allproc_lock); + if (tryagain != 0 && attempts <= 10) + goto again; + } +} + +/* + * Allow a thread's kernel stack to be paged out. + */ +static void +vm_thread_swapout(struct thread *td) +{ + vm_object_t ksobj; + vm_page_t m; + int i, pages; + + cpu_thread_swapout(td); + pages = td->td_kstack_pages; + ksobj = td->td_kstack_obj; + pmap_qremove(td->td_kstack, pages); + VM_OBJECT_WLOCK(ksobj); + for (i = 0; i < pages; i++) { + m = vm_page_lookup(ksobj, i); + if (m == NULL) + panic("vm_thread_swapout: kstack already missing?"); + vm_page_dirty(m); + vm_page_lock(m); + vm_page_unwire(m, PQ_INACTIVE); + vm_page_unlock(m); + } + VM_OBJECT_WUNLOCK(ksobj); +} + +/* + * Bring the kernel stack for a specified thread back in. + */ +static void +vm_thread_swapin(struct thread *td) +{ + vm_object_t ksobj; + vm_page_t ma[KSTACK_MAX_PAGES]; + int pages; + + pages = td->td_kstack_pages; + ksobj = td->td_kstack_obj; + VM_OBJECT_WLOCK(ksobj); + (void)vm_page_grab_pages(ksobj, 0, VM_ALLOC_NORMAL | VM_ALLOC_WIRED, ma, + pages); + for (int i = 0; i < pages;) { + int j, a, count, rv; + + vm_page_assert_xbusied(ma[i]); + if (ma[i]->valid == VM_PAGE_BITS_ALL) { + vm_page_xunbusy(ma[i]); + i++; + continue; + } + vm_object_pip_add(ksobj, 1); + for (j = i + 1; j < pages; j++) + if (ma[j]->valid == VM_PAGE_BITS_ALL) + break; + rv = vm_pager_has_page(ksobj, ma[i]->pindex, NULL, &a); + KASSERT(rv == 1, ("%s: missing page %p", __func__, ma[i])); + count = min(a + 1, j - i); + rv = vm_pager_get_pages(ksobj, ma + i, count, NULL, NULL); + KASSERT(rv == VM_PAGER_OK, ("%s: cannot get kstack for proc %d", + __func__, td->td_proc->p_pid)); + vm_object_pip_wakeup(ksobj); + for (j = i; j < i + count; j++) + vm_page_xunbusy(ma[j]); + i += count; + } + VM_OBJECT_WUNLOCK(ksobj); + pmap_qenter(td->td_kstack, ma, pages); + cpu_thread_swapin(td); +} + +void +faultin(struct proc *p) +{ + struct thread *td; + + PROC_LOCK_ASSERT(p, MA_OWNED); + /* + * If another process is swapping in this process, + * just wait until it finishes. + */ + if (p->p_flag & P_SWAPPINGIN) { + while (p->p_flag & P_SWAPPINGIN) + msleep(&p->p_flag, &p->p_mtx, PVM, "faultin", 0); + return; + } + if ((p->p_flag & P_INMEM) == 0) { + /* + * Don't let another thread swap process p out while we are + * busy swapping it in. + */ + ++p->p_lock; + p->p_flag |= P_SWAPPINGIN; + PROC_UNLOCK(p); + + /* + * We hold no lock here because the list of threads + * can not change while all threads in the process are + * swapped out. + */ + FOREACH_THREAD_IN_PROC(p, td) + vm_thread_swapin(td); + PROC_LOCK(p); + swapclear(p); + p->p_swtick = ticks; + + wakeup(&p->p_flag); + + /* Allow other threads to swap p out now. */ + --p->p_lock; + } +} + +/* + * This swapin algorithm attempts to swap-in processes only if there + * is enough space for them. Of course, if a process waits for a long + * time, it will be swapped in anyway. + */ +void +swapper(void) +{ + struct proc *p; + struct thread *td; + struct proc *pp; + int slptime; + int swtime; + int ppri; + int pri; + +loop: + if (vm_page_count_min()) { + VM_WAIT; + goto loop; + } + + pp = NULL; + ppri = INT_MIN; + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + PROC_LOCK(p); + if (p->p_state == PRS_NEW || + p->p_flag & (P_SWAPPINGOUT | P_SWAPPINGIN | P_INMEM)) { + PROC_UNLOCK(p); + continue; + } + swtime = (ticks - p->p_swtick) / hz; + FOREACH_THREAD_IN_PROC(p, td) { + /* + * An otherwise runnable thread of a process + * swapped out has only the TDI_SWAPPED bit set. + */ + thread_lock(td); + if (td->td_inhibitors == TDI_SWAPPED) { + slptime = (ticks - td->td_slptick) / hz; + pri = swtime + slptime; + if ((td->td_flags & TDF_SWAPINREQ) == 0) + pri -= p->p_nice * 8; + /* + * if this thread is higher priority + * and there is enough space, then select + * this process instead of the previous + * selection. + */ + if (pri > ppri) { + pp = p; + ppri = pri; + } + } + thread_unlock(td); + } + PROC_UNLOCK(p); + } + sx_sunlock(&allproc_lock); + + /* + * Nothing to do, back to sleep. + */ + if ((p = pp) == NULL) { + tsleep(&proc0, PVM, "swapin", MAXSLP * hz / 2); + goto loop; + } + PROC_LOCK(p); + + /* + * Another process may be bringing or may have already + * brought this process in while we traverse all threads. + * Or, this process may even be being swapped out again. + */ + if (p->p_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) { + PROC_UNLOCK(p); + goto loop; + } + + /* + * We would like to bring someone in. (only if there is space). + * [What checks the space? ] + */ + faultin(p); + PROC_UNLOCK(p); + goto loop; +} + +/* + * First, if any processes have been sleeping or stopped for at least + * "swap_idle_threshold1" seconds, they are swapped out. If, however, + * no such processes exist, then the longest-sleeping or stopped + * process is swapped out. Finally, and only as a last resort, if + * there are no sleeping or stopped processes, the longest-resident + * process is swapped out. + */ +static void +swapout_procs(int action) +{ + struct proc *p; + struct thread *td; + int didswap = 0; + +retry: + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + struct vmspace *vm; + int minslptime = 100000; + int slptime; + + PROC_LOCK(p); + /* + * Watch out for a process in + * creation. It may have no + * address space or lock yet. + */ + if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); + continue; + } + /* + * An aio daemon switches its + * address space while running. + * Perform a quick check whether + * a process has P_SYSTEM. + * Filter out exiting processes. + */ + if ((p->p_flag & (P_SYSTEM | P_WEXIT)) != 0) { + PROC_UNLOCK(p); + continue; + } + _PHOLD_LITE(p); + PROC_UNLOCK(p); + sx_sunlock(&allproc_lock); + + /* + * Do not swapout a process that + * is waiting for VM data + * structures as there is a possible + * deadlock. Test this first as + * this may block. + * + * Lock the map until swapout + * finishes, or a thread of this + * process may attempt to alter + * the map. + */ + vm = vmspace_acquire_ref(p); + if (vm == NULL) + goto nextproc2; + if (!vm_map_trylock(&vm->vm_map)) + goto nextproc1; + + PROC_LOCK(p); + if (p->p_lock != 1 || (p->p_flag & (P_STOPPED_SINGLE | + P_TRACED | P_SYSTEM)) != 0) + goto nextproc; + + /* + * only aiod changes vmspace, however it will be + * skipped because of the if statement above checking + * for P_SYSTEM + */ + if ((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) != P_INMEM) + goto nextproc; + + switch (p->p_state) { + default: + /* Don't swap out processes in any sort + * of 'special' state. */ + break; + + case PRS_NORMAL: + /* + * do not swapout a realtime process + * Check all the thread groups.. + */ + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + if (PRI_IS_REALTIME(td->td_pri_class)) { + thread_unlock(td); + goto nextproc; + } + slptime = (ticks - td->td_slptick) / hz; + /* + * Guarantee swap_idle_threshold1 + * time in memory. + */ + if (slptime < swap_idle_threshold1) { + thread_unlock(td); + goto nextproc; + } + + /* + * Do not swapout a process if it is + * waiting on a critical event of some + * kind or there is a thread whose + * pageable memory may be accessed. + * + * This could be refined to support + * swapping out a thread. + */ + if (!thread_safetoswapout(td)) { + thread_unlock(td); + goto nextproc; + } + /* + * If the system is under memory stress, + * or if we are swapping + * idle processes >= swap_idle_threshold2, + * then swap the process out. + */ + if (((action & VM_SWAP_NORMAL) == 0) && + (((action & VM_SWAP_IDLE) == 0) || + (slptime < swap_idle_threshold2))) { + thread_unlock(td); + goto nextproc; + } + + if (minslptime > slptime) + minslptime = slptime; + thread_unlock(td); + } + + /* + * If the pageout daemon didn't free enough pages, + * or if this process is idle and the system is + * configured to swap proactively, swap it out. + */ + if ((action & VM_SWAP_NORMAL) || + ((action & VM_SWAP_IDLE) && + (minslptime > swap_idle_threshold2))) { + _PRELE(p); + if (swapout(p) == 0) + didswap++; + PROC_UNLOCK(p); + vm_map_unlock(&vm->vm_map); + vmspace_free(vm); + goto retry; + } + } +nextproc: + PROC_UNLOCK(p); + vm_map_unlock(&vm->vm_map); +nextproc1: + vmspace_free(vm); +nextproc2: + sx_slock(&allproc_lock); + PRELE(p); + } + sx_sunlock(&allproc_lock); + /* + * If we swapped something out, and another process needed memory, + * then wakeup the sched process. + */ + if (didswap) + wakeup(&proc0); +} + +static void +swapclear(struct proc *p) +{ + struct thread *td; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + td->td_flags |= TDF_INMEM; + td->td_flags &= ~TDF_SWAPINREQ; + TD_CLR_SWAPPED(td); + if (TD_CAN_RUN(td)) + if (setrunnable(td)) { +#ifdef INVARIANTS + /* + * XXX: We just cleared TDI_SWAPPED + * above and set TDF_INMEM, so this + * should never happen. + */ + panic("not waking up swapper"); +#endif + } + thread_unlock(td); + } + p->p_flag &= ~(P_SWAPPINGIN | P_SWAPPINGOUT); + p->p_flag |= P_INMEM; +} + +static int +swapout(struct proc *p) +{ + struct thread *td; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + /* + * The states of this process and its threads may have changed + * by now. Assuming that there is only one pageout daemon thread, + * this process should still be in memory. + */ + KASSERT((p->p_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) == + P_INMEM, ("swapout: lost a swapout race?")); + + /* + * remember the process resident count + */ + p->p_vmspace->vm_swrss = vmspace_resident_count(p->p_vmspace); + /* + * Check and mark all threads before we proceed. + */ + p->p_flag &= ~P_INMEM; + p->p_flag |= P_SWAPPINGOUT; + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + if (!thread_safetoswapout(td)) { + thread_unlock(td); + swapclear(p); + return (EBUSY); + } + td->td_flags &= ~TDF_INMEM; + TD_SET_SWAPPED(td); + thread_unlock(td); + } + td = FIRST_THREAD_IN_PROC(p); + ++td->td_ru.ru_nswap; + PROC_UNLOCK(p); + + /* + * This list is stable because all threads are now prevented from + * running. The list is only modified in the context of a running + * thread in this process. + */ + FOREACH_THREAD_IN_PROC(p, td) + vm_thread_swapout(td); + + PROC_LOCK(p); + p->p_flag &= ~P_SWAPPINGOUT; + p->p_swtick = ticks; + return (0); +} diff --git a/sys/vm/vm_swapout_dummy.c b/sys/vm/vm_swapout_dummy.c new file mode 100644 index 000000000000..9cdfcb8ac954 --- /dev/null +++ b/sys/vm/vm_swapout_dummy.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 1991 Regents of the University of California. + * All rights reserved. + * Copyright (c) 1994 John S. Dyson + * All rights reserved. + * Copyright (c) 1994 David Greenman + * All rights reserved. + * Copyright (c) 2005 Yahoo! Technologies Norway AS + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * The Mach Operating System project at Carnegie-Mellon University. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * from: @(#)vm_pageout.c 7.4 (Berkeley) 5/7/91 + * + * + * Copyright (c) 1987, 1990 Carnegie-Mellon University. + * All rights reserved. + * + * Authors: Avadis Tevanian, Jr., Michael Wayne Young + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int vm_swap_enabled = 0; +SYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled, CTLFLAG_RD, + &vm_swap_enabled, 0, + "Enable entire process swapout"); + +static int vm_swap_idle_enabled = 0; +SYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled, CTLFLAG_RD, + &vm_swap_idle_enabled, 0, + "Allow swapout on idle criteria"); + +void +vm_swapout_run(void) +{ +} + +void +vm_swapout_run_idle(void) +{ +} + +void +faultin(struct proc *p) +{ + + PROC_LOCK_ASSERT(p, MA_OWNED); + if ((p->p_flag & P_INMEM) == 0) + panic("faultin: proc %p swapped out with NO_SWAPPING", p); +} + +void +swapper(void) +{ + + for (;;) + tsleep(&proc0, PVM, "swapin", MAXSLP * hz); +} diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index e5bb3c2ff8db..e569503cc74d 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -1179,6 +1179,23 @@ vnode_pager_putpages(vm_object_t object, vm_page_t *m, int count, VM_OBJECT_WLOCK(object); } +static int +vn_off2bidx(vm_ooffset_t offset) +{ + + return ((offset & PAGE_MASK) / DEV_BSIZE); +} + +static bool +vn_dirty_blk(vm_page_t m, vm_ooffset_t offset) +{ + + KASSERT(IDX_TO_OFF(m->pindex) <= offset && + offset < IDX_TO_OFF(m->pindex + 1), + ("page %p pidx %ju offset %ju", m, (uintmax_t)m->pindex, + (uintmax_t)offset)); + return ((m->dirty & ((vm_page_bits_t)1 << vn_off2bidx(offset))) != 0); +} /* * This is now called from local media FS's to operate against their @@ -1195,10 +1212,12 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_page_t *ma, int bytecount, { vm_object_t object; vm_page_t m; - vm_ooffset_t poffset; + vm_ooffset_t maxblksz, next_offset, poffset, prev_offset; struct uio auio; struct iovec aiov; + off_t prev_resid, wrsz; int count, error, i, maxsize, ncount, pgoff, ppscheck; + bool in_hole; static struct timeval lastfail; static int curfail; @@ -1233,8 +1252,14 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_page_t *ma, int bytecount, * We do not under any circumstances truncate the valid bits, as * this will screw up bogus page replacement. */ - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); if (maxsize + poffset > object->un_pager.vnp.vnp_size) { + if (!VM_OBJECT_TRYUPGRADE(object)) { + VM_OBJECT_RUNLOCK(object); + VM_OBJECT_WLOCK(object); + if (maxsize + poffset <= object->un_pager.vnp.vnp_size) + goto downgrade; + } if (object->un_pager.vnp.vnp_size > poffset) { maxsize = object->un_pager.vnp.vnp_size - poffset; ncount = btoc(maxsize); @@ -1259,35 +1284,105 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_page_t *ma, int bytecount, } for (i = ncount; i < count; i++) rtvals[i] = VM_PAGER_BAD; +downgrade: + VM_OBJECT_LOCK_DOWNGRADE(object); } - for (i = 0; i < ncount - ((btoc(maxsize) & PAGE_MASK) != 0); i++) - MPASS(ma[i]->dirty == VM_PAGE_BITS_ALL); - VM_OBJECT_WUNLOCK(object); - aiov.iov_base = NULL; - aiov.iov_len = maxsize; auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = poffset; auio.uio_segflg = UIO_NOCOPY; auio.uio_rw = UIO_WRITE; - auio.uio_resid = maxsize; auio.uio_td = NULL; - error = VOP_WRITE(vp, &auio, vnode_pager_putpages_ioflags(flags), - curthread->td_ucred); - VM_CNT_INC(v_vnodeout); - VM_CNT_ADD(v_vnodepgsout, ncount); + maxblksz = roundup2(poffset + maxsize, DEV_BSIZE); - ppscheck = 0; - if (error != 0 && (ppscheck = ppsratecheck(&lastfail, &curfail, 1)) - != 0) - printf("vnode_pager_putpages: I/O error %d\n", error); - if (auio.uio_resid != 0 && (ppscheck != 0 || - ppsratecheck(&lastfail, &curfail, 1) != 0)) - printf("vnode_pager_putpages: residual I/O %zd at %ju\n", - auio.uio_resid, (uintmax_t)ma[0]->pindex); - for (i = 0; i < ncount; i++) + for (prev_offset = poffset; prev_offset < maxblksz;) { + /* Skip clean blocks. */ + for (in_hole = true; in_hole && prev_offset < maxblksz;) { + m = ma[OFF_TO_IDX(prev_offset - poffset)]; + for (i = vn_off2bidx(prev_offset); + i < sizeof(vm_page_bits_t) * NBBY && + prev_offset < maxblksz; i++) { + if (vn_dirty_blk(m, prev_offset)) { + in_hole = false; + break; + } + prev_offset += DEV_BSIZE; + } + } + if (in_hole) + goto write_done; + + /* Find longest run of dirty blocks. */ + for (next_offset = prev_offset; next_offset < maxblksz;) { + m = ma[OFF_TO_IDX(next_offset - poffset)]; + for (i = vn_off2bidx(next_offset); + i < sizeof(vm_page_bits_t) * NBBY && + next_offset < maxblksz; i++) { + if (!vn_dirty_blk(m, next_offset)) + goto start_write; + next_offset += DEV_BSIZE; + } + } +start_write: + if (next_offset > poffset + maxsize) + next_offset = poffset + maxsize; + + /* + * Getting here requires finding a dirty block in the + * 'skip clean blocks' loop. + */ + MPASS(prev_offset < next_offset); + + VM_OBJECT_RUNLOCK(object); + aiov.iov_base = NULL; + auio.uio_iovcnt = 1; + auio.uio_offset = prev_offset; + prev_resid = auio.uio_resid = aiov.iov_len = next_offset - + prev_offset; + error = VOP_WRITE(vp, &auio, + vnode_pager_putpages_ioflags(flags), curthread->td_ucred); + + wrsz = prev_resid - auio.uio_resid; + if (wrsz == 0) { + if (ppsratecheck(&lastfail, &curfail, 1) != 0) { + vn_printf(vp, "vnode_pager_putpages: " + "zero-length write at %ju resid %zd\n", + auio.uio_offset, auio.uio_resid); + } + VM_OBJECT_RLOCK(object); + break; + } + + /* Adjust the starting offset for next iteration. */ + prev_offset += wrsz; + MPASS(auio.uio_offset == prev_offset); + + ppscheck = 0; + if (error != 0 && (ppscheck = ppsratecheck(&lastfail, + &curfail, 1)) != 0) + vn_printf(vp, "vnode_pager_putpages: I/O error %d\n", + error); + if (auio.uio_resid != 0 && (ppscheck != 0 || + ppsratecheck(&lastfail, &curfail, 1) != 0)) + vn_printf(vp, "vnode_pager_putpages: residual I/O %zd " + "at %ju\n", auio.uio_resid, + (uintmax_t)ma[0]->pindex); + VM_OBJECT_RLOCK(object); + if (error != 0 || auio.uio_resid != 0) + break; + } +write_done: + /* Mark completely processed pages. */ + for (i = 0; i < OFF_TO_IDX(prev_offset - poffset); i++) rtvals[i] = VM_PAGER_OK; + /* Mark partial EOF page. */ + if (prev_offset == poffset + maxsize && (prev_offset & PAGE_MASK) != 0) + rtvals[i++] = VM_PAGER_OK; + /* Unwritten pages in range, free bonus if the page is clean. */ + for (; i < ncount; i++) + rtvals[i] = ma[i]->dirty == 0 ? VM_PAGER_OK : VM_PAGER_ERROR; + VM_OBJECT_RUNLOCK(object); + VM_CNT_ADD(v_vnodepgsout, i); + VM_CNT_INC(v_vnodeout); return (rtvals[0]); } diff --git a/sys/x86/include/elf.h b/sys/x86/include/elf.h index cde395b30bfe..6273360d7d0e 100644 --- a/sys/x86/include/elf.h +++ b/sys/x86/include/elf.h @@ -100,8 +100,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* * Relocation types. @@ -185,8 +188,11 @@ __ElfType(Auxinfo); #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ +#define AT_HWCAP2 26 /* CPU feature flags 2. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 27 /* Count of defined aux entry types. */ /* * Relocation types. diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h index cb65df8b6fb3..d327d1112f66 100644 --- a/sys/x86/include/specialreg.h +++ b/sys/x86/include/specialreg.h @@ -330,6 +330,13 @@ #define AMDPM_TSC_INVARIANT 0x00000100 #define AMDPM_CPB 0x00000200 +/* + * AMD extended function 8000_0008h ebx info (amd_extended_feature_extensions) + */ +#define AMDFEID_CLZERO 0x00000001 +#define AMDFEID_IRPERF 0x00000002 +#define AMDFEID_XSAVEERPTR 0x00000004 + /* * AMD extended function 8000_0008h ecx info */ diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index 3ed5007fd9ca..57716869584c 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -46,6 +46,7 @@ extern u_int amd_feature; extern u_int amd_feature2; extern u_int amd_rascap; extern u_int amd_pminfo; +extern u_int amd_extended_feature_extensions; extern u_int via_feature_rng; extern u_int via_feature_xcrypt; extern u_int cpu_clflush_line_size; diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c index 82051340daf0..6a29ce26528f 100644 --- a/sys/x86/x86/identcpu.c +++ b/sys/x86/x86/identcpu.c @@ -93,6 +93,7 @@ u_int amd_feature; /* AMD feature flags */ u_int amd_feature2; /* AMD feature flags */ u_int amd_rascap; /* AMD RAS capabilities */ u_int amd_pminfo; /* AMD advanced power management info */ +u_int amd_extended_feature_extensions; u_int via_feature_rng; /* VIA RNG features */ u_int via_feature_xcrypt; /* VIA ACE features */ u_int cpu_high; /* Highest arg to CPUID */ @@ -992,6 +993,16 @@ printcpuinfo(void) } } + if (amd_extended_feature_extensions != 0) { + printf("\n " + "AMD Extended Feature Extensions ID EBX=" + "0x%b", amd_extended_feature_extensions, + "\020" + "\001CLZERO" + "\002IRPerf" + "\003XSaveErPtr"); + } + if (via_feature_rng != 0 || via_feature_xcrypt != 0) print_via_padlock_info(); @@ -1468,6 +1479,7 @@ finishidentcpu(void) if (cpu_exthigh >= 0x80000008) { do_cpuid(0x80000008, regs); cpu_maxphyaddr = regs[0] & 0xff; + amd_extended_feature_extensions = regs[1]; cpu_procinfo2 = regs[2]; } else { cpu_maxphyaddr = (cpu_feature & CPUID_PAE) != 0 ? 36 : 32; diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index e63e64ce2ce8..a75ac7490713 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -1426,8 +1426,9 @@ native_lapic_enable_mca_elvt(void) value = lapic_read32(LAPIC_EXT_LVT0 + APIC_ELVT_MCA); if ((value & APIC_LVT_M) == 0) { - printf("AMD MCE Thresholding Extended LVT is already active\n"); - return (-1); + if (bootverbose) + printf("AMD MCE Thresholding Extended LVT is already active\n"); + return (APIC_ELVT_MCA); } lapics[apic_id].la_elvts[APIC_ELVT_MCA].lvt_masked = 0; lapics[apic_id].la_elvts[APIC_ELVT_MCA].lvt_active = 1; diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c index 7fbaeb056477..c217c88780a7 100644 --- a/sys/x86/x86/mca.c +++ b/sys/x86/x86/mca.c @@ -124,7 +124,7 @@ static struct mtx mca_lock; #ifdef DEV_APIC static struct cmc_state **cmc_state; /* Indexed by cpuid, bank. */ -static struct amd_et_state *amd_et_state; /* Indexed by cpuid. */ +static struct amd_et_state **amd_et_state; /* Indexed by cpuid, bank. */ static int cmc_throttle = 60; /* Time in seconds to throttle CMCI. */ static int amd_elvt = -1; @@ -645,9 +645,7 @@ amd_thresholding_update(enum scan_mode mode, int bank, int valid) int new_threshold; int count; - KASSERT(bank == MC_AMDNB_BANK, - ("%s: unexpected bank %d", __func__, bank)); - cc = &amd_et_state[PCPU_GET(cpuid)]; + cc = &amd_et_state[PCPU_GET(cpuid)][bank]; misc = rdmsr(MSR_MC_MISC(bank)); count = (misc & MC_MISC_AMD_CNT_MASK) >> MC_MISC_AMD_CNT_SHIFT; count = count - (MC_MISC_AMD_CNT_MAX - cc->cur_threshold); @@ -841,9 +839,13 @@ cmci_setup(void) static void amd_thresholding_setup(void) { + int i; - amd_et_state = malloc((mp_maxid + 1) * sizeof(struct amd_et_state), - M_MCA, M_WAITOK | M_ZERO); + amd_et_state = malloc((mp_maxid + 1) * sizeof(struct amd_et_state *), + M_MCA, M_WAITOK); + for (i = 0; i <= mp_maxid; i++) + amd_et_state[i] = malloc(sizeof(struct amd_et_state) * + mca_banks, M_MCA, M_WAITOK | M_ZERO); SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "cmc_throttle", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &cmc_throttle, 0, sysctl_positive_int, "I", @@ -964,44 +966,59 @@ cmci_resume(int i) wrmsr(MSR_MC_CTL2(i), ctl); } +/* + * Apply an AMD ET configuration to the corresponding MSR. + */ static void -amd_thresholding_start(struct amd_et_state *cc) +amd_thresholding_start(struct amd_et_state *cc, int bank) { uint64_t misc; KASSERT(amd_elvt >= 0, ("ELVT offset is not set")); - misc = rdmsr(MSR_MC_MISC(MC_AMDNB_BANK)); + + misc = rdmsr(MSR_MC_MISC(bank)); + misc &= ~MC_MISC_AMD_INT_MASK; misc |= MC_MISC_AMD_INT_LVT; + misc &= ~MC_MISC_AMD_LVT_MASK; misc |= (uint64_t)amd_elvt << MC_MISC_AMD_LVT_SHIFT; + misc &= ~MC_MISC_AMD_CNT_MASK; misc |= (uint64_t)(MC_MISC_AMD_CNT_MAX - cc->cur_threshold) << MC_MISC_AMD_CNT_SHIFT; + misc &= ~MC_MISC_AMD_OVERFLOW; misc |= MC_MISC_AMD_CNTEN; - wrmsr(MSR_MC_MISC(MC_AMDNB_BANK), misc); + wrmsr(MSR_MC_MISC(bank), misc); } static void -amd_thresholding_init(void) +amd_thresholding_monitor(int i) { struct amd_et_state *cc; uint64_t misc; - /* The counter must be valid and present. */ - misc = rdmsr(MSR_MC_MISC(MC_AMDNB_BANK)); - if ((misc & (MC_MISC_AMD_VAL | MC_MISC_AMD_CNTP)) != - (MC_MISC_AMD_VAL | MC_MISC_AMD_CNTP)) { - printf("%s: 0x%jx: !valid | !present\n", __func__, - (uintmax_t)misc); + /* + * Kludge: On 10h, banks after 4 are not thresholding but also may have + * bogus Valid bits. Skip them. This is definitely fixed in 15h, but + * I have not investigated whether it is fixed in earlier models. + */ + if (CPUID_TO_FAMILY(cpu_id) < 0x15 && i >= 5) + return; + + /* The counter must be valid and present. */ + misc = rdmsr(MSR_MC_MISC(i)); + if ((misc & (MC_MISC_AMD_VAL | MC_MISC_AMD_CNTP)) != + (MC_MISC_AMD_VAL | MC_MISC_AMD_CNTP)) return; - } /* The register should not be locked. */ if ((misc & MC_MISC_AMD_LOCK) != 0) { - printf("%s: 0x%jx: locked\n", __func__, (uintmax_t)misc); + if (bootverbose) + printf("%s: 0x%jx: Bank %d: locked\n", __func__, + (uintmax_t)misc, i); return; } @@ -1010,8 +1027,9 @@ amd_thresholding_init(void) * has already claimed it. */ if ((misc & MC_MISC_AMD_CNTEN) != 0) { - printf("%s: 0x%jx: count already enabled\n", __func__, - (uintmax_t)misc); + if (bootverbose) + printf("%s: 0x%jx: Bank %d: already enabled\n", + __func__, (uintmax_t)misc, i); return; } @@ -1022,35 +1040,39 @@ amd_thresholding_init(void) */ amd_elvt = lapic_enable_mca_elvt(); if (amd_elvt < 0) { - printf("%s: lapic enable mca elvt failed: %d\n", __func__, amd_elvt); + printf("%s: Bank %d: lapic enable mca elvt failed: %d\n", + __func__, i, amd_elvt); return; } /* Re-use Intel CMC support infrastructure. */ if (bootverbose) - printf("%s: Starting AMD thresholding\n", __func__); + printf("%s: Starting AMD thresholding on bank %d\n", __func__, + i); - cc = &amd_et_state[PCPU_GET(cpuid)]; + cc = &amd_et_state[PCPU_GET(cpuid)][i]; cc->cur_threshold = 1; - amd_thresholding_start(cc); + amd_thresholding_start(cc, i); - /* Mark the NB bank as monitored. */ - PCPU_SET(cmci_mask, PCPU_GET(cmci_mask) | 1 << MC_AMDNB_BANK); + /* Mark this bank as monitored. */ + PCPU_SET(cmci_mask, PCPU_GET(cmci_mask) | 1 << i); } static void -amd_thresholding_resume(void) +amd_thresholding_resume(int i) { struct amd_et_state *cc; - /* Nothing to do if this CPU doesn't monitor the NB bank. */ - if ((PCPU_GET(cmci_mask) & 1 << MC_AMDNB_BANK) == 0) + KASSERT(i < mca_banks, ("CPU %d has more MC banks", PCPU_GET(cpuid))); + + /* Ignore banks not monitored by this CPU. */ + if (!(PCPU_GET(cmci_mask) & 1 << i)) return; - cc = &amd_et_state[PCPU_GET(cpuid)]; + cc = &amd_et_state[PCPU_GET(cpuid)][i]; cc->last_intr = 0; cc->cur_threshold = 1; - amd_thresholding_start(cc); + amd_thresholding_start(cc, i); } #endif @@ -1063,7 +1085,9 @@ _mca_init(int boot) { uint64_t mcg_cap; uint64_t ctl, mask; - int i, skip; + int i, skip, family; + + family = CPUID_TO_FAMILY(cpu_id); /* MCE is required. */ if (!mca_enabled || !(cpu_feature & CPUID_MCE)) @@ -1087,8 +1111,8 @@ _mca_init(int boot) * is no performance penalty to this workaround. However, * L1TP errors will go unreported. */ - if (cpu_vendor_id == CPU_VENDOR_AMD && - CPUID_TO_FAMILY(cpu_id) == 0x10 && !amd10h_L1TP) { + if (cpu_vendor_id == CPU_VENDOR_AMD && family == 0x10 && + !amd10h_L1TP) { mask = rdmsr(MSR_MC0_CTL_MASK); if ((mask & (1UL << 5)) == 0) wrmsr(MSR_MC0_CTL_MASK, mask | (1UL << 5)); @@ -1103,12 +1127,12 @@ _mca_init(int boot) * For P6 models before Nehalem MC0_CTL is * always enabled and reserved. */ - if (i == 0 && CPUID_TO_FAMILY(cpu_id) == 0x6 + if (i == 0 && family == 0x6 && CPUID_TO_MODEL(cpu_id) < 0x1a) skip = 1; } else if (cpu_vendor_id == CPU_VENDOR_AMD) { /* BKDG for Family 10h: unset GartTblWkEn. */ - if (i == 4 && CPUID_TO_FAMILY(cpu_id) >= 0xf) + if (i == MC_AMDNB_BANK && family >= 0xf) ctl &= ~(1UL << 10); } @@ -1121,6 +1145,11 @@ _mca_init(int boot) cmci_monitor(i); else cmci_resume(i); + } else if (amd_thresholding_supported()) { + if (boot) + amd_thresholding_monitor(i); + else + amd_thresholding_resume(i); } #endif @@ -1129,26 +1158,9 @@ _mca_init(int boot) } #ifdef DEV_APIC - /* - * AMD Processors from families 10h - 16h provide support - * for Machine Check Error Thresholding. - * The processors support counters of MC errors and they - * can be configured to generate an interrupt when a counter - * overflows. - * The counters are all associated with Bank 4 and each - * of them covers a group of errors reported via that bank. - * At the moment only the DRAM Error Threshold Group is - * supported. - */ - if (amd_thresholding_supported() && - (mcg_cap & MCG_CAP_COUNT) >= 4) { - if (boot) - amd_thresholding_init(); - else - amd_thresholding_resume(); - } else if (PCPU_GET(cmci_mask) != 0 && boot) { + if (!amd_thresholding_supported() && + PCPU_GET(cmci_mask) != 0 && boot) lapic_enable_cmc(); - } #endif } diff --git a/targets/pseudo/bootstrap-tools/Makefile b/targets/pseudo/bootstrap-tools/Makefile index 9b0f524f0c63..525320702a41 100644 --- a/targets/pseudo/bootstrap-tools/Makefile +++ b/targets/pseudo/bootstrap-tools/Makefile @@ -13,10 +13,10 @@ TARGET_MACHINE= host HOST_MACHINE!= uname -m HOST_MACHINE_ARCH!= uname -p BTOOLSDIR?= ${HOST_OBJTOP}/tools +WORLDTMP= ${BTOOLSDIR} LEGACY_TOOLS?= ${BTOOLSDIR}/legacy BSENV= \ - unset MAKEOBJDIR; MAKEOBJDIRPREFIX=${BTOOLSDIR} \ MAKESYSPATH=${SRCTOP}/tools/build/mk:${SRCTOP}/share/mk \ TARGET=${HOST_MACHINE} TARGET_ARCH=${HOST_MACHINE_ARCH} \ WITHOUT_STAGING=1 STAGE_ROOT= BOOTSTRAPPING_TOOLS=1 \ @@ -34,6 +34,9 @@ OSRELDATE?= 0 # need to keep this in sync with src/Makefile.inc1 BSARGS= DESTDIR= \ + OBJTOP='${WORLDTMP}/obj-tools' \ + OBJROOT='$${OBJTOP}/' \ + MAKEOBJDIRPREFIX= \ BOOTSTRAPPING=${OSRELDATE} \ BWPHASE=${.TARGET} \ SSP_CFLAGS= \ @@ -44,8 +47,6 @@ BSARGS= DESTDIR= \ MK_LLDB=no MK_TESTS=no \ MK_INCLUDES=yes -# Need to override these so OBJTOP uses are proper in the non-meta build. -BSARGS+= OBJTOP=${BTOOLSDIR}${SRCTOP} OBJROOT='$${OBJTOP}/' # We will handle building the toolchain and cross-compiler. BSARGS+= MK_CROSS_COMPILER=no MK_CLANG=no MK_GCC=no @@ -86,7 +87,7 @@ BSTCARGS= \ # finally we build toolchain leveraging the above. bootstrap-toolchain: .MAKE cross-tools - ${BSTCENV} ${MAKE} -C ${.CURDIR:H:H} ${BSTCARGS} toolchain + ${BSTCENV} ${MAKE} -C ${SRCTOP} ${BSTCARGS} toolchain # Ensure CCACHE_DIR is ignored since we are processing .meta files here. .include diff --git a/targets/pseudo/clang/Makefile.depend b/targets/pseudo/clang/Makefile.depend index 97dcb727d68e..7065a2adc043 100644 --- a/targets/pseudo/clang/Makefile.depend +++ b/targets/pseudo/clang/Makefile.depend @@ -12,6 +12,28 @@ DIRDEPS = \ usr.bin/clang/llvm-objdump \ usr.bin/clang/llvm-tblgen \ +.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" +DIRDEPS+= \ + lib/libclang_rt/include \ + lib/libclang_rt/asan \ + lib/libclang_rt/asan-preinit \ + lib/libclang_rt/asan_dynamic \ + lib/libclang_rt/asan_cxx \ + lib/libclang_rt/safestack \ + lib/libclang_rt/stats \ + lib/libclang_rt/stats_client \ + lib/libclang_rt/ubsan_standalone \ + lib/libclang_rt/ubsan_standalone_cxx \ + +.endif + +.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" || \ + (${MACHINE_CPUARCH} == "arm" && ${MACHINE_ARCH} != "armeb") +DIRDEPS+= \ + lib/libclang_rt/profile \ + +.endif + .if ${MK_LLDB} == "yes" DIRDEPS+= \ usr.bin/clang/lldb @@ -40,6 +62,7 @@ DIRDEPS+= \ usr.bin/clang/llvm-modextract \ usr.bin/clang/llvm-nm \ usr.bin/clang/llvm-pdbdump \ + usr.bin/clang/llvm-pdbutil \ usr.bin/clang/llvm-profdata \ usr.bin/clang/llvm-rtdyld \ usr.bin/clang/llvm-symbolizer \ diff --git a/targets/pseudo/tests/Makefile.depend b/targets/pseudo/tests/Makefile.depend index a89f6de8f53a..937b3d79f149 100644 --- a/targets/pseudo/tests/Makefile.depend +++ b/targets/pseudo/tests/Makefile.depend @@ -7,6 +7,7 @@ # find . -name Makefile -exec grep -l '^\.include.*\.test.mk' {} + | grep -v '^\./contrib' | sed -e 's,/Makefile,,' -e 's,^\./,,' -e 's,^, ,' -e 's,$, \\,' | sort DIRDEPS= \ bin/cat/tests \ + bin/chflags/tests \ bin/chmod/tests \ bin/date/tests \ bin/dd/tests \ @@ -14,15 +15,18 @@ DIRDEPS= \ bin/expr/tests \ bin/ln/tests \ bin/ls/tests \ + bin/mkdir/tests \ bin/mv/tests \ bin/pax/tests \ bin/pkill/tests \ bin/pwait/tests \ + bin/rmdir/tests \ bin/sh/tests \ bin/sh/tests/builtins \ bin/sh/tests/errors \ bin/sh/tests/execution \ bin/sh/tests/expansion \ + bin/sh/tests/invocation \ bin/sh/tests/parameters \ bin/sh/tests/parser \ bin/sh/tests/set-e \ @@ -152,20 +156,20 @@ DIRDEPS= \ lib/libc/tests/string \ lib/libc/tests/sys \ lib/libc/tests/termios \ - lib/libc/tests/time \ lib/libc/tests/tls \ + lib/libc/tests/tls/dso \ + lib/libc/tests/tls_dso \ lib/libc/tests/ttyio \ lib/libcam/tests \ lib/libcasper/services/cap_dns/tests \ lib/libcasper/services/cap_grp/tests \ lib/libcasper/services/cap_pwd/tests \ lib/libcasper/services/cap_sysctl/tests \ + lib/libcasper/services/tests \ lib/libcrypt/tests \ - lib/libdevdctl/tests \ lib/libkvm/tests \ lib/libmp/tests \ lib/libnv/tests \ - lib/libpathconv/tests \ lib/libproc/tests \ lib/librt/tests \ lib/libsbuf/tests \ @@ -175,6 +179,7 @@ DIRDEPS= \ lib/libthread_db/tests \ lib/libutil/tests \ lib/libxo/tests \ + lib/libxo/tests/encoder \ lib/msun/tests \ lib/tests \ libexec/atf/atf-check/tests \ @@ -188,6 +193,7 @@ DIRDEPS= \ sbin/ifconfig/tests \ sbin/mdconfig/tests \ sbin/pfctl/tests \ + sbin/pfctl/tests/files \ sbin/savecore/tests \ sbin/tests \ secure/lib/tests \ @@ -234,6 +240,8 @@ DIRDEPS= \ tests/sys/mac/portacl \ tests/sys/mqueue \ tests/sys/netinet \ + tests/sys/netpfil \ + tests/sys/netpfil/pf \ tests/sys/opencrypto \ tests/sys/pjdfstest/tests \ tests/sys/pjdfstest/tests/chflags \ diff --git a/targets/pseudo/the-lot/Makefile.depend b/targets/pseudo/the-lot/Makefile.depend index 9909bfa46e2c..6903eab45d38 100644 --- a/targets/pseudo/the-lot/Makefile.depend +++ b/targets/pseudo/the-lot/Makefile.depend @@ -10,7 +10,7 @@ DIRDEPS = \ targets/pseudo/userland \ .if ${MK_TESTS} != "no" -DIRDEPS+= targes/pseudo/tests +DIRDEPS+= targets/pseudo/tests .endif .include diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 4fc4b07daa63..73d46e2759fb 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -100,11 +100,9 @@ DIRDEPS+= \ sbin/ipf/ipf \ sbin/ipf/ipfs \ sbin/ipf/ipfstat \ - sbin/ipf/ipftest \ sbin/ipf/ipmon \ sbin/ipf/ipnat \ sbin/ipf/ippool \ - sbin/ipf/ipresend \ sbin/ipf/libipf \ sbin/ipfw \ sbin/iscontrol \ @@ -199,7 +197,6 @@ DIRDEPS+= \ usr.bin/cpio \ usr.bin/cpuset \ usr.bin/csplit \ - usr.bin/csup \ usr.bin/ctags \ usr.bin/ctlstat \ usr.bin/cut \ @@ -708,7 +705,6 @@ DIRDEPS+= \ usr.sbin/pppctl \ usr.sbin/praliases \ usr.sbin/praudit \ - usr.sbin/procctl \ usr.sbin/prometheus_sysctl_exporter \ usr.sbin/pstat \ usr.sbin/pw \ diff --git a/targets/pseudo/userland/cddl/Makefile.depend b/targets/pseudo/userland/cddl/Makefile.depend index 5b4f1a697bc9..b24b1bbf63d5 100644 --- a/targets/pseudo/userland/cddl/Makefile.depend +++ b/targets/pseudo/userland/cddl/Makefile.depend @@ -7,6 +7,7 @@ .endif DIRDEPS = \ + lib/libprocstat/zfs \ cddl/lib/drti \ cddl/lib/libavl \ cddl/lib/libctf \ diff --git a/targets/pseudo/userland/gnu/Makefile.depend b/targets/pseudo/userland/gnu/Makefile.depend index cb9bda628cfc..e42e2d628b32 100644 --- a/targets/pseudo/userland/gnu/Makefile.depend +++ b/targets/pseudo/userland/gnu/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ gnu/lib/libgcov \ gnu/lib/libgomp \ gnu/lib/libreadline/history/doc \ @@ -28,10 +27,7 @@ DIRDEPS = \ gnu/usr.bin/binutils/libiberty \ gnu/usr.bin/binutils/libopcodes \ gnu/usr.bin/binutils/objdump \ - gnu/usr.bin/binutils/ranlib \ gnu/usr.bin/dialog \ - gnu/usr.bin/diff \ - gnu/usr.bin/diff/doc \ gnu/usr.bin/diff3 \ gnu/usr.bin/gdb/doc \ gnu/usr.bin/gdb/gdb \ @@ -43,76 +39,12 @@ DIRDEPS = \ gnu/usr.bin/gperf/doc \ gnu/usr.bin/grep \ gnu/usr.bin/grep/doc \ - gnu/usr.bin/groff/contrib/mm \ - gnu/usr.bin/groff/doc \ - gnu/usr.bin/groff/font/devX100 \ - gnu/usr.bin/groff/font/devX100-12 \ - gnu/usr.bin/groff/font/devX75 \ - gnu/usr.bin/groff/font/devX75-12 \ - gnu/usr.bin/groff/font/devascii \ - gnu/usr.bin/groff/font/devcp1047 \ - gnu/usr.bin/groff/font/devdvi \ - gnu/usr.bin/groff/font/devhtml \ - gnu/usr.bin/groff/font/devkoi8-r \ - gnu/usr.bin/groff/font/devlatin1 \ - gnu/usr.bin/groff/font/devlbp \ - gnu/usr.bin/groff/font/devlj4 \ - gnu/usr.bin/groff/font/devps \ - gnu/usr.bin/groff/font/devutf8 \ - gnu/usr.bin/groff/man \ - gnu/usr.bin/groff/src/devices/grodvi \ - gnu/usr.bin/groff/src/devices/grohtml \ - gnu/usr.bin/groff/src/devices/grolbp \ - gnu/usr.bin/groff/src/devices/grolj4 \ - gnu/usr.bin/groff/src/devices/grops \ - gnu/usr.bin/groff/src/devices/grotty \ - gnu/usr.bin/groff/src/libs/libbib \ - gnu/usr.bin/groff/src/libs/libdriver \ - gnu/usr.bin/groff/src/libs/libgroff \ - gnu/usr.bin/groff/src/preproc/eqn \ - gnu/usr.bin/groff/src/preproc/grn \ - gnu/usr.bin/groff/src/preproc/html \ - gnu/usr.bin/groff/src/preproc/pic \ - gnu/usr.bin/groff/src/preproc/refer \ - gnu/usr.bin/groff/src/preproc/soelim \ - gnu/usr.bin/groff/src/preproc/tbl \ - gnu/usr.bin/groff/src/roff/groff \ - gnu/usr.bin/groff/src/roff/grog \ - gnu/usr.bin/groff/src/roff/nroff \ - gnu/usr.bin/groff/src/roff/psroff \ - gnu/usr.bin/groff/src/roff/troff \ - gnu/usr.bin/groff/src/utils/addftinfo \ - gnu/usr.bin/groff/src/utils/afmtodit \ - gnu/usr.bin/groff/src/utils/hpftodit \ - gnu/usr.bin/groff/src/utils/indxbib \ - gnu/usr.bin/groff/src/utils/lkbib \ - gnu/usr.bin/groff/src/utils/lookbib \ - gnu/usr.bin/groff/src/utils/pfbtops \ - gnu/usr.bin/groff/src/utils/tfmtodit \ - gnu/usr.bin/groff/tmac \ - gnu/usr.bin/rcs/ci \ - gnu/usr.bin/rcs/co \ - gnu/usr.bin/rcs/ident \ - gnu/usr.bin/rcs/lib \ - gnu/usr.bin/rcs/merge \ - gnu/usr.bin/rcs/rcs \ - gnu/usr.bin/rcs/rcsclean \ - gnu/usr.bin/rcs/rcsdiff \ - gnu/usr.bin/rcs/rcsfreeze \ - gnu/usr.bin/rcs/rcsmerge \ - gnu/usr.bin/rcs/rlog \ - gnu/usr.bin/sdiff \ - gnu/usr.bin/send-pr/doc \ - gnu/usr.bin/texinfo/doc \ - gnu/usr.bin/texinfo/info \ - gnu/usr.bin/texinfo/infokey \ - gnu/usr.bin/texinfo/install-info \ - gnu/usr.bin/texinfo/libtxi \ - gnu/usr.bin/texinfo/makeinfo \ - gnu/usr.bin/texinfo/texindex \ .if ${MK_GPL_DTC} != "no" DIRDEPS+= gnu/usr.bin/dtc .endif +.if ${MK_LLVM_LIBUNWIND} == "no" +.endif + .include diff --git a/targets/pseudo/userland/lib/Makefile.depend b/targets/pseudo/userland/lib/Makefile.depend index 2735e3b8ca15..c9a880aec3aa 100644 --- a/targets/pseudo/userland/lib/Makefile.depend +++ b/targets/pseudo/userland/lib/Makefile.depend @@ -122,10 +122,10 @@ DIRDEPS = \ lib/libpam/modules/pam_tacplus \ lib/libpam/modules/pam_unix \ lib/libpam/static_libpam \ + lib/libpathconv \ lib/libpcap \ lib/libpe \ lib/libpjdlog \ - lib/libpmc \ lib/libproc \ lib/libprocstat \ lib/libradius \ @@ -134,13 +134,14 @@ DIRDEPS = \ lib/librss \ lib/librt \ lib/librtld_db \ + lib/libsa \ lib/libsbuf \ lib/libsdp \ lib/libsm \ lib/libsmb \ lib/libsmdb \ lib/libsmutil \ - lib/libstand \ + lib/libsqlite3 \ lib/libstdbuf \ lib/libstdthreads \ lib/libsysdecode \ @@ -193,6 +194,11 @@ DIRDEPS+= \ .endif +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ + ${MACHINE_CPUARCH} == "powerpc" +DIRDEPS+= sys/boot/libsa32 +.endif + .if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mfilter} DIRDEPS+= lib/libdl .endif @@ -224,6 +230,18 @@ DIRDEPS+= lib/libgpio DIRDEPS+= lib/libefivar .endif +.if ${MK_LLVM_LIBUNWIND} != "no" +DIRDEPS+= \ + lib/libgcc_eh \ + lib/libgcc_s +.endif + +.if ${MK_PMC} != "no" +DIRDEPS+= \ + lib/libpmc \ + lib/libpmcstat +.endif + .if ${MK_OFED} != "no" DIRDEPS+= \ contrib/ofed/usr.lib/libcxgb4 \ diff --git a/targets/pseudo/userland/misc/Makefile.depend b/targets/pseudo/userland/misc/Makefile.depend index e721efedb42d..6d473ea1f88c 100644 --- a/targets/pseudo/userland/misc/Makefile.depend +++ b/targets/pseudo/userland/misc/Makefile.depend @@ -42,14 +42,13 @@ DIRDEPS.x86sys= \ sys/boot/i386/btx/lib \ sys/boot/i386/cdboot \ sys/boot/i386/gptboot \ - sys/boot/i386/kgzldr \ sys/boot/i386/libfirewire \ sys/boot/i386/libi386 \ sys/boot/i386/loader \ sys/boot/i386/mbr \ sys/boot/i386/pmbr \ sys/boot/i386/pxeldr \ - sys/boot/libstand32 \ + sys/boot/libsa32 \ ${_sys_boot_zfs} \ .if ${MK_ZFS} != "no" @@ -67,14 +66,12 @@ DIRDEPS.amd64= \ ${DIRDEPS.x86sys} \ ${_sys_boot_efi} \ sys/boot/ficl32 \ - sys/boot/userboot/ficl \ - sys/boot/userboot/libstand \ sys/boot/userboot/test \ sys/boot/userboot/userboot \ .if ${MK_ZFS} != "no" DIRDEPS.amd64+= \ - sys/boot/userboot/zfs \ + sys/boot/zfs32 \ .endif @@ -86,8 +83,8 @@ DIRDEPS+= \ DIRDEPS.arm= ${_sys_boot_fdt} ${_sys_boot_efi} DIRDEPS.arm64= ${_sys_boot_fdt} ${_sys_boot_efi} -DIRDEPS.i386= ${DIRDEPS.x86sys} ${_sys_boot_efi} -DIRDEPS.powerpc= ${_sys_boot_fdt} sys/boot/libstand32 sys/boot/ofw sys/boot/uboot +DIRDEPS.i386= ${DIRDEPS.x86sys} ${_sys_boot_efi} sys/boot/i386/kgzldr +DIRDEPS.powerpc= ${_sys_boot_fdt} sys/boot/libsa32 sys/boot/ofw sys/boot/uboot DIRDEPS.sparc64= sys/boot/ofw ${_sys_boot_zfs} .endif diff --git a/targets/pseudo/userland/share/Makefile.depend b/targets/pseudo/userland/share/Makefile.depend index 5465f31daa01..3bac4b78d4a8 100644 --- a/targets/pseudo/userland/share/Makefile.depend +++ b/targets/pseudo/userland/share/Makefile.depend @@ -91,6 +91,7 @@ DIRDEPS = \ share/xml/atf \ share/xsl/atf \ share/zoneinfo \ + sys/boot/man \ .include diff --git a/tests/sys/Makefile b/tests/sys/Makefile index 1bcd76ec2649..9c053d94ac76 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -13,6 +13,7 @@ TESTS_SUBDIRS+= kqueue TESTS_SUBDIRS+= mac TESTS_SUBDIRS+= mqueue TESTS_SUBDIRS+= netinet +TESTS_SUBDIRS+= netpfil TESTS_SUBDIRS+= opencrypto TESTS_SUBDIRS+= posixshm TESTS_SUBDIRS+= sys diff --git a/tests/sys/aio/Makefile.depend b/tests/sys/aio/Makefile.depend index 5915a38b10f4..53bbf5dedee7 100644 --- a/tests/sys/aio/Makefile.depend +++ b/tests/sys/aio/Makefile.depend @@ -3,13 +3,14 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ lib/atf/libatf-c \ lib/libc \ lib/libcompiler_rt \ + lib/librt \ + lib/libthr \ lib/libutil \ diff --git a/tests/sys/fifo/Makefile.depend b/tests/sys/fifo/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/tests/sys/fifo/Makefile.depend +++ b/tests/sys/fifo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/file/Makefile.depend b/tests/sys/file/Makefile.depend index 1c2cb193ad93..31e8adb0b2f9 100644 --- a/tests/sys/file/Makefile.depend +++ b/tests/sys/file/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/fs/Makefile.depend b/tests/sys/fs/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/tests/sys/fs/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/rcp/Makefile.depend b/tests/sys/fs/tmpfs/Makefile.depend similarity index 93% rename from bin/rcp/Makefile.depend rename to tests/sys/fs/tmpfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/bin/rcp/Makefile.depend +++ b/tests/sys/fs/tmpfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/geom/class/eli/Makefile.depend b/tests/sys/geom/class/eli/Makefile.depend index f80275d86ab1..bf15a3771e71 100644 --- a/tests/sys/geom/class/eli/Makefile.depend +++ b/tests/sys/geom/class/eli/Makefile.depend @@ -2,6 +2,14 @@ # Autogenerated - do NOT edit! DIRDEPS = \ + gnu/lib/csu \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/atf/libatf-c \ + lib/libc \ + lib/libcompiler_rt \ + secure/lib/libcrypto \ .include diff --git a/tests/sys/geom/class/eli/resize_test.sh b/tests/sys/geom/class/eli/resize_test.sh index 7a7cf635837b..ef40ee59b0c7 100644 --- a/tests/sys/geom/class/eli/resize_test.sh +++ b/tests/sys/geom/class/eli/resize_test.sh @@ -12,6 +12,19 @@ md=$(mdconfig -s40m) || exit 1 unit=${md#md} i=1 +fsck_md() +{ + local is_clean + + out=$(fsck_ffs -Ffy ${md}a.eli) + if [ $? -eq 0 -o $? -eq 7 ]; then + echo "ok $i - fsck says ${md}a.eli is clean" + else + echo "not ok $i - fsck says ${md}a.eli is dirty" + fi + i=$((i + 1)) +} + setsize() { partszMB=$1 unitszMB=$2 @@ -38,12 +51,7 @@ i=$((i + 1)) newfs -U ${md}a.eli >/dev/null || echo -n "not " echo ok $i - "Initialised the filesystem on ${md}a.eli" i=$((i + 1)) -out=$(fsck -tufs -y ${md}a.eli) -echo "$out" | fgrep -q MODIFIED && echo -n "not " -echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \ - "lines of output" -i=$((i + 1)) - +fsck_md # Doing a backup, resize & restore must be forced (with -f) as geli # verifies that the provider size in the metadata matches the consumer. @@ -78,12 +86,7 @@ growfs -y ${md}a.eli >/dev/null || echo -n "not " echo ok $i - "Extended the filesystem on ${md}a.eli" i=$((i + 1)) -out=$(fsck -tufs -y ${md}a.eli) -echo "$out" | fgrep -q MODIFIED && echo -n "not " -echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \ - "lines of output" -i=$((i + 1)) - +fsck_md # Now do the resize properly @@ -110,11 +113,7 @@ growfs -y ${md}a.eli >/dev/null || echo -n "not " echo ok $i - "Extended the filesystem on ${md}a.eli" i=$((i + 1)) -out=$(fsck -tufs -y ${md}a.eli) -echo "$out" | fgrep -q MODIFIED && echo -n "not " -echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \ - "lines of output" -i=$((i + 1)) +fsck_md geli detach ${md}a.eli gpart destroy -F $md >/dev/null diff --git a/tests/sys/kern/Makefile.depend b/tests/sys/kern/Makefile.depend index e2d637cb0fc5..779c178f27a0 100644 --- a/tests/sys/kern/Makefile.depend +++ b/tests/sys/kern/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/kern/acct/Makefile.depend b/tests/sys/kern/acct/Makefile.depend index 1e94e70f7739..6dadc2e21434 100644 --- a/tests/sys/kern/acct/Makefile.depend +++ b/tests/sys/kern/acct/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/kern/execve/Makefile.depend b/tests/sys/kern/execve/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/tests/sys/kern/execve/Makefile.depend +++ b/tests/sys/kern/execve/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/tests/sys/kern/pipe/Makefile.depend b/tests/sys/kern/pipe/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/tests/sys/kern/pipe/Makefile.depend +++ b/tests/sys/kern/pipe/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c index 5097678ad357..ce648b99c084 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -2402,6 +2402,106 @@ ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) ATF_REQUIRE(errno == ECHILD); } +static sem_t sigusr1_sem; +static int got_usr1; + +static void +sigusr1_sempost_handler(int sig __unused) +{ + + got_usr1++; + CHILD_REQUIRE(sem_post(&sigusr1_sem) == 0); +} + +/* + * Verify that even if the signal queue is full for a child process, + * and the signal is masked, a PT_CONTINUE with a signal will not + * result in loss of that signal. + */ +ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); +ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) +{ + struct ptrace_lwpinfo pl; + pid_t fpid, wpid; + int status, err; + int max_pending_per_proc; + size_t len; + int i; + sigset_t sigmask; + + ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); + ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); + ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); + + got_usr1 = 0; + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + CHILD_REQUIRE(sigemptyset(&sigmask) == 0); + CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); + CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); + + trace_me(); + CHILD_REQUIRE(got_usr1 == 0); + + /* Allow the pending SIGUSR1 in now. */ + CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); + /* Wait to receive the SIGUSR1. */ + do { + err = sem_wait(&sigusr1_sem); + CHILD_REQUIRE(err == 0 || errno == EINTR); + } while (err != 0 && errno == EINTR); + CHILD_REQUIRE(got_usr1 == 1); + exit(1); + } + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + len = sizeof(max_pending_per_proc); + ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", + &max_pending_per_proc, &len, NULL, 0) == 0); + + /* Fill the signal queue. */ + for (i = 0; i < max_pending_per_proc; ++i) + ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); + + /* Continue with signal. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); + + /* Collect and ignore all of the SIGUSR2. */ + for (i = 0; i < max_pending_per_proc; ++i) { + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGUSR2); + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + } + + /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); + ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); + + /* Continue the child, ignoring the SIGUSR1. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The last wait() should report exit after receiving SIGUSR1. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + /* * Verify that, after stopping due to a signal, that signal can be * replaced with another signal. @@ -2467,12 +2567,16 @@ ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) { struct ptrace_lwpinfo pl; + struct rlimit rl; pid_t fpid, wpid; int status; ATF_REQUIRE((fpid = fork()) != -1); if (fpid == 0) { trace_me(); + /* SIGTRAP expected to cause exit on syscall entry. */ + rl.rlim_cur = rl.rlim_max = 0; + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); getpid(); exit(1); } @@ -2670,15 +2774,6 @@ ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) ATF_REQUIRE(errno == ECHILD); } -static sem_t sigusr1_sem; - -static void -sigusr1_sempost_handler(int sig __unused) -{ - - CHILD_REQUIRE(sem_post(&sigusr1_sem) == 0); -} - static void * signal_thread(void *arg) { @@ -2713,6 +2808,148 @@ signal_thread(void *arg) return (NULL); } +/* + * Verify that a traced process with blocked signal received the + * signal from kill() once unmasked. + */ +ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); +ATF_TC_BODY(ptrace__killed_with_sigmask, tc) +{ + struct ptrace_lwpinfo pl; + pid_t fpid, wpid; + int status, err; + sigset_t sigmask; + + ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); + ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); + got_usr1 = 0; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + CHILD_REQUIRE(sigemptyset(&sigmask) == 0); + CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); + CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); + + trace_me(); + CHILD_REQUIRE(got_usr1 == 0); + + /* Allow the pending SIGUSR1 in now. */ + CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); + /* Wait to receive a SIGUSR1. */ + do { + err = sem_wait(&sigusr1_sem); + CHILD_REQUIRE(err == 0 || errno == EINTR); + } while (err != 0 && errno == EINTR); + CHILD_REQUIRE(got_usr1 == 1); + exit(1); + } + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGSTOP); + + /* Send blocked SIGUSR1 which should cause a stop. */ + ATF_REQUIRE(kill(fpid, SIGUSR1) == 0); + + /* Continue the child ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The next wait() should report the kill(SIGUSR1) was received. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); + ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); + + /* Continue the child, allowing in the SIGUSR1. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); + + /* The last wait() should report normal exit with code 1. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +/* + * Verify that a traced process with blocked signal received the + * signal from PT_CONTINUE once unmasked. + */ +ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); +ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) +{ + struct ptrace_lwpinfo pl; + pid_t fpid, wpid; + int status, err; + sigset_t sigmask; + + ATF_REQUIRE(sem_init(&sigusr1_sem, 0, 0) == 0); + ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); + got_usr1 = 0; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + CHILD_REQUIRE(sigemptyset(&sigmask) == 0); + CHILD_REQUIRE(sigaddset(&sigmask, SIGUSR1) == 0); + CHILD_REQUIRE(sigprocmask(SIG_BLOCK, &sigmask, NULL) == 0); + + trace_me(); + CHILD_REQUIRE(got_usr1 == 0); + + /* Allow the pending SIGUSR1 in now. */ + CHILD_REQUIRE(sigprocmask(SIG_UNBLOCK, &sigmask, NULL) == 0); + /* Wait to receive a SIGUSR1. */ + do { + err = sem_wait(&sigusr1_sem); + CHILD_REQUIRE(err == 0 || errno == EINTR); + } while (err != 0 && errno == EINTR); + + CHILD_REQUIRE(got_usr1 == 1); + exit(1); + } + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGSTOP); + + /* Continue the child replacing SIGSTOP with SIGUSR1. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1) == 0); + + /* The next wait() should report the SIGUSR1 was received. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGUSR1); + ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGUSR1); + + /* Continue the child, ignoring the SIGUSR1. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The last wait() should report normal exit with code 1. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + /* * Verify that if ptrace stops due to a signal but continues with * a different signal that the new signal is routed to a thread @@ -3084,7 +3321,7 @@ ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) ATF_REQUIRE((child = fork()) != -1); if (child == 0) { pthread_t t[2]; - int error, cfd; + int cfd; error = pthread_barrier_wait(&barrier); if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) @@ -3140,6 +3377,260 @@ ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) ATF_REQUIRE(close(fd) == 0); } +static void +sigusr1_step_handler(int sig) +{ + + CHILD_REQUIRE(sig == SIGUSR1); + raise(SIGABRT); +} + +/* + * Verify that PT_STEP with a signal invokes the signal before + * stepping the next instruction (and that the next instruction is + * stepped correctly). + */ +ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); +ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) +{ + struct ptrace_lwpinfo pl; + pid_t fpid, wpid; + int status; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + signal(SIGUSR1, sigusr1_step_handler); + raise(SIGABRT); + exit(1); + } + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The next stop should report the SIGABRT in the child body. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); + + /* Step the child process inserting SIGUSR1. */ + ATF_REQUIRE(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1) == 0); + + /* The next stop should report the SIGABRT in the signal handler. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGABRT); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGABRT); + + /* Continue the child process discarding the signal. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The next stop should report a trace trap from PT_STEP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP); + ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_TRACE); + + /* Continue the child to let it exit. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* The last event should be for the child process's exit. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +#if defined(__amd64__) || defined(__i386__) +/* + * Only x86 both define breakpoint() and have a PC after breakpoint so + * that restarting doesn't retrigger the breakpoint. + */ +static void * +continue_thread(void *arg) +{ + breakpoint(); + return (NULL); +} + +static __dead2 void +continue_thread_main(void) +{ + pthread_t threads[2]; + + CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, + NULL) == 0); + CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, + NULL) == 0); + CHILD_REQUIRE(pthread_join(threads[0], NULL) == 0); + CHILD_REQUIRE(pthread_join(threads[1], NULL) == 0); + exit(1); +} + +/* + * Ensure that PT_CONTINUE clears the status of the thread that + * triggered the stop even if a different thread's LWP was passed to + * PT_CONTINUE. + */ +ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); +ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) +{ + struct ptrace_lwpinfo pl; + pid_t fpid, wpid; + lwpid_t lwps[2]; + bool hit_break[2]; + int i, j, status; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + continue_thread_main(); + } + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, + sizeof(pl)) != -1); + + ATF_REQUIRE(ptrace(PT_LWP_EVENTS, wpid, NULL, 1) == 0); + + /* Continue the child ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* One of the new threads should report it's birth. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == + (PL_FLAG_BORN | PL_FLAG_SCX)); + lwps[0] = pl.pl_lwpid; + + /* + * Suspend this thread to ensure both threads are alive before + * hitting the breakpoint. + */ + ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); + + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* Second thread should report it's birth. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)) == + (PL_FLAG_BORN | PL_FLAG_SCX)); + ATF_REQUIRE(pl.pl_lwpid != lwps[0]); + lwps[1] = pl.pl_lwpid; + + /* Resume both threads waiting for breakpoint events. */ + hit_break[0] = hit_break[1] = false; + ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + + /* One thread should report a breakpoint. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); + ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP && + pl.pl_siginfo.si_code == TRAP_BRKPT); + if (pl.pl_lwpid == lwps[0]) + i = 0; + else + i = 1; + hit_break[i] = true; + + /* + * Resume both threads but pass the other thread's LWPID to + * PT_CONTINUE. + */ + ATF_REQUIRE(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0) == 0); + + /* + * Will now get two thread exit events and one more breakpoint + * event. + */ + for (j = 0; j < 3; j++) { + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, + sizeof(pl)) != -1); + + if (pl.pl_lwpid == lwps[0]) + i = 0; + else + i = 1; + + ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); + if (pl.pl_flags & PL_FLAG_EXITED) { + ATF_REQUIRE_MSG(hit_break[i], + "exited thread did not report breakpoint"); + lwps[i] = 0; + } else { + ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); + ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP && + pl.pl_siginfo.si_code == TRAP_BRKPT); + ATF_REQUIRE_MSG(!hit_break[i], + "double breakpoint event"); + hit_break[i] = true; + } + + ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); + } + + /* Both threads should have exited. */ + ATF_REQUIRE(lwps[0] == 0); + ATF_REQUIRE(lwps[1] == 0); + + /* The last event should be for the child process's exit. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} +#endif + ATF_TP_ADD_TCS(tp) { @@ -3179,15 +3670,22 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); + ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); + ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); + ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); + ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); +#if defined(__amd64__) || defined(__i386__) + ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); +#endif return (atf_no_error()); } diff --git a/tests/sys/kqueue/Makefile.depend b/tests/sys/kqueue/Makefile.depend new file mode 100644 index 000000000000..10e58b789640 --- /dev/null +++ b/tests/sys/kqueue/Makefile.depend @@ -0,0 +1,19 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/atf/libatf-c \ + lib/libc \ + lib/libcompiler_rt \ + lib/libnetbsd \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/tests/sys/kqueue/libkqueue/Makefile.depend b/tests/sys/kqueue/libkqueue/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/tests/sys/kqueue/libkqueue/Makefile.depend +++ b/tests/sys/kqueue/libkqueue/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/mac/bsdextended/Makefile.depend b/tests/sys/mac/bsdextended/Makefile.depend index 24a1de909f18..65c3644dbf39 100644 --- a/tests/sys/mac/bsdextended/Makefile.depend +++ b/tests/sys/mac/bsdextended/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/mqueue/Makefile.depend b/tests/sys/mqueue/Makefile.depend index 24e69ea5bc4c..05a315e8dff9 100644 --- a/tests/sys/mqueue/Makefile.depend +++ b/tests/sys/mqueue/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/netinet/Makefile.depend b/tests/sys/netinet/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/tests/sys/netinet/Makefile.depend +++ b/tests/sys/netinet/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/tests/sys/netpfil/Makefile b/tests/sys/netpfil/Makefile new file mode 100644 index 000000000000..f9719f6ce2b4 --- /dev/null +++ b/tests/sys/netpfil/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/netpfil + +TESTS_SUBDIRS+= pf + +.include diff --git a/tests/sys/netpfil/Makefile.depend b/tests/sys/netpfil/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/tests/sys/netpfil/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile new file mode 100644 index 000000000000..259e1275d9c6 --- /dev/null +++ b/tests/sys/netpfil/pf/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +PACKAGE= tests + +TESTSDIR= ${TESTSBASE}/sys/netpfil/pf + +ATF_TESTS_SH+= pass_block \ + forward \ + fragmentation \ + set_tos + +${PACKAGE}FILES+= utils.subr \ + pft_ping.py + +${PACKAGE}FILESMODE_pft_ping.py= 0555 + +.include diff --git a/tests/sys/netpfil/pf/Makefile.depend b/tests/sys/netpfil/pf/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/tests/sys/netpfil/pf/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/tests/sys/netpfil/pf/forward.sh b/tests/sys/netpfil/pf/forward.sh new file mode 100755 index 000000000000..a41ff8934a83 --- /dev/null +++ b/tests/sys/netpfil/pf/forward.sh @@ -0,0 +1,149 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "v4" "cleanup" +v4_head() +{ + atf_set descr 'Basic forwarding test' + atf_set require.user root + + # We need scapy to be installed for out test scripts to work + atf_set require.progs scapy +} + +v4_body() +{ + pft_init + + epair_send=$(pft_mkepair) + ifconfig ${epair_send}a 192.0.2.1/24 up + + epair_recv=$(pft_mkepair) + ifconfig ${epair_recv}a up + + pft_mkjail alcatraz ${epair_send}b ${epair_recv}b + jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up + jexec alcatraz ifconfig ${epair_recv}b 198.51.100.2/24 up + jexec alcatraz sysctl net.inet.ip.forwarding=1 + jexec alcatraz arp -s 198.51.100.3 00:01:02:03:04:05 + route add -net 198.51.100.0/24 192.0.2.2 + + # Sanity check, can we forward ICMP echo requests without pf? + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a + + jexec alcatraz pfctl -e + + # Forward with pf enabled + pft_set_rules alcatraz "block in" + atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a + + pft_set_rules alcatraz "block out" + atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recv ${epair_recv}a + + # Allow ICMP + pft_set_rules alcatraz "block in" "pass in proto icmp" + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a +} + +v4_cleanup() +{ + pft_cleanup +} + +atf_test_case "v6" "cleanup" +v6_head() +{ + atf_set descr 'Basic IPv6 forwarding test' + atf_set require.user root + atf_set require.progs scapy +} + +v6_body() +{ + pft_init + + epair_send=$(pft_mkepair) + epair_recv=$(pft_mkepair) + + ifconfig ${epair_send}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled + ifconfig ${epair_recv}a up + + pft_mkjail alcatraz ${epair_send}b ${epair_recv}b + + jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 up no_dad + jexec alcatraz ifconfig ${epair_recv}b inet6 2001:db8:43::2/64 up no_dad + jexec alcatraz sysctl net.inet6.ip6.forwarding=1 + jexec alcatraz ndp -s 2001:db8:43::3 00:01:02:03:04:05 + route add -6 2001:db8:43::/64 2001:db8:42::2 + + # Sanity check, can we forward ICMP echo requests without pf? + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --ip6 \ + --sendif ${epair_send}a \ + --to 2001:db8:43::3 \ + --recvif ${epair_recv}a + + jexec alcatraz pfctl -e + + # Block incoming echo request packets + pft_set_rules alcatraz \ + "block in inet6 proto icmp6 icmp6-type echoreq" + atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \ + --ip6 \ + --sendif ${epair_send}a \ + --to 2001:db8:43::3 \ + --recvif ${epair_recv}a + + # Block outgoing echo request packets + pft_set_rules alcatraz \ + "block out inet6 proto icmp6 icmp6-type echoreq" + atf_check -s exit:1 -e ignore $(atf_get_srcdir)/pft_ping.py \ + --ip6 \ + --sendif ${epair_send}a \ + --to 2001:db8:43::3 \ + --recvif ${epair_recv}a + + # Allow ICMPv6 but nothing else + pft_set_rules alcatraz \ + "block out" \ + "pass out inet6 proto icmp6" + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --ip6 \ + --sendif ${epair_send}a \ + --to 2001:db8:43::3 \ + --recvif ${epair_recv}a + + # Allowing ICMPv4 does not allow ICMPv6 + pft_set_rules alcatraz \ + "block out inet6 proto icmp6 icmp6-type echoreq" \ + "pass in proto icmp" + atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \ + --ip6 \ + --sendif ${epair_send}a \ + --to 2001:db8:43::3 \ + --recvif ${epair_recv}a +} + +v6_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "v4" + atf_add_test_case "v6" +} diff --git a/tests/sys/netpfil/pf/fragmentation.sh b/tests/sys/netpfil/pf/fragmentation.sh new file mode 100755 index 000000000000..3ef939582411 --- /dev/null +++ b/tests/sys/netpfil/pf/fragmentation.sh @@ -0,0 +1,74 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "v6" "cleanup" +v6_head() +{ + atf_set descr 'IPv6 fragmentation test' + atf_set require.user root + atf_set require.progs scapy +} + +v6_body() +{ + pft_init + + epair_send=$(pft_mkepair) + epair_link=$(pft_mkepair) + + pft_mkjail alcatraz ${epair_send}b ${epair_link}a + pft_mkjail singsing ${epair_link}b + + ifconfig ${epair_send}a inet6 2001:db8:42::1/64 no_dad up + + jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 no_dad up + jexec alcatraz ifconfig ${epair_link}a inet6 2001:db8:43::2/64 no_dad up + jexec alcatraz sysctl net.inet6.ip6.forwarding=1 + + jexec singsing ifconfig ${epair_link}b inet6 2001:db8:43::3/64 no_dad up + jexec singsing route add -6 2001:db8:42::/64 2001:db8:43::2 + route add -6 2001:db8:43::/64 2001:db8:42::2 + + jexec alcatraz ifconfig ${epair_send}b inet6 -ifdisabled + jexec alcatraz ifconfig ${epair_link}a inet6 -ifdisabled + jexec singsing ifconfig ${epair_link}b inet6 -ifdisabled + ifconfig ${epair_send}a inet6 -ifdisabled + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "scrub fragment reassemble" \ + "block in" \ + "pass in inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ + "pass in inet6 proto icmp6 icmp6-type { echoreq, echorep }" + + # Host test + atf_check -s exit:0 -o ignore \ + ping6 -c 1 2001:db8:42::2 + + atf_check -s exit:0 -o ignore \ + ping6 -c 1 -s 4500 2001:db8:42::2 + + atf_check -s exit:0 -o ignore\ + ping6 -c 1 -b 70000 -s 65000 2001:db8:42::2 + + # Forwarding test + atf_check -s exit:0 -o ignore \ + ping6 -c 1 2001:db8:43::3 + + atf_check -s exit:0 -o ignore \ + ping6 -c 1 -s 4500 2001:db8:43::3 + + atf_check -s exit:0 -o ignore\ + ping6 -c 1 -b 70000 -s 65000 2001:db8:43::3 +} + +v6_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "v6" +} diff --git a/tests/sys/netpfil/pf/pass_block.sh b/tests/sys/netpfil/pf/pass_block.sh new file mode 100755 index 000000000000..9eeb89b17037 --- /dev/null +++ b/tests/sys/netpfil/pf/pass_block.sh @@ -0,0 +1,91 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "v4" "cleanup" +v4_head() +{ + atf_set descr 'Basic pass/block test for IPv4' + atf_set require.user root +} + +v4_body() +{ + pft_init + + epair=$(pft_mkepair) + ifconfig ${epair}a 192.0.2.1/24 up + + # Set up a simple jail with one interface + pft_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up + + # Trivial ping to the jail, without pf + atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 + + # pf without policy will let us ping + jexec alcatraz pfctl -e + atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 + + # Block everything + pft_set_rules alcatraz "block in" + atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 + + # Block everything but ICMP + pft_set_rules alcatraz "block in" "pass in proto icmp" + atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 +} + +v4_cleanup() +{ + pft_cleanup +} + +atf_test_case "v6" "cleanup" +v6_head() +{ + atf_set descr 'Basic pass/block test for IPv6' + atf_set require.user root +} + +v6_body() +{ + pft_init + + epair=$(pft_mkepair) + ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad + + # Set up a simple jail with one interface + pft_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad + + # Trivial ping to the jail, without pf + atf_check -s exit:0 -o ignore ping6 -c 1 -x 1 2001:db8:42::2 + + # pf without policy will let us ping + jexec alcatraz pfctl -e + atf_check -s exit:0 -o ignore ping6 -c 1 -x 1 2001:db8:42::2 + + # Block everything + pft_set_rules alcatraz "block in" + atf_check -s exit:2 -o ignore ping6 -c 1 -x 1 2001:db8:42::2 + + # Block everything but ICMP + pft_set_rules alcatraz "block in" "pass in proto icmp6" + atf_check -s exit:0 -o ignore ping6 -c 1 -x 1 2001:db8:42::2 + + # Allowing ICMPv4 does not allow ICMPv6 + pft_set_rules alcatraz "block in" "pass in proto icmp" + atf_check -s exit:2 -o ignore ping6 -c 1 -x 1 2001:db8:42::2 +} + +v6_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "v4" + atf_add_test_case "v6" +} diff --git a/tests/sys/netpfil/pf/pft_ping.py b/tests/sys/netpfil/pf/pft_ping.py new file mode 100644 index 000000000000..98bce2e0716f --- /dev/null +++ b/tests/sys/netpfil/pf/pft_ping.py @@ -0,0 +1,145 @@ +#!/usr/local/bin/python2.7 + +import argparse +import scapy.all as sp +import sys +import threading + +PAYLOAD_MAGIC = 0x42c0ffee + +class Sniffer(threading.Thread): + def __init__(self, recvif): + threading.Thread.__init__(self) + + self._recvif = recvif + + self.start() + + def run(self): + self.packets = sp.sniff(iface=self._recvif, timeout=3) + +def check_ping_request(packet, dst_ip, args): + if args.ip6: + return check_ping6_request(packet, dst_ip, args) + else: + return check_ping4_request(packet, dst_ip, args) + +def check_ping4_request(packet, dst_ip, args): + """ + Verify that the packet matches what we'd have sent + """ + ip = packet.getlayer(sp.IP) + if not ip: + return False + if ip.dst != dst_ip: + return False + + icmp = packet.getlayer(sp.ICMP) + if not icmp: + return False + if sp.icmptypes[icmp.type] != 'echo-request': + return False + + raw = packet.getlayer(sp.Raw) + if not raw: + return False + if raw.load != str(PAYLOAD_MAGIC): + return False + + # Wait to check expectations until we've established this is the packet we + # sent. + if args.expect_tos: + if ip.tos != int(args.expect_tos[0]): + print "Unexpected ToS value %d, expected %s" \ + % (ip.tos, args.expect_tos[0]) + return False + + + return True + +def check_ping6_request(packet, dst_ip, args): + """ + Verify that the packet matches what we'd have sent + """ + ip = packet.getlayer(sp.IPv6) + if not ip: + return False + if ip.dst != dst_ip: + return False + + icmp = packet.getlayer(sp.ICMPv6EchoRequest) + if not icmp: + return False + if icmp.data != str(PAYLOAD_MAGIC): + return False + + return True + +def ping(send_if, dst_ip, args): + ether = sp.Ether() + ip = sp.IP(dst=dst_ip) + icmp = sp.ICMP(type='echo-request') + raw = sp.Raw(PAYLOAD_MAGIC) + + if args.send_tos: + ip.tos = int(args.send_tos[0]) + + req = ether / ip / icmp / raw + sp.sendp(req, iface=send_if, verbose=False) + +def ping6(send_if, dst_ip, args): + ether = sp.Ether() + ip6 = sp.IPv6(dst=dst_ip) + icmp = sp.ICMPv6EchoRequest(data=PAYLOAD_MAGIC) + + req = ether / ip6 / icmp + sp.sendp(req, iface=send_if, verbose=False) + +def main(): + parser = argparse.ArgumentParser("pft_ping.py", + description="Ping test tool") + parser.add_argument('--sendif', nargs=1, + required=True, + help='The interface through which the packet(s) will be sent') + parser.add_argument('--recvif', nargs=1, + help='The interface on which to expect the ICMP echo response') + parser.add_argument('--ip6', action='store_true', + help='Use IPv6') + parser.add_argument('--to', nargs=1, + required=True, + help='The destination IP address for the ICMP echo request') + + # Packet settings + parser.add_argument('--send-tos', nargs=1, + help='Set the ToS value for the transmitted packet') + + # Expectations + parser.add_argument('--expect-tos', nargs=1, + help='The expected ToS value in the received packet') + + args = parser.parse_args() + + # We may not have a default route. Tell scapy where to start looking for routes + sp.conf.iface6 = args.sendif[0] + + sniffer = None + if not args.recvif is None: + sniffer = Sniffer(args.recvif[0]) + + if args.ip6: + ping6(args.sendif[0], args.to[0], args) + else: + ping(args.sendif[0], args.to[0], args) + + if sniffer: + sniffer.join() + + for packet in sniffer.packets: + if check_ping_request(packet, args.to[0], args): + sys.exit(0) + + # We did not get the packet we expected + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/tests/sys/netpfil/pf/set_tos.sh b/tests/sys/netpfil/pf/set_tos.sh new file mode 100755 index 000000000000..5e56b7ceb656 --- /dev/null +++ b/tests/sys/netpfil/pf/set_tos.sh @@ -0,0 +1,93 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "v4" "cleanup" +v4_head() +{ + atf_set descr 'set-tos test' + atf_set require.user root + + # We need scapy to be installed for out test scripts to work + atf_set require.progs scapy +} + +v4_body() +{ + pft_init + + epair_send=$(pft_mkepair) + ifconfig ${epair_send}a 192.0.2.1/24 up + + epair_recv=$(pft_mkepair) + ifconfig ${epair_recv}a up + + pft_mkjail alcatraz ${epair_send}b ${epair_recv}b + jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up + jexec alcatraz ifconfig ${epair_recv}b 198.51.100.2/24 up + jexec alcatraz sysctl net.inet.ip.forwarding=1 + jexec alcatraz arp -s 198.51.100.3 00:01:02:03:04:05 + route add -net 198.51.100.0/24 192.0.2.2 + + jexec alcatraz pfctl -e + + # No change is done if not requested + pft_set_rules alcatraz "scrub out proto icmp" + atf_check -s exit:1 -o ignore $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # The requested ToS is set + pft_set_rules alcatraz "scrub out proto icmp set-tos 42" + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # ToS is not changed if the scrub rule does not match + pft_set_rules alcatraz "scrub out proto tcp set-tos 42" + atf_check -s exit:1 -o ignore $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # Multiple scrub rules match as expected + pft_set_rules alcatraz "scrub out proto tcp set-tos 13" \ + "scrub out proto icmp set-tos 14" + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 14 + + # And this works even if the packet already has ToS values set + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --send-tos 42 \ + --expect-tos 14 + + # ToS values are unmolested if the packets do not match a scrub rule + pft_set_rules alcatraz "scrub out proto tcp set-tos 13" + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --send-tos 42 \ + --expect-tos 42 +} + +v4_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "v4" +} diff --git a/tests/sys/netpfil/pf/utils.subr b/tests/sys/netpfil/pf/utils.subr new file mode 100644 index 000000000000..f2f28ed0c66a --- /dev/null +++ b/tests/sys/netpfil/pf/utils.subr @@ -0,0 +1,69 @@ +# $FreeBSD$ +# Utility functions +## + +pft_init() +{ + if [ ! -c /dev/pf ]; then + atf_skip "This test requires pf" + fi + + if [ "`sysctl -i -n kern.features.vimage`" != 1 ]; then + atf_skip "This test requires VIMAGE" + fi +} + +pft_mkepair() +{ + ifname=$(ifconfig epair create) + echo $ifname >> created_interfaces.lst + echo ${ifname%a} +} + +pft_mkjail() +{ + jailname=$1 + shift + + vnet_interfaces= + for ifname in $@ + do + vnet_interfaces="${vnet_interfaces} vnet.interface=${ifname}" + done + jail -c name=${jailname} persist vnet ${vnet_interfaces} + + echo $jailname >> created_jails.lst +} + +pft_set_rules() +{ + jname=$1 + shift + + # Flush all states, rules, fragments, ... + jexec ${jname} pfctl -F all + + while [ $# -gt 0 ]; do + printf "$1\n" + shift + done | jexec ${jname} pfctl -f - +} + +pft_cleanup() +{ + if [ -f created_jails.lst ]; then + for jailname in `cat created_jails.lst` + do + jail -r ${jailname} + done + rm created_jails.lst + fi + + if [ -f created_interfaces.lst ]; then + for ifname in `cat created_interfaces.lst` + do + ifconfig ${ifname} destroy + done + rm created_interfaces.lst + fi +} diff --git a/tests/sys/opencrypto/cryptodev.py b/tests/sys/opencrypto/cryptodev.py index afe075d7de86..3e0ae0120b06 100644 --- a/tests/sys/opencrypto/cryptodev.py +++ b/tests/sys/opencrypto/cryptodev.py @@ -30,6 +30,7 @@ # $FreeBSD$ # +from __future__ import print_function import array import dpkt from fcntl import ioctl @@ -174,9 +175,9 @@ def __init__(self, cipher=0, key=None, mac=0, mackey=None, if not cipher and not mac: raise ValueError('one of cipher or mac MUST be specified.') ses.crid = crid - #print `ses` + #print(ses) s = array.array('B', ses.pack_hdr()) - #print `s` + #print(s) ioctl(_cryptodev, CIOCGSESSION2, s, 1) ses.unpack(s) @@ -206,7 +207,7 @@ def _doop(self, op, src, iv): ivbuf = array.array('B', iv) cop.iv = ivbuf.buffer_info()[0] - #print 'cop:', `cop` + #print('cop:', cop) ioctl(_cryptodev, CIOCCRYPT, str(cop)) s = s.tostring() @@ -234,7 +235,8 @@ def _doaead(self, op, src, aad, iv, tag=None): if tag is None: tag = array.array('B', [0] * self._maclen) else: - assert len(tag) == self._maclen, `len(tag), self._maclen` + assert len(tag) == self._maclen, \ + '%d != %d' % (len(tag), self._maclen) tag = array.array('B', tag) caead.tag = tag.buffer_info()[0] @@ -288,8 +290,8 @@ def alarmhandle(a, b, exit=exit): signal.signal(signal.SIGALRM, oldalarm) - print 'time:', end - start - print 'perf MB/sec:', (reps * size) / (end - start) / 1024 / 1024 + print('time:', end - start) + print('perf MB/sec:', (reps * size) / (end - start) / 1024 / 1024) def encrypt(self, data, iv, aad=None): if aad is None: @@ -332,7 +334,7 @@ def __iter__(self): if i[0] == '[': yield i[1:].split(']', 1)[0], self.fielditer() else: - raise ValueError('unknown line: %s' % `i`) + raise ValueError('unknown line: %r' % repr(i)) def eatblanks(self): while True: @@ -362,12 +364,12 @@ def fielditer(self): if line == 'FAIL': f, v = 'FAIL', '' else: - print 'line:', `line` + print('line:', repr(line)) raise v = v.strip() if f in values: - raise ValueError('already present: %s' % `f`) + raise ValueError('already present: %r' % repr(f)) values[f] = v line = self.fp.readline().strip() if not line: @@ -377,7 +379,7 @@ def fielditer(self): remain = self.fields.copy() - set(values.keys()) # XXX - special case GCM decrypt if remain and not ('FAIL' in values and 'PT' in remain): - raise ValueError('not all fields found: %s' % `remain`) + raise ValueError('not all fields found: %r' % repr(remain)) yield values @@ -388,22 +390,22 @@ def _spdechex(s): if True: try: crid = Crypto.findcrid('aesni0') - print 'aesni:', crid + print('aesni:', crid) except IOError: - print 'aesni0 not found' + print('aesni0 not found') for i in xrange(10): try: name = Crypto.getcridname(i) - print '%2d: %s' % (i, `name`) + print('%2d: %r' % (i, repr(name))) except IOError: pass elif False: kp = KATParser('/usr/home/jmg/aesni.testing/format tweak value input - data unit seq no/XTSGenAES128.rsp', [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 'CT' ]) for mode, ni in kp: - print `i`, `ni` + print(i, ni) for j in ni: - print `j` + print(j) elif False: key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') iv = _spdechex('00000000000000000000000000000001') @@ -414,15 +416,15 @@ def _spdechex(s): c = Crypto(CRYPTO_AES_ICM, key) enc = c.encrypt(pt, iv) - print 'enc:', enc.encode('hex') - print ' ct:', ct.encode('hex') + print('enc:', enc.encode('hex')) + print(' ct:', ct.encode('hex')) assert ct == enc dec = c.decrypt(ct, iv) - print 'dec:', dec.encode('hex') - print ' pt:', pt.encode('hex') + print('dec:', dec.encode('hex')) + print(' pt:', pt.encode('hex')) assert pt == dec elif False: @@ -435,15 +437,15 @@ def _spdechex(s): c = Crypto(CRYPTO_AES_ICM, key) enc = c.encrypt(pt, iv) - print 'enc:', enc.encode('hex') - print ' ct:', ct.encode('hex') + print('enc:', enc.encode('hex')) + print(' ct:', ct.encode('hex')) assert ct == enc dec = c.decrypt(ct, iv) - print 'dec:', dec.encode('hex') - print ' pt:', pt.encode('hex') + print('dec:', dec.encode('hex')) + print(' pt:', pt.encode('hex')) assert pt == dec elif False: @@ -455,15 +457,15 @@ def _spdechex(s): enc = c.encrypt(pt, iv) - print 'enc:', enc.encode('hex') - print ' ct:', ct.encode('hex') + print('enc:', enc.encode('hex')) + print(' ct:', ct.encode('hex')) assert ct == enc dec = c.decrypt(ct, iv) - print 'dec:', dec.encode('hex') - print ' pt:', pt.encode('hex') + print('dec:', dec.encode('hex')) + print(' pt:', pt.encode('hex')) assert pt == dec elif False: @@ -481,26 +483,26 @@ def _spdechex(s): enc, enctag = c.encrypt(pt, iv, aad=aad) - print 'enc:', enc.encode('hex') - print ' ct:', ct.encode('hex') + print('enc:', enc.encode('hex')) + print(' ct:', ct.encode('hex')) assert enc == ct - print 'etg:', enctag.encode('hex') - print 'tag:', tag.encode('hex') + print('etg:', enctag.encode('hex')) + print('tag:', tag.encode('hex')) assert enctag == tag # Make sure we get EBADMSG #enctag = enctag[:-1] + 'a' dec, dectag = c.decrypt(ct, iv, aad=aad, tag=enctag) - print 'dec:', dec.encode('hex') - print ' pt:', pt.encode('hex') + print('dec:', dec.encode('hex')) + print(' pt:', pt.encode('hex')) assert dec == pt - print 'dtg:', dectag.encode('hex') - print 'tag:', tag.encode('hex') + print('dtg:', dectag.encode('hex')) + print('tag:', tag.encode('hex')) assert dectag == tag elif False: @@ -517,13 +519,13 @@ def _spdechex(s): enc, enctag = c.encrypt(pt, iv, aad=aad) - print 'enc:', enc.encode('hex') - print ' ct:', ct.encode('hex') + print('enc:', enc.encode('hex')) + print(' ct:', ct.encode('hex')) assert enc == ct - print 'etg:', enctag.encode('hex') - print 'tag:', tag.encode('hex') + print('etg:', enctag.encode('hex')) + print('tag:', tag.encode('hex')) assert enctag == tag elif False: for i in xrange(100000): @@ -550,9 +552,9 @@ def _spdechex(s): else: key = '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex') - print 'XTS %d testing:' % (len(key) * 8) + print('XTS %d testing:' % (len(key) * 8)) c = Crypto(CRYPTO_AES_XTS, key) for i in [ 8192, 192*1024]: - print 'block size: %d' % i + print('block size: %d' % i) c.perftest(COP_ENCRYPT, i) c.perftest(COP_DECRYPT, i) diff --git a/tests/sys/opencrypto/cryptotest.py b/tests/sys/opencrypto/cryptotest.py index 46d9261f2a78..db8c87ecd476 100644 --- a/tests/sys/opencrypto/cryptotest.py +++ b/tests/sys/opencrypto/cryptotest.py @@ -29,6 +29,8 @@ # $FreeBSD$ # +from __future__ import print_function +import errno import cryptodev import itertools import os @@ -40,11 +42,12 @@ katdir = '/usr/local/share/nist-kat' def katg(base, glob): + assert os.path.exists(os.path.join(katdir, base)), "Please 'pkg install nist-kat'" return iglob(os.path.join(katdir, base, glob)) aesmodules = [ 'cryptosoft0', 'aesni0', 'ccr0' ] desmodules = [ 'cryptosoft0', ] -shamodules = [ 'cryptosoft0', 'ccr0' ] +shamodules = [ 'cryptosoft0', 'aesni0', 'ccr0' ] def GenTestCase(cname): try: @@ -56,15 +59,17 @@ class GendCryptoTestCase(unittest.TestCase): ############### ##### AES ##### ############### - @unittest.skipIf(cname not in aesmodules, 'skipping AES on %s' % `cname`) + @unittest.skipIf(cname not in aesmodules, 'skipping AES on %s' % (cname)) def test_xts(self): for i in katg('XTSTestVectors/format tweak value input - data unit seq no', '*.rsp'): self.runXTS(i, cryptodev.CRYPTO_AES_XTS) + @unittest.skipIf(cname not in aesmodules, 'skipping AES on %s' % (cname)) def test_cbc(self): for i in katg('KAT_AES', 'CBC[GKV]*.rsp'): self.runCBC(i) + @unittest.skipIf(cname not in aesmodules, 'skipping AES on %s' % (cname)) def test_gcm(self): for i in katg('gcmtestvectors', 'gcmEncrypt*'): self.runGCM(i, 'ENCRYPT') @@ -85,7 +90,7 @@ def runGCM(self, fname, mode): swapptct = True curfun = Crypto.decrypt else: - raise RuntimeError('unknown mode: %s' % `mode`) + raise RuntimeError('unknown mode: %r' % repr(mode)) for bogusmode, lines in cryptodev.KATParser(fname, [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ]): @@ -113,8 +118,8 @@ def runGCM(self, fname, mode): rtag = rtag[:len(tag)] data['rct'] = rct.encode('hex') data['rtag'] = rtag.encode('hex') - self.assertEqual(rct, ct, `data`) - self.assertEqual(rtag, tag, `data`) + self.assertEqual(rct, ct, repr(data)) + self.assertEqual(rtag, tag, repr(data)) else: if len(tag) != 16: continue @@ -127,7 +132,7 @@ def runGCM(self, fname, mode): data['rpt'] = rpt.encode('hex') data['rtag'] = rtag.encode('hex') self.assertEqual(rpt, pt, - `data`) + repr(data)) def runCBC(self, fname): curfun = None @@ -140,7 +145,7 @@ def runCBC(self, fname): swapptct = True curfun = Crypto.decrypt else: - raise RuntimeError('unknown mode: %s' % `mode`) + raise RuntimeError('unknown mode: %r' % repr(mode)) for data in lines: curcnt = int(data['COUNT']) @@ -168,7 +173,7 @@ def runXTS(self, fname, meth): swapptct = True curfun = Crypto.decrypt else: - raise RuntimeError('unknown mode: %s' % `mode`) + raise RuntimeError('unknown mode: %r' % repr(mode)) for data in lines: curcnt = int(data['COUNT']) @@ -191,7 +196,7 @@ def runXTS(self, fname, meth): ############### ##### DES ##### ############### - @unittest.skipIf(cname not in desmodules, 'skipping DES on %s' % `cname`) + @unittest.skipIf(cname not in desmodules, 'skipping DES on %s' % (cname)) def test_tdes(self): for i in katg('KAT_TDES', 'TCBC[a-z]*.rsp'): self.runTDES(i) @@ -207,7 +212,7 @@ def runTDES(self, fname): swapptct = True curfun = Crypto.decrypt else: - raise RuntimeError('unknown mode: %s' % `mode`) + raise RuntimeError('unknown mode: %r' % repr(mode)) for data in lines: curcnt = int(data['COUNT']) @@ -227,34 +232,77 @@ def runTDES(self, fname): ############### ##### SHA ##### ############### - @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % `cname`) + @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname)) def test_sha(self): # SHA not available in software pass #for i in iglob('SHA1*'): # self.runSHA(i) + @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname)) def test_sha1hmac(self): for i in katg('hmactestvectors', 'HMAC.rsp'): self.runSHA1HMAC(i) def runSHA1HMAC(self, fname): - for bogusmode, lines in cryptodev.KATParser(fname, + for hashlength, lines in cryptodev.KATParser(fname, [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ]): + # E.g., hashlength will be "L=20" (bytes) + hashlen = int(hashlength.split("=")[1]) + + blocksize = None + if hashlen == 20: + alg = cryptodev.CRYPTO_SHA1_HMAC + blocksize = 64 + elif hashlen == 28: + # Cryptodev doesn't support SHA-224 + # Slurp remaining input in section + for data in lines: + continue + continue + elif hashlen == 32: + alg = cryptodev.CRYPTO_SHA2_256_HMAC + blocksize = 64 + elif hashlen == 48: + alg = cryptodev.CRYPTO_SHA2_384_HMAC + blocksize = 128 + elif hashlen == 64: + alg = cryptodev.CRYPTO_SHA2_512_HMAC + blocksize = 128 + else: + # Skip unsupported hashes + # Slurp remaining input in section + for data in lines: + continue + continue + for data in lines: key = data['Key'].decode('hex') msg = data['Msg'].decode('hex') mac = data['Mac'].decode('hex') + tlen = int(data['Tlen']) - if len(key) != 20: - # XXX - implementation bug + if len(key) > blocksize: continue - c = Crypto(mac=cryptodev.CRYPTO_SHA1_HMAC, - mackey=key, crid=crid) + try: + c = Crypto(mac=alg, mackey=key, + crid=crid) + except EnvironmentError, e: + # Can't test hashes the driver does not support. + if e.errno != errno.EOPNOTSUPP: + raise + continue - r = c.encrypt(msg) - self.assertEqual(r, mac, `data`) + _, r = c.encrypt(msg, iv="") + + # A limitation in cryptodev.py means we + # can only store MACs up to 16 bytes. + # That's good enough to validate the + # correct behavior, more or less. + maclen = min(tlen, 16) + self.assertEqual(r[:maclen], mac[:maclen], "Actual: " + \ + repr(r[:maclen].encode("hex")) + " Expected: " + repr(data)) return GendCryptoTestCase diff --git a/tests/sys/pjdfstest/pjdfstest/Makefile.depend b/tests/sys/pjdfstest/pjdfstest/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/tests/sys/pjdfstest/pjdfstest/Makefile.depend +++ b/tests/sys/pjdfstest/pjdfstest/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/pjdfstest/tests/utimensat/Makefile.depend b/tests/sys/pjdfstest/tests/utimensat/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/tests/sys/pjdfstest/tests/utimensat/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/tests/sys/posixshm/Makefile.depend b/tests/sys/posixshm/Makefile.depend index 74074b9588ec..c062f6026d94 100644 --- a/tests/sys/posixshm/Makefile.depend +++ b/tests/sys/posixshm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/sys/Makefile.depend b/tests/sys/sys/Makefile.depend index 74074b9588ec..c062f6026d94 100644 --- a/tests/sys/sys/Makefile.depend +++ b/tests/sys/sys/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tests/sys/vfs/Makefile.depend b/tests/sys/vfs/Makefile.depend index f80275d86ab1..c062f6026d94 100644 --- a/tests/sys/vfs/Makefile.depend +++ b/tests/sys/vfs/Makefile.depend @@ -2,6 +2,13 @@ # Autogenerated - do NOT edit! DIRDEPS = \ + gnu/lib/csu \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/atf/libatf-c \ + lib/libc \ + lib/libcompiler_rt \ .include diff --git a/tests/sys/vm/Makefile.depend b/tests/sys/vm/Makefile.depend index 74074b9588ec..c062f6026d94 100644 --- a/tests/sys/vm/Makefile.depend +++ b/tests/sys/vm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tools/boot/universe.sh b/tools/boot/universe.sh new file mode 100755 index 000000000000..fa11ad2dde7e --- /dev/null +++ b/tools/boot/universe.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# $FreeBSD$ + +# +# Full list of all arches, but we only build a subset. All different mips add any +# value, and there's a few others we just don't support. +# +# mips/mipsel mips/mips mips/mips64el mips/mips64 mips/mipsn32 \ +# mips/mipselhf mips/mipshf mips/mips64elhf mips/mips64hf \ +# powerpc/powerpc powerpc/powerpc64 powerpc/powerpcspe \ +# riscv/riscv64 riscv/riscv64sf +# +# This script is expected to be run in sys/boot (though you could run it anywhere +# in the tree). It does a full clean build. For sys/boot you can do all the archs in +# about a minute or two on a fast machine. It's also possible that you need a full +# make universe for this to work completely. +# +# Output is put into _.boot.$TARGET_ARCH.log in sys.boot. +# + +top=$(make -V SRCTOP) +cd $top/sys/boot + +for i in \ + amd64/amd64 \ + arm/arm arm/armeb arm/armv7 \ + arm64/aarch64 \ + i386/i386 \ + mips/mips mips/mips64 \ + powerpc/powerpc powerpc/powerpc64 \ + sparc64/sparc64 \ + ; do + ta=${i##*/} + echo -n "Building $ta..." + if ! make buildenv TARGET_ARCH=$ta BUILDENV_SHELL="make clean cleandepend cleandir obj depend" \ + > _.boot.${ta}.log 2>&1; then + echo "Fail (cleanup)" + continue + fi + if ! make buildenv TARGET_ARCH=$ta BUILDENV_SHELL="make -j 20 all" \ + >> _.boot.${ta}.log 2>&1; then + echo "Fail (build)" + continue + fi + echo "Success" +done +for i in \ + amd64/amd64 \ + i386/i386 \ + ; do + ta=${i##*/} + echo -n "Building $ta MK_ZFS=no..." + if ! make buildenv TARGET_ARCH=$ta BUILDENV_SHELL="make clean cleandepend cleandir obj depend" \ + > _.boot.${ta}.noZFS.log 2>&1; then + echo "Fail (cleanup)" + continue + fi + if ! make buildenv TARGET_ARCH=$ta BUILDENV_SHELL="make MK_ZFS=no -j 20 all" \ + >> _.boot.${ta}.noZFS.log 2>&1; then + echo "Fail (build)" + continue + fi + echo "Success" +done diff --git a/tools/bsdbox/Makefile.depend b/tools/bsdbox/Makefile.depend index 4ed702841d90..5c55689d1148 100644 --- a/tools/bsdbox/Makefile.depend +++ b/tools/bsdbox/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/tools/build/beinstall.sh b/tools/build/beinstall.sh index 0467ce0e0ed3..94b25c59af24 100755 --- a/tools/build/beinstall.sh +++ b/tools/build/beinstall.sh @@ -106,7 +106,13 @@ if [ -d .git ] ; then [ $? -ne 0 ] && errx "Can't lookup git commit timestamp" commit_ts=$(date -r ${commit_time} '+%Y%m%d.%H%M%S') elif [ -d .svn ] ; then - commit_ts=$( svn info | awk '/Last Changed Date/ {print $4 "." $5}' | tr -d :- ) + if [ -f /usr/bin/svnlite ]; then + commit_ts=$( svnlite info --show-item last-changed-date | sed -e 's/\..*//' -e 's/T/./' -e 's/-//g' -e s'/://g' ) + elif [ -f /usr/local/bin/svn ]; then + commit_ts=$( svn info --show-item last-changed-date | sed -e 's/\..*//' -e 's/T/./' -e 's/-//g' -e s'/://g' ) + else + errx "Can't lookup Subversion commit timestamp" + fi [ $? -ne 0 ] && errx "Can't lookup Subversion commit timestamp" else errx "Unable to determine sandbox type" diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index e72ed85ca5c2..82c4b7370fc4 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -2480,11 +2480,8 @@ OLD_FILES+=usr/share/man/man8/gpioctl.8.gz .endif .if ${MK_GNU_DIFF} == no -OLD_FILES+=usr/bin/diff OLD_FILES+=usr/bin/diff3 -OLD_FILES+=usr/share/man/man1/diff.1.gz OLD_FILES+=usr/share/man/man1/diff3.1.gz -OLD_FILES+=usr/share/man/man7/diff.7.gz .endif .if ${MK_GNU_GREP} == no @@ -6397,16 +6394,26 @@ OLD_FILES+=usr/sbin/ntpdate OLD_FILES+=usr/sbin/ntpdc OLD_FILES+=usr/sbin/ntptime OLD_FILES+=usr/sbin/sntp +OLD_FILES+=usr/share/doc/ntp/access.html OLD_FILES+=usr/share/doc/ntp/accopt.html OLD_FILES+=usr/share/doc/ntp/assoc.html OLD_FILES+=usr/share/doc/ntp/audio.html +OLD_FILES+=usr/share/doc/ntp/authentic.html OLD_FILES+=usr/share/doc/ntp/authopt.html +OLD_FILES+=usr/share/doc/ntp/autokey.html +OLD_FILES+=usr/share/doc/ntp/bugs.html OLD_FILES+=usr/share/doc/ntp/build.html +OLD_FILES+=usr/share/doc/ntp/clock.html OLD_FILES+=usr/share/doc/ntp/clockopt.html +OLD_FILES+=usr/share/doc/ntp/cluster.html +OLD_FILES+=usr/share/doc/ntp/comdex.html OLD_FILES+=usr/share/doc/ntp/config.html OLD_FILES+=usr/share/doc/ntp/confopt.html OLD_FILES+=usr/share/doc/ntp/copyright.html OLD_FILES+=usr/share/doc/ntp/debug.html +OLD_FILES+=usr/share/doc/ntp/decode.html +OLD_FILES+=usr/share/doc/ntp/discipline.html +OLD_FILES+=usr/share/doc/ntp/discover.html OLD_FILES+=usr/share/doc/ntp/driver1.html OLD_FILES+=usr/share/doc/ntp/driver10.html OLD_FILES+=usr/share/doc/ntp/driver11.html @@ -6435,34 +6442,227 @@ OLD_FILES+=usr/share/doc/ntp/driver6.html OLD_FILES+=usr/share/doc/ntp/driver7.html OLD_FILES+=usr/share/doc/ntp/driver8.html OLD_FILES+=usr/share/doc/ntp/driver9.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver1.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver10.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver11.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver12.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver16.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver18.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver19.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver20.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver22.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver26.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver27.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver28.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver29.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver3.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver30.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver31.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver32.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver33.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver34.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver35.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver36.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver37.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver38.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver39.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver4.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver40.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver42.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver43.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver44.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver45.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver46.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver5.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver6.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver7.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver8.html +OLD_FILES+=usr/share/doc/ntp/drivers/driver9.html +OLD_FILES+=usr/share/doc/ntp/drivers/icons/home.gif +OLD_FILES+=usr/share/doc/ntp/drivers/icons/mail2.gif +OLD_FILES+=usr/share/doc/ntp/drivers/mx4200data.html +OLD_FILES+=usr/share/doc/ntp/drivers/oncore-shmem.html +OLD_FILES+=usr/share/doc/ntp/drivers/scripts/footer.txt +OLD_FILES+=usr/share/doc/ntp/drivers/scripts/style.css +OLD_FILES+=usr/share/doc/ntp/drivers/tf582_4.html OLD_FILES+=usr/share/doc/ntp/extern.html +OLD_FILES+=usr/share/doc/ntp/filter.html OLD_FILES+=usr/share/doc/ntp/hints.html +OLD_FILES+=usr/share/doc/ntp/hints/a-ux +OLD_FILES+=usr/share/doc/ntp/hints/aix +OLD_FILES+=usr/share/doc/ntp/hints/bsdi +OLD_FILES+=usr/share/doc/ntp/hints/changes +OLD_FILES+=usr/share/doc/ntp/hints/decosf1 +OLD_FILES+=usr/share/doc/ntp/hints/decosf2 +OLD_FILES+=usr/share/doc/ntp/hints/freebsd +OLD_FILES+=usr/share/doc/ntp/hints/hpux +OLD_FILES+=usr/share/doc/ntp/hints/linux +OLD_FILES+=usr/share/doc/ntp/hints/mpeix +OLD_FILES+=usr/share/doc/ntp/hints/notes-xntp-v3 +OLD_FILES+=usr/share/doc/ntp/hints/parse +OLD_FILES+=usr/share/doc/ntp/hints/refclocks +OLD_FILES+=usr/share/doc/ntp/hints/rs6000 +OLD_FILES+=usr/share/doc/ntp/hints/sco.html +OLD_FILES+=usr/share/doc/ntp/hints/sgi +OLD_FILES+=usr/share/doc/ntp/hints/solaris-dosynctodr.html +OLD_FILES+=usr/share/doc/ntp/hints/solaris.html +OLD_FILES+=usr/share/doc/ntp/hints/solaris.xtra.4023118 +OLD_FILES+=usr/share/doc/ntp/hints/solaris.xtra.4095849 +OLD_FILES+=usr/share/doc/ntp/hints/solaris.xtra.S99ntpd +OLD_FILES+=usr/share/doc/ntp/hints/solaris.xtra.patchfreq +OLD_FILES+=usr/share/doc/ntp/hints/sun4 +OLD_FILES+=usr/share/doc/ntp/hints/svr4-dell +OLD_FILES+=usr/share/doc/ntp/hints/svr4_package +OLD_FILES+=usr/share/doc/ntp/hints/todo +OLD_FILES+=usr/share/doc/ntp/hints/vxworks.html +OLD_FILES+=usr/share/doc/ntp/hints/winnt.html +OLD_FILES+=usr/share/doc/ntp/history.html OLD_FILES+=usr/share/doc/ntp/howto.html +OLD_FILES+=usr/share/doc/ntp/huffpuff.html +OLD_FILES+=usr/share/doc/ntp/icons/home.gif +OLD_FILES+=usr/share/doc/ntp/icons/mail2.gif +OLD_FILES+=usr/share/doc/ntp/icons/sitemap.png OLD_FILES+=usr/share/doc/ntp/index.html OLD_FILES+=usr/share/doc/ntp/kern.html +OLD_FILES+=usr/share/doc/ntp/kernpps.html +OLD_FILES+=usr/share/doc/ntp/keygen.html OLD_FILES+=usr/share/doc/ntp/ldisc.html +OLD_FILES+=usr/share/doc/ntp/leap.html OLD_FILES+=usr/share/doc/ntp/measure.html OLD_FILES+=usr/share/doc/ntp/miscopt.html OLD_FILES+=usr/share/doc/ntp/monopt.html +OLD_FILES+=usr/share/doc/ntp/msyslog.html OLD_FILES+=usr/share/doc/ntp/mx4200data.html OLD_FILES+=usr/share/doc/ntp/notes.html +OLD_FILES+=usr/share/doc/ntp/ntp-keygen.html +OLD_FILES+=usr/share/doc/ntp/ntp-wait.html +OLD_FILES+=usr/share/doc/ntp/ntp.conf.html +OLD_FILES+=usr/share/doc/ntp/ntp.keys.html +OLD_FILES+=usr/share/doc/ntp/ntp_conf.html OLD_FILES+=usr/share/doc/ntp/ntpd.html OLD_FILES+=usr/share/doc/ntp/ntpdate.html OLD_FILES+=usr/share/doc/ntp/ntpdc.html +OLD_FILES+=usr/share/doc/ntp/ntpdsim.html +OLD_FILES+=usr/share/doc/ntp/ntpdsim_new.html OLD_FILES+=usr/share/doc/ntp/ntpq.html +OLD_FILES+=usr/share/doc/ntp/ntpsnmpd.html OLD_FILES+=usr/share/doc/ntp/ntptime.html OLD_FILES+=usr/share/doc/ntp/ntptrace.html +OLD_FILES+=usr/share/doc/ntp/orphan.html OLD_FILES+=usr/share/doc/ntp/parsedata.html OLD_FILES+=usr/share/doc/ntp/parsenew.html OLD_FILES+=usr/share/doc/ntp/patches.html +OLD_FILES+=usr/share/doc/ntp/pic/9400n.jpg +OLD_FILES+=usr/share/doc/ntp/pic/alice11.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice13.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice15.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice23.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice31.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice32.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice35.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice38.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice44.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice47.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice51.gif +OLD_FILES+=usr/share/doc/ntp/pic/alice61.gif +OLD_FILES+=usr/share/doc/ntp/pic/barnstable.gif +OLD_FILES+=usr/share/doc/ntp/pic/beaver.gif +OLD_FILES+=usr/share/doc/ntp/pic/boom3.gif +OLD_FILES+=usr/share/doc/ntp/pic/boom3a.gif +OLD_FILES+=usr/share/doc/ntp/pic/boom4.gif +OLD_FILES+=usr/share/doc/ntp/pic/broad.gif +OLD_FILES+=usr/share/doc/ntp/pic/bustardfly.gif +OLD_FILES+=usr/share/doc/ntp/pic/c51.jpg +OLD_FILES+=usr/share/doc/ntp/pic/description.jpg +OLD_FILES+=usr/share/doc/ntp/pic/discipline.gif +OLD_FILES+=usr/share/doc/ntp/pic/dogsnake.gif +OLD_FILES+=usr/share/doc/ntp/pic/driver29.gif +OLD_FILES+=usr/share/doc/ntp/pic/driver43_1.gif +OLD_FILES+=usr/share/doc/ntp/pic/driver43_2.jpg +OLD_FILES+=usr/share/doc/ntp/pic/fg6021.gif +OLD_FILES+=usr/share/doc/ntp/pic/fg6039.jpg +OLD_FILES+=usr/share/doc/ntp/pic/fig_3_1.gif +OLD_FILES+=usr/share/doc/ntp/pic/flatheads.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt1.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt2.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt3.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt4.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt5.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt6.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt7.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt8.gif +OLD_FILES+=usr/share/doc/ntp/pic/flt9.gif +OLD_FILES+=usr/share/doc/ntp/pic/freq1211.gif +OLD_FILES+=usr/share/doc/ntp/pic/gadget.jpg +OLD_FILES+=usr/share/doc/ntp/pic/gps167.jpg +OLD_FILES+=usr/share/doc/ntp/pic/group.gif +OLD_FILES+=usr/share/doc/ntp/pic/hornraba.gif +OLD_FILES+=usr/share/doc/ntp/pic/igclock.gif +OLD_FILES+=usr/share/doc/ntp/pic/neoclock4x.gif +OLD_FILES+=usr/share/doc/ntp/pic/offset1211.gif +OLD_FILES+=usr/share/doc/ntp/pic/oncore_evalbig.gif +OLD_FILES+=usr/share/doc/ntp/pic/oncore_remoteant.jpg +OLD_FILES+=usr/share/doc/ntp/pic/oncore_utplusbig.gif +OLD_FILES+=usr/share/doc/ntp/pic/oz2.gif +OLD_FILES+=usr/share/doc/ntp/pic/panda.gif +OLD_FILES+=usr/share/doc/ntp/pic/pd_om006.gif +OLD_FILES+=usr/share/doc/ntp/pic/pd_om011.gif +OLD_FILES+=usr/share/doc/ntp/pic/peer.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo1a.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo3a.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo4.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo5.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo6.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo7.gif +OLD_FILES+=usr/share/doc/ntp/pic/pogo8.gif +OLD_FILES+=usr/share/doc/ntp/pic/pzf509.jpg +OLD_FILES+=usr/share/doc/ntp/pic/pzf511.jpg +OLD_FILES+=usr/share/doc/ntp/pic/rabbit.gif +OLD_FILES+=usr/share/doc/ntp/pic/radio2.jpg +OLD_FILES+=usr/share/doc/ntp/pic/sheepb.jpg +OLD_FILES+=usr/share/doc/ntp/pic/stack1a.jpg +OLD_FILES+=usr/share/doc/ntp/pic/stats.gif +OLD_FILES+=usr/share/doc/ntp/pic/sx5.gif +OLD_FILES+=usr/share/doc/ntp/pic/thunderbolt.jpg +OLD_FILES+=usr/share/doc/ntp/pic/time1.gif +OLD_FILES+=usr/share/doc/ntp/pic/tonea.gif +OLD_FILES+=usr/share/doc/ntp/pic/tribeb.gif +OLD_FILES+=usr/share/doc/ntp/pic/wingdorothy.gif +OLD_FILES+=usr/share/doc/ntp/poll.html OLD_FILES+=usr/share/doc/ntp/porting.html OLD_FILES+=usr/share/doc/ntp/pps.html OLD_FILES+=usr/share/doc/ntp/prefer.html OLD_FILES+=usr/share/doc/ntp/quick.html +OLD_FILES+=usr/share/doc/ntp/rate.html OLD_FILES+=usr/share/doc/ntp/rdebug.html OLD_FILES+=usr/share/doc/ntp/refclock.html OLD_FILES+=usr/share/doc/ntp/release.html +OLD_FILES+=usr/share/doc/ntp/scripts/accopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/audio.txt +OLD_FILES+=usr/share/doc/ntp/scripts/authopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/clockopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/command.txt +OLD_FILES+=usr/share/doc/ntp/scripts/config.txt +OLD_FILES+=usr/share/doc/ntp/scripts/confopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/external.txt +OLD_FILES+=usr/share/doc/ntp/scripts/footer.txt +OLD_FILES+=usr/share/doc/ntp/scripts/hand.txt +OLD_FILES+=usr/share/doc/ntp/scripts/install.txt +OLD_FILES+=usr/share/doc/ntp/scripts/manual.txt +OLD_FILES+=usr/share/doc/ntp/scripts/misc.txt +OLD_FILES+=usr/share/doc/ntp/scripts/miscopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/monopt.txt +OLD_FILES+=usr/share/doc/ntp/scripts/refclock.txt +OLD_FILES+=usr/share/doc/ntp/scripts/special.txt +OLD_FILES+=usr/share/doc/ntp/scripts/style.css +OLD_FILES+=usr/share/doc/ntp/select.html +OLD_FILES+=usr/share/doc/ntp/sitemap.html +OLD_FILES+=usr/share/doc/ntp/sntp.html +OLD_FILES+=usr/share/doc/ntp/stats.html OLD_FILES+=usr/share/doc/ntp/tickadj.html +OLD_FILES+=usr/share/doc/ntp/warp.html +OLD_FILES+=usr/share/doc/ntp/xleave.html OLD_DIRS+=usr/share/doc/ntp/drivers OLD_DIRS+=usr/share/doc/ntp/drivers/scripts OLD_DIRS+=usr/share/doc/ntp/drivers/icons @@ -6904,20 +7104,6 @@ OLD_FILES+=usr/libexec/rbootd OLD_FILES+=usr/share/man/man8/rbootd.8.gz .endif -.if ${MK_RCMDS} == no -OLD_FILES+=bin/rcp -OLD_FILES+=rescue/rcp -OLD_FILES+=usr/bin/rlogin -OLD_FILES+=usr/bin/rsh -OLD_FILES+=usr/libexec/rlogind -OLD_FILES+=usr/libexec/rshd -OLD_FILES+=usr/share/man/man1/rcp.1.gz -OLD_FILES+=usr/share/man/man1/rlogin.1.gz -OLD_FILES+=usr/share/man/man1/rsh.1.gz -OLD_FILES+=usr/share/man/man8/rlogind.8.gz -OLD_FILES+=usr/share/man/man8/rshd.8.gz -.endif - .if ${MK_RESCUE} == no . if exists(${DESTDIR}${TESTSBASE}) RESCUE_DIRS!=find ${DESTDIR}/rescue -type d 2>/dev/null | sed -e 's,^${DESTDIR}/,,'; echo diff --git a/tools/build/options/WITHOUT_AUTO_OBJ b/tools/build/options/WITHOUT_AUTO_OBJ new file mode 100644 index 000000000000..69dd6c387bdb --- /dev/null +++ b/tools/build/options/WITHOUT_AUTO_OBJ @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Disable automatic creation of objdirs. +This is enabled by default if the wanted OBJDIR is writable by the current user. diff --git a/tools/build/options/WITHOUT_RCMDS b/tools/build/options/WITHOUT_RCMDS deleted file mode 100644 index fbde9399c44f..000000000000 --- a/tools/build/options/WITHOUT_RCMDS +++ /dev/null @@ -1,8 +0,0 @@ -.\" $FreeBSD$ -Disable building of the -.Bx -r-commands. -This includes -.Xr rlogin 1 , -.Xr rsh 1 , -etc. diff --git a/tools/build/options/WITHOUT_UNIFIED_OBJDIR b/tools/build/options/WITHOUT_UNIFIED_OBJDIR new file mode 100644 index 000000000000..355730c4a17e --- /dev/null +++ b/tools/build/options/WITHOUT_UNIFIED_OBJDIR @@ -0,0 +1,15 @@ +.\" $FreeBSD$ +Set to use the historical object directory format for +.Xr build 7 +targets. +For native-builds and builds done directly in sub-directories the format of +.Pa ${MAKEOBJDIRPREFIX}/${.CURDIR} +is used, +while for cross-builds +.Pa ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH}/${.CURDIR} +is used. +.Pp +This option is transitional and will be removed before the 12.0 release, +at which time +.va WITH_UNIFIED_OBJDIR +will be enabled permanently. diff --git a/tools/build/options/WITH_RCMDS b/tools/build/options/WITH_RCMDS deleted file mode 100644 index dddc4ecabac3..000000000000 --- a/tools/build/options/WITH_RCMDS +++ /dev/null @@ -1,8 +0,0 @@ -.\" $FreeBSD$ -Enable building of the -.Bx -r-commands. -This includes -.Xr rlogin 1 , -.Xr rsh 1 , -etc. diff --git a/tools/build/options/WITH_UNIFIED_OBJDIR b/tools/build/options/WITH_UNIFIED_OBJDIR new file mode 100644 index 000000000000..6efc01d09c5e --- /dev/null +++ b/tools/build/options/WITH_UNIFIED_OBJDIR @@ -0,0 +1,12 @@ +.\" $FreeBSD$ +Set to use the unified object directory format for +.Xr build 7 +targets. +For cross-builds, native-builds, and sub-directory builds, the format of +.Pa ${MAKEOBJDIRPREFIX}/${.CURDIR}/${TARGET}.${TARGET_ARCH} +is used. +.Pp +This option is transitional and will be removed before the 12.0 release, +at which time +.va WITH_UNIFIED_OBJDIR +will be enabled permanently. diff --git a/tools/build/options/makeman b/tools/build/options/makeman index c498bde26af4..c59c7179a856 100755 --- a/tools/build/options/makeman +++ b/tools/build/options/makeman @@ -44,7 +44,7 @@ no_targets() show_options() { - ALL_TARGETS=$(echo $(${make} targets | tail -n +2)) + ALL_TARGETS=$(echo $(${make} targets MK_AUTO_OBJ=no | tail -n +2)) rm -f $t/settings for target in ${ALL_TARGETS} ; do prev_opt= @@ -217,12 +217,10 @@ variable, which defaults to Some examples that may only be set in this file are .Va WITH_DIRDEPS_BUILD , and -.Va WITH_META_MODE -as they are environment-only variables. -Note that +.Va WITH_META_MODE , +and .Va MAKEOBJDIRPREFIX -may be set here only when using -.Va WITH_DIRDEPS_BUILD . +as they are environment-only variables. .Pp The values of variables are ignored regardless of their setting; even if they would be set to @@ -245,7 +243,7 @@ EOF show with SRC_ENV_CONF=/dev/null | sort | sed 's/$/=/' > $t/src.conf show settings SRC_ENV_CONF=$t/src.conf | sort > $t/config_WITH_ALL show without SRC_ENV_CONF=/dev/null | sort > $t/config_WITHOUT_ALL - env_only_options="$(${make} -V __ENV_ONLY_OPTIONS)" + env_only_options="$(${make} MK_AUTO_OBJ=no -V __ENV_ONLY_OPTIONS)" show_options | while read opt targets ; do diff --git a/tools/regression/include/stdatomic/Makefile.depend b/tools/regression/include/stdatomic/Makefile.depend index cda9eb2ca783..8d409f5263ac 100644 --- a/tools/regression/include/stdatomic/Makefile.depend +++ b/tools/regression/include/stdatomic/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tools/tools/ath/ath_ee_9300_print/Makefile.depend b/tools/tools/ath/ath_ee_9300_print/Makefile.depend index cda9eb2ca783..8d409f5263ac 100644 --- a/tools/tools/ath/ath_ee_9300_print/Makefile.depend +++ b/tools/tools/ath/ath_ee_9300_print/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tools/tools/build_option_survey/option_survey.sh b/tools/tools/build_option_survey/option_survey.sh index 3fee3164de0f..0e1b911ae0df 100644 --- a/tools/tools/build_option_survey/option_survey.sh +++ b/tools/tools/build_option_survey/option_survey.sh @@ -13,6 +13,7 @@ ODIR=/usr/obj/`pwd` FDIR=${ODIR}/files MNT=${ODIR}/_.mnt RDIR=${ODIR}/_.result +: ${MAKE_JOBS:="-j$(sysctl -n hw.ncpu)"} export ODIR MNT RDIR FDIR @@ -26,7 +27,7 @@ bw ( ) ( if [ $a -ne 0 ] ; then exit 1 fi - make -j 4 buildworld \ + make ${MAKE_JOBS} buildworld \ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ > ${FDIR}/_.bw 2>&1 a=$? @@ -34,7 +35,7 @@ bw ( ) ( if [ $a -ne 0 ] ; then exit 1 fi - make -j 4 buildkernel \ + make ${MAKE_JOBS} buildkernel \ KERNCONF=GENERIC \ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ > ${FDIR}/_.bk 2>&1 @@ -53,7 +54,7 @@ iw ( ) ( mount /dev/md${MDUNIT} ${MNT} cd ../../.. - make installworld \ + make ${MAKE_JOBS} installworld \ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ DESTDIR=${MNT} \ > ${FDIR}/_.iw 2>&1 @@ -73,7 +74,7 @@ iw ( ) ( exit 1 fi cd .. - make installkernel \ + make ${MAKE_JOBS} installkernel \ KERNCONF=GENERIC \ DESTDIR=${MNT} \ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ diff --git a/tools/tools/cd2dvd/cd2dvd.sh b/tools/tools/cd2dvd/cd2dvd.sh index c741344e73bd..8032c2f141f1 100755 --- a/tools/tools/cd2dvd/cd2dvd.sh +++ b/tools/tools/cd2dvd/cd2dvd.sh @@ -259,7 +259,7 @@ rm "${tmpdirout}"/cdrom.inf~ || exit 1 mkisofs -b boot/cdboot -no-emul-boot -r -J \ -V "FreeBSD_Install" \ - -publisher "The FreeBSD Project. http://www.freebsd.org/" \ + -publisher "The FreeBSD Project. https://www.freebsd.org/" \ -o ${DVDIMAGE} "${tmpdirout}" \ || exit 1 diff --git a/tools/tools/drm/radeon/mkregtable/Makefile.depend b/tools/tools/drm/radeon/mkregtable/Makefile.depend index cda9eb2ca783..8d409f5263ac 100644 --- a/tools/tools/drm/radeon/mkregtable/Makefile.depend +++ b/tools/tools/drm/radeon/mkregtable/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/tools/tools/fetchbench/fetchbench b/tools/tools/fetchbench/fetchbench new file mode 100755 index 000000000000..8cab0b23c758 --- /dev/null +++ b/tools/tools/fetchbench/fetchbench @@ -0,0 +1,76 @@ +#!/bin/sh +#- +# Copyright (c) 2017 Edward Tomasz Napierala +# All rights reserved. +# +# This software was developed by SRI International and the University of +# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) +# ("CTSRD"), as part of the DARPA CRASH research programme. +# +# 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 AUTHOR 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 AUTHOR 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. +# +# $FreeBSD$ + +# This is a simple HTTP benchmark. It works by running a number of fetch(1) +# instances in parallel, 10 by default, each performing a number of fetches, +# 100 by default, and then printing out the time it took. +# +# Example usage: ./fetchbench -i 2 -n 5 http://freebsd.org + +usage() +{ + cat <&2 +usage: fetchbench [-i number-of-instances] [-n fetches-per-instance] url +EOF + exit 1 +} + +NPROC=10 +NFETCH=100 + +while getopts "i:n:X" opt; do + case "$opt" in + i) NPROC="${OPTARG}" ;; + n) NFETCH="${OPTARG}" ;; + X) MEASURE_PLEASE=1 ;; + *) usage ;; + esac +done +shift $(($OPTIND - 1)) + +if [ $# -ne 1 ]; then + usage +fi + +URL="${1}" + +if [ -n "${MEASURE_PLEASE}" ]; then + for p in `/usr/bin/jot ${NPROC}`; do + ( + for f in `/usr/bin/jot ${NFETCH}`; do echo "${URL}"; done | /usr/bin/xargs /usr/bin/fetch -qo /dev/null + ) & + done + wait + echo -n "${0}: $((${NFETCH} * ${NPROC})) requests for ${URL}, spread among ${NPROC} parallel processes, in " +else + ( /usr/bin/time -h "${0}" -i "${NPROC}" -n "${NFETCH}" -X "${URL}" ) 2>&1 | sed -E 's/ //;s/ +/, /g' +fi diff --git a/tools/tools/locale/etc/charmaps.xml b/tools/tools/locale/etc/charmaps.xml index c1add0f91209..4cd5feaf2c4c 100644 --- a/tools/tools/locale/etc/charmaps.xml +++ b/tools/tools/locale/etc/charmaps.xml @@ -200,7 +200,7 @@ - diff --git a/tools/tools/locale/etc/common.UTF-8.src b/tools/tools/locale/etc/common.UTF-8.src index f54f9add3700..bebdb9180b56 100644 --- a/tools/tools/locale/etc/common.UTF-8.src +++ b/tools/tools/locale/etc/common.UTF-8.src @@ -3162,7 +3162,8 @@ alpha ;...;;/ ;/ ;...;;/ ;/ - + ;/ + graph ;...;;/ ;...;;/ ;/ @@ -3180,7 +3181,8 @@ graph ;...;;/ ;/ ;/ ;...;;/ - ;...; + ;...; +punct ********************************************************************** * 0x0A00 - 0x0A7F Gurmukhi @@ -3250,7 +3252,7 @@ alpha ;...;;/ ;/ ;/ ;...;;/ - + ;...; graph ;...;;/ ;...;;/ ;...;;/ @@ -3266,7 +3268,7 @@ graph ;...;;/ ;/ ;...;;/ ;...;;/ - + ;...; punct ********************************************************************** @@ -3433,7 +3435,7 @@ graph ;...;;/ ********************************************************************** * 0x0D00 - 0x0D7F Malayalam ********************************************************************** -alpha ;...;;/ +alpha ;...;;/ ;...;;/ ;...;;/ ;...;;/ @@ -3445,11 +3447,10 @@ alpha ;...;;/ ;...;;/ ;...;;/ ;...; -graph ;...;;/ +graph ;...;;/ ;...;;/ ;...;;/ - ;...;;/ - ;...;;/ + ;...;;/ ;...;;/ ;...;;/ ;...;;/ diff --git a/tools/tools/locale/etc/final-maps/map.UTF-8 b/tools/tools/locale/etc/final-maps/map.UTF-8 index b75b5ffc12fe..f303c1ecd6fb 100644 --- a/tools/tools/locale/etc/final-maps/map.UTF-8 +++ b/tools/tools/locale/etc/final-maps/map.UTF-8 @@ -2232,6 +2232,17 @@ CHARMAP \xE0\xA1\x9A \xE0\xA1\x9B \xE0\xA1\x9E + \xE0\xA1\xA0 + \xE0\xA1\xA1 + \xE0\xA1\xA2 + \xE0\xA1\xA3 + \xE0\xA1\xA4 + \xE0\xA1\xA5 + \xE0\xA1\xA6 + \xE0\xA1\xA7 + \xE0\xA1\xA8 + \xE0\xA1\xA9 + \xE0\xA1\xAA \xE0\xA2\xA0 \xE0\xA2\xA1 \xE0\xA2\xA2 @@ -2526,6 +2537,8 @@ CHARMAP \xE0\xA7\xB9 \xE0\xA7\xBA \xE0\xA7\xBB + \xE0\xA7\xBC + \xE0\xA7\xBD \xE0\xA8\x81 \xE0\xA8\x82 \xE0\xA8\x83 @@ -2690,6 +2703,12 @@ CHARMAP \xE0\xAB\xB0 \xE0\xAB\xB1 \xE0\xAB\xB9 + \xE0\xAB\xBA + \xE0\xAB\xBB + \xE0\xAB\xBC + \xE0\xAB\xBD + \xE0\xAB\xBE + \xE0\xAB\xBF \xE0\xAC\x81 \xE0\xAC\x82 \xE0\xAC\x83 @@ -3036,6 +3055,7 @@ CHARMAP \xE0\xB3\xAF \xE0\xB3\xB1 \xE0\xB3\xB2 + \xE0\xB4\x80 \xE0\xB4\x81 \xE0\xB4\x82 \xE0\xB4\x83 @@ -3091,6 +3111,8 @@ CHARMAP \xE0\xB4\xB8 \xE0\xB4\xB9 \xE0\xB4\xBA + \xE0\xB4\xBB + \xE0\xB4\xBC \xE0\xB4\xBD \xE0\xB4\xBE \xE0\xB4\xBF @@ -6573,6 +6595,7 @@ CHARMAP \xE1\xB3\xB4 \xE1\xB3\xB5 \xE1\xB3\xB6 + \xE1\xB3\xB7 \xE1\xB3\xB8 \xE1\xB3\xB9 \xE1\xB4\x80 @@ -6821,6 +6844,10 @@ CHARMAP \xE1\xB7\xB3 \xE1\xB7\xB4 \xE1\xB7\xB5 + \xE1\xB7\xB6 + \xE1\xB7\xB7 + \xE1\xB7\xB8 + \xE1\xB7\xB9 \xE1\xB7\xBB \xE1\xB7\xBC \xE1\xB7\xBD @@ -7499,6 +7526,7 @@ CHARMAP \xE2\x82\xBC \xE2\x82\xBD \xE2\x82\xBE + \xE2\x82\xBF \xE2\x83\x90 \xE2\x83\x91 \xE2\x83\x92 @@ -8295,6 +8323,7 @@ CHARMAP \xE2\x8F\xBC \xE2\x8F\xBD \xE2\x8F\xBE + \xE2\x8F\xBF \xE2\x90\x80 \xE2\x90\x81 \xE2\x90\x82 @@ -10243,6 +10272,7 @@ CHARMAP \xE2\xAF\x8F \xE2\xAF\x90 \xE2\xAF\x91 + \xE2\xAF\x92 \xE2\xAF\xAC \xE2\xAF\xAD \xE2\xAF\xAE @@ -10775,6 +10805,11 @@ CHARMAP \xE2\xB9\x82 \xE2\xB9\x83 \xE2\xB9\x84 + \xE2\xB9\x85 + \xE2\xB9\x86 + \xE2\xB9\x87 + \xE2\xB9\x88 + \xE2\xB9\x89 \xE2\xBA\x80 \xE2\xBA\x81 \xE2\xBA\x82 @@ -11410,6 +11445,7 @@ CHARMAP \xE3\x84\xAB \xE3\x84\xAC \xE3\x84\xAD + \xE3\x84\xAE \xE3\x84\xB1 \xE3\x84\xB2 \xE3\x84\xB3 @@ -39705,6 +39741,27 @@ CHARMAP \xE9\xBF\x93 \xE9\xBF\x94 \xE9\xBF\x95 + \xE9\xBF\x96 + \xE9\xBF\x97 + \xE9\xBF\x98 + \xE9\xBF\x99 + \xE9\xBF\x9A + \xE9\xBF\x9B + \xE9\xBF\x9C + \xE9\xBF\x9D + \xE9\xBF\x9E + \xE9\xBF\x9F + \xE9\xBF\xA0 + \xE9\xBF\xA1 + \xE9\xBF\xA2 + \xE9\xBF\xA3 + \xE9\xBF\xA4 + \xE9\xBF\xA5 + \xE9\xBF\xA6 + \xE9\xBF\xA7 + \xE9\xBF\xA8 + \xE9\xBF\xA9 + \xE9\xBF\xAA \xEA\x80\x80 \xEA\x80\x81 \xEA\x80\x82 @@ -62343,6 +62400,9 @@ CHARMAP \xF0\x90\x8C\xA1 \xF0\x90\x8C\xA2 \xF0\x90\x8C\xA3 + \xF0\x90\x8C\xAD + \xF0\x90\x8C\xAE + \xF0\x90\x8C\xAF \xF0\x90\x8C\xB0 \xF0\x90\x8C\xB1 \xF0\x90\x8C\xB2 @@ -65318,6 +65378,158 @@ CHARMAP \xF0\x91\xA3\xB1 \xF0\x91\xA3\xB2 \xF0\x91\xA3\xBF + \xF0\x91\xA8\x80 + \xF0\x91\xA8\x81 + \xF0\x91\xA8\x82 + \xF0\x91\xA8\x83 + \xF0\x91\xA8\x84 + \xF0\x91\xA8\x85 + \xF0\x91\xA8\x86 + \xF0\x91\xA8\x87 + \xF0\x91\xA8\x88 + \xF0\x91\xA8\x89 + \xF0\x91\xA8\x8A + \xF0\x91\xA8\x8B + \xF0\x91\xA8\x8C + \xF0\x91\xA8\x8D + \xF0\x91\xA8\x8E + \xF0\x91\xA8\x8F + \xF0\x91\xA8\x90 + \xF0\x91\xA8\x91 + \xF0\x91\xA8\x92 + \xF0\x91\xA8\x93 + \xF0\x91\xA8\x94 + \xF0\x91\xA8\x95 + \xF0\x91\xA8\x96 + \xF0\x91\xA8\x97 + \xF0\x91\xA8\x98 + \xF0\x91\xA8\x99 + \xF0\x91\xA8\x9A + \xF0\x91\xA8\x9B + \xF0\x91\xA8\x9C + \xF0\x91\xA8\x9D + \xF0\x91\xA8\x9E + \xF0\x91\xA8\x9F + \xF0\x91\xA8\xA0 + \xF0\x91\xA8\xA1 + \xF0\x91\xA8\xA2 + \xF0\x91\xA8\xA3 + \xF0\x91\xA8\xA4 + \xF0\x91\xA8\xA5 + \xF0\x91\xA8\xA6 + \xF0\x91\xA8\xA7 + \xF0\x91\xA8\xA8 + \xF0\x91\xA8\xA9 + \xF0\x91\xA8\xAA + \xF0\x91\xA8\xAB + \xF0\x91\xA8\xAC + \xF0\x91\xA8\xAD + \xF0\x91\xA8\xAE + \xF0\x91\xA8\xAF + \xF0\x91\xA8\xB0 + \xF0\x91\xA8\xB1 + \xF0\x91\xA8\xB2 + \xF0\x91\xA8\xB3 + \xF0\x91\xA8\xB4 + \xF0\x91\xA8\xB5 + \xF0\x91\xA8\xB6 + \xF0\x91\xA8\xB7 + \xF0\x91\xA8\xB8 + \xF0\x91\xA8\xB9 + \xF0\x91\xA8\xBA + \xF0\x91\xA8\xBB + \xF0\x91\xA8\xBC + \xF0\x91\xA8\xBD + \xF0\x91\xA8\xBE + \xF0\x91\xA8\xBF + \xF0\x91\xA9\x80 + \xF0\x91\xA9\x81 + \xF0\x91\xA9\x82 + \xF0\x91\xA9\x83 + \xF0\x91\xA9\x84 + \xF0\x91\xA9\x85 + \xF0\x91\xA9\x86 + \xF0\x91\xA9\x87 + \xF0\x91\xA9\x90 + \xF0\x91\xA9\x91 + \xF0\x91\xA9\x92 + \xF0\x91\xA9\x93 + \xF0\x91\xA9\x94 + \xF0\x91\xA9\x95 + \xF0\x91\xA9\x96 + \xF0\x91\xA9\x97 + \xF0\x91\xA9\x98 + \xF0\x91\xA9\x99 + \xF0\x91\xA9\x9A + \xF0\x91\xA9\x9B + \xF0\x91\xA9\x9C + \xF0\x91\xA9\x9D + \xF0\x91\xA9\x9E + \xF0\x91\xA9\x9F + \xF0\x91\xA9\xA0 + \xF0\x91\xA9\xA1 + \xF0\x91\xA9\xA2 + \xF0\x91\xA9\xA3 + \xF0\x91\xA9\xA4 + \xF0\x91\xA9\xA5 + \xF0\x91\xA9\xA6 + \xF0\x91\xA9\xA7 + \xF0\x91\xA9\xA8 + \xF0\x91\xA9\xA9 + \xF0\x91\xA9\xAA + \xF0\x91\xA9\xAB + \xF0\x91\xA9\xAC + \xF0\x91\xA9\xAD + \xF0\x91\xA9\xAE + \xF0\x91\xA9\xAF + \xF0\x91\xA9\xB0 + \xF0\x91\xA9\xB1 + \xF0\x91\xA9\xB2 + \xF0\x91\xA9\xB3 + \xF0\x91\xA9\xB4 + \xF0\x91\xA9\xB5 + \xF0\x91\xA9\xB6 + \xF0\x91\xA9\xB7 + \xF0\x91\xA9\xB8 + \xF0\x91\xA9\xB9 + \xF0\x91\xA9\xBA + \xF0\x91\xA9\xBB + \xF0\x91\xA9\xBC + \xF0\x91\xA9\xBD + \xF0\x91\xA9\xBE + \xF0\x91\xA9\xBF + \xF0\x91\xAA\x80 + \xF0\x91\xAA\x81 + \xF0\x91\xAA\x82 + \xF0\x91\xAA\x83 + \xF0\x91\xAA\x86 + \xF0\x91\xAA\x87 + \xF0\x91\xAA\x88 + \xF0\x91\xAA\x89 + \xF0\x91\xAA\x8A + \xF0\x91\xAA\x8B + \xF0\x91\xAA\x8C + \xF0\x91\xAA\x8D + \xF0\x91\xAA\x8E + \xF0\x91\xAA\x8F + \xF0\x91\xAA\x90 + \xF0\x91\xAA\x91 + \xF0\x91\xAA\x92 + \xF0\x91\xAA\x93 + \xF0\x91\xAA\x94 + \xF0\x91\xAA\x95 + \xF0\x91\xAA\x96 + \xF0\x91\xAA\x97 + \xF0\x91\xAA\x98 + \xF0\x91\xAA\x99 + \xF0\x91\xAA\x9A + \xF0\x91\xAA\x9B + \xF0\x91\xAA\x9C + \xF0\x91\xAA\x9E + \xF0\x91\xAA\x9F + \xF0\x91\xAA\xA0 + \xF0\x91\xAA\xA1 + \xF0\x91\xAA\xA2 \xF0\x91\xAB\x80 \xF0\x91\xAB\x81 \xF0\x91\xAB\x82 @@ -65540,6 +65752,81 @@ CHARMAP \xF0\x91\xB2\xB4 \xF0\x91\xB2\xB5 \xF0\x91\xB2\xB6 + \xF0\x91\xB4\x80 + \xF0\x91\xB4\x81 + \xF0\x91\xB4\x82 + \xF0\x91\xB4\x83 + \xF0\x91\xB4\x84 + \xF0\x91\xB4\x85 + \xF0\x91\xB4\x86 + \xF0\x91\xB4\x88 + \xF0\x91\xB4\x89 + \xF0\x91\xB4\x8B + \xF0\x91\xB4\x8C + \xF0\x91\xB4\x8D + \xF0\x91\xB4\x8E + \xF0\x91\xB4\x8F + \xF0\x91\xB4\x90 + \xF0\x91\xB4\x91 + \xF0\x91\xB4\x92 + \xF0\x91\xB4\x93 + \xF0\x91\xB4\x94 + \xF0\x91\xB4\x95 + \xF0\x91\xB4\x96 + \xF0\x91\xB4\x97 + \xF0\x91\xB4\x98 + \xF0\x91\xB4\x99 + \xF0\x91\xB4\x9A + \xF0\x91\xB4\x9B + \xF0\x91\xB4\x9C + \xF0\x91\xB4\x9D + \xF0\x91\xB4\x9E + \xF0\x91\xB4\x9F + \xF0\x91\xB4\xA0 + \xF0\x91\xB4\xA1 + \xF0\x91\xB4\xA2 + \xF0\x91\xB4\xA3 + \xF0\x91\xB4\xA4 + \xF0\x91\xB4\xA5 + \xF0\x91\xB4\xA6 + \xF0\x91\xB4\xA7 + \xF0\x91\xB4\xA8 + \xF0\x91\xB4\xA9 + \xF0\x91\xB4\xAA + \xF0\x91\xB4\xAB + \xF0\x91\xB4\xAC + \xF0\x91\xB4\xAD + \xF0\x91\xB4\xAE + \xF0\x91\xB4\xAF + \xF0\x91\xB4\xB0 + \xF0\x91\xB4\xB1 + \xF0\x91\xB4\xB2 + \xF0\x91\xB4\xB3 + \xF0\x91\xB4\xB4 + \xF0\x91\xB4\xB5 + \xF0\x91\xB4\xB6 + \xF0\x91\xB4\xBA + \xF0\x91\xB4\xBC + \xF0\x91\xB4\xBD + \xF0\x91\xB4\xBF + \xF0\x91\xB5\x80 + \xF0\x91\xB5\x81 + \xF0\x91\xB5\x82 + \xF0\x91\xB5\x83 + \xF0\x91\xB5\x84 + \xF0\x91\xB5\x85 + \xF0\x91\xB5\x86 + \xF0\x91\xB5\x87 + \xF0\x91\xB5\x90 + \xF0\x91\xB5\x91 + \xF0\x91\xB5\x92 + \xF0\x91\xB5\x93 + \xF0\x91\xB5\x94 + \xF0\x91\xB5\x95 + \xF0\x91\xB5\x96 + \xF0\x91\xB5\x97 + \xF0\x91\xB5\x98 + \xF0\x91\xB5\x99 \xF0\x92\x80\x80 \xF0\x92\x80\x81 \xF0\x92\x80\x82 @@ -69337,6 +69624,7 @@ CHARMAP \xF0\x96\xBE\x9E \xF0\x96\xBE\x9F \xF0\x96\xBF\xA0 + \xF0\x96\xBF\xA1 \xF0\x97\x80\x80 \xF0\x97\x80\x81 \xF0\x97\x80\x82 @@ -76219,6 +76507,687 @@ CHARMAP \xF0\x98\xAB\xB2 \xF0\x9B\x80\x80 \xF0\x9B\x80\x81 + \xF0\x9B\x80\x82 + \xF0\x9B\x80\x83 + \xF0\x9B\x80\x84 + \xF0\x9B\x80\x85 + \xF0\x9B\x80\x86 + \xF0\x9B\x80\x87 + \xF0\x9B\x80\x88 + \xF0\x9B\x80\x89 + \xF0\x9B\x80\x8A + \xF0\x9B\x80\x8B + \xF0\x9B\x80\x8C + \xF0\x9B\x80\x8D + \xF0\x9B\x80\x8E + \xF0\x9B\x80\x8F + \xF0\x9B\x80\x90 + \xF0\x9B\x80\x91 + \xF0\x9B\x80\x92 + \xF0\x9B\x80\x93 + \xF0\x9B\x80\x94 + \xF0\x9B\x80\x95 + \xF0\x9B\x80\x96 + \xF0\x9B\x80\x97 + \xF0\x9B\x80\x98 + \xF0\x9B\x80\x99 + \xF0\x9B\x80\x9A + \xF0\x9B\x80\x9B + \xF0\x9B\x80\x9C + \xF0\x9B\x80\x9D + \xF0\x9B\x80\x9E + \xF0\x9B\x80\x9F + \xF0\x9B\x80\xA0 + \xF0\x9B\x80\xA1 + \xF0\x9B\x80\xA2 + \xF0\x9B\x80\xA3 + \xF0\x9B\x80\xA4 + \xF0\x9B\x80\xA5 + \xF0\x9B\x80\xA6 + \xF0\x9B\x80\xA7 + \xF0\x9B\x80\xA8 + \xF0\x9B\x80\xA9 + \xF0\x9B\x80\xAA + \xF0\x9B\x80\xAB + \xF0\x9B\x80\xAC + \xF0\x9B\x80\xAD + \xF0\x9B\x80\xAE + \xF0\x9B\x80\xAF + \xF0\x9B\x80\xB0 + \xF0\x9B\x80\xB1 + \xF0\x9B\x80\xB2 + \xF0\x9B\x80\xB3 + \xF0\x9B\x80\xB4 + \xF0\x9B\x80\xB5 + \xF0\x9B\x80\xB6 + \xF0\x9B\x80\xB7 + \xF0\x9B\x80\xB8 + \xF0\x9B\x80\xB9 + \xF0\x9B\x80\xBA + \xF0\x9B\x80\xBB + \xF0\x9B\x80\xBC + \xF0\x9B\x80\xBD + \xF0\x9B\x80\xBE + \xF0\x9B\x80\xBF + \xF0\x9B\x81\x80 + \xF0\x9B\x81\x81 + \xF0\x9B\x81\x82 + \xF0\x9B\x81\x83 + \xF0\x9B\x81\x84 + \xF0\x9B\x81\x85 + \xF0\x9B\x81\x86 + \xF0\x9B\x81\x87 + \xF0\x9B\x81\x88 + \xF0\x9B\x81\x89 + \xF0\x9B\x81\x8A + \xF0\x9B\x81\x8B + \xF0\x9B\x81\x8C + \xF0\x9B\x81\x8D + \xF0\x9B\x81\x8E + \xF0\x9B\x81\x8F + \xF0\x9B\x81\x90 + \xF0\x9B\x81\x91 + \xF0\x9B\x81\x92 + \xF0\x9B\x81\x93 + \xF0\x9B\x81\x94 + \xF0\x9B\x81\x95 + \xF0\x9B\x81\x96 + \xF0\x9B\x81\x97 + \xF0\x9B\x81\x98 + \xF0\x9B\x81\x99 + \xF0\x9B\x81\x9A + \xF0\x9B\x81\x9B + \xF0\x9B\x81\x9C + \xF0\x9B\x81\x9D + \xF0\x9B\x81\x9E + \xF0\x9B\x81\x9F + \xF0\x9B\x81\xA0 + \xF0\x9B\x81\xA1 + \xF0\x9B\x81\xA2 + \xF0\x9B\x81\xA3 + \xF0\x9B\x81\xA4 + \xF0\x9B\x81\xA5 + \xF0\x9B\x81\xA6 + \xF0\x9B\x81\xA7 + \xF0\x9B\x81\xA8 + \xF0\x9B\x81\xA9 + \xF0\x9B\x81\xAA + \xF0\x9B\x81\xAB + \xF0\x9B\x81\xAC + \xF0\x9B\x81\xAD + \xF0\x9B\x81\xAE + \xF0\x9B\x81\xAF + \xF0\x9B\x81\xB0 + \xF0\x9B\x81\xB1 + \xF0\x9B\x81\xB2 + \xF0\x9B\x81\xB3 + \xF0\x9B\x81\xB4 + \xF0\x9B\x81\xB5 + \xF0\x9B\x81\xB6 + \xF0\x9B\x81\xB7 + \xF0\x9B\x81\xB8 + \xF0\x9B\x81\xB9 + \xF0\x9B\x81\xBA + \xF0\x9B\x81\xBB + \xF0\x9B\x81\xBC + \xF0\x9B\x81\xBD + \xF0\x9B\x81\xBE + \xF0\x9B\x81\xBF + \xF0\x9B\x82\x80 + \xF0\x9B\x82\x81 + \xF0\x9B\x82\x82 + \xF0\x9B\x82\x83 + \xF0\x9B\x82\x84 + \xF0\x9B\x82\x85 + \xF0\x9B\x82\x86 + \xF0\x9B\x82\x87 + \xF0\x9B\x82\x88 + \xF0\x9B\x82\x89 + \xF0\x9B\x82\x8A + \xF0\x9B\x82\x8B + \xF0\x9B\x82\x8C + \xF0\x9B\x82\x8D + \xF0\x9B\x82\x8E + \xF0\x9B\x82\x8F + \xF0\x9B\x82\x90 + \xF0\x9B\x82\x91 + \xF0\x9B\x82\x92 + \xF0\x9B\x82\x93 + \xF0\x9B\x82\x94 + \xF0\x9B\x82\x95 + \xF0\x9B\x82\x96 + \xF0\x9B\x82\x97 + \xF0\x9B\x82\x98 + \xF0\x9B\x82\x99 + \xF0\x9B\x82\x9A + \xF0\x9B\x82\x9B + \xF0\x9B\x82\x9C + \xF0\x9B\x82\x9D + \xF0\x9B\x82\x9E + \xF0\x9B\x82\x9F + \xF0\x9B\x82\xA0 + \xF0\x9B\x82\xA1 + \xF0\x9B\x82\xA2 + \xF0\x9B\x82\xA3 + \xF0\x9B\x82\xA4 + \xF0\x9B\x82\xA5 + \xF0\x9B\x82\xA6 + \xF0\x9B\x82\xA7 + \xF0\x9B\x82\xA8 + \xF0\x9B\x82\xA9 + \xF0\x9B\x82\xAA + \xF0\x9B\x82\xAB + \xF0\x9B\x82\xAC + \xF0\x9B\x82\xAD + \xF0\x9B\x82\xAE + \xF0\x9B\x82\xAF + \xF0\x9B\x82\xB0 + \xF0\x9B\x82\xB1 + \xF0\x9B\x82\xB2 + \xF0\x9B\x82\xB3 + \xF0\x9B\x82\xB4 + \xF0\x9B\x82\xB5 + \xF0\x9B\x82\xB6 + \xF0\x9B\x82\xB7 + \xF0\x9B\x82\xB8 + \xF0\x9B\x82\xB9 + \xF0\x9B\x82\xBA + \xF0\x9B\x82\xBB + \xF0\x9B\x82\xBC + \xF0\x9B\x82\xBD + \xF0\x9B\x82\xBE + \xF0\x9B\x82\xBF + \xF0\x9B\x83\x80 + \xF0\x9B\x83\x81 + \xF0\x9B\x83\x82 + \xF0\x9B\x83\x83 + \xF0\x9B\x83\x84 + \xF0\x9B\x83\x85 + \xF0\x9B\x83\x86 + \xF0\x9B\x83\x87 + \xF0\x9B\x83\x88 + \xF0\x9B\x83\x89 + \xF0\x9B\x83\x8A + \xF0\x9B\x83\x8B + \xF0\x9B\x83\x8C + \xF0\x9B\x83\x8D + \xF0\x9B\x83\x8E + \xF0\x9B\x83\x8F + \xF0\x9B\x83\x90 + \xF0\x9B\x83\x91 + \xF0\x9B\x83\x92 + \xF0\x9B\x83\x93 + \xF0\x9B\x83\x94 + \xF0\x9B\x83\x95 + \xF0\x9B\x83\x96 + \xF0\x9B\x83\x97 + \xF0\x9B\x83\x98 + \xF0\x9B\x83\x99 + \xF0\x9B\x83\x9A + \xF0\x9B\x83\x9B + \xF0\x9B\x83\x9C + \xF0\x9B\x83\x9D + \xF0\x9B\x83\x9E + \xF0\x9B\x83\x9F + \xF0\x9B\x83\xA0 + \xF0\x9B\x83\xA1 + \xF0\x9B\x83\xA2 + \xF0\x9B\x83\xA3 + \xF0\x9B\x83\xA4 + \xF0\x9B\x83\xA5 + \xF0\x9B\x83\xA6 + \xF0\x9B\x83\xA7 + \xF0\x9B\x83\xA8 + \xF0\x9B\x83\xA9 + \xF0\x9B\x83\xAA + \xF0\x9B\x83\xAB + \xF0\x9B\x83\xAC + \xF0\x9B\x83\xAD + \xF0\x9B\x83\xAE + \xF0\x9B\x83\xAF + \xF0\x9B\x83\xB0 + \xF0\x9B\x83\xB1 + \xF0\x9B\x83\xB2 + \xF0\x9B\x83\xB3 + \xF0\x9B\x83\xB4 + \xF0\x9B\x83\xB5 + \xF0\x9B\x83\xB6 + \xF0\x9B\x83\xB7 + \xF0\x9B\x83\xB8 + \xF0\x9B\x83\xB9 + \xF0\x9B\x83\xBA + \xF0\x9B\x83\xBB + \xF0\x9B\x83\xBC + \xF0\x9B\x83\xBD + \xF0\x9B\x83\xBE + \xF0\x9B\x83\xBF + \xF0\x9B\x84\x80 + \xF0\x9B\x84\x81 + \xF0\x9B\x84\x82 + \xF0\x9B\x84\x83 + \xF0\x9B\x84\x84 + \xF0\x9B\x84\x85 + \xF0\x9B\x84\x86 + \xF0\x9B\x84\x87 + \xF0\x9B\x84\x88 + \xF0\x9B\x84\x89 + \xF0\x9B\x84\x8A + \xF0\x9B\x84\x8B + \xF0\x9B\x84\x8C + \xF0\x9B\x84\x8D + \xF0\x9B\x84\x8E + \xF0\x9B\x84\x8F + \xF0\x9B\x84\x90 + \xF0\x9B\x84\x91 + \xF0\x9B\x84\x92 + \xF0\x9B\x84\x93 + \xF0\x9B\x84\x94 + \xF0\x9B\x84\x95 + \xF0\x9B\x84\x96 + \xF0\x9B\x84\x97 + \xF0\x9B\x84\x98 + \xF0\x9B\x84\x99 + \xF0\x9B\x84\x9A + \xF0\x9B\x84\x9B + \xF0\x9B\x84\x9C + \xF0\x9B\x84\x9D + \xF0\x9B\x84\x9E + \xF0\x9B\x85\xB0 + \xF0\x9B\x85\xB1 + \xF0\x9B\x85\xB2 + \xF0\x9B\x85\xB3 + \xF0\x9B\x85\xB4 + \xF0\x9B\x85\xB5 + \xF0\x9B\x85\xB6 + \xF0\x9B\x85\xB7 + \xF0\x9B\x85\xB8 + \xF0\x9B\x85\xB9 + \xF0\x9B\x85\xBA + \xF0\x9B\x85\xBB + \xF0\x9B\x85\xBC + \xF0\x9B\x85\xBD + \xF0\x9B\x85\xBE + \xF0\x9B\x85\xBF + \xF0\x9B\x86\x80 + \xF0\x9B\x86\x81 + \xF0\x9B\x86\x82 + \xF0\x9B\x86\x83 + \xF0\x9B\x86\x84 + \xF0\x9B\x86\x85 + \xF0\x9B\x86\x86 + \xF0\x9B\x86\x87 + \xF0\x9B\x86\x88 + \xF0\x9B\x86\x89 + \xF0\x9B\x86\x8A + \xF0\x9B\x86\x8B + \xF0\x9B\x86\x8C + \xF0\x9B\x86\x8D + \xF0\x9B\x86\x8E + \xF0\x9B\x86\x8F + \xF0\x9B\x86\x90 + \xF0\x9B\x86\x91 + \xF0\x9B\x86\x92 + \xF0\x9B\x86\x93 + \xF0\x9B\x86\x94 + \xF0\x9B\x86\x95 + \xF0\x9B\x86\x96 + \xF0\x9B\x86\x97 + \xF0\x9B\x86\x98 + \xF0\x9B\x86\x99 + \xF0\x9B\x86\x9A + \xF0\x9B\x86\x9B + \xF0\x9B\x86\x9C + \xF0\x9B\x86\x9D + \xF0\x9B\x86\x9E + \xF0\x9B\x86\x9F + \xF0\x9B\x86\xA0 + \xF0\x9B\x86\xA1 + \xF0\x9B\x86\xA2 + \xF0\x9B\x86\xA3 + \xF0\x9B\x86\xA4 + \xF0\x9B\x86\xA5 + \xF0\x9B\x86\xA6 + \xF0\x9B\x86\xA7 + \xF0\x9B\x86\xA8 + \xF0\x9B\x86\xA9 + \xF0\x9B\x86\xAA + \xF0\x9B\x86\xAB + \xF0\x9B\x86\xAC + \xF0\x9B\x86\xAD + \xF0\x9B\x86\xAE + \xF0\x9B\x86\xAF + \xF0\x9B\x86\xB0 + \xF0\x9B\x86\xB1 + \xF0\x9B\x86\xB2 + \xF0\x9B\x86\xB3 + \xF0\x9B\x86\xB4 + \xF0\x9B\x86\xB5 + \xF0\x9B\x86\xB6 + \xF0\x9B\x86\xB7 + \xF0\x9B\x86\xB8 + \xF0\x9B\x86\xB9 + \xF0\x9B\x86\xBA + \xF0\x9B\x86\xBB + \xF0\x9B\x86\xBC + \xF0\x9B\x86\xBD + \xF0\x9B\x86\xBE + \xF0\x9B\x86\xBF + \xF0\x9B\x87\x80 + \xF0\x9B\x87\x81 + \xF0\x9B\x87\x82 + \xF0\x9B\x87\x83 + \xF0\x9B\x87\x84 + \xF0\x9B\x87\x85 + \xF0\x9B\x87\x86 + \xF0\x9B\x87\x87 + \xF0\x9B\x87\x88 + \xF0\x9B\x87\x89 + \xF0\x9B\x87\x8A + \xF0\x9B\x87\x8B + \xF0\x9B\x87\x8C + \xF0\x9B\x87\x8D + \xF0\x9B\x87\x8E + \xF0\x9B\x87\x8F + \xF0\x9B\x87\x90 + \xF0\x9B\x87\x91 + \xF0\x9B\x87\x92 + \xF0\x9B\x87\x93 + \xF0\x9B\x87\x94 + \xF0\x9B\x87\x95 + \xF0\x9B\x87\x96 + \xF0\x9B\x87\x97 + \xF0\x9B\x87\x98 + \xF0\x9B\x87\x99 + \xF0\x9B\x87\x9A + \xF0\x9B\x87\x9B + \xF0\x9B\x87\x9C + \xF0\x9B\x87\x9D + \xF0\x9B\x87\x9E + \xF0\x9B\x87\x9F + \xF0\x9B\x87\xA0 + \xF0\x9B\x87\xA1 + \xF0\x9B\x87\xA2 + \xF0\x9B\x87\xA3 + \xF0\x9B\x87\xA4 + \xF0\x9B\x87\xA5 + \xF0\x9B\x87\xA6 + \xF0\x9B\x87\xA7 + \xF0\x9B\x87\xA8 + \xF0\x9B\x87\xA9 + \xF0\x9B\x87\xAA + \xF0\x9B\x87\xAB + \xF0\x9B\x87\xAC + \xF0\x9B\x87\xAD + \xF0\x9B\x87\xAE + \xF0\x9B\x87\xAF + \xF0\x9B\x87\xB0 + \xF0\x9B\x87\xB1 + \xF0\x9B\x87\xB2 + \xF0\x9B\x87\xB3 + \xF0\x9B\x87\xB4 + \xF0\x9B\x87\xB5 + \xF0\x9B\x87\xB6 + \xF0\x9B\x87\xB7 + \xF0\x9B\x87\xB8 + \xF0\x9B\x87\xB9 + \xF0\x9B\x87\xBA + \xF0\x9B\x87\xBB + \xF0\x9B\x87\xBC + \xF0\x9B\x87\xBD + \xF0\x9B\x87\xBE + \xF0\x9B\x87\xBF + \xF0\x9B\x88\x80 + \xF0\x9B\x88\x81 + \xF0\x9B\x88\x82 + \xF0\x9B\x88\x83 + \xF0\x9B\x88\x84 + \xF0\x9B\x88\x85 + \xF0\x9B\x88\x86 + \xF0\x9B\x88\x87 + \xF0\x9B\x88\x88 + \xF0\x9B\x88\x89 + \xF0\x9B\x88\x8A + \xF0\x9B\x88\x8B + \xF0\x9B\x88\x8C + \xF0\x9B\x88\x8D + \xF0\x9B\x88\x8E + \xF0\x9B\x88\x8F + \xF0\x9B\x88\x90 + \xF0\x9B\x88\x91 + \xF0\x9B\x88\x92 + \xF0\x9B\x88\x93 + \xF0\x9B\x88\x94 + \xF0\x9B\x88\x95 + \xF0\x9B\x88\x96 + \xF0\x9B\x88\x97 + \xF0\x9B\x88\x98 + \xF0\x9B\x88\x99 + \xF0\x9B\x88\x9A + \xF0\x9B\x88\x9B + \xF0\x9B\x88\x9C + \xF0\x9B\x88\x9D + \xF0\x9B\x88\x9E + \xF0\x9B\x88\x9F + \xF0\x9B\x88\xA0 + \xF0\x9B\x88\xA1 + \xF0\x9B\x88\xA2 + \xF0\x9B\x88\xA3 + \xF0\x9B\x88\xA4 + \xF0\x9B\x88\xA5 + \xF0\x9B\x88\xA6 + \xF0\x9B\x88\xA7 + \xF0\x9B\x88\xA8 + \xF0\x9B\x88\xA9 + \xF0\x9B\x88\xAA + \xF0\x9B\x88\xAB + \xF0\x9B\x88\xAC + \xF0\x9B\x88\xAD + \xF0\x9B\x88\xAE + \xF0\x9B\x88\xAF + \xF0\x9B\x88\xB0 + \xF0\x9B\x88\xB1 + \xF0\x9B\x88\xB2 + \xF0\x9B\x88\xB3 + \xF0\x9B\x88\xB4 + \xF0\x9B\x88\xB5 + \xF0\x9B\x88\xB6 + \xF0\x9B\x88\xB7 + \xF0\x9B\x88\xB8 + \xF0\x9B\x88\xB9 + \xF0\x9B\x88\xBA + \xF0\x9B\x88\xBB + \xF0\x9B\x88\xBC + \xF0\x9B\x88\xBD + \xF0\x9B\x88\xBE + \xF0\x9B\x88\xBF + \xF0\x9B\x89\x80 + \xF0\x9B\x89\x81 + \xF0\x9B\x89\x82 + \xF0\x9B\x89\x83 + \xF0\x9B\x89\x84 + \xF0\x9B\x89\x85 + \xF0\x9B\x89\x86 + \xF0\x9B\x89\x87 + \xF0\x9B\x89\x88 + \xF0\x9B\x89\x89 + \xF0\x9B\x89\x8A + \xF0\x9B\x89\x8B + \xF0\x9B\x89\x8C + \xF0\x9B\x89\x8D + \xF0\x9B\x89\x8E + \xF0\x9B\x89\x8F + \xF0\x9B\x89\x90 + \xF0\x9B\x89\x91 + \xF0\x9B\x89\x92 + \xF0\x9B\x89\x93 + \xF0\x9B\x89\x94 + \xF0\x9B\x89\x95 + \xF0\x9B\x89\x96 + \xF0\x9B\x89\x97 + \xF0\x9B\x89\x98 + \xF0\x9B\x89\x99 + \xF0\x9B\x89\x9A + \xF0\x9B\x89\x9B + \xF0\x9B\x89\x9C + \xF0\x9B\x89\x9D + \xF0\x9B\x89\x9E + \xF0\x9B\x89\x9F + \xF0\x9B\x89\xA0 + \xF0\x9B\x89\xA1 + \xF0\x9B\x89\xA2 + \xF0\x9B\x89\xA3 + \xF0\x9B\x89\xA4 + \xF0\x9B\x89\xA5 + \xF0\x9B\x89\xA6 + \xF0\x9B\x89\xA7 + \xF0\x9B\x89\xA8 + \xF0\x9B\x89\xA9 + \xF0\x9B\x89\xAA + \xF0\x9B\x89\xAB + \xF0\x9B\x89\xAC + \xF0\x9B\x89\xAD + \xF0\x9B\x89\xAE + \xF0\x9B\x89\xAF + \xF0\x9B\x89\xB0 + \xF0\x9B\x89\xB1 + \xF0\x9B\x89\xB2 + \xF0\x9B\x89\xB3 + \xF0\x9B\x89\xB4 + \xF0\x9B\x89\xB5 + \xF0\x9B\x89\xB6 + \xF0\x9B\x89\xB7 + \xF0\x9B\x89\xB8 + \xF0\x9B\x89\xB9 + \xF0\x9B\x89\xBA + \xF0\x9B\x89\xBB + \xF0\x9B\x89\xBC + \xF0\x9B\x89\xBD + \xF0\x9B\x89\xBE + \xF0\x9B\x89\xBF + \xF0\x9B\x8A\x80 + \xF0\x9B\x8A\x81 + \xF0\x9B\x8A\x82 + \xF0\x9B\x8A\x83 + \xF0\x9B\x8A\x84 + \xF0\x9B\x8A\x85 + \xF0\x9B\x8A\x86 + \xF0\x9B\x8A\x87 + \xF0\x9B\x8A\x88 + \xF0\x9B\x8A\x89 + \xF0\x9B\x8A\x8A + \xF0\x9B\x8A\x8B + \xF0\x9B\x8A\x8C + \xF0\x9B\x8A\x8D + \xF0\x9B\x8A\x8E + \xF0\x9B\x8A\x8F + \xF0\x9B\x8A\x90 + \xF0\x9B\x8A\x91 + \xF0\x9B\x8A\x92 + \xF0\x9B\x8A\x93 + \xF0\x9B\x8A\x94 + \xF0\x9B\x8A\x95 + \xF0\x9B\x8A\x96 + \xF0\x9B\x8A\x97 + \xF0\x9B\x8A\x98 + \xF0\x9B\x8A\x99 + \xF0\x9B\x8A\x9A + \xF0\x9B\x8A\x9B + \xF0\x9B\x8A\x9C + \xF0\x9B\x8A\x9D + \xF0\x9B\x8A\x9E + \xF0\x9B\x8A\x9F + \xF0\x9B\x8A\xA0 + \xF0\x9B\x8A\xA1 + \xF0\x9B\x8A\xA2 + \xF0\x9B\x8A\xA3 + \xF0\x9B\x8A\xA4 + \xF0\x9B\x8A\xA5 + \xF0\x9B\x8A\xA6 + \xF0\x9B\x8A\xA7 + \xF0\x9B\x8A\xA8 + \xF0\x9B\x8A\xA9 + \xF0\x9B\x8A\xAA + \xF0\x9B\x8A\xAB + \xF0\x9B\x8A\xAC + \xF0\x9B\x8A\xAD + \xF0\x9B\x8A\xAE + \xF0\x9B\x8A\xAF + \xF0\x9B\x8A\xB0 + \xF0\x9B\x8A\xB1 + \xF0\x9B\x8A\xB2 + \xF0\x9B\x8A\xB3 + \xF0\x9B\x8A\xB4 + \xF0\x9B\x8A\xB5 + \xF0\x9B\x8A\xB6 + \xF0\x9B\x8A\xB7 + \xF0\x9B\x8A\xB8 + \xF0\x9B\x8A\xB9 + \xF0\x9B\x8A\xBA + \xF0\x9B\x8A\xBB + \xF0\x9B\x8A\xBC + \xF0\x9B\x8A\xBD + \xF0\x9B\x8A\xBE + \xF0\x9B\x8A\xBF + \xF0\x9B\x8B\x80 + \xF0\x9B\x8B\x81 + \xF0\x9B\x8B\x82 + \xF0\x9B\x8B\x83 + \xF0\x9B\x8B\x84 + \xF0\x9B\x8B\x85 + \xF0\x9B\x8B\x86 + \xF0\x9B\x8B\x87 + \xF0\x9B\x8B\x88 + \xF0\x9B\x8B\x89 + \xF0\x9B\x8B\x8A + \xF0\x9B\x8B\x8B + \xF0\x9B\x8B\x8C + \xF0\x9B\x8B\x8D + \xF0\x9B\x8B\x8E + \xF0\x9B\x8B\x8F + \xF0\x9B\x8B\x90 + \xF0\x9B\x8B\x91 + \xF0\x9B\x8B\x92 + \xF0\x9B\x8B\x93 + \xF0\x9B\x8B\x94 + \xF0\x9B\x8B\x95 + \xF0\x9B\x8B\x96 + \xF0\x9B\x8B\x97 + \xF0\x9B\x8B\x98 + \xF0\x9B\x8B\x99 + \xF0\x9B\x8B\x9A + \xF0\x9B\x8B\x9B + \xF0\x9B\x8B\x9C + \xF0\x9B\x8B\x9D + \xF0\x9B\x8B\x9E + \xF0\x9B\x8B\x9F + \xF0\x9B\x8B\xA0 + \xF0\x9B\x8B\xA1 + \xF0\x9B\x8B\xA2 + \xF0\x9B\x8B\xA3 + \xF0\x9B\x8B\xA4 + \xF0\x9B\x8B\xA5 + \xF0\x9B\x8B\xA6 + \xF0\x9B\x8B\xA7 + \xF0\x9B\x8B\xA8 + \xF0\x9B\x8B\xA9 + \xF0\x9B\x8B\xAA + \xF0\x9B\x8B\xAB + \xF0\x9B\x8B\xAC + \xF0\x9B\x8B\xAD + \xF0\x9B\x8B\xAE + \xF0\x9B\x8B\xAF + \xF0\x9B\x8B\xB0 + \xF0\x9B\x8B\xB1 + \xF0\x9B\x8B\xB2 + \xF0\x9B\x8B\xB3 + \xF0\x9B\x8B\xB4 + \xF0\x9B\x8B\xB5 + \xF0\x9B\x8B\xB6 + \xF0\x9B\x8B\xB7 + \xF0\x9B\x8B\xB8 + \xF0\x9B\x8B\xB9 + \xF0\x9B\x8B\xBA + \xF0\x9B\x8B\xBB \xF0\x9B\xB0\x80 \xF0\x9B\xB0\x81 \xF0\x9B\xB0\x82 @@ -79642,6 +80611,12 @@ CHARMAP \xF0\x9F\x89\x88 \xF0\x9F\x89\x90 \xF0\x9F\x89\x91 + \xF0\x9F\x89\xA0 + \xF0\x9F\x89\xA1 + \xF0\x9F\x89\xA2 + \xF0\x9F\x89\xA3 + \xF0\x9F\x89\xA4 + \xF0\x9F\x89\xA5 \xF0\x9F\x8C\x80 \xF0\x9F\x8C\x81 \xF0\x9F\x8C\x82 @@ -80621,6 +81596,8 @@ CHARMAP \xF0\x9F\x9B\x90 \xF0\x9F\x9B\x91 \xF0\x9F\x9B\x92 + \xF0\x9F\x9B\x93 + \xF0\x9F\x9B\x94 \xF0\x9F\x9B\xA0 \xF0\x9F\x9B\xA1 \xF0\x9F\x9B\xA2 @@ -80641,6 +81618,8 @@ CHARMAP \xF0\x9F\x9B\xB4 \xF0\x9F\x9B\xB5 \xF0\x9F\x9B\xB6 + \xF0\x9F\x9B\xB7 + \xF0\x9F\x9B\xB8 \xF0\x9F\x9C\x80 \xF0\x9F\x9C\x81 \xF0\x9F\x9C\x82 @@ -80990,6 +81969,18 @@ CHARMAP \xF0\x9F\xA2\xAB \xF0\x9F\xA2\xAC \xF0\x9F\xA2\xAD + \xF0\x9F\xA4\x80 + \xF0\x9F\xA4\x81 + \xF0\x9F\xA4\x82 + \xF0\x9F\xA4\x83 + \xF0\x9F\xA4\x84 + \xF0\x9F\xA4\x85 + \xF0\x9F\xA4\x86 + \xF0\x9F\xA4\x87 + \xF0\x9F\xA4\x88 + \xF0\x9F\xA4\x89 + \xF0\x9F\xA4\x8A + \xF0\x9F\xA4\x8B \xF0\x9F\xA4\x90 \xF0\x9F\xA4\x91 \xF0\x9F\xA4\x92 @@ -81005,6 +81996,7 @@ CHARMAP \xF0\x9F\xA4\x9C \xF0\x9F\xA4\x9D \xF0\x9F\xA4\x9E + \xF0\x9F\xA4\x9F \xF0\x9F\xA4\xA0 \xF0\x9F\xA4\xA1 \xF0\x9F\xA4\xA2 @@ -81013,7 +82005,17 @@ CHARMAP \xF0\x9F\xA4\xA5 \xF0\x9F\xA4\xA6 \xF0\x9F\xA4\xA7 + \xF0\x9F\xA4\xA8 + \xF0\x9F\xA4\xA9 + \xF0\x9F\xA4\xAA + \xF0\x9F\xA4\xAB + \xF0\x9F\xA4\xAC + \xF0\x9F\xA4\xAD + \xF0\x9F\xA4\xAE + \xF0\x9F\xA4\xAF \xF0\x9F\xA4\xB0 + \xF0\x9F\xA4\xB1 + \xF0\x9F\xA4\xB2 \xF0\x9F\xA4\xB3 \xF0\x9F\xA4\xB4 \xF0\x9F\xA4\xB5 @@ -81038,6 +82040,7 @@ CHARMAP \xF0\x9F\xA5\x89 \xF0\x9F\xA5\x8A \xF0\x9F\xA5\x8B + \xF0\x9F\xA5\x8C \xF0\x9F\xA5\x90 \xF0\x9F\xA5\x91 \xF0\x9F\xA5\x92 @@ -81053,6 +82056,19 @@ CHARMAP \xF0\x9F\xA5\x9C \xF0\x9F\xA5\x9D \xF0\x9F\xA5\x9E + \xF0\x9F\xA5\x9F + \xF0\x9F\xA5\xA0 + \xF0\x9F\xA5\xA1 + \xF0\x9F\xA5\xA2 + \xF0\x9F\xA5\xA3 + \xF0\x9F\xA5\xA4 + \xF0\x9F\xA5\xA5 + \xF0\x9F\xA5\xA6 + \xF0\x9F\xA5\xA7 + \xF0\x9F\xA5\xA8 + \xF0\x9F\xA5\xA9 + \xF0\x9F\xA5\xAA + \xF0\x9F\xA5\xAB \xF0\x9F\xA6\x80 \xF0\x9F\xA6\x81 \xF0\x9F\xA6\x82 @@ -81071,7 +82087,36 @@ CHARMAP \xF0\x9F\xA6\x8F \xF0\x9F\xA6\x90 \xF0\x9F\xA6\x91 + \xF0\x9F\xA6\x92 + \xF0\x9F\xA6\x93 + \xF0\x9F\xA6\x94 + \xF0\x9F\xA6\x95 + \xF0\x9F\xA6\x96 + \xF0\x9F\xA6\x97 \xF0\x9F\xA7\x80 + \xF0\x9F\xA7\x90 + \xF0\x9F\xA7\x91 + \xF0\x9F\xA7\x92 + \xF0\x9F\xA7\x93 + \xF0\x9F\xA7\x94 + \xF0\x9F\xA7\x95 + \xF0\x9F\xA7\x96 + \xF0\x9F\xA7\x97 + \xF0\x9F\xA7\x98 + \xF0\x9F\xA7\x99 + \xF0\x9F\xA7\x9A + \xF0\x9F\xA7\x9B + \xF0\x9F\xA7\x9C + \xF0\x9F\xA7\x9D + \xF0\x9F\xA7\x9E + \xF0\x9F\xA7\x9F + \xF0\x9F\xA7\xA0 + \xF0\x9F\xA7\xA1 + \xF0\x9F\xA7\xA2 + \xF0\x9F\xA7\xA3 + \xF0\x9F\xA7\xA4 + \xF0\x9F\xA7\xA5 + \xF0\x9F\xA7\xA6 \xF0\xA0\x80\x80 \xF0\xA0\x80\x81 \xF0\xA0\x80\x82 @@ -133916,6 +134961,7479 @@ CHARMAP \xF0\xAC\xBA\x9F \xF0\xAC\xBA\xA0 \xF0\xAC\xBA\xA1 + \xF0\xAC\xBA\xB0 + \xF0\xAC\xBA\xB1 + \xF0\xAC\xBA\xB2 + \xF0\xAC\xBA\xB3 + \xF0\xAC\xBA\xB4 + \xF0\xAC\xBA\xB5 + \xF0\xAC\xBA\xB6 + \xF0\xAC\xBA\xB7 + \xF0\xAC\xBA\xB8 + \xF0\xAC\xBA\xB9 + \xF0\xAC\xBA\xBA + \xF0\xAC\xBA\xBB + \xF0\xAC\xBA\xBC + \xF0\xAC\xBA\xBD + \xF0\xAC\xBA\xBE + \xF0\xAC\xBA\xBF + \xF0\xAC\xBB\x80 + \xF0\xAC\xBB\x81 + \xF0\xAC\xBB\x82 + \xF0\xAC\xBB\x83 + \xF0\xAC\xBB\x84 + \xF0\xAC\xBB\x85 + \xF0\xAC\xBB\x86 + \xF0\xAC\xBB\x87 + \xF0\xAC\xBB\x88 + \xF0\xAC\xBB\x89 + \xF0\xAC\xBB\x8A + \xF0\xAC\xBB\x8B + \xF0\xAC\xBB\x8C + \xF0\xAC\xBB\x8D + \xF0\xAC\xBB\x8E + \xF0\xAC\xBB\x8F + \xF0\xAC\xBB\x90 + \xF0\xAC\xBB\x91 + \xF0\xAC\xBB\x92 + \xF0\xAC\xBB\x93 + \xF0\xAC\xBB\x94 + \xF0\xAC\xBB\x95 + \xF0\xAC\xBB\x96 + \xF0\xAC\xBB\x97 + \xF0\xAC\xBB\x98 + \xF0\xAC\xBB\x99 + \xF0\xAC\xBB\x9A + \xF0\xAC\xBB\x9B + \xF0\xAC\xBB\x9C + \xF0\xAC\xBB\x9D + \xF0\xAC\xBB\x9E + \xF0\xAC\xBB\x9F + \xF0\xAC\xBB\xA0 + \xF0\xAC\xBB\xA1 + \xF0\xAC\xBB\xA2 + \xF0\xAC\xBB\xA3 + \xF0\xAC\xBB\xA4 + \xF0\xAC\xBB\xA5 + \xF0\xAC\xBB\xA6 + \xF0\xAC\xBB\xA7 + \xF0\xAC\xBB\xA8 + \xF0\xAC\xBB\xA9 + \xF0\xAC\xBB\xAA + \xF0\xAC\xBB\xAB + \xF0\xAC\xBB\xAC + \xF0\xAC\xBB\xAD + \xF0\xAC\xBB\xAE + \xF0\xAC\xBB\xAF + \xF0\xAC\xBB\xB0 + \xF0\xAC\xBB\xB1 + \xF0\xAC\xBB\xB2 + \xF0\xAC\xBB\xB3 + \xF0\xAC\xBB\xB4 + \xF0\xAC\xBB\xB5 + \xF0\xAC\xBB\xB6 + \xF0\xAC\xBB\xB7 + \xF0\xAC\xBB\xB8 + \xF0\xAC\xBB\xB9 + \xF0\xAC\xBB\xBA + \xF0\xAC\xBB\xBB + \xF0\xAC\xBB\xBC + \xF0\xAC\xBB\xBD + \xF0\xAC\xBB\xBE + \xF0\xAC\xBB\xBF + \xF0\xAC\xBC\x80 + \xF0\xAC\xBC\x81 + \xF0\xAC\xBC\x82 + \xF0\xAC\xBC\x83 + \xF0\xAC\xBC\x84 + \xF0\xAC\xBC\x85 + \xF0\xAC\xBC\x86 + \xF0\xAC\xBC\x87 + \xF0\xAC\xBC\x88 + \xF0\xAC\xBC\x89 + \xF0\xAC\xBC\x8A + \xF0\xAC\xBC\x8B + \xF0\xAC\xBC\x8C + \xF0\xAC\xBC\x8D + \xF0\xAC\xBC\x8E + \xF0\xAC\xBC\x8F + \xF0\xAC\xBC\x90 + \xF0\xAC\xBC\x91 + \xF0\xAC\xBC\x92 + \xF0\xAC\xBC\x93 + \xF0\xAC\xBC\x94 + \xF0\xAC\xBC\x95 + \xF0\xAC\xBC\x96 + \xF0\xAC\xBC\x97 + \xF0\xAC\xBC\x98 + \xF0\xAC\xBC\x99 + \xF0\xAC\xBC\x9A + \xF0\xAC\xBC\x9B + \xF0\xAC\xBC\x9C + \xF0\xAC\xBC\x9D + \xF0\xAC\xBC\x9E + \xF0\xAC\xBC\x9F + \xF0\xAC\xBC\xA0 + \xF0\xAC\xBC\xA1 + \xF0\xAC\xBC\xA2 + \xF0\xAC\xBC\xA3 + \xF0\xAC\xBC\xA4 + \xF0\xAC\xBC\xA5 + \xF0\xAC\xBC\xA6 + \xF0\xAC\xBC\xA7 + \xF0\xAC\xBC\xA8 + \xF0\xAC\xBC\xA9 + \xF0\xAC\xBC\xAA + \xF0\xAC\xBC\xAB + \xF0\xAC\xBC\xAC + \xF0\xAC\xBC\xAD + \xF0\xAC\xBC\xAE + \xF0\xAC\xBC\xAF + \xF0\xAC\xBC\xB0 + \xF0\xAC\xBC\xB1 + \xF0\xAC\xBC\xB2 + \xF0\xAC\xBC\xB3 + \xF0\xAC\xBC\xB4 + \xF0\xAC\xBC\xB5 + \xF0\xAC\xBC\xB6 + \xF0\xAC\xBC\xB7 + \xF0\xAC\xBC\xB8 + \xF0\xAC\xBC\xB9 + \xF0\xAC\xBC\xBA + \xF0\xAC\xBC\xBB + \xF0\xAC\xBC\xBC + \xF0\xAC\xBC\xBD + \xF0\xAC\xBC\xBE + \xF0\xAC\xBC\xBF + \xF0\xAC\xBD\x80 + \xF0\xAC\xBD\x81 + \xF0\xAC\xBD\x82 + \xF0\xAC\xBD\x83 + \xF0\xAC\xBD\x84 + \xF0\xAC\xBD\x85 + \xF0\xAC\xBD\x86 + \xF0\xAC\xBD\x87 + \xF0\xAC\xBD\x88 + \xF0\xAC\xBD\x89 + \xF0\xAC\xBD\x8A + \xF0\xAC\xBD\x8B + \xF0\xAC\xBD\x8C + \xF0\xAC\xBD\x8D + \xF0\xAC\xBD\x8E + \xF0\xAC\xBD\x8F + \xF0\xAC\xBD\x90 + \xF0\xAC\xBD\x91 + \xF0\xAC\xBD\x92 + \xF0\xAC\xBD\x93 + \xF0\xAC\xBD\x94 + \xF0\xAC\xBD\x95 + \xF0\xAC\xBD\x96 + \xF0\xAC\xBD\x97 + \xF0\xAC\xBD\x98 + \xF0\xAC\xBD\x99 + \xF0\xAC\xBD\x9A + \xF0\xAC\xBD\x9B + \xF0\xAC\xBD\x9C + \xF0\xAC\xBD\x9D + \xF0\xAC\xBD\x9E + \xF0\xAC\xBD\x9F + \xF0\xAC\xBD\xA0 + \xF0\xAC\xBD\xA1 + \xF0\xAC\xBD\xA2 + \xF0\xAC\xBD\xA3 + \xF0\xAC\xBD\xA4 + \xF0\xAC\xBD\xA5 + \xF0\xAC\xBD\xA6 + \xF0\xAC\xBD\xA7 + \xF0\xAC\xBD\xA8 + \xF0\xAC\xBD\xA9 + \xF0\xAC\xBD\xAA + \xF0\xAC\xBD\xAB + \xF0\xAC\xBD\xAC + \xF0\xAC\xBD\xAD + \xF0\xAC\xBD\xAE + \xF0\xAC\xBD\xAF + \xF0\xAC\xBD\xB0 + \xF0\xAC\xBD\xB1 + \xF0\xAC\xBD\xB2 + \xF0\xAC\xBD\xB3 + \xF0\xAC\xBD\xB4 + \xF0\xAC\xBD\xB5 + \xF0\xAC\xBD\xB6 + \xF0\xAC\xBD\xB7 + \xF0\xAC\xBD\xB8 + \xF0\xAC\xBD\xB9 + \xF0\xAC\xBD\xBA + \xF0\xAC\xBD\xBB + \xF0\xAC\xBD\xBC + \xF0\xAC\xBD\xBD + \xF0\xAC\xBD\xBE + \xF0\xAC\xBD\xBF + \xF0\xAC\xBE\x80 + \xF0\xAC\xBE\x81 + \xF0\xAC\xBE\x82 + \xF0\xAC\xBE\x83 + \xF0\xAC\xBE\x84 + \xF0\xAC\xBE\x85 + \xF0\xAC\xBE\x86 + \xF0\xAC\xBE\x87 + \xF0\xAC\xBE\x88 + \xF0\xAC\xBE\x89 + \xF0\xAC\xBE\x8A + \xF0\xAC\xBE\x8B + \xF0\xAC\xBE\x8C + \xF0\xAC\xBE\x8D + \xF0\xAC\xBE\x8E + \xF0\xAC\xBE\x8F + \xF0\xAC\xBE\x90 + \xF0\xAC\xBE\x91 + \xF0\xAC\xBE\x92 + \xF0\xAC\xBE\x93 + \xF0\xAC\xBE\x94 + \xF0\xAC\xBE\x95 + \xF0\xAC\xBE\x96 + \xF0\xAC\xBE\x97 + \xF0\xAC\xBE\x98 + \xF0\xAC\xBE\x99 + \xF0\xAC\xBE\x9A + \xF0\xAC\xBE\x9B + \xF0\xAC\xBE\x9C + \xF0\xAC\xBE\x9D + \xF0\xAC\xBE\x9E + \xF0\xAC\xBE\x9F + \xF0\xAC\xBE\xA0 + \xF0\xAC\xBE\xA1 + \xF0\xAC\xBE\xA2 + \xF0\xAC\xBE\xA3 + \xF0\xAC\xBE\xA4 + \xF0\xAC\xBE\xA5 + \xF0\xAC\xBE\xA6 + \xF0\xAC\xBE\xA7 + \xF0\xAC\xBE\xA8 + \xF0\xAC\xBE\xA9 + \xF0\xAC\xBE\xAA + \xF0\xAC\xBE\xAB + \xF0\xAC\xBE\xAC + \xF0\xAC\xBE\xAD + \xF0\xAC\xBE\xAE + \xF0\xAC\xBE\xAF + \xF0\xAC\xBE\xB0 + \xF0\xAC\xBE\xB1 + \xF0\xAC\xBE\xB2 + \xF0\xAC\xBE\xB3 + \xF0\xAC\xBE\xB4 + \xF0\xAC\xBE\xB5 + \xF0\xAC\xBE\xB6 + \xF0\xAC\xBE\xB7 + \xF0\xAC\xBE\xB8 + \xF0\xAC\xBE\xB9 + \xF0\xAC\xBE\xBA + \xF0\xAC\xBE\xBB + \xF0\xAC\xBE\xBC + \xF0\xAC\xBE\xBD + \xF0\xAC\xBE\xBE + \xF0\xAC\xBE\xBF + \xF0\xAC\xBF\x80 + \xF0\xAC\xBF\x81 + \xF0\xAC\xBF\x82 + \xF0\xAC\xBF\x83 + \xF0\xAC\xBF\x84 + \xF0\xAC\xBF\x85 + \xF0\xAC\xBF\x86 + \xF0\xAC\xBF\x87 + \xF0\xAC\xBF\x88 + \xF0\xAC\xBF\x89 + \xF0\xAC\xBF\x8A + \xF0\xAC\xBF\x8B + \xF0\xAC\xBF\x8C + \xF0\xAC\xBF\x8D + \xF0\xAC\xBF\x8E + \xF0\xAC\xBF\x8F + \xF0\xAC\xBF\x90 + \xF0\xAC\xBF\x91 + \xF0\xAC\xBF\x92 + \xF0\xAC\xBF\x93 + \xF0\xAC\xBF\x94 + \xF0\xAC\xBF\x95 + \xF0\xAC\xBF\x96 + \xF0\xAC\xBF\x97 + \xF0\xAC\xBF\x98 + \xF0\xAC\xBF\x99 + \xF0\xAC\xBF\x9A + \xF0\xAC\xBF\x9B + \xF0\xAC\xBF\x9C + \xF0\xAC\xBF\x9D + \xF0\xAC\xBF\x9E + \xF0\xAC\xBF\x9F + \xF0\xAC\xBF\xA0 + \xF0\xAC\xBF\xA1 + \xF0\xAC\xBF\xA2 + \xF0\xAC\xBF\xA3 + \xF0\xAC\xBF\xA4 + \xF0\xAC\xBF\xA5 + \xF0\xAC\xBF\xA6 + \xF0\xAC\xBF\xA7 + \xF0\xAC\xBF\xA8 + \xF0\xAC\xBF\xA9 + \xF0\xAC\xBF\xAA + \xF0\xAC\xBF\xAB + \xF0\xAC\xBF\xAC + \xF0\xAC\xBF\xAD + \xF0\xAC\xBF\xAE + \xF0\xAC\xBF\xAF + \xF0\xAC\xBF\xB0 + \xF0\xAC\xBF\xB1 + \xF0\xAC\xBF\xB2 + \xF0\xAC\xBF\xB3 + \xF0\xAC\xBF\xB4 + \xF0\xAC\xBF\xB5 + \xF0\xAC\xBF\xB6 + \xF0\xAC\xBF\xB7 + \xF0\xAC\xBF\xB8 + \xF0\xAC\xBF\xB9 + \xF0\xAC\xBF\xBA + \xF0\xAC\xBF\xBB + \xF0\xAC\xBF\xBC + \xF0\xAC\xBF\xBD + \xF0\xAC\xBF\xBE + \xF0\xAC\xBF\xBF + \xF0\xAD\x80\x80 + \xF0\xAD\x80\x81 + \xF0\xAD\x80\x82 + \xF0\xAD\x80\x83 + \xF0\xAD\x80\x84 + \xF0\xAD\x80\x85 + \xF0\xAD\x80\x86 + \xF0\xAD\x80\x87 + \xF0\xAD\x80\x88 + \xF0\xAD\x80\x89 + \xF0\xAD\x80\x8A + \xF0\xAD\x80\x8B + \xF0\xAD\x80\x8C + \xF0\xAD\x80\x8D + \xF0\xAD\x80\x8E + \xF0\xAD\x80\x8F + \xF0\xAD\x80\x90 + \xF0\xAD\x80\x91 + \xF0\xAD\x80\x92 + \xF0\xAD\x80\x93 + \xF0\xAD\x80\x94 + \xF0\xAD\x80\x95 + \xF0\xAD\x80\x96 + \xF0\xAD\x80\x97 + \xF0\xAD\x80\x98 + \xF0\xAD\x80\x99 + \xF0\xAD\x80\x9A + \xF0\xAD\x80\x9B + \xF0\xAD\x80\x9C + \xF0\xAD\x80\x9D + \xF0\xAD\x80\x9E + \xF0\xAD\x80\x9F + \xF0\xAD\x80\xA0 + \xF0\xAD\x80\xA1 + \xF0\xAD\x80\xA2 + \xF0\xAD\x80\xA3 + \xF0\xAD\x80\xA4 + \xF0\xAD\x80\xA5 + \xF0\xAD\x80\xA6 + \xF0\xAD\x80\xA7 + \xF0\xAD\x80\xA8 + \xF0\xAD\x80\xA9 + \xF0\xAD\x80\xAA + \xF0\xAD\x80\xAB + \xF0\xAD\x80\xAC + \xF0\xAD\x80\xAD + \xF0\xAD\x80\xAE + \xF0\xAD\x80\xAF + \xF0\xAD\x80\xB0 + \xF0\xAD\x80\xB1 + \xF0\xAD\x80\xB2 + \xF0\xAD\x80\xB3 + \xF0\xAD\x80\xB4 + \xF0\xAD\x80\xB5 + \xF0\xAD\x80\xB6 + \xF0\xAD\x80\xB7 + \xF0\xAD\x80\xB8 + \xF0\xAD\x80\xB9 + \xF0\xAD\x80\xBA + \xF0\xAD\x80\xBB + \xF0\xAD\x80\xBC + \xF0\xAD\x80\xBD + \xF0\xAD\x80\xBE + \xF0\xAD\x80\xBF + \xF0\xAD\x81\x80 + \xF0\xAD\x81\x81 + \xF0\xAD\x81\x82 + \xF0\xAD\x81\x83 + \xF0\xAD\x81\x84 + \xF0\xAD\x81\x85 + \xF0\xAD\x81\x86 + \xF0\xAD\x81\x87 + \xF0\xAD\x81\x88 + \xF0\xAD\x81\x89 + \xF0\xAD\x81\x8A + \xF0\xAD\x81\x8B + \xF0\xAD\x81\x8C + \xF0\xAD\x81\x8D + \xF0\xAD\x81\x8E + \xF0\xAD\x81\x8F + \xF0\xAD\x81\x90 + \xF0\xAD\x81\x91 + \xF0\xAD\x81\x92 + \xF0\xAD\x81\x93 + \xF0\xAD\x81\x94 + \xF0\xAD\x81\x95 + \xF0\xAD\x81\x96 + \xF0\xAD\x81\x97 + \xF0\xAD\x81\x98 + \xF0\xAD\x81\x99 + \xF0\xAD\x81\x9A + \xF0\xAD\x81\x9B + \xF0\xAD\x81\x9C + \xF0\xAD\x81\x9D + \xF0\xAD\x81\x9E + \xF0\xAD\x81\x9F + \xF0\xAD\x81\xA0 + \xF0\xAD\x81\xA1 + \xF0\xAD\x81\xA2 + \xF0\xAD\x81\xA3 + \xF0\xAD\x81\xA4 + \xF0\xAD\x81\xA5 + \xF0\xAD\x81\xA6 + \xF0\xAD\x81\xA7 + \xF0\xAD\x81\xA8 + \xF0\xAD\x81\xA9 + \xF0\xAD\x81\xAA + \xF0\xAD\x81\xAB + \xF0\xAD\x81\xAC + \xF0\xAD\x81\xAD + \xF0\xAD\x81\xAE + \xF0\xAD\x81\xAF + \xF0\xAD\x81\xB0 + \xF0\xAD\x81\xB1 + \xF0\xAD\x81\xB2 + \xF0\xAD\x81\xB3 + \xF0\xAD\x81\xB4 + \xF0\xAD\x81\xB5 + \xF0\xAD\x81\xB6 + \xF0\xAD\x81\xB7 + \xF0\xAD\x81\xB8 + \xF0\xAD\x81\xB9 + \xF0\xAD\x81\xBA + \xF0\xAD\x81\xBB + \xF0\xAD\x81\xBC + \xF0\xAD\x81\xBD + \xF0\xAD\x81\xBE + \xF0\xAD\x81\xBF + \xF0\xAD\x82\x80 + \xF0\xAD\x82\x81 + \xF0\xAD\x82\x82 + \xF0\xAD\x82\x83 + \xF0\xAD\x82\x84 + \xF0\xAD\x82\x85 + \xF0\xAD\x82\x86 + \xF0\xAD\x82\x87 + \xF0\xAD\x82\x88 + \xF0\xAD\x82\x89 + \xF0\xAD\x82\x8A + \xF0\xAD\x82\x8B + \xF0\xAD\x82\x8C + \xF0\xAD\x82\x8D + \xF0\xAD\x82\x8E + \xF0\xAD\x82\x8F + \xF0\xAD\x82\x90 + \xF0\xAD\x82\x91 + \xF0\xAD\x82\x92 + \xF0\xAD\x82\x93 + \xF0\xAD\x82\x94 + \xF0\xAD\x82\x95 + \xF0\xAD\x82\x96 + \xF0\xAD\x82\x97 + \xF0\xAD\x82\x98 + \xF0\xAD\x82\x99 + \xF0\xAD\x82\x9A + \xF0\xAD\x82\x9B + \xF0\xAD\x82\x9C + \xF0\xAD\x82\x9D + \xF0\xAD\x82\x9E + \xF0\xAD\x82\x9F + \xF0\xAD\x82\xA0 + \xF0\xAD\x82\xA1 + \xF0\xAD\x82\xA2 + \xF0\xAD\x82\xA3 + \xF0\xAD\x82\xA4 + \xF0\xAD\x82\xA5 + \xF0\xAD\x82\xA6 + \xF0\xAD\x82\xA7 + \xF0\xAD\x82\xA8 + \xF0\xAD\x82\xA9 + \xF0\xAD\x82\xAA + \xF0\xAD\x82\xAB + \xF0\xAD\x82\xAC + \xF0\xAD\x82\xAD + \xF0\xAD\x82\xAE + \xF0\xAD\x82\xAF + \xF0\xAD\x82\xB0 + \xF0\xAD\x82\xB1 + \xF0\xAD\x82\xB2 + \xF0\xAD\x82\xB3 + \xF0\xAD\x82\xB4 + \xF0\xAD\x82\xB5 + \xF0\xAD\x82\xB6 + \xF0\xAD\x82\xB7 + \xF0\xAD\x82\xB8 + \xF0\xAD\x82\xB9 + \xF0\xAD\x82\xBA + \xF0\xAD\x82\xBB + \xF0\xAD\x82\xBC + \xF0\xAD\x82\xBD + \xF0\xAD\x82\xBE + \xF0\xAD\x82\xBF + \xF0\xAD\x83\x80 + \xF0\xAD\x83\x81 + \xF0\xAD\x83\x82 + \xF0\xAD\x83\x83 + \xF0\xAD\x83\x84 + \xF0\xAD\x83\x85 + \xF0\xAD\x83\x86 + \xF0\xAD\x83\x87 + \xF0\xAD\x83\x88 + \xF0\xAD\x83\x89 + \xF0\xAD\x83\x8A + \xF0\xAD\x83\x8B + \xF0\xAD\x83\x8C + \xF0\xAD\x83\x8D + \xF0\xAD\x83\x8E + \xF0\xAD\x83\x8F + \xF0\xAD\x83\x90 + \xF0\xAD\x83\x91 + \xF0\xAD\x83\x92 + \xF0\xAD\x83\x93 + \xF0\xAD\x83\x94 + \xF0\xAD\x83\x95 + \xF0\xAD\x83\x96 + \xF0\xAD\x83\x97 + \xF0\xAD\x83\x98 + \xF0\xAD\x83\x99 + \xF0\xAD\x83\x9A + \xF0\xAD\x83\x9B + \xF0\xAD\x83\x9C + \xF0\xAD\x83\x9D + \xF0\xAD\x83\x9E + \xF0\xAD\x83\x9F + \xF0\xAD\x83\xA0 + \xF0\xAD\x83\xA1 + \xF0\xAD\x83\xA2 + \xF0\xAD\x83\xA3 + \xF0\xAD\x83\xA4 + \xF0\xAD\x83\xA5 + \xF0\xAD\x83\xA6 + \xF0\xAD\x83\xA7 + \xF0\xAD\x83\xA8 + \xF0\xAD\x83\xA9 + \xF0\xAD\x83\xAA + \xF0\xAD\x83\xAB + \xF0\xAD\x83\xAC + \xF0\xAD\x83\xAD + \xF0\xAD\x83\xAE + \xF0\xAD\x83\xAF + \xF0\xAD\x83\xB0 + \xF0\xAD\x83\xB1 + \xF0\xAD\x83\xB2 + \xF0\xAD\x83\xB3 + \xF0\xAD\x83\xB4 + \xF0\xAD\x83\xB5 + \xF0\xAD\x83\xB6 + \xF0\xAD\x83\xB7 + \xF0\xAD\x83\xB8 + \xF0\xAD\x83\xB9 + \xF0\xAD\x83\xBA + \xF0\xAD\x83\xBB + \xF0\xAD\x83\xBC + \xF0\xAD\x83\xBD + \xF0\xAD\x83\xBE + \xF0\xAD\x83\xBF + \xF0\xAD\x84\x80 + \xF0\xAD\x84\x81 + \xF0\xAD\x84\x82 + \xF0\xAD\x84\x83 + \xF0\xAD\x84\x84 + \xF0\xAD\x84\x85 + \xF0\xAD\x84\x86 + \xF0\xAD\x84\x87 + \xF0\xAD\x84\x88 + \xF0\xAD\x84\x89 + \xF0\xAD\x84\x8A + \xF0\xAD\x84\x8B + \xF0\xAD\x84\x8C + \xF0\xAD\x84\x8D + \xF0\xAD\x84\x8E + \xF0\xAD\x84\x8F + \xF0\xAD\x84\x90 + \xF0\xAD\x84\x91 + \xF0\xAD\x84\x92 + \xF0\xAD\x84\x93 + \xF0\xAD\x84\x94 + \xF0\xAD\x84\x95 + \xF0\xAD\x84\x96 + \xF0\xAD\x84\x97 + \xF0\xAD\x84\x98 + \xF0\xAD\x84\x99 + \xF0\xAD\x84\x9A + \xF0\xAD\x84\x9B + \xF0\xAD\x84\x9C + \xF0\xAD\x84\x9D + \xF0\xAD\x84\x9E + \xF0\xAD\x84\x9F + \xF0\xAD\x84\xA0 + \xF0\xAD\x84\xA1 + \xF0\xAD\x84\xA2 + \xF0\xAD\x84\xA3 + \xF0\xAD\x84\xA4 + \xF0\xAD\x84\xA5 + \xF0\xAD\x84\xA6 + \xF0\xAD\x84\xA7 + \xF0\xAD\x84\xA8 + \xF0\xAD\x84\xA9 + \xF0\xAD\x84\xAA + \xF0\xAD\x84\xAB + \xF0\xAD\x84\xAC + \xF0\xAD\x84\xAD + \xF0\xAD\x84\xAE + \xF0\xAD\x84\xAF + \xF0\xAD\x84\xB0 + \xF0\xAD\x84\xB1 + \xF0\xAD\x84\xB2 + \xF0\xAD\x84\xB3 + \xF0\xAD\x84\xB4 + \xF0\xAD\x84\xB5 + \xF0\xAD\x84\xB6 + \xF0\xAD\x84\xB7 + \xF0\xAD\x84\xB8 + \xF0\xAD\x84\xB9 + \xF0\xAD\x84\xBA + \xF0\xAD\x84\xBB + \xF0\xAD\x84\xBC + \xF0\xAD\x84\xBD + \xF0\xAD\x84\xBE + \xF0\xAD\x84\xBF + \xF0\xAD\x85\x80 + \xF0\xAD\x85\x81 + \xF0\xAD\x85\x82 + \xF0\xAD\x85\x83 + \xF0\xAD\x85\x84 + \xF0\xAD\x85\x85 + \xF0\xAD\x85\x86 + \xF0\xAD\x85\x87 + \xF0\xAD\x85\x88 + \xF0\xAD\x85\x89 + \xF0\xAD\x85\x8A + \xF0\xAD\x85\x8B + \xF0\xAD\x85\x8C + \xF0\xAD\x85\x8D + \xF0\xAD\x85\x8E + \xF0\xAD\x85\x8F + \xF0\xAD\x85\x90 + \xF0\xAD\x85\x91 + \xF0\xAD\x85\x92 + \xF0\xAD\x85\x93 + \xF0\xAD\x85\x94 + \xF0\xAD\x85\x95 + \xF0\xAD\x85\x96 + \xF0\xAD\x85\x97 + \xF0\xAD\x85\x98 + \xF0\xAD\x85\x99 + \xF0\xAD\x85\x9A + \xF0\xAD\x85\x9B + \xF0\xAD\x85\x9C + \xF0\xAD\x85\x9D + \xF0\xAD\x85\x9E + \xF0\xAD\x85\x9F + \xF0\xAD\x85\xA0 + \xF0\xAD\x85\xA1 + \xF0\xAD\x85\xA2 + \xF0\xAD\x85\xA3 + \xF0\xAD\x85\xA4 + \xF0\xAD\x85\xA5 + \xF0\xAD\x85\xA6 + \xF0\xAD\x85\xA7 + \xF0\xAD\x85\xA8 + \xF0\xAD\x85\xA9 + \xF0\xAD\x85\xAA + \xF0\xAD\x85\xAB + \xF0\xAD\x85\xAC + \xF0\xAD\x85\xAD + \xF0\xAD\x85\xAE + \xF0\xAD\x85\xAF + \xF0\xAD\x85\xB0 + \xF0\xAD\x85\xB1 + \xF0\xAD\x85\xB2 + \xF0\xAD\x85\xB3 + \xF0\xAD\x85\xB4 + \xF0\xAD\x85\xB5 + \xF0\xAD\x85\xB6 + \xF0\xAD\x85\xB7 + \xF0\xAD\x85\xB8 + \xF0\xAD\x85\xB9 + \xF0\xAD\x85\xBA + \xF0\xAD\x85\xBB + \xF0\xAD\x85\xBC + \xF0\xAD\x85\xBD + \xF0\xAD\x85\xBE + \xF0\xAD\x85\xBF + \xF0\xAD\x86\x80 + \xF0\xAD\x86\x81 + \xF0\xAD\x86\x82 + \xF0\xAD\x86\x83 + \xF0\xAD\x86\x84 + \xF0\xAD\x86\x85 + \xF0\xAD\x86\x86 + \xF0\xAD\x86\x87 + \xF0\xAD\x86\x88 + \xF0\xAD\x86\x89 + \xF0\xAD\x86\x8A + \xF0\xAD\x86\x8B + \xF0\xAD\x86\x8C + \xF0\xAD\x86\x8D + \xF0\xAD\x86\x8E + \xF0\xAD\x86\x8F + \xF0\xAD\x86\x90 + \xF0\xAD\x86\x91 + \xF0\xAD\x86\x92 + \xF0\xAD\x86\x93 + \xF0\xAD\x86\x94 + \xF0\xAD\x86\x95 + \xF0\xAD\x86\x96 + \xF0\xAD\x86\x97 + \xF0\xAD\x86\x98 + \xF0\xAD\x86\x99 + \xF0\xAD\x86\x9A + \xF0\xAD\x86\x9B + \xF0\xAD\x86\x9C + \xF0\xAD\x86\x9D + \xF0\xAD\x86\x9E + \xF0\xAD\x86\x9F + \xF0\xAD\x86\xA0 + \xF0\xAD\x86\xA1 + \xF0\xAD\x86\xA2 + \xF0\xAD\x86\xA3 + \xF0\xAD\x86\xA4 + \xF0\xAD\x86\xA5 + \xF0\xAD\x86\xA6 + \xF0\xAD\x86\xA7 + \xF0\xAD\x86\xA8 + \xF0\xAD\x86\xA9 + \xF0\xAD\x86\xAA + \xF0\xAD\x86\xAB + \xF0\xAD\x86\xAC + \xF0\xAD\x86\xAD + \xF0\xAD\x86\xAE + \xF0\xAD\x86\xAF + \xF0\xAD\x86\xB0 + \xF0\xAD\x86\xB1 + \xF0\xAD\x86\xB2 + \xF0\xAD\x86\xB3 + \xF0\xAD\x86\xB4 + \xF0\xAD\x86\xB5 + \xF0\xAD\x86\xB6 + \xF0\xAD\x86\xB7 + \xF0\xAD\x86\xB8 + \xF0\xAD\x86\xB9 + \xF0\xAD\x86\xBA + \xF0\xAD\x86\xBB + \xF0\xAD\x86\xBC + \xF0\xAD\x86\xBD + \xF0\xAD\x86\xBE + \xF0\xAD\x86\xBF + \xF0\xAD\x87\x80 + \xF0\xAD\x87\x81 + \xF0\xAD\x87\x82 + \xF0\xAD\x87\x83 + \xF0\xAD\x87\x84 + \xF0\xAD\x87\x85 + \xF0\xAD\x87\x86 + \xF0\xAD\x87\x87 + \xF0\xAD\x87\x88 + \xF0\xAD\x87\x89 + \xF0\xAD\x87\x8A + \xF0\xAD\x87\x8B + \xF0\xAD\x87\x8C + \xF0\xAD\x87\x8D + \xF0\xAD\x87\x8E + \xF0\xAD\x87\x8F + \xF0\xAD\x87\x90 + \xF0\xAD\x87\x91 + \xF0\xAD\x87\x92 + \xF0\xAD\x87\x93 + \xF0\xAD\x87\x94 + \xF0\xAD\x87\x95 + \xF0\xAD\x87\x96 + \xF0\xAD\x87\x97 + \xF0\xAD\x87\x98 + \xF0\xAD\x87\x99 + \xF0\xAD\x87\x9A + \xF0\xAD\x87\x9B + \xF0\xAD\x87\x9C + \xF0\xAD\x87\x9D + \xF0\xAD\x87\x9E + \xF0\xAD\x87\x9F + \xF0\xAD\x87\xA0 + \xF0\xAD\x87\xA1 + \xF0\xAD\x87\xA2 + \xF0\xAD\x87\xA3 + \xF0\xAD\x87\xA4 + \xF0\xAD\x87\xA5 + \xF0\xAD\x87\xA6 + \xF0\xAD\x87\xA7 + \xF0\xAD\x87\xA8 + \xF0\xAD\x87\xA9 + \xF0\xAD\x87\xAA + \xF0\xAD\x87\xAB + \xF0\xAD\x87\xAC + \xF0\xAD\x87\xAD + \xF0\xAD\x87\xAE + \xF0\xAD\x87\xAF + \xF0\xAD\x87\xB0 + \xF0\xAD\x87\xB1 + \xF0\xAD\x87\xB2 + \xF0\xAD\x87\xB3 + \xF0\xAD\x87\xB4 + \xF0\xAD\x87\xB5 + \xF0\xAD\x87\xB6 + \xF0\xAD\x87\xB7 + \xF0\xAD\x87\xB8 + \xF0\xAD\x87\xB9 + \xF0\xAD\x87\xBA + \xF0\xAD\x87\xBB + \xF0\xAD\x87\xBC + \xF0\xAD\x87\xBD + \xF0\xAD\x87\xBE + \xF0\xAD\x87\xBF + \xF0\xAD\x88\x80 + \xF0\xAD\x88\x81 + \xF0\xAD\x88\x82 + \xF0\xAD\x88\x83 + \xF0\xAD\x88\x84 + \xF0\xAD\x88\x85 + \xF0\xAD\x88\x86 + \xF0\xAD\x88\x87 + \xF0\xAD\x88\x88 + \xF0\xAD\x88\x89 + \xF0\xAD\x88\x8A + \xF0\xAD\x88\x8B + \xF0\xAD\x88\x8C + \xF0\xAD\x88\x8D + \xF0\xAD\x88\x8E + \xF0\xAD\x88\x8F + \xF0\xAD\x88\x90 + \xF0\xAD\x88\x91 + \xF0\xAD\x88\x92 + \xF0\xAD\x88\x93 + \xF0\xAD\x88\x94 + \xF0\xAD\x88\x95 + \xF0\xAD\x88\x96 + \xF0\xAD\x88\x97 + \xF0\xAD\x88\x98 + \xF0\xAD\x88\x99 + \xF0\xAD\x88\x9A + \xF0\xAD\x88\x9B + \xF0\xAD\x88\x9C + \xF0\xAD\x88\x9D + \xF0\xAD\x88\x9E + \xF0\xAD\x88\x9F + \xF0\xAD\x88\xA0 + \xF0\xAD\x88\xA1 + \xF0\xAD\x88\xA2 + \xF0\xAD\x88\xA3 + \xF0\xAD\x88\xA4 + \xF0\xAD\x88\xA5 + \xF0\xAD\x88\xA6 + \xF0\xAD\x88\xA7 + \xF0\xAD\x88\xA8 + \xF0\xAD\x88\xA9 + \xF0\xAD\x88\xAA + \xF0\xAD\x88\xAB + \xF0\xAD\x88\xAC + \xF0\xAD\x88\xAD + \xF0\xAD\x88\xAE + \xF0\xAD\x88\xAF + \xF0\xAD\x88\xB0 + \xF0\xAD\x88\xB1 + \xF0\xAD\x88\xB2 + \xF0\xAD\x88\xB3 + \xF0\xAD\x88\xB4 + \xF0\xAD\x88\xB5 + \xF0\xAD\x88\xB6 + \xF0\xAD\x88\xB7 + \xF0\xAD\x88\xB8 + \xF0\xAD\x88\xB9 + \xF0\xAD\x88\xBA + \xF0\xAD\x88\xBB + \xF0\xAD\x88\xBC + \xF0\xAD\x88\xBD + \xF0\xAD\x88\xBE + \xF0\xAD\x88\xBF + \xF0\xAD\x89\x80 + \xF0\xAD\x89\x81 + \xF0\xAD\x89\x82 + \xF0\xAD\x89\x83 + \xF0\xAD\x89\x84 + \xF0\xAD\x89\x85 + \xF0\xAD\x89\x86 + \xF0\xAD\x89\x87 + \xF0\xAD\x89\x88 + \xF0\xAD\x89\x89 + \xF0\xAD\x89\x8A + \xF0\xAD\x89\x8B + \xF0\xAD\x89\x8C + \xF0\xAD\x89\x8D + \xF0\xAD\x89\x8E + \xF0\xAD\x89\x8F + \xF0\xAD\x89\x90 + \xF0\xAD\x89\x91 + \xF0\xAD\x89\x92 + \xF0\xAD\x89\x93 + \xF0\xAD\x89\x94 + \xF0\xAD\x89\x95 + \xF0\xAD\x89\x96 + \xF0\xAD\x89\x97 + \xF0\xAD\x89\x98 + \xF0\xAD\x89\x99 + \xF0\xAD\x89\x9A + \xF0\xAD\x89\x9B + \xF0\xAD\x89\x9C + \xF0\xAD\x89\x9D + \xF0\xAD\x89\x9E + \xF0\xAD\x89\x9F + \xF0\xAD\x89\xA0 + \xF0\xAD\x89\xA1 + \xF0\xAD\x89\xA2 + \xF0\xAD\x89\xA3 + \xF0\xAD\x89\xA4 + \xF0\xAD\x89\xA5 + \xF0\xAD\x89\xA6 + \xF0\xAD\x89\xA7 + \xF0\xAD\x89\xA8 + \xF0\xAD\x89\xA9 + \xF0\xAD\x89\xAA + \xF0\xAD\x89\xAB + \xF0\xAD\x89\xAC + \xF0\xAD\x89\xAD + \xF0\xAD\x89\xAE + \xF0\xAD\x89\xAF + \xF0\xAD\x89\xB0 + \xF0\xAD\x89\xB1 + \xF0\xAD\x89\xB2 + \xF0\xAD\x89\xB3 + \xF0\xAD\x89\xB4 + \xF0\xAD\x89\xB5 + \xF0\xAD\x89\xB6 + \xF0\xAD\x89\xB7 + \xF0\xAD\x89\xB8 + \xF0\xAD\x89\xB9 + \xF0\xAD\x89\xBA + \xF0\xAD\x89\xBB + \xF0\xAD\x89\xBC + \xF0\xAD\x89\xBD + \xF0\xAD\x89\xBE + \xF0\xAD\x89\xBF + \xF0\xAD\x8A\x80 + \xF0\xAD\x8A\x81 + \xF0\xAD\x8A\x82 + \xF0\xAD\x8A\x83 + \xF0\xAD\x8A\x84 + \xF0\xAD\x8A\x85 + \xF0\xAD\x8A\x86 + \xF0\xAD\x8A\x87 + \xF0\xAD\x8A\x88 + \xF0\xAD\x8A\x89 + \xF0\xAD\x8A\x8A + \xF0\xAD\x8A\x8B + \xF0\xAD\x8A\x8C + \xF0\xAD\x8A\x8D + \xF0\xAD\x8A\x8E + \xF0\xAD\x8A\x8F + \xF0\xAD\x8A\x90 + \xF0\xAD\x8A\x91 + \xF0\xAD\x8A\x92 + \xF0\xAD\x8A\x93 + \xF0\xAD\x8A\x94 + \xF0\xAD\x8A\x95 + \xF0\xAD\x8A\x96 + \xF0\xAD\x8A\x97 + \xF0\xAD\x8A\x98 + \xF0\xAD\x8A\x99 + \xF0\xAD\x8A\x9A + \xF0\xAD\x8A\x9B + \xF0\xAD\x8A\x9C + \xF0\xAD\x8A\x9D + \xF0\xAD\x8A\x9E + \xF0\xAD\x8A\x9F + \xF0\xAD\x8A\xA0 + \xF0\xAD\x8A\xA1 + \xF0\xAD\x8A\xA2 + \xF0\xAD\x8A\xA3 + \xF0\xAD\x8A\xA4 + \xF0\xAD\x8A\xA5 + \xF0\xAD\x8A\xA6 + \xF0\xAD\x8A\xA7 + \xF0\xAD\x8A\xA8 + \xF0\xAD\x8A\xA9 + \xF0\xAD\x8A\xAA + \xF0\xAD\x8A\xAB + \xF0\xAD\x8A\xAC + \xF0\xAD\x8A\xAD + \xF0\xAD\x8A\xAE + \xF0\xAD\x8A\xAF + \xF0\xAD\x8A\xB0 + \xF0\xAD\x8A\xB1 + \xF0\xAD\x8A\xB2 + \xF0\xAD\x8A\xB3 + \xF0\xAD\x8A\xB4 + \xF0\xAD\x8A\xB5 + \xF0\xAD\x8A\xB6 + \xF0\xAD\x8A\xB7 + \xF0\xAD\x8A\xB8 + \xF0\xAD\x8A\xB9 + \xF0\xAD\x8A\xBA + \xF0\xAD\x8A\xBB + \xF0\xAD\x8A\xBC + \xF0\xAD\x8A\xBD + \xF0\xAD\x8A\xBE + \xF0\xAD\x8A\xBF + \xF0\xAD\x8B\x80 + \xF0\xAD\x8B\x81 + \xF0\xAD\x8B\x82 + \xF0\xAD\x8B\x83 + \xF0\xAD\x8B\x84 + \xF0\xAD\x8B\x85 + \xF0\xAD\x8B\x86 + \xF0\xAD\x8B\x87 + \xF0\xAD\x8B\x88 + \xF0\xAD\x8B\x89 + \xF0\xAD\x8B\x8A + \xF0\xAD\x8B\x8B + \xF0\xAD\x8B\x8C + \xF0\xAD\x8B\x8D + \xF0\xAD\x8B\x8E + \xF0\xAD\x8B\x8F + \xF0\xAD\x8B\x90 + \xF0\xAD\x8B\x91 + \xF0\xAD\x8B\x92 + \xF0\xAD\x8B\x93 + \xF0\xAD\x8B\x94 + \xF0\xAD\x8B\x95 + \xF0\xAD\x8B\x96 + \xF0\xAD\x8B\x97 + \xF0\xAD\x8B\x98 + \xF0\xAD\x8B\x99 + \xF0\xAD\x8B\x9A + \xF0\xAD\x8B\x9B + \xF0\xAD\x8B\x9C + \xF0\xAD\x8B\x9D + \xF0\xAD\x8B\x9E + \xF0\xAD\x8B\x9F + \xF0\xAD\x8B\xA0 + \xF0\xAD\x8B\xA1 + \xF0\xAD\x8B\xA2 + \xF0\xAD\x8B\xA3 + \xF0\xAD\x8B\xA4 + \xF0\xAD\x8B\xA5 + \xF0\xAD\x8B\xA6 + \xF0\xAD\x8B\xA7 + \xF0\xAD\x8B\xA8 + \xF0\xAD\x8B\xA9 + \xF0\xAD\x8B\xAA + \xF0\xAD\x8B\xAB + \xF0\xAD\x8B\xAC + \xF0\xAD\x8B\xAD + \xF0\xAD\x8B\xAE + \xF0\xAD\x8B\xAF + \xF0\xAD\x8B\xB0 + \xF0\xAD\x8B\xB1 + \xF0\xAD\x8B\xB2 + \xF0\xAD\x8B\xB3 + \xF0\xAD\x8B\xB4 + \xF0\xAD\x8B\xB5 + \xF0\xAD\x8B\xB6 + \xF0\xAD\x8B\xB7 + \xF0\xAD\x8B\xB8 + \xF0\xAD\x8B\xB9 + \xF0\xAD\x8B\xBA + \xF0\xAD\x8B\xBB + \xF0\xAD\x8B\xBC + \xF0\xAD\x8B\xBD + \xF0\xAD\x8B\xBE + \xF0\xAD\x8B\xBF + \xF0\xAD\x8C\x80 + \xF0\xAD\x8C\x81 + \xF0\xAD\x8C\x82 + \xF0\xAD\x8C\x83 + \xF0\xAD\x8C\x84 + \xF0\xAD\x8C\x85 + \xF0\xAD\x8C\x86 + \xF0\xAD\x8C\x87 + \xF0\xAD\x8C\x88 + \xF0\xAD\x8C\x89 + \xF0\xAD\x8C\x8A + \xF0\xAD\x8C\x8B + \xF0\xAD\x8C\x8C + \xF0\xAD\x8C\x8D + \xF0\xAD\x8C\x8E + \xF0\xAD\x8C\x8F + \xF0\xAD\x8C\x90 + \xF0\xAD\x8C\x91 + \xF0\xAD\x8C\x92 + \xF0\xAD\x8C\x93 + \xF0\xAD\x8C\x94 + \xF0\xAD\x8C\x95 + \xF0\xAD\x8C\x96 + \xF0\xAD\x8C\x97 + \xF0\xAD\x8C\x98 + \xF0\xAD\x8C\x99 + \xF0\xAD\x8C\x9A + \xF0\xAD\x8C\x9B + \xF0\xAD\x8C\x9C + \xF0\xAD\x8C\x9D + \xF0\xAD\x8C\x9E + \xF0\xAD\x8C\x9F + \xF0\xAD\x8C\xA0 + \xF0\xAD\x8C\xA1 + \xF0\xAD\x8C\xA2 + \xF0\xAD\x8C\xA3 + \xF0\xAD\x8C\xA4 + \xF0\xAD\x8C\xA5 + \xF0\xAD\x8C\xA6 + \xF0\xAD\x8C\xA7 + \xF0\xAD\x8C\xA8 + \xF0\xAD\x8C\xA9 + \xF0\xAD\x8C\xAA + \xF0\xAD\x8C\xAB + \xF0\xAD\x8C\xAC + \xF0\xAD\x8C\xAD + \xF0\xAD\x8C\xAE + \xF0\xAD\x8C\xAF + \xF0\xAD\x8C\xB0 + \xF0\xAD\x8C\xB1 + \xF0\xAD\x8C\xB2 + \xF0\xAD\x8C\xB3 + \xF0\xAD\x8C\xB4 + \xF0\xAD\x8C\xB5 + \xF0\xAD\x8C\xB6 + \xF0\xAD\x8C\xB7 + \xF0\xAD\x8C\xB8 + \xF0\xAD\x8C\xB9 + \xF0\xAD\x8C\xBA + \xF0\xAD\x8C\xBB + \xF0\xAD\x8C\xBC + \xF0\xAD\x8C\xBD + \xF0\xAD\x8C\xBE + \xF0\xAD\x8C\xBF + \xF0\xAD\x8D\x80 + \xF0\xAD\x8D\x81 + \xF0\xAD\x8D\x82 + \xF0\xAD\x8D\x83 + \xF0\xAD\x8D\x84 + \xF0\xAD\x8D\x85 + \xF0\xAD\x8D\x86 + \xF0\xAD\x8D\x87 + \xF0\xAD\x8D\x88 + \xF0\xAD\x8D\x89 + \xF0\xAD\x8D\x8A + \xF0\xAD\x8D\x8B + \xF0\xAD\x8D\x8C + \xF0\xAD\x8D\x8D + \xF0\xAD\x8D\x8E + \xF0\xAD\x8D\x8F + \xF0\xAD\x8D\x90 + \xF0\xAD\x8D\x91 + \xF0\xAD\x8D\x92 + \xF0\xAD\x8D\x93 + \xF0\xAD\x8D\x94 + \xF0\xAD\x8D\x95 + \xF0\xAD\x8D\x96 + \xF0\xAD\x8D\x97 + \xF0\xAD\x8D\x98 + \xF0\xAD\x8D\x99 + \xF0\xAD\x8D\x9A + \xF0\xAD\x8D\x9B + \xF0\xAD\x8D\x9C + \xF0\xAD\x8D\x9D + \xF0\xAD\x8D\x9E + \xF0\xAD\x8D\x9F + \xF0\xAD\x8D\xA0 + \xF0\xAD\x8D\xA1 + \xF0\xAD\x8D\xA2 + \xF0\xAD\x8D\xA3 + \xF0\xAD\x8D\xA4 + \xF0\xAD\x8D\xA5 + \xF0\xAD\x8D\xA6 + \xF0\xAD\x8D\xA7 + \xF0\xAD\x8D\xA8 + \xF0\xAD\x8D\xA9 + \xF0\xAD\x8D\xAA + \xF0\xAD\x8D\xAB + \xF0\xAD\x8D\xAC + \xF0\xAD\x8D\xAD + \xF0\xAD\x8D\xAE + \xF0\xAD\x8D\xAF + \xF0\xAD\x8D\xB0 + \xF0\xAD\x8D\xB1 + \xF0\xAD\x8D\xB2 + \xF0\xAD\x8D\xB3 + \xF0\xAD\x8D\xB4 + \xF0\xAD\x8D\xB5 + \xF0\xAD\x8D\xB6 + \xF0\xAD\x8D\xB7 + \xF0\xAD\x8D\xB8 + \xF0\xAD\x8D\xB9 + \xF0\xAD\x8D\xBA + \xF0\xAD\x8D\xBB + \xF0\xAD\x8D\xBC + \xF0\xAD\x8D\xBD + \xF0\xAD\x8D\xBE + \xF0\xAD\x8D\xBF + \xF0\xAD\x8E\x80 + \xF0\xAD\x8E\x81 + \xF0\xAD\x8E\x82 + \xF0\xAD\x8E\x83 + \xF0\xAD\x8E\x84 + \xF0\xAD\x8E\x85 + \xF0\xAD\x8E\x86 + \xF0\xAD\x8E\x87 + \xF0\xAD\x8E\x88 + \xF0\xAD\x8E\x89 + \xF0\xAD\x8E\x8A + \xF0\xAD\x8E\x8B + \xF0\xAD\x8E\x8C + \xF0\xAD\x8E\x8D + \xF0\xAD\x8E\x8E + \xF0\xAD\x8E\x8F + \xF0\xAD\x8E\x90 + \xF0\xAD\x8E\x91 + \xF0\xAD\x8E\x92 + \xF0\xAD\x8E\x93 + \xF0\xAD\x8E\x94 + \xF0\xAD\x8E\x95 + \xF0\xAD\x8E\x96 + \xF0\xAD\x8E\x97 + \xF0\xAD\x8E\x98 + \xF0\xAD\x8E\x99 + \xF0\xAD\x8E\x9A + \xF0\xAD\x8E\x9B + \xF0\xAD\x8E\x9C + \xF0\xAD\x8E\x9D + \xF0\xAD\x8E\x9E + \xF0\xAD\x8E\x9F + \xF0\xAD\x8E\xA0 + \xF0\xAD\x8E\xA1 + \xF0\xAD\x8E\xA2 + \xF0\xAD\x8E\xA3 + \xF0\xAD\x8E\xA4 + \xF0\xAD\x8E\xA5 + \xF0\xAD\x8E\xA6 + \xF0\xAD\x8E\xA7 + \xF0\xAD\x8E\xA8 + \xF0\xAD\x8E\xA9 + \xF0\xAD\x8E\xAA + \xF0\xAD\x8E\xAB + \xF0\xAD\x8E\xAC + \xF0\xAD\x8E\xAD + \xF0\xAD\x8E\xAE + \xF0\xAD\x8E\xAF + \xF0\xAD\x8E\xB0 + \xF0\xAD\x8E\xB1 + \xF0\xAD\x8E\xB2 + \xF0\xAD\x8E\xB3 + \xF0\xAD\x8E\xB4 + \xF0\xAD\x8E\xB5 + \xF0\xAD\x8E\xB6 + \xF0\xAD\x8E\xB7 + \xF0\xAD\x8E\xB8 + \xF0\xAD\x8E\xB9 + \xF0\xAD\x8E\xBA + \xF0\xAD\x8E\xBB + \xF0\xAD\x8E\xBC + \xF0\xAD\x8E\xBD + \xF0\xAD\x8E\xBE + \xF0\xAD\x8E\xBF + \xF0\xAD\x8F\x80 + \xF0\xAD\x8F\x81 + \xF0\xAD\x8F\x82 + \xF0\xAD\x8F\x83 + \xF0\xAD\x8F\x84 + \xF0\xAD\x8F\x85 + \xF0\xAD\x8F\x86 + \xF0\xAD\x8F\x87 + \xF0\xAD\x8F\x88 + \xF0\xAD\x8F\x89 + \xF0\xAD\x8F\x8A + \xF0\xAD\x8F\x8B + \xF0\xAD\x8F\x8C + \xF0\xAD\x8F\x8D + \xF0\xAD\x8F\x8E + \xF0\xAD\x8F\x8F + \xF0\xAD\x8F\x90 + \xF0\xAD\x8F\x91 + \xF0\xAD\x8F\x92 + \xF0\xAD\x8F\x93 + \xF0\xAD\x8F\x94 + \xF0\xAD\x8F\x95 + \xF0\xAD\x8F\x96 + \xF0\xAD\x8F\x97 + \xF0\xAD\x8F\x98 + \xF0\xAD\x8F\x99 + \xF0\xAD\x8F\x9A + \xF0\xAD\x8F\x9B + \xF0\xAD\x8F\x9C + \xF0\xAD\x8F\x9D + \xF0\xAD\x8F\x9E + \xF0\xAD\x8F\x9F + \xF0\xAD\x8F\xA0 + \xF0\xAD\x8F\xA1 + \xF0\xAD\x8F\xA2 + \xF0\xAD\x8F\xA3 + \xF0\xAD\x8F\xA4 + \xF0\xAD\x8F\xA5 + \xF0\xAD\x8F\xA6 + \xF0\xAD\x8F\xA7 + \xF0\xAD\x8F\xA8 + \xF0\xAD\x8F\xA9 + \xF0\xAD\x8F\xAA + \xF0\xAD\x8F\xAB + \xF0\xAD\x8F\xAC + \xF0\xAD\x8F\xAD + \xF0\xAD\x8F\xAE + \xF0\xAD\x8F\xAF + \xF0\xAD\x8F\xB0 + \xF0\xAD\x8F\xB1 + \xF0\xAD\x8F\xB2 + \xF0\xAD\x8F\xB3 + \xF0\xAD\x8F\xB4 + \xF0\xAD\x8F\xB5 + \xF0\xAD\x8F\xB6 + \xF0\xAD\x8F\xB7 + \xF0\xAD\x8F\xB8 + \xF0\xAD\x8F\xB9 + \xF0\xAD\x8F\xBA + \xF0\xAD\x8F\xBB + \xF0\xAD\x8F\xBC + \xF0\xAD\x8F\xBD + \xF0\xAD\x8F\xBE + \xF0\xAD\x8F\xBF + \xF0\xAD\x90\x80 + \xF0\xAD\x90\x81 + \xF0\xAD\x90\x82 + \xF0\xAD\x90\x83 + \xF0\xAD\x90\x84 + \xF0\xAD\x90\x85 + \xF0\xAD\x90\x86 + \xF0\xAD\x90\x87 + \xF0\xAD\x90\x88 + \xF0\xAD\x90\x89 + \xF0\xAD\x90\x8A + \xF0\xAD\x90\x8B + \xF0\xAD\x90\x8C + \xF0\xAD\x90\x8D + \xF0\xAD\x90\x8E + \xF0\xAD\x90\x8F + \xF0\xAD\x90\x90 + \xF0\xAD\x90\x91 + \xF0\xAD\x90\x92 + \xF0\xAD\x90\x93 + \xF0\xAD\x90\x94 + \xF0\xAD\x90\x95 + \xF0\xAD\x90\x96 + \xF0\xAD\x90\x97 + \xF0\xAD\x90\x98 + \xF0\xAD\x90\x99 + \xF0\xAD\x90\x9A + \xF0\xAD\x90\x9B + \xF0\xAD\x90\x9C + \xF0\xAD\x90\x9D + \xF0\xAD\x90\x9E + \xF0\xAD\x90\x9F + \xF0\xAD\x90\xA0 + \xF0\xAD\x90\xA1 + \xF0\xAD\x90\xA2 + \xF0\xAD\x90\xA3 + \xF0\xAD\x90\xA4 + \xF0\xAD\x90\xA5 + \xF0\xAD\x90\xA6 + \xF0\xAD\x90\xA7 + \xF0\xAD\x90\xA8 + \xF0\xAD\x90\xA9 + \xF0\xAD\x90\xAA + \xF0\xAD\x90\xAB + \xF0\xAD\x90\xAC + \xF0\xAD\x90\xAD + \xF0\xAD\x90\xAE + \xF0\xAD\x90\xAF + \xF0\xAD\x90\xB0 + \xF0\xAD\x90\xB1 + \xF0\xAD\x90\xB2 + \xF0\xAD\x90\xB3 + \xF0\xAD\x90\xB4 + \xF0\xAD\x90\xB5 + \xF0\xAD\x90\xB6 + \xF0\xAD\x90\xB7 + \xF0\xAD\x90\xB8 + \xF0\xAD\x90\xB9 + \xF0\xAD\x90\xBA + \xF0\xAD\x90\xBB + \xF0\xAD\x90\xBC + \xF0\xAD\x90\xBD + \xF0\xAD\x90\xBE + \xF0\xAD\x90\xBF + \xF0\xAD\x91\x80 + \xF0\xAD\x91\x81 + \xF0\xAD\x91\x82 + \xF0\xAD\x91\x83 + \xF0\xAD\x91\x84 + \xF0\xAD\x91\x85 + \xF0\xAD\x91\x86 + \xF0\xAD\x91\x87 + \xF0\xAD\x91\x88 + \xF0\xAD\x91\x89 + \xF0\xAD\x91\x8A + \xF0\xAD\x91\x8B + \xF0\xAD\x91\x8C + \xF0\xAD\x91\x8D + \xF0\xAD\x91\x8E + \xF0\xAD\x91\x8F + \xF0\xAD\x91\x90 + \xF0\xAD\x91\x91 + \xF0\xAD\x91\x92 + \xF0\xAD\x91\x93 + \xF0\xAD\x91\x94 + \xF0\xAD\x91\x95 + \xF0\xAD\x91\x96 + \xF0\xAD\x91\x97 + \xF0\xAD\x91\x98 + \xF0\xAD\x91\x99 + \xF0\xAD\x91\x9A + \xF0\xAD\x91\x9B + \xF0\xAD\x91\x9C + \xF0\xAD\x91\x9D + \xF0\xAD\x91\x9E + \xF0\xAD\x91\x9F + \xF0\xAD\x91\xA0 + \xF0\xAD\x91\xA1 + \xF0\xAD\x91\xA2 + \xF0\xAD\x91\xA3 + \xF0\xAD\x91\xA4 + \xF0\xAD\x91\xA5 + \xF0\xAD\x91\xA6 + \xF0\xAD\x91\xA7 + \xF0\xAD\x91\xA8 + \xF0\xAD\x91\xA9 + \xF0\xAD\x91\xAA + \xF0\xAD\x91\xAB + \xF0\xAD\x91\xAC + \xF0\xAD\x91\xAD + \xF0\xAD\x91\xAE + \xF0\xAD\x91\xAF + \xF0\xAD\x91\xB0 + \xF0\xAD\x91\xB1 + \xF0\xAD\x91\xB2 + \xF0\xAD\x91\xB3 + \xF0\xAD\x91\xB4 + \xF0\xAD\x91\xB5 + \xF0\xAD\x91\xB6 + \xF0\xAD\x91\xB7 + \xF0\xAD\x91\xB8 + \xF0\xAD\x91\xB9 + \xF0\xAD\x91\xBA + \xF0\xAD\x91\xBB + \xF0\xAD\x91\xBC + \xF0\xAD\x91\xBD + \xF0\xAD\x91\xBE + \xF0\xAD\x91\xBF + \xF0\xAD\x92\x80 + \xF0\xAD\x92\x81 + \xF0\xAD\x92\x82 + \xF0\xAD\x92\x83 + \xF0\xAD\x92\x84 + \xF0\xAD\x92\x85 + \xF0\xAD\x92\x86 + \xF0\xAD\x92\x87 + \xF0\xAD\x92\x88 + \xF0\xAD\x92\x89 + \xF0\xAD\x92\x8A + \xF0\xAD\x92\x8B + \xF0\xAD\x92\x8C + \xF0\xAD\x92\x8D + \xF0\xAD\x92\x8E + \xF0\xAD\x92\x8F + \xF0\xAD\x92\x90 + \xF0\xAD\x92\x91 + \xF0\xAD\x92\x92 + \xF0\xAD\x92\x93 + \xF0\xAD\x92\x94 + \xF0\xAD\x92\x95 + \xF0\xAD\x92\x96 + \xF0\xAD\x92\x97 + \xF0\xAD\x92\x98 + \xF0\xAD\x92\x99 + \xF0\xAD\x92\x9A + \xF0\xAD\x92\x9B + \xF0\xAD\x92\x9C + \xF0\xAD\x92\x9D + \xF0\xAD\x92\x9E + \xF0\xAD\x92\x9F + \xF0\xAD\x92\xA0 + \xF0\xAD\x92\xA1 + \xF0\xAD\x92\xA2 + \xF0\xAD\x92\xA3 + \xF0\xAD\x92\xA4 + \xF0\xAD\x92\xA5 + \xF0\xAD\x92\xA6 + \xF0\xAD\x92\xA7 + \xF0\xAD\x92\xA8 + \xF0\xAD\x92\xA9 + \xF0\xAD\x92\xAA + \xF0\xAD\x92\xAB + \xF0\xAD\x92\xAC + \xF0\xAD\x92\xAD + \xF0\xAD\x92\xAE + \xF0\xAD\x92\xAF + \xF0\xAD\x92\xB0 + \xF0\xAD\x92\xB1 + \xF0\xAD\x92\xB2 + \xF0\xAD\x92\xB3 + \xF0\xAD\x92\xB4 + \xF0\xAD\x92\xB5 + \xF0\xAD\x92\xB6 + \xF0\xAD\x92\xB7 + \xF0\xAD\x92\xB8 + \xF0\xAD\x92\xB9 + \xF0\xAD\x92\xBA + \xF0\xAD\x92\xBB + \xF0\xAD\x92\xBC + \xF0\xAD\x92\xBD + \xF0\xAD\x92\xBE + \xF0\xAD\x92\xBF + \xF0\xAD\x93\x80 + \xF0\xAD\x93\x81 + \xF0\xAD\x93\x82 + \xF0\xAD\x93\x83 + \xF0\xAD\x93\x84 + \xF0\xAD\x93\x85 + \xF0\xAD\x93\x86 + \xF0\xAD\x93\x87 + \xF0\xAD\x93\x88 + \xF0\xAD\x93\x89 + \xF0\xAD\x93\x8A + \xF0\xAD\x93\x8B + \xF0\xAD\x93\x8C + \xF0\xAD\x93\x8D + \xF0\xAD\x93\x8E + \xF0\xAD\x93\x8F + \xF0\xAD\x93\x90 + \xF0\xAD\x93\x91 + \xF0\xAD\x93\x92 + \xF0\xAD\x93\x93 + \xF0\xAD\x93\x94 + \xF0\xAD\x93\x95 + \xF0\xAD\x93\x96 + \xF0\xAD\x93\x97 + \xF0\xAD\x93\x98 + \xF0\xAD\x93\x99 + \xF0\xAD\x93\x9A + \xF0\xAD\x93\x9B + \xF0\xAD\x93\x9C + \xF0\xAD\x93\x9D + \xF0\xAD\x93\x9E + \xF0\xAD\x93\x9F + \xF0\xAD\x93\xA0 + \xF0\xAD\x93\xA1 + \xF0\xAD\x93\xA2 + \xF0\xAD\x93\xA3 + \xF0\xAD\x93\xA4 + \xF0\xAD\x93\xA5 + \xF0\xAD\x93\xA6 + \xF0\xAD\x93\xA7 + \xF0\xAD\x93\xA8 + \xF0\xAD\x93\xA9 + \xF0\xAD\x93\xAA + \xF0\xAD\x93\xAB + \xF0\xAD\x93\xAC + \xF0\xAD\x93\xAD + \xF0\xAD\x93\xAE + \xF0\xAD\x93\xAF + \xF0\xAD\x93\xB0 + \xF0\xAD\x93\xB1 + \xF0\xAD\x93\xB2 + \xF0\xAD\x93\xB3 + \xF0\xAD\x93\xB4 + \xF0\xAD\x93\xB5 + \xF0\xAD\x93\xB6 + \xF0\xAD\x93\xB7 + \xF0\xAD\x93\xB8 + \xF0\xAD\x93\xB9 + \xF0\xAD\x93\xBA + \xF0\xAD\x93\xBB + \xF0\xAD\x93\xBC + \xF0\xAD\x93\xBD + \xF0\xAD\x93\xBE + \xF0\xAD\x93\xBF + \xF0\xAD\x94\x80 + \xF0\xAD\x94\x81 + \xF0\xAD\x94\x82 + \xF0\xAD\x94\x83 + \xF0\xAD\x94\x84 + \xF0\xAD\x94\x85 + \xF0\xAD\x94\x86 + \xF0\xAD\x94\x87 + \xF0\xAD\x94\x88 + \xF0\xAD\x94\x89 + \xF0\xAD\x94\x8A + \xF0\xAD\x94\x8B + \xF0\xAD\x94\x8C + \xF0\xAD\x94\x8D + \xF0\xAD\x94\x8E + \xF0\xAD\x94\x8F + \xF0\xAD\x94\x90 + \xF0\xAD\x94\x91 + \xF0\xAD\x94\x92 + \xF0\xAD\x94\x93 + \xF0\xAD\x94\x94 + \xF0\xAD\x94\x95 + \xF0\xAD\x94\x96 + \xF0\xAD\x94\x97 + \xF0\xAD\x94\x98 + \xF0\xAD\x94\x99 + \xF0\xAD\x94\x9A + \xF0\xAD\x94\x9B + \xF0\xAD\x94\x9C + \xF0\xAD\x94\x9D + \xF0\xAD\x94\x9E + \xF0\xAD\x94\x9F + \xF0\xAD\x94\xA0 + \xF0\xAD\x94\xA1 + \xF0\xAD\x94\xA2 + \xF0\xAD\x94\xA3 + \xF0\xAD\x94\xA4 + \xF0\xAD\x94\xA5 + \xF0\xAD\x94\xA6 + \xF0\xAD\x94\xA7 + \xF0\xAD\x94\xA8 + \xF0\xAD\x94\xA9 + \xF0\xAD\x94\xAA + \xF0\xAD\x94\xAB + \xF0\xAD\x94\xAC + \xF0\xAD\x94\xAD + \xF0\xAD\x94\xAE + \xF0\xAD\x94\xAF + \xF0\xAD\x94\xB0 + \xF0\xAD\x94\xB1 + \xF0\xAD\x94\xB2 + \xF0\xAD\x94\xB3 + \xF0\xAD\x94\xB4 + \xF0\xAD\x94\xB5 + \xF0\xAD\x94\xB6 + \xF0\xAD\x94\xB7 + \xF0\xAD\x94\xB8 + \xF0\xAD\x94\xB9 + \xF0\xAD\x94\xBA + \xF0\xAD\x94\xBB + \xF0\xAD\x94\xBC + \xF0\xAD\x94\xBD + \xF0\xAD\x94\xBE + \xF0\xAD\x94\xBF + \xF0\xAD\x95\x80 + \xF0\xAD\x95\x81 + \xF0\xAD\x95\x82 + \xF0\xAD\x95\x83 + \xF0\xAD\x95\x84 + \xF0\xAD\x95\x85 + \xF0\xAD\x95\x86 + \xF0\xAD\x95\x87 + \xF0\xAD\x95\x88 + \xF0\xAD\x95\x89 + \xF0\xAD\x95\x8A + \xF0\xAD\x95\x8B + \xF0\xAD\x95\x8C + \xF0\xAD\x95\x8D + \xF0\xAD\x95\x8E + \xF0\xAD\x95\x8F + \xF0\xAD\x95\x90 + \xF0\xAD\x95\x91 + \xF0\xAD\x95\x92 + \xF0\xAD\x95\x93 + \xF0\xAD\x95\x94 + \xF0\xAD\x95\x95 + \xF0\xAD\x95\x96 + \xF0\xAD\x95\x97 + \xF0\xAD\x95\x98 + \xF0\xAD\x95\x99 + \xF0\xAD\x95\x9A + \xF0\xAD\x95\x9B + \xF0\xAD\x95\x9C + \xF0\xAD\x95\x9D + \xF0\xAD\x95\x9E + \xF0\xAD\x95\x9F + \xF0\xAD\x95\xA0 + \xF0\xAD\x95\xA1 + \xF0\xAD\x95\xA2 + \xF0\xAD\x95\xA3 + \xF0\xAD\x95\xA4 + \xF0\xAD\x95\xA5 + \xF0\xAD\x95\xA6 + \xF0\xAD\x95\xA7 + \xF0\xAD\x95\xA8 + \xF0\xAD\x95\xA9 + \xF0\xAD\x95\xAA + \xF0\xAD\x95\xAB + \xF0\xAD\x95\xAC + \xF0\xAD\x95\xAD + \xF0\xAD\x95\xAE + \xF0\xAD\x95\xAF + \xF0\xAD\x95\xB0 + \xF0\xAD\x95\xB1 + \xF0\xAD\x95\xB2 + \xF0\xAD\x95\xB3 + \xF0\xAD\x95\xB4 + \xF0\xAD\x95\xB5 + \xF0\xAD\x95\xB6 + \xF0\xAD\x95\xB7 + \xF0\xAD\x95\xB8 + \xF0\xAD\x95\xB9 + \xF0\xAD\x95\xBA + \xF0\xAD\x95\xBB + \xF0\xAD\x95\xBC + \xF0\xAD\x95\xBD + \xF0\xAD\x95\xBE + \xF0\xAD\x95\xBF + \xF0\xAD\x96\x80 + \xF0\xAD\x96\x81 + \xF0\xAD\x96\x82 + \xF0\xAD\x96\x83 + \xF0\xAD\x96\x84 + \xF0\xAD\x96\x85 + \xF0\xAD\x96\x86 + \xF0\xAD\x96\x87 + \xF0\xAD\x96\x88 + \xF0\xAD\x96\x89 + \xF0\xAD\x96\x8A + \xF0\xAD\x96\x8B + \xF0\xAD\x96\x8C + \xF0\xAD\x96\x8D + \xF0\xAD\x96\x8E + \xF0\xAD\x96\x8F + \xF0\xAD\x96\x90 + \xF0\xAD\x96\x91 + \xF0\xAD\x96\x92 + \xF0\xAD\x96\x93 + \xF0\xAD\x96\x94 + \xF0\xAD\x96\x95 + \xF0\xAD\x96\x96 + \xF0\xAD\x96\x97 + \xF0\xAD\x96\x98 + \xF0\xAD\x96\x99 + \xF0\xAD\x96\x9A + \xF0\xAD\x96\x9B + \xF0\xAD\x96\x9C + \xF0\xAD\x96\x9D + \xF0\xAD\x96\x9E + \xF0\xAD\x96\x9F + \xF0\xAD\x96\xA0 + \xF0\xAD\x96\xA1 + \xF0\xAD\x96\xA2 + \xF0\xAD\x96\xA3 + \xF0\xAD\x96\xA4 + \xF0\xAD\x96\xA5 + \xF0\xAD\x96\xA6 + \xF0\xAD\x96\xA7 + \xF0\xAD\x96\xA8 + \xF0\xAD\x96\xA9 + \xF0\xAD\x96\xAA + \xF0\xAD\x96\xAB + \xF0\xAD\x96\xAC + \xF0\xAD\x96\xAD + \xF0\xAD\x96\xAE + \xF0\xAD\x96\xAF + \xF0\xAD\x96\xB0 + \xF0\xAD\x96\xB1 + \xF0\xAD\x96\xB2 + \xF0\xAD\x96\xB3 + \xF0\xAD\x96\xB4 + \xF0\xAD\x96\xB5 + \xF0\xAD\x96\xB6 + \xF0\xAD\x96\xB7 + \xF0\xAD\x96\xB8 + \xF0\xAD\x96\xB9 + \xF0\xAD\x96\xBA + \xF0\xAD\x96\xBB + \xF0\xAD\x96\xBC + \xF0\xAD\x96\xBD + \xF0\xAD\x96\xBE + \xF0\xAD\x96\xBF + \xF0\xAD\x97\x80 + \xF0\xAD\x97\x81 + \xF0\xAD\x97\x82 + \xF0\xAD\x97\x83 + \xF0\xAD\x97\x84 + \xF0\xAD\x97\x85 + \xF0\xAD\x97\x86 + \xF0\xAD\x97\x87 + \xF0\xAD\x97\x88 + \xF0\xAD\x97\x89 + \xF0\xAD\x97\x8A + \xF0\xAD\x97\x8B + \xF0\xAD\x97\x8C + \xF0\xAD\x97\x8D + \xF0\xAD\x97\x8E + \xF0\xAD\x97\x8F + \xF0\xAD\x97\x90 + \xF0\xAD\x97\x91 + \xF0\xAD\x97\x92 + \xF0\xAD\x97\x93 + \xF0\xAD\x97\x94 + \xF0\xAD\x97\x95 + \xF0\xAD\x97\x96 + \xF0\xAD\x97\x97 + \xF0\xAD\x97\x98 + \xF0\xAD\x97\x99 + \xF0\xAD\x97\x9A + \xF0\xAD\x97\x9B + \xF0\xAD\x97\x9C + \xF0\xAD\x97\x9D + \xF0\xAD\x97\x9E + \xF0\xAD\x97\x9F + \xF0\xAD\x97\xA0 + \xF0\xAD\x97\xA1 + \xF0\xAD\x97\xA2 + \xF0\xAD\x97\xA3 + \xF0\xAD\x97\xA4 + \xF0\xAD\x97\xA5 + \xF0\xAD\x97\xA6 + \xF0\xAD\x97\xA7 + \xF0\xAD\x97\xA8 + \xF0\xAD\x97\xA9 + \xF0\xAD\x97\xAA + \xF0\xAD\x97\xAB + \xF0\xAD\x97\xAC + \xF0\xAD\x97\xAD + \xF0\xAD\x97\xAE + \xF0\xAD\x97\xAF + \xF0\xAD\x97\xB0 + \xF0\xAD\x97\xB1 + \xF0\xAD\x97\xB2 + \xF0\xAD\x97\xB3 + \xF0\xAD\x97\xB4 + \xF0\xAD\x97\xB5 + \xF0\xAD\x97\xB6 + \xF0\xAD\x97\xB7 + \xF0\xAD\x97\xB8 + \xF0\xAD\x97\xB9 + \xF0\xAD\x97\xBA + \xF0\xAD\x97\xBB + \xF0\xAD\x97\xBC + \xF0\xAD\x97\xBD + \xF0\xAD\x97\xBE + \xF0\xAD\x97\xBF + \xF0\xAD\x98\x80 + \xF0\xAD\x98\x81 + \xF0\xAD\x98\x82 + \xF0\xAD\x98\x83 + \xF0\xAD\x98\x84 + \xF0\xAD\x98\x85 + \xF0\xAD\x98\x86 + \xF0\xAD\x98\x87 + \xF0\xAD\x98\x88 + \xF0\xAD\x98\x89 + \xF0\xAD\x98\x8A + \xF0\xAD\x98\x8B + \xF0\xAD\x98\x8C + \xF0\xAD\x98\x8D + \xF0\xAD\x98\x8E + \xF0\xAD\x98\x8F + \xF0\xAD\x98\x90 + \xF0\xAD\x98\x91 + \xF0\xAD\x98\x92 + \xF0\xAD\x98\x93 + \xF0\xAD\x98\x94 + \xF0\xAD\x98\x95 + \xF0\xAD\x98\x96 + \xF0\xAD\x98\x97 + \xF0\xAD\x98\x98 + \xF0\xAD\x98\x99 + \xF0\xAD\x98\x9A + \xF0\xAD\x98\x9B + \xF0\xAD\x98\x9C + \xF0\xAD\x98\x9D + \xF0\xAD\x98\x9E + \xF0\xAD\x98\x9F + \xF0\xAD\x98\xA0 + \xF0\xAD\x98\xA1 + \xF0\xAD\x98\xA2 + \xF0\xAD\x98\xA3 + \xF0\xAD\x98\xA4 + \xF0\xAD\x98\xA5 + \xF0\xAD\x98\xA6 + \xF0\xAD\x98\xA7 + \xF0\xAD\x98\xA8 + \xF0\xAD\x98\xA9 + \xF0\xAD\x98\xAA + \xF0\xAD\x98\xAB + \xF0\xAD\x98\xAC + \xF0\xAD\x98\xAD + \xF0\xAD\x98\xAE + \xF0\xAD\x98\xAF + \xF0\xAD\x98\xB0 + \xF0\xAD\x98\xB1 + \xF0\xAD\x98\xB2 + \xF0\xAD\x98\xB3 + \xF0\xAD\x98\xB4 + \xF0\xAD\x98\xB5 + \xF0\xAD\x98\xB6 + \xF0\xAD\x98\xB7 + \xF0\xAD\x98\xB8 + \xF0\xAD\x98\xB9 + \xF0\xAD\x98\xBA + \xF0\xAD\x98\xBB + \xF0\xAD\x98\xBC + \xF0\xAD\x98\xBD + \xF0\xAD\x98\xBE + \xF0\xAD\x98\xBF + \xF0\xAD\x99\x80 + \xF0\xAD\x99\x81 + \xF0\xAD\x99\x82 + \xF0\xAD\x99\x83 + \xF0\xAD\x99\x84 + \xF0\xAD\x99\x85 + \xF0\xAD\x99\x86 + \xF0\xAD\x99\x87 + \xF0\xAD\x99\x88 + \xF0\xAD\x99\x89 + \xF0\xAD\x99\x8A + \xF0\xAD\x99\x8B + \xF0\xAD\x99\x8C + \xF0\xAD\x99\x8D + \xF0\xAD\x99\x8E + \xF0\xAD\x99\x8F + \xF0\xAD\x99\x90 + \xF0\xAD\x99\x91 + \xF0\xAD\x99\x92 + \xF0\xAD\x99\x93 + \xF0\xAD\x99\x94 + \xF0\xAD\x99\x95 + \xF0\xAD\x99\x96 + \xF0\xAD\x99\x97 + \xF0\xAD\x99\x98 + \xF0\xAD\x99\x99 + \xF0\xAD\x99\x9A + \xF0\xAD\x99\x9B + \xF0\xAD\x99\x9C + \xF0\xAD\x99\x9D + \xF0\xAD\x99\x9E + \xF0\xAD\x99\x9F + \xF0\xAD\x99\xA0 + \xF0\xAD\x99\xA1 + \xF0\xAD\x99\xA2 + \xF0\xAD\x99\xA3 + \xF0\xAD\x99\xA4 + \xF0\xAD\x99\xA5 + \xF0\xAD\x99\xA6 + \xF0\xAD\x99\xA7 + \xF0\xAD\x99\xA8 + \xF0\xAD\x99\xA9 + \xF0\xAD\x99\xAA + \xF0\xAD\x99\xAB + \xF0\xAD\x99\xAC + \xF0\xAD\x99\xAD + \xF0\xAD\x99\xAE + \xF0\xAD\x99\xAF + \xF0\xAD\x99\xB0 + \xF0\xAD\x99\xB1 + \xF0\xAD\x99\xB2 + \xF0\xAD\x99\xB3 + \xF0\xAD\x99\xB4 + \xF0\xAD\x99\xB5 + \xF0\xAD\x99\xB6 + \xF0\xAD\x99\xB7 + \xF0\xAD\x99\xB8 + \xF0\xAD\x99\xB9 + \xF0\xAD\x99\xBA + \xF0\xAD\x99\xBB + \xF0\xAD\x99\xBC + \xF0\xAD\x99\xBD + \xF0\xAD\x99\xBE + \xF0\xAD\x99\xBF + \xF0\xAD\x9A\x80 + \xF0\xAD\x9A\x81 + \xF0\xAD\x9A\x82 + \xF0\xAD\x9A\x83 + \xF0\xAD\x9A\x84 + \xF0\xAD\x9A\x85 + \xF0\xAD\x9A\x86 + \xF0\xAD\x9A\x87 + \xF0\xAD\x9A\x88 + \xF0\xAD\x9A\x89 + \xF0\xAD\x9A\x8A + \xF0\xAD\x9A\x8B + \xF0\xAD\x9A\x8C + \xF0\xAD\x9A\x8D + \xF0\xAD\x9A\x8E + \xF0\xAD\x9A\x8F + \xF0\xAD\x9A\x90 + \xF0\xAD\x9A\x91 + \xF0\xAD\x9A\x92 + \xF0\xAD\x9A\x93 + \xF0\xAD\x9A\x94 + \xF0\xAD\x9A\x95 + \xF0\xAD\x9A\x96 + \xF0\xAD\x9A\x97 + \xF0\xAD\x9A\x98 + \xF0\xAD\x9A\x99 + \xF0\xAD\x9A\x9A + \xF0\xAD\x9A\x9B + \xF0\xAD\x9A\x9C + \xF0\xAD\x9A\x9D + \xF0\xAD\x9A\x9E + \xF0\xAD\x9A\x9F + \xF0\xAD\x9A\xA0 + \xF0\xAD\x9A\xA1 + \xF0\xAD\x9A\xA2 + \xF0\xAD\x9A\xA3 + \xF0\xAD\x9A\xA4 + \xF0\xAD\x9A\xA5 + \xF0\xAD\x9A\xA6 + \xF0\xAD\x9A\xA7 + \xF0\xAD\x9A\xA8 + \xF0\xAD\x9A\xA9 + \xF0\xAD\x9A\xAA + \xF0\xAD\x9A\xAB + \xF0\xAD\x9A\xAC + \xF0\xAD\x9A\xAD + \xF0\xAD\x9A\xAE + \xF0\xAD\x9A\xAF + \xF0\xAD\x9A\xB0 + \xF0\xAD\x9A\xB1 + \xF0\xAD\x9A\xB2 + \xF0\xAD\x9A\xB3 + \xF0\xAD\x9A\xB4 + \xF0\xAD\x9A\xB5 + \xF0\xAD\x9A\xB6 + \xF0\xAD\x9A\xB7 + \xF0\xAD\x9A\xB8 + \xF0\xAD\x9A\xB9 + \xF0\xAD\x9A\xBA + \xF0\xAD\x9A\xBB + \xF0\xAD\x9A\xBC + \xF0\xAD\x9A\xBD + \xF0\xAD\x9A\xBE + \xF0\xAD\x9A\xBF + \xF0\xAD\x9B\x80 + \xF0\xAD\x9B\x81 + \xF0\xAD\x9B\x82 + \xF0\xAD\x9B\x83 + \xF0\xAD\x9B\x84 + \xF0\xAD\x9B\x85 + \xF0\xAD\x9B\x86 + \xF0\xAD\x9B\x87 + \xF0\xAD\x9B\x88 + \xF0\xAD\x9B\x89 + \xF0\xAD\x9B\x8A + \xF0\xAD\x9B\x8B + \xF0\xAD\x9B\x8C + \xF0\xAD\x9B\x8D + \xF0\xAD\x9B\x8E + \xF0\xAD\x9B\x8F + \xF0\xAD\x9B\x90 + \xF0\xAD\x9B\x91 + \xF0\xAD\x9B\x92 + \xF0\xAD\x9B\x93 + \xF0\xAD\x9B\x94 + \xF0\xAD\x9B\x95 + \xF0\xAD\x9B\x96 + \xF0\xAD\x9B\x97 + \xF0\xAD\x9B\x98 + \xF0\xAD\x9B\x99 + \xF0\xAD\x9B\x9A + \xF0\xAD\x9B\x9B + \xF0\xAD\x9B\x9C + \xF0\xAD\x9B\x9D + \xF0\xAD\x9B\x9E + \xF0\xAD\x9B\x9F + \xF0\xAD\x9B\xA0 + \xF0\xAD\x9B\xA1 + \xF0\xAD\x9B\xA2 + \xF0\xAD\x9B\xA3 + \xF0\xAD\x9B\xA4 + \xF0\xAD\x9B\xA5 + \xF0\xAD\x9B\xA6 + \xF0\xAD\x9B\xA7 + \xF0\xAD\x9B\xA8 + \xF0\xAD\x9B\xA9 + \xF0\xAD\x9B\xAA + \xF0\xAD\x9B\xAB + \xF0\xAD\x9B\xAC + \xF0\xAD\x9B\xAD + \xF0\xAD\x9B\xAE + \xF0\xAD\x9B\xAF + \xF0\xAD\x9B\xB0 + \xF0\xAD\x9B\xB1 + \xF0\xAD\x9B\xB2 + \xF0\xAD\x9B\xB3 + \xF0\xAD\x9B\xB4 + \xF0\xAD\x9B\xB5 + \xF0\xAD\x9B\xB6 + \xF0\xAD\x9B\xB7 + \xF0\xAD\x9B\xB8 + \xF0\xAD\x9B\xB9 + \xF0\xAD\x9B\xBA + \xF0\xAD\x9B\xBB + \xF0\xAD\x9B\xBC + \xF0\xAD\x9B\xBD + \xF0\xAD\x9B\xBE + \xF0\xAD\x9B\xBF + \xF0\xAD\x9C\x80 + \xF0\xAD\x9C\x81 + \xF0\xAD\x9C\x82 + \xF0\xAD\x9C\x83 + \xF0\xAD\x9C\x84 + \xF0\xAD\x9C\x85 + \xF0\xAD\x9C\x86 + \xF0\xAD\x9C\x87 + \xF0\xAD\x9C\x88 + \xF0\xAD\x9C\x89 + \xF0\xAD\x9C\x8A + \xF0\xAD\x9C\x8B + \xF0\xAD\x9C\x8C + \xF0\xAD\x9C\x8D + \xF0\xAD\x9C\x8E + \xF0\xAD\x9C\x8F + \xF0\xAD\x9C\x90 + \xF0\xAD\x9C\x91 + \xF0\xAD\x9C\x92 + \xF0\xAD\x9C\x93 + \xF0\xAD\x9C\x94 + \xF0\xAD\x9C\x95 + \xF0\xAD\x9C\x96 + \xF0\xAD\x9C\x97 + \xF0\xAD\x9C\x98 + \xF0\xAD\x9C\x99 + \xF0\xAD\x9C\x9A + \xF0\xAD\x9C\x9B + \xF0\xAD\x9C\x9C + \xF0\xAD\x9C\x9D + \xF0\xAD\x9C\x9E + \xF0\xAD\x9C\x9F + \xF0\xAD\x9C\xA0 + \xF0\xAD\x9C\xA1 + \xF0\xAD\x9C\xA2 + \xF0\xAD\x9C\xA3 + \xF0\xAD\x9C\xA4 + \xF0\xAD\x9C\xA5 + \xF0\xAD\x9C\xA6 + \xF0\xAD\x9C\xA7 + \xF0\xAD\x9C\xA8 + \xF0\xAD\x9C\xA9 + \xF0\xAD\x9C\xAA + \xF0\xAD\x9C\xAB + \xF0\xAD\x9C\xAC + \xF0\xAD\x9C\xAD + \xF0\xAD\x9C\xAE + \xF0\xAD\x9C\xAF + \xF0\xAD\x9C\xB0 + \xF0\xAD\x9C\xB1 + \xF0\xAD\x9C\xB2 + \xF0\xAD\x9C\xB3 + \xF0\xAD\x9C\xB4 + \xF0\xAD\x9C\xB5 + \xF0\xAD\x9C\xB6 + \xF0\xAD\x9C\xB7 + \xF0\xAD\x9C\xB8 + \xF0\xAD\x9C\xB9 + \xF0\xAD\x9C\xBA + \xF0\xAD\x9C\xBB + \xF0\xAD\x9C\xBC + \xF0\xAD\x9C\xBD + \xF0\xAD\x9C\xBE + \xF0\xAD\x9C\xBF + \xF0\xAD\x9D\x80 + \xF0\xAD\x9D\x81 + \xF0\xAD\x9D\x82 + \xF0\xAD\x9D\x83 + \xF0\xAD\x9D\x84 + \xF0\xAD\x9D\x85 + \xF0\xAD\x9D\x86 + \xF0\xAD\x9D\x87 + \xF0\xAD\x9D\x88 + \xF0\xAD\x9D\x89 + \xF0\xAD\x9D\x8A + \xF0\xAD\x9D\x8B + \xF0\xAD\x9D\x8C + \xF0\xAD\x9D\x8D + \xF0\xAD\x9D\x8E + \xF0\xAD\x9D\x8F + \xF0\xAD\x9D\x90 + \xF0\xAD\x9D\x91 + \xF0\xAD\x9D\x92 + \xF0\xAD\x9D\x93 + \xF0\xAD\x9D\x94 + \xF0\xAD\x9D\x95 + \xF0\xAD\x9D\x96 + \xF0\xAD\x9D\x97 + \xF0\xAD\x9D\x98 + \xF0\xAD\x9D\x99 + \xF0\xAD\x9D\x9A + \xF0\xAD\x9D\x9B + \xF0\xAD\x9D\x9C + \xF0\xAD\x9D\x9D + \xF0\xAD\x9D\x9E + \xF0\xAD\x9D\x9F + \xF0\xAD\x9D\xA0 + \xF0\xAD\x9D\xA1 + \xF0\xAD\x9D\xA2 + \xF0\xAD\x9D\xA3 + \xF0\xAD\x9D\xA4 + \xF0\xAD\x9D\xA5 + \xF0\xAD\x9D\xA6 + \xF0\xAD\x9D\xA7 + \xF0\xAD\x9D\xA8 + \xF0\xAD\x9D\xA9 + \xF0\xAD\x9D\xAA + \xF0\xAD\x9D\xAB + \xF0\xAD\x9D\xAC + \xF0\xAD\x9D\xAD + \xF0\xAD\x9D\xAE + \xF0\xAD\x9D\xAF + \xF0\xAD\x9D\xB0 + \xF0\xAD\x9D\xB1 + \xF0\xAD\x9D\xB2 + \xF0\xAD\x9D\xB3 + \xF0\xAD\x9D\xB4 + \xF0\xAD\x9D\xB5 + \xF0\xAD\x9D\xB6 + \xF0\xAD\x9D\xB7 + \xF0\xAD\x9D\xB8 + \xF0\xAD\x9D\xB9 + \xF0\xAD\x9D\xBA + \xF0\xAD\x9D\xBB + \xF0\xAD\x9D\xBC + \xF0\xAD\x9D\xBD + \xF0\xAD\x9D\xBE + \xF0\xAD\x9D\xBF + \xF0\xAD\x9E\x80 + \xF0\xAD\x9E\x81 + \xF0\xAD\x9E\x82 + \xF0\xAD\x9E\x83 + \xF0\xAD\x9E\x84 + \xF0\xAD\x9E\x85 + \xF0\xAD\x9E\x86 + \xF0\xAD\x9E\x87 + \xF0\xAD\x9E\x88 + \xF0\xAD\x9E\x89 + \xF0\xAD\x9E\x8A + \xF0\xAD\x9E\x8B + \xF0\xAD\x9E\x8C + \xF0\xAD\x9E\x8D + \xF0\xAD\x9E\x8E + \xF0\xAD\x9E\x8F + \xF0\xAD\x9E\x90 + \xF0\xAD\x9E\x91 + \xF0\xAD\x9E\x92 + \xF0\xAD\x9E\x93 + \xF0\xAD\x9E\x94 + \xF0\xAD\x9E\x95 + \xF0\xAD\x9E\x96 + \xF0\xAD\x9E\x97 + \xF0\xAD\x9E\x98 + \xF0\xAD\x9E\x99 + \xF0\xAD\x9E\x9A + \xF0\xAD\x9E\x9B + \xF0\xAD\x9E\x9C + \xF0\xAD\x9E\x9D + \xF0\xAD\x9E\x9E + \xF0\xAD\x9E\x9F + \xF0\xAD\x9E\xA0 + \xF0\xAD\x9E\xA1 + \xF0\xAD\x9E\xA2 + \xF0\xAD\x9E\xA3 + \xF0\xAD\x9E\xA4 + \xF0\xAD\x9E\xA5 + \xF0\xAD\x9E\xA6 + \xF0\xAD\x9E\xA7 + \xF0\xAD\x9E\xA8 + \xF0\xAD\x9E\xA9 + \xF0\xAD\x9E\xAA + \xF0\xAD\x9E\xAB + \xF0\xAD\x9E\xAC + \xF0\xAD\x9E\xAD + \xF0\xAD\x9E\xAE + \xF0\xAD\x9E\xAF + \xF0\xAD\x9E\xB0 + \xF0\xAD\x9E\xB1 + \xF0\xAD\x9E\xB2 + \xF0\xAD\x9E\xB3 + \xF0\xAD\x9E\xB4 + \xF0\xAD\x9E\xB5 + \xF0\xAD\x9E\xB6 + \xF0\xAD\x9E\xB7 + \xF0\xAD\x9E\xB8 + \xF0\xAD\x9E\xB9 + \xF0\xAD\x9E\xBA + \xF0\xAD\x9E\xBB + \xF0\xAD\x9E\xBC + \xF0\xAD\x9E\xBD + \xF0\xAD\x9E\xBE + \xF0\xAD\x9E\xBF + \xF0\xAD\x9F\x80 + \xF0\xAD\x9F\x81 + \xF0\xAD\x9F\x82 + \xF0\xAD\x9F\x83 + \xF0\xAD\x9F\x84 + \xF0\xAD\x9F\x85 + \xF0\xAD\x9F\x86 + \xF0\xAD\x9F\x87 + \xF0\xAD\x9F\x88 + \xF0\xAD\x9F\x89 + \xF0\xAD\x9F\x8A + \xF0\xAD\x9F\x8B + \xF0\xAD\x9F\x8C + \xF0\xAD\x9F\x8D + \xF0\xAD\x9F\x8E + \xF0\xAD\x9F\x8F + \xF0\xAD\x9F\x90 + \xF0\xAD\x9F\x91 + \xF0\xAD\x9F\x92 + \xF0\xAD\x9F\x93 + \xF0\xAD\x9F\x94 + \xF0\xAD\x9F\x95 + \xF0\xAD\x9F\x96 + \xF0\xAD\x9F\x97 + \xF0\xAD\x9F\x98 + \xF0\xAD\x9F\x99 + \xF0\xAD\x9F\x9A + \xF0\xAD\x9F\x9B + \xF0\xAD\x9F\x9C + \xF0\xAD\x9F\x9D + \xF0\xAD\x9F\x9E + \xF0\xAD\x9F\x9F + \xF0\xAD\x9F\xA0 + \xF0\xAD\x9F\xA1 + \xF0\xAD\x9F\xA2 + \xF0\xAD\x9F\xA3 + \xF0\xAD\x9F\xA4 + \xF0\xAD\x9F\xA5 + \xF0\xAD\x9F\xA6 + \xF0\xAD\x9F\xA7 + \xF0\xAD\x9F\xA8 + \xF0\xAD\x9F\xA9 + \xF0\xAD\x9F\xAA + \xF0\xAD\x9F\xAB + \xF0\xAD\x9F\xAC + \xF0\xAD\x9F\xAD + \xF0\xAD\x9F\xAE + \xF0\xAD\x9F\xAF + \xF0\xAD\x9F\xB0 + \xF0\xAD\x9F\xB1 + \xF0\xAD\x9F\xB2 + \xF0\xAD\x9F\xB3 + \xF0\xAD\x9F\xB4 + \xF0\xAD\x9F\xB5 + \xF0\xAD\x9F\xB6 + \xF0\xAD\x9F\xB7 + \xF0\xAD\x9F\xB8 + \xF0\xAD\x9F\xB9 + \xF0\xAD\x9F\xBA + \xF0\xAD\x9F\xBB + \xF0\xAD\x9F\xBC + \xF0\xAD\x9F\xBD + \xF0\xAD\x9F\xBE + \xF0\xAD\x9F\xBF + \xF0\xAD\xA0\x80 + \xF0\xAD\xA0\x81 + \xF0\xAD\xA0\x82 + \xF0\xAD\xA0\x83 + \xF0\xAD\xA0\x84 + \xF0\xAD\xA0\x85 + \xF0\xAD\xA0\x86 + \xF0\xAD\xA0\x87 + \xF0\xAD\xA0\x88 + \xF0\xAD\xA0\x89 + \xF0\xAD\xA0\x8A + \xF0\xAD\xA0\x8B + \xF0\xAD\xA0\x8C + \xF0\xAD\xA0\x8D + \xF0\xAD\xA0\x8E + \xF0\xAD\xA0\x8F + \xF0\xAD\xA0\x90 + \xF0\xAD\xA0\x91 + \xF0\xAD\xA0\x92 + \xF0\xAD\xA0\x93 + \xF0\xAD\xA0\x94 + \xF0\xAD\xA0\x95 + \xF0\xAD\xA0\x96 + \xF0\xAD\xA0\x97 + \xF0\xAD\xA0\x98 + \xF0\xAD\xA0\x99 + \xF0\xAD\xA0\x9A + \xF0\xAD\xA0\x9B + \xF0\xAD\xA0\x9C + \xF0\xAD\xA0\x9D + \xF0\xAD\xA0\x9E + \xF0\xAD\xA0\x9F + \xF0\xAD\xA0\xA0 + \xF0\xAD\xA0\xA1 + \xF0\xAD\xA0\xA2 + \xF0\xAD\xA0\xA3 + \xF0\xAD\xA0\xA4 + \xF0\xAD\xA0\xA5 + \xF0\xAD\xA0\xA6 + \xF0\xAD\xA0\xA7 + \xF0\xAD\xA0\xA8 + \xF0\xAD\xA0\xA9 + \xF0\xAD\xA0\xAA + \xF0\xAD\xA0\xAB + \xF0\xAD\xA0\xAC + \xF0\xAD\xA0\xAD + \xF0\xAD\xA0\xAE + \xF0\xAD\xA0\xAF + \xF0\xAD\xA0\xB0 + \xF0\xAD\xA0\xB1 + \xF0\xAD\xA0\xB2 + \xF0\xAD\xA0\xB3 + \xF0\xAD\xA0\xB4 + \xF0\xAD\xA0\xB5 + \xF0\xAD\xA0\xB6 + \xF0\xAD\xA0\xB7 + \xF0\xAD\xA0\xB8 + \xF0\xAD\xA0\xB9 + \xF0\xAD\xA0\xBA + \xF0\xAD\xA0\xBB + \xF0\xAD\xA0\xBC + \xF0\xAD\xA0\xBD + \xF0\xAD\xA0\xBE + \xF0\xAD\xA0\xBF + \xF0\xAD\xA1\x80 + \xF0\xAD\xA1\x81 + \xF0\xAD\xA1\x82 + \xF0\xAD\xA1\x83 + \xF0\xAD\xA1\x84 + \xF0\xAD\xA1\x85 + \xF0\xAD\xA1\x86 + \xF0\xAD\xA1\x87 + \xF0\xAD\xA1\x88 + \xF0\xAD\xA1\x89 + \xF0\xAD\xA1\x8A + \xF0\xAD\xA1\x8B + \xF0\xAD\xA1\x8C + \xF0\xAD\xA1\x8D + \xF0\xAD\xA1\x8E + \xF0\xAD\xA1\x8F + \xF0\xAD\xA1\x90 + \xF0\xAD\xA1\x91 + \xF0\xAD\xA1\x92 + \xF0\xAD\xA1\x93 + \xF0\xAD\xA1\x94 + \xF0\xAD\xA1\x95 + \xF0\xAD\xA1\x96 + \xF0\xAD\xA1\x97 + \xF0\xAD\xA1\x98 + \xF0\xAD\xA1\x99 + \xF0\xAD\xA1\x9A + \xF0\xAD\xA1\x9B + \xF0\xAD\xA1\x9C + \xF0\xAD\xA1\x9D + \xF0\xAD\xA1\x9E + \xF0\xAD\xA1\x9F + \xF0\xAD\xA1\xA0 + \xF0\xAD\xA1\xA1 + \xF0\xAD\xA1\xA2 + \xF0\xAD\xA1\xA3 + \xF0\xAD\xA1\xA4 + \xF0\xAD\xA1\xA5 + \xF0\xAD\xA1\xA6 + \xF0\xAD\xA1\xA7 + \xF0\xAD\xA1\xA8 + \xF0\xAD\xA1\xA9 + \xF0\xAD\xA1\xAA + \xF0\xAD\xA1\xAB + \xF0\xAD\xA1\xAC + \xF0\xAD\xA1\xAD + \xF0\xAD\xA1\xAE + \xF0\xAD\xA1\xAF + \xF0\xAD\xA1\xB0 + \xF0\xAD\xA1\xB1 + \xF0\xAD\xA1\xB2 + \xF0\xAD\xA1\xB3 + \xF0\xAD\xA1\xB4 + \xF0\xAD\xA1\xB5 + \xF0\xAD\xA1\xB6 + \xF0\xAD\xA1\xB7 + \xF0\xAD\xA1\xB8 + \xF0\xAD\xA1\xB9 + \xF0\xAD\xA1\xBA + \xF0\xAD\xA1\xBB + \xF0\xAD\xA1\xBC + \xF0\xAD\xA1\xBD + \xF0\xAD\xA1\xBE + \xF0\xAD\xA1\xBF + \xF0\xAD\xA2\x80 + \xF0\xAD\xA2\x81 + \xF0\xAD\xA2\x82 + \xF0\xAD\xA2\x83 + \xF0\xAD\xA2\x84 + \xF0\xAD\xA2\x85 + \xF0\xAD\xA2\x86 + \xF0\xAD\xA2\x87 + \xF0\xAD\xA2\x88 + \xF0\xAD\xA2\x89 + \xF0\xAD\xA2\x8A + \xF0\xAD\xA2\x8B + \xF0\xAD\xA2\x8C + \xF0\xAD\xA2\x8D + \xF0\xAD\xA2\x8E + \xF0\xAD\xA2\x8F + \xF0\xAD\xA2\x90 + \xF0\xAD\xA2\x91 + \xF0\xAD\xA2\x92 + \xF0\xAD\xA2\x93 + \xF0\xAD\xA2\x94 + \xF0\xAD\xA2\x95 + \xF0\xAD\xA2\x96 + \xF0\xAD\xA2\x97 + \xF0\xAD\xA2\x98 + \xF0\xAD\xA2\x99 + \xF0\xAD\xA2\x9A + \xF0\xAD\xA2\x9B + \xF0\xAD\xA2\x9C + \xF0\xAD\xA2\x9D + \xF0\xAD\xA2\x9E + \xF0\xAD\xA2\x9F + \xF0\xAD\xA2\xA0 + \xF0\xAD\xA2\xA1 + \xF0\xAD\xA2\xA2 + \xF0\xAD\xA2\xA3 + \xF0\xAD\xA2\xA4 + \xF0\xAD\xA2\xA5 + \xF0\xAD\xA2\xA6 + \xF0\xAD\xA2\xA7 + \xF0\xAD\xA2\xA8 + \xF0\xAD\xA2\xA9 + \xF0\xAD\xA2\xAA + \xF0\xAD\xA2\xAB + \xF0\xAD\xA2\xAC + \xF0\xAD\xA2\xAD + \xF0\xAD\xA2\xAE + \xF0\xAD\xA2\xAF + \xF0\xAD\xA2\xB0 + \xF0\xAD\xA2\xB1 + \xF0\xAD\xA2\xB2 + \xF0\xAD\xA2\xB3 + \xF0\xAD\xA2\xB4 + \xF0\xAD\xA2\xB5 + \xF0\xAD\xA2\xB6 + \xF0\xAD\xA2\xB7 + \xF0\xAD\xA2\xB8 + \xF0\xAD\xA2\xB9 + \xF0\xAD\xA2\xBA + \xF0\xAD\xA2\xBB + \xF0\xAD\xA2\xBC + \xF0\xAD\xA2\xBD + \xF0\xAD\xA2\xBE + \xF0\xAD\xA2\xBF + \xF0\xAD\xA3\x80 + \xF0\xAD\xA3\x81 + \xF0\xAD\xA3\x82 + \xF0\xAD\xA3\x83 + \xF0\xAD\xA3\x84 + \xF0\xAD\xA3\x85 + \xF0\xAD\xA3\x86 + \xF0\xAD\xA3\x87 + \xF0\xAD\xA3\x88 + \xF0\xAD\xA3\x89 + \xF0\xAD\xA3\x8A + \xF0\xAD\xA3\x8B + \xF0\xAD\xA3\x8C + \xF0\xAD\xA3\x8D + \xF0\xAD\xA3\x8E + \xF0\xAD\xA3\x8F + \xF0\xAD\xA3\x90 + \xF0\xAD\xA3\x91 + \xF0\xAD\xA3\x92 + \xF0\xAD\xA3\x93 + \xF0\xAD\xA3\x94 + \xF0\xAD\xA3\x95 + \xF0\xAD\xA3\x96 + \xF0\xAD\xA3\x97 + \xF0\xAD\xA3\x98 + \xF0\xAD\xA3\x99 + \xF0\xAD\xA3\x9A + \xF0\xAD\xA3\x9B + \xF0\xAD\xA3\x9C + \xF0\xAD\xA3\x9D + \xF0\xAD\xA3\x9E + \xF0\xAD\xA3\x9F + \xF0\xAD\xA3\xA0 + \xF0\xAD\xA3\xA1 + \xF0\xAD\xA3\xA2 + \xF0\xAD\xA3\xA3 + \xF0\xAD\xA3\xA4 + \xF0\xAD\xA3\xA5 + \xF0\xAD\xA3\xA6 + \xF0\xAD\xA3\xA7 + \xF0\xAD\xA3\xA8 + \xF0\xAD\xA3\xA9 + \xF0\xAD\xA3\xAA + \xF0\xAD\xA3\xAB + \xF0\xAD\xA3\xAC + \xF0\xAD\xA3\xAD + \xF0\xAD\xA3\xAE + \xF0\xAD\xA3\xAF + \xF0\xAD\xA3\xB0 + \xF0\xAD\xA3\xB1 + \xF0\xAD\xA3\xB2 + \xF0\xAD\xA3\xB3 + \xF0\xAD\xA3\xB4 + \xF0\xAD\xA3\xB5 + \xF0\xAD\xA3\xB6 + \xF0\xAD\xA3\xB7 + \xF0\xAD\xA3\xB8 + \xF0\xAD\xA3\xB9 + \xF0\xAD\xA3\xBA + \xF0\xAD\xA3\xBB + \xF0\xAD\xA3\xBC + \xF0\xAD\xA3\xBD + \xF0\xAD\xA3\xBE + \xF0\xAD\xA3\xBF + \xF0\xAD\xA4\x80 + \xF0\xAD\xA4\x81 + \xF0\xAD\xA4\x82 + \xF0\xAD\xA4\x83 + \xF0\xAD\xA4\x84 + \xF0\xAD\xA4\x85 + \xF0\xAD\xA4\x86 + \xF0\xAD\xA4\x87 + \xF0\xAD\xA4\x88 + \xF0\xAD\xA4\x89 + \xF0\xAD\xA4\x8A + \xF0\xAD\xA4\x8B + \xF0\xAD\xA4\x8C + \xF0\xAD\xA4\x8D + \xF0\xAD\xA4\x8E + \xF0\xAD\xA4\x8F + \xF0\xAD\xA4\x90 + \xF0\xAD\xA4\x91 + \xF0\xAD\xA4\x92 + \xF0\xAD\xA4\x93 + \xF0\xAD\xA4\x94 + \xF0\xAD\xA4\x95 + \xF0\xAD\xA4\x96 + \xF0\xAD\xA4\x97 + \xF0\xAD\xA4\x98 + \xF0\xAD\xA4\x99 + \xF0\xAD\xA4\x9A + \xF0\xAD\xA4\x9B + \xF0\xAD\xA4\x9C + \xF0\xAD\xA4\x9D + \xF0\xAD\xA4\x9E + \xF0\xAD\xA4\x9F + \xF0\xAD\xA4\xA0 + \xF0\xAD\xA4\xA1 + \xF0\xAD\xA4\xA2 + \xF0\xAD\xA4\xA3 + \xF0\xAD\xA4\xA4 + \xF0\xAD\xA4\xA5 + \xF0\xAD\xA4\xA6 + \xF0\xAD\xA4\xA7 + \xF0\xAD\xA4\xA8 + \xF0\xAD\xA4\xA9 + \xF0\xAD\xA4\xAA + \xF0\xAD\xA4\xAB + \xF0\xAD\xA4\xAC + \xF0\xAD\xA4\xAD + \xF0\xAD\xA4\xAE + \xF0\xAD\xA4\xAF + \xF0\xAD\xA4\xB0 + \xF0\xAD\xA4\xB1 + \xF0\xAD\xA4\xB2 + \xF0\xAD\xA4\xB3 + \xF0\xAD\xA4\xB4 + \xF0\xAD\xA4\xB5 + \xF0\xAD\xA4\xB6 + \xF0\xAD\xA4\xB7 + \xF0\xAD\xA4\xB8 + \xF0\xAD\xA4\xB9 + \xF0\xAD\xA4\xBA + \xF0\xAD\xA4\xBB + \xF0\xAD\xA4\xBC + \xF0\xAD\xA4\xBD + \xF0\xAD\xA4\xBE + \xF0\xAD\xA4\xBF + \xF0\xAD\xA5\x80 + \xF0\xAD\xA5\x81 + \xF0\xAD\xA5\x82 + \xF0\xAD\xA5\x83 + \xF0\xAD\xA5\x84 + \xF0\xAD\xA5\x85 + \xF0\xAD\xA5\x86 + \xF0\xAD\xA5\x87 + \xF0\xAD\xA5\x88 + \xF0\xAD\xA5\x89 + \xF0\xAD\xA5\x8A + \xF0\xAD\xA5\x8B + \xF0\xAD\xA5\x8C + \xF0\xAD\xA5\x8D + \xF0\xAD\xA5\x8E + \xF0\xAD\xA5\x8F + \xF0\xAD\xA5\x90 + \xF0\xAD\xA5\x91 + \xF0\xAD\xA5\x92 + \xF0\xAD\xA5\x93 + \xF0\xAD\xA5\x94 + \xF0\xAD\xA5\x95 + \xF0\xAD\xA5\x96 + \xF0\xAD\xA5\x97 + \xF0\xAD\xA5\x98 + \xF0\xAD\xA5\x99 + \xF0\xAD\xA5\x9A + \xF0\xAD\xA5\x9B + \xF0\xAD\xA5\x9C + \xF0\xAD\xA5\x9D + \xF0\xAD\xA5\x9E + \xF0\xAD\xA5\x9F + \xF0\xAD\xA5\xA0 + \xF0\xAD\xA5\xA1 + \xF0\xAD\xA5\xA2 + \xF0\xAD\xA5\xA3 + \xF0\xAD\xA5\xA4 + \xF0\xAD\xA5\xA5 + \xF0\xAD\xA5\xA6 + \xF0\xAD\xA5\xA7 + \xF0\xAD\xA5\xA8 + \xF0\xAD\xA5\xA9 + \xF0\xAD\xA5\xAA + \xF0\xAD\xA5\xAB + \xF0\xAD\xA5\xAC + \xF0\xAD\xA5\xAD + \xF0\xAD\xA5\xAE + \xF0\xAD\xA5\xAF + \xF0\xAD\xA5\xB0 + \xF0\xAD\xA5\xB1 + \xF0\xAD\xA5\xB2 + \xF0\xAD\xA5\xB3 + \xF0\xAD\xA5\xB4 + \xF0\xAD\xA5\xB5 + \xF0\xAD\xA5\xB6 + \xF0\xAD\xA5\xB7 + \xF0\xAD\xA5\xB8 + \xF0\xAD\xA5\xB9 + \xF0\xAD\xA5\xBA + \xF0\xAD\xA5\xBB + \xF0\xAD\xA5\xBC + \xF0\xAD\xA5\xBD + \xF0\xAD\xA5\xBE + \xF0\xAD\xA5\xBF + \xF0\xAD\xA6\x80 + \xF0\xAD\xA6\x81 + \xF0\xAD\xA6\x82 + \xF0\xAD\xA6\x83 + \xF0\xAD\xA6\x84 + \xF0\xAD\xA6\x85 + \xF0\xAD\xA6\x86 + \xF0\xAD\xA6\x87 + \xF0\xAD\xA6\x88 + \xF0\xAD\xA6\x89 + \xF0\xAD\xA6\x8A + \xF0\xAD\xA6\x8B + \xF0\xAD\xA6\x8C + \xF0\xAD\xA6\x8D + \xF0\xAD\xA6\x8E + \xF0\xAD\xA6\x8F + \xF0\xAD\xA6\x90 + \xF0\xAD\xA6\x91 + \xF0\xAD\xA6\x92 + \xF0\xAD\xA6\x93 + \xF0\xAD\xA6\x94 + \xF0\xAD\xA6\x95 + \xF0\xAD\xA6\x96 + \xF0\xAD\xA6\x97 + \xF0\xAD\xA6\x98 + \xF0\xAD\xA6\x99 + \xF0\xAD\xA6\x9A + \xF0\xAD\xA6\x9B + \xF0\xAD\xA6\x9C + \xF0\xAD\xA6\x9D + \xF0\xAD\xA6\x9E + \xF0\xAD\xA6\x9F + \xF0\xAD\xA6\xA0 + \xF0\xAD\xA6\xA1 + \xF0\xAD\xA6\xA2 + \xF0\xAD\xA6\xA3 + \xF0\xAD\xA6\xA4 + \xF0\xAD\xA6\xA5 + \xF0\xAD\xA6\xA6 + \xF0\xAD\xA6\xA7 + \xF0\xAD\xA6\xA8 + \xF0\xAD\xA6\xA9 + \xF0\xAD\xA6\xAA + \xF0\xAD\xA6\xAB + \xF0\xAD\xA6\xAC + \xF0\xAD\xA6\xAD + \xF0\xAD\xA6\xAE + \xF0\xAD\xA6\xAF + \xF0\xAD\xA6\xB0 + \xF0\xAD\xA6\xB1 + \xF0\xAD\xA6\xB2 + \xF0\xAD\xA6\xB3 + \xF0\xAD\xA6\xB4 + \xF0\xAD\xA6\xB5 + \xF0\xAD\xA6\xB6 + \xF0\xAD\xA6\xB7 + \xF0\xAD\xA6\xB8 + \xF0\xAD\xA6\xB9 + \xF0\xAD\xA6\xBA + \xF0\xAD\xA6\xBB + \xF0\xAD\xA6\xBC + \xF0\xAD\xA6\xBD + \xF0\xAD\xA6\xBE + \xF0\xAD\xA6\xBF + \xF0\xAD\xA7\x80 + \xF0\xAD\xA7\x81 + \xF0\xAD\xA7\x82 + \xF0\xAD\xA7\x83 + \xF0\xAD\xA7\x84 + \xF0\xAD\xA7\x85 + \xF0\xAD\xA7\x86 + \xF0\xAD\xA7\x87 + \xF0\xAD\xA7\x88 + \xF0\xAD\xA7\x89 + \xF0\xAD\xA7\x8A + \xF0\xAD\xA7\x8B + \xF0\xAD\xA7\x8C + \xF0\xAD\xA7\x8D + \xF0\xAD\xA7\x8E + \xF0\xAD\xA7\x8F + \xF0\xAD\xA7\x90 + \xF0\xAD\xA7\x91 + \xF0\xAD\xA7\x92 + \xF0\xAD\xA7\x93 + \xF0\xAD\xA7\x94 + \xF0\xAD\xA7\x95 + \xF0\xAD\xA7\x96 + \xF0\xAD\xA7\x97 + \xF0\xAD\xA7\x98 + \xF0\xAD\xA7\x99 + \xF0\xAD\xA7\x9A + \xF0\xAD\xA7\x9B + \xF0\xAD\xA7\x9C + \xF0\xAD\xA7\x9D + \xF0\xAD\xA7\x9E + \xF0\xAD\xA7\x9F + \xF0\xAD\xA7\xA0 + \xF0\xAD\xA7\xA1 + \xF0\xAD\xA7\xA2 + \xF0\xAD\xA7\xA3 + \xF0\xAD\xA7\xA4 + \xF0\xAD\xA7\xA5 + \xF0\xAD\xA7\xA6 + \xF0\xAD\xA7\xA7 + \xF0\xAD\xA7\xA8 + \xF0\xAD\xA7\xA9 + \xF0\xAD\xA7\xAA + \xF0\xAD\xA7\xAB + \xF0\xAD\xA7\xAC + \xF0\xAD\xA7\xAD + \xF0\xAD\xA7\xAE + \xF0\xAD\xA7\xAF + \xF0\xAD\xA7\xB0 + \xF0\xAD\xA7\xB1 + \xF0\xAD\xA7\xB2 + \xF0\xAD\xA7\xB3 + \xF0\xAD\xA7\xB4 + \xF0\xAD\xA7\xB5 + \xF0\xAD\xA7\xB6 + \xF0\xAD\xA7\xB7 + \xF0\xAD\xA7\xB8 + \xF0\xAD\xA7\xB9 + \xF0\xAD\xA7\xBA + \xF0\xAD\xA7\xBB + \xF0\xAD\xA7\xBC + \xF0\xAD\xA7\xBD + \xF0\xAD\xA7\xBE + \xF0\xAD\xA7\xBF + \xF0\xAD\xA8\x80 + \xF0\xAD\xA8\x81 + \xF0\xAD\xA8\x82 + \xF0\xAD\xA8\x83 + \xF0\xAD\xA8\x84 + \xF0\xAD\xA8\x85 + \xF0\xAD\xA8\x86 + \xF0\xAD\xA8\x87 + \xF0\xAD\xA8\x88 + \xF0\xAD\xA8\x89 + \xF0\xAD\xA8\x8A + \xF0\xAD\xA8\x8B + \xF0\xAD\xA8\x8C + \xF0\xAD\xA8\x8D + \xF0\xAD\xA8\x8E + \xF0\xAD\xA8\x8F + \xF0\xAD\xA8\x90 + \xF0\xAD\xA8\x91 + \xF0\xAD\xA8\x92 + \xF0\xAD\xA8\x93 + \xF0\xAD\xA8\x94 + \xF0\xAD\xA8\x95 + \xF0\xAD\xA8\x96 + \xF0\xAD\xA8\x97 + \xF0\xAD\xA8\x98 + \xF0\xAD\xA8\x99 + \xF0\xAD\xA8\x9A + \xF0\xAD\xA8\x9B + \xF0\xAD\xA8\x9C + \xF0\xAD\xA8\x9D + \xF0\xAD\xA8\x9E + \xF0\xAD\xA8\x9F + \xF0\xAD\xA8\xA0 + \xF0\xAD\xA8\xA1 + \xF0\xAD\xA8\xA2 + \xF0\xAD\xA8\xA3 + \xF0\xAD\xA8\xA4 + \xF0\xAD\xA8\xA5 + \xF0\xAD\xA8\xA6 + \xF0\xAD\xA8\xA7 + \xF0\xAD\xA8\xA8 + \xF0\xAD\xA8\xA9 + \xF0\xAD\xA8\xAA + \xF0\xAD\xA8\xAB + \xF0\xAD\xA8\xAC + \xF0\xAD\xA8\xAD + \xF0\xAD\xA8\xAE + \xF0\xAD\xA8\xAF + \xF0\xAD\xA8\xB0 + \xF0\xAD\xA8\xB1 + \xF0\xAD\xA8\xB2 + \xF0\xAD\xA8\xB3 + \xF0\xAD\xA8\xB4 + \xF0\xAD\xA8\xB5 + \xF0\xAD\xA8\xB6 + \xF0\xAD\xA8\xB7 + \xF0\xAD\xA8\xB8 + \xF0\xAD\xA8\xB9 + \xF0\xAD\xA8\xBA + \xF0\xAD\xA8\xBB + \xF0\xAD\xA8\xBC + \xF0\xAD\xA8\xBD + \xF0\xAD\xA8\xBE + \xF0\xAD\xA8\xBF + \xF0\xAD\xA9\x80 + \xF0\xAD\xA9\x81 + \xF0\xAD\xA9\x82 + \xF0\xAD\xA9\x83 + \xF0\xAD\xA9\x84 + \xF0\xAD\xA9\x85 + \xF0\xAD\xA9\x86 + \xF0\xAD\xA9\x87 + \xF0\xAD\xA9\x88 + \xF0\xAD\xA9\x89 + \xF0\xAD\xA9\x8A + \xF0\xAD\xA9\x8B + \xF0\xAD\xA9\x8C + \xF0\xAD\xA9\x8D + \xF0\xAD\xA9\x8E + \xF0\xAD\xA9\x8F + \xF0\xAD\xA9\x90 + \xF0\xAD\xA9\x91 + \xF0\xAD\xA9\x92 + \xF0\xAD\xA9\x93 + \xF0\xAD\xA9\x94 + \xF0\xAD\xA9\x95 + \xF0\xAD\xA9\x96 + \xF0\xAD\xA9\x97 + \xF0\xAD\xA9\x98 + \xF0\xAD\xA9\x99 + \xF0\xAD\xA9\x9A + \xF0\xAD\xA9\x9B + \xF0\xAD\xA9\x9C + \xF0\xAD\xA9\x9D + \xF0\xAD\xA9\x9E + \xF0\xAD\xA9\x9F + \xF0\xAD\xA9\xA0 + \xF0\xAD\xA9\xA1 + \xF0\xAD\xA9\xA2 + \xF0\xAD\xA9\xA3 + \xF0\xAD\xA9\xA4 + \xF0\xAD\xA9\xA5 + \xF0\xAD\xA9\xA6 + \xF0\xAD\xA9\xA7 + \xF0\xAD\xA9\xA8 + \xF0\xAD\xA9\xA9 + \xF0\xAD\xA9\xAA + \xF0\xAD\xA9\xAB + \xF0\xAD\xA9\xAC + \xF0\xAD\xA9\xAD + \xF0\xAD\xA9\xAE + \xF0\xAD\xA9\xAF + \xF0\xAD\xA9\xB0 + \xF0\xAD\xA9\xB1 + \xF0\xAD\xA9\xB2 + \xF0\xAD\xA9\xB3 + \xF0\xAD\xA9\xB4 + \xF0\xAD\xA9\xB5 + \xF0\xAD\xA9\xB6 + \xF0\xAD\xA9\xB7 + \xF0\xAD\xA9\xB8 + \xF0\xAD\xA9\xB9 + \xF0\xAD\xA9\xBA + \xF0\xAD\xA9\xBB + \xF0\xAD\xA9\xBC + \xF0\xAD\xA9\xBD + \xF0\xAD\xA9\xBE + \xF0\xAD\xA9\xBF + \xF0\xAD\xAA\x80 + \xF0\xAD\xAA\x81 + \xF0\xAD\xAA\x82 + \xF0\xAD\xAA\x83 + \xF0\xAD\xAA\x84 + \xF0\xAD\xAA\x85 + \xF0\xAD\xAA\x86 + \xF0\xAD\xAA\x87 + \xF0\xAD\xAA\x88 + \xF0\xAD\xAA\x89 + \xF0\xAD\xAA\x8A + \xF0\xAD\xAA\x8B + \xF0\xAD\xAA\x8C + \xF0\xAD\xAA\x8D + \xF0\xAD\xAA\x8E + \xF0\xAD\xAA\x8F + \xF0\xAD\xAA\x90 + \xF0\xAD\xAA\x91 + \xF0\xAD\xAA\x92 + \xF0\xAD\xAA\x93 + \xF0\xAD\xAA\x94 + \xF0\xAD\xAA\x95 + \xF0\xAD\xAA\x96 + \xF0\xAD\xAA\x97 + \xF0\xAD\xAA\x98 + \xF0\xAD\xAA\x99 + \xF0\xAD\xAA\x9A + \xF0\xAD\xAA\x9B + \xF0\xAD\xAA\x9C + \xF0\xAD\xAA\x9D + \xF0\xAD\xAA\x9E + \xF0\xAD\xAA\x9F + \xF0\xAD\xAA\xA0 + \xF0\xAD\xAA\xA1 + \xF0\xAD\xAA\xA2 + \xF0\xAD\xAA\xA3 + \xF0\xAD\xAA\xA4 + \xF0\xAD\xAA\xA5 + \xF0\xAD\xAA\xA6 + \xF0\xAD\xAA\xA7 + \xF0\xAD\xAA\xA8 + \xF0\xAD\xAA\xA9 + \xF0\xAD\xAA\xAA + \xF0\xAD\xAA\xAB + \xF0\xAD\xAA\xAC + \xF0\xAD\xAA\xAD + \xF0\xAD\xAA\xAE + \xF0\xAD\xAA\xAF + \xF0\xAD\xAA\xB0 + \xF0\xAD\xAA\xB1 + \xF0\xAD\xAA\xB2 + \xF0\xAD\xAA\xB3 + \xF0\xAD\xAA\xB4 + \xF0\xAD\xAA\xB5 + \xF0\xAD\xAA\xB6 + \xF0\xAD\xAA\xB7 + \xF0\xAD\xAA\xB8 + \xF0\xAD\xAA\xB9 + \xF0\xAD\xAA\xBA + \xF0\xAD\xAA\xBB + \xF0\xAD\xAA\xBC + \xF0\xAD\xAA\xBD + \xF0\xAD\xAA\xBE + \xF0\xAD\xAA\xBF + \xF0\xAD\xAB\x80 + \xF0\xAD\xAB\x81 + \xF0\xAD\xAB\x82 + \xF0\xAD\xAB\x83 + \xF0\xAD\xAB\x84 + \xF0\xAD\xAB\x85 + \xF0\xAD\xAB\x86 + \xF0\xAD\xAB\x87 + \xF0\xAD\xAB\x88 + \xF0\xAD\xAB\x89 + \xF0\xAD\xAB\x8A + \xF0\xAD\xAB\x8B + \xF0\xAD\xAB\x8C + \xF0\xAD\xAB\x8D + \xF0\xAD\xAB\x8E + \xF0\xAD\xAB\x8F + \xF0\xAD\xAB\x90 + \xF0\xAD\xAB\x91 + \xF0\xAD\xAB\x92 + \xF0\xAD\xAB\x93 + \xF0\xAD\xAB\x94 + \xF0\xAD\xAB\x95 + \xF0\xAD\xAB\x96 + \xF0\xAD\xAB\x97 + \xF0\xAD\xAB\x98 + \xF0\xAD\xAB\x99 + \xF0\xAD\xAB\x9A + \xF0\xAD\xAB\x9B + \xF0\xAD\xAB\x9C + \xF0\xAD\xAB\x9D + \xF0\xAD\xAB\x9E + \xF0\xAD\xAB\x9F + \xF0\xAD\xAB\xA0 + \xF0\xAD\xAB\xA1 + \xF0\xAD\xAB\xA2 + \xF0\xAD\xAB\xA3 + \xF0\xAD\xAB\xA4 + \xF0\xAD\xAB\xA5 + \xF0\xAD\xAB\xA6 + \xF0\xAD\xAB\xA7 + \xF0\xAD\xAB\xA8 + \xF0\xAD\xAB\xA9 + \xF0\xAD\xAB\xAA + \xF0\xAD\xAB\xAB + \xF0\xAD\xAB\xAC + \xF0\xAD\xAB\xAD + \xF0\xAD\xAB\xAE + \xF0\xAD\xAB\xAF + \xF0\xAD\xAB\xB0 + \xF0\xAD\xAB\xB1 + \xF0\xAD\xAB\xB2 + \xF0\xAD\xAB\xB3 + \xF0\xAD\xAB\xB4 + \xF0\xAD\xAB\xB5 + \xF0\xAD\xAB\xB6 + \xF0\xAD\xAB\xB7 + \xF0\xAD\xAB\xB8 + \xF0\xAD\xAB\xB9 + \xF0\xAD\xAB\xBA + \xF0\xAD\xAB\xBB + \xF0\xAD\xAB\xBC + \xF0\xAD\xAB\xBD + \xF0\xAD\xAB\xBE + \xF0\xAD\xAB\xBF + \xF0\xAD\xAC\x80 + \xF0\xAD\xAC\x81 + \xF0\xAD\xAC\x82 + \xF0\xAD\xAC\x83 + \xF0\xAD\xAC\x84 + \xF0\xAD\xAC\x85 + \xF0\xAD\xAC\x86 + \xF0\xAD\xAC\x87 + \xF0\xAD\xAC\x88 + \xF0\xAD\xAC\x89 + \xF0\xAD\xAC\x8A + \xF0\xAD\xAC\x8B + \xF0\xAD\xAC\x8C + \xF0\xAD\xAC\x8D + \xF0\xAD\xAC\x8E + \xF0\xAD\xAC\x8F + \xF0\xAD\xAC\x90 + \xF0\xAD\xAC\x91 + \xF0\xAD\xAC\x92 + \xF0\xAD\xAC\x93 + \xF0\xAD\xAC\x94 + \xF0\xAD\xAC\x95 + \xF0\xAD\xAC\x96 + \xF0\xAD\xAC\x97 + \xF0\xAD\xAC\x98 + \xF0\xAD\xAC\x99 + \xF0\xAD\xAC\x9A + \xF0\xAD\xAC\x9B + \xF0\xAD\xAC\x9C + \xF0\xAD\xAC\x9D + \xF0\xAD\xAC\x9E + \xF0\xAD\xAC\x9F + \xF0\xAD\xAC\xA0 + \xF0\xAD\xAC\xA1 + \xF0\xAD\xAC\xA2 + \xF0\xAD\xAC\xA3 + \xF0\xAD\xAC\xA4 + \xF0\xAD\xAC\xA5 + \xF0\xAD\xAC\xA6 + \xF0\xAD\xAC\xA7 + \xF0\xAD\xAC\xA8 + \xF0\xAD\xAC\xA9 + \xF0\xAD\xAC\xAA + \xF0\xAD\xAC\xAB + \xF0\xAD\xAC\xAC + \xF0\xAD\xAC\xAD + \xF0\xAD\xAC\xAE + \xF0\xAD\xAC\xAF + \xF0\xAD\xAC\xB0 + \xF0\xAD\xAC\xB1 + \xF0\xAD\xAC\xB2 + \xF0\xAD\xAC\xB3 + \xF0\xAD\xAC\xB4 + \xF0\xAD\xAC\xB5 + \xF0\xAD\xAC\xB6 + \xF0\xAD\xAC\xB7 + \xF0\xAD\xAC\xB8 + \xF0\xAD\xAC\xB9 + \xF0\xAD\xAC\xBA + \xF0\xAD\xAC\xBB + \xF0\xAD\xAC\xBC + \xF0\xAD\xAC\xBD + \xF0\xAD\xAC\xBE + \xF0\xAD\xAC\xBF + \xF0\xAD\xAD\x80 + \xF0\xAD\xAD\x81 + \xF0\xAD\xAD\x82 + \xF0\xAD\xAD\x83 + \xF0\xAD\xAD\x84 + \xF0\xAD\xAD\x85 + \xF0\xAD\xAD\x86 + \xF0\xAD\xAD\x87 + \xF0\xAD\xAD\x88 + \xF0\xAD\xAD\x89 + \xF0\xAD\xAD\x8A + \xF0\xAD\xAD\x8B + \xF0\xAD\xAD\x8C + \xF0\xAD\xAD\x8D + \xF0\xAD\xAD\x8E + \xF0\xAD\xAD\x8F + \xF0\xAD\xAD\x90 + \xF0\xAD\xAD\x91 + \xF0\xAD\xAD\x92 + \xF0\xAD\xAD\x93 + \xF0\xAD\xAD\x94 + \xF0\xAD\xAD\x95 + \xF0\xAD\xAD\x96 + \xF0\xAD\xAD\x97 + \xF0\xAD\xAD\x98 + \xF0\xAD\xAD\x99 + \xF0\xAD\xAD\x9A + \xF0\xAD\xAD\x9B + \xF0\xAD\xAD\x9C + \xF0\xAD\xAD\x9D + \xF0\xAD\xAD\x9E + \xF0\xAD\xAD\x9F + \xF0\xAD\xAD\xA0 + \xF0\xAD\xAD\xA1 + \xF0\xAD\xAD\xA2 + \xF0\xAD\xAD\xA3 + \xF0\xAD\xAD\xA4 + \xF0\xAD\xAD\xA5 + \xF0\xAD\xAD\xA6 + \xF0\xAD\xAD\xA7 + \xF0\xAD\xAD\xA8 + \xF0\xAD\xAD\xA9 + \xF0\xAD\xAD\xAA + \xF0\xAD\xAD\xAB + \xF0\xAD\xAD\xAC + \xF0\xAD\xAD\xAD + \xF0\xAD\xAD\xAE + \xF0\xAD\xAD\xAF + \xF0\xAD\xAD\xB0 + \xF0\xAD\xAD\xB1 + \xF0\xAD\xAD\xB2 + \xF0\xAD\xAD\xB3 + \xF0\xAD\xAD\xB4 + \xF0\xAD\xAD\xB5 + \xF0\xAD\xAD\xB6 + \xF0\xAD\xAD\xB7 + \xF0\xAD\xAD\xB8 + \xF0\xAD\xAD\xB9 + \xF0\xAD\xAD\xBA + \xF0\xAD\xAD\xBB + \xF0\xAD\xAD\xBC + \xF0\xAD\xAD\xBD + \xF0\xAD\xAD\xBE + \xF0\xAD\xAD\xBF + \xF0\xAD\xAE\x80 + \xF0\xAD\xAE\x81 + \xF0\xAD\xAE\x82 + \xF0\xAD\xAE\x83 + \xF0\xAD\xAE\x84 + \xF0\xAD\xAE\x85 + \xF0\xAD\xAE\x86 + \xF0\xAD\xAE\x87 + \xF0\xAD\xAE\x88 + \xF0\xAD\xAE\x89 + \xF0\xAD\xAE\x8A + \xF0\xAD\xAE\x8B + \xF0\xAD\xAE\x8C + \xF0\xAD\xAE\x8D + \xF0\xAD\xAE\x8E + \xF0\xAD\xAE\x8F + \xF0\xAD\xAE\x90 + \xF0\xAD\xAE\x91 + \xF0\xAD\xAE\x92 + \xF0\xAD\xAE\x93 + \xF0\xAD\xAE\x94 + \xF0\xAD\xAE\x95 + \xF0\xAD\xAE\x96 + \xF0\xAD\xAE\x97 + \xF0\xAD\xAE\x98 + \xF0\xAD\xAE\x99 + \xF0\xAD\xAE\x9A + \xF0\xAD\xAE\x9B + \xF0\xAD\xAE\x9C + \xF0\xAD\xAE\x9D + \xF0\xAD\xAE\x9E + \xF0\xAD\xAE\x9F + \xF0\xAD\xAE\xA0 + \xF0\xAD\xAE\xA1 + \xF0\xAD\xAE\xA2 + \xF0\xAD\xAE\xA3 + \xF0\xAD\xAE\xA4 + \xF0\xAD\xAE\xA5 + \xF0\xAD\xAE\xA6 + \xF0\xAD\xAE\xA7 + \xF0\xAD\xAE\xA8 + \xF0\xAD\xAE\xA9 + \xF0\xAD\xAE\xAA + \xF0\xAD\xAE\xAB + \xF0\xAD\xAE\xAC + \xF0\xAD\xAE\xAD + \xF0\xAD\xAE\xAE + \xF0\xAD\xAE\xAF + \xF0\xAD\xAE\xB0 + \xF0\xAD\xAE\xB1 + \xF0\xAD\xAE\xB2 + \xF0\xAD\xAE\xB3 + \xF0\xAD\xAE\xB4 + \xF0\xAD\xAE\xB5 + \xF0\xAD\xAE\xB6 + \xF0\xAD\xAE\xB7 + \xF0\xAD\xAE\xB8 + \xF0\xAD\xAE\xB9 + \xF0\xAD\xAE\xBA + \xF0\xAD\xAE\xBB + \xF0\xAD\xAE\xBC + \xF0\xAD\xAE\xBD + \xF0\xAD\xAE\xBE + \xF0\xAD\xAE\xBF + \xF0\xAD\xAF\x80 + \xF0\xAD\xAF\x81 + \xF0\xAD\xAF\x82 + \xF0\xAD\xAF\x83 + \xF0\xAD\xAF\x84 + \xF0\xAD\xAF\x85 + \xF0\xAD\xAF\x86 + \xF0\xAD\xAF\x87 + \xF0\xAD\xAF\x88 + \xF0\xAD\xAF\x89 + \xF0\xAD\xAF\x8A + \xF0\xAD\xAF\x8B + \xF0\xAD\xAF\x8C + \xF0\xAD\xAF\x8D + \xF0\xAD\xAF\x8E + \xF0\xAD\xAF\x8F + \xF0\xAD\xAF\x90 + \xF0\xAD\xAF\x91 + \xF0\xAD\xAF\x92 + \xF0\xAD\xAF\x93 + \xF0\xAD\xAF\x94 + \xF0\xAD\xAF\x95 + \xF0\xAD\xAF\x96 + \xF0\xAD\xAF\x97 + \xF0\xAD\xAF\x98 + \xF0\xAD\xAF\x99 + \xF0\xAD\xAF\x9A + \xF0\xAD\xAF\x9B + \xF0\xAD\xAF\x9C + \xF0\xAD\xAF\x9D + \xF0\xAD\xAF\x9E + \xF0\xAD\xAF\x9F + \xF0\xAD\xAF\xA0 + \xF0\xAD\xAF\xA1 + \xF0\xAD\xAF\xA2 + \xF0\xAD\xAF\xA3 + \xF0\xAD\xAF\xA4 + \xF0\xAD\xAF\xA5 + \xF0\xAD\xAF\xA6 + \xF0\xAD\xAF\xA7 + \xF0\xAD\xAF\xA8 + \xF0\xAD\xAF\xA9 + \xF0\xAD\xAF\xAA + \xF0\xAD\xAF\xAB + \xF0\xAD\xAF\xAC + \xF0\xAD\xAF\xAD + \xF0\xAD\xAF\xAE + \xF0\xAD\xAF\xAF + \xF0\xAD\xAF\xB0 + \xF0\xAD\xAF\xB1 + \xF0\xAD\xAF\xB2 + \xF0\xAD\xAF\xB3 + \xF0\xAD\xAF\xB4 + \xF0\xAD\xAF\xB5 + \xF0\xAD\xAF\xB6 + \xF0\xAD\xAF\xB7 + \xF0\xAD\xAF\xB8 + \xF0\xAD\xAF\xB9 + \xF0\xAD\xAF\xBA + \xF0\xAD\xAF\xBB + \xF0\xAD\xAF\xBC + \xF0\xAD\xAF\xBD + \xF0\xAD\xAF\xBE + \xF0\xAD\xAF\xBF + \xF0\xAD\xB0\x80 + \xF0\xAD\xB0\x81 + \xF0\xAD\xB0\x82 + \xF0\xAD\xB0\x83 + \xF0\xAD\xB0\x84 + \xF0\xAD\xB0\x85 + \xF0\xAD\xB0\x86 + \xF0\xAD\xB0\x87 + \xF0\xAD\xB0\x88 + \xF0\xAD\xB0\x89 + \xF0\xAD\xB0\x8A + \xF0\xAD\xB0\x8B + \xF0\xAD\xB0\x8C + \xF0\xAD\xB0\x8D + \xF0\xAD\xB0\x8E + \xF0\xAD\xB0\x8F + \xF0\xAD\xB0\x90 + \xF0\xAD\xB0\x91 + \xF0\xAD\xB0\x92 + \xF0\xAD\xB0\x93 + \xF0\xAD\xB0\x94 + \xF0\xAD\xB0\x95 + \xF0\xAD\xB0\x96 + \xF0\xAD\xB0\x97 + \xF0\xAD\xB0\x98 + \xF0\xAD\xB0\x99 + \xF0\xAD\xB0\x9A + \xF0\xAD\xB0\x9B + \xF0\xAD\xB0\x9C + \xF0\xAD\xB0\x9D + \xF0\xAD\xB0\x9E + \xF0\xAD\xB0\x9F + \xF0\xAD\xB0\xA0 + \xF0\xAD\xB0\xA1 + \xF0\xAD\xB0\xA2 + \xF0\xAD\xB0\xA3 + \xF0\xAD\xB0\xA4 + \xF0\xAD\xB0\xA5 + \xF0\xAD\xB0\xA6 + \xF0\xAD\xB0\xA7 + \xF0\xAD\xB0\xA8 + \xF0\xAD\xB0\xA9 + \xF0\xAD\xB0\xAA + \xF0\xAD\xB0\xAB + \xF0\xAD\xB0\xAC + \xF0\xAD\xB0\xAD + \xF0\xAD\xB0\xAE + \xF0\xAD\xB0\xAF + \xF0\xAD\xB0\xB0 + \xF0\xAD\xB0\xB1 + \xF0\xAD\xB0\xB2 + \xF0\xAD\xB0\xB3 + \xF0\xAD\xB0\xB4 + \xF0\xAD\xB0\xB5 + \xF0\xAD\xB0\xB6 + \xF0\xAD\xB0\xB7 + \xF0\xAD\xB0\xB8 + \xF0\xAD\xB0\xB9 + \xF0\xAD\xB0\xBA + \xF0\xAD\xB0\xBB + \xF0\xAD\xB0\xBC + \xF0\xAD\xB0\xBD + \xF0\xAD\xB0\xBE + \xF0\xAD\xB0\xBF + \xF0\xAD\xB1\x80 + \xF0\xAD\xB1\x81 + \xF0\xAD\xB1\x82 + \xF0\xAD\xB1\x83 + \xF0\xAD\xB1\x84 + \xF0\xAD\xB1\x85 + \xF0\xAD\xB1\x86 + \xF0\xAD\xB1\x87 + \xF0\xAD\xB1\x88 + \xF0\xAD\xB1\x89 + \xF0\xAD\xB1\x8A + \xF0\xAD\xB1\x8B + \xF0\xAD\xB1\x8C + \xF0\xAD\xB1\x8D + \xF0\xAD\xB1\x8E + \xF0\xAD\xB1\x8F + \xF0\xAD\xB1\x90 + \xF0\xAD\xB1\x91 + \xF0\xAD\xB1\x92 + \xF0\xAD\xB1\x93 + \xF0\xAD\xB1\x94 + \xF0\xAD\xB1\x95 + \xF0\xAD\xB1\x96 + \xF0\xAD\xB1\x97 + \xF0\xAD\xB1\x98 + \xF0\xAD\xB1\x99 + \xF0\xAD\xB1\x9A + \xF0\xAD\xB1\x9B + \xF0\xAD\xB1\x9C + \xF0\xAD\xB1\x9D + \xF0\xAD\xB1\x9E + \xF0\xAD\xB1\x9F + \xF0\xAD\xB1\xA0 + \xF0\xAD\xB1\xA1 + \xF0\xAD\xB1\xA2 + \xF0\xAD\xB1\xA3 + \xF0\xAD\xB1\xA4 + \xF0\xAD\xB1\xA5 + \xF0\xAD\xB1\xA6 + \xF0\xAD\xB1\xA7 + \xF0\xAD\xB1\xA8 + \xF0\xAD\xB1\xA9 + \xF0\xAD\xB1\xAA + \xF0\xAD\xB1\xAB + \xF0\xAD\xB1\xAC + \xF0\xAD\xB1\xAD + \xF0\xAD\xB1\xAE + \xF0\xAD\xB1\xAF + \xF0\xAD\xB1\xB0 + \xF0\xAD\xB1\xB1 + \xF0\xAD\xB1\xB2 + \xF0\xAD\xB1\xB3 + \xF0\xAD\xB1\xB4 + \xF0\xAD\xB1\xB5 + \xF0\xAD\xB1\xB6 + \xF0\xAD\xB1\xB7 + \xF0\xAD\xB1\xB8 + \xF0\xAD\xB1\xB9 + \xF0\xAD\xB1\xBA + \xF0\xAD\xB1\xBB + \xF0\xAD\xB1\xBC + \xF0\xAD\xB1\xBD + \xF0\xAD\xB1\xBE + \xF0\xAD\xB1\xBF + \xF0\xAD\xB2\x80 + \xF0\xAD\xB2\x81 + \xF0\xAD\xB2\x82 + \xF0\xAD\xB2\x83 + \xF0\xAD\xB2\x84 + \xF0\xAD\xB2\x85 + \xF0\xAD\xB2\x86 + \xF0\xAD\xB2\x87 + \xF0\xAD\xB2\x88 + \xF0\xAD\xB2\x89 + \xF0\xAD\xB2\x8A + \xF0\xAD\xB2\x8B + \xF0\xAD\xB2\x8C + \xF0\xAD\xB2\x8D + \xF0\xAD\xB2\x8E + \xF0\xAD\xB2\x8F + \xF0\xAD\xB2\x90 + \xF0\xAD\xB2\x91 + \xF0\xAD\xB2\x92 + \xF0\xAD\xB2\x93 + \xF0\xAD\xB2\x94 + \xF0\xAD\xB2\x95 + \xF0\xAD\xB2\x96 + \xF0\xAD\xB2\x97 + \xF0\xAD\xB2\x98 + \xF0\xAD\xB2\x99 + \xF0\xAD\xB2\x9A + \xF0\xAD\xB2\x9B + \xF0\xAD\xB2\x9C + \xF0\xAD\xB2\x9D + \xF0\xAD\xB2\x9E + \xF0\xAD\xB2\x9F + \xF0\xAD\xB2\xA0 + \xF0\xAD\xB2\xA1 + \xF0\xAD\xB2\xA2 + \xF0\xAD\xB2\xA3 + \xF0\xAD\xB2\xA4 + \xF0\xAD\xB2\xA5 + \xF0\xAD\xB2\xA6 + \xF0\xAD\xB2\xA7 + \xF0\xAD\xB2\xA8 + \xF0\xAD\xB2\xA9 + \xF0\xAD\xB2\xAA + \xF0\xAD\xB2\xAB + \xF0\xAD\xB2\xAC + \xF0\xAD\xB2\xAD + \xF0\xAD\xB2\xAE + \xF0\xAD\xB2\xAF + \xF0\xAD\xB2\xB0 + \xF0\xAD\xB2\xB1 + \xF0\xAD\xB2\xB2 + \xF0\xAD\xB2\xB3 + \xF0\xAD\xB2\xB4 + \xF0\xAD\xB2\xB5 + \xF0\xAD\xB2\xB6 + \xF0\xAD\xB2\xB7 + \xF0\xAD\xB2\xB8 + \xF0\xAD\xB2\xB9 + \xF0\xAD\xB2\xBA + \xF0\xAD\xB2\xBB + \xF0\xAD\xB2\xBC + \xF0\xAD\xB2\xBD + \xF0\xAD\xB2\xBE + \xF0\xAD\xB2\xBF + \xF0\xAD\xB3\x80 + \xF0\xAD\xB3\x81 + \xF0\xAD\xB3\x82 + \xF0\xAD\xB3\x83 + \xF0\xAD\xB3\x84 + \xF0\xAD\xB3\x85 + \xF0\xAD\xB3\x86 + \xF0\xAD\xB3\x87 + \xF0\xAD\xB3\x88 + \xF0\xAD\xB3\x89 + \xF0\xAD\xB3\x8A + \xF0\xAD\xB3\x8B + \xF0\xAD\xB3\x8C + \xF0\xAD\xB3\x8D + \xF0\xAD\xB3\x8E + \xF0\xAD\xB3\x8F + \xF0\xAD\xB3\x90 + \xF0\xAD\xB3\x91 + \xF0\xAD\xB3\x92 + \xF0\xAD\xB3\x93 + \xF0\xAD\xB3\x94 + \xF0\xAD\xB3\x95 + \xF0\xAD\xB3\x96 + \xF0\xAD\xB3\x97 + \xF0\xAD\xB3\x98 + \xF0\xAD\xB3\x99 + \xF0\xAD\xB3\x9A + \xF0\xAD\xB3\x9B + \xF0\xAD\xB3\x9C + \xF0\xAD\xB3\x9D + \xF0\xAD\xB3\x9E + \xF0\xAD\xB3\x9F + \xF0\xAD\xB3\xA0 + \xF0\xAD\xB3\xA1 + \xF0\xAD\xB3\xA2 + \xF0\xAD\xB3\xA3 + \xF0\xAD\xB3\xA4 + \xF0\xAD\xB3\xA5 + \xF0\xAD\xB3\xA6 + \xF0\xAD\xB3\xA7 + \xF0\xAD\xB3\xA8 + \xF0\xAD\xB3\xA9 + \xF0\xAD\xB3\xAA + \xF0\xAD\xB3\xAB + \xF0\xAD\xB3\xAC + \xF0\xAD\xB3\xAD + \xF0\xAD\xB3\xAE + \xF0\xAD\xB3\xAF + \xF0\xAD\xB3\xB0 + \xF0\xAD\xB3\xB1 + \xF0\xAD\xB3\xB2 + \xF0\xAD\xB3\xB3 + \xF0\xAD\xB3\xB4 + \xF0\xAD\xB3\xB5 + \xF0\xAD\xB3\xB6 + \xF0\xAD\xB3\xB7 + \xF0\xAD\xB3\xB8 + \xF0\xAD\xB3\xB9 + \xF0\xAD\xB3\xBA + \xF0\xAD\xB3\xBB + \xF0\xAD\xB3\xBC + \xF0\xAD\xB3\xBD + \xF0\xAD\xB3\xBE + \xF0\xAD\xB3\xBF + \xF0\xAD\xB4\x80 + \xF0\xAD\xB4\x81 + \xF0\xAD\xB4\x82 + \xF0\xAD\xB4\x83 + \xF0\xAD\xB4\x84 + \xF0\xAD\xB4\x85 + \xF0\xAD\xB4\x86 + \xF0\xAD\xB4\x87 + \xF0\xAD\xB4\x88 + \xF0\xAD\xB4\x89 + \xF0\xAD\xB4\x8A + \xF0\xAD\xB4\x8B + \xF0\xAD\xB4\x8C + \xF0\xAD\xB4\x8D + \xF0\xAD\xB4\x8E + \xF0\xAD\xB4\x8F + \xF0\xAD\xB4\x90 + \xF0\xAD\xB4\x91 + \xF0\xAD\xB4\x92 + \xF0\xAD\xB4\x93 + \xF0\xAD\xB4\x94 + \xF0\xAD\xB4\x95 + \xF0\xAD\xB4\x96 + \xF0\xAD\xB4\x97 + \xF0\xAD\xB4\x98 + \xF0\xAD\xB4\x99 + \xF0\xAD\xB4\x9A + \xF0\xAD\xB4\x9B + \xF0\xAD\xB4\x9C + \xF0\xAD\xB4\x9D + \xF0\xAD\xB4\x9E + \xF0\xAD\xB4\x9F + \xF0\xAD\xB4\xA0 + \xF0\xAD\xB4\xA1 + \xF0\xAD\xB4\xA2 + \xF0\xAD\xB4\xA3 + \xF0\xAD\xB4\xA4 + \xF0\xAD\xB4\xA5 + \xF0\xAD\xB4\xA6 + \xF0\xAD\xB4\xA7 + \xF0\xAD\xB4\xA8 + \xF0\xAD\xB4\xA9 + \xF0\xAD\xB4\xAA + \xF0\xAD\xB4\xAB + \xF0\xAD\xB4\xAC + \xF0\xAD\xB4\xAD + \xF0\xAD\xB4\xAE + \xF0\xAD\xB4\xAF + \xF0\xAD\xB4\xB0 + \xF0\xAD\xB4\xB1 + \xF0\xAD\xB4\xB2 + \xF0\xAD\xB4\xB3 + \xF0\xAD\xB4\xB4 + \xF0\xAD\xB4\xB5 + \xF0\xAD\xB4\xB6 + \xF0\xAD\xB4\xB7 + \xF0\xAD\xB4\xB8 + \xF0\xAD\xB4\xB9 + \xF0\xAD\xB4\xBA + \xF0\xAD\xB4\xBB + \xF0\xAD\xB4\xBC + \xF0\xAD\xB4\xBD + \xF0\xAD\xB4\xBE + \xF0\xAD\xB4\xBF + \xF0\xAD\xB5\x80 + \xF0\xAD\xB5\x81 + \xF0\xAD\xB5\x82 + \xF0\xAD\xB5\x83 + \xF0\xAD\xB5\x84 + \xF0\xAD\xB5\x85 + \xF0\xAD\xB5\x86 + \xF0\xAD\xB5\x87 + \xF0\xAD\xB5\x88 + \xF0\xAD\xB5\x89 + \xF0\xAD\xB5\x8A + \xF0\xAD\xB5\x8B + \xF0\xAD\xB5\x8C + \xF0\xAD\xB5\x8D + \xF0\xAD\xB5\x8E + \xF0\xAD\xB5\x8F + \xF0\xAD\xB5\x90 + \xF0\xAD\xB5\x91 + \xF0\xAD\xB5\x92 + \xF0\xAD\xB5\x93 + \xF0\xAD\xB5\x94 + \xF0\xAD\xB5\x95 + \xF0\xAD\xB5\x96 + \xF0\xAD\xB5\x97 + \xF0\xAD\xB5\x98 + \xF0\xAD\xB5\x99 + \xF0\xAD\xB5\x9A + \xF0\xAD\xB5\x9B + \xF0\xAD\xB5\x9C + \xF0\xAD\xB5\x9D + \xF0\xAD\xB5\x9E + \xF0\xAD\xB5\x9F + \xF0\xAD\xB5\xA0 + \xF0\xAD\xB5\xA1 + \xF0\xAD\xB5\xA2 + \xF0\xAD\xB5\xA3 + \xF0\xAD\xB5\xA4 + \xF0\xAD\xB5\xA5 + \xF0\xAD\xB5\xA6 + \xF0\xAD\xB5\xA7 + \xF0\xAD\xB5\xA8 + \xF0\xAD\xB5\xA9 + \xF0\xAD\xB5\xAA + \xF0\xAD\xB5\xAB + \xF0\xAD\xB5\xAC + \xF0\xAD\xB5\xAD + \xF0\xAD\xB5\xAE + \xF0\xAD\xB5\xAF + \xF0\xAD\xB5\xB0 + \xF0\xAD\xB5\xB1 + \xF0\xAD\xB5\xB2 + \xF0\xAD\xB5\xB3 + \xF0\xAD\xB5\xB4 + \xF0\xAD\xB5\xB5 + \xF0\xAD\xB5\xB6 + \xF0\xAD\xB5\xB7 + \xF0\xAD\xB5\xB8 + \xF0\xAD\xB5\xB9 + \xF0\xAD\xB5\xBA + \xF0\xAD\xB5\xBB + \xF0\xAD\xB5\xBC + \xF0\xAD\xB5\xBD + \xF0\xAD\xB5\xBE + \xF0\xAD\xB5\xBF + \xF0\xAD\xB6\x80 + \xF0\xAD\xB6\x81 + \xF0\xAD\xB6\x82 + \xF0\xAD\xB6\x83 + \xF0\xAD\xB6\x84 + \xF0\xAD\xB6\x85 + \xF0\xAD\xB6\x86 + \xF0\xAD\xB6\x87 + \xF0\xAD\xB6\x88 + \xF0\xAD\xB6\x89 + \xF0\xAD\xB6\x8A + \xF0\xAD\xB6\x8B + \xF0\xAD\xB6\x8C + \xF0\xAD\xB6\x8D + \xF0\xAD\xB6\x8E + \xF0\xAD\xB6\x8F + \xF0\xAD\xB6\x90 + \xF0\xAD\xB6\x91 + \xF0\xAD\xB6\x92 + \xF0\xAD\xB6\x93 + \xF0\xAD\xB6\x94 + \xF0\xAD\xB6\x95 + \xF0\xAD\xB6\x96 + \xF0\xAD\xB6\x97 + \xF0\xAD\xB6\x98 + \xF0\xAD\xB6\x99 + \xF0\xAD\xB6\x9A + \xF0\xAD\xB6\x9B + \xF0\xAD\xB6\x9C + \xF0\xAD\xB6\x9D + \xF0\xAD\xB6\x9E + \xF0\xAD\xB6\x9F + \xF0\xAD\xB6\xA0 + \xF0\xAD\xB6\xA1 + \xF0\xAD\xB6\xA2 + \xF0\xAD\xB6\xA3 + \xF0\xAD\xB6\xA4 + \xF0\xAD\xB6\xA5 + \xF0\xAD\xB6\xA6 + \xF0\xAD\xB6\xA7 + \xF0\xAD\xB6\xA8 + \xF0\xAD\xB6\xA9 + \xF0\xAD\xB6\xAA + \xF0\xAD\xB6\xAB + \xF0\xAD\xB6\xAC + \xF0\xAD\xB6\xAD + \xF0\xAD\xB6\xAE + \xF0\xAD\xB6\xAF + \xF0\xAD\xB6\xB0 + \xF0\xAD\xB6\xB1 + \xF0\xAD\xB6\xB2 + \xF0\xAD\xB6\xB3 + \xF0\xAD\xB6\xB4 + \xF0\xAD\xB6\xB5 + \xF0\xAD\xB6\xB6 + \xF0\xAD\xB6\xB7 + \xF0\xAD\xB6\xB8 + \xF0\xAD\xB6\xB9 + \xF0\xAD\xB6\xBA + \xF0\xAD\xB6\xBB + \xF0\xAD\xB6\xBC + \xF0\xAD\xB6\xBD + \xF0\xAD\xB6\xBE + \xF0\xAD\xB6\xBF + \xF0\xAD\xB7\x80 + \xF0\xAD\xB7\x81 + \xF0\xAD\xB7\x82 + \xF0\xAD\xB7\x83 + \xF0\xAD\xB7\x84 + \xF0\xAD\xB7\x85 + \xF0\xAD\xB7\x86 + \xF0\xAD\xB7\x87 + \xF0\xAD\xB7\x88 + \xF0\xAD\xB7\x89 + \xF0\xAD\xB7\x8A + \xF0\xAD\xB7\x8B + \xF0\xAD\xB7\x8C + \xF0\xAD\xB7\x8D + \xF0\xAD\xB7\x8E + \xF0\xAD\xB7\x8F + \xF0\xAD\xB7\x90 + \xF0\xAD\xB7\x91 + \xF0\xAD\xB7\x92 + \xF0\xAD\xB7\x93 + \xF0\xAD\xB7\x94 + \xF0\xAD\xB7\x95 + \xF0\xAD\xB7\x96 + \xF0\xAD\xB7\x97 + \xF0\xAD\xB7\x98 + \xF0\xAD\xB7\x99 + \xF0\xAD\xB7\x9A + \xF0\xAD\xB7\x9B + \xF0\xAD\xB7\x9C + \xF0\xAD\xB7\x9D + \xF0\xAD\xB7\x9E + \xF0\xAD\xB7\x9F + \xF0\xAD\xB7\xA0 + \xF0\xAD\xB7\xA1 + \xF0\xAD\xB7\xA2 + \xF0\xAD\xB7\xA3 + \xF0\xAD\xB7\xA4 + \xF0\xAD\xB7\xA5 + \xF0\xAD\xB7\xA6 + \xF0\xAD\xB7\xA7 + \xF0\xAD\xB7\xA8 + \xF0\xAD\xB7\xA9 + \xF0\xAD\xB7\xAA + \xF0\xAD\xB7\xAB + \xF0\xAD\xB7\xAC + \xF0\xAD\xB7\xAD + \xF0\xAD\xB7\xAE + \xF0\xAD\xB7\xAF + \xF0\xAD\xB7\xB0 + \xF0\xAD\xB7\xB1 + \xF0\xAD\xB7\xB2 + \xF0\xAD\xB7\xB3 + \xF0\xAD\xB7\xB4 + \xF0\xAD\xB7\xB5 + \xF0\xAD\xB7\xB6 + \xF0\xAD\xB7\xB7 + \xF0\xAD\xB7\xB8 + \xF0\xAD\xB7\xB9 + \xF0\xAD\xB7\xBA + \xF0\xAD\xB7\xBB + \xF0\xAD\xB7\xBC + \xF0\xAD\xB7\xBD + \xF0\xAD\xB7\xBE + \xF0\xAD\xB7\xBF + \xF0\xAD\xB8\x80 + \xF0\xAD\xB8\x81 + \xF0\xAD\xB8\x82 + \xF0\xAD\xB8\x83 + \xF0\xAD\xB8\x84 + \xF0\xAD\xB8\x85 + \xF0\xAD\xB8\x86 + \xF0\xAD\xB8\x87 + \xF0\xAD\xB8\x88 + \xF0\xAD\xB8\x89 + \xF0\xAD\xB8\x8A + \xF0\xAD\xB8\x8B + \xF0\xAD\xB8\x8C + \xF0\xAD\xB8\x8D + \xF0\xAD\xB8\x8E + \xF0\xAD\xB8\x8F + \xF0\xAD\xB8\x90 + \xF0\xAD\xB8\x91 + \xF0\xAD\xB8\x92 + \xF0\xAD\xB8\x93 + \xF0\xAD\xB8\x94 + \xF0\xAD\xB8\x95 + \xF0\xAD\xB8\x96 + \xF0\xAD\xB8\x97 + \xF0\xAD\xB8\x98 + \xF0\xAD\xB8\x99 + \xF0\xAD\xB8\x9A + \xF0\xAD\xB8\x9B + \xF0\xAD\xB8\x9C + \xF0\xAD\xB8\x9D + \xF0\xAD\xB8\x9E + \xF0\xAD\xB8\x9F + \xF0\xAD\xB8\xA0 + \xF0\xAD\xB8\xA1 + \xF0\xAD\xB8\xA2 + \xF0\xAD\xB8\xA3 + \xF0\xAD\xB8\xA4 + \xF0\xAD\xB8\xA5 + \xF0\xAD\xB8\xA6 + \xF0\xAD\xB8\xA7 + \xF0\xAD\xB8\xA8 + \xF0\xAD\xB8\xA9 + \xF0\xAD\xB8\xAA + \xF0\xAD\xB8\xAB + \xF0\xAD\xB8\xAC + \xF0\xAD\xB8\xAD + \xF0\xAD\xB8\xAE + \xF0\xAD\xB8\xAF + \xF0\xAD\xB8\xB0 + \xF0\xAD\xB8\xB1 + \xF0\xAD\xB8\xB2 + \xF0\xAD\xB8\xB3 + \xF0\xAD\xB8\xB4 + \xF0\xAD\xB8\xB5 + \xF0\xAD\xB8\xB6 + \xF0\xAD\xB8\xB7 + \xF0\xAD\xB8\xB8 + \xF0\xAD\xB8\xB9 + \xF0\xAD\xB8\xBA + \xF0\xAD\xB8\xBB + \xF0\xAD\xB8\xBC + \xF0\xAD\xB8\xBD + \xF0\xAD\xB8\xBE + \xF0\xAD\xB8\xBF + \xF0\xAD\xB9\x80 + \xF0\xAD\xB9\x81 + \xF0\xAD\xB9\x82 + \xF0\xAD\xB9\x83 + \xF0\xAD\xB9\x84 + \xF0\xAD\xB9\x85 + \xF0\xAD\xB9\x86 + \xF0\xAD\xB9\x87 + \xF0\xAD\xB9\x88 + \xF0\xAD\xB9\x89 + \xF0\xAD\xB9\x8A + \xF0\xAD\xB9\x8B + \xF0\xAD\xB9\x8C + \xF0\xAD\xB9\x8D + \xF0\xAD\xB9\x8E + \xF0\xAD\xB9\x8F + \xF0\xAD\xB9\x90 + \xF0\xAD\xB9\x91 + \xF0\xAD\xB9\x92 + \xF0\xAD\xB9\x93 + \xF0\xAD\xB9\x94 + \xF0\xAD\xB9\x95 + \xF0\xAD\xB9\x96 + \xF0\xAD\xB9\x97 + \xF0\xAD\xB9\x98 + \xF0\xAD\xB9\x99 + \xF0\xAD\xB9\x9A + \xF0\xAD\xB9\x9B + \xF0\xAD\xB9\x9C + \xF0\xAD\xB9\x9D + \xF0\xAD\xB9\x9E + \xF0\xAD\xB9\x9F + \xF0\xAD\xB9\xA0 + \xF0\xAD\xB9\xA1 + \xF0\xAD\xB9\xA2 + \xF0\xAD\xB9\xA3 + \xF0\xAD\xB9\xA4 + \xF0\xAD\xB9\xA5 + \xF0\xAD\xB9\xA6 + \xF0\xAD\xB9\xA7 + \xF0\xAD\xB9\xA8 + \xF0\xAD\xB9\xA9 + \xF0\xAD\xB9\xAA + \xF0\xAD\xB9\xAB + \xF0\xAD\xB9\xAC + \xF0\xAD\xB9\xAD + \xF0\xAD\xB9\xAE + \xF0\xAD\xB9\xAF + \xF0\xAD\xB9\xB0 + \xF0\xAD\xB9\xB1 + \xF0\xAD\xB9\xB2 + \xF0\xAD\xB9\xB3 + \xF0\xAD\xB9\xB4 + \xF0\xAD\xB9\xB5 + \xF0\xAD\xB9\xB6 + \xF0\xAD\xB9\xB7 + \xF0\xAD\xB9\xB8 + \xF0\xAD\xB9\xB9 + \xF0\xAD\xB9\xBA + \xF0\xAD\xB9\xBB + \xF0\xAD\xB9\xBC + \xF0\xAD\xB9\xBD + \xF0\xAD\xB9\xBE + \xF0\xAD\xB9\xBF + \xF0\xAD\xBA\x80 + \xF0\xAD\xBA\x81 + \xF0\xAD\xBA\x82 + \xF0\xAD\xBA\x83 + \xF0\xAD\xBA\x84 + \xF0\xAD\xBA\x85 + \xF0\xAD\xBA\x86 + \xF0\xAD\xBA\x87 + \xF0\xAD\xBA\x88 + \xF0\xAD\xBA\x89 + \xF0\xAD\xBA\x8A + \xF0\xAD\xBA\x8B + \xF0\xAD\xBA\x8C + \xF0\xAD\xBA\x8D + \xF0\xAD\xBA\x8E + \xF0\xAD\xBA\x8F + \xF0\xAD\xBA\x90 + \xF0\xAD\xBA\x91 + \xF0\xAD\xBA\x92 + \xF0\xAD\xBA\x93 + \xF0\xAD\xBA\x94 + \xF0\xAD\xBA\x95 + \xF0\xAD\xBA\x96 + \xF0\xAD\xBA\x97 + \xF0\xAD\xBA\x98 + \xF0\xAD\xBA\x99 + \xF0\xAD\xBA\x9A + \xF0\xAD\xBA\x9B + \xF0\xAD\xBA\x9C + \xF0\xAD\xBA\x9D + \xF0\xAD\xBA\x9E + \xF0\xAD\xBA\x9F + \xF0\xAD\xBA\xA0 + \xF0\xAD\xBA\xA1 + \xF0\xAD\xBA\xA2 + \xF0\xAD\xBA\xA3 + \xF0\xAD\xBA\xA4 + \xF0\xAD\xBA\xA5 + \xF0\xAD\xBA\xA6 + \xF0\xAD\xBA\xA7 + \xF0\xAD\xBA\xA8 + \xF0\xAD\xBA\xA9 + \xF0\xAD\xBA\xAA + \xF0\xAD\xBA\xAB + \xF0\xAD\xBA\xAC + \xF0\xAD\xBA\xAD + \xF0\xAD\xBA\xAE + \xF0\xAD\xBA\xAF + \xF0\xAD\xBA\xB0 + \xF0\xAD\xBA\xB1 + \xF0\xAD\xBA\xB2 + \xF0\xAD\xBA\xB3 + \xF0\xAD\xBA\xB4 + \xF0\xAD\xBA\xB5 + \xF0\xAD\xBA\xB6 + \xF0\xAD\xBA\xB7 + \xF0\xAD\xBA\xB8 + \xF0\xAD\xBA\xB9 + \xF0\xAD\xBA\xBA + \xF0\xAD\xBA\xBB + \xF0\xAD\xBA\xBC + \xF0\xAD\xBA\xBD + \xF0\xAD\xBA\xBE + \xF0\xAD\xBA\xBF + \xF0\xAD\xBB\x80 + \xF0\xAD\xBB\x81 + \xF0\xAD\xBB\x82 + \xF0\xAD\xBB\x83 + \xF0\xAD\xBB\x84 + \xF0\xAD\xBB\x85 + \xF0\xAD\xBB\x86 + \xF0\xAD\xBB\x87 + \xF0\xAD\xBB\x88 + \xF0\xAD\xBB\x89 + \xF0\xAD\xBB\x8A + \xF0\xAD\xBB\x8B + \xF0\xAD\xBB\x8C + \xF0\xAD\xBB\x8D + \xF0\xAD\xBB\x8E + \xF0\xAD\xBB\x8F + \xF0\xAD\xBB\x90 + \xF0\xAD\xBB\x91 + \xF0\xAD\xBB\x92 + \xF0\xAD\xBB\x93 + \xF0\xAD\xBB\x94 + \xF0\xAD\xBB\x95 + \xF0\xAD\xBB\x96 + \xF0\xAD\xBB\x97 + \xF0\xAD\xBB\x98 + \xF0\xAD\xBB\x99 + \xF0\xAD\xBB\x9A + \xF0\xAD\xBB\x9B + \xF0\xAD\xBB\x9C + \xF0\xAD\xBB\x9D + \xF0\xAD\xBB\x9E + \xF0\xAD\xBB\x9F + \xF0\xAD\xBB\xA0 + \xF0\xAD\xBB\xA1 + \xF0\xAD\xBB\xA2 + \xF0\xAD\xBB\xA3 + \xF0\xAD\xBB\xA4 + \xF0\xAD\xBB\xA5 + \xF0\xAD\xBB\xA6 + \xF0\xAD\xBB\xA7 + \xF0\xAD\xBB\xA8 + \xF0\xAD\xBB\xA9 + \xF0\xAD\xBB\xAA + \xF0\xAD\xBB\xAB + \xF0\xAD\xBB\xAC + \xF0\xAD\xBB\xAD + \xF0\xAD\xBB\xAE + \xF0\xAD\xBB\xAF + \xF0\xAD\xBB\xB0 + \xF0\xAD\xBB\xB1 + \xF0\xAD\xBB\xB2 + \xF0\xAD\xBB\xB3 + \xF0\xAD\xBB\xB4 + \xF0\xAD\xBB\xB5 + \xF0\xAD\xBB\xB6 + \xF0\xAD\xBB\xB7 + \xF0\xAD\xBB\xB8 + \xF0\xAD\xBB\xB9 + \xF0\xAD\xBB\xBA + \xF0\xAD\xBB\xBB + \xF0\xAD\xBB\xBC + \xF0\xAD\xBB\xBD + \xF0\xAD\xBB\xBE + \xF0\xAD\xBB\xBF + \xF0\xAD\xBC\x80 + \xF0\xAD\xBC\x81 + \xF0\xAD\xBC\x82 + \xF0\xAD\xBC\x83 + \xF0\xAD\xBC\x84 + \xF0\xAD\xBC\x85 + \xF0\xAD\xBC\x86 + \xF0\xAD\xBC\x87 + \xF0\xAD\xBC\x88 + \xF0\xAD\xBC\x89 + \xF0\xAD\xBC\x8A + \xF0\xAD\xBC\x8B + \xF0\xAD\xBC\x8C + \xF0\xAD\xBC\x8D + \xF0\xAD\xBC\x8E + \xF0\xAD\xBC\x8F + \xF0\xAD\xBC\x90 + \xF0\xAD\xBC\x91 + \xF0\xAD\xBC\x92 + \xF0\xAD\xBC\x93 + \xF0\xAD\xBC\x94 + \xF0\xAD\xBC\x95 + \xF0\xAD\xBC\x96 + \xF0\xAD\xBC\x97 + \xF0\xAD\xBC\x98 + \xF0\xAD\xBC\x99 + \xF0\xAD\xBC\x9A + \xF0\xAD\xBC\x9B + \xF0\xAD\xBC\x9C + \xF0\xAD\xBC\x9D + \xF0\xAD\xBC\x9E + \xF0\xAD\xBC\x9F + \xF0\xAD\xBC\xA0 + \xF0\xAD\xBC\xA1 + \xF0\xAD\xBC\xA2 + \xF0\xAD\xBC\xA3 + \xF0\xAD\xBC\xA4 + \xF0\xAD\xBC\xA5 + \xF0\xAD\xBC\xA6 + \xF0\xAD\xBC\xA7 + \xF0\xAD\xBC\xA8 + \xF0\xAD\xBC\xA9 + \xF0\xAD\xBC\xAA + \xF0\xAD\xBC\xAB + \xF0\xAD\xBC\xAC + \xF0\xAD\xBC\xAD + \xF0\xAD\xBC\xAE + \xF0\xAD\xBC\xAF + \xF0\xAD\xBC\xB0 + \xF0\xAD\xBC\xB1 + \xF0\xAD\xBC\xB2 + \xF0\xAD\xBC\xB3 + \xF0\xAD\xBC\xB4 + \xF0\xAD\xBC\xB5 + \xF0\xAD\xBC\xB6 + \xF0\xAD\xBC\xB7 + \xF0\xAD\xBC\xB8 + \xF0\xAD\xBC\xB9 + \xF0\xAD\xBC\xBA + \xF0\xAD\xBC\xBB + \xF0\xAD\xBC\xBC + \xF0\xAD\xBC\xBD + \xF0\xAD\xBC\xBE + \xF0\xAD\xBC\xBF + \xF0\xAD\xBD\x80 + \xF0\xAD\xBD\x81 + \xF0\xAD\xBD\x82 + \xF0\xAD\xBD\x83 + \xF0\xAD\xBD\x84 + \xF0\xAD\xBD\x85 + \xF0\xAD\xBD\x86 + \xF0\xAD\xBD\x87 + \xF0\xAD\xBD\x88 + \xF0\xAD\xBD\x89 + \xF0\xAD\xBD\x8A + \xF0\xAD\xBD\x8B + \xF0\xAD\xBD\x8C + \xF0\xAD\xBD\x8D + \xF0\xAD\xBD\x8E + \xF0\xAD\xBD\x8F + \xF0\xAD\xBD\x90 + \xF0\xAD\xBD\x91 + \xF0\xAD\xBD\x92 + \xF0\xAD\xBD\x93 + \xF0\xAD\xBD\x94 + \xF0\xAD\xBD\x95 + \xF0\xAD\xBD\x96 + \xF0\xAD\xBD\x97 + \xF0\xAD\xBD\x98 + \xF0\xAD\xBD\x99 + \xF0\xAD\xBD\x9A + \xF0\xAD\xBD\x9B + \xF0\xAD\xBD\x9C + \xF0\xAD\xBD\x9D + \xF0\xAD\xBD\x9E + \xF0\xAD\xBD\x9F + \xF0\xAD\xBD\xA0 + \xF0\xAD\xBD\xA1 + \xF0\xAD\xBD\xA2 + \xF0\xAD\xBD\xA3 + \xF0\xAD\xBD\xA4 + \xF0\xAD\xBD\xA5 + \xF0\xAD\xBD\xA6 + \xF0\xAD\xBD\xA7 + \xF0\xAD\xBD\xA8 + \xF0\xAD\xBD\xA9 + \xF0\xAD\xBD\xAA + \xF0\xAD\xBD\xAB + \xF0\xAD\xBD\xAC + \xF0\xAD\xBD\xAD + \xF0\xAD\xBD\xAE + \xF0\xAD\xBD\xAF + \xF0\xAD\xBD\xB0 + \xF0\xAD\xBD\xB1 + \xF0\xAD\xBD\xB2 + \xF0\xAD\xBD\xB3 + \xF0\xAD\xBD\xB4 + \xF0\xAD\xBD\xB5 + \xF0\xAD\xBD\xB6 + \xF0\xAD\xBD\xB7 + \xF0\xAD\xBD\xB8 + \xF0\xAD\xBD\xB9 + \xF0\xAD\xBD\xBA + \xF0\xAD\xBD\xBB + \xF0\xAD\xBD\xBC + \xF0\xAD\xBD\xBD + \xF0\xAD\xBD\xBE + \xF0\xAD\xBD\xBF + \xF0\xAD\xBE\x80 + \xF0\xAD\xBE\x81 + \xF0\xAD\xBE\x82 + \xF0\xAD\xBE\x83 + \xF0\xAD\xBE\x84 + \xF0\xAD\xBE\x85 + \xF0\xAD\xBE\x86 + \xF0\xAD\xBE\x87 + \xF0\xAD\xBE\x88 + \xF0\xAD\xBE\x89 + \xF0\xAD\xBE\x8A + \xF0\xAD\xBE\x8B + \xF0\xAD\xBE\x8C + \xF0\xAD\xBE\x8D + \xF0\xAD\xBE\x8E + \xF0\xAD\xBE\x8F + \xF0\xAD\xBE\x90 + \xF0\xAD\xBE\x91 + \xF0\xAD\xBE\x92 + \xF0\xAD\xBE\x93 + \xF0\xAD\xBE\x94 + \xF0\xAD\xBE\x95 + \xF0\xAD\xBE\x96 + \xF0\xAD\xBE\x97 + \xF0\xAD\xBE\x98 + \xF0\xAD\xBE\x99 + \xF0\xAD\xBE\x9A + \xF0\xAD\xBE\x9B + \xF0\xAD\xBE\x9C + \xF0\xAD\xBE\x9D + \xF0\xAD\xBE\x9E + \xF0\xAD\xBE\x9F + \xF0\xAD\xBE\xA0 + \xF0\xAD\xBE\xA1 + \xF0\xAD\xBE\xA2 + \xF0\xAD\xBE\xA3 + \xF0\xAD\xBE\xA4 + \xF0\xAD\xBE\xA5 + \xF0\xAD\xBE\xA6 + \xF0\xAD\xBE\xA7 + \xF0\xAD\xBE\xA8 + \xF0\xAD\xBE\xA9 + \xF0\xAD\xBE\xAA + \xF0\xAD\xBE\xAB + \xF0\xAD\xBE\xAC + \xF0\xAD\xBE\xAD + \xF0\xAD\xBE\xAE + \xF0\xAD\xBE\xAF + \xF0\xAD\xBE\xB0 + \xF0\xAD\xBE\xB1 + \xF0\xAD\xBE\xB2 + \xF0\xAD\xBE\xB3 + \xF0\xAD\xBE\xB4 + \xF0\xAD\xBE\xB5 + \xF0\xAD\xBE\xB6 + \xF0\xAD\xBE\xB7 + \xF0\xAD\xBE\xB8 + \xF0\xAD\xBE\xB9 + \xF0\xAD\xBE\xBA + \xF0\xAD\xBE\xBB + \xF0\xAD\xBE\xBC + \xF0\xAD\xBE\xBD + \xF0\xAD\xBE\xBE + \xF0\xAD\xBE\xBF + \xF0\xAD\xBF\x80 + \xF0\xAD\xBF\x81 + \xF0\xAD\xBF\x82 + \xF0\xAD\xBF\x83 + \xF0\xAD\xBF\x84 + \xF0\xAD\xBF\x85 + \xF0\xAD\xBF\x86 + \xF0\xAD\xBF\x87 + \xF0\xAD\xBF\x88 + \xF0\xAD\xBF\x89 + \xF0\xAD\xBF\x8A + \xF0\xAD\xBF\x8B + \xF0\xAD\xBF\x8C + \xF0\xAD\xBF\x8D + \xF0\xAD\xBF\x8E + \xF0\xAD\xBF\x8F + \xF0\xAD\xBF\x90 + \xF0\xAD\xBF\x91 + \xF0\xAD\xBF\x92 + \xF0\xAD\xBF\x93 + \xF0\xAD\xBF\x94 + \xF0\xAD\xBF\x95 + \xF0\xAD\xBF\x96 + \xF0\xAD\xBF\x97 + \xF0\xAD\xBF\x98 + \xF0\xAD\xBF\x99 + \xF0\xAD\xBF\x9A + \xF0\xAD\xBF\x9B + \xF0\xAD\xBF\x9C + \xF0\xAD\xBF\x9D + \xF0\xAD\xBF\x9E + \xF0\xAD\xBF\x9F + \xF0\xAD\xBF\xA0 + \xF0\xAD\xBF\xA1 + \xF0\xAD\xBF\xA2 + \xF0\xAD\xBF\xA3 + \xF0\xAD\xBF\xA4 + \xF0\xAD\xBF\xA5 + \xF0\xAD\xBF\xA6 + \xF0\xAD\xBF\xA7 + \xF0\xAD\xBF\xA8 + \xF0\xAD\xBF\xA9 + \xF0\xAD\xBF\xAA + \xF0\xAD\xBF\xAB + \xF0\xAD\xBF\xAC + \xF0\xAD\xBF\xAD + \xF0\xAD\xBF\xAE + \xF0\xAD\xBF\xAF + \xF0\xAD\xBF\xB0 + \xF0\xAD\xBF\xB1 + \xF0\xAD\xBF\xB2 + \xF0\xAD\xBF\xB3 + \xF0\xAD\xBF\xB4 + \xF0\xAD\xBF\xB5 + \xF0\xAD\xBF\xB6 + \xF0\xAD\xBF\xB7 + \xF0\xAD\xBF\xB8 + \xF0\xAD\xBF\xB9 + \xF0\xAD\xBF\xBA + \xF0\xAD\xBF\xBB + \xF0\xAD\xBF\xBC + \xF0\xAD\xBF\xBD + \xF0\xAD\xBF\xBE + \xF0\xAD\xBF\xBF + \xF0\xAE\x80\x80 + \xF0\xAE\x80\x81 + \xF0\xAE\x80\x82 + \xF0\xAE\x80\x83 + \xF0\xAE\x80\x84 + \xF0\xAE\x80\x85 + \xF0\xAE\x80\x86 + \xF0\xAE\x80\x87 + \xF0\xAE\x80\x88 + \xF0\xAE\x80\x89 + \xF0\xAE\x80\x8A + \xF0\xAE\x80\x8B + \xF0\xAE\x80\x8C + \xF0\xAE\x80\x8D + \xF0\xAE\x80\x8E + \xF0\xAE\x80\x8F + \xF0\xAE\x80\x90 + \xF0\xAE\x80\x91 + \xF0\xAE\x80\x92 + \xF0\xAE\x80\x93 + \xF0\xAE\x80\x94 + \xF0\xAE\x80\x95 + \xF0\xAE\x80\x96 + \xF0\xAE\x80\x97 + \xF0\xAE\x80\x98 + \xF0\xAE\x80\x99 + \xF0\xAE\x80\x9A + \xF0\xAE\x80\x9B + \xF0\xAE\x80\x9C + \xF0\xAE\x80\x9D + \xF0\xAE\x80\x9E + \xF0\xAE\x80\x9F + \xF0\xAE\x80\xA0 + \xF0\xAE\x80\xA1 + \xF0\xAE\x80\xA2 + \xF0\xAE\x80\xA3 + \xF0\xAE\x80\xA4 + \xF0\xAE\x80\xA5 + \xF0\xAE\x80\xA6 + \xF0\xAE\x80\xA7 + \xF0\xAE\x80\xA8 + \xF0\xAE\x80\xA9 + \xF0\xAE\x80\xAA + \xF0\xAE\x80\xAB + \xF0\xAE\x80\xAC + \xF0\xAE\x80\xAD + \xF0\xAE\x80\xAE + \xF0\xAE\x80\xAF + \xF0\xAE\x80\xB0 + \xF0\xAE\x80\xB1 + \xF0\xAE\x80\xB2 + \xF0\xAE\x80\xB3 + \xF0\xAE\x80\xB4 + \xF0\xAE\x80\xB5 + \xF0\xAE\x80\xB6 + \xF0\xAE\x80\xB7 + \xF0\xAE\x80\xB8 + \xF0\xAE\x80\xB9 + \xF0\xAE\x80\xBA + \xF0\xAE\x80\xBB + \xF0\xAE\x80\xBC + \xF0\xAE\x80\xBD + \xF0\xAE\x80\xBE + \xF0\xAE\x80\xBF + \xF0\xAE\x81\x80 + \xF0\xAE\x81\x81 + \xF0\xAE\x81\x82 + \xF0\xAE\x81\x83 + \xF0\xAE\x81\x84 + \xF0\xAE\x81\x85 + \xF0\xAE\x81\x86 + \xF0\xAE\x81\x87 + \xF0\xAE\x81\x88 + \xF0\xAE\x81\x89 + \xF0\xAE\x81\x8A + \xF0\xAE\x81\x8B + \xF0\xAE\x81\x8C + \xF0\xAE\x81\x8D + \xF0\xAE\x81\x8E + \xF0\xAE\x81\x8F + \xF0\xAE\x81\x90 + \xF0\xAE\x81\x91 + \xF0\xAE\x81\x92 + \xF0\xAE\x81\x93 + \xF0\xAE\x81\x94 + \xF0\xAE\x81\x95 + \xF0\xAE\x81\x96 + \xF0\xAE\x81\x97 + \xF0\xAE\x81\x98 + \xF0\xAE\x81\x99 + \xF0\xAE\x81\x9A + \xF0\xAE\x81\x9B + \xF0\xAE\x81\x9C + \xF0\xAE\x81\x9D + \xF0\xAE\x81\x9E + \xF0\xAE\x81\x9F + \xF0\xAE\x81\xA0 + \xF0\xAE\x81\xA1 + \xF0\xAE\x81\xA2 + \xF0\xAE\x81\xA3 + \xF0\xAE\x81\xA4 + \xF0\xAE\x81\xA5 + \xF0\xAE\x81\xA6 + \xF0\xAE\x81\xA7 + \xF0\xAE\x81\xA8 + \xF0\xAE\x81\xA9 + \xF0\xAE\x81\xAA + \xF0\xAE\x81\xAB + \xF0\xAE\x81\xAC + \xF0\xAE\x81\xAD + \xF0\xAE\x81\xAE + \xF0\xAE\x81\xAF + \xF0\xAE\x81\xB0 + \xF0\xAE\x81\xB1 + \xF0\xAE\x81\xB2 + \xF0\xAE\x81\xB3 + \xF0\xAE\x81\xB4 + \xF0\xAE\x81\xB5 + \xF0\xAE\x81\xB6 + \xF0\xAE\x81\xB7 + \xF0\xAE\x81\xB8 + \xF0\xAE\x81\xB9 + \xF0\xAE\x81\xBA + \xF0\xAE\x81\xBB + \xF0\xAE\x81\xBC + \xF0\xAE\x81\xBD + \xF0\xAE\x81\xBE + \xF0\xAE\x81\xBF + \xF0\xAE\x82\x80 + \xF0\xAE\x82\x81 + \xF0\xAE\x82\x82 + \xF0\xAE\x82\x83 + \xF0\xAE\x82\x84 + \xF0\xAE\x82\x85 + \xF0\xAE\x82\x86 + \xF0\xAE\x82\x87 + \xF0\xAE\x82\x88 + \xF0\xAE\x82\x89 + \xF0\xAE\x82\x8A + \xF0\xAE\x82\x8B + \xF0\xAE\x82\x8C + \xF0\xAE\x82\x8D + \xF0\xAE\x82\x8E + \xF0\xAE\x82\x8F + \xF0\xAE\x82\x90 + \xF0\xAE\x82\x91 + \xF0\xAE\x82\x92 + \xF0\xAE\x82\x93 + \xF0\xAE\x82\x94 + \xF0\xAE\x82\x95 + \xF0\xAE\x82\x96 + \xF0\xAE\x82\x97 + \xF0\xAE\x82\x98 + \xF0\xAE\x82\x99 + \xF0\xAE\x82\x9A + \xF0\xAE\x82\x9B + \xF0\xAE\x82\x9C + \xF0\xAE\x82\x9D + \xF0\xAE\x82\x9E + \xF0\xAE\x82\x9F + \xF0\xAE\x82\xA0 + \xF0\xAE\x82\xA1 + \xF0\xAE\x82\xA2 + \xF0\xAE\x82\xA3 + \xF0\xAE\x82\xA4 + \xF0\xAE\x82\xA5 + \xF0\xAE\x82\xA6 + \xF0\xAE\x82\xA7 + \xF0\xAE\x82\xA8 + \xF0\xAE\x82\xA9 + \xF0\xAE\x82\xAA + \xF0\xAE\x82\xAB + \xF0\xAE\x82\xAC + \xF0\xAE\x82\xAD + \xF0\xAE\x82\xAE + \xF0\xAE\x82\xAF + \xF0\xAE\x82\xB0 + \xF0\xAE\x82\xB1 + \xF0\xAE\x82\xB2 + \xF0\xAE\x82\xB3 + \xF0\xAE\x82\xB4 + \xF0\xAE\x82\xB5 + \xF0\xAE\x82\xB6 + \xF0\xAE\x82\xB7 + \xF0\xAE\x82\xB8 + \xF0\xAE\x82\xB9 + \xF0\xAE\x82\xBA + \xF0\xAE\x82\xBB + \xF0\xAE\x82\xBC + \xF0\xAE\x82\xBD + \xF0\xAE\x82\xBE + \xF0\xAE\x82\xBF + \xF0\xAE\x83\x80 + \xF0\xAE\x83\x81 + \xF0\xAE\x83\x82 + \xF0\xAE\x83\x83 + \xF0\xAE\x83\x84 + \xF0\xAE\x83\x85 + \xF0\xAE\x83\x86 + \xF0\xAE\x83\x87 + \xF0\xAE\x83\x88 + \xF0\xAE\x83\x89 + \xF0\xAE\x83\x8A + \xF0\xAE\x83\x8B + \xF0\xAE\x83\x8C + \xF0\xAE\x83\x8D + \xF0\xAE\x83\x8E + \xF0\xAE\x83\x8F + \xF0\xAE\x83\x90 + \xF0\xAE\x83\x91 + \xF0\xAE\x83\x92 + \xF0\xAE\x83\x93 + \xF0\xAE\x83\x94 + \xF0\xAE\x83\x95 + \xF0\xAE\x83\x96 + \xF0\xAE\x83\x97 + \xF0\xAE\x83\x98 + \xF0\xAE\x83\x99 + \xF0\xAE\x83\x9A + \xF0\xAE\x83\x9B + \xF0\xAE\x83\x9C + \xF0\xAE\x83\x9D + \xF0\xAE\x83\x9E + \xF0\xAE\x83\x9F + \xF0\xAE\x83\xA0 + \xF0\xAE\x83\xA1 + \xF0\xAE\x83\xA2 + \xF0\xAE\x83\xA3 + \xF0\xAE\x83\xA4 + \xF0\xAE\x83\xA5 + \xF0\xAE\x83\xA6 + \xF0\xAE\x83\xA7 + \xF0\xAE\x83\xA8 + \xF0\xAE\x83\xA9 + \xF0\xAE\x83\xAA + \xF0\xAE\x83\xAB + \xF0\xAE\x83\xAC + \xF0\xAE\x83\xAD + \xF0\xAE\x83\xAE + \xF0\xAE\x83\xAF + \xF0\xAE\x83\xB0 + \xF0\xAE\x83\xB1 + \xF0\xAE\x83\xB2 + \xF0\xAE\x83\xB3 + \xF0\xAE\x83\xB4 + \xF0\xAE\x83\xB5 + \xF0\xAE\x83\xB6 + \xF0\xAE\x83\xB7 + \xF0\xAE\x83\xB8 + \xF0\xAE\x83\xB9 + \xF0\xAE\x83\xBA + \xF0\xAE\x83\xBB + \xF0\xAE\x83\xBC + \xF0\xAE\x83\xBD + \xF0\xAE\x83\xBE + \xF0\xAE\x83\xBF + \xF0\xAE\x84\x80 + \xF0\xAE\x84\x81 + \xF0\xAE\x84\x82 + \xF0\xAE\x84\x83 + \xF0\xAE\x84\x84 + \xF0\xAE\x84\x85 + \xF0\xAE\x84\x86 + \xF0\xAE\x84\x87 + \xF0\xAE\x84\x88 + \xF0\xAE\x84\x89 + \xF0\xAE\x84\x8A + \xF0\xAE\x84\x8B + \xF0\xAE\x84\x8C + \xF0\xAE\x84\x8D + \xF0\xAE\x84\x8E + \xF0\xAE\x84\x8F + \xF0\xAE\x84\x90 + \xF0\xAE\x84\x91 + \xF0\xAE\x84\x92 + \xF0\xAE\x84\x93 + \xF0\xAE\x84\x94 + \xF0\xAE\x84\x95 + \xF0\xAE\x84\x96 + \xF0\xAE\x84\x97 + \xF0\xAE\x84\x98 + \xF0\xAE\x84\x99 + \xF0\xAE\x84\x9A + \xF0\xAE\x84\x9B + \xF0\xAE\x84\x9C + \xF0\xAE\x84\x9D + \xF0\xAE\x84\x9E + \xF0\xAE\x84\x9F + \xF0\xAE\x84\xA0 + \xF0\xAE\x84\xA1 + \xF0\xAE\x84\xA2 + \xF0\xAE\x84\xA3 + \xF0\xAE\x84\xA4 + \xF0\xAE\x84\xA5 + \xF0\xAE\x84\xA6 + \xF0\xAE\x84\xA7 + \xF0\xAE\x84\xA8 + \xF0\xAE\x84\xA9 + \xF0\xAE\x84\xAA + \xF0\xAE\x84\xAB + \xF0\xAE\x84\xAC + \xF0\xAE\x84\xAD + \xF0\xAE\x84\xAE + \xF0\xAE\x84\xAF + \xF0\xAE\x84\xB0 + \xF0\xAE\x84\xB1 + \xF0\xAE\x84\xB2 + \xF0\xAE\x84\xB3 + \xF0\xAE\x84\xB4 + \xF0\xAE\x84\xB5 + \xF0\xAE\x84\xB6 + \xF0\xAE\x84\xB7 + \xF0\xAE\x84\xB8 + \xF0\xAE\x84\xB9 + \xF0\xAE\x84\xBA + \xF0\xAE\x84\xBB + \xF0\xAE\x84\xBC + \xF0\xAE\x84\xBD + \xF0\xAE\x84\xBE + \xF0\xAE\x84\xBF + \xF0\xAE\x85\x80 + \xF0\xAE\x85\x81 + \xF0\xAE\x85\x82 + \xF0\xAE\x85\x83 + \xF0\xAE\x85\x84 + \xF0\xAE\x85\x85 + \xF0\xAE\x85\x86 + \xF0\xAE\x85\x87 + \xF0\xAE\x85\x88 + \xF0\xAE\x85\x89 + \xF0\xAE\x85\x8A + \xF0\xAE\x85\x8B + \xF0\xAE\x85\x8C + \xF0\xAE\x85\x8D + \xF0\xAE\x85\x8E + \xF0\xAE\x85\x8F + \xF0\xAE\x85\x90 + \xF0\xAE\x85\x91 + \xF0\xAE\x85\x92 + \xF0\xAE\x85\x93 + \xF0\xAE\x85\x94 + \xF0\xAE\x85\x95 + \xF0\xAE\x85\x96 + \xF0\xAE\x85\x97 + \xF0\xAE\x85\x98 + \xF0\xAE\x85\x99 + \xF0\xAE\x85\x9A + \xF0\xAE\x85\x9B + \xF0\xAE\x85\x9C + \xF0\xAE\x85\x9D + \xF0\xAE\x85\x9E + \xF0\xAE\x85\x9F + \xF0\xAE\x85\xA0 + \xF0\xAE\x85\xA1 + \xF0\xAE\x85\xA2 + \xF0\xAE\x85\xA3 + \xF0\xAE\x85\xA4 + \xF0\xAE\x85\xA5 + \xF0\xAE\x85\xA6 + \xF0\xAE\x85\xA7 + \xF0\xAE\x85\xA8 + \xF0\xAE\x85\xA9 + \xF0\xAE\x85\xAA + \xF0\xAE\x85\xAB + \xF0\xAE\x85\xAC + \xF0\xAE\x85\xAD + \xF0\xAE\x85\xAE + \xF0\xAE\x85\xAF + \xF0\xAE\x85\xB0 + \xF0\xAE\x85\xB1 + \xF0\xAE\x85\xB2 + \xF0\xAE\x85\xB3 + \xF0\xAE\x85\xB4 + \xF0\xAE\x85\xB5 + \xF0\xAE\x85\xB6 + \xF0\xAE\x85\xB7 + \xF0\xAE\x85\xB8 + \xF0\xAE\x85\xB9 + \xF0\xAE\x85\xBA + \xF0\xAE\x85\xBB + \xF0\xAE\x85\xBC + \xF0\xAE\x85\xBD + \xF0\xAE\x85\xBE + \xF0\xAE\x85\xBF + \xF0\xAE\x86\x80 + \xF0\xAE\x86\x81 + \xF0\xAE\x86\x82 + \xF0\xAE\x86\x83 + \xF0\xAE\x86\x84 + \xF0\xAE\x86\x85 + \xF0\xAE\x86\x86 + \xF0\xAE\x86\x87 + \xF0\xAE\x86\x88 + \xF0\xAE\x86\x89 + \xF0\xAE\x86\x8A + \xF0\xAE\x86\x8B + \xF0\xAE\x86\x8C + \xF0\xAE\x86\x8D + \xF0\xAE\x86\x8E + \xF0\xAE\x86\x8F + \xF0\xAE\x86\x90 + \xF0\xAE\x86\x91 + \xF0\xAE\x86\x92 + \xF0\xAE\x86\x93 + \xF0\xAE\x86\x94 + \xF0\xAE\x86\x95 + \xF0\xAE\x86\x96 + \xF0\xAE\x86\x97 + \xF0\xAE\x86\x98 + \xF0\xAE\x86\x99 + \xF0\xAE\x86\x9A + \xF0\xAE\x86\x9B + \xF0\xAE\x86\x9C + \xF0\xAE\x86\x9D + \xF0\xAE\x86\x9E + \xF0\xAE\x86\x9F + \xF0\xAE\x86\xA0 + \xF0\xAE\x86\xA1 + \xF0\xAE\x86\xA2 + \xF0\xAE\x86\xA3 + \xF0\xAE\x86\xA4 + \xF0\xAE\x86\xA5 + \xF0\xAE\x86\xA6 + \xF0\xAE\x86\xA7 + \xF0\xAE\x86\xA8 + \xF0\xAE\x86\xA9 + \xF0\xAE\x86\xAA + \xF0\xAE\x86\xAB + \xF0\xAE\x86\xAC + \xF0\xAE\x86\xAD + \xF0\xAE\x86\xAE + \xF0\xAE\x86\xAF + \xF0\xAE\x86\xB0 + \xF0\xAE\x86\xB1 + \xF0\xAE\x86\xB2 + \xF0\xAE\x86\xB3 + \xF0\xAE\x86\xB4 + \xF0\xAE\x86\xB5 + \xF0\xAE\x86\xB6 + \xF0\xAE\x86\xB7 + \xF0\xAE\x86\xB8 + \xF0\xAE\x86\xB9 + \xF0\xAE\x86\xBA + \xF0\xAE\x86\xBB + \xF0\xAE\x86\xBC + \xF0\xAE\x86\xBD + \xF0\xAE\x86\xBE + \xF0\xAE\x86\xBF + \xF0\xAE\x87\x80 + \xF0\xAE\x87\x81 + \xF0\xAE\x87\x82 + \xF0\xAE\x87\x83 + \xF0\xAE\x87\x84 + \xF0\xAE\x87\x85 + \xF0\xAE\x87\x86 + \xF0\xAE\x87\x87 + \xF0\xAE\x87\x88 + \xF0\xAE\x87\x89 + \xF0\xAE\x87\x8A + \xF0\xAE\x87\x8B + \xF0\xAE\x87\x8C + \xF0\xAE\x87\x8D + \xF0\xAE\x87\x8E + \xF0\xAE\x87\x8F + \xF0\xAE\x87\x90 + \xF0\xAE\x87\x91 + \xF0\xAE\x87\x92 + \xF0\xAE\x87\x93 + \xF0\xAE\x87\x94 + \xF0\xAE\x87\x95 + \xF0\xAE\x87\x96 + \xF0\xAE\x87\x97 + \xF0\xAE\x87\x98 + \xF0\xAE\x87\x99 + \xF0\xAE\x87\x9A + \xF0\xAE\x87\x9B + \xF0\xAE\x87\x9C + \xF0\xAE\x87\x9D + \xF0\xAE\x87\x9E + \xF0\xAE\x87\x9F + \xF0\xAE\x87\xA0 + \xF0\xAE\x87\xA1 + \xF0\xAE\x87\xA2 + \xF0\xAE\x87\xA3 + \xF0\xAE\x87\xA4 + \xF0\xAE\x87\xA5 + \xF0\xAE\x87\xA6 + \xF0\xAE\x87\xA7 + \xF0\xAE\x87\xA8 + \xF0\xAE\x87\xA9 + \xF0\xAE\x87\xAA + \xF0\xAE\x87\xAB + \xF0\xAE\x87\xAC + \xF0\xAE\x87\xAD + \xF0\xAE\x87\xAE + \xF0\xAE\x87\xAF + \xF0\xAE\x87\xB0 + \xF0\xAE\x87\xB1 + \xF0\xAE\x87\xB2 + \xF0\xAE\x87\xB3 + \xF0\xAE\x87\xB4 + \xF0\xAE\x87\xB5 + \xF0\xAE\x87\xB6 + \xF0\xAE\x87\xB7 + \xF0\xAE\x87\xB8 + \xF0\xAE\x87\xB9 + \xF0\xAE\x87\xBA + \xF0\xAE\x87\xBB + \xF0\xAE\x87\xBC + \xF0\xAE\x87\xBD + \xF0\xAE\x87\xBE + \xF0\xAE\x87\xBF + \xF0\xAE\x88\x80 + \xF0\xAE\x88\x81 + \xF0\xAE\x88\x82 + \xF0\xAE\x88\x83 + \xF0\xAE\x88\x84 + \xF0\xAE\x88\x85 + \xF0\xAE\x88\x86 + \xF0\xAE\x88\x87 + \xF0\xAE\x88\x88 + \xF0\xAE\x88\x89 + \xF0\xAE\x88\x8A + \xF0\xAE\x88\x8B + \xF0\xAE\x88\x8C + \xF0\xAE\x88\x8D + \xF0\xAE\x88\x8E + \xF0\xAE\x88\x8F + \xF0\xAE\x88\x90 + \xF0\xAE\x88\x91 + \xF0\xAE\x88\x92 + \xF0\xAE\x88\x93 + \xF0\xAE\x88\x94 + \xF0\xAE\x88\x95 + \xF0\xAE\x88\x96 + \xF0\xAE\x88\x97 + \xF0\xAE\x88\x98 + \xF0\xAE\x88\x99 + \xF0\xAE\x88\x9A + \xF0\xAE\x88\x9B + \xF0\xAE\x88\x9C + \xF0\xAE\x88\x9D + \xF0\xAE\x88\x9E + \xF0\xAE\x88\x9F + \xF0\xAE\x88\xA0 + \xF0\xAE\x88\xA1 + \xF0\xAE\x88\xA2 + \xF0\xAE\x88\xA3 + \xF0\xAE\x88\xA4 + \xF0\xAE\x88\xA5 + \xF0\xAE\x88\xA6 + \xF0\xAE\x88\xA7 + \xF0\xAE\x88\xA8 + \xF0\xAE\x88\xA9 + \xF0\xAE\x88\xAA + \xF0\xAE\x88\xAB + \xF0\xAE\x88\xAC + \xF0\xAE\x88\xAD + \xF0\xAE\x88\xAE + \xF0\xAE\x88\xAF + \xF0\xAE\x88\xB0 + \xF0\xAE\x88\xB1 + \xF0\xAE\x88\xB2 + \xF0\xAE\x88\xB3 + \xF0\xAE\x88\xB4 + \xF0\xAE\x88\xB5 + \xF0\xAE\x88\xB6 + \xF0\xAE\x88\xB7 + \xF0\xAE\x88\xB8 + \xF0\xAE\x88\xB9 + \xF0\xAE\x88\xBA + \xF0\xAE\x88\xBB + \xF0\xAE\x88\xBC + \xF0\xAE\x88\xBD + \xF0\xAE\x88\xBE + \xF0\xAE\x88\xBF + \xF0\xAE\x89\x80 + \xF0\xAE\x89\x81 + \xF0\xAE\x89\x82 + \xF0\xAE\x89\x83 + \xF0\xAE\x89\x84 + \xF0\xAE\x89\x85 + \xF0\xAE\x89\x86 + \xF0\xAE\x89\x87 + \xF0\xAE\x89\x88 + \xF0\xAE\x89\x89 + \xF0\xAE\x89\x8A + \xF0\xAE\x89\x8B + \xF0\xAE\x89\x8C + \xF0\xAE\x89\x8D + \xF0\xAE\x89\x8E + \xF0\xAE\x89\x8F + \xF0\xAE\x89\x90 + \xF0\xAE\x89\x91 + \xF0\xAE\x89\x92 + \xF0\xAE\x89\x93 + \xF0\xAE\x89\x94 + \xF0\xAE\x89\x95 + \xF0\xAE\x89\x96 + \xF0\xAE\x89\x97 + \xF0\xAE\x89\x98 + \xF0\xAE\x89\x99 + \xF0\xAE\x89\x9A + \xF0\xAE\x89\x9B + \xF0\xAE\x89\x9C + \xF0\xAE\x89\x9D + \xF0\xAE\x89\x9E + \xF0\xAE\x89\x9F + \xF0\xAE\x89\xA0 + \xF0\xAE\x89\xA1 + \xF0\xAE\x89\xA2 + \xF0\xAE\x89\xA3 + \xF0\xAE\x89\xA4 + \xF0\xAE\x89\xA5 + \xF0\xAE\x89\xA6 + \xF0\xAE\x89\xA7 + \xF0\xAE\x89\xA8 + \xF0\xAE\x89\xA9 + \xF0\xAE\x89\xAA + \xF0\xAE\x89\xAB + \xF0\xAE\x89\xAC + \xF0\xAE\x89\xAD + \xF0\xAE\x89\xAE + \xF0\xAE\x89\xAF + \xF0\xAE\x89\xB0 + \xF0\xAE\x89\xB1 + \xF0\xAE\x89\xB2 + \xF0\xAE\x89\xB3 + \xF0\xAE\x89\xB4 + \xF0\xAE\x89\xB5 + \xF0\xAE\x89\xB6 + \xF0\xAE\x89\xB7 + \xF0\xAE\x89\xB8 + \xF0\xAE\x89\xB9 + \xF0\xAE\x89\xBA + \xF0\xAE\x89\xBB + \xF0\xAE\x89\xBC + \xF0\xAE\x89\xBD + \xF0\xAE\x89\xBE + \xF0\xAE\x89\xBF + \xF0\xAE\x8A\x80 + \xF0\xAE\x8A\x81 + \xF0\xAE\x8A\x82 + \xF0\xAE\x8A\x83 + \xF0\xAE\x8A\x84 + \xF0\xAE\x8A\x85 + \xF0\xAE\x8A\x86 + \xF0\xAE\x8A\x87 + \xF0\xAE\x8A\x88 + \xF0\xAE\x8A\x89 + \xF0\xAE\x8A\x8A + \xF0\xAE\x8A\x8B + \xF0\xAE\x8A\x8C + \xF0\xAE\x8A\x8D + \xF0\xAE\x8A\x8E + \xF0\xAE\x8A\x8F + \xF0\xAE\x8A\x90 + \xF0\xAE\x8A\x91 + \xF0\xAE\x8A\x92 + \xF0\xAE\x8A\x93 + \xF0\xAE\x8A\x94 + \xF0\xAE\x8A\x95 + \xF0\xAE\x8A\x96 + \xF0\xAE\x8A\x97 + \xF0\xAE\x8A\x98 + \xF0\xAE\x8A\x99 + \xF0\xAE\x8A\x9A + \xF0\xAE\x8A\x9B + \xF0\xAE\x8A\x9C + \xF0\xAE\x8A\x9D + \xF0\xAE\x8A\x9E + \xF0\xAE\x8A\x9F + \xF0\xAE\x8A\xA0 + \xF0\xAE\x8A\xA1 + \xF0\xAE\x8A\xA2 + \xF0\xAE\x8A\xA3 + \xF0\xAE\x8A\xA4 + \xF0\xAE\x8A\xA5 + \xF0\xAE\x8A\xA6 + \xF0\xAE\x8A\xA7 + \xF0\xAE\x8A\xA8 + \xF0\xAE\x8A\xA9 + \xF0\xAE\x8A\xAA + \xF0\xAE\x8A\xAB + \xF0\xAE\x8A\xAC + \xF0\xAE\x8A\xAD + \xF0\xAE\x8A\xAE + \xF0\xAE\x8A\xAF + \xF0\xAE\x8A\xB0 + \xF0\xAE\x8A\xB1 + \xF0\xAE\x8A\xB2 + \xF0\xAE\x8A\xB3 + \xF0\xAE\x8A\xB4 + \xF0\xAE\x8A\xB5 + \xF0\xAE\x8A\xB6 + \xF0\xAE\x8A\xB7 + \xF0\xAE\x8A\xB8 + \xF0\xAE\x8A\xB9 + \xF0\xAE\x8A\xBA + \xF0\xAE\x8A\xBB + \xF0\xAE\x8A\xBC + \xF0\xAE\x8A\xBD + \xF0\xAE\x8A\xBE + \xF0\xAE\x8A\xBF + \xF0\xAE\x8B\x80 + \xF0\xAE\x8B\x81 + \xF0\xAE\x8B\x82 + \xF0\xAE\x8B\x83 + \xF0\xAE\x8B\x84 + \xF0\xAE\x8B\x85 + \xF0\xAE\x8B\x86 + \xF0\xAE\x8B\x87 + \xF0\xAE\x8B\x88 + \xF0\xAE\x8B\x89 + \xF0\xAE\x8B\x8A + \xF0\xAE\x8B\x8B + \xF0\xAE\x8B\x8C + \xF0\xAE\x8B\x8D + \xF0\xAE\x8B\x8E + \xF0\xAE\x8B\x8F + \xF0\xAE\x8B\x90 + \xF0\xAE\x8B\x91 + \xF0\xAE\x8B\x92 + \xF0\xAE\x8B\x93 + \xF0\xAE\x8B\x94 + \xF0\xAE\x8B\x95 + \xF0\xAE\x8B\x96 + \xF0\xAE\x8B\x97 + \xF0\xAE\x8B\x98 + \xF0\xAE\x8B\x99 + \xF0\xAE\x8B\x9A + \xF0\xAE\x8B\x9B + \xF0\xAE\x8B\x9C + \xF0\xAE\x8B\x9D + \xF0\xAE\x8B\x9E + \xF0\xAE\x8B\x9F + \xF0\xAE\x8B\xA0 + \xF0\xAE\x8B\xA1 + \xF0\xAE\x8B\xA2 + \xF0\xAE\x8B\xA3 + \xF0\xAE\x8B\xA4 + \xF0\xAE\x8B\xA5 + \xF0\xAE\x8B\xA6 + \xF0\xAE\x8B\xA7 + \xF0\xAE\x8B\xA8 + \xF0\xAE\x8B\xA9 + \xF0\xAE\x8B\xAA + \xF0\xAE\x8B\xAB + \xF0\xAE\x8B\xAC + \xF0\xAE\x8B\xAD + \xF0\xAE\x8B\xAE + \xF0\xAE\x8B\xAF + \xF0\xAE\x8B\xB0 + \xF0\xAE\x8B\xB1 + \xF0\xAE\x8B\xB2 + \xF0\xAE\x8B\xB3 + \xF0\xAE\x8B\xB4 + \xF0\xAE\x8B\xB5 + \xF0\xAE\x8B\xB6 + \xF0\xAE\x8B\xB7 + \xF0\xAE\x8B\xB8 + \xF0\xAE\x8B\xB9 + \xF0\xAE\x8B\xBA + \xF0\xAE\x8B\xBB + \xF0\xAE\x8B\xBC + \xF0\xAE\x8B\xBD + \xF0\xAE\x8B\xBE + \xF0\xAE\x8B\xBF + \xF0\xAE\x8C\x80 + \xF0\xAE\x8C\x81 + \xF0\xAE\x8C\x82 + \xF0\xAE\x8C\x83 + \xF0\xAE\x8C\x84 + \xF0\xAE\x8C\x85 + \xF0\xAE\x8C\x86 + \xF0\xAE\x8C\x87 + \xF0\xAE\x8C\x88 + \xF0\xAE\x8C\x89 + \xF0\xAE\x8C\x8A + \xF0\xAE\x8C\x8B + \xF0\xAE\x8C\x8C + \xF0\xAE\x8C\x8D + \xF0\xAE\x8C\x8E + \xF0\xAE\x8C\x8F + \xF0\xAE\x8C\x90 + \xF0\xAE\x8C\x91 + \xF0\xAE\x8C\x92 + \xF0\xAE\x8C\x93 + \xF0\xAE\x8C\x94 + \xF0\xAE\x8C\x95 + \xF0\xAE\x8C\x96 + \xF0\xAE\x8C\x97 + \xF0\xAE\x8C\x98 + \xF0\xAE\x8C\x99 + \xF0\xAE\x8C\x9A + \xF0\xAE\x8C\x9B + \xF0\xAE\x8C\x9C + \xF0\xAE\x8C\x9D + \xF0\xAE\x8C\x9E + \xF0\xAE\x8C\x9F + \xF0\xAE\x8C\xA0 + \xF0\xAE\x8C\xA1 + \xF0\xAE\x8C\xA2 + \xF0\xAE\x8C\xA3 + \xF0\xAE\x8C\xA4 + \xF0\xAE\x8C\xA5 + \xF0\xAE\x8C\xA6 + \xF0\xAE\x8C\xA7 + \xF0\xAE\x8C\xA8 + \xF0\xAE\x8C\xA9 + \xF0\xAE\x8C\xAA + \xF0\xAE\x8C\xAB + \xF0\xAE\x8C\xAC + \xF0\xAE\x8C\xAD + \xF0\xAE\x8C\xAE + \xF0\xAE\x8C\xAF + \xF0\xAE\x8C\xB0 + \xF0\xAE\x8C\xB1 + \xF0\xAE\x8C\xB2 + \xF0\xAE\x8C\xB3 + \xF0\xAE\x8C\xB4 + \xF0\xAE\x8C\xB5 + \xF0\xAE\x8C\xB6 + \xF0\xAE\x8C\xB7 + \xF0\xAE\x8C\xB8 + \xF0\xAE\x8C\xB9 + \xF0\xAE\x8C\xBA + \xF0\xAE\x8C\xBB + \xF0\xAE\x8C\xBC + \xF0\xAE\x8C\xBD + \xF0\xAE\x8C\xBE + \xF0\xAE\x8C\xBF + \xF0\xAE\x8D\x80 + \xF0\xAE\x8D\x81 + \xF0\xAE\x8D\x82 + \xF0\xAE\x8D\x83 + \xF0\xAE\x8D\x84 + \xF0\xAE\x8D\x85 + \xF0\xAE\x8D\x86 + \xF0\xAE\x8D\x87 + \xF0\xAE\x8D\x88 + \xF0\xAE\x8D\x89 + \xF0\xAE\x8D\x8A + \xF0\xAE\x8D\x8B + \xF0\xAE\x8D\x8C + \xF0\xAE\x8D\x8D + \xF0\xAE\x8D\x8E + \xF0\xAE\x8D\x8F + \xF0\xAE\x8D\x90 + \xF0\xAE\x8D\x91 + \xF0\xAE\x8D\x92 + \xF0\xAE\x8D\x93 + \xF0\xAE\x8D\x94 + \xF0\xAE\x8D\x95 + \xF0\xAE\x8D\x96 + \xF0\xAE\x8D\x97 + \xF0\xAE\x8D\x98 + \xF0\xAE\x8D\x99 + \xF0\xAE\x8D\x9A + \xF0\xAE\x8D\x9B + \xF0\xAE\x8D\x9C + \xF0\xAE\x8D\x9D + \xF0\xAE\x8D\x9E + \xF0\xAE\x8D\x9F + \xF0\xAE\x8D\xA0 + \xF0\xAE\x8D\xA1 + \xF0\xAE\x8D\xA2 + \xF0\xAE\x8D\xA3 + \xF0\xAE\x8D\xA4 + \xF0\xAE\x8D\xA5 + \xF0\xAE\x8D\xA6 + \xF0\xAE\x8D\xA7 + \xF0\xAE\x8D\xA8 + \xF0\xAE\x8D\xA9 + \xF0\xAE\x8D\xAA + \xF0\xAE\x8D\xAB + \xF0\xAE\x8D\xAC + \xF0\xAE\x8D\xAD + \xF0\xAE\x8D\xAE + \xF0\xAE\x8D\xAF + \xF0\xAE\x8D\xB0 + \xF0\xAE\x8D\xB1 + \xF0\xAE\x8D\xB2 + \xF0\xAE\x8D\xB3 + \xF0\xAE\x8D\xB4 + \xF0\xAE\x8D\xB5 + \xF0\xAE\x8D\xB6 + \xF0\xAE\x8D\xB7 + \xF0\xAE\x8D\xB8 + \xF0\xAE\x8D\xB9 + \xF0\xAE\x8D\xBA + \xF0\xAE\x8D\xBB + \xF0\xAE\x8D\xBC + \xF0\xAE\x8D\xBD + \xF0\xAE\x8D\xBE + \xF0\xAE\x8D\xBF + \xF0\xAE\x8E\x80 + \xF0\xAE\x8E\x81 + \xF0\xAE\x8E\x82 + \xF0\xAE\x8E\x83 + \xF0\xAE\x8E\x84 + \xF0\xAE\x8E\x85 + \xF0\xAE\x8E\x86 + \xF0\xAE\x8E\x87 + \xF0\xAE\x8E\x88 + \xF0\xAE\x8E\x89 + \xF0\xAE\x8E\x8A + \xF0\xAE\x8E\x8B + \xF0\xAE\x8E\x8C + \xF0\xAE\x8E\x8D + \xF0\xAE\x8E\x8E + \xF0\xAE\x8E\x8F + \xF0\xAE\x8E\x90 + \xF0\xAE\x8E\x91 + \xF0\xAE\x8E\x92 + \xF0\xAE\x8E\x93 + \xF0\xAE\x8E\x94 + \xF0\xAE\x8E\x95 + \xF0\xAE\x8E\x96 + \xF0\xAE\x8E\x97 + \xF0\xAE\x8E\x98 + \xF0\xAE\x8E\x99 + \xF0\xAE\x8E\x9A + \xF0\xAE\x8E\x9B + \xF0\xAE\x8E\x9C + \xF0\xAE\x8E\x9D + \xF0\xAE\x8E\x9E + \xF0\xAE\x8E\x9F + \xF0\xAE\x8E\xA0 + \xF0\xAE\x8E\xA1 + \xF0\xAE\x8E\xA2 + \xF0\xAE\x8E\xA3 + \xF0\xAE\x8E\xA4 + \xF0\xAE\x8E\xA5 + \xF0\xAE\x8E\xA6 + \xF0\xAE\x8E\xA7 + \xF0\xAE\x8E\xA8 + \xF0\xAE\x8E\xA9 + \xF0\xAE\x8E\xAA + \xF0\xAE\x8E\xAB + \xF0\xAE\x8E\xAC + \xF0\xAE\x8E\xAD + \xF0\xAE\x8E\xAE + \xF0\xAE\x8E\xAF + \xF0\xAE\x8E\xB0 + \xF0\xAE\x8E\xB1 + \xF0\xAE\x8E\xB2 + \xF0\xAE\x8E\xB3 + \xF0\xAE\x8E\xB4 + \xF0\xAE\x8E\xB5 + \xF0\xAE\x8E\xB6 + \xF0\xAE\x8E\xB7 + \xF0\xAE\x8E\xB8 + \xF0\xAE\x8E\xB9 + \xF0\xAE\x8E\xBA + \xF0\xAE\x8E\xBB + \xF0\xAE\x8E\xBC + \xF0\xAE\x8E\xBD + \xF0\xAE\x8E\xBE + \xF0\xAE\x8E\xBF + \xF0\xAE\x8F\x80 + \xF0\xAE\x8F\x81 + \xF0\xAE\x8F\x82 + \xF0\xAE\x8F\x83 + \xF0\xAE\x8F\x84 + \xF0\xAE\x8F\x85 + \xF0\xAE\x8F\x86 + \xF0\xAE\x8F\x87 + \xF0\xAE\x8F\x88 + \xF0\xAE\x8F\x89 + \xF0\xAE\x8F\x8A + \xF0\xAE\x8F\x8B + \xF0\xAE\x8F\x8C + \xF0\xAE\x8F\x8D + \xF0\xAE\x8F\x8E + \xF0\xAE\x8F\x8F + \xF0\xAE\x8F\x90 + \xF0\xAE\x8F\x91 + \xF0\xAE\x8F\x92 + \xF0\xAE\x8F\x93 + \xF0\xAE\x8F\x94 + \xF0\xAE\x8F\x95 + \xF0\xAE\x8F\x96 + \xF0\xAE\x8F\x97 + \xF0\xAE\x8F\x98 + \xF0\xAE\x8F\x99 + \xF0\xAE\x8F\x9A + \xF0\xAE\x8F\x9B + \xF0\xAE\x8F\x9C + \xF0\xAE\x8F\x9D + \xF0\xAE\x8F\x9E + \xF0\xAE\x8F\x9F + \xF0\xAE\x8F\xA0 + \xF0\xAE\x8F\xA1 + \xF0\xAE\x8F\xA2 + \xF0\xAE\x8F\xA3 + \xF0\xAE\x8F\xA4 + \xF0\xAE\x8F\xA5 + \xF0\xAE\x8F\xA6 + \xF0\xAE\x8F\xA7 + \xF0\xAE\x8F\xA8 + \xF0\xAE\x8F\xA9 + \xF0\xAE\x8F\xAA + \xF0\xAE\x8F\xAB + \xF0\xAE\x8F\xAC + \xF0\xAE\x8F\xAD + \xF0\xAE\x8F\xAE + \xF0\xAE\x8F\xAF + \xF0\xAE\x8F\xB0 + \xF0\xAE\x8F\xB1 + \xF0\xAE\x8F\xB2 + \xF0\xAE\x8F\xB3 + \xF0\xAE\x8F\xB4 + \xF0\xAE\x8F\xB5 + \xF0\xAE\x8F\xB6 + \xF0\xAE\x8F\xB7 + \xF0\xAE\x8F\xB8 + \xF0\xAE\x8F\xB9 + \xF0\xAE\x8F\xBA + \xF0\xAE\x8F\xBB + \xF0\xAE\x8F\xBC + \xF0\xAE\x8F\xBD + \xF0\xAE\x8F\xBE + \xF0\xAE\x8F\xBF + \xF0\xAE\x90\x80 + \xF0\xAE\x90\x81 + \xF0\xAE\x90\x82 + \xF0\xAE\x90\x83 + \xF0\xAE\x90\x84 + \xF0\xAE\x90\x85 + \xF0\xAE\x90\x86 + \xF0\xAE\x90\x87 + \xF0\xAE\x90\x88 + \xF0\xAE\x90\x89 + \xF0\xAE\x90\x8A + \xF0\xAE\x90\x8B + \xF0\xAE\x90\x8C + \xF0\xAE\x90\x8D + \xF0\xAE\x90\x8E + \xF0\xAE\x90\x8F + \xF0\xAE\x90\x90 + \xF0\xAE\x90\x91 + \xF0\xAE\x90\x92 + \xF0\xAE\x90\x93 + \xF0\xAE\x90\x94 + \xF0\xAE\x90\x95 + \xF0\xAE\x90\x96 + \xF0\xAE\x90\x97 + \xF0\xAE\x90\x98 + \xF0\xAE\x90\x99 + \xF0\xAE\x90\x9A + \xF0\xAE\x90\x9B + \xF0\xAE\x90\x9C + \xF0\xAE\x90\x9D + \xF0\xAE\x90\x9E + \xF0\xAE\x90\x9F + \xF0\xAE\x90\xA0 + \xF0\xAE\x90\xA1 + \xF0\xAE\x90\xA2 + \xF0\xAE\x90\xA3 + \xF0\xAE\x90\xA4 + \xF0\xAE\x90\xA5 + \xF0\xAE\x90\xA6 + \xF0\xAE\x90\xA7 + \xF0\xAE\x90\xA8 + \xF0\xAE\x90\xA9 + \xF0\xAE\x90\xAA + \xF0\xAE\x90\xAB + \xF0\xAE\x90\xAC + \xF0\xAE\x90\xAD + \xF0\xAE\x90\xAE + \xF0\xAE\x90\xAF + \xF0\xAE\x90\xB0 + \xF0\xAE\x90\xB1 + \xF0\xAE\x90\xB2 + \xF0\xAE\x90\xB3 + \xF0\xAE\x90\xB4 + \xF0\xAE\x90\xB5 + \xF0\xAE\x90\xB6 + \xF0\xAE\x90\xB7 + \xF0\xAE\x90\xB8 + \xF0\xAE\x90\xB9 + \xF0\xAE\x90\xBA + \xF0\xAE\x90\xBB + \xF0\xAE\x90\xBC + \xF0\xAE\x90\xBD + \xF0\xAE\x90\xBE + \xF0\xAE\x90\xBF + \xF0\xAE\x91\x80 + \xF0\xAE\x91\x81 + \xF0\xAE\x91\x82 + \xF0\xAE\x91\x83 + \xF0\xAE\x91\x84 + \xF0\xAE\x91\x85 + \xF0\xAE\x91\x86 + \xF0\xAE\x91\x87 + \xF0\xAE\x91\x88 + \xF0\xAE\x91\x89 + \xF0\xAE\x91\x8A + \xF0\xAE\x91\x8B + \xF0\xAE\x91\x8C + \xF0\xAE\x91\x8D + \xF0\xAE\x91\x8E + \xF0\xAE\x91\x8F + \xF0\xAE\x91\x90 + \xF0\xAE\x91\x91 + \xF0\xAE\x91\x92 + \xF0\xAE\x91\x93 + \xF0\xAE\x91\x94 + \xF0\xAE\x91\x95 + \xF0\xAE\x91\x96 + \xF0\xAE\x91\x97 + \xF0\xAE\x91\x98 + \xF0\xAE\x91\x99 + \xF0\xAE\x91\x9A + \xF0\xAE\x91\x9B + \xF0\xAE\x91\x9C + \xF0\xAE\x91\x9D + \xF0\xAE\x91\x9E + \xF0\xAE\x91\x9F + \xF0\xAE\x91\xA0 + \xF0\xAE\x91\xA1 + \xF0\xAE\x91\xA2 + \xF0\xAE\x91\xA3 + \xF0\xAE\x91\xA4 + \xF0\xAE\x91\xA5 + \xF0\xAE\x91\xA6 + \xF0\xAE\x91\xA7 + \xF0\xAE\x91\xA8 + \xF0\xAE\x91\xA9 + \xF0\xAE\x91\xAA + \xF0\xAE\x91\xAB + \xF0\xAE\x91\xAC + \xF0\xAE\x91\xAD + \xF0\xAE\x91\xAE + \xF0\xAE\x91\xAF + \xF0\xAE\x91\xB0 + \xF0\xAE\x91\xB1 + \xF0\xAE\x91\xB2 + \xF0\xAE\x91\xB3 + \xF0\xAE\x91\xB4 + \xF0\xAE\x91\xB5 + \xF0\xAE\x91\xB6 + \xF0\xAE\x91\xB7 + \xF0\xAE\x91\xB8 + \xF0\xAE\x91\xB9 + \xF0\xAE\x91\xBA + \xF0\xAE\x91\xBB + \xF0\xAE\x91\xBC + \xF0\xAE\x91\xBD + \xF0\xAE\x91\xBE + \xF0\xAE\x91\xBF + \xF0\xAE\x92\x80 + \xF0\xAE\x92\x81 + \xF0\xAE\x92\x82 + \xF0\xAE\x92\x83 + \xF0\xAE\x92\x84 + \xF0\xAE\x92\x85 + \xF0\xAE\x92\x86 + \xF0\xAE\x92\x87 + \xF0\xAE\x92\x88 + \xF0\xAE\x92\x89 + \xF0\xAE\x92\x8A + \xF0\xAE\x92\x8B + \xF0\xAE\x92\x8C + \xF0\xAE\x92\x8D + \xF0\xAE\x92\x8E + \xF0\xAE\x92\x8F + \xF0\xAE\x92\x90 + \xF0\xAE\x92\x91 + \xF0\xAE\x92\x92 + \xF0\xAE\x92\x93 + \xF0\xAE\x92\x94 + \xF0\xAE\x92\x95 + \xF0\xAE\x92\x96 + \xF0\xAE\x92\x97 + \xF0\xAE\x92\x98 + \xF0\xAE\x92\x99 + \xF0\xAE\x92\x9A + \xF0\xAE\x92\x9B + \xF0\xAE\x92\x9C + \xF0\xAE\x92\x9D + \xF0\xAE\x92\x9E + \xF0\xAE\x92\x9F + \xF0\xAE\x92\xA0 + \xF0\xAE\x92\xA1 + \xF0\xAE\x92\xA2 + \xF0\xAE\x92\xA3 + \xF0\xAE\x92\xA4 + \xF0\xAE\x92\xA5 + \xF0\xAE\x92\xA6 + \xF0\xAE\x92\xA7 + \xF0\xAE\x92\xA8 + \xF0\xAE\x92\xA9 + \xF0\xAE\x92\xAA + \xF0\xAE\x92\xAB + \xF0\xAE\x92\xAC + \xF0\xAE\x92\xAD + \xF0\xAE\x92\xAE + \xF0\xAE\x92\xAF + \xF0\xAE\x92\xB0 + \xF0\xAE\x92\xB1 + \xF0\xAE\x92\xB2 + \xF0\xAE\x92\xB3 + \xF0\xAE\x92\xB4 + \xF0\xAE\x92\xB5 + \xF0\xAE\x92\xB6 + \xF0\xAE\x92\xB7 + \xF0\xAE\x92\xB8 + \xF0\xAE\x92\xB9 + \xF0\xAE\x92\xBA + \xF0\xAE\x92\xBB + \xF0\xAE\x92\xBC + \xF0\xAE\x92\xBD + \xF0\xAE\x92\xBE + \xF0\xAE\x92\xBF + \xF0\xAE\x93\x80 + \xF0\xAE\x93\x81 + \xF0\xAE\x93\x82 + \xF0\xAE\x93\x83 + \xF0\xAE\x93\x84 + \xF0\xAE\x93\x85 + \xF0\xAE\x93\x86 + \xF0\xAE\x93\x87 + \xF0\xAE\x93\x88 + \xF0\xAE\x93\x89 + \xF0\xAE\x93\x8A + \xF0\xAE\x93\x8B + \xF0\xAE\x93\x8C + \xF0\xAE\x93\x8D + \xF0\xAE\x93\x8E + \xF0\xAE\x93\x8F + \xF0\xAE\x93\x90 + \xF0\xAE\x93\x91 + \xF0\xAE\x93\x92 + \xF0\xAE\x93\x93 + \xF0\xAE\x93\x94 + \xF0\xAE\x93\x95 + \xF0\xAE\x93\x96 + \xF0\xAE\x93\x97 + \xF0\xAE\x93\x98 + \xF0\xAE\x93\x99 + \xF0\xAE\x93\x9A + \xF0\xAE\x93\x9B + \xF0\xAE\x93\x9C + \xF0\xAE\x93\x9D + \xF0\xAE\x93\x9E + \xF0\xAE\x93\x9F + \xF0\xAE\x93\xA0 + \xF0\xAE\x93\xA1 + \xF0\xAE\x93\xA2 + \xF0\xAE\x93\xA3 + \xF0\xAE\x93\xA4 + \xF0\xAE\x93\xA5 + \xF0\xAE\x93\xA6 + \xF0\xAE\x93\xA7 + \xF0\xAE\x93\xA8 + \xF0\xAE\x93\xA9 + \xF0\xAE\x93\xAA + \xF0\xAE\x93\xAB + \xF0\xAE\x93\xAC + \xF0\xAE\x93\xAD + \xF0\xAE\x93\xAE + \xF0\xAE\x93\xAF + \xF0\xAE\x93\xB0 + \xF0\xAE\x93\xB1 + \xF0\xAE\x93\xB2 + \xF0\xAE\x93\xB3 + \xF0\xAE\x93\xB4 + \xF0\xAE\x93\xB5 + \xF0\xAE\x93\xB6 + \xF0\xAE\x93\xB7 + \xF0\xAE\x93\xB8 + \xF0\xAE\x93\xB9 + \xF0\xAE\x93\xBA + \xF0\xAE\x93\xBB + \xF0\xAE\x93\xBC + \xF0\xAE\x93\xBD + \xF0\xAE\x93\xBE + \xF0\xAE\x93\xBF + \xF0\xAE\x94\x80 + \xF0\xAE\x94\x81 + \xF0\xAE\x94\x82 + \xF0\xAE\x94\x83 + \xF0\xAE\x94\x84 + \xF0\xAE\x94\x85 + \xF0\xAE\x94\x86 + \xF0\xAE\x94\x87 + \xF0\xAE\x94\x88 + \xF0\xAE\x94\x89 + \xF0\xAE\x94\x8A + \xF0\xAE\x94\x8B + \xF0\xAE\x94\x8C + \xF0\xAE\x94\x8D + \xF0\xAE\x94\x8E + \xF0\xAE\x94\x8F + \xF0\xAE\x94\x90 + \xF0\xAE\x94\x91 + \xF0\xAE\x94\x92 + \xF0\xAE\x94\x93 + \xF0\xAE\x94\x94 + \xF0\xAE\x94\x95 + \xF0\xAE\x94\x96 + \xF0\xAE\x94\x97 + \xF0\xAE\x94\x98 + \xF0\xAE\x94\x99 + \xF0\xAE\x94\x9A + \xF0\xAE\x94\x9B + \xF0\xAE\x94\x9C + \xF0\xAE\x94\x9D + \xF0\xAE\x94\x9E + \xF0\xAE\x94\x9F + \xF0\xAE\x94\xA0 + \xF0\xAE\x94\xA1 + \xF0\xAE\x94\xA2 + \xF0\xAE\x94\xA3 + \xF0\xAE\x94\xA4 + \xF0\xAE\x94\xA5 + \xF0\xAE\x94\xA6 + \xF0\xAE\x94\xA7 + \xF0\xAE\x94\xA8 + \xF0\xAE\x94\xA9 + \xF0\xAE\x94\xAA + \xF0\xAE\x94\xAB + \xF0\xAE\x94\xAC + \xF0\xAE\x94\xAD + \xF0\xAE\x94\xAE + \xF0\xAE\x94\xAF + \xF0\xAE\x94\xB0 + \xF0\xAE\x94\xB1 + \xF0\xAE\x94\xB2 + \xF0\xAE\x94\xB3 + \xF0\xAE\x94\xB4 + \xF0\xAE\x94\xB5 + \xF0\xAE\x94\xB6 + \xF0\xAE\x94\xB7 + \xF0\xAE\x94\xB8 + \xF0\xAE\x94\xB9 + \xF0\xAE\x94\xBA + \xF0\xAE\x94\xBB + \xF0\xAE\x94\xBC + \xF0\xAE\x94\xBD + \xF0\xAE\x94\xBE + \xF0\xAE\x94\xBF + \xF0\xAE\x95\x80 + \xF0\xAE\x95\x81 + \xF0\xAE\x95\x82 + \xF0\xAE\x95\x83 + \xF0\xAE\x95\x84 + \xF0\xAE\x95\x85 + \xF0\xAE\x95\x86 + \xF0\xAE\x95\x87 + \xF0\xAE\x95\x88 + \xF0\xAE\x95\x89 + \xF0\xAE\x95\x8A + \xF0\xAE\x95\x8B + \xF0\xAE\x95\x8C + \xF0\xAE\x95\x8D + \xF0\xAE\x95\x8E + \xF0\xAE\x95\x8F + \xF0\xAE\x95\x90 + \xF0\xAE\x95\x91 + \xF0\xAE\x95\x92 + \xF0\xAE\x95\x93 + \xF0\xAE\x95\x94 + \xF0\xAE\x95\x95 + \xF0\xAE\x95\x96 + \xF0\xAE\x95\x97 + \xF0\xAE\x95\x98 + \xF0\xAE\x95\x99 + \xF0\xAE\x95\x9A + \xF0\xAE\x95\x9B + \xF0\xAE\x95\x9C + \xF0\xAE\x95\x9D + \xF0\xAE\x95\x9E + \xF0\xAE\x95\x9F + \xF0\xAE\x95\xA0 + \xF0\xAE\x95\xA1 + \xF0\xAE\x95\xA2 + \xF0\xAE\x95\xA3 + \xF0\xAE\x95\xA4 + \xF0\xAE\x95\xA5 + \xF0\xAE\x95\xA6 + \xF0\xAE\x95\xA7 + \xF0\xAE\x95\xA8 + \xF0\xAE\x95\xA9 + \xF0\xAE\x95\xAA + \xF0\xAE\x95\xAB + \xF0\xAE\x95\xAC + \xF0\xAE\x95\xAD + \xF0\xAE\x95\xAE + \xF0\xAE\x95\xAF + \xF0\xAE\x95\xB0 + \xF0\xAE\x95\xB1 + \xF0\xAE\x95\xB2 + \xF0\xAE\x95\xB3 + \xF0\xAE\x95\xB4 + \xF0\xAE\x95\xB5 + \xF0\xAE\x95\xB6 + \xF0\xAE\x95\xB7 + \xF0\xAE\x95\xB8 + \xF0\xAE\x95\xB9 + \xF0\xAE\x95\xBA + \xF0\xAE\x95\xBB + \xF0\xAE\x95\xBC + \xF0\xAE\x95\xBD + \xF0\xAE\x95\xBE + \xF0\xAE\x95\xBF + \xF0\xAE\x96\x80 + \xF0\xAE\x96\x81 + \xF0\xAE\x96\x82 + \xF0\xAE\x96\x83 + \xF0\xAE\x96\x84 + \xF0\xAE\x96\x85 + \xF0\xAE\x96\x86 + \xF0\xAE\x96\x87 + \xF0\xAE\x96\x88 + \xF0\xAE\x96\x89 + \xF0\xAE\x96\x8A + \xF0\xAE\x96\x8B + \xF0\xAE\x96\x8C + \xF0\xAE\x96\x8D + \xF0\xAE\x96\x8E + \xF0\xAE\x96\x8F + \xF0\xAE\x96\x90 + \xF0\xAE\x96\x91 + \xF0\xAE\x96\x92 + \xF0\xAE\x96\x93 + \xF0\xAE\x96\x94 + \xF0\xAE\x96\x95 + \xF0\xAE\x96\x96 + \xF0\xAE\x96\x97 + \xF0\xAE\x96\x98 + \xF0\xAE\x96\x99 + \xF0\xAE\x96\x9A + \xF0\xAE\x96\x9B + \xF0\xAE\x96\x9C + \xF0\xAE\x96\x9D + \xF0\xAE\x96\x9E + \xF0\xAE\x96\x9F + \xF0\xAE\x96\xA0 + \xF0\xAE\x96\xA1 + \xF0\xAE\x96\xA2 + \xF0\xAE\x96\xA3 + \xF0\xAE\x96\xA4 + \xF0\xAE\x96\xA5 + \xF0\xAE\x96\xA6 + \xF0\xAE\x96\xA7 + \xF0\xAE\x96\xA8 + \xF0\xAE\x96\xA9 + \xF0\xAE\x96\xAA + \xF0\xAE\x96\xAB + \xF0\xAE\x96\xAC + \xF0\xAE\x96\xAD + \xF0\xAE\x96\xAE + \xF0\xAE\x96\xAF + \xF0\xAE\x96\xB0 + \xF0\xAE\x96\xB1 + \xF0\xAE\x96\xB2 + \xF0\xAE\x96\xB3 + \xF0\xAE\x96\xB4 + \xF0\xAE\x96\xB5 + \xF0\xAE\x96\xB6 + \xF0\xAE\x96\xB7 + \xF0\xAE\x96\xB8 + \xF0\xAE\x96\xB9 + \xF0\xAE\x96\xBA + \xF0\xAE\x96\xBB + \xF0\xAE\x96\xBC + \xF0\xAE\x96\xBD + \xF0\xAE\x96\xBE + \xF0\xAE\x96\xBF + \xF0\xAE\x97\x80 + \xF0\xAE\x97\x81 + \xF0\xAE\x97\x82 + \xF0\xAE\x97\x83 + \xF0\xAE\x97\x84 + \xF0\xAE\x97\x85 + \xF0\xAE\x97\x86 + \xF0\xAE\x97\x87 + \xF0\xAE\x97\x88 + \xF0\xAE\x97\x89 + \xF0\xAE\x97\x8A + \xF0\xAE\x97\x8B + \xF0\xAE\x97\x8C + \xF0\xAE\x97\x8D + \xF0\xAE\x97\x8E + \xF0\xAE\x97\x8F + \xF0\xAE\x97\x90 + \xF0\xAE\x97\x91 + \xF0\xAE\x97\x92 + \xF0\xAE\x97\x93 + \xF0\xAE\x97\x94 + \xF0\xAE\x97\x95 + \xF0\xAE\x97\x96 + \xF0\xAE\x97\x97 + \xF0\xAE\x97\x98 + \xF0\xAE\x97\x99 + \xF0\xAE\x97\x9A + \xF0\xAE\x97\x9B + \xF0\xAE\x97\x9C + \xF0\xAE\x97\x9D + \xF0\xAE\x97\x9E + \xF0\xAE\x97\x9F + \xF0\xAE\x97\xA0 + \xF0\xAE\x97\xA1 + \xF0\xAE\x97\xA2 + \xF0\xAE\x97\xA3 + \xF0\xAE\x97\xA4 + \xF0\xAE\x97\xA5 + \xF0\xAE\x97\xA6 + \xF0\xAE\x97\xA7 + \xF0\xAE\x97\xA8 + \xF0\xAE\x97\xA9 + \xF0\xAE\x97\xAA + \xF0\xAE\x97\xAB + \xF0\xAE\x97\xAC + \xF0\xAE\x97\xAD + \xF0\xAE\x97\xAE + \xF0\xAE\x97\xAF + \xF0\xAE\x97\xB0 + \xF0\xAE\x97\xB1 + \xF0\xAE\x97\xB2 + \xF0\xAE\x97\xB3 + \xF0\xAE\x97\xB4 + \xF0\xAE\x97\xB5 + \xF0\xAE\x97\xB6 + \xF0\xAE\x97\xB7 + \xF0\xAE\x97\xB8 + \xF0\xAE\x97\xB9 + \xF0\xAE\x97\xBA + \xF0\xAE\x97\xBB + \xF0\xAE\x97\xBC + \xF0\xAE\x97\xBD + \xF0\xAE\x97\xBE + \xF0\xAE\x97\xBF + \xF0\xAE\x98\x80 + \xF0\xAE\x98\x81 + \xF0\xAE\x98\x82 + \xF0\xAE\x98\x83 + \xF0\xAE\x98\x84 + \xF0\xAE\x98\x85 + \xF0\xAE\x98\x86 + \xF0\xAE\x98\x87 + \xF0\xAE\x98\x88 + \xF0\xAE\x98\x89 + \xF0\xAE\x98\x8A + \xF0\xAE\x98\x8B + \xF0\xAE\x98\x8C + \xF0\xAE\x98\x8D + \xF0\xAE\x98\x8E + \xF0\xAE\x98\x8F + \xF0\xAE\x98\x90 + \xF0\xAE\x98\x91 + \xF0\xAE\x98\x92 + \xF0\xAE\x98\x93 + \xF0\xAE\x98\x94 + \xF0\xAE\x98\x95 + \xF0\xAE\x98\x96 + \xF0\xAE\x98\x97 + \xF0\xAE\x98\x98 + \xF0\xAE\x98\x99 + \xF0\xAE\x98\x9A + \xF0\xAE\x98\x9B + \xF0\xAE\x98\x9C + \xF0\xAE\x98\x9D + \xF0\xAE\x98\x9E + \xF0\xAE\x98\x9F + \xF0\xAE\x98\xA0 + \xF0\xAE\x98\xA1 + \xF0\xAE\x98\xA2 + \xF0\xAE\x98\xA3 + \xF0\xAE\x98\xA4 + \xF0\xAE\x98\xA5 + \xF0\xAE\x98\xA6 + \xF0\xAE\x98\xA7 + \xF0\xAE\x98\xA8 + \xF0\xAE\x98\xA9 + \xF0\xAE\x98\xAA + \xF0\xAE\x98\xAB + \xF0\xAE\x98\xAC + \xF0\xAE\x98\xAD + \xF0\xAE\x98\xAE + \xF0\xAE\x98\xAF + \xF0\xAE\x98\xB0 + \xF0\xAE\x98\xB1 + \xF0\xAE\x98\xB2 + \xF0\xAE\x98\xB3 + \xF0\xAE\x98\xB4 + \xF0\xAE\x98\xB5 + \xF0\xAE\x98\xB6 + \xF0\xAE\x98\xB7 + \xF0\xAE\x98\xB8 + \xF0\xAE\x98\xB9 + \xF0\xAE\x98\xBA + \xF0\xAE\x98\xBB + \xF0\xAE\x98\xBC + \xF0\xAE\x98\xBD + \xF0\xAE\x98\xBE + \xF0\xAE\x98\xBF + \xF0\xAE\x99\x80 + \xF0\xAE\x99\x81 + \xF0\xAE\x99\x82 + \xF0\xAE\x99\x83 + \xF0\xAE\x99\x84 + \xF0\xAE\x99\x85 + \xF0\xAE\x99\x86 + \xF0\xAE\x99\x87 + \xF0\xAE\x99\x88 + \xF0\xAE\x99\x89 + \xF0\xAE\x99\x8A + \xF0\xAE\x99\x8B + \xF0\xAE\x99\x8C + \xF0\xAE\x99\x8D + \xF0\xAE\x99\x8E + \xF0\xAE\x99\x8F + \xF0\xAE\x99\x90 + \xF0\xAE\x99\x91 + \xF0\xAE\x99\x92 + \xF0\xAE\x99\x93 + \xF0\xAE\x99\x94 + \xF0\xAE\x99\x95 + \xF0\xAE\x99\x96 + \xF0\xAE\x99\x97 + \xF0\xAE\x99\x98 + \xF0\xAE\x99\x99 + \xF0\xAE\x99\x9A + \xF0\xAE\x99\x9B + \xF0\xAE\x99\x9C + \xF0\xAE\x99\x9D + \xF0\xAE\x99\x9E + \xF0\xAE\x99\x9F + \xF0\xAE\x99\xA0 + \xF0\xAE\x99\xA1 + \xF0\xAE\x99\xA2 + \xF0\xAE\x99\xA3 + \xF0\xAE\x99\xA4 + \xF0\xAE\x99\xA5 + \xF0\xAE\x99\xA6 + \xF0\xAE\x99\xA7 + \xF0\xAE\x99\xA8 + \xF0\xAE\x99\xA9 + \xF0\xAE\x99\xAA + \xF0\xAE\x99\xAB + \xF0\xAE\x99\xAC + \xF0\xAE\x99\xAD + \xF0\xAE\x99\xAE + \xF0\xAE\x99\xAF + \xF0\xAE\x99\xB0 + \xF0\xAE\x99\xB1 + \xF0\xAE\x99\xB2 + \xF0\xAE\x99\xB3 + \xF0\xAE\x99\xB4 + \xF0\xAE\x99\xB5 + \xF0\xAE\x99\xB6 + \xF0\xAE\x99\xB7 + \xF0\xAE\x99\xB8 + \xF0\xAE\x99\xB9 + \xF0\xAE\x99\xBA + \xF0\xAE\x99\xBB + \xF0\xAE\x99\xBC + \xF0\xAE\x99\xBD + \xF0\xAE\x99\xBE + \xF0\xAE\x99\xBF + \xF0\xAE\x9A\x80 + \xF0\xAE\x9A\x81 + \xF0\xAE\x9A\x82 + \xF0\xAE\x9A\x83 + \xF0\xAE\x9A\x84 + \xF0\xAE\x9A\x85 + \xF0\xAE\x9A\x86 + \xF0\xAE\x9A\x87 + \xF0\xAE\x9A\x88 + \xF0\xAE\x9A\x89 + \xF0\xAE\x9A\x8A + \xF0\xAE\x9A\x8B + \xF0\xAE\x9A\x8C + \xF0\xAE\x9A\x8D + \xF0\xAE\x9A\x8E + \xF0\xAE\x9A\x8F + \xF0\xAE\x9A\x90 + \xF0\xAE\x9A\x91 + \xF0\xAE\x9A\x92 + \xF0\xAE\x9A\x93 + \xF0\xAE\x9A\x94 + \xF0\xAE\x9A\x95 + \xF0\xAE\x9A\x96 + \xF0\xAE\x9A\x97 + \xF0\xAE\x9A\x98 + \xF0\xAE\x9A\x99 + \xF0\xAE\x9A\x9A + \xF0\xAE\x9A\x9B + \xF0\xAE\x9A\x9C + \xF0\xAE\x9A\x9D + \xF0\xAE\x9A\x9E + \xF0\xAE\x9A\x9F + \xF0\xAE\x9A\xA0 + \xF0\xAE\x9A\xA1 + \xF0\xAE\x9A\xA2 + \xF0\xAE\x9A\xA3 + \xF0\xAE\x9A\xA4 + \xF0\xAE\x9A\xA5 + \xF0\xAE\x9A\xA6 + \xF0\xAE\x9A\xA7 + \xF0\xAE\x9A\xA8 + \xF0\xAE\x9A\xA9 + \xF0\xAE\x9A\xAA + \xF0\xAE\x9A\xAB + \xF0\xAE\x9A\xAC + \xF0\xAE\x9A\xAD + \xF0\xAE\x9A\xAE + \xF0\xAE\x9A\xAF + \xF0\xAE\x9A\xB0 + \xF0\xAE\x9A\xB1 + \xF0\xAE\x9A\xB2 + \xF0\xAE\x9A\xB3 + \xF0\xAE\x9A\xB4 + \xF0\xAE\x9A\xB5 + \xF0\xAE\x9A\xB6 + \xF0\xAE\x9A\xB7 + \xF0\xAE\x9A\xB8 + \xF0\xAE\x9A\xB9 + \xF0\xAE\x9A\xBA + \xF0\xAE\x9A\xBB + \xF0\xAE\x9A\xBC + \xF0\xAE\x9A\xBD + \xF0\xAE\x9A\xBE + \xF0\xAE\x9A\xBF + \xF0\xAE\x9B\x80 + \xF0\xAE\x9B\x81 + \xF0\xAE\x9B\x82 + \xF0\xAE\x9B\x83 + \xF0\xAE\x9B\x84 + \xF0\xAE\x9B\x85 + \xF0\xAE\x9B\x86 + \xF0\xAE\x9B\x87 + \xF0\xAE\x9B\x88 + \xF0\xAE\x9B\x89 + \xF0\xAE\x9B\x8A + \xF0\xAE\x9B\x8B + \xF0\xAE\x9B\x8C + \xF0\xAE\x9B\x8D + \xF0\xAE\x9B\x8E + \xF0\xAE\x9B\x8F + \xF0\xAE\x9B\x90 + \xF0\xAE\x9B\x91 + \xF0\xAE\x9B\x92 + \xF0\xAE\x9B\x93 + \xF0\xAE\x9B\x94 + \xF0\xAE\x9B\x95 + \xF0\xAE\x9B\x96 + \xF0\xAE\x9B\x97 + \xF0\xAE\x9B\x98 + \xF0\xAE\x9B\x99 + \xF0\xAE\x9B\x9A + \xF0\xAE\x9B\x9B + \xF0\xAE\x9B\x9C + \xF0\xAE\x9B\x9D + \xF0\xAE\x9B\x9E + \xF0\xAE\x9B\x9F + \xF0\xAE\x9B\xA0 + \xF0\xAE\x9B\xA1 + \xF0\xAE\x9B\xA2 + \xF0\xAE\x9B\xA3 + \xF0\xAE\x9B\xA4 + \xF0\xAE\x9B\xA5 + \xF0\xAE\x9B\xA6 + \xF0\xAE\x9B\xA7 + \xF0\xAE\x9B\xA8 + \xF0\xAE\x9B\xA9 + \xF0\xAE\x9B\xAA + \xF0\xAE\x9B\xAB + \xF0\xAE\x9B\xAC + \xF0\xAE\x9B\xAD + \xF0\xAE\x9B\xAE + \xF0\xAE\x9B\xAF + \xF0\xAE\x9B\xB0 + \xF0\xAE\x9B\xB1 + \xF0\xAE\x9B\xB2 + \xF0\xAE\x9B\xB3 + \xF0\xAE\x9B\xB4 + \xF0\xAE\x9B\xB5 + \xF0\xAE\x9B\xB6 + \xF0\xAE\x9B\xB7 + \xF0\xAE\x9B\xB8 + \xF0\xAE\x9B\xB9 + \xF0\xAE\x9B\xBA + \xF0\xAE\x9B\xBB + \xF0\xAE\x9B\xBC + \xF0\xAE\x9B\xBD + \xF0\xAE\x9B\xBE + \xF0\xAE\x9B\xBF + \xF0\xAE\x9C\x80 + \xF0\xAE\x9C\x81 + \xF0\xAE\x9C\x82 + \xF0\xAE\x9C\x83 + \xF0\xAE\x9C\x84 + \xF0\xAE\x9C\x85 + \xF0\xAE\x9C\x86 + \xF0\xAE\x9C\x87 + \xF0\xAE\x9C\x88 + \xF0\xAE\x9C\x89 + \xF0\xAE\x9C\x8A + \xF0\xAE\x9C\x8B + \xF0\xAE\x9C\x8C + \xF0\xAE\x9C\x8D + \xF0\xAE\x9C\x8E + \xF0\xAE\x9C\x8F + \xF0\xAE\x9C\x90 + \xF0\xAE\x9C\x91 + \xF0\xAE\x9C\x92 + \xF0\xAE\x9C\x93 + \xF0\xAE\x9C\x94 + \xF0\xAE\x9C\x95 + \xF0\xAE\x9C\x96 + \xF0\xAE\x9C\x97 + \xF0\xAE\x9C\x98 + \xF0\xAE\x9C\x99 + \xF0\xAE\x9C\x9A + \xF0\xAE\x9C\x9B + \xF0\xAE\x9C\x9C + \xF0\xAE\x9C\x9D + \xF0\xAE\x9C\x9E + \xF0\xAE\x9C\x9F + \xF0\xAE\x9C\xA0 + \xF0\xAE\x9C\xA1 + \xF0\xAE\x9C\xA2 + \xF0\xAE\x9C\xA3 + \xF0\xAE\x9C\xA4 + \xF0\xAE\x9C\xA5 + \xF0\xAE\x9C\xA6 + \xF0\xAE\x9C\xA7 + \xF0\xAE\x9C\xA8 + \xF0\xAE\x9C\xA9 + \xF0\xAE\x9C\xAA + \xF0\xAE\x9C\xAB + \xF0\xAE\x9C\xAC + \xF0\xAE\x9C\xAD + \xF0\xAE\x9C\xAE + \xF0\xAE\x9C\xAF + \xF0\xAE\x9C\xB0 + \xF0\xAE\x9C\xB1 + \xF0\xAE\x9C\xB2 + \xF0\xAE\x9C\xB3 + \xF0\xAE\x9C\xB4 + \xF0\xAE\x9C\xB5 + \xF0\xAE\x9C\xB6 + \xF0\xAE\x9C\xB7 + \xF0\xAE\x9C\xB8 + \xF0\xAE\x9C\xB9 + \xF0\xAE\x9C\xBA + \xF0\xAE\x9C\xBB + \xF0\xAE\x9C\xBC + \xF0\xAE\x9C\xBD + \xF0\xAE\x9C\xBE + \xF0\xAE\x9C\xBF + \xF0\xAE\x9D\x80 + \xF0\xAE\x9D\x81 + \xF0\xAE\x9D\x82 + \xF0\xAE\x9D\x83 + \xF0\xAE\x9D\x84 + \xF0\xAE\x9D\x85 + \xF0\xAE\x9D\x86 + \xF0\xAE\x9D\x87 + \xF0\xAE\x9D\x88 + \xF0\xAE\x9D\x89 + \xF0\xAE\x9D\x8A + \xF0\xAE\x9D\x8B + \xF0\xAE\x9D\x8C + \xF0\xAE\x9D\x8D + \xF0\xAE\x9D\x8E + \xF0\xAE\x9D\x8F + \xF0\xAE\x9D\x90 + \xF0\xAE\x9D\x91 + \xF0\xAE\x9D\x92 + \xF0\xAE\x9D\x93 + \xF0\xAE\x9D\x94 + \xF0\xAE\x9D\x95 + \xF0\xAE\x9D\x96 + \xF0\xAE\x9D\x97 + \xF0\xAE\x9D\x98 + \xF0\xAE\x9D\x99 + \xF0\xAE\x9D\x9A + \xF0\xAE\x9D\x9B + \xF0\xAE\x9D\x9C + \xF0\xAE\x9D\x9D + \xF0\xAE\x9D\x9E + \xF0\xAE\x9D\x9F + \xF0\xAE\x9D\xA0 + \xF0\xAE\x9D\xA1 + \xF0\xAE\x9D\xA2 + \xF0\xAE\x9D\xA3 + \xF0\xAE\x9D\xA4 + \xF0\xAE\x9D\xA5 + \xF0\xAE\x9D\xA6 + \xF0\xAE\x9D\xA7 + \xF0\xAE\x9D\xA8 + \xF0\xAE\x9D\xA9 + \xF0\xAE\x9D\xAA + \xF0\xAE\x9D\xAB + \xF0\xAE\x9D\xAC + \xF0\xAE\x9D\xAD + \xF0\xAE\x9D\xAE + \xF0\xAE\x9D\xAF + \xF0\xAE\x9D\xB0 + \xF0\xAE\x9D\xB1 + \xF0\xAE\x9D\xB2 + \xF0\xAE\x9D\xB3 + \xF0\xAE\x9D\xB4 + \xF0\xAE\x9D\xB5 + \xF0\xAE\x9D\xB6 + \xF0\xAE\x9D\xB7 + \xF0\xAE\x9D\xB8 + \xF0\xAE\x9D\xB9 + \xF0\xAE\x9D\xBA + \xF0\xAE\x9D\xBB + \xF0\xAE\x9D\xBC + \xF0\xAE\x9D\xBD + \xF0\xAE\x9D\xBE + \xF0\xAE\x9D\xBF + \xF0\xAE\x9E\x80 + \xF0\xAE\x9E\x81 + \xF0\xAE\x9E\x82 + \xF0\xAE\x9E\x83 + \xF0\xAE\x9E\x84 + \xF0\xAE\x9E\x85 + \xF0\xAE\x9E\x86 + \xF0\xAE\x9E\x87 + \xF0\xAE\x9E\x88 + \xF0\xAE\x9E\x89 + \xF0\xAE\x9E\x8A + \xF0\xAE\x9E\x8B + \xF0\xAE\x9E\x8C + \xF0\xAE\x9E\x8D + \xF0\xAE\x9E\x8E + \xF0\xAE\x9E\x8F + \xF0\xAE\x9E\x90 + \xF0\xAE\x9E\x91 + \xF0\xAE\x9E\x92 + \xF0\xAE\x9E\x93 + \xF0\xAE\x9E\x94 + \xF0\xAE\x9E\x95 + \xF0\xAE\x9E\x96 + \xF0\xAE\x9E\x97 + \xF0\xAE\x9E\x98 + \xF0\xAE\x9E\x99 + \xF0\xAE\x9E\x9A + \xF0\xAE\x9E\x9B + \xF0\xAE\x9E\x9C + \xF0\xAE\x9E\x9D + \xF0\xAE\x9E\x9E + \xF0\xAE\x9E\x9F + \xF0\xAE\x9E\xA0 + \xF0\xAE\x9E\xA1 + \xF0\xAE\x9E\xA2 + \xF0\xAE\x9E\xA3 + \xF0\xAE\x9E\xA4 + \xF0\xAE\x9E\xA5 + \xF0\xAE\x9E\xA6 + \xF0\xAE\x9E\xA7 + \xF0\xAE\x9E\xA8 + \xF0\xAE\x9E\xA9 + \xF0\xAE\x9E\xAA + \xF0\xAE\x9E\xAB + \xF0\xAE\x9E\xAC + \xF0\xAE\x9E\xAD + \xF0\xAE\x9E\xAE + \xF0\xAE\x9E\xAF + \xF0\xAE\x9E\xB0 + \xF0\xAE\x9E\xB1 + \xF0\xAE\x9E\xB2 + \xF0\xAE\x9E\xB3 + \xF0\xAE\x9E\xB4 + \xF0\xAE\x9E\xB5 + \xF0\xAE\x9E\xB6 + \xF0\xAE\x9E\xB7 + \xF0\xAE\x9E\xB8 + \xF0\xAE\x9E\xB9 + \xF0\xAE\x9E\xBA + \xF0\xAE\x9E\xBB + \xF0\xAE\x9E\xBC + \xF0\xAE\x9E\xBD + \xF0\xAE\x9E\xBE + \xF0\xAE\x9E\xBF + \xF0\xAE\x9F\x80 + \xF0\xAE\x9F\x81 + \xF0\xAE\x9F\x82 + \xF0\xAE\x9F\x83 + \xF0\xAE\x9F\x84 + \xF0\xAE\x9F\x85 + \xF0\xAE\x9F\x86 + \xF0\xAE\x9F\x87 + \xF0\xAE\x9F\x88 + \xF0\xAE\x9F\x89 + \xF0\xAE\x9F\x8A + \xF0\xAE\x9F\x8B + \xF0\xAE\x9F\x8C + \xF0\xAE\x9F\x8D + \xF0\xAE\x9F\x8E + \xF0\xAE\x9F\x8F + \xF0\xAE\x9F\x90 + \xF0\xAE\x9F\x91 + \xF0\xAE\x9F\x92 + \xF0\xAE\x9F\x93 + \xF0\xAE\x9F\x94 + \xF0\xAE\x9F\x95 + \xF0\xAE\x9F\x96 + \xF0\xAE\x9F\x97 + \xF0\xAE\x9F\x98 + \xF0\xAE\x9F\x99 + \xF0\xAE\x9F\x9A + \xF0\xAE\x9F\x9B + \xF0\xAE\x9F\x9C + \xF0\xAE\x9F\x9D + \xF0\xAE\x9F\x9E + \xF0\xAE\x9F\x9F + \xF0\xAE\x9F\xA0 + \xF0\xAE\x9F\xA1 + \xF0\xAE\x9F\xA2 + \xF0\xAE\x9F\xA3 + \xF0\xAE\x9F\xA4 + \xF0\xAE\x9F\xA5 + \xF0\xAE\x9F\xA6 + \xF0\xAE\x9F\xA7 + \xF0\xAE\x9F\xA8 + \xF0\xAE\x9F\xA9 + \xF0\xAE\x9F\xAA + \xF0\xAE\x9F\xAB + \xF0\xAE\x9F\xAC + \xF0\xAE\x9F\xAD + \xF0\xAE\x9F\xAE + \xF0\xAE\x9F\xAF + \xF0\xAE\x9F\xB0 + \xF0\xAE\x9F\xB1 + \xF0\xAE\x9F\xB2 + \xF0\xAE\x9F\xB3 + \xF0\xAE\x9F\xB4 + \xF0\xAE\x9F\xB5 + \xF0\xAE\x9F\xB6 + \xF0\xAE\x9F\xB7 + \xF0\xAE\x9F\xB8 + \xF0\xAE\x9F\xB9 + \xF0\xAE\x9F\xBA + \xF0\xAE\x9F\xBB + \xF0\xAE\x9F\xBC + \xF0\xAE\x9F\xBD + \xF0\xAE\x9F\xBE + \xF0\xAE\x9F\xBF + \xF0\xAE\xA0\x80 + \xF0\xAE\xA0\x81 + \xF0\xAE\xA0\x82 + \xF0\xAE\xA0\x83 + \xF0\xAE\xA0\x84 + \xF0\xAE\xA0\x85 + \xF0\xAE\xA0\x86 + \xF0\xAE\xA0\x87 + \xF0\xAE\xA0\x88 + \xF0\xAE\xA0\x89 + \xF0\xAE\xA0\x8A + \xF0\xAE\xA0\x8B + \xF0\xAE\xA0\x8C + \xF0\xAE\xA0\x8D + \xF0\xAE\xA0\x8E + \xF0\xAE\xA0\x8F + \xF0\xAE\xA0\x90 + \xF0\xAE\xA0\x91 + \xF0\xAE\xA0\x92 + \xF0\xAE\xA0\x93 + \xF0\xAE\xA0\x94 + \xF0\xAE\xA0\x95 + \xF0\xAE\xA0\x96 + \xF0\xAE\xA0\x97 + \xF0\xAE\xA0\x98 + \xF0\xAE\xA0\x99 + \xF0\xAE\xA0\x9A + \xF0\xAE\xA0\x9B + \xF0\xAE\xA0\x9C + \xF0\xAE\xA0\x9D + \xF0\xAE\xA0\x9E + \xF0\xAE\xA0\x9F + \xF0\xAE\xA0\xA0 + \xF0\xAE\xA0\xA1 + \xF0\xAE\xA0\xA2 + \xF0\xAE\xA0\xA3 + \xF0\xAE\xA0\xA4 + \xF0\xAE\xA0\xA5 + \xF0\xAE\xA0\xA6 + \xF0\xAE\xA0\xA7 + \xF0\xAE\xA0\xA8 + \xF0\xAE\xA0\xA9 + \xF0\xAE\xA0\xAA + \xF0\xAE\xA0\xAB + \xF0\xAE\xA0\xAC + \xF0\xAE\xA0\xAD + \xF0\xAE\xA0\xAE + \xF0\xAE\xA0\xAF + \xF0\xAE\xA0\xB0 + \xF0\xAE\xA0\xB1 + \xF0\xAE\xA0\xB2 + \xF0\xAE\xA0\xB3 + \xF0\xAE\xA0\xB4 + \xF0\xAE\xA0\xB5 + \xF0\xAE\xA0\xB6 + \xF0\xAE\xA0\xB7 + \xF0\xAE\xA0\xB8 + \xF0\xAE\xA0\xB9 + \xF0\xAE\xA0\xBA + \xF0\xAE\xA0\xBB + \xF0\xAE\xA0\xBC + \xF0\xAE\xA0\xBD + \xF0\xAE\xA0\xBE + \xF0\xAE\xA0\xBF + \xF0\xAE\xA1\x80 + \xF0\xAE\xA1\x81 + \xF0\xAE\xA1\x82 + \xF0\xAE\xA1\x83 + \xF0\xAE\xA1\x84 + \xF0\xAE\xA1\x85 + \xF0\xAE\xA1\x86 + \xF0\xAE\xA1\x87 + \xF0\xAE\xA1\x88 + \xF0\xAE\xA1\x89 + \xF0\xAE\xA1\x8A + \xF0\xAE\xA1\x8B + \xF0\xAE\xA1\x8C + \xF0\xAE\xA1\x8D + \xF0\xAE\xA1\x8E + \xF0\xAE\xA1\x8F + \xF0\xAE\xA1\x90 + \xF0\xAE\xA1\x91 + \xF0\xAE\xA1\x92 + \xF0\xAE\xA1\x93 + \xF0\xAE\xA1\x94 + \xF0\xAE\xA1\x95 + \xF0\xAE\xA1\x96 + \xF0\xAE\xA1\x97 + \xF0\xAE\xA1\x98 + \xF0\xAE\xA1\x99 + \xF0\xAE\xA1\x9A + \xF0\xAE\xA1\x9B + \xF0\xAE\xA1\x9C + \xF0\xAE\xA1\x9D + \xF0\xAE\xA1\x9E + \xF0\xAE\xA1\x9F + \xF0\xAE\xA1\xA0 + \xF0\xAE\xA1\xA1 + \xF0\xAE\xA1\xA2 + \xF0\xAE\xA1\xA3 + \xF0\xAE\xA1\xA4 + \xF0\xAE\xA1\xA5 + \xF0\xAE\xA1\xA6 + \xF0\xAE\xA1\xA7 + \xF0\xAE\xA1\xA8 + \xF0\xAE\xA1\xA9 + \xF0\xAE\xA1\xAA + \xF0\xAE\xA1\xAB + \xF0\xAE\xA1\xAC + \xF0\xAE\xA1\xAD + \xF0\xAE\xA1\xAE + \xF0\xAE\xA1\xAF + \xF0\xAE\xA1\xB0 + \xF0\xAE\xA1\xB1 + \xF0\xAE\xA1\xB2 + \xF0\xAE\xA1\xB3 + \xF0\xAE\xA1\xB4 + \xF0\xAE\xA1\xB5 + \xF0\xAE\xA1\xB6 + \xF0\xAE\xA1\xB7 + \xF0\xAE\xA1\xB8 + \xF0\xAE\xA1\xB9 + \xF0\xAE\xA1\xBA + \xF0\xAE\xA1\xBB + \xF0\xAE\xA1\xBC + \xF0\xAE\xA1\xBD + \xF0\xAE\xA1\xBE + \xF0\xAE\xA1\xBF + \xF0\xAE\xA2\x80 + \xF0\xAE\xA2\x81 + \xF0\xAE\xA2\x82 + \xF0\xAE\xA2\x83 + \xF0\xAE\xA2\x84 + \xF0\xAE\xA2\x85 + \xF0\xAE\xA2\x86 + \xF0\xAE\xA2\x87 + \xF0\xAE\xA2\x88 + \xF0\xAE\xA2\x89 + \xF0\xAE\xA2\x8A + \xF0\xAE\xA2\x8B + \xF0\xAE\xA2\x8C + \xF0\xAE\xA2\x8D + \xF0\xAE\xA2\x8E + \xF0\xAE\xA2\x8F + \xF0\xAE\xA2\x90 + \xF0\xAE\xA2\x91 + \xF0\xAE\xA2\x92 + \xF0\xAE\xA2\x93 + \xF0\xAE\xA2\x94 + \xF0\xAE\xA2\x95 + \xF0\xAE\xA2\x96 + \xF0\xAE\xA2\x97 + \xF0\xAE\xA2\x98 + \xF0\xAE\xA2\x99 + \xF0\xAE\xA2\x9A + \xF0\xAE\xA2\x9B + \xF0\xAE\xA2\x9C + \xF0\xAE\xA2\x9D + \xF0\xAE\xA2\x9E + \xF0\xAE\xA2\x9F + \xF0\xAE\xA2\xA0 + \xF0\xAE\xA2\xA1 + \xF0\xAE\xA2\xA2 + \xF0\xAE\xA2\xA3 + \xF0\xAE\xA2\xA4 + \xF0\xAE\xA2\xA5 + \xF0\xAE\xA2\xA6 + \xF0\xAE\xA2\xA7 + \xF0\xAE\xA2\xA8 + \xF0\xAE\xA2\xA9 + \xF0\xAE\xA2\xAA + \xF0\xAE\xA2\xAB + \xF0\xAE\xA2\xAC + \xF0\xAE\xA2\xAD + \xF0\xAE\xA2\xAE + \xF0\xAE\xA2\xAF + \xF0\xAE\xA2\xB0 + \xF0\xAE\xA2\xB1 + \xF0\xAE\xA2\xB2 + \xF0\xAE\xA2\xB3 + \xF0\xAE\xA2\xB4 + \xF0\xAE\xA2\xB5 + \xF0\xAE\xA2\xB6 + \xF0\xAE\xA2\xB7 + \xF0\xAE\xA2\xB8 + \xF0\xAE\xA2\xB9 + \xF0\xAE\xA2\xBA + \xF0\xAE\xA2\xBB + \xF0\xAE\xA2\xBC + \xF0\xAE\xA2\xBD + \xF0\xAE\xA2\xBE + \xF0\xAE\xA2\xBF + \xF0\xAE\xA3\x80 + \xF0\xAE\xA3\x81 + \xF0\xAE\xA3\x82 + \xF0\xAE\xA3\x83 + \xF0\xAE\xA3\x84 + \xF0\xAE\xA3\x85 + \xF0\xAE\xA3\x86 + \xF0\xAE\xA3\x87 + \xF0\xAE\xA3\x88 + \xF0\xAE\xA3\x89 + \xF0\xAE\xA3\x8A + \xF0\xAE\xA3\x8B + \xF0\xAE\xA3\x8C + \xF0\xAE\xA3\x8D + \xF0\xAE\xA3\x8E + \xF0\xAE\xA3\x8F + \xF0\xAE\xA3\x90 + \xF0\xAE\xA3\x91 + \xF0\xAE\xA3\x92 + \xF0\xAE\xA3\x93 + \xF0\xAE\xA3\x94 + \xF0\xAE\xA3\x95 + \xF0\xAE\xA3\x96 + \xF0\xAE\xA3\x97 + \xF0\xAE\xA3\x98 + \xF0\xAE\xA3\x99 + \xF0\xAE\xA3\x9A + \xF0\xAE\xA3\x9B + \xF0\xAE\xA3\x9C + \xF0\xAE\xA3\x9D + \xF0\xAE\xA3\x9E + \xF0\xAE\xA3\x9F + \xF0\xAE\xA3\xA0 + \xF0\xAE\xA3\xA1 + \xF0\xAE\xA3\xA2 + \xF0\xAE\xA3\xA3 + \xF0\xAE\xA3\xA4 + \xF0\xAE\xA3\xA5 + \xF0\xAE\xA3\xA6 + \xF0\xAE\xA3\xA7 + \xF0\xAE\xA3\xA8 + \xF0\xAE\xA3\xA9 + \xF0\xAE\xA3\xAA + \xF0\xAE\xA3\xAB + \xF0\xAE\xA3\xAC + \xF0\xAE\xA3\xAD + \xF0\xAE\xA3\xAE + \xF0\xAE\xA3\xAF + \xF0\xAE\xA3\xB0 + \xF0\xAE\xA3\xB1 + \xF0\xAE\xA3\xB2 + \xF0\xAE\xA3\xB3 + \xF0\xAE\xA3\xB4 + \xF0\xAE\xA3\xB5 + \xF0\xAE\xA3\xB6 + \xF0\xAE\xA3\xB7 + \xF0\xAE\xA3\xB8 + \xF0\xAE\xA3\xB9 + \xF0\xAE\xA3\xBA + \xF0\xAE\xA3\xBB + \xF0\xAE\xA3\xBC + \xF0\xAE\xA3\xBD + \xF0\xAE\xA3\xBE + \xF0\xAE\xA3\xBF + \xF0\xAE\xA4\x80 + \xF0\xAE\xA4\x81 + \xF0\xAE\xA4\x82 + \xF0\xAE\xA4\x83 + \xF0\xAE\xA4\x84 + \xF0\xAE\xA4\x85 + \xF0\xAE\xA4\x86 + \xF0\xAE\xA4\x87 + \xF0\xAE\xA4\x88 + \xF0\xAE\xA4\x89 + \xF0\xAE\xA4\x8A + \xF0\xAE\xA4\x8B + \xF0\xAE\xA4\x8C + \xF0\xAE\xA4\x8D + \xF0\xAE\xA4\x8E + \xF0\xAE\xA4\x8F + \xF0\xAE\xA4\x90 + \xF0\xAE\xA4\x91 + \xF0\xAE\xA4\x92 + \xF0\xAE\xA4\x93 + \xF0\xAE\xA4\x94 + \xF0\xAE\xA4\x95 + \xF0\xAE\xA4\x96 + \xF0\xAE\xA4\x97 + \xF0\xAE\xA4\x98 + \xF0\xAE\xA4\x99 + \xF0\xAE\xA4\x9A + \xF0\xAE\xA4\x9B + \xF0\xAE\xA4\x9C + \xF0\xAE\xA4\x9D + \xF0\xAE\xA4\x9E + \xF0\xAE\xA4\x9F + \xF0\xAE\xA4\xA0 + \xF0\xAE\xA4\xA1 + \xF0\xAE\xA4\xA2 + \xF0\xAE\xA4\xA3 + \xF0\xAE\xA4\xA4 + \xF0\xAE\xA4\xA5 + \xF0\xAE\xA4\xA6 + \xF0\xAE\xA4\xA7 + \xF0\xAE\xA4\xA8 + \xF0\xAE\xA4\xA9 + \xF0\xAE\xA4\xAA + \xF0\xAE\xA4\xAB + \xF0\xAE\xA4\xAC + \xF0\xAE\xA4\xAD + \xF0\xAE\xA4\xAE + \xF0\xAE\xA4\xAF + \xF0\xAE\xA4\xB0 + \xF0\xAE\xA4\xB1 + \xF0\xAE\xA4\xB2 + \xF0\xAE\xA4\xB3 + \xF0\xAE\xA4\xB4 + \xF0\xAE\xA4\xB5 + \xF0\xAE\xA4\xB6 + \xF0\xAE\xA4\xB7 + \xF0\xAE\xA4\xB8 + \xF0\xAE\xA4\xB9 + \xF0\xAE\xA4\xBA + \xF0\xAE\xA4\xBB + \xF0\xAE\xA4\xBC + \xF0\xAE\xA4\xBD + \xF0\xAE\xA4\xBE + \xF0\xAE\xA4\xBF + \xF0\xAE\xA5\x80 + \xF0\xAE\xA5\x81 + \xF0\xAE\xA5\x82 + \xF0\xAE\xA5\x83 + \xF0\xAE\xA5\x84 + \xF0\xAE\xA5\x85 + \xF0\xAE\xA5\x86 + \xF0\xAE\xA5\x87 + \xF0\xAE\xA5\x88 + \xF0\xAE\xA5\x89 + \xF0\xAE\xA5\x8A + \xF0\xAE\xA5\x8B + \xF0\xAE\xA5\x8C + \xF0\xAE\xA5\x8D + \xF0\xAE\xA5\x8E + \xF0\xAE\xA5\x8F + \xF0\xAE\xA5\x90 + \xF0\xAE\xA5\x91 + \xF0\xAE\xA5\x92 + \xF0\xAE\xA5\x93 + \xF0\xAE\xA5\x94 + \xF0\xAE\xA5\x95 + \xF0\xAE\xA5\x96 + \xF0\xAE\xA5\x97 + \xF0\xAE\xA5\x98 + \xF0\xAE\xA5\x99 + \xF0\xAE\xA5\x9A + \xF0\xAE\xA5\x9B + \xF0\xAE\xA5\x9C + \xF0\xAE\xA5\x9D + \xF0\xAE\xA5\x9E + \xF0\xAE\xA5\x9F + \xF0\xAE\xA5\xA0 + \xF0\xAE\xA5\xA1 + \xF0\xAE\xA5\xA2 + \xF0\xAE\xA5\xA3 + \xF0\xAE\xA5\xA4 + \xF0\xAE\xA5\xA5 + \xF0\xAE\xA5\xA6 + \xF0\xAE\xA5\xA7 + \xF0\xAE\xA5\xA8 + \xF0\xAE\xA5\xA9 + \xF0\xAE\xA5\xAA + \xF0\xAE\xA5\xAB + \xF0\xAE\xA5\xAC + \xF0\xAE\xA5\xAD + \xF0\xAE\xA5\xAE + \xF0\xAE\xA5\xAF + \xF0\xAE\xA5\xB0 + \xF0\xAE\xA5\xB1 + \xF0\xAE\xA5\xB2 + \xF0\xAE\xA5\xB3 + \xF0\xAE\xA5\xB4 + \xF0\xAE\xA5\xB5 + \xF0\xAE\xA5\xB6 + \xF0\xAE\xA5\xB7 + \xF0\xAE\xA5\xB8 + \xF0\xAE\xA5\xB9 + \xF0\xAE\xA5\xBA + \xF0\xAE\xA5\xBB + \xF0\xAE\xA5\xBC + \xF0\xAE\xA5\xBD + \xF0\xAE\xA5\xBE + \xF0\xAE\xA5\xBF + \xF0\xAE\xA6\x80 + \xF0\xAE\xA6\x81 + \xF0\xAE\xA6\x82 + \xF0\xAE\xA6\x83 + \xF0\xAE\xA6\x84 + \xF0\xAE\xA6\x85 + \xF0\xAE\xA6\x86 + \xF0\xAE\xA6\x87 + \xF0\xAE\xA6\x88 + \xF0\xAE\xA6\x89 + \xF0\xAE\xA6\x8A + \xF0\xAE\xA6\x8B + \xF0\xAE\xA6\x8C + \xF0\xAE\xA6\x8D + \xF0\xAE\xA6\x8E + \xF0\xAE\xA6\x8F + \xF0\xAE\xA6\x90 + \xF0\xAE\xA6\x91 + \xF0\xAE\xA6\x92 + \xF0\xAE\xA6\x93 + \xF0\xAE\xA6\x94 + \xF0\xAE\xA6\x95 + \xF0\xAE\xA6\x96 + \xF0\xAE\xA6\x97 + \xF0\xAE\xA6\x98 + \xF0\xAE\xA6\x99 + \xF0\xAE\xA6\x9A + \xF0\xAE\xA6\x9B + \xF0\xAE\xA6\x9C + \xF0\xAE\xA6\x9D + \xF0\xAE\xA6\x9E + \xF0\xAE\xA6\x9F + \xF0\xAE\xA6\xA0 + \xF0\xAE\xA6\xA1 + \xF0\xAE\xA6\xA2 + \xF0\xAE\xA6\xA3 + \xF0\xAE\xA6\xA4 + \xF0\xAE\xA6\xA5 + \xF0\xAE\xA6\xA6 + \xF0\xAE\xA6\xA7 + \xF0\xAE\xA6\xA8 + \xF0\xAE\xA6\xA9 + \xF0\xAE\xA6\xAA + \xF0\xAE\xA6\xAB + \xF0\xAE\xA6\xAC + \xF0\xAE\xA6\xAD + \xF0\xAE\xA6\xAE + \xF0\xAE\xA6\xAF + \xF0\xAE\xA6\xB0 + \xF0\xAE\xA6\xB1 + \xF0\xAE\xA6\xB2 + \xF0\xAE\xA6\xB3 + \xF0\xAE\xA6\xB4 + \xF0\xAE\xA6\xB5 + \xF0\xAE\xA6\xB6 + \xF0\xAE\xA6\xB7 + \xF0\xAE\xA6\xB8 + \xF0\xAE\xA6\xB9 + \xF0\xAE\xA6\xBA + \xF0\xAE\xA6\xBB + \xF0\xAE\xA6\xBC + \xF0\xAE\xA6\xBD + \xF0\xAE\xA6\xBE + \xF0\xAE\xA6\xBF + \xF0\xAE\xA7\x80 + \xF0\xAE\xA7\x81 + \xF0\xAE\xA7\x82 + \xF0\xAE\xA7\x83 + \xF0\xAE\xA7\x84 + \xF0\xAE\xA7\x85 + \xF0\xAE\xA7\x86 + \xF0\xAE\xA7\x87 + \xF0\xAE\xA7\x88 + \xF0\xAE\xA7\x89 + \xF0\xAE\xA7\x8A + \xF0\xAE\xA7\x8B + \xF0\xAE\xA7\x8C + \xF0\xAE\xA7\x8D + \xF0\xAE\xA7\x8E + \xF0\xAE\xA7\x8F + \xF0\xAE\xA7\x90 + \xF0\xAE\xA7\x91 + \xF0\xAE\xA7\x92 + \xF0\xAE\xA7\x93 + \xF0\xAE\xA7\x94 + \xF0\xAE\xA7\x95 + \xF0\xAE\xA7\x96 + \xF0\xAE\xA7\x97 + \xF0\xAE\xA7\x98 + \xF0\xAE\xA7\x99 + \xF0\xAE\xA7\x9A + \xF0\xAE\xA7\x9B + \xF0\xAE\xA7\x9C + \xF0\xAE\xA7\x9D + \xF0\xAE\xA7\x9E + \xF0\xAE\xA7\x9F + \xF0\xAE\xA7\xA0 + \xF0\xAE\xA7\xA1 + \xF0\xAE\xA7\xA2 + \xF0\xAE\xA7\xA3 + \xF0\xAE\xA7\xA4 + \xF0\xAE\xA7\xA5 + \xF0\xAE\xA7\xA6 + \xF0\xAE\xA7\xA7 + \xF0\xAE\xA7\xA8 + \xF0\xAE\xA7\xA9 + \xF0\xAE\xA7\xAA + \xF0\xAE\xA7\xAB + \xF0\xAE\xA7\xAC + \xF0\xAE\xA7\xAD + \xF0\xAE\xA7\xAE + \xF0\xAE\xA7\xAF + \xF0\xAE\xA7\xB0 + \xF0\xAE\xA7\xB1 + \xF0\xAE\xA7\xB2 + \xF0\xAE\xA7\xB3 + \xF0\xAE\xA7\xB4 + \xF0\xAE\xA7\xB5 + \xF0\xAE\xA7\xB6 + \xF0\xAE\xA7\xB7 + \xF0\xAE\xA7\xB8 + \xF0\xAE\xA7\xB9 + \xF0\xAE\xA7\xBA + \xF0\xAE\xA7\xBB + \xF0\xAE\xA7\xBC + \xF0\xAE\xA7\xBD + \xF0\xAE\xA7\xBE + \xF0\xAE\xA7\xBF + \xF0\xAE\xA8\x80 + \xF0\xAE\xA8\x81 + \xF0\xAE\xA8\x82 + \xF0\xAE\xA8\x83 + \xF0\xAE\xA8\x84 + \xF0\xAE\xA8\x85 + \xF0\xAE\xA8\x86 + \xF0\xAE\xA8\x87 + \xF0\xAE\xA8\x88 + \xF0\xAE\xA8\x89 + \xF0\xAE\xA8\x8A + \xF0\xAE\xA8\x8B + \xF0\xAE\xA8\x8C + \xF0\xAE\xA8\x8D + \xF0\xAE\xA8\x8E + \xF0\xAE\xA8\x8F + \xF0\xAE\xA8\x90 + \xF0\xAE\xA8\x91 + \xF0\xAE\xA8\x92 + \xF0\xAE\xA8\x93 + \xF0\xAE\xA8\x94 + \xF0\xAE\xA8\x95 + \xF0\xAE\xA8\x96 + \xF0\xAE\xA8\x97 + \xF0\xAE\xA8\x98 + \xF0\xAE\xA8\x99 + \xF0\xAE\xA8\x9A + \xF0\xAE\xA8\x9B + \xF0\xAE\xA8\x9C + \xF0\xAE\xA8\x9D + \xF0\xAE\xA8\x9E + \xF0\xAE\xA8\x9F + \xF0\xAE\xA8\xA0 + \xF0\xAE\xA8\xA1 + \xF0\xAE\xA8\xA2 + \xF0\xAE\xA8\xA3 + \xF0\xAE\xA8\xA4 + \xF0\xAE\xA8\xA5 + \xF0\xAE\xA8\xA6 + \xF0\xAE\xA8\xA7 + \xF0\xAE\xA8\xA8 + \xF0\xAE\xA8\xA9 + \xF0\xAE\xA8\xAA + \xF0\xAE\xA8\xAB + \xF0\xAE\xA8\xAC + \xF0\xAE\xA8\xAD + \xF0\xAE\xA8\xAE + \xF0\xAE\xA8\xAF + \xF0\xAE\xA8\xB0 + \xF0\xAE\xA8\xB1 + \xF0\xAE\xA8\xB2 + \xF0\xAE\xA8\xB3 + \xF0\xAE\xA8\xB4 + \xF0\xAE\xA8\xB5 + \xF0\xAE\xA8\xB6 + \xF0\xAE\xA8\xB7 + \xF0\xAE\xA8\xB8 + \xF0\xAE\xA8\xB9 + \xF0\xAE\xA8\xBA + \xF0\xAE\xA8\xBB + \xF0\xAE\xA8\xBC + \xF0\xAE\xA8\xBD + \xF0\xAE\xA8\xBE + \xF0\xAE\xA8\xBF + \xF0\xAE\xA9\x80 + \xF0\xAE\xA9\x81 + \xF0\xAE\xA9\x82 + \xF0\xAE\xA9\x83 + \xF0\xAE\xA9\x84 + \xF0\xAE\xA9\x85 + \xF0\xAE\xA9\x86 + \xF0\xAE\xA9\x87 + \xF0\xAE\xA9\x88 + \xF0\xAE\xA9\x89 + \xF0\xAE\xA9\x8A + \xF0\xAE\xA9\x8B + \xF0\xAE\xA9\x8C + \xF0\xAE\xA9\x8D + \xF0\xAE\xA9\x8E + \xF0\xAE\xA9\x8F + \xF0\xAE\xA9\x90 + \xF0\xAE\xA9\x91 + \xF0\xAE\xA9\x92 + \xF0\xAE\xA9\x93 + \xF0\xAE\xA9\x94 + \xF0\xAE\xA9\x95 + \xF0\xAE\xA9\x96 + \xF0\xAE\xA9\x97 + \xF0\xAE\xA9\x98 + \xF0\xAE\xA9\x99 + \xF0\xAE\xA9\x9A + \xF0\xAE\xA9\x9B + \xF0\xAE\xA9\x9C + \xF0\xAE\xA9\x9D + \xF0\xAE\xA9\x9E + \xF0\xAE\xA9\x9F + \xF0\xAE\xA9\xA0 + \xF0\xAE\xA9\xA1 + \xF0\xAE\xA9\xA2 + \xF0\xAE\xA9\xA3 + \xF0\xAE\xA9\xA4 + \xF0\xAE\xA9\xA5 + \xF0\xAE\xA9\xA6 + \xF0\xAE\xA9\xA7 + \xF0\xAE\xA9\xA8 + \xF0\xAE\xA9\xA9 + \xF0\xAE\xA9\xAA + \xF0\xAE\xA9\xAB + \xF0\xAE\xA9\xAC + \xF0\xAE\xA9\xAD + \xF0\xAE\xA9\xAE + \xF0\xAE\xA9\xAF + \xF0\xAE\xA9\xB0 + \xF0\xAE\xA9\xB1 + \xF0\xAE\xA9\xB2 + \xF0\xAE\xA9\xB3 + \xF0\xAE\xA9\xB4 + \xF0\xAE\xA9\xB5 + \xF0\xAE\xA9\xB6 + \xF0\xAE\xA9\xB7 + \xF0\xAE\xA9\xB8 + \xF0\xAE\xA9\xB9 + \xF0\xAE\xA9\xBA + \xF0\xAE\xA9\xBB + \xF0\xAE\xA9\xBC + \xF0\xAE\xA9\xBD + \xF0\xAE\xA9\xBE + \xF0\xAE\xA9\xBF + \xF0\xAE\xAA\x80 + \xF0\xAE\xAA\x81 + \xF0\xAE\xAA\x82 + \xF0\xAE\xAA\x83 + \xF0\xAE\xAA\x84 + \xF0\xAE\xAA\x85 + \xF0\xAE\xAA\x86 + \xF0\xAE\xAA\x87 + \xF0\xAE\xAA\x88 + \xF0\xAE\xAA\x89 + \xF0\xAE\xAA\x8A + \xF0\xAE\xAA\x8B + \xF0\xAE\xAA\x8C + \xF0\xAE\xAA\x8D + \xF0\xAE\xAA\x8E + \xF0\xAE\xAA\x8F + \xF0\xAE\xAA\x90 + \xF0\xAE\xAA\x91 + \xF0\xAE\xAA\x92 + \xF0\xAE\xAA\x93 + \xF0\xAE\xAA\x94 + \xF0\xAE\xAA\x95 + \xF0\xAE\xAA\x96 + \xF0\xAE\xAA\x97 + \xF0\xAE\xAA\x98 + \xF0\xAE\xAA\x99 + \xF0\xAE\xAA\x9A + \xF0\xAE\xAA\x9B + \xF0\xAE\xAA\x9C + \xF0\xAE\xAA\x9D + \xF0\xAE\xAA\x9E + \xF0\xAE\xAA\x9F + \xF0\xAE\xAA\xA0 + \xF0\xAE\xAA\xA1 + \xF0\xAE\xAA\xA2 + \xF0\xAE\xAA\xA3 + \xF0\xAE\xAA\xA4 + \xF0\xAE\xAA\xA5 + \xF0\xAE\xAA\xA6 + \xF0\xAE\xAA\xA7 + \xF0\xAE\xAA\xA8 + \xF0\xAE\xAA\xA9 + \xF0\xAE\xAA\xAA + \xF0\xAE\xAA\xAB + \xF0\xAE\xAA\xAC + \xF0\xAE\xAA\xAD + \xF0\xAE\xAA\xAE + \xF0\xAE\xAA\xAF + \xF0\xAE\xAA\xB0 + \xF0\xAE\xAA\xB1 + \xF0\xAE\xAA\xB2 + \xF0\xAE\xAA\xB3 + \xF0\xAE\xAA\xB4 + \xF0\xAE\xAA\xB5 + \xF0\xAE\xAA\xB6 + \xF0\xAE\xAA\xB7 + \xF0\xAE\xAA\xB8 + \xF0\xAE\xAA\xB9 + \xF0\xAE\xAA\xBA + \xF0\xAE\xAA\xBB + \xF0\xAE\xAA\xBC + \xF0\xAE\xAA\xBD + \xF0\xAE\xAA\xBE + \xF0\xAE\xAA\xBF + \xF0\xAE\xAB\x80 + \xF0\xAE\xAB\x81 + \xF0\xAE\xAB\x82 + \xF0\xAE\xAB\x83 + \xF0\xAE\xAB\x84 + \xF0\xAE\xAB\x85 + \xF0\xAE\xAB\x86 + \xF0\xAE\xAB\x87 + \xF0\xAE\xAB\x88 + \xF0\xAE\xAB\x89 + \xF0\xAE\xAB\x8A + \xF0\xAE\xAB\x8B + \xF0\xAE\xAB\x8C + \xF0\xAE\xAB\x8D + \xF0\xAE\xAB\x8E + \xF0\xAE\xAB\x8F + \xF0\xAE\xAB\x90 + \xF0\xAE\xAB\x91 + \xF0\xAE\xAB\x92 + \xF0\xAE\xAB\x93 + \xF0\xAE\xAB\x94 + \xF0\xAE\xAB\x95 + \xF0\xAE\xAB\x96 + \xF0\xAE\xAB\x97 + \xF0\xAE\xAB\x98 + \xF0\xAE\xAB\x99 + \xF0\xAE\xAB\x9A + \xF0\xAE\xAB\x9B + \xF0\xAE\xAB\x9C + \xF0\xAE\xAB\x9D + \xF0\xAE\xAB\x9E + \xF0\xAE\xAB\x9F + \xF0\xAE\xAB\xA0 + \xF0\xAE\xAB\xA1 + \xF0\xAE\xAB\xA2 + \xF0\xAE\xAB\xA3 + \xF0\xAE\xAB\xA4 + \xF0\xAE\xAB\xA5 + \xF0\xAE\xAB\xA6 + \xF0\xAE\xAB\xA7 + \xF0\xAE\xAB\xA8 + \xF0\xAE\xAB\xA9 + \xF0\xAE\xAB\xAA + \xF0\xAE\xAB\xAB + \xF0\xAE\xAB\xAC + \xF0\xAE\xAB\xAD + \xF0\xAE\xAB\xAE + \xF0\xAE\xAB\xAF + \xF0\xAE\xAB\xB0 + \xF0\xAE\xAB\xB1 + \xF0\xAE\xAB\xB2 + \xF0\xAE\xAB\xB3 + \xF0\xAE\xAB\xB4 + \xF0\xAE\xAB\xB5 + \xF0\xAE\xAB\xB6 + \xF0\xAE\xAB\xB7 + \xF0\xAE\xAB\xB8 + \xF0\xAE\xAB\xB9 + \xF0\xAE\xAB\xBA + \xF0\xAE\xAB\xBB + \xF0\xAE\xAB\xBC + \xF0\xAE\xAB\xBD + \xF0\xAE\xAB\xBE + \xF0\xAE\xAB\xBF + \xF0\xAE\xAC\x80 + \xF0\xAE\xAC\x81 + \xF0\xAE\xAC\x82 + \xF0\xAE\xAC\x83 + \xF0\xAE\xAC\x84 + \xF0\xAE\xAC\x85 + \xF0\xAE\xAC\x86 + \xF0\xAE\xAC\x87 + \xF0\xAE\xAC\x88 + \xF0\xAE\xAC\x89 + \xF0\xAE\xAC\x8A + \xF0\xAE\xAC\x8B + \xF0\xAE\xAC\x8C + \xF0\xAE\xAC\x8D + \xF0\xAE\xAC\x8E + \xF0\xAE\xAC\x8F + \xF0\xAE\xAC\x90 + \xF0\xAE\xAC\x91 + \xF0\xAE\xAC\x92 + \xF0\xAE\xAC\x93 + \xF0\xAE\xAC\x94 + \xF0\xAE\xAC\x95 + \xF0\xAE\xAC\x96 + \xF0\xAE\xAC\x97 + \xF0\xAE\xAC\x98 + \xF0\xAE\xAC\x99 + \xF0\xAE\xAC\x9A + \xF0\xAE\xAC\x9B + \xF0\xAE\xAC\x9C + \xF0\xAE\xAC\x9D + \xF0\xAE\xAC\x9E + \xF0\xAE\xAC\x9F + \xF0\xAE\xAC\xA0 + \xF0\xAE\xAC\xA1 + \xF0\xAE\xAC\xA2 + \xF0\xAE\xAC\xA3 + \xF0\xAE\xAC\xA4 + \xF0\xAE\xAC\xA5 + \xF0\xAE\xAC\xA6 + \xF0\xAE\xAC\xA7 + \xF0\xAE\xAC\xA8 + \xF0\xAE\xAC\xA9 + \xF0\xAE\xAC\xAA + \xF0\xAE\xAC\xAB + \xF0\xAE\xAC\xAC + \xF0\xAE\xAC\xAD + \xF0\xAE\xAC\xAE + \xF0\xAE\xAC\xAF + \xF0\xAE\xAC\xB0 + \xF0\xAE\xAC\xB1 + \xF0\xAE\xAC\xB2 + \xF0\xAE\xAC\xB3 + \xF0\xAE\xAC\xB4 + \xF0\xAE\xAC\xB5 + \xF0\xAE\xAC\xB6 + \xF0\xAE\xAC\xB7 + \xF0\xAE\xAC\xB8 + \xF0\xAE\xAC\xB9 + \xF0\xAE\xAC\xBA + \xF0\xAE\xAC\xBB + \xF0\xAE\xAC\xBC + \xF0\xAE\xAC\xBD + \xF0\xAE\xAC\xBE + \xF0\xAE\xAC\xBF + \xF0\xAE\xAD\x80 + \xF0\xAE\xAD\x81 + \xF0\xAE\xAD\x82 + \xF0\xAE\xAD\x83 + \xF0\xAE\xAD\x84 + \xF0\xAE\xAD\x85 + \xF0\xAE\xAD\x86 + \xF0\xAE\xAD\x87 + \xF0\xAE\xAD\x88 + \xF0\xAE\xAD\x89 + \xF0\xAE\xAD\x8A + \xF0\xAE\xAD\x8B + \xF0\xAE\xAD\x8C + \xF0\xAE\xAD\x8D + \xF0\xAE\xAD\x8E + \xF0\xAE\xAD\x8F + \xF0\xAE\xAD\x90 + \xF0\xAE\xAD\x91 + \xF0\xAE\xAD\x92 + \xF0\xAE\xAD\x93 + \xF0\xAE\xAD\x94 + \xF0\xAE\xAD\x95 + \xF0\xAE\xAD\x96 + \xF0\xAE\xAD\x97 + \xF0\xAE\xAD\x98 + \xF0\xAE\xAD\x99 + \xF0\xAE\xAD\x9A + \xF0\xAE\xAD\x9B + \xF0\xAE\xAD\x9C + \xF0\xAE\xAD\x9D + \xF0\xAE\xAD\x9E + \xF0\xAE\xAD\x9F + \xF0\xAE\xAD\xA0 + \xF0\xAE\xAD\xA1 + \xF0\xAE\xAD\xA2 + \xF0\xAE\xAD\xA3 + \xF0\xAE\xAD\xA4 + \xF0\xAE\xAD\xA5 + \xF0\xAE\xAD\xA6 + \xF0\xAE\xAD\xA7 + \xF0\xAE\xAD\xA8 + \xF0\xAE\xAD\xA9 + \xF0\xAE\xAD\xAA + \xF0\xAE\xAD\xAB + \xF0\xAE\xAD\xAC + \xF0\xAE\xAD\xAD + \xF0\xAE\xAD\xAE + \xF0\xAE\xAD\xAF + \xF0\xAE\xAD\xB0 + \xF0\xAE\xAD\xB1 + \xF0\xAE\xAD\xB2 + \xF0\xAE\xAD\xB3 + \xF0\xAE\xAD\xB4 + \xF0\xAE\xAD\xB5 + \xF0\xAE\xAD\xB6 + \xF0\xAE\xAD\xB7 + \xF0\xAE\xAD\xB8 + \xF0\xAE\xAD\xB9 + \xF0\xAE\xAD\xBA + \xF0\xAE\xAD\xBB + \xF0\xAE\xAD\xBC + \xF0\xAE\xAD\xBD + \xF0\xAE\xAD\xBE + \xF0\xAE\xAD\xBF + \xF0\xAE\xAE\x80 + \xF0\xAE\xAE\x81 + \xF0\xAE\xAE\x82 + \xF0\xAE\xAE\x83 + \xF0\xAE\xAE\x84 + \xF0\xAE\xAE\x85 + \xF0\xAE\xAE\x86 + \xF0\xAE\xAE\x87 + \xF0\xAE\xAE\x88 + \xF0\xAE\xAE\x89 + \xF0\xAE\xAE\x8A + \xF0\xAE\xAE\x8B + \xF0\xAE\xAE\x8C + \xF0\xAE\xAE\x8D + \xF0\xAE\xAE\x8E + \xF0\xAE\xAE\x8F + \xF0\xAE\xAE\x90 + \xF0\xAE\xAE\x91 + \xF0\xAE\xAE\x92 + \xF0\xAE\xAE\x93 + \xF0\xAE\xAE\x94 + \xF0\xAE\xAE\x95 + \xF0\xAE\xAE\x96 + \xF0\xAE\xAE\x97 + \xF0\xAE\xAE\x98 + \xF0\xAE\xAE\x99 + \xF0\xAE\xAE\x9A + \xF0\xAE\xAE\x9B + \xF0\xAE\xAE\x9C + \xF0\xAE\xAE\x9D + \xF0\xAE\xAE\x9E + \xF0\xAE\xAE\x9F + \xF0\xAE\xAE\xA0 + \xF0\xAE\xAE\xA1 + \xF0\xAE\xAE\xA2 + \xF0\xAE\xAE\xA3 + \xF0\xAE\xAE\xA4 + \xF0\xAE\xAE\xA5 + \xF0\xAE\xAE\xA6 + \xF0\xAE\xAE\xA7 + \xF0\xAE\xAE\xA8 + \xF0\xAE\xAE\xA9 + \xF0\xAE\xAE\xAA + \xF0\xAE\xAE\xAB + \xF0\xAE\xAE\xAC + \xF0\xAE\xAE\xAD + \xF0\xAE\xAE\xAE + \xF0\xAE\xAE\xAF + \xF0\xAE\xAE\xB0 + \xF0\xAE\xAE\xB1 + \xF0\xAE\xAE\xB2 + \xF0\xAE\xAE\xB3 + \xF0\xAE\xAE\xB4 + \xF0\xAE\xAE\xB5 + \xF0\xAE\xAE\xB6 + \xF0\xAE\xAE\xB7 + \xF0\xAE\xAE\xB8 + \xF0\xAE\xAE\xB9 + \xF0\xAE\xAE\xBA + \xF0\xAE\xAE\xBB + \xF0\xAE\xAE\xBC + \xF0\xAE\xAE\xBD + \xF0\xAE\xAE\xBE + \xF0\xAE\xAE\xBF + \xF0\xAE\xAF\x80 + \xF0\xAE\xAF\x81 + \xF0\xAE\xAF\x82 + \xF0\xAE\xAF\x83 + \xF0\xAE\xAF\x84 + \xF0\xAE\xAF\x85 + \xF0\xAE\xAF\x86 + \xF0\xAE\xAF\x87 + \xF0\xAE\xAF\x88 + \xF0\xAE\xAF\x89 + \xF0\xAE\xAF\x8A + \xF0\xAE\xAF\x8B + \xF0\xAE\xAF\x8C + \xF0\xAE\xAF\x8D + \xF0\xAE\xAF\x8E + \xF0\xAE\xAF\x8F + \xF0\xAE\xAF\x90 + \xF0\xAE\xAF\x91 + \xF0\xAE\xAF\x92 + \xF0\xAE\xAF\x93 + \xF0\xAE\xAF\x94 + \xF0\xAE\xAF\x95 + \xF0\xAE\xAF\x96 + \xF0\xAE\xAF\x97 + \xF0\xAE\xAF\x98 + \xF0\xAE\xAF\x99 + \xF0\xAE\xAF\x9A + \xF0\xAE\xAF\x9B + \xF0\xAE\xAF\x9C + \xF0\xAE\xAF\x9D + \xF0\xAE\xAF\x9E + \xF0\xAE\xAF\x9F + \xF0\xAE\xAF\xA0 \xF0\xAF\xA0\x80 \xF0\xAF\xA0\x81 \xF0\xAF\xA0\x82 diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh index a419f5af9d83..9a837d483103 100755 --- a/tools/tools/nanobsd/defaults.sh +++ b/tools/tools/nanobsd/defaults.sh @@ -256,7 +256,6 @@ rm ( ) { # are relative to NANO_WORLDDIR. # tgt_touch ( ) ( - cd "${NANO_WORLDDIR}" for i; do touch $i @@ -270,7 +269,7 @@ tgt_touch ( ) ( # directory is removed and a symlink is created. If we're doing # a nopriv build, then append this fact to the metalog # -tgt_dir2symlink () ( +tgt_dir2symlink ( ) ( dir=$1 symlink=$2 @@ -292,11 +291,6 @@ CR0 ( ) { chroot "${NANO_WORLDDIR}" /bin/sh -c "$*" || true } -nano_cleanup ( ) ( - [ $? -eq 0 ] || echo "Error encountered. Check for errors in last log file." 1>&2 - exit $? -) - clean_build ( ) ( pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})" @@ -334,8 +328,6 @@ build_world ( ) ( ) build_kernel ( ) ( - local extra - pprint 2 "build kernel ($NANO_KERNEL)" pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk" @@ -402,7 +394,6 @@ install_world ( ) ( ) install_etc ( ) ( - pprint 2 "install /etc" pprint 3 "log: ${NANO_LOG}/_.etc" @@ -418,8 +409,6 @@ install_etc ( ) ( ) install_kernel ( ) ( - local extra - pprint 2 "install kernel ($NANO_KERNEL)" pprint 3 "log: ${NANO_LOG}/_.ik" @@ -449,7 +438,8 @@ native_xtools ( ) ( nano_make_install_env set -o xtrace cd "${NANO_SRC}" - ${NANO_MAKE} native-xtools DESTDIR="${NANO_WORLDDIR}" + ${NANO_MAKE} native-xtools + ${NANO_MAKE} native-xtools-install DESTDIR="${NANO_WORLDDIR}" ) > ${NANO_LOG}/_.native_xtools 2>&1 ) @@ -458,8 +448,7 @@ native_xtools ( ) ( # Run the requested set of early customization scripts, run before # buildworld. # -run_early_customize() { - +run_early_customize ( ) { pprint 2 "run early customize scripts" for c in $NANO_EARLY_CUSTOMIZE do @@ -492,7 +481,6 @@ run_customize ( ) ( # setup nanobsd, prune empty dirs from /usr, etc # run_late_customize ( ) ( - pprint 2 "run late customize scripts" for c in $NANO_LATE_CUSTOMIZE do @@ -511,7 +499,6 @@ run_late_customize ( ) ( # a user's cfg file would override this. # fixup_before_diskimage ( ) ( - # Run the deduplication script that takes the matalog journal and # combines multiple entries for the same file (see source for # details). We take the extra step of removing the size keywords. This @@ -541,15 +528,20 @@ setup_nanobsd ( ) ( # have hardcoded paths under ${prefix}/etc are not tweakable. if [ -d usr/local/etc ] ; then ( - mkdir -p etc/local cd usr/local/etc find . -print | cpio -dumpl ../../../etc/local cd .. rm -rf etc - ln -s ../../etc/local etc ) fi + # Always setup the usr/local/etc -> etc/local symlink. + # usr/local/etc gets created by packages, but if no packages + # are installed by this point, but are later in the process, + # the symlink not being here causes problems. It never hurts + # to have the symlink in error though. + ln -s ../../etc/local usr/local/etc + for d in var etc do # link /$d under /conf @@ -595,11 +587,13 @@ setup_nanobsd_etc ( ) ( echo "/dev/${NANO_DRIVE}${NANO_ROOT} / ufs ro 1 1" > etc/fstab echo "/dev/${NANO_DRIVE}${NANO_SLICE_CFG} /cfg ufs rw,noauto 2 2" >> etc/fstab mkdir -p cfg + + # Create directory for eventual /usr/local/etc contents + mkdir -p etc/local ) ) prune_usr ( ) ( - # Remove all empty directories in /usr find "${NANO_WORLDDIR}"/usr -type d -depth -print | while read d @@ -754,10 +748,9 @@ cust_install_files ( ) ( # Install packages from ${NANO_PACKAGE_DIR} cust_pkgng ( ) ( - mkdir -p ${NANO_WORLDDIR}/usr/local/etc local PKG_CONF="${NANO_WORLDDIR}/usr/local/etc/pkg.conf" - local PKGCMD="env ASSUME_ALWAYS_YES=YES PKG_DBDIR=${NANO_PKG_META_BASE}/pkg SIGNATURE_TYPE=none /usr/sbin/pkg" + local PKGCMD="env BATCH=YES ASSUME_ALWAYS_YES=YES PKG_DBDIR=${NANO_PKG_META_BASE}/pkg SIGNATURE_TYPE=none /usr/sbin/pkg" # Ensure pkg.conf points pkg to where the package meta data lives. touch ${PKG_CONF} @@ -820,7 +813,7 @@ cust_pkgng ( ) ( # Register all args as early customize function to run just before # build commences. -early_customize_cmd () { +early_customize_cmd ( ) { NANO_EARLY_CUSTOMIZE="$NANO_EARLY_CUSTOMIZE $*" } diff --git a/tools/tools/nanobsd/dhcpd/common b/tools/tools/nanobsd/dhcpd/common index c8c7598a1c02..685435692bdf 100644 --- a/tools/tools/nanobsd/dhcpd/common +++ b/tools/tools/nanobsd/dhcpd/common @@ -129,7 +129,6 @@ WITHOUT_NLS=true WITHOUT_NS_CACHING=true WITHOUT_OBJC=true WITHOUT_PROFILE=true -WITHOUT_RCMDS=true WITHOUT_SENDMAIL=true WITHOUT_SHAREDOCS=true WITHOUT_SYSCONS=true diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common index b7c5c2806814..4ad19872bfdf 100644 --- a/tools/tools/nanobsd/embedded/common +++ b/tools/tools/nanobsd/embedded/common @@ -66,7 +66,7 @@ # o common tooling for creating images for odd-ball platforms # o support for boot loaders other than uboot in the image # or via special instructions -# o No pony support. Sadly, you cannot have a pony. +# o no pony support; sadly, you cannot have a pony # if [ -z $NANO_NAME ]; then @@ -160,7 +160,6 @@ WITHOUT_NLS=true WITHOUT_NS_CACHING=true WITHOUT_OBJC=true WITHOUT_PROFILE=true -WITHOUT_RCMDS=true WITHOUT_SENDMAIL=true WITHOUT_SHAREDOCS=true WITHOUT_SYSCONS=true @@ -281,7 +280,7 @@ create_diskimage_mbr ( ) ( out=${NANO_DISKIMGDIR}/_.disk.image.${NANO_NAME}${fmt} # below depends on https://reviews.freebsd.org/D4403 not yet in the tree # but there's problems: it marks all partitions as active, so you have to - # boot off parittion 3 or 2 by hand if you're playing around with this WIP + # boot off partition 3 or 2 by hand if you're playing around with this WIP case ${NANO_LAYOUT} in std-embedded) mkimg -a 3 ${skiparg} ${fmtarg} ${bootmbr} -s mbr -p ${s1}:=${NANO_LOG}/_.s1 \ diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common index bc38e993b454..393d656b09aa 100644 --- a/tools/tools/nanobsd/gateworks/common +++ b/tools/tools/nanobsd/gateworks/common @@ -140,7 +140,6 @@ WITHOUT_PMC=true WITHOUT_PORTSNAP=true WITHOUT_PROFILE=true WITHOUT_QUOTAS=true -WITHOUT_RCMDS=true WITHOUT_RCS=true WITHOUT_RESCUE=true WITHOUT_SENDMAIL=true diff --git a/tools/tools/nanobsd/legacy.sh b/tools/tools/nanobsd/legacy.sh index ce8c50f931e7..0ae8290b75f3 100644 --- a/tools/tools/nanobsd/legacy.sh +++ b/tools/tools/nanobsd/legacy.sh @@ -197,8 +197,7 @@ create_diskimage ( ) ( fi mdconfig -d -u $MD - trap - 1 2 15 - trap nano_cleanup EXIT + trap - 1 2 15 EXIT ) > ${NANO_LOG}/_.di 2>&1 ) diff --git a/tools/tools/portsinfo/portsinfo.sh b/tools/tools/portsinfo/portsinfo.sh index f3dcf5039b92..a5e700b50efe 100644 --- a/tools/tools/portsinfo/portsinfo.sh +++ b/tools/tools/portsinfo/portsinfo.sh @@ -7,7 +7,7 @@ PATH=/bin:/usr/bin:/usr/local/bin:$PATH; export PATH -host=http://www.freebsd.org +host=https://www.freebsd.org url=$host/cgi/ports.cgi time='?type=new&time=2+week+ago&sektion=all' time2='?type=changed&time=2+week+ago&sektion=all' @@ -31,9 +31,9 @@ type make install to install the application. For more information about using ports, see the ports collection - http://www.freebsd.org/handbook/ports.html + https://www.freebsd.org/handbook/ports.html and - http://www.freebsd.org/ports/ + https://www.freebsd.org/ports/ EOF diff --git a/tools/tools/syscall_timing/syscall_timing.c b/tools/tools/syscall_timing/syscall_timing.c index 52d3359f17c5..08e71c4ce146 100644 --- a/tools/tools/syscall_timing/syscall_timing.c +++ b/tools/tools/syscall_timing/syscall_timing.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include +#include #include #include #include @@ -129,6 +131,22 @@ test_getppid(uintmax_t num, uintmax_t int_arg, const char *path) return (i); } +uintmax_t +test_getresuid(uintmax_t num, uintmax_t int_arg, const char *path) +{ + uid_t ruid, euid, suid; + uintmax_t i; + + benchmark_start(); + for (i = 0; i < num; i++) { + if (alarm_fired) + break; + (void)getresuid(&ruid, &euid, &suid); + } + benchmark_stop(); + return (i); +} + uintmax_t test_clock_gettime(uintmax_t num, uintmax_t int_arg, const char *path) { @@ -161,6 +179,21 @@ test_gettimeofday(uintmax_t num, uintmax_t int_arg, const char *path) return (i); } +uintmax_t +test_getpriority(uintmax_t num, uintmax_t int_arg, const char *path) +{ + uintmax_t i; + + benchmark_start(); + for (i = 0; i < num; i++) { + if (alarm_fired) + break; + (void)getpriority(PRIO_PROCESS, 0); + } + benchmark_stop(); + return (i); +} + uintmax_t test_pipe(uintmax_t num, uintmax_t int_arg, const char *path) { @@ -189,6 +222,31 @@ test_pipe(uintmax_t num, uintmax_t int_arg, const char *path) return (i); } +uintmax_t +test_select(uintmax_t num, uintmax_t int_arg, const char *path) +{ + fd_set readfds, writefds, exceptfds; + struct timeval tv; + uintmax_t i; + int error; + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + benchmark_start(); + for (i = 0; i < num; i++) { + if (alarm_fired) + break; + (void)select(0, &readfds, &writefds, &exceptfds, &tv); + } + benchmark_stop(); + return (i); +} + uintmax_t test_socket_stream(uintmax_t num, uintmax_t int_arg, const char *path) { @@ -281,6 +339,28 @@ test_socketpair_dgram(uintmax_t num, uintmax_t int_arg, const char *path) return (i); } +uintmax_t +test_access(uintmax_t num, uintmax_t int_arg, const char *path) +{ + uintmax_t i; + int fd; + + fd = access(path, O_RDONLY); + if (fd < 0) + err(-1, "test_access: %s", path); + close(fd); + + benchmark_start(); + for (i = 0; i < num; i++) { + if (alarm_fired) + break; + access(path, O_RDONLY); + close(fd); + } + benchmark_stop(); + return (i); +} + uintmax_t test_create_unlink(uintmax_t num, uintmax_t int_arg, const char *path) { @@ -333,6 +413,21 @@ test_open_close(uintmax_t num, uintmax_t int_arg, const char *path) return (i); } +uintmax_t +test_bad_open(uintmax_t num, uintmax_t int_arg, const char *path) +{ + uintmax_t i; + + benchmark_start(); + for (i = 0; i < num; i++) { + if (alarm_fired) + break; + open("", O_RDONLY); + } + benchmark_stop(); + return (i); +} + uintmax_t test_read(uintmax_t num, uintmax_t int_arg, const char *path) { @@ -631,16 +726,21 @@ struct test { static const struct test tests[] = { { "getuid", test_getuid }, { "getppid", test_getppid }, + { "getresuid", test_getresuid }, { "clock_gettime", test_clock_gettime }, { "gettimeofday", test_gettimeofday }, + { "getpriority", test_getpriority }, { "pipe", test_pipe }, + { "select", test_select }, { "socket_local_stream", test_socket_stream, .t_int = PF_LOCAL }, { "socket_local_dgram", test_socket_dgram, .t_int = PF_LOCAL }, { "socketpair_stream", test_socketpair_stream }, { "socketpair_dgram", test_socketpair_dgram }, { "socket_tcp", test_socket_stream, .t_int = PF_INET }, { "socket_udp", test_socket_dgram, .t_int = PF_INET }, + { "access", test_access, .t_flags = FLAG_PATH }, { "create_unlink", test_create_unlink, .t_flags = FLAG_PATH }, + { "bad_open", test_bad_open }, { "open_close", test_open_close, .t_flags = FLAG_PATH }, { "open_read_close_1", test_open_read_close, .t_flags = FLAG_PATH, .t_int = 1 }, @@ -693,20 +793,22 @@ main(int argc, char *argv[]) struct timespec ts_res; const struct test *the_test; const char *path; + char *tmp_dir, *tmp_path; long long ll; char *endp; - int ch, error, i, j, k; + int ch, fd, error, i, j, k, rv; uintmax_t iterations, loops; alarm_timeout = 1; iterations = 0; loops = 10; path = NULL; + tmp_path = NULL; while ((ch = getopt(argc, argv, "i:l:p:s:")) != -1) { switch (ch) { case 'i': ll = strtol(optarg, &endp, 10); - if (*endp != 0 || ll < 1 || ll > 100000) + if (*endp != 0 || ll < 1) usage(); iterations = ll; break; @@ -760,7 +862,15 @@ main(int argc, char *argv[]) if (the_test == NULL) usage(); if ((the_test->t_flags & FLAG_PATH) && (path == NULL)) { - errx(-1, "%s requires -p", the_test->t_name); + tmp_dir = strdup("/tmp/syscall_timing.XXXXXXXX"); + if (tmp_dir == NULL) + err(1, "strdup"); + tmp_dir = mkdtemp(tmp_dir); + if (tmp_dir == NULL) + err(1, "mkdtemp"); + rv = asprintf(&tmp_path, "%s/testfile", tmp_dir); + if (rv <= 0) + err(1, "asprintf"); } } @@ -779,6 +889,19 @@ main(int argc, char *argv[]) the_test = &tests[i]; } + if (tmp_path != NULL) { + fd = open(tmp_path, O_WRONLY | O_CREAT, 0700); + if (fd < 0) + err(1, "cannot open %s", tmp_path); + error = ftruncate(fd, 1000000); + if (error != 0) + err(1, "ftruncate"); + error = close(fd); + if (error != 0) + err(1, "close"); + path = tmp_path; + } + /* * Run one warmup, then do the real thing (loops) times. */ @@ -804,5 +927,15 @@ main(int argc, char *argv[]) printf("0.%09ju\n", (uintmax_t)nsecsperit); } } + + if (tmp_path != NULL) { + error = unlink(tmp_path); + if (error != 0 && errno != ENOENT) + warn("cannot unlink %s", tmp_path); + error = rmdir(tmp_dir); + if (error != 0) + warn("cannot rmdir %s", tmp_dir); + } + return (0); } diff --git a/tools/tools/usbtest/Makefile.depend b/tools/tools/usbtest/Makefile.depend index f1aeab00195d..6b278b826fd0 100644 --- a/tools/tools/usbtest/Makefile.depend +++ b/tools/tools/usbtest/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 03c0d500a5eb..cad3d5c2bd4d 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -250,8 +250,6 @@ SUBDIR.${MK_OPENSSL}+= chkey SUBDIR.${MK_OPENSSL}+= dc SUBDIR.${MK_OPENSSL}+= newkey SUBDIR.${MK_QUOTAS}+= quota -SUBDIR.${MK_RCMDS}+= rlogin -SUBDIR.${MK_RCMDS}+= rsh SUBDIR.${MK_SENDMAIL}+= vacation SUBDIR.${MK_TALK}+= talk SUBDIR.${MK_TELNET}+= telnet diff --git a/usr.bin/addr2line/Makefile.depend b/usr.bin/addr2line/Makefile.depend index 20f498cfb39b..c3f78dbc4cb6 100644 --- a/usr.bin/addr2line/Makefile.depend +++ b/usr.bin/addr2line/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/apply/Makefile.depend b/usr.bin/apply/Makefile.depend index 6002005509a1..cfec878c09d0 100644 --- a/usr.bin/apply/Makefile.depend +++ b/usr.bin/apply/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ar/Makefile.depend b/usr.bin/ar/Makefile.depend index 8def7bcfc9a2..d35ec72622d9 100644 --- a/usr.bin/ar/Makefile.depend +++ b/usr.bin/ar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/asa/Makefile.depend b/usr.bin/asa/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/asa/Makefile.depend +++ b/usr.bin/asa/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/at/Makefile.depend b/usr.bin/at/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/at/Makefile.depend +++ b/usr.bin/at/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/atm/sscop/Makefile.depend b/usr.bin/atm/sscop/Makefile.depend index a49eafb82488..34779573a216 100644 --- a/usr.bin/atm/sscop/Makefile.depend +++ b/usr.bin/atm/sscop/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/awk/Makefile.depend b/usr.bin/awk/Makefile.depend index cb804542add1..7e06312d1eb7 100644 --- a/usr.bin/awk/Makefile.depend +++ b/usr.bin/awk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/awk/awk.1 b/usr.bin/awk/awk.1 index 2de54738031d..aba0f393dd08 100644 --- a/usr.bin/awk/awk.1 +++ b/usr.bin/awk/awk.1 @@ -690,12 +690,15 @@ and returns its exit status. .Bl -tag -width "lshift(a, b)" .It Fn compl x Returns the bitwise complement of integer argument x. -.It Fn and x y -Performs a bitwise AND on integer arguments x and y. -.It Fn or x y -Performs a bitwise OR on integer arguments x and y. -.It Fn xor x y -Performs a bitwise Exclusive-OR on integer arguments x and y. +.It Fn and v1 v2 ... +Performs a bitwise AND on all arguments provided, as integers. +There must be at least two values. +.It Fn or v1 v2 ... +Performs a bitwise OR on all arguments provided, as integers. +There must be at least two values. +.It Fn xor v1 v2 ... +Performs a bitwise Exclusive-OR on all arguments provided, as integers. +There must be at least two values. .It Fn lshift x n Returns integer argument x shifted by n bits to the left. .It Fn rshift x n diff --git a/usr.bin/banner/Makefile.depend b/usr.bin/banner/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/banner/Makefile.depend +++ b/usr.bin/banner/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/basename/Makefile.depend b/usr.bin/basename/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/basename/Makefile.depend +++ b/usr.bin/basename/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bc/Makefile.depend b/usr.bin/bc/Makefile.depend index eb5b17459733..23785ca7f9b4 100644 --- a/usr.bin/bc/Makefile.depend +++ b/usr.bin/bc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/biff/Makefile.depend b/usr.bin/biff/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/biff/Makefile.depend +++ b/usr.bin/biff/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bluetooth/bthost/Makefile.depend b/usr.bin/bluetooth/bthost/Makefile.depend index 5d2103865524..f556d37ea8e6 100644 --- a/usr.bin/bluetooth/bthost/Makefile.depend +++ b/usr.bin/bluetooth/bthost/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bluetooth/btsockstat/Makefile.depend b/usr.bin/bluetooth/btsockstat/Makefile.depend index 0ea1c90dafad..ab1720427ef9 100644 --- a/usr.bin/bluetooth/btsockstat/Makefile.depend +++ b/usr.bin/bluetooth/btsockstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.c b/usr.bin/bluetooth/btsockstat/btsockstat.c index 78f61279d47c..67d95f295b04 100644 --- a/usr.bin/bluetooth/btsockstat/btsockstat.c +++ b/usr.bin/bluetooth/btsockstat/btsockstat.c @@ -35,6 +35,7 @@ #include #include #include +#define _WANT_SOCKET #include #include diff --git a/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend b/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend index 4633528bfb23..b4d153024640 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend +++ b/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bmake/Makefile b/usr.bin/bmake/Makefile index 98122f84eaed..f7562004f8e7 100644 --- a/usr.bin/bmake/Makefile +++ b/usr.bin/bmake/Makefile @@ -14,10 +14,7 @@ CFLAGS+= -I${.CURDIR} CLEANDIRS+= FreeBSD CLEANFILES+= bootstrap -# $Id: Makefile,v 1.95 2017/07/20 19:36:13 sjg Exp $ - -# Base version on src date -_MAKE_VERSION= 20170720 +# $Id: Makefile,v 1.99 2017/08/13 20:12:53 sjg Exp $ PROG?= ${.CURDIR:T} @@ -74,6 +71,7 @@ SRCS+= \ lstReplace.c \ lstSucc.c + # this file gets generated by configure .sinclude "Makefile.config" @@ -160,9 +158,6 @@ MANDIR= ${MANDIR.bmake:U${SHAREDIR}/man} ${OBJS}: config.h .endif -# make sure that MAKE_VERSION gets updated. -main.o: ${SRCS} ${MAKEFILE} - # A simple unit-test driver to help catch regressions accept test: diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config index 7110870359e8..93e16cbae397 100644 --- a/usr.bin/bmake/Makefile.config +++ b/usr.bin/bmake/Makefile.config @@ -7,10 +7,12 @@ SRCTOP?= ${.CURDIR:H:H} # things set by configure -prefix= /usr +_MAKE_VERSION=20171028 + +prefix?= /usr srcdir= ${SRCTOP}/contrib/bmake CC?= gcc -DEFAULT_SYS_PATH= .../share/mk:/usr/share/mk +DEFAULT_SYS_PATH?= .../share/mk:/usr/share/mk CPPFLAGS+= CFLAGS+= ${CPPFLAGS} -DHAVE_CONFIG_H @@ -22,4 +24,3 @@ FILEMON_H= /usr/include/dev/filemon/filemon.h BMAKE_PATH_MAX?= 1024 # used if MAXPATHLEN not defined CPPFLAGS+= -DBMAKE_PATH_MAX=${BMAKE_PATH_MAX} - diff --git a/usr.bin/bmake/Makefile.depend b/usr.bin/bmake/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/bmake/Makefile.depend +++ b/usr.bin/bmake/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bmake/config.h b/usr.bin/bmake/config.h index 7a47d4c69575..16e043e683d8 100644 --- a/usr.bin/bmake/config.h +++ b/usr.bin/bmake/config.h @@ -245,7 +245,7 @@ #define PACKAGE_NAME "bmake" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "bmake 20160606" +#define PACKAGE_STRING "bmake 20170812" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "bmake" @@ -254,7 +254,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "20160606" +#define PACKAGE_VERSION "20170812" /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void diff --git a/usr.bin/brandelf/Makefile.depend b/usr.bin/brandelf/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/brandelf/Makefile.depend +++ b/usr.bin/brandelf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bsdcat/Makefile.depend b/usr.bin/bsdcat/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/bsdcat/Makefile.depend +++ b/usr.bin/bsdcat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bsdcat/tests/Makefile b/usr.bin/bsdcat/tests/Makefile index 2aa678b2432a..921299dd3c7e 100644 --- a/usr.bin/bsdcat/tests/Makefile +++ b/usr.bin/bsdcat/tests/Makefile @@ -28,6 +28,7 @@ TESTS_SRCS= \ test_empty_gz.c \ test_empty_lz4.c \ test_empty_xz.c \ + test_empty_zstd.c \ test_error.c \ test_error_mixed.c \ test_expand_Z.c \ @@ -37,6 +38,7 @@ TESTS_SRCS= \ test_expand_mixed.c \ test_expand_plain.c \ test_expand_xz.c \ + test_expand_zstd.c \ test_help.c \ test_version.c @@ -59,11 +61,13 @@ CLEANFILES+= list.h list.h.tmp ${PACKAGE}FILES+= test_empty.gz.uu ${PACKAGE}FILES+= test_empty.lz4.uu ${PACKAGE}FILES+= test_empty.xz.uu +${PACKAGE}FILES+= test_empty.zst.uu ${PACKAGE}FILES+= test_expand.Z.uu ${PACKAGE}FILES+= test_expand.bz2.uu ${PACKAGE}FILES+= test_expand.gz.uu ${PACKAGE}FILES+= test_expand.lz4.uu ${PACKAGE}FILES+= test_expand.plain.uu ${PACKAGE}FILES+= test_expand.xz.uu +${PACKAGE}FILES+= test_expand.zst.uu .include diff --git a/usr.bin/bsdcat/tests/Makefile.depend b/usr.bin/bsdcat/tests/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/bsdcat/tests/Makefile.depend +++ b/usr.bin/bsdcat/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bsdiff/bsdiff/Makefile.depend b/usr.bin/bsdiff/bsdiff/Makefile.depend index 36fe4681c1c9..c93d137e9c2e 100644 --- a/usr.bin/bsdiff/bsdiff/Makefile.depend +++ b/usr.bin/bsdiff/bsdiff/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bsdiff/bspatch/Makefile.depend b/usr.bin/bsdiff/bspatch/Makefile.depend index 36fe4681c1c9..c93d137e9c2e 100644 --- a/usr.bin/bsdiff/bspatch/Makefile.depend +++ b/usr.bin/bsdiff/bspatch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bzip2/Makefile.depend b/usr.bin/bzip2/Makefile.depend index 509010f59033..81ca59e9e1be 100644 --- a/usr.bin/bzip2/Makefile.depend +++ b/usr.bin/bzip2/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/bzip2recover/Makefile.depend b/usr.bin/bzip2recover/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/bzip2recover/Makefile.depend +++ b/usr.bin/bzip2recover/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/c89/Makefile.depend b/usr.bin/c89/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/c89/Makefile.depend +++ b/usr.bin/c89/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/c99/Makefile.depend b/usr.bin/c99/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/c99/Makefile.depend +++ b/usr.bin/c99/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/caesar/Makefile.depend b/usr.bin/caesar/Makefile.depend index c9f9d52f6e26..905e67cc66c9 100644 --- a/usr.bin/caesar/Makefile.depend +++ b/usr.bin/caesar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/calendar/Makefile.depend b/usr.bin/calendar/Makefile.depend index c9f9d52f6e26..905e67cc66c9 100644 --- a/usr.bin/calendar/Makefile.depend +++ b/usr.bin/calendar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 1da45bfcbcd5..41a30bc23ee3 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -419,6 +419,7 @@ 11/23 Luca Pizzamiglio born in Casalpusterlengo, Italy, 1978 11/24 Andrey Zakhvatov born in Chelyabinsk, Russian Federation, 1974 11/24 Daniel Gerzo born in Bratislava, Slovakia, 1986 +11/25 Fedor Uporov born in Yalta, Crimea, USSR, 1988 11/28 Nik Clayton born in Peterborough, United Kingdom, 1973 11/28 Stanislav Sedov born in Chelyabinsk, USSR, 1985 12/01 Hajimu Umemoto born in Nara, Japan, 1961 diff --git a/usr.bin/calendar/calendars/pt_BR.UTF-8/calendar.commemorative b/usr.bin/calendar/calendars/pt_BR.UTF-8/calendar.commemorative index 2620aae24793..3f5df5221c02 100644 --- a/usr.bin/calendar/calendars/pt_BR.UTF-8/calendar.commemorative +++ b/usr.bin/calendar/calendars/pt_BR.UTF-8/calendar.commemorative @@ -4,8 +4,6 @@ * Originally submitted by Renato Tambellini * * Brazilian commemorative days - * - * http://www.ibge.gov.br/ibgeteen/datas/home.html */ #ifndef _pt_BR_UTF_8_commemorative_ diff --git a/usr.bin/calendar/events.c b/usr.bin/calendar/events.c index d6f358a472b7..e53dbe8d3b08 100644 --- a/usr.bin/calendar/events.c +++ b/usr.bin/calendar/events.c @@ -86,12 +86,9 @@ event_continue(struct event *e, char *txt) errx(1, "event_continue: cannot allocate memory"); free(e->text); - e->text = (char *)malloc(strlen(text) + strlen(txt) + 3); + asprintf(&e->text, "%s\n%s", text, txt); if (e->text == NULL) errx(1, "event_continue: cannot allocate memory"); - strcpy(e->text, text); - strcat(e->text, "\n"); - strcat(e->text, txt); free(text); return; diff --git a/usr.bin/calendar/sunpos.c b/usr.bin/calendar/sunpos.c index f905c3f4a720..1e39cbabb574 100644 --- a/usr.bin/calendar/sunpos.c +++ b/usr.bin/calendar/sunpos.c @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$"); /* * This code is created to match the formulas available at: * Formula and examples obtained from "How to Calculate alt/az: SAAO" at - * http://www.saao.ac.za/public-info/sun-moon-stars/sun-index/how-to-calculate-altaz/ + * http://old.saao.ac.za/public-info/sun-moon-stars/sun-index/how-to-calculate-altaz/ */ #include diff --git a/usr.bin/cap_mkdb/Makefile.depend b/usr.bin/cap_mkdb/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/cap_mkdb/Makefile.depend +++ b/usr.bin/cap_mkdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/chat/Makefile.depend b/usr.bin/chat/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/chat/Makefile.depend +++ b/usr.bin/chat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/chkey/Makefile.depend b/usr.bin/chkey/Makefile.depend index bae15c2d809d..97ec617dcc81 100644 --- a/usr.bin/chkey/Makefile.depend +++ b/usr.bin/chkey/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/chpass/Makefile.depend b/usr.bin/chpass/Makefile.depend index 3dc74b2b9d39..73f87bf8bbcc 100644 --- a/usr.bin/chpass/Makefile.depend +++ b/usr.bin/chpass/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/chpass/chpass.c b/usr.bin/chpass/chpass.c index 9f9be5335a68..74c96beb92e7 100644 --- a/usr.bin/chpass/chpass.c +++ b/usr.bin/chpass/chpass.c @@ -82,7 +82,7 @@ main(int argc, char *argv[]) struct passwd lpw, *old_pw, *pw; int ch, pfd, tfd; const char *password; - char *arg = NULL; + char *arg = NULL, *cryptpw; uid_t uid; #ifdef YP struct ypclnt *ypclnt; @@ -228,8 +228,8 @@ main(int argc, char *argv[]) if (old_pw && !master_mode) { password = getpass("Password: "); - if (strcmp(crypt(password, old_pw->pw_passwd), - old_pw->pw_passwd) != 0) + cryptpw = crypt(password, old_pw->pw_passwd); + if (cryptpw == NULL || strcmp(cryptpw, old_pw->pw_passwd) != 0) baduser(); } else { password = ""; diff --git a/usr.bin/cksum/Makefile.depend b/usr.bin/cksum/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/cksum/Makefile.depend +++ b/usr.bin/cksum/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/bugpoint/Makefile.depend b/usr.bin/clang/bugpoint/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/bugpoint/Makefile.depend +++ b/usr.bin/clang/bugpoint/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/clang-format/Makefile.depend b/usr.bin/clang/clang-format/Makefile.depend index 7a822fac93b9..6cbdf44b0812 100644 --- a/usr.bin/clang/clang-format/Makefile.depend +++ b/usr.bin/clang/clang-format/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/clang-tblgen/Makefile.depend b/usr.bin/clang/clang-tblgen/Makefile.depend index 9f12128ea718..5459b436be4c 100644 --- a/usr.bin/clang/clang-tblgen/Makefile.depend +++ b/usr.bin/clang/clang-tblgen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/clang/Makefile.depend b/usr.bin/clang/clang/Makefile.depend index 4d1a1657e1b6..50ee86e9addb 100644 --- a/usr.bin/clang/clang/Makefile.depend +++ b/usr.bin/clang/clang/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llc/Makefile.depend b/usr.bin/clang/llc/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llc/Makefile.depend +++ b/usr.bin/clang/llc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/lld/Makefile.depend b/usr.bin/clang/lld/Makefile.depend index b47c72f6636f..878fb135c885 100644 --- a/usr.bin/clang/lld/Makefile.depend +++ b/usr.bin/clang/lld/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/lldb/Makefile.depend b/usr.bin/clang/lldb/Makefile.depend index 162877523067..920832156fd8 100644 --- a/usr.bin/clang/lldb/Makefile.depend +++ b/usr.bin/clang/lldb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/lli/Makefile.depend b/usr.bin/clang/lli/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/lli/Makefile.depend +++ b/usr.bin/clang/lli/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-ar/Makefile.depend b/usr.bin/clang/llvm-ar/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-ar/Makefile.depend +++ b/usr.bin/clang/llvm-ar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-as/Makefile.depend b/usr.bin/clang/llvm-as/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-as/Makefile.depend +++ b/usr.bin/clang/llvm-as/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-bcanalyzer/Makefile.depend b/usr.bin/clang/llvm-bcanalyzer/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-bcanalyzer/Makefile.depend +++ b/usr.bin/clang/llvm-bcanalyzer/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-cov/Makefile.depend b/usr.bin/clang/llvm-cov/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-cov/Makefile.depend +++ b/usr.bin/clang/llvm-cov/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-cxxdump/Makefile.depend b/usr.bin/clang/llvm-cxxdump/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-cxxdump/Makefile.depend +++ b/usr.bin/clang/llvm-cxxdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-cxxfilt/Makefile.depend b/usr.bin/clang/llvm-cxxfilt/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-cxxfilt/Makefile.depend +++ b/usr.bin/clang/llvm-cxxfilt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-diff/Makefile.depend b/usr.bin/clang/llvm-diff/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-diff/Makefile.depend +++ b/usr.bin/clang/llvm-diff/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-dis/Makefile.depend b/usr.bin/clang/llvm-dis/Makefile.depend index 9f12128ea718..5459b436be4c 100644 --- a/usr.bin/clang/llvm-dis/Makefile.depend +++ b/usr.bin/clang/llvm-dis/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-dwarfdump/Makefile.depend b/usr.bin/clang/llvm-dwarfdump/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-dwarfdump/Makefile.depend +++ b/usr.bin/clang/llvm-dwarfdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-extract/Makefile.depend b/usr.bin/clang/llvm-extract/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-extract/Makefile.depend +++ b/usr.bin/clang/llvm-extract/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-link/Makefile.depend b/usr.bin/clang/llvm-link/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-link/Makefile.depend +++ b/usr.bin/clang/llvm-link/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-lto/Makefile.depend b/usr.bin/clang/llvm-lto/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-lto/Makefile.depend +++ b/usr.bin/clang/llvm-lto/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-lto2/Makefile.depend b/usr.bin/clang/llvm-lto2/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-lto2/Makefile.depend +++ b/usr.bin/clang/llvm-lto2/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-mc/Makefile.depend b/usr.bin/clang/llvm-mc/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-mc/Makefile.depend +++ b/usr.bin/clang/llvm-mc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-modextract/Makefile.depend b/usr.bin/clang/llvm-modextract/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-modextract/Makefile.depend +++ b/usr.bin/clang/llvm-modextract/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-nm/Makefile.depend b/usr.bin/clang/llvm-nm/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-nm/Makefile.depend +++ b/usr.bin/clang/llvm-nm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-objdump/Makefile.depend b/usr.bin/clang/llvm-objdump/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-objdump/Makefile.depend +++ b/usr.bin/clang/llvm-objdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-pdbutil/Makefile.depend b/usr.bin/clang/llvm-pdbutil/Makefile.depend index 9f12128ea718..5459b436be4c 100644 --- a/usr.bin/clang/llvm-pdbutil/Makefile.depend +++ b/usr.bin/clang/llvm-pdbutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-profdata/Makefile.depend b/usr.bin/clang/llvm-profdata/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-profdata/Makefile.depend +++ b/usr.bin/clang/llvm-profdata/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-rtdyld/Makefile.depend b/usr.bin/clang/llvm-rtdyld/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-rtdyld/Makefile.depend +++ b/usr.bin/clang/llvm-rtdyld/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-symbolizer/Makefile.depend b/usr.bin/clang/llvm-symbolizer/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-symbolizer/Makefile.depend +++ b/usr.bin/clang/llvm-symbolizer/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-tblgen/Makefile.depend b/usr.bin/clang/llvm-tblgen/Makefile.depend index 9f12128ea718..5459b436be4c 100644 --- a/usr.bin/clang/llvm-tblgen/Makefile.depend +++ b/usr.bin/clang/llvm-tblgen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/llvm-xray/Makefile.depend b/usr.bin/clang/llvm-xray/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/llvm-xray/Makefile.depend +++ b/usr.bin/clang/llvm-xray/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/clang/opt/Makefile.depend b/usr.bin/clang/opt/Makefile.depend index 3fd78c934924..1423340957b6 100644 --- a/usr.bin/clang/opt/Makefile.depend +++ b/usr.bin/clang/opt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/cmp/Makefile.depend b/usr.bin/cmp/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/cmp/Makefile.depend +++ b/usr.bin/cmp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/col/Makefile.depend b/usr.bin/col/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/col/Makefile.depend +++ b/usr.bin/col/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/colldef/Makefile.depend b/usr.bin/colldef/Makefile.depend index 26839bd6174a..b9ab526886b5 100644 --- a/usr.bin/colldef/Makefile.depend +++ b/usr.bin/colldef/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/colrm/Makefile.depend b/usr.bin/colrm/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/colrm/Makefile.depend +++ b/usr.bin/colrm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/column/Makefile.depend b/usr.bin/column/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/column/Makefile.depend +++ b/usr.bin/column/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/comm/Makefile.depend b/usr.bin/comm/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/comm/Makefile.depend +++ b/usr.bin/comm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/compile_et/Makefile.depend b/usr.bin/compile_et/Makefile.depend index 1288666d2fad..5eff1f3d88e9 100644 --- a/usr.bin/compile_et/Makefile.depend +++ b/usr.bin/compile_et/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/compress/Makefile.depend b/usr.bin/compress/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/compress/Makefile.depend +++ b/usr.bin/compress/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/compress/tests/Makefile.depend b/usr.bin/compress/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/compress/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/cpio/Makefile.depend b/usr.bin/cpio/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/cpio/Makefile.depend +++ b/usr.bin/cpio/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/cpio/tests/Makefile b/usr.bin/cpio/tests/Makefile index b71bdca3c409..4e5618bfe3dc 100644 --- a/usr.bin/cpio/tests/Makefile +++ b/usr.bin/cpio/tests/Makefile @@ -43,6 +43,7 @@ TESTS_SRCS= \ test_extract_cpio_lzma.c \ test_extract_cpio_lzo.c \ test_extract_cpio_xz.c \ + test_extract_cpio_zstd.c \ test_format_newc.c \ test_gcpio_compat.c \ test_missing_file.c \ @@ -73,6 +74,7 @@ TESTS_SRCS= \ test_option_xz.c \ test_option_y.c \ test_option_z.c \ + test_option_zstd.c \ test_owner_parse.c \ test_passthrough_dotdot.c \ test_passthrough_reverse.c @@ -104,6 +106,7 @@ ${PACKAGE}FILES+= test_extract.cpio.lz4.uu ${PACKAGE}FILES+= test_extract.cpio.lzma.uu ${PACKAGE}FILES+= test_extract.cpio.lzo.uu ${PACKAGE}FILES+= test_extract.cpio.xz.uu +${PACKAGE}FILES+= test_extract.cpio.zst.uu ${PACKAGE}FILES+= test_gcpio_compat_ref.bin.uu ${PACKAGE}FILES+= test_gcpio_compat_ref.crc.uu ${PACKAGE}FILES+= test_gcpio_compat_ref.newc.uu diff --git a/usr.bin/cpio/tests/Makefile.depend b/usr.bin/cpio/tests/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/cpio/tests/Makefile.depend +++ b/usr.bin/cpio/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/cpuset/Makefile.depend b/usr.bin/cpuset/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/cpuset/Makefile.depend +++ b/usr.bin/cpuset/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/csplit/Makefile.depend b/usr.bin/csplit/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/csplit/Makefile.depend +++ b/usr.bin/csplit/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/csplit/tests/Makefile.depend b/usr.bin/csplit/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/csplit/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/ctags/Makefile.depend b/usr.bin/ctags/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/ctags/Makefile.depend +++ b/usr.bin/ctags/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ctlstat/Makefile.depend b/usr.bin/ctlstat/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/ctlstat/Makefile.depend +++ b/usr.bin/ctlstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/cut/Makefile.depend b/usr.bin/cut/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/cut/Makefile.depend +++ b/usr.bin/cut/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/cxxfilt/Makefile.depend b/usr.bin/cxxfilt/Makefile.depend index 40241f30eaf8..4f2cad33521d 100644 --- a/usr.bin/cxxfilt/Makefile.depend +++ b/usr.bin/cxxfilt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/dc/Makefile.depend b/usr.bin/dc/Makefile.depend index 7e1b62db9b93..83920ef06124 100644 --- a/usr.bin/dc/Makefile.depend +++ b/usr.bin/dc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/diff/tests/Makefile.depend b/usr.bin/diff/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/diff/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/diff3/tests/Makefile.depend b/usr.bin/diff3/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/diff3/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/dirname/Makefile.depend b/usr.bin/dirname/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/dirname/Makefile.depend +++ b/usr.bin/dirname/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/dpv/Makefile.depend b/usr.bin/dpv/Makefile.depend index 849ebfc4f96b..a64291919578 100644 --- a/usr.bin/dpv/Makefile.depend +++ b/usr.bin/dpv/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/drill/Makefile.depend b/usr.bin/drill/Makefile.depend index 750a0a3fb67f..6df275334c05 100644 --- a/usr.bin/drill/Makefile.depend +++ b/usr.bin/drill/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/dtc/Makefile.depend b/usr.bin/dtc/Makefile.depend index b6027086c86c..ea8bba31ec06 100644 --- a/usr.bin/dtc/Makefile.depend +++ b/usr.bin/dtc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/du/Makefile.depend b/usr.bin/du/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/du/Makefile.depend +++ b/usr.bin/du/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/du/tests/Makefile.depend b/usr.bin/du/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/du/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/ee/Makefile.depend b/usr.bin/ee/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/ee/Makefile.depend +++ b/usr.bin/ee/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/elf2aout/Makefile.depend b/usr.bin/elf2aout/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/elf2aout/Makefile.depend +++ b/usr.bin/elf2aout/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/elfcopy/Makefile.depend b/usr.bin/elfcopy/Makefile.depend index 6416d535adfa..1188b4e4157e 100644 --- a/usr.bin/elfcopy/Makefile.depend +++ b/usr.bin/elfcopy/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/elfdump/Makefile.depend b/usr.bin/elfdump/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/elfdump/Makefile.depend +++ b/usr.bin/elfdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/enigma/Makefile.depend b/usr.bin/enigma/Makefile.depend index 4d4fe056ec40..931a9e5f35c5 100644 --- a/usr.bin/enigma/Makefile.depend +++ b/usr.bin/enigma/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/env/Makefile.depend b/usr.bin/env/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/env/Makefile.depend +++ b/usr.bin/env/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/expand/Makefile.depend b/usr.bin/expand/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/expand/Makefile.depend +++ b/usr.bin/expand/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/factor/Makefile.depend b/usr.bin/factor/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/usr.bin/factor/Makefile.depend +++ b/usr.bin/factor/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/false/Makefile.depend b/usr.bin/false/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/false/Makefile.depend +++ b/usr.bin/false/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/fetch/Makefile.depend b/usr.bin/fetch/Makefile.depend index 30112de0e218..853edec5b9da 100644 --- a/usr.bin/fetch/Makefile.depend +++ b/usr.bin/fetch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/file/Makefile.depend b/usr.bin/file/Makefile.depend index 4057a4c6b1ce..1d4438985327 100644 --- a/usr.bin/file/Makefile.depend +++ b/usr.bin/file/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/file2c/Makefile.depend b/usr.bin/file2c/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/file2c/Makefile.depend +++ b/usr.bin/file2c/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/find/Makefile.depend b/usr.bin/find/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/usr.bin/find/Makefile.depend +++ b/usr.bin/find/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/finger/Makefile.depend b/usr.bin/finger/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/finger/Makefile.depend +++ b/usr.bin/finger/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fmt/Makefile.depend b/usr.bin/fmt/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/fmt/Makefile.depend +++ b/usr.bin/fmt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fold/Makefile.depend b/usr.bin/fold/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/fold/Makefile.depend +++ b/usr.bin/fold/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fortune/datfiles/fortunes b/usr.bin/fortune/datfiles/fortunes index f8aaadabb37e..832c9d437337 100644 --- a/usr.bin/fortune/datfiles/fortunes +++ b/usr.bin/fortune/datfiles/fortunes @@ -46260,7 +46260,7 @@ error: The operation completed successfully. For more information, see Help and Support Center at -http://go.microsoft.com/fwlink/events.asp. +https://go.microsoft.com/fwlink/events.asp. % The minute a man is convinced that he is interesting, he isn't. % diff --git a/usr.bin/fortune/datfiles/freebsd-tips b/usr.bin/fortune/datfiles/freebsd-tips index 57e6cbbaf9ab..e8800c6e8d57 100644 --- a/usr.bin/fortune/datfiles/freebsd-tips +++ b/usr.bin/fortune/datfiles/freebsd-tips @@ -47,10 +47,6 @@ reinstall it with gpart(8). See If you accidentally end up inside vi, you can quit it by pressing Escape, colon (:), q (q), bang (!) and pressing return. % -If you are in the C shell and have just installed a new program, you won't -be able to run it unless you first type "rehash". - -- Dru -% If you do not want to get beeps in X11 (X Windows), you can turn them off with xset b off @@ -69,7 +65,7 @@ If you need a reminder to leave your terminal, type "leave +hhmm" where % If you need to ask a question on the FreeBSD-questions mailing list then - http://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/\ + https://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/\ freebsd-questions/index.html contains lots of useful advice to help you get the best results. @@ -100,7 +96,7 @@ environment variable in order to make cdcontrol want to start.) If you'd like to keep track of applications in the FreeBSD ports tree, take a look at FreshPorts; - http://www.freshports.org/ + https://www.freshports.org/ % In order to make fetch (the FreeBSD downloading tool) ask for username/password when it encounters a password-protected web page, you can set @@ -115,7 +111,7 @@ also do a lot more advanced searches - type 'man grep' for details. % In order to support national characters for European languages in tools like less without creating other nationalisation aspects, set the environment -variable LC_ALL to 'en_US.ISO8859-1'. +variable LC_ALL to 'en_US.UTF-8'. % "man firewall" will give advice for building a FreeBSD firewall using ipfw(8). -- David Scheidt @@ -154,11 +150,6 @@ Use "lock -p". When you return, use your password as the key to unlock the terminal. -- Dru % -Need to print a manpage? Use - - man name_of_manpage | col -bx | lpr - -- Dru -% Need to quickly empty a file? Use ": > filename". -- Dru % @@ -256,9 +247,6 @@ To read a compressed file without having to first uncompress it, use and "xzless". -- Dru % -To repeat the last command in the C shell, type "!!". - -- Dru -% To save disk space in your home directory, compress files you rarely use with "gzip filename". -- Dru @@ -455,7 +443,7 @@ You can use "pkg info" to see a list of packages you have installed. % You can use the 'fetch' command to retrieve files over ftp, http or https. - fetch http://www.FreeBSD.org/index.html + fetch https://www.FreeBSD.org/index.html will download the front page of the FreeBSD web site. % @@ -467,7 +455,7 @@ Try "whereis firefox" and "whereis whereis". -- Konstantinos Konstantinidis % Want to run the same command again? -In tcsh you can type "!!". +In many shells (e.g., tcsh, zsh, bash) you can type "!!". % Want to go the directory you were just in? Type "cd -" diff --git a/usr.bin/fortune/fortune/Makefile.depend b/usr.bin/fortune/fortune/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/fortune/fortune/Makefile.depend +++ b/usr.bin/fortune/fortune/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fortune/strfile/Makefile.depend b/usr.bin/fortune/strfile/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/fortune/strfile/Makefile.depend +++ b/usr.bin/fortune/strfile/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fortune/unstr/Makefile.depend b/usr.bin/fortune/unstr/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/fortune/unstr/Makefile.depend +++ b/usr.bin/fortune/unstr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/from/Makefile.depend b/usr.bin/from/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/from/Makefile.depend +++ b/usr.bin/from/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fstat/Makefile.depend b/usr.bin/fstat/Makefile.depend index 5cba1bd6fded..15bf667a0adc 100644 --- a/usr.bin/fstat/Makefile.depend +++ b/usr.bin/fstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/fsync/Makefile.depend b/usr.bin/fsync/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/fsync/Makefile.depend +++ b/usr.bin/fsync/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/ftp/Makefile.depend b/usr.bin/ftp/Makefile.depend index d6c8db88e89b..965e3a120be6 100644 --- a/usr.bin/ftp/Makefile.depend +++ b/usr.bin/ftp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/gcore/Makefile.depend b/usr.bin/gcore/Makefile.depend index 8df34bc70a45..c3cca03a0705 100644 --- a/usr.bin/gcore/Makefile.depend +++ b/usr.bin/gcore/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index ff1010001c3f..ae52d61c9281 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -109,6 +109,9 @@ static void *elf_note_prpsinfo(void *, size_t *); static void *elf_note_prstatus(void *, size_t *); static void *elf_note_thrmisc(void *, size_t *); static void *elf_note_ptlwpinfo(void *, size_t *); +#if defined(__arm__) +static void *elf_note_arm_vfp(void *, size_t *); +#endif #if defined(__i386__) || defined(__amd64__) static void *elf_note_x86_xstate(void *, size_t *); #endif @@ -368,6 +371,9 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep) elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb); +#if defined(__arm__) + elf_putnote(NT_ARM_VFP, elf_note_arm_vfp, tids + i, sb); +#endif #if defined(__i386__) || defined(__amd64__) elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb); #endif @@ -718,6 +724,31 @@ elf_note_ptlwpinfo(void *arg, size_t *sizep) return (p); } +#if defined(__arm__) +static void * +elf_note_arm_vfp(void *arg, size_t *sizep) +{ + lwpid_t tid; + struct vfpreg *vfp; + static bool has_vfp = true; + struct vfpreg info; + + tid = *(lwpid_t *)arg; + if (has_vfp) { + if (ptrace(PT_GETVFPREGS, tid, (void *)&info, 0) != 0) + has_vfp = false; + } + if (!has_vfp) { + *sizep = 0; + return (NULL); + } + vfp = calloc(1, sizeof(*vfp)); + memcpy(vfp, &info, sizeof(*vfp)); + *sizep = sizeof(*vfp); + return (vfp); +} +#endif + #if defined(__i386__) || defined(__amd64__) static void * elf_note_x86_xstate(void *arg, size_t *sizep) diff --git a/usr.bin/gencat/Makefile.depend b/usr.bin/gencat/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/gencat/Makefile.depend +++ b/usr.bin/gencat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/getaddrinfo/Makefile.depend b/usr.bin/getaddrinfo/Makefile.depend index 77151bbd1faf..21c8dc037003 100644 --- a/usr.bin/getaddrinfo/Makefile.depend +++ b/usr.bin/getaddrinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/getconf/Makefile.depend b/usr.bin/getconf/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/getconf/Makefile.depend +++ b/usr.bin/getconf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/getconf/confstr.gperf b/usr.bin/getconf/confstr.gperf index c629987e5caf..f75ad91abd63 100644 --- a/usr.bin/getconf/confstr.gperf +++ b/usr.bin/getconf/confstr.gperf @@ -68,3 +68,14 @@ find_confstr(const char *name, int *key) } return 0; } + +void +foreach_confstr(void (*func)(const char *, int)) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key); + } +} diff --git a/usr.bin/getconf/getconf.1 b/usr.bin/getconf/getconf.1 index 6b5116c704b5..77fdfc65ea43 100644 --- a/usr.bin/getconf/getconf.1 +++ b/usr.bin/getconf/getconf.1 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 8, 2016 +.Dd September 15, 2017 .Dt GETCONF 1 .Os .Sh NAME @@ -36,6 +36,9 @@ .Nd retrieve standard configuration variables .Sh SYNOPSIS .Nm +.Fl a +.Op Ar file +.Nm .Op Fl v Ar environment .Ar path_var .Ar file @@ -45,20 +48,35 @@ .Sh DESCRIPTION The .Nm -utility prints the value of a +utility prints the values of .Tn POSIX or .Tn X/Open -path or system configuration variable to the standard output. -If the specified variable is undefined, the string +path or system configuration variables to the standard output. +If a variable is undefined, the string .Dq Li undefined is output. .Pp -The first form of the command, with two mandatory +The first form of the command displays all of the path or system configuration +variables to standard output. +If +.Ar file +is provided, +all path configuration variables are reported for +.Ar file +using +.Xr pathconf 2 . +Otherwise, +all system configuration variables are reported using +.Xr confstr 3 +and +.Xr sysconf 3. +.Pp +The second form of the command, with two mandatory arguments, retrieves file- and file system-specific configuration variables using .Xr pathconf 2 . -The second form, with a single argument, retrieves system +The third form, with a single argument, retrieves system configuration variables using .Xr confstr 3 and diff --git a/usr.bin/getconf/getconf.c b/usr.bin/getconf/getconf.c index a82196e33d2e..7cbebfe6b183 100644 --- a/usr.bin/getconf/getconf.c +++ b/usr.bin/getconf/getconf.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -41,6 +42,8 @@ __FBSDID("$FreeBSD$"); #include "getconf.h" +static void do_allsys(void); +static void do_allpath(const char *path); static void do_confstr(const char *name, int key); static void do_sysconf(const char *name, int key); static void do_pathconf(const char *name, int key, const char *path); @@ -49,7 +52,8 @@ static void usage(void) { fprintf(stderr, -"usage: getconf [-v prog_env] system_var\n" +"usage: getconf -a [pathname]\n" +" getconf [-v prog_env] system_var\n" " getconf [-v prog_env] path_var pathname\n"); exit(EX_USAGE); } @@ -57,13 +61,18 @@ usage(void) int main(int argc, char **argv) { + bool aflag; int c, key, valid; const char *name, *vflag, *alt_path; intmax_t limitval; + aflag = false; vflag = NULL; - while ((c = getopt(argc, argv, "v:")) != -1) { + while ((c = getopt(argc, argv, "av:")) != -1) { switch (c) { + case 'a': + aflag = true; + break; case 'v': vflag = optarg; break; @@ -73,6 +82,16 @@ main(int argc, char **argv) } } + if (aflag) { + if (vflag != NULL) + usage(); + if (argv[optind] == NULL) + do_allsys(); + else + do_allpath(argv[optind]); + return (0); + } + if ((name = argv[optind]) == NULL) usage(); @@ -135,6 +154,77 @@ main(int argc, char **argv) return 0; } +static void +do_onestr(const char *name, int key) +{ + size_t len; + + errno = 0; + len = confstr(key, 0, 0); + if (len == 0 && errno != 0) { + warn("confstr: %s", name); + return; + } + printf("%s: ", name); + if (len == 0) + printf("undefined\n"); + else { + char buf[len + 1]; + + confstr(key, buf, len); + printf("%s\n", buf); + } +} + +static void +do_onesys(const char *name, int key) +{ + long value; + + errno = 0; + value = sysconf(key); + if (value == -1 && errno != 0) { + warn("sysconf: %s", name); + return; + } + printf("%s: ", name); + if (value == -1) + printf("undefined\n"); + else + printf("%ld\n", value); +} + +static void +do_allsys(void) +{ + + foreach_confstr(do_onestr); + foreach_sysconf(do_onesys); +} + +static void +do_onepath(const char *name, int key, const char *path) +{ + long value; + + errno = 0; + value = pathconf(path, key); + if (value == -1 && errno != EINVAL && errno != 0) + warn("pathconf: %s", name); + printf("%s: ", name); + if (value == -1) + printf("undefined\n"); + else + printf("%ld\n", value); +} + +static void +do_allpath(const char *path) +{ + + foreach_pathconf(do_onepath, path); +} + static void do_confstr(const char *name, int key) { diff --git a/usr.bin/getconf/getconf.h b/usr.bin/getconf/getconf.h index 266a0ff3b051..7629e2bd8116 100644 --- a/usr.bin/getconf/getconf.h +++ b/usr.bin/getconf/getconf.h @@ -41,3 +41,7 @@ int find_limit(const char *name, intmax_t *value); int find_pathconf(const char *name, int *key); int find_progenv(const char *name, const char **alt_path); int find_sysconf(const char *name, int *key); +void foreach_confstr(void (*func)(const char *, int)); +void foreach_pathconf(void (*func)(const char *, int, const char *), + const char *path); +void foreach_sysconf(void (*func)(const char *, int)); diff --git a/usr.bin/getconf/pathconf.gperf b/usr.bin/getconf/pathconf.gperf index f283546f063a..f33a66a06c7f 100644 --- a/usr.bin/getconf/pathconf.gperf +++ b/usr.bin/getconf/pathconf.gperf @@ -68,3 +68,15 @@ find_pathconf(const char *name, int *key) } return 0; } + +void +foreach_pathconf(void (*func)(const char *, int, const char *), + const char *path) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key, path); + } +} diff --git a/usr.bin/getconf/sysconf.gperf b/usr.bin/getconf/sysconf.gperf index 6a0a34989877..d1102ef3c395 100644 --- a/usr.bin/getconf/sysconf.gperf +++ b/usr.bin/getconf/sysconf.gperf @@ -147,3 +147,14 @@ find_sysconf(const char *name, int *key) } return 0; } + +void +foreach_sysconf(void (*func)(const char *, int)) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key); + } +} diff --git a/usr.bin/getconf/tests/Makefile.depend b/usr.bin/getconf/tests/Makefile.depend new file mode 100644 index 000000000000..cae7e645ef6a --- /dev/null +++ b/usr.bin/getconf/tests/Makefile.depend @@ -0,0 +1,16 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/getent/Makefile.depend b/usr.bin/getent/Makefile.depend index 1eb0f334cbe9..ff7c06a53300 100644 --- a/usr.bin/getent/Makefile.depend +++ b/usr.bin/getent/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.bin/getopt/Makefile.depend b/usr.bin/getopt/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/getopt/Makefile.depend +++ b/usr.bin/getopt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/gprof/Makefile.depend b/usr.bin/gprof/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/gprof/Makefile.depend +++ b/usr.bin/gprof/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/grdc/Makefile.depend b/usr.bin/grdc/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/grdc/Makefile.depend +++ b/usr.bin/grdc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/grep/Makefile.depend b/usr.bin/grep/Makefile.depend index f3f02a165db1..2cba2abce257 100644 --- a/usr.bin/grep/Makefile.depend +++ b/usr.bin/grep/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/grep/regex/fastmatch.h b/usr.bin/grep/regex/fastmatch.h index 68a50c60e446..15178a02fa68 100644 --- a/usr.bin/grep/regex/fastmatch.h +++ b/usr.bin/grep/regex/fastmatch.h @@ -92,17 +92,4 @@ tre_fastwnexec(const fastmatch_t *preg, const wchar_t *string, size_t len, #define fastexec tre_fastexec #define fastwnexec tre_fastwnexec #define fastwexec tre_fastwexec -#define fixcomp tre_fixcomp -#define fastcomp tre_fastcomp -#define fastexec tre_fastexec -#define fastfree tre_fastfree -#define fixwcomp tre_fixwcomp -#define fastwcomp tre_fastwcomp -#define fastwexec tre_fastwexec -#define fixncomp tre_fixncomp -#define fastncomp tre_fastncomp -#define fastnexec tre_fastnexec -#define fixwncomp tre_fixwncomp -#define fastwncomp tre_fastwncomp -#define fastwnexec tre_fastwnexec #endif /* FASTMATCH_H */ diff --git a/usr.bin/gzip/Makefile.depend b/usr.bin/gzip/Makefile.depend index f3f02a165db1..2cba2abce257 100644 --- a/usr.bin/gzip/Makefile.depend +++ b/usr.bin/gzip/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/head/Makefile.depend b/usr.bin/head/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/head/Makefile.depend +++ b/usr.bin/head/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/hexdump/Makefile.depend b/usr.bin/hexdump/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/hexdump/Makefile.depend +++ b/usr.bin/hexdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/hexdump/tests/Makefile.depend b/usr.bin/hexdump/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/hexdump/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/hexdump/tests/hexdump_test.sh b/usr.bin/hexdump/tests/hexdump_test.sh index 400ccf3f7128..52b493f9f729 100755 --- a/usr.bin/hexdump/tests/hexdump_test.sh +++ b/usr.bin/hexdump/tests/hexdump_test.sh @@ -134,7 +134,6 @@ s_flag_head() } s_flag_body() { - atf_expect_fail "-s option is currently broken due to capsicum (PR 219173)" atf_check -o file:"$(atf_get_srcdir)/d_hexdump_sflag_a.out" \ hexdump -bs 4 "$(atf_get_srcdir)/d_hexdump_a.in" @@ -148,7 +147,6 @@ v_flag_head() } v_flag_body() { - atf_expect_fail "-s option is currently broken due to capsicum (PR 219173)" for i in $(seq 0 7); do atf_check -o match:"^\*$" \ hexdump -s ${i} "$(atf_get_srcdir)/d_hexdump_c.in" diff --git a/usr.bin/host/Makefile.depend b/usr.bin/host/Makefile.depend index 0c13258b0d9c..8c17f93c9a8e 100644 --- a/usr.bin/host/Makefile.depend +++ b/usr.bin/host/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/iconv/Makefile.depend b/usr.bin/iconv/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/iconv/Makefile.depend +++ b/usr.bin/iconv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/id/Makefile.depend b/usr.bin/id/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/id/Makefile.depend +++ b/usr.bin/id/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ident/Makefile.depend b/usr.bin/ident/Makefile.depend index f5d5993a161d..0ea507d1bbb6 100644 --- a/usr.bin/ident/Makefile.depend +++ b/usr.bin/ident/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/indent/Makefile.depend b/usr.bin/indent/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/indent/Makefile.depend +++ b/usr.bin/indent/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/indent/tests/Makefile.depend b/usr.bin/indent/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/indent/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/ipcrm/Makefile.depend b/usr.bin/ipcrm/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/usr.bin/ipcrm/Makefile.depend +++ b/usr.bin/ipcrm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ipcs/Makefile.depend b/usr.bin/ipcs/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/usr.bin/ipcs/Makefile.depend +++ b/usr.bin/ipcs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/iscsictl/Makefile.depend b/usr.bin/iscsictl/Makefile.depend index 6146f8608f72..4f526892ed67 100644 --- a/usr.bin/iscsictl/Makefile.depend +++ b/usr.bin/iscsictl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/join/Makefile.depend b/usr.bin/join/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/join/Makefile.depend +++ b/usr.bin/join/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/jot/Makefile.depend b/usr.bin/jot/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/jot/Makefile.depend +++ b/usr.bin/jot/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/kdump/Makefile b/usr.bin/kdump/Makefile index c91704efdeda..e1b9d4fd68a2 100644 --- a/usr.bin/kdump/Makefile +++ b/usr.bin/kdump/Makefile @@ -14,7 +14,7 @@ LIBADD= sysdecode LIBADD+= casper LIBADD+= cap_grp LIBADD+= cap_pwd -CFLAGS+=-DHAVE_LIBCASPER +CFLAGS+=-DWITH_CASPER .endif #NO_WERROR?= YES diff --git a/usr.bin/kdump/Makefile.depend b/usr.bin/kdump/Makefile.depend index 59ec51a9b1d7..d0dd4584102c 100644 --- a/usr.bin/kdump/Makefile.depend +++ b/usr.bin/kdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 005fdefc5508..986c7fe78acd 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER #include #endif #include @@ -80,7 +80,7 @@ __FBSDID("$FreeBSD$"); #include #include "ktrace.h" -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER #include #include @@ -164,7 +164,7 @@ struct proc_info static TAILQ_HEAD(trace_procs, proc_info) trace_procs; -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER static cap_channel_t *cappwd, *capgrp; #endif @@ -193,7 +193,7 @@ localtime_init(void) (void)localtime(<ime); } -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER static int cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) { @@ -235,7 +235,7 @@ cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) *capgrpp = capgrploc; return (0); } -#endif /* HAVE_LIBCASPER */ +#endif /* WITH_CASPER */ static void print_integer_arg(const char *(*decoder)(int), int value) @@ -443,7 +443,7 @@ main(int argc, char *argv[]) strerror_init(); localtime_init(); -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (resolv != 0) { if (cappwdgrp_setup(&cappwd, &capgrp) < 0) { cappwd = NULL; @@ -1874,7 +1874,7 @@ ktrstat(struct stat *statp) if (resolv == 0) { pwd = NULL; } else { -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (cappwd != NULL) pwd = cap_getpwuid(cappwd, statp->st_uid); else @@ -1888,7 +1888,7 @@ ktrstat(struct stat *statp) if (resolv == 0) { grp = NULL; } else { -#ifdef HAVE_LIBCASPER +#ifdef WITH_CASPER if (capgrp != NULL) grp = cap_getgrgid(capgrp, statp->st_gid); else diff --git a/usr.bin/keylogin/Makefile.depend b/usr.bin/keylogin/Makefile.depend index c8383bd76e80..5b0587ae477a 100644 --- a/usr.bin/keylogin/Makefile.depend +++ b/usr.bin/keylogin/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/keylogout/Makefile.depend b/usr.bin/keylogout/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.bin/keylogout/Makefile.depend +++ b/usr.bin/keylogout/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/killall/Makefile.depend b/usr.bin/killall/Makefile.depend index 41ef6ecb240d..832aef499286 100644 --- a/usr.bin/killall/Makefile.depend +++ b/usr.bin/killall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ktrace/Makefile.depend b/usr.bin/ktrace/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/ktrace/Makefile.depend +++ b/usr.bin/ktrace/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ktrdump/Makefile.depend b/usr.bin/ktrdump/Makefile.depend index 8b8697b239e0..1ff7af5cf330 100644 --- a/usr.bin/ktrdump/Makefile.depend +++ b/usr.bin/ktrdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lam/Makefile.depend b/usr.bin/lam/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/lam/Makefile.depend +++ b/usr.bin/lam/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/last/Makefile.depend b/usr.bin/last/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/last/Makefile.depend +++ b/usr.bin/last/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lastcomm/Makefile.depend b/usr.bin/lastcomm/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/lastcomm/Makefile.depend +++ b/usr.bin/lastcomm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ldd/Makefile.depend b/usr.bin/ldd/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/ldd/Makefile.depend +++ b/usr.bin/ldd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/leave/Makefile.depend b/usr.bin/leave/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/leave/Makefile.depend +++ b/usr.bin/leave/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/less/Makefile.depend b/usr.bin/less/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/less/Makefile.depend +++ b/usr.bin/less/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lessecho/Makefile.depend b/usr.bin/lessecho/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/lessecho/Makefile.depend +++ b/usr.bin/lessecho/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lesskey/Makefile.depend b/usr.bin/lesskey/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/lesskey/Makefile.depend +++ b/usr.bin/lesskey/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lex/Makefile.depend b/usr.bin/lex/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/usr.bin/lex/Makefile.depend +++ b/usr.bin/lex/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/limits/Makefile.depend b/usr.bin/limits/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/limits/Makefile.depend +++ b/usr.bin/limits/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/locale/Makefile.depend b/usr.bin/locale/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/locale/Makefile.depend +++ b/usr.bin/locale/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/localedef/Makefile.depend b/usr.bin/localedef/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/usr.bin/localedef/Makefile.depend +++ b/usr.bin/localedef/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/locate/bigram/Makefile.depend b/usr.bin/locate/bigram/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/locate/bigram/Makefile.depend +++ b/usr.bin/locate/bigram/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/locate/code/Makefile.depend b/usr.bin/locate/code/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/locate/code/Makefile.depend +++ b/usr.bin/locate/code/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/locate/locate/Makefile.depend b/usr.bin/locate/locate/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/locate/locate/Makefile.depend +++ b/usr.bin/locate/locate/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/lock/Makefile.depend b/usr.bin/lock/Makefile.depend index 4d4fe056ec40..931a9e5f35c5 100644 --- a/usr.bin/lock/Makefile.depend +++ b/usr.bin/lock/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lock/lock.c b/usr.bin/lock/lock.c index 68e69a5b6e0d..5000aa672f7a 100644 --- a/usr.bin/lock/lock.c +++ b/usr.bin/lock/lock.c @@ -223,7 +223,7 @@ main(int argc, char **argv) if (usemine) { s[strlen(s) - 1] = '\0'; cryptpw = crypt(s, mypw); - if (cryptpw == NULL || !strcmp(mypw, cryptpw)) + if (cryptpw != NULL && !strcmp(mypw, cryptpw)) break; } else if (!strcmp(s, s1)) diff --git a/usr.bin/lockf/Makefile.depend b/usr.bin/lockf/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/lockf/Makefile.depend +++ b/usr.bin/lockf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/logger/Makefile.depend b/usr.bin/logger/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/logger/Makefile.depend +++ b/usr.bin/logger/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/login/Makefile.depend b/usr.bin/login/Makefile.depend index 85813bf9b52d..ec5c7b0ac3a1 100644 --- a/usr.bin/login/Makefile.depend +++ b/usr.bin/login/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/logins/Makefile.depend b/usr.bin/logins/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/logins/Makefile.depend +++ b/usr.bin/logins/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/logname/Makefile.depend b/usr.bin/logname/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/logname/Makefile.depend +++ b/usr.bin/logname/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/look/Makefile.depend b/usr.bin/look/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/look/Makefile.depend +++ b/usr.bin/look/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lsvfs/Makefile.depend b/usr.bin/lsvfs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/lsvfs/Makefile.depend +++ b/usr.bin/lsvfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/lzmainfo/Makefile.depend b/usr.bin/lzmainfo/Makefile.depend index 987c48738e8a..c02c88a2cd25 100644 --- a/usr.bin/lzmainfo/Makefile.depend +++ b/usr.bin/lzmainfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/m4/Makefile.depend b/usr.bin/m4/Makefile.depend index d97824aedd83..6fd1ab689225 100644 --- a/usr.bin/m4/Makefile.depend +++ b/usr.bin/m4/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mail/Makefile.depend b/usr.bin/mail/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/mail/Makefile.depend +++ b/usr.bin/mail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh index f92dea9db844..7d021d78f260 100755 --- a/usr.bin/man/man.sh +++ b/usr.bin/man/man.sh @@ -333,7 +333,7 @@ man_display_page() { if [ -n "$use_width" ]; then mandoc_args="-O width=${use_width}" fi - testline="mandoc -Tlint -Wunsupp 2>/dev/null" + testline="mandoc -Tlint -Wunsupp >/dev/null 2>&1" if [ -n "$tflag" ]; then pipeline="mandoc -Tps $mandoc_args" else diff --git a/usr.bin/mandoc/Makefile.depend b/usr.bin/mandoc/Makefile.depend index 1fe4610a2f03..858582db5662 100644 --- a/usr.bin/mandoc/Makefile.depend +++ b/usr.bin/mandoc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mesg/Makefile.depend b/usr.bin/mesg/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/mesg/Makefile.depend +++ b/usr.bin/mesg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/minigzip/Makefile.depend b/usr.bin/minigzip/Makefile.depend index d209adbd4ff2..9a8221bf3321 100644 --- a/usr.bin/minigzip/Makefile.depend +++ b/usr.bin/minigzip/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ministat/Makefile.depend b/usr.bin/ministat/Makefile.depend index d56ccd254179..ca713780ce7f 100644 --- a/usr.bin/ministat/Makefile.depend +++ b/usr.bin/ministat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mkcsmapper/Makefile.depend b/usr.bin/mkcsmapper/Makefile.depend index 75e27669e9f3..f2071f254a6b 100644 --- a/usr.bin/mkcsmapper/Makefile.depend +++ b/usr.bin/mkcsmapper/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/mkcsmapper/mkcsmapper.1 b/usr.bin/mkcsmapper/mkcsmapper.1 index ede990e2d525..89941827e35e 100644 --- a/usr.bin/mkcsmapper/mkcsmapper.1 +++ b/usr.bin/mkcsmapper/mkcsmapper.1 @@ -29,8 +29,8 @@ .\" Electrical and Electronics Engineers, Inc and The Open Group. In the .\" event of any discrepancy between this version and the original IEEE and .\" The Open Group Standard, the original IEEE and The Open Group Standard is -.\" the referee document. The original Standard can be obtained online at -.\" http://www.opengroup.org/unix/online.html. +.\" the referee document. The original Standard can be obtained at +.\" http://www.opengroup.org/standards/unix. .\" .\" $FreeBSD$ .\" diff --git a/usr.bin/mkcsmapper_static/Makefile.depend b/usr.bin/mkcsmapper_static/Makefile.depend index 75e27669e9f3..f2071f254a6b 100644 --- a/usr.bin/mkcsmapper_static/Makefile.depend +++ b/usr.bin/mkcsmapper_static/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/mkesdb/Makefile.depend b/usr.bin/mkesdb/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/usr.bin/mkesdb/Makefile.depend +++ b/usr.bin/mkesdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mkesdb_static/Makefile.depend b/usr.bin/mkesdb_static/Makefile.depend index 75e27669e9f3..f2071f254a6b 100644 --- a/usr.bin/mkesdb_static/Makefile.depend +++ b/usr.bin/mkesdb_static/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/mkfifo/Makefile.depend b/usr.bin/mkfifo/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/mkfifo/Makefile.depend +++ b/usr.bin/mkfifo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mkimg/Makefile.depend b/usr.bin/mkimg/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/mkimg/Makefile.depend +++ b/usr.bin/mkimg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mklocale/Makefile.depend b/usr.bin/mklocale/Makefile.depend index 75e27669e9f3..f2071f254a6b 100644 --- a/usr.bin/mklocale/Makefile.depend +++ b/usr.bin/mklocale/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/mkstr/Makefile.depend b/usr.bin/mkstr/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/mkstr/Makefile.depend +++ b/usr.bin/mkstr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mktemp/Makefile.depend b/usr.bin/mktemp/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/mktemp/Makefile.depend +++ b/usr.bin/mktemp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mkuzip/Makefile.depend b/usr.bin/mkuzip/Makefile.depend index b485aca179ec..562bfa7a8a33 100644 --- a/usr.bin/mkuzip/Makefile.depend +++ b/usr.bin/mkuzip/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/morse/Makefile.depend b/usr.bin/morse/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/morse/Makefile.depend +++ b/usr.bin/morse/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/msgs/Makefile.depend b/usr.bin/msgs/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/msgs/Makefile.depend +++ b/usr.bin/msgs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mt/Makefile.depend b/usr.bin/mt/Makefile.depend index 81381e27a355..1cb7c6b18e99 100644 --- a/usr.bin/mt/Makefile.depend +++ b/usr.bin/mt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/mt/mt.1 b/usr.bin/mt/mt.1 index 73ce0978d563..287be2ee7f64 100644 --- a/usr.bin/mt/mt.1 +++ b/usr.bin/mt/mt.1 @@ -29,7 +29,7 @@ .\" @(#)mt.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd August 11, 2017 +.Dd November 3, 2017 .Dt MT 1 .Os .Sh NAME @@ -522,6 +522,7 @@ Value Width Tracks Density Code Type Reference Note 0x58 12.7 (0.5) 1280 15,142 (384,607) C LTO-5 0x5A 12.7 (0.5) 2176 15,142 (384,607) C LTO-6 0x5C 12.7 (0.5) 3584 19,107 (485,318) C LTO-7 +0x5D 12.7 (0.5) 5376 19,107 (485,318) C LTO-M8 14 0x5E 12.7 (0.5) 6656 20,669 (524,993) C LTO-8 0x71 12.7 (0.5) 512 11,800 (299,720) C 3592A1 (encrypted) 0x72 12.7 (0.5) 896 11,800 (299,720) C 3592A2 (encrypted) @@ -565,6 +566,10 @@ NOTES 12. This is Exabyte 8500 uncompressed format. The compressed format density code is 0x8c. 13. This density code (0x48) was also used for DAT-160. +14. Officially known as LTO-8 Type M, abbreviated M8. This is a pristine + LTO-7 cartridge initialized with a higher density format by an LTO-8 + drive. It cannot be read by an LTO-7 drive. Uncompressed capacity + is 9TB, compared to 6TB for LTO-7 and 12TB for LTO-8. .Ed .Bd -literal -offset 2n NOTE ON QIC STREAMERS diff --git a/usr.bin/nc/Makefile.depend b/usr.bin/nc/Makefile.depend index 27cbf261b843..b78c121a5f29 100644 --- a/usr.bin/nc/Makefile.depend +++ b/usr.bin/nc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/ncal/Makefile.depend b/usr.bin/ncal/Makefile.depend index 1841f7d974f0..ab7455b54eda 100644 --- a/usr.bin/ncal/Makefile.depend +++ b/usr.bin/ncal/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/netstat/Makefile.depend b/usr.bin/netstat/Makefile.depend index 27fa66073706..24bc82b4284b 100644 --- a/usr.bin/netstat/Makefile.depend +++ b/usr.bin/netstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index d0c56006b0e3..03c779dcad70 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include @@ -172,7 +173,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso) xso->xso_family = domain.dom_family; xso->so_timeo = so->so_timeo; xso->so_error = so->so_error; - if (SOLISTENING(so)) { + if ((so->so_options & SO_ACCEPTCONN) != 0) { xso->so_qlen = so->sol_qlen; xso->so_incqlen = so->sol_incqlen; xso->so_qlimit = so->sol_qlimit; diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c index dc3ad829ef62..68ebcf7eff0a 100644 --- a/usr.bin/netstat/netgraph.c +++ b/usr.bin/netstat/netgraph.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include #include diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c index 3b83f2ca006a..34e6b3977b1f 100644 --- a/usr.bin/netstat/unix.c +++ b/usr.bin/netstat/unix.c @@ -43,10 +43,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include #include #include +#define _WANT_UNPCB #include #include @@ -100,7 +102,7 @@ static int pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) { struct unp_head head; - struct unpcb *unp, unp_conn; + struct unpcb *unp, unp0, unp_conn; u_char sun_len; struct socket so; struct xunpgen xug; @@ -150,8 +152,8 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) KREAD(head_off, &head, sizeof(head)); LIST_FOREACH(unp, &head, unp_link) { xu.xu_unpp = unp; - KREAD(unp, &xu.xu_unp, sizeof (*unp)); - unp = &xu.xu_unp; + KREAD(unp, &unp0, sizeof (*unp)); + unp = &unp0; if (unp->unp_gencnt > unp_gencnt) continue; @@ -236,7 +238,7 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, so = &xunp->xu_socket; /* Ignore PCBs which were freed during copyout. */ - if (xunp->xu_unp.unp_gencnt > oxug->xug_gen) + if (xunp->unp_gencnt > oxug->xug_gen) continue; if (*first) { xo_open_list("socket"); @@ -268,7 +270,6 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, static void unixdomainpr(struct xunpcb *xunp, struct xsocket *so) { - struct unpcb *unp; struct sockaddr_un *sa; static int first = 1; char buf1[33]; @@ -292,11 +293,7 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) }; int fmt = (sizeof(void *) == 8) ? 1 : 0; - unp = &xunp->xu_unp; - if (unp->unp_addr) - sa = &xunp->xu_addr; - else - sa = (struct sockaddr_un *)0; + sa = (xunp->xu_addr.sun_family == AF_UNIX) ? &xunp->xu_addr : NULL; if (first && !Lflag) { xo_emit("{T:Active UNIX domain sockets}\n"); @@ -318,10 +315,9 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) } else { xo_emit(format[fmt], (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc, - so->so_snd.sb_cc, (long)unp->unp_vnode, - (long)unp->unp_conn, - (long)LIST_FIRST(&unp->unp_refs), - (long)LIST_NEXT(unp, unp_reflink)); + so->so_snd.sb_cc, (long)xunp->unp_vnode, + (long)xunp->unp_conn, (long)xunp->xu_firstref, + (long)xunp->xu_nextref); } if (sa) xo_emit(" {:path/%.*s}", diff --git a/usr.bin/newgrp/Makefile.depend b/usr.bin/newgrp/Makefile.depend index d8297c28fac7..10a95e7fdc38 100644 --- a/usr.bin/newgrp/Makefile.depend +++ b/usr.bin/newgrp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/newkey/Makefile.depend b/usr.bin/newkey/Makefile.depend index bae15c2d809d..97ec617dcc81 100644 --- a/usr.bin/newkey/Makefile.depend +++ b/usr.bin/newkey/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/nfsstat/Makefile.depend b/usr.bin/nfsstat/Makefile.depend index 270f59a1f4bb..4ea94319c964 100644 --- a/usr.bin/nfsstat/Makefile.depend +++ b/usr.bin/nfsstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/nice/Makefile.depend b/usr.bin/nice/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/nice/Makefile.depend +++ b/usr.bin/nice/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/nl/Makefile.depend b/usr.bin/nl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/nl/Makefile.depend +++ b/usr.bin/nl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/nm/Makefile.depend b/usr.bin/nm/Makefile.depend index 20f498cfb39b..c3f78dbc4cb6 100644 --- a/usr.bin/nm/Makefile.depend +++ b/usr.bin/nm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/nohup/Makefile.depend b/usr.bin/nohup/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/nohup/Makefile.depend +++ b/usr.bin/nohup/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/numactl/Makefile.depend b/usr.bin/numactl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/numactl/Makefile.depend +++ b/usr.bin/numactl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/number/Makefile.depend b/usr.bin/number/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/number/Makefile.depend +++ b/usr.bin/number/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/opieinfo/Makefile.depend b/usr.bin/opieinfo/Makefile.depend index 0466610b7034..bf6e70e24fc5 100644 --- a/usr.bin/opieinfo/Makefile.depend +++ b/usr.bin/opieinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/opiekey/Makefile.depend b/usr.bin/opiekey/Makefile.depend index 0466610b7034..bf6e70e24fc5 100644 --- a/usr.bin/opiekey/Makefile.depend +++ b/usr.bin/opiekey/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/opiepasswd/Makefile.depend b/usr.bin/opiepasswd/Makefile.depend index 0466610b7034..bf6e70e24fc5 100644 --- a/usr.bin/opiepasswd/Makefile.depend +++ b/usr.bin/opiepasswd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/pamtest/Makefile.depend b/usr.bin/pamtest/Makefile.depend index 916227df0bfd..3abafe3d350c 100644 --- a/usr.bin/pamtest/Makefile.depend +++ b/usr.bin/pamtest/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/passwd/Makefile.depend b/usr.bin/passwd/Makefile.depend index 1078f3391c30..5fb710255efc 100644 --- a/usr.bin/passwd/Makefile.depend +++ b/usr.bin/passwd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/paste/Makefile.depend b/usr.bin/paste/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/paste/Makefile.depend +++ b/usr.bin/paste/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/patch/Makefile.depend b/usr.bin/patch/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/patch/Makefile.depend +++ b/usr.bin/patch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c index 24e09ed304ad..204b1146b94c 100644 --- a/usr.bin/patch/patch.c +++ b/usr.bin/patch/patch.c @@ -1026,6 +1026,9 @@ patch_match(LINENUM base, LINENUM offset, LINENUM fuzz) const char *plineptr; unsigned short plinelen; + /* Patch does not match if we don't have anymore context to use */ + if (pline > pat_lines) + return false; for (iline = base + offset + fuzz; pline <= pat_lines; pline++, iline++) { ilineptr = ifetch(iline, offset >= 0); if (ilineptr == NULL) diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index 563c539b5686..d9087bb32391 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1135,7 +1135,12 @@ another_hunk(void) if (*buf != '>') fatal("> expected at line %ld of patch\n", p_input_line); - p_line[i] = savestr(buf + 2); + /* Don't overrun if we don't have enough line */ + if (len > 2) + p_line[i] = savestr(buf + 2); + else + p_line[i] = savestr(""); + if (out_of_mem) { p_end = i - 1; return false; diff --git a/usr.bin/pathchk/Makefile.depend b/usr.bin/pathchk/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/pathchk/Makefile.depend +++ b/usr.bin/pathchk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/perror/Makefile.depend b/usr.bin/perror/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/perror/Makefile.depend +++ b/usr.bin/perror/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/pom/Makefile.depend b/usr.bin/pom/Makefile.depend index d56ccd254179..ca713780ce7f 100644 --- a/usr.bin/pom/Makefile.depend +++ b/usr.bin/pom/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/pr/Makefile.depend b/usr.bin/pr/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/pr/Makefile.depend +++ b/usr.bin/pr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/pr/tests/Makefile.depend b/usr.bin/pr/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/pr/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/primes/Makefile.depend b/usr.bin/primes/Makefile.depend index c9f9d52f6e26..905e67cc66c9 100644 --- a/usr.bin/primes/Makefile.depend +++ b/usr.bin/primes/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/printenv/Makefile.depend b/usr.bin/printenv/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/printenv/Makefile.depend +++ b/usr.bin/printenv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/printf/Makefile.depend b/usr.bin/printf/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/printf/Makefile.depend +++ b/usr.bin/printf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/proccontrol/Makefile.depend b/usr.bin/proccontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/proccontrol/Makefile.depend +++ b/usr.bin/proccontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/procstat/Makefile.depend b/usr.bin/procstat/Makefile.depend index 5260cce40b48..8707112a6300 100644 --- a/usr.bin/procstat/Makefile.depend +++ b/usr.bin/procstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index 9f401d4f08d5..14b0e1eba17b 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 26, 2017 +.Dd October 14, 2017 .Dt PROCSTAT 1 .Os .Sh NAME @@ -34,14 +34,75 @@ .Sh SYNOPSIS .Nm .Op Fl -libxo -.Op Fl CHhn +.Op Fl h .Op Fl M Ar core .Op Fl N Ar system .Op Fl w Ar interval -.Op Fl b | c | e | f | i | j | k | l | L | r | s | S | t | v | x -.Op Fl a | Ar pid | Ar core ... +.Ar command +.Op Ar pid ... | Ar core ... +.Nm +.Op Fl -libxo +.Fl a +.Op Fl h +.Op Fl M Ar core +.Op Fl N Ar system +.Op Fl w Ar interval +.Ar command +.Nm +.Op Fl -libxo +.Op Fl h +.Op Fl M Ar core +.Op Fl N Ar system +.Op Fl w Ar interval +.Oo +.Fl b | +.Fl c | +.Fl e | +.Fl f Oo Fl C Oc | +.Fl i Oo Fl n Oc | +.Fl j Oo Fl n Oc | +.Fl k Oo Fl k Oc | +.Fl l | +.Fl r Oo Fl H Oc | +.Fl s | +.Fl S | +.Fl t | +.Fl v | +.Fl x +.Oc +.Op Ar pid ... | Ar core ... +.Nm +.Op Fl -libxo +.Fl a +.Op Fl h +.Op Fl M Ar core +.Op Fl N Ar system +.Op Fl w Ar interval +.Oo +.Fl b | +.Fl c | +.Fl e | +.Fl f Oo Fl C Oc | +.Fl i Oo Fl n Oc | +.Fl j Oo Fl n Oc | +.Fl k Oo Fl k Oc | +.Fl l | +.Fl r Oo Fl H Oc | +.Fl s | +.Fl S | +.Fl t | +.Fl v | +.Fl x +.Oc +.Nm +.Op Fl -libxo +.Fl L +.Op Fl h +.Op Fl M Ar core +.Op Fl N Ar system +.Op Fl w Ar interval +.Ar core ... .Sh DESCRIPTION -The .Nm utility displays detailed information about the processes identified by the .Ar pid @@ -51,49 +112,89 @@ flag is used, all processes. It can also display information extracted from a process core file, if the core file is specified as the argument. .Pp -By default, basic process statistics are printed; one of the following -options may be specified in order to select more detailed process information -for printing: -.Bl -tag -width indent -.It Fl -libxo -Generate output via +If the +.Fl -libxo +flag is specified the output is generated via .Xr libxo 3 in a selection of different human and machine readable formats. See .Xr xo_parse_args 3 for details on command line arguments. -.It Fl b +.Pp +The following commands are available: +.Bl -tag -width indent +.It Ar basic +Print basic process statistics (this is the default). +.It Ar binary | Fl b Display binary information for the process. -.It Fl c +.Pp +Substring commands are accepted. +.It Ar argument(s) | Fl c Display command line arguments for the process. -.It Fl e +.Pp +Substring commands are accepted. +.It Ar environment | Fl e Display environment variables for the process. -.It Fl f +.Pp +Substring commands are accepted. +.It Ar file(s) | Ar fd(s) | Fl f Display file descriptor information for the process. -.It Fl i +.Pp +If the +.Fl C +subcommand flag is used then additional capability information is printed. +.It Ar signal(s) | Fl i Display signal pending and disposition information for the process. -.It Fl j +.Pp +If the +.Fl n +subcommand option is used, the signal numbers are shown instead of signal +names. +.Pp +Substring commands are accepted. +.It Ar tsignal(s) | Fl j Display signal pending and blocked information for the process's threads. -.It Fl k +.Pp +If the +.Fl n +subcommand option is used, the signal numbers are shown instead of signal +names. +.Pp +Substring commands are accepted. +.It Ar kstack | Fl k Display the stacks of kernel threads in the process, excluding stacks of threads currently running on a CPU and threads with stacks swapped to disk. -If the flag is repeated, function offsets as well as function names are -printed. -.It Fl l +.Pp +If the +.Fl v +subcommand option is used (or the command flag is repeated), function +offsets as well as function names are printed. +.It Ar rlimit | Fl l Display resource limits for the process. -.It Fl L +.It Ar ptlwpinfo | Fl L Display LWP info for the process pertaining to its signal driven exit. -.It Fl r +.It Ar rusage | Fl r Display resource usage information for the process. -.It Fl s +.Pp +If the +.Fl v +.Pq or Fl H +subcommand flag +is used then per-thread statistics are printed, rather than per-process +statistics. +The second field in the table will list the thread ID to which the row of +information corresponds. +.It Ar credential(s) | Fl s Display security credential information for the process. -.It Fl S +.Pp +Substring commands are accepted. +.It Ar cpuset | Ar cs | Fl S Display the cpuset information for the thread. -.It Fl t +.It Ar thread(s) | Fl t Display thread information for the process. -.It Fl v +.It Ar vm | Fl v Display virtual memory mappings for the process. -.It Fl x +.It Ar auxv | Fl x Display ELF auxiliary vector for the process. .El .Pp @@ -111,23 +212,6 @@ If the .Fl w flag is not specified, the output will not repeat. .Pp -The -.Fl C -flag requests the printing of additional capability information in the file -descriptor view. -.Pp -The -.Fl H -flag may be used to request per-thread statistics rather than per-process -statistics for some options. -For those options, the second field in the table will list the thread ID -to which the row of information corresponds. -The -.Fl H -flag is implied for the -.Fl S -mode. -.Pp Information for VM, file descriptor, and cpuset options is available only to the owner of a process or the superuser. A cpuset value displayed as -1 means that the information is either invalid @@ -212,6 +296,8 @@ shared memory kqueue .It m message queue +.It P +process descriptor .It p pipe .It s diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index 375664119821..7ab9ba458aea 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -42,37 +42,111 @@ #include "procstat.h" -static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag; -static int lflag, Lflag, rflag, sflag, tflag, vflag, xflag, Sflag; -int hflag, nflag, Cflag, Hflag; +enum { + PS_CMP_NORMAL = 0x00, + PS_CMP_PLURAL = 0x01, + PS_CMP_SUBSTR = 0x02 +}; + +struct procstat_cmd { + const char *command; + const char *xocontainer; + const char *usage; + void (*cmd)(struct procstat *, struct kinfo_proc *); + void (*opt)(int, char * const *); + int cmp; +}; + +int procstat_opts = 0; + +static void cmdopt_none(int argc, char * const argv[]); +static void cmdopt_verbose(int argc, char * const argv[]); +static void cmdopt_signals(int argc, char * const argv[]); +static void cmdopt_rusage(int argc, char * const argv[]); +static void cmdopt_files(int argc, char * const argv[]); +static void cmdopt_cpuset(int argc, char * const argv[]); + +static const struct procstat_cmd cmd_table[] = { + { "argument", "arguments", NULL, &procstat_args, &cmdopt_none, + PS_CMP_PLURAL | PS_CMP_SUBSTR }, + { "auxv", "auxv", NULL, &procstat_auxv, &cmdopt_none, PS_CMP_NORMAL }, + { "basic", "basic", NULL, &procstat_basic, &cmdopt_none, + PS_CMP_NORMAL }, + { "binary", "binary", NULL, &procstat_bin, &cmdopt_none, + PS_CMP_SUBSTR }, + { "cpuset", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, + { "cs", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, + { "credential", "credentials", NULL, &procstat_cred, &cmdopt_none, + PS_CMP_PLURAL | PS_CMP_SUBSTR }, + { "environment", "environment", NULL, &procstat_env, &cmdopt_none, + PS_CMP_SUBSTR }, + { "fd", "files", "[-C]", &procstat_files, &cmdopt_files, + PS_CMP_PLURAL }, + { "file", "files", "[-C]", &procstat_files, &cmdopt_files, + PS_CMP_PLURAL }, + { "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose, + PS_CMP_NORMAL }, + { "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo, &cmdopt_none, + PS_CMP_NORMAL }, + { "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none, + PS_CMP_NORMAL }, + { "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage, + PS_CMP_NORMAL }, + { "signal", "signals", "[-n]", &procstat_sigs, &cmdopt_signals, + PS_CMP_PLURAL | PS_CMP_SUBSTR }, + { "thread", "threads", NULL, &procstat_threads, &cmdopt_none, + PS_CMP_PLURAL }, + { "tsignal", "thread_signals", "[-n]", &procstat_threads_sigs, + &cmdopt_signals, PS_CMP_PLURAL | PS_CMP_SUBSTR }, + { "vm", "vm", NULL, &procstat_vm, &cmdopt_none, PS_CMP_NORMAL } +}; static void usage(void) { + size_t i, l; + int multi; - xo_error( - "usage: procstat [--libxo] [-Hhn] [-M core] " - "[-N system] [-w interval]\n" - " [-S | -b | -c | -e | -i | -j | -k | -kk | " - "-l | -r | -s | \n" - " -t | -v | -x]\n" - " [-a | pid ... | core ...]\n" - " procstat [--libxo] -Cf [-hn] [-M core] " - "[-N system] [-a | pid ... | core ...]\n" - " [-S | -b | -c | -e | -i | -j | -k | -kk | " - "-l | -r | -s | \n" - " procstat [--libxo] -L [-hn] [-M core] " - "[-N system] [-w interval]\n" - " [-S | -b | -c | -e | -i | -j | -k | -kk | " - "-l | -r | -s | \n" - " -t | -v | -x]\n" - " [core ...]\n"); + xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]" + " [-w interval] command\n" + " [pid ... | core ...]\n" + " procstat [--libxo] -a [-h] [-M core] [-N system] " + " [-w interval] command\n" + " procstat [--libxo] [-h] [-M core] [-N system]" + " [-w interval]\n" + " [-S | -b | -c | -e | -f [-C] | -i [-n] | " + "-j [-n] | -k [-k] |\n" + " -l | -r [-H] | -s | -t | -v | -x] " + "[pid ... | core ...]\n" + " procstat [--libxo] -a [-h] [-M core] [-N system]" + " [-w interval]\n" + " [-S | -b | -c | -e | -f [-C] | -i [-n] | " + "-j [-n] | -k [-k] |\n" + " -l | -r [-H] | -s | -t | -v | -x]\n" + " procstat [--libxo] -L [-h] [-M core] [-N system] core ...\n" + "Available commands:\n"); + for (i = 0, l = nitems(cmd_table); i < l; i++) { + multi = i + 1 < l && cmd_table[i].cmd == cmd_table[i + 1].cmd; + xo_error(" %s%s%s", multi ? "[" : "", + cmd_table[i].command, (cmd_table[i].cmp & PS_CMP_PLURAL) ? + "(s)" : ""); + for (; i + 1 < l && cmd_table[i].cmd == cmd_table[i + 1].cmd; + i++) + xo_error(" | %s%s", cmd_table[i + 1].command, + (cmd_table[i].cmp & PS_CMP_PLURAL) ? "(s)" : ""); + if (multi) + xo_error("]"); + if (cmd_table[i].usage != NULL) + xo_error(" %s", cmd_table[i].usage); + xo_error("\n"); + } xo_finish(); exit(EX_USAGE); } static void -procstat(struct procstat *prstat, struct kinfo_proc *kipp) +procstat(const struct procstat_cmd *cmd, struct procstat *prstat, + struct kinfo_proc *kipp) { char *pidstr = NULL; @@ -80,40 +154,7 @@ procstat(struct procstat *prstat, struct kinfo_proc *kipp) if (pidstr == NULL) xo_errc(1, ENOMEM, "Failed to allocate memory in procstat()"); xo_open_container(pidstr); - - if (bflag) - procstat_bin(prstat, kipp); - else if (cflag) - procstat_args(prstat, kipp); - else if (eflag) - procstat_env(prstat, kipp); - else if (fflag) - procstat_files(prstat, kipp); - else if (iflag) - procstat_sigs(prstat, kipp); - else if (jflag) - procstat_threads_sigs(prstat, kipp); - else if (kflag) - procstat_kstack(prstat, kipp, kflag); - else if (lflag) - procstat_rlimit(prstat, kipp); - else if (Lflag) - procstat_ptlwpinfo(prstat); - else if (rflag) - procstat_rusage(prstat, kipp); - else if (sflag) - procstat_cred(prstat, kipp); - else if (tflag) - procstat_threads(prstat, kipp); - else if (vflag) - procstat_vm(prstat, kipp); - else if (xflag) - procstat_auxv(prstat, kipp); - else if (Sflag) - procstat_cs(prstat, kipp); - else - procstat_basic(kipp); - + cmd->cmd(prstat, kipp); xo_close_container(pidstr); free(pidstr); } @@ -157,122 +198,158 @@ kinfo_proc_thread_name(const struct kinfo_proc *kipp) return (name); } +static const struct procstat_cmd * +getcmd(const char *str) +{ + const struct procstat_cmd *cmd; + size_t i, l; + int cmp, s; + + if (str == NULL) + return (NULL); + cmd = NULL; + if ((l = strlen(str)) == 0) + return (getcmd("basic")); + s = l > 1 && strcasecmp(str + l - 1, "s") == 0; + for (i = 0; i < nitems(cmd_table); i++) { + /* + * After the first match substring matches are disabled, + * allowing subsequent full matches to take precedence. + */ + if (cmd == NULL && (cmd_table[i].cmp & PS_CMP_SUBSTR)) + cmp = strncasecmp(str, cmd_table[i].command, l - + ((cmd_table[i].cmp & PS_CMP_PLURAL) && s ? 1 : 0)); + else if ((cmd_table[i].cmp & PS_CMP_PLURAL) && s && + l == strlen(cmd_table[i].command) + 1) + cmp = strncasecmp(str, cmd_table[i].command, l - 1); + else + cmp = strcasecmp(str, cmd_table[i].command); + if (cmp == 0) + cmd = &cmd_table[i]; + } + return (cmd); +} + int main(int argc, char *argv[]) { - int ch, interval, tmp; + int ch, interval; int i; struct kinfo_proc *p; + const struct procstat_cmd *cmd; struct procstat *prstat, *cprstat; long l; pid_t pid; char *dummy; char *nlistf, *memf; - const char *xocontainer; + int aflag; int cnt; interval = 0; + cmd = NULL; memf = nlistf = NULL; + aflag = 0; argc = xo_parse_args(argc, argv); - xocontainer = "basic"; while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) { switch (ch) { + case 'a': + aflag++; + break; + case 'b': + if (cmd != NULL) + usage(); + cmd = getcmd("binary"); + break; case 'C': - Cflag++; + procstat_opts |= PS_OPT_CAPABILITIES; + break; + case 'c': + if (cmd != NULL) + usage(); + cmd = getcmd("arguments"); + break; + case 'e': + if (cmd != NULL) + usage(); + cmd = getcmd("environment"); + break; + case 'f': + if (cmd != NULL) + usage(); + cmd = getcmd("files"); break; - case 'H': - Hflag++; + procstat_opts |= PS_OPT_PERTHREAD; + break; + case 'h': + procstat_opts |= PS_OPT_NOHEADER; + break; + case 'i': + if (cmd != NULL) + usage(); + cmd = getcmd("signals"); + break; + case 'j': + if (cmd != NULL) + usage(); + cmd = getcmd("tsignals"); + break; + case 'k': + if (cmd->cmd == procstat_kstack) { + if ((procstat_opts & PS_OPT_VERBOSE) != 0) + usage(); + procstat_opts |= PS_OPT_VERBOSE; + } else { + if (cmd != NULL) + usage(); + cmd = getcmd("kstack"); + } + break; + case 'L': + if (cmd != NULL) + usage(); + cmd = getcmd("ptlwpinfo"); + break; + case 'l': + if (cmd != NULL) + usage(); + cmd = getcmd("rlimit"); break; - case 'M': memf = optarg; break; case 'N': nlistf = optarg; break; - case 'S': - Sflag++; - xocontainer = "cs"; - break; - case 'a': - aflag++; - break; - - case 'b': - bflag++; - xocontainer = "binary"; - break; - - case 'c': - cflag++; - xocontainer = "arguments"; - break; - - case 'e': - eflag++; - xocontainer = "environment"; - break; - - case 'f': - fflag++; - xocontainer = "files"; - break; - - case 'i': - iflag++; - xocontainer = "signals"; - break; - - case 'j': - jflag++; - xocontainer = "thread_signals"; - break; - - case 'k': - kflag++; - xocontainer = "kstack"; - break; - - case 'l': - lflag++; - xocontainer = "rlimit"; - break; - - case 'L': - Lflag++; - xocontainer = "ptlwpinfo"; - break; - case 'n': - nflag++; + procstat_opts |= PS_OPT_SIGNUM; break; - - case 'h': - hflag++; - break; - case 'r': - rflag++; - xocontainer = "rusage"; + if (cmd != NULL) + usage(); + cmd = getcmd("rusage"); + break; + case 'S': + if (cmd != NULL) + usage(); + cmd = getcmd("cpuset"); break; - case 's': - sflag++; - xocontainer = "credentials"; + if (cmd != NULL) + usage(); + cmd = getcmd("credentials"); break; - case 't': - tflag++; - xocontainer = "threads"; + if (cmd != NULL) + usage(); + cmd = getcmd("threads"); break; - case 'v': - vflag++; - xocontainer = "vm"; + if (cmd != NULL) + usage(); + cmd = getcmd("vm"); break; - case 'w': l = strtol(optarg, &dummy, 10); if (*dummy != '\0') @@ -281,12 +358,11 @@ main(int argc, char *argv[]) usage(); interval = l; break; - case 'x': - xflag++; - xocontainer = "auxv"; + if (cmd != NULL) + usage(); + cmd = getcmd("auxv"); break; - case '?': default: usage(); @@ -296,24 +372,31 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - /* We require that either 0 or 1 mode flags be set. */ - tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) + - lflag + rflag + sflag + tflag + vflag + xflag + Sflag; - if (!(tmp == 0 || tmp == 1)) - usage(); - - /* We allow -k to be specified up to twice, but not more. */ - if (kflag > 2) - usage(); + if (cmd == NULL && argv[0] != NULL && (cmd = getcmd(argv[0])) != NULL) { + if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0) + usage(); + if (cmd->opt != NULL) { + optreset = 1; + optind = 1; + cmd->opt(argc, argv); + argc -= optind; + argv += optind; + } else { + argc -= 1; + argv += 1; + } + } else { + if (cmd == NULL) + cmd = getcmd("basic"); + if (cmd->cmd != procstat_files && + (procstat_opts & PS_OPT_CAPABILITIES) != 0) + usage(); + } /* Must specify either the -a flag or a list of pids. */ if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0)) usage(); - /* Only allow -C with -f. */ - if (Cflag && !fflag) - usage(); - if (memf != NULL) prstat = procstat_open_kvm(nlistf, memf); else @@ -323,7 +406,7 @@ main(int argc, char *argv[]) do { xo_set_version(PROCSTAT_XO_VERSION); xo_open_container("procstat"); - xo_open_container(xocontainer); + xo_open_container(cmd->xocontainer); if (aflag) { p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt); @@ -331,10 +414,10 @@ main(int argc, char *argv[]) xo_errx(1, "procstat_getprocs()"); kinfo_proc_sort(p, cnt); for (i = 0; i < cnt; i++) { - procstat(prstat, &p[i]); + procstat(cmd, prstat, &p[i]); /* Suppress header after first process. */ - hflag = 1; + procstat_opts |= PS_OPT_NOHEADER; xo_flush(); } procstat_freeprocs(prstat, p); @@ -351,7 +434,7 @@ main(int argc, char *argv[]) if (p == NULL) xo_errx(1, "procstat_getprocs()"); if (cnt != 0) - procstat(prstat, p); + procstat(cmd, prstat, p); procstat_freeprocs(prstat, p); } else { cprstat = procstat_open_core(argv[i]); @@ -364,15 +447,15 @@ main(int argc, char *argv[]) if (p == NULL) xo_errx(1, "procstat_getprocs()"); if (cnt != 0) - procstat(cprstat, p); + procstat(cmd, cprstat, p); procstat_freeprocs(cprstat, p); procstat_close(cprstat); } /* Suppress header after first process. */ - hflag = 1; + procstat_opts |= PS_OPT_NOHEADER; } - xo_close_container(xocontainer); + xo_close_container(cmd->xocontainer); xo_close_container("procstat"); xo_finish(); if (interval) @@ -383,3 +466,95 @@ main(int argc, char *argv[]) exit(0); } + +void +cmdopt_none(int argc, char * const argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "")) != -1) { + switch (ch) { + case '?': + default: + usage(); + } + } +} + +void +cmdopt_verbose(int argc, char * const argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "v")) != -1) { + switch (ch) { + case 'v': + procstat_opts |= PS_OPT_VERBOSE; + break; + case '?': + default: + usage(); + } + } +} + +void +cmdopt_signals(int argc, char * const argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "n")) != -1) { + switch (ch) { + case 'n': + procstat_opts |= PS_OPT_SIGNUM; + break; + case '?': + default: + usage(); + } + } +} + +void +cmdopt_rusage(int argc, char * const argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "Ht")) != -1) { + switch (ch) { + case 'H': + /* FALLTHROUGH */ + case 't': + procstat_opts |= PS_OPT_PERTHREAD; + break; + case '?': + default: + usage(); + } + } +} + +void +cmdopt_files(int argc, char * const argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "C")) != -1) { + switch (ch) { + case 'C': + procstat_opts |= PS_OPT_CAPABILITIES; + break; + case '?': + default: + usage(); + } + } +} + +void +cmdopt_cpuset(int argc, char * const argv[]) +{ + + procstat_opts |= PS_OPT_PERTHREAD; + cmdopt_none(argc, argv); +} diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h index dd35c9c796c7..c75018fc0908 100644 --- a/usr.bin/procstat/procstat.h +++ b/usr.bin/procstat/procstat.h @@ -35,7 +35,19 @@ #define PROCSTAT_XO_VERSION "1" -extern int hflag, nflag, Cflag, Hflag; +enum { + PS_OPT_CAPABILITIES = 0x01, + PS_OPT_NOHEADER = 0x02, + PS_OPT_PERTHREAD = 0x04, + PS_OPT_SIGNUM = 0x08, + PS_OPT_VERBOSE = 0x10 +}; + +#define PS_SUBCOMMAND_OPTS \ + (PS_OPT_CAPABILITIES | PS_OPT_SIGNUM | \ + PS_OPT_PERTHREAD | PS_OPT_VERBOSE) + +extern int procstat_opts; struct kinfo_proc; void kinfo_proc_sort(struct kinfo_proc *kipp, int count); @@ -43,15 +55,14 @@ const char * kinfo_proc_thread_name(const struct kinfo_proc *kipp); void procstat_args(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_auxv(struct procstat *prstat, struct kinfo_proc *kipp); -void procstat_basic(struct kinfo_proc *kipp); +void procstat_basic(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_cs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_env(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp); -void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp, - int kflag); -void procstat_ptlwpinfo(struct procstat *prstat); +void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp); +void procstat_ptlwpinfo(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp); diff --git a/usr.bin/procstat/procstat_args.c b/usr.bin/procstat/procstat_args.c index fd5f3d3b0738..b64364bd8d81 100644 --- a/usr.bin/procstat/procstat_args.c +++ b/usr.bin/procstat/procstat_args.c @@ -47,7 +47,7 @@ procstat_args(struct procstat *procstat, struct kinfo_proc *kipp) int i; char **args; - if (!hflag) { + if ((procstat_opts & PS_OPT_NOHEADER) == 0) { xo_emit("{T:/%5s %-16s %-53s}\n", "PID", "COMM", "ARGS"); } @@ -74,7 +74,7 @@ procstat_env(struct procstat *procstat, struct kinfo_proc *kipp) int i; char **envs; - if (!hflag) { + if ((procstat_opts & PS_OPT_NOHEADER) == 0) { xo_emit("{T:/%5s %-16s %-53s}\n", "PID", "COMM", "ENVIRONMENT"); } diff --git a/usr.bin/procstat/procstat_auxv.c b/usr.bin/procstat/procstat_auxv.c index f4a2265d762a..0c930cae9140 100644 --- a/usr.bin/procstat/procstat_auxv.c +++ b/usr.bin/procstat/procstat_auxv.c @@ -51,7 +51,7 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) u_int count, i; static char prefix[256]; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %-16s %-16s %-16s}\n", "PID", "COMM", "AUXV", "VALUE"); diff --git a/usr.bin/procstat/procstat_basic.c b/usr.bin/procstat/procstat_basic.c index 75bb7a8d9ef1..b5675248f88e 100644 --- a/usr.bin/procstat/procstat_basic.c +++ b/usr.bin/procstat/procstat_basic.c @@ -39,10 +39,10 @@ #include "procstat.h" void -procstat_basic(struct kinfo_proc *kipp) +procstat_basic(struct procstat *procstat __unused, struct kinfo_proc *kipp) { - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %5s %5s %5s %5s %3s %-8s %-9s %-13s %-12s}\n", "PID", "PPID", "PGID", "SID", "TSID", "THR", "LOGIN", "WCHAN", "EMUL", "COMM"); diff --git a/usr.bin/procstat/procstat_bin.c b/usr.bin/procstat/procstat_bin.c index 8b2b8a14be8b..800775f3efe7 100644 --- a/usr.bin/procstat/procstat_bin.c +++ b/usr.bin/procstat/procstat_bin.c @@ -46,7 +46,7 @@ procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp) int osrel; static char pathname[PATH_MAX]; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %-16s %8s %s}\n", "PID", "COMM", "OSREL", "PATH"); diff --git a/usr.bin/procstat/procstat_cred.c b/usr.bin/procstat/procstat_cred.c index 940c952a8324..dbc0831233d3 100644 --- a/usr.bin/procstat/procstat_cred.c +++ b/usr.bin/procstat/procstat_cred.c @@ -48,7 +48,7 @@ procstat_cred(struct procstat *procstat, struct kinfo_proc *kipp) unsigned int i, ngroups; gid_t *groups; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %-16s %5s %5s %5s %5s %5s %5s %5s %5s %-15s}\n", "PID", "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID", "SVGID", "UMASK", "FLAGS", "GROUPS"); diff --git a/usr.bin/procstat/procstat_cs.c b/usr.bin/procstat/procstat_cs.c index 8af912edb749..7b8a61645be4 100644 --- a/usr.bin/procstat/procstat_cs.c +++ b/usr.bin/procstat/procstat_cs.c @@ -52,7 +52,7 @@ procstat_cs(struct procstat *procstat, struct kinfo_proc *kipp) unsigned int count, i; int once, twice, lastcpu, cpu; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s}\n", "PID", "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK"); diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c index 373f413e3b60..25ae8ae26d58 100644 --- a/usr.bin/procstat/procstat_files.c +++ b/usr.bin/procstat/procstat_files.c @@ -303,7 +303,8 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) */ capwidth = 0; head = procstat_getfiles(procstat, kipp, 0); - if (head != NULL && Cflag) { + if (head != NULL && + (procstat_opts & PS_OPT_CAPABILITIES) != 0) { STAILQ_FOREACH(fst, head, next) { width = width_capability(&fst->fs_cap_rights); if (width > capwidth) @@ -313,8 +314,8 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) capwidth = strlen("CAPABILITIES"); } - if (!hflag) { - if (Cflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) { + if ((procstat_opts & PS_OPT_CAPABILITIES) != 0) xo_emit("{T:/%5s %-16s %5s %1s %-8s %-*s " "%-3s %-12s}\n", "PID", "COMM", "FD", "T", "FLAGS", capwidth, "CAPABILITIES", "PRO", @@ -400,6 +401,11 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) xo_emit("{eq:fd_type/sem}"); break; + case PS_FST_TYPE_PROCDESC: + str = "P"; + xo_emit("{eq:fd_type/procdesc}"); + break; + case PS_FST_TYPE_NONE: str = "?"; xo_emit("{eq:fd_type/none}"); @@ -412,7 +418,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) break; } xo_emit("{d:fd_type/%1s/%s} ", str); - if (!Cflag) { + if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) { str = "-"; if (fst->fs_type == PS_FST_TYPE_VNODE) { error = procstat_get_vnode_info(procstat, fst, @@ -509,7 +515,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) xo_emit("{elq:fd_flags/lock_held}"); xo_close_list("fd_flags"); - if (!Cflag) { + if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) { if (fst->fs_ref_count > -1) xo_emit("{:ref_count/%3d/%d} ", fst->fs_ref_count); @@ -521,7 +527,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) else xo_emit("{q:offset/%7c/%c} ", '-'); } - if (Cflag) { + if ((procstat_opts & PS_OPT_CAPABILITIES) != 0) { print_capability(&fst->fs_cap_rights, capwidth); xo_emit(" "); } diff --git a/usr.bin/procstat/procstat_kstack.c b/usr.bin/procstat/procstat_kstack.c index 374f9d085692..225d939b22c4 100644 --- a/usr.bin/procstat/procstat_kstack.c +++ b/usr.bin/procstat/procstat_kstack.c @@ -162,7 +162,7 @@ kinfo_kstack_sort(struct kinfo_kstack *kkstp, int count) void -procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag) +procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp) { struct kinfo_kstack *kkstp, *kkstp_free; struct kinfo_proc *kip, *kip_free; @@ -170,7 +170,7 @@ procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag) unsigned int i, j; unsigned int kip_count, kstk_count; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-19s %-19s %-29s}\n", "PID", "TID", "COMM", "TDNAME", "KSTACK"); @@ -234,9 +234,11 @@ procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag) * entries, but for a more compact view, we convert carriage * returns to spaces. */ - kstack_cleanup(kkstp->kkst_trace, trace, kflag); + kstack_cleanup(kkstp->kkst_trace, trace, + (procstat_opts & PS_OPT_VERBOSE) != 0 ? 2 : 1); xo_open_list("trace"); - kstack_cleanup_encoded(kkstp->kkst_trace, encoded_trace, kflag); + kstack_cleanup_encoded(kkstp->kkst_trace, encoded_trace, + (procstat_opts & PS_OPT_VERBOSE) != 0 ? 2 : 1); xo_close_list("trace"); xo_emit("{d:trace/%-29s}\n", trace); } diff --git a/usr.bin/procstat/procstat_ptlwpinfo.c b/usr.bin/procstat/procstat_ptlwpinfo.c index 20ab95889e6c..f95bdab28b2d 100644 --- a/usr.bin/procstat/procstat_ptlwpinfo.c +++ b/usr.bin/procstat/procstat_ptlwpinfo.c @@ -36,7 +36,7 @@ #include "procstat.h" void -procstat_ptlwpinfo(struct procstat *prstat) +procstat_ptlwpinfo(struct procstat *prstat, struct kinfo_proc *kipp __unused) { struct ptrace_lwpinfo *pl; unsigned int count, i; @@ -45,7 +45,7 @@ procstat_ptlwpinfo(struct procstat *prstat) if (pl == NULL) return; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit( "{T:/%6s %7s %5s %5s %5s %6s %5s} {[:/%d}{T:/%s}{]:} {T:/%s}\n", "LWPID", "EVENT", "SIGNO", "CODE", "ERRNO", "PID", "UID", diff --git a/usr.bin/procstat/procstat_rlimit.c b/usr.bin/procstat/procstat_rlimit.c index 5088c59767e9..dc0d486dbb2e 100644 --- a/usr.bin/procstat/procstat_rlimit.c +++ b/usr.bin/procstat/procstat_rlimit.c @@ -94,7 +94,7 @@ procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp) struct rlimit rlimit; int i; - if (!hflag) { + if ((procstat_opts & PS_OPT_NOHEADER) == 0) { xo_emit("{T:/%5s %-16s %-16s %16s %16s}\n", "PID", "COMM", "RLIMIT", "SOFT ", "HARD "); } diff --git a/usr.bin/procstat/procstat_rusage.c b/usr.bin/procstat/procstat_rusage.c index e14ae2470fef..3d8c76370c0c 100644 --- a/usr.bin/procstat/procstat_rusage.c +++ b/usr.bin/procstat/procstat_rusage.c @@ -106,7 +106,7 @@ print_prefix(struct kinfo_proc *kipp) { xo_emit("{d:process_id/%5d/%d} ", kipp->ki_pid); - if (Hflag) + if ((procstat_opts & PS_OPT_PERTHREAD) != 0) xo_emit("{d:thread_id/%6d/%d} ", kipp->ki_tid); xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm); } @@ -125,7 +125,7 @@ print_rusage(struct kinfo_proc *kipp) xo_emit("{d:resource/%-14s} {d:usage/%29s}{P: }\n", "system time", format_time(&kipp->ki_rusage.ru_stime)); - if (Hflag) { + if ((procstat_opts & PS_OPT_PERTHREAD) != 0) { asprintf(&threadid, "%d", kipp->ki_tid); if (threadid == NULL) xo_errc(1, ENOMEM, @@ -154,7 +154,7 @@ print_rusage(struct kinfo_proc *kipp) rusage_info[i].ri_scale)); lp++; } - if (Hflag) { + if ((procstat_opts & PS_OPT_PERTHREAD) != 0) { xo_close_container(threadid); free(threadid); } @@ -166,15 +166,15 @@ procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp) struct kinfo_proc *kip; unsigned int count, i; - if (!hflag) { + if ((procstat_opts & PS_OPT_NOHEADER) == 0) { xo_emit("{d:ta/%5s} ", "PID"); - if (Hflag) + if ((procstat_opts & PS_OPT_PERTHREAD) != 0) xo_emit("{d:tb/%6s} ", "TID"); xo_emit("{d:tc/%-16s %-32s %14s}\n", "COMM", "RESOURCE", "VALUE "); } - if (!Hflag) { + if ((procstat_opts & PS_OPT_PERTHREAD) == 0) { print_rusage(kipp); return; } diff --git a/usr.bin/procstat/procstat_sigs.c b/usr.bin/procstat/procstat_sigs.c index 7bc73ec43471..59759b2b7899 100644 --- a/usr.bin/procstat/procstat_sigs.c +++ b/usr.bin/procstat/procstat_sigs.c @@ -48,7 +48,7 @@ procstat_print_signame(int sig) char name[12]; int i; - if (!nflag && sig < sys_nsig) { + if ((procstat_opts & PS_OPT_SIGNUM) == 0 && sig < sys_nsig) { strlcpy(name, sys_signame[sig], sizeof(name)); for (i = 0; name[i] != 0; i++) name[i] = toupper(name[i]); @@ -67,7 +67,7 @@ procstat_close_signame(int sig) char name[12]; int i; - if (!nflag && sig < sys_nsig) { + if ((procstat_opts & PS_OPT_SIGNUM) == 0 && sig < sys_nsig) { strlcpy(name, sys_signame[sig], sizeof(name)); for (i = 0; name[i] != 0; i++) name[i] = toupper(name[i]); @@ -110,7 +110,7 @@ procstat_sigs(struct procstat *prstat __unused, struct kinfo_proc *kipp) { int j; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %-16s %-7s %4s}\n", "PID", "COMM", "SIG", "FLAGS"); @@ -139,7 +139,7 @@ procstat_threads_sigs(struct procstat *procstat, struct kinfo_proc *kipp) unsigned int count, i; char *threadid; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-16s %-7s %4s}\n", "PID", "TID", "COMM", "SIG", "FLAGS"); diff --git a/usr.bin/procstat/procstat_threads.c b/usr.bin/procstat/procstat_threads.c index 40e1b4b15bae..a09f7e83584b 100644 --- a/usr.bin/procstat/procstat_threads.c +++ b/usr.bin/procstat/procstat_threads.c @@ -48,7 +48,7 @@ procstat_threads(struct procstat *procstat, struct kinfo_proc *kipp) const char *str; char *threadid; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s %-9s}\n", "PID", "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN"); diff --git a/usr.bin/procstat/procstat_vm.c b/usr.bin/procstat/procstat_vm.c index 8c641e55aad5..9f38c6432651 100644 --- a/usr.bin/procstat/procstat_vm.c +++ b/usr.bin/procstat/procstat_vm.c @@ -50,7 +50,7 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) const char *str, *lstr; ptrwidth = 2*sizeof(void *) + 2; - if (!hflag) + if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %*s %*s %3s %4s %4s %3s %3s %-4s %-2s %-s}\n", "PID", ptrwidth, "START", ptrwidth, "END", "PRT", "RES", "PRES", "REF", "SHD", "FLAG", "TP", "PATH"); diff --git a/usr.bin/procstat/tests/Makefile.depend b/usr.bin/procstat/tests/Makefile.depend new file mode 100644 index 000000000000..cae7e645ef6a --- /dev/null +++ b/usr.bin/procstat/tests/Makefile.depend @@ -0,0 +1,16 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/procstat/tests/procstat_test.sh b/usr.bin/procstat/tests/procstat_test.sh index a939f4f26cd7..06fa1f995522 100755 --- a/usr.bin/procstat/tests/procstat_test.sh +++ b/usr.bin/procstat/tests/procstat_test.sh @@ -63,8 +63,11 @@ binary_info_body() header_re=$(printf "$line_format" "PID" "COMM" "OSREL" "PATH") line_re=$(printf "$line_format" $PROG_PID $PROG_COMM "[[:digit:]]+" "$PROG_PATH") - atf_check -o save:procstat.out procstat -b $PROG_PID + atf_check -o save:procstat.out procstat binary $PROG_PID + atf_check -o match:"$header_re" head -n 1 procstat.out + atf_check -o match:"$line_re" tail -n 1 procstat.out + atf_check -o save:procstat.out procstat -b $PROG_PID atf_check -o match:"$header_re" head -n 1 procstat.out atf_check -o match:"$line_re" tail -n 1 procstat.out } @@ -84,6 +87,10 @@ command_line_arguments_body() header_re=$(printf "$line_format" "PID" "COMM" "ARGS") line_re=$(printf "$line_format" $PROG_PID "$PROG_COMM" "$PROG_PATH $arguments") + atf_check -o save:procstat.out procstat arguments $PROG_PID + atf_check -o match:"$header_re" head -n 1 procstat.out + atf_check -o match:"$line_re" tail -n 1 procstat.out + atf_check -o save:procstat.out procstat -c $PROG_PID atf_check -o match:"$header_re" head -n 1 procstat.out atf_check -o match:"$line_re" tail -n 1 procstat.out @@ -105,8 +112,11 @@ environment_body() header_re=$(printf "$line_format" "PID" "COMM" "ENVIRONMENT") line_re=$(printf "$line_format" $PROG_PID $PROG_COMM ".*$var.*") - atf_check -o save:procstat.out procstat -e $PROG_PID + atf_check -o save:procstat.out procstat environment $PROG_PID + atf_check -o match:"$header_re" head -n 1 procstat.out + atf_check -o match:"$line_re" tail -n 1 procstat.out + atf_check -o save:procstat.out procstat -e $PROG_PID atf_check -o match:"$header_re" head -n 1 procstat.out atf_check -o match:"$line_re" tail -n 1 procstat.out } @@ -125,8 +135,11 @@ file_descriptor_body() # XXX: write a more sensible feature test line_re=$(printf "$line_format" $PROG_PID $PROG_COMM ".+" ".+" ".+" ".+" ".+" ".+" ".+" ".+") - atf_check -o save:procstat.out procstat -f $PROG_PID + atf_check -o save:procstat.out procstat files $PROG_PID + atf_check -o match:"$header_re" head -n 1 procstat.out + atf_check -o match:"$line_re" awk 'NR > 1' procstat.out + atf_check -o save:procstat.out procstat -f $PROG_PID atf_check -o match:"$header_re" head -n 1 procstat.out atf_check -o match:"$line_re" awk 'NR > 1' procstat.out } diff --git a/usr.bin/protect/Makefile.depend b/usr.bin/protect/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/protect/Makefile.depend +++ b/usr.bin/protect/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/quota/Makefile.depend b/usr.bin/quota/Makefile.depend index 88d0220337f2..3866c0bbf1f9 100644 --- a/usr.bin/quota/Makefile.depend +++ b/usr.bin/quota/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/random/Makefile.depend b/usr.bin/random/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/random/Makefile.depend +++ b/usr.bin/random/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/rctl/Makefile.depend b/usr.bin/rctl/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/rctl/Makefile.depend +++ b/usr.bin/rctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/readelf/Makefile.depend b/usr.bin/readelf/Makefile.depend index 20f498cfb39b..c3f78dbc4cb6 100644 --- a/usr.bin/readelf/Makefile.depend +++ b/usr.bin/readelf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/renice/Makefile.depend b/usr.bin/renice/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/renice/Makefile.depend +++ b/usr.bin/renice/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/resizewin/Makefile.depend b/usr.bin/resizewin/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/resizewin/Makefile.depend +++ b/usr.bin/resizewin/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/rev/Makefile.depend b/usr.bin/rev/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/rev/Makefile.depend +++ b/usr.bin/rev/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/revoke/Makefile.depend b/usr.bin/revoke/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/revoke/Makefile.depend +++ b/usr.bin/revoke/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/rlogin/Makefile b/usr.bin/rlogin/Makefile deleted file mode 100644 index 74ab15bd2972..000000000000 --- a/usr.bin/rlogin/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 7/19/93 -# $FreeBSD$ - -PROG= rlogin - -PACKAGE=rcmds - -BINOWN= root -BINMODE=4555 - -.include diff --git a/usr.bin/rlogin/rlogin.1 b/usr.bin/rlogin/rlogin.1 deleted file mode 100644 index 5b974382cc5c..000000000000 --- a/usr.bin/rlogin/rlogin.1 +++ /dev/null @@ -1,167 +0,0 @@ -.\" Copyright (c) 1983, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)rlogin.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD$ -.\" -.Dd July 3, 2017 -.Dt RLOGIN 1 -.Os -.Sh NAME -.Nm rlogin -.Nd remote login -.Sh SYNOPSIS -.Ar rlogin -.Op Fl 468DEd -.Op Fl e Ar char -.Op Fl i Ar localname -.Op Fl l Ar username -.Ar host -.Sh DEPRECATION NOTICE -.Nm -is deprecated and will be removed from future versions of the -.Fx -base system. -If -.Nm -is still required, it can be installed from ports or packages -(net/bsdrcmds). -.Sh DESCRIPTION -The -.Nm -utility starts a terminal session on a remote host -.Ar host . -.Pp -The standard Berkeley -.Pa rhosts -authorization mechanism is used. -.Pp -The following options are available: -.Bl -tag -width flag -.It Fl 4 -Use IPv4 addresses only. -.It Fl 6 -Use IPv6 addresses only. -.It Fl 8 -Allow an eight-bit input data path at all times; otherwise -parity bits are stripped except when the remote side's stop and start -characters are other than -^S/^Q. -.It Fl D -Set the TCP_NODELAY socket option which can improve interactive response -at the expense of increased network load. -.It Fl E -Stop any character from being recognized as an escape character. -When used with the -.Fl 8 -option, this provides a completely transparent connection. -.It Fl d -Turn on socket debugging (see -.Xr setsockopt 2 ) -on the TCP sockets used for communication with the remote host. -.It Fl e -Allow user specification of the escape character, which is -.Dq ~ -by default. -This specification may be as a literal character, or as an octal -value in the form \ennn. -.It Fl i -Allow the caller to specify a different local name to be used -for authentication. -This option is restricted to processes with uid 0. -.It Fl l -Specify a different -.Ar username -for the remote login. -If this option is not specified, your local username will be used. -.El -.Pp -A line of the form -.Dq Ao escape char Ac Ns \&. -disconnects from the remote host. -Similarly, the line -.Dq Ao escape char Ac Ns ^Z -will suspend the -.Nm -session, and -.Dq Ao escape\ char Ac Ns Ao delayed-suspend\ char Ac -suspends the -send portion of the -.Nm -session, but allows output from the remote system. -By default, the tilde -.Pq Dq ~ -character is the escape character, and -normally control-Y -.Pq Dq ^Y -is the delayed-suspend character. -.Pp -All echoing takes place at the remote site, so that (except for delays) -the -.Nm -is transparent. -Flow control via ^S/^Q and flushing of input and output on interrupts -are handled properly. -.Sh ENVIRONMENT -The following environment variable is utilized by -.Nm : -.Bl -tag -width TERM -.It Ev TERM -Determines the user's terminal type. -.El -.Sh FILES -.Bl -tag -width /etc/hosts -compact -.It Pa /etc/hosts -.It Pa /etc/hosts.equiv -.It Ev $HOME Ns Pa /.rhosts -.El -.Sh SEE ALSO -.Xr login 1 , -.Xr rsh 1 , -.Xr telnet 1 , -.Xr setsockopt 2 , -.Xr ruserok 3 , -.Xr tty 4 , -.Xr hosts 5 , -.Xr hosts.equiv 5 , -.Xr rlogind 8 , -.Xr rshd 8 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . -.Pp -IPv6 support was added by WIDE/KAME project. -.Sh BUGS -The -.Nm -utility will be replaced by -.Xr telnet 1 -in the near future. -.Pp -More of the environment should be propagated. diff --git a/usr.bin/rlogin/rlogin.c b/usr.bin/rlogin/rlogin.c deleted file mode 100644 index 26692554958c..000000000000 --- a/usr.bin/rlogin/rlogin.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2002 Networks Associates Technology, Inc. - * All rights reserved. - * - * Portions of this software were developed for the FreeBSD Project by - * ThinkSec AS and NAI Labs, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1983, 1990, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#if 0 -#ifndef lint -static const char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ -#endif - -#include -__FBSDID("$FreeBSD$"); - -/* - * rlogin - remote login - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef TIOCPKT_WINDOW -#define TIOCPKT_WINDOW 0x80 -#endif - -/* concession to Sun */ -#ifndef SIGUSR1 -#define SIGUSR1 30 -#endif - -static int eight, rem; -static struct termios deftty; - -static int family = PF_UNSPEC; - -static int noescape; -static u_char escapechar = '~'; - -#define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp) -static struct winsize winsize; - -static void catch_child(int); -static void copytochild(int); -static _Noreturn void doit(long); -static _Noreturn void done(int); -static void echo(char); -static u_int getescape(const char *); -static void lostpeer(int); -static void mode(int); -static void msg(const char *); -static void oob(int); -static int reader(int); -static void sendwindow(void); -static void setsignal(int); -static void sigwinch(int); -static void stop(char); -static _Noreturn void usage(void); -static void writer(void); -static void writeroob(int); - -int -main(int argc, char *argv[]) -{ - struct passwd *pw; - struct servent *sp; - struct termios tty; - long omask; - int argoff, ch, dflag, Dflag, one; - uid_t uid; - char *host, *localname, *p, *user, term[1024] = "network"; - speed_t ospeed; - struct sockaddr_storage ss; - socklen_t sslen; - size_t len, len2; - int i; - - argoff = dflag = Dflag = 0; - one = 1; - host = localname = user = NULL; - - if ((p = strrchr(argv[0], '/'))) - ++p; - else - p = argv[0]; - - if (strcmp(p, "rlogin")) - host = p; - - /* handle "rlogin host flags" */ - if (!host && argc > 2 && argv[1][0] != '-') { - host = argv[1]; - argoff = 1; - } - -#define OPTIONS "468DEde:i:l:" - while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) - switch(ch) { - case '4': - family = PF_INET; - break; - - case '6': - family = PF_INET6; - break; - - case '8': - eight = 1; - break; - case 'D': - Dflag = 1; - break; - case 'E': - noescape = 1; - break; - case 'd': - dflag = 1; - break; - case 'e': - noescape = 0; - escapechar = getescape(optarg); - break; - case 'i': - if (getuid() != 0) - errx(1, "-i user: permission denied"); - localname = optarg; - break; - case 'l': - user = optarg; - break; - case '?': - default: - usage(); - } - optind += argoff; - - /* if haven't gotten a host yet, do so */ - if (!host && !(host = argv[optind++])) - usage(); - - if (argv[optind]) - usage(); - - if (!(pw = getpwuid(uid = getuid()))) - errx(1, "unknown user id"); - if (!user) - user = pw->pw_name; - if (!localname) - localname = pw->pw_name; - - sp = NULL; - sp = getservbyname("login", "tcp"); - if (sp == NULL) - errx(1, "login/tcp: unknown service"); - - if ((p = getenv("TERM")) != NULL) - (void)strlcpy(term, p, sizeof(term)); - len = strlen(term); - if (len < (sizeof(term) - 1) && tcgetattr(0, &tty) == 0) { - /* start at 2 to include the / */ - for (ospeed = i = cfgetospeed(&tty), len2 = 2; i > 9; len2++) - i /= 10; - if (len + len2 < sizeof(term)) - (void)snprintf(term + len, len2 + 1, "/%d", ospeed); - } - - (void)get_window_size(0, &winsize); - - (void)signal(SIGPIPE, lostpeer); - /* will use SIGUSR1 for window size hack, so hold it off */ - omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1)); - /* - * We set SIGURG and SIGUSR1 below so that an - * incoming signal will be held pending rather than being - * discarded. Note that these routines will be ready to get - * a signal by the time that they are unblocked below. - */ - (void)signal(SIGURG, copytochild); - (void)signal(SIGUSR1, writeroob); - - rem = rcmd_af(&host, sp->s_port, localname, user, term, 0, family); - - if (rem < 0) - exit(1); - - if (dflag && - setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0) - warn("setsockopt"); - if (Dflag && - setsockopt(rem, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) - warn("setsockopt NODELAY (ignored)"); - - sslen = sizeof(ss); - one = IPTOS_LOWDELAY; - if (getsockname(rem, (struct sockaddr *)&ss, &sslen) == 0 && - ss.ss_family == AF_INET) { - if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, - sizeof(int)) < 0) - warn("setsockopt TOS (ignored)"); - } else - if (ss.ss_family == AF_INET) - warn("setsockopt getsockname failed"); - - (void)setuid(uid); - doit(omask); - /*NOTREACHED*/ -} - -static int child; - -static void -doit(long omask) -{ - - (void)signal(SIGINT, SIG_IGN); - setsignal(SIGHUP); - setsignal(SIGQUIT); - mode(1); - child = fork(); - if (child == -1) { - warn("fork"); - done(1); - } - if (child == 0) { - if (reader(omask) == 0) { - msg("connection closed"); - exit(0); - } - sleep(1); - msg("\007connection closed"); - exit(1); - } - - /* - * We may still own the socket, and may have a pending SIGURG (or might - * receive one soon) that we really want to send to the reader. When - * one of these comes in, the trap copytochild simply copies such - * signals to the child. We can now unblock SIGURG and SIGUSR1 - * that were set above. - */ - (void)sigsetmask(omask); - (void)signal(SIGCHLD, catch_child); - writer(); - msg("closed connection"); - done(0); -} - -/* trap a signal, unless it is being ignored. */ -static void -setsignal(int sig) -{ - int omask = sigblock(sigmask(sig)); - - if (signal(sig, exit) == SIG_IGN) - (void)signal(sig, SIG_IGN); - (void)sigsetmask(omask); -} - -static void -done(int status) -{ - int w, wstatus; - - mode(0); - if (child > 0) { - /* make sure catch_child does not snap it up */ - (void)signal(SIGCHLD, SIG_DFL); - if (kill(child, SIGKILL) >= 0) - while ((w = wait(&wstatus)) > 0 && w != child); - } - exit(status); -} - -static int dosigwinch; - -/* - * This is called when the reader process gets the out-of-band (urgent) - * request to turn on the window-changing protocol. - */ -/* ARGSUSED */ -static void -writeroob(int signo __unused) -{ - if (dosigwinch == 0) { - sendwindow(); - (void)signal(SIGWINCH, sigwinch); - } - dosigwinch = 1; -} - -/* ARGSUSED */ -static void -catch_child(int signo __unused) -{ - pid_t pid; - int status; - - for (;;) { - pid = wait3(&status, WNOHANG|WUNTRACED, NULL); - if (pid == 0) - return; - /* if the child (reader) dies, just quit */ - if (pid < 0 || (pid == child && !WIFSTOPPED(status))) - done(WTERMSIG(status) | WEXITSTATUS(status)); - } - /* NOTREACHED */ -} - -/* - * writer: write to remote: 0 -> line. - * ~. terminate - * ~^Z suspend rlogin process. - * ~ suspend rlogin process, but leave reader alone. - */ -static void -writer(void) -{ - int bol, local, n; - char c; - - bol = 1; /* beginning of line */ - local = 0; - for (;;) { - n = read(STDIN_FILENO, &c, 1); - if (n <= 0) { - if (n < 0 && errno == EINTR) - continue; - break; - } - /* - * If we're at the beginning of the line and recognize a - * command character, then we echo locally. Otherwise, - * characters are echo'd remotely. If the command character - * is doubled, this acts as a force and local echo is - * suppressed. - */ - if (bol) { - bol = 0; - if (!noescape && c == escapechar) { - local = 1; - continue; - } - } else if (local) { - local = 0; - if (c == '.' || CCEQ(deftty.c_cc[VEOF], c)) { - echo(c); - break; - } - if (CCEQ(deftty.c_cc[VSUSP], c) || - CCEQ(deftty.c_cc[VDSUSP], c)) { - bol = 1; - echo(c); - stop(c); - continue; - } - if (c != escapechar) - (void)write(rem, &escapechar, 1); - } - - if (write(rem, &c, 1) == 0) { - msg("line gone"); - break; - } - bol = CCEQ(deftty.c_cc[VKILL], c) || - CCEQ(deftty.c_cc[VEOF], c) || - CCEQ(deftty.c_cc[VINTR], c) || - CCEQ(deftty.c_cc[VSUSP], c) || - c == '\r' || c == '\n'; - } -} - -static void -echo(char c) -{ - char *p; - char buf[8]; - - p = buf; - c &= 0177; - *p++ = escapechar; - if (c < ' ') { - *p++ = '^'; - *p++ = c + '@'; - } else if (c == 0177) { - *p++ = '^'; - *p++ = '?'; - } else - *p++ = c; - *p++ = '\r'; - *p++ = '\n'; - (void)write(STDOUT_FILENO, buf, p - buf); -} - -static void -stop(char cmdc) -{ - mode(0); - (void)signal(SIGCHLD, SIG_IGN); - (void)kill(CCEQ(deftty.c_cc[VSUSP], cmdc) ? 0 : getpid(), SIGTSTP); - (void)signal(SIGCHLD, catch_child); - mode(1); - sigwinch(0); /* check for size changes */ -} - -/* ARGSUSED */ -static void -sigwinch(int signo __unused) -{ - struct winsize ws; - - if (dosigwinch && get_window_size(0, &ws) == 0 && - bcmp(&ws, &winsize, sizeof(ws))) { - winsize = ws; - sendwindow(); - } -} - -/* - * Send the window size to the server via the magic escape - */ -static void -sendwindow(void) -{ - struct winsize ws; - char obuf[4 + sizeof (struct winsize)]; - - obuf[0] = 0377; - obuf[1] = 0377; - obuf[2] = 's'; - obuf[3] = 's'; - ws.ws_row = htons(winsize.ws_row); - ws.ws_col = htons(winsize.ws_col); - ws.ws_xpixel = htons(winsize.ws_xpixel); - ws.ws_ypixel = htons(winsize.ws_ypixel); - bcopy(&ws, obuf + 4, sizeof(ws)); - - (void)write(rem, obuf, sizeof(obuf)); -} - -/* - * reader: read from remote: line -> 1 - */ -#define READING 1 -#define WRITING 2 - -static jmp_buf rcvtop; -static int rcvcnt, rcvstate; -static pid_t ppid; -static char rcvbuf[8 * 1024]; - -/* ARGSUSED */ -static void -oob(int signo __unused) -{ - struct termios tty; - int atmark, n, rcvd; - char waste[BUFSIZ], mark; - - rcvd = 0; - while (recv(rem, &mark, 1, MSG_OOB) < 0) { - switch (errno) { - case EWOULDBLOCK: - /* - * Urgent data not here yet. It may not be possible - * to send it yet if we are blocked for output and - * our input buffer is full. - */ - if (rcvcnt < (int)sizeof(rcvbuf)) { - n = read(rem, rcvbuf + rcvcnt, - sizeof(rcvbuf) - rcvcnt); - if (n <= 0) - return; - rcvd += n; - } else { - n = read(rem, waste, sizeof(waste)); - if (n <= 0) - return; - } - continue; - default: - return; - } - } - if (mark & TIOCPKT_WINDOW) { - /* Let server know about window size changes */ - (void)kill(ppid, SIGUSR1); - } - if (!eight && (mark & TIOCPKT_NOSTOP)) { - (void)tcgetattr(0, &tty); - tty.c_iflag &= ~IXON; - (void)tcsetattr(0, TCSANOW, &tty); - } - if (!eight && (mark & TIOCPKT_DOSTOP)) { - (void)tcgetattr(0, &tty); - tty.c_iflag |= (deftty.c_iflag & IXON); - (void)tcsetattr(0, TCSANOW, &tty); - } - if (mark & TIOCPKT_FLUSHWRITE) { - (void)tcflush(1, TCIOFLUSH); - for (;;) { - if (ioctl(rem, SIOCATMARK, &atmark) < 0) { - warn("ioctl"); - break; - } - if (atmark) - break; - n = read(rem, waste, sizeof (waste)); - if (n <= 0) - break; - } - /* - * Don't want any pending data to be output, so clear the recv - * buffer. If we were hanging on a write when interrupted, - * don't want it to restart. If we were reading, restart - * anyway. - */ - rcvcnt = 0; - longjmp(rcvtop, 1); - } - - /* oob does not do FLUSHREAD (alas!) */ - - /* - * If we filled the receive buffer while a read was pending, longjmp - * to the top to restart appropriately. Don't abort a pending write, - * however, or we won't know how much was written. - */ - if (rcvd && rcvstate == READING) - longjmp(rcvtop, 1); -} - -/* reader: read from remote: line -> 1 */ -static int -reader(int omask) -{ - int n, remaining; - char *bufp; - pid_t pid; - - pid = getpid(); - (void)signal(SIGTTOU, SIG_IGN); - (void)signal(SIGURG, oob); - (void)signal(SIGUSR1, oob); /* When propogating SIGURG from parent */ - ppid = getppid(); - (void)fcntl(rem, F_SETOWN, pid); - (void)setjmp(rcvtop); - (void)sigsetmask(omask); - bufp = rcvbuf; - for (;;) { - while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { - rcvstate = WRITING; - n = write(STDOUT_FILENO, bufp, remaining); - if (n < 0) { - if (errno != EINTR) - return (-1); - continue; - } - bufp += n; - } - bufp = rcvbuf; - rcvcnt = 0; - rcvstate = READING; - - rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf)); - if (rcvcnt == 0) - return (0); - if (rcvcnt < 0) { - if (errno == EINTR) - continue; - warn("read"); - return (-1); - } - } -} - -static void -mode(int f) -{ - struct termios tty; - - switch (f) { - case 0: - (void)tcsetattr(0, TCSANOW, &deftty); - break; - case 1: - (void)tcgetattr(0, &deftty); - tty = deftty; - /* This is loosely derived from sys/kern/tty_compat.c. */ - tty.c_lflag &= ~(ECHO|ICANON|ISIG|IEXTEN); - tty.c_iflag &= ~ICRNL; - tty.c_oflag &= ~OPOST; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - if (eight) { - tty.c_iflag &= IXOFF; - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - } - (void)tcsetattr(0, TCSANOW, &tty); - break; - default: - return; - } -} - -/* ARGSUSED */ -static void -lostpeer(int signo __unused) -{ - (void)signal(SIGPIPE, SIG_IGN); - msg("\007connection closed"); - done(1); -} - -/* copy SIGURGs to the child process via SIGUSR1. */ -/* ARGSUSED */ -static void -copytochild(int signo __unused) -{ - (void)kill(child, SIGUSR1); -} - -static void -msg(const char *str) -{ - (void)fprintf(stderr, "rlogin: %s\r\n", str); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "usage: rlogin [-46%s]%s[-e char] [-i localname] [-l username] host\n", - "8DEd", " "); - exit(1); -} - -static u_int -getescape(const char *p) -{ - long val; - size_t len; - - if ((len = strlen(p)) == 1) /* use any single char, including '\' */ - return ((u_int)*p); - /* otherwise, \nnn */ - if (*p == '\\' && len >= 2 && len <= 4) { - val = strtol(++p, NULL, 8); - for (;;) { - if (!*++p) - return ((u_int)val); - if (*p < '0' || *p > '8') - break; - } - } - msg("illegal option value -- e"); - usage(); - /* NOTREACHED */ -} diff --git a/usr.bin/rpcgen/Makefile.depend b/usr.bin/rpcgen/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/rpcgen/Makefile.depend +++ b/usr.bin/rpcgen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/rpcinfo/Makefile.depend b/usr.bin/rpcinfo/Makefile.depend index 1eb0f334cbe9..ff7c06a53300 100644 --- a/usr.bin/rpcinfo/Makefile.depend +++ b/usr.bin/rpcinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.bin/rs/Makefile.depend b/usr.bin/rs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/rs/Makefile.depend +++ b/usr.bin/rs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/rsh/Makefile b/usr.bin/rsh/Makefile deleted file mode 100644 index 6883c7dcbb13..000000000000 --- a/usr.bin/rsh/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 7/19/93 -# $FreeBSD$ - -PROG= rsh -CFLAGS+=-I${SRCTOP}/libexec/rlogind - -PACKAGE=rcmds - -BINOWN= root -BINMODE=4555 - -.include diff --git a/usr.bin/rsh/rsh.1 b/usr.bin/rsh/rsh.1 deleted file mode 100644 index 56c5e6c3dece..000000000000 --- a/usr.bin/rsh/rsh.1 +++ /dev/null @@ -1,181 +0,0 @@ -.\" Copyright (c) 1983, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)rsh.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD$ -.\" -.Dd July 3, 2017 -.Dt RSH 1 -.Os -.Sh NAME -.Nm rsh -.Nd remote shell -.Sh SYNOPSIS -.Nm -.Op Fl 46dn -.Op Fl l Ar username -.Op Fl t Ar timeout -.Ar host -.Op command -.Sh DEPRECATION NOTICE -.Nm -is deprecated and will be removed from future versions of the -.Fx -base system. -If -.Nm -is still required, it can be installed from ports or packages -(net/bsdrcmds). -.Sh DESCRIPTION -The -.Nm -utility executes -.Ar command -on -.Ar host . -.Pp -The -.Nm -utility copies its standard input to the remote command, the standard -output of the remote command to its standard output, and the -standard error of the remote command to its standard error. -Interrupt, quit and terminate signals are propagated to the remote -command; -.Nm -normally terminates when the remote command does. -The options are as follows: -.Bl -tag -width flag -.It Fl 4 -Use IPv4 addresses only. -.It Fl 6 -Use IPv6 addresses only. -.It Fl d -Turn on socket debugging (using -.Xr setsockopt 2 ) -on the -.Tn TCP -sockets used for communication with the remote host. -.It Fl l Ar username -Allow the remote -.Ar username -to be specified. -By default, the remote username is the same as the local username. -Authorization is determined -as in -.Xr rlogin 1 . -.It Fl n -Redirect input from the special device -.Pa /dev/null -(see the -.Sx BUGS -section of this manual page). -.It Fl t Ar timeout -Allow a -.Ar timeout -to be specified (in seconds). -If no -data is sent or received in this time, -.Nm -will exit. -.El -.Pp -If no -.Ar command -is specified, you will be logged in on the remote host using -.Xr rlogin 1 . -.Pp -Shell metacharacters which are not quoted are interpreted on local machine, -while quoted metacharacters are interpreted on the remote machine. -For example, the command -.Pp -.Dl rsh otherhost cat remotefile >> localfile -.Pp -appends the remote file -.Ar remotefile -to the local file -.Ar localfile , -while -.Pp -.Dl rsh otherhost cat remotefile \&">>\&" other_remotefile -.Pp -appends -.Ar remotefile -to -.Ar other_remotefile . -.\" .Pp -.\" Many sites specify a large number of host names as commands in the -.\" directory /usr/hosts. -.\" If this directory is included in your search path, you can use the -.\" shorthand ``host command'' for the longer form ``rsh host command''. -.Sh FILES -.Bl -tag -width /etc/hosts -compact -.It Pa /etc/hosts -.El -.Sh SEE ALSO -.Xr rlogin 1 , -.Xr setsockopt 2 , -.Xr rcmd 3 , -.Xr ruserok 3 , -.Xr hosts 5 , -.Xr hosts.equiv 5 , -.Xr rlogind 8 , -.Xr rshd 8 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . -.Sh BUGS -If you are using -.Xr csh 1 -and put a -.Nm -in the background without redirecting its input away from the terminal, -it will block even if no reads are posted by the remote command. -If no input is desired you should redirect the input of -.Nm -to -.Pa /dev/null -using the -.Fl n -option. -.Pp -You cannot run an interactive command -(like -.Xr ee 1 -or -.Xr vi 1 ) -using -.Nm ; -use -.Xr rlogin 1 -instead. -.Pp -Stop signals stop the local -.Nm -process only; this is arguably wrong, but currently hard to fix for reasons -too complicated to explain here. diff --git a/usr.bin/rsh/rsh.c b/usr.bin/rsh/rsh.c deleted file mode 100644 index 5fa33e24b26b..000000000000 --- a/usr.bin/rsh/rsh.c +++ /dev/null @@ -1,376 +0,0 @@ -/*- - * Copyright (c) 1983, 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2002 Networks Associates Technology, Inc. - * All rights reserved. - * - * Portions of this software were developed for the FreeBSD Project by - * ThinkSec AS and NAI Labs, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1983, 1990, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#if 0 -#ifndef lint -static const char sccsid[] = "From: @(#)rsh.c 8.3 (Berkeley) 4/6/94"; -#endif /* not lint */ -#endif - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * rsh - remote shell - */ -static int rfd2; - -static int family = PF_UNSPEC; -static char rlogin[] = "rlogin"; - -void connect_timeout(int); -char *copyargs(char * const *); -void sendsig(int); -void talk(int, long, pid_t, int, int); -void usage(void); - -int -main(int argc, char *argv[]) -{ - struct passwd const *pw; - struct servent const *sp; - long omask; - int argoff, asrsh, ch, dflag, nflag, one, rem; - pid_t pid = 0; - uid_t uid; - char *args, *host, *p, *user; - int timeout = 0; - - argoff = asrsh = dflag = nflag = 0; - one = 1; - host = user = NULL; - - /* if called as something other than "rsh", use it as the host name */ - if ((p = strrchr(argv[0], '/'))) - ++p; - else - p = argv[0]; - if (strcmp(p, "rsh")) - host = p; - else - asrsh = 1; - - /* handle "rsh host flags" */ - if (!host && argc > 2 && argv[1][0] != '-') { - host = argv[1]; - argoff = 1; - } - -#define OPTIONS "468Lde:l:nt:w" - while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) - switch(ch) { - case '4': - family = PF_INET; - break; - - case '6': - family = PF_INET6; - break; - - case 'L': /* -8Lew are ignored to allow rlogin aliases */ - case 'e': - case 'w': - case '8': - break; - case 'd': - dflag = 1; - break; - case 'l': - user = optarg; - break; - case 'n': - nflag = 1; - break; - case 't': - timeout = atoi(optarg); - break; - case '?': - default: - usage(); - } - optind += argoff; - - /* if haven't gotten a host yet, do so */ - if (!host && !(host = argv[optind++])) - usage(); - - /* if no further arguments, must have been called as rlogin. */ - if (!argv[optind]) { - if (asrsh) - *argv = rlogin; - execv(_PATH_RLOGIN, argv); - err(1, "can't exec %s", _PATH_RLOGIN); - } - - argc -= optind; - argv += optind; - - if (!(pw = getpwuid(uid = getuid()))) - errx(1, "unknown user id"); - if (!user) - user = pw->pw_name; - - args = copyargs(argv); - - sp = NULL; - if (sp == NULL) - sp = getservbyname("shell", "tcp"); - if (sp == NULL) - errx(1, "shell/tcp: unknown service"); - - if (timeout) { - signal(SIGALRM, connect_timeout); - alarm(timeout); - } - rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2, - family); - if (timeout) { - signal(SIGALRM, SIG_DFL); - alarm(0); - } - - if (rem < 0) - exit(1); - - if (rfd2 < 0) - errx(1, "can't establish stderr"); - if (dflag) { - if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, - sizeof(one)) < 0) - warn("setsockopt"); - if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, - sizeof(one)) < 0) - warn("setsockopt"); - } - - (void)setuid(uid); - omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - (void)signal(SIGINT, sendsig); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - (void)signal(SIGQUIT, sendsig); - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - (void)signal(SIGTERM, sendsig); - - if (!nflag) { - pid = fork(); - if (pid < 0) - err(1, "fork"); - } - else - (void)shutdown(rem, SHUT_WR); - - (void)ioctl(rfd2, FIONBIO, &one); - (void)ioctl(rem, FIONBIO, &one); - - talk(nflag, omask, pid, rem, timeout); - - if (!nflag) - (void)kill(pid, SIGKILL); - exit(0); -} - -void -talk(int nflag, long omask, pid_t pid, int rem, int timeout) -{ - int cc, wc; - fd_set readfrom, ready, rembits; - char buf[BUFSIZ]; - const char *bp; - struct timeval tvtimeout; - int nfds, srval; - - if (!nflag && pid == 0) { - (void)close(rfd2); - -reread: errno = 0; - if ((cc = read(0, buf, sizeof buf)) <= 0) - goto done; - bp = buf; - -rewrite: - if (rem >= FD_SETSIZE) - errx(1, "descriptor too big"); - FD_ZERO(&rembits); - FD_SET(rem, &rembits); - nfds = rem + 1; - if (select(nfds, 0, &rembits, 0, 0) < 0) { - if (errno != EINTR) - err(1, "select"); - goto rewrite; - } - if (!FD_ISSET(rem, &rembits)) - goto rewrite; - wc = write(rem, bp, cc); - if (wc < 0) { - if (errno == EWOULDBLOCK) - goto rewrite; - goto done; - } - bp += wc; - cc -= wc; - if (cc == 0) - goto reread; - goto rewrite; -done: - (void)shutdown(rem, SHUT_WR); - exit(0); - } - - tvtimeout.tv_sec = timeout; - tvtimeout.tv_usec = 0; - - (void)sigsetmask(omask); - if (rfd2 >= FD_SETSIZE || rem >= FD_SETSIZE) - errx(1, "descriptor too big"); - FD_ZERO(&readfrom); - FD_SET(rfd2, &readfrom); - FD_SET(rem, &readfrom); - nfds = MAX(rfd2+1, rem+1); - do { - ready = readfrom; - if (timeout) { - srval = select(nfds, &ready, 0, 0, &tvtimeout); - } else { - srval = select(nfds, &ready, 0, 0, 0); - } - - if (srval < 0) { - if (errno != EINTR) - err(1, "select"); - continue; - } - if (srval == 0) - errx(1, "timeout reached (%d seconds)", timeout); - if (FD_ISSET(rfd2, &ready)) { - errno = 0; - cc = read(rfd2, buf, sizeof buf); - if (cc <= 0) { - if (errno != EWOULDBLOCK) - FD_CLR(rfd2, &readfrom); - } else - (void)write(STDERR_FILENO, buf, cc); - } - if (FD_ISSET(rem, &ready)) { - errno = 0; - cc = read(rem, buf, sizeof buf); - if (cc <= 0) { - if (errno != EWOULDBLOCK) - FD_CLR(rem, &readfrom); - } else - (void)write(STDOUT_FILENO, buf, cc); - } - } while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom)); -} - -void -connect_timeout(int sig __unused) -{ - char message[] = "timeout reached before connection completed.\n"; - - write(STDERR_FILENO, message, sizeof(message) - 1); - _exit(1); -} - -void -sendsig(int sig) -{ - char signo; - - signo = sig; - (void)write(rfd2, &signo, 1); -} - -char * -copyargs(char * const *argv) -{ - int cc; - char *args, *p; - char * const *ap; - - cc = 0; - for (ap = argv; *ap; ++ap) - cc += strlen(*ap) + 1; - if (!(args = malloc((u_int)cc))) - err(1, NULL); - for (p = args, ap = argv; *ap; ++ap) { - (void)strcpy(p, *ap); - for (p = strcpy(p, *ap); *p; ++p); - if (ap[1]) - *p++ = ' '; - } - return (args); -} - -void -usage(void) -{ - - (void)fprintf(stderr, - "usage: rsh [-46dn] [-l username] [-t timeout] host [command]\n"); - exit(1); -} diff --git a/usr.bin/rup/Makefile.depend b/usr.bin/rup/Makefile.depend index bdd7bc273d10..572fc8dbf41a 100644 --- a/usr.bin/rup/Makefile.depend +++ b/usr.bin/rup/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.bin/ruptime/Makefile.depend b/usr.bin/ruptime/Makefile.depend index 26cae4ede976..4bd09984c29d 100644 --- a/usr.bin/ruptime/Makefile.depend +++ b/usr.bin/ruptime/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/protocols \ include/xlocale \ diff --git a/usr.bin/ruptime/ruptime.1 b/usr.bin/ruptime/ruptime.1 index 8053974babf9..94604ca39a8e 100644 --- a/usr.bin/ruptime/ruptime.1 +++ b/usr.bin/ruptime/ruptime.1 @@ -28,7 +28,7 @@ .\" @(#)ruptime.1 8.2 (Berkeley) 4/5/94 .\" $FreeBSD$ .\" -.Dd July 3, 2017 +.Dd August 8, 2017 .Dt RUPTIME 1 .Os .Sh NAME diff --git a/usr.bin/rusers/Makefile.depend b/usr.bin/rusers/Makefile.depend index bdd7bc273d10..572fc8dbf41a 100644 --- a/usr.bin/rusers/Makefile.depend +++ b/usr.bin/rusers/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.bin/rwall/Makefile.depend b/usr.bin/rwall/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.bin/rwall/Makefile.depend +++ b/usr.bin/rwall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/rwho/Makefile.depend b/usr.bin/rwho/Makefile.depend index 26cae4ede976..4bd09984c29d 100644 --- a/usr.bin/rwho/Makefile.depend +++ b/usr.bin/rwho/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/protocols \ include/xlocale \ diff --git a/usr.bin/rwho/rwho.1 b/usr.bin/rwho/rwho.1 index 20420769bc0b..84e943760dbf 100644 --- a/usr.bin/rwho/rwho.1 +++ b/usr.bin/rwho/rwho.1 @@ -28,7 +28,7 @@ .\" @(#)rwho.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd July 3, 2017 +.Dd August 8, 2017 .Dt RWHO 1 .Os .Sh NAME diff --git a/usr.bin/script/Makefile.depend b/usr.bin/script/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/script/Makefile.depend +++ b/usr.bin/script/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/sdiff/Makefile.depend b/usr.bin/sdiff/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/sdiff/Makefile.depend +++ b/usr.bin/sdiff/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/sdiotool/Makefile b/usr.bin/sdiotool/Makefile index 76d091f42956..f7d1681335ed 100644 --- a/usr.bin/sdiotool/Makefile +++ b/usr.bin/sdiotool/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ PROG= sdiotool -SRCS= sdiotool.c +SRCS= sdiotool.c cam_sdio.c linux_sdio_compat.c LIBADD= cam util MAN= diff --git a/usr.bin/sdiotool/brcmfmac_bus.h b/usr.bin/sdiotool/brcmfmac_bus.h new file mode 100644 index 000000000000..2c7cb2953598 --- /dev/null +++ b/usr.bin/sdiotool/brcmfmac_bus.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +/* The level of bus communication with the dongle */ +enum brcmf_bus_state { + BRCMF_BUS_DOWN, /* Not ready for frame transfers */ + BRCMF_BUS_UP /* Ready for frame transfers */ +}; + +struct brcmf_bus { + enum brcmf_bus_state state; +}; diff --git a/usr.bin/sdiotool/brcmfmac_sdio.h b/usr.bin/sdiotool/brcmfmac_sdio.h new file mode 100644 index 000000000000..c4d0b3756def --- /dev/null +++ b/usr.bin/sdiotool/brcmfmac_sdio.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#define SDIO_FUNC_0 0 +#define SDIO_FUNC_1 1 +#define SDIO_FUNC_2 2 + +#define SDIOD_FBR_SIZE 0x100 + +/* io_en */ +#define SDIO_FUNC_ENABLE_1 0x02 +#define SDIO_FUNC_ENABLE_2 0x04 + +/* io_rdys */ +#define SDIO_FUNC_READY_1 0x02 +#define SDIO_FUNC_READY_2 0x04 + +/* intr_status */ +#define INTR_STATUS_FUNC1 0x2 +#define INTR_STATUS_FUNC2 0x4 + +/* Maximum number of I/O funcs */ +#define SDIOD_MAX_IOFUNCS 7 + +/* mask of register map */ +#define REG_F0_REG_MASK 0x7FF +#define REG_F1_MISC_MASK 0x1FFFF + +/* as of sdiod rev 0, supports 3 functions */ +#define SBSDIO_NUM_FUNCTION 3 + +/* function 0 vendor specific CCCR registers */ +#define SDIO_CCCR_BRCM_CARDCAP 0xf0 +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 +#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 +#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 +#define SDIO_CCCR_BRCM_SEPINT 0xf2 + +#define SDIO_SEPINT_MASK 0x01 +#define SDIO_SEPINT_OE 0x02 +#define SDIO_SEPINT_ACT_HI 0x04 + +/* function 1 miscellaneous registers */ + +/* sprom command and status */ +#define SBSDIO_SPROM_CS 0x10000 +/* sprom info register */ +#define SBSDIO_SPROM_INFO 0x10001 +/* sprom indirect access data byte 0 */ +#define SBSDIO_SPROM_DATA_LOW 0x10002 +/* sprom indirect access data byte 1 */ +#define SBSDIO_SPROM_DATA_HIGH 0x10003 +/* sprom indirect access addr byte 0 */ +#define SBSDIO_SPROM_ADDR_LOW 0x10004 +/* gpio select */ +#define SBSDIO_GPIO_SELECT 0x10005 +/* gpio output */ +#define SBSDIO_GPIO_OUT 0x10006 +/* gpio enable */ +#define SBSDIO_GPIO_EN 0x10007 +/* rev < 7, watermark for sdio device */ +#define SBSDIO_WATERMARK 0x10008 +/* control busy signal generation */ +#define SBSDIO_DEVICE_CTL 0x10009 + +/* SB Address Window Low (b15) */ +#define SBSDIO_FUNC1_SBADDRLOW 0x1000A +/* SB Address Window Mid (b23:b16) */ +#define SBSDIO_FUNC1_SBADDRMID 0x1000B +/* SB Address Window High (b31:b24) */ +#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C +/* Frame Control (frame term/abort) */ +#define SBSDIO_FUNC1_FRAMECTRL 0x1000D +/* ChipClockCSR (ALP/HT ctl/status) */ +#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E +/* SdioPullUp (on cmd, d0-d2) */ +#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F +/* Write Frame Byte Count Low */ +#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 +/* Write Frame Byte Count High */ +#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A +/* Read Frame Byte Count Low */ +#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B +/* Read Frame Byte Count High */ +#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C +/* MesBusyCtl (rev 11) */ +#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D +/* Sdio Core Rev 12 */ +#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1 +#define SBSDIO_FUNC1_SLEEPCSR 0x1001F +#define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1 + +#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ +#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001F /* f1 misc register end */ + +/* function 1 OCP space */ + +/* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF +#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 +/* with b15, maps to 32-bit SB access */ +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 + +/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ + +#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ +#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ +#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ +/* Address bits from SBADDR regs */ +#define SBSDIO_SBWINDOW_MASK 0xffff8000 + +#define SDIOH_READ 0 /* Read request */ +#define SDIOH_WRITE 1 /* Write request */ + +#define SDIOH_DATA_FIX 0 /* Fixed addressing */ +#define SDIOH_DATA_INC 1 /* Incremental addressing */ + +/* internal return code */ +#define SUCCESS 0 +#define ERROR 1 + +/* Packet alignment for most efficient SDIO (can change based on platform) */ +#define BRCMF_SDALIGN (1 << 6) + +/** + * enum brcmf_sdiod_state - the state of the bus. + * + * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC. + * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled. + * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible. + */ +enum brcmf_sdiod_state { + BRCMF_SDIOD_DOWN, + BRCMF_SDIOD_DATA, + BRCMF_SDIOD_NOMEDIUM +}; diff --git a/usr.bin/sdiotool/cam_sdio.c b/usr.bin/sdiotool/cam_sdio.c new file mode 100644 index 000000000000..13576bbf188a --- /dev/null +++ b/usr.bin/sdiotool/cam_sdio.c @@ -0,0 +1,440 @@ +/*- + * Copyright (c) 2017 Ilya Bakulin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "cam_sdio.h" + +/* Use CMD52 to read or write a single byte */ +int +sdio_rw_direct(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + uint8_t *data, uint8_t *resp) { + union ccb *ccb; + uint32_t flags; + uint32_t arg; + int retval = 0; + + ccb = cam_getccb(dev); + if (ccb == NULL) { + warnx("%s: error allocating CCB", __func__); + return (-1); + } + bzero(&(&ccb->ccb_h)[1], + sizeof(union ccb) - sizeof(struct ccb_hdr)); + + flags = MMC_RSP_R5 | MMC_CMD_AC; + arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr); + if (is_write) + arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); + + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ CAM_DIR_NONE, + /*mmc_opcode*/ SD_IO_RW_DIRECT, + /*mmc_arg*/ arg, + /*mmc_flags*/ flags, + /*mmc_data*/ 0, + /*timeout*/ 5000); + + if (((retval = cam_send_ccb(dev, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + const char warnstr[] = "error sending command"; + + if (retval < 0) + warn(warnstr); + else + warnx(warnstr); + return (-1); + } + + *resp = ccb->mmcio.cmd.resp[0] & 0xFF; + cam_freeccb(ccb); + return (retval); +} + +/* + * CMD53 -- IO_RW_EXTENDED + * Use to read or write memory blocks + * + * is_increment=1: FIFO mode + * blk_count > 0: block mode + */ +int +sdio_rw_extended(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + caddr_t data, size_t datalen, + uint8_t is_increment, + uint16_t blk_count) { + union ccb *ccb; + uint32_t flags; + uint32_t arg; + uint32_t cam_flags; + uint8_t resp; + struct mmc_data mmcd; + int retval = 0; + + if (blk_count != 0) { + warnx("%s: block mode is not supported yet", __func__); + return (-1); + } + + ccb = cam_getccb(dev); + if (ccb == NULL) { + warnx("%s: error allocating CCB", __func__); + return (-1); + } + bzero(&(&ccb->ccb_h)[1], + sizeof(union ccb) - sizeof(struct ccb_hdr)); + + flags = MMC_RSP_R5 | MMC_CMD_ADTC; + arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr) | + SD_IOE_RW_LEN(datalen); + + if (is_increment) + arg |= SD_IO_RW_INCR; + + mmcd.data = data; + mmcd.len = datalen; + mmcd.xfer_len = 0; /* not used by MMCCAM */ + mmcd.mrq = NULL; /* not used by MMCCAM */ + + if (is_write) { + arg |= SD_IO_RW_WR; + cam_flags = CAM_DIR_OUT; + mmcd.flags = MMC_DATA_WRITE; + } else { + cam_flags = CAM_DIR_IN; + mmcd.flags = MMC_DATA_READ; + } + cam_fill_mmcio(&ccb->mmcio, + /*retries*/ 0, + /*cbfcnp*/ NULL, + /*flags*/ cam_flags, + /*mmc_opcode*/ SD_IO_RW_EXTENDED, + /*mmc_arg*/ arg, + /*mmc_flags*/ flags, + /*mmc_data*/ &mmcd, + /*timeout*/ 5000); + + if (((retval = cam_send_ccb(dev, ccb)) < 0) + || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { + const char warnstr[] = "error sending command"; + + if (retval < 0) + warn(warnstr); + else + warnx(warnstr); + return (-1); + } + + resp = ccb->mmcio.cmd.resp[0] & 0xFF; + if (resp != 0) + warn("Response from CMD53 is not 0?!"); + cam_freeccb(ccb); + return (retval); +} + + +int +sdio_read_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, uint8_t *is_enab) { + uint8_t resp; + int ret; + + ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); + if (ret < 0) + return ret; + + *is_enab = (resp & (1 << func_number)) > 0 ? 1 : 0; + + return (0); +} + +int +sdio_set_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, int enable) { + uint8_t resp; + int ret; + uint8_t is_enabled; + + ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); + if (ret != 0) + return ret; + + is_enabled = resp & (1 << func_number); + if ((is_enabled !=0 && enable == 1) || (is_enabled == 0 && enable == 0)) + return 0; + + if (enable) + resp |= 1 << func_number; + else + resp &= ~ (1 << func_number); + + ret = sdio_rw_direct(dev, 0, addr, 1, &resp, &resp); + + return ret; +} + +/* Conventional I/O functions */ +uint8_t +sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret) { + uint8_t val; + *ret = sdio_rw_direct(dev, func_number, addr, 0, NULL, &val); + return val; +} + +int +sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val) { + uint8_t _val; + return sdio_rw_direct(dev, func_number, addr, 0, &val, &_val); +} + +uint16_t +sdio_read_2(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret) { + uint16_t val; + *ret = sdio_rw_extended(dev, func_number, addr, + /* is_write */ 0, + /* data */ (caddr_t) &val, + /* datalen */ sizeof(val), + /* is_increment */ 1, + /* blk_count */ 0 + ); + return val; +} + + +int +sdio_write_2(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint16_t val) { + return sdio_rw_extended(dev, func_number, addr, + /* is_write */ 1, + /* data */ (caddr_t) &val, + /* datalen */ sizeof(val), + /* is_increment */ 1, + /* blk_count */ 0 + ); +} + +uint32_t +sdio_read_4(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret) { + uint32_t val; + *ret = sdio_rw_extended(dev, func_number, addr, + /* is_write */ 0, + /* data */ (caddr_t) &val, + /* datalen */ sizeof(val), + /* is_increment */ 1, + /* blk_count */ 0 + ); + return val; +} + + +int +sdio_write_4(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint32_t val) { + return sdio_rw_extended(dev, func_number, addr, + /* is_write */ 1, + /* data */ (caddr_t) &val, + /* datalen */ sizeof(val), + /* is_increment */ 1, + /* blk_count */ 0 + ); +} + +/* Higher-level wrappers for certain management operations */ +int +sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_READY, func_number, is_enab); +} + +int +sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, is_enab); +} + +int +sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable) { + return sdio_set_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, enable); +} + +int +sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { + return sdio_read_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, is_enab); +} + +int +sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable) { + return sdio_set_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, enable); +} + +int +sdio_card_set_bus_width(struct cam_device *dev, enum mmc_bus_width bw) { + int ret; + uint8_t ctl_val; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 0, NULL, &ctl_val); + if (ret < 0) { + warn("Error getting CCCR_BUS_WIDTH value"); + return ret; + } + ctl_val &= ~0x3; + switch (bw) { + case bus_width_1: + /* Already set to 1-bit */ + break; + case bus_width_4: + ctl_val |= CCCR_BUS_WIDTH_4; + break; + case bus_width_8: + warn("Cannot do 8-bit on SDIO yet"); + return -1; + break; + } + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 1, &ctl_val, &ctl_val); + if (ret < 0) { + warn("Error setting CCCR_BUS_WIDTH value"); + return ret; + } + return ret; +} + +int +sdio_func_read_cis(struct cam_device *dev, uint8_t func_number, + uint32_t cis_addr, struct cis_info *info) { + uint8_t tuple_id, tuple_len, tuple_count; + uint32_t addr; + + char *cis1_info[4]; + int start, i, ch, count, ret; + char cis1_info_buf[256]; + + tuple_count = 0; /* Use to prevent infinite loop in case of parse errors */ + memset(cis1_info_buf, 0, 256); + do { + addr = cis_addr; + tuple_id = sdio_read_1(dev, 0, addr++, &ret); + if (tuple_id == SD_IO_CISTPL_END) + break; + if (tuple_id == 0) { + cis_addr++; + continue; + } + tuple_len = sdio_read_1(dev, 0, addr++, &ret); + if (tuple_len == 0 && tuple_id != 0x00) { + warn("Parse error: 0-length tuple %02X\n", tuple_id); + return -1; + } + + switch (tuple_id) { + case SD_IO_CISTPL_VERS_1: + addr += 2; + for (count = 0, start = 0, i = 0; + (count < 4) && ((i + 4) < 256); i++) { + ch = sdio_read_1(dev, 0, addr + i, &ret); + printf("count=%d, start=%d, i=%d, Got %c (0x%02x)\n", count, start, i, ch, ch); + if (ch == 0xff) + break; + cis1_info_buf[i] = ch; + if (ch == 0) { + cis1_info[count] = + cis1_info_buf + start; + start = i + 1; + count++; + } + } + printf("Card info:"); + for (i=0; i<4; i++) + if (cis1_info[i]) + printf(" %s", cis1_info[i]); + printf("\n"); + break; + case SD_IO_CISTPL_MANFID: + info->man_id = sdio_read_1(dev, 0, addr++, &ret); + info->man_id |= sdio_read_1(dev, 0, addr++, &ret) << 8; + + info->prod_id = sdio_read_1(dev, 0, addr++, &ret); + info->prod_id |= sdio_read_1(dev, 0, addr++, &ret) << 8; + break; + case SD_IO_CISTPL_FUNCID: + /* not sure if we need to parse it? */ + break; + case SD_IO_CISTPL_FUNCE: + if (tuple_len < 4) { + printf("FUNCE is too short: %d\n", tuple_len); + break; + } + if (func_number == 0) { + /* skip extended_data */ + addr++; + info->max_block_size = sdio_read_1(dev, 0, addr++, &ret); + info->max_block_size |= sdio_read_1(dev, 0, addr++, &ret) << 8; + } else { + info->max_block_size = sdio_read_1(dev, 0, addr + 0xC, &ret); + info->max_block_size |= sdio_read_1(dev, 0, addr + 0xD, &ret) << 8; + } + break; + default: + warnx("Skipping tuple ID %02X len %02X\n", tuple_id, tuple_len); + } + cis_addr += tuple_len + 2; + tuple_count++; + } while (tuple_count < 20); + + return 0; +} + +uint32_t +sdio_get_common_cis_addr(struct cam_device *dev) { + uint32_t addr; + int ret; + + addr = sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR, &ret); + addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 1, &ret) << 8; + addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 2, &ret) << 16; + + if (addr < SD_IO_CIS_START || addr > SD_IO_CIS_START + SD_IO_CIS_SIZE) { + warn("Bad CIS address: %04X\n", addr); + addr = 0; + } + + return addr; +} + +void sdio_card_reset(struct cam_device *dev) { + int ret; + uint8_t ctl_val; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 0, NULL, &ctl_val); + if (ret < 0) + errx(1, "Error getting CCCR_CTL value"); + ctl_val |= CCCR_CTL_RES; + ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 1, &ctl_val, &ctl_val); + if (ret < 0) + errx(1, "Error setting CCCR_CTL value"); +} diff --git a/usr.bin/sdiotool/cam_sdio.h b/usr.bin/sdiotool/cam_sdio.h new file mode 100644 index 000000000000..6f57fada45a0 --- /dev/null +++ b/usr.bin/sdiotool/cam_sdio.h @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2017 Ilya Bakulin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct cis_info { + uint16_t man_id; + uint16_t prod_id; + uint16_t max_block_size; +}; + +int sdio_rw_direct(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + uint8_t *data, + uint8_t *resp); +int +sdio_rw_extended(struct cam_device *dev, + uint8_t func_number, + uint32_t addr, + uint8_t is_write, + caddr_t data, size_t datalen, + uint8_t is_increment, + uint16_t blk_count); +uint8_t sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret); +int sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val); +uint16_t sdio_read_2(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret); +int sdio_write_2(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint16_t val); +uint32_t sdio_read_4(struct cam_device *dev, uint8_t func_number, uint32_t addr, int *ret); +int sdio_write_4(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint32_t val); +int sdio_read_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, uint8_t *is_enab); +int sdio_set_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, int enable); +int sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +int sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +int sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable); +int sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); +int sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable); +void sdio_card_reset(struct cam_device *dev); +uint32_t sdio_get_common_cis_addr(struct cam_device *dev); +int sdio_func_read_cis(struct cam_device *dev, uint8_t func_number, + uint32_t cis_addr, struct cis_info *info); +int sdio_card_set_bus_width(struct cam_device *dev, enum mmc_bus_width bw); diff --git a/usr.bin/sdiotool/linux_compat.h b/usr.bin/sdiotool/linux_compat.h new file mode 100644 index 000000000000..7f49fbde0a09 --- /dev/null +++ b/usr.bin/sdiotool/linux_compat.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2016-2017 Ilya Bakulin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#ifndef _LINUX_COMPAT_H_ +#define _LINUX_COMPAT_H_ + +/* Linux compatibility shims */ +#define uint unsigned int +#define u32 uint32_t +#define u8 uint8_t +#define u16 uint16_t +#define s32 int32_t +#define bool int8_t +#define true 1 +#define false 0 + +#define usleep_range(a, b) usleep(a) +#define ENOMEDIUM -1 +#define EINVAL -2 + +#define WARN_ON(cond) ({ \ + bool __ret = (cond); \ + if (__ret) { \ + printf("WARNING %s failed at %s:%d\n", \ + #cond, __FILE__, __LINE__); \ + } \ + (__ret); \ +}) + +#endif diff --git a/usr.bin/sdiotool/linux_sdio_compat.c b/usr.bin/sdiotool/linux_sdio_compat.c new file mode 100644 index 000000000000..85a0a8347162 --- /dev/null +++ b/usr.bin/sdiotool/linux_sdio_compat.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2016-2017 Ilya Bakulin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "linux_compat.h" +#include "linux_sdio_compat.h" +#include "cam_sdio.h" + +u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret) { + return sdio_read_1(func->dev, func->num, addr, err_ret); +} + +unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr, int *err_ret) { + return sdio_readb(func, addr, err_ret); +} + +u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret) { + return sdio_read_2(func->dev, func->num, addr, err_ret); +} + +u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret) { + return sdio_read_4(func->dev, func->num, addr, err_ret); +} + +void sdio_writeb(struct sdio_func *func, u8 b, + unsigned int addr, int *err_ret) { + *err_ret = sdio_write_1(func->dev, func->num, addr, b); +} + +/* Only writes to the vendor specific CCCR registers + * (0xF0 - 0xFF) are permiited. */ +void sdio_f0_writeb(struct sdio_func *func, unsigned char b, + unsigned int addr, int *err_ret) +{ + if (addr < 0xF0 || addr > 0xFF) { + if (err_ret) + *err_ret = -EINVAL; + return; + } + sdio_writeb(func, b, addr, err_ret); +} + +void sdio_writew(struct sdio_func *func, u16 b, + unsigned int addr, int *err_ret) { + *err_ret = sdio_write_2(func->dev, func->num, addr, b); +} + +void sdio_writel(struct sdio_func *func, u32 b, + unsigned int addr, int *err_ret) { + *err_ret = sdio_write_4(func->dev, func->num, addr, b); +} diff --git a/usr.bin/sdiotool/linux_sdio_compat.h b/usr.bin/sdiotool/linux_sdio_compat.h new file mode 100644 index 000000000000..671da405d374 --- /dev/null +++ b/usr.bin/sdiotool/linux_sdio_compat.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2017 Ilya Bakulin + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#ifndef _LINUX_SDIO_COMPAT_H_ +#define _LINUX_SDIO_COMPAT_H_ + +#include +#include "linux_compat.h" + +/* Linux SDIO stack functions and definitions */ +#define SDIO_CCCR_ABORT SD_IO_CCCR_CTL +#define SDIO_CCCR_IENx SD_IO_CCCR_INT_ENABLE + +struct sdio_func { + struct cam_device *dev; + uint8_t num; +}; + +u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret); +unsigned char sdio_f0_readb(struct sdio_func *func, + unsigned int addr, int *err_ret); +u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret); +u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret); + +void sdio_writeb(struct sdio_func *func, u8 b, + unsigned int addr, int *err_ret); +void sdio_f0_writeb(struct sdio_func *func, unsigned char b, + unsigned int addr, int *err_ret); +void sdio_writew(struct sdio_func *func, u16 b, + unsigned int addr, int *err_ret); +void sdio_writel(struct sdio_func *func, u32 b, + unsigned int addr, int *err_ret); + + +#endif diff --git a/usr.bin/sdiotool/sdiotool.c b/usr.bin/sdiotool/sdiotool.c index f665535bcc35..4d7b6ca91094 100644 --- a/usr.bin/sdiotool/sdiotool.c +++ b/usr.bin/sdiotool/sdiotool.c @@ -23,6 +23,20 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * * $FreeBSD$ */ @@ -55,365 +69,14 @@ __FBSDID("$FreeBSD$"); #include #include -struct cis_info { - uint16_t man_id; - uint16_t prod_id; - uint16_t max_block_size; -}; +#include "linux_compat.h" +#include "linux_sdio_compat.h" +#include "cam_sdio.h" +#include "brcmfmac_sdio.h" +#include "brcmfmac_bus.h" -static int sdio_rw_direct(struct cam_device *dev, - uint8_t func_number, - uint32_t addr, - uint8_t is_write, - uint8_t *data, - uint8_t *resp); -static uint8_t sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr); -static void sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val); -static int sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); -static int sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); -static int sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable); -static int sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab); -static int sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable); -static void sdio_card_reset(struct cam_device *dev); -static uint32_t sdio_get_common_cis_addr(struct cam_device *dev); static void probe_bcrm(struct cam_device *dev); -/* Use CMD52 to read or write a single byte */ -int -sdio_rw_direct(struct cam_device *dev, - uint8_t func_number, - uint32_t addr, - uint8_t is_write, - uint8_t *data, uint8_t *resp) { - union ccb *ccb; - uint32_t flags; - uint32_t arg; - int retval = 0; - - ccb = cam_getccb(dev); - if (ccb == NULL) { - warnx("%s: error allocating CCB", __func__); - return (1); - } - bzero(&(&ccb->ccb_h)[1], - sizeof(union ccb) - sizeof(struct ccb_hdr)); - - flags = MMC_RSP_R5 | MMC_CMD_AC; - arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr); - if (is_write) - arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); - - cam_fill_mmcio(&ccb->mmcio, - /*retries*/ 0, - /*cbfcnp*/ NULL, - /*flags*/ CAM_DIR_NONE, - /*mmc_opcode*/ SD_IO_RW_DIRECT, - /*mmc_arg*/ arg, - /*mmc_flags*/ flags, - /*mmc_data*/ 0, - /*timeout*/ 5000); - - if (((retval = cam_send_ccb(dev, ccb)) < 0) - || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { - const char warnstr[] = "error sending command"; - - if (retval < 0) - warn(warnstr); - else - warnx(warnstr); - return (-1); - } - - *resp = ccb->mmcio.cmd.resp[0] & 0xFF; - cam_freeccb(ccb); - return (retval); -} - -#if 0 -/* - * CMD53 -- IO_RW_EXTENDED - * Use to read or write memory blocks - * - * is_increment=1: FIFO mode - * blk_count > 0: block mode - */ -int -sdio_rw_extended(struct cam_device *dev, - uint8_t func_number, - uint32_t addr, - uint8_t is_write, - uint8_t *data, size_t datalen, - uint8_t is_increment, - uint16_t blk_count) { - union ccb *ccb; - uint32_t flags; - uint32_t arg; - int retval = 0; - - if (blk_count != 0) { - warnx("%s: block mode is not supported yet", __func__); - return (1); - } - - ccb = cam_getccb(dev); - if (ccb == NULL) { - warnx("%s: error allocating CCB", __func__); - return (1); - } - bzero(&(&ccb->ccb_h)[1], - sizeof(union ccb) - sizeof(struct ccb_hdr)); - - flags = MMC_RSP_R5 | MMC_CMD_AC; - arg = SD_IO_RW_FUNC(func_number) | SD_IO_RW_ADR(addr); - if (is_write) - arg |= SD_IO_RW_WR; - - cam_fill_mmcio(&ccb->mmcio, - /*retries*/ 0, - /*cbfcnp*/ NULL, - /*flags*/ CAM_DIR_NONE, - /*mmc_opcode*/ SD_IO_RW_DIRECT, - /*mmc_arg*/ arg, - /*mmc_flags*/ flags, - /*mmc_data*/ 0, - /*timeout*/ 5000); - - if (((retval = cam_send_ccb(dev, ccb)) < 0) - || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { - const char warnstr[] = "error sending command"; - - if (retval < 0) - warn(warnstr); - else - warnx(warnstr); - return (-1); - } - - *resp = ccb->mmcio.cmd.resp[0] & 0xFF; - cam_freeccb(ccb); - return (retval); -} -#endif - -static int -sdio_read_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, uint8_t *is_enab) { - uint8_t resp; - int ret; - - ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); - if (ret < 0) - return ret; - - *is_enab = (resp & (1 << func_number)) > 0 ? 1 : 0; - - return (0); -} - -static int -sdio_set_bool_for_func(struct cam_device *dev, uint32_t addr, uint8_t func_number, int enable) { - uint8_t resp; - int ret; - uint8_t is_enabled; - - ret = sdio_rw_direct(dev, 0, addr, 0, NULL, &resp); - if (ret != 0) - return ret; - - is_enabled = resp & (1 << func_number); - if ((is_enabled !=0 && enable == 1) || (is_enabled == 0 && enable == 0)) - return 0; - - if (enable) - resp |= 1 << func_number; - else - resp &= ~ (1 << func_number); - - ret = sdio_rw_direct(dev, 0, addr, 1, &resp, &resp); - - return ret; -} - -static uint8_t -sdio_read_1(struct cam_device *dev, uint8_t func_number, uint32_t addr) { - uint8_t val; - sdio_rw_direct(dev, func_number, addr, 0, NULL, &val); - return val; -} - -__unused static void -sdio_write_1(struct cam_device *dev, uint8_t func_number, uint32_t addr, uint8_t val) { - uint8_t _val; - sdio_rw_direct(dev, func_number, addr, 0, &val, &_val); -} - -static int -sdio_is_func_ready(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { - return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_READY, func_number, is_enab); -} - -static int -sdio_is_func_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { - return sdio_read_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, is_enab); -} - -static int -sdio_func_enable(struct cam_device *dev, uint8_t func_number, int enable) { - return sdio_set_bool_for_func(dev, SD_IO_CCCR_FN_ENABLE, func_number, enable); -} - -static int -sdio_is_func_intr_enabled(struct cam_device *dev, uint8_t func_number, uint8_t *is_enab) { - return sdio_read_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, is_enab); -} - -static int -sdio_func_intr_enable(struct cam_device *dev, uint8_t func_number, int enable) { - return sdio_set_bool_for_func(dev, SD_IO_CCCR_INT_ENABLE, func_number, enable); -} - -static int -sdio_card_set_bus_width(struct cam_device *dev, enum mmc_bus_width bw) { - int ret; - uint8_t ctl_val; - ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 0, NULL, &ctl_val); - if (ret < 0) { - warn("Error getting CCCR_BUS_WIDTH value"); - return ret; - } - ctl_val &= ~0x3; - switch (bw) { - case bus_width_1: - /* Already set to 1-bit */ - break; - case bus_width_4: - ctl_val |= CCCR_BUS_WIDTH_4; - break; - case bus_width_8: - warn("Cannot do 8-bit on SDIO yet"); - return -1; - break; - } - ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_BUS_WIDTH, 1, &ctl_val, &ctl_val); - if (ret < 0) { - warn("Error setting CCCR_BUS_WIDTH value"); - return ret; - } - return ret; -} - -static int -sdio_func_read_cis(struct cam_device *dev, uint8_t func_number, - uint32_t cis_addr, struct cis_info *info) { - uint8_t tuple_id, tuple_len, tuple_count; - uint32_t addr; - - char *cis1_info[4]; - int start, i, ch, count; - char cis1_info_buf[256]; - - tuple_count = 0; /* Use to prevent infinite loop in case of parse errors */ - memset(cis1_info_buf, 0, 256); - do { - addr = cis_addr; - tuple_id = sdio_read_1(dev, 0, addr++); - if (tuple_id == SD_IO_CISTPL_END) - break; - if (tuple_id == 0) { - cis_addr++; - continue; - } - tuple_len = sdio_read_1(dev, 0, addr++); - if (tuple_len == 0 && tuple_id != 0x00) { - warn("Parse error: 0-length tuple %02X\n", tuple_id); - return -1; - } - - switch (tuple_id) { - case SD_IO_CISTPL_VERS_1: - addr += 2; - for (count = 0, start = 0, i = 0; - (count < 4) && ((i + 4) < 256); i++) { - ch = sdio_read_1(dev, 0, addr + i); - printf("count=%d, start=%d, i=%d, Got %c (0x%02x)\n", count, start, i, ch, ch); - if (ch == 0xff) - break; - cis1_info_buf[i] = ch; - if (ch == 0) { - cis1_info[count] = - cis1_info_buf + start; - start = i + 1; - count++; - } - } - printf("Card info:"); - for (i=0; i<4; i++) - if (cis1_info[i]) - printf(" %s", cis1_info[i]); - printf("\n"); - break; - case SD_IO_CISTPL_MANFID: - info->man_id = sdio_read_1(dev, 0, addr++); - info->man_id |= sdio_read_1(dev, 0, addr++) << 8; - - info->prod_id = sdio_read_1(dev, 0, addr++); - info->prod_id |= sdio_read_1(dev, 0, addr++) << 8; - break; - case SD_IO_CISTPL_FUNCID: - /* not sure if we need to parse it? */ - break; - case SD_IO_CISTPL_FUNCE: - if (tuple_len < 4) { - printf("FUNCE is too short: %d\n", tuple_len); - break; - } - if (func_number == 0) { - /* skip extended_data */ - addr++; - info->max_block_size = sdio_read_1(dev, 0, addr++); - info->max_block_size |= sdio_read_1(dev, 0, addr++) << 8; - } else { - info->max_block_size = sdio_read_1(dev, 0, addr + 0xC); - info->max_block_size |= sdio_read_1(dev, 0, addr + 0xD) << 8; - } - break; - default: - printf("Skipping tuple ID %02X len %02X\n", tuple_id, tuple_len); - } - cis_addr += tuple_len + 2; - tuple_count++; - } while (tuple_count < 20); - - return 0; -} - -static uint32_t -sdio_get_common_cis_addr(struct cam_device *dev) { - uint32_t addr; - - addr = sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR); - addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 1) << 8; - addr |= sdio_read_1(dev, 0, SD_IO_CCCR_CISPTR + 2) << 16; - - if (addr < SD_IO_CIS_START || addr > SD_IO_CIS_START + SD_IO_CIS_SIZE) { - warn("Bad CIS address: %04X\n", addr); - addr = 0; - } - - return addr; -} - -static void sdio_card_reset(struct cam_device *dev) { - int ret; - uint8_t ctl_val; - ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 0, NULL, &ctl_val); - if (ret < 0) - errx(1, "Error getting CCCR_CTL value"); - ctl_val |= CCCR_CTL_RES; - ret = sdio_rw_direct(dev, 0, SD_IO_CCCR_CTL, 1, &ctl_val, &ctl_val); - if (ret < 0) - errx(1, "Error setting CCCR_CTL value"); -} - /* * How Linux driver works * @@ -494,6 +157,258 @@ static void sdio_card_reset(struct cam_device *dev) { * * */ + +/* BRCM-specific functions */ +#define SDIOH_API_ACCESS_RETRY_LIMIT 2 +#define SI_ENUM_BASE 0x18000000 +#define REPLY_MAGIC 0x16044330 +#define brcmf_err(fmt, ...) brcmf_dbg(0, fmt, ##__VA_ARGS__) +#define brcmf_dbg(level, fmt, ...) printf(fmt, ##__VA_ARGS__) + +struct brcmf_sdio_dev { + struct cam_device *cam_dev; + u32 sbwad; /* Save backplane window address */ + struct brcmf_bus *bus_if; + enum brcmf_sdiod_state state; + struct sdio_func *func[8]; +}; + +void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); +void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, + enum brcmf_sdiod_state state); +static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, u32 addr, + u8 regsz, void *data, bool write); +static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address); +static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr); +u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); + +static void bailout(int ret); + +static void +bailout(int ret) { + if (ret == 0) + return; + errx(1, "Operation returned error %d", ret); +} + +void +brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state) +{ + bus->state = state; +} + +void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, + enum brcmf_sdiod_state state) +{ + if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM || + state == sdiodev->state) + return; + + //brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state); + switch (sdiodev->state) { + case BRCMF_SDIOD_DATA: + /* any other state means bus interface is down */ + brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN); + break; + case BRCMF_SDIOD_DOWN: + /* transition from DOWN to DATA means bus interface is up */ + if (state == BRCMF_SDIOD_DATA) + brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP); + break; + default: + break; + } + sdiodev->state = state; +} + +static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, + uint regaddr, u8 byte) { + int err_ret; + + /* + * Can only directly write to some F0 registers. + * Handle CCCR_IENx and CCCR_ABORT command + * as a special case. + */ + if ((regaddr == SDIO_CCCR_ABORT) || + (regaddr == SDIO_CCCR_IENx)) + sdio_writeb(func, byte, regaddr, &err_ret); + else + sdio_f0_writeb(func, byte, regaddr, &err_ret); + + return err_ret; +} + +static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, u32 addr, u8 regsz, void *data, bool write) +{ + struct sdio_func *func; + int ret = -EINVAL; + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + write, fn, addr, regsz); + + /* only allow byte access on F0 */ + if (WARN_ON(regsz > 1 && !fn)) + return -EINVAL; + func = sdiodev->func[fn]; + + switch (regsz) { + case sizeof(u8): + if (write) { + if (fn) + sdio_writeb(func, *(u8 *)data, addr, &ret); + else + ret = brcmf_sdiod_f0_writeb(func, addr, + *(u8 *)data); + } else { + if (fn) + *(u8 *)data = sdio_readb(func, addr, &ret); + else + *(u8 *)data = sdio_f0_readb(func, addr, &ret); + } + break; + case sizeof(u16): + if (write) + sdio_writew(func, *(u16 *)data, addr, &ret); + else + *(u16 *)data = sdio_readw(func, addr, &ret); + break; + case sizeof(u32): + if (write) + sdio_writel(func, *(u32 *)data, addr, &ret); + else + *(u32 *)data = sdio_readl(func, addr, &ret); + break; + default: + brcmf_err("invalid size: %d\n", regsz); + break; + } + + if (ret) + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", + write ? "write" : "read", fn, addr, ret); + + return ret; +} + +static int +brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) +{ + uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; + int err = 0; + + if (bar0 != sdiodev->sbwad) { + err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); + if (err) + return err; + + sdiodev->sbwad = bar0; + } + + *addr &= SBSDIO_SB_OFT_ADDR_MASK; + + if (width == 4) + *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + return 0; +} + +static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 regsz, void *data, bool write) { + u8 func; + s32 retry = 0; + int ret; + + if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) + return -ENOMEDIUM; + + /* + * figure out how to read the register based on address range + * 0x00 ~ 0x7FF: function 0 CCCR and FBR + * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers + * The rest: function 1 silicon backplane core registers + */ + if ((addr & ~REG_F0_REG_MASK) == 0) + func = SDIO_FUNC_0; + else + func = SDIO_FUNC_1; + + do { + if (!write) + memset(data, 0, regsz); + /* for retry wait for 1 ms till bus get settled down */ + if (retry) + usleep_range(1000, 2000); + ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, + data, write); + } while (ret != 0 && ret != -ENOMEDIUM && + retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); + + if (ret == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); + else if (ret != 0) { + /* + * SleepCSR register access can fail when + * waking up the device so reduce this noise + * in the logs. + */ + if (addr != SBSDIO_FUNC1_SLEEPCSR) + brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", + write ? "write" : "read", func, addr, ret); + else + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", + write ? "write" : "read", func, addr, ret); + } + return ret; +} + +static int +brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +{ + int err = 0, i; + u8 addr[3]; + + if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) + return -ENOMEDIUM; + + addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; + addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; + addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; + + for (i = 0; i < 3; i++) { + err = brcmf_sdiod_regrw_helper(sdiodev, + SBSDIO_FUNC1_SBADDRLOW + i, + sizeof(u8), &addr[i], true); + if (err) { + brcmf_err("failed at addr: 0x%0x\n", + SBSDIO_FUNC1_SBADDRLOW + i); + break; + } + } + + return err; +} + +u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +{ + u32 data = 0; + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); + retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); + if (retval) + goto done; + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, + false); + brcmf_dbg(SDIO, "data:0x%08x\n", data); + +done: + if (ret) + *ret = retval; + + return data; +} + +/********************************************************/ __unused static void probe_bcrm(struct cam_device *dev) { @@ -508,8 +423,8 @@ probe_bcrm(struct cam_device *dev) { sdio_func_read_cis(dev, 0, cis_addr, &info); printf("Vendor 0x%04X product 0x%04X\n", info.man_id, info.prod_id); } -__unused -static uint8_t * + +__unused static uint8_t* mmap_fw() { const char fw_path[] = "/home/kibab/repos/fbsd-bbb/brcm-firmware/brcmfmac4330-sdio.bin"; struct stat sb; @@ -533,69 +448,65 @@ usage() { exit(0); } +struct card_info { + uint8_t num_funcs; + struct cis_info f[8]; +}; + +/* + * TODO: We should add SDIO card info about at least number of + * available functions to struct cam_device and use it instead + * of checking for man_id = 0x00 for detecting number of functions + */ static void -get_sdio_card_info(struct cam_device *dev) { +get_sdio_card_info(struct cam_device *dev, struct card_info *ci) { uint32_t cis_addr; uint32_t fbr_addr; - struct cis_info info; + int ret; cis_addr = sdio_get_common_cis_addr(dev); - memset(&info, 0, sizeof(info)); - sdio_func_read_cis(dev, 0, cis_addr, &info); + memset(ci, 0, sizeof(struct card_info)); + sdio_func_read_cis(dev, 0, cis_addr, &ci->f[0]); printf("F0: Vendor 0x%04X product 0x%04X max block size %d bytes\n", - info.man_id, info.prod_id, info.max_block_size); - for (int i = 1; i <= 2; i++) { + ci->f[0].man_id, ci->f[0].prod_id, ci->f[0].max_block_size); + for (int i = 1; i <= 7; i++) { fbr_addr = SD_IO_FBR_START * i + 0x9; - cis_addr = sdio_read_1(dev, 0, fbr_addr++); - cis_addr |= sdio_read_1(dev, 0, fbr_addr++) << 8; - cis_addr |= sdio_read_1(dev, 0, fbr_addr++) << 16; - memset(&info, 0, sizeof(info)); - sdio_func_read_cis(dev, i, cis_addr, &info); + cis_addr = sdio_read_1(dev, 0, fbr_addr++, &ret);bailout(ret); + cis_addr |= sdio_read_1(dev, 0, fbr_addr++, &ret) << 8; + cis_addr |= sdio_read_1(dev, 0, fbr_addr++, &ret) << 16; + sdio_func_read_cis(dev, i, cis_addr, &ci->f[i]); printf("F%d: Vendor 0x%04X product 0x%04X max block size %d bytes\n", - i, info.man_id, info.prod_id, info.max_block_size); + i, ci->f[i].man_id, ci->f[i].prod_id, ci->f[i].max_block_size); + if (ci->f[i].man_id == 0) { + printf("F%d doesn't exist\n", i); + break; + } + ci->num_funcs++; } } -/* Test interrupt delivery when select() */ -__unused static int -sdio_signal_intr(struct cam_device *dev) { - uint8_t resp; - int ret; - - ret = sdio_rw_direct(dev, 0, 0x666, 0, NULL, &resp); - if (ret < 0) - return ret; - return (0); -} - -static void -do_intr_test(__unused struct cam_device *dev) { -} - int main(int argc, char **argv) { char device[] = "pass"; int unit = 0; int func = 0; - uint8_t resp; - uint8_t is_enab; __unused uint8_t *fw_ptr; int ch; struct cam_device *cam_dev; - int is_intr_test = 0; + int ret; + struct card_info ci; //fw_ptr = mmap_fw(); - while ((ch = getopt(argc, argv, "Iu:")) != -1) { + while ((ch = getopt(argc, argv, "fu:")) != -1) { switch (ch) { case 'u': unit = (int) strtol(optarg, NULL, 10); break; case 'f': func = (int) strtol(optarg, NULL, 10); - case 'I': - is_intr_test = 1; + break; case '?': default: usage(); @@ -607,43 +518,39 @@ main(int argc, char **argv) { if ((cam_dev = cam_open_spec_device(device, unit, O_RDWR, NULL)) == NULL) errx(1, "Cannot open device"); - get_sdio_card_info(cam_dev); - if (is_intr_test > 0) - do_intr_test(cam_dev); - exit(0); - sdio_card_reset(cam_dev); + get_sdio_card_info(cam_dev, &ci); - /* Read Addr 7 of func 0 */ - int ret = sdio_rw_direct(cam_dev, 0, 7, 0, NULL, &resp); - if (ret < 0) - errx(1, "Error sending CAM command"); - printf("Result: %02x\n", resp); + /* For now, everything non-broadcom is out of the question */ + if (ci.f[0].man_id != 0x02D0) { + printf("The card is not a Broadcom device\n"); + exit(1); + } + /* Init structures */ + struct brcmf_sdio_dev brcmf_dev; + struct brcmf_bus bus_if; + struct sdio_func f0, f1, f2; + bus_if.state = BRCMF_BUS_DOWN; + brcmf_dev.cam_dev = cam_dev; + brcmf_dev.bus_if = &bus_if; + brcmf_dev.state = BRCMF_SDIOD_DOWN; - /* Check if func 1 is enabled */ - ret = sdio_is_func_enabled(cam_dev, 1, &is_enab); - if (ret < 0) - errx(1, "Cannot check if func is enabled"); - printf("F1 enabled: %d\n", is_enab); - ret = sdio_func_enable(cam_dev, 1, 1 - is_enab); - if (ret < 0) - errx(1, "Cannot enable/disable func"); - printf("F1 en/dis result: %d\n", ret); + /* Fill in functions */ + brcmf_dev.func[0] = &f0; + brcmf_dev.func[1] = &f1; + brcmf_dev.func[2] = &f2; - /* Check if func 1 is ready */ - ret = sdio_is_func_ready(cam_dev, 1, &is_enab); - if (ret < 0) - errx(1, "Cannot check if func is ready"); - printf("F1 ready: %d\n", is_enab); - - /* Check if interrupts are enabled */ - ret = sdio_is_func_intr_enabled(cam_dev, 1, &is_enab); - if (ret < 0) - errx(1, "Cannot check if func intr is enabled"); - printf("F1 intr enabled: %d\n", is_enab); - ret = sdio_func_intr_enable(cam_dev, 1, 1 - is_enab); - if (ret < 0) - errx(1, "Cannot enable/disable func intr"); - printf("F1 intr en/dis result: %d\n", ret); + brcmf_dev.func[0]->dev = brcmf_dev.func[1]->dev + = brcmf_dev.func[2]->dev = cam_dev; + brcmf_dev.func[0]->num = 0; + brcmf_dev.func[1]->num = 1; + brcmf_dev.func[2]->num = 2; + ret = sdio_func_enable(cam_dev, 1, 1);bailout(ret); + uint32_t magic = brcmf_sdiod_regrl(&brcmf_dev, 0x18000000, &ret); + printf("Magic = %08x\n", magic); + if (magic != REPLY_MAGIC) { + errx(1, "Reply magic is incorrect: expected %08x, got %08x", + REPLY_MAGIC, magic); + } cam_close_spec_device(cam_dev); } diff --git a/usr.bin/sed/Makefile.depend b/usr.bin/sed/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/sed/Makefile.depend +++ b/usr.bin/sed/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/seq/Makefile.depend b/usr.bin/seq/Makefile.depend index c9f9d52f6e26..905e67cc66c9 100644 --- a/usr.bin/seq/Makefile.depend +++ b/usr.bin/seq/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/setchannel/Makefile.depend b/usr.bin/setchannel/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/usr.bin/setchannel/Makefile.depend +++ b/usr.bin/setchannel/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/showmount/Makefile.depend b/usr.bin/showmount/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.bin/showmount/Makefile.depend +++ b/usr.bin/showmount/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/size/Makefile.depend b/usr.bin/size/Makefile.depend index 40241f30eaf8..4f2cad33521d 100644 --- a/usr.bin/size/Makefile.depend +++ b/usr.bin/size/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/smbutil/Makefile.depend b/usr.bin/smbutil/Makefile.depend index 4db7ad30ce22..53bd740fd597 100644 --- a/usr.bin/smbutil/Makefile.depend +++ b/usr.bin/smbutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/sockstat/Makefile.depend b/usr.bin/sockstat/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/sockstat/Makefile.depend +++ b/usr.bin/sockstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index a4de5d18a05b..02b43b81374c 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include +#define _WANT_UNPCB #include #include @@ -535,7 +536,7 @@ gather_sctp(void) "address family %d not supported", xraddr->address.sa.sa_family); } - faddr->encaps_port = xraddr->encaps_port; + faddr->encaps_port = xraddr->encaps_port; faddr->state = xraddr->state; faddr->next = NULL; if (prev_faddr == NULL) @@ -784,8 +785,8 @@ gather_unix(int proto) warnx("struct xunpcb size mismatch"); goto out; } - if ((xup->xu_unp.unp_conn == NULL && !opt_l) || - (xup->xu_unp.unp_conn != NULL && !opt_c)) + if ((xup->unp_conn == NULL && !opt_l) || + (xup->unp_conn != NULL && !opt_c)) continue; if ((sock = calloc(1, sizeof(*sock))) == NULL) err(1, "malloc()"); @@ -798,11 +799,11 @@ gather_unix(int proto) sock->proto = proto; sock->family = AF_UNIX; sock->protoname = protoname; - if (xup->xu_unp.unp_addr != NULL) + if (xup->xu_addr.sun_family == AF_UNIX) laddr->address = *(struct sockaddr_storage *)(void *)&xup->xu_addr; - else if (xup->xu_unp.unp_conn != NULL) - *(void **)&(faddr->address) = xup->xu_unp.unp_conn; + else if (xup->unp_conn != NULL) + *(void **)&(faddr->address) = xup->unp_conn; laddr->next = NULL; faddr->next = NULL; sock->laddr = laddr; diff --git a/usr.bin/soelim/Makefile.depend b/usr.bin/soelim/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/soelim/Makefile.depend +++ b/usr.bin/soelim/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/sort/Makefile.depend b/usr.bin/sort/Makefile.depend index 0940f16c0398..c190762cfcc7 100644 --- a/usr.bin/sort/Makefile.depend +++ b/usr.bin/sort/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/split/Makefile.depend b/usr.bin/split/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/split/Makefile.depend +++ b/usr.bin/split/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/stat/Makefile.depend b/usr.bin/stat/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/stat/Makefile.depend +++ b/usr.bin/stat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/stat/tests/Makefile.depend b/usr.bin/stat/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/stat/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/stdbuf/Makefile.depend b/usr.bin/stdbuf/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/stdbuf/Makefile.depend +++ b/usr.bin/stdbuf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/strings/Makefile.depend b/usr.bin/strings/Makefile.depend index 40241f30eaf8..4f2cad33521d 100644 --- a/usr.bin/strings/Makefile.depend +++ b/usr.bin/strings/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/su/Makefile.depend b/usr.bin/su/Makefile.depend index 85813bf9b52d..ec5c7b0ac3a1 100644 --- a/usr.bin/su/Makefile.depend +++ b/usr.bin/su/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c index 627a35bde25c..6ad691cf0df8 100644 --- a/usr.bin/su/su.c +++ b/usr.bin/su/su.c @@ -172,7 +172,7 @@ main(int argc, char *argv[]) au_id_t auid; #endif - shell = class = cleanenv = NULL; + p = shell = class = cleanenv = NULL; asme = asthem = fastlogin = statusp = 0; user = "root"; iscsh = UNSET; diff --git a/usr.bin/svn/svn/Makefile.depend b/usr.bin/svn/svn/Makefile.depend index 979ea0bb0172..5bcf06ed92b9 100644 --- a/usr.bin/svn/svn/Makefile.depend +++ b/usr.bin/svn/svn/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnadmin/Makefile.depend b/usr.bin/svn/svnadmin/Makefile.depend index 1f7a76064287..bc03ab03dddb 100644 --- a/usr.bin/svn/svnadmin/Makefile.depend +++ b/usr.bin/svn/svnadmin/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnbench/Makefile.depend b/usr.bin/svn/svnbench/Makefile.depend index 979ea0bb0172..5bcf06ed92b9 100644 --- a/usr.bin/svn/svnbench/Makefile.depend +++ b/usr.bin/svn/svnbench/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svndumpfilter/Makefile.depend b/usr.bin/svn/svndumpfilter/Makefile.depend index 8495fb324e88..77b90815c862 100644 --- a/usr.bin/svn/svndumpfilter/Makefile.depend +++ b/usr.bin/svn/svndumpfilter/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnfsfs/Makefile.depend b/usr.bin/svn/svnfsfs/Makefile.depend index 0b846baf1034..48f9d02a71be 100644 --- a/usr.bin/svn/svnfsfs/Makefile.depend +++ b/usr.bin/svn/svnfsfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/svn/svnlook/Makefile.depend b/usr.bin/svn/svnlook/Makefile.depend index aa8be0e96d33..8a567399590a 100644 --- a/usr.bin/svn/svnlook/Makefile.depend +++ b/usr.bin/svn/svnlook/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnmucc/Makefile.depend b/usr.bin/svn/svnmucc/Makefile.depend index c510cb370f3f..14f1e46633f1 100644 --- a/usr.bin/svn/svnmucc/Makefile.depend +++ b/usr.bin/svn/svnmucc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnrdump/Makefile.depend b/usr.bin/svn/svnrdump/Makefile.depend index c510cb370f3f..14f1e46633f1 100644 --- a/usr.bin/svn/svnrdump/Makefile.depend +++ b/usr.bin/svn/svnrdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnserve/Makefile.depend b/usr.bin/svn/svnserve/Makefile.depend index edbca2ec0b54..8abec29e9629 100644 --- a/usr.bin/svn/svnserve/Makefile.depend +++ b/usr.bin/svn/svnserve/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnsync/Makefile.depend b/usr.bin/svn/svnsync/Makefile.depend index 2e39f66407dd..b2330a8694d0 100644 --- a/usr.bin/svn/svnsync/Makefile.depend +++ b/usr.bin/svn/svnsync/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/svn/svnversion/Makefile.depend b/usr.bin/svn/svnversion/Makefile.depend index 65b3e9a18a52..5c4d8e81a85a 100644 --- a/usr.bin/svn/svnversion/Makefile.depend +++ b/usr.bin/svn/svnversion/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/systat/Makefile.depend b/usr.bin/systat/Makefile.depend index f0f460288baf..01628d979f33 100644 --- a/usr.bin/systat/Makefile.depend +++ b/usr.bin/systat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c index 5ab367a0a878..704df8a9dbf1 100644 --- a/usr.bin/systat/netstat.c +++ b/usr.bin/systat/netstat.c @@ -41,6 +41,7 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93"; #include #include #include +#define _WANT_SOCKET #include #include diff --git a/usr.bin/tabs/Makefile.depend b/usr.bin/tabs/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/tabs/Makefile.depend +++ b/usr.bin/tabs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tail/Makefile.depend b/usr.bin/tail/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/tail/Makefile.depend +++ b/usr.bin/tail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tail/tests/Makefile.depend b/usr.bin/tail/tests/Makefile.depend new file mode 100644 index 000000000000..f80275d86ab1 --- /dev/null +++ b/usr.bin/tail/tests/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/talk/Makefile.depend b/usr.bin/talk/Makefile.depend index 618a09dfb669..e812fe003083 100644 --- a/usr.bin/talk/Makefile.depend +++ b/usr.bin/talk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/usr.bin/tar/Makefile.depend b/usr.bin/tar/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/tar/Makefile.depend +++ b/usr.bin/tar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tar/tests/Makefile b/usr.bin/tar/tests/Makefile index c64686e2dca2..7fba6e077f93 100644 --- a/usr.bin/tar/tests/Makefile +++ b/usr.bin/tar/tests/Makefile @@ -35,6 +35,7 @@ TESTS_SRCS= \ test_extract_tar_lzma.c \ test_extract_tar_lzo.c \ test_extract_tar_xz.c \ + test_extract_tar_zstd.c \ test_format_newc.c \ test_help.c \ test_leading_slash.c \ @@ -74,6 +75,7 @@ TESTS_SRCS= \ test_option_xattrs.c \ test_option_xz.c \ test_option_z.c \ + test_option_zstd.c \ test_patterns.c \ test_print_longpath.c \ test_stdio.c \ @@ -108,6 +110,7 @@ ${PACKAGE}FILES+= test_extract.tar.lz4.uu ${PACKAGE}FILES+= test_extract.tar.lzma.uu ${PACKAGE}FILES+= test_extract.tar.lzo.uu ${PACKAGE}FILES+= test_extract.tar.xz.uu +${PACKAGE}FILES+= test_extract.tar.zst.uu ${PACKAGE}FILES+= test_leading_slash.tar.uu ${PACKAGE}FILES+= test_option_keep_newer_files.tar.Z.uu ${PACKAGE}FILES+= test_option_passphrase.zip.uu diff --git a/usr.bin/tar/tests/Makefile.depend b/usr.bin/tar/tests/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/tar/tests/Makefile.depend +++ b/usr.bin/tar/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tcopy/Makefile.depend b/usr.bin/tcopy/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/tcopy/Makefile.depend +++ b/usr.bin/tcopy/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tee/Makefile.depend b/usr.bin/tee/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/tee/Makefile.depend +++ b/usr.bin/tee/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/telnet/Makefile.depend b/usr.bin/telnet/Makefile.depend index 6578e9f74a47..506b38fa84b2 100644 --- a/usr.bin/telnet/Makefile.depend +++ b/usr.bin/telnet/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/tftp/Makefile.depend b/usr.bin/tftp/Makefile.depend index d6c8db88e89b..965e3a120be6 100644 --- a/usr.bin/tftp/Makefile.depend +++ b/usr.bin/tftp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/time/Makefile.depend b/usr.bin/time/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/time/Makefile.depend +++ b/usr.bin/time/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/timeout/Makefile.depend b/usr.bin/timeout/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/timeout/Makefile.depend +++ b/usr.bin/timeout/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tip/tip/Makefile.depend b/usr.bin/tip/tip/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/tip/tip/Makefile.depend +++ b/usr.bin/tip/tip/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/top/Makefile.depend b/usr.bin/top/Makefile.depend index fafa76b62245..9fc529fc3ec7 100644 --- a/usr.bin/top/Makefile.depend +++ b/usr.bin/top/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index 6acfb38323ae..2d97d7f867f3 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -1671,8 +1671,9 @@ static int swapmode(int *retavail, int *retfree) { int n; - int pagesize = getpagesize(); struct kvm_swap swapary[1]; + static int pagesize = 0; + static u_long swap_maxpages = 0; *retavail = 0; *retfree = 0; @@ -1683,6 +1684,16 @@ swapmode(int *retavail, int *retfree) if (n < 0 || swapary[0].ksw_total == 0) return (0); + if (pagesize == 0) + pagesize = getpagesize(); + if (swap_maxpages == 0) + GETSYSCTL("vm.swap_maxpages", swap_maxpages); + + /* ksw_total contains the total size of swap all devices which may + exceed the maximum swap size allocatable in the system */ + if ( swapary[0].ksw_total > swap_maxpages ) + swapary[0].ksw_total = swap_maxpages; + *retavail = CONVERT(swapary[0].ksw_total); *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used); diff --git a/usr.bin/touch/Makefile.depend b/usr.bin/touch/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/touch/Makefile.depend +++ b/usr.bin/touch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tput/Makefile.depend b/usr.bin/tput/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/tput/Makefile.depend +++ b/usr.bin/tput/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tr/Makefile.depend b/usr.bin/tr/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/tr/Makefile.depend +++ b/usr.bin/tr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/true/Makefile.depend b/usr.bin/true/Makefile.depend index 43d71f8b2760..03d33794d0e3 100644 --- a/usr.bin/true/Makefile.depend +++ b/usr.bin/true/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ diff --git a/usr.bin/truncate/Makefile.depend b/usr.bin/truncate/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.bin/truncate/Makefile.depend +++ b/usr.bin/truncate/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/truss/Makefile.depend b/usr.bin/truss/Makefile.depend index 3c34d02197b2..fa7ed60a07d9 100644 --- a/usr.bin/truss/Makefile.depend +++ b/usr.bin/truss/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index 84fd37e2a4d8..052546a032c0 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -57,8 +57,8 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n", - "usage: truss [-cfaedDS] [-o file] [-s strsize] -p pid", - " truss [-cfaedDS] [-o file] [-s strsize] command [args]"); + "usage: truss [-cfaedDHS] [-o file] [-s strsize] -p pid", + " truss [-cfaedDHS] [-o file] [-s strsize] command [args]"); exit(1); } diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index f6585ebc3abd..251a43f6cec3 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -734,7 +734,7 @@ static struct xlat cloudabi_fdsflags[] = { static struct xlat cloudabi_filetype[] = { X(FILETYPE_UNKNOWN) X(FILETYPE_BLOCK_DEVICE) X(FILETYPE_CHARACTER_DEVICE) X(FILETYPE_DIRECTORY) - X(FILETYPE_POLL) X(FILETYPE_PROCESS) X(FILETYPE_REGULAR_FILE) + X(FILETYPE_PROCESS) X(FILETYPE_REGULAR_FILE) X(FILETYPE_SHARED_MEMORY) X(FILETYPE_SOCKET_DGRAM) X(FILETYPE_SOCKET_STREAM) X(FILETYPE_SYMBOLIC_LINK) XEND diff --git a/usr.bin/tset/Makefile.depend b/usr.bin/tset/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/tset/Makefile.depend +++ b/usr.bin/tset/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tsort/Makefile.depend b/usr.bin/tsort/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/tsort/Makefile.depend +++ b/usr.bin/tsort/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/tty/Makefile.depend b/usr.bin/tty/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/tty/Makefile.depend +++ b/usr.bin/tty/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/ul/Makefile.depend b/usr.bin/ul/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.bin/ul/Makefile.depend +++ b/usr.bin/ul/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/uname/Makefile.depend b/usr.bin/uname/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/uname/Makefile.depend +++ b/usr.bin/uname/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/unexpand/Makefile.depend b/usr.bin/unexpand/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/unexpand/Makefile.depend +++ b/usr.bin/unexpand/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/unifdef/Makefile.depend b/usr.bin/unifdef/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/unifdef/Makefile.depend +++ b/usr.bin/unifdef/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/unifdef/unifdef.1 b/usr.bin/unifdef/unifdef.1 index 430f743b6b4f..2bbefc0a2947 100644 --- a/usr.bin/unifdef/unifdef.1 +++ b/usr.bin/unifdef/unifdef.1 @@ -477,7 +477,7 @@ Unterminated char or string literal .Xr diff 1 .Pp The unifdef home page is -.Pa http://dotat.at/prog/unifdef +.Pa https://dotat.at/prog/unifdef .Sh HISTORY The .Nm diff --git a/usr.bin/unifdef/unifdef.c b/usr.bin/unifdef/unifdef.c index 4a28ed435641..290a15a33f72 100644 --- a/usr.bin/unifdef/unifdef.c +++ b/usr.bin/unifdef/unifdef.c @@ -49,7 +49,7 @@ static const char copyright[] = "@(#) $Version: unifdef-2.11 $\n" "@(#) $FreeBSD$\n" "@(#) $Author: Tony Finch (dot@dotat.at) $\n" - "@(#) $URL: http://dotat.at/prog/unifdef $\n" + "@(#) $URL: https://dotat.at/prog/unifdef $\n" ; /* types of input lines: */ diff --git a/usr.bin/uniq/Makefile.depend b/usr.bin/uniq/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/uniq/Makefile.depend +++ b/usr.bin/uniq/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/units/Makefile.depend b/usr.bin/units/Makefile.depend index 3d9203935abf..0e0490b10835 100644 --- a/usr.bin/units/Makefile.depend +++ b/usr.bin/units/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/units/definitions.units b/usr.bin/units/definitions.units index 2ebcf4f29688..65120a239b57 100644 --- a/usr.bin/units/definitions.units +++ b/usr.bin/units/definitions.units @@ -332,7 +332,7 @@ lumen cd sr lux cd sr/m2 # EMU currencies have constant exchange rate against Euro since 1.1.1999. -# See http://en.wikipedia.org/wiki/Euro for details. +# See https://en.wikipedia.org/wiki/Euro for details. austriaschilling 1|13.7603 euro belgiumfranc 1|40.3399 euro finlandmarkka 1|5.94573 euro @@ -351,7 +351,7 @@ malteselira 1|0.429300 euro slovakkoruna 1|30.1260 euro # These ones are pegged to the Euro -# See http://en.wikipedia.org/wiki/Euro for details. +# See https://en.wikipedia.org/wiki/Euro for details. bosniaherzegovinamark 1|1.95583 euro bulgarianlev 1|1.95583 euro capeverdeanescudo 1|110.265 euro @@ -528,7 +528,7 @@ ZMW zambiakwacha ZWL zimbabwedollar # These ones are pegged on the US Dollar -# See http://en.wikipedia.org/wiki/USD for details. +# See https://en.wikipedia.org/wiki/USD for details. dollar usdollar arubanflorin 1|1.75 usdollar bahamiandollar 1|1 usdollar diff --git a/usr.bin/unvis/Makefile.depend b/usr.bin/unvis/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/unvis/Makefile.depend +++ b/usr.bin/unvis/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/unzip/Makefile.depend b/usr.bin/unzip/Makefile.depend index 4e7906b9d349..138ae4120671 100644 --- a/usr.bin/unzip/Makefile.depend +++ b/usr.bin/unzip/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/usbhidaction/Makefile.depend b/usr.bin/usbhidaction/Makefile.depend index 3a42599fdd9b..e80cab0974c8 100644 --- a/usr.bin/usbhidaction/Makefile.depend +++ b/usr.bin/usbhidaction/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/usbhidctl/Makefile.depend b/usr.bin/usbhidctl/Makefile.depend index 3a42599fdd9b..e80cab0974c8 100644 --- a/usr.bin/usbhidctl/Makefile.depend +++ b/usr.bin/usbhidctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/users/Makefile.depend b/usr.bin/users/Makefile.depend index b6027086c86c..ea8bba31ec06 100644 --- a/usr.bin/users/Makefile.depend +++ b/usr.bin/users/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/uudecode/Makefile.depend b/usr.bin/uudecode/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/uudecode/Makefile.depend +++ b/usr.bin/uudecode/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/uuencode/Makefile.depend b/usr.bin/uuencode/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/uuencode/Makefile.depend +++ b/usr.bin/uuencode/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/vacation/Makefile.depend b/usr.bin/vacation/Makefile.depend index b0af42fdb943..0feabbf167e0 100644 --- a/usr.bin/vacation/Makefile.depend +++ b/usr.bin/vacation/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/vgrind/Makefile.depend b/usr.bin/vgrind/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/vgrind/Makefile.depend +++ b/usr.bin/vgrind/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/vi/Makefile.depend b/usr.bin/vi/Makefile.depend index 57c7034f7f1d..274b0a661c9d 100644 --- a/usr.bin/vi/Makefile.depend +++ b/usr.bin/vi/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/vis/Makefile.depend b/usr.bin/vis/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/vis/Makefile.depend +++ b/usr.bin/vis/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/vmstat/Makefile.depend b/usr.bin/vmstat/Makefile.depend index 742f642bc94e..322cfcb729e6 100644 --- a/usr.bin/vmstat/Makefile.depend +++ b/usr.bin/vmstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/vtfontcvt/Makefile.depend b/usr.bin/vtfontcvt/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/vtfontcvt/Makefile.depend +++ b/usr.bin/vtfontcvt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/w/Makefile.depend b/usr.bin/w/Makefile.depend index fd7546e46147..93b426d97e90 100644 --- a/usr.bin/w/Makefile.depend +++ b/usr.bin/w/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/wall/Makefile.depend b/usr.bin/wall/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/wall/Makefile.depend +++ b/usr.bin/wall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/wc/Makefile.depend b/usr.bin/wc/Makefile.depend index 137678c21e46..5770a091f2a6 100644 --- a/usr.bin/wc/Makefile.depend +++ b/usr.bin/wc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/what/Makefile.depend b/usr.bin/what/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.bin/what/Makefile.depend +++ b/usr.bin/what/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.bin/whereis/Makefile.depend b/usr.bin/whereis/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/whereis/Makefile.depend +++ b/usr.bin/whereis/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/which/Makefile.depend b/usr.bin/which/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/which/Makefile.depend +++ b/usr.bin/which/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/who/Makefile.depend b/usr.bin/who/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/who/Makefile.depend +++ b/usr.bin/who/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/whois/Makefile.depend b/usr.bin/whois/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.bin/whois/Makefile.depend +++ b/usr.bin/whois/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.bin/write/Makefile.depend b/usr.bin/write/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/write/Makefile.depend +++ b/usr.bin/write/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xargs/Makefile.depend b/usr.bin/xargs/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/xargs/Makefile.depend +++ b/usr.bin/xargs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xinstall/Makefile.depend b/usr.bin/xinstall/Makefile.depend index b4491b508ea5..a2d871d3f1b9 100644 --- a/usr.bin/xinstall/Makefile.depend +++ b/usr.bin/xinstall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 44ab194f9fbb..16eba7768d89 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -1292,17 +1292,19 @@ install_dir(char *path) { char *p; struct stat sb; - int ch; + int ch, tried_mkdir; for (p = path;; ++p) if (!*p || (p != path && *p == '/')) { + tried_mkdir = 0; ch = *p; *p = '\0'; again: if (stat(path, &sb) < 0) { - if (errno != ENOENT) + if (errno != ENOENT || tried_mkdir) err(EX_OSERR, "stat %s", path); if (mkdir(path, 0755) < 0) { + tried_mkdir = 1; if (errno == EEXIST) goto again; err(EX_OSERR, "mkdir %s", path); diff --git a/usr.bin/xlint/lint1/Makefile.depend b/usr.bin/xlint/lint1/Makefile.depend index dab799564cd4..8f4224119cdd 100644 --- a/usr.bin/xlint/lint1/Makefile.depend +++ b/usr.bin/xlint/lint1/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xlint/lint2/Makefile.depend b/usr.bin/xlint/lint2/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/xlint/lint2/Makefile.depend +++ b/usr.bin/xlint/lint2/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xlint/xlint/Makefile.depend b/usr.bin/xlint/xlint/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/xlint/xlint/Makefile.depend +++ b/usr.bin/xlint/xlint/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xo/Makefile.depend b/usr.bin/xo/Makefile.depend index 137678c21e46..5770a091f2a6 100644 --- a/usr.bin/xo/Makefile.depend +++ b/usr.bin/xo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xohtml/xohtml.sh b/usr.bin/xohtml/xohtml.sh index 932993488f3b..58d52388d61c 100755 --- a/usr.bin/xohtml/xohtml.sh +++ b/usr.bin/xohtml/xohtml.sh @@ -15,7 +15,7 @@ BASE=/usr/share/libxo VERSION=0.8.4 CMD=cat DONE= -WEB=http://juniper.github.io/libxo/${VERSION}/xohtml +WEB=https://juniper.github.io/libxo/${VERSION}/xohtml do_help () { echo "xohtml: wrap libxo-enabled output in HTML" diff --git a/usr.bin/xstr/Makefile.depend b/usr.bin/xstr/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/xstr/Makefile.depend +++ b/usr.bin/xstr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xz/Makefile.depend b/usr.bin/xz/Makefile.depend index 987c48738e8a..c02c88a2cd25 100644 --- a/usr.bin/xz/Makefile.depend +++ b/usr.bin/xz/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/xzdec/Makefile.depend b/usr.bin/xzdec/Makefile.depend index 987c48738e8a..c02c88a2cd25 100644 --- a/usr.bin/xzdec/Makefile.depend +++ b/usr.bin/xzdec/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/yacc/Makefile.depend b/usr.bin/yacc/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.bin/yacc/Makefile.depend +++ b/usr.bin/yacc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/yes/Makefile.depend b/usr.bin/yes/Makefile.depend index 4def626103ce..1adfc08a54d6 100644 --- a/usr.bin/yes/Makefile.depend +++ b/usr.bin/yes/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.bin/ypcat/Makefile.depend b/usr.bin/ypcat/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.bin/ypcat/Makefile.depend +++ b/usr.bin/ypcat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/ypmatch/Makefile.depend b/usr.bin/ypmatch/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.bin/ypmatch/Makefile.depend +++ b/usr.bin/ypmatch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.bin/ypwhich/Makefile.depend b/usr.bin/ypwhich/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.bin/ypwhich/Makefile.depend +++ b/usr.bin/ypwhich/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.bin/zstd/Makefile.depend b/usr.bin/zstd/Makefile.depend index 6d2c75dd4bbe..dc77a14e7964 100644 --- a/usr.bin/zstd/Makefile.depend +++ b/usr.bin/zstd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index cb7aabc5be37..a8eaa9f9c6ac 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -61,7 +61,6 @@ SUBDIR= adduser \ pciconf \ periodic \ powerd \ - procctl \ prometheus_sysctl_exporter \ pstat \ pw \ diff --git a/usr.sbin/ac/Makefile.depend b/usr.sbin/ac/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/ac/Makefile.depend +++ b/usr.sbin/ac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/accton/Makefile.depend b/usr.sbin/accton/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/accton/Makefile.depend +++ b/usr.sbin/accton/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/acpi/acpiconf/Makefile.depend b/usr.sbin/acpi/acpiconf/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/acpi/acpiconf/Makefile.depend +++ b/usr.sbin/acpi/acpiconf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/acpi/acpidb/Makefile.depend b/usr.sbin/acpi/acpidb/Makefile.depend index 7b92dbd89f4a..8bb1973e0ff5 100644 --- a/usr.sbin/acpi/acpidb/Makefile.depend +++ b/usr.sbin/acpi/acpidb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/acpi/acpidump/Makefile.depend b/usr.sbin/acpi/acpidump/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/acpi/acpidump/Makefile.depend +++ b/usr.sbin/acpi/acpidump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index 44fa594f8dc7..7529094196c8 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -65,6 +65,7 @@ static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp); static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp); static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp); static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp); +static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp); static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, uint32_t flags); static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp); @@ -678,6 +679,40 @@ acpi_handle_slit(ACPI_TABLE_HEADER *sdp) printf(END_COMMENT); } +static void +acpi_handle_wddt(ACPI_TABLE_HEADER *sdp) +{ + ACPI_TABLE_WDDT *wddt; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + wddt = (ACPI_TABLE_WDDT *)sdp; + printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n", + wddt->SpecVersion, wddt->TableVersion); + printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId); + acpi_print_gas(&wddt->Address); + printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n", + wddt->MaxCount, wddt->MinCount, wddt->Period); + +#define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag) + printf("\tStatus="); + PRINTFLAG(wddt->Status, AVAILABLE); + PRINTFLAG(wddt->Status, ACTIVE); + PRINTFLAG(wddt->Status, TCO_OS_OWNED); + PRINTFLAG(wddt->Status, USER_RESET); + PRINTFLAG(wddt->Status, WDT_RESET); + PRINTFLAG(wddt->Status, POWER_FAIL); + PRINTFLAG(wddt->Status, UNKNOWN_RESET); + PRINTFLAG_END(); + printf("\tCapability="); + PRINTFLAG(wddt->Capability, AUTO_RESET); + PRINTFLAG(wddt->Capability, ALERT_SUPPORT); + PRINTFLAG_END(); +#undef PRINTFLAG + + printf(END_COMMENT); +} + static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, uint32_t flags) @@ -1654,6 +1689,8 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp) acpi_handle_dmar(sdp); else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4)) acpi_handle_nfit(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4)) + acpi_handle_wddt(sdp); else { printf(BEGIN_COMMENT); acpi_print_sdt(sdp); diff --git a/usr.sbin/acpi/acpidump/acpidump.8 b/usr.sbin/acpi/acpidump/acpidump.8 index a03917a1baba..60d4b5d3d779 100644 --- a/usr.sbin/acpi/acpidump/acpidump.8 +++ b/usr.sbin/acpi/acpidump/acpidump.8 @@ -107,6 +107,7 @@ utility dumps contents of the following tables: .It MCFG .It RSD PTR .It RSDT +.It WDDT .El .Pp The RSDT contains a pointer to the physical memory address of the FACP diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile index b3c08c0ffba6..8171d5ae73ac 100644 --- a/usr.sbin/acpi/iasl/Makefile +++ b/usr.sbin/acpi/iasl/Makefile @@ -9,27 +9,27 @@ SRCS= acfileio.c adfile.c adisasm.c adwalk.c ahids.c \ dmtbinfo.c getopt.c # compiler -SRCS+= aslanalyze.c aslascii.c aslbtypes.c aslcodegen.c \ - aslcompile.c aslcompiler.y.h aslcompilerlex.c \ - aslcompilerparse.c asldebug.c aslerror.c aslexternal.c \ - aslfileio.c aslfiles.c aslfold.c aslhelp.c aslhex.c \ - asllength.c asllisting.c asllistsup.c aslload.c \ - asllookup.c aslmain.c aslmap.c aslmapenter.c \ - aslmapoutput.c aslmaputils.c aslmessages.c aslmethod.c \ - aslnamesp.c asloffset.c aslopcodes.c asloperands.c \ - aslopt.c asloptions.c aslparseop.c aslpld.c aslpredef.c \ - aslprepkg.c aslprintf.c aslprune.c aslresource.c \ - aslrestype1.c aslrestype1i.c aslrestype2.c \ - aslrestype2d.c aslrestype2e.c aslrestype2q.c \ - aslrestype2s.c aslrestype2w.c aslstartup.c aslstubs.c \ - asltransform.c asltree.c aslutils.c asluuid.c \ - aslwalks.c aslxref.c aslxrefout.c cvcompiler.c \ - cvdisasm.c cvparser.c dtcompile.c dtexpress.c dtfield.c \ - dtio.c dtparser.y.h dtparserlex.c dtparserparse.c \ - dtsubtable.c dttable.c dttable1.c dttable2.c \ - dttemplate.c dtutils.c prexpress.c prmacros.c \ - prparser.y.h prparserlex.c prparserparse.c prscan.c \ - prutils.c +SRCS+= aslallocate.c aslanalyze.c aslascii.c aslbtypes.c \ + aslcache.c aslcodegen.c aslcompile.c aslcompiler.y.h \ + aslcompilerlex.c aslcompilerparse.c asldebug.c \ + aslerror.c aslexternal.c aslfileio.c aslfiles.c \ + aslfold.c aslhelp.c aslhex.c asllength.c asllisting.c \ + asllistsup.c aslload.c asllookup.c aslmain.c aslmap.c \ + aslmapenter.c aslmapoutput.c aslmaputils.c \ + aslmessages.c aslmethod.c aslnamesp.c asloffset.c \ + aslopcodes.c asloperands.c aslopt.c asloptions.c \ + aslparseop.c aslpld.c aslpredef.c aslprepkg.c \ + aslprintf.c aslprune.c aslresource.c aslrestype1.c \ + aslrestype1i.c aslrestype2.c aslrestype2d.c \ + aslrestype2e.c aslrestype2q.c aslrestype2s.c \ + aslrestype2w.c aslstartup.c aslstubs.c asltransform.c \ + asltree.c aslutils.c asluuid.c aslwalks.c aslxref.c \ + aslxrefout.c cvcompiler.c cvdisasm.c cvparser.c \ + dtcompile.c dtexpress.c dtfield.c dtio.c dtparser.y.h \ + dtparserlex.c dtparserparse.c dtsubtable.c dttable.c \ + dttable1.c dttable2.c dttemplate.c dtutils.c \ + prexpress.c prmacros.c prparser.y.h prparserlex.c \ + prparserparse.c prscan.c prutils.c # components/debugger SRCS+= dbfileio.c diff --git a/usr.sbin/acpi/iasl/Makefile.depend b/usr.sbin/acpi/iasl/Makefile.depend index ca0b2f9610f7..d084433f911c 100644 --- a/usr.sbin/acpi/iasl/Makefile.depend +++ b/usr.sbin/acpi/iasl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/adduser/adduser.8 b/usr.sbin/adduser/adduser.8 index 2e6a5b5a3897..6687ed0ef988 100644 --- a/usr.sbin/adduser/adduser.8 +++ b/usr.sbin/adduser/adduser.8 @@ -436,7 +436,6 @@ logfile for .Xr login.conf 5 , .Xr passwd 5 , .Xr shells 5 , -.Xr adding_user 8 , .Xr pw 8 , .Xr pwd_mkdb 8 , .Xr rmuser 8 , diff --git a/usr.sbin/amd/amd/Makefile.depend b/usr.sbin/amd/amd/Makefile.depend index 5f63255c3f8b..3478f9fbed72 100644 --- a/usr.sbin/amd/amd/Makefile.depend +++ b/usr.sbin/amd/amd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/amq/Makefile.depend b/usr.sbin/amd/amq/Makefile.depend index 0e0bb6e1e1f1..eec6cd4d599b 100644 --- a/usr.sbin/amd/amq/Makefile.depend +++ b/usr.sbin/amd/amq/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/fixmount/Makefile.depend b/usr.sbin/amd/fixmount/Makefile.depend index a47404470813..659d244d0cd6 100644 --- a/usr.sbin/amd/fixmount/Makefile.depend +++ b/usr.sbin/amd/fixmount/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/fsinfo/Makefile.depend b/usr.sbin/amd/fsinfo/Makefile.depend index cfaeac1fe13e..9563855e5f3a 100644 --- a/usr.sbin/amd/fsinfo/Makefile.depend +++ b/usr.sbin/amd/fsinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/hlfsd/Makefile.depend b/usr.sbin/amd/hlfsd/Makefile.depend index 0e0bb6e1e1f1..eec6cd4d599b 100644 --- a/usr.sbin/amd/hlfsd/Makefile.depend +++ b/usr.sbin/amd/hlfsd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/mk-amd-map/Makefile.depend b/usr.sbin/amd/mk-amd-map/Makefile.depend index 0e0bb6e1e1f1..eec6cd4d599b 100644 --- a/usr.sbin/amd/mk-amd-map/Makefile.depend +++ b/usr.sbin/amd/mk-amd-map/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/pawd/Makefile.depend b/usr.sbin/amd/pawd/Makefile.depend index 0e0bb6e1e1f1..eec6cd4d599b 100644 --- a/usr.sbin/amd/pawd/Makefile.depend +++ b/usr.sbin/amd/pawd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/amd/wire-test/Makefile.depend b/usr.sbin/amd/wire-test/Makefile.depend index 0e0bb6e1e1f1..eec6cd4d599b 100644 --- a/usr.sbin/amd/wire-test/Makefile.depend +++ b/usr.sbin/amd/wire-test/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/ancontrol/Makefile.depend b/usr.sbin/ancontrol/Makefile.depend index 6a2d4068b6cc..9dfb51c0b371 100644 --- a/usr.sbin/ancontrol/Makefile.depend +++ b/usr.sbin/ancontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/apm/Makefile.depend b/usr.sbin/apm/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/apm/Makefile.depend +++ b/usr.sbin/apm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/apmd/Makefile.depend b/usr.sbin/apmd/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/usr.sbin/apmd/Makefile.depend +++ b/usr.sbin/apmd/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/arp/Makefile.depend b/usr.sbin/arp/Makefile.depend index 7fad2713c8db..a0d0ea100062 100644 --- a/usr.sbin/arp/Makefile.depend +++ b/usr.sbin/arp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/asf/Makefile.depend b/usr.sbin/asf/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/usr.sbin/asf/Makefile.depend +++ b/usr.sbin/asf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/audit/Makefile.depend b/usr.sbin/audit/Makefile.depend index 97143a89bccf..2511c90c76b0 100644 --- a/usr.sbin/audit/Makefile.depend +++ b/usr.sbin/audit/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/auditd/Makefile.depend b/usr.sbin/auditd/Makefile.depend index ae040b6a0df0..b5a4efa4ee85 100644 --- a/usr.sbin/auditd/Makefile.depend +++ b/usr.sbin/auditd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/auditdistd/Makefile.depend b/usr.sbin/auditdistd/Makefile.depend index 82c7f95daedf..5d5b308975cf 100644 --- a/usr.sbin/auditdistd/Makefile.depend +++ b/usr.sbin/auditdistd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/auditreduce/Makefile.depend b/usr.sbin/auditreduce/Makefile.depend index 97143a89bccf..2511c90c76b0 100644 --- a/usr.sbin/auditreduce/Makefile.depend +++ b/usr.sbin/auditreduce/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/authpf/Makefile.depend b/usr.sbin/authpf/Makefile.depend index fb0a041a5aab..0f7ec3606b47 100644 --- a/usr.sbin/authpf/Makefile.depend +++ b/usr.sbin/authpf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/autofs/Makefile.depend b/usr.sbin/autofs/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/autofs/Makefile.depend +++ b/usr.sbin/autofs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bhyve/Makefile.depend b/usr.sbin/bhyve/Makefile.depend index 6a1e47258af7..07fe2b5b7d05 100644 --- a/usr.sbin/bhyve/Makefile.depend +++ b/usr.sbin/bhyve/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/bhyve/xmsr.c b/usr.sbin/bhyve/xmsr.c index 5b7bfbbc71e3..55992a71cdd9 100644 --- a/usr.sbin/bhyve/xmsr.c +++ b/usr.sbin/bhyve/xmsr.c @@ -188,7 +188,7 @@ emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) /* * OpenBSD guests test bit 0 of this MSR to detect if the * workaround for erratum 721 is already applied. - * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf + * https://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf */ case 0xC0011029: *val = 1; diff --git a/usr.sbin/bhyvectl/Makefile.depend b/usr.sbin/bhyvectl/Makefile.depend index 2d0f3243a1db..0550c3e85424 100644 --- a/usr.sbin/bhyvectl/Makefile.depend +++ b/usr.sbin/bhyvectl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bhyveload/Makefile.depend b/usr.sbin/bhyveload/Makefile.depend index 2d0f3243a1db..0550c3e85424 100644 --- a/usr.sbin/bhyveload/Makefile.depend +++ b/usr.sbin/bhyveload/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/binmiscctl/Makefile.depend b/usr.sbin/binmiscctl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/binmiscctl/Makefile.depend +++ b/usr.sbin/binmiscctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/blacklistctl/Makefile.depend b/usr.sbin/blacklistctl/Makefile.depend index 5ac9545f6f12..741c9b987127 100644 --- a/usr.sbin/blacklistctl/Makefile.depend +++ b/usr.sbin/blacklistctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/blacklistd/Makefile.depend b/usr.sbin/blacklistd/Makefile.depend index 5ac9545f6f12..741c9b987127 100644 --- a/usr.sbin/blacklistd/Makefile.depend +++ b/usr.sbin/blacklistd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/bluetooth/ath3kfw/Makefile.depend b/usr.sbin/bluetooth/ath3kfw/Makefile.depend index 3ddb39c3f983..a93901938c4b 100644 --- a/usr.sbin/bluetooth/ath3kfw/Makefile.depend +++ b/usr.sbin/bluetooth/ath3kfw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/bcmfw/Makefile.depend b/usr.sbin/bluetooth/bcmfw/Makefile.depend index 92ae034c03ef..3f4cb50e1709 100644 --- a/usr.sbin/bluetooth/bcmfw/Makefile.depend +++ b/usr.sbin/bluetooth/bcmfw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/bt3cfw/Makefile.depend b/usr.sbin/bluetooth/bt3cfw/Makefile.depend index 92ae034c03ef..3f4cb50e1709 100644 --- a/usr.sbin/bluetooth/bt3cfw/Makefile.depend +++ b/usr.sbin/bluetooth/bt3cfw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/bthidcontrol/Makefile.depend b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend index bc60d3027fff..025b326c97f5 100644 --- a/usr.sbin/bluetooth/bthidcontrol/Makefile.depend +++ b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/bthidd/Makefile.depend b/usr.sbin/bluetooth/bthidd/Makefile.depend index 5c2aa9d173a3..1549057016d2 100644 --- a/usr.sbin/bluetooth/bthidd/Makefile.depend +++ b/usr.sbin/bluetooth/bthidd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/bthidd/hid.c b/usr.sbin/bluetooth/bthidd/hid.c index 9dd9d5fc8166..263ecd8b68f9 100644 --- a/usr.sbin/bluetooth/bthidd/hid.c +++ b/usr.sbin/bluetooth/bthidd/hid.c @@ -169,7 +169,7 @@ hid_interrupt(bthid_session_p s, uint8_t *data, int32_t len) hid_data_t d; hid_item_t h; int32_t report_id, usage, page, val, - mouse_x, mouse_y, mouse_z, mouse_butt, + mouse_x, mouse_y, mouse_z, mouse_t, mouse_butt, mevents, kevents, i; assert(s != NULL); @@ -196,7 +196,8 @@ hid_interrupt(bthid_session_p s, uint8_t *data, int32_t len) hid_device = get_hid_device(&s->bdaddr); assert(hid_device != NULL); - mouse_x = mouse_y = mouse_z = mouse_butt = mevents = kevents = 0; + mouse_x = mouse_y = mouse_z = mouse_t = mouse_butt = 0; + mevents = kevents = 0; for (d = hid_start_parse(hid_device->desc, 1 << hid_input, -1); hid_get_item(d, &h) > 0; ) { @@ -283,11 +284,7 @@ hid_interrupt(bthid_session_p s, uint8_t *data, int32_t len) switch (usage) { case HUC_AC_PAN: /* Horizontal scroll */ - if (val < 0) - mouse_butt |= (1 << 5); - else - mouse_butt |= (1 << 6); - + mouse_t = val; mevents ++; val = 0; break; @@ -529,7 +526,20 @@ hid_interrupt(bthid_session_p s, uint8_t *data, int32_t len) if (mevents > 0) { struct mouse_info mi; + memset(&mi, 0, sizeof(mi)); mi.operation = MOUSE_ACTION; + mi.u.data.buttons = mouse_butt; + + /* translate T-axis into button presses */ + if (mouse_t != 0) { + mi.u.data.buttons |= 1 << (mouse_t > 0 ? 6 : 5); + if (ioctl(s->srv->cons, CONS_MOUSECTL, &mi) < 0) + syslog(LOG_ERR, "Could not process mouse " \ + "events from %s. %s (%d)", + bt_ntoa(&s->bdaddr, NULL), + strerror(errno), errno); + } + mi.u.data.x = mouse_x; mi.u.data.y = mouse_y; mi.u.data.z = mouse_z; diff --git a/usr.sbin/bluetooth/bthidd/kbd.c b/usr.sbin/bluetooth/bthidd/kbd.c index a92a63a7c444..e946f0169fe7 100644 --- a/usr.sbin/bluetooth/bthidd/kbd.c +++ b/usr.sbin/bluetooth/bthidd/kbd.c @@ -569,6 +569,11 @@ kbd_status_changed(bthid_session_p s, uint8_t *data, int32_t len) } hid_end_parse(d); + if (report_id != NO_REPORT_ID) { + data[2] = data[1]; + data[1] = report_id; + } + if (found) write(s->intr, data, (report_id != NO_REPORT_ID) ? 3 : 2); diff --git a/usr.sbin/bluetooth/btpand/Makefile.depend b/usr.sbin/bluetooth/btpand/Makefile.depend index 4633528bfb23..b4d153024640 100644 --- a/usr.sbin/bluetooth/btpand/Makefile.depend +++ b/usr.sbin/bluetooth/btpand/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/hccontrol/Makefile.depend b/usr.sbin/bluetooth/hccontrol/Makefile.depend index 5d2103865524..f556d37ea8e6 100644 --- a/usr.sbin/bluetooth/hccontrol/Makefile.depend +++ b/usr.sbin/bluetooth/hccontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/hcsecd/Makefile.depend b/usr.sbin/bluetooth/hcsecd/Makefile.depend index f11236ea3671..0ef8a0651b9f 100644 --- a/usr.sbin/bluetooth/hcsecd/Makefile.depend +++ b/usr.sbin/bluetooth/hcsecd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/hcseriald/Makefile.depend b/usr.sbin/bluetooth/hcseriald/Makefile.depend index 92ae034c03ef..3f4cb50e1709 100644 --- a/usr.sbin/bluetooth/hcseriald/Makefile.depend +++ b/usr.sbin/bluetooth/hcseriald/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/l2control/Makefile.depend b/usr.sbin/bluetooth/l2control/Makefile.depend index 5d2103865524..f556d37ea8e6 100644 --- a/usr.sbin/bluetooth/l2control/Makefile.depend +++ b/usr.sbin/bluetooth/l2control/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/l2ping/Makefile.depend b/usr.sbin/bluetooth/l2ping/Makefile.depend index 179dbbe07ac2..3dfd9699a934 100644 --- a/usr.sbin/bluetooth/l2ping/Makefile.depend +++ b/usr.sbin/bluetooth/l2ping/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend b/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend index 8fea47e509de..65af16d12ab3 100644 --- a/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend +++ b/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/sdpcontrol/Makefile.depend b/usr.sbin/bluetooth/sdpcontrol/Makefile.depend index 8fea47e509de..65af16d12ab3 100644 --- a/usr.sbin/bluetooth/sdpcontrol/Makefile.depend +++ b/usr.sbin/bluetooth/sdpcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bluetooth/sdpd/Makefile.depend b/usr.sbin/bluetooth/sdpd/Makefile.depend index ce65fbb37449..feddf3a700bc 100644 --- a/usr.sbin/bluetooth/sdpd/Makefile.depend +++ b/usr.sbin/bluetooth/sdpd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/boot0cfg/Makefile.depend b/usr.sbin/boot0cfg/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/usr.sbin/boot0cfg/Makefile.depend +++ b/usr.sbin/boot0cfg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bootparamd/bootparamd/Makefile.depend b/usr.sbin/bootparamd/bootparamd/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/bootparamd/bootparamd/Makefile.depend +++ b/usr.sbin/bootparamd/bootparamd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/bootparamd/callbootd/Makefile.depend b/usr.sbin/bootparamd/callbootd/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/bootparamd/callbootd/Makefile.depend +++ b/usr.sbin/bootparamd/callbootd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/bsdconfig/networking/share/hostname.subr b/usr.sbin/bsdconfig/networking/share/hostname.subr index 1c3a67b7139f..34bfd6e1d572 100644 --- a/usr.sbin/bsdconfig/networking/share/hostname.subr +++ b/usr.sbin/bsdconfig/networking/share/hostname.subr @@ -68,10 +68,10 @@ f_dialog_hnerror() # with standards set-forth in RFC's 952 and 1123 of the Network Working Group: # # RFC 952 - DoD Internet host table specification -# http://tools.ietf.org/html/rfc952 +# https://tools.ietf.org/html/rfc952 # # RFC 1123 - Requirements for Internet Hosts - Application and Support -# http://tools.ietf.org/html/rfc1123 +# https://tools.ietf.org/html/rfc1123 # # If the hostname is determined to be invalid, the appropriate error will be # displayed using the f_dialog_hnerror function above. diff --git a/usr.sbin/bsdinstall/distextract/Makefile.depend b/usr.sbin/bsdinstall/distextract/Makefile.depend index d7411cc2716a..78020ffb2489 100644 --- a/usr.sbin/bsdinstall/distextract/Makefile.depend +++ b/usr.sbin/bsdinstall/distextract/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsdinstall/distfetch/Makefile.depend b/usr.sbin/bsdinstall/distfetch/Makefile.depend index 5dca986d1a9d..c1195d955ced 100644 --- a/usr.sbin/bsdinstall/distfetch/Makefile.depend +++ b/usr.sbin/bsdinstall/distfetch/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsdinstall/partedit/Makefile.depend b/usr.sbin/bsdinstall/partedit/Makefile.depend index c0a768da02ee..2c3bc47c6d42 100644 --- a/usr.sbin/bsdinstall/partedit/Makefile.depend +++ b/usr.sbin/bsdinstall/partedit/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsdinstall/scripts/hardening b/usr.sbin/bsdinstall/scripts/hardening index 1ea312db7ef7..1b82f8121753 100755 --- a/usr.sbin/bsdinstall/scripts/hardening +++ b/usr.sbin/bsdinstall/scripts/hardening @@ -66,7 +66,7 @@ for feature in $FEATURES; do echo security.bsd.unprivileged_proc_debug=0 >> $BSDINSTALL_TMPETC/sysctl.conf.hardening fi if [ "$feature" = "random_pid" ]; then - echo kern.randompid=$(jot -r 1 9999) >> $BSDINSTALL_TMPETC/sysctl.conf.hardening + echo kern.randompid=1 >> $BSDINSTALL_TMPETC/sysctl.conf.hardening fi if [ "$feature" = "clear_tmp" ]; then echo 'clear_tmp_enable="YES"' >> $BSDINSTALL_TMPETC/rc.conf.hardening diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile.depend b/usr.sbin/bsnmpd/bsnmpd/Makefile.depend index bb28dec8df49..9f618a5122b3 100644 --- a/usr.sbin/bsnmpd/bsnmpd/Makefile.depend +++ b/usr.sbin/bsnmpd/bsnmpd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/bsnmpd/gensnmptree/Makefile.depend b/usr.sbin/bsnmpd/gensnmptree/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/bsnmpd/gensnmptree/Makefile.depend +++ b/usr.sbin/bsnmpd/gensnmptree/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend index 2391f3d10afa..f927b80bbaed 100644 --- a/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend index 7f8402715a60..3202aed9b615 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ @@ -12,7 +11,6 @@ DIRDEPS = \ lib/libc \ lib/libcompiler_rt \ lib/libutil \ - usr.bin/yacc.host \ usr.sbin/bsnmpd/modules \ diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend index 77b21c312feb..2d5480637707 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c index 8216acce27dc..a360898e6785 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c @@ -479,7 +479,9 @@ devd_socket_callback(int fd, void *arg __unused) } else { if (read_len == sizeof(buf)) goto again; - refresh_device_tbl(1); + /* Only refresh device table on a device add or remove event. */ + if (buf[0] == '+' || buf[0] == '-') + refresh_device_tbl(1); } } diff --git a/usr.sbin/bsnmpd/modules/snmp_lm75/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_lm75/Makefile.depend index b83e8c504e63..b9ab90d16f85 100644 --- a/usr.sbin/bsnmpd/modules/snmp_lm75/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_lm75/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend index fc795736c34a..432f0e617a9f 100644 --- a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend index ced7822ff588..668a9d633920 100644 --- a/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend index b83e8c504e63..b9ab90d16f85 100644 --- a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend index fc311a38e221..8abd5d2de4ea 100644 --- a/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend index fc311a38e221..8abd5d2de4ea 100644 --- a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend index fc311a38e221..8abd5d2de4ea 100644 --- a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend index 2391f3d10afa..f927b80bbaed 100644 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend +++ b/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/bsnmpd/tools/Makefile.inc b/usr.sbin/bsnmpd/tools/Makefile.inc index ba1727e471c4..9d5ac4cdb810 100644 --- a/usr.sbin/bsnmpd/tools/Makefile.inc +++ b/usr.sbin/bsnmpd/tools/Makefile.inc @@ -6,11 +6,4 @@ PACKAGE= bsnmp CFLAGS+= -I. -I${.CURDIR} -.if exists(${.OBJDIR:H}/libbsnmptools) -LIBBSNMPTOOLSDIR= ${.OBJDIR:H}/libbsnmptools -.else -LIBBSNMPTOOLSDIR= ${.CURDIR:H}/libbsnmptools -.endif -LIBBSNMPTOOLS= ${LIBBSNMPTOOLSDIR}/libbsnmptools.a - WARNS?= 6 diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend index 0aeb9833db34..8bc992fec38f 100644 --- a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend +++ b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/btxld/Makefile.depend b/usr.sbin/btxld/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/btxld/Makefile.depend +++ b/usr.sbin/btxld/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/camdd/Makefile.depend b/usr.sbin/camdd/Makefile.depend index 17ca2bcd0024..0c2bad278bed 100644 --- a/usr.sbin/camdd/Makefile.depend +++ b/usr.sbin/camdd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/cdcontrol/Makefile.depend b/usr.sbin/cdcontrol/Makefile.depend index d6c8db88e89b..965e3a120be6 100644 --- a/usr.sbin/cdcontrol/Makefile.depend +++ b/usr.sbin/cdcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/chkgrp/Makefile.depend b/usr.sbin/chkgrp/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/chkgrp/Makefile.depend +++ b/usr.sbin/chkgrp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/chown/Makefile.depend b/usr.sbin/chown/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/chown/Makefile.depend +++ b/usr.sbin/chown/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/chroot/Makefile.depend b/usr.sbin/chroot/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/chroot/Makefile.depend +++ b/usr.sbin/chroot/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ckdist/Makefile.depend b/usr.sbin/ckdist/Makefile.depend index 064e492dd3e7..31fbf9bc2f9f 100644 --- a/usr.sbin/ckdist/Makefile.depend +++ b/usr.sbin/ckdist/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/clear_locks/Makefile.depend b/usr.sbin/clear_locks/Makefile.depend index c8383bd76e80..5b0587ae477a 100644 --- a/usr.sbin/clear_locks/Makefile.depend +++ b/usr.sbin/clear_locks/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/config/Makefile.depend b/usr.sbin/config/Makefile.depend index 88ef4a6f6dec..7d98418717a1 100644 --- a/usr.sbin/config/Makefile.depend +++ b/usr.sbin/config/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index ad1eb3ea95cc..d6b2f62ea151 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -152,7 +152,7 @@ struct includepath { SLIST_HEAD(, includepath) includepath; /* - * Tag present in the kernelconf.tmlp template file. It's mandatory for those + * Tag present in the kernconf.tmpl template file. It's mandatory for those * two strings to be the same. Otherwise you'll get into trouble. */ #define KERNCONFTAG "%%KERNCONFFILE%%" diff --git a/usr.sbin/cpucontrol/Makefile.depend b/usr.sbin/cpucontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/cpucontrol/Makefile.depend +++ b/usr.sbin/cpucontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/cpucontrol/cpucontrol.8 b/usr.sbin/cpucontrol/cpucontrol.8 index 426b6e3227dd..2a1a5f109901 100644 --- a/usr.sbin/cpucontrol/cpucontrol.8 +++ b/usr.sbin/cpucontrol/cpucontrol.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 30, 2009 +.Dd September 30, 2017 .Dt CPUCONTROL 8 .Os .Sh NAME @@ -34,43 +34,43 @@ device .Sh SYNOPSIS .Nm -.Op Fl vh +.Op Fl v .Fl m Ar msr .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl v .Fl m Ar msr Ns = Ns Ar value .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl v .Fl m Ar msr Ns &= Ns Ar mask .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl v .Fl m Ar msr Ns |= Ns Ar mask .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl v .Fl i Ar level .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl v .Fl i Ar level,level_type .Bk .Ar device .Ek .Nm -.Op Fl vh +.Op Fl vn .Op Fl d Ar datadir .Fl u .Bk @@ -88,8 +88,14 @@ It can also be used to apply CPU firmware updates. The following options are available: .Bl -tag -width indent .It Fl d Ar datadir -Where to look for microcode images. +Directory paths where to look for microcode images. The option can be specified multiple times. +The paths are added in order of the options appearance on the command +line, default directories are appended after the user-supplied paths. +.It Fl n +Do not look for the microcode images in the standard directories. +Currently standard directory to look for the microcode update files is +.Pa /usr/local/share/cpucontrol . .It Fl m Ar msr Show value of the specified MSR. MSR register number should be given as a hexadecimal number. @@ -163,10 +169,10 @@ The command will retrieve the CPUID level 0x1 from CPU 1. .Pp To perform firmware updates on CPU 0 from images located at -.Pa /usr/local/share/cpuctl/ +.Pa /usr/local/share/cpuctl use the following command: .Pp -.Dq Li "cpucontrol -d /usr/local/share/cpuctl/ -u /dev/cpuctl0" +.Dq Li "cpucontrol -nd /usr/local/share/cpuctl -u /dev/cpuctl0" .Sh SEE ALSO .Xr cpuctl 4 .Sh HISTORY @@ -179,5 +185,3 @@ The .Nm utility and this manual page was written by .An Stanislav Sedov Aq Mt stas@FreeBSD.org . -.Sh BUGS -Yes, probably, report if any. diff --git a/usr.sbin/cpucontrol/cpucontrol.c b/usr.sbin/cpucontrol/cpucontrol.c index 48e12e7ae6b4..6760b836dd3a 100644 --- a/usr.sbin/cpucontrol/cpucontrol.c +++ b/usr.sbin/cpucontrol/cpucontrol.c @@ -60,6 +60,7 @@ int verbosity_level = 0; #define FLAG_I 0x01 #define FLAG_M 0x02 #define FLAG_U 0x04 +#define FLAG_N 0x08 #define OP_INVAL 0x00 #define OP_READ 0x01 @@ -427,11 +428,7 @@ main(int argc, char *argv[]) error = 0; cmdarg = ""; /* To keep gcc3 happy. */ - /* - * Add all default data dirs to the list first. - */ - datadir_add(DEFAULT_DATADIR); - while ((c = getopt(argc, argv, "d:hi:m:uv")) != -1) { + while ((c = getopt(argc, argv, "d:hi:m:nuv")) != -1) { switch (c) { case 'd': datadir_add(optarg); @@ -444,6 +441,9 @@ main(int argc, char *argv[]) flags |= FLAG_M; cmdarg = optarg; break; + case 'n': + flags |= FLAG_N; + break; case 'u': flags |= FLAG_U; break; @@ -463,6 +463,8 @@ main(int argc, char *argv[]) usage(); /* NOTREACHED */ } + if ((flags & FLAG_N) == 0) + datadir_add(DEFAULT_DATADIR); dev = argv[0]; c = flags & (FLAG_I | FLAG_M | FLAG_U); switch (c) { diff --git a/usr.sbin/cron/cron/Makefile.depend b/usr.sbin/cron/cron/Makefile.depend index b21f78a1e5c1..c4674852688f 100644 --- a/usr.sbin/cron/cron/Makefile.depend +++ b/usr.sbin/cron/cron/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/cron/crontab/Makefile.depend b/usr.sbin/cron/crontab/Makefile.depend index a1bc9b1f0247..cfb82e7beff4 100644 --- a/usr.sbin/cron/crontab/Makefile.depend +++ b/usr.sbin/cron/crontab/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/crunch/crunchgen/Makefile.depend b/usr.sbin/crunch/crunchgen/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/crunch/crunchgen/Makefile.depend +++ b/usr.sbin/crunch/crunchgen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/crunch/crunchide/Makefile.depend b/usr.sbin/crunch/crunchide/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/crunch/crunchide/Makefile.depend +++ b/usr.sbin/crunch/crunchide/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/crunch/examples/fixit.conf b/usr.sbin/crunch/examples/fixit.conf index 80a2346e34f2..4a373241d46f 100644 --- a/usr.sbin/crunch/examples/fixit.conf +++ b/usr.sbin/crunch/examples/fixit.conf @@ -1,4 +1,5 @@ # fixit.conf - put in anything we think we might want on a fixit floppy +# $FreeBSD$ # first, we list the source dirs that our programs reside in. These are # searched in order listed to find the dir containing each program. @@ -21,7 +22,7 @@ ln sh -sh # init invokes the shell this way # /sbin stuff -progs badsect chown clri disklabel dump dmesg fdisk fsck ifconfig init +progs chown clri disklabel dump dmesg fdisk fsck ifconfig init progs mknod mount newfs ping reboot restore swapon umount ln dump rdump ln restore rrestore diff --git a/usr.sbin/crunch/examples/really-big.conf b/usr.sbin/crunch/examples/really-big.conf index cf95ee04c8b8..696fc7b811a1 100644 --- a/usr.sbin/crunch/examples/really-big.conf +++ b/usr.sbin/crunch/examples/really-big.conf @@ -23,7 +23,7 @@ ln sh -sh srcdirs /usr/src/sbin -progs badsect bim clri disklabel dmesg dump dumpfs fdisk fsck halt +progs bim clri disklabel dmesg dump dumpfs fdisk fsck halt progs ifconfig init mknod modload modunload mount mount_isofs progs mount_lofs mount_msdosfs mountd progs newfs nfsd nfsiod ping quotacheck reboot restore route routed savecore diff --git a/usr.sbin/ctladm/Makefile.depend b/usr.sbin/ctladm/Makefile.depend index f96ac2f71dce..89190e05b84a 100644 --- a/usr.sbin/ctladm/Makefile.depend +++ b/usr.sbin/ctladm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ctld/Makefile.depend b/usr.sbin/ctld/Makefile.depend index 494176741816..b19183257618 100644 --- a/usr.sbin/ctld/Makefile.depend +++ b/usr.sbin/ctld/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index 221b6eb7edda..6df037f5dee6 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -435,7 +435,7 @@ login_chap(struct connection *conn, struct auth_group *ag) * Yay, authentication succeeded! */ log_debugx("authentication succeeded for user \"%s\"; " - "transitioning to Negotiation Phase", auth->a_user); + "transitioning to operational parameter negotiation", auth->a_user); login_send_chap_success(request, auth); pdu_delete(request); diff --git a/usr.sbin/ctld/uclparse.c b/usr.sbin/ctld/uclparse.c index 21872420b62d..73d5c0a93197 100644 --- a/usr.sbin/ctld/uclparse.c +++ b/usr.sbin/ctld/uclparse.c @@ -619,6 +619,8 @@ uclparse_target(const char *name, const ucl_object_t *top) const char *key; target = target_new(conf, name); + if (target == NULL) + return (1); while ((obj = ucl_iterate_object(top, &it, true))) { key = ucl_object_key(obj); @@ -807,6 +809,8 @@ uclparse_lun(const char *name, const ucl_object_t *top) const char *key; lun = lun_new(conf, name); + if (lun == NULL) + return (1); while ((obj = ucl_iterate_object(top, &it, true))) { key = ucl_object_key(obj); diff --git a/usr.sbin/ctm/ctm/Makefile.depend b/usr.sbin/ctm/ctm/Makefile.depend index 064e492dd3e7..31fbf9bc2f9f 100644 --- a/usr.sbin/ctm/ctm/Makefile.depend +++ b/usr.sbin/ctm/ctm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ctm/ctm_dequeue/Makefile.depend b/usr.sbin/ctm/ctm_dequeue/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/ctm/ctm_dequeue/Makefile.depend +++ b/usr.sbin/ctm/ctm_dequeue/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ctm/ctm_rmail/Makefile.depend b/usr.sbin/ctm/ctm_rmail/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/ctm/ctm_rmail/Makefile.depend +++ b/usr.sbin/ctm/ctm_rmail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ctm/ctm_smail/Makefile.depend b/usr.sbin/ctm/ctm_smail/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/ctm/ctm_smail/Makefile.depend +++ b/usr.sbin/ctm/ctm_smail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/cxgbetool/Makefile.depend b/usr.sbin/cxgbetool/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/cxgbetool/Makefile.depend +++ b/usr.sbin/cxgbetool/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/cxgbetool/cxgbetool.c b/usr.sbin/cxgbetool/cxgbetool.c index b11001f10c0c..4b8dc0f709af 100644 --- a/usr.sbin/cxgbetool/cxgbetool.c +++ b/usr.sbin/cxgbetool/cxgbetool.c @@ -1896,26 +1896,29 @@ dumpstate(int argc, const char *argv[]) return (EINVAL); } - fd = open(fname, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, - S_IRUSR | S_IRGRP); - if (fd < 0) { - warn("open(%s)", fname); - return (errno); - } - dump.wr_flash = 0; memset(&dump.bitmap, 0xff, sizeof(dump.bitmap)); dump.len = 8 * 1024 * 1024; dump.data = malloc(dump.len); if (dump.data == NULL) { - close(fd); return (ENOMEM); } rc = doit(CHELSIO_T4_CUDBG_DUMP, &dump); + if (rc != 0) + goto done; + + fd = open(fname, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, + S_IRUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + warn("open(%s)", fname); + rc = errno; + goto done; + } write(fd, dump.data, dump.len); - free(dump.data); close(fd); +done: + free(dump.data); return (rc); } diff --git a/usr.sbin/daemon/Makefile.depend b/usr.sbin/daemon/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/daemon/Makefile.depend +++ b/usr.sbin/daemon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/dconschat/Makefile.depend b/usr.sbin/dconschat/Makefile.depend index 442e3ca8003d..daaa39c06eaf 100644 --- a/usr.sbin/dconschat/Makefile.depend +++ b/usr.sbin/dconschat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/devctl/Makefile.depend b/usr.sbin/devctl/Makefile.depend index 34e1a913e4a3..74130daab290 100644 --- a/usr.sbin/devctl/Makefile.depend +++ b/usr.sbin/devctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/devinfo/Makefile.depend b/usr.sbin/devinfo/Makefile.depend index a6afa4796d96..2c68d7ccef0d 100644 --- a/usr.sbin/devinfo/Makefile.depend +++ b/usr.sbin/devinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/digictl/Makefile.depend b/usr.sbin/digictl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/digictl/Makefile.depend +++ b/usr.sbin/digictl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/diskinfo/Makefile.depend b/usr.sbin/diskinfo/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/diskinfo/Makefile.depend +++ b/usr.sbin/diskinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/diskinfo/diskinfo.8 b/usr.sbin/diskinfo/diskinfo.8 index a30337a7c020..753850d4ca5c 100644 --- a/usr.sbin/diskinfo/diskinfo.8 +++ b/usr.sbin/diskinfo/diskinfo.8 @@ -64,7 +64,7 @@ Return the physical path of the disk. This is a string that identifies the physical path to the disk in the storage enclosure. .It Fl s -Return the disk serial number +Return the disk ident, usually the serial number. .It Fl S Perform synchronous random write test (ZFS SLOG test), measuring time required to write data blocks of different size and @@ -82,13 +82,6 @@ with the following fields: device name, sectorsize, media size in bytes, media size in sectors, stripe size, stripe offset, firmware cylinders, firmware heads, and firmware sectors. The last three fields are only present if the information is available. -.It Fl i -Return the disk ident, usually the serial number. -.It Fl p -Return the physical path of the disk. -This is a string that identifies the physical path to the disk in the -storage enclosure. -.El .Sh HISTORY The .Nm diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c index e6ae46f8c3f0..00ff537c587b 100644 --- a/usr.sbin/diskinfo/diskinfo.c +++ b/usr.sbin/diskinfo/diskinfo.c @@ -31,6 +31,7 @@ * $FreeBSD$ */ +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +52,8 @@ #include #define NAIO 128 +#define MAXTX (8*1024*1024) +#define MEGATX (1024*1024) static void usage(void) @@ -60,20 +64,25 @@ usage(void) static int opt_c, opt_i, opt_p, opt_s, opt_S, opt_t, opt_v, opt_w; +static bool candelete(int fd); static void speeddisk(int fd, off_t mediasize, u_int sectorsize); static void commandtime(int fd, off_t mediasize, u_int sectorsize); static void iopsbench(int fd, off_t mediasize, u_int sectorsize); +static void rotationrate(int fd, char *buf, size_t buflen); static void slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize); static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len); +static uint8_t *buf; + int main(int argc, char **argv) { struct stat sb; int i, ch, fd, error, exitval = 0; - char buf[BUFSIZ], ident[DISK_IDENT_SIZE], physpath[MAXPATHLEN]; + char tstr[BUFSIZ], ident[DISK_IDENT_SIZE], physpath[MAXPATHLEN]; char zone_desc[64]; + char rrate[64]; struct diocgattr_arg arg; off_t mediasize, stripesize, stripeoffset; u_int sectorsize, fwsectors, fwheads, zoned = 0, isreg; @@ -129,11 +138,13 @@ main(int argc, char **argv) usage(); } + if (posix_memalign((void **)&buf, PAGE_SIZE, MAXTX)) + errx(1, "Can't allocate memory buffer"); for (i = 0; i < argc; i++) { fd = open(argv[i], (opt_w ? O_RDWR : O_RDONLY) | O_DIRECT); if (fd < 0 && errno == ENOENT && *argv[i] != '/') { - snprintf(buf, BUFSIZ, "%s%s", _PATH_DEV, argv[i]); - fd = open(buf, O_RDONLY); + snprintf(tstr, sizeof(tstr), "%s%s", _PATH_DEV, argv[i]); + fd = open(tstr, O_RDONLY); } if (fd < 0) { warn("%s", argv[i]); @@ -216,12 +227,12 @@ main(int argc, char **argv) printf("\t%u", fwsectors); } } else { - humanize_number(buf, 5, (int64_t)mediasize, "", + humanize_number(tstr, 5, (int64_t)mediasize, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); printf("%s\n", argv[i]); printf("\t%-12u\t# sectorsize\n", sectorsize); printf("\t%-12jd\t# mediasize in bytes (%s)\n", - (intmax_t)mediasize, buf); + (intmax_t)mediasize, tstr); printf("\t%-12jd\t# mediasize in sectors\n", (intmax_t)mediasize/sectorsize); printf("\t%-12jd\t# stripesize\n", stripesize); @@ -240,6 +251,10 @@ main(int argc, char **argv) printf("\t%-12s\t# Disk ident.\n", ident); if (ioctl(fd, DIOCGPHYSPATH, physpath) == 0) printf("\t%-12s\t# Physical path\n", physpath); + printf("\t%-12s\t# TRIM/UNMAP support\n", + candelete(fd) ? "Yes" : "No"); + rotationrate(fd, rrate, sizeof(rrate)); + printf("\t%-12s\t# Rotation rate in RPM\n", rrate); if (zoned != 0) printf("\t%-12s\t# Zone Mode\n", zone_desc); } @@ -255,12 +270,42 @@ main(int argc, char **argv) out: close(fd); } + free(buf); exit (exitval); } -#define MAXTX (8*1024*1024) -#define MEGATX (1024*1024) -static uint8_t buf[MAXTX]; +static bool +candelete(int fd) +{ + struct diocgattr_arg arg; + + strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name)); + arg.len = sizeof(arg.value.i); + if (ioctl(fd, DIOCGATTR, &arg) == 0) + return (arg.value.i != 0); + else + return (false); +} + +static void +rotationrate(int fd, char *rate, size_t buflen) +{ + struct diocgattr_arg arg; + int ret; + + strlcpy(arg.name, "GEOM::rotation_rate", sizeof(arg.name)); + arg.len = sizeof(arg.value.u16); + + ret = ioctl(fd, DIOCGATTR, &arg); + if (ret < 0 || arg.value.u16 == DISK_RR_UNKNOWN) + snprintf(rate, buflen, "Unknown"); + else if (arg.value.u16 == DISK_RR_NON_ROTATING) + snprintf(rate, buflen, "%d", 0); + else if (arg.value.u16 >= DISK_RR_MIN && arg.value.u16 <= DISK_RR_MAX) + snprintf(rate, buflen, "%d", arg.value.u16); + else + snprintf(rate, buflen, "Invalid"); +} static void rdsect(int fd, off_t blockno, u_int sectorsize) @@ -630,7 +675,7 @@ slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize) { off_t off; u_int size; - int error, n, N; + int error, n, N, nowritecache = 0; printf("Synchronous random writes:\n"); for (size = sectorsize; size <= MAXTX; size *= 2) { @@ -641,12 +686,18 @@ slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize) for (n = 0; n < 250; n++) { off = random() % (mediasize / size); parwrite(fd, size, off * size); + if (nowritecache) + continue; if (isreg) error = fsync(fd); else error = ioctl(fd, DIOCGFLUSH); - if (error < 0) - err(EX_IOERR, "Flush error"); + if (error < 0) { + if (errno == ENOTSUP) + nowritecache = 1; + else + err(EX_IOERR, "Flush error"); + } } N += 250; } while (delta_t() < 1.0); diff --git a/usr.sbin/dumpcis/Makefile.depend b/usr.sbin/dumpcis/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/dumpcis/Makefile.depend +++ b/usr.sbin/dumpcis/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/editmap/Makefile.depend b/usr.sbin/editmap/Makefile.depend index b0af42fdb943..0feabbf167e0 100644 --- a/usr.sbin/editmap/Makefile.depend +++ b/usr.sbin/editmap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/edquota/Makefile.depend b/usr.sbin/edquota/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/edquota/Makefile.depend +++ b/usr.sbin/edquota/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/eeprom/Makefile.depend b/usr.sbin/eeprom/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/usr.sbin/eeprom/Makefile.depend +++ b/usr.sbin/eeprom/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/efidp/Makefile.depend b/usr.sbin/efidp/Makefile.depend index 8af72d7991ad..204b8d257e53 100644 --- a/usr.sbin/efidp/Makefile.depend +++ b/usr.sbin/efidp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/efivar/Makefile.depend b/usr.sbin/efivar/Makefile.depend index 8af72d7991ad..204b8d257e53 100644 --- a/usr.sbin/efivar/Makefile.depend +++ b/usr.sbin/efivar/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/extattr/Makefile.depend b/usr.sbin/extattr/Makefile.depend index 8df34bc70a45..c3cca03a0705 100644 --- a/usr.sbin/extattr/Makefile.depend +++ b/usr.sbin/extattr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/extattrctl/Makefile.depend b/usr.sbin/extattrctl/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/extattrctl/Makefile.depend +++ b/usr.sbin/extattrctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fdcontrol/Makefile.depend b/usr.sbin/fdcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/fdcontrol/Makefile.depend +++ b/usr.sbin/fdcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fdformat/Makefile.depend b/usr.sbin/fdformat/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/fdformat/Makefile.depend +++ b/usr.sbin/fdformat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fdread/Makefile.depend b/usr.sbin/fdread/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/fdread/Makefile.depend +++ b/usr.sbin/fdread/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fdwrite/Makefile.depend b/usr.sbin/fdwrite/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/fdwrite/Makefile.depend +++ b/usr.sbin/fdwrite/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fifolog/fifolog_create/Makefile.depend b/usr.sbin/fifolog/fifolog_create/Makefile.depend index 2a0e9d797c44..ce13a0df74aa 100644 --- a/usr.sbin/fifolog/fifolog_create/Makefile.depend +++ b/usr.sbin/fifolog/fifolog_create/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/fifolog/fifolog_reader/Makefile.depend b/usr.sbin/fifolog/fifolog_reader/Makefile.depend index 50fc7bda38bb..d223e22c5c58 100644 --- a/usr.sbin/fifolog/fifolog_reader/Makefile.depend +++ b/usr.sbin/fifolog/fifolog_reader/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/fifolog/fifolog_writer/Makefile.depend b/usr.sbin/fifolog/fifolog_writer/Makefile.depend index 50fc7bda38bb..d223e22c5c58 100644 --- a/usr.sbin/fifolog/fifolog_writer/Makefile.depend +++ b/usr.sbin/fifolog/fifolog_writer/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/flowctl/Makefile.depend b/usr.sbin/flowctl/Makefile.depend index 4fa00ad6b9c0..d64c9ccbda7b 100644 --- a/usr.sbin/flowctl/Makefile.depend +++ b/usr.sbin/flowctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/fmtree/Makefile.depend b/usr.sbin/fmtree/Makefile.depend index 064e492dd3e7..31fbf9bc2f9f 100644 --- a/usr.sbin/fmtree/Makefile.depend +++ b/usr.sbin/fmtree/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index dcc275fcd7b1..eebe85d3c34e 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -418,6 +418,9 @@ init_params () { # Run without a TTY NOTTYOK=0 + + # Fetched first in a chain of commands + ISFETCHED=0 } # Parse the command line @@ -783,8 +786,10 @@ install_check_params () { # Check that we have updates ready to install if ! [ -L ${BDHASH}-install ]; then echo "No updates are available to install." - echo "Run '$0 fetch' first." - exit 1 + if [ $ISFETCHED -eq 0 ]; then + echo "Run '$0 fetch' first." + fi + exit 0 fi if ! [ -f ${BDHASH}-install/INDEX-OLD ] || ! [ -f ${BDHASH}-install/INDEX-NEW ]; then @@ -3241,6 +3246,7 @@ cmd_fetch () { fi fetch_check_params fetch_run || exit 1 + ISFETCHED=1 } # Cron command. Make sure the parameters are sensible; wait diff --git a/usr.sbin/fstyp/Makefile.depend b/usr.sbin/fstyp/Makefile.depend index b1a2eff6cb4f..53090da6e2fc 100644 --- a/usr.sbin/fstyp/Makefile.depend +++ b/usr.sbin/fstyp/Makefile.depend @@ -9,7 +9,6 @@ DIRDEPS = \ cddl/lib/libzfs \ cddl/lib/libzfs_core \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ftp-proxy/Makefile.depend b/usr.sbin/ftp-proxy/Makefile.depend index c02eb2d9c00d..34af16caac3e 100644 --- a/usr.sbin/ftp-proxy/Makefile.depend +++ b/usr.sbin/ftp-proxy/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/fwcontrol/Makefile.depend b/usr.sbin/fwcontrol/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/fwcontrol/Makefile.depend +++ b/usr.sbin/fwcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/getfmac/Makefile.depend b/usr.sbin/getfmac/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/getfmac/Makefile.depend +++ b/usr.sbin/getfmac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/getpmac/Makefile.depend b/usr.sbin/getpmac/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/getpmac/Makefile.depend +++ b/usr.sbin/getpmac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/gpioctl/Makefile.depend b/usr.sbin/gpioctl/Makefile.depend index 712b56e32622..fd3b3da66347 100644 --- a/usr.sbin/gpioctl/Makefile.depend +++ b/usr.sbin/gpioctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/gssd/Makefile.depend b/usr.sbin/gssd/Makefile.depend index 642bb5d83ad9..5e5afbc78314 100644 --- a/usr.sbin/gssd/Makefile.depend +++ b/usr.sbin/gssd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/gssapi \ include/rpc \ diff --git a/usr.sbin/gstat/Makefile.depend b/usr.sbin/gstat/Makefile.depend index c8fd534e0df1..7a3e02950915 100644 --- a/usr.sbin/gstat/Makefile.depend +++ b/usr.sbin/gstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/hyperv/tools/kvp/Makefile.depend b/usr.sbin/hyperv/tools/kvp/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/hyperv/tools/kvp/Makefile.depend +++ b/usr.sbin/hyperv/tools/kvp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/hyperv/tools/vss/Makefile.depend b/usr.sbin/hyperv/tools/vss/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/hyperv/tools/vss/Makefile.depend +++ b/usr.sbin/hyperv/tools/vss/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/i2c/Makefile.depend b/usr.sbin/i2c/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/i2c/Makefile.depend +++ b/usr.sbin/i2c/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/i2c/i2c.8 b/usr.sbin/i2c/i2c.8 index 27f7621156b6..03f0c125c24a 100644 --- a/usr.sbin/i2c/i2c.8 +++ b/usr.sbin/i2c/i2c.8 @@ -83,6 +83,10 @@ using selected addresses 'a:b:c'. This option is available only when "-s" is used. .It Fl o Ar offset offset within the device for data transfer (hex). +The default is zero. +Use +.Dq -w 0 +to disable writing of the offset to the slave. .It Fl r reset the controller. .It Fl s @@ -91,6 +95,12 @@ scan the bus for devices. be verbose. .It Fl w Ar 0|8|16 device addressing width (in bits). +This is used to determine how to pass +.Ar offset +specified with +.Fl o +to the slave. +Zero means that the offset is ignored and not passed to the slave at all. .El .Sh WARNINGS Great care must be taken when manipulating slave I2C devices with the diff --git a/usr.sbin/i2c/i2c.c b/usr.sbin/i2c/i2c.c index 29e7aedaba5e..8ab58219b794 100644 --- a/usr.sbin/i2c/i2c.c +++ b/usr.sbin/i2c/i2c.c @@ -212,15 +212,14 @@ scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr) use_read_xfer = 1; goto start_over; } - cmd.slave = i << 1; - cmd.last = 1; - ioctl(fd, I2CSTOP, &cmd); + ioctl(fd, I2CSTOP); } if (error == 0) { ++num_found; printf("%02x ", i); } } + /* * If we found nothing, maybe START is not supported and returns a * generic error code such as EIO or ENXIO, so try again using reads. @@ -355,7 +354,7 @@ i2c_write(char *dev, struct options i2c_opt, char *i2c_buf) } } - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "ioctl: error sending stop condition"; goto err2; @@ -439,8 +438,7 @@ i2c_write(char *dev, struct options i2c_opt, char *i2c_buf) } break; } - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "ioctl: error sending stop condition"; goto err2; @@ -450,8 +448,7 @@ i2c_write(char *dev, struct options i2c_opt, char *i2c_buf) return (0); err1: - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) fprintf(stderr, "error sending stop condition\n"); err2: @@ -466,7 +463,7 @@ static int i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) { struct iiccmd cmd; - int i, fd, error, bufsize; + int fd, error, bufsize; char *err_msg, data = 0, *buf; fd = open(dev, O_RDWR); @@ -503,23 +500,22 @@ i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) } if (i2c_opt.mode == I2C_MODE_STOP_START) { - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "error sending stop condition"; goto err2; } } } - cmd.slave = i2c_opt.addr; + cmd.slave = i2c_opt.addr | 1; cmd.count = 1; cmd.last = 0; cmd.buf = &data; - if (i2c_opt.mode == I2C_MODE_STOP_START) { + if (i2c_opt.mode == I2C_MODE_STOP_START || i2c_opt.width == 0) { error = ioctl(fd, I2CSTART, &cmd); if (error == -1) { err_msg = "ioctl: error sending start condition"; - goto err1; + goto err2; } } else if (i2c_opt.mode == I2C_MODE_REPEATED_START) { error = ioctl(fd, I2CRPTSTART, &cmd); @@ -529,26 +525,27 @@ i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) goto err1; } } - error = ioctl(fd, I2CSTOP, &cmd); + + cmd.count = i2c_opt.count; + cmd.buf = i2c_buf; + cmd.last = 1; + error = ioctl(fd, I2CREAD, &cmd); if (error == -1) { - err_msg = "error sending stop condition"; - goto err2; + err_msg = "ioctl: error while reading"; + goto err1; } - for (i = 0; i < i2c_opt.count; i++) { - error = read(fd, &i2c_buf[i], 1); - if (error == -1) { - err_msg = "ioctl: error while reading"; - goto err1; - } + error = ioctl(fd, I2CSTOP); + if (error == -1) { + err_msg = "error sending stop condtion\n"; + goto err2; } close(fd); return (0); err1: - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) fprintf(stderr, "error sending stop condition\n"); err2: diff --git a/usr.sbin/ifmcstat/Makefile.depend b/usr.sbin/ifmcstat/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/ifmcstat/Makefile.depend +++ b/usr.sbin/ifmcstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/inetd/Makefile.depend b/usr.sbin/inetd/Makefile.depend index cc94252aa4f7..cbb9aa679f8a 100644 --- a/usr.sbin/inetd/Makefile.depend +++ b/usr.sbin/inetd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/iostat/Makefile.depend b/usr.sbin/iostat/Makefile.depend index ca404f2f90a0..70e72f3ef71d 100644 --- a/usr.sbin/iostat/Makefile.depend +++ b/usr.sbin/iostat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/iovctl/Makefile.depend b/usr.sbin/iovctl/Makefile.depend index d88352954b44..2082bfb7951c 100644 --- a/usr.sbin/iovctl/Makefile.depend +++ b/usr.sbin/iovctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ip6addrctl/Makefile.depend b/usr.sbin/ip6addrctl/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/ip6addrctl/Makefile.depend +++ b/usr.sbin/ip6addrctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ipfwpcap/Makefile.depend b/usr.sbin/ipfwpcap/Makefile.depend index 268320b6f6e3..893e74eb908c 100644 --- a/usr.sbin/ipfwpcap/Makefile.depend +++ b/usr.sbin/ipfwpcap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/iscsid/Makefile.depend b/usr.sbin/iscsid/Makefile.depend index 023ec4300e65..aa7d77115eb0 100644 --- a/usr.sbin/iscsid/Makefile.depend +++ b/usr.sbin/iscsid/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/jail/Makefile.depend b/usr.sbin/jail/Makefile.depend index 9b995ab699ba..7f608aab0712 100644 --- a/usr.sbin/jail/Makefile.depend +++ b/usr.sbin/jail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index f728dbf153c0..166c79b8b0b0 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -1006,7 +1006,7 @@ jail -c path=/data/jail/testjail mount.devfs \\ .Pp Assuming no errors, you will end up with a shell prompt within the jail. You can now run -.Pa /usr/sbin/sysinstall +.Pa /usr/sbin/bsdinstall and do the post-install configuration to set various configuration options, or perform these actions manually by editing .Pa /etc/rc.conf , diff --git a/usr.sbin/jexec/Makefile.depend b/usr.sbin/jexec/Makefile.depend index b92a98a8ac1d..98929049af54 100644 --- a/usr.sbin/jexec/Makefile.depend +++ b/usr.sbin/jexec/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/jls/Makefile.depend b/usr.sbin/jls/Makefile.depend index 50e6f23c947a..d4d0b05e7f43 100644 --- a/usr.sbin/jls/Makefile.depend +++ b/usr.sbin/jls/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/kbdcontrol/Makefile.depend b/usr.sbin/kbdcontrol/Makefile.depend index dc77d0ee8564..b3c7e9af13c7 100644 --- a/usr.sbin/kbdcontrol/Makefile.depend +++ b/usr.sbin/kbdcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/kbdmap/Makefile.depend b/usr.sbin/kbdmap/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/kbdmap/Makefile.depend +++ b/usr.sbin/kbdmap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/keyserv/Makefile.depend b/usr.sbin/keyserv/Makefile.depend index bae15c2d809d..97ec617dcc81 100644 --- a/usr.sbin/keyserv/Makefile.depend +++ b/usr.sbin/keyserv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/kgmon/Makefile.depend b/usr.sbin/kgmon/Makefile.depend index 34582cd083a2..4a0ebeceed6f 100644 --- a/usr.sbin/kgmon/Makefile.depend +++ b/usr.sbin/kgmon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/kgzip/Makefile.depend b/usr.sbin/kgzip/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/usr.sbin/kgzip/Makefile.depend +++ b/usr.sbin/kgzip/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/kldxref/Makefile.depend b/usr.sbin/kldxref/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/kldxref/Makefile.depend +++ b/usr.sbin/kldxref/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lastlogin/Makefile.depend b/usr.sbin/lastlogin/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/lastlogin/Makefile.depend +++ b/usr.sbin/lastlogin/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lmcconfig/Makefile.depend b/usr.sbin/lmcconfig/Makefile.depend index 92ae034c03ef..3f4cb50e1709 100644 --- a/usr.sbin/lmcconfig/Makefile.depend +++ b/usr.sbin/lmcconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/chkprintcap/Makefile.depend b/usr.sbin/lpr/chkprintcap/Makefile.depend index 5d7143daa2fc..5ca32400912b 100644 --- a/usr.sbin/lpr/chkprintcap/Makefile.depend +++ b/usr.sbin/lpr/chkprintcap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend b/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend +++ b/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend b/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend +++ b/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/lpr/filters/Makefile.depend b/usr.sbin/lpr/filters/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/lpr/filters/Makefile.depend +++ b/usr.sbin/lpr/filters/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/lpc/Makefile.depend b/usr.sbin/lpr/lpc/Makefile.depend index 69f631ff9990..e59ad46a72f3 100644 --- a/usr.sbin/lpr/lpc/Makefile.depend +++ b/usr.sbin/lpr/lpc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/lpd/Makefile.depend b/usr.sbin/lpr/lpd/Makefile.depend index 42a1eb570e27..288e8eec083e 100644 --- a/usr.sbin/lpr/lpd/Makefile.depend +++ b/usr.sbin/lpr/lpd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/lpr/lpq/Makefile.depend b/usr.sbin/lpr/lpq/Makefile.depend index 5d7143daa2fc..5ca32400912b 100644 --- a/usr.sbin/lpr/lpq/Makefile.depend +++ b/usr.sbin/lpr/lpq/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/lpr/Makefile.depend b/usr.sbin/lpr/lpr/Makefile.depend index 5d7143daa2fc..5ca32400912b 100644 --- a/usr.sbin/lpr/lpr/Makefile.depend +++ b/usr.sbin/lpr/lpr/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/lprm/Makefile.depend b/usr.sbin/lpr/lprm/Makefile.depend index 5d7143daa2fc..5ca32400912b 100644 --- a/usr.sbin/lpr/lprm/Makefile.depend +++ b/usr.sbin/lpr/lprm/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lpr/lptest/Makefile.depend b/usr.sbin/lpr/lptest/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.sbin/lpr/lptest/Makefile.depend +++ b/usr.sbin/lpr/lptest/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/lpr/pac/Makefile.depend b/usr.sbin/lpr/pac/Makefile.depend index 5d7143daa2fc..5ca32400912b 100644 --- a/usr.sbin/lpr/pac/Makefile.depend +++ b/usr.sbin/lpr/pac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/lptcontrol/Makefile.depend b/usr.sbin/lptcontrol/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.sbin/lptcontrol/Makefile.depend +++ b/usr.sbin/lptcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/mailstats/Makefile.depend b/usr.sbin/mailstats/Makefile.depend index ed1b531f8645..d1b41fcc8417 100644 --- a/usr.sbin/mailstats/Makefile.depend +++ b/usr.sbin/mailstats/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mailwrapper/Makefile.depend b/usr.sbin/mailwrapper/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/mailwrapper/Makefile.depend +++ b/usr.sbin/mailwrapper/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/makefs/Makefile.depend b/usr.sbin/makefs/Makefile.depend index 51e7dfa4154b..fafbbbb0cda1 100644 --- a/usr.sbin/makefs/Makefile.depend +++ b/usr.sbin/makefs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/makefs/tests/makefs_cd9660_tests.sh b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh index 8b4e33777f3b..01c99f730ec6 100755 --- a/usr.sbin/makefs/tests/makefs_cd9660_tests.sh +++ b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh @@ -29,7 +29,7 @@ # A note on specs: # - A copy of the ISO-9660 spec can be found here: -# http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf +# https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf # - Any references to `rockridge` are referring to the `Rock Ridge` extensions # of the ISO-9660 spec. A copy of the draft `IEEE-P1282` spec can be found # here: diff --git a/usr.sbin/makemap/Makefile.depend b/usr.sbin/makemap/Makefile.depend index b0af42fdb943..0feabbf167e0 100644 --- a/usr.sbin/makemap/Makefile.depend +++ b/usr.sbin/makemap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/memcontrol/Makefile.depend b/usr.sbin/memcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/memcontrol/Makefile.depend +++ b/usr.sbin/memcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8 index e561a727af04..329e74d090d2 100644 --- a/usr.sbin/mergemaster/mergemaster.8 +++ b/usr.sbin/mergemaster/mergemaster.8 @@ -457,7 +457,7 @@ comparison, use: .Pp .Pa /usr/src/etc/Makefile .Rs -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html +.%U https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html .%T The Cutting Edge (using make world) .%A Nik Clayton .Re diff --git a/usr.sbin/mfiutil/Makefile.depend b/usr.sbin/mfiutil/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/mfiutil/Makefile.depend +++ b/usr.sbin/mfiutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mixer/Makefile.depend b/usr.sbin/mixer/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/mixer/Makefile.depend +++ b/usr.sbin/mixer/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mld6query/Makefile.depend b/usr.sbin/mld6query/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/mld6query/Makefile.depend +++ b/usr.sbin/mld6query/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/mlxcontrol/Makefile.depend b/usr.sbin/mlxcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/mlxcontrol/Makefile.depend +++ b/usr.sbin/mlxcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mount_smbfs/Makefile.depend b/usr.sbin/mount_smbfs/Makefile.depend index 9c676a05ad57..6d0625c20465 100644 --- a/usr.sbin/mount_smbfs/Makefile.depend +++ b/usr.sbin/mount_smbfs/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mountd/Makefile.depend b/usr.sbin/mountd/Makefile.depend index 0a49c9e6a4d0..741d5bc5bd59 100644 --- a/usr.sbin/mountd/Makefile.depend +++ b/usr.sbin/mountd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 66c47255a518..4431f881581b 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -91,9 +92,10 @@ __FBSDID("$FreeBSD$"); * Structures for keeping the mount list and export list */ struct mountlist { - struct mountlist *ml_next; char ml_host[MNTNAMLEN+1]; char ml_dirp[MNTPATHLEN+1]; + + SLIST_ENTRY(mountlist) next; }; struct dirlist { @@ -101,14 +103,13 @@ struct dirlist { struct dirlist *dp_right; int dp_flag; struct hostlist *dp_hosts; /* List of hosts this dir exported to */ - char dp_dirp[1]; /* Actually malloc'd to size of dir */ + char *dp_dirp; }; /* dp_flag bits */ #define DP_DEFSET 0x1 #define DP_HOSTSET 0x2 struct exportlist { - struct exportlist *ex_next; struct dirlist *ex_dirl; struct dirlist *ex_defdir; int ex_flag; @@ -119,6 +120,8 @@ struct exportlist { int ex_secflavors[MAXSECFLAVORS]; int ex_defnumsecflavors; int ex_defsecflavors[MAXSECFLAVORS]; + + SLIST_ENTRY(exportlist) entries; }; /* ex_flag bits */ #define EX_LINKED 0x1 @@ -222,8 +225,8 @@ static int xdr_fhs(XDR *, caddr_t); static int xdr_mlist(XDR *, caddr_t); static void terminate(int); -static struct exportlist *exphead; -static struct mountlist *mlhead; +static SLIST_HEAD(, exportlist) exphead = SLIST_HEAD_INITIALIZER(exphead); +static SLIST_HEAD(, mountlist) mlhead = SLIST_HEAD_INITIALIZER(mlhead); static struct grouplist *grphead; static char *exnames_default[2] = { _PATH_EXPORTS, NULL }; static char **exnames; @@ -445,8 +448,6 @@ main(int argc, char **argv) argc -= optind; argv += optind; grphead = (struct grouplist *)NULL; - exphead = (struct exportlist *)NULL; - mlhead = (struct mountlist *)NULL; if (argc > 0) exnames = argv; else @@ -1253,8 +1254,7 @@ xdr_mlist(XDR *xdrsp, caddr_t cp __unused) int false = 0; char *strp; - mlp = mlhead; - while (mlp) { + SLIST_FOREACH(mlp, &mlhead, next) { if (!xdr_bool(xdrsp, &true)) return (0); strp = &mlp->ml_host[0]; @@ -1263,7 +1263,6 @@ xdr_mlist(XDR *xdrsp, caddr_t cp __unused) strp = &mlp->ml_dirp[0]; if (!xdr_string(xdrsp, &strp, MNTPATHLEN)) return (0); - mlp = mlp->ml_next; } if (!xdr_bool(xdrsp, &false)) return (0); @@ -1284,8 +1283,8 @@ xdr_explist_common(XDR *xdrsp, caddr_t cp __unused, int brief) sigemptyset(&sighup_mask); sigaddset(&sighup_mask, SIGHUP); sigprocmask(SIG_BLOCK, &sighup_mask, NULL); - ep = exphead; - while (ep) { + + SLIST_FOREACH(ep, &exphead, entries) { putdef = 0; if (put_exlist(ep->ex_dirl, xdrsp, ep->ex_defdir, &putdef, brief)) @@ -1294,7 +1293,6 @@ xdr_explist_common(XDR *xdrsp, caddr_t cp __unused, int brief) put_exlist(ep->ex_defdir, xdrsp, (struct dirlist *)NULL, &putdef, brief)) goto errout; - ep = ep->ex_next; } sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); if (!xdr_bool(xdrsp, &false)) @@ -1397,9 +1395,8 @@ static FILE *exp_file; static void get_exportlist_one(void) { - struct exportlist *ep, *ep2; + struct exportlist *ep; struct grouplist *grp, *tgrp; - struct exportlist **epp; struct dirlist *dirhead; struct statfs fsb; struct xucred anon; @@ -1525,12 +1522,8 @@ get_exportlist_one(void) if (ep == (struct exportlist *)NULL) { ep = get_exp(); ep->ex_fs = fsb.f_fsid; - ep->ex_fsdir = (char *)malloc - (strlen(fsb.f_mntonname) + 1); - if (ep->ex_fsdir) - strcpy(ep->ex_fsdir, - fsb.f_mntonname); - else + ep->ex_fsdir = strdup(fsb.f_mntonname); + if (ep->ex_fsdir == NULL) out_of_mem(); if (debug) warnx( @@ -1680,19 +1673,8 @@ get_exportlist_one(void) } dirhead = (struct dirlist *)NULL; if ((ep->ex_flag & EX_LINKED) == 0) { - ep2 = exphead; - epp = &exphead; + SLIST_INSERT_HEAD(&exphead, ep, entries); - /* - * Insert in the list in alphabetical order. - */ - while (ep2 && strcmp(ep2->ex_fsdir, ep->ex_fsdir) < 0) { - epp = &ep2->ex_next; - ep2 = ep2->ex_next; - } - if (ep2) - ep->ex_next = ep2; - *epp = ep; ep->ex_flag |= EX_LINKED; } nextline: @@ -1734,13 +1716,10 @@ get_exportlist(void) /* * First, get rid of the old list */ - ep = exphead; - while (ep) { - ep2 = ep; - ep = ep->ex_next; - free_exp(ep2); + SLIST_FOREACH_SAFE(ep, &exphead, entries, ep2) { + SLIST_REMOVE(&exphead, ep, exportlist, entries); + free_exp(ep); } - exphead = (struct exportlist *)NULL; grp = grphead; while (grp) { @@ -1922,13 +1901,12 @@ ex_search(fsid_t *fsid) { struct exportlist *ep; - ep = exphead; - while (ep) { + SLIST_FOREACH(ep, &exphead, entries) { if (ep->ex_fs.val[0] == fsid->val[0] && ep->ex_fs.val[1] == fsid->val[1]) return (ep); - ep = ep->ex_next; } + return (ep); } @@ -1940,14 +1918,16 @@ add_expdir(struct dirlist **dpp, char *cp, int len) { struct dirlist *dp; - dp = (struct dirlist *)malloc(sizeof (struct dirlist) + len); + dp = malloc(sizeof (struct dirlist)); if (dp == (struct dirlist *)NULL) out_of_mem(); dp->dp_left = *dpp; dp->dp_right = (struct dirlist *)NULL; dp->dp_flag = 0; dp->dp_hosts = (struct hostlist *)NULL; - strcpy(dp->dp_dirp, cp); + dp->dp_dirp = strndup(cp, len); + if (dp->dp_dirp == NULL) + out_of_mem(); *dpp = dp; return (dp->dp_dirp); } @@ -2161,7 +2141,8 @@ free_dir(struct dirlist *dp) free_dir(dp->dp_left); free_dir(dp->dp_right); free_host(dp->dp_hosts); - free((caddr_t)dp); + free(dp->dp_dirp); + free(dp); } } @@ -2963,7 +2944,7 @@ parsecred(char *namelist, struct xucred *cr) static void get_mountlist(void) { - struct mountlist *mlp, **mlpp; + struct mountlist *mlp; char *host, *dirp, *cp; char str[STRSIZ]; FILE *mlfile; @@ -2976,7 +2957,6 @@ get_mountlist(void) return; } } - mlpp = &mlhead; while (fgets(str, STRSIZ, mlfile) != NULL) { cp = str; host = strsep(&cp, " \t\n"); @@ -2990,9 +2970,8 @@ get_mountlist(void) mlp->ml_host[MNTNAMLEN] = '\0'; strncpy(mlp->ml_dirp, dirp, MNTPATHLEN); mlp->ml_dirp[MNTPATHLEN] = '\0'; - mlp->ml_next = (struct mountlist *)NULL; - *mlpp = mlp; - mlpp = &mlp->ml_next; + + SLIST_INSERT_HEAD(&mlhead, mlp, next); } fclose(mlfile); } @@ -3000,23 +2979,16 @@ get_mountlist(void) static void del_mlist(char *hostp, char *dirp) { - struct mountlist *mlp, **mlpp; - struct mountlist *mlp2; + struct mountlist *mlp, *mlp2; FILE *mlfile; int fnd = 0; - mlpp = &mlhead; - mlp = mlhead; - while (mlp) { + SLIST_FOREACH_SAFE(mlp, &mlhead, next, mlp2) { if (!strcmp(mlp->ml_host, hostp) && (!dirp || !strcmp(mlp->ml_dirp, dirp))) { fnd = 1; - mlp2 = mlp; - *mlpp = mlp = mlp->ml_next; - free((caddr_t)mlp2); - } else { - mlpp = &mlp->ml_next; - mlp = mlp->ml_next; + SLIST_REMOVE(&mlhead, mlp, mountlist, next); + free((caddr_t)mlp); } } if (fnd) { @@ -3024,10 +2996,8 @@ del_mlist(char *hostp, char *dirp) syslog(LOG_ERR,"can't update %s", _PATH_RMOUNTLIST); return; } - mlp = mlhead; - while (mlp) { + SLIST_FOREACH(mlp, &mlhead, next) { fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp); - mlp = mlp->ml_next; } fclose(mlfile); } @@ -3036,17 +3006,14 @@ del_mlist(char *hostp, char *dirp) static void add_mlist(char *hostp, char *dirp) { - struct mountlist *mlp, **mlpp; + struct mountlist *mlp; FILE *mlfile; - mlpp = &mlhead; - mlp = mlhead; - while (mlp) { + SLIST_FOREACH(mlp, &mlhead, next) { if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp)) return; - mlpp = &mlp->ml_next; - mlp = mlp->ml_next; } + mlp = (struct mountlist *)malloc(sizeof (*mlp)); if (mlp == (struct mountlist *)NULL) out_of_mem(); @@ -3054,8 +3021,7 @@ add_mlist(char *hostp, char *dirp) mlp->ml_host[MNTNAMLEN] = '\0'; strncpy(mlp->ml_dirp, dirp, MNTPATHLEN); mlp->ml_dirp[MNTPATHLEN] = '\0'; - mlp->ml_next = (struct mountlist *)NULL; - *mlpp = mlp; + SLIST_INSERT_HEAD(&mlhead, mlp, next); if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) { syslog(LOG_ERR, "can't update %s", _PATH_RMOUNTLIST); return; diff --git a/usr.sbin/moused/Makefile.depend b/usr.sbin/moused/Makefile.depend index a79b1eb12b7b..a015e205da56 100644 --- a/usr.sbin/moused/Makefile.depend +++ b/usr.sbin/moused/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mpsutil/Makefile.depend b/usr.sbin/mpsutil/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/mpsutil/Makefile.depend +++ b/usr.sbin/mpsutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mptable/Makefile.depend b/usr.sbin/mptable/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/mptable/Makefile.depend +++ b/usr.sbin/mptable/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mptutil/Makefile.depend b/usr.sbin/mptutil/Makefile.depend index 48a48dd2446c..ee06e1c20939 100644 --- a/usr.sbin/mptutil/Makefile.depend +++ b/usr.sbin/mptutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/mtest/Makefile.depend b/usr.sbin/mtest/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/mtest/Makefile.depend +++ b/usr.sbin/mtest/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/nandsim/Makefile.depend b/usr.sbin/nandsim/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/nandsim/Makefile.depend +++ b/usr.sbin/nandsim/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nandtool/Makefile.depend b/usr.sbin/nandtool/Makefile.depend index 851372cfd559..0220673c9076 100644 --- a/usr.sbin/nandtool/Makefile.depend +++ b/usr.sbin/nandtool/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ndiscvt/Makefile.depend b/usr.sbin/ndiscvt/Makefile.depend index b0669297e422..af1fb7abc88e 100644 --- a/usr.sbin/ndiscvt/Makefile.depend +++ b/usr.sbin/ndiscvt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ndp/Makefile.depend b/usr.sbin/ndp/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/ndp/Makefile.depend +++ b/usr.sbin/ndp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/newsyslog/Makefile.depend b/usr.sbin/newsyslog/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/newsyslog/Makefile.depend +++ b/usr.sbin/newsyslog/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nfscbd/Makefile.depend b/usr.sbin/nfscbd/Makefile.depend index 106151641a97..74a3ee19f459 100644 --- a/usr.sbin/nfscbd/Makefile.depend +++ b/usr.sbin/nfscbd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/xlocale \ diff --git a/usr.sbin/nfsd/Makefile.depend b/usr.sbin/nfsd/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/nfsd/Makefile.depend +++ b/usr.sbin/nfsd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/nfsdumpstate/Makefile.depend b/usr.sbin/nfsdumpstate/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/nfsdumpstate/Makefile.depend +++ b/usr.sbin/nfsdumpstate/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/nfsrevoke/Makefile.depend b/usr.sbin/nfsrevoke/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/nfsrevoke/Makefile.depend +++ b/usr.sbin/nfsrevoke/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nfsuserd/Makefile.depend b/usr.sbin/nfsuserd/Makefile.depend index 106151641a97..74a3ee19f459 100644 --- a/usr.sbin/nfsuserd/Makefile.depend +++ b/usr.sbin/nfsuserd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/xlocale \ diff --git a/usr.sbin/ngctl/Makefile.depend b/usr.sbin/ngctl/Makefile.depend index a0a98329803f..52687c716a09 100644 --- a/usr.sbin/ngctl/Makefile.depend +++ b/usr.sbin/ngctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nghook/Makefile.depend b/usr.sbin/nghook/Makefile.depend index 92ae034c03ef..3f4cb50e1709 100644 --- a/usr.sbin/nghook/Makefile.depend +++ b/usr.sbin/nghook/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nmtree/Makefile.depend b/usr.sbin/nmtree/Makefile.depend index 87dbfec94015..4e01fee15c05 100644 --- a/usr.sbin/nmtree/Makefile.depend +++ b/usr.sbin/nmtree/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/nologin/Makefile.depend b/usr.sbin/nologin/Makefile.depend index 9cb890b58360..cae7e645ef6a 100644 --- a/usr.sbin/nologin/Makefile.depend +++ b/usr.sbin/nologin/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/nscd/Makefile.depend b/usr.sbin/nscd/Makefile.depend index eec69a41def2..b208e1c5f44c 100644 --- a/usr.sbin/nscd/Makefile.depend +++ b/usr.sbin/nscd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ntp/ntp-keygen/Makefile.depend b/usr.sbin/ntp/ntp-keygen/Makefile.depend index 88a55c04f4ab..06280e113273 100644 --- a/usr.sbin/ntp/ntp-keygen/Makefile.depend +++ b/usr.sbin/ntp/ntp-keygen/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/ntpd/Makefile.depend b/usr.sbin/ntp/ntpd/Makefile.depend index e42a4dabfb46..39bf350d59d4 100644 --- a/usr.sbin/ntp/ntpd/Makefile.depend +++ b/usr.sbin/ntp/ntpd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/ntpdate/Makefile.depend b/usr.sbin/ntp/ntpdate/Makefile.depend index a231d4a4b5d5..c7f2a7c3eff4 100644 --- a/usr.sbin/ntp/ntpdate/Makefile.depend +++ b/usr.sbin/ntp/ntpdate/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/ntpdc/Makefile.depend b/usr.sbin/ntp/ntpdc/Makefile.depend index 6cb342f340d8..134f7eeb8c3c 100644 --- a/usr.sbin/ntp/ntpdc/Makefile.depend +++ b/usr.sbin/ntp/ntpdc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/ntpq/Makefile.depend b/usr.sbin/ntp/ntpq/Makefile.depend index 6cb342f340d8..134f7eeb8c3c 100644 --- a/usr.sbin/ntp/ntpq/Makefile.depend +++ b/usr.sbin/ntp/ntpq/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/ntptime/Makefile.depend b/usr.sbin/ntp/ntptime/Makefile.depend index a231d4a4b5d5..c7f2a7c3eff4 100644 --- a/usr.sbin/ntp/ntptime/Makefile.depend +++ b/usr.sbin/ntp/ntptime/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ntp/sntp/Makefile.depend b/usr.sbin/ntp/sntp/Makefile.depend index 9f44d4000727..3fa6c6c19b1c 100644 --- a/usr.sbin/ntp/sntp/Makefile.depend +++ b/usr.sbin/ntp/sntp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ofwdump/Makefile.depend b/usr.sbin/ofwdump/Makefile.depend index a5da8fda10c4..2ff61520f354 100644 --- a/usr.sbin/ofwdump/Makefile.depend +++ b/usr.sbin/ofwdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pciconf/Makefile.depend b/usr.sbin/pciconf/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/pciconf/Makefile.depend +++ b/usr.sbin/pciconf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pkg/Makefile.depend b/usr.sbin/pkg/Makefile.depend index 98b04b0859ac..0d93f91b60de 100644 --- a/usr.sbin/pkg/Makefile.depend +++ b/usr.sbin/pkg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/pmcannotate/Makefile.depend b/usr.sbin/pmcannotate/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/pmcannotate/Makefile.depend +++ b/usr.sbin/pmcannotate/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pmccontrol/Makefile.depend b/usr.sbin/pmccontrol/Makefile.depend index d29a35863180..a52f7b8c67dc 100644 --- a/usr.sbin/pmccontrol/Makefile.depend +++ b/usr.sbin/pmccontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile index dc5a30a40003..472067767ab2 100644 --- a/usr.sbin/pmcstat/Makefile +++ b/usr.sbin/pmcstat/Makefile @@ -5,7 +5,7 @@ PROG= pmcstat MAN= pmcstat.8 -LIBADD= elf kvm pmc m ncursesw +LIBADD= kvm pmc m ncursesw pmcstat elf SRCS= pmcstat.c pmcstat.h pmcstat_log.c \ pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c \ diff --git a/usr.sbin/pmcstat/Makefile.depend b/usr.sbin/pmcstat/Makefile.depend index a3f722581ca0..6d010477ce76 100644 --- a/usr.sbin/pmcstat/Makefile.depend +++ b/usr.sbin/pmcstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ @@ -12,6 +11,7 @@ DIRDEPS = \ lib/libelf \ lib/libkvm \ lib/libpmc \ + lib/libpmcstat \ lib/msun \ lib/ncurses/ncursesw \ diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c index 33998b51baac..b461388e928e 100644 --- a/usr.sbin/pmcstat/pmcpl_callgraph.c +++ b/usr.sbin/pmcstat/pmcpl_callgraph.c @@ -73,6 +73,9 @@ __FBSDID("$FreeBSD$"); #include "pmcstat_top.h" #include "pmcpl_callgraph.h" +#define min(A,B) ((A) < (B) ? (A) : (B)) +#define max(A,B) ((A) > (B) ? (A) : (B)) + /* Get the sample value in percent related to nsamples. */ #define PMCPL_CG_COUNTP(a) \ ((a)->pcg_count * 100.0 / nsamples) @@ -638,8 +641,11 @@ pmcpl_cg_topdisplay(void) */ int -pmcpl_cg_topkeypress(int c, WINDOW *w) +pmcpl_cg_topkeypress(int c, void *arg) { + WINDOW *w; + + w = (WINDOW *)arg; (void) c; (void) w; diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.h b/usr.sbin/pmcstat/pmcpl_callgraph.h index aaf0e1ba1d69..d67359b64981 100644 --- a/usr.sbin/pmcstat/pmcpl_callgraph.h +++ b/usr.sbin/pmcstat/pmcpl_callgraph.h @@ -60,7 +60,7 @@ void pmcpl_cg_shutdown(FILE *mf); void pmcpl_cg_process( struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu); -int pmcpl_cg_topkeypress(int c, WINDOW *w); +int pmcpl_cg_topkeypress(int c, void *w); void pmcpl_cg_topdisplay(void); void pmcpl_cg_configure(char *opt); diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c index 0f95ac172668..be03f3e8bc00 100644 --- a/usr.sbin/pmcstat/pmcpl_calltree.c +++ b/usr.sbin/pmcstat/pmcpl_calltree.c @@ -58,6 +58,9 @@ __FBSDID("$FreeBSD$"); #include "pmcstat_top.h" #include "pmcpl_calltree.h" +#define min(A,B) ((A) < (B) ? (A) : (B)) +#define max(A,B) ((A) > (B) ? (A) : (B)) + #define PMCPL_CT_GROWSIZE 4 static int pmcstat_skiplink = 0; @@ -581,8 +584,11 @@ pmcpl_ct_topdisplay(void) */ int -pmcpl_ct_topkeypress(int c, WINDOW *w) +pmcpl_ct_topkeypress(int c, void *arg) { + WINDOW *w; + + w = (WINDOW *)arg; switch (c) { case 'f': diff --git a/usr.sbin/pmcstat/pmcpl_calltree.h b/usr.sbin/pmcstat/pmcpl_calltree.h index f54957f83f71..763a4ad75ce2 100644 --- a/usr.sbin/pmcstat/pmcpl_calltree.h +++ b/usr.sbin/pmcstat/pmcpl_calltree.h @@ -35,7 +35,7 @@ void pmcpl_ct_shutdown(FILE *mf); void pmcpl_ct_process( struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu); -int pmcpl_ct_topkeypress(int c, WINDOW *w); +int pmcpl_ct_topkeypress(int c, void *w); void pmcpl_ct_topdisplay(void); int pmcpl_ct_configure(char *opt); diff --git a/usr.sbin/pmcstat/pmcpl_gprof.c b/usr.sbin/pmcstat/pmcpl_gprof.c index acb339e96f51..fc80fbce8a17 100644 --- a/usr.sbin/pmcstat/pmcpl_gprof.c +++ b/usr.sbin/pmcstat/pmcpl_gprof.c @@ -76,6 +76,9 @@ __FBSDID("$FreeBSD$"); typedef uint64_t WIDEHISTCOUNTER; +#define min(A,B) ((A) < (B) ? (A) : (B)) +#define max(A,B) ((A) > (B) ? (A) : (B)) + #define WIDEHISTCOUNTER_MAX UINT64_MAX #define HISTCOUNTER_MAX USHRT_MAX #define WIDEHISTCOUNTER_GMONTYPE ((int) 64) @@ -436,7 +439,7 @@ pmcpl_gmon_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, * this executable image, try determine its parameters. */ if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_determine_type(image); + pmcstat_image_determine_type(image, &args); assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN); diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c index b87444339600..853acc6dd11f 100644 --- a/usr.sbin/pmcstat/pmcstat.c +++ b/usr.sbin/pmcstat/pmcstat.c @@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "pmcstat.h" /* @@ -113,38 +115,6 @@ static kvm_t *pmcstat_kvm; static struct kinfo_proc *pmcstat_plist; struct pmcstat_args args; -static void -pmcstat_clone_event_descriptor(struct pmcstat_ev *ev, const cpuset_t *cpumask) -{ - int cpu; - struct pmcstat_ev *ev_clone; - - for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { - if (!CPU_ISSET(cpu, cpumask)) - continue; - - if ((ev_clone = malloc(sizeof(*ev_clone))) == NULL) - errx(EX_SOFTWARE, "ERROR: Out of memory"); - (void) memset(ev_clone, 0, sizeof(*ev_clone)); - - ev_clone->ev_count = ev->ev_count; - ev_clone->ev_cpu = cpu; - ev_clone->ev_cumulative = ev->ev_cumulative; - ev_clone->ev_flags = ev->ev_flags; - ev_clone->ev_mode = ev->ev_mode; - ev_clone->ev_name = strdup(ev->ev_name); - if (ev_clone->ev_name == NULL) - errx(EX_SOFTWARE, "ERROR: Out of memory"); - ev_clone->ev_pmcid = ev->ev_pmcid; - ev_clone->ev_saved = ev->ev_saved; - ev_clone->ev_spec = strdup(ev->ev_spec); - if (ev_clone->ev_spec == NULL) - errx(EX_SOFTWARE, "ERROR: Out of memory"); - - STAILQ_INSERT_TAIL(&args.pa_events, ev_clone, ev_next); - } -} - static void pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask) { @@ -167,32 +137,6 @@ pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask) assert(!CPU_EMPTY(cpumask)); } -void -pmcstat_attach_pmcs(void) -{ - struct pmcstat_ev *ev; - struct pmcstat_target *pt; - int count; - - /* Attach all process PMCs to target processes. */ - count = 0; - STAILQ_FOREACH(ev, &args.pa_events, ev_next) { - if (PMC_IS_SYSTEM_MODE(ev->ev_mode)) - continue; - SLIST_FOREACH(pt, &args.pa_targets, pt_next) - if (pmc_attach(ev->ev_pmcid, pt->pt_pid) == 0) - count++; - else if (errno != ESRCH) - err(EX_OSERR, -"ERROR: cannot attach pmc \"%s\" to process %d", - ev->ev_name, (int)pt->pt_pid); - } - - if (count == 0) - errx(EX_DATAERR, "ERROR: No processes were attached to."); -} - - void pmcstat_cleanup(void) { @@ -220,66 +164,7 @@ pmcstat_cleanup(void) args.pa_logparser = NULL; } - pmcstat_shutdown_logging(); -} - -void -pmcstat_create_process(void) -{ - char token; - pid_t pid; - struct kevent kev; - struct pmcstat_target *pt; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pmcstat_sockpair) < 0) - err(EX_OSERR, "ERROR: cannot create socket pair"); - - switch (pid = fork()) { - case -1: - err(EX_OSERR, "ERROR: cannot fork"); - /*NOTREACHED*/ - - case 0: /* child */ - (void) close(pmcstat_sockpair[PARENTSOCKET]); - - /* Write a token to tell our parent we've started executing. */ - if (write(pmcstat_sockpair[CHILDSOCKET], "+", 1) != 1) - err(EX_OSERR, "ERROR (child): cannot write token"); - - /* Wait for our parent to signal us to start. */ - if (read(pmcstat_sockpair[CHILDSOCKET], &token, 1) < 0) - err(EX_OSERR, "ERROR (child): cannot read token"); - (void) close(pmcstat_sockpair[CHILDSOCKET]); - - /* exec() the program requested */ - execvp(*args.pa_argv, args.pa_argv); - /* and if that fails, notify the parent */ - kill(getppid(), SIGCHLD); - err(EX_OSERR, "ERROR: execvp \"%s\" failed", *args.pa_argv); - /*NOTREACHED*/ - - default: /* parent */ - (void) close(pmcstat_sockpair[CHILDSOCKET]); - break; - } - - /* Ask to be notified via a kevent when the target process exits. */ - EV_SET(&kev, pid, EVFILT_PROC, EV_ADD|EV_ONESHOT, NOTE_EXIT, 0, - NULL); - if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0) - err(EX_OSERR, "ERROR: cannot monitor child process %d", pid); - - if ((pt = malloc(sizeof(*pt))) == NULL) - errx(EX_SOFTWARE, "ERROR: Out of memory."); - - pt->pt_pid = pid; - SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next); - - /* Wait for the child to signal that its ready to go. */ - if (read(pmcstat_sockpair[PARENTSOCKET], &token, 1) < 0) - err(EX_OSERR, "ERROR (parent): cannot read token"); - - return; + pmcstat_log_shutdown_logging(); } void @@ -377,7 +262,6 @@ pmcstat_start_pmcs(void) exit(EX_OSERR); } } - } void @@ -465,24 +349,6 @@ pmcstat_print_pmcs(void) return; } -/* - * Do process profiling - * - * If a pid was specified, attach each allocated PMC to the target - * process. Otherwise, fork a child and attach the PMCs to the child, - * and have the child exec() the target program. - */ - -void -pmcstat_start_process(void) -{ - /* Signal the child to proceed. */ - if (write(pmcstat_sockpair[PARENTSOCKET], "!", 1) != 1) - err(EX_OSERR, "ERROR (parent): write of token failed"); - - (void) close(pmcstat_sockpair[PARENTSOCKET]); -} - void pmcstat_show_usage(void) { @@ -772,7 +638,7 @@ main(int argc, char **argv) if (option == 's' || option == 'S') args.pa_flags |= FLAG_HAS_SYSTEM_PMCS; - ev->ev_spec = strdup(optarg); + ev->ev_spec = strdup(optarg); if (ev->ev_spec == NULL) errx(EX_SOFTWARE, "ERROR: Out of memory."); @@ -813,7 +679,7 @@ main(int argc, char **argv) if (option == 's' || option == 'S') { CPU_CLR(ev->ev_cpu, &cpumask); - pmcstat_clone_event_descriptor(ev, &cpumask); + pmcstat_clone_event_descriptor(ev, &cpumask, &args); CPU_SET(ev->ev_cpu, &cpumask); } @@ -1157,7 +1023,7 @@ main(int argc, char **argv) if ((args.pa_flags & FLAG_DO_ANALYSIS) == 0) args.pa_flags |= FLAG_DO_PRINT; - pmcstat_initialize_logging(); + pmcstat_log_initialize_logging(); rfd = pmcstat_open_log(args.pa_inputpath, PMCSTAT_OPEN_FOR_READ); if ((args.pa_logparser = pmclog_open(rfd)) == NULL) @@ -1333,7 +1199,7 @@ main(int argc, char **argv) /* attach PMCs to the target process, starting it if specified */ if (args.pa_flags & FLAG_HAS_COMMANDLINE) - pmcstat_create_process(); + pmcstat_create_process(pmcstat_sockpair, &args, pmcstat_kq); if (check_driver_stats && pmc_get_driver_stats(&ds_start) < 0) err(EX_OSERR, "ERROR: Cannot retrieve driver statistics"); @@ -1344,7 +1210,7 @@ main(int argc, char **argv) errx(EX_DATAERR, "ERROR: No matching target processes."); if (args.pa_flags & FLAG_HAS_PROCESS_PMCS) - pmcstat_attach_pmcs(); + pmcstat_attach_pmcs(&args); if (pmcstat_kvm) { kvm_close(pmcstat_kvm); @@ -1357,10 +1223,10 @@ main(int argc, char **argv) /* start the (commandline) process if needed */ if (args.pa_flags & FLAG_HAS_COMMANDLINE) - pmcstat_start_process(); + pmcstat_start_process(pmcstat_sockpair); /* initialize logging */ - pmcstat_initialize_logging(); + pmcstat_log_initialize_logging(); /* Handle SIGINT using the kqueue loop */ sa.sa_handler = SIG_IGN; @@ -1424,7 +1290,7 @@ main(int argc, char **argv) switch (kev.filter) { case EVFILT_PROC: /* target has exited */ - runstate = pmcstat_close_log(); + runstate = pmcstat_close_log(&args); do_print = 1; break; @@ -1432,7 +1298,7 @@ main(int argc, char **argv) if (kev.ident == (unsigned)fileno(stdin) && (args.pa_flags & FLAG_DO_TOP)) { if (pmcstat_keypress_log()) - runstate = pmcstat_close_log(); + runstate = pmcstat_close_log(&args); } else { do_read = 0; runstate = pmcstat_process_log(); @@ -1455,13 +1321,13 @@ main(int argc, char **argv) * of its targets, or if logfile * writes encounter an error. */ - runstate = pmcstat_close_log(); + runstate = pmcstat_close_log(&args); do_print = 1; /* print PMCs at exit */ } else if (kev.ident == SIGINT) { /* Kill the child process if we started it */ if (args.pa_flags & FLAG_HAS_COMMANDLINE) pmcstat_kill_process(); - runstate = pmcstat_close_log(); + runstate = pmcstat_close_log(&args); } else if (kev.ident == SIGWINCH) { if (ioctl(fileno(args.pa_printfile), TIOCGWINSZ, &ws) < 0) diff --git a/usr.sbin/pmcstat/pmcstat.h b/usr.sbin/pmcstat/pmcstat.h index 5b1d3d916792..d008f54e7de9 100644 --- a/usr.sbin/pmcstat/pmcstat.h +++ b/usr.sbin/pmcstat/pmcstat.h @@ -33,29 +33,7 @@ #ifndef _PMCSTAT_H_ #define _PMCSTAT_H_ -#include - -#define FLAG_HAS_TARGET 0x00000001 /* process target */ -#define FLAG_HAS_WAIT_INTERVAL 0x00000002 /* -w secs */ -#define FLAG_HAS_OUTPUT_LOGFILE 0x00000004 /* -O file or pipe */ -#define FLAG_HAS_COMMANDLINE 0x00000008 /* command */ -#define FLAG_HAS_SAMPLING_PMCS 0x00000010 /* -S or -P */ -#define FLAG_HAS_COUNTING_PMCS 0x00000020 /* -s or -p */ -#define FLAG_HAS_PROCESS_PMCS 0x00000040 /* -P or -p */ -#define FLAG_HAS_SYSTEM_PMCS 0x00000080 /* -S or -s */ -#define FLAG_HAS_PIPE 0x00000100 /* implicit log */ -#define FLAG_READ_LOGFILE 0x00000200 /* -R file */ -#define FLAG_DO_GPROF 0x00000400 /* -g */ -#define FLAG_HAS_SAMPLESDIR 0x00000800 /* -D dir */ -#define FLAG_HAS_KERNELPATH 0x00001000 /* -k kernel */ -#define FLAG_DO_PRINT 0x00002000 /* -o */ -#define FLAG_DO_CALLGRAPHS 0x00004000 /* -G or -F */ -#define FLAG_DO_ANNOTATE 0x00008000 /* -m */ -#define FLAG_DO_TOP 0x00010000 /* -T */ -#define FLAG_DO_ANALYSIS 0x00020000 /* -g or -G or -m or -T */ -#define FLAGS_HAS_CPUMASK 0x00040000 /* -c */ -#define FLAG_HAS_DURATION 0x00080000 /* -l secs */ -#define FLAG_DO_WIDE_GPROF_HC 0x00100000 /* -e */ +#include #define DEFAULT_SAMPLE_COUNT 65536 #define DEFAULT_WAIT_INTERVAL 5.0 @@ -65,20 +43,9 @@ #define DEFAULT_CALLGRAPH_DEPTH 16 #define PRINT_HEADER_PREFIX "# " -#define READPIPEFD 0 -#define WRITEPIPEFD 1 -#define NPIPEFD 2 -#define NSOCKPAIRFD 2 -#define PARENTSOCKET 0 -#define CHILDSOCKET 1 - -#define PMCSTAT_OPEN_FOR_READ 0 -#define PMCSTAT_OPEN_FOR_WRITE 1 #define PMCSTAT_DEFAULT_NW_HOST "localhost" #define PMCSTAT_DEFAULT_NW_PORT "9000" -#define PMCSTAT_NHASH 256 -#define PMCSTAT_HASH_MASK 0xFF #define PMCSTAT_LDD_COMMAND "/usr/bin/ldd" @@ -98,90 +65,26 @@ #define PMCSTAT_TOP_DELTA 0 #define PMCSTAT_TOP_ACCUM 1 -#define min(A,B) ((A) < (B) ? (A) : (B)) -#define max(A,B) ((A) > (B) ? (A) : (B)) - -enum pmcstat_state { - PMCSTAT_FINISHED = 0, - PMCSTAT_EXITING = 1, - PMCSTAT_RUNNING = 2 -}; - -struct pmcstat_ev { - STAILQ_ENTRY(pmcstat_ev) ev_next; - int ev_count; /* associated count if in sampling mode */ - uint32_t ev_cpu; /* cpus for this event */ - int ev_cumulative; /* show cumulative counts */ - int ev_flags; /* PMC_F_* */ - int ev_fieldskip; /* #leading spaces */ - int ev_fieldwidth; /* print width */ - enum pmc_mode ev_mode; /* desired mode */ - char *ev_name; /* (derived) event name */ - pmc_id_t ev_pmcid; /* allocated ID */ - pmc_value_t ev_saved; /* for incremental counts */ - char *ev_spec; /* event specification */ -}; - -struct pmcstat_target { - SLIST_ENTRY(pmcstat_target) pt_next; - pid_t pt_pid; -}; - -struct pmcstat_args { - int pa_flags; /* argument flags */ - int pa_required; /* required features */ - int pa_pplugin; /* pre-processing plugin */ - int pa_plugin; /* analysis plugin */ - int pa_verbosity; /* verbosity level */ - FILE *pa_printfile; /* where to send printed output */ - int pa_logfd; /* output log file */ - char *pa_inputpath; /* path to input log */ - char *pa_outputpath; /* path to output log */ - void *pa_logparser; /* log file parser */ - const char *pa_fsroot; /* FS root where executables reside */ - char *pa_kernel; /* pathname of the kernel */ - const char *pa_samplesdir; /* directory for profile files */ - const char *pa_mapfilename;/* mapfile name */ - FILE *pa_graphfile; /* where to send the callgraph */ - int pa_graphdepth; /* print depth for callgraphs */ - double pa_interval; /* printing interval in seconds */ - cpuset_t pa_cpumask; /* filter for CPUs analysed */ - int pa_ctdumpinstr; /* dump instructions with calltree */ - int pa_topmode; /* delta or accumulative */ - int pa_toptty; /* output to tty or file */ - int pa_topcolor; /* terminal support color */ - int pa_mergepmc; /* merge PMC with same name */ - double pa_duration; /* time duration */ - int pa_argc; - char **pa_argv; - STAILQ_HEAD(, pmcstat_ev) pa_events; - SLIST_HEAD(, pmcstat_target) pa_targets; -}; - extern int pmcstat_displayheight; /* current terminal height */ extern int pmcstat_displaywidth; /* current terminal width */ extern struct pmcstat_args args; /* command line args */ /* Function prototypes */ -void pmcstat_attach_pmcs(void); void pmcstat_cleanup(void); -int pmcstat_close_log(void); -void pmcstat_create_process(void); void pmcstat_find_targets(const char *_arg); -void pmcstat_initialize_logging(void); void pmcstat_kill_process(void); -int pmcstat_open_log(const char *_p, int _mode); void pmcstat_print_counters(void); void pmcstat_print_headers(void); void pmcstat_print_pmcs(void); void pmcstat_show_usage(void); -void pmcstat_shutdown_logging(void); void pmcstat_start_pmcs(void); -void pmcstat_start_process(void); int pmcstat_process_log(void); int pmcstat_keypress_log(void); void pmcstat_display_log(void); void pmcstat_pluginconfigure_log(char *_opt); -void pmcstat_topexit(void); +void pmcstat_topexit(void); + +void pmcstat_log_shutdown_logging(void); +void pmcstat_log_initialize_logging(void); #endif /* _PMCSTAT_H_ */ diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index aaca29220c12..5efad1bf0374 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -73,8 +73,6 @@ __FBSDID("$FreeBSD$"); #include "pmcstat_log.h" #include "pmcstat_top.h" -#define PMCSTAT_ALLOCATE 1 - /* * PUBLIC INTERFACES * @@ -152,36 +150,7 @@ struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */ #include "pmcpl_annotate_cg.h" #include "pmcpl_calltree.h" -static struct pmc_plugins { - const char *pl_name; /* name */ - - /* configure */ - int (*pl_configure)(char *opt); - - /* init and shutdown */ - int (*pl_init)(void); - void (*pl_shutdown)(FILE *mf); - - /* sample processing */ - void (*pl_process)(struct pmcstat_process *pp, - struct pmcstat_pmcrecord *pmcr, uint32_t nsamples, - uintfptr_t *cc, int usermode, uint32_t cpu); - - /* image */ - void (*pl_initimage)(struct pmcstat_image *pi); - void (*pl_shutdownimage)(struct pmcstat_image *pi); - - /* pmc */ - void (*pl_newpmc)(pmcstat_interned_string ps, - struct pmcstat_pmcrecord *pr); - - /* top display */ - void (*pl_topdisplay)(void); - - /* top keypress */ - int (*pl_topkeypress)(int c, WINDOW *w); - -} plugins[] = { +static struct pmc_plugins plugins[] = { { .pl_name = "none", }, @@ -233,46 +202,8 @@ float pmcstat_threshold = 0.5; /* Cost filter for top mode. */ * Prototypes */ -static struct pmcstat_image *pmcstat_image_from_path(pmcstat_interned_string - _path, int _iskernelmodule); -static void pmcstat_image_get_aout_params(struct pmcstat_image *_image); -static void pmcstat_image_get_elf_params(struct pmcstat_image *_image); -static void pmcstat_image_link(struct pmcstat_process *_pp, - struct pmcstat_image *_i, uintfptr_t _lpc); - -static void pmcstat_pmcid_add(pmc_id_t _pmcid, - pmcstat_interned_string _name); - -static void pmcstat_process_aout_exec(struct pmcstat_process *_pp, - struct pmcstat_image *_image, uintfptr_t _entryaddr); -static void pmcstat_process_elf_exec(struct pmcstat_process *_pp, - struct pmcstat_image *_image, uintfptr_t _entryaddr); -static void pmcstat_process_exec(struct pmcstat_process *_pp, - pmcstat_interned_string _path, uintfptr_t _entryaddr); -static struct pmcstat_process *pmcstat_process_lookup(pid_t _pid, - int _allocate); -static int pmcstat_string_compute_hash(const char *_string); -static void pmcstat_string_initialize(void); -static int pmcstat_string_lookup_hash(pmcstat_interned_string _is); -static void pmcstat_string_shutdown(void); static void pmcstat_stats_reset(int _reset_global); -/* - * A simple implementation of interned strings. Each interned string - * is assigned a unique address, so that subsequent string compares - * can be done by a simple pointer comparison instead of using - * strcmp(). This speeds up hash table lookups and saves memory if - * duplicate strings are the norm. - */ -struct pmcstat_string { - LIST_ENTRY(pmcstat_string) ps_next; /* hash link */ - int ps_len; - int ps_hash; - char *ps_string; -}; - -static LIST_HEAD(,pmcstat_string) pmcstat_string_hash[PMCSTAT_NHASH]; - /* * PMC count. */ @@ -300,663 +231,6 @@ pmcstat_stats_reset(int reset_global) bzero(&pmcstat_stats, sizeof(struct pmcstat_stats)); } -/* - * Compute a 'hash' value for a string. - */ - -static int -pmcstat_string_compute_hash(const char *s) -{ - unsigned hash; - - for (hash = 2166136261; *s; s++) - hash = (hash ^ *s) * 16777619; - - return (hash & PMCSTAT_HASH_MASK); -} - -/* - * Intern a copy of string 's', and return a pointer to the - * interned structure. - */ - -pmcstat_interned_string -pmcstat_string_intern(const char *s) -{ - struct pmcstat_string *ps; - const struct pmcstat_string *cps; - int hash, len; - - if ((cps = pmcstat_string_lookup(s)) != NULL) - return (cps); - - hash = pmcstat_string_compute_hash(s); - len = strlen(s); - - if ((ps = malloc(sizeof(*ps))) == NULL) - err(EX_OSERR, "ERROR: Could not intern string"); - ps->ps_len = len; - ps->ps_hash = hash; - ps->ps_string = strdup(s); - LIST_INSERT_HEAD(&pmcstat_string_hash[hash], ps, ps_next); - return ((pmcstat_interned_string) ps); -} - -const char * -pmcstat_string_unintern(pmcstat_interned_string str) -{ - const char *s; - - s = ((const struct pmcstat_string *) str)->ps_string; - return (s); -} - -pmcstat_interned_string -pmcstat_string_lookup(const char *s) -{ - struct pmcstat_string *ps; - int hash, len; - - hash = pmcstat_string_compute_hash(s); - len = strlen(s); - - LIST_FOREACH(ps, &pmcstat_string_hash[hash], ps_next) - if (ps->ps_len == len && ps->ps_hash == hash && - strcmp(ps->ps_string, s) == 0) - return (ps); - return (NULL); -} - -static int -pmcstat_string_lookup_hash(pmcstat_interned_string s) -{ - const struct pmcstat_string *ps; - - ps = (const struct pmcstat_string *) s; - return (ps->ps_hash); -} - -/* - * Initialize the string interning facility. - */ - -static void -pmcstat_string_initialize(void) -{ - int i; - - for (i = 0; i < PMCSTAT_NHASH; i++) - LIST_INIT(&pmcstat_string_hash[i]); -} - -/* - * Destroy the string table, free'ing up space. - */ - -static void -pmcstat_string_shutdown(void) -{ - int i; - struct pmcstat_string *ps, *pstmp; - - for (i = 0; i < PMCSTAT_NHASH; i++) - LIST_FOREACH_SAFE(ps, &pmcstat_string_hash[i], ps_next, - pstmp) { - LIST_REMOVE(ps, ps_next); - free(ps->ps_string); - free(ps); - } -} - -/* - * Determine whether a given executable image is an A.OUT object, and - * if so, fill in its parameters from the text file. - * Sets image->pi_type. - */ - -static void -pmcstat_image_get_aout_params(struct pmcstat_image *image) -{ - int fd; - ssize_t nbytes; - struct exec ex; - const char *path; - char buffer[PATH_MAX]; - - path = pmcstat_string_unintern(image->pi_execpath); - assert(path != NULL); - - if (image->pi_iskernelmodule) - errx(EX_SOFTWARE, - "ERROR: a.out kernel modules are unsupported \"%s\"", path); - - (void) snprintf(buffer, sizeof(buffer), "%s%s", - args.pa_fsroot, path); - - if ((fd = open(buffer, O_RDONLY, 0)) < 0 || - (nbytes = read(fd, &ex, sizeof(ex))) < 0) { - if (args.pa_verbosity >= 2) - warn("WARNING: Cannot determine type of \"%s\"", - path); - image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE; - if (fd != -1) - (void) close(fd); - return; - } - - (void) close(fd); - - if ((unsigned) nbytes != sizeof(ex) || - N_BADMAG(ex)) - return; - - image->pi_type = PMCSTAT_IMAGE_AOUT; - - /* TODO: the rest of a.out processing */ - - return; -} - -/* - * Helper function. - */ - -static int -pmcstat_symbol_compare(const void *a, const void *b) -{ - const struct pmcstat_symbol *sym1, *sym2; - - sym1 = (const struct pmcstat_symbol *) a; - sym2 = (const struct pmcstat_symbol *) b; - - if (sym1->ps_end <= sym2->ps_start) - return (-1); - if (sym1->ps_start >= sym2->ps_end) - return (1); - return (0); -} - -/* - * Map an address to a symbol in an image. - */ - -struct pmcstat_symbol * -pmcstat_symbol_search(struct pmcstat_image *image, uintfptr_t addr) -{ - struct pmcstat_symbol sym; - - if (image->pi_symbols == NULL) - return (NULL); - - sym.ps_name = NULL; - sym.ps_start = addr; - sym.ps_end = addr + 1; - - return (bsearch((void *) &sym, image->pi_symbols, - image->pi_symcount, sizeof(struct pmcstat_symbol), - pmcstat_symbol_compare)); -} - -/* - * Add the list of symbols in the given section to the list associated - * with the object. - */ -static void -pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e, - Elf_Scn *scn, GElf_Shdr *sh) -{ - int firsttime; - size_t n, newsyms, nshsyms, nfuncsyms; - struct pmcstat_symbol *symptr; - char *fnname; - GElf_Sym sym; - Elf_Data *data; - - if ((data = elf_getdata(scn, NULL)) == NULL) - return; - - /* - * Determine the number of functions named in this - * section. - */ - - nshsyms = sh->sh_size / sh->sh_entsize; - for (n = nfuncsyms = 0; n < nshsyms; n++) { - if (gelf_getsym(data, (int) n, &sym) != &sym) - return; - if (GELF_ST_TYPE(sym.st_info) == STT_FUNC) - nfuncsyms++; - } - - if (nfuncsyms == 0) - return; - - /* - * Allocate space for the new entries. - */ - firsttime = image->pi_symbols == NULL; - symptr = reallocarray(image->pi_symbols, - image->pi_symcount + nfuncsyms, sizeof(*symptr)); - if (symptr == image->pi_symbols) /* realloc() failed. */ - return; - image->pi_symbols = symptr; - - /* - * Append new symbols to the end of the current table. - */ - symptr += image->pi_symcount; - - for (n = newsyms = 0; n < nshsyms; n++) { - if (gelf_getsym(data, (int) n, &sym) != &sym) - return; - if (GELF_ST_TYPE(sym.st_info) != STT_FUNC) - continue; - if (sym.st_shndx == STN_UNDEF) - continue; - - if (!firsttime && pmcstat_symbol_search(image, sym.st_value)) - continue; /* We've seen this symbol already. */ - - if ((fnname = elf_strptr(e, sh->sh_link, sym.st_name)) - == NULL) - continue; -#ifdef __arm__ - /* Remove spurious ARM function name. */ - if (fnname[0] == '$' && - (fnname[1] == 'a' || fnname[1] == 't' || - fnname[1] == 'd') && - fnname[2] == '\0') - continue; -#endif - - symptr->ps_name = pmcstat_string_intern(fnname); - symptr->ps_start = sym.st_value - image->pi_vaddr; - symptr->ps_end = symptr->ps_start + sym.st_size; - symptr++; - - newsyms++; - } - - image->pi_symcount += newsyms; - if (image->pi_symcount == 0) - return; - - assert(newsyms <= nfuncsyms); - - /* - * Return space to the system if there were duplicates. - */ - if (newsyms < nfuncsyms) - image->pi_symbols = reallocarray(image->pi_symbols, - image->pi_symcount, sizeof(*symptr)); - - /* - * Keep the list of symbols sorted. - */ - qsort(image->pi_symbols, image->pi_symcount, sizeof(*symptr), - pmcstat_symbol_compare); - - /* - * Deal with function symbols that have a size of 'zero' by - * making them extend to the next higher address. These - * symbols are usually defined in assembly code. - */ - for (symptr = image->pi_symbols; - symptr < image->pi_symbols + (image->pi_symcount - 1); - symptr++) - if (symptr->ps_start == symptr->ps_end) - symptr->ps_end = (symptr+1)->ps_start; -} - -/* - * Examine an ELF file to determine the size of its text segment. - * Sets image->pi_type if anything conclusive can be determined about - * this image. - */ - -static void -pmcstat_image_get_elf_params(struct pmcstat_image *image) -{ - int fd; - size_t i, nph, nsh; - const char *path, *elfbase; - char *p, *endp; - uintfptr_t minva, maxva; - Elf *e; - Elf_Scn *scn; - GElf_Ehdr eh; - GElf_Phdr ph; - GElf_Shdr sh; - enum pmcstat_image_type image_type; - char buffer[PATH_MAX]; - - assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); - - image->pi_start = minva = ~(uintfptr_t) 0; - image->pi_end = maxva = (uintfptr_t) 0; - image->pi_type = image_type = PMCSTAT_IMAGE_INDETERMINABLE; - image->pi_isdynamic = 0; - image->pi_dynlinkerpath = NULL; - image->pi_vaddr = 0; - - path = pmcstat_string_unintern(image->pi_execpath); - assert(path != NULL); - - /* - * Look for kernel modules under FSROOT/KERNELPATH/NAME, - * and user mode executable objects under FSROOT/PATHNAME. - */ - if (image->pi_iskernelmodule) - (void) snprintf(buffer, sizeof(buffer), "%s%s/%s", - args.pa_fsroot, args.pa_kernel, path); - else - (void) snprintf(buffer, sizeof(buffer), "%s%s", - args.pa_fsroot, path); - - e = NULL; - if ((fd = open(buffer, O_RDONLY, 0)) < 0 || - (e = elf_begin(fd, ELF_C_READ, NULL)) == NULL || - (elf_kind(e) != ELF_K_ELF)) { - if (args.pa_verbosity >= 2) - warnx("WARNING: Cannot determine the type of \"%s\".", - buffer); - goto done; - } - - if (gelf_getehdr(e, &eh) != &eh) { - warnx( - "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.", - buffer, elf_errmsg(-1)); - goto done; - } - - if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN && - !(image->pi_iskernelmodule && eh.e_type == ET_REL)) { - warnx("WARNING: \"%s\" is of an unsupported ELF type.", - buffer); - goto done; - } - - image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ? - PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64; - - /* - * Determine the virtual address where an executable would be - * loaded. Additionally, for dynamically linked executables, - * save the pathname to the runtime linker. - */ - if (eh.e_type == ET_EXEC) { - if (elf_getphnum(e, &nph) == 0) { - warnx( -"WARNING: Could not determine the number of program headers in \"%s\": %s.", - buffer, - elf_errmsg(-1)); - goto done; - } - for (i = 0; i < eh.e_phnum; i++) { - if (gelf_getphdr(e, i, &ph) != &ph) { - warnx( -"WARNING: Retrieval of PHDR entry #%ju in \"%s\" failed: %s.", - (uintmax_t) i, buffer, elf_errmsg(-1)); - goto done; - } - switch (ph.p_type) { - case PT_DYNAMIC: - image->pi_isdynamic = 1; - break; - case PT_INTERP: - if ((elfbase = elf_rawfile(e, NULL)) == NULL) { - warnx( -"WARNING: Cannot retrieve the interpreter for \"%s\": %s.", - buffer, elf_errmsg(-1)); - goto done; - } - image->pi_dynlinkerpath = - pmcstat_string_intern(elfbase + - ph.p_offset); - break; - case PT_LOAD: - if ((ph.p_flags & PF_X) != 0 && - (ph.p_offset & (-ph.p_align)) == 0) - image->pi_vaddr = ph.p_vaddr & (-ph.p_align); - break; - } - } - } - - /* - * Get the min and max VA associated with this ELF object. - */ - if (elf_getshnum(e, &nsh) == 0) { - warnx( -"WARNING: Could not determine the number of sections for \"%s\": %s.", - buffer, elf_errmsg(-1)); - goto done; - } - - for (i = 0; i < nsh; i++) { - if ((scn = elf_getscn(e, i)) == NULL || - gelf_getshdr(scn, &sh) != &sh) { - warnx( -"WARNING: Could not retrieve section header #%ju in \"%s\": %s.", - (uintmax_t) i, buffer, elf_errmsg(-1)); - goto done; - } - if (sh.sh_flags & SHF_EXECINSTR) { - minva = min(minva, sh.sh_addr); - maxva = max(maxva, sh.sh_addr + sh.sh_size); - } - if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM) - pmcstat_image_add_symbols(image, e, scn, &sh); - } - - image->pi_start = minva; - image->pi_end = maxva; - image->pi_type = image_type; - image->pi_fullpath = pmcstat_string_intern(buffer); - - /* Build display name - */ - endp = buffer; - for (p = buffer; *p; p++) - if (*p == '/') - endp = p+1; - image->pi_name = pmcstat_string_intern(endp); - - done: - (void) elf_end(e); - if (fd >= 0) - (void) close(fd); - return; -} - -/* - * Given an image descriptor, determine whether it is an ELF, or AOUT. - * If no handler claims the image, set its type to 'INDETERMINABLE'. - */ - -void -pmcstat_image_determine_type(struct pmcstat_image *image) -{ - assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); - - /* Try each kind of handler in turn */ - if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_get_elf_params(image); - if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_get_aout_params(image); - - /* - * Otherwise, remember that we tried to determine - * the object's type and had failed. - */ - if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE; -} - -/* - * Locate an image descriptor given an interned path, adding a fresh - * descriptor to the cache if necessary. This function also finds a - * suitable name for this image's sample file. - * - * We defer filling in the file format specific parts of the image - * structure till the time we actually see a sample that would fall - * into this image. - */ - -static struct pmcstat_image * -pmcstat_image_from_path(pmcstat_interned_string internedpath, - int iskernelmodule) -{ - int hash; - struct pmcstat_image *pi; - - hash = pmcstat_string_lookup_hash(internedpath); - - /* First, look for an existing entry. */ - LIST_FOREACH(pi, &pmcstat_image_hash[hash], pi_next) - if (pi->pi_execpath == internedpath && - pi->pi_iskernelmodule == iskernelmodule) - return (pi); - - /* - * Allocate a new entry and place it at the head of the hash - * and LRU lists. - */ - pi = malloc(sizeof(*pi)); - if (pi == NULL) - return (NULL); - - pi->pi_type = PMCSTAT_IMAGE_UNKNOWN; - pi->pi_execpath = internedpath; - pi->pi_start = ~0; - pi->pi_end = 0; - pi->pi_entry = 0; - pi->pi_vaddr = 0; - pi->pi_isdynamic = 0; - pi->pi_iskernelmodule = iskernelmodule; - pi->pi_dynlinkerpath = NULL; - pi->pi_symbols = NULL; - pi->pi_symcount = 0; - pi->pi_addr2line = NULL; - - if (plugins[args.pa_pplugin].pl_initimage != NULL) - plugins[args.pa_pplugin].pl_initimage(pi); - if (plugins[args.pa_plugin].pl_initimage != NULL) - plugins[args.pa_plugin].pl_initimage(pi); - - LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next); - - return (pi); -} - -/* - * Record the fact that PC values from 'start' to 'end' come from - * image 'image'. - */ - -static void -pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image, - uintfptr_t start) -{ - struct pmcstat_pcmap *pcm, *pcmnew; - uintfptr_t offset; - - assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN && - image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE); - - if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL) - err(EX_OSERR, "ERROR: Cannot create a map entry"); - - /* - * Adjust the map entry to only cover the text portion - * of the object. - */ - - offset = start - image->pi_vaddr; - pcmnew->ppm_lowpc = image->pi_start + offset; - pcmnew->ppm_highpc = image->pi_end + offset; - pcmnew->ppm_image = image; - - assert(pcmnew->ppm_lowpc < pcmnew->ppm_highpc); - - /* Overlapped mmap()'s are assumed to never occur. */ - TAILQ_FOREACH(pcm, &pp->pp_map, ppm_next) - if (pcm->ppm_lowpc >= pcmnew->ppm_highpc) - break; - - if (pcm == NULL) - TAILQ_INSERT_TAIL(&pp->pp_map, pcmnew, ppm_next); - else - TAILQ_INSERT_BEFORE(pcm, pcmnew, ppm_next); -} - -/* - * Unmap images in the range [start..end) associated with process - * 'pp'. - */ - -static void -pmcstat_image_unmap(struct pmcstat_process *pp, uintfptr_t start, - uintfptr_t end) -{ - struct pmcstat_pcmap *pcm, *pcmtmp, *pcmnew; - - assert(pp != NULL); - assert(start < end); - - /* - * Cases: - * - we could have the range completely in the middle of an - * existing pcmap; in this case we have to split the pcmap - * structure into two (i.e., generate a 'hole'). - * - we could have the range covering multiple pcmaps; these - * will have to be removed. - * - we could have either 'start' or 'end' falling in the - * middle of a pcmap; in this case shorten the entry. - */ - TAILQ_FOREACH_SAFE(pcm, &pp->pp_map, ppm_next, pcmtmp) { - assert(pcm->ppm_lowpc < pcm->ppm_highpc); - if (pcm->ppm_highpc <= start) - continue; - if (pcm->ppm_lowpc >= end) - return; - if (pcm->ppm_lowpc >= start && pcm->ppm_highpc <= end) { - /* - * The current pcmap is completely inside the - * unmapped range: remove it entirely. - */ - TAILQ_REMOVE(&pp->pp_map, pcm, ppm_next); - free(pcm); - } else if (pcm->ppm_lowpc < start && pcm->ppm_highpc > end) { - /* - * Split this pcmap into two; curtail the - * current map to end at [start-1], and start - * the new one at [end]. - */ - if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL) - err(EX_OSERR, - "ERROR: Cannot split a map entry"); - - pcmnew->ppm_image = pcm->ppm_image; - - pcmnew->ppm_lowpc = end; - pcmnew->ppm_highpc = pcm->ppm_highpc; - - pcm->ppm_highpc = start; - - TAILQ_INSERT_AFTER(&pp->pp_map, pcm, pcmnew, ppm_next); - - return; - } else if (pcm->ppm_lowpc < start && pcm->ppm_highpc <= end) - pcm->ppm_highpc = start; - else if (pcm->ppm_lowpc >= start && pcm->ppm_highpc > end) - pcm->ppm_lowpc = end; - else - assert(0); - } -} - /* * Resolve file name and line number for the given address. */ @@ -1046,46 +320,6 @@ pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr, return (1); } -/* - * Add a {pmcid,name} mapping. - */ - -static void -pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps) -{ - struct pmcstat_pmcrecord *pr, *prm; - - /* Replace an existing name for the PMC. */ - prm = NULL; - LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) - if (pr->pr_pmcid == pmcid) { - pr->pr_pmcname = ps; - return; - } else if (pr->pr_pmcname == ps) - prm = pr; - - /* - * Otherwise, allocate a new descriptor and call the - * plugins hook. - */ - if ((pr = malloc(sizeof(*pr))) == NULL) - err(EX_OSERR, "ERROR: Cannot allocate pmc record"); - - pr->pr_pmcid = pmcid; - pr->pr_pmcname = ps; - pr->pr_pmcin = pmcstat_npmcs++; - pr->pr_samples = 0; - pr->pr_dubious_frames = 0; - pr->pr_merge = prm == NULL ? pr : prm; - - LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next); - - if (plugins[args.pa_pplugin].pl_newpmc != NULL) - plugins[args.pa_pplugin].pl_newpmc(ps, pr); - if (plugins[args.pa_plugin].pl_newpmc != NULL) - plugins[args.pa_plugin].pl_newpmc(ps, pr); -} - /* * Given a pmcid in use, find its human-readable name. */ @@ -1134,486 +368,6 @@ pmcstat_pmcindex_to_pmcr(int pmcin) return NULL; } -/* - * Get PMC record by id, apply merge policy. - */ - -static struct pmcstat_pmcrecord * -pmcstat_lookup_pmcid(pmc_id_t pmcid) -{ - struct pmcstat_pmcrecord *pr; - - LIST_FOREACH(pr, &pmcstat_pmcs, pr_next) { - if (pr->pr_pmcid == pmcid) { - if (pmcstat_mergepmc) - return pr->pr_merge; - return pr; - } - } - - return NULL; -} - -/* - * Associate an AOUT image with a process. - */ - -static void -pmcstat_process_aout_exec(struct pmcstat_process *pp, - struct pmcstat_image *image, uintfptr_t entryaddr) -{ - (void) pp; - (void) image; - (void) entryaddr; - /* TODO Implement a.out handling */ -} - -/* - * Associate an ELF image with a process. - */ - -static void -pmcstat_process_elf_exec(struct pmcstat_process *pp, - struct pmcstat_image *image, uintfptr_t entryaddr) -{ - uintmax_t libstart; - struct pmcstat_image *rtldimage; - - assert(image->pi_type == PMCSTAT_IMAGE_ELF32 || - image->pi_type == PMCSTAT_IMAGE_ELF64); - - /* Create a map entry for the base executable. */ - pmcstat_image_link(pp, image, image->pi_vaddr); - - /* - * For dynamically linked executables we need to determine - * where the dynamic linker was mapped to for this process, - * Subsequent executable objects that are mapped in by the - * dynamic linker will be tracked by log events of type - * PMCLOG_TYPE_MAP_IN. - */ - - if (image->pi_isdynamic) { - - /* - * The runtime loader gets loaded just after the maximum - * possible heap address. Like so: - * - * [ TEXT DATA BSS HEAP -->*RTLD SHLIBS <--STACK] - * ^ ^ - * 0 VM_MAXUSER_ADDRESS - - * - * The exact address where the loader gets mapped in - * will vary according to the size of the executable - * and the limits on the size of the process'es data - * segment at the time of exec(). The entry address - * recorded at process exec time corresponds to the - * 'start' address inside the dynamic linker. From - * this we can figure out the address where the - * runtime loader's file object had been mapped to. - */ - rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath, 0); - if (rtldimage == NULL) { - warnx("WARNING: Cannot find image for \"%s\".", - pmcstat_string_unintern(image->pi_dynlinkerpath)); - pmcstat_stats.ps_exec_errors++; - return; - } - - if (rtldimage->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_get_elf_params(rtldimage); - - if (rtldimage->pi_type != PMCSTAT_IMAGE_ELF32 && - rtldimage->pi_type != PMCSTAT_IMAGE_ELF64) { - warnx("WARNING: rtld not an ELF object \"%s\".", - pmcstat_string_unintern(image->pi_dynlinkerpath)); - return; - } - - libstart = entryaddr - rtldimage->pi_entry; - pmcstat_image_link(pp, rtldimage, libstart); - } -} - -/* - * Find the process descriptor corresponding to a PID. If 'allocate' - * is zero, we return a NULL if a pid descriptor could not be found or - * a process descriptor process. If 'allocate' is non-zero, then we - * will attempt to allocate a fresh process descriptor. Zombie - * process descriptors are only removed if a fresh allocation for the - * same PID is requested. - */ - -static struct pmcstat_process * -pmcstat_process_lookup(pid_t pid, int allocate) -{ - uint32_t hash; - struct pmcstat_pcmap *ppm, *ppmtmp; - struct pmcstat_process *pp, *pptmp; - - hash = (uint32_t) pid & PMCSTAT_HASH_MASK; /* simplicity wins */ - - LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[hash], pp_next, pptmp) - if (pp->pp_pid == pid) { - /* Found a descriptor, check and process zombies */ - if (allocate && pp->pp_isactive == 0) { - /* remove maps */ - TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, - ppmtmp) { - TAILQ_REMOVE(&pp->pp_map, ppm, - ppm_next); - free(ppm); - } - /* remove process entry */ - LIST_REMOVE(pp, pp_next); - free(pp); - break; - } - return (pp); - } - - if (!allocate) - return (NULL); - - if ((pp = malloc(sizeof(*pp))) == NULL) - err(EX_OSERR, "ERROR: Cannot allocate pid descriptor"); - - pp->pp_pid = pid; - pp->pp_isactive = 1; - - TAILQ_INIT(&pp->pp_map); - - LIST_INSERT_HEAD(&pmcstat_process_hash[hash], pp, pp_next); - return (pp); -} - -/* - * Associate an image and a process. - */ - -static void -pmcstat_process_exec(struct pmcstat_process *pp, - pmcstat_interned_string path, uintfptr_t entryaddr) -{ - struct pmcstat_image *image; - - if ((image = pmcstat_image_from_path(path, 0)) == NULL) { - pmcstat_stats.ps_exec_errors++; - return; - } - - if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_determine_type(image); - - assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN); - - switch (image->pi_type) { - case PMCSTAT_IMAGE_ELF32: - case PMCSTAT_IMAGE_ELF64: - pmcstat_stats.ps_exec_elf++; - pmcstat_process_elf_exec(pp, image, entryaddr); - break; - - case PMCSTAT_IMAGE_AOUT: - pmcstat_stats.ps_exec_aout++; - pmcstat_process_aout_exec(pp, image, entryaddr); - break; - - case PMCSTAT_IMAGE_INDETERMINABLE: - pmcstat_stats.ps_exec_indeterminable++; - break; - - default: - err(EX_SOFTWARE, - "ERROR: Unsupported executable type for \"%s\"", - pmcstat_string_unintern(path)); - } -} - - -/* - * Find the map entry associated with process 'p' at PC value 'pc'. - */ - -struct pmcstat_pcmap * -pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc) -{ - struct pmcstat_pcmap *ppm; - - TAILQ_FOREACH(ppm, &p->pp_map, ppm_next) { - if (pc >= ppm->ppm_lowpc && pc < ppm->ppm_highpc) - return (ppm); - if (pc < ppm->ppm_lowpc) - return (NULL); - } - - return (NULL); -} - -/* - * Convert a hwpmc(4) log to profile information. A system-wide - * callgraph is generated if FLAG_DO_CALLGRAPHS is set. gmon.out - * files usable by gprof(1) are created if FLAG_DO_GPROF is set. - */ -static int -pmcstat_analyze_log(void) -{ - uint32_t cpu, cpuflags; - uintfptr_t pc; - pid_t pid; - struct pmcstat_image *image; - struct pmcstat_process *pp, *ppnew; - struct pmcstat_pcmap *ppm, *ppmtmp; - struct pmclog_ev ev; - struct pmcstat_pmcrecord *pmcr; - pmcstat_interned_string image_path; - - assert(args.pa_flags & FLAG_DO_ANALYSIS); - - if (elf_version(EV_CURRENT) == EV_NONE) - err(EX_UNAVAILABLE, "Elf library initialization failed"); - - while (pmclog_read(args.pa_logparser, &ev) == 0) { - assert(ev.pl_state == PMCLOG_OK); - - switch (ev.pl_type) { - case PMCLOG_TYPE_INITIALIZE: - if ((ev.pl_u.pl_i.pl_version & 0xFF000000) != - PMC_VERSION_MAJOR << 24 && args.pa_verbosity > 0) - warnx( -"WARNING: Log version 0x%x does not match compiled version 0x%x.", - ev.pl_u.pl_i.pl_version, PMC_VERSION_MAJOR); - break; - - case PMCLOG_TYPE_MAP_IN: - /* - * Introduce an address range mapping for a - * userland process or the kernel (pid == -1). - * - * We always allocate a process descriptor so - * that subsequent samples seen for this - * address range are mapped to the current - * object being mapped in. - */ - pid = ev.pl_u.pl_mi.pl_pid; - if (pid == -1) - pp = pmcstat_kernproc; - else - pp = pmcstat_process_lookup(pid, - PMCSTAT_ALLOCATE); - - assert(pp != NULL); - - image_path = pmcstat_string_intern(ev.pl_u.pl_mi. - pl_pathname); - image = pmcstat_image_from_path(image_path, pid == -1); - if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) - pmcstat_image_determine_type(image); - if (image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE) - pmcstat_image_link(pp, image, - ev.pl_u.pl_mi.pl_start); - break; - - case PMCLOG_TYPE_MAP_OUT: - /* - * Remove an address map. - */ - pid = ev.pl_u.pl_mo.pl_pid; - if (pid == -1) - pp = pmcstat_kernproc; - else - pp = pmcstat_process_lookup(pid, 0); - - if (pp == NULL) /* unknown process */ - break; - - pmcstat_image_unmap(pp, ev.pl_u.pl_mo.pl_start, - ev.pl_u.pl_mo.pl_end); - break; - - case PMCLOG_TYPE_PCSAMPLE: - /* - * Note: the `PCSAMPLE' log entry is not - * generated by hpwmc(4) after version 2. - */ - - /* - * We bring in the gmon file for the image - * currently associated with the PMC & pid - * pair and increment the appropriate entry - * bin inside this. - */ - pmcstat_stats.ps_samples_total++; - ps_samples_period++; - - pc = ev.pl_u.pl_s.pl_pc; - pp = pmcstat_process_lookup(ev.pl_u.pl_s.pl_pid, - PMCSTAT_ALLOCATE); - - /* Get PMC record. */ - pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_s.pl_pmcid); - assert(pmcr != NULL); - pmcr->pr_samples++; - - /* - * Call the plugins processing - * TODO: move pmcstat_process_find_map inside plugins - */ - - if (plugins[args.pa_pplugin].pl_process != NULL) - plugins[args.pa_pplugin].pl_process( - pp, pmcr, 1, &pc, - pmcstat_process_find_map(pp, pc) != NULL, 0); - plugins[args.pa_plugin].pl_process( - pp, pmcr, 1, &pc, - pmcstat_process_find_map(pp, pc) != NULL, 0); - break; - - case PMCLOG_TYPE_CALLCHAIN: - pmcstat_stats.ps_samples_total++; - ps_samples_period++; - - cpuflags = ev.pl_u.pl_cc.pl_cpuflags; - cpu = PMC_CALLCHAIN_CPUFLAGS_TO_CPU(cpuflags); - - /* Filter on the CPU id. */ - if (!CPU_ISSET(cpu, &(args.pa_cpumask))) { - pmcstat_stats.ps_samples_skipped++; - break; - } - - pp = pmcstat_process_lookup(ev.pl_u.pl_cc.pl_pid, - PMCSTAT_ALLOCATE); - - /* Get PMC record. */ - pmcr = pmcstat_lookup_pmcid(ev.pl_u.pl_cc.pl_pmcid); - assert(pmcr != NULL); - pmcr->pr_samples++; - - /* - * Call the plugins processing - */ - - if (plugins[args.pa_pplugin].pl_process != NULL) - plugins[args.pa_pplugin].pl_process( - pp, pmcr, - ev.pl_u.pl_cc.pl_npc, - ev.pl_u.pl_cc.pl_pc, - PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags), - cpu); - plugins[args.pa_plugin].pl_process( - pp, pmcr, - ev.pl_u.pl_cc.pl_npc, - ev.pl_u.pl_cc.pl_pc, - PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags), - cpu); - break; - - case PMCLOG_TYPE_PMCALLOCATE: - /* - * Record the association pmc id between this - * PMC and its name. - */ - pmcstat_pmcid_add(ev.pl_u.pl_a.pl_pmcid, - pmcstat_string_intern(ev.pl_u.pl_a.pl_evname)); - break; - - case PMCLOG_TYPE_PMCALLOCATEDYN: - /* - * Record the association pmc id between this - * PMC and its name. - */ - pmcstat_pmcid_add(ev.pl_u.pl_ad.pl_pmcid, - pmcstat_string_intern(ev.pl_u.pl_ad.pl_evname)); - break; - - case PMCLOG_TYPE_PROCEXEC: - - /* - * Change the executable image associated with - * a process. - */ - pp = pmcstat_process_lookup(ev.pl_u.pl_x.pl_pid, - PMCSTAT_ALLOCATE); - - /* delete the current process map */ - TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, ppmtmp) { - TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next); - free(ppm); - } - - /* - * Associate this process image. - */ - image_path = pmcstat_string_intern( - ev.pl_u.pl_x.pl_pathname); - assert(image_path != NULL); - pmcstat_process_exec(pp, image_path, - ev.pl_u.pl_x.pl_entryaddr); - break; - - case PMCLOG_TYPE_PROCEXIT: - - /* - * Due to the way the log is generated, the - * last few samples corresponding to a process - * may appear in the log after the process - * exit event is recorded. Thus we keep the - * process' descriptor and associated data - * structures around, but mark the process as - * having exited. - */ - pp = pmcstat_process_lookup(ev.pl_u.pl_e.pl_pid, 0); - if (pp == NULL) - break; - pp->pp_isactive = 0; /* mark as a zombie */ - break; - - case PMCLOG_TYPE_SYSEXIT: - pp = pmcstat_process_lookup(ev.pl_u.pl_se.pl_pid, 0); - if (pp == NULL) - break; - pp->pp_isactive = 0; /* make a zombie */ - break; - - case PMCLOG_TYPE_PROCFORK: - - /* - * Allocate a process descriptor for the new - * (child) process. - */ - ppnew = - pmcstat_process_lookup(ev.pl_u.pl_f.pl_newpid, - PMCSTAT_ALLOCATE); - - /* - * If we had been tracking the parent, clone - * its address maps. - */ - pp = pmcstat_process_lookup(ev.pl_u.pl_f.pl_oldpid, 0); - if (pp == NULL) - break; - TAILQ_FOREACH(ppm, &pp->pp_map, ppm_next) - pmcstat_image_link(ppnew, ppm->ppm_image, - ppm->ppm_lowpc); - break; - - default: /* other types of entries are not relevant */ - break; - } - } - - if (ev.pl_state == PMCLOG_EOF) - return (PMCSTAT_FINISHED); - else if (ev.pl_state == PMCLOG_REQUIRE_DATA) - return (PMCSTAT_RUNNING); - - err(EX_DATAERR, - "ERROR: event parsing failed (record %jd, offset 0x%jx)", - (uintmax_t) ev.pl_count + 1, ev.pl_offset); -} - /* * Print log entries as text. */ @@ -1737,7 +491,7 @@ pmcstat_print_log(void) if (ev.pl_state == PMCLOG_EOF) return (PMCSTAT_FINISHED); - else if (ev.pl_state == PMCLOG_REQUIRE_DATA) + else if (ev.pl_state == PMCLOG_REQUIRE_DATA) return (PMCSTAT_RUNNING); errx(EX_DATAERR, @@ -1750,131 +504,6 @@ pmcstat_print_log(void) * Public Interfaces. */ -/* - * Close a logfile, after first flushing all in-module queued data. - */ - -int -pmcstat_close_log(void) -{ - /* If a local logfile is configured ask the kernel to stop - * and flush data. Kernel will close the file when data is flushed - * so keep the status to EXITING. - */ - if (args.pa_logfd != -1) { - if (pmc_close_logfile() < 0) - err(EX_OSERR, "ERROR: logging failed"); - } - - return (args.pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING : - PMCSTAT_FINISHED); -} - - - -/* - * Open a log file, for reading or writing. - * - * The function returns the fd of a successfully opened log or -1 in - * case of failure. - */ - -int -pmcstat_open_log(const char *path, int mode) -{ - int error, fd, cfd; - size_t hlen; - const char *p, *errstr; - struct addrinfo hints, *res, *res0; - char hostname[MAXHOSTNAMELEN]; - - errstr = NULL; - fd = -1; - - /* - * If 'path' is "-" then open one of stdin or stdout depending - * on the value of 'mode'. - * - * If 'path' contains a ':' and does not start with a '/' or '.', - * and is being opened for writing, treat it as a "host:port" - * specification and open a network socket. - * - * Otherwise, treat 'path' as a file name and open that. - */ - if (path[0] == '-' && path[1] == '\0') - fd = (mode == PMCSTAT_OPEN_FOR_READ) ? 0 : 1; - else if (path[0] != '/' && - path[0] != '.' && strchr(path, ':') != NULL) { - - p = strrchr(path, ':'); - hlen = p - path; - if (p == path || hlen >= sizeof(hostname)) { - errstr = strerror(EINVAL); - goto done; - } - - assert(hlen < sizeof(hostname)); - (void) strncpy(hostname, path, hlen); - hostname[hlen] = '\0'; - - (void) memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - if ((error = getaddrinfo(hostname, p+1, &hints, &res0)) != 0) { - errstr = gai_strerror(error); - goto done; - } - - fd = -1; - for (res = res0; res; res = res->ai_next) { - if ((fd = socket(res->ai_family, res->ai_socktype, - res->ai_protocol)) < 0) { - errstr = strerror(errno); - continue; - } - if (mode == PMCSTAT_OPEN_FOR_READ) { - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { - errstr = strerror(errno); - (void) close(fd); - fd = -1; - continue; - } - listen(fd, 1); - cfd = accept(fd, NULL, NULL); - (void) close(fd); - if (cfd < 0) { - errstr = strerror(errno); - fd = -1; - break; - } - fd = cfd; - } else { - if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - errstr = strerror(errno); - (void) close(fd); - fd = -1; - continue; - } - } - errstr = NULL; - break; - } - freeaddrinfo(res0); - - } else if ((fd = open(path, mode == PMCSTAT_OPEN_FOR_READ ? - O_RDONLY : (O_WRONLY|O_CREAT|O_TRUNC), - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) - errstr = strerror(errno); - - done: - if (errstr) - errx(EX_OSERR, "ERROR: Cannot open \"%s\" for %s: %s.", path, - (mode == PMCSTAT_OPEN_FOR_READ ? "reading" : "writing"), - errstr); - - return (fd); -} - /* * Process a log file in offline analysis mode. */ @@ -1890,7 +519,8 @@ pmcstat_process_log(void) if (args.pa_flags & FLAG_DO_PRINT) return (pmcstat_print_log()); else - return (pmcstat_analyze_log()); + return (pmcstat_analyze_log(&args, plugins, &pmcstat_stats, pmcstat_kernproc, + pmcstat_mergepmc, &pmcstat_npmcs, &ps_samples_period)); } /* @@ -2052,7 +682,7 @@ pmcstat_keypress_log(void) break; default: if (plugins[args.pa_plugin].pl_topkeypress != NULL) - if (plugins[args.pa_plugin].pl_topkeypress(c, w)) + if (plugins[args.pa_plugin].pl_topkeypress(c, (void *)w)) ret = 1; } @@ -2080,7 +710,6 @@ pmcstat_display_log(void) if (plugins[args.pa_plugin].pl_init != NULL) plugins[args.pa_plugin].pl_init(); } - } /* @@ -2102,137 +731,17 @@ pmcstat_pluginconfigure_log(char *opt) } } -/* - * Initialize module. - */ - void -pmcstat_initialize_logging(void) +pmcstat_log_shutdown_logging(void) { - int i; - /* use a convenient format for 'ldd' output */ - if (setenv("LD_TRACE_LOADED_OBJECTS_FMT1","%o \"%p\" %x\n",1) != 0) - err(EX_OSERR, "ERROR: Cannot setenv"); - - /* Initialize hash tables */ - pmcstat_string_initialize(); - for (i = 0; i < PMCSTAT_NHASH; i++) { - LIST_INIT(&pmcstat_image_hash[i]); - LIST_INIT(&pmcstat_process_hash[i]); - } - - /* - * Create a fake 'process' entry for the kernel with pid -1. - * hwpmc(4) will subsequently inform us about where the kernel - * and any loaded kernel modules are mapped. - */ - if ((pmcstat_kernproc = pmcstat_process_lookup((pid_t) -1, - PMCSTAT_ALLOCATE)) == NULL) - err(EX_OSERR, "ERROR: Cannot initialize logging"); - - /* PMC count. */ - pmcstat_npmcs = 0; - - /* Merge PMC with same name. */ - pmcstat_mergepmc = args.pa_mergepmc; - - /* - * Initialize plugins - */ - - if (plugins[args.pa_pplugin].pl_init != NULL) - plugins[args.pa_pplugin].pl_init(); - if (plugins[args.pa_plugin].pl_init != NULL) - plugins[args.pa_plugin].pl_init(); + pmcstat_shutdown_logging(&args, plugins, &pmcstat_stats); } -/* - * Shutdown module. - */ - void -pmcstat_shutdown_logging(void) +pmcstat_log_initialize_logging(void) { - int i; - FILE *mf; - struct pmcstat_image *pi, *pitmp; - struct pmcstat_process *pp, *pptmp; - struct pmcstat_pcmap *ppm, *ppmtmp; - /* determine where to send the map file */ - mf = NULL; - if (args.pa_mapfilename != NULL) - mf = (strcmp(args.pa_mapfilename, "-") == 0) ? - args.pa_printfile : fopen(args.pa_mapfilename, "w"); - - if (mf == NULL && args.pa_flags & FLAG_DO_GPROF && - args.pa_verbosity >= 2) - mf = args.pa_printfile; - - if (mf) - (void) fprintf(mf, "MAP:\n"); - - /* - * Shutdown the plugins - */ - - if (plugins[args.pa_plugin].pl_shutdown != NULL) - plugins[args.pa_plugin].pl_shutdown(mf); - if (plugins[args.pa_pplugin].pl_shutdown != NULL) - plugins[args.pa_pplugin].pl_shutdown(mf); - - for (i = 0; i < PMCSTAT_NHASH; i++) { - LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next, - pitmp) { - if (plugins[args.pa_plugin].pl_shutdownimage != NULL) - plugins[args.pa_plugin].pl_shutdownimage(pi); - if (plugins[args.pa_pplugin].pl_shutdownimage != NULL) - plugins[args.pa_pplugin].pl_shutdownimage(pi); - - free(pi->pi_symbols); - if (pi->pi_addr2line != NULL) - pclose(pi->pi_addr2line); - LIST_REMOVE(pi, pi_next); - free(pi); - } - - LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[i], pp_next, - pptmp) { - TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, ppmtmp) { - TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next); - free(ppm); - } - LIST_REMOVE(pp, pp_next); - free(pp); - } - } - - pmcstat_string_shutdown(); - - /* - * Print errors unless -q was specified. Print all statistics - * if verbosity > 1. - */ -#define PRINT(N,V) do { \ - if (pmcstat_stats.ps_##V || args.pa_verbosity >= 2) \ - (void) fprintf(args.pa_printfile, " %-40s %d\n",\ - N, pmcstat_stats.ps_##V); \ - } while (0) - - if (args.pa_verbosity >= 1 && (args.pa_flags & FLAG_DO_ANALYSIS)) { - (void) fprintf(args.pa_printfile, "CONVERSION STATISTICS:\n"); - PRINT("#exec/a.out", exec_aout); - PRINT("#exec/elf", exec_elf); - PRINT("#exec/unknown", exec_indeterminable); - PRINT("#exec handling errors", exec_errors); - PRINT("#samples/total", samples_total); - PRINT("#samples/unclaimed", samples_unknown_offset); - PRINT("#samples/unknown-object", samples_indeterminable); - PRINT("#samples/unknown-function", samples_unknown_function); - PRINT("#callchain/dubious-frames", callchain_dubious_frames); - } - - if (mf) - (void) fclose(mf); + pmcstat_initialize_logging(&pmcstat_kernproc, + &args, plugins, &pmcstat_npmcs, &pmcstat_mergepmc); } diff --git a/usr.sbin/pmcstat/pmcstat_log.h b/usr.sbin/pmcstat/pmcstat_log.h index 32a22f45063f..fc8d60964ed9 100644 --- a/usr.sbin/pmcstat/pmcstat_log.h +++ b/usr.sbin/pmcstat/pmcstat_log.h @@ -34,142 +34,10 @@ #ifndef _PMCSTAT_LOG_H_ #define _PMCSTAT_LOG_H_ -typedef const void *pmcstat_interned_string; +#include -/* - * A 'pmcstat_process' structure models processes. Each process is - * associated with a set of pmcstat_pcmap structures that map - * addresses inside it to executable objects. This set is implemented - * as a list, kept sorted in ascending order of mapped addresses. - * - * 'pp_pid' holds the pid of the process. When a process exits, the - * 'pp_isactive' field is set to zero, but the process structure is - * not immediately reclaimed because there may still be samples in the - * log for this process. - */ - -struct pmcstat_process { - LIST_ENTRY(pmcstat_process) pp_next; /* hash-next */ - pid_t pp_pid; /* associated pid */ - int pp_isactive; /* whether active */ - uintfptr_t pp_entryaddr; /* entry address */ - TAILQ_HEAD(,pmcstat_pcmap) pp_map; /* address range map */ -}; -extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH]; - -/* - * A 'pmcstat_image' structure describes an executable program on - * disk. 'pi_execpath' is a cookie representing the pathname of - * the executable. 'pi_start' and 'pi_end' are the least and greatest - * virtual addresses for the text segments in the executable. - * 'pi_gmonlist' contains a linked list of gmon.out files associated - * with this image. - */ - -enum pmcstat_image_type { - PMCSTAT_IMAGE_UNKNOWN = 0, /* never looked at the image */ - PMCSTAT_IMAGE_INDETERMINABLE, /* can't tell what the image is */ - PMCSTAT_IMAGE_ELF32, /* ELF 32 bit object */ - PMCSTAT_IMAGE_ELF64, /* ELF 64 bit object */ - PMCSTAT_IMAGE_AOUT /* AOUT object */ -}; - -struct pmcstat_image { - LIST_ENTRY(pmcstat_image) pi_next; /* hash link */ - pmcstat_interned_string pi_execpath; /* cookie */ - pmcstat_interned_string pi_samplename; /* sample path name */ - pmcstat_interned_string pi_fullpath; /* path to FS object */ - pmcstat_interned_string pi_name; /* display name */ - - enum pmcstat_image_type pi_type; /* executable type */ - - /* - * Executables have pi_start and pi_end; these are zero - * for shared libraries. - */ - uintfptr_t pi_start; /* start address (inclusive) */ - uintfptr_t pi_end; /* end address (exclusive) */ - uintfptr_t pi_entry; /* entry address */ - uintfptr_t pi_vaddr; /* virtual address where loaded */ - int pi_isdynamic; /* whether a dynamic object */ - int pi_iskernelmodule; - pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */ - - /* All symbols associated with this object. */ - struct pmcstat_symbol *pi_symbols; - size_t pi_symcount; - - /* Handle to addr2line for this image. */ - FILE *pi_addr2line; - - /* - * Plugins private data - */ - - /* gprof: - * An image can be associated with one or more gmon.out files; - * one per PMC. - */ - LIST_HEAD(,pmcstat_gmonfile) pi_gmlist; -}; -extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH]; - -/* - * A 'pmcstat_pcmap' structure maps a virtual address range to an - * underlying 'pmcstat_image' descriptor. - */ -struct pmcstat_pcmap { - TAILQ_ENTRY(pmcstat_pcmap) ppm_next; - uintfptr_t ppm_lowpc; - uintfptr_t ppm_highpc; - struct pmcstat_image *ppm_image; -}; - -/* - * Each function symbol tracked by pmcstat(8). - */ - -struct pmcstat_symbol { - pmcstat_interned_string ps_name; - uint64_t ps_start; - uint64_t ps_end; -}; - -/* - * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable - * names. - */ - -struct pmcstat_pmcrecord { - LIST_ENTRY(pmcstat_pmcrecord) pr_next; - pmc_id_t pr_pmcid; - int pr_pmcin; - pmcstat_interned_string pr_pmcname; - int pr_samples; - int pr_dubious_frames; - struct pmcstat_pmcrecord *pr_merge; -}; -extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */ - -/* - * Misc. statistics - */ -struct pmcstat_stats { - int ps_exec_aout; /* # a.out executables seen */ - int ps_exec_elf; /* # elf executables seen */ - int ps_exec_errors; /* # errors processing executables */ - int ps_exec_indeterminable; /* # unknown executables seen */ - int ps_samples_total; /* total number of samples processed */ - int ps_samples_skipped; /* #samples filtered out for any reason */ - int ps_samples_unknown_offset; /* #samples of rank 0 not in a map */ - int ps_samples_indeterminable; /* #samples in indeterminable images */ - int ps_samples_unknown_function;/* #samples with unknown function at offset */ - int ps_callchain_dubious_frames;/* #dubious frame pointers seen */ -}; extern struct pmcstat_stats pmcstat_stats; /* statistics */ - extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */ - extern int pmcstat_npmcs; /* PMC count. */ /* @@ -182,17 +50,8 @@ extern int pmcstat_pmcinfilter; /* PMC index displayed. */ const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid); const char *pmcstat_pmcindex_to_name(int pmcin); struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin); -struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p, - uintfptr_t _pc); -struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image, - uintfptr_t addr); -const char *pmcstat_string_unintern(pmcstat_interned_string _is); -pmcstat_interned_string pmcstat_string_intern(const char *_s); -void pmcstat_image_determine_type(struct pmcstat_image *_image); -pmcstat_interned_string pmcstat_string_lookup(const char *_s); int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr, char *sourcefile, size_t sourcefile_len, unsigned *sourceline, char *funcname, size_t funcname_len); #endif /* _PMCSTAT_LOG_H_ */ - diff --git a/usr.sbin/pmcstudy/Makefile.depend b/usr.sbin/pmcstudy/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/pmcstudy/Makefile.depend +++ b/usr.sbin/pmcstudy/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pnpinfo/Makefile.depend b/usr.sbin/pnpinfo/Makefile.depend index 79eb58b4a779..c729e17c52db 100644 --- a/usr.sbin/pnpinfo/Makefile.depend +++ b/usr.sbin/pnpinfo/Makefile.depend @@ -2,7 +2,6 @@ # Autogenerated - do NOT edit! DIRDEPS = \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/portsnap/make_index/Makefile.depend b/usr.sbin/portsnap/make_index/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/portsnap/make_index/Makefile.depend +++ b/usr.sbin/portsnap/make_index/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/portsnap/phttpget/Makefile.depend b/usr.sbin/portsnap/phttpget/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/portsnap/phttpget/Makefile.depend +++ b/usr.sbin/portsnap/phttpget/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/powerd/Makefile.depend b/usr.sbin/powerd/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/powerd/Makefile.depend +++ b/usr.sbin/powerd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ppp/Makefile.depend b/usr.sbin/ppp/Makefile.depend index 250763c553ca..92ea9e3b6910 100644 --- a/usr.sbin/ppp/Makefile.depend +++ b/usr.sbin/ppp/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/ppp/auth.c b/usr.sbin/ppp/auth.c index fbfc9290bcda..f75c2d36f1c8 100644 --- a/usr.sbin/ppp/auth.c +++ b/usr.sbin/ppp/auth.c @@ -125,13 +125,19 @@ auth_CheckPasswd(const char *name, const char *data, const char *key) #ifdef NOPAM /* Then look up the real password database */ struct passwd *pw; - int result; + int result = 0; char *cryptpw; + + pw = getpwnam(name); + + if (pw) { + cryptpw = crypt(key, pw->pw_passwd); + + result = (cryptpw != NULL) && !strcmp(cryptpw, pw->pw_passwd); + } - cryptpw = crypt(key, pw->pw_passwd); - result = (pw = getpwnam(name)) && - (cryptpw == NULL || !strcmp(cryptpw, pw->pw_passwd)); endpwent(); + return result; #else /* !NOPAM */ /* Then consult with PAM. */ diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index 8430bcb2c462..6c3fedc9446d 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -5950,9 +5950,9 @@ to get online information about what is available. The following URLs contain useful information: .Bl -bullet -compact .It -http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/faq/ppp.html +https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/faq/ppp.html .It -http://www.FreeBSD.org/doc/handbook/userppp.html +https://www.FreeBSD.org/doc/handbook/userppp.html .El .El .Sh FILES diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c index 758b40319ec4..643bf0ff55f8 100644 --- a/usr.sbin/ppp/route.c +++ b/usr.sbin/ppp/route.c @@ -801,7 +801,8 @@ rt_Set(struct bundle *bundle, int cmd, const struct ncprange *dst, if (!ncprange_ishost(dst)) { cp += memcpy_roundup(cp, &samask, samask.ss_len); rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; - } + } else + rtmes.m_rtm.rtm_flags |= RTF_HOST; nb = cp - (char *)&rtmes; rtmes.m_rtm.rtm_msglen = nb; @@ -905,7 +906,8 @@ rt_Update(struct bundle *bundle, const struct sockaddr *dst, if (mask) { rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; p += memcpy_roundup(p, mask, mask->sa_len); - } + } else + rtmes.m_rtm.rtm_flags |= RTF_HOST; if (ifa && ifp && ifp->sa_family == AF_LINK) { rtmes.m_rtm.rtm_addrs |= RTA_IFP; diff --git a/usr.sbin/pppctl/Makefile.depend b/usr.sbin/pppctl/Makefile.depend index 93d2803bcd33..199e18875437 100644 --- a/usr.sbin/pppctl/Makefile.depend +++ b/usr.sbin/pppctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/praliases/Makefile.depend b/usr.sbin/praliases/Makefile.depend index b0af42fdb943..0feabbf167e0 100644 --- a/usr.sbin/praliases/Makefile.depend +++ b/usr.sbin/praliases/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/praudit/Makefile.depend b/usr.sbin/praudit/Makefile.depend index 97143a89bccf..2511c90c76b0 100644 --- a/usr.sbin/praudit/Makefile.depend +++ b/usr.sbin/praudit/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/procctl/Makefile b/usr.sbin/procctl/Makefile deleted file mode 100644 index 880b93a13fe0..000000000000 --- a/usr.sbin/procctl/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -PROG= procctl -MAN= procctl.8 - -.include diff --git a/usr.sbin/procctl/procctl.8 b/usr.sbin/procctl/procctl.8 deleted file mode 100644 index 1add286472f4..000000000000 --- a/usr.sbin/procctl/procctl.8 +++ /dev/null @@ -1,34 +0,0 @@ -.\" $FreeBSD$ -.Dd November 23, 1997 -.Dt PROCCTL 8 -.Os -.Sh NAME -.Nm procctl -.Nd clear procfs event flags -.Sh SYNOPSIS -.Nm -.Ar pid ... -.Sh DESCRIPTION -The -.Nm -utility clears the -.Xr procfs 5 -event mask used by -.Xr truss 1 . -This can be used in the event that a process is left stranded, since -the -.Xr procfs 5 -events result in a non-killable process. -The arguments are a list of process IDs; -.Nm -goes through the list and clears the event masks for each specified process. -.Sh SEE ALSO -.Xr truss 1 , -.Xr procfs 5 -.Sh HISTORY -The -.Nm -utility was written by -.An Sean Eric Fagan -for -.Fx . diff --git a/usr.sbin/procctl/procctl.c b/usr.sbin/procctl/procctl.c deleted file mode 100644 index 5bd1f21954c6..000000000000 --- a/usr.sbin/procctl/procctl.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 1997 Sean Eric Fagan - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Sean Eric Fagan - * 4. Neither the name of the author may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 -__FBSDID("$FreeBSD$"); - -/* - * procctl -- clear the event mask, and continue, any specified processes. - * This is largely an example of how to use the procfs interface; however, - * for now, it is also sometimes necessary, as a stopped process will not - * otherwise continue. (This will be fixed in a later version of the - * procfs code, almost certainly; however, this program will still be useful - * for some annoying circumstances.) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int -main(int ac, char **av) { - int fd; - int i; - - for (i = 1; i < ac; i++) { - char buf[32]; - - snprintf(buf, sizeof(buf), "/proc/%s/mem", av[i]); - fd = open(buf, O_RDWR); - if (fd == -1) { - if (errno == ENOENT) - continue; - warn("cannot open pid %s", av[i]); - continue; - } - if (ioctl(fd, PIOCBIC, ~0) == -1) - warn("cannot clear process %s's event mask", av[i]); - if (ioctl(fd, PIOCCONT, 0) == -1 && errno != EINVAL) - warn("cannot continue process %s", av[i]); - close(fd); - } - return 0; -} diff --git a/usr.sbin/prometheus_sysctl_exporter/Makefile.depend b/usr.sbin/prometheus_sysctl_exporter/Makefile.depend index 411ae145c7fc..5ed09d7880db 100644 --- a/usr.sbin/prometheus_sysctl_exporter/Makefile.depend +++ b/usr.sbin/prometheus_sysctl_exporter/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pstat/Makefile.depend b/usr.sbin/pstat/Makefile.depend index 7c356c962d78..1487255a4257 100644 --- a/usr.sbin/pstat/Makefile.depend +++ b/usr.sbin/pstat/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pw/Makefile.depend b/usr.sbin/pw/Makefile.depend index 392fb607a95a..f746d7af1b21 100644 --- a/usr.sbin/pw/Makefile.depend +++ b/usr.sbin/pw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/pw/tests/Makefile.depend b/usr.sbin/pw/tests/Makefile.depend index aa053cfb4c50..9124664318e7 100644 --- a/usr.sbin/pw/tests/Makefile.depend +++ b/usr.sbin/pw/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ lib/${CSU_DIR} \ lib/libc \ diff --git a/usr.sbin/pwd_mkdb/Makefile.depend b/usr.sbin/pwd_mkdb/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/pwd_mkdb/Makefile.depend +++ b/usr.sbin/pwd_mkdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/quot/Makefile.depend b/usr.sbin/quot/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/quot/Makefile.depend +++ b/usr.sbin/quot/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/quotaon/Makefile.depend b/usr.sbin/quotaon/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/quotaon/Makefile.depend +++ b/usr.sbin/quotaon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/rarpd/Makefile.depend b/usr.sbin/rarpd/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/rarpd/Makefile.depend +++ b/usr.sbin/rarpd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/repquota/Makefile.depend b/usr.sbin/repquota/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/repquota/Makefile.depend +++ b/usr.sbin/repquota/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/rip6query/Makefile.depend b/usr.sbin/rip6query/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/rip6query/Makefile.depend +++ b/usr.sbin/rip6query/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rmt/Makefile.depend b/usr.sbin/rmt/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/rmt/Makefile.depend +++ b/usr.sbin/rmt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/route6d/Makefile.depend b/usr.sbin/route6d/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/route6d/Makefile.depend +++ b/usr.sbin/route6d/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rpc.lockd/Makefile.depend b/usr.sbin/rpc.lockd/Makefile.depend index b3a9fa611a20..8939901b94fd 100644 --- a/usr.sbin/rpc.lockd/Makefile.depend +++ b/usr.sbin/rpc.lockd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rpc.statd/Makefile.depend b/usr.sbin/rpc.statd/Makefile.depend index bdd7bc273d10..572fc8dbf41a 100644 --- a/usr.sbin/rpc.statd/Makefile.depend +++ b/usr.sbin/rpc.statd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rpc.umntall/Makefile.depend b/usr.sbin/rpc.umntall/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.sbin/rpc.umntall/Makefile.depend +++ b/usr.sbin/rpc.umntall/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/rpc.yppasswdd/Makefile.depend b/usr.sbin/rpc.yppasswdd/Makefile.depend index 669b7c81d737..f4474e3dffda 100644 --- a/usr.sbin/rpc.yppasswdd/Makefile.depend +++ b/usr.sbin/rpc.yppasswdd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rpc.ypupdated/Makefile.depend b/usr.sbin/rpc.ypupdated/Makefile.depend index c8383bd76e80..5b0587ae477a 100644 --- a/usr.sbin/rpc.ypupdated/Makefile.depend +++ b/usr.sbin/rpc.ypupdated/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/rpc.ypxfrd/Makefile.depend b/usr.sbin/rpc.ypxfrd/Makefile.depend index bdd7bc273d10..572fc8dbf41a 100644 --- a/usr.sbin/rpc.ypxfrd/Makefile.depend +++ b/usr.sbin/rpc.ypxfrd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rpcbind/Makefile.depend b/usr.sbin/rpcbind/Makefile.depend index 0944291fc98f..93dc35867c19 100644 --- a/usr.sbin/rpcbind/Makefile.depend +++ b/usr.sbin/rpcbind/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rpcbind/tests/Makefile.depend b/usr.sbin/rpcbind/tests/Makefile.depend index 4d038059d9d9..d313b17d4486 100644 --- a/usr.sbin/rpcbind/tests/Makefile.depend +++ b/usr.sbin/rpcbind/tests/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/rrenumd/Makefile.depend b/usr.sbin/rrenumd/Makefile.depend index 88d8cebda9cf..ca3301c271b9 100644 --- a/usr.sbin/rrenumd/Makefile.depend +++ b/usr.sbin/rrenumd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rtadvctl/Makefile.depend b/usr.sbin/rtadvctl/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/rtadvctl/Makefile.depend +++ b/usr.sbin/rtadvctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rtadvd/Makefile.depend b/usr.sbin/rtadvd/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/rtadvd/Makefile.depend +++ b/usr.sbin/rtadvd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rtprio/Makefile.depend b/usr.sbin/rtprio/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/rtprio/Makefile.depend +++ b/usr.sbin/rtprio/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/rtsold/Makefile.depend b/usr.sbin/rtsold/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/rtsold/Makefile.depend +++ b/usr.sbin/rtsold/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/rwhod/Makefile.depend b/usr.sbin/rwhod/Makefile.depend index e77ca8db1787..782b0d5c171e 100644 --- a/usr.sbin/rwhod/Makefile.depend +++ b/usr.sbin/rwhod/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/usr.sbin/rwhod/rwhod.8 b/usr.sbin/rwhod/rwhod.8 index 3124d8781c86..aa9b00e9c158 100644 --- a/usr.sbin/rwhod/rwhod.8 +++ b/usr.sbin/rwhod/rwhod.8 @@ -28,7 +28,7 @@ .\" @(#)rwhod.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd July 3, 2017 +.Dd August 8, 2017 .Dt RWHOD 8 .Os .Sh NAME diff --git a/usr.sbin/sa/Makefile.depend b/usr.sbin/sa/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/sa/Makefile.depend +++ b/usr.sbin/sa/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/sendmail/Makefile.depend b/usr.sbin/sendmail/Makefile.depend index c734c3b63832..24c42b3d8aaa 100644 --- a/usr.sbin/sendmail/Makefile.depend +++ b/usr.sbin/sendmail/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpcsvc \ diff --git a/usr.sbin/services_mkdb/Makefile.depend b/usr.sbin/services_mkdb/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/services_mkdb/Makefile.depend +++ b/usr.sbin/services_mkdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/sesutil/Makefile.depend b/usr.sbin/sesutil/Makefile.depend index 137678c21e46..5770a091f2a6 100644 --- a/usr.sbin/sesutil/Makefile.depend +++ b/usr.sbin/sesutil/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/setfib/Makefile.depend b/usr.sbin/setfib/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/setfib/Makefile.depend +++ b/usr.sbin/setfib/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/setfmac/Makefile.depend b/usr.sbin/setfmac/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/setfmac/Makefile.depend +++ b/usr.sbin/setfmac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/setpmac/Makefile.depend b/usr.sbin/setpmac/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/setpmac/Makefile.depend +++ b/usr.sbin/setpmac/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/smbmsg/Makefile.depend b/usr.sbin/smbmsg/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/smbmsg/Makefile.depend +++ b/usr.sbin/smbmsg/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/snapinfo/Makefile.depend b/usr.sbin/snapinfo/Makefile.depend index 99cf113eba55..735bf03b75b6 100644 --- a/usr.sbin/snapinfo/Makefile.depend +++ b/usr.sbin/snapinfo/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/spray/Makefile.depend b/usr.sbin/spray/Makefile.depend index c8383bd76e80..5b0587ae477a 100644 --- a/usr.sbin/spray/Makefile.depend +++ b/usr.sbin/spray/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/syslogd/Makefile.depend b/usr.sbin/syslogd/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/syslogd/Makefile.depend +++ b/usr.sbin/syslogd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/tcpdchk/Makefile.depend b/usr.sbin/tcpdchk/Makefile.depend index e314de58e956..8af4779ea996 100644 --- a/usr.sbin/tcpdchk/Makefile.depend +++ b/usr.sbin/tcpdchk/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/tcpdmatch/Makefile.depend b/usr.sbin/tcpdmatch/Makefile.depend index e314de58e956..8af4779ea996 100644 --- a/usr.sbin/tcpdmatch/Makefile.depend +++ b/usr.sbin/tcpdmatch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/tcpdrop/Makefile.depend b/usr.sbin/tcpdrop/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/tcpdrop/Makefile.depend +++ b/usr.sbin/tcpdrop/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/tcpdrop/tcpdrop.8 b/usr.sbin/tcpdrop/tcpdrop.8 index 3f3fa0c9cc8e..1f0c75b9674a 100644 --- a/usr.sbin/tcpdrop/tcpdrop.8 +++ b/usr.sbin/tcpdrop/tcpdrop.8 @@ -17,7 +17,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 12, 2017 +.Dd September 15, 2017 .Dt TCPDROP 8 .Os .Sh NAME @@ -78,6 +78,26 @@ is one of .Dv FIN_WAIT_2 , or .Dv TIME_WAIT . .Pp +If +.Fl S Ar stack +and +.Fl s Ar state +are specified, +.Nm +will attempt to drop all TCP connections being in the state +.Ar state +and using the TCP stack +.Ar stack . +Since TCP connections in the +.Dv TIME_WAIT +state are not tied to any TCP stack, using the option +.Fl s Dv TIME_WAIT +in combination with the +.Fl S Ar stack +option results in +.Nm +not dropping any TCP connection. +.Pp The .Fl l flag may be given in addition to the @@ -152,7 +172,9 @@ LAST_ACK state use: .Ed .Sh SEE ALSO .Xr netstat 1 , -.Xr sockstat 1 +.Xr sockstat 1 , +.Xr tcp 4 , +.Xr tcp_functions 9 .Sh AUTHORS .An Markus Friedl Aq Mt markus@openbsd.org .An Juli Mallett Aq Mt jmallett@FreeBSD.org diff --git a/usr.sbin/tcpdump/tcpdump/Makefile b/usr.sbin/tcpdump/tcpdump/Makefile index 9872cbe319c8..8f6f47754b4d 100644 --- a/usr.sbin/tcpdump/tcpdump/Makefile +++ b/usr.sbin/tcpdump/tcpdump/Makefile @@ -173,7 +173,7 @@ SRCS= addrtoname.c \ tcpdump.c \ util-print.c \ version.c -CLEANFILES+= version.c +CLEANFILES+= version.c ${MAN} CFLAGS+= -I${.CURDIR} -I${TCPDUMP_DISTDIR} CFLAGS+= -DHAVE_CONFIG_H @@ -210,3 +210,9 @@ version.c: ${TCPDUMP_DISTDIR}/VERSION > version.c .include + +.for mp in ${MAN} +${mp}: ${mp}.in + sed -e 's/@MAN_MISC_INFO@/7/g' -e 's/@MAN_FILE_FORMATS@/5/g' \ + ${.ALLSRC} > ${.TARGET} +.endfor diff --git a/usr.sbin/tcpdump/tcpdump/Makefile.depend b/usr.sbin/tcpdump/tcpdump/Makefile.depend index cce87b47f747..ae39c732c3b9 100644 --- a/usr.sbin/tcpdump/tcpdump/Makefile.depend +++ b/usr.sbin/tcpdump/tcpdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/tcpdump/tcpdump/tcpdump.1 b/usr.sbin/tcpdump/tcpdump/tcpdump.1 deleted file mode 100644 index 2a2388c931d0..000000000000 --- a/usr.sbin/tcpdump/tcpdump/tcpdump.1 +++ /dev/null @@ -1,1977 +0,0 @@ -.\" $FreeBSD$ -.\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $ -.\" -.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 -.\" The Regents of the University of California. All rights reserved. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that: (1) source code distributions -.\" retain the above copyright notice and this paragraph in its entirety, (2) -.\" distributions including binary code include the above copyright notice and -.\" this paragraph in its entirety in the documentation or other materials -.\" provided with the distribution, and (3) all advertising materials mentioning -.\" features or use of this software display the following acknowledgement: -.\" ``This product includes software developed by the University of California, -.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of -.\" the University nor the names of its contributors may be used to endorse -.\" or promote products derived from this software without specific prior -.\" written permission. -.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -.\" -.TH TCPDUMP 1 "11 July 2014" -.SH NAME -tcpdump \- dump traffic on a network -.SH SYNOPSIS -.na -.B tcpdump -[ -.B \-AbdDefhHIJKlLnNOpqRStuUvxX# -] [ -.B \-B -.I buffer_size -] -.br -.ti +8 -[ -.B \-c -.I count -] -.br -.ti +8 -[ -.B \-C -.I file_size -] [ -.B \-G -.I rotate_seconds -] [ -.B \-F -.I file -] -.br -.ti +8 -[ -.B \-i -.I interface -] -[ -.B \-j -.I tstamp_type -] -[ -.B \-m -.I module -] -[ -.B \-M -.I secret -] -.br -.ti +8 -[ -.B \-\-number -] -[ -.B \-Q -.I in|out|inout -] -.ti +8 -[ -.B \-r -.I file -] -[ -.B \-V -.I file -] -[ -.B \-s -.I snaplen -] -[ -.B \-T -.I type -] -[ -.B \-w -.I file -] -.br -.ti +8 -[ -.B \-W -.I filecount -] -.br -.ti +8 -[ -.B \-E -.I spi@ipaddr algo:secret,... -] -.br -.ti +8 -[ -.B \-y -.I datalinktype -] -[ -.B \-z -.I postrotate-command -] -[ -.B \-Z -.I user -] -.ti +8 -[ -.BI \-\-time\-stamp\-precision= tstamp_precision -] -.ti +8 -[ -.B \-\-immediate\-mode -] -[ -.B \-\-version -] -.ti +8 -[ -.I expression -] -.br -.ad -.SH DESCRIPTION -.LP -\fITcpdump\fP prints out a description of the contents of packets on a -network interface that match the boolean \fIexpression\fP; the -description is preceded by a time stamp, printed, by default, as hours, -minutes, seconds, and fractions of a second since midnight. It can also -be run with the -.B \-w -flag, which causes it to save the packet data to a file for later -analysis, and/or with the -.B \-r -flag, which causes it to read from a saved packet file rather than to -read packets from a network interface. It can also be run with the -.B \-V -flag, which causes it to read a list of saved packet files. In all cases, -only packets that match -.I expression -will be processed by -.IR tcpdump . -.LP -.I Tcpdump -will, if not run with the -.B \-c -flag, continue capturing packets until it is interrupted by a SIGINT -signal (generated, for example, by typing your interrupt character, -typically control-C) or a SIGTERM signal (typically generated with the -.BR kill (1) -command); if run with the -.B \-c -flag, it will capture packets until it is interrupted by a SIGINT or -SIGTERM signal or the specified number of packets have been processed. -.LP -When -.I tcpdump -finishes capturing packets, it will report counts of: -.IP -packets ``captured'' (this is the number of packets that -.I tcpdump -has received and processed); -.IP -packets ``received by filter'' (the meaning of this depends on the OS on -which you're running -.IR tcpdump , -and possibly on the way the OS was configured - if a filter was -specified on the command line, on some OSes it counts packets regardless -of whether they were matched by the filter expression and, even if they -were matched by the filter expression, regardless of whether -.I tcpdump -has read and processed them yet, on other OSes it counts only packets that were -matched by the filter expression regardless of whether -.I tcpdump -has read and processed them yet, and on other OSes it counts only -packets that were matched by the filter expression and were processed by -.IR tcpdump ); -.IP -packets ``dropped by kernel'' (this is the number of packets that were -dropped, due to a lack of buffer space, by the packet capture mechanism -in the OS on which -.I tcpdump -is running, if the OS reports that information to applications; if not, -it will be reported as 0). -.LP -On platforms that support the SIGINFO signal, such as most BSDs -(including Mac OS X) and Digital/Tru64 UNIX, it will report those counts -when it receives a SIGINFO signal (generated, for example, by typing -your ``status'' character, typically control-T, although on some -platforms, such as Mac OS X, the ``status'' character is not set by -default, so you must set it with -.BR stty (1) -in order to use it) and will continue capturing packets. On platforms that -do not support the SIGINFO signal, the same can be achieved by using the -SIGUSR1 signal. -.LP -Reading packets from a network interface may require that you have -special privileges; see the -.B pcap (3PCAP) -man page for details. Reading a saved packet file doesn't require -special privileges. -.SH OPTIONS -.TP -.B \-A -Print each packet (minus its link level header) in ASCII. Handy for -capturing web pages. -.TP -.B \-b -Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN -notation. -.TP -.BI \-B " buffer_size" -.PD 0 -.TP -.BI \-\-buffer\-size= buffer_size -.PD -Set the operating system capture buffer size to \fIbuffer_size\fP, in -units of KiB (1024 bytes). -.TP -.BI \-c " count" -Exit after receiving \fIcount\fP packets. -.TP -.BI \-C " file_size" -Before writing a raw packet to a savefile, check whether the file is -currently larger than \fIfile_size\fP and, if so, close the current -savefile and open a new one. Savefiles after the first savefile will -have the name specified with the -.B \-w -flag, with a number after it, starting at 1 and continuing upward. -The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, -not 1,048,576 bytes). -.TP -.B \-d -Dump the compiled packet-matching code in a human readable form to -standard output and stop. -.TP -.B \-dd -Dump packet-matching code as a -.B C -program fragment. -.TP -.B \-ddd -Dump packet-matching code as decimal numbers (preceded with a count). -.TP -.B \-D -.PD 0 -.TP -.B \-\-list\-interfaces -.PD -Print the list of the network interfaces available on the system and on -which -.I tcpdump -can capture packets. For each network interface, a number and an -interface name, possibly followed by a text description of the -interface, is printed. The interface name or the number can be supplied -to the -.B \-i -flag to specify an interface on which to capture. -.IP -This can be useful on systems that don't have a command to list them -(e.g., Windows systems, or UNIX systems lacking -.BR "ifconfig \-a" ); -the number can be useful on Windows 2000 and later systems, where the -interface name is a somewhat complex string. -.IP -The -.B \-D -flag will not be supported if -.I tcpdump -was built with an older version of -.I libpcap -that lacks the -.B pcap_findalldevs() -function. -.TP -.B \-e -Print the link-level header on each dump line. This can be used, for -example, to print MAC layer addresses for protocols such as Ethernet and -IEEE 802.11. -.TP -.B \-E -Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that -are addressed to \fIaddr\fP and contain Security Parameter Index value -\fIspi\fP. This combination may be repeated with comma or newline separation. -.IP -Note that setting the secret for IPv4 ESP packets is supported at this time. -.IP -Algorithms may be -\fBdes-cbc\fP, -\fB3des-cbc\fP, -\fBblowfish-cbc\fP, -\fBrc3-cbc\fP, -\fBcast128-cbc\fP, or -\fBnone\fP. -The default is \fBdes-cbc\fP. -The ability to decrypt packets is only present if \fItcpdump\fP was compiled -with cryptography enabled. -.IP -\fIsecret\fP is the ASCII text for ESP secret key. -If preceded by 0x, then a hex value will be read. -.IP -The option assumes RFC2406 ESP, not RFC1827 ESP. -The option is only for debugging purposes, and -the use of this option with a true `secret' key is discouraged. -By presenting IPsec secret key onto command line -you make it visible to others, via -.IR ps (1) -and other occasions. -.IP -In addition to the above syntax, the syntax \fIfile name\fP may be used -to have tcpdump read the provided file in. The file is opened upon -receiving the first ESP packet, so any special permissions that tcpdump -may have been given should already have been given up. -.TP -.B \-f -Print `foreign' IPv4 addresses numerically rather than symbolically -(this option is intended to get around serious brain damage in -Sun's NIS server \(em usually it hangs forever translating non-local -internet numbers). -.IP -The test for `foreign' IPv4 addresses is done using the IPv4 address and -netmask of the interface on which capture is being done. If that -address or netmask are not available, available, either because the -interface on which capture is being done has no address or netmask or -because the capture is being done on the Linux "any" interface, which -can capture on more than one interface, this option will not work -correctly. -.TP -.BI \-F " file" -Use \fIfile\fP as input for the filter expression. -An additional expression given on the command line is ignored. -.TP -.BI \-G " rotate_seconds" -If specified, rotates the dump file specified with the -.B \-w -option every \fIrotate_seconds\fP seconds. -Savefiles will have the name specified by -.B \-w -which should include a time format as defined by -.BR strftime (3). -If no time format is specified, each new file will overwrite the previous. -.IP -If used in conjunction with the -.B \-C -option, filenames will take the form of `\fIfile\fP'. -.TP -.B \-h -.PD 0 -.TP -.B \-\-help -.PD -Print the tcpdump and libpcap version strings, print a usage message, -and exit. -.TP -.B \-\-version -.PD -Print the tcpdump and libpcap version strings and exit. -.TP -.B \-H -Attempt to detect 802.11s draft mesh headers. -.TP -.BI \-i " interface" -.PD 0 -.TP -.BI \-\-interface= interface -.PD -Listen on \fIinterface\fP. -If unspecified, \fItcpdump\fP searches the system interface list for the -lowest numbered, configured up interface (excluding loopback), which may turn -out to be, for example, ``eth0''. -.IP -On Linux systems with 2.2 or later kernels, an -.I interface -argument of ``any'' can be used to capture packets from all interfaces. -Note that captures on the ``any'' device will not be done in promiscuous -mode. -.IP -If the -.B \-D -flag is supported, an interface number as printed by that flag can be -used as the -.I interface -argument. -.TP -.B \-I -.PD 0 -.TP -.B \-\-monitor\-mode -.PD -Put the interface in "monitor mode"; this is supported only on IEEE -802.11 Wi-Fi interfaces, and supported only on some operating systems. -.IP -Note that in monitor mode the adapter might disassociate from the -network with which it's associated, so that you will not be able to use -any wireless networks with that adapter. This could prevent accessing -files on a network server, or resolving host names or network addresses, -if you are capturing in monitor mode and are not connected to another -network with another adapter. -.IP -This flag will affect the output of the -.B \-L -flag. If -.B \-I -isn't specified, only those link-layer types available when not in -monitor mode will be shown; if -.B \-I -is specified, only those link-layer types available when in monitor mode -will be shown. -.TP -.BI \-\-immediate\-mode -Capture in "immediate mode". In this mode, packets are delivered to -tcpdump as soon as they arrive, rather than being buffered for -efficiency. This is the default when printing packets rather than -saving packets to a ``savefile'' if the packets are being printed to a -terminal rather than to a file or pipe. -.TP -.BI \-j " tstamp_type" -.PD 0 -.TP -.BI \-\-time\-stamp\-type= tstamp_type -.PD -Set the time stamp type for the capture to \fItstamp_type\fP. The names -to use for the time stamp types are given in -.BR pcap-tstamp (7); -not all the types listed there will necessarily be valid for any given -interface. -.TP -.B \-J -.PD 0 -.TP -.B \-\-list\-time\-stamp\-types -.PD -List the supported time stamp types for the interface and exit. If the -time stamp type cannot be set for the interface, no time stamp types are -listed. -.TP -.BI \-\-time\-stamp\-precision= tstamp_precision -When capturing, set the time stamp precision for the capture to -\fItstamp_precision\fP. Note that availability of high precision time -stamps (nanoseconds) and their actual accuracy is platform and hardware -dependent. Also note that when writing captures made with nanosecond -accuracy to a savefile, the time stamps are written with nanosecond -resolution, and the file is written with a different magic number, to -indicate that the time stamps are in seconds and nanoseconds; not all -programs that read pcap savefiles will be able to read those captures. -.LP -When reading a savefile, convert time stamps to the precision specified -by \fItimestamp_precision\fP, and display them with that resolution. If -the precision specified is less than the precision of time stamps in the -file, the conversion will lose precision. -.LP -The supported values for \fItimestamp_precision\fP are \fBmicro\fP for -microsecond resolution and \fBnano\fP for nanosecond resolution. The -default is microsecond resolution. -.TP -.B \-K -.PD 0 -.TP -.B \-\-dont\-verify\-checksums -.PD -Don't attempt to verify IP, TCP, or UDP checksums. This is useful for -interfaces that perform some or all of those checksum calculation in -hardware; otherwise, all outgoing TCP checksums will be flagged as bad. -.TP -.B \-l -Make stdout line buffered. -Useful if you want to see the data -while capturing it. -E.g., -.IP -.RS -.RS -.nf -\fBtcpdump \-l | tee dat\fP -.fi -.RE -.RE -.IP -or -.IP -.RS -.RS -.nf -\fBtcpdump \-l > dat & tail \-f dat\fP -.fi -.RE -.RE -.IP -Note that on Windows,``line buffered'' means ``unbuffered'', so that -WinDump will write each character individually if -.B \-l -is specified. -.IP -.B \-U -is similar to -.B \-l -in its behavior, but it will cause output to be ``packet-buffered'', so -that the output is written to stdout at the end of each packet rather -than at the end of each line; this is buffered on all platforms, -including Windows. -.TP -.B \-L -.PD 0 -.TP -.B \-\-list\-data\-link\-types -.PD -List the known data link types for the interface, in the specified mode, -and exit. The list of known data link types may be dependent on the -specified mode; for example, on some platforms, a Wi-Fi interface might -support one set of data link types when not in monitor mode (for -example, it might support only fake Ethernet headers, or might support -802.11 headers but not support 802.11 headers with radio information) -and another set of data link types when in monitor mode (for example, it -might support 802.11 headers, or 802.11 headers with radio information, -only in monitor mode). -.TP -.BI \-m " module" -Load SMI MIB module definitions from file \fImodule\fR. -This option -can be used several times to load several MIB modules into \fItcpdump\fP. -.TP -.BI \-M " secret" -Use \fIsecret\fP as a shared secret for validating the digests found in -TCP segments with the TCP-MD5 option (RFC 2385), if present. -.TP -.B \-n -Don't convert addresses (i.e., host addresses, port numbers, etc.) to names. -.TP -.B \-N -Don't print domain name qualification of host names. -E.g., -if you give this flag then \fItcpdump\fP will print ``nic'' -instead of ``nic.ddn.mil''. -.TP -.B \-# -.PD 0 -.TP -.B \-\-number -.PD -Print an optional packet number at the beginning of the line. -.TP -.B \-O -.PD 0 -.TP -.B \-\-no\-optimize -.PD -Do not run the packet-matching code optimizer. -This is useful only -if you suspect a bug in the optimizer. -.TP -.B \-p -.PD 0 -.TP -.B \-\-no\-promiscuous\-mode -.PD -\fIDon't\fP put the interface -into promiscuous mode. -Note that the interface might be in promiscuous -mode for some other reason; hence, `-p' cannot be used as an abbreviation for -`ether host {local-hw-addr} or ether broadcast'. -.TP -.BI \-Q " direction" -.PD 0 -.TP -.BI \-\-direction= direction -.PD -Choose send/receive direction \fIdirection\fR for which packets should be -captured. Possible values are `in', `out' and `inout'. Not available -on all platforms. -.TP -.B \-q -Quick (quiet?) output. -Print less protocol information so output -lines are shorter. -.TP -.B \-R -Assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829). -If specified, \fItcpdump\fP will not print replay prevention field. -Since there is no protocol version field in ESP/AH specification, -\fItcpdump\fP cannot deduce the version of ESP/AH protocol. -.TP -.BI \-r " file" -Read packets from \fIfile\fR (which was created with the -.B \-w -option or by other tools that write pcap or pcap-ng files). -Standard input is used if \fIfile\fR is ``-''. -.TP -.B \-S -.PD 0 -.TP -.B \-\-absolute\-tcp\-sequence\-numbers -.PD -Print absolute, rather than relative, TCP sequence numbers. -.TP -.BI \-s " snaplen" -.PD 0 -.TP -.BI \-\-snapshot\-length= snaplen -.PD -Snarf \fIsnaplen\fP bytes of data from each packet rather than the -default of 65535 bytes. -Packets truncated because of a limited snapshot -are indicated in the output with ``[|\fIproto\fP]'', where \fIproto\fP -is the name of the protocol level at which the truncation has occurred. -Note that taking larger snapshots both increases -the amount of time it takes to process packets and, effectively, -decreases the amount of packet buffering. -This may cause packets to be -lost. -You should limit \fIsnaplen\fP to the smallest number that will -capture the protocol information you're interested in. -Setting -\fIsnaplen\fP to 0 sets it to the default of 65535, -for backwards compatibility with recent older versions of -.IR tcpdump . -.TP -.BI \-T " type" -Force packets selected by "\fIexpression\fP" to be interpreted the -specified \fItype\fR. -Currently known types are -\fBaodv\fR (Ad-hoc On-demand Distance Vector protocol), -\fBcarp\fR (Common Address Redundancy Protocol), -\fBcnfp\fR (Cisco NetFlow protocol), -\fBlmp\fR (Link Management Protocol), -\fBpgm\fR (Pragmatic General Multicast), -\fBpgm_zmtp1\fR (ZMTP/1.0 inside PGM/EPGM), -\fBradius\fR (RADIUS), -\fBrpc\fR (Remote Procedure Call), -\fBrtp\fR (Real-Time Applications protocol), -\fBrtcp\fR (Real-Time Applications control protocol), -\fBsnmp\fR (Simple Network Management Protocol), -\fBtftp\fR (Trivial File Transfer Protocol), -\fBvat\fR (Visual Audio Tool), -\fBwb\fR (distributed White Board), -\fBzmtp1\fR (ZeroMQ Message Transport Protocol 1.0) -and -\fBvxlan\fR (Virtual eXtensible Local Area Network). -.IP -Note that the \fBpgm\fR type above affects UDP interpretation only, the native -PGM is always recognised as IP protocol 113 regardless. UDP-encapsulated PGM is -often called "EPGM" or "PGM/UDP". -.IP -Note that the \fBpgm_zmtp1\fR type above affects interpretation of both native -PGM and UDP at once. During the native PGM decoding the application data of an -ODATA/RDATA packet would be decoded as a ZeroMQ datagram with ZMTP/1.0 frames. -During the UDP decoding in addition to that any UDP packet would be treated as -an encapsulated PGM packet. -.TP -.B \-t -\fIDon't\fP print a timestamp on each dump line. -.TP -.B \-tt -Print the timestamp, as seconds since January 1, 1970, 00:00:00, UTC, and -fractions of a second since that time, on each dump line. -.TP -.B \-ttt -Print a delta (micro-second resolution) between current and previous line -on each dump line. -.TP -.B \-tttt -Print a timestamp, as hours, minutes, seconds, and fractions of a second -since midnight, preceded by the date, on each dump line. -.TP -.B \-ttttt -Print a delta (micro-second resolution) between current and first line -on each dump line. -.TP -.B \-u -Print undecoded NFS handles. -.TP -.B \-U -.PD 0 -.TP -.B \-\-packet\-buffered -.PD -If the -.B \-w -option is not specified, make the printed packet output -``packet-buffered''; i.e., as the description of the contents of each -packet is printed, it will be written to the standard output, rather -than, when not writing to a terminal, being written only when the output -buffer fills. -.IP -If the -.B \-w -option is specified, make the saved raw packet output -``packet-buffered''; i.e., as each packet is saved, it will be written -to the output file, rather than being written only when the output -buffer fills. -.IP -The -.B \-U -flag will not be supported if -.I tcpdump -was built with an older version of -.I libpcap -that lacks the -.B pcap_dump_flush() -function. -.TP -.B \-v -When parsing and printing, produce (slightly more) verbose output. -For example, the time to live, -identification, total length and options in an IP packet are printed. -Also enables additional packet integrity checks such as verifying the -IP and ICMP header checksum. -.IP -When writing to a file with the -.B \-w -option, report, every 10 seconds, the number of packets captured. -.TP -.B \-vv -Even more verbose output. -For example, additional fields are -printed from NFS reply packets, and SMB packets are fully decoded. -.TP -.B \-vvv -Even more verbose output. -For example, -telnet \fBSB\fP ... \fBSE\fP options -are printed in full. -With -.B \-X -Telnet options are printed in hex as well. -.TP -.BI \-V " file" -Read a list of filenames from \fIfile\fR. Standard input is used -if \fIfile\fR is ``-''. -.TP -.BI \-w " file" -Write the raw packets to \fIfile\fR rather than parsing and printing -them out. -They can later be printed with the \-r option. -Standard output is used if \fIfile\fR is ``-''. -.IP -This output will be buffered if written to a file or pipe, so a program -reading from the file or pipe may not see packets for an arbitrary -amount of time after they are received. Use the -.B \-U -flag to cause packets to be written as soon as they are received. -.IP -The MIME type \fIapplication/vnd.tcpdump.pcap\fP has been registered -with IANA for \fIpcap\fP files. The filename extension \fI.pcap\fP -appears to be the most commonly used along with \fI.cap\fP and -\fI.dmp\fP. \fITcpdump\fP itself doesn't check the extension when -reading capture files and doesn't add an extension when writing them -(it uses magic numbers in the file header instead). However, many -operating systems and applications will use the extension if it is -present and adding one (e.g. .pcap) is recommended. -.IP -See -.BR pcap-savefile (5) -for a description of the file format. -.TP -.B \-W -Used in conjunction with the -.B \-C -option, this will limit the number -of files created to the specified number, and begin overwriting files -from the beginning, thus creating a 'rotating' buffer. -In addition, it will name -the files with enough leading 0s to support the maximum number of -files, allowing them to sort correctly. -.IP -Used in conjunction with the -.B \-G -option, this will limit the number of rotated dump files that get -created, exiting with status 0 when reaching the limit. If used with -.B \-C -as well, the behavior will result in cyclical files per timeslice. -.TP -.B \-x -When parsing and printing, -in addition to printing the headers of each packet, print the data of -each packet (minus its link level header) in hex. -The smaller of the entire packet or -.I snaplen -bytes will be printed. Note that this is the entire link-layer -packet, so for link layers that pad (e.g. Ethernet), the padding bytes -will also be printed when the higher layer packet is shorter than the -required padding. -.TP -.B \-xx -When parsing and printing, -in addition to printing the headers of each packet, print the data of -each packet, -.I including -its link level header, in hex. -.TP -.B \-X -When parsing and printing, -in addition to printing the headers of each packet, print the data of -each packet (minus its link level header) in hex and ASCII. -This is very handy for analysing new protocols. -.TP -.B \-XX -When parsing and printing, -in addition to printing the headers of each packet, print the data of -each packet, -.I including -its link level header, in hex and ASCII. -.TP -.BI \-y " datalinktype" -.PD 0 -.TP -.BI \-\-linktype= datalinktype -.PD -Set the data link type to use while capturing packets to \fIdatalinktype\fP. -.TP -.BI \-z " postrotate-command" -Used in conjunction with the -.B -C -or -.B -G -options, this will make -.I tcpdump -run " -.I postrotate-command file -" where -.I file -is the savefile being closed after each rotation. For example, specifying -.B \-z gzip -or -.B \-z bzip2 -will compress each savefile using gzip or bzip2. -.IP -Note that tcpdump will run the command in parallel to the capture, using -the lowest priority so that this doesn't disturb the capture process. -.IP -And in case you would like to use a command that itself takes flags or -different arguments, you can always write a shell script that will take the -savefile name as the only argument, make the flags & arguments arrangements -and execute the command that you want. -.TP -.BI \-Z " user" -.PD 0 -.TP -.BI \-\-relinquish\-privileges= user -.PD -If -.I tcpdump -is running as root, after opening the capture device or input savefile, -but before opening any savefiles for output, change the user ID to -.I user -and the group ID to the primary group of -.IR user . -.IP -This behavior can also be enabled by default at compile time. -.IP "\fI expression\fP" -.RS -selects which packets will be dumped. -If no \fIexpression\fP -is given, all packets on the net will be dumped. -Otherwise, -only packets for which \fIexpression\fP is `true' will be dumped. -.LP -For the \fIexpression\fP syntax, see -.BR pcap-filter (7). -.LP -The \fIexpression\fP argument can be passed to \fItcpdump\fP as either a single -Shell argument, or as multiple Shell arguments, whichever is more convenient. -Generally, if the expression contains Shell metacharacters, such as -backslashes used to escape protocol names, it is easier to pass it as -a single, quoted argument rather than to escape the Shell -metacharacters. -Multiple arguments are concatenated with spaces before being parsed. -.SH EXAMPLES -.LP -To print all packets arriving at or departing from \fIsundown\fP: -.RS -.nf -\fBtcpdump host sundown\fP -.fi -.RE -.LP -To print traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR: -.RS -.nf -\fBtcpdump host helios and \\( hot or ace \\)\fP -.fi -.RE -.LP -To print all IP packets between \fIace\fR and any host except \fIhelios\fR: -.RS -.nf -\fBtcpdump ip host ace and not helios\fP -.fi -.RE -.LP -To print all traffic between local hosts and hosts at Berkeley: -.RS -.nf -.B -tcpdump net ucb-ether -.fi -.RE -.LP -To print all ftp traffic through internet gateway \fIsnup\fP: -(note that the expression is quoted to prevent the shell from -(mis-)interpreting the parentheses): -.RS -.nf -.B -tcpdump 'gateway snup and (port ftp or ftp-data)' -.fi -.RE -.LP -To print traffic neither sourced from nor destined for local hosts -(if you gateway to one other net, this stuff should never make it -onto your local net). -.RS -.nf -.B -tcpdump ip and not net \fIlocalnet\fP -.fi -.RE -.LP -To print the start and end packets (the SYN and FIN packets) of each -TCP conversation that involves a non-local host. -.RS -.nf -.B -tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP' -.fi -.RE -.LP -To print all IPv4 HTTP packets to and from port 80, i.e. print only -packets that contain data, not, for example, SYN and FIN packets and -ACK-only packets. (IPv6 is left as an exercise for the reader.) -.RS -.nf -.B -tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -.fi -.RE -.LP -To print IP packets longer than 576 bytes sent through gateway \fIsnup\fP: -.RS -.nf -.B -tcpdump 'gateway snup and ip[2:2] > 576' -.fi -.RE -.LP -To print IP broadcast or multicast packets that were -.I not -sent via Ethernet broadcast or multicast: -.RS -.nf -.B -tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224' -.fi -.RE -.LP -To print all ICMP packets that are not echo requests/replies (i.e., not -ping packets): -.RS -.nf -.B -tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply' -.fi -.RE -.SH OUTPUT FORMAT -.LP -The output of \fItcpdump\fP is protocol dependent. -The following -gives a brief description and examples of most of the formats. -.de HD -.sp 1.5 -.B -.. -.HD -Link Level Headers -.LP -If the '-e' option is given, the link level header is printed out. -On Ethernets, the source and destination addresses, protocol, -and packet length are printed. -.LP -On FDDI networks, the '-e' option causes \fItcpdump\fP to print -the `frame control' field, the source and destination addresses, -and the packet length. -(The `frame control' field governs the -interpretation of the rest of the packet. -Normal packets (such -as those containing IP datagrams) are `async' packets, with a priority -value between 0 and 7; for example, `\fBasync4\fR'. -Such packets -are assumed to contain an 802.2 Logical Link Control (LLC) packet; -the LLC header is printed if it is \fInot\fR an ISO datagram or a -so-called SNAP packet. -.LP -On Token Ring networks, the '-e' option causes \fItcpdump\fP to print -the `access control' and `frame control' fields, the source and -destination addresses, and the packet length. -As on FDDI networks, -packets are assumed to contain an LLC packet. -Regardless of whether -the '-e' option is specified or not, the source routing information is -printed for source-routed packets. -.LP -On 802.11 networks, the '-e' option causes \fItcpdump\fP to print -the `frame control' fields, all of the addresses in the 802.11 header, -and the packet length. -As on FDDI networks, -packets are assumed to contain an LLC packet. -.LP -\fI(N.B.: The following description assumes familiarity with -the SLIP compression algorithm described in RFC-1144.)\fP -.LP -On SLIP links, a direction indicator (``I'' for inbound, ``O'' for outbound), -packet type, and compression information are printed out. -The packet type is printed first. -The three types are \fIip\fP, \fIutcp\fP, and \fIctcp\fP. -No further link information is printed for \fIip\fR packets. -For TCP packets, the connection identifier is printed following the type. -If the packet is compressed, its encoded header is printed out. -The special cases are printed out as -\fB*S+\fIn\fR and \fB*SA+\fIn\fR, where \fIn\fR is the amount by which -the sequence number (or sequence number and ack) has changed. -If it is not a special case, -zero or more changes are printed. -A change is indicated by U (urgent pointer), W (window), A (ack), -S (sequence number), and I (packet ID), followed by a delta (+n or -n), -or a new value (=n). -Finally, the amount of data in the packet and compressed header length -are printed. -.LP -For example, the following line shows an outbound compressed TCP packet, -with an implicit connection identifier; the ack has changed by 6, -the sequence number by 49, and the packet ID by 6; there are 3 bytes of -data and 6 bytes of compressed header: -.RS -.nf -\fBO ctcp * A+6 S+49 I+6 3 (6)\fP -.fi -.RE -.HD -ARP/RARP Packets -.LP -Arp/rarp output shows the type of request and its arguments. -The -format is intended to be self explanatory. -Here is a short sample taken from the start of an `rlogin' from -host \fIrtsg\fP to host \fIcsam\fP: -.RS -.nf -.sp .5 -\f(CWarp who-has csam tell rtsg -arp reply csam is-at CSAM\fR -.sp .5 -.fi -.RE -The first line says that rtsg sent an arp packet asking -for the Ethernet address of internet host csam. -Csam -replies with its Ethernet address (in this example, Ethernet addresses -are in caps and internet addresses in lower case). -.LP -This would look less redundant if we had done \fItcpdump \-n\fP: -.RS -.nf -.sp .5 -\f(CWarp who-has 128.3.254.6 tell 128.3.254.68 -arp reply 128.3.254.6 is-at 02:07:01:00:01:c4\fP -.fi -.RE -.LP -If we had done \fItcpdump \-e\fP, the fact that the first packet is -broadcast and the second is point-to-point would be visible: -.RS -.nf -.sp .5 -\f(CWRTSG Broadcast 0806 64: arp who-has csam tell rtsg -CSAM RTSG 0806 64: arp reply csam is-at CSAM\fR -.sp .5 -.fi -.RE -For the first packet this says the Ethernet source address is RTSG, the -destination is the Ethernet broadcast address, the type field -contained hex 0806 (type ETHER_ARP) and the total length was 64 bytes. -.HD -TCP Packets -.LP -\fI(N.B.:The following description assumes familiarity with -the TCP protocol described in RFC-793. -If you are not familiar -with the protocol, neither this description nor \fItcpdump\fP will -be of much use to you.)\fP -.LP -The general format of a tcp protocol line is: -.RS -.nf -.sp .5 -\fIsrc > dst: flags data-seqno ack window urgent options\fP -.sp .5 -.fi -.RE -\fISrc\fP and \fIdst\fP are the source and destination IP -addresses and ports. -\fIFlags\fP are some combination of S (SYN), -F (FIN), P (PUSH), R (RST), U (URG), W (ECN CWR), E (ECN-Echo) or -`.' (ACK), or `none' if no flags are set. -\fIData-seqno\fP describes the portion of sequence space covered -by the data in this packet (see example below). -\fIAck\fP is sequence number of the next data expected the other -direction on this connection. -\fIWindow\fP is the number of bytes of receive buffer space available -the other direction on this connection. -\fIUrg\fP indicates there is `urgent' data in the packet. -\fIOptions\fP are tcp options enclosed in angle brackets (e.g., ). -.LP -\fISrc, dst\fP and \fIflags\fP are always present. -The other fields -depend on the contents of the packet's tcp protocol header and -are output only if appropriate. -.LP -Here is the opening portion of an rlogin from host \fIrtsg\fP to -host \fIcsam\fP. -.RS -.nf -.sp .5 -\s-2\f(CWrtsg.1023 > csam.login: S 768512:768512(0) win 4096 -csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 -rtsg.1023 > csam.login: . ack 1 win 4096 -rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096 -csam.login > rtsg.1023: . ack 2 win 4096 -rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096 -csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077 -csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1 -csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fR\s+2 -.sp .5 -.fi -.RE -The first line says that tcp port 1023 on rtsg sent a packet -to port \fIlogin\fP -on csam. -The \fBS\fP indicates that the \fISYN\fP flag was set. -The packet sequence number was 768512 and it contained no data. -(The notation is `first:last(nbytes)' which means `sequence -numbers \fIfirst\fP -up to but not including \fIlast\fP which is \fInbytes\fP bytes of user data'.) -There was no piggy-backed ack, the available receive window was 4096 -bytes and there was a max-segment-size option requesting an mss of -1024 bytes. -.LP -Csam replies with a similar packet except it includes a piggy-backed -ack for rtsg's SYN. -Rtsg then acks csam's SYN. -The `.' means the ACK flag was set. -The packet contained no data so there is no data sequence number. -Note that the ack sequence -number is a small integer (1). -The first time \fItcpdump\fP sees a -tcp `conversation', it prints the sequence number from the packet. -On subsequent packets of the conversation, the difference between -the current packet's sequence number and this initial sequence number -is printed. -This means that sequence numbers after the -first can be interpreted -as relative byte positions in the conversation's data stream (with the -first data byte each direction being `1'). -`-S' will override this -feature, causing the original sequence numbers to be output. -.LP -On the 6th line, rtsg sends csam 19 bytes of data (bytes 2 through 20 -in the rtsg \(-> csam side of the conversation). -The PUSH flag is set in the packet. -On the 7th line, csam says it's received data sent by rtsg up to -but not including byte 21. -Most of this data is apparently sitting in the -socket buffer since csam's receive window has gotten 19 bytes smaller. -Csam also sends one byte of data to rtsg in this packet. -On the 8th and 9th lines, -csam sends two bytes of urgent, pushed data to rtsg. -.LP -If the snapshot was small enough that \fItcpdump\fP didn't capture -the full TCP header, it interprets as much of the header as it can -and then reports ``[|\fItcp\fP]'' to indicate the remainder could not -be interpreted. -If the header contains a bogus option (one with a length -that's either too small or beyond the end of the header), \fItcpdump\fP -reports it as ``[\fIbad opt\fP]'' and does not interpret any further -options (since it's impossible to tell where they start). -If the header -length indicates options are present but the IP datagram length is not -long enough for the options to actually be there, \fItcpdump\fP reports -it as ``[\fIbad hdr length\fP]''. -.HD -.B Capturing TCP packets with particular flag combinations (SYN-ACK, URG-ACK, etc.) -.PP -There are 8 bits in the control bits section of the TCP header: -.IP -.I CWR | ECE | URG | ACK | PSH | RST | SYN | FIN -.PP -Let's assume that we want to watch packets used in establishing -a TCP connection. -Recall that TCP uses a 3-way handshake protocol -when it initializes a new connection; the connection sequence with -regard to the TCP control bits is -.PP -.RS -1) Caller sends SYN -.RE -.RS -2) Recipient responds with SYN, ACK -.RE -.RS -3) Caller sends ACK -.RE -.PP -Now we're interested in capturing packets that have only the -SYN bit set (Step 1). -Note that we don't want packets from step 2 -(SYN-ACK), just a plain initial SYN. -What we need is a correct filter -expression for \fItcpdump\fP. -.PP -Recall the structure of a TCP header without options: -.PP -.nf - 0 15 31 ------------------------------------------------------------------ -| source port | destination port | ------------------------------------------------------------------ -| sequence number | ------------------------------------------------------------------ -| acknowledgment number | ------------------------------------------------------------------ -| HL | rsvd |C|E|U|A|P|R|S|F| window size | ------------------------------------------------------------------ -| TCP checksum | urgent pointer | ------------------------------------------------------------------ -.fi -.PP -A TCP header usually holds 20 octets of data, unless options are -present. -The first line of the graph contains octets 0 - 3, the -second line shows octets 4 - 7 etc. -.PP -Starting to count with 0, the relevant TCP control bits are contained -in octet 13: -.PP -.nf - 0 7| 15| 23| 31 -----------------|---------------|---------------|---------------- -| HL | rsvd |C|E|U|A|P|R|S|F| window size | -----------------|---------------|---------------|---------------- -| | 13th octet | | | -.fi -.PP -Let's have a closer look at octet no. 13: -.PP -.nf - | | - |---------------| - |C|E|U|A|P|R|S|F| - |---------------| - |7 5 3 0| -.fi -.PP -These are the TCP control bits we are interested -in. -We have numbered the bits in this octet from 0 to 7, right to -left, so the PSH bit is bit number 3, while the URG bit is number 5. -.PP -Recall that we want to capture packets with only SYN set. -Let's see what happens to octet 13 if a TCP datagram arrives -with the SYN bit set in its header: -.PP -.nf - |C|E|U|A|P|R|S|F| - |---------------| - |0 0 0 0 0 0 1 0| - |---------------| - |7 6 5 4 3 2 1 0| -.fi -.PP -Looking at the -control bits section we see that only bit number 1 (SYN) is set. -.PP -Assuming that octet number 13 is an 8-bit unsigned integer in -network byte order, the binary value of this octet is -.IP -00000010 -.PP -and its decimal representation is -.PP -.nf - 7 6 5 4 3 2 1 0 -0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 1*2 + 0*2 = 2 -.fi -.PP -We're almost done, because now we know that if only SYN is set, -the value of the 13th octet in the TCP header, when interpreted -as a 8-bit unsigned integer in network byte order, must be exactly 2. -.PP -This relationship can be expressed as -.RS -.B -tcp[13] == 2 -.RE -.PP -We can use this expression as the filter for \fItcpdump\fP in order -to watch packets which have only SYN set: -.RS -.B -tcpdump -i xl0 tcp[13] == 2 -.RE -.PP -The expression says "let the 13th octet of a TCP datagram have -the decimal value 2", which is exactly what we want. -.PP -Now, let's assume that we need to capture SYN packets, but we -don't care if ACK or any other TCP control bit is set at the -same time. -Let's see what happens to octet 13 when a TCP datagram -with SYN-ACK set arrives: -.PP -.nf - |C|E|U|A|P|R|S|F| - |---------------| - |0 0 0 1 0 0 1 0| - |---------------| - |7 6 5 4 3 2 1 0| -.fi -.PP -Now bits 1 and 4 are set in the 13th octet. -The binary value of -octet 13 is -.IP - 00010010 -.PP -which translates to decimal -.PP -.nf - 7 6 5 4 3 2 1 0 -0*2 + 0*2 + 0*2 + 1*2 + 0*2 + 0*2 + 1*2 + 0*2 = 18 -.fi -.PP -Now we can't just use 'tcp[13] == 18' in the \fItcpdump\fP filter -expression, because that would select only those packets that have -SYN-ACK set, but not those with only SYN set. -Remember that we don't care -if ACK or any other control bit is set as long as SYN is set. -.PP -In order to achieve our goal, we need to logically AND the -binary value of octet 13 with some other value to preserve -the SYN bit. -We know that we want SYN to be set in any case, -so we'll logically AND the value in the 13th octet with -the binary value of a SYN: -.PP -.nf - - 00010010 SYN-ACK 00000010 SYN - AND 00000010 (we want SYN) AND 00000010 (we want SYN) - -------- -------- - = 00000010 = 00000010 -.fi -.PP -We see that this AND operation delivers the same result -regardless whether ACK or another TCP control bit is set. -The decimal representation of the AND value as well as -the result of this operation is 2 (binary 00000010), -so we know that for packets with SYN set the following -relation must hold true: -.IP -( ( value of octet 13 ) AND ( 2 ) ) == ( 2 ) -.PP -This points us to the \fItcpdump\fP filter expression -.RS -.B - tcpdump -i xl0 'tcp[13] & 2 == 2' -.RE -.PP -Some offsets and field values may be expressed as names -rather than as numeric values. For example tcp[13] may -be replaced with tcp[tcpflags]. The following TCP flag -field values are also available: tcp-fin, tcp-syn, tcp-rst, -tcp-push, tcp-act, tcp-urg. -.PP -This can be demonstrated as: -.RS -.B - tcpdump -i xl0 'tcp[tcpflags] & tcp-push != 0' -.RE -.PP -Note that you should use single quotes or a backslash -in the expression to hide the AND ('&') special character -from the shell. -.HD -.B -UDP Packets -.LP -UDP format is illustrated by this rwho packet: -.RS -.nf -.sp .5 -\f(CWactinide.who > broadcast.who: udp 84\fP -.sp .5 -.fi -.RE -This says that port \fIwho\fP on host \fIactinide\fP sent a udp -datagram to port \fIwho\fP on host \fIbroadcast\fP, the Internet -broadcast address. -The packet contained 84 bytes of user data. -.LP -Some UDP services are recognized (from the source or destination -port number) and the higher level protocol information printed. -In particular, Domain Name service requests (RFC-1034/1035) and Sun -RPC calls (RFC-1050) to NFS. -.HD -UDP Name Server Requests -.LP -\fI(N.B.:The following description assumes familiarity with -the Domain Service protocol described in RFC-1035. -If you are not familiar -with the protocol, the following description will appear to be written -in greek.)\fP -.LP -Name server requests are formatted as -.RS -.nf -.sp .5 -\fIsrc > dst: id op? flags qtype qclass name (len)\fP -.sp .5 -\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fR -.sp .5 -.fi -.RE -Host \fIh2opolo\fP asked the domain server on \fIhelios\fP for an -address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP -The query id was `3'. -The `+' indicates the \fIrecursion desired\fP flag -was set. -The query length was 37 bytes, not including the UDP and -IP protocol headers. -The query operation was the normal one, \fIQuery\fP, -so the op field was omitted. -If the op had been anything else, it would -have been printed between the `3' and the `+'. -Similarly, the qclass was the normal one, -\fIC_IN\fP, and omitted. -Any other qclass would have been printed -immediately after the `A'. -.LP -A few anomalies are checked and may result in extra fields enclosed in -square brackets: If a query contains an answer, authority records or -additional records section, -.IR ancount , -.IR nscount , -or -.I arcount -are printed as `[\fIn\fPa]', `[\fIn\fPn]' or `[\fIn\fPau]' where \fIn\fP -is the appropriate count. -If any of the response bits are set (AA, RA or rcode) or any of the -`must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]' -is printed, where \fIx\fP is the hex value of header bytes two and three. -.HD -UDP Name Server Responses -.LP -Name server responses are formatted as -.RS -.nf -.sp .5 -\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP -.sp .5 -\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273) -helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fR -.sp .5 -.fi -.RE -In the first example, \fIhelios\fP responds to query id 3 from \fIh2opolo\fP -with 3 answer records, 3 name server records and 7 additional records. -The first answer record is type A (address) and its data is internet -address 128.32.137.3. -The total size of the response was 273 bytes, -excluding UDP and IP headers. -The op (Query) and response code -(NoError) were omitted, as was the class (C_IN) of the A record. -.LP -In the second example, \fIhelios\fP responds to query 2 with a -response code of non-existent domain (NXDomain) with no answers, -one name server and no authority records. -The `*' indicates that -the \fIauthoritative answer\fP bit was set. -Since there were no -answers, no type, class or data were printed. -.LP -Other flag characters that might appear are `\-' (recursion available, -RA, \fInot\fP set) and `|' (truncated message, TC, set). -If the -`question' section doesn't contain exactly one entry, `[\fIn\fPq]' -is printed. -.HD -SMB/CIFS decoding -.LP -\fItcpdump\fP now includes fairly extensive SMB/CIFS/NBT decoding for data -on UDP/137, UDP/138 and TCP/139. -Some primitive decoding of IPX and -NetBEUI SMB data is also done. -.LP -By default a fairly minimal decode is done, with a much more detailed -decode done if -v is used. -Be warned that with -v a single SMB packet -may take up a page or more, so only use -v if you really want all the -gory details. -.LP -For information on SMB packet formats and what all the fields mean see -www.cifs.org or the pub/samba/specs/ directory on your favorite -samba.org mirror site. -The SMB patches were written by Andrew Tridgell -(tridge@samba.org). -.HD -NFS Requests and Replies -.LP -Sun NFS (Network File System) requests and replies are printed as: -.RS -.nf -.sp .5 -\fIsrc.sport > dst.nfs: NFS request xid xid len op args\fP -\fIsrc.nfs > dst.dport: NFS reply xid xid reply stat len op results\fP -.sp .5 -\f(CW -sushi.1023 > wrl.nfs: NFS request xid 26377 - 112 readlink fh 21,24/10.73165 -wrl.nfs > sushi.1023: NFS reply xid 26377 - reply ok 40 readlink "../var" -sushi.1022 > wrl.nfs: NFS request xid 8219 - 144 lookup fh 9,74/4096.6878 "xcolors" -wrl.nfs > sushi.1022: NFS reply xid 8219 - reply ok 128 lookup fh 9,74/4134.3150 -\fR -.sp .5 -.fi -.RE -In the first line, host \fIsushi\fP sends a transaction with id \fI26377\fP -to \fIwrl\fP. -The request was 112 bytes, -excluding the UDP and IP headers. -The operation was a \fIreadlink\fP -(read symbolic link) on file handle (\fIfh\fP) 21,24/10.731657119. -(If one is lucky, as in this case, the file handle can be interpreted -as a major,minor device number pair, followed by the inode number and -generation number.) In the second line, \fIwrl\fP replies `ok' with -the same transaction id and the contents of the link. -.LP -In the third line, \fIsushi\fP asks (using a new transaction id) \fIwrl\fP -to lookup the name `\fIxcolors\fP' in directory file 9,74/4096.6878. In -the fourth line, \fIwrl\fP sends a reply with the respective transaction id. -.LP -Note that the data printed -depends on the operation type. -The format is intended to be self -explanatory if read in conjunction with -an NFS protocol spec. -Also note that older versions of tcpdump printed NFS packets in a -slightly different format: the transaction id (xid) would be printed -instead of the non-NFS port number of the packet. -.LP -If the \-v (verbose) flag is given, additional information is printed. -For example: -.RS -.nf -.sp .5 -\f(CW -sushi.1023 > wrl.nfs: NFS request xid 79658 - 148 read fh 21,11/12.195 8192 bytes @ 24576 -wrl.nfs > sushi.1023: NFS reply xid 79658 - reply ok 1472 read REG 100664 ids 417/0 sz 29388 -\fP -.sp .5 -.fi -.RE -(\-v also prints the IP header TTL, ID, length, and fragmentation fields, -which have been omitted from this example.) In the first line, -\fIsushi\fP asks \fIwrl\fP to read 8192 bytes from file 21,11/12.195, -at byte offset 24576. -\fIWrl\fP replies `ok'; the packet shown on the -second line is the first fragment of the reply, and hence is only 1472 -bytes long (the other bytes will follow in subsequent fragments, but -these fragments do not have NFS or even UDP headers and so might not be -printed, depending on the filter expression used). -Because the \-v flag -is given, some of the file attributes (which are returned in addition -to the file data) are printed: the file type (``REG'', for regular file), -the file mode (in octal), the uid and gid, and the file size. -.LP -If the \-v flag is given more than once, even more details are printed. -.LP -Note that NFS requests are very large and much of the detail won't be printed -unless \fIsnaplen\fP is increased. -Try using `\fB\-s 192\fP' to watch -NFS traffic. -.LP -NFS reply packets do not explicitly identify the RPC operation. -Instead, -\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the -replies using the transaction ID. -If a reply does not closely follow the -corresponding request, it might not be parsable. -.HD -AFS Requests and Replies -.LP -Transarc AFS (Andrew File System) requests and replies are printed -as: -.HD -.RS -.nf -.sp .5 -\fIsrc.sport > dst.dport: rx packet-type\fP -\fIsrc.sport > dst.dport: rx packet-type service call call-name args\fP -\fIsrc.sport > dst.dport: rx packet-type service reply call-name args\fP -.sp .5 -\f(CW -elvis.7001 > pike.afsfs: - rx data fs call rename old fid 536876964/1/1 ".newsrc.new" - new fid 536876964/1/1 ".newsrc" -pike.afsfs > elvis.7001: rx data fs reply rename -\fR -.sp .5 -.fi -.RE -In the first line, host elvis sends a RX packet to pike. -This was -a RX data packet to the fs (fileserver) service, and is the start of -an RPC call. -The RPC call was a rename, with the old directory file id -of 536876964/1/1 and an old filename of `.newsrc.new', and a new directory -file id of 536876964/1/1 and a new filename of `.newsrc'. -The host pike -responds with a RPC reply to the rename call (which was successful, because -it was a data packet and not an abort packet). -.LP -In general, all AFS RPCs are decoded at least by RPC call name. -Most -AFS RPCs have at least some of the arguments decoded (generally only -the `interesting' arguments, for some definition of interesting). -.LP -The format is intended to be self-describing, but it will probably -not be useful to people who are not familiar with the workings of -AFS and RX. -.LP -If the -v (verbose) flag is given twice, acknowledgement packets and -additional header information is printed, such as the RX call ID, -call number, sequence number, serial number, and the RX packet flags. -.LP -If the -v flag is given twice, additional information is printed, -such as the RX call ID, serial number, and the RX packet flags. -The MTU negotiation information is also printed from RX ack packets. -.LP -If the -v flag is given three times, the security index and service id -are printed. -.LP -Error codes are printed for abort packets, with the exception of Ubik -beacon packets (because abort packets are used to signify a yes vote -for the Ubik protocol). -.LP -Note that AFS requests are very large and many of the arguments won't -be printed unless \fIsnaplen\fP is increased. -Try using `\fB-s 256\fP' -to watch AFS traffic. -.LP -AFS reply packets do not explicitly identify the RPC operation. -Instead, -\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the -replies using the call number and service ID. -If a reply does not closely -follow the -corresponding request, it might not be parsable. - -.HD -KIP AppleTalk (DDP in UDP) -.LP -AppleTalk DDP packets encapsulated in UDP datagrams are de-encapsulated -and dumped as DDP packets (i.e., all the UDP header information is -discarded). -The file -.I /etc/atalk.names -is used to translate AppleTalk net and node numbers to names. -Lines in this file have the form -.RS -.nf -.sp .5 -\fInumber name\fP - -\f(CW1.254 ether -16.1 icsd-net -1.254.110 ace\fR -.sp .5 -.fi -.RE -The first two lines give the names of AppleTalk networks. -The third -line gives the name of a particular host (a host is distinguished -from a net by the 3rd octet in the number \- -a net number \fImust\fP have two octets and a host number \fImust\fP -have three octets.) The number and name should be separated by -whitespace (blanks or tabs). -The -.I /etc/atalk.names -file may contain blank lines or comment lines (lines starting with -a `#'). -.LP -AppleTalk addresses are printed in the form -.RS -.nf -.sp .5 -\fInet.host.port\fP - -\f(CW144.1.209.2 > icsd-net.112.220 -office.2 > icsd-net.112.220 -jssmag.149.235 > icsd-net.2\fR -.sp .5 -.fi -.RE -(If the -.I /etc/atalk.names -doesn't exist or doesn't contain an entry for some AppleTalk -host/net number, addresses are printed in numeric form.) -In the first example, NBP (DDP port 2) on net 144.1 node 209 -is sending to whatever is listening on port 220 of net icsd node 112. -The second line is the same except the full name of the source node -is known (`office'). -The third line is a send from port 235 on -net jssmag node 149 to broadcast on the icsd-net NBP port (note that -the broadcast address (255) is indicated by a net name with no host -number \- for this reason it's a good idea to keep node names and -net names distinct in /etc/atalk.names). -.LP -NBP (name binding protocol) and ATP (AppleTalk transaction protocol) -packets have their contents interpreted. -Other protocols just dump -the protocol name (or number if no name is registered for the -protocol) and packet size. - -\fBNBP packets\fP are formatted like the following examples: -.RS -.nf -.sp .5 -\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*" -jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250 -techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR\s+2 -.sp .5 -.fi -.RE -The first line is a name lookup request for laserwriters sent by net icsd host -112 and broadcast on net jssmag. -The nbp id for the lookup is 190. -The second line shows a reply for this request (note that it has the -same id) from host jssmag.209 saying that it has a laserwriter -resource named "RM1140" registered on port 250. -The third line is -another reply to the same request saying host techpit has laserwriter -"techpit" registered on port 186. - -\fBATP packet\fP formatting is demonstrated by the following example: -.RS -.nf -.sp .5 -\s-2\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001 -helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:4 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:6 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp*12266:7 (512) 0xae040000 -jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001 -helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000 -helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000 -jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001 -jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR\s+2 -.sp .5 -.fi -.RE -Jssmag.209 initiates transaction id 12266 with host helios by requesting -up to 8 packets (the `<0-7>'). -The hex number at the end of the line -is the value of the `userdata' field in the request. -.LP -Helios responds with 8 512-byte packets. -The `:digit' following the -transaction id gives the packet sequence number in the transaction -and the number in parens is the amount of data in the packet, -excluding the atp header. -The `*' on packet 7 indicates that the -EOM bit was set. -.LP -Jssmag.209 then requests that packets 3 & 5 be retransmitted. -Helios -resends them then jssmag.209 releases the transaction. -Finally, -jssmag.209 initiates the next request. -The `*' on the request -indicates that XO (`exactly once') was \fInot\fP set. - -.HD -IP Fragmentation -.LP -Fragmented Internet datagrams are printed as -.RS -.nf -.sp .5 -\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB+)\fR -\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB)\fR -.sp .5 -.fi -.RE -(The first form indicates there are more fragments. -The second -indicates this is the last fragment.) -.LP -\fIId\fP is the fragment id. -\fISize\fP is the fragment -size (in bytes) excluding the IP header. -\fIOffset\fP is this -fragment's offset (in bytes) in the original datagram. -.LP -The fragment information is output for each fragment. -The first -fragment contains the higher level protocol header and the frag -info is printed after the protocol info. -Fragments -after the first contain no higher level protocol header and the -frag info is printed after the source and destination addresses. -For example, here is part of an ftp from arizona.edu to lbl-rtsg.arpa -over a CSNET connection that doesn't appear to handle 576 byte datagrams: -.RS -.nf -.sp .5 -\s-2\f(CWarizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+) -arizona > rtsg: (frag 595a:204@328) -rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560\fP\s+2 -.sp .5 -.fi -.RE -There are a couple of things to note here: First, addresses in the -2nd line don't include port numbers. -This is because the TCP -protocol information is all in the first fragment and we have no idea -what the port or sequence numbers are when we print the later fragments. -Second, the tcp sequence information in the first line is printed as if there -were 308 bytes of user data when, in fact, there are 512 bytes (308 in -the first frag and 204 in the second). -If you are looking for holes -in the sequence space or trying to match up acks -with packets, this can fool you. -.LP -A packet with the IP \fIdon't fragment\fP flag is marked with a -trailing \fB(DF)\fP. -.HD -Timestamps -.LP -By default, all output lines are preceded by a timestamp. -The timestamp -is the current clock time in the form -.RS -.nf -\fIhh:mm:ss.frac\fP -.fi -.RE -and is as accurate as the kernel's clock. -The timestamp reflects the time the kernel first saw the packet. -No attempt -is made to account for the time lag between when the -Ethernet interface removed the packet from the wire and when the kernel -serviced the `new packet' interrupt. -.SH "SEE ALSO" -stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(5), -pcap-filter(7), pcap-tstamp(7) -.LP -.RS -.I http://www.iana.org/assignments/media-types/application/vnd.tcpdump.pcap -.RE -.LP -.SH AUTHORS -The original authors are: -.LP -Van Jacobson, -Craig Leres and -Steven McCanne, all of the -Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. -.LP -It is currently being maintained by tcpdump.org. -.LP -The current version is available via http: -.LP -.RS -.I http://www.tcpdump.org/ -.RE -.LP -The original distribution is available via anonymous ftp: -.LP -.RS -.I ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z -.RE -.LP -IPv6/IPsec support is added by WIDE/KAME project. -This program uses Eric Young's SSLeay library, under specific configurations. -.SH BUGS -Please send problems, bugs, questions, desirable enhancements, patches -etc. to: -.LP -.RS -tcpdump-workers@lists.tcpdump.org -.RE -.LP -NIT doesn't let you watch your own outbound traffic, BPF will. -We recommend that you use the latter. -.LP -On Linux systems with 2.0[.x] kernels: -.IP -packets on the loopback device will be seen twice; -.IP -packet filtering cannot be done in the kernel, so that all packets must -be copied from the kernel in order to be filtered in user mode; -.IP -all of a packet, not just the part that's within the snapshot length, -will be copied from the kernel (the 2.0[.x] packet capture mechanism, if -asked to copy only part of a packet to userland, will not report the -true length of the packet; this would cause most IP packets to get an -error from -.BR tcpdump ); -.IP -capturing on some PPP devices won't work correctly. -.LP -We recommend that you upgrade to a 2.2 or later kernel. -.LP -Some attempt should be made to reassemble IP fragments or, at least -to compute the right length for the higher level protocol. -.LP -Name server inverse queries are not dumped correctly: the (empty) -question section is printed rather than real query in the answer -section. -Some believe that inverse queries are themselves a bug and -prefer to fix the program generating them rather than \fItcpdump\fP. -.LP -A packet trace that crosses a daylight savings time change will give -skewed time stamps (the time change is ignored). -.LP -Filter expressions on fields other than those in Token Ring headers will -not correctly handle source-routed Token Ring packets. -.LP -Filter expressions on fields other than those in 802.11 headers will not -correctly handle 802.11 data packets with both To DS and From DS set. -.LP -.BR "ip6 proto" -should chase header chain, but at this moment it does not. -.BR "ip6 protochain" -is supplied for this behavior. -.LP -Arithmetic expression against transport layer headers, like \fBtcp[0]\fP, -does not work against IPv6 packets. -It only looks at IPv4 packets. diff --git a/usr.sbin/timed/timed/Makefile.depend b/usr.sbin/timed/timed/Makefile.depend index c0e71696d4d9..a42543b2d06e 100644 --- a/usr.sbin/timed/timed/Makefile.depend +++ b/usr.sbin/timed/timed/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/usr.sbin/timed/timedc/Makefile.depend b/usr.sbin/timed/timedc/Makefile.depend index e77ca8db1787..782b0d5c171e 100644 --- a/usr.sbin/timed/timedc/Makefile.depend +++ b/usr.sbin/timed/timedc/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/protocols \ diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile index 41f40772df03..ada19698a9a1 100644 --- a/usr.sbin/traceroute/Makefile +++ b/usr.sbin/traceroute/Makefile @@ -33,7 +33,7 @@ LIBADD+= ipsec .if ${MK_CASPER} != "no" LIBADD+= casper LIBADD+= cap_dns -CFLAGS+=-DHAVE_LIBCASPER +CFLAGS+=-DWITH_CASPER .endif CFLAGS+= -I${TRACEROUTE_DISTDIR} diff --git a/usr.sbin/traceroute/Makefile.depend b/usr.sbin/traceroute/Makefile.depend index fd3e4ac98a4b..b30f732d1d32 100644 --- a/usr.sbin/traceroute/Makefile.depend +++ b/usr.sbin/traceroute/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/traceroute6/Makefile.depend b/usr.sbin/traceroute6/Makefile.depend index 27cbf261b843..b78c121a5f29 100644 --- a/usr.sbin/traceroute6/Makefile.depend +++ b/usr.sbin/traceroute6/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8 index 884ad6dc339c..4aa51553b757 100644 --- a/usr.sbin/traceroute6/traceroute6.8 +++ b/usr.sbin/traceroute6/traceroute6.8 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 24, 2009 +.Dd September 30, 2017 .Dt TRACEROUTE6 8 .Os .\" @@ -40,7 +40,7 @@ .Sh SYNOPSIS .Nm .Bk -words -.Op Fl adIlnNrvU +.Op Fl adIlnNrSTUv .Ek .Bk -words .Op Fl f Ar firsthop @@ -79,7 +79,7 @@ uses the IPv6 protocol hop limit field to elicit an ICMPv6 TIME_EXCEEDED response from each gateway along the path to some host. .Pp The only mandatory parameter is the destination host name or IPv6 address. -The default probe datagram carries 12 bytes of payload, +The default probe datagram carries 20 bytes of payload, in addition to the IPv6 header. The size of the payload can be specified by giving a length (in bytes) @@ -96,9 +96,9 @@ Debug mode. .It Fl f Ar firsthop Specify how many hops to skip in trace. .It Fl g Ar gateway -Specify intermediate gateway -.Nm ( -uses routing header). +Specify intermediate gateway. Please note that +.Nm +tries to use routing headers. .It Fl I Use ICMP6 ECHO instead of UDP datagrams. .It Fl l @@ -119,7 +119,7 @@ Do not resolve numeric address to hostname. Use a packet with no upper layer header for the probes, instead of UDP datagrams. .It Fl p Ar port -Set UDP port number to +Set SCTP/TCP/UDP port number to .Ar port . .It Fl q Ar probes Set the number of probe per hop count to @@ -138,6 +138,10 @@ that has no route through it .It Fl s Ar src .Ar Src specifies the source IPv6 address to be used. +.It Fl S +Use SCTP packets for the probes. +.It Fl T +Use TCP segments for the probes. .It Fl U Use UDP datagrams for the probes. This is the default. diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c index c0189480d223..03ba808ca508 100644 --- a/usr.sbin/traceroute6/traceroute6.c +++ b/usr.sbin/traceroute6/traceroute6.c @@ -271,6 +271,8 @@ static const char rcsid[] = #include #include +#include +#include #include #ifdef IPSEC @@ -289,23 +291,8 @@ static const char rcsid[] = #define freehostent(x) #endif -/* - * format of a (udp) probe packet. - */ -struct tv32 { - u_int32_t tv32_sec; - u_int32_t tv32_usec; -}; - -struct opacket { - u_char seq; /* sequence number of this packet */ - u_char hops; /* hop limit of the packet */ - u_char pad[2]; - struct tv32 tv; /* time packet left */ -} __attribute__((__packed__)); - u_char packet[512]; /* last inbound (icmp) packet */ -struct opacket *outpacket; /* last output (udp) packet */ +char *outpacket; /* last output packet */ int main(int, char *[]); int wait_for_reply(int, struct msghdr *); @@ -322,10 +309,14 @@ const char *pr_type(int); int packet_ok(struct msghdr *, int, int); void print(struct msghdr *, int); const char *inetname(struct sockaddr *); +u_int32_t sctp_crc32c(void *, u_int32_t); +u_int16_t in_cksum(u_int16_t *addr, int); +u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *, + void *, u_int32_t); void usage(void); int rcvsock; /* receive (icmp) socket file descriptor */ -int sndsock; /* send (udp) socket file descriptor */ +int sndsock; /* send (raw/udp) socket file descriptor */ struct msghdr rcvmhdr; struct iovec rcviov[2]; @@ -333,7 +324,7 @@ int rcvhlim; struct in6_pktinfo *rcvpktinfo; struct sockaddr_in6 Src, Dst, Rcv; -u_long datalen; /* How much data */ +u_long datalen = 20; /* How much data */ #define ICMP6ECHOLEN 8 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ char rtbuf[2064]; @@ -362,9 +353,7 @@ char *as_server = NULL; void *asn; int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; @@ -411,8 +400,9 @@ main(argc, argv) #endif seq = 0; + ident = htons(getpid() & 0xffff); /* same as ping6 */ - while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:Uvw:")) != -1) + while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1) switch (ch) { case 'a': as_path = 1; @@ -472,7 +462,6 @@ main(argc, argv) break; case 'I': useproto = IPPROTO_ICMPV6; - ident = htons(getpid() & 0xffff); /* same as ping6 */ break; case 'l': lflag++; @@ -533,12 +522,18 @@ main(argc, argv) */ source = optarg; break; - case 'v': - verbose++; + case 'S': + useproto = IPPROTO_SCTP; + break; + case 'T': + useproto = IPPROTO_TCP; break; case 'U': useproto = IPPROTO_UDP; break; + case 'v': + verbose++; + break; case 'w': ep = NULL; errno = 0; @@ -574,13 +569,15 @@ main(argc, argv) } break; case IPPROTO_NONE: - if ((sndsock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) { + case IPPROTO_SCTP: + case IPPROTO_TCP: + if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) { perror("socket(SOCK_RAW)"); exit(5); } break; default: - fprintf(stderr, "traceroute6: unknown probe protocol %d", + fprintf(stderr, "traceroute6: unknown probe protocol %d\n", useproto); exit(5); } @@ -641,7 +638,7 @@ main(argc, argv) ep = NULL; errno = 0; datalen = strtoul(*argv, &ep, 0); - if (errno || !*argv || *ep) { + if (errno || *ep) { fprintf(stderr, "traceroute6: invalid packet length.\n"); exit(1); @@ -649,15 +646,21 @@ main(argc, argv) } switch (useproto) { case IPPROTO_ICMPV6: - minlen = ICMP6ECHOLEN + sizeof(struct tv32); + minlen = ICMP6ECHOLEN; break; case IPPROTO_UDP: - minlen = sizeof(struct opacket); + minlen = sizeof(struct udphdr); break; case IPPROTO_NONE: minlen = 0; datalen = 0; break; + case IPPROTO_SCTP: + minlen = sizeof(struct sctphdr); + break; + case IPPROTO_TCP: + minlen = sizeof(struct tcphdr); + break; default: fprintf(stderr, "traceroute6: unknown probe protocol %d.\n", useproto); @@ -671,6 +674,8 @@ main(argc, argv) minlen, MAXPACKET); exit(1); } + if (useproto == IPPROTO_UDP) + datalen -= sizeof(struct udphdr); outpacket = malloc(datalen); if (!outpacket) { perror("malloc"); @@ -735,8 +740,10 @@ main(argc, argv) #ifdef SO_SNDBUF i = datalen; + if (i == 0) + i = 1; if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i, - sizeof(i)) < 0 && useproto != IPPROTO_NONE) { + sizeof(i)) < 0) { perror("setsockopt(SO_SNDBUF)"); exit(6); } @@ -897,7 +904,8 @@ main(argc, argv) if (source) fprintf(stderr, " from %s", source); fprintf(stderr, ", %lu hops max, %lu byte packets\n", - max_hops, datalen); + max_hops, + datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0)); (void) fflush(stderr); if (first_hop > 1) @@ -977,9 +985,7 @@ main(argc, argv) } int -wait_for_reply(sock, mhdr) - int sock; - struct msghdr *mhdr; +wait_for_reply(int sock, struct msghdr *mhdr) { #ifdef HAVE_POLL struct pollfd pfd[1]; @@ -1038,14 +1044,12 @@ setpolicy(so, policy) #endif void -send_probe(seq, hops) - int seq; - u_long hops; +send_probe(int seq, u_long hops) { struct icmp6_hdr *icp; - struct opacket *op; - struct timeval tv; - struct tv32 tv32; + struct sctphdr *sctp; + struct sctp_chunkhdr *chk; + struct tcphdr *tcp; int i; i = hops; @@ -1055,9 +1059,6 @@ send_probe(seq, hops) } Dst.sin6_port = htons(port + seq); - (void) gettimeofday(&tv, NULL); - tv32.tv32_sec = htonl(tv.tv_sec); - tv32.tv32_usec = htonl(tv.tv_usec); switch (useproto) { case IPPROTO_ICMPV6: @@ -1068,19 +1069,49 @@ send_probe(seq, hops) icp->icmp6_cksum = 0; icp->icmp6_id = ident; icp->icmp6_seq = htons(seq); - bcopy(&tv32, ((u_int8_t *)outpacket + ICMP6ECHOLEN), - sizeof(tv32)); break; case IPPROTO_UDP: - op = outpacket; - - op->seq = seq; - op->hops = hops; - bcopy(&tv32, &op->tv, sizeof tv32); break; case IPPROTO_NONE: /* No space for anything. No harm as seq/tv32 are decorative. */ break; + case IPPROTO_SCTP: + sctp = (struct sctphdr *)outpacket; + + sctp->src_port = htons(ident); + sctp->dest_port = htons(port + seq); + sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port; + sctp->checksum = htonl(0); + if (datalen >= (u_long)(sizeof(struct sctphdr) + + sizeof(struct sctp_chunkhdr))) { + chk = (struct sctp_chunkhdr *)(sctp + 1); + chk->chunk_type = SCTP_SHUTDOWN_ACK; + chk->chunk_flags = 0; + chk->chunk_length = htons(4); + } + if (datalen >= (u_long)(sizeof(struct sctphdr) + + 2 * sizeof(struct sctp_chunkhdr))) { + chk = chk + 1; + chk->chunk_type = SCTP_PAD_CHUNK; + chk->chunk_flags = 0; + chk->chunk_length = htons((u_int16_t)(datalen - + sizeof(struct sctphdr) - + sizeof(struct sctp_chunkhdr))); + } + sctp->checksum = sctp_crc32c(outpacket, datalen); + break; + case IPPROTO_TCP: + tcp = (struct tcphdr *)outpacket; + + tcp->th_sport = htons(ident); + tcp->th_dport = htons(port + seq); + tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; + tcp->th_ack = 0; + tcp->th_off = 5; + tcp->th_flags = TH_SYN; + tcp->th_sum = 0; + tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen); + break; default: fprintf(stderr, "Unknown probe protocol %d.\n", useproto); exit(1); @@ -1098,8 +1129,7 @@ send_probe(seq, hops) } int -get_hoplim(mhdr) - struct msghdr *mhdr; +get_hoplim(struct msghdr *mhdr) { struct cmsghdr *cm; @@ -1115,8 +1145,7 @@ get_hoplim(mhdr) } double -deltaT(t1p, t2p) - struct timeval *t1p, *t2p; +deltaT(struct timeval *t1p, struct timeval *t2p) { double dt; @@ -1185,10 +1214,7 @@ pr_type(int t0) } int -packet_ok(mhdr, cc, seq) - struct msghdr *mhdr; - int cc; - int seq; +packet_ok(struct msghdr *mhdr, int cc, int seq) { struct icmp6_hdr *icp; struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; @@ -1262,6 +1288,10 @@ packet_ok(mhdr, cc, seq) if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) || type == ICMP6_DST_UNREACH) { struct ip6_hdr *hip; + struct icmp6_hdr *icmp; + struct sctphdr *sctp; + struct tcphdr *tcp; + struct udphdr *udp; void *up; hip = (struct ip6_hdr *)(icp + 1); @@ -1272,14 +1302,34 @@ packet_ok(mhdr, cc, seq) } switch (useproto) { case IPPROTO_ICMPV6: - if (((struct icmp6_hdr *)up)->icmp6_id == ident && - ((struct icmp6_hdr *)up)->icmp6_seq == htons(seq)) + icmp = (struct icmp6_hdr *)up; + if (icmp->icmp6_id == ident && + icmp->icmp6_seq == htons(seq)) return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1); break; case IPPROTO_UDP: - if (((struct udphdr *)up)->uh_sport == htons(srcport) && - ((struct udphdr *)up)->uh_dport == htons(port + seq)) + udp = (struct udphdr *)up; + if (udp->uh_sport == htons(srcport) && + udp->uh_dport == htons(port + seq)) + return (type == ICMP6_TIME_EXCEEDED ? + -1 : code + 1); + break; + case IPPROTO_SCTP: + sctp = (struct sctphdr *)up; + if (sctp->src_port == htons(ident) && + sctp->dest_port == htons(port + seq) && + sctp->v_tag == + (u_int32_t)((sctp->src_port << 16) | sctp->dest_port)) + return (type == ICMP6_TIME_EXCEEDED ? + -1 : code + 1); + break; + case IPPROTO_TCP: + tcp = (struct tcphdr *)up; + if (tcp->th_sport == htons(ident) && + tcp->th_dport == htons(port + seq) && + tcp->th_seq == + (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport)) return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1); break; @@ -1328,9 +1378,7 @@ packet_ok(mhdr, cc, seq) * Increment pointer until find the UDP or ICMP header. */ void * -get_uphdr(ip6, lim) - struct ip6_hdr *ip6; - u_char *lim; +get_uphdr(struct ip6_hdr *ip6, u_char *lim) { u_char *cp = (u_char *)ip6, nh; int hlen; @@ -1345,10 +1393,11 @@ get_uphdr(ip6, lim) while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) { switch (nh) { case IPPROTO_ESP: - case IPPROTO_TCP: return(NULL); case IPPROTO_ICMPV6: return(useproto == nh ? cp : NULL); + case IPPROTO_SCTP: + case IPPROTO_TCP: case IPPROTO_UDP: return(useproto == nh ? cp : NULL); case IPPROTO_NONE: @@ -1374,9 +1423,7 @@ get_uphdr(ip6, lim) } void -print(mhdr, cc) - struct msghdr *mhdr; - int cc; +print(struct msghdr *mhdr, int cc) { struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; char hbuf[NI_MAXHOST]; @@ -1412,8 +1459,7 @@ print(mhdr, cc) * numeric value, otherwise try for symbolic name. */ const char * -inetname(sa) - struct sockaddr *sa; +inetname(struct sockaddr *sa) { static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1]; static int first = 1; @@ -1446,12 +1492,163 @@ inetname(sa) return line; } +/* + * CRC32C routine for the Stream Control Transmission Protocol + */ + +#define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF]) + +static u_int32_t crc_c[256] = { + 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, + 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, + 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, + 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, + 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, + 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, + 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, + 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, + 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, + 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, + 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, + 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, + 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, + 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, + 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, + 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, + 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, + 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, + 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, + 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, + 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, + 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, + 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, + 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, + 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, + 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, + 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, + 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, + 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, + 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, + 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, + 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, + 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, + 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, + 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, + 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, + 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, + 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, + 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, + 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, + 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, + 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, + 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, + 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, + 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, + 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, + 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, + 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, + 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, + 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, + 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, + 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, + 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, + 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, + 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, + 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, + 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, + 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, + 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, + 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, + 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, + 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, + 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, + 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 +}; + +u_int32_t +sctp_crc32c(void *packet, u_int32_t len) +{ + u_int32_t i, crc32c; + u_int8_t byte0, byte1, byte2, byte3; + u_int8_t *buf = (u_int8_t *)packet; + + crc32c = ~0; + for (i = 0; i < len; i++) + CRC32C(crc32c, buf[i]); + crc32c = ~crc32c; + byte0 = crc32c & 0xff; + byte1 = (crc32c>>8) & 0xff; + byte2 = (crc32c>>16) & 0xff; + byte3 = (crc32c>>24) & 0xff; + crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); + return htonl(crc32c); +} + +u_int16_t +in_cksum(u_int16_t *addr, int len) +{ + int nleft = len; + u_int16_t *w = addr; + u_int16_t answer; + int sum = 0; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), + * we add sequential 16 bit words to it, and at the end, fold + * back all the carry bits from the top 16 bits into the lower + * 16 bits. + */ + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + /* mop up an odd byte, if necessary */ + if (nleft == 1) + sum += *(u_char *)w; + + /* + * add back carry outs from top 16 bits to low 16 bits + */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return (answer); +} + +u_int16_t +tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, + void *payload, u_int32_t len) +{ + struct { + struct in6_addr src; + struct in6_addr dst; + u_int32_t len; + u_int8_t zero[3]; + u_int8_t next; + } pseudo_hdr; + u_int16_t sum[2]; + + pseudo_hdr.src = src->sin6_addr; + pseudo_hdr.dst = dst->sin6_addr; + pseudo_hdr.len = htonl(len); + pseudo_hdr.zero[0] = 0; + pseudo_hdr.zero[1] = 0; + pseudo_hdr.zero[2] = 0; + pseudo_hdr.next = IPPROTO_TCP; + + sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); + sum[0] = in_cksum(payload, len); + + return (~in_cksum(sum, sizeof(sum))); +} + void -usage() +usage(void) { fprintf(stderr, -"usage: traceroute6 [-adIlnNrUv] [-A as_server] [-f firsthop] [-g gateway]\n" +"usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n" " [datalen]\n"); exit(1); diff --git a/usr.sbin/trpt/Makefile.depend b/usr.sbin/trpt/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/trpt/Makefile.depend +++ b/usr.sbin/trpt/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/tzsetup/Makefile.depend b/usr.sbin/tzsetup/Makefile.depend index 5e97e258b259..87a30b89d0f0 100644 --- a/usr.sbin/tzsetup/Makefile.depend +++ b/usr.sbin/tzsetup/Makefile.depend @@ -4,7 +4,6 @@ DIRDEPS = \ gnu/lib/csu \ gnu/lib/libdialog \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/uathload/Makefile.depend b/usr.sbin/uathload/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/uathload/Makefile.depend +++ b/usr.sbin/uathload/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/uefisign/Makefile.depend b/usr.sbin/uefisign/Makefile.depend index fc0b63320671..cdd96948933d 100644 --- a/usr.sbin/uefisign/Makefile.depend +++ b/usr.sbin/uefisign/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/ugidfw/Makefile.depend b/usr.sbin/ugidfw/Makefile.depend index 24a1de909f18..65c3644dbf39 100644 --- a/usr.sbin/ugidfw/Makefile.depend +++ b/usr.sbin/ugidfw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/uhsoctl/Makefile.depend b/usr.sbin/uhsoctl/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/uhsoctl/Makefile.depend +++ b/usr.sbin/uhsoctl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/unbound/anchor/Makefile.depend b/usr.sbin/unbound/anchor/Makefile.depend index 399b8c2e1a5a..75cb691c1c91 100644 --- a/usr.sbin/unbound/anchor/Makefile.depend +++ b/usr.sbin/unbound/anchor/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/unbound/checkconf/Makefile.depend b/usr.sbin/unbound/checkconf/Makefile.depend index 36ffed022d93..37b991b9f24c 100644 --- a/usr.sbin/unbound/checkconf/Makefile.depend +++ b/usr.sbin/unbound/checkconf/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/unbound/control/Makefile.depend b/usr.sbin/unbound/control/Makefile.depend index 36ffed022d93..37b991b9f24c 100644 --- a/usr.sbin/unbound/control/Makefile.depend +++ b/usr.sbin/unbound/control/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/unbound/daemon/Makefile.depend b/usr.sbin/unbound/daemon/Makefile.depend index 06c0c16b9bf7..fb63d6473d7b 100644 --- a/usr.sbin/unbound/daemon/Makefile.depend +++ b/usr.sbin/unbound/daemon/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/usbconfig/Makefile.depend b/usr.sbin/usbconfig/Makefile.depend index 3ddb39c3f983..a93901938c4b 100644 --- a/usr.sbin/usbconfig/Makefile.depend +++ b/usr.sbin/usbconfig/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/usbdump/Makefile.depend b/usr.sbin/usbdump/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/usbdump/Makefile.depend +++ b/usr.sbin/usbdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/utx/Makefile.depend b/usr.sbin/utx/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/utx/Makefile.depend +++ b/usr.sbin/utx/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/vidcontrol/Makefile.depend b/usr.sbin/vidcontrol/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/vidcontrol/Makefile.depend +++ b/usr.sbin/vidcontrol/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/vipw/Makefile.depend b/usr.sbin/vipw/Makefile.depend index 58f9a3347b00..991757ecadc0 100644 --- a/usr.sbin/vipw/Makefile.depend +++ b/usr.sbin/vipw/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/wake/Makefile.depend b/usr.sbin/wake/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/wake/Makefile.depend +++ b/usr.sbin/wake/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/watch/Makefile.depend b/usr.sbin/watch/Makefile.depend index 59bc82802604..9b2a343de2dc 100644 --- a/usr.sbin/watch/Makefile.depend +++ b/usr.sbin/watch/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/watchdogd/Makefile.depend b/usr.sbin/watchdogd/Makefile.depend index a79b1eb12b7b..a015e205da56 100644 --- a/usr.sbin/watchdogd/Makefile.depend +++ b/usr.sbin/watchdogd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/wlandebug/Makefile b/usr.sbin/wlandebug/Makefile index e916c23e7512..7ac993319947 100644 --- a/usr.sbin/wlandebug/Makefile +++ b/usr.sbin/wlandebug/Makefile @@ -3,6 +3,8 @@ PROG= wlandebug MAN= wlandebug.8 +LIBADD+= ifconfig + WARNS?= 2 .include diff --git a/usr.sbin/wlandebug/Makefile.depend b/usr.sbin/wlandebug/Makefile.depend index 3646e2e2b1af..37b288fd73d8 100644 --- a/usr.sbin/wlandebug/Makefile.depend +++ b/usr.sbin/wlandebug/Makefile.depend @@ -3,12 +3,12 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libifconfig \ .include diff --git a/usr.sbin/wlandebug/wlandebug.c b/usr.sbin/wlandebug/wlandebug.c index 9bec123b5f63..b5c635074300 100644 --- a/usr.sbin/wlandebug/wlandebug.c +++ b/usr.sbin/wlandebug/wlandebug.c @@ -43,6 +43,8 @@ #include #include +#include + #define N(a) (sizeof(a)/sizeof(a[0])) const char *progname; @@ -160,6 +162,24 @@ setoid(char oid[], size_t oidlen, const char *wlan) #endif } +static void +get_orig_iface_name(char *oid, size_t oid_size, char *name) +{ + struct ifconfig_handle *h; + char *orig_name; + + h = ifconfig_open(); + if (ifconfig_get_orig_name(h, name, &orig_name) < 0) + errc(1, ifconfig_err_errno(h), "cannot get interface name"); + + if (strlen(orig_name) < strlen("wlan") + 1) + errx(1, "expecting a wlan interface name"); + + ifconfig_close(h); + setoid(oid, oid_size, orig_name); + free(orig_name); +} + int main(int argc, char *argv[]) { @@ -179,9 +199,7 @@ main(int argc, char *argv[]) } else if (strcmp(argv[1], "-i") == 0) { if (argc <= 2) errx(1, "missing interface name for -i option"); - if (strncmp(argv[2], "wlan", 4) != 0) - errx(1, "expecting a wlan interface name"); - setoid(oid, sizeof(oid), argv[2]); + get_orig_iface_name(oid, sizeof(oid), argv[2]); argc -= 2, argv += 2; } else if (strcmp(argv[1], "-?") == 0) usage(); diff --git a/usr.sbin/wpa/hostapd/Makefile.depend b/usr.sbin/wpa/hostapd/Makefile.depend index 8d486ac28c75..59c29ce26572 100644 --- a/usr.sbin/wpa/hostapd/Makefile.depend +++ b/usr.sbin/wpa/hostapd/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/wpa/hostapd_cli/Makefile.depend b/usr.sbin/wpa/hostapd_cli/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/wpa/hostapd_cli/Makefile.depend +++ b/usr.sbin/wpa/hostapd_cli/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/wpa/ndis_events/Makefile.depend b/usr.sbin/wpa/ndis_events/Makefile.depend index 54c1f6f1442e..d5ed563ecfc8 100644 --- a/usr.sbin/wpa/ndis_events/Makefile.depend +++ b/usr.sbin/wpa/ndis_events/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/wpa/wpa_cli/Makefile.depend b/usr.sbin/wpa/wpa_cli/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/wpa/wpa_cli/Makefile.depend +++ b/usr.sbin/wpa/wpa_cli/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile.depend b/usr.sbin/wpa/wpa_passphrase/Makefile.depend index 7de116d21d37..4fc5be2a35f0 100644 --- a/usr.sbin/wpa/wpa_passphrase/Makefile.depend +++ b/usr.sbin/wpa/wpa_passphrase/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile.depend b/usr.sbin/wpa/wpa_supplicant/Makefile.depend index 8d486ac28c75..59c29ce26572 100644 --- a/usr.sbin/wpa/wpa_supplicant/Makefile.depend +++ b/usr.sbin/wpa/wpa_supplicant/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/xlocale \ diff --git a/usr.sbin/yp_mkdb/Makefile.depend b/usr.sbin/yp_mkdb/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.sbin/yp_mkdb/Makefile.depend +++ b/usr.sbin/yp_mkdb/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/ypbind/Makefile.depend b/usr.sbin/ypbind/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/ypbind/Makefile.depend +++ b/usr.sbin/ypbind/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/ypldap/Makefile.depend b/usr.sbin/ypldap/Makefile.depend index 9bbec4ae8769..2a162b74233c 100644 --- a/usr.sbin/ypldap/Makefile.depend +++ b/usr.sbin/ypldap/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/yppoll/Makefile.depend b/usr.sbin/yppoll/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/yppoll/Makefile.depend +++ b/usr.sbin/yppoll/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/yppush/Makefile.depend b/usr.sbin/yppush/Makefile.depend index ddd5dbd24c8d..85338ebe3beb 100644 --- a/usr.sbin/yppush/Makefile.depend +++ b/usr.sbin/yppush/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/rpc \ include/rpcsvc \ diff --git a/usr.sbin/ypserv/Makefile.depend b/usr.sbin/ypserv/Makefile.depend index 16d959fe306a..48ed3670a8c1 100644 --- a/usr.sbin/ypserv/Makefile.depend +++ b/usr.sbin/ypserv/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/ypset/Makefile.depend b/usr.sbin/ypset/Makefile.depend index c0b7a1462fde..faed4b4cc2aa 100644 --- a/usr.sbin/ypset/Makefile.depend +++ b/usr.sbin/ypset/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/arpa \ include/rpc \ diff --git a/usr.sbin/zic/zdump/Makefile.depend b/usr.sbin/zic/zdump/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/zic/zdump/Makefile.depend +++ b/usr.sbin/zic/zdump/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/zic/zic/Makefile b/usr.sbin/zic/zic/Makefile index 9702c4c4b30f..36cc79009b45 100644 --- a/usr.sbin/zic/zic/Makefile +++ b/usr.sbin/zic/zic/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + .PATH: ${SRCTOP}/contrib/tzcode/zic PROG= zic @@ -13,4 +15,8 @@ CFLAGS+= -I${.CURDIR:H} -I${SRCTOP}/contrib/tzcode/stdtime WARNS?= 2 +.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 50300 +CWARNFLAGS+= -Wno-error=strict-overflow +.endif + .include diff --git a/usr.sbin/zic/zic/Makefile.depend b/usr.sbin/zic/zic/Makefile.depend index 3646e2e2b1af..6cfaab1c3644 100644 --- a/usr.sbin/zic/zic/Makefile.depend +++ b/usr.sbin/zic/zic/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \ diff --git a/usr.sbin/zonectl/Makefile.depend b/usr.sbin/zonectl/Makefile.depend index 48a48dd2446c..ee06e1c20939 100644 --- a/usr.sbin/zonectl/Makefile.depend +++ b/usr.sbin/zonectl/Makefile.depend @@ -3,7 +3,6 @@ DIRDEPS = \ gnu/lib/csu \ - gnu/lib/libgcc \ include \ include/xlocale \ lib/${CSU_DIR} \

This file, and other release-related documents, - can be downloaded from .